linux/drivers/iio/health/max30100.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * max30100.c - Support for MAX30100 heart rate and pulse oximeter sensor
   4 *
   5 * Copyright (C) 2015, 2018
   6 * Author: Matt Ranostay <matt.ranostay@konsulko.com>
   7 *
   8 * TODO: enable pulse length controls via device tree properties
   9 */
  10
  11#include <linux/module.h>
  12#include <linux/init.h>
  13#include <linux/interrupt.h>
  14#include <linux/delay.h>
  15#include <linux/err.h>
  16#include <linux/irq.h>
  17#include <linux/i2c.h>
  18#include <linux/mutex.h>
  19#include <linux/property.h>
  20#include <linux/regmap.h>
  21#include <linux/iio/iio.h>
  22#include <linux/iio/buffer.h>
  23#include <linux/iio/kfifo_buf.h>
  24
  25#define MAX30100_REGMAP_NAME    "max30100_regmap"
  26#define MAX30100_DRV_NAME       "max30100"
  27
  28#define MAX30100_REG_INT_STATUS                 0x00
  29#define MAX30100_REG_INT_STATUS_PWR_RDY         BIT(0)
  30#define MAX30100_REG_INT_STATUS_SPO2_RDY        BIT(4)
  31#define MAX30100_REG_INT_STATUS_HR_RDY          BIT(5)
  32#define MAX30100_REG_INT_STATUS_FIFO_RDY        BIT(7)
  33
  34#define MAX30100_REG_INT_ENABLE                 0x01
  35#define MAX30100_REG_INT_ENABLE_SPO2_EN         BIT(0)
  36#define MAX30100_REG_INT_ENABLE_HR_EN           BIT(1)
  37#define MAX30100_REG_INT_ENABLE_FIFO_EN         BIT(3)
  38#define MAX30100_REG_INT_ENABLE_MASK            0xf0
  39#define MAX30100_REG_INT_ENABLE_MASK_SHIFT      4
  40
  41#define MAX30100_REG_FIFO_WR_PTR                0x02
  42#define MAX30100_REG_FIFO_OVR_CTR               0x03
  43#define MAX30100_REG_FIFO_RD_PTR                0x04
  44#define MAX30100_REG_FIFO_DATA                  0x05
  45#define MAX30100_REG_FIFO_DATA_ENTRY_COUNT      16
  46#define MAX30100_REG_FIFO_DATA_ENTRY_LEN        4
  47
  48#define MAX30100_REG_MODE_CONFIG                0x06
  49#define MAX30100_REG_MODE_CONFIG_MODE_SPO2_EN   BIT(0)
  50#define MAX30100_REG_MODE_CONFIG_MODE_HR_EN     BIT(1)
  51#define MAX30100_REG_MODE_CONFIG_MODE_MASK      0x03
  52#define MAX30100_REG_MODE_CONFIG_TEMP_EN        BIT(3)
  53#define MAX30100_REG_MODE_CONFIG_PWR            BIT(7)
  54
  55#define MAX30100_REG_SPO2_CONFIG                0x07
  56#define MAX30100_REG_SPO2_CONFIG_100HZ          BIT(2)
  57#define MAX30100_REG_SPO2_CONFIG_HI_RES_EN      BIT(6)
  58#define MAX30100_REG_SPO2_CONFIG_1600US         0x3
  59
  60#define MAX30100_REG_LED_CONFIG                 0x09
  61#define MAX30100_REG_LED_CONFIG_LED_MASK        0x0f
  62#define MAX30100_REG_LED_CONFIG_RED_LED_SHIFT   4
  63
  64#define MAX30100_REG_LED_CONFIG_24MA            0x07
  65#define MAX30100_REG_LED_CONFIG_50MA            0x0f
  66
  67#define MAX30100_REG_TEMP_INTEGER               0x16
  68#define MAX30100_REG_TEMP_FRACTION              0x17
  69
  70struct max30100_data {
  71        struct i2c_client *client;
  72        struct iio_dev *indio_dev;
  73        struct mutex lock;
  74        struct regmap *regmap;
  75
  76        __be16 buffer[2]; /* 2 16-bit channels */
  77};
  78
  79static bool max30100_is_volatile_reg(struct device *dev, unsigned int reg)
  80{
  81        switch (reg) {
  82        case MAX30100_REG_INT_STATUS:
  83        case MAX30100_REG_MODE_CONFIG:
  84        case MAX30100_REG_FIFO_WR_PTR:
  85        case MAX30100_REG_FIFO_OVR_CTR:
  86        case MAX30100_REG_FIFO_RD_PTR:
  87        case MAX30100_REG_FIFO_DATA:
  88        case MAX30100_REG_TEMP_INTEGER:
  89        case MAX30100_REG_TEMP_FRACTION:
  90                return true;
  91        default:
  92                return false;
  93        }
  94}
  95
  96static const struct regmap_config max30100_regmap_config = {
  97        .name = MAX30100_REGMAP_NAME,
  98
  99        .reg_bits = 8,
 100        .val_bits = 8,
 101
 102        .max_register = MAX30100_REG_TEMP_FRACTION,
 103        .cache_type = REGCACHE_FLAT,
 104
 105        .volatile_reg = max30100_is_volatile_reg,
 106};
 107
 108static const unsigned int max30100_led_current_mapping[] = {
 109        4400, 7600, 11000, 14200, 17400,
 110        20800, 24000, 27100, 30600, 33800,
 111        37000, 40200, 43600, 46800, 50000
 112};
 113
 114static const unsigned long max30100_scan_masks[] = {0x3, 0};
 115
 116static const struct iio_chan_spec max30100_channels[] = {
 117        {
 118                .type = IIO_INTENSITY,
 119                .channel2 = IIO_MOD_LIGHT_IR,
 120                .modified = 1,
 121
 122                .scan_index = 0,
 123                .scan_type = {
 124                        .sign = 'u',
 125                        .realbits = 16,
 126                        .storagebits = 16,
 127                        .endianness = IIO_BE,
 128                },
 129        },
 130        {
 131                .type = IIO_INTENSITY,
 132                .channel2 = IIO_MOD_LIGHT_RED,
 133                .modified = 1,
 134
 135                .scan_index = 1,
 136                .scan_type = {
 137                        .sign = 'u',
 138                        .realbits = 16,
 139                        .storagebits = 16,
 140                        .endianness = IIO_BE,
 141                },
 142        },
 143        {
 144                .type = IIO_TEMP,
 145                .info_mask_separate =
 146                        BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
 147                .scan_index = -1,
 148        },
 149};
 150
 151static int max30100_set_powermode(struct max30100_data *data, bool state)
 152{
 153        return regmap_update_bits(data->regmap, MAX30100_REG_MODE_CONFIG,
 154                                  MAX30100_REG_MODE_CONFIG_PWR,
 155                                  state ? 0 : MAX30100_REG_MODE_CONFIG_PWR);
 156}
 157
 158static int max30100_clear_fifo(struct max30100_data *data)
 159{
 160        int ret;
 161
 162        ret = regmap_write(data->regmap, MAX30100_REG_FIFO_WR_PTR, 0);
 163        if (ret)
 164                return ret;
 165
 166        ret = regmap_write(data->regmap, MAX30100_REG_FIFO_OVR_CTR, 0);
 167        if (ret)
 168                return ret;
 169
 170        return regmap_write(data->regmap, MAX30100_REG_FIFO_RD_PTR, 0);
 171}
 172
 173static int max30100_buffer_postenable(struct iio_dev *indio_dev)
 174{
 175        struct max30100_data *data = iio_priv(indio_dev);
 176        int ret;
 177
 178        ret = max30100_set_powermode(data, true);
 179        if (ret)
 180                return ret;
 181
 182        return max30100_clear_fifo(data);
 183}
 184
 185static int max30100_buffer_predisable(struct iio_dev *indio_dev)
 186{
 187        struct max30100_data *data = iio_priv(indio_dev);
 188
 189        return max30100_set_powermode(data, false);
 190}
 191
 192static const struct iio_buffer_setup_ops max30100_buffer_setup_ops = {
 193        .postenable = max30100_buffer_postenable,
 194        .predisable = max30100_buffer_predisable,
 195};
 196
 197static inline int max30100_fifo_count(struct max30100_data *data)
 198{
 199        unsigned int val;
 200        int ret;
 201
 202        ret = regmap_read(data->regmap, MAX30100_REG_INT_STATUS, &val);
 203        if (ret)
 204                return ret;
 205
 206        /* FIFO is almost full */
 207        if (val & MAX30100_REG_INT_STATUS_FIFO_RDY)
 208                return MAX30100_REG_FIFO_DATA_ENTRY_COUNT - 1;
 209
 210        return 0;
 211}
 212
 213static int max30100_read_measurement(struct max30100_data *data)
 214{
 215        int ret;
 216
 217        ret = i2c_smbus_read_i2c_block_data(data->client,
 218                                            MAX30100_REG_FIFO_DATA,
 219                                            MAX30100_REG_FIFO_DATA_ENTRY_LEN,
 220                                            (u8 *) &data->buffer);
 221
 222        return (ret == MAX30100_REG_FIFO_DATA_ENTRY_LEN) ? 0 : ret;
 223}
 224
 225static irqreturn_t max30100_interrupt_handler(int irq, void *private)
 226{
 227        struct iio_dev *indio_dev = private;
 228        struct max30100_data *data = iio_priv(indio_dev);
 229        int ret, cnt = 0;
 230
 231        mutex_lock(&data->lock);
 232
 233        while (cnt || (cnt = max30100_fifo_count(data)) > 0) {
 234                ret = max30100_read_measurement(data);
 235                if (ret)
 236                        break;
 237
 238                iio_push_to_buffers(data->indio_dev, data->buffer);
 239                cnt--;
 240        }
 241
 242        mutex_unlock(&data->lock);
 243
 244        return IRQ_HANDLED;
 245}
 246
 247static int max30100_get_current_idx(unsigned int val, int *reg)
 248{
 249        int idx;
 250
 251        /* LED turned off */
 252        if (val == 0) {
 253                *reg = 0;
 254                return 0;
 255        }
 256
 257        for (idx = 0; idx < ARRAY_SIZE(max30100_led_current_mapping); idx++) {
 258                if (max30100_led_current_mapping[idx] == val) {
 259                        *reg = idx + 1;
 260                        return 0;
 261                }
 262        }
 263
 264        return -EINVAL;
 265}
 266
 267static int max30100_led_init(struct max30100_data *data)
 268{
 269        struct device *dev = &data->client->dev;
 270        unsigned int val[2];
 271        int reg, ret;
 272
 273        ret = device_property_read_u32_array(dev, "maxim,led-current-microamp",
 274                                        (unsigned int *) &val, 2);
 275        if (ret) {
 276                /* Default to 24 mA RED LED, 50 mA IR LED */
 277                reg = (MAX30100_REG_LED_CONFIG_24MA <<
 278                        MAX30100_REG_LED_CONFIG_RED_LED_SHIFT) |
 279                        MAX30100_REG_LED_CONFIG_50MA;
 280                dev_warn(dev, "no led-current-microamp set");
 281
 282                return regmap_write(data->regmap, MAX30100_REG_LED_CONFIG, reg);
 283        }
 284
 285        /* RED LED current */
 286        ret = max30100_get_current_idx(val[0], &reg);
 287        if (ret) {
 288                dev_err(dev, "invalid RED current setting %d", val[0]);
 289                return ret;
 290        }
 291
 292        ret = regmap_update_bits(data->regmap, MAX30100_REG_LED_CONFIG,
 293                MAX30100_REG_LED_CONFIG_LED_MASK <<
 294                MAX30100_REG_LED_CONFIG_RED_LED_SHIFT,
 295                reg << MAX30100_REG_LED_CONFIG_RED_LED_SHIFT);
 296        if (ret)
 297                return ret;
 298
 299        /* IR LED current */
 300        ret = max30100_get_current_idx(val[1], &reg);
 301        if (ret) {
 302                dev_err(dev, "invalid IR current setting %d", val[1]);
 303                return ret;
 304        }
 305
 306        return regmap_update_bits(data->regmap, MAX30100_REG_LED_CONFIG,
 307                MAX30100_REG_LED_CONFIG_LED_MASK, reg);
 308}
 309
 310static int max30100_chip_init(struct max30100_data *data)
 311{
 312        int ret;
 313
 314        /* setup LED current settings */
 315        ret = max30100_led_init(data);
 316        if (ret)
 317                return ret;
 318
 319        /* enable hi-res SPO2 readings at 100Hz */
 320        ret = regmap_write(data->regmap, MAX30100_REG_SPO2_CONFIG,
 321                                 MAX30100_REG_SPO2_CONFIG_HI_RES_EN |
 322                                 MAX30100_REG_SPO2_CONFIG_100HZ);
 323        if (ret)
 324                return ret;
 325
 326        /* enable SPO2 mode */
 327        ret = regmap_update_bits(data->regmap, MAX30100_REG_MODE_CONFIG,
 328                                 MAX30100_REG_MODE_CONFIG_MODE_MASK,
 329                                 MAX30100_REG_MODE_CONFIG_MODE_HR_EN |
 330                                 MAX30100_REG_MODE_CONFIG_MODE_SPO2_EN);
 331        if (ret)
 332                return ret;
 333
 334        /* enable FIFO interrupt */
 335        return regmap_update_bits(data->regmap, MAX30100_REG_INT_ENABLE,
 336                                 MAX30100_REG_INT_ENABLE_MASK,
 337                                 MAX30100_REG_INT_ENABLE_FIFO_EN
 338                                 << MAX30100_REG_INT_ENABLE_MASK_SHIFT);
 339}
 340
 341static int max30100_read_temp(struct max30100_data *data, int *val)
 342{
 343        int ret;
 344        unsigned int reg;
 345
 346        ret = regmap_read(data->regmap, MAX30100_REG_TEMP_INTEGER, &reg);
 347        if (ret < 0)
 348                return ret;
 349        *val = reg << 4;
 350
 351        ret = regmap_read(data->regmap, MAX30100_REG_TEMP_FRACTION, &reg);
 352        if (ret < 0)
 353                return ret;
 354
 355        *val |= reg & 0xf;
 356        *val = sign_extend32(*val, 11);
 357
 358        return 0;
 359}
 360
 361static int max30100_get_temp(struct max30100_data *data, int *val)
 362{
 363        int ret;
 364
 365        /* start acquisition */
 366        ret = regmap_update_bits(data->regmap, MAX30100_REG_MODE_CONFIG,
 367                                 MAX30100_REG_MODE_CONFIG_TEMP_EN,
 368                                 MAX30100_REG_MODE_CONFIG_TEMP_EN);
 369        if (ret)
 370                return ret;
 371
 372        msleep(35);
 373
 374        return max30100_read_temp(data, val);
 375}
 376
 377static int max30100_read_raw(struct iio_dev *indio_dev,
 378                             struct iio_chan_spec const *chan,
 379                             int *val, int *val2, long mask)
 380{
 381        struct max30100_data *data = iio_priv(indio_dev);
 382        int ret = -EINVAL;
 383
 384        switch (mask) {
 385        case IIO_CHAN_INFO_RAW:
 386                /*
 387                 * Temperature reading can only be acquired while engine
 388                 * is running
 389                 */
 390                mutex_lock(&indio_dev->mlock);
 391
 392                if (!iio_buffer_enabled(indio_dev))
 393                        ret = -EAGAIN;
 394                else {
 395                        ret = max30100_get_temp(data, val);
 396                        if (!ret)
 397                                ret = IIO_VAL_INT;
 398
 399                }
 400
 401                mutex_unlock(&indio_dev->mlock);
 402                break;
 403        case IIO_CHAN_INFO_SCALE:
 404                *val = 1;  /* 0.0625 */
 405                *val2 = 16;
 406                ret = IIO_VAL_FRACTIONAL;
 407                break;
 408        }
 409
 410        return ret;
 411}
 412
 413static const struct iio_info max30100_info = {
 414        .read_raw = max30100_read_raw,
 415};
 416
 417static int max30100_probe(struct i2c_client *client,
 418                          const struct i2c_device_id *id)
 419{
 420        struct max30100_data *data;
 421        struct iio_dev *indio_dev;
 422        int ret;
 423
 424        indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
 425        if (!indio_dev)
 426                return -ENOMEM;
 427
 428        indio_dev->name = MAX30100_DRV_NAME;
 429        indio_dev->channels = max30100_channels;
 430        indio_dev->info = &max30100_info;
 431        indio_dev->num_channels = ARRAY_SIZE(max30100_channels);
 432        indio_dev->available_scan_masks = max30100_scan_masks;
 433        indio_dev->modes = INDIO_DIRECT_MODE;
 434
 435        ret = devm_iio_kfifo_buffer_setup(&client->dev, indio_dev,
 436                                          INDIO_BUFFER_SOFTWARE,
 437                                          &max30100_buffer_setup_ops);
 438        if (ret)
 439                return ret;
 440
 441        data = iio_priv(indio_dev);
 442        data->indio_dev = indio_dev;
 443        data->client = client;
 444
 445        mutex_init(&data->lock);
 446        i2c_set_clientdata(client, indio_dev);
 447
 448        data->regmap = devm_regmap_init_i2c(client, &max30100_regmap_config);
 449        if (IS_ERR(data->regmap)) {
 450                dev_err(&client->dev, "regmap initialization failed.\n");
 451                return PTR_ERR(data->regmap);
 452        }
 453        max30100_set_powermode(data, false);
 454
 455        ret = max30100_chip_init(data);
 456        if (ret)
 457                return ret;
 458
 459        if (client->irq <= 0) {
 460                dev_err(&client->dev, "no valid irq defined\n");
 461                return -EINVAL;
 462        }
 463        ret = devm_request_threaded_irq(&client->dev, client->irq,
 464                                        NULL, max30100_interrupt_handler,
 465                                        IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
 466                                        "max30100_irq", indio_dev);
 467        if (ret) {
 468                dev_err(&client->dev, "request irq (%d) failed\n", client->irq);
 469                return ret;
 470        }
 471
 472        return iio_device_register(indio_dev);
 473}
 474
 475static int max30100_remove(struct i2c_client *client)
 476{
 477        struct iio_dev *indio_dev = i2c_get_clientdata(client);
 478        struct max30100_data *data = iio_priv(indio_dev);
 479
 480        iio_device_unregister(indio_dev);
 481        max30100_set_powermode(data, false);
 482
 483        return 0;
 484}
 485
 486static const struct i2c_device_id max30100_id[] = {
 487        { "max30100", 0 },
 488        {}
 489};
 490MODULE_DEVICE_TABLE(i2c, max30100_id);
 491
 492static const struct of_device_id max30100_dt_ids[] = {
 493        { .compatible = "maxim,max30100" },
 494        { }
 495};
 496MODULE_DEVICE_TABLE(of, max30100_dt_ids);
 497
 498static struct i2c_driver max30100_driver = {
 499        .driver = {
 500                .name   = MAX30100_DRV_NAME,
 501                .of_match_table = max30100_dt_ids,
 502        },
 503        .probe          = max30100_probe,
 504        .remove         = max30100_remove,
 505        .id_table       = max30100_id,
 506};
 507module_i2c_driver(max30100_driver);
 508
 509MODULE_AUTHOR("Matt Ranostay <matt.ranostay@konsulko.com>");
 510MODULE_DESCRIPTION("MAX30100 heart rate and pulse oximeter sensor");
 511MODULE_LICENSE("GPL");
 512