diff options
author | David Hardeman <david@hardeman.nu> | 2006-12-02 18:16:05 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2006-12-10 06:05:17 -0500 |
commit | 2520fffd8b7a312e77009414d3201c9751d6448c (patch) | |
tree | 72a997320430ce7ec75212af8e63fe4cff396812 | |
parent | ee579bc9332ef8a67e20f512e7bc91e3efb92225 (diff) |
V4L/DVB (4879): budget-ci IR: integrate with ir-common
This converts the budget-ci driver so that it uses ir-common for some of its
IR processing. In particular, the keymap for the Nova-T (sub 13c2:1011) is
switched to the Hauppauge grey/black keymap, of which the keys on the
supplied R808 remote control form a subset.
The old budget-ci keymap is moved to ir-keymaps.c and is used for other
remotes.
The debounce logic for buggy remotes (i.e. Zenith) is made conditional the
new debounce parameter and defaults to off (so that repeat keypresses aren't
ignored for all working remotes).
Some parts are based on Darren Salt's dvb-ir patchset.
Signed-off-by: David Hardeman <david@hardeman.nu>
Signed-off-by: Andrew de Quincey <adq_dvb@lidskialf.net>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
-rw-r--r-- | drivers/media/common/ir-keymaps.c | 55 | ||||
-rw-r--r-- | drivers/media/dvb/ttpci/Kconfig | 1 | ||||
-rw-r--r-- | drivers/media/dvb/ttpci/budget-ci.c | 138 | ||||
-rw-r--r-- | include/media/ir-common.h | 1 |
4 files changed, 134 insertions, 61 deletions
diff --git a/drivers/media/common/ir-keymaps.c b/drivers/media/common/ir-keymaps.c index db753443587a..f51e02fe3655 100644 --- a/drivers/media/common/ir-keymaps.c +++ b/drivers/media/common/ir-keymaps.c | |||
@@ -1552,3 +1552,58 @@ IR_KEYTAB_TYPE ir_codes_norwood[IR_KEYTAB_SIZE] = { | |||
1552 | }; | 1552 | }; |
1553 | 1553 | ||
1554 | EXPORT_SYMBOL_GPL(ir_codes_norwood); | 1554 | EXPORT_SYMBOL_GPL(ir_codes_norwood); |
1555 | |||
1556 | /* From reading the following remotes: | ||
1557 | * Zenith Universal 7 / TV Mode 807 / VCR Mode 837 | ||
1558 | * Hauppauge (from NOVA-CI-s box product) | ||
1559 | * This is a "middle of the road" approach, differences are noted | ||
1560 | */ | ||
1561 | IR_KEYTAB_TYPE ir_codes_budget_ci_old[IR_KEYTAB_SIZE] = { | ||
1562 | [ 0x00 ] = KEY_0, | ||
1563 | [ 0x01 ] = KEY_1, | ||
1564 | [ 0x02 ] = KEY_2, | ||
1565 | [ 0x03 ] = KEY_3, | ||
1566 | [ 0x04 ] = KEY_4, | ||
1567 | [ 0x05 ] = KEY_5, | ||
1568 | [ 0x06 ] = KEY_6, | ||
1569 | [ 0x07 ] = KEY_7, | ||
1570 | [ 0x08 ] = KEY_8, | ||
1571 | [ 0x09 ] = KEY_9, | ||
1572 | [ 0x0a ] = KEY_ENTER, | ||
1573 | [ 0x0b ] = KEY_RED, | ||
1574 | [ 0x0c ] = KEY_POWER, /* RADIO on Hauppauge */ | ||
1575 | [ 0x0d ] = KEY_MUTE, | ||
1576 | [ 0x0f ] = KEY_A, /* TV on Hauppauge */ | ||
1577 | [ 0x10 ] = KEY_VOLUMEUP, | ||
1578 | [ 0x11 ] = KEY_VOLUMEDOWN, | ||
1579 | [ 0x14 ] = KEY_B, | ||
1580 | [ 0x1c ] = KEY_UP, | ||
1581 | [ 0x1d ] = KEY_DOWN, | ||
1582 | [ 0x1e ] = KEY_OPTION, /* RESERVED on Hauppauge */ | ||
1583 | [ 0x1f ] = KEY_BREAK, | ||
1584 | [ 0x20 ] = KEY_CHANNELUP, | ||
1585 | [ 0x21 ] = KEY_CHANNELDOWN, | ||
1586 | [ 0x22 ] = KEY_PREVIOUS, /* Prev. Ch on Zenith, SOURCE on Hauppauge */ | ||
1587 | [ 0x24 ] = KEY_RESTART, | ||
1588 | [ 0x25 ] = KEY_OK, | ||
1589 | [ 0x26 ] = KEY_CYCLEWINDOWS, /* MINIMIZE on Hauppauge */ | ||
1590 | [ 0x28 ] = KEY_ENTER, /* VCR mode on Zenith */ | ||
1591 | [ 0x29 ] = KEY_PAUSE, | ||
1592 | [ 0x2b ] = KEY_RIGHT, | ||
1593 | [ 0x2c ] = KEY_LEFT, | ||
1594 | [ 0x2e ] = KEY_MENU, /* FULL SCREEN on Hauppauge */ | ||
1595 | [ 0x30 ] = KEY_SLOW, | ||
1596 | [ 0x31 ] = KEY_PREVIOUS, /* VCR mode on Zenith */ | ||
1597 | [ 0x32 ] = KEY_REWIND, | ||
1598 | [ 0x34 ] = KEY_FASTFORWARD, | ||
1599 | [ 0x35 ] = KEY_PLAY, | ||
1600 | [ 0x36 ] = KEY_STOP, | ||
1601 | [ 0x37 ] = KEY_RECORD, | ||
1602 | [ 0x38 ] = KEY_TUNER, /* TV/VCR on Zenith */ | ||
1603 | [ 0x3a ] = KEY_C, | ||
1604 | [ 0x3c ] = KEY_EXIT, | ||
1605 | [ 0x3d ] = KEY_POWER2, | ||
1606 | [ 0x3e ] = KEY_TUNER, | ||
1607 | }; | ||
1608 | |||
1609 | EXPORT_SYMBOL_GPL(ir_codes_budget_ci_old); | ||
diff --git a/drivers/media/dvb/ttpci/Kconfig b/drivers/media/dvb/ttpci/Kconfig index 95531a624991..eec7ccf41f8b 100644 --- a/drivers/media/dvb/ttpci/Kconfig +++ b/drivers/media/dvb/ttpci/Kconfig | |||
@@ -92,6 +92,7 @@ config DVB_BUDGET_CI | |||
92 | select DVB_STV0299 if !DVB_FE_CUSTOMISE | 92 | select DVB_STV0299 if !DVB_FE_CUSTOMISE |
93 | select DVB_TDA1004X if !DVB_FE_CUSTOMISE | 93 | select DVB_TDA1004X if !DVB_FE_CUSTOMISE |
94 | select DVB_LNBP21 if !DVB_FE_CUSTOMISE | 94 | select DVB_LNBP21 if !DVB_FE_CUSTOMISE |
95 | select VIDEO_IR | ||
95 | help | 96 | help |
96 | Support for simple SAA7146 based DVB cards | 97 | Support for simple SAA7146 based DVB cards |
97 | (so called Budget- or Nova-PCI cards) without onboard | 98 | (so called Budget- or Nova-PCI cards) without onboard |
diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c index c34b5d3bdde5..d1b5402cd6fe 100644 --- a/drivers/media/dvb/ttpci/budget-ci.c +++ b/drivers/media/dvb/ttpci/budget-ci.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include <linux/interrupt.h> | 37 | #include <linux/interrupt.h> |
38 | #include <linux/input.h> | 38 | #include <linux/input.h> |
39 | #include <linux/spinlock.h> | 39 | #include <linux/spinlock.h> |
40 | #include <media/ir-common.h> | ||
40 | 41 | ||
41 | #include "dvb_ca_en50221.h" | 42 | #include "dvb_ca_en50221.h" |
42 | #include "stv0299.h" | 43 | #include "stv0299.h" |
@@ -72,11 +73,24 @@ | |||
72 | #define SLOTSTATUS_READY 8 | 73 | #define SLOTSTATUS_READY 8 |
73 | #define SLOTSTATUS_OCCUPIED (SLOTSTATUS_PRESENT|SLOTSTATUS_RESET|SLOTSTATUS_READY) | 74 | #define SLOTSTATUS_OCCUPIED (SLOTSTATUS_PRESENT|SLOTSTATUS_RESET|SLOTSTATUS_READY) |
74 | 75 | ||
76 | /* Milliseconds during which key presses are regarded as key repeat and during | ||
77 | * which the debounce logic is active | ||
78 | */ | ||
79 | #define IR_REPEAT_TIMEOUT 350 | ||
80 | |||
81 | /* Some remotes sends multiple sequences per keypress (e.g. Zenith sends two), | ||
82 | * this setting allows the superflous sequences to be ignored | ||
83 | */ | ||
84 | static int debounce = 0; | ||
85 | module_param(debounce, int, 0644); | ||
86 | MODULE_PARM_DESC(debounce, "ignore repeated IR sequences (default: 0 = ignore no sequences)"); | ||
87 | |||
75 | struct budget_ci_ir { | 88 | struct budget_ci_ir { |
76 | struct input_dev *dev; | 89 | struct input_dev *dev; |
77 | struct tasklet_struct msp430_irq_tasklet; | 90 | struct tasklet_struct msp430_irq_tasklet; |
78 | char name[72]; /* 40 + 32 for (struct saa7146_dev).name */ | 91 | char name[72]; /* 40 + 32 for (struct saa7146_dev).name */ |
79 | char phys[32]; | 92 | char phys[32]; |
93 | struct ir_input_state state; | ||
80 | }; | 94 | }; |
81 | 95 | ||
82 | struct budget_ci { | 96 | struct budget_ci { |
@@ -89,59 +103,44 @@ struct budget_ci { | |||
89 | u8 tuner_pll_address; /* used for philips_tdm1316l configs */ | 103 | u8 tuner_pll_address; /* used for philips_tdm1316l configs */ |
90 | }; | 104 | }; |
91 | 105 | ||
92 | /* from reading the following remotes: | 106 | static void msp430_ir_keyup(unsigned long data) |
93 | Zenith Universal 7 / TV Mode 807 / VCR Mode 837 | 107 | { |
94 | Hauppauge (from NOVA-CI-s box product) | 108 | struct budget_ci_ir *ir = (struct budget_ci_ir *) data; |
95 | i've taken a "middle of the road" approach and note the differences | 109 | ir_input_nokey(ir->dev, &ir->state); |
96 | */ | 110 | } |
97 | static u16 key_map[64] = { | 111 | |
98 | /* 0x0X */ | 112 | static void msp430_ir_interrupt(unsigned long data) |
99 | KEY_0, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7, KEY_8, | 113 | { |
100 | KEY_9, | 114 | struct budget_ci *budget_ci = (struct budget_ci *) data; |
101 | KEY_ENTER, | 115 | struct input_dev *dev = budget_ci->ir.dev; |
102 | KEY_RED, | 116 | static int bounces = 0; |
103 | KEY_POWER, /* RADIO on Hauppauge */ | 117 | u32 ir_key; |
104 | KEY_MUTE, | 118 | u32 command = ttpci_budget_debiread(&budget_ci->budget, DEBINOSWAP, DEBIADDR_IR, 2, 1, 0) >> 8; |
105 | 0, | 119 | |
106 | KEY_A, /* TV on Hauppauge */ | 120 | if (command & 0x40) { |
107 | /* 0x1X */ | 121 | ir_key = command & 0x3f; |
108 | KEY_VOLUMEUP, KEY_VOLUMEDOWN, | 122 | |
109 | 0, 0, | 123 | if (ir_key != dev->repeat_key && del_timer(&dev->timer)) |
110 | KEY_B, | 124 | /* We were still waiting for a keyup event but this is a new key */ |
111 | 0, 0, 0, 0, 0, 0, 0, | 125 | ir_input_nokey(dev, &budget_ci->ir.state); |
112 | KEY_UP, KEY_DOWN, | 126 | |
113 | KEY_OPTION, /* RESERVED on Hauppauge */ | 127 | if (ir_key == dev->repeat_key && bounces > 0 && timer_pending(&dev->timer)) { |
114 | KEY_BREAK, | 128 | /* Ignore repeated key sequences if requested */ |
115 | /* 0x2X */ | 129 | bounces--; |
116 | KEY_CHANNELUP, KEY_CHANNELDOWN, | 130 | return; |
117 | KEY_PREVIOUS, /* Prev. Ch on Zenith, SOURCE on Hauppauge */ | 131 | } |
118 | 0, KEY_RESTART, KEY_OK, | 132 | |
119 | KEY_CYCLEWINDOWS, /* MINIMIZE on Hauppauge */ | 133 | if (!timer_pending(&dev->timer)) |
120 | 0, | 134 | /* New keypress */ |
121 | KEY_ENTER, /* VCR mode on Zenith */ | 135 | bounces = debounce; |
122 | KEY_PAUSE, | 136 | |
123 | 0, | 137 | /* Prepare a keyup event sometime in the future */ |
124 | KEY_RIGHT, KEY_LEFT, | 138 | mod_timer(&dev->timer, jiffies + msecs_to_jiffies(IR_REPEAT_TIMEOUT)); |
125 | 0, | 139 | |
126 | KEY_MENU, /* FULL SCREEN on Hauppauge */ | 140 | /* Generate a new or repeated keypress */ |
127 | 0, | 141 | ir_input_keydown(dev, &budget_ci->ir.state, ir_key, command); |
128 | /* 0x3X */ | 142 | } |
129 | KEY_SLOW, | 143 | } |
130 | KEY_PREVIOUS, /* VCR mode on Zenith */ | ||
131 | KEY_REWIND, | ||
132 | 0, | ||
133 | KEY_FASTFORWARD, | ||
134 | KEY_PLAY, KEY_STOP, | ||
135 | KEY_RECORD, | ||
136 | KEY_TUNER, /* TV/VCR on Zenith */ | ||
137 | 0, | ||
138 | KEY_C, | ||
139 | 0, | ||
140 | KEY_EXIT, | ||
141 | KEY_POWER2, | ||
142 | KEY_TUNER, /* VCR mode on Zenith */ | ||
143 | 0, | ||
144 | }; | ||
145 | 144 | ||
146 | static void msp430_ir_debounce(unsigned long data) | 145 | static void msp430_ir_debounce(unsigned long data) |
147 | { | 146 | { |
@@ -197,7 +196,6 @@ static int msp430_ir_init(struct budget_ci *budget_ci) | |||
197 | { | 196 | { |
198 | struct saa7146_dev *saa = budget_ci->budget.dev; | 197 | struct saa7146_dev *saa = budget_ci->budget.dev; |
199 | struct input_dev *input_dev = budget_ci->ir.dev; | 198 | struct input_dev *input_dev = budget_ci->ir.dev; |
200 | int i; | ||
201 | int error; | 199 | int error; |
202 | 200 | ||
203 | budget_ci->ir.dev = input_dev = input_allocate_device(); | 201 | budget_ci->ir.dev = input_dev = input_allocate_device(); |
@@ -230,10 +228,30 @@ static int msp430_ir_init(struct budget_ci *budget_ci) | |||
230 | input_dev->dev = &saa->pci->dev; | 228 | input_dev->dev = &saa->pci->dev; |
231 | # endif | 229 | # endif |
232 | 230 | ||
233 | set_bit(EV_KEY, input_dev->evbit); | 231 | /* Select keymap */ |
234 | for (i = 0; i < ARRAY_SIZE(key_map); i++) | 232 | switch (budget_ci->budget.dev->pci->subsystem_device) { |
235 | if (key_map[i]) | 233 | case 0x100c: |
236 | set_bit(key_map[i], input_dev->keybit); | 234 | case 0x100f: |
235 | case 0x1010: | ||
236 | case 0x1011: | ||
237 | case 0x1012: | ||
238 | case 0x1017: | ||
239 | /* The hauppauge keymap is a superset of these remotes */ | ||
240 | ir_input_init(input_dev, &budget_ci->ir.state, | ||
241 | IR_TYPE_RC5, ir_codes_hauppauge_new); | ||
242 | break; | ||
243 | default: | ||
244 | /* unknown remote */ | ||
245 | ir_input_init(input_dev, &budget_ci->ir.state, | ||
246 | IR_TYPE_RC5, ir_codes_budget_ci_old); | ||
247 | break; | ||
248 | } | ||
249 | |||
250 | /* initialise the key-up timeout handler */ | ||
251 | input_dev->timer.function = msp430_ir_keyup; | ||
252 | input_dev->timer.data = (unsigned long) &budget_ci->ir; | ||
253 | input_dev->rep[REP_DELAY] = 1; | ||
254 | input_dev->rep[REP_PERIOD] = 1; | ||
237 | 255 | ||
238 | error = input_register_device(input_dev); | 256 | error = input_register_device(input_dev); |
239 | if (error) { | 257 | if (error) { |
@@ -241,8 +259,6 @@ static int msp430_ir_init(struct budget_ci *budget_ci) | |||
241 | goto out2; | 259 | goto out2; |
242 | } | 260 | } |
243 | 261 | ||
244 | input_dev->timer.function = msp430_ir_debounce; | ||
245 | |||
246 | tasklet_init(&budget_ci->ir.msp430_irq_tasklet, msp430_ir_interrupt, | 262 | tasklet_init(&budget_ci->ir.msp430_irq_tasklet, msp430_ir_interrupt, |
247 | (unsigned long) budget_ci); | 263 | (unsigned long) budget_ci); |
248 | 264 | ||
@@ -267,7 +283,7 @@ static void msp430_ir_deinit(struct budget_ci *budget_ci) | |||
267 | tasklet_kill(&budget_ci->ir.msp430_irq_tasklet); | 283 | tasklet_kill(&budget_ci->ir.msp430_irq_tasklet); |
268 | 284 | ||
269 | if (del_timer(&dev->timer)) { | 285 | if (del_timer(&dev->timer)) { |
270 | input_event(dev, EV_KEY, key_map[dev->repeat_key], 0); | 286 | ir_input_nokey(dev, &budget_ci->ir.state); |
271 | input_sync(dev); | 287 | input_sync(dev); |
272 | } | 288 | } |
273 | 289 | ||
diff --git a/include/media/ir-common.h b/include/media/ir-common.h index 8f58406533c6..2b25f5c95006 100644 --- a/include/media/ir-common.h +++ b/include/media/ir-common.h | |||
@@ -92,6 +92,7 @@ extern IR_KEYTAB_TYPE ir_codes_hauppauge_new[IR_KEYTAB_SIZE]; | |||
92 | extern IR_KEYTAB_TYPE ir_codes_npgtech[IR_KEYTAB_SIZE]; | 92 | extern IR_KEYTAB_TYPE ir_codes_npgtech[IR_KEYTAB_SIZE]; |
93 | extern IR_KEYTAB_TYPE ir_codes_norwood[IR_KEYTAB_SIZE]; | 93 | extern IR_KEYTAB_TYPE ir_codes_norwood[IR_KEYTAB_SIZE]; |
94 | extern IR_KEYTAB_TYPE ir_codes_proteus_2309[IR_KEYTAB_SIZE]; | 94 | extern IR_KEYTAB_TYPE ir_codes_proteus_2309[IR_KEYTAB_SIZE]; |
95 | extern IR_KEYTAB_TYPE ir_codes_budget_ci_old[IR_KEYTAB_SIZE]; | ||
95 | 96 | ||
96 | #endif | 97 | #endif |
97 | 98 | ||