aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2012-09-28 10:04:21 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-10-07 08:43:01 -0400
commit78ef81f6ea9649fd09d1fafcfa0ad68763172c42 (patch)
tree7e7737736c2c7b08cc9aa682538b91d6cbda9538
parent034351ff6372c1a880ed4c5d333e430e9c83d467 (diff)
[media] tda18271-common: hold the I2C adapter during write transfers
The tda18271 datasheet says: "The image rejection calibration and RF tracking filter calibration must be launched exactly as described in the flowchart, otherwise bad calibration or even blocking of the TDA18211HD can result making it impossible to communicate via the I2C-bus." (yeah, tda18271 refers there to tda18211 - likely a typo at their datasheets) That likely explains why sometimes tda18271 stops answering. That is now happening more often on designs with drx-k chips, as the firmware is now loaded asyncrousnly there. While the above text doesn't explicitly tell that the I2C bus couldn't be used by other devices during such initialization, that seems to be a requirement there. So, let's explicitly use the I2C lock there, avoiding I2C bus share during those critical moments. Compile-tested only. Please test. Acked-by: Michael Krufky <mkrufky@linuxtv.org> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r--drivers/media/tuners/tda18271-common.c104
1 files changed, 71 insertions, 33 deletions
diff --git a/drivers/media/tuners/tda18271-common.c b/drivers/media/tuners/tda18271-common.c
index 221171eeb0c..18c77afe2e4 100644
--- a/drivers/media/tuners/tda18271-common.c
+++ b/drivers/media/tuners/tda18271-common.c
@@ -187,7 +187,8 @@ int tda18271_read_extended(struct dvb_frontend *fe)
187 return (ret == 2 ? 0 : ret); 187 return (ret == 2 ? 0 : ret);
188} 188}
189 189
190int tda18271_write_regs(struct dvb_frontend *fe, int idx, int len) 190static int __tda18271_write_regs(struct dvb_frontend *fe, int idx, int len,
191 bool lock_i2c)
191{ 192{
192 struct tda18271_priv *priv = fe->tuner_priv; 193 struct tda18271_priv *priv = fe->tuner_priv;
193 unsigned char *regs = priv->tda18271_regs; 194 unsigned char *regs = priv->tda18271_regs;
@@ -198,7 +199,6 @@ int tda18271_write_regs(struct dvb_frontend *fe, int idx, int len)
198 199
199 BUG_ON((len == 0) || (idx + len > sizeof(buf))); 200 BUG_ON((len == 0) || (idx + len > sizeof(buf)));
200 201
201
202 switch (priv->small_i2c) { 202 switch (priv->small_i2c) {
203 case TDA18271_03_BYTE_CHUNK_INIT: 203 case TDA18271_03_BYTE_CHUNK_INIT:
204 max = 3; 204 max = 3;
@@ -214,7 +214,19 @@ int tda18271_write_regs(struct dvb_frontend *fe, int idx, int len)
214 max = 39; 214 max = 39;
215 } 215 }
216 216
217 tda18271_i2c_gate_ctrl(fe, 1); 217
218 /*
219 * If lock_i2c is true, it will take the I2C bus for tda18271 private
220 * usage during the entire write ops, as otherwise, bad things could
221 * happen.
222 * During device init, several write operations will happen. So,
223 * tda18271_init_regs controls the I2C lock directly,
224 * disabling lock_i2c here.
225 */
226 if (lock_i2c) {
227 tda18271_i2c_gate_ctrl(fe, 1);
228 i2c_lock_adapter(priv->i2c_props.adap);
229 }
218 while (len) { 230 while (len) {
219 if (max > len) 231 if (max > len)
220 max = len; 232 max = len;
@@ -226,14 +238,17 @@ int tda18271_write_regs(struct dvb_frontend *fe, int idx, int len)
226 msg.len = max + 1; 238 msg.len = max + 1;
227 239
228 /* write registers */ 240 /* write registers */
229 ret = i2c_transfer(priv->i2c_props.adap, &msg, 1); 241 ret = __i2c_transfer(priv->i2c_props.adap, &msg, 1);
230 if (ret != 1) 242 if (ret != 1)
231 break; 243 break;
232 244
233 idx += max; 245 idx += max;
234 len -= max; 246 len -= max;
235 } 247 }
236 tda18271_i2c_gate_ctrl(fe, 0); 248 if (lock_i2c) {
249 i2c_unlock_adapter(priv->i2c_props.adap);
250 tda18271_i2c_gate_ctrl(fe, 0);
251 }
237 252
238 if (ret != 1) 253 if (ret != 1)
239 tda_err("ERROR: idx = 0x%x, len = %d, " 254 tda_err("ERROR: idx = 0x%x, len = %d, "
@@ -242,10 +257,16 @@ int tda18271_write_regs(struct dvb_frontend *fe, int idx, int len)
242 return (ret == 1 ? 0 : ret); 257 return (ret == 1 ? 0 : ret);
243} 258}
244 259
260int tda18271_write_regs(struct dvb_frontend *fe, int idx, int len)
261{
262 return __tda18271_write_regs(fe, idx, len, true);
263}
264
245/*---------------------------------------------------------------------*/ 265/*---------------------------------------------------------------------*/
246 266
247int tda18271_charge_pump_source(struct dvb_frontend *fe, 267static int __tda18271_charge_pump_source(struct dvb_frontend *fe,
248 enum tda18271_pll pll, int force) 268 enum tda18271_pll pll, int force,
269 bool lock_i2c)
249{ 270{
250 struct tda18271_priv *priv = fe->tuner_priv; 271 struct tda18271_priv *priv = fe->tuner_priv;
251 unsigned char *regs = priv->tda18271_regs; 272 unsigned char *regs = priv->tda18271_regs;
@@ -255,9 +276,16 @@ int tda18271_charge_pump_source(struct dvb_frontend *fe,
255 regs[r_cp] &= ~0x20; 276 regs[r_cp] &= ~0x20;
256 regs[r_cp] |= ((force & 1) << 5); 277 regs[r_cp] |= ((force & 1) << 5);
257 278
258 return tda18271_write_regs(fe, r_cp, 1); 279 return __tda18271_write_regs(fe, r_cp, 1, lock_i2c);
280}
281
282int tda18271_charge_pump_source(struct dvb_frontend *fe,
283 enum tda18271_pll pll, int force)
284{
285 return __tda18271_charge_pump_source(fe, pll, force, true);
259} 286}
260 287
288
261int tda18271_init_regs(struct dvb_frontend *fe) 289int tda18271_init_regs(struct dvb_frontend *fe)
262{ 290{
263 struct tda18271_priv *priv = fe->tuner_priv; 291 struct tda18271_priv *priv = fe->tuner_priv;
@@ -267,6 +295,13 @@ int tda18271_init_regs(struct dvb_frontend *fe)
267 i2c_adapter_id(priv->i2c_props.adap), 295 i2c_adapter_id(priv->i2c_props.adap),
268 priv->i2c_props.addr); 296 priv->i2c_props.addr);
269 297
298 /*
299 * Don't let any other I2C transfer to happen at adapter during init,
300 * as those could cause bad things
301 */
302 tda18271_i2c_gate_ctrl(fe, 1);
303 i2c_lock_adapter(priv->i2c_props.adap);
304
270 /* initialize registers */ 305 /* initialize registers */
271 switch (priv->id) { 306 switch (priv->id) {
272 case TDA18271HDC1: 307 case TDA18271HDC1:
@@ -352,28 +387,28 @@ int tda18271_init_regs(struct dvb_frontend *fe)
352 regs[R_EB22] = 0x48; 387 regs[R_EB22] = 0x48;
353 regs[R_EB23] = 0xb0; 388 regs[R_EB23] = 0xb0;
354 389
355 tda18271_write_regs(fe, 0x00, TDA18271_NUM_REGS); 390 __tda18271_write_regs(fe, 0x00, TDA18271_NUM_REGS, false);
356 391
357 /* setup agc1 gain */ 392 /* setup agc1 gain */
358 regs[R_EB17] = 0x00; 393 regs[R_EB17] = 0x00;
359 tda18271_write_regs(fe, R_EB17, 1); 394 __tda18271_write_regs(fe, R_EB17, 1, false);
360 regs[R_EB17] = 0x03; 395 regs[R_EB17] = 0x03;
361 tda18271_write_regs(fe, R_EB17, 1); 396 __tda18271_write_regs(fe, R_EB17, 1, false);
362 regs[R_EB17] = 0x43; 397 regs[R_EB17] = 0x43;
363 tda18271_write_regs(fe, R_EB17, 1); 398 __tda18271_write_regs(fe, R_EB17, 1, false);
364 regs[R_EB17] = 0x4c; 399 regs[R_EB17] = 0x4c;
365 tda18271_write_regs(fe, R_EB17, 1); 400 __tda18271_write_regs(fe, R_EB17, 1, false);
366 401
367 /* setup agc2 gain */ 402 /* setup agc2 gain */
368 if ((priv->id) == TDA18271HDC1) { 403 if ((priv->id) == TDA18271HDC1) {
369 regs[R_EB20] = 0xa0; 404 regs[R_EB20] = 0xa0;
370 tda18271_write_regs(fe, R_EB20, 1); 405 __tda18271_write_regs(fe, R_EB20, 1, false);
371 regs[R_EB20] = 0xa7; 406 regs[R_EB20] = 0xa7;
372 tda18271_write_regs(fe, R_EB20, 1); 407 __tda18271_write_regs(fe, R_EB20, 1, false);
373 regs[R_EB20] = 0xe7; 408 regs[R_EB20] = 0xe7;
374 tda18271_write_regs(fe, R_EB20, 1); 409 __tda18271_write_regs(fe, R_EB20, 1, false);
375 regs[R_EB20] = 0xec; 410 regs[R_EB20] = 0xec;
376 tda18271_write_regs(fe, R_EB20, 1); 411 __tda18271_write_regs(fe, R_EB20, 1, false);
377 } 412 }
378 413
379 /* image rejection calibration */ 414 /* image rejection calibration */
@@ -391,21 +426,21 @@ int tda18271_init_regs(struct dvb_frontend *fe)
391 regs[R_MD2] = 0x08; 426 regs[R_MD2] = 0x08;
392 regs[R_MD3] = 0x00; 427 regs[R_MD3] = 0x00;
393 428
394 tda18271_write_regs(fe, R_EP3, 11); 429 __tda18271_write_regs(fe, R_EP3, 11, false);
395 430
396 if ((priv->id) == TDA18271HDC2) { 431 if ((priv->id) == TDA18271HDC2) {
397 /* main pll cp source on */ 432 /* main pll cp source on */
398 tda18271_charge_pump_source(fe, TDA18271_MAIN_PLL, 1); 433 __tda18271_charge_pump_source(fe, TDA18271_MAIN_PLL, 1, false);
399 msleep(1); 434 msleep(1);
400 435
401 /* main pll cp source off */ 436 /* main pll cp source off */
402 tda18271_charge_pump_source(fe, TDA18271_MAIN_PLL, 0); 437 __tda18271_charge_pump_source(fe, TDA18271_MAIN_PLL, 0, false);
403 } 438 }
404 439
405 msleep(5); /* pll locking */ 440 msleep(5); /* pll locking */
406 441
407 /* launch detector */ 442 /* launch detector */
408 tda18271_write_regs(fe, R_EP1, 1); 443 __tda18271_write_regs(fe, R_EP1, 1, false);
409 msleep(5); /* wanted low measurement */ 444 msleep(5); /* wanted low measurement */
410 445
411 regs[R_EP5] = 0x85; 446 regs[R_EP5] = 0x85;
@@ -413,11 +448,11 @@ int tda18271_init_regs(struct dvb_frontend *fe)
413 regs[R_CD1] = 0x66; 448 regs[R_CD1] = 0x66;
414 regs[R_CD2] = 0x70; 449 regs[R_CD2] = 0x70;
415 450
416 tda18271_write_regs(fe, R_EP3, 7); 451 __tda18271_write_regs(fe, R_EP3, 7, false);
417 msleep(5); /* pll locking */ 452 msleep(5); /* pll locking */
418 453
419 /* launch optimization algorithm */ 454 /* launch optimization algorithm */
420 tda18271_write_regs(fe, R_EP2, 1); 455 __tda18271_write_regs(fe, R_EP2, 1, false);
421 msleep(30); /* image low optimization completion */ 456 msleep(30); /* image low optimization completion */
422 457
423 /* mid-band */ 458 /* mid-band */
@@ -428,11 +463,11 @@ int tda18271_init_regs(struct dvb_frontend *fe)
428 regs[R_MD1] = 0x73; 463 regs[R_MD1] = 0x73;
429 regs[R_MD2] = 0x1a; 464 regs[R_MD2] = 0x1a;
430 465
431 tda18271_write_regs(fe, R_EP3, 11); 466 __tda18271_write_regs(fe, R_EP3, 11, false);
432 msleep(5); /* pll locking */ 467 msleep(5); /* pll locking */
433 468
434 /* launch detector */ 469 /* launch detector */
435 tda18271_write_regs(fe, R_EP1, 1); 470 __tda18271_write_regs(fe, R_EP1, 1, false);
436 msleep(5); /* wanted mid measurement */ 471 msleep(5); /* wanted mid measurement */
437 472
438 regs[R_EP5] = 0x86; 473 regs[R_EP5] = 0x86;
@@ -440,11 +475,11 @@ int tda18271_init_regs(struct dvb_frontend *fe)
440 regs[R_CD1] = 0x66; 475 regs[R_CD1] = 0x66;
441 regs[R_CD2] = 0xa0; 476 regs[R_CD2] = 0xa0;
442 477
443 tda18271_write_regs(fe, R_EP3, 7); 478 __tda18271_write_regs(fe, R_EP3, 7, false);
444 msleep(5); /* pll locking */ 479 msleep(5); /* pll locking */
445 480
446 /* launch optimization algorithm */ 481 /* launch optimization algorithm */
447 tda18271_write_regs(fe, R_EP2, 1); 482 __tda18271_write_regs(fe, R_EP2, 1, false);
448 msleep(30); /* image mid optimization completion */ 483 msleep(30); /* image mid optimization completion */
449 484
450 /* high-band */ 485 /* high-band */
@@ -456,30 +491,33 @@ int tda18271_init_regs(struct dvb_frontend *fe)
456 regs[R_MD1] = 0x71; 491 regs[R_MD1] = 0x71;
457 regs[R_MD2] = 0xcd; 492 regs[R_MD2] = 0xcd;
458 493
459 tda18271_write_regs(fe, R_EP3, 11); 494 __tda18271_write_regs(fe, R_EP3, 11, false);
460 msleep(5); /* pll locking */ 495 msleep(5); /* pll locking */
461 496
462 /* launch detector */ 497 /* launch detector */
463 tda18271_write_regs(fe, R_EP1, 1); 498 __tda18271_write_regs(fe, R_EP1, 1, false);
464 msleep(5); /* wanted high measurement */ 499 msleep(5); /* wanted high measurement */
465 500
466 regs[R_EP5] = 0x87; 501 regs[R_EP5] = 0x87;
467 regs[R_CD1] = 0x65; 502 regs[R_CD1] = 0x65;
468 regs[R_CD2] = 0x50; 503 regs[R_CD2] = 0x50;
469 504
470 tda18271_write_regs(fe, R_EP3, 7); 505 __tda18271_write_regs(fe, R_EP3, 7, false);
471 msleep(5); /* pll locking */ 506 msleep(5); /* pll locking */
472 507
473 /* launch optimization algorithm */ 508 /* launch optimization algorithm */
474 tda18271_write_regs(fe, R_EP2, 1); 509 __tda18271_write_regs(fe, R_EP2, 1, false);
475 msleep(30); /* image high optimization completion */ 510 msleep(30); /* image high optimization completion */
476 511
477 /* return to normal mode */ 512 /* return to normal mode */
478 regs[R_EP4] = 0x64; 513 regs[R_EP4] = 0x64;
479 tda18271_write_regs(fe, R_EP4, 1); 514 __tda18271_write_regs(fe, R_EP4, 1, false);
480 515
481 /* synchronize */ 516 /* synchronize */
482 tda18271_write_regs(fe, R_EP1, 1); 517 __tda18271_write_regs(fe, R_EP1, 1, false);
518
519 i2c_unlock_adapter(priv->i2c_props.adap);
520 tda18271_i2c_gate_ctrl(fe, 0);
483 521
484 return 0; 522 return 0;
485} 523}