1d2912cb1SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only 2fc167f62SPhilippe Reynes /* 3fc167f62SPhilippe Reynes * iio/adc/max1027.c 4fc167f62SPhilippe Reynes * Copyright (C) 2014 Philippe Reynes 5fc167f62SPhilippe Reynes * 6fc167f62SPhilippe Reynes * based on linux/drivers/iio/ad7923.c 7fc167f62SPhilippe Reynes * Copyright 2011 Analog Devices Inc (from AD7923 Driver) 8fc167f62SPhilippe Reynes * Copyright 2012 CS Systemes d'Information 9fc167f62SPhilippe Reynes * 10fc167f62SPhilippe Reynes * max1027.c 11fc167f62SPhilippe Reynes * 12fc167f62SPhilippe Reynes * Partial support for max1027 and similar chips. 13fc167f62SPhilippe Reynes */ 14fc167f62SPhilippe Reynes 15fc167f62SPhilippe Reynes #include <linux/kernel.h> 16fc167f62SPhilippe Reynes #include <linux/module.h> 1753469fa5SJonathan Cameron #include <linux/mod_devicetable.h> 18fc167f62SPhilippe Reynes #include <linux/spi/spi.h> 19fc167f62SPhilippe Reynes #include <linux/delay.h> 20fc167f62SPhilippe Reynes 21fc167f62SPhilippe Reynes #include <linux/iio/iio.h> 22fc167f62SPhilippe Reynes #include <linux/iio/buffer.h> 23fc167f62SPhilippe Reynes #include <linux/iio/trigger.h> 24fc167f62SPhilippe Reynes #include <linux/iio/trigger_consumer.h> 25fc167f62SPhilippe Reynes #include <linux/iio/triggered_buffer.h> 26fc167f62SPhilippe Reynes 27fc167f62SPhilippe Reynes #define MAX1027_CONV_REG BIT(7) 28fc167f62SPhilippe Reynes #define MAX1027_SETUP_REG BIT(6) 29fc167f62SPhilippe Reynes #define MAX1027_AVG_REG BIT(5) 30fc167f62SPhilippe Reynes #define MAX1027_RST_REG BIT(4) 31fc167f62SPhilippe Reynes 32fc167f62SPhilippe Reynes /* conversion register */ 33fc167f62SPhilippe Reynes #define MAX1027_TEMP BIT(0) 34fc167f62SPhilippe Reynes #define MAX1027_SCAN_0_N (0x00 << 1) 35fc167f62SPhilippe Reynes #define MAX1027_SCAN_N_M (0x01 << 1) 36fc167f62SPhilippe Reynes #define MAX1027_SCAN_N (0x02 << 1) 37fc167f62SPhilippe Reynes #define MAX1027_NOSCAN (0x03 << 1) 38fc167f62SPhilippe Reynes #define MAX1027_CHAN(n) ((n) << 3) 39fc167f62SPhilippe Reynes 40fc167f62SPhilippe Reynes /* setup register */ 41fc167f62SPhilippe Reynes #define MAX1027_UNIPOLAR 0x02 42fc167f62SPhilippe Reynes #define MAX1027_BIPOLAR 0x03 43fc167f62SPhilippe Reynes #define MAX1027_REF_MODE0 (0x00 << 2) 44fc167f62SPhilippe Reynes #define MAX1027_REF_MODE1 (0x01 << 2) 45fc167f62SPhilippe Reynes #define MAX1027_REF_MODE2 (0x02 << 2) 46fc167f62SPhilippe Reynes #define MAX1027_REF_MODE3 (0x03 << 2) 47fc167f62SPhilippe Reynes #define MAX1027_CKS_MODE0 (0x00 << 4) 48fc167f62SPhilippe Reynes #define MAX1027_CKS_MODE1 (0x01 << 4) 49fc167f62SPhilippe Reynes #define MAX1027_CKS_MODE2 (0x02 << 4) 50fc167f62SPhilippe Reynes #define MAX1027_CKS_MODE3 (0x03 << 4) 51fc167f62SPhilippe Reynes 52fc167f62SPhilippe Reynes /* averaging register */ 53fc167f62SPhilippe Reynes #define MAX1027_NSCAN_4 0x00 54fc167f62SPhilippe Reynes #define MAX1027_NSCAN_8 0x01 55fc167f62SPhilippe Reynes #define MAX1027_NSCAN_12 0x02 56fc167f62SPhilippe Reynes #define MAX1027_NSCAN_16 0x03 57fc167f62SPhilippe Reynes #define MAX1027_NAVG_4 (0x00 << 2) 58fc167f62SPhilippe Reynes #define MAX1027_NAVG_8 (0x01 << 2) 59fc167f62SPhilippe Reynes #define MAX1027_NAVG_16 (0x02 << 2) 60fc167f62SPhilippe Reynes #define MAX1027_NAVG_32 (0x03 << 2) 61fc167f62SPhilippe Reynes #define MAX1027_AVG_EN BIT(4) 62fc167f62SPhilippe Reynes 63a0e83165SMiquel Raynal /* Device can achieve 300ksps so we assume a 3.33us conversion delay */ 64a0e83165SMiquel Raynal #define MAX1027_CONVERSION_UDELAY 4 65a0e83165SMiquel Raynal 66fc167f62SPhilippe Reynes enum max1027_id { 67fc167f62SPhilippe Reynes max1027, 68fc167f62SPhilippe Reynes max1029, 69fc167f62SPhilippe Reynes max1031, 70ae47d009SMiquel Raynal max1227, 71ae47d009SMiquel Raynal max1229, 72ae47d009SMiquel Raynal max1231, 73fc167f62SPhilippe Reynes }; 74fc167f62SPhilippe Reynes 75fc167f62SPhilippe Reynes static const struct spi_device_id max1027_id[] = { 76fc167f62SPhilippe Reynes {"max1027", max1027}, 77fc167f62SPhilippe Reynes {"max1029", max1029}, 78fc167f62SPhilippe Reynes {"max1031", max1031}, 79ae47d009SMiquel Raynal {"max1227", max1227}, 80ae47d009SMiquel Raynal {"max1229", max1229}, 81ae47d009SMiquel Raynal {"max1231", max1231}, 82fc167f62SPhilippe Reynes {} 83fc167f62SPhilippe Reynes }; 84fc167f62SPhilippe Reynes MODULE_DEVICE_TABLE(spi, max1027_id); 85fc167f62SPhilippe Reynes 86fc167f62SPhilippe Reynes static const struct of_device_id max1027_adc_dt_ids[] = { 87fc167f62SPhilippe Reynes { .compatible = "maxim,max1027" }, 88fc167f62SPhilippe Reynes { .compatible = "maxim,max1029" }, 89fc167f62SPhilippe Reynes { .compatible = "maxim,max1031" }, 90ae47d009SMiquel Raynal { .compatible = "maxim,max1227" }, 91ae47d009SMiquel Raynal { .compatible = "maxim,max1229" }, 92ae47d009SMiquel Raynal { .compatible = "maxim,max1231" }, 93fc167f62SPhilippe Reynes {}, 94fc167f62SPhilippe Reynes }; 95fc167f62SPhilippe Reynes MODULE_DEVICE_TABLE(of, max1027_adc_dt_ids); 96fc167f62SPhilippe Reynes 977af5257dSMiquel Raynal #define MAX1027_V_CHAN(index, depth) \ 98fc167f62SPhilippe Reynes { \ 99fc167f62SPhilippe Reynes .type = IIO_VOLTAGE, \ 100fc167f62SPhilippe Reynes .indexed = 1, \ 101fc167f62SPhilippe Reynes .channel = index, \ 102fc167f62SPhilippe Reynes .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ 103fc167f62SPhilippe Reynes .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ 104fc167f62SPhilippe Reynes .scan_index = index + 1, \ 105fc167f62SPhilippe Reynes .scan_type = { \ 106fc167f62SPhilippe Reynes .sign = 'u', \ 1077af5257dSMiquel Raynal .realbits = depth, \ 108fc167f62SPhilippe Reynes .storagebits = 16, \ 109732ae19eSMiquel Raynal .shift = (depth == 10) ? 2 : 0, \ 110fc167f62SPhilippe Reynes .endianness = IIO_BE, \ 111fc167f62SPhilippe Reynes }, \ 112fc167f62SPhilippe Reynes } 113fc167f62SPhilippe Reynes 114fc167f62SPhilippe Reynes #define MAX1027_T_CHAN \ 115fc167f62SPhilippe Reynes { \ 116fc167f62SPhilippe Reynes .type = IIO_TEMP, \ 117fc167f62SPhilippe Reynes .channel = 0, \ 118fc167f62SPhilippe Reynes .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ 119fc167f62SPhilippe Reynes .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ 120fc167f62SPhilippe Reynes .scan_index = 0, \ 121fc167f62SPhilippe Reynes .scan_type = { \ 122fc167f62SPhilippe Reynes .sign = 'u', \ 123fc167f62SPhilippe Reynes .realbits = 12, \ 124fc167f62SPhilippe Reynes .storagebits = 16, \ 125fc167f62SPhilippe Reynes .endianness = IIO_BE, \ 126fc167f62SPhilippe Reynes }, \ 127fc167f62SPhilippe Reynes } 128fc167f62SPhilippe Reynes 1297af5257dSMiquel Raynal #define MAX1X27_CHANNELS(depth) \ 1307af5257dSMiquel Raynal MAX1027_T_CHAN, \ 1317af5257dSMiquel Raynal MAX1027_V_CHAN(0, depth), \ 1327af5257dSMiquel Raynal MAX1027_V_CHAN(1, depth), \ 1337af5257dSMiquel Raynal MAX1027_V_CHAN(2, depth), \ 1347af5257dSMiquel Raynal MAX1027_V_CHAN(3, depth), \ 1357af5257dSMiquel Raynal MAX1027_V_CHAN(4, depth), \ 1367af5257dSMiquel Raynal MAX1027_V_CHAN(5, depth), \ 1377af5257dSMiquel Raynal MAX1027_V_CHAN(6, depth), \ 1387af5257dSMiquel Raynal MAX1027_V_CHAN(7, depth) 1397af5257dSMiquel Raynal 1407af5257dSMiquel Raynal #define MAX1X29_CHANNELS(depth) \ 1417af5257dSMiquel Raynal MAX1X27_CHANNELS(depth), \ 1427af5257dSMiquel Raynal MAX1027_V_CHAN(8, depth), \ 1437af5257dSMiquel Raynal MAX1027_V_CHAN(9, depth), \ 1447af5257dSMiquel Raynal MAX1027_V_CHAN(10, depth), \ 1457af5257dSMiquel Raynal MAX1027_V_CHAN(11, depth) 1467af5257dSMiquel Raynal 1477af5257dSMiquel Raynal #define MAX1X31_CHANNELS(depth) \ 1487af5257dSMiquel Raynal MAX1X29_CHANNELS(depth), \ 1497af5257dSMiquel Raynal MAX1027_V_CHAN(12, depth), \ 1507af5257dSMiquel Raynal MAX1027_V_CHAN(13, depth), \ 1517af5257dSMiquel Raynal MAX1027_V_CHAN(14, depth), \ 1527af5257dSMiquel Raynal MAX1027_V_CHAN(15, depth) 1537af5257dSMiquel Raynal 154fc167f62SPhilippe Reynes static const struct iio_chan_spec max1027_channels[] = { 1557af5257dSMiquel Raynal MAX1X27_CHANNELS(10), 156fc167f62SPhilippe Reynes }; 157fc167f62SPhilippe Reynes 158fc167f62SPhilippe Reynes static const struct iio_chan_spec max1029_channels[] = { 1597af5257dSMiquel Raynal MAX1X29_CHANNELS(10), 160fc167f62SPhilippe Reynes }; 161fc167f62SPhilippe Reynes 162fc167f62SPhilippe Reynes static const struct iio_chan_spec max1031_channels[] = { 1637af5257dSMiquel Raynal MAX1X31_CHANNELS(10), 164fc167f62SPhilippe Reynes }; 165fc167f62SPhilippe Reynes 166ae47d009SMiquel Raynal static const struct iio_chan_spec max1227_channels[] = { 167ae47d009SMiquel Raynal MAX1X27_CHANNELS(12), 168ae47d009SMiquel Raynal }; 169ae47d009SMiquel Raynal 170ae47d009SMiquel Raynal static const struct iio_chan_spec max1229_channels[] = { 171ae47d009SMiquel Raynal MAX1X29_CHANNELS(12), 172ae47d009SMiquel Raynal }; 173ae47d009SMiquel Raynal 174ae47d009SMiquel Raynal static const struct iio_chan_spec max1231_channels[] = { 175ae47d009SMiquel Raynal MAX1X31_CHANNELS(12), 176ae47d009SMiquel Raynal }; 177ae47d009SMiquel Raynal 178e1c0ea8fSMiquel Raynal /* 179e1c0ea8fSMiquel Raynal * These devices are able to scan from 0 to N, N being the highest voltage 180e1c0ea8fSMiquel Raynal * channel requested by the user. The temperature can be included or not, 181e1c0ea8fSMiquel Raynal * but cannot be retrieved alone. Based on the below 182e1c0ea8fSMiquel Raynal * ->available_scan_masks, the core will select the most appropriate 183e1c0ea8fSMiquel Raynal * ->active_scan_mask and the "minimum" number of channels will be 184e1c0ea8fSMiquel Raynal * scanned and pushed to the buffers. 185e1c0ea8fSMiquel Raynal * 186e1c0ea8fSMiquel Raynal * For example, if the user wants channels 1, 4 and 5, all channels from 187e1c0ea8fSMiquel Raynal * 0 to 5 will be scanned and pushed to the IIO buffers. The core will then 188e1c0ea8fSMiquel Raynal * filter out the unneeded samples based on the ->active_scan_mask that has 189e1c0ea8fSMiquel Raynal * been selected and only channels 1, 4 and 5 will be available to the user 190e1c0ea8fSMiquel Raynal * in the shared buffer. 191e1c0ea8fSMiquel Raynal */ 192e1c0ea8fSMiquel Raynal #define MAX1X27_SCAN_MASK_TEMP BIT(0) 193e1c0ea8fSMiquel Raynal 194e1c0ea8fSMiquel Raynal #define MAX1X27_SCAN_MASKS(temp) \ 195e1c0ea8fSMiquel Raynal GENMASK(1, 1 - (temp)), GENMASK(2, 1 - (temp)), \ 196e1c0ea8fSMiquel Raynal GENMASK(3, 1 - (temp)), GENMASK(4, 1 - (temp)), \ 197e1c0ea8fSMiquel Raynal GENMASK(5, 1 - (temp)), GENMASK(6, 1 - (temp)), \ 198e1c0ea8fSMiquel Raynal GENMASK(7, 1 - (temp)), GENMASK(8, 1 - (temp)) 199e1c0ea8fSMiquel Raynal 200e1c0ea8fSMiquel Raynal #define MAX1X29_SCAN_MASKS(temp) \ 201e1c0ea8fSMiquel Raynal MAX1X27_SCAN_MASKS(temp), \ 202e1c0ea8fSMiquel Raynal GENMASK(9, 1 - (temp)), GENMASK(10, 1 - (temp)), \ 203e1c0ea8fSMiquel Raynal GENMASK(11, 1 - (temp)), GENMASK(12, 1 - (temp)) 204e1c0ea8fSMiquel Raynal 205e1c0ea8fSMiquel Raynal #define MAX1X31_SCAN_MASKS(temp) \ 206e1c0ea8fSMiquel Raynal MAX1X29_SCAN_MASKS(temp), \ 207e1c0ea8fSMiquel Raynal GENMASK(13, 1 - (temp)), GENMASK(14, 1 - (temp)), \ 208e1c0ea8fSMiquel Raynal GENMASK(15, 1 - (temp)), GENMASK(16, 1 - (temp)) 209e1c0ea8fSMiquel Raynal 210fc167f62SPhilippe Reynes static const unsigned long max1027_available_scan_masks[] = { 211e1c0ea8fSMiquel Raynal MAX1X27_SCAN_MASKS(0), 212e1c0ea8fSMiquel Raynal MAX1X27_SCAN_MASKS(1), 213fc167f62SPhilippe Reynes 0x00000000, 214fc167f62SPhilippe Reynes }; 215fc167f62SPhilippe Reynes 216fc167f62SPhilippe Reynes static const unsigned long max1029_available_scan_masks[] = { 217e1c0ea8fSMiquel Raynal MAX1X29_SCAN_MASKS(0), 218e1c0ea8fSMiquel Raynal MAX1X29_SCAN_MASKS(1), 219fc167f62SPhilippe Reynes 0x00000000, 220fc167f62SPhilippe Reynes }; 221fc167f62SPhilippe Reynes 222fc167f62SPhilippe Reynes static const unsigned long max1031_available_scan_masks[] = { 223e1c0ea8fSMiquel Raynal MAX1X31_SCAN_MASKS(0), 224e1c0ea8fSMiquel Raynal MAX1X31_SCAN_MASKS(1), 225fc167f62SPhilippe Reynes 0x00000000, 226fc167f62SPhilippe Reynes }; 227fc167f62SPhilippe Reynes 228fc167f62SPhilippe Reynes struct max1027_chip_info { 229fc167f62SPhilippe Reynes const struct iio_chan_spec *channels; 230fc167f62SPhilippe Reynes unsigned int num_channels; 231fc167f62SPhilippe Reynes const unsigned long *available_scan_masks; 232fc167f62SPhilippe Reynes }; 233fc167f62SPhilippe Reynes 234fc167f62SPhilippe Reynes static const struct max1027_chip_info max1027_chip_info_tbl[] = { 235fc167f62SPhilippe Reynes [max1027] = { 236fc167f62SPhilippe Reynes .channels = max1027_channels, 237fc167f62SPhilippe Reynes .num_channels = ARRAY_SIZE(max1027_channels), 238fc167f62SPhilippe Reynes .available_scan_masks = max1027_available_scan_masks, 239fc167f62SPhilippe Reynes }, 240fc167f62SPhilippe Reynes [max1029] = { 241fc167f62SPhilippe Reynes .channels = max1029_channels, 242fc167f62SPhilippe Reynes .num_channels = ARRAY_SIZE(max1029_channels), 243fc167f62SPhilippe Reynes .available_scan_masks = max1029_available_scan_masks, 244fc167f62SPhilippe Reynes }, 245fc167f62SPhilippe Reynes [max1031] = { 246fc167f62SPhilippe Reynes .channels = max1031_channels, 247fc167f62SPhilippe Reynes .num_channels = ARRAY_SIZE(max1031_channels), 248fc167f62SPhilippe Reynes .available_scan_masks = max1031_available_scan_masks, 249fc167f62SPhilippe Reynes }, 250ae47d009SMiquel Raynal [max1227] = { 251ae47d009SMiquel Raynal .channels = max1227_channels, 252ae47d009SMiquel Raynal .num_channels = ARRAY_SIZE(max1227_channels), 253ae47d009SMiquel Raynal .available_scan_masks = max1027_available_scan_masks, 254ae47d009SMiquel Raynal }, 255ae47d009SMiquel Raynal [max1229] = { 256ae47d009SMiquel Raynal .channels = max1229_channels, 257ae47d009SMiquel Raynal .num_channels = ARRAY_SIZE(max1229_channels), 258ae47d009SMiquel Raynal .available_scan_masks = max1029_available_scan_masks, 259ae47d009SMiquel Raynal }, 260ae47d009SMiquel Raynal [max1231] = { 261ae47d009SMiquel Raynal .channels = max1231_channels, 262ae47d009SMiquel Raynal .num_channels = ARRAY_SIZE(max1231_channels), 263ae47d009SMiquel Raynal .available_scan_masks = max1031_available_scan_masks, 264ae47d009SMiquel Raynal }, 265fc167f62SPhilippe Reynes }; 266fc167f62SPhilippe Reynes 267fc167f62SPhilippe Reynes struct max1027_state { 268fc167f62SPhilippe Reynes const struct max1027_chip_info *info; 269fc167f62SPhilippe Reynes struct spi_device *spi; 270fc167f62SPhilippe Reynes struct iio_trigger *trig; 271fc167f62SPhilippe Reynes __be16 *buffer; 272fc167f62SPhilippe Reynes struct mutex lock; 2731f7b4048SMiquel Raynal struct completion complete; 274fc167f62SPhilippe Reynes 275*e754fb7eSJonathan Cameron u8 reg __aligned(IIO_DMA_MINALIGN); 276fc167f62SPhilippe Reynes }; 277fc167f62SPhilippe Reynes 278a0e83165SMiquel Raynal static int max1027_wait_eoc(struct iio_dev *indio_dev) 279a0e83165SMiquel Raynal { 2801f7b4048SMiquel Raynal struct max1027_state *st = iio_priv(indio_dev); 281a0e83165SMiquel Raynal unsigned int conversion_time = MAX1027_CONVERSION_UDELAY; 2821f7b4048SMiquel Raynal int ret; 283a0e83165SMiquel Raynal 2841f7b4048SMiquel Raynal if (st->spi->irq) { 2851f7b4048SMiquel Raynal ret = wait_for_completion_timeout(&st->complete, 2861f7b4048SMiquel Raynal msecs_to_jiffies(1000)); 2871f7b4048SMiquel Raynal reinit_completion(&st->complete); 2881f7b4048SMiquel Raynal if (!ret) 2892021ef06SDan Carpenter return -ETIMEDOUT; 2901f7b4048SMiquel Raynal } else { 291089ec5e9SMiquel Raynal if (indio_dev->active_scan_mask) 292089ec5e9SMiquel Raynal conversion_time *= hweight32(*indio_dev->active_scan_mask); 293089ec5e9SMiquel Raynal 294a0e83165SMiquel Raynal usleep_range(conversion_time, conversion_time * 2); 2951f7b4048SMiquel Raynal } 296a0e83165SMiquel Raynal 297a0e83165SMiquel Raynal return 0; 298a0e83165SMiquel Raynal } 299a0e83165SMiquel Raynal 300af8b93e2SMiquel Raynal /* Scan from chan 0 to the highest requested channel. Include temperature on demand. */ 301af8b93e2SMiquel Raynal static int max1027_configure_chans_and_start(struct iio_dev *indio_dev) 302af8b93e2SMiquel Raynal { 303af8b93e2SMiquel Raynal struct max1027_state *st = iio_priv(indio_dev); 304af8b93e2SMiquel Raynal 305af8b93e2SMiquel Raynal st->reg = MAX1027_CONV_REG | MAX1027_SCAN_0_N; 306af8b93e2SMiquel Raynal st->reg |= MAX1027_CHAN(fls(*indio_dev->active_scan_mask) - 2); 307af8b93e2SMiquel Raynal if (*indio_dev->active_scan_mask & MAX1X27_SCAN_MASK_TEMP) 308af8b93e2SMiquel Raynal st->reg |= MAX1027_TEMP; 309af8b93e2SMiquel Raynal 310af8b93e2SMiquel Raynal return spi_write(st->spi, &st->reg, 1); 311af8b93e2SMiquel Raynal } 312af8b93e2SMiquel Raynal 313eaf57d50SMiquel Raynal static int max1027_enable_trigger(struct iio_dev *indio_dev, bool enable) 314eaf57d50SMiquel Raynal { 315eaf57d50SMiquel Raynal struct max1027_state *st = iio_priv(indio_dev); 316eaf57d50SMiquel Raynal 317eaf57d50SMiquel Raynal st->reg = MAX1027_SETUP_REG | MAX1027_REF_MODE2; 318eaf57d50SMiquel Raynal 319eaf57d50SMiquel Raynal /* 320eaf57d50SMiquel Raynal * Start acquisition on: 321eaf57d50SMiquel Raynal * MODE0: external hardware trigger wired to the cnvst input pin 322eaf57d50SMiquel Raynal * MODE2: conversion register write 323eaf57d50SMiquel Raynal */ 324eaf57d50SMiquel Raynal if (enable) 325eaf57d50SMiquel Raynal st->reg |= MAX1027_CKS_MODE0; 326eaf57d50SMiquel Raynal else 327eaf57d50SMiquel Raynal st->reg |= MAX1027_CKS_MODE2; 328eaf57d50SMiquel Raynal 329eaf57d50SMiquel Raynal return spi_write(st->spi, &st->reg, 1); 330eaf57d50SMiquel Raynal } 331eaf57d50SMiquel Raynal 332fc167f62SPhilippe Reynes static int max1027_read_single_value(struct iio_dev *indio_dev, 333fc167f62SPhilippe Reynes struct iio_chan_spec const *chan, 334fc167f62SPhilippe Reynes int *val) 335fc167f62SPhilippe Reynes { 336fc167f62SPhilippe Reynes int ret; 337fc167f62SPhilippe Reynes struct max1027_state *st = iio_priv(indio_dev); 338fc167f62SPhilippe Reynes 33959fcc6afSMiquel Raynal ret = iio_device_claim_direct_mode(indio_dev); 34059fcc6afSMiquel Raynal if (ret) 341fc167f62SPhilippe Reynes return ret; 342fc167f62SPhilippe Reynes 343fc167f62SPhilippe Reynes /* Configure conversion register with the requested chan */ 344fc167f62SPhilippe Reynes st->reg = MAX1027_CONV_REG | MAX1027_CHAN(chan->channel) | 34558b90a8dSSandhya Bankar MAX1027_NOSCAN; 34658b90a8dSSandhya Bankar if (chan->type == IIO_TEMP) 34758b90a8dSSandhya Bankar st->reg |= MAX1027_TEMP; 348fc167f62SPhilippe Reynes ret = spi_write(st->spi, &st->reg, 1); 349fc167f62SPhilippe Reynes if (ret < 0) { 350fc167f62SPhilippe Reynes dev_err(&indio_dev->dev, 351fc167f62SPhilippe Reynes "Failed to configure conversion register\n"); 35259fcc6afSMiquel Raynal iio_device_release_direct_mode(indio_dev); 353fc167f62SPhilippe Reynes return ret; 354fc167f62SPhilippe Reynes } 355fc167f62SPhilippe Reynes 356fc167f62SPhilippe Reynes /* 357fc167f62SPhilippe Reynes * For an unknown reason, when we use the mode "10" (write 358fc167f62SPhilippe Reynes * conversion register), the interrupt doesn't occur every time. 359a0e83165SMiquel Raynal * So we just wait the maximum conversion time and deliver the value. 360fc167f62SPhilippe Reynes */ 361a0e83165SMiquel Raynal ret = max1027_wait_eoc(indio_dev); 362a0e83165SMiquel Raynal if (ret) 363a0e83165SMiquel Raynal return ret; 364fc167f62SPhilippe Reynes 365fc167f62SPhilippe Reynes /* Read result */ 366fc167f62SPhilippe Reynes ret = spi_read(st->spi, st->buffer, (chan->type == IIO_TEMP) ? 4 : 2); 36759fcc6afSMiquel Raynal 36859fcc6afSMiquel Raynal iio_device_release_direct_mode(indio_dev); 36959fcc6afSMiquel Raynal 370fc167f62SPhilippe Reynes if (ret < 0) 371fc167f62SPhilippe Reynes return ret; 372fc167f62SPhilippe Reynes 373fc167f62SPhilippe Reynes *val = be16_to_cpu(st->buffer[0]); 374fc167f62SPhilippe Reynes 375fc167f62SPhilippe Reynes return IIO_VAL_INT; 376fc167f62SPhilippe Reynes } 377fc167f62SPhilippe Reynes 378fc167f62SPhilippe Reynes static int max1027_read_raw(struct iio_dev *indio_dev, 379fc167f62SPhilippe Reynes struct iio_chan_spec const *chan, 380fc167f62SPhilippe Reynes int *val, int *val2, long mask) 381fc167f62SPhilippe Reynes { 382fc167f62SPhilippe Reynes int ret = 0; 383fc167f62SPhilippe Reynes struct max1027_state *st = iio_priv(indio_dev); 384fc167f62SPhilippe Reynes 385fc167f62SPhilippe Reynes mutex_lock(&st->lock); 386fc167f62SPhilippe Reynes 387fc167f62SPhilippe Reynes switch (mask) { 388fc167f62SPhilippe Reynes case IIO_CHAN_INFO_RAW: 389fc167f62SPhilippe Reynes ret = max1027_read_single_value(indio_dev, chan, val); 390fc167f62SPhilippe Reynes break; 391fc167f62SPhilippe Reynes case IIO_CHAN_INFO_SCALE: 392fc167f62SPhilippe Reynes switch (chan->type) { 393fc167f62SPhilippe Reynes case IIO_TEMP: 394fc167f62SPhilippe Reynes *val = 1; 395fc167f62SPhilippe Reynes *val2 = 8; 396fc167f62SPhilippe Reynes ret = IIO_VAL_FRACTIONAL; 397fc167f62SPhilippe Reynes break; 398fc167f62SPhilippe Reynes case IIO_VOLTAGE: 399fc167f62SPhilippe Reynes *val = 2500; 4007af5257dSMiquel Raynal *val2 = chan->scan_type.realbits; 401fc167f62SPhilippe Reynes ret = IIO_VAL_FRACTIONAL_LOG2; 402fc167f62SPhilippe Reynes break; 403fc167f62SPhilippe Reynes default: 404fc167f62SPhilippe Reynes ret = -EINVAL; 405fc167f62SPhilippe Reynes break; 406fc167f62SPhilippe Reynes } 407fc167f62SPhilippe Reynes break; 408fc167f62SPhilippe Reynes default: 409fc167f62SPhilippe Reynes ret = -EINVAL; 410fc167f62SPhilippe Reynes break; 411fc167f62SPhilippe Reynes } 412fc167f62SPhilippe Reynes 413fc167f62SPhilippe Reynes mutex_unlock(&st->lock); 414fc167f62SPhilippe Reynes 415fc167f62SPhilippe Reynes return ret; 416fc167f62SPhilippe Reynes } 417fc167f62SPhilippe Reynes 418fc167f62SPhilippe Reynes static int max1027_debugfs_reg_access(struct iio_dev *indio_dev, 4197127822dSMiquel Raynal unsigned int reg, unsigned int writeval, 4207127822dSMiquel Raynal unsigned int *readval) 421fc167f62SPhilippe Reynes { 422fc167f62SPhilippe Reynes struct max1027_state *st = iio_priv(indio_dev); 423fc167f62SPhilippe Reynes u8 *val = (u8 *)st->buffer; 424fc167f62SPhilippe Reynes 425038696f8SMiquel Raynal if (readval) { 426038696f8SMiquel Raynal int ret = spi_read(st->spi, val, 2); 427038696f8SMiquel Raynal *readval = be16_to_cpu(st->buffer[0]); 428038696f8SMiquel Raynal return ret; 429038696f8SMiquel Raynal } 430fc167f62SPhilippe Reynes 431fc167f62SPhilippe Reynes *val = (u8)writeval; 432fc167f62SPhilippe Reynes return spi_write(st->spi, val, 1); 433fc167f62SPhilippe Reynes } 434fc167f62SPhilippe Reynes 4354201519aSMiquel Raynal static int max1027_set_cnvst_trigger_state(struct iio_trigger *trig, bool state) 436fc167f62SPhilippe Reynes { 437fc167f62SPhilippe Reynes struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig); 438fc167f62SPhilippe Reynes int ret; 439fc167f62SPhilippe Reynes 440c5a39629SMiquel Raynal /* 441c5a39629SMiquel Raynal * In order to disable the convst trigger, start acquisition on 442c5a39629SMiquel Raynal * conversion register write, which basically disables triggering 443c5a39629SMiquel Raynal * conversions upon cnvst changes and thus has the effect of disabling 444c5a39629SMiquel Raynal * the external hardware trigger. 445c5a39629SMiquel Raynal */ 446eaf57d50SMiquel Raynal ret = max1027_enable_trigger(indio_dev, state); 447eaf57d50SMiquel Raynal if (ret) 448fc167f62SPhilippe Reynes return ret; 449fc167f62SPhilippe Reynes 450c5a39629SMiquel Raynal if (state) { 451af8b93e2SMiquel Raynal ret = max1027_configure_chans_and_start(indio_dev); 452af8b93e2SMiquel Raynal if (ret) 453fc167f62SPhilippe Reynes return ret; 454fc167f62SPhilippe Reynes } 455fc167f62SPhilippe Reynes 456fc167f62SPhilippe Reynes return 0; 457fc167f62SPhilippe Reynes } 458fc167f62SPhilippe Reynes 459c757fc07SMiquel Raynal static int max1027_read_scan(struct iio_dev *indio_dev) 460fc167f62SPhilippe Reynes { 461fc167f62SPhilippe Reynes struct max1027_state *st = iio_priv(indio_dev); 462e1c0ea8fSMiquel Raynal unsigned int scanned_chans; 463c757fc07SMiquel Raynal int ret; 464e1c0ea8fSMiquel Raynal 465e1c0ea8fSMiquel Raynal scanned_chans = fls(*indio_dev->active_scan_mask) - 1; 466e1c0ea8fSMiquel Raynal if (*indio_dev->active_scan_mask & MAX1X27_SCAN_MASK_TEMP) 467e1c0ea8fSMiquel Raynal scanned_chans++; 468fc167f62SPhilippe Reynes 469fc167f62SPhilippe Reynes /* fill buffer with all channel */ 470c757fc07SMiquel Raynal ret = spi_read(st->spi, st->buffer, scanned_chans * 2); 471c757fc07SMiquel Raynal if (ret < 0) 472c757fc07SMiquel Raynal return ret; 473fc167f62SPhilippe Reynes 474fc167f62SPhilippe Reynes iio_push_to_buffers(indio_dev, st->buffer); 475fc167f62SPhilippe Reynes 476c757fc07SMiquel Raynal return 0; 477c757fc07SMiquel Raynal } 478c757fc07SMiquel Raynal 4791f7b4048SMiquel Raynal static irqreturn_t max1027_handler(int irq, void *private) 4801f7b4048SMiquel Raynal { 4811f7b4048SMiquel Raynal struct iio_dev *indio_dev = private; 4821f7b4048SMiquel Raynal struct max1027_state *st = iio_priv(indio_dev); 4831f7b4048SMiquel Raynal 4841f7b4048SMiquel Raynal /* 485075d3280SMiquel Raynal * If buffers are disabled (raw read) or when using external triggers, 486075d3280SMiquel Raynal * we just need to unlock the waiters which will then handle the data. 4871f7b4048SMiquel Raynal * 4881f7b4048SMiquel Raynal * When using the internal trigger, we must hand-off the choice of the 4891f7b4048SMiquel Raynal * handler to the core which will then lookup through the interrupt tree 4901f7b4048SMiquel Raynal * for the right handler registered with iio_triggered_buffer_setup() 4911f7b4048SMiquel Raynal * to execute, as this trigger might very well be used in conjunction 4921f7b4048SMiquel Raynal * with another device. The core will then call the relevant handler to 4931f7b4048SMiquel Raynal * perform the data processing step. 4941f7b4048SMiquel Raynal */ 4951f7b4048SMiquel Raynal if (!iio_buffer_enabled(indio_dev)) 4961f7b4048SMiquel Raynal complete(&st->complete); 4971f7b4048SMiquel Raynal else 4981f7b4048SMiquel Raynal iio_trigger_poll(indio_dev->trig); 4991f7b4048SMiquel Raynal 5001f7b4048SMiquel Raynal return IRQ_HANDLED; 5011f7b4048SMiquel Raynal } 5021f7b4048SMiquel Raynal 503fc167f62SPhilippe Reynes static irqreturn_t max1027_trigger_handler(int irq, void *private) 504fc167f62SPhilippe Reynes { 505fc167f62SPhilippe Reynes struct iio_poll_func *pf = private; 506fc167f62SPhilippe Reynes struct iio_dev *indio_dev = pf->indio_dev; 507c757fc07SMiquel Raynal int ret; 508fc167f62SPhilippe Reynes 509075d3280SMiquel Raynal if (!iio_trigger_using_own(indio_dev)) { 510075d3280SMiquel Raynal ret = max1027_configure_chans_and_start(indio_dev); 511075d3280SMiquel Raynal if (ret) 512075d3280SMiquel Raynal goto out; 513fc167f62SPhilippe Reynes 514075d3280SMiquel Raynal /* This is a threaded handler, it is fine to wait for an IRQ */ 515075d3280SMiquel Raynal ret = max1027_wait_eoc(indio_dev); 516075d3280SMiquel Raynal if (ret) 517075d3280SMiquel Raynal goto out; 518075d3280SMiquel Raynal } 519fc167f62SPhilippe Reynes 520c757fc07SMiquel Raynal ret = max1027_read_scan(indio_dev); 521075d3280SMiquel Raynal out: 522c757fc07SMiquel Raynal if (ret) 523c757fc07SMiquel Raynal dev_err(&indio_dev->dev, 524c757fc07SMiquel Raynal "Cannot read scanned values (%d)\n", ret); 525fc167f62SPhilippe Reynes 526fc167f62SPhilippe Reynes iio_trigger_notify_done(indio_dev->trig); 527fc167f62SPhilippe Reynes 528fc167f62SPhilippe Reynes return IRQ_HANDLED; 529fc167f62SPhilippe Reynes } 530fc167f62SPhilippe Reynes 531fc167f62SPhilippe Reynes static const struct iio_trigger_ops max1027_trigger_ops = { 532bea15d51SLars-Peter Clausen .validate_device = &iio_trigger_validate_own_device, 5334201519aSMiquel Raynal .set_trigger_state = &max1027_set_cnvst_trigger_state, 534fc167f62SPhilippe Reynes }; 535fc167f62SPhilippe Reynes 536fc167f62SPhilippe Reynes static const struct iio_info max1027_info = { 537fc167f62SPhilippe Reynes .read_raw = &max1027_read_raw, 538fc167f62SPhilippe Reynes .debugfs_reg_access = &max1027_debugfs_reg_access, 539fc167f62SPhilippe Reynes }; 540fc167f62SPhilippe Reynes 541fc167f62SPhilippe Reynes static int max1027_probe(struct spi_device *spi) 542fc167f62SPhilippe Reynes { 543fc167f62SPhilippe Reynes int ret; 544fc167f62SPhilippe Reynes struct iio_dev *indio_dev; 545fc167f62SPhilippe Reynes struct max1027_state *st; 546fc167f62SPhilippe Reynes 547fc167f62SPhilippe Reynes indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); 5487127822dSMiquel Raynal if (!indio_dev) { 549fc167f62SPhilippe Reynes pr_err("Can't allocate iio device\n"); 550fc167f62SPhilippe Reynes return -ENOMEM; 551fc167f62SPhilippe Reynes } 552fc167f62SPhilippe Reynes 553fc167f62SPhilippe Reynes st = iio_priv(indio_dev); 554fc167f62SPhilippe Reynes st->spi = spi; 555fc167f62SPhilippe Reynes st->info = &max1027_chip_info_tbl[spi_get_device_id(spi)->driver_data]; 556fc167f62SPhilippe Reynes 557fc167f62SPhilippe Reynes mutex_init(&st->lock); 5581f7b4048SMiquel Raynal init_completion(&st->complete); 559fc167f62SPhilippe Reynes 560fc167f62SPhilippe Reynes indio_dev->name = spi_get_device_id(spi)->name; 561fc167f62SPhilippe Reynes indio_dev->info = &max1027_info; 562fc167f62SPhilippe Reynes indio_dev->modes = INDIO_DIRECT_MODE; 563fc167f62SPhilippe Reynes indio_dev->channels = st->info->channels; 564fc167f62SPhilippe Reynes indio_dev->num_channels = st->info->num_channels; 565fc167f62SPhilippe Reynes indio_dev->available_scan_masks = st->info->available_scan_masks; 566fc167f62SPhilippe Reynes 5673c4211baSKees Cook st->buffer = devm_kmalloc_array(&indio_dev->dev, 5683c4211baSKees Cook indio_dev->num_channels, 2, 569fc167f62SPhilippe Reynes GFP_KERNEL); 570064652c0SMiquel Raynal if (!st->buffer) 571fc167f62SPhilippe Reynes return -ENOMEM; 572fc167f62SPhilippe Reynes 573089ec5e9SMiquel Raynal /* Enable triggered buffers */ 5742715a281SChuhong Yuan ret = devm_iio_triggered_buffer_setup(&spi->dev, indio_dev, 5752715a281SChuhong Yuan &iio_pollfunc_store_time, 576ffae1067SMiquel Raynal &max1027_trigger_handler, 577ffae1067SMiquel Raynal NULL); 578fc167f62SPhilippe Reynes if (ret < 0) { 579fc167f62SPhilippe Reynes dev_err(&indio_dev->dev, "Failed to setup buffer\n"); 580fc167f62SPhilippe Reynes return ret; 581fc167f62SPhilippe Reynes } 582fc167f62SPhilippe Reynes 583089ec5e9SMiquel Raynal /* If there is an EOC interrupt, register the cnvst hardware trigger */ 584089ec5e9SMiquel Raynal if (spi->irq) { 585fc167f62SPhilippe Reynes st->trig = devm_iio_trigger_alloc(&spi->dev, "%s-trigger", 586fc167f62SPhilippe Reynes indio_dev->name); 5877127822dSMiquel Raynal if (!st->trig) { 588fc167f62SPhilippe Reynes ret = -ENOMEM; 589ffae1067SMiquel Raynal dev_err(&indio_dev->dev, 590ffae1067SMiquel Raynal "Failed to allocate iio trigger\n"); 5912715a281SChuhong Yuan return ret; 592fc167f62SPhilippe Reynes } 593fc167f62SPhilippe Reynes 594fc167f62SPhilippe Reynes st->trig->ops = &max1027_trigger_ops; 595fc167f62SPhilippe Reynes iio_trigger_set_drvdata(st->trig, indio_dev); 596c41d79b7SChuhong Yuan ret = devm_iio_trigger_register(&indio_dev->dev, 597c41d79b7SChuhong Yuan st->trig); 598c41d79b7SChuhong Yuan if (ret < 0) { 599c41d79b7SChuhong Yuan dev_err(&indio_dev->dev, 600c41d79b7SChuhong Yuan "Failed to register iio trigger\n"); 601c41d79b7SChuhong Yuan return ret; 602c41d79b7SChuhong Yuan } 603fc167f62SPhilippe Reynes 6041f7b4048SMiquel Raynal ret = devm_request_irq(&spi->dev, spi->irq, max1027_handler, 605fc167f62SPhilippe Reynes IRQF_TRIGGER_FALLING, 6061f7b4048SMiquel Raynal spi->dev.driver->name, indio_dev); 607fc167f62SPhilippe Reynes if (ret < 0) { 608fc167f62SPhilippe Reynes dev_err(&indio_dev->dev, "Failed to allocate IRQ.\n"); 6092715a281SChuhong Yuan return ret; 610fc167f62SPhilippe Reynes } 611ffae1067SMiquel Raynal } 612fc167f62SPhilippe Reynes 613db033831SMiquel Raynal /* Internal reset */ 614db033831SMiquel Raynal st->reg = MAX1027_RST_REG; 615db033831SMiquel Raynal ret = spi_write(st->spi, &st->reg, 1); 616db033831SMiquel Raynal if (ret < 0) { 617db033831SMiquel Raynal dev_err(&indio_dev->dev, "Failed to reset the ADC\n"); 618db033831SMiquel Raynal return ret; 619db033831SMiquel Raynal } 620db033831SMiquel Raynal 621fc167f62SPhilippe Reynes /* Disable averaging */ 622fc167f62SPhilippe Reynes st->reg = MAX1027_AVG_REG; 623fc167f62SPhilippe Reynes ret = spi_write(st->spi, &st->reg, 1); 624fc167f62SPhilippe Reynes if (ret < 0) { 625fc167f62SPhilippe Reynes dev_err(&indio_dev->dev, "Failed to configure averaging register\n"); 626fc167f62SPhilippe Reynes return ret; 627fc167f62SPhilippe Reynes } 628fc167f62SPhilippe Reynes 629cba18232SMiquel Raynal /* Assume conversion on register write for now */ 630cba18232SMiquel Raynal ret = max1027_enable_trigger(indio_dev, false); 631cba18232SMiquel Raynal if (ret) 632cba18232SMiquel Raynal return ret; 633cba18232SMiquel Raynal 6342715a281SChuhong Yuan return devm_iio_device_register(&spi->dev, indio_dev); 635fc167f62SPhilippe Reynes } 636fc167f62SPhilippe Reynes 637fc167f62SPhilippe Reynes static struct spi_driver max1027_driver = { 638fc167f62SPhilippe Reynes .driver = { 639fc167f62SPhilippe Reynes .name = "max1027", 64053469fa5SJonathan Cameron .of_match_table = max1027_adc_dt_ids, 641fc167f62SPhilippe Reynes }, 642fc167f62SPhilippe Reynes .probe = max1027_probe, 643fc167f62SPhilippe Reynes .id_table = max1027_id, 644fc167f62SPhilippe Reynes }; 645fc167f62SPhilippe Reynes module_spi_driver(max1027_driver); 646fc167f62SPhilippe Reynes 647fc167f62SPhilippe Reynes MODULE_AUTHOR("Philippe Reynes <tremyfr@yahoo.fr>"); 648ae47d009SMiquel Raynal MODULE_DESCRIPTION("MAX1X27/MAX1X29/MAX1X31 ADC"); 649fc167f62SPhilippe Reynes MODULE_LICENSE("GPL v2"); 650