mirror of https://gitee.com/openkylin/linux.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 <dheitmueller@linuxtv.org> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
This commit is contained in:
parent
9beb0de9ad
commit
16af6f5a7f
|
@ -46,6 +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_30KHZ,
|
||||||
.input = {
|
.input = {
|
||||||
{
|
{
|
||||||
.type = AU0828_VMUX_TELEVISION,
|
.type = AU0828_VMUX_TELEVISION,
|
||||||
|
@ -70,6 +71,13 @@ struct au0828_board au0828_boards[] = {
|
||||||
.name = "Hauppauge HVR950Q",
|
.name = "Hauppauge HVR950Q",
|
||||||
.tuner_type = TUNER_XC5000,
|
.tuner_type = TUNER_XC5000,
|
||||||
.tuner_addr = 0x61,
|
.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 = {
|
.input = {
|
||||||
{
|
{
|
||||||
.type = AU0828_VMUX_TELEVISION,
|
.type = AU0828_VMUX_TELEVISION,
|
||||||
|
@ -94,16 +102,19 @@ struct au0828_board au0828_boards[] = {
|
||||||
.name = "Hauppauge HVR950Q rev xxF8",
|
.name = "Hauppauge HVR950Q rev xxF8",
|
||||||
.tuner_type = UNSET,
|
.tuner_type = UNSET,
|
||||||
.tuner_addr = ADDR_UNSET,
|
.tuner_addr = ADDR_UNSET,
|
||||||
|
.i2c_clk_divider = AU0828_I2C_CLK_250KHZ,
|
||||||
},
|
},
|
||||||
[AU0828_BOARD_DVICO_FUSIONHDTV7] = {
|
[AU0828_BOARD_DVICO_FUSIONHDTV7] = {
|
||||||
.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_250KHZ,
|
||||||
},
|
},
|
||||||
[AU0828_BOARD_HAUPPAUGE_WOODBURY] = {
|
[AU0828_BOARD_HAUPPAUGE_WOODBURY] = {
|
||||||
.name = "Hauppauge Woodbury",
|
.name = "Hauppauge Woodbury",
|
||||||
.tuner_type = UNSET,
|
.tuner_type = UNSET,
|
||||||
.tuner_addr = ADDR_UNSET,
|
.tuner_addr = ADDR_UNSET,
|
||||||
|
.i2c_clk_divider = AU0828_I2C_CLK_250KHZ,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -146,16 +146,9 @@ static int i2c_sendbytes(struct i2c_adapter *i2c_adap,
|
||||||
|
|
||||||
au0828_write(dev, AU0828_I2C_MULTIBYTE_MODE_2FF, 0x01);
|
au0828_write(dev, AU0828_I2C_MULTIBYTE_MODE_2FF, 0x01);
|
||||||
|
|
||||||
/* FIXME: There is a problem with i2c communications with xc5000 that
|
/* Set the I2C clock */
|
||||||
requires us to slow down the i2c clock until we have a better
|
au0828_write(dev, AU0828_I2C_CLK_DIVIDER_202,
|
||||||
strategy (such as using the secondary i2c bus to do firmware
|
dev->board.i2c_clk_divider);
|
||||||
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);
|
|
||||||
|
|
||||||
/* 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);
|
||||||
|
@ -230,16 +223,9 @@ static int i2c_readbytes(struct i2c_adapter *i2c_adap,
|
||||||
|
|
||||||
au0828_write(dev, AU0828_I2C_MULTIBYTE_MODE_2FF, 0x01);
|
au0828_write(dev, AU0828_I2C_MULTIBYTE_MODE_2FF, 0x01);
|
||||||
|
|
||||||
/* FIXME: There is a problem with i2c communications with xc5000 that
|
/* Set the I2C clock */
|
||||||
requires us to slow down the i2c clock until we have a better
|
au0828_write(dev, AU0828_I2C_CLK_DIVIDER_202,
|
||||||
strategy (such as using the secondary i2c bus to do firmware
|
dev->board.i2c_clk_divider);
|
||||||
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);
|
|
||||||
|
|
||||||
/* 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);
|
||||||
|
|
|
@ -81,6 +81,7 @@ struct au0828_board {
|
||||||
char *name;
|
char *name;
|
||||||
unsigned int tuner_type;
|
unsigned int tuner_type;
|
||||||
unsigned char tuner_addr;
|
unsigned char tuner_addr;
|
||||||
|
unsigned char i2c_clk_divider;
|
||||||
struct au0828_input input[AU0828_MAX_INPUT];
|
struct au0828_input input[AU0828_MAX_INPUT];
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue