2 * Greybus Vibrator protocol driver.
4 * Copyright 2014 Google Inc.
5 * Copyright 2014 Linaro Ltd.
7 * Released under the GPLv2 only.
10 #include <linux/kernel.h>
11 #include <linux/module.h>
12 #include <linux/slab.h>
13 #include <linux/device.h>
14 #include <linux/kdev_t.h>
15 #include <linux/idr.h>
18 struct gb_vibrator_device {
19 struct gb_connection *connection;
21 int minor; /* vibrator minor number */
24 /* Version of the Greybus vibrator protocol we support */
25 #define GB_VIBRATOR_VERSION_MAJOR 0x00
26 #define GB_VIBRATOR_VERSION_MINOR 0x01
28 /* Greybus Vibrator operation types */
29 #define GB_VIBRATOR_TYPE_ON 0x02
30 #define GB_VIBRATOR_TYPE_OFF 0x03
32 struct gb_vibrator_on_request {
36 static int turn_on(struct gb_vibrator_device *vib, u16 timeout_ms)
38 struct gb_vibrator_on_request request;
40 request.timeout_ms = cpu_to_le16(timeout_ms);
41 return gb_operation_sync(vib->connection, GB_VIBRATOR_TYPE_ON,
42 &request, sizeof(request), NULL, 0);
45 static int turn_off(struct gb_vibrator_device *vib)
47 return gb_operation_sync(vib->connection, GB_VIBRATOR_TYPE_OFF,
51 static ssize_t timeout_store(struct device *dev, struct device_attribute *attr,
52 const char *buf, size_t count)
54 struct gb_vibrator_device *vib = dev_get_drvdata(dev);
58 retval = kstrtoul(buf, 10, &val);
60 dev_err(dev, "could not parse timeout value %d\n", retval);
65 retval = turn_on(vib, (u16)val);
67 retval = turn_off(vib);
73 static DEVICE_ATTR_WO(timeout);
75 static struct attribute *vibrator_attrs[] = {
76 &dev_attr_timeout.attr,
79 ATTRIBUTE_GROUPS(vibrator);
81 static struct class vibrator_class = {
84 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)
85 .dev_groups = vibrator_groups,
89 static DEFINE_IDA(minors);
91 static int gb_vibrator_probe(struct gb_bundle *bundle,
92 const struct greybus_bundle_id *id)
94 struct greybus_descriptor_cport *cport_desc;
95 struct gb_connection *connection;
96 struct gb_vibrator_device *vib;
100 if (bundle->num_cports != 1)
103 cport_desc = &bundle->cport_desc[0];
104 if (cport_desc->protocol_id != GREYBUS_PROTOCOL_VIBRATOR)
107 vib = kzalloc(sizeof(*vib), GFP_KERNEL);
111 connection = gb_connection_create(bundle, le16_to_cpu(cport_desc->id),
113 if (IS_ERR(connection)) {
114 retval = PTR_ERR(connection);
117 connection->private = vib;
119 vib->connection = connection;
121 greybus_set_drvdata(bundle, vib);
123 retval = gb_connection_enable(connection);
125 goto err_connection_destroy;
128 * For now we create a device in sysfs for the vibrator, but odds are
129 * there is a "real" device somewhere in the kernel for this, but I
130 * can't find it at the moment...
132 vib->minor = ida_simple_get(&minors, 0, 0, GFP_KERNEL);
133 if (vib->minor < 0) {
135 goto err_connection_disable;
137 dev = device_create(&vibrator_class, &bundle->dev,
138 MKDEV(0, 0), vib, "vibrator%d", vib->minor);
145 #if LINUX_VERSION_CODE <= KERNEL_VERSION(3,11,0)
147 * Newer kernels handle this in a race-free manner, by the dev_groups
148 * field in the struct class up above. But for older kernels, we need
149 * to "open code this :(
151 retval = sysfs_create_group(&dev->kobj, vibrator_groups[0]);
153 device_unregister(dev);
161 ida_simple_remove(&minors, vib->minor);
162 err_connection_disable:
163 gb_connection_disable(connection);
164 err_connection_destroy:
165 gb_connection_destroy(connection);
172 static void gb_vibrator_disconnect(struct gb_bundle *bundle)
174 struct gb_vibrator_device *vib = greybus_get_drvdata(bundle);
176 #if LINUX_VERSION_CODE <= KERNEL_VERSION(3,11,0)
177 sysfs_remove_group(&vib->dev->kobj, vibrator_groups[0]);
179 device_unregister(vib->dev);
180 ida_simple_remove(&minors, vib->minor);
181 gb_connection_disable(vib->connection);
182 gb_connection_destroy(vib->connection);
186 static const struct greybus_bundle_id gb_vibrator_id_table[] = {
187 { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_VIBRATOR) },
190 MODULE_DEVICE_TABLE(greybus, gb_vibrator_id_table);
192 static struct greybus_driver gb_vibrator_driver = {
194 .probe = gb_vibrator_probe,
195 .disconnect = gb_vibrator_disconnect,
196 .id_table = gb_vibrator_id_table,
199 static __init int gb_vibrator_init(void)
203 retval = class_register(&vibrator_class);
207 retval = greybus_register(&gb_vibrator_driver);
209 goto err_class_unregister;
213 err_class_unregister:
214 class_unregister(&vibrator_class);
218 module_init(gb_vibrator_init);
220 static __exit void gb_vibrator_exit(void)
222 greybus_deregister(&gb_vibrator_driver);
223 class_unregister(&vibrator_class);
224 ida_destroy(&minors);
226 module_exit(gb_vibrator_exit);
228 MODULE_LICENSE("GPL v2");