From: Devin Heitmueller Date: Wed, 1 Apr 2009 03:11:31 +0000 (-0300) Subject: V4L/DVB (11343): au0828: make i2c clock speed per-board configurable X-Git-Url: http://pilppa.com/gitweb/?a=commitdiff_plain;h=16af6f5a7fc2c56c4d8246b850b96324be2fec13;p=linux-2.6-omap-h63xx.git 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 Signed-off-by: Mauro Carvalho Chehab --- diff --git a/drivers/media/video/au0828/au0828-cards.c b/drivers/media/video/au0828/au0828-cards.c index 1aabaa7e55b..abba48b154c 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 27dcfc69cd8..13e494365e7 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 6ed1a612973..b977915efbd 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]; };