diff options
Diffstat (limited to 'drivers/media/dvb/frontends/dib0090.c')
-rw-r--r-- | drivers/media/dvb/frontends/dib0090.c | 71 |
1 files changed, 54 insertions, 17 deletions
diff --git a/drivers/media/dvb/frontends/dib0090.c b/drivers/media/dvb/frontends/dib0090.c index 52ff1a252a90..c9c935ae41e4 100644 --- a/drivers/media/dvb/frontends/dib0090.c +++ b/drivers/media/dvb/frontends/dib0090.c | |||
@@ -191,6 +191,11 @@ struct dib0090_state { | |||
191 | u8 wbd_calibration_gain; | 191 | u8 wbd_calibration_gain; |
192 | const struct dib0090_wbd_slope *current_wbd_table; | 192 | const struct dib0090_wbd_slope *current_wbd_table; |
193 | u16 wbdmux; | 193 | u16 wbdmux; |
194 | |||
195 | /* for the I2C transfer */ | ||
196 | struct i2c_msg msg[2]; | ||
197 | u8 i2c_write_buffer[3]; | ||
198 | u8 i2c_read_buffer[2]; | ||
194 | }; | 199 | }; |
195 | 200 | ||
196 | struct dib0090_fw_state { | 201 | struct dib0090_fw_state { |
@@ -198,27 +203,48 @@ struct dib0090_fw_state { | |||
198 | struct dvb_frontend *fe; | 203 | struct dvb_frontend *fe; |
199 | struct dib0090_identity identity; | 204 | struct dib0090_identity identity; |
200 | const struct dib0090_config *config; | 205 | const struct dib0090_config *config; |
206 | |||
207 | /* for the I2C transfer */ | ||
208 | struct i2c_msg msg; | ||
209 | u8 i2c_write_buffer[2]; | ||
210 | u8 i2c_read_buffer[2]; | ||
201 | }; | 211 | }; |
202 | 212 | ||
203 | static u16 dib0090_read_reg(struct dib0090_state *state, u8 reg) | 213 | static u16 dib0090_read_reg(struct dib0090_state *state, u8 reg) |
204 | { | 214 | { |
205 | u8 b[2]; | 215 | state->i2c_write_buffer[0] = reg; |
206 | struct i2c_msg msg[2] = { | 216 | |
207 | {.addr = state->config->i2c_address, .flags = 0, .buf = ®, .len = 1}, | 217 | memset(state->msg, 0, 2 * sizeof(struct i2c_msg)); |
208 | {.addr = state->config->i2c_address, .flags = I2C_M_RD, .buf = b, .len = 2}, | 218 | state->msg[0].addr = state->config->i2c_address; |
209 | }; | 219 | state->msg[0].flags = 0; |
210 | if (i2c_transfer(state->i2c, msg, 2) != 2) { | 220 | state->msg[0].buf = state->i2c_write_buffer; |
221 | state->msg[0].len = 1; | ||
222 | state->msg[1].addr = state->config->i2c_address; | ||
223 | state->msg[1].flags = I2C_M_RD; | ||
224 | state->msg[1].buf = state->i2c_read_buffer; | ||
225 | state->msg[1].len = 2; | ||
226 | |||
227 | if (i2c_transfer(state->i2c, state->msg, 2) != 2) { | ||
211 | printk(KERN_WARNING "DiB0090 I2C read failed\n"); | 228 | printk(KERN_WARNING "DiB0090 I2C read failed\n"); |
212 | return 0; | 229 | return 0; |
213 | } | 230 | } |
214 | return (b[0] << 8) | b[1]; | 231 | |
232 | return (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1]; | ||
215 | } | 233 | } |
216 | 234 | ||
217 | static int dib0090_write_reg(struct dib0090_state *state, u32 reg, u16 val) | 235 | static int dib0090_write_reg(struct dib0090_state *state, u32 reg, u16 val) |
218 | { | 236 | { |
219 | u8 b[3] = { reg & 0xff, val >> 8, val & 0xff }; | 237 | state->i2c_write_buffer[0] = reg & 0xff; |
220 | struct i2c_msg msg = {.addr = state->config->i2c_address, .flags = 0, .buf = b, .len = 3 }; | 238 | state->i2c_write_buffer[1] = val >> 8; |
221 | if (i2c_transfer(state->i2c, &msg, 1) != 1) { | 239 | state->i2c_write_buffer[2] = val & 0xff; |
240 | |||
241 | memset(state->msg, 0, sizeof(struct i2c_msg)); | ||
242 | state->msg[0].addr = state->config->i2c_address; | ||
243 | state->msg[0].flags = 0; | ||
244 | state->msg[0].buf = state->i2c_write_buffer; | ||
245 | state->msg[0].len = 3; | ||
246 | |||
247 | if (i2c_transfer(state->i2c, state->msg, 1) != 1) { | ||
222 | printk(KERN_WARNING "DiB0090 I2C write failed\n"); | 248 | printk(KERN_WARNING "DiB0090 I2C write failed\n"); |
223 | return -EREMOTEIO; | 249 | return -EREMOTEIO; |
224 | } | 250 | } |
@@ -227,20 +253,31 @@ static int dib0090_write_reg(struct dib0090_state *state, u32 reg, u16 val) | |||
227 | 253 | ||
228 | static u16 dib0090_fw_read_reg(struct dib0090_fw_state *state, u8 reg) | 254 | static u16 dib0090_fw_read_reg(struct dib0090_fw_state *state, u8 reg) |
229 | { | 255 | { |
230 | u8 b[2]; | 256 | state->i2c_write_buffer[0] = reg; |
231 | struct i2c_msg msg = {.addr = reg, .flags = I2C_M_RD, .buf = b, .len = 2 }; | 257 | |
232 | if (i2c_transfer(state->i2c, &msg, 1) != 1) { | 258 | memset(&state->msg, 0, sizeof(struct i2c_msg)); |
259 | state->msg.addr = reg; | ||
260 | state->msg.flags = I2C_M_RD; | ||
261 | state->msg.buf = state->i2c_read_buffer; | ||
262 | state->msg.len = 2; | ||
263 | if (i2c_transfer(state->i2c, &state->msg, 1) != 1) { | ||
233 | printk(KERN_WARNING "DiB0090 I2C read failed\n"); | 264 | printk(KERN_WARNING "DiB0090 I2C read failed\n"); |
234 | return 0; | 265 | return 0; |
235 | } | 266 | } |
236 | return (b[0] << 8) | b[1]; | 267 | return (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1]; |
237 | } | 268 | } |
238 | 269 | ||
239 | static int dib0090_fw_write_reg(struct dib0090_fw_state *state, u8 reg, u16 val) | 270 | static int dib0090_fw_write_reg(struct dib0090_fw_state *state, u8 reg, u16 val) |
240 | { | 271 | { |
241 | u8 b[2] = { val >> 8, val & 0xff }; | 272 | state->i2c_write_buffer[0] = val >> 8; |
242 | struct i2c_msg msg = {.addr = reg, .flags = 0, .buf = b, .len = 2 }; | 273 | state->i2c_write_buffer[1] = val & 0xff; |
243 | if (i2c_transfer(state->i2c, &msg, 1) != 1) { | 274 | |
275 | memset(&state->msg, 0, sizeof(struct i2c_msg)); | ||
276 | state->msg.addr = reg; | ||
277 | state->msg.flags = 0; | ||
278 | state->msg.buf = state->i2c_write_buffer; | ||
279 | state->msg.len = 2; | ||
280 | if (i2c_transfer(state->i2c, &state->msg, 1) != 1) { | ||
244 | printk(KERN_WARNING "DiB0090 I2C write failed\n"); | 281 | printk(KERN_WARNING "DiB0090 I2C write failed\n"); |
245 | return -EREMOTEIO; | 282 | return -EREMOTEIO; |
246 | } | 283 | } |