595 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * AFE4403 Heart Rate Monitors and Low-Cost Pulse Oximeters4 *5 * Copyright (C) 2015-2016 Texas Instruments Incorporated - https://www.ti.com/6 * Andrew F. Davis <afd@ti.com>7 */8 9#include <linux/device.h>10#include <linux/err.h>11#include <linux/interrupt.h>12#include <linux/kernel.h>13#include <linux/module.h>14#include <linux/regmap.h>15#include <linux/spi/spi.h>16#include <linux/sysfs.h>17#include <linux/regulator/consumer.h>18 19#include <linux/iio/iio.h>20#include <linux/iio/sysfs.h>21#include <linux/iio/buffer.h>22#include <linux/iio/trigger.h>23#include <linux/iio/triggered_buffer.h>24#include <linux/iio/trigger_consumer.h>25 26#include <linux/unaligned.h>27 28#include "afe440x.h"29 30#define AFE4403_DRIVER_NAME "afe4403"31 32/* AFE4403 Registers */33#define AFE4403_TIAGAIN 0x2034#define AFE4403_TIA_AMB_GAIN 0x2135 36enum afe4403_fields {37 /* Gains */38 F_RF_LED1, F_CF_LED1,39 F_RF_LED, F_CF_LED,40 41 /* LED Current */42 F_ILED1, F_ILED2,43 44 /* sentinel */45 F_MAX_FIELDS46};47 48static const struct reg_field afe4403_reg_fields[] = {49 /* Gains */50 [F_RF_LED1] = REG_FIELD(AFE4403_TIAGAIN, 0, 2),51 [F_CF_LED1] = REG_FIELD(AFE4403_TIAGAIN, 3, 7),52 [F_RF_LED] = REG_FIELD(AFE4403_TIA_AMB_GAIN, 0, 2),53 [F_CF_LED] = REG_FIELD(AFE4403_TIA_AMB_GAIN, 3, 7),54 /* LED Current */55 [F_ILED1] = REG_FIELD(AFE440X_LEDCNTRL, 0, 7),56 [F_ILED2] = REG_FIELD(AFE440X_LEDCNTRL, 8, 15),57};58 59/**60 * struct afe4403_data - AFE4403 device instance data61 * @dev: Device structure62 * @spi: SPI device handle63 * @regmap: Register map of the device64 * @fields: Register fields of the device65 * @regulator: Pointer to the regulator for the IC66 * @trig: IIO trigger for this device67 * @irq: ADC_RDY line interrupt number68 * @buffer: Used to construct data layout to push into IIO buffer.69 */70struct afe4403_data {71 struct device *dev;72 struct spi_device *spi;73 struct regmap *regmap;74 struct regmap_field *fields[F_MAX_FIELDS];75 struct regulator *regulator;76 struct iio_trigger *trig;77 int irq;78 /* Ensure suitable alignment for timestamp */79 s32 buffer[8] __aligned(8);80};81 82enum afe4403_chan_id {83 LED2 = 1,84 ALED2,85 LED1,86 ALED1,87 LED2_ALED2,88 LED1_ALED1,89};90 91static const unsigned int afe4403_channel_values[] = {92 [LED2] = AFE440X_LED2VAL,93 [ALED2] = AFE440X_ALED2VAL,94 [LED1] = AFE440X_LED1VAL,95 [ALED1] = AFE440X_ALED1VAL,96 [LED2_ALED2] = AFE440X_LED2_ALED2VAL,97 [LED1_ALED1] = AFE440X_LED1_ALED1VAL,98};99 100static const unsigned int afe4403_channel_leds[] = {101 [LED2] = F_ILED2,102 [LED1] = F_ILED1,103};104 105static const struct iio_chan_spec afe4403_channels[] = {106 /* ADC values */107 AFE440X_INTENSITY_CHAN(LED2, 0),108 AFE440X_INTENSITY_CHAN(ALED2, 0),109 AFE440X_INTENSITY_CHAN(LED1, 0),110 AFE440X_INTENSITY_CHAN(ALED1, 0),111 AFE440X_INTENSITY_CHAN(LED2_ALED2, 0),112 AFE440X_INTENSITY_CHAN(LED1_ALED1, 0),113 /* LED current */114 AFE440X_CURRENT_CHAN(LED2),115 AFE440X_CURRENT_CHAN(LED1),116};117 118static const struct afe440x_val_table afe4403_res_table[] = {119 { 500000 }, { 250000 }, { 100000 }, { 50000 },120 { 25000 }, { 10000 }, { 1000000 }, { 0 },121};122AFE440X_TABLE_ATTR(in_intensity_resistance_available, afe4403_res_table);123 124static const struct afe440x_val_table afe4403_cap_table[] = {125 { 0, 5000 }, { 0, 10000 }, { 0, 20000 }, { 0, 25000 },126 { 0, 30000 }, { 0, 35000 }, { 0, 45000 }, { 0, 50000 },127 { 0, 55000 }, { 0, 60000 }, { 0, 70000 }, { 0, 75000 },128 { 0, 80000 }, { 0, 85000 }, { 0, 95000 }, { 0, 100000 },129 { 0, 155000 }, { 0, 160000 }, { 0, 170000 }, { 0, 175000 },130 { 0, 180000 }, { 0, 185000 }, { 0, 195000 }, { 0, 200000 },131 { 0, 205000 }, { 0, 210000 }, { 0, 220000 }, { 0, 225000 },132 { 0, 230000 }, { 0, 235000 }, { 0, 245000 }, { 0, 250000 },133};134AFE440X_TABLE_ATTR(in_intensity_capacitance_available, afe4403_cap_table);135 136static ssize_t afe440x_show_register(struct device *dev,137 struct device_attribute *attr,138 char *buf)139{140 struct iio_dev *indio_dev = dev_to_iio_dev(dev);141 struct afe4403_data *afe = iio_priv(indio_dev);142 struct afe440x_attr *afe440x_attr = to_afe440x_attr(attr);143 unsigned int reg_val;144 int vals[2];145 int ret;146 147 ret = regmap_field_read(afe->fields[afe440x_attr->field], ®_val);148 if (ret)149 return ret;150 151 if (reg_val >= afe440x_attr->table_size)152 return -EINVAL;153 154 vals[0] = afe440x_attr->val_table[reg_val].integer;155 vals[1] = afe440x_attr->val_table[reg_val].fract;156 157 return iio_format_value(buf, IIO_VAL_INT_PLUS_MICRO, 2, vals);158}159 160static ssize_t afe440x_store_register(struct device *dev,161 struct device_attribute *attr,162 const char *buf, size_t count)163{164 struct iio_dev *indio_dev = dev_to_iio_dev(dev);165 struct afe4403_data *afe = iio_priv(indio_dev);166 struct afe440x_attr *afe440x_attr = to_afe440x_attr(attr);167 int val, integer, fract, ret;168 169 ret = iio_str_to_fixpoint(buf, 100000, &integer, &fract);170 if (ret)171 return ret;172 173 for (val = 0; val < afe440x_attr->table_size; val++)174 if (afe440x_attr->val_table[val].integer == integer &&175 afe440x_attr->val_table[val].fract == fract)176 break;177 if (val == afe440x_attr->table_size)178 return -EINVAL;179 180 ret = regmap_field_write(afe->fields[afe440x_attr->field], val);181 if (ret)182 return ret;183 184 return count;185}186 187static AFE440X_ATTR(in_intensity1_resistance, F_RF_LED, afe4403_res_table);188static AFE440X_ATTR(in_intensity1_capacitance, F_CF_LED, afe4403_cap_table);189 190static AFE440X_ATTR(in_intensity2_resistance, F_RF_LED, afe4403_res_table);191static AFE440X_ATTR(in_intensity2_capacitance, F_CF_LED, afe4403_cap_table);192 193static AFE440X_ATTR(in_intensity3_resistance, F_RF_LED1, afe4403_res_table);194static AFE440X_ATTR(in_intensity3_capacitance, F_CF_LED1, afe4403_cap_table);195 196static AFE440X_ATTR(in_intensity4_resistance, F_RF_LED1, afe4403_res_table);197static AFE440X_ATTR(in_intensity4_capacitance, F_CF_LED1, afe4403_cap_table);198 199static struct attribute *afe440x_attributes[] = {200 &dev_attr_in_intensity_resistance_available.attr,201 &dev_attr_in_intensity_capacitance_available.attr,202 &afe440x_attr_in_intensity1_resistance.dev_attr.attr,203 &afe440x_attr_in_intensity1_capacitance.dev_attr.attr,204 &afe440x_attr_in_intensity2_resistance.dev_attr.attr,205 &afe440x_attr_in_intensity2_capacitance.dev_attr.attr,206 &afe440x_attr_in_intensity3_resistance.dev_attr.attr,207 &afe440x_attr_in_intensity3_capacitance.dev_attr.attr,208 &afe440x_attr_in_intensity4_resistance.dev_attr.attr,209 &afe440x_attr_in_intensity4_capacitance.dev_attr.attr,210 NULL211};212 213static const struct attribute_group afe440x_attribute_group = {214 .attrs = afe440x_attributes215};216 217static int afe4403_read(struct afe4403_data *afe, unsigned int reg, u32 *val)218{219 u8 tx[4] = {AFE440X_CONTROL0, 0x0, 0x0, AFE440X_CONTROL0_READ};220 u8 rx[3];221 int ret;222 223 /* Enable reading from the device */224 ret = spi_write_then_read(afe->spi, tx, 4, NULL, 0);225 if (ret)226 return ret;227 228 ret = spi_write_then_read(afe->spi, ®, 1, rx, sizeof(rx));229 if (ret)230 return ret;231 232 *val = get_unaligned_be24(&rx[0]);233 234 /* Disable reading from the device */235 tx[3] = AFE440X_CONTROL0_WRITE;236 ret = spi_write_then_read(afe->spi, tx, 4, NULL, 0);237 if (ret)238 return ret;239 240 return 0;241}242 243static int afe4403_read_raw(struct iio_dev *indio_dev,244 struct iio_chan_spec const *chan,245 int *val, int *val2, long mask)246{247 struct afe4403_data *afe = iio_priv(indio_dev);248 unsigned int reg, field;249 int ret;250 251 switch (chan->type) {252 case IIO_INTENSITY:253 switch (mask) {254 case IIO_CHAN_INFO_RAW:255 reg = afe4403_channel_values[chan->address];256 ret = afe4403_read(afe, reg, val);257 if (ret)258 return ret;259 return IIO_VAL_INT;260 }261 break;262 case IIO_CURRENT:263 switch (mask) {264 case IIO_CHAN_INFO_RAW:265 field = afe4403_channel_leds[chan->address];266 ret = regmap_field_read(afe->fields[field], val);267 if (ret)268 return ret;269 return IIO_VAL_INT;270 case IIO_CHAN_INFO_SCALE:271 *val = 0;272 *val2 = 800000;273 return IIO_VAL_INT_PLUS_MICRO;274 }275 break;276 default:277 break;278 }279 280 return -EINVAL;281}282 283static int afe4403_write_raw(struct iio_dev *indio_dev,284 struct iio_chan_spec const *chan,285 int val, int val2, long mask)286{287 struct afe4403_data *afe = iio_priv(indio_dev);288 unsigned int field = afe4403_channel_leds[chan->address];289 290 switch (chan->type) {291 case IIO_CURRENT:292 switch (mask) {293 case IIO_CHAN_INFO_RAW:294 return regmap_field_write(afe->fields[field], val);295 }296 break;297 default:298 break;299 }300 301 return -EINVAL;302}303 304static const struct iio_info afe4403_iio_info = {305 .attrs = &afe440x_attribute_group,306 .read_raw = afe4403_read_raw,307 .write_raw = afe4403_write_raw,308};309 310static irqreturn_t afe4403_trigger_handler(int irq, void *private)311{312 struct iio_poll_func *pf = private;313 struct iio_dev *indio_dev = pf->indio_dev;314 struct afe4403_data *afe = iio_priv(indio_dev);315 int ret, bit, i = 0;316 u8 tx[4] = {AFE440X_CONTROL0, 0x0, 0x0, AFE440X_CONTROL0_READ};317 u8 rx[3];318 319 /* Enable reading from the device */320 ret = spi_write_then_read(afe->spi, tx, 4, NULL, 0);321 if (ret)322 goto err;323 324 iio_for_each_active_channel(indio_dev, bit) {325 ret = spi_write_then_read(afe->spi,326 &afe4403_channel_values[bit], 1,327 rx, sizeof(rx));328 if (ret)329 goto err;330 331 afe->buffer[i++] = get_unaligned_be24(&rx[0]);332 }333 334 /* Disable reading from the device */335 tx[3] = AFE440X_CONTROL0_WRITE;336 ret = spi_write_then_read(afe->spi, tx, 4, NULL, 0);337 if (ret)338 goto err;339 340 iio_push_to_buffers_with_timestamp(indio_dev, afe->buffer,341 pf->timestamp);342err:343 iio_trigger_notify_done(indio_dev->trig);344 345 return IRQ_HANDLED;346}347 348static void afe4403_regulator_disable(void *data)349{350 struct regulator *regulator = data;351 352 regulator_disable(regulator);353}354 355#define AFE4403_TIMING_PAIRS \356 { AFE440X_LED2STC, 0x000050 }, \357 { AFE440X_LED2ENDC, 0x0003e7 }, \358 { AFE440X_LED1LEDSTC, 0x0007d0 }, \359 { AFE440X_LED1LEDENDC, 0x000bb7 }, \360 { AFE440X_ALED2STC, 0x000438 }, \361 { AFE440X_ALED2ENDC, 0x0007cf }, \362 { AFE440X_LED1STC, 0x000820 }, \363 { AFE440X_LED1ENDC, 0x000bb7 }, \364 { AFE440X_LED2LEDSTC, 0x000000 }, \365 { AFE440X_LED2LEDENDC, 0x0003e7 }, \366 { AFE440X_ALED1STC, 0x000c08 }, \367 { AFE440X_ALED1ENDC, 0x000f9f }, \368 { AFE440X_LED2CONVST, 0x0003ef }, \369 { AFE440X_LED2CONVEND, 0x0007cf }, \370 { AFE440X_ALED2CONVST, 0x0007d7 }, \371 { AFE440X_ALED2CONVEND, 0x000bb7 }, \372 { AFE440X_LED1CONVST, 0x000bbf }, \373 { AFE440X_LED1CONVEND, 0x009c3f }, \374 { AFE440X_ALED1CONVST, 0x000fa7 }, \375 { AFE440X_ALED1CONVEND, 0x001387 }, \376 { AFE440X_ADCRSTSTCT0, 0x0003e8 }, \377 { AFE440X_ADCRSTENDCT0, 0x0003eb }, \378 { AFE440X_ADCRSTSTCT1, 0x0007d0 }, \379 { AFE440X_ADCRSTENDCT1, 0x0007d3 }, \380 { AFE440X_ADCRSTSTCT2, 0x000bb8 }, \381 { AFE440X_ADCRSTENDCT2, 0x000bbb }, \382 { AFE440X_ADCRSTSTCT3, 0x000fa0 }, \383 { AFE440X_ADCRSTENDCT3, 0x000fa3 }, \384 { AFE440X_PRPCOUNT, 0x009c3f }, \385 { AFE440X_PDNCYCLESTC, 0x001518 }, \386 { AFE440X_PDNCYCLEENDC, 0x00991f }387 388static const struct reg_sequence afe4403_reg_sequences[] = {389 AFE4403_TIMING_PAIRS,390 { AFE440X_CONTROL1, AFE440X_CONTROL1_TIMEREN },391 { AFE4403_TIAGAIN, AFE440X_TIAGAIN_ENSEPGAIN },392};393 394static const struct regmap_range afe4403_yes_ranges[] = {395 regmap_reg_range(AFE440X_LED2VAL, AFE440X_LED1_ALED1VAL),396};397 398static const struct regmap_access_table afe4403_volatile_table = {399 .yes_ranges = afe4403_yes_ranges,400 .n_yes_ranges = ARRAY_SIZE(afe4403_yes_ranges),401};402 403static const struct regmap_config afe4403_regmap_config = {404 .reg_bits = 8,405 .val_bits = 24,406 407 .max_register = AFE440X_PDNCYCLEENDC,408 .cache_type = REGCACHE_RBTREE,409 .volatile_table = &afe4403_volatile_table,410};411 412static const struct of_device_id afe4403_of_match[] = {413 { .compatible = "ti,afe4403", },414 { /* sentinel */ }415};416MODULE_DEVICE_TABLE(of, afe4403_of_match);417 418static int afe4403_suspend(struct device *dev)419{420 struct iio_dev *indio_dev = spi_get_drvdata(to_spi_device(dev));421 struct afe4403_data *afe = iio_priv(indio_dev);422 int ret;423 424 ret = regmap_set_bits(afe->regmap, AFE440X_CONTROL2,425 AFE440X_CONTROL2_PDN_AFE);426 if (ret)427 return ret;428 429 ret = regulator_disable(afe->regulator);430 if (ret) {431 dev_err(dev, "Unable to disable regulator\n");432 return ret;433 }434 435 return 0;436}437 438static int afe4403_resume(struct device *dev)439{440 struct iio_dev *indio_dev = spi_get_drvdata(to_spi_device(dev));441 struct afe4403_data *afe = iio_priv(indio_dev);442 int ret;443 444 ret = regulator_enable(afe->regulator);445 if (ret) {446 dev_err(dev, "Unable to enable regulator\n");447 return ret;448 }449 450 ret = regmap_clear_bits(afe->regmap, AFE440X_CONTROL2,451 AFE440X_CONTROL2_PDN_AFE);452 if (ret)453 return ret;454 455 return 0;456}457 458static DEFINE_SIMPLE_DEV_PM_OPS(afe4403_pm_ops, afe4403_suspend,459 afe4403_resume);460 461static int afe4403_probe(struct spi_device *spi)462{463 struct iio_dev *indio_dev;464 struct afe4403_data *afe;465 int i, ret;466 467 indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*afe));468 if (!indio_dev)469 return -ENOMEM;470 471 afe = iio_priv(indio_dev);472 spi_set_drvdata(spi, indio_dev);473 474 afe->dev = &spi->dev;475 afe->spi = spi;476 afe->irq = spi->irq;477 478 afe->regmap = devm_regmap_init_spi(spi, &afe4403_regmap_config);479 if (IS_ERR(afe->regmap)) {480 dev_err(afe->dev, "Unable to allocate register map\n");481 return PTR_ERR(afe->regmap);482 }483 484 for (i = 0; i < F_MAX_FIELDS; i++) {485 afe->fields[i] = devm_regmap_field_alloc(afe->dev, afe->regmap,486 afe4403_reg_fields[i]);487 if (IS_ERR(afe->fields[i])) {488 dev_err(afe->dev, "Unable to allocate regmap fields\n");489 return PTR_ERR(afe->fields[i]);490 }491 }492 493 afe->regulator = devm_regulator_get(afe->dev, "tx_sup");494 if (IS_ERR(afe->regulator))495 return dev_err_probe(afe->dev, PTR_ERR(afe->regulator),496 "Unable to get regulator\n");497 498 ret = regulator_enable(afe->regulator);499 if (ret) {500 dev_err(afe->dev, "Unable to enable regulator\n");501 return ret;502 }503 ret = devm_add_action_or_reset(afe->dev, afe4403_regulator_disable, afe->regulator);504 if (ret) {505 dev_err(afe->dev, "Unable to add regulator disable action\n");506 return ret;507 }508 509 ret = regmap_write(afe->regmap, AFE440X_CONTROL0,510 AFE440X_CONTROL0_SW_RESET);511 if (ret) {512 dev_err(afe->dev, "Unable to reset device\n");513 return ret;514 }515 516 ret = regmap_multi_reg_write(afe->regmap, afe4403_reg_sequences,517 ARRAY_SIZE(afe4403_reg_sequences));518 if (ret) {519 dev_err(afe->dev, "Unable to set register defaults\n");520 return ret;521 }522 523 indio_dev->modes = INDIO_DIRECT_MODE;524 indio_dev->channels = afe4403_channels;525 indio_dev->num_channels = ARRAY_SIZE(afe4403_channels);526 indio_dev->name = AFE4403_DRIVER_NAME;527 indio_dev->info = &afe4403_iio_info;528 529 if (afe->irq > 0) {530 afe->trig = devm_iio_trigger_alloc(afe->dev,531 "%s-dev%d",532 indio_dev->name,533 iio_device_id(indio_dev));534 if (!afe->trig) {535 dev_err(afe->dev, "Unable to allocate IIO trigger\n");536 return -ENOMEM;537 }538 539 iio_trigger_set_drvdata(afe->trig, indio_dev);540 541 ret = devm_iio_trigger_register(afe->dev, afe->trig);542 if (ret) {543 dev_err(afe->dev, "Unable to register IIO trigger\n");544 return ret;545 }546 547 ret = devm_request_threaded_irq(afe->dev, afe->irq,548 iio_trigger_generic_data_rdy_poll,549 NULL, IRQF_ONESHOT,550 AFE4403_DRIVER_NAME,551 afe->trig);552 if (ret) {553 dev_err(afe->dev, "Unable to request IRQ\n");554 return ret;555 }556 }557 558 ret = devm_iio_triggered_buffer_setup(afe->dev, indio_dev,559 &iio_pollfunc_store_time,560 afe4403_trigger_handler, NULL);561 if (ret) {562 dev_err(afe->dev, "Unable to setup buffer\n");563 return ret;564 }565 566 ret = devm_iio_device_register(afe->dev, indio_dev);567 if (ret) {568 dev_err(afe->dev, "Unable to register IIO device\n");569 return ret;570 }571 572 return 0;573}574 575static const struct spi_device_id afe4403_ids[] = {576 { "afe4403", 0 },577 { /* sentinel */ }578};579MODULE_DEVICE_TABLE(spi, afe4403_ids);580 581static struct spi_driver afe4403_spi_driver = {582 .driver = {583 .name = AFE4403_DRIVER_NAME,584 .of_match_table = afe4403_of_match,585 .pm = pm_sleep_ptr(&afe4403_pm_ops),586 },587 .probe = afe4403_probe,588 .id_table = afe4403_ids,589};590module_spi_driver(afe4403_spi_driver);591 592MODULE_AUTHOR("Andrew F. Davis <afd@ti.com>");593MODULE_DESCRIPTION("TI AFE4403 Heart Rate Monitor and Pulse Oximeter AFE");594MODULE_LICENSE("GPL v2");595