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/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");
1012