greybus: replace Ara references
[cascardo/linux.git] / drivers / staging / greybus / vibrator.c
1 /*
2  * Greybus Vibrator protocol driver.
3  *
4  * Copyright 2014 Google Inc.
5  * Copyright 2014 Linaro Ltd.
6  *
7  * Released under the GPLv2 only.
8  */
9
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>
16 #include <linux/pm_runtime.h>
17
18 #include "greybus.h"
19
20 struct gb_vibrator_device {
21         struct gb_connection    *connection;
22         struct device           *dev;
23         int                     minor;          /* vibrator minor number */
24 };
25
26 /* Greybus Vibrator operation types */
27 #define GB_VIBRATOR_TYPE_ON                     0x02
28 #define GB_VIBRATOR_TYPE_OFF                    0x03
29
30 struct gb_vibrator_on_request {
31         __le16  timeout_ms;
32 };
33
34 static int turn_on(struct gb_vibrator_device *vib, u16 timeout_ms)
35 {
36         struct gb_vibrator_on_request request;
37         struct gb_bundle *bundle = vib->connection->bundle;
38         int ret;
39
40         ret = gb_pm_runtime_get_sync(bundle);
41         if (ret)
42                 return ret;
43
44         request.timeout_ms = cpu_to_le16(timeout_ms);
45         ret = gb_operation_sync(vib->connection, GB_VIBRATOR_TYPE_ON,
46                         &request, sizeof(request), NULL, 0);
47
48         gb_pm_runtime_put_autosuspend(bundle);
49
50         return ret;
51 }
52
53 static int turn_off(struct gb_vibrator_device *vib)
54 {
55         struct gb_bundle *bundle = vib->connection->bundle;
56         int ret;
57
58         ret = gb_pm_runtime_get_sync(bundle);
59         if (ret)
60                 return ret;
61
62         ret = gb_operation_sync(vib->connection, GB_VIBRATOR_TYPE_OFF,
63                         NULL, 0, NULL, 0);
64
65         gb_pm_runtime_put_autosuspend(bundle);
66
67         return ret;
68 }
69
70 static ssize_t timeout_store(struct device *dev, struct device_attribute *attr,
71                              const char *buf, size_t count)
72 {
73         struct gb_vibrator_device *vib = dev_get_drvdata(dev);
74         unsigned long val;
75         int retval;
76
77         retval = kstrtoul(buf, 10, &val);
78         if (retval < 0) {
79                 dev_err(dev, "could not parse timeout value %d\n", retval);
80                 return retval;
81         }
82
83         if (val)
84                 retval = turn_on(vib, (u16)val);
85         else
86                 retval = turn_off(vib);
87         if (retval)
88                 return retval;
89
90         return count;
91 }
92 static DEVICE_ATTR_WO(timeout);
93
94 static struct attribute *vibrator_attrs[] = {
95         &dev_attr_timeout.attr,
96         NULL,
97 };
98 ATTRIBUTE_GROUPS(vibrator);
99
100 static struct class vibrator_class = {
101         .name           = "vibrator",
102         .owner          = THIS_MODULE,
103 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)
104         .dev_groups     = vibrator_groups,
105 #endif
106 };
107
108 static DEFINE_IDA(minors);
109
110 static int gb_vibrator_probe(struct gb_bundle *bundle,
111                                         const struct greybus_bundle_id *id)
112 {
113         struct greybus_descriptor_cport *cport_desc;
114         struct gb_connection *connection;
115         struct gb_vibrator_device *vib;
116         struct device *dev;
117         int retval;
118
119         if (bundle->num_cports != 1)
120                 return -ENODEV;
121
122         cport_desc = &bundle->cport_desc[0];
123         if (cport_desc->protocol_id != GREYBUS_PROTOCOL_VIBRATOR)
124                 return -ENODEV;
125
126         vib = kzalloc(sizeof(*vib), GFP_KERNEL);
127         if (!vib)
128                 return -ENOMEM;
129
130         connection = gb_connection_create(bundle, le16_to_cpu(cport_desc->id),
131                                                 NULL);
132         if (IS_ERR(connection)) {
133                 retval = PTR_ERR(connection);
134                 goto err_free_vib;
135         }
136         gb_connection_set_data(connection, vib);
137
138         vib->connection = connection;
139
140         greybus_set_drvdata(bundle, vib);
141
142         retval = gb_connection_enable(connection);
143         if (retval)
144                 goto err_connection_destroy;
145
146         /*
147          * For now we create a device in sysfs for the vibrator, but odds are
148          * there is a "real" device somewhere in the kernel for this, but I
149          * can't find it at the moment...
150          */
151         vib->minor = ida_simple_get(&minors, 0, 0, GFP_KERNEL);
152         if (vib->minor < 0) {
153                 retval = vib->minor;
154                 goto err_connection_disable;
155         }
156         dev = device_create(&vibrator_class, &bundle->dev,
157                             MKDEV(0, 0), vib, "vibrator%d", vib->minor);
158         if (IS_ERR(dev)) {
159                 retval = -EINVAL;
160                 goto err_ida_remove;
161         }
162         vib->dev = dev;
163
164 #if LINUX_VERSION_CODE <= KERNEL_VERSION(3,11,0)
165         /*
166          * Newer kernels handle this in a race-free manner, by the dev_groups
167          * field in the struct class up above.  But for older kernels, we need
168          * to "open code this :(
169          */
170         retval = sysfs_create_group(&dev->kobj, vibrator_groups[0]);
171         if (retval) {
172                 device_unregister(dev);
173                 goto err_ida_remove;
174         }
175 #endif
176
177         gb_pm_runtime_put_autosuspend(bundle);
178
179         return 0;
180
181 err_ida_remove:
182         ida_simple_remove(&minors, vib->minor);
183 err_connection_disable:
184         gb_connection_disable(connection);
185 err_connection_destroy:
186         gb_connection_destroy(connection);
187 err_free_vib:
188         kfree(vib);
189
190         return retval;
191 }
192
193 static void gb_vibrator_disconnect(struct gb_bundle *bundle)
194 {
195         struct gb_vibrator_device *vib = greybus_get_drvdata(bundle);
196         int ret;
197
198         ret = gb_pm_runtime_get_sync(bundle);
199         if (ret)
200                 gb_pm_runtime_get_noresume(bundle);
201
202 #if LINUX_VERSION_CODE <= KERNEL_VERSION(3,11,0)
203         sysfs_remove_group(&vib->dev->kobj, vibrator_groups[0]);
204 #endif
205         device_unregister(vib->dev);
206         ida_simple_remove(&minors, vib->minor);
207         gb_connection_disable(vib->connection);
208         gb_connection_destroy(vib->connection);
209         kfree(vib);
210 }
211
212 static const struct greybus_bundle_id gb_vibrator_id_table[] = {
213         { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_VIBRATOR) },
214         { }
215 };
216 MODULE_DEVICE_TABLE(greybus, gb_vibrator_id_table);
217
218 static struct greybus_driver gb_vibrator_driver = {
219         .name           = "vibrator",
220         .probe          = gb_vibrator_probe,
221         .disconnect     = gb_vibrator_disconnect,
222         .id_table       = gb_vibrator_id_table,
223 };
224
225 static __init int gb_vibrator_init(void)
226 {
227         int retval;
228
229         retval = class_register(&vibrator_class);
230         if (retval)
231                 return retval;
232
233         retval = greybus_register(&gb_vibrator_driver);
234         if (retval)
235                 goto err_class_unregister;
236
237         return 0;
238
239 err_class_unregister:
240         class_unregister(&vibrator_class);
241
242         return retval;
243 }
244 module_init(gb_vibrator_init);
245
246 static __exit void gb_vibrator_exit(void)
247 {
248         greybus_deregister(&gb_vibrator_driver);
249         class_unregister(&vibrator_class);
250         ida_destroy(&minors);
251 }
252 module_exit(gb_vibrator_exit);
253
254 MODULE_LICENSE("GPL v2");