Skip to content

Commit

Permalink
drivers: sensor: Add F75303 driver
Browse files Browse the repository at this point in the history
Add driver for F75303 temperature sensor IC.

Signed-off-by: Paweł Anikiel <pan@semihalf.com>
  • Loading branch information
Paweł Anikiel authored and panikiel committed Jul 31, 2023
1 parent a0a9539 commit f05fae4
Show file tree
Hide file tree
Showing 17 changed files with 509 additions and 0 deletions.
1 change: 1 addition & 0 deletions drivers/sensor/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ add_subdirectory_ifdef(CONFIG_DPS310 dps310)
add_subdirectory_ifdef(CONFIG_DS18B20 ds18b20)
add_subdirectory_ifdef(CONFIG_ENS210 ens210)
add_subdirectory_ifdef(CONFIG_ESP32_TEMP esp32_temp)
add_subdirectory_ifdef(CONFIG_F75303 f75303)
add_subdirectory_ifdef(CONFIG_FDC2X1X fdc2x1x)
add_subdirectory_ifdef(CONFIG_FXAS21002 fxas21002)
add_subdirectory_ifdef(CONFIG_FXOS8700 fxos8700)
Expand Down
1 change: 1 addition & 0 deletions drivers/sensor/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ source "drivers/sensor/dps310/Kconfig"
source "drivers/sensor/ds18b20/Kconfig"
source "drivers/sensor/ens210/Kconfig"
source "drivers/sensor/esp32_temp/Kconfig"
source "drivers/sensor/f75303/Kconfig"
source "drivers/sensor/fdc2x1x/Kconfig"
source "drivers/sensor/fxas21002/Kconfig"
source "drivers/sensor/fxos8700/Kconfig"
Expand Down
6 changes: 6 additions & 0 deletions drivers/sensor/f75303/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# SPDX-License-Identifier: Apache-2.0

zephyr_library()
zephyr_library_sources(f75303.c)
zephyr_library_sources_ifdef(CONFIG_EMUL_F75303 f75303_emul.c)
zephyr_include_directories_ifdef(CONFIG_EMUL_F75303 .)
22 changes: 22 additions & 0 deletions drivers/sensor/f75303/Kconfig
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.
156 changes: 156 additions & 0 deletions drivers/sensor/f75303/f75303.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
/*
* 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/logging/log.h>
#include <zephyr/drivers/sensor/f75303.h>
#include "f75303.h"

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)
{
int res;

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 *drv_data = dev->data;
uint16_t sample;

switch ((uint32_t)chan) {
case SENSOR_CHAN_AMBIENT_TEMP:
sample = drv_data->sample_local;
break;
case SENSOR_CHAN_F75303_REMOTE1:
sample = drv_data->sample_remote1;
break;
case SENSOR_CHAN_F75303_REMOTE2:
sample = drv_data->sample_remote2;
break;
default:
return -ENOTSUP;
}

val->val1 = sample >> 3;
val->val2 = (sample & 7) * 125000;

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 *cfg = dev->config;

if (!i2c_is_ready_dt(&cfg->i2c)) {
LOG_ERR("I2C device not ready");
return -ENODEV;
}

return 0;
}

#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), \
}; \
SENSOR_DEVICE_DT_INST_DEFINE(inst, f75303_init, NULL, &f75303_data_##inst, \
&f75303_config_##inst, POST_KERNEL, \
CONFIG_SENSOR_INIT_PRIORITY, &f75303_driver_api);

DT_INST_FOREACH_STATUS_OKAY(F75303_INST)
30 changes: 30 additions & 0 deletions drivers/sensor/f75303/f75303.h
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
114 changes: 114 additions & 0 deletions drivers/sensor/f75303/f75303_emul.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
/*
* Copyright (c) 2023 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/

#define DT_DRV_COMPAT fintek_f75303

#include <zephyr/device.h>
#include <zephyr/drivers/emul.h>
#include <zephyr/drivers/i2c.h>
#include <zephyr/drivers/i2c_emul.h>
#include <zephyr/logging/log.h>
#include "f75303.h"

LOG_MODULE_DECLARE(F75303, CONFIG_SENSOR_LOG_LEVEL);

#define NUM_REGS 128

struct f75303_emul_data {
uint8_t reg[NUM_REGS];
};

struct f75303_emul_cfg {
};

void f75303_emul_set_reg(const struct emul *target, uint8_t reg, uint8_t val)
{
struct f75303_emul_data *data = target->data;

__ASSERT_NO_MSG(reg < NUM_REGS);
data->reg[reg] = val;
}

uint8_t f75303_emul_get_reg(const struct emul *target, uint8_t reg)
{
struct f75303_emul_data *data = target->data;

__ASSERT_NO_MSG(reg < NUM_REGS);
return data->reg[reg];
}

void f75303_emul_reset(const struct emul *target)
{
struct f75303_emul_data *data = target->data;

memset(data->reg, 0, NUM_REGS);
}

static int f75303_emul_transfer_i2c(const struct emul *target, struct i2c_msg *msgs,
int num_msgs, int addr)
{
/* Largely copied from emul_bmi160.c */
unsigned int val;
int reg;

__ASSERT_NO_MSG(msgs && num_msgs);

i2c_dump_msgs_rw("emul", msgs, num_msgs, addr, false);
switch (num_msgs) {
case 2:
if (msgs->flags & I2C_MSG_READ) {
LOG_ERR("Unexpected read");
return -EIO;
}
if (msgs->len != 1) {
LOG_ERR("Unexpected msg0 length %d", msgs->len);
return -EIO;
}
reg = msgs->buf[0];

/* Now process the 'read' part of the message */
msgs++;
if (msgs->flags & I2C_MSG_READ) {
switch (msgs->len) {
case 1:
val = f75303_emul_get_reg(target, reg);
msgs->buf[0] = val;
break;
default:
LOG_ERR("Unexpected msg1 length %d", msgs->len);
return -EIO;
}
} else {
if (msgs->len != 1) {
LOG_ERR("Unexpected msg1 length %d", msgs->len);
}
f75303_emul_set_reg(target, reg, msgs->buf[0]);
}
break;
default:
LOG_ERR("Invalid number of messages: %d", num_msgs);
return -EIO;
}

return 0;
}

static int f75303_emul_init(const struct emul *target, const struct device *parent)
{
f75303_emul_reset(target);
return 0;
}

static const struct i2c_emul_api f75303_emul_api_i2c = {
.transfer = f75303_emul_transfer_i2c,
};

#define F75303_EMUL(n) \
const struct f75303_emul_cfg f75303_emul_cfg_##n; \
struct f75303_emul_data f75303_emul_data_##n; \
EMUL_DT_INST_DEFINE(n, f75303_emul_init, &f75303_emul_data_##n, \
&f75303_emul_cfg_##n, &f75303_emul_api_i2c, NULL)

DT_INST_FOREACH_STATUS_OKAY(F75303_EMUL)
17 changes: 17 additions & 0 deletions drivers/sensor/f75303/f75303_emul.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*
* Copyright (c) 2023 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/

#ifndef ZEPHYR_DRIVERS_SENSOR_F75303_F75303_EMUL_H_
#define ZEPHYR_DRIVERS_SENSOR_F75303_F75303_EMUL_H_

#include <zephyr/drivers/emul.h>

void f75303_emul_set_reg(const struct emul *target, uint8_t reg, uint8_t val);

uint8_t f75303_emul_get_reg(const struct emul *target, uint8_t reg);

void f75303_emul_reset(const struct emul *target);

#endif
10 changes: 10 additions & 0 deletions dts/bindings/sensor/fintek,f75303.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Copyright (c) 2023 Google LLC
# SPDX-License-Identifier: Apache-2.0

description: |
F75303 temperature sensor IC. This device has three temperature
channels - one local (on-chip), and two remote.
compatible: "fintek,f75303"

include: [sensor-device.yaml, i2c-device.yaml]
1 change: 1 addition & 0 deletions dts/bindings/vendor-prefixes.txt
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,7 @@ fcs Fairchild Semiconductor
feixin Shenzhen Feixin Photoelectic Co., Ltd
feiyang Shenzhen Fly Young Technology Co.,LTD.
fii Foxconn Industrial Internet
fintek Feature Integration Technology Inc.
firefly Firefly
focaltech FocalTech Systems Co.,Ltd
frida Shenzhen Frida LCD Co., Ltd.
Expand Down
Loading

0 comments on commit f05fae4

Please sign in to comment.