Lines Matching +full:gpio +full:- +full:keymap
1 // SPDX-License-Identifier: GPL-2.0-only
5 * Copyright (C) 2007 - 2008 Alfred E. Heggestad <aeh@db.org>
10 * - Komunikate KIP1000
11 * - Genius G-talk
12 * - Allied-Telesis Corega USBPH01
13 * - ...
18 * - Authors of yealink.c
19 * - Thomas Reitmayr
20 * - Oliver Neukum for good review comments and code
21 * - Shaun Jackman <sjackman@gmail.com> for Genius G-talk keymap
22 * - Dmitry Torokhov for valuable input and review
25 * - Read/write EEPROM
46 HID_IR0 = 0x00, /* Record/Playback-mute button, Volume up/down */
51 HID_OR1 = 0x01, /* GPO - General Purpose Output */
52 HID_OR2 = 0x02, /* Set GPIO to input/output mode */
62 /* bits 7-6
63 0: HID_OR1-2 are used for GPO; HID_OR0, 3 are used for buzzer
65 1: HID_OR0-3 are used as generic HID registers
66 2: Values written to HID_OR0-3 are also mapped to MCU_CTRL,
67 EEPROM_DATA0-1, EEPROM_CTRL (see Note)
123 unsigned short keymap[KEYMAP_SIZE]; member
138 switch (code - 0xff) { in special_keymap()
156 -> -- 1 -- 2 -- 3 --> GPI pin 4 (0x10)
158 <- -- 4 -- 5 -- 6 --> GPI pin 5 (0x20)
160 END - 7 -- 8 -- 9 --> GPI pin 6 (0x40)
162 OK -- * -- 0 -- # --> GPI pin 7 (0x80)
198 Genius G-Talk keyboard matrix
229 * Keymap for Allied-Telesis Corega USBPH01
230 * http://www.alliedtelesis-corega.com/2/1344/1437/1360/chprd.html
258 * Keymap for ATCom AU-100
261 * http://www.voip-info.org/wiki/view/AU-100
263 * Contributed by daniel@gimpelevich.san-francisco.ca.us
288 static unsigned short (*keymap)(int) = keymap_kip1000; variable
296 struct input_dev *idev = dev->idev; in report_key()
298 if (dev->key_code >= 0) { in report_key()
300 input_report_key(idev, dev->key_code, 0); in report_key()
303 dev->key_code = key; in report_key()
314 * for the input subsystem, sends press-n-release for mute keys.
319 struct input_dev *idev = dev->idev; in cm109_report_special()
320 u8 data = dev->irq_data->byte[HID_IR0]; in cm109_report_special()
325 keycode = dev->keymap[0xff + BIT(i)]; in cm109_report_special()
346 if (dev->buzzer_state) in cm109_submit_buzz_toggle()
347 dev->ctl_data->byte[HID_OR0] |= BUZZER_ON; in cm109_submit_buzz_toggle()
349 dev->ctl_data->byte[HID_OR0] &= ~BUZZER_ON; in cm109_submit_buzz_toggle()
351 error = usb_submit_urb(dev->urb_ctl, GFP_ATOMIC); in cm109_submit_buzz_toggle()
353 dev_err(&dev->intf->dev, in cm109_submit_buzz_toggle()
363 struct cm109_dev *dev = urb->context; in cm109_urb_irq_callback()
364 const int status = urb->status; in cm109_urb_irq_callback()
368 dev_dbg(&dev->intf->dev, "### URB IRQ: [0x%02x 0x%02x 0x%02x 0x%02x] keybit=0x%02x\n", in cm109_urb_irq_callback()
369 dev->irq_data->byte[0], in cm109_urb_irq_callback()
370 dev->irq_data->byte[1], in cm109_urb_irq_callback()
371 dev->irq_data->byte[2], in cm109_urb_irq_callback()
372 dev->irq_data->byte[3], in cm109_urb_irq_callback()
373 dev->keybit); in cm109_urb_irq_callback()
376 if (status == -ESHUTDOWN) in cm109_urb_irq_callback()
378 dev_err_ratelimited(&dev->intf->dev, "%s: urb status %d\n", in cm109_urb_irq_callback()
387 if (dev->keybit == 0xf) { in cm109_urb_irq_callback()
390 if ((dev->gpi & 0xf0) == (dev->irq_data->byte[HID_IR1] & 0xf0)) in cm109_urb_irq_callback()
393 dev->gpi = dev->irq_data->byte[HID_IR1] & 0xf0; in cm109_urb_irq_callback()
394 dev->keybit = 0x1; in cm109_urb_irq_callback()
396 report_key(dev, dev->keymap[dev->irq_data->byte[HID_IR1]]); in cm109_urb_irq_callback()
398 dev->keybit <<= 1; in cm109_urb_irq_callback()
399 if (dev->keybit > 0x8) in cm109_urb_irq_callback()
400 dev->keybit = 0xf; in cm109_urb_irq_callback()
405 spin_lock_irqsave(&dev->ctl_submit_lock, flags); in cm109_urb_irq_callback()
407 dev->irq_urb_pending = 0; in cm109_urb_irq_callback()
409 if (likely(!dev->shutdown)) { in cm109_urb_irq_callback()
411 if (dev->buzzer_state) in cm109_urb_irq_callback()
412 dev->ctl_data->byte[HID_OR0] |= BUZZER_ON; in cm109_urb_irq_callback()
414 dev->ctl_data->byte[HID_OR0] &= ~BUZZER_ON; in cm109_urb_irq_callback()
416 dev->ctl_data->byte[HID_OR1] = dev->keybit; in cm109_urb_irq_callback()
417 dev->ctl_data->byte[HID_OR2] = dev->keybit; in cm109_urb_irq_callback()
419 dev->buzzer_pending = 0; in cm109_urb_irq_callback()
420 dev->ctl_urb_pending = 1; in cm109_urb_irq_callback()
422 error = usb_submit_urb(dev->urb_ctl, GFP_ATOMIC); in cm109_urb_irq_callback()
424 dev_err(&dev->intf->dev, in cm109_urb_irq_callback()
429 spin_unlock_irqrestore(&dev->ctl_submit_lock, flags); in cm109_urb_irq_callback()
434 struct cm109_dev *dev = urb->context; in cm109_urb_ctl_callback()
435 const int status = urb->status; in cm109_urb_ctl_callback()
439 dev_dbg(&dev->intf->dev, "### URB CTL: [0x%02x 0x%02x 0x%02x 0x%02x]\n", in cm109_urb_ctl_callback()
440 dev->ctl_data->byte[0], in cm109_urb_ctl_callback()
441 dev->ctl_data->byte[1], in cm109_urb_ctl_callback()
442 dev->ctl_data->byte[2], in cm109_urb_ctl_callback()
443 dev->ctl_data->byte[3]); in cm109_urb_ctl_callback()
446 if (status == -ESHUTDOWN) in cm109_urb_ctl_callback()
448 dev_err_ratelimited(&dev->intf->dev, "%s: urb status %d\n", in cm109_urb_ctl_callback()
452 spin_lock_irqsave(&dev->ctl_submit_lock, flags); in cm109_urb_ctl_callback()
454 dev->ctl_urb_pending = 0; in cm109_urb_ctl_callback()
456 if (likely(!dev->shutdown)) { in cm109_urb_ctl_callback()
458 if (dev->buzzer_pending || status) { in cm109_urb_ctl_callback()
459 dev->buzzer_pending = 0; in cm109_urb_ctl_callback()
460 dev->ctl_urb_pending = 1; in cm109_urb_ctl_callback()
462 } else if (likely(!dev->irq_urb_pending)) { in cm109_urb_ctl_callback()
464 dev->irq_urb_pending = 1; in cm109_urb_ctl_callback()
465 error = usb_submit_urb(dev->urb_irq, GFP_ATOMIC); in cm109_urb_ctl_callback()
467 dev_err(&dev->intf->dev, in cm109_urb_ctl_callback()
473 spin_unlock_irqrestore(&dev->ctl_submit_lock, flags); in cm109_urb_ctl_callback()
480 spin_lock_irqsave(&dev->ctl_submit_lock, flags); in cm109_toggle_buzzer_async()
482 if (dev->ctl_urb_pending) { in cm109_toggle_buzzer_async()
484 dev->buzzer_pending = 1; in cm109_toggle_buzzer_async()
486 dev->ctl_urb_pending = 1; in cm109_toggle_buzzer_async()
490 spin_unlock_irqrestore(&dev->ctl_submit_lock, flags); in cm109_toggle_buzzer_async()
498 dev->ctl_data->byte[HID_OR0] |= BUZZER_ON; in cm109_toggle_buzzer_sync()
500 dev->ctl_data->byte[HID_OR0] &= ~BUZZER_ON; in cm109_toggle_buzzer_sync()
502 error = usb_control_msg(dev->udev, in cm109_toggle_buzzer_sync()
503 usb_sndctrlpipe(dev->udev, 0), in cm109_toggle_buzzer_sync()
504 dev->ctl_req->bRequest, in cm109_toggle_buzzer_sync()
505 dev->ctl_req->bRequestType, in cm109_toggle_buzzer_sync()
506 le16_to_cpu(dev->ctl_req->wValue), in cm109_toggle_buzzer_sync()
507 le16_to_cpu(dev->ctl_req->wIndex), in cm109_toggle_buzzer_sync()
508 dev->ctl_data, in cm109_toggle_buzzer_sync()
510 if (error < 0 && error != -EINTR) in cm109_toggle_buzzer_sync()
511 dev_err(&dev->intf->dev, "%s: usb_control_msg() failed %d\n", in cm109_toggle_buzzer_sync()
517 dev->shutdown = 1; in cm109_stop_traffic()
523 usb_kill_urb(dev->urb_ctl); in cm109_stop_traffic()
524 usb_kill_urb(dev->urb_irq); in cm109_stop_traffic()
528 dev->shutdown = 0; in cm109_stop_traffic()
534 if (dev->open) { in cm109_restore_state()
552 error = usb_autopm_get_interface(dev->intf); in cm109_input_open()
554 dev_err(&idev->dev, "%s - cannot autoresume, result %d\n", in cm109_input_open()
559 mutex_lock(&dev->pm_mutex); in cm109_input_open()
561 dev->buzzer_state = 0; in cm109_input_open()
562 dev->key_code = -1; /* no keys pressed */ in cm109_input_open()
563 dev->keybit = 0xf; in cm109_input_open()
566 dev->ctl_data->byte[HID_OR0] = HID_OR_GPO_BUZ_SPDIF; in cm109_input_open()
567 dev->ctl_data->byte[HID_OR1] = dev->keybit; in cm109_input_open()
568 dev->ctl_data->byte[HID_OR2] = dev->keybit; in cm109_input_open()
569 dev->ctl_data->byte[HID_OR3] = 0x00; in cm109_input_open()
571 dev->ctl_urb_pending = 1; in cm109_input_open()
572 error = usb_submit_urb(dev->urb_ctl, GFP_KERNEL); in cm109_input_open()
574 dev->ctl_urb_pending = 0; in cm109_input_open()
575 dev_err(&dev->intf->dev, "%s: usb_submit_urb (urb_ctl) failed %d\n", in cm109_input_open()
578 dev->open = 1; in cm109_input_open()
581 mutex_unlock(&dev->pm_mutex); in cm109_input_open()
584 usb_autopm_put_interface(dev->intf); in cm109_input_open()
593 mutex_lock(&dev->pm_mutex); in cm109_input_close()
601 dev->open = 0; in cm109_input_close()
603 mutex_unlock(&dev->pm_mutex); in cm109_input_close()
605 usb_autopm_put_interface(dev->intf); in cm109_input_close()
613 dev_dbg(&dev->intf->dev, in cm109_input_ev()
617 return -EINVAL; in cm109_input_ev()
622 dev->buzzer_state = !!value; in cm109_input_ev()
623 if (!dev->resetting) in cm109_input_ev()
628 return -EINVAL; in cm109_input_ev()
646 VENDOR_ID = 0x0d8c, /* C-Media Electronics */
647 PRODUCT_ID_CM109 = 0x000e, /* CM109 defines range 0x0008 - 0x000f */
662 /* you can add more devices here with product ID 0x0008 - 0x000f */
668 kfree(dev->ctl_req); in cm109_usb_cleanup()
669 usb_free_coherent(dev->udev, USB_PKT_LEN, dev->ctl_data, dev->ctl_dma); in cm109_usb_cleanup()
670 usb_free_coherent(dev->udev, USB_PKT_LEN, dev->irq_data, dev->irq_dma); in cm109_usb_cleanup()
672 usb_free_urb(dev->urb_irq); /* parameter validation in core/urb */ in cm109_usb_cleanup()
673 usb_free_urb(dev->urb_ctl); /* parameter validation in core/urb */ in cm109_usb_cleanup()
682 input_unregister_device(dev->idev); in cm109_usb_disconnect()
690 struct driver_info *nfo = (struct driver_info *)id->driver_info; in cm109_usb_probe()
696 int error = -ENOMEM; in cm109_usb_probe()
698 interface = intf->cur_altsetting; in cm109_usb_probe()
700 if (interface->desc.bNumEndpoints < 1) in cm109_usb_probe()
701 return -ENODEV; in cm109_usb_probe()
703 endpoint = &interface->endpoint[0].desc; in cm109_usb_probe()
706 return -ENODEV; in cm109_usb_probe()
710 return -ENOMEM; in cm109_usb_probe()
712 spin_lock_init(&dev->ctl_submit_lock); in cm109_usb_probe()
713 mutex_init(&dev->pm_mutex); in cm109_usb_probe()
715 dev->udev = udev; in cm109_usb_probe()
716 dev->intf = intf; in cm109_usb_probe()
718 dev->idev = input_dev = input_allocate_device(); in cm109_usb_probe()
723 dev->irq_data = usb_alloc_coherent(udev, USB_PKT_LEN, in cm109_usb_probe()
724 GFP_KERNEL, &dev->irq_dma); in cm109_usb_probe()
725 if (!dev->irq_data) in cm109_usb_probe()
728 dev->ctl_data = usb_alloc_coherent(udev, USB_PKT_LEN, in cm109_usb_probe()
729 GFP_KERNEL, &dev->ctl_dma); in cm109_usb_probe()
730 if (!dev->ctl_data) in cm109_usb_probe()
733 dev->ctl_req = kmalloc(sizeof(*(dev->ctl_req)), GFP_KERNEL); in cm109_usb_probe()
734 if (!dev->ctl_req) in cm109_usb_probe()
738 dev->urb_irq = usb_alloc_urb(0, GFP_KERNEL); in cm109_usb_probe()
739 if (!dev->urb_irq) in cm109_usb_probe()
742 dev->urb_ctl = usb_alloc_urb(0, GFP_KERNEL); in cm109_usb_probe()
743 if (!dev->urb_ctl) in cm109_usb_probe()
747 pipe = usb_rcvintpipe(udev, endpoint->bEndpointAddress); in cm109_usb_probe()
750 dev_err(&intf->dev, "invalid payload size %d, expected %d\n", in cm109_usb_probe()
754 usb_fill_int_urb(dev->urb_irq, udev, pipe, dev->irq_data, in cm109_usb_probe()
756 cm109_urb_irq_callback, dev, endpoint->bInterval); in cm109_usb_probe()
757 dev->urb_irq->transfer_dma = dev->irq_dma; in cm109_usb_probe()
758 dev->urb_irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; in cm109_usb_probe()
759 dev->urb_irq->dev = udev; in cm109_usb_probe()
762 dev->ctl_req->bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE | in cm109_usb_probe()
764 dev->ctl_req->bRequest = USB_REQ_SET_CONFIGURATION; in cm109_usb_probe()
765 dev->ctl_req->wValue = cpu_to_le16(0x200); in cm109_usb_probe()
766 dev->ctl_req->wIndex = cpu_to_le16(interface->desc.bInterfaceNumber); in cm109_usb_probe()
767 dev->ctl_req->wLength = cpu_to_le16(USB_PKT_LEN); in cm109_usb_probe()
769 usb_fill_control_urb(dev->urb_ctl, udev, usb_sndctrlpipe(udev, 0), in cm109_usb_probe()
770 (void *)dev->ctl_req, dev->ctl_data, USB_PKT_LEN, in cm109_usb_probe()
772 dev->urb_ctl->transfer_dma = dev->ctl_dma; in cm109_usb_probe()
773 dev->urb_ctl->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; in cm109_usb_probe()
774 dev->urb_ctl->dev = udev; in cm109_usb_probe()
777 usb_make_path(udev, dev->phys, sizeof(dev->phys)); in cm109_usb_probe()
778 strlcat(dev->phys, "/input0", sizeof(dev->phys)); in cm109_usb_probe()
781 input_dev->name = nfo->name; in cm109_usb_probe()
782 input_dev->phys = dev->phys; in cm109_usb_probe()
783 usb_to_input_id(udev, &input_dev->id); in cm109_usb_probe()
784 input_dev->dev.parent = &intf->dev; in cm109_usb_probe()
787 input_dev->open = cm109_input_open; in cm109_usb_probe()
788 input_dev->close = cm109_input_close; in cm109_usb_probe()
789 input_dev->event = cm109_input_ev; in cm109_usb_probe()
791 input_dev->keycode = dev->keymap; in cm109_usb_probe()
792 input_dev->keycodesize = sizeof(unsigned char); in cm109_usb_probe()
793 input_dev->keycodemax = ARRAY_SIZE(dev->keymap); in cm109_usb_probe()
795 input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_SND); in cm109_usb_probe()
796 input_dev->sndbit[0] = BIT_MASK(SND_BELL) | BIT_MASK(SND_TONE); in cm109_usb_probe()
800 unsigned short k = keymap(i); in cm109_usb_probe()
801 dev->keymap[i] = k; in cm109_usb_probe()
802 __set_bit(k, input_dev->keybit); in cm109_usb_probe()
804 __clear_bit(KEY_RESERVED, input_dev->keybit); in cm109_usb_probe()
806 error = input_register_device(dev->idev); in cm109_usb_probe()
824 dev_info(&intf->dev, "cm109: usb_suspend (event=%d)\n", message.event); in cm109_usb_suspend()
826 mutex_lock(&dev->pm_mutex); in cm109_usb_suspend()
828 mutex_unlock(&dev->pm_mutex); in cm109_usb_suspend()
837 dev_info(&intf->dev, "cm109: usb_resume\n"); in cm109_usb_resume()
839 mutex_lock(&dev->pm_mutex); in cm109_usb_resume()
841 mutex_unlock(&dev->pm_mutex); in cm109_usb_resume()
850 mutex_lock(&dev->pm_mutex); in cm109_usb_pre_reset()
856 dev->resetting = 1; in cm109_usb_pre_reset()
868 dev->resetting = 0; in cm109_usb_post_reset()
873 mutex_unlock(&dev->pm_mutex); in cm109_usb_post_reset()
893 /* Load the phone keymap */ in cm109_select_keymap()
895 keymap = keymap_kip1000; in cm109_select_keymap()
897 "Keymap for Komunikate KIP1000 phone loaded\n"); in cm109_select_keymap()
899 keymap = keymap_gtalk; in cm109_select_keymap()
901 "Keymap for Genius G-talk phone loaded\n"); in cm109_select_keymap()
903 keymap = keymap_usbph01; in cm109_select_keymap()
905 "Keymap for Allied-Telesis Corega USBPH01 phone loaded\n"); in cm109_select_keymap()
907 keymap = keymap_atcom; in cm109_select_keymap()
909 "Keymap for ATCom AU-100 phone loaded\n"); in cm109_select_keymap()
913 return -EINVAL; in cm109_select_keymap()