aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorErik Andren <erik.andren@gmail.com>2009-01-07 04:11:50 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-03-30 11:42:30 -0400
commit5658ae9007490c18853fbf112f1b3516f5949e62 (patch)
treeafdd8f46d41a50709b178f0c36e8830ab689c793 /drivers
parentd5b53f467bf5c2d0dbd5b043461275255073886d (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.c66
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h2
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
45static const struct ctrl vv6410_ctrl[] = { 45static 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[] = {
85static int vv6410_probe(struct sd *sd) 90static 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
149static void vv6410_disconnect(struct sd *sd)
150{
151 sd->sensor = NULL;
152 kfree(sd->sensor_priv);
153}
154
136static int vv6410_start(struct sd *sd) 155static 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
210static int vv6410_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) 229static 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
225static int vv6410_set_hflip(struct gspca_dev *gspca_dev, __s32 val) 240static 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
245static int vv6410_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) 263static 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
260static int vv6410_set_vflip(struct gspca_dev *gspca_dev, __s32 val) 274static 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
280static int vv6410_get_analog_gain(struct gspca_dev *gspca_dev, __s32 *val) 297static 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
295static int vv6410_set_analog_gain(struct gspca_dev *gspca_dev, __s32 val) 309static 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);
178static int vv6410_init(struct sd *sd); 178static int vv6410_init(struct sd *sd);
179static int vv6410_stop(struct sd *sd); 179static int vv6410_stop(struct sd *sd);
180static int vv6410_dump(struct sd *sd); 180static int vv6410_dump(struct sd *sd);
181static void vv6410_disconnect(struct sd *sd);
181 182
182/* V4L2 controls supported by the driver */ 183/* V4L2 controls supported by the driver */
183static int vv6410_get_hflip(struct gspca_dev *gspca_dev, __s32 *val); 184static 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 */