Skip to content
Snippets Groups Projects
rc-main.c 29 KiB
Newer Older
		rc_map = get_rc_map(RC_MAP_EMPTY);
	if (!rc_map || !rc_map->scan || rc_map->size == 0)
		return -EINVAL;

	set_bit(EV_KEY, dev->input_dev->evbit);
	set_bit(EV_REP, dev->input_dev->evbit);
	set_bit(EV_MSC, dev->input_dev->evbit);
	set_bit(MSC_SCAN, dev->input_dev->mscbit);
	if (dev->open)
		dev->input_dev->open = ir_open;
	if (dev->close)
		dev->input_dev->close = ir_close;

	dev->devno = (unsigned long)(atomic_inc_return(&devno) - 1);
	dev_set_name(&dev->dev, "rc%ld", dev->devno);
	dev_set_drvdata(&dev->dev, dev);
	rc = device_add(&dev->dev);
	if (rc)
	rc = ir_setkeytable(dev, rc_map);
	if (rc)
		goto out_dev;

	dev->input_dev->dev.parent = &dev->dev;
	memcpy(&dev->input_dev->id, &dev->input_id, sizeof(dev->input_id));
	dev->input_dev->phys = dev->input_phys;
	dev->input_dev->name = dev->input_name;
	rc = input_register_device(dev->input_dev);
	if (rc)
		goto out_table;
	/*
	 * 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. Note that this must be
	 * set after the call to input_register_device().
	 */
	dev->input_dev->rep[REP_DELAY] = 500;

	path = kobject_get_path(&dev->dev.kobj, GFP_KERNEL);
	printk(KERN_INFO "%s: %s as %s\n",
		dev_name(&dev->dev),
		dev->input_name ? dev->input_name : "Unspecified device",
	if (dev->driver_type == RC_DRIVER_IR_RAW) {
		rc = ir_raw_event_register(dev);
		if (rc < 0)
			goto out_input;
	}

	if (dev->change_protocol) {
		rc = dev->change_protocol(dev, rc_map->rc_type);
		if (rc < 0)
			goto out_raw;
	}

	IR_dprintk(1, "Registered rc%ld (driver: %s, remote: %s, mode %s)\n",
		   dev->devno,
		   dev->driver_name ? dev->driver_name : "unknown",
		   rc_map->name ? rc_map->name : "unknown",
		   dev->driver_type == RC_DRIVER_IR_RAW ? "raw" : "cooked");


out_raw:
	if (dev->driver_type == RC_DRIVER_IR_RAW)
		ir_raw_event_unregister(dev);
out_input:
	input_unregister_device(dev->input_dev);
	dev->input_dev = NULL;
out_table:
	ir_free_table(&dev->rc_map);
out_dev:
	device_del(&dev->dev);
	return rc;
EXPORT_SYMBOL_GPL(rc_register_device);
void rc_unregister_device(struct rc_dev *dev)
	del_timer_sync(&dev->timer_keyup);
	if (dev->driver_type == RC_DRIVER_IR_RAW)
		ir_raw_event_unregister(dev);

	input_unregister_device(dev->input_dev);
	dev->input_dev = NULL;

	ir_free_table(&dev->rc_map);
	IR_dprintk(1, "Freed keycode table\n");

	device_unregister(&dev->dev);
EXPORT_SYMBOL_GPL(rc_unregister_device);

/*
 * Init/exit code for the module. Basically, creates/removes /sys/class/rc
 */

static int __init rc_core_init(void)
{
	int rc = class_register(&ir_input_class);
	if (rc) {
		printk(KERN_ERR "rc_core: unable to register rc class\n");
		return rc;
	}

	/* Initialize/load the decoders/keymap code that will be used */
	ir_raw_init();
static void __exit rc_core_exit(void)
{
	class_unregister(&ir_input_class);
module_init(rc_core_init);
module_exit(rc_core_exit);
int rc_core_debug;    /* ir_debug level (0,1,2) */
EXPORT_SYMBOL_GPL(rc_core_debug);
module_param_named(debug, rc_core_debug, int, 0644);

MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
MODULE_LICENSE("GPL");