aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorMalcolm Priestley <tvboxspy@gmail.com>2015-01-02 08:56:30 -0500
committerMauro Carvalho Chehab <mchehab@osg.samsung.com>2015-02-03 14:16:13 -0500
commit743ab6a1ccafaa55b8ce00804ce4f9cc2fda8394 (patch)
tree11ffc2d122fcdc228cafc2ca970f9c11eb573d28 /drivers/media
parentd8bad1e2abdf09def76ff9736443d25ad1ea67eb (diff)
[media] lmedm04: Create frontend call back for read status
Create dm04_read_status to check lock through either interrupt values or directly by the call back. When the device is not streaming the frontends original call back is used. When streaming has started it turns off I2C messaging by setting st->i2c_talk_onoff to zero. I2C can only be turn on again by one of the other allowed frontend calls. All old code is removed from lme2510_msg and this function only needs to set st->i2c_talk_onoff to 1. The lock status is saved and when the frondend is locked is maintained by lme2510_int_response who will now just kill the lock. The call back for rs2000 tuner is nologer required. All frontend types have been tested. Signed-off-by: Malcolm Priestley <tvboxspy@gmail.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/usb/dvb-usb-v2/lmedm04.c205
1 files changed, 60 insertions, 145 deletions
diff --git a/drivers/media/usb/dvb-usb-v2/lmedm04.c b/drivers/media/usb/dvb-usb-v2/lmedm04.c
index 55d76904131f..a9c7fd0fa086 100644
--- a/drivers/media/usb/dvb-usb-v2/lmedm04.c
+++ b/drivers/media/usb/dvb-usb-v2/lmedm04.c
@@ -126,9 +126,9 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
126 126
127struct lme2510_state { 127struct lme2510_state {
128 unsigned long int_urb_due; 128 unsigned long int_urb_due;
129 fe_status_t lock_status;
129 u8 id; 130 u8 id;
130 u8 tuner_config; 131 u8 tuner_config;
131 u8 signal_lock;
132 u8 signal_level; 132 u8 signal_level;
133 u8 signal_sn; 133 u8 signal_sn;
134 u8 time_key; 134 u8 time_key;
@@ -143,6 +143,8 @@ struct lme2510_state {
143 void *buffer; 143 void *buffer;
144 struct urb *lme_urb; 144 struct urb *lme_urb;
145 void *usb_buffer; 145 void *usb_buffer;
146 /* Frontend original calls */
147 int (*fe_read_status)(struct dvb_frontend *, fe_status_t *);
146 int (*fe_set_voltage)(struct dvb_frontend *, fe_sec_voltage_t); 148 int (*fe_set_voltage)(struct dvb_frontend *, fe_sec_voltage_t);
147 u8 dvb_usb_lme2510_firmware; 149 u8 dvb_usb_lme2510_firmware;
148}; 150};
@@ -258,6 +260,7 @@ static void lme2510_int_response(struct urb *lme_urb)
258 static u8 *ibuf, *rbuf; 260 static u8 *ibuf, *rbuf;
259 int i = 0, offset; 261 int i = 0, offset;
260 u32 key; 262 u32 key;
263 u8 signal_lock = 0;
261 264
262 switch (lme_urb->status) { 265 switch (lme_urb->status) {
263 case 0: 266 case 0:
@@ -298,8 +301,7 @@ static void lme2510_int_response(struct urb *lme_urb)
298 case 0xbb: 301 case 0xbb:
299 switch (st->tuner_config) { 302 switch (st->tuner_config) {
300 case TUNER_LG: 303 case TUNER_LG:
301 if (ibuf[2] > 0) 304 signal_lock = ibuf[2] & BIT(5);
302 st->signal_lock = ibuf[2];
303 st->signal_level = ibuf[4]; 305 st->signal_level = ibuf[4];
304 st->signal_sn = ibuf[3]; 306 st->signal_sn = ibuf[3];
305 st->time_key = ibuf[7]; 307 st->time_key = ibuf[7];
@@ -308,29 +310,29 @@ static void lme2510_int_response(struct urb *lme_urb)
308 case TUNER_S0194: 310 case TUNER_S0194:
309 /* Tweak for earlier firmware*/ 311 /* Tweak for earlier firmware*/
310 if (ibuf[1] == 0x03) { 312 if (ibuf[1] == 0x03) {
311 if (ibuf[2] > 1) 313 signal_lock = ibuf[2] & BIT(4);
312 st->signal_lock = ibuf[2];
313 st->signal_level = ibuf[3]; 314 st->signal_level = ibuf[3];
314 st->signal_sn = ibuf[4]; 315 st->signal_sn = ibuf[4];
315 } else { 316 } else {
316 st->signal_level = ibuf[4]; 317 st->signal_level = ibuf[4];
317 st->signal_sn = ibuf[5]; 318 st->signal_sn = ibuf[5];
318 st->signal_lock =
319 (st->signal_lock & 0xf7) +
320 ((ibuf[2] & 0x01) << 0x03);
321 } 319 }
322 break; 320 break;
323 case TUNER_RS2000: 321 case TUNER_RS2000:
324 if (ibuf[2] & 0x1) 322 signal_lock = ibuf[2] & 0xee;
325 st->signal_lock = 0xff;
326 else
327 st->signal_lock = 0x00;
328 st->signal_level = ibuf[5]; 323 st->signal_level = ibuf[5];
329 st->signal_sn = ibuf[4]; 324 st->signal_sn = ibuf[4];
330 st->time_key = ibuf[7]; 325 st->time_key = ibuf[7];
331 default: 326 default:
332 break; 327 break;
333 } 328 }
329
330 /* Interrupt will also throw just BIT 0 as lock */
331 signal_lock |= ibuf[2] & BIT(0);
332
333 if (!signal_lock)
334 st->lock_status &= ~FE_HAS_LOCK;
335
334 debug_data_snipet(5, "INT Remote data snipet in", ibuf); 336 debug_data_snipet(5, "INT Remote data snipet in", ibuf);
335 break; 337 break;
336 case 0xcc: 338 case 0xcc:
@@ -457,124 +459,13 @@ static int lme2510_return_status(struct dvb_usb_device *d)
457static int lme2510_msg(struct dvb_usb_device *d, 459static int lme2510_msg(struct dvb_usb_device *d,
458 u8 *wbuf, int wlen, u8 *rbuf, int rlen) 460 u8 *wbuf, int wlen, u8 *rbuf, int rlen)
459{ 461{
460 int ret = 0;
461 struct lme2510_state *st = d->priv; 462 struct lme2510_state *st = d->priv;
462 463
463 if (st->i2c_talk_onoff == 1) { 464 st->i2c_talk_onoff = 1;
464
465 ret = lme2510_usb_talk(d, wbuf, wlen, rbuf, rlen);
466
467 switch (st->tuner_config) {
468 case TUNER_LG:
469 if (wbuf[2] == 0x1c) {
470 if (wbuf[3] == 0x0e) {
471 st->signal_lock = rbuf[1];
472 if ((st->stream_on & 1) &&
473 (st->signal_lock & 0x10)) {
474 lme2510_stream_restart(d);
475 st->i2c_talk_onoff = 0;
476 }
477 msleep(80);
478 }
479 }
480 break;
481 case TUNER_S7395:
482 if (wbuf[2] == 0xd0) {
483 if (wbuf[3] == 0x24) {
484 st->signal_lock = rbuf[1];
485 if ((st->stream_on & 1) &&
486 (st->signal_lock & 0x8)) {
487 lme2510_stream_restart(d);
488 st->i2c_talk_onoff = 0;
489 }
490 }
491 }
492 break;
493 case TUNER_S0194:
494 if (wbuf[2] == 0xd0) {
495 if (wbuf[3] == 0x1b) {
496 st->signal_lock = rbuf[1];
497 if ((st->stream_on & 1) &&
498 (st->signal_lock & 0x8)) {
499 lme2510_stream_restart(d);
500 st->i2c_talk_onoff = 0;
501 }
502 }
503 }
504 break;
505 case TUNER_RS2000:
506 default:
507 break;
508 }
509 } else {
510 /* TODO rewrite this section */
511 switch (st->tuner_config) {
512 case TUNER_LG:
513 switch (wbuf[3]) {
514 case 0x0e:
515 rbuf[0] = 0x55;
516 rbuf[1] = st->signal_lock;
517 break;
518 default:
519 lme2510_usb_talk(d, wbuf, wlen, rbuf, rlen);
520 st->i2c_talk_onoff = 1;
521 break;
522 }
523 break;
524 case TUNER_S7395:
525 switch (wbuf[3]) {
526 case 0x24:
527 rbuf[0] = 0x55;
528 rbuf[1] = st->signal_lock;
529 break;
530 default:
531 lme2510_usb_talk(d, wbuf, wlen, rbuf, rlen);
532 st->i2c_talk_onoff = 1;
533 break;
534 }
535 break;
536 case TUNER_S0194:
537 switch (wbuf[3]) {
538 case 0x1b:
539 rbuf[0] = 0x55;
540 rbuf[1] = st->signal_lock;
541 break;
542 default:
543 lme2510_usb_talk(d, wbuf, wlen, rbuf, rlen);
544 st->i2c_talk_onoff = 1;
545 break;
546 }
547 break;
548 case TUNER_RS2000:
549 switch (wbuf[3]) {
550 case 0x8c:
551 rbuf[0] = 0x55;
552 rbuf[1] = st->signal_lock;
553
554 /* If int_urb_due overdue
555 * set rbuf[1] to 0 to clear lock */
556 if (time_after(jiffies, st->int_urb_due))
557 rbuf[1] = 0;
558
559 break;
560 default:
561 lme2510_usb_talk(d, wbuf, wlen, rbuf, rlen);
562 st->i2c_talk_onoff = 1;
563 break;
564 }
565 default:
566 break;
567 }
568
569 deb_info(4, "I2C From Interrupt Message out(%02x) in(%02x)",
570 wbuf[3], rbuf[1]);
571
572 }
573 465
574 return ret; 466 return lme2510_usb_talk(d, wbuf, wlen, rbuf, rlen);
575} 467}
576 468
577
578static int lme2510_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], 469static int lme2510_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
579 int num) 470 int num)
580{ 471{
@@ -897,26 +788,8 @@ static struct stv0299_config sharp_z0194_config = {
897 .set_symbol_rate = sharp_z0194a_set_symbol_rate, 788 .set_symbol_rate = sharp_z0194a_set_symbol_rate,
898}; 789};
899 790
900static int dm04_rs2000_set_ts_param(struct dvb_frontend *fe,
901 int caller)
902{
903 struct dvb_usb_adapter *adap = fe_to_adap(fe);
904 struct dvb_usb_device *d = adap_to_d(adap);
905 struct lme2510_state *st = d->priv;
906
907 mutex_lock(&d->i2c_mutex);
908 if ((st->i2c_talk_onoff == 1) && (st->stream_on & 1)) {
909 st->i2c_talk_onoff = 0;
910 lme2510_stream_restart(d);
911 }
912 mutex_unlock(&d->i2c_mutex);
913
914 return 0;
915}
916
917static struct m88rs2000_config m88rs2000_config = { 791static struct m88rs2000_config m88rs2000_config = {
918 .demod_addr = 0x68, 792 .demod_addr = 0x68
919 .set_ts_params = dm04_rs2000_set_ts_param,
920}; 793};
921 794
922static struct ts2020_config ts2020_config = { 795static struct ts2020_config ts2020_config = {
@@ -960,6 +833,46 @@ static int dm04_lme2510_set_voltage(struct dvb_frontend *fe,
960 return (ret < 0) ? -ENODEV : 0; 833 return (ret < 0) ? -ENODEV : 0;
961} 834}
962 835
836static int dm04_read_status(struct dvb_frontend *fe, fe_status_t *status)
837{
838 struct dvb_usb_device *d = fe_to_d(fe);
839 struct lme2510_state *st = d->priv;
840 int ret = 0;
841
842 if (st->i2c_talk_onoff) {
843 if (st->fe_read_status) {
844 ret = st->fe_read_status(fe, status);
845 if (ret < 0)
846 return ret;
847 }
848
849 st->lock_status = *status;
850
851 if (*status & FE_HAS_LOCK && st->stream_on) {
852 mutex_lock(&d->i2c_mutex);
853
854 st->i2c_talk_onoff = 0;
855 ret = lme2510_stream_restart(d);
856
857 mutex_unlock(&d->i2c_mutex);
858 }
859
860 return ret;
861 }
862
863 /* Timeout of interrupt reached on RS2000 */
864 if (st->tuner_config == TUNER_RS2000 &&
865 time_after(jiffies, st->int_urb_due))
866 st->lock_status &= ~FE_HAS_LOCK;
867
868 *status = st->lock_status;
869
870 if (!(*status & FE_HAS_LOCK))
871 st->i2c_talk_onoff = 1;
872
873 return ret;
874}
875
963static int dm04_read_signal_strength(struct dvb_frontend *fe, u16 *strength) 876static int dm04_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
964{ 877{
965 struct lme2510_state *st = fe_to_priv(fe); 878 struct lme2510_state *st = fe_to_priv(fe);
@@ -1122,6 +1035,9 @@ static int dm04_lme2510_frontend_attach(struct dvb_usb_adapter *adap)
1122 return -ENODEV; 1035 return -ENODEV;
1123 } 1036 }
1124 1037
1038 st->fe_read_status = adap->fe[0]->ops.read_status;
1039
1040 adap->fe[0]->ops.read_status = dm04_read_status;
1125 adap->fe[0]->ops.read_signal_strength = dm04_read_signal_strength; 1041 adap->fe[0]->ops.read_signal_strength = dm04_read_signal_strength;
1126 adap->fe[0]->ops.read_snr = dm04_read_snr; 1042 adap->fe[0]->ops.read_snr = dm04_read_snr;
1127 adap->fe[0]->ops.read_ber = dm04_read_ber; 1043 adap->fe[0]->ops.read_ber = dm04_read_ber;
@@ -1269,7 +1185,6 @@ static void *lme2510_exit_int(struct dvb_usb_device *d)
1269 1185
1270 if (st->usb_buffer != NULL) { 1186 if (st->usb_buffer != NULL) {
1271 st->i2c_talk_onoff = 1; 1187 st->i2c_talk_onoff = 1;
1272 st->signal_lock = 0;
1273 st->signal_level = 0; 1188 st->signal_level = 0;
1274 st->signal_sn = 0; 1189 st->signal_sn = 0;
1275 buffer = st->usb_buffer; 1190 buffer = st->usb_buffer;