<commit_before>/* Bosch BMI160 inertial measurement unit driver
 *
 * Copyright (c) 2016 Intel Corporation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Datasheet:
 * http://ae-bst.resource.bosch.com/media/_tech/media/datasheets/BST-BMI160-DS000-07.pdf
 */

#include <init.h>
#include <sensor.h>
#include <spi.h>
#include <gpio.h>
#include <misc/byteorder.h>
#include <nanokernel.h>

#include "sensor_bmi160.h"

struct bmi160_device_data bmi160_data;

static int bmi160_transceive(struct device *dev, uint8_t *tx_buf,
			     uint8_t tx_buf_len, uint8_t *rx_buf,
			     uint8_t rx_buf_len)
{
	struct bmi160_device_config *dev_cfg = dev->config->config_info;
	struct bmi160_device_data *bmi160 = dev->driver_data;
	struct spi_config spi_cfg;

	spi_cfg.config = SPI_WORD(8);
	spi_cfg.max_sys_freq = dev_cfg->spi_freq;

	if (spi_configure(bmi160->spi, &spi_cfg) < 0) {
		DBG("Cannot configure SPI bus.\n");
		return -EIO;
	}

	if (spi_slave_select(bmi160->spi, dev_cfg->spi_slave) < 0) {
		DBG("Cannot select slave.\n");
		return -EIO;
	}

	return spi_transceive(bmi160->spi, tx_buf, tx_buf_len,
			      rx_buf, rx_buf_len);
}

static int bmi160_read(struct device *dev, uint8_t reg_addr,
		       uint8_t *data, uint8_t len)
{
	uint8_t tx = reg_addr | (1 << 7);

	return bmi160_transceive(dev, &tx, 1, data, len);
}

static int bmi160_byte_read(struct device *dev, uint8_t reg_addr,
			    uint8_t *byte)
{
	uint8_t rx_buf[2];

	if (bmi160_read(dev, reg_addr, rx_buf, 2) < 0) {
		return -EIO;
	}

	*byte = rx_buf[1];

	return 0;
}

static int bmi160_word_read(struct device *dev, uint8_t reg_addr,
			    uint16_t *word)
{
	union {
		uint8_t raw[3];
		struct {
			uint8_t dummy;
			uint16_t word;
		} __packed;
	} buf;

	if (bmi160_read(dev, reg_addr, buf.raw, 3) < 0) {
		return -EIO;
	}

	*word = sys_le16_to_cpu(buf.word);

	return 0;
}

static int bmi160_byte_write(struct device *dev, uint8_t reg_addr, uint8_t byte)
{
	uint8_t tx_buf[2] = {reg_addr & 0x7F, byte};

	return bmi160_transceive(dev, tx_buf, 2, NULL, 0);
}

static int bmi160_reg_field_update(struct device *dev, uint8_t reg_addr,
				   uint8_t pos, uint8_t mask, uint8_t val)
{
	uint8_t old_val;

	if (bmi160_byte_read(dev, reg_addr, &old_val) < 0) {
		return -EIO;
	}

	return  bmi160_byte_write(dev, reg_addr,
				  (old_val & ~mask) | (val << pos));
}

static int bmi160_pmu_set(struct device *dev, union bmi160_pmu_status *pmu_sts)
{
	struct {
		uint8_t cmd;
		uint16_t delay_us; /* values taken from page 82 */
	} cmds[] = {
		{BMI160_CMD_PMU_MAG | pmu_sts->mag, 350},
		{BMI160_CMD_PMU_ACC | pmu_sts->acc, 3200},
		{BMI160_CMD_PMU_GYR | pmu_sts->gyr, 55000}
	};
	int i;

	for (i = 0; i < ARRAY_SIZE(cmds); i++) {
		union bmi160_pmu_status sts;
		bool pmu_set = false;

		if (bmi160_byte_write(dev, BMI160_REG_CMD, cmds[i].cmd) < 0) {
			return -EIO;
		}

		/*
		 * Cannot use a nano timer here since this is called from the
		 * init function and the timeouts were not initialized yet.
		 */
		sys_thread_busy_wait(cmds[i].delay_us);

		/* make sure the PMU_STATUS was set, though */<commit_msg>sensor: bmi160: fix bmi160_reg_field_update function<commit_after>/* Bosch BMI160 inertial measurement unit driver
 *
 * Copyright (c) 2016 Intel Corporation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Datasheet:
 * http://ae-bst.resource.bosch.com/media/_tech/media/datasheets/BST-BMI160-DS000-07.pdf
 */

#include <init.h>
#include <sensor.h>
#include <spi.h>
#include <gpio.h>
#include <misc/byteorder.h>
#include <nanokernel.h>

#include "sensor_bmi160.h"

struct bmi160_device_data bmi160_data;

static int bmi160_transceive(struct device *dev, uint8_t *tx_buf,
			     uint8_t tx_buf_len, uint8_t *rx_buf,
			     uint8_t rx_buf_len)
{
	struct bmi160_device_config *dev_cfg = dev->config->config_info;
	struct bmi160_device_data *bmi160 = dev->driver_data;
	struct spi_config spi_cfg;

	spi_cfg.config = SPI_WORD(8);
	spi_cfg.max_sys_freq = dev_cfg->spi_freq;

	if (spi_configure(bmi160->spi, &spi_cfg) < 0) {
		DBG("Cannot configure SPI bus.\n");
		return -EIO;
	}

	if (spi_slave_select(bmi160->spi, dev_cfg->spi_slave) < 0) {
		DBG("Cannot select slave.\n");
		return -EIO;
	}

	return spi_transceive(bmi160->spi, tx_buf, tx_buf_len,
			      rx_buf, rx_buf_len);
}

static int bmi160_read(struct device *dev, uint8_t reg_addr,
		       uint8_t *data, uint8_t len)
{
	uint8_t tx = reg_addr | (1 << 7);

	return bmi160_transceive(dev, &tx, 1, data, len);
}

static int bmi160_byte_read(struct device *dev, uint8_t reg_addr,
			    uint8_t *byte)
{
	uint8_t rx_buf[2];

	if (bmi160_read(dev, reg_addr, rx_buf, 2) < 0) {
		return -EIO;
	}

	*byte = rx_buf[1];

	return 0;
}

static int bmi160_word_read(struct device *dev, uint8_t reg_addr,
			    uint16_t *word)
{
	union {
		uint8_t raw[3];
		struct {
			uint8_t dummy;
			uint16_t word;
		} __packed;
	} buf;

	if (bmi160_read(dev, reg_addr, buf.raw, 3) < 0) {
		return -EIO;
	}

	*word = sys_le16_to_cpu(buf.word);

	return 0;
}

static int bmi160_byte_write(struct device *dev, uint8_t reg_addr, uint8_t byte)
{
	uint8_t tx_buf[2] = {reg_addr & 0x7F, byte};

	return bmi160_transceive(dev, tx_buf, 2, NULL, 0);
}

static int bmi160_reg_field_update(struct device *dev, uint8_t reg_addr,
				   uint8_t pos, uint8_t mask, uint8_t val)
{
	uint8_t old_val;

	if (bmi160_byte_read(dev, reg_addr, &old_val) < 0) {
		return -EIO;
	}

	return  bmi160_byte_write(dev, reg_addr,
				  (old_val & ~mask) | ((val << pos) & mask));
}

static int bmi160_pmu_set(struct device *dev, union bmi160_pmu_status *pmu_sts)
{
	struct {
		uint8_t cmd;
		uint16_t delay_us; /* values taken from page 82 */
	} cmds[] = {
		{BMI160_CMD_PMU_MAG | pmu_sts->mag, 350},
		{BMI160_CMD_PMU_ACC | pmu_sts->acc, 3200},
		{BMI160_CMD_PMU_GYR | pmu_sts->gyr, 55000}
	};
	int i;

	for (i = 0; i < ARRAY_SIZE(cmds); i++) {
		union bmi160_pmu_status sts;
		bool pmu_set = false;

		if (bmi160_byte_write(dev, BMI160_REG_CMD, cmds[i].cmd) < 0) {
			return -EIO;
		}

		/*
		 * Cannot use a nano timer here since this is called from the
		 * init function and the timeouts were not initialized yet.
		 */
		sys_thread_busy_wait(cmds[i].delay_us);

		/* make sure the PMU_STATUS was set, though */
{'fraction_non_alphanumeric': 0.11638527539440909, 'fraction_numerical': 0.04898975920287849, 'mean_word_length': 3.9263803680981595, 'pattern_counts': {'":': 0, '<': 37, '<?xml version=': 0, '>': 37, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1053263', 'n_tokens_mistral': 3234, 'n_tokens_neox': 2841, 'n_words': 737}