644 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * max30102.c - Support for MAX30102 heart rate and pulse oximeter sensor4 *5 * Copyright (C) 2017 Matt Ranostay <matt.ranostay@konsulko.com>6 *7 * Support for MAX30105 optical particle sensor8 * Copyright (C) 2017 Peter Meerwald-Stadler <pmeerw@pmeerw.net>9 *10 * 7-bit I2C chip address: 0x5711 * TODO: proximity power saving feature12 */13 14#include <linux/module.h>15#include <linux/init.h>16#include <linux/interrupt.h>17#include <linux/delay.h>18#include <linux/err.h>19#include <linux/irq.h>20#include <linux/i2c.h>21#include <linux/mutex.h>22#include <linux/mod_devicetable.h>23#include <linux/regmap.h>24#include <linux/iio/iio.h>25#include <linux/iio/buffer.h>26#include <linux/iio/kfifo_buf.h>27 28#define MAX30102_REGMAP_NAME "max30102_regmap"29#define MAX30102_DRV_NAME "max30102"30#define MAX30102_PART_NUMBER 0x1531 32enum max30102_chip_id {33 max30102,34 max30105,35};36 37enum max3012_led_idx {38 MAX30102_LED_RED,39 MAX30102_LED_IR,40 MAX30105_LED_GREEN,41};42 43#define MAX30102_REG_INT_STATUS 0x0044#define MAX30102_REG_INT_STATUS_PWR_RDY BIT(0)45#define MAX30102_REG_INT_STATUS_PROX_INT BIT(4)46#define MAX30102_REG_INT_STATUS_ALC_OVF BIT(5)47#define MAX30102_REG_INT_STATUS_PPG_RDY BIT(6)48#define MAX30102_REG_INT_STATUS_FIFO_RDY BIT(7)49 50#define MAX30102_REG_INT_ENABLE 0x0251#define MAX30102_REG_INT_ENABLE_PROX_INT_EN BIT(4)52#define MAX30102_REG_INT_ENABLE_ALC_OVF_EN BIT(5)53#define MAX30102_REG_INT_ENABLE_PPG_EN BIT(6)54#define MAX30102_REG_INT_ENABLE_FIFO_EN BIT(7)55#define MAX30102_REG_INT_ENABLE_MASK 0xf056#define MAX30102_REG_INT_ENABLE_MASK_SHIFT 457 58#define MAX30102_REG_FIFO_WR_PTR 0x0459#define MAX30102_REG_FIFO_OVR_CTR 0x0560#define MAX30102_REG_FIFO_RD_PTR 0x0661#define MAX30102_REG_FIFO_DATA 0x0762#define MAX30102_REG_FIFO_DATA_BYTES 363 64#define MAX30102_REG_FIFO_CONFIG 0x0865#define MAX30102_REG_FIFO_CONFIG_AVG_4SAMPLES BIT(1)66#define MAX30102_REG_FIFO_CONFIG_AVG_SHIFT 567#define MAX30102_REG_FIFO_CONFIG_AFULL BIT(0)68 69#define MAX30102_REG_MODE_CONFIG 0x0970#define MAX30102_REG_MODE_CONFIG_MODE_NONE 0x0071#define MAX30102_REG_MODE_CONFIG_MODE_HR 0x02 /* red LED */72#define MAX30102_REG_MODE_CONFIG_MODE_HR_SPO2 0x03 /* red + IR LED */73#define MAX30102_REG_MODE_CONFIG_MODE_MULTI 0x07 /* multi-LED mode */74#define MAX30102_REG_MODE_CONFIG_MODE_MASK GENMASK(2, 0)75#define MAX30102_REG_MODE_CONFIG_PWR BIT(7)76 77#define MAX30102_REG_MODE_CONTROL_SLOT21 0x11 /* multi-LED control */78#define MAX30102_REG_MODE_CONTROL_SLOT43 0x1279#define MAX30102_REG_MODE_CONTROL_SLOT_MASK (GENMASK(6, 4) | GENMASK(2, 0))80#define MAX30102_REG_MODE_CONTROL_SLOT_SHIFT 481 82#define MAX30102_REG_SPO2_CONFIG 0x0a83#define MAX30102_REG_SPO2_CONFIG_PULSE_411_US 0x0384#define MAX30102_REG_SPO2_CONFIG_SR_400HZ 0x0385#define MAX30102_REG_SPO2_CONFIG_SR_MASK 0x0786#define MAX30102_REG_SPO2_CONFIG_SR_MASK_SHIFT 287#define MAX30102_REG_SPO2_CONFIG_ADC_4096_STEPS BIT(0)88#define MAX30102_REG_SPO2_CONFIG_ADC_MASK_SHIFT 589 90#define MAX30102_REG_RED_LED_CONFIG 0x0c91#define MAX30102_REG_IR_LED_CONFIG 0x0d92#define MAX30105_REG_GREEN_LED_CONFIG 0x0e93 94#define MAX30102_REG_TEMP_CONFIG 0x2195#define MAX30102_REG_TEMP_CONFIG_TEMP_EN BIT(0)96 97#define MAX30102_REG_TEMP_INTEGER 0x1f98#define MAX30102_REG_TEMP_FRACTION 0x2099 100#define MAX30102_REG_REV_ID 0xfe101#define MAX30102_REG_PART_ID 0xff102 103struct max30102_data {104 struct i2c_client *client;105 struct iio_dev *indio_dev;106 struct mutex lock;107 struct regmap *regmap;108 enum max30102_chip_id chip_id;109 110 u8 buffer[12];111 __be32 processed_buffer[3]; /* 3 x 18-bit (padded to 32-bits) */112};113 114static const struct regmap_config max30102_regmap_config = {115 .name = MAX30102_REGMAP_NAME,116 117 .reg_bits = 8,118 .val_bits = 8,119};120 121static const unsigned long max30102_scan_masks[] = {122 BIT(MAX30102_LED_RED) | BIT(MAX30102_LED_IR),123 0124};125 126static const unsigned long max30105_scan_masks[] = {127 BIT(MAX30102_LED_RED) | BIT(MAX30102_LED_IR),128 BIT(MAX30102_LED_RED) | BIT(MAX30102_LED_IR) |129 BIT(MAX30105_LED_GREEN),130 0131};132 133#define MAX30102_INTENSITY_CHANNEL(_si, _mod) { \134 .type = IIO_INTENSITY, \135 .channel2 = _mod, \136 .modified = 1, \137 .scan_index = _si, \138 .scan_type = { \139 .sign = 'u', \140 .shift = 8, \141 .realbits = 18, \142 .storagebits = 32, \143 .endianness = IIO_BE, \144 }, \145 }146 147static const struct iio_chan_spec max30102_channels[] = {148 MAX30102_INTENSITY_CHANNEL(MAX30102_LED_RED, IIO_MOD_LIGHT_RED),149 MAX30102_INTENSITY_CHANNEL(MAX30102_LED_IR, IIO_MOD_LIGHT_IR),150 {151 .type = IIO_TEMP,152 .info_mask_separate =153 BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),154 .scan_index = -1,155 },156};157 158static const struct iio_chan_spec max30105_channels[] = {159 MAX30102_INTENSITY_CHANNEL(MAX30102_LED_RED, IIO_MOD_LIGHT_RED),160 MAX30102_INTENSITY_CHANNEL(MAX30102_LED_IR, IIO_MOD_LIGHT_IR),161 MAX30102_INTENSITY_CHANNEL(MAX30105_LED_GREEN, IIO_MOD_LIGHT_GREEN),162 {163 .type = IIO_TEMP,164 .info_mask_separate =165 BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),166 .scan_index = -1,167 },168};169 170static int max30102_set_power(struct max30102_data *data, bool en)171{172 return regmap_update_bits(data->regmap, MAX30102_REG_MODE_CONFIG,173 MAX30102_REG_MODE_CONFIG_PWR,174 en ? 0 : MAX30102_REG_MODE_CONFIG_PWR);175}176 177static int max30102_set_powermode(struct max30102_data *data, u8 mode, bool en)178{179 u8 reg = mode;180 181 if (!en)182 reg |= MAX30102_REG_MODE_CONFIG_PWR;183 184 return regmap_update_bits(data->regmap, MAX30102_REG_MODE_CONFIG,185 MAX30102_REG_MODE_CONFIG_PWR |186 MAX30102_REG_MODE_CONFIG_MODE_MASK, reg);187}188 189#define MAX30102_MODE_CONTROL_LED_SLOTS(slot2, slot1) \190 ((slot2 << MAX30102_REG_MODE_CONTROL_SLOT_SHIFT) | slot1)191 192static int max30102_buffer_postenable(struct iio_dev *indio_dev)193{194 struct max30102_data *data = iio_priv(indio_dev);195 int ret;196 u8 reg;197 198 switch (*indio_dev->active_scan_mask) {199 case BIT(MAX30102_LED_RED) | BIT(MAX30102_LED_IR):200 reg = MAX30102_REG_MODE_CONFIG_MODE_HR_SPO2;201 break;202 case BIT(MAX30102_LED_RED) | BIT(MAX30102_LED_IR) |203 BIT(MAX30105_LED_GREEN):204 ret = regmap_update_bits(data->regmap,205 MAX30102_REG_MODE_CONTROL_SLOT21,206 MAX30102_REG_MODE_CONTROL_SLOT_MASK,207 MAX30102_MODE_CONTROL_LED_SLOTS(2, 1));208 if (ret)209 return ret;210 211 ret = regmap_update_bits(data->regmap,212 MAX30102_REG_MODE_CONTROL_SLOT43,213 MAX30102_REG_MODE_CONTROL_SLOT_MASK,214 MAX30102_MODE_CONTROL_LED_SLOTS(0, 3));215 if (ret)216 return ret;217 218 reg = MAX30102_REG_MODE_CONFIG_MODE_MULTI;219 break;220 default:221 return -EINVAL;222 }223 224 return max30102_set_powermode(data, reg, true);225}226 227static int max30102_buffer_predisable(struct iio_dev *indio_dev)228{229 struct max30102_data *data = iio_priv(indio_dev);230 231 return max30102_set_powermode(data, MAX30102_REG_MODE_CONFIG_MODE_NONE,232 false);233}234 235static const struct iio_buffer_setup_ops max30102_buffer_setup_ops = {236 .postenable = max30102_buffer_postenable,237 .predisable = max30102_buffer_predisable,238};239 240static inline int max30102_fifo_count(struct max30102_data *data)241{242 unsigned int val;243 int ret;244 245 ret = regmap_read(data->regmap, MAX30102_REG_INT_STATUS, &val);246 if (ret)247 return ret;248 249 /* FIFO has one sample slot left */250 if (val & MAX30102_REG_INT_STATUS_FIFO_RDY)251 return 1;252 253 return 0;254}255 256#define MAX30102_COPY_DATA(i) \257 memcpy(&data->processed_buffer[(i)], \258 &buffer[(i) * MAX30102_REG_FIFO_DATA_BYTES], \259 MAX30102_REG_FIFO_DATA_BYTES)260 261static int max30102_read_measurement(struct max30102_data *data,262 unsigned int measurements)263{264 int ret;265 u8 *buffer = (u8 *) &data->buffer;266 267 ret = i2c_smbus_read_i2c_block_data(data->client,268 MAX30102_REG_FIFO_DATA,269 measurements *270 MAX30102_REG_FIFO_DATA_BYTES,271 buffer);272 273 switch (measurements) {274 case 3:275 MAX30102_COPY_DATA(2);276 fallthrough;277 case 2:278 MAX30102_COPY_DATA(1);279 fallthrough;280 case 1:281 MAX30102_COPY_DATA(0);282 break;283 default:284 return -EINVAL;285 }286 287 return (ret == measurements * MAX30102_REG_FIFO_DATA_BYTES) ?288 0 : -EINVAL;289}290 291static irqreturn_t max30102_interrupt_handler(int irq, void *private)292{293 struct iio_dev *indio_dev = private;294 struct max30102_data *data = iio_priv(indio_dev);295 unsigned int measurements = bitmap_weight(indio_dev->active_scan_mask,296 iio_get_masklength(indio_dev));297 int ret, cnt = 0;298 299 mutex_lock(&data->lock);300 301 while (cnt || (cnt = max30102_fifo_count(data)) > 0) {302 ret = max30102_read_measurement(data, measurements);303 if (ret)304 break;305 306 iio_push_to_buffers(data->indio_dev, data->processed_buffer);307 cnt--;308 }309 310 mutex_unlock(&data->lock);311 312 return IRQ_HANDLED;313}314 315static int max30102_get_current_idx(unsigned int val, int *reg)316{317 /* each step is 0.200 mA */318 *reg = val / 200;319 320 return *reg > 0xff ? -EINVAL : 0;321}322 323static int max30102_led_init(struct max30102_data *data)324{325 struct device *dev = &data->client->dev;326 unsigned int val;327 int reg, ret;328 329 ret = device_property_read_u32(dev, "maxim,red-led-current-microamp", &val);330 if (ret) {331 dev_info(dev, "no red-led-current-microamp set\n");332 333 /* Default to 7 mA RED LED */334 val = 7000;335 }336 337 ret = max30102_get_current_idx(val, ®);338 if (ret) {339 dev_err(dev, "invalid RED LED current setting %d\n", val);340 return ret;341 }342 343 ret = regmap_write(data->regmap, MAX30102_REG_RED_LED_CONFIG, reg);344 if (ret)345 return ret;346 347 if (data->chip_id == max30105) {348 ret = device_property_read_u32(dev,349 "maxim,green-led-current-microamp", &val);350 if (ret) {351 dev_info(dev, "no green-led-current-microamp set\n");352 353 /* Default to 7 mA green LED */354 val = 7000;355 }356 357 ret = max30102_get_current_idx(val, ®);358 if (ret) {359 dev_err(dev, "invalid green LED current setting %d\n",360 val);361 return ret;362 }363 364 ret = regmap_write(data->regmap, MAX30105_REG_GREEN_LED_CONFIG,365 reg);366 if (ret)367 return ret;368 }369 370 ret = device_property_read_u32(dev, "maxim,ir-led-current-microamp", &val);371 if (ret) {372 dev_info(dev, "no ir-led-current-microamp set\n");373 374 /* Default to 7 mA IR LED */375 val = 7000;376 }377 378 ret = max30102_get_current_idx(val, ®);379 if (ret) {380 dev_err(dev, "invalid IR LED current setting %d\n", val);381 return ret;382 }383 384 return regmap_write(data->regmap, MAX30102_REG_IR_LED_CONFIG, reg);385}386 387static int max30102_chip_init(struct max30102_data *data)388{389 int ret;390 391 /* setup LED current settings */392 ret = max30102_led_init(data);393 if (ret)394 return ret;395 396 /* configure 18-bit HR + SpO2 readings at 400Hz */397 ret = regmap_write(data->regmap, MAX30102_REG_SPO2_CONFIG,398 (MAX30102_REG_SPO2_CONFIG_ADC_4096_STEPS399 << MAX30102_REG_SPO2_CONFIG_ADC_MASK_SHIFT) |400 (MAX30102_REG_SPO2_CONFIG_SR_400HZ401 << MAX30102_REG_SPO2_CONFIG_SR_MASK_SHIFT) |402 MAX30102_REG_SPO2_CONFIG_PULSE_411_US);403 if (ret)404 return ret;405 406 /* average 4 samples + generate FIFO interrupt */407 ret = regmap_write(data->regmap, MAX30102_REG_FIFO_CONFIG,408 (MAX30102_REG_FIFO_CONFIG_AVG_4SAMPLES409 << MAX30102_REG_FIFO_CONFIG_AVG_SHIFT) |410 MAX30102_REG_FIFO_CONFIG_AFULL);411 if (ret)412 return ret;413 414 /* enable FIFO interrupt */415 return regmap_update_bits(data->regmap, MAX30102_REG_INT_ENABLE,416 MAX30102_REG_INT_ENABLE_MASK,417 MAX30102_REG_INT_ENABLE_FIFO_EN);418}419 420static int max30102_read_temp(struct max30102_data *data, int *val)421{422 int ret;423 unsigned int reg;424 425 ret = regmap_read(data->regmap, MAX30102_REG_TEMP_INTEGER, ®);426 if (ret < 0)427 return ret;428 *val = reg << 4;429 430 ret = regmap_read(data->regmap, MAX30102_REG_TEMP_FRACTION, ®);431 if (ret < 0)432 return ret;433 434 *val |= reg & 0xf;435 *val = sign_extend32(*val, 11);436 437 return 0;438}439 440static int max30102_get_temp(struct max30102_data *data, int *val, bool en)441{442 int ret;443 444 if (en) {445 ret = max30102_set_power(data, true);446 if (ret)447 return ret;448 }449 450 /* start acquisition */451 ret = regmap_set_bits(data->regmap, MAX30102_REG_TEMP_CONFIG,452 MAX30102_REG_TEMP_CONFIG_TEMP_EN);453 if (ret)454 goto out;455 456 msleep(35);457 ret = max30102_read_temp(data, val);458 459out:460 if (en)461 max30102_set_power(data, false);462 463 return ret;464}465 466static int max30102_read_raw(struct iio_dev *indio_dev,467 struct iio_chan_spec const *chan,468 int *val, int *val2, long mask)469{470 struct max30102_data *data = iio_priv(indio_dev);471 int ret = -EINVAL;472 473 switch (mask) {474 case IIO_CHAN_INFO_RAW:475 /*476 * Temperature reading can only be acquired when not in477 * shutdown; leave shutdown briefly when buffer not running478 */479any_mode_retry:480 if (iio_device_claim_buffer_mode(indio_dev)) {481 /*482 * This one is a *bit* hacky. If we cannot claim buffer483 * mode, then try direct mode so that we make sure484 * things cannot concurrently change. And we just keep485 * trying until we get one of the modes...486 */487 if (iio_device_claim_direct_mode(indio_dev))488 goto any_mode_retry;489 490 ret = max30102_get_temp(data, val, true);491 iio_device_release_direct_mode(indio_dev);492 } else {493 ret = max30102_get_temp(data, val, false);494 iio_device_release_buffer_mode(indio_dev);495 }496 if (ret)497 return ret;498 499 ret = IIO_VAL_INT;500 break;501 case IIO_CHAN_INFO_SCALE:502 *val = 1000; /* 62.5 */503 *val2 = 16;504 ret = IIO_VAL_FRACTIONAL;505 break;506 }507 508 return ret;509}510 511static const struct iio_info max30102_info = {512 .read_raw = max30102_read_raw,513};514 515static int max30102_probe(struct i2c_client *client)516{517 const struct i2c_device_id *id = i2c_client_get_device_id(client);518 struct max30102_data *data;519 struct iio_dev *indio_dev;520 int ret;521 unsigned int reg;522 523 indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));524 if (!indio_dev)525 return -ENOMEM;526 527 indio_dev->name = MAX30102_DRV_NAME;528 indio_dev->info = &max30102_info;529 indio_dev->modes = INDIO_DIRECT_MODE;530 531 data = iio_priv(indio_dev);532 data->indio_dev = indio_dev;533 data->client = client;534 data->chip_id = id->driver_data;535 536 mutex_init(&data->lock);537 i2c_set_clientdata(client, indio_dev);538 539 switch (data->chip_id) {540 case max30105:541 indio_dev->channels = max30105_channels;542 indio_dev->num_channels = ARRAY_SIZE(max30105_channels);543 indio_dev->available_scan_masks = max30105_scan_masks;544 break;545 case max30102:546 indio_dev->channels = max30102_channels;547 indio_dev->num_channels = ARRAY_SIZE(max30102_channels);548 indio_dev->available_scan_masks = max30102_scan_masks;549 break;550 default:551 return -ENODEV;552 }553 554 ret = devm_iio_kfifo_buffer_setup(&client->dev, indio_dev,555 &max30102_buffer_setup_ops);556 if (ret)557 return ret;558 559 data->regmap = devm_regmap_init_i2c(client, &max30102_regmap_config);560 if (IS_ERR(data->regmap)) {561 dev_err(&client->dev, "regmap initialization failed\n");562 return PTR_ERR(data->regmap);563 }564 565 /* check part ID */566 ret = regmap_read(data->regmap, MAX30102_REG_PART_ID, ®);567 if (ret)568 return ret;569 if (reg != MAX30102_PART_NUMBER)570 return -ENODEV;571 572 /* show revision ID */573 ret = regmap_read(data->regmap, MAX30102_REG_REV_ID, ®);574 if (ret)575 return ret;576 dev_dbg(&client->dev, "max3010x revision %02x\n", reg);577 578 /* clear mode setting, chip shutdown */579 ret = max30102_set_powermode(data, MAX30102_REG_MODE_CONFIG_MODE_NONE,580 false);581 if (ret)582 return ret;583 584 ret = max30102_chip_init(data);585 if (ret)586 return ret;587 588 if (client->irq <= 0) {589 dev_err(&client->dev, "no valid irq defined\n");590 return -EINVAL;591 }592 593 ret = devm_request_threaded_irq(&client->dev, client->irq,594 NULL, max30102_interrupt_handler,595 IRQF_TRIGGER_FALLING | IRQF_ONESHOT,596 "max30102_irq", indio_dev);597 if (ret) {598 dev_err(&client->dev, "request irq (%d) failed\n", client->irq);599 return ret;600 }601 602 return iio_device_register(indio_dev);603}604 605static void max30102_remove(struct i2c_client *client)606{607 struct iio_dev *indio_dev = i2c_get_clientdata(client);608 struct max30102_data *data = iio_priv(indio_dev);609 610 iio_device_unregister(indio_dev);611 max30102_set_power(data, false);612}613 614static const struct i2c_device_id max30102_id[] = {615 { "max30101", max30105 },616 { "max30102", max30102 },617 { "max30105", max30105 },618 {}619};620MODULE_DEVICE_TABLE(i2c, max30102_id);621 622static const struct of_device_id max30102_dt_ids[] = {623 { .compatible = "maxim,max30101" },624 { .compatible = "maxim,max30102" },625 { .compatible = "maxim,max30105" },626 { }627};628MODULE_DEVICE_TABLE(of, max30102_dt_ids);629 630static struct i2c_driver max30102_driver = {631 .driver = {632 .name = MAX30102_DRV_NAME,633 .of_match_table = max30102_dt_ids,634 },635 .probe = max30102_probe,636 .remove = max30102_remove,637 .id_table = max30102_id,638};639module_i2c_driver(max30102_driver);640 641MODULE_AUTHOR("Matt Ranostay <matt.ranostay@konsulko.com>");642MODULE_DESCRIPTION("MAX30102 heart rate/pulse oximeter and MAX30105 particle sensor driver");643MODULE_LICENSE("GPL");644