]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blame - drivers/media/usb/dvb-usb/dib0700_core.c
media: dib0700: fix locking in dib0700_i2c_xfer_new()
[mirror_ubuntu-artful-kernel.git] / drivers / media / usb / dvb-usb / dib0700_core.c
CommitLineData
b7f54910
PB
1/* Linux driver for devices based on the DiBcom DiB0700 USB bridge
2 *
3 * This program is free software; you can redistribute it and/or modify it
4 * under the terms of the GNU General Public License as published by the Free
5 * Software Foundation, version 2.
6 *
7 * Copyright (C) 2005-6 DiBcom, SA
8 */
9#include "dib0700.h"
10
11/* debug */
12int dvb_usb_dib0700_debug;
13module_param_named(debug,dvb_usb_dib0700_debug, int, 0644);
14MODULE_PARM_DESC(debug, "set debugging level (1=info,2=fw,4=fwdata,8=data (or-able))." DVB_USB_DEBUG_STATUS);
15
acc5c9ee
OG
16static int nb_packet_buffer_size = 21;
17module_param(nb_packet_buffer_size, int, 0644);
18MODULE_PARM_DESC(nb_packet_buffer_size,
f319ed91 19 "Set the dib0700 driver data buffer size. This parameter corresponds to the number of TS packets. The actual size of the data buffer corresponds to this parameter multiplied by 188 (default: 21)");
acc5c9ee 20
78e92006
JG
21DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
22
99afb989
DH
23
24int dib0700_get_version(struct dvb_usb_device *d, u32 *hwversion,
25 u32 *romversion, u32 *ramversion, u32 *fwtype)
26{
ffa5899c
OG
27 struct dib0700_state *st = d->priv;
28 int ret;
29
bff469f4 30 if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
680417bb 31 err("could not acquire lock");
26a11eb1 32 return -EINTR;
bff469f4
OG
33 }
34
ffa5899c 35 ret = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0),
99afb989
DH
36 REQUEST_GET_VERSION,
37 USB_TYPE_VENDOR | USB_DIR_IN, 0, 0,
ffa5899c 38 st->buf, 16, USB_CTRL_GET_TIMEOUT);
acc5c9ee 39 if (hwversion != NULL)
ffa5899c
OG
40 *hwversion = (st->buf[0] << 24) | (st->buf[1] << 16) |
41 (st->buf[2] << 8) | st->buf[3];
acc5c9ee 42 if (romversion != NULL)
ffa5899c
OG
43 *romversion = (st->buf[4] << 24) | (st->buf[5] << 16) |
44 (st->buf[6] << 8) | st->buf[7];
acc5c9ee 45 if (ramversion != NULL)
ffa5899c
OG
46 *ramversion = (st->buf[8] << 24) | (st->buf[9] << 16) |
47 (st->buf[10] << 8) | st->buf[11];
acc5c9ee 48 if (fwtype != NULL)
ffa5899c
OG
49 *fwtype = (st->buf[12] << 24) | (st->buf[13] << 16) |
50 (st->buf[14] << 8) | st->buf[15];
bff469f4 51 mutex_unlock(&d->usb_mutex);
99afb989
DH
52 return ret;
53}
54
b7f54910
PB
55/* expecting rx buffer: request data[0] data[1] ... data[2] */
56static int dib0700_ctrl_wr(struct dvb_usb_device *d, u8 *tx, u8 txlen)
57{
58 int status;
59
60 deb_data(">>> ");
230b27cd 61 debug_dump(tx, txlen, deb_data);
b7f54910
PB
62
63 status = usb_control_msg(d->udev, usb_sndctrlpipe(d->udev,0),
64 tx[0], USB_TYPE_VENDOR | USB_DIR_OUT, 0, 0, tx, txlen,
65 USB_CTRL_GET_TIMEOUT);
66
67 if (status != txlen)
6958effe 68 deb_data("ep 0 write error (status = %d, len: %d)\n",status,txlen);
b7f54910
PB
69
70 return status < 0 ? status : 0;
71}
72
73/* expecting tx buffer: request data[0] ... data[n] (n <= 4) */
54d75eba 74int dib0700_ctrl_rd(struct dvb_usb_device *d, u8 *tx, u8 txlen, u8 *rx, u8 rxlen)
b7f54910
PB
75{
76 u16 index, value;
77 int status;
78
79 if (txlen < 2) {
80 err("tx buffer length is smaller than 2. Makes no sense.");
81 return -EINVAL;
82 }
83 if (txlen > 4) {
84 err("tx buffer length is larger than 4. Not supported.");
85 return -EINVAL;
86 }
87
88 deb_data(">>> ");
89 debug_dump(tx,txlen,deb_data);
90
91 value = ((txlen - 2) << 8) | tx[1];
92 index = 0;
93 if (txlen > 2)
94 index |= (tx[2] << 8);
95 if (txlen > 3)
96 index |= tx[3];
97
b7f54910
PB
98 status = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev,0), tx[0],
99 USB_TYPE_VENDOR | USB_DIR_IN, value, index, rx, rxlen,
100 USB_CTRL_GET_TIMEOUT);
101
102 if (status < 0)
6958effe 103 deb_info("ep 0 read error (status = %d)\n",status);
b7f54910
PB
104
105 deb_data("<<< ");
230b27cd 106 debug_dump(rx, rxlen, deb_data);
b7f54910
PB
107
108 return status; /* length in case of success */
109}
110
111int dib0700_set_gpio(struct dvb_usb_device *d, enum dib07x0_gpios gpio, u8 gpio_dir, u8 gpio_val)
112{
ffa5899c 113 struct dib0700_state *st = d->priv;
bff469f4
OG
114 int ret;
115
116 if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
680417bb 117 err("could not acquire lock");
26a11eb1 118 return -EINTR;
bff469f4 119 }
ffa5899c
OG
120
121 st->buf[0] = REQUEST_SET_GPIO;
122 st->buf[1] = gpio;
123 st->buf[2] = ((gpio_dir & 0x01) << 7) | ((gpio_val & 0x01) << 6);
124
125 ret = dib0700_ctrl_wr(d, st->buf, 3);
126
bff469f4 127 mutex_unlock(&d->usb_mutex);
ffa5899c 128 return ret;
b7f54910
PB
129}
130
acc5c9ee
OG
131static int dib0700_set_usb_xfer_len(struct dvb_usb_device *d, u16 nb_ts_packets)
132{
230b27cd 133 struct dib0700_state *st = d->priv;
230b27cd
DM
134 int ret;
135
136 if (st->fw_version >= 0x10201) {
bff469f4 137 if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
680417bb 138 err("could not acquire lock");
26a11eb1 139 return -EINTR;
bff469f4
OG
140 }
141
ffa5899c
OG
142 st->buf[0] = REQUEST_SET_USB_XFER_LEN;
143 st->buf[1] = (nb_ts_packets >> 8) & 0xff;
144 st->buf[2] = nb_ts_packets & 0xff;
230b27cd
DM
145
146 deb_info("set the USB xfer len to %i Ts packet\n", nb_ts_packets);
147
ffa5899c 148 ret = dib0700_ctrl_wr(d, st->buf, 3);
bff469f4 149 mutex_unlock(&d->usb_mutex);
230b27cd
DM
150 } else {
151 deb_info("this firmware does not allow to change the USB xfer len\n");
152 ret = -EIO;
153 }
154
155 return ret;
acc5c9ee
OG
156}
157
b7f54910 158/*
bdc203e1 159 * I2C master xfer function (supported in 1.20 firmware)
b7f54910 160 */
bdc203e1
DH
161static int dib0700_i2c_xfer_new(struct i2c_adapter *adap, struct i2c_msg *msg,
162 int num)
163{
164 /* The new i2c firmware messages are more reliable and in particular
165 properly support i2c read calls not preceded by a write */
166
167 struct dvb_usb_device *d = i2c_get_adapdata(adap);
ffa5899c 168 struct dib0700_state *st = d->priv;
bdc203e1
DH
169 uint8_t bus_mode = 1; /* 0=eeprom bus, 1=frontend bus */
170 uint8_t gen_mode = 0; /* 0=master i2c, 1=gpio i2c */
171 uint8_t en_start = 0;
172 uint8_t en_stop = 0;
bdc203e1
DH
173 int result, i;
174
175 /* Ensure nobody else hits the i2c bus while we're sending our
176 sequence of messages, (such as the remote control thread) */
177 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
26a11eb1 178 return -EINTR;
bdc203e1
DH
179
180 for (i = 0; i < num; i++) {
181 if (i == 0) {
182 /* First message in the transaction */
183 en_start = 1;
184 } else if (!(msg[i].flags & I2C_M_NOSTART)) {
185 /* Device supports repeated-start */
186 en_start = 1;
187 } else {
188 /* Not the first packet and device doesn't support
189 repeated start */
190 en_start = 0;
191 }
192 if (i == (num - 1)) {
193 /* Last message in the transaction */
194 en_stop = 1;
195 }
196
197 if (msg[i].flags & I2C_M_RD) {
198 /* Read request */
199 u16 index, value;
200 uint8_t i2c_dest;
201
202 i2c_dest = (msg[i].addr << 1);
203 value = ((en_start << 7) | (en_stop << 6) |
204 (msg[i].len & 0x3F)) << 8 | i2c_dest;
205 /* I2C ctrl + FE bus; */
230b27cd
DM
206 index = ((gen_mode << 6) & 0xC0) |
207 ((bus_mode << 4) & 0x30);
bdc203e1
DH
208
209 result = usb_control_msg(d->udev,
210 usb_rcvctrlpipe(d->udev, 0),
211 REQUEST_NEW_I2C_READ,
212 USB_TYPE_VENDOR | USB_DIR_IN,
fa1ecd8d 213 value, index, st->buf,
bdc203e1
DH
214 msg[i].len,
215 USB_CTRL_GET_TIMEOUT);
216 if (result < 0) {
be9bae10 217 deb_info("i2c read error (status = %d)\n", result);
d18a6ef5 218 goto unlock;
bdc203e1 219 }
d2514991 220
fa1ecd8d
MCC
221 if (msg[i].len > sizeof(st->buf)) {
222 deb_info("buffer too small to fit %d bytes\n",
223 msg[i].len);
d18a6ef5
DC
224 result = -EIO;
225 goto unlock;
fa1ecd8d
MCC
226 }
227
228 memcpy(msg[i].buf, st->buf, msg[i].len);
229
d2514991
MK
230 deb_data("<<< ");
231 debug_dump(msg[i].buf, msg[i].len, deb_data);
232
bdc203e1
DH
233 } else {
234 /* Write request */
bff469f4 235 if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
680417bb 236 err("could not acquire lock");
d18a6ef5
DC
237 result = -EINTR;
238 goto unlock;
bff469f4 239 }
ffa5899c
OG
240 st->buf[0] = REQUEST_NEW_I2C_WRITE;
241 st->buf[1] = msg[i].addr << 1;
242 st->buf[2] = (en_start << 7) | (en_stop << 6) |
bdc203e1
DH
243 (msg[i].len & 0x3F);
244 /* I2C ctrl + FE bus; */
ffa5899c 245 st->buf[3] = ((gen_mode << 6) & 0xC0) |
230b27cd 246 ((bus_mode << 4) & 0x30);
fa1ecd8d
MCC
247
248 if (msg[i].len > sizeof(st->buf) - 4) {
249 deb_info("i2c message to big: %d\n",
250 msg[i].len);
d18a6ef5
DC
251 mutex_unlock(&d->usb_mutex);
252 result = -EIO;
253 goto unlock;
fa1ecd8d
MCC
254 }
255
bdc203e1 256 /* The Actual i2c payload */
ffa5899c 257 memcpy(&st->buf[4], msg[i].buf, msg[i].len);
bdc203e1 258
d2514991 259 deb_data(">>> ");
ffa5899c 260 debug_dump(st->buf, msg[i].len + 4, deb_data);
d2514991 261
bdc203e1
DH
262 result = usb_control_msg(d->udev,
263 usb_sndctrlpipe(d->udev, 0),
264 REQUEST_NEW_I2C_WRITE,
265 USB_TYPE_VENDOR | USB_DIR_OUT,
ffa5899c 266 0, 0, st->buf, msg[i].len + 4,
bdc203e1 267 USB_CTRL_GET_TIMEOUT);
bff469f4 268 mutex_unlock(&d->usb_mutex);
bdc203e1 269 if (result < 0) {
be9bae10 270 deb_info("i2c write error (status = %d)\n", result);
bdc203e1
DH
271 break;
272 }
273 }
274 }
d18a6ef5
DC
275 result = i;
276
277unlock:
bdc203e1 278 mutex_unlock(&d->i2c_mutex);
d18a6ef5 279 return result;
bdc203e1
DH
280}
281
282/*
283 * I2C master xfer function (pre-1.20 firmware)
284 */
285static int dib0700_i2c_xfer_legacy(struct i2c_adapter *adap,
286 struct i2c_msg *msg, int num)
b7f54910
PB
287{
288 struct dvb_usb_device *d = i2c_get_adapdata(adap);
ffa5899c 289 struct dib0700_state *st = d->priv;
b7f54910 290 int i,len;
b7f54910
PB
291
292 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
26a11eb1 293 return -EINTR;
bff469f4 294 if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
680417bb 295 err("could not acquire lock");
26a11eb1
SN
296 mutex_unlock(&d->i2c_mutex);
297 return -EINTR;
bff469f4 298 }
b7f54910
PB
299
300 for (i = 0; i < num; i++) {
301 /* fill in the address */
ffa5899c 302 st->buf[1] = msg[i].addr << 1;
b7f54910 303 /* fill the buffer */
fa1ecd8d
MCC
304 if (msg[i].len > sizeof(st->buf) - 2) {
305 deb_info("i2c xfer to big: %d\n",
306 msg[i].len);
307 return -EIO;
308 }
ffa5899c 309 memcpy(&st->buf[2], msg[i].buf, msg[i].len);
b7f54910
PB
310
311 /* write/read request */
312 if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) {
ffa5899c
OG
313 st->buf[0] = REQUEST_I2C_READ;
314 st->buf[1] |= 1;
b7f54910
PB
315
316 /* special thing in the current firmware: when length is zero the read-failed */
ffa5899c 317 len = dib0700_ctrl_rd(d, st->buf, msg[i].len + 2,
bd1f976c 318 st->buf, msg[i + 1].len);
ffa5899c 319 if (len <= 0) {
8db12cdf 320 deb_info("I2C read failed on address 0x%02x\n",
ffa5899c 321 msg[i].addr);
b7f54910 322 break;
303cbeaa 323 }
b7f54910 324
fa1ecd8d
MCC
325 if (msg[i + 1].len > sizeof(st->buf)) {
326 deb_info("i2c xfer buffer to small for %d\n",
327 msg[i].len);
328 return -EIO;
329 }
bd1f976c
MCC
330 memcpy(msg[i + 1].buf, st->buf, msg[i + 1].len);
331
b7f54910
PB
332 msg[i+1].len = len;
333
334 i++;
335 } else {
ffa5899c
OG
336 st->buf[0] = REQUEST_I2C_WRITE;
337 if (dib0700_ctrl_wr(d, st->buf, msg[i].len + 2) < 0)
b7f54910
PB
338 break;
339 }
340 }
bff469f4 341 mutex_unlock(&d->usb_mutex);
b7f54910 342 mutex_unlock(&d->i2c_mutex);
ffa5899c 343
b7f54910
PB
344 return i;
345}
346
bdc203e1
DH
347static int dib0700_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msg,
348 int num)
349{
350 struct dvb_usb_device *d = i2c_get_adapdata(adap);
351 struct dib0700_state *st = d->priv;
352
353 if (st->fw_use_new_i2c_api == 1) {
354 /* User running at least fw 1.20 */
355 return dib0700_i2c_xfer_new(adap, msg, num);
356 } else {
357 /* Use legacy calls */
358 return dib0700_i2c_xfer_legacy(adap, msg, num);
359 }
360}
361
b7f54910
PB
362static u32 dib0700_i2c_func(struct i2c_adapter *adapter)
363{
364 return I2C_FUNC_I2C;
365}
366
367struct i2c_algorithm dib0700_i2c_algo = {
368 .master_xfer = dib0700_i2c_xfer,
369 .functionality = dib0700_i2c_func,
370};
371
6958effe
PB
372int dib0700_identify_state(struct usb_device *udev, struct dvb_usb_device_properties *props,
373 struct dvb_usb_device_description **desc, int *cold)
374{
ffa5899c
OG
375 s16 ret;
376 u8 *b;
377
378 b = kmalloc(16, GFP_KERNEL);
379 if (!b)
380 return -ENOMEM;
381
382
383 ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
a75763ff
PB
384 REQUEST_GET_VERSION, USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, b, 16, USB_CTRL_GET_TIMEOUT);
385
386 deb_info("FW GET_VERSION length: %d\n",ret);
387
388 *cold = ret <= 0;
6958effe 389 deb_info("cold: %d\n", *cold);
ffa5899c
OG
390
391 kfree(b);
6958effe
PB
392 return 0;
393}
394
a75763ff
PB
395static int dib0700_set_clock(struct dvb_usb_device *d, u8 en_pll,
396 u8 pll_src, u8 pll_range, u8 clock_gpio3, u16 pll_prediv,
397 u16 pll_loopdiv, u16 free_div, u16 dsuScaler)
398{
ffa5899c 399 struct dib0700_state *st = d->priv;
bff469f4
OG
400 int ret;
401
402 if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
680417bb 403 err("could not acquire lock");
26a11eb1 404 return -EINTR;
bff469f4 405 }
ffa5899c
OG
406
407 st->buf[0] = REQUEST_SET_CLOCK;
408 st->buf[1] = (en_pll << 7) | (pll_src << 6) |
409 (pll_range << 5) | (clock_gpio3 << 4);
410 st->buf[2] = (pll_prediv >> 8) & 0xff; /* MSB */
411 st->buf[3] = pll_prediv & 0xff; /* LSB */
412 st->buf[4] = (pll_loopdiv >> 8) & 0xff; /* MSB */
413 st->buf[5] = pll_loopdiv & 0xff; /* LSB */
414 st->buf[6] = (free_div >> 8) & 0xff; /* MSB */
415 st->buf[7] = free_div & 0xff; /* LSB */
416 st->buf[8] = (dsuScaler >> 8) & 0xff; /* MSB */
417 st->buf[9] = dsuScaler & 0xff; /* LSB */
418
419 ret = dib0700_ctrl_wr(d, st->buf, 10);
bff469f4 420 mutex_unlock(&d->usb_mutex);
ffa5899c
OG
421
422 return ret;
a75763ff
PB
423}
424
7757ddda
OG
425int dib0700_set_i2c_speed(struct dvb_usb_device *d, u16 scl_kHz)
426{
ffa5899c 427 struct dib0700_state *st = d->priv;
7757ddda 428 u16 divider;
bff469f4 429 int ret;
7757ddda
OG
430
431 if (scl_kHz == 0)
432 return -EINVAL;
433
bff469f4 434 if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
680417bb 435 err("could not acquire lock");
26a11eb1 436 return -EINTR;
bff469f4
OG
437 }
438
ffa5899c 439 st->buf[0] = REQUEST_SET_I2C_PARAM;
7757ddda 440 divider = (u16) (30000 / scl_kHz);
ffa5899c
OG
441 st->buf[1] = 0;
442 st->buf[2] = (u8) (divider >> 8);
443 st->buf[3] = (u8) (divider & 0xff);
7757ddda 444 divider = (u16) (72000 / scl_kHz);
ffa5899c
OG
445 st->buf[4] = (u8) (divider >> 8);
446 st->buf[5] = (u8) (divider & 0xff);
7757ddda 447 divider = (u16) (72000 / scl_kHz); /* clock: 72MHz */
ffa5899c
OG
448 st->buf[6] = (u8) (divider >> 8);
449 st->buf[7] = (u8) (divider & 0xff);
7757ddda 450
b4d6046e 451 deb_info("setting I2C speed: %04x %04x %04x (%d kHz).",
ffa5899c
OG
452 (st->buf[2] << 8) | (st->buf[3]), (st->buf[4] << 8) |
453 st->buf[5], (st->buf[6] << 8) | st->buf[7], scl_kHz);
bff469f4
OG
454
455 ret = dib0700_ctrl_wr(d, st->buf, 8);
456 mutex_unlock(&d->usb_mutex);
457
458 return ret;
7757ddda
OG
459}
460
461
a75763ff
PB
462int dib0700_ctrl_clock(struct dvb_usb_device *d, u32 clk_MHz, u8 clock_out_gp3)
463{
464 switch (clk_MHz) {
465 case 72: dib0700_set_clock(d, 1, 0, 1, clock_out_gp3, 2, 24, 0, 0x4c); break;
466 default: return -EINVAL;
467 }
468 return 0;
469}
470
b7f54910
PB
471static int dib0700_jumpram(struct usb_device *udev, u32 address)
472{
ffa5899c
OG
473 int ret = 0, actlen;
474 u8 *buf;
475
476 buf = kmalloc(8, GFP_KERNEL);
477 if (!buf)
478 return -ENOMEM;
479 buf[0] = REQUEST_JUMPRAM;
480 buf[1] = 0;
481 buf[2] = 0;
482 buf[3] = 0;
483 buf[4] = (address >> 24) & 0xff;
484 buf[5] = (address >> 16) & 0xff;
485 buf[6] = (address >> 8) & 0xff;
486 buf[7] = address & 0xff;
b7f54910
PB
487
488 if ((ret = usb_bulk_msg(udev, usb_sndbulkpipe(udev, 0x01),buf,8,&actlen,1000)) < 0) {
489 deb_fw("jumpram to 0x%x failed\n",address);
ffa5899c 490 goto out;
b7f54910
PB
491 }
492 if (actlen != 8) {
493 deb_fw("jumpram to 0x%x failed\n",address);
ffa5899c
OG
494 ret = -EIO;
495 goto out;
b7f54910 496 }
ffa5899c
OG
497out:
498 kfree(buf);
499 return ret;
b7f54910
PB
500}
501
502int dib0700_download_firmware(struct usb_device *udev, const struct firmware *fw)
503{
504 struct hexline hx;
acc5c9ee 505 int pos = 0, ret, act_len, i, adap_num;
ffa5899c 506 u8 *buf;
acc5c9ee 507 u32 fw_version;
b7f54910 508
ffa5899c
OG
509 buf = kmalloc(260, GFP_KERNEL);
510 if (!buf)
511 return -ENOMEM;
b7f54910
PB
512
513 while ((ret = dvb_usb_get_hexline(fw, &hx, &pos)) > 0) {
230b27cd
DM
514 deb_fwdata("writing to address 0x%08x (buffer: 0x%02x %02x)\n",
515 hx.addr, hx.len, hx.chk);
b7f54910
PB
516
517 buf[0] = hx.len;
5bc63607
PB
518 buf[1] = (hx.addr >> 8) & 0xff;
519 buf[2] = hx.addr & 0xff;
b7f54910
PB
520 buf[3] = hx.type;
521 memcpy(&buf[4],hx.data,hx.len);
522 buf[4+hx.len] = hx.chk;
523
524 ret = usb_bulk_msg(udev,
525 usb_sndbulkpipe(udev, 0x01),
526 buf,
527 hx.len + 5,
528 &act_len,
529 1000);
530
531 if (ret < 0) {
532 err("firmware download failed at %d with %d",pos,ret);
ffa5899c 533 goto out;
b7f54910
PB
534 }
535 }
536
537 if (ret == 0) {
538 /* start the firmware */
6958effe 539 if ((ret = dib0700_jumpram(udev, 0x70000000)) == 0) {
b7f54910 540 info("firmware started successfully.");
a75763ff 541 msleep(500);
6958effe 542 }
b7f54910
PB
543 } else
544 ret = -EIO;
545
acc5c9ee
OG
546 /* the number of ts packet has to be at least 1 */
547 if (nb_packet_buffer_size < 1)
548 nb_packet_buffer_size = 1;
549
bad7de74 550 /* get the firmware version */
acc5c9ee
OG
551 usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
552 REQUEST_GET_VERSION,
553 USB_TYPE_VENDOR | USB_DIR_IN, 0, 0,
ffa5899c
OG
554 buf, 16, USB_CTRL_GET_TIMEOUT);
555 fw_version = (buf[8] << 24) | (buf[9] << 16) | (buf[10] << 8) | buf[11];
acc5c9ee
OG
556
557 /* set the buffer size - DVB-USB is allocating URB buffers
558 * only after the firwmare download was successful */
559 for (i = 0; i < dib0700_device_count; i++) {
560 for (adap_num = 0; adap_num < dib0700_devices[i].num_adapters;
561 adap_num++) {
230b27cd 562 if (fw_version >= 0x10201) {
77eed219 563 dib0700_devices[i].adapter[adap_num].fe[0].stream.u.bulk.buffersize = 188*nb_packet_buffer_size;
230b27cd 564 } else {
acc5c9ee
OG
565 /* for fw version older than 1.20.1,
566 * the buffersize has to be n times 512 */
77eed219
MK
567 dib0700_devices[i].adapter[adap_num].fe[0].stream.u.bulk.buffersize = ((188*nb_packet_buffer_size+188/2)/512)*512;
568 if (dib0700_devices[i].adapter[adap_num].fe[0].stream.u.bulk.buffersize < 512)
569 dib0700_devices[i].adapter[adap_num].fe[0].stream.u.bulk.buffersize = 512;
acc5c9ee
OG
570 }
571 }
572 }
ffa5899c
OG
573out:
574 kfree(buf);
b7f54910
PB
575 return ret;
576}
577
578int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
579{
580 struct dib0700_state *st = adap->dev->priv;
acc5c9ee
OG
581 int ret;
582
583 if ((onoff != 0) && (st->fw_version >= 0x10201)) {
584 /* for firmware later than 1.20.1,
585 * the USB xfer length can be set */
586 ret = dib0700_set_usb_xfer_len(adap->dev,
587 st->nb_packet_buffer_size);
588 if (ret < 0) {
589 deb_info("can not set the USB xfer len\n");
590 return ret;
591 }
592 }
b7f54910 593
a96fbe04 594 mutex_lock(&adap->dev->usb_mutex);
bff469f4 595
ffa5899c
OG
596 st->buf[0] = REQUEST_ENABLE_VIDEO;
597 /* this bit gives a kind of command,
598 * rather than enabling something or not */
599 st->buf[1] = (onoff << 4) | 0x00;
cb22cb52
DH
600
601 if (st->disable_streaming_master_mode == 1)
ffa5899c 602 st->buf[2] = 0x00;
cb22cb52 603 else
ffa5899c 604 st->buf[2] = 0x01 << 4; /* Master mode */
cb22cb52 605
ffa5899c 606 st->buf[3] = 0x00;
b7f54910
PB
607
608 deb_info("modifying (%d) streaming state for %d\n", onoff, adap->id);
609
7757ddda 610 st->channel_state &= ~0x3;
77eed219
MK
611 if ((adap->fe_adap[0].stream.props.endpoint != 2)
612 && (adap->fe_adap[0].stream.props.endpoint != 3)) {
613 deb_info("the endpoint number (%i) is not correct, use the adapter id instead", adap->fe_adap[0].stream.props.endpoint);
7757ddda
OG
614 if (onoff)
615 st->channel_state |= 1 << (adap->id);
616 else
f85ed0ce 617 st->channel_state |= 1 << ~(adap->id);
b4d6046e 618 } else {
7757ddda 619 if (onoff)
77eed219 620 st->channel_state |= 1 << (adap->fe_adap[0].stream.props.endpoint-2);
7757ddda 621 else
77eed219 622 st->channel_state |= 1 << (3-adap->fe_adap[0].stream.props.endpoint);
7757ddda 623 }
b7f54910 624
ffa5899c 625 st->buf[2] |= st->channel_state;
b7f54910 626
ffa5899c 627 deb_info("data for streaming: %x %x\n", st->buf[1], st->buf[2]);
b7f54910 628
bff469f4
OG
629 ret = dib0700_ctrl_wr(adap->dev, st->buf, 4);
630 mutex_unlock(&adap->dev->usb_mutex);
631
632 return ret;
b7f54910
PB
633}
634
c003ab1b 635int dib0700_change_protocol(struct rc_dev *rc, u64 *rc_type)
0ffd1ab3 636{
d8b4b582 637 struct dvb_usb_device *d = rc->priv;
0ffd1ab3 638 struct dib0700_state *st = d->priv;
0ffd1ab3
MCC
639 int new_proto, ret;
640
bff469f4 641 if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
680417bb 642 err("could not acquire lock");
26a11eb1 643 return -EINTR;
bff469f4
OG
644 }
645
ffa5899c
OG
646 st->buf[0] = REQUEST_SET_RC;
647 st->buf[1] = 0;
648 st->buf[2] = 0;
649
0ffd1ab3 650 /* Set the IR mode */
c003ab1b 651 if (*rc_type & RC_BIT_RC5) {
0ffd1ab3 652 new_proto = 1;
c003ab1b
DH
653 *rc_type = RC_BIT_RC5;
654 } else if (*rc_type & RC_BIT_NEC) {
0ffd1ab3 655 new_proto = 0;
c003ab1b
DH
656 *rc_type = RC_BIT_NEC;
657 } else if (*rc_type & RC_BIT_RC6_MCE) {
bff469f4
OG
658 if (st->fw_version < 0x10200) {
659 ret = -EINVAL;
660 goto out;
661 }
0ffd1ab3 662 new_proto = 2;
c003ab1b 663 *rc_type = RC_BIT_RC6_MCE;
bff469f4
OG
664 } else {
665 ret = -EINVAL;
666 goto out;
667 }
0ffd1ab3 668
ffa5899c 669 st->buf[1] = new_proto;
0ffd1ab3 670
ffa5899c 671 ret = dib0700_ctrl_wr(d, st->buf, 3);
0ffd1ab3
MCC
672 if (ret < 0) {
673 err("ir protocol setup failed");
bff469f4 674 goto out;
0ffd1ab3
MCC
675 }
676
c003ab1b 677 d->props.rc.core.protocol = *rc_type;
0ffd1ab3 678
bff469f4
OG
679out:
680 mutex_unlock(&d->usb_mutex);
0ffd1ab3
MCC
681 return ret;
682}
683
6a207100
DH
684/* This is the structure of the RC response packet starting in firmware 1.20 */
685struct dib0700_rc_response {
686 u8 report_id;
687 u8 data_state;
4d298b85
DH
688 union {
689 struct {
690 u8 system;
691 u8 not_system;
692 u8 data;
693 u8 not_data;
694 } nec;
695 struct {
696 u8 not_used;
697 u8 system;
698 u8 data;
699 u8 not_data;
700 } rc5;
701 };
6a207100
DH
702};
703#define RC_MSG_SIZE_V1_20 6
704
705static void dib0700_rc_urb_completion(struct urb *purb)
706{
707 struct dvb_usb_device *d = purb->context;
d3c501d1 708 struct dib0700_rc_response *poll_reply;
120703f9 709 enum rc_type protocol;
ba13e98f 710 u32 keycode;
72b39310 711 u8 toggle;
6a207100
DH
712
713 deb_info("%s()\n", __func__);
d8b4b582 714 if (d->rc_dev == NULL) {
6a207100 715 /* This will occur if disable_rc_polling=1 */
d3db22e1 716 kfree(purb->transfer_buffer);
6a207100
DH
717 usb_free_urb(purb);
718 return;
719 }
720
d3c501d1 721 poll_reply = purb->transfer_buffer;
6a207100
DH
722
723 if (purb->status < 0) {
724 deb_info("discontinuing polling\n");
d3db22e1 725 kfree(purb->transfer_buffer);
6a207100
DH
726 usb_free_urb(purb);
727 return;
728 }
729
730 if (purb->actual_length != RC_MSG_SIZE_V1_20) {
731 deb_info("malformed rc msg size=%d\n", purb->actual_length);
732 goto resubmit;
733 }
734
d3c501d1
MCC
735 deb_data("IR ID = %02X state = %02X System = %02X %02X Cmd = %02X %02X (len %d)\n",
736 poll_reply->report_id, poll_reply->data_state,
4d298b85
DH
737 poll_reply->nec.system, poll_reply->nec.not_system,
738 poll_reply->nec.data, poll_reply->nec.not_data,
d3c501d1 739 purb->actual_length);
6a207100 740
0ffd1ab3 741 switch (d->props.rc.core.protocol) {
c003ab1b 742 case RC_BIT_NEC:
72b39310 743 toggle = 0;
6a207100
DH
744
745 /* NEC protocol sends repeat code as 0 0 0 FF */
4d298b85
DH
746 if (poll_reply->nec.system == 0x00 &&
747 poll_reply->nec.not_system == 0x00 &&
748 poll_reply->nec.data == 0x00 &&
749 poll_reply->nec.not_data == 0xff) {
d3c501d1 750 poll_reply->data_state = 2;
ba13e98f
SY
751 rc_repeat(d->rc_dev);
752 goto resubmit;
6a207100 753 }
72b39310 754
4d298b85 755 if ((poll_reply->nec.data ^ poll_reply->nec.not_data) != 0xff) {
af3a4a9b 756 deb_data("NEC32 protocol\n");
4d298b85
DH
757 keycode = RC_SCANCODE_NEC32(poll_reply->nec.system << 24 |
758 poll_reply->nec.not_system << 16 |
759 poll_reply->nec.data << 8 |
760 poll_reply->nec.not_data);
2ceeca04 761 protocol = RC_TYPE_NEC32;
4d298b85 762 } else if ((poll_reply->nec.system ^ poll_reply->nec.not_system) != 0xff) {
d3c501d1 763 deb_data("NEC extended protocol\n");
4d298b85
DH
764 keycode = RC_SCANCODE_NECX(poll_reply->nec.system << 8 |
765 poll_reply->nec.not_system,
766 poll_reply->nec.data);
120703f9 767
2ceeca04 768 protocol = RC_TYPE_NECX;
d3c501d1
MCC
769 } else {
770 deb_data("NEC normal protocol\n");
4d298b85
DH
771 keycode = RC_SCANCODE_NEC(poll_reply->nec.system,
772 poll_reply->nec.data);
2ceeca04 773 protocol = RC_TYPE_NEC;
d3c501d1
MCC
774 }
775
6a207100
DH
776 break;
777 default:
d3c501d1 778 deb_data("RC5 protocol\n");
120703f9 779 protocol = RC_TYPE_RC5;
d3c501d1 780 toggle = poll_reply->report_id;
4d298b85
DH
781 keycode = RC_SCANCODE_RC5(poll_reply->rc5.system, poll_reply->rc5.data);
782
783 if ((poll_reply->rc5.data ^ poll_reply->rc5.not_data) != 0xff) {
784 /* Key failed integrity check */
785 err("key failed integrity check: %02x %02x %02x %02x",
786 poll_reply->rc5.not_used, poll_reply->rc5.system,
787 poll_reply->rc5.data, poll_reply->rc5.not_data);
788 goto resubmit;
789 }
72b39310 790
6a207100
DH
791 break;
792 }
793
120703f9 794 rc_keydown(d->rc_dev, protocol, keycode, toggle);
6a207100
DH
795
796resubmit:
797 /* Clean the buffer before we requeue */
798 memset(purb->transfer_buffer, 0, RC_MSG_SIZE_V1_20);
799
800 /* Requeue URB */
801 usb_submit_urb(purb, GFP_ATOMIC);
802}
803
c4018fa2 804int dib0700_rc_setup(struct dvb_usb_device *d, struct usb_interface *intf)
89f4267d 805{
6a207100 806 struct dib0700_state *st = d->priv;
6a207100 807 struct urb *purb;
c4018fa2
MCC
808 const struct usb_endpoint_descriptor *e;
809 int ret, rc_ep = 1;
810 unsigned int pipe = 0;
6a207100 811
0ffd1ab3 812 /* Poll-based. Don't initialize bulk mode */
c4018fa2 813 if (st->fw_version < 0x10200 || !intf)
6a207100
DH
814 return 0;
815
816 /* Starting in firmware 1.20, the RC info is provided on a bulk pipe */
c4018fa2 817
d5823511
JH
818 if (intf->altsetting[0].desc.bNumEndpoints < rc_ep + 1)
819 return -ENODEV;
820
6a207100 821 purb = usb_alloc_urb(0, GFP_KERNEL);
abbde78f 822 if (purb == NULL)
8871c85d 823 return -ENOMEM;
6a207100
DH
824
825 purb->transfer_buffer = kzalloc(RC_MSG_SIZE_V1_20, GFP_KERNEL);
826 if (purb->transfer_buffer == NULL) {
24ed693d 827 err("rc kzalloc failed");
6a207100 828 usb_free_urb(purb);
8871c85d 829 return -ENOMEM;
6a207100
DH
830 }
831
832 purb->status = -EINPROGRESS;
c4018fa2
MCC
833
834 /*
835 * Some devices like the Hauppauge NovaTD model 52009 use an interrupt
836 * endpoint, while others use a bulk one.
837 */
838 e = &intf->altsetting[0].endpoint[rc_ep].desc;
839 if (usb_endpoint_dir_in(e)) {
840 if (usb_endpoint_xfer_bulk(e)) {
841 pipe = usb_rcvbulkpipe(d->udev, rc_ep);
842 usb_fill_bulk_urb(purb, d->udev, pipe,
843 purb->transfer_buffer,
844 RC_MSG_SIZE_V1_20,
845 dib0700_rc_urb_completion, d);
846
847 } else if (usb_endpoint_xfer_int(e)) {
848 pipe = usb_rcvintpipe(d->udev, rc_ep);
849 usb_fill_int_urb(purb, d->udev, pipe,
850 purb->transfer_buffer,
851 RC_MSG_SIZE_V1_20,
852 dib0700_rc_urb_completion, d, 1);
853 }
854 }
855
856 if (!pipe) {
857 err("There's no endpoint for remote controller");
858 kfree(purb->transfer_buffer);
859 usb_free_urb(purb);
860 return 0;
861 }
6a207100
DH
862
863 ret = usb_submit_urb(purb, GFP_ATOMIC);
d3db22e1 864 if (ret) {
24ed693d 865 err("rc submit urb failed");
d3db22e1
JD
866 kfree(purb->transfer_buffer);
867 usb_free_urb(purb);
868 }
6a207100 869
8871c85d 870 return ret;
89f4267d
JG
871}
872
b7f54910
PB
873static int dib0700_probe(struct usb_interface *intf,
874 const struct usb_device_id *id)
875{
876 int i;
89f4267d 877 struct dvb_usb_device *dev;
b7f54910
PB
878
879 for (i = 0; i < dib0700_device_count; i++)
78e92006 880 if (dvb_usb_device_init(intf, &dib0700_devices[i], THIS_MODULE,
acc5c9ee
OG
881 &dev, adapter_nr) == 0) {
882 struct dib0700_state *st = dev->priv;
883 u32 hwversion, romversion, fw_version, fwtype;
884
885 dib0700_get_version(dev, &hwversion, &romversion,
886 &fw_version, &fwtype);
887
888 deb_info("Firmware version: %x, %d, 0x%x, %d\n",
889 hwversion, romversion, fw_version, fwtype);
890
891 st->fw_version = fw_version;
892 st->nb_packet_buffer_size = (u32)nb_packet_buffer_size;
893
72b39310
MCC
894 /* Disable polling mode on newer firmwares */
895 if (st->fw_version >= 0x10200)
896 dev->props.rc.core.bulk_mode = true;
897 else
898 dev->props.rc.core.bulk_mode = false;
899
c4018fa2 900 dib0700_rc_setup(dev, intf);
acc5c9ee 901
b7f54910 902 return 0;
89f4267d 903 }
b7f54910
PB
904
905 return -ENODEV;
906}
907
908static struct usb_driver dib0700_driver = {
909 .name = "dvb_usb_dib0700",
910 .probe = dib0700_probe,
911 .disconnect = dvb_usb_device_exit,
912 .id_table = dib0700_usb_id_table,
913};
914
ecb3b2b3 915module_usb_driver(dib0700_driver);
b7f54910 916
68dc8bc5 917MODULE_FIRMWARE("dvb-usb-dib0700-1.20.fw");
99e44da7 918MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@posteo.de>");
b7f54910
PB
919MODULE_DESCRIPTION("Driver for devices based on DiBcom DiB0700 - USB bridge");
920MODULE_VERSION("1.0");
921MODULE_LICENSE("GPL");