diff options
author | Erik Andren <erik.andren@gmail.com> | 2009-01-07 04:11:50 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-03-30 11:42:30 -0400 |
commit | 5658ae9007490c18853fbf112f1b3516f5949e62 (patch) | |
tree | afdd8f46d41a50709b178f0c36e8830ab689c793 /drivers | |
parent | d5b53f467bf5c2d0dbd5b043461275255073886d (diff) |
V4L/DVB (10342): gspca - stv06xx: Add ctrl caching to the vv6410.
Signed-off-by: Erik Andren <erik.andren@gmail.com>
Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c | 66 | ||||
-rw-r--r-- | drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h | 2 |
2 files changed, 43 insertions, 25 deletions
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c index a204b5891f63..69c77c932fc0 100644 --- a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c +++ b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c | |||
@@ -43,6 +43,7 @@ static struct v4l2_pix_format vv6410_mode[] = { | |||
43 | }; | 43 | }; |
44 | 44 | ||
45 | static const struct ctrl vv6410_ctrl[] = { | 45 | static const struct ctrl vv6410_ctrl[] = { |
46 | #define HFLIP_IDX 0 | ||
46 | { | 47 | { |
47 | { | 48 | { |
48 | .id = V4L2_CID_HFLIP, | 49 | .id = V4L2_CID_HFLIP, |
@@ -55,7 +56,9 @@ static const struct ctrl vv6410_ctrl[] = { | |||
55 | }, | 56 | }, |
56 | .set = vv6410_set_hflip, | 57 | .set = vv6410_set_hflip, |
57 | .get = vv6410_get_hflip | 58 | .get = vv6410_get_hflip |
58 | }, { | 59 | }, |
60 | #define VFLIP_IDX 1 | ||
61 | { | ||
59 | { | 62 | { |
60 | .id = V4L2_CID_VFLIP, | 63 | .id = V4L2_CID_VFLIP, |
61 | .type = V4L2_CTRL_TYPE_BOOLEAN, | 64 | .type = V4L2_CTRL_TYPE_BOOLEAN, |
@@ -67,7 +70,9 @@ static const struct ctrl vv6410_ctrl[] = { | |||
67 | }, | 70 | }, |
68 | .set = vv6410_set_vflip, | 71 | .set = vv6410_set_vflip, |
69 | .get = vv6410_get_vflip | 72 | .get = vv6410_get_vflip |
70 | }, { | 73 | }, |
74 | #define GAIN_IDX 2 | ||
75 | { | ||
71 | { | 76 | { |
72 | .id = V4L2_CID_GAIN, | 77 | .id = V4L2_CID_GAIN, |
73 | .type = V4L2_CTRL_TYPE_INTEGER, | 78 | .type = V4L2_CTRL_TYPE_INTEGER, |
@@ -85,23 +90,31 @@ static const struct ctrl vv6410_ctrl[] = { | |||
85 | static int vv6410_probe(struct sd *sd) | 90 | static int vv6410_probe(struct sd *sd) |
86 | { | 91 | { |
87 | u16 data; | 92 | u16 data; |
88 | int err; | 93 | int err, i; |
94 | s32 *sensor_settings; | ||
89 | 95 | ||
90 | err = stv06xx_read_sensor(sd, VV6410_DEVICEH, &data); | 96 | err = stv06xx_read_sensor(sd, VV6410_DEVICEH, &data); |
91 | |||
92 | if (err < 0) | 97 | if (err < 0) |
93 | return -ENODEV; | 98 | return -ENODEV; |
94 | 99 | ||
95 | if (data == 0x19) { | 100 | if (data == 0x19) { |
96 | info("vv6410 sensor detected"); | 101 | info("vv6410 sensor detected"); |
97 | 102 | ||
103 | sensor_settings = kmalloc(ARRAY_SIZE(vv6410_ctrl) * sizeof(s32), | ||
104 | GFP_KERNEL); | ||
105 | if (!sensor_settings) | ||
106 | return -ENOMEM; | ||
107 | |||
98 | sd->gspca_dev.cam.cam_mode = vv6410_mode; | 108 | sd->gspca_dev.cam.cam_mode = vv6410_mode; |
99 | sd->gspca_dev.cam.nmodes = ARRAY_SIZE(vv6410_mode); | 109 | sd->gspca_dev.cam.nmodes = ARRAY_SIZE(vv6410_mode); |
100 | sd->desc.ctrls = vv6410_ctrl; | 110 | sd->desc.ctrls = vv6410_ctrl; |
101 | sd->desc.nctrls = ARRAY_SIZE(vv6410_ctrl); | 111 | sd->desc.nctrls = ARRAY_SIZE(vv6410_ctrl); |
112 | |||
113 | for (i = 0; i < sd->desc.nctrls; i++) | ||
114 | sensor_settings[i] = vv6410_ctrl[i].qctrl.default_value; | ||
115 | sd->sensor_priv = sensor_settings; | ||
102 | return 0; | 116 | return 0; |
103 | } | 117 | } |
104 | |||
105 | return -ENODEV; | 118 | return -ENODEV; |
106 | } | 119 | } |
107 | 120 | ||
@@ -133,6 +146,12 @@ static int vv6410_init(struct sd *sd) | |||
133 | return (err < 0) ? err : 0; | 146 | return (err < 0) ? err : 0; |
134 | } | 147 | } |
135 | 148 | ||
149 | static void vv6410_disconnect(struct sd *sd) | ||
150 | { | ||
151 | sd->sensor = NULL; | ||
152 | kfree(sd->sensor_priv); | ||
153 | } | ||
154 | |||
136 | static int vv6410_start(struct sd *sd) | 155 | static int vv6410_start(struct sd *sd) |
137 | { | 156 | { |
138 | int err; | 157 | int err; |
@@ -209,17 +228,13 @@ static int vv6410_dump(struct sd *sd) | |||
209 | 228 | ||
210 | static int vv6410_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) | 229 | static int vv6410_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) |
211 | { | 230 | { |
212 | int err; | ||
213 | u16 i2c_data; | ||
214 | struct sd *sd = (struct sd *) gspca_dev; | 231 | struct sd *sd = (struct sd *) gspca_dev; |
232 | s32 *sensor_settings = sd->sensor_priv; | ||
215 | 233 | ||
216 | err = stv06xx_read_sensor(sd, VV6410_DATAFORMAT, &i2c_data); | 234 | *val = sensor_settings[HFLIP_IDX]; |
217 | |||
218 | *val = (i2c_data & VV6410_HFLIP) ? 1 : 0; | ||
219 | |||
220 | PDEBUG(D_V4L2, "Read horizontal flip %d", *val); | 235 | PDEBUG(D_V4L2, "Read horizontal flip %d", *val); |
221 | 236 | ||
222 | return (err < 0) ? err : 0; | 237 | return 0; |
223 | } | 238 | } |
224 | 239 | ||
225 | static int vv6410_set_hflip(struct gspca_dev *gspca_dev, __s32 val) | 240 | static int vv6410_set_hflip(struct gspca_dev *gspca_dev, __s32 val) |
@@ -227,6 +242,9 @@ static int vv6410_set_hflip(struct gspca_dev *gspca_dev, __s32 val) | |||
227 | int err; | 242 | int err; |
228 | u16 i2c_data; | 243 | u16 i2c_data; |
229 | struct sd *sd = (struct sd *) gspca_dev; | 244 | struct sd *sd = (struct sd *) gspca_dev; |
245 | s32 *sensor_settings = sd->sensor_priv; | ||
246 | |||
247 | sensor_settings[HFLIP_IDX] = val; | ||
230 | err = stv06xx_read_sensor(sd, VV6410_DATAFORMAT, &i2c_data); | 248 | err = stv06xx_read_sensor(sd, VV6410_DATAFORMAT, &i2c_data); |
231 | if (err < 0) | 249 | if (err < 0) |
232 | return err; | 250 | return err; |
@@ -244,17 +262,13 @@ static int vv6410_set_hflip(struct gspca_dev *gspca_dev, __s32 val) | |||
244 | 262 | ||
245 | static int vv6410_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) | 263 | static int vv6410_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) |
246 | { | 264 | { |
247 | int err; | ||
248 | u16 i2c_data; | ||
249 | struct sd *sd = (struct sd *) gspca_dev; | 265 | struct sd *sd = (struct sd *) gspca_dev; |
266 | s32 *sensor_settings = sd->sensor_priv; | ||
250 | 267 | ||
251 | err = stv06xx_read_sensor(sd, VV6410_DATAFORMAT, &i2c_data); | 268 | *val = sensor_settings[VFLIP_IDX]; |
252 | |||
253 | *val = (i2c_data & VV6410_VFLIP) ? 1 : 0; | ||
254 | |||
255 | PDEBUG(D_V4L2, "Read vertical flip %d", *val); | 269 | PDEBUG(D_V4L2, "Read vertical flip %d", *val); |
256 | 270 | ||
257 | return (err < 0) ? err : 0; | 271 | return 0; |
258 | } | 272 | } |
259 | 273 | ||
260 | static int vv6410_set_vflip(struct gspca_dev *gspca_dev, __s32 val) | 274 | static int vv6410_set_vflip(struct gspca_dev *gspca_dev, __s32 val) |
@@ -262,6 +276,9 @@ static int vv6410_set_vflip(struct gspca_dev *gspca_dev, __s32 val) | |||
262 | int err; | 276 | int err; |
263 | u16 i2c_data; | 277 | u16 i2c_data; |
264 | struct sd *sd = (struct sd *) gspca_dev; | 278 | struct sd *sd = (struct sd *) gspca_dev; |
279 | s32 *sensor_settings = sd->sensor_priv; | ||
280 | |||
281 | sensor_settings[VFLIP_IDX] = val; | ||
265 | err = stv06xx_read_sensor(sd, VV6410_DATAFORMAT, &i2c_data); | 282 | err = stv06xx_read_sensor(sd, VV6410_DATAFORMAT, &i2c_data); |
266 | if (err < 0) | 283 | if (err < 0) |
267 | return err; | 284 | return err; |
@@ -279,24 +296,23 @@ static int vv6410_set_vflip(struct gspca_dev *gspca_dev, __s32 val) | |||
279 | 296 | ||
280 | static int vv6410_get_analog_gain(struct gspca_dev *gspca_dev, __s32 *val) | 297 | static int vv6410_get_analog_gain(struct gspca_dev *gspca_dev, __s32 *val) |
281 | { | 298 | { |
282 | int err; | ||
283 | u16 i2c_data; | ||
284 | struct sd *sd = (struct sd *) gspca_dev; | 299 | struct sd *sd = (struct sd *) gspca_dev; |
300 | s32 *sensor_settings = sd->sensor_priv; | ||
285 | 301 | ||
286 | err = stv06xx_read_sensor(sd, VV6410_ANALOGGAIN, &i2c_data); | 302 | *val = sensor_settings[GAIN_IDX]; |
287 | |||
288 | *val = i2c_data & 0xf; | ||
289 | 303 | ||
290 | PDEBUG(D_V4L2, "Read analog gain %d", *val); | 304 | PDEBUG(D_V4L2, "Read analog gain %d", *val); |
291 | 305 | ||
292 | return (err < 0) ? err : 0; | 306 | return 0; |
293 | } | 307 | } |
294 | 308 | ||
295 | static int vv6410_set_analog_gain(struct gspca_dev *gspca_dev, __s32 val) | 309 | static int vv6410_set_analog_gain(struct gspca_dev *gspca_dev, __s32 val) |
296 | { | 310 | { |
297 | int err; | 311 | int err; |
298 | struct sd *sd = (struct sd *) gspca_dev; | 312 | struct sd *sd = (struct sd *) gspca_dev; |
313 | s32 *sensor_settings = sd->sensor_priv; | ||
299 | 314 | ||
315 | sensor_settings[GAIN_IDX] = val; | ||
300 | PDEBUG(D_V4L2, "Set analog gain to %d", val); | 316 | PDEBUG(D_V4L2, "Set analog gain to %d", val); |
301 | err = stv06xx_write_sensor(sd, VV6410_ANALOGGAIN, 0xf0 | (val & 0xf)); | 317 | err = stv06xx_write_sensor(sd, VV6410_ANALOGGAIN, 0xf0 | (val & 0xf)); |
302 | 318 | ||
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h index 1cb5f57651bd..95ac55891bd4 100644 --- a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h +++ b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h | |||
@@ -178,6 +178,7 @@ static int vv6410_start(struct sd *sd); | |||
178 | static int vv6410_init(struct sd *sd); | 178 | static int vv6410_init(struct sd *sd); |
179 | static int vv6410_stop(struct sd *sd); | 179 | static int vv6410_stop(struct sd *sd); |
180 | static int vv6410_dump(struct sd *sd); | 180 | static int vv6410_dump(struct sd *sd); |
181 | static void vv6410_disconnect(struct sd *sd); | ||
181 | 182 | ||
182 | /* V4L2 controls supported by the driver */ | 183 | /* V4L2 controls supported by the driver */ |
183 | static int vv6410_get_hflip(struct gspca_dev *gspca_dev, __s32 *val); | 184 | static int vv6410_get_hflip(struct gspca_dev *gspca_dev, __s32 *val); |
@@ -197,6 +198,7 @@ const struct stv06xx_sensor stv06xx_sensor_vv6410 = { | |||
197 | .start = vv6410_start, | 198 | .start = vv6410_start, |
198 | .stop = vv6410_stop, | 199 | .stop = vv6410_stop, |
199 | .dump = vv6410_dump, | 200 | .dump = vv6410_dump, |
201 | .disconnect = vv6410_disconnect, | ||
200 | }; | 202 | }; |
201 | 203 | ||
202 | /* If NULL, only single value to write, stored in len */ | 204 | /* If NULL, only single value to write, stored in len */ |