#include <linux/proc_fs.h>
#include <linux/pci.h>
#include <linux/dma-mapping.h>
-#include <linux/input.h>
#include <linux/slab.h>
#include <media/ir-core.h>
/* infrared remote control */
struct infrared {
- struct input_dev *input_dev;
+ struct rc_dev *dev;
char input_phys[32];
struct work_struct work;
u32 ir_command;
data = (ircom >> 8) & 0x7f;
- ir_keydown(ir->input_dev, data, 0);
+ ir_keydown(ir->dev, data, 0);
}
/* work handler */
int __devinit dm1105_ir_init(struct dm1105_dev *dm1105)
{
- struct input_dev *input_dev;
- char *ir_codes = RC_MAP_DM1105_NEC;
+ struct rc_dev *dev;
int err = -ENOMEM;
- input_dev = input_allocate_device();
- if (!input_dev)
+ dev = rc_allocate_device();
+ if (!dev)
return -ENOMEM;
- dm1105->ir.input_dev = input_dev;
snprintf(dm1105->ir.input_phys, sizeof(dm1105->ir.input_phys),
"pci-%s/ir0", pci_name(dm1105->pdev));
- input_dev->name = "DVB on-card IR receiver";
- input_dev->phys = dm1105->ir.input_phys;
- input_dev->id.bustype = BUS_PCI;
- input_dev->id.version = 1;
+ dev->driver_name = MODULE_NAME;
+ dev->map_name = RC_MAP_DM1105_NEC;
+ dev->driver_type = RC_DRIVER_SCANCODE;
+ dev->input_name = "DVB on-card IR receiver";
+ dev->input_phys = dm1105->ir.input_phys;
+ dev->input_id.bustype = BUS_PCI;
+ dev->input_id.version = 1;
if (dm1105->pdev->subsystem_vendor) {
- input_dev->id.vendor = dm1105->pdev->subsystem_vendor;
- input_dev->id.product = dm1105->pdev->subsystem_device;
+ dev->input_id.vendor = dm1105->pdev->subsystem_vendor;
+ dev->input_id.product = dm1105->pdev->subsystem_device;
} else {
- input_dev->id.vendor = dm1105->pdev->vendor;
- input_dev->id.product = dm1105->pdev->device;
+ dev->input_id.vendor = dm1105->pdev->vendor;
+ dev->input_id.product = dm1105->pdev->device;
}
-
- input_dev->dev.parent = &dm1105->pdev->dev;
+ dev->dev.parent = &dm1105->pdev->dev;
INIT_WORK(&dm1105->ir.work, dm1105_emit_key);
- err = ir_input_register(input_dev, ir_codes, NULL, MODULE_NAME);
+ err = rc_register_device(dev);
if (err < 0) {
- input_free_device(input_dev);
+ rc_free_device(dev);
return err;
}
+ dm1105->ir.dev = dev;
return 0;
}
void __devexit dm1105_ir_exit(struct dm1105_dev *dm1105)
{
- ir_input_unregister(dm1105->ir.input_dev);
+ rc_unregister_device(dm1105->ir.dev);
}
static int __devinit dm1105_hw_init(struct dm1105_dev *dev)
priv->rc_keycode = buf[12] << 16 |
buf[13] << 8 | buf[14];
}
- ir_keydown(d->rc_input_dev, priv->rc_keycode, 0);
+ ir_keydown(d->rc_dev, priv->rc_keycode, 0);
} else {
priv->rc_keycode = 0; /* clear just for sure */
}
} else if (priv->rc_repeat != buf[6] || buf[0]) {
deb_rc("%s: key repeated\n", __func__);
- ir_keydown(d->rc_input_dev, priv->rc_keycode, 0);
+ ir_keydown(d->rc_dev, priv->rc_keycode, 0);
} else {
deb_rc("%s: no key press\n", __func__);
}
.module_name = "af9015",
.rc_query = af9015_rc_query,
.rc_interval = AF9015_RC_INTERVAL,
- .rc_props = {
- .allowed_protos = IR_TYPE_NEC,
- },
+ .allowed_protos = IR_TYPE_NEC,
},
.i2c_algo = &af9015_i2c_algo,
.module_name = "af9015",
.rc_query = af9015_rc_query,
.rc_interval = AF9015_RC_INTERVAL,
- .rc_props = {
- .allowed_protos = IR_TYPE_NEC,
- },
+ .allowed_protos = IR_TYPE_NEC,
},
.i2c_algo = &af9015_i2c_algo,
.module_name = "af9015",
.rc_query = af9015_rc_query,
.rc_interval = AF9015_RC_INTERVAL,
- .rc_props = {
- .allowed_protos = IR_TYPE_NEC,
- },
+ .allowed_protos = IR_TYPE_NEC,
},
.i2c_algo = &af9015_i2c_algo,
if (ircode[0]) {
deb_rc("%s: key pressed %02x\n", __func__, ircode[1]);
- ir_keydown(d->rc_input_dev, 0x08 << 8 | ircode[1], 0);
+ ir_keydown(d->rc_dev, 0x08 << 8 | ircode[1], 0);
}
return 0;
extern struct i2c_algorithm dib0700_i2c_algo;
extern int dib0700_identify_state(struct usb_device *udev, struct dvb_usb_device_properties *props,
struct dvb_usb_device_description **desc, int *cold);
-extern int dib0700_change_protocol(void *priv, u64 ir_type);
+extern int dib0700_change_protocol(struct rc_dev *dev, u64 ir_type);
extern int dib0700_device_count;
extern int dvb_usb_dib0700_ir_proto;
return dib0700_ctrl_wr(adap->dev, b, 4);
}
-int dib0700_change_protocol(void *priv, u64 ir_type)
+int dib0700_change_protocol(struct rc_dev *rc, u64 ir_type)
{
- struct dvb_usb_device *d = priv;
+ struct dvb_usb_device *d = rc->priv;
struct dib0700_state *st = d->priv;
u8 rc_setup[3] = { REQUEST_SET_RC, 0, 0 };
int new_proto, ret;
if (d == NULL)
return;
- if (d->rc_input_dev == NULL) {
+ if (d->rc_dev == NULL) {
/* This will occur if disable_rc_polling=1 */
usb_free_urb(purb);
return;
goto resubmit;
}
- ir_keydown(d->rc_input_dev, keycode, toggle);
+ ir_keydown(d->rc_dev, keycode, toggle);
resubmit:
/* Clean the buffer before we requeue */
d->last_event = keycode;
}
- ir_keydown(d->rc_input_dev, keycode, 0);
+ ir_keydown(d->rc_dev, keycode, 0);
break;
default:
/* RC-5 protocol changes toggle bit on new keypress */
keycode = key[3-2] << 8 | key[3-3];
toggle = key[3-1];
- ir_keydown(d->rc_input_dev, keycode, toggle);
+ ir_keydown(d->rc_dev, keycode, toggle);
break;
}
.rc_interval = DEFAULT_RC_INTERVAL,
.rc_codes = RC_MAP_DIB0700_RC5_TABLE,
.rc_query = dib0700_rc_query_old_firmware,
- .rc_props = {
- .allowed_protos = IR_TYPE_RC5 |
- IR_TYPE_RC6 |
- IR_TYPE_NEC,
- .change_protocol = dib0700_change_protocol,
- },
+ .allowed_protos = IR_TYPE_RC5 |
+ IR_TYPE_RC6 |
+ IR_TYPE_NEC,
+ .change_protocol = dib0700_change_protocol,
},
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
.rc_interval = DEFAULT_RC_INTERVAL,
.rc_codes = RC_MAP_DIB0700_RC5_TABLE,
.rc_query = dib0700_rc_query_old_firmware,
- .rc_props = {
- .allowed_protos = IR_TYPE_RC5 |
- IR_TYPE_RC6 |
- IR_TYPE_NEC,
- .change_protocol = dib0700_change_protocol,
- },
+ .allowed_protos = IR_TYPE_RC5 |
+ IR_TYPE_RC6 |
+ IR_TYPE_NEC,
+ .change_protocol = dib0700_change_protocol,
},
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
.rc_interval = DEFAULT_RC_INTERVAL,
.rc_codes = RC_MAP_DIB0700_RC5_TABLE,
.rc_query = dib0700_rc_query_old_firmware,
- .rc_props = {
- .allowed_protos = IR_TYPE_RC5 |
- IR_TYPE_RC6 |
- IR_TYPE_NEC,
- .change_protocol = dib0700_change_protocol,
- },
+ .allowed_protos = IR_TYPE_RC5 |
+ IR_TYPE_RC6 |
+ IR_TYPE_NEC,
+ .change_protocol = dib0700_change_protocol,
},
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
.rc_codes = RC_MAP_DIB0700_RC5_TABLE,
.module_name = "dib0700",
.rc_query = dib0700_rc_query_old_firmware,
- .rc_props = {
- .allowed_protos = IR_TYPE_RC5 |
- IR_TYPE_RC6 |
- IR_TYPE_NEC,
- .change_protocol = dib0700_change_protocol,
- },
+ .allowed_protos = IR_TYPE_RC5 |
+ IR_TYPE_RC6 |
+ IR_TYPE_NEC,
+ .change_protocol = dib0700_change_protocol,
},
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
.rc_codes = RC_MAP_DIB0700_RC5_TABLE,
.module_name = "dib0700",
.rc_query = dib0700_rc_query_old_firmware,
- .rc_props = {
- .allowed_protos = IR_TYPE_RC5 |
- IR_TYPE_RC6 |
- IR_TYPE_NEC,
- .change_protocol = dib0700_change_protocol,
- },
+ .allowed_protos = IR_TYPE_RC5 |
+ IR_TYPE_RC6 |
+ IR_TYPE_NEC,
+ .change_protocol = dib0700_change_protocol,
},
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
.rc_codes = RC_MAP_DIB0700_RC5_TABLE,
.module_name = "dib0700",
.rc_query = dib0700_rc_query_old_firmware,
- .rc_props = {
- .allowed_protos = IR_TYPE_RC5 |
- IR_TYPE_RC6 |
- IR_TYPE_NEC,
- .change_protocol = dib0700_change_protocol,
- },
+ .allowed_protos = IR_TYPE_RC5 |
+ IR_TYPE_RC6 |
+ IR_TYPE_NEC,
+ .change_protocol = dib0700_change_protocol,
},
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
.rc_codes = RC_MAP_DIB0700_RC5_TABLE,
.module_name = "dib0700",
.rc_query = dib0700_rc_query_old_firmware,
- .rc_props = {
- .allowed_protos = IR_TYPE_RC5 |
- IR_TYPE_RC6 |
- IR_TYPE_NEC,
- .change_protocol = dib0700_change_protocol,
- },
+ .allowed_protos = IR_TYPE_RC5 |
+ IR_TYPE_RC6 |
+ IR_TYPE_NEC,
+ .change_protocol = dib0700_change_protocol,
},
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
.rc_codes = RC_MAP_DIB0700_NEC_TABLE,
.module_name = "dib0700",
.rc_query = dib0700_rc_query_old_firmware,
- .rc_props = {
- .allowed_protos = IR_TYPE_RC5 |
- IR_TYPE_RC6 |
- IR_TYPE_NEC,
- .change_protocol = dib0700_change_protocol,
- },
+ .allowed_protos = IR_TYPE_RC5 |
+ IR_TYPE_RC6 |
+ IR_TYPE_NEC,
+ .change_protocol = dib0700_change_protocol,
},
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
.rc_codes = RC_MAP_DIB0700_RC5_TABLE,
.module_name = "dib0700",
.rc_query = dib0700_rc_query_old_firmware,
- .rc_props = {
- .allowed_protos = IR_TYPE_RC5 |
- IR_TYPE_RC6 |
- IR_TYPE_NEC,
- .change_protocol = dib0700_change_protocol,
- },
+ .allowed_protos = IR_TYPE_RC5 |
+ IR_TYPE_RC6 |
+ IR_TYPE_NEC,
+ .change_protocol = dib0700_change_protocol,
},
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
.num_adapters = 1,
.rc_codes = RC_MAP_DIB0700_RC5_TABLE,
.module_name = "dib0700",
.rc_query = dib0700_rc_query_old_firmware,
- .rc_props = {
- .allowed_protos = IR_TYPE_RC5 |
- IR_TYPE_RC6 |
- IR_TYPE_NEC,
- .change_protocol = dib0700_change_protocol,
- },
+ .allowed_protos = IR_TYPE_RC5 |
+ IR_TYPE_RC6 |
+ IR_TYPE_NEC,
+ .change_protocol = dib0700_change_protocol,
},
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
.num_adapters = 1,
.rc_codes = RC_MAP_DIB0700_RC5_TABLE,
.module_name = "dib0700",
.rc_query = dib0700_rc_query_old_firmware,
- .rc_props = {
- .allowed_protos = IR_TYPE_RC5 |
- IR_TYPE_RC6 |
- IR_TYPE_NEC,
- .change_protocol = dib0700_change_protocol,
- },
+ .allowed_protos = IR_TYPE_RC5 |
+ IR_TYPE_RC6 |
+ IR_TYPE_NEC,
+ .change_protocol = dib0700_change_protocol,
},
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
.num_adapters = 1,
.rc_codes = RC_MAP_DIB0700_NEC_TABLE,
.module_name = "dib0700",
.rc_query = dib0700_rc_query_old_firmware,
- .rc_props = {
- .allowed_protos = IR_TYPE_RC5 |
- IR_TYPE_RC6 |
- IR_TYPE_NEC,
- .change_protocol = dib0700_change_protocol,
- },
+ .allowed_protos = IR_TYPE_RC5 |
+ IR_TYPE_RC6 |
+ IR_TYPE_NEC,
+ .change_protocol = dib0700_change_protocol,
},
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
.num_adapters = 2,
.rc_codes = RC_MAP_DIB0700_RC5_TABLE,
.module_name = "dib0700",
.rc_query = dib0700_rc_query_old_firmware,
- .rc_props = {
- .allowed_protos = IR_TYPE_RC5 |
- IR_TYPE_RC6 |
- IR_TYPE_NEC,
- .change_protocol = dib0700_change_protocol,
- },
+ .allowed_protos = IR_TYPE_RC5 |
+ IR_TYPE_RC6 |
+ IR_TYPE_NEC,
+ .change_protocol = dib0700_change_protocol,
},
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
.num_adapters = 1,
.rc_codes = RC_MAP_DIB0700_RC5_TABLE,
.module_name = "dib0700",
.rc_query = dib0700_rc_query_old_firmware,
- .rc_props = {
- .allowed_protos = IR_TYPE_RC5 |
- IR_TYPE_RC6 |
- IR_TYPE_NEC,
- .change_protocol = dib0700_change_protocol,
- },
+ .allowed_protos = IR_TYPE_RC5 |
+ IR_TYPE_RC6 |
+ IR_TYPE_NEC,
+ .change_protocol = dib0700_change_protocol,
},
},
};
d->last_event = event;
case REMOTE_KEY_REPEAT:
deb_rc("key repeated\n");
- input_event(d->rc_input_dev, EV_KEY, event, 1);
- input_sync(d->rc_input_dev);
- input_event(d->rc_input_dev, EV_KEY, d->last_event, 0);
- input_sync(d->rc_input_dev);
+ input_event(d->input_dev, EV_KEY, event, 1);
+ input_sync(d->input_dev);
+ input_event(d->input_dev, EV_KEY, d->last_event, 0);
+ input_sync(d->input_dev);
break;
default:
break;
schedule_delayed_work(&d->rc_query_work,msecs_to_jiffies(d->props.rc.legacy.rc_interval));
}
-static int legacy_dvb_usb_remote_init(struct dvb_usb_device *d,
- struct input_dev *input_dev)
+static int legacy_dvb_usb_remote_init(struct dvb_usb_device *d)
{
int i, err, rc_interval;
+ struct input_dev *input_dev;
+
+ input_dev = input_allocate_device();
+ if (!input_dev)
+ return -ENOMEM;
+
+ input_dev->evbit[0] = BIT_MASK(EV_KEY);
+ input_dev->name = "IR-receiver inside an USB DVB receiver";
+ input_dev->phys = d->rc_phys;
+ usb_to_input_id(d->udev, &input_dev->id);
+ input_dev->dev.parent = &d->udev->dev;
+ d->input_dev = input_dev;
+ d->rc_dev = NULL;
input_dev->getkeycode = legacy_dvb_usb_getkeycode;
input_dev->setkeycode = legacy_dvb_usb_setkeycode;
msecs_to_jiffies(d->props.rc.core.rc_interval));
}
-static int rc_core_dvb_usb_remote_init(struct dvb_usb_device *d,
- struct input_dev *input_dev)
+static int rc_core_dvb_usb_remote_init(struct dvb_usb_device *d)
{
int err, rc_interval;
+ struct rc_dev *dev;
+
+ dev = rc_allocate_device();
+ if (!dev)
+ return -ENOMEM;
- d->props.rc.core.rc_props.priv = d;
- err = ir_input_register(input_dev,
- d->props.rc.core.rc_codes,
- &d->props.rc.core.rc_props,
- d->props.rc.core.module_name);
- if (err < 0)
+ dev->driver_name = d->props.rc.core.module_name;
+ dev->map_name = d->props.rc.core.rc_codes;
+ dev->change_protocol = d->props.rc.core.change_protocol;
+ dev->allowed_protos = d->props.rc.core.allowed_protos;
+ dev->driver_type = RC_DRIVER_SCANCODE;
+ usb_to_input_id(d->udev, &dev->input_id);
+ dev->input_name = "IR-receiver inside an USB DVB receiver";
+ dev->input_phys = d->rc_phys;
+ dev->dev.parent = &d->udev->dev;
+ dev->priv = d;
+
+ err = rc_register_device(dev);
+ if (err < 0) {
+ rc_free_device(dev);
return err;
+ }
+
+ d->input_dev = NULL;
+ d->rc_dev = dev;
if (!d->props.rc.core.rc_query || d->props.rc.core.bulk_mode)
return 0;
int dvb_usb_remote_init(struct dvb_usb_device *d)
{
- struct input_dev *input_dev;
int err;
if (dvb_usb_disable_rc_polling)
usb_make_path(d->udev, d->rc_phys, sizeof(d->rc_phys));
strlcat(d->rc_phys, "/ir0", sizeof(d->rc_phys));
- input_dev = input_allocate_device();
- if (!input_dev)
- return -ENOMEM;
-
- input_dev->evbit[0] = BIT_MASK(EV_KEY);
- input_dev->name = "IR-receiver inside an USB DVB receiver";
- input_dev->phys = d->rc_phys;
- usb_to_input_id(d->udev, &input_dev->id);
- input_dev->dev.parent = &d->udev->dev;
-
/* Start the remote-control polling. */
if (d->props.rc.legacy.rc_interval < 40)
d->props.rc.legacy.rc_interval = 100; /* default */
- d->rc_input_dev = input_dev;
-
if (d->props.rc.mode == DVB_RC_LEGACY)
- err = legacy_dvb_usb_remote_init(d, input_dev);
+ err = legacy_dvb_usb_remote_init(d);
else
- err = rc_core_dvb_usb_remote_init(d, input_dev);
+ err = rc_core_dvb_usb_remote_init(d);
if (err)
return err;
cancel_rearming_delayed_work(&d->rc_query_work);
flush_scheduled_work();
if (d->props.rc.mode == DVB_RC_LEGACY)
- input_unregister_device(d->rc_input_dev);
+ input_unregister_device(d->input_dev);
else
- ir_input_unregister(d->rc_input_dev);
+ rc_unregister_device(d->rc_dev);
}
d->state &= ~DVB_USB_STATE_REMOTE;
return 0;
* struct dvb_rc properties of remote controller, using rc-core
* @rc_codes: name of rc codes table
* @protocol: type of protocol(s) currently used by the driver
+ * @allowed_protos: protocol(s) supported by the driver
+ * @change_protocol: callback to change protocol
* @rc_query: called to query an event event.
* @rc_interval: time in ms between two queries.
- * @rc_props: remote controller properties
* @bulk_mode: device supports bulk mode for RC (disable polling mode)
*/
struct dvb_rc {
char *rc_codes;
u64 protocol;
+ u64 allowed_protos;
+ int (*change_protocol)(struct rc_dev *dev, u64 ir_type);
char *module_name;
int (*rc_query) (struct dvb_usb_device *d);
int rc_interval;
- struct ir_dev_props rc_props;
bool bulk_mode; /* uses bulk mode */
};
*
* @i2c_adap: device's i2c_adapter if it uses I2CoverUSB
*
- * @rc_input_dev: input device for the remote control.
+ * @rc_dev: rc device for the remote control (rc-core mode)
+ * @input_dev: input device for the remote control (legacy mode)
* @rc_query_work: struct work_struct frequent rc queries
* @last_event: last triggered event
* @last_state: last state (no, pressed, repeat)
struct dvb_usb_adapter adapter[MAX_NO_OF_ADAPTER_PER_DEVICE];
/* remote control */
- struct input_dev *rc_input_dev;
+ struct rc_dev *rc_dev;
+ struct input_dev *input_dev;
char rc_phys[64];
struct delayed_work rc_query_work;
u32 last_event;
deb_info(1, "INT Key Keypress =%04x", keypress);
if (keypress > 0)
- ir_keydown(d->rc_input_dev, keypress, 0);
+ ir_keydown(d->rc_dev, keypress, 0);
return 0;
}
static int lme2510_int_service(struct dvb_usb_adapter *adap)
{
struct dvb_usb_device *d = adap->dev;
- struct input_dev *input_dev;
- char *ir_codes = RC_MAP_LME2510;
- int ret = 0;
+ struct rc_dev *rc;
+ int ret;
info("STA Configuring Remote");
- usb_make_path(d->udev, d->rc_phys, sizeof(d->rc_phys));
-
- strlcat(d->rc_phys, "/ir0", sizeof(d->rc_phys));
-
- input_dev = input_allocate_device();
- if (!input_dev)
+ rc = rc_allocate_device();
+ if (!rc)
return -ENOMEM;
- input_dev->name = "LME2510 Remote Control";
- input_dev->phys = d->rc_phys;
-
- usb_to_input_id(d->udev, &input_dev->id);
+ usb_make_path(d->udev, d->rc_phys, sizeof(d->rc_phys));
+ strlcat(d->rc_phys, "/ir0", sizeof(d->rc_phys));
- ret |= ir_input_register(input_dev, ir_codes, NULL, "LME 2510");
+ rc->input_name = "LME2510 Remote Control";
+ rc->input_phys = d->rc_phys;
+ rc->map_name = RC_MAP_LME2510;
+ rc->driver_name = "LME 2510";
+ usb_to_input_id(d->udev, &rc->input_id);
+ ret = rc_register_device(rc);
if (ret) {
- input_free_device(input_dev);
+ rc_free_device(rc);
return ret;
}
+ d->rc_dev = rc;
- d->rc_input_dev = input_dev;
/* Start the Interupt */
ret = lme2510_int_read(adap);
-
if (ret < 0) {
- ir_input_unregister(input_dev);
- input_free_device(input_dev);
+ rc_unregister_device(rc);
+ return -ENODEV;
}
- return (ret < 0) ? -ENODEV : 0;
+ return 0;
}
static u8 check_sum(u8 *p, u8 len)
usb_free_coherent(d->udev, 5000, st->buffer,
st->lme_urb->transfer_dma);
info("Interupt Service Stopped");
- ir_input_unregister(d->rc_input_dev);
+ rc_unregister_device(d->rc_dev);
info("Remote Stopped");
}
return buffer;
struct work_struct uart_work;
spinlock_t uart_lock;
- struct input_dev *rc;
+ struct rc_dev *rc;
+ char input_name[80];
+ char input_phys[80];
};
#define MANTIS_HIF_STATUS (mantis->gpio_status)
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include <linux/input.h>
#include <media/ir-core.h>
#include <linux/pci.h>
#include "mantis_uart.h"
#define MODULE_NAME "mantis_core"
+#define RC_MAP_MANTIS "rc-mantis"
static struct ir_scancode mantis_ir_table[] = {
{ 0x29, KEY_POWER },
{ 0x00, KEY_BLUE },
};
-struct ir_scancode_table ir_mantis = {
- .scan = mantis_ir_table,
- .size = ARRAY_SIZE(mantis_ir_table),
+static struct rc_keymap ir_mantis_map = {
+ .map = {
+ .scan = mantis_ir_table,
+ .size = ARRAY_SIZE(mantis_ir_table),
+ .ir_type = IR_TYPE_UNKNOWN,
+ .name = RC_MAP_MANTIS,
+ }
};
-EXPORT_SYMBOL_GPL(ir_mantis);
int mantis_input_init(struct mantis_pci *mantis)
{
- struct input_dev *rc;
- char name[80], dev[80];
+ struct rc_dev *dev;
int err;
- rc = input_allocate_device();
- if (!rc) {
- dprintk(MANTIS_ERROR, 1, "Input device allocate failed");
- return -ENOMEM;
- }
+ err = ir_register_map(&ir_mantis_map);
+ if (err)
+ goto out;
- sprintf(name, "Mantis %s IR receiver", mantis->hwconfig->model_name);
- sprintf(dev, "pci-%s/ir0", pci_name(mantis->pdev));
+ dev = rc_allocate_device();
+ if (!dev) {
+ dprintk(MANTIS_ERROR, 1, "Remote device allocation failed");
+ err = -ENOMEM;
+ goto out_map;
+ }
- rc->name = name;
- rc->phys = dev;
+ sprintf(mantis->input_name, "Mantis %s IR receiver", mantis->hwconfig->model_name);
+ sprintf(mantis->input_phys, "pci-%s/ir0", pci_name(mantis->pdev));
- rc->id.bustype = BUS_PCI;
- rc->id.vendor = mantis->vendor_id;
- rc->id.product = mantis->device_id;
- rc->id.version = 1;
- rc->dev = mantis->pdev->dev;
+ dev->input_name = mantis->input_name;
+ dev->input_phys = mantis->input_phys;
+ dev->input_id.bustype = BUS_PCI;
+ dev->input_id.vendor = mantis->vendor_id;
+ dev->input_id.product = mantis->device_id;
+ dev->input_id.version = 1;
+ dev->driver_name = MODULE_NAME;
+ dev->map_name = RC_MAP_MANTIS;
+ dev->dev.parent = &mantis->pdev->dev;
- err = __ir_input_register(rc, &ir_mantis, NULL, MODULE_NAME);
+ err = rc_register_device(dev);
if (err) {
dprintk(MANTIS_ERROR, 1, "IR device registration failed, ret = %d", err);
- input_free_device(rc);
- return -ENODEV;
+ goto out_dev;
}
- mantis->rc = rc;
-
+ mantis->rc = dev;
return 0;
+
+out_dev:
+ rc_free_device(dev);
+out_map:
+ ir_unregister_map(&ir_mantis_map);
+out:
+ return err;
}
int mantis_exit(struct mantis_pci *mantis)
{
- struct input_dev *rc = mantis->rc;
-
- ir_input_unregister(rc);
-
+ rc_unregister_device(mantis->rc);
+ ir_unregister_map(&ir_mantis_map);
return 0;
}
+
int rc;
void *buffer;
- coredev->ir.input_dev = NULL;
+ coredev->ir.dev = NULL;
ir_io = sms_get_board(smscore_get_board_id(coredev))->board_cfg.ir;
if (ir_io) {/* only if IR port exist we use IR sub-module */
sms_info("IR loading");
ev.duration = abs(samples[i]) * 1000; /* Convert to ns */
ev.pulse = (samples[i] > 0) ? false : true;
- ir_raw_event_store(coredev->ir.input_dev, &ev);
+ ir_raw_event_store(coredev->ir.dev, &ev);
}
- ir_raw_event_handle(coredev->ir.input_dev);
+ ir_raw_event_handle(coredev->ir.dev);
}
int sms_ir_init(struct smscore_device_t *coredev)
{
- struct input_dev *input_dev;
+ int err;
int board_id = smscore_get_board_id(coredev);
+ struct rc_dev *dev;
- sms_log("Allocating input device");
- input_dev = input_allocate_device();
- if (!input_dev) {
+ sms_log("Allocating rc device");
+ dev = rc_allocate_device();
+ if (!dev) {
sms_err("Not enough memory");
return -ENOMEM;
}
- coredev->ir.input_dev = input_dev;
-
coredev->ir.controller = 0; /* Todo: vega/nova SPI number */
coredev->ir.timeout = IR_DEFAULT_TIMEOUT;
sms_log("IR port %d, timeout %d ms",
strlcpy(coredev->ir.phys, coredev->devpath, sizeof(coredev->ir.phys));
strlcat(coredev->ir.phys, "/ir0", sizeof(coredev->ir.phys));
- input_dev->name = coredev->ir.name;
- input_dev->phys = coredev->ir.phys;
- input_dev->dev.parent = coredev->device;
+ dev->input_name = coredev->ir.name;
+ dev->input_phys = coredev->ir.phys;
+ dev->dev.parent = coredev->device;
#if 0
/* TODO: properly initialize the parameters bellow */
- input_dev->id.bustype = BUS_USB;
- input_dev->id.version = 1;
- input_dev->id.vendor = le16_to_cpu(dev->udev->descriptor.idVendor);
- input_dev->id.product = le16_to_cpu(dev->udev->descriptor.idProduct);
+ dev->input_id.bustype = BUS_USB;
+ dev->input_id.version = 1;
+ dev->input_id.vendor = le16_to_cpu(dev->udev->descriptor.idVendor);
+ dev->input_id.product = le16_to_cpu(dev->udev->descriptor.idProduct);
#endif
- coredev->ir.props.priv = coredev;
- coredev->ir.props.driver_type = RC_DRIVER_IR_RAW;
- coredev->ir.props.allowed_protos = IR_TYPE_ALL;
+ dev->priv = coredev;
+ dev->driver_type = RC_DRIVER_IR_RAW;
+ dev->allowed_protos = IR_TYPE_ALL;
+ dev->map_name = sms_get_board(board_id)->rc_codes;
+ dev->driver_name = MODULE_NAME;
- sms_log("Input device (IR) %s is set for key events", input_dev->name);
+ sms_log("Input device (IR) %s is set for key events", dev->input_name);
- if (ir_input_register(input_dev, sms_get_board(board_id)->rc_codes,
- &coredev->ir.props, MODULE_NAME)) {
+ err = rc_register_device(dev);
+ if (err < 0) {
sms_err("Failed to register device");
- input_free_device(input_dev);
- return -EACCES;
+ rc_free_device(dev);
+ return err;
}
+ coredev->ir.dev = dev;
return 0;
}
void sms_ir_exit(struct smscore_device_t *coredev)
{
- if (coredev->ir.input_dev)
- ir_input_unregister(coredev->ir.input_dev);
+ if (coredev->ir.dev)
+ rc_unregister_device(coredev->ir.dev);
sms_log("");
}
struct smscore_device_t;
struct ir_t {
- struct input_dev *input_dev;
+ struct rc_dev *dev;
char name[40];
char phys[32];
char *rc_codes;
u64 protocol;
- struct ir_dev_props props;
u32 timeout;
u32 controller;
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
-#include <linux/input.h>
#include <linux/spinlock.h>
#include <media/ir-core.h>
DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
struct budget_ci_ir {
- struct input_dev *dev;
+ struct rc_dev *dev;
struct tasklet_struct msp430_irq_tasklet;
char name[72]; /* 40 + 32 for (struct saa7146_dev).name */
char phys[32];
static void msp430_ir_interrupt(unsigned long data)
{
struct budget_ci *budget_ci = (struct budget_ci *) data;
- struct input_dev *dev = budget_ci->ir.dev;
+ struct rc_dev *dev = budget_ci->ir.dev;
u32 command = ttpci_budget_debiread(&budget_ci->budget, DEBINOSWAP, DEBIADDR_IR, 2, 1, 0) >> 8;
/*
static int msp430_ir_init(struct budget_ci *budget_ci)
{
struct saa7146_dev *saa = budget_ci->budget.dev;
- struct input_dev *input_dev = budget_ci->ir.dev;
+ struct rc_dev *dev;
int error;
- char *ir_codes = NULL;
-
- budget_ci->ir.dev = input_dev = input_allocate_device();
- if (!input_dev) {
+ dev = rc_allocate_device();
+ if (!dev) {
printk(KERN_ERR "budget_ci: IR interface initialisation failed\n");
return -ENOMEM;
}
snprintf(budget_ci->ir.phys, sizeof(budget_ci->ir.phys),
"pci-%s/ir0", pci_name(saa->pci));
- input_dev->name = budget_ci->ir.name;
-
- input_dev->phys = budget_ci->ir.phys;
- input_dev->id.bustype = BUS_PCI;
- input_dev->id.version = 1;
+ dev->driver_name = MODULE_NAME;
+ dev->input_name = budget_ci->ir.name;
+ dev->input_phys = budget_ci->ir.phys;
+ dev->input_id.bustype = BUS_PCI;
+ dev->input_id.version = 1;
if (saa->pci->subsystem_vendor) {
- input_dev->id.vendor = saa->pci->subsystem_vendor;
- input_dev->id.product = saa->pci->subsystem_device;
+ dev->input_id.vendor = saa->pci->subsystem_vendor;
+ dev->input_id.product = saa->pci->subsystem_device;
} else {
- input_dev->id.vendor = saa->pci->vendor;
- input_dev->id.product = saa->pci->device;
+ dev->input_id.vendor = saa->pci->vendor;
+ dev->input_id.product = saa->pci->device;
}
- input_dev->dev.parent = &saa->pci->dev;
+ dev->dev.parent = &saa->pci->dev;
if (rc5_device < 0)
budget_ci->ir.rc5_device = IR_DEVICE_ANY;
case 0x1011:
case 0x1012:
/* The hauppauge keymap is a superset of these remotes */
- ir_codes = RC_MAP_HAUPPAUGE_NEW;
+ dev->map_name = RC_MAP_HAUPPAUGE_NEW;
if (rc5_device < 0)
budget_ci->ir.rc5_device = 0x1f;
case 0x1019:
case 0x101a:
/* for the Technotrend 1500 bundled remote */
- ir_codes = RC_MAP_TT_1500;
+ dev->map_name = RC_MAP_TT_1500;
break;
default:
/* unknown remote */
- ir_codes = RC_MAP_BUDGET_CI_OLD;
+ dev->map_name = RC_MAP_BUDGET_CI_OLD;
break;
}
- error = ir_input_register(input_dev, ir_codes, NULL, MODULE_NAME);
+ error = rc_register_device(dev);
if (error) {
printk(KERN_ERR "budget_ci: could not init driver for IR device (code %d)\n", error);
+ rc_free_device(dev);
return error;
}
- /* note: these must be after input_register_device */
- input_dev->rep[REP_DELAY] = 400;
- input_dev->rep[REP_PERIOD] = 250;
+ budget_ci->ir.dev = dev;
tasklet_init(&budget_ci->ir.msp430_irq_tasklet, msp430_ir_interrupt,
(unsigned long) budget_ci);
static void msp430_ir_deinit(struct budget_ci *budget_ci)
{
struct saa7146_dev *saa = budget_ci->budget.dev;
- struct input_dev *dev = budget_ci->ir.dev;
SAA7146_IER_DISABLE(saa, MASK_06);
saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT);
tasklet_kill(&budget_ci->ir.msp430_irq_tasklet);
- ir_input_unregister(dev);
+ rc_unregister_device(budget_ci->ir.dev);
}
static int ciintf_read_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address)
#include <linux/interrupt.h>
#include <linux/sched.h>
#include <linux/slab.h>
-#include <linux/input.h>
#include <media/ir-core.h>
-#include <media/ir-common.h>
#include "ene_ir.h"
static int sample_period;
ev.carrier_report = true;
ev.carrier = carrier;
ev.duty_cycle = duty_cycle;
- ir_raw_event_store(dev->idev, &ev);
+ ir_raw_event_store(dev->rdev, &ev);
}
}
select_timeout:
if (dev->rx_fan_input_inuse) {
- dev->props->rx_resolution = MS_TO_NS(ENE_FW_SAMPLE_PERIOD_FAN);
+ dev->rdev->rx_resolution = MS_TO_NS(ENE_FW_SAMPLE_PERIOD_FAN);
/* Fan input doesn't support timeouts, it just ends the
input with a maximum sample */
- dev->props->min_timeout = dev->props->max_timeout =
+ dev->rdev->min_timeout = dev->rdev->max_timeout =
MS_TO_NS(ENE_FW_SMPL_BUF_FAN_MSK *
ENE_FW_SAMPLE_PERIOD_FAN);
} else {
- dev->props->rx_resolution = MS_TO_NS(sample_period);
+ dev->rdev->rx_resolution = MS_TO_NS(sample_period);
/* Theoreticly timeout is unlimited, but we cap it
* because it was seen that on one device, it
* would stop sending spaces after around 250 msec.
* Besides, this is close to 2^32 anyway and timeout is u32.
*/
- dev->props->min_timeout = MS_TO_NS(127 * sample_period);
- dev->props->max_timeout = MS_TO_NS(200000);
+ dev->rdev->min_timeout = MS_TO_NS(127 * sample_period);
+ dev->rdev->max_timeout = MS_TO_NS(200000);
}
if (dev->hw_learning_and_tx_capable)
- dev->props->tx_resolution = MS_TO_NS(sample_period);
+ dev->rdev->tx_resolution = MS_TO_NS(sample_period);
- if (dev->props->timeout > dev->props->max_timeout)
- dev->props->timeout = dev->props->max_timeout;
- if (dev->props->timeout < dev->props->min_timeout)
- dev->props->timeout = dev->props->min_timeout;
+ if (dev->rdev->timeout > dev->rdev->max_timeout)
+ dev->rdev->timeout = dev->rdev->max_timeout;
+ if (dev->rdev->timeout < dev->rdev->min_timeout)
+ dev->rdev->timeout = dev->rdev->min_timeout;
}
/* Enable the device for receive */
ene_set_reg_mask(dev, ENE_FW1, ENE_FW1_ENABLE | ENE_FW1_IRQ);
/* enter idle mode */
- ir_raw_event_set_idle(dev->idev, true);
+ ir_raw_event_set_idle(dev->rdev, true);
dev->rx_enabled = true;
}
/* disable hardware IRQ and firmware flag */
ene_clear_reg_mask(dev, ENE_FW1, ENE_FW1_ENABLE | ENE_FW1_IRQ);
- ir_raw_event_set_idle(dev->idev, true);
+ ir_raw_event_set_idle(dev->rdev, true);
dev->rx_enabled = false;
}
ev.duration = MS_TO_NS(hw_sample);
ev.pulse = pulse;
- ir_raw_event_store_with_filter(dev->idev, &ev);
+ ir_raw_event_store_with_filter(dev->rdev, &ev);
}
- ir_raw_event_handle(dev->idev);
+ ir_raw_event_handle(dev->rdev);
unlock:
spin_unlock_irqrestore(&dev->hw_lock, flags);
return retval;
dev->learning_mode_enabled = learning_mode_force;
/* Set reasonable default timeout */
- dev->props->timeout = MS_TO_NS(150000);
+ dev->rdev->timeout = MS_TO_NS(150000);
}
/* Upload all hardware settings at once. Used at load and resume time */
}
/* outside interface: called on first open*/
-static int ene_open(void *data)
+static int ene_open(struct rc_dev *rdev)
{
- struct ene_device *dev = (struct ene_device *)data;
+ struct ene_device *dev = rdev->priv;
unsigned long flags;
spin_lock_irqsave(&dev->hw_lock, flags);
}
/* outside interface: called on device close*/
-static void ene_close(void *data)
+static void ene_close(struct rc_dev *rdev)
{
- struct ene_device *dev = (struct ene_device *)data;
+ struct ene_device *dev = rdev->priv;
unsigned long flags;
spin_lock_irqsave(&dev->hw_lock, flags);
}
/* outside interface: set transmitter mask */
-static int ene_set_tx_mask(void *data, u32 tx_mask)
+static int ene_set_tx_mask(struct rc_dev *rdev, u32 tx_mask)
{
- struct ene_device *dev = (struct ene_device *)data;
+ struct ene_device *dev = rdev->priv;
dbg("TX: attempt to set transmitter mask %02x", tx_mask);
/* invalid txmask */
}
/* outside interface : set tx carrier */
-static int ene_set_tx_carrier(void *data, u32 carrier)
+static int ene_set_tx_carrier(struct rc_dev *rdev, u32 carrier)
{
- struct ene_device *dev = (struct ene_device *)data;
+ struct ene_device *dev = rdev->priv;
u32 period = 2000000 / carrier;
dbg("TX: attempt to set tx carrier to %d kHz", carrier);
}
/*outside interface : set tx duty cycle */
-static int ene_set_tx_duty_cycle(void *data, u32 duty_cycle)
+static int ene_set_tx_duty_cycle(struct rc_dev *rdev, u32 duty_cycle)
{
- struct ene_device *dev = (struct ene_device *)data;
+ struct ene_device *dev = rdev->priv;
dbg("TX: setting duty cycle to %d%%", duty_cycle);
dev->tx_duty_cycle = duty_cycle;
ene_tx_set_carrier(dev);
}
/* outside interface: enable learning mode */
-static int ene_set_learning_mode(void *data, int enable)
+static int ene_set_learning_mode(struct rc_dev *rdev, int enable)
{
- struct ene_device *dev = (struct ene_device *)data;
+ struct ene_device *dev = rdev->priv;
unsigned long flags;
if (enable == dev->learning_mode_enabled)
return 0;
return 0;
}
-static int ene_set_carrier_report(void *data, int enable)
+static int ene_set_carrier_report(struct rc_dev *rdev, int enable)
{
- struct ene_device *dev = (struct ene_device *)data;
+ struct ene_device *dev = rdev->priv;
unsigned long flags;
if (enable == dev->carrier_detect_enabled)
}
/* outside interface: enable or disable idle mode */
-static void ene_set_idle(void *data, bool idle)
+static void ene_set_idle(struct rc_dev *rdev, bool idle)
{
+ struct ene_device *dev = rdev->priv;
+
if (idle) {
- ene_rx_reset((struct ene_device *)data);
+ ene_rx_reset(dev);
dbg("RX: end of data");
}
}
/* outside interface: transmit */
-static int ene_transmit(void *data, int *buf, u32 n)
+static int ene_transmit(struct rc_dev *rdev, int *buf, u32 n)
{
- struct ene_device *dev = (struct ene_device *)data;
+ struct ene_device *dev = rdev->priv;
unsigned long flags;
dev->tx_buffer = buf;
static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id)
{
int error = -ENOMEM;
- struct ir_dev_props *ir_props;
- struct input_dev *input_dev;
+ struct rc_dev *rdev;
struct ene_device *dev;
/* allocate memory */
- input_dev = input_allocate_device();
- ir_props = kzalloc(sizeof(struct ir_dev_props), GFP_KERNEL);
dev = kzalloc(sizeof(struct ene_device), GFP_KERNEL);
-
- if (!input_dev || !ir_props || !dev)
+ rdev = rc_allocate_device();
+ if (!dev || !rdev)
goto error1;
/* validate resources */
if (!dev->hw_learning_and_tx_capable)
learning_mode_force = false;
- ir_props->driver_type = RC_DRIVER_IR_RAW;
- ir_props->allowed_protos = IR_TYPE_ALL;
- ir_props->priv = dev;
- ir_props->open = ene_open;
- ir_props->close = ene_close;
- ir_props->s_idle = ene_set_idle;
-
- dev->props = ir_props;
- dev->idev = input_dev;
+ rdev->driver_type = RC_DRIVER_IR_RAW;
+ rdev->allowed_protos = IR_TYPE_ALL;
+ rdev->priv = dev;
+ rdev->open = ene_open;
+ rdev->close = ene_close;
+ rdev->s_idle = ene_set_idle;
+ rdev->driver_name = ENE_DRIVER_NAME;
+ rdev->map_name = RC_MAP_RC6_MCE;
+ rdev->input_name = "ENE eHome Infrared Remote Receiver";
if (dev->hw_learning_and_tx_capable) {
- ir_props->s_learning_mode = ene_set_learning_mode;
+ rdev->s_learning_mode = ene_set_learning_mode;
init_completion(&dev->tx_complete);
- ir_props->tx_ir = ene_transmit;
- ir_props->s_tx_mask = ene_set_tx_mask;
- ir_props->s_tx_carrier = ene_set_tx_carrier;
- ir_props->s_tx_duty_cycle = ene_set_tx_duty_cycle;
- ir_props->s_carrier_report = ene_set_carrier_report;
+ rdev->tx_ir = ene_transmit;
+ rdev->s_tx_mask = ene_set_tx_mask;
+ rdev->s_tx_carrier = ene_set_tx_carrier;
+ rdev->s_tx_duty_cycle = ene_set_tx_duty_cycle;
+ rdev->s_carrier_report = ene_set_carrier_report;
+ rdev->input_name = "ENE eHome Infrared Remote Transceiver";
}
ene_rx_setup_hw_buffer(dev);
device_set_wakeup_capable(&pnp_dev->dev, true);
device_set_wakeup_enable(&pnp_dev->dev, true);
- if (dev->hw_learning_and_tx_capable)
- input_dev->name = "ENE eHome Infrared Remote Transceiver";
- else
- input_dev->name = "ENE eHome Infrared Remote Receiver";
-
- error = -ENODEV;
- if (ir_input_register(input_dev, RC_MAP_RC6_MCE, ir_props,
- ENE_DRIVER_NAME))
+ error = rc_register_device(rdev);
+ if (error < 0)
goto error;
+ dev->rdev = rdev;
ene_notice("driver has been succesfully loaded");
return 0;
error:
if (dev && dev->hw_io >= 0)
release_region(dev->hw_io, ENE_IO_SIZE);
error1:
- input_free_device(input_dev);
- kfree(ir_props);
+ rc_free_device(rdev);
kfree(dev);
return error;
}
free_irq(dev->irq, dev);
release_region(dev->hw_io, ENE_IO_SIZE);
- ir_input_unregister(dev->idev);
- kfree(dev->props);
+ rc_unregister_device(dev->rdev);
kfree(dev);
}
struct ene_device {
struct pnp_dev *pnp_dev;
- struct input_dev *idev;
- struct ir_dev_props *props;
+ struct rc_dev *rdev;
/* hw IO settings */
long hw_io;
struct imon_context {
struct device *dev;
- struct ir_dev_props *props;
/* Newer devices have two interfaces */
struct usb_device *usbdev_intf0;
struct usb_device *usbdev_intf1;
u16 vendor; /* usb vendor ID */
u16 product; /* usb product ID */
- struct input_dev *rdev; /* input device for remote */
+ struct rc_dev *rdev; /* rc-core device for remote */
struct input_dev *idev; /* input device for panel & IR mouse */
struct input_dev *touch; /* input device for touchscreen */
* really just RC-6), but only one or the other at a time, as the signals
* are decoded onboard the receiver.
*/
-int imon_ir_change_protocol(void *priv, u64 ir_type)
+static int imon_ir_change_protocol(struct rc_dev *rc, u64 ir_type)
{
int retval;
- struct imon_context *ictx = priv;
+ struct imon_context *ictx = rc->priv;
struct device *dev = ictx->dev;
bool pad_mouse;
unsigned char ir_proto_packet[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86 };
- if (ir_type && !(ir_type & ictx->props->allowed_protos))
+ if (ir_type && !(ir_type & rc->allowed_protos))
dev_warn(dev, "Looks like you're trying to use an IR protocol "
"this device does not support\n");
printk(KERN_CONT " (id 0x%02x)\n", ffdc_cfg_byte);
ictx->display_type = detected_display_type;
- ictx->props->allowed_protos = allowed_protos;
+ ictx->rdev->allowed_protos = allowed_protos;
ictx->ir_type = allowed_protos;
}
ictx->display_type = configured_display_type;
}
-static struct input_dev *imon_init_rdev(struct imon_context *ictx)
+static struct rc_dev *imon_init_rdev(struct imon_context *ictx)
{
- struct input_dev *rdev;
- struct ir_dev_props *props;
+ struct rc_dev *rdev;
int ret;
- char *ir_codes = NULL;
const unsigned char fp_packet[] = { 0x40, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x88 };
- rdev = input_allocate_device();
- props = kzalloc(sizeof(*props), GFP_KERNEL);
- if (!rdev || !props) {
+ rdev = rc_allocate_device();
+ if (!rdev) {
dev_err(ictx->dev, "remote control dev allocation failed\n");
goto out;
}
sizeof(ictx->phys_rdev));
strlcat(ictx->phys_rdev, "/input0", sizeof(ictx->phys_rdev));
- rdev->name = ictx->name_rdev;
- rdev->phys = ictx->phys_rdev;
- usb_to_input_id(ictx->usbdev_intf0, &rdev->id);
+ rdev->input_name = ictx->name_rdev;
+ rdev->input_phys = ictx->phys_rdev;
+ usb_to_input_id(ictx->usbdev_intf0, &rdev->input_id);
rdev->dev.parent = ictx->dev;
- rdev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
- input_set_drvdata(rdev, ictx);
- props->priv = ictx;
- props->driver_type = RC_DRIVER_SCANCODE;
- props->allowed_protos = IR_TYPE_OTHER | IR_TYPE_RC6; /* iMON PAD or MCE */
- props->change_protocol = imon_ir_change_protocol;
- ictx->props = props;
+ rdev->priv = ictx;
+ rdev->driver_type = RC_DRIVER_SCANCODE;
+ rdev->allowed_protos = IR_TYPE_OTHER | IR_TYPE_RC6; /* iMON PAD or MCE */
+ rdev->change_protocol = imon_ir_change_protocol;
+ rdev->driver_name = MOD_NAME;
+ if (ictx->ir_type == IR_TYPE_RC6)
+ rdev->map_name = RC_MAP_IMON_MCE;
+ else
+ rdev->map_name = RC_MAP_IMON_PAD;
/* Enable front-panel buttons and/or knobs */
memcpy(ictx->usb_tx_buf, &fp_packet, sizeof(fp_packet));
imon_set_display_type(ictx);
- if (ictx->ir_type == IR_TYPE_RC6)
- ir_codes = RC_MAP_IMON_MCE;
- else
- ir_codes = RC_MAP_IMON_PAD;
-
- ret = ir_input_register(rdev, ir_codes, props, MOD_NAME);
+ ret = rc_register_device(rdev);
if (ret < 0) {
dev_err(ictx->dev, "remote input dev register failed\n");
goto out;
return rdev;
out:
- kfree(props);
- input_free_device(rdev);
+ rc_free_device(rdev);
return NULL;
}
return ictx;
urb_submit_failed:
- ir_input_unregister(ictx->rdev);
+ rc_unregister_device(ictx->rdev);
rdev_setup_failed:
input_unregister_device(ictx->idev);
idev_setup_failed:
ictx->dev_present_intf0 = false;
usb_kill_urb(ictx->rx_urb_intf0);
input_unregister_device(ictx->idev);
- ir_input_unregister(ictx->rdev);
+ rc_unregister_device(ictx->rdev);
if (ictx->display_supported) {
if (ictx->display_type == IMON_DISPLAY_TYPE_LCD)
usb_deregister_dev(interface, &imon_lcd_class);
/**
* ir_jvc_decode() - Decode one JVC pulse or space
- * @input_dev: the struct input_dev descriptor of the device
+ * @dev: the struct rc_dev descriptor of the device
* @duration: the struct ir_raw_event descriptor of the pulse/space
*
* This function returns -EINVAL if the pulse violates the state machine
*/
-static int ir_jvc_decode(struct input_dev *input_dev, struct ir_raw_event ev)
+static int ir_jvc_decode(struct rc_dev *dev, struct ir_raw_event ev)
{
- struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
- struct jvc_dec *data = &ir_dev->raw->jvc;
+ struct jvc_dec *data = &dev->raw->jvc;
- if (!(ir_dev->raw->enabled_protocols & IR_TYPE_JVC))
+ if (!(dev->raw->enabled_protocols & IR_TYPE_JVC))
return 0;
if (!is_timing_event(ev)) {
scancode = (bitrev8((data->bits >> 8) & 0xff) << 8) |
(bitrev8((data->bits >> 0) & 0xff) << 0);
IR_dprintk(1, "JVC scancode 0x%04x\n", scancode);
- ir_keydown(input_dev, scancode, data->toggle);
+ ir_keydown(dev, scancode, data->toggle);
data->first = false;
data->old_bits = data->bits;
} else if (data->bits == data->old_bits) {
IR_dprintk(1, "JVC repeat\n");
- ir_repeat(input_dev);
+ ir_repeat(dev);
} else {
IR_dprintk(1, "JVC invalid repeat msg\n");
break;
/**
* ir_lirc_decode() - Send raw IR data to lirc_dev to be relayed to the
* lircd userspace daemon for decoding.
- * @input_dev: the struct input_dev descriptor of the device
+ * @input_dev: the struct rc_dev descriptor of the device
* @duration: the struct ir_raw_event descriptor of the pulse/space
*
* This function returns -EINVAL if the lirc interfaces aren't wired up.
*/
-static int ir_lirc_decode(struct input_dev *input_dev, struct ir_raw_event ev)
+static int ir_lirc_decode(struct rc_dev *dev, struct ir_raw_event ev)
{
- struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
- struct lirc_codec *lirc = &ir_dev->raw->lirc;
+ struct lirc_codec *lirc = &dev->raw->lirc;
int sample;
- if (!(ir_dev->raw->enabled_protocols & IR_TYPE_LIRC))
+ if (!(dev->raw->enabled_protocols & IR_TYPE_LIRC))
return 0;
- if (!ir_dev->raw->lirc.drv || !ir_dev->raw->lirc.drv->rbuf)
+ if (!dev->raw->lirc.drv || !dev->raw->lirc.drv->rbuf)
return -EINVAL;
/* Packet start */
(u64)LIRC_VALUE_MASK);
gap_sample = LIRC_SPACE(lirc->gap_duration);
- lirc_buffer_write(ir_dev->raw->lirc.drv->rbuf,
+ lirc_buffer_write(dev->raw->lirc.drv->rbuf,
(unsigned char *) &gap_sample);
lirc->gap = false;
}
LIRC_SPACE(ev.duration / 1000);
}
- lirc_buffer_write(ir_dev->raw->lirc.drv->rbuf,
+ lirc_buffer_write(dev->raw->lirc.drv->rbuf,
(unsigned char *) &sample);
- wake_up(&ir_dev->raw->lirc.drv->rbuf->wait_poll);
+ wake_up(&dev->raw->lirc.drv->rbuf->wait_poll);
return 0;
}
size_t n, loff_t *ppos)
{
struct lirc_codec *lirc;
- struct ir_input_dev *ir_dev;
+ struct rc_dev *dev;
int *txbuf; /* buffer with values to transmit */
int ret = 0, count;
if (IS_ERR(txbuf))
return PTR_ERR(txbuf);
- ir_dev = lirc->ir_dev;
- if (!ir_dev) {
+ dev = lirc->dev;
+ if (!dev) {
ret = -EFAULT;
goto out;
}
- if (ir_dev->props && ir_dev->props->tx_ir)
- ret = ir_dev->props->tx_ir(ir_dev->props->priv, txbuf, (u32)n);
+ if (dev->tx_ir)
+ ret = dev->tx_ir(dev, txbuf, (u32)n);
out:
kfree(txbuf);
unsigned long __user arg)
{
struct lirc_codec *lirc;
- struct ir_input_dev *ir_dev;
+ struct rc_dev *dev;
int ret = 0;
- void *drv_data;
__u32 val = 0, tmp;
lirc = lirc_get_pdata(filep);
if (!lirc)
return -EFAULT;
- ir_dev = lirc->ir_dev;
- if (!ir_dev || !ir_dev->props || !ir_dev->props->priv)
+ dev = lirc->dev;
+ if (!dev)
return -EFAULT;
- drv_data = ir_dev->props->priv;
-
if (_IOC_DIR(cmd) & _IOC_WRITE) {
ret = get_user(val, (__u32 *)arg);
if (ret)
/* TX settings */
case LIRC_SET_TRANSMITTER_MASK:
- if (!ir_dev->props->s_tx_mask)
+ if (!dev->s_tx_mask)
return -EINVAL;
- return ir_dev->props->s_tx_mask(drv_data, val);
+ return dev->s_tx_mask(dev, val);
case LIRC_SET_SEND_CARRIER:
- if (!ir_dev->props->s_tx_carrier)
+ if (!dev->s_tx_carrier)
return -EINVAL;
- return ir_dev->props->s_tx_carrier(drv_data, val);
+ return dev->s_tx_carrier(dev, val);
case LIRC_SET_SEND_DUTY_CYCLE:
- if (!ir_dev->props->s_tx_duty_cycle)
+ if (!dev->s_tx_duty_cycle)
return -ENOSYS;
if (val <= 0 || val >= 100)
return -EINVAL;
- return ir_dev->props->s_tx_duty_cycle(drv_data, val);
+ return dev->s_tx_duty_cycle(dev, val);
/* RX settings */
case LIRC_SET_REC_CARRIER:
- if (!ir_dev->props->s_rx_carrier_range)
+ if (!dev->s_rx_carrier_range)
return -ENOSYS;
if (val <= 0)
return -EINVAL;
- return ir_dev->props->s_rx_carrier_range(drv_data,
- ir_dev->raw->lirc.carrier_low, val);
+ return dev->s_rx_carrier_range(dev,
+ dev->raw->lirc.carrier_low,
+ val);
case LIRC_SET_REC_CARRIER_RANGE:
if (val <= 0)
return -EINVAL;
- ir_dev->raw->lirc.carrier_low = val;
+ dev->raw->lirc.carrier_low = val;
return 0;
case LIRC_GET_REC_RESOLUTION:
- val = ir_dev->props->rx_resolution;
+ val = dev->rx_resolution;
break;
case LIRC_SET_WIDEBAND_RECEIVER:
- if (!ir_dev->props->s_learning_mode)
+ if (!dev->s_learning_mode)
return -ENOSYS;
- return ir_dev->props->s_learning_mode(drv_data, !!val);
+ return dev->s_learning_mode(dev, !!val);
case LIRC_SET_MEASURE_CARRIER_MODE:
- if (!ir_dev->props->s_carrier_report)
+ if (!dev->s_carrier_report)
return -ENOSYS;
- return ir_dev->props->s_carrier_report(drv_data, !!val);
+ return dev->s_carrier_report(dev, !!val);
/* Generic timeout support */
case LIRC_GET_MIN_TIMEOUT:
- if (!ir_dev->props->max_timeout)
+ if (!dev->max_timeout)
return -ENOSYS;
- val = ir_dev->props->min_timeout / 1000;
+ val = dev->min_timeout / 1000;
break;
case LIRC_GET_MAX_TIMEOUT:
- if (!ir_dev->props->max_timeout)
+ if (!dev->max_timeout)
return -ENOSYS;
- val = ir_dev->props->max_timeout / 1000;
+ val = dev->max_timeout / 1000;
break;
case LIRC_SET_REC_TIMEOUT:
- if (!ir_dev->props->max_timeout)
+ if (!dev->max_timeout)
return -ENOSYS;
tmp = val * 1000;
- if (tmp < ir_dev->props->min_timeout ||
- tmp > ir_dev->props->max_timeout)
+ if (tmp < dev->min_timeout ||
+ tmp > dev->max_timeout)
return -EINVAL;
- ir_dev->props->timeout = tmp;
+ dev->timeout = tmp;
break;
case LIRC_SET_REC_TIMEOUT_REPORTS:
.llseek = no_llseek,
};
-static int ir_lirc_register(struct input_dev *input_dev)
+static int ir_lirc_register(struct rc_dev *dev)
{
- struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
struct lirc_driver *drv;
struct lirc_buffer *rbuf;
int rc = -ENOMEM;
goto rbuf_init_failed;
features = LIRC_CAN_REC_MODE2;
- if (ir_dev->props->tx_ir) {
-
+ if (dev->tx_ir) {
features |= LIRC_CAN_SEND_PULSE;
- if (ir_dev->props->s_tx_mask)
+ if (dev->s_tx_mask)
features |= LIRC_CAN_SET_TRANSMITTER_MASK;
- if (ir_dev->props->s_tx_carrier)
+ if (dev->s_tx_carrier)
features |= LIRC_CAN_SET_SEND_CARRIER;
-
- if (ir_dev->props->s_tx_duty_cycle)
+ if (dev->s_tx_duty_cycle)
features |= LIRC_CAN_SET_SEND_DUTY_CYCLE;
}
- if (ir_dev->props->s_rx_carrier_range)
+ if (dev->s_rx_carrier_range)
features |= LIRC_CAN_SET_REC_CARRIER |
LIRC_CAN_SET_REC_CARRIER_RANGE;
- if (ir_dev->props->s_learning_mode)
+ if (dev->s_learning_mode)
features |= LIRC_CAN_USE_WIDEBAND_RECEIVER;
- if (ir_dev->props->s_carrier_report)
+ if (dev->s_carrier_report)
features |= LIRC_CAN_MEASURE_CARRIER;
-
- if (ir_dev->props->max_timeout)
+ if (dev->max_timeout)
features |= LIRC_CAN_SET_REC_TIMEOUT;
-
snprintf(drv->name, sizeof(drv->name), "ir-lirc-codec (%s)",
- ir_dev->driver_name);
+ dev->driver_name);
drv->minor = -1;
drv->features = features;
- drv->data = &ir_dev->raw->lirc;
+ drv->data = &dev->raw->lirc;
drv->rbuf = rbuf;
drv->set_use_inc = &ir_lirc_open;
drv->set_use_dec = &ir_lirc_close;
drv->code_length = sizeof(struct ir_raw_event) * 8;
drv->fops = &lirc_fops;
- drv->dev = &ir_dev->dev;
+ drv->dev = &dev->dev;
drv->owner = THIS_MODULE;
drv->minor = lirc_register_driver(drv);
goto lirc_register_failed;
}
- ir_dev->raw->lirc.drv = drv;
- ir_dev->raw->lirc.ir_dev = ir_dev;
+ dev->raw->lirc.drv = drv;
+ dev->raw->lirc.dev = dev;
return 0;
lirc_register_failed:
return rc;
}
-static int ir_lirc_unregister(struct input_dev *input_dev)
+static int ir_lirc_unregister(struct rc_dev *dev)
{
- struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
- struct lirc_codec *lirc = &ir_dev->raw->lirc;
+ struct lirc_codec *lirc = &dev->raw->lirc;
lirc_unregister_driver(lirc->drv->minor);
lirc_buffer_free(lirc->drv->rbuf);
/**
* ir_nec_decode() - Decode one NEC pulse or space
- * @input_dev: the struct input_dev descriptor of the device
+ * @dev: the struct rc_dev descriptor of the device
* @duration: the struct ir_raw_event descriptor of the pulse/space
*
* This function returns -EINVAL if the pulse violates the state machine
*/
-static int ir_nec_decode(struct input_dev *input_dev, struct ir_raw_event ev)
+static int ir_nec_decode(struct rc_dev *dev, struct ir_raw_event ev)
{
- struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
- struct nec_dec *data = &ir_dev->raw->nec;
+ struct nec_dec *data = &dev->raw->nec;
u32 scancode;
u8 address, not_address, command, not_command;
- if (!(ir_dev->raw->enabled_protocols & IR_TYPE_NEC))
+ if (!(dev->raw->enabled_protocols & IR_TYPE_NEC))
return 0;
if (!is_timing_event(ev)) {
data->state = STATE_BIT_PULSE;
return 0;
} else if (eq_margin(ev.duration, NEC_REPEAT_SPACE, NEC_UNIT / 2)) {
- ir_repeat(input_dev);
+ ir_repeat(dev);
IR_dprintk(1, "Repeat last key\n");
data->state = STATE_TRAILER_PULSE;
return 0;
geq_margin(ev.duration,
NEC_TRAILER_SPACE, NEC_UNIT / 2)) {
IR_dprintk(1, "Repeat last key\n");
- ir_repeat(input_dev);
+ ir_repeat(dev);
data->state = STATE_INACTIVE;
return 0;
if (data->is_nec_x)
data->necx_repeat = true;
- ir_keydown(input_dev, scancode, 0);
+ ir_keydown(dev, scancode, 0);
data->state = STATE_INACTIVE;
return 0;
}
/**
* ir_rc5_decode() - Decode one RC-5 pulse or space
- * @input_dev: the struct input_dev descriptor of the device
+ * @dev: the struct rc_dev descriptor of the device
* @ev: the struct ir_raw_event descriptor of the pulse/space
*
* This function returns -EINVAL if the pulse violates the state machine
*/
-static int ir_rc5_decode(struct input_dev *input_dev, struct ir_raw_event ev)
+static int ir_rc5_decode(struct rc_dev *dev, struct ir_raw_event ev)
{
- struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
- struct rc5_dec *data = &ir_dev->raw->rc5;
+ struct rc5_dec *data = &dev->raw->rc5;
u8 toggle;
u32 scancode;
- if (!(ir_dev->raw->enabled_protocols & IR_TYPE_RC5))
+ if (!(dev->raw->enabled_protocols & IR_TYPE_RC5))
return 0;
if (!is_timing_event(ev)) {
return 0;
case STATE_BIT_END:
- if (!is_transition(&ev, &ir_dev->raw->prev_ev))
+ if (!is_transition(&ev, &dev->raw->prev_ev))
break;
if (data->count == data->wanted_bits)
scancode, toggle);
}
- ir_keydown(input_dev, scancode, toggle);
+ ir_keydown(dev, scancode, toggle);
data->state = STATE_INACTIVE;
return 0;
}
/**
* ir_rc5_sz_decode() - Decode one RC-5 Streamzap pulse or space
- * @input_dev: the struct input_dev descriptor of the device
+ * @dev: the struct rc_dev descriptor of the device
* @ev: the struct ir_raw_event descriptor of the pulse/space
*
* This function returns -EINVAL if the pulse violates the state machine
*/
-static int ir_rc5_sz_decode(struct input_dev *input_dev, struct ir_raw_event ev)
+static int ir_rc5_sz_decode(struct rc_dev *dev, struct ir_raw_event ev)
{
- struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
- struct rc5_sz_dec *data = &ir_dev->raw->rc5_sz;
+ struct rc5_sz_dec *data = &dev->raw->rc5_sz;
u8 toggle, command, system;
u32 scancode;
- if (!(ir_dev->raw->enabled_protocols & IR_TYPE_RC5_SZ))
+ if (!(dev->raw->enabled_protocols & IR_TYPE_RC5_SZ))
return 0;
if (!is_timing_event(ev)) {
return 0;
case STATE_BIT_END:
- if (!is_transition(&ev, &ir_dev->raw->prev_ev))
+ if (!is_transition(&ev, &dev->raw->prev_ev))
break;
if (data->count == data->wanted_bits)
IR_dprintk(1, "RC5-sz scancode 0x%04x (toggle: %u)\n",
scancode, toggle);
- ir_keydown(input_dev, scancode, toggle);
+ ir_keydown(dev, scancode, toggle);
data->state = STATE_INACTIVE;
return 0;
}
/**
* ir_rc6_decode() - Decode one RC6 pulse or space
- * @input_dev: the struct input_dev descriptor of the device
+ * @dev: the struct rc_dev descriptor of the device
* @ev: the struct ir_raw_event descriptor of the pulse/space
*
* This function returns -EINVAL if the pulse violates the state machine
*/
-static int ir_rc6_decode(struct input_dev *input_dev, struct ir_raw_event ev)
+static int ir_rc6_decode(struct rc_dev *dev, struct ir_raw_event ev)
{
- struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
- struct rc6_dec *data = &ir_dev->raw->rc6;
+ struct rc6_dec *data = &dev->raw->rc6;
u32 scancode;
u8 toggle;
- if (!(ir_dev->raw->enabled_protocols & IR_TYPE_RC6))
+ if (!(dev->raw->enabled_protocols & IR_TYPE_RC6))
return 0;
if (!is_timing_event(ev)) {
return 0;
case STATE_HEADER_BIT_END:
- if (!is_transition(&ev, &ir_dev->raw->prev_ev))
+ if (!is_transition(&ev, &dev->raw->prev_ev))
break;
if (data->count == RC6_HEADER_NBITS)
return 0;
case STATE_TOGGLE_END:
- if (!is_transition(&ev, &ir_dev->raw->prev_ev) ||
+ if (!is_transition(&ev, &dev->raw->prev_ev) ||
!geq_margin(ev.duration, RC6_TOGGLE_END, RC6_UNIT / 2))
break;
return 0;
case STATE_BODY_BIT_END:
- if (!is_transition(&ev, &ir_dev->raw->prev_ev))
+ if (!is_transition(&ev, &dev->raw->prev_ev))
break;
if (data->count == data->wanted_bits)
goto out;
}
- ir_keydown(input_dev, scancode, toggle);
+ ir_keydown(dev, scancode, toggle);
data->state = STATE_INACTIVE;
return 0;
}
/**
* ir_sony_decode() - Decode one Sony pulse or space
- * @input_dev: the struct input_dev descriptor of the device
+ * @dev: the struct rc_dev descriptor of the device
* @ev: the struct ir_raw_event descriptor of the pulse/space
*
* This function returns -EINVAL if the pulse violates the state machine
*/
-static int ir_sony_decode(struct input_dev *input_dev, struct ir_raw_event ev)
+static int ir_sony_decode(struct rc_dev *dev, struct ir_raw_event ev)
{
- struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
- struct sony_dec *data = &ir_dev->raw->sony;
+ struct sony_dec *data = &dev->raw->sony;
u32 scancode;
u8 device, subdevice, function;
- if (!(ir_dev->raw->enabled_protocols & IR_TYPE_SONY))
+ if (!(dev->raw->enabled_protocols & IR_TYPE_SONY))
return 0;
if (!is_timing_event(ev)) {
scancode = device << 16 | subdevice << 8 | function;
IR_dprintk(1, "Sony(%u) scancode 0x%05x\n", data->count, scancode);
- ir_keydown(input_dev, scancode, 0);
+ ir_keydown(dev, scancode, 0);
data->state = STATE_INACTIVE;
return 0;
}
#include <linux/device.h>
#include <linux/module.h>
#include <linux/slab.h>
-#include <linux/input.h>
#include <linux/usb.h>
#include <linux/usb/input.h>
#include <media/ir-core.h>
/* data structure for each usb transceiver */
struct mceusb_dev {
/* ir-core bits */
- struct ir_dev_props *props;
+ struct rc_dev *rc;
/* optional features we can enable */
bool carrier_report_enabled;
/* core device bits */
struct device *dev;
- struct input_dev *idev;
/* usb */
struct usb_device *usbdev;
}
/* Send data out the IR blaster port(s) */
-static int mceusb_tx_ir(void *priv, int *txbuf, u32 n)
+static int mceusb_tx_ir(struct rc_dev *dev, int *txbuf, u32 n)
{
- struct mceusb_dev *ir = priv;
+ struct mceusb_dev *ir = dev->priv;
int i, ret = 0;
int count, cmdcount = 0;
unsigned char *cmdbuf; /* MCE command buffer */
}
/* Sets active IR outputs -- mce devices typically have two */
-static int mceusb_set_tx_mask(void *priv, u32 mask)
+static int mceusb_set_tx_mask(struct rc_dev *dev, u32 mask)
{
- struct mceusb_dev *ir = priv;
+ struct mceusb_dev *ir = dev->priv;
if (ir->flags.tx_mask_normal)
ir->tx_mask = mask;
}
/* Sets the send carrier frequency and mode */
-static int mceusb_set_tx_carrier(void *priv, u32 carrier)
+static int mceusb_set_tx_carrier(struct rc_dev *dev, u32 carrier)
{
- struct mceusb_dev *ir = priv;
+ struct mceusb_dev *ir = dev->priv;
int clk = 10000000;
int prescaler = 0, divisor = 0;
unsigned char cmdbuf[4] = { MCE_COMMAND_HEADER,
switch (ir->buf_in[index]) {
/* 2-byte return value commands */
case MCE_CMD_S_TIMEOUT:
- ir->props->timeout = MS_TO_NS((hi << 8 | lo) / 2);
+ ir->rc->timeout = MS_TO_NS((hi << 8 | lo) / 2);
break;
/* 1-byte return value commands */
rawir.pulse ? "pulse" : "space",
rawir.duration);
- ir_raw_event_store_with_filter(ir->idev, &rawir);
+ ir_raw_event_store_with_filter(ir->rc, &rawir);
break;
case CMD_DATA:
ir->rem--;
ir->parser_state = CMD_HEADER;
}
dev_dbg(ir->dev, "processed IR data, calling ir_raw_event_handle\n");
- ir_raw_event_handle(ir->idev);
+ ir_raw_event_handle(ir->rc);
}
static void mceusb_dev_recv(struct urb *urb, struct pt_regs *regs)
mce_sync_in(ir, NULL, maxp);
}
-static struct input_dev *mceusb_init_input_dev(struct mceusb_dev *ir)
+static struct rc_dev *mceusb_init_rc_dev(struct mceusb_dev *ir)
{
- struct input_dev *idev;
- struct ir_dev_props *props;
struct device *dev = ir->dev;
- const char *rc_map = RC_MAP_RC6_MCE;
- const char *name = "Media Center Ed. eHome Infrared Remote Transceiver";
- int ret = -ENODEV;
-
- idev = input_allocate_device();
- if (!idev) {
- dev_err(dev, "remote input dev allocation failed\n");
- goto idev_alloc_failed;
- }
+ struct rc_dev *rc;
+ int ret;
- ret = -ENOMEM;
- props = kzalloc(sizeof(struct ir_dev_props), GFP_KERNEL);
- if (!props) {
- dev_err(dev, "remote ir dev props allocation failed\n");
- goto props_alloc_failed;
+ rc = rc_allocate_device();
+ if (!rc) {
+ dev_err(dev, "remote dev allocation failed\n");
+ goto out;
}
- if (mceusb_model[ir->model].name)
- name = mceusb_model[ir->model].name;
-
snprintf(ir->name, sizeof(ir->name), "%s (%04x:%04x)",
- name,
+ mceusb_model[ir->model].name ?
+ mceusb_model[ir->model].name :
+ "Media Center Ed. eHome Infrared Remote Transceiver",
le16_to_cpu(ir->usbdev->descriptor.idVendor),
le16_to_cpu(ir->usbdev->descriptor.idProduct));
- idev->name = ir->name;
usb_make_path(ir->usbdev, ir->phys, sizeof(ir->phys));
- strlcat(ir->phys, "/input0", sizeof(ir->phys));
- idev->phys = ir->phys;
- props->priv = ir;
- props->driver_type = RC_DRIVER_IR_RAW;
- props->allowed_protos = IR_TYPE_ALL;
- props->timeout = MS_TO_NS(1000);
+ rc->input_name = ir->name;
+ rc->input_phys = ir->phys;
+ usb_to_input_id(ir->usbdev, &rc->input_id);
+ rc->dev.parent = dev;
+ rc->priv = ir;
+ rc->driver_type = RC_DRIVER_IR_RAW;
+ rc->allowed_protos = IR_TYPE_ALL;
+ rc->timeout = MS_TO_NS(1000);
if (!ir->flags.no_tx) {
- props->s_tx_mask = mceusb_set_tx_mask;
- props->s_tx_carrier = mceusb_set_tx_carrier;
- props->tx_ir = mceusb_tx_ir;
+ rc->s_tx_mask = mceusb_set_tx_mask;
+ rc->s_tx_carrier = mceusb_set_tx_carrier;
+ rc->tx_ir = mceusb_tx_ir;
}
+ rc->driver_name = DRIVER_NAME;
+ rc->map_name = mceusb_model[ir->model].rc_map ?
+ mceusb_model[ir->model].rc_map : RC_MAP_RC6_MCE;
- ir->props = props;
-
- usb_to_input_id(ir->usbdev, &idev->id);
- idev->dev.parent = ir->dev;
-
- if (mceusb_model[ir->model].rc_map)
- rc_map = mceusb_model[ir->model].rc_map;
-
- ret = ir_input_register(idev, rc_map, props, DRIVER_NAME);
+ ret = rc_register_device(rc);
if (ret < 0) {
- dev_err(dev, "remote input device register failed\n");
- goto irdev_failed;
+ dev_err(dev, "remote dev registration failed\n");
+ goto out;
}
- return idev;
+ return rc;
-irdev_failed:
- kfree(props);
-props_alloc_failed:
- input_free_device(idev);
-idev_alloc_failed:
+out:
+ rc_free_device(rc);
return NULL;
}
snprintf(name + strlen(name), sizeof(name) - strlen(name),
" %s", buf);
- ir->idev = mceusb_init_input_dev(ir);
- if (!ir->idev)
- goto input_dev_fail;
+ ir->rc = mceusb_init_rc_dev(ir);
+ if (!ir->rc)
+ goto rc_dev_fail;
/* flush buffers on the device */
mce_sync_in(ir, NULL, maxp);
mceusb_get_parameters(ir);
if (!ir->flags.no_tx)
- mceusb_set_tx_mask(ir, MCE_DEFAULT_TX_MASK);
+ mceusb_set_tx_mask(ir->rc, MCE_DEFAULT_TX_MASK);
usb_set_intfdata(intf, ir);
return 0;
/* Error-handling path */
-input_dev_fail:
+rc_dev_fail:
usb_free_urb(ir->urb_in);
urb_in_alloc_fail:
usb_free_coherent(dev, maxp, ir->buf_in, ir->dma_in);
return;
ir->usbdev = NULL;
- ir_input_unregister(ir->idev);
+ rc_unregister_device(ir->rc);
usb_kill_urb(ir->urb_in);
usb_free_urb(ir->urb_in);
usb_free_coherent(dev, ir->len_in, ir->buf_in, ir->dma_in);
#include <linux/interrupt.h>
#include <linux/sched.h>
#include <linux/slab.h>
-#include <linux/input.h>
#include <media/ir-core.h>
#include <linux/pci_ids.h>
* always set CP as 0x81
* set CC by SPEC, CC = 3MHz/carrier - 1
*/
-static int nvt_set_tx_carrier(void *data, u32 carrier)
+static int nvt_set_tx_carrier(struct rc_dev *dev, u32 carrier)
{
- struct nvt_dev *nvt = data;
+ struct nvt_dev *nvt = dev->priv;
u16 val;
nvt_cir_reg_write(nvt, 1, CIR_CP);
* number may larger than TXFCONT (0xff). So in interrupt_handler, it has to
* set TXFCONT as 0xff, until buf_count less than 0xff.
*/
-static int nvt_tx_ir(void *priv, int *txbuf, u32 n)
+static int nvt_tx_ir(struct rc_dev *dev, int *txbuf, u32 n)
{
- struct nvt_dev *nvt = priv;
+ struct nvt_dev *nvt = dev->priv;
unsigned long flags;
size_t cur_count;
unsigned int i;
nvt_efm_disable(nvt);
}
-static int nvt_open(void *data)
+static int nvt_open(struct rc_dev *dev)
{
- struct nvt_dev *nvt = (struct nvt_dev *)data;
+ struct nvt_dev *nvt = dev->priv;
unsigned long flags;
spin_lock_irqsave(&nvt->nvt_lock, flags);
return 0;
}
-static void nvt_close(void *data)
+static void nvt_close(struct rc_dev *dev)
{
- struct nvt_dev *nvt = (struct nvt_dev *)data;
+ struct nvt_dev *nvt = dev->priv;
unsigned long flags;
spin_lock_irqsave(&nvt->nvt_lock, flags);
/* Allocate memory, probe hardware, and initialize everything */
static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id)
{
- struct nvt_dev *nvt = NULL;
- struct input_dev *rdev = NULL;
- struct ir_dev_props *props = NULL;
+ struct nvt_dev *nvt;
+ struct rc_dev *rdev;
int ret = -ENOMEM;
nvt = kzalloc(sizeof(struct nvt_dev), GFP_KERNEL);
if (!nvt)
return ret;
- props = kzalloc(sizeof(struct ir_dev_props), GFP_KERNEL);
- if (!props)
- goto failure;
-
/* input device for IR remote (and tx) */
- rdev = input_allocate_device();
+ rdev = rc_allocate_device();
if (!rdev)
goto failure;
nvt_cir_regs_init(nvt);
nvt_cir_wake_regs_init(nvt);
- /* Set up ir-core props */
- props->priv = nvt;
- props->driver_type = RC_DRIVER_IR_RAW;
- props->allowed_protos = IR_TYPE_ALL;
- props->open = nvt_open;
- props->close = nvt_close;
+ /* Set up the rc device */
+ rdev->priv = nvt;
+ rdev->driver_type = RC_DRIVER_IR_RAW;
+ rdev->allowed_protos = IR_TYPE_ALL;
+ rdev->open = nvt_open;
+ rdev->close = nvt_close;
+ rdev->tx_ir = nvt_tx_ir;
+ rdev->s_tx_carrier = nvt_set_tx_carrier;
+ rdev->input_name = "Nuvoton w836x7hg Infrared Remote Transceiver";
+ rdev->input_id.bustype = BUS_HOST;
+ rdev->input_id.vendor = PCI_VENDOR_ID_WINBOND2;
+ rdev->input_id.product = nvt->chip_major;
+ rdev->input_id.version = nvt->chip_minor;
+ rdev->driver_name = NVT_DRIVER_NAME;
+ rdev->map_name = RC_MAP_RC6_MCE;
#if 0
- props->min_timeout = XYZ;
- props->max_timeout = XYZ;
- props->timeout = XYZ;
+ rdev->min_timeout = XYZ;
+ rdev->max_timeout = XYZ;
+ rdev->timeout = XYZ;
/* rx resolution is hardwired to 50us atm, 1, 25, 100 also possible */
- props->rx_resolution = XYZ;
-
+ rdev->rx_resolution = XYZ;
/* tx bits */
- props->tx_resolution = XYZ;
+ rdev->tx_resolution = XYZ;
#endif
- props->tx_ir = nvt_tx_ir;
- props->s_tx_carrier = nvt_set_tx_carrier;
-
- rdev->name = "Nuvoton w836x7hg Infrared Remote Transceiver";
- rdev->id.bustype = BUS_HOST;
- rdev->id.vendor = PCI_VENDOR_ID_WINBOND2;
- rdev->id.product = nvt->chip_major;
- rdev->id.version = nvt->chip_minor;
-
- nvt->props = props;
- nvt->rdev = rdev;
- device_set_wakeup_capable(&pdev->dev, 1);
- device_set_wakeup_enable(&pdev->dev, 1);
-
- ret = ir_input_register(rdev, RC_MAP_RC6_MCE, props, NVT_DRIVER_NAME);
+ ret = rc_register_device(rdev);
if (ret)
goto failure;
+ device_set_wakeup_capable(&pdev->dev, 1);
+ device_set_wakeup_enable(&pdev->dev, 1);
+ nvt->rdev = rdev;
nvt_pr(KERN_NOTICE, "driver has been successfully loaded\n");
if (debug) {
cir_dump_regs(nvt);
if (nvt->cir_wake_addr)
release_region(nvt->cir_wake_addr, CIR_IOREG_LENGTH);
- input_free_device(rdev);
- kfree(props);
+ rc_free_device(rdev);
kfree(nvt);
return ret;
release_region(nvt->cir_addr, CIR_IOREG_LENGTH);
release_region(nvt->cir_wake_addr, CIR_IOREG_LENGTH);
- ir_input_unregister(nvt->rdev);
+ rc_unregister_device(nvt->rdev);
- kfree(nvt->props);
kfree(nvt);
}
struct nvt_dev {
struct pnp_dev *pdev;
- struct input_dev *rdev;
- struct ir_dev_props *props;
+ struct rc_dev *rdev;
struct ir_raw_event rawir;
spinlock_t nvt_lock;
struct list_head list;
u64 protocols; /* which are handled by this handler */
- int (*decode)(struct input_dev *input_dev, struct ir_raw_event event);
+ int (*decode)(struct rc_dev *dev, struct ir_raw_event event);
/* These two should only be used by the lirc decoder */
- int (*raw_register)(struct input_dev *input_dev);
- int (*raw_unregister)(struct input_dev *input_dev);
+ int (*raw_register)(struct rc_dev *dev);
+ int (*raw_unregister)(struct rc_dev *dev);
};
struct ir_raw_event_ctrl {
struct kfifo kfifo; /* fifo for the pulse/space durations */
ktime_t last_event; /* when last event occurred */
enum raw_event_type last_type; /* last event type */
- struct input_dev *input_dev; /* pointer to the parent input_dev */
+ struct rc_dev *dev; /* pointer to the parent rc_dev */
u64 enabled_protocols; /* enabled raw protocol decoders */
/* raw decoder state follows */
unsigned wanted_bits;
} rc5_sz;
struct lirc_codec {
- struct ir_input_dev *ir_dev;
+ struct rc_dev *dev;
struct lirc_driver *drv;
int carrier_low;
#define TO_STR(is_pulse) ((is_pulse) ? "pulse" : "space")
/*
- * Routines from ir-raw-event.c to be used internally and by decoders
+ * Routines from rc-raw.c to be used internally and by decoders
*/
u64 ir_raw_get_allowed_protocols(void);
-int ir_raw_event_register(struct input_dev *input_dev);
-void ir_raw_event_unregister(struct input_dev *input_dev);
+int ir_raw_event_register(struct rc_dev *dev);
+void ir_raw_event_unregister(struct rc_dev *dev);
int ir_raw_handler_register(struct ir_raw_handler *ir_raw_handler);
void ir_raw_handler_unregister(struct ir_raw_handler *ir_raw_handler);
void ir_raw_init(void);
#include <linux/device.h>
#include "rc-core-priv.h"
-#define IRRCV_NUM_DEVICES 256
-
-/* bit array to represent IR sysfs device number */
-static unsigned long ir_core_dev_number;
-
/* Sizes are in bytes, 256 bytes allows for 32 entries on x64 */
#define IR_TAB_MIN_SIZE 256
#define IR_TAB_MAX_SIZE 8192
static LIST_HEAD(rc_map_list);
static DEFINE_SPINLOCK(rc_map_lock);
-/* Forward declarations */
-static int ir_register_class(struct input_dev *input_dev);
-static void ir_unregister_class(struct input_dev *input_dev);
-static int ir_register_input(struct input_dev *input_dev);
-
-
static struct rc_keymap *seek_rc_map(const char *name)
{
struct rc_keymap *map = NULL;
* @return: zero on success or a negative error code
*
* This routine will initialize the ir_scancode_table and will allocate
- * memory to hold at least the specified number elements.
+ * memory to hold at least the specified number of elements.
*/
static int ir_create_table(struct ir_scancode_table *rc_tab,
const char *name, u64 ir_type, size_t size)
/**
* ir_update_mapping() - set a keycode in the scancode->keycode table
- * @dev: the struct input_dev device descriptor
+ * @dev: the struct rc_dev device descriptor
* @rc_tab: scancode table to be adjusted
* @index: index of the mapping that needs to be updated
* @keycode: the desired keycode
* @return: previous keycode assigned to the mapping
*
- * This routine is used to update scancode->keycopde mapping at given
+ * This routine is used to update scancode->keycode mapping at given
* position.
*/
-static unsigned int ir_update_mapping(struct input_dev *dev,
+static unsigned int ir_update_mapping(struct rc_dev *dev,
struct ir_scancode_table *rc_tab,
unsigned int index,
unsigned int new_keycode)
old_keycode == KEY_RESERVED ? "New" : "Replacing",
rc_tab->scan[index].scancode, new_keycode);
rc_tab->scan[index].keycode = new_keycode;
- __set_bit(new_keycode, dev->keybit);
+ __set_bit(new_keycode, dev->input_dev->keybit);
}
if (old_keycode != KEY_RESERVED) {
/* A previous mapping was updated... */
- __clear_bit(old_keycode, dev->keybit);
+ __clear_bit(old_keycode, dev->input_dev->keybit);
/* ... but another scancode might use the same keycode */
for (i = 0; i < rc_tab->len; i++) {
if (rc_tab->scan[i].keycode == old_keycode) {
- __set_bit(old_keycode, dev->keybit);
+ __set_bit(old_keycode, dev->input_dev->keybit);
break;
}
}
/**
* ir_establish_scancode() - set a keycode in the scancode->keycode table
- * @ir_dev: the struct ir_input_dev device descriptor
+ * @dev: the struct rc_dev device descriptor
* @rc_tab: scancode table to be searched
* @scancode: the desired scancode
* @resize: controls whether we allowed to resize the table to
* If scancode is not yet present the routine will allocate a new slot
* for it.
*/
-static unsigned int ir_establish_scancode(struct ir_input_dev *ir_dev,
+static unsigned int ir_establish_scancode(struct rc_dev *dev,
struct ir_scancode_table *rc_tab,
unsigned int scancode,
bool resize)
* all bits for the complete IR code. In general, they provide only
* the command part of the IR code. Yet, as it is possible to replace
* the provided IR with another one, it is needed to allow loading
- * IR tables from other remotes. So,
+ * IR tables from other remotes. So, we support specifying a mask to
+ * indicate the valid bits of the scancodes.
*/
- if (ir_dev->props && ir_dev->props->scanmask)
- scancode &= ir_dev->props->scanmask;
+ if (dev->scanmask)
+ scancode &= dev->scanmask;
/* First check if we already have a mapping for this ir command */
for (i = 0; i < rc_tab->len; i++) {
/**
* ir_setkeycode() - set a keycode in the scancode->keycode table
- * @dev: the struct input_dev device descriptor
+ * @idev: the struct input_dev device descriptor
* @scancode: the desired scancode
* @keycode: result
* @return: -EINVAL if the keycode could not be inserted, otherwise zero.
*
* This routine is used to handle evdev EVIOCSKEY ioctl.
*/
-static int ir_setkeycode(struct input_dev *dev,
+static int ir_setkeycode(struct input_dev *idev,
const struct input_keymap_entry *ke,
unsigned int *old_keycode)
{
- struct ir_input_dev *ir_dev = input_get_drvdata(dev);
- struct ir_scancode_table *rc_tab = &ir_dev->rc_tab;
+ struct rc_dev *rdev = input_get_drvdata(idev);
+ struct ir_scancode_table *rc_tab = &rdev->rc_tab;
unsigned int index;
unsigned int scancode;
int retval;
if (retval)
goto out;
- index = ir_establish_scancode(ir_dev, rc_tab, scancode, true);
+ index = ir_establish_scancode(rdev, rc_tab, scancode, true);
if (index >= rc_tab->len) {
retval = -ENOMEM;
goto out;
}
}
- *old_keycode = ir_update_mapping(dev, rc_tab, index, ke->keycode);
+ *old_keycode = ir_update_mapping(rdev, rc_tab, index, ke->keycode);
out:
spin_unlock_irqrestore(&rc_tab->lock, flags);
/**
* ir_setkeytable() - sets several entries in the scancode->keycode table
- * @dev: the struct input_dev device descriptor
+ * @dev: the struct rc_dev device descriptor
* @to: the struct ir_scancode_table to copy entries to
* @from: the struct ir_scancode_table to copy entries from
* @return: -ENOMEM if all keycodes could not be inserted, otherwise zero.
*
* This routine is used to handle table initialization.
*/
-static int ir_setkeytable(struct ir_input_dev *ir_dev,
+static int ir_setkeytable(struct rc_dev *dev,
const struct ir_scancode_table *from)
{
- struct ir_scancode_table *rc_tab = &ir_dev->rc_tab;
+ struct ir_scancode_table *rc_tab = &dev->rc_tab;
unsigned int i, index;
int rc;
- rc = ir_create_table(&ir_dev->rc_tab,
- from->name, from->ir_type, from->size);
+ rc = ir_create_table(rc_tab, from->name,
+ from->ir_type, from->size);
if (rc)
return rc;
rc_tab->size, rc_tab->alloc);
for (i = 0; i < from->size; i++) {
- index = ir_establish_scancode(ir_dev, rc_tab,
+ index = ir_establish_scancode(dev, rc_tab,
from->scan[i].scancode, false);
if (index >= rc_tab->len) {
rc = -ENOMEM;
break;
}
- ir_update_mapping(ir_dev->input_dev, rc_tab, index,
+ ir_update_mapping(dev, rc_tab, index,
from->scan[i].keycode);
}
/**
* ir_lookup_by_scancode() - locate mapping by scancode
- * @rc_tab: the &struct ir_scancode_table to search
+ * @rc_tab: the struct ir_scancode_table to search
* @scancode: scancode to look for in the table
* @return: index in the table, -1U if not found
*
/**
* ir_getkeycode() - get a keycode from the scancode->keycode table
- * @dev: the struct input_dev device descriptor
+ * @idev: the struct input_dev device descriptor
* @scancode: the desired scancode
* @keycode: used to return the keycode, if found, or KEY_RESERVED
* @return: always returns zero.
*
* This routine is used to handle evdev EVIOCGKEY ioctl.
*/
-static int ir_getkeycode(struct input_dev *dev,
+static int ir_getkeycode(struct input_dev *idev,
struct input_keymap_entry *ke)
{
- struct ir_input_dev *ir_dev = input_get_drvdata(dev);
- struct ir_scancode_table *rc_tab = &ir_dev->rc_tab;
+ struct rc_dev *rdev = input_get_drvdata(idev);
+ struct ir_scancode_table *rc_tab = &rdev->rc_tab;
struct ir_scancode *entry;
unsigned long flags;
unsigned int index;
/**
* ir_g_keycode_from_table() - gets the keycode that corresponds to a scancode
- * @input_dev: the struct input_dev descriptor of the device
- * @scancode: the scancode that we're seeking
+ * @dev: the struct rc_dev descriptor of the device
+ * @scancode: the scancode to look for
+ * @return: the corresponding keycode, or KEY_RESERVED
*
- * This routine is used by the input routines when a key is pressed at the
- * IR. The scancode is received and needs to be converted into a keycode.
- * If the key is not found, it returns KEY_RESERVED. Otherwise, returns the
- * corresponding keycode from the table.
+ * This routine is used by drivers which need to convert a scancode to a
+ * keycode. Normally it should not be used since drivers should have no
+ * interest in keycodes.
*/
-u32 ir_g_keycode_from_table(struct input_dev *dev, u32 scancode)
+u32 ir_g_keycode_from_table(struct rc_dev *dev, u32 scancode)
{
- struct ir_input_dev *ir_dev = input_get_drvdata(dev);
- struct ir_scancode_table *rc_tab = &ir_dev->rc_tab;
+ struct ir_scancode_table *rc_tab = &dev->rc_tab;
unsigned int keycode;
unsigned int index;
unsigned long flags;
if (keycode != KEY_RESERVED)
IR_dprintk(1, "%s: scancode 0x%04x keycode 0x%02x\n",
- dev->name, scancode, keycode);
+ dev->input_name, scancode, keycode);
return keycode;
}
/**
* ir_do_keyup() - internal function to signal the release of a keypress
- * @ir: the struct ir_input_dev descriptor of the device
+ * @dev: the struct rc_dev descriptor of the device
*
* This function is used internally to release a keypress, it must be
* called with keylock held.
*/
-static void ir_do_keyup(struct ir_input_dev *ir)
+static void ir_do_keyup(struct rc_dev *dev)
{
- if (!ir->keypressed)
+ if (!dev->keypressed)
return;
- IR_dprintk(1, "keyup key 0x%04x\n", ir->last_keycode);
- input_report_key(ir->input_dev, ir->last_keycode, 0);
- input_sync(ir->input_dev);
- ir->keypressed = false;
+ IR_dprintk(1, "keyup key 0x%04x\n", dev->last_keycode);
+ input_report_key(dev->input_dev, dev->last_keycode, 0);
+ input_sync(dev->input_dev);
+ dev->keypressed = false;
}
/**
- * ir_keyup() - generates input event to signal the release of a keypress
- * @dev: the struct input_dev descriptor of the device
+ * ir_keyup() - signals the release of a keypress
+ * @dev: the struct rc_dev descriptor of the device
*
* This routine is used to signal that a key has been released on the
* remote control.
*/
-void ir_keyup(struct input_dev *dev)
+void ir_keyup(struct rc_dev *dev)
{
unsigned long flags;
- struct ir_input_dev *ir = input_get_drvdata(dev);
- spin_lock_irqsave(&ir->keylock, flags);
- ir_do_keyup(ir);
- spin_unlock_irqrestore(&ir->keylock, flags);
+ spin_lock_irqsave(&dev->keylock, flags);
+ ir_do_keyup(dev);
+ spin_unlock_irqrestore(&dev->keylock, flags);
}
EXPORT_SYMBOL_GPL(ir_keyup);
/**
* ir_timer_keyup() - generates a keyup event after a timeout
- * @cookie: a pointer to struct ir_input_dev passed to setup_timer()
+ * @cookie: a pointer to the struct rc_dev for the device
*
* This routine will generate a keyup event some time after a keydown event
* is generated when no further activity has been detected.
*/
static void ir_timer_keyup(unsigned long cookie)
{
- struct ir_input_dev *ir = (struct ir_input_dev *)cookie;
+ struct rc_dev *dev = (struct rc_dev *)cookie;
unsigned long flags;
/*
* to allow the input subsystem to do its auto-repeat magic or
* a keyup event might follow immediately after the keydown.
*/
- spin_lock_irqsave(&ir->keylock, flags);
- if (time_is_before_eq_jiffies(ir->keyup_jiffies))
- ir_do_keyup(ir);
- spin_unlock_irqrestore(&ir->keylock, flags);
+ spin_lock_irqsave(&dev->keylock, flags);
+ if (time_is_before_eq_jiffies(dev->keyup_jiffies))
+ ir_do_keyup(dev);
+ spin_unlock_irqrestore(&dev->keylock, flags);
}
/**
- * ir_repeat() - notifies the IR core that a key is still pressed
- * @dev: the struct input_dev descriptor of the device
+ * ir_repeat() - signals that a key is still pressed
+ * @dev: the struct rc_dev descriptor of the device
*
* This routine is used by IR decoders when a repeat message which does
* not include the necessary bits to reproduce the scancode has been
* received.
*/
-void ir_repeat(struct input_dev *dev)
+void ir_repeat(struct rc_dev *dev)
{
unsigned long flags;
- struct ir_input_dev *ir = input_get_drvdata(dev);
- spin_lock_irqsave(&ir->keylock, flags);
+ spin_lock_irqsave(&dev->keylock, flags);
- input_event(dev, EV_MSC, MSC_SCAN, ir->last_scancode);
+ input_event(dev->input_dev, EV_MSC, MSC_SCAN, dev->last_scancode);
- if (!ir->keypressed)
+ if (!dev->keypressed)
goto out;
- ir->keyup_jiffies = jiffies + msecs_to_jiffies(IR_KEYPRESS_TIMEOUT);
- mod_timer(&ir->timer_keyup, ir->keyup_jiffies);
+ dev->keyup_jiffies = jiffies + msecs_to_jiffies(IR_KEYPRESS_TIMEOUT);
+ mod_timer(&dev->timer_keyup, dev->keyup_jiffies);
out:
- spin_unlock_irqrestore(&ir->keylock, flags);
+ spin_unlock_irqrestore(&dev->keylock, flags);
}
EXPORT_SYMBOL_GPL(ir_repeat);
/**
* ir_do_keydown() - internal function to process a keypress
- * @dev: the struct input_dev descriptor of the device
+ * @dev: the struct rc_dev descriptor of the device
* @scancode: the scancode of the keypress
* @keycode: the keycode of the keypress
* @toggle: the toggle value of the keypress
* This function is used internally to register a keypress, it must be
* called with keylock held.
*/
-static void ir_do_keydown(struct input_dev *dev, int scancode,
+static void ir_do_keydown(struct rc_dev *dev, int scancode,
u32 keycode, u8 toggle)
{
- struct ir_input_dev *ir = input_get_drvdata(dev);
-
- input_event(dev, EV_MSC, MSC_SCAN, scancode);
+ input_event(dev->input_dev, EV_MSC, MSC_SCAN, scancode);
/* Repeat event? */
- if (ir->keypressed &&
- ir->last_scancode == scancode &&
- ir->last_toggle == toggle)
+ if (dev->keypressed &&
+ dev->last_scancode == scancode &&
+ dev->last_toggle == toggle)
return;
/* Release old keypress */
- ir_do_keyup(ir);
+ ir_do_keyup(dev);
- ir->last_scancode = scancode;
- ir->last_toggle = toggle;
- ir->last_keycode = keycode;
+ dev->last_scancode = scancode;
+ dev->last_toggle = toggle;
+ dev->last_keycode = keycode;
if (keycode == KEY_RESERVED)
return;
/* Register a keypress */
- ir->keypressed = true;
+ dev->keypressed = true;
IR_dprintk(1, "%s: key down event, key 0x%04x, scancode 0x%04x\n",
- dev->name, keycode, scancode);
- input_report_key(dev, ir->last_keycode, 1);
- input_sync(dev);
+ dev->input_name, keycode, scancode);
+ input_report_key(dev->input_dev, dev->last_keycode, 1);
+ input_sync(dev->input_dev);
}
/**
* ir_keydown() - generates input event for a key press
- * @dev: the struct input_dev descriptor of the device
+ * @dev: the struct rc_dev descriptor of the device
* @scancode: the scancode that we're seeking
* @toggle: the toggle value (protocol dependent, if the protocol doesn't
* support toggle values, this should be set to zero)
*
- * This routine is used by the input routines when a key is pressed at the
- * IR. It gets the keycode for a scancode and reports an input event via
- * input_report_key().
+ * This routine is used to signal that a key has been pressed on the
+ * remote control.
*/
-void ir_keydown(struct input_dev *dev, int scancode, u8 toggle)
+void ir_keydown(struct rc_dev *dev, int scancode, u8 toggle)
{
unsigned long flags;
- struct ir_input_dev *ir = input_get_drvdata(dev);
u32 keycode = ir_g_keycode_from_table(dev, scancode);
- spin_lock_irqsave(&ir->keylock, flags);
+ spin_lock_irqsave(&dev->keylock, flags);
ir_do_keydown(dev, scancode, keycode, toggle);
- if (ir->keypressed) {
- ir->keyup_jiffies = jiffies + msecs_to_jiffies(IR_KEYPRESS_TIMEOUT);
- mod_timer(&ir->timer_keyup, ir->keyup_jiffies);
+ if (dev->keypressed) {
+ dev->keyup_jiffies = jiffies + msecs_to_jiffies(IR_KEYPRESS_TIMEOUT);
+ mod_timer(&dev->timer_keyup, dev->keyup_jiffies);
}
- spin_unlock_irqrestore(&ir->keylock, flags);
+ spin_unlock_irqrestore(&dev->keylock, flags);
}
EXPORT_SYMBOL_GPL(ir_keydown);
/**
* ir_keydown_notimeout() - generates input event for a key press without
* an automatic keyup event at a later time
- * @dev: the struct input_dev descriptor of the device
+ * @dev: the struct rc_dev descriptor of the device
* @scancode: the scancode that we're seeking
* @toggle: the toggle value (protocol dependent, if the protocol doesn't
* support toggle values, this should be set to zero)
*
- * This routine is used by the input routines when a key is pressed at the
- * IR. It gets the keycode for a scancode and reports an input event via
- * input_report_key(). The driver must manually call ir_keyup() at a later
- * stage.
+ * This routine is used to signal that a key has been pressed on the
+ * remote control. The driver must manually call ir_keyup() at a later stage.
*/
-void ir_keydown_notimeout(struct input_dev *dev, int scancode, u8 toggle)
+void ir_keydown_notimeout(struct rc_dev *dev, int scancode, u8 toggle)
{
unsigned long flags;
- struct ir_input_dev *ir = input_get_drvdata(dev);
u32 keycode = ir_g_keycode_from_table(dev, scancode);
- spin_lock_irqsave(&ir->keylock, flags);
+ spin_lock_irqsave(&dev->keylock, flags);
ir_do_keydown(dev, scancode, keycode, toggle);
- spin_unlock_irqrestore(&ir->keylock, flags);
+ spin_unlock_irqrestore(&dev->keylock, flags);
}
EXPORT_SYMBOL_GPL(ir_keydown_notimeout);
-static int ir_open(struct input_dev *input_dev)
-{
- struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
-
- return ir_dev->props->open(ir_dev->props->priv);
-}
-
-static void ir_close(struct input_dev *input_dev)
-{
- struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
-
- ir_dev->props->close(ir_dev->props->priv);
-}
-
-/**
- * __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)
+static int ir_open(struct input_dev *idev)
{
- 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_new = ir_getkeycode;
- input_dev->setkeycode_new = 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);
-
- if (props) {
- ir_dev->props = props;
- if (props->open)
- input_dev->open = ir_open;
- if (props->close)
- input_dev->close = ir_close;
- }
-
- 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);
-
- rc = ir_setkeytable(ir_dev, rc_tab);
- if (rc)
- goto out_name;
+ struct rc_dev *rdev = input_get_drvdata(idev);
- 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;
- }
-
- rc = ir_register_input(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:
- ir_free_table(&ir_dev->rc_tab);
-out_name:
- kfree(ir_dev->driver_name);
-out_dev:
- kfree(ir_dev);
- return rc;
+ return rdev->open(rdev);
}
-EXPORT_SYMBOL_GPL(__ir_input_register);
-
-/**
- * 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)
+static void ir_close(struct input_dev *idev)
{
- struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
-
- if (!ir_dev)
- return;
-
- IR_dprintk(1, "Freed keycode table\n");
+ struct rc_dev *rdev = input_get_drvdata(idev);
- 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);
-
- ir_free_table(&ir_dev->rc_tab);
-
- ir_unregister_class(input_dev);
-
- kfree(ir_dev->driver_name);
- kfree(ir_dev);
+ rdev->close(rdev);
}
-EXPORT_SYMBOL_GPL(ir_input_unregister);
/* class for /sys/class/rc */
static char *ir_devnode(struct device *dev, mode_t *mode)
/**
* show_protocols() - shows the current IR protocol(s)
- * @d: the device descriptor
+ * @device: the device descriptor
* @mattr: the device attribute struct (unused)
* @buf: a pointer to the output buffer
*
* It returns the protocol names of supported protocols.
* Enabled protocols are printed in brackets.
*/
-static ssize_t show_protocols(struct device *d,
+static ssize_t show_protocols(struct device *device,
struct device_attribute *mattr, char *buf)
{
- struct ir_input_dev *ir_dev = dev_get_drvdata(d);
+ struct rc_dev *dev = to_rc_dev(device);
u64 allowed, enabled;
char *tmp = buf;
int i;
/* Device is being removed */
- if (!ir_dev)
+ if (!dev)
return -EINVAL;
- if (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_SCANCODE) {
- enabled = ir_dev->rc_tab.ir_type;
- allowed = ir_dev->props->allowed_protos;
- } else if (ir_dev->raw) {
- enabled = ir_dev->raw->enabled_protocols;
+ if (dev->driver_type == RC_DRIVER_SCANCODE) {
+ enabled = dev->rc_tab.ir_type;
+ allowed = dev->allowed_protos;
+ } else {
+ enabled = dev->raw->enabled_protocols;
allowed = ir_raw_get_allowed_protocols();
- } else
- return sprintf(tmp, "[builtin]\n");
+ }
IR_dprintk(1, "allowed - 0x%llx, enabled - 0x%llx\n",
(long long)allowed,
/**
* store_protocols() - changes the current IR protocol(s)
- * @d: the device descriptor
+ * @device: the device descriptor
* @mattr: the device attribute struct (unused)
* @buf: a pointer to the input buffer
* @len: length of the input buffer
*
- * This routine is a callback routine for changing the IR protocol type.
+ * This routine is for changing the IR protocol type.
* It is trigged by writing to /sys/class/rc/rc?/protocols.
* Writing "+proto" will add a protocol to the list of enabled protocols.
* Writing "-proto" will remove a protocol from the list of enabled protocols.
* Returns -EINVAL if an invalid protocol combination or unknown protocol name
* is used, otherwise @len.
*/
-static ssize_t store_protocols(struct device *d,
+static ssize_t store_protocols(struct device *device,
struct device_attribute *mattr,
const char *data,
size_t len)
{
- struct ir_input_dev *ir_dev = dev_get_drvdata(d);
+ struct rc_dev *dev = to_rc_dev(device);
bool enable, disable;
const char *tmp;
u64 type;
unsigned long flags;
/* Device is being removed */
- if (!ir_dev)
+ if (!dev)
return -EINVAL;
- if (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_SCANCODE)
- type = ir_dev->rc_tab.ir_type;
- else if (ir_dev->raw)
- type = ir_dev->raw->enabled_protocols;
+ if (dev->driver_type == RC_DRIVER_SCANCODE)
+ type = dev->rc_tab.ir_type;
+ else if (dev->raw)
+ type = dev->raw->enabled_protocols;
else {
IR_dprintk(1, "Protocol switching not supported\n");
return -EINVAL;
return -EINVAL;
}
- if (ir_dev->props && ir_dev->props->change_protocol) {
- rc = ir_dev->props->change_protocol(ir_dev->props->priv,
- type);
+ if (dev->change_protocol) {
+ rc = dev->change_protocol(dev, type);
if (rc < 0) {
IR_dprintk(1, "Error setting protocols to 0x%llx\n",
(long long)type);
}
}
- if (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_SCANCODE) {
- spin_lock_irqsave(&ir_dev->rc_tab.lock, flags);
- ir_dev->rc_tab.ir_type = type;
- spin_unlock_irqrestore(&ir_dev->rc_tab.lock, flags);
+ if (dev->driver_type == RC_DRIVER_SCANCODE) {
+ spin_lock_irqsave(&dev->rc_tab.lock, flags);
+ dev->rc_tab.ir_type = type;
+ spin_unlock_irqrestore(&dev->rc_tab.lock, flags);
} else {
- ir_dev->raw->enabled_protocols = type;
+ dev->raw->enabled_protocols = type;
}
IR_dprintk(1, "Current protocol(s): 0x%llx\n",
return len;
}
+static void rc_dev_release(struct device *device)
+{
+ struct rc_dev *dev = to_rc_dev(device);
+
+ kfree(dev);
+ module_put(THIS_MODULE);
+}
+
#define ADD_HOTPLUG_VAR(fmt, val...) \
do { \
int err = add_uevent_var(env, fmt, val); \
static int rc_dev_uevent(struct device *device, struct kobj_uevent_env *env)
{
- struct ir_input_dev *ir_dev = dev_get_drvdata(device);
+ struct rc_dev *dev = to_rc_dev(device);
- if (ir_dev->rc_tab.name)
- ADD_HOTPLUG_VAR("NAME=%s", ir_dev->rc_tab.name);
- if (ir_dev->driver_name)
- ADD_HOTPLUG_VAR("DRV_NAME=%s", ir_dev->driver_name);
+ if (dev->rc_tab.name)
+ ADD_HOTPLUG_VAR("NAME=%s", dev->rc_tab.name);
+ if (dev->driver_name)
+ ADD_HOTPLUG_VAR("DRV_NAME=%s", dev->driver_name);
return 0;
}
static struct device_type rc_dev_type = {
.groups = rc_dev_attr_groups,
+ .release = rc_dev_release,
.uevent = rc_dev_uevent,
};
-/**
- * ir_register_class() - creates the sysfs for /sys/class/rc/rc?
- * @input_dev: the struct input_dev descriptor of the device
- *
- * This routine is used to register the syfs code for IR class
- */
-static int ir_register_class(struct input_dev *input_dev)
+struct rc_dev *rc_allocate_device(void)
{
- struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
- int devno = find_first_zero_bit(&ir_core_dev_number,
- IRRCV_NUM_DEVICES);
-
- if (unlikely(devno < 0))
- return devno;
-
- ir_dev->dev.type = &rc_dev_type;
- ir_dev->devno = devno;
-
- ir_dev->dev.class = &ir_input_class;
- ir_dev->dev.parent = input_dev->dev.parent;
- input_dev->dev.parent = &ir_dev->dev;
- dev_set_name(&ir_dev->dev, "rc%d", devno);
- dev_set_drvdata(&ir_dev->dev, ir_dev);
- return device_register(&ir_dev->dev);
-};
+ struct rc_dev *dev;
-/**
- * ir_register_input - registers ir input device with input subsystem
- * @input_dev: the struct input_dev descriptor of the device
- */
+ dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+ if (!dev)
+ return NULL;
+
+ dev->input_dev = input_allocate_device();
+ if (!dev->input_dev) {
+ kfree(dev);
+ return NULL;
+ }
+
+ dev->input_dev->getkeycode_new = ir_getkeycode;
+ dev->input_dev->setkeycode_new = ir_setkeycode;
+ input_set_drvdata(dev->input_dev, dev);
+
+ spin_lock_init(&dev->rc_tab.lock);
+ spin_lock_init(&dev->keylock);
+ setup_timer(&dev->timer_keyup, ir_timer_keyup, (unsigned long)dev);
-static int ir_register_input(struct input_dev *input_dev)
+ dev->dev.type = &rc_dev_type;
+ dev->dev.class = &ir_input_class;
+ device_initialize(&dev->dev);
+
+ __module_get(THIS_MODULE);
+ return dev;
+}
+EXPORT_SYMBOL_GPL(rc_allocate_device);
+
+void rc_free_device(struct rc_dev *dev)
{
- struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
- int rc;
+ if (dev) {
+ input_free_device(dev->input_dev);
+ put_device(&dev->dev);
+ }
+}
+EXPORT_SYMBOL_GPL(rc_free_device);
+
+int rc_register_device(struct rc_dev *dev)
+{
+ static atomic_t devno = ATOMIC_INIT(0);
+ struct ir_scancode_table *rc_tab;
const char *path;
+ int rc;
+ if (!dev || !dev->map_name)
+ return -EINVAL;
- rc = input_register_device(input_dev);
- if (rc < 0) {
- device_del(&ir_dev->dev);
+ rc_tab = get_rc_map(dev->map_name);
+ if (!rc_tab)
+ rc_tab = get_rc_map(RC_MAP_EMPTY);
+ if (!rc_tab || !rc_tab->scan || rc_tab->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)
return rc;
- }
- __module_get(THIS_MODULE);
+ rc = ir_setkeytable(dev, rc_tab);
+ 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;
- path = kobject_get_path(&ir_dev->dev.kobj, GFP_KERNEL);
+ /*
+ * 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(&ir_dev->dev),
- input_dev->name ? input_dev->name : "Unspecified device",
+ dev_name(&dev->dev),
+ dev->input_name ? dev->input_name : "Unspecified device",
path ? path : "N/A");
kfree(path);
- set_bit(ir_dev->devno, &ir_core_dev_number);
+ 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_tab->ir_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_tab->name ? rc_tab->name : "unknown",
+ dev->driver_type == RC_DRIVER_IR_RAW ? "raw" : "cooked");
+
return 0;
+
+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_tab);
+out_dev:
+ device_del(&dev->dev);
+ return rc;
}
+EXPORT_SYMBOL_GPL(rc_register_device);
-/**
- * ir_unregister_class() - removes the sysfs for sysfs for
- * /sys/class/rc/rc?
- * @input_dev: the struct input_dev descriptor of the device
- *
- * This routine is used to unregister the syfs code for IR class
- */
-static void ir_unregister_class(struct input_dev *input_dev)
+void rc_unregister_device(struct rc_dev *dev)
{
- struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
+ if (!dev)
+ return;
- input_set_drvdata(input_dev, NULL);
- clear_bit(ir_dev->devno, &ir_core_dev_number);
- input_unregister_device(input_dev);
- device_del(&ir_dev->dev);
+ del_timer_sync(&dev->timer_keyup);
- module_put(THIS_MODULE);
+ 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_tab);
+ 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
mutex_lock(&ir_raw_handler_lock);
list_for_each_entry(handler, &ir_raw_handler_list, list)
- handler->decode(raw->input_dev, ev);
+ handler->decode(raw->dev, ev);
raw->prev_ev = ev;
mutex_unlock(&ir_raw_handler_lock);
}
/**
* ir_raw_event_store() - pass a pulse/space duration to the raw ir decoders
- * @input_dev: the struct input_dev device descriptor
+ * @dev: the struct rc_dev device descriptor
* @ev: the struct ir_raw_event descriptor of the pulse/space
*
* This routine (which may be called from an interrupt context) stores a
* signalled as positive values and spaces as negative values. A zero value
* will reset the decoding state machines.
*/
-int ir_raw_event_store(struct input_dev *input_dev, struct ir_raw_event *ev)
+int ir_raw_event_store(struct rc_dev *dev, struct ir_raw_event *ev)
{
- struct ir_input_dev *ir = input_get_drvdata(input_dev);
-
- if (!ir->raw)
+ if (!dev->raw)
return -EINVAL;
IR_dprintk(2, "sample: (%05dus %s)\n",
- TO_US(ev->duration), TO_STR(ev->pulse));
+ TO_US(ev->duration), TO_STR(ev->pulse));
- if (kfifo_in(&ir->raw->kfifo, ev, sizeof(*ev)) != sizeof(*ev))
+ if (kfifo_in(&dev->raw->kfifo, ev, sizeof(*ev)) != sizeof(*ev))
return -ENOMEM;
return 0;
/**
* ir_raw_event_store_edge() - notify raw ir decoders of the start of a pulse/space
- * @input_dev: the struct input_dev device descriptor
+ * @dev: the struct rc_dev device descriptor
* @type: the type of the event that has occurred
*
* This routine (which may be called from an interrupt context) is used to
* hardware which does not provide durations directly but only interrupts
* (or similar events) on state change.
*/
-int ir_raw_event_store_edge(struct input_dev *input_dev, enum raw_event_type type)
+int ir_raw_event_store_edge(struct rc_dev *dev, enum raw_event_type type)
{
- struct ir_input_dev *ir = input_get_drvdata(input_dev);
ktime_t now;
s64 delta; /* ns */
struct ir_raw_event ev;
int rc = 0;
- if (!ir->raw)
+ if (!dev->raw)
return -EINVAL;
now = ktime_get();
- delta = ktime_to_ns(ktime_sub(now, ir->raw->last_event));
+ delta = ktime_to_ns(ktime_sub(now, dev->raw->last_event));
/* Check for a long duration since last event or if we're
* being called for the first time, note that delta can't
* possibly be negative.
*/
ev.duration = 0;
- if (delta > IR_MAX_DURATION || !ir->raw->last_type)
+ if (delta > IR_MAX_DURATION || !dev->raw->last_type)
type |= IR_START_EVENT;
else
ev.duration = delta;
if (type & IR_START_EVENT)
- ir_raw_event_reset(input_dev);
- else if (ir->raw->last_type & IR_SPACE) {
+ ir_raw_event_reset(dev);
+ else if (dev->raw->last_type & IR_SPACE) {
ev.pulse = false;
- rc = ir_raw_event_store(input_dev, &ev);
- } else if (ir->raw->last_type & IR_PULSE) {
+ rc = ir_raw_event_store(dev, &ev);
+ } else if (dev->raw->last_type & IR_PULSE) {
ev.pulse = true;
- rc = ir_raw_event_store(input_dev, &ev);
+ rc = ir_raw_event_store(dev, &ev);
} else
return 0;
- ir->raw->last_event = now;
- ir->raw->last_type = type;
+ dev->raw->last_event = now;
+ dev->raw->last_type = type;
return rc;
}
EXPORT_SYMBOL_GPL(ir_raw_event_store_edge);
/**
* ir_raw_event_store_with_filter() - pass next pulse/space to decoders with some processing
- * @input_dev: the struct input_dev device descriptor
+ * @dev: the struct rc_dev device descriptor
* @type: the type of the event that has occurred
*
* This routine (which may be called from an interrupt context) works
* This routine is intended for devices with limited internal buffer
* It automerges samples of same type, and handles timeouts
*/
-int ir_raw_event_store_with_filter(struct input_dev *input_dev,
- struct ir_raw_event *ev)
+int ir_raw_event_store_with_filter(struct rc_dev *dev, struct ir_raw_event *ev)
{
- struct ir_input_dev *ir = input_get_drvdata(input_dev);
- struct ir_raw_event_ctrl *raw = ir->raw;
-
- if (!raw || !ir->props)
+ if (!dev->raw)
return -EINVAL;
/* Ignore spaces in idle mode */
- if (ir->idle && !ev->pulse)
+ if (dev->idle && !ev->pulse)
return 0;
- else if (ir->idle)
- ir_raw_event_set_idle(input_dev, false);
-
- if (!raw->this_ev.duration) {
- raw->this_ev = *ev;
- } else if (ev->pulse == raw->this_ev.pulse) {
- raw->this_ev.duration += ev->duration;
- } else {
- ir_raw_event_store(input_dev, &raw->this_ev);
- raw->this_ev = *ev;
+ else if (dev->idle)
+ ir_raw_event_set_idle(dev, false);
+
+ if (!dev->raw->this_ev.duration)
+ dev->raw->this_ev = *ev;
+ else if (ev->pulse == dev->raw->this_ev.pulse)
+ dev->raw->this_ev.duration += ev->duration;
+ else {
+ ir_raw_event_store(dev, &dev->raw->this_ev);
+ dev->raw->this_ev = *ev;
}
/* Enter idle mode if nessesary */
- if (!ev->pulse && ir->props->timeout &&
- raw->this_ev.duration >= ir->props->timeout) {
- ir_raw_event_set_idle(input_dev, true);
- }
+ if (!ev->pulse && dev->timeout &&
+ dev->raw->this_ev.duration >= dev->timeout)
+ ir_raw_event_set_idle(dev, true);
+
return 0;
}
EXPORT_SYMBOL_GPL(ir_raw_event_store_with_filter);
/**
- * ir_raw_event_set_idle() - hint the ir core if device is receiving
- * IR data or not
- * @input_dev: the struct input_dev device descriptor
- * @idle: the hint value
+ * ir_raw_event_set_idle() - provide hint to rc-core when the device is idle or not
+ * @dev: the struct rc_dev device descriptor
+ * @idle: whether the device is idle or not
*/
-void ir_raw_event_set_idle(struct input_dev *input_dev, bool idle)
+void ir_raw_event_set_idle(struct rc_dev *dev, bool idle)
{
- struct ir_input_dev *ir = input_get_drvdata(input_dev);
- struct ir_raw_event_ctrl *raw = ir->raw;
-
- if (!ir->props || !ir->raw)
+ if (!dev->raw)
return;
IR_dprintk(2, "%s idle mode\n", idle ? "enter" : "leave");
if (idle) {
- raw->this_ev.timeout = true;
- ir_raw_event_store(input_dev, &raw->this_ev);
- init_ir_raw_event(&raw->this_ev);
+ dev->raw->this_ev.timeout = true;
+ ir_raw_event_store(dev, &dev->raw->this_ev);
+ init_ir_raw_event(&dev->raw->this_ev);
}
- if (ir->props->s_idle)
- ir->props->s_idle(ir->props->priv, idle);
- ir->idle = idle;
+ if (dev->s_idle)
+ dev->s_idle(dev, idle);
+
+ dev->idle = idle;
}
EXPORT_SYMBOL_GPL(ir_raw_event_set_idle);
/**
* ir_raw_event_handle() - schedules the decoding of stored ir data
- * @input_dev: the struct input_dev device descriptor
+ * @dev: the struct rc_dev device descriptor
*
- * This routine will signal the workqueue to start decoding stored ir data.
+ * This routine will tell rc-core to start decoding stored ir data.
*/
-void ir_raw_event_handle(struct input_dev *input_dev)
+void ir_raw_event_handle(struct rc_dev *dev)
{
- struct ir_input_dev *ir = input_get_drvdata(input_dev);
unsigned long flags;
- if (!ir->raw)
+ if (!dev->raw)
return;
- spin_lock_irqsave(&ir->raw->lock, flags);
- wake_up_process(ir->raw->thread);
- spin_unlock_irqrestore(&ir->raw->lock, flags);
+ spin_lock_irqsave(&dev->raw->lock, flags);
+ wake_up_process(dev->raw->thread);
+ spin_unlock_irqrestore(&dev->raw->lock, flags);
}
EXPORT_SYMBOL_GPL(ir_raw_event_handle);
/*
* Used to (un)register raw event clients
*/
-int ir_raw_event_register(struct input_dev *input_dev)
+int ir_raw_event_register(struct rc_dev *dev)
{
- struct ir_input_dev *ir = input_get_drvdata(input_dev);
int rc;
struct ir_raw_handler *handler;
- ir->raw = kzalloc(sizeof(*ir->raw), GFP_KERNEL);
- if (!ir->raw)
- return -ENOMEM;
+ if (!dev)
+ return -EINVAL;
- ir->raw->input_dev = input_dev;
+ dev->raw = kzalloc(sizeof(*dev->raw), GFP_KERNEL);
+ if (!dev->raw)
+ return -ENOMEM;
- ir->raw->enabled_protocols = ~0;
- rc = kfifo_alloc(&ir->raw->kfifo, sizeof(s64) * MAX_IR_EVENT_SIZE,
+ dev->raw->dev = dev;
+ dev->raw->enabled_protocols = ~0;
+ rc = kfifo_alloc(&dev->raw->kfifo,
+ sizeof(struct ir_raw_event) * MAX_IR_EVENT_SIZE,
GFP_KERNEL);
- if (rc < 0) {
- kfree(ir->raw);
- ir->raw = NULL;
- return rc;
- }
+ if (rc < 0)
+ goto out;
- spin_lock_init(&ir->raw->lock);
- ir->raw->thread = kthread_run(ir_raw_event_thread, ir->raw,
- "rc%u", (unsigned int)ir->devno);
+ spin_lock_init(&dev->raw->lock);
+ dev->raw->thread = kthread_run(ir_raw_event_thread, dev->raw,
+ "rc%ld", dev->devno);
- if (IS_ERR(ir->raw->thread)) {
- int ret = PTR_ERR(ir->raw->thread);
-
- kfree(ir->raw);
- ir->raw = NULL;
- return ret;
+ if (IS_ERR(dev->raw->thread)) {
+ rc = PTR_ERR(dev->raw->thread);
+ goto out;
}
mutex_lock(&ir_raw_handler_lock);
- list_add_tail(&ir->raw->list, &ir_raw_client_list);
+ list_add_tail(&dev->raw->list, &ir_raw_client_list);
list_for_each_entry(handler, &ir_raw_handler_list, list)
if (handler->raw_register)
- handler->raw_register(ir->raw->input_dev);
+ handler->raw_register(dev);
mutex_unlock(&ir_raw_handler_lock);
return 0;
+
+out:
+ kfree(dev->raw);
+ dev->raw = NULL;
+ return rc;
}
-void ir_raw_event_unregister(struct input_dev *input_dev)
+void ir_raw_event_unregister(struct rc_dev *dev)
{
- struct ir_input_dev *ir = input_get_drvdata(input_dev);
struct ir_raw_handler *handler;
- if (!ir->raw)
+ if (!dev || !dev->raw)
return;
- kthread_stop(ir->raw->thread);
+ kthread_stop(dev->raw->thread);
mutex_lock(&ir_raw_handler_lock);
- list_del(&ir->raw->list);
+ list_del(&dev->raw->list);
list_for_each_entry(handler, &ir_raw_handler_list, list)
if (handler->raw_unregister)
- handler->raw_unregister(ir->raw->input_dev);
+ handler->raw_unregister(dev);
mutex_unlock(&ir_raw_handler_lock);
- kfifo_free(&ir->raw->kfifo);
- kfree(ir->raw);
- ir->raw = NULL;
+ kfifo_free(&dev->raw->kfifo);
+ kfree(dev->raw);
+ dev->raw = NULL;
}
/*
list_add_tail(&ir_raw_handler->list, &ir_raw_handler_list);
if (ir_raw_handler->raw_register)
list_for_each_entry(raw, &ir_raw_client_list, list)
- ir_raw_handler->raw_register(raw->input_dev);
+ ir_raw_handler->raw_register(raw->dev);
available_protocols |= ir_raw_handler->protocols;
mutex_unlock(&ir_raw_handler_lock);
list_del(&ir_raw_handler->list);
if (ir_raw_handler->raw_unregister)
list_for_each_entry(raw, &ir_raw_client_list, list)
- ir_raw_handler->raw_unregister(raw->input_dev);
+ ir_raw_handler->raw_unregister(raw->dev);
available_protocols &= ~ir_raw_handler->protocols;
mutex_unlock(&ir_raw_handler_lock);
}
#include <linux/device.h>
#include <linux/module.h>
#include <linux/slab.h>
-#include <linux/input.h>
#include <linux/usb.h>
#include <linux/usb/input.h>
#include <media/ir-core.h>
/* structure to hold our device specific stuff */
struct streamzap_ir {
-
/* ir-core */
- struct ir_dev_props *props;
+ struct rc_dev *rdev;
/* core device info */
struct device *dev;
- struct input_dev *idev;
/* usb */
struct usb_device *usbdev;
{
dev_dbg(sz->dev, "Storing %s with duration %u us\n",
(rawir.pulse ? "pulse" : "space"), rawir.duration);
- ir_raw_event_store_with_filter(sz->idev, &rawir);
+ ir_raw_event_store_with_filter(sz->rdev, &rawir);
}
static void sz_push_full_pulse(struct streamzap_ir *sz,
DEFINE_IR_RAW_EVENT(rawir);
rawir.pulse = false;
- rawir.duration = sz->props->timeout;
+ rawir.duration = sz->rdev->timeout;
sz->idle = true;
if (sz->timeout_enabled)
sz_push(sz, rawir);
- ir_raw_event_handle(sz->idev);
+ ir_raw_event_handle(sz->rdev);
} else {
sz_push_full_space(sz, sz->buf_in[i]);
}
return;
}
-static struct input_dev *streamzap_init_input_dev(struct streamzap_ir *sz)
+static struct rc_dev *streamzap_init_rc_dev(struct streamzap_ir *sz)
{
- struct input_dev *idev;
- struct ir_dev_props *props;
+ struct rc_dev *rdev;
struct device *dev = sz->dev;
int ret;
- idev = input_allocate_device();
- if (!idev) {
- dev_err(dev, "remote input dev allocation failed\n");
- goto idev_alloc_failed;
- }
-
- props = kzalloc(sizeof(struct ir_dev_props), GFP_KERNEL);
- if (!props) {
- dev_err(dev, "remote ir dev props allocation failed\n");
- goto props_alloc_failed;
+ rdev = rc_allocate_device();
+ if (!rdev) {
+ dev_err(dev, "remote dev allocation failed\n");
+ goto out;
}
snprintf(sz->name, sizeof(sz->name), "Streamzap PC Remote Infrared "
"Receiver (%04x:%04x)",
le16_to_cpu(sz->usbdev->descriptor.idVendor),
le16_to_cpu(sz->usbdev->descriptor.idProduct));
-
- idev->name = sz->name;
usb_make_path(sz->usbdev, sz->phys, sizeof(sz->phys));
strlcat(sz->phys, "/input0", sizeof(sz->phys));
- idev->phys = sz->phys;
-
- props->priv = sz;
- props->driver_type = RC_DRIVER_IR_RAW;
- props->allowed_protos = IR_TYPE_ALL;
-
- sz->props = props;
- usb_to_input_id(sz->usbdev, &idev->id);
- idev->dev.parent = sz->dev;
+ rdev->input_name = sz->name;
+ rdev->input_phys = sz->phys;
+ rdev->priv = sz;
+ rdev->driver_type = RC_DRIVER_IR_RAW;
+ rdev->allowed_protos = IR_TYPE_ALL;
+ rdev->driver_name = DRIVER_NAME;
+ rdev->map_name = RC_MAP_STREAMZAP;
- ret = ir_input_register(idev, RC_MAP_STREAMZAP, props, DRIVER_NAME);
+ ret = rc_register_device(rdev);
if (ret < 0) {
dev_err(dev, "remote input device register failed\n");
- goto irdev_failed;
+ goto out;
}
- return idev;
+ return rdev;
-irdev_failed:
- kfree(props);
-props_alloc_failed:
- input_free_device(idev);
-idev_alloc_failed:
+out:
+ rc_free_device(rdev);
return NULL;
}
snprintf(name + strlen(name), sizeof(name) - strlen(name),
" %s", buf);
- sz->idev = streamzap_init_input_dev(sz);
- if (!sz->idev)
- goto input_dev_fail;
+ sz->rdev = streamzap_init_rc_dev(sz);
+ if (!sz->rdev)
+ goto rc_dev_fail;
sz->idle = true;
sz->decoder_state = PulseSpace;
/* FIXME: don't yet have a way to set this */
sz->timeout_enabled = true;
- sz->props->timeout = (((SZ_TIMEOUT * SZ_RESOLUTION * 1000) &
+ sz->rdev->timeout = (((SZ_TIMEOUT * SZ_RESOLUTION * 1000) &
IR_MAX_DURATION) | 0x03000000);
#if 0
/* not yet supported, depends on patches from maxim */
return 0;
-input_dev_fail:
+rc_dev_fail:
usb_free_urb(sz->urb_in);
free_buf_in:
usb_free_coherent(usbdev, maxp, sz->buf_in, sz->dma_in);
return;
sz->usbdev = NULL;
- ir_input_unregister(sz->idev);
+ rc_unregister_device(sz->rdev);
usb_kill_urb(sz->urb_in);
usb_free_urb(sz->urb_in);
usb_free_coherent(usbdev, sz->buf_in_len, sz->buf_in, sz->dma_in);
static int ir_debug;
module_param(ir_debug, int, 0644);
-static int repeat_delay = 500;
-module_param(repeat_delay, int, 0644);
-static int repeat_period = 33;
-module_param(repeat_period, int, 0644);
static int ir_rc5_remote_gap = 885;
module_param(ir_rc5_remote_gap, int, 0644);
{
struct card_ir *ir;
char *ir_codes = NULL;
- struct input_dev *input_dev;
+ struct rc_dev *rc;
int err = -ENOMEM;
if (!btv->has_remote)
return -ENODEV;
ir = kzalloc(sizeof(*ir),GFP_KERNEL);
- input_dev = input_allocate_device();
- if (!ir || !input_dev)
+ rc = rc_allocate_device();
+ if (!ir || !rc)
goto err_out_free;
/* detect & configure */
}
/* init input device */
- ir->dev = input_dev;
+ ir->dev = rc;
snprintf(ir->name, sizeof(ir->name), "bttv IR (card=%d)",
btv->c.type);
snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0",
pci_name(btv->c.pci));
- input_dev->name = ir->name;
- input_dev->phys = ir->phys;
- input_dev->id.bustype = BUS_PCI;
- input_dev->id.version = 1;
+ rc->input_name = ir->name;
+ rc->input_phys = ir->phys;
+ rc->input_id.bustype = BUS_PCI;
+ rc->input_id.version = 1;
if (btv->c.pci->subsystem_vendor) {
- input_dev->id.vendor = btv->c.pci->subsystem_vendor;
- input_dev->id.product = btv->c.pci->subsystem_device;
+ rc->input_id.vendor = btv->c.pci->subsystem_vendor;
+ rc->input_id.product = btv->c.pci->subsystem_device;
} else {
- input_dev->id.vendor = btv->c.pci->vendor;
- input_dev->id.product = btv->c.pci->device;
+ rc->input_id.vendor = btv->c.pci->vendor;
+ rc->input_id.product = btv->c.pci->device;
}
- input_dev->dev.parent = &btv->c.pci->dev;
+ rc->dev.parent = &btv->c.pci->dev;
+ rc->map_name = ir_codes;
+ rc->driver_name = MODULE_NAME;
btv->remote = ir;
bttv_ir_start(btv, ir);
/* all done */
- err = ir_input_register(btv->remote->dev, ir_codes, NULL, MODULE_NAME);
+ err = rc_register_device(rc);
if (err)
goto err_out_stop;
- /* the remote isn't as bouncy as a keyboard */
- ir->dev->rep[REP_DELAY] = repeat_delay;
- ir->dev->rep[REP_PERIOD] = repeat_period;
-
return 0;
err_out_stop:
bttv_ir_stop(btv);
btv->remote = NULL;
err_out_free:
+ rc_free_device(rc);
kfree(ir);
return err;
}
return;
bttv_ir_stop(btv);
- ir_input_unregister(btv->remote->dev);
+ rc_unregister_device(btv->remote->dev);
kfree(btv->remote);
btv->remote = NULL;
}
char name[40];
char phys[32];
+#if 0
+ /*
+ * Due to a Kconfig change, cx231xx-input is not being compiled.
+ * This structure disappeared, but other fixes are also needed.
+ * So, as a workaround, let's just comment this struct and let a
+ * latter patch fix it.
+ */
struct ir_dev_props props;
+#endif
/* I2C keyboard data */
struct IR_i2c_init_data init_data;
* 02110-1301, USA.
*/
-#include <linux/input.h>
#include <linux/slab.h>
#include <media/ir-core.h>
#include <media/v4l2-subdev.h>
count = num / sizeof(struct ir_raw_event);
for (i = 0; i < count; i++) {
- ir_raw_event_store(kernel_ir->inp_dev,
+ ir_raw_event_store(kernel_ir->rc,
&ir_core_event[i]);
handle = true;
}
} while (num != 0);
if (overrun)
- ir_raw_event_reset(kernel_ir->inp_dev);
+ ir_raw_event_reset(kernel_ir->rc);
else if (handle)
- ir_raw_event_handle(kernel_ir->inp_dev);
+ ir_raw_event_handle(kernel_ir->rc);
}
void cx23885_input_rx_work_handler(struct cx23885_dev *dev, u32 events)
return 0;
}
-static int cx23885_input_ir_open(void *priv)
+static int cx23885_input_ir_open(struct rc_dev *rc)
{
- struct cx23885_kernel_ir *kernel_ir = priv;
+ struct cx23885_kernel_ir *kernel_ir = rc->priv;
if (kernel_ir->cx == NULL)
return -ENODEV;
flush_scheduled_work();
}
-static void cx23885_input_ir_close(void *priv)
+static void cx23885_input_ir_close(struct rc_dev *rc)
{
- struct cx23885_kernel_ir *kernel_ir = priv;
+ struct cx23885_kernel_ir *kernel_ir = rc->priv;
if (kernel_ir->cx != NULL)
cx23885_input_ir_stop(kernel_ir->cx);
int cx23885_input_init(struct cx23885_dev *dev)
{
struct cx23885_kernel_ir *kernel_ir;
- struct input_dev *inp_dev;
- struct ir_dev_props *props;
-
+ struct rc_dev *rc;
char *rc_map;
enum rc_driver_type driver_type;
unsigned long allowed_protos;
pci_name(dev->pci));
/* input device */
- inp_dev = input_allocate_device();
- if (inp_dev == NULL) {
+ rc = rc_allocate_device();
+ if (!rc) {
ret = -ENOMEM;
goto err_out_free;
}
- kernel_ir->inp_dev = inp_dev;
- inp_dev->name = kernel_ir->name;
- inp_dev->phys = kernel_ir->phys;
- inp_dev->id.bustype = BUS_PCI;
- inp_dev->id.version = 1;
+ kernel_ir->rc = rc;
+ rc->input_name = kernel_ir->name;
+ rc->input_phys = kernel_ir->phys;
+ rc->input_id.bustype = BUS_PCI;
+ rc->input_id.version = 1;
if (dev->pci->subsystem_vendor) {
- inp_dev->id.vendor = dev->pci->subsystem_vendor;
- inp_dev->id.product = dev->pci->subsystem_device;
+ rc->input_id.vendor = dev->pci->subsystem_vendor;
+ rc->input_id.product = dev->pci->subsystem_device;
} else {
- inp_dev->id.vendor = dev->pci->vendor;
- inp_dev->id.product = dev->pci->device;
+ rc->input_id.vendor = dev->pci->vendor;
+ rc->input_id.product = dev->pci->device;
}
- inp_dev->dev.parent = &dev->pci->dev;
-
- /* kernel ir device properties */
- props = &kernel_ir->props;
- props->driver_type = driver_type;
- props->allowed_protos = allowed_protos;
- props->priv = kernel_ir;
- props->open = cx23885_input_ir_open;
- props->close = cx23885_input_ir_close;
+ rc->dev.parent = &dev->pci->dev;
+ rc->driver_type = driver_type;
+ rc->allowed_protos = allowed_protos;
+ rc->priv = kernel_ir;
+ rc->open = cx23885_input_ir_open;
+ rc->close = cx23885_input_ir_close;
+ rc->map_name = rc_map;
+ rc->driver_name = MODULE_NAME;
/* Go */
dev->kernel_ir = kernel_ir;
- ret = ir_input_register(inp_dev, rc_map, props, MODULE_NAME);
+ ret = rc_register_device(rc);
if (ret)
goto err_out_stop;
err_out_stop:
cx23885_input_ir_stop(dev);
dev->kernel_ir = NULL;
- /* TODO: double check clean-up of kernel_ir->inp_dev */
+ rc_free_device(rc);
err_out_free:
kfree(kernel_ir->phys);
kfree(kernel_ir->name);
if (dev->kernel_ir == NULL)
return;
- ir_input_unregister(dev->kernel_ir->inp_dev);
+ rc_unregister_device(dev->kernel_ir->rc);
kfree(dev->kernel_ir->phys);
kfree(dev->kernel_ir->name);
kfree(dev->kernel_ir);
char *name;
char *phys;
- struct input_dev *inp_dev;
- struct ir_dev_props props;
+ struct rc_dev *rc;
};
struct cx23885_dev {
#include <linux/init.h>
#include <linux/hrtimer.h>
-#include <linux/input.h>
#include <linux/pci.h>
#include <linux/slab.h>
#include <linux/module.h>
struct cx88_IR {
struct cx88_core *core;
- struct input_dev *input;
- struct ir_dev_props props;
+ struct rc_dev *dev;
int users;
data = (data << 4) | ((gpio_key & 0xf0) >> 4);
- ir_keydown(ir->input, data, 0);
+ ir_keydown(ir->dev, data, 0);
} else if (ir->mask_keydown) {
/* bit set on keydown */
if (gpio & ir->mask_keydown)
- ir_keydown_notimeout(ir->input, data, 0);
+ ir_keydown_notimeout(ir->dev, data, 0);
else
- ir_keyup(ir->input);
+ ir_keyup(ir->dev);
} else if (ir->mask_keyup) {
/* bit cleared on keydown */
if (0 == (gpio & ir->mask_keyup))
- ir_keydown_notimeout(ir->input, data, 0);
+ ir_keydown_notimeout(ir->dev, data, 0);
else
- ir_keyup(ir->input);
+ ir_keyup(ir->dev);
} else {
/* can't distinguish keydown/up :-/ */
- ir_keydown_notimeout(ir->input, data, 0);
- ir_keyup(ir->input);
+ ir_keydown_notimeout(ir->dev, data, 0);
+ ir_keyup(ir->dev);
}
}
__cx88_ir_stop(core);
}
-static int cx88_ir_open(void *priv)
+static int cx88_ir_open(struct rc_dev *rc)
{
- struct cx88_core *core = priv;
+ struct cx88_core *core = rc->priv;
core->ir->users++;
return __cx88_ir_start(core);
}
-static void cx88_ir_close(void *priv)
+static void cx88_ir_close(struct rc_dev *rc)
{
- struct cx88_core *core = priv;
+ struct cx88_core *core = rc->priv;
core->ir->users--;
if (!core->ir->users)
int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
{
struct cx88_IR *ir;
- struct input_dev *input_dev;
+ struct rc_dev *dev;
char *ir_codes = NULL;
u64 ir_type = IR_TYPE_OTHER;
int err = -ENOMEM;
*/
ir = kzalloc(sizeof(*ir), GFP_KERNEL);
- input_dev = input_allocate_device();
- if (!ir || !input_dev)
+ dev = rc_allocate_device();
+ if (!ir || !dev)
goto err_out_free;
- ir->input = input_dev;
+ ir->dev = dev;
/* detect & configure */
switch (core->boardnr) {
snprintf(ir->name, sizeof(ir->name), "cx88 IR (%s)", core->board.name);
snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", pci_name(pci));
- input_dev->name = ir->name;
- input_dev->phys = ir->phys;
- input_dev->id.bustype = BUS_PCI;
- input_dev->id.version = 1;
+ dev->input_name = ir->name;
+ dev->input_phys = ir->phys;
+ dev->input_id.bustype = BUS_PCI;
+ dev->input_id.version = 1;
if (pci->subsystem_vendor) {
- input_dev->id.vendor = pci->subsystem_vendor;
- input_dev->id.product = pci->subsystem_device;
+ dev->input_id.vendor = pci->subsystem_vendor;
+ dev->input_id.product = pci->subsystem_device;
} else {
- input_dev->id.vendor = pci->vendor;
- input_dev->id.product = pci->device;
+ dev->input_id.vendor = pci->vendor;
+ dev->input_id.product = pci->device;
}
- input_dev->dev.parent = &pci->dev;
- /* record handles to ourself */
- ir->core = core;
- core->ir = ir;
+ dev->dev.parent = &pci->dev;
+ dev->map_name = ir_codes;
+ dev->driver_name = MODULE_NAME;
+ dev->priv = core;
+ dev->open = cx88_ir_open;
+ dev->close = cx88_ir_close;
+ dev->scanmask = hardware_mask;
if (ir->sampling) {
- ir_type = IR_TYPE_ALL;
- ir->props.driver_type = RC_DRIVER_IR_RAW;
- ir->props.timeout = 10 * 1000 * 1000; /* 10 ms */
- } else
- ir->props.driver_type = RC_DRIVER_SCANCODE;
-
- ir->props.priv = core;
- ir->props.open = cx88_ir_open;
- ir->props.close = cx88_ir_close;
- ir->props.scanmask = hardware_mask;
- ir->props.allowed_protos = ir_type;
+ dev->driver_type = RC_DRIVER_IR_RAW;
+ dev->timeout = 10 * 1000 * 1000; /* 10 ms */
+ } else {
+ dev->driver_type = RC_DRIVER_SCANCODE;
+ dev->allowed_protos = ir_type;
+ }
+
+ ir->core = core;
+ core->ir = ir;
/* all done */
- err = ir_input_register(ir->input, ir_codes, &ir->props, MODULE_NAME);
+ err = rc_register_device(dev);
if (err)
goto err_out_free;
return 0;
- err_out_free:
+err_out_free:
+ rc_free_device(dev);
core->ir = NULL;
kfree(ir);
return err;
return 0;
cx88_ir_stop(core);
- ir_input_unregister(ir->input);
+ rc_unregister_device(ir->dev);
kfree(ir);
/* done */
u32 samples;
unsigned todo, bits;
struct ir_raw_event ev;
- struct ir_input_dev *irdev;
if (!ir || !ir->sampling)
return;
* represents a pulse.
*/
samples = cx_read(MO_SAMPLE_IO);
- irdev = input_get_drvdata(ir->input);
- if (samples == 0xff && irdev->idle)
+ if (samples == 0xff && ir->dev->idle)
return;
init_ir_raw_event(&ev);
ev.pulse = samples & 0x80000000 ? false : true;
bits = min(todo, 32U - fls(ev.pulse ? samples : ~samples));
ev.duration = (bits * NSEC_PER_SEC) / (1000 * ir_samplerate);
- ir_raw_event_store_with_filter(ir->input, &ev);
+ ir_raw_event_store_with_filter(ir->dev, &ev);
samples <<= bits;
}
- ir_raw_event_handle(ir->input);
+ ir_raw_event_handle(ir->dev);
}
void cx88_i2c_init_ir(struct cx88_core *core)
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
-#include <linux/input.h>
#include <linux/usb.h>
#include <linux/slab.h>
struct em28xx_IR {
struct em28xx *dev;
- struct input_dev *input;
+ struct rc_dev *rc;
char name[32];
char phys[32];
unsigned int last_readcount;
int (*get_key)(struct em28xx_IR *, struct em28xx_ir_poll_result *);
-
- /* IR device properties */
-
- struct ir_dev_props props;
};
/**********************************************************
poll_result.toggle_bit, poll_result.read_count,
poll_result.rc_address, poll_result.rc_data[0]);
if (ir->full_code)
- ir_keydown(ir->input,
+ ir_keydown(ir->rc,
poll_result.rc_address << 8 |
poll_result.rc_data[0],
poll_result.toggle_bit);
else
- ir_keydown(ir->input,
+ ir_keydown(ir->rc,
poll_result.rc_data[0],
poll_result.toggle_bit);
schedule_delayed_work(&ir->work, msecs_to_jiffies(ir->polling));
}
-static int em28xx_ir_start(void *priv)
+static int em28xx_ir_start(struct rc_dev *rc)
{
- struct em28xx_IR *ir = priv;
+ struct em28xx_IR *ir = rc->priv;
INIT_DELAYED_WORK(&ir->work, em28xx_ir_work);
schedule_delayed_work(&ir->work, 0);
return 0;
}
-static void em28xx_ir_stop(void *priv)
+static void em28xx_ir_stop(struct rc_dev *rc)
{
- struct em28xx_IR *ir = priv;
+ struct em28xx_IR *ir = rc->priv;
cancel_delayed_work_sync(&ir->work);
}
-int em28xx_ir_change_protocol(void *priv, u64 ir_type)
+int em28xx_ir_change_protocol(struct rc_dev *rc_dev, u64 ir_type)
{
int rc = 0;
- struct em28xx_IR *ir = priv;
+ struct em28xx_IR *ir = rc_dev->priv;
struct em28xx *dev = ir->dev;
u8 ir_config = EM2874_IR_RC5;
int em28xx_ir_init(struct em28xx *dev)
{
struct em28xx_IR *ir;
- struct input_dev *input_dev;
+ struct rc_dev *rc;
int err = -ENOMEM;
if (dev->board.ir_codes == NULL) {
}
ir = kzalloc(sizeof(*ir), GFP_KERNEL);
- input_dev = input_allocate_device();
- if (!ir || !input_dev)
+ rc = rc_allocate_device();
+ if (!ir || !rc)
goto err_out_free;
/* record handles to ourself */
ir->dev = dev;
dev->ir = ir;
-
- ir->input = input_dev;
+ ir->rc = rc;
/*
* em2874 supports more protocols. For now, let's just announce
* the two protocols that were already tested
*/
- ir->props.allowed_protos = IR_TYPE_RC5 | IR_TYPE_NEC;
- ir->props.priv = ir;
- ir->props.change_protocol = em28xx_ir_change_protocol;
- ir->props.open = em28xx_ir_start;
- ir->props.close = em28xx_ir_stop;
+ rc->allowed_protos = IR_TYPE_RC5 | IR_TYPE_NEC;
+ rc->priv = ir;
+ rc->change_protocol = em28xx_ir_change_protocol;
+ rc->open = em28xx_ir_start;
+ rc->close = em28xx_ir_stop;
/* By default, keep protocol field untouched */
- err = em28xx_ir_change_protocol(ir, IR_TYPE_UNKNOWN);
+ err = em28xx_ir_change_protocol(rc, IR_TYPE_UNKNOWN);
if (err)
goto err_out_free;
usb_make_path(dev->udev, ir->phys, sizeof(ir->phys));
strlcat(ir->phys, "/input0", sizeof(ir->phys));
- input_dev->name = ir->name;
- input_dev->phys = ir->phys;
- input_dev->id.bustype = BUS_USB;
- input_dev->id.version = 1;
- input_dev->id.vendor = le16_to_cpu(dev->udev->descriptor.idVendor);
- input_dev->id.product = le16_to_cpu(dev->udev->descriptor.idProduct);
-
- input_dev->dev.parent = &dev->udev->dev;
-
-
+ rc->input_name = ir->name;
+ rc->input_phys = ir->phys;
+ rc->input_id.bustype = BUS_USB;
+ rc->input_id.version = 1;
+ rc->input_id.vendor = le16_to_cpu(dev->udev->descriptor.idVendor);
+ rc->input_id.product = le16_to_cpu(dev->udev->descriptor.idProduct);
+ rc->dev.parent = &dev->udev->dev;
+ rc->map_name = dev->board.ir_codes;
+ rc->driver_name = MODULE_NAME;
/* all done */
- err = ir_input_register(ir->input, dev->board.ir_codes,
- &ir->props, MODULE_NAME);
+ err = rc_register_device(rc);
if (err)
goto err_out_stop;
return 0;
+
err_out_stop:
dev->ir = NULL;
err_out_free:
+ rc_free_device(rc);
kfree(ir);
return err;
}
if (!ir)
return 0;
- em28xx_ir_stop(ir);
- ir_input_unregister(ir->input);
+ em28xx_ir_stop(ir->rc);
+ rc_unregister_device(ir->rc);
kfree(ir);
/* done */
}
if (rc)
- ir_keydown(ir->input, ir_key, 0);
+ ir_keydown(ir->rc, ir_key, 0);
}
static void ir_work(struct work_struct *work)
const char *name = NULL;
u64 ir_type = IR_TYPE_UNKNOWN;
struct IR_i2c *ir;
- struct input_dev *input_dev;
+ struct rc_dev *rc;
struct i2c_adapter *adap = client->adapter;
unsigned short addr = client->addr;
int err;
ir = kzalloc(sizeof(struct IR_i2c),GFP_KERNEL);
- input_dev = input_allocate_device();
- if (!ir || !input_dev) {
+ rc = rc_allocate_device();
+ if (!ir || !rc) {
err = -ENOMEM;
goto err_out_free;
}
ir->c = client;
- ir->input = input_dev;
+ ir->rc = rc;
ir->polling_interval = DEFAULT_POLLING_INTERVAL;
i2c_set_clientdata(client, ir);
dev_name(&client->dev));
/* init + register input device */
- input_dev->id.bustype = BUS_I2C;
- input_dev->name = ir->name;
- input_dev->phys = ir->phys;
+ rc->input_id.bustype = BUS_I2C;
+ rc->input_name = ir->name;
+ rc->input_phys = ir->phys;
+ rc->map_name = ir->ir_codes;
+ rc->driver_name = MODULE_NAME;
- err = ir_input_register(ir->input, ir->ir_codes, NULL, MODULE_NAME);
+ err = rc_register_device(rc);
if (err)
goto err_out_free;
printk(MODULE_NAME ": %s detected at %s [%s]\n",
- ir->input->name, ir->input->phys, adap->name);
+ ir->name, ir->phys, adap->name);
/* start polling via eventd */
INIT_DELAYED_WORK(&ir->work, ir_work);
return 0;
err_out_free:
+ rc_free_device(rc);
kfree(ir);
return err;
}
cancel_delayed_work_sync(&ir->work);
/* unregister device */
- ir_input_unregister(ir->input);
+ rc_unregister_device(ir->rc);
/* free memory */
kfree(ir);
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
-#include <linux/input.h>
#include <linux/slab.h>
#include "saa7134-reg.h"
static int ir_rc5_remote_gap = 885;
module_param(ir_rc5_remote_gap, int, 0644);
-static int repeat_delay = 500;
-module_param(repeat_delay, int, 0644);
-MODULE_PARM_DESC(repeat_delay, "delay before key repeat started");
-static int repeat_period = 33;
-module_param(repeat_period, int, 0644);
-MODULE_PARM_DESC(repeat_period, "repeat period between "
- "keypresses when key is down");
-
static unsigned int disable_other_ir;
module_param(disable_other_ir, int, 0644);
MODULE_PARM_DESC(disable_other_ir, "disable full codes of "
__saa7134_ir_stop(dev);
}
-static int saa7134_ir_open(void *priv)
+static int saa7134_ir_open(struct rc_dev *rc)
{
- struct saa7134_dev *dev = priv;
+ struct saa7134_dev *dev = rc->priv;
dev->remote->users++;
return __saa7134_ir_start(dev);
}
-static void saa7134_ir_close(void *priv)
+static void saa7134_ir_close(struct rc_dev *rc)
{
- struct saa7134_dev *dev = priv;
+ struct saa7134_dev *dev = rc->priv;
dev->remote->users--;
if (!dev->remote->users)
}
-static int saa7134_ir_change_protocol(void *priv, u64 ir_type)
+static int saa7134_ir_change_protocol(struct rc_dev *rc, u64 ir_type)
{
- struct saa7134_dev *dev = priv;
+ struct saa7134_dev *dev = rc->priv;
struct card_ir *ir = dev->remote;
u32 nec_gpio, rc5_gpio;
int saa7134_input_init1(struct saa7134_dev *dev)
{
struct card_ir *ir;
- struct input_dev *input_dev;
+ struct rc_dev *rc;
char *ir_codes = NULL;
u32 mask_keycode = 0;
u32 mask_keydown = 0;
}
ir = kzalloc(sizeof(*ir), GFP_KERNEL);
- input_dev = input_allocate_device();
- if (!ir || !input_dev) {
+ rc = rc_allocate_device();
+ if (!ir || !rc) {
err = -ENOMEM;
goto err_out_free;
}
- ir->dev = input_dev;
+ ir->dev = rc;
dev->remote = ir;
ir->running = 0;
snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0",
pci_name(dev->pci));
-
- ir->props.priv = dev;
- ir->props.open = saa7134_ir_open;
- ir->props.close = saa7134_ir_close;
-
+ rc->priv = dev;
+ rc->open = saa7134_ir_open;
+ rc->close = saa7134_ir_close;
if (raw_decode)
- ir->props.driver_type = RC_DRIVER_IR_RAW;
+ rc->driver_type = RC_DRIVER_IR_RAW;
if (!raw_decode && allow_protocol_change) {
- ir->props.allowed_protos = IR_TYPE_RC5 | IR_TYPE_NEC;
- ir->props.change_protocol = saa7134_ir_change_protocol;
+ rc->allowed_protos = IR_TYPE_RC5 | IR_TYPE_NEC;
+ rc->change_protocol = saa7134_ir_change_protocol;
}
- input_dev->name = ir->name;
- input_dev->phys = ir->phys;
- input_dev->id.bustype = BUS_PCI;
- input_dev->id.version = 1;
+ rc->input_name = ir->name;
+ rc->input_phys = ir->phys;
+ rc->input_id.bustype = BUS_PCI;
+ rc->input_id.version = 1;
if (dev->pci->subsystem_vendor) {
- input_dev->id.vendor = dev->pci->subsystem_vendor;
- input_dev->id.product = dev->pci->subsystem_device;
+ rc->input_id.vendor = dev->pci->subsystem_vendor;
+ rc->input_id.product = dev->pci->subsystem_device;
} else {
- input_dev->id.vendor = dev->pci->vendor;
- input_dev->id.product = dev->pci->device;
+ rc->input_id.vendor = dev->pci->vendor;
+ rc->input_id.product = dev->pci->device;
}
- input_dev->dev.parent = &dev->pci->dev;
+ rc->dev.parent = &dev->pci->dev;
+ rc->map_name = ir_codes;
+ rc->driver_name = MODULE_NAME;
- err = ir_input_register(ir->dev, ir_codes, &ir->props, MODULE_NAME);
+ err = rc_register_device(rc);
if (err)
goto err_out_free;
- /* the remote isn't as bouncy as a keyboard */
- ir->dev->rep[REP_DELAY] = repeat_delay;
- ir->dev->rep[REP_PERIOD] = repeat_period;
-
return 0;
err_out_free:
+ rc_free_device(rc);
dev->remote = NULL;
kfree(ir);
return err;
return;
saa7134_ir_stop(dev);
- ir_input_unregister(dev->remote->dev);
+ rc_unregister_device(dev->remote->dev);
kfree(dev->remote);
dev->remote = NULL;
}
struct tm6000_IR {
struct tm6000_core *dev;
- struct ir_input_dev *input;
+ struct rc_dev *rc;
char name[32];
char phys[32];
/* IR device properties */
u64 ir_type;
- struct ir_dev_props props;
};
dprintk("ir->get_key result data=%04x\n", poll_result.rc_data);
if (ir->key) {
- ir_keydown(ir->input->input_dev, poll_result.rc_data, 0);
+ ir_keydown(ir->rc, poll_result.rc_data, 0);
ir->key = 0;
}
return;
schedule_delayed_work(&ir->work, msecs_to_jiffies(ir->polling));
}
-static int tm6000_ir_start(void *priv)
+static int tm6000_ir_start(struct rc_dev *rc)
{
- struct tm6000_IR *ir = priv;
+ struct tm6000_IR *ir = rc->priv;
INIT_DELAYED_WORK(&ir->work, tm6000_ir_work);
schedule_delayed_work(&ir->work, 0);
return 0;
}
-static void tm6000_ir_stop(void *priv)
+static void tm6000_ir_stop(struct rc_dev *rc)
{
- struct tm6000_IR *ir = priv;
+ struct tm6000_IR *ir = rc->priv;
cancel_delayed_work_sync(&ir->work);
}
-int tm6000_ir_change_protocol(void *priv, u64 ir_type)
+int tm6000_ir_change_protocol(struct rc_dev *rc, u64 ir_type)
{
- struct tm6000_IR *ir = priv;
+ struct tm6000_IR *ir = rc->priv;
ir->get_key = default_polling_getkey;
int tm6000_ir_init(struct tm6000_core *dev)
{
struct tm6000_IR *ir;
- struct ir_input_dev *ir_input_dev;
+ struct rc_dev *rc;
int err = -ENOMEM;
- int pipe, size, rc;
+ int pipe, size;
if (!enable_ir)
return -ENODEV;
return 0;
ir = kzalloc(sizeof(*ir), GFP_KERNEL);
- ir_input_dev = kzalloc(sizeof(*ir_input_dev), GFP_KERNEL);
- ir_input_dev->input_dev = input_allocate_device();
- if (!ir || !ir_input_dev || !ir_input_dev->input_dev)
- goto err_out_free;
+ rc = rc_allocate_device();
+ if (!ir | !rc)
+ goto out;
/* record handles to ourself */
ir->dev = dev;
dev->ir = ir;
-
- ir->input = ir_input_dev;
+ ir->rc = rc;
/* input einrichten */
- ir->props.allowed_protos = IR_TYPE_RC5 | IR_TYPE_NEC;
- ir->props.priv = ir;
- ir->props.change_protocol = tm6000_ir_change_protocol;
- ir->props.open = tm6000_ir_start;
- ir->props.close = tm6000_ir_stop;
- ir->props.driver_type = RC_DRIVER_SCANCODE;
+ rc->allowed_protos = IR_TYPE_RC5 | IR_TYPE_NEC;
+ rc->priv = ir;
+ rc->change_protocol = tm6000_ir_change_protocol;
+ rc->open = tm6000_ir_start;
+ rc->close = tm6000_ir_stop;
+ rc->driver_type = RC_DRIVER_SCANCODE;
ir->polling = 50;
usb_make_path(dev->udev, ir->phys, sizeof(ir->phys));
strlcat(ir->phys, "/input0", sizeof(ir->phys));
- tm6000_ir_change_protocol(ir, IR_TYPE_UNKNOWN);
-
- ir_input_dev->input_dev->name = ir->name;
- ir_input_dev->input_dev->phys = ir->phys;
- ir_input_dev->input_dev->id.bustype = BUS_USB;
- ir_input_dev->input_dev->id.version = 1;
- ir_input_dev->input_dev->id.vendor = le16_to_cpu(dev->udev->descriptor.idVendor);
- ir_input_dev->input_dev->id.product = le16_to_cpu(dev->udev->descriptor.idProduct);
+ tm6000_ir_change_protocol(rc, IR_TYPE_UNKNOWN);
- ir_input_dev->input_dev->dev.parent = &dev->udev->dev;
+ rc->input_name = ir->name;
+ rc->input_phys = ir->phys;
+ rc->input_id.bustype = BUS_USB;
+ rc->input_id.version = 1;
+ rc->input_id.vendor = le16_to_cpu(dev->udev->descriptor.idVendor);
+ rc->input_id.product = le16_to_cpu(dev->udev->descriptor.idProduct);
+ rc->map_name = dev->ir_codes;
+ rc->driver_name = "tm6000";
+ rc->dev.parent = &dev->udev->dev;
if (&dev->int_in) {
dprintk("IR over int\n");
ir->int_urb->transfer_buffer = kzalloc(size, GFP_KERNEL);
if (ir->int_urb->transfer_buffer == NULL) {
usb_free_urb(ir->int_urb);
- goto err_out_stop;
+ goto out;
}
dprintk("int interval: %d\n", dev->int_in.endp->desc.bInterval);
usb_fill_int_urb(ir->int_urb, dev->udev, pipe,
ir->int_urb->transfer_buffer, size,
tm6000_ir_urb_received, dev,
dev->int_in.endp->desc.bInterval);
- rc = usb_submit_urb(ir->int_urb, GFP_KERNEL);
- if (rc) {
+ err = usb_submit_urb(ir->int_urb, GFP_KERNEL);
+ if (err) {
kfree(ir->int_urb->transfer_buffer);
usb_free_urb(ir->int_urb);
- err = rc;
- goto err_out_stop;
+ goto out;
}
ir->urb_data = kzalloc(size, GFP_KERNEL);
}
/* ir register */
- err = ir_input_register(ir->input->input_dev, dev->ir_codes,
- &ir->props, "tm6000");
+ err = rc_register_device(rc);
if (err)
- goto err_out_stop;
+ goto out;
return 0;
-err_out_stop:
+out:
dev->ir = NULL;
-err_out_free:
- kfree(ir_input_dev);
+ rc_free_device(rc);
kfree(ir);
return err;
}
if (!ir)
return 0;
- ir_input_unregister(ir->input->input_dev);
+ rc_unregister_device(ir->rc);
if (ir->int_urb) {
usb_kill_urb(ir->int_urb);
ir->urb_data = NULL;
}
- kfree(ir->input);
- ir->input = NULL;
kfree(ir);
dev->ir = NULL;
/* this was saa7134_ir and bttv_ir, moved here for
* rc5 decoding. */
struct card_ir {
- struct input_dev *dev;
+ struct rc_dev *dev;
char name[32];
char phys[32];
int users;
u32 running:1;
- struct ir_dev_props props;
/* Usual gpio signalling */
u32 mask_keycode;
};
/**
- * struct ir_dev_props - Allow caller drivers to set special properties
- * @driver_type: specifies if the driver or hardware have already a decoder,
- * or if it needs to use the IR raw event decoders to produce a scancode
+ * struct rc_dev - represents a remote control device
+ * @dev: driver model's view of this device
+ * @input_name: name of the input child device
+ * @input_phys: physical path to the input child device
+ * @input_id: id of the input child device (struct input_id)
+ * @driver_name: name of the hardware driver which registered this device
+ * @map_name: name of the default keymap
+ * @rc_tab: current scan/key table
+ * @devno: unique remote control device number
+ * @raw: additional data for raw pulse/space devices
+ * @input_dev: the input child device used to communicate events to userspace
+ * @driver_type: specifies if protocol decoding is done in hardware or software
+ * @idle: used to keep track of RX state
* @allowed_protos: bitmask with the supported IR_TYPE_* protocols
* @scanmask: some hardware decoders are not capable of providing the full
* scancode to the application. As this is a hardware limit, we can't do
* anything with it. Yet, as the same keycode table can be used with other
* devices, a mask is provided to allow its usage. Drivers should generally
* leave this field in blank
+ * @priv: driver-specific data
+ * @keylock: protects the remaining members of the struct
+ * @keypressed: whether a key is currently pressed
+ * @keyup_jiffies: time (in jiffies) when the current keypress should be released
+ * @timer_keyup: timer for releasing a keypress
+ * @last_keycode: keycode of last keypress
+ * @last_scancode: scancode of last keypress
+ * @last_toggle: toggle value of last command
* @timeout: optional time after which device stops sending data
* @min_timeout: minimum timeout supported by device
* @max_timeout: maximum timeout supported by device
* @rx_resolution : resolution (in ns) of input sampler
* @tx_resolution: resolution (in ns) of output sampler
- * @priv: driver-specific data, to be used on the callbacks
* @change_protocol: allow changing the protocol used on hardware decoders
* @open: callback to allow drivers to enable polling/irq when IR input device
* is opened.
* @s_tx_duty_cycle: set transmit duty cycle (0% - 100%)
* @s_rx_carrier: inform driver about carrier it is expected to handle
* @tx_ir: transmit IR
- * @s_idle: optional: enable/disable hardware idle mode, upon which,
- device doesn't interrupt host until it sees IR pulses
+ * @s_idle: enable/disable hardware idle mode, upon which,
+ * device doesn't interrupt host until it sees IR pulses
* @s_learning_mode: enable wide band receiver used for learning
* @s_carrier_report: enable carrier reports
*/
-struct ir_dev_props {
- enum rc_driver_type driver_type;
- unsigned long allowed_protos;
- u32 scanmask;
-
- u32 timeout;
- u32 min_timeout;
- u32 max_timeout;
-
- u32 rx_resolution;
- u32 tx_resolution;
-
- void *priv;
- int (*change_protocol)(void *priv, u64 ir_type);
- int (*open)(void *priv);
- void (*close)(void *priv);
- int (*s_tx_mask)(void *priv, u32 mask);
- int (*s_tx_carrier)(void *priv, u32 carrier);
- int (*s_tx_duty_cycle)(void *priv, u32 duty_cycle);
- int (*s_rx_carrier_range)(void *priv, u32 min, u32 max);
- int (*tx_ir)(void *priv, int *txbuf, u32 n);
- void (*s_idle)(void *priv, bool enable);
- int (*s_learning_mode)(void *priv, int enable);
- int (*s_carrier_report) (void *priv, int enable);
-};
-
-struct ir_input_dev {
- struct device dev; /* device */
- char *driver_name; /* Name of the driver module */
- struct ir_scancode_table rc_tab; /* scan/key table */
- unsigned long devno; /* device number */
- struct ir_dev_props *props; /* Device properties */
- struct ir_raw_event_ctrl *raw; /* for raw pulse/space events */
- struct input_dev *input_dev; /* the input device associated with this device */
+struct rc_dev {
+ struct device dev;
+ const char *input_name;
+ const char *input_phys;
+ struct input_id input_id;
+ char *driver_name;
+ const char *map_name;
+ struct ir_scancode_table rc_tab;
+ unsigned long devno;
+ struct ir_raw_event_ctrl *raw;
+ struct input_dev *input_dev;
+ enum rc_driver_type driver_type;
bool idle;
-
- /* key info - needed by IR keycode handlers */
- spinlock_t keylock; /* protects the below members */
- bool keypressed; /* current state */
- unsigned long keyup_jiffies; /* when should the current keypress be released? */
- struct timer_list timer_keyup; /* timer for releasing a keypress */
- u32 last_keycode; /* keycode of last command */
- u32 last_scancode; /* scancode of last command */
- u8 last_toggle; /* toggle of last command */
+ u64 allowed_protos;
+ u32 scanmask;
+ void *priv;
+ spinlock_t keylock;
+ bool keypressed;
+ unsigned long keyup_jiffies;
+ struct timer_list timer_keyup;
+ u32 last_keycode;
+ u32 last_scancode;
+ u8 last_toggle;
+ u32 timeout;
+ u32 min_timeout;
+ u32 max_timeout;
+ u32 rx_resolution;
+ u32 tx_resolution;
+ int (*change_protocol)(struct rc_dev *dev, u64 ir_type);
+ int (*open)(struct rc_dev *dev);
+ void (*close)(struct rc_dev *dev);
+ int (*s_tx_mask)(struct rc_dev *dev, u32 mask);
+ int (*s_tx_carrier)(struct rc_dev *dev, u32 carrier);
+ int (*s_tx_duty_cycle)(struct rc_dev *dev, u32 duty_cycle);
+ int (*s_rx_carrier_range)(struct rc_dev *dev, u32 min, u32 max);
+ int (*tx_ir)(struct rc_dev *dev, int *txbuf, u32 n);
+ void (*s_idle)(struct rc_dev *dev, bool enable);
+ int (*s_learning_mode)(struct rc_dev *dev, int enable);
+ int (*s_carrier_report) (struct rc_dev *dev, int enable);
};
enum raw_event_type {
IR_STOP_EVENT = (1 << 3),
};
-#define to_ir_input_dev(_attr) container_of(_attr, struct ir_input_dev, attr)
-
-int __ir_input_register(struct input_dev *dev,
- const struct ir_scancode_table *ir_codes,
- struct ir_dev_props *props,
- const char *driver_name);
-
-static inline int ir_input_register(struct input_dev *dev,
- const char *map_name,
- struct ir_dev_props *props,
- const char *driver_name) {
- struct ir_scancode_table *ir_codes;
- struct ir_input_dev *ir_dev;
- int rc;
-
- if (!map_name)
- return -EINVAL;
-
- ir_codes = get_rc_map(map_name);
- if (!ir_codes) {
- ir_codes = get_rc_map(RC_MAP_EMPTY);
+#define to_rc_dev(d) container_of(d, struct rc_dev, dev)
- if (!ir_codes)
- return -EINVAL;
- }
- rc = __ir_input_register(dev, ir_codes, props, driver_name);
- if (rc < 0)
- return -EINVAL;
-
- ir_dev = input_get_drvdata(dev);
-
- if (!rc && ir_dev->props && ir_dev->props->change_protocol)
- rc = ir_dev->props->change_protocol(ir_dev->props->priv,
- ir_codes->ir_type);
-
- return rc;
-}
-
-void ir_input_unregister(struct input_dev *input_dev);
-
-void ir_repeat(struct input_dev *dev);
-void ir_keydown(struct input_dev *dev, int scancode, u8 toggle);
-void ir_keydown_notimeout(struct input_dev *dev, int scancode, u8 toggle);
-void ir_keyup(struct input_dev *dev);
-u32 ir_g_keycode_from_table(struct input_dev *input_dev, u32 scancode);
+void ir_repeat(struct rc_dev *dev);
+void ir_keydown(struct rc_dev *dev, int scancode, u8 toggle);
+void ir_keydown_notimeout(struct rc_dev *dev, int scancode, u8 toggle);
+void ir_keyup(struct rc_dev *dev);
+u32 ir_g_keycode_from_table(struct rc_dev *dev, u32 scancode);
/* From ir-raw-event.c */
struct ir_raw_event {
#define IR_MAX_DURATION 0xFFFFFFFF /* a bit more than 4 seconds */
-void ir_raw_event_handle(struct input_dev *input_dev);
-int ir_raw_event_store(struct input_dev *input_dev, struct ir_raw_event *ev);
-int ir_raw_event_store_edge(struct input_dev *input_dev, enum raw_event_type type);
-int ir_raw_event_store_with_filter(struct input_dev *input_dev,
+struct rc_dev *rc_allocate_device(void);
+void rc_free_device(struct rc_dev *dev);
+int rc_register_device(struct rc_dev *dev);
+void rc_unregister_device(struct rc_dev *dev);
+
+void ir_raw_event_handle(struct rc_dev *dev);
+int ir_raw_event_store(struct rc_dev *dev, struct ir_raw_event *ev);
+int ir_raw_event_store_edge(struct rc_dev *dev, enum raw_event_type type);
+int ir_raw_event_store_with_filter(struct rc_dev *dev,
struct ir_raw_event *ev);
-void ir_raw_event_set_idle(struct input_dev *input_dev, bool idle);
+void ir_raw_event_set_idle(struct rc_dev *dev, bool idle);
-static inline void ir_raw_event_reset(struct input_dev *input_dev)
+static inline void ir_raw_event_reset(struct rc_dev *dev)
{
DEFINE_IR_RAW_EVENT(ev);
ev.reset = true;
- ir_raw_event_store(input_dev, &ev);
- ir_raw_event_handle(input_dev);
+ ir_raw_event_store(dev, &ev);
+ ir_raw_event_handle(dev);
}
struct IR_i2c {
char *ir_codes;
-
struct i2c_client *c;
- struct input_dev *input;
+ struct rc_dev *rc;
/* Used to avoid fast repeating */
unsigned char old;