diff options
author | Malcolm Priestley <tvboxspy@gmail.com> | 2012-02-12 07:03:06 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-03-08 06:53:39 -0500 |
commit | 6c5637e4eda58292f7d9ee6ee0b1f9aa4b0a7e7f (patch) | |
tree | 6af144c29824c2ba6b50811abd04798483f5d5c7 /drivers | |
parent | aaa589fc5e768eb8df1a7552e37f9c767ce5e384 (diff) |
[media] it913x-fe ver 1.15 read signal strenght using reg VAR_P_INBAND
Read signal strength using VAR_P_INBAND and apply FEC preferred values.
Note this does not work on IT9137 devices even with dvb-usb-it9135-01.fw
firmware.
Config read_sl allows switch between read signal strength and signal
level.
Signed-off-by: Malcolm Priestley <tvboxspy@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/media/dvb/dvb-usb/it913x.c | 3 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/it913x-fe-priv.h | 5 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/it913x-fe.c | 91 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/it913x-fe.h | 4 |
4 files changed, 93 insertions, 10 deletions
diff --git a/drivers/media/dvb/dvb-usb/it913x.c b/drivers/media/dvb/dvb-usb/it913x.c index cfa415b0816d..3b7b102f20ae 100644 --- a/drivers/media/dvb/dvb-usb/it913x.c +++ b/drivers/media/dvb/dvb-usb/it913x.c | |||
@@ -412,11 +412,13 @@ static int ite_firmware_select(struct usb_device *udev, | |||
412 | case IT9135_V1_FW: | 412 | case IT9135_V1_FW: |
413 | it913x_config.firmware_ver = 1; | 413 | it913x_config.firmware_ver = 1; |
414 | it913x_config.adc_x2 = 1; | 414 | it913x_config.adc_x2 = 1; |
415 | it913x_config.read_slevel = false; | ||
415 | props->firmware = fw_it9135_v1; | 416 | props->firmware = fw_it9135_v1; |
416 | break; | 417 | break; |
417 | case IT9135_V2_FW: | 418 | case IT9135_V2_FW: |
418 | it913x_config.firmware_ver = 1; | 419 | it913x_config.firmware_ver = 1; |
419 | it913x_config.adc_x2 = 1; | 420 | it913x_config.adc_x2 = 1; |
421 | it913x_config.read_slevel = false; | ||
420 | props->firmware = fw_it9135_v2; | 422 | props->firmware = fw_it9135_v2; |
421 | switch (it913x_config.tuner_id_0) { | 423 | switch (it913x_config.tuner_id_0) { |
422 | case IT9135_61: | 424 | case IT9135_61: |
@@ -432,6 +434,7 @@ static int ite_firmware_select(struct usb_device *udev, | |||
432 | default: | 434 | default: |
433 | it913x_config.firmware_ver = 0; | 435 | it913x_config.firmware_ver = 0; |
434 | it913x_config.adc_x2 = 0; | 436 | it913x_config.adc_x2 = 0; |
437 | it913x_config.read_slevel = true; | ||
435 | props->firmware = fw_it9137; | 438 | props->firmware = fw_it9137; |
436 | } | 439 | } |
437 | 440 | ||
diff --git a/drivers/media/dvb/frontends/it913x-fe-priv.h b/drivers/media/dvb/frontends/it913x-fe-priv.h index 93b086ea7e1c..eb6fd8aebdb3 100644 --- a/drivers/media/dvb/frontends/it913x-fe-priv.h +++ b/drivers/media/dvb/frontends/it913x-fe-priv.h | |||
@@ -201,6 +201,11 @@ fe_modulation_t fe_con[] = { | |||
201 | QAM_64, | 201 | QAM_64, |
202 | }; | 202 | }; |
203 | 203 | ||
204 | enum { | ||
205 | PRIORITY_HIGH = 0, /* High-priority stream */ | ||
206 | PRIORITY_LOW, /* Low-priority stream */ | ||
207 | }; | ||
208 | |||
204 | /* Standard demodulator functions */ | 209 | /* Standard demodulator functions */ |
205 | static struct it913xset set_solo_fe[] = { | 210 | static struct it913xset set_solo_fe[] = { |
206 | {PRO_LINK, GPIOH5_EN, {0x01}, 0x01}, | 211 | {PRO_LINK, GPIOH5_EN, {0x01}, 0x01}, |
diff --git a/drivers/media/dvb/frontends/it913x-fe.c b/drivers/media/dvb/frontends/it913x-fe.c index ccc36bf2deb4..84df03c29179 100644 --- a/drivers/media/dvb/frontends/it913x-fe.c +++ b/drivers/media/dvb/frontends/it913x-fe.c | |||
@@ -57,6 +57,7 @@ struct it913x_fe_state { | |||
57 | u32 frequency; | 57 | u32 frequency; |
58 | fe_modulation_t constellation; | 58 | fe_modulation_t constellation; |
59 | fe_transmit_mode_t transmission_mode; | 59 | fe_transmit_mode_t transmission_mode; |
60 | u8 priority; | ||
60 | u32 crystalFrequency; | 61 | u32 crystalFrequency; |
61 | u32 adcFrequency; | 62 | u32 adcFrequency; |
62 | u8 tuner_type; | 63 | u8 tuner_type; |
@@ -500,19 +501,87 @@ static int it913x_fe_read_status(struct dvb_frontend *fe, fe_status_t *status) | |||
500 | return 0; | 501 | return 0; |
501 | } | 502 | } |
502 | 503 | ||
504 | /* FEC values based on fe_code_rate_t non supported values 0*/ | ||
505 | int it913x_qpsk_pval[] = {0, -93, -91, -90, 0, -89, -88}; | ||
506 | int it913x_16qam_pval[] = {0, -87, -85, -84, 0, -83, -82}; | ||
507 | int it913x_64qam_pval[] = {0, -82, -80, -78, 0, -77, -76}; | ||
508 | |||
509 | static int it913x_get_signal_strength(struct dvb_frontend *fe) | ||
510 | { | ||
511 | struct dtv_frontend_properties *p = &fe->dtv_property_cache; | ||
512 | struct it913x_fe_state *state = fe->demodulator_priv; | ||
513 | u8 code_rate; | ||
514 | int ret, temp; | ||
515 | u8 lna_gain_os; | ||
516 | |||
517 | ret = it913x_read_reg_u8(state, VAR_P_INBAND); | ||
518 | if (ret < 0) | ||
519 | return ret; | ||
520 | |||
521 | /* VHF/UHF gain offset */ | ||
522 | if (state->frequency < 300000000) | ||
523 | lna_gain_os = 7; | ||
524 | else | ||
525 | lna_gain_os = 14; | ||
526 | |||
527 | temp = (ret - 100) - lna_gain_os; | ||
528 | |||
529 | if (state->priority == PRIORITY_HIGH) | ||
530 | code_rate = p->code_rate_HP; | ||
531 | else | ||
532 | code_rate = p->code_rate_LP; | ||
533 | |||
534 | if (code_rate >= ARRAY_SIZE(it913x_qpsk_pval)) | ||
535 | return -EINVAL; | ||
536 | |||
537 | deb_info("Reg VAR_P_INBAND:%d Calc Offset Value:%d", ret, temp); | ||
538 | |||
539 | /* Apply FEC offset values*/ | ||
540 | switch (p->modulation) { | ||
541 | case QPSK: | ||
542 | temp -= it913x_qpsk_pval[code_rate]; | ||
543 | break; | ||
544 | case QAM_16: | ||
545 | temp -= it913x_16qam_pval[code_rate]; | ||
546 | break; | ||
547 | case QAM_64: | ||
548 | temp -= it913x_64qam_pval[code_rate]; | ||
549 | break; | ||
550 | default: | ||
551 | return -EINVAL; | ||
552 | } | ||
553 | |||
554 | if (temp < -15) | ||
555 | ret = 0; | ||
556 | else if ((-15 <= temp) && (temp < 0)) | ||
557 | ret = (2 * (temp + 15)) / 3; | ||
558 | else if ((0 <= temp) && (temp < 20)) | ||
559 | ret = 4 * temp + 10; | ||
560 | else if ((20 <= temp) && (temp < 35)) | ||
561 | ret = (2 * (temp - 20)) / 3 + 90; | ||
562 | else if (temp >= 35) | ||
563 | ret = 100; | ||
564 | |||
565 | deb_info("Signal Strength :%d", ret); | ||
566 | |||
567 | return ret; | ||
568 | } | ||
569 | |||
503 | static int it913x_fe_read_signal_strength(struct dvb_frontend *fe, | 570 | static int it913x_fe_read_signal_strength(struct dvb_frontend *fe, |
504 | u16 *strength) | 571 | u16 *strength) |
505 | { | 572 | { |
506 | struct it913x_fe_state *state = fe->demodulator_priv; | 573 | struct it913x_fe_state *state = fe->demodulator_priv; |
507 | int ret = it913x_read_reg_u8(state, SIGNAL_LEVEL); | 574 | int ret = 0; |
508 | /*SIGNAL_LEVEL always returns 100%! so using FE_HAS_SIGNAL as switch*/ | 575 | if (state->config->read_slevel) { |
509 | if (state->it913x_status & FE_HAS_SIGNAL) | 576 | if (state->it913x_status & FE_HAS_SIGNAL) |
510 | ret = (ret * 0xff) / 0x64; | 577 | ret = it913x_read_reg_u8(state, SIGNAL_LEVEL); |
511 | else | 578 | } else |
512 | ret = 0x0; | 579 | ret = it913x_get_signal_strength(fe); |
513 | ret |= ret << 0x8; | 580 | |
514 | *strength = ret; | 581 | if (ret >= 0) |
515 | return 0; | 582 | *strength = (u16)((u32)ret * 0xffff / 0x64); |
583 | |||
584 | return (ret < 0) ? -ENODEV : 0; | ||
516 | } | 585 | } |
517 | 586 | ||
518 | static int it913x_fe_read_snr(struct dvb_frontend *fe, u16 *snr) | 587 | static int it913x_fe_read_snr(struct dvb_frontend *fe, u16 *snr) |
@@ -606,6 +675,8 @@ static int it913x_fe_get_frontend(struct dvb_frontend *fe) | |||
606 | if (reg[2] < 4) | 675 | if (reg[2] < 4) |
607 | p->hierarchy = fe_hi[reg[2]]; | 676 | p->hierarchy = fe_hi[reg[2]]; |
608 | 677 | ||
678 | state->priority = reg[5]; | ||
679 | |||
609 | p->code_rate_HP = (reg[6] < 6) ? fe_code[reg[6]] : FEC_NONE; | 680 | p->code_rate_HP = (reg[6] < 6) ? fe_code[reg[6]] : FEC_NONE; |
610 | p->code_rate_LP = (reg[7] < 6) ? fe_code[reg[7]] : FEC_NONE; | 681 | p->code_rate_LP = (reg[7] < 6) ? fe_code[reg[7]] : FEC_NONE; |
611 | 682 | ||
@@ -972,5 +1043,5 @@ static struct dvb_frontend_ops it913x_fe_ofdm_ops = { | |||
972 | 1043 | ||
973 | MODULE_DESCRIPTION("it913x Frontend and it9137 tuner"); | 1044 | MODULE_DESCRIPTION("it913x Frontend and it9137 tuner"); |
974 | MODULE_AUTHOR("Malcolm Priestley tvboxspy@gmail.com"); | 1045 | MODULE_AUTHOR("Malcolm Priestley tvboxspy@gmail.com"); |
975 | MODULE_VERSION("1.13"); | 1046 | MODULE_VERSION("1.15"); |
976 | MODULE_LICENSE("GPL"); | 1047 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/media/dvb/frontends/it913x-fe.h b/drivers/media/dvb/frontends/it913x-fe.h index c4a908e354e0..07fa4594c12b 100644 --- a/drivers/media/dvb/frontends/it913x-fe.h +++ b/drivers/media/dvb/frontends/it913x-fe.h | |||
@@ -34,6 +34,8 @@ struct ite_config { | |||
34 | u8 tuner_id_1; | 34 | u8 tuner_id_1; |
35 | u8 dual_mode; | 35 | u8 dual_mode; |
36 | u8 adf; | 36 | u8 adf; |
37 | /* option to read SIGNAL_LEVEL */ | ||
38 | u8 read_slevel; | ||
37 | }; | 39 | }; |
38 | 40 | ||
39 | #if defined(CONFIG_DVB_IT913X_FE) || (defined(CONFIG_DVB_IT913X_FE_MODULE) && \ | 41 | #if defined(CONFIG_DVB_IT913X_FE) || (defined(CONFIG_DVB_IT913X_FE_MODULE) && \ |
@@ -168,6 +170,8 @@ static inline struct dvb_frontend *it913x_fe_attach( | |||
168 | #define EST_SIGNAL_LEVEL 0x004a | 170 | #define EST_SIGNAL_LEVEL 0x004a |
169 | #define FREE_BAND 0x004b | 171 | #define FREE_BAND 0x004b |
170 | #define SUSPEND_FLAG 0x004c | 172 | #define SUSPEND_FLAG 0x004c |
173 | #define VAR_P_INBAND 0x00f7 | ||
174 | |||
171 | /* Build in tuner types */ | 175 | /* Build in tuner types */ |
172 | #define IT9137 0x38 | 176 | #define IT9137 0x38 |
173 | #define IT9135_38 0x38 | 177 | #define IT9135_38 0x38 |