root/drivers/iio/adc/men_z188_adc.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. z188_iio_read_raw
  2. men_z188_config_channels
  3. men_z188_probe
  4. men_z188_remove

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * MEN 16z188 Analog to Digial Converter
   4  *
   5  * Copyright (C) 2014 MEN Mikroelektronik GmbH (www.men.de)
   6  * Author: Johannes Thumshirn <johannes.thumshirn@men.de>
   7  */
   8 
   9 #include <linux/kernel.h>
  10 #include <linux/module.h>
  11 #include <linux/mcb.h>
  12 #include <linux/io.h>
  13 #include <linux/iio/iio.h>
  14 
  15 #define Z188_ADC_MAX_CHAN       8
  16 #define Z188_ADC_GAIN           0x0700000
  17 #define Z188_MODE_VOLTAGE       BIT(27)
  18 #define Z188_CFG_AUTO           0x1
  19 #define Z188_CTRL_REG           0x40
  20 
  21 #define ADC_DATA(x) (((x) >> 2) & 0x7ffffc)
  22 #define ADC_OVR(x) ((x) & 0x1)
  23 
  24 struct z188_adc {
  25         struct resource *mem;
  26         void __iomem *base;
  27 };
  28 
  29 #define Z188_ADC_CHANNEL(idx) {                                 \
  30                 .type = IIO_VOLTAGE,                            \
  31                 .indexed = 1,                                   \
  32                 .channel = (idx),                               \
  33                 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),   \
  34 }
  35 
  36 static const struct iio_chan_spec z188_adc_iio_channels[] = {
  37         Z188_ADC_CHANNEL(0),
  38         Z188_ADC_CHANNEL(1),
  39         Z188_ADC_CHANNEL(2),
  40         Z188_ADC_CHANNEL(3),
  41         Z188_ADC_CHANNEL(4),
  42         Z188_ADC_CHANNEL(5),
  43         Z188_ADC_CHANNEL(6),
  44         Z188_ADC_CHANNEL(7),
  45 };
  46 
  47 static int z188_iio_read_raw(struct iio_dev *iio_dev,
  48                         struct iio_chan_spec const *chan,
  49                         int *val,
  50                         int *val2,
  51                         long info)
  52 {
  53         struct z188_adc *adc = iio_priv(iio_dev);
  54         int ret;
  55         u16 tmp;
  56 
  57         switch (info) {
  58         case IIO_CHAN_INFO_RAW:
  59                 tmp = readw(adc->base + chan->channel * 4);
  60 
  61                 if (ADC_OVR(tmp)) {
  62                         dev_info(&iio_dev->dev,
  63                                 "Oversampling error on ADC channel %d\n",
  64                                 chan->channel);
  65                         return -EIO;
  66                 }
  67                 *val = ADC_DATA(tmp);
  68                 ret = IIO_VAL_INT;
  69                 break;
  70         default:
  71                 ret = -EINVAL;
  72                 break;
  73         }
  74 
  75         return ret;
  76 }
  77 
  78 static const struct iio_info z188_adc_info = {
  79         .read_raw = &z188_iio_read_raw,
  80 };
  81 
  82 static void men_z188_config_channels(void __iomem *addr)
  83 {
  84         int i;
  85         u32 cfg;
  86         u32 ctl;
  87 
  88         ctl = readl(addr + Z188_CTRL_REG);
  89         ctl |= Z188_CFG_AUTO;
  90         writel(ctl, addr + Z188_CTRL_REG);
  91 
  92         for (i = 0; i < Z188_ADC_MAX_CHAN; i++) {
  93                 cfg = readl(addr + i);
  94                 cfg &= ~Z188_ADC_GAIN;
  95                 cfg |= Z188_MODE_VOLTAGE;
  96                 writel(cfg, addr + i);
  97         }
  98 }
  99 
 100 static int men_z188_probe(struct mcb_device *dev,
 101                         const struct mcb_device_id *id)
 102 {
 103         struct z188_adc *adc;
 104         struct iio_dev *indio_dev;
 105         struct resource *mem;
 106 
 107         indio_dev = devm_iio_device_alloc(&dev->dev, sizeof(struct z188_adc));
 108         if (!indio_dev)
 109                 return -ENOMEM;
 110 
 111         adc = iio_priv(indio_dev);
 112         indio_dev->name = "z188-adc";
 113         indio_dev->dev.parent = &dev->dev;
 114         indio_dev->info = &z188_adc_info;
 115         indio_dev->modes = INDIO_DIRECT_MODE;
 116         indio_dev->channels = z188_adc_iio_channels;
 117         indio_dev->num_channels = ARRAY_SIZE(z188_adc_iio_channels);
 118 
 119         mem = mcb_request_mem(dev, "z188-adc");
 120         if (IS_ERR(mem))
 121                 return PTR_ERR(mem);
 122 
 123         adc->base = ioremap(mem->start, resource_size(mem));
 124         if (adc->base == NULL)
 125                 goto err;
 126 
 127         men_z188_config_channels(adc->base);
 128 
 129         adc->mem = mem;
 130         mcb_set_drvdata(dev, indio_dev);
 131 
 132         return iio_device_register(indio_dev);
 133 
 134 err:
 135         mcb_release_mem(mem);
 136         return -ENXIO;
 137 }
 138 
 139 static void men_z188_remove(struct mcb_device *dev)
 140 {
 141         struct iio_dev *indio_dev  = mcb_get_drvdata(dev);
 142         struct z188_adc *adc = iio_priv(indio_dev);
 143 
 144         iio_device_unregister(indio_dev);
 145         iounmap(adc->base);
 146         mcb_release_mem(adc->mem);
 147 }
 148 
 149 static const struct mcb_device_id men_z188_ids[] = {
 150         { .device = 0xbc },
 151         { }
 152 };
 153 MODULE_DEVICE_TABLE(mcb, men_z188_ids);
 154 
 155 static struct mcb_driver men_z188_driver = {
 156         .driver = {
 157                 .name = "z188-adc",
 158                 .owner = THIS_MODULE,
 159         },
 160         .probe = men_z188_probe,
 161         .remove = men_z188_remove,
 162         .id_table = men_z188_ids,
 163 };
 164 module_mcb_driver(men_z188_driver);
 165 
 166 MODULE_AUTHOR("Johannes Thumshirn <johannes.thumshirn@men.de>");
 167 MODULE_LICENSE("GPL");
 168 MODULE_DESCRIPTION("IIO ADC driver for MEN 16z188 ADC Core");
 169 MODULE_ALIAS("mcb:16z188");

/* [<][>][^][v][top][bottom][index][help] */