Blame view
drivers/mfd/viperboard.c
3.35 KB
f01312d84 mfd: Add viperboa... |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
/* * Nano River Technologies viperboard driver * * This is the core driver for the viperboard. There are cell drivers * available for I2C, ADC and both GPIOs. SPI is not yet supported. * The drivers do not support all features the board exposes. See user * manual of the viperboard. * * (C) 2012 by Lemonage GmbH * Author: Lars Poeschel <poeschel@lemonage.de> * All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * */ #include <linux/kernel.h> #include <linux/errno.h> #include <linux/module.h> #include <linux/slab.h> #include <linux/types.h> #include <linux/mutex.h> #include <linux/mfd/core.h> #include <linux/mfd/viperboard.h> #include <linux/usb.h> static const struct usb_device_id vprbrd_table[] = { { USB_DEVICE(0x2058, 0x1005) }, /* Nano River Technologies */ { } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, vprbrd_table); |
5ac98553a mfd: Constify str... |
39 |
static const struct mfd_cell vprbrd_devs[] = { |
9d5b72de0 gpio: Add viperbo... |
40 41 42 |
{ .name = "viperboard-gpio", }, |
174a13aa8 i2c: Add viperboa... |
43 44 45 |
{ .name = "viperboard-i2c", }, |
ffd8a6e7a iio: adc: Add vip... |
46 47 48 |
{ .name = "viperboard-adc", }, |
f01312d84 mfd: Add viperboa... |
49 50 51 52 53 54 55 56 57 |
}; static int vprbrd_probe(struct usb_interface *interface, const struct usb_device_id *id) { struct vprbrd *vb; u16 version = 0; int pipe, ret; |
f01312d84 mfd: Add viperboa... |
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
/* allocate memory for our device state and initialize it */ vb = kzalloc(sizeof(*vb), GFP_KERNEL); if (vb == NULL) { dev_err(&interface->dev, "Out of memory "); return -ENOMEM; } mutex_init(&vb->lock); vb->usb_dev = usb_get_dev(interface_to_usbdev(interface)); /* save our data pointer in this interface device */ usb_set_intfdata(interface, vb); dev_set_drvdata(&vb->pdev.dev, vb); /* get version information, major first, minor then */ pipe = usb_rcvctrlpipe(vb->usb_dev, 0); ret = usb_control_msg(vb->usb_dev, pipe, VPRBRD_USB_REQUEST_MAJOR, |
302b95621 mfd: viperboard: ... |
78 |
VPRBRD_USB_TYPE_IN, 0x0000, 0x0000, vb->buf, 1, |
f01312d84 mfd: Add viperboa... |
79 80 |
VPRBRD_USB_TIMEOUT_MS); if (ret == 1) |
302b95621 mfd: viperboard: ... |
81 |
version = vb->buf[0]; |
f01312d84 mfd: Add viperboa... |
82 83 |
ret = usb_control_msg(vb->usb_dev, pipe, VPRBRD_USB_REQUEST_MINOR, |
302b95621 mfd: viperboard: ... |
84 |
VPRBRD_USB_TYPE_IN, 0x0000, 0x0000, vb->buf, 1, |
f01312d84 mfd: Add viperboa... |
85 86 87 |
VPRBRD_USB_TIMEOUT_MS); if (ret == 1) { version <<= 8; |
302b95621 mfd: viperboard: ... |
88 |
version = version | vb->buf[0]; |
f01312d84 mfd: Add viperboa... |
89 90 91 92 93 94 95 |
} dev_info(&interface->dev, "version %x.%02x found at bus %03d address %03d ", version >> 8, version & 0xff, vb->usb_dev->bus->busnum, vb->usb_dev->devnum); |
1ab589c72 mfd: Use mfd_add_... |
96 97 |
ret = mfd_add_hotplug_devices(&interface->dev, vprbrd_devs, ARRAY_SIZE(vprbrd_devs)); |
f01312d84 mfd: Add viperboa... |
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 |
if (ret != 0) { dev_err(&interface->dev, "Failed to add mfd devices to core."); goto error; } return 0; error: if (vb) { usb_put_dev(vb->usb_dev); kfree(vb); } return ret; } static void vprbrd_disconnect(struct usb_interface *interface) { struct vprbrd *vb = usb_get_intfdata(interface); mfd_remove_devices(&interface->dev); usb_set_intfdata(interface, NULL); usb_put_dev(vb->usb_dev); kfree(vb); dev_dbg(&interface->dev, "disconnected "); } static struct usb_driver vprbrd_driver = { .name = "viperboard", .probe = vprbrd_probe, .disconnect = vprbrd_disconnect, .id_table = vprbrd_table, }; module_usb_driver(vprbrd_driver); MODULE_DESCRIPTION("Nano River Technologies viperboard mfd core driver"); MODULE_AUTHOR("Lars Poeschel <poeschel@lemonage.de>"); MODULE_LICENSE("GPL"); |