Skip to content

drivers: sensor: bmm350: add default odr/osr from dts and attr_get api #90078

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

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
141 changes: 133 additions & 8 deletions drivers/sensor/bosch/bmm350/bmm350.c
Original file line number Diff line number Diff line change
Expand Up @@ -676,7 +676,8 @@ static int bmm350_channel_get(const struct device *dev, enum sensor_channel chan

return 0;
}
static uint8_t acc_odr_to_reg(const struct sensor_value *val)

static uint8_t mag_odr_to_reg(const struct sensor_value *val)
{
double odr = sensor_value_to_double((struct sensor_value *)val);

Expand Down Expand Up @@ -706,10 +707,10 @@ static uint8_t acc_odr_to_reg(const struct sensor_value *val)
return reg;
}

static uint8_t acc_osr_to_reg(const struct sensor_value *val)
static uint8_t mag_osr_to_reg(const struct sensor_value *val)
{
switch (val->val1) {
case 0:
case 1:
return BMM350_NO_AVERAGING;
case 2:
return BMM350_AVERAGING_2;
Expand Down Expand Up @@ -767,6 +768,7 @@ int8_t bmm350_set_odr_performance(enum bmm350_data_rates odr,

return rslt;
}

static int set_mag_odr_osr(const struct device *dev, const struct sensor_value *odr,
const struct sensor_value *osr)
{
Expand All @@ -792,10 +794,10 @@ static int set_mag_odr_osr(const struct device *dev, const struct sensor_value *
}

if (odr) {
odr_bits = acc_odr_to_reg(odr);
odr_bits = mag_odr_to_reg(odr);
}
if (osr) {
osr_bits = acc_osr_to_reg(osr);
osr_bits = mag_osr_to_reg(osr);
if (osr_bits == 0xFF) {
LOG_ERR("unsupported oversampling rate");
return -EINVAL;
Expand Down Expand Up @@ -836,8 +838,125 @@ static int bmm350_attr_set(const struct device *dev, enum sensor_channel chan,

return 0;
}

void mag_reg_to_odr(uint8_t bits, struct sensor_value *val)
{
switch (bits) {
case BMM350_DATA_RATE_1_5625HZ:
val->val1 = 1;
val->val2 = 562500;
break;
case BMM350_DATA_RATE_3_125HZ:
val->val1 = 3;
val->val2 = 125000;
break;
case BMM350_DATA_RATE_6_25HZ:
val->val1 = 6;
val->val2 = 250000;
break;
case BMM350_DATA_RATE_12_5HZ:
val->val1 = 12;
val->val2 = 500000;
break;
case BMM350_DATA_RATE_25HZ:
val->val1 = 25;
val->val2 = 0;
break;
case BMM350_DATA_RATE_50HZ:
val->val1 = 50;
val->val2 = 0;
break;
case BMM350_DATA_RATE_100HZ:
val->val1 = 100;
val->val2 = 0;
break;
case BMM350_DATA_RATE_200HZ:
val->val1 = 200;
val->val2 = 0;
break;
case BMM350_DATA_RATE_400HZ:
val->val1 = 400;
val->val2 = 0;
break;
default:
val->val1 = 0;
val->val2 = 0;
break;
}
}

void mag_reg_to_osr(uint8_t bits, struct sensor_value *val)
{
val->val2 = 0;

switch (bits) {
case BMM350_NO_AVERAGING:
val->val1 = 1;
break;
case BMM350_AVERAGING_2:
val->val1 = 2;
break;
case BMM350_AVERAGING_4:
val->val1 = 4;
break;
case BMM350_AVERAGING_8:
val->val1 = 8;
break;
default:
val->val1 = 0;
break;
}
}

static int get_mag_odr_osr(const struct device *dev, struct sensor_value *odr,
struct sensor_value *osr)
{
int ret;
uint8_t rx_buf[3] = {0x00};
uint8_t osr_bits;
uint8_t odr_bits;

/* read current state */
ret = bmm350_reg_read(dev, BMM350_REG_PMU_CMD_AGGR_SET, &rx_buf[0], 3);
if (ret < 0) {
LOG_ERR("failed to read PMU_CMD_AGGR_SET");
return -EIO;
}
osr_bits = ((rx_buf[2] & BMM350_AVG_MSK) >> BMM350_AVG_POS);
odr_bits = ((rx_buf[2] & BMM350_ODR_MSK) >> BMM350_ODR_POS);

if (odr) {
mag_reg_to_odr(odr_bits, odr);
}
if (osr) {
mag_reg_to_osr(osr_bits, osr);
}

return 0;
}

static int bmm350_attr_get(const struct device *dev, enum sensor_channel chan,
enum sensor_attribute attr, struct sensor_value *val)
{
int ret;

switch (attr) {
case SENSOR_ATTR_SAMPLING_FREQUENCY:
ret = get_mag_odr_osr(dev, val, NULL);
break;
case SENSOR_ATTR_OVERSAMPLING:
ret = get_mag_odr_osr(dev, NULL, val);
break;
default:
ret = -EINVAL;
}

return ret;
}

static DEVICE_API(sensor, bmm350_api_funcs) = {
.attr_set = bmm350_attr_set,
.attr_get = bmm350_attr_get,
.sample_fetch = bmm350_sample_fetch,
.channel_get = bmm350_channel_get,
#ifdef CONFIG_BMM350_TRIGGER
Expand Down Expand Up @@ -934,9 +1053,12 @@ static int pm_action(const struct device *dev, enum pm_device_action action)
static int bmm350_init(const struct device *dev)
{
int err = 0;
const struct bmm350_config *config = dev->config;
struct bmm350_data *data = dev->data;
const struct sensor_value odr = {100, 0};
const struct sensor_value osr = {2, 0};
const struct sensor_value osr = {config->default_osr, 0};
struct sensor_value odr;

mag_reg_to_odr(config->default_odr, &odr);

err = bmm350_bus_check(dev);
if (err < 0) {
Expand All @@ -959,8 +1081,9 @@ static int bmm350_init(const struct device *dev)
/* Assign axis_en with all axis enabled (BMM350_EN_XYZ_MSK) */
data->axis_en = BMM350_EN_XYZ_MSK;

/* Initialize to 100Hz, averaging between 2 samples by default */
/* Initialize to odr and osr */
if (set_mag_odr_osr(dev, &odr, &osr) < 0) {
LOG_ERR("failed to set default odr and osr");
return -EIO;
}

Expand All @@ -976,6 +1099,8 @@ static int bmm350_init(const struct device *dev)
static const struct bmm350_config bmm350_config_##inst = { \
.bus.i2c = I2C_DT_SPEC_INST_GET(inst), \
.bus_io = &bmm350_bus_io_i2c, \
.default_odr = DT_INST_ENUM_IDX(inst, odr) + BMM350_DATA_RATE_400HZ, \
.default_osr = DT_INST_PROP(inst, osr), \
BMM350_INT_CFG(inst)}; \
\
PM_DEVICE_DT_INST_DEFINE(inst, pm_action); \
Expand Down
2 changes: 2 additions & 0 deletions drivers/sensor/bosch/bmm350/bmm350.h
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,8 @@ struct bmm350_config {
struct bmm350_bus bus;
const struct bmm350_bus_io *bus_io;
struct gpio_dt_spec drdy_int;
uint8_t default_odr;
uint8_t default_osr;
};

struct bmm350_data {
Expand Down
40 changes: 40 additions & 0 deletions dts/bindings/sensor/bosch,bmm350.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,43 @@ properties:
description: |
This property specifies the connection for data ready pin.
The polarity default is active high when sensor data is ready.

odr:
type: string
description: |
Default output data rate in Hz. Only the following values are allowed:
400 - 400 - 2.5ms
200 - 200 - 5ms
100 - 100 - 10ms
50 - 50 - 20ms
25 - 25 - 40ms
12.5 - 25/2 - 80ms
6.25 - 25/4 - 160ms
3.125 - 25/8 - 320ms
1.5625 - 25/16 - 640ms
default: "100"
enum:
- "400"
- "200"
- "100"
- "50"
- "25"
- "12.5"
- "6.25"
- "3.125"
- "1.5625"

osr:
type: int
description: |
Default oversampling. Only the following values are allowed:
8 - 8x
4 - 4x
2 - 2x
1 - 1x
default: 2
enum:
- 1
- 2
- 4
- 8