root/drivers/input/misc/yealink.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. setChar
  2. map_p1k_to_key
  3. report_key
  4. yealink_cmd
  5. yealink_set_ringtone
  6. yealink_do_idle_tasks
  7. urb_irq_callback
  8. urb_ctl_callback
  9. input_open
  10. input_close
  11. show_map
  12. store_map
  13. show_line
  14. show_line1
  15. show_line2
  16. show_line3
  17. store_line
  18. store_line1
  19. store_line2
  20. store_line3
  21. get_icons
  22. set_icon
  23. show_icon
  24. hide_icon
  25. store_ringtone
  26. usb_cleanup
  27. usb_disconnect
  28. usb_probe

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

/* [<][>][^][v][top][bottom][index][help] */