mirror of
https://github.com/zephyrproject-rtos/zephyr
synced 2025-09-04 02:51:56 +00:00
Some device include a temperature sensor, usually used as a companion for helping in drift compensation, that measure the die temperature. This temperature IS NOT related to the the ambient temperature, hence a clean separation between the two is required. This commit introduces a clean separation between the two types of temperature leaving the old deprecated definition still there. The list of current drivers that read the die (and not the ambient) temperature is the following: - adxl362 - bma280 - bmg160 - bmi160 - fxos8700 - lis3mdl - lsm6ds0 - lsm6dsl - lsm9ds0 - mpu6050 Signed-off-by: Armando Visconti <armando.visconti@st.com>
103 lines
2.2 KiB
C
103 lines
2.2 KiB
C
/* sensor_mcp9808.c - Driver for MCP9808 temperature sensor */
|
|
|
|
/*
|
|
* Copyright (c) 2016 Intel Corporation
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
#include <errno.h>
|
|
|
|
#include <kernel.h>
|
|
#include <i2c.h>
|
|
#include <init.h>
|
|
#include <misc/byteorder.h>
|
|
#include <misc/__assert.h>
|
|
|
|
#include "mcp9808.h"
|
|
|
|
|
|
int mcp9808_reg_read(struct mcp9808_data *data, u8_t reg, u16_t *val)
|
|
{
|
|
struct i2c_msg msgs[2] = {
|
|
{
|
|
.buf = ®,
|
|
.len = 1,
|
|
.flags = I2C_MSG_WRITE | I2C_MSG_RESTART,
|
|
},
|
|
{
|
|
.buf = (u8_t *)val,
|
|
.len = 2,
|
|
.flags = I2C_MSG_READ | I2C_MSG_STOP,
|
|
},
|
|
};
|
|
|
|
if (i2c_transfer(data->i2c_master, msgs, 2, data->i2c_slave_addr)
|
|
< 0) {
|
|
return -EIO;
|
|
}
|
|
|
|
*val = sys_be16_to_cpu(*val);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int mcp9808_sample_fetch(struct device *dev, enum sensor_channel chan)
|
|
{
|
|
struct mcp9808_data *data = dev->driver_data;
|
|
|
|
__ASSERT_NO_MSG(chan == SENSOR_CHAN_ALL || chan == SENSOR_CHAN_AMBIENT_TEMP);
|
|
|
|
return mcp9808_reg_read(data, MCP9808_REG_TEMP_AMB, &data->reg_val);
|
|
}
|
|
|
|
static int mcp9808_channel_get(struct device *dev,
|
|
enum sensor_channel chan,
|
|
struct sensor_value *val)
|
|
{
|
|
struct mcp9808_data *data = dev->driver_data;
|
|
|
|
__ASSERT_NO_MSG(chan == SENSOR_CHAN_AMBIENT_TEMP);
|
|
|
|
val->val1 = (data->reg_val & MCP9808_TEMP_INT_MASK) >>
|
|
MCP9808_TEMP_INT_SHIFT;
|
|
val->val2 = (data->reg_val & MCP9808_TEMP_FRAC_MASK) * 62500;
|
|
|
|
if (data->reg_val & MCP9808_SIGN_BIT) {
|
|
val->val1 -= 256;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static const struct sensor_driver_api mcp9808_api_funcs = {
|
|
.sample_fetch = mcp9808_sample_fetch,
|
|
.channel_get = mcp9808_channel_get,
|
|
.attr_set = mcp9808_attr_set,
|
|
.trigger_set = mcp9808_trigger_set,
|
|
};
|
|
|
|
int mcp9808_init(struct device *dev)
|
|
{
|
|
struct mcp9808_data *data = dev->driver_data;
|
|
|
|
data->i2c_master = device_get_binding(CONFIG_MCP9808_I2C_DEV_NAME);
|
|
if (!data->i2c_master) {
|
|
SYS_LOG_DBG("mcp9808: i2c master not found: %s",
|
|
CONFIG_MCP9808_I2C_DEV_NAME);
|
|
return -EINVAL;
|
|
}
|
|
|
|
data->i2c_slave_addr = CONFIG_MCP9808_I2C_ADDR;
|
|
|
|
mcp9808_setup_interrupt(dev);
|
|
|
|
return 0;
|
|
}
|
|
|
|
struct mcp9808_data mcp9808_data;
|
|
|
|
DEVICE_AND_API_INIT(mcp9808, CONFIG_MCP9808_DEV_NAME, mcp9808_init,
|
|
&mcp9808_data, NULL, POST_KERNEL,
|
|
CONFIG_SENSOR_INIT_PRIORITY, &mcp9808_api_funcs);
|