0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036 #include <linux/kernel.h>
0037 #include <linux/slab.h>
0038 #include <linux/module.h>
0039 #include <linux/rwsem.h>
0040 #include <linux/usb/input.h>
0041 #include <linux/map_to_7segment.h>
0042
0043 #include "yealink.h"
0044
0045 #define DRIVER_VERSION "yld-20051230"
0046
0047 #define YEALINK_POLLING_FREQUENCY 10
0048
0049 struct yld_status {
0050 u8 lcd[24];
0051 u8 led;
0052 u8 dialtone;
0053 u8 ringtone;
0054 u8 keynum;
0055 } __attribute__ ((packed));
0056
0057
0058
0059
0060 #define _LOC(k,l) { .a = (k), .m = (l) }
0061 #define _SEG(t, a, am, b, bm, c, cm, d, dm, e, em, f, fm, g, gm) \
0062 { .type = (t), \
0063 .u = { .s = { _LOC(a, am), _LOC(b, bm), _LOC(c, cm), \
0064 _LOC(d, dm), _LOC(e, em), _LOC(g, gm), \
0065 _LOC(f, fm) } } }
0066 #define _PIC(t, h, hm, n) \
0067 { .type = (t), \
0068 .u = { .p = { .name = (n), .a = (h), .m = (hm) } } }
0069
0070 static const struct lcd_segment_map {
0071 char type;
0072 union {
0073 struct pictogram_map {
0074 u8 a,m;
0075 char name[10];
0076 } p;
0077 struct segment_map {
0078 u8 a,m;
0079 } s[7];
0080 } u;
0081 } lcdMap[] = {
0082 #include "yealink.h"
0083 };
0084
0085 struct yealink_dev {
0086 struct input_dev *idev;
0087 struct usb_device *udev;
0088 struct usb_interface *intf;
0089
0090
0091 struct yld_ctl_packet *irq_data;
0092 dma_addr_t irq_dma;
0093 struct urb *urb_irq;
0094
0095
0096 struct yld_ctl_packet *ctl_data;
0097 dma_addr_t ctl_dma;
0098 struct usb_ctrlrequest *ctl_req;
0099 struct urb *urb_ctl;
0100
0101 char phys[64];
0102
0103 u8 lcdMap[ARRAY_SIZE(lcdMap)];
0104 int key_code;
0105
0106 unsigned int shutdown:1;
0107
0108 int stat_ix;
0109 union {
0110 struct yld_status s;
0111 u8 b[sizeof(struct yld_status)];
0112 } master, copy;
0113 };
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123 static SEG7_DEFAULT_MAP(map_seg7);
0124
0125
0126
0127
0128
0129 static int setChar(struct yealink_dev *yld, int el, int chr)
0130 {
0131 int i, a, m, val;
0132
0133 if (el >= ARRAY_SIZE(lcdMap))
0134 return -EINVAL;
0135
0136 if (chr == '\t' || chr == '\n')
0137 return 0;
0138
0139 yld->lcdMap[el] = chr;
0140
0141 if (lcdMap[el].type == '.') {
0142 a = lcdMap[el].u.p.a;
0143 m = lcdMap[el].u.p.m;
0144 if (chr != ' ')
0145 yld->master.b[a] |= m;
0146 else
0147 yld->master.b[a] &= ~m;
0148 return 0;
0149 }
0150
0151 val = map_to_seg7(&map_seg7, chr);
0152 for (i = 0; i < ARRAY_SIZE(lcdMap[0].u.s); i++) {
0153 m = lcdMap[el].u.s[i].m;
0154
0155 if (m == 0)
0156 continue;
0157
0158 a = lcdMap[el].u.s[i].a;
0159 if (val & 1)
0160 yld->master.b[a] |= m;
0161 else
0162 yld->master.b[a] &= ~m;
0163 val = val >> 1;
0164 }
0165 return 0;
0166 };
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188
0189
0190 static int map_p1k_to_key(int scancode)
0191 {
0192 switch(scancode) {
0193 case 0x23: return KEY_LEFT;
0194 case 0x33: return KEY_UP;
0195 case 0x04: return KEY_RIGHT;
0196 case 0x24: return KEY_DOWN;
0197 case 0x03: return KEY_ENTER;
0198 case 0x14: return KEY_BACKSPACE;
0199 case 0x13: return KEY_ESC;
0200 case 0x00: return KEY_1;
0201 case 0x01: return KEY_2;
0202 case 0x02: return KEY_3;
0203 case 0x10: return KEY_4;
0204 case 0x11: return KEY_5;
0205 case 0x12: return KEY_6;
0206 case 0x20: return KEY_7;
0207 case 0x21: return KEY_8;
0208 case 0x22: return KEY_9;
0209 case 0x30: return KEY_KPASTERISK;
0210 case 0x31: return KEY_0;
0211 case 0x32: return KEY_LEFTSHIFT |
0212 KEY_3 << 8;
0213 }
0214 return -EINVAL;
0215 }
0216
0217
0218
0219
0220
0221
0222 static void report_key(struct yealink_dev *yld, int key)
0223 {
0224 struct input_dev *idev = yld->idev;
0225
0226 if (yld->key_code >= 0) {
0227
0228 input_report_key(idev, yld->key_code & 0xff, 0);
0229 if (yld->key_code >> 8)
0230 input_report_key(idev, yld->key_code >> 8, 0);
0231 }
0232
0233 yld->key_code = key;
0234 if (key >= 0) {
0235
0236 input_report_key(idev, key & 0xff, 1);
0237 if (key >> 8)
0238 input_report_key(idev, key >> 8, 1);
0239 }
0240 input_sync(idev);
0241 }
0242
0243
0244
0245
0246
0247 static int yealink_cmd(struct yealink_dev *yld, struct yld_ctl_packet *p)
0248 {
0249 u8 *buf = (u8 *)p;
0250 int i;
0251 u8 sum = 0;
0252
0253 for(i=0; i<USB_PKT_LEN-1; i++)
0254 sum -= buf[i];
0255 p->sum = sum;
0256 return usb_control_msg(yld->udev,
0257 usb_sndctrlpipe(yld->udev, 0),
0258 USB_REQ_SET_CONFIGURATION,
0259 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
0260 0x200, 3,
0261 p, sizeof(*p),
0262 USB_CTRL_SET_TIMEOUT);
0263 }
0264
0265 static u8 default_ringtone[] = {
0266 0xEF,
0267 0xFB, 0x1E, 0x00, 0x0C,
0268 0xFC, 0x18, 0x00, 0x0C,
0269 0xFB, 0x1E, 0x00, 0x0C,
0270 0xFC, 0x18, 0x00, 0x0C,
0271 0xFB, 0x1E, 0x00, 0x0C,
0272 0xFC, 0x18, 0x00, 0x0C,
0273 0xFB, 0x1E, 0x00, 0x0C,
0274 0xFC, 0x18, 0x00, 0x0C,
0275 0xFF, 0xFF, 0x01, 0x90,
0276 0x00, 0x00
0277 };
0278
0279 static int yealink_set_ringtone(struct yealink_dev *yld, u8 *buf, size_t size)
0280 {
0281 struct yld_ctl_packet *p = yld->ctl_data;
0282 int ix, len;
0283
0284 if (size <= 0)
0285 return -EINVAL;
0286
0287
0288 memset(yld->ctl_data, 0, sizeof(*(yld->ctl_data)));
0289 yld->ctl_data->cmd = CMD_RING_VOLUME;
0290 yld->ctl_data->size = 1;
0291 yld->ctl_data->data[0] = buf[0];
0292 yealink_cmd(yld, p);
0293
0294 buf++;
0295 size--;
0296
0297 p->cmd = CMD_RING_NOTE;
0298 ix = 0;
0299 while (size != ix) {
0300 len = size - ix;
0301 if (len > sizeof(p->data))
0302 len = sizeof(p->data);
0303 p->size = len;
0304 p->offset = cpu_to_be16(ix);
0305 memcpy(p->data, &buf[ix], len);
0306 yealink_cmd(yld, p);
0307 ix += len;
0308 }
0309 return 0;
0310 }
0311
0312
0313
0314 static int yealink_do_idle_tasks(struct yealink_dev *yld)
0315 {
0316 u8 val;
0317 int i, ix, len;
0318
0319 ix = yld->stat_ix;
0320
0321 memset(yld->ctl_data, 0, sizeof(*(yld->ctl_data)));
0322 yld->ctl_data->cmd = CMD_KEYPRESS;
0323 yld->ctl_data->size = 1;
0324 yld->ctl_data->sum = 0xff - CMD_KEYPRESS;
0325
0326
0327 if (ix >= sizeof(yld->master)) {
0328 yld->stat_ix = 0;
0329 return 0;
0330 }
0331
0332
0333 do {
0334 val = yld->master.b[ix];
0335 if (val != yld->copy.b[ix])
0336 goto send_update;
0337 } while (++ix < sizeof(yld->master));
0338
0339
0340 yld->stat_ix = 0;
0341
0342
0343
0344 return 0;
0345
0346 send_update:
0347
0348
0349 yld->copy.b[ix] = val;
0350 yld->ctl_data->data[0] = val;
0351
0352 switch(ix) {
0353 case offsetof(struct yld_status, led):
0354 yld->ctl_data->cmd = CMD_LED;
0355 yld->ctl_data->sum = -1 - CMD_LED - val;
0356 break;
0357 case offsetof(struct yld_status, dialtone):
0358 yld->ctl_data->cmd = CMD_DIALTONE;
0359 yld->ctl_data->sum = -1 - CMD_DIALTONE - val;
0360 break;
0361 case offsetof(struct yld_status, ringtone):
0362 yld->ctl_data->cmd = CMD_RINGTONE;
0363 yld->ctl_data->sum = -1 - CMD_RINGTONE - val;
0364 break;
0365 case offsetof(struct yld_status, keynum):
0366 val--;
0367 val &= 0x1f;
0368 yld->ctl_data->cmd = CMD_SCANCODE;
0369 yld->ctl_data->offset = cpu_to_be16(val);
0370 yld->ctl_data->data[0] = 0;
0371 yld->ctl_data->sum = -1 - CMD_SCANCODE - val;
0372 break;
0373 default:
0374 len = sizeof(yld->master.s.lcd) - ix;
0375 if (len > sizeof(yld->ctl_data->data))
0376 len = sizeof(yld->ctl_data->data);
0377
0378
0379
0380 yld->ctl_data->cmd = CMD_LCD;
0381 yld->ctl_data->offset = cpu_to_be16(ix);
0382 yld->ctl_data->size = len;
0383 yld->ctl_data->sum = -CMD_LCD - ix - val - len;
0384 for(i=1; i<len; i++) {
0385 ix++;
0386 val = yld->master.b[ix];
0387 yld->copy.b[ix] = val;
0388 yld->ctl_data->data[i] = val;
0389 yld->ctl_data->sum -= val;
0390 }
0391 }
0392 yld->stat_ix = ix + 1;
0393 return 1;
0394 }
0395
0396
0397
0398
0399
0400
0401
0402
0403
0404
0405
0406
0407
0408
0409
0410 static void urb_irq_callback(struct urb *urb)
0411 {
0412 struct yealink_dev *yld = urb->context;
0413 int ret, status = urb->status;
0414
0415 if (status)
0416 dev_err(&yld->intf->dev, "%s - urb status %d\n",
0417 __func__, status);
0418
0419 switch (yld->irq_data->cmd) {
0420 case CMD_KEYPRESS:
0421
0422 yld->master.s.keynum = yld->irq_data->data[0];
0423 break;
0424
0425 case CMD_SCANCODE:
0426 dev_dbg(&yld->intf->dev, "get scancode %x\n",
0427 yld->irq_data->data[0]);
0428
0429 report_key(yld, map_p1k_to_key(yld->irq_data->data[0]));
0430 break;
0431
0432 default:
0433 dev_err(&yld->intf->dev, "unexpected response %x\n",
0434 yld->irq_data->cmd);
0435 }
0436
0437 yealink_do_idle_tasks(yld);
0438
0439 if (!yld->shutdown) {
0440 ret = usb_submit_urb(yld->urb_ctl, GFP_ATOMIC);
0441 if (ret && ret != -EPERM)
0442 dev_err(&yld->intf->dev,
0443 "%s - usb_submit_urb failed %d\n",
0444 __func__, ret);
0445 }
0446 }
0447
0448 static void urb_ctl_callback(struct urb *urb)
0449 {
0450 struct yealink_dev *yld = urb->context;
0451 int ret = 0, status = urb->status;
0452
0453 if (status)
0454 dev_err(&yld->intf->dev, "%s - urb status %d\n",
0455 __func__, status);
0456
0457 switch (yld->ctl_data->cmd) {
0458 case CMD_KEYPRESS:
0459 case CMD_SCANCODE:
0460
0461 if (!yld->shutdown)
0462 ret = usb_submit_urb(yld->urb_irq, GFP_ATOMIC);
0463 break;
0464 default:
0465
0466 yealink_do_idle_tasks(yld);
0467 if (!yld->shutdown)
0468 ret = usb_submit_urb(yld->urb_ctl, GFP_ATOMIC);
0469 break;
0470 }
0471
0472 if (ret && ret != -EPERM)
0473 dev_err(&yld->intf->dev, "%s - usb_submit_urb failed %d\n",
0474 __func__, ret);
0475 }
0476
0477
0478
0479
0480
0481
0482
0483
0484
0485
0486
0487
0488
0489
0490
0491
0492
0493
0494
0495
0496
0497
0498
0499
0500
0501 static int input_open(struct input_dev *dev)
0502 {
0503 struct yealink_dev *yld = input_get_drvdata(dev);
0504 int i, ret;
0505
0506 dev_dbg(&yld->intf->dev, "%s\n", __func__);
0507
0508
0509 for (i = 0; i<sizeof(yld->master); i++)
0510 yld->copy.b[i] = ~yld->master.b[i];
0511 yld->key_code = -1;
0512
0513 yealink_set_ringtone(yld, default_ringtone, sizeof(default_ringtone));
0514
0515
0516 memset(yld->ctl_data, 0, sizeof(*(yld->ctl_data)));
0517 yld->ctl_data->cmd = CMD_INIT;
0518 yld->ctl_data->size = 10;
0519 yld->ctl_data->sum = 0x100-CMD_INIT-10;
0520 if ((ret = usb_submit_urb(yld->urb_ctl, GFP_KERNEL)) != 0) {
0521 dev_dbg(&yld->intf->dev,
0522 "%s - usb_submit_urb failed with result %d\n",
0523 __func__, ret);
0524 return ret;
0525 }
0526 return 0;
0527 }
0528
0529 static void input_close(struct input_dev *dev)
0530 {
0531 struct yealink_dev *yld = input_get_drvdata(dev);
0532
0533 yld->shutdown = 1;
0534
0535
0536
0537
0538 smp_wmb();
0539
0540 usb_kill_urb(yld->urb_ctl);
0541 usb_kill_urb(yld->urb_irq);
0542
0543 yld->shutdown = 0;
0544 smp_wmb();
0545 }
0546
0547
0548
0549
0550
0551 static DECLARE_RWSEM(sysfs_rwsema);
0552
0553
0554
0555 static ssize_t show_map(struct device *dev, struct device_attribute *attr,
0556 char *buf)
0557 {
0558 memcpy(buf, &map_seg7, sizeof(map_seg7));
0559 return sizeof(map_seg7);
0560 }
0561
0562 static ssize_t store_map(struct device *dev, struct device_attribute *attr,
0563 const char *buf, size_t cnt)
0564 {
0565 if (cnt != sizeof(map_seg7))
0566 return -EINVAL;
0567 memcpy(&map_seg7, buf, sizeof(map_seg7));
0568 return sizeof(map_seg7);
0569 }
0570
0571
0572
0573
0574
0575
0576
0577
0578
0579
0580
0581 static ssize_t show_line(struct device *dev, char *buf, int a, int b)
0582 {
0583 struct yealink_dev *yld;
0584 int i;
0585
0586 down_read(&sysfs_rwsema);
0587 yld = dev_get_drvdata(dev);
0588 if (yld == NULL) {
0589 up_read(&sysfs_rwsema);
0590 return -ENODEV;
0591 }
0592
0593 for (i = a; i < b; i++)
0594 *buf++ = lcdMap[i].type;
0595 *buf++ = '\n';
0596 for (i = a; i < b; i++)
0597 *buf++ = yld->lcdMap[i];
0598 *buf++ = '\n';
0599 *buf = 0;
0600
0601 up_read(&sysfs_rwsema);
0602 return 3 + ((b - a) << 1);
0603 }
0604
0605 static ssize_t show_line1(struct device *dev, struct device_attribute *attr,
0606 char *buf)
0607 {
0608 return show_line(dev, buf, LCD_LINE1_OFFSET, LCD_LINE2_OFFSET);
0609 }
0610
0611 static ssize_t show_line2(struct device *dev, struct device_attribute *attr,
0612 char *buf)
0613 {
0614 return show_line(dev, buf, LCD_LINE2_OFFSET, LCD_LINE3_OFFSET);
0615 }
0616
0617 static ssize_t show_line3(struct device *dev, struct device_attribute *attr,
0618 char *buf)
0619 {
0620 return show_line(dev, buf, LCD_LINE3_OFFSET, LCD_LINE4_OFFSET);
0621 }
0622
0623
0624
0625
0626
0627
0628
0629
0630 static ssize_t store_line(struct device *dev, const char *buf, size_t count,
0631 int el, size_t len)
0632 {
0633 struct yealink_dev *yld;
0634 int i;
0635
0636 down_write(&sysfs_rwsema);
0637 yld = dev_get_drvdata(dev);
0638 if (yld == NULL) {
0639 up_write(&sysfs_rwsema);
0640 return -ENODEV;
0641 }
0642
0643 if (len > count)
0644 len = count;
0645 for (i = 0; i < len; i++)
0646 setChar(yld, el++, buf[i]);
0647
0648 up_write(&sysfs_rwsema);
0649 return count;
0650 }
0651
0652 static ssize_t store_line1(struct device *dev, struct device_attribute *attr,
0653 const char *buf, size_t count)
0654 {
0655 return store_line(dev, buf, count, LCD_LINE1_OFFSET, LCD_LINE1_SIZE);
0656 }
0657
0658 static ssize_t store_line2(struct device *dev, struct device_attribute *attr,
0659 const char *buf, size_t count)
0660 {
0661 return store_line(dev, buf, count, LCD_LINE2_OFFSET, LCD_LINE2_SIZE);
0662 }
0663
0664 static ssize_t store_line3(struct device *dev, struct device_attribute *attr,
0665 const char *buf, size_t count)
0666 {
0667 return store_line(dev, buf, count, LCD_LINE3_OFFSET, LCD_LINE3_SIZE);
0668 }
0669
0670
0671
0672
0673
0674
0675 static ssize_t get_icons(struct device *dev, struct device_attribute *attr,
0676 char *buf)
0677 {
0678 struct yealink_dev *yld;
0679 int i, ret = 1;
0680
0681 down_read(&sysfs_rwsema);
0682 yld = dev_get_drvdata(dev);
0683 if (yld == NULL) {
0684 up_read(&sysfs_rwsema);
0685 return -ENODEV;
0686 }
0687
0688 for (i = 0; i < ARRAY_SIZE(lcdMap); i++) {
0689 if (lcdMap[i].type != '.')
0690 continue;
0691 ret += sprintf(&buf[ret], "%s %s\n",
0692 yld->lcdMap[i] == ' ' ? " " : "on",
0693 lcdMap[i].u.p.name);
0694 }
0695 up_read(&sysfs_rwsema);
0696 return ret;
0697 }
0698
0699
0700 static ssize_t set_icon(struct device *dev, const char *buf, size_t count,
0701 int chr)
0702 {
0703 struct yealink_dev *yld;
0704 int i;
0705
0706 down_write(&sysfs_rwsema);
0707 yld = dev_get_drvdata(dev);
0708 if (yld == NULL) {
0709 up_write(&sysfs_rwsema);
0710 return -ENODEV;
0711 }
0712
0713 for (i = 0; i < ARRAY_SIZE(lcdMap); i++) {
0714 if (lcdMap[i].type != '.')
0715 continue;
0716 if (strncmp(buf, lcdMap[i].u.p.name, count) == 0) {
0717 setChar(yld, i, chr);
0718 break;
0719 }
0720 }
0721
0722 up_write(&sysfs_rwsema);
0723 return count;
0724 }
0725
0726 static ssize_t show_icon(struct device *dev, struct device_attribute *attr,
0727 const char *buf, size_t count)
0728 {
0729 return set_icon(dev, buf, count, buf[0]);
0730 }
0731
0732 static ssize_t hide_icon(struct device *dev, struct device_attribute *attr,
0733 const char *buf, size_t count)
0734 {
0735 return set_icon(dev, buf, count, ' ');
0736 }
0737
0738
0739
0740
0741
0742 static ssize_t store_ringtone(struct device *dev,
0743 struct device_attribute *attr,
0744 const char *buf, size_t count)
0745 {
0746 struct yealink_dev *yld;
0747
0748 down_write(&sysfs_rwsema);
0749 yld = dev_get_drvdata(dev);
0750 if (yld == NULL) {
0751 up_write(&sysfs_rwsema);
0752 return -ENODEV;
0753 }
0754
0755
0756 yealink_set_ringtone(yld, (char *)buf, count);
0757 up_write(&sysfs_rwsema);
0758 return count;
0759 }
0760
0761 #define _M444 S_IRUGO
0762 #define _M664 S_IRUGO|S_IWUSR|S_IWGRP
0763 #define _M220 S_IWUSR|S_IWGRP
0764
0765 static DEVICE_ATTR(map_seg7 , _M664, show_map , store_map );
0766 static DEVICE_ATTR(line1 , _M664, show_line1 , store_line1 );
0767 static DEVICE_ATTR(line2 , _M664, show_line2 , store_line2 );
0768 static DEVICE_ATTR(line3 , _M664, show_line3 , store_line3 );
0769 static DEVICE_ATTR(get_icons , _M444, get_icons , NULL );
0770 static DEVICE_ATTR(show_icon , _M220, NULL , show_icon );
0771 static DEVICE_ATTR(hide_icon , _M220, NULL , hide_icon );
0772 static DEVICE_ATTR(ringtone , _M220, NULL , store_ringtone);
0773
0774 static struct attribute *yld_attributes[] = {
0775 &dev_attr_line1.attr,
0776 &dev_attr_line2.attr,
0777 &dev_attr_line3.attr,
0778 &dev_attr_get_icons.attr,
0779 &dev_attr_show_icon.attr,
0780 &dev_attr_hide_icon.attr,
0781 &dev_attr_map_seg7.attr,
0782 &dev_attr_ringtone.attr,
0783 NULL
0784 };
0785
0786 static const struct attribute_group yld_attr_group = {
0787 .attrs = yld_attributes
0788 };
0789
0790
0791
0792
0793
0794 struct driver_info {
0795 char *name;
0796 };
0797
0798 static const struct driver_info info_P1K = {
0799 .name = "Yealink usb-p1k",
0800 };
0801
0802 static const struct usb_device_id usb_table [] = {
0803 {
0804 .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
0805 USB_DEVICE_ID_MATCH_INT_INFO,
0806 .idVendor = 0x6993,
0807 .idProduct = 0xb001,
0808 .bInterfaceClass = USB_CLASS_HID,
0809 .bInterfaceSubClass = 0,
0810 .bInterfaceProtocol = 0,
0811 .driver_info = (kernel_ulong_t)&info_P1K
0812 },
0813 { }
0814 };
0815
0816 static int usb_cleanup(struct yealink_dev *yld, int err)
0817 {
0818 if (yld == NULL)
0819 return err;
0820
0821 if (yld->idev) {
0822 if (err)
0823 input_free_device(yld->idev);
0824 else
0825 input_unregister_device(yld->idev);
0826 }
0827
0828 usb_free_urb(yld->urb_irq);
0829 usb_free_urb(yld->urb_ctl);
0830
0831 kfree(yld->ctl_req);
0832 usb_free_coherent(yld->udev, USB_PKT_LEN, yld->ctl_data, yld->ctl_dma);
0833 usb_free_coherent(yld->udev, USB_PKT_LEN, yld->irq_data, yld->irq_dma);
0834
0835 kfree(yld);
0836 return err;
0837 }
0838
0839 static void usb_disconnect(struct usb_interface *intf)
0840 {
0841 struct yealink_dev *yld;
0842
0843 down_write(&sysfs_rwsema);
0844 yld = usb_get_intfdata(intf);
0845 sysfs_remove_group(&intf->dev.kobj, &yld_attr_group);
0846 usb_set_intfdata(intf, NULL);
0847 up_write(&sysfs_rwsema);
0848
0849 usb_cleanup(yld, 0);
0850 }
0851
0852 static int usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
0853 {
0854 struct usb_device *udev = interface_to_usbdev (intf);
0855 struct driver_info *nfo = (struct driver_info *)id->driver_info;
0856 struct usb_host_interface *interface;
0857 struct usb_endpoint_descriptor *endpoint;
0858 struct yealink_dev *yld;
0859 struct input_dev *input_dev;
0860 int ret, pipe, i;
0861
0862 interface = intf->cur_altsetting;
0863
0864 if (interface->desc.bNumEndpoints < 1)
0865 return -ENODEV;
0866
0867 endpoint = &interface->endpoint[0].desc;
0868 if (!usb_endpoint_is_int_in(endpoint))
0869 return -ENODEV;
0870
0871 yld = kzalloc(sizeof(struct yealink_dev), GFP_KERNEL);
0872 if (!yld)
0873 return -ENOMEM;
0874
0875 yld->udev = udev;
0876 yld->intf = intf;
0877
0878 yld->idev = input_dev = input_allocate_device();
0879 if (!input_dev)
0880 return usb_cleanup(yld, -ENOMEM);
0881
0882
0883 yld->irq_data = usb_alloc_coherent(udev, USB_PKT_LEN,
0884 GFP_KERNEL, &yld->irq_dma);
0885 if (yld->irq_data == NULL)
0886 return usb_cleanup(yld, -ENOMEM);
0887
0888 yld->ctl_data = usb_alloc_coherent(udev, USB_PKT_LEN,
0889 GFP_KERNEL, &yld->ctl_dma);
0890 if (!yld->ctl_data)
0891 return usb_cleanup(yld, -ENOMEM);
0892
0893 yld->ctl_req = kmalloc(sizeof(*(yld->ctl_req)), GFP_KERNEL);
0894 if (yld->ctl_req == NULL)
0895 return usb_cleanup(yld, -ENOMEM);
0896
0897
0898 yld->urb_irq = usb_alloc_urb(0, GFP_KERNEL);
0899 if (yld->urb_irq == NULL)
0900 return usb_cleanup(yld, -ENOMEM);
0901
0902 yld->urb_ctl = usb_alloc_urb(0, GFP_KERNEL);
0903 if (yld->urb_ctl == NULL)
0904 return usb_cleanup(yld, -ENOMEM);
0905
0906
0907 pipe = usb_rcvintpipe(udev, endpoint->bEndpointAddress);
0908 ret = usb_maxpacket(udev, pipe);
0909 if (ret != USB_PKT_LEN)
0910 dev_err(&intf->dev, "invalid payload size %d, expected %zd\n",
0911 ret, USB_PKT_LEN);
0912
0913
0914 usb_fill_int_urb(yld->urb_irq, udev, pipe, yld->irq_data,
0915 USB_PKT_LEN,
0916 urb_irq_callback,
0917 yld, endpoint->bInterval);
0918 yld->urb_irq->transfer_dma = yld->irq_dma;
0919 yld->urb_irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
0920 yld->urb_irq->dev = udev;
0921
0922
0923 yld->ctl_req->bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE |
0924 USB_DIR_OUT;
0925 yld->ctl_req->bRequest = USB_REQ_SET_CONFIGURATION;
0926 yld->ctl_req->wValue = cpu_to_le16(0x200);
0927 yld->ctl_req->wIndex = cpu_to_le16(interface->desc.bInterfaceNumber);
0928 yld->ctl_req->wLength = cpu_to_le16(USB_PKT_LEN);
0929
0930 usb_fill_control_urb(yld->urb_ctl, udev, usb_sndctrlpipe(udev, 0),
0931 (void *)yld->ctl_req, yld->ctl_data, USB_PKT_LEN,
0932 urb_ctl_callback, yld);
0933 yld->urb_ctl->transfer_dma = yld->ctl_dma;
0934 yld->urb_ctl->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
0935 yld->urb_ctl->dev = udev;
0936
0937
0938 usb_make_path(udev, yld->phys, sizeof(yld->phys));
0939 strlcat(yld->phys, "/input0", sizeof(yld->phys));
0940
0941
0942 input_dev->name = nfo->name;
0943 input_dev->phys = yld->phys;
0944 usb_to_input_id(udev, &input_dev->id);
0945 input_dev->dev.parent = &intf->dev;
0946
0947 input_set_drvdata(input_dev, yld);
0948
0949 input_dev->open = input_open;
0950 input_dev->close = input_close;
0951
0952
0953
0954 input_dev->evbit[0] = BIT_MASK(EV_KEY);
0955 for (i = 0; i < 256; i++) {
0956 int k = map_p1k_to_key(i);
0957 if (k >= 0) {
0958 set_bit(k & 0xff, input_dev->keybit);
0959 if (k >> 8)
0960 set_bit(k >> 8, input_dev->keybit);
0961 }
0962 }
0963
0964 ret = input_register_device(yld->idev);
0965 if (ret)
0966 return usb_cleanup(yld, ret);
0967
0968 usb_set_intfdata(intf, yld);
0969
0970
0971 for (i = 0; i < ARRAY_SIZE(lcdMap); i++)
0972 setChar(yld, i, ' ');
0973
0974
0975 store_line3(&intf->dev, NULL,
0976 DRIVER_VERSION, sizeof(DRIVER_VERSION));
0977
0978
0979 ret = sysfs_create_group(&intf->dev.kobj, &yld_attr_group);
0980 return 0;
0981 }
0982
0983 static struct usb_driver yealink_driver = {
0984 .name = "yealink",
0985 .probe = usb_probe,
0986 .disconnect = usb_disconnect,
0987 .id_table = usb_table,
0988 };
0989
0990 module_usb_driver(yealink_driver);
0991
0992 MODULE_DEVICE_TABLE (usb, usb_table);
0993
0994 MODULE_AUTHOR("Henk Vergonet");
0995 MODULE_DESCRIPTION("Yealink phone driver");
0996 MODULE_LICENSE("GPL");