aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/common
diff options
context:
space:
mode:
authorDevin Heitmueller <dheitmueller@kernellabs.com>2009-10-04 22:09:18 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2011-07-27 16:52:30 -0400
commit799ed11afe7694858584d1ed4e9ae2f9e48142ec (patch)
treeef723e6d86876d60ecbf8a95623939a147b13576 /drivers/media/common
parent8583fc834e704312fa9e7c756244895de55d800a (diff)
[media] xc4000: handle dib0700 broken i2c stretching
It was confirmed by DibCom that i2c stretching is broken in the i2c master on the dib7700. So we need to put a hack into the xc4000 driver to not complain in certain very specific cases where we know i2c stretching occurs. Signed-off-by: Devin Heitmueller <dheitmueller@kernellabs.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/common')
-rw-r--r--drivers/media/common/tuners/xc4000.c34
1 files changed, 29 insertions, 5 deletions
diff --git a/drivers/media/common/tuners/xc4000.c b/drivers/media/common/tuners/xc4000.c
index 2dacf209d427..b3b33d266b7c 100644
--- a/drivers/media/common/tuners/xc4000.c
+++ b/drivers/media/common/tuners/xc4000.c
@@ -89,6 +89,7 @@ struct xc4000_priv {
89 struct firmware_properties cur_fw; 89 struct firmware_properties cur_fw;
90 __u16 hwmodel; 90 __u16 hwmodel;
91 __u16 hwvers; 91 __u16 hwvers;
92 u8 ignore_i2c_write_errors;
92}; 93};
93 94
94/* Misc Defines */ 95/* Misc Defines */
@@ -255,8 +256,15 @@ static int xc_send_i2c_data(struct xc4000_priv *priv, u8 *buf, int len)
255 struct i2c_msg msg = { .addr = priv->i2c_props.addr, 256 struct i2c_msg msg = { .addr = priv->i2c_props.addr,
256 .flags = 0, .buf = buf, .len = len }; 257 .flags = 0, .buf = buf, .len = len };
257 if (i2c_transfer(priv->i2c_props.adap, &msg, 1) != 1) { 258 if (i2c_transfer(priv->i2c_props.adap, &msg, 1) != 1) {
258 printk(KERN_ERR "xc4000: I2C write failed (len=%i)\n", len); 259 if (priv->ignore_i2c_write_errors == 0) {
259 return XC_RESULT_I2C_WRITE_FAILURE; 260 printk(KERN_ERR "xc4000: I2C write failed (len=%i)\n",
261 len);
262 if (len == 4) {
263 printk("bytes %02x %02x %02x %02x\n", buf[0],
264 buf[1], buf[2], buf[3]);
265 }
266 return XC_RESULT_I2C_WRITE_FAILURE;
267 }
260 } 268 }
261 return XC_RESULT_SUCCESS; 269 return XC_RESULT_SUCCESS;
262} 270}
@@ -371,10 +379,15 @@ static int xc_SetTVStandard(struct xc4000_priv *priv,
371 __func__, 379 __func__,
372 XC4000_Standard[priv->video_standard].Name); 380 XC4000_Standard[priv->video_standard].Name);
373 381
382 /* Don't complain when the request fails because of i2c stretching */
383 priv->ignore_i2c_write_errors = 1;
384
374 ret = xc_write_reg(priv, XREG_VIDEO_MODE, VideoMode); 385 ret = xc_write_reg(priv, XREG_VIDEO_MODE, VideoMode);
375 if (ret == XC_RESULT_SUCCESS) 386 if (ret == XC_RESULT_SUCCESS)
376 ret = xc_write_reg(priv, XREG_AUDIO_MODE, AudioMode); 387 ret = xc_write_reg(priv, XREG_AUDIO_MODE, AudioMode);
377 388
389 priv->ignore_i2c_write_errors = 0;
390
378 return ret; 391 return ret;
379} 392}
380 393
@@ -506,10 +519,16 @@ static u16 WaitForLock(struct xc4000_priv *priv)
506static int xc_tune_channel(struct xc4000_priv *priv, u32 freq_hz, int mode) 519static int xc_tune_channel(struct xc4000_priv *priv, u32 freq_hz, int mode)
507{ 520{
508 int found = 0; 521 int found = 0;
522 int result = 0;
509 523
510 dprintk(1, "%s(%u)\n", __func__, freq_hz); 524 dprintk(1, "%s(%u)\n", __func__, freq_hz);
511 525
512 if (xc_set_RF_frequency(priv, freq_hz) != XC_RESULT_SUCCESS) 526 /* Don't complain when the request fails because of i2c stretching */
527 priv->ignore_i2c_write_errors = 1;
528 result = xc_set_RF_frequency(priv, freq_hz);
529 priv->ignore_i2c_write_errors = 0;
530
531 if (result != XC_RESULT_SUCCESS)
513 return 0; 532 return 0;
514 533
515 if (mode == XC_TUNE_ANALOG) { 534 if (mode == XC_TUNE_ANALOG) {
@@ -721,8 +740,13 @@ static int load_firmware(struct dvb_frontend *fe, unsigned int type,
721 p = priv->firm[pos].ptr; 740 p = priv->firm[pos].ptr;
722 printk("firmware length = %d\n", priv->firm[pos].size); 741 printk("firmware length = %d\n", priv->firm[pos].size);
723 742
743 /* Don't complain when the request fails because of i2c stretching */
744 priv->ignore_i2c_write_errors = 1;
745
724 rc = xc_load_i2c_sequence(fe, p); 746 rc = xc_load_i2c_sequence(fe, p);
725 747
748 priv->ignore_i2c_write_errors = 0;
749
726 return rc; 750 return rc;
727} 751}
728 752
@@ -954,7 +978,7 @@ static int check_firmware(struct dvb_frontend *fe, unsigned int type,
954 int rc = 0, is_retry = 0; 978 int rc = 0, is_retry = 0;
955 u16 version, hwmodel; 979 u16 version, hwmodel;
956 v4l2_std_id std0; 980 v4l2_std_id std0;
957 u8 hw_major, hw_minor, fw_major, fw_minor; 981 u8 hw_major, hw_minor, fw_major, fw_minor;
958 982
959 dprintk(1, "%s called\n", __func__); 983 dprintk(1, "%s called\n", __func__);
960 984
@@ -1071,7 +1095,7 @@ skip_std_specific:
1071check_device: 1095check_device:
1072 rc = xc4000_readreg(priv, XREG_PRODUCT_ID, &hwmodel); 1096 rc = xc4000_readreg(priv, XREG_PRODUCT_ID, &hwmodel);
1073 1097
1074 if (xc_get_version(priv, &hw_major, &hw_minor, &fw_major, 1098 if (xc_get_version(priv, &hw_major, &hw_minor, &fw_major,
1075 &fw_minor) != XC_RESULT_SUCCESS) { 1099 &fw_minor) != XC_RESULT_SUCCESS) {
1076 printk("Unable to read tuner registers.\n"); 1100 printk("Unable to read tuner registers.\n");
1077 goto fail; 1101 goto fail;