diff options
author | Devin Heitmueller <dheitmueller@linuxtv.org> | 2009-03-31 23:11:31 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-04-06 20:43:56 -0400 |
commit | 16af6f5a7fc2c56c4d8246b850b96324be2fec13 (patch) | |
tree | 90a463eaf04bc98b3f98df8217aeff38800c5196 /drivers/media/video/au0828 | |
parent | 9beb0de9adc789a7da22dac811b03ff342b27b63 (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.c | 11 | ||||
-rw-r--r-- | drivers/media/video/au0828/au0828-i2c.c | 26 | ||||
-rw-r--r-- | drivers/media/video/au0828/au0828.h | 1 |
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 | }; |