summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDevin Heitmueller <dheitmueller@linuxtv.org>2009-04-01 00:11:31 -0300
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-04-06 21:43:56 -0300
commit16af6f5a7fc2c56c4d8246b850b96324be2fec13 (patch)
tree90a463eaf04bc98b3f98df8217aeff38800c5196
parent9beb0de9adc789a7da22dac811b03ff342b27b63 (diff)
downloadlinux-16af6f5a7fc2c56c4d8246b850b96324be2fec13.tar.bz2
V4L/DVB (11343): au0828: make i2c clock speed per-board configurable
Setup the i2c clock speed to be definable on a per-board basis. This allows us to explicitly set the clock speed to 30 KHz on the 950q, and also gets rid of code which sets it on a basis of what chip the i2c master is talking to at any given time (which could have caused issues because i2c slaves should never receive commands at a clock higher than their supported clock speed). Signed-off-by: Devin Heitmueller <dheitmueller@linuxtv.org> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r--drivers/media/video/au0828/au0828-cards.c11
-rw-r--r--drivers/media/video/au0828/au0828-i2c.c26
-rw-r--r--drivers/media/video/au0828/au0828.h1
3 files changed, 18 insertions, 20 deletions
diff --git a/drivers/media/video/au0828/au0828-cards.c b/drivers/media/video/au0828/au0828-cards.c
index 1aabaa7e55bb..abba48b154c5 100644
--- a/drivers/media/video/au0828/au0828-cards.c
+++ b/drivers/media/video/au0828/au0828-cards.c
@@ -46,6 +46,7 @@ struct au0828_board au0828_boards[] = {
.name = "Hauppauge HVR850",
.tuner_type = TUNER_XC5000,
.tuner_addr = 0x61,
+ .i2c_clk_divider = AU0828_I2C_CLK_30KHZ,
.input = {
{
.type = AU0828_VMUX_TELEVISION,
@@ -70,6 +71,13 @@ struct au0828_board au0828_boards[] = {
.name = "Hauppauge HVR950Q",
.tuner_type = TUNER_XC5000,
.tuner_addr = 0x61,
+ /* The au0828 hardware i2c implementation does not properly
+ support the xc5000's i2c clock stretching. So we need to
+ lower the clock frequency enough where the 15us clock
+ stretch fits inside of a normal clock cycle, or else the
+ au0828 fails to set the STOP bit. A 30 KHz clock puts the
+ clock pulse width at 18us */
+ .i2c_clk_divider = AU0828_I2C_CLK_30KHZ,
.input = {
{
.type = AU0828_VMUX_TELEVISION,
@@ -94,16 +102,19 @@ struct au0828_board au0828_boards[] = {
.name = "Hauppauge HVR950Q rev xxF8",
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
+ .i2c_clk_divider = AU0828_I2C_CLK_250KHZ,
},
[AU0828_BOARD_DVICO_FUSIONHDTV7] = {
.name = "DViCO FusionHDTV USB",
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
+ .i2c_clk_divider = AU0828_I2C_CLK_250KHZ,
},
[AU0828_BOARD_HAUPPAUGE_WOODBURY] = {
.name = "Hauppauge Woodbury",
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
+ .i2c_clk_divider = AU0828_I2C_CLK_250KHZ,
},
};
diff --git a/drivers/media/video/au0828/au0828-i2c.c b/drivers/media/video/au0828/au0828-i2c.c
index 27dcfc69cd80..13e494365e70 100644
--- a/drivers/media/video/au0828/au0828-i2c.c
+++ b/drivers/media/video/au0828/au0828-i2c.c
@@ -146,16 +146,9 @@ static int i2c_sendbytes(struct i2c_adapter *i2c_adap,
au0828_write(dev, AU0828_I2C_MULTIBYTE_MODE_2FF, 0x01);
- /* FIXME: There is a problem with i2c communications with xc5000 that
- requires us to slow down the i2c clock until we have a better
- strategy (such as using the secondary i2c bus to do firmware
- loading */
- if ((msg->addr << 1) == 0xc2)
- au0828_write(dev, AU0828_I2C_CLK_DIVIDER_202,
- AU0828_I2C_CLK_30KHZ);
- else
- au0828_write(dev, AU0828_I2C_CLK_DIVIDER_202,
- AU0828_I2C_CLK_250KHZ);
+ /* Set the I2C clock */
+ au0828_write(dev, AU0828_I2C_CLK_DIVIDER_202,
+ dev->board.i2c_clk_divider);
/* Hardware needs 8 bit addresses */
au0828_write(dev, AU0828_I2C_DEST_ADDR_203, msg->addr << 1);
@@ -230,16 +223,9 @@ static int i2c_readbytes(struct i2c_adapter *i2c_adap,
au0828_write(dev, AU0828_I2C_MULTIBYTE_MODE_2FF, 0x01);
- /* FIXME: There is a problem with i2c communications with xc5000 that
- requires us to slow down the i2c clock until we have a better
- strategy (such as using the secondary i2c bus to do firmware
- loading */
- if ((msg->addr << 1) == 0xc2)
- au0828_write(dev, AU0828_I2C_CLK_DIVIDER_202,
- AU0828_I2C_CLK_30KHZ);
- else
- au0828_write(dev, AU0828_I2C_CLK_DIVIDER_202,
- AU0828_I2C_CLK_250KHZ);
+ /* Set the I2C clock */
+ au0828_write(dev, AU0828_I2C_CLK_DIVIDER_202,
+ dev->board.i2c_clk_divider);
/* Hardware needs 8 bit addresses */
au0828_write(dev, AU0828_I2C_DEST_ADDR_203, msg->addr << 1);
diff --git a/drivers/media/video/au0828/au0828.h b/drivers/media/video/au0828/au0828.h
index 6ed1a6129731..b977915efbd0 100644
--- a/drivers/media/video/au0828/au0828.h
+++ b/drivers/media/video/au0828/au0828.h
@@ -81,6 +81,7 @@ struct au0828_board {
char *name;
unsigned int tuner_type;
unsigned char tuner_addr;
+ unsigned char i2c_clk_divider;
struct au0828_input input[AU0828_MAX_INPUT];
};