aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/media/dvb/dvb-usb/az6007.c148
1 files changed, 83 insertions, 65 deletions
diff --git a/drivers/media/dvb/dvb-usb/az6007.c b/drivers/media/dvb/dvb-usb/az6007.c
index 81fdc90be449..f0e4c013bb5d 100644
--- a/drivers/media/dvb/dvb-usb/az6007.c
+++ b/drivers/media/dvb/dvb-usb/az6007.c
@@ -54,12 +54,16 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
54struct az6007_device_state { 54struct az6007_device_state {
55 struct dvb_ca_en50221 ca; 55 struct dvb_ca_en50221 ca;
56 struct mutex ca_mutex; 56 struct mutex ca_mutex;
57 u8 power_state; 57 unsigned warm : 1;
58 58
59 /* Due to DRX-K - probably need changes */ 59 /* Due to DRX-K - probably need changes */
60 int (*gate_ctrl) (struct dvb_frontend *, int); 60 int (*gate_ctrl) (struct dvb_frontend *, int);
61 struct semaphore pll_mutex; 61 struct semaphore pll_mutex;
62 bool tuner_attached; 62 bool tuner_attached;
63
64 unsigned char data[4096];
65
66 struct usb_data_stream *stream;
63}; 67};
64 68
65static struct drxk_config terratec_h7_drxk = { 69static struct drxk_config terratec_h7_drxk = {
@@ -71,7 +75,7 @@ static struct drxk_config terratec_h7_drxk = {
71 .no_i2c_bridge = false, 75 .no_i2c_bridge = false,
72 .chunk_size = 64, 76 .chunk_size = 64,
73 .mpeg_out_clk_strength = 0x02, 77 .mpeg_out_clk_strength = 0x02,
74 .microcode_name = "dvb-usb-terratec-h7-az6007.fw", 78 .microcode_name = "dvb-usb-terratec-h7-drxk.fw",
75}; 79};
76 80
77static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable) 81static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable)
@@ -162,7 +166,9 @@ static int az6007_write(struct usb_device *udev, u8 req, u16 value,
162 166
163static int az6007_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) 167static int az6007_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
164{ 168{
165 return 0; 169 deb_info("%s: %s", __func__, onoff ? "enable" : "disable");
170
171 return az6007_write(adap->dev->udev, 0xbc, onoff, 0, NULL, 0);
166} 172}
167 173
168/* keys for the enclosed remote control */ 174/* keys for the enclosed remote control */
@@ -236,46 +242,6 @@ static int az6007_read_mac_addr(struct dvb_usb_device *d, u8 mac[6])
236 return ret; 242 return ret;
237} 243}
238 244
239static int az6007_frontend_poweron(struct dvb_usb_adapter *adap)
240{
241 int ret;
242 struct usb_device *udev = adap->dev->udev;
243
244 deb_info("%s: adap=%p adap->dev=%p\n", __func__, adap, adap->dev);
245
246 ret = az6007_write(udev, AZ6007_POWER, 0, 2, NULL, 0);
247 if (ret < 0)
248 goto error;
249 msleep(150);
250 ret = az6007_write(udev, AZ6007_POWER, 1, 4, NULL, 0);
251 if (ret < 0)
252 goto error;
253 msleep(100);
254 ret = az6007_write(udev, AZ6007_POWER, 1, 3, NULL, 0);
255 if (ret < 0)
256 goto error;
257 msleep(100);
258 ret = az6007_write(udev, AZ6007_POWER, 1, 4, NULL, 0);
259 if (ret < 0)
260 goto error;
261 msleep(100);
262 ret = az6007_write(udev, FX2_SCON1, 0, 3, NULL, 0);
263 if (ret < 0)
264 goto error;
265 msleep (10);
266 ret = az6007_write(udev, FX2_SCON1, 1, 3, NULL, 0);
267 if (ret < 0)
268 goto error;
269 msleep (10);
270 ret = az6007_write(udev, AZ6007_POWER, 0, 0, NULL, 0);
271
272error:
273 if (ret < 0)
274 err("%s failed with error %d", __func__, ret);
275
276 return ret;
277}
278
279static int az6007_led_on_off(struct usb_interface *intf, int onoff) 245static int az6007_led_on_off(struct usb_interface *intf, int onoff)
280{ 246{
281 struct usb_device *udev = interface_to_usbdev(intf); 247 struct usb_device *udev = interface_to_usbdev(intf);
@@ -293,9 +259,8 @@ static int az6007_frontend_attach(struct dvb_usb_adapter *adap)
293 259
294 BUG_ON(!st); 260 BUG_ON(!st);
295 261
296 az6007_frontend_poweron(adap); 262 deb_info("attaching demod drxk");
297 263
298 info("attaching demod drxk");
299 adap->fe_adap[0].fe = dvb_attach(drxk_attach, &terratec_h7_drxk, 264 adap->fe_adap[0].fe = dvb_attach(drxk_attach, &terratec_h7_drxk,
300 &adap->dev->i2c_adap); 265 &adap->dev->i2c_adap);
301 if (!adap->fe_adap[0].fe) 266 if (!adap->fe_adap[0].fe)
@@ -319,11 +284,11 @@ static int az6007_tuner_attach(struct dvb_usb_adapter *adap)
319 284
320 st->tuner_attached = true; 285 st->tuner_attached = true;
321 286
322 info("attaching tuner mt2063"); 287 deb_info("attaching tuner mt2063");
323 /* Attach mt2063 to DVB-C frontend */ 288 /* Attach mt2063 to DVB-C frontend */
324 if (adap->fe_adap[0].fe->ops.i2c_gate_ctrl) 289 if (adap->fe_adap[0].fe->ops.i2c_gate_ctrl)
325 adap->fe_adap[0].fe->ops.i2c_gate_ctrl(adap->fe_adap[0].fe, 1); 290 adap->fe_adap[0].fe->ops.i2c_gate_ctrl(adap->fe_adap[0].fe, 1);
326 if (!dvb_attach(mt2063_attach, adap->fe_adap[0].fe, 291 if (!dvb_attach(mt2063_attach, adap->fe_adap[0].fe,
327 &az6007_mt2063_config, 292 &az6007_mt2063_config,
328 &adap->dev->i2c_adap)) 293 &adap->dev->i2c_adap))
329 return -EINVAL; 294 return -EINVAL;
@@ -336,22 +301,69 @@ static int az6007_tuner_attach(struct dvb_usb_adapter *adap)
336 301
337int az6007_power_ctrl(struct dvb_usb_device *d, int onoff) 302int az6007_power_ctrl(struct dvb_usb_device *d, int onoff)
338{ 303{
339 if (!onoff) 304 struct az6007_device_state *st = d->priv;
340 return 0; 305 struct usb_device *udev = d->udev;
306 int ret;
307
308 deb_info("%s()\n", __func__);
309
310 if (!st->warm) {
311 u8 data[6];
312
313 az6007_read(udev, FX2_OED, 1, 0, data, 1); /* {0x01} */
314 az6007_read(udev, AZ6007_READ_DATA, 0, 8160, data, 1); /* {0x20} */
315 az6007_read(udev, AZ6007_READ_DATA, 0, 0, data, 5); /* {0x00, 0x00, 0x00, 0x00, 0x0a} */
316 az6007_read(udev, AZ6007_READ_DATA, 0, 4080, data, 6); /* {0x00, 0x08, 0x00, 0x0c, 0x22, 0x38} */
317
318 ret = az6007_write(udev, AZ6007_POWER, 0, 2, NULL, 0);
319 if (ret < 0)
320 return ret;
321 msleep(60);
322 ret = az6007_write(udev, AZ6007_POWER, 1, 4, NULL, 0);
323 if (ret < 0)
324 return ret;
325 msleep(100);
326 ret = az6007_write(udev, AZ6007_POWER, 1, 3, NULL, 0);
327 if (ret < 0)
328 return ret;
329 msleep(20);
330 ret = az6007_write(udev, AZ6007_POWER, 1, 4, NULL, 0);
331 if (ret < 0)
332 return ret;
333
334 msleep(400);
335 ret = az6007_write(udev, FX2_SCON1, 0, 3, NULL, 0);
336 if (ret < 0)
337 return ret;
338 msleep (150);
339 ret = az6007_write(udev, FX2_SCON1, 1, 3, NULL, 0);
340 if (ret < 0)
341 return ret;
342 msleep (430);
343 ret = az6007_write(udev, AZ6007_POWER, 0, 0, NULL, 0);
344 if (ret < 0)
345 return ret;
341 346
347 st->warm = true;
342 348
343 info("Sending poweron sequence"); 349 return 0;
350 }
344 351
345 az6007_write(d->udev, AZ6007_TS_THROUGH, 0, 0, NULL, 0); 352 if (!onoff)
353 return 0;
354
355 az6007_write(udev, AZ6007_POWER, 0, 0, NULL, 0);
356 az6007_write(udev, AZ6007_TS_THROUGH, 0, 0, NULL, 0);
346 357
347#if 0 358#if 0
348 // Seems to be a poweroff sequence 359 // Seems to be a poweroff sequence
349 az6007_write(d->udev, 0xbc, 1, 3, NULL, 0); 360 az6007_write(udev, 0xbc, 1, 3, NULL, 0);
350 az6007_write(d->udev, 0xbc, 1, 4, NULL, 0); 361 az6007_write(udev, 0xbc, 1, 4, NULL, 0);
351 az6007_write(d->udev, 0xc0, 0, 3, NULL, 0); 362 az6007_write(udev, 0xc0, 0, 3, NULL, 0);
352 az6007_write(d->udev, 0xc0, 1, 3, NULL, 0); 363 az6007_write(udev, 0xc0, 1, 3, NULL, 0);
353 az6007_write(d->udev, 0xbc, 0, 1, NULL, 0); 364 az6007_write(udev, 0xbc, 0, 1, NULL, 0);
354#endif 365#endif
366
355 return 0; 367 return 0;
356} 368}
357 369
@@ -367,13 +379,13 @@ static int az6007_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],
367 int num) 379 int num)
368{ 380{
369 struct dvb_usb_device *d = i2c_get_adapdata(adap); 381 struct dvb_usb_device *d = i2c_get_adapdata(adap);
382 struct az6007_device_state *st = d->priv;
370 int i, j, len; 383 int i, j, len;
371 int ret = 0; 384 int ret = 0;
372 u16 index; 385 u16 index;
373 u16 value; 386 u16 value;
374 int length; 387 int length;
375 u8 req, addr; 388 u8 req, addr;
376 u8 data[512];
377 389
378 if (mutex_lock_interruptible(&d->i2c_mutex) < 0) 390 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
379 return -EAGAIN; 391 return -EAGAIN;
@@ -399,11 +411,11 @@ static int az6007_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],
399 value = addr | (1 << 8); 411 value = addr | (1 << 8);
400 length = 6 + msgs[i + 1].len; 412 length = 6 + msgs[i + 1].len;
401 len = msgs[i + 1].len; 413 len = msgs[i + 1].len;
402 ret = az6007_read(d->udev, req, value, index, data, 414 ret = az6007_read(d->udev, req, value, index, st->data,
403 length); 415 length);
404 if (ret >= len) { 416 if (ret >= len) {
405 for (j = 0; j < len; j++) { 417 for (j = 0; j < len; j++) {
406 msgs[i + 1].buf[j] = data[j + 5]; 418 msgs[i + 1].buf[j] = st->data[j + 5];
407 if (dvb_usb_az6007_debug & 2) 419 if (dvb_usb_az6007_debug & 2)
408 printk(KERN_CONT 420 printk(KERN_CONT
409 "0x%02x ", 421 "0x%02x ",
@@ -426,11 +438,11 @@ static int az6007_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],
426 if (dvb_usb_az6007_debug & 2) 438 if (dvb_usb_az6007_debug & 2)
427 printk(KERN_CONT "(0x%02x) ", msgs[i].buf[0]); 439 printk(KERN_CONT "(0x%02x) ", msgs[i].buf[0]);
428 for (j = 0; j < len; j++) { 440 for (j = 0; j < len; j++) {
429 data[j] = msgs[i].buf[j + 1]; 441 st->data[j] = msgs[i].buf[j + 1];
430 if (dvb_usb_az6007_debug & 2) 442 if (dvb_usb_az6007_debug & 2)
431 printk(KERN_CONT "0x%02x ", data[j]); 443 printk(KERN_CONT "0x%02x ", st->data[j]);
432 } 444 }
433 ret = az6007_write(d->udev, req, value, index, data, 445 ret = az6007_write(d->udev, req, value, index, st->data,
434 length); 446 length);
435 } else { 447 } else {
436 /* read bytes */ 448 /* read bytes */
@@ -443,13 +455,13 @@ static int az6007_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],
443 value = addr; 455 value = addr;
444 length = msgs[i].len + 6; 456 length = msgs[i].len + 6;
445 len = msgs[i].len; 457 len = msgs[i].len;
446 ret = az6007_read(d->udev, req, value, index, data, 458 ret = az6007_read(d->udev, req, value, index, st->data,
447 length); 459 length);
448 for (j = 0; j < len; j++) { 460 for (j = 0; j < len; j++) {
449 msgs[i].buf[j] = data[j + 5]; 461 msgs[i].buf[j] = st->data[j + 5];
450 if (dvb_usb_az6007_debug & 2) 462 if (dvb_usb_az6007_debug & 2)
451 printk(KERN_CONT 463 printk(KERN_CONT
452 "0x%02x ", data[j + 5]); 464 "0x%02x ", st->data[j + 5]);
453 } 465 }
454 } 466 }
455 if (dvb_usb_az6007_debug & 2) 467 if (dvb_usb_az6007_debug & 2)
@@ -491,6 +503,12 @@ int az6007_identify_state(struct usb_device *udev,
491 else 503 else
492 *cold = 1; 504 *cold = 1;
493 505
506 if (*cold) {
507 az6007_write(udev, 0x09, 1, 0, NULL, 0);
508 az6007_write(udev, 0x00, 0, 0, NULL, 0);
509 az6007_write(udev, 0x00, 0, 0, NULL, 0);
510 }
511
494 deb_info("Device is on %s state\n", *cold? "warm" : "cold"); 512 deb_info("Device is on %s state\n", *cold? "warm" : "cold");
495 return 0; 513 return 0;
496} 514}