| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * iio/adc/max1027.c |
|---|
| 3 | 4 | * Copyright (C) 2014 Philippe Reynes |
|---|
| .. | .. |
|---|
| 6 | 7 | * Copyright 2011 Analog Devices Inc (from AD7923 Driver) |
|---|
| 7 | 8 | * Copyright 2012 CS Systemes d'Information |
|---|
| 8 | 9 | * |
|---|
| 9 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 10 | | - * it under the terms of the GNU General Public License version 2 as |
|---|
| 11 | | - * published by the Free Software Foundation. |
|---|
| 12 | | - * |
|---|
| 13 | 10 | * max1027.c |
|---|
| 14 | 11 | * |
|---|
| 15 | 12 | * Partial support for max1027 and similar chips. |
|---|
| .. | .. |
|---|
| 17 | 14 | |
|---|
| 18 | 15 | #include <linux/kernel.h> |
|---|
| 19 | 16 | #include <linux/module.h> |
|---|
| 17 | +#include <linux/mod_devicetable.h> |
|---|
| 20 | 18 | #include <linux/spi/spi.h> |
|---|
| 21 | 19 | #include <linux/delay.h> |
|---|
| 22 | 20 | |
|---|
| .. | .. |
|---|
| 66 | 64 | max1027, |
|---|
| 67 | 65 | max1029, |
|---|
| 68 | 66 | max1031, |
|---|
| 67 | + max1227, |
|---|
| 68 | + max1229, |
|---|
| 69 | + max1231, |
|---|
| 69 | 70 | }; |
|---|
| 70 | 71 | |
|---|
| 71 | 72 | static const struct spi_device_id max1027_id[] = { |
|---|
| 72 | 73 | {"max1027", max1027}, |
|---|
| 73 | 74 | {"max1029", max1029}, |
|---|
| 74 | 75 | {"max1031", max1031}, |
|---|
| 76 | + {"max1227", max1227}, |
|---|
| 77 | + {"max1229", max1229}, |
|---|
| 78 | + {"max1231", max1231}, |
|---|
| 75 | 79 | {} |
|---|
| 76 | 80 | }; |
|---|
| 77 | 81 | MODULE_DEVICE_TABLE(spi, max1027_id); |
|---|
| 78 | 82 | |
|---|
| 79 | | -#ifdef CONFIG_OF |
|---|
| 80 | 83 | static const struct of_device_id max1027_adc_dt_ids[] = { |
|---|
| 81 | 84 | { .compatible = "maxim,max1027" }, |
|---|
| 82 | 85 | { .compatible = "maxim,max1029" }, |
|---|
| 83 | 86 | { .compatible = "maxim,max1031" }, |
|---|
| 87 | + { .compatible = "maxim,max1227" }, |
|---|
| 88 | + { .compatible = "maxim,max1229" }, |
|---|
| 89 | + { .compatible = "maxim,max1231" }, |
|---|
| 84 | 90 | {}, |
|---|
| 85 | 91 | }; |
|---|
| 86 | 92 | MODULE_DEVICE_TABLE(of, max1027_adc_dt_ids); |
|---|
| 87 | | -#endif |
|---|
| 88 | 93 | |
|---|
| 89 | | -#define MAX1027_V_CHAN(index) \ |
|---|
| 94 | +#define MAX1027_V_CHAN(index, depth) \ |
|---|
| 90 | 95 | { \ |
|---|
| 91 | 96 | .type = IIO_VOLTAGE, \ |
|---|
| 92 | 97 | .indexed = 1, \ |
|---|
| .. | .. |
|---|
| 96 | 101 | .scan_index = index + 1, \ |
|---|
| 97 | 102 | .scan_type = { \ |
|---|
| 98 | 103 | .sign = 'u', \ |
|---|
| 99 | | - .realbits = 10, \ |
|---|
| 104 | + .realbits = depth, \ |
|---|
| 100 | 105 | .storagebits = 16, \ |
|---|
| 101 | | - .shift = 2, \ |
|---|
| 106 | + .shift = (depth == 10) ? 2 : 0, \ |
|---|
| 102 | 107 | .endianness = IIO_BE, \ |
|---|
| 103 | 108 | }, \ |
|---|
| 104 | 109 | } |
|---|
| .. | .. |
|---|
| 118 | 123 | }, \ |
|---|
| 119 | 124 | } |
|---|
| 120 | 125 | |
|---|
| 126 | +#define MAX1X27_CHANNELS(depth) \ |
|---|
| 127 | + MAX1027_T_CHAN, \ |
|---|
| 128 | + MAX1027_V_CHAN(0, depth), \ |
|---|
| 129 | + MAX1027_V_CHAN(1, depth), \ |
|---|
| 130 | + MAX1027_V_CHAN(2, depth), \ |
|---|
| 131 | + MAX1027_V_CHAN(3, depth), \ |
|---|
| 132 | + MAX1027_V_CHAN(4, depth), \ |
|---|
| 133 | + MAX1027_V_CHAN(5, depth), \ |
|---|
| 134 | + MAX1027_V_CHAN(6, depth), \ |
|---|
| 135 | + MAX1027_V_CHAN(7, depth) |
|---|
| 136 | + |
|---|
| 137 | +#define MAX1X29_CHANNELS(depth) \ |
|---|
| 138 | + MAX1X27_CHANNELS(depth), \ |
|---|
| 139 | + MAX1027_V_CHAN(8, depth), \ |
|---|
| 140 | + MAX1027_V_CHAN(9, depth), \ |
|---|
| 141 | + MAX1027_V_CHAN(10, depth), \ |
|---|
| 142 | + MAX1027_V_CHAN(11, depth) |
|---|
| 143 | + |
|---|
| 144 | +#define MAX1X31_CHANNELS(depth) \ |
|---|
| 145 | + MAX1X29_CHANNELS(depth), \ |
|---|
| 146 | + MAX1027_V_CHAN(12, depth), \ |
|---|
| 147 | + MAX1027_V_CHAN(13, depth), \ |
|---|
| 148 | + MAX1027_V_CHAN(14, depth), \ |
|---|
| 149 | + MAX1027_V_CHAN(15, depth) |
|---|
| 150 | + |
|---|
| 121 | 151 | static const struct iio_chan_spec max1027_channels[] = { |
|---|
| 122 | | - MAX1027_T_CHAN, |
|---|
| 123 | | - MAX1027_V_CHAN(0), |
|---|
| 124 | | - MAX1027_V_CHAN(1), |
|---|
| 125 | | - MAX1027_V_CHAN(2), |
|---|
| 126 | | - MAX1027_V_CHAN(3), |
|---|
| 127 | | - MAX1027_V_CHAN(4), |
|---|
| 128 | | - MAX1027_V_CHAN(5), |
|---|
| 129 | | - MAX1027_V_CHAN(6), |
|---|
| 130 | | - MAX1027_V_CHAN(7) |
|---|
| 152 | + MAX1X27_CHANNELS(10), |
|---|
| 131 | 153 | }; |
|---|
| 132 | 154 | |
|---|
| 133 | 155 | static const struct iio_chan_spec max1029_channels[] = { |
|---|
| 134 | | - MAX1027_T_CHAN, |
|---|
| 135 | | - MAX1027_V_CHAN(0), |
|---|
| 136 | | - MAX1027_V_CHAN(1), |
|---|
| 137 | | - MAX1027_V_CHAN(2), |
|---|
| 138 | | - MAX1027_V_CHAN(3), |
|---|
| 139 | | - MAX1027_V_CHAN(4), |
|---|
| 140 | | - MAX1027_V_CHAN(5), |
|---|
| 141 | | - MAX1027_V_CHAN(6), |
|---|
| 142 | | - MAX1027_V_CHAN(7), |
|---|
| 143 | | - MAX1027_V_CHAN(8), |
|---|
| 144 | | - MAX1027_V_CHAN(9), |
|---|
| 145 | | - MAX1027_V_CHAN(10), |
|---|
| 146 | | - MAX1027_V_CHAN(11) |
|---|
| 156 | + MAX1X29_CHANNELS(10), |
|---|
| 147 | 157 | }; |
|---|
| 148 | 158 | |
|---|
| 149 | 159 | static const struct iio_chan_spec max1031_channels[] = { |
|---|
| 150 | | - MAX1027_T_CHAN, |
|---|
| 151 | | - MAX1027_V_CHAN(0), |
|---|
| 152 | | - MAX1027_V_CHAN(1), |
|---|
| 153 | | - MAX1027_V_CHAN(2), |
|---|
| 154 | | - MAX1027_V_CHAN(3), |
|---|
| 155 | | - MAX1027_V_CHAN(4), |
|---|
| 156 | | - MAX1027_V_CHAN(5), |
|---|
| 157 | | - MAX1027_V_CHAN(6), |
|---|
| 158 | | - MAX1027_V_CHAN(7), |
|---|
| 159 | | - MAX1027_V_CHAN(8), |
|---|
| 160 | | - MAX1027_V_CHAN(9), |
|---|
| 161 | | - MAX1027_V_CHAN(10), |
|---|
| 162 | | - MAX1027_V_CHAN(11), |
|---|
| 163 | | - MAX1027_V_CHAN(12), |
|---|
| 164 | | - MAX1027_V_CHAN(13), |
|---|
| 165 | | - MAX1027_V_CHAN(14), |
|---|
| 166 | | - MAX1027_V_CHAN(15) |
|---|
| 160 | + MAX1X31_CHANNELS(10), |
|---|
| 161 | +}; |
|---|
| 162 | + |
|---|
| 163 | +static const struct iio_chan_spec max1227_channels[] = { |
|---|
| 164 | + MAX1X27_CHANNELS(12), |
|---|
| 165 | +}; |
|---|
| 166 | + |
|---|
| 167 | +static const struct iio_chan_spec max1229_channels[] = { |
|---|
| 168 | + MAX1X29_CHANNELS(12), |
|---|
| 169 | +}; |
|---|
| 170 | + |
|---|
| 171 | +static const struct iio_chan_spec max1231_channels[] = { |
|---|
| 172 | + MAX1X31_CHANNELS(12), |
|---|
| 167 | 173 | }; |
|---|
| 168 | 174 | |
|---|
| 169 | 175 | static const unsigned long max1027_available_scan_masks[] = { |
|---|
| .. | .. |
|---|
| 201 | 207 | [max1031] = { |
|---|
| 202 | 208 | .channels = max1031_channels, |
|---|
| 203 | 209 | .num_channels = ARRAY_SIZE(max1031_channels), |
|---|
| 210 | + .available_scan_masks = max1031_available_scan_masks, |
|---|
| 211 | + }, |
|---|
| 212 | + [max1227] = { |
|---|
| 213 | + .channels = max1227_channels, |
|---|
| 214 | + .num_channels = ARRAY_SIZE(max1227_channels), |
|---|
| 215 | + .available_scan_masks = max1027_available_scan_masks, |
|---|
| 216 | + }, |
|---|
| 217 | + [max1229] = { |
|---|
| 218 | + .channels = max1229_channels, |
|---|
| 219 | + .num_channels = ARRAY_SIZE(max1229_channels), |
|---|
| 220 | + .available_scan_masks = max1029_available_scan_masks, |
|---|
| 221 | + }, |
|---|
| 222 | + [max1231] = { |
|---|
| 223 | + .channels = max1231_channels, |
|---|
| 224 | + .num_channels = ARRAY_SIZE(max1231_channels), |
|---|
| 204 | 225 | .available_scan_masks = max1031_available_scan_masks, |
|---|
| 205 | 226 | }, |
|---|
| 206 | 227 | }; |
|---|
| .. | .. |
|---|
| 287 | 308 | break; |
|---|
| 288 | 309 | case IIO_VOLTAGE: |
|---|
| 289 | 310 | *val = 2500; |
|---|
| 290 | | - *val2 = 10; |
|---|
| 311 | + *val2 = chan->scan_type.realbits; |
|---|
| 291 | 312 | ret = IIO_VAL_FRACTIONAL_LOG2; |
|---|
| 292 | 313 | break; |
|---|
| 293 | 314 | default: |
|---|
| .. | .. |
|---|
| 312 | 333 | struct max1027_state *st = iio_priv(indio_dev); |
|---|
| 313 | 334 | u8 *val = (u8 *)st->buffer; |
|---|
| 314 | 335 | |
|---|
| 315 | | - if (readval != NULL) |
|---|
| 316 | | - return -EINVAL; |
|---|
| 336 | + if (readval) { |
|---|
| 337 | + int ret = spi_read(st->spi, val, 2); |
|---|
| 338 | + *readval = be16_to_cpu(st->buffer[0]); |
|---|
| 339 | + return ret; |
|---|
| 340 | + } |
|---|
| 317 | 341 | |
|---|
| 318 | 342 | *val = (u8)writeval; |
|---|
| 319 | 343 | return spi_write(st->spi, val, 1); |
|---|
| .. | .. |
|---|
| 414 | 438 | mutex_init(&st->lock); |
|---|
| 415 | 439 | |
|---|
| 416 | 440 | indio_dev->name = spi_get_device_id(spi)->name; |
|---|
| 417 | | - indio_dev->dev.parent = &spi->dev; |
|---|
| 418 | | - indio_dev->dev.of_node = spi->dev.of_node; |
|---|
| 419 | 441 | indio_dev->info = &max1027_info; |
|---|
| 420 | 442 | indio_dev->modes = INDIO_DIRECT_MODE; |
|---|
| 421 | 443 | indio_dev->channels = st->info->channels; |
|---|
| .. | .. |
|---|
| 430 | 452 | return -ENOMEM; |
|---|
| 431 | 453 | } |
|---|
| 432 | 454 | |
|---|
| 433 | | - ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time, |
|---|
| 434 | | - &max1027_trigger_handler, NULL); |
|---|
| 435 | | - if (ret < 0) { |
|---|
| 436 | | - dev_err(&indio_dev->dev, "Failed to setup buffer\n"); |
|---|
| 437 | | - return ret; |
|---|
| 438 | | - } |
|---|
| 455 | + if (spi->irq) { |
|---|
| 456 | + ret = devm_iio_triggered_buffer_setup(&spi->dev, indio_dev, |
|---|
| 457 | + &iio_pollfunc_store_time, |
|---|
| 458 | + &max1027_trigger_handler, |
|---|
| 459 | + NULL); |
|---|
| 460 | + if (ret < 0) { |
|---|
| 461 | + dev_err(&indio_dev->dev, "Failed to setup buffer\n"); |
|---|
| 462 | + return ret; |
|---|
| 463 | + } |
|---|
| 439 | 464 | |
|---|
| 440 | | - st->trig = devm_iio_trigger_alloc(&spi->dev, "%s-trigger", |
|---|
| 441 | | - indio_dev->name); |
|---|
| 442 | | - if (st->trig == NULL) { |
|---|
| 443 | | - ret = -ENOMEM; |
|---|
| 444 | | - dev_err(&indio_dev->dev, "Failed to allocate iio trigger\n"); |
|---|
| 445 | | - goto fail_trigger_alloc; |
|---|
| 446 | | - } |
|---|
| 465 | + st->trig = devm_iio_trigger_alloc(&spi->dev, "%s-trigger", |
|---|
| 466 | + indio_dev->name); |
|---|
| 467 | + if (st->trig == NULL) { |
|---|
| 468 | + ret = -ENOMEM; |
|---|
| 469 | + dev_err(&indio_dev->dev, |
|---|
| 470 | + "Failed to allocate iio trigger\n"); |
|---|
| 471 | + return ret; |
|---|
| 472 | + } |
|---|
| 447 | 473 | |
|---|
| 448 | | - st->trig->ops = &max1027_trigger_ops; |
|---|
| 449 | | - st->trig->dev.parent = &spi->dev; |
|---|
| 450 | | - iio_trigger_set_drvdata(st->trig, indio_dev); |
|---|
| 451 | | - iio_trigger_register(st->trig); |
|---|
| 474 | + st->trig->ops = &max1027_trigger_ops; |
|---|
| 475 | + st->trig->dev.parent = &spi->dev; |
|---|
| 476 | + iio_trigger_set_drvdata(st->trig, indio_dev); |
|---|
| 477 | + ret = devm_iio_trigger_register(&indio_dev->dev, |
|---|
| 478 | + st->trig); |
|---|
| 479 | + if (ret < 0) { |
|---|
| 480 | + dev_err(&indio_dev->dev, |
|---|
| 481 | + "Failed to register iio trigger\n"); |
|---|
| 482 | + return ret; |
|---|
| 483 | + } |
|---|
| 452 | 484 | |
|---|
| 453 | | - ret = devm_request_threaded_irq(&spi->dev, spi->irq, |
|---|
| 454 | | - iio_trigger_generic_data_rdy_poll, |
|---|
| 455 | | - NULL, |
|---|
| 456 | | - IRQF_TRIGGER_FALLING, |
|---|
| 457 | | - spi->dev.driver->name, st->trig); |
|---|
| 458 | | - if (ret < 0) { |
|---|
| 459 | | - dev_err(&indio_dev->dev, "Failed to allocate IRQ.\n"); |
|---|
| 460 | | - goto fail_dev_register; |
|---|
| 485 | + ret = devm_request_threaded_irq(&spi->dev, spi->irq, |
|---|
| 486 | + iio_trigger_generic_data_rdy_poll, |
|---|
| 487 | + NULL, |
|---|
| 488 | + IRQF_TRIGGER_FALLING, |
|---|
| 489 | + spi->dev.driver->name, |
|---|
| 490 | + st->trig); |
|---|
| 491 | + if (ret < 0) { |
|---|
| 492 | + dev_err(&indio_dev->dev, "Failed to allocate IRQ.\n"); |
|---|
| 493 | + return ret; |
|---|
| 494 | + } |
|---|
| 461 | 495 | } |
|---|
| 462 | 496 | |
|---|
| 463 | 497 | /* Internal reset */ |
|---|
| .. | .. |
|---|
| 473 | 507 | ret = spi_write(st->spi, &st->reg, 1); |
|---|
| 474 | 508 | if (ret < 0) { |
|---|
| 475 | 509 | dev_err(&indio_dev->dev, "Failed to configure averaging register\n"); |
|---|
| 476 | | - goto fail_dev_register; |
|---|
| 510 | + return ret; |
|---|
| 477 | 511 | } |
|---|
| 478 | 512 | |
|---|
| 479 | | - ret = iio_device_register(indio_dev); |
|---|
| 480 | | - if (ret < 0) { |
|---|
| 481 | | - dev_err(&indio_dev->dev, "Failed to register iio device\n"); |
|---|
| 482 | | - goto fail_dev_register; |
|---|
| 483 | | - } |
|---|
| 484 | | - |
|---|
| 485 | | - return 0; |
|---|
| 486 | | - |
|---|
| 487 | | -fail_dev_register: |
|---|
| 488 | | -fail_trigger_alloc: |
|---|
| 489 | | - iio_triggered_buffer_cleanup(indio_dev); |
|---|
| 490 | | - |
|---|
| 491 | | - return ret; |
|---|
| 492 | | -} |
|---|
| 493 | | - |
|---|
| 494 | | -static int max1027_remove(struct spi_device *spi) |
|---|
| 495 | | -{ |
|---|
| 496 | | - struct iio_dev *indio_dev = spi_get_drvdata(spi); |
|---|
| 497 | | - |
|---|
| 498 | | - pr_debug("%s: remove(spi = 0x%p)\n", __func__, spi); |
|---|
| 499 | | - |
|---|
| 500 | | - iio_device_unregister(indio_dev); |
|---|
| 501 | | - iio_triggered_buffer_cleanup(indio_dev); |
|---|
| 502 | | - |
|---|
| 503 | | - return 0; |
|---|
| 513 | + return devm_iio_device_register(&spi->dev, indio_dev); |
|---|
| 504 | 514 | } |
|---|
| 505 | 515 | |
|---|
| 506 | 516 | static struct spi_driver max1027_driver = { |
|---|
| 507 | 517 | .driver = { |
|---|
| 508 | 518 | .name = "max1027", |
|---|
| 509 | | - .of_match_table = of_match_ptr(max1027_adc_dt_ids), |
|---|
| 519 | + .of_match_table = max1027_adc_dt_ids, |
|---|
| 510 | 520 | }, |
|---|
| 511 | 521 | .probe = max1027_probe, |
|---|
| 512 | | - .remove = max1027_remove, |
|---|
| 513 | 522 | .id_table = max1027_id, |
|---|
| 514 | 523 | }; |
|---|
| 515 | 524 | module_spi_driver(max1027_driver); |
|---|
| 516 | 525 | |
|---|
| 517 | 526 | MODULE_AUTHOR("Philippe Reynes <tremyfr@yahoo.fr>"); |
|---|
| 518 | | -MODULE_DESCRIPTION("MAX1027/MAX1029/MAX1031 ADC"); |
|---|
| 527 | +MODULE_DESCRIPTION("MAX1X27/MAX1X29/MAX1X31 ADC"); |
|---|
| 519 | 528 | MODULE_LICENSE("GPL v2"); |
|---|