1 // SPDX-License-Identifier: GPL-2.0-only
3 * MEN 16z188 Analog to Digial Converter
5 * Copyright (C) 2014 MEN Mikroelektronik GmbH (www.men.de)
6 * Author: Johannes Thumshirn <johannes.thumshirn@men.de>
9 #include <linux/kernel.h>
10 #include <linux/module.h>
11 #include <linux/mcb.h>
13 #include <linux/iio/iio.h>
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
21 #define ADC_DATA(x) (((x) >> 2) & 0x7ffffc)
22 #define ADC_OVR(x) ((x) & 0x1)
29 #define Z188_ADC_CHANNEL(idx) { \
30 .type = IIO_VOLTAGE, \
33 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
36 static const struct iio_chan_spec z188_adc_iio_channels
[] = {
47 static int z188_iio_read_raw(struct iio_dev
*iio_dev
,
48 struct iio_chan_spec
const *chan
,
53 struct z188_adc
*adc
= iio_priv(iio_dev
);
58 case IIO_CHAN_INFO_RAW
:
59 tmp
= readw(adc
->base
+ chan
->channel
* 4);
62 dev_info(&iio_dev
->dev
,
63 "Oversampling error on ADC channel %d\n",
78 static const struct iio_info z188_adc_info
= {
79 .read_raw
= &z188_iio_read_raw
,
82 static void men_z188_config_channels(void __iomem
*addr
)
88 ctl
= readl(addr
+ Z188_CTRL_REG
);
90 writel(ctl
, addr
+ Z188_CTRL_REG
);
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
);
100 static int men_z188_probe(struct mcb_device
*dev
,
101 const struct mcb_device_id
*id
)
103 struct z188_adc
*adc
;
104 struct iio_dev
*indio_dev
;
105 struct resource
*mem
;
107 indio_dev
= devm_iio_device_alloc(&dev
->dev
, sizeof(struct z188_adc
));
111 adc
= iio_priv(indio_dev
);
112 indio_dev
->name
= "z188-adc";
113 indio_dev
->info
= &z188_adc_info
;
114 indio_dev
->modes
= INDIO_DIRECT_MODE
;
115 indio_dev
->channels
= z188_adc_iio_channels
;
116 indio_dev
->num_channels
= ARRAY_SIZE(z188_adc_iio_channels
);
118 mem
= mcb_request_mem(dev
, "z188-adc");
122 adc
->base
= ioremap(mem
->start
, resource_size(mem
));
123 if (adc
->base
== NULL
)
126 men_z188_config_channels(adc
->base
);
129 mcb_set_drvdata(dev
, indio_dev
);
131 return iio_device_register(indio_dev
);
134 mcb_release_mem(mem
);
138 static void men_z188_remove(struct mcb_device
*dev
)
140 struct iio_dev
*indio_dev
= mcb_get_drvdata(dev
);
141 struct z188_adc
*adc
= iio_priv(indio_dev
);
143 iio_device_unregister(indio_dev
);
145 mcb_release_mem(adc
->mem
);
148 static const struct mcb_device_id men_z188_ids
[] = {
152 MODULE_DEVICE_TABLE(mcb
, men_z188_ids
);
154 static struct mcb_driver men_z188_driver
= {
157 .owner
= THIS_MODULE
,
159 .probe
= men_z188_probe
,
160 .remove
= men_z188_remove
,
161 .id_table
= men_z188_ids
,
163 module_mcb_driver(men_z188_driver
);
165 MODULE_AUTHOR("Johannes Thumshirn <johannes.thumshirn@men.de>");
166 MODULE_LICENSE("GPL");
167 MODULE_DESCRIPTION("IIO ADC driver for MEN 16z188 ADC Core");
168 MODULE_ALIAS("mcb:16z188");
169 MODULE_IMPORT_NS(MCB
);