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 275af8b93e2SMiquel Raynal /* Scan from chan 0 to the highest requested channel. Include temperature on demand. */ 276af8b93e2SMiquel Raynal static int max1027_configure_chans_and_start(struct iio_dev *indio_dev) 277af8b93e2SMiquel Raynal { 278af8b93e2SMiquel Raynal struct max1027_state *st = iio_priv(indio_dev); 279af8b93e2SMiquel Raynal 280af8b93e2SMiquel Raynal st->reg = MAX1027_CONV_REG | MAX1027_SCAN_0_N; 281af8b93e2SMiquel Raynal st->reg |= MAX1027_CHAN(fls(*indio_dev->active_scan_mask) - 2); 282af8b93e2SMiquel Raynal if (*indio_dev->active_scan_mask & MAX1X27_SCAN_MASK_TEMP) 283af8b93e2SMiquel Raynal st->reg |= MAX1027_TEMP; 284af8b93e2SMiquel Raynal 285af8b93e2SMiquel Raynal return spi_write(st->spi, &st->reg, 1); 286af8b93e2SMiquel Raynal } 287af8b93e2SMiquel Raynal 288eaf57d50SMiquel Raynal static int max1027_enable_trigger(struct iio_dev *indio_dev, bool enable) 289eaf57d50SMiquel Raynal { 290eaf57d50SMiquel Raynal struct max1027_state *st = iio_priv(indio_dev); 291eaf57d50SMiquel Raynal 292eaf57d50SMiquel Raynal st->reg = MAX1027_SETUP_REG | MAX1027_REF_MODE2; 293eaf57d50SMiquel Raynal 294eaf57d50SMiquel Raynal /* 295eaf57d50SMiquel Raynal * Start acquisition on: 296eaf57d50SMiquel Raynal * MODE0: external hardware trigger wired to the cnvst input pin 297eaf57d50SMiquel Raynal * MODE2: conversion register write 298eaf57d50SMiquel Raynal */ 299eaf57d50SMiquel Raynal if (enable) 300eaf57d50SMiquel Raynal st->reg |= MAX1027_CKS_MODE0; 301eaf57d50SMiquel Raynal else 302eaf57d50SMiquel Raynal st->reg |= MAX1027_CKS_MODE2; 303eaf57d50SMiquel Raynal 304eaf57d50SMiquel Raynal return spi_write(st->spi, &st->reg, 1); 305eaf57d50SMiquel Raynal } 306eaf57d50SMiquel Raynal 307fc167f62SPhilippe Reynes static int max1027_read_single_value(struct iio_dev *indio_dev, 308fc167f62SPhilippe Reynes struct iio_chan_spec const *chan, 309fc167f62SPhilippe Reynes int *val) 310fc167f62SPhilippe Reynes { 311fc167f62SPhilippe Reynes int ret; 312fc167f62SPhilippe Reynes struct max1027_state *st = iio_priv(indio_dev); 313fc167f62SPhilippe Reynes 314*59fcc6afSMiquel Raynal ret = iio_device_claim_direct_mode(indio_dev); 315*59fcc6afSMiquel Raynal if (ret) 316*59fcc6afSMiquel Raynal return ret; 317fc167f62SPhilippe Reynes 318fc167f62SPhilippe Reynes /* Configure conversion register with the requested chan */ 319fc167f62SPhilippe Reynes st->reg = MAX1027_CONV_REG | MAX1027_CHAN(chan->channel) | 32058b90a8dSSandhya Bankar MAX1027_NOSCAN; 32158b90a8dSSandhya Bankar if (chan->type == IIO_TEMP) 32258b90a8dSSandhya Bankar st->reg |= MAX1027_TEMP; 323fc167f62SPhilippe Reynes ret = spi_write(st->spi, &st->reg, 1); 324fc167f62SPhilippe Reynes if (ret < 0) { 325fc167f62SPhilippe Reynes dev_err(&indio_dev->dev, 326fc167f62SPhilippe Reynes "Failed to configure conversion register\n"); 327*59fcc6afSMiquel Raynal iio_device_release_direct_mode(indio_dev); 328fc167f62SPhilippe Reynes return ret; 329fc167f62SPhilippe Reynes } 330fc167f62SPhilippe Reynes 331fc167f62SPhilippe Reynes /* 332fc167f62SPhilippe Reynes * For an unknown reason, when we use the mode "10" (write 333fc167f62SPhilippe Reynes * conversion register), the interrupt doesn't occur every time. 334fc167f62SPhilippe Reynes * So we just wait 1 ms. 335fc167f62SPhilippe Reynes */ 336fc167f62SPhilippe Reynes mdelay(1); 337fc167f62SPhilippe Reynes 338fc167f62SPhilippe Reynes /* Read result */ 339fc167f62SPhilippe Reynes ret = spi_read(st->spi, st->buffer, (chan->type == IIO_TEMP) ? 4 : 2); 340*59fcc6afSMiquel Raynal 341*59fcc6afSMiquel Raynal iio_device_release_direct_mode(indio_dev); 342*59fcc6afSMiquel Raynal 343fc167f62SPhilippe Reynes if (ret < 0) 344fc167f62SPhilippe Reynes return ret; 345fc167f62SPhilippe Reynes 346fc167f62SPhilippe Reynes *val = be16_to_cpu(st->buffer[0]); 347fc167f62SPhilippe Reynes 348fc167f62SPhilippe Reynes return IIO_VAL_INT; 349fc167f62SPhilippe Reynes } 350fc167f62SPhilippe Reynes 351fc167f62SPhilippe Reynes static int max1027_read_raw(struct iio_dev *indio_dev, 352fc167f62SPhilippe Reynes struct iio_chan_spec const *chan, 353fc167f62SPhilippe Reynes int *val, int *val2, long mask) 354fc167f62SPhilippe Reynes { 355fc167f62SPhilippe Reynes int ret = 0; 356fc167f62SPhilippe Reynes struct max1027_state *st = iio_priv(indio_dev); 357fc167f62SPhilippe Reynes 358fc167f62SPhilippe Reynes mutex_lock(&st->lock); 359fc167f62SPhilippe Reynes 360fc167f62SPhilippe Reynes switch (mask) { 361fc167f62SPhilippe Reynes case IIO_CHAN_INFO_RAW: 362fc167f62SPhilippe Reynes ret = max1027_read_single_value(indio_dev, chan, val); 363fc167f62SPhilippe Reynes break; 364fc167f62SPhilippe Reynes case IIO_CHAN_INFO_SCALE: 365fc167f62SPhilippe Reynes switch (chan->type) { 366fc167f62SPhilippe Reynes case IIO_TEMP: 367fc167f62SPhilippe Reynes *val = 1; 368fc167f62SPhilippe Reynes *val2 = 8; 369fc167f62SPhilippe Reynes ret = IIO_VAL_FRACTIONAL; 370fc167f62SPhilippe Reynes break; 371fc167f62SPhilippe Reynes case IIO_VOLTAGE: 372fc167f62SPhilippe Reynes *val = 2500; 3737af5257dSMiquel Raynal *val2 = chan->scan_type.realbits; 374fc167f62SPhilippe Reynes ret = IIO_VAL_FRACTIONAL_LOG2; 375fc167f62SPhilippe Reynes break; 376fc167f62SPhilippe Reynes default: 377fc167f62SPhilippe Reynes ret = -EINVAL; 378fc167f62SPhilippe Reynes break; 379fc167f62SPhilippe Reynes } 380fc167f62SPhilippe Reynes break; 381fc167f62SPhilippe Reynes default: 382fc167f62SPhilippe Reynes ret = -EINVAL; 383fc167f62SPhilippe Reynes break; 384fc167f62SPhilippe Reynes } 385fc167f62SPhilippe Reynes 386fc167f62SPhilippe Reynes mutex_unlock(&st->lock); 387fc167f62SPhilippe Reynes 388fc167f62SPhilippe Reynes return ret; 389fc167f62SPhilippe Reynes } 390fc167f62SPhilippe Reynes 391fc167f62SPhilippe Reynes static int max1027_debugfs_reg_access(struct iio_dev *indio_dev, 3927127822dSMiquel Raynal unsigned int reg, unsigned int writeval, 3937127822dSMiquel Raynal unsigned int *readval) 394fc167f62SPhilippe Reynes { 395fc167f62SPhilippe Reynes struct max1027_state *st = iio_priv(indio_dev); 396fc167f62SPhilippe Reynes u8 *val = (u8 *)st->buffer; 397fc167f62SPhilippe Reynes 398038696f8SMiquel Raynal if (readval) { 399038696f8SMiquel Raynal int ret = spi_read(st->spi, val, 2); 400038696f8SMiquel Raynal *readval = be16_to_cpu(st->buffer[0]); 401038696f8SMiquel Raynal return ret; 402038696f8SMiquel Raynal } 403fc167f62SPhilippe Reynes 404fc167f62SPhilippe Reynes *val = (u8)writeval; 405fc167f62SPhilippe Reynes return spi_write(st->spi, val, 1); 406fc167f62SPhilippe Reynes } 407fc167f62SPhilippe Reynes 408fc167f62SPhilippe Reynes static int max1027_validate_trigger(struct iio_dev *indio_dev, 409fc167f62SPhilippe Reynes struct iio_trigger *trig) 410fc167f62SPhilippe Reynes { 411fc167f62SPhilippe Reynes struct max1027_state *st = iio_priv(indio_dev); 412fc167f62SPhilippe Reynes 413fc167f62SPhilippe Reynes if (st->trig != trig) 414fc167f62SPhilippe Reynes return -EINVAL; 415fc167f62SPhilippe Reynes 416fc167f62SPhilippe Reynes return 0; 417fc167f62SPhilippe Reynes } 418fc167f62SPhilippe Reynes 4194201519aSMiquel Raynal static int max1027_set_cnvst_trigger_state(struct iio_trigger *trig, bool state) 420fc167f62SPhilippe Reynes { 421fc167f62SPhilippe Reynes struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig); 422fc167f62SPhilippe Reynes int ret; 423fc167f62SPhilippe Reynes 424c5a39629SMiquel Raynal /* 425c5a39629SMiquel Raynal * In order to disable the convst trigger, start acquisition on 426c5a39629SMiquel Raynal * conversion register write, which basically disables triggering 427c5a39629SMiquel Raynal * conversions upon cnvst changes and thus has the effect of disabling 428c5a39629SMiquel Raynal * the external hardware trigger. 429c5a39629SMiquel Raynal */ 430eaf57d50SMiquel Raynal ret = max1027_enable_trigger(indio_dev, state); 431eaf57d50SMiquel Raynal if (ret) 432fc167f62SPhilippe Reynes return ret; 433fc167f62SPhilippe Reynes 434c5a39629SMiquel Raynal if (state) { 435af8b93e2SMiquel Raynal ret = max1027_configure_chans_and_start(indio_dev); 436af8b93e2SMiquel Raynal if (ret) 437fc167f62SPhilippe Reynes return ret; 438fc167f62SPhilippe Reynes } 439fc167f62SPhilippe Reynes 440fc167f62SPhilippe Reynes return 0; 441fc167f62SPhilippe Reynes } 442fc167f62SPhilippe Reynes 443fc167f62SPhilippe Reynes static irqreturn_t max1027_trigger_handler(int irq, void *private) 444fc167f62SPhilippe Reynes { 4450b568b3cSsimran singhal struct iio_poll_func *pf = private; 446fc167f62SPhilippe Reynes struct iio_dev *indio_dev = pf->indio_dev; 447fc167f62SPhilippe Reynes struct max1027_state *st = iio_priv(indio_dev); 448e1c0ea8fSMiquel Raynal unsigned int scanned_chans; 449e1c0ea8fSMiquel Raynal 450e1c0ea8fSMiquel Raynal scanned_chans = fls(*indio_dev->active_scan_mask) - 1; 451e1c0ea8fSMiquel Raynal if (*indio_dev->active_scan_mask & MAX1X27_SCAN_MASK_TEMP) 452e1c0ea8fSMiquel Raynal scanned_chans++; 453fc167f62SPhilippe Reynes 454fc167f62SPhilippe Reynes /* fill buffer with all channel */ 455e1c0ea8fSMiquel Raynal spi_read(st->spi, st->buffer, scanned_chans * 2); 456fc167f62SPhilippe Reynes 457fc167f62SPhilippe Reynes iio_push_to_buffers(indio_dev, st->buffer); 458fc167f62SPhilippe Reynes 459fc167f62SPhilippe Reynes iio_trigger_notify_done(indio_dev->trig); 460fc167f62SPhilippe Reynes 461fc167f62SPhilippe Reynes return IRQ_HANDLED; 462fc167f62SPhilippe Reynes } 463fc167f62SPhilippe Reynes 464fc167f62SPhilippe Reynes static const struct iio_trigger_ops max1027_trigger_ops = { 465bea15d51SLars-Peter Clausen .validate_device = &iio_trigger_validate_own_device, 4664201519aSMiquel Raynal .set_trigger_state = &max1027_set_cnvst_trigger_state, 467fc167f62SPhilippe Reynes }; 468fc167f62SPhilippe Reynes 469fc167f62SPhilippe Reynes static const struct iio_info max1027_info = { 470fc167f62SPhilippe Reynes .read_raw = &max1027_read_raw, 471fc167f62SPhilippe Reynes .validate_trigger = &max1027_validate_trigger, 472fc167f62SPhilippe Reynes .debugfs_reg_access = &max1027_debugfs_reg_access, 473fc167f62SPhilippe Reynes }; 474fc167f62SPhilippe Reynes 475fc167f62SPhilippe Reynes static int max1027_probe(struct spi_device *spi) 476fc167f62SPhilippe Reynes { 477fc167f62SPhilippe Reynes int ret; 478fc167f62SPhilippe Reynes struct iio_dev *indio_dev; 479fc167f62SPhilippe Reynes struct max1027_state *st; 480fc167f62SPhilippe Reynes 481fc167f62SPhilippe Reynes indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); 4827127822dSMiquel Raynal if (!indio_dev) { 483fc167f62SPhilippe Reynes pr_err("Can't allocate iio device\n"); 484fc167f62SPhilippe Reynes return -ENOMEM; 485fc167f62SPhilippe Reynes } 486fc167f62SPhilippe Reynes 487fc167f62SPhilippe Reynes st = iio_priv(indio_dev); 488fc167f62SPhilippe Reynes st->spi = spi; 489fc167f62SPhilippe Reynes st->info = &max1027_chip_info_tbl[spi_get_device_id(spi)->driver_data]; 490fc167f62SPhilippe Reynes 491fc167f62SPhilippe Reynes mutex_init(&st->lock); 492fc167f62SPhilippe Reynes 493fc167f62SPhilippe Reynes indio_dev->name = spi_get_device_id(spi)->name; 494fc167f62SPhilippe Reynes indio_dev->info = &max1027_info; 495fc167f62SPhilippe Reynes indio_dev->modes = INDIO_DIRECT_MODE; 496fc167f62SPhilippe Reynes indio_dev->channels = st->info->channels; 497fc167f62SPhilippe Reynes indio_dev->num_channels = st->info->num_channels; 498fc167f62SPhilippe Reynes indio_dev->available_scan_masks = st->info->available_scan_masks; 499fc167f62SPhilippe Reynes 5003c4211baSKees Cook st->buffer = devm_kmalloc_array(&indio_dev->dev, 5013c4211baSKees Cook indio_dev->num_channels, 2, 502fc167f62SPhilippe Reynes GFP_KERNEL); 503064652c0SMiquel Raynal if (!st->buffer) 504fc167f62SPhilippe Reynes return -ENOMEM; 505fc167f62SPhilippe Reynes 506ffae1067SMiquel Raynal if (spi->irq) { 5072715a281SChuhong Yuan ret = devm_iio_triggered_buffer_setup(&spi->dev, indio_dev, 5082715a281SChuhong Yuan &iio_pollfunc_store_time, 509ffae1067SMiquel Raynal &max1027_trigger_handler, 510ffae1067SMiquel Raynal NULL); 511fc167f62SPhilippe Reynes if (ret < 0) { 512fc167f62SPhilippe Reynes dev_err(&indio_dev->dev, "Failed to setup buffer\n"); 513fc167f62SPhilippe Reynes return ret; 514fc167f62SPhilippe Reynes } 515fc167f62SPhilippe Reynes 516fc167f62SPhilippe Reynes st->trig = devm_iio_trigger_alloc(&spi->dev, "%s-trigger", 517fc167f62SPhilippe Reynes indio_dev->name); 5187127822dSMiquel Raynal if (!st->trig) { 519fc167f62SPhilippe Reynes ret = -ENOMEM; 520ffae1067SMiquel Raynal dev_err(&indio_dev->dev, 521ffae1067SMiquel Raynal "Failed to allocate iio trigger\n"); 5222715a281SChuhong Yuan return ret; 523fc167f62SPhilippe Reynes } 524fc167f62SPhilippe Reynes 525fc167f62SPhilippe Reynes st->trig->ops = &max1027_trigger_ops; 526fc167f62SPhilippe Reynes iio_trigger_set_drvdata(st->trig, indio_dev); 527c41d79b7SChuhong Yuan ret = devm_iio_trigger_register(&indio_dev->dev, 528c41d79b7SChuhong Yuan st->trig); 529c41d79b7SChuhong Yuan if (ret < 0) { 530c41d79b7SChuhong Yuan dev_err(&indio_dev->dev, 531c41d79b7SChuhong Yuan "Failed to register iio trigger\n"); 532c41d79b7SChuhong Yuan return ret; 533c41d79b7SChuhong Yuan } 534fc167f62SPhilippe Reynes 535fc167f62SPhilippe Reynes ret = devm_request_threaded_irq(&spi->dev, spi->irq, 536fc167f62SPhilippe Reynes iio_trigger_generic_data_rdy_poll, 537fc167f62SPhilippe Reynes NULL, 538fc167f62SPhilippe Reynes IRQF_TRIGGER_FALLING, 539ffae1067SMiquel Raynal spi->dev.driver->name, 540ffae1067SMiquel Raynal st->trig); 541fc167f62SPhilippe Reynes if (ret < 0) { 542fc167f62SPhilippe Reynes dev_err(&indio_dev->dev, "Failed to allocate IRQ.\n"); 5432715a281SChuhong Yuan return ret; 544fc167f62SPhilippe Reynes } 545ffae1067SMiquel Raynal } 546fc167f62SPhilippe Reynes 547db033831SMiquel Raynal /* Internal reset */ 548db033831SMiquel Raynal st->reg = MAX1027_RST_REG; 549db033831SMiquel Raynal ret = spi_write(st->spi, &st->reg, 1); 550db033831SMiquel Raynal if (ret < 0) { 551db033831SMiquel Raynal dev_err(&indio_dev->dev, "Failed to reset the ADC\n"); 552db033831SMiquel Raynal return ret; 553db033831SMiquel Raynal } 554db033831SMiquel Raynal 555fc167f62SPhilippe Reynes /* Disable averaging */ 556fc167f62SPhilippe Reynes st->reg = MAX1027_AVG_REG; 557fc167f62SPhilippe Reynes ret = spi_write(st->spi, &st->reg, 1); 558fc167f62SPhilippe Reynes if (ret < 0) { 559fc167f62SPhilippe Reynes dev_err(&indio_dev->dev, "Failed to configure averaging register\n"); 560fc167f62SPhilippe Reynes return ret; 561fc167f62SPhilippe Reynes } 562fc167f62SPhilippe Reynes 563cba18232SMiquel Raynal /* Assume conversion on register write for now */ 564cba18232SMiquel Raynal ret = max1027_enable_trigger(indio_dev, false); 565cba18232SMiquel Raynal if (ret) 566cba18232SMiquel Raynal return ret; 567cba18232SMiquel Raynal 5682715a281SChuhong Yuan return devm_iio_device_register(&spi->dev, indio_dev); 569fc167f62SPhilippe Reynes } 570fc167f62SPhilippe Reynes 571fc167f62SPhilippe Reynes static struct spi_driver max1027_driver = { 572fc167f62SPhilippe Reynes .driver = { 573fc167f62SPhilippe Reynes .name = "max1027", 57453469fa5SJonathan Cameron .of_match_table = max1027_adc_dt_ids, 575fc167f62SPhilippe Reynes }, 576fc167f62SPhilippe Reynes .probe = max1027_probe, 577fc167f62SPhilippe Reynes .id_table = max1027_id, 578fc167f62SPhilippe Reynes }; 579fc167f62SPhilippe Reynes module_spi_driver(max1027_driver); 580fc167f62SPhilippe Reynes 581fc167f62SPhilippe Reynes MODULE_AUTHOR("Philippe Reynes <tremyfr@yahoo.fr>"); 582ae47d009SMiquel Raynal MODULE_DESCRIPTION("MAX1X27/MAX1X29/MAX1X31 ADC"); 583fc167f62SPhilippe Reynes MODULE_LICENSE("GPL v2"); 584