/** * ir_input_unregister() - unregisters IR and frees resources * @input_dev: the struct input_dev descriptor of the device * This routine is used to free memory and de-register interfaces. */ void ir_input_unregister(struct input_dev *input_dev) { struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); struct ir_scancode_table *rc_tab; if (!ir_dev) return; IR_dprintk(1, "Freed keycode table\n"); del_timer_sync(&ir_dev->timer_keyup); if (ir_dev->props) if (ir_dev->props->driver_type == RC_DRIVER_IR_RAW) ir_raw_event_unregister(input_dev); rc_tab = &ir_dev->rc_tab; rc_tab->size = 0; kfree(rc_tab->scan); rc_tab->scan = NULL; ir_unregister_class(input_dev); kfree(ir_dev->driver_name); kfree(ir_dev); }
/** * __ir_input_register() - sets the IR keycode table and add the handlers * for keymap table get/set * @input_dev: the struct input_dev descriptor of the device * @rc_tab: the struct ir_scancode_table table of scancode/keymap * * This routine is used to initialize the input infrastructure * to work with an IR. * It will register the input/evdev interface for the device and * register the syfs code for IR class */ int __ir_input_register(struct input_dev *input_dev, const struct ir_scancode_table *rc_tab, struct ir_dev_props *props, const char *driver_name) { struct ir_input_dev *ir_dev; int rc; if (rc_tab->scan == NULL || !rc_tab->size) return -EINVAL; ir_dev = kzalloc(sizeof(*ir_dev), GFP_KERNEL); if (!ir_dev) return -ENOMEM; ir_dev->driver_name = kasprintf(GFP_KERNEL, "%s", driver_name); if (!ir_dev->driver_name) { rc = -ENOMEM; goto out_dev; } input_dev->getkeycode = ir_getkeycode; input_dev->setkeycode = ir_setkeycode; input_set_drvdata(input_dev, ir_dev); ir_dev->input_dev = input_dev; spin_lock_init(&ir_dev->rc_tab.lock); spin_lock_init(&ir_dev->keylock); setup_timer(&ir_dev->timer_keyup, ir_timer_keyup, (unsigned long)ir_dev); ir_dev->rc_tab.name = rc_tab->name; ir_dev->rc_tab.ir_type = rc_tab->ir_type; ir_dev->rc_tab.alloc = roundup_pow_of_two(rc_tab->size * sizeof(struct ir_scancode)); ir_dev->rc_tab.scan = kmalloc(ir_dev->rc_tab.alloc, GFP_KERNEL); ir_dev->rc_tab.size = ir_dev->rc_tab.alloc / sizeof(struct ir_scancode); if (props) { ir_dev->props = props; if (props->open) input_dev->open = ir_open; if (props->close) input_dev->close = ir_close; } if (!ir_dev->rc_tab.scan) { rc = -ENOMEM; goto out_name; } IR_dprintk(1, "Allocated space for %u keycode entries (%u bytes)\n", ir_dev->rc_tab.size, ir_dev->rc_tab.alloc); set_bit(EV_KEY, input_dev->evbit); set_bit(EV_REP, input_dev->evbit); set_bit(EV_MSC, input_dev->evbit); set_bit(MSC_SCAN, input_dev->mscbit); if (ir_setkeytable(input_dev, &ir_dev->rc_tab, rc_tab)) { rc = -ENOMEM; goto out_table; } rc = ir_register_class(input_dev); if (rc < 0) goto out_table; if (ir_dev->props) if (ir_dev->props->driver_type == RC_DRIVER_IR_RAW) { rc = ir_raw_event_register(input_dev); if (rc < 0) goto out_event; } IR_dprintk(1, "Registered input device on %s for %s remote%s.\n", driver_name, rc_tab->name, (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_IR_RAW) ? " in raw mode" : ""); /* * Default delay of 250ms is too short for some protocols, expecially * since the timeout is currently set to 250ms. Increase it to 500ms, * to avoid wrong repetition of the keycodes. */ input_dev->rep[REP_DELAY] = 500; return 0; out_event: ir_unregister_class(input_dev); out_table: kfree(ir_dev->rc_tab.scan); out_name: kfree(ir_dev->driver_name); out_dev: kfree(ir_dev); return rc; }
/** * __ir_input_register() - sets the IR keycode table and add the handlers * for keymap table get/set * @input_dev: the struct input_dev descriptor of the device * @rc_tab: the struct ir_scancode_table table of scancode/keymap * * This routine is used to initialize the input infrastructure * to work with an IR. * It will register the input/evdev interface for the device and * register the syfs code for IR class */ int __ir_input_register(struct input_dev *input_dev, const struct ir_scancode_table *rc_tab, const struct ir_dev_props *props, const char *driver_name) { struct ir_input_dev *ir_dev; int rc; if (rc_tab->scan == NULL || !rc_tab->size) return -EINVAL; ir_dev = kzalloc(sizeof(*ir_dev), GFP_KERNEL); if (!ir_dev) return -ENOMEM; ir_dev->driver_name = kasprintf(GFP_KERNEL, "%s", driver_name); if (!ir_dev->driver_name) { rc = -ENOMEM; goto out_dev; } input_dev->getkeycode = ir_getkeycode; input_dev->setkeycode = ir_setkeycode; input_set_drvdata(input_dev, ir_dev); ir_dev->input_dev = input_dev; spin_lock_init(&ir_dev->rc_tab.lock); spin_lock_init(&ir_dev->keylock); setup_timer(&ir_dev->timer_keyup, ir_timer_keyup, (unsigned long)ir_dev); ir_dev->rc_tab.name = rc_tab->name; ir_dev->rc_tab.ir_type = rc_tab->ir_type; ir_dev->rc_tab.alloc = roundup_pow_of_two(rc_tab->size * sizeof(struct ir_scancode)); ir_dev->rc_tab.scan = kmalloc(ir_dev->rc_tab.alloc, GFP_KERNEL); ir_dev->rc_tab.size = ir_dev->rc_tab.alloc / sizeof(struct ir_scancode); if (props) { ir_dev->props = props; if (props->open) input_dev->open = ir_open; if (props->close) input_dev->close = ir_close; } if (!ir_dev->rc_tab.scan) { rc = -ENOMEM; goto out_name; } IR_dprintk(1, "Allocated space for %u keycode entries (%u bytes)\n", ir_dev->rc_tab.size, ir_dev->rc_tab.alloc); set_bit(EV_KEY, input_dev->evbit); set_bit(EV_REP, input_dev->evbit); if (ir_setkeytable(input_dev, &ir_dev->rc_tab, rc_tab)) { rc = -ENOMEM; goto out_table; } rc = ir_register_class(input_dev); if (rc < 0) goto out_table; if (ir_dev->props) if (ir_dev->props->driver_type == RC_DRIVER_IR_RAW) { rc = ir_raw_event_register(input_dev); if (rc < 0) goto out_event; } IR_dprintk(1, "Registered input device on %s for %s remote.\n", driver_name, rc_tab->name); return 0; out_event: ir_unregister_class(input_dev); out_table: kfree(ir_dev->rc_tab.scan); out_name: kfree(ir_dev->driver_name); out_dev: kfree(ir_dev); return rc; }