Skip to content

Commit 242477c

Browse files
committed
drivers: sensor: Add support for BH1730 ambient light sensor
Signed-off-by: Borislav Kereziev <b.kereziev@gmail.com>
1 parent ec92906 commit 242477c

File tree

6 files changed

+189
-0
lines changed

6 files changed

+189
-0
lines changed

drivers/sensor/rohm/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,5 @@
55
add_subdirectory_ifdef(CONFIG_BD8LB600FS_DIAGNOSTICS bd8lb600fs)
66
add_subdirectory_ifdef(CONFIG_BH1730 bh1730)
77
add_subdirectory_ifdef(CONFIG_BH1750 bh1750)
8+
add_subdirectory_ifdef(CONFIG_BH1790 bh1790)
89
# zephyr-keep-sorted-stop

drivers/sensor/rohm/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,5 @@
55
source "drivers/sensor/rohm/bd8lb600fs/Kconfig"
66
source "drivers/sensor/rohm/bh1730/Kconfig"
77
source "drivers/sensor/rohm/bh1750/Kconfig"
8+
source "drivers/sensor/rohm/bh1790/Kconfig"
89
# zephyr-keep-sorted-stop
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# SPDX-License-Identifier: Apache-2.0
2+
3+
zephyr_library()
4+
5+
zephyr_library_sources(bh1790.c)

drivers/sensor/rohm/bh1790/Kconfig

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# BH1790 BH1790 Optical Sensor for Heart Rate Monitor IC sensor configuration options
2+
3+
# Copyright(c) 2025 Magpie Embedded
4+
# SPDX-License-Identifier: Apache-2.0
5+
6+
config BH1790
7+
bool "BH1790 Optical Sensor for Heart Rate Monitor IC"
8+
default y
9+
depends on DT_HAS_ROHM_BH1790_ENABLED
10+
select I2C
11+
help
12+
BH1790 Optical Sensor for Heart Rate Monitor IC.

drivers/sensor/rohm/bh1790/bh1790.c

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
/*
2+
* Copyright (c) 2025, Magpie Embedded
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#define DT_DRV_COMPAT rohm_bh1790
8+
9+
#include <zephyr/drivers/sensor.h>
10+
#include <zephyr/drivers/i2c.h>
11+
#include <zephyr/logging/log.h>
12+
#include <zephyr/kernel.h>
13+
#include <zephyr/devicetree.h>
14+
#include <zephyr/sys/byteorder.h>
15+
#include <zephyr/sys/__assert.h>
16+
17+
LOG_MODULE_REGISTER(BH1790, CONFIG_SENSOR_LOG_LEVEL);
18+
19+
/* Register addresses as in the datasheet */
20+
#define BH1790_REG_ADDR_MANUFACTURER_ID (0x0F)
21+
#define BH1790_REG_ADDR_PART_ID (0x10)
22+
#define BH1790_REG_ADDR_MEASURE_CONTROL1 (0x41)
23+
#define BH1790_REG_ADDR_MEASURE_CONTROL2 (0x42)
24+
#define BH1790_REG_ADDR_MEASURE_START (0x43)
25+
#define BH1790_REG_ADDR_DATAOUT (0x54)
26+
27+
/* ID values as in the datasheet */
28+
#define BH1790_MANUFACTURER_ID (0xE0)
29+
#define BH1790_PART_ID (0x0D)
30+
31+
/* Constant value to write to registers as in the datasheet */
32+
#define BH1790_MEASURE_CONTROL_1_DEFAULT_VALUE (0x82)
33+
#define BH1790_MEASURE_CONTROL_2_DEFAULT_VALUE (0x0C)
34+
#define BH1790_MEASURE_START (0x01)
35+
36+
struct bh1790_dev_config {
37+
struct i2c_dt_spec bus;
38+
};
39+
40+
struct bh1790_data {
41+
uint16_t led_off_data;
42+
uint16_t led_on_data;
43+
};
44+
45+
static int bh1790_sample_fetch(const struct device *dev, enum sensor_channel chan)
46+
{
47+
const struct bh1790_dev_config *cfg = dev->config;
48+
struct bh1790_data *drv_data = dev->data;
49+
50+
if (chan != SENSOR_CHAN_ALL && chan != SENSOR_CHAN_GREEN && chan != SENSOR_CHAN_LIGHT) {
51+
return -ENOTSUP;
52+
}
53+
54+
uint8_t read_buffer[4];
55+
56+
const uint8_t value_read_start_address = BH1790_REG_ADDR_DATAOUT;
57+
58+
int res = i2c_write_read_dt(&cfg->bus, &value_read_start_address, 1U, read_buffer, 4U);
59+
60+
if (res < 0) {
61+
LOG_ERR("I2C error: %d", res);
62+
return -EIO;
63+
}
64+
65+
drv_data->led_off_data = sys_get_le16(&read_buffer[0]);
66+
drv_data->led_on_data = sys_get_le16(&read_buffer[2]);
67+
68+
return 0;
69+
}
70+
71+
static int bh1790_channel_get(const struct device *dev, enum sensor_channel chan,
72+
struct sensor_value *val)
73+
{
74+
struct bh1790_data *drv_data = dev->data;
75+
76+
switch (chan) {
77+
case SENSOR_CHAN_GREEN:
78+
val->val1 = drv_data->led_on_data;
79+
val->val2 = 0;
80+
break;
81+
case SENSOR_CHAN_LIGHT:
82+
val->val1 = drv_data->led_off_data;
83+
val->val2 = 0;
84+
break;
85+
default:
86+
return -ENOTSUP;
87+
}
88+
89+
return 0;
90+
}
91+
92+
static int bh1790_init(const struct device *dev)
93+
{
94+
const struct bh1790_dev_config *cfg = dev->config;
95+
96+
if (!i2c_is_ready_dt(&cfg->bus)) {
97+
LOG_ERR("I2C dev %s not ready", cfg->bus.bus->name);
98+
return -ENODEV;
99+
}
100+
101+
/* Check Manufacturer ID and Part ID as specified in the Register Map of the datasheet */
102+
uint8_t manufacturer_id_byte = 0x00;
103+
104+
if (i2c_reg_read_byte_dt(&cfg->bus, BH1790_REG_ADDR_MANUFACTURER_ID,
105+
&manufacturer_id_byte)) {
106+
LOG_ERR("Could not read manufacturer id");
107+
return -EIO;
108+
}
109+
110+
if (manufacturer_id_byte != BH1790_MANUFACTURER_ID) {
111+
LOG_ERR("Incorrect manufacturer id (%d)", manufacturer_id_byte);
112+
return -EIO;
113+
}
114+
115+
uint8_t part_id_byte = 0x00;
116+
117+
if (i2c_reg_read_byte_dt(&cfg->bus, BH1790_REG_ADDR_PART_ID, &part_id_byte)) {
118+
LOG_ERR("Could not read part id");
119+
return -EIO;
120+
}
121+
122+
if (part_id_byte != BH1790_PART_ID) {
123+
LOG_ERR("Incorrect part id (%d)", part_id_byte);
124+
return -EIO;
125+
}
126+
127+
/* Set control registers to perform measurements with default values */
128+
if (i2c_reg_write_byte_dt(&cfg->bus, BH1790_REG_ADDR_MEASURE_CONTROL1,
129+
BH1790_MEASURE_CONTROL_1_DEFAULT_VALUE)) {
130+
LOG_ERR("Could not write to MEAS_CONTROL1");
131+
return -EIO;
132+
}
133+
134+
if (i2c_reg_write_byte_dt(&cfg->bus, BH1790_REG_ADDR_MEASURE_CONTROL2,
135+
BH1790_MEASURE_CONTROL_2_DEFAULT_VALUE)) {
136+
LOG_ERR("Could not write to MEAS_CONTROL2");
137+
return -EIO;
138+
}
139+
140+
/* Trigger first measurement, additional reads triggered by sensor fetch
141+
* See Measurement Sequence in the datasheet, page 9
142+
*/
143+
if (i2c_reg_write_byte_dt(&cfg->bus, BH1790_REG_ADDR_MEASURE_START, BH1790_MEASURE_START)) {
144+
LOG_ERR("Could not start initial measurement");
145+
return -EIO;
146+
}
147+
148+
return 0;
149+
}
150+
151+
static DEVICE_API(sensor, bh1790_driver_api) = {.sample_fetch = bh1790_sample_fetch,
152+
.channel_get = bh1790_channel_get};
153+
154+
#define DEFINE_BH1790(_num) \
155+
static struct bh1790_data bh1790_data_##_num; \
156+
static const struct bh1790_dev_config bh1790_config_##_num = { \
157+
.bus = I2C_DT_SPEC_INST_GET(_num)}; \
158+
SENSOR_DEVICE_DT_INST_DEFINE(_num, bh1790_init, NULL, &bh1790_data_##_num, \
159+
&bh1790_config_##_num, POST_KERNEL, \
160+
CONFIG_SENSOR_INIT_PRIORITY, &bh1790_driver_api);
161+
162+
DT_INST_FOREACH_STATUS_OKAY(DEFINE_BH1790)

dts/bindings/sensor/rohm,bh1790.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Copyright (c) 2025, Magpie Embedded
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
description: Rohm BH1790 Optical Sensor for Heart Rate Monitor IC.
5+
6+
compatible: "rohm,bh1790"
7+
8+
include: [sensor-device.yaml, i2c-device.yaml]

0 commit comments

Comments
 (0)