diff options
author | Chris Pascoe <c.pascoe@itee.uq.edu.au> | 2007-12-15 01:24:00 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2008-01-25 16:04:03 -0500 |
commit | bc514710889ebb975be9e84ca9c04f698225b656 (patch) | |
tree | 207c2e6f7a896678b95d036e11811df0de04988d /drivers/media/dvb/frontends/zl10353.c | |
parent | 3dfefc50ff45744ffb97ce0bf9c213a3fb6d5d3d (diff) |
V4L/DVB (6856): zl10353: improve tuning parameters and update register map
Some more I2C traces and a experimentation with register values on
both the ZL10353 and MT352 mean that I can now guess at what more
of the ZL10353 registers do.
Guess at the registers' names (based on the equivalent names in MT352)
and update set_parameters/get_parameters with the new knowledge.
Signed-off-by: Chris Pascoe <c.pascoe@itee.uq.edu.au>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/dvb/frontends/zl10353.c')
-rw-r--r-- | drivers/media/dvb/frontends/zl10353.c | 243 |
1 files changed, 230 insertions, 13 deletions
diff --git a/drivers/media/dvb/frontends/zl10353.c b/drivers/media/dvb/frontends/zl10353.c index e874ec8df60c..276e3b631dc2 100644 --- a/drivers/media/dvb/frontends/zl10353.c +++ b/drivers/media/dvb/frontends/zl10353.c | |||
@@ -36,6 +36,8 @@ struct zl10353_state { | |||
36 | struct dvb_frontend frontend; | 36 | struct dvb_frontend frontend; |
37 | 37 | ||
38 | struct zl10353_config config; | 38 | struct zl10353_config config; |
39 | |||
40 | enum fe_bandwidth bandwidth; | ||
39 | }; | 41 | }; |
40 | 42 | ||
41 | static int debug; | 43 | static int debug; |
@@ -195,27 +197,156 @@ static int zl10353_set_parameters(struct dvb_frontend *fe, | |||
195 | { | 197 | { |
196 | struct zl10353_state *state = fe->demodulator_priv; | 198 | struct zl10353_state *state = fe->demodulator_priv; |
197 | u16 nominal_rate, input_freq; | 199 | u16 nominal_rate, input_freq; |
198 | u8 pllbuf[6] = { 0x67 }; | 200 | u8 pllbuf[6] = { 0x67 }, acq_ctl = 0; |
201 | u16 tps = 0; | ||
202 | struct dvb_ofdm_parameters *op = ¶m->u.ofdm; | ||
199 | 203 | ||
200 | /* These settings set "auto-everything" and start the FSM. */ | 204 | zl10353_single_write(fe, RESET, 0x80); |
201 | zl10353_single_write(fe, 0x55, 0x80); | ||
202 | udelay(200); | 205 | udelay(200); |
203 | zl10353_single_write(fe, 0xEA, 0x01); | 206 | zl10353_single_write(fe, 0xEA, 0x01); |
204 | udelay(200); | 207 | udelay(200); |
205 | zl10353_single_write(fe, 0xEA, 0x00); | 208 | zl10353_single_write(fe, 0xEA, 0x00); |
206 | 209 | ||
207 | zl10353_single_write(fe, 0x56, 0x28); | 210 | zl10353_single_write(fe, AGC_TARGET, 0x28); |
208 | zl10353_single_write(fe, 0x89, 0x20); | 211 | |
209 | zl10353_single_write(fe, 0x5E, 0x00); | 212 | if (op->transmission_mode != TRANSMISSION_MODE_AUTO) |
213 | acq_ctl |= (1 << 0); | ||
214 | if (op->guard_interval != GUARD_INTERVAL_AUTO) | ||
215 | acq_ctl |= (1 << 1); | ||
216 | zl10353_single_write(fe, ACQ_CTL, acq_ctl); | ||
210 | 217 | ||
211 | zl10353_calc_nominal_rate(fe, param->u.ofdm.bandwidth, &nominal_rate); | 218 | switch (op->bandwidth) { |
219 | case BANDWIDTH_6_MHZ: | ||
220 | /* These are extrapolated from the 7 and 8MHz values */ | ||
221 | zl10353_single_write(fe, MCLK_RATIO, 0x97); | ||
222 | zl10353_single_write(fe, 0x64, 0x34); | ||
223 | break; | ||
224 | case BANDWIDTH_7_MHZ: | ||
225 | zl10353_single_write(fe, MCLK_RATIO, 0x86); | ||
226 | zl10353_single_write(fe, 0x64, 0x35); | ||
227 | break; | ||
228 | case BANDWIDTH_8_MHZ: | ||
229 | default: | ||
230 | zl10353_single_write(fe, MCLK_RATIO, 0x75); | ||
231 | zl10353_single_write(fe, 0x64, 0x36); | ||
232 | } | ||
233 | |||
234 | zl10353_calc_nominal_rate(fe, op->bandwidth, &nominal_rate); | ||
212 | zl10353_single_write(fe, TRL_NOMINAL_RATE_1, msb(nominal_rate)); | 235 | zl10353_single_write(fe, TRL_NOMINAL_RATE_1, msb(nominal_rate)); |
213 | zl10353_single_write(fe, TRL_NOMINAL_RATE_0, lsb(nominal_rate)); | 236 | zl10353_single_write(fe, TRL_NOMINAL_RATE_0, lsb(nominal_rate)); |
237 | state->bandwidth = op->bandwidth; | ||
214 | 238 | ||
215 | zl10353_calc_input_freq(fe, &input_freq); | 239 | zl10353_calc_input_freq(fe, &input_freq); |
216 | zl10353_single_write(fe, INPUT_FREQ_1, msb(input_freq)); | 240 | zl10353_single_write(fe, INPUT_FREQ_1, msb(input_freq)); |
217 | zl10353_single_write(fe, INPUT_FREQ_0, lsb(input_freq)); | 241 | zl10353_single_write(fe, INPUT_FREQ_0, lsb(input_freq)); |
218 | 242 | ||
243 | /* Hint at TPS settings */ | ||
244 | switch (op->code_rate_HP) { | ||
245 | case FEC_2_3: | ||
246 | tps |= (1 << 7); | ||
247 | break; | ||
248 | case FEC_3_4: | ||
249 | tps |= (2 << 7); | ||
250 | break; | ||
251 | case FEC_5_6: | ||
252 | tps |= (3 << 7); | ||
253 | break; | ||
254 | case FEC_7_8: | ||
255 | tps |= (4 << 7); | ||
256 | break; | ||
257 | case FEC_1_2: | ||
258 | case FEC_AUTO: | ||
259 | break; | ||
260 | default: | ||
261 | return -EINVAL; | ||
262 | } | ||
263 | |||
264 | switch (op->code_rate_LP) { | ||
265 | case FEC_2_3: | ||
266 | tps |= (1 << 4); | ||
267 | break; | ||
268 | case FEC_3_4: | ||
269 | tps |= (2 << 4); | ||
270 | break; | ||
271 | case FEC_5_6: | ||
272 | tps |= (3 << 4); | ||
273 | break; | ||
274 | case FEC_7_8: | ||
275 | tps |= (4 << 4); | ||
276 | break; | ||
277 | case FEC_1_2: | ||
278 | case FEC_AUTO: | ||
279 | break; | ||
280 | case FEC_NONE: | ||
281 | if (op->hierarchy_information == HIERARCHY_AUTO || | ||
282 | op->hierarchy_information == HIERARCHY_NONE) | ||
283 | break; | ||
284 | default: | ||
285 | return -EINVAL; | ||
286 | } | ||
287 | |||
288 | switch (op->constellation) { | ||
289 | case QPSK: | ||
290 | break; | ||
291 | case QAM_AUTO: | ||
292 | case QAM_16: | ||
293 | tps |= (1 << 13); | ||
294 | break; | ||
295 | case QAM_64: | ||
296 | tps |= (2 << 13); | ||
297 | break; | ||
298 | default: | ||
299 | return -EINVAL; | ||
300 | } | ||
301 | |||
302 | switch (op->transmission_mode) { | ||
303 | case TRANSMISSION_MODE_2K: | ||
304 | case TRANSMISSION_MODE_AUTO: | ||
305 | break; | ||
306 | case TRANSMISSION_MODE_8K: | ||
307 | tps |= (1 << 0); | ||
308 | break; | ||
309 | default: | ||
310 | return -EINVAL; | ||
311 | } | ||
312 | |||
313 | switch (op->guard_interval) { | ||
314 | case GUARD_INTERVAL_1_32: | ||
315 | case GUARD_INTERVAL_AUTO: | ||
316 | break; | ||
317 | case GUARD_INTERVAL_1_16: | ||
318 | tps |= (1 << 2); | ||
319 | break; | ||
320 | case GUARD_INTERVAL_1_8: | ||
321 | tps |= (2 << 2); | ||
322 | break; | ||
323 | case GUARD_INTERVAL_1_4: | ||
324 | tps |= (3 << 2); | ||
325 | break; | ||
326 | default: | ||
327 | return -EINVAL; | ||
328 | } | ||
329 | |||
330 | switch (op->hierarchy_information) { | ||
331 | case HIERARCHY_AUTO: | ||
332 | case HIERARCHY_NONE: | ||
333 | break; | ||
334 | case HIERARCHY_1: | ||
335 | tps |= (1 << 10); | ||
336 | break; | ||
337 | case HIERARCHY_2: | ||
338 | tps |= (2 << 10); | ||
339 | break; | ||
340 | case HIERARCHY_4: | ||
341 | tps |= (3 << 10); | ||
342 | break; | ||
343 | default: | ||
344 | return -EINVAL; | ||
345 | } | ||
346 | |||
347 | zl10353_single_write(fe, TPS_GIVEN_1, msb(tps)); | ||
348 | zl10353_single_write(fe, TPS_GIVEN_0, lsb(tps)); | ||
349 | |||
219 | if (fe->ops.i2c_gate_ctrl) | 350 | if (fe->ops.i2c_gate_ctrl) |
220 | fe->ops.i2c_gate_ctrl(fe, 0); | 351 | fe->ops.i2c_gate_ctrl(fe, 0); |
221 | 352 | ||
@@ -244,12 +375,97 @@ static int zl10353_set_parameters(struct dvb_frontend *fe, | |||
244 | else | 375 | else |
245 | zl10353_single_write(fe, TUNER_GO, 0x01); | 376 | zl10353_single_write(fe, TUNER_GO, 0x01); |
246 | 377 | ||
247 | udelay(250); | 378 | return 0; |
248 | zl10353_single_write(fe, 0xE4, 0x00); | 379 | } |
249 | zl10353_single_write(fe, 0xE5, 0x2A); | 380 | |
250 | zl10353_single_write(fe, 0xE9, 0x02); | 381 | static int zl10353_get_parameters(struct dvb_frontend *fe, |
251 | zl10353_single_write(fe, 0xE7, 0x40); | 382 | struct dvb_frontend_parameters *param) |
252 | zl10353_single_write(fe, 0xE8, 0x10); | 383 | { |
384 | struct zl10353_state *state = fe->demodulator_priv; | ||
385 | struct dvb_ofdm_parameters *op = ¶m->u.ofdm; | ||
386 | int s6, s9; | ||
387 | u16 tps; | ||
388 | static const u8 tps_fec_to_api[8] = { | ||
389 | FEC_1_2, | ||
390 | FEC_2_3, | ||
391 | FEC_3_4, | ||
392 | FEC_5_6, | ||
393 | FEC_7_8, | ||
394 | FEC_AUTO, | ||
395 | FEC_AUTO, | ||
396 | FEC_AUTO | ||
397 | }; | ||
398 | |||
399 | s6 = zl10353_read_register(state, STATUS_6); | ||
400 | s9 = zl10353_read_register(state, STATUS_9); | ||
401 | if (s6 < 0 || s9 < 0) | ||
402 | return -EREMOTEIO; | ||
403 | if ((s6 & (1 << 5)) == 0 || (s9 & (1 << 4)) == 0) | ||
404 | return -EINVAL; /* no FE or TPS lock */ | ||
405 | |||
406 | tps = zl10353_read_register(state, TPS_RECEIVED_1) << 8 | | ||
407 | zl10353_read_register(state, TPS_RECEIVED_0); | ||
408 | |||
409 | op->code_rate_HP = tps_fec_to_api[(tps >> 7) & 7]; | ||
410 | op->code_rate_LP = tps_fec_to_api[(tps >> 4) & 7]; | ||
411 | |||
412 | switch ((tps >> 13) & 3) { | ||
413 | case 0: | ||
414 | op->constellation = QPSK; | ||
415 | break; | ||
416 | case 1: | ||
417 | op->constellation = QAM_16; | ||
418 | break; | ||
419 | case 2: | ||
420 | op->constellation = QAM_64; | ||
421 | break; | ||
422 | default: | ||
423 | op->constellation = QAM_AUTO; | ||
424 | break; | ||
425 | } | ||
426 | |||
427 | op->transmission_mode = (tps & 0x01) ? TRANSMISSION_MODE_8K : | ||
428 | TRANSMISSION_MODE_2K; | ||
429 | |||
430 | switch ((tps >> 2) & 3) { | ||
431 | case 0: | ||
432 | op->guard_interval = GUARD_INTERVAL_1_32; | ||
433 | break; | ||
434 | case 1: | ||
435 | op->guard_interval = GUARD_INTERVAL_1_16; | ||
436 | break; | ||
437 | case 2: | ||
438 | op->guard_interval = GUARD_INTERVAL_1_8; | ||
439 | break; | ||
440 | case 3: | ||
441 | op->guard_interval = GUARD_INTERVAL_1_4; | ||
442 | break; | ||
443 | default: | ||
444 | op->guard_interval = GUARD_INTERVAL_AUTO; | ||
445 | break; | ||
446 | } | ||
447 | |||
448 | switch ((tps >> 10) & 7) { | ||
449 | case 0: | ||
450 | op->hierarchy_information = HIERARCHY_NONE; | ||
451 | break; | ||
452 | case 1: | ||
453 | op->hierarchy_information = HIERARCHY_1; | ||
454 | break; | ||
455 | case 2: | ||
456 | op->hierarchy_information = HIERARCHY_2; | ||
457 | break; | ||
458 | case 3: | ||
459 | op->hierarchy_information = HIERARCHY_4; | ||
460 | break; | ||
461 | default: | ||
462 | op->hierarchy_information = HIERARCHY_AUTO; | ||
463 | break; | ||
464 | } | ||
465 | |||
466 | param->frequency = 0; | ||
467 | op->bandwidth = state->bandwidth; | ||
468 | param->inversion = INVERSION_AUTO; | ||
253 | 469 | ||
254 | return 0; | 470 | return 0; |
255 | } | 471 | } |
@@ -438,6 +654,7 @@ static struct dvb_frontend_ops zl10353_ops = { | |||
438 | .write = zl10353_write, | 654 | .write = zl10353_write, |
439 | 655 | ||
440 | .set_frontend = zl10353_set_parameters, | 656 | .set_frontend = zl10353_set_parameters, |
657 | .get_frontend = zl10353_get_parameters, | ||
441 | .get_tune_settings = zl10353_get_tune_settings, | 658 | .get_tune_settings = zl10353_get_tune_settings, |
442 | 659 | ||
443 | .read_status = zl10353_read_status, | 660 | .read_status = zl10353_read_status, |