aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/dvb-usb/vp702x.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/dvb/dvb-usb/vp702x.c')
-rw-r--r--drivers/media/dvb/dvb-usb/vp702x.c225
1 files changed, 173 insertions, 52 deletions
diff --git a/drivers/media/dvb/dvb-usb/vp702x.c b/drivers/media/dvb/dvb-usb/vp702x.c
index 5c9f3275aaa0..54355f84a98f 100644
--- a/drivers/media/dvb/dvb-usb/vp702x.c
+++ b/drivers/media/dvb/dvb-usb/vp702x.c
@@ -15,6 +15,7 @@
15 * see Documentation/dvb/README.dvb-usb for more information 15 * see Documentation/dvb/README.dvb-usb for more information
16 */ 16 */
17#include "vp702x.h" 17#include "vp702x.h"
18#include <linux/mutex.h>
18 19
19/* debug */ 20/* debug */
20int dvb_usb_vp702x_debug; 21int dvb_usb_vp702x_debug;
@@ -23,27 +24,23 @@ MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,rc=4 (or-able))." DV
23 24
24DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); 25DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
25 26
26struct vp702x_state { 27struct vp702x_adapter_state {
27 int pid_filter_count; 28 int pid_filter_count;
28 int pid_filter_can_bypass; 29 int pid_filter_can_bypass;
29 u8 pid_filter_state; 30 u8 pid_filter_state;
30}; 31};
31 32
32struct vp702x_device_state { 33static int vp702x_usb_in_op_unlocked(struct dvb_usb_device *d, u8 req,
33 u8 power_state; 34 u16 value, u16 index, u8 *b, int blen)
34};
35
36/* check for mutex FIXME */
37int vp702x_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen)
38{ 35{
39 int ret = -1; 36 int ret;
40 37
41 ret = usb_control_msg(d->udev, 38 ret = usb_control_msg(d->udev,
42 usb_rcvctrlpipe(d->udev,0), 39 usb_rcvctrlpipe(d->udev, 0),
43 req, 40 req,
44 USB_TYPE_VENDOR | USB_DIR_IN, 41 USB_TYPE_VENDOR | USB_DIR_IN,
45 value,index,b,blen, 42 value, index, b, blen,
46 2000); 43 2000);
47 44
48 if (ret < 0) { 45 if (ret < 0) {
49 warn("usb in operation failed. (%d)", ret); 46 warn("usb in operation failed. (%d)", ret);
@@ -58,8 +55,20 @@ int vp702x_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8
58 return ret; 55 return ret;
59} 56}
60 57
61static int vp702x_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value, 58int vp702x_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value,
62 u16 index, u8 *b, int blen) 59 u16 index, u8 *b, int blen)
60{
61 int ret;
62
63 mutex_lock(&d->usb_mutex);
64 ret = vp702x_usb_in_op_unlocked(d, req, value, index, b, blen);
65 mutex_unlock(&d->usb_mutex);
66
67 return ret;
68}
69
70int vp702x_usb_out_op_unlocked(struct dvb_usb_device *d, u8 req, u16 value,
71 u16 index, u8 *b, int blen)
63{ 72{
64 int ret; 73 int ret;
65 deb_xfer("out: req. %02x, val: %04x, ind: %04x, buffer: ",req,value,index); 74 deb_xfer("out: req. %02x, val: %04x, ind: %04x, buffer: ",req,value,index);
@@ -77,6 +86,18 @@ static int vp702x_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value,
77 return 0; 86 return 0;
78} 87}
79 88
89int vp702x_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value,
90 u16 index, u8 *b, int blen)
91{
92 int ret;
93
94 mutex_lock(&d->usb_mutex);
95 ret = vp702x_usb_out_op_unlocked(d, req, value, index, b, blen);
96 mutex_unlock(&d->usb_mutex);
97
98 return ret;
99}
100
80int vp702x_usb_inout_op(struct dvb_usb_device *d, u8 *o, int olen, u8 *i, int ilen, int msec) 101int vp702x_usb_inout_op(struct dvb_usb_device *d, u8 *o, int olen, u8 *i, int ilen, int msec)
81{ 102{
82 int ret; 103 int ret;
@@ -84,50 +105,93 @@ int vp702x_usb_inout_op(struct dvb_usb_device *d, u8 *o, int olen, u8 *i, int il
84 if ((ret = mutex_lock_interruptible(&d->usb_mutex))) 105 if ((ret = mutex_lock_interruptible(&d->usb_mutex)))
85 return ret; 106 return ret;
86 107
87 ret = vp702x_usb_out_op(d,REQUEST_OUT,0,0,o,olen); 108 ret = vp702x_usb_out_op_unlocked(d, REQUEST_OUT, 0, 0, o, olen);
88 msleep(msec); 109 msleep(msec);
89 ret = vp702x_usb_in_op(d,REQUEST_IN,0,0,i,ilen); 110 ret = vp702x_usb_in_op_unlocked(d, REQUEST_IN, 0, 0, i, ilen);
90 111
91 mutex_unlock(&d->usb_mutex); 112 mutex_unlock(&d->usb_mutex);
92
93 return ret; 113 return ret;
94} 114}
95 115
96static int vp702x_usb_inout_cmd(struct dvb_usb_device *d, u8 cmd, u8 *o, 116static int vp702x_usb_inout_cmd(struct dvb_usb_device *d, u8 cmd, u8 *o,
97 int olen, u8 *i, int ilen, int msec) 117 int olen, u8 *i, int ilen, int msec)
98{ 118{
99 u8 bout[olen+2]; 119 struct vp702x_device_state *st = d->priv;
100 u8 bin[ilen+1];
101 int ret = 0; 120 int ret = 0;
121 u8 *buf;
122 int buflen = max(olen + 2, ilen + 1);
123
124 ret = mutex_lock_interruptible(&st->buf_mutex);
125 if (ret < 0)
126 return ret;
127
128 if (buflen > st->buf_len) {
129 buf = kmalloc(buflen, GFP_KERNEL);
130 if (!buf) {
131 mutex_unlock(&st->buf_mutex);
132 return -ENOMEM;
133 }
134 info("successfully reallocated a bigger buffer");
135 kfree(st->buf);
136 st->buf = buf;
137 st->buf_len = buflen;
138 } else {
139 buf = st->buf;
140 }
102 141
103 bout[0] = 0x00; 142 buf[0] = 0x00;
104 bout[1] = cmd; 143 buf[1] = cmd;
105 memcpy(&bout[2],o,olen); 144 memcpy(&buf[2], o, olen);
106 145
107 ret = vp702x_usb_inout_op(d, bout, olen+2, bin, ilen+1,msec); 146 ret = vp702x_usb_inout_op(d, buf, olen+2, buf, ilen+1, msec);
108 147
109 if (ret == 0) 148 if (ret == 0)
110 memcpy(i,&bin[1],ilen); 149 memcpy(i, &buf[1], ilen);
150 mutex_unlock(&st->buf_mutex);
111 151
112 return ret; 152 return ret;
113} 153}
114 154
115static int vp702x_set_pld_mode(struct dvb_usb_adapter *adap, u8 bypass) 155static int vp702x_set_pld_mode(struct dvb_usb_adapter *adap, u8 bypass)
116{ 156{
117 u8 buf[16] = { 0 }; 157 int ret;
118 return vp702x_usb_in_op(adap->dev, 0xe0, (bypass << 8) | 0x0e, 0, buf, 16); 158 struct vp702x_device_state *st = adap->dev->priv;
159 u8 *buf;
160
161 mutex_lock(&st->buf_mutex);
162
163 buf = st->buf;
164 memset(buf, 0, 16);
165
166 ret = vp702x_usb_in_op(adap->dev, 0xe0, (bypass << 8) | 0x0e,
167 0, buf, 16);
168 mutex_unlock(&st->buf_mutex);
169 return ret;
119} 170}
120 171
121static int vp702x_set_pld_state(struct dvb_usb_adapter *adap, u8 state) 172static int vp702x_set_pld_state(struct dvb_usb_adapter *adap, u8 state)
122{ 173{
123 u8 buf[16] = { 0 }; 174 int ret;
124 return vp702x_usb_in_op(adap->dev, 0xe0, (state << 8) | 0x0f, 0, buf, 16); 175 struct vp702x_device_state *st = adap->dev->priv;
176 u8 *buf;
177
178 mutex_lock(&st->buf_mutex);
179
180 buf = st->buf;
181 memset(buf, 0, 16);
182 ret = vp702x_usb_in_op(adap->dev, 0xe0, (state << 8) | 0x0f,
183 0, buf, 16);
184
185 mutex_unlock(&st->buf_mutex);
186
187 return ret;
125} 188}
126 189
127static int vp702x_set_pid(struct dvb_usb_adapter *adap, u16 pid, u8 id, int onoff) 190static int vp702x_set_pid(struct dvb_usb_adapter *adap, u16 pid, u8 id, int onoff)
128{ 191{
129 struct vp702x_state *st = adap->priv; 192 struct vp702x_adapter_state *st = adap->priv;
130 u8 buf[16] = { 0 }; 193 struct vp702x_device_state *dst = adap->dev->priv;
194 u8 *buf;
131 195
132 if (onoff) 196 if (onoff)
133 st->pid_filter_state |= (1 << id); 197 st->pid_filter_state |= (1 << id);
@@ -139,32 +203,45 @@ static int vp702x_set_pid(struct dvb_usb_adapter *adap, u16 pid, u8 id, int onof
139 id = 0x10 + id*2; 203 id = 0x10 + id*2;
140 204
141 vp702x_set_pld_state(adap, st->pid_filter_state); 205 vp702x_set_pld_state(adap, st->pid_filter_state);
206
207 mutex_lock(&dst->buf_mutex);
208
209 buf = dst->buf;
210 memset(buf, 0, 16);
142 vp702x_usb_in_op(adap->dev, 0xe0, (((pid >> 8) & 0xff) << 8) | (id), 0, buf, 16); 211 vp702x_usb_in_op(adap->dev, 0xe0, (((pid >> 8) & 0xff) << 8) | (id), 0, buf, 16);
143 vp702x_usb_in_op(adap->dev, 0xe0, (((pid ) & 0xff) << 8) | (id+1), 0, buf, 16); 212 vp702x_usb_in_op(adap->dev, 0xe0, (((pid ) & 0xff) << 8) | (id+1), 0, buf, 16);
213
214 mutex_unlock(&dst->buf_mutex);
215
144 return 0; 216 return 0;
145} 217}
146 218
147 219
148static int vp702x_init_pid_filter(struct dvb_usb_adapter *adap) 220static int vp702x_init_pid_filter(struct dvb_usb_adapter *adap)
149{ 221{
150 struct vp702x_state *st = adap->priv; 222 struct vp702x_adapter_state *st = adap->priv;
223 struct vp702x_device_state *dst = adap->dev->priv;
151 int i; 224 int i;
152 u8 b[10] = { 0 }; 225 u8 *b;
153 226
154 st->pid_filter_count = 8; 227 st->pid_filter_count = 8;
155 st->pid_filter_can_bypass = 1; 228 st->pid_filter_can_bypass = 1;
156 st->pid_filter_state = 0x00; 229 st->pid_filter_state = 0x00;
157 230
158 vp702x_set_pld_mode(adap, 1); // bypass 231 vp702x_set_pld_mode(adap, 1); /* bypass */
159 232
160 for (i = 0; i < st->pid_filter_count; i++) 233 for (i = 0; i < st->pid_filter_count; i++)
161 vp702x_set_pid(adap, 0xffff, i, 1); 234 vp702x_set_pid(adap, 0xffff, i, 1);
162 235
236 mutex_lock(&dst->buf_mutex);
237 b = dst->buf;
238 memset(b, 0, 10);
163 vp702x_usb_in_op(adap->dev, 0xb5, 3, 0, b, 10); 239 vp702x_usb_in_op(adap->dev, 0xb5, 3, 0, b, 10);
164 vp702x_usb_in_op(adap->dev, 0xb5, 0, 0, b, 10); 240 vp702x_usb_in_op(adap->dev, 0xb5, 0, 0, b, 10);
165 vp702x_usb_in_op(adap->dev, 0xb5, 1, 0, b, 10); 241 vp702x_usb_in_op(adap->dev, 0xb5, 1, 0, b, 10);
242 mutex_unlock(&dst->buf_mutex);
243 /*vp702x_set_pld_mode(d, 0); // filter */
166 244
167 //vp702x_set_pld_mode(d, 0); // filter
168 return 0; 245 return 0;
169} 246}
170 247
@@ -174,7 +251,7 @@ static int vp702x_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
174} 251}
175 252
176/* keys for the enclosed remote control */ 253/* keys for the enclosed remote control */
177static struct ir_scancode ir_codes_vp702x_table[] = { 254static struct rc_map_table rc_map_vp702x_table[] = {
178 { 0x0001, KEY_1 }, 255 { 0x0001, KEY_1 },
179 { 0x0002, KEY_2 }, 256 { 0x0002, KEY_2 },
180}; 257};
@@ -182,36 +259,49 @@ static struct ir_scancode ir_codes_vp702x_table[] = {
182/* remote control stuff (does not work with my box) */ 259/* remote control stuff (does not work with my box) */
183static int vp702x_rc_query(struct dvb_usb_device *d, u32 *event, int *state) 260static int vp702x_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
184{ 261{
185 u8 key[10]; 262 u8 *key;
186 int i; 263 int i;
187 264
188/* remove the following return to enabled remote querying */ 265/* remove the following return to enabled remote querying */
189 return 0; 266 return 0;
190 267
268 key = kmalloc(10, GFP_KERNEL);
269 if (!key)
270 return -ENOMEM;
271
191 vp702x_usb_in_op(d,READ_REMOTE_REQ,0,0,key,10); 272 vp702x_usb_in_op(d,READ_REMOTE_REQ,0,0,key,10);
192 273
193 deb_rc("remote query key: %x %d\n",key[1],key[1]); 274 deb_rc("remote query key: %x %d\n",key[1],key[1]);
194 275
195 if (key[1] == 0x44) { 276 if (key[1] == 0x44) {
196 *state = REMOTE_NO_KEY_PRESSED; 277 *state = REMOTE_NO_KEY_PRESSED;
278 kfree(key);
197 return 0; 279 return 0;
198 } 280 }
199 281
200 for (i = 0; i < ARRAY_SIZE(ir_codes_vp702x_table); i++) 282 for (i = 0; i < ARRAY_SIZE(rc_map_vp702x_table); i++)
201 if (rc5_custom(&ir_codes_vp702x_table[i]) == key[1]) { 283 if (rc5_custom(&rc_map_vp702x_table[i]) == key[1]) {
202 *state = REMOTE_KEY_PRESSED; 284 *state = REMOTE_KEY_PRESSED;
203 *event = ir_codes_vp702x_table[i].keycode; 285 *event = rc_map_vp702x_table[i].keycode;
204 break; 286 break;
205 } 287 }
288 kfree(key);
206 return 0; 289 return 0;
207} 290}
208 291
209 292
210static int vp702x_read_mac_addr(struct dvb_usb_device *d,u8 mac[6]) 293static int vp702x_read_mac_addr(struct dvb_usb_device *d,u8 mac[6])
211{ 294{
212 u8 i; 295 u8 i, *buf;
296 struct vp702x_device_state *st = d->priv;
297
298 mutex_lock(&st->buf_mutex);
299 buf = st->buf;
213 for (i = 6; i < 12; i++) 300 for (i = 6; i < 12; i++)
214 vp702x_usb_in_op(d, READ_EEPROM_REQ, i, 1, &mac[i - 6], 1); 301 vp702x_usb_in_op(d, READ_EEPROM_REQ, i, 1, &buf[i - 6], 1);
302
303 memcpy(mac, buf, 6);
304 mutex_unlock(&st->buf_mutex);
215 return 0; 305 return 0;
216} 306}
217 307
@@ -221,7 +311,8 @@ static int vp702x_frontend_attach(struct dvb_usb_adapter *adap)
221 311
222 vp702x_usb_out_op(adap->dev, SET_TUNER_POWER_REQ, 0, 7, NULL, 0); 312 vp702x_usb_out_op(adap->dev, SET_TUNER_POWER_REQ, 0, 7, NULL, 0);
223 313
224 if (vp702x_usb_inout_cmd(adap->dev, GET_SYSTEM_STRING, NULL, 0, buf, 10, 10)) 314 if (vp702x_usb_inout_cmd(adap->dev, GET_SYSTEM_STRING, NULL, 0,
315 buf, 10, 10))
225 return -EIO; 316 return -EIO;
226 317
227 buf[9] = '\0'; 318 buf[9] = '\0';
@@ -240,8 +331,38 @@ static struct dvb_usb_device_properties vp702x_properties;
240static int vp702x_usb_probe(struct usb_interface *intf, 331static int vp702x_usb_probe(struct usb_interface *intf,
241 const struct usb_device_id *id) 332 const struct usb_device_id *id)
242{ 333{
243 return dvb_usb_device_init(intf, &vp702x_properties, 334 struct dvb_usb_device *d;
244 THIS_MODULE, NULL, adapter_nr); 335 struct vp702x_device_state *st;
336 int ret;
337
338 ret = dvb_usb_device_init(intf, &vp702x_properties,
339 THIS_MODULE, &d, adapter_nr);
340 if (ret)
341 goto out;
342
343 st = d->priv;
344 st->buf_len = 16;
345 st->buf = kmalloc(st->buf_len, GFP_KERNEL);
346 if (!st->buf) {
347 ret = -ENOMEM;
348 dvb_usb_device_exit(intf);
349 goto out;
350 }
351 mutex_init(&st->buf_mutex);
352
353out:
354 return ret;
355
356}
357
358static void vp702x_usb_disconnect(struct usb_interface *intf)
359{
360 struct dvb_usb_device *d = usb_get_intfdata(intf);
361 struct vp702x_device_state *st = d->priv;
362 mutex_lock(&st->buf_mutex);
363 kfree(st->buf);
364 mutex_unlock(&st->buf_mutex);
365 dvb_usb_device_exit(intf);
245} 366}
246 367
247static struct usb_device_id vp702x_usb_table [] = { 368static struct usb_device_id vp702x_usb_table [] = {
@@ -278,14 +399,14 @@ static struct dvb_usb_device_properties vp702x_properties = {
278 } 399 }
279 } 400 }
280 }, 401 },
281 .size_of_priv = sizeof(struct vp702x_state), 402 .size_of_priv = sizeof(struct vp702x_adapter_state),
282 } 403 }
283 }, 404 },
284 .read_mac_address = vp702x_read_mac_addr, 405 .read_mac_address = vp702x_read_mac_addr,
285 406
286 .rc.legacy = { 407 .rc.legacy = {
287 .rc_key_map = ir_codes_vp702x_table, 408 .rc_map_table = rc_map_vp702x_table,
288 .rc_key_map_size = ARRAY_SIZE(ir_codes_vp702x_table), 409 .rc_map_size = ARRAY_SIZE(rc_map_vp702x_table),
289 .rc_interval = 400, 410 .rc_interval = 400,
290 .rc_query = vp702x_rc_query, 411 .rc_query = vp702x_rc_query,
291 }, 412 },
@@ -307,9 +428,9 @@ static struct dvb_usb_device_properties vp702x_properties = {
307/* usb specific object needed to register this driver with the usb subsystem */ 428/* usb specific object needed to register this driver with the usb subsystem */
308static struct usb_driver vp702x_usb_driver = { 429static struct usb_driver vp702x_usb_driver = {
309 .name = "dvb_usb_vp702x", 430 .name = "dvb_usb_vp702x",
310 .probe = vp702x_usb_probe, 431 .probe = vp702x_usb_probe,
311 .disconnect = dvb_usb_device_exit, 432 .disconnect = vp702x_usb_disconnect,
312 .id_table = vp702x_usb_table, 433 .id_table = vp702x_usb_table,
313}; 434};
314 435
315/* module stuff */ 436/* module stuff */