linux/drivers/iio/adc/ltc2497.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * ltc2497.c - Driver for Analog Devices/Linear Technology LTC2497 ADC
   4 *
   5 * Copyright (C) 2017 Analog Devices Inc.
   6 *
   7 * Datasheet: http://cds.linear.com/docs/en/datasheet/2497fd.pdf
   8 */
   9
  10#include <linux/i2c.h>
  11#include <linux/iio/iio.h>
  12#include <linux/iio/driver.h>
  13#include <linux/module.h>
  14#include <linux/mod_devicetable.h>
  15
  16#include "ltc2497.h"
  17
  18struct ltc2497_driverdata {
  19        /* this must be the first member */
  20        struct ltc2497core_driverdata common_ddata;
  21        struct i2c_client *client;
  22        /*
  23         * DMA (thus cache coherency maintenance) requires the
  24         * transfer buffers to live in their own cache lines.
  25         */
  26        __be32 buf ____cacheline_aligned;
  27};
  28
  29static int ltc2497_result_and_measure(struct ltc2497core_driverdata *ddata,
  30                                      u8 address, int *val)
  31{
  32        struct ltc2497_driverdata *st =
  33                container_of(ddata, struct ltc2497_driverdata, common_ddata);
  34        int ret;
  35
  36        if (val) {
  37                ret = i2c_master_recv(st->client, (char *)&st->buf, 3);
  38                if (ret < 0) {
  39                        dev_err(&st->client->dev, "i2c_master_recv failed\n");
  40                        return ret;
  41                }
  42
  43                *val = (be32_to_cpu(st->buf) >> 14) - (1 << 17);
  44        }
  45
  46        ret = i2c_smbus_write_byte(st->client,
  47                                   LTC2497_ENABLE | address);
  48        if (ret)
  49                dev_err(&st->client->dev, "i2c transfer failed: %pe\n",
  50                        ERR_PTR(ret));
  51        return ret;
  52}
  53
  54static int ltc2497_probe(struct i2c_client *client,
  55                         const struct i2c_device_id *id)
  56{
  57        struct iio_dev *indio_dev;
  58        struct ltc2497_driverdata *st;
  59        struct device *dev = &client->dev;
  60
  61        if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C |
  62                                     I2C_FUNC_SMBUS_WRITE_BYTE))
  63                return -EOPNOTSUPP;
  64
  65        indio_dev = devm_iio_device_alloc(dev, sizeof(*st));
  66        if (!indio_dev)
  67                return -ENOMEM;
  68
  69        st = iio_priv(indio_dev);
  70        i2c_set_clientdata(client, indio_dev);
  71        st->client = client;
  72        st->common_ddata.result_and_measure = ltc2497_result_and_measure;
  73
  74        return ltc2497core_probe(dev, indio_dev);
  75}
  76
  77static int ltc2497_remove(struct i2c_client *client)
  78{
  79        struct iio_dev *indio_dev = i2c_get_clientdata(client);
  80
  81        ltc2497core_remove(indio_dev);
  82
  83        return 0;
  84}
  85
  86static const struct i2c_device_id ltc2497_id[] = {
  87        { "ltc2497", 0 },
  88        { }
  89};
  90MODULE_DEVICE_TABLE(i2c, ltc2497_id);
  91
  92static const struct of_device_id ltc2497_of_match[] = {
  93        { .compatible = "lltc,ltc2497", },
  94        {},
  95};
  96MODULE_DEVICE_TABLE(of, ltc2497_of_match);
  97
  98static struct i2c_driver ltc2497_driver = {
  99        .driver = {
 100                .name = "ltc2497",
 101                .of_match_table = ltc2497_of_match,
 102        },
 103        .probe = ltc2497_probe,
 104        .remove = ltc2497_remove,
 105        .id_table = ltc2497_id,
 106};
 107module_i2c_driver(ltc2497_driver);
 108
 109MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>");
 110MODULE_DESCRIPTION("Linear Technology LTC2497 ADC driver");
 111MODULE_LICENSE("GPL v2");
 112