iio: health: max30100: Make LED pulse-width configurable via DT
The required LED pulse width depends on board-specific optical and mechanical design, which affects measurement accuracy and power use. Making it configurable via Device Tree allows each platform to define an appropriate value instead of relying on a hardcoded default. If unspecified, the driver defaults to 1600 us for backward compatibility. Tested on: Raspberry Pi 3B + MAX30100 breakout board. Reviewed-by: Nuno Sa <nuno.sa@analog.com> Signed-off-by: Shrikant Raskar <raskar.shree97@gmail.com> Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>pull/1354/merge
parent
e7966a4953
commit
6365d2b988
|
|
@ -5,7 +5,6 @@
|
|||
* Copyright (C) 2015, 2018
|
||||
* Author: Matt Ranostay <matt.ranostay@konsulko.com>
|
||||
*
|
||||
* TODO: enable pulse length controls via device tree properties
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
|
|
@ -18,6 +17,7 @@
|
|||
#include <linux/mutex.h>
|
||||
#include <linux/property.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/iio/iio.h>
|
||||
#include <linux/iio/buffer.h>
|
||||
#include <linux/iio/kfifo_buf.h>
|
||||
|
|
@ -52,9 +52,13 @@
|
|||
#define MAX30100_REG_MODE_CONFIG_PWR BIT(7)
|
||||
|
||||
#define MAX30100_REG_SPO2_CONFIG 0x07
|
||||
#define MAX30100_REG_SPO2_CONFIG_PW_MASK GENMASK(1, 0)
|
||||
#define MAX30100_REG_SPO2_CONFIG_200US 0x0
|
||||
#define MAX30100_REG_SPO2_CONFIG_400US 0x1
|
||||
#define MAX30100_REG_SPO2_CONFIG_800US 0x2
|
||||
#define MAX30100_REG_SPO2_CONFIG_1600US 0x3
|
||||
#define MAX30100_REG_SPO2_CONFIG_100HZ BIT(2)
|
||||
#define MAX30100_REG_SPO2_CONFIG_HI_RES_EN BIT(6)
|
||||
#define MAX30100_REG_SPO2_CONFIG_1600US 0x3
|
||||
|
||||
#define MAX30100_REG_LED_CONFIG 0x09
|
||||
#define MAX30100_REG_LED_CONFIG_LED_MASK 0x0f
|
||||
|
|
@ -306,19 +310,47 @@ static int max30100_led_init(struct max30100_data *data)
|
|||
MAX30100_REG_LED_CONFIG_LED_MASK, reg);
|
||||
}
|
||||
|
||||
static int max30100_get_pulse_width(unsigned int pwidth_us)
|
||||
{
|
||||
switch (pwidth_us) {
|
||||
case 200:
|
||||
return MAX30100_REG_SPO2_CONFIG_200US;
|
||||
case 400:
|
||||
return MAX30100_REG_SPO2_CONFIG_400US;
|
||||
case 800:
|
||||
return MAX30100_REG_SPO2_CONFIG_800US;
|
||||
case 1600:
|
||||
return MAX30100_REG_SPO2_CONFIG_1600US;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
static int max30100_chip_init(struct max30100_data *data)
|
||||
{
|
||||
int ret;
|
||||
int pulse_width;
|
||||
/* set default LED pulse-width to 1600 us */
|
||||
unsigned int pulse_us = 1600;
|
||||
struct device *dev = &data->client->dev;
|
||||
|
||||
/* setup LED current settings */
|
||||
ret = max30100_led_init(data);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Read LED pulse-width-us from DT */
|
||||
device_property_read_u32(dev, "maxim,pulse-width-us", &pulse_us);
|
||||
|
||||
pulse_width = max30100_get_pulse_width(pulse_us);
|
||||
if (pulse_width < 0)
|
||||
return dev_err_probe(dev, pulse_width, "invalid LED pulse-width %uus\n", pulse_us);
|
||||
|
||||
/* enable hi-res SPO2 readings at 100Hz */
|
||||
ret = regmap_write(data->regmap, MAX30100_REG_SPO2_CONFIG,
|
||||
MAX30100_REG_SPO2_CONFIG_HI_RES_EN |
|
||||
MAX30100_REG_SPO2_CONFIG_100HZ);
|
||||
MAX30100_REG_SPO2_CONFIG_100HZ |
|
||||
FIELD_PREP(MAX30100_REG_SPO2_CONFIG_PW_MASK, pulse_width));
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue