diff options
author | Erik Andr?n <erik.andren@gmail.com> | 2009-01-06 04:39:11 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-06-16 17:20:23 -0400 |
commit | 05d7d9ced6fa6153735123412ba8bef329f80a53 (patch) | |
tree | cb4ad542c8fa96c340e502d2eb8a0b064e217ef6 | |
parent | ac3d5bfecc362a91f38ad864f5d34c639f894214 (diff) |
V4L/DVB (11452): gspca - m5602-po1030: Convert to have a v4l2 ctrl cache
Let the po1030 have a local v4l2 ctrl cache as this minimizes the load on reading the registers and improves performance.
Signed-off-by: Erik Andr?n <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r-- | drivers/media/video/gspca/m5602/m5602_po1030.c | 140 | ||||
-rw-r--r-- | drivers/media/video/gspca/m5602/m5602_po1030.h | 2 |
2 files changed, 79 insertions, 63 deletions
diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.c b/drivers/media/video/gspca/m5602/m5602_po1030.c index eaddf488bad..27596fd6152 100644 --- a/drivers/media/video/gspca/m5602/m5602_po1030.c +++ b/drivers/media/video/gspca/m5602/m5602_po1030.c | |||
@@ -32,6 +32,7 @@ static struct v4l2_pix_format po1030_modes[] = { | |||
32 | }; | 32 | }; |
33 | 33 | ||
34 | const static struct ctrl po1030_ctrls[] = { | 34 | const static struct ctrl po1030_ctrls[] = { |
35 | #define GAIN_IDX 0 | ||
35 | { | 36 | { |
36 | { | 37 | { |
37 | .id = V4L2_CID_GAIN, | 38 | .id = V4L2_CID_GAIN, |
@@ -45,7 +46,9 @@ const static struct ctrl po1030_ctrls[] = { | |||
45 | }, | 46 | }, |
46 | .set = po1030_set_gain, | 47 | .set = po1030_set_gain, |
47 | .get = po1030_get_gain | 48 | .get = po1030_get_gain |
48 | }, { | 49 | }, |
50 | #define EXPOSURE_IDX 1 | ||
51 | { | ||
49 | { | 52 | { |
50 | .id = V4L2_CID_EXPOSURE, | 53 | .id = V4L2_CID_EXPOSURE, |
51 | .type = V4L2_CTRL_TYPE_INTEGER, | 54 | .type = V4L2_CTRL_TYPE_INTEGER, |
@@ -58,7 +61,9 @@ const static struct ctrl po1030_ctrls[] = { | |||
58 | }, | 61 | }, |
59 | .set = po1030_set_exposure, | 62 | .set = po1030_set_exposure, |
60 | .get = po1030_get_exposure | 63 | .get = po1030_get_exposure |
61 | }, { | 64 | }, |
65 | #define RED_BALANCE_IDX 2 | ||
66 | { | ||
62 | { | 67 | { |
63 | .id = V4L2_CID_RED_BALANCE, | 68 | .id = V4L2_CID_RED_BALANCE, |
64 | .type = V4L2_CTRL_TYPE_INTEGER, | 69 | .type = V4L2_CTRL_TYPE_INTEGER, |
@@ -71,7 +76,9 @@ const static struct ctrl po1030_ctrls[] = { | |||
71 | }, | 76 | }, |
72 | .set = po1030_set_red_balance, | 77 | .set = po1030_set_red_balance, |
73 | .get = po1030_get_red_balance | 78 | .get = po1030_get_red_balance |
74 | }, { | 79 | }, |
80 | #define BLUE_BALANCE_IDX 3 | ||
81 | { | ||
75 | { | 82 | { |
76 | .id = V4L2_CID_BLUE_BALANCE, | 83 | .id = V4L2_CID_BLUE_BALANCE, |
77 | .type = V4L2_CTRL_TYPE_INTEGER, | 84 | .type = V4L2_CTRL_TYPE_INTEGER, |
@@ -84,7 +91,9 @@ const static struct ctrl po1030_ctrls[] = { | |||
84 | }, | 91 | }, |
85 | .set = po1030_set_blue_balance, | 92 | .set = po1030_set_blue_balance, |
86 | .get = po1030_get_blue_balance | 93 | .get = po1030_get_blue_balance |
87 | }, { | 94 | }, |
95 | #define HFLIP_IDX 4 | ||
96 | { | ||
88 | { | 97 | { |
89 | .id = V4L2_CID_HFLIP, | 98 | .id = V4L2_CID_HFLIP, |
90 | .type = V4L2_CTRL_TYPE_BOOLEAN, | 99 | .type = V4L2_CTRL_TYPE_BOOLEAN, |
@@ -96,7 +105,9 @@ const static struct ctrl po1030_ctrls[] = { | |||
96 | }, | 105 | }, |
97 | .set = po1030_set_hflip, | 106 | .set = po1030_set_hflip, |
98 | .get = po1030_get_hflip | 107 | .get = po1030_get_hflip |
99 | }, { | 108 | }, |
109 | #define VFLIP_IDX 5 | ||
110 | { | ||
100 | { | 111 | { |
101 | .id = V4L2_CID_VFLIP, | 112 | .id = V4L2_CID_VFLIP, |
102 | .type = V4L2_CTRL_TYPE_BOOLEAN, | 113 | .type = V4L2_CTRL_TYPE_BOOLEAN, |
@@ -116,6 +127,7 @@ static void po1030_dump_registers(struct sd *sd); | |||
116 | int po1030_probe(struct sd *sd) | 127 | int po1030_probe(struct sd *sd) |
117 | { | 128 | { |
118 | u8 prod_id = 0, ver_id = 0, i; | 129 | u8 prod_id = 0, ver_id = 0, i; |
130 | s32 *sensor_settings = sd->sensor_priv; | ||
119 | 131 | ||
120 | if (force_sensor) { | 132 | if (force_sensor) { |
121 | if (force_sensor == PO1030_SENSOR) { | 133 | if (force_sensor == PO1030_SENSOR) { |
@@ -152,10 +164,19 @@ int po1030_probe(struct sd *sd) | |||
152 | return -ENODEV; | 164 | return -ENODEV; |
153 | 165 | ||
154 | sensor_found: | 166 | sensor_found: |
167 | sensor_settings = kmalloc( | ||
168 | ARRAY_SIZE(po1030_ctrls) * sizeof(s32), GFP_KERNEL); | ||
169 | if (!sensor_settings) | ||
170 | return -ENOMEM; | ||
171 | |||
155 | sd->gspca_dev.cam.cam_mode = po1030_modes; | 172 | sd->gspca_dev.cam.cam_mode = po1030_modes; |
156 | sd->gspca_dev.cam.nmodes = ARRAY_SIZE(po1030_modes); | 173 | sd->gspca_dev.cam.nmodes = ARRAY_SIZE(po1030_modes); |
157 | sd->desc->ctrls = po1030_ctrls; | 174 | sd->desc->ctrls = po1030_ctrls; |
158 | sd->desc->nctrls = ARRAY_SIZE(po1030_ctrls); | 175 | sd->desc->nctrls = ARRAY_SIZE(po1030_ctrls); |
176 | |||
177 | for (i = 0; i < ARRAY_SIZE(po1030_ctrls); i++) | ||
178 | sensor_settings[i] = po1030_ctrls[i].qctrl.default_value; | ||
179 | sd->sensor_priv = sensor_settings; | ||
159 | return 0; | 180 | return 0; |
160 | } | 181 | } |
161 | 182 | ||
@@ -195,30 +216,21 @@ int po1030_init(struct sd *sd) | |||
195 | int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val) | 216 | int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val) |
196 | { | 217 | { |
197 | struct sd *sd = (struct sd *) gspca_dev; | 218 | struct sd *sd = (struct sd *) gspca_dev; |
198 | u8 i2c_data; | 219 | s32 *sensor_settings = sd->sensor_priv; |
199 | int err; | ||
200 | |||
201 | err = m5602_read_sensor(sd, PO1030_REG_INTEGLINES_H, | ||
202 | &i2c_data, 1); | ||
203 | if (err < 0) | ||
204 | return err; | ||
205 | *val = (i2c_data << 8); | ||
206 | |||
207 | err = m5602_read_sensor(sd, PO1030_REG_INTEGLINES_M, | ||
208 | &i2c_data, 1); | ||
209 | *val |= i2c_data; | ||
210 | 220 | ||
221 | *val = sensor_settings[EXPOSURE_IDX]; | ||
211 | PDEBUG(D_V4L2, "Exposure read as %d", *val); | 222 | PDEBUG(D_V4L2, "Exposure read as %d", *val); |
212 | 223 | return 0; | |
213 | return err; | ||
214 | } | 224 | } |
215 | 225 | ||
216 | int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val) | 226 | int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val) |
217 | { | 227 | { |
218 | struct sd *sd = (struct sd *) gspca_dev; | 228 | struct sd *sd = (struct sd *) gspca_dev; |
229 | s32 *sensor_settings = sd->sensor_priv; | ||
219 | u8 i2c_data; | 230 | u8 i2c_data; |
220 | int err; | 231 | int err; |
221 | 232 | ||
233 | sensor_settings[EXPOSURE_IDX] = val; | ||
222 | PDEBUG(D_V4L2, "Set exposure to %d", val & 0xffff); | 234 | PDEBUG(D_V4L2, "Set exposure to %d", val & 0xffff); |
223 | 235 | ||
224 | i2c_data = ((val & 0xff00) >> 8); | 236 | i2c_data = ((val & 0xff00) >> 8); |
@@ -242,39 +254,49 @@ int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val) | |||
242 | int po1030_get_gain(struct gspca_dev *gspca_dev, __s32 *val) | 254 | int po1030_get_gain(struct gspca_dev *gspca_dev, __s32 *val) |
243 | { | 255 | { |
244 | struct sd *sd = (struct sd *) gspca_dev; | 256 | struct sd *sd = (struct sd *) gspca_dev; |
245 | u8 i2c_data; | 257 | s32 *sensor_settings = sd->sensor_priv; |
246 | int err; | ||
247 | 258 | ||
248 | err = m5602_read_sensor(sd, PO1030_REG_GLOBALGAIN, | 259 | *val = sensor_settings[GAIN_IDX]; |
249 | &i2c_data, 1); | ||
250 | *val = i2c_data; | ||
251 | PDEBUG(D_V4L2, "Read global gain %d", *val); | 260 | PDEBUG(D_V4L2, "Read global gain %d", *val); |
252 | 261 | return 0; | |
253 | return err; | ||
254 | } | 262 | } |
255 | 263 | ||
256 | int po1030_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) | 264 | int po1030_set_gain(struct gspca_dev *gspca_dev, __s32 val) |
257 | { | 265 | { |
258 | struct sd *sd = (struct sd *) gspca_dev; | 266 | struct sd *sd = (struct sd *) gspca_dev; |
267 | s32 *sensor_settings = sd->sensor_priv; | ||
259 | u8 i2c_data; | 268 | u8 i2c_data; |
260 | int err; | 269 | int err; |
261 | 270 | ||
262 | err = m5602_read_sensor(sd, PO1030_REG_CONTROL2, | 271 | sensor_settings[GAIN_IDX] = val; |
272 | |||
273 | i2c_data = val & 0xff; | ||
274 | PDEBUG(D_V4L2, "Set global gain to %d", i2c_data); | ||
275 | err = m5602_write_sensor(sd, PO1030_REG_GLOBALGAIN, | ||
263 | &i2c_data, 1); | 276 | &i2c_data, 1); |
277 | return err; | ||
278 | } | ||
264 | 279 | ||
265 | *val = (i2c_data >> 7) & 0x01 ; | 280 | int po1030_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) |
281 | { | ||
282 | struct sd *sd = (struct sd *) gspca_dev; | ||
283 | s32 *sensor_settings = sd->sensor_priv; | ||
266 | 284 | ||
285 | *val = sensor_settings[HFLIP_IDX]; | ||
267 | PDEBUG(D_V4L2, "Read hflip %d", *val); | 286 | PDEBUG(D_V4L2, "Read hflip %d", *val); |
268 | 287 | ||
269 | return err; | 288 | return 0; |
270 | } | 289 | } |
271 | 290 | ||
272 | int po1030_set_hflip(struct gspca_dev *gspca_dev, __s32 val) | 291 | int po1030_set_hflip(struct gspca_dev *gspca_dev, __s32 val) |
273 | { | 292 | { |
274 | struct sd *sd = (struct sd *) gspca_dev; | 293 | struct sd *sd = (struct sd *) gspca_dev; |
294 | s32 *sensor_settings = sd->sensor_priv; | ||
275 | u8 i2c_data; | 295 | u8 i2c_data; |
276 | int err; | 296 | int err; |
277 | 297 | ||
298 | sensor_settings[HFLIP_IDX] = val; | ||
299 | |||
278 | PDEBUG(D_V4L2, "Set hflip %d", val); | 300 | PDEBUG(D_V4L2, "Set hflip %d", val); |
279 | err = m5602_read_sensor(sd, PO1030_REG_CONTROL2, &i2c_data, 1); | 301 | err = m5602_read_sensor(sd, PO1030_REG_CONTROL2, &i2c_data, 1); |
280 | if (err < 0) | 302 | if (err < 0) |
@@ -291,25 +313,23 @@ int po1030_set_hflip(struct gspca_dev *gspca_dev, __s32 val) | |||
291 | int po1030_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) | 313 | int po1030_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) |
292 | { | 314 | { |
293 | struct sd *sd = (struct sd *) gspca_dev; | 315 | struct sd *sd = (struct sd *) gspca_dev; |
294 | u8 i2c_data; | 316 | s32 *sensor_settings = sd->sensor_priv; |
295 | int err; | ||
296 | |||
297 | err = m5602_read_sensor(sd, PO1030_REG_GLOBALGAIN, | ||
298 | &i2c_data, 1); | ||
299 | |||
300 | *val = (i2c_data >> 6) & 0x01; | ||
301 | 317 | ||
318 | *val= sensor_settings[VFLIP_IDX]; | ||
302 | PDEBUG(D_V4L2, "Read vflip %d", *val); | 319 | PDEBUG(D_V4L2, "Read vflip %d", *val); |
303 | 320 | ||
304 | return err; | 321 | return 0; |
305 | } | 322 | } |
306 | 323 | ||
307 | int po1030_set_vflip(struct gspca_dev *gspca_dev, __s32 val) | 324 | int po1030_set_vflip(struct gspca_dev *gspca_dev, __s32 val) |
308 | { | 325 | { |
309 | struct sd *sd = (struct sd *) gspca_dev; | 326 | struct sd *sd = (struct sd *) gspca_dev; |
327 | s32 *sensor_settings = sd->sensor_priv; | ||
310 | u8 i2c_data; | 328 | u8 i2c_data; |
311 | int err; | 329 | int err; |
312 | 330 | ||
331 | sensor_settings[VFLIP_IDX] = val; | ||
332 | |||
313 | PDEBUG(D_V4L2, "Set vflip %d", val); | 333 | PDEBUG(D_V4L2, "Set vflip %d", val); |
314 | err = m5602_read_sensor(sd, PO1030_REG_CONTROL2, &i2c_data, 1); | 334 | err = m5602_read_sensor(sd, PO1030_REG_CONTROL2, &i2c_data, 1); |
315 | if (err < 0) | 335 | if (err < 0) |
@@ -323,38 +343,25 @@ int po1030_set_vflip(struct gspca_dev *gspca_dev, __s32 val) | |||
323 | return err; | 343 | return err; |
324 | } | 344 | } |
325 | 345 | ||
326 | int po1030_set_gain(struct gspca_dev *gspca_dev, __s32 val) | ||
327 | { | ||
328 | struct sd *sd = (struct sd *) gspca_dev; | ||
329 | u8 i2c_data; | ||
330 | int err; | ||
331 | |||
332 | i2c_data = val & 0xff; | ||
333 | PDEBUG(D_V4L2, "Set global gain to %d", i2c_data); | ||
334 | err = m5602_write_sensor(sd, PO1030_REG_GLOBALGAIN, | ||
335 | &i2c_data, 1); | ||
336 | return err; | ||
337 | } | ||
338 | |||
339 | int po1030_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val) | 346 | int po1030_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val) |
340 | { | 347 | { |
341 | struct sd *sd = (struct sd *) gspca_dev; | 348 | struct sd *sd = (struct sd *) gspca_dev; |
342 | u8 i2c_data; | 349 | s32 *sensor_settings = sd->sensor_priv; |
343 | int err; | ||
344 | 350 | ||
345 | err = m5602_read_sensor(sd, PO1030_REG_RED_GAIN, | 351 | *val = sensor_settings[RED_BALANCE_IDX]; |
346 | &i2c_data, 1); | ||
347 | *val = i2c_data; | ||
348 | PDEBUG(D_V4L2, "Read red gain %d", *val); | 352 | PDEBUG(D_V4L2, "Read red gain %d", *val); |
349 | return err; | 353 | return 0; |
350 | } | 354 | } |
351 | 355 | ||
352 | int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val) | 356 | int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val) |
353 | { | 357 | { |
354 | struct sd *sd = (struct sd *) gspca_dev; | 358 | struct sd *sd = (struct sd *) gspca_dev; |
359 | s32 *sensor_settings = sd->sensor_priv; | ||
355 | u8 i2c_data; | 360 | u8 i2c_data; |
356 | int err; | 361 | int err; |
357 | 362 | ||
363 | sensor_settings[RED_BALANCE_IDX] = val; | ||
364 | |||
358 | i2c_data = val & 0xff; | 365 | i2c_data = val & 0xff; |
359 | PDEBUG(D_V4L2, "Set red gain to %d", i2c_data); | 366 | PDEBUG(D_V4L2, "Set red gain to %d", i2c_data); |
360 | err = m5602_write_sensor(sd, PO1030_REG_RED_GAIN, | 367 | err = m5602_write_sensor(sd, PO1030_REG_RED_GAIN, |
@@ -365,22 +372,23 @@ int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val) | |||
365 | int po1030_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val) | 372 | int po1030_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val) |
366 | { | 373 | { |
367 | struct sd *sd = (struct sd *) gspca_dev; | 374 | struct sd *sd = (struct sd *) gspca_dev; |
368 | u8 i2c_data; | 375 | s32 *sensor_settings = sd->sensor_priv; |
369 | int err; | ||
370 | 376 | ||
371 | err = m5602_read_sensor(sd, PO1030_REG_BLUE_GAIN, | 377 | *val = sensor_settings[BLUE_BALANCE_IDX]; |
372 | &i2c_data, 1); | ||
373 | *val = i2c_data; | ||
374 | PDEBUG(D_V4L2, "Read blue gain %d", *val); | 378 | PDEBUG(D_V4L2, "Read blue gain %d", *val); |
375 | 379 | ||
376 | return err; | 380 | return 0; |
377 | } | 381 | } |
378 | 382 | ||
379 | int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val) | 383 | int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val) |
380 | { | 384 | { |
381 | struct sd *sd = (struct sd *) gspca_dev; | 385 | struct sd *sd = (struct sd *) gspca_dev; |
386 | s32 *sensor_settings = sd->sensor_priv; | ||
382 | u8 i2c_data; | 387 | u8 i2c_data; |
383 | int err; | 388 | int err; |
389 | |||
390 | sensor_settings[BLUE_BALANCE_IDX] = val; | ||
391 | |||
384 | i2c_data = val & 0xff; | 392 | i2c_data = val & 0xff; |
385 | PDEBUG(D_V4L2, "Set blue gain to %d", i2c_data); | 393 | PDEBUG(D_V4L2, "Set blue gain to %d", i2c_data); |
386 | err = m5602_write_sensor(sd, PO1030_REG_BLUE_GAIN, | 394 | err = m5602_write_sensor(sd, PO1030_REG_BLUE_GAIN, |
@@ -394,6 +402,12 @@ int po1030_power_down(struct sd *sd) | |||
394 | return 0; | 402 | return 0; |
395 | } | 403 | } |
396 | 404 | ||
405 | void po1030_disconnect(struct sd *sd) | ||
406 | { | ||
407 | sd->sensor = NULL; | ||
408 | kfree(sd->sensor_priv); | ||
409 | } | ||
410 | |||
397 | static void po1030_dump_registers(struct sd *sd) | 411 | static void po1030_dump_registers(struct sd *sd) |
398 | { | 412 | { |
399 | int address; | 413 | int address; |
diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.h b/drivers/media/video/gspca/m5602/m5602_po1030.h index c10b1233581..4c04d1b9a1b 100644 --- a/drivers/media/video/gspca/m5602/m5602_po1030.h +++ b/drivers/media/video/gspca/m5602/m5602_po1030.h | |||
@@ -127,6 +127,7 @@ extern int dump_sensor; | |||
127 | int po1030_probe(struct sd *sd); | 127 | int po1030_probe(struct sd *sd); |
128 | int po1030_init(struct sd *sd); | 128 | int po1030_init(struct sd *sd); |
129 | int po1030_power_down(struct sd *sd); | 129 | int po1030_power_down(struct sd *sd); |
130 | void po1030_disconnect(struct sd *sd); | ||
130 | 131 | ||
131 | int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val); | 132 | int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val); |
132 | int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val); | 133 | int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val); |
@@ -150,6 +151,7 @@ static const struct m5602_sensor po1030 = { | |||
150 | .probe = po1030_probe, | 151 | .probe = po1030_probe, |
151 | .init = po1030_init, | 152 | .init = po1030_init, |
152 | .power_down = po1030_power_down, | 153 | .power_down = po1030_power_down, |
154 | .disconnect = po1030_disconnect, | ||
153 | }; | 155 | }; |
154 | 156 | ||
155 | static const unsigned char preinit_po1030[][3] = | 157 | static const unsigned char preinit_po1030[][3] = |