-
Notifications
You must be signed in to change notification settings - Fork 6.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add driver for F75303 temperature sensor IC. Signed-off-by: Paweł Anikiel <pan@semihalf.com>
- Loading branch information
Paweł Anikiel
committed
Aug 9, 2023
1 parent
af55a8e
commit fd5b8a1
Showing
10 changed files
with
465 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
zephyr_library() | ||
zephyr_library_sources(f75303.c) | ||
zephyr_library_sources_ifdef(CONFIG_EMUL_F75303 f75303_emul.c) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
# F75303 temperature sensor configuration options | ||
|
||
# Copyright (c) 2023 Google LLC | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
config F75303 | ||
bool "F75303 Temperature Sensor" | ||
default y | ||
depends on DT_HAS_FINTEK_F75303_ENABLED | ||
select I2C | ||
help | ||
Enable the driver for Fintek F75303 Temperature Sensor. | ||
This device has three temperature channels - one local (on-chip), | ||
and two remote. | ||
|
||
config EMUL_F75303 | ||
bool "Emulator for F75303" | ||
default y | ||
depends on F75303 | ||
depends on EMUL | ||
help | ||
Enable the hardware emulator for F75303 Temperature Sensor. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,198 @@ | ||
/* | ||
* Copyright (c) 2023 Google LLC | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
#define DT_DRV_COMPAT fintek_f75303 | ||
|
||
#include <zephyr/device.h> | ||
#include <zephyr/drivers/i2c.h> | ||
#include <zephyr/drivers/sensor.h> | ||
#include <zephyr/pm/device.h> | ||
#include <zephyr/pm/device_runtime.h> | ||
#include <zephyr/logging/log.h> | ||
#include <zephyr/drivers/sensor/f75303.h> | ||
#include "f75303.h" | ||
|
||
#define F75303_SAMPLE_INT_SHIFT 3 | ||
#define F75303_SAMPLE_FRAC_MASK GENMASK(2, 0) | ||
#define F75303_SAMPLE_MICROCELSIUS_PER_BIT 125000 | ||
|
||
LOG_MODULE_REGISTER(F75303, CONFIG_SENSOR_LOG_LEVEL); | ||
|
||
static int f75303_fetch(const struct i2c_dt_spec *i2c, | ||
uint8_t off_h, uint8_t off_l, uint16_t *sample) | ||
{ | ||
uint8_t val_h; | ||
uint8_t val_l; | ||
int res; | ||
|
||
res = i2c_reg_read_byte_dt(i2c, off_h, &val_h); | ||
if (res) { | ||
return res; | ||
} | ||
|
||
res = i2c_reg_read_byte_dt(i2c, off_l, &val_l); | ||
if (res) { | ||
return res; | ||
} | ||
|
||
*sample = val_h << 3 | val_l >> 5; | ||
|
||
return 0; | ||
} | ||
|
||
static int f75303_fetch_local(const struct device *dev) | ||
{ | ||
struct f75303_data *data = dev->data; | ||
const struct f75303_config *config = dev->config; | ||
|
||
return f75303_fetch(&config->i2c, | ||
F75303_LOCAL_TEMP_H, | ||
F75303_LOCAL_TEMP_L, | ||
&data->sample_local); | ||
} | ||
|
||
static int f75303_fetch_remote1(const struct device *dev) | ||
{ | ||
struct f75303_data *data = dev->data; | ||
const struct f75303_config *config = dev->config; | ||
|
||
return f75303_fetch(&config->i2c, | ||
F75303_REMOTE1_TEMP_H, | ||
F75303_REMOTE1_TEMP_L, | ||
&data->sample_remote1); | ||
} | ||
|
||
static int f75303_fetch_remote2(const struct device *dev) | ||
{ | ||
struct f75303_data *data = dev->data; | ||
const struct f75303_config *config = dev->config; | ||
|
||
return f75303_fetch(&config->i2c, | ||
F75303_REMOTE2_TEMP_H, | ||
F75303_REMOTE2_TEMP_L, | ||
&data->sample_remote2); | ||
} | ||
|
||
static int f75303_sample_fetch(const struct device *dev, | ||
enum sensor_channel chan) | ||
{ | ||
enum pm_device_state pm_state; | ||
int res; | ||
|
||
(void)pm_device_state_get(dev, &pm_state); | ||
if (pm_state != PM_DEVICE_STATE_ACTIVE) { | ||
return -EIO; | ||
} | ||
|
||
switch ((uint32_t)chan) { | ||
case SENSOR_CHAN_ALL: | ||
res = f75303_fetch_local(dev); | ||
if (res) { | ||
break; | ||
} | ||
res = f75303_fetch_remote1(dev); | ||
if (res) { | ||
break; | ||
} | ||
res = f75303_fetch_remote2(dev); | ||
break; | ||
case SENSOR_CHAN_AMBIENT_TEMP: | ||
return f75303_fetch_local(dev); | ||
case SENSOR_CHAN_F75303_REMOTE1: | ||
return f75303_fetch_remote1(dev); | ||
case SENSOR_CHAN_F75303_REMOTE2: | ||
return f75303_fetch_remote2(dev); | ||
default: | ||
return -ENOTSUP; | ||
} | ||
|
||
return res; | ||
} | ||
|
||
static int f75303_channel_get(const struct device *dev, | ||
enum sensor_channel chan, | ||
struct sensor_value *val) | ||
{ | ||
struct f75303_data *data = dev->data; | ||
uint16_t sample; | ||
|
||
switch ((uint32_t)chan) { | ||
case SENSOR_CHAN_AMBIENT_TEMP: | ||
sample = data->sample_local; | ||
break; | ||
case SENSOR_CHAN_F75303_REMOTE1: | ||
sample = data->sample_remote1; | ||
break; | ||
case SENSOR_CHAN_F75303_REMOTE2: | ||
sample = data->sample_remote2; | ||
break; | ||
default: | ||
return -ENOTSUP; | ||
} | ||
|
||
/* | ||
* The reading is given in steps of 0.125 degrees celsius, i.e. the | ||
* temperature in degrees celsius is equal to sample / 8. | ||
*/ | ||
val->val1 = sample >> F75303_SAMPLE_INT_SHIFT; | ||
val->val2 = (sample & F75303_SAMPLE_FRAC_MASK) * F75303_SAMPLE_MICROCELSIUS_PER_BIT; | ||
|
||
return 0; | ||
} | ||
|
||
static const struct sensor_driver_api f75303_driver_api = { | ||
.sample_fetch = f75303_sample_fetch, | ||
.channel_get = f75303_channel_get, | ||
}; | ||
|
||
static int f75303_init(const struct device *dev) | ||
{ | ||
const struct f75303_config *config = dev->config; | ||
int res = 0; | ||
|
||
if (!i2c_is_ready_dt(&config->i2c)) { | ||
LOG_ERR("I2C device not ready"); | ||
return -ENODEV; | ||
} | ||
|
||
#ifdef CONFIG_PM_DEVICE_RUNTIME | ||
pm_device_init_suspended(dev); | ||
|
||
res = pm_device_runtime_enable(dev); | ||
if (res) { | ||
LOG_ERR("Failed to enable runtime power management"); | ||
} | ||
#endif | ||
|
||
return res; | ||
} | ||
|
||
#ifdef CONFIG_PM_DEVICE | ||
static int f75303_pm_action(const struct device *dev, enum pm_device_action action) | ||
{ | ||
switch (action) { | ||
case PM_DEVICE_ACTION_TURN_ON: | ||
case PM_DEVICE_ACTION_RESUME: | ||
case PM_DEVICE_ACTION_TURN_OFF: | ||
case PM_DEVICE_ACTION_SUSPEND: | ||
return 0; | ||
default: | ||
return -ENOTSUP; | ||
} | ||
} | ||
#endif | ||
|
||
#define F75303_INST(inst) \ | ||
static struct f75303_data f75303_data_##inst; \ | ||
static const struct f75303_config f75303_config_##inst = { \ | ||
.i2c = I2C_DT_SPEC_INST_GET(inst), \ | ||
}; \ | ||
PM_DEVICE_DT_INST_DEFINE(inst, f75303_pm_action); \ | ||
SENSOR_DEVICE_DT_INST_DEFINE(inst, f75303_init, PM_DEVICE_DT_INST_GET(inst), \ | ||
&f75303_data_##inst, &f75303_config_##inst, POST_KERNEL, \ | ||
CONFIG_SENSOR_INIT_PRIORITY, &f75303_driver_api); | ||
|
||
DT_INST_FOREACH_STATUS_OKAY(F75303_INST) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
/* | ||
* Copyright (c) 2023 Google LLC | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
#ifndef ZEPHYR_DRIVERS_SENSOR_F75303_F75303_H_ | ||
#define ZEPHYR_DRIVERS_SENSOR_F75303_F75303_H_ | ||
|
||
#include <zephyr/device.h> | ||
#include <zephyr/sys/util.h> | ||
|
||
#define F75303_LOCAL_TEMP_H 0x00 | ||
#define F75303_REMOTE1_TEMP_H 0x01 | ||
#define F75303_REMOTE1_TEMP_L 0x10 | ||
#define F75303_REMOTE2_TEMP_H 0x23 | ||
#define F75303_REMOTE2_TEMP_L 0x24 | ||
#define F75303_LOCAL_TEMP_L 0x29 | ||
|
||
struct f75303_data { | ||
uint16_t sample_local; | ||
uint16_t sample_remote1; | ||
uint16_t sample_remote2; | ||
}; | ||
|
||
struct f75303_config { | ||
struct i2c_dt_spec i2c; | ||
}; | ||
|
||
#endif |
Oops, something went wrong.