diff options
author | Devin Heitmueller <devin.heitmueller@gmail.com> | 2008-11-16 18:17:14 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-06-16 17:21:04 -0400 |
commit | bdd335636a1afe1f30076915395874549be8cd35 (patch) | |
tree | 20a0e609aa1ed8709bbe2ccce20b31d8bcab33b3 /drivers/media/common/tuners | |
parent | 91bd625e217452f01fc568f4d2cb3ad5cee4640c (diff) |
V4L/DVB (11787): xc5000: cleanup i2c read routines
This patch centralizes the i2c read functions, and eliminates pass-through
function only called by one caller.
Make reading of xc5000 registers an atomic i2c transaction in case we're on a
multi-master bus.
Signed-off-by: Devin Heitmueller <devin.heitmueller@gmail.com>
Signed-off-by: Michael Krufky <mkrufky@linuxtv.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/common/tuners')
-rw-r--r-- | drivers/media/common/tuners/xc5000.c | 62 |
1 files changed, 20 insertions, 42 deletions
diff --git a/drivers/media/common/tuners/xc5000.c b/drivers/media/common/tuners/xc5000.c index be6981737fb1..759168af0e2a 100644 --- a/drivers/media/common/tuners/xc5000.c +++ b/drivers/media/common/tuners/xc5000.c | |||
@@ -193,7 +193,7 @@ static struct XC_TV_STANDARD XC5000_Standard[MAX_TV_STANDARD] = { | |||
193 | 193 | ||
194 | static int xc5000_is_firmware_loaded(struct dvb_frontend *fe); | 194 | static int xc5000_is_firmware_loaded(struct dvb_frontend *fe); |
195 | static int xc5000_writeregs(struct xc5000_priv *priv, u8 *buf, u8 len); | 195 | static int xc5000_writeregs(struct xc5000_priv *priv, u8 *buf, u8 len); |
196 | static int xc5000_readregs(struct xc5000_priv *priv, u8 *buf, u8 len); | 196 | static int xc5000_readreg(struct xc5000_priv *priv, u16 reg, u16 *val); |
197 | static int xc5000_TunerReset(struct dvb_frontend *fe); | 197 | static int xc5000_TunerReset(struct dvb_frontend *fe); |
198 | 198 | ||
199 | static int xc_send_i2c_data(struct xc5000_priv *priv, u8 *buf, int len) | 199 | static int xc_send_i2c_data(struct xc5000_priv *priv, u8 *buf, int len) |
@@ -202,10 +202,19 @@ static int xc_send_i2c_data(struct xc5000_priv *priv, u8 *buf, int len) | |||
202 | ? XC_RESULT_I2C_WRITE_FAILURE : XC_RESULT_SUCCESS; | 202 | ? XC_RESULT_I2C_WRITE_FAILURE : XC_RESULT_SUCCESS; |
203 | } | 203 | } |
204 | 204 | ||
205 | /* This routine is never used because the only time we read data from the | ||
206 | i2c bus is when we read registers, and we want that to be an atomic i2c | ||
207 | transaction in case we are on a multi-master bus */ | ||
205 | static int xc_read_i2c_data(struct xc5000_priv *priv, u8 *buf, int len) | 208 | static int xc_read_i2c_data(struct xc5000_priv *priv, u8 *buf, int len) |
206 | { | 209 | { |
207 | return xc5000_readregs(priv, buf, len) | 210 | struct i2c_msg msg = { .addr = priv->i2c_props.addr, |
208 | ? XC_RESULT_I2C_READ_FAILURE : XC_RESULT_SUCCESS; | 211 | .flags = I2C_M_RD, .buf = buf, .len = len }; |
212 | |||
213 | if (i2c_transfer(priv->i2c_props.adap, &msg, 1) != 1) { | ||
214 | printk(KERN_ERR "xc5000 I2C read failed (len=%i)\n", len); | ||
215 | return -EREMOTEIO; | ||
216 | } | ||
217 | return 0; | ||
209 | } | 218 | } |
210 | 219 | ||
211 | static void xc_wait(int wait_ms) | 220 | static void xc_wait(int wait_ms) |
@@ -275,25 +284,6 @@ static int xc_write_reg(struct xc5000_priv *priv, u16 regAddr, u16 i2cData) | |||
275 | return result; | 284 | return result; |
276 | } | 285 | } |
277 | 286 | ||
278 | static int xc_read_reg(struct xc5000_priv *priv, u16 regAddr, u16 *i2cData) | ||
279 | { | ||
280 | u8 buf[2]; | ||
281 | int result; | ||
282 | |||
283 | buf[0] = (regAddr >> 8) & 0xFF; | ||
284 | buf[1] = regAddr & 0xFF; | ||
285 | result = xc_send_i2c_data(priv, buf, 2); | ||
286 | if (result != XC_RESULT_SUCCESS) | ||
287 | return result; | ||
288 | |||
289 | result = xc_read_i2c_data(priv, buf, 2); | ||
290 | if (result != XC_RESULT_SUCCESS) | ||
291 | return result; | ||
292 | |||
293 | *i2cData = buf[0] * 256 + buf[1]; | ||
294 | return result; | ||
295 | } | ||
296 | |||
297 | static int xc_load_i2c_sequence(struct dvb_frontend *fe, const u8 *i2c_sequence) | 287 | static int xc_load_i2c_sequence(struct dvb_frontend *fe, const u8 *i2c_sequence) |
298 | { | 288 | { |
299 | struct xc5000_priv *priv = fe->tuner_priv; | 289 | struct xc5000_priv *priv = fe->tuner_priv; |
@@ -423,7 +413,7 @@ static int xc_set_IF_frequency(struct xc5000_priv *priv, u32 freq_khz) | |||
423 | 413 | ||
424 | static int xc_get_ADC_Envelope(struct xc5000_priv *priv, u16 *adc_envelope) | 414 | static int xc_get_ADC_Envelope(struct xc5000_priv *priv, u16 *adc_envelope) |
425 | { | 415 | { |
426 | return xc_read_reg(priv, XREG_ADC_ENV, adc_envelope); | 416 | return xc5000_readreg(priv, XREG_ADC_ENV, adc_envelope); |
427 | } | 417 | } |
428 | 418 | ||
429 | static int xc_get_frequency_error(struct xc5000_priv *priv, u32 *freq_error_hz) | 419 | static int xc_get_frequency_error(struct xc5000_priv *priv, u32 *freq_error_hz) |
@@ -432,7 +422,7 @@ static int xc_get_frequency_error(struct xc5000_priv *priv, u32 *freq_error_hz) | |||
432 | u16 regData; | 422 | u16 regData; |
433 | u32 tmp; | 423 | u32 tmp; |
434 | 424 | ||
435 | result = xc_read_reg(priv, XREG_FREQ_ERROR, ®Data); | 425 | result = xc5000_readreg(priv, XREG_FREQ_ERROR, ®Data); |
436 | if (result) | 426 | if (result) |
437 | return result; | 427 | return result; |
438 | 428 | ||
@@ -443,7 +433,7 @@ static int xc_get_frequency_error(struct xc5000_priv *priv, u32 *freq_error_hz) | |||
443 | 433 | ||
444 | static int xc_get_lock_status(struct xc5000_priv *priv, u16 *lock_status) | 434 | static int xc_get_lock_status(struct xc5000_priv *priv, u16 *lock_status) |
445 | { | 435 | { |
446 | return xc_read_reg(priv, XREG_LOCK, lock_status); | 436 | return xc5000_readreg(priv, XREG_LOCK, lock_status); |
447 | } | 437 | } |
448 | 438 | ||
449 | static int xc_get_version(struct xc5000_priv *priv, | 439 | static int xc_get_version(struct xc5000_priv *priv, |
@@ -453,7 +443,7 @@ static int xc_get_version(struct xc5000_priv *priv, | |||
453 | u16 data; | 443 | u16 data; |
454 | int result; | 444 | int result; |
455 | 445 | ||
456 | result = xc_read_reg(priv, XREG_VERSION, &data); | 446 | result = xc5000_readreg(priv, XREG_VERSION, &data); |
457 | if (result) | 447 | if (result) |
458 | return result; | 448 | return result; |
459 | 449 | ||
@@ -470,7 +460,7 @@ static int xc_get_hsync_freq(struct xc5000_priv *priv, u32 *hsync_freq_hz) | |||
470 | u16 regData; | 460 | u16 regData; |
471 | int result; | 461 | int result; |
472 | 462 | ||
473 | result = xc_read_reg(priv, XREG_HSYNC_FREQ, ®Data); | 463 | result = xc5000_readreg(priv, XREG_HSYNC_FREQ, ®Data); |
474 | if (result) | 464 | if (result) |
475 | return result; | 465 | return result; |
476 | 466 | ||
@@ -480,12 +470,12 @@ static int xc_get_hsync_freq(struct xc5000_priv *priv, u32 *hsync_freq_hz) | |||
480 | 470 | ||
481 | static int xc_get_frame_lines(struct xc5000_priv *priv, u16 *frame_lines) | 471 | static int xc_get_frame_lines(struct xc5000_priv *priv, u16 *frame_lines) |
482 | { | 472 | { |
483 | return xc_read_reg(priv, XREG_FRAME_LINES, frame_lines); | 473 | return xc5000_readreg(priv, XREG_FRAME_LINES, frame_lines); |
484 | } | 474 | } |
485 | 475 | ||
486 | static int xc_get_quality(struct xc5000_priv *priv, u16 *quality) | 476 | static int xc_get_quality(struct xc5000_priv *priv, u16 *quality) |
487 | { | 477 | { |
488 | return xc_read_reg(priv, XREG_QUALITY, quality); | 478 | return xc5000_readreg(priv, XREG_QUALITY, quality); |
489 | } | 479 | } |
490 | 480 | ||
491 | static u16 WaitForLock(struct xc5000_priv *priv) | 481 | static u16 WaitForLock(struct xc5000_priv *priv) |
@@ -535,7 +525,7 @@ static int xc5000_readreg(struct xc5000_priv *priv, u16 reg, u16 *val) | |||
535 | } | 525 | } |
536 | 526 | ||
537 | *val = (bval[0] << 8) | bval[1]; | 527 | *val = (bval[0] << 8) | bval[1]; |
538 | return 0; | 528 | return XC_RESULT_SUCCESS; |
539 | } | 529 | } |
540 | 530 | ||
541 | static int xc5000_writeregs(struct xc5000_priv *priv, u8 *buf, u8 len) | 531 | static int xc5000_writeregs(struct xc5000_priv *priv, u8 *buf, u8 len) |
@@ -551,18 +541,6 @@ static int xc5000_writeregs(struct xc5000_priv *priv, u8 *buf, u8 len) | |||
551 | return 0; | 541 | return 0; |
552 | } | 542 | } |
553 | 543 | ||
554 | static int xc5000_readregs(struct xc5000_priv *priv, u8 *buf, u8 len) | ||
555 | { | ||
556 | struct i2c_msg msg = { .addr = priv->i2c_props.addr, | ||
557 | .flags = I2C_M_RD, .buf = buf, .len = len }; | ||
558 | |||
559 | if (i2c_transfer(priv->i2c_props.adap, &msg, 1) != 1) { | ||
560 | printk(KERN_ERR "xc5000 I2C read failed (len=%i)\n", (int)len); | ||
561 | return -EREMOTEIO; | ||
562 | } | ||
563 | return 0; | ||
564 | } | ||
565 | |||
566 | static int xc5000_fwupload(struct dvb_frontend *fe) | 544 | static int xc5000_fwupload(struct dvb_frontend *fe) |
567 | { | 545 | { |
568 | struct xc5000_priv *priv = fe->tuner_priv; | 546 | struct xc5000_priv *priv = fe->tuner_priv; |