aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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 221171eeb0c3..18c77afe2e4f 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}