1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-only
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * Driver for the VoIP USB phones with CM109 chipsets.
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Copyright (C) 2007 - 2008 Alfred E. Heggestad <aeh@db.org>
6*4882a593Smuzhiyun */
7*4882a593Smuzhiyun
8*4882a593Smuzhiyun /*
9*4882a593Smuzhiyun * Tested devices:
10*4882a593Smuzhiyun * - Komunikate KIP1000
11*4882a593Smuzhiyun * - Genius G-talk
12*4882a593Smuzhiyun * - Allied-Telesis Corega USBPH01
13*4882a593Smuzhiyun * - ...
14*4882a593Smuzhiyun *
15*4882a593Smuzhiyun * This driver is based on the yealink.c driver
16*4882a593Smuzhiyun *
17*4882a593Smuzhiyun * Thanks to:
18*4882a593Smuzhiyun * - Authors of yealink.c
19*4882a593Smuzhiyun * - Thomas Reitmayr
20*4882a593Smuzhiyun * - Oliver Neukum for good review comments and code
21*4882a593Smuzhiyun * - Shaun Jackman <sjackman@gmail.com> for Genius G-talk keymap
22*4882a593Smuzhiyun * - Dmitry Torokhov for valuable input and review
23*4882a593Smuzhiyun *
24*4882a593Smuzhiyun * Todo:
25*4882a593Smuzhiyun * - Read/write EEPROM
26*4882a593Smuzhiyun */
27*4882a593Smuzhiyun
28*4882a593Smuzhiyun #include <linux/kernel.h>
29*4882a593Smuzhiyun #include <linux/init.h>
30*4882a593Smuzhiyun #include <linux/slab.h>
31*4882a593Smuzhiyun #include <linux/module.h>
32*4882a593Smuzhiyun #include <linux/moduleparam.h>
33*4882a593Smuzhiyun #include <linux/rwsem.h>
34*4882a593Smuzhiyun #include <linux/usb/input.h>
35*4882a593Smuzhiyun
36*4882a593Smuzhiyun #define DRIVER_VERSION "20080805"
37*4882a593Smuzhiyun #define DRIVER_AUTHOR "Alfred E. Heggestad"
38*4882a593Smuzhiyun #define DRIVER_DESC "CM109 phone driver"
39*4882a593Smuzhiyun
40*4882a593Smuzhiyun static char *phone = "kip1000";
41*4882a593Smuzhiyun module_param(phone, charp, S_IRUSR);
42*4882a593Smuzhiyun MODULE_PARM_DESC(phone, "Phone name {kip1000, gtalk, usbph01, atcom}");
43*4882a593Smuzhiyun
44*4882a593Smuzhiyun enum {
45*4882a593Smuzhiyun /* HID Registers */
46*4882a593Smuzhiyun HID_IR0 = 0x00, /* Record/Playback-mute button, Volume up/down */
47*4882a593Smuzhiyun HID_IR1 = 0x01, /* GPI, generic registers or EEPROM_DATA0 */
48*4882a593Smuzhiyun HID_IR2 = 0x02, /* Generic registers or EEPROM_DATA1 */
49*4882a593Smuzhiyun HID_IR3 = 0x03, /* Generic registers or EEPROM_CTRL */
50*4882a593Smuzhiyun HID_OR0 = 0x00, /* Mapping control, buzzer, SPDIF (offset 0x04) */
51*4882a593Smuzhiyun HID_OR1 = 0x01, /* GPO - General Purpose Output */
52*4882a593Smuzhiyun HID_OR2 = 0x02, /* Set GPIO to input/output mode */
53*4882a593Smuzhiyun HID_OR3 = 0x03, /* SPDIF status channel or EEPROM_CTRL */
54*4882a593Smuzhiyun
55*4882a593Smuzhiyun /* HID_IR0 */
56*4882a593Smuzhiyun RECORD_MUTE = 1 << 3,
57*4882a593Smuzhiyun PLAYBACK_MUTE = 1 << 2,
58*4882a593Smuzhiyun VOLUME_DOWN = 1 << 1,
59*4882a593Smuzhiyun VOLUME_UP = 1 << 0,
60*4882a593Smuzhiyun
61*4882a593Smuzhiyun /* HID_OR0 */
62*4882a593Smuzhiyun /* bits 7-6
63*4882a593Smuzhiyun 0: HID_OR1-2 are used for GPO; HID_OR0, 3 are used for buzzer
64*4882a593Smuzhiyun and SPDIF
65*4882a593Smuzhiyun 1: HID_OR0-3 are used as generic HID registers
66*4882a593Smuzhiyun 2: Values written to HID_OR0-3 are also mapped to MCU_CTRL,
67*4882a593Smuzhiyun EEPROM_DATA0-1, EEPROM_CTRL (see Note)
68*4882a593Smuzhiyun 3: Reserved
69*4882a593Smuzhiyun */
70*4882a593Smuzhiyun HID_OR_GPO_BUZ_SPDIF = 0 << 6,
71*4882a593Smuzhiyun HID_OR_GENERIC_HID_REG = 1 << 6,
72*4882a593Smuzhiyun HID_OR_MAP_MCU_EEPROM = 2 << 6,
73*4882a593Smuzhiyun
74*4882a593Smuzhiyun BUZZER_ON = 1 << 5,
75*4882a593Smuzhiyun
76*4882a593Smuzhiyun /* up to 256 normal keys, up to 15 special key combinations */
77*4882a593Smuzhiyun KEYMAP_SIZE = 256 + 15,
78*4882a593Smuzhiyun };
79*4882a593Smuzhiyun
80*4882a593Smuzhiyun /* CM109 protocol packet */
81*4882a593Smuzhiyun struct cm109_ctl_packet {
82*4882a593Smuzhiyun u8 byte[4];
83*4882a593Smuzhiyun } __attribute__ ((packed));
84*4882a593Smuzhiyun
85*4882a593Smuzhiyun enum { USB_PKT_LEN = sizeof(struct cm109_ctl_packet) };
86*4882a593Smuzhiyun
87*4882a593Smuzhiyun /* CM109 device structure */
88*4882a593Smuzhiyun struct cm109_dev {
89*4882a593Smuzhiyun struct input_dev *idev; /* input device */
90*4882a593Smuzhiyun struct usb_device *udev; /* usb device */
91*4882a593Smuzhiyun struct usb_interface *intf;
92*4882a593Smuzhiyun
93*4882a593Smuzhiyun /* irq input channel */
94*4882a593Smuzhiyun struct cm109_ctl_packet *irq_data;
95*4882a593Smuzhiyun dma_addr_t irq_dma;
96*4882a593Smuzhiyun struct urb *urb_irq;
97*4882a593Smuzhiyun
98*4882a593Smuzhiyun /* control output channel */
99*4882a593Smuzhiyun struct cm109_ctl_packet *ctl_data;
100*4882a593Smuzhiyun dma_addr_t ctl_dma;
101*4882a593Smuzhiyun struct usb_ctrlrequest *ctl_req;
102*4882a593Smuzhiyun struct urb *urb_ctl;
103*4882a593Smuzhiyun /*
104*4882a593Smuzhiyun * The 3 bitfields below are protected by ctl_submit_lock.
105*4882a593Smuzhiyun * They have to be separate since they are accessed from IRQ
106*4882a593Smuzhiyun * context.
107*4882a593Smuzhiyun */
108*4882a593Smuzhiyun unsigned irq_urb_pending:1; /* irq_urb is in flight */
109*4882a593Smuzhiyun unsigned ctl_urb_pending:1; /* ctl_urb is in flight */
110*4882a593Smuzhiyun unsigned buzzer_pending:1; /* need to issue buzz command */
111*4882a593Smuzhiyun spinlock_t ctl_submit_lock;
112*4882a593Smuzhiyun
113*4882a593Smuzhiyun unsigned char buzzer_state; /* on/off */
114*4882a593Smuzhiyun
115*4882a593Smuzhiyun /* flags */
116*4882a593Smuzhiyun unsigned open:1;
117*4882a593Smuzhiyun unsigned resetting:1;
118*4882a593Smuzhiyun unsigned shutdown:1;
119*4882a593Smuzhiyun
120*4882a593Smuzhiyun /* This mutex protects writes to the above flags */
121*4882a593Smuzhiyun struct mutex pm_mutex;
122*4882a593Smuzhiyun
123*4882a593Smuzhiyun unsigned short keymap[KEYMAP_SIZE];
124*4882a593Smuzhiyun
125*4882a593Smuzhiyun char phys[64]; /* physical device path */
126*4882a593Smuzhiyun int key_code; /* last reported key */
127*4882a593Smuzhiyun int keybit; /* 0=new scan 1,2,4,8=scan columns */
128*4882a593Smuzhiyun u8 gpi; /* Cached value of GPI (high nibble) */
129*4882a593Smuzhiyun };
130*4882a593Smuzhiyun
131*4882a593Smuzhiyun /******************************************************************************
132*4882a593Smuzhiyun * CM109 key interface
133*4882a593Smuzhiyun *****************************************************************************/
134*4882a593Smuzhiyun
special_keymap(int code)135*4882a593Smuzhiyun static unsigned short special_keymap(int code)
136*4882a593Smuzhiyun {
137*4882a593Smuzhiyun if (code > 0xff) {
138*4882a593Smuzhiyun switch (code - 0xff) {
139*4882a593Smuzhiyun case RECORD_MUTE: return KEY_MICMUTE;
140*4882a593Smuzhiyun case PLAYBACK_MUTE: return KEY_MUTE;
141*4882a593Smuzhiyun case VOLUME_DOWN: return KEY_VOLUMEDOWN;
142*4882a593Smuzhiyun case VOLUME_UP: return KEY_VOLUMEUP;
143*4882a593Smuzhiyun }
144*4882a593Smuzhiyun }
145*4882a593Smuzhiyun return KEY_RESERVED;
146*4882a593Smuzhiyun }
147*4882a593Smuzhiyun
148*4882a593Smuzhiyun /* Map device buttons to internal key events.
149*4882a593Smuzhiyun *
150*4882a593Smuzhiyun * The "up" and "down" keys, are symbolised by arrows on the button.
151*4882a593Smuzhiyun * The "pickup" and "hangup" keys are symbolised by a green and red phone
152*4882a593Smuzhiyun * on the button.
153*4882a593Smuzhiyun
154*4882a593Smuzhiyun Komunikate KIP1000 Keyboard Matrix
155*4882a593Smuzhiyun
156*4882a593Smuzhiyun -> -- 1 -- 2 -- 3 --> GPI pin 4 (0x10)
157*4882a593Smuzhiyun | | | |
158*4882a593Smuzhiyun <- -- 4 -- 5 -- 6 --> GPI pin 5 (0x20)
159*4882a593Smuzhiyun | | | |
160*4882a593Smuzhiyun END - 7 -- 8 -- 9 --> GPI pin 6 (0x40)
161*4882a593Smuzhiyun | | | |
162*4882a593Smuzhiyun OK -- * -- 0 -- # --> GPI pin 7 (0x80)
163*4882a593Smuzhiyun | | | |
164*4882a593Smuzhiyun
165*4882a593Smuzhiyun /|\ /|\ /|\ /|\
166*4882a593Smuzhiyun | | | |
167*4882a593Smuzhiyun GPO
168*4882a593Smuzhiyun pin: 3 2 1 0
169*4882a593Smuzhiyun 0x8 0x4 0x2 0x1
170*4882a593Smuzhiyun
171*4882a593Smuzhiyun */
keymap_kip1000(int scancode)172*4882a593Smuzhiyun static unsigned short keymap_kip1000(int scancode)
173*4882a593Smuzhiyun {
174*4882a593Smuzhiyun switch (scancode) { /* phone key: */
175*4882a593Smuzhiyun case 0x82: return KEY_NUMERIC_0; /* 0 */
176*4882a593Smuzhiyun case 0x14: return KEY_NUMERIC_1; /* 1 */
177*4882a593Smuzhiyun case 0x12: return KEY_NUMERIC_2; /* 2 */
178*4882a593Smuzhiyun case 0x11: return KEY_NUMERIC_3; /* 3 */
179*4882a593Smuzhiyun case 0x24: return KEY_NUMERIC_4; /* 4 */
180*4882a593Smuzhiyun case 0x22: return KEY_NUMERIC_5; /* 5 */
181*4882a593Smuzhiyun case 0x21: return KEY_NUMERIC_6; /* 6 */
182*4882a593Smuzhiyun case 0x44: return KEY_NUMERIC_7; /* 7 */
183*4882a593Smuzhiyun case 0x42: return KEY_NUMERIC_8; /* 8 */
184*4882a593Smuzhiyun case 0x41: return KEY_NUMERIC_9; /* 9 */
185*4882a593Smuzhiyun case 0x81: return KEY_NUMERIC_POUND; /* # */
186*4882a593Smuzhiyun case 0x84: return KEY_NUMERIC_STAR; /* * */
187*4882a593Smuzhiyun case 0x88: return KEY_ENTER; /* pickup */
188*4882a593Smuzhiyun case 0x48: return KEY_ESC; /* hangup */
189*4882a593Smuzhiyun case 0x28: return KEY_LEFT; /* IN */
190*4882a593Smuzhiyun case 0x18: return KEY_RIGHT; /* OUT */
191*4882a593Smuzhiyun default: return special_keymap(scancode);
192*4882a593Smuzhiyun }
193*4882a593Smuzhiyun }
194*4882a593Smuzhiyun
195*4882a593Smuzhiyun /*
196*4882a593Smuzhiyun Contributed by Shaun Jackman <sjackman@gmail.com>
197*4882a593Smuzhiyun
198*4882a593Smuzhiyun Genius G-Talk keyboard matrix
199*4882a593Smuzhiyun 0 1 2 3
200*4882a593Smuzhiyun 4: 0 4 8 Talk
201*4882a593Smuzhiyun 5: 1 5 9 End
202*4882a593Smuzhiyun 6: 2 6 # Up
203*4882a593Smuzhiyun 7: 3 7 * Down
204*4882a593Smuzhiyun */
keymap_gtalk(int scancode)205*4882a593Smuzhiyun static unsigned short keymap_gtalk(int scancode)
206*4882a593Smuzhiyun {
207*4882a593Smuzhiyun switch (scancode) {
208*4882a593Smuzhiyun case 0x11: return KEY_NUMERIC_0;
209*4882a593Smuzhiyun case 0x21: return KEY_NUMERIC_1;
210*4882a593Smuzhiyun case 0x41: return KEY_NUMERIC_2;
211*4882a593Smuzhiyun case 0x81: return KEY_NUMERIC_3;
212*4882a593Smuzhiyun case 0x12: return KEY_NUMERIC_4;
213*4882a593Smuzhiyun case 0x22: return KEY_NUMERIC_5;
214*4882a593Smuzhiyun case 0x42: return KEY_NUMERIC_6;
215*4882a593Smuzhiyun case 0x82: return KEY_NUMERIC_7;
216*4882a593Smuzhiyun case 0x14: return KEY_NUMERIC_8;
217*4882a593Smuzhiyun case 0x24: return KEY_NUMERIC_9;
218*4882a593Smuzhiyun case 0x44: return KEY_NUMERIC_POUND; /* # */
219*4882a593Smuzhiyun case 0x84: return KEY_NUMERIC_STAR; /* * */
220*4882a593Smuzhiyun case 0x18: return KEY_ENTER; /* Talk (green handset) */
221*4882a593Smuzhiyun case 0x28: return KEY_ESC; /* End (red handset) */
222*4882a593Smuzhiyun case 0x48: return KEY_UP; /* Menu up (rocker switch) */
223*4882a593Smuzhiyun case 0x88: return KEY_DOWN; /* Menu down (rocker switch) */
224*4882a593Smuzhiyun default: return special_keymap(scancode);
225*4882a593Smuzhiyun }
226*4882a593Smuzhiyun }
227*4882a593Smuzhiyun
228*4882a593Smuzhiyun /*
229*4882a593Smuzhiyun * Keymap for Allied-Telesis Corega USBPH01
230*4882a593Smuzhiyun * http://www.alliedtelesis-corega.com/2/1344/1437/1360/chprd.html
231*4882a593Smuzhiyun *
232*4882a593Smuzhiyun * Contributed by july@nat.bg
233*4882a593Smuzhiyun */
keymap_usbph01(int scancode)234*4882a593Smuzhiyun static unsigned short keymap_usbph01(int scancode)
235*4882a593Smuzhiyun {
236*4882a593Smuzhiyun switch (scancode) {
237*4882a593Smuzhiyun case 0x11: return KEY_NUMERIC_0; /* 0 */
238*4882a593Smuzhiyun case 0x21: return KEY_NUMERIC_1; /* 1 */
239*4882a593Smuzhiyun case 0x41: return KEY_NUMERIC_2; /* 2 */
240*4882a593Smuzhiyun case 0x81: return KEY_NUMERIC_3; /* 3 */
241*4882a593Smuzhiyun case 0x12: return KEY_NUMERIC_4; /* 4 */
242*4882a593Smuzhiyun case 0x22: return KEY_NUMERIC_5; /* 5 */
243*4882a593Smuzhiyun case 0x42: return KEY_NUMERIC_6; /* 6 */
244*4882a593Smuzhiyun case 0x82: return KEY_NUMERIC_7; /* 7 */
245*4882a593Smuzhiyun case 0x14: return KEY_NUMERIC_8; /* 8 */
246*4882a593Smuzhiyun case 0x24: return KEY_NUMERIC_9; /* 9 */
247*4882a593Smuzhiyun case 0x44: return KEY_NUMERIC_POUND; /* # */
248*4882a593Smuzhiyun case 0x84: return KEY_NUMERIC_STAR; /* * */
249*4882a593Smuzhiyun case 0x18: return KEY_ENTER; /* pickup */
250*4882a593Smuzhiyun case 0x28: return KEY_ESC; /* hangup */
251*4882a593Smuzhiyun case 0x48: return KEY_LEFT; /* IN */
252*4882a593Smuzhiyun case 0x88: return KEY_RIGHT; /* OUT */
253*4882a593Smuzhiyun default: return special_keymap(scancode);
254*4882a593Smuzhiyun }
255*4882a593Smuzhiyun }
256*4882a593Smuzhiyun
257*4882a593Smuzhiyun /*
258*4882a593Smuzhiyun * Keymap for ATCom AU-100
259*4882a593Smuzhiyun * http://www.atcom.cn/products.html
260*4882a593Smuzhiyun * http://www.packetizer.com/products/au100/
261*4882a593Smuzhiyun * http://www.voip-info.org/wiki/view/AU-100
262*4882a593Smuzhiyun *
263*4882a593Smuzhiyun * Contributed by daniel@gimpelevich.san-francisco.ca.us
264*4882a593Smuzhiyun */
keymap_atcom(int scancode)265*4882a593Smuzhiyun static unsigned short keymap_atcom(int scancode)
266*4882a593Smuzhiyun {
267*4882a593Smuzhiyun switch (scancode) { /* phone key: */
268*4882a593Smuzhiyun case 0x82: return KEY_NUMERIC_0; /* 0 */
269*4882a593Smuzhiyun case 0x11: return KEY_NUMERIC_1; /* 1 */
270*4882a593Smuzhiyun case 0x12: return KEY_NUMERIC_2; /* 2 */
271*4882a593Smuzhiyun case 0x14: return KEY_NUMERIC_3; /* 3 */
272*4882a593Smuzhiyun case 0x21: return KEY_NUMERIC_4; /* 4 */
273*4882a593Smuzhiyun case 0x22: return KEY_NUMERIC_5; /* 5 */
274*4882a593Smuzhiyun case 0x24: return KEY_NUMERIC_6; /* 6 */
275*4882a593Smuzhiyun case 0x41: return KEY_NUMERIC_7; /* 7 */
276*4882a593Smuzhiyun case 0x42: return KEY_NUMERIC_8; /* 8 */
277*4882a593Smuzhiyun case 0x44: return KEY_NUMERIC_9; /* 9 */
278*4882a593Smuzhiyun case 0x84: return KEY_NUMERIC_POUND; /* # */
279*4882a593Smuzhiyun case 0x81: return KEY_NUMERIC_STAR; /* * */
280*4882a593Smuzhiyun case 0x18: return KEY_ENTER; /* pickup */
281*4882a593Smuzhiyun case 0x28: return KEY_ESC; /* hangup */
282*4882a593Smuzhiyun case 0x48: return KEY_LEFT; /* left arrow */
283*4882a593Smuzhiyun case 0x88: return KEY_RIGHT; /* right arrow */
284*4882a593Smuzhiyun default: return special_keymap(scancode);
285*4882a593Smuzhiyun }
286*4882a593Smuzhiyun }
287*4882a593Smuzhiyun
288*4882a593Smuzhiyun static unsigned short (*keymap)(int) = keymap_kip1000;
289*4882a593Smuzhiyun
290*4882a593Smuzhiyun /*
291*4882a593Smuzhiyun * Completes a request by converting the data into events for the
292*4882a593Smuzhiyun * input subsystem.
293*4882a593Smuzhiyun */
report_key(struct cm109_dev * dev,int key)294*4882a593Smuzhiyun static void report_key(struct cm109_dev *dev, int key)
295*4882a593Smuzhiyun {
296*4882a593Smuzhiyun struct input_dev *idev = dev->idev;
297*4882a593Smuzhiyun
298*4882a593Smuzhiyun if (dev->key_code >= 0) {
299*4882a593Smuzhiyun /* old key up */
300*4882a593Smuzhiyun input_report_key(idev, dev->key_code, 0);
301*4882a593Smuzhiyun }
302*4882a593Smuzhiyun
303*4882a593Smuzhiyun dev->key_code = key;
304*4882a593Smuzhiyun if (key >= 0) {
305*4882a593Smuzhiyun /* new valid key */
306*4882a593Smuzhiyun input_report_key(idev, key, 1);
307*4882a593Smuzhiyun }
308*4882a593Smuzhiyun
309*4882a593Smuzhiyun input_sync(idev);
310*4882a593Smuzhiyun }
311*4882a593Smuzhiyun
312*4882a593Smuzhiyun /*
313*4882a593Smuzhiyun * Converts data of special key presses (volume, mute) into events
314*4882a593Smuzhiyun * for the input subsystem, sends press-n-release for mute keys.
315*4882a593Smuzhiyun */
cm109_report_special(struct cm109_dev * dev)316*4882a593Smuzhiyun static void cm109_report_special(struct cm109_dev *dev)
317*4882a593Smuzhiyun {
318*4882a593Smuzhiyun static const u8 autorelease = RECORD_MUTE | PLAYBACK_MUTE;
319*4882a593Smuzhiyun struct input_dev *idev = dev->idev;
320*4882a593Smuzhiyun u8 data = dev->irq_data->byte[HID_IR0];
321*4882a593Smuzhiyun unsigned short keycode;
322*4882a593Smuzhiyun int i;
323*4882a593Smuzhiyun
324*4882a593Smuzhiyun for (i = 0; i < 4; i++) {
325*4882a593Smuzhiyun keycode = dev->keymap[0xff + BIT(i)];
326*4882a593Smuzhiyun if (keycode == KEY_RESERVED)
327*4882a593Smuzhiyun continue;
328*4882a593Smuzhiyun
329*4882a593Smuzhiyun input_report_key(idev, keycode, data & BIT(i));
330*4882a593Smuzhiyun if (data & autorelease & BIT(i)) {
331*4882a593Smuzhiyun input_sync(idev);
332*4882a593Smuzhiyun input_report_key(idev, keycode, 0);
333*4882a593Smuzhiyun }
334*4882a593Smuzhiyun }
335*4882a593Smuzhiyun input_sync(idev);
336*4882a593Smuzhiyun }
337*4882a593Smuzhiyun
338*4882a593Smuzhiyun /******************************************************************************
339*4882a593Smuzhiyun * CM109 usb communication interface
340*4882a593Smuzhiyun *****************************************************************************/
341*4882a593Smuzhiyun
cm109_submit_buzz_toggle(struct cm109_dev * dev)342*4882a593Smuzhiyun static void cm109_submit_buzz_toggle(struct cm109_dev *dev)
343*4882a593Smuzhiyun {
344*4882a593Smuzhiyun int error;
345*4882a593Smuzhiyun
346*4882a593Smuzhiyun if (dev->buzzer_state)
347*4882a593Smuzhiyun dev->ctl_data->byte[HID_OR0] |= BUZZER_ON;
348*4882a593Smuzhiyun else
349*4882a593Smuzhiyun dev->ctl_data->byte[HID_OR0] &= ~BUZZER_ON;
350*4882a593Smuzhiyun
351*4882a593Smuzhiyun error = usb_submit_urb(dev->urb_ctl, GFP_ATOMIC);
352*4882a593Smuzhiyun if (error)
353*4882a593Smuzhiyun dev_err(&dev->intf->dev,
354*4882a593Smuzhiyun "%s: usb_submit_urb (urb_ctl) failed %d\n",
355*4882a593Smuzhiyun __func__, error);
356*4882a593Smuzhiyun }
357*4882a593Smuzhiyun
358*4882a593Smuzhiyun /*
359*4882a593Smuzhiyun * IRQ handler
360*4882a593Smuzhiyun */
cm109_urb_irq_callback(struct urb * urb)361*4882a593Smuzhiyun static void cm109_urb_irq_callback(struct urb *urb)
362*4882a593Smuzhiyun {
363*4882a593Smuzhiyun struct cm109_dev *dev = urb->context;
364*4882a593Smuzhiyun const int status = urb->status;
365*4882a593Smuzhiyun int error;
366*4882a593Smuzhiyun unsigned long flags;
367*4882a593Smuzhiyun
368*4882a593Smuzhiyun dev_dbg(&dev->intf->dev, "### URB IRQ: [0x%02x 0x%02x 0x%02x 0x%02x] keybit=0x%02x\n",
369*4882a593Smuzhiyun dev->irq_data->byte[0],
370*4882a593Smuzhiyun dev->irq_data->byte[1],
371*4882a593Smuzhiyun dev->irq_data->byte[2],
372*4882a593Smuzhiyun dev->irq_data->byte[3],
373*4882a593Smuzhiyun dev->keybit);
374*4882a593Smuzhiyun
375*4882a593Smuzhiyun if (status) {
376*4882a593Smuzhiyun if (status == -ESHUTDOWN)
377*4882a593Smuzhiyun return;
378*4882a593Smuzhiyun dev_err_ratelimited(&dev->intf->dev, "%s: urb status %d\n",
379*4882a593Smuzhiyun __func__, status);
380*4882a593Smuzhiyun goto out;
381*4882a593Smuzhiyun }
382*4882a593Smuzhiyun
383*4882a593Smuzhiyun /* Special keys */
384*4882a593Smuzhiyun cm109_report_special(dev);
385*4882a593Smuzhiyun
386*4882a593Smuzhiyun /* Scan key column */
387*4882a593Smuzhiyun if (dev->keybit == 0xf) {
388*4882a593Smuzhiyun
389*4882a593Smuzhiyun /* Any changes ? */
390*4882a593Smuzhiyun if ((dev->gpi & 0xf0) == (dev->irq_data->byte[HID_IR1] & 0xf0))
391*4882a593Smuzhiyun goto out;
392*4882a593Smuzhiyun
393*4882a593Smuzhiyun dev->gpi = dev->irq_data->byte[HID_IR1] & 0xf0;
394*4882a593Smuzhiyun dev->keybit = 0x1;
395*4882a593Smuzhiyun } else {
396*4882a593Smuzhiyun report_key(dev, dev->keymap[dev->irq_data->byte[HID_IR1]]);
397*4882a593Smuzhiyun
398*4882a593Smuzhiyun dev->keybit <<= 1;
399*4882a593Smuzhiyun if (dev->keybit > 0x8)
400*4882a593Smuzhiyun dev->keybit = 0xf;
401*4882a593Smuzhiyun }
402*4882a593Smuzhiyun
403*4882a593Smuzhiyun out:
404*4882a593Smuzhiyun
405*4882a593Smuzhiyun spin_lock_irqsave(&dev->ctl_submit_lock, flags);
406*4882a593Smuzhiyun
407*4882a593Smuzhiyun dev->irq_urb_pending = 0;
408*4882a593Smuzhiyun
409*4882a593Smuzhiyun if (likely(!dev->shutdown)) {
410*4882a593Smuzhiyun
411*4882a593Smuzhiyun if (dev->buzzer_state)
412*4882a593Smuzhiyun dev->ctl_data->byte[HID_OR0] |= BUZZER_ON;
413*4882a593Smuzhiyun else
414*4882a593Smuzhiyun dev->ctl_data->byte[HID_OR0] &= ~BUZZER_ON;
415*4882a593Smuzhiyun
416*4882a593Smuzhiyun dev->ctl_data->byte[HID_OR1] = dev->keybit;
417*4882a593Smuzhiyun dev->ctl_data->byte[HID_OR2] = dev->keybit;
418*4882a593Smuzhiyun
419*4882a593Smuzhiyun dev->buzzer_pending = 0;
420*4882a593Smuzhiyun dev->ctl_urb_pending = 1;
421*4882a593Smuzhiyun
422*4882a593Smuzhiyun error = usb_submit_urb(dev->urb_ctl, GFP_ATOMIC);
423*4882a593Smuzhiyun if (error)
424*4882a593Smuzhiyun dev_err(&dev->intf->dev,
425*4882a593Smuzhiyun "%s: usb_submit_urb (urb_ctl) failed %d\n",
426*4882a593Smuzhiyun __func__, error);
427*4882a593Smuzhiyun }
428*4882a593Smuzhiyun
429*4882a593Smuzhiyun spin_unlock_irqrestore(&dev->ctl_submit_lock, flags);
430*4882a593Smuzhiyun }
431*4882a593Smuzhiyun
cm109_urb_ctl_callback(struct urb * urb)432*4882a593Smuzhiyun static void cm109_urb_ctl_callback(struct urb *urb)
433*4882a593Smuzhiyun {
434*4882a593Smuzhiyun struct cm109_dev *dev = urb->context;
435*4882a593Smuzhiyun const int status = urb->status;
436*4882a593Smuzhiyun int error;
437*4882a593Smuzhiyun unsigned long flags;
438*4882a593Smuzhiyun
439*4882a593Smuzhiyun dev_dbg(&dev->intf->dev, "### URB CTL: [0x%02x 0x%02x 0x%02x 0x%02x]\n",
440*4882a593Smuzhiyun dev->ctl_data->byte[0],
441*4882a593Smuzhiyun dev->ctl_data->byte[1],
442*4882a593Smuzhiyun dev->ctl_data->byte[2],
443*4882a593Smuzhiyun dev->ctl_data->byte[3]);
444*4882a593Smuzhiyun
445*4882a593Smuzhiyun if (status) {
446*4882a593Smuzhiyun if (status == -ESHUTDOWN)
447*4882a593Smuzhiyun return;
448*4882a593Smuzhiyun dev_err_ratelimited(&dev->intf->dev, "%s: urb status %d\n",
449*4882a593Smuzhiyun __func__, status);
450*4882a593Smuzhiyun }
451*4882a593Smuzhiyun
452*4882a593Smuzhiyun spin_lock_irqsave(&dev->ctl_submit_lock, flags);
453*4882a593Smuzhiyun
454*4882a593Smuzhiyun dev->ctl_urb_pending = 0;
455*4882a593Smuzhiyun
456*4882a593Smuzhiyun if (likely(!dev->shutdown)) {
457*4882a593Smuzhiyun
458*4882a593Smuzhiyun if (dev->buzzer_pending || status) {
459*4882a593Smuzhiyun dev->buzzer_pending = 0;
460*4882a593Smuzhiyun dev->ctl_urb_pending = 1;
461*4882a593Smuzhiyun cm109_submit_buzz_toggle(dev);
462*4882a593Smuzhiyun } else if (likely(!dev->irq_urb_pending)) {
463*4882a593Smuzhiyun /* ask for key data */
464*4882a593Smuzhiyun dev->irq_urb_pending = 1;
465*4882a593Smuzhiyun error = usb_submit_urb(dev->urb_irq, GFP_ATOMIC);
466*4882a593Smuzhiyun if (error)
467*4882a593Smuzhiyun dev_err(&dev->intf->dev,
468*4882a593Smuzhiyun "%s: usb_submit_urb (urb_irq) failed %d\n",
469*4882a593Smuzhiyun __func__, error);
470*4882a593Smuzhiyun }
471*4882a593Smuzhiyun }
472*4882a593Smuzhiyun
473*4882a593Smuzhiyun spin_unlock_irqrestore(&dev->ctl_submit_lock, flags);
474*4882a593Smuzhiyun }
475*4882a593Smuzhiyun
cm109_toggle_buzzer_async(struct cm109_dev * dev)476*4882a593Smuzhiyun static void cm109_toggle_buzzer_async(struct cm109_dev *dev)
477*4882a593Smuzhiyun {
478*4882a593Smuzhiyun unsigned long flags;
479*4882a593Smuzhiyun
480*4882a593Smuzhiyun spin_lock_irqsave(&dev->ctl_submit_lock, flags);
481*4882a593Smuzhiyun
482*4882a593Smuzhiyun if (dev->ctl_urb_pending) {
483*4882a593Smuzhiyun /* URB completion will resubmit */
484*4882a593Smuzhiyun dev->buzzer_pending = 1;
485*4882a593Smuzhiyun } else {
486*4882a593Smuzhiyun dev->ctl_urb_pending = 1;
487*4882a593Smuzhiyun cm109_submit_buzz_toggle(dev);
488*4882a593Smuzhiyun }
489*4882a593Smuzhiyun
490*4882a593Smuzhiyun spin_unlock_irqrestore(&dev->ctl_submit_lock, flags);
491*4882a593Smuzhiyun }
492*4882a593Smuzhiyun
cm109_toggle_buzzer_sync(struct cm109_dev * dev,int on)493*4882a593Smuzhiyun static void cm109_toggle_buzzer_sync(struct cm109_dev *dev, int on)
494*4882a593Smuzhiyun {
495*4882a593Smuzhiyun int error;
496*4882a593Smuzhiyun
497*4882a593Smuzhiyun if (on)
498*4882a593Smuzhiyun dev->ctl_data->byte[HID_OR0] |= BUZZER_ON;
499*4882a593Smuzhiyun else
500*4882a593Smuzhiyun dev->ctl_data->byte[HID_OR0] &= ~BUZZER_ON;
501*4882a593Smuzhiyun
502*4882a593Smuzhiyun error = usb_control_msg(dev->udev,
503*4882a593Smuzhiyun usb_sndctrlpipe(dev->udev, 0),
504*4882a593Smuzhiyun dev->ctl_req->bRequest,
505*4882a593Smuzhiyun dev->ctl_req->bRequestType,
506*4882a593Smuzhiyun le16_to_cpu(dev->ctl_req->wValue),
507*4882a593Smuzhiyun le16_to_cpu(dev->ctl_req->wIndex),
508*4882a593Smuzhiyun dev->ctl_data,
509*4882a593Smuzhiyun USB_PKT_LEN, USB_CTRL_SET_TIMEOUT);
510*4882a593Smuzhiyun if (error < 0 && error != -EINTR)
511*4882a593Smuzhiyun dev_err(&dev->intf->dev, "%s: usb_control_msg() failed %d\n",
512*4882a593Smuzhiyun __func__, error);
513*4882a593Smuzhiyun }
514*4882a593Smuzhiyun
cm109_stop_traffic(struct cm109_dev * dev)515*4882a593Smuzhiyun static void cm109_stop_traffic(struct cm109_dev *dev)
516*4882a593Smuzhiyun {
517*4882a593Smuzhiyun dev->shutdown = 1;
518*4882a593Smuzhiyun /*
519*4882a593Smuzhiyun * Make sure other CPUs see this
520*4882a593Smuzhiyun */
521*4882a593Smuzhiyun smp_wmb();
522*4882a593Smuzhiyun
523*4882a593Smuzhiyun usb_kill_urb(dev->urb_ctl);
524*4882a593Smuzhiyun usb_kill_urb(dev->urb_irq);
525*4882a593Smuzhiyun
526*4882a593Smuzhiyun cm109_toggle_buzzer_sync(dev, 0);
527*4882a593Smuzhiyun
528*4882a593Smuzhiyun dev->shutdown = 0;
529*4882a593Smuzhiyun smp_wmb();
530*4882a593Smuzhiyun }
531*4882a593Smuzhiyun
cm109_restore_state(struct cm109_dev * dev)532*4882a593Smuzhiyun static void cm109_restore_state(struct cm109_dev *dev)
533*4882a593Smuzhiyun {
534*4882a593Smuzhiyun if (dev->open) {
535*4882a593Smuzhiyun /*
536*4882a593Smuzhiyun * Restore buzzer state.
537*4882a593Smuzhiyun * This will also kick regular URB submission
538*4882a593Smuzhiyun */
539*4882a593Smuzhiyun cm109_toggle_buzzer_async(dev);
540*4882a593Smuzhiyun }
541*4882a593Smuzhiyun }
542*4882a593Smuzhiyun
543*4882a593Smuzhiyun /******************************************************************************
544*4882a593Smuzhiyun * input event interface
545*4882a593Smuzhiyun *****************************************************************************/
546*4882a593Smuzhiyun
cm109_input_open(struct input_dev * idev)547*4882a593Smuzhiyun static int cm109_input_open(struct input_dev *idev)
548*4882a593Smuzhiyun {
549*4882a593Smuzhiyun struct cm109_dev *dev = input_get_drvdata(idev);
550*4882a593Smuzhiyun int error;
551*4882a593Smuzhiyun
552*4882a593Smuzhiyun error = usb_autopm_get_interface(dev->intf);
553*4882a593Smuzhiyun if (error < 0) {
554*4882a593Smuzhiyun dev_err(&idev->dev, "%s - cannot autoresume, result %d\n",
555*4882a593Smuzhiyun __func__, error);
556*4882a593Smuzhiyun return error;
557*4882a593Smuzhiyun }
558*4882a593Smuzhiyun
559*4882a593Smuzhiyun mutex_lock(&dev->pm_mutex);
560*4882a593Smuzhiyun
561*4882a593Smuzhiyun dev->buzzer_state = 0;
562*4882a593Smuzhiyun dev->key_code = -1; /* no keys pressed */
563*4882a593Smuzhiyun dev->keybit = 0xf;
564*4882a593Smuzhiyun
565*4882a593Smuzhiyun /* issue INIT */
566*4882a593Smuzhiyun dev->ctl_data->byte[HID_OR0] = HID_OR_GPO_BUZ_SPDIF;
567*4882a593Smuzhiyun dev->ctl_data->byte[HID_OR1] = dev->keybit;
568*4882a593Smuzhiyun dev->ctl_data->byte[HID_OR2] = dev->keybit;
569*4882a593Smuzhiyun dev->ctl_data->byte[HID_OR3] = 0x00;
570*4882a593Smuzhiyun
571*4882a593Smuzhiyun dev->ctl_urb_pending = 1;
572*4882a593Smuzhiyun error = usb_submit_urb(dev->urb_ctl, GFP_KERNEL);
573*4882a593Smuzhiyun if (error) {
574*4882a593Smuzhiyun dev->ctl_urb_pending = 0;
575*4882a593Smuzhiyun dev_err(&dev->intf->dev, "%s: usb_submit_urb (urb_ctl) failed %d\n",
576*4882a593Smuzhiyun __func__, error);
577*4882a593Smuzhiyun } else {
578*4882a593Smuzhiyun dev->open = 1;
579*4882a593Smuzhiyun }
580*4882a593Smuzhiyun
581*4882a593Smuzhiyun mutex_unlock(&dev->pm_mutex);
582*4882a593Smuzhiyun
583*4882a593Smuzhiyun if (error)
584*4882a593Smuzhiyun usb_autopm_put_interface(dev->intf);
585*4882a593Smuzhiyun
586*4882a593Smuzhiyun return error;
587*4882a593Smuzhiyun }
588*4882a593Smuzhiyun
cm109_input_close(struct input_dev * idev)589*4882a593Smuzhiyun static void cm109_input_close(struct input_dev *idev)
590*4882a593Smuzhiyun {
591*4882a593Smuzhiyun struct cm109_dev *dev = input_get_drvdata(idev);
592*4882a593Smuzhiyun
593*4882a593Smuzhiyun mutex_lock(&dev->pm_mutex);
594*4882a593Smuzhiyun
595*4882a593Smuzhiyun /*
596*4882a593Smuzhiyun * Once we are here event delivery is stopped so we
597*4882a593Smuzhiyun * don't need to worry about someone starting buzzer
598*4882a593Smuzhiyun * again
599*4882a593Smuzhiyun */
600*4882a593Smuzhiyun cm109_stop_traffic(dev);
601*4882a593Smuzhiyun dev->open = 0;
602*4882a593Smuzhiyun
603*4882a593Smuzhiyun mutex_unlock(&dev->pm_mutex);
604*4882a593Smuzhiyun
605*4882a593Smuzhiyun usb_autopm_put_interface(dev->intf);
606*4882a593Smuzhiyun }
607*4882a593Smuzhiyun
cm109_input_ev(struct input_dev * idev,unsigned int type,unsigned int code,int value)608*4882a593Smuzhiyun static int cm109_input_ev(struct input_dev *idev, unsigned int type,
609*4882a593Smuzhiyun unsigned int code, int value)
610*4882a593Smuzhiyun {
611*4882a593Smuzhiyun struct cm109_dev *dev = input_get_drvdata(idev);
612*4882a593Smuzhiyun
613*4882a593Smuzhiyun dev_dbg(&dev->intf->dev,
614*4882a593Smuzhiyun "input_ev: type=%u code=%u value=%d\n", type, code, value);
615*4882a593Smuzhiyun
616*4882a593Smuzhiyun if (type != EV_SND)
617*4882a593Smuzhiyun return -EINVAL;
618*4882a593Smuzhiyun
619*4882a593Smuzhiyun switch (code) {
620*4882a593Smuzhiyun case SND_TONE:
621*4882a593Smuzhiyun case SND_BELL:
622*4882a593Smuzhiyun dev->buzzer_state = !!value;
623*4882a593Smuzhiyun if (!dev->resetting)
624*4882a593Smuzhiyun cm109_toggle_buzzer_async(dev);
625*4882a593Smuzhiyun return 0;
626*4882a593Smuzhiyun
627*4882a593Smuzhiyun default:
628*4882a593Smuzhiyun return -EINVAL;
629*4882a593Smuzhiyun }
630*4882a593Smuzhiyun }
631*4882a593Smuzhiyun
632*4882a593Smuzhiyun
633*4882a593Smuzhiyun /******************************************************************************
634*4882a593Smuzhiyun * Linux interface and usb initialisation
635*4882a593Smuzhiyun *****************************************************************************/
636*4882a593Smuzhiyun
637*4882a593Smuzhiyun struct driver_info {
638*4882a593Smuzhiyun char *name;
639*4882a593Smuzhiyun };
640*4882a593Smuzhiyun
641*4882a593Smuzhiyun static const struct driver_info info_cm109 = {
642*4882a593Smuzhiyun .name = "CM109 USB driver",
643*4882a593Smuzhiyun };
644*4882a593Smuzhiyun
645*4882a593Smuzhiyun enum {
646*4882a593Smuzhiyun VENDOR_ID = 0x0d8c, /* C-Media Electronics */
647*4882a593Smuzhiyun PRODUCT_ID_CM109 = 0x000e, /* CM109 defines range 0x0008 - 0x000f */
648*4882a593Smuzhiyun };
649*4882a593Smuzhiyun
650*4882a593Smuzhiyun /* table of devices that work with this driver */
651*4882a593Smuzhiyun static const struct usb_device_id cm109_usb_table[] = {
652*4882a593Smuzhiyun {
653*4882a593Smuzhiyun .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
654*4882a593Smuzhiyun USB_DEVICE_ID_MATCH_INT_INFO,
655*4882a593Smuzhiyun .idVendor = VENDOR_ID,
656*4882a593Smuzhiyun .idProduct = PRODUCT_ID_CM109,
657*4882a593Smuzhiyun .bInterfaceClass = USB_CLASS_HID,
658*4882a593Smuzhiyun .bInterfaceSubClass = 0,
659*4882a593Smuzhiyun .bInterfaceProtocol = 0,
660*4882a593Smuzhiyun .driver_info = (kernel_ulong_t) &info_cm109
661*4882a593Smuzhiyun },
662*4882a593Smuzhiyun /* you can add more devices here with product ID 0x0008 - 0x000f */
663*4882a593Smuzhiyun { }
664*4882a593Smuzhiyun };
665*4882a593Smuzhiyun
cm109_usb_cleanup(struct cm109_dev * dev)666*4882a593Smuzhiyun static void cm109_usb_cleanup(struct cm109_dev *dev)
667*4882a593Smuzhiyun {
668*4882a593Smuzhiyun kfree(dev->ctl_req);
669*4882a593Smuzhiyun usb_free_coherent(dev->udev, USB_PKT_LEN, dev->ctl_data, dev->ctl_dma);
670*4882a593Smuzhiyun usb_free_coherent(dev->udev, USB_PKT_LEN, dev->irq_data, dev->irq_dma);
671*4882a593Smuzhiyun
672*4882a593Smuzhiyun usb_free_urb(dev->urb_irq); /* parameter validation in core/urb */
673*4882a593Smuzhiyun usb_free_urb(dev->urb_ctl); /* parameter validation in core/urb */
674*4882a593Smuzhiyun kfree(dev);
675*4882a593Smuzhiyun }
676*4882a593Smuzhiyun
cm109_usb_disconnect(struct usb_interface * interface)677*4882a593Smuzhiyun static void cm109_usb_disconnect(struct usb_interface *interface)
678*4882a593Smuzhiyun {
679*4882a593Smuzhiyun struct cm109_dev *dev = usb_get_intfdata(interface);
680*4882a593Smuzhiyun
681*4882a593Smuzhiyun usb_set_intfdata(interface, NULL);
682*4882a593Smuzhiyun input_unregister_device(dev->idev);
683*4882a593Smuzhiyun cm109_usb_cleanup(dev);
684*4882a593Smuzhiyun }
685*4882a593Smuzhiyun
cm109_usb_probe(struct usb_interface * intf,const struct usb_device_id * id)686*4882a593Smuzhiyun static int cm109_usb_probe(struct usb_interface *intf,
687*4882a593Smuzhiyun const struct usb_device_id *id)
688*4882a593Smuzhiyun {
689*4882a593Smuzhiyun struct usb_device *udev = interface_to_usbdev(intf);
690*4882a593Smuzhiyun struct driver_info *nfo = (struct driver_info *)id->driver_info;
691*4882a593Smuzhiyun struct usb_host_interface *interface;
692*4882a593Smuzhiyun struct usb_endpoint_descriptor *endpoint;
693*4882a593Smuzhiyun struct cm109_dev *dev;
694*4882a593Smuzhiyun struct input_dev *input_dev = NULL;
695*4882a593Smuzhiyun int ret, pipe, i;
696*4882a593Smuzhiyun int error = -ENOMEM;
697*4882a593Smuzhiyun
698*4882a593Smuzhiyun interface = intf->cur_altsetting;
699*4882a593Smuzhiyun
700*4882a593Smuzhiyun if (interface->desc.bNumEndpoints < 1)
701*4882a593Smuzhiyun return -ENODEV;
702*4882a593Smuzhiyun
703*4882a593Smuzhiyun endpoint = &interface->endpoint[0].desc;
704*4882a593Smuzhiyun
705*4882a593Smuzhiyun if (!usb_endpoint_is_int_in(endpoint))
706*4882a593Smuzhiyun return -ENODEV;
707*4882a593Smuzhiyun
708*4882a593Smuzhiyun dev = kzalloc(sizeof(*dev), GFP_KERNEL);
709*4882a593Smuzhiyun if (!dev)
710*4882a593Smuzhiyun return -ENOMEM;
711*4882a593Smuzhiyun
712*4882a593Smuzhiyun spin_lock_init(&dev->ctl_submit_lock);
713*4882a593Smuzhiyun mutex_init(&dev->pm_mutex);
714*4882a593Smuzhiyun
715*4882a593Smuzhiyun dev->udev = udev;
716*4882a593Smuzhiyun dev->intf = intf;
717*4882a593Smuzhiyun
718*4882a593Smuzhiyun dev->idev = input_dev = input_allocate_device();
719*4882a593Smuzhiyun if (!input_dev)
720*4882a593Smuzhiyun goto err_out;
721*4882a593Smuzhiyun
722*4882a593Smuzhiyun /* allocate usb buffers */
723*4882a593Smuzhiyun dev->irq_data = usb_alloc_coherent(udev, USB_PKT_LEN,
724*4882a593Smuzhiyun GFP_KERNEL, &dev->irq_dma);
725*4882a593Smuzhiyun if (!dev->irq_data)
726*4882a593Smuzhiyun goto err_out;
727*4882a593Smuzhiyun
728*4882a593Smuzhiyun dev->ctl_data = usb_alloc_coherent(udev, USB_PKT_LEN,
729*4882a593Smuzhiyun GFP_KERNEL, &dev->ctl_dma);
730*4882a593Smuzhiyun if (!dev->ctl_data)
731*4882a593Smuzhiyun goto err_out;
732*4882a593Smuzhiyun
733*4882a593Smuzhiyun dev->ctl_req = kmalloc(sizeof(*(dev->ctl_req)), GFP_KERNEL);
734*4882a593Smuzhiyun if (!dev->ctl_req)
735*4882a593Smuzhiyun goto err_out;
736*4882a593Smuzhiyun
737*4882a593Smuzhiyun /* allocate urb structures */
738*4882a593Smuzhiyun dev->urb_irq = usb_alloc_urb(0, GFP_KERNEL);
739*4882a593Smuzhiyun if (!dev->urb_irq)
740*4882a593Smuzhiyun goto err_out;
741*4882a593Smuzhiyun
742*4882a593Smuzhiyun dev->urb_ctl = usb_alloc_urb(0, GFP_KERNEL);
743*4882a593Smuzhiyun if (!dev->urb_ctl)
744*4882a593Smuzhiyun goto err_out;
745*4882a593Smuzhiyun
746*4882a593Smuzhiyun /* get a handle to the interrupt data pipe */
747*4882a593Smuzhiyun pipe = usb_rcvintpipe(udev, endpoint->bEndpointAddress);
748*4882a593Smuzhiyun ret = usb_maxpacket(udev, pipe, usb_pipeout(pipe));
749*4882a593Smuzhiyun if (ret != USB_PKT_LEN)
750*4882a593Smuzhiyun dev_err(&intf->dev, "invalid payload size %d, expected %d\n",
751*4882a593Smuzhiyun ret, USB_PKT_LEN);
752*4882a593Smuzhiyun
753*4882a593Smuzhiyun /* initialise irq urb */
754*4882a593Smuzhiyun usb_fill_int_urb(dev->urb_irq, udev, pipe, dev->irq_data,
755*4882a593Smuzhiyun USB_PKT_LEN,
756*4882a593Smuzhiyun cm109_urb_irq_callback, dev, endpoint->bInterval);
757*4882a593Smuzhiyun dev->urb_irq->transfer_dma = dev->irq_dma;
758*4882a593Smuzhiyun dev->urb_irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
759*4882a593Smuzhiyun dev->urb_irq->dev = udev;
760*4882a593Smuzhiyun
761*4882a593Smuzhiyun /* initialise ctl urb */
762*4882a593Smuzhiyun dev->ctl_req->bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE |
763*4882a593Smuzhiyun USB_DIR_OUT;
764*4882a593Smuzhiyun dev->ctl_req->bRequest = USB_REQ_SET_CONFIGURATION;
765*4882a593Smuzhiyun dev->ctl_req->wValue = cpu_to_le16(0x200);
766*4882a593Smuzhiyun dev->ctl_req->wIndex = cpu_to_le16(interface->desc.bInterfaceNumber);
767*4882a593Smuzhiyun dev->ctl_req->wLength = cpu_to_le16(USB_PKT_LEN);
768*4882a593Smuzhiyun
769*4882a593Smuzhiyun usb_fill_control_urb(dev->urb_ctl, udev, usb_sndctrlpipe(udev, 0),
770*4882a593Smuzhiyun (void *)dev->ctl_req, dev->ctl_data, USB_PKT_LEN,
771*4882a593Smuzhiyun cm109_urb_ctl_callback, dev);
772*4882a593Smuzhiyun dev->urb_ctl->transfer_dma = dev->ctl_dma;
773*4882a593Smuzhiyun dev->urb_ctl->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
774*4882a593Smuzhiyun dev->urb_ctl->dev = udev;
775*4882a593Smuzhiyun
776*4882a593Smuzhiyun /* find out the physical bus location */
777*4882a593Smuzhiyun usb_make_path(udev, dev->phys, sizeof(dev->phys));
778*4882a593Smuzhiyun strlcat(dev->phys, "/input0", sizeof(dev->phys));
779*4882a593Smuzhiyun
780*4882a593Smuzhiyun /* register settings for the input device */
781*4882a593Smuzhiyun input_dev->name = nfo->name;
782*4882a593Smuzhiyun input_dev->phys = dev->phys;
783*4882a593Smuzhiyun usb_to_input_id(udev, &input_dev->id);
784*4882a593Smuzhiyun input_dev->dev.parent = &intf->dev;
785*4882a593Smuzhiyun
786*4882a593Smuzhiyun input_set_drvdata(input_dev, dev);
787*4882a593Smuzhiyun input_dev->open = cm109_input_open;
788*4882a593Smuzhiyun input_dev->close = cm109_input_close;
789*4882a593Smuzhiyun input_dev->event = cm109_input_ev;
790*4882a593Smuzhiyun
791*4882a593Smuzhiyun input_dev->keycode = dev->keymap;
792*4882a593Smuzhiyun input_dev->keycodesize = sizeof(unsigned char);
793*4882a593Smuzhiyun input_dev->keycodemax = ARRAY_SIZE(dev->keymap);
794*4882a593Smuzhiyun
795*4882a593Smuzhiyun input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_SND);
796*4882a593Smuzhiyun input_dev->sndbit[0] = BIT_MASK(SND_BELL) | BIT_MASK(SND_TONE);
797*4882a593Smuzhiyun
798*4882a593Smuzhiyun /* register available key events */
799*4882a593Smuzhiyun for (i = 0; i < KEYMAP_SIZE; i++) {
800*4882a593Smuzhiyun unsigned short k = keymap(i);
801*4882a593Smuzhiyun dev->keymap[i] = k;
802*4882a593Smuzhiyun __set_bit(k, input_dev->keybit);
803*4882a593Smuzhiyun }
804*4882a593Smuzhiyun __clear_bit(KEY_RESERVED, input_dev->keybit);
805*4882a593Smuzhiyun
806*4882a593Smuzhiyun error = input_register_device(dev->idev);
807*4882a593Smuzhiyun if (error)
808*4882a593Smuzhiyun goto err_out;
809*4882a593Smuzhiyun
810*4882a593Smuzhiyun usb_set_intfdata(intf, dev);
811*4882a593Smuzhiyun
812*4882a593Smuzhiyun return 0;
813*4882a593Smuzhiyun
814*4882a593Smuzhiyun err_out:
815*4882a593Smuzhiyun input_free_device(input_dev);
816*4882a593Smuzhiyun cm109_usb_cleanup(dev);
817*4882a593Smuzhiyun return error;
818*4882a593Smuzhiyun }
819*4882a593Smuzhiyun
cm109_usb_suspend(struct usb_interface * intf,pm_message_t message)820*4882a593Smuzhiyun static int cm109_usb_suspend(struct usb_interface *intf, pm_message_t message)
821*4882a593Smuzhiyun {
822*4882a593Smuzhiyun struct cm109_dev *dev = usb_get_intfdata(intf);
823*4882a593Smuzhiyun
824*4882a593Smuzhiyun dev_info(&intf->dev, "cm109: usb_suspend (event=%d)\n", message.event);
825*4882a593Smuzhiyun
826*4882a593Smuzhiyun mutex_lock(&dev->pm_mutex);
827*4882a593Smuzhiyun cm109_stop_traffic(dev);
828*4882a593Smuzhiyun mutex_unlock(&dev->pm_mutex);
829*4882a593Smuzhiyun
830*4882a593Smuzhiyun return 0;
831*4882a593Smuzhiyun }
832*4882a593Smuzhiyun
cm109_usb_resume(struct usb_interface * intf)833*4882a593Smuzhiyun static int cm109_usb_resume(struct usb_interface *intf)
834*4882a593Smuzhiyun {
835*4882a593Smuzhiyun struct cm109_dev *dev = usb_get_intfdata(intf);
836*4882a593Smuzhiyun
837*4882a593Smuzhiyun dev_info(&intf->dev, "cm109: usb_resume\n");
838*4882a593Smuzhiyun
839*4882a593Smuzhiyun mutex_lock(&dev->pm_mutex);
840*4882a593Smuzhiyun cm109_restore_state(dev);
841*4882a593Smuzhiyun mutex_unlock(&dev->pm_mutex);
842*4882a593Smuzhiyun
843*4882a593Smuzhiyun return 0;
844*4882a593Smuzhiyun }
845*4882a593Smuzhiyun
cm109_usb_pre_reset(struct usb_interface * intf)846*4882a593Smuzhiyun static int cm109_usb_pre_reset(struct usb_interface *intf)
847*4882a593Smuzhiyun {
848*4882a593Smuzhiyun struct cm109_dev *dev = usb_get_intfdata(intf);
849*4882a593Smuzhiyun
850*4882a593Smuzhiyun mutex_lock(&dev->pm_mutex);
851*4882a593Smuzhiyun
852*4882a593Smuzhiyun /*
853*4882a593Smuzhiyun * Make sure input events don't try to toggle buzzer
854*4882a593Smuzhiyun * while we are resetting
855*4882a593Smuzhiyun */
856*4882a593Smuzhiyun dev->resetting = 1;
857*4882a593Smuzhiyun smp_wmb();
858*4882a593Smuzhiyun
859*4882a593Smuzhiyun cm109_stop_traffic(dev);
860*4882a593Smuzhiyun
861*4882a593Smuzhiyun return 0;
862*4882a593Smuzhiyun }
863*4882a593Smuzhiyun
cm109_usb_post_reset(struct usb_interface * intf)864*4882a593Smuzhiyun static int cm109_usb_post_reset(struct usb_interface *intf)
865*4882a593Smuzhiyun {
866*4882a593Smuzhiyun struct cm109_dev *dev = usb_get_intfdata(intf);
867*4882a593Smuzhiyun
868*4882a593Smuzhiyun dev->resetting = 0;
869*4882a593Smuzhiyun smp_wmb();
870*4882a593Smuzhiyun
871*4882a593Smuzhiyun cm109_restore_state(dev);
872*4882a593Smuzhiyun
873*4882a593Smuzhiyun mutex_unlock(&dev->pm_mutex);
874*4882a593Smuzhiyun
875*4882a593Smuzhiyun return 0;
876*4882a593Smuzhiyun }
877*4882a593Smuzhiyun
878*4882a593Smuzhiyun static struct usb_driver cm109_driver = {
879*4882a593Smuzhiyun .name = "cm109",
880*4882a593Smuzhiyun .probe = cm109_usb_probe,
881*4882a593Smuzhiyun .disconnect = cm109_usb_disconnect,
882*4882a593Smuzhiyun .suspend = cm109_usb_suspend,
883*4882a593Smuzhiyun .resume = cm109_usb_resume,
884*4882a593Smuzhiyun .reset_resume = cm109_usb_resume,
885*4882a593Smuzhiyun .pre_reset = cm109_usb_pre_reset,
886*4882a593Smuzhiyun .post_reset = cm109_usb_post_reset,
887*4882a593Smuzhiyun .id_table = cm109_usb_table,
888*4882a593Smuzhiyun .supports_autosuspend = 1,
889*4882a593Smuzhiyun };
890*4882a593Smuzhiyun
cm109_select_keymap(void)891*4882a593Smuzhiyun static int __init cm109_select_keymap(void)
892*4882a593Smuzhiyun {
893*4882a593Smuzhiyun /* Load the phone keymap */
894*4882a593Smuzhiyun if (!strcasecmp(phone, "kip1000")) {
895*4882a593Smuzhiyun keymap = keymap_kip1000;
896*4882a593Smuzhiyun printk(KERN_INFO KBUILD_MODNAME ": "
897*4882a593Smuzhiyun "Keymap for Komunikate KIP1000 phone loaded\n");
898*4882a593Smuzhiyun } else if (!strcasecmp(phone, "gtalk")) {
899*4882a593Smuzhiyun keymap = keymap_gtalk;
900*4882a593Smuzhiyun printk(KERN_INFO KBUILD_MODNAME ": "
901*4882a593Smuzhiyun "Keymap for Genius G-talk phone loaded\n");
902*4882a593Smuzhiyun } else if (!strcasecmp(phone, "usbph01")) {
903*4882a593Smuzhiyun keymap = keymap_usbph01;
904*4882a593Smuzhiyun printk(KERN_INFO KBUILD_MODNAME ": "
905*4882a593Smuzhiyun "Keymap for Allied-Telesis Corega USBPH01 phone loaded\n");
906*4882a593Smuzhiyun } else if (!strcasecmp(phone, "atcom")) {
907*4882a593Smuzhiyun keymap = keymap_atcom;
908*4882a593Smuzhiyun printk(KERN_INFO KBUILD_MODNAME ": "
909*4882a593Smuzhiyun "Keymap for ATCom AU-100 phone loaded\n");
910*4882a593Smuzhiyun } else {
911*4882a593Smuzhiyun printk(KERN_ERR KBUILD_MODNAME ": "
912*4882a593Smuzhiyun "Unsupported phone: %s\n", phone);
913*4882a593Smuzhiyun return -EINVAL;
914*4882a593Smuzhiyun }
915*4882a593Smuzhiyun
916*4882a593Smuzhiyun return 0;
917*4882a593Smuzhiyun }
918*4882a593Smuzhiyun
cm109_init(void)919*4882a593Smuzhiyun static int __init cm109_init(void)
920*4882a593Smuzhiyun {
921*4882a593Smuzhiyun int err;
922*4882a593Smuzhiyun
923*4882a593Smuzhiyun err = cm109_select_keymap();
924*4882a593Smuzhiyun if (err)
925*4882a593Smuzhiyun return err;
926*4882a593Smuzhiyun
927*4882a593Smuzhiyun err = usb_register(&cm109_driver);
928*4882a593Smuzhiyun if (err)
929*4882a593Smuzhiyun return err;
930*4882a593Smuzhiyun
931*4882a593Smuzhiyun printk(KERN_INFO KBUILD_MODNAME ": "
932*4882a593Smuzhiyun DRIVER_DESC ": " DRIVER_VERSION " (C) " DRIVER_AUTHOR "\n");
933*4882a593Smuzhiyun
934*4882a593Smuzhiyun return 0;
935*4882a593Smuzhiyun }
936*4882a593Smuzhiyun
cm109_exit(void)937*4882a593Smuzhiyun static void __exit cm109_exit(void)
938*4882a593Smuzhiyun {
939*4882a593Smuzhiyun usb_deregister(&cm109_driver);
940*4882a593Smuzhiyun }
941*4882a593Smuzhiyun
942*4882a593Smuzhiyun module_init(cm109_init);
943*4882a593Smuzhiyun module_exit(cm109_exit);
944*4882a593Smuzhiyun
945*4882a593Smuzhiyun MODULE_DEVICE_TABLE(usb, cm109_usb_table);
946*4882a593Smuzhiyun
947*4882a593Smuzhiyun MODULE_AUTHOR(DRIVER_AUTHOR);
948*4882a593Smuzhiyun MODULE_DESCRIPTION(DRIVER_DESC);
949*4882a593Smuzhiyun MODULE_LICENSE("GPL");
950