2
0
mirror of https://github.com/edk2-porting/linux-next.git synced 2024-12-23 12:43:55 +08:00

[media] ir-core: make struct rc_dev the primary interface

This patch merges the ir_input_dev and ir_dev_props structs into a single
struct called rc_dev. The drivers and various functions in rc-core used
by the drivers are also changed to use rc_dev as the primary interface
when dealing with rc-core.

This means that the input_dev is abstracted away from the drivers which
is necessary if we ever want to support multiple input devs per rc device.

The new API is similar to what the input subsystem uses, i.e:
rc_device_alloc()
rc_device_free()
rc_device_register()
rc_device_unregister()

[mchehab@redhat.com: Fix compilation on mceusb and cx231xx, due to merge conflicts]
Signed-off-by: David Härdeman <david@hardeman.nu>
Acked-by: Jarod Wilson <jarod@redhat.com>
Tested-by: Jarod Wilson <jarod@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
This commit is contained in:
David Härdeman 2010-10-29 16:08:23 -03:00 committed by Mauro Carvalho Chehab
parent 4c7b355df6
commit d8b4b5822f
44 changed files with 1230 additions and 1444 deletions

View File

@ -26,7 +26,6 @@
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/dma-mapping.h> #include <linux/dma-mapping.h>
#include <linux/input.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <media/ir-core.h> #include <media/ir-core.h>
@ -266,7 +265,7 @@ static void dm1105_card_list(struct pci_dev *pci)
/* infrared remote control */ /* infrared remote control */
struct infrared { struct infrared {
struct input_dev *input_dev; struct rc_dev *dev;
char input_phys[32]; char input_phys[32];
struct work_struct work; struct work_struct work;
u32 ir_command; u32 ir_command;
@ -532,7 +531,7 @@ static void dm1105_emit_key(struct work_struct *work)
data = (ircom >> 8) & 0x7f; data = (ircom >> 8) & 0x7f;
ir_keydown(ir->input_dev, data, 0); ir_keydown(ir->dev, data, 0);
} }
/* work handler */ /* work handler */
@ -593,46 +592,47 @@ static irqreturn_t dm1105_irq(int irq, void *dev_id)
int __devinit dm1105_ir_init(struct dm1105_dev *dm1105) int __devinit dm1105_ir_init(struct dm1105_dev *dm1105)
{ {
struct input_dev *input_dev; struct rc_dev *dev;
char *ir_codes = RC_MAP_DM1105_NEC;
int err = -ENOMEM; int err = -ENOMEM;
input_dev = input_allocate_device(); dev = rc_allocate_device();
if (!input_dev) if (!dev)
return -ENOMEM; return -ENOMEM;
dm1105->ir.input_dev = input_dev;
snprintf(dm1105->ir.input_phys, sizeof(dm1105->ir.input_phys), snprintf(dm1105->ir.input_phys, sizeof(dm1105->ir.input_phys),
"pci-%s/ir0", pci_name(dm1105->pdev)); "pci-%s/ir0", pci_name(dm1105->pdev));
input_dev->name = "DVB on-card IR receiver"; dev->driver_name = MODULE_NAME;
input_dev->phys = dm1105->ir.input_phys; dev->map_name = RC_MAP_DM1105_NEC;
input_dev->id.bustype = BUS_PCI; dev->driver_type = RC_DRIVER_SCANCODE;
input_dev->id.version = 1; 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) { if (dm1105->pdev->subsystem_vendor) {
input_dev->id.vendor = dm1105->pdev->subsystem_vendor; dev->input_id.vendor = dm1105->pdev->subsystem_vendor;
input_dev->id.product = dm1105->pdev->subsystem_device; dev->input_id.product = dm1105->pdev->subsystem_device;
} else { } else {
input_dev->id.vendor = dm1105->pdev->vendor; dev->input_id.vendor = dm1105->pdev->vendor;
input_dev->id.product = dm1105->pdev->device; dev->input_id.product = dm1105->pdev->device;
} }
dev->dev.parent = &dm1105->pdev->dev;
input_dev->dev.parent = &dm1105->pdev->dev;
INIT_WORK(&dm1105->ir.work, dm1105_emit_key); 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) { if (err < 0) {
input_free_device(input_dev); rc_free_device(dev);
return err; return err;
} }
dm1105->ir.dev = dev;
return 0; return 0;
} }
void __devexit dm1105_ir_exit(struct dm1105_dev *dm1105) 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) static int __devinit dm1105_hw_init(struct dm1105_dev *dev)

View File

@ -1041,13 +1041,13 @@ static int af9015_rc_query(struct dvb_usb_device *d)
priv->rc_keycode = buf[12] << 16 | priv->rc_keycode = buf[12] << 16 |
buf[13] << 8 | buf[14]; 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 { } else {
priv->rc_keycode = 0; /* clear just for sure */ priv->rc_keycode = 0; /* clear just for sure */
} }
} else if (priv->rc_repeat != buf[6] || buf[0]) { } else if (priv->rc_repeat != buf[6] || buf[0]) {
deb_rc("%s: key repeated\n", __func__); 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 { } else {
deb_rc("%s: no key press\n", __func__); deb_rc("%s: no key press\n", __func__);
} }
@ -1348,9 +1348,7 @@ static struct dvb_usb_device_properties af9015_properties[] = {
.module_name = "af9015", .module_name = "af9015",
.rc_query = af9015_rc_query, .rc_query = af9015_rc_query,
.rc_interval = AF9015_RC_INTERVAL, .rc_interval = AF9015_RC_INTERVAL,
.rc_props = { .allowed_protos = IR_TYPE_NEC,
.allowed_protos = IR_TYPE_NEC,
},
}, },
.i2c_algo = &af9015_i2c_algo, .i2c_algo = &af9015_i2c_algo,
@ -1478,9 +1476,7 @@ static struct dvb_usb_device_properties af9015_properties[] = {
.module_name = "af9015", .module_name = "af9015",
.rc_query = af9015_rc_query, .rc_query = af9015_rc_query,
.rc_interval = AF9015_RC_INTERVAL, .rc_interval = AF9015_RC_INTERVAL,
.rc_props = { .allowed_protos = IR_TYPE_NEC,
.allowed_protos = IR_TYPE_NEC,
},
}, },
.i2c_algo = &af9015_i2c_algo, .i2c_algo = &af9015_i2c_algo,
@ -1592,9 +1588,7 @@ static struct dvb_usb_device_properties af9015_properties[] = {
.module_name = "af9015", .module_name = "af9015",
.rc_query = af9015_rc_query, .rc_query = af9015_rc_query,
.rc_interval = AF9015_RC_INTERVAL, .rc_interval = AF9015_RC_INTERVAL,
.rc_props = { .allowed_protos = IR_TYPE_NEC,
.allowed_protos = IR_TYPE_NEC,
},
}, },
.i2c_algo = &af9015_i2c_algo, .i2c_algo = &af9015_i2c_algo,

View File

@ -394,7 +394,7 @@ static int anysee_rc_query(struct dvb_usb_device *d)
if (ircode[0]) { if (ircode[0]) {
deb_rc("%s: key pressed %02x\n", __func__, ircode[1]); 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; return 0;

View File

@ -60,7 +60,7 @@ extern int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff);
extern struct i2c_algorithm dib0700_i2c_algo; extern struct i2c_algorithm dib0700_i2c_algo;
extern int dib0700_identify_state(struct usb_device *udev, struct dvb_usb_device_properties *props, extern int dib0700_identify_state(struct usb_device *udev, struct dvb_usb_device_properties *props,
struct dvb_usb_device_description **desc, int *cold); 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 dib0700_device_count;
extern int dvb_usb_dib0700_ir_proto; extern int dvb_usb_dib0700_ir_proto;

View File

@ -471,9 +471,9 @@ int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
return dib0700_ctrl_wr(adap->dev, b, 4); 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; struct dib0700_state *st = d->priv;
u8 rc_setup[3] = { REQUEST_SET_RC, 0, 0 }; u8 rc_setup[3] = { REQUEST_SET_RC, 0, 0 };
int new_proto, ret; int new_proto, ret;
@ -535,7 +535,7 @@ static void dib0700_rc_urb_completion(struct urb *purb)
if (d == NULL) if (d == NULL)
return; return;
if (d->rc_input_dev == NULL) { if (d->rc_dev == NULL) {
/* This will occur if disable_rc_polling=1 */ /* This will occur if disable_rc_polling=1 */
usb_free_urb(purb); usb_free_urb(purb);
return; return;
@ -600,7 +600,7 @@ static void dib0700_rc_urb_completion(struct urb *purb)
goto resubmit; goto resubmit;
} }
ir_keydown(d->rc_input_dev, keycode, toggle); ir_keydown(d->rc_dev, keycode, toggle);
resubmit: resubmit:
/* Clean the buffer before we requeue */ /* Clean the buffer before we requeue */

View File

@ -520,13 +520,13 @@ static int dib0700_rc_query_old_firmware(struct dvb_usb_device *d)
d->last_event = keycode; d->last_event = keycode;
} }
ir_keydown(d->rc_input_dev, keycode, 0); ir_keydown(d->rc_dev, keycode, 0);
break; break;
default: default:
/* RC-5 protocol changes toggle bit on new keypress */ /* RC-5 protocol changes toggle bit on new keypress */
keycode = key[3-2] << 8 | key[3-3]; keycode = key[3-2] << 8 | key[3-3];
toggle = key[3-1]; toggle = key[3-1];
ir_keydown(d->rc_input_dev, keycode, toggle); ir_keydown(d->rc_dev, keycode, toggle);
break; break;
} }
@ -1924,12 +1924,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
.rc_interval = DEFAULT_RC_INTERVAL, .rc_interval = DEFAULT_RC_INTERVAL,
.rc_codes = RC_MAP_DIB0700_RC5_TABLE, .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
.rc_query = dib0700_rc_query_old_firmware, .rc_query = dib0700_rc_query_old_firmware,
.rc_props = { .allowed_protos = IR_TYPE_RC5 |
.allowed_protos = IR_TYPE_RC5 | IR_TYPE_RC6 |
IR_TYPE_RC6 | IR_TYPE_NEC,
IR_TYPE_NEC, .change_protocol = dib0700_change_protocol,
.change_protocol = dib0700_change_protocol,
},
}, },
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES, }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
@ -1960,12 +1958,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
.rc_interval = DEFAULT_RC_INTERVAL, .rc_interval = DEFAULT_RC_INTERVAL,
.rc_codes = RC_MAP_DIB0700_RC5_TABLE, .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
.rc_query = dib0700_rc_query_old_firmware, .rc_query = dib0700_rc_query_old_firmware,
.rc_props = { .allowed_protos = IR_TYPE_RC5 |
.allowed_protos = IR_TYPE_RC5 | IR_TYPE_RC6 |
IR_TYPE_RC6 | IR_TYPE_NEC,
IR_TYPE_NEC, .change_protocol = dib0700_change_protocol,
.change_protocol = dib0700_change_protocol,
},
}, },
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES, }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
@ -2021,12 +2017,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
.rc_interval = DEFAULT_RC_INTERVAL, .rc_interval = DEFAULT_RC_INTERVAL,
.rc_codes = RC_MAP_DIB0700_RC5_TABLE, .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
.rc_query = dib0700_rc_query_old_firmware, .rc_query = dib0700_rc_query_old_firmware,
.rc_props = { .allowed_protos = IR_TYPE_RC5 |
.allowed_protos = IR_TYPE_RC5 | IR_TYPE_RC6 |
IR_TYPE_RC6 | IR_TYPE_NEC,
IR_TYPE_NEC, .change_protocol = dib0700_change_protocol,
.change_protocol = dib0700_change_protocol,
},
}, },
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES, }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
@ -2065,12 +2059,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
.rc_codes = RC_MAP_DIB0700_RC5_TABLE, .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
.module_name = "dib0700", .module_name = "dib0700",
.rc_query = dib0700_rc_query_old_firmware, .rc_query = dib0700_rc_query_old_firmware,
.rc_props = { .allowed_protos = IR_TYPE_RC5 |
.allowed_protos = IR_TYPE_RC5 | IR_TYPE_RC6 |
IR_TYPE_RC6 | IR_TYPE_NEC,
IR_TYPE_NEC, .change_protocol = dib0700_change_protocol,
.change_protocol = dib0700_change_protocol,
},
}, },
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES, }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
@ -2143,12 +2135,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
.rc_codes = RC_MAP_DIB0700_RC5_TABLE, .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
.module_name = "dib0700", .module_name = "dib0700",
.rc_query = dib0700_rc_query_old_firmware, .rc_query = dib0700_rc_query_old_firmware,
.rc_props = { .allowed_protos = IR_TYPE_RC5 |
.allowed_protos = IR_TYPE_RC5 | IR_TYPE_RC6 |
IR_TYPE_RC6 | IR_TYPE_NEC,
IR_TYPE_NEC, .change_protocol = dib0700_change_protocol,
.change_protocol = dib0700_change_protocol,
},
}, },
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES, }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
@ -2189,12 +2179,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
.rc_codes = RC_MAP_DIB0700_RC5_TABLE, .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
.module_name = "dib0700", .module_name = "dib0700",
.rc_query = dib0700_rc_query_old_firmware, .rc_query = dib0700_rc_query_old_firmware,
.rc_props = { .allowed_protos = IR_TYPE_RC5 |
.allowed_protos = IR_TYPE_RC5 | IR_TYPE_RC6 |
IR_TYPE_RC6 | IR_TYPE_NEC,
IR_TYPE_NEC, .change_protocol = dib0700_change_protocol,
.change_protocol = dib0700_change_protocol,
},
}, },
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES, }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
@ -2259,12 +2247,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
.rc_codes = RC_MAP_DIB0700_RC5_TABLE, .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
.module_name = "dib0700", .module_name = "dib0700",
.rc_query = dib0700_rc_query_old_firmware, .rc_query = dib0700_rc_query_old_firmware,
.rc_props = { .allowed_protos = IR_TYPE_RC5 |
.allowed_protos = IR_TYPE_RC5 | IR_TYPE_RC6 |
IR_TYPE_RC6 | IR_TYPE_NEC,
IR_TYPE_NEC, .change_protocol = dib0700_change_protocol,
.change_protocol = dib0700_change_protocol,
},
}, },
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES, }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
@ -2308,12 +2294,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
.rc_codes = RC_MAP_DIB0700_NEC_TABLE, .rc_codes = RC_MAP_DIB0700_NEC_TABLE,
.module_name = "dib0700", .module_name = "dib0700",
.rc_query = dib0700_rc_query_old_firmware, .rc_query = dib0700_rc_query_old_firmware,
.rc_props = { .allowed_protos = IR_TYPE_RC5 |
.allowed_protos = IR_TYPE_RC5 | IR_TYPE_RC6 |
IR_TYPE_RC6 | IR_TYPE_NEC,
IR_TYPE_NEC, .change_protocol = dib0700_change_protocol,
.change_protocol = dib0700_change_protocol,
},
}, },
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES, }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
@ -2379,12 +2363,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
.rc_codes = RC_MAP_DIB0700_RC5_TABLE, .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
.module_name = "dib0700", .module_name = "dib0700",
.rc_query = dib0700_rc_query_old_firmware, .rc_query = dib0700_rc_query_old_firmware,
.rc_props = { .allowed_protos = IR_TYPE_RC5 |
.allowed_protos = IR_TYPE_RC5 | IR_TYPE_RC6 |
IR_TYPE_RC6 | IR_TYPE_NEC,
IR_TYPE_NEC, .change_protocol = dib0700_change_protocol,
.change_protocol = dib0700_change_protocol,
},
}, },
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES, }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
.num_adapters = 1, .num_adapters = 1,
@ -2417,12 +2399,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
.rc_codes = RC_MAP_DIB0700_RC5_TABLE, .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
.module_name = "dib0700", .module_name = "dib0700",
.rc_query = dib0700_rc_query_old_firmware, .rc_query = dib0700_rc_query_old_firmware,
.rc_props = { .allowed_protos = IR_TYPE_RC5 |
.allowed_protos = IR_TYPE_RC5 | IR_TYPE_RC6 |
IR_TYPE_RC6 | IR_TYPE_NEC,
IR_TYPE_NEC, .change_protocol = dib0700_change_protocol,
.change_protocol = dib0700_change_protocol,
},
}, },
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES, }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
.num_adapters = 1, .num_adapters = 1,
@ -2487,12 +2467,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
.rc_codes = RC_MAP_DIB0700_RC5_TABLE, .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
.module_name = "dib0700", .module_name = "dib0700",
.rc_query = dib0700_rc_query_old_firmware, .rc_query = dib0700_rc_query_old_firmware,
.rc_props = { .allowed_protos = IR_TYPE_RC5 |
.allowed_protos = IR_TYPE_RC5 | IR_TYPE_RC6 |
IR_TYPE_RC6 | IR_TYPE_NEC,
IR_TYPE_NEC, .change_protocol = dib0700_change_protocol,
.change_protocol = dib0700_change_protocol,
},
}, },
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES, }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
.num_adapters = 1, .num_adapters = 1,
@ -2533,12 +2511,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
.rc_codes = RC_MAP_DIB0700_NEC_TABLE, .rc_codes = RC_MAP_DIB0700_NEC_TABLE,
.module_name = "dib0700", .module_name = "dib0700",
.rc_query = dib0700_rc_query_old_firmware, .rc_query = dib0700_rc_query_old_firmware,
.rc_props = { .allowed_protos = IR_TYPE_RC5 |
.allowed_protos = IR_TYPE_RC5 | IR_TYPE_RC6 |
IR_TYPE_RC6 | IR_TYPE_NEC,
IR_TYPE_NEC, .change_protocol = dib0700_change_protocol,
.change_protocol = dib0700_change_protocol,
},
}, },
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES, }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
.num_adapters = 2, .num_adapters = 2,
@ -2584,12 +2560,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
.rc_codes = RC_MAP_DIB0700_RC5_TABLE, .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
.module_name = "dib0700", .module_name = "dib0700",
.rc_query = dib0700_rc_query_old_firmware, .rc_query = dib0700_rc_query_old_firmware,
.rc_props = { .allowed_protos = IR_TYPE_RC5 |
.allowed_protos = IR_TYPE_RC5 | IR_TYPE_RC6 |
IR_TYPE_RC6 | IR_TYPE_NEC,
IR_TYPE_NEC, .change_protocol = dib0700_change_protocol,
.change_protocol = dib0700_change_protocol,
},
}, },
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES, }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
.num_adapters = 1, .num_adapters = 1,
@ -2623,12 +2597,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
.rc_codes = RC_MAP_DIB0700_RC5_TABLE, .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
.module_name = "dib0700", .module_name = "dib0700",
.rc_query = dib0700_rc_query_old_firmware, .rc_query = dib0700_rc_query_old_firmware,
.rc_props = { .allowed_protos = IR_TYPE_RC5 |
.allowed_protos = IR_TYPE_RC5 | IR_TYPE_RC6 |
IR_TYPE_RC6 | IR_TYPE_NEC,
IR_TYPE_NEC, .change_protocol = dib0700_change_protocol,
.change_protocol = dib0700_change_protocol,
},
}, },
}, },
}; };

View File

@ -106,10 +106,10 @@ static void legacy_dvb_usb_read_remote_control(struct work_struct *work)
d->last_event = event; d->last_event = event;
case REMOTE_KEY_REPEAT: case REMOTE_KEY_REPEAT:
deb_rc("key repeated\n"); deb_rc("key repeated\n");
input_event(d->rc_input_dev, EV_KEY, event, 1); input_event(d->input_dev, EV_KEY, event, 1);
input_sync(d->rc_input_dev); input_sync(d->input_dev);
input_event(d->rc_input_dev, EV_KEY, d->last_event, 0); input_event(d->input_dev, EV_KEY, d->last_event, 0);
input_sync(d->rc_input_dev); input_sync(d->input_dev);
break; break;
default: default:
break; break;
@ -154,10 +154,22 @@ schedule:
schedule_delayed_work(&d->rc_query_work,msecs_to_jiffies(d->props.rc.legacy.rc_interval)); 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, static int legacy_dvb_usb_remote_init(struct dvb_usb_device *d)
struct input_dev *input_dev)
{ {
int i, err, rc_interval; 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->getkeycode = legacy_dvb_usb_getkeycode;
input_dev->setkeycode = legacy_dvb_usb_setkeycode; input_dev->setkeycode = legacy_dvb_usb_setkeycode;
@ -221,18 +233,34 @@ static void dvb_usb_read_remote_control(struct work_struct *work)
msecs_to_jiffies(d->props.rc.core.rc_interval)); msecs_to_jiffies(d->props.rc.core.rc_interval));
} }
static int rc_core_dvb_usb_remote_init(struct dvb_usb_device *d, static int rc_core_dvb_usb_remote_init(struct dvb_usb_device *d)
struct input_dev *input_dev)
{ {
int err, rc_interval; int err, rc_interval;
struct rc_dev *dev;
d->props.rc.core.rc_props.priv = d; dev = rc_allocate_device();
err = ir_input_register(input_dev, if (!dev)
d->props.rc.core.rc_codes, return -ENOMEM;
&d->props.rc.core.rc_props,
d->props.rc.core.module_name); dev->driver_name = d->props.rc.core.module_name;
if (err < 0) 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; return err;
}
d->input_dev = NULL;
d->rc_dev = dev;
if (!d->props.rc.core.rc_query || d->props.rc.core.bulk_mode) if (!d->props.rc.core.rc_query || d->props.rc.core.bulk_mode)
return 0; return 0;
@ -251,7 +279,6 @@ static int rc_core_dvb_usb_remote_init(struct dvb_usb_device *d,
int dvb_usb_remote_init(struct dvb_usb_device *d) int dvb_usb_remote_init(struct dvb_usb_device *d)
{ {
struct input_dev *input_dev;
int err; int err;
if (dvb_usb_disable_rc_polling) if (dvb_usb_disable_rc_polling)
@ -267,26 +294,14 @@ int dvb_usb_remote_init(struct dvb_usb_device *d)
usb_make_path(d->udev, d->rc_phys, sizeof(d->rc_phys)); usb_make_path(d->udev, d->rc_phys, sizeof(d->rc_phys));
strlcat(d->rc_phys, "/ir0", 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. */ /* Start the remote-control polling. */
if (d->props.rc.legacy.rc_interval < 40) if (d->props.rc.legacy.rc_interval < 40)
d->props.rc.legacy.rc_interval = 100; /* default */ d->props.rc.legacy.rc_interval = 100; /* default */
d->rc_input_dev = input_dev;
if (d->props.rc.mode == DVB_RC_LEGACY) 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 else
err = rc_core_dvb_usb_remote_init(d, input_dev); err = rc_core_dvb_usb_remote_init(d);
if (err) if (err)
return err; return err;
@ -301,9 +316,9 @@ int dvb_usb_remote_exit(struct dvb_usb_device *d)
cancel_rearming_delayed_work(&d->rc_query_work); cancel_rearming_delayed_work(&d->rc_query_work);
flush_scheduled_work(); flush_scheduled_work();
if (d->props.rc.mode == DVB_RC_LEGACY) if (d->props.rc.mode == DVB_RC_LEGACY)
input_unregister_device(d->rc_input_dev); input_unregister_device(d->input_dev);
else else
ir_input_unregister(d->rc_input_dev); rc_unregister_device(d->rc_dev);
} }
d->state &= ~DVB_USB_STATE_REMOTE; d->state &= ~DVB_USB_STATE_REMOTE;
return 0; return 0;

View File

@ -180,18 +180,20 @@ struct dvb_rc_legacy {
* struct dvb_rc properties of remote controller, using rc-core * struct dvb_rc properties of remote controller, using rc-core
* @rc_codes: name of rc codes table * @rc_codes: name of rc codes table
* @protocol: type of protocol(s) currently used by the driver * @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_query: called to query an event event.
* @rc_interval: time in ms between two queries. * @rc_interval: time in ms between two queries.
* @rc_props: remote controller properties
* @bulk_mode: device supports bulk mode for RC (disable polling mode) * @bulk_mode: device supports bulk mode for RC (disable polling mode)
*/ */
struct dvb_rc { struct dvb_rc {
char *rc_codes; char *rc_codes;
u64 protocol; u64 protocol;
u64 allowed_protos;
int (*change_protocol)(struct rc_dev *dev, u64 ir_type);
char *module_name; char *module_name;
int (*rc_query) (struct dvb_usb_device *d); int (*rc_query) (struct dvb_usb_device *d);
int rc_interval; int rc_interval;
struct ir_dev_props rc_props;
bool bulk_mode; /* uses bulk mode */ bool bulk_mode; /* uses bulk mode */
}; };
@ -385,7 +387,8 @@ struct dvb_usb_adapter {
* *
* @i2c_adap: device's i2c_adapter if it uses I2CoverUSB * @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 * @rc_query_work: struct work_struct frequent rc queries
* @last_event: last triggered event * @last_event: last triggered event
* @last_state: last state (no, pressed, repeat) * @last_state: last state (no, pressed, repeat)
@ -418,7 +421,8 @@ struct dvb_usb_device {
struct dvb_usb_adapter adapter[MAX_NO_OF_ADAPTER_PER_DEVICE]; struct dvb_usb_adapter adapter[MAX_NO_OF_ADAPTER_PER_DEVICE];
/* remote control */ /* remote control */
struct input_dev *rc_input_dev; struct rc_dev *rc_dev;
struct input_dev *input_dev;
char rc_phys[64]; char rc_phys[64];
struct delayed_work rc_query_work; struct delayed_work rc_query_work;
u32 last_event; u32 last_event;

View File

@ -198,7 +198,7 @@ static int lme2510_remote_keypress(struct dvb_usb_adapter *adap, u16 keypress)
deb_info(1, "INT Key Keypress =%04x", keypress); deb_info(1, "INT Key Keypress =%04x", keypress);
if (keypress > 0) if (keypress > 0)
ir_keydown(d->rc_input_dev, keypress, 0); ir_keydown(d->rc_dev, keypress, 0);
return 0; return 0;
} }
@ -555,42 +555,39 @@ static int lme2510_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
static int lme2510_int_service(struct dvb_usb_adapter *adap) static int lme2510_int_service(struct dvb_usb_adapter *adap)
{ {
struct dvb_usb_device *d = adap->dev; struct dvb_usb_device *d = adap->dev;
struct input_dev *input_dev; struct rc_dev *rc;
char *ir_codes = RC_MAP_LME2510; int ret;
int ret = 0;
info("STA Configuring Remote"); info("STA Configuring Remote");
usb_make_path(d->udev, d->rc_phys, sizeof(d->rc_phys)); rc = rc_allocate_device();
if (!rc)
strlcat(d->rc_phys, "/ir0", sizeof(d->rc_phys));
input_dev = input_allocate_device();
if (!input_dev)
return -ENOMEM; return -ENOMEM;
input_dev->name = "LME2510 Remote Control"; usb_make_path(d->udev, d->rc_phys, sizeof(d->rc_phys));
input_dev->phys = d->rc_phys; strlcat(d->rc_phys, "/ir0", sizeof(d->rc_phys));
usb_to_input_id(d->udev, &input_dev->id); rc->input_name = "LME2510 Remote Control";
rc->input_phys = d->rc_phys;
ret |= ir_input_register(input_dev, ir_codes, NULL, "LME 2510"); 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) { if (ret) {
input_free_device(input_dev); rc_free_device(rc);
return ret; return ret;
} }
d->rc_dev = rc;
d->rc_input_dev = input_dev;
/* Start the Interupt */ /* Start the Interupt */
ret = lme2510_int_read(adap); ret = lme2510_int_read(adap);
if (ret < 0) { if (ret < 0) {
ir_input_unregister(input_dev); rc_unregister_device(rc);
input_free_device(input_dev); return -ENODEV;
} }
return (ret < 0) ? -ENODEV : 0; return 0;
} }
static u8 check_sum(u8 *p, u8 len) static u8 check_sum(u8 *p, u8 len)
@ -1025,7 +1022,7 @@ void *lme2510_exit_int(struct dvb_usb_device *d)
usb_free_coherent(d->udev, 5000, st->buffer, usb_free_coherent(d->udev, 5000, st->buffer,
st->lme_urb->transfer_dma); st->lme_urb->transfer_dma);
info("Interupt Service Stopped"); info("Interupt Service Stopped");
ir_input_unregister(d->rc_input_dev); rc_unregister_device(d->rc_dev);
info("Remote Stopped"); info("Remote Stopped");
} }
return buffer; return buffer;

View File

@ -171,7 +171,9 @@ struct mantis_pci {
struct work_struct uart_work; struct work_struct uart_work;
spinlock_t uart_lock; 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) #define MANTIS_HIF_STATUS (mantis->gpio_status)

View File

@ -18,7 +18,6 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
#include <linux/input.h>
#include <media/ir-core.h> #include <media/ir-core.h>
#include <linux/pci.h> #include <linux/pci.h>
@ -33,6 +32,7 @@
#include "mantis_uart.h" #include "mantis_uart.h"
#define MODULE_NAME "mantis_core" #define MODULE_NAME "mantis_core"
#define RC_MAP_MANTIS "rc-mantis"
static struct ir_scancode mantis_ir_table[] = { static struct ir_scancode mantis_ir_table[] = {
{ 0x29, KEY_POWER }, { 0x29, KEY_POWER },
@ -95,53 +95,65 @@ static struct ir_scancode mantis_ir_table[] = {
{ 0x00, KEY_BLUE }, { 0x00, KEY_BLUE },
}; };
struct ir_scancode_table ir_mantis = { static struct rc_keymap ir_mantis_map = {
.scan = mantis_ir_table, .map = {
.size = ARRAY_SIZE(mantis_ir_table), .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) int mantis_input_init(struct mantis_pci *mantis)
{ {
struct input_dev *rc; struct rc_dev *dev;
char name[80], dev[80];
int err; int err;
rc = input_allocate_device(); err = ir_register_map(&ir_mantis_map);
if (!rc) { if (err)
dprintk(MANTIS_ERROR, 1, "Input device allocate failed"); goto out;
return -ENOMEM;
dev = rc_allocate_device();
if (!dev) {
dprintk(MANTIS_ERROR, 1, "Remote device allocation failed");
err = -ENOMEM;
goto out_map;
} }
sprintf(name, "Mantis %s IR receiver", mantis->hwconfig->model_name); sprintf(mantis->input_name, "Mantis %s IR receiver", mantis->hwconfig->model_name);
sprintf(dev, "pci-%s/ir0", pci_name(mantis->pdev)); sprintf(mantis->input_phys, "pci-%s/ir0", pci_name(mantis->pdev));
rc->name = name; dev->input_name = mantis->input_name;
rc->phys = dev; 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;
rc->id.bustype = BUS_PCI; err = rc_register_device(dev);
rc->id.vendor = mantis->vendor_id;
rc->id.product = mantis->device_id;
rc->id.version = 1;
rc->dev = mantis->pdev->dev;
err = __ir_input_register(rc, &ir_mantis, NULL, MODULE_NAME);
if (err) { if (err) {
dprintk(MANTIS_ERROR, 1, "IR device registration failed, ret = %d", err); dprintk(MANTIS_ERROR, 1, "IR device registration failed, ret = %d", err);
input_free_device(rc); goto out_dev;
return -ENODEV;
} }
mantis->rc = rc; mantis->rc = dev;
return 0; 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) int mantis_exit(struct mantis_pci *mantis)
{ {
struct input_dev *rc = mantis->rc; rc_unregister_device(mantis->rc);
ir_unregister_map(&ir_mantis_map);
ir_input_unregister(rc);
return 0; return 0;
} }

View File

@ -438,7 +438,7 @@ static int smscore_init_ir(struct smscore_device_t *coredev)
int rc; int rc;
void *buffer; void *buffer;
coredev->ir.input_dev = NULL; coredev->ir.dev = NULL;
ir_io = sms_get_board(smscore_get_board_id(coredev))->board_cfg.ir; 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 */ if (ir_io) {/* only if IR port exist we use IR sub-module */
sms_info("IR loading"); sms_info("IR loading");

View File

@ -45,25 +45,24 @@ void sms_ir_event(struct smscore_device_t *coredev, const char *buf, int len)
ev.duration = abs(samples[i]) * 1000; /* Convert to ns */ ev.duration = abs(samples[i]) * 1000; /* Convert to ns */
ev.pulse = (samples[i] > 0) ? false : true; 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) int sms_ir_init(struct smscore_device_t *coredev)
{ {
struct input_dev *input_dev; int err;
int board_id = smscore_get_board_id(coredev); int board_id = smscore_get_board_id(coredev);
struct rc_dev *dev;
sms_log("Allocating input device"); sms_log("Allocating rc device");
input_dev = input_allocate_device(); dev = rc_allocate_device();
if (!input_dev) { if (!dev) {
sms_err("Not enough memory"); sms_err("Not enough memory");
return -ENOMEM; return -ENOMEM;
} }
coredev->ir.input_dev = input_dev;
coredev->ir.controller = 0; /* Todo: vega/nova SPI number */ coredev->ir.controller = 0; /* Todo: vega/nova SPI number */
coredev->ir.timeout = IR_DEFAULT_TIMEOUT; coredev->ir.timeout = IR_DEFAULT_TIMEOUT;
sms_log("IR port %d, timeout %d ms", sms_log("IR port %d, timeout %d ms",
@ -75,38 +74,41 @@ int sms_ir_init(struct smscore_device_t *coredev)
strlcpy(coredev->ir.phys, coredev->devpath, sizeof(coredev->ir.phys)); strlcpy(coredev->ir.phys, coredev->devpath, sizeof(coredev->ir.phys));
strlcat(coredev->ir.phys, "/ir0", sizeof(coredev->ir.phys)); strlcat(coredev->ir.phys, "/ir0", sizeof(coredev->ir.phys));
input_dev->name = coredev->ir.name; dev->input_name = coredev->ir.name;
input_dev->phys = coredev->ir.phys; dev->input_phys = coredev->ir.phys;
input_dev->dev.parent = coredev->device; dev->dev.parent = coredev->device;
#if 0 #if 0
/* TODO: properly initialize the parameters bellow */ /* TODO: properly initialize the parameters bellow */
input_dev->id.bustype = BUS_USB; dev->input_id.bustype = BUS_USB;
input_dev->id.version = 1; dev->input_id.version = 1;
input_dev->id.vendor = le16_to_cpu(dev->udev->descriptor.idVendor); dev->input_id.vendor = le16_to_cpu(dev->udev->descriptor.idVendor);
input_dev->id.product = le16_to_cpu(dev->udev->descriptor.idProduct); dev->input_id.product = le16_to_cpu(dev->udev->descriptor.idProduct);
#endif #endif
coredev->ir.props.priv = coredev; dev->priv = coredev;
coredev->ir.props.driver_type = RC_DRIVER_IR_RAW; dev->driver_type = RC_DRIVER_IR_RAW;
coredev->ir.props.allowed_protos = IR_TYPE_ALL; 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, err = rc_register_device(dev);
&coredev->ir.props, MODULE_NAME)) { if (err < 0) {
sms_err("Failed to register device"); sms_err("Failed to register device");
input_free_device(input_dev); rc_free_device(dev);
return -EACCES; return err;
} }
coredev->ir.dev = dev;
return 0; return 0;
} }
void sms_ir_exit(struct smscore_device_t *coredev) void sms_ir_exit(struct smscore_device_t *coredev)
{ {
if (coredev->ir.input_dev) if (coredev->ir.dev)
ir_input_unregister(coredev->ir.input_dev); rc_unregister_device(coredev->ir.dev);
sms_log(""); sms_log("");
} }

View File

@ -35,13 +35,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
struct smscore_device_t; struct smscore_device_t;
struct ir_t { struct ir_t {
struct input_dev *input_dev; struct rc_dev *dev;
char name[40]; char name[40];
char phys[32]; char phys[32];
char *rc_codes; char *rc_codes;
u64 protocol; u64 protocol;
struct ir_dev_props props;
u32 timeout; u32 timeout;
u32 controller; u32 controller;

View File

@ -33,7 +33,6 @@
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/input.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <media/ir-core.h> #include <media/ir-core.h>
@ -96,7 +95,7 @@ MODULE_PARM_DESC(ir_debug, "enable debugging information for IR decoding");
DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
struct budget_ci_ir { struct budget_ci_ir {
struct input_dev *dev; struct rc_dev *dev;
struct tasklet_struct msp430_irq_tasklet; struct tasklet_struct msp430_irq_tasklet;
char name[72]; /* 40 + 32 for (struct saa7146_dev).name */ char name[72]; /* 40 + 32 for (struct saa7146_dev).name */
char phys[32]; char phys[32];
@ -118,7 +117,7 @@ struct budget_ci {
static void msp430_ir_interrupt(unsigned long data) static void msp430_ir_interrupt(unsigned long data)
{ {
struct budget_ci *budget_ci = (struct budget_ci *) 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; u32 command = ttpci_budget_debiread(&budget_ci->budget, DEBINOSWAP, DEBIADDR_IR, 2, 1, 0) >> 8;
/* /*
@ -166,13 +165,11 @@ static void msp430_ir_interrupt(unsigned long data)
static int msp430_ir_init(struct budget_ci *budget_ci) static int msp430_ir_init(struct budget_ci *budget_ci)
{ {
struct saa7146_dev *saa = budget_ci->budget.dev; struct saa7146_dev *saa = budget_ci->budget.dev;
struct input_dev *input_dev = budget_ci->ir.dev; struct rc_dev *dev;
int error; int error;
char *ir_codes = NULL;
dev = rc_allocate_device();
budget_ci->ir.dev = input_dev = input_allocate_device(); if (!dev) {
if (!input_dev) {
printk(KERN_ERR "budget_ci: IR interface initialisation failed\n"); printk(KERN_ERR "budget_ci: IR interface initialisation failed\n");
return -ENOMEM; return -ENOMEM;
} }
@ -182,19 +179,19 @@ static int msp430_ir_init(struct budget_ci *budget_ci)
snprintf(budget_ci->ir.phys, sizeof(budget_ci->ir.phys), snprintf(budget_ci->ir.phys, sizeof(budget_ci->ir.phys),
"pci-%s/ir0", pci_name(saa->pci)); "pci-%s/ir0", pci_name(saa->pci));
input_dev->name = budget_ci->ir.name; dev->driver_name = MODULE_NAME;
dev->input_name = budget_ci->ir.name;
input_dev->phys = budget_ci->ir.phys; dev->input_phys = budget_ci->ir.phys;
input_dev->id.bustype = BUS_PCI; dev->input_id.bustype = BUS_PCI;
input_dev->id.version = 1; dev->input_id.version = 1;
if (saa->pci->subsystem_vendor) { if (saa->pci->subsystem_vendor) {
input_dev->id.vendor = saa->pci->subsystem_vendor; dev->input_id.vendor = saa->pci->subsystem_vendor;
input_dev->id.product = saa->pci->subsystem_device; dev->input_id.product = saa->pci->subsystem_device;
} else { } else {
input_dev->id.vendor = saa->pci->vendor; dev->input_id.vendor = saa->pci->vendor;
input_dev->id.product = saa->pci->device; dev->input_id.product = saa->pci->device;
} }
input_dev->dev.parent = &saa->pci->dev; dev->dev.parent = &saa->pci->dev;
if (rc5_device < 0) if (rc5_device < 0)
budget_ci->ir.rc5_device = IR_DEVICE_ANY; budget_ci->ir.rc5_device = IR_DEVICE_ANY;
@ -208,7 +205,7 @@ static int msp430_ir_init(struct budget_ci *budget_ci)
case 0x1011: case 0x1011:
case 0x1012: case 0x1012:
/* The hauppauge keymap is a superset of these remotes */ /* 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) if (rc5_device < 0)
budget_ci->ir.rc5_device = 0x1f; budget_ci->ir.rc5_device = 0x1f;
@ -218,23 +215,22 @@ static int msp430_ir_init(struct budget_ci *budget_ci)
case 0x1019: case 0x1019:
case 0x101a: case 0x101a:
/* for the Technotrend 1500 bundled remote */ /* for the Technotrend 1500 bundled remote */
ir_codes = RC_MAP_TT_1500; dev->map_name = RC_MAP_TT_1500;
break; break;
default: default:
/* unknown remote */ /* unknown remote */
ir_codes = RC_MAP_BUDGET_CI_OLD; dev->map_name = RC_MAP_BUDGET_CI_OLD;
break; break;
} }
error = ir_input_register(input_dev, ir_codes, NULL, MODULE_NAME); error = rc_register_device(dev);
if (error) { if (error) {
printk(KERN_ERR "budget_ci: could not init driver for IR device (code %d)\n", error); printk(KERN_ERR "budget_ci: could not init driver for IR device (code %d)\n", error);
rc_free_device(dev);
return error; return error;
} }
/* note: these must be after input_register_device */ budget_ci->ir.dev = dev;
input_dev->rep[REP_DELAY] = 400;
input_dev->rep[REP_PERIOD] = 250;
tasklet_init(&budget_ci->ir.msp430_irq_tasklet, msp430_ir_interrupt, tasklet_init(&budget_ci->ir.msp430_irq_tasklet, msp430_ir_interrupt,
(unsigned long) budget_ci); (unsigned long) budget_ci);
@ -248,13 +244,12 @@ static int msp430_ir_init(struct budget_ci *budget_ci)
static void msp430_ir_deinit(struct budget_ci *budget_ci) static void msp430_ir_deinit(struct budget_ci *budget_ci)
{ {
struct saa7146_dev *saa = budget_ci->budget.dev; struct saa7146_dev *saa = budget_ci->budget.dev;
struct input_dev *dev = budget_ci->ir.dev;
SAA7146_IER_DISABLE(saa, MASK_06); SAA7146_IER_DISABLE(saa, MASK_06);
saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT); saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT);
tasklet_kill(&budget_ci->ir.msp430_irq_tasklet); 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) static int ciintf_read_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address)

View File

@ -37,9 +37,7 @@
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/input.h>
#include <media/ir-core.h> #include <media/ir-core.h>
#include <media/ir-common.h>
#include "ene_ir.h" #include "ene_ir.h"
static int sample_period; static int sample_period;
@ -357,7 +355,7 @@ void ene_rx_sense_carrier(struct ene_device *dev)
ev.carrier_report = true; ev.carrier_report = true;
ev.carrier = carrier; ev.carrier = carrier;
ev.duty_cycle = duty_cycle; ev.duty_cycle = duty_cycle;
ir_raw_event_store(dev->idev, &ev); ir_raw_event_store(dev->rdev, &ev);
} }
} }
@ -448,32 +446,32 @@ static void ene_rx_setup(struct ene_device *dev)
select_timeout: select_timeout:
if (dev->rx_fan_input_inuse) { 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 /* Fan input doesn't support timeouts, it just ends the
input with a maximum sample */ 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 * MS_TO_NS(ENE_FW_SMPL_BUF_FAN_MSK *
ENE_FW_SAMPLE_PERIOD_FAN); ENE_FW_SAMPLE_PERIOD_FAN);
} else { } 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 /* Theoreticly timeout is unlimited, but we cap it
* because it was seen that on one device, it * because it was seen that on one device, it
* would stop sending spaces after around 250 msec. * would stop sending spaces after around 250 msec.
* Besides, this is close to 2^32 anyway and timeout is u32. * Besides, this is close to 2^32 anyway and timeout is u32.
*/ */
dev->props->min_timeout = MS_TO_NS(127 * sample_period); dev->rdev->min_timeout = MS_TO_NS(127 * sample_period);
dev->props->max_timeout = MS_TO_NS(200000); dev->rdev->max_timeout = MS_TO_NS(200000);
} }
if (dev->hw_learning_and_tx_capable) 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) if (dev->rdev->timeout > dev->rdev->max_timeout)
dev->props->timeout = dev->props->max_timeout; dev->rdev->timeout = dev->rdev->max_timeout;
if (dev->props->timeout < dev->props->min_timeout) if (dev->rdev->timeout < dev->rdev->min_timeout)
dev->props->timeout = dev->props->min_timeout; dev->rdev->timeout = dev->rdev->min_timeout;
} }
/* Enable the device for receive */ /* Enable the device for receive */
@ -504,7 +502,7 @@ static void ene_rx_enable(struct ene_device *dev)
ene_set_reg_mask(dev, ENE_FW1, ENE_FW1_ENABLE | ENE_FW1_IRQ); ene_set_reg_mask(dev, ENE_FW1, ENE_FW1_ENABLE | ENE_FW1_IRQ);
/* enter idle mode */ /* enter idle mode */
ir_raw_event_set_idle(dev->idev, true); ir_raw_event_set_idle(dev->rdev, true);
dev->rx_enabled = true; dev->rx_enabled = true;
} }
@ -518,7 +516,7 @@ static void ene_rx_disable(struct ene_device *dev)
/* disable hardware IRQ and firmware flag */ /* disable hardware IRQ and firmware flag */
ene_clear_reg_mask(dev, ENE_FW1, ENE_FW1_ENABLE | ENE_FW1_IRQ); 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; dev->rx_enabled = false;
} }
@ -805,10 +803,10 @@ static irqreturn_t ene_isr(int irq, void *data)
ev.duration = MS_TO_NS(hw_sample); ev.duration = MS_TO_NS(hw_sample);
ev.pulse = pulse; 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: unlock:
spin_unlock_irqrestore(&dev->hw_lock, flags); spin_unlock_irqrestore(&dev->hw_lock, flags);
return retval; return retval;
@ -823,7 +821,7 @@ static void ene_setup_default_settings(struct ene_device *dev)
dev->learning_mode_enabled = learning_mode_force; dev->learning_mode_enabled = learning_mode_force;
/* Set reasonable default timeout */ /* 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 */ /* Upload all hardware settings at once. Used at load and resume time */
@ -838,9 +836,9 @@ static void ene_setup_hw_settings(struct ene_device *dev)
} }
/* outside interface: called on first open*/ /* 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; unsigned long flags;
spin_lock_irqsave(&dev->hw_lock, flags); spin_lock_irqsave(&dev->hw_lock, flags);
@ -850,9 +848,9 @@ static int ene_open(void *data)
} }
/* outside interface: called on device close*/ /* 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; unsigned long flags;
spin_lock_irqsave(&dev->hw_lock, flags); spin_lock_irqsave(&dev->hw_lock, flags);
@ -861,9 +859,9 @@ static void ene_close(void *data)
} }
/* outside interface: set transmitter mask */ /* 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); dbg("TX: attempt to set transmitter mask %02x", tx_mask);
/* invalid txmask */ /* invalid txmask */
@ -879,9 +877,9 @@ static int ene_set_tx_mask(void *data, u32 tx_mask)
} }
/* outside interface : set tx carrier */ /* 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; u32 period = 2000000 / carrier;
dbg("TX: attempt to set tx carrier to %d kHz", carrier); dbg("TX: attempt to set tx carrier to %d kHz", carrier);
@ -900,9 +898,9 @@ static int ene_set_tx_carrier(void *data, u32 carrier)
} }
/*outside interface : set tx duty cycle */ /*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); dbg("TX: setting duty cycle to %d%%", duty_cycle);
dev->tx_duty_cycle = duty_cycle; dev->tx_duty_cycle = duty_cycle;
ene_tx_set_carrier(dev); ene_tx_set_carrier(dev);
@ -910,9 +908,9 @@ static int ene_set_tx_duty_cycle(void *data, u32 duty_cycle)
} }
/* outside interface: enable learning mode */ /* 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; unsigned long flags;
if (enable == dev->learning_mode_enabled) if (enable == dev->learning_mode_enabled)
return 0; return 0;
@ -926,9 +924,9 @@ static int ene_set_learning_mode(void *data, int enable)
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; unsigned long flags;
if (enable == dev->carrier_detect_enabled) if (enable == dev->carrier_detect_enabled)
@ -944,18 +942,20 @@ static int ene_set_carrier_report(void *data, int enable)
} }
/* outside interface: enable or disable idle mode */ /* 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) { if (idle) {
ene_rx_reset((struct ene_device *)data); ene_rx_reset(dev);
dbg("RX: end of data"); dbg("RX: end of data");
} }
} }
/* outside interface: transmit */ /* 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; unsigned long flags;
dev->tx_buffer = buf; dev->tx_buffer = buf;
@ -992,16 +992,13 @@ static int ene_transmit(void *data, int *buf, u32 n)
static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id) static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id)
{ {
int error = -ENOMEM; int error = -ENOMEM;
struct ir_dev_props *ir_props; struct rc_dev *rdev;
struct input_dev *input_dev;
struct ene_device *dev; struct ene_device *dev;
/* allocate memory */ /* 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); dev = kzalloc(sizeof(struct ene_device), GFP_KERNEL);
rdev = rc_allocate_device();
if (!input_dev || !ir_props || !dev) if (!dev || !rdev)
goto error1; goto error1;
/* validate resources */ /* validate resources */
@ -1054,24 +1051,25 @@ static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id)
if (!dev->hw_learning_and_tx_capable) if (!dev->hw_learning_and_tx_capable)
learning_mode_force = false; learning_mode_force = false;
ir_props->driver_type = RC_DRIVER_IR_RAW; rdev->driver_type = RC_DRIVER_IR_RAW;
ir_props->allowed_protos = IR_TYPE_ALL; rdev->allowed_protos = IR_TYPE_ALL;
ir_props->priv = dev; rdev->priv = dev;
ir_props->open = ene_open; rdev->open = ene_open;
ir_props->close = ene_close; rdev->close = ene_close;
ir_props->s_idle = ene_set_idle; rdev->s_idle = ene_set_idle;
rdev->driver_name = ENE_DRIVER_NAME;
dev->props = ir_props; rdev->map_name = RC_MAP_RC6_MCE;
dev->idev = input_dev; rdev->input_name = "ENE eHome Infrared Remote Receiver";
if (dev->hw_learning_and_tx_capable) { 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); init_completion(&dev->tx_complete);
ir_props->tx_ir = ene_transmit; rdev->tx_ir = ene_transmit;
ir_props->s_tx_mask = ene_set_tx_mask; rdev->s_tx_mask = ene_set_tx_mask;
ir_props->s_tx_carrier = ene_set_tx_carrier; rdev->s_tx_carrier = ene_set_tx_carrier;
ir_props->s_tx_duty_cycle = ene_set_tx_duty_cycle; rdev->s_tx_duty_cycle = ene_set_tx_duty_cycle;
ir_props->s_carrier_report = ene_set_carrier_report; rdev->s_carrier_report = ene_set_carrier_report;
rdev->input_name = "ENE eHome Infrared Remote Transceiver";
} }
ene_rx_setup_hw_buffer(dev); ene_rx_setup_hw_buffer(dev);
@ -1081,16 +1079,11 @@ static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id)
device_set_wakeup_capable(&pnp_dev->dev, true); device_set_wakeup_capable(&pnp_dev->dev, true);
device_set_wakeup_enable(&pnp_dev->dev, true); device_set_wakeup_enable(&pnp_dev->dev, true);
if (dev->hw_learning_and_tx_capable) error = rc_register_device(rdev);
input_dev->name = "ENE eHome Infrared Remote Transceiver"; if (error < 0)
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))
goto error; goto error;
dev->rdev = rdev;
ene_notice("driver has been succesfully loaded"); ene_notice("driver has been succesfully loaded");
return 0; return 0;
error: error:
@ -1099,8 +1092,7 @@ error:
if (dev && dev->hw_io >= 0) if (dev && dev->hw_io >= 0)
release_region(dev->hw_io, ENE_IO_SIZE); release_region(dev->hw_io, ENE_IO_SIZE);
error1: error1:
input_free_device(input_dev); rc_free_device(rdev);
kfree(ir_props);
kfree(dev); kfree(dev);
return error; return error;
} }
@ -1118,8 +1110,7 @@ static void ene_remove(struct pnp_dev *pnp_dev)
free_irq(dev->irq, dev); free_irq(dev->irq, dev);
release_region(dev->hw_io, ENE_IO_SIZE); release_region(dev->hw_io, ENE_IO_SIZE);
ir_input_unregister(dev->idev); rc_unregister_device(dev->rdev);
kfree(dev->props);
kfree(dev); kfree(dev);
} }

View File

@ -205,8 +205,7 @@
struct ene_device { struct ene_device {
struct pnp_dev *pnp_dev; struct pnp_dev *pnp_dev;
struct input_dev *idev; struct rc_dev *rdev;
struct ir_dev_props *props;
/* hw IO settings */ /* hw IO settings */
long hw_io; long hw_io;

View File

@ -88,7 +88,6 @@ static ssize_t lcd_write(struct file *file, const char *buf,
struct imon_context { struct imon_context {
struct device *dev; struct device *dev;
struct ir_dev_props *props;
/* Newer devices have two interfaces */ /* Newer devices have two interfaces */
struct usb_device *usbdev_intf0; struct usb_device *usbdev_intf0;
struct usb_device *usbdev_intf1; struct usb_device *usbdev_intf1;
@ -123,7 +122,7 @@ struct imon_context {
u16 vendor; /* usb vendor ID */ u16 vendor; /* usb vendor ID */
u16 product; /* usb product 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 *idev; /* input device for panel & IR mouse */
struct input_dev *touch; /* input device for touchscreen */ struct input_dev *touch; /* input device for touchscreen */
@ -984,16 +983,16 @@ static void imon_touch_display_timeout(unsigned long data)
* really just RC-6), but only one or the other at a time, as the signals * really just RC-6), but only one or the other at a time, as the signals
* are decoded onboard the receiver. * 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; int retval;
struct imon_context *ictx = priv; struct imon_context *ictx = rc->priv;
struct device *dev = ictx->dev; struct device *dev = ictx->dev;
bool pad_mouse; bool pad_mouse;
unsigned char ir_proto_packet[] = { unsigned char ir_proto_packet[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86 }; 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 " dev_warn(dev, "Looks like you're trying to use an IR protocol "
"this device does not support\n"); "this device does not support\n");
@ -1757,7 +1756,7 @@ static void imon_get_ffdc_type(struct imon_context *ictx)
printk(KERN_CONT " (id 0x%02x)\n", ffdc_cfg_byte); printk(KERN_CONT " (id 0x%02x)\n", ffdc_cfg_byte);
ictx->display_type = detected_display_type; ictx->display_type = detected_display_type;
ictx->props->allowed_protos = allowed_protos; ictx->rdev->allowed_protos = allowed_protos;
ictx->ir_type = allowed_protos; ictx->ir_type = allowed_protos;
} }
@ -1811,18 +1810,15 @@ static void imon_set_display_type(struct imon_context *ictx)
ictx->display_type = configured_display_type; 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 rc_dev *rdev;
struct ir_dev_props *props;
int ret; int ret;
char *ir_codes = NULL;
const unsigned char fp_packet[] = { 0x40, 0x00, 0x00, 0x00, const unsigned char fp_packet[] = { 0x40, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x88 }; 0x00, 0x00, 0x00, 0x88 };
rdev = input_allocate_device(); rdev = rc_allocate_device();
props = kzalloc(sizeof(*props), GFP_KERNEL); if (!rdev) {
if (!rdev || !props) {
dev_err(ictx->dev, "remote control dev allocation failed\n"); dev_err(ictx->dev, "remote control dev allocation failed\n");
goto out; goto out;
} }
@ -1833,18 +1829,20 @@ static struct input_dev *imon_init_rdev(struct imon_context *ictx)
sizeof(ictx->phys_rdev)); sizeof(ictx->phys_rdev));
strlcat(ictx->phys_rdev, "/input0", sizeof(ictx->phys_rdev)); strlcat(ictx->phys_rdev, "/input0", sizeof(ictx->phys_rdev));
rdev->name = ictx->name_rdev; rdev->input_name = ictx->name_rdev;
rdev->phys = ictx->phys_rdev; rdev->input_phys = ictx->phys_rdev;
usb_to_input_id(ictx->usbdev_intf0, &rdev->id); usb_to_input_id(ictx->usbdev_intf0, &rdev->input_id);
rdev->dev.parent = ictx->dev; rdev->dev.parent = ictx->dev;
rdev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
input_set_drvdata(rdev, ictx);
props->priv = ictx; rdev->priv = ictx;
props->driver_type = RC_DRIVER_SCANCODE; rdev->driver_type = RC_DRIVER_SCANCODE;
props->allowed_protos = IR_TYPE_OTHER | IR_TYPE_RC6; /* iMON PAD or MCE */ rdev->allowed_protos = IR_TYPE_OTHER | IR_TYPE_RC6; /* iMON PAD or MCE */
props->change_protocol = imon_ir_change_protocol; rdev->change_protocol = imon_ir_change_protocol;
ictx->props = props; 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 */ /* Enable front-panel buttons and/or knobs */
memcpy(ictx->usb_tx_buf, &fp_packet, sizeof(fp_packet)); memcpy(ictx->usb_tx_buf, &fp_packet, sizeof(fp_packet));
@ -1858,12 +1856,7 @@ static struct input_dev *imon_init_rdev(struct imon_context *ictx)
imon_set_display_type(ictx); imon_set_display_type(ictx);
if (ictx->ir_type == IR_TYPE_RC6) ret = rc_register_device(rdev);
ir_codes = RC_MAP_IMON_MCE;
else
ir_codes = RC_MAP_IMON_PAD;
ret = ir_input_register(rdev, ir_codes, props, MOD_NAME);
if (ret < 0) { if (ret < 0) {
dev_err(ictx->dev, "remote input dev register failed\n"); dev_err(ictx->dev, "remote input dev register failed\n");
goto out; goto out;
@ -1872,8 +1865,7 @@ static struct input_dev *imon_init_rdev(struct imon_context *ictx)
return rdev; return rdev;
out: out:
kfree(props); rc_free_device(rdev);
input_free_device(rdev);
return NULL; return NULL;
} }
@ -2144,7 +2136,7 @@ static struct imon_context *imon_init_intf0(struct usb_interface *intf)
return ictx; return ictx;
urb_submit_failed: urb_submit_failed:
ir_input_unregister(ictx->rdev); rc_unregister_device(ictx->rdev);
rdev_setup_failed: rdev_setup_failed:
input_unregister_device(ictx->idev); input_unregister_device(ictx->idev);
idev_setup_failed: idev_setup_failed:
@ -2371,7 +2363,7 @@ static void __devexit imon_disconnect(struct usb_interface *interface)
ictx->dev_present_intf0 = false; ictx->dev_present_intf0 = false;
usb_kill_urb(ictx->rx_urb_intf0); usb_kill_urb(ictx->rx_urb_intf0);
input_unregister_device(ictx->idev); input_unregister_device(ictx->idev);
ir_input_unregister(ictx->rdev); rc_unregister_device(ictx->rdev);
if (ictx->display_supported) { if (ictx->display_supported) {
if (ictx->display_type == IMON_DISPLAY_TYPE_LCD) if (ictx->display_type == IMON_DISPLAY_TYPE_LCD)
usb_deregister_dev(interface, &imon_lcd_class); usb_deregister_dev(interface, &imon_lcd_class);

View File

@ -37,17 +37,16 @@ enum jvc_state {
/** /**
* ir_jvc_decode() - Decode one JVC pulse or space * 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 * @duration: the struct ir_raw_event descriptor of the pulse/space
* *
* This function returns -EINVAL if the pulse violates the state machine * 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 = &dev->raw->jvc;
struct jvc_dec *data = &ir_dev->raw->jvc;
if (!(ir_dev->raw->enabled_protocols & IR_TYPE_JVC)) if (!(dev->raw->enabled_protocols & IR_TYPE_JVC))
return 0; return 0;
if (!is_timing_event(ev)) { if (!is_timing_event(ev)) {
@ -140,12 +139,12 @@ again:
scancode = (bitrev8((data->bits >> 8) & 0xff) << 8) | scancode = (bitrev8((data->bits >> 8) & 0xff) << 8) |
(bitrev8((data->bits >> 0) & 0xff) << 0); (bitrev8((data->bits >> 0) & 0xff) << 0);
IR_dprintk(1, "JVC scancode 0x%04x\n", scancode); 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->first = false;
data->old_bits = data->bits; data->old_bits = data->bits;
} else if (data->bits == data->old_bits) { } else if (data->bits == data->old_bits) {
IR_dprintk(1, "JVC repeat\n"); IR_dprintk(1, "JVC repeat\n");
ir_repeat(input_dev); ir_repeat(dev);
} else { } else {
IR_dprintk(1, "JVC invalid repeat msg\n"); IR_dprintk(1, "JVC invalid repeat msg\n");
break; break;

View File

@ -24,21 +24,20 @@
/** /**
* ir_lirc_decode() - Send raw IR data to lirc_dev to be relayed to the * ir_lirc_decode() - Send raw IR data to lirc_dev to be relayed to the
* lircd userspace daemon for decoding. * 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 * @duration: the struct ir_raw_event descriptor of the pulse/space
* *
* This function returns -EINVAL if the lirc interfaces aren't wired up. * 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 = &dev->raw->lirc;
struct lirc_codec *lirc = &ir_dev->raw->lirc;
int sample; int sample;
if (!(ir_dev->raw->enabled_protocols & IR_TYPE_LIRC)) if (!(dev->raw->enabled_protocols & IR_TYPE_LIRC))
return 0; 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; return -EINVAL;
/* Packet start */ /* Packet start */
@ -79,7 +78,7 @@ static int ir_lirc_decode(struct input_dev *input_dev, struct ir_raw_event ev)
(u64)LIRC_VALUE_MASK); (u64)LIRC_VALUE_MASK);
gap_sample = LIRC_SPACE(lirc->gap_duration); 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); (unsigned char *) &gap_sample);
lirc->gap = false; lirc->gap = false;
} }
@ -88,9 +87,9 @@ static int ir_lirc_decode(struct input_dev *input_dev, struct ir_raw_event ev)
LIRC_SPACE(ev.duration / 1000); 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); (unsigned char *) &sample);
wake_up(&ir_dev->raw->lirc.drv->rbuf->wait_poll); wake_up(&dev->raw->lirc.drv->rbuf->wait_poll);
return 0; return 0;
} }
@ -99,7 +98,7 @@ static ssize_t ir_lirc_transmit_ir(struct file *file, const char *buf,
size_t n, loff_t *ppos) size_t n, loff_t *ppos)
{ {
struct lirc_codec *lirc; struct lirc_codec *lirc;
struct ir_input_dev *ir_dev; struct rc_dev *dev;
int *txbuf; /* buffer with values to transmit */ int *txbuf; /* buffer with values to transmit */
int ret = 0, count; int ret = 0, count;
@ -118,14 +117,14 @@ static ssize_t ir_lirc_transmit_ir(struct file *file, const char *buf,
if (IS_ERR(txbuf)) if (IS_ERR(txbuf))
return PTR_ERR(txbuf); return PTR_ERR(txbuf);
ir_dev = lirc->ir_dev; dev = lirc->dev;
if (!ir_dev) { if (!dev) {
ret = -EFAULT; ret = -EFAULT;
goto out; goto out;
} }
if (ir_dev->props && ir_dev->props->tx_ir) if (dev->tx_ir)
ret = ir_dev->props->tx_ir(ir_dev->props->priv, txbuf, (u32)n); ret = dev->tx_ir(dev, txbuf, (u32)n);
out: out:
kfree(txbuf); kfree(txbuf);
@ -136,21 +135,18 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd,
unsigned long __user arg) unsigned long __user arg)
{ {
struct lirc_codec *lirc; struct lirc_codec *lirc;
struct ir_input_dev *ir_dev; struct rc_dev *dev;
int ret = 0; int ret = 0;
void *drv_data;
__u32 val = 0, tmp; __u32 val = 0, tmp;
lirc = lirc_get_pdata(filep); lirc = lirc_get_pdata(filep);
if (!lirc) if (!lirc)
return -EFAULT; return -EFAULT;
ir_dev = lirc->ir_dev; dev = lirc->dev;
if (!ir_dev || !ir_dev->props || !ir_dev->props->priv) if (!dev)
return -EFAULT; return -EFAULT;
drv_data = ir_dev->props->priv;
if (_IOC_DIR(cmd) & _IOC_WRITE) { if (_IOC_DIR(cmd) & _IOC_WRITE) {
ret = get_user(val, (__u32 *)arg); ret = get_user(val, (__u32 *)arg);
if (ret) if (ret)
@ -171,84 +167,85 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd,
/* TX settings */ /* TX settings */
case LIRC_SET_TRANSMITTER_MASK: case LIRC_SET_TRANSMITTER_MASK:
if (!ir_dev->props->s_tx_mask) if (!dev->s_tx_mask)
return -EINVAL; return -EINVAL;
return ir_dev->props->s_tx_mask(drv_data, val); return dev->s_tx_mask(dev, val);
case LIRC_SET_SEND_CARRIER: case LIRC_SET_SEND_CARRIER:
if (!ir_dev->props->s_tx_carrier) if (!dev->s_tx_carrier)
return -EINVAL; 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: case LIRC_SET_SEND_DUTY_CYCLE:
if (!ir_dev->props->s_tx_duty_cycle) if (!dev->s_tx_duty_cycle)
return -ENOSYS; return -ENOSYS;
if (val <= 0 || val >= 100) if (val <= 0 || val >= 100)
return -EINVAL; return -EINVAL;
return ir_dev->props->s_tx_duty_cycle(drv_data, val); return dev->s_tx_duty_cycle(dev, val);
/* RX settings */ /* RX settings */
case LIRC_SET_REC_CARRIER: case LIRC_SET_REC_CARRIER:
if (!ir_dev->props->s_rx_carrier_range) if (!dev->s_rx_carrier_range)
return -ENOSYS; return -ENOSYS;
if (val <= 0) if (val <= 0)
return -EINVAL; return -EINVAL;
return ir_dev->props->s_rx_carrier_range(drv_data, return dev->s_rx_carrier_range(dev,
ir_dev->raw->lirc.carrier_low, val); dev->raw->lirc.carrier_low,
val);
case LIRC_SET_REC_CARRIER_RANGE: case LIRC_SET_REC_CARRIER_RANGE:
if (val <= 0) if (val <= 0)
return -EINVAL; return -EINVAL;
ir_dev->raw->lirc.carrier_low = val; dev->raw->lirc.carrier_low = val;
return 0; return 0;
case LIRC_GET_REC_RESOLUTION: case LIRC_GET_REC_RESOLUTION:
val = ir_dev->props->rx_resolution; val = dev->rx_resolution;
break; break;
case LIRC_SET_WIDEBAND_RECEIVER: case LIRC_SET_WIDEBAND_RECEIVER:
if (!ir_dev->props->s_learning_mode) if (!dev->s_learning_mode)
return -ENOSYS; 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: case LIRC_SET_MEASURE_CARRIER_MODE:
if (!ir_dev->props->s_carrier_report) if (!dev->s_carrier_report)
return -ENOSYS; return -ENOSYS;
return ir_dev->props->s_carrier_report(drv_data, !!val); return dev->s_carrier_report(dev, !!val);
/* Generic timeout support */ /* Generic timeout support */
case LIRC_GET_MIN_TIMEOUT: case LIRC_GET_MIN_TIMEOUT:
if (!ir_dev->props->max_timeout) if (!dev->max_timeout)
return -ENOSYS; return -ENOSYS;
val = ir_dev->props->min_timeout / 1000; val = dev->min_timeout / 1000;
break; break;
case LIRC_GET_MAX_TIMEOUT: case LIRC_GET_MAX_TIMEOUT:
if (!ir_dev->props->max_timeout) if (!dev->max_timeout)
return -ENOSYS; return -ENOSYS;
val = ir_dev->props->max_timeout / 1000; val = dev->max_timeout / 1000;
break; break;
case LIRC_SET_REC_TIMEOUT: case LIRC_SET_REC_TIMEOUT:
if (!ir_dev->props->max_timeout) if (!dev->max_timeout)
return -ENOSYS; return -ENOSYS;
tmp = val * 1000; tmp = val * 1000;
if (tmp < ir_dev->props->min_timeout || if (tmp < dev->min_timeout ||
tmp > ir_dev->props->max_timeout) tmp > dev->max_timeout)
return -EINVAL; return -EINVAL;
ir_dev->props->timeout = tmp; dev->timeout = tmp;
break; break;
case LIRC_SET_REC_TIMEOUT_REPORTS: case LIRC_SET_REC_TIMEOUT_REPORTS:
@ -289,9 +286,8 @@ static struct file_operations lirc_fops = {
.llseek = no_llseek, .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_driver *drv;
struct lirc_buffer *rbuf; struct lirc_buffer *rbuf;
int rc = -ENOMEM; int rc = -ENOMEM;
@ -310,44 +306,40 @@ static int ir_lirc_register(struct input_dev *input_dev)
goto rbuf_init_failed; goto rbuf_init_failed;
features = LIRC_CAN_REC_MODE2; features = LIRC_CAN_REC_MODE2;
if (ir_dev->props->tx_ir) { if (dev->tx_ir) {
features |= LIRC_CAN_SEND_PULSE; features |= LIRC_CAN_SEND_PULSE;
if (ir_dev->props->s_tx_mask) if (dev->s_tx_mask)
features |= LIRC_CAN_SET_TRANSMITTER_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; features |= LIRC_CAN_SET_SEND_CARRIER;
if (dev->s_tx_duty_cycle)
if (ir_dev->props->s_tx_duty_cycle)
features |= LIRC_CAN_SET_SEND_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 | features |= LIRC_CAN_SET_REC_CARRIER |
LIRC_CAN_SET_REC_CARRIER_RANGE; LIRC_CAN_SET_REC_CARRIER_RANGE;
if (ir_dev->props->s_learning_mode) if (dev->s_learning_mode)
features |= LIRC_CAN_USE_WIDEBAND_RECEIVER; features |= LIRC_CAN_USE_WIDEBAND_RECEIVER;
if (ir_dev->props->s_carrier_report) if (dev->s_carrier_report)
features |= LIRC_CAN_MEASURE_CARRIER; features |= LIRC_CAN_MEASURE_CARRIER;
if (dev->max_timeout)
if (ir_dev->props->max_timeout)
features |= LIRC_CAN_SET_REC_TIMEOUT; features |= LIRC_CAN_SET_REC_TIMEOUT;
snprintf(drv->name, sizeof(drv->name), "ir-lirc-codec (%s)", snprintf(drv->name, sizeof(drv->name), "ir-lirc-codec (%s)",
ir_dev->driver_name); dev->driver_name);
drv->minor = -1; drv->minor = -1;
drv->features = features; drv->features = features;
drv->data = &ir_dev->raw->lirc; drv->data = &dev->raw->lirc;
drv->rbuf = rbuf; drv->rbuf = rbuf;
drv->set_use_inc = &ir_lirc_open; drv->set_use_inc = &ir_lirc_open;
drv->set_use_dec = &ir_lirc_close; drv->set_use_dec = &ir_lirc_close;
drv->code_length = sizeof(struct ir_raw_event) * 8; drv->code_length = sizeof(struct ir_raw_event) * 8;
drv->fops = &lirc_fops; drv->fops = &lirc_fops;
drv->dev = &ir_dev->dev; drv->dev = &dev->dev;
drv->owner = THIS_MODULE; drv->owner = THIS_MODULE;
drv->minor = lirc_register_driver(drv); drv->minor = lirc_register_driver(drv);
@ -356,8 +348,8 @@ static int ir_lirc_register(struct input_dev *input_dev)
goto lirc_register_failed; goto lirc_register_failed;
} }
ir_dev->raw->lirc.drv = drv; dev->raw->lirc.drv = drv;
ir_dev->raw->lirc.ir_dev = ir_dev; dev->raw->lirc.dev = dev;
return 0; return 0;
lirc_register_failed: lirc_register_failed:
@ -369,10 +361,9 @@ rbuf_alloc_failed:
return rc; 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 = &dev->raw->lirc;
struct lirc_codec *lirc = &ir_dev->raw->lirc;
lirc_unregister_driver(lirc->drv->minor); lirc_unregister_driver(lirc->drv->minor);
lirc_buffer_free(lirc->drv->rbuf); lirc_buffer_free(lirc->drv->rbuf);

View File

@ -39,19 +39,18 @@ enum nec_state {
/** /**
* ir_nec_decode() - Decode one NEC pulse or space * 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 * @duration: the struct ir_raw_event descriptor of the pulse/space
* *
* This function returns -EINVAL if the pulse violates the state machine * 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 = &dev->raw->nec;
struct nec_dec *data = &ir_dev->raw->nec;
u32 scancode; u32 scancode;
u8 address, not_address, command, not_command; 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; return 0;
if (!is_timing_event(ev)) { if (!is_timing_event(ev)) {
@ -89,7 +88,7 @@ static int ir_nec_decode(struct input_dev *input_dev, struct ir_raw_event ev)
data->state = STATE_BIT_PULSE; data->state = STATE_BIT_PULSE;
return 0; return 0;
} else if (eq_margin(ev.duration, NEC_REPEAT_SPACE, NEC_UNIT / 2)) { } 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"); IR_dprintk(1, "Repeat last key\n");
data->state = STATE_TRAILER_PULSE; data->state = STATE_TRAILER_PULSE;
return 0; return 0;
@ -115,7 +114,7 @@ static int ir_nec_decode(struct input_dev *input_dev, struct ir_raw_event ev)
geq_margin(ev.duration, geq_margin(ev.duration,
NEC_TRAILER_SPACE, NEC_UNIT / 2)) { NEC_TRAILER_SPACE, NEC_UNIT / 2)) {
IR_dprintk(1, "Repeat last key\n"); IR_dprintk(1, "Repeat last key\n");
ir_repeat(input_dev); ir_repeat(dev);
data->state = STATE_INACTIVE; data->state = STATE_INACTIVE;
return 0; return 0;
@ -179,7 +178,7 @@ static int ir_nec_decode(struct input_dev *input_dev, struct ir_raw_event ev)
if (data->is_nec_x) if (data->is_nec_x)
data->necx_repeat = true; data->necx_repeat = true;
ir_keydown(input_dev, scancode, 0); ir_keydown(dev, scancode, 0);
data->state = STATE_INACTIVE; data->state = STATE_INACTIVE;
return 0; return 0;
} }

View File

@ -40,19 +40,18 @@ enum rc5_state {
/** /**
* ir_rc5_decode() - Decode one RC-5 pulse or space * 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 * @ev: the struct ir_raw_event descriptor of the pulse/space
* *
* This function returns -EINVAL if the pulse violates the state machine * 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 = &dev->raw->rc5;
struct rc5_dec *data = &ir_dev->raw->rc5;
u8 toggle; u8 toggle;
u32 scancode; u32 scancode;
if (!(ir_dev->raw->enabled_protocols & IR_TYPE_RC5)) if (!(dev->raw->enabled_protocols & IR_TYPE_RC5))
return 0; return 0;
if (!is_timing_event(ev)) { if (!is_timing_event(ev)) {
@ -96,7 +95,7 @@ again:
return 0; return 0;
case STATE_BIT_END: case STATE_BIT_END:
if (!is_transition(&ev, &ir_dev->raw->prev_ev)) if (!is_transition(&ev, &dev->raw->prev_ev))
break; break;
if (data->count == data->wanted_bits) if (data->count == data->wanted_bits)
@ -151,7 +150,7 @@ again:
scancode, toggle); scancode, toggle);
} }
ir_keydown(input_dev, scancode, toggle); ir_keydown(dev, scancode, toggle);
data->state = STATE_INACTIVE; data->state = STATE_INACTIVE;
return 0; return 0;
} }

View File

@ -36,19 +36,18 @@ enum rc5_sz_state {
/** /**
* ir_rc5_sz_decode() - Decode one RC-5 Streamzap pulse or space * 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 * @ev: the struct ir_raw_event descriptor of the pulse/space
* *
* This function returns -EINVAL if the pulse violates the state machine * 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 = &dev->raw->rc5_sz;
struct rc5_sz_dec *data = &ir_dev->raw->rc5_sz;
u8 toggle, command, system; u8 toggle, command, system;
u32 scancode; u32 scancode;
if (!(ir_dev->raw->enabled_protocols & IR_TYPE_RC5_SZ)) if (!(dev->raw->enabled_protocols & IR_TYPE_RC5_SZ))
return 0; return 0;
if (!is_timing_event(ev)) { if (!is_timing_event(ev)) {
@ -91,7 +90,7 @@ again:
return 0; return 0;
case STATE_BIT_END: case STATE_BIT_END:
if (!is_transition(&ev, &ir_dev->raw->prev_ev)) if (!is_transition(&ev, &dev->raw->prev_ev))
break; break;
if (data->count == data->wanted_bits) if (data->count == data->wanted_bits)
@ -115,7 +114,7 @@ again:
IR_dprintk(1, "RC5-sz scancode 0x%04x (toggle: %u)\n", IR_dprintk(1, "RC5-sz scancode 0x%04x (toggle: %u)\n",
scancode, toggle); scancode, toggle);
ir_keydown(input_dev, scancode, toggle); ir_keydown(dev, scancode, toggle);
data->state = STATE_INACTIVE; data->state = STATE_INACTIVE;
return 0; return 0;
} }

View File

@ -70,19 +70,18 @@ static enum rc6_mode rc6_mode(struct rc6_dec *data)
/** /**
* ir_rc6_decode() - Decode one RC6 pulse or space * 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 * @ev: the struct ir_raw_event descriptor of the pulse/space
* *
* This function returns -EINVAL if the pulse violates the state machine * 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 = &dev->raw->rc6;
struct rc6_dec *data = &ir_dev->raw->rc6;
u32 scancode; u32 scancode;
u8 toggle; u8 toggle;
if (!(ir_dev->raw->enabled_protocols & IR_TYPE_RC6)) if (!(dev->raw->enabled_protocols & IR_TYPE_RC6))
return 0; return 0;
if (!is_timing_event(ev)) { if (!is_timing_event(ev)) {
@ -139,7 +138,7 @@ again:
return 0; return 0;
case STATE_HEADER_BIT_END: case STATE_HEADER_BIT_END:
if (!is_transition(&ev, &ir_dev->raw->prev_ev)) if (!is_transition(&ev, &dev->raw->prev_ev))
break; break;
if (data->count == RC6_HEADER_NBITS) if (data->count == RC6_HEADER_NBITS)
@ -159,7 +158,7 @@ again:
return 0; return 0;
case STATE_TOGGLE_END: 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)) !geq_margin(ev.duration, RC6_TOGGLE_END, RC6_UNIT / 2))
break; break;
@ -204,7 +203,7 @@ again:
return 0; return 0;
case STATE_BODY_BIT_END: case STATE_BODY_BIT_END:
if (!is_transition(&ev, &ir_dev->raw->prev_ev)) if (!is_transition(&ev, &dev->raw->prev_ev))
break; break;
if (data->count == data->wanted_bits) if (data->count == data->wanted_bits)
@ -243,7 +242,7 @@ again:
goto out; goto out;
} }
ir_keydown(input_dev, scancode, toggle); ir_keydown(dev, scancode, toggle);
data->state = STATE_INACTIVE; data->state = STATE_INACTIVE;
return 0; return 0;
} }

View File

@ -33,19 +33,18 @@ enum sony_state {
/** /**
* ir_sony_decode() - Decode one Sony pulse or space * 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 * @ev: the struct ir_raw_event descriptor of the pulse/space
* *
* This function returns -EINVAL if the pulse violates the state machine * 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 = &dev->raw->sony;
struct sony_dec *data = &ir_dev->raw->sony;
u32 scancode; u32 scancode;
u8 device, subdevice, function; u8 device, subdevice, function;
if (!(ir_dev->raw->enabled_protocols & IR_TYPE_SONY)) if (!(dev->raw->enabled_protocols & IR_TYPE_SONY))
return 0; return 0;
if (!is_timing_event(ev)) { if (!is_timing_event(ev)) {
@ -144,7 +143,7 @@ static int ir_sony_decode(struct input_dev *input_dev, struct ir_raw_event ev)
scancode = device << 16 | subdevice << 8 | function; scancode = device << 16 | subdevice << 8 | function;
IR_dprintk(1, "Sony(%u) scancode 0x%05x\n", data->count, scancode); 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; data->state = STATE_INACTIVE;
return 0; return 0;
} }

View File

@ -35,7 +35,6 @@
#include <linux/device.h> #include <linux/device.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/input.h>
#include <linux/usb.h> #include <linux/usb.h>
#include <linux/usb/input.h> #include <linux/usb/input.h>
#include <media/ir-core.h> #include <media/ir-core.h>
@ -317,7 +316,7 @@ static struct usb_device_id mceusb_dev_table[] = {
/* data structure for each usb transceiver */ /* data structure for each usb transceiver */
struct mceusb_dev { struct mceusb_dev {
/* ir-core bits */ /* ir-core bits */
struct ir_dev_props *props; struct rc_dev *rc;
/* optional features we can enable */ /* optional features we can enable */
bool carrier_report_enabled; bool carrier_report_enabled;
@ -325,7 +324,6 @@ struct mceusb_dev {
/* core device bits */ /* core device bits */
struct device *dev; struct device *dev;
struct input_dev *idev;
/* usb */ /* usb */
struct usb_device *usbdev; struct usb_device *usbdev;
@ -663,9 +661,9 @@ static void mce_sync_in(struct mceusb_dev *ir, unsigned char *data, int size)
} }
/* Send data out the IR blaster port(s) */ /* 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 i, ret = 0;
int count, cmdcount = 0; int count, cmdcount = 0;
unsigned char *cmdbuf; /* MCE command buffer */ unsigned char *cmdbuf; /* MCE command buffer */
@ -749,9 +747,9 @@ out:
} }
/* Sets active IR outputs -- mce devices typically have two */ /* 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) if (ir->flags.tx_mask_normal)
ir->tx_mask = mask; ir->tx_mask = mask;
@ -763,9 +761,9 @@ static int mceusb_set_tx_mask(void *priv, u32 mask)
} }
/* Sets the send carrier frequency and mode */ /* 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 clk = 10000000;
int prescaler = 0, divisor = 0; int prescaler = 0, divisor = 0;
unsigned char cmdbuf[4] = { MCE_COMMAND_HEADER, unsigned char cmdbuf[4] = { MCE_COMMAND_HEADER,
@ -819,7 +817,7 @@ static void mceusb_handle_command(struct mceusb_dev *ir, int index)
switch (ir->buf_in[index]) { switch (ir->buf_in[index]) {
/* 2-byte return value commands */ /* 2-byte return value commands */
case MCE_CMD_S_TIMEOUT: 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; break;
/* 1-byte return value commands */ /* 1-byte return value commands */
@ -866,7 +864,7 @@ static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len)
rawir.pulse ? "pulse" : "space", rawir.pulse ? "pulse" : "space",
rawir.duration); rawir.duration);
ir_raw_event_store_with_filter(ir->idev, &rawir); ir_raw_event_store_with_filter(ir->rc, &rawir);
break; break;
case CMD_DATA: case CMD_DATA:
ir->rem--; ir->rem--;
@ -893,7 +891,7 @@ static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len)
ir->parser_state = CMD_HEADER; ir->parser_state = CMD_HEADER;
} }
dev_dbg(ir->dev, "processed IR data, calling ir_raw_event_handle\n"); 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) static void mceusb_dev_recv(struct urb *urb, struct pt_regs *regs)
@ -1035,72 +1033,54 @@ static void mceusb_get_parameters(struct mceusb_dev *ir)
mce_sync_in(ir, NULL, maxp); 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; struct device *dev = ir->dev;
const char *rc_map = RC_MAP_RC6_MCE; struct rc_dev *rc;
const char *name = "Media Center Ed. eHome Infrared Remote Transceiver"; int ret;
int ret = -ENODEV;
idev = input_allocate_device(); rc = rc_allocate_device();
if (!idev) { if (!rc) {
dev_err(dev, "remote input dev allocation failed\n"); dev_err(dev, "remote dev allocation failed\n");
goto idev_alloc_failed; goto out;
} }
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;
}
if (mceusb_model[ir->model].name)
name = mceusb_model[ir->model].name;
snprintf(ir->name, sizeof(ir->name), "%s (%04x:%04x)", 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.idVendor),
le16_to_cpu(ir->usbdev->descriptor.idProduct)); le16_to_cpu(ir->usbdev->descriptor.idProduct));
idev->name = ir->name;
usb_make_path(ir->usbdev, ir->phys, sizeof(ir->phys)); usb_make_path(ir->usbdev, ir->phys, sizeof(ir->phys));
strlcat(ir->phys, "/input0", sizeof(ir->phys));
idev->phys = ir->phys;
props->priv = ir; rc->input_name = ir->name;
props->driver_type = RC_DRIVER_IR_RAW; rc->input_phys = ir->phys;
props->allowed_protos = IR_TYPE_ALL; usb_to_input_id(ir->usbdev, &rc->input_id);
props->timeout = MS_TO_NS(1000); 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) { if (!ir->flags.no_tx) {
props->s_tx_mask = mceusb_set_tx_mask; rc->s_tx_mask = mceusb_set_tx_mask;
props->s_tx_carrier = mceusb_set_tx_carrier; rc->s_tx_carrier = mceusb_set_tx_carrier;
props->tx_ir = mceusb_tx_ir; 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; ret = rc_register_device(rc);
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);
if (ret < 0) { if (ret < 0) {
dev_err(dev, "remote input device register failed\n"); dev_err(dev, "remote dev registration failed\n");
goto irdev_failed; goto out;
} }
return idev; return rc;
irdev_failed: out:
kfree(props); rc_free_device(rc);
props_alloc_failed:
input_free_device(idev);
idev_alloc_failed:
return NULL; return NULL;
} }
@ -1212,9 +1192,9 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf,
snprintf(name + strlen(name), sizeof(name) - strlen(name), snprintf(name + strlen(name), sizeof(name) - strlen(name),
" %s", buf); " %s", buf);
ir->idev = mceusb_init_input_dev(ir); ir->rc = mceusb_init_rc_dev(ir);
if (!ir->idev) if (!ir->rc)
goto input_dev_fail; goto rc_dev_fail;
/* flush buffers on the device */ /* flush buffers on the device */
mce_sync_in(ir, NULL, maxp); mce_sync_in(ir, NULL, maxp);
@ -1235,7 +1215,7 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf,
mceusb_get_parameters(ir); mceusb_get_parameters(ir);
if (!ir->flags.no_tx) 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); usb_set_intfdata(intf, ir);
@ -1245,7 +1225,7 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf,
return 0; return 0;
/* Error-handling path */ /* Error-handling path */
input_dev_fail: rc_dev_fail:
usb_free_urb(ir->urb_in); usb_free_urb(ir->urb_in);
urb_in_alloc_fail: urb_in_alloc_fail:
usb_free_coherent(dev, maxp, ir->buf_in, ir->dma_in); usb_free_coherent(dev, maxp, ir->buf_in, ir->dma_in);
@ -1269,7 +1249,7 @@ static void __devexit mceusb_dev_disconnect(struct usb_interface *intf)
return; return;
ir->usbdev = NULL; ir->usbdev = NULL;
ir_input_unregister(ir->idev); rc_unregister_device(ir->rc);
usb_kill_urb(ir->urb_in); usb_kill_urb(ir->urb_in);
usb_free_urb(ir->urb_in); usb_free_urb(ir->urb_in);
usb_free_coherent(dev, ir->len_in, ir->buf_in, ir->dma_in); usb_free_coherent(dev, ir->len_in, ir->buf_in, ir->dma_in);

View File

@ -32,7 +32,6 @@
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/input.h>
#include <media/ir-core.h> #include <media/ir-core.h>
#include <linux/pci_ids.h> #include <linux/pci_ids.h>
@ -476,9 +475,9 @@ static u32 nvt_rx_carrier_detect(struct nvt_dev *nvt)
* always set CP as 0x81 * always set CP as 0x81
* set CC by SPEC, CC = 3MHz/carrier - 1 * 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; u16 val;
nvt_cir_reg_write(nvt, 1, CIR_CP); nvt_cir_reg_write(nvt, 1, CIR_CP);
@ -509,9 +508,9 @@ static int nvt_set_tx_carrier(void *data, u32 carrier)
* number may larger than TXFCONT (0xff). So in interrupt_handler, it has to * number may larger than TXFCONT (0xff). So in interrupt_handler, it has to
* set TXFCONT as 0xff, until buf_count less than 0xff. * 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; unsigned long flags;
size_t cur_count; size_t cur_count;
unsigned int i; unsigned int i;
@ -948,9 +947,9 @@ static void nvt_disable_cir(struct nvt_dev *nvt)
nvt_efm_disable(nvt); 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; unsigned long flags;
spin_lock_irqsave(&nvt->nvt_lock, flags); spin_lock_irqsave(&nvt->nvt_lock, flags);
@ -961,9 +960,9 @@ static int nvt_open(void *data)
return 0; 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; unsigned long flags;
spin_lock_irqsave(&nvt->nvt_lock, flags); spin_lock_irqsave(&nvt->nvt_lock, flags);
@ -975,21 +974,16 @@ static void nvt_close(void *data)
/* Allocate memory, probe hardware, and initialize everything */ /* Allocate memory, probe hardware, and initialize everything */
static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id) static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id)
{ {
struct nvt_dev *nvt = NULL; struct nvt_dev *nvt;
struct input_dev *rdev = NULL; struct rc_dev *rdev;
struct ir_dev_props *props = NULL;
int ret = -ENOMEM; int ret = -ENOMEM;
nvt = kzalloc(sizeof(struct nvt_dev), GFP_KERNEL); nvt = kzalloc(sizeof(struct nvt_dev), GFP_KERNEL);
if (!nvt) if (!nvt)
return ret; return ret;
props = kzalloc(sizeof(struct ir_dev_props), GFP_KERNEL);
if (!props)
goto failure;
/* input device for IR remote (and tx) */ /* input device for IR remote (and tx) */
rdev = input_allocate_device(); rdev = rc_allocate_device();
if (!rdev) if (!rdev)
goto failure; goto failure;
@ -1063,41 +1057,38 @@ static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id)
nvt_cir_regs_init(nvt); nvt_cir_regs_init(nvt);
nvt_cir_wake_regs_init(nvt); nvt_cir_wake_regs_init(nvt);
/* Set up ir-core props */ /* Set up the rc device */
props->priv = nvt; rdev->priv = nvt;
props->driver_type = RC_DRIVER_IR_RAW; rdev->driver_type = RC_DRIVER_IR_RAW;
props->allowed_protos = IR_TYPE_ALL; rdev->allowed_protos = IR_TYPE_ALL;
props->open = nvt_open; rdev->open = nvt_open;
props->close = nvt_close; 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 #if 0
props->min_timeout = XYZ; rdev->min_timeout = XYZ;
props->max_timeout = XYZ; rdev->max_timeout = XYZ;
props->timeout = XYZ; rdev->timeout = XYZ;
/* rx resolution is hardwired to 50us atm, 1, 25, 100 also possible */ /* rx resolution is hardwired to 50us atm, 1, 25, 100 also possible */
props->rx_resolution = XYZ; rdev->rx_resolution = XYZ;
/* tx bits */ /* tx bits */
props->tx_resolution = XYZ; rdev->tx_resolution = XYZ;
#endif #endif
props->tx_ir = nvt_tx_ir;
props->s_tx_carrier = nvt_set_tx_carrier;
rdev->name = "Nuvoton w836x7hg Infrared Remote Transceiver"; ret = rc_register_device(rdev);
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);
if (ret) if (ret)
goto failure; 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"); nvt_pr(KERN_NOTICE, "driver has been successfully loaded\n");
if (debug) { if (debug) {
cir_dump_regs(nvt); cir_dump_regs(nvt);
@ -1117,8 +1108,7 @@ failure:
if (nvt->cir_wake_addr) if (nvt->cir_wake_addr)
release_region(nvt->cir_wake_addr, CIR_IOREG_LENGTH); release_region(nvt->cir_wake_addr, CIR_IOREG_LENGTH);
input_free_device(rdev); rc_free_device(rdev);
kfree(props);
kfree(nvt); kfree(nvt);
return ret; return ret;
@ -1143,9 +1133,8 @@ static void __devexit nvt_remove(struct pnp_dev *pdev)
release_region(nvt->cir_addr, CIR_IOREG_LENGTH); release_region(nvt->cir_addr, CIR_IOREG_LENGTH);
release_region(nvt->cir_wake_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); kfree(nvt);
} }

View File

@ -66,8 +66,7 @@ static int debug;
struct nvt_dev { struct nvt_dev {
struct pnp_dev *pdev; struct pnp_dev *pdev;
struct input_dev *rdev; struct rc_dev *rdev;
struct ir_dev_props *props;
struct ir_raw_event rawir; struct ir_raw_event rawir;
spinlock_t nvt_lock; spinlock_t nvt_lock;

View File

@ -24,11 +24,11 @@ struct ir_raw_handler {
struct list_head list; struct list_head list;
u64 protocols; /* which are handled by this handler */ 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 */ /* These two should only be used by the lirc decoder */
int (*raw_register)(struct input_dev *input_dev); int (*raw_register)(struct rc_dev *dev);
int (*raw_unregister)(struct input_dev *input_dev); int (*raw_unregister)(struct rc_dev *dev);
}; };
struct ir_raw_event_ctrl { struct ir_raw_event_ctrl {
@ -38,7 +38,7 @@ struct ir_raw_event_ctrl {
struct kfifo kfifo; /* fifo for the pulse/space durations */ struct kfifo kfifo; /* fifo for the pulse/space durations */
ktime_t last_event; /* when last event occurred */ ktime_t last_event; /* when last event occurred */
enum raw_event_type last_type; /* last event type */ 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 */ u64 enabled_protocols; /* enabled raw protocol decoders */
/* raw decoder state follows */ /* raw decoder state follows */
@ -85,7 +85,7 @@ struct ir_raw_event_ctrl {
unsigned wanted_bits; unsigned wanted_bits;
} rc5_sz; } rc5_sz;
struct lirc_codec { struct lirc_codec {
struct ir_input_dev *ir_dev; struct rc_dev *dev;
struct lirc_driver *drv; struct lirc_driver *drv;
int carrier_low; int carrier_low;
@ -131,11 +131,11 @@ static inline bool is_timing_event(struct ir_raw_event ev)
#define TO_STR(is_pulse) ((is_pulse) ? "pulse" : "space") #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); u64 ir_raw_get_allowed_protocols(void);
int ir_raw_event_register(struct input_dev *input_dev); int ir_raw_event_register(struct rc_dev *dev);
void ir_raw_event_unregister(struct input_dev *input_dev); void ir_raw_event_unregister(struct rc_dev *dev);
int ir_raw_handler_register(struct ir_raw_handler *ir_raw_handler); 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_handler_unregister(struct ir_raw_handler *ir_raw_handler);
void ir_raw_init(void); void ir_raw_init(void);

File diff suppressed because it is too large Load Diff

View File

@ -64,7 +64,7 @@ static int ir_raw_event_thread(void *data)
mutex_lock(&ir_raw_handler_lock); mutex_lock(&ir_raw_handler_lock);
list_for_each_entry(handler, &ir_raw_handler_list, list) 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; raw->prev_ev = ev;
mutex_unlock(&ir_raw_handler_lock); mutex_unlock(&ir_raw_handler_lock);
} }
@ -74,7 +74,7 @@ static int ir_raw_event_thread(void *data)
/** /**
* ir_raw_event_store() - pass a pulse/space duration to the raw ir decoders * 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 * @ev: the struct ir_raw_event descriptor of the pulse/space
* *
* This routine (which may be called from an interrupt context) stores a * This routine (which may be called from an interrupt context) stores a
@ -82,17 +82,15 @@ static int ir_raw_event_thread(void *data)
* signalled as positive values and spaces as negative values. A zero value * signalled as positive values and spaces as negative values. A zero value
* will reset the decoding state machines. * 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 (!dev->raw)
if (!ir->raw)
return -EINVAL; return -EINVAL;
IR_dprintk(2, "sample: (%05dus %s)\n", 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 -ENOMEM;
return 0; return 0;
@ -101,7 +99,7 @@ EXPORT_SYMBOL_GPL(ir_raw_event_store);
/** /**
* ir_raw_event_store_edge() - notify raw ir decoders of the start of a pulse/space * 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 * @type: the type of the event that has occurred
* *
* This routine (which may be called from an interrupt context) is used to * This routine (which may be called from an interrupt context) is used to
@ -110,50 +108,49 @@ EXPORT_SYMBOL_GPL(ir_raw_event_store);
* hardware which does not provide durations directly but only interrupts * hardware which does not provide durations directly but only interrupts
* (or similar events) on state change. * (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; ktime_t now;
s64 delta; /* ns */ s64 delta; /* ns */
struct ir_raw_event ev; struct ir_raw_event ev;
int rc = 0; int rc = 0;
if (!ir->raw) if (!dev->raw)
return -EINVAL; return -EINVAL;
now = ktime_get(); 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 /* Check for a long duration since last event or if we're
* being called for the first time, note that delta can't * being called for the first time, note that delta can't
* possibly be negative. * possibly be negative.
*/ */
ev.duration = 0; 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; type |= IR_START_EVENT;
else else
ev.duration = delta; ev.duration = delta;
if (type & IR_START_EVENT) if (type & IR_START_EVENT)
ir_raw_event_reset(input_dev); ir_raw_event_reset(dev);
else if (ir->raw->last_type & IR_SPACE) { else if (dev->raw->last_type & IR_SPACE) {
ev.pulse = false; ev.pulse = false;
rc = ir_raw_event_store(input_dev, &ev); rc = ir_raw_event_store(dev, &ev);
} else if (ir->raw->last_type & IR_PULSE) { } else if (dev->raw->last_type & IR_PULSE) {
ev.pulse = true; ev.pulse = true;
rc = ir_raw_event_store(input_dev, &ev); rc = ir_raw_event_store(dev, &ev);
} else } else
return 0; return 0;
ir->raw->last_event = now; dev->raw->last_event = now;
ir->raw->last_type = type; dev->raw->last_type = type;
return rc; return rc;
} }
EXPORT_SYMBOL_GPL(ir_raw_event_store_edge); EXPORT_SYMBOL_GPL(ir_raw_event_store_edge);
/** /**
* ir_raw_event_store_with_filter() - pass next pulse/space to decoders with some processing * 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 * @type: the type of the event that has occurred
* *
* This routine (which may be called from an interrupt context) works * This routine (which may be called from an interrupt context) works
@ -161,84 +158,76 @@ EXPORT_SYMBOL_GPL(ir_raw_event_store_edge);
* This routine is intended for devices with limited internal buffer * This routine is intended for devices with limited internal buffer
* It automerges samples of same type, and handles timeouts * It automerges samples of same type, and handles timeouts
*/ */
int ir_raw_event_store_with_filter(struct input_dev *input_dev, int ir_raw_event_store_with_filter(struct rc_dev *dev, struct ir_raw_event *ev)
struct ir_raw_event *ev)
{ {
struct ir_input_dev *ir = input_get_drvdata(input_dev); if (!dev->raw)
struct ir_raw_event_ctrl *raw = ir->raw;
if (!raw || !ir->props)
return -EINVAL; return -EINVAL;
/* Ignore spaces in idle mode */ /* Ignore spaces in idle mode */
if (ir->idle && !ev->pulse) if (dev->idle && !ev->pulse)
return 0; return 0;
else if (ir->idle) else if (dev->idle)
ir_raw_event_set_idle(input_dev, false); ir_raw_event_set_idle(dev, false);
if (!raw->this_ev.duration) { if (!dev->raw->this_ev.duration)
raw->this_ev = *ev; dev->raw->this_ev = *ev;
} else if (ev->pulse == raw->this_ev.pulse) { else if (ev->pulse == dev->raw->this_ev.pulse)
raw->this_ev.duration += ev->duration; dev->raw->this_ev.duration += ev->duration;
} else { else {
ir_raw_event_store(input_dev, &raw->this_ev); ir_raw_event_store(dev, &dev->raw->this_ev);
raw->this_ev = *ev; dev->raw->this_ev = *ev;
} }
/* Enter idle mode if nessesary */ /* Enter idle mode if nessesary */
if (!ev->pulse && ir->props->timeout && if (!ev->pulse && dev->timeout &&
raw->this_ev.duration >= ir->props->timeout) { dev->raw->this_ev.duration >= dev->timeout)
ir_raw_event_set_idle(input_dev, true); ir_raw_event_set_idle(dev, true);
}
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(ir_raw_event_store_with_filter); EXPORT_SYMBOL_GPL(ir_raw_event_store_with_filter);
/** /**
* ir_raw_event_set_idle() - hint the ir core if device is receiving * ir_raw_event_set_idle() - provide hint to rc-core when the device is idle or not
* IR data or not * @dev: the struct rc_dev device descriptor
* @input_dev: the struct input_dev device descriptor * @idle: whether the device is idle or not
* @idle: the hint value
*/ */
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); if (!dev->raw)
struct ir_raw_event_ctrl *raw = ir->raw;
if (!ir->props || !ir->raw)
return; return;
IR_dprintk(2, "%s idle mode\n", idle ? "enter" : "leave"); IR_dprintk(2, "%s idle mode\n", idle ? "enter" : "leave");
if (idle) { if (idle) {
raw->this_ev.timeout = true; dev->raw->this_ev.timeout = true;
ir_raw_event_store(input_dev, &raw->this_ev); ir_raw_event_store(dev, &dev->raw->this_ev);
init_ir_raw_event(&raw->this_ev); init_ir_raw_event(&dev->raw->this_ev);
} }
if (ir->props->s_idle) if (dev->s_idle)
ir->props->s_idle(ir->props->priv, idle); dev->s_idle(dev, idle);
ir->idle = idle;
dev->idle = idle;
} }
EXPORT_SYMBOL_GPL(ir_raw_event_set_idle); EXPORT_SYMBOL_GPL(ir_raw_event_set_idle);
/** /**
* ir_raw_event_handle() - schedules the decoding of stored ir data * 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; unsigned long flags;
if (!ir->raw) if (!dev->raw)
return; return;
spin_lock_irqsave(&ir->raw->lock, flags); spin_lock_irqsave(&dev->raw->lock, flags);
wake_up_process(ir->raw->thread); wake_up_process(dev->raw->thread);
spin_unlock_irqrestore(&ir->raw->lock, flags); spin_unlock_irqrestore(&dev->raw->lock, flags);
} }
EXPORT_SYMBOL_GPL(ir_raw_event_handle); EXPORT_SYMBOL_GPL(ir_raw_event_handle);
@ -256,69 +245,69 @@ ir_raw_get_allowed_protocols()
/* /*
* Used to (un)register raw event clients * 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; int rc;
struct ir_raw_handler *handler; struct ir_raw_handler *handler;
ir->raw = kzalloc(sizeof(*ir->raw), GFP_KERNEL); if (!dev)
if (!ir->raw) return -EINVAL;
dev->raw = kzalloc(sizeof(*dev->raw), GFP_KERNEL);
if (!dev->raw)
return -ENOMEM; return -ENOMEM;
ir->raw->input_dev = input_dev; dev->raw->dev = dev;
dev->raw->enabled_protocols = ~0;
ir->raw->enabled_protocols = ~0; rc = kfifo_alloc(&dev->raw->kfifo,
rc = kfifo_alloc(&ir->raw->kfifo, sizeof(s64) * MAX_IR_EVENT_SIZE, sizeof(struct ir_raw_event) * MAX_IR_EVENT_SIZE,
GFP_KERNEL); GFP_KERNEL);
if (rc < 0) { if (rc < 0)
kfree(ir->raw); goto out;
ir->raw = NULL;
return rc;
}
spin_lock_init(&ir->raw->lock); spin_lock_init(&dev->raw->lock);
ir->raw->thread = kthread_run(ir_raw_event_thread, ir->raw, dev->raw->thread = kthread_run(ir_raw_event_thread, dev->raw,
"rc%u", (unsigned int)ir->devno); "rc%ld", dev->devno);
if (IS_ERR(ir->raw->thread)) { if (IS_ERR(dev->raw->thread)) {
int ret = PTR_ERR(ir->raw->thread); rc = PTR_ERR(dev->raw->thread);
goto out;
kfree(ir->raw);
ir->raw = NULL;
return ret;
} }
mutex_lock(&ir_raw_handler_lock); 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) list_for_each_entry(handler, &ir_raw_handler_list, list)
if (handler->raw_register) if (handler->raw_register)
handler->raw_register(ir->raw->input_dev); handler->raw_register(dev);
mutex_unlock(&ir_raw_handler_lock); mutex_unlock(&ir_raw_handler_lock);
return 0; 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; struct ir_raw_handler *handler;
if (!ir->raw) if (!dev || !dev->raw)
return; return;
kthread_stop(ir->raw->thread); kthread_stop(dev->raw->thread);
mutex_lock(&ir_raw_handler_lock); 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) list_for_each_entry(handler, &ir_raw_handler_list, list)
if (handler->raw_unregister) if (handler->raw_unregister)
handler->raw_unregister(ir->raw->input_dev); handler->raw_unregister(dev);
mutex_unlock(&ir_raw_handler_lock); mutex_unlock(&ir_raw_handler_lock);
kfifo_free(&ir->raw->kfifo); kfifo_free(&dev->raw->kfifo);
kfree(ir->raw); kfree(dev->raw);
ir->raw = NULL; dev->raw = NULL;
} }
/* /*
@ -333,7 +322,7 @@ int ir_raw_handler_register(struct ir_raw_handler *ir_raw_handler)
list_add_tail(&ir_raw_handler->list, &ir_raw_handler_list); list_add_tail(&ir_raw_handler->list, &ir_raw_handler_list);
if (ir_raw_handler->raw_register) if (ir_raw_handler->raw_register)
list_for_each_entry(raw, &ir_raw_client_list, list) 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; available_protocols |= ir_raw_handler->protocols;
mutex_unlock(&ir_raw_handler_lock); mutex_unlock(&ir_raw_handler_lock);
@ -349,7 +338,7 @@ void ir_raw_handler_unregister(struct ir_raw_handler *ir_raw_handler)
list_del(&ir_raw_handler->list); list_del(&ir_raw_handler->list);
if (ir_raw_handler->raw_unregister) if (ir_raw_handler->raw_unregister)
list_for_each_entry(raw, &ir_raw_client_list, list) 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; available_protocols &= ~ir_raw_handler->protocols;
mutex_unlock(&ir_raw_handler_lock); mutex_unlock(&ir_raw_handler_lock);
} }

View File

@ -34,7 +34,6 @@
#include <linux/device.h> #include <linux/device.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/input.h>
#include <linux/usb.h> #include <linux/usb.h>
#include <linux/usb/input.h> #include <linux/usb/input.h>
#include <media/ir-core.h> #include <media/ir-core.h>
@ -86,13 +85,11 @@ enum StreamzapDecoderState {
/* structure to hold our device specific stuff */ /* structure to hold our device specific stuff */
struct streamzap_ir { struct streamzap_ir {
/* ir-core */ /* ir-core */
struct ir_dev_props *props; struct rc_dev *rdev;
/* core device info */ /* core device info */
struct device *dev; struct device *dev;
struct input_dev *idev;
/* usb */ /* usb */
struct usb_device *usbdev; struct usb_device *usbdev;
@ -143,7 +140,7 @@ static void sz_push(struct streamzap_ir *sz, struct ir_raw_event rawir)
{ {
dev_dbg(sz->dev, "Storing %s with duration %u us\n", dev_dbg(sz->dev, "Storing %s with duration %u us\n",
(rawir.pulse ? "pulse" : "space"), rawir.duration); (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, static void sz_push_full_pulse(struct streamzap_ir *sz,
@ -271,11 +268,11 @@ static void streamzap_callback(struct urb *urb)
DEFINE_IR_RAW_EVENT(rawir); DEFINE_IR_RAW_EVENT(rawir);
rawir.pulse = false; rawir.pulse = false;
rawir.duration = sz->props->timeout; rawir.duration = sz->rdev->timeout;
sz->idle = true; sz->idle = true;
if (sz->timeout_enabled) if (sz->timeout_enabled)
sz_push(sz, rawir); sz_push(sz, rawir);
ir_raw_event_handle(sz->idev); ir_raw_event_handle(sz->rdev);
} else { } else {
sz_push_full_space(sz, sz->buf_in[i]); sz_push_full_space(sz, sz->buf_in[i]);
} }
@ -298,57 +295,43 @@ static void streamzap_callback(struct urb *urb)
return; 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 rc_dev *rdev;
struct ir_dev_props *props;
struct device *dev = sz->dev; struct device *dev = sz->dev;
int ret; int ret;
idev = input_allocate_device(); rdev = rc_allocate_device();
if (!idev) { if (!rdev) {
dev_err(dev, "remote input dev allocation failed\n"); dev_err(dev, "remote dev allocation failed\n");
goto idev_alloc_failed; goto out;
}
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;
} }
snprintf(sz->name, sizeof(sz->name), "Streamzap PC Remote Infrared " snprintf(sz->name, sizeof(sz->name), "Streamzap PC Remote Infrared "
"Receiver (%04x:%04x)", "Receiver (%04x:%04x)",
le16_to_cpu(sz->usbdev->descriptor.idVendor), le16_to_cpu(sz->usbdev->descriptor.idVendor),
le16_to_cpu(sz->usbdev->descriptor.idProduct)); le16_to_cpu(sz->usbdev->descriptor.idProduct));
idev->name = sz->name;
usb_make_path(sz->usbdev, sz->phys, sizeof(sz->phys)); usb_make_path(sz->usbdev, sz->phys, sizeof(sz->phys));
strlcat(sz->phys, "/input0", sizeof(sz->phys)); strlcat(sz->phys, "/input0", sizeof(sz->phys));
idev->phys = sz->phys;
props->priv = sz; rdev->input_name = sz->name;
props->driver_type = RC_DRIVER_IR_RAW; rdev->input_phys = sz->phys;
props->allowed_protos = IR_TYPE_ALL; 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;
sz->props = props; ret = rc_register_device(rdev);
usb_to_input_id(sz->usbdev, &idev->id);
idev->dev.parent = sz->dev;
ret = ir_input_register(idev, RC_MAP_STREAMZAP, props, DRIVER_NAME);
if (ret < 0) { if (ret < 0) {
dev_err(dev, "remote input device register failed\n"); dev_err(dev, "remote input device register failed\n");
goto irdev_failed; goto out;
} }
return idev; return rdev;
irdev_failed: out:
kfree(props); rc_free_device(rdev);
props_alloc_failed:
input_free_device(idev);
idev_alloc_failed:
return NULL; return NULL;
} }
@ -437,15 +420,15 @@ static int __devinit streamzap_probe(struct usb_interface *intf,
snprintf(name + strlen(name), sizeof(name) - strlen(name), snprintf(name + strlen(name), sizeof(name) - strlen(name),
" %s", buf); " %s", buf);
sz->idev = streamzap_init_input_dev(sz); sz->rdev = streamzap_init_rc_dev(sz);
if (!sz->idev) if (!sz->rdev)
goto input_dev_fail; goto rc_dev_fail;
sz->idle = true; sz->idle = true;
sz->decoder_state = PulseSpace; sz->decoder_state = PulseSpace;
/* FIXME: don't yet have a way to set this */ /* FIXME: don't yet have a way to set this */
sz->timeout_enabled = true; sz->timeout_enabled = true;
sz->props->timeout = (((SZ_TIMEOUT * SZ_RESOLUTION * 1000) & sz->rdev->timeout = (((SZ_TIMEOUT * SZ_RESOLUTION * 1000) &
IR_MAX_DURATION) | 0x03000000); IR_MAX_DURATION) | 0x03000000);
#if 0 #if 0
/* not yet supported, depends on patches from maxim */ /* not yet supported, depends on patches from maxim */
@ -476,7 +459,7 @@ static int __devinit streamzap_probe(struct usb_interface *intf,
return 0; return 0;
input_dev_fail: rc_dev_fail:
usb_free_urb(sz->urb_in); usb_free_urb(sz->urb_in);
free_buf_in: free_buf_in:
usb_free_coherent(usbdev, maxp, sz->buf_in, sz->dma_in); usb_free_coherent(usbdev, maxp, sz->buf_in, sz->dma_in);
@ -507,7 +490,7 @@ static void streamzap_disconnect(struct usb_interface *interface)
return; return;
sz->usbdev = NULL; sz->usbdev = NULL;
ir_input_unregister(sz->idev); rc_unregister_device(sz->rdev);
usb_kill_urb(sz->urb_in); usb_kill_urb(sz->urb_in);
usb_free_urb(sz->urb_in); usb_free_urb(sz->urb_in);
usb_free_coherent(usbdev, sz->buf_in_len, sz->buf_in, sz->dma_in); usb_free_coherent(usbdev, sz->buf_in_len, sz->buf_in, sz->dma_in);

View File

@ -31,10 +31,6 @@
static int ir_debug; static int ir_debug;
module_param(ir_debug, int, 0644); 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; static int ir_rc5_remote_gap = 885;
module_param(ir_rc5_remote_gap, int, 0644); module_param(ir_rc5_remote_gap, int, 0644);
@ -317,15 +313,15 @@ int bttv_input_init(struct bttv *btv)
{ {
struct card_ir *ir; struct card_ir *ir;
char *ir_codes = NULL; char *ir_codes = NULL;
struct input_dev *input_dev; struct rc_dev *rc;
int err = -ENOMEM; int err = -ENOMEM;
if (!btv->has_remote) if (!btv->has_remote)
return -ENODEV; return -ENODEV;
ir = kzalloc(sizeof(*ir),GFP_KERNEL); ir = kzalloc(sizeof(*ir),GFP_KERNEL);
input_dev = input_allocate_device(); rc = rc_allocate_device();
if (!ir || !input_dev) if (!ir || !rc)
goto err_out_free; goto err_out_free;
/* detect & configure */ /* detect & configure */
@ -431,44 +427,43 @@ int bttv_input_init(struct bttv *btv)
} }
/* init input device */ /* init input device */
ir->dev = input_dev; ir->dev = rc;
snprintf(ir->name, sizeof(ir->name), "bttv IR (card=%d)", snprintf(ir->name, sizeof(ir->name), "bttv IR (card=%d)",
btv->c.type); btv->c.type);
snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0",
pci_name(btv->c.pci)); pci_name(btv->c.pci));
input_dev->name = ir->name; rc->input_name = ir->name;
input_dev->phys = ir->phys; rc->input_phys = ir->phys;
input_dev->id.bustype = BUS_PCI; rc->input_id.bustype = BUS_PCI;
input_dev->id.version = 1; rc->input_id.version = 1;
if (btv->c.pci->subsystem_vendor) { if (btv->c.pci->subsystem_vendor) {
input_dev->id.vendor = btv->c.pci->subsystem_vendor; rc->input_id.vendor = btv->c.pci->subsystem_vendor;
input_dev->id.product = btv->c.pci->subsystem_device; rc->input_id.product = btv->c.pci->subsystem_device;
} else { } else {
input_dev->id.vendor = btv->c.pci->vendor; rc->input_id.vendor = btv->c.pci->vendor;
input_dev->id.product = btv->c.pci->device; 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; btv->remote = ir;
bttv_ir_start(btv, ir); bttv_ir_start(btv, ir);
/* all done */ /* all done */
err = ir_input_register(btv->remote->dev, ir_codes, NULL, MODULE_NAME); err = rc_register_device(rc);
if (err) if (err)
goto err_out_stop; 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; return 0;
err_out_stop: err_out_stop:
bttv_ir_stop(btv); bttv_ir_stop(btv);
btv->remote = NULL; btv->remote = NULL;
err_out_free: err_out_free:
rc_free_device(rc);
kfree(ir); kfree(ir);
return err; return err;
} }
@ -479,7 +474,7 @@ void bttv_input_fini(struct bttv *btv)
return; return;
bttv_ir_stop(btv); bttv_ir_stop(btv);
ir_input_unregister(btv->remote->dev); rc_unregister_device(btv->remote->dev);
kfree(btv->remote); kfree(btv->remote);
btv->remote = NULL; btv->remote = NULL;
} }

View File

@ -607,7 +607,15 @@ struct cx231xx_ir_t {
char name[40]; char name[40];
char phys[32]; 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; struct ir_dev_props props;
#endif
/* I2C keyboard data */ /* I2C keyboard data */
struct IR_i2c_init_data init_data; struct IR_i2c_init_data init_data;

View File

@ -35,7 +35,6 @@
* 02110-1301, USA. * 02110-1301, USA.
*/ */
#include <linux/input.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <media/ir-core.h> #include <media/ir-core.h>
#include <media/v4l2-subdev.h> #include <media/v4l2-subdev.h>
@ -62,16 +61,16 @@ static void cx23885_input_process_measurements(struct cx23885_dev *dev,
count = num / sizeof(struct ir_raw_event); count = num / sizeof(struct ir_raw_event);
for (i = 0; i < count; i++) { 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]); &ir_core_event[i]);
handle = true; handle = true;
} }
} while (num != 0); } while (num != 0);
if (overrun) if (overrun)
ir_raw_event_reset(kernel_ir->inp_dev); ir_raw_event_reset(kernel_ir->rc);
else if (handle) 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) void cx23885_input_rx_work_handler(struct cx23885_dev *dev, u32 events)
@ -197,9 +196,9 @@ static int cx23885_input_ir_start(struct cx23885_dev *dev)
return 0; 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) if (kernel_ir->cx == NULL)
return -ENODEV; return -ENODEV;
@ -234,9 +233,9 @@ static void cx23885_input_ir_stop(struct cx23885_dev *dev)
flush_scheduled_work(); 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) if (kernel_ir->cx != NULL)
cx23885_input_ir_stop(kernel_ir->cx); cx23885_input_ir_stop(kernel_ir->cx);
@ -245,9 +244,7 @@ static void cx23885_input_ir_close(void *priv)
int cx23885_input_init(struct cx23885_dev *dev) int cx23885_input_init(struct cx23885_dev *dev)
{ {
struct cx23885_kernel_ir *kernel_ir; struct cx23885_kernel_ir *kernel_ir;
struct input_dev *inp_dev; struct rc_dev *rc;
struct ir_dev_props *props;
char *rc_map; char *rc_map;
enum rc_driver_type driver_type; enum rc_driver_type driver_type;
unsigned long allowed_protos; unsigned long allowed_protos;
@ -294,37 +291,36 @@ int cx23885_input_init(struct cx23885_dev *dev)
pci_name(dev->pci)); pci_name(dev->pci));
/* input device */ /* input device */
inp_dev = input_allocate_device(); rc = rc_allocate_device();
if (inp_dev == NULL) { if (!rc) {
ret = -ENOMEM; ret = -ENOMEM;
goto err_out_free; goto err_out_free;
} }
kernel_ir->inp_dev = inp_dev; kernel_ir->rc = rc;
inp_dev->name = kernel_ir->name; rc->input_name = kernel_ir->name;
inp_dev->phys = kernel_ir->phys; rc->input_phys = kernel_ir->phys;
inp_dev->id.bustype = BUS_PCI; rc->input_id.bustype = BUS_PCI;
inp_dev->id.version = 1; rc->input_id.version = 1;
if (dev->pci->subsystem_vendor) { if (dev->pci->subsystem_vendor) {
inp_dev->id.vendor = dev->pci->subsystem_vendor; rc->input_id.vendor = dev->pci->subsystem_vendor;
inp_dev->id.product = dev->pci->subsystem_device; rc->input_id.product = dev->pci->subsystem_device;
} else { } else {
inp_dev->id.vendor = dev->pci->vendor; rc->input_id.vendor = dev->pci->vendor;
inp_dev->id.product = dev->pci->device; rc->input_id.product = dev->pci->device;
} }
inp_dev->dev.parent = &dev->pci->dev; rc->dev.parent = &dev->pci->dev;
rc->driver_type = driver_type;
/* kernel ir device properties */ rc->allowed_protos = allowed_protos;
props = &kernel_ir->props; rc->priv = kernel_ir;
props->driver_type = driver_type; rc->open = cx23885_input_ir_open;
props->allowed_protos = allowed_protos; rc->close = cx23885_input_ir_close;
props->priv = kernel_ir; rc->map_name = rc_map;
props->open = cx23885_input_ir_open; rc->driver_name = MODULE_NAME;
props->close = cx23885_input_ir_close;
/* Go */ /* Go */
dev->kernel_ir = kernel_ir; dev->kernel_ir = kernel_ir;
ret = ir_input_register(inp_dev, rc_map, props, MODULE_NAME); ret = rc_register_device(rc);
if (ret) if (ret)
goto err_out_stop; goto err_out_stop;
@ -333,7 +329,7 @@ int cx23885_input_init(struct cx23885_dev *dev)
err_out_stop: err_out_stop:
cx23885_input_ir_stop(dev); cx23885_input_ir_stop(dev);
dev->kernel_ir = NULL; dev->kernel_ir = NULL;
/* TODO: double check clean-up of kernel_ir->inp_dev */ rc_free_device(rc);
err_out_free: err_out_free:
kfree(kernel_ir->phys); kfree(kernel_ir->phys);
kfree(kernel_ir->name); kfree(kernel_ir->name);
@ -348,7 +344,7 @@ void cx23885_input_fini(struct cx23885_dev *dev)
if (dev->kernel_ir == NULL) if (dev->kernel_ir == NULL)
return; 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->phys);
kfree(dev->kernel_ir->name); kfree(dev->kernel_ir->name);
kfree(dev->kernel_ir); kfree(dev->kernel_ir);

View File

@ -310,8 +310,7 @@ struct cx23885_kernel_ir {
char *name; char *name;
char *phys; char *phys;
struct input_dev *inp_dev; struct rc_dev *rc;
struct ir_dev_props props;
}; };
struct cx23885_dev { struct cx23885_dev {

View File

@ -24,7 +24,6 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/hrtimer.h> #include <linux/hrtimer.h>
#include <linux/input.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/module.h> #include <linux/module.h>
@ -38,8 +37,7 @@
struct cx88_IR { struct cx88_IR {
struct cx88_core *core; struct cx88_core *core;
struct input_dev *input; struct rc_dev *dev;
struct ir_dev_props props;
int users; int users;
@ -125,26 +123,26 @@ static void cx88_ir_handle_key(struct cx88_IR *ir)
data = (data << 4) | ((gpio_key & 0xf0) >> 4); data = (data << 4) | ((gpio_key & 0xf0) >> 4);
ir_keydown(ir->input, data, 0); ir_keydown(ir->dev, data, 0);
} else if (ir->mask_keydown) { } else if (ir->mask_keydown) {
/* bit set on keydown */ /* bit set on keydown */
if (gpio & ir->mask_keydown) if (gpio & ir->mask_keydown)
ir_keydown_notimeout(ir->input, data, 0); ir_keydown_notimeout(ir->dev, data, 0);
else else
ir_keyup(ir->input); ir_keyup(ir->dev);
} else if (ir->mask_keyup) { } else if (ir->mask_keyup) {
/* bit cleared on keydown */ /* bit cleared on keydown */
if (0 == (gpio & ir->mask_keyup)) if (0 == (gpio & ir->mask_keyup))
ir_keydown_notimeout(ir->input, data, 0); ir_keydown_notimeout(ir->dev, data, 0);
else else
ir_keyup(ir->input); ir_keyup(ir->dev);
} else { } else {
/* can't distinguish keydown/up :-/ */ /* can't distinguish keydown/up :-/ */
ir_keydown_notimeout(ir->input, data, 0); ir_keydown_notimeout(ir->dev, data, 0);
ir_keyup(ir->input); ir_keyup(ir->dev);
} }
} }
@ -219,17 +217,17 @@ void cx88_ir_stop(struct cx88_core *core)
__cx88_ir_stop(core); __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++; core->ir->users++;
return __cx88_ir_start(core); 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--; core->ir->users--;
if (!core->ir->users) if (!core->ir->users)
@ -241,7 +239,7 @@ static void cx88_ir_close(void *priv)
int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
{ {
struct cx88_IR *ir; struct cx88_IR *ir;
struct input_dev *input_dev; struct rc_dev *dev;
char *ir_codes = NULL; char *ir_codes = NULL;
u64 ir_type = IR_TYPE_OTHER; u64 ir_type = IR_TYPE_OTHER;
int err = -ENOMEM; int err = -ENOMEM;
@ -250,11 +248,11 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
*/ */
ir = kzalloc(sizeof(*ir), GFP_KERNEL); ir = kzalloc(sizeof(*ir), GFP_KERNEL);
input_dev = input_allocate_device(); dev = rc_allocate_device();
if (!ir || !input_dev) if (!ir || !dev)
goto err_out_free; goto err_out_free;
ir->input = input_dev; ir->dev = dev;
/* detect & configure */ /* detect & configure */
switch (core->boardnr) { switch (core->boardnr) {
@ -435,43 +433,45 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
snprintf(ir->name, sizeof(ir->name), "cx88 IR (%s)", core->board.name); snprintf(ir->name, sizeof(ir->name), "cx88 IR (%s)", core->board.name);
snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", pci_name(pci)); snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", pci_name(pci));
input_dev->name = ir->name; dev->input_name = ir->name;
input_dev->phys = ir->phys; dev->input_phys = ir->phys;
input_dev->id.bustype = BUS_PCI; dev->input_id.bustype = BUS_PCI;
input_dev->id.version = 1; dev->input_id.version = 1;
if (pci->subsystem_vendor) { if (pci->subsystem_vendor) {
input_dev->id.vendor = pci->subsystem_vendor; dev->input_id.vendor = pci->subsystem_vendor;
input_dev->id.product = pci->subsystem_device; dev->input_id.product = pci->subsystem_device;
} else { } else {
input_dev->id.vendor = pci->vendor; dev->input_id.vendor = pci->vendor;
input_dev->id.product = pci->device; dev->input_id.product = pci->device;
} }
input_dev->dev.parent = &pci->dev; dev->dev.parent = &pci->dev;
/* record handles to ourself */ 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) {
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; ir->core = core;
core->ir = ir; core->ir = ir;
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;
/* all done */ /* all done */
err = ir_input_register(ir->input, ir_codes, &ir->props, MODULE_NAME); err = rc_register_device(dev);
if (err) if (err)
goto err_out_free; goto err_out_free;
return 0; return 0;
err_out_free: err_out_free:
rc_free_device(dev);
core->ir = NULL; core->ir = NULL;
kfree(ir); kfree(ir);
return err; return err;
@ -486,7 +486,7 @@ int cx88_ir_fini(struct cx88_core *core)
return 0; return 0;
cx88_ir_stop(core); cx88_ir_stop(core);
ir_input_unregister(ir->input); rc_unregister_device(ir->dev);
kfree(ir); kfree(ir);
/* done */ /* done */
@ -502,7 +502,6 @@ void cx88_ir_irq(struct cx88_core *core)
u32 samples; u32 samples;
unsigned todo, bits; unsigned todo, bits;
struct ir_raw_event ev; struct ir_raw_event ev;
struct ir_input_dev *irdev;
if (!ir || !ir->sampling) if (!ir || !ir->sampling)
return; return;
@ -513,9 +512,8 @@ void cx88_ir_irq(struct cx88_core *core)
* represents a pulse. * represents a pulse.
*/ */
samples = cx_read(MO_SAMPLE_IO); samples = cx_read(MO_SAMPLE_IO);
irdev = input_get_drvdata(ir->input);
if (samples == 0xff && irdev->idle) if (samples == 0xff && ir->dev->idle)
return; return;
init_ir_raw_event(&ev); init_ir_raw_event(&ev);
@ -523,10 +521,10 @@ void cx88_ir_irq(struct cx88_core *core)
ev.pulse = samples & 0x80000000 ? false : true; ev.pulse = samples & 0x80000000 ? false : true;
bits = min(todo, 32U - fls(ev.pulse ? samples : ~samples)); bits = min(todo, 32U - fls(ev.pulse ? samples : ~samples));
ev.duration = (bits * NSEC_PER_SEC) / (1000 * ir_samplerate); 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; samples <<= bits;
} }
ir_raw_event_handle(ir->input); ir_raw_event_handle(ir->dev);
} }
void cx88_i2c_init_ir(struct cx88_core *core) void cx88_i2c_init_ir(struct cx88_core *core)

View File

@ -25,7 +25,6 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/input.h>
#include <linux/usb.h> #include <linux/usb.h>
#include <linux/slab.h> #include <linux/slab.h>
@ -64,7 +63,7 @@ struct em28xx_ir_poll_result {
struct em28xx_IR { struct em28xx_IR {
struct em28xx *dev; struct em28xx *dev;
struct input_dev *input; struct rc_dev *rc;
char name[32]; char name[32];
char phys[32]; char phys[32];
@ -75,10 +74,6 @@ struct em28xx_IR {
unsigned int last_readcount; unsigned int last_readcount;
int (*get_key)(struct em28xx_IR *, struct em28xx_ir_poll_result *); int (*get_key)(struct em28xx_IR *, struct em28xx_ir_poll_result *);
/* IR device properties */
struct ir_dev_props props;
}; };
/********************************************************** /**********************************************************
@ -302,12 +297,12 @@ static void em28xx_ir_handle_key(struct em28xx_IR *ir)
poll_result.toggle_bit, poll_result.read_count, poll_result.toggle_bit, poll_result.read_count,
poll_result.rc_address, poll_result.rc_data[0]); poll_result.rc_address, poll_result.rc_data[0]);
if (ir->full_code) if (ir->full_code)
ir_keydown(ir->input, ir_keydown(ir->rc,
poll_result.rc_address << 8 | poll_result.rc_address << 8 |
poll_result.rc_data[0], poll_result.rc_data[0],
poll_result.toggle_bit); poll_result.toggle_bit);
else else
ir_keydown(ir->input, ir_keydown(ir->rc,
poll_result.rc_data[0], poll_result.rc_data[0],
poll_result.toggle_bit); poll_result.toggle_bit);
@ -331,9 +326,9 @@ static void em28xx_ir_work(struct work_struct *work)
schedule_delayed_work(&ir->work, msecs_to_jiffies(ir->polling)); 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); INIT_DELAYED_WORK(&ir->work, em28xx_ir_work);
schedule_delayed_work(&ir->work, 0); schedule_delayed_work(&ir->work, 0);
@ -341,17 +336,17 @@ static int em28xx_ir_start(void *priv)
return 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); 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; int rc = 0;
struct em28xx_IR *ir = priv; struct em28xx_IR *ir = rc_dev->priv;
struct em28xx *dev = ir->dev; struct em28xx *dev = ir->dev;
u8 ir_config = EM2874_IR_RC5; u8 ir_config = EM2874_IR_RC5;
@ -391,7 +386,7 @@ int em28xx_ir_change_protocol(void *priv, u64 ir_type)
int em28xx_ir_init(struct em28xx *dev) int em28xx_ir_init(struct em28xx *dev)
{ {
struct em28xx_IR *ir; struct em28xx_IR *ir;
struct input_dev *input_dev; struct rc_dev *rc;
int err = -ENOMEM; int err = -ENOMEM;
if (dev->board.ir_codes == NULL) { if (dev->board.ir_codes == NULL) {
@ -400,28 +395,27 @@ int em28xx_ir_init(struct em28xx *dev)
} }
ir = kzalloc(sizeof(*ir), GFP_KERNEL); ir = kzalloc(sizeof(*ir), GFP_KERNEL);
input_dev = input_allocate_device(); rc = rc_allocate_device();
if (!ir || !input_dev) if (!ir || !rc)
goto err_out_free; goto err_out_free;
/* record handles to ourself */ /* record handles to ourself */
ir->dev = dev; ir->dev = dev;
dev->ir = ir; dev->ir = ir;
ir->rc = rc;
ir->input = input_dev;
/* /*
* em2874 supports more protocols. For now, let's just announce * em2874 supports more protocols. For now, let's just announce
* the two protocols that were already tested * the two protocols that were already tested
*/ */
ir->props.allowed_protos = IR_TYPE_RC5 | IR_TYPE_NEC; rc->allowed_protos = IR_TYPE_RC5 | IR_TYPE_NEC;
ir->props.priv = ir; rc->priv = ir;
ir->props.change_protocol = em28xx_ir_change_protocol; rc->change_protocol = em28xx_ir_change_protocol;
ir->props.open = em28xx_ir_start; rc->open = em28xx_ir_start;
ir->props.close = em28xx_ir_stop; rc->close = em28xx_ir_stop;
/* By default, keep protocol field untouched */ /* 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) if (err)
goto err_out_free; goto err_out_free;
@ -435,27 +429,27 @@ int em28xx_ir_init(struct em28xx *dev)
usb_make_path(dev->udev, ir->phys, sizeof(ir->phys)); usb_make_path(dev->udev, ir->phys, sizeof(ir->phys));
strlcat(ir->phys, "/input0", sizeof(ir->phys)); strlcat(ir->phys, "/input0", sizeof(ir->phys));
input_dev->name = ir->name; rc->input_name = ir->name;
input_dev->phys = ir->phys; rc->input_phys = ir->phys;
input_dev->id.bustype = BUS_USB; rc->input_id.bustype = BUS_USB;
input_dev->id.version = 1; rc->input_id.version = 1;
input_dev->id.vendor = le16_to_cpu(dev->udev->descriptor.idVendor); rc->input_id.vendor = le16_to_cpu(dev->udev->descriptor.idVendor);
input_dev->id.product = le16_to_cpu(dev->udev->descriptor.idProduct); rc->input_id.product = le16_to_cpu(dev->udev->descriptor.idProduct);
rc->dev.parent = &dev->udev->dev;
input_dev->dev.parent = &dev->udev->dev; rc->map_name = dev->board.ir_codes;
rc->driver_name = MODULE_NAME;
/* all done */ /* all done */
err = ir_input_register(ir->input, dev->board.ir_codes, err = rc_register_device(rc);
&ir->props, MODULE_NAME);
if (err) if (err)
goto err_out_stop; goto err_out_stop;
return 0; return 0;
err_out_stop: err_out_stop:
dev->ir = NULL; dev->ir = NULL;
err_out_free: err_out_free:
rc_free_device(rc);
kfree(ir); kfree(ir);
return err; return err;
} }
@ -468,8 +462,8 @@ int em28xx_ir_fini(struct em28xx *dev)
if (!ir) if (!ir)
return 0; return 0;
em28xx_ir_stop(ir); em28xx_ir_stop(ir->rc);
ir_input_unregister(ir->input); rc_unregister_device(ir->rc);
kfree(ir); kfree(ir);
/* done */ /* done */

View File

@ -252,7 +252,7 @@ static void ir_key_poll(struct IR_i2c *ir)
} }
if (rc) if (rc)
ir_keydown(ir->input, ir_key, 0); ir_keydown(ir->rc, ir_key, 0);
} }
static void ir_work(struct work_struct *work) static void ir_work(struct work_struct *work)
@ -271,20 +271,20 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
const char *name = NULL; const char *name = NULL;
u64 ir_type = IR_TYPE_UNKNOWN; u64 ir_type = IR_TYPE_UNKNOWN;
struct IR_i2c *ir; struct IR_i2c *ir;
struct input_dev *input_dev; struct rc_dev *rc;
struct i2c_adapter *adap = client->adapter; struct i2c_adapter *adap = client->adapter;
unsigned short addr = client->addr; unsigned short addr = client->addr;
int err; int err;
ir = kzalloc(sizeof(struct IR_i2c),GFP_KERNEL); ir = kzalloc(sizeof(struct IR_i2c),GFP_KERNEL);
input_dev = input_allocate_device(); rc = rc_allocate_device();
if (!ir || !input_dev) { if (!ir || !rc) {
err = -ENOMEM; err = -ENOMEM;
goto err_out_free; goto err_out_free;
} }
ir->c = client; ir->c = client;
ir->input = input_dev; ir->rc = rc;
ir->polling_interval = DEFAULT_POLLING_INTERVAL; ir->polling_interval = DEFAULT_POLLING_INTERVAL;
i2c_set_clientdata(client, ir); i2c_set_clientdata(client, ir);
@ -383,16 +383,18 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
dev_name(&client->dev)); dev_name(&client->dev));
/* init + register input device */ /* init + register input device */
input_dev->id.bustype = BUS_I2C; rc->input_id.bustype = BUS_I2C;
input_dev->name = ir->name; rc->input_name = ir->name;
input_dev->phys = ir->phys; 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) if (err)
goto err_out_free; goto err_out_free;
printk(MODULE_NAME ": %s detected at %s [%s]\n", 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 */ /* start polling via eventd */
INIT_DELAYED_WORK(&ir->work, ir_work); INIT_DELAYED_WORK(&ir->work, ir_work);
@ -401,6 +403,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
return 0; return 0;
err_out_free: err_out_free:
rc_free_device(rc);
kfree(ir); kfree(ir);
return err; return err;
} }
@ -413,7 +416,7 @@ static int ir_remove(struct i2c_client *client)
cancel_delayed_work_sync(&ir->work); cancel_delayed_work_sync(&ir->work);
/* unregister device */ /* unregister device */
ir_input_unregister(ir->input); rc_unregister_device(ir->rc);
/* free memory */ /* free memory */
kfree(ir); kfree(ir);

View File

@ -22,7 +22,6 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/input.h>
#include <linux/slab.h> #include <linux/slab.h>
#include "saa7134-reg.h" #include "saa7134-reg.h"
@ -45,14 +44,6 @@ MODULE_PARM_DESC(pinnacle_remote, "Specify Pinnacle PCTV remote: 0=coloured, 1=g
static int ir_rc5_remote_gap = 885; static int ir_rc5_remote_gap = 885;
module_param(ir_rc5_remote_gap, int, 0644); 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; static unsigned int disable_other_ir;
module_param(disable_other_ir, int, 0644); module_param(disable_other_ir, int, 0644);
MODULE_PARM_DESC(disable_other_ir, "disable full codes of " MODULE_PARM_DESC(disable_other_ir, "disable full codes of "
@ -523,17 +514,17 @@ void saa7134_ir_stop(struct saa7134_dev *dev)
__saa7134_ir_stop(dev); __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++; dev->remote->users++;
return __saa7134_ir_start(dev); 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--; dev->remote->users--;
if (!dev->remote->users) if (!dev->remote->users)
@ -541,9 +532,9 @@ static void saa7134_ir_close(void *priv)
} }
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; struct card_ir *ir = dev->remote;
u32 nec_gpio, rc5_gpio; u32 nec_gpio, rc5_gpio;
@ -577,7 +568,7 @@ static int saa7134_ir_change_protocol(void *priv, u64 ir_type)
int saa7134_input_init1(struct saa7134_dev *dev) int saa7134_input_init1(struct saa7134_dev *dev)
{ {
struct card_ir *ir; struct card_ir *ir;
struct input_dev *input_dev; struct rc_dev *rc;
char *ir_codes = NULL; char *ir_codes = NULL;
u32 mask_keycode = 0; u32 mask_keycode = 0;
u32 mask_keydown = 0; u32 mask_keydown = 0;
@ -822,13 +813,13 @@ int saa7134_input_init1(struct saa7134_dev *dev)
} }
ir = kzalloc(sizeof(*ir), GFP_KERNEL); ir = kzalloc(sizeof(*ir), GFP_KERNEL);
input_dev = input_allocate_device(); rc = rc_allocate_device();
if (!ir || !input_dev) { if (!ir || !rc) {
err = -ENOMEM; err = -ENOMEM;
goto err_out_free; goto err_out_free;
} }
ir->dev = input_dev; ir->dev = rc;
dev->remote = ir; dev->remote = ir;
ir->running = 0; ir->running = 0;
@ -848,43 +839,40 @@ int saa7134_input_init1(struct saa7134_dev *dev)
snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0",
pci_name(dev->pci)); pci_name(dev->pci));
rc->priv = dev;
ir->props.priv = dev; rc->open = saa7134_ir_open;
ir->props.open = saa7134_ir_open; rc->close = saa7134_ir_close;
ir->props.close = saa7134_ir_close;
if (raw_decode) if (raw_decode)
ir->props.driver_type = RC_DRIVER_IR_RAW; rc->driver_type = RC_DRIVER_IR_RAW;
if (!raw_decode && allow_protocol_change) { if (!raw_decode && allow_protocol_change) {
ir->props.allowed_protos = IR_TYPE_RC5 | IR_TYPE_NEC; rc->allowed_protos = IR_TYPE_RC5 | IR_TYPE_NEC;
ir->props.change_protocol = saa7134_ir_change_protocol; rc->change_protocol = saa7134_ir_change_protocol;
} }
input_dev->name = ir->name; rc->input_name = ir->name;
input_dev->phys = ir->phys; rc->input_phys = ir->phys;
input_dev->id.bustype = BUS_PCI; rc->input_id.bustype = BUS_PCI;
input_dev->id.version = 1; rc->input_id.version = 1;
if (dev->pci->subsystem_vendor) { if (dev->pci->subsystem_vendor) {
input_dev->id.vendor = dev->pci->subsystem_vendor; rc->input_id.vendor = dev->pci->subsystem_vendor;
input_dev->id.product = dev->pci->subsystem_device; rc->input_id.product = dev->pci->subsystem_device;
} else { } else {
input_dev->id.vendor = dev->pci->vendor; rc->input_id.vendor = dev->pci->vendor;
input_dev->id.product = dev->pci->device; 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) if (err)
goto err_out_free; 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; return 0;
err_out_free: err_out_free:
rc_free_device(rc);
dev->remote = NULL; dev->remote = NULL;
kfree(ir); kfree(ir);
return err; return err;
@ -896,7 +884,7 @@ void saa7134_input_fini(struct saa7134_dev *dev)
return; return;
saa7134_ir_stop(dev); saa7134_ir_stop(dev);
ir_input_unregister(dev->remote->dev); rc_unregister_device(dev->remote->dev);
kfree(dev->remote); kfree(dev->remote);
dev->remote = NULL; dev->remote = NULL;
} }

View File

@ -50,7 +50,7 @@ struct tm6000_ir_poll_result {
struct tm6000_IR { struct tm6000_IR {
struct tm6000_core *dev; struct tm6000_core *dev;
struct ir_input_dev *input; struct rc_dev *rc;
char name[32]; char name[32];
char phys[32]; char phys[32];
@ -66,7 +66,6 @@ struct tm6000_IR {
/* IR device properties */ /* IR device properties */
u64 ir_type; u64 ir_type;
struct ir_dev_props props;
}; };
@ -200,7 +199,7 @@ static void tm6000_ir_handle_key(struct tm6000_IR *ir)
dprintk("ir->get_key result data=%04x\n", poll_result.rc_data); dprintk("ir->get_key result data=%04x\n", poll_result.rc_data);
if (ir->key) { 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; ir->key = 0;
} }
return; return;
@ -214,9 +213,9 @@ static void tm6000_ir_work(struct work_struct *work)
schedule_delayed_work(&ir->work, msecs_to_jiffies(ir->polling)); 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); INIT_DELAYED_WORK(&ir->work, tm6000_ir_work);
schedule_delayed_work(&ir->work, 0); schedule_delayed_work(&ir->work, 0);
@ -224,16 +223,16 @@ static int tm6000_ir_start(void *priv)
return 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); 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; ir->get_key = default_polling_getkey;
@ -245,9 +244,9 @@ int tm6000_ir_change_protocol(void *priv, u64 ir_type)
int tm6000_ir_init(struct tm6000_core *dev) int tm6000_ir_init(struct tm6000_core *dev)
{ {
struct tm6000_IR *ir; struct tm6000_IR *ir;
struct ir_input_dev *ir_input_dev; struct rc_dev *rc;
int err = -ENOMEM; int err = -ENOMEM;
int pipe, size, rc; int pipe, size;
if (!enable_ir) if (!enable_ir)
return -ENODEV; return -ENODEV;
@ -259,24 +258,22 @@ int tm6000_ir_init(struct tm6000_core *dev)
return 0; return 0;
ir = kzalloc(sizeof(*ir), GFP_KERNEL); ir = kzalloc(sizeof(*ir), GFP_KERNEL);
ir_input_dev = kzalloc(sizeof(*ir_input_dev), GFP_KERNEL); rc = rc_allocate_device();
ir_input_dev->input_dev = input_allocate_device(); if (!ir | !rc)
if (!ir || !ir_input_dev || !ir_input_dev->input_dev) goto out;
goto err_out_free;
/* record handles to ourself */ /* record handles to ourself */
ir->dev = dev; ir->dev = dev;
dev->ir = ir; dev->ir = ir;
ir->rc = rc;
ir->input = ir_input_dev;
/* input einrichten */ /* input einrichten */
ir->props.allowed_protos = IR_TYPE_RC5 | IR_TYPE_NEC; rc->allowed_protos = IR_TYPE_RC5 | IR_TYPE_NEC;
ir->props.priv = ir; rc->priv = ir;
ir->props.change_protocol = tm6000_ir_change_protocol; rc->change_protocol = tm6000_ir_change_protocol;
ir->props.open = tm6000_ir_start; rc->open = tm6000_ir_start;
ir->props.close = tm6000_ir_stop; rc->close = tm6000_ir_stop;
ir->props.driver_type = RC_DRIVER_SCANCODE; rc->driver_type = RC_DRIVER_SCANCODE;
ir->polling = 50; ir->polling = 50;
@ -286,16 +283,17 @@ int tm6000_ir_init(struct tm6000_core *dev)
usb_make_path(dev->udev, ir->phys, sizeof(ir->phys)); usb_make_path(dev->udev, ir->phys, sizeof(ir->phys));
strlcat(ir->phys, "/input0", sizeof(ir->phys)); strlcat(ir->phys, "/input0", sizeof(ir->phys));
tm6000_ir_change_protocol(ir, IR_TYPE_UNKNOWN); tm6000_ir_change_protocol(rc, IR_TYPE_UNKNOWN);
ir_input_dev->input_dev->name = ir->name; rc->input_name = ir->name;
ir_input_dev->input_dev->phys = ir->phys; rc->input_phys = ir->phys;
ir_input_dev->input_dev->id.bustype = BUS_USB; rc->input_id.bustype = BUS_USB;
ir_input_dev->input_dev->id.version = 1; rc->input_id.version = 1;
ir_input_dev->input_dev->id.vendor = le16_to_cpu(dev->udev->descriptor.idVendor); rc->input_id.vendor = le16_to_cpu(dev->udev->descriptor.idVendor);
ir_input_dev->input_dev->id.product = le16_to_cpu(dev->udev->descriptor.idProduct); rc->input_id.product = le16_to_cpu(dev->udev->descriptor.idProduct);
rc->map_name = dev->ir_codes;
ir_input_dev->input_dev->dev.parent = &dev->udev->dev; rc->driver_name = "tm6000";
rc->dev.parent = &dev->udev->dev;
if (&dev->int_in) { if (&dev->int_in) {
dprintk("IR over int\n"); dprintk("IR over int\n");
@ -312,35 +310,32 @@ int tm6000_ir_init(struct tm6000_core *dev)
ir->int_urb->transfer_buffer = kzalloc(size, GFP_KERNEL); ir->int_urb->transfer_buffer = kzalloc(size, GFP_KERNEL);
if (ir->int_urb->transfer_buffer == NULL) { if (ir->int_urb->transfer_buffer == NULL) {
usb_free_urb(ir->int_urb); usb_free_urb(ir->int_urb);
goto err_out_stop; goto out;
} }
dprintk("int interval: %d\n", dev->int_in.endp->desc.bInterval); dprintk("int interval: %d\n", dev->int_in.endp->desc.bInterval);
usb_fill_int_urb(ir->int_urb, dev->udev, pipe, usb_fill_int_urb(ir->int_urb, dev->udev, pipe,
ir->int_urb->transfer_buffer, size, ir->int_urb->transfer_buffer, size,
tm6000_ir_urb_received, dev, tm6000_ir_urb_received, dev,
dev->int_in.endp->desc.bInterval); dev->int_in.endp->desc.bInterval);
rc = usb_submit_urb(ir->int_urb, GFP_KERNEL); err = usb_submit_urb(ir->int_urb, GFP_KERNEL);
if (rc) { if (err) {
kfree(ir->int_urb->transfer_buffer); kfree(ir->int_urb->transfer_buffer);
usb_free_urb(ir->int_urb); usb_free_urb(ir->int_urb);
err = rc; goto out;
goto err_out_stop;
} }
ir->urb_data = kzalloc(size, GFP_KERNEL); ir->urb_data = kzalloc(size, GFP_KERNEL);
} }
/* ir register */ /* ir register */
err = ir_input_register(ir->input->input_dev, dev->ir_codes, err = rc_register_device(rc);
&ir->props, "tm6000");
if (err) if (err)
goto err_out_stop; goto out;
return 0; return 0;
err_out_stop: out:
dev->ir = NULL; dev->ir = NULL;
err_out_free: rc_free_device(rc);
kfree(ir_input_dev);
kfree(ir); kfree(ir);
return err; return err;
} }
@ -354,7 +349,7 @@ int tm6000_ir_fini(struct tm6000_core *dev)
if (!ir) if (!ir)
return 0; return 0;
ir_input_unregister(ir->input->input_dev); rc_unregister_device(ir->rc);
if (ir->int_urb) { if (ir->int_urb) {
usb_kill_urb(ir->int_urb); usb_kill_urb(ir->int_urb);
@ -365,8 +360,6 @@ int tm6000_ir_fini(struct tm6000_core *dev)
ir->urb_data = NULL; ir->urb_data = NULL;
} }
kfree(ir->input);
ir->input = NULL;
kfree(ir); kfree(ir);
dev->ir = NULL; dev->ir = NULL;

View File

@ -36,12 +36,11 @@
/* this was saa7134_ir and bttv_ir, moved here for /* this was saa7134_ir and bttv_ir, moved here for
* rc5 decoding. */ * rc5 decoding. */
struct card_ir { struct card_ir {
struct input_dev *dev; struct rc_dev *dev;
char name[32]; char name[32];
char phys[32]; char phys[32];
int users; int users;
u32 running:1; u32 running:1;
struct ir_dev_props props;
/* Usual gpio signalling */ /* Usual gpio signalling */
u32 mask_keycode; u32 mask_keycode;

View File

@ -32,21 +32,38 @@ enum rc_driver_type {
}; };
/** /**
* struct ir_dev_props - Allow caller drivers to set special properties * struct rc_dev - represents a remote control device
* @driver_type: specifies if the driver or hardware have already a decoder, * @dev: driver model's view of this device
* or if it needs to use the IR raw event decoders to produce a scancode * @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 * @allowed_protos: bitmask with the supported IR_TYPE_* protocols
* @scanmask: some hardware decoders are not capable of providing the full * @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 * 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 * 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 * devices, a mask is provided to allow its usage. Drivers should generally
* leave this field in blank * 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 * @timeout: optional time after which device stops sending data
* @min_timeout: minimum timeout supported by device * @min_timeout: minimum timeout supported by device
* @max_timeout: maximum timeout supported by device * @max_timeout: maximum timeout supported by device
* @rx_resolution : resolution (in ns) of input sampler * @rx_resolution : resolution (in ns) of input sampler
* @tx_resolution: resolution (in ns) of output 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 * @change_protocol: allow changing the protocol used on hardware decoders
* @open: callback to allow drivers to enable polling/irq when IR input device * @open: callback to allow drivers to enable polling/irq when IR input device
* is opened. * is opened.
@ -57,55 +74,50 @@ enum rc_driver_type {
* @s_tx_duty_cycle: set transmit duty cycle (0% - 100%) * @s_tx_duty_cycle: set transmit duty cycle (0% - 100%)
* @s_rx_carrier: inform driver about carrier it is expected to handle * @s_rx_carrier: inform driver about carrier it is expected to handle
* @tx_ir: transmit IR * @tx_ir: transmit IR
* @s_idle: optional: enable/disable hardware idle mode, upon which, * @s_idle: enable/disable hardware idle mode, upon which,
device doesn't interrupt host until it sees IR pulses * device doesn't interrupt host until it sees IR pulses
* @s_learning_mode: enable wide band receiver used for learning * @s_learning_mode: enable wide band receiver used for learning
* @s_carrier_report: enable carrier reports * @s_carrier_report: enable carrier reports
*/ */
struct ir_dev_props { struct rc_dev {
enum rc_driver_type driver_type; struct device dev;
unsigned long allowed_protos; const char *input_name;
u32 scanmask; const char *input_phys;
struct input_id input_id;
u32 timeout; char *driver_name;
u32 min_timeout; const char *map_name;
u32 max_timeout; struct ir_scancode_table rc_tab;
unsigned long devno;
u32 rx_resolution; struct ir_raw_event_ctrl *raw;
u32 tx_resolution; struct input_dev *input_dev;
enum rc_driver_type driver_type;
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 */
bool idle; bool idle;
u64 allowed_protos;
/* key info - needed by IR keycode handlers */ u32 scanmask;
spinlock_t keylock; /* protects the below members */ void *priv;
bool keypressed; /* current state */ spinlock_t keylock;
unsigned long keyup_jiffies; /* when should the current keypress be released? */ bool keypressed;
struct timer_list timer_keyup; /* timer for releasing a keypress */ unsigned long keyup_jiffies;
u32 last_keycode; /* keycode of last command */ struct timer_list timer_keyup;
u32 last_scancode; /* scancode of last command */ u32 last_keycode;
u8 last_toggle; /* toggle of last command */ 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 { enum raw_event_type {
@ -115,52 +127,14 @@ enum raw_event_type {
IR_STOP_EVENT = (1 << 3), IR_STOP_EVENT = (1 << 3),
}; };
#define to_ir_input_dev(_attr) container_of(_attr, struct ir_input_dev, attr) #define to_rc_dev(d) container_of(d, struct rc_dev, dev)
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, void ir_repeat(struct rc_dev *dev);
const char *map_name, void ir_keydown(struct rc_dev *dev, int scancode, u8 toggle);
struct ir_dev_props *props, void ir_keydown_notimeout(struct rc_dev *dev, int scancode, u8 toggle);
const char *driver_name) { void ir_keyup(struct rc_dev *dev);
struct ir_scancode_table *ir_codes; u32 ir_g_keycode_from_table(struct rc_dev *dev, u32 scancode);
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);
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);
/* From ir-raw-event.c */ /* From ir-raw-event.c */
struct ir_raw_event { struct ir_raw_event {
@ -194,20 +168,25 @@ static inline void init_ir_raw_event(struct ir_raw_event *ev)
#define IR_MAX_DURATION 0xFFFFFFFF /* a bit more than 4 seconds */ #define IR_MAX_DURATION 0xFFFFFFFF /* a bit more than 4 seconds */
void ir_raw_event_handle(struct input_dev *input_dev); struct rc_dev *rc_allocate_device(void);
int ir_raw_event_store(struct input_dev *input_dev, struct ir_raw_event *ev); void rc_free_device(struct rc_dev *dev);
int ir_raw_event_store_edge(struct input_dev *input_dev, enum raw_event_type type); int rc_register_device(struct rc_dev *dev);
int ir_raw_event_store_with_filter(struct input_dev *input_dev, void rc_unregister_device(struct rc_dev *dev);
struct ir_raw_event *ev);
void ir_raw_event_set_idle(struct input_dev *input_dev, bool idle);
static inline void ir_raw_event_reset(struct input_dev *input_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 rc_dev *dev, bool idle);
static inline void ir_raw_event_reset(struct rc_dev *dev)
{ {
DEFINE_IR_RAW_EVENT(ev); DEFINE_IR_RAW_EVENT(ev);
ev.reset = true; ev.reset = true;
ir_raw_event_store(input_dev, &ev); ir_raw_event_store(dev, &ev);
ir_raw_event_handle(input_dev); ir_raw_event_handle(dev);
} }

View File

@ -9,9 +9,8 @@ struct IR_i2c;
struct IR_i2c { struct IR_i2c {
char *ir_codes; char *ir_codes;
struct i2c_client *c; struct i2c_client *c;
struct input_dev *input; struct rc_dev *rc;
/* Used to avoid fast repeating */ /* Used to avoid fast repeating */
unsigned char old; unsigned char old;