aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/usb/au0828/au0828-i2c.c
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <m.chehab@samsung.com>2014-07-25 13:02:14 -0400
committerMauro Carvalho Chehab <m.chehab@samsung.com>2014-07-30 14:44:25 -0400
commitcfd0c77d0830d33288e9da17aa10db3a61de601a (patch)
tree5c5bdd468bc6a3b7c7f4ddba3fed70c4e8d9743e /drivers/media/usb/au0828/au0828-i2c.c
parent7f196789b3ffee243b681d3e7dab8890038db856 (diff)
[media] au0828: improve I2C speed
Commits 21dc61d3c0a4 and 7a1dd50b89d4 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: Mauro Carvalho Chehab <m.chehab@samsung.com>
Diffstat (limited to 'drivers/media/usb/au0828/au0828-i2c.c')
-rw-r--r--drivers/media/usb/au0828/au0828-i2c.c37
1 files changed, 24 insertions, 13 deletions
diff --git a/drivers/media/usb/au0828/au0828-i2c.c b/drivers/media/usb/au0828/au0828-i2c.c
index 17ec3651b10e..daaeaf1b089c 100644
--- a/drivers/media/usb/au0828/au0828-i2c.c
+++ b/drivers/media/usb/au0828/au0828-i2c.c
@@ -141,25 +141,27 @@ static int i2c_sendbytes(struct i2c_adapter *i2c_adap,
141{ 141{
142 int i, strobe = 0; 142 int i, strobe = 0;
143 struct au0828_dev *dev = i2c_adap->algo_data; 143 struct au0828_dev *dev = i2c_adap->algo_data;
144 u8 i2c_speed = dev->board.i2c_clk_divider;
144 145
145 dprintk(4, "%s()\n", __func__); 146 dprintk(4, "%s()\n", __func__);
146 147
147 au0828_write(dev, AU0828_I2C_MULTIBYTE_MODE_2FF, 0x01); 148 au0828_write(dev, AU0828_I2C_MULTIBYTE_MODE_2FF, 0x01);
148 149
149 /* Set the I2C clock */
150 if (((dev->board.tuner_type == TUNER_XC5000) || 150 if (((dev->board.tuner_type == TUNER_XC5000) ||
151 (dev->board.tuner_type == TUNER_XC5000C)) && 151 (dev->board.tuner_type == TUNER_XC5000C)) &&
152 (dev->board.tuner_addr == msg->addr) && 152 (dev->board.tuner_addr == msg->addr)) {
153 (msg->len == 64)) { 153 /*
154 /* Hack to speed up firmware load. The xc5000 lets us do up 154 * Due to I2C clock stretch, we need to use a lower speed
155 to 400 KHz when in firmware download mode */ 155 * on xc5000 for commands. However, firmware transfer can
156 au0828_write(dev, AU0828_I2C_CLK_DIVIDER_202, 156 * speed up to 400 KHz.
157 AU0828_I2C_CLK_250KHZ); 157 */
158 } else { 158 if (msg->len == 64)
159 /* Use the i2c clock speed in the board configuration */ 159 i2c_speed = AU0828_I2C_CLK_250KHZ;
160 au0828_write(dev, AU0828_I2C_CLK_DIVIDER_202, 160 else
161 dev->board.i2c_clk_divider); 161 i2c_speed = AU0828_I2C_CLK_20KHZ;
162 } 162 }
163 /* Set the I2C clock */
164 au0828_write(dev, AU0828_I2C_CLK_DIVIDER_202, i2c_speed);
163 165
164 /* Hardware needs 8 bit addresses */ 166 /* Hardware needs 8 bit addresses */
165 au0828_write(dev, AU0828_I2C_DEST_ADDR_203, msg->addr << 1); 167 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 const struct i2c_msg *msg, int joined) 230 const struct i2c_msg *msg, int joined)
229{ 231{
230 struct au0828_dev *dev = i2c_adap->algo_data; 232 struct au0828_dev *dev = i2c_adap->algo_data;
233 u8 i2c_speed = dev->board.i2c_clk_divider;
231 int i; 234 int i;
232 235
233 dprintk(4, "%s()\n", __func__); 236 dprintk(4, "%s()\n", __func__);
234 237
235 au0828_write(dev, AU0828_I2C_MULTIBYTE_MODE_2FF, 0x01); 238 au0828_write(dev, AU0828_I2C_MULTIBYTE_MODE_2FF, 0x01);
236 239
240 /*
241 * Due to xc5000c clock stretch, we cannot use full speed at
242 * readings from xc5000, as otherwise they'll fail.
243 */
244 if (((dev->board.tuner_type == TUNER_XC5000) ||
245 (dev->board.tuner_type == TUNER_XC5000C)) &&
246 (dev->board.tuner_addr == msg->addr))
247 i2c_speed = AU0828_I2C_CLK_20KHZ;
248
237 /* Set the I2C clock */ 249 /* Set the I2C clock */
238 au0828_write(dev, AU0828_I2C_CLK_DIVIDER_202, 250 au0828_write(dev, AU0828_I2C_CLK_DIVIDER_202, i2c_speed);
239 dev->board.i2c_clk_divider);
240 251
241 /* Hardware needs 8 bit addresses */ 252 /* Hardware needs 8 bit addresses */
242 au0828_write(dev, AU0828_I2C_DEST_ADDR_203, msg->addr << 1); 253 au0828_write(dev, AU0828_I2C_DEST_ADDR_203, msg->addr << 1);