aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/ttpci/budget-ci.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/dvb/ttpci/budget-ci.c')
-rw-r--r--drivers/media/dvb/ttpci/budget-ci.c138
1 files changed, 77 insertions, 61 deletions
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 */
84static int debounce = 0;
85module_param(debounce, int, 0644);
86MODULE_PARM_DESC(debounce, "ignore repeated IR sequences (default: 0 = ignore no sequences)");
87
75struct budget_ci_ir { 88struct 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
82struct budget_ci { 96struct 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: 106static 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}
97static u16 key_map[64] = { 111
98 /* 0x0X */ 112static 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
146static void msp430_ir_debounce(unsigned long data) 145static 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