2 * MEN 16z188 Analog to Digial Converter
4 * Copyright (C) 2014 MEN Mikroelektronik GmbH (www.men.de)
5 * Author: Johannes Thumshirn <johannes.thumshirn@men.de>
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the Free
9 * Software Foundation; version 2 of the License.
12 #include <linux/kernel.h>
13 #include <linux/module.h>
14 #include <linux/mcb.h>
16 #include <linux/iio/iio.h>
18 #define Z188_ADC_MAX_CHAN 8
19 #define Z188_ADC_GAIN 0x0700000
20 #define Z188_MODE_VOLTAGE BIT(27)
21 #define Z188_CFG_AUTO 0x1
22 #define Z188_CTRL_REG 0x40
24 #define ADC_DATA(x) (((x) >> 2) & 0x7ffffc)
25 #define ADC_OVR(x) ((x) & 0x1)
32 #define Z188_ADC_CHANNEL(idx) { \
33 .type = IIO_VOLTAGE, \
36 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
39 static const struct iio_chan_spec z188_adc_iio_channels
[] = {
50 static int z188_iio_read_raw(struct iio_dev
*iio_dev
,
51 struct iio_chan_spec
const *chan
,
56 struct z188_adc
*adc
= iio_priv(iio_dev
);
61 case IIO_CHAN_INFO_RAW
:
62 tmp
= readw(adc
->base
+ chan
->channel
* 4);
65 dev_info(&iio_dev
->dev
,
66 "Oversampling error on ADC channel %d\n",
81 static const struct iio_info z188_adc_info
= {
82 .read_raw
= &z188_iio_read_raw
,
83 .driver_module
= THIS_MODULE
,
86 static void men_z188_config_channels(void __iomem
*addr
)
92 ctl
= readl(addr
+ Z188_CTRL_REG
);
94 writel(ctl
, addr
+ Z188_CTRL_REG
);
96 for (i
= 0; i
< Z188_ADC_MAX_CHAN
; i
++) {
97 cfg
= readl(addr
+ i
);
98 cfg
&= ~Z188_ADC_GAIN
;
99 cfg
|= Z188_MODE_VOLTAGE
;
100 writel(cfg
, addr
+ i
);
104 static int men_z188_probe(struct mcb_device
*dev
,
105 const struct mcb_device_id
*id
)
107 struct z188_adc
*adc
;
108 struct iio_dev
*indio_dev
;
109 struct resource
*mem
;
111 indio_dev
= devm_iio_device_alloc(&dev
->dev
, sizeof(struct z188_adc
));
115 adc
= iio_priv(indio_dev
);
116 indio_dev
->name
= "z188-adc";
117 indio_dev
->dev
.parent
= &dev
->dev
;
118 indio_dev
->info
= &z188_adc_info
;
119 indio_dev
->modes
= INDIO_DIRECT_MODE
;
120 indio_dev
->channels
= z188_adc_iio_channels
;
121 indio_dev
->num_channels
= ARRAY_SIZE(z188_adc_iio_channels
);
123 mem
= mcb_request_mem(dev
, "z188-adc");
127 adc
->base
= ioremap(mem
->start
, resource_size(mem
));
128 if (adc
->base
== NULL
)
131 men_z188_config_channels(adc
->base
);
134 mcb_set_drvdata(dev
, indio_dev
);
136 return iio_device_register(indio_dev
);
139 mcb_release_mem(mem
);
143 static void men_z188_remove(struct mcb_device
*dev
)
145 struct iio_dev
*indio_dev
= mcb_get_drvdata(dev
);
146 struct z188_adc
*adc
= iio_priv(indio_dev
);
148 iio_device_unregister(indio_dev
);
150 mcb_release_mem(adc
->mem
);
153 static const struct mcb_device_id men_z188_ids
[] = {
157 MODULE_DEVICE_TABLE(mcb
, men_z188_ids
);
159 static struct mcb_driver men_z188_driver
= {
162 .owner
= THIS_MODULE
,
164 .probe
= men_z188_probe
,
165 .remove
= men_z188_remove
,
166 .id_table
= men_z188_ids
,
168 module_mcb_driver(men_z188_driver
);
170 MODULE_AUTHOR("Johannes Thumshirn <johannes.thumshirn@men.de>");
171 MODULE_LICENSE("GPL");
172 MODULE_DESCRIPTION("IIO ADC driver for MEN 16z188 ADC Core");
173 MODULE_ALIAS("mcb:16z188");