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 63fc167f62SPhilippe Reynes enum max1027_id { 64fc167f62SPhilippe Reynes max1027, 65fc167f62SPhilippe Reynes max1029, 66fc167f62SPhilippe Reynes max1031, 67ae47d009SMiquel Raynal max1227, 68ae47d009SMiquel Raynal max1229, 69ae47d009SMiquel Raynal max1231, 70fc167f62SPhilippe Reynes }; 71fc167f62SPhilippe Reynes 72fc167f62SPhilippe Reynes static const struct spi_device_id max1027_id[] = { 73fc167f62SPhilippe Reynes {"max1027", max1027}, 74fc167f62SPhilippe Reynes {"max1029", max1029}, 75fc167f62SPhilippe Reynes {"max1031", max1031}, 76ae47d009SMiquel Raynal {"max1227", max1227}, 77ae47d009SMiquel Raynal {"max1229", max1229}, 78ae47d009SMiquel Raynal {"max1231", max1231}, 79fc167f62SPhilippe Reynes {} 80fc167f62SPhilippe Reynes }; 81fc167f62SPhilippe Reynes MODULE_DEVICE_TABLE(spi, max1027_id); 82fc167f62SPhilippe Reynes 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" }, 87ae47d009SMiquel Raynal { .compatible = "maxim,max1227" }, 88ae47d009SMiquel Raynal { .compatible = "maxim,max1229" }, 89ae47d009SMiquel Raynal { .compatible = "maxim,max1231" }, 90fc167f62SPhilippe Reynes {}, 91fc167f62SPhilippe Reynes }; 92fc167f62SPhilippe Reynes MODULE_DEVICE_TABLE(of, max1027_adc_dt_ids); 93fc167f62SPhilippe Reynes 947af5257dSMiquel Raynal #define MAX1027_V_CHAN(index, depth) \ 95fc167f62SPhilippe Reynes { \ 96fc167f62SPhilippe Reynes .type = IIO_VOLTAGE, \ 97fc167f62SPhilippe Reynes .indexed = 1, \ 98fc167f62SPhilippe Reynes .channel = index, \ 99fc167f62SPhilippe Reynes .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ 100fc167f62SPhilippe Reynes .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ 101fc167f62SPhilippe Reynes .scan_index = index + 1, \ 102fc167f62SPhilippe Reynes .scan_type = { \ 103fc167f62SPhilippe Reynes .sign = 'u', \ 1047af5257dSMiquel Raynal .realbits = depth, \ 105fc167f62SPhilippe Reynes .storagebits = 16, \ 106fc167f62SPhilippe Reynes .shift = 2, \ 107fc167f62SPhilippe Reynes .endianness = IIO_BE, \ 108fc167f62SPhilippe Reynes }, \ 109fc167f62SPhilippe Reynes } 110fc167f62SPhilippe Reynes 111fc167f62SPhilippe Reynes #define MAX1027_T_CHAN \ 112fc167f62SPhilippe Reynes { \ 113fc167f62SPhilippe Reynes .type = IIO_TEMP, \ 114fc167f62SPhilippe Reynes .channel = 0, \ 115fc167f62SPhilippe Reynes .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ 116fc167f62SPhilippe Reynes .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ 117fc167f62SPhilippe Reynes .scan_index = 0, \ 118fc167f62SPhilippe Reynes .scan_type = { \ 119fc167f62SPhilippe Reynes .sign = 'u', \ 120fc167f62SPhilippe Reynes .realbits = 12, \ 121fc167f62SPhilippe Reynes .storagebits = 16, \ 122fc167f62SPhilippe Reynes .endianness = IIO_BE, \ 123fc167f62SPhilippe Reynes }, \ 124fc167f62SPhilippe Reynes } 125fc167f62SPhilippe Reynes 1267af5257dSMiquel Raynal #define MAX1X27_CHANNELS(depth) \ 1277af5257dSMiquel Raynal MAX1027_T_CHAN, \ 1287af5257dSMiquel Raynal MAX1027_V_CHAN(0, depth), \ 1297af5257dSMiquel Raynal MAX1027_V_CHAN(1, depth), \ 1307af5257dSMiquel Raynal MAX1027_V_CHAN(2, depth), \ 1317af5257dSMiquel Raynal MAX1027_V_CHAN(3, depth), \ 1327af5257dSMiquel Raynal MAX1027_V_CHAN(4, depth), \ 1337af5257dSMiquel Raynal MAX1027_V_CHAN(5, depth), \ 1347af5257dSMiquel Raynal MAX1027_V_CHAN(6, depth), \ 1357af5257dSMiquel Raynal MAX1027_V_CHAN(7, depth) 1367af5257dSMiquel Raynal 1377af5257dSMiquel Raynal #define MAX1X29_CHANNELS(depth) \ 1387af5257dSMiquel Raynal MAX1X27_CHANNELS(depth), \ 1397af5257dSMiquel Raynal MAX1027_V_CHAN(8, depth), \ 1407af5257dSMiquel Raynal MAX1027_V_CHAN(9, depth), \ 1417af5257dSMiquel Raynal MAX1027_V_CHAN(10, depth), \ 1427af5257dSMiquel Raynal MAX1027_V_CHAN(11, depth) 1437af5257dSMiquel Raynal 1447af5257dSMiquel Raynal #define MAX1X31_CHANNELS(depth) \ 1457af5257dSMiquel Raynal MAX1X27_CHANNELS(depth), \ 1467af5257dSMiquel Raynal MAX1X29_CHANNELS(depth), \ 1477af5257dSMiquel Raynal MAX1027_V_CHAN(12, depth), \ 1487af5257dSMiquel Raynal MAX1027_V_CHAN(13, depth), \ 1497af5257dSMiquel Raynal MAX1027_V_CHAN(14, depth), \ 1507af5257dSMiquel Raynal MAX1027_V_CHAN(15, depth) 1517af5257dSMiquel Raynal 152fc167f62SPhilippe Reynes static const struct iio_chan_spec max1027_channels[] = { 1537af5257dSMiquel Raynal MAX1X27_CHANNELS(10), 154fc167f62SPhilippe Reynes }; 155fc167f62SPhilippe Reynes 156fc167f62SPhilippe Reynes static const struct iio_chan_spec max1029_channels[] = { 1577af5257dSMiquel Raynal MAX1X29_CHANNELS(10), 158fc167f62SPhilippe Reynes }; 159fc167f62SPhilippe Reynes 160fc167f62SPhilippe Reynes static const struct iio_chan_spec max1031_channels[] = { 1617af5257dSMiquel Raynal MAX1X31_CHANNELS(10), 162fc167f62SPhilippe Reynes }; 163fc167f62SPhilippe Reynes 164ae47d009SMiquel Raynal static const struct iio_chan_spec max1227_channels[] = { 165ae47d009SMiquel Raynal MAX1X27_CHANNELS(12), 166ae47d009SMiquel Raynal }; 167ae47d009SMiquel Raynal 168ae47d009SMiquel Raynal static const struct iio_chan_spec max1229_channels[] = { 169ae47d009SMiquel Raynal MAX1X29_CHANNELS(12), 170ae47d009SMiquel Raynal }; 171ae47d009SMiquel Raynal 172ae47d009SMiquel Raynal static const struct iio_chan_spec max1231_channels[] = { 173ae47d009SMiquel Raynal MAX1X31_CHANNELS(12), 174ae47d009SMiquel Raynal }; 175ae47d009SMiquel Raynal 176e1c0ea8fSMiquel Raynal /* 177e1c0ea8fSMiquel Raynal * These devices are able to scan from 0 to N, N being the highest voltage 178e1c0ea8fSMiquel Raynal * channel requested by the user. The temperature can be included or not, 179e1c0ea8fSMiquel Raynal * but cannot be retrieved alone. Based on the below 180e1c0ea8fSMiquel Raynal * ->available_scan_masks, the core will select the most appropriate 181e1c0ea8fSMiquel Raynal * ->active_scan_mask and the "minimum" number of channels will be 182e1c0ea8fSMiquel Raynal * scanned and pushed to the buffers. 183e1c0ea8fSMiquel Raynal * 184e1c0ea8fSMiquel Raynal * For example, if the user wants channels 1, 4 and 5, all channels from 185e1c0ea8fSMiquel Raynal * 0 to 5 will be scanned and pushed to the IIO buffers. The core will then 186e1c0ea8fSMiquel Raynal * filter out the unneeded samples based on the ->active_scan_mask that has 187e1c0ea8fSMiquel Raynal * been selected and only channels 1, 4 and 5 will be available to the user 188e1c0ea8fSMiquel Raynal * in the shared buffer. 189e1c0ea8fSMiquel Raynal */ 190e1c0ea8fSMiquel Raynal #define MAX1X27_SCAN_MASK_TEMP BIT(0) 191e1c0ea8fSMiquel Raynal 192e1c0ea8fSMiquel Raynal #define MAX1X27_SCAN_MASKS(temp) \ 193e1c0ea8fSMiquel Raynal GENMASK(1, 1 - (temp)), GENMASK(2, 1 - (temp)), \ 194e1c0ea8fSMiquel Raynal GENMASK(3, 1 - (temp)), GENMASK(4, 1 - (temp)), \ 195e1c0ea8fSMiquel Raynal GENMASK(5, 1 - (temp)), GENMASK(6, 1 - (temp)), \ 196e1c0ea8fSMiquel Raynal GENMASK(7, 1 - (temp)), GENMASK(8, 1 - (temp)) 197e1c0ea8fSMiquel Raynal 198e1c0ea8fSMiquel Raynal #define MAX1X29_SCAN_MASKS(temp) \ 199e1c0ea8fSMiquel Raynal MAX1X27_SCAN_MASKS(temp), \ 200e1c0ea8fSMiquel Raynal GENMASK(9, 1 - (temp)), GENMASK(10, 1 - (temp)), \ 201e1c0ea8fSMiquel Raynal GENMASK(11, 1 - (temp)), GENMASK(12, 1 - (temp)) 202e1c0ea8fSMiquel Raynal 203e1c0ea8fSMiquel Raynal #define MAX1X31_SCAN_MASKS(temp) \ 204e1c0ea8fSMiquel Raynal MAX1X29_SCAN_MASKS(temp), \ 205e1c0ea8fSMiquel Raynal GENMASK(13, 1 - (temp)), GENMASK(14, 1 - (temp)), \ 206e1c0ea8fSMiquel Raynal GENMASK(15, 1 - (temp)), GENMASK(16, 1 - (temp)) 207e1c0ea8fSMiquel Raynal 208fc167f62SPhilippe Reynes static const unsigned long max1027_available_scan_masks[] = { 209e1c0ea8fSMiquel Raynal MAX1X27_SCAN_MASKS(0), 210e1c0ea8fSMiquel Raynal MAX1X27_SCAN_MASKS(1), 211fc167f62SPhilippe Reynes 0x00000000, 212fc167f62SPhilippe Reynes }; 213fc167f62SPhilippe Reynes 214fc167f62SPhilippe Reynes static const unsigned long max1029_available_scan_masks[] = { 215e1c0ea8fSMiquel Raynal MAX1X29_SCAN_MASKS(0), 216e1c0ea8fSMiquel Raynal MAX1X29_SCAN_MASKS(1), 217fc167f62SPhilippe Reynes 0x00000000, 218fc167f62SPhilippe Reynes }; 219fc167f62SPhilippe Reynes 220fc167f62SPhilippe Reynes static const unsigned long max1031_available_scan_masks[] = { 221e1c0ea8fSMiquel Raynal MAX1X31_SCAN_MASKS(0), 222e1c0ea8fSMiquel Raynal MAX1X31_SCAN_MASKS(1), 223fc167f62SPhilippe Reynes 0x00000000, 224fc167f62SPhilippe Reynes }; 225fc167f62SPhilippe Reynes 226fc167f62SPhilippe Reynes struct max1027_chip_info { 227fc167f62SPhilippe Reynes const struct iio_chan_spec *channels; 228fc167f62SPhilippe Reynes unsigned int num_channels; 229fc167f62SPhilippe Reynes const unsigned long *available_scan_masks; 230fc167f62SPhilippe Reynes }; 231fc167f62SPhilippe Reynes 232fc167f62SPhilippe Reynes static const struct max1027_chip_info max1027_chip_info_tbl[] = { 233fc167f62SPhilippe Reynes [max1027] = { 234fc167f62SPhilippe Reynes .channels = max1027_channels, 235fc167f62SPhilippe Reynes .num_channels = ARRAY_SIZE(max1027_channels), 236fc167f62SPhilippe Reynes .available_scan_masks = max1027_available_scan_masks, 237fc167f62SPhilippe Reynes }, 238fc167f62SPhilippe Reynes [max1029] = { 239fc167f62SPhilippe Reynes .channels = max1029_channels, 240fc167f62SPhilippe Reynes .num_channels = ARRAY_SIZE(max1029_channels), 241fc167f62SPhilippe Reynes .available_scan_masks = max1029_available_scan_masks, 242fc167f62SPhilippe Reynes }, 243fc167f62SPhilippe Reynes [max1031] = { 244fc167f62SPhilippe Reynes .channels = max1031_channels, 245fc167f62SPhilippe Reynes .num_channels = ARRAY_SIZE(max1031_channels), 246fc167f62SPhilippe Reynes .available_scan_masks = max1031_available_scan_masks, 247fc167f62SPhilippe Reynes }, 248ae47d009SMiquel Raynal [max1227] = { 249ae47d009SMiquel Raynal .channels = max1227_channels, 250ae47d009SMiquel Raynal .num_channels = ARRAY_SIZE(max1227_channels), 251ae47d009SMiquel Raynal .available_scan_masks = max1027_available_scan_masks, 252ae47d009SMiquel Raynal }, 253ae47d009SMiquel Raynal [max1229] = { 254ae47d009SMiquel Raynal .channels = max1229_channels, 255ae47d009SMiquel Raynal .num_channels = ARRAY_SIZE(max1229_channels), 256ae47d009SMiquel Raynal .available_scan_masks = max1029_available_scan_masks, 257ae47d009SMiquel Raynal }, 258ae47d009SMiquel Raynal [max1231] = { 259ae47d009SMiquel Raynal .channels = max1231_channels, 260ae47d009SMiquel Raynal .num_channels = ARRAY_SIZE(max1231_channels), 261ae47d009SMiquel Raynal .available_scan_masks = max1031_available_scan_masks, 262ae47d009SMiquel Raynal }, 263fc167f62SPhilippe Reynes }; 264fc167f62SPhilippe Reynes 265fc167f62SPhilippe Reynes struct max1027_state { 266fc167f62SPhilippe Reynes const struct max1027_chip_info *info; 267fc167f62SPhilippe Reynes struct spi_device *spi; 268fc167f62SPhilippe Reynes struct iio_trigger *trig; 269fc167f62SPhilippe Reynes __be16 *buffer; 270fc167f62SPhilippe Reynes struct mutex lock; 271fc167f62SPhilippe Reynes 272fc167f62SPhilippe Reynes u8 reg ____cacheline_aligned; 273fc167f62SPhilippe Reynes }; 274fc167f62SPhilippe Reynes 275eaf57d50SMiquel Raynal static int max1027_enable_trigger(struct iio_dev *indio_dev, bool enable) 276eaf57d50SMiquel Raynal { 277eaf57d50SMiquel Raynal struct max1027_state *st = iio_priv(indio_dev); 278eaf57d50SMiquel Raynal 279eaf57d50SMiquel Raynal st->reg = MAX1027_SETUP_REG | MAX1027_REF_MODE2; 280eaf57d50SMiquel Raynal 281eaf57d50SMiquel Raynal /* 282eaf57d50SMiquel Raynal * Start acquisition on: 283eaf57d50SMiquel Raynal * MODE0: external hardware trigger wired to the cnvst input pin 284eaf57d50SMiquel Raynal * MODE2: conversion register write 285eaf57d50SMiquel Raynal */ 286eaf57d50SMiquel Raynal if (enable) 287eaf57d50SMiquel Raynal st->reg |= MAX1027_CKS_MODE0; 288eaf57d50SMiquel Raynal else 289eaf57d50SMiquel Raynal st->reg |= MAX1027_CKS_MODE2; 290eaf57d50SMiquel Raynal 291eaf57d50SMiquel Raynal return spi_write(st->spi, &st->reg, 1); 292eaf57d50SMiquel Raynal } 293eaf57d50SMiquel Raynal 294fc167f62SPhilippe Reynes static int max1027_read_single_value(struct iio_dev *indio_dev, 295fc167f62SPhilippe Reynes struct iio_chan_spec const *chan, 296fc167f62SPhilippe Reynes int *val) 297fc167f62SPhilippe Reynes { 298fc167f62SPhilippe Reynes int ret; 299fc167f62SPhilippe Reynes struct max1027_state *st = iio_priv(indio_dev); 300fc167f62SPhilippe Reynes 301fc167f62SPhilippe Reynes if (iio_buffer_enabled(indio_dev)) { 302fc167f62SPhilippe Reynes dev_warn(&indio_dev->dev, "trigger mode already enabled"); 303fc167f62SPhilippe Reynes return -EBUSY; 304fc167f62SPhilippe Reynes } 305fc167f62SPhilippe Reynes 306fc167f62SPhilippe Reynes /* Configure conversion register with the requested chan */ 307fc167f62SPhilippe Reynes st->reg = MAX1027_CONV_REG | MAX1027_CHAN(chan->channel) | 30858b90a8dSSandhya Bankar MAX1027_NOSCAN; 30958b90a8dSSandhya Bankar if (chan->type == IIO_TEMP) 31058b90a8dSSandhya Bankar st->reg |= MAX1027_TEMP; 311fc167f62SPhilippe Reynes ret = spi_write(st->spi, &st->reg, 1); 312fc167f62SPhilippe Reynes if (ret < 0) { 313fc167f62SPhilippe Reynes dev_err(&indio_dev->dev, 314fc167f62SPhilippe Reynes "Failed to configure conversion register\n"); 315fc167f62SPhilippe Reynes return ret; 316fc167f62SPhilippe Reynes } 317fc167f62SPhilippe Reynes 318fc167f62SPhilippe Reynes /* 319fc167f62SPhilippe Reynes * For an unknown reason, when we use the mode "10" (write 320fc167f62SPhilippe Reynes * conversion register), the interrupt doesn't occur every time. 321fc167f62SPhilippe Reynes * So we just wait 1 ms. 322fc167f62SPhilippe Reynes */ 323fc167f62SPhilippe Reynes mdelay(1); 324fc167f62SPhilippe Reynes 325fc167f62SPhilippe Reynes /* Read result */ 326fc167f62SPhilippe Reynes ret = spi_read(st->spi, st->buffer, (chan->type == IIO_TEMP) ? 4 : 2); 327fc167f62SPhilippe Reynes if (ret < 0) 328fc167f62SPhilippe Reynes return ret; 329fc167f62SPhilippe Reynes 330fc167f62SPhilippe Reynes *val = be16_to_cpu(st->buffer[0]); 331fc167f62SPhilippe Reynes 332fc167f62SPhilippe Reynes return IIO_VAL_INT; 333fc167f62SPhilippe Reynes } 334fc167f62SPhilippe Reynes 335fc167f62SPhilippe Reynes static int max1027_read_raw(struct iio_dev *indio_dev, 336fc167f62SPhilippe Reynes struct iio_chan_spec const *chan, 337fc167f62SPhilippe Reynes int *val, int *val2, long mask) 338fc167f62SPhilippe Reynes { 339fc167f62SPhilippe Reynes int ret = 0; 340fc167f62SPhilippe Reynes struct max1027_state *st = iio_priv(indio_dev); 341fc167f62SPhilippe Reynes 342fc167f62SPhilippe Reynes mutex_lock(&st->lock); 343fc167f62SPhilippe Reynes 344fc167f62SPhilippe Reynes switch (mask) { 345fc167f62SPhilippe Reynes case IIO_CHAN_INFO_RAW: 346fc167f62SPhilippe Reynes ret = max1027_read_single_value(indio_dev, chan, val); 347fc167f62SPhilippe Reynes break; 348fc167f62SPhilippe Reynes case IIO_CHAN_INFO_SCALE: 349fc167f62SPhilippe Reynes switch (chan->type) { 350fc167f62SPhilippe Reynes case IIO_TEMP: 351fc167f62SPhilippe Reynes *val = 1; 352fc167f62SPhilippe Reynes *val2 = 8; 353fc167f62SPhilippe Reynes ret = IIO_VAL_FRACTIONAL; 354fc167f62SPhilippe Reynes break; 355fc167f62SPhilippe Reynes case IIO_VOLTAGE: 356fc167f62SPhilippe Reynes *val = 2500; 3577af5257dSMiquel Raynal *val2 = chan->scan_type.realbits; 358fc167f62SPhilippe Reynes ret = IIO_VAL_FRACTIONAL_LOG2; 359fc167f62SPhilippe Reynes break; 360fc167f62SPhilippe Reynes default: 361fc167f62SPhilippe Reynes ret = -EINVAL; 362fc167f62SPhilippe Reynes break; 363fc167f62SPhilippe Reynes } 364fc167f62SPhilippe Reynes break; 365fc167f62SPhilippe Reynes default: 366fc167f62SPhilippe Reynes ret = -EINVAL; 367fc167f62SPhilippe Reynes break; 368fc167f62SPhilippe Reynes } 369fc167f62SPhilippe Reynes 370fc167f62SPhilippe Reynes mutex_unlock(&st->lock); 371fc167f62SPhilippe Reynes 372fc167f62SPhilippe Reynes return ret; 373fc167f62SPhilippe Reynes } 374fc167f62SPhilippe Reynes 375fc167f62SPhilippe Reynes static int max1027_debugfs_reg_access(struct iio_dev *indio_dev, 3767127822dSMiquel Raynal unsigned int reg, unsigned int writeval, 3777127822dSMiquel Raynal unsigned int *readval) 378fc167f62SPhilippe Reynes { 379fc167f62SPhilippe Reynes struct max1027_state *st = iio_priv(indio_dev); 380fc167f62SPhilippe Reynes u8 *val = (u8 *)st->buffer; 381fc167f62SPhilippe Reynes 382038696f8SMiquel Raynal if (readval) { 383038696f8SMiquel Raynal int ret = spi_read(st->spi, val, 2); 384038696f8SMiquel Raynal *readval = be16_to_cpu(st->buffer[0]); 385038696f8SMiquel Raynal return ret; 386038696f8SMiquel Raynal } 387fc167f62SPhilippe Reynes 388fc167f62SPhilippe Reynes *val = (u8)writeval; 389fc167f62SPhilippe Reynes return spi_write(st->spi, val, 1); 390fc167f62SPhilippe Reynes } 391fc167f62SPhilippe Reynes 392fc167f62SPhilippe Reynes static int max1027_validate_trigger(struct iio_dev *indio_dev, 393fc167f62SPhilippe Reynes struct iio_trigger *trig) 394fc167f62SPhilippe Reynes { 395fc167f62SPhilippe Reynes struct max1027_state *st = iio_priv(indio_dev); 396fc167f62SPhilippe Reynes 397fc167f62SPhilippe Reynes if (st->trig != trig) 398fc167f62SPhilippe Reynes return -EINVAL; 399fc167f62SPhilippe Reynes 400fc167f62SPhilippe Reynes return 0; 401fc167f62SPhilippe Reynes } 402fc167f62SPhilippe Reynes 4034201519aSMiquel Raynal static int max1027_set_cnvst_trigger_state(struct iio_trigger *trig, bool state) 404fc167f62SPhilippe Reynes { 405fc167f62SPhilippe Reynes struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig); 406fc167f62SPhilippe Reynes struct max1027_state *st = iio_priv(indio_dev); 407fc167f62SPhilippe Reynes int ret; 408fc167f62SPhilippe Reynes 409c5a39629SMiquel Raynal /* 410c5a39629SMiquel Raynal * In order to disable the convst trigger, start acquisition on 411c5a39629SMiquel Raynal * conversion register write, which basically disables triggering 412c5a39629SMiquel Raynal * conversions upon cnvst changes and thus has the effect of disabling 413c5a39629SMiquel Raynal * the external hardware trigger. 414c5a39629SMiquel Raynal */ 415eaf57d50SMiquel Raynal ret = max1027_enable_trigger(indio_dev, state); 416eaf57d50SMiquel Raynal if (ret) 417fc167f62SPhilippe Reynes return ret; 418fc167f62SPhilippe Reynes 419c5a39629SMiquel Raynal if (state) { 420e1c0ea8fSMiquel Raynal /* 421e1c0ea8fSMiquel Raynal * Scan from chan 0 to the highest requested channel. 422e1c0ea8fSMiquel Raynal * Include temperature on demand. 423e1c0ea8fSMiquel Raynal */ 424e1c0ea8fSMiquel Raynal st->reg = MAX1027_CONV_REG | MAX1027_SCAN_0_N; 425e1c0ea8fSMiquel Raynal st->reg |= MAX1027_CHAN(fls(*indio_dev->active_scan_mask) - 2); 426e1c0ea8fSMiquel Raynal if (*indio_dev->active_scan_mask & MAX1X27_SCAN_MASK_TEMP) 427e1c0ea8fSMiquel Raynal st->reg |= MAX1027_TEMP; 428e1c0ea8fSMiquel Raynal 429fc167f62SPhilippe Reynes ret = spi_write(st->spi, &st->reg, 1); 430fc167f62SPhilippe Reynes if (ret < 0) 431fc167f62SPhilippe Reynes return ret; 432fc167f62SPhilippe Reynes } 433fc167f62SPhilippe Reynes 434fc167f62SPhilippe Reynes return 0; 435fc167f62SPhilippe Reynes } 436fc167f62SPhilippe Reynes 437fc167f62SPhilippe Reynes static irqreturn_t max1027_trigger_handler(int irq, void *private) 438fc167f62SPhilippe Reynes { 4390b568b3cSsimran singhal struct iio_poll_func *pf = private; 440fc167f62SPhilippe Reynes struct iio_dev *indio_dev = pf->indio_dev; 441fc167f62SPhilippe Reynes struct max1027_state *st = iio_priv(indio_dev); 442e1c0ea8fSMiquel Raynal unsigned int scanned_chans; 443e1c0ea8fSMiquel Raynal 444e1c0ea8fSMiquel Raynal scanned_chans = fls(*indio_dev->active_scan_mask) - 1; 445e1c0ea8fSMiquel Raynal if (*indio_dev->active_scan_mask & MAX1X27_SCAN_MASK_TEMP) 446e1c0ea8fSMiquel Raynal scanned_chans++; 447fc167f62SPhilippe Reynes 448fc167f62SPhilippe Reynes /* fill buffer with all channel */ 449e1c0ea8fSMiquel Raynal spi_read(st->spi, st->buffer, scanned_chans * 2); 450fc167f62SPhilippe Reynes 451fc167f62SPhilippe Reynes iio_push_to_buffers(indio_dev, st->buffer); 452fc167f62SPhilippe Reynes 453fc167f62SPhilippe Reynes iio_trigger_notify_done(indio_dev->trig); 454fc167f62SPhilippe Reynes 455fc167f62SPhilippe Reynes return IRQ_HANDLED; 456fc167f62SPhilippe Reynes } 457fc167f62SPhilippe Reynes 458fc167f62SPhilippe Reynes static const struct iio_trigger_ops max1027_trigger_ops = { 459bea15d51SLars-Peter Clausen .validate_device = &iio_trigger_validate_own_device, 4604201519aSMiquel Raynal .set_trigger_state = &max1027_set_cnvst_trigger_state, 461fc167f62SPhilippe Reynes }; 462fc167f62SPhilippe Reynes 463fc167f62SPhilippe Reynes static const struct iio_info max1027_info = { 464fc167f62SPhilippe Reynes .read_raw = &max1027_read_raw, 465fc167f62SPhilippe Reynes .validate_trigger = &max1027_validate_trigger, 466fc167f62SPhilippe Reynes .debugfs_reg_access = &max1027_debugfs_reg_access, 467fc167f62SPhilippe Reynes }; 468fc167f62SPhilippe Reynes 469fc167f62SPhilippe Reynes static int max1027_probe(struct spi_device *spi) 470fc167f62SPhilippe Reynes { 471fc167f62SPhilippe Reynes int ret; 472fc167f62SPhilippe Reynes struct iio_dev *indio_dev; 473fc167f62SPhilippe Reynes struct max1027_state *st; 474fc167f62SPhilippe Reynes 475fc167f62SPhilippe Reynes indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); 4767127822dSMiquel Raynal if (!indio_dev) { 477fc167f62SPhilippe Reynes pr_err("Can't allocate iio device\n"); 478fc167f62SPhilippe Reynes return -ENOMEM; 479fc167f62SPhilippe Reynes } 480fc167f62SPhilippe Reynes 481fc167f62SPhilippe Reynes st = iio_priv(indio_dev); 482fc167f62SPhilippe Reynes st->spi = spi; 483fc167f62SPhilippe Reynes st->info = &max1027_chip_info_tbl[spi_get_device_id(spi)->driver_data]; 484fc167f62SPhilippe Reynes 485fc167f62SPhilippe Reynes mutex_init(&st->lock); 486fc167f62SPhilippe Reynes 487fc167f62SPhilippe Reynes indio_dev->name = spi_get_device_id(spi)->name; 488fc167f62SPhilippe Reynes indio_dev->info = &max1027_info; 489fc167f62SPhilippe Reynes indio_dev->modes = INDIO_DIRECT_MODE; 490fc167f62SPhilippe Reynes indio_dev->channels = st->info->channels; 491fc167f62SPhilippe Reynes indio_dev->num_channels = st->info->num_channels; 492fc167f62SPhilippe Reynes indio_dev->available_scan_masks = st->info->available_scan_masks; 493fc167f62SPhilippe Reynes 4943c4211baSKees Cook st->buffer = devm_kmalloc_array(&indio_dev->dev, 4953c4211baSKees Cook indio_dev->num_channels, 2, 496fc167f62SPhilippe Reynes GFP_KERNEL); 497064652c0SMiquel Raynal if (!st->buffer) 498fc167f62SPhilippe Reynes return -ENOMEM; 499fc167f62SPhilippe Reynes 500ffae1067SMiquel Raynal if (spi->irq) { 5012715a281SChuhong Yuan ret = devm_iio_triggered_buffer_setup(&spi->dev, indio_dev, 5022715a281SChuhong Yuan &iio_pollfunc_store_time, 503ffae1067SMiquel Raynal &max1027_trigger_handler, 504ffae1067SMiquel Raynal NULL); 505fc167f62SPhilippe Reynes if (ret < 0) { 506fc167f62SPhilippe Reynes dev_err(&indio_dev->dev, "Failed to setup buffer\n"); 507fc167f62SPhilippe Reynes return ret; 508fc167f62SPhilippe Reynes } 509fc167f62SPhilippe Reynes 510fc167f62SPhilippe Reynes st->trig = devm_iio_trigger_alloc(&spi->dev, "%s-trigger", 511fc167f62SPhilippe Reynes indio_dev->name); 5127127822dSMiquel Raynal if (!st->trig) { 513fc167f62SPhilippe Reynes ret = -ENOMEM; 514ffae1067SMiquel Raynal dev_err(&indio_dev->dev, 515ffae1067SMiquel Raynal "Failed to allocate iio trigger\n"); 5162715a281SChuhong Yuan return ret; 517fc167f62SPhilippe Reynes } 518fc167f62SPhilippe Reynes 519fc167f62SPhilippe Reynes st->trig->ops = &max1027_trigger_ops; 520fc167f62SPhilippe Reynes iio_trigger_set_drvdata(st->trig, indio_dev); 521c41d79b7SChuhong Yuan ret = devm_iio_trigger_register(&indio_dev->dev, 522c41d79b7SChuhong Yuan st->trig); 523c41d79b7SChuhong Yuan if (ret < 0) { 524c41d79b7SChuhong Yuan dev_err(&indio_dev->dev, 525c41d79b7SChuhong Yuan "Failed to register iio trigger\n"); 526c41d79b7SChuhong Yuan return ret; 527c41d79b7SChuhong Yuan } 528fc167f62SPhilippe Reynes 529fc167f62SPhilippe Reynes ret = devm_request_threaded_irq(&spi->dev, spi->irq, 530fc167f62SPhilippe Reynes iio_trigger_generic_data_rdy_poll, 531fc167f62SPhilippe Reynes NULL, 532fc167f62SPhilippe Reynes IRQF_TRIGGER_FALLING, 533ffae1067SMiquel Raynal spi->dev.driver->name, 534ffae1067SMiquel Raynal st->trig); 535fc167f62SPhilippe Reynes if (ret < 0) { 536fc167f62SPhilippe Reynes dev_err(&indio_dev->dev, "Failed to allocate IRQ.\n"); 5372715a281SChuhong Yuan return ret; 538fc167f62SPhilippe Reynes } 539ffae1067SMiquel Raynal } 540fc167f62SPhilippe Reynes 541db033831SMiquel Raynal /* Internal reset */ 542db033831SMiquel Raynal st->reg = MAX1027_RST_REG; 543db033831SMiquel Raynal ret = spi_write(st->spi, &st->reg, 1); 544db033831SMiquel Raynal if (ret < 0) { 545db033831SMiquel Raynal dev_err(&indio_dev->dev, "Failed to reset the ADC\n"); 546db033831SMiquel Raynal return ret; 547db033831SMiquel Raynal } 548db033831SMiquel Raynal 549fc167f62SPhilippe Reynes /* Disable averaging */ 550fc167f62SPhilippe Reynes st->reg = MAX1027_AVG_REG; 551fc167f62SPhilippe Reynes ret = spi_write(st->spi, &st->reg, 1); 552fc167f62SPhilippe Reynes if (ret < 0) { 553fc167f62SPhilippe Reynes dev_err(&indio_dev->dev, "Failed to configure averaging register\n"); 554fc167f62SPhilippe Reynes return ret; 555fc167f62SPhilippe Reynes } 556fc167f62SPhilippe Reynes 557*cba18232SMiquel Raynal /* Assume conversion on register write for now */ 558*cba18232SMiquel Raynal ret = max1027_enable_trigger(indio_dev, false); 559*cba18232SMiquel Raynal if (ret) 560*cba18232SMiquel Raynal return ret; 561*cba18232SMiquel Raynal 5622715a281SChuhong Yuan return devm_iio_device_register(&spi->dev, indio_dev); 563fc167f62SPhilippe Reynes } 564fc167f62SPhilippe Reynes 565fc167f62SPhilippe Reynes static struct spi_driver max1027_driver = { 566fc167f62SPhilippe Reynes .driver = { 567fc167f62SPhilippe Reynes .name = "max1027", 56853469fa5SJonathan Cameron .of_match_table = max1027_adc_dt_ids, 569fc167f62SPhilippe Reynes }, 570fc167f62SPhilippe Reynes .probe = max1027_probe, 571fc167f62SPhilippe Reynes .id_table = max1027_id, 572fc167f62SPhilippe Reynes }; 573fc167f62SPhilippe Reynes module_spi_driver(max1027_driver); 574fc167f62SPhilippe Reynes 575fc167f62SPhilippe Reynes MODULE_AUTHOR("Philippe Reynes <tremyfr@yahoo.fr>"); 576ae47d009SMiquel Raynal MODULE_DESCRIPTION("MAX1X27/MAX1X29/MAX1X31 ADC"); 577fc167f62SPhilippe Reynes MODULE_LICENSE("GPL v2"); 578