diff options
Diffstat (limited to 'drivers/media/dvb/frontends/cx24110.c')
-rw-r--r-- | drivers/media/dvb/frontends/cx24110.c | 312 |
1 files changed, 156 insertions, 156 deletions
diff --git a/drivers/media/dvb/frontends/cx24110.c b/drivers/media/dvb/frontends/cx24110.c index 654d7dc879d9..0c4db80ec332 100644 --- a/drivers/media/dvb/frontends/cx24110.c +++ b/drivers/media/dvb/frontends/cx24110.c | |||
@@ -55,81 +55,81 @@ static int debug; | |||
55 | } while (0) | 55 | } while (0) |
56 | 56 | ||
57 | static struct {u8 reg; u8 data;} cx24110_regdata[]= | 57 | static struct {u8 reg; u8 data;} cx24110_regdata[]= |
58 | /* Comments beginning with @ denote this value should | 58 | /* Comments beginning with @ denote this value should |
59 | be the default */ | 59 | be the default */ |
60 | {{0x09,0x01}, /* SoftResetAll */ | 60 | {{0x09,0x01}, /* SoftResetAll */ |
61 | {0x09,0x00}, /* release reset */ | 61 | {0x09,0x00}, /* release reset */ |
62 | {0x01,0xe8}, /* MSB of code rate 27.5MS/s */ | 62 | {0x01,0xe8}, /* MSB of code rate 27.5MS/s */ |
63 | {0x02,0x17}, /* middle byte " */ | 63 | {0x02,0x17}, /* middle byte " */ |
64 | {0x03,0x29}, /* LSB " */ | 64 | {0x03,0x29}, /* LSB " */ |
65 | {0x05,0x03}, /* @ DVB mode, standard code rate 3/4 */ | 65 | {0x05,0x03}, /* @ DVB mode, standard code rate 3/4 */ |
66 | {0x06,0xa5}, /* @ PLL 60MHz */ | 66 | {0x06,0xa5}, /* @ PLL 60MHz */ |
67 | {0x07,0x01}, /* @ Fclk, i.e. sampling clock, 60MHz */ | 67 | {0x07,0x01}, /* @ Fclk, i.e. sampling clock, 60MHz */ |
68 | {0x0a,0x00}, /* @ partial chip disables, do not set */ | 68 | {0x0a,0x00}, /* @ partial chip disables, do not set */ |
69 | {0x0b,0x01}, /* set output clock in gapped mode, start signal low | 69 | {0x0b,0x01}, /* set output clock in gapped mode, start signal low |
70 | active for first byte */ | 70 | active for first byte */ |
71 | {0x0c,0x11}, /* no parity bytes, large hold time, serial data out */ | 71 | {0x0c,0x11}, /* no parity bytes, large hold time, serial data out */ |
72 | {0x0d,0x6f}, /* @ RS Sync/Unsync thresholds */ | 72 | {0x0d,0x6f}, /* @ RS Sync/Unsync thresholds */ |
73 | {0x10,0x40}, /* chip doc is misleading here: write bit 6 as 1 | 73 | {0x10,0x40}, /* chip doc is misleading here: write bit 6 as 1 |
74 | to avoid starting the BER counter. Reset the | 74 | to avoid starting the BER counter. Reset the |
75 | CRC test bit. Finite counting selected */ | 75 | CRC test bit. Finite counting selected */ |
76 | {0x15,0xff}, /* @ size of the limited time window for RS BER | 76 | {0x15,0xff}, /* @ size of the limited time window for RS BER |
77 | estimation. It is <value>*256 RS blocks, this | 77 | estimation. It is <value>*256 RS blocks, this |
78 | gives approx. 2.6 sec at 27.5MS/s, rate 3/4 */ | 78 | gives approx. 2.6 sec at 27.5MS/s, rate 3/4 */ |
79 | {0x16,0x00}, /* @ enable all RS output ports */ | 79 | {0x16,0x00}, /* @ enable all RS output ports */ |
80 | {0x17,0x04}, /* @ time window allowed for the RS to sync */ | 80 | {0x17,0x04}, /* @ time window allowed for the RS to sync */ |
81 | {0x18,0xae}, /* @ allow all standard DVB code rates to be scanned | 81 | {0x18,0xae}, /* @ allow all standard DVB code rates to be scanned |
82 | for automatically */ | 82 | for automatically */ |
83 | /* leave the current code rate and normalization | 83 | /* leave the current code rate and normalization |
84 | registers as they are after reset... */ | 84 | registers as they are after reset... */ |
85 | {0x21,0x10}, /* @ during AutoAcq, search each viterbi setting | 85 | {0x21,0x10}, /* @ during AutoAcq, search each viterbi setting |
86 | only once */ | 86 | only once */ |
87 | {0x23,0x18}, /* @ size of the limited time window for Viterbi BER | 87 | {0x23,0x18}, /* @ size of the limited time window for Viterbi BER |
88 | estimation. It is <value>*65536 channel bits, i.e. | 88 | estimation. It is <value>*65536 channel bits, i.e. |
89 | approx. 38ms at 27.5MS/s, rate 3/4 */ | 89 | approx. 38ms at 27.5MS/s, rate 3/4 */ |
90 | {0x24,0x24}, /* do not trigger Viterbi CRC test. Finite count window */ | 90 | {0x24,0x24}, /* do not trigger Viterbi CRC test. Finite count window */ |
91 | /* leave front-end AGC parameters at default values */ | 91 | /* leave front-end AGC parameters at default values */ |
92 | /* leave decimation AGC parameters at default values */ | 92 | /* leave decimation AGC parameters at default values */ |
93 | {0x35,0x40}, /* disable all interrupts. They are not connected anyway */ | 93 | {0x35,0x40}, /* disable all interrupts. They are not connected anyway */ |
94 | {0x36,0xff}, /* clear all interrupt pending flags */ | 94 | {0x36,0xff}, /* clear all interrupt pending flags */ |
95 | {0x37,0x00}, /* @ fully enable AutoAcqq state machine */ | 95 | {0x37,0x00}, /* @ fully enable AutoAcqq state machine */ |
96 | {0x38,0x07}, /* @ enable fade recovery, but not autostart AutoAcq */ | 96 | {0x38,0x07}, /* @ enable fade recovery, but not autostart AutoAcq */ |
97 | /* leave the equalizer parameters on their default values */ | 97 | /* leave the equalizer parameters on their default values */ |
98 | /* leave the final AGC parameters on their default values */ | 98 | /* leave the final AGC parameters on their default values */ |
99 | {0x41,0x00}, /* @ MSB of front-end derotator frequency */ | 99 | {0x41,0x00}, /* @ MSB of front-end derotator frequency */ |
100 | {0x42,0x00}, /* @ middle bytes " */ | 100 | {0x42,0x00}, /* @ middle bytes " */ |
101 | {0x43,0x00}, /* @ LSB " */ | 101 | {0x43,0x00}, /* @ LSB " */ |
102 | /* leave the carrier tracking loop parameters on default */ | 102 | /* leave the carrier tracking loop parameters on default */ |
103 | /* leave the bit timing loop parameters at gefault */ | 103 | /* leave the bit timing loop parameters at gefault */ |
104 | {0x56,0x4d}, /* set the filtune voltage to 2.7V, as recommended by */ | 104 | {0x56,0x4d}, /* set the filtune voltage to 2.7V, as recommended by */ |
105 | /* the cx24108 data sheet for symbol rates above 15MS/s */ | 105 | /* the cx24108 data sheet for symbol rates above 15MS/s */ |
106 | {0x57,0x00}, /* @ Filter sigma delta enabled, positive */ | 106 | {0x57,0x00}, /* @ Filter sigma delta enabled, positive */ |
107 | {0x61,0x95}, /* GPIO pins 1-4 have special function */ | 107 | {0x61,0x95}, /* GPIO pins 1-4 have special function */ |
108 | {0x62,0x05}, /* GPIO pin 5 has special function, pin 6 is GPIO */ | 108 | {0x62,0x05}, /* GPIO pin 5 has special function, pin 6 is GPIO */ |
109 | {0x63,0x00}, /* All GPIO pins use CMOS output characteristics */ | 109 | {0x63,0x00}, /* All GPIO pins use CMOS output characteristics */ |
110 | {0x64,0x20}, /* GPIO 6 is input, all others are outputs */ | 110 | {0x64,0x20}, /* GPIO 6 is input, all others are outputs */ |
111 | {0x6d,0x30}, /* tuner auto mode clock freq 62kHz */ | 111 | {0x6d,0x30}, /* tuner auto mode clock freq 62kHz */ |
112 | {0x70,0x15}, /* use auto mode, tuner word is 21 bits long */ | 112 | {0x70,0x15}, /* use auto mode, tuner word is 21 bits long */ |
113 | {0x73,0x00}, /* @ disable several demod bypasses */ | 113 | {0x73,0x00}, /* @ disable several demod bypasses */ |
114 | {0x74,0x00}, /* @ " */ | 114 | {0x74,0x00}, /* @ " */ |
115 | {0x75,0x00} /* @ " */ | 115 | {0x75,0x00} /* @ " */ |
116 | /* the remaining registers are for SEC */ | 116 | /* the remaining registers are for SEC */ |
117 | }; | 117 | }; |
118 | 118 | ||
119 | 119 | ||
120 | static int cx24110_writereg (struct cx24110_state* state, int reg, int data) | 120 | static int cx24110_writereg (struct cx24110_state* state, int reg, int data) |
121 | { | 121 | { |
122 | u8 buf [] = { reg, data }; | 122 | u8 buf [] = { reg, data }; |
123 | struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 }; | 123 | struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 }; |
124 | int err; | 124 | int err; |
125 | 125 | ||
126 | if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) { | 126 | if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) { |
127 | dprintk ("%s: writereg error (err == %i, reg == 0x%02x," | 127 | dprintk ("%s: writereg error (err == %i, reg == 0x%02x," |
128 | " data == 0x%02x)\n", __FUNCTION__, err, reg, data); | 128 | " data == 0x%02x)\n", __FUNCTION__, err, reg, data); |
129 | return -EREMOTEIO; | 129 | return -EREMOTEIO; |
130 | } | 130 | } |
131 | 131 | ||
132 | return 0; | 132 | return 0; |
133 | } | 133 | } |
134 | 134 | ||
135 | static int cx24110_readreg (struct cx24110_state* state, u8 reg) | 135 | static int cx24110_readreg (struct cx24110_state* state, u8 reg) |
@@ -153,27 +153,27 @@ static int cx24110_set_inversion (struct cx24110_state* state, fe_spectral_inver | |||
153 | 153 | ||
154 | switch (inversion) { | 154 | switch (inversion) { |
155 | case INVERSION_OFF: | 155 | case INVERSION_OFF: |
156 | cx24110_writereg(state,0x37,cx24110_readreg(state,0x37)|0x1); | 156 | cx24110_writereg(state,0x37,cx24110_readreg(state,0x37)|0x1); |
157 | /* AcqSpectrInvDis on. No idea why someone should want this */ | 157 | /* AcqSpectrInvDis on. No idea why someone should want this */ |
158 | cx24110_writereg(state,0x5,cx24110_readreg(state,0x5)&0xf7); | 158 | cx24110_writereg(state,0x5,cx24110_readreg(state,0x5)&0xf7); |
159 | /* Initial value 0 at start of acq */ | 159 | /* Initial value 0 at start of acq */ |
160 | cx24110_writereg(state,0x22,cx24110_readreg(state,0x22)&0xef); | 160 | cx24110_writereg(state,0x22,cx24110_readreg(state,0x22)&0xef); |
161 | /* current value 0 */ | 161 | /* current value 0 */ |
162 | /* The cx24110 manual tells us this reg is read-only. | 162 | /* The cx24110 manual tells us this reg is read-only. |
163 | But what the heck... set it ayways */ | 163 | But what the heck... set it ayways */ |
164 | break; | 164 | break; |
165 | case INVERSION_ON: | 165 | case INVERSION_ON: |
166 | cx24110_writereg(state,0x37,cx24110_readreg(state,0x37)|0x1); | 166 | cx24110_writereg(state,0x37,cx24110_readreg(state,0x37)|0x1); |
167 | /* AcqSpectrInvDis on. No idea why someone should want this */ | 167 | /* AcqSpectrInvDis on. No idea why someone should want this */ |
168 | cx24110_writereg(state,0x5,cx24110_readreg(state,0x5)|0x08); | 168 | cx24110_writereg(state,0x5,cx24110_readreg(state,0x5)|0x08); |
169 | /* Initial value 1 at start of acq */ | 169 | /* Initial value 1 at start of acq */ |
170 | cx24110_writereg(state,0x22,cx24110_readreg(state,0x22)|0x10); | 170 | cx24110_writereg(state,0x22,cx24110_readreg(state,0x22)|0x10); |
171 | /* current value 1 */ | 171 | /* current value 1 */ |
172 | break; | 172 | break; |
173 | case INVERSION_AUTO: | 173 | case INVERSION_AUTO: |
174 | cx24110_writereg(state,0x37,cx24110_readreg(state,0x37)&0xfe); | 174 | cx24110_writereg(state,0x37,cx24110_readreg(state,0x37)&0xfe); |
175 | /* AcqSpectrInvDis off. Leave initial & current states as is */ | 175 | /* AcqSpectrInvDis off. Leave initial & current states as is */ |
176 | break; | 176 | break; |
177 | default: | 177 | default: |
178 | return -EINVAL; | 178 | return -EINVAL; |
179 | } | 179 | } |
@@ -185,18 +185,18 @@ static int cx24110_set_fec (struct cx24110_state* state, fe_code_rate_t fec) | |||
185 | { | 185 | { |
186 | /* fixme (low): error handling */ | 186 | /* fixme (low): error handling */ |
187 | 187 | ||
188 | static const int rate[]={-1,1,2,3,5,7,-1}; | 188 | static const int rate[]={-1,1,2,3,5,7,-1}; |
189 | static const int g1[]={-1,0x01,0x02,0x05,0x15,0x45,-1}; | 189 | static const int g1[]={-1,0x01,0x02,0x05,0x15,0x45,-1}; |
190 | static const int g2[]={-1,0x01,0x03,0x06,0x1a,0x7a,-1}; | 190 | static const int g2[]={-1,0x01,0x03,0x06,0x1a,0x7a,-1}; |
191 | 191 | ||
192 | /* Well, the AutoAcq engine of the cx24106 and 24110 automatically | 192 | /* Well, the AutoAcq engine of the cx24106 and 24110 automatically |
193 | searches all enabled viterbi rates, and can handle non-standard | 193 | searches all enabled viterbi rates, and can handle non-standard |
194 | rates as well. */ | 194 | rates as well. */ |
195 | 195 | ||
196 | if (fec>FEC_AUTO) | 196 | if (fec>FEC_AUTO) |
197 | fec=FEC_AUTO; | 197 | fec=FEC_AUTO; |
198 | 198 | ||
199 | if (fec==FEC_AUTO) { /* (re-)establish AutoAcq behaviour */ | 199 | if (fec==FEC_AUTO) { /* (re-)establish AutoAcq behaviour */ |
200 | cx24110_writereg(state,0x37,cx24110_readreg(state,0x37)&0xdf); | 200 | cx24110_writereg(state,0x37,cx24110_readreg(state,0x37)&0xdf); |
201 | /* clear AcqVitDis bit */ | 201 | /* clear AcqVitDis bit */ |
202 | cx24110_writereg(state,0x18,0xae); | 202 | cx24110_writereg(state,0x18,0xae); |
@@ -208,7 +208,7 @@ static int cx24110_set_fec (struct cx24110_state* state, fe_code_rate_t fec) | |||
208 | cx24110_writereg(state,0x1a,0x05); cx24110_writereg(state,0x1b,0x06); | 208 | cx24110_writereg(state,0x1a,0x05); cx24110_writereg(state,0x1b,0x06); |
209 | /* set the puncture registers for code rate 3/4 */ | 209 | /* set the puncture registers for code rate 3/4 */ |
210 | return 0; | 210 | return 0; |
211 | } else { | 211 | } else { |
212 | cx24110_writereg(state,0x37,cx24110_readreg(state,0x37)|0x20); | 212 | cx24110_writereg(state,0x37,cx24110_readreg(state,0x37)|0x20); |
213 | /* set AcqVitDis bit */ | 213 | /* set AcqVitDis bit */ |
214 | if(rate[fec]>0) { | 214 | if(rate[fec]>0) { |
@@ -219,10 +219,10 @@ static int cx24110_set_fec (struct cx24110_state* state, fe_code_rate_t fec) | |||
219 | cx24110_writereg(state,0x1a,g1[fec]); | 219 | cx24110_writereg(state,0x1a,g1[fec]); |
220 | cx24110_writereg(state,0x1b,g2[fec]); | 220 | cx24110_writereg(state,0x1b,g2[fec]); |
221 | /* not sure if this is the right way: I always used AutoAcq mode */ | 221 | /* not sure if this is the right way: I always used AutoAcq mode */ |
222 | } else | 222 | } else |
223 | return -EOPNOTSUPP; | 223 | return -EOPNOTSUPP; |
224 | /* fixme (low): which is the correct return code? */ | 224 | /* fixme (low): which is the correct return code? */ |
225 | }; | 225 | }; |
226 | return 0; | 226 | return 0; |
227 | } | 227 | } |
228 | 228 | ||
@@ -245,72 +245,72 @@ static fe_code_rate_t cx24110_get_fec (struct cx24110_state* state) | |||
245 | static int cx24110_set_symbolrate (struct cx24110_state* state, u32 srate) | 245 | static int cx24110_set_symbolrate (struct cx24110_state* state, u32 srate) |
246 | { | 246 | { |
247 | /* fixme (low): add error handling */ | 247 | /* fixme (low): add error handling */ |
248 | u32 ratio; | 248 | u32 ratio; |
249 | u32 tmp, fclk, BDRI; | 249 | u32 tmp, fclk, BDRI; |
250 | 250 | ||
251 | static const u32 bands[]={5000000UL,15000000UL,90999000UL/2}; | 251 | static const u32 bands[]={5000000UL,15000000UL,90999000UL/2}; |
252 | int i; | 252 | int i; |
253 | 253 | ||
254 | dprintk("cx24110 debug: entering %s(%d)\n",__FUNCTION__,srate); | 254 | dprintk("cx24110 debug: entering %s(%d)\n",__FUNCTION__,srate); |
255 | if (srate>90999000UL/2) | 255 | if (srate>90999000UL/2) |
256 | srate=90999000UL/2; | 256 | srate=90999000UL/2; |
257 | if (srate<500000) | 257 | if (srate<500000) |
258 | srate=500000; | 258 | srate=500000; |
259 | 259 | ||
260 | for(i=0;(i<sizeof(bands)/sizeof(bands[0]))&&(srate>bands[i]);i++) | 260 | for(i=0;(i<sizeof(bands)/sizeof(bands[0]))&&(srate>bands[i]);i++) |
261 | ; | 261 | ; |
262 | /* first, check which sample rate is appropriate: 45, 60 80 or 90 MHz, | 262 | /* first, check which sample rate is appropriate: 45, 60 80 or 90 MHz, |
263 | and set the PLL accordingly (R07[1:0] Fclk, R06[7:4] PLLmult, | 263 | and set the PLL accordingly (R07[1:0] Fclk, R06[7:4] PLLmult, |
264 | R06[3:0] PLLphaseDetGain */ | 264 | R06[3:0] PLLphaseDetGain */ |
265 | tmp=cx24110_readreg(state,0x07)&0xfc; | 265 | tmp=cx24110_readreg(state,0x07)&0xfc; |
266 | if(srate<90999000UL/4) { /* sample rate 45MHz*/ | 266 | if(srate<90999000UL/4) { /* sample rate 45MHz*/ |
267 | cx24110_writereg(state,0x07,tmp); | 267 | cx24110_writereg(state,0x07,tmp); |
268 | cx24110_writereg(state,0x06,0x78); | 268 | cx24110_writereg(state,0x06,0x78); |
269 | fclk=90999000UL/2; | 269 | fclk=90999000UL/2; |
270 | } else if(srate<60666000UL/2) { /* sample rate 60MHz */ | 270 | } else if(srate<60666000UL/2) { /* sample rate 60MHz */ |
271 | cx24110_writereg(state,0x07,tmp|0x1); | 271 | cx24110_writereg(state,0x07,tmp|0x1); |
272 | cx24110_writereg(state,0x06,0xa5); | 272 | cx24110_writereg(state,0x06,0xa5); |
273 | fclk=60666000UL; | 273 | fclk=60666000UL; |
274 | } else if(srate<80888000UL/2) { /* sample rate 80MHz */ | 274 | } else if(srate<80888000UL/2) { /* sample rate 80MHz */ |
275 | cx24110_writereg(state,0x07,tmp|0x2); | 275 | cx24110_writereg(state,0x07,tmp|0x2); |
276 | cx24110_writereg(state,0x06,0x87); | 276 | cx24110_writereg(state,0x06,0x87); |
277 | fclk=80888000UL; | 277 | fclk=80888000UL; |
278 | } else { /* sample rate 90MHz */ | 278 | } else { /* sample rate 90MHz */ |
279 | cx24110_writereg(state,0x07,tmp|0x3); | 279 | cx24110_writereg(state,0x07,tmp|0x3); |
280 | cx24110_writereg(state,0x06,0x78); | 280 | cx24110_writereg(state,0x06,0x78); |
281 | fclk=90999000UL; | 281 | fclk=90999000UL; |
282 | }; | 282 | }; |
283 | dprintk("cx24110 debug: fclk %d Hz\n",fclk); | 283 | dprintk("cx24110 debug: fclk %d Hz\n",fclk); |
284 | /* we need to divide two integers with approx. 27 bits in 32 bit | 284 | /* we need to divide two integers with approx. 27 bits in 32 bit |
285 | arithmetic giving a 25 bit result */ | 285 | arithmetic giving a 25 bit result */ |
286 | /* the maximum dividend is 90999000/2, 0x02b6446c, this number is | 286 | /* the maximum dividend is 90999000/2, 0x02b6446c, this number is |
287 | also the most complex divisor. Hence, the dividend has, | 287 | also the most complex divisor. Hence, the dividend has, |
288 | assuming 32bit unsigned arithmetic, 6 clear bits on top, the | 288 | assuming 32bit unsigned arithmetic, 6 clear bits on top, the |
289 | divisor 2 unused bits at the bottom. Also, the quotient is | 289 | divisor 2 unused bits at the bottom. Also, the quotient is |
290 | always less than 1/2. Borrowed from VES1893.c, of course */ | 290 | always less than 1/2. Borrowed from VES1893.c, of course */ |
291 | 291 | ||
292 | tmp=srate<<6; | 292 | tmp=srate<<6; |
293 | BDRI=fclk>>2; | 293 | BDRI=fclk>>2; |
294 | ratio=(tmp/BDRI); | 294 | ratio=(tmp/BDRI); |
295 | 295 | ||
296 | tmp=(tmp%BDRI)<<8; | 296 | tmp=(tmp%BDRI)<<8; |
297 | ratio=(ratio<<8)+(tmp/BDRI); | 297 | ratio=(ratio<<8)+(tmp/BDRI); |
298 | 298 | ||
299 | tmp=(tmp%BDRI)<<8; | 299 | tmp=(tmp%BDRI)<<8; |
300 | ratio=(ratio<<8)+(tmp/BDRI); | 300 | ratio=(ratio<<8)+(tmp/BDRI); |
301 | 301 | ||
302 | tmp=(tmp%BDRI)<<1; | 302 | tmp=(tmp%BDRI)<<1; |
303 | ratio=(ratio<<1)+(tmp/BDRI); | 303 | ratio=(ratio<<1)+(tmp/BDRI); |
304 | 304 | ||
305 | dprintk("srate= %d (range %d, up to %d)\n", srate,i,bands[i]); | 305 | dprintk("srate= %d (range %d, up to %d)\n", srate,i,bands[i]); |
306 | dprintk("fclk = %d\n", fclk); | 306 | dprintk("fclk = %d\n", fclk); |
307 | dprintk("ratio= %08x\n", ratio); | 307 | dprintk("ratio= %08x\n", ratio); |
308 | 308 | ||
309 | cx24110_writereg(state, 0x1, (ratio>>16)&0xff); | 309 | cx24110_writereg(state, 0x1, (ratio>>16)&0xff); |
310 | cx24110_writereg(state, 0x2, (ratio>>8)&0xff); | 310 | cx24110_writereg(state, 0x2, (ratio>>8)&0xff); |
311 | cx24110_writereg(state, 0x3, (ratio)&0xff); | 311 | cx24110_writereg(state, 0x3, (ratio)&0xff); |
312 | 312 | ||
313 | return 0; | 313 | return 0; |
314 | 314 | ||
315 | } | 315 | } |
316 | 316 | ||
@@ -324,48 +324,48 @@ int cx24110_pll_write (struct dvb_frontend* fe, u32 data) | |||
324 | 324 | ||
325 | dprintk("cx24110 debug: cx24108_write(%8.8x)\n",data); | 325 | dprintk("cx24110 debug: cx24108_write(%8.8x)\n",data); |
326 | 326 | ||
327 | cx24110_writereg(state,0x6d,0x30); /* auto mode at 62kHz */ | 327 | cx24110_writereg(state,0x6d,0x30); /* auto mode at 62kHz */ |
328 | cx24110_writereg(state,0x70,0x15); /* auto mode 21 bits */ | 328 | cx24110_writereg(state,0x70,0x15); /* auto mode 21 bits */ |
329 | 329 | ||
330 | /* if the auto tuner writer is still busy, clear it out */ | 330 | /* if the auto tuner writer is still busy, clear it out */ |
331 | while (cx24110_readreg(state,0x6d)&0x80) | 331 | while (cx24110_readreg(state,0x6d)&0x80) |
332 | cx24110_writereg(state,0x72,0); | 332 | cx24110_writereg(state,0x72,0); |
333 | 333 | ||
334 | /* write the topmost 8 bits */ | 334 | /* write the topmost 8 bits */ |
335 | cx24110_writereg(state,0x72,(data>>24)&0xff); | 335 | cx24110_writereg(state,0x72,(data>>24)&0xff); |
336 | 336 | ||
337 | /* wait for the send to be completed */ | 337 | /* wait for the send to be completed */ |
338 | while ((cx24110_readreg(state,0x6d)&0xc0)==0x80) | 338 | while ((cx24110_readreg(state,0x6d)&0xc0)==0x80) |
339 | ; | 339 | ; |
340 | 340 | ||
341 | /* send another 8 bytes */ | 341 | /* send another 8 bytes */ |
342 | cx24110_writereg(state,0x72,(data>>16)&0xff); | 342 | cx24110_writereg(state,0x72,(data>>16)&0xff); |
343 | while ((cx24110_readreg(state,0x6d)&0xc0)==0x80) | 343 | while ((cx24110_readreg(state,0x6d)&0xc0)==0x80) |
344 | ; | 344 | ; |
345 | 345 | ||
346 | /* and the topmost 5 bits of this byte */ | 346 | /* and the topmost 5 bits of this byte */ |
347 | cx24110_writereg(state,0x72,(data>>8)&0xff); | 347 | cx24110_writereg(state,0x72,(data>>8)&0xff); |
348 | while ((cx24110_readreg(state,0x6d)&0xc0)==0x80) | 348 | while ((cx24110_readreg(state,0x6d)&0xc0)==0x80) |
349 | ; | 349 | ; |
350 | 350 | ||
351 | /* now strobe the enable line once */ | 351 | /* now strobe the enable line once */ |
352 | cx24110_writereg(state,0x6d,0x32); | 352 | cx24110_writereg(state,0x6d,0x32); |
353 | cx24110_writereg(state,0x6d,0x30); | 353 | cx24110_writereg(state,0x6d,0x30); |
354 | 354 | ||
355 | return 0; | 355 | return 0; |
356 | } | 356 | } |
357 | 357 | ||
358 | static int cx24110_initfe(struct dvb_frontend* fe) | 358 | static int cx24110_initfe(struct dvb_frontend* fe) |
359 | { | 359 | { |
360 | struct cx24110_state *state = fe->demodulator_priv; | 360 | struct cx24110_state *state = fe->demodulator_priv; |
361 | /* fixme (low): error handling */ | 361 | /* fixme (low): error handling */ |
362 | int i; | 362 | int i; |
363 | 363 | ||
364 | dprintk("%s: init chip\n", __FUNCTION__); | 364 | dprintk("%s: init chip\n", __FUNCTION__); |
365 | 365 | ||
366 | for(i=0;i<sizeof(cx24110_regdata)/sizeof(cx24110_regdata[0]);i++) { | 366 | for(i=0;i<sizeof(cx24110_regdata)/sizeof(cx24110_regdata[0]);i++) { |
367 | cx24110_writereg(state, cx24110_regdata[i].reg, cx24110_regdata[i].data); | 367 | cx24110_writereg(state, cx24110_regdata[i].reg, cx24110_regdata[i].data); |
368 | }; | 368 | }; |
369 | 369 | ||
370 | if (state->config->pll_init) state->config->pll_init(fe); | 370 | if (state->config->pll_init) state->config->pll_init(fe); |
371 | 371 | ||