Commit cfd0c77d authored by Mauro Carvalho Chehab's avatar Mauro Carvalho Chehab

[media] au0828: improve I2C speed

Commits 21dc61d3 and 7a1dd50b reduced the board I2C
speed to 20 MHz by default, due to a I2C stretch issue:
while xc5000 uses i2c stretch when a command is sent to it,
au0828 doesn't support this feature.

However, this is needed only for Xceive tuners. The other
I2C devices can work at the max speed.

So, revert the workarounds at board level, handling it at
I2C level, only when talking with xc5000.
Signed-off-by: default avatarMauro Carvalho Chehab <m.chehab@samsung.com>
parent 7f196789
...@@ -46,7 +46,7 @@ struct au0828_board au0828_boards[] = { ...@@ -46,7 +46,7 @@ struct au0828_board au0828_boards[] = {
.name = "Hauppauge HVR850", .name = "Hauppauge HVR850",
.tuner_type = TUNER_XC5000, .tuner_type = TUNER_XC5000,
.tuner_addr = 0x61, .tuner_addr = 0x61,
.i2c_clk_divider = AU0828_I2C_CLK_20KHZ, .i2c_clk_divider = AU0828_I2C_CLK_250KHZ,
.input = { .input = {
{ {
.type = AU0828_VMUX_TELEVISION, .type = AU0828_VMUX_TELEVISION,
...@@ -77,7 +77,7 @@ struct au0828_board au0828_boards[] = { ...@@ -77,7 +77,7 @@ struct au0828_board au0828_boards[] = {
stretch fits inside of a normal clock cycle, or else the stretch fits inside of a normal clock cycle, or else the
au0828 fails to set the STOP bit. A 30 KHz clock puts the au0828 fails to set the STOP bit. A 30 KHz clock puts the
clock pulse width at 18us */ clock pulse width at 18us */
.i2c_clk_divider = AU0828_I2C_CLK_20KHZ, .i2c_clk_divider = AU0828_I2C_CLK_250KHZ,
.input = { .input = {
{ {
.type = AU0828_VMUX_TELEVISION, .type = AU0828_VMUX_TELEVISION,
...@@ -108,7 +108,7 @@ struct au0828_board au0828_boards[] = { ...@@ -108,7 +108,7 @@ struct au0828_board au0828_boards[] = {
.name = "DViCO FusionHDTV USB", .name = "DViCO FusionHDTV USB",
.tuner_type = UNSET, .tuner_type = UNSET,
.tuner_addr = ADDR_UNSET, .tuner_addr = ADDR_UNSET,
.i2c_clk_divider = AU0828_I2C_CLK_20KHZ, .i2c_clk_divider = AU0828_I2C_CLK_250KHZ,
}, },
[AU0828_BOARD_HAUPPAUGE_WOODBURY] = { [AU0828_BOARD_HAUPPAUGE_WOODBURY] = {
.name = "Hauppauge Woodbury", .name = "Hauppauge Woodbury",
......
...@@ -141,25 +141,27 @@ static int i2c_sendbytes(struct i2c_adapter *i2c_adap, ...@@ -141,25 +141,27 @@ static int i2c_sendbytes(struct i2c_adapter *i2c_adap,
{ {
int i, strobe = 0; int i, strobe = 0;
struct au0828_dev *dev = i2c_adap->algo_data; struct au0828_dev *dev = i2c_adap->algo_data;
u8 i2c_speed = dev->board.i2c_clk_divider;
dprintk(4, "%s()\n", __func__); dprintk(4, "%s()\n", __func__);
au0828_write(dev, AU0828_I2C_MULTIBYTE_MODE_2FF, 0x01); au0828_write(dev, AU0828_I2C_MULTIBYTE_MODE_2FF, 0x01);
/* Set the I2C clock */
if (((dev->board.tuner_type == TUNER_XC5000) || if (((dev->board.tuner_type == TUNER_XC5000) ||
(dev->board.tuner_type == TUNER_XC5000C)) && (dev->board.tuner_type == TUNER_XC5000C)) &&
(dev->board.tuner_addr == msg->addr) && (dev->board.tuner_addr == msg->addr)) {
(msg->len == 64)) { /*
/* Hack to speed up firmware load. The xc5000 lets us do up * Due to I2C clock stretch, we need to use a lower speed
to 400 KHz when in firmware download mode */ * on xc5000 for commands. However, firmware transfer can
au0828_write(dev, AU0828_I2C_CLK_DIVIDER_202, * speed up to 400 KHz.
AU0828_I2C_CLK_250KHZ); */
} else { if (msg->len == 64)
/* Use the i2c clock speed in the board configuration */ i2c_speed = AU0828_I2C_CLK_250KHZ;
au0828_write(dev, AU0828_I2C_CLK_DIVIDER_202, else
dev->board.i2c_clk_divider); i2c_speed = AU0828_I2C_CLK_20KHZ;
} }
/* Set the I2C clock */
au0828_write(dev, AU0828_I2C_CLK_DIVIDER_202, i2c_speed);
/* Hardware needs 8 bit addresses */ /* Hardware needs 8 bit addresses */
au0828_write(dev, AU0828_I2C_DEST_ADDR_203, msg->addr << 1); au0828_write(dev, AU0828_I2C_DEST_ADDR_203, msg->addr << 1);
...@@ -228,15 +230,24 @@ static int i2c_readbytes(struct i2c_adapter *i2c_adap, ...@@ -228,15 +230,24 @@ static int i2c_readbytes(struct i2c_adapter *i2c_adap,
const struct i2c_msg *msg, int joined) const struct i2c_msg *msg, int joined)
{ {
struct au0828_dev *dev = i2c_adap->algo_data; struct au0828_dev *dev = i2c_adap->algo_data;
u8 i2c_speed = dev->board.i2c_clk_divider;
int i; int i;
dprintk(4, "%s()\n", __func__); dprintk(4, "%s()\n", __func__);
au0828_write(dev, AU0828_I2C_MULTIBYTE_MODE_2FF, 0x01); au0828_write(dev, AU0828_I2C_MULTIBYTE_MODE_2FF, 0x01);
/*
* Due to xc5000c clock stretch, we cannot use full speed at
* readings from xc5000, as otherwise they'll fail.
*/
if (((dev->board.tuner_type == TUNER_XC5000) ||
(dev->board.tuner_type == TUNER_XC5000C)) &&
(dev->board.tuner_addr == msg->addr))
i2c_speed = AU0828_I2C_CLK_20KHZ;
/* Set the I2C clock */ /* Set the I2C clock */
au0828_write(dev, AU0828_I2C_CLK_DIVIDER_202, au0828_write(dev, AU0828_I2C_CLK_DIVIDER_202, i2c_speed);
dev->board.i2c_clk_divider);
/* Hardware needs 8 bit addresses */ /* Hardware needs 8 bit addresses */
au0828_write(dev, AU0828_I2C_DEST_ADDR_203, msg->addr << 1); au0828_write(dev, AU0828_I2C_DEST_ADDR_203, msg->addr << 1);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment