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