Beispiel #1
0
/**
 * 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);
}
Beispiel #2
0
/**
 * __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;
}
Beispiel #3
0
/**
 * __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;
}