Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / drivers / iio / adc / viperboard_adc.c
1 /*
2  *  Nano River Technologies viperboard IIO ADC driver
3  *
4  *  (C) 2012 by Lemonage GmbH
5  *  Author: Lars Poeschel <poeschel@lemonage.de>
6  *  All rights reserved.
7  *
8  *  This program is free software; you can redistribute  it and/or modify it
9  *  under  the terms of  the GNU General  Public License as published by the
10  *  Free Software Foundation;  either version 2 of the  License, or (at your
11  *  option) any later version.
12  *
13  */
14
15 #include <linux/kernel.h>
16 #include <linux/errno.h>
17 #include <linux/module.h>
18 #include <linux/slab.h>
19 #include <linux/types.h>
20 #include <linux/mutex.h>
21 #include <linux/platform_device.h>
22
23 #include <linux/usb.h>
24 #include <linux/iio/iio.h>
25
26 #include <linux/mfd/viperboard.h>
27
28 #define VPRBRD_ADC_CMD_GET              0x00
29
30 struct vprbrd_adc_msg {
31         u8 cmd;
32         u8 chan;
33         u8 val;
34 } __packed;
35
36 struct vprbrd_adc {
37         struct vprbrd *vb;
38 };
39
40 #define VPRBRD_ADC_CHANNEL(_index) {                    \
41         .type = IIO_VOLTAGE,                            \
42         .indexed = 1,                                   \
43         .channel = _index,                              \
44         .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),   \
45 }
46
47 static struct iio_chan_spec const vprbrd_adc_iio_channels[] = {
48         VPRBRD_ADC_CHANNEL(0),
49         VPRBRD_ADC_CHANNEL(1),
50         VPRBRD_ADC_CHANNEL(2),
51         VPRBRD_ADC_CHANNEL(3),
52 };
53
54 static int vprbrd_iio_read_raw(struct iio_dev *iio_dev,
55                                 struct iio_chan_spec const *chan,
56                                 int *val,
57                                 int *val2,
58                                 long info)
59 {
60         int ret, error = 0;
61         struct vprbrd_adc *adc = iio_priv(iio_dev);
62         struct vprbrd *vb = adc->vb;
63         struct vprbrd_adc_msg *admsg = (struct vprbrd_adc_msg *)vb->buf;
64
65         switch (info) {
66         case IIO_CHAN_INFO_RAW:
67                 mutex_lock(&vb->lock);
68
69                 admsg->cmd = VPRBRD_ADC_CMD_GET;
70                 admsg->chan = chan->channel;
71                 admsg->val = 0x00;
72
73                 ret = usb_control_msg(vb->usb_dev,
74                         usb_sndctrlpipe(vb->usb_dev, 0), VPRBRD_USB_REQUEST_ADC,
75                         VPRBRD_USB_TYPE_OUT, 0x0000, 0x0000, admsg,
76                         sizeof(struct vprbrd_adc_msg), VPRBRD_USB_TIMEOUT_MS);
77                 if (ret != sizeof(struct vprbrd_adc_msg)) {
78                         dev_err(&iio_dev->dev, "usb send error on adc read\n");
79                         error = -EREMOTEIO;
80                 }
81
82                 ret = usb_control_msg(vb->usb_dev,
83                         usb_rcvctrlpipe(vb->usb_dev, 0), VPRBRD_USB_REQUEST_ADC,
84                         VPRBRD_USB_TYPE_IN, 0x0000, 0x0000, admsg,
85                         sizeof(struct vprbrd_adc_msg), VPRBRD_USB_TIMEOUT_MS);
86
87                 *val = admsg->val;
88
89                 mutex_unlock(&vb->lock);
90
91                 if (ret != sizeof(struct vprbrd_adc_msg)) {
92                         dev_err(&iio_dev->dev, "usb recv error on adc read\n");
93                         error = -EREMOTEIO;
94                 }
95
96                 if (error)
97                         goto error;
98
99                 return IIO_VAL_INT;
100         default:
101                 error = -EINVAL;
102                 break;
103         }
104 error:
105         return error;
106 }
107
108 static const struct iio_info vprbrd_adc_iio_info = {
109         .read_raw = &vprbrd_iio_read_raw,
110         .driver_module = THIS_MODULE,
111 };
112
113 static int vprbrd_adc_probe(struct platform_device *pdev)
114 {
115         struct vprbrd *vb = dev_get_drvdata(pdev->dev.parent);
116         struct vprbrd_adc *adc;
117         struct iio_dev *indio_dev;
118         int ret;
119
120         /* registering iio */
121         indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*adc));
122         if (!indio_dev) {
123                 dev_err(&pdev->dev, "failed allocating iio device\n");
124                 return -ENOMEM;
125         }
126
127         adc = iio_priv(indio_dev);
128         adc->vb = vb;
129         indio_dev->name = "viperboard adc";
130         indio_dev->dev.parent = &pdev->dev;
131         indio_dev->info = &vprbrd_adc_iio_info;
132         indio_dev->modes = INDIO_DIRECT_MODE;
133         indio_dev->channels = vprbrd_adc_iio_channels;
134         indio_dev->num_channels = ARRAY_SIZE(vprbrd_adc_iio_channels);
135
136         ret = devm_iio_device_register(&pdev->dev, indio_dev);
137         if (ret) {
138                 dev_err(&pdev->dev, "could not register iio (adc)");
139                 return ret;
140         }
141
142         return 0;
143 }
144
145 static struct platform_driver vprbrd_adc_driver = {
146         .driver = {
147                 .name   = "viperboard-adc",
148         },
149         .probe          = vprbrd_adc_probe,
150 };
151
152 module_platform_driver(vprbrd_adc_driver);
153
154 MODULE_AUTHOR("Lars Poeschel <poeschel@lemonage.de>");
155 MODULE_DESCRIPTION("IIO ADC driver for Nano River Techs Viperboard");
156 MODULE_LICENSE("GPL");
157 MODULE_ALIAS("platform:viperboard-adc");