1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* DVB USB compliant Linux driver for the Afatech 9005 3 * USB1.1 DVB-T receiver. 4 * 5 * Standard remote decode function 6 * 7 * Copyright (C) 2007 Luca Olivetti (luca@ventoso.org) 8 * 9 * Thanks to Afatech who kindly provided information. 10 * 11 * see Documentation/driver-api/media/drivers/dvb-usb.rst for more information 12 */ 13 #include "af9005.h" 14 /* debug */ 15 static int dvb_usb_af9005_remote_debug; 16 module_param_named(debug, dvb_usb_af9005_remote_debug, int, 0644); 17 MODULE_PARM_DESC(debug, 18 "enable (1) or disable (0) debug messages." 19 DVB_USB_DEBUG_STATUS); 20 21 #define deb_decode(args...) dprintk(dvb_usb_af9005_remote_debug,0x01,args) 22 23 struct rc_map_table rc_map_af9005_table[] = { 24 25 {0x01b7, KEY_POWER}, 26 {0x01a7, KEY_VOLUMEUP}, 27 {0x0187, KEY_CHANNELUP}, 28 {0x017f, KEY_MUTE}, 29 {0x01bf, KEY_VOLUMEDOWN}, 30 {0x013f, KEY_CHANNELDOWN}, 31 {0x01df, KEY_1}, 32 {0x015f, KEY_2}, 33 {0x019f, KEY_3}, 34 {0x011f, KEY_4}, 35 {0x01ef, KEY_5}, 36 {0x016f, KEY_6}, 37 {0x01af, KEY_7}, 38 {0x0127, KEY_8}, 39 {0x0107, KEY_9}, 40 {0x01cf, KEY_ZOOM}, 41 {0x014f, KEY_0}, 42 {0x018f, KEY_GOTO}, /* marked jump on the remote */ 43 44 {0x00bd, KEY_POWER}, 45 {0x007d, KEY_VOLUMEUP}, 46 {0x00fd, KEY_CHANNELUP}, 47 {0x009d, KEY_MUTE}, 48 {0x005d, KEY_VOLUMEDOWN}, 49 {0x00dd, KEY_CHANNELDOWN}, 50 {0x00ad, KEY_1}, 51 {0x006d, KEY_2}, 52 {0x00ed, KEY_3}, 53 {0x008d, KEY_4}, 54 {0x004d, KEY_5}, 55 {0x00cd, KEY_6}, 56 {0x00b5, KEY_7}, 57 {0x0075, KEY_8}, 58 {0x00f5, KEY_9}, 59 {0x0095, KEY_ZOOM}, 60 {0x0055, KEY_0}, 61 {0x00d5, KEY_GOTO}, /* marked jump on the remote */ 62 }; 63 64 int rc_map_af9005_table_size = ARRAY_SIZE(rc_map_af9005_table); 65 66 static int repeatable_keys[] = { 67 KEY_VOLUMEUP, 68 KEY_VOLUMEDOWN, 69 KEY_CHANNELUP, 70 KEY_CHANNELDOWN 71 }; 72 73 int af9005_rc_decode(struct dvb_usb_device *d, u8 * data, int len, u32 * event, 74 int *state) 75 { 76 u16 mark, space; 77 u32 result; 78 u8 cust, dat, invdat; 79 int i; 80 81 if (len >= 6) { 82 mark = (u16) (data[0] << 8) + data[1]; 83 space = (u16) (data[2] << 8) + data[3]; 84 if (space * 3 < mark) { 85 for (i = 0; i < ARRAY_SIZE(repeatable_keys); i++) { 86 if (d->last_event == repeatable_keys[i]) { 87 *state = REMOTE_KEY_REPEAT; 88 *event = d->last_event; 89 deb_decode("repeat key, event %x\n", 90 *event); 91 return 0; 92 } 93 } 94 deb_decode("repeated key ignored (non repeatable)\n"); 95 return 0; 96 } else if (len >= 33 * 4) { /*32 bits + start code */ 97 result = 0; 98 for (i = 4; i < 4 + 32 * 4; i += 4) { 99 result <<= 1; 100 mark = (u16) (data[i] << 8) + data[i + 1]; 101 mark >>= 1; 102 space = (u16) (data[i + 2] << 8) + data[i + 3]; 103 space >>= 1; 104 if (mark * 2 > space) 105 result += 1; 106 } 107 deb_decode("key pressed, raw value %x\n", result); 108 if ((result & 0xff000000) != 0xfe000000) { 109 deb_decode 110 ("doesn't start with 0xfe, ignored\n"); 111 return 0; 112 } 113 cust = (result >> 16) & 0xff; 114 dat = (result >> 8) & 0xff; 115 invdat = (~result) & 0xff; 116 if (dat != invdat) { 117 deb_decode("code != inverted code\n"); 118 return 0; 119 } 120 for (i = 0; i < rc_map_af9005_table_size; i++) { 121 if (rc5_custom(&rc_map_af9005_table[i]) == cust 122 && rc5_data(&rc_map_af9005_table[i]) == dat) { 123 *event = rc_map_af9005_table[i].keycode; 124 *state = REMOTE_KEY_PRESSED; 125 deb_decode 126 ("key pressed, event %x\n", *event); 127 return 0; 128 } 129 } 130 deb_decode("not found in table\n"); 131 } 132 } 133 return 0; 134 } 135 136 EXPORT_SYMBOL(rc_map_af9005_table); 137 EXPORT_SYMBOL(rc_map_af9005_table_size); 138 EXPORT_SYMBOL(af9005_rc_decode); 139 140 MODULE_AUTHOR("Luca Olivetti <luca@ventoso.org>"); 141 MODULE_DESCRIPTION 142 ("Standard remote control decoder for Afatech 9005 DVB-T USB1.1 stick"); 143 MODULE_VERSION("1.0"); 144 MODULE_LICENSE("GPL"); 145