source: src/linux/universal/linux-3.18/drivers/input/misc/yealink.c @ 31885

Last change on this file since 31885 was 31885, checked in by brainslayer, 3 months ago

update

File size: 25.0 KB
Line 
1/*
2 * drivers/usb/input/yealink.c
3 *
4 * Copyright (c) 2005 Henk Vergonet <Henk.Vergonet@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of
9 * the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20/*
21 * Description:
22 *   Driver for the USB-P1K voip usb phone.
23 *   This device is produced by Yealink Network Technology Co Ltd
24 *   but may be branded under several names:
25 *      - Yealink usb-p1k
26 *      - Tiptel 115
27 *      - ...
28 *
29 * This driver is based on:
30 *   - the usbb2k-api   http://savannah.nongnu.org/projects/usbb2k-api/
31 *   - information from http://memeteau.free.fr/usbb2k
32 *   - the xpad-driver  drivers/input/joystick/xpad.c
33 *
34 * Thanks to:
35 *   - Olivier Vandorpe, for providing the usbb2k-api.
36 *   - Martin Diehl, for spotting my memory allocation bug.
37 *
38 * History:
39 *   20050527 henk      First version, functional keyboard. Keyboard events
40 *                      will pop-up on the ../input/eventX bus.
41 *   20050531 henk      Added led, LCD, dialtone and sysfs interface.
42 *   20050610 henk      Cleanups, make it ready for public consumption.
43 *   20050630 henk      Cleanups, fixes in response to comments.
44 *   20050701 henk      sysfs write serialisation, fix potential unload races
45 *   20050801 henk      Added ringtone, restructure USB
46 *   20050816 henk      Merge 2.6.13-rc6
47 */
48
49#include <linux/kernel.h>
50#include <linux/slab.h>
51#include <linux/module.h>
52#include <linux/rwsem.h>
53#include <linux/usb/input.h>
54#include <linux/map_to_7segment.h>
55
56#include "yealink.h"
57
58#define DRIVER_VERSION "yld-20051230"
59#define DRIVER_AUTHOR "Henk Vergonet"
60#define DRIVER_DESC "Yealink phone driver"
61
62#define YEALINK_POLLING_FREQUENCY       10      /* in [Hz] */
63
64struct yld_status {
65        u8      lcd[24];
66        u8      led;
67        u8      dialtone;
68        u8      ringtone;
69        u8      keynum;
70} __attribute__ ((packed));
71
72/*
73 * Register the LCD segment and icon map
74 */
75#define _LOC(k,l)       { .a = (k), .m = (l) }
76#define _SEG(t, a, am, b, bm, c, cm, d, dm, e, em, f, fm, g, gm)        \
77        { .type = (t),                                                  \
78          .u = { .s = { _LOC(a, am), _LOC(b, bm), _LOC(c, cm),          \
79                        _LOC(d, dm), _LOC(e, em), _LOC(g, gm),          \
80                        _LOC(f, fm) } } }
81#define _PIC(t, h, hm, n)                                               \
82        { .type = (t),                                                  \
83          .u = { .p = { .name = (n), .a = (h), .m = (hm) } } }
84
85static const struct lcd_segment_map {
86        char    type;
87        union {
88                struct pictogram_map {
89                        u8      a,m;
90                        char    name[10];
91                }       p;
92                struct segment_map {
93                        u8      a,m;
94                } s[7];
95        } u;
96} lcdMap[] = {
97#include "yealink.h"
98};
99
100struct yealink_dev {
101        struct input_dev *idev;         /* input device */
102        struct usb_device *udev;        /* usb device */
103        struct usb_interface *intf;     /* usb interface */
104
105        /* irq input channel */
106        struct yld_ctl_packet   *irq_data;
107        dma_addr_t              irq_dma;
108        struct urb              *urb_irq;
109
110        /* control output channel */
111        struct yld_ctl_packet   *ctl_data;
112        dma_addr_t              ctl_dma;
113        struct usb_ctrlrequest  *ctl_req;
114        struct urb              *urb_ctl;
115
116        char phys[64];                  /* physical device path */
117
118        u8 lcdMap[ARRAY_SIZE(lcdMap)];  /* state of LCD, LED ... */
119        int key_code;                   /* last reported key     */
120
121        unsigned int shutdown:1;
122
123        int     stat_ix;
124        union {
125                struct yld_status s;
126                u8                b[sizeof(struct yld_status)];
127        } master, copy;
128};
129
130
131/*******************************************************************************
132 * Yealink lcd interface
133 ******************************************************************************/
134
135/*
136 * Register a default 7 segment character set
137 */
138static SEG7_DEFAULT_MAP(map_seg7);
139
140 /* Display a char,
141  * char '\9' and '\n' are placeholders and do not overwrite the original text.
142  * A space will always hide an icon.
143  */
144static int setChar(struct yealink_dev *yld, int el, int chr)
145{
146        int i, a, m, val;
147
148        if (el >= ARRAY_SIZE(lcdMap))
149                return -EINVAL;
150
151        if (chr == '\t' || chr == '\n')
152            return 0;
153
154        yld->lcdMap[el] = chr;
155
156        if (lcdMap[el].type == '.') {
157                a = lcdMap[el].u.p.a;
158                m = lcdMap[el].u.p.m;
159                if (chr != ' ')
160                        yld->master.b[a] |= m;
161                else
162                        yld->master.b[a] &= ~m;
163                return 0;
164        }
165
166        val = map_to_seg7(&map_seg7, chr);
167        for (i = 0; i < ARRAY_SIZE(lcdMap[0].u.s); i++) {
168                m = lcdMap[el].u.s[i].m;
169
170                if (m == 0)
171                        continue;
172
173                a = lcdMap[el].u.s[i].a;
174                if (val & 1)
175                        yld->master.b[a] |= m;
176                else
177                        yld->master.b[a] &= ~m;
178                val = val >> 1;
179        }
180        return 0;
181};
182
183/*******************************************************************************
184 * Yealink key interface
185 ******************************************************************************/
186
187/* Map device buttons to internal key events.
188 *
189 * USB-P1K button layout:
190 *
191 *             up
192 *       IN           OUT
193 *            down
194 *
195 *     pickup   C    hangup
196 *       1      2      3
197 *       4      5      6
198 *       7      8      9
199 *       *      0      #
200 *
201 * The "up" and "down" keys, are symbolised by arrows on the button.
202 * The "pickup" and "hangup" keys are symbolised by a green and red phone
203 * on the button.
204 */
205static int map_p1k_to_key(int scancode)
206{
207        switch(scancode) {              /* phone key:   */
208        case 0x23: return KEY_LEFT;     /*   IN         */
209        case 0x33: return KEY_UP;       /*   up         */
210        case 0x04: return KEY_RIGHT;    /*   OUT        */
211        case 0x24: return KEY_DOWN;     /*   down       */
212        case 0x03: return KEY_ENTER;    /*   pickup     */
213        case 0x14: return KEY_BACKSPACE; /*  C          */
214        case 0x13: return KEY_ESC;      /*   hangup     */
215        case 0x00: return KEY_1;        /*   1          */
216        case 0x01: return KEY_2;        /*   2          */
217        case 0x02: return KEY_3;        /*   3          */
218        case 0x10: return KEY_4;        /*   4          */
219        case 0x11: return KEY_5;        /*   5          */
220        case 0x12: return KEY_6;        /*   6          */
221        case 0x20: return KEY_7;        /*   7          */
222        case 0x21: return KEY_8;        /*   8          */
223        case 0x22: return KEY_9;        /*   9          */
224        case 0x30: return KEY_KPASTERISK; /* *          */
225        case 0x31: return KEY_0;        /*   0          */
226        case 0x32: return KEY_LEFTSHIFT |
227                          KEY_3 << 8;   /*   #          */
228        }
229        return -EINVAL;
230}
231
232/* Completes a request by converting the data into events for the
233 * input subsystem.
234 *
235 * The key parameter can be cascaded: key2 << 8 | key1
236 */
237static void report_key(struct yealink_dev *yld, int key)
238{
239        struct input_dev *idev = yld->idev;
240
241        if (yld->key_code >= 0) {
242                /* old key up */
243                input_report_key(idev, yld->key_code & 0xff, 0);
244                if (yld->key_code >> 8)
245                        input_report_key(idev, yld->key_code >> 8, 0);
246        }
247
248        yld->key_code = key;
249        if (key >= 0) {
250                /* new valid key */
251                input_report_key(idev, key & 0xff, 1);
252                if (key >> 8)
253                        input_report_key(idev, key >> 8, 1);
254        }
255        input_sync(idev);
256}
257
258/*******************************************************************************
259 * Yealink usb communication interface
260 ******************************************************************************/
261
262static int yealink_cmd(struct yealink_dev *yld, struct yld_ctl_packet *p)
263{
264        u8      *buf = (u8 *)p;
265        int     i;
266        u8      sum = 0;
267
268        for(i=0; i<USB_PKT_LEN-1; i++)
269                sum -= buf[i];
270        p->sum = sum;
271        return usb_control_msg(yld->udev,
272                        usb_sndctrlpipe(yld->udev, 0),
273                        USB_REQ_SET_CONFIGURATION,
274                        USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
275                        0x200, 3,
276                        p, sizeof(*p),
277                        USB_CTRL_SET_TIMEOUT);
278}
279
280static u8 default_ringtone[] = {
281        0xEF,                   /* volume [0-255] */
282        0xFB, 0x1E, 0x00, 0x0C, /* 1250 [hz], 12/100 [s] */
283        0xFC, 0x18, 0x00, 0x0C, /* 1000 [hz], 12/100 [s] */
284        0xFB, 0x1E, 0x00, 0x0C,
285        0xFC, 0x18, 0x00, 0x0C,
286        0xFB, 0x1E, 0x00, 0x0C,
287        0xFC, 0x18, 0x00, 0x0C,
288        0xFB, 0x1E, 0x00, 0x0C,
289        0xFC, 0x18, 0x00, 0x0C,
290        0xFF, 0xFF, 0x01, 0x90, /* silent, 400/100 [s] */
291        0x00, 0x00              /* end of sequence */
292};
293
294static int yealink_set_ringtone(struct yealink_dev *yld, u8 *buf, size_t size)
295{
296        struct yld_ctl_packet *p = yld->ctl_data;
297        int     ix, len;
298
299        if (size <= 0)
300                return -EINVAL;
301
302        /* Set the ringtone volume */
303        memset(yld->ctl_data, 0, sizeof(*(yld->ctl_data)));
304        yld->ctl_data->cmd      = CMD_RING_VOLUME;
305        yld->ctl_data->size     = 1;
306        yld->ctl_data->data[0]  = buf[0];
307        yealink_cmd(yld, p);
308
309        buf++;
310        size--;
311
312        p->cmd = CMD_RING_NOTE;
313        ix = 0;
314        while (size != ix) {
315                len = size - ix;
316                if (len > sizeof(p->data))
317                        len = sizeof(p->data);
318                p->size   = len;
319                p->offset = cpu_to_be16(ix);
320                memcpy(p->data, &buf[ix], len);
321                yealink_cmd(yld, p);
322                ix += len;
323        }
324        return 0;
325}
326
327/* keep stat_master & stat_copy in sync.
328 */
329static int yealink_do_idle_tasks(struct yealink_dev *yld)
330{
331        u8 val;
332        int i, ix, len;
333
334        ix = yld->stat_ix;
335
336        memset(yld->ctl_data, 0, sizeof(*(yld->ctl_data)));
337        yld->ctl_data->cmd  = CMD_KEYPRESS;
338        yld->ctl_data->size = 1;
339        yld->ctl_data->sum  = 0xff - CMD_KEYPRESS;
340
341        /* If state update pointer wraps do a KEYPRESS first. */
342        if (ix >= sizeof(yld->master)) {
343                yld->stat_ix = 0;
344                return 0;
345        }
346
347        /* find update candidates: copy != master */
348        do {
349                val = yld->master.b[ix];
350                if (val != yld->copy.b[ix])
351                        goto send_update;
352        } while (++ix < sizeof(yld->master));
353
354        /* nothing todo, wait a bit and poll for a KEYPRESS */
355        yld->stat_ix = 0;
356        /* TODO how can we wait abit. ??
357         * msleep_interruptible(1000 / YEALINK_POLLING_FREQUENCY);
358         */
359        return 0;
360
361send_update:
362
363        /* Setup an appropriate update request */
364        yld->copy.b[ix] = val;
365        yld->ctl_data->data[0] = val;
366
367        switch(ix) {
368        case offsetof(struct yld_status, led):
369                yld->ctl_data->cmd      = CMD_LED;
370                yld->ctl_data->sum      = -1 - CMD_LED - val;
371                break;
372        case offsetof(struct yld_status, dialtone):
373                yld->ctl_data->cmd      = CMD_DIALTONE;
374                yld->ctl_data->sum      = -1 - CMD_DIALTONE - val;
375                break;
376        case offsetof(struct yld_status, ringtone):
377                yld->ctl_data->cmd      = CMD_RINGTONE;
378                yld->ctl_data->sum      = -1 - CMD_RINGTONE - val;
379                break;
380        case offsetof(struct yld_status, keynum):
381                val--;
382                val &= 0x1f;
383                yld->ctl_data->cmd      = CMD_SCANCODE;
384                yld->ctl_data->offset   = cpu_to_be16(val);
385                yld->ctl_data->data[0]  = 0;
386                yld->ctl_data->sum      = -1 - CMD_SCANCODE - val;
387                break;
388        default:
389                len = sizeof(yld->master.s.lcd) - ix;
390                if (len > sizeof(yld->ctl_data->data))
391                        len = sizeof(yld->ctl_data->data);
392
393                /* Combine up to <len> consecutive LCD bytes in a singe request
394                 */
395                yld->ctl_data->cmd      = CMD_LCD;
396                yld->ctl_data->offset   = cpu_to_be16(ix);
397                yld->ctl_data->size     = len;
398                yld->ctl_data->sum      = -CMD_LCD - ix - val - len;
399                for(i=1; i<len; i++) {
400                        ix++;
401                        val = yld->master.b[ix];
402                        yld->copy.b[ix]         = val;
403                        yld->ctl_data->data[i]  = val;
404                        yld->ctl_data->sum     -= val;
405                }
406        }
407        yld->stat_ix = ix + 1;
408        return 1;
409}
410
411/* Decide on how to handle responses
412 *
413 * The state transition diagram is somethhing like:
414 *
415 *          syncState<--+
416 *               |      |
417 *               |    idle
418 *              \|/     |
419 * init --ok--> waitForKey --ok--> getKey
420 *  ^               ^                |
421 *  |               +-------ok-------+
422 * error,start
423 *
424 */
425static void urb_irq_callback(struct urb *urb)
426{
427        struct yealink_dev *yld = urb->context;
428        int ret, status = urb->status;
429
430        if (status)
431                dev_err(&yld->intf->dev, "%s - urb status %d\n",
432                        __func__, status);
433
434        switch (yld->irq_data->cmd) {
435        case CMD_KEYPRESS:
436
437                yld->master.s.keynum = yld->irq_data->data[0];
438                break;
439
440        case CMD_SCANCODE:
441                dev_dbg(&yld->intf->dev, "get scancode %x\n",
442                        yld->irq_data->data[0]);
443
444                report_key(yld, map_p1k_to_key(yld->irq_data->data[0]));
445                break;
446
447        default:
448                dev_err(&yld->intf->dev, "unexpected response %x\n",
449                        yld->irq_data->cmd);
450        }
451
452        yealink_do_idle_tasks(yld);
453
454        if (!yld->shutdown) {
455                ret = usb_submit_urb(yld->urb_ctl, GFP_ATOMIC);
456                if (ret && ret != -EPERM)
457                        dev_err(&yld->intf->dev,
458                                "%s - usb_submit_urb failed %d\n",
459                                __func__, ret);
460        }
461}
462
463static void urb_ctl_callback(struct urb *urb)
464{
465        struct yealink_dev *yld = urb->context;
466        int ret = 0, status = urb->status;
467
468        if (status)
469                dev_err(&yld->intf->dev, "%s - urb status %d\n",
470                        __func__, status);
471
472        switch (yld->ctl_data->cmd) {
473        case CMD_KEYPRESS:
474        case CMD_SCANCODE:
475                /* ask for a response */
476                if (!yld->shutdown)
477                        ret = usb_submit_urb(yld->urb_irq, GFP_ATOMIC);
478                break;
479        default:
480                /* send new command */
481                yealink_do_idle_tasks(yld);
482                if (!yld->shutdown)
483                        ret = usb_submit_urb(yld->urb_ctl, GFP_ATOMIC);
484                break;
485        }
486
487        if (ret && ret != -EPERM)
488                dev_err(&yld->intf->dev, "%s - usb_submit_urb failed %d\n",
489                        __func__, ret);
490}
491
492/*******************************************************************************
493 * input event interface
494 ******************************************************************************/
495
496/* TODO should we issue a ringtone on a SND_BELL event?
497static int input_ev(struct input_dev *dev, unsigned int type,
498                unsigned int code, int value)
499{
500
501        if (type != EV_SND)
502                return -EINVAL;
503
504        switch (code) {
505        case SND_BELL:
506        case SND_TONE:
507                break;
508        default:
509                return -EINVAL;
510        }
511
512        return 0;
513}
514*/
515
516static int input_open(struct input_dev *dev)
517{
518        struct yealink_dev *yld = input_get_drvdata(dev);
519        int i, ret;
520
521        dev_dbg(&yld->intf->dev, "%s\n", __func__);
522
523        /* force updates to device */
524        for (i = 0; i<sizeof(yld->master); i++)
525                yld->copy.b[i] = ~yld->master.b[i];
526        yld->key_code = -1;     /* no keys pressed */
527
528        yealink_set_ringtone(yld, default_ringtone, sizeof(default_ringtone));
529
530        /* issue INIT */
531        memset(yld->ctl_data, 0, sizeof(*(yld->ctl_data)));
532        yld->ctl_data->cmd      = CMD_INIT;
533        yld->ctl_data->size     = 10;
534        yld->ctl_data->sum      = 0x100-CMD_INIT-10;
535        if ((ret = usb_submit_urb(yld->urb_ctl, GFP_KERNEL)) != 0) {
536                dev_dbg(&yld->intf->dev,
537                        "%s - usb_submit_urb failed with result %d\n",
538                        __func__, ret);
539                return ret;
540        }
541        return 0;
542}
543
544static void input_close(struct input_dev *dev)
545{
546        struct yealink_dev *yld = input_get_drvdata(dev);
547
548        yld->shutdown = 1;
549        /*
550         * Make sure the flag is seen by other CPUs before we start
551         * killing URBs so new URBs won't be submitted
552         */
553        smp_wmb();
554
555        usb_kill_urb(yld->urb_ctl);
556        usb_kill_urb(yld->urb_irq);
557
558        yld->shutdown = 0;
559        smp_wmb();
560}
561
562/*******************************************************************************
563 * sysfs interface
564 ******************************************************************************/
565
566static DECLARE_RWSEM(sysfs_rwsema);
567
568/* Interface to the 7-segments translation table aka. char set.
569 */
570static ssize_t show_map(struct device *dev, struct device_attribute *attr,
571                                char *buf)
572{
573        memcpy(buf, &map_seg7, sizeof(map_seg7));
574        return sizeof(map_seg7);
575}
576
577static ssize_t store_map(struct device *dev, struct device_attribute *attr,
578                                const char *buf, size_t cnt)
579{
580        if (cnt != sizeof(map_seg7))
581                return -EINVAL;
582        memcpy(&map_seg7, buf, sizeof(map_seg7));
583        return sizeof(map_seg7);
584}
585
586/* Interface to the LCD.
587 */
588
589/* Reading /sys/../lineX will return the format string with its settings:
590 *
591 * Example:
592 * cat ./line3
593 * 888888888888
594 * Linux Rocks!
595 */
596static ssize_t show_line(struct device *dev, char *buf, int a, int b)
597{
598        struct yealink_dev *yld;
599        int i;
600
601        down_read(&sysfs_rwsema);
602        yld = dev_get_drvdata(dev);
603        if (yld == NULL) {
604                up_read(&sysfs_rwsema);
605                return -ENODEV;
606        }
607
608        for (i = a; i < b; i++)
609                *buf++ = lcdMap[i].type;
610        *buf++ = '\n';
611        for (i = a; i < b; i++)
612                *buf++ = yld->lcdMap[i];
613        *buf++ = '\n';
614        *buf = 0;
615
616        up_read(&sysfs_rwsema);
617        return 3 + ((b - a) << 1);
618}
619
620static ssize_t show_line1(struct device *dev, struct device_attribute *attr,
621                        char *buf)
622{
623        return show_line(dev, buf, LCD_LINE1_OFFSET, LCD_LINE2_OFFSET);
624}
625
626static ssize_t show_line2(struct device *dev, struct device_attribute *attr,
627                        char *buf)
628{
629        return show_line(dev, buf, LCD_LINE2_OFFSET, LCD_LINE3_OFFSET);
630}
631
632static ssize_t show_line3(struct device *dev, struct device_attribute *attr,
633                        char *buf)
634{
635        return show_line(dev, buf, LCD_LINE3_OFFSET, LCD_LINE4_OFFSET);
636}
637
638/* Writing to /sys/../lineX will set the coresponding LCD line.
639 * - Excess characters are ignored.
640 * - If less characters are written than allowed, the remaining digits are
641 *   unchanged.
642 * - The '\n' or '\t' char is a placeholder, it does not overwrite the
643 *   original content.
644 */
645static ssize_t store_line(struct device *dev, const char *buf, size_t count,
646                int el, size_t len)
647{
648        struct yealink_dev *yld;
649        int i;
650
651        down_write(&sysfs_rwsema);
652        yld = dev_get_drvdata(dev);
653        if (yld == NULL) {
654                up_write(&sysfs_rwsema);
655                return -ENODEV;
656        }
657
658        if (len > count)
659                len = count;
660        for (i = 0; i < len; i++)
661                setChar(yld, el++, buf[i]);
662
663        up_write(&sysfs_rwsema);
664        return count;
665}
666
667static ssize_t store_line1(struct device *dev, struct device_attribute *attr,
668                                const char *buf, size_t count)
669{
670        return store_line(dev, buf, count, LCD_LINE1_OFFSET, LCD_LINE1_SIZE);
671}
672
673static ssize_t store_line2(struct device *dev, struct device_attribute *attr,
674                                const char *buf, size_t count)
675{
676        return store_line(dev, buf, count, LCD_LINE2_OFFSET, LCD_LINE2_SIZE);
677}
678
679static ssize_t store_line3(struct device *dev, struct device_attribute *attr,
680                                const char *buf, size_t count)
681{
682        return store_line(dev, buf, count, LCD_LINE3_OFFSET, LCD_LINE3_SIZE);
683}
684
685/* Interface to visible and audible "icons", these include:
686 * pictures on the LCD, the LED, and the dialtone signal.
687 */
688
689/* Get a list of "switchable elements" with their current state. */
690static ssize_t get_icons(struct device *dev, struct device_attribute *attr,
691                        char *buf)
692{
693        struct yealink_dev *yld;
694        int i, ret = 1;
695
696        down_read(&sysfs_rwsema);
697        yld = dev_get_drvdata(dev);
698        if (yld == NULL) {
699                up_read(&sysfs_rwsema);
700                return -ENODEV;
701        }
702
703        for (i = 0; i < ARRAY_SIZE(lcdMap); i++) {
704                if (lcdMap[i].type != '.')
705                        continue;
706                ret += sprintf(&buf[ret], "%s %s\n",
707                                yld->lcdMap[i] == ' ' ? "  " : "on",
708                                lcdMap[i].u.p.name);
709        }
710        up_read(&sysfs_rwsema);
711        return ret;
712}
713
714/* Change the visibility of a particular element. */
715static ssize_t set_icon(struct device *dev, const char *buf, size_t count,
716                        int chr)
717{
718        struct yealink_dev *yld;
719        int i;
720
721        down_write(&sysfs_rwsema);
722        yld = dev_get_drvdata(dev);
723        if (yld == NULL) {
724                up_write(&sysfs_rwsema);
725                return -ENODEV;
726        }
727
728        for (i = 0; i < ARRAY_SIZE(lcdMap); i++) {
729                if (lcdMap[i].type != '.')
730                        continue;
731                if (strncmp(buf, lcdMap[i].u.p.name, count) == 0) {
732                        setChar(yld, i, chr);
733                        break;
734                }
735        }
736
737        up_write(&sysfs_rwsema);
738        return count;
739}
740
741static ssize_t show_icon(struct device *dev, struct device_attribute *attr,
742                const char *buf, size_t count)
743{
744        return set_icon(dev, buf, count, buf[0]);
745}
746
747static ssize_t hide_icon(struct device *dev, struct device_attribute *attr,
748                const char *buf, size_t count)
749{
750        return set_icon(dev, buf, count, ' ');
751}
752
753/* Upload a ringtone to the device.
754 */
755
756/* Stores raw ringtone data in the phone */
757static ssize_t store_ringtone(struct device *dev,
758                struct device_attribute *attr,
759                const char *buf, size_t count)
760{
761        struct yealink_dev *yld;
762
763        down_write(&sysfs_rwsema);
764        yld = dev_get_drvdata(dev);
765        if (yld == NULL) {
766                up_write(&sysfs_rwsema);
767                return -ENODEV;
768        }
769
770        /* TODO locking with async usb control interface??? */
771        yealink_set_ringtone(yld, (char *)buf, count);
772        up_write(&sysfs_rwsema);
773        return count;
774}
775
776#define _M444   S_IRUGO
777#define _M664   S_IRUGO|S_IWUSR|S_IWGRP
778#define _M220   S_IWUSR|S_IWGRP
779
780static DEVICE_ATTR(map_seg7     , _M664, show_map       , store_map     );
781static DEVICE_ATTR(line1        , _M664, show_line1     , store_line1   );
782static DEVICE_ATTR(line2        , _M664, show_line2     , store_line2   );
783static DEVICE_ATTR(line3        , _M664, show_line3     , store_line3   );
784static DEVICE_ATTR(get_icons    , _M444, get_icons      , NULL          );
785static DEVICE_ATTR(show_icon    , _M220, NULL           , show_icon     );
786static DEVICE_ATTR(hide_icon    , _M220, NULL           , hide_icon     );
787static DEVICE_ATTR(ringtone     , _M220, NULL           , store_ringtone);
788
789static struct attribute *yld_attributes[] = {
790        &dev_attr_line1.attr,
791        &dev_attr_line2.attr,
792        &dev_attr_line3.attr,
793        &dev_attr_get_icons.attr,
794        &dev_attr_show_icon.attr,
795        &dev_attr_hide_icon.attr,
796        &dev_attr_map_seg7.attr,
797        &dev_attr_ringtone.attr,
798        NULL
799};
800
801static struct attribute_group yld_attr_group = {
802        .attrs = yld_attributes
803};
804
805/*******************************************************************************
806 * Linux interface and usb initialisation
807 ******************************************************************************/
808
809struct driver_info {
810        char *name;
811};
812
813static const struct driver_info info_P1K = {
814        .name   = "Yealink usb-p1k",
815};
816
817static const struct usb_device_id usb_table [] = {
818        {
819                .match_flags            = USB_DEVICE_ID_MATCH_DEVICE |
820                                                USB_DEVICE_ID_MATCH_INT_INFO,
821                .idVendor               = 0x6993,
822                .idProduct              = 0xb001,
823                .bInterfaceClass        = USB_CLASS_HID,
824                .bInterfaceSubClass     = 0,
825                .bInterfaceProtocol     = 0,
826                .driver_info            = (kernel_ulong_t)&info_P1K
827        },
828        { }
829};
830
831static int usb_cleanup(struct yealink_dev *yld, int err)
832{
833        if (yld == NULL)
834                return err;
835
836        if (yld->idev) {
837                if (err)
838                        input_free_device(yld->idev);
839                else
840                        input_unregister_device(yld->idev);
841        }
842
843        usb_free_urb(yld->urb_irq);
844        usb_free_urb(yld->urb_ctl);
845
846        kfree(yld->ctl_req);
847        usb_free_coherent(yld->udev, USB_PKT_LEN, yld->ctl_data, yld->ctl_dma);
848        usb_free_coherent(yld->udev, USB_PKT_LEN, yld->irq_data, yld->irq_dma);
849
850        kfree(yld);
851        return err;
852}
853
854static void usb_disconnect(struct usb_interface *intf)
855{
856        struct yealink_dev *yld;
857
858        down_write(&sysfs_rwsema);
859        yld = usb_get_intfdata(intf);
860        sysfs_remove_group(&intf->dev.kobj, &yld_attr_group);
861        usb_set_intfdata(intf, NULL);
862        up_write(&sysfs_rwsema);
863
864        usb_cleanup(yld, 0);
865}
866
867static int usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
868{
869        struct usb_device *udev = interface_to_usbdev (intf);
870        struct driver_info *nfo = (struct driver_info *)id->driver_info;
871        struct usb_host_interface *interface;
872        struct usb_endpoint_descriptor *endpoint;
873        struct yealink_dev *yld;
874        struct input_dev *input_dev;
875        int ret, pipe, i;
876
877        interface = intf->cur_altsetting;
878
879        if (interface->desc.bNumEndpoints < 1)
880                return -ENODEV;
881
882        endpoint = &interface->endpoint[0].desc;
883        if (!usb_endpoint_is_int_in(endpoint))
884                return -ENODEV;
885
886        yld = kzalloc(sizeof(struct yealink_dev), GFP_KERNEL);
887        if (!yld)
888                return -ENOMEM;
889
890        yld->udev = udev;
891        yld->intf = intf;
892
893        yld->idev = input_dev = input_allocate_device();
894        if (!input_dev)
895                return usb_cleanup(yld, -ENOMEM);
896
897        /* allocate usb buffers */
898        yld->irq_data = usb_alloc_coherent(udev, USB_PKT_LEN,
899                                           GFP_ATOMIC, &yld->irq_dma);
900        if (yld->irq_data == NULL)
901                return usb_cleanup(yld, -ENOMEM);
902
903        yld->ctl_data = usb_alloc_coherent(udev, USB_PKT_LEN,
904                                           GFP_ATOMIC, &yld->ctl_dma);
905        if (!yld->ctl_data)
906                return usb_cleanup(yld, -ENOMEM);
907
908        yld->ctl_req = kmalloc(sizeof(*(yld->ctl_req)), GFP_KERNEL);
909        if (yld->ctl_req == NULL)
910                return usb_cleanup(yld, -ENOMEM);
911
912        /* allocate urb structures */
913        yld->urb_irq = usb_alloc_urb(0, GFP_KERNEL);
914        if (yld->urb_irq == NULL)
915                return usb_cleanup(yld, -ENOMEM);
916
917        yld->urb_ctl = usb_alloc_urb(0, GFP_KERNEL);
918        if (yld->urb_ctl == NULL)
919                return usb_cleanup(yld, -ENOMEM);
920
921        /* get a handle to the interrupt data pipe */
922        pipe = usb_rcvintpipe(udev, endpoint->bEndpointAddress);
923        ret = usb_maxpacket(udev, pipe, usb_pipeout(pipe));
924        if (ret != USB_PKT_LEN)
925                dev_err(&intf->dev, "invalid payload size %d, expected %zd\n",
926                        ret, USB_PKT_LEN);
927
928        /* initialise irq urb */
929        usb_fill_int_urb(yld->urb_irq, udev, pipe, yld->irq_data,
930                        USB_PKT_LEN,
931                        urb_irq_callback,
932                        yld, endpoint->bInterval);
933        yld->urb_irq->transfer_dma = yld->irq_dma;
934        yld->urb_irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
935        yld->urb_irq->dev = udev;
936
937        /* initialise ctl urb */
938        yld->ctl_req->bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE |
939                                      USB_DIR_OUT;
940        yld->ctl_req->bRequest  = USB_REQ_SET_CONFIGURATION;
941        yld->ctl_req->wValue    = cpu_to_le16(0x200);
942        yld->ctl_req->wIndex    = cpu_to_le16(interface->desc.bInterfaceNumber);
943        yld->ctl_req->wLength   = cpu_to_le16(USB_PKT_LEN);
944
945        usb_fill_control_urb(yld->urb_ctl, udev, usb_sndctrlpipe(udev, 0),
946                        (void *)yld->ctl_req, yld->ctl_data, USB_PKT_LEN,
947                        urb_ctl_callback, yld);
948        yld->urb_ctl->transfer_dma      = yld->ctl_dma;
949        yld->urb_ctl->transfer_flags    |= URB_NO_TRANSFER_DMA_MAP;
950        yld->urb_ctl->dev = udev;
951
952        /* find out the physical bus location */
953        usb_make_path(udev, yld->phys, sizeof(yld->phys));
954        strlcat(yld->phys,  "/input0", sizeof(yld->phys));
955
956        /* register settings for the input device */
957        input_dev->name = nfo->name;
958        input_dev->phys = yld->phys;
959        usb_to_input_id(udev, &input_dev->id);
960        input_dev->dev.parent = &intf->dev;
961
962        input_set_drvdata(input_dev, yld);
963
964        input_dev->open = input_open;
965        input_dev->close = input_close;
966        /* input_dev->event = input_ev; TODO */
967
968        /* register available key events */
969        input_dev->evbit[0] = BIT_MASK(EV_KEY);
970        for (i = 0; i < 256; i++) {
971                int k = map_p1k_to_key(i);
972                if (k >= 0) {
973                        set_bit(k & 0xff, input_dev->keybit);
974                        if (k >> 8)
975                                set_bit(k >> 8, input_dev->keybit);
976                }
977        }
978
979        ret = input_register_device(yld->idev);
980        if (ret)
981                return usb_cleanup(yld, ret);
982
983        usb_set_intfdata(intf, yld);
984
985        /* clear visible elements */
986        for (i = 0; i < ARRAY_SIZE(lcdMap); i++)
987                setChar(yld, i, ' ');
988
989        /* display driver version on LCD line 3 */
990        store_line3(&intf->dev, NULL,
991                        DRIVER_VERSION, sizeof(DRIVER_VERSION));
992
993        /* Register sysfs hooks (don't care about failure) */
994        ret = sysfs_create_group(&intf->dev.kobj, &yld_attr_group);
995        return 0;
996}
997
998static struct usb_driver yealink_driver = {
999        .name           = "yealink",
1000        .probe          = usb_probe,
1001        .disconnect     = usb_disconnect,
1002        .id_table       = usb_table,
1003};
1004
1005module_usb_driver(yealink_driver);
1006
1007MODULE_DEVICE_TABLE (usb, usb_table);
1008
1009MODULE_AUTHOR(DRIVER_AUTHOR);
1010MODULE_DESCRIPTION(DRIVER_DESC);
1011MODULE_LICENSE("GPL");
Note: See TracBrowser for help on using the repository browser.