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>
16 #include <linux/pm_runtime.h>
20 struct gb_vibrator_device
{
21 struct gb_connection
*connection
;
23 int minor
; /* vibrator minor number */
24 struct delayed_work delayed_work
;
27 /* Greybus Vibrator operation types */
28 #define GB_VIBRATOR_TYPE_ON 0x02
29 #define GB_VIBRATOR_TYPE_OFF 0x03
31 static int turn_off(struct gb_vibrator_device
*vib
)
33 struct gb_bundle
*bundle
= vib
->connection
->bundle
;
36 ret
= gb_operation_sync(vib
->connection
, GB_VIBRATOR_TYPE_OFF
,
39 gb_pm_runtime_put_autosuspend(bundle
);
44 static int turn_on(struct gb_vibrator_device
*vib
, u16 timeout_ms
)
46 struct gb_bundle
*bundle
= vib
->connection
->bundle
;
49 ret
= gb_pm_runtime_get_sync(bundle
);
53 /* Vibrator was switched ON earlier */
54 if (cancel_delayed_work_sync(&vib
->delayed_work
))
57 ret
= gb_operation_sync(vib
->connection
, GB_VIBRATOR_TYPE_ON
,
60 gb_pm_runtime_put_autosuspend(bundle
);
64 schedule_delayed_work(&vib
->delayed_work
, msecs_to_jiffies(timeout_ms
));
69 static void gb_vibrator_worker(struct work_struct
*work
)
71 struct delayed_work
*delayed_work
= to_delayed_work(work
);
72 struct gb_vibrator_device
*vib
=
73 container_of(delayed_work
,
74 struct gb_vibrator_device
,
80 static ssize_t
timeout_store(struct device
*dev
, struct device_attribute
*attr
,
81 const char *buf
, size_t count
)
83 struct gb_vibrator_device
*vib
= dev_get_drvdata(dev
);
87 retval
= kstrtoul(buf
, 10, &val
);
89 dev_err(dev
, "could not parse timeout value %d\n", retval
);
94 retval
= turn_on(vib
, (u16
)val
);
96 retval
= turn_off(vib
);
102 static DEVICE_ATTR_WO(timeout
);
104 static struct attribute
*vibrator_attrs
[] = {
105 &dev_attr_timeout
.attr
,
108 ATTRIBUTE_GROUPS(vibrator
);
110 static struct class vibrator_class
= {
112 .owner
= THIS_MODULE
,
113 .dev_groups
= vibrator_groups
,
116 static DEFINE_IDA(minors
);
118 static int gb_vibrator_probe(struct gb_bundle
*bundle
,
119 const struct greybus_bundle_id
*id
)
121 struct greybus_descriptor_cport
*cport_desc
;
122 struct gb_connection
*connection
;
123 struct gb_vibrator_device
*vib
;
127 if (bundle
->num_cports
!= 1)
130 cport_desc
= &bundle
->cport_desc
[0];
131 if (cport_desc
->protocol_id
!= GREYBUS_PROTOCOL_VIBRATOR
)
134 vib
= kzalloc(sizeof(*vib
), GFP_KERNEL
);
138 connection
= gb_connection_create(bundle
, le16_to_cpu(cport_desc
->id
),
140 if (IS_ERR(connection
)) {
141 retval
= PTR_ERR(connection
);
144 gb_connection_set_data(connection
, vib
);
146 vib
->connection
= connection
;
148 greybus_set_drvdata(bundle
, vib
);
150 retval
= gb_connection_enable(connection
);
152 goto err_connection_destroy
;
155 * For now we create a device in sysfs for the vibrator, but odds are
156 * there is a "real" device somewhere in the kernel for this, but I
157 * can't find it at the moment...
159 vib
->minor
= ida_simple_get(&minors
, 0, 0, GFP_KERNEL
);
160 if (vib
->minor
< 0) {
162 goto err_connection_disable
;
164 dev
= device_create(&vibrator_class
, &bundle
->dev
,
165 MKDEV(0, 0), vib
, "vibrator%d", vib
->minor
);
172 INIT_DELAYED_WORK(&vib
->delayed_work
, gb_vibrator_worker
);
174 gb_pm_runtime_put_autosuspend(bundle
);
179 ida_simple_remove(&minors
, vib
->minor
);
180 err_connection_disable
:
181 gb_connection_disable(connection
);
182 err_connection_destroy
:
183 gb_connection_destroy(connection
);
190 static void gb_vibrator_disconnect(struct gb_bundle
*bundle
)
192 struct gb_vibrator_device
*vib
= greybus_get_drvdata(bundle
);
195 ret
= gb_pm_runtime_get_sync(bundle
);
197 gb_pm_runtime_get_noresume(bundle
);
199 if (cancel_delayed_work_sync(&vib
->delayed_work
))
202 device_unregister(vib
->dev
);
203 ida_simple_remove(&minors
, vib
->minor
);
204 gb_connection_disable(vib
->connection
);
205 gb_connection_destroy(vib
->connection
);
209 static const struct greybus_bundle_id gb_vibrator_id_table
[] = {
210 { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_VIBRATOR
) },
213 MODULE_DEVICE_TABLE(greybus
, gb_vibrator_id_table
);
215 static struct greybus_driver gb_vibrator_driver
= {
217 .probe
= gb_vibrator_probe
,
218 .disconnect
= gb_vibrator_disconnect
,
219 .id_table
= gb_vibrator_id_table
,
222 static __init
int gb_vibrator_init(void)
226 retval
= class_register(&vibrator_class
);
230 retval
= greybus_register(&gb_vibrator_driver
);
232 goto err_class_unregister
;
236 err_class_unregister
:
237 class_unregister(&vibrator_class
);
241 module_init(gb_vibrator_init
);
243 static __exit
void gb_vibrator_exit(void)
245 greybus_deregister(&gb_vibrator_driver
);
246 class_unregister(&vibrator_class
);
247 ida_destroy(&minors
);
249 module_exit(gb_vibrator_exit
);
251 MODULE_LICENSE("GPL v2");