aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAntti Palosaari <crope@iki.fi>2013-03-08 14:54:09 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2013-03-21 18:06:00 -0400
commit3bf5e55299ac5a389a4e6b9991f900579a765172 (patch)
tree382b4a698493a3d57896c553b3e27f21ff5e5ff1
parent0c13c54d8527df03decf7c522f35886fb721f282 (diff)
[media] af9033: implement i/o optimized reg table writer
Use register address auto increment to reduce I/O when large register / values tables are written. Signed-off-by: Antti Palosaari <crope@iki.fi> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r--drivers/media/dvb-frontends/af9033.c47
1 files changed, 37 insertions, 10 deletions
diff --git a/drivers/media/dvb-frontends/af9033.c b/drivers/media/dvb-frontends/af9033.c
index 2dba516d5680..a777b4b944eb 100644
--- a/drivers/media/dvb-frontends/af9033.c
+++ b/drivers/media/dvb-frontends/af9033.c
@@ -156,6 +156,37 @@ static int af9033_rd_reg_mask(struct af9033_state *state, u32 reg, u8 *val,
156 return 0; 156 return 0;
157} 157}
158 158
159/* write reg val table using reg addr auto increment */
160static int af9033_wr_reg_val_tab(struct af9033_state *state,
161 const struct reg_val *tab, int tab_len)
162{
163 int ret, i, j;
164 u8 buf[tab_len];
165
166 dev_dbg(&state->i2c->dev, "%s: tab_len=%d\n", __func__, tab_len);
167
168 for (i = 0, j = 0; i < tab_len; i++) {
169 buf[j] = tab[i].val;
170
171 if (i == tab_len - 1 || tab[i].reg != tab[i + 1].reg - 1) {
172 ret = af9033_wr_regs(state, tab[i].reg - j, buf, j + 1);
173 if (ret < 0)
174 goto err;
175
176 j = 0;
177 } else {
178 j++;
179 }
180 }
181
182 return 0;
183
184err:
185 dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret);
186
187 return ret;
188}
189
159static u32 af9033_div(struct af9033_state *state, u32 a, u32 b, u32 x) 190static u32 af9033_div(struct af9033_state *state, u32 a, u32 b, u32 x)
160{ 191{
161 u32 r = 0, c = 0, i; 192 u32 r = 0, c = 0, i;
@@ -306,11 +337,9 @@ static int af9033_init(struct dvb_frontend *fe)
306 break; 337 break;
307 } 338 }
308 339
309 for (i = 0; i < len; i++) { 340 ret = af9033_wr_reg_val_tab(state, init, len);
310 ret = af9033_wr_reg(state, init[i].reg, init[i].val); 341 if (ret < 0)
311 if (ret < 0) 342 goto err;
312 goto err;
313 }
314 343
315 /* load tuner specific settings */ 344 /* load tuner specific settings */
316 dev_dbg(&state->i2c->dev, "%s: load tuner specific settings\n", 345 dev_dbg(&state->i2c->dev, "%s: load tuner specific settings\n",
@@ -371,11 +400,9 @@ static int af9033_init(struct dvb_frontend *fe)
371 goto err; 400 goto err;
372 } 401 }
373 402
374 for (i = 0; i < len; i++) { 403 ret = af9033_wr_reg_val_tab(state, init, len);
375 ret = af9033_wr_reg(state, init[i].reg, init[i].val); 404 if (ret < 0)
376 if (ret < 0) 405 goto err;
377 goto err;
378 }
379 406
380 if (state->cfg.ts_mode == AF9033_TS_MODE_SERIAL) { 407 if (state->cfg.ts_mode == AF9033_TS_MODE_SERIAL) {
381 ret = af9033_wr_reg_mask(state, 0x00d91c, 0x01, 0x01); 408 ret = af9033_wr_reg_mask(state, 0x00d91c, 0x01, 0x01);