aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/gspca/m5602/m5602_po1030.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/gspca/m5602/m5602_po1030.c')
-rw-r--r--drivers/media/video/gspca/m5602/m5602_po1030.c140
1 files changed, 77 insertions, 63 deletions
diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.c b/drivers/media/video/gspca/m5602/m5602_po1030.c
index eaddf488bad1..27596fd6152c 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
34const static struct ctrl po1030_ctrls[] = { 34const 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);
116int po1030_probe(struct sd *sd) 127int 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
154sensor_found: 166sensor_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)
195int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val) 216int 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
216int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val) 226int 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)
242int po1030_get_gain(struct gspca_dev *gspca_dev, __s32 *val) 254int 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
256int po1030_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) 264int 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 ; 280int 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
272int po1030_set_hflip(struct gspca_dev *gspca_dev, __s32 val) 291int 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)
291int po1030_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) 313int 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
307int po1030_set_vflip(struct gspca_dev *gspca_dev, __s32 val) 324int 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
326int 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
339int po1030_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val) 346int 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
352int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val) 356int 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)
365int po1030_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val) 372int 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
379int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val) 383int 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
405void po1030_disconnect(struct sd *sd)
406{
407 sd->sensor = NULL;
408 kfree(sd->sensor_priv);
409}
410
397static void po1030_dump_registers(struct sd *sd) 411static void po1030_dump_registers(struct sd *sd)
398{ 412{
399 int address; 413 int address;