diff options
author | Erik Andr?n <erik.andren@gmail.com> | 2009-01-06 09:37:03 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-06-16 17:20:24 -0400 |
commit | a594fb4866ddebcb413577974654be8cffc37a1b (patch) | |
tree | 1f061466e5ea5da427a9bf9dff1b4e61f4d6590e /drivers/media/video/gspca/m5602/m5602_s5k4aa.c | |
parent | 05d7d9ced6fa6153735123412ba8bef329f80a53 (diff) |
V4L/DVB (11453): gspca - m5602-s5k4aa: Convert to use the v4l2 ctrl cache
Signed-off-by: Erik Andr?n <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/gspca/m5602/m5602_s5k4aa.c')
-rw-r--r-- | drivers/media/video/gspca/m5602/m5602_s5k4aa.c | 103 |
1 files changed, 54 insertions, 49 deletions
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c index 4306d596056d..84ca7532c754 100644 --- a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c +++ b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c | |||
@@ -65,6 +65,7 @@ static struct v4l2_pix_format s5k4aa_modes[] = { | |||
65 | }; | 65 | }; |
66 | 66 | ||
67 | const static struct ctrl s5k4aa_ctrls[] = { | 67 | const static struct ctrl s5k4aa_ctrls[] = { |
68 | #define VFLIP_IDX 0 | ||
68 | { | 69 | { |
69 | { | 70 | { |
70 | .id = V4L2_CID_VFLIP, | 71 | .id = V4L2_CID_VFLIP, |
@@ -77,8 +78,9 @@ const static struct ctrl s5k4aa_ctrls[] = { | |||
77 | }, | 78 | }, |
78 | .set = s5k4aa_set_vflip, | 79 | .set = s5k4aa_set_vflip, |
79 | .get = s5k4aa_get_vflip | 80 | .get = s5k4aa_get_vflip |
80 | 81 | }, | |
81 | }, { | 82 | #define HFLIP_IDX 1 |
83 | { | ||
82 | { | 84 | { |
83 | .id = V4L2_CID_HFLIP, | 85 | .id = V4L2_CID_HFLIP, |
84 | .type = V4L2_CTRL_TYPE_BOOLEAN, | 86 | .type = V4L2_CTRL_TYPE_BOOLEAN, |
@@ -90,8 +92,9 @@ const static struct ctrl s5k4aa_ctrls[] = { | |||
90 | }, | 92 | }, |
91 | .set = s5k4aa_set_hflip, | 93 | .set = s5k4aa_set_hflip, |
92 | .get = s5k4aa_get_hflip | 94 | .get = s5k4aa_get_hflip |
93 | 95 | }, | |
94 | }, { | 96 | #define GAIN_IDX 2 |
97 | { | ||
95 | { | 98 | { |
96 | .id = V4L2_CID_GAIN, | 99 | .id = V4L2_CID_GAIN, |
97 | .type = V4L2_CTRL_TYPE_INTEGER, | 100 | .type = V4L2_CTRL_TYPE_INTEGER, |
@@ -104,7 +107,9 @@ const static struct ctrl s5k4aa_ctrls[] = { | |||
104 | }, | 107 | }, |
105 | .set = s5k4aa_set_gain, | 108 | .set = s5k4aa_set_gain, |
106 | .get = s5k4aa_get_gain | 109 | .get = s5k4aa_get_gain |
107 | }, { | 110 | }, |
111 | #define EXPOSURE_IDX 3 | ||
112 | { | ||
108 | { | 113 | { |
109 | .id = V4L2_CID_EXPOSURE, | 114 | .id = V4L2_CID_EXPOSURE, |
110 | .type = V4L2_CTRL_TYPE_INTEGER, | 115 | .type = V4L2_CTRL_TYPE_INTEGER, |
@@ -127,6 +132,7 @@ int s5k4aa_probe(struct sd *sd) | |||
127 | u8 prod_id[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; | 132 | u8 prod_id[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; |
128 | const u8 expected_prod_id[6] = {0x00, 0x10, 0x00, 0x4b, 0x33, 0x75}; | 133 | const u8 expected_prod_id[6] = {0x00, 0x10, 0x00, 0x4b, 0x33, 0x75}; |
129 | int i, err = 0; | 134 | int i, err = 0; |
135 | s32 *sensor_settings; | ||
130 | 136 | ||
131 | if (force_sensor) { | 137 | if (force_sensor) { |
132 | if (force_sensor == S5K4AA_SENSOR) { | 138 | if (force_sensor == S5K4AA_SENSOR) { |
@@ -185,10 +191,19 @@ int s5k4aa_probe(struct sd *sd) | |||
185 | info("Detected a s5k4aa sensor"); | 191 | info("Detected a s5k4aa sensor"); |
186 | 192 | ||
187 | sensor_found: | 193 | sensor_found: |
194 | sensor_settings = kmalloc( | ||
195 | ARRAY_SIZE(s5k4aa_ctrls) * sizeof(s32), GFP_KERNEL); | ||
196 | if (!sensor_settings) | ||
197 | return -ENOMEM; | ||
198 | |||
188 | sd->gspca_dev.cam.cam_mode = s5k4aa_modes; | 199 | sd->gspca_dev.cam.cam_mode = s5k4aa_modes; |
189 | sd->gspca_dev.cam.nmodes = ARRAY_SIZE(s5k4aa_modes); | 200 | sd->gspca_dev.cam.nmodes = ARRAY_SIZE(s5k4aa_modes); |
190 | sd->desc->ctrls = s5k4aa_ctrls; | 201 | sd->desc->ctrls = s5k4aa_ctrls; |
191 | sd->desc->nctrls = ARRAY_SIZE(s5k4aa_ctrls); | 202 | sd->desc->nctrls = ARRAY_SIZE(s5k4aa_ctrls); |
203 | |||
204 | for (i = 0; i < ARRAY_SIZE(s5k4aa_ctrls); i++) | ||
205 | sensor_settings[i] = s5k4aa_ctrls[i].qctrl.default_value; | ||
206 | sd->sensor_priv = sensor_settings; | ||
192 | return 0; | 207 | return 0; |
193 | } | 208 | } |
194 | 209 | ||
@@ -301,31 +316,22 @@ int s5k4aa_power_down(struct sd *sd) | |||
301 | int s5k4aa_get_exposure(struct gspca_dev *gspca_dev, __s32 *val) | 316 | int s5k4aa_get_exposure(struct gspca_dev *gspca_dev, __s32 *val) |
302 | { | 317 | { |
303 | struct sd *sd = (struct sd *) gspca_dev; | 318 | struct sd *sd = (struct sd *) gspca_dev; |
304 | u8 data = S5K4AA_PAGE_MAP_2; | 319 | s32 *sensor_settings = sd->sensor_priv; |
305 | int err; | ||
306 | 320 | ||
307 | err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); | 321 | *val = sensor_settings[EXPOSURE_IDX]; |
308 | if (err < 0) | ||
309 | return err; | ||
310 | |||
311 | err = m5602_read_sensor(sd, S5K4AA_EXPOSURE_HI, &data, 1); | ||
312 | if (err < 0) | ||
313 | return err; | ||
314 | |||
315 | *val = data << 8; | ||
316 | err = m5602_read_sensor(sd, S5K4AA_EXPOSURE_LO, &data, 1); | ||
317 | *val |= data; | ||
318 | PDEBUG(D_V4L2, "Read exposure %d", *val); | 322 | PDEBUG(D_V4L2, "Read exposure %d", *val); |
319 | 323 | ||
320 | return err; | 324 | return 0; |
321 | } | 325 | } |
322 | 326 | ||
323 | int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val) | 327 | int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val) |
324 | { | 328 | { |
325 | struct sd *sd = (struct sd *) gspca_dev; | 329 | struct sd *sd = (struct sd *) gspca_dev; |
330 | s32 *sensor_settings = sd->sensor_priv; | ||
326 | u8 data = S5K4AA_PAGE_MAP_2; | 331 | u8 data = S5K4AA_PAGE_MAP_2; |
327 | int err; | 332 | int err; |
328 | 333 | ||
334 | sensor_settings[EXPOSURE_IDX] = val; | ||
329 | PDEBUG(D_V4L2, "Set exposure to %d", val); | 335 | PDEBUG(D_V4L2, "Set exposure to %d", val); |
330 | err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); | 336 | err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); |
331 | if (err < 0) | 337 | if (err < 0) |
@@ -343,26 +349,23 @@ int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val) | |||
343 | int s5k4aa_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) | 349 | int s5k4aa_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) |
344 | { | 350 | { |
345 | struct sd *sd = (struct sd *) gspca_dev; | 351 | struct sd *sd = (struct sd *) gspca_dev; |
346 | u8 data = S5K4AA_PAGE_MAP_2; | 352 | s32 *sensor_settings = sd->sensor_priv; |
347 | int err; | ||
348 | 353 | ||
349 | err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); | 354 | *val = sensor_settings[VFLIP_IDX]; |
350 | if (err < 0) | ||
351 | return err; | ||
352 | |||
353 | err = m5602_read_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); | ||
354 | *val = (data & S5K4AA_RM_V_FLIP) >> 7; | ||
355 | PDEBUG(D_V4L2, "Read vertical flip %d", *val); | 355 | PDEBUG(D_V4L2, "Read vertical flip %d", *val); |
356 | 356 | ||
357 | return err; | 357 | return 0; |
358 | } | 358 | } |
359 | 359 | ||
360 | int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val) | 360 | int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val) |
361 | { | 361 | { |
362 | struct sd *sd = (struct sd *) gspca_dev; | 362 | struct sd *sd = (struct sd *) gspca_dev; |
363 | s32 *sensor_settings = sd->sensor_priv; | ||
363 | u8 data = S5K4AA_PAGE_MAP_2; | 364 | u8 data = S5K4AA_PAGE_MAP_2; |
364 | int err; | 365 | int err; |
365 | 366 | ||
367 | sensor_settings[VFLIP_IDX] = val; | ||
368 | |||
366 | PDEBUG(D_V4L2, "Set vertical flip to %d", val); | 369 | PDEBUG(D_V4L2, "Set vertical flip to %d", val); |
367 | err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); | 370 | err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); |
368 | if (err < 0) | 371 | if (err < 0) |
@@ -370,6 +373,10 @@ int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val) | |||
370 | err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1); | 373 | err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1); |
371 | if (err < 0) | 374 | if (err < 0) |
372 | return err; | 375 | return err; |
376 | |||
377 | if (dmi_check_system(s5k4aa_vflip_dmi_table)) | ||
378 | val = !val; | ||
379 | |||
373 | data = ((data & ~S5K4AA_RM_V_FLIP) | 380 | data = ((data & ~S5K4AA_RM_V_FLIP) |
374 | | ((val & 0x01) << 7)); | 381 | | ((val & 0x01) << 7)); |
375 | err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1); | 382 | err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1); |
@@ -398,28 +405,24 @@ int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val) | |||
398 | int s5k4aa_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) | 405 | int s5k4aa_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) |
399 | { | 406 | { |
400 | struct sd *sd = (struct sd *) gspca_dev; | 407 | struct sd *sd = (struct sd *) gspca_dev; |
401 | u8 data = S5K4AA_PAGE_MAP_2; | 408 | s32 *sensor_settings = sd->sensor_priv; |
402 | int err; | ||
403 | 409 | ||
404 | err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); | 410 | *val = sensor_settings[HFLIP_IDX]; |
405 | if (err < 0) | ||
406 | return err; | ||
407 | |||
408 | err = m5602_read_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); | ||
409 | *val = (data & S5K4AA_RM_H_FLIP) >> 6; | ||
410 | PDEBUG(D_V4L2, "Read horizontal flip %d", *val); | 411 | PDEBUG(D_V4L2, "Read horizontal flip %d", *val); |
411 | 412 | ||
412 | return err; | 413 | return 0; |
413 | } | 414 | } |
414 | 415 | ||
415 | int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val) | 416 | int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val) |
416 | { | 417 | { |
417 | struct sd *sd = (struct sd *) gspca_dev; | 418 | struct sd *sd = (struct sd *) gspca_dev; |
419 | s32 *sensor_settings = sd->sensor_priv; | ||
418 | u8 data = S5K4AA_PAGE_MAP_2; | 420 | u8 data = S5K4AA_PAGE_MAP_2; |
419 | int err; | 421 | int err; |
420 | 422 | ||
421 | PDEBUG(D_V4L2, "Set horizontal flip to %d", | 423 | sensor_settings[HFLIP_IDX] = val; |
422 | val); | 424 | |
425 | PDEBUG(D_V4L2, "Set horizontal flip to %d", val); | ||
423 | err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); | 426 | err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); |
424 | if (err < 0) | 427 | if (err < 0) |
425 | return err; | 428 | return err; |
@@ -454,26 +457,22 @@ int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val) | |||
454 | int s5k4aa_get_gain(struct gspca_dev *gspca_dev, __s32 *val) | 457 | int s5k4aa_get_gain(struct gspca_dev *gspca_dev, __s32 *val) |
455 | { | 458 | { |
456 | struct sd *sd = (struct sd *) gspca_dev; | 459 | struct sd *sd = (struct sd *) gspca_dev; |
457 | u8 data = S5K4AA_PAGE_MAP_2; | 460 | s32 *sensor_settings = sd->sensor_priv; |
458 | int err; | ||
459 | |||
460 | err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); | ||
461 | if (err < 0) | ||
462 | return err; | ||
463 | 461 | ||
464 | err = m5602_read_sensor(sd, S5K4AA_GAIN_2, &data, 1); | 462 | *val = sensor_settings[GAIN_IDX]; |
465 | *val = data; | ||
466 | PDEBUG(D_V4L2, "Read gain %d", *val); | 463 | PDEBUG(D_V4L2, "Read gain %d", *val); |
467 | 464 | return 0; | |
468 | return err; | ||
469 | } | 465 | } |
470 | 466 | ||
471 | int s5k4aa_set_gain(struct gspca_dev *gspca_dev, __s32 val) | 467 | int s5k4aa_set_gain(struct gspca_dev *gspca_dev, __s32 val) |
472 | { | 468 | { |
473 | struct sd *sd = (struct sd *) gspca_dev; | 469 | struct sd *sd = (struct sd *) gspca_dev; |
470 | s32 *sensor_settings = sd->sensor_priv; | ||
474 | u8 data = S5K4AA_PAGE_MAP_2; | 471 | u8 data = S5K4AA_PAGE_MAP_2; |
475 | int err; | 472 | int err; |
476 | 473 | ||
474 | sensor_settings[GAIN_IDX] = val; | ||
475 | |||
477 | PDEBUG(D_V4L2, "Set gain to %d", val); | 476 | PDEBUG(D_V4L2, "Set gain to %d", val); |
478 | err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); | 477 | err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); |
479 | if (err < 0) | 478 | if (err < 0) |
@@ -485,6 +484,12 @@ int s5k4aa_set_gain(struct gspca_dev *gspca_dev, __s32 val) | |||
485 | return err; | 484 | return err; |
486 | } | 485 | } |
487 | 486 | ||
487 | void s5k4aa_disconnect(struct sd *sd) | ||
488 | { | ||
489 | sd->sensor = NULL; | ||
490 | kfree(sd->sensor_priv); | ||
491 | } | ||
492 | |||
488 | static void s5k4aa_dump_registers(struct sd *sd) | 493 | static void s5k4aa_dump_registers(struct sd *sd) |
489 | { | 494 | { |
490 | int address; | 495 | int address; |