aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/siano
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/dvb/siano')
-rw-r--r--drivers/media/dvb/siano/sms-cards.c2
-rw-r--r--drivers/media/dvb/siano/sms-cards.h2
-rw-r--r--drivers/media/dvb/siano/smscoreapi.c4
-rw-r--r--drivers/media/dvb/siano/smsir.c261
-rw-r--r--drivers/media/dvb/siano/smsir.h63
-rw-r--r--drivers/media/dvb/siano/smsusb.c3
6 files changed, 54 insertions, 281 deletions
diff --git a/drivers/media/dvb/siano/sms-cards.c b/drivers/media/dvb/siano/sms-cards.c
index cff77e2eb557..25b43e587fa6 100644
--- a/drivers/media/dvb/siano/sms-cards.c
+++ b/drivers/media/dvb/siano/sms-cards.c
@@ -64,9 +64,11 @@ static struct sms_board sms_boards[] = {
64 .type = SMS_NOVA_B0, 64 .type = SMS_NOVA_B0,
65 .fw[DEVICE_MODE_ISDBT_BDA] = "sms1xxx-hcw-55xxx-isdbt-02.fw", 65 .fw[DEVICE_MODE_ISDBT_BDA] = "sms1xxx-hcw-55xxx-isdbt-02.fw",
66 .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw", 66 .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw",
67 .rc_codes = RC_MAP_RC5_HAUPPAUGE_NEW,
67 .board_cfg.leds_power = 26, 68 .board_cfg.leds_power = 26,
68 .board_cfg.led0 = 27, 69 .board_cfg.led0 = 27,
69 .board_cfg.led1 = 28, 70 .board_cfg.led1 = 28,
71 .board_cfg.ir = 9,
70 .led_power = 26, 72 .led_power = 26,
71 .led_lo = 27, 73 .led_lo = 27,
72 .led_hi = 28, 74 .led_hi = 28,
diff --git a/drivers/media/dvb/siano/sms-cards.h b/drivers/media/dvb/siano/sms-cards.h
index 8f19fc000b46..d8cdf756f7cf 100644
--- a/drivers/media/dvb/siano/sms-cards.h
+++ b/drivers/media/dvb/siano/sms-cards.h
@@ -75,7 +75,7 @@ struct sms_board {
75 enum sms_device_type_st type; 75 enum sms_device_type_st type;
76 char *name, *fw[DEVICE_MODE_MAX]; 76 char *name, *fw[DEVICE_MODE_MAX];
77 struct sms_board_gpio_cfg board_cfg; 77 struct sms_board_gpio_cfg board_cfg;
78 enum ir_kb_type ir_kb_type; 78 char *rc_codes; /* Name of IR codes table */
79 79
80 /* gpios */ 80 /* gpios */
81 int led_power, led_hi, led_lo, lna_ctrl, rf_switch; 81 int led_power, led_hi, led_lo, lna_ctrl, rf_switch;
diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c
index 0c87a3c3899a..828bcc2e129b 100644
--- a/drivers/media/dvb/siano/smscoreapi.c
+++ b/drivers/media/dvb/siano/smscoreapi.c
@@ -116,9 +116,7 @@ static struct smscore_registry_entry_t *smscore_find_registry(char *devpath)
116 return entry; 116 return entry;
117 } 117 }
118 } 118 }
119 entry = (struct smscore_registry_entry_t *) 119 entry = kmalloc(sizeof(struct smscore_registry_entry_t), GFP_KERNEL);
120 kmalloc(sizeof(struct smscore_registry_entry_t),
121 GFP_KERNEL);
122 if (entry) { 120 if (entry) {
123 entry->mode = default_mode; 121 entry->mode = default_mode;
124 strcpy(entry->devpath, devpath); 122 strcpy(entry->devpath, devpath);
diff --git a/drivers/media/dvb/siano/smsir.c b/drivers/media/dvb/siano/smsir.c
index a56eac76e0f0..d0e4639ee9db 100644
--- a/drivers/media/dvb/siano/smsir.c
+++ b/drivers/media/dvb/siano/smsir.c
@@ -4,6 +4,11 @@
4 MDTV receiver kernel modules. 4 MDTV receiver kernel modules.
5 Copyright (C) 2006-2009, Uri Shkolnik 5 Copyright (C) 2006-2009, Uri Shkolnik
6 6
7 Copyright (c) 2010 - Mauro Carvalho Chehab
8 - Ported the driver to use rc-core
9 - IR raw event decoding is now done at rc-core
10 - Code almost re-written
11
7 This program is free software: you can redistribute it and/or modify 12 This program is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by 13 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 2 of the License, or 14 the Free Software Foundation, either version 2 of the License, or
@@ -27,226 +32,28 @@
27#include "smsir.h" 32#include "smsir.h"
28#include "sms-cards.h" 33#include "sms-cards.h"
29 34
30/* In order to add new IR remote control - 35#define MODULE_NAME "smsmdtv"
31 * 1) Add it to the <enum ir_kb_type> @ smsir,h,
32 * 2) Add its map to keyboard_layout_maps below
33 * 3) Set your board (sms-cards sub-module) to use it
34 */
35
36static struct keyboard_layout_map_t keyboard_layout_maps[] = {
37 [SMS_IR_KB_DEFAULT_TV] = {
38 .ir_protocol = IR_RC5,
39 .rc5_kbd_address = KEYBOARD_ADDRESS_TV1,
40 .keyboard_layout_map = {
41 KEY_0, KEY_1, KEY_2,
42 KEY_3, KEY_4, KEY_5,
43 KEY_6, KEY_7, KEY_8,
44 KEY_9, 0, 0, KEY_POWER,
45 KEY_MUTE, 0, 0,
46 KEY_VOLUMEUP, KEY_VOLUMEDOWN,
47 KEY_BRIGHTNESSUP,
48 KEY_BRIGHTNESSDOWN, KEY_CHANNELUP,
49 KEY_CHANNELDOWN,
50 0, 0, 0, 0, 0, 0, 0, 0,
51 0, 0, 0, 0, 0, 0, 0, 0,
52 0, 0, 0, 0, 0, 0, 0, 0,
53 0, 0, 0, 0, 0, 0, 0, 0,
54 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
55 }
56 },
57 [SMS_IR_KB_HCW_SILVER] = {
58 .ir_protocol = IR_RC5,
59 .rc5_kbd_address = KEYBOARD_ADDRESS_LIGHTING1,
60 .keyboard_layout_map = {
61 KEY_0, KEY_1, KEY_2,
62 KEY_3, KEY_4, KEY_5,
63 KEY_6, KEY_7, KEY_8,
64 KEY_9, KEY_TEXT, KEY_RED,
65 KEY_RADIO, KEY_MENU,
66 KEY_SUBTITLE,
67 KEY_MUTE, KEY_VOLUMEUP,
68 KEY_VOLUMEDOWN, KEY_PREVIOUS, 0,
69 KEY_UP, KEY_DOWN, KEY_LEFT,
70 KEY_RIGHT, KEY_VIDEO, KEY_AUDIO,
71 KEY_MHP, KEY_EPG, KEY_TV,
72 0, KEY_NEXTSONG, KEY_EXIT,
73 KEY_CHANNELUP, KEY_CHANNELDOWN,
74 KEY_CHANNEL, 0,
75 KEY_PREVIOUSSONG, KEY_ENTER,
76 KEY_SLEEP, 0, 0, KEY_BLUE,
77 0, 0, 0, 0, KEY_GREEN, 0,
78 KEY_PAUSE, 0, KEY_REWIND,
79 0, KEY_FASTFORWARD, KEY_PLAY,
80 KEY_STOP, KEY_RECORD,
81 KEY_YELLOW, 0, 0, KEY_SELECT,
82 KEY_ZOOM, KEY_POWER, 0, 0
83 }
84 },
85 { } /* Terminating entry */
86};
87
88static u32 ir_pos;
89static u32 ir_word;
90static u32 ir_toggle;
91
92#define RC5_PUSH_BIT(dst, bit, pos) \
93 { dst <<= 1; dst |= bit; pos++; }
94
95
96static void sms_ir_rc5_event(struct smscore_device_t *coredev,
97 u32 toggle, u32 addr, u32 cmd)
98{
99 bool toggle_changed;
100 u16 keycode;
101
102 sms_log("IR RC5 word: address %d, command %d, toggle %d",
103 addr, cmd, toggle);
104
105 toggle_changed = ir_toggle != toggle;
106 /* keep toggle */
107 ir_toggle = toggle;
108
109 if (addr !=
110 keyboard_layout_maps[coredev->ir.ir_kb_type].rc5_kbd_address)
111 return; /* Check for valid address */
112
113 keycode =
114 keyboard_layout_maps
115 [coredev->ir.ir_kb_type].keyboard_layout_map[cmd];
116 36
117 if (!toggle_changed && 37void sms_ir_event(struct smscore_device_t *coredev, const char *buf, int len)
118 (keycode != KEY_VOLUMEUP && keycode != KEY_VOLUMEDOWN))
119 return; /* accept only repeated volume, reject other keys */
120
121 sms_log("kernel input keycode (from ir) %d", keycode);
122 input_report_key(coredev->ir.input_dev, keycode, 1);
123 input_sync(coredev->ir.input_dev);
124
125}
126
127/* decode raw bit pattern to RC5 code */
128/* taken from ir-functions.c */
129static u32 ir_rc5_decode(unsigned int code)
130{ 38{
131/* unsigned int org_code = code;*/
132 unsigned int pair;
133 unsigned int rc5 = 0;
134 int i; 39 int i;
40 const s32 *samples = (const void *)buf;
135 41
136 for (i = 0; i < 14; ++i) { 42 for (i = 0; i < len >> 2; i++) {
137 pair = code & 0x3; 43 struct ir_raw_event ev;
138 code >>= 2;
139
140 rc5 <<= 1;
141 switch (pair) {
142 case 0:
143 case 2:
144 break;
145 case 1:
146 rc5 |= 1;
147 break;
148 case 3:
149/* dprintk(1, "ir-common: ir_rc5_decode(%x) bad code\n", org_code);*/
150 sms_log("bad code");
151 return 0;
152 }
153 }
154/*
155 dprintk(1, "ir-common: code=%x, rc5=%x, start=%x,
156 toggle=%x, address=%x, "
157 "instr=%x\n", rc5, org_code, RC5_START(rc5),
158 RC5_TOGGLE(rc5), RC5_ADDR(rc5), RC5_INSTR(rc5));
159*/
160 return rc5;
161}
162
163static void sms_rc5_parse_word(struct smscore_device_t *coredev)
164{
165 #define RC5_START(x) (((x)>>12)&3)
166 #define RC5_TOGGLE(x) (((x)>>11)&1)
167 #define RC5_ADDR(x) (((x)>>6)&0x1F)
168 #define RC5_INSTR(x) ((x)&0x3F)
169
170 int i, j;
171 u32 rc5_word = 0;
172
173 /* Reverse the IR word direction */
174 for (i = 0 ; i < 28 ; i++)
175 RC5_PUSH_BIT(rc5_word, (ir_word>>i)&1, j)
176
177 rc5_word = ir_rc5_decode(rc5_word);
178 /* sms_log("temp = 0x%x, rc5_code = 0x%x", ir_word, rc5_word); */
179
180 sms_ir_rc5_event(coredev,
181 RC5_TOGGLE(rc5_word),
182 RC5_ADDR(rc5_word),
183 RC5_INSTR(rc5_word));
184}
185
186
187static void sms_rc5_accumulate_bits(struct smscore_device_t *coredev,
188 s32 ir_sample)
189{
190 #define RC5_TIME_GRANULARITY 200
191 #define RC5_DEF_BIT_TIME 889
192 #define RC5_MAX_SAME_BIT_CONT 4
193 #define RC5_WORD_LEN 27 /* 28 bit */
194
195 u32 i, j;
196 s32 delta_time;
197 u32 time = (ir_sample > 0) ? ir_sample : (0-ir_sample);
198 u32 level = (ir_sample < 0) ? 0 : 1;
199
200 for (i = RC5_MAX_SAME_BIT_CONT; i > 0; i--) {
201 delta_time = time - (i*RC5_DEF_BIT_TIME) + RC5_TIME_GRANULARITY;
202 if (delta_time < 0)
203 continue; /* not so many consecutive bits */
204 if (delta_time > (2 * RC5_TIME_GRANULARITY)) {
205 /* timeout */
206 if (ir_pos == (RC5_WORD_LEN-1))
207 /* complete last bit */
208 RC5_PUSH_BIT(ir_word, level, ir_pos)
209
210 if (ir_pos == RC5_WORD_LEN)
211 sms_rc5_parse_word(coredev);
212 else if (ir_pos) /* timeout within a word */
213 sms_log("IR error parsing a word");
214 44
215 ir_pos = 0; 45 ev.duration = abs(samples[i]) * 1000; /* Convert to ns */
216 ir_word = 0; 46 ev.pulse = (samples[i] > 0) ? false : true;
217 /* sms_log("timeout %d", time); */
218 break;
219 }
220 /* The time is within the range of this number of bits */
221 for (j = 0 ; j < i ; j++)
222 RC5_PUSH_BIT(ir_word, level, ir_pos)
223 47
224 break; 48 ir_raw_event_store(coredev->ir.input_dev, &ev);
225 } 49 }
226} 50 ir_raw_event_handle(coredev->ir.input_dev);
227
228void sms_ir_event(struct smscore_device_t *coredev, const char *buf, int len)
229{
230 #define IR_DATA_RECEIVE_MAX_LEN 520 /* 128*4 + 4 + 4 */
231 u32 i;
232 enum ir_protocol ir_protocol =
233 keyboard_layout_maps[coredev->ir.ir_kb_type]
234 .ir_protocol;
235 s32 *samples;
236 int count = len>>2;
237
238 samples = (s32 *)buf;
239/* sms_log("IR buffer received, length = %d", count);*/
240
241 for (i = 0; i < count; i++)
242 if (ir_protocol == IR_RC5)
243 sms_rc5_accumulate_bits(coredev, samples[i]);
244 /* IR_RCMM not implemented */
245} 51}
246 52
247int sms_ir_init(struct smscore_device_t *coredev) 53int sms_ir_init(struct smscore_device_t *coredev)
248{ 54{
249 struct input_dev *input_dev; 55 struct input_dev *input_dev;
56 int board_id = smscore_get_board_id(coredev);
250 57
251 sms_log("Allocating input device"); 58 sms_log("Allocating input device");
252 input_dev = input_allocate_device(); 59 input_dev = input_allocate_device();
@@ -256,33 +63,38 @@ int sms_ir_init(struct smscore_device_t *coredev)
256 } 63 }
257 64
258 coredev->ir.input_dev = input_dev; 65 coredev->ir.input_dev = input_dev;
259 coredev->ir.ir_kb_type =
260 sms_get_board(smscore_get_board_id(coredev))->ir_kb_type;
261 coredev->ir.keyboard_layout_map =
262 keyboard_layout_maps[coredev->ir.ir_kb_type].
263 keyboard_layout_map;
264 sms_log("IR remote keyboard type is %d", coredev->ir.ir_kb_type);
265 66
266 coredev->ir.controller = 0; /* Todo: vega/nova SPI number */ 67 coredev->ir.controller = 0; /* Todo: vega/nova SPI number */
267 coredev->ir.timeout = IR_DEFAULT_TIMEOUT; 68 coredev->ir.timeout = IR_DEFAULT_TIMEOUT;
268 sms_log("IR port %d, timeout %d ms", 69 sms_log("IR port %d, timeout %d ms",
269 coredev->ir.controller, coredev->ir.timeout); 70 coredev->ir.controller, coredev->ir.timeout);
270 71
271 snprintf(coredev->ir.name, 72 snprintf(coredev->ir.name, sizeof(coredev->ir.name),
272 IR_DEV_NAME_MAX_LEN, 73 "SMS IR (%s)", sms_get_board(board_id)->name);
273 "SMS IR w/kbd type %d", 74
274 coredev->ir.ir_kb_type); 75 strlcpy(coredev->ir.phys, coredev->devpath, sizeof(coredev->ir.phys));
76 strlcat(coredev->ir.phys, "/ir0", sizeof(coredev->ir.phys));
77
275 input_dev->name = coredev->ir.name; 78 input_dev->name = coredev->ir.name;
276 input_dev->phys = coredev->ir.name; 79 input_dev->phys = coredev->ir.phys;
277 input_dev->dev.parent = coredev->device; 80 input_dev->dev.parent = coredev->device;
278 81
279 /* Key press events only */ 82#if 0
280 input_dev->evbit[0] = BIT_MASK(EV_KEY); 83 /* TODO: properly initialize the parameters bellow */
281 input_dev->keybit[BIT_WORD(BTN_0)] = BIT_MASK(BTN_0); 84 input_dev->id.bustype = BUS_USB;
85 input_dev->id.version = 1;
86 input_dev->id.vendor = le16_to_cpu(dev->udev->descriptor.idVendor);
87 input_dev->id.product = le16_to_cpu(dev->udev->descriptor.idProduct);
88#endif
89
90 coredev->ir.props.priv = coredev;
91 coredev->ir.props.driver_type = RC_DRIVER_IR_RAW;
92 coredev->ir.props.allowed_protos = IR_TYPE_ALL;
282 93
283 sms_log("Input device (IR) %s is set for key events", input_dev->name); 94 sms_log("Input device (IR) %s is set for key events", input_dev->name);
284 95
285 if (input_register_device(input_dev)) { 96 if (ir_input_register(input_dev, sms_get_board(board_id)->rc_codes,
97 &coredev->ir.props, MODULE_NAME)) {
286 sms_err("Failed to register device"); 98 sms_err("Failed to register device");
287 input_free_device(input_dev); 99 input_free_device(input_dev);
288 return -EACCES; 100 return -EACCES;
@@ -294,8 +106,7 @@ int sms_ir_init(struct smscore_device_t *coredev)
294void sms_ir_exit(struct smscore_device_t *coredev) 106void sms_ir_exit(struct smscore_device_t *coredev)
295{ 107{
296 if (coredev->ir.input_dev) 108 if (coredev->ir.input_dev)
297 input_unregister_device(coredev->ir.input_dev); 109 ir_input_unregister(coredev->ir.input_dev);
298 110
299 sms_log(""); 111 sms_log("");
300} 112}
301
diff --git a/drivers/media/dvb/siano/smsir.h b/drivers/media/dvb/siano/smsir.h
index b7d703e2d338..926e247523bd 100644
--- a/drivers/media/dvb/siano/smsir.h
+++ b/drivers/media/dvb/siano/smsir.h
@@ -4,6 +4,11 @@ Siano Mobile Silicon, Inc.
4MDTV receiver kernel modules. 4MDTV receiver kernel modules.
5Copyright (C) 2006-2009, Uri Shkolnik 5Copyright (C) 2006-2009, Uri Shkolnik
6 6
7 Copyright (c) 2010 - Mauro Carvalho Chehab
8 - Ported the driver to use rc-core
9 - IR raw event decoding is now done at rc-core
10 - Code almost re-written
11
7This program is free software: you can redistribute it and/or modify 12This program is free software: you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by 13it under the terms of the GNU General Public License as published by
9the Free Software Foundation, either version 2 of the License, or 14the Free Software Foundation, either version 2 of the License, or
@@ -23,63 +28,21 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
23#define __SMS_IR_H__ 28#define __SMS_IR_H__
24 29
25#include <linux/input.h> 30#include <linux/input.h>
31#include <media/ir-core.h>
26 32
27#define IR_DEV_NAME_MAX_LEN 23 /* "SMS IR kbd type nn\0" */
28#define IR_KEYBOARD_LAYOUT_SIZE 64
29#define IR_DEFAULT_TIMEOUT 100 33#define IR_DEFAULT_TIMEOUT 100
30 34
31enum ir_kb_type {
32 SMS_IR_KB_DEFAULT_TV,
33 SMS_IR_KB_HCW_SILVER
34};
35
36enum rc5_keyboard_address {
37 KEYBOARD_ADDRESS_TV1 = 0,
38 KEYBOARD_ADDRESS_TV2 = 1,
39 KEYBOARD_ADDRESS_TELETEXT = 2,
40 KEYBOARD_ADDRESS_VIDEO = 3,
41 KEYBOARD_ADDRESS_LV1 = 4,
42 KEYBOARD_ADDRESS_VCR1 = 5,
43 KEYBOARD_ADDRESS_VCR2 = 6,
44 KEYBOARD_ADDRESS_EXPERIMENTAL = 7,
45 KEYBOARD_ADDRESS_SAT1 = 8,
46 KEYBOARD_ADDRESS_CAMERA = 9,
47 KEYBOARD_ADDRESS_SAT2 = 10,
48 KEYBOARD_ADDRESS_CDV = 12,
49 KEYBOARD_ADDRESS_CAMCORDER = 13,
50 KEYBOARD_ADDRESS_PRE_AMP = 16,
51 KEYBOARD_ADDRESS_TUNER = 17,
52 KEYBOARD_ADDRESS_RECORDER1 = 18,
53 KEYBOARD_ADDRESS_PRE_AMP1 = 19,
54 KEYBOARD_ADDRESS_CD_PLAYER = 20,
55 KEYBOARD_ADDRESS_PHONO = 21,
56 KEYBOARD_ADDRESS_SATA = 22,
57 KEYBOARD_ADDRESS_RECORDER2 = 23,
58 KEYBOARD_ADDRESS_CDR = 26,
59 KEYBOARD_ADDRESS_LIGHTING = 29,
60 KEYBOARD_ADDRESS_LIGHTING1 = 30, /* KEYBOARD_ADDRESS_HCW_SILVER */
61 KEYBOARD_ADDRESS_PHONE = 31,
62 KEYBOARD_ADDRESS_NOT_RC5 = 0xFFFF
63};
64
65enum ir_protocol {
66 IR_RC5,
67 IR_RCMM
68};
69
70struct keyboard_layout_map_t {
71 enum ir_protocol ir_protocol;
72 enum rc5_keyboard_address rc5_kbd_address;
73 u16 keyboard_layout_map[IR_KEYBOARD_LAYOUT_SIZE];
74};
75
76struct smscore_device_t; 35struct smscore_device_t;
77 36
78struct ir_t { 37struct ir_t {
79 struct input_dev *input_dev; 38 struct input_dev *input_dev;
80 enum ir_kb_type ir_kb_type; 39 char name[40];
81 char name[IR_DEV_NAME_MAX_LEN+1]; 40 char phys[32];
82 u16 *keyboard_layout_map; 41
42 char *rc_codes;
43 u64 protocol;
44 struct ir_dev_props props;
45
83 u32 timeout; 46 u32 timeout;
84 u32 controller; 47 u32 controller;
85}; 48};
diff --git a/drivers/media/dvb/siano/smsusb.c b/drivers/media/dvb/siano/smsusb.c
index a9c27fb69ba7..50d4338610e0 100644
--- a/drivers/media/dvb/siano/smsusb.c
+++ b/drivers/media/dvb/siano/smsusb.c
@@ -352,8 +352,7 @@ static int smsusb_init_device(struct usb_interface *intf, int board_id)
352 params.num_buffers = MAX_BUFFERS; 352 params.num_buffers = MAX_BUFFERS;
353 params.sendrequest_handler = smsusb_sendrequest; 353 params.sendrequest_handler = smsusb_sendrequest;
354 params.context = dev; 354 params.context = dev;
355 snprintf(params.devpath, sizeof(params.devpath), 355 usb_make_path(dev->udev, params.devpath, sizeof(params.devpath));
356 "usb\\%d-%s", dev->udev->bus->busnum, dev->udev->devpath);
357 356
358 /* register in smscore */ 357 /* register in smscore */
359 rc = smscore_register_device(&params, &dev->coredev); 358 rc = smscore_register_device(&params, &dev->coredev);