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        struct usb_interface *intf;     /* usb interface */
 105
 106        /* irq input channel */
 107        struct yld_ctl_packet   *irq_data;
 108        dma_addr_t              irq_dma;
 109        struct urb              *urb_irq;
 110
 111        /* control output channel */
 112        struct yld_ctl_packet   *ctl_data;
 113        dma_addr_t              ctl_dma;
 114        struct usb_ctrlrequest  *ctl_req;
 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                dev_err(&yld->intf->dev, "%s - urb status %d\n",
 433                        __func__, status);
 434
 435        switch (yld->irq_data->cmd) {
 436        case CMD_KEYPRESS:
 437
 438                yld->master.s.keynum = yld->irq_data->data[0];
 439                break;
 440
 441        case CMD_SCANCODE:
 442                dev_dbg(&yld->intf->dev, "get scancode %x\n",
 443                        yld->irq_data->data[0]);
 444
 445                report_key(yld, map_p1k_to_key(yld->irq_data->data[0]));
 446                break;
 447
 448        default:
 449                dev_err(&yld->intf->dev, "unexpected response %x\n",
 450                        yld->irq_data->cmd);
 451        }
 452
 453        yealink_do_idle_tasks(yld);
 454
 455        if (!yld->shutdown) {
 456                ret = usb_submit_urb(yld->urb_ctl, GFP_ATOMIC);
 457                if (ret && ret != -EPERM)
 458                        dev_err(&yld->intf->dev,
 459                                "%s - usb_submit_urb failed %d\n",
 460                                __func__, ret);
 461        }
 462}
 463
 464static void urb_ctl_callback(struct urb *urb)
 465{
 466        struct yealink_dev *yld = urb->context;
 467        int ret = 0, status = urb->status;
 468
 469        if (status)
 470                dev_err(&yld->intf->dev, "%s - urb status %d\n",
 471                        __func__, status);
 472
 473        switch (yld->ctl_data->cmd) {
 474        case CMD_KEYPRESS:
 475        case CMD_SCANCODE:
 476                /* ask for a response */
 477                if (!yld->shutdown)
 478                        ret = usb_submit_urb(yld->urb_irq, GFP_ATOMIC);
 479                break;
 480        default:
 481                /* send new command */
 482                yealink_do_idle_tasks(yld);
 483                if (!yld->shutdown)
 484                        ret = usb_submit_urb(yld->urb_ctl, GFP_ATOMIC);
 485                break;
 486        }
 487
 488        if (ret && ret != -EPERM)
 489                dev_err(&yld->intf->dev, "%s - usb_submit_urb failed %d\n",
 490                        __func__, ret);
 491}
 492
 493/*******************************************************************************
 494 * input event interface
 495 ******************************************************************************/
 496
 497/* TODO should we issue a ringtone on a SND_BELL event?
 498static int input_ev(struct input_dev *dev, unsigned int type,
 499                unsigned int code, int value)
 500{
 501
 502        if (type != EV_SND)
 503                return -EINVAL;
 504
 505        switch (code) {
 506        case SND_BELL:
 507        case SND_TONE:
 508                break;
 509        default:
 510                return -EINVAL;
 511        }
 512
 513        return 0;
 514}
 515*/
 516
 517static int input_open(struct input_dev *dev)
 518{
 519        struct yealink_dev *yld = input_get_drvdata(dev);
 520        int i, ret;
 521
 522        dev_dbg(&yld->intf->dev, "%s\n", __func__);
 523
 524        /* force updates to device */
 525        for (i = 0; i<sizeof(yld->master); i++)
 526                yld->copy.b[i] = ~yld->master.b[i];
 527        yld->key_code = -1;     /* no keys pressed */
 528
 529        yealink_set_ringtone(yld, default_ringtone, sizeof(default_ringtone));
 530
 531        /* issue INIT */
 532        memset(yld->ctl_data, 0, sizeof(*(yld->ctl_data)));
 533        yld->ctl_data->cmd      = CMD_INIT;
 534        yld->ctl_data->size     = 10;
 535        yld->ctl_data->sum      = 0x100-CMD_INIT-10;
 536        if ((ret = usb_submit_urb(yld->urb_ctl, GFP_KERNEL)) != 0) {
 537                dev_dbg(&yld->intf->dev,
 538                        "%s - usb_submit_urb failed with result %d\n",
 539                        __func__, ret);
 540                return ret;
 541        }
 542        return 0;
 543}
 544
 545static void input_close(struct input_dev *dev)
 546{
 547        struct yealink_dev *yld = input_get_drvdata(dev);
 548
 549        yld->shutdown = 1;
 550        /*
 551         * Make sure the flag is seen by other CPUs before we start
 552         * killing URBs so new URBs won't be submitted
 553         */
 554        smp_wmb();
 555
 556        usb_kill_urb(yld->urb_ctl);
 557        usb_kill_urb(yld->urb_irq);
 558
 559        yld->shutdown = 0;
 560        smp_wmb();
 561}
 562
 563/*******************************************************************************
 564 * sysfs interface
 565 ******************************************************************************/
 566
 567static DECLARE_RWSEM(sysfs_rwsema);
 568
 569/* Interface to the 7-segments translation table aka. char set.
 570 */
 571static ssize_t show_map(struct device *dev, struct device_attribute *attr,
 572                                char *buf)
 573{
 574        memcpy(buf, &map_seg7, sizeof(map_seg7));
 575        return sizeof(map_seg7);
 576}
 577
 578static ssize_t store_map(struct device *dev, struct device_attribute *attr,
 579                                const char *buf, size_t cnt)
 580{
 581        if (cnt != sizeof(map_seg7))
 582                return -EINVAL;
 583        memcpy(&map_seg7, buf, sizeof(map_seg7));
 584        return sizeof(map_seg7);
 585}
 586
 587/* Interface to the LCD.
 588 */
 589
 590/* Reading /sys/../lineX will return the format string with its settings:
 591 *
 592 * Example:
 593 * cat ./line3
 594 * 888888888888
 595 * Linux Rocks!
 596 */
 597static ssize_t show_line(struct device *dev, char *buf, int a, int b)
 598{
 599        struct yealink_dev *yld;
 600        int i;
 601
 602        down_read(&sysfs_rwsema);
 603        yld = dev_get_drvdata(dev);
 604        if (yld == NULL) {
 605                up_read(&sysfs_rwsema);
 606                return -ENODEV;
 607        }
 608
 609        for (i = a; i < b; i++)
 610                *buf++ = lcdMap[i].type;
 611        *buf++ = '\n';
 612        for (i = a; i < b; i++)
 613                *buf++ = yld->lcdMap[i];
 614        *buf++ = '\n';
 615        *buf = 0;
 616
 617        up_read(&sysfs_rwsema);
 618        return 3 + ((b - a) << 1);
 619}
 620
 621static ssize_t show_line1(struct device *dev, struct device_attribute *attr,
 622                        char *buf)
 623{
 624        return show_line(dev, buf, LCD_LINE1_OFFSET, LCD_LINE2_OFFSET);
 625}
 626
 627static ssize_t show_line2(struct device *dev, struct device_attribute *attr,
 628                        char *buf)
 629{
 630        return show_line(dev, buf, LCD_LINE2_OFFSET, LCD_LINE3_OFFSET);
 631}
 632
 633static ssize_t show_line3(struct device *dev, struct device_attribute *attr,
 634                        char *buf)
 635{
 636        return show_line(dev, buf, LCD_LINE3_OFFSET, LCD_LINE4_OFFSET);
 637}
 638
 639/* Writing to /sys/../lineX will set the coresponding LCD line.
 640 * - Excess characters are ignored.
 641 * - If less characters are written than allowed, the remaining digits are
 642 *   unchanged.
 643 * - The '\n' or '\t' char is a placeholder, it does not overwrite the
 644 *   original content.
 645 */
 646static ssize_t store_line(struct device *dev, const char *buf, size_t count,
 647                int el, size_t len)
 648{
 649        struct yealink_dev *yld;
 650        int i;
 651
 652        down_write(&sysfs_rwsema);
 653        yld = dev_get_drvdata(dev);
 654        if (yld == NULL) {
 655                up_write(&sysfs_rwsema);
 656                return -ENODEV;
 657        }
 658
 659        if (len > count)
 660                len = count;
 661        for (i = 0; i < len; i++)
 662                setChar(yld, el++, buf[i]);
 663
 664        up_write(&sysfs_rwsema);
 665        return count;
 666}
 667
 668static ssize_t store_line1(struct device *dev, struct device_attribute *attr,
 669                                const char *buf, size_t count)
 670{
 671        return store_line(dev, buf, count, LCD_LINE1_OFFSET, LCD_LINE1_SIZE);
 672}
 673
 674static ssize_t store_line2(struct device *dev, struct device_attribute *attr,
 675                                const char *buf, size_t count)
 676{
 677        return store_line(dev, buf, count, LCD_LINE2_OFFSET, LCD_LINE2_SIZE);
 678}
 679
 680static ssize_t store_line3(struct device *dev, struct device_attribute *attr,
 681                                const char *buf, size_t count)
 682{
 683        return store_line(dev, buf, count, LCD_LINE3_OFFSET, LCD_LINE3_SIZE);
 684}
 685
 686/* Interface to visible and audible "icons", these include:
 687 * pictures on the LCD, the LED, and the dialtone signal.
 688 */
 689
 690/* Get a list of "switchable elements" with their current state. */
 691static ssize_t get_icons(struct device *dev, struct device_attribute *attr,
 692                        char *buf)
 693{
 694        struct yealink_dev *yld;
 695        int i, ret = 1;
 696
 697        down_read(&sysfs_rwsema);
 698        yld = dev_get_drvdata(dev);
 699        if (yld == NULL) {
 700                up_read(&sysfs_rwsema);
 701                return -ENODEV;
 702        }
 703
 704        for (i = 0; i < ARRAY_SIZE(lcdMap); i++) {
 705                if (lcdMap[i].type != '.')
 706                        continue;
 707                ret += sprintf(&buf[ret], "%s %s\n",
 708                                yld->lcdMap[i] == ' ' ? "  " : "on",
 709                                lcdMap[i].u.p.name);
 710        }
 711        up_read(&sysfs_rwsema);
 712        return ret;
 713}
 714
 715/* Change the visibility of a particular element. */
 716static ssize_t set_icon(struct device *dev, const char *buf, size_t count,
 717                        int chr)
 718{
 719        struct yealink_dev *yld;
 720        int i;
 721
 722        down_write(&sysfs_rwsema);
 723        yld = dev_get_drvdata(dev);
 724        if (yld == NULL) {
 725                up_write(&sysfs_rwsema);
 726                return -ENODEV;
 727        }
 728
 729        for (i = 0; i < ARRAY_SIZE(lcdMap); i++) {
 730                if (lcdMap[i].type != '.')
 731                        continue;
 732                if (strncmp(buf, lcdMap[i].u.p.name, count) == 0) {
 733                        setChar(yld, i, chr);
 734                        break;
 735                }
 736        }
 737
 738        up_write(&sysfs_rwsema);
 739        return count;
 740}
 741
 742static ssize_t show_icon(struct device *dev, struct device_attribute *attr,
 743                const char *buf, size_t count)
 744{
 745        return set_icon(dev, buf, count, buf[0]);
 746}
 747
 748static ssize_t hide_icon(struct device *dev, struct device_attribute *attr,
 749                const char *buf, size_t count)
 750{
 751        return set_icon(dev, buf, count, ' ');
 752}
 753
 754/* Upload a ringtone to the device.
 755 */
 756
 757/* Stores raw ringtone data in the phone */
 758static ssize_t store_ringtone(struct device *dev,
 759                struct device_attribute *attr,
 760                const char *buf, size_t count)
 761{
 762        struct yealink_dev *yld;
 763
 764        down_write(&sysfs_rwsema);
 765        yld = dev_get_drvdata(dev);
 766        if (yld == NULL) {
 767                up_write(&sysfs_rwsema);
 768                return -ENODEV;
 769        }
 770
 771        /* TODO locking with async usb control interface??? */
 772        yealink_set_ringtone(yld, (char *)buf, count);
 773        up_write(&sysfs_rwsema);
 774        return count;
 775}
 776
 777#define _M444   S_IRUGO
 778#define _M664   S_IRUGO|S_IWUSR|S_IWGRP
 779#define _M220   S_IWUSR|S_IWGRP
 780
 781static DEVICE_ATTR(map_seg7     , _M664, show_map       , store_map     );
 782static DEVICE_ATTR(line1        , _M664, show_line1     , store_line1   );
 783static DEVICE_ATTR(line2        , _M664, show_line2     , store_line2   );
 784static DEVICE_ATTR(line3        , _M664, show_line3     , store_line3   );
 785static DEVICE_ATTR(get_icons    , _M444, get_icons      , NULL          );
 786static DEVICE_ATTR(show_icon    , _M220, NULL           , show_icon     );
 787static DEVICE_ATTR(hide_icon    , _M220, NULL           , hide_icon     );
 788static DEVICE_ATTR(ringtone     , _M220, NULL           , store_ringtone);
 789
 790static struct attribute *yld_attributes[] = {
 791        &dev_attr_line1.attr,
 792        &dev_attr_line2.attr,
 793        &dev_attr_line3.attr,
 794        &dev_attr_get_icons.attr,
 795        &dev_attr_show_icon.attr,
 796        &dev_attr_hide_icon.attr,
 797        &dev_attr_map_seg7.attr,
 798        &dev_attr_ringtone.attr,
 799        NULL
 800};
 801
 802static struct attribute_group yld_attr_group = {
 803        .attrs = yld_attributes
 804};
 805
 806/*******************************************************************************
 807 * Linux interface and usb initialisation
 808 ******************************************************************************/
 809
 810struct driver_info {
 811        char *name;
 812};
 813
 814static const struct driver_info info_P1K = {
 815        .name   = "Yealink usb-p1k",
 816};
 817
 818static const struct usb_device_id usb_table [] = {
 819        {
 820                .match_flags            = USB_DEVICE_ID_MATCH_DEVICE |
 821                                                USB_DEVICE_ID_MATCH_INT_INFO,
 822                .idVendor               = 0x6993,
 823                .idProduct              = 0xb001,
 824                .bInterfaceClass        = USB_CLASS_HID,
 825                .bInterfaceSubClass     = 0,
 826                .bInterfaceProtocol     = 0,
 827                .driver_info            = (kernel_ulong_t)&info_P1K
 828        },
 829        { }
 830};
 831
 832static int usb_cleanup(struct yealink_dev *yld, int err)
 833{
 834        if (yld == NULL)
 835                return err;
 836
 837        if (yld->idev) {
 838                if (err)
 839                        input_free_device(yld->idev);
 840                else
 841                        input_unregister_device(yld->idev);
 842        }
 843
 844        usb_free_urb(yld->urb_irq);
 845        usb_free_urb(yld->urb_ctl);
 846
 847        kfree(yld->ctl_req);
 848        usb_free_coherent(yld->udev, USB_PKT_LEN, yld->ctl_data, yld->ctl_dma);
 849        usb_free_coherent(yld->udev, USB_PKT_LEN, yld->irq_data, yld->irq_dma);
 850
 851        kfree(yld);
 852        return err;
 853}
 854
 855static void usb_disconnect(struct usb_interface *intf)
 856{
 857        struct yealink_dev *yld;
 858
 859        down_write(&sysfs_rwsema);
 860        yld = usb_get_intfdata(intf);
 861        sysfs_remove_group(&intf->dev.kobj, &yld_attr_group);
 862        usb_set_intfdata(intf, NULL);
 863        up_write(&sysfs_rwsema);
 864
 865        usb_cleanup(yld, 0);
 866}
 867
 868static int usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
 869{
 870        struct usb_device *udev = interface_to_usbdev (intf);
 871        struct driver_info *nfo = (struct driver_info *)id->driver_info;
 872        struct usb_host_interface *interface;
 873        struct usb_endpoint_descriptor *endpoint;
 874        struct yealink_dev *yld;
 875        struct input_dev *input_dev;
 876        int ret, pipe, i;
 877
 878        interface = intf->cur_altsetting;
 879        endpoint = &interface->endpoint[0].desc;
 880        if (!usb_endpoint_is_int_in(endpoint))
 881                return -ENODEV;
 882
 883        yld = kzalloc(sizeof(struct yealink_dev), GFP_KERNEL);
 884        if (!yld)
 885                return -ENOMEM;
 886
 887        yld->udev = udev;
 888        yld->intf = intf;
 889
 890        yld->idev = input_dev = input_allocate_device();
 891        if (!input_dev)
 892                return usb_cleanup(yld, -ENOMEM);
 893
 894        /* allocate usb buffers */
 895        yld->irq_data = usb_alloc_coherent(udev, USB_PKT_LEN,
 896                                           GFP_ATOMIC, &yld->irq_dma);
 897        if (yld->irq_data == NULL)
 898                return usb_cleanup(yld, -ENOMEM);
 899
 900        yld->ctl_data = usb_alloc_coherent(udev, USB_PKT_LEN,
 901                                           GFP_ATOMIC, &yld->ctl_dma);
 902        if (!yld->ctl_data)
 903                return usb_cleanup(yld, -ENOMEM);
 904
 905        yld->ctl_req = kmalloc(sizeof(*(yld->ctl_req)), GFP_KERNEL);
 906        if (yld->ctl_req == NULL)
 907                return usb_cleanup(yld, -ENOMEM);
 908
 909        /* allocate urb structures */
 910        yld->urb_irq = usb_alloc_urb(0, GFP_KERNEL);
 911        if (yld->urb_irq == NULL)
 912                return usb_cleanup(yld, -ENOMEM);
 913
 914        yld->urb_ctl = usb_alloc_urb(0, GFP_KERNEL);
 915        if (yld->urb_ctl == NULL)
 916                return usb_cleanup(yld, -ENOMEM);
 917
 918        /* get a handle to the interrupt data pipe */
 919        pipe = usb_rcvintpipe(udev, endpoint->bEndpointAddress);
 920        ret = usb_maxpacket(udev, pipe, usb_pipeout(pipe));
 921        if (ret != USB_PKT_LEN)
 922                dev_err(&intf->dev, "invalid payload size %d, expected %zd\n",
 923                        ret, USB_PKT_LEN);
 924
 925        /* initialise irq urb */
 926        usb_fill_int_urb(yld->urb_irq, udev, pipe, yld->irq_data,
 927                        USB_PKT_LEN,
 928                        urb_irq_callback,
 929                        yld, endpoint->bInterval);
 930        yld->urb_irq->transfer_dma = yld->irq_dma;
 931        yld->urb_irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
 932        yld->urb_irq->dev = udev;
 933
 934        /* initialise ctl urb */
 935        yld->ctl_req->bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE |
 936                                      USB_DIR_OUT;
 937        yld->ctl_req->bRequest  = USB_REQ_SET_CONFIGURATION;
 938        yld->ctl_req->wValue    = cpu_to_le16(0x200);
 939        yld->ctl_req->wIndex    = cpu_to_le16(interface->desc.bInterfaceNumber);
 940        yld->ctl_req->wLength   = cpu_to_le16(USB_PKT_LEN);
 941
 942        usb_fill_control_urb(yld->urb_ctl, udev, usb_sndctrlpipe(udev, 0),
 943                        (void *)yld->ctl_req, yld->ctl_data, USB_PKT_LEN,
 944                        urb_ctl_callback, yld);
 945        yld->urb_ctl->transfer_dma      = yld->ctl_dma;
 946        yld->urb_ctl->transfer_flags    |= URB_NO_TRANSFER_DMA_MAP;
 947        yld->urb_ctl->dev = udev;
 948
 949        /* find out the physical bus location */
 950        usb_make_path(udev, yld->phys, sizeof(yld->phys));
 951        strlcat(yld->phys,  "/input0", sizeof(yld->phys));
 952
 953        /* register settings for the input device */
 954        input_dev->name = nfo->name;
 955        input_dev->phys = yld->phys;
 956        usb_to_input_id(udev, &input_dev->id);
 957        input_dev->dev.parent = &intf->dev;
 958
 959        input_set_drvdata(input_dev, yld);
 960
 961        input_dev->open = input_open;
 962        input_dev->close = input_close;
 963        /* input_dev->event = input_ev; TODO */
 964
 965        /* register available key events */
 966        input_dev->evbit[0] = BIT_MASK(EV_KEY);
 967        for (i = 0; i < 256; i++) {
 968                int k = map_p1k_to_key(i);
 969                if (k >= 0) {
 970                        set_bit(k & 0xff, input_dev->keybit);
 971                        if (k >> 8)
 972                                set_bit(k >> 8, input_dev->keybit);
 973                }
 974        }
 975
 976        ret = input_register_device(yld->idev);
 977        if (ret)
 978                return usb_cleanup(yld, ret);
 979
 980        usb_set_intfdata(intf, yld);
 981
 982        /* clear visible elements */
 983        for (i = 0; i < ARRAY_SIZE(lcdMap); i++)
 984                setChar(yld, i, ' ');
 985
 986        /* display driver version on LCD line 3 */
 987        store_line3(&intf->dev, NULL,
 988                        DRIVER_VERSION, sizeof(DRIVER_VERSION));
 989
 990        /* Register sysfs hooks (don't care about failure) */
 991        ret = sysfs_create_group(&intf->dev.kobj, &yld_attr_group);
 992        return 0;
 993}
 994
 995static struct usb_driver yealink_driver = {
 996        .name           = "yealink",
 997        .probe          = usb_probe,
 998        .disconnect     = usb_disconnect,
 999        .id_table       = usb_table,
1000};
1001
1002module_usb_driver(yealink_driver);
1003
1004MODULE_DEVICE_TABLE (usb, usb_table);
1005
1006MODULE_AUTHOR(DRIVER_AUTHOR);
1007MODULE_DESCRIPTION(DRIVER_DESC);
1008MODULE_LICENSE("GPL");
1009