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> 17fc167f62SPhilippe Reynes #include <linux/spi/spi.h> 18fc167f62SPhilippe Reynes #include <linux/delay.h> 19fc167f62SPhilippe Reynes 20fc167f62SPhilippe Reynes #include <linux/iio/iio.h> 21fc167f62SPhilippe Reynes #include <linux/iio/buffer.h> 22fc167f62SPhilippe Reynes #include <linux/iio/trigger.h> 23fc167f62SPhilippe Reynes #include <linux/iio/trigger_consumer.h> 24fc167f62SPhilippe Reynes #include <linux/iio/triggered_buffer.h> 25fc167f62SPhilippe Reynes 26fc167f62SPhilippe Reynes #define MAX1027_CONV_REG BIT(7) 27fc167f62SPhilippe Reynes #define MAX1027_SETUP_REG BIT(6) 28fc167f62SPhilippe Reynes #define MAX1027_AVG_REG BIT(5) 29fc167f62SPhilippe Reynes #define MAX1027_RST_REG BIT(4) 30fc167f62SPhilippe Reynes 31fc167f62SPhilippe Reynes /* conversion register */ 32fc167f62SPhilippe Reynes #define MAX1027_TEMP BIT(0) 33fc167f62SPhilippe Reynes #define MAX1027_SCAN_0_N (0x00 << 1) 34fc167f62SPhilippe Reynes #define MAX1027_SCAN_N_M (0x01 << 1) 35fc167f62SPhilippe Reynes #define MAX1027_SCAN_N (0x02 << 1) 36fc167f62SPhilippe Reynes #define MAX1027_NOSCAN (0x03 << 1) 37fc167f62SPhilippe Reynes #define MAX1027_CHAN(n) ((n) << 3) 38fc167f62SPhilippe Reynes 39fc167f62SPhilippe Reynes /* setup register */ 40fc167f62SPhilippe Reynes #define MAX1027_UNIPOLAR 0x02 41fc167f62SPhilippe Reynes #define MAX1027_BIPOLAR 0x03 42fc167f62SPhilippe Reynes #define MAX1027_REF_MODE0 (0x00 << 2) 43fc167f62SPhilippe Reynes #define MAX1027_REF_MODE1 (0x01 << 2) 44fc167f62SPhilippe Reynes #define MAX1027_REF_MODE2 (0x02 << 2) 45fc167f62SPhilippe Reynes #define MAX1027_REF_MODE3 (0x03 << 2) 46fc167f62SPhilippe Reynes #define MAX1027_CKS_MODE0 (0x00 << 4) 47fc167f62SPhilippe Reynes #define MAX1027_CKS_MODE1 (0x01 << 4) 48fc167f62SPhilippe Reynes #define MAX1027_CKS_MODE2 (0x02 << 4) 49fc167f62SPhilippe Reynes #define MAX1027_CKS_MODE3 (0x03 << 4) 50fc167f62SPhilippe Reynes 51fc167f62SPhilippe Reynes /* averaging register */ 52fc167f62SPhilippe Reynes #define MAX1027_NSCAN_4 0x00 53fc167f62SPhilippe Reynes #define MAX1027_NSCAN_8 0x01 54fc167f62SPhilippe Reynes #define MAX1027_NSCAN_12 0x02 55fc167f62SPhilippe Reynes #define MAX1027_NSCAN_16 0x03 56fc167f62SPhilippe Reynes #define MAX1027_NAVG_4 (0x00 << 2) 57fc167f62SPhilippe Reynes #define MAX1027_NAVG_8 (0x01 << 2) 58fc167f62SPhilippe Reynes #define MAX1027_NAVG_16 (0x02 << 2) 59fc167f62SPhilippe Reynes #define MAX1027_NAVG_32 (0x03 << 2) 60fc167f62SPhilippe Reynes #define MAX1027_AVG_EN BIT(4) 61fc167f62SPhilippe Reynes 62fc167f62SPhilippe Reynes enum max1027_id { 63fc167f62SPhilippe Reynes max1027, 64fc167f62SPhilippe Reynes max1029, 65fc167f62SPhilippe Reynes max1031, 66*ae47d009SMiquel Raynal max1227, 67*ae47d009SMiquel Raynal max1229, 68*ae47d009SMiquel Raynal max1231, 69fc167f62SPhilippe Reynes }; 70fc167f62SPhilippe Reynes 71fc167f62SPhilippe Reynes static const struct spi_device_id max1027_id[] = { 72fc167f62SPhilippe Reynes {"max1027", max1027}, 73fc167f62SPhilippe Reynes {"max1029", max1029}, 74fc167f62SPhilippe Reynes {"max1031", max1031}, 75*ae47d009SMiquel Raynal {"max1227", max1227}, 76*ae47d009SMiquel Raynal {"max1229", max1229}, 77*ae47d009SMiquel Raynal {"max1231", max1231}, 78fc167f62SPhilippe Reynes {} 79fc167f62SPhilippe Reynes }; 80fc167f62SPhilippe Reynes MODULE_DEVICE_TABLE(spi, max1027_id); 81fc167f62SPhilippe Reynes 82fc167f62SPhilippe Reynes #ifdef CONFIG_OF 83fc167f62SPhilippe Reynes static const struct of_device_id max1027_adc_dt_ids[] = { 84fc167f62SPhilippe Reynes { .compatible = "maxim,max1027" }, 85fc167f62SPhilippe Reynes { .compatible = "maxim,max1029" }, 86fc167f62SPhilippe Reynes { .compatible = "maxim,max1031" }, 87*ae47d009SMiquel Raynal { .compatible = "maxim,max1227" }, 88*ae47d009SMiquel Raynal { .compatible = "maxim,max1229" }, 89*ae47d009SMiquel Raynal { .compatible = "maxim,max1231" }, 90fc167f62SPhilippe Reynes {}, 91fc167f62SPhilippe Reynes }; 92fc167f62SPhilippe Reynes MODULE_DEVICE_TABLE(of, max1027_adc_dt_ids); 93fc167f62SPhilippe Reynes #endif 94fc167f62SPhilippe Reynes 957af5257dSMiquel Raynal #define MAX1027_V_CHAN(index, depth) \ 96fc167f62SPhilippe Reynes { \ 97fc167f62SPhilippe Reynes .type = IIO_VOLTAGE, \ 98fc167f62SPhilippe Reynes .indexed = 1, \ 99fc167f62SPhilippe Reynes .channel = index, \ 100fc167f62SPhilippe Reynes .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ 101fc167f62SPhilippe Reynes .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ 102fc167f62SPhilippe Reynes .scan_index = index + 1, \ 103fc167f62SPhilippe Reynes .scan_type = { \ 104fc167f62SPhilippe Reynes .sign = 'u', \ 1057af5257dSMiquel Raynal .realbits = depth, \ 106fc167f62SPhilippe Reynes .storagebits = 16, \ 107fc167f62SPhilippe Reynes .shift = 2, \ 108fc167f62SPhilippe Reynes .endianness = IIO_BE, \ 109fc167f62SPhilippe Reynes }, \ 110fc167f62SPhilippe Reynes } 111fc167f62SPhilippe Reynes 112fc167f62SPhilippe Reynes #define MAX1027_T_CHAN \ 113fc167f62SPhilippe Reynes { \ 114fc167f62SPhilippe Reynes .type = IIO_TEMP, \ 115fc167f62SPhilippe Reynes .channel = 0, \ 116fc167f62SPhilippe Reynes .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ 117fc167f62SPhilippe Reynes .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ 118fc167f62SPhilippe Reynes .scan_index = 0, \ 119fc167f62SPhilippe Reynes .scan_type = { \ 120fc167f62SPhilippe Reynes .sign = 'u', \ 121fc167f62SPhilippe Reynes .realbits = 12, \ 122fc167f62SPhilippe Reynes .storagebits = 16, \ 123fc167f62SPhilippe Reynes .endianness = IIO_BE, \ 124fc167f62SPhilippe Reynes }, \ 125fc167f62SPhilippe Reynes } 126fc167f62SPhilippe Reynes 1277af5257dSMiquel Raynal #define MAX1X27_CHANNELS(depth) \ 1287af5257dSMiquel Raynal MAX1027_T_CHAN, \ 1297af5257dSMiquel Raynal MAX1027_V_CHAN(0, depth), \ 1307af5257dSMiquel Raynal MAX1027_V_CHAN(1, depth), \ 1317af5257dSMiquel Raynal MAX1027_V_CHAN(2, depth), \ 1327af5257dSMiquel Raynal MAX1027_V_CHAN(3, depth), \ 1337af5257dSMiquel Raynal MAX1027_V_CHAN(4, depth), \ 1347af5257dSMiquel Raynal MAX1027_V_CHAN(5, depth), \ 1357af5257dSMiquel Raynal MAX1027_V_CHAN(6, depth), \ 1367af5257dSMiquel Raynal MAX1027_V_CHAN(7, depth) 1377af5257dSMiquel Raynal 1387af5257dSMiquel Raynal #define MAX1X29_CHANNELS(depth) \ 1397af5257dSMiquel Raynal MAX1X27_CHANNELS(depth), \ 1407af5257dSMiquel Raynal MAX1027_V_CHAN(8, depth), \ 1417af5257dSMiquel Raynal MAX1027_V_CHAN(9, depth), \ 1427af5257dSMiquel Raynal MAX1027_V_CHAN(10, depth), \ 1437af5257dSMiquel Raynal MAX1027_V_CHAN(11, depth) 1447af5257dSMiquel Raynal 1457af5257dSMiquel Raynal #define MAX1X31_CHANNELS(depth) \ 1467af5257dSMiquel Raynal MAX1X27_CHANNELS(depth), \ 1477af5257dSMiquel Raynal MAX1X29_CHANNELS(depth), \ 1487af5257dSMiquel Raynal MAX1027_V_CHAN(12, depth), \ 1497af5257dSMiquel Raynal MAX1027_V_CHAN(13, depth), \ 1507af5257dSMiquel Raynal MAX1027_V_CHAN(14, depth), \ 1517af5257dSMiquel Raynal MAX1027_V_CHAN(15, depth) 1527af5257dSMiquel Raynal 153fc167f62SPhilippe Reynes static const struct iio_chan_spec max1027_channels[] = { 1547af5257dSMiquel Raynal MAX1X27_CHANNELS(10), 155fc167f62SPhilippe Reynes }; 156fc167f62SPhilippe Reynes 157fc167f62SPhilippe Reynes static const struct iio_chan_spec max1029_channels[] = { 1587af5257dSMiquel Raynal MAX1X29_CHANNELS(10), 159fc167f62SPhilippe Reynes }; 160fc167f62SPhilippe Reynes 161fc167f62SPhilippe Reynes static const struct iio_chan_spec max1031_channels[] = { 1627af5257dSMiquel Raynal MAX1X31_CHANNELS(10), 163fc167f62SPhilippe Reynes }; 164fc167f62SPhilippe Reynes 165*ae47d009SMiquel Raynal static const struct iio_chan_spec max1227_channels[] = { 166*ae47d009SMiquel Raynal MAX1X27_CHANNELS(12), 167*ae47d009SMiquel Raynal }; 168*ae47d009SMiquel Raynal 169*ae47d009SMiquel Raynal static const struct iio_chan_spec max1229_channels[] = { 170*ae47d009SMiquel Raynal MAX1X29_CHANNELS(12), 171*ae47d009SMiquel Raynal }; 172*ae47d009SMiquel Raynal 173*ae47d009SMiquel Raynal static const struct iio_chan_spec max1231_channels[] = { 174*ae47d009SMiquel Raynal MAX1X31_CHANNELS(12), 175*ae47d009SMiquel Raynal }; 176*ae47d009SMiquel Raynal 177fc167f62SPhilippe Reynes static const unsigned long max1027_available_scan_masks[] = { 178fc167f62SPhilippe Reynes 0x000001ff, 179fc167f62SPhilippe Reynes 0x00000000, 180fc167f62SPhilippe Reynes }; 181fc167f62SPhilippe Reynes 182fc167f62SPhilippe Reynes static const unsigned long max1029_available_scan_masks[] = { 183fc167f62SPhilippe Reynes 0x00001fff, 184fc167f62SPhilippe Reynes 0x00000000, 185fc167f62SPhilippe Reynes }; 186fc167f62SPhilippe Reynes 187fc167f62SPhilippe Reynes static const unsigned long max1031_available_scan_masks[] = { 188fc167f62SPhilippe Reynes 0x0001ffff, 189fc167f62SPhilippe Reynes 0x00000000, 190fc167f62SPhilippe Reynes }; 191fc167f62SPhilippe Reynes 192fc167f62SPhilippe Reynes struct max1027_chip_info { 193fc167f62SPhilippe Reynes const struct iio_chan_spec *channels; 194fc167f62SPhilippe Reynes unsigned int num_channels; 195fc167f62SPhilippe Reynes const unsigned long *available_scan_masks; 196fc167f62SPhilippe Reynes }; 197fc167f62SPhilippe Reynes 198fc167f62SPhilippe Reynes static const struct max1027_chip_info max1027_chip_info_tbl[] = { 199fc167f62SPhilippe Reynes [max1027] = { 200fc167f62SPhilippe Reynes .channels = max1027_channels, 201fc167f62SPhilippe Reynes .num_channels = ARRAY_SIZE(max1027_channels), 202fc167f62SPhilippe Reynes .available_scan_masks = max1027_available_scan_masks, 203fc167f62SPhilippe Reynes }, 204fc167f62SPhilippe Reynes [max1029] = { 205fc167f62SPhilippe Reynes .channels = max1029_channels, 206fc167f62SPhilippe Reynes .num_channels = ARRAY_SIZE(max1029_channels), 207fc167f62SPhilippe Reynes .available_scan_masks = max1029_available_scan_masks, 208fc167f62SPhilippe Reynes }, 209fc167f62SPhilippe Reynes [max1031] = { 210fc167f62SPhilippe Reynes .channels = max1031_channels, 211fc167f62SPhilippe Reynes .num_channels = ARRAY_SIZE(max1031_channels), 212fc167f62SPhilippe Reynes .available_scan_masks = max1031_available_scan_masks, 213fc167f62SPhilippe Reynes }, 214*ae47d009SMiquel Raynal [max1227] = { 215*ae47d009SMiquel Raynal .channels = max1227_channels, 216*ae47d009SMiquel Raynal .num_channels = ARRAY_SIZE(max1227_channels), 217*ae47d009SMiquel Raynal .available_scan_masks = max1027_available_scan_masks, 218*ae47d009SMiquel Raynal }, 219*ae47d009SMiquel Raynal [max1229] = { 220*ae47d009SMiquel Raynal .channels = max1229_channels, 221*ae47d009SMiquel Raynal .num_channels = ARRAY_SIZE(max1229_channels), 222*ae47d009SMiquel Raynal .available_scan_masks = max1029_available_scan_masks, 223*ae47d009SMiquel Raynal }, 224*ae47d009SMiquel Raynal [max1231] = { 225*ae47d009SMiquel Raynal .channels = max1231_channels, 226*ae47d009SMiquel Raynal .num_channels = ARRAY_SIZE(max1231_channels), 227*ae47d009SMiquel Raynal .available_scan_masks = max1031_available_scan_masks, 228*ae47d009SMiquel Raynal }, 229fc167f62SPhilippe Reynes }; 230fc167f62SPhilippe Reynes 231fc167f62SPhilippe Reynes struct max1027_state { 232fc167f62SPhilippe Reynes const struct max1027_chip_info *info; 233fc167f62SPhilippe Reynes struct spi_device *spi; 234fc167f62SPhilippe Reynes struct iio_trigger *trig; 235fc167f62SPhilippe Reynes __be16 *buffer; 236fc167f62SPhilippe Reynes struct mutex lock; 237fc167f62SPhilippe Reynes 238fc167f62SPhilippe Reynes u8 reg ____cacheline_aligned; 239fc167f62SPhilippe Reynes }; 240fc167f62SPhilippe Reynes 241fc167f62SPhilippe Reynes static int max1027_read_single_value(struct iio_dev *indio_dev, 242fc167f62SPhilippe Reynes struct iio_chan_spec const *chan, 243fc167f62SPhilippe Reynes int *val) 244fc167f62SPhilippe Reynes { 245fc167f62SPhilippe Reynes int ret; 246fc167f62SPhilippe Reynes struct max1027_state *st = iio_priv(indio_dev); 247fc167f62SPhilippe Reynes 248fc167f62SPhilippe Reynes if (iio_buffer_enabled(indio_dev)) { 249fc167f62SPhilippe Reynes dev_warn(&indio_dev->dev, "trigger mode already enabled"); 250fc167f62SPhilippe Reynes return -EBUSY; 251fc167f62SPhilippe Reynes } 252fc167f62SPhilippe Reynes 253fc167f62SPhilippe Reynes /* Start acquisition on conversion register write */ 254fc167f62SPhilippe Reynes st->reg = MAX1027_SETUP_REG | MAX1027_REF_MODE2 | MAX1027_CKS_MODE2; 255fc167f62SPhilippe Reynes ret = spi_write(st->spi, &st->reg, 1); 256fc167f62SPhilippe Reynes if (ret < 0) { 257fc167f62SPhilippe Reynes dev_err(&indio_dev->dev, 258fc167f62SPhilippe Reynes "Failed to configure setup register\n"); 259fc167f62SPhilippe Reynes return ret; 260fc167f62SPhilippe Reynes } 261fc167f62SPhilippe Reynes 262fc167f62SPhilippe Reynes /* Configure conversion register with the requested chan */ 263fc167f62SPhilippe Reynes st->reg = MAX1027_CONV_REG | MAX1027_CHAN(chan->channel) | 26458b90a8dSSandhya Bankar MAX1027_NOSCAN; 26558b90a8dSSandhya Bankar if (chan->type == IIO_TEMP) 26658b90a8dSSandhya Bankar st->reg |= MAX1027_TEMP; 267fc167f62SPhilippe Reynes ret = spi_write(st->spi, &st->reg, 1); 268fc167f62SPhilippe Reynes if (ret < 0) { 269fc167f62SPhilippe Reynes dev_err(&indio_dev->dev, 270fc167f62SPhilippe Reynes "Failed to configure conversion register\n"); 271fc167f62SPhilippe Reynes return ret; 272fc167f62SPhilippe Reynes } 273fc167f62SPhilippe Reynes 274fc167f62SPhilippe Reynes /* 275fc167f62SPhilippe Reynes * For an unknown reason, when we use the mode "10" (write 276fc167f62SPhilippe Reynes * conversion register), the interrupt doesn't occur every time. 277fc167f62SPhilippe Reynes * So we just wait 1 ms. 278fc167f62SPhilippe Reynes */ 279fc167f62SPhilippe Reynes mdelay(1); 280fc167f62SPhilippe Reynes 281fc167f62SPhilippe Reynes /* Read result */ 282fc167f62SPhilippe Reynes ret = spi_read(st->spi, st->buffer, (chan->type == IIO_TEMP) ? 4 : 2); 283fc167f62SPhilippe Reynes if (ret < 0) 284fc167f62SPhilippe Reynes return ret; 285fc167f62SPhilippe Reynes 286fc167f62SPhilippe Reynes *val = be16_to_cpu(st->buffer[0]); 287fc167f62SPhilippe Reynes 288fc167f62SPhilippe Reynes return IIO_VAL_INT; 289fc167f62SPhilippe Reynes } 290fc167f62SPhilippe Reynes 291fc167f62SPhilippe Reynes static int max1027_read_raw(struct iio_dev *indio_dev, 292fc167f62SPhilippe Reynes struct iio_chan_spec const *chan, 293fc167f62SPhilippe Reynes int *val, int *val2, long mask) 294fc167f62SPhilippe Reynes { 295fc167f62SPhilippe Reynes int ret = 0; 296fc167f62SPhilippe Reynes struct max1027_state *st = iio_priv(indio_dev); 297fc167f62SPhilippe Reynes 298fc167f62SPhilippe Reynes mutex_lock(&st->lock); 299fc167f62SPhilippe Reynes 300fc167f62SPhilippe Reynes switch (mask) { 301fc167f62SPhilippe Reynes case IIO_CHAN_INFO_RAW: 302fc167f62SPhilippe Reynes ret = max1027_read_single_value(indio_dev, chan, val); 303fc167f62SPhilippe Reynes break; 304fc167f62SPhilippe Reynes case IIO_CHAN_INFO_SCALE: 305fc167f62SPhilippe Reynes switch (chan->type) { 306fc167f62SPhilippe Reynes case IIO_TEMP: 307fc167f62SPhilippe Reynes *val = 1; 308fc167f62SPhilippe Reynes *val2 = 8; 309fc167f62SPhilippe Reynes ret = IIO_VAL_FRACTIONAL; 310fc167f62SPhilippe Reynes break; 311fc167f62SPhilippe Reynes case IIO_VOLTAGE: 312fc167f62SPhilippe Reynes *val = 2500; 3137af5257dSMiquel Raynal *val2 = chan->scan_type.realbits; 314fc167f62SPhilippe Reynes ret = IIO_VAL_FRACTIONAL_LOG2; 315fc167f62SPhilippe Reynes break; 316fc167f62SPhilippe Reynes default: 317fc167f62SPhilippe Reynes ret = -EINVAL; 318fc167f62SPhilippe Reynes break; 319fc167f62SPhilippe Reynes } 320fc167f62SPhilippe Reynes break; 321fc167f62SPhilippe Reynes default: 322fc167f62SPhilippe Reynes ret = -EINVAL; 323fc167f62SPhilippe Reynes break; 324fc167f62SPhilippe Reynes } 325fc167f62SPhilippe Reynes 326fc167f62SPhilippe Reynes mutex_unlock(&st->lock); 327fc167f62SPhilippe Reynes 328fc167f62SPhilippe Reynes return ret; 329fc167f62SPhilippe Reynes } 330fc167f62SPhilippe Reynes 331fc167f62SPhilippe Reynes static int max1027_debugfs_reg_access(struct iio_dev *indio_dev, 332fc167f62SPhilippe Reynes unsigned reg, unsigned writeval, 333fc167f62SPhilippe Reynes unsigned *readval) 334fc167f62SPhilippe Reynes { 335fc167f62SPhilippe Reynes struct max1027_state *st = iio_priv(indio_dev); 336fc167f62SPhilippe Reynes u8 *val = (u8 *)st->buffer; 337fc167f62SPhilippe Reynes 338038696f8SMiquel Raynal if (readval) { 339038696f8SMiquel Raynal int ret = spi_read(st->spi, val, 2); 340038696f8SMiquel Raynal *readval = be16_to_cpu(st->buffer[0]); 341038696f8SMiquel Raynal return ret; 342038696f8SMiquel Raynal } 343fc167f62SPhilippe Reynes 344fc167f62SPhilippe Reynes *val = (u8)writeval; 345fc167f62SPhilippe Reynes return spi_write(st->spi, val, 1); 346fc167f62SPhilippe Reynes } 347fc167f62SPhilippe Reynes 348fc167f62SPhilippe Reynes static int max1027_validate_trigger(struct iio_dev *indio_dev, 349fc167f62SPhilippe Reynes struct iio_trigger *trig) 350fc167f62SPhilippe Reynes { 351fc167f62SPhilippe Reynes struct max1027_state *st = iio_priv(indio_dev); 352fc167f62SPhilippe Reynes 353fc167f62SPhilippe Reynes if (st->trig != trig) 354fc167f62SPhilippe Reynes return -EINVAL; 355fc167f62SPhilippe Reynes 356fc167f62SPhilippe Reynes return 0; 357fc167f62SPhilippe Reynes } 358fc167f62SPhilippe Reynes 359fc167f62SPhilippe Reynes static int max1027_set_trigger_state(struct iio_trigger *trig, bool state) 360fc167f62SPhilippe Reynes { 361fc167f62SPhilippe Reynes struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig); 362fc167f62SPhilippe Reynes struct max1027_state *st = iio_priv(indio_dev); 363fc167f62SPhilippe Reynes int ret; 364fc167f62SPhilippe Reynes 365fc167f62SPhilippe Reynes if (state) { 366fc167f62SPhilippe Reynes /* Start acquisition on cnvst */ 367fc167f62SPhilippe Reynes st->reg = MAX1027_SETUP_REG | MAX1027_CKS_MODE0 | 368fc167f62SPhilippe Reynes MAX1027_REF_MODE2; 369fc167f62SPhilippe Reynes ret = spi_write(st->spi, &st->reg, 1); 370fc167f62SPhilippe Reynes if (ret < 0) 371fc167f62SPhilippe Reynes return ret; 372fc167f62SPhilippe Reynes 373fc167f62SPhilippe Reynes /* Scan from 0 to max */ 374fc167f62SPhilippe Reynes st->reg = MAX1027_CONV_REG | MAX1027_CHAN(0) | 375fc167f62SPhilippe Reynes MAX1027_SCAN_N_M | MAX1027_TEMP; 376fc167f62SPhilippe Reynes ret = spi_write(st->spi, &st->reg, 1); 377fc167f62SPhilippe Reynes if (ret < 0) 378fc167f62SPhilippe Reynes return ret; 379fc167f62SPhilippe Reynes } else { 380fc167f62SPhilippe Reynes /* Start acquisition on conversion register write */ 381fc167f62SPhilippe Reynes st->reg = MAX1027_SETUP_REG | MAX1027_CKS_MODE2 | 382fc167f62SPhilippe Reynes MAX1027_REF_MODE2; 383fc167f62SPhilippe Reynes ret = spi_write(st->spi, &st->reg, 1); 384fc167f62SPhilippe Reynes if (ret < 0) 385fc167f62SPhilippe Reynes return ret; 386fc167f62SPhilippe Reynes } 387fc167f62SPhilippe Reynes 388fc167f62SPhilippe Reynes return 0; 389fc167f62SPhilippe Reynes } 390fc167f62SPhilippe Reynes 391fc167f62SPhilippe Reynes static irqreturn_t max1027_trigger_handler(int irq, void *private) 392fc167f62SPhilippe Reynes { 3930b568b3cSsimran singhal struct iio_poll_func *pf = private; 394fc167f62SPhilippe Reynes struct iio_dev *indio_dev = pf->indio_dev; 395fc167f62SPhilippe Reynes struct max1027_state *st = iio_priv(indio_dev); 396fc167f62SPhilippe Reynes 397fc167f62SPhilippe Reynes pr_debug("%s(irq=%d, private=0x%p)\n", __func__, irq, private); 398fc167f62SPhilippe Reynes 399fc167f62SPhilippe Reynes /* fill buffer with all channel */ 400fc167f62SPhilippe Reynes spi_read(st->spi, st->buffer, indio_dev->masklength * 2); 401fc167f62SPhilippe Reynes 402fc167f62SPhilippe Reynes iio_push_to_buffers(indio_dev, st->buffer); 403fc167f62SPhilippe Reynes 404fc167f62SPhilippe Reynes iio_trigger_notify_done(indio_dev->trig); 405fc167f62SPhilippe Reynes 406fc167f62SPhilippe Reynes return IRQ_HANDLED; 407fc167f62SPhilippe Reynes } 408fc167f62SPhilippe Reynes 409fc167f62SPhilippe Reynes static const struct iio_trigger_ops max1027_trigger_ops = { 410bea15d51SLars-Peter Clausen .validate_device = &iio_trigger_validate_own_device, 411fc167f62SPhilippe Reynes .set_trigger_state = &max1027_set_trigger_state, 412fc167f62SPhilippe Reynes }; 413fc167f62SPhilippe Reynes 414fc167f62SPhilippe Reynes static const struct iio_info max1027_info = { 415fc167f62SPhilippe Reynes .read_raw = &max1027_read_raw, 416fc167f62SPhilippe Reynes .validate_trigger = &max1027_validate_trigger, 417fc167f62SPhilippe Reynes .debugfs_reg_access = &max1027_debugfs_reg_access, 418fc167f62SPhilippe Reynes }; 419fc167f62SPhilippe Reynes 420fc167f62SPhilippe Reynes static int max1027_probe(struct spi_device *spi) 421fc167f62SPhilippe Reynes { 422fc167f62SPhilippe Reynes int ret; 423fc167f62SPhilippe Reynes struct iio_dev *indio_dev; 424fc167f62SPhilippe Reynes struct max1027_state *st; 425fc167f62SPhilippe Reynes 426fc167f62SPhilippe Reynes pr_debug("%s: probe(spi = 0x%p)\n", __func__, spi); 427fc167f62SPhilippe Reynes 428fc167f62SPhilippe Reynes indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); 429fc167f62SPhilippe Reynes if (indio_dev == NULL) { 430fc167f62SPhilippe Reynes pr_err("Can't allocate iio device\n"); 431fc167f62SPhilippe Reynes return -ENOMEM; 432fc167f62SPhilippe Reynes } 433fc167f62SPhilippe Reynes 434fc167f62SPhilippe Reynes spi_set_drvdata(spi, indio_dev); 435fc167f62SPhilippe Reynes 436fc167f62SPhilippe Reynes st = iio_priv(indio_dev); 437fc167f62SPhilippe Reynes st->spi = spi; 438fc167f62SPhilippe Reynes st->info = &max1027_chip_info_tbl[spi_get_device_id(spi)->driver_data]; 439fc167f62SPhilippe Reynes 440fc167f62SPhilippe Reynes mutex_init(&st->lock); 441fc167f62SPhilippe Reynes 442fc167f62SPhilippe Reynes indio_dev->name = spi_get_device_id(spi)->name; 443fc167f62SPhilippe Reynes indio_dev->dev.parent = &spi->dev; 444b541eaffSMatt Ranostay indio_dev->dev.of_node = spi->dev.of_node; 445fc167f62SPhilippe Reynes indio_dev->info = &max1027_info; 446fc167f62SPhilippe Reynes indio_dev->modes = INDIO_DIRECT_MODE; 447fc167f62SPhilippe Reynes indio_dev->channels = st->info->channels; 448fc167f62SPhilippe Reynes indio_dev->num_channels = st->info->num_channels; 449fc167f62SPhilippe Reynes indio_dev->available_scan_masks = st->info->available_scan_masks; 450fc167f62SPhilippe Reynes 4513c4211baSKees Cook st->buffer = devm_kmalloc_array(&indio_dev->dev, 4523c4211baSKees Cook indio_dev->num_channels, 2, 453fc167f62SPhilippe Reynes GFP_KERNEL); 454fc167f62SPhilippe Reynes if (st->buffer == NULL) { 455d939be3aSMasanari Iida dev_err(&indio_dev->dev, "Can't allocate buffer\n"); 456fc167f62SPhilippe Reynes return -ENOMEM; 457fc167f62SPhilippe Reynes } 458fc167f62SPhilippe Reynes 459ffae1067SMiquel Raynal if (spi->irq) { 4602715a281SChuhong Yuan ret = devm_iio_triggered_buffer_setup(&spi->dev, indio_dev, 4612715a281SChuhong Yuan &iio_pollfunc_store_time, 462ffae1067SMiquel Raynal &max1027_trigger_handler, 463ffae1067SMiquel Raynal NULL); 464fc167f62SPhilippe Reynes if (ret < 0) { 465fc167f62SPhilippe Reynes dev_err(&indio_dev->dev, "Failed to setup buffer\n"); 466fc167f62SPhilippe Reynes return ret; 467fc167f62SPhilippe Reynes } 468fc167f62SPhilippe Reynes 469fc167f62SPhilippe Reynes st->trig = devm_iio_trigger_alloc(&spi->dev, "%s-trigger", 470fc167f62SPhilippe Reynes indio_dev->name); 471fc167f62SPhilippe Reynes if (st->trig == NULL) { 472fc167f62SPhilippe Reynes ret = -ENOMEM; 473ffae1067SMiquel Raynal dev_err(&indio_dev->dev, 474ffae1067SMiquel Raynal "Failed to allocate iio trigger\n"); 4752715a281SChuhong Yuan return ret; 476fc167f62SPhilippe Reynes } 477fc167f62SPhilippe Reynes 478fc167f62SPhilippe Reynes st->trig->ops = &max1027_trigger_ops; 479fc167f62SPhilippe Reynes st->trig->dev.parent = &spi->dev; 480fc167f62SPhilippe Reynes iio_trigger_set_drvdata(st->trig, indio_dev); 481fc167f62SPhilippe Reynes iio_trigger_register(st->trig); 482fc167f62SPhilippe Reynes 483fc167f62SPhilippe Reynes ret = devm_request_threaded_irq(&spi->dev, spi->irq, 484fc167f62SPhilippe Reynes iio_trigger_generic_data_rdy_poll, 485fc167f62SPhilippe Reynes NULL, 486fc167f62SPhilippe Reynes IRQF_TRIGGER_FALLING, 487ffae1067SMiquel Raynal spi->dev.driver->name, 488ffae1067SMiquel Raynal st->trig); 489fc167f62SPhilippe Reynes if (ret < 0) { 490fc167f62SPhilippe Reynes dev_err(&indio_dev->dev, "Failed to allocate IRQ.\n"); 4912715a281SChuhong Yuan return ret; 492fc167f62SPhilippe Reynes } 493ffae1067SMiquel Raynal } 494fc167f62SPhilippe Reynes 495db033831SMiquel Raynal /* Internal reset */ 496db033831SMiquel Raynal st->reg = MAX1027_RST_REG; 497db033831SMiquel Raynal ret = spi_write(st->spi, &st->reg, 1); 498db033831SMiquel Raynal if (ret < 0) { 499db033831SMiquel Raynal dev_err(&indio_dev->dev, "Failed to reset the ADC\n"); 500db033831SMiquel Raynal return ret; 501db033831SMiquel Raynal } 502db033831SMiquel Raynal 503fc167f62SPhilippe Reynes /* Disable averaging */ 504fc167f62SPhilippe Reynes st->reg = MAX1027_AVG_REG; 505fc167f62SPhilippe Reynes ret = spi_write(st->spi, &st->reg, 1); 506fc167f62SPhilippe Reynes if (ret < 0) { 507fc167f62SPhilippe Reynes dev_err(&indio_dev->dev, "Failed to configure averaging register\n"); 508fc167f62SPhilippe Reynes return ret; 509fc167f62SPhilippe Reynes } 510fc167f62SPhilippe Reynes 5112715a281SChuhong Yuan return devm_iio_device_register(&spi->dev, indio_dev); 512fc167f62SPhilippe Reynes } 513fc167f62SPhilippe Reynes 514fc167f62SPhilippe Reynes static struct spi_driver max1027_driver = { 515fc167f62SPhilippe Reynes .driver = { 516fc167f62SPhilippe Reynes .name = "max1027", 517d1b895feSJavier Martinez Canillas .of_match_table = of_match_ptr(max1027_adc_dt_ids), 518fc167f62SPhilippe Reynes }, 519fc167f62SPhilippe Reynes .probe = max1027_probe, 520fc167f62SPhilippe Reynes .id_table = max1027_id, 521fc167f62SPhilippe Reynes }; 522fc167f62SPhilippe Reynes module_spi_driver(max1027_driver); 523fc167f62SPhilippe Reynes 524fc167f62SPhilippe Reynes MODULE_AUTHOR("Philippe Reynes <tremyfr@yahoo.fr>"); 525*ae47d009SMiquel Raynal MODULE_DESCRIPTION("MAX1X27/MAX1X29/MAX1X31 ADC"); 526fc167f62SPhilippe Reynes MODULE_LICENSE("GPL v2"); 527