23 #include <linux/kernel.h>
24 #include <linux/module.h>
25 #include <linux/string.h>
26 #include <linux/videodev2.h>
30 static unsigned int debug;
34 #define dprintk(level, fmt, arg...) do { \
36 printk(KERN_DEBUG "mt2063 %s: " fmt, __func__, ## arg); \
43 #define MT2063_SPUR_PRESENT_ERR (0x00800000)
46 #define MT2063_SPUR_CNT_MASK (0x001f0000)
47 #define MT2063_SPUR_SHIFT (16)
50 #define MT2063_UPC_RANGE (0x04000000)
53 #define MT2063_DNC_RANGE (0x08000000)
65 #define MT2063_DECT_AVOID_US_FREQS 0x00000001
67 #define MT2063_DECT_AVOID_EURO_FREQS 0x00000002
69 #define MT2063_EXCLUDE_US_DECT_FREQUENCIES(s) (((s) & MT2063_DECT_AVOID_US_FREQS) != 0)
71 #define MT2063_EXCLUDE_EURO_DECT_FREQUENCIES(s) (((s) & MT2063_DECT_AVOID_EURO_FREQS) != 0)
80 #define MT2063_MAX_ZONES 48
265 if (fe->
ops.i2c_gate_ctrl)
266 fe->
ops.i2c_gate_ctrl(fe, 1);
268 if (fe->
ops.i2c_gate_ctrl)
269 fe->
ops.i2c_gate_ctrl(fe, 0);
289 status = mt2063_write(state, reg, &val, 1);
308 dprintk(2,
"addr 0x%02x, cnt %d\n", subAddress, cnt);
310 if (fe->
ops.i2c_gate_ctrl)
311 fe->
ops.i2c_gate_ctrl(fe, 1);
313 for (i = 0; i <
cnt; i++) {
314 u8 b0[] = { subAddress + i };
322 .addr = state->
config->tuner_address,
330 dprintk(2,
"addr 0x%02x, ret = %d, val = 0x%02x\n",
331 subAddress + i, status, *(pData + i));
335 if (fe->
ops.i2c_gate_ctrl)
336 fe->
ops.i2c_gate_ctrl(fe, 0);
363 #define ceil(n, d) (((n) < 0) ? (-((-(n))/(d))) : (n)/(d) + ((n)%(d) != 0))
364 #define floor(n, d) (((n) < 0) ? (-((-(n))/(d))) - ((n)%(d) != 0) : (n)/(d))
389 if (pPrevNode !=
NULL) {
391 pPrevNode->
next_ = pNode;
413 if (pPrevNode !=
NULL)
414 pPrevNode->
next_ = pNext;
446 && (f_min < f_max)) {
456 while ((pNode !=
NULL) && (pNode->
max_ < f_min)) {
458 pNode = pNode->
next_;
461 if ((pNode !=
NULL) && (pNode->
min_ < f_max)) {
463 if (f_min < pNode->
min_)
465 if (f_max > pNode->
max_)
468 pNode = InsertNode(pAS_Info, pPrev);
474 pNext = pNode->
next_;
475 while ((pNext !=
NULL) && (pNext->
min_ < pNode->
max_)) {
479 pNext = RemoveNode(pAS_Info, pNode, pNext);
506 MT2063_AddExclZone(pAS_Info,
509 MT2063_AddExclZone(pAS_Info, center + 1,
511 center += pAS_Info->
f_ref;
522 MT2063_AddExclZone(pAS_Info,
525 MT2063_AddExclZone(pAS_Info, center + 1,
527 center += pAS_Info->
f_ref;
532 MT2063_AddExclZone(pAS_Info, 1920836000 - pAS_Info->
f_in, 1922236000 - pAS_Info->
f_in);
533 MT2063_AddExclZone(pAS_Info, 1922564000 - pAS_Info->
f_in, 1923964000 - pAS_Info->
f_in);
534 MT2063_AddExclZone(pAS_Info, 1924292000 - pAS_Info->
f_in, 1925692000 - pAS_Info->
f_in);
535 MT2063_AddExclZone(pAS_Info, 1926020000 - pAS_Info->
f_in, 1927420000 - pAS_Info->
f_in);
536 MT2063_AddExclZone(pAS_Info, 1927748000 - pAS_Info->
f_in, 1929148000 - pAS_Info->
f_in);
540 MT2063_AddExclZone(pAS_Info, 1896644000 - pAS_Info->
f_in, 1898044000 - pAS_Info->
f_in);
541 MT2063_AddExclZone(pAS_Info, 1894916000 - pAS_Info->
f_in, 1896316000 - pAS_Info->
f_in);
542 MT2063_AddExclZone(pAS_Info, 1893188000 - pAS_Info->
f_in, 1894588000 - pAS_Info->
f_in);
543 MT2063_AddExclZone(pAS_Info, 1891460000 - pAS_Info->
f_in, 1892860000 - pAS_Info->
f_in);
544 MT2063_AddExclZone(pAS_Info, 1889732000 - pAS_Info->
f_in, 1891132000 - pAS_Info->
f_in);
545 MT2063_AddExclZone(pAS_Info, 1888004000 - pAS_Info->
f_in, 1889404000 - pAS_Info->
f_in);
546 MT2063_AddExclZone(pAS_Info, 1886276000 - pAS_Info->
f_in, 1887676000 - pAS_Info->
f_in);
547 MT2063_AddExclZone(pAS_Info, 1884548000 - pAS_Info->
f_in, 1885948000 - pAS_Info->
f_in);
548 MT2063_AddExclZone(pAS_Info, 1882820000 - pAS_Info->
f_in, 1884220000 - pAS_Info->
f_in);
549 MT2063_AddExclZone(pAS_Info, 1881092000 - pAS_Info->
f_in, 1882492000 - pAS_Info->
f_in);
569 const u32 f_Desired =
581 u32 bDesiredExcluded = 0;
582 u32 bZeroExcluded = 0;
590 if (pAS_Info->
nZones == 0)
602 f_Step / 2) / f_Step);
608 f_Step / 2) / f_Step);
614 while (pNode !=
NULL) {
623 if ((pNode->
min_ < f_Desired) && (pNode->
max_ > f_Desired))
624 bDesiredExcluded = 1;
626 if ((tmpMin < 0) && (tmpMax > 0))
630 if ((
j > 0) && (tmpMin < zones[
j - 1].
max_))
631 zones[
j - 1].max_ = tmpMax;
634 zones[
j].min_ = tmpMin;
635 zones[
j].max_ = tmpMax;
638 pNode = pNode->
next_;
644 if (bDesiredExcluded == 0)
650 if (bZeroExcluded == 0)
654 bestDiff = zones[0].min_;
655 for (i = 0; i <
j; i++) {
656 if (
abs(zones[i].min_) <
abs(bestDiff))
657 bestDiff = zones[
i].min_;
659 bestDiff = zones[
i].max_;
663 return f_Center - ((
u32) (-bestDiff) * f_Step);
665 return f_Center + (bestDiff * f_Step);
721 s32 f_nsLO1, f_nsLO2;
724 u32 lo_gcd, gd_Scale, gc_Scale, gf_Scale, hgds, hgfs, hgcs;
735 lo_gcd = MT2063_gcd(f_LO1, f_LO2);
736 gd_Scale =
max((
u32) MT2063_gcd(lo_gcd, d), f_Scale);
738 gc_Scale =
max((
u32) MT2063_gcd(lo_gcd, c), f_Scale);
740 gf_Scale =
max((
u32) MT2063_gcd(lo_gcd, f), f_Scale);
746 for (n = n0; n <= pAS_Info->
maxH1; ++
n) {
747 md = (n * ((f_LO1 + hgds) / gd_Scale) -
748 ((d + hgds) / gd_Scale)) / ((f_LO2 + hgds) / gd_Scale);
751 if (md >= pAS_Info->
maxH1)
754 ma = (n * ((f_LO1 + hgds) / gd_Scale) +
755 ((d + hgds) / gd_Scale)) / ((f_LO2 + hgds) / gd_Scale);
761 mc = (n * ((f_LO1 + hgcs) / gc_Scale) -
762 ((c + hgcs) / gc_Scale)) / ((f_LO2 + hgcs) / gc_Scale);
764 f_nsLO1 = (
s32) (n * (f_LO1 / gc_Scale));
765 f_nsLO2 = (
s32) (mc * (f_LO2 / gc_Scale));
767 (gc_Scale * (f_nsLO1 - f_nsLO2)) +
768 n * (f_LO1 % gc_Scale) - mc * (f_LO2 % gc_Scale);
770 *fp = ((f_Spur - (
s32) c) / (mc -
n)) + 1;
771 *fm = (((
s32) d - f_Spur) / (mc -
n)) + 1;
776 me = (n * ((f_LO1 + hgfs) / gf_Scale) +
777 ((f + hgfs) / gf_Scale)) / ((f_LO2 + hgfs) / gf_Scale);
778 mf = (n * ((f_LO1 + hgfs) / gf_Scale) -
779 ((f + hgfs) / gf_Scale)) / ((f_LO2 + hgfs) / gf_Scale);
781 f_nsLO1 = n * (f_LO1 / gf_Scale);
782 f_nsLO2 = me * (f_LO2 / gf_Scale);
784 (gf_Scale * (f_nsLO1 - f_nsLO2)) +
785 n * (f_LO1 % gf_Scale) - me * (f_LO2 % gf_Scale);
787 *fp = ((f_Spur + (
s32) f) / (me -
n)) + 1;
788 *fm = (((
s32) f - f_Spur) / (me -
n)) + 1;
792 mb = (n * ((f_LO1 + hgcs) / gc_Scale) +
793 ((c + hgcs) / gc_Scale)) / ((f_LO2 + hgcs) / gc_Scale);
795 f_nsLO1 = n * (f_LO1 / gc_Scale);
796 f_nsLO2 = ma * (f_LO2 / gc_Scale);
798 (gc_Scale * (f_nsLO1 - f_nsLO2)) +
799 n * (f_LO1 % gc_Scale) - ma * (f_LO2 % gc_Scale);
801 *fp = (((
s32) d + f_Spur) / (ma -
n)) + 1;
802 *fm = (-(f_Spur + (
s32) c) / (ma -
n)) + 1;
826 if (pAS_Info->
maxH1 == 0)
840 pAS_Info->
bSpurPresent = IsSpurInBand(pAS_Info, &fm, &fp);
855 MT2063_AddExclZone(pAS_Info, zfIF1 - fm, zfIF1 + fp);
858 new_IF1 = MT2063_ChooseFirstIF(pAS_Info);
860 if (new_IF1 > zfIF1) {
861 pAS_Info->
f_LO1 += (new_IF1 - zfIF1);
862 pAS_Info->
f_LO2 += (new_IF1 - zfIF1);
864 pAS_Info->
f_LO1 -= (zfIF1 - new_IF1);
865 pAS_Info->
f_LO2 -= (zfIF1 - new_IF1);
874 pAS_Info->
bSpurPresent = IsSpurInBand(pAS_Info, &fm, &fp);
888 pAS_Info->
f_LO1 = zfLO1;
889 pAS_Info->
f_LO2 = zfLO2;
904 #define MT2063_REF_FREQ (16000000UL)
905 #define MT2063_IF1_BW (22000000UL)
906 #define MT2063_TUNE_STEP_SIZE (50000UL)
907 #define MT2063_SPUR_STEP_HZ (250000UL)
908 #define MT2063_ZIF_BW (2000000UL)
909 #define MT2063_MAX_HARMONICS_1 (15UL)
910 #define MT2063_MAX_HARMONICS_2 (5UL)
911 #define MT2063_MIN_LO_SEP (1000000UL)
912 #define MT2063_LO1_FRACN_AVOID (0UL)
913 #define MT2063_LO2_FRACN_AVOID (199999UL)
914 #define MT2063_MIN_FIN_FREQ (44000000UL)
915 #define MT2063_MAX_FIN_FREQ (1100000000UL)
916 #define MT2063_MIN_FOUT_FREQ (36000000UL)
917 #define MT2063_MAX_FOUT_FREQ (57000000UL)
918 #define MT2063_MIN_DNC_FREQ (1293000000UL)
919 #define MT2063_MAX_DNC_FREQ (1614000000UL)
920 #define MT2063_MIN_UPC_FREQ (1396000000UL)
921 #define MT2063_MAX_UPC_FREQ (2750000000UL)
926 #define MT2063_B0 (0x9B)
927 #define MT2063_B1 (0x9C)
928 #define MT2063_B2 (0x9D)
929 #define MT2063_B3 (0x9E)
938 static int mt2063_lockStatus(
struct mt2063_state *state)
940 const u32 nMaxWait = 100;
941 const u32 nPollRate = 2;
942 const u32 nMaxLoops = nMaxWait / nPollRate;
943 const u8 LO1LK = 0x80;
966 }
while (++nDelays < nMaxLoops);
1020 static const char *mt2063_mode_name[] = {
1029 static const u8 RFAGCEN[] = { 0, 0, 0, 0, 0, 0 };
1030 static const u8 LNARIN[] = { 0, 0, 3, 3, 3, 3 };
1031 static const u8 FIFFQEN[] = { 1, 1, 1, 1, 1, 1 };
1032 static const u8 FIFFQ[] = { 0, 0, 0, 0, 0, 0 };
1033 static const u8 DNC1GC[] = { 0, 0, 0, 0, 0, 0 };
1034 static const u8 DNC2GC[] = { 0, 0, 0, 0, 0, 0 };
1035 static const u8 ACLNAMAX[] = { 31, 31, 31, 31, 31, 31 };
1036 static const u8 LNATGT[] = { 44, 43, 43, 43, 43, 43 };
1037 static const u8 RFOVDIS[] = { 0, 0, 0, 0, 0, 0 };
1038 static const u8 ACRFMAX[] = { 31, 31, 31, 31, 31, 31 };
1039 static const u8 PD1TGT[] = { 36, 36, 38, 38, 36, 38 };
1040 static const u8 FIFOVDIS[] = { 0, 0, 0, 0, 0, 0 };
1041 static const u8 ACFIFMAX[] = { 29, 29, 29, 29, 29, 29 };
1042 static const u8 PD2TGT[] = { 40, 33, 38, 42, 30, 38 };
1084 mt2063_setreg(state,
1092 mt2063_setreg(state,
1100 mt2063_setreg(state,
1110 mt2063_setreg(state,
1118 mt2063_setreg(state,
1126 mt2063_setreg(state,
1136 mt2063_setreg(state,
1144 mt2063_setreg(state,
1152 mt2063_setreg(state,
1162 mt2063_setreg(state,
1170 mt2063_setreg(state,
1178 mt2063_setreg(state,
1229 (LNARIN[
Mode] & 0x03);
1239 (FIFFQEN[
Mode] << 7) | (FIFFQ[Mode] << 4);
1257 status |= mt2063_get_dnc_output_enable(state, &longval);
1258 status |= mt2063_set_dnc_output_enable(state, longval);
1263 (ACLNAMAX[
Mode] & 0x1F);
1271 (LNATGT[
Mode] & 0x3F);
1279 (ACRFMAX[
Mode] & 0x1F);
1287 (PD1TGT[
Mode] & 0x3F);
1306 (PD2TGT[
Mode] & 0x3F);
1314 (RFOVDIS[
Mode] ? 0x80 : 0x00);
1322 (FIFOVDIS[
Mode] ? 0x80 : 0x00);
1329 dprintk(1,
"mt2063 mode changed to %s\n",
1352 if ((Bits & 0xFF00) != 0) {
1359 if ((Bits & 0xFF) != 0) {
1385 status = mt2063_write(state,
1389 if (Shutdown != 1) {
1409 static u32 MT2063_Round_fLO(
u32 f_LO,
u32 f_LO_Step,
u32 f_ref)
1411 return f_ref * (f_LO / f_ref)
1412 + f_LO_Step * (((f_LO % f_ref) + (f_LO_Step / 2)) / f_LO_Step);
1433 static u32 MT2063_fLO_FractionalTerm(
u32 f_ref,
u32 num,
u32 denom)
1435 u32 t1 = (f_ref >> 14) * num;
1436 u32 term1 = t1 / denom;
1437 u32 loss = t1 % denom;
1439 (((f_ref & 0x00003FFF) * num + (loss << 14)) + (denom / 2)) / denom;
1440 return (term1 << 14) + term2;
1460 static u32 MT2063_CalcLO1Mult(
u32 *Div,
1463 u32 f_LO_Step,
u32 f_Ref)
1466 *Div = f_LO / f_Ref;
1470 (64 * (((f_LO % f_Ref) + (f_LO_Step / 2)) / f_LO_Step) +
1471 (f_Ref / f_LO_Step / 2)) / (f_Ref / f_LO_Step);
1473 return (f_Ref * (*Div)) + MT2063_fLO_FractionalTerm(f_Ref, *FracN, 64);
1493 static u32 MT2063_CalcLO2Mult(
u32 *Div,
1496 u32 f_LO_Step,
u32 f_Ref)
1499 *Div = f_LO / f_Ref;
1503 (8191 * (((f_LO % f_Ref) + (f_LO_Step / 2)) / f_LO_Step) +
1504 (f_Ref / f_LO_Step / 2)) / (f_Ref / f_LO_Step);
1506 return (f_Ref * (*Div)) + MT2063_fLO_FractionalTerm(f_Ref, *FracN,
1528 for (idx = 0; idx < 31; ++
idx) {
1552 const u8 LO1LK = 0x80;
1582 RFBand = FindClearTuneFilter(state, f_in);
1607 state->
AS_Data.f_if1_Request =
1608 MT2063_Round_fLO(state->
AS_Data.f_if1_Request + f_in,
1616 MT2063_ResetExclZones(&state->
AS_Data);
1618 f_IF1 = MT2063_ChooseFirstIF(&state->
AS_Data);
1621 MT2063_Round_fLO(f_IF1 + f_in, state->
AS_Data.f_LO1_Step,
1625 MT2063_Round_fLO(state->
AS_Data.f_LO1 - state->
AS_Data.f_out - f_in,
1632 status |= MT2063_AvoidSpurs(&state->
AS_Data);
1639 MT2063_CalcLO1Mult(&LO1, &Num1, state->
AS_Data.f_LO1,
1642 MT2063_Round_fLO(state->
AS_Data.f_LO1 - state->
AS_Data.f_out - f_in,
1645 MT2063_CalcLO2Mult(&LO2, &Num2, state->
AS_Data.f_LO2,
1665 if ((ofLO1 != state->
AS_Data.f_LO1)
1666 || (ofLO2 != state->
AS_Data.f_LO2)
1678 f_in) / (state->
AS_Data.f_ref / 64) - 8 * (
u32) fiffc -
1726 status = mt2063_lockStatus(state);
1741 static const u8 MT2063B0_defaults[] = {
1766 static const u8 MT2063B1_defaults[] = {
1793 static const u8 MT2063B3_defaults[] = {
1808 u8 all_resets = 0xF0;
1871 def = MT2063B3_defaults;
1875 def = MT2063B1_defaults;
1879 def = MT2063B0_defaults;
1887 while (status >= 0 && *def) {
1890 status = mt2063_write(state, reg, &val, 1);
1898 while (status >= 0 && (FCRUN != 0) && (maxReads-- > 0)) {
1900 status = mt2063_read(state,
1907 if (FCRUN != 0 || status < 0)
1910 status = mt2063_read(state,
1917 status = mt2063_read(state,
2006 for (i = 0; i < 31; i++)
2009 status = MT2063_SoftwareShutdown(state, 1);
2012 status = MT2063_ClearPowerMaskBits(state, MT2063_ALL_SD);
2032 status = mt2063_lockStatus(state);
2038 dprintk(1,
"Tuner status: %d", *tuner_status);
2055 static int mt2063_set_analog_params(
struct dvb_frontend *fe,
2069 status = mt2063_init(fe);
2074 switch (params->
mode) {
2076 pict_car = 38900000;
2078 pict2chanb_vsb = -(ch_bw / 2);
2084 pict_car = 38900000;
2086 pict2chanb_vsb = -1250000;
2088 pict_car = 38900000;
2090 pict2chanb_vsb = -1250000;
2092 pict_car = 38900000;
2094 pict2chanb_vsb = -1250000;
2100 if_mid = pict_car - (pict2chanb_vsb + (ch_bw / 2));
2102 state->
AS_Data.f_LO2_Step = 125000;
2103 state->
AS_Data.f_out = if_mid;
2104 state->
AS_Data.f_out_bw = ch_bw + 750000;
2105 status = MT2063_SetReceiverMode(state, rcvr_mode);
2109 dprintk(1,
"Tuning to frequency: %d, bandwidth %d, foffset %d\n",
2110 params->
frequency, ch_bw, pict2chanb_vsb);
2112 status = MT2063_Tune(state, (params->
frequency + (pict2chanb_vsb + (ch_bw / 2))));
2127 #define MAX_SYMBOL_RATE_6MHz 5217391
2141 status = mt2063_init(fe);
2160 pict_car = 36125000;
2161 pict2chanb_vsb = -(ch_bw / 2);
2166 pict_car = 36125000;
2167 pict2chanb_vsb = -(ch_bw / 2);
2172 if_mid = pict_car - (pict2chanb_vsb + (ch_bw / 2));
2174 state->
AS_Data.f_LO2_Step = 125000;
2175 state->
AS_Data.f_out = if_mid;
2176 state->
AS_Data.f_out_bw = ch_bw + 750000;
2177 status = MT2063_SetReceiverMode(state, rcvr_mode);
2181 dprintk(1,
"Tuning to frequency: %d, bandwidth %d, foffset %d\n",
2184 status = MT2063_Tune(state, (c->
frequency + (pict2chanb_vsb + (ch_bw / 2))));
2204 dprintk(1,
"IF frequency: %d\n", *freq);
2218 *bw = state->
AS_Data.f_out_bw - 750000;
2220 dprintk(1,
"bandwidth: %d\n", *bw);
2227 .name =
"MT2063 Silicon Tuner",
2228 .frequency_min = 45000000,
2229 .frequency_max = 865000000,
2230 .frequency_step = 0,
2233 .init = mt2063_init,
2234 .sleep = MT2063_Sleep,
2235 .get_status = mt2063_get_status,
2236 .set_analog_params = mt2063_set_analog_params,
2237 .set_params = mt2063_set_params,
2238 .get_if_frequency = mt2063_get_if_frequency,
2239 .get_bandwidth = mt2063_get_bandwidth,
2240 .release = mt2063_release,
2260 fe->
ops.tuner_ops = mt2063_ops;
2272 static int tuner_MT2063_SoftwareShutdown(
struct dvb_frontend *fe)
2279 err = MT2063_SoftwareShutdown(state, 1);
2286 static int tuner_MT2063_ClearPowerMaskBits(
struct dvb_frontend *fe)
2293 err = MT2063_ClearPowerMaskBits(state, MT2063_ALL_SD);