1/* 2 * Driver for the remote control of SAA7146 based AV7110 cards 3 * 4 * Copyright (C) 1999-2003 Holger Waechtler <holger@convergence.de> 5 * Copyright (C) 2003-2007 Oliver Endriss <o.endriss@gmx.de> 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 20 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html 21 * 22 */ 23 24 25#include <linux/types.h> 26#include <linux/init.h> 27#include <linux/module.h> 28#include <linux/proc_fs.h> 29#include <linux/kernel.h> 30#include <linux/bitops.h> 31 32#include "av7110.h" 33#include "av7110_hw.h" 34 35 36#define AV_CNT 4 37 38#define IR_RC5 0 39#define IR_RCMM 1 40#define IR_RC5_EXT 2 /* internal only */ 41 42#define IR_ALL 0xffffffff 43 44#define UP_TIMEOUT (HZ*7/25) 45 46 47/* Note: enable ir debugging by or'ing debug with 16 */ 48 49static int ir_protocol[AV_CNT] = { IR_RCMM, IR_RCMM, IR_RCMM, IR_RCMM}; 50module_param_array(ir_protocol, int, NULL, 0644); 51MODULE_PARM_DESC(ir_protocol, "Infrared protocol: 0 RC5, 1 RCMM (default)"); 52 53static int ir_inversion[AV_CNT]; 54module_param_array(ir_inversion, int, NULL, 0644); 55MODULE_PARM_DESC(ir_inversion, "Inversion of infrared signal: 0 not inverted (default), 1 inverted"); 56 57static uint ir_device_mask[AV_CNT] = { IR_ALL, IR_ALL, IR_ALL, IR_ALL }; 58module_param_array(ir_device_mask, uint, NULL, 0644); 59MODULE_PARM_DESC(ir_device_mask, "Bitmask of infrared devices: bit 0..31 = device 0..31 (default: all)"); 60 61 62static int av_cnt; 63static struct av7110 *av_list[AV_CNT]; 64 65static u16 default_key_map [256] = { 66 KEY_0, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7, 67 KEY_8, KEY_9, KEY_BACK, 0, KEY_POWER, KEY_MUTE, 0, KEY_INFO, 68 KEY_VOLUMEUP, KEY_VOLUMEDOWN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69 KEY_CHANNELUP, KEY_CHANNELDOWN, 0, 0, 0, 0, 0, 0, 70 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71 0, 0, 0, 0, KEY_TEXT, 0, 0, KEY_TV, 0, 0, 0, 0, 0, KEY_SETUP, 0, 0, 72 0, 0, 0, KEY_SUBTITLE, 0, 0, KEY_LANGUAGE, 0, 73 KEY_RADIO, 0, 0, 0, 0, KEY_EXIT, 0, 0, 74 KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT, KEY_OK, 0, 0, 0, 75 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, KEY_RED, KEY_GREEN, KEY_YELLOW, 76 KEY_BLUE, 0, 0, 0, 0, 0, 0, 0, KEY_MENU, KEY_LIST, 0, 0, 0, 0, 0, 0, 77 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 78 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81 0, 0, 0, 0, KEY_UP, KEY_UP, KEY_DOWN, KEY_DOWN, 82 0, 0, 0, 0, KEY_EPG, 0, 0, 0, 83 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 84 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, KEY_VCR 86}; 87 88 89/* key-up timer */ 90static void av7110_emit_keyup(unsigned long parm) 91{ 92 struct infrared *ir = (struct infrared *) parm; 93 94 if (!ir || !test_bit(ir->last_key, ir->input_dev->key)) 95 return; 96 97 input_report_key(ir->input_dev, ir->last_key, 0); 98 input_sync(ir->input_dev); 99} 100 101 102/* tasklet */ 103static void av7110_emit_key(unsigned long parm) 104{ 105 struct infrared *ir = (struct infrared *) parm; 106 u32 ircom = ir->ir_command; 107 u8 data; 108 u8 addr; 109 u16 toggle; 110 u16 keycode; 111 112 /* extract device address and data */ 113 switch (ir->protocol) { 114 case IR_RC5: /* RC5: 5 bits device address, 6 bits data */ 115 data = ircom & 0x3f; 116 addr = (ircom >> 6) & 0x1f; 117 toggle = ircom & 0x0800; 118 break; 119 120 case IR_RCMM: /* RCMM: ? bits device address, ? bits data */ 121 data = ircom & 0xff; 122 addr = (ircom >> 8) & 0x1f; 123 toggle = ircom & 0x8000; 124 break; 125 126 case IR_RC5_EXT: /* extended RC5: 5 bits device address, 7 bits data */ 127 data = ircom & 0x3f; 128 addr = (ircom >> 6) & 0x1f; 129 /* invert 7th data bit for backward compatibility with RC5 keymaps */ 130 if (!(ircom & 0x1000)) 131 data |= 0x40; 132 toggle = ircom & 0x0800; 133 break; 134 135 default: 136 printk("%s invalid protocol %x\n", __func__, ir->protocol); 137 return; 138 } 139 140 input_event(ir->input_dev, EV_MSC, MSC_RAW, (addr << 16) | data); 141 input_event(ir->input_dev, EV_MSC, MSC_SCAN, data); 142 143 keycode = ir->key_map[data]; 144 145 dprintk(16, "%s: code %08x -> addr %i data 0x%02x -> keycode %i\n", 146 __func__, ircom, addr, data, keycode); 147 148 /* check device address */ 149 if (!(ir->device_mask & (1 << addr))) 150 return; 151 152 if (!keycode) { 153 printk ("%s: code %08x -> addr %i data 0x%02x -> unknown key!\n", 154 __func__, ircom, addr, data); 155 return; 156 } 157 158 if (timer_pending(&ir->keyup_timer)) { 159 del_timer(&ir->keyup_timer); 160 if (ir->last_key != keycode || toggle != ir->last_toggle) { 161 ir->delay_timer_finished = 0; 162 input_event(ir->input_dev, EV_KEY, ir->last_key, 0); 163 input_event(ir->input_dev, EV_KEY, keycode, 1); 164 input_sync(ir->input_dev); 165 } else if (ir->delay_timer_finished) { 166 input_event(ir->input_dev, EV_KEY, keycode, 2); 167 input_sync(ir->input_dev); 168 } 169 } else { 170 ir->delay_timer_finished = 0; 171 input_event(ir->input_dev, EV_KEY, keycode, 1); 172 input_sync(ir->input_dev); 173 } 174 175 ir->last_key = keycode; 176 ir->last_toggle = toggle; 177 178 ir->keyup_timer.expires = jiffies + UP_TIMEOUT; 179 add_timer(&ir->keyup_timer); 180 181} 182 183 184/* register with input layer */ 185static void input_register_keys(struct infrared *ir) 186{ 187 int i; 188 189 set_bit(EV_KEY, ir->input_dev->evbit); 190 set_bit(EV_REP, ir->input_dev->evbit); 191 set_bit(EV_MSC, ir->input_dev->evbit); 192 193 set_bit(MSC_RAW, ir->input_dev->mscbit); 194 set_bit(MSC_SCAN, ir->input_dev->mscbit); 195 196 memset(ir->input_dev->keybit, 0, sizeof(ir->input_dev->keybit)); 197 198 for (i = 0; i < ARRAY_SIZE(ir->key_map); i++) { 199 if (ir->key_map[i] > KEY_MAX) 200 ir->key_map[i] = 0; 201 else if (ir->key_map[i] > KEY_RESERVED) 202 set_bit(ir->key_map[i], ir->input_dev->keybit); 203 } 204 205 ir->input_dev->keycode = ir->key_map; 206 ir->input_dev->keycodesize = sizeof(ir->key_map[0]); 207 ir->input_dev->keycodemax = ARRAY_SIZE(ir->key_map); 208} 209 210 211/* called by the input driver after rep[REP_DELAY] ms */ 212static void input_repeat_key(unsigned long parm) 213{ 214 struct infrared *ir = (struct infrared *) parm; 215 216 ir->delay_timer_finished = 1; 217} 218 219 220/* check for configuration changes */ 221int av7110_check_ir_config(struct av7110 *av7110, int force) 222{ 223 int i; 224 int modified = force; 225 int ret = -ENODEV; 226 227 for (i = 0; i < av_cnt; i++) 228 if (av7110 == av_list[i]) 229 break; 230 231 if (i < av_cnt && av7110) { 232 if ((av7110->ir.protocol & 1) != ir_protocol[i] || 233 av7110->ir.inversion != ir_inversion[i]) 234 modified = true; 235 236 if (modified) { 237 /* protocol */ 238 if (ir_protocol[i]) { 239 ir_protocol[i] = 1; 240 av7110->ir.protocol = IR_RCMM; 241 av7110->ir.ir_config = 0x0001; 242 } else if (FW_VERSION(av7110->arm_app) >= 0x2620) { 243 av7110->ir.protocol = IR_RC5_EXT; 244 av7110->ir.ir_config = 0x0002; 245 } else { 246 av7110->ir.protocol = IR_RC5; 247 av7110->ir.ir_config = 0x0000; 248 } 249 /* inversion */ 250 if (ir_inversion[i]) { 251 ir_inversion[i] = 1; 252 av7110->ir.ir_config |= 0x8000; 253 } 254 av7110->ir.inversion = ir_inversion[i]; 255 /* update ARM */ 256 ret = av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, SetIR, 1, 257 av7110->ir.ir_config); 258 } else 259 ret = 0; 260 261 /* address */ 262 if (av7110->ir.device_mask != ir_device_mask[i]) 263 av7110->ir.device_mask = ir_device_mask[i]; 264 } 265 266 return ret; 267} 268 269 270/* /proc/av7110_ir interface */ 271static ssize_t av7110_ir_proc_write(struct file *file, const char __user *buffer, 272 size_t count, loff_t *pos) 273{ 274 char *page; 275 u32 ir_config; 276 int size = sizeof ir_config + sizeof av_list[0]->ir.key_map; 277 int i; 278 279 if (count < size) 280 return -EINVAL; 281 282 page = vmalloc(size); 283 if (!page) 284 return -ENOMEM; 285 286 if (copy_from_user(page, buffer, size)) { 287 vfree(page); 288 return -EFAULT; 289 } 290 291 memcpy(&ir_config, page, sizeof ir_config); 292 293 for (i = 0; i < av_cnt; i++) { 294 /* keymap */ 295 memcpy(av_list[i]->ir.key_map, page + sizeof ir_config, 296 sizeof(av_list[i]->ir.key_map)); 297 /* protocol, inversion, address */ 298 ir_protocol[i] = ir_config & 0x0001; 299 ir_inversion[i] = ir_config & 0x8000 ? 1 : 0; 300 if (ir_config & 0x4000) 301 ir_device_mask[i] = 1 << ((ir_config >> 16) & 0x1f); 302 else 303 ir_device_mask[i] = IR_ALL; 304 /* update configuration */ 305 av7110_check_ir_config(av_list[i], false); 306 input_register_keys(&av_list[i]->ir); 307 } 308 vfree(page); 309 return count; 310} 311 312static const struct file_operations av7110_ir_proc_fops = { 313 .owner = THIS_MODULE, 314 .write = av7110_ir_proc_write, 315 .llseek = noop_llseek, 316}; 317 318/* interrupt handler */ 319static void ir_handler(struct av7110 *av7110, u32 ircom) 320{ 321 dprintk(4, "ir command = %08x\n", ircom); 322 av7110->ir.ir_command = ircom; 323 tasklet_schedule(&av7110->ir.ir_tasklet); 324} 325 326 327int __devinit av7110_ir_init(struct av7110 *av7110) 328{ 329 struct input_dev *input_dev; 330 static struct proc_dir_entry *e; 331 int err; 332 333 if (av_cnt >= ARRAY_SIZE(av_list)) 334 return -ENOSPC; 335 336 av_list[av_cnt++] = av7110; 337 av7110_check_ir_config(av7110, true); 338 339 init_timer(&av7110->ir.keyup_timer); 340 av7110->ir.keyup_timer.function = av7110_emit_keyup; 341 av7110->ir.keyup_timer.data = (unsigned long) &av7110->ir; 342 343 input_dev = input_allocate_device(); 344 if (!input_dev) 345 return -ENOMEM; 346 347 av7110->ir.input_dev = input_dev; 348 snprintf(av7110->ir.input_phys, sizeof(av7110->ir.input_phys), 349 "pci-%s/ir0", pci_name(av7110->dev->pci)); 350 351 input_dev->name = "DVB on-card IR receiver"; 352 353 input_dev->phys = av7110->ir.input_phys; 354 input_dev->id.bustype = BUS_PCI; 355 input_dev->id.version = 2; 356 if (av7110->dev->pci->subsystem_vendor) { 357 input_dev->id.vendor = av7110->dev->pci->subsystem_vendor; 358 input_dev->id.product = av7110->dev->pci->subsystem_device; 359 } else { 360 input_dev->id.vendor = av7110->dev->pci->vendor; 361 input_dev->id.product = av7110->dev->pci->device; 362 } 363 input_dev->dev.parent = &av7110->dev->pci->dev; 364 /* initial keymap */ 365 memcpy(av7110->ir.key_map, default_key_map, sizeof av7110->ir.key_map); 366 input_register_keys(&av7110->ir); 367 err = input_register_device(input_dev); 368 if (err) { 369 input_free_device(input_dev); 370 return err; 371 } 372 input_dev->timer.function = input_repeat_key; 373 input_dev->timer.data = (unsigned long) &av7110->ir; 374 375 if (av_cnt == 1) { 376 e = proc_create("av7110_ir", S_IWUSR, NULL, &av7110_ir_proc_fops); 377 if (e) 378 e->size = 4 + 256 * sizeof(u16); 379 } 380 381 tasklet_init(&av7110->ir.ir_tasklet, av7110_emit_key, (unsigned long) &av7110->ir); 382 av7110->ir.ir_handler = ir_handler; 383 384 return 0; 385} 386 387 388void __devexit av7110_ir_exit(struct av7110 *av7110) 389{ 390 int i; 391 392 if (av_cnt == 0) 393 return; 394 395 del_timer_sync(&av7110->ir.keyup_timer); 396 av7110->ir.ir_handler = NULL; 397 tasklet_kill(&av7110->ir.ir_tasklet); 398 399 for (i = 0; i < av_cnt; i++) 400 if (av_list[i] == av7110) { 401 av_list[i] = av_list[av_cnt-1]; 402 av_list[av_cnt-1] = NULL; 403 break; 404 } 405 406 if (av_cnt == 1) 407 remove_proc_entry("av7110_ir", NULL); 408 409 input_unregister_device(av7110->ir.input_dev); 410 411 av_cnt--; 412} 413 414//MODULE_AUTHOR("Holger Waechtler <holger@convergence.de>, Oliver Endriss <o.endriss@gmx.de>"); 415//MODULE_LICENSE("GPL"); 416