Version:  2.0.40 2.2.26 2.4.37 3.0 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14 3.15 3.16

Linux/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                 .owner  = THIS_MODULE,
149         },
150         .probe          = vprbrd_adc_probe,
151 };
152 
153 module_platform_driver(vprbrd_adc_driver);
154 
155 MODULE_AUTHOR("Lars Poeschel <poeschel@lemonage.de>");
156 MODULE_DESCRIPTION("IIO ADC driver for Nano River Techs Viperboard");
157 MODULE_LICENSE("GPL");
158 MODULE_ALIAS("platform:viperboard-adc");
159 

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us