more changes on original files
[linux-2.4.git] / drivers / usb / powermate.c
1 /*
2  * A driver for the Griffin Technology, Inc. "PowerMate" USB controller dial.
3  *
4  * v1.1, (c)2002 William R Sowerbutts <will@sowerbutts.com>
5  *
6  * This device is an anodized aluminium knob which connects over USB. It can measure
7  * clockwise and anticlockwise rotation. The dial also acts as a pushbutton with
8  * a spring for automatic release. The base contains a pair of LEDs which illuminate
9  * the translucent base. It rotates without limit and reports its relative rotation
10  * back to the host when polled by the USB controller.
11  *
12  * Testing with the knob I have has shown that it measures approximately 96 "clicks"
13  * for one full rotation. Testing with my High Speed Rotation Actuator (ok, it was 
14  * a variable speed cordless electric drill) has shown that the device can measure
15  * speeds of up to 7 clicks either clockwise or anticlockwise between pollings from
16  * the host. If it counts more than 7 clicks before it is polled, it will wrap back
17  * to zero and start counting again. This was at quite high speed, however, almost
18  * certainly faster than the human hand could turn it. Griffin say that it loses a
19  * pulse or two on a direction change; the granularity is so fine that I never
20  * noticed this in practice.
21  *
22  * The device's microcontroller can be programmed to set the LED to either a constant
23  * intensity, or to a rhythmic pulsing. Several patterns and speeds are available.
24  *
25  * Griffin were very happy to provide documentation and free hardware for development.
26  *
27  */
28
29 #include <linux/kernel.h>
30 #include <linux/slab.h>
31 #include <linux/input.h>
32 #include <linux/module.h>
33 #include <linux/init.h>
34 #include <linux/usb.h>
35
36 #define POWERMATE_VENDOR       0x077d    /* Griffin Technology, Inc. */
37 #define POWERMATE_PRODUCT_NEW  0x0410    /* Griffin PowerMate */
38 #define POWERMATE_PRODUCT_OLD  0x04AA    /* Griffin soundKnob */
39
40 /* these are the command codes we send to the device */
41 #define SET_STATIC_BRIGHTNESS  0x01
42 #define SET_PULSE_ASLEEP       0x02
43 #define SET_PULSE_AWAKE        0x03
44 #define SET_PULSE_MODE         0x04
45
46 /* these refer to bits in the powermate_device's requires_update field. */
47 #define UPDATE_STATIC_BRIGHTNESS (1<<0)
48 #define UPDATE_PULSE_ASLEEP      (1<<1)
49 #define UPDATE_PULSE_AWAKE       (1<<2)
50 #define UPDATE_PULSE_MODE        (1<<3)
51
52 /* at least two versions of the hardware exist, with differing payload 
53    sizes. the first three bytes always contain the "interesting" data in
54    the relevant format. */
55 #define POWERMATE_PAYLOAD_SIZE_MAX 6
56 #define POWERMATE_PAYLOAD_SIZE_MIN 3
57 struct powermate_device {
58         signed char data[POWERMATE_PAYLOAD_SIZE_MAX];
59         struct urb irq, config;
60         struct usb_ctrlrequest configdr;
61         struct usb_device *udev;
62         struct input_dev input;
63         struct semaphore lock;
64         int static_brightness;
65         int pulse_speed;
66         int pulse_table;
67         int pulse_asleep;
68         int pulse_awake;
69         int requires_update; // physical settings which are out of sync
70         char phys[64];
71 };
72
73 static char pm_name_powermate[] = "Griffin PowerMate";
74 static char pm_name_soundknob[] = "Griffin SoundKnob";
75
76 static void powermate_config_complete(struct urb *urb); /* forward declararation of callback */
77
78 /* Callback for data arriving from the PowerMate over the USB interrupt pipe */
79 static void powermate_irq(struct urb *urb)
80 {
81         struct powermate_device *pm = urb->context;
82
83         if(urb->status)
84                 return;
85
86         /* handle updates to device state */
87         input_report_key(&pm->input, BTN_0, pm->data[0] & 0x01);
88         input_report_rel(&pm->input, REL_DIAL, pm->data[1]);
89 }
90
91 /* Decide if we need to issue a control message and do so. Must be called with pm->lock down */
92 static void powermate_sync_state(struct powermate_device *pm)
93 {
94         if(pm->requires_update == 0) 
95                 return; /* no updates are required */
96         if(pm->config.status == -EINPROGRESS) 
97                 return; /* an update is already in progress; it'll issue this update when it completes */
98
99         if(pm->requires_update & UPDATE_PULSE_ASLEEP){
100                 pm->configdr.wValue = cpu_to_le16( SET_PULSE_ASLEEP );
101                 pm->configdr.wIndex = cpu_to_le16( pm->pulse_asleep ? 1 : 0 );
102                 pm->requires_update &= ~UPDATE_PULSE_ASLEEP;
103         }else if(pm->requires_update & UPDATE_PULSE_AWAKE){
104                 pm->configdr.wValue = cpu_to_le16( SET_PULSE_AWAKE );
105                 pm->configdr.wIndex = cpu_to_le16( pm->pulse_awake ? 1 : 0 );
106                 pm->requires_update &= ~UPDATE_PULSE_AWAKE;
107         }else if(pm->requires_update & UPDATE_PULSE_MODE){
108                 int op, arg;
109                 /* the powermate takes an operation and an argument for its pulse algorithm.
110                    the operation can be:
111                    0: divide the speed
112                    1: pulse at normal speed
113                    2: multiply the speed
114                    the argument only has an effect for operations 0 and 2, and ranges between
115                    1 (least effect) to 255 (maximum effect).
116        
117                    thus, several states are equivalent and are coalesced into one state.
118
119                    we map this onto a range from 0 to 510, with:
120                    0 -- 254    -- use divide (0 = slowest)
121                    255         -- use normal speed
122                    256 -- 510  -- use multiple (510 = fastest).
123
124                    Only values of 'arg' quite close to 255 are particularly useful/spectacular.
125                 */    
126                 if(pm->pulse_speed < 255){
127                         op = 0;                   // divide
128                         arg = 255 - pm->pulse_speed;
129                 }else if(pm->pulse_speed > 255){
130                         op = 2;                   // multiply
131                         arg = pm->pulse_speed - 255;
132                 }else{
133                         op = 1;                   // normal speed
134                         arg = 0;                  // can be any value
135                 }
136                 pm->configdr.wValue = cpu_to_le16( (pm->pulse_table << 8) | SET_PULSE_MODE );
137                 pm->configdr.wIndex = cpu_to_le16( (arg << 8) | op );
138                 pm->requires_update &= ~UPDATE_PULSE_MODE;
139         }else if(pm->requires_update & UPDATE_STATIC_BRIGHTNESS){
140                 pm->configdr.wValue = cpu_to_le16( SET_STATIC_BRIGHTNESS );
141                 pm->configdr.wIndex = cpu_to_le16( pm->static_brightness );
142                 pm->requires_update &= ~UPDATE_STATIC_BRIGHTNESS;
143         }else{
144                 printk(KERN_ERR "powermate: unknown update required");
145                 pm->requires_update = 0; /* fudge the bug */
146                 return;
147         }
148
149         pm->config.dev = pm->udev; /* is this necessary? */
150         pm->configdr.bRequestType = 0x41; /* vendor request */
151         pm->configdr.bRequest = 0x01;
152         pm->configdr.wLength = 0;
153
154         FILL_CONTROL_URB(&pm->config, pm->udev, usb_sndctrlpipe(pm->udev, 0), 
155                          (void*)&pm->configdr, 0, 0, powermate_config_complete, pm);    
156
157         if(usb_submit_urb(&pm->config))
158                 printk(KERN_ERR "powermate: usb_submit_urb(config) failed");
159 }
160
161 /* Called when our asynchronous control message completes. We may need to issue another immediately */
162 static void powermate_config_complete(struct urb *urb)
163 {
164         struct powermate_device *pm = urb->context;
165
166         if(urb->status)
167                 printk(KERN_ERR "powermate: config urb returned %d\n", urb->status);
168         
169         down(&pm->lock);
170         powermate_sync_state(pm);
171         up(&pm->lock);
172 }
173
174 /* Set the LED up as described and begin the sync with the hardware if required */
175 static void powermate_pulse_led(struct powermate_device *pm, int static_brightness, int pulse_speed, 
176                                 int pulse_table, int pulse_asleep, int pulse_awake)
177 {
178         if(pulse_speed < 0)
179                 pulse_speed = 0;
180         if(pulse_table < 0)
181                 pulse_table = 0;
182         if(pulse_speed > 510)
183                 pulse_speed = 510;
184         if(pulse_table > 2)
185                 pulse_table = 2;
186
187         pulse_asleep = !!pulse_asleep;
188         pulse_awake = !!pulse_awake;
189
190         down(&pm->lock);
191
192         /* mark state updates which are required */
193         /* we update the static brightness if we've changed pulse mode,
194            because the hardware seems to stick at an arbitrary value rather
195            than jumping back to the static brightness we requested */
196         if(static_brightness != pm->static_brightness){
197                 pm->static_brightness = static_brightness;
198                 pm->requires_update |= UPDATE_STATIC_BRIGHTNESS;                
199         }
200         if(pulse_asleep != pm->pulse_asleep){
201                 pm->pulse_asleep = pulse_asleep;
202                 pm->requires_update |= (UPDATE_PULSE_ASLEEP | UPDATE_STATIC_BRIGHTNESS);
203         }
204         if(pulse_awake != pm->pulse_awake){
205                 pm->pulse_awake = pulse_awake;
206                 pm->requires_update |= (UPDATE_PULSE_AWAKE | UPDATE_STATIC_BRIGHTNESS);
207         }
208         if(pulse_speed != pm->pulse_speed || pulse_table != pm->pulse_table){
209                 pm->pulse_speed = pulse_speed;
210                 pm->pulse_table = pulse_table;
211                 pm->requires_update |= UPDATE_PULSE_MODE;
212         }
213
214         powermate_sync_state(pm);
215    
216         up(&pm->lock);
217 }
218
219 /* Callback from the Input layer when an event arrives from userspace to configure the LED */
220 static int powermate_input_event(struct input_dev *dev, unsigned int type, unsigned int code, int _value)
221 {
222         unsigned int command = (unsigned int)_value;
223         struct powermate_device *pm = dev->private;
224
225         if(type == EV_MSC && code == MSC_PULSELED){
226                 /*  
227                     bits  0- 7: 8 bits: LED brightness
228                     bits  8-16: 9 bits: pulsing speed modifier (0 ... 510); 0-254 = slower, 255 = standard, 256-510 = faster.
229                     bits 17-18: 2 bits: pulse table (0, 1, 2 valid)
230                     bit     19: 1 bit : pulse whilst asleep?
231                     bit     20: 1 bit : pulse constantly?
232                 */  
233                 int static_brightness = command & 0xFF;   // bits 0-7
234                 int pulse_speed = (command >> 8) & 0x1FF; // bits 8-16
235                 int pulse_table = (command >> 17) & 0x3;  // bits 17-18
236                 int pulse_asleep = (command >> 19) & 0x1; // bit 19
237                 int pulse_awake  = (command >> 20) & 0x1; // bit 20
238   
239                 powermate_pulse_led(pm, static_brightness, pulse_speed, pulse_table, pulse_asleep, pulse_awake);
240         }
241
242         return 0;
243 }
244
245 /* Called whenever a USB device matching one in our supported devices table is connected */
246 static void *powermate_probe(struct usb_device *udev, unsigned int ifnum, const struct usb_device_id *id)
247 {
248         struct usb_interface_descriptor *interface;
249         struct usb_endpoint_descriptor *endpoint;
250         struct powermate_device *pm;
251         int pipe, maxp;
252
253         interface = udev->config[0].interface[ifnum].altsetting + 0;
254         endpoint = interface->endpoint + 0;
255         if (!(endpoint->bEndpointAddress & 0x80)) return NULL;
256         if ((endpoint->bmAttributes & 3) != 3) return NULL;
257
258         usb_set_protocol(udev, interface->bInterfaceNumber, 0);
259         usb_set_idle(udev, interface->bInterfaceNumber, 0, 0);
260
261         if (!(pm = kmalloc(sizeof(struct powermate_device), GFP_KERNEL)))
262                 return NULL;
263
264         memset(pm, 0, sizeof(struct powermate_device));
265         pm->udev = udev;
266
267         init_MUTEX(&pm->lock);
268
269         /* get a handle to the interrupt data pipe */
270         pipe = usb_rcvintpipe(udev, endpoint->bEndpointAddress);
271         maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe));
272
273         if(maxp < POWERMATE_PAYLOAD_SIZE_MIN || maxp > POWERMATE_PAYLOAD_SIZE_MAX){
274                 printk("powermate: Expected payload of %d--%d bytes, found %d bytes!\n", 
275                        POWERMATE_PAYLOAD_SIZE_MIN, POWERMATE_PAYLOAD_SIZE_MAX, maxp);
276                 maxp = POWERMATE_PAYLOAD_SIZE_MAX;
277         }
278
279
280         FILL_INT_URB(&pm->irq, udev, pipe, pm->data, maxp, powermate_irq, pm, endpoint->bInterval);
281
282         /* register our interrupt URB with the USB system */
283         if(usb_submit_urb(&pm->irq)) {
284                 kfree(pm);
285                 return NULL; /* failure */
286         }
287
288         switch (udev->descriptor.idProduct) {
289         case POWERMATE_PRODUCT_NEW: pm->input.name = pm_name_powermate; break;
290         case POWERMATE_PRODUCT_OLD: pm->input.name = pm_name_soundknob; break;
291         default: 
292           pm->input.name = pm_name_soundknob;
293           printk(KERN_WARNING "powermate: unknown product id %04x\n", udev->descriptor.idProduct);
294         }
295
296         pm->input.private = pm;
297         pm->input.evbit[0] = BIT(EV_KEY) | BIT(EV_REL) | BIT(EV_MSC);
298         pm->input.keybit[LONG(BTN_0)] = BIT(BTN_0);
299         pm->input.relbit[LONG(REL_DIAL)] = BIT(REL_DIAL);
300         pm->input.mscbit[LONG(MSC_PULSELED)] = BIT(MSC_PULSELED);
301         pm->input.idbus = BUS_USB;
302         pm->input.idvendor = udev->descriptor.idVendor;
303         pm->input.idproduct = udev->descriptor.idProduct;
304         pm->input.idversion = udev->descriptor.bcdDevice;
305         pm->input.event = powermate_input_event;
306
307         input_register_device(&pm->input);
308
309 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0) /* Vojtech -- is this the correct version? */
310         {
311                 char path[64];
312                 usb_make_path(udev, path, 64);
313                 snprintf(pm->phys, 64, "%s/input0", path);
314                 printk(KERN_INFO "input: %s on %s\n", pm->input.name, pm->input.path);
315         }
316 #else
317         printk(KERN_INFO "input: %s on input%d\n", pm->input.name, pm->input.number);
318 #endif
319         
320         /* force an update of everything */
321         pm->requires_update = UPDATE_PULSE_ASLEEP | UPDATE_PULSE_AWAKE | UPDATE_PULSE_MODE | UPDATE_STATIC_BRIGHTNESS;
322         powermate_pulse_led(pm, 0x80, 255, 0, 1, 0); // set default pulse parameters
323   
324         return pm;
325 }
326
327 /* Called when a USB device we've accepted ownership of is removed */
328 static void powermate_disconnect(struct usb_device *dev, void *ptr)
329 {
330         struct powermate_device *pm = ptr;
331         down(&pm->lock);
332         pm->requires_update = 0;
333         usb_unlink_urb(&pm->irq);  
334         input_unregister_device(&pm->input);
335   
336         kfree(pm);
337 }
338
339 static struct usb_device_id powermate_devices [] = {
340         { USB_DEVICE(POWERMATE_VENDOR, POWERMATE_PRODUCT_NEW) },
341         { USB_DEVICE(POWERMATE_VENDOR, POWERMATE_PRODUCT_OLD) },
342         { } /* Terminating entry */
343 };
344
345 MODULE_DEVICE_TABLE (usb, powermate_devices);
346
347 static struct usb_driver powermate_driver = {
348         name:           "powermate",
349         probe:          powermate_probe,
350         disconnect:     powermate_disconnect,
351         id_table:       powermate_devices,
352 };
353
354 int powermate_init(void)
355 {
356         if (usb_register(&powermate_driver) < 0)
357                 return -1;
358         return 0;
359 }
360
361 void powermate_cleanup(void)
362 {
363         usb_deregister(&powermate_driver);
364 }
365
366 module_init(powermate_init);
367 module_exit(powermate_cleanup);
368
369 MODULE_AUTHOR( "William R Sowerbutts" );
370 MODULE_DESCRIPTION( "Griffin Technology, Inc PowerMate driver" );
371 MODULE_LICENSE("GPL");