Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[media] tda10021: Add support for DVB-C Annex C

While tda10021 supports both DVB-C Annex A and C, it is currently
hard-coded to Annex A. Add support for Annex C and re-work the
code in order to report the delivery systems, thans to Andreas,
that passed us the register settings for the Roll-off factor.

Thanks-to: Andreas Oberriter <obi@linuxtv.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

+45 -4
+45 -4
drivers/media/dvb/frontends/tda10021.c
··· 231 231 static int tda10021_set_parameters (struct dvb_frontend *fe, 232 232 struct dvb_frontend_parameters *p) 233 233 { 234 + struct dtv_frontend_properties *c = &fe->dtv_property_cache; 235 + u32 delsys = c->delivery_system; 236 + unsigned qam = c->modulation; 237 + bool is_annex_c; 238 + u32 reg0x3d; 234 239 struct tda10021_state* state = fe->demodulator_priv; 235 240 static const struct qam_params qam_params[] = { 236 241 /* Modulation Conf AGCref LTHR MSETH AREF */ ··· 246 241 [QAM_128] = { 0x0c, 0x78, 0x36, 0x34, 0x7e }, 247 242 [QAM_256] = { 0x10, 0x5c, 0x26, 0x23, 0x6b }, 248 243 }; 249 - int qam = p->u.qam.modulation; 244 + 245 + switch (delsys) { 246 + case SYS_DVBC_ANNEX_A: 247 + is_annex_c = false; 248 + break; 249 + case SYS_DVBC_ANNEX_C: 250 + is_annex_c = true; 251 + break; 252 + default: 253 + return -EINVAL; 254 + } 250 255 251 256 /* 252 257 * gcc optimizes the code bellow the same way as it would code: ··· 277 262 return -EINVAL; 278 263 } 279 264 280 - if (p->inversion != INVERSION_ON && p->inversion != INVERSION_OFF) 265 + if (c->inversion != INVERSION_ON && c->inversion != INVERSION_OFF) 281 266 return -EINVAL; 282 267 283 268 //printk("tda10021: set frequency to %d qam=%d symrate=%d\n", p->frequency,qam,p->u.qam.symbol_rate); ··· 287 272 if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); 288 273 } 289 274 290 - tda10021_set_symbolrate(state, p->u.qam.symbol_rate); 275 + tda10021_set_symbolrate(state, c->symbol_rate); 291 276 _tda10021_writereg(state, 0x34, state->pwm); 292 277 293 278 _tda10021_writereg(state, 0x01, qam_params[qam].agcref); 294 279 _tda10021_writereg(state, 0x05, qam_params[qam].lthr); 295 280 _tda10021_writereg(state, 0x08, qam_params[qam].mseth); 296 281 _tda10021_writereg(state, 0x09, qam_params[qam].aref); 297 - tda10021_setup_reg0(state, qam_params[qam].conf, p->inversion); 282 + 283 + /* 284 + * Bit 0 == 0 means roll-off = 0.15 (Annex A) 285 + * == 1 means roll-off = 0.13 (Annex C) 286 + */ 287 + reg0x3d = tda10021_readreg (state, 0x3d); 288 + if (is_annex_c) 289 + _tda10021_writereg (state, 0x3d, 0x01 | reg0x3d); 290 + else 291 + _tda10021_writereg (state, 0x3d, 0xfe & reg0x3d); 292 + tda10021_setup_reg0(state, qam_params[qam].conf, c->inversion); 298 293 299 294 return 0; 300 295 } ··· 483 458 return NULL; 484 459 } 485 460 461 + static int tda10021_get_property(struct dvb_frontend *fe, 462 + struct dtv_property *p) 463 + { 464 + switch (p->cmd) { 465 + case DTV_ENUM_DELSYS: 466 + p->u.buffer.data[0] = SYS_DVBC_ANNEX_A; 467 + p->u.buffer.data[1] = SYS_DVBC_ANNEX_C; 468 + p->u.buffer.len = 2; 469 + break; 470 + default: 471 + break; 472 + } 473 + return 0; 474 + } 475 + 486 476 static struct dvb_frontend_ops tda10021_ops = { 487 477 488 478 .info = { ··· 526 486 527 487 .set_frontend = tda10021_set_parameters, 528 488 .get_frontend = tda10021_get_frontend, 489 + .get_property = tda10021_get_property, 529 490 530 491 .read_status = tda10021_read_status, 531 492 .read_ber = tda10021_read_ber,