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