1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * A driver for the Griffin Technology, Inc. "PowerMate" USB controller dial. |
4 | * |
5 | * v1.1, (c)2002 William R Sowerbutts <will@sowerbutts.com> |
6 | * |
7 | * This device is a anodised aluminium knob which connects over USB. It can measure |
8 | * clockwise and anticlockwise rotation. The dial also acts as a pushbutton with |
9 | * a spring for automatic release. The base contains a pair of LEDs which illuminate |
10 | * the translucent base. It rotates without limit and reports its relative rotation |
11 | * back to the host when polled by the USB controller. |
12 | * |
13 | * Testing with the knob I have has shown that it measures approximately 94 "clicks" |
14 | * for one full rotation. Testing with my High Speed Rotation Actuator (ok, it was |
15 | * a variable speed cordless electric drill) has shown that the device can measure |
16 | * speeds of up to 7 clicks either clockwise or anticlockwise between pollings from |
17 | * the host. If it counts more than 7 clicks before it is polled, it will wrap back |
18 | * to zero and start counting again. This was at quite high speed, however, almost |
19 | * certainly faster than the human hand could turn it. Griffin say that it loses a |
20 | * pulse or two on a direction change; the granularity is so fine that I never |
21 | * noticed this in practice. |
22 | * |
23 | * The device's microcontroller can be programmed to set the LED to either a constant |
24 | * intensity, or to a rhythmic pulsing. Several patterns and speeds are available. |
25 | * |
26 | * Griffin were very happy to provide documentation and free hardware for development. |
27 | * |
28 | * Some userspace tools are available on the web: http://sowerbutts.com/powermate/ |
29 | * |
30 | */ |
31 | |
32 | #include <linux/kernel.h> |
33 | #include <linux/slab.h> |
34 | #include <linux/module.h> |
35 | #include <linux/spinlock.h> |
36 | #include <linux/usb/input.h> |
37 | |
38 | #define POWERMATE_VENDOR 0x077d /* Griffin Technology, Inc. */ |
39 | #define POWERMATE_PRODUCT_NEW 0x0410 /* Griffin PowerMate */ |
40 | #define POWERMATE_PRODUCT_OLD 0x04AA /* Griffin soundKnob */ |
41 | |
42 | #define CONTOUR_VENDOR 0x05f3 /* Contour Design, Inc. */ |
43 | #define CONTOUR_JOG 0x0240 /* Jog and Shuttle */ |
44 | |
45 | /* these are the command codes we send to the device */ |
46 | #define SET_STATIC_BRIGHTNESS 0x01 |
47 | #define SET_PULSE_ASLEEP 0x02 |
48 | #define SET_PULSE_AWAKE 0x03 |
49 | #define SET_PULSE_MODE 0x04 |
50 | |
51 | /* these refer to bits in the powermate_device's requires_update field. */ |
52 | #define UPDATE_STATIC_BRIGHTNESS (1<<0) |
53 | #define UPDATE_PULSE_ASLEEP (1<<1) |
54 | #define UPDATE_PULSE_AWAKE (1<<2) |
55 | #define UPDATE_PULSE_MODE (1<<3) |
56 | |
57 | /* at least two versions of the hardware exist, with differing payload |
58 | sizes. the first three bytes always contain the "interesting" data in |
59 | the relevant format. */ |
60 | #define POWERMATE_PAYLOAD_SIZE_MAX 6 |
61 | #define POWERMATE_PAYLOAD_SIZE_MIN 3 |
62 | struct powermate_device { |
63 | signed char *data; |
64 | dma_addr_t data_dma; |
65 | struct urb *irq, *config; |
66 | struct usb_ctrlrequest *configcr; |
67 | struct usb_device *udev; |
68 | struct usb_interface *intf; |
69 | struct input_dev *input; |
70 | spinlock_t lock; |
71 | int static_brightness; |
72 | int pulse_speed; |
73 | int pulse_table; |
74 | int pulse_asleep; |
75 | int pulse_awake; |
76 | int requires_update; // physical settings which are out of sync |
77 | char phys[64]; |
78 | }; |
79 | |
80 | static char pm_name_powermate[] = "Griffin PowerMate" ; |
81 | static char pm_name_soundknob[] = "Griffin SoundKnob" ; |
82 | |
83 | static void powermate_config_complete(struct urb *urb); |
84 | |
85 | /* Callback for data arriving from the PowerMate over the USB interrupt pipe */ |
86 | static void powermate_irq(struct urb *urb) |
87 | { |
88 | struct powermate_device *pm = urb->context; |
89 | struct device *dev = &pm->intf->dev; |
90 | int retval; |
91 | |
92 | switch (urb->status) { |
93 | case 0: |
94 | /* success */ |
95 | break; |
96 | case -ECONNRESET: |
97 | case -ENOENT: |
98 | case -ESHUTDOWN: |
99 | /* this urb is terminated, clean up */ |
100 | dev_dbg(dev, "%s - urb shutting down with status: %d\n" , |
101 | __func__, urb->status); |
102 | return; |
103 | default: |
104 | dev_dbg(dev, "%s - nonzero urb status received: %d\n" , |
105 | __func__, urb->status); |
106 | goto exit; |
107 | } |
108 | |
109 | /* handle updates to device state */ |
110 | input_report_key(dev: pm->input, BTN_0, value: pm->data[0] & 0x01); |
111 | input_report_rel(dev: pm->input, REL_DIAL, value: pm->data[1]); |
112 | input_sync(dev: pm->input); |
113 | |
114 | exit: |
115 | retval = usb_submit_urb (urb, GFP_ATOMIC); |
116 | if (retval) |
117 | dev_err(dev, "%s - usb_submit_urb failed with result: %d\n" , |
118 | __func__, retval); |
119 | } |
120 | |
121 | /* Decide if we need to issue a control message and do so. Must be called with pm->lock taken */ |
122 | static void powermate_sync_state(struct powermate_device *pm) |
123 | { |
124 | if (pm->requires_update == 0) |
125 | return; /* no updates are required */ |
126 | if (pm->config->status == -EINPROGRESS) |
127 | return; /* an update is already in progress; it'll issue this update when it completes */ |
128 | |
129 | if (pm->requires_update & UPDATE_PULSE_ASLEEP){ |
130 | pm->configcr->wValue = cpu_to_le16( SET_PULSE_ASLEEP ); |
131 | pm->configcr->wIndex = cpu_to_le16( pm->pulse_asleep ? 1 : 0 ); |
132 | pm->requires_update &= ~UPDATE_PULSE_ASLEEP; |
133 | }else if (pm->requires_update & UPDATE_PULSE_AWAKE){ |
134 | pm->configcr->wValue = cpu_to_le16( SET_PULSE_AWAKE ); |
135 | pm->configcr->wIndex = cpu_to_le16( pm->pulse_awake ? 1 : 0 ); |
136 | pm->requires_update &= ~UPDATE_PULSE_AWAKE; |
137 | }else if (pm->requires_update & UPDATE_PULSE_MODE){ |
138 | int op, arg; |
139 | /* the powermate takes an operation and an argument for its pulse algorithm. |
140 | the operation can be: |
141 | 0: divide the speed |
142 | 1: pulse at normal speed |
143 | 2: multiply the speed |
144 | the argument only has an effect for operations 0 and 2, and ranges between |
145 | 1 (least effect) to 255 (maximum effect). |
146 | |
147 | thus, several states are equivalent and are coalesced into one state. |
148 | |
149 | we map this onto a range from 0 to 510, with: |
150 | 0 -- 254 -- use divide (0 = slowest) |
151 | 255 -- use normal speed |
152 | 256 -- 510 -- use multiple (510 = fastest). |
153 | |
154 | Only values of 'arg' quite close to 255 are particularly useful/spectacular. |
155 | */ |
156 | if (pm->pulse_speed < 255) { |
157 | op = 0; // divide |
158 | arg = 255 - pm->pulse_speed; |
159 | } else if (pm->pulse_speed > 255) { |
160 | op = 2; // multiply |
161 | arg = pm->pulse_speed - 255; |
162 | } else { |
163 | op = 1; // normal speed |
164 | arg = 0; // can be any value |
165 | } |
166 | pm->configcr->wValue = cpu_to_le16( (pm->pulse_table << 8) | SET_PULSE_MODE ); |
167 | pm->configcr->wIndex = cpu_to_le16( (arg << 8) | op ); |
168 | pm->requires_update &= ~UPDATE_PULSE_MODE; |
169 | } else if (pm->requires_update & UPDATE_STATIC_BRIGHTNESS) { |
170 | pm->configcr->wValue = cpu_to_le16( SET_STATIC_BRIGHTNESS ); |
171 | pm->configcr->wIndex = cpu_to_le16( pm->static_brightness ); |
172 | pm->requires_update &= ~UPDATE_STATIC_BRIGHTNESS; |
173 | } else { |
174 | printk(KERN_ERR "powermate: unknown update required" ); |
175 | pm->requires_update = 0; /* fudge the bug */ |
176 | return; |
177 | } |
178 | |
179 | /* printk("powermate: %04x %04x\n", pm->configcr->wValue, pm->configcr->wIndex); */ |
180 | |
181 | pm->configcr->bRequestType = 0x41; /* vendor request */ |
182 | pm->configcr->bRequest = 0x01; |
183 | pm->configcr->wLength = 0; |
184 | |
185 | usb_fill_control_urb(urb: pm->config, dev: pm->udev, usb_sndctrlpipe(pm->udev, 0), |
186 | setup_packet: (void *) pm->configcr, NULL, buffer_length: 0, |
187 | complete_fn: powermate_config_complete, context: pm); |
188 | |
189 | if (usb_submit_urb(urb: pm->config, GFP_ATOMIC)) |
190 | printk(KERN_ERR "powermate: usb_submit_urb(config) failed" ); |
191 | } |
192 | |
193 | /* Called when our asynchronous control message completes. We may need to issue another immediately */ |
194 | static void powermate_config_complete(struct urb *urb) |
195 | { |
196 | struct powermate_device *pm = urb->context; |
197 | unsigned long flags; |
198 | |
199 | if (urb->status) |
200 | printk(KERN_ERR "powermate: config urb returned %d\n" , urb->status); |
201 | |
202 | spin_lock_irqsave(&pm->lock, flags); |
203 | powermate_sync_state(pm); |
204 | spin_unlock_irqrestore(lock: &pm->lock, flags); |
205 | } |
206 | |
207 | /* Set the LED up as described and begin the sync with the hardware if required */ |
208 | static void powermate_pulse_led(struct powermate_device *pm, int static_brightness, int pulse_speed, |
209 | int pulse_table, int pulse_asleep, int pulse_awake) |
210 | { |
211 | unsigned long flags; |
212 | |
213 | if (pulse_speed < 0) |
214 | pulse_speed = 0; |
215 | if (pulse_table < 0) |
216 | pulse_table = 0; |
217 | if (pulse_speed > 510) |
218 | pulse_speed = 510; |
219 | if (pulse_table > 2) |
220 | pulse_table = 2; |
221 | |
222 | pulse_asleep = !!pulse_asleep; |
223 | pulse_awake = !!pulse_awake; |
224 | |
225 | |
226 | spin_lock_irqsave(&pm->lock, flags); |
227 | |
228 | /* mark state updates which are required */ |
229 | if (static_brightness != pm->static_brightness) { |
230 | pm->static_brightness = static_brightness; |
231 | pm->requires_update |= UPDATE_STATIC_BRIGHTNESS; |
232 | } |
233 | if (pulse_asleep != pm->pulse_asleep) { |
234 | pm->pulse_asleep = pulse_asleep; |
235 | pm->requires_update |= (UPDATE_PULSE_ASLEEP | UPDATE_STATIC_BRIGHTNESS); |
236 | } |
237 | if (pulse_awake != pm->pulse_awake) { |
238 | pm->pulse_awake = pulse_awake; |
239 | pm->requires_update |= (UPDATE_PULSE_AWAKE | UPDATE_STATIC_BRIGHTNESS); |
240 | } |
241 | if (pulse_speed != pm->pulse_speed || pulse_table != pm->pulse_table) { |
242 | pm->pulse_speed = pulse_speed; |
243 | pm->pulse_table = pulse_table; |
244 | pm->requires_update |= UPDATE_PULSE_MODE; |
245 | } |
246 | |
247 | powermate_sync_state(pm); |
248 | |
249 | spin_unlock_irqrestore(lock: &pm->lock, flags); |
250 | } |
251 | |
252 | /* Callback from the Input layer when an event arrives from userspace to configure the LED */ |
253 | static int powermate_input_event(struct input_dev *dev, unsigned int type, unsigned int code, int _value) |
254 | { |
255 | unsigned int command = (unsigned int)_value; |
256 | struct powermate_device *pm = input_get_drvdata(dev); |
257 | |
258 | if (type == EV_MSC && code == MSC_PULSELED){ |
259 | /* |
260 | bits 0- 7: 8 bits: LED brightness |
261 | bits 8-16: 9 bits: pulsing speed modifier (0 ... 510); 0-254 = slower, 255 = standard, 256-510 = faster. |
262 | bits 17-18: 2 bits: pulse table (0, 1, 2 valid) |
263 | bit 19: 1 bit : pulse whilst asleep? |
264 | bit 20: 1 bit : pulse constantly? |
265 | */ |
266 | int static_brightness = command & 0xFF; // bits 0-7 |
267 | int pulse_speed = (command >> 8) & 0x1FF; // bits 8-16 |
268 | int pulse_table = (command >> 17) & 0x3; // bits 17-18 |
269 | int pulse_asleep = (command >> 19) & 0x1; // bit 19 |
270 | int pulse_awake = (command >> 20) & 0x1; // bit 20 |
271 | |
272 | powermate_pulse_led(pm, static_brightness, pulse_speed, pulse_table, pulse_asleep, pulse_awake); |
273 | } |
274 | |
275 | return 0; |
276 | } |
277 | |
278 | static int powermate_alloc_buffers(struct usb_device *udev, struct powermate_device *pm) |
279 | { |
280 | pm->data = usb_alloc_coherent(dev: udev, POWERMATE_PAYLOAD_SIZE_MAX, |
281 | GFP_KERNEL, dma: &pm->data_dma); |
282 | if (!pm->data) |
283 | return -1; |
284 | |
285 | pm->configcr = kmalloc(size: sizeof(*(pm->configcr)), GFP_KERNEL); |
286 | if (!pm->configcr) |
287 | return -ENOMEM; |
288 | |
289 | return 0; |
290 | } |
291 | |
292 | static void powermate_free_buffers(struct usb_device *udev, struct powermate_device *pm) |
293 | { |
294 | usb_free_coherent(dev: udev, POWERMATE_PAYLOAD_SIZE_MAX, |
295 | addr: pm->data, dma: pm->data_dma); |
296 | kfree(objp: pm->configcr); |
297 | } |
298 | |
299 | /* Called whenever a USB device matching one in our supported devices table is connected */ |
300 | static int powermate_probe(struct usb_interface *intf, const struct usb_device_id *id) |
301 | { |
302 | struct usb_device *udev = interface_to_usbdev (intf); |
303 | struct usb_host_interface *interface; |
304 | struct usb_endpoint_descriptor *endpoint; |
305 | struct powermate_device *pm; |
306 | struct input_dev *input_dev; |
307 | int pipe, maxp; |
308 | int error = -ENOMEM; |
309 | |
310 | interface = intf->cur_altsetting; |
311 | if (interface->desc.bNumEndpoints < 1) |
312 | return -EINVAL; |
313 | |
314 | endpoint = &interface->endpoint[0].desc; |
315 | if (!usb_endpoint_is_int_in(epd: endpoint)) |
316 | return -EIO; |
317 | |
318 | usb_control_msg(dev: udev, usb_sndctrlpipe(udev, 0), |
319 | request: 0x0a, USB_TYPE_CLASS | USB_RECIP_INTERFACE, |
320 | value: 0, index: interface->desc.bInterfaceNumber, NULL, size: 0, |
321 | USB_CTRL_SET_TIMEOUT); |
322 | |
323 | pm = kzalloc(size: sizeof(struct powermate_device), GFP_KERNEL); |
324 | input_dev = input_allocate_device(); |
325 | if (!pm || !input_dev) |
326 | goto fail1; |
327 | |
328 | if (powermate_alloc_buffers(udev, pm)) |
329 | goto fail2; |
330 | |
331 | pm->irq = usb_alloc_urb(iso_packets: 0, GFP_KERNEL); |
332 | if (!pm->irq) |
333 | goto fail2; |
334 | |
335 | pm->config = usb_alloc_urb(iso_packets: 0, GFP_KERNEL); |
336 | if (!pm->config) |
337 | goto fail3; |
338 | |
339 | pm->udev = udev; |
340 | pm->intf = intf; |
341 | pm->input = input_dev; |
342 | |
343 | usb_make_path(dev: udev, buf: pm->phys, size: sizeof(pm->phys)); |
344 | strlcat(p: pm->phys, q: "/input0" , avail: sizeof(pm->phys)); |
345 | |
346 | spin_lock_init(&pm->lock); |
347 | |
348 | switch (le16_to_cpu(udev->descriptor.idProduct)) { |
349 | case POWERMATE_PRODUCT_NEW: |
350 | input_dev->name = pm_name_powermate; |
351 | break; |
352 | case POWERMATE_PRODUCT_OLD: |
353 | input_dev->name = pm_name_soundknob; |
354 | break; |
355 | default: |
356 | input_dev->name = pm_name_soundknob; |
357 | printk(KERN_WARNING "powermate: unknown product id %04x\n" , |
358 | le16_to_cpu(udev->descriptor.idProduct)); |
359 | } |
360 | |
361 | input_dev->phys = pm->phys; |
362 | usb_to_input_id(dev: udev, id: &input_dev->id); |
363 | input_dev->dev.parent = &intf->dev; |
364 | |
365 | input_set_drvdata(dev: input_dev, data: pm); |
366 | |
367 | input_dev->event = powermate_input_event; |
368 | |
369 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL) | |
370 | BIT_MASK(EV_MSC); |
371 | input_dev->keybit[BIT_WORD(BTN_0)] = BIT_MASK(BTN_0); |
372 | input_dev->relbit[BIT_WORD(REL_DIAL)] = BIT_MASK(REL_DIAL); |
373 | input_dev->mscbit[BIT_WORD(MSC_PULSELED)] = BIT_MASK(MSC_PULSELED); |
374 | |
375 | /* get a handle to the interrupt data pipe */ |
376 | pipe = usb_rcvintpipe(udev, endpoint->bEndpointAddress); |
377 | maxp = usb_maxpacket(udev, pipe); |
378 | |
379 | if (maxp < POWERMATE_PAYLOAD_SIZE_MIN || maxp > POWERMATE_PAYLOAD_SIZE_MAX) { |
380 | printk(KERN_WARNING "powermate: Expected payload of %d--%d bytes, found %d bytes!\n" , |
381 | POWERMATE_PAYLOAD_SIZE_MIN, POWERMATE_PAYLOAD_SIZE_MAX, maxp); |
382 | maxp = POWERMATE_PAYLOAD_SIZE_MAX; |
383 | } |
384 | |
385 | usb_fill_int_urb(urb: pm->irq, dev: udev, pipe, transfer_buffer: pm->data, |
386 | buffer_length: maxp, complete_fn: powermate_irq, |
387 | context: pm, interval: endpoint->bInterval); |
388 | pm->irq->transfer_dma = pm->data_dma; |
389 | pm->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; |
390 | |
391 | /* register our interrupt URB with the USB system */ |
392 | if (usb_submit_urb(urb: pm->irq, GFP_KERNEL)) { |
393 | error = -EIO; |
394 | goto fail4; |
395 | } |
396 | |
397 | error = input_register_device(pm->input); |
398 | if (error) |
399 | goto fail5; |
400 | |
401 | |
402 | /* force an update of everything */ |
403 | pm->requires_update = UPDATE_PULSE_ASLEEP | UPDATE_PULSE_AWAKE | UPDATE_PULSE_MODE | UPDATE_STATIC_BRIGHTNESS; |
404 | powermate_pulse_led(pm, static_brightness: 0x80, pulse_speed: 255, pulse_table: 0, pulse_asleep: 1, pulse_awake: 0); // set default pulse parameters |
405 | |
406 | usb_set_intfdata(intf, data: pm); |
407 | return 0; |
408 | |
409 | fail5: usb_kill_urb(urb: pm->irq); |
410 | fail4: usb_free_urb(urb: pm->config); |
411 | fail3: usb_free_urb(urb: pm->irq); |
412 | fail2: powermate_free_buffers(udev, pm); |
413 | fail1: input_free_device(dev: input_dev); |
414 | kfree(objp: pm); |
415 | return error; |
416 | } |
417 | |
418 | /* Called when a USB device we've accepted ownership of is removed */ |
419 | static void powermate_disconnect(struct usb_interface *intf) |
420 | { |
421 | struct powermate_device *pm = usb_get_intfdata (intf); |
422 | |
423 | usb_set_intfdata(intf, NULL); |
424 | if (pm) { |
425 | pm->requires_update = 0; |
426 | usb_kill_urb(urb: pm->irq); |
427 | input_unregister_device(pm->input); |
428 | usb_kill_urb(urb: pm->config); |
429 | usb_free_urb(urb: pm->irq); |
430 | usb_free_urb(urb: pm->config); |
431 | powermate_free_buffers(interface_to_usbdev(intf), pm); |
432 | |
433 | kfree(objp: pm); |
434 | } |
435 | } |
436 | |
437 | static const struct usb_device_id powermate_devices[] = { |
438 | { USB_DEVICE(POWERMATE_VENDOR, POWERMATE_PRODUCT_NEW) }, |
439 | { USB_DEVICE(POWERMATE_VENDOR, POWERMATE_PRODUCT_OLD) }, |
440 | { USB_DEVICE(CONTOUR_VENDOR, CONTOUR_JOG) }, |
441 | { } /* Terminating entry */ |
442 | }; |
443 | |
444 | MODULE_DEVICE_TABLE (usb, powermate_devices); |
445 | |
446 | static struct usb_driver powermate_driver = { |
447 | .name = "powermate" , |
448 | .probe = powermate_probe, |
449 | .disconnect = powermate_disconnect, |
450 | .id_table = powermate_devices, |
451 | }; |
452 | |
453 | module_usb_driver(powermate_driver); |
454 | |
455 | MODULE_AUTHOR( "William R Sowerbutts" ); |
456 | MODULE_DESCRIPTION( "Griffin Technology, Inc PowerMate driver" ); |
457 | MODULE_LICENSE("GPL" ); |
458 | |