diff options
Diffstat (limited to 'drivers/media/dvb/frontends')
| -rw-r--r-- | drivers/media/dvb/frontends/Kconfig | 28 | ||||
| -rw-r--r-- | drivers/media/dvb/frontends/Makefile | 3 | ||||
| -rw-r--r-- | drivers/media/dvb/frontends/dvb-pll.c | 340 | ||||
| -rw-r--r-- | drivers/media/dvb/frontends/dvb-pll.h | 16 | ||||
| -rw-r--r-- | drivers/media/dvb/frontends/lgdt330x.c | 4 | ||||
| -rw-r--r-- | drivers/media/dvb/frontends/lgh06xf.c | 134 | ||||
| -rw-r--r-- | drivers/media/dvb/frontends/lgh06xf.h | 35 | ||||
| -rw-r--r-- | drivers/media/dvb/frontends/or51132.c | 305 | ||||
| -rw-r--r-- | drivers/media/dvb/frontends/tda10021.c | 47 | ||||
| -rw-r--r-- | drivers/media/dvb/frontends/tda10023.c | 540 | ||||
| -rw-r--r-- | drivers/media/dvb/frontends/tda1002x.h (renamed from drivers/media/dvb/frontends/tda10021.h) | 33 | ||||
| -rw-r--r-- | drivers/media/dvb/frontends/tda1004x.c | 98 | ||||
| -rw-r--r-- | drivers/media/dvb/frontends/tda1004x.h | 54 | ||||
| -rw-r--r-- | drivers/media/dvb/frontends/tda827x.c | 512 | ||||
| -rw-r--r-- | drivers/media/dvb/frontends/tda827x.h | 62 |
15 files changed, 1632 insertions, 579 deletions
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig index 22c2cf2cea98..ff448761dcef 100644 --- a/drivers/media/dvb/frontends/Kconfig +++ b/drivers/media/dvb/frontends/Kconfig | |||
| @@ -205,6 +205,13 @@ config DVB_TDA10021 | |||
| 205 | help | 205 | help |
| 206 | A DVB-C tuner module. Say Y when you want to support this frontend. | 206 | A DVB-C tuner module. Say Y when you want to support this frontend. |
| 207 | 207 | ||
| 208 | config DVB_TDA10023 | ||
| 209 | tristate "Philips TDA10023 based" | ||
| 210 | depends on DVB_CORE && I2C | ||
| 211 | default m if DVB_FE_CUSTOMISE | ||
| 212 | help | ||
| 213 | A DVB-C tuner module. Say Y when you want to support this frontend. | ||
| 214 | |||
| 208 | config DVB_STV0297 | 215 | config DVB_STV0297 |
| 209 | tristate "ST STV0297 based" | 216 | tristate "ST STV0297 based" |
| 210 | depends on DVB_CORE && I2C | 217 | depends on DVB_CORE && I2C |
| @@ -280,8 +287,12 @@ comment "Tuners/PLL support" | |||
| 280 | depends on DVB_CORE | 287 | depends on DVB_CORE |
| 281 | 288 | ||
| 282 | config DVB_PLL | 289 | config DVB_PLL |
| 283 | tristate | 290 | tristate "Generic I2C PLL based tuners" |
| 284 | depends on DVB_CORE && I2C | 291 | depends on DVB_CORE && I2C |
| 292 | default m if DVB_FE_CUSTOMISE | ||
| 293 | help | ||
| 294 | This module driver a number of tuners based on PLL chips with a | ||
| 295 | common I2C interface. Say Y when you want to support these tuners. | ||
| 285 | 296 | ||
| 286 | config DVB_TDA826X | 297 | config DVB_TDA826X |
| 287 | tristate "Philips TDA826X silicon tuner" | 298 | tristate "Philips TDA826X silicon tuner" |
| @@ -290,6 +301,13 @@ config DVB_TDA826X | |||
| 290 | help | 301 | help |
| 291 | A DVB-S silicon tuner module. Say Y when you want to support this tuner. | 302 | A DVB-S silicon tuner module. Say Y when you want to support this tuner. |
| 292 | 303 | ||
| 304 | config DVB_TDA827X | ||
| 305 | tristate "Philips TDA827X silicon tuner" | ||
| 306 | depends on DVB_CORE && I2C | ||
| 307 | default m if DVB_FE_CUSTOMISE | ||
| 308 | help | ||
| 309 | A DVB-T silicon tuner module. Say Y when you want to support this tuner. | ||
| 310 | |||
| 293 | config DVB_TUNER_QT1010 | 311 | config DVB_TUNER_QT1010 |
| 294 | tristate "Quantek QT1010 silicon tuner" | 312 | tristate "Quantek QT1010 silicon tuner" |
| 295 | depends on DVB_CORE && I2C | 313 | depends on DVB_CORE && I2C |
| @@ -304,14 +322,6 @@ config DVB_TUNER_MT2060 | |||
| 304 | help | 322 | help |
| 305 | A driver for the silicon IF tuner MT2060 from Microtune. | 323 | A driver for the silicon IF tuner MT2060 from Microtune. |
| 306 | 324 | ||
| 307 | config DVB_TUNER_LGH06XF | ||
| 308 | tristate "LG TDVS-H06xF ATSC tuner" | ||
| 309 | depends on DVB_CORE && I2C | ||
| 310 | select DVB_PLL | ||
| 311 | default m if DVB_FE_CUSTOMISE | ||
| 312 | help | ||
| 313 | A driver for the LG TDVS-H06xF ATSC tuner family. | ||
| 314 | |||
| 315 | comment "Miscellaneous devices" | 325 | comment "Miscellaneous devices" |
| 316 | depends on DVB_CORE | 326 | depends on DVB_CORE |
| 317 | 327 | ||
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile index a646d9969b71..27f386585d43 100644 --- a/drivers/media/dvb/frontends/Makefile +++ b/drivers/media/dvb/frontends/Makefile | |||
| @@ -25,6 +25,7 @@ obj-$(CONFIG_DVB_MT352) += mt352.o | |||
| 25 | obj-$(CONFIG_DVB_ZL10353) += zl10353.o | 25 | obj-$(CONFIG_DVB_ZL10353) += zl10353.o |
| 26 | obj-$(CONFIG_DVB_CX22702) += cx22702.o | 26 | obj-$(CONFIG_DVB_CX22702) += cx22702.o |
| 27 | obj-$(CONFIG_DVB_TDA10021) += tda10021.o | 27 | obj-$(CONFIG_DVB_TDA10021) += tda10021.o |
| 28 | obj-$(CONFIG_DVB_TDA10023) += tda10023.o | ||
| 28 | obj-$(CONFIG_DVB_STV0297) += stv0297.o | 29 | obj-$(CONFIG_DVB_STV0297) += stv0297.o |
| 29 | obj-$(CONFIG_DVB_NXT200X) += nxt200x.o | 30 | obj-$(CONFIG_DVB_NXT200X) += nxt200x.o |
| 30 | obj-$(CONFIG_DVB_OR51211) += or51211.o | 31 | obj-$(CONFIG_DVB_OR51211) += or51211.o |
| @@ -37,7 +38,7 @@ obj-$(CONFIG_DVB_LNBP21) += lnbp21.o | |||
| 37 | obj-$(CONFIG_DVB_ISL6421) += isl6421.o | 38 | obj-$(CONFIG_DVB_ISL6421) += isl6421.o |
| 38 | obj-$(CONFIG_DVB_TDA10086) += tda10086.o | 39 | obj-$(CONFIG_DVB_TDA10086) += tda10086.o |
| 39 | obj-$(CONFIG_DVB_TDA826X) += tda826x.o | 40 | obj-$(CONFIG_DVB_TDA826X) += tda826x.o |
| 41 | obj-$(CONFIG_DVB_TDA827X) += tda827x.o | ||
| 40 | obj-$(CONFIG_DVB_TUNER_MT2060) += mt2060.o | 42 | obj-$(CONFIG_DVB_TUNER_MT2060) += mt2060.o |
| 41 | obj-$(CONFIG_DVB_TUNER_QT1010) += qt1010.o | 43 | obj-$(CONFIG_DVB_TUNER_QT1010) += qt1010.o |
| 42 | obj-$(CONFIG_DVB_TUA6100) += tua6100.o | 44 | obj-$(CONFIG_DVB_TUA6100) += tua6100.o |
| 43 | obj-$(CONFIG_DVB_TUNER_LGH06XF) += lgh06xf.o | ||
diff --git a/drivers/media/dvb/frontends/dvb-pll.c b/drivers/media/dvb/frontends/dvb-pll.c index 62de760c844f..5f96ffda91ad 100644 --- a/drivers/media/dvb/frontends/dvb-pll.c +++ b/drivers/media/dvb/frontends/dvb-pll.c | |||
| @@ -27,17 +27,29 @@ | |||
| 27 | /* ----------------------------------------------------------- */ | 27 | /* ----------------------------------------------------------- */ |
| 28 | /* descriptions */ | 28 | /* descriptions */ |
| 29 | 29 | ||
| 30 | /* Set AGC TOP value to 103 dBuV: | ||
| 31 | 0x80 = Control Byte | ||
| 32 | 0x40 = 250 uA charge pump (irrelevant) | ||
| 33 | 0x18 = Aux Byte to follow | ||
| 34 | 0x06 = 64.5 kHz divider (irrelevant) | ||
| 35 | 0x01 = Disable Vt (aka sleep) | ||
| 36 | |||
| 37 | 0x00 = AGC Time constant 2s Iagc = 300 nA (vs 0x80 = 9 nA) | ||
| 38 | 0x50 = AGC Take over point = 103 dBuV */ | ||
| 39 | static u8 tua603x_agc103[] = { 2, 0x80|0x40|0x18|0x06|0x01, 0x00|0x50 }; | ||
| 40 | |||
| 30 | struct dvb_pll_desc dvb_pll_thomson_dtt7579 = { | 41 | struct dvb_pll_desc dvb_pll_thomson_dtt7579 = { |
| 31 | .name = "Thomson dtt7579", | 42 | .name = "Thomson dtt7579", |
| 32 | .min = 177000000, | 43 | .min = 177000000, |
| 33 | .max = 858000000, | 44 | .max = 858000000, |
| 34 | .count = 5, | 45 | .iffreq= 36166667, |
| 46 | .sleepdata = (u8[]){ 2, 0xb4, 0x03 }, | ||
| 47 | .count = 4, | ||
| 35 | .entries = { | 48 | .entries = { |
| 36 | { 0, 36166667, 166666, 0xb4, 0x03 }, /* go sleep */ | 49 | { 443250000, 166667, 0xb4, 0x02 }, |
| 37 | { 443250000, 36166667, 166666, 0xb4, 0x02 }, | 50 | { 542000000, 166667, 0xb4, 0x08 }, |
| 38 | { 542000000, 36166667, 166666, 0xb4, 0x08 }, | 51 | { 771000000, 166667, 0xbc, 0x08 }, |
| 39 | { 771000000, 36166667, 166666, 0xbc, 0x08 }, | 52 | { 999999999, 166667, 0xf4, 0x08 }, |
| 40 | { 999999999, 36166667, 166666, 0xf4, 0x08 }, | ||
| 41 | }, | 53 | }, |
| 42 | }; | 54 | }; |
| 43 | EXPORT_SYMBOL(dvb_pll_thomson_dtt7579); | 55 | EXPORT_SYMBOL(dvb_pll_thomson_dtt7579); |
| @@ -46,11 +58,12 @@ struct dvb_pll_desc dvb_pll_thomson_dtt7610 = { | |||
| 46 | .name = "Thomson dtt7610", | 58 | .name = "Thomson dtt7610", |
| 47 | .min = 44000000, | 59 | .min = 44000000, |
| 48 | .max = 958000000, | 60 | .max = 958000000, |
| 61 | .iffreq= 44000000, | ||
| 49 | .count = 3, | 62 | .count = 3, |
| 50 | .entries = { | 63 | .entries = { |
| 51 | { 157250000, 44000000, 62500, 0x8e, 0x39 }, | 64 | { 157250000, 62500, 0x8e, 0x39 }, |
| 52 | { 454000000, 44000000, 62500, 0x8e, 0x3a }, | 65 | { 454000000, 62500, 0x8e, 0x3a }, |
| 53 | { 999999999, 44000000, 62500, 0x8e, 0x3c }, | 66 | { 999999999, 62500, 0x8e, 0x3c }, |
| 54 | }, | 67 | }, |
| 55 | }; | 68 | }; |
| 56 | EXPORT_SYMBOL(dvb_pll_thomson_dtt7610); | 69 | EXPORT_SYMBOL(dvb_pll_thomson_dtt7610); |
| @@ -66,14 +79,15 @@ struct dvb_pll_desc dvb_pll_thomson_dtt759x = { | |||
| 66 | .min = 177000000, | 79 | .min = 177000000, |
| 67 | .max = 896000000, | 80 | .max = 896000000, |
| 68 | .setbw = thomson_dtt759x_bw, | 81 | .setbw = thomson_dtt759x_bw, |
| 69 | .count = 6, | 82 | .iffreq= 36166667, |
| 83 | .sleepdata = (u8[]){ 2, 0x84, 0x03 }, | ||
| 84 | .count = 5, | ||
| 70 | .entries = { | 85 | .entries = { |
| 71 | { 0, 36166667, 166666, 0x84, 0x03 }, | 86 | { 264000000, 166667, 0xb4, 0x02 }, |
| 72 | { 264000000, 36166667, 166666, 0xb4, 0x02 }, | 87 | { 470000000, 166667, 0xbc, 0x02 }, |
| 73 | { 470000000, 36166667, 166666, 0xbc, 0x02 }, | 88 | { 735000000, 166667, 0xbc, 0x08 }, |
| 74 | { 735000000, 36166667, 166666, 0xbc, 0x08 }, | 89 | { 835000000, 166667, 0xf4, 0x08 }, |
| 75 | { 835000000, 36166667, 166666, 0xf4, 0x08 }, | 90 | { 999999999, 166667, 0xfc, 0x08 }, |
| 76 | { 999999999, 36166667, 166666, 0xfc, 0x08 }, | ||
| 77 | }, | 91 | }, |
| 78 | }; | 92 | }; |
| 79 | EXPORT_SYMBOL(dvb_pll_thomson_dtt759x); | 93 | EXPORT_SYMBOL(dvb_pll_thomson_dtt759x); |
| @@ -82,14 +96,15 @@ struct dvb_pll_desc dvb_pll_lg_z201 = { | |||
| 82 | .name = "LG z201", | 96 | .name = "LG z201", |
| 83 | .min = 174000000, | 97 | .min = 174000000, |
| 84 | .max = 862000000, | 98 | .max = 862000000, |
| 85 | .count = 6, | 99 | .iffreq= 36166667, |
| 100 | .sleepdata = (u8[]){ 2, 0xbc, 0x03 }, | ||
| 101 | .count = 5, | ||
| 86 | .entries = { | 102 | .entries = { |
| 87 | { 0, 36166667, 166666, 0xbc, 0x03 }, | 103 | { 157500000, 166667, 0xbc, 0x01 }, |
| 88 | { 157500000, 36166667, 166666, 0xbc, 0x01 }, | 104 | { 443250000, 166667, 0xbc, 0x02 }, |
| 89 | { 443250000, 36166667, 166666, 0xbc, 0x02 }, | 105 | { 542000000, 166667, 0xbc, 0x04 }, |
| 90 | { 542000000, 36166667, 166666, 0xbc, 0x04 }, | 106 | { 830000000, 166667, 0xf4, 0x04 }, |
| 91 | { 830000000, 36166667, 166666, 0xf4, 0x04 }, | 107 | { 999999999, 166667, 0xfc, 0x04 }, |
| 92 | { 999999999, 36166667, 166666, 0xfc, 0x04 }, | ||
| 93 | }, | 108 | }, |
| 94 | }; | 109 | }; |
| 95 | EXPORT_SYMBOL(dvb_pll_lg_z201); | 110 | EXPORT_SYMBOL(dvb_pll_lg_z201); |
| @@ -98,11 +113,12 @@ struct dvb_pll_desc dvb_pll_microtune_4042 = { | |||
| 98 | .name = "Microtune 4042 FI5", | 113 | .name = "Microtune 4042 FI5", |
| 99 | .min = 57000000, | 114 | .min = 57000000, |
| 100 | .max = 858000000, | 115 | .max = 858000000, |
| 116 | .iffreq= 44000000, | ||
| 101 | .count = 3, | 117 | .count = 3, |
| 102 | .entries = { | 118 | .entries = { |
| 103 | { 162000000, 44000000, 62500, 0x8e, 0xa1 }, | 119 | { 162000000, 62500, 0x8e, 0xa1 }, |
| 104 | { 457000000, 44000000, 62500, 0x8e, 0x91 }, | 120 | { 457000000, 62500, 0x8e, 0x91 }, |
| 105 | { 999999999, 44000000, 62500, 0x8e, 0x31 }, | 121 | { 999999999, 62500, 0x8e, 0x31 }, |
| 106 | }, | 122 | }, |
| 107 | }; | 123 | }; |
| 108 | EXPORT_SYMBOL(dvb_pll_microtune_4042); | 124 | EXPORT_SYMBOL(dvb_pll_microtune_4042); |
| @@ -112,11 +128,13 @@ struct dvb_pll_desc dvb_pll_thomson_dtt761x = { | |||
| 112 | .name = "Thomson dtt761x", | 128 | .name = "Thomson dtt761x", |
| 113 | .min = 57000000, | 129 | .min = 57000000, |
| 114 | .max = 863000000, | 130 | .max = 863000000, |
| 131 | .iffreq= 44000000, | ||
| 115 | .count = 3, | 132 | .count = 3, |
| 133 | .initdata = tua603x_agc103, | ||
| 116 | .entries = { | 134 | .entries = { |
| 117 | { 147000000, 44000000, 62500, 0x8e, 0x39 }, | 135 | { 147000000, 62500, 0x8e, 0x39 }, |
| 118 | { 417000000, 44000000, 62500, 0x8e, 0x3a }, | 136 | { 417000000, 62500, 0x8e, 0x3a }, |
| 119 | { 999999999, 44000000, 62500, 0x8e, 0x3c }, | 137 | { 999999999, 62500, 0x8e, 0x3c }, |
| 120 | }, | 138 | }, |
| 121 | }; | 139 | }; |
| 122 | EXPORT_SYMBOL(dvb_pll_thomson_dtt761x); | 140 | EXPORT_SYMBOL(dvb_pll_thomson_dtt761x); |
| @@ -125,17 +143,18 @@ struct dvb_pll_desc dvb_pll_unknown_1 = { | |||
| 125 | .name = "unknown 1", /* used by dntv live dvb-t */ | 143 | .name = "unknown 1", /* used by dntv live dvb-t */ |
| 126 | .min = 174000000, | 144 | .min = 174000000, |
| 127 | .max = 862000000, | 145 | .max = 862000000, |
| 146 | .iffreq= 36166667, | ||
| 128 | .count = 9, | 147 | .count = 9, |
| 129 | .entries = { | 148 | .entries = { |
| 130 | { 150000000, 36166667, 166666, 0xb4, 0x01 }, | 149 | { 150000000, 166667, 0xb4, 0x01 }, |
| 131 | { 173000000, 36166667, 166666, 0xbc, 0x01 }, | 150 | { 173000000, 166667, 0xbc, 0x01 }, |
| 132 | { 250000000, 36166667, 166666, 0xb4, 0x02 }, | 151 | { 250000000, 166667, 0xb4, 0x02 }, |
| 133 | { 400000000, 36166667, 166666, 0xbc, 0x02 }, | 152 | { 400000000, 166667, 0xbc, 0x02 }, |
| 134 | { 420000000, 36166667, 166666, 0xf4, 0x02 }, | 153 | { 420000000, 166667, 0xf4, 0x02 }, |
| 135 | { 470000000, 36166667, 166666, 0xfc, 0x02 }, | 154 | { 470000000, 166667, 0xfc, 0x02 }, |
| 136 | { 600000000, 36166667, 166666, 0xbc, 0x08 }, | 155 | { 600000000, 166667, 0xbc, 0x08 }, |
| 137 | { 730000000, 36166667, 166666, 0xf4, 0x08 }, | 156 | { 730000000, 166667, 0xf4, 0x08 }, |
| 138 | { 999999999, 36166667, 166666, 0xfc, 0x08 }, | 157 | { 999999999, 166667, 0xfc, 0x08 }, |
| 139 | }, | 158 | }, |
| 140 | }; | 159 | }; |
| 141 | EXPORT_SYMBOL(dvb_pll_unknown_1); | 160 | EXPORT_SYMBOL(dvb_pll_unknown_1); |
| @@ -147,11 +166,12 @@ struct dvb_pll_desc dvb_pll_tua6010xs = { | |||
| 147 | .name = "Infineon TUA6010XS", | 166 | .name = "Infineon TUA6010XS", |
| 148 | .min = 44250000, | 167 | .min = 44250000, |
| 149 | .max = 858000000, | 168 | .max = 858000000, |
| 169 | .iffreq= 36125000, | ||
| 150 | .count = 3, | 170 | .count = 3, |
| 151 | .entries = { | 171 | .entries = { |
| 152 | { 115750000, 36125000, 62500, 0x8e, 0x03 }, | 172 | { 115750000, 62500, 0x8e, 0x03 }, |
| 153 | { 403250000, 36125000, 62500, 0x8e, 0x06 }, | 173 | { 403250000, 62500, 0x8e, 0x06 }, |
| 154 | { 999999999, 36125000, 62500, 0x8e, 0x85 }, | 174 | { 999999999, 62500, 0x8e, 0x85 }, |
| 155 | }, | 175 | }, |
| 156 | }; | 176 | }; |
| 157 | EXPORT_SYMBOL(dvb_pll_tua6010xs); | 177 | EXPORT_SYMBOL(dvb_pll_tua6010xs); |
| @@ -161,12 +181,13 @@ struct dvb_pll_desc dvb_pll_env57h1xd5 = { | |||
| 161 | .name = "Panasonic ENV57H1XD5", | 181 | .name = "Panasonic ENV57H1XD5", |
| 162 | .min = 44250000, | 182 | .min = 44250000, |
| 163 | .max = 858000000, | 183 | .max = 858000000, |
| 184 | .iffreq= 36125000, | ||
| 164 | .count = 4, | 185 | .count = 4, |
| 165 | .entries = { | 186 | .entries = { |
| 166 | { 153000000, 36291666, 166666, 0xc2, 0x41 }, | 187 | { 153000000, 166667, 0xc2, 0x41 }, |
| 167 | { 470000000, 36291666, 166666, 0xc2, 0x42 }, | 188 | { 470000000, 166667, 0xc2, 0x42 }, |
| 168 | { 526000000, 36291666, 166666, 0xc2, 0x84 }, | 189 | { 526000000, 166667, 0xc2, 0x84 }, |
| 169 | { 999999999, 36291666, 166666, 0xc2, 0xa4 }, | 190 | { 999999999, 166667, 0xc2, 0xa4 }, |
| 170 | }, | 191 | }, |
| 171 | }; | 192 | }; |
| 172 | EXPORT_SYMBOL(dvb_pll_env57h1xd5); | 193 | EXPORT_SYMBOL(dvb_pll_env57h1xd5); |
| @@ -185,20 +206,21 @@ struct dvb_pll_desc dvb_pll_tda665x = { | |||
| 185 | .min = 44250000, | 206 | .min = 44250000, |
| 186 | .max = 858000000, | 207 | .max = 858000000, |
| 187 | .setbw = tda665x_bw, | 208 | .setbw = tda665x_bw, |
| 209 | .iffreq= 36166667, | ||
| 188 | .count = 12, | 210 | .count = 12, |
| 189 | .entries = { | 211 | .entries = { |
| 190 | { 93834000, 36249333, 166667, 0xca, 0x61 /* 011 0 0 0 01 */ }, | 212 | { 93834000, 166667, 0xca, 0x61 /* 011 0 0 0 01 */ }, |
| 191 | { 123834000, 36249333, 166667, 0xca, 0xa1 /* 101 0 0 0 01 */ }, | 213 | { 123834000, 166667, 0xca, 0xa1 /* 101 0 0 0 01 */ }, |
| 192 | { 161000000, 36249333, 166667, 0xca, 0xa1 /* 101 0 0 0 01 */ }, | 214 | { 161000000, 166667, 0xca, 0xa1 /* 101 0 0 0 01 */ }, |
| 193 | { 163834000, 36249333, 166667, 0xca, 0xc2 /* 110 0 0 0 10 */ }, | 215 | { 163834000, 166667, 0xca, 0xc2 /* 110 0 0 0 10 */ }, |
| 194 | { 253834000, 36249333, 166667, 0xca, 0x62 /* 011 0 0 0 10 */ }, | 216 | { 253834000, 166667, 0xca, 0x62 /* 011 0 0 0 10 */ }, |
| 195 | { 383834000, 36249333, 166667, 0xca, 0xa2 /* 101 0 0 0 10 */ }, | 217 | { 383834000, 166667, 0xca, 0xa2 /* 101 0 0 0 10 */ }, |
| 196 | { 443834000, 36249333, 166667, 0xca, 0xc2 /* 110 0 0 0 10 */ }, | 218 | { 443834000, 166667, 0xca, 0xc2 /* 110 0 0 0 10 */ }, |
| 197 | { 444000000, 36249333, 166667, 0xca, 0xc4 /* 110 0 0 1 00 */ }, | 219 | { 444000000, 166667, 0xca, 0xc4 /* 110 0 0 1 00 */ }, |
| 198 | { 583834000, 36249333, 166667, 0xca, 0x64 /* 011 0 0 1 00 */ }, | 220 | { 583834000, 166667, 0xca, 0x64 /* 011 0 0 1 00 */ }, |
| 199 | { 793834000, 36249333, 166667, 0xca, 0xa4 /* 101 0 0 1 00 */ }, | 221 | { 793834000, 166667, 0xca, 0xa4 /* 101 0 0 1 00 */ }, |
| 200 | { 444834000, 36249333, 166667, 0xca, 0xc4 /* 110 0 0 1 00 */ }, | 222 | { 444834000, 166667, 0xca, 0xc4 /* 110 0 0 1 00 */ }, |
| 201 | { 861000000, 36249333, 166667, 0xca, 0xe4 /* 111 0 0 1 00 */ }, | 223 | { 861000000, 166667, 0xca, 0xe4 /* 111 0 0 1 00 */ }, |
| 202 | } | 224 | } |
| 203 | }; | 225 | }; |
| 204 | EXPORT_SYMBOL(dvb_pll_tda665x); | 226 | EXPORT_SYMBOL(dvb_pll_tda665x); |
| @@ -216,12 +238,13 @@ struct dvb_pll_desc dvb_pll_tua6034 = { | |||
| 216 | .name = "Infineon TUA6034", | 238 | .name = "Infineon TUA6034", |
| 217 | .min = 44250000, | 239 | .min = 44250000, |
| 218 | .max = 858000000, | 240 | .max = 858000000, |
| 241 | .iffreq= 36166667, | ||
| 219 | .count = 3, | 242 | .count = 3, |
| 220 | .setbw = tua6034_bw, | 243 | .setbw = tua6034_bw, |
| 221 | .entries = { | 244 | .entries = { |
| 222 | { 174500000, 36166667, 62500, 0xce, 0x01 }, | 245 | { 174500000, 62500, 0xce, 0x01 }, |
| 223 | { 230000000, 36166667, 62500, 0xce, 0x02 }, | 246 | { 230000000, 62500, 0xce, 0x02 }, |
| 224 | { 999999999, 36166667, 62500, 0xce, 0x04 }, | 247 | { 999999999, 62500, 0xce, 0x04 }, |
| 225 | }, | 248 | }, |
| 226 | }; | 249 | }; |
| 227 | EXPORT_SYMBOL(dvb_pll_tua6034); | 250 | EXPORT_SYMBOL(dvb_pll_tua6034); |
| @@ -233,11 +256,13 @@ struct dvb_pll_desc dvb_pll_lg_tdvs_h06xf = { | |||
| 233 | .name = "LG TDVS-H06xF", | 256 | .name = "LG TDVS-H06xF", |
| 234 | .min = 54000000, | 257 | .min = 54000000, |
| 235 | .max = 863000000, | 258 | .max = 863000000, |
| 259 | .iffreq= 44000000, | ||
| 260 | .initdata = tua603x_agc103, | ||
| 236 | .count = 3, | 261 | .count = 3, |
| 237 | .entries = { | 262 | .entries = { |
| 238 | { 165000000, 44000000, 62500, 0xce, 0x01 }, | 263 | { 165000000, 62500, 0xce, 0x01 }, |
| 239 | { 450000000, 44000000, 62500, 0xce, 0x02 }, | 264 | { 450000000, 62500, 0xce, 0x02 }, |
| 240 | { 999999999, 44000000, 62500, 0xce, 0x04 }, | 265 | { 999999999, 62500, 0xce, 0x04 }, |
| 241 | }, | 266 | }, |
| 242 | }; | 267 | }; |
| 243 | EXPORT_SYMBOL(dvb_pll_lg_tdvs_h06xf); | 268 | EXPORT_SYMBOL(dvb_pll_lg_tdvs_h06xf); |
| @@ -255,16 +280,17 @@ struct dvb_pll_desc dvb_pll_fmd1216me = { | |||
| 255 | .name = "Philips FMD1216ME", | 280 | .name = "Philips FMD1216ME", |
| 256 | .min = 50870000, | 281 | .min = 50870000, |
| 257 | .max = 858000000, | 282 | .max = 858000000, |
| 283 | .iffreq= 36125000, | ||
| 258 | .setbw = fmd1216me_bw, | 284 | .setbw = fmd1216me_bw, |
| 259 | .count = 7, | 285 | .count = 7, |
| 260 | .entries = { | 286 | .entries = { |
| 261 | { 143870000, 36213333, 166667, 0xbc, 0x41 }, | 287 | { 143870000, 166667, 0xbc, 0x41 }, |
| 262 | { 158870000, 36213333, 166667, 0xf4, 0x41 }, | 288 | { 158870000, 166667, 0xf4, 0x41 }, |
| 263 | { 329870000, 36213333, 166667, 0xbc, 0x42 }, | 289 | { 329870000, 166667, 0xbc, 0x42 }, |
| 264 | { 441870000, 36213333, 166667, 0xf4, 0x42 }, | 290 | { 441870000, 166667, 0xf4, 0x42 }, |
| 265 | { 625870000, 36213333, 166667, 0xbc, 0x44 }, | 291 | { 625870000, 166667, 0xbc, 0x44 }, |
| 266 | { 803870000, 36213333, 166667, 0xf4, 0x44 }, | 292 | { 803870000, 166667, 0xf4, 0x44 }, |
| 267 | { 999999999, 36213333, 166667, 0xfc, 0x44 }, | 293 | { 999999999, 166667, 0xfc, 0x44 }, |
| 268 | } | 294 | } |
| 269 | }; | 295 | }; |
| 270 | EXPORT_SYMBOL(dvb_pll_fmd1216me); | 296 | EXPORT_SYMBOL(dvb_pll_fmd1216me); |
| @@ -282,13 +308,14 @@ struct dvb_pll_desc dvb_pll_tded4 = { | |||
| 282 | .name = "ALPS TDED4", | 308 | .name = "ALPS TDED4", |
| 283 | .min = 47000000, | 309 | .min = 47000000, |
| 284 | .max = 863000000, | 310 | .max = 863000000, |
| 311 | .iffreq= 36166667, | ||
| 285 | .setbw = tded4_bw, | 312 | .setbw = tded4_bw, |
| 286 | .count = 4, | 313 | .count = 4, |
| 287 | .entries = { | 314 | .entries = { |
| 288 | { 153000000, 36166667, 166667, 0x85, 0x01 }, | 315 | { 153000000, 166667, 0x85, 0x01 }, |
| 289 | { 470000000, 36166667, 166667, 0x85, 0x02 }, | 316 | { 470000000, 166667, 0x85, 0x02 }, |
| 290 | { 823000000, 36166667, 166667, 0x85, 0x08 }, | 317 | { 823000000, 166667, 0x85, 0x08 }, |
| 291 | { 999999999, 36166667, 166667, 0x85, 0x88 }, | 318 | { 999999999, 166667, 0x85, 0x88 }, |
| 292 | } | 319 | } |
| 293 | }; | 320 | }; |
| 294 | EXPORT_SYMBOL(dvb_pll_tded4); | 321 | EXPORT_SYMBOL(dvb_pll_tded4); |
| @@ -300,12 +327,13 @@ struct dvb_pll_desc dvb_pll_tdhu2 = { | |||
| 300 | .name = "ALPS TDHU2", | 327 | .name = "ALPS TDHU2", |
| 301 | .min = 54000000, | 328 | .min = 54000000, |
| 302 | .max = 864000000, | 329 | .max = 864000000, |
| 330 | .iffreq= 44000000, | ||
| 303 | .count = 4, | 331 | .count = 4, |
| 304 | .entries = { | 332 | .entries = { |
| 305 | { 162000000, 44000000, 62500, 0x85, 0x01 }, | 333 | { 162000000, 62500, 0x85, 0x01 }, |
| 306 | { 426000000, 44000000, 62500, 0x85, 0x02 }, | 334 | { 426000000, 62500, 0x85, 0x02 }, |
| 307 | { 782000000, 44000000, 62500, 0x85, 0x08 }, | 335 | { 782000000, 62500, 0x85, 0x08 }, |
| 308 | { 999999999, 44000000, 62500, 0x85, 0x88 }, | 336 | { 999999999, 62500, 0x85, 0x88 }, |
| 309 | } | 337 | } |
| 310 | }; | 338 | }; |
| 311 | EXPORT_SYMBOL(dvb_pll_tdhu2); | 339 | EXPORT_SYMBOL(dvb_pll_tdhu2); |
| @@ -317,11 +345,12 @@ struct dvb_pll_desc dvb_pll_tuv1236d = { | |||
| 317 | .name = "Philips TUV1236D", | 345 | .name = "Philips TUV1236D", |
| 318 | .min = 54000000, | 346 | .min = 54000000, |
| 319 | .max = 864000000, | 347 | .max = 864000000, |
| 348 | .iffreq= 44000000, | ||
| 320 | .count = 3, | 349 | .count = 3, |
| 321 | .entries = { | 350 | .entries = { |
| 322 | { 157250000, 44000000, 62500, 0xc6, 0x41 }, | 351 | { 157250000, 62500, 0xc6, 0x41 }, |
| 323 | { 454000000, 44000000, 62500, 0xc6, 0x42 }, | 352 | { 454000000, 62500, 0xc6, 0x42 }, |
| 324 | { 999999999, 44000000, 62500, 0xc6, 0x44 }, | 353 | { 999999999, 62500, 0xc6, 0x44 }, |
| 325 | }, | 354 | }, |
| 326 | }; | 355 | }; |
| 327 | EXPORT_SYMBOL(dvb_pll_tuv1236d); | 356 | EXPORT_SYMBOL(dvb_pll_tuv1236d); |
| @@ -333,14 +362,15 @@ struct dvb_pll_desc dvb_pll_samsung_tbmv = { | |||
| 333 | .name = "Samsung TBMV30111IN / TBMV30712IN1", | 362 | .name = "Samsung TBMV30111IN / TBMV30712IN1", |
| 334 | .min = 54000000, | 363 | .min = 54000000, |
| 335 | .max = 860000000, | 364 | .max = 860000000, |
| 365 | .iffreq= 44000000, | ||
| 336 | .count = 6, | 366 | .count = 6, |
| 337 | .entries = { | 367 | .entries = { |
| 338 | { 172000000, 44000000, 166666, 0xb4, 0x01 }, | 368 | { 172000000, 166667, 0xb4, 0x01 }, |
| 339 | { 214000000, 44000000, 166666, 0xb4, 0x02 }, | 369 | { 214000000, 166667, 0xb4, 0x02 }, |
| 340 | { 467000000, 44000000, 166666, 0xbc, 0x02 }, | 370 | { 467000000, 166667, 0xbc, 0x02 }, |
| 341 | { 721000000, 44000000, 166666, 0xbc, 0x08 }, | 371 | { 721000000, 166667, 0xbc, 0x08 }, |
| 342 | { 841000000, 44000000, 166666, 0xf4, 0x08 }, | 372 | { 841000000, 166667, 0xf4, 0x08 }, |
| 343 | { 999999999, 44000000, 166666, 0xfc, 0x02 }, | 373 | { 999999999, 166667, 0xfc, 0x02 }, |
| 344 | } | 374 | } |
| 345 | }; | 375 | }; |
| 346 | EXPORT_SYMBOL(dvb_pll_samsung_tbmv); | 376 | EXPORT_SYMBOL(dvb_pll_samsung_tbmv); |
| @@ -352,12 +382,13 @@ struct dvb_pll_desc dvb_pll_philips_sd1878_tda8261 = { | |||
| 352 | .name = "Philips SD1878", | 382 | .name = "Philips SD1878", |
| 353 | .min = 950000, | 383 | .min = 950000, |
| 354 | .max = 2150000, | 384 | .max = 2150000, |
| 385 | .iffreq= 249, /* zero-IF, offset 249 is to round up */ | ||
| 355 | .count = 4, | 386 | .count = 4, |
| 356 | .entries = { | 387 | .entries = { |
| 357 | { 1250000, 499, 500, 0xc4, 0x00}, | 388 | { 1250000, 500, 0xc4, 0x00}, |
| 358 | { 1550000, 499, 500, 0xc4, 0x40}, | 389 | { 1550000, 500, 0xc4, 0x40}, |
| 359 | { 2050000, 499, 500, 0xc4, 0x80}, | 390 | { 2050000, 500, 0xc4, 0x80}, |
| 360 | { 2150000, 499, 500, 0xc4, 0xc0}, | 391 | { 2150000, 500, 0xc4, 0xc0}, |
| 361 | }, | 392 | }, |
| 362 | }; | 393 | }; |
| 363 | EXPORT_SYMBOL(dvb_pll_philips_sd1878_tda8261); | 394 | EXPORT_SYMBOL(dvb_pll_philips_sd1878_tda8261); |
| @@ -388,18 +419,19 @@ struct dvb_pll_desc dvb_pll_philips_td1316 = { | |||
| 388 | .name = "Philips TD1316", | 419 | .name = "Philips TD1316", |
| 389 | .min = 87000000, | 420 | .min = 87000000, |
| 390 | .max = 895000000, | 421 | .max = 895000000, |
| 422 | .iffreq= 36166667, | ||
| 391 | .setbw = td1316_bw, | 423 | .setbw = td1316_bw, |
| 392 | .count = 9, | 424 | .count = 9, |
| 393 | .entries = { | 425 | .entries = { |
| 394 | { 93834000, 36166000, 166666, 0xca, 0x60}, | 426 | { 93834000, 166667, 0xca, 0x60}, |
| 395 | { 123834000, 36166000, 166666, 0xca, 0xa0}, | 427 | { 123834000, 166667, 0xca, 0xa0}, |
| 396 | { 163834000, 36166000, 166666, 0xca, 0xc0}, | 428 | { 163834000, 166667, 0xca, 0xc0}, |
| 397 | { 253834000, 36166000, 166666, 0xca, 0x60}, | 429 | { 253834000, 166667, 0xca, 0x60}, |
| 398 | { 383834000, 36166000, 166666, 0xca, 0xa0}, | 430 | { 383834000, 166667, 0xca, 0xa0}, |
| 399 | { 443834000, 36166000, 166666, 0xca, 0xc0}, | 431 | { 443834000, 166667, 0xca, 0xc0}, |
| 400 | { 583834000, 36166000, 166666, 0xca, 0x60}, | 432 | { 583834000, 166667, 0xca, 0x60}, |
| 401 | { 793834000, 36166000, 166666, 0xca, 0xa0}, | 433 | { 793834000, 166667, 0xca, 0xa0}, |
| 402 | { 858834000, 36166000, 166666, 0xca, 0xe0}, | 434 | { 858834000, 166667, 0xca, 0xe0}, |
| 403 | }, | 435 | }, |
| 404 | }; | 436 | }; |
| 405 | EXPORT_SYMBOL(dvb_pll_philips_td1316); | 437 | EXPORT_SYMBOL(dvb_pll_philips_td1316); |
| @@ -409,15 +441,41 @@ struct dvb_pll_desc dvb_pll_thomson_fe6600 = { | |||
| 409 | .name = "Thomson FE6600", | 441 | .name = "Thomson FE6600", |
| 410 | .min = 44250000, | 442 | .min = 44250000, |
| 411 | .max = 858000000, | 443 | .max = 858000000, |
| 444 | .iffreq= 36125000, | ||
| 412 | .count = 4, | 445 | .count = 4, |
| 413 | .entries = { | 446 | .entries = { |
| 414 | { 250000000, 36213333, 166667, 0xb4, 0x12 }, | 447 | { 250000000, 166667, 0xb4, 0x12 }, |
| 415 | { 455000000, 36213333, 166667, 0xfe, 0x11 }, | 448 | { 455000000, 166667, 0xfe, 0x11 }, |
| 416 | { 775500000, 36213333, 166667, 0xbc, 0x18 }, | 449 | { 775500000, 166667, 0xbc, 0x18 }, |
| 417 | { 999999999, 36213333, 166667, 0xf4, 0x18 }, | 450 | { 999999999, 166667, 0xf4, 0x18 }, |
| 418 | } | 451 | } |
| 419 | }; | 452 | }; |
| 420 | EXPORT_SYMBOL(dvb_pll_thomson_fe6600); | 453 | EXPORT_SYMBOL(dvb_pll_thomson_fe6600); |
| 454 | static void opera1_bw(u8 *buf, u32 freq, int bandwidth) | ||
| 455 | { | ||
| 456 | if (bandwidth == BANDWIDTH_8_MHZ) | ||
| 457 | buf[2] |= 0x08; | ||
| 458 | } | ||
| 459 | |||
| 460 | struct dvb_pll_desc dvb_pll_opera1 = { | ||
| 461 | .name = "Opera Tuner", | ||
| 462 | .min = 900000, | ||
| 463 | .max = 2250000, | ||
| 464 | .iffreq= 0, | ||
| 465 | .setbw = opera1_bw, | ||
| 466 | .count = 8, | ||
| 467 | .entries = { | ||
| 468 | { 1064000, 500, 0xe5, 0xc6 }, | ||
| 469 | { 1169000, 500, 0xe5, 0xe6 }, | ||
| 470 | { 1299000, 500, 0xe5, 0x24 }, | ||
| 471 | { 1444000, 500, 0xe5, 0x44 }, | ||
| 472 | { 1606000, 500, 0xe5, 0x64 }, | ||
| 473 | { 1777000, 500, 0xe5, 0x84 }, | ||
| 474 | { 1941000, 500, 0xe5, 0xa4 }, | ||
| 475 | { 2250000, 500, 0xe5, 0xc4 }, | ||
| 476 | } | ||
| 477 | }; | ||
| 478 | EXPORT_SYMBOL(dvb_pll_opera1); | ||
| 421 | 479 | ||
| 422 | struct dvb_pll_priv { | 480 | struct dvb_pll_priv { |
| 423 | /* i2c details */ | 481 | /* i2c details */ |
| @@ -459,7 +517,8 @@ int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf, | |||
| 459 | if (i == desc->count) | 517 | if (i == desc->count) |
| 460 | return -EINVAL; | 518 | return -EINVAL; |
| 461 | 519 | ||
| 462 | div = (freq + desc->entries[i].offset) / desc->entries[i].stepsize; | 520 | div = (freq + desc->iffreq + desc->entries[i].stepsize/2) / |
| 521 | desc->entries[i].stepsize; | ||
| 463 | buf[0] = div >> 8; | 522 | buf[0] = div >> 8; |
| 464 | buf[1] = div & 0xff; | 523 | buf[1] = div & 0xff; |
| 465 | buf[2] = desc->entries[i].config; | 524 | buf[2] = desc->entries[i].config; |
| @@ -473,7 +532,7 @@ int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf, | |||
| 473 | desc->name, div, buf[0], buf[1], buf[2], buf[3]); | 532 | desc->name, div, buf[0], buf[1], buf[2], buf[3]); |
| 474 | 533 | ||
| 475 | // calculate the frequency we set it to | 534 | // calculate the frequency we set it to |
| 476 | return (div * desc->entries[i].stepsize) - desc->entries[i].offset; | 535 | return (div * desc->entries[i].stepsize) - desc->iffreq; |
| 477 | } | 536 | } |
| 478 | EXPORT_SYMBOL(dvb_pll_configure); | 537 | EXPORT_SYMBOL(dvb_pll_configure); |
| 479 | 538 | ||
| @@ -487,35 +546,27 @@ static int dvb_pll_release(struct dvb_frontend *fe) | |||
| 487 | static int dvb_pll_sleep(struct dvb_frontend *fe) | 546 | static int dvb_pll_sleep(struct dvb_frontend *fe) |
| 488 | { | 547 | { |
| 489 | struct dvb_pll_priv *priv = fe->tuner_priv; | 548 | struct dvb_pll_priv *priv = fe->tuner_priv; |
| 490 | u8 buf[4]; | ||
| 491 | struct i2c_msg msg = | ||
| 492 | { .addr = priv->pll_i2c_address, .flags = 0, | ||
| 493 | .buf = buf, .len = sizeof(buf) }; | ||
| 494 | int i; | ||
| 495 | int result; | ||
| 496 | 549 | ||
| 497 | if (priv->i2c == NULL) | 550 | if (priv->i2c == NULL) |
| 498 | return -EINVAL; | 551 | return -EINVAL; |
| 499 | 552 | ||
| 500 | for (i = 0; i < priv->pll_desc->count; i++) { | 553 | if (priv->pll_desc->sleepdata) { |
| 501 | if (priv->pll_desc->entries[i].limit == 0) | 554 | struct i2c_msg msg = { .flags = 0, |
| 502 | break; | 555 | .addr = priv->pll_i2c_address, |
| 503 | } | 556 | .buf = priv->pll_desc->sleepdata + 1, |
| 504 | if (i == priv->pll_desc->count) | 557 | .len = priv->pll_desc->sleepdata[0] }; |
| 505 | return 0; | ||
| 506 | 558 | ||
| 507 | buf[0] = 0; | 559 | int result; |
| 508 | buf[1] = 0; | ||
| 509 | buf[2] = priv->pll_desc->entries[i].config; | ||
| 510 | buf[3] = priv->pll_desc->entries[i].cb; | ||
| 511 | 560 | ||
| 512 | if (fe->ops.i2c_gate_ctrl) | 561 | if (fe->ops.i2c_gate_ctrl) |
| 513 | fe->ops.i2c_gate_ctrl(fe, 1); | 562 | fe->ops.i2c_gate_ctrl(fe, 1); |
| 514 | if ((result = i2c_transfer(priv->i2c, &msg, 1)) != 1) { | 563 | if ((result = i2c_transfer(priv->i2c, &msg, 1)) != 1) { |
| 515 | return result; | 564 | return result; |
| 565 | } | ||
| 566 | return 0; | ||
| 516 | } | 567 | } |
| 517 | 568 | /* Shouldn't be called when initdata is NULL, maybe BUG()? */ | |
| 518 | return 0; | 569 | return -EINVAL; |
| 519 | } | 570 | } |
| 520 | 571 | ||
| 521 | static int dvb_pll_set_params(struct dvb_frontend *fe, | 572 | static int dvb_pll_set_params(struct dvb_frontend *fe, |
| @@ -599,9 +650,35 @@ static int dvb_pll_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth) | |||
| 599 | return 0; | 650 | return 0; |
| 600 | } | 651 | } |
| 601 | 652 | ||
| 653 | static int dvb_pll_init(struct dvb_frontend *fe) | ||
| 654 | { | ||
| 655 | struct dvb_pll_priv *priv = fe->tuner_priv; | ||
| 656 | |||
| 657 | if (priv->i2c == NULL) | ||
| 658 | return -EINVAL; | ||
| 659 | |||
| 660 | if (priv->pll_desc->initdata) { | ||
| 661 | struct i2c_msg msg = { .flags = 0, | ||
| 662 | .addr = priv->pll_i2c_address, | ||
| 663 | .buf = priv->pll_desc->initdata + 1, | ||
| 664 | .len = priv->pll_desc->initdata[0] }; | ||
| 665 | |||
| 666 | int result; | ||
| 667 | if (fe->ops.i2c_gate_ctrl) | ||
| 668 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
| 669 | if ((result = i2c_transfer(priv->i2c, &msg, 1)) != 1) { | ||
| 670 | return result; | ||
| 671 | } | ||
| 672 | return 0; | ||
| 673 | } | ||
| 674 | /* Shouldn't be called when initdata is NULL, maybe BUG()? */ | ||
| 675 | return -EINVAL; | ||
| 676 | } | ||
| 677 | |||
| 602 | static struct dvb_tuner_ops dvb_pll_tuner_ops = { | 678 | static struct dvb_tuner_ops dvb_pll_tuner_ops = { |
| 603 | .release = dvb_pll_release, | 679 | .release = dvb_pll_release, |
| 604 | .sleep = dvb_pll_sleep, | 680 | .sleep = dvb_pll_sleep, |
| 681 | .init = dvb_pll_init, | ||
| 605 | .set_params = dvb_pll_set_params, | 682 | .set_params = dvb_pll_set_params, |
| 606 | .calc_regs = dvb_pll_calc_regs, | 683 | .calc_regs = dvb_pll_calc_regs, |
| 607 | .get_frequency = dvb_pll_get_frequency, | 684 | .get_frequency = dvb_pll_get_frequency, |
| @@ -640,9 +717,14 @@ struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, int pll_addr, | |||
| 640 | memcpy(&fe->ops.tuner_ops, &dvb_pll_tuner_ops, | 717 | memcpy(&fe->ops.tuner_ops, &dvb_pll_tuner_ops, |
| 641 | sizeof(struct dvb_tuner_ops)); | 718 | sizeof(struct dvb_tuner_ops)); |
| 642 | 719 | ||
| 643 | strncpy(fe->ops.tuner_ops.info.name, desc->name, 128); | 720 | strncpy(fe->ops.tuner_ops.info.name, desc->name, |
| 721 | sizeof(fe->ops.tuner_ops.info.name)); | ||
| 644 | fe->ops.tuner_ops.info.frequency_min = desc->min; | 722 | fe->ops.tuner_ops.info.frequency_min = desc->min; |
| 645 | fe->ops.tuner_ops.info.frequency_min = desc->max; | 723 | fe->ops.tuner_ops.info.frequency_min = desc->max; |
| 724 | if (!desc->initdata) | ||
| 725 | fe->ops.tuner_ops.init = NULL; | ||
| 726 | if (!desc->sleepdata) | ||
| 727 | fe->ops.tuner_ops.sleep = NULL; | ||
| 646 | 728 | ||
| 647 | fe->tuner_priv = priv; | 729 | fe->tuner_priv = priv; |
| 648 | return fe; | 730 | return fe; |
diff --git a/drivers/media/dvb/frontends/dvb-pll.h b/drivers/media/dvb/frontends/dvb-pll.h index 681186a5e5eb..5209f46f0893 100644 --- a/drivers/media/dvb/frontends/dvb-pll.h +++ b/drivers/media/dvb/frontends/dvb-pll.h | |||
| @@ -12,11 +12,13 @@ struct dvb_pll_desc { | |||
| 12 | char *name; | 12 | char *name; |
| 13 | u32 min; | 13 | u32 min; |
| 14 | u32 max; | 14 | u32 max; |
| 15 | u32 iffreq; | ||
| 15 | void (*setbw)(u8 *buf, u32 freq, int bandwidth); | 16 | void (*setbw)(u8 *buf, u32 freq, int bandwidth); |
| 17 | u8 *initdata; | ||
| 18 | u8 *sleepdata; | ||
| 16 | int count; | 19 | int count; |
| 17 | struct { | 20 | struct { |
| 18 | u32 limit; | 21 | u32 limit; |
| 19 | u32 offset; | ||
| 20 | u32 stepsize; | 22 | u32 stepsize; |
| 21 | u8 config; | 23 | u8 config; |
| 22 | u8 cb; | 24 | u8 cb; |
| @@ -46,6 +48,7 @@ extern struct dvb_pll_desc dvb_pll_philips_sd1878_tda8261; | |||
| 46 | extern struct dvb_pll_desc dvb_pll_philips_td1316; | 48 | extern struct dvb_pll_desc dvb_pll_philips_td1316; |
| 47 | 49 | ||
| 48 | extern struct dvb_pll_desc dvb_pll_thomson_fe6600; | 50 | extern struct dvb_pll_desc dvb_pll_thomson_fe6600; |
| 51 | extern struct dvb_pll_desc dvb_pll_opera1; | ||
| 49 | 52 | ||
| 50 | extern int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf, | 53 | extern int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf, |
| 51 | u32 freq, int bandwidth); | 54 | u32 freq, int bandwidth); |
| @@ -59,9 +62,20 @@ extern int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf, | |||
| 59 | * @param desc dvb_pll_desc to use. | 62 | * @param desc dvb_pll_desc to use. |
| 60 | * @return Frontend pointer on success, NULL on failure | 63 | * @return Frontend pointer on success, NULL on failure |
| 61 | */ | 64 | */ |
| 65 | #if defined(CONFIG_DVB_PLL) || (defined(CONFIG_DVB_PLL_MODULE) && defined(MODULE)) | ||
| 62 | extern struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, | 66 | extern struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, |
| 63 | int pll_addr, | 67 | int pll_addr, |
| 64 | struct i2c_adapter *i2c, | 68 | struct i2c_adapter *i2c, |
| 65 | struct dvb_pll_desc *desc); | 69 | struct dvb_pll_desc *desc); |
| 70 | #else | ||
| 71 | static inline struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, | ||
| 72 | int pll_addr, | ||
| 73 | struct i2c_adapter *i2c, | ||
| 74 | struct dvb_pll_desc *desc) | ||
| 75 | { | ||
| 76 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); | ||
| 77 | return NULL; | ||
| 78 | } | ||
| 79 | #endif | ||
| 66 | 80 | ||
| 67 | #endif | 81 | #endif |
diff --git a/drivers/media/dvb/frontends/lgdt330x.c b/drivers/media/dvb/frontends/lgdt330x.c index 68aad0f6519f..e25286e2d431 100644 --- a/drivers/media/dvb/frontends/lgdt330x.c +++ b/drivers/media/dvb/frontends/lgdt330x.c | |||
| @@ -475,7 +475,7 @@ static int lgdt3302_read_status(struct dvb_frontend* fe, fe_status_t* status) | |||
| 475 | *status |= FE_HAS_CARRIER; | 475 | *status |= FE_HAS_CARRIER; |
| 476 | break; | 476 | break; |
| 477 | default: | 477 | default: |
| 478 | printk("KERN_WARNING lgdt330x: %s: Modulation set to unsupported value\n", __FUNCTION__); | 478 | printk(KERN_WARNING "lgdt330x: %s: Modulation set to unsupported value\n", __FUNCTION__); |
| 479 | } | 479 | } |
| 480 | 480 | ||
| 481 | return 0; | 481 | return 0; |
| @@ -534,7 +534,7 @@ static int lgdt3303_read_status(struct dvb_frontend* fe, fe_status_t* status) | |||
| 534 | } | 534 | } |
| 535 | break; | 535 | break; |
| 536 | default: | 536 | default: |
| 537 | printk("KERN_WARNING lgdt330x: %s: Modulation set to unsupported value\n", __FUNCTION__); | 537 | printk(KERN_WARNING "lgdt330x: %s: Modulation set to unsupported value\n", __FUNCTION__); |
| 538 | } | 538 | } |
| 539 | return 0; | 539 | return 0; |
| 540 | } | 540 | } |
diff --git a/drivers/media/dvb/frontends/lgh06xf.c b/drivers/media/dvb/frontends/lgh06xf.c deleted file mode 100644 index 2202d0cc878b..000000000000 --- a/drivers/media/dvb/frontends/lgh06xf.c +++ /dev/null | |||
| @@ -1,134 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * lgh06xf.c - ATSC Tuner support for LG TDVS-H06xF | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify | ||
| 5 | * it under the terms of the GNU General Public License as published by | ||
| 6 | * the Free Software Foundation; either version 2 of the License, or | ||
| 7 | * (at your option) any later version. | ||
| 8 | * | ||
| 9 | * This program is distributed in the hope that it will be useful, | ||
| 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | * GNU General Public License for more details. | ||
| 13 | * | ||
| 14 | * You should have received a copy of the GNU General Public License | ||
| 15 | * along with this program; if not, write to the Free Software | ||
| 16 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 17 | */ | ||
| 18 | |||
| 19 | #include "dvb-pll.h" | ||
| 20 | #include "lgh06xf.h" | ||
| 21 | |||
| 22 | #define LG_H06XF_PLL_I2C_ADDR 0x61 | ||
| 23 | |||
| 24 | struct lgh06xf_priv { | ||
| 25 | struct i2c_adapter *i2c; | ||
| 26 | u32 frequency; | ||
| 27 | }; | ||
| 28 | |||
| 29 | static int lgh06xf_release(struct dvb_frontend *fe) | ||
| 30 | { | ||
| 31 | kfree(fe->tuner_priv); | ||
| 32 | fe->tuner_priv = NULL; | ||
| 33 | return 0; | ||
| 34 | } | ||
| 35 | |||
| 36 | static int lgh06xf_set_params(struct dvb_frontend* fe, | ||
| 37 | struct dvb_frontend_parameters* params) | ||
| 38 | { | ||
| 39 | struct lgh06xf_priv *priv = fe->tuner_priv; | ||
| 40 | u8 buf[4]; | ||
| 41 | struct i2c_msg msg = { .addr = LG_H06XF_PLL_I2C_ADDR, .flags = 0, | ||
| 42 | .buf = buf, .len = sizeof(buf) }; | ||
| 43 | u32 frequency; | ||
| 44 | int result; | ||
| 45 | |||
| 46 | if ((result = dvb_pll_configure(&dvb_pll_lg_tdvs_h06xf, buf, | ||
| 47 | params->frequency, 0)) < 0) | ||
| 48 | return result; | ||
| 49 | else | ||
| 50 | frequency = result; | ||
| 51 | |||
| 52 | if (fe->ops.i2c_gate_ctrl) | ||
| 53 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
| 54 | if ((result = i2c_transfer(priv->i2c, &msg, 1)) != 1) { | ||
| 55 | printk(KERN_WARNING "lgh06xf: %s error " | ||
| 56 | "(addr %02x <- %02x, result = %i)\n", | ||
| 57 | __FUNCTION__, buf[0], buf[1], result); | ||
| 58 | if (result < 0) | ||
| 59 | return result; | ||
| 60 | else | ||
| 61 | return -EREMOTEIO; | ||
| 62 | } | ||
| 63 | |||
| 64 | /* Set the Auxiliary Byte. */ | ||
| 65 | buf[0] = buf[2]; | ||
| 66 | buf[0] &= ~0x20; | ||
| 67 | buf[0] |= 0x18; | ||
| 68 | buf[1] = 0x50; | ||
| 69 | msg.len = 2; | ||
| 70 | if (fe->ops.i2c_gate_ctrl) | ||
| 71 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
| 72 | if ((result = i2c_transfer(priv->i2c, &msg, 1)) != 1) { | ||
| 73 | printk(KERN_WARNING "lgh06xf: %s error " | ||
| 74 | "(addr %02x <- %02x, result = %i)\n", | ||
| 75 | __FUNCTION__, buf[0], buf[1], result); | ||
| 76 | if (result < 0) | ||
| 77 | return result; | ||
| 78 | else | ||
| 79 | return -EREMOTEIO; | ||
| 80 | } | ||
| 81 | |||
| 82 | priv->frequency = frequency; | ||
| 83 | |||
| 84 | return 0; | ||
| 85 | } | ||
| 86 | |||
| 87 | static int lgh06xf_get_frequency(struct dvb_frontend *fe, u32 *frequency) | ||
| 88 | { | ||
| 89 | struct lgh06xf_priv *priv = fe->tuner_priv; | ||
| 90 | *frequency = priv->frequency; | ||
| 91 | return 0; | ||
| 92 | } | ||
| 93 | |||
| 94 | static struct dvb_tuner_ops lgh06xf_tuner_ops = { | ||
| 95 | .release = lgh06xf_release, | ||
| 96 | .set_params = lgh06xf_set_params, | ||
| 97 | .get_frequency = lgh06xf_get_frequency, | ||
| 98 | }; | ||
| 99 | |||
| 100 | struct dvb_frontend* lgh06xf_attach(struct dvb_frontend *fe, | ||
| 101 | struct i2c_adapter *i2c) | ||
| 102 | { | ||
| 103 | struct lgh06xf_priv *priv = NULL; | ||
| 104 | |||
| 105 | priv = kzalloc(sizeof(struct lgh06xf_priv), GFP_KERNEL); | ||
| 106 | if (priv == NULL) | ||
| 107 | return NULL; | ||
| 108 | |||
| 109 | priv->i2c = i2c; | ||
| 110 | |||
| 111 | memcpy(&fe->ops.tuner_ops, &lgh06xf_tuner_ops, | ||
| 112 | sizeof(struct dvb_tuner_ops)); | ||
| 113 | |||
| 114 | strlcpy(fe->ops.tuner_ops.info.name, dvb_pll_lg_tdvs_h06xf.name, | ||
| 115 | sizeof(fe->ops.tuner_ops.info.name)); | ||
| 116 | |||
| 117 | fe->ops.tuner_ops.info.frequency_min = dvb_pll_lg_tdvs_h06xf.min; | ||
| 118 | fe->ops.tuner_ops.info.frequency_max = dvb_pll_lg_tdvs_h06xf.max; | ||
| 119 | |||
| 120 | fe->tuner_priv = priv; | ||
| 121 | return fe; | ||
| 122 | } | ||
| 123 | |||
| 124 | EXPORT_SYMBOL(lgh06xf_attach); | ||
| 125 | |||
| 126 | MODULE_DESCRIPTION("LG TDVS-H06xF ATSC Tuner support"); | ||
| 127 | MODULE_AUTHOR("Michael Krufky"); | ||
| 128 | MODULE_LICENSE("GPL"); | ||
| 129 | |||
| 130 | /* | ||
| 131 | * Local variables: | ||
| 132 | * c-basic-offset: 8 | ||
| 133 | * End: | ||
| 134 | */ | ||
diff --git a/drivers/media/dvb/frontends/lgh06xf.h b/drivers/media/dvb/frontends/lgh06xf.h deleted file mode 100644 index 510b4bedfb24..000000000000 --- a/drivers/media/dvb/frontends/lgh06xf.h +++ /dev/null | |||
| @@ -1,35 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * lgh06xf.h - ATSC Tuner support for LG TDVS-H06xF | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify | ||
| 5 | * it under the terms of the GNU General Public License as published by | ||
| 6 | * the Free Software Foundation; either version 2 of the License, or | ||
| 7 | * (at your option) any later version. | ||
| 8 | * | ||
| 9 | * This program is distributed in the hope that it will be useful, | ||
| 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | * GNU General Public License for more details. | ||
| 13 | * | ||
| 14 | * You should have received a copy of the GNU General Public License | ||
| 15 | * along with this program; if not, write to the Free Software | ||
| 16 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 17 | */ | ||
| 18 | |||
| 19 | #ifndef _LGH06XF_H_ | ||
| 20 | #define _LGH06XF_H_ | ||
| 21 | #include "dvb_frontend.h" | ||
| 22 | |||
| 23 | #if defined(CONFIG_DVB_TUNER_LGH06XF) || (defined(CONFIG_DVB_TUNER_LGH06XF_MODULE) && defined(MODULE)) | ||
| 24 | extern struct dvb_frontend* lgh06xf_attach(struct dvb_frontend* fe, | ||
| 25 | struct i2c_adapter *i2c); | ||
| 26 | #else | ||
| 27 | static inline struct dvb_frontend* lgh06xf_attach(struct dvb_frontend* fe, | ||
| 28 | struct i2c_adapter *i2c) | ||
| 29 | { | ||
| 30 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); | ||
| 31 | return NULL; | ||
| 32 | } | ||
| 33 | #endif /* CONFIG_DVB_TUNER_LGH06XF */ | ||
| 34 | |||
| 35 | #endif /* _LGH06XF_H_ */ | ||
diff --git a/drivers/media/dvb/frontends/or51132.c b/drivers/media/dvb/frontends/or51132.c index 5a3a6e53cda2..4e0aca7c67aa 100644 --- a/drivers/media/dvb/frontends/or51132.c +++ b/drivers/media/dvb/frontends/or51132.c | |||
| @@ -1,6 +1,9 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Support for OR51132 (pcHDTV HD-3000) - VSB/QAM | 2 | * Support for OR51132 (pcHDTV HD-3000) - VSB/QAM |
| 3 | * | 3 | * |
| 4 | * | ||
| 5 | * Copyright (C) 2007 Trent Piepho <xyzzy@speakeasy.org> | ||
| 6 | * | ||
| 4 | * Copyright (C) 2005 Kirk Lapray <kirk_lapray@bigfoot.com> | 7 | * Copyright (C) 2005 Kirk Lapray <kirk_lapray@bigfoot.com> |
| 5 | * | 8 | * |
| 6 | * Based on code from Jack Kelliher (kelliher@xmission.com) | 9 | * Based on code from Jack Kelliher (kelliher@xmission.com) |
| @@ -69,46 +72,70 @@ struct or51132_state | |||
| 69 | u32 current_frequency; | 72 | u32 current_frequency; |
| 70 | }; | 73 | }; |
| 71 | 74 | ||
| 72 | static int i2c_writebytes (struct or51132_state* state, u8 reg, u8 *buf, int len) | 75 | |
| 76 | /* Write buffer to demod */ | ||
| 77 | static int or51132_writebuf(struct or51132_state *state, const u8 *buf, int len) | ||
| 73 | { | 78 | { |
| 74 | int err; | 79 | int err; |
| 75 | struct i2c_msg msg; | 80 | struct i2c_msg msg = { .addr = state->config->demod_address, |
| 76 | msg.addr = reg; | 81 | .flags = 0, .buf = (u8*)buf, .len = len }; |
| 77 | msg.flags = 0; | ||
| 78 | msg.len = len; | ||
| 79 | msg.buf = buf; | ||
| 80 | 82 | ||
| 83 | /* msleep(20); */ /* doesn't appear to be necessary */ | ||
| 81 | if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) { | 84 | if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) { |
| 82 | printk(KERN_WARNING "or51132: i2c_writebytes error (addr %02x, err == %i)\n", reg, err); | 85 | printk(KERN_WARNING "or51132: I2C write (addr 0x%02x len %d) error: %d\n", |
| 86 | msg.addr, msg.len, err); | ||
| 83 | return -EREMOTEIO; | 87 | return -EREMOTEIO; |
| 84 | } | 88 | } |
| 85 | |||
| 86 | return 0; | 89 | return 0; |
| 87 | } | 90 | } |
| 88 | 91 | ||
| 89 | static u8 i2c_readbytes (struct or51132_state* state, u8 reg, u8* buf, int len) | 92 | /* Write constant bytes, e.g. or51132_writebytes(state, 0x04, 0x42, 0x00); |
| 93 | Less code and more efficient that loading a buffer on the stack with | ||
| 94 | the bytes to send and then calling or51132_writebuf() on that. */ | ||
| 95 | #define or51132_writebytes(state, data...) \ | ||
| 96 | ({ const static u8 _data[] = {data}; \ | ||
| 97 | or51132_writebuf(state, _data, sizeof(_data)); }) | ||
| 98 | |||
| 99 | /* Read data from demod into buffer. Returns 0 on success. */ | ||
| 100 | static int or51132_readbuf(struct or51132_state *state, u8 *buf, int len) | ||
| 90 | { | 101 | { |
| 91 | int err; | 102 | int err; |
| 92 | struct i2c_msg msg; | 103 | struct i2c_msg msg = { .addr = state->config->demod_address, |
| 93 | msg.addr = reg; | 104 | .flags = I2C_M_RD, .buf = buf, .len = len }; |
| 94 | msg.flags = I2C_M_RD; | ||
| 95 | msg.len = len; | ||
| 96 | msg.buf = buf; | ||
| 97 | 105 | ||
| 106 | /* msleep(20); */ /* doesn't appear to be necessary */ | ||
| 98 | if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) { | 107 | if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) { |
| 99 | printk(KERN_WARNING "or51132: i2c_readbytes error (addr %02x, err == %i)\n", reg, err); | 108 | printk(KERN_WARNING "or51132: I2C read (addr 0x%02x len %d) error: %d\n", |
| 109 | msg.addr, msg.len, err); | ||
| 100 | return -EREMOTEIO; | 110 | return -EREMOTEIO; |
| 101 | } | 111 | } |
| 102 | |||
| 103 | return 0; | 112 | return 0; |
| 104 | } | 113 | } |
| 105 | 114 | ||
| 115 | /* Reads a 16-bit demod register. Returns <0 on error. */ | ||
| 116 | static int or51132_readreg(struct or51132_state *state, u8 reg) | ||
| 117 | { | ||
| 118 | u8 buf[2] = { 0x04, reg }; | ||
| 119 | struct i2c_msg msg[2] = { | ||
| 120 | {.addr = state->config->demod_address, .flags = 0, | ||
| 121 | .buf = buf, .len = 2 }, | ||
| 122 | {.addr = state->config->demod_address, .flags = I2C_M_RD, | ||
| 123 | .buf = buf, .len = 2 }}; | ||
| 124 | int err; | ||
| 125 | |||
| 126 | if ((err = i2c_transfer(state->i2c, msg, 2)) != 2) { | ||
| 127 | printk(KERN_WARNING "or51132: I2C error reading register %d: %d\n", | ||
| 128 | reg, err); | ||
| 129 | return -EREMOTEIO; | ||
| 130 | } | ||
| 131 | return le16_to_cpup((u16*)buf); | ||
| 132 | } | ||
| 133 | |||
| 106 | static int or51132_load_firmware (struct dvb_frontend* fe, const struct firmware *fw) | 134 | static int or51132_load_firmware (struct dvb_frontend* fe, const struct firmware *fw) |
| 107 | { | 135 | { |
| 108 | struct or51132_state* state = fe->demodulator_priv; | 136 | struct or51132_state* state = fe->demodulator_priv; |
| 109 | static u8 run_buf[] = {0x7F,0x01}; | 137 | const static u8 run_buf[] = {0x7F,0x01}; |
| 110 | u8 rec_buf[8]; | 138 | u8 rec_buf[8]; |
| 111 | u8 cmd_buf[3]; | ||
| 112 | u32 firmwareAsize, firmwareBsize; | 139 | u32 firmwareAsize, firmwareBsize; |
| 113 | int i,ret; | 140 | int i,ret; |
| 114 | 141 | ||
| @@ -121,30 +148,21 @@ static int or51132_load_firmware (struct dvb_frontend* fe, const struct firmware | |||
| 121 | dprintk("FirmwareB is %i bytes\n",firmwareBsize); | 148 | dprintk("FirmwareB is %i bytes\n",firmwareBsize); |
| 122 | 149 | ||
| 123 | /* Upload firmware */ | 150 | /* Upload firmware */ |
| 124 | if ((ret = i2c_writebytes(state,state->config->demod_address, | 151 | if ((ret = or51132_writebuf(state, &fw->data[8], firmwareAsize))) { |
| 125 | &fw->data[8],firmwareAsize))) { | ||
| 126 | printk(KERN_WARNING "or51132: load_firmware error 1\n"); | 152 | printk(KERN_WARNING "or51132: load_firmware error 1\n"); |
| 127 | return ret; | 153 | return ret; |
| 128 | } | 154 | } |
| 129 | msleep(1); /* 1ms */ | 155 | if ((ret = or51132_writebuf(state, &fw->data[8+firmwareAsize], |
| 130 | if ((ret = i2c_writebytes(state,state->config->demod_address, | 156 | firmwareBsize))) { |
| 131 | &fw->data[8+firmwareAsize],firmwareBsize))) { | ||
| 132 | printk(KERN_WARNING "or51132: load_firmware error 2\n"); | 157 | printk(KERN_WARNING "or51132: load_firmware error 2\n"); |
| 133 | return ret; | 158 | return ret; |
| 134 | } | 159 | } |
| 135 | msleep(1); /* 1ms */ | ||
| 136 | 160 | ||
| 137 | if ((ret = i2c_writebytes(state,state->config->demod_address, | 161 | if ((ret = or51132_writebuf(state, run_buf, 2))) { |
| 138 | run_buf,2))) { | ||
| 139 | printk(KERN_WARNING "or51132: load_firmware error 3\n"); | 162 | printk(KERN_WARNING "or51132: load_firmware error 3\n"); |
| 140 | return ret; | 163 | return ret; |
| 141 | } | 164 | } |
| 142 | 165 | if ((ret = or51132_writebuf(state, run_buf, 2))) { | |
| 143 | /* Wait at least 5 msec */ | ||
| 144 | msleep(20); /* 10ms */ | ||
| 145 | |||
| 146 | if ((ret = i2c_writebytes(state,state->config->demod_address, | ||
| 147 | run_buf,2))) { | ||
| 148 | printk(KERN_WARNING "or51132: load_firmware error 4\n"); | 166 | printk(KERN_WARNING "or51132: load_firmware error 4\n"); |
| 149 | return ret; | 167 | return ret; |
| 150 | } | 168 | } |
| @@ -154,43 +172,25 @@ static int or51132_load_firmware (struct dvb_frontend* fe, const struct firmware | |||
| 154 | 172 | ||
| 155 | /* Read back ucode version to besure we loaded correctly and are really up and running */ | 173 | /* Read back ucode version to besure we loaded correctly and are really up and running */ |
| 156 | /* Get uCode version */ | 174 | /* Get uCode version */ |
| 157 | cmd_buf[0] = 0x10; | 175 | if ((ret = or51132_writebytes(state, 0x10, 0x10, 0x00))) { |
| 158 | cmd_buf[1] = 0x10; | ||
| 159 | cmd_buf[2] = 0x00; | ||
| 160 | msleep(20); /* 20ms */ | ||
| 161 | if ((ret = i2c_writebytes(state,state->config->demod_address, | ||
| 162 | cmd_buf,3))) { | ||
| 163 | printk(KERN_WARNING "or51132: load_firmware error a\n"); | 176 | printk(KERN_WARNING "or51132: load_firmware error a\n"); |
| 164 | return ret; | 177 | return ret; |
| 165 | } | 178 | } |
| 166 | 179 | if ((ret = or51132_writebytes(state, 0x04, 0x17))) { | |
| 167 | cmd_buf[0] = 0x04; | ||
| 168 | cmd_buf[1] = 0x17; | ||
| 169 | msleep(20); /* 20ms */ | ||
| 170 | if ((ret = i2c_writebytes(state,state->config->demod_address, | ||
| 171 | cmd_buf,2))) { | ||
| 172 | printk(KERN_WARNING "or51132: load_firmware error b\n"); | 180 | printk(KERN_WARNING "or51132: load_firmware error b\n"); |
| 173 | return ret; | 181 | return ret; |
| 174 | } | 182 | } |
| 175 | 183 | if ((ret = or51132_writebytes(state, 0x00, 0x00))) { | |
| 176 | cmd_buf[0] = 0x00; | ||
| 177 | cmd_buf[1] = 0x00; | ||
| 178 | msleep(20); /* 20ms */ | ||
| 179 | if ((ret = i2c_writebytes(state,state->config->demod_address, | ||
| 180 | cmd_buf,2))) { | ||
| 181 | printk(KERN_WARNING "or51132: load_firmware error c\n"); | 184 | printk(KERN_WARNING "or51132: load_firmware error c\n"); |
| 182 | return ret; | 185 | return ret; |
| 183 | } | 186 | } |
| 184 | 187 | for (i=0;i<4;i++) { | |
| 185 | for(i=0;i<4;i++) { | ||
| 186 | msleep(20); /* 20ms */ | ||
| 187 | /* Once upon a time, this command might have had something | 188 | /* Once upon a time, this command might have had something |
| 188 | to do with getting the firmware version, but it's | 189 | to do with getting the firmware version, but it's |
| 189 | not used anymore: | 190 | not used anymore: |
| 190 | {0x04,0x00,0x30,0x00,i+1} */ | 191 | {0x04,0x00,0x30,0x00,i+1} */ |
| 191 | /* Read 8 bytes, two bytes at a time */ | 192 | /* Read 8 bytes, two bytes at a time */ |
| 192 | if ((ret = i2c_readbytes(state,state->config->demod_address, | 193 | if ((ret = or51132_readbuf(state, &rec_buf[i*2], 2))) { |
| 193 | &rec_buf[i*2],2))) { | ||
| 194 | printk(KERN_WARNING | 194 | printk(KERN_WARNING |
| 195 | "or51132: load_firmware error d - %d\n",i); | 195 | "or51132: load_firmware error d - %d\n",i); |
| 196 | return ret; | 196 | return ret; |
| @@ -204,12 +204,7 @@ static int or51132_load_firmware (struct dvb_frontend* fe, const struct firmware | |||
| 204 | rec_buf[3],rec_buf[2]>>4,rec_buf[2]&0x0f, | 204 | rec_buf[3],rec_buf[2]>>4,rec_buf[2]&0x0f, |
| 205 | rec_buf[5],rec_buf[4]>>4,rec_buf[4]&0x0f); | 205 | rec_buf[5],rec_buf[4]>>4,rec_buf[4]&0x0f); |
| 206 | 206 | ||
| 207 | cmd_buf[0] = 0x10; | 207 | if ((ret = or51132_writebytes(state, 0x10, 0x00, 0x00))) { |
| 208 | cmd_buf[1] = 0x00; | ||
| 209 | cmd_buf[2] = 0x00; | ||
| 210 | msleep(20); /* 20ms */ | ||
| 211 | if ((ret = i2c_writebytes(state,state->config->demod_address, | ||
| 212 | cmd_buf,3))) { | ||
| 213 | printk(KERN_WARNING "or51132: load_firmware error e\n"); | 208 | printk(KERN_WARNING "or51132: load_firmware error e\n"); |
| 214 | return ret; | 209 | return ret; |
| 215 | } | 210 | } |
| @@ -241,70 +236,55 @@ static int or51132_sleep(struct dvb_frontend* fe) | |||
| 241 | static int or51132_setmode(struct dvb_frontend* fe) | 236 | static int or51132_setmode(struct dvb_frontend* fe) |
| 242 | { | 237 | { |
| 243 | struct or51132_state* state = fe->demodulator_priv; | 238 | struct or51132_state* state = fe->demodulator_priv; |
| 244 | unsigned char cmd_buf[3]; | 239 | u8 cmd_buf1[3] = {0x04, 0x01, 0x5f}; |
| 240 | u8 cmd_buf2[3] = {0x1c, 0x00, 0 }; | ||
| 245 | 241 | ||
| 246 | dprintk("setmode %d\n",(int)state->current_modulation); | 242 | dprintk("setmode %d\n",(int)state->current_modulation); |
| 247 | /* set operation mode in Receiver 1 register; */ | 243 | |
| 248 | cmd_buf[0] = 0x04; | ||
| 249 | cmd_buf[1] = 0x01; | ||
| 250 | switch (state->current_modulation) { | 244 | switch (state->current_modulation) { |
| 251 | case QAM_256: | ||
| 252 | case QAM_64: | ||
| 253 | case QAM_AUTO: | ||
| 254 | /* Auto-deinterleave; MPEG ser, MPEG2tr, phase noise-high*/ | ||
| 255 | cmd_buf[2] = 0x5F; | ||
| 256 | break; | ||
| 257 | case VSB_8: | 245 | case VSB_8: |
| 258 | /* Auto CH, Auto NTSC rej, MPEGser, MPEG2tr, phase noise-high*/ | 246 | /* Auto CH, Auto NTSC rej, MPEGser, MPEG2tr, phase noise-high */ |
| 259 | cmd_buf[2] = 0x50; | 247 | cmd_buf1[2] = 0x50; |
| 248 | /* REC MODE inv IF spectrum, Normal */ | ||
| 249 | cmd_buf2[1] = 0x03; | ||
| 250 | /* Channel MODE ATSC/VSB8 */ | ||
| 251 | cmd_buf2[2] = 0x06; | ||
| 260 | break; | 252 | break; |
| 261 | default: | 253 | /* All QAM modes are: |
| 262 | printk("setmode:Modulation set to unsupported value\n"); | 254 | Auto-deinterleave; MPEGser, MPEG2tr, phase noise-high |
| 263 | }; | 255 | REC MODE Normal Carrier Lock */ |
| 264 | if (i2c_writebytes(state,state->config->demod_address, | ||
| 265 | cmd_buf,3)) { | ||
| 266 | printk(KERN_WARNING "or51132: set_mode error 1\n"); | ||
| 267 | return -1; | ||
| 268 | } | ||
| 269 | dprintk("or51132: set #1 to %02x\n", cmd_buf[2]); | ||
| 270 | |||
| 271 | /* Set operation mode in Receiver 6 register */ | ||
| 272 | cmd_buf[0] = 0x1C; | ||
| 273 | switch (state->current_modulation) { | ||
| 274 | case QAM_AUTO: | 256 | case QAM_AUTO: |
| 275 | /* REC MODE Normal Carrier Lock */ | ||
| 276 | cmd_buf[1] = 0x00; | ||
| 277 | /* Channel MODE Auto QAM64/256 */ | 257 | /* Channel MODE Auto QAM64/256 */ |
| 278 | cmd_buf[2] = 0x4f; | 258 | cmd_buf2[2] = 0x4f; |
| 279 | break; | 259 | break; |
| 280 | case QAM_256: | 260 | case QAM_256: |
| 281 | /* REC MODE Normal Carrier Lock */ | ||
| 282 | cmd_buf[1] = 0x00; | ||
| 283 | /* Channel MODE QAM256 */ | 261 | /* Channel MODE QAM256 */ |
| 284 | cmd_buf[2] = 0x45; | 262 | cmd_buf2[2] = 0x45; |
| 285 | break; | 263 | break; |
| 286 | case QAM_64: | 264 | case QAM_64: |
| 287 | /* REC MODE Normal Carrier Lock */ | ||
| 288 | cmd_buf[1] = 0x00; | ||
| 289 | /* Channel MODE QAM64 */ | 265 | /* Channel MODE QAM64 */ |
| 290 | cmd_buf[2] = 0x43; | 266 | cmd_buf2[2] = 0x43; |
| 291 | break; | ||
| 292 | case VSB_8: | ||
| 293 | /* REC MODE inv IF spectrum, Normal */ | ||
| 294 | cmd_buf[1] = 0x03; | ||
| 295 | /* Channel MODE ATSC/VSB8 */ | ||
| 296 | cmd_buf[2] = 0x06; | ||
| 297 | break; | 267 | break; |
| 298 | default: | 268 | default: |
| 299 | printk("setmode: Modulation set to unsupported value\n"); | 269 | printk(KERN_WARNING |
| 300 | }; | 270 | "or51132: setmode: Modulation set to unsupported value (%d)\n", |
| 301 | msleep(20); /* 20ms */ | 271 | state->current_modulation); |
| 302 | if (i2c_writebytes(state,state->config->demod_address, | 272 | return -EINVAL; |
| 303 | cmd_buf,3)) { | 273 | } |
| 274 | |||
| 275 | /* Set Receiver 1 register */ | ||
| 276 | if (or51132_writebuf(state, cmd_buf1, 3)) { | ||
| 277 | printk(KERN_WARNING "or51132: set_mode error 1\n"); | ||
| 278 | return -EREMOTEIO; | ||
| 279 | } | ||
| 280 | dprintk("set #1 to %02x\n", cmd_buf1[2]); | ||
| 281 | |||
| 282 | /* Set operation mode in Receiver 6 register */ | ||
| 283 | if (or51132_writebuf(state, cmd_buf2, 3)) { | ||
| 304 | printk(KERN_WARNING "or51132: set_mode error 2\n"); | 284 | printk(KERN_WARNING "or51132: set_mode error 2\n"); |
| 305 | return -1; | 285 | return -EREMOTEIO; |
| 306 | } | 286 | } |
| 307 | dprintk("or51132: set #6 to 0x%02x%02x\n", cmd_buf[1], cmd_buf[2]); | 287 | dprintk("set #6 to 0x%02x%02x\n", cmd_buf2[1], cmd_buf2[2]); |
| 308 | 288 | ||
| 309 | return 0; | 289 | return 0; |
| 310 | } | 290 | } |
| @@ -401,28 +381,23 @@ static int or51132_get_parameters(struct dvb_frontend* fe, | |||
| 401 | struct dvb_frontend_parameters *param) | 381 | struct dvb_frontend_parameters *param) |
| 402 | { | 382 | { |
| 403 | struct or51132_state* state = fe->demodulator_priv; | 383 | struct or51132_state* state = fe->demodulator_priv; |
| 404 | u8 buf[2]; | 384 | int status; |
| 385 | int retry = 1; | ||
| 405 | 386 | ||
| 387 | start: | ||
| 406 | /* Receiver Status */ | 388 | /* Receiver Status */ |
| 407 | buf[0]=0x04; | 389 | if ((status = or51132_readreg(state, 0x00)) < 0) { |
| 408 | buf[1]=0x00; | 390 | printk(KERN_WARNING "or51132: get_parameters: error reading receiver status\n"); |
| 409 | msleep(30); /* 30ms */ | ||
| 410 | if (i2c_writebytes(state,state->config->demod_address,buf,2)) { | ||
| 411 | printk(KERN_WARNING "or51132: get_parameters write error\n"); | ||
| 412 | return -EREMOTEIO; | ||
| 413 | } | ||
| 414 | msleep(30); /* 30ms */ | ||
| 415 | if (i2c_readbytes(state,state->config->demod_address,buf,2)) { | ||
| 416 | printk(KERN_WARNING "or51132: get_parameters read error\n"); | ||
| 417 | return -EREMOTEIO; | 391 | return -EREMOTEIO; |
| 418 | } | 392 | } |
| 419 | switch(buf[0]) { | 393 | switch(status&0xff) { |
| 420 | case 0x06: param->u.vsb.modulation = VSB_8; break; | 394 | case 0x06: param->u.vsb.modulation = VSB_8; break; |
| 421 | case 0x43: param->u.vsb.modulation = QAM_64; break; | 395 | case 0x43: param->u.vsb.modulation = QAM_64; break; |
| 422 | case 0x45: param->u.vsb.modulation = QAM_256; break; | 396 | case 0x45: param->u.vsb.modulation = QAM_256; break; |
| 423 | default: | 397 | default: |
| 398 | if (retry--) goto start; | ||
| 424 | printk(KERN_WARNING "or51132: unknown status 0x%02x\n", | 399 | printk(KERN_WARNING "or51132: unknown status 0x%02x\n", |
| 425 | buf[0]); | 400 | status&0xff); |
| 426 | return -EREMOTEIO; | 401 | return -EREMOTEIO; |
| 427 | } | 402 | } |
| 428 | 403 | ||
| @@ -438,32 +413,21 @@ static int or51132_get_parameters(struct dvb_frontend* fe, | |||
| 438 | static int or51132_read_status(struct dvb_frontend* fe, fe_status_t* status) | 413 | static int or51132_read_status(struct dvb_frontend* fe, fe_status_t* status) |
| 439 | { | 414 | { |
| 440 | struct or51132_state* state = fe->demodulator_priv; | 415 | struct or51132_state* state = fe->demodulator_priv; |
| 441 | unsigned char rec_buf[2]; | 416 | int reg; |
| 442 | unsigned char snd_buf[2]; | ||
| 443 | *status = 0; | ||
| 444 | 417 | ||
| 445 | /* Receiver Status */ | 418 | /* Receiver Status */ |
| 446 | snd_buf[0]=0x04; | 419 | if ((reg = or51132_readreg(state, 0x00)) < 0) { |
| 447 | snd_buf[1]=0x00; | 420 | printk(KERN_WARNING "or51132: read_status: error reading receiver status: %d\n", reg); |
| 448 | msleep(30); /* 30ms */ | 421 | *status = 0; |
| 449 | if (i2c_writebytes(state,state->config->demod_address,snd_buf,2)) { | 422 | return -EREMOTEIO; |
| 450 | printk(KERN_WARNING "or51132: read_status write error\n"); | ||
| 451 | return -1; | ||
| 452 | } | ||
| 453 | msleep(30); /* 30ms */ | ||
| 454 | if (i2c_readbytes(state,state->config->demod_address,rec_buf,2)) { | ||
| 455 | printk(KERN_WARNING "or51132: read_status read error\n"); | ||
| 456 | return -1; | ||
| 457 | } | ||
| 458 | dprintk("read_status %x %x\n",rec_buf[0],rec_buf[1]); | ||
| 459 | |||
| 460 | if (rec_buf[1] & 0x01) { /* Receiver Lock */ | ||
| 461 | *status |= FE_HAS_SIGNAL; | ||
| 462 | *status |= FE_HAS_CARRIER; | ||
| 463 | *status |= FE_HAS_VITERBI; | ||
| 464 | *status |= FE_HAS_SYNC; | ||
| 465 | *status |= FE_HAS_LOCK; | ||
| 466 | } | 423 | } |
| 424 | dprintk("%s: read_status %04x\n", __FUNCTION__, reg); | ||
| 425 | |||
| 426 | if (reg & 0x0100) /* Receiver Lock */ | ||
| 427 | *status = FE_HAS_SIGNAL|FE_HAS_CARRIER|FE_HAS_VITERBI| | ||
| 428 | FE_HAS_SYNC|FE_HAS_LOCK; | ||
| 429 | else | ||
| 430 | *status = 0; | ||
| 467 | return 0; | 431 | return 0; |
| 468 | } | 432 | } |
| 469 | 433 | ||
| @@ -506,47 +470,30 @@ static u32 calculate_snr(u32 mse, u32 c) | |||
| 506 | static int or51132_read_snr(struct dvb_frontend* fe, u16* snr) | 470 | static int or51132_read_snr(struct dvb_frontend* fe, u16* snr) |
| 507 | { | 471 | { |
| 508 | struct or51132_state* state = fe->demodulator_priv; | 472 | struct or51132_state* state = fe->demodulator_priv; |
| 509 | u8 rec_buf[2]; | 473 | int noise, reg; |
| 510 | u8 snd_buf[2]; | 474 | u32 c, usK = 0; |
| 511 | u32 noise; | 475 | int retry = 1; |
| 512 | u32 c; | 476 | |
| 513 | u32 usK; | 477 | start: |
| 514 | 478 | /* SNR after Equalizer */ | |
| 515 | /* Register is same for VSB or QAM firmware */ | 479 | noise = or51132_readreg(state, 0x02); |
| 516 | snd_buf[0]=0x04; | 480 | if (noise < 0) { |
| 517 | snd_buf[1]=0x02; /* SNR after Equalizer */ | 481 | printk(KERN_WARNING "or51132: read_snr: error reading equalizer\n"); |
| 518 | msleep(30); /* 30ms */ | ||
| 519 | if (i2c_writebytes(state,state->config->demod_address,snd_buf,2)) { | ||
| 520 | printk(KERN_WARNING "or51132: snr write error\n"); | ||
| 521 | return -EREMOTEIO; | ||
| 522 | } | ||
| 523 | msleep(30); /* 30ms */ | ||
| 524 | if (i2c_readbytes(state,state->config->demod_address,rec_buf,2)) { | ||
| 525 | printk(KERN_WARNING "or51132: snr read error\n"); | ||
| 526 | return -EREMOTEIO; | 482 | return -EREMOTEIO; |
| 527 | } | 483 | } |
| 528 | noise = rec_buf[0] | (rec_buf[1] << 8); | 484 | dprintk("read_snr noise (%d)\n", noise); |
| 529 | dprintk("read_snr noise %x %x (%i)\n",rec_buf[0],rec_buf[1],noise); | ||
| 530 | 485 | ||
| 531 | /* Read status, contains modulation type for QAM_AUTO and | 486 | /* Read status, contains modulation type for QAM_AUTO and |
| 532 | NTSC filter for VSB */ | 487 | NTSC filter for VSB */ |
| 533 | snd_buf[0]=0x04; | 488 | reg = or51132_readreg(state, 0x00); |
| 534 | snd_buf[1]=0x00; /* Status register */ | 489 | if (reg < 0) { |
| 535 | msleep(30); /* 30ms */ | 490 | printk(KERN_WARNING "or51132: read_snr: error reading receiver status\n"); |
| 536 | if (i2c_writebytes(state,state->config->demod_address,snd_buf,2)) { | ||
| 537 | printk(KERN_WARNING "or51132: status write error\n"); | ||
| 538 | return -EREMOTEIO; | ||
| 539 | } | ||
| 540 | msleep(30); /* 30ms */ | ||
| 541 | if (i2c_readbytes(state,state->config->demod_address,rec_buf,2)) { | ||
| 542 | printk(KERN_WARNING "or51132: status read error\n"); | ||
| 543 | return -EREMOTEIO; | 491 | return -EREMOTEIO; |
| 544 | } | 492 | } |
| 545 | 493 | ||
| 546 | usK = 0; | 494 | switch (reg&0xff) { |
| 547 | switch (rec_buf[0]) { | ||
| 548 | case 0x06: | 495 | case 0x06: |
| 549 | usK = (rec_buf[1] & 0x10) ? 0x03000000 : 0; | 496 | if (reg & 0x1000) usK = 3 << 24; |
| 550 | /* Fall through to QAM64 case */ | 497 | /* Fall through to QAM64 case */ |
| 551 | case 0x43: | 498 | case 0x43: |
| 552 | c = 150204167; | 499 | c = 150204167; |
| @@ -555,11 +502,12 @@ static int or51132_read_snr(struct dvb_frontend* fe, u16* snr) | |||
| 555 | c = 150290396; | 502 | c = 150290396; |
| 556 | break; | 503 | break; |
| 557 | default: | 504 | default: |
| 558 | printk(KERN_ERR "or51132: unknown status 0x%02x\n", rec_buf[0]); | 505 | printk(KERN_WARNING "or51132: unknown status 0x%02x\n", reg&0xff); |
| 506 | if (retry--) goto start; | ||
| 559 | return -EREMOTEIO; | 507 | return -EREMOTEIO; |
| 560 | } | 508 | } |
| 561 | dprintk("%s: modulation %02x, NTSC rej O%s\n", __FUNCTION__, | 509 | dprintk("%s: modulation %02x, NTSC rej O%s\n", __FUNCTION__, |
| 562 | rec_buf[0], rec_buf[1]&0x10?"n":"ff"); | 510 | reg&0xff, reg&0x1000?"n":"ff"); |
| 563 | 511 | ||
| 564 | /* Calculate SNR using noise, c, and NTSC rejection correction */ | 512 | /* Calculate SNR using noise, c, and NTSC rejection correction */ |
| 565 | state->snr = calculate_snr(noise, c) - usK; | 513 | state->snr = calculate_snr(noise, c) - usK; |
| @@ -671,6 +619,7 @@ MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); | |||
| 671 | 619 | ||
| 672 | MODULE_DESCRIPTION("OR51132 ATSC [pcHDTV HD-3000] (8VSB & ITU J83 AnnexB FEC QAM64/256) Demodulator Driver"); | 620 | MODULE_DESCRIPTION("OR51132 ATSC [pcHDTV HD-3000] (8VSB & ITU J83 AnnexB FEC QAM64/256) Demodulator Driver"); |
| 673 | MODULE_AUTHOR("Kirk Lapray"); | 621 | MODULE_AUTHOR("Kirk Lapray"); |
| 622 | MODULE_AUTHOR("Trent Piepho"); | ||
| 674 | MODULE_LICENSE("GPL"); | 623 | MODULE_LICENSE("GPL"); |
| 675 | 624 | ||
| 676 | EXPORT_SYMBOL(or51132_attach); | 625 | EXPORT_SYMBOL(or51132_attach); |
diff --git a/drivers/media/dvb/frontends/tda10021.c b/drivers/media/dvb/frontends/tda10021.c index 5b9c5bb29b23..110536843e8e 100644 --- a/drivers/media/dvb/frontends/tda10021.c +++ b/drivers/media/dvb/frontends/tda10021.c | |||
| @@ -30,13 +30,13 @@ | |||
| 30 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
| 31 | 31 | ||
| 32 | #include "dvb_frontend.h" | 32 | #include "dvb_frontend.h" |
| 33 | #include "tda10021.h" | 33 | #include "tda1002x.h" |
| 34 | 34 | ||
| 35 | 35 | ||
| 36 | struct tda10021_state { | 36 | struct tda10021_state { |
| 37 | struct i2c_adapter* i2c; | 37 | struct i2c_adapter* i2c; |
| 38 | /* configuration settings */ | 38 | /* configuration settings */ |
| 39 | const struct tda10021_config* config; | 39 | const struct tda1002x_config* config; |
| 40 | struct dvb_frontend frontend; | 40 | struct dvb_frontend frontend; |
| 41 | 41 | ||
| 42 | u8 pwm; | 42 | u8 pwm; |
| @@ -53,9 +53,6 @@ struct tda10021_state { | |||
| 53 | static int verbose; | 53 | static int verbose; |
| 54 | 54 | ||
| 55 | #define XIN 57840000UL | 55 | #define XIN 57840000UL |
| 56 | #define DISABLE_INVERSION(reg0) do { reg0 |= 0x20; } while (0) | ||
| 57 | #define ENABLE_INVERSION(reg0) do { reg0 &= ~0x20; } while (0) | ||
| 58 | #define HAS_INVERSION(reg0) (!(reg0 & 0x20)) | ||
| 59 | 56 | ||
| 60 | #define FIN (XIN >> 4) | 57 | #define FIN (XIN >> 4) |
| 61 | 58 | ||
| @@ -64,7 +61,7 @@ static u8 tda10021_inittab[0x40]= | |||
| 64 | { | 61 | { |
| 65 | 0x73, 0x6a, 0x23, 0x0a, 0x02, 0x37, 0x77, 0x1a, | 62 | 0x73, 0x6a, 0x23, 0x0a, 0x02, 0x37, 0x77, 0x1a, |
| 66 | 0x37, 0x6a, 0x17, 0x8a, 0x1e, 0x86, 0x43, 0x40, | 63 | 0x37, 0x6a, 0x17, 0x8a, 0x1e, 0x86, 0x43, 0x40, |
| 67 | 0xb8, 0x3f, 0xa0, 0x00, 0xcd, 0x01, 0x00, 0xff, | 64 | 0xb8, 0x3f, 0xa1, 0x00, 0xcd, 0x01, 0x00, 0xff, |
| 68 | 0x11, 0x00, 0x7c, 0x31, 0x30, 0x20, 0x00, 0x00, | 65 | 0x11, 0x00, 0x7c, 0x31, 0x30, 0x20, 0x00, 0x00, |
| 69 | 0x02, 0x00, 0x00, 0x7d, 0x00, 0x00, 0x00, 0x00, | 66 | 0x02, 0x00, 0x00, 0x7d, 0x00, 0x00, 0x00, 0x00, |
| 70 | 0x07, 0x00, 0x33, 0x11, 0x0d, 0x95, 0x08, 0x58, | 67 | 0x07, 0x00, 0x33, 0x11, 0x0d, 0x95, 0x08, 0x58, |
| @@ -97,7 +94,8 @@ static u8 tda10021_readreg (struct tda10021_state* state, u8 reg) | |||
| 97 | int ret; | 94 | int ret; |
| 98 | 95 | ||
| 99 | ret = i2c_transfer (state->i2c, msg, 2); | 96 | ret = i2c_transfer (state->i2c, msg, 2); |
| 100 | if (ret != 2) | 97 | // Don't print an error message if the id is read. |
| 98 | if (ret != 2 && reg != 0x1a) | ||
| 101 | printk("DVB: TDA10021: %s: readreg error (ret == %i)\n", | 99 | printk("DVB: TDA10021: %s: readreg error (ret == %i)\n", |
| 102 | __FUNCTION__, ret); | 100 | __FUNCTION__, ret); |
| 103 | return b1[0]; | 101 | return b1[0]; |
| @@ -136,10 +134,10 @@ static int tda10021_setup_reg0 (struct tda10021_state* state, u8 reg0, | |||
| 136 | { | 134 | { |
| 137 | reg0 |= state->reg0 & 0x63; | 135 | reg0 |= state->reg0 & 0x63; |
| 138 | 136 | ||
| 139 | if (INVERSION_ON == inversion) | 137 | if ((INVERSION_ON == inversion) ^ (state->config->invert == 0)) |
| 140 | ENABLE_INVERSION(reg0); | 138 | reg0 &= ~0x20; |
| 141 | else if (INVERSION_OFF == inversion) | 139 | else |
| 142 | DISABLE_INVERSION(reg0); | 140 | reg0 |= 0x20; |
| 143 | 141 | ||
| 144 | _tda10021_writereg (state, 0x00, reg0 & 0xfe); | 142 | _tda10021_writereg (state, 0x00, reg0 & 0xfe); |
| 145 | _tda10021_writereg (state, 0x00, reg0 | 0x01); | 143 | _tda10021_writereg (state, 0x00, reg0 | 0x01); |
| @@ -201,16 +199,6 @@ static int tda10021_set_symbolrate (struct tda10021_state* state, u32 symbolrate | |||
| 201 | return 0; | 199 | return 0; |
| 202 | } | 200 | } |
| 203 | 201 | ||
| 204 | static int tda10021_write(struct dvb_frontend* fe, u8 *buf, int len) | ||
| 205 | { | ||
| 206 | struct tda10021_state* state = fe->demodulator_priv; | ||
| 207 | |||
| 208 | if (len != 2) | ||
| 209 | return -EINVAL; | ||
| 210 | |||
| 211 | return _tda10021_writereg(state, buf[0], buf[1]); | ||
| 212 | } | ||
| 213 | |||
| 214 | static int tda10021_init (struct dvb_frontend *fe) | 202 | static int tda10021_init (struct dvb_frontend *fe) |
| 215 | { | 203 | { |
| 216 | struct tda10021_state* state = fe->demodulator_priv; | 204 | struct tda10021_state* state = fe->demodulator_priv; |
| @@ -258,6 +246,9 @@ static int tda10021_set_parameters (struct dvb_frontend *fe, | |||
| 258 | if (qam < 0 || qam > 5) | 246 | if (qam < 0 || qam > 5) |
| 259 | return -EINVAL; | 247 | return -EINVAL; |
| 260 | 248 | ||
| 249 | if (p->inversion != INVERSION_ON && p->inversion != INVERSION_OFF) | ||
| 250 | return -EINVAL; | ||
| 251 | |||
| 261 | //printk("tda10021: set frequency to %d qam=%d symrate=%d\n", p->frequency,qam,p->u.qam.symbol_rate); | 252 | //printk("tda10021: set frequency to %d qam=%d symrate=%d\n", p->frequency,qam,p->u.qam.symbol_rate); |
| 262 | 253 | ||
| 263 | if (fe->ops.tuner_ops.set_params) { | 254 | if (fe->ops.tuner_ops.set_params) { |
| @@ -366,7 +357,7 @@ static int tda10021_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_pa | |||
| 366 | -((s32)p->u.qam.symbol_rate * afc) >> 10); | 357 | -((s32)p->u.qam.symbol_rate * afc) >> 10); |
| 367 | } | 358 | } |
| 368 | 359 | ||
| 369 | p->inversion = HAS_INVERSION(state->reg0) ? INVERSION_ON : INVERSION_OFF; | 360 | p->inversion = ((state->reg0 & 0x20) == 0x20) ^ (state->config->invert != 0) ? INVERSION_ON : INVERSION_OFF; |
| 370 | p->u.qam.modulation = ((state->reg0 >> 2) & 7) + QAM_16; | 361 | p->u.qam.modulation = ((state->reg0 >> 2) & 7) + QAM_16; |
| 371 | 362 | ||
| 372 | p->u.qam.fec_inner = FEC_NONE; | 363 | p->u.qam.fec_inner = FEC_NONE; |
| @@ -408,11 +399,12 @@ static void tda10021_release(struct dvb_frontend* fe) | |||
| 408 | 399 | ||
| 409 | static struct dvb_frontend_ops tda10021_ops; | 400 | static struct dvb_frontend_ops tda10021_ops; |
| 410 | 401 | ||
| 411 | struct dvb_frontend* tda10021_attach(const struct tda10021_config* config, | 402 | struct dvb_frontend* tda10021_attach(const struct tda1002x_config* config, |
| 412 | struct i2c_adapter* i2c, | 403 | struct i2c_adapter* i2c, |
| 413 | u8 pwm) | 404 | u8 pwm) |
| 414 | { | 405 | { |
| 415 | struct tda10021_state* state = NULL; | 406 | struct tda10021_state* state = NULL; |
| 407 | u8 id; | ||
| 416 | 408 | ||
| 417 | /* allocate memory for the internal state */ | 409 | /* allocate memory for the internal state */ |
| 418 | state = kmalloc(sizeof(struct tda10021_state), GFP_KERNEL); | 410 | state = kmalloc(sizeof(struct tda10021_state), GFP_KERNEL); |
| @@ -425,7 +417,11 @@ struct dvb_frontend* tda10021_attach(const struct tda10021_config* config, | |||
| 425 | state->reg0 = tda10021_inittab[0]; | 417 | state->reg0 = tda10021_inittab[0]; |
| 426 | 418 | ||
| 427 | /* check if the demod is there */ | 419 | /* check if the demod is there */ |
| 428 | if ((tda10021_readreg(state, 0x1a) & 0xf0) != 0x70) goto error; | 420 | id = tda10021_readreg(state, 0x1a); |
| 421 | if ((id & 0xf0) != 0x70) goto error; | ||
| 422 | |||
| 423 | printk("TDA10021: i2c-addr = 0x%02x, id = 0x%02x\n", | ||
| 424 | state->config->demod_address, id); | ||
| 429 | 425 | ||
| 430 | /* create dvb_frontend */ | 426 | /* create dvb_frontend */ |
| 431 | memcpy(&state->frontend.ops, &tda10021_ops, sizeof(struct dvb_frontend_ops)); | 427 | memcpy(&state->frontend.ops, &tda10021_ops, sizeof(struct dvb_frontend_ops)); |
| @@ -447,7 +443,7 @@ static struct dvb_frontend_ops tda10021_ops = { | |||
| 447 | .frequency_max = 858000000, | 443 | .frequency_max = 858000000, |
| 448 | .symbol_rate_min = (XIN/2)/64, /* SACLK/64 == (XIN/2)/64 */ | 444 | .symbol_rate_min = (XIN/2)/64, /* SACLK/64 == (XIN/2)/64 */ |
| 449 | .symbol_rate_max = (XIN/2)/4, /* SACLK/4 */ | 445 | .symbol_rate_max = (XIN/2)/4, /* SACLK/4 */ |
| 450 | #if 0 | 446 | #if 0 |
| 451 | .frequency_tolerance = ???, | 447 | .frequency_tolerance = ???, |
| 452 | .symbol_rate_tolerance = ???, /* ppm */ /* == 8% (spec p. 5) */ | 448 | .symbol_rate_tolerance = ???, /* ppm */ /* == 8% (spec p. 5) */ |
| 453 | #endif | 449 | #endif |
| @@ -461,7 +457,6 @@ static struct dvb_frontend_ops tda10021_ops = { | |||
| 461 | 457 | ||
| 462 | .init = tda10021_init, | 458 | .init = tda10021_init, |
| 463 | .sleep = tda10021_sleep, | 459 | .sleep = tda10021_sleep, |
| 464 | .write = tda10021_write, | ||
| 465 | .i2c_gate_ctrl = tda10021_i2c_gate_ctrl, | 460 | .i2c_gate_ctrl = tda10021_i2c_gate_ctrl, |
| 466 | 461 | ||
| 467 | .set_frontend = tda10021_set_parameters, | 462 | .set_frontend = tda10021_set_parameters, |
diff --git a/drivers/media/dvb/frontends/tda10023.c b/drivers/media/dvb/frontends/tda10023.c new file mode 100644 index 000000000000..da796e784be3 --- /dev/null +++ b/drivers/media/dvb/frontends/tda10023.c | |||
| @@ -0,0 +1,540 @@ | |||
| 1 | /* | ||
| 2 | TDA10023 - DVB-C decoder | ||
| 3 | (as used in Philips CU1216-3 NIM and the Reelbox DVB-C tuner card) | ||
| 4 | |||
| 5 | Copyright (C) 2005 Georg Acher, BayCom GmbH (acher at baycom dot de) | ||
| 6 | Copyright (c) 2006 Hartmut Birr (e9hack at gmail dot com) | ||
| 7 | |||
| 8 | Remotely based on tda10021.c | ||
| 9 | Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de> | ||
| 10 | Copyright (C) 2004 Markus Schulz <msc@antzsystem.de> | ||
| 11 | Support for TDA10021 | ||
| 12 | |||
| 13 | This program is free software; you can redistribute it and/or modify | ||
| 14 | it under the terms of the GNU General Public License as published by | ||
| 15 | the Free Software Foundation; either version 2 of the License, or | ||
| 16 | (at your option) any later version. | ||
| 17 | |||
| 18 | This program is distributed in the hope that it will be useful, | ||
| 19 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 20 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 21 | GNU General Public License for more details. | ||
| 22 | |||
| 23 | You should have received a copy of the GNU General Public License | ||
| 24 | along with this program; if not, write to the Free Software | ||
| 25 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 26 | */ | ||
| 27 | |||
| 28 | #include <linux/delay.h> | ||
| 29 | #include <linux/errno.h> | ||
| 30 | #include <linux/init.h> | ||
| 31 | #include <linux/kernel.h> | ||
| 32 | #include <linux/module.h> | ||
| 33 | #include <linux/string.h> | ||
| 34 | #include <linux/slab.h> | ||
| 35 | |||
| 36 | #include <asm/div64.h> | ||
| 37 | |||
| 38 | #include "dvb_frontend.h" | ||
| 39 | #include "tda1002x.h" | ||
| 40 | |||
| 41 | |||
| 42 | struct tda10023_state { | ||
| 43 | struct i2c_adapter* i2c; | ||
| 44 | /* configuration settings */ | ||
| 45 | const struct tda1002x_config* config; | ||
| 46 | struct dvb_frontend frontend; | ||
| 47 | |||
| 48 | u8 pwm; | ||
| 49 | u8 reg0; | ||
| 50 | }; | ||
| 51 | |||
| 52 | |||
| 53 | #define dprintk(x...) | ||
| 54 | |||
| 55 | static int verbose; | ||
| 56 | |||
| 57 | #define XTAL 28920000UL | ||
| 58 | #define PLL_M 8UL | ||
| 59 | #define PLL_P 4UL | ||
| 60 | #define PLL_N 1UL | ||
| 61 | #define SYSCLK (XTAL*PLL_M/(PLL_N*PLL_P)) // -> 57840000 | ||
| 62 | |||
| 63 | static u8 tda10023_inittab[]={ | ||
| 64 | // reg mask val | ||
| 65 | 0x2a,0xff,0x02, // PLL3, Bypass, Power Down | ||
| 66 | 0xff,0x64,0x00, // Sleep 100ms | ||
| 67 | 0x2a,0xff,0x03, // PLL3, Bypass, Power Down | ||
| 68 | 0xff,0x64,0x00, // Sleep 100ms | ||
| 69 | 0x28,0xff,PLL_M-1, // PLL1 M=8 | ||
| 70 | 0x29,0xff,((PLL_P-1)<<6)|(PLL_N-1), // PLL2 | ||
| 71 | 0x00,0xff,0x23, // GPR FSAMPLING=1 | ||
| 72 | 0x2a,0xff,0x08, // PLL3 PSACLK=1 | ||
| 73 | 0xff,0x64,0x00, // Sleep 100ms | ||
| 74 | 0x1f,0xff,0x00, // RESET | ||
| 75 | 0xff,0x64,0x00, // Sleep 100ms | ||
| 76 | 0xe6,0x0c,0x04, // RSCFG_IND | ||
| 77 | 0x10,0xc0,0x80, // DECDVBCFG1 PBER=1 | ||
| 78 | |||
| 79 | 0x0e,0xff,0x82, // GAIN1 | ||
| 80 | 0x03,0x08,0x08, // CLKCONF DYN=1 | ||
| 81 | 0x2e,0xbf,0x30, // AGCCONF2 TRIAGC=0,POSAGC=ENAGCIF=1 PPWMTUN=0 PPWMIF=0 | ||
| 82 | 0x01,0xff,0x30, // AGCREF | ||
| 83 | 0x1e,0x84,0x84, // CONTROL SACLK_ON=1 | ||
| 84 | 0x1b,0xff,0xc8, // ADC TWOS=1 | ||
| 85 | 0x3b,0xff,0xff, // IFMAX | ||
| 86 | 0x3c,0xff,0x00, // IFMIN | ||
| 87 | 0x34,0xff,0x00, // PWMREF | ||
| 88 | 0x35,0xff,0xff, // TUNMAX | ||
| 89 | 0x36,0xff,0x00, // TUNMIN | ||
| 90 | 0x06,0xff,0x7f, // EQCONF1 POSI=7 ENADAPT=ENEQUAL=DFE=1 // 0x77 | ||
| 91 | 0x1c,0x30,0x30, // EQCONF2 STEPALGO=SGNALGO=1 | ||
| 92 | 0x37,0xff,0xf6, // DELTAF_LSB | ||
| 93 | 0x38,0xff,0xff, // DELTAF_MSB | ||
| 94 | 0x02,0xff,0x93, // AGCCONF1 IFS=1 KAGCIF=2 KAGCTUN=3 | ||
| 95 | 0x2d,0xff,0xf6, // SWEEP SWPOS=1 SWDYN=7 SWSTEP=1 SWLEN=2 | ||
| 96 | 0x04,0x10,0x00, // SWRAMP=1 | ||
| 97 | 0x12,0xff,0xa1, // INTP1 POCLKP=1 FEL=1 MFS=0 | ||
| 98 | 0x2b,0x01,0xa1, // INTS1 | ||
| 99 | 0x20,0xff,0x04, // INTP2 SWAPP=? MSBFIRSTP=? INTPSEL=? | ||
| 100 | 0x2c,0xff,0x0d, // INTP/S TRIP=0 TRIS=0 | ||
| 101 | 0xc4,0xff,0x00, | ||
| 102 | 0xc3,0x30,0x00, | ||
| 103 | 0xb5,0xff,0x19, // ERAGC_THD | ||
| 104 | 0x00,0x03,0x01, // GPR, CLBS soft reset | ||
| 105 | 0x00,0x03,0x03, // GPR, CLBS soft reset | ||
| 106 | 0xff,0x64,0x00, // Sleep 100ms | ||
| 107 | 0xff,0xff,0xff | ||
| 108 | }; | ||
| 109 | |||
| 110 | static u8 tda10023_readreg (struct tda10023_state* state, u8 reg) | ||
| 111 | { | ||
| 112 | u8 b0 [] = { reg }; | ||
| 113 | u8 b1 [] = { 0 }; | ||
| 114 | struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 }, | ||
| 115 | { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } }; | ||
| 116 | int ret; | ||
| 117 | |||
| 118 | ret = i2c_transfer (state->i2c, msg, 2); | ||
| 119 | if (ret != 2) | ||
| 120 | printk("DVB: TDA10023: %s: readreg error (ret == %i)\n", | ||
| 121 | __FUNCTION__, ret); | ||
| 122 | return b1[0]; | ||
| 123 | } | ||
| 124 | |||
| 125 | static int tda10023_writereg (struct tda10023_state* state, u8 reg, u8 data) | ||
| 126 | { | ||
| 127 | u8 buf[] = { reg, data }; | ||
| 128 | struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 }; | ||
| 129 | int ret; | ||
| 130 | |||
| 131 | ret = i2c_transfer (state->i2c, &msg, 1); | ||
| 132 | if (ret != 1) | ||
| 133 | printk("DVB: TDA10023(%d): %s, writereg error " | ||
| 134 | "(reg == 0x%02x, val == 0x%02x, ret == %i)\n", | ||
| 135 | state->frontend.dvb->num, __FUNCTION__, reg, data, ret); | ||
| 136 | |||
| 137 | return (ret != 1) ? -EREMOTEIO : 0; | ||
| 138 | } | ||
| 139 | |||
| 140 | |||
| 141 | static int tda10023_writebit (struct tda10023_state* state, u8 reg, u8 mask,u8 data) | ||
| 142 | { | ||
| 143 | if (mask==0xff) | ||
| 144 | return tda10023_writereg(state, reg, data); | ||
| 145 | else { | ||
| 146 | u8 val; | ||
| 147 | val=tda10023_readreg(state,reg); | ||
| 148 | val&=~mask; | ||
| 149 | val|=(data&mask); | ||
| 150 | return tda10023_writereg(state, reg, val); | ||
| 151 | } | ||
| 152 | } | ||
| 153 | |||
| 154 | static void tda10023_writetab(struct tda10023_state* state, u8* tab) | ||
| 155 | { | ||
| 156 | u8 r,m,v; | ||
| 157 | while (1) { | ||
| 158 | r=*tab++; | ||
| 159 | m=*tab++; | ||
| 160 | v=*tab++; | ||
| 161 | if (r==0xff) { | ||
| 162 | if (m==0xff) | ||
| 163 | break; | ||
| 164 | else | ||
| 165 | msleep(m); | ||
| 166 | } | ||
| 167 | else | ||
| 168 | tda10023_writebit(state,r,m,v); | ||
| 169 | } | ||
| 170 | } | ||
| 171 | |||
| 172 | //get access to tuner | ||
| 173 | static int lock_tuner(struct tda10023_state* state) | ||
| 174 | { | ||
| 175 | u8 buf[2] = { 0x0f, 0xc0 }; | ||
| 176 | struct i2c_msg msg = {.addr=state->config->demod_address, .flags=0, .buf=buf, .len=2}; | ||
| 177 | |||
| 178 | if(i2c_transfer(state->i2c, &msg, 1) != 1) | ||
| 179 | { | ||
| 180 | printk("tda10023: lock tuner fails\n"); | ||
| 181 | return -EREMOTEIO; | ||
| 182 | } | ||
| 183 | return 0; | ||
| 184 | } | ||
| 185 | |||
| 186 | //release access from tuner | ||
| 187 | static int unlock_tuner(struct tda10023_state* state) | ||
| 188 | { | ||
| 189 | u8 buf[2] = { 0x0f, 0x40 }; | ||
| 190 | struct i2c_msg msg_post={.addr=state->config->demod_address, .flags=0, .buf=buf, .len=2}; | ||
| 191 | |||
| 192 | if(i2c_transfer(state->i2c, &msg_post, 1) != 1) | ||
| 193 | { | ||
| 194 | printk("tda10023: unlock tuner fails\n"); | ||
| 195 | return -EREMOTEIO; | ||
| 196 | } | ||
| 197 | return 0; | ||
| 198 | } | ||
| 199 | |||
| 200 | static int tda10023_setup_reg0 (struct tda10023_state* state, u8 reg0) | ||
| 201 | { | ||
| 202 | reg0 |= state->reg0 & 0x63; | ||
| 203 | |||
| 204 | tda10023_writereg (state, 0x00, reg0 & 0xfe); | ||
| 205 | tda10023_writereg (state, 0x00, reg0 | 0x01); | ||
| 206 | |||
| 207 | state->reg0 = reg0; | ||
| 208 | return 0; | ||
| 209 | } | ||
| 210 | |||
| 211 | static int tda10023_set_symbolrate (struct tda10023_state* state, u32 sr) | ||
| 212 | { | ||
| 213 | s32 BDR; | ||
| 214 | s32 BDRI; | ||
| 215 | s16 SFIL=0; | ||
| 216 | u16 NDEC = 0; | ||
| 217 | |||
| 218 | if (sr > (SYSCLK/(2*4))) | ||
| 219 | sr=SYSCLK/(2*4); | ||
| 220 | |||
| 221 | if (sr<870000) | ||
| 222 | sr=870000; | ||
| 223 | |||
| 224 | if (sr < (u32)(SYSCLK/98.40)) { | ||
| 225 | NDEC=3; | ||
| 226 | SFIL=1; | ||
| 227 | } else if (sr<(u32)(SYSCLK/64.0)) { | ||
| 228 | NDEC=3; | ||
| 229 | SFIL=0; | ||
| 230 | } else if (sr<(u32)(SYSCLK/49.2)) { | ||
| 231 | NDEC=2; | ||
| 232 | SFIL=1; | ||
| 233 | } else if (sr<(u32)(SYSCLK/32.0)) { | ||
| 234 | NDEC=2; | ||
| 235 | SFIL=0; | ||
| 236 | } else if (sr<(u32)(SYSCLK/24.6)) { | ||
| 237 | NDEC=1; | ||
| 238 | SFIL=1; | ||
| 239 | } else if (sr<(u32)(SYSCLK/16.0)) { | ||
| 240 | NDEC=1; | ||
| 241 | SFIL=0; | ||
| 242 | } else if (sr<(u32)(SYSCLK/12.3)) { | ||
| 243 | NDEC=0; | ||
| 244 | SFIL=1; | ||
| 245 | } | ||
| 246 | |||
| 247 | BDRI=SYSCLK*16; | ||
| 248 | BDRI>>=NDEC; | ||
| 249 | BDRI +=sr/2; | ||
| 250 | BDRI /=sr; | ||
| 251 | |||
| 252 | if (BDRI>255) | ||
| 253 | BDRI=255; | ||
| 254 | |||
| 255 | { | ||
| 256 | u64 BDRX; | ||
| 257 | |||
| 258 | BDRX=1<<(24+NDEC); | ||
| 259 | BDRX*=sr; | ||
| 260 | do_div(BDRX,SYSCLK); // BDRX/=SYSCLK; | ||
| 261 | |||
| 262 | BDR=(s32)BDRX; | ||
| 263 | } | ||
| 264 | // printk("Symbolrate %i, BDR %i BDRI %i, NDEC %i\n",sr,BDR,BDRI,NDEC); | ||
| 265 | tda10023_writebit (state, 0x03, 0xc0, NDEC<<6); | ||
| 266 | tda10023_writereg (state, 0x0a, BDR&255); | ||
| 267 | tda10023_writereg (state, 0x0b, (BDR>>8)&255); | ||
| 268 | tda10023_writereg (state, 0x0c, (BDR>>16)&31); | ||
| 269 | tda10023_writereg (state, 0x0d, BDRI); | ||
| 270 | tda10023_writereg (state, 0x3d, (SFIL<<7)); | ||
| 271 | return 0; | ||
| 272 | } | ||
| 273 | |||
| 274 | static int tda10023_init (struct dvb_frontend *fe) | ||
| 275 | { | ||
| 276 | struct tda10023_state* state = fe->demodulator_priv; | ||
| 277 | |||
| 278 | dprintk("DVB: TDA10023(%d): init chip\n", fe->adapter->num); | ||
| 279 | |||
| 280 | tda10023_writetab(state, tda10023_inittab); | ||
| 281 | |||
| 282 | return 0; | ||
| 283 | } | ||
| 284 | |||
| 285 | static int tda10023_set_parameters (struct dvb_frontend *fe, | ||
| 286 | struct dvb_frontend_parameters *p) | ||
| 287 | { | ||
| 288 | struct tda10023_state* state = fe->demodulator_priv; | ||
| 289 | |||
| 290 | static int qamvals[6][6] = { | ||
| 291 | // QAM LOCKTHR MSETH AREF AGCREFNYQ ERAGCNYQ_THD | ||
| 292 | { (5<<2), 0x78, 0x8c, 0x96, 0x78, 0x4c }, // 4 QAM | ||
| 293 | { (0<<2), 0x87, 0xa2, 0x91, 0x8c, 0x57 }, // 16 QAM | ||
| 294 | { (1<<2), 0x64, 0x74, 0x96, 0x8c, 0x57 }, // 32 QAM | ||
| 295 | { (2<<2), 0x46, 0x43, 0x6a, 0x6a, 0x44 }, // 64 QAM | ||
| 296 | { (3<<2), 0x36, 0x34, 0x7e, 0x78, 0x4c }, // 128 QAM | ||
| 297 | { (4<<2), 0x26, 0x23, 0x6c, 0x5c, 0x3c }, // 256 QAM | ||
| 298 | }; | ||
| 299 | |||
| 300 | int qam = p->u.qam.modulation; | ||
| 301 | |||
| 302 | if (qam < 0 || qam > 5) | ||
| 303 | return -EINVAL; | ||
| 304 | |||
| 305 | if (fe->ops.tuner_ops.set_params) { | ||
| 306 | fe->ops.tuner_ops.set_params(fe, p); | ||
| 307 | if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); | ||
| 308 | } | ||
| 309 | |||
| 310 | tda10023_set_symbolrate (state, p->u.qam.symbol_rate); | ||
| 311 | tda10023_writereg (state, 0x05, qamvals[qam][1]); | ||
| 312 | tda10023_writereg (state, 0x08, qamvals[qam][2]); | ||
| 313 | tda10023_writereg (state, 0x09, qamvals[qam][3]); | ||
| 314 | tda10023_writereg (state, 0xb4, qamvals[qam][4]); | ||
| 315 | tda10023_writereg (state, 0xb6, qamvals[qam][5]); | ||
| 316 | |||
| 317 | // tda10023_writereg (state, 0x04, (p->inversion?0x12:0x32)); | ||
| 318 | // tda10023_writebit (state, 0x04, 0x60, (p->inversion?0:0x20)); | ||
| 319 | tda10023_writebit (state, 0x04, 0x40, 0x40); | ||
| 320 | tda10023_setup_reg0 (state, qamvals[qam][0]); | ||
| 321 | |||
| 322 | return 0; | ||
| 323 | } | ||
| 324 | |||
| 325 | static int tda10023_read_status(struct dvb_frontend* fe, fe_status_t* status) | ||
| 326 | { | ||
| 327 | struct tda10023_state* state = fe->demodulator_priv; | ||
| 328 | int sync; | ||
| 329 | |||
| 330 | *status = 0; | ||
| 331 | |||
| 332 | //0x11[1] == CARLOCK -> Carrier locked | ||
| 333 | //0x11[2] == FSYNC -> Frame synchronisation | ||
| 334 | //0x11[3] == FEL -> Front End locked | ||
| 335 | //0x11[6] == NODVB -> DVB Mode Information | ||
| 336 | sync = tda10023_readreg (state, 0x11); | ||
| 337 | |||
| 338 | if (sync & 2) | ||
| 339 | *status |= FE_HAS_SIGNAL|FE_HAS_CARRIER; | ||
| 340 | |||
| 341 | if (sync & 4) | ||
| 342 | *status |= FE_HAS_SYNC|FE_HAS_VITERBI; | ||
| 343 | |||
| 344 | if (sync & 8) | ||
| 345 | *status |= FE_HAS_LOCK; | ||
| 346 | |||
| 347 | return 0; | ||
| 348 | } | ||
| 349 | |||
| 350 | static int tda10023_read_ber(struct dvb_frontend* fe, u32* ber) | ||
| 351 | { | ||
| 352 | struct tda10023_state* state = fe->demodulator_priv; | ||
| 353 | u8 a,b,c; | ||
| 354 | a=tda10023_readreg(state, 0x14); | ||
| 355 | b=tda10023_readreg(state, 0x15); | ||
| 356 | c=tda10023_readreg(state, 0x16)&0xf; | ||
| 357 | tda10023_writebit (state, 0x10, 0xc0, 0x00); | ||
| 358 | |||
| 359 | *ber = a | (b<<8)| (c<<16); | ||
| 360 | return 0; | ||
| 361 | } | ||
| 362 | |||
| 363 | static int tda10023_read_signal_strength(struct dvb_frontend* fe, u16* strength) | ||
| 364 | { | ||
| 365 | struct tda10023_state* state = fe->demodulator_priv; | ||
| 366 | u8 ifgain=tda10023_readreg(state, 0x2f); | ||
| 367 | |||
| 368 | u16 gain = ((255-tda10023_readreg(state, 0x17))) + (255-ifgain)/16; | ||
| 369 | // Max raw value is about 0xb0 -> Normalize to >0xf0 after 0x90 | ||
| 370 | if (gain>0x90) | ||
| 371 | gain=gain+2*(gain-0x90); | ||
| 372 | if (gain>255) | ||
| 373 | gain=255; | ||
| 374 | |||
| 375 | *strength = (gain<<8)|gain; | ||
| 376 | return 0; | ||
| 377 | } | ||
| 378 | |||
| 379 | static int tda10023_read_snr(struct dvb_frontend* fe, u16* snr) | ||
| 380 | { | ||
| 381 | struct tda10023_state* state = fe->demodulator_priv; | ||
| 382 | |||
| 383 | u8 quality = ~tda10023_readreg(state, 0x18); | ||
| 384 | *snr = (quality << 8) | quality; | ||
| 385 | return 0; | ||
| 386 | } | ||
| 387 | |||
| 388 | static int tda10023_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) | ||
| 389 | { | ||
| 390 | struct tda10023_state* state = fe->demodulator_priv; | ||
| 391 | u8 a,b,c,d; | ||
| 392 | a= tda10023_readreg (state, 0x74); | ||
| 393 | b= tda10023_readreg (state, 0x75); | ||
| 394 | c= tda10023_readreg (state, 0x76); | ||
| 395 | d= tda10023_readreg (state, 0x77); | ||
| 396 | *ucblocks = a | (b<<8)|(c<<16)|(d<<24); | ||
| 397 | |||
| 398 | tda10023_writebit (state, 0x10, 0x20,0x00); | ||
| 399 | tda10023_writebit (state, 0x10, 0x20,0x20); | ||
| 400 | tda10023_writebit (state, 0x13, 0x01, 0x00); | ||
| 401 | |||
| 402 | return 0; | ||
| 403 | } | ||
| 404 | |||
| 405 | static int tda10023_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) | ||
| 406 | { | ||
| 407 | struct tda10023_state* state = fe->demodulator_priv; | ||
| 408 | int sync,inv; | ||
| 409 | s8 afc = 0; | ||
| 410 | |||
| 411 | sync = tda10023_readreg(state, 0x11); | ||
| 412 | afc = tda10023_readreg(state, 0x19); | ||
| 413 | inv = tda10023_readreg(state, 0x04); | ||
| 414 | |||
| 415 | if (verbose) { | ||
| 416 | /* AFC only valid when carrier has been recovered */ | ||
| 417 | printk(sync & 2 ? "DVB: TDA10023(%d): AFC (%d) %dHz\n" : | ||
| 418 | "DVB: TDA10023(%d): [AFC (%d) %dHz]\n", | ||
| 419 | state->frontend.dvb->num, afc, | ||
| 420 | -((s32)p->u.qam.symbol_rate * afc) >> 10); | ||
| 421 | } | ||
| 422 | |||
| 423 | p->inversion = (inv&0x20?0:1); | ||
| 424 | p->u.qam.modulation = ((state->reg0 >> 2) & 7) + QAM_16; | ||
| 425 | |||
| 426 | p->u.qam.fec_inner = FEC_NONE; | ||
| 427 | p->frequency = ((p->frequency + 31250) / 62500) * 62500; | ||
| 428 | |||
| 429 | if (sync & 2) | ||
| 430 | p->frequency -= ((s32)p->u.qam.symbol_rate * afc) >> 10; | ||
| 431 | |||
| 432 | return 0; | ||
| 433 | } | ||
| 434 | |||
| 435 | static int tda10023_sleep(struct dvb_frontend* fe) | ||
| 436 | { | ||
| 437 | struct tda10023_state* state = fe->demodulator_priv; | ||
| 438 | |||
| 439 | tda10023_writereg (state, 0x1b, 0x02); /* pdown ADC */ | ||
| 440 | tda10023_writereg (state, 0x00, 0x80); /* standby */ | ||
| 441 | |||
| 442 | return 0; | ||
| 443 | } | ||
| 444 | |||
| 445 | static int tda10023_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) | ||
| 446 | { | ||
| 447 | struct tda10023_state* state = fe->demodulator_priv; | ||
| 448 | |||
| 449 | if (enable) { | ||
| 450 | lock_tuner(state); | ||
| 451 | } else { | ||
| 452 | unlock_tuner(state); | ||
| 453 | } | ||
| 454 | return 0; | ||
| 455 | } | ||
| 456 | |||
| 457 | static void tda10023_release(struct dvb_frontend* fe) | ||
| 458 | { | ||
| 459 | struct tda10023_state* state = fe->demodulator_priv; | ||
| 460 | kfree(state); | ||
| 461 | } | ||
| 462 | |||
| 463 | static struct dvb_frontend_ops tda10023_ops; | ||
| 464 | |||
| 465 | struct dvb_frontend* tda10023_attach(const struct tda1002x_config* config, | ||
| 466 | struct i2c_adapter* i2c, | ||
| 467 | u8 pwm) | ||
| 468 | { | ||
| 469 | struct tda10023_state* state = NULL; | ||
| 470 | int i; | ||
| 471 | |||
| 472 | /* allocate memory for the internal state */ | ||
| 473 | state = kmalloc(sizeof(struct tda10023_state), GFP_KERNEL); | ||
| 474 | if (state == NULL) goto error; | ||
| 475 | |||
| 476 | /* setup the state */ | ||
| 477 | state->config = config; | ||
| 478 | state->i2c = i2c; | ||
| 479 | memcpy(&state->frontend.ops, &tda10023_ops, sizeof(struct dvb_frontend_ops)); | ||
| 480 | state->pwm = pwm; | ||
| 481 | for (i=0; i < sizeof(tda10023_inittab)/sizeof(*tda10023_inittab);i+=3) { | ||
| 482 | if (tda10023_inittab[i] == 0x00) { | ||
| 483 | state->reg0 = tda10023_inittab[i+2]; | ||
| 484 | break; | ||
| 485 | } | ||
| 486 | } | ||
| 487 | |||
| 488 | // Wakeup if in standby | ||
| 489 | tda10023_writereg (state, 0x00, 0x33); | ||
| 490 | /* check if the demod is there */ | ||
| 491 | if ((tda10023_readreg(state, 0x1a) & 0xf0) != 0x70) goto error; | ||
| 492 | |||
| 493 | /* create dvb_frontend */ | ||
| 494 | memcpy(&state->frontend.ops, &tda10023_ops, sizeof(struct dvb_frontend_ops)); | ||
| 495 | state->frontend.demodulator_priv = state; | ||
| 496 | return &state->frontend; | ||
| 497 | |||
| 498 | error: | ||
| 499 | kfree(state); | ||
| 500 | return NULL; | ||
| 501 | } | ||
| 502 | |||
| 503 | static struct dvb_frontend_ops tda10023_ops = { | ||
| 504 | |||
| 505 | .info = { | ||
| 506 | .name = "Philips TDA10023 DVB-C", | ||
| 507 | .type = FE_QAM, | ||
| 508 | .frequency_stepsize = 62500, | ||
| 509 | .frequency_min = 51000000, | ||
| 510 | .frequency_max = 858000000, | ||
| 511 | .symbol_rate_min = (SYSCLK/2)/64, /* SACLK/64 == (SYSCLK/2)/64 */ | ||
| 512 | .symbol_rate_max = (SYSCLK/2)/4, /* SACLK/4 */ | ||
| 513 | .caps = 0x400 | //FE_CAN_QAM_4 | ||
| 514 | FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 | | ||
| 515 | FE_CAN_QAM_128 | FE_CAN_QAM_256 | | ||
| 516 | FE_CAN_FEC_AUTO | ||
| 517 | }, | ||
| 518 | |||
| 519 | .release = tda10023_release, | ||
| 520 | |||
| 521 | .init = tda10023_init, | ||
| 522 | .sleep = tda10023_sleep, | ||
| 523 | .i2c_gate_ctrl = tda10023_i2c_gate_ctrl, | ||
| 524 | |||
| 525 | .set_frontend = tda10023_set_parameters, | ||
| 526 | .get_frontend = tda10023_get_frontend, | ||
| 527 | |||
| 528 | .read_status = tda10023_read_status, | ||
| 529 | .read_ber = tda10023_read_ber, | ||
| 530 | .read_signal_strength = tda10023_read_signal_strength, | ||
| 531 | .read_snr = tda10023_read_snr, | ||
| 532 | .read_ucblocks = tda10023_read_ucblocks, | ||
| 533 | }; | ||
| 534 | |||
| 535 | |||
| 536 | MODULE_DESCRIPTION("Philips TDA10023 DVB-C demodulator driver"); | ||
| 537 | MODULE_AUTHOR("Georg Acher, Hartmut Birr"); | ||
| 538 | MODULE_LICENSE("GPL"); | ||
| 539 | |||
| 540 | EXPORT_SYMBOL(tda10023_attach); | ||
diff --git a/drivers/media/dvb/frontends/tda10021.h b/drivers/media/dvb/frontends/tda1002x.h index e3da780108f6..e9094d8123f6 100644 --- a/drivers/media/dvb/frontends/tda10021.h +++ b/drivers/media/dvb/frontends/tda1002x.h | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* | 1 | /* |
| 2 | TDA10021 - Single Chip Cable Channel Receiver driver module | 2 | TDA10021/TDA10023 - Single Chip Cable Channel Receiver driver module |
| 3 | used on the the Siemens DVB-C cards | 3 | used on the the Siemens DVB-C cards |
| 4 | 4 | ||
| 5 | Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de> | 5 | Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de> |
| 6 | Copyright (C) 2004 Markus Schulz <msc@antzsystem.de> | 6 | Copyright (C) 2004 Markus Schulz <msc@antzsystem.de> |
| @@ -21,22 +21,23 @@ | |||
| 21 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 21 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
| 22 | */ | 22 | */ |
| 23 | 23 | ||
| 24 | #ifndef TDA10021_H | 24 | #ifndef TDA1002x_H |
| 25 | #define TDA10021_H | 25 | #define TDA1002x_H |
| 26 | 26 | ||
| 27 | #include <linux/dvb/frontend.h> | 27 | #include <linux/dvb/frontend.h> |
| 28 | 28 | ||
| 29 | struct tda10021_config | 29 | struct tda1002x_config |
| 30 | { | 30 | { |
| 31 | /* the demodulator's i2c address */ | 31 | /* the demodulator's i2c address */ |
| 32 | u8 demod_address; | 32 | u8 demod_address; |
| 33 | u8 invert; | ||
| 33 | }; | 34 | }; |
| 34 | 35 | ||
| 35 | #if defined(CONFIG_DVB_TDA10021) || (defined(CONFIG_DVB_TDA10021_MODULE) && defined(MODULE)) | 36 | #if defined(CONFIG_DVB_TDA10021) || (defined(CONFIG_DVB_TDA10021_MODULE) && defined(MODULE)) |
| 36 | extern struct dvb_frontend* tda10021_attach(const struct tda10021_config* config, | 37 | extern struct dvb_frontend* tda10021_attach(const struct tda1002x_config* config, |
| 37 | struct i2c_adapter* i2c, u8 pwm); | 38 | struct i2c_adapter* i2c, u8 pwm); |
| 38 | #else | 39 | #else |
| 39 | static inline struct dvb_frontend* tda10021_attach(const struct tda10021_config* config, | 40 | static inline struct dvb_frontend* tda10021_attach(const struct tda1002x_config* config, |
| 40 | struct i2c_adapter* i2c, u8 pwm) | 41 | struct i2c_adapter* i2c, u8 pwm) |
| 41 | { | 42 | { |
| 42 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); | 43 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); |
| @@ -44,12 +45,16 @@ static inline struct dvb_frontend* tda10021_attach(const struct tda10021_config* | |||
| 44 | } | 45 | } |
| 45 | #endif // CONFIG_DVB_TDA10021 | 46 | #endif // CONFIG_DVB_TDA10021 |
| 46 | 47 | ||
| 47 | static inline int tda10021_writereg(struct dvb_frontend *fe, u8 reg, u8 val) { | 48 | #if defined(CONFIG_DVB_TDA10023) || (defined(CONFIG_DVB_TDA10023_MODULE) && defined(MODULE)) |
| 48 | int r = 0; | 49 | extern struct dvb_frontend* tda10023_attach(const struct tda1002x_config* config, |
| 49 | u8 buf[] = {reg, val}; | 50 | struct i2c_adapter* i2c, u8 pwm); |
| 50 | if (fe->ops.write) | 51 | #else |
| 51 | r = fe->ops.write(fe, buf, 2); | 52 | static inline struct dvb_frontend* tda10023_attach(const struct tda1002x_config* config, |
| 52 | return r; | 53 | struct i2c_adapter* i2c, u8 pwm) |
| 54 | { | ||
| 55 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); | ||
| 56 | return NULL; | ||
| 53 | } | 57 | } |
| 58 | #endif // CONFIG_DVB_TDA10023 | ||
| 54 | 59 | ||
| 55 | #endif // TDA10021_H | 60 | #endif // TDA1002x_H |
diff --git a/drivers/media/dvb/frontends/tda1004x.c b/drivers/media/dvb/frontends/tda1004x.c index f4a9cf9d26d0..33a84372c9e6 100644 --- a/drivers/media/dvb/frontends/tda1004x.c +++ b/drivers/media/dvb/frontends/tda1004x.c | |||
| @@ -40,20 +40,6 @@ | |||
| 40 | #include "dvb_frontend.h" | 40 | #include "dvb_frontend.h" |
| 41 | #include "tda1004x.h" | 41 | #include "tda1004x.h" |
| 42 | 42 | ||
| 43 | enum tda1004x_demod { | ||
| 44 | TDA1004X_DEMOD_TDA10045, | ||
| 45 | TDA1004X_DEMOD_TDA10046, | ||
| 46 | }; | ||
| 47 | |||
| 48 | struct tda1004x_state { | ||
| 49 | struct i2c_adapter* i2c; | ||
| 50 | const struct tda1004x_config* config; | ||
| 51 | struct dvb_frontend frontend; | ||
| 52 | |||
| 53 | /* private demod data */ | ||
| 54 | enum tda1004x_demod demod_type; | ||
| 55 | }; | ||
| 56 | |||
| 57 | static int debug; | 43 | static int debug; |
| 58 | #define dprintk(args...) \ | 44 | #define dprintk(args...) \ |
| 59 | do { \ | 45 | do { \ |
| @@ -507,35 +493,51 @@ static int tda10046_fwupload(struct dvb_frontend* fe) | |||
| 507 | tda1004x_write_byteI(state, TDA1004X_CONFC4, 0x80); | 493 | tda1004x_write_byteI(state, TDA1004X_CONFC4, 0x80); |
| 508 | } | 494 | } |
| 509 | tda1004x_write_mask(state, TDA10046H_CONF_TRISTATE1, 1, 0); | 495 | tda1004x_write_mask(state, TDA10046H_CONF_TRISTATE1, 1, 0); |
| 496 | /* set GPIO 1 and 3 */ | ||
| 497 | if (state->config->gpio_config != TDA10046_GPTRI) { | ||
| 498 | tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE2, 0x33); | ||
| 499 | tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0x0f, state->config->gpio_config &0x0f); | ||
| 500 | } | ||
| 510 | /* let the clocks recover from sleep */ | 501 | /* let the clocks recover from sleep */ |
| 511 | msleep(5); | 502 | msleep(10); |
| 512 | 503 | ||
| 513 | /* The PLLs need to be reprogrammed after sleep */ | 504 | /* The PLLs need to be reprogrammed after sleep */ |
| 514 | tda10046_init_plls(fe); | 505 | tda10046_init_plls(fe); |
| 506 | tda1004x_write_mask(state, TDA1004X_CONFADC2, 0xc0, 0); | ||
| 515 | 507 | ||
| 516 | /* don't re-upload unless necessary */ | 508 | /* don't re-upload unless necessary */ |
| 517 | if (tda1004x_check_upload_ok(state) == 0) | 509 | if (tda1004x_check_upload_ok(state) == 0) |
| 518 | return 0; | 510 | return 0; |
| 519 | 511 | ||
| 512 | printk(KERN_INFO "tda1004x: trying to boot from eeprom\n"); | ||
| 513 | tda1004x_write_mask(state, TDA1004X_CONFC4, 4, 4); | ||
| 514 | msleep(300); | ||
| 515 | /* don't re-upload unless necessary */ | ||
| 516 | if (tda1004x_check_upload_ok(state) == 0) | ||
| 517 | return 0; | ||
| 518 | |||
| 520 | if (state->config->request_firmware != NULL) { | 519 | if (state->config->request_firmware != NULL) { |
| 521 | /* request the firmware, this will block until someone uploads it */ | 520 | /* request the firmware, this will block until someone uploads it */ |
| 522 | printk(KERN_INFO "tda1004x: waiting for firmware upload...\n"); | 521 | printk(KERN_INFO "tda1004x: waiting for firmware upload...\n"); |
| 523 | ret = state->config->request_firmware(fe, &fw, TDA10046_DEFAULT_FIRMWARE); | 522 | ret = state->config->request_firmware(fe, &fw, TDA10046_DEFAULT_FIRMWARE); |
| 524 | if (ret) { | 523 | if (ret) { |
| 525 | printk(KERN_ERR "tda1004x: no firmware upload (timeout or file not found?)\n"); | 524 | /* remain compatible to old bug: try to load with tda10045 image name */ |
| 526 | return ret; | 525 | ret = state->config->request_firmware(fe, &fw, TDA10045_DEFAULT_FIRMWARE); |
| 526 | if (ret) { | ||
| 527 | printk(KERN_ERR "tda1004x: no firmware upload (timeout or file not found?)\n"); | ||
| 528 | return ret; | ||
| 529 | } else { | ||
| 530 | printk(KERN_INFO "tda1004x: please rename the firmware file to %s\n", | ||
| 531 | TDA10046_DEFAULT_FIRMWARE); | ||
| 532 | } | ||
| 527 | } | 533 | } |
| 528 | tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 8); // going to boot from HOST | ||
| 529 | ret = tda1004x_do_upload(state, fw->data, fw->size, TDA10046H_CODE_CPT, TDA10046H_CODE_IN); | ||
| 530 | release_firmware(fw); | ||
| 531 | if (ret) | ||
| 532 | return ret; | ||
| 533 | } else { | 534 | } else { |
| 534 | /* boot from firmware eeprom */ | 535 | printk(KERN_ERR "tda1004x: no request function defined, can't upload from file\n"); |
| 535 | printk(KERN_INFO "tda1004x: booting from eeprom\n"); | 536 | return -EIO; |
| 536 | tda1004x_write_mask(state, TDA1004X_CONFC4, 4, 4); | ||
| 537 | msleep(300); | ||
| 538 | } | 537 | } |
| 538 | tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 8); // going to boot from HOST | ||
| 539 | ret = tda1004x_do_upload(state, fw->data, fw->size, TDA10046H_CODE_CPT, TDA10046H_CODE_IN); | ||
| 540 | release_firmware(fw); | ||
| 539 | return tda1004x_check_upload_ok(state); | 541 | return tda1004x_check_upload_ok(state); |
| 540 | } | 542 | } |
| 541 | 543 | ||
| @@ -638,37 +640,33 @@ static int tda10046_init(struct dvb_frontend* fe) | |||
| 638 | switch (state->config->agc_config) { | 640 | switch (state->config->agc_config) { |
| 639 | case TDA10046_AGC_DEFAULT: | 641 | case TDA10046_AGC_DEFAULT: |
| 640 | tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x00); // AGC setup | 642 | tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x00); // AGC setup |
| 641 | tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x60); // set AGC polarities | 643 | tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0xf0, 0x60); // set AGC polarities |
| 642 | break; | 644 | break; |
| 643 | case TDA10046_AGC_IFO_AUTO_NEG: | 645 | case TDA10046_AGC_IFO_AUTO_NEG: |
| 644 | tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x0a); // AGC setup | 646 | tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x0a); // AGC setup |
| 645 | tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x60); // set AGC polarities | 647 | tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0xf0, 0x60); // set AGC polarities |
| 646 | break; | 648 | break; |
| 647 | case TDA10046_AGC_IFO_AUTO_POS: | 649 | case TDA10046_AGC_IFO_AUTO_POS: |
| 648 | tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x0a); // AGC setup | 650 | tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x0a); // AGC setup |
| 649 | tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x00); // set AGC polarities | 651 | tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0xf0, 0x00); // set AGC polarities |
| 650 | break; | ||
| 651 | case TDA10046_AGC_TDA827X_GP11: | ||
| 652 | tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x02); // AGC setup | ||
| 653 | tda1004x_write_byteI(state, TDA10046H_AGC_THR, 0x70); // AGC Threshold | ||
| 654 | tda1004x_write_byteI(state, TDA10046H_AGC_RENORM, 0x08); // Gain Renormalize | ||
| 655 | tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x6a); // set AGC polarities | ||
| 656 | break; | ||
| 657 | case TDA10046_AGC_TDA827X_GP00: | ||
| 658 | tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x02); // AGC setup | ||
| 659 | tda1004x_write_byteI(state, TDA10046H_AGC_THR, 0x70); // AGC Threshold | ||
| 660 | tda1004x_write_byteI(state, TDA10046H_AGC_RENORM, 0x08); // Gain Renormalize | ||
| 661 | tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x60); // set AGC polarities | ||
| 662 | break; | 652 | break; |
| 663 | case TDA10046_AGC_TDA827X_GP01: | 653 | case TDA10046_AGC_TDA827X: |
| 664 | tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x02); // AGC setup | 654 | tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x02); // AGC setup |
| 665 | tda1004x_write_byteI(state, TDA10046H_AGC_THR, 0x70); // AGC Threshold | 655 | tda1004x_write_byteI(state, TDA10046H_AGC_THR, 0x70); // AGC Threshold |
| 666 | tda1004x_write_byteI(state, TDA10046H_AGC_RENORM, 0x08); // Gain Renormalize | 656 | tda1004x_write_byteI(state, TDA10046H_AGC_RENORM, 0x08); // Gain Renormalize |
| 667 | tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x62); // set AGC polarities | 657 | tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0xf0, 0x60); // set AGC polarities |
| 668 | break; | 658 | break; |
| 669 | } | 659 | } |
| 660 | if (state->config->ts_mode == 0) { | ||
| 661 | tda1004x_write_mask(state, TDA10046H_CONF_TRISTATE1, 0xc0, 0x40); | ||
| 662 | tda1004x_write_mask(state, 0x3a, 0x80, state->config->invert_oclk << 7); | ||
| 663 | } else { | ||
| 664 | tda1004x_write_mask(state, TDA10046H_CONF_TRISTATE1, 0xc0, 0x80); | ||
| 665 | tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0x10, | ||
| 666 | state->config->invert_oclk << 4); | ||
| 667 | } | ||
| 670 | tda1004x_write_byteI(state, TDA1004X_CONFADC2, 0x38); | 668 | tda1004x_write_byteI(state, TDA1004X_CONFADC2, 0x38); |
| 671 | tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE1, 0x61); // Turn both AGC outputs on | 669 | tda1004x_write_mask (state, TDA10046H_CONF_TRISTATE1, 0x3e, 0x38); // Turn IF AGC output on |
| 672 | tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MIN, 0); // } | 670 | tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MIN, 0); // } |
| 673 | tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MAX, 0xff); // } AGC min/max values | 671 | tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MAX, 0xff); // } AGC min/max values |
| 674 | tda1004x_write_byteI(state, TDA10046H_AGC_IF_MIN, 0); // } | 672 | tda1004x_write_byteI(state, TDA10046H_AGC_IF_MIN, 0); // } |
| @@ -678,7 +676,6 @@ static int tda10046_init(struct dvb_frontend* fe) | |||
| 678 | tda1004x_write_byteI(state, TDA1004X_CONF_TS1, 7); // MPEG2 interface config | 676 | tda1004x_write_byteI(state, TDA1004X_CONF_TS1, 7); // MPEG2 interface config |
| 679 | tda1004x_write_byteI(state, TDA1004X_CONF_TS2, 0xc0); // MPEG2 interface config | 677 | tda1004x_write_byteI(state, TDA1004X_CONF_TS2, 0xc0); // MPEG2 interface config |
| 680 | // tda1004x_write_mask(state, 0x50, 0x80, 0x80); // handle out of guard echoes | 678 | // tda1004x_write_mask(state, 0x50, 0x80, 0x80); // handle out of guard echoes |
| 681 | tda1004x_write_mask(state, 0x3a, 0x80, state->config->invert_oclk << 7); | ||
| 682 | 679 | ||
| 683 | return 0; | 680 | return 0; |
| 684 | } | 681 | } |
| @@ -705,7 +702,8 @@ static int tda1004x_set_fe(struct dvb_frontend* fe, | |||
| 705 | // set frequency | 702 | // set frequency |
| 706 | if (fe->ops.tuner_ops.set_params) { | 703 | if (fe->ops.tuner_ops.set_params) { |
| 707 | fe->ops.tuner_ops.set_params(fe, fe_params); | 704 | fe->ops.tuner_ops.set_params(fe, fe_params); |
| 708 | if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); | 705 | if (fe->ops.i2c_gate_ctrl) |
| 706 | fe->ops.i2c_gate_ctrl(fe, 0); | ||
| 709 | } | 707 | } |
| 710 | 708 | ||
| 711 | // Hardcoded to use auto as much as possible on the TDA10045 as it | 709 | // Hardcoded to use auto as much as possible on the TDA10045 as it |
| @@ -1165,6 +1163,7 @@ static int tda1004x_read_ber(struct dvb_frontend* fe, u32* ber) | |||
| 1165 | static int tda1004x_sleep(struct dvb_frontend* fe) | 1163 | static int tda1004x_sleep(struct dvb_frontend* fe) |
| 1166 | { | 1164 | { |
| 1167 | struct tda1004x_state* state = fe->demodulator_priv; | 1165 | struct tda1004x_state* state = fe->demodulator_priv; |
| 1166 | int gpio_conf; | ||
| 1168 | 1167 | ||
| 1169 | switch (state->demod_type) { | 1168 | switch (state->demod_type) { |
| 1170 | case TDA1004X_DEMOD_TDA10045: | 1169 | case TDA1004X_DEMOD_TDA10045: |
| @@ -1174,6 +1173,13 @@ static int tda1004x_sleep(struct dvb_frontend* fe) | |||
| 1174 | case TDA1004X_DEMOD_TDA10046: | 1173 | case TDA1004X_DEMOD_TDA10046: |
| 1175 | /* set outputs to tristate */ | 1174 | /* set outputs to tristate */ |
| 1176 | tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE1, 0xff); | 1175 | tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE1, 0xff); |
| 1176 | /* invert GPIO 1 and 3 if desired*/ | ||
| 1177 | gpio_conf = state->config->gpio_config; | ||
| 1178 | if (gpio_conf >= TDA10046_GP00_I) | ||
| 1179 | tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0x0f, | ||
| 1180 | (gpio_conf & 0x0f) ^ 0x0a); | ||
| 1181 | |||
| 1182 | tda1004x_write_mask(state, TDA1004X_CONFADC2, 0xc0, 0xc0); | ||
| 1177 | tda1004x_write_mask(state, TDA1004X_CONFC4, 1, 1); | 1183 | tda1004x_write_mask(state, TDA1004X_CONFC4, 1, 1); |
| 1178 | break; | 1184 | break; |
| 1179 | } | 1185 | } |
diff --git a/drivers/media/dvb/frontends/tda1004x.h b/drivers/media/dvb/frontends/tda1004x.h index ec502d71b83c..abae84350142 100644 --- a/drivers/media/dvb/frontends/tda1004x.h +++ b/drivers/media/dvb/frontends/tda1004x.h | |||
| @@ -35,9 +35,23 @@ enum tda10046_agc { | |||
| 35 | TDA10046_AGC_DEFAULT, /* original configuration */ | 35 | TDA10046_AGC_DEFAULT, /* original configuration */ |
| 36 | TDA10046_AGC_IFO_AUTO_NEG, /* IF AGC only, automatic, negtive */ | 36 | TDA10046_AGC_IFO_AUTO_NEG, /* IF AGC only, automatic, negtive */ |
| 37 | TDA10046_AGC_IFO_AUTO_POS, /* IF AGC only, automatic, positive */ | 37 | TDA10046_AGC_IFO_AUTO_POS, /* IF AGC only, automatic, positive */ |
| 38 | TDA10046_AGC_TDA827X_GP11, /* IF AGC only, special setup for tda827x */ | 38 | TDA10046_AGC_TDA827X, /* IF AGC only, special setup for tda827x */ |
| 39 | TDA10046_AGC_TDA827X_GP00, /* same as above, but GPIOs 0 */ | 39 | }; |
| 40 | TDA10046_AGC_TDA827X_GP01, /* same as above, but GPIO3=0 GPIO1=1*/ | 40 | |
| 41 | /* Many (hybrid) boards use GPIO 1 and 3 | ||
| 42 | GPIO1 analog - dvb switch | ||
| 43 | GPIO3 firmware eeprom address switch | ||
| 44 | */ | ||
| 45 | enum tda10046_gpio { | ||
| 46 | TDA10046_GPTRI = 0x00, /* All GPIOs tristate */ | ||
| 47 | TDA10046_GP00 = 0x40, /* GPIO3=0, GPIO1=0 */ | ||
| 48 | TDA10046_GP01 = 0x42, /* GPIO3=0, GPIO1=1 */ | ||
| 49 | TDA10046_GP10 = 0x48, /* GPIO3=1, GPIO1=0 */ | ||
| 50 | TDA10046_GP11 = 0x4a, /* GPIO3=1, GPIO1=1 */ | ||
| 51 | TDA10046_GP00_I = 0x80, /* GPIO3=0, GPIO1=0, invert in sleep mode*/ | ||
| 52 | TDA10046_GP01_I = 0x82, /* GPIO3=0, GPIO1=1, invert in sleep mode */ | ||
| 53 | TDA10046_GP10_I = 0x88, /* GPIO3=1, GPIO1=0, invert in sleep mode */ | ||
| 54 | TDA10046_GP11_I = 0x8a, /* GPIO3=1, GPIO1=1, invert in sleep mode */ | ||
| 41 | }; | 55 | }; |
| 42 | 56 | ||
| 43 | enum tda10046_if { | 57 | enum tda10046_if { |
| @@ -47,6 +61,11 @@ enum tda10046_if { | |||
| 47 | TDA10046_FREQ_052, /* low IF, 5.1667 MHZ for tda9889 */ | 61 | TDA10046_FREQ_052, /* low IF, 5.1667 MHZ for tda9889 */ |
| 48 | }; | 62 | }; |
| 49 | 63 | ||
| 64 | enum tda10046_tsout { | ||
| 65 | TDA10046_TS_PARALLEL = 0x00, /* parallel transport stream, default */ | ||
| 66 | TDA10046_TS_SERIAL = 0x01, /* serial transport stream */ | ||
| 67 | }; | ||
| 68 | |||
| 50 | struct tda1004x_config | 69 | struct tda1004x_config |
| 51 | { | 70 | { |
| 52 | /* the demodulator's i2c address */ | 71 | /* the demodulator's i2c address */ |
| @@ -58,6 +77,9 @@ struct tda1004x_config | |||
| 58 | /* Does the OCLK signal need inverted? */ | 77 | /* Does the OCLK signal need inverted? */ |
| 59 | u8 invert_oclk; | 78 | u8 invert_oclk; |
| 60 | 79 | ||
| 80 | /* parallel or serial transport stream */ | ||
| 81 | enum tda10046_tsout ts_mode; | ||
| 82 | |||
| 61 | /* Xtal frequency, 4 or 16MHz*/ | 83 | /* Xtal frequency, 4 or 16MHz*/ |
| 62 | enum tda10046_xtal xtal_freq; | 84 | enum tda10046_xtal xtal_freq; |
| 63 | 85 | ||
| @@ -67,11 +89,35 @@ struct tda1004x_config | |||
| 67 | /* AGC configuration */ | 89 | /* AGC configuration */ |
| 68 | enum tda10046_agc agc_config; | 90 | enum tda10046_agc agc_config; |
| 69 | 91 | ||
| 92 | /* setting of GPIO1 and 3 */ | ||
| 93 | enum tda10046_gpio gpio_config; | ||
| 94 | |||
| 95 | /* slave address and configuration of the tuner */ | ||
| 96 | u8 tuner_address; | ||
| 97 | u8 tuner_config; | ||
| 98 | u8 antenna_switch; | ||
| 99 | |||
| 100 | /* if the board uses another I2c Bridge (tda8290), its address */ | ||
| 101 | u8 i2c_gate; | ||
| 102 | |||
| 70 | /* request firmware for device */ | 103 | /* request firmware for device */ |
| 71 | /* set this to NULL if the card has a firmware EEPROM */ | ||
| 72 | int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name); | 104 | int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name); |
| 73 | }; | 105 | }; |
| 74 | 106 | ||
| 107 | enum tda1004x_demod { | ||
| 108 | TDA1004X_DEMOD_TDA10045, | ||
| 109 | TDA1004X_DEMOD_TDA10046, | ||
| 110 | }; | ||
| 111 | |||
| 112 | struct tda1004x_state { | ||
| 113 | struct i2c_adapter* i2c; | ||
| 114 | const struct tda1004x_config* config; | ||
| 115 | struct dvb_frontend frontend; | ||
| 116 | |||
| 117 | /* private demod data */ | ||
| 118 | enum tda1004x_demod demod_type; | ||
| 119 | }; | ||
| 120 | |||
| 75 | #if defined(CONFIG_DVB_TDA1004X) || (defined(CONFIG_DVB_TDA1004X_MODULE) && defined(MODULE)) | 121 | #if defined(CONFIG_DVB_TDA1004X) || (defined(CONFIG_DVB_TDA1004X_MODULE) && defined(MODULE)) |
| 76 | extern struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config, | 122 | extern struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config, |
| 77 | struct i2c_adapter* i2c); | 123 | struct i2c_adapter* i2c); |
diff --git a/drivers/media/dvb/frontends/tda827x.c b/drivers/media/dvb/frontends/tda827x.c new file mode 100644 index 000000000000..256fc4bf500b --- /dev/null +++ b/drivers/media/dvb/frontends/tda827x.c | |||
| @@ -0,0 +1,512 @@ | |||
| 1 | /* | ||
| 2 | * | ||
| 3 | * (c) 2005 Hartmut Hackmann | ||
| 4 | * (c) 2007 Michael Krufky | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License as published by | ||
| 8 | * the Free Software Foundation; either version 2 of the License, or | ||
| 9 | * (at your option) any later version. | ||
| 10 | * | ||
| 11 | * This program is distributed in the hope that it will be useful, | ||
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | * GNU General Public License for more details. | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License | ||
| 17 | * along with this program; if not, write to the Free Software | ||
| 18 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | #include <linux/module.h> | ||
| 22 | #include <linux/dvb/frontend.h> | ||
| 23 | #include <asm/types.h> | ||
| 24 | |||
| 25 | #include "tda827x.h" | ||
| 26 | |||
| 27 | static int debug = 0; | ||
| 28 | #define dprintk(args...) \ | ||
| 29 | do { \ | ||
| 30 | if (debug) printk(KERN_DEBUG "tda827x: " args); \ | ||
| 31 | } while (0) | ||
| 32 | |||
| 33 | struct tda827x_priv { | ||
| 34 | int i2c_addr; | ||
| 35 | struct i2c_adapter *i2c_adap; | ||
| 36 | struct tda827x_config *cfg; | ||
| 37 | u32 frequency; | ||
| 38 | u32 bandwidth; | ||
| 39 | }; | ||
| 40 | |||
| 41 | struct tda827x_data { | ||
| 42 | u32 lomax; | ||
| 43 | u8 spd; | ||
| 44 | u8 bs; | ||
| 45 | u8 bp; | ||
| 46 | u8 cp; | ||
| 47 | u8 gc3; | ||
| 48 | u8 div1p5; | ||
| 49 | }; | ||
| 50 | |||
| 51 | static const struct tda827x_data tda827x_dvbt[] = { | ||
| 52 | { .lomax = 62000000, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 1}, | ||
| 53 | { .lomax = 66000000, .spd = 3, .bs = 3, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 1}, | ||
| 54 | { .lomax = 76000000, .spd = 3, .bs = 1, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 0}, | ||
| 55 | { .lomax = 84000000, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 0}, | ||
| 56 | { .lomax = 93000000, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 1, .div1p5 = 0}, | ||
| 57 | { .lomax = 98000000, .spd = 3, .bs = 3, .bp = 0, .cp = 0, .gc3 = 1, .div1p5 = 0}, | ||
| 58 | { .lomax = 109000000, .spd = 3, .bs = 3, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0}, | ||
| 59 | { .lomax = 123000000, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 1}, | ||
| 60 | { .lomax = 133000000, .spd = 2, .bs = 3, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 1}, | ||
| 61 | { .lomax = 151000000, .spd = 2, .bs = 1, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0}, | ||
| 62 | { .lomax = 154000000, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0}, | ||
| 63 | { .lomax = 181000000, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 0, .div1p5 = 0}, | ||
| 64 | { .lomax = 185000000, .spd = 2, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0}, | ||
| 65 | { .lomax = 217000000, .spd = 2, .bs = 3, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0}, | ||
| 66 | { .lomax = 244000000, .spd = 1, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 1}, | ||
| 67 | { .lomax = 265000000, .spd = 1, .bs = 3, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 1}, | ||
| 68 | { .lomax = 302000000, .spd = 1, .bs = 1, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0}, | ||
| 69 | { .lomax = 324000000, .spd = 1, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0}, | ||
| 70 | { .lomax = 370000000, .spd = 1, .bs = 2, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0}, | ||
| 71 | { .lomax = 454000000, .spd = 1, .bs = 3, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0}, | ||
| 72 | { .lomax = 493000000, .spd = 0, .bs = 2, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 1}, | ||
| 73 | { .lomax = 530000000, .spd = 0, .bs = 3, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 1}, | ||
| 74 | { .lomax = 554000000, .spd = 0, .bs = 1, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0}, | ||
| 75 | { .lomax = 604000000, .spd = 0, .bs = 1, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0}, | ||
| 76 | { .lomax = 696000000, .spd = 0, .bs = 2, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0}, | ||
| 77 | { .lomax = 740000000, .spd = 0, .bs = 2, .bp = 4, .cp = 1, .gc3 = 0, .div1p5 = 0}, | ||
| 78 | { .lomax = 820000000, .spd = 0, .bs = 3, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0}, | ||
| 79 | { .lomax = 865000000, .spd = 0, .bs = 3, .bp = 4, .cp = 1, .gc3 = 0, .div1p5 = 0}, | ||
| 80 | { .lomax = 0, .spd = 0, .bs = 0, .bp = 0, .cp = 0, .gc3 = 0, .div1p5 = 0} | ||
| 81 | }; | ||
| 82 | |||
| 83 | static int tda827xo_set_params(struct dvb_frontend *fe, | ||
| 84 | struct dvb_frontend_parameters *params) | ||
| 85 | { | ||
| 86 | struct tda827x_priv *priv = fe->tuner_priv; | ||
| 87 | u8 buf[14]; | ||
| 88 | |||
| 89 | struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0, | ||
| 90 | .buf = buf, .len = sizeof(buf) }; | ||
| 91 | int i, tuner_freq, if_freq; | ||
| 92 | u32 N; | ||
| 93 | |||
| 94 | dprintk("%s:\n", __FUNCTION__); | ||
| 95 | switch (params->u.ofdm.bandwidth) { | ||
| 96 | case BANDWIDTH_6_MHZ: | ||
| 97 | if_freq = 4000000; | ||
| 98 | break; | ||
| 99 | case BANDWIDTH_7_MHZ: | ||
| 100 | if_freq = 4500000; | ||
| 101 | break; | ||
| 102 | default: /* 8 MHz or Auto */ | ||
| 103 | if_freq = 5000000; | ||
| 104 | break; | ||
| 105 | } | ||
| 106 | tuner_freq = params->frequency + if_freq; | ||
| 107 | |||
| 108 | i = 0; | ||
| 109 | while (tda827x_dvbt[i].lomax < tuner_freq) { | ||
| 110 | if(tda827x_dvbt[i + 1].lomax == 0) | ||
| 111 | break; | ||
| 112 | i++; | ||
| 113 | } | ||
| 114 | |||
| 115 | N = ((tuner_freq + 125000) / 250000) << (tda827x_dvbt[i].spd + 2); | ||
| 116 | buf[0] = 0; | ||
| 117 | buf[1] = (N>>8) | 0x40; | ||
| 118 | buf[2] = N & 0xff; | ||
| 119 | buf[3] = 0; | ||
| 120 | buf[4] = 0x52; | ||
| 121 | buf[5] = (tda827x_dvbt[i].spd << 6) + (tda827x_dvbt[i].div1p5 << 5) + | ||
| 122 | (tda827x_dvbt[i].bs << 3) + tda827x_dvbt[i].bp; | ||
| 123 | buf[6] = (tda827x_dvbt[i].gc3 << 4) + 0x8f; | ||
| 124 | buf[7] = 0xbf; | ||
| 125 | buf[8] = 0x2a; | ||
| 126 | buf[9] = 0x05; | ||
| 127 | buf[10] = 0xff; | ||
| 128 | buf[11] = 0x00; | ||
| 129 | buf[12] = 0x00; | ||
| 130 | buf[13] = 0x40; | ||
| 131 | |||
| 132 | msg.len = 14; | ||
| 133 | if (fe->ops.i2c_gate_ctrl) | ||
| 134 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
| 135 | if (i2c_transfer(priv->i2c_adap, &msg, 1) != 1) { | ||
| 136 | printk("%s: could not write to tuner at addr: 0x%02x\n", | ||
| 137 | __FUNCTION__, priv->i2c_addr << 1); | ||
| 138 | return -EIO; | ||
| 139 | } | ||
| 140 | msleep(500); | ||
| 141 | /* correct CP value */ | ||
| 142 | buf[0] = 0x30; | ||
| 143 | buf[1] = 0x50 + tda827x_dvbt[i].cp; | ||
| 144 | msg.len = 2; | ||
| 145 | |||
| 146 | if (fe->ops.i2c_gate_ctrl) | ||
| 147 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
| 148 | i2c_transfer(priv->i2c_adap, &msg, 1); | ||
| 149 | |||
| 150 | priv->frequency = tuner_freq - if_freq; // FIXME | ||
| 151 | priv->bandwidth = (fe->ops.info.type == FE_OFDM) ? params->u.ofdm.bandwidth : 0; | ||
| 152 | |||
| 153 | return 0; | ||
| 154 | } | ||
| 155 | |||
| 156 | static int tda827xo_sleep(struct dvb_frontend *fe) | ||
| 157 | { | ||
| 158 | struct tda827x_priv *priv = fe->tuner_priv; | ||
| 159 | static u8 buf[] = { 0x30, 0xd0 }; | ||
| 160 | struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0, | ||
| 161 | .buf = buf, .len = sizeof(buf) }; | ||
| 162 | |||
| 163 | dprintk("%s:\n", __FUNCTION__); | ||
| 164 | if (fe->ops.i2c_gate_ctrl) | ||
| 165 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
| 166 | i2c_transfer(priv->i2c_adap, &msg, 1); | ||
| 167 | |||
| 168 | if (priv->cfg && priv->cfg->sleep) | ||
| 169 | priv->cfg->sleep(fe); | ||
| 170 | |||
| 171 | return 0; | ||
| 172 | } | ||
| 173 | |||
| 174 | /* ------------------------------------------------------------------ */ | ||
| 175 | |||
| 176 | struct tda827xa_data { | ||
| 177 | u32 lomax; | ||
| 178 | u8 svco; | ||
| 179 | u8 spd; | ||
| 180 | u8 scr; | ||
| 181 | u8 sbs; | ||
| 182 | u8 gc3; | ||
| 183 | }; | ||
| 184 | |||
| 185 | static const struct tda827xa_data tda827xa_dvbt[] = { | ||
| 186 | { .lomax = 56875000, .svco = 3, .spd = 4, .scr = 0, .sbs = 0, .gc3 = 1}, | ||
| 187 | { .lomax = 67250000, .svco = 0, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1}, | ||
| 188 | { .lomax = 81250000, .svco = 1, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1}, | ||
| 189 | { .lomax = 97500000, .svco = 2, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1}, | ||
| 190 | { .lomax = 113750000, .svco = 3, .spd = 3, .scr = 0, .sbs = 1, .gc3 = 1}, | ||
| 191 | { .lomax = 134500000, .svco = 0, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1}, | ||
| 192 | { .lomax = 154000000, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1}, | ||
| 193 | { .lomax = 162500000, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1}, | ||
| 194 | { .lomax = 183000000, .svco = 2, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1}, | ||
| 195 | { .lomax = 195000000, .svco = 2, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 1}, | ||
| 196 | { .lomax = 227500000, .svco = 3, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 1}, | ||
| 197 | { .lomax = 269000000, .svco = 0, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 1}, | ||
| 198 | { .lomax = 290000000, .svco = 1, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 1}, | ||
| 199 | { .lomax = 325000000, .svco = 1, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 1}, | ||
| 200 | { .lomax = 390000000, .svco = 2, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 1}, | ||
| 201 | { .lomax = 455000000, .svco = 3, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 1}, | ||
| 202 | { .lomax = 520000000, .svco = 0, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1}, | ||
| 203 | { .lomax = 538000000, .svco = 0, .spd = 0, .scr = 1, .sbs = 3, .gc3 = 1}, | ||
| 204 | { .lomax = 550000000, .svco = 1, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1}, | ||
| 205 | { .lomax = 620000000, .svco = 1, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0}, | ||
| 206 | { .lomax = 650000000, .svco = 1, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0}, | ||
| 207 | { .lomax = 700000000, .svco = 2, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0}, | ||
| 208 | { .lomax = 780000000, .svco = 2, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0}, | ||
| 209 | { .lomax = 820000000, .svco = 3, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0}, | ||
| 210 | { .lomax = 870000000, .svco = 3, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0}, | ||
| 211 | { .lomax = 911000000, .svco = 3, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 0}, | ||
| 212 | { .lomax = 0, .svco = 0, .spd = 0, .scr = 0, .sbs = 0, .gc3 = 0} | ||
| 213 | }; | ||
| 214 | |||
| 215 | static int tda827xa_set_params(struct dvb_frontend *fe, | ||
| 216 | struct dvb_frontend_parameters *params) | ||
| 217 | { | ||
| 218 | struct tda827x_priv *priv = fe->tuner_priv; | ||
| 219 | u8 buf[11]; | ||
| 220 | |||
| 221 | struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0, | ||
| 222 | .buf = buf, .len = sizeof(buf) }; | ||
| 223 | |||
| 224 | int i, tuner_freq, if_freq; | ||
| 225 | u32 N; | ||
| 226 | |||
| 227 | dprintk("%s:\n", __FUNCTION__); | ||
| 228 | if (priv->cfg && priv->cfg->lna_gain) | ||
| 229 | priv->cfg->lna_gain(fe, 1); | ||
| 230 | msleep(20); | ||
| 231 | |||
| 232 | switch (params->u.ofdm.bandwidth) { | ||
| 233 | case BANDWIDTH_6_MHZ: | ||
| 234 | if_freq = 4000000; | ||
| 235 | break; | ||
| 236 | case BANDWIDTH_7_MHZ: | ||
| 237 | if_freq = 4500000; | ||
| 238 | break; | ||
| 239 | default: /* 8 MHz or Auto */ | ||
| 240 | if_freq = 5000000; | ||
| 241 | break; | ||
| 242 | } | ||
| 243 | tuner_freq = params->frequency + if_freq; | ||
| 244 | |||
| 245 | i = 0; | ||
| 246 | while (tda827xa_dvbt[i].lomax < tuner_freq) { | ||
| 247 | if(tda827xa_dvbt[i + 1].lomax == 0) | ||
| 248 | break; | ||
| 249 | i++; | ||
| 250 | } | ||
| 251 | |||
| 252 | N = ((tuner_freq + 31250) / 62500) << tda827xa_dvbt[i].spd; | ||
| 253 | buf[0] = 0; // subaddress | ||
| 254 | buf[1] = N >> 8; | ||
| 255 | buf[2] = N & 0xff; | ||
| 256 | buf[3] = 0; | ||
| 257 | buf[4] = 0x16; | ||
| 258 | buf[5] = (tda827xa_dvbt[i].spd << 5) + (tda827xa_dvbt[i].svco << 3) + | ||
| 259 | tda827xa_dvbt[i].sbs; | ||
| 260 | buf[6] = 0x4b + (tda827xa_dvbt[i].gc3 << 4); | ||
| 261 | buf[7] = 0x1c; | ||
| 262 | buf[8] = 0x06; | ||
| 263 | buf[9] = 0x24; | ||
| 264 | buf[10] = 0x00; | ||
| 265 | msg.len = 11; | ||
| 266 | if (fe->ops.i2c_gate_ctrl) | ||
| 267 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
| 268 | if (i2c_transfer(priv->i2c_adap, &msg, 1) != 1) { | ||
| 269 | printk("%s: could not write to tuner at addr: 0x%02x\n", | ||
| 270 | __FUNCTION__, priv->i2c_addr << 1); | ||
| 271 | return -EIO; | ||
| 272 | } | ||
| 273 | buf[0] = 0x90; | ||
| 274 | buf[1] = 0xff; | ||
| 275 | buf[2] = 0x60; | ||
| 276 | buf[3] = 0x00; | ||
| 277 | buf[4] = 0x59; // lpsel, for 6MHz + 2 | ||
| 278 | msg.len = 5; | ||
| 279 | if (fe->ops.i2c_gate_ctrl) | ||
| 280 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
| 281 | i2c_transfer(priv->i2c_adap, &msg, 1); | ||
| 282 | |||
| 283 | buf[0] = 0xa0; | ||
| 284 | buf[1] = 0x40; | ||
| 285 | msg.len = 2; | ||
| 286 | if (fe->ops.i2c_gate_ctrl) | ||
| 287 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
| 288 | i2c_transfer(priv->i2c_adap, &msg, 1); | ||
| 289 | |||
| 290 | msleep(11); | ||
| 291 | msg.flags = I2C_M_RD; | ||
| 292 | if (fe->ops.i2c_gate_ctrl) | ||
| 293 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
| 294 | i2c_transfer(priv->i2c_adap, &msg, 1); | ||
| 295 | msg.flags = 0; | ||
| 296 | |||
| 297 | buf[1] >>= 4; | ||
| 298 | dprintk("tda8275a AGC2 gain is: %d\n", buf[1]); | ||
| 299 | if ((buf[1]) < 2) { | ||
| 300 | if (priv->cfg && priv->cfg->lna_gain) | ||
| 301 | priv->cfg->lna_gain(fe, 0); | ||
| 302 | buf[0] = 0x60; | ||
| 303 | buf[1] = 0x0c; | ||
| 304 | if (fe->ops.i2c_gate_ctrl) | ||
| 305 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
| 306 | i2c_transfer(priv->i2c_adap, &msg, 1); | ||
| 307 | } | ||
| 308 | |||
| 309 | buf[0] = 0xc0; | ||
| 310 | buf[1] = 0x99; // lpsel, for 6MHz + 2 | ||
| 311 | if (fe->ops.i2c_gate_ctrl) | ||
| 312 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
| 313 | i2c_transfer(priv->i2c_adap, &msg, 1); | ||
| 314 | |||
| 315 | buf[0] = 0x60; | ||
| 316 | buf[1] = 0x3c; | ||
| 317 | if (fe->ops.i2c_gate_ctrl) | ||
| 318 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
| 319 | i2c_transfer(priv->i2c_adap, &msg, 1); | ||
| 320 | |||
| 321 | /* correct CP value */ | ||
| 322 | buf[0] = 0x30; | ||
| 323 | buf[1] = 0x10 + tda827xa_dvbt[i].scr; | ||
| 324 | if (fe->ops.i2c_gate_ctrl) | ||
| 325 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
| 326 | i2c_transfer(priv->i2c_adap, &msg, 1); | ||
| 327 | |||
| 328 | msleep(163); | ||
| 329 | buf[0] = 0xc0; | ||
| 330 | buf[1] = 0x39; // lpsel, for 6MHz + 2 | ||
| 331 | if (fe->ops.i2c_gate_ctrl) | ||
| 332 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
| 333 | i2c_transfer(priv->i2c_adap, &msg, 1); | ||
| 334 | |||
| 335 | msleep(3); | ||
| 336 | /* freeze AGC1 */ | ||
| 337 | buf[0] = 0x50; | ||
| 338 | buf[1] = 0x4f + (tda827xa_dvbt[i].gc3 << 4); | ||
| 339 | if (fe->ops.i2c_gate_ctrl) | ||
| 340 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
| 341 | i2c_transfer(priv->i2c_adap, &msg, 1); | ||
| 342 | |||
| 343 | priv->frequency = tuner_freq - if_freq; // FIXME | ||
| 344 | priv->bandwidth = (fe->ops.info.type == FE_OFDM) ? params->u.ofdm.bandwidth : 0; | ||
| 345 | |||
| 346 | return 0; | ||
| 347 | } | ||
| 348 | |||
| 349 | static int tda827xa_sleep(struct dvb_frontend *fe) | ||
| 350 | { | ||
| 351 | struct tda827x_priv *priv = fe->tuner_priv; | ||
| 352 | static u8 buf[] = { 0x30, 0x90 }; | ||
| 353 | struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0, | ||
| 354 | .buf = buf, .len = sizeof(buf) }; | ||
| 355 | |||
| 356 | dprintk("%s:\n", __FUNCTION__); | ||
| 357 | if (fe->ops.i2c_gate_ctrl) | ||
| 358 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
| 359 | |||
| 360 | i2c_transfer(priv->i2c_adap, &msg, 1); | ||
| 361 | |||
| 362 | if (fe->ops.i2c_gate_ctrl) | ||
| 363 | fe->ops.i2c_gate_ctrl(fe, 0); | ||
| 364 | |||
| 365 | if (priv->cfg && priv->cfg->sleep) | ||
| 366 | priv->cfg->sleep(fe); | ||
| 367 | |||
| 368 | return 0; | ||
| 369 | } | ||
| 370 | |||
| 371 | static int tda827x_release(struct dvb_frontend *fe) | ||
| 372 | { | ||
| 373 | kfree(fe->tuner_priv); | ||
| 374 | fe->tuner_priv = NULL; | ||
| 375 | return 0; | ||
| 376 | } | ||
| 377 | |||
| 378 | static int tda827x_get_frequency(struct dvb_frontend *fe, u32 *frequency) | ||
| 379 | { | ||
| 380 | struct tda827x_priv *priv = fe->tuner_priv; | ||
| 381 | *frequency = priv->frequency; | ||
| 382 | return 0; | ||
| 383 | } | ||
| 384 | |||
| 385 | static int tda827x_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth) | ||
| 386 | { | ||
| 387 | struct tda827x_priv *priv = fe->tuner_priv; | ||
| 388 | *bandwidth = priv->bandwidth; | ||
| 389 | return 0; | ||
| 390 | } | ||
| 391 | |||
| 392 | static int tda827x_init(struct dvb_frontend *fe) | ||
| 393 | { | ||
| 394 | struct tda827x_priv *priv = fe->tuner_priv; | ||
| 395 | dprintk("%s:\n", __FUNCTION__); | ||
| 396 | if (priv->cfg && priv->cfg->init) | ||
| 397 | priv->cfg->init(fe); | ||
| 398 | |||
| 399 | return 0; | ||
| 400 | } | ||
| 401 | |||
| 402 | static int tda827x_probe_version(struct dvb_frontend *fe); | ||
| 403 | |||
| 404 | static int tda827x_initial_init(struct dvb_frontend *fe) | ||
| 405 | { | ||
| 406 | int ret; | ||
| 407 | ret = tda827x_probe_version(fe); | ||
| 408 | if (ret) | ||
| 409 | return ret; | ||
| 410 | return fe->ops.tuner_ops.init(fe); | ||
| 411 | } | ||
| 412 | |||
| 413 | static int tda827x_initial_sleep(struct dvb_frontend *fe) | ||
| 414 | { | ||
| 415 | int ret; | ||
| 416 | ret = tda827x_probe_version(fe); | ||
| 417 | if (ret) | ||
| 418 | return ret; | ||
| 419 | return fe->ops.tuner_ops.sleep(fe); | ||
| 420 | } | ||
| 421 | |||
| 422 | static struct dvb_tuner_ops tda827xo_tuner_ops = { | ||
| 423 | .info = { | ||
| 424 | .name = "Philips TDA827X", | ||
| 425 | .frequency_min = 55000000, | ||
| 426 | .frequency_max = 860000000, | ||
| 427 | .frequency_step = 250000 | ||
| 428 | }, | ||
| 429 | .release = tda827x_release, | ||
| 430 | .init = tda827x_initial_init, | ||
| 431 | .sleep = tda827x_initial_sleep, | ||
| 432 | .set_params = tda827xo_set_params, | ||
| 433 | .get_frequency = tda827x_get_frequency, | ||
| 434 | .get_bandwidth = tda827x_get_bandwidth, | ||
| 435 | }; | ||
| 436 | |||
| 437 | static struct dvb_tuner_ops tda827xa_tuner_ops = { | ||
| 438 | .info = { | ||
| 439 | .name = "Philips TDA827XA", | ||
| 440 | .frequency_min = 44000000, | ||
| 441 | .frequency_max = 906000000, | ||
| 442 | .frequency_step = 62500 | ||
| 443 | }, | ||
| 444 | .release = tda827x_release, | ||
| 445 | .init = tda827x_init, | ||
| 446 | .sleep = tda827xa_sleep, | ||
| 447 | .set_params = tda827xa_set_params, | ||
| 448 | .get_frequency = tda827x_get_frequency, | ||
| 449 | .get_bandwidth = tda827x_get_bandwidth, | ||
| 450 | }; | ||
| 451 | |||
| 452 | static int tda827x_probe_version(struct dvb_frontend *fe) | ||
| 453 | { u8 data; | ||
| 454 | struct tda827x_priv *priv = fe->tuner_priv; | ||
| 455 | struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = I2C_M_RD, | ||
| 456 | .buf = &data, .len = 1 }; | ||
| 457 | if (fe->ops.i2c_gate_ctrl) | ||
| 458 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
| 459 | if (i2c_transfer(priv->i2c_adap, &msg, 1) != 1) { | ||
| 460 | printk("%s: could not read from tuner at addr: 0x%02x\n", | ||
| 461 | __FUNCTION__, msg.addr << 1); | ||
| 462 | return -EIO; | ||
| 463 | } | ||
| 464 | if ((data & 0x3c) == 0) { | ||
| 465 | dprintk("tda827x tuner found\n"); | ||
| 466 | fe->ops.tuner_ops.init = tda827x_init; | ||
| 467 | fe->ops.tuner_ops.sleep = tda827xo_sleep; | ||
| 468 | } else { | ||
| 469 | dprintk("tda827xa tuner found\n"); | ||
| 470 | memcpy(&fe->ops.tuner_ops, &tda827xa_tuner_ops, sizeof(struct dvb_tuner_ops)); | ||
| 471 | } | ||
| 472 | return 0; | ||
| 473 | } | ||
| 474 | |||
| 475 | struct dvb_frontend *tda827x_attach(struct dvb_frontend *fe, int addr, | ||
| 476 | struct i2c_adapter *i2c, | ||
| 477 | struct tda827x_config *cfg) | ||
| 478 | { | ||
| 479 | struct tda827x_priv *priv = NULL; | ||
| 480 | |||
| 481 | dprintk("%s:\n", __FUNCTION__); | ||
| 482 | priv = kzalloc(sizeof(struct tda827x_priv), GFP_KERNEL); | ||
| 483 | if (priv == NULL) | ||
| 484 | return NULL; | ||
| 485 | |||
| 486 | priv->i2c_addr = addr; | ||
| 487 | priv->i2c_adap = i2c; | ||
| 488 | priv->cfg = cfg; | ||
| 489 | memcpy(&fe->ops.tuner_ops, &tda827xo_tuner_ops, sizeof(struct dvb_tuner_ops)); | ||
| 490 | |||
| 491 | fe->tuner_priv = priv; | ||
| 492 | |||
| 493 | return fe; | ||
| 494 | } | ||
| 495 | |||
| 496 | EXPORT_SYMBOL(tda827x_attach); | ||
| 497 | |||
| 498 | module_param(debug, int, 0644); | ||
| 499 | MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); | ||
| 500 | |||
| 501 | MODULE_DESCRIPTION("DVB TDA827x driver"); | ||
| 502 | MODULE_AUTHOR("Hartmut Hackmann <hartmut.hackmann@t-online.de>"); | ||
| 503 | MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>"); | ||
| 504 | MODULE_LICENSE("GPL"); | ||
| 505 | |||
| 506 | /* | ||
| 507 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
| 508 | * --------------------------------------------------------------------------- | ||
| 509 | * Local variables: | ||
| 510 | * c-basic-offset: 8 | ||
| 511 | * End: | ||
| 512 | */ | ||
diff --git a/drivers/media/dvb/frontends/tda827x.h b/drivers/media/dvb/frontends/tda827x.h new file mode 100644 index 000000000000..69e8263d6d59 --- /dev/null +++ b/drivers/media/dvb/frontends/tda827x.h | |||
| @@ -0,0 +1,62 @@ | |||
| 1 | /* | ||
| 2 | DVB Driver for Philips tda827x / tda827xa Silicon tuners | ||
| 3 | |||
| 4 | (c) 2005 Hartmut Hackmann | ||
| 5 | (c) 2007 Michael Krufky | ||
| 6 | |||
| 7 | This program is free software; you can redistribute it and/or modify | ||
| 8 | it under the terms of the GNU General Public License as published by | ||
| 9 | the Free Software Foundation; either version 2 of the License, or | ||
| 10 | (at your option) any later version. | ||
| 11 | |||
| 12 | This program is distributed in the hope that it will be useful, | ||
| 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | |||
| 16 | GNU General Public License for more details. | ||
| 17 | |||
| 18 | You should have received a copy of the GNU General Public License | ||
| 19 | along with this program; if not, write to the Free Software | ||
| 20 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 21 | |||
| 22 | */ | ||
| 23 | |||
| 24 | #ifndef __DVB_TDA827X_H__ | ||
| 25 | #define __DVB_TDA827X_H__ | ||
| 26 | |||
| 27 | #include <linux/i2c.h> | ||
| 28 | #include "dvb_frontend.h" | ||
| 29 | |||
| 30 | struct tda827x_config | ||
| 31 | { | ||
| 32 | void (*lna_gain) (struct dvb_frontend *fe, int high); | ||
| 33 | int (*init) (struct dvb_frontend *fe); | ||
| 34 | int (*sleep) (struct dvb_frontend *fe); | ||
| 35 | }; | ||
| 36 | |||
| 37 | |||
| 38 | /** | ||
| 39 | * Attach a tda827x tuner to the supplied frontend structure. | ||
| 40 | * | ||
| 41 | * @param fe Frontend to attach to. | ||
| 42 | * @param addr i2c address of the tuner. | ||
| 43 | * @param i2c i2c adapter to use. | ||
| 44 | * @param cfg optional callback function pointers. | ||
| 45 | * @return FE pointer on success, NULL on failure. | ||
| 46 | */ | ||
| 47 | #if defined(CONFIG_DVB_TDA827X) || (defined(CONFIG_DVB_TDA827X_MODULE) && defined(MODULE)) | ||
| 48 | extern struct dvb_frontend* tda827x_attach(struct dvb_frontend *fe, int addr, | ||
| 49 | struct i2c_adapter *i2c, | ||
| 50 | struct tda827x_config *cfg); | ||
| 51 | #else | ||
| 52 | static inline struct dvb_frontend* tda827x_attach(struct dvb_frontend *fe, | ||
| 53 | int addr, | ||
| 54 | struct i2c_adapter *i2c, | ||
| 55 | struct tda827x_config *cfg) | ||
| 56 | { | ||
| 57 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); | ||
| 58 | return NULL; | ||
| 59 | } | ||
| 60 | #endif // CONFIG_DVB_TDA827X | ||
| 61 | |||
| 62 | #endif // __DVB_TDA827X_H__ | ||
