aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/media/dvb/ttpci/budget-ci.c76
1 files changed, 59 insertions, 17 deletions
diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c
index d1b5402cd6fe..76d3b6694bce 100644
--- a/drivers/media/dvb/ttpci/budget-ci.c
+++ b/drivers/media/dvb/ttpci/budget-ci.c
@@ -78,6 +78,9 @@
78 */ 78 */
79#define IR_REPEAT_TIMEOUT 350 79#define IR_REPEAT_TIMEOUT 350
80 80
81/* RC5 device wildcard */
82#define IR_DEVICE_ANY 255
83
81/* Some remotes sends multiple sequences per keypress (e.g. Zenith sends two), 84/* Some remotes sends multiple sequences per keypress (e.g. Zenith sends two),
82 * this setting allows the superflous sequences to be ignored 85 * this setting allows the superflous sequences to be ignored
83 */ 86 */
@@ -85,12 +88,17 @@ static int debounce = 0;
85module_param(debounce, int, 0644); 88module_param(debounce, int, 0644);
86MODULE_PARM_DESC(debounce, "ignore repeated IR sequences (default: 0 = ignore no sequences)"); 89MODULE_PARM_DESC(debounce, "ignore repeated IR sequences (default: 0 = ignore no sequences)");
87 90
91static int rc5_device = -1;
92module_param(rc5_device, int, 0644);
93MODULE_PARM_DESC(rc5_device, "only IR commands to given RC5 device (device = 0 - 31, any device = 255, default: autodetect)");
94
88struct budget_ci_ir { 95struct budget_ci_ir {
89 struct input_dev *dev; 96 struct input_dev *dev;
90 struct tasklet_struct msp430_irq_tasklet; 97 struct tasklet_struct msp430_irq_tasklet;
91 char name[72]; /* 40 + 32 for (struct saa7146_dev).name */ 98 char name[72]; /* 40 + 32 for (struct saa7146_dev).name */
92 char phys[32]; 99 char phys[32];
93 struct ir_input_state state; 100 struct ir_input_state state;
101 int rc5_device;
94}; 102};
95 103
96struct budget_ci { 104struct budget_ci {
@@ -114,32 +122,56 @@ static void msp430_ir_interrupt(unsigned long data)
114 struct budget_ci *budget_ci = (struct budget_ci *) data; 122 struct budget_ci *budget_ci = (struct budget_ci *) data;
115 struct input_dev *dev = budget_ci->ir.dev; 123 struct input_dev *dev = budget_ci->ir.dev;
116 static int bounces = 0; 124 static int bounces = 0;
117 u32 ir_key; 125 int device;
126 int toggle;
127 static int prev_toggle = -1;
128 static u32 ir_key;
118 u32 command = ttpci_budget_debiread(&budget_ci->budget, DEBINOSWAP, DEBIADDR_IR, 2, 1, 0) >> 8; 129 u32 command = ttpci_budget_debiread(&budget_ci->budget, DEBINOSWAP, DEBIADDR_IR, 2, 1, 0) >> 8;
119 130
131 /*
132 * The msp430 chip can generate two different bytes, command and device
133 *
134 * type1: X1CCCCCC, C = command bits (0 - 63)
135 * type2: X0TDDDDD, D = device bits (0 - 31), T = RC5 toggle bit
136 *
137 * More than one command byte may be generated before the device byte
138 * Only when we have both, a correct keypress is generated
139 */
140
141 /* Is this a RC5 command byte? */
120 if (command & 0x40) { 142 if (command & 0x40) {
121 ir_key = command & 0x3f; 143 ir_key = command & 0x3f;
144 return;
145 }
122 146
123 if (ir_key != dev->repeat_key && del_timer(&dev->timer)) 147 /* It's a RC5 device byte */
124 /* We were still waiting for a keyup event but this is a new key */ 148 device = command & 0x1f;
125 ir_input_nokey(dev, &budget_ci->ir.state); 149 toggle = command & 0x20;
126 150
127 if (ir_key == dev->repeat_key && bounces > 0 && timer_pending(&dev->timer)) { 151 if (budget_ci->ir.rc5_device != IR_DEVICE_ANY && budget_ci->ir.rc5_device != device)
128 /* Ignore repeated key sequences if requested */ 152 return;
129 bounces--;
130 return;
131 }
132 153
133 if (!timer_pending(&dev->timer)) 154 /* Are we still waiting for a keyup event while this is a new key? */
134 /* New keypress */ 155 if ((ir_key != dev->repeat_key || toggle != prev_toggle) && del_timer(&dev->timer))
135 bounces = debounce; 156 ir_input_nokey(dev, &budget_ci->ir.state);
136 157
137 /* Prepare a keyup event sometime in the future */ 158 prev_toggle = toggle;
138 mod_timer(&dev->timer, jiffies + msecs_to_jiffies(IR_REPEAT_TIMEOUT));
139 159
140 /* Generate a new or repeated keypress */ 160 /* Ignore repeated key sequences if requested */
141 ir_input_keydown(dev, &budget_ci->ir.state, ir_key, command); 161 if (ir_key == dev->repeat_key && bounces > 0 && timer_pending(&dev->timer)) {
162 bounces--;
163 return;
142 } 164 }
165
166 /* New keypress? */
167 if (!timer_pending(&dev->timer))
168 bounces = debounce;
169
170 /* Prepare a keyup event sometime in the future */
171 mod_timer(&dev->timer, jiffies + msecs_to_jiffies(IR_REPEAT_TIMEOUT));
172
173 /* Generate a new or repeated keypress */
174 ir_input_keydown(dev, &budget_ci->ir.state, ir_key, ((device << 8) | command));
143} 175}
144 176
145static void msp430_ir_debounce(unsigned long data) 177static void msp430_ir_debounce(unsigned long data)
@@ -228,7 +260,7 @@ static int msp430_ir_init(struct budget_ci *budget_ci)
228 input_dev->dev = &saa->pci->dev; 260 input_dev->dev = &saa->pci->dev;
229# endif 261# endif
230 262
231 /* Select keymap */ 263 /* Select keymap and address */
232 switch (budget_ci->budget.dev->pci->subsystem_device) { 264 switch (budget_ci->budget.dev->pci->subsystem_device) {
233 case 0x100c: 265 case 0x100c:
234 case 0x100f: 266 case 0x100f:
@@ -239,11 +271,21 @@ static int msp430_ir_init(struct budget_ci *budget_ci)
239 /* The hauppauge keymap is a superset of these remotes */ 271 /* The hauppauge keymap is a superset of these remotes */
240 ir_input_init(input_dev, &budget_ci->ir.state, 272 ir_input_init(input_dev, &budget_ci->ir.state,
241 IR_TYPE_RC5, ir_codes_hauppauge_new); 273 IR_TYPE_RC5, ir_codes_hauppauge_new);
274
275 if (rc5_device < 0)
276 budget_ci->ir.rc5_device = 0x1f;
277 else
278 budget_ci->ir.rc5_device = rc5_device;
242 break; 279 break;
243 default: 280 default:
244 /* unknown remote */ 281 /* unknown remote */
245 ir_input_init(input_dev, &budget_ci->ir.state, 282 ir_input_init(input_dev, &budget_ci->ir.state,
246 IR_TYPE_RC5, ir_codes_budget_ci_old); 283 IR_TYPE_RC5, ir_codes_budget_ci_old);
284
285 if (rc5_device < 0)
286 budget_ci->ir.rc5_device = IR_DEVICE_ANY;
287 else
288 budget_ci->ir.rc5_device = rc5_device;
247 break; 289 break;
248 } 290 }
249 291