~ubuntu-branches/ubuntu/saucy/linux-ti-omap4/saucy-proposed

« back to all changes in this revision

Viewing changes to drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c

  • Committer: Package Import Robot
  • Author(s): Paolo Pisati, Paolo Pisati, Stefan Bader, Upstream Kernel Changes
  • Date: 2012-08-15 17:17:43 UTC
  • Revision ID: package-import@ubuntu.com-20120815171743-h5wnuf51xe7pvdid
Tags: 3.5.0-207.13
[ Paolo Pisati ]

* Start new release

[ Stefan Bader ]

* (config) Enable getabis to use local package copies

[ Upstream Kernel Changes ]

* fixup: gargabe collect iva_seq[0|1] init
* [Config] enable all SND_OMAP_SOC_*s
* fixup: cm2xxx_3xxx.o is needed for omap2_cm_read|write_reg
* fixup: add some snd_soc_dai* helper functions
* fixup: s/snd_soc_dpcm_params/snd_soc_dpcm/g
* fixup: typo, no_host_mode and useless SDP4430 init
* fixup: enable again aess hwmod

Show diffs side-by-side

added added

removed removed

Lines of Context:
48
48
 
49
49
#include "stv06xx_pb0100.h"
50
50
 
51
 
static const struct ctrl pb0100_ctrl[] = {
52
 
#define GAIN_IDX 0
53
 
        {
54
 
                {
55
 
                        .id             = V4L2_CID_GAIN,
56
 
                        .type           = V4L2_CTRL_TYPE_INTEGER,
57
 
                        .name           = "Gain",
58
 
                        .minimum        = 0,
59
 
                        .maximum        = 255,
60
 
                        .step           = 1,
61
 
                        .default_value  = 128
62
 
                },
63
 
                .set = pb0100_set_gain,
64
 
                .get = pb0100_get_gain
65
 
        },
66
 
#define RED_BALANCE_IDX 1
67
 
        {
68
 
                {
69
 
                        .id             = V4L2_CID_RED_BALANCE,
70
 
                        .type           = V4L2_CTRL_TYPE_INTEGER,
71
 
                        .name           = "Red Balance",
72
 
                        .minimum        = -255,
73
 
                        .maximum        = 255,
74
 
                        .step           = 1,
75
 
                        .default_value  = 0
76
 
                },
77
 
                .set = pb0100_set_red_balance,
78
 
                .get = pb0100_get_red_balance
79
 
        },
80
 
#define BLUE_BALANCE_IDX 2
81
 
        {
82
 
                {
83
 
                        .id             = V4L2_CID_BLUE_BALANCE,
84
 
                        .type           = V4L2_CTRL_TYPE_INTEGER,
85
 
                        .name           = "Blue Balance",
86
 
                        .minimum        = -255,
87
 
                        .maximum        = 255,
88
 
                        .step           = 1,
89
 
                        .default_value  = 0
90
 
                },
91
 
                .set = pb0100_set_blue_balance,
92
 
                .get = pb0100_get_blue_balance
93
 
        },
94
 
#define EXPOSURE_IDX 3
95
 
        {
96
 
                {
97
 
                        .id             = V4L2_CID_EXPOSURE,
98
 
                        .type           = V4L2_CTRL_TYPE_INTEGER,
99
 
                        .name           = "Exposure",
100
 
                        .minimum        = 0,
101
 
                        .maximum        = 511,
102
 
                        .step           = 1,
103
 
                        .default_value  = 12
104
 
                },
105
 
                .set = pb0100_set_exposure,
106
 
                .get = pb0100_get_exposure
107
 
        },
108
 
#define AUTOGAIN_IDX 4
109
 
        {
110
 
                {
111
 
                        .id             = V4L2_CID_AUTOGAIN,
112
 
                        .type           = V4L2_CTRL_TYPE_BOOLEAN,
113
 
                        .name           = "Automatic Gain and Exposure",
114
 
                        .minimum        = 0,
115
 
                        .maximum        = 1,
116
 
                        .step           = 1,
117
 
                        .default_value  = 1
118
 
                },
119
 
                .set = pb0100_set_autogain,
120
 
                .get = pb0100_get_autogain
121
 
        },
122
 
#define AUTOGAIN_TARGET_IDX 5
123
 
        {
124
 
                {
125
 
                        .id             = V4L2_CTRL_CLASS_USER + 0x1000,
126
 
                        .type           = V4L2_CTRL_TYPE_INTEGER,
127
 
                        .name           = "Automatic Gain Target",
128
 
                        .minimum        = 0,
129
 
                        .maximum        = 255,
130
 
                        .step           = 1,
131
 
                        .default_value  = 128
132
 
                },
133
 
                .set = pb0100_set_autogain_target,
134
 
                .get = pb0100_get_autogain_target
135
 
        },
136
 
#define NATURAL_IDX 6
137
 
        {
138
 
                {
139
 
                        .id             = V4L2_CTRL_CLASS_USER + 0x1001,
140
 
                        .type           = V4L2_CTRL_TYPE_BOOLEAN,
141
 
                        .name           = "Natural Light Source",
142
 
                        .minimum        = 0,
143
 
                        .maximum        = 1,
144
 
                        .step           = 1,
145
 
                        .default_value  = 1
146
 
                },
147
 
                .set = pb0100_set_natural,
148
 
                .get = pb0100_get_natural
149
 
        }
 
51
struct pb0100_ctrls {
 
52
        struct { /* one big happy control cluster... */
 
53
                struct v4l2_ctrl *autogain;
 
54
                struct v4l2_ctrl *gain;
 
55
                struct v4l2_ctrl *exposure;
 
56
                struct v4l2_ctrl *red;
 
57
                struct v4l2_ctrl *blue;
 
58
                struct v4l2_ctrl *natural;
 
59
        };
 
60
        struct v4l2_ctrl *target;
150
61
};
151
62
 
152
63
static struct v4l2_pix_format pb0100_mode[] = {
174
85
        }
175
86
};
176
87
 
 
88
static int pb0100_s_ctrl(struct v4l2_ctrl *ctrl)
 
89
{
 
90
        struct gspca_dev *gspca_dev =
 
91
                container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
 
92
        struct sd *sd = (struct sd *)gspca_dev;
 
93
        struct pb0100_ctrls *ctrls = sd->sensor_priv;
 
94
        int err = -EINVAL;
 
95
 
 
96
        switch (ctrl->id) {
 
97
        case V4L2_CID_AUTOGAIN:
 
98
                err = pb0100_set_autogain(gspca_dev, ctrl->val);
 
99
                if (err)
 
100
                        break;
 
101
                if (ctrl->val)
 
102
                        break;
 
103
                err = pb0100_set_gain(gspca_dev, ctrls->gain->val);
 
104
                if (err)
 
105
                        break;
 
106
                err = pb0100_set_exposure(gspca_dev, ctrls->exposure->val);
 
107
                break;
 
108
        case V4L2_CTRL_CLASS_USER + 0x1001:
 
109
                err = pb0100_set_autogain_target(gspca_dev, ctrl->val);
 
110
                break;
 
111
        }
 
112
        return err;
 
113
}
 
114
 
 
115
static const struct v4l2_ctrl_ops pb0100_ctrl_ops = {
 
116
        .s_ctrl = pb0100_s_ctrl,
 
117
};
 
118
 
 
119
static int pb0100_init_controls(struct sd *sd)
 
120
{
 
121
        struct v4l2_ctrl_handler *hdl = &sd->gspca_dev.ctrl_handler;
 
122
        struct pb0100_ctrls *ctrls;
 
123
        static const struct v4l2_ctrl_config autogain_target = {
 
124
                .ops = &pb0100_ctrl_ops,
 
125
                .id = V4L2_CTRL_CLASS_USER + 0x1000,
 
126
                .type = V4L2_CTRL_TYPE_INTEGER,
 
127
                .name = "Automatic Gain Target",
 
128
                .max = 255,
 
129
                .step = 1,
 
130
                .def = 128,
 
131
        };
 
132
        static const struct v4l2_ctrl_config natural_light = {
 
133
                .ops = &pb0100_ctrl_ops,
 
134
                .id = V4L2_CTRL_CLASS_USER + 0x1001,
 
135
                .type = V4L2_CTRL_TYPE_BOOLEAN,
 
136
                .name = "Natural Light Source",
 
137
                .max = 1,
 
138
                .step = 1,
 
139
                .def = 1,
 
140
        };
 
141
 
 
142
        ctrls = kzalloc(sizeof(*ctrls), GFP_KERNEL);
 
143
        if (!ctrls)
 
144
                return -ENOMEM;
 
145
 
 
146
        v4l2_ctrl_handler_init(hdl, 6);
 
147
        ctrls->autogain = v4l2_ctrl_new_std(hdl, &pb0100_ctrl_ops,
 
148
                        V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
 
149
        ctrls->exposure = v4l2_ctrl_new_std(hdl, &pb0100_ctrl_ops,
 
150
                        V4L2_CID_EXPOSURE, 0, 511, 1, 12);
 
151
        ctrls->gain = v4l2_ctrl_new_std(hdl, &pb0100_ctrl_ops,
 
152
                        V4L2_CID_GAIN, 0, 255, 1, 128);
 
153
        ctrls->red = v4l2_ctrl_new_std(hdl, &pb0100_ctrl_ops,
 
154
                        V4L2_CID_RED_BALANCE, -255, 255, 1, 0);
 
155
        ctrls->blue = v4l2_ctrl_new_std(hdl, &pb0100_ctrl_ops,
 
156
                        V4L2_CID_BLUE_BALANCE, -255, 255, 1, 0);
 
157
        ctrls->natural = v4l2_ctrl_new_custom(hdl, &natural_light, NULL);
 
158
        ctrls->target = v4l2_ctrl_new_custom(hdl, &autogain_target, NULL);
 
159
        if (hdl->error) {
 
160
                kfree(ctrls);
 
161
                return hdl->error;
 
162
        }
 
163
        sd->sensor_priv = ctrls;
 
164
        v4l2_ctrl_auto_cluster(5, &ctrls->autogain, 0, false);
 
165
        return 0;
 
166
}
 
167
 
177
168
static int pb0100_probe(struct sd *sd)
178
169
{
179
170
        u16 sensor;
180
 
        int i, err;
181
 
        s32 *sensor_settings;
 
171
        int err;
182
172
 
183
173
        err = stv06xx_read_sensor(sd, PB_IDENT, &sensor);
184
174
 
185
175
        if (err < 0)
186
176
                return -ENODEV;
187
 
 
188
 
        if ((sensor >> 8) == 0x64) {
189
 
                sensor_settings = kmalloc(
190
 
                                ARRAY_SIZE(pb0100_ctrl) * sizeof(s32),
191
 
                                GFP_KERNEL);
192
 
                if (!sensor_settings)
193
 
                        return -ENOMEM;
194
 
 
195
 
                pr_info("Photobit pb0100 sensor detected\n");
196
 
 
197
 
                sd->gspca_dev.cam.cam_mode = pb0100_mode;
198
 
                sd->gspca_dev.cam.nmodes = ARRAY_SIZE(pb0100_mode);
199
 
                sd->desc.ctrls = pb0100_ctrl;
200
 
                sd->desc.nctrls = ARRAY_SIZE(pb0100_ctrl);
201
 
                for (i = 0; i < sd->desc.nctrls; i++)
202
 
                        sensor_settings[i] = pb0100_ctrl[i].qctrl.default_value;
203
 
                sd->sensor_priv = sensor_settings;
204
 
 
205
 
                return 0;
206
 
        }
207
 
 
208
 
        return -ENODEV;
 
177
        if ((sensor >> 8) != 0x64)
 
178
                return -ENODEV;
 
179
 
 
180
        pr_info("Photobit pb0100 sensor detected\n");
 
181
 
 
182
        sd->gspca_dev.cam.cam_mode = pb0100_mode;
 
183
        sd->gspca_dev.cam.nmodes = ARRAY_SIZE(pb0100_mode);
 
184
 
 
185
        return 0;
209
186
}
210
187
 
211
188
static int pb0100_start(struct sd *sd)
214
191
        struct usb_host_interface *alt;
215
192
        struct usb_interface *intf;
216
193
        struct cam *cam = &sd->gspca_dev.cam;
217
 
        s32 *sensor_settings = sd->sensor_priv;
218
194
        u32 mode = cam->cam_mode[sd->gspca_dev.curr_mode].priv;
219
195
 
220
196
        intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface);
255
231
                stv06xx_write_bridge(sd, STV_SCAN_RATE, 0x20);
256
232
        }
257
233
 
258
 
        /* set_gain also sets red and blue balance */
259
 
        pb0100_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]);
260
 
        pb0100_set_exposure(&sd->gspca_dev, sensor_settings[EXPOSURE_IDX]);
261
 
        pb0100_set_autogain_target(&sd->gspca_dev,
262
 
                                   sensor_settings[AUTOGAIN_TARGET_IDX]);
263
 
        pb0100_set_autogain(&sd->gspca_dev, sensor_settings[AUTOGAIN_IDX]);
264
 
 
265
234
        err = stv06xx_write_sensor(sd, PB_CONTROL, BIT(5)|BIT(3)|BIT(1));
266
235
        PDEBUG(D_STREAM, "Started stream, status: %d", err);
267
236
 
285
254
        return (err < 0) ? err : 0;
286
255
}
287
256
 
288
 
static void pb0100_disconnect(struct sd *sd)
289
 
{
290
 
        sd->sensor = NULL;
291
 
        kfree(sd->sensor_priv);
292
 
}
293
 
 
294
257
/* FIXME: Sort the init commands out and put them into tables,
295
258
          this is only for getting the camera to work */
296
259
/* FIXME: No error handling for now,
362
325
        return 0;
363
326
}
364
327
 
365
 
static int pb0100_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
366
 
{
367
 
        struct sd *sd = (struct sd *) gspca_dev;
368
 
        s32 *sensor_settings = sd->sensor_priv;
369
 
 
370
 
        *val = sensor_settings[GAIN_IDX];
371
 
 
372
 
        return 0;
373
 
}
374
 
 
375
328
static int pb0100_set_gain(struct gspca_dev *gspca_dev, __s32 val)
376
329
{
377
330
        int err;
378
331
        struct sd *sd = (struct sd *) gspca_dev;
379
 
        s32 *sensor_settings = sd->sensor_priv;
380
 
 
381
 
        if (sensor_settings[AUTOGAIN_IDX])
382
 
                return -EBUSY;
383
 
 
384
 
        sensor_settings[GAIN_IDX] = val;
 
332
        struct pb0100_ctrls *ctrls = sd->sensor_priv;
 
333
 
385
334
        err = stv06xx_write_sensor(sd, PB_G1GAIN, val);
386
335
        if (!err)
387
336
                err = stv06xx_write_sensor(sd, PB_G2GAIN, val);
388
337
        PDEBUG(D_V4L2, "Set green gain to %d, status: %d", val, err);
389
338
 
390
339
        if (!err)
391
 
                err = pb0100_set_red_balance(gspca_dev,
392
 
                                             sensor_settings[RED_BALANCE_IDX]);
 
340
                err = pb0100_set_red_balance(gspca_dev, ctrls->red->val);
393
341
        if (!err)
394
 
                err = pb0100_set_blue_balance(gspca_dev,
395
 
                                            sensor_settings[BLUE_BALANCE_IDX]);
 
342
                err = pb0100_set_blue_balance(gspca_dev, ctrls->blue->val);
396
343
 
397
344
        return err;
398
345
}
399
346
 
400
 
static int pb0100_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val)
401
 
{
402
 
        struct sd *sd = (struct sd *) gspca_dev;
403
 
        s32 *sensor_settings = sd->sensor_priv;
404
 
 
405
 
        *val = sensor_settings[RED_BALANCE_IDX];
406
 
 
407
 
        return 0;
408
 
}
409
 
 
410
347
static int pb0100_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
411
348
{
412
349
        int err;
413
350
        struct sd *sd = (struct sd *) gspca_dev;
414
 
        s32 *sensor_settings = sd->sensor_priv;
415
 
 
416
 
        if (sensor_settings[AUTOGAIN_IDX])
417
 
                return -EBUSY;
418
 
 
419
 
        sensor_settings[RED_BALANCE_IDX] = val;
420
 
        val += sensor_settings[GAIN_IDX];
 
351
        struct pb0100_ctrls *ctrls = sd->sensor_priv;
 
352
 
 
353
        val += ctrls->gain->val;
421
354
        if (val < 0)
422
355
                val = 0;
423
356
        else if (val > 255)
429
362
        return err;
430
363
}
431
364
 
432
 
static int pb0100_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val)
433
 
{
434
 
        struct sd *sd = (struct sd *) gspca_dev;
435
 
        s32 *sensor_settings = sd->sensor_priv;
436
 
 
437
 
        *val = sensor_settings[BLUE_BALANCE_IDX];
438
 
 
439
 
        return 0;
440
 
}
441
 
 
442
365
static int pb0100_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
443
366
{
444
367
        int err;
445
368
        struct sd *sd = (struct sd *) gspca_dev;
446
 
        s32 *sensor_settings = sd->sensor_priv;
447
 
 
448
 
        if (sensor_settings[AUTOGAIN_IDX])
449
 
                return -EBUSY;
450
 
 
451
 
        sensor_settings[BLUE_BALANCE_IDX] = val;
452
 
        val += sensor_settings[GAIN_IDX];
 
369
        struct pb0100_ctrls *ctrls = sd->sensor_priv;
 
370
 
 
371
        val += ctrls->gain->val;
453
372
        if (val < 0)
454
373
                val = 0;
455
374
        else if (val > 255)
461
380
        return err;
462
381
}
463
382
 
464
 
static int pb0100_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
465
 
{
466
 
        struct sd *sd = (struct sd *) gspca_dev;
467
 
        s32 *sensor_settings = sd->sensor_priv;
468
 
 
469
 
        *val = sensor_settings[EXPOSURE_IDX];
470
 
 
471
 
        return 0;
472
 
}
473
 
 
474
383
static int pb0100_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
475
384
{
 
385
        struct sd *sd = (struct sd *) gspca_dev;
476
386
        int err;
477
 
        struct sd *sd = (struct sd *) gspca_dev;
478
 
        s32 *sensor_settings = sd->sensor_priv;
479
 
 
480
 
        if (sensor_settings[AUTOGAIN_IDX])
481
 
                return -EBUSY;
482
 
 
483
 
        sensor_settings[EXPOSURE_IDX] = val;
 
387
 
484
388
        err = stv06xx_write_sensor(sd, PB_RINTTIME, val);
485
389
        PDEBUG(D_V4L2, "Set exposure to %d, status: %d", val, err);
486
390
 
487
391
        return err;
488
392
}
489
393
 
490
 
static int pb0100_get_autogain(struct gspca_dev *gspca_dev, __s32 *val)
491
 
{
492
 
        struct sd *sd = (struct sd *) gspca_dev;
493
 
        s32 *sensor_settings = sd->sensor_priv;
494
 
 
495
 
        *val = sensor_settings[AUTOGAIN_IDX];
496
 
 
497
 
        return 0;
498
 
}
499
 
 
500
394
static int pb0100_set_autogain(struct gspca_dev *gspca_dev, __s32 val)
501
395
{
502
396
        int err;
503
397
        struct sd *sd = (struct sd *) gspca_dev;
504
 
        s32 *sensor_settings = sd->sensor_priv;
 
398
        struct pb0100_ctrls *ctrls = sd->sensor_priv;
505
399
 
506
 
        sensor_settings[AUTOGAIN_IDX] = val;
507
 
        if (sensor_settings[AUTOGAIN_IDX]) {
508
 
                if (sensor_settings[NATURAL_IDX])
 
400
        if (val) {
 
401
                if (ctrls->natural->val)
509
402
                        val = BIT(6)|BIT(4)|BIT(0);
510
403
                else
511
404
                        val = BIT(4)|BIT(0);
514
407
 
515
408
        err = stv06xx_write_sensor(sd, PB_EXPGAIN, val);
516
409
        PDEBUG(D_V4L2, "Set autogain to %d (natural: %d), status: %d",
517
 
               sensor_settings[AUTOGAIN_IDX], sensor_settings[NATURAL_IDX],
518
 
               err);
 
410
               val, ctrls->natural->val, err);
519
411
 
520
412
        return err;
521
413
}
522
414
 
523
 
static int pb0100_get_autogain_target(struct gspca_dev *gspca_dev, __s32 *val)
524
 
{
525
 
        struct sd *sd = (struct sd *) gspca_dev;
526
 
        s32 *sensor_settings = sd->sensor_priv;
527
 
 
528
 
        *val = sensor_settings[AUTOGAIN_TARGET_IDX];
529
 
 
530
 
        return 0;
531
 
}
532
 
 
533
415
static int pb0100_set_autogain_target(struct gspca_dev *gspca_dev, __s32 val)
534
416
{
535
417
        int err, totalpixels, brightpixels, darkpixels;
536
418
        struct sd *sd = (struct sd *) gspca_dev;
537
 
        s32 *sensor_settings = sd->sensor_priv;
538
 
 
539
 
        sensor_settings[AUTOGAIN_TARGET_IDX] = val;
540
419
 
541
420
        /* Number of pixels counted by the sensor when subsampling the pixels.
542
421
         * Slightly larger than the real value to avoid oscillation */
553
432
 
554
433
        return err;
555
434
}
556
 
 
557
 
static int pb0100_get_natural(struct gspca_dev *gspca_dev, __s32 *val)
558
 
{
559
 
        struct sd *sd = (struct sd *) gspca_dev;
560
 
        s32 *sensor_settings = sd->sensor_priv;
561
 
 
562
 
        *val = sensor_settings[NATURAL_IDX];
563
 
 
564
 
        return 0;
565
 
}
566
 
 
567
 
static int pb0100_set_natural(struct gspca_dev *gspca_dev, __s32 val)
568
 
{
569
 
        struct sd *sd = (struct sd *) gspca_dev;
570
 
        s32 *sensor_settings = sd->sensor_priv;
571
 
 
572
 
        sensor_settings[NATURAL_IDX] = val;
573
 
 
574
 
        return pb0100_set_autogain(gspca_dev, sensor_settings[AUTOGAIN_IDX]);
575
 
}