hc
2024-05-10 9999e48639b3cecb08ffb37358bcba3b48161b29
kernel/drivers/media/pci/ttpci/av7110_ir.c
....@@ -1,394 +1,157 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * Driver for the remote control of SAA7146 based AV7110 cards
34 *
45 * Copyright (C) 1999-2003 Holger Waechtler <holger@convergence.de>
56 * Copyright (C) 2003-2007 Oliver Endriss <o.endriss@gmx.de>
6
- *
7
- * This program is free software; you can redistribute it and/or
8
- * modify it under the terms of the GNU General Public License
9
- * as published by the Free Software Foundation; either version 2
10
- * of the License, or (at your option) any later version.
11
- *
12
- * This program is distributed in the hope that it will be useful,
13
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
- * GNU General Public License for more details.
16
- * To obtain the license, point your browser to
17
- * http://www.gnu.org/copyleft/gpl.html
18
- *
7
+ * Copyright (C) 2019 Sean Young <sean@mess.org>
198 */
209
21
-
22
-#include <linux/types.h>
23
-#include <linux/init.h>
24
-#include <linux/module.h>
25
-#include <linux/proc_fs.h>
2610 #include <linux/kernel.h>
27
-#include <linux/bitops.h>
11
+#include <media/rc-core.h>
2812
2913 #include "av7110.h"
3014 #include "av7110_hw.h"
31
-
32
-
33
-#define AV_CNT 4
3415
3516 #define IR_RC5 0
3617 #define IR_RCMM 1
3718 #define IR_RC5_EXT 2 /* internal only */
3819
39
-#define IR_ALL 0xffffffff
40
-
41
-#define UP_TIMEOUT (HZ*7/25)
42
-
43
-
44
-/* Note: enable ir debugging by or'ing debug with 16 */
45
-
46
-static int ir_protocol[AV_CNT] = { IR_RCMM, IR_RCMM, IR_RCMM, IR_RCMM};
47
-module_param_array(ir_protocol, int, NULL, 0644);
48
-MODULE_PARM_DESC(ir_protocol, "Infrared protocol: 0 RC5, 1 RCMM (default)");
49
-
50
-static int ir_inversion[AV_CNT];
51
-module_param_array(ir_inversion, int, NULL, 0644);
52
-MODULE_PARM_DESC(ir_inversion, "Inversion of infrared signal: 0 not inverted (default), 1 inverted");
53
-
54
-static uint ir_device_mask[AV_CNT] = { IR_ALL, IR_ALL, IR_ALL, IR_ALL };
55
-module_param_array(ir_device_mask, uint, NULL, 0644);
56
-MODULE_PARM_DESC(ir_device_mask, "Bitmask of infrared devices: bit 0..31 = device 0..31 (default: all)");
57
-
58
-
59
-static int av_cnt;
60
-static struct av7110 *av_list[AV_CNT];
61
-
62
-static u16 default_key_map [256] = {
63
- KEY_0, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7,
64
- KEY_8, KEY_9, KEY_BACK, 0, KEY_POWER, KEY_MUTE, 0, KEY_INFO,
65
- KEY_VOLUMEUP, KEY_VOLUMEDOWN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
66
- KEY_CHANNELUP, KEY_CHANNELDOWN, 0, 0, 0, 0, 0, 0,
67
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
68
- 0, 0, 0, 0, KEY_TEXT, 0, 0, KEY_TV, 0, 0, 0, 0, 0, KEY_SETUP, 0, 0,
69
- 0, 0, 0, KEY_SUBTITLE, 0, 0, KEY_LANGUAGE, 0,
70
- KEY_RADIO, 0, 0, 0, 0, KEY_EXIT, 0, 0,
71
- KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT, KEY_OK, 0, 0, 0,
72
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, KEY_RED, KEY_GREEN, KEY_YELLOW,
73
- KEY_BLUE, 0, 0, 0, 0, 0, 0, 0, KEY_MENU, KEY_LIST, 0, 0, 0, 0, 0, 0,
74
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
75
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
76
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
77
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
78
- 0, 0, 0, 0, KEY_UP, KEY_UP, KEY_DOWN, KEY_DOWN,
79
- 0, 0, 0, 0, KEY_EPG, 0, 0, 0,
80
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
81
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
82
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, KEY_VCR
83
-};
84
-
85
-
86
-/* key-up timer */
87
-static void av7110_emit_keyup(struct timer_list *t)
20
+/* interrupt handler */
21
+void av7110_ir_handler(struct av7110 *av7110, u32 ircom)
8822 {
89
- struct infrared *ir = from_timer(ir, t, keyup_timer);
23
+ struct rc_dev *rcdev = av7110->ir.rcdev;
24
+ enum rc_proto proto;
25
+ u32 command, addr, scancode;
26
+ u32 toggle;
9027
91
- if (!ir || !ir->keypressed)
92
- return;
28
+ dprintk(4, "ir command = %08x\n", ircom);
9329
94
- input_report_key(ir->input_dev, ir->last_key, 0);
95
- input_sync(ir->input_dev);
96
- ir->keypressed = false;
97
-}
98
-
99
-
100
-/* tasklet */
101
-static void av7110_emit_key(unsigned long parm)
102
-{
103
- struct infrared *ir = (struct infrared *) parm;
104
- u32 ircom = ir->ir_command;
105
- u8 data;
106
- u8 addr;
107
- u16 toggle;
108
- u16 keycode;
109
-
110
- /* extract device address and data */
111
- switch (ir->protocol) {
112
- case IR_RC5: /* RC5: 5 bits device address, 6 bits data */
113
- data = ircom & 0x3f;
114
- addr = (ircom >> 6) & 0x1f;
115
- toggle = ircom & 0x0800;
116
- break;
117
-
118
- case IR_RCMM: /* RCMM: ? bits device address, ? bits data */
119
- data = ircom & 0xff;
120
- addr = (ircom >> 8) & 0x1f;
121
- toggle = ircom & 0x8000;
122
- break;
123
-
124
- case IR_RC5_EXT: /* extended RC5: 5 bits device address, 7 bits data */
125
- data = ircom & 0x3f;
126
- addr = (ircom >> 6) & 0x1f;
127
- /* invert 7th data bit for backward compatibility with RC5 keymaps */
128
- if (!(ircom & 0x1000))
129
- data |= 0x40;
130
- toggle = ircom & 0x0800;
131
- break;
132
-
133
- default:
134
- printk("%s invalid protocol %x\n", __func__, ir->protocol);
135
- return;
136
- }
137
-
138
- input_event(ir->input_dev, EV_MSC, MSC_RAW, (addr << 16) | data);
139
- input_event(ir->input_dev, EV_MSC, MSC_SCAN, data);
140
-
141
- keycode = ir->key_map[data];
142
-
143
- dprintk(16, "%s: code %08x -> addr %i data 0x%02x -> keycode %i\n",
144
- __func__, ircom, addr, data, keycode);
145
-
146
- /* check device address */
147
- if (!(ir->device_mask & (1 << addr)))
148
- return;
149
-
150
- if (!keycode) {
151
- printk ("%s: code %08x -> addr %i data 0x%02x -> unknown key!\n",
152
- __func__, ircom, addr, data);
153
- return;
154
- }
155
-
156
- if (ir->keypressed &&
157
- (ir->last_key != keycode || toggle != ir->last_toggle))
158
- input_event(ir->input_dev, EV_KEY, ir->last_key, 0);
159
-
160
- input_event(ir->input_dev, EV_KEY, keycode, 1);
161
- input_sync(ir->input_dev);
162
-
163
- ir->keypressed = true;
164
- ir->last_key = keycode;
165
- ir->last_toggle = toggle;
166
-
167
- mod_timer(&ir->keyup_timer, jiffies + UP_TIMEOUT);
168
-}
169
-
170
-
171
-/* register with input layer */
172
-static void input_register_keys(struct infrared *ir)
173
-{
174
- int i;
175
-
176
- set_bit(EV_KEY, ir->input_dev->evbit);
177
- set_bit(EV_REP, ir->input_dev->evbit);
178
- set_bit(EV_MSC, ir->input_dev->evbit);
179
-
180
- set_bit(MSC_RAW, ir->input_dev->mscbit);
181
- set_bit(MSC_SCAN, ir->input_dev->mscbit);
182
-
183
- memset(ir->input_dev->keybit, 0, sizeof(ir->input_dev->keybit));
184
-
185
- for (i = 0; i < ARRAY_SIZE(ir->key_map); i++) {
186
- if (ir->key_map[i] > KEY_MAX)
187
- ir->key_map[i] = 0;
188
- else if (ir->key_map[i] > KEY_RESERVED)
189
- set_bit(ir->key_map[i], ir->input_dev->keybit);
190
- }
191
-
192
- ir->input_dev->keycode = ir->key_map;
193
- ir->input_dev->keycodesize = sizeof(ir->key_map[0]);
194
- ir->input_dev->keycodemax = ARRAY_SIZE(ir->key_map);
195
-}
196
-
197
-/* check for configuration changes */
198
-int av7110_check_ir_config(struct av7110 *av7110, int force)
199
-{
200
- int i;
201
- int modified = force;
202
- int ret = -ENODEV;
203
-
204
- for (i = 0; i < av_cnt; i++)
205
- if (av7110 == av_list[i])
30
+ if (rcdev) {
31
+ switch (av7110->ir.ir_config) {
32
+ case IR_RC5: /* RC5: 5 bits device address, 6 bits command */
33
+ command = ircom & 0x3f;
34
+ addr = (ircom >> 6) & 0x1f;
35
+ scancode = RC_SCANCODE_RC5(addr, command);
36
+ toggle = ircom & 0x0800;
37
+ proto = RC_PROTO_RC5;
20638 break;
20739
208
- if (i < av_cnt && av7110) {
209
- if ((av7110->ir.protocol & 1) != ir_protocol[i] ||
210
- av7110->ir.inversion != ir_inversion[i])
211
- modified = true;
40
+ case IR_RCMM: /* RCMM: 32 bits scancode */
41
+ scancode = ircom & ~0x8000;
42
+ toggle = ircom & 0x8000;
43
+ proto = RC_PROTO_RCMM32;
44
+ break;
21245
213
- if (modified) {
214
- /* protocol */
215
- if (ir_protocol[i]) {
216
- ir_protocol[i] = 1;
217
- av7110->ir.protocol = IR_RCMM;
218
- av7110->ir.ir_config = 0x0001;
219
- } else if (FW_VERSION(av7110->arm_app) >= 0x2620) {
220
- av7110->ir.protocol = IR_RC5_EXT;
221
- av7110->ir.ir_config = 0x0002;
222
- } else {
223
- av7110->ir.protocol = IR_RC5;
224
- av7110->ir.ir_config = 0x0000;
225
- }
226
- /* inversion */
227
- if (ir_inversion[i]) {
228
- ir_inversion[i] = 1;
229
- av7110->ir.ir_config |= 0x8000;
230
- }
231
- av7110->ir.inversion = ir_inversion[i];
232
- /* update ARM */
233
- ret = av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, SetIR, 1,
234
- av7110->ir.ir_config);
235
- } else
236
- ret = 0;
46
+ case IR_RC5_EXT:
47
+ /*
48
+ * extended RC5: 5 bits device address, 7 bits command
49
+ *
50
+ * Extended RC5 uses only one start bit. The second
51
+ * start bit is re-assigned bit 6 of the command bit.
52
+ */
53
+ command = ircom & 0x3f;
54
+ addr = (ircom >> 6) & 0x1f;
55
+ if (!(ircom & 0x1000))
56
+ command |= 0x40;
57
+ scancode = RC_SCANCODE_RC5(addr, command);
58
+ toggle = ircom & 0x0800;
59
+ proto = RC_PROTO_RC5;
60
+ break;
61
+ default:
62
+ dprintk(2, "unknown ir config %d\n",
63
+ av7110->ir.ir_config);
64
+ return;
65
+ }
23766
238
- /* address */
239
- if (av7110->ir.device_mask != ir_device_mask[i])
240
- av7110->ir.device_mask = ir_device_mask[i];
67
+ rc_keydown(rcdev, proto, scancode, toggle != 0);
68
+ }
69
+}
70
+
71
+int av7110_set_ir_config(struct av7110 *av7110)
72
+{
73
+ dprintk(4, "ir config = %08x\n", av7110->ir.ir_config);
74
+
75
+ return av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, SetIR, 1,
76
+ av7110->ir.ir_config);
77
+}
78
+
79
+static int change_protocol(struct rc_dev *rcdev, u64 *rc_type)
80
+{
81
+ struct av7110 *av7110 = rcdev->priv;
82
+ u32 ir_config;
83
+
84
+ if (*rc_type & RC_PROTO_BIT_RCMM32) {
85
+ ir_config = IR_RCMM;
86
+ *rc_type = RC_PROTO_BIT_RCMM32;
87
+ } else if (*rc_type & RC_PROTO_BIT_RC5) {
88
+ if (FW_VERSION(av7110->arm_app) >= 0x2620)
89
+ ir_config = IR_RC5_EXT;
90
+ else
91
+ ir_config = IR_RC5;
92
+ *rc_type = RC_PROTO_BIT_RC5;
93
+ } else {
94
+ return -EINVAL;
95
+ }
96
+
97
+ if (ir_config == av7110->ir.ir_config)
98
+ return 0;
99
+
100
+ av7110->ir.ir_config = ir_config;
101
+
102
+ return av7110_set_ir_config(av7110);
103
+}
104
+
105
+int av7110_ir_init(struct av7110 *av7110)
106
+{
107
+ struct rc_dev *rcdev;
108
+ struct pci_dev *pci;
109
+ int ret;
110
+
111
+ rcdev = rc_allocate_device(RC_DRIVER_SCANCODE);
112
+ if (!rcdev)
113
+ return -ENOMEM;
114
+
115
+ pci = av7110->dev->pci;
116
+
117
+ snprintf(av7110->ir.input_phys, sizeof(av7110->ir.input_phys),
118
+ "pci-%s/ir0", pci_name(pci));
119
+
120
+ rcdev->device_name = av7110->card_name;
121
+ rcdev->driver_name = KBUILD_MODNAME;
122
+ rcdev->input_phys = av7110->ir.input_phys;
123
+ rcdev->input_id.bustype = BUS_PCI;
124
+ rcdev->input_id.version = 2;
125
+ if (pci->subsystem_vendor) {
126
+ rcdev->input_id.vendor = pci->subsystem_vendor;
127
+ rcdev->input_id.product = pci->subsystem_device;
128
+ } else {
129
+ rcdev->input_id.vendor = pci->vendor;
130
+ rcdev->input_id.product = pci->device;
131
+ }
132
+
133
+ rcdev->dev.parent = &pci->dev;
134
+ rcdev->allowed_protocols = RC_PROTO_BIT_RC5 | RC_PROTO_BIT_RCMM32;
135
+ rcdev->change_protocol = change_protocol;
136
+ rcdev->map_name = RC_MAP_HAUPPAUGE;
137
+ rcdev->priv = av7110;
138
+
139
+ av7110->ir.rcdev = rcdev;
140
+ av7110->ir.ir_config = IR_RC5;
141
+ av7110_set_ir_config(av7110);
142
+
143
+ ret = rc_register_device(rcdev);
144
+ if (ret) {
145
+ av7110->ir.rcdev = NULL;
146
+ rc_free_device(rcdev);
241147 }
242148
243149 return ret;
244150 }
245151
246
-
247
-/* /proc/av7110_ir interface */
248
-static ssize_t av7110_ir_proc_write(struct file *file, const char __user *buffer,
249
- size_t count, loff_t *pos)
250
-{
251
- char *page;
252
- u32 ir_config;
253
- int size = sizeof ir_config + sizeof av_list[0]->ir.key_map;
254
- int i;
255
-
256
- if (count < size)
257
- return -EINVAL;
258
-
259
- page = vmalloc(size);
260
- if (!page)
261
- return -ENOMEM;
262
-
263
- if (copy_from_user(page, buffer, size)) {
264
- vfree(page);
265
- return -EFAULT;
266
- }
267
-
268
- memcpy(&ir_config, page, sizeof ir_config);
269
-
270
- for (i = 0; i < av_cnt; i++) {
271
- /* keymap */
272
- memcpy(av_list[i]->ir.key_map, page + sizeof ir_config,
273
- sizeof(av_list[i]->ir.key_map));
274
- /* protocol, inversion, address */
275
- ir_protocol[i] = ir_config & 0x0001;
276
- ir_inversion[i] = ir_config & 0x8000 ? 1 : 0;
277
- if (ir_config & 0x4000)
278
- ir_device_mask[i] = 1 << ((ir_config >> 16) & 0x1f);
279
- else
280
- ir_device_mask[i] = IR_ALL;
281
- /* update configuration */
282
- av7110_check_ir_config(av_list[i], false);
283
- input_register_keys(&av_list[i]->ir);
284
- }
285
- vfree(page);
286
- return count;
287
-}
288
-
289
-static const struct file_operations av7110_ir_proc_fops = {
290
- .owner = THIS_MODULE,
291
- .write = av7110_ir_proc_write,
292
- .llseek = noop_llseek,
293
-};
294
-
295
-/* interrupt handler */
296
-static void ir_handler(struct av7110 *av7110, u32 ircom)
297
-{
298
- dprintk(4, "ir command = %08x\n", ircom);
299
- av7110->ir.ir_command = ircom;
300
- tasklet_schedule(&av7110->ir.ir_tasklet);
301
-}
302
-
303
-
304
-int av7110_ir_init(struct av7110 *av7110)
305
-{
306
- struct input_dev *input_dev;
307
- static struct proc_dir_entry *e;
308
- int err;
309
-
310
- if (av_cnt >= ARRAY_SIZE(av_list))
311
- return -ENOSPC;
312
-
313
- av_list[av_cnt++] = av7110;
314
- av7110_check_ir_config(av7110, true);
315
-
316
- timer_setup(&av7110->ir.keyup_timer, av7110_emit_keyup, 0);
317
-
318
- input_dev = input_allocate_device();
319
- if (!input_dev)
320
- return -ENOMEM;
321
-
322
- av7110->ir.input_dev = input_dev;
323
- snprintf(av7110->ir.input_phys, sizeof(av7110->ir.input_phys),
324
- "pci-%s/ir0", pci_name(av7110->dev->pci));
325
-
326
- input_dev->name = "DVB on-card IR receiver";
327
-
328
- input_dev->phys = av7110->ir.input_phys;
329
- input_dev->id.bustype = BUS_PCI;
330
- input_dev->id.version = 2;
331
- if (av7110->dev->pci->subsystem_vendor) {
332
- input_dev->id.vendor = av7110->dev->pci->subsystem_vendor;
333
- input_dev->id.product = av7110->dev->pci->subsystem_device;
334
- } else {
335
- input_dev->id.vendor = av7110->dev->pci->vendor;
336
- input_dev->id.product = av7110->dev->pci->device;
337
- }
338
- input_dev->dev.parent = &av7110->dev->pci->dev;
339
- /* initial keymap */
340
- memcpy(av7110->ir.key_map, default_key_map, sizeof av7110->ir.key_map);
341
- input_register_keys(&av7110->ir);
342
- err = input_register_device(input_dev);
343
- if (err) {
344
- input_free_device(input_dev);
345
- return err;
346
- }
347
-
348
- /*
349
- * Input core's default autorepeat is 33 cps with 250 msec
350
- * delay, let's adjust to numbers more suitable for remote
351
- * control.
352
- */
353
- input_enable_softrepeat(input_dev, 250, 125);
354
-
355
- if (av_cnt == 1) {
356
- e = proc_create("av7110_ir", S_IWUSR, NULL, &av7110_ir_proc_fops);
357
- if (e)
358
- proc_set_size(e, 4 + 256 * sizeof(u16));
359
- }
360
-
361
- tasklet_init(&av7110->ir.ir_tasklet, av7110_emit_key, (unsigned long) &av7110->ir);
362
- av7110->ir.ir_handler = ir_handler;
363
-
364
- return 0;
365
-}
366
-
367
-
368152 void av7110_ir_exit(struct av7110 *av7110)
369153 {
370
- int i;
371
-
372
- if (av_cnt == 0)
373
- return;
374
-
375
- del_timer_sync(&av7110->ir.keyup_timer);
376
- av7110->ir.ir_handler = NULL;
377
- tasklet_kill(&av7110->ir.ir_tasklet);
378
-
379
- for (i = 0; i < av_cnt; i++)
380
- if (av_list[i] == av7110) {
381
- av_list[i] = av_list[av_cnt-1];
382
- av_list[av_cnt-1] = NULL;
383
- break;
384
- }
385
-
386
- if (av_cnt == 1)
387
- remove_proc_entry("av7110_ir", NULL);
388
-
389
- input_unregister_device(av7110->ir.input_dev);
390
-
391
- av_cnt--;
154
+ rc_unregister_device(av7110->ir.rcdev);
392155 }
393156
394157 //MODULE_AUTHOR("Holger Waechtler <holger@convergence.de>, Oliver Endriss <o.endriss@gmx.de>");