123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164 |
- #include <linux/delay.h>
- #include <linux/iio/iio.h>
- #include <linux/iio/driver.h>
- #include <linux/iio/machine.h>
- #include <linux/module.h>
- #include <linux/mutex.h>
- #include <linux/platform_device.h>
- #include <linux/slab.h>
- #include <linux/usb.h>
- #define USBIO_VENDOR_ID 0x04d8
- #define USBIO_PRODUCT_ID 0x003f
- struct usbio_adc {
- struct usb_device *udev;
- int value;
- };
- static const struct iio_chan_spec const usbio_adc_channels[] = {
- {
- .indexed = 1,
- .type = IIO_VOLTAGE,
- .channel = 0,
- .datasheet_name = "DM0",
- .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
- }, {
- .indexed = 1,
- .type = IIO_VOLTAGE,
- .channel = 1,
- .datasheet_name = "DM1",
- .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
- }
- };
- static int usbio_adc_read(struct usb_device *usb_dev, int channel, int *val)
- {
- u8 data[64];
- int ret, actual_len;
- actual_len = 1;
- data[0] = 0x37+channel;
- *val = 0;
- printk(KERN_INFO "reading from %x", data[0]);
- ret = usb_interrupt_msg(usb_dev,
- usb_sndintpipe(usb_dev, 1),
- data, sizeof(data), &actual_len, USB_CTRL_SET_TIMEOUT);
- if(ret < 0)
- return -EIO;
- actual_len = 64;
- memset(data, 0, 64);
- ret = usb_bulk_msg(usb_dev,
- usb_rcvbulkpipe(usb_dev, 0x81),
- data, sizeof(data), &actual_len, USB_CTRL_SET_TIMEOUT);
- if(ret < 0)
- return -EIO;
- printk(KERN_INFO "back from %x",data[0]);
- *val = (data[2] << 8) | data[1];
- return IIO_VAL_INT;
- }
- static int usbio_adc_read_raw(struct iio_dev *usbio_adc_dev, struct iio_chan_spec const *chan, int *val, int *val2, long mask)
- {
- int ret;
- struct usbio_adc *adc = iio_priv(usbio_adc_dev);
- mutex_lock(&usbio_adc_dev->mlock);
- switch(mask) {
- case IIO_CHAN_INFO_RAW:
- ret = usbio_adc_read(adc->udev, chan->channel, val);
- break;
- default:
- ret = -EINVAL;
- }
- mutex_unlock(&usbio_adc_dev->mlock);
- return ret;
- }
- static const struct iio_info usbio_adc_iio_info = {
- .read_raw = &usbio_adc_read_raw,
- .driver_module = THIS_MODULE
- };
-
- static struct iio_map usbio_adc_default_maps[] = {
- {
- .adc_channel_label = "DM0",
- .consumer_dev_name = "usbio-adc",
- .consumer_channel = "usbio-adc0",
- },
- {
- .adc_channel_label = "DM1",
- .consumer_dev_name = "usbio-adc",
- .consumer_channel = "usbio-adc1",
- }
- };
- static int usbio_adc_probe(struct usb_interface *interface, const struct usb_device_id *id)
- {
- struct usb_device *udev = interface_to_usbdev(interface);
- struct iio_dev *usbio_adc_dev;
- struct usbio_adc *adc = NULL;
- int ret;
- usbio_adc_dev = devm_iio_device_alloc(&udev->dev, sizeof(*adc));
- if(!usbio_adc_dev)
- return -ENOMEM;
- adc = iio_priv(usbio_adc_dev);
- adc->udev = udev;
- adc->value = 0;
- usb_set_intfdata(interface, usbio_adc_dev);
- usbio_adc_dev->dev.parent = &udev->dev;
- usbio_adc_dev->name = "usbio-adc";
- usbio_adc_dev->channels = usbio_adc_channels;
- usbio_adc_dev->num_channels = ARRAY_SIZE(usbio_adc_channels);
- usbio_adc_dev->info = &usbio_adc_iio_info;
- usbio_adc_dev->modes = INDIO_DIRECT_MODE;
-
- ret = iio_map_array_register(usbio_adc_dev, usbio_adc_default_maps);
- if(ret < 0) {
- dev_err(&udev->dev, "something went wrong");
- return ret;
- }
- ret = iio_device_register(usbio_adc_dev);
- if(ret < 0) {
- dev_err(&udev->dev, "unable to register iiodevice \n");
- goto err_array_unregister;
- }
- return 0;
- err_array_unregister:
- iio_map_array_unregister(usbio_adc_dev);
- return ret;
- }
- static void usbio_adc_disconnect(struct usb_interface *interface)
- {
- struct iio_dev *usbio_adc_dev = usb_get_intfdata(interface);
- struct usbio_adc *adc = iio_priv(usbio_adc_dev);
- //usb_set_intfdata(interface, NULL);
- usb_put_dev(adc->udev);
- // kfree(adc);
- iio_device_unregister(usbio_adc_dev);
- iio_map_array_unregister(usbio_adc_dev);
- }
- static struct usb_device_id usbio_id_table[] = {
- { USB_DEVICE(USBIO_VENDOR_ID, USBIO_PRODUCT_ID) },
- {}
- };
- MODULE_DEVICE_TABLE(usb, usbio_id_table);
- static struct usb_driver usbio_adc_driver = {
- .name = "usbio_adc",
- .probe = usbio_adc_probe,
- .disconnect = usbio_adc_disconnect,
- .id_table = usbio_id_table
- };
- module_usb_driver(usbio_adc_driver);
- MODULE_DESCRIPTION("USBIO ADC");
- MODULE_AUTHOR("encrypt <encrypt@labr.xyz>");
- MODULE_LICENSE("GPL");
|