-
Notifications
You must be signed in to change notification settings - Fork 6.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
drivers: sensor: add F75303 temperature sensor driver #60833
Merged
Merged
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This sort of thing is exactly why we need to support channel type and index pairs and not just channel type
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are there any open issues/proposals to to do this?
This could also be modeled as a multi-function device, with each temperature sensor nested under a parent device. But that seems a little heavyweight.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's being discussed in #61163, though to the best of my knowledge, there is no dedicated issue about this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#13718 #1387 both note the need for multiple channels of the same type, it is a long standing issue
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
MFD for that seems incredibly overkill for this, device specific channels seems reasonable to close the gap and get the code in, easy enough to change it to subchannel later.