// SPDX-License-Identifier: GPL-2.0-only /* * Driver for the VoIP USB phones with CM109 chipsets. * * Copyright (C) 2007 - 2008 Alfred E. Heggestad <[email protected]> */ /* * Tested devices: * - Komunikate KIP1000 * - Genius G-talk * - Allied-Telesis Corega USBPH01 * - ... * * This driver is based on the yealink.c driver * * Thanks to: * - Authors of yealink.c * - Thomas Reitmayr * - Oliver Neukum for good review comments and code * - Shaun Jackman <[email protected]> for Genius G-talk keymap * - Dmitry Torokhov for valuable input and review * * Todo: * - Read/write EEPROM */ #include <linux/kernel.h> #include <linux/init.h> #include <linux/slab.h> #include <linux/module.h> #include <linux/moduleparam.h> #include <linux/rwsem.h> #include <linux/usb/input.h> #define DRIVER_VERSION … #define DRIVER_AUTHOR … #define DRIVER_DESC … static char *phone = …; module_param(phone, charp, S_IRUSR); MODULE_PARM_DESC(…) …; enum { … }; /* CM109 protocol packet */ struct cm109_ctl_packet { … } __attribute__ ((packed)); enum { … }; /* CM109 device structure */ struct cm109_dev { … }; /****************************************************************************** * CM109 key interface *****************************************************************************/ static unsigned short special_keymap(int code) { … } /* Map device buttons to internal key events. * * The "up" and "down" keys, are symbolised by arrows on the button. * The "pickup" and "hangup" keys are symbolised by a green and red phone * on the button. Komunikate KIP1000 Keyboard Matrix -> -- 1 -- 2 -- 3 --> GPI pin 4 (0x10) | | | | <- -- 4 -- 5 -- 6 --> GPI pin 5 (0x20) | | | | END - 7 -- 8 -- 9 --> GPI pin 6 (0x40) | | | | OK -- * -- 0 -- # --> GPI pin 7 (0x80) | | | | /|\ /|\ /|\ /|\ | | | | GPO pin: 3 2 1 0 0x8 0x4 0x2 0x1 */ static unsigned short keymap_kip1000(int scancode) { … } /* Contributed by Shaun Jackman <[email protected]> Genius G-Talk keyboard matrix 0 1 2 3 4: 0 4 8 Talk 5: 1 5 9 End 6: 2 6 # Up 7: 3 7 * Down */ static unsigned short keymap_gtalk(int scancode) { … } /* * Keymap for Allied-Telesis Corega USBPH01 * http://www.alliedtelesis-corega.com/2/1344/1437/1360/chprd.html * * Contributed by [email protected] */ static unsigned short keymap_usbph01(int scancode) { … } /* * Keymap for ATCom AU-100 * http://www.atcom.cn/products.html * http://www.packetizer.com/products/au100/ * http://www.voip-info.org/wiki/view/AU-100 * * Contributed by [email protected] */ static unsigned short keymap_atcom(int scancode) { … } static unsigned short (*keymap)(int) = …; /* * Completes a request by converting the data into events for the * input subsystem. */ static void report_key(struct cm109_dev *dev, int key) { … } /* * Converts data of special key presses (volume, mute) into events * for the input subsystem, sends press-n-release for mute keys. */ static void cm109_report_special(struct cm109_dev *dev) { … } /****************************************************************************** * CM109 usb communication interface *****************************************************************************/ static void cm109_submit_buzz_toggle(struct cm109_dev *dev) { … } /* * IRQ handler */ static void cm109_urb_irq_callback(struct urb *urb) { … } static void cm109_urb_ctl_callback(struct urb *urb) { … } static void cm109_toggle_buzzer_async(struct cm109_dev *dev) { … } static void cm109_toggle_buzzer_sync(struct cm109_dev *dev, int on) { … } static void cm109_stop_traffic(struct cm109_dev *dev) { … } static void cm109_restore_state(struct cm109_dev *dev) { … } /****************************************************************************** * input event interface *****************************************************************************/ static int cm109_input_open(struct input_dev *idev) { … } static void cm109_input_close(struct input_dev *idev) { … } static int cm109_input_ev(struct input_dev *idev, unsigned int type, unsigned int code, int value) { … } /****************************************************************************** * Linux interface and usb initialisation *****************************************************************************/ struct driver_info { … }; static const struct driver_info info_cm109 = …; enum { … }; /* table of devices that work with this driver */ static const struct usb_device_id cm109_usb_table[] = …; static void cm109_usb_cleanup(struct cm109_dev *dev) { … } static void cm109_usb_disconnect(struct usb_interface *interface) { … } static int cm109_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) { … } static int cm109_usb_suspend(struct usb_interface *intf, pm_message_t message) { … } static int cm109_usb_resume(struct usb_interface *intf) { … } static int cm109_usb_pre_reset(struct usb_interface *intf) { … } static int cm109_usb_post_reset(struct usb_interface *intf) { … } static struct usb_driver cm109_driver = …; static int __init cm109_select_keymap(void) { … } static int __init cm109_init(void) { … } static void __exit cm109_exit(void) { … } module_init(…) …; module_exit(cm109_exit); MODULE_DEVICE_TABLE(usb, cm109_usb_table); MODULE_AUTHOR(…); MODULE_DESCRIPTION(…); MODULE_LICENSE(…) …;