aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/au0828
diff options
context:
space:
mode:
authorDevin Heitmueller <dheitmueller@linuxtv.org>2009-03-31 23:11:31 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-04-06 20:43:56 -0400
commit16af6f5a7fc2c56c4d8246b850b96324be2fec13 (patch)
tree90a463eaf04bc98b3f98df8217aeff38800c5196 /drivers/media/video/au0828
parent9beb0de9adc789a7da22dac811b03ff342b27b63 (diff)
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>
Diffstat (limited to 'drivers/media/video/au0828')
-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[] = {
46 .name = "Hauppauge HVR850", 46 .name = "Hauppauge HVR850",
47 .tuner_type = TUNER_XC5000, 47 .tuner_type = TUNER_XC5000,
48 .tuner_addr = 0x61, 48 .tuner_addr = 0x61,
49 .i2c_clk_divider = AU0828_I2C_CLK_30KHZ,
49 .input = { 50 .input = {
50 { 51 {
51 .type = AU0828_VMUX_TELEVISION, 52 .type = AU0828_VMUX_TELEVISION,
@@ -70,6 +71,13 @@ struct au0828_board au0828_boards[] = {
70 .name = "Hauppauge HVR950Q", 71 .name = "Hauppauge HVR950Q",
71 .tuner_type = TUNER_XC5000, 72 .tuner_type = TUNER_XC5000,
72 .tuner_addr = 0x61, 73 .tuner_addr = 0x61,
74 /* The au0828 hardware i2c implementation does not properly
75 support the xc5000's i2c clock stretching. So we need to
76 lower the clock frequency enough where the 15us clock
77 stretch fits inside of a normal clock cycle, or else the
78 au0828 fails to set the STOP bit. A 30 KHz clock puts the
79 clock pulse width at 18us */
80 .i2c_clk_divider = AU0828_I2C_CLK_30KHZ,
73 .input = { 81 .input = {
74 { 82 {
75 .type = AU0828_VMUX_TELEVISION, 83 .type = AU0828_VMUX_TELEVISION,
@@ -94,16 +102,19 @@ struct au0828_board au0828_boards[] = {
94 .name = "Hauppauge HVR950Q rev xxF8", 102 .name = "Hauppauge HVR950Q rev xxF8",
95 .tuner_type = UNSET, 103 .tuner_type = UNSET,
96 .tuner_addr = ADDR_UNSET, 104 .tuner_addr = ADDR_UNSET,
105 .i2c_clk_divider = AU0828_I2C_CLK_250KHZ,
97 }, 106 },
98 [AU0828_BOARD_DVICO_FUSIONHDTV7] = { 107 [AU0828_BOARD_DVICO_FUSIONHDTV7] = {
99 .name = "DViCO FusionHDTV USB", 108 .name = "DViCO FusionHDTV USB",
100 .tuner_type = UNSET, 109 .tuner_type = UNSET,
101 .tuner_addr = ADDR_UNSET, 110 .tuner_addr = ADDR_UNSET,
111 .i2c_clk_divider = AU0828_I2C_CLK_250KHZ,
102 }, 112 },
103 [AU0828_BOARD_HAUPPAUGE_WOODBURY] = { 113 [AU0828_BOARD_HAUPPAUGE_WOODBURY] = {
104 .name = "Hauppauge Woodbury", 114 .name = "Hauppauge Woodbury",
105 .tuner_type = UNSET, 115 .tuner_type = UNSET,
106 .tuner_addr = ADDR_UNSET, 116 .tuner_addr = ADDR_UNSET,
117 .i2c_clk_divider = AU0828_I2C_CLK_250KHZ,
107 }, 118 },
108}; 119};
109 120
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,
146 146
147 au0828_write(dev, AU0828_I2C_MULTIBYTE_MODE_2FF, 0x01); 147 au0828_write(dev, AU0828_I2C_MULTIBYTE_MODE_2FF, 0x01);
148 148
149 /* FIXME: There is a problem with i2c communications with xc5000 that 149 /* Set the I2C clock */
150 requires us to slow down the i2c clock until we have a better 150 au0828_write(dev, AU0828_I2C_CLK_DIVIDER_202,
151 strategy (such as using the secondary i2c bus to do firmware 151 dev->board.i2c_clk_divider);
152 loading */
153 if ((msg->addr << 1) == 0xc2)
154 au0828_write(dev, AU0828_I2C_CLK_DIVIDER_202,
155 AU0828_I2C_CLK_30KHZ);
156 else
157 au0828_write(dev, AU0828_I2C_CLK_DIVIDER_202,
158 AU0828_I2C_CLK_250KHZ);
159 152
160 /* Hardware needs 8 bit addresses */ 153 /* Hardware needs 8 bit addresses */
161 au0828_write(dev, AU0828_I2C_DEST_ADDR_203, msg->addr << 1); 154 au0828_write(dev, AU0828_I2C_DEST_ADDR_203, msg->addr << 1);
@@ -230,16 +223,9 @@ static int i2c_readbytes(struct i2c_adapter *i2c_adap,
230 223
231 au0828_write(dev, AU0828_I2C_MULTIBYTE_MODE_2FF, 0x01); 224 au0828_write(dev, AU0828_I2C_MULTIBYTE_MODE_2FF, 0x01);
232 225
233 /* FIXME: There is a problem with i2c communications with xc5000 that 226 /* Set the I2C clock */
234 requires us to slow down the i2c clock until we have a better 227 au0828_write(dev, AU0828_I2C_CLK_DIVIDER_202,
235 strategy (such as using the secondary i2c bus to do firmware 228 dev->board.i2c_clk_divider);
236 loading */
237 if ((msg->addr << 1) == 0xc2)
238 au0828_write(dev, AU0828_I2C_CLK_DIVIDER_202,
239 AU0828_I2C_CLK_30KHZ);
240 else
241 au0828_write(dev, AU0828_I2C_CLK_DIVIDER_202,
242 AU0828_I2C_CLK_250KHZ);
243 229
244 /* Hardware needs 8 bit addresses */ 230 /* Hardware needs 8 bit addresses */
245 au0828_write(dev, AU0828_I2C_DEST_ADDR_203, msg->addr << 1); 231 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 {
81 char *name; 81 char *name;
82 unsigned int tuner_type; 82 unsigned int tuner_type;
83 unsigned char tuner_addr; 83 unsigned char tuner_addr;
84 unsigned char i2c_clk_divider;
84 struct au0828_input input[AU0828_MAX_INPUT]; 85 struct au0828_input input[AU0828_MAX_INPUT];
85 86
86}; 87};