diff options
author | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-02-18 23:45:00 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-02-26 13:11:03 -0500 |
commit | 7f2199c03b4946f1b79514b3411e3dbf130a6bba (patch) | |
tree | 34a49284c83a9cd7055f483e36be9553d8be3e1f /drivers/media | |
parent | d90a4ae4ae5a5e535782ab090507898e042db81a (diff) |
V4L/DVB: tuner-xc2028: fix tuning logic to solve a regression in Australia
There's one reported regression in Australia (DTV7) and some
reported troubles with newer firmwares found on xc3028l chips.
Rework the logic to improve tuner on those cases.
Thanks-to: Robert Lowery <rglowery@exemail.com.au>
Thanks-to: Stefan Ringel <stefan.ringel@arcor.de>
Tested-by: Robert Lowery <rglowery@exemail.com.au>
CC: stable.kernel.org
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/common/tuners/tuner-xc2028.c | 77 |
1 files changed, 60 insertions, 17 deletions
diff --git a/drivers/media/common/tuners/tuner-xc2028.c b/drivers/media/common/tuners/tuner-xc2028.c index f270e605da83..96f45a80fe56 100644 --- a/drivers/media/common/tuners/tuner-xc2028.c +++ b/drivers/media/common/tuners/tuner-xc2028.c | |||
@@ -917,30 +917,68 @@ static int generic_set_freq(struct dvb_frontend *fe, u32 freq /* in HZ */, | |||
917 | * that xc2028 will be in a safe state. | 917 | * that xc2028 will be in a safe state. |
918 | * Maybe this might also be needed for DTV. | 918 | * Maybe this might also be needed for DTV. |
919 | */ | 919 | */ |
920 | if (new_mode == T_ANALOG_TV) | 920 | if (new_mode == T_ANALOG_TV) { |
921 | rc = send_seq(priv, {0x00, 0x00}); | 921 | rc = send_seq(priv, {0x00, 0x00}); |
922 | 922 | ||
923 | /* | 923 | /* Analog modes require offset = 0 */ |
924 | * Digital modes require an offset to adjust to the | 924 | } else { |
925 | * proper frequency. | 925 | /* |
926 | * Analog modes require offset = 0 | 926 | * Digital modes require an offset to adjust to the |
927 | */ | 927 | * proper frequency. The offset depends on what |
928 | if (new_mode == T_DIGITAL_TV) { | 928 | * firmware version is used. |
929 | /* Sets the offset according with firmware */ | 929 | */ |
930 | |||
931 | /* | ||
932 | * Adjust to the center frequency. This is calculated by the | ||
933 | * formula: offset = 1.25MHz - BW/2 | ||
934 | * For DTV 7/8, the firmware uses BW = 8000, so it needs a | ||
935 | * further adjustment to get the frequency center on VHF | ||
936 | */ | ||
930 | if (priv->cur_fw.type & DTV6) | 937 | if (priv->cur_fw.type & DTV6) |
931 | offset = 1750000; | 938 | offset = 1750000; |
932 | else if (priv->cur_fw.type & DTV7) | 939 | else if (priv->cur_fw.type & DTV7) |
933 | offset = 2250000; | 940 | offset = 2250000; |
934 | else /* DTV8 or DTV78 */ | 941 | else /* DTV8 or DTV78 */ |
935 | offset = 2750000; | 942 | offset = 2750000; |
943 | if ((priv->cur_fw.type & DTV78) && freq < 470000000) | ||
944 | offset -= 500000; | ||
936 | 945 | ||
937 | /* | 946 | /* |
938 | * We must adjust the offset by 500kHz when | 947 | * xc3028 additional "magic" |
939 | * tuning a 7MHz VHF channel with DTV78 firmware | 948 | * Depending on the firmware version, it needs some adjustments |
940 | * (used in Australia, Italy and Germany) | 949 | * to properly centralize the frequency. This seems to be |
950 | * needed to compensate the SCODE table adjustments made by | ||
951 | * newer firmwares | ||
941 | */ | 952 | */ |
942 | if ((priv->cur_fw.type & DTV78) && freq < 470000000) | 953 | |
943 | offset -= 500000; | 954 | #if 1 |
955 | /* | ||
956 | * The proper adjustment would be to do it at s-code table. | ||
957 | * However, this didn't work, as reported by | ||
958 | * Robert Lowery <rglowery@exemail.com.au> | ||
959 | */ | ||
960 | |||
961 | if (priv->cur_fw.type & DTV7) | ||
962 | offset += 500000; | ||
963 | |||
964 | #else | ||
965 | /* | ||
966 | * Still need tests for XC3028L (firmware 3.2 or upper) | ||
967 | * So, for now, let's just comment the per-firmware | ||
968 | * version of this change. Reports with xc3028l working | ||
969 | * with and without the lines bellow are welcome | ||
970 | */ | ||
971 | |||
972 | if (priv->firm_version < 0x0302) { | ||
973 | if (priv->cur_fw.type & DTV7) | ||
974 | offset += 500000; | ||
975 | } else { | ||
976 | if (priv->cur_fw.type & DTV7) | ||
977 | offset -= 300000; | ||
978 | else if (type != ATSC) /* DVB @6MHz, DTV 8 and DTV 7/8 */ | ||
979 | offset += 200000; | ||
980 | } | ||
981 | #endif | ||
944 | } | 982 | } |
945 | 983 | ||
946 | div = (freq - offset + DIV / 2) / DIV; | 984 | div = (freq - offset + DIV / 2) / DIV; |
@@ -1097,17 +1135,22 @@ static int xc2028_set_params(struct dvb_frontend *fe, | |||
1097 | 1135 | ||
1098 | /* All S-code tables need a 200kHz shift */ | 1136 | /* All S-code tables need a 200kHz shift */ |
1099 | if (priv->ctrl.demod) { | 1137 | if (priv->ctrl.demod) { |
1100 | demod = priv->ctrl.demod + 200; | 1138 | /* |
1139 | * Newer firmwares require a 200 kHz offset only for ATSC | ||
1140 | */ | ||
1141 | if (type == ATSC || priv->firm_version < 0x0302) | ||
1142 | demod = priv->ctrl.demod + 200; | ||
1101 | /* | 1143 | /* |
1102 | * The DTV7 S-code table needs a 700 kHz shift. | 1144 | * The DTV7 S-code table needs a 700 kHz shift. |
1103 | * Thanks to Terry Wu <terrywu2009@gmail.com> for reporting this | ||
1104 | * | 1145 | * |
1105 | * DTV7 is only used in Australia. Germany or Italy may also | 1146 | * DTV7 is only used in Australia. Germany or Italy may also |
1106 | * use this firmware after initialization, but a tune to a UHF | 1147 | * use this firmware after initialization, but a tune to a UHF |
1107 | * channel should then cause DTV78 to be used. | 1148 | * channel should then cause DTV78 to be used. |
1149 | * | ||
1150 | * Unfortunately, on real-field tests, the s-code offset | ||
1151 | * didn't work as expected, as reported by | ||
1152 | * Robert Lowery <rglowery@exemail.com.au> | ||
1108 | */ | 1153 | */ |
1109 | if (type & DTV7) | ||
1110 | demod += 500; | ||
1111 | } | 1154 | } |
1112 | 1155 | ||
1113 | return generic_set_freq(fe, p->frequency, | 1156 | return generic_set_freq(fe, p->frequency, |