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()
362 guard(spinlock_irqsave)(&dev->ctl_submit_lock); in cm109_submit_ctl()
364 dev->irq_urb_pending = 0; in cm109_submit_ctl()
366 if (unlikely(dev->shutdown)) in cm109_submit_ctl()
369 if (dev->buzzer_state) in cm109_submit_ctl()
370 dev->ctl_data->byte[HID_OR0] |= BUZZER_ON; in cm109_submit_ctl()
372 dev->ctl_data->byte[HID_OR0] &= ~BUZZER_ON; in cm109_submit_ctl()
374 dev->ctl_data->byte[HID_OR1] = dev->keybit; in cm109_submit_ctl()
375 dev->ctl_data->byte[HID_OR2] = dev->keybit; in cm109_submit_ctl()
377 dev->buzzer_pending = 0; in cm109_submit_ctl()
378 dev->ctl_urb_pending = 1; in cm109_submit_ctl()
380 error = usb_submit_urb(dev->urb_ctl, GFP_ATOMIC); in cm109_submit_ctl()
382 dev_err(&dev->intf->dev, in cm109_submit_ctl()
392 struct cm109_dev *dev = urb->context; in cm109_urb_irq_callback()
393 const int status = urb->status; in cm109_urb_irq_callback()
395 dev_dbg(&dev->intf->dev, "### URB IRQ: [0x%02x 0x%02x 0x%02x 0x%02x] keybit=0x%02x\n", in cm109_urb_irq_callback()
396 dev->irq_data->byte[0], in cm109_urb_irq_callback()
397 dev->irq_data->byte[1], in cm109_urb_irq_callback()
398 dev->irq_data->byte[2], in cm109_urb_irq_callback()
399 dev->irq_data->byte[3], in cm109_urb_irq_callback()
400 dev->keybit); in cm109_urb_irq_callback()
403 if (status == -ESHUTDOWN) in cm109_urb_irq_callback()
405 dev_err_ratelimited(&dev->intf->dev, "%s: urb status %d\n", in cm109_urb_irq_callback()
414 if (dev->keybit == 0xf) { in cm109_urb_irq_callback()
417 if ((dev->gpi & 0xf0) == (dev->irq_data->byte[HID_IR1] & 0xf0)) in cm109_urb_irq_callback()
420 dev->gpi = dev->irq_data->byte[HID_IR1] & 0xf0; in cm109_urb_irq_callback()
421 dev->keybit = 0x1; in cm109_urb_irq_callback()
423 report_key(dev, dev->keymap[dev->irq_data->byte[HID_IR1]]); in cm109_urb_irq_callback()
425 dev->keybit <<= 1; in cm109_urb_irq_callback()
426 if (dev->keybit > 0x8) in cm109_urb_irq_callback()
427 dev->keybit = 0xf; in cm109_urb_irq_callback()
436 struct cm109_dev *dev = urb->context; in cm109_urb_ctl_callback()
437 const int status = urb->status; in cm109_urb_ctl_callback()
440 dev_dbg(&dev->intf->dev, "### URB CTL: [0x%02x 0x%02x 0x%02x 0x%02x]\n", in cm109_urb_ctl_callback()
441 dev->ctl_data->byte[0], in cm109_urb_ctl_callback()
442 dev->ctl_data->byte[1], in cm109_urb_ctl_callback()
443 dev->ctl_data->byte[2], in cm109_urb_ctl_callback()
444 dev->ctl_data->byte[3]); in cm109_urb_ctl_callback()
447 if (status == -ESHUTDOWN) in cm109_urb_ctl_callback()
449 dev_err_ratelimited(&dev->intf->dev, "%s: urb status %d\n", in cm109_urb_ctl_callback()
453 guard(spinlock_irqsave)(&dev->ctl_submit_lock); in cm109_urb_ctl_callback()
455 dev->ctl_urb_pending = 0; in cm109_urb_ctl_callback()
457 if (unlikely(dev->shutdown)) in cm109_urb_ctl_callback()
460 if (dev->buzzer_pending || status) { in cm109_urb_ctl_callback()
461 dev->buzzer_pending = 0; in cm109_urb_ctl_callback()
462 dev->ctl_urb_pending = 1; in cm109_urb_ctl_callback()
464 } else if (likely(!dev->irq_urb_pending)) { in cm109_urb_ctl_callback()
466 dev->irq_urb_pending = 1; in cm109_urb_ctl_callback()
467 error = usb_submit_urb(dev->urb_irq, GFP_ATOMIC); in cm109_urb_ctl_callback()
469 dev_err(&dev->intf->dev, in cm109_urb_ctl_callback()
477 guard(spinlock_irqsave)(&dev->ctl_submit_lock); in cm109_toggle_buzzer_async()
479 if (dev->ctl_urb_pending) { in cm109_toggle_buzzer_async()
481 dev->buzzer_pending = 1; in cm109_toggle_buzzer_async()
483 dev->ctl_urb_pending = 1; in cm109_toggle_buzzer_async()
493 dev->ctl_data->byte[HID_OR0] |= BUZZER_ON; in cm109_toggle_buzzer_sync()
495 dev->ctl_data->byte[HID_OR0] &= ~BUZZER_ON; in cm109_toggle_buzzer_sync()
497 error = usb_control_msg(dev->udev, in cm109_toggle_buzzer_sync()
498 usb_sndctrlpipe(dev->udev, 0), in cm109_toggle_buzzer_sync()
499 dev->ctl_req->bRequest, in cm109_toggle_buzzer_sync()
500 dev->ctl_req->bRequestType, in cm109_toggle_buzzer_sync()
501 le16_to_cpu(dev->ctl_req->wValue), in cm109_toggle_buzzer_sync()
502 le16_to_cpu(dev->ctl_req->wIndex), in cm109_toggle_buzzer_sync()
503 dev->ctl_data, in cm109_toggle_buzzer_sync()
505 if (error < 0 && error != -EINTR) in cm109_toggle_buzzer_sync()
506 dev_err(&dev->intf->dev, "%s: usb_control_msg() failed %d\n", in cm109_toggle_buzzer_sync()
512 dev->shutdown = 1; in cm109_stop_traffic()
518 usb_kill_urb(dev->urb_ctl); in cm109_stop_traffic()
519 usb_kill_urb(dev->urb_irq); in cm109_stop_traffic()
523 dev->shutdown = 0; in cm109_stop_traffic()
529 if (dev->open) { in cm109_restore_state()
547 error = usb_autopm_get_interface(dev->intf); in cm109_input_open()
549 dev_err(&idev->dev, "%s - cannot autoresume, result %d\n", in cm109_input_open()
554 scoped_guard(mutex, &dev->pm_mutex) { in cm109_input_open()
555 dev->buzzer_state = 0; in cm109_input_open()
556 dev->key_code = -1; /* no keys pressed */ in cm109_input_open()
557 dev->keybit = 0xf; in cm109_input_open()
560 dev->ctl_data->byte[HID_OR0] = HID_OR_GPO_BUZ_SPDIF; in cm109_input_open()
561 dev->ctl_data->byte[HID_OR1] = dev->keybit; in cm109_input_open()
562 dev->ctl_data->byte[HID_OR2] = dev->keybit; in cm109_input_open()
563 dev->ctl_data->byte[HID_OR3] = 0x00; in cm109_input_open()
565 dev->ctl_urb_pending = 1; in cm109_input_open()
566 error = usb_submit_urb(dev->urb_ctl, GFP_KERNEL); in cm109_input_open()
568 dev->open = 1; in cm109_input_open()
573 dev->ctl_urb_pending = 0; in cm109_input_open()
574 usb_autopm_put_interface(dev->intf); in cm109_input_open()
576 dev_err(&dev->intf->dev, "%s: usb_submit_urb (urb_ctl) failed %d\n", in cm109_input_open()
586 scoped_guard(mutex, &dev->pm_mutex) { in cm109_input_close()
593 dev->open = 0; in cm109_input_close()
596 usb_autopm_put_interface(dev->intf); in cm109_input_close()
604 dev_dbg(&dev->intf->dev, in cm109_input_ev()
608 return -EINVAL; in cm109_input_ev()
613 dev->buzzer_state = !!value; in cm109_input_ev()
614 if (!dev->resetting) in cm109_input_ev()
619 return -EINVAL; in cm109_input_ev()
637 VENDOR_ID = 0x0d8c, /* C-Media Electronics */
638 PRODUCT_ID_CM109 = 0x000e, /* CM109 defines range 0x0008 - 0x000f */
653 /* you can add more devices here with product ID 0x0008 - 0x000f */
659 kfree(dev->ctl_req); in cm109_usb_cleanup()
660 usb_free_coherent(dev->udev, USB_PKT_LEN, dev->ctl_data, dev->ctl_dma); in cm109_usb_cleanup()
661 usb_free_coherent(dev->udev, USB_PKT_LEN, dev->irq_data, dev->irq_dma); in cm109_usb_cleanup()
663 usb_free_urb(dev->urb_irq); /* parameter validation in core/urb */ in cm109_usb_cleanup()
664 usb_free_urb(dev->urb_ctl); /* parameter validation in core/urb */ in cm109_usb_cleanup()
673 input_unregister_device(dev->idev); in cm109_usb_disconnect()
681 struct driver_info *nfo = (struct driver_info *)id->driver_info; in cm109_usb_probe()
687 int error = -ENOMEM; in cm109_usb_probe()
689 interface = intf->cur_altsetting; in cm109_usb_probe()
691 if (interface->desc.bNumEndpoints < 1) in cm109_usb_probe()
692 return -ENODEV; in cm109_usb_probe()
694 endpoint = &interface->endpoint[0].desc; in cm109_usb_probe()
697 return -ENODEV; in cm109_usb_probe()
701 return -ENOMEM; in cm109_usb_probe()
703 spin_lock_init(&dev->ctl_submit_lock); in cm109_usb_probe()
704 mutex_init(&dev->pm_mutex); in cm109_usb_probe()
706 dev->udev = udev; in cm109_usb_probe()
707 dev->intf = intf; in cm109_usb_probe()
709 dev->idev = input_dev = input_allocate_device(); in cm109_usb_probe()
714 dev->irq_data = usb_alloc_coherent(udev, USB_PKT_LEN, in cm109_usb_probe()
715 GFP_KERNEL, &dev->irq_dma); in cm109_usb_probe()
716 if (!dev->irq_data) in cm109_usb_probe()
719 dev->ctl_data = usb_alloc_coherent(udev, USB_PKT_LEN, in cm109_usb_probe()
720 GFP_KERNEL, &dev->ctl_dma); in cm109_usb_probe()
721 if (!dev->ctl_data) in cm109_usb_probe()
724 dev->ctl_req = kmalloc(sizeof(*(dev->ctl_req)), GFP_KERNEL); in cm109_usb_probe()
725 if (!dev->ctl_req) in cm109_usb_probe()
729 dev->urb_irq = usb_alloc_urb(0, GFP_KERNEL); in cm109_usb_probe()
730 if (!dev->urb_irq) in cm109_usb_probe()
733 dev->urb_ctl = usb_alloc_urb(0, GFP_KERNEL); in cm109_usb_probe()
734 if (!dev->urb_ctl) in cm109_usb_probe()
738 pipe = usb_rcvintpipe(udev, endpoint->bEndpointAddress); in cm109_usb_probe()
741 dev_err(&intf->dev, "invalid payload size %d, expected %d\n", in cm109_usb_probe()
745 usb_fill_int_urb(dev->urb_irq, udev, pipe, dev->irq_data, in cm109_usb_probe()
747 cm109_urb_irq_callback, dev, endpoint->bInterval); in cm109_usb_probe()
748 dev->urb_irq->transfer_dma = dev->irq_dma; in cm109_usb_probe()
749 dev->urb_irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; in cm109_usb_probe()
750 dev->urb_irq->dev = udev; in cm109_usb_probe()
753 dev->ctl_req->bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE | in cm109_usb_probe()
755 dev->ctl_req->bRequest = USB_REQ_SET_CONFIGURATION; in cm109_usb_probe()
756 dev->ctl_req->wValue = cpu_to_le16(0x200); in cm109_usb_probe()
757 dev->ctl_req->wIndex = cpu_to_le16(interface->desc.bInterfaceNumber); in cm109_usb_probe()
758 dev->ctl_req->wLength = cpu_to_le16(USB_PKT_LEN); in cm109_usb_probe()
760 usb_fill_control_urb(dev->urb_ctl, udev, usb_sndctrlpipe(udev, 0), in cm109_usb_probe()
761 (void *)dev->ctl_req, dev->ctl_data, USB_PKT_LEN, in cm109_usb_probe()
763 dev->urb_ctl->transfer_dma = dev->ctl_dma; in cm109_usb_probe()
764 dev->urb_ctl->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; in cm109_usb_probe()
765 dev->urb_ctl->dev = udev; in cm109_usb_probe()
768 usb_make_path(udev, dev->phys, sizeof(dev->phys)); in cm109_usb_probe()
769 strlcat(dev->phys, "/input0", sizeof(dev->phys)); in cm109_usb_probe()
772 input_dev->name = nfo->name; in cm109_usb_probe()
773 input_dev->phys = dev->phys; in cm109_usb_probe()
774 usb_to_input_id(udev, &input_dev->id); in cm109_usb_probe()
775 input_dev->dev.parent = &intf->dev; in cm109_usb_probe()
778 input_dev->open = cm109_input_open; in cm109_usb_probe()
779 input_dev->close = cm109_input_close; in cm109_usb_probe()
780 input_dev->event = cm109_input_ev; in cm109_usb_probe()
782 input_dev->keycode = dev->keymap; in cm109_usb_probe()
783 input_dev->keycodesize = sizeof(unsigned char); in cm109_usb_probe()
784 input_dev->keycodemax = ARRAY_SIZE(dev->keymap); in cm109_usb_probe()
786 input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_SND); in cm109_usb_probe()
787 input_dev->sndbit[0] = BIT_MASK(SND_BELL) | BIT_MASK(SND_TONE); in cm109_usb_probe()
791 unsigned short k = keymap(i); in cm109_usb_probe()
792 dev->keymap[i] = k; in cm109_usb_probe()
793 __set_bit(k, input_dev->keybit); in cm109_usb_probe()
795 __clear_bit(KEY_RESERVED, input_dev->keybit); in cm109_usb_probe()
797 error = input_register_device(dev->idev); in cm109_usb_probe()
815 dev_info(&intf->dev, "cm109: usb_suspend (event=%d)\n", message.event); in cm109_usb_suspend()
817 guard(mutex)(&dev->pm_mutex); in cm109_usb_suspend()
828 dev_info(&intf->dev, "cm109: usb_resume\n"); in cm109_usb_resume()
830 guard(mutex)(&dev->pm_mutex); in cm109_usb_resume()
841 mutex_lock(&dev->pm_mutex); in cm109_usb_pre_reset()
847 dev->resetting = 1; in cm109_usb_pre_reset()
859 dev->resetting = 0; in cm109_usb_post_reset()
864 mutex_unlock(&dev->pm_mutex); in cm109_usb_post_reset()
884 /* Load the phone keymap */ in cm109_select_keymap()
886 keymap = keymap_kip1000; in cm109_select_keymap()
888 "Keymap for Komunikate KIP1000 phone loaded\n"); in cm109_select_keymap()
890 keymap = keymap_gtalk; in cm109_select_keymap()
892 "Keymap for Genius G-talk phone loaded\n"); in cm109_select_keymap()
894 keymap = keymap_usbph01; in cm109_select_keymap()
896 "Keymap for Allied-Telesis Corega USBPH01 phone loaded\n"); in cm109_select_keymap()
898 keymap = keymap_atcom; in cm109_select_keymap()
900 "Keymap for ATCom AU-100 phone loaded\n"); in cm109_select_keymap()
904 return -EINVAL; in cm109_select_keymap()