aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/gspca/vc032x.c
diff options
context:
space:
mode:
authorJean-Francois Moine <moinejf@free.fr>2009-12-26 14:07:24 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-02-26 13:10:28 -0500
commit83c94a186382307508cbe800588219607fb38148 (patch)
treeb8b7e45774fb591fab05dcb67bcd5c0884ae7f1d /drivers/media/video/gspca/vc032x.c
parent219f3027a8078148ddc2a75125afbb071a4d70c7 (diff)
V4L/DVB (13893): gspca - vc032x: Change the sensor of 046d:0892 and 046d:0896.
- new sensor POxxxx (unknown ID) - no probe - new controls - table for the disabled controls Signed-off-by: Jean-Francois Moine <moinejf@free.fr> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/gspca/vc032x.c')
-rw-r--r--drivers/media/video/gspca/vc032x.c568
1 files changed, 522 insertions, 46 deletions
diff --git a/drivers/media/video/gspca/vc032x.c b/drivers/media/video/gspca/vc032x.c
index 531e9be13d52..dbadb97dd465 100644
--- a/drivers/media/video/gspca/vc032x.c
+++ b/drivers/media/video/gspca/vc032x.c
@@ -32,10 +32,13 @@ MODULE_LICENSE("GPL");
32struct sd { 32struct sd {
33 struct gspca_dev gspca_dev; /* !! must be the first item */ 33 struct gspca_dev gspca_dev; /* !! must be the first item */
34 34
35 u8 brightness;
36 u8 contrast;
37 u8 colors;
35 u8 hflip; 38 u8 hflip;
36 u8 vflip; 39 u8 vflip;
37 u8 lightfreq; 40 u8 lightfreq;
38 u8 sharpness; 41 s8 sharpness;
39 42
40 u8 image_offset; 43 u8 image_offset;
41 44
@@ -52,6 +55,7 @@ struct sd {
52#define SENSOR_OV7670 6 55#define SENSOR_OV7670 6
53#define SENSOR_PO1200 7 56#define SENSOR_PO1200 7
54#define SENSOR_PO3130NC 8 57#define SENSOR_PO3130NC 8
58#define SENSOR_POxxxx 9
55 u8 flags; 59 u8 flags;
56#define FL_SAMSUNG 0x01 /* SamsungQ1 (2 sensors) */ 60#define FL_SAMSUNG 0x01 /* SamsungQ1 (2 sensors) */
57#define FL_HFLIP 0x02 /* mirrored by default */ 61#define FL_HFLIP 0x02 /* mirrored by default */
@@ -59,6 +63,12 @@ struct sd {
59}; 63};
60 64
61/* V4L2 controls supported by the driver */ 65/* V4L2 controls supported by the driver */
66static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
67static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
68static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
69static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
70static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
71static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
62static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val); 72static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val);
63static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val); 73static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val);
64static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val); 74static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
@@ -69,8 +79,53 @@ static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val);
69static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val); 79static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val);
70 80
71static struct ctrl sd_ctrls[] = { 81static struct ctrl sd_ctrls[] = {
82#define BRIGHTNESS_IDX 0
83 {
84 {
85 .id = V4L2_CID_BRIGHTNESS,
86 .type = V4L2_CTRL_TYPE_INTEGER,
87 .name = "Brightness",
88 .minimum = 0,
89 .maximum = 255,
90 .step = 1,
91#define BRIGHTNESS_DEF 128
92 .default_value = BRIGHTNESS_DEF,
93 },
94 .set = sd_setbrightness,
95 .get = sd_getbrightness,
96 },
97#define CONTRAST_IDX 1
98 {
99 {
100 .id = V4L2_CID_CONTRAST,
101 .type = V4L2_CTRL_TYPE_INTEGER,
102 .name = "Contrast",
103 .minimum = 0,
104 .maximum = 255,
105 .step = 1,
106#define CONTRAST_DEF 127
107 .default_value = CONTRAST_DEF,
108 },
109 .set = sd_setcontrast,
110 .get = sd_getcontrast,
111 },
112#define COLORS_IDX 2
113 {
114 {
115 .id = V4L2_CID_SATURATION,
116 .type = V4L2_CTRL_TYPE_INTEGER,
117 .name = "Saturation",
118 .minimum = 1,
119 .maximum = 127,
120 .step = 1,
121#define COLOR_DEF 63
122 .default_value = COLOR_DEF,
123 },
124 .set = sd_setcolors,
125 .get = sd_getcolors,
126 },
72/* next 2 controls work with some sensors only */ 127/* next 2 controls work with some sensors only */
73#define HFLIP_IDX 0 128#define HFLIP_IDX 3
74 { 129 {
75 { 130 {
76 .id = V4L2_CID_HFLIP, 131 .id = V4L2_CID_HFLIP,
@@ -85,7 +140,7 @@ static struct ctrl sd_ctrls[] = {
85 .set = sd_sethflip, 140 .set = sd_sethflip,
86 .get = sd_gethflip, 141 .get = sd_gethflip,
87 }, 142 },
88#define VFLIP_IDX 1 143#define VFLIP_IDX 4
89 { 144 {
90 { 145 {
91 .id = V4L2_CID_VFLIP, 146 .id = V4L2_CID_VFLIP,
@@ -100,7 +155,7 @@ static struct ctrl sd_ctrls[] = {
100 .set = sd_setvflip, 155 .set = sd_setvflip,
101 .get = sd_getvflip, 156 .get = sd_getvflip,
102 }, 157 },
103#define LIGHTFREQ_IDX 2 158#define LIGHTFREQ_IDX 5
104 { 159 {
105 { 160 {
106 .id = V4L2_CID_POWER_LINE_FREQUENCY, 161 .id = V4L2_CID_POWER_LINE_FREQUENCY,
@@ -115,17 +170,16 @@ static struct ctrl sd_ctrls[] = {
115 .set = sd_setfreq, 170 .set = sd_setfreq,
116 .get = sd_getfreq, 171 .get = sd_getfreq,
117 }, 172 },
118/* po1200 only */ 173#define SHARPNESS_IDX 6
119#define SHARPNESS_IDX 3
120 { 174 {
121 { 175 {
122 .id = V4L2_CID_SHARPNESS, 176 .id = V4L2_CID_SHARPNESS,
123 .type = V4L2_CTRL_TYPE_INTEGER, 177 .type = V4L2_CTRL_TYPE_INTEGER,
124 .name = "Sharpness", 178 .name = "Sharpness",
125 .minimum = 0, 179 .minimum = -1,
126 .maximum = 2, 180 .maximum = 2,
127 .step = 1, 181 .step = 1,
128#define SHARPNESS_DEF 1 182#define SHARPNESS_DEF -1
129 .default_value = SHARPNESS_DEF, 183 .default_value = SHARPNESS_DEF,
130 }, 184 },
131 .set = sd_setsharpness, 185 .set = sd_setsharpness,
@@ -133,6 +187,42 @@ static struct ctrl sd_ctrls[] = {
133 }, 187 },
134}; 188};
135 189
190/* table of the disabled controls */
191static u32 ctrl_dis[] = {
192/* SENSOR_HV7131R 0 */
193 (1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX)
194 | (1 << HFLIP_IDX) | (1 << VFLIP_IDX) | (1 << LIGHTFREQ_IDX)
195 | (1 << SHARPNESS_IDX),
196/* SENSOR_MI0360 1 */
197 (1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX)
198 | (1 << HFLIP_IDX) | (1 << VFLIP_IDX) | (1 << LIGHTFREQ_IDX)
199 | (1 << SHARPNESS_IDX),
200/* SENSOR_MI1310_SOC 2 */
201 (1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX)
202 | (1 << LIGHTFREQ_IDX) | (1 << SHARPNESS_IDX),
203/* SENSOR_MI1320 3 */
204 (1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX)
205 | (1 << LIGHTFREQ_IDX) | (1 << SHARPNESS_IDX),
206/* SENSOR_MI1320_SOC 4 */
207 (1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX)
208 | (1 << LIGHTFREQ_IDX) | (1 << SHARPNESS_IDX),
209/* SENSOR_OV7660 5 */
210 (1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX)
211 | (1 << LIGHTFREQ_IDX) | (1 << SHARPNESS_IDX),
212/* SENSOR_OV7670 6 */
213 (1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX)
214 | (1 << SHARPNESS_IDX),
215/* SENSOR_PO1200 7 */
216 (1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX)
217 | (1 << LIGHTFREQ_IDX),
218/* SENSOR_PO3130NC 8 */
219 (1 << BRIGHTNESS_IDX) | (1 << CONTRAST_IDX) | (1 << COLORS_IDX)
220 | (1 << HFLIP_IDX) | (1 << VFLIP_IDX) | (1 << LIGHTFREQ_IDX)
221 | (1 << SHARPNESS_IDX),
222/* SENSOR_POxxxx 9 */
223 (1 << HFLIP_IDX) | (1 << VFLIP_IDX) | (1 << LIGHTFREQ_IDX),
224};
225
136static const struct v4l2_pix_format vc0321_mode[] = { 226static const struct v4l2_pix_format vc0321_mode[] = {
137 {320, 240, V4L2_PIX_FMT_YVYU, V4L2_FIELD_NONE, 227 {320, 240, V4L2_PIX_FMT_YVYU, V4L2_FIELD_NONE,
138 .bytesperline = 320, 228 .bytesperline = 320,
@@ -2413,6 +2503,251 @@ static const u8 po1200_initVGA_data[][4] = {
2413 {0x00, 0xb6, 0x39, 0xaa}, 2503 {0x00, 0xb6, 0x39, 0xaa},
2414 {0x00, 0xb7, 0x24, 0xaa}, 2504 {0x00, 0xb7, 0x24, 0xaa},
2415/*write 89 0400 1415*/ 2505/*write 89 0400 1415*/
2506 {}
2507};
2508
2509static const u8 poxxxx_init_common[][4] = {
2510 {0xb3, 0x00, 0x04, 0xcc},
2511 {0x00, 0x00, 0x10, 0xdd},
2512 {0xb3, 0x00, 0x64, 0xcc},
2513 {0x00, 0x00, 0x10, 0xdd},
2514 {0xb3, 0x00, 0x65, 0xcc},
2515 {0x00, 0x00, 0x10, 0xdd},
2516 {0xb3, 0x00, 0x67, 0xcc},
2517 {0xb0, 0x03, 0x09, 0xcc},
2518 {0xb3, 0x05, 0x00, 0xcc},
2519 {0xb3, 0x06, 0x00, 0xcc},
2520 {0xb3, 0x5c, 0x01, 0xcc},
2521 {0xb3, 0x08, 0x01, 0xcc},
2522 {0xb3, 0x09, 0x0c, 0xcc},
2523 {0xb3, 0x34, 0x01, 0xcc},
2524 {0xb3, 0x35, 0xf6, 0xcc}, /* i2c add: 76 */
2525 {0xb3, 0x02, 0xb0, 0xcc},
2526 {0xb3, 0x03, 0x18, 0xcc},
2527 {0xb3, 0x04, 0x15, 0xcc},
2528 {0xb3, 0x20, 0x00, 0xcc},
2529 {0xb3, 0x21, 0x00, 0xcc},
2530 {0xb3, 0x22, 0x04, 0xcc},
2531 {0xb3, 0x23, 0x00, 0xcc},
2532 {0xb3, 0x14, 0x00, 0xcc},
2533 {0xb3, 0x15, 0x00, 0xcc},
2534 {0xb3, 0x16, 0x04, 0xcc},
2535 {0xb3, 0x17, 0xff, 0xcc},
2536 {0xb3, 0x2c, 0x03, 0xcc},
2537 {0xb3, 0x2d, 0x56, 0xcc},
2538 {0xb3, 0x2e, 0x02, 0xcc},
2539 {0xb3, 0x2f, 0x0a, 0xcc},
2540 {0xb3, 0x40, 0x00, 0xcc},
2541 {0xb3, 0x41, 0x34, 0xcc},
2542 {0xb3, 0x42, 0x01, 0xcc},
2543 {0xb3, 0x43, 0xe0, 0xcc},
2544 {0xbc, 0x00, 0x71, 0xcc},
2545 {0xbc, 0x01, 0x01, 0xcc},
2546 {0xb3, 0x01, 0x41, 0xcc},
2547 {0xb3, 0x4d, 0x00, 0xcc},
2548 {0x00, 0x0b, 0x2a, 0xaa},
2549 {0x00, 0x0e, 0x03, 0xaa},
2550 {0x00, 0x0f, 0xea, 0xaa},
2551 {0x00, 0x12, 0x08, 0xaa},
2552 {0x00, 0x1e, 0x06, 0xaa},
2553 {0x00, 0x21, 0x00, 0xaa},
2554 {0x00, 0x31, 0x1f, 0xaa},
2555 {0x00, 0x33, 0x38, 0xaa},
2556 {0x00, 0x36, 0xc0, 0xaa},
2557 {0x00, 0x37, 0xc8, 0xaa},
2558 {0x00, 0x3b, 0x36, 0xaa},
2559 {0x00, 0x4b, 0xfe, 0xaa},
2560 {0x00, 0x4d, 0x2e, 0xaa},
2561 {0x00, 0x51, 0x1c, 0xaa},
2562 {0x00, 0x52, 0x01, 0xaa},
2563 {0x00, 0x55, 0x0a, 0xaa},
2564 {0x00, 0x56, 0x0a, 0xaa},
2565 {0x00, 0x57, 0x07, 0xaa},
2566 {0x00, 0x58, 0x07, 0xaa},
2567 {0x00, 0x59, 0x04, 0xaa},
2568 {0x00, 0x70, 0x68, 0xaa},
2569 {0x00, 0x71, 0x04, 0xaa},
2570 {0x00, 0x72, 0x10, 0xaa},
2571 {0x00, 0x80, 0x71, 0xaa},
2572 {0x00, 0x81, 0x08, 0xaa},
2573 {0x00, 0x82, 0x00, 0xaa},
2574 {0x00, 0x83, 0x55, 0xaa},
2575 {0x00, 0x84, 0x06, 0xaa},
2576 {0x00, 0x85, 0x06, 0xaa},
2577 {0x00, 0x8b, 0x25, 0xaa},
2578 {0x00, 0x8c, 0x00, 0xaa},
2579 {0x00, 0x8d, 0x86, 0xaa},
2580 {0x00, 0x8e, 0x82, 0xaa},
2581 {0x00, 0x8f, 0x2d, 0xaa},
2582 {0x00, 0x90, 0x8b, 0xaa},
2583 {0x00, 0x91, 0x81, 0xaa},
2584 {0x00, 0x92, 0x81, 0xaa},
2585 {0x00, 0x93, 0x23, 0xaa},
2586 {0x00, 0xa3, 0x2a, 0xaa},
2587 {0x00, 0xa4, 0x03, 0xaa},
2588 {0x00, 0xa5, 0xea, 0xaa},
2589 {0x00, 0xb0, 0x68, 0xaa},
2590 {0x00, 0xbc, 0x04, 0xaa},
2591 {0x00, 0xbe, 0x3b, 0xaa},
2592 {0x00, 0x4e, 0x40, 0xaa},
2593 {0x00, 0x06, 0x04, 0xaa},
2594 {0x00, 0x07, 0x03, 0xaa},
2595 {0x00, 0xcd, 0x18, 0xaa},
2596 {0x00, 0x28, 0x03, 0xaa},
2597 {0x00, 0x29, 0xef, 0xaa},
2598/* reinit on alt 2 (qvga) or alt7 (vga) */
2599 {0xb3, 0x05, 0x00, 0xcc},
2600 {0xb3, 0x06, 0x00, 0xcc},
2601 {0xb8, 0x00, 0x01, 0xcc},
2602
2603 {0x00, 0x1d, 0x85, 0xaa},
2604 {0x00, 0x1e, 0xc6, 0xaa},
2605 {0x00, 0x00, 0x40, 0xdd},
2606 {0x00, 0x1d, 0x05, 0xaa},
2607
2608 {0x00, 0xd6, 0x22, 0xaa}, /* gamma 0 */
2609 {0x00, 0x73, 0x00, 0xaa},
2610 {0x00, 0x74, 0x0a, 0xaa},
2611 {0x00, 0x75, 0x16, 0xaa},
2612 {0x00, 0x76, 0x25, 0xaa},
2613 {0x00, 0x77, 0x34, 0xaa},
2614 {0x00, 0x78, 0x49, 0xaa},
2615 {0x00, 0x79, 0x5a, 0xaa},
2616 {0x00, 0x7a, 0x7f, 0xaa},
2617 {0x00, 0x7b, 0x9b, 0xaa},
2618 {0x00, 0x7c, 0xba, 0xaa},
2619 {0x00, 0x7d, 0xd4, 0xaa},
2620 {0x00, 0x7e, 0xea, 0xaa},
2621
2622 {0x00, 0xd6, 0x62, 0xaa}, /* gamma 1 */
2623 {0x00, 0x73, 0x00, 0xaa},
2624 {0x00, 0x74, 0x0a, 0xaa},
2625 {0x00, 0x75, 0x16, 0xaa},
2626 {0x00, 0x76, 0x25, 0xaa},
2627 {0x00, 0x77, 0x34, 0xaa},
2628 {0x00, 0x78, 0x49, 0xaa},
2629 {0x00, 0x79, 0x5a, 0xaa},
2630 {0x00, 0x7a, 0x7f, 0xaa},
2631 {0x00, 0x7b, 0x9b, 0xaa},
2632 {0x00, 0x7c, 0xba, 0xaa},
2633 {0x00, 0x7d, 0xd4, 0xaa},
2634 {0x00, 0x7e, 0xea, 0xaa},
2635
2636 {0x00, 0xd6, 0xa2, 0xaa}, /* gamma 2 */
2637 {0x00, 0x73, 0x00, 0xaa},
2638 {0x00, 0x74, 0x0a, 0xaa},
2639 {0x00, 0x75, 0x16, 0xaa},
2640 {0x00, 0x76, 0x25, 0xaa},
2641 {0x00, 0x77, 0x34, 0xaa},
2642 {0x00, 0x78, 0x49, 0xaa},
2643 {0x00, 0x79, 0x5a, 0xaa},
2644 {0x00, 0x7a, 0x7f, 0xaa},
2645 {0x00, 0x7b, 0x9b, 0xaa},
2646 {0x00, 0x7c, 0xba, 0xaa},
2647 {0x00, 0x7d, 0xd4, 0xaa},
2648 {0x00, 0x7e, 0xea, 0xaa},
2649
2650 {0x00, 0xaa, 0xff, 0xaa}, /* back light comp */
2651 {0x00, 0xc4, 0x03, 0xaa},
2652 {0x00, 0xc5, 0x19, 0xaa},
2653 {0x00, 0xc6, 0x03, 0xaa},
2654 {0x00, 0xc7, 0x91, 0xaa},
2655 {0x00, 0xc8, 0x01, 0xaa},
2656 {0x00, 0xc9, 0xdd, 0xaa},
2657 {0x00, 0xca, 0x02, 0xaa},
2658 {0x00, 0xcb, 0x37, 0xaa},
2659
2660/* read d1 */
2661 {0x00, 0xd1, 0x3c, 0xaa},
2662 {0x00, 0xb8, 0x28, 0xaa},
2663 {0x00, 0xb9, 0x1e, 0xaa},
2664 {0x00, 0xb6, 0x14, 0xaa},
2665 {0x00, 0xb7, 0x0f, 0xaa},
2666 {0x00, 0x5c, 0x10, 0xaa},
2667 {0x00, 0x5d, 0x18, 0xaa},
2668 {0x00, 0x5e, 0x24, 0xaa},
2669 {0x00, 0x5f, 0x24, 0xaa},
2670 {0x00, 0x86, 0x1a, 0xaa},
2671 {0x00, 0x60, 0x00, 0xaa},
2672 {0x00, 0x61, 0x1b, 0xaa},
2673 {0x00, 0x62, 0x30, 0xaa},
2674 {0x00, 0x63, 0x40, 0xaa},
2675 {0x00, 0x87, 0x1a, 0xaa},
2676 {0x00, 0x64, 0x00, 0xaa},
2677 {0x00, 0x65, 0x08, 0xaa},
2678 {0x00, 0x66, 0x10, 0xaa},
2679 {0x00, 0x67, 0x20, 0xaa},
2680 {0x00, 0x88, 0x10, 0xaa},
2681 {0x00, 0x68, 0x00, 0xaa},
2682 {0x00, 0x69, 0x08, 0xaa},
2683 {0x00, 0x6a, 0x0f, 0xaa},
2684 {0x00, 0x6b, 0x0f, 0xaa},
2685 {0x00, 0x89, 0x07, 0xaa},
2686 {0x00, 0xd5, 0x4c, 0xaa},
2687 {0x00, 0x0a, 0x00, 0xaa},
2688 {0x00, 0x0b, 0x2a, 0xaa},
2689 {0x00, 0x0e, 0x03, 0xaa},
2690 {0x00, 0x0f, 0xea, 0xaa},
2691 {0x00, 0xa2, 0x00, 0xaa},
2692 {0x00, 0xa3, 0x2a, 0xaa},
2693 {0x00, 0xa4, 0x03, 0xaa},
2694 {0x00, 0xa5, 0xea, 0xaa},
2695 {}
2696};
2697static const u8 poxxxx_initVGA[][4] = {
2698 {0x00, 0x20, 0x11, 0xaa},
2699 {0x00, 0x33, 0x38, 0xaa},
2700 {0x00, 0xbb, 0x0d, 0xaa},
2701 {0xb3, 0x22, 0x01, 0xcc},
2702 {0xb3, 0x23, 0xe0, 0xcc},
2703 {0xb3, 0x16, 0x02, 0xcc},
2704 {0xb3, 0x17, 0x7f, 0xcc},
2705 {0xb3, 0x02, 0xb0, 0xcc},
2706 {0xb3, 0x06, 0x00, 0xcc},
2707 {0xb3, 0x5c, 0x01, 0xcc},
2708 {0x00, 0x04, 0x06, 0xaa},
2709 {0x00, 0x05, 0x3f, 0xaa},
2710 {0x00, 0x04, 0x00, 0xdd}, /* delay 1s */
2711 {}
2712};
2713static const u8 poxxxx_initQVGA[][4] = {
2714 {0x00, 0x20, 0x33, 0xaa},
2715 {0x00, 0x33, 0x38, 0xaa},
2716 {0x00, 0xbb, 0x0d, 0xaa},
2717 {0xb3, 0x22, 0x00, 0xcc},
2718 {0xb3, 0x23, 0xf0, 0xcc},
2719 {0xb3, 0x16, 0x01, 0xcc},
2720 {0xb3, 0x17, 0x3f, 0xcc},
2721 {0xb3, 0x02, 0xb0, 0xcc},
2722 {0xb3, 0x06, 0x01, 0xcc},
2723 {0xb3, 0x5c, 0x00, 0xcc},
2724 {0x00, 0x04, 0x06, 0xaa},
2725 {0x00, 0x05, 0x3f, 0xaa},
2726 {0x00, 0x04, 0x00, 0xdd}, /* delay 1s */
2727 {}
2728};
2729static const u8 poxxxx_init_end_1[][4] = {
2730 {0x00, 0x47, 0x25, 0xaa},
2731 {0x00, 0x48, 0x80, 0xaa},
2732 {0x00, 0x49, 0x1f, 0xaa},
2733 {0x00, 0x4a, 0x40, 0xaa},
2734 {0x00, 0x44, 0x40, 0xaa},
2735 {0x00, 0xab, 0x4a, 0xaa},
2736 {0x00, 0xb1, 0x00, 0xaa},
2737 {0x00, 0xb2, 0x04, 0xaa},
2738 {0x00, 0xb3, 0x08, 0xaa},
2739 {0x00, 0xb4, 0x0b, 0xaa},
2740 {0x00, 0xb5, 0x0d, 0xaa},
2741 {0x00, 0x59, 0x7e, 0xaa}, /* sharpness */
2742 {0x00, 0x16, 0x00, 0xaa}, /* white balance */
2743 {0x00, 0x18, 0x00, 0xaa},
2744 {}
2745};
2746static const u8 poxxxx_init_end_2[][4] = {
2747 {0x00, 0x1d, 0x85, 0xaa},
2748 {0x00, 0x1e, 0x06, 0xaa},
2749 {0x00, 0x1d, 0x05, 0xaa},
2750 {}
2416}; 2751};
2417 2752
2418struct sensor_info { 2753struct sensor_info {
@@ -2689,7 +3024,7 @@ static void usb_exchange(struct gspca_dev *gspca_dev,
2689 i2c_write(gspca_dev, data[i][0], &data[i][1], 2); 3024 i2c_write(gspca_dev, data[i][0], &data[i][1], 2);
2690 break; 3025 break;
2691 case 0xdd: 3026 case 0xdd:
2692 msleep(data[i][2] + 10); 3027 msleep(data[i][1] * 256 + data[i][2] + 10);
2693 break; 3028 break;
2694 } 3029 }
2695 i++; 3030 i++;
@@ -2716,12 +3051,17 @@ static int sd_config(struct gspca_dev *gspca_dev,
2716 64, /* OV7670 6 */ 3051 64, /* OV7670 6 */
2717 128, /* PO1200 7 */ 3052 128, /* PO1200 7 */
2718 128, /* PO3130NC 8 */ 3053 128, /* PO3130NC 8 */
3054 128, /* POxxxx 9 */
2719 }; 3055 };
2720 3056
2721 cam = &gspca_dev->cam; 3057 cam = &gspca_dev->cam;
2722 sd->bridge = id->driver_info >> 8; 3058 sd->bridge = id->driver_info >> 8;
2723 sd->flags = id->driver_info & 0xff; 3059 sd->flags = id->driver_info & 0xff;
2724 sensor = vc032x_probe_sensor(gspca_dev); 3060 if (id->idVendor == 0x046d &&
3061 (id->idProduct == 0x0892 || id->idProduct == 0x0896))
3062 sensor = SENSOR_POxxxx;
3063 else
3064 sensor = vc032x_probe_sensor(gspca_dev);
2725 switch (sensor) { 3065 switch (sensor) {
2726 case -1: 3066 case -1:
2727 PDEBUG(D_PROBE, "Unknown sensor..."); 3067 PDEBUG(D_PROBE, "Unknown sensor...");
@@ -2754,6 +3094,9 @@ static int sd_config(struct gspca_dev *gspca_dev,
2754 case SENSOR_PO3130NC: 3094 case SENSOR_PO3130NC:
2755 PDEBUG(D_PROBE, "Find Sensor PO3130NC"); 3095 PDEBUG(D_PROBE, "Find Sensor PO3130NC");
2756 break; 3096 break;
3097 case SENSOR_POxxxx:
3098 PDEBUG(D_PROBE, "Sensor POxxxx");
3099 break;
2757 } 3100 }
2758 sd->sensor = sensor; 3101 sd->sensor = sensor;
2759 3102
@@ -2782,29 +3125,19 @@ static int sd_config(struct gspca_dev *gspca_dev,
2782 } 3125 }
2783 cam->npkt = npkt[sd->sensor]; 3126 cam->npkt = npkt[sd->sensor];
2784 3127
3128 sd->brightness = BRIGHTNESS_DEF;
3129 sd->contrast = CONTRAST_DEF;
3130 sd->colors = COLOR_DEF;
2785 sd->hflip = HFLIP_DEF; 3131 sd->hflip = HFLIP_DEF;
2786 sd->vflip = VFLIP_DEF; 3132 sd->vflip = VFLIP_DEF;
2787 if (sd->sensor == SENSOR_OV7670)
2788 sd->flags |= FL_HFLIP | FL_VFLIP;
2789 sd->lightfreq = FREQ_DEF; 3133 sd->lightfreq = FREQ_DEF;
2790 if (sd->sensor != SENSOR_OV7670)
2791 gspca_dev->ctrl_dis = (1 << LIGHTFREQ_IDX);
2792 switch (sd->sensor) {
2793 case SENSOR_MI1310_SOC:
2794 case SENSOR_MI1320:
2795 case SENSOR_MI1320_SOC:
2796 case SENSOR_OV7660:
2797 case SENSOR_OV7670:
2798 case SENSOR_PO1200:
2799 break;
2800 default:
2801 gspca_dev->ctrl_dis = (1 << HFLIP_IDX)
2802 | (1 << VFLIP_IDX);
2803 break;
2804 }
2805
2806 sd->sharpness = SHARPNESS_DEF; 3134 sd->sharpness = SHARPNESS_DEF;
2807 3135
3136 gspca_dev->ctrl_dis = ctrl_dis[sd->sensor];
3137
3138 if (sd->sensor == SENSOR_OV7670)
3139 sd->flags |= FL_HFLIP | FL_VFLIP;
3140
2808 if (sd->bridge == BRIDGE_VC0321) { 3141 if (sd->bridge == BRIDGE_VC0321) {
2809 reg_r(gspca_dev, 0x8a, 0, 3); 3142 reg_r(gspca_dev, 0x8a, 0, 3);
2810 reg_w(dev, 0x87, 0x00, 0x0f0f); 3143 reg_w(dev, 0x87, 0x00, 0x0f0f);
@@ -2818,10 +3151,55 @@ static int sd_config(struct gspca_dev *gspca_dev,
2818/* this function is called at probe and resume time */ 3151/* this function is called at probe and resume time */
2819static int sd_init(struct gspca_dev *gspca_dev) 3152static int sd_init(struct gspca_dev *gspca_dev)
2820{ 3153{
3154 struct sd *sd = (struct sd *) gspca_dev;
3155
3156 if (sd->sensor == SENSOR_POxxxx) {
3157 reg_r(gspca_dev, 0xa1, 0xb300, 1);
3158 if (gspca_dev->usb_buf[0] != 0) {
3159 reg_w(gspca_dev->dev, 0xa0, 0x26, 0xb300);
3160 reg_w(gspca_dev->dev, 0xa0, 0x04, 0xb300);
3161 reg_w(gspca_dev->dev, 0xa0, 0x00, 0xb300);
3162 }
3163 }
2821 return 0; 3164 return 0;
2822} 3165}
2823 3166
2824/* some sensors only */ 3167static void setbrightness(struct gspca_dev *gspca_dev)
3168{
3169 struct sd *sd = (struct sd *) gspca_dev;
3170 u8 data;
3171
3172 if (gspca_dev->ctrl_dis & (1 << BRIGHTNESS_IDX))
3173 return;
3174 data = sd->brightness;
3175 if (data >= 0x80)
3176 data &= 0x7f;
3177 else
3178 data = 0xff ^ data;
3179 i2c_write(gspca_dev, 0x98, &data, 1);
3180}
3181
3182static void setcontrast(struct gspca_dev *gspca_dev)
3183{
3184 struct sd *sd = (struct sd *) gspca_dev;
3185
3186 if (gspca_dev->ctrl_dis & (1 << CONTRAST_IDX))
3187 return;
3188 i2c_write(gspca_dev, 0x99, &sd->contrast, 1);
3189}
3190
3191static void setcolors(struct gspca_dev *gspca_dev)
3192{
3193 struct sd *sd = (struct sd *) gspca_dev;
3194 u8 data;
3195
3196 if (gspca_dev->ctrl_dis & (1 << COLORS_IDX))
3197 return;
3198 data = sd->colors - (sd->colors >> 3) - 1;
3199 i2c_write(gspca_dev, 0x94, &data, 1);
3200 i2c_write(gspca_dev, 0x95, &sd->colors, 1);
3201}
3202
2825static void sethvflip(struct gspca_dev *gspca_dev) 3203static void sethvflip(struct gspca_dev *gspca_dev)
2826{ 3204{
2827 struct sd *sd = (struct sd *) gspca_dev; 3205 struct sd *sd = (struct sd *) gspca_dev;
@@ -2873,18 +3251,29 @@ static void setlightfreq(struct gspca_dev *gspca_dev)
2873 usb_exchange(gspca_dev, ov7660_freq_tb[sd->lightfreq]); 3251 usb_exchange(gspca_dev, ov7660_freq_tb[sd->lightfreq]);
2874} 3252}
2875 3253
2876/* po1200 only */
2877static void setsharpness(struct gspca_dev *gspca_dev) 3254static void setsharpness(struct gspca_dev *gspca_dev)
2878{ 3255{
2879 struct sd *sd = (struct sd *) gspca_dev; 3256 struct sd *sd = (struct sd *) gspca_dev;
2880 u8 data; 3257 u8 data;
2881 3258
2882 if (sd->sensor != SENSOR_PO1200) 3259 switch (sd->sensor) {
2883 return; 3260 case SENSOR_PO1200:
2884 data = 0; 3261 data = 0;
2885 i2c_write(gspca_dev, 0x03, &data, 1); 3262 i2c_write(gspca_dev, 0x03, &data, 1);
2886 data = 0xb5 + sd->sharpness * 3; 3263 if (sd->sharpness < 0)
2887 i2c_write(gspca_dev, 0x61, &data, 1); 3264 data = 0x6a;
3265 else
3266 data = 0xb5 + sd->sharpness * 3;
3267 i2c_write(gspca_dev, 0x61, &data, 1);
3268 break;
3269 case SENSOR_POxxxx:
3270 if (sd->sharpness < 0)
3271 data = 0x7e; /* def = max */
3272 else
3273 data = 0x60 + sd->sharpness * 0x0f;
3274 i2c_write(gspca_dev, 0x59, &data, 1);
3275 break;
3276 }
2888} 3277}
2889 3278
2890static int sd_start(struct gspca_dev *gspca_dev) 3279static int sd_start(struct gspca_dev *gspca_dev)
@@ -2994,12 +3383,27 @@ static int sd_start(struct gspca_dev *gspca_dev)
2994 usb_exchange(gspca_dev, init); 3383 usb_exchange(gspca_dev, init);
2995 init = po3130_rundata; 3384 init = po3130_rundata;
2996 break; 3385 break;
2997 default: 3386 case SENSOR_PO1200:
2998/* case SENSOR_PO1200: */
2999 GammaT = po1200_gamma; 3387 GammaT = po1200_gamma;
3000 MatrixT = po1200_matrix; 3388 MatrixT = po1200_matrix;
3001 init = po1200_initVGA_data; 3389 init = po1200_initVGA_data;
3002 break; 3390 break;
3391 default:
3392/* case SENSOR_POxxxx: */
3393 usb_exchange(gspca_dev, poxxxx_init_common);
3394 if (mode)
3395 init = poxxxx_initQVGA;
3396 else
3397 init = poxxxx_initVGA;
3398 usb_exchange(gspca_dev, init);
3399 reg_r(gspca_dev, 0x8c, 0x0000, 3);
3400 reg_w(gspca_dev->dev, 0xa0,
3401 gspca_dev->usb_buf[2] & 1 ? 0 : 1,
3402 0xb35c);
3403 msleep(300);
3404/*fixme: i2c read 04 and 05*/
3405 init = poxxxx_init_end_1;
3406 break;
3003 } 3407 }
3004 usb_exchange(gspca_dev, init); 3408 usb_exchange(gspca_dev, init);
3005 if (GammaT && MatrixT) { 3409 if (GammaT && MatrixT) {
@@ -3008,7 +3412,6 @@ static int sd_start(struct gspca_dev *gspca_dev)
3008 put_tab_to_reg(gspca_dev, GammaT, 17, 0xb86c); 3412 put_tab_to_reg(gspca_dev, GammaT, 17, 0xb86c);
3009 put_tab_to_reg(gspca_dev, MatrixT, 9, 0xb82c); 3413 put_tab_to_reg(gspca_dev, MatrixT, 9, 0xb82c);
3010 3414
3011 /* set the led on 0x0892 0x0896 */
3012 switch (sd->sensor) { 3415 switch (sd->sensor) {
3013 case SENSOR_PO1200: 3416 case SENSOR_PO1200:
3014 case SENSOR_HV7131R: 3417 case SENSOR_HV7131R:
@@ -3017,16 +3420,22 @@ static int sd_start(struct gspca_dev *gspca_dev)
3017 case SENSOR_MI1310_SOC: 3420 case SENSOR_MI1310_SOC:
3018 reg_w(gspca_dev->dev, 0x89, 0x058c, 0x0000); 3421 reg_w(gspca_dev->dev, 0x89, 0x058c, 0x0000);
3019 break; 3422 break;
3020 default:
3021 if (!(sd->flags & FL_SAMSUNG))
3022 reg_w(gspca_dev->dev, 0x89, 0xffff, 0xfdff);
3023 break;
3024 } 3423 }
3025 msleep(100); 3424 msleep(100);
3026 setsharpness(gspca_dev); 3425 setsharpness(gspca_dev);
3027 sethvflip(gspca_dev); 3426 sethvflip(gspca_dev);
3028 setlightfreq(gspca_dev); 3427 setlightfreq(gspca_dev);
3029 } 3428 }
3429 if (sd->sensor == SENSOR_POxxxx) {
3430 setcolors(gspca_dev);
3431 setbrightness(gspca_dev);
3432 setcontrast(gspca_dev);
3433
3434 /* led on */
3435 msleep(80);
3436 reg_w(gspca_dev->dev, 0x89, 0xffff, 0xfdff);
3437 usb_exchange(gspca_dev, poxxxx_init_end_2);
3438 }
3030 return 0; 3439 return 0;
3031} 3440}
3032 3441
@@ -3035,10 +3444,17 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
3035 struct usb_device *dev = gspca_dev->dev; 3444 struct usb_device *dev = gspca_dev->dev;
3036 struct sd *sd = (struct sd *) gspca_dev; 3445 struct sd *sd = (struct sd *) gspca_dev;
3037 3446
3038 if (sd->sensor == SENSOR_MI1310_SOC) 3447 switch (sd->sensor) {
3448 case SENSOR_MI1310_SOC:
3039 reg_w(dev, 0x89, 0x058c, 0x00ff); 3449 reg_w(dev, 0x89, 0x058c, 0x00ff);
3040 else if (!(sd->flags & FL_SAMSUNG)) 3450 break;
3041 reg_w(dev, 0x89, 0xffff, 0xffff); 3451 case SENSOR_POxxxx:
3452 return;
3453 default:
3454 if (!(sd->flags & FL_SAMSUNG))
3455 reg_w(dev, 0x89, 0xffff, 0xffff);
3456 break;
3457 }
3042 reg_w(dev, 0xa0, 0x01, 0xb301); 3458 reg_w(dev, 0xa0, 0x01, 0xb301);
3043 reg_w(dev, 0xa0, 0x09, 0xb003); 3459 reg_w(dev, 0xa0, 0x09, 0xb003);
3044} 3460}
@@ -3056,6 +3472,12 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
3056 reg_w(dev, 0x89, 0x058c, 0x00ff); 3472 reg_w(dev, 0x89, 0x058c, 0x00ff);
3057 else if (!(sd->flags & FL_SAMSUNG)) 3473 else if (!(sd->flags & FL_SAMSUNG))
3058 reg_w(dev, 0x89, 0xffff, 0xffff); 3474 reg_w(dev, 0x89, 0xffff, 0xffff);
3475
3476 if (sd->sensor == SENSOR_POxxxx) {
3477 reg_w(dev, 0xa0, 0x26, 0xb300);
3478 reg_w(dev, 0xa0, 0x04, 0xb300);
3479 reg_w(dev, 0xa0, 0x00, 0xb300);
3480 }
3059} 3481}
3060 3482
3061static void sd_pkt_scan(struct gspca_dev *gspca_dev, 3483static void sd_pkt_scan(struct gspca_dev *gspca_dev,
@@ -3092,6 +3514,60 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
3092 gspca_frame_add(gspca_dev, INTER_PACKET, data, len); 3514 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
3093} 3515}
3094 3516
3517static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
3518{
3519 struct sd *sd = (struct sd *) gspca_dev;
3520
3521 sd->brightness = val;
3522 if (gspca_dev->streaming)
3523 setbrightness(gspca_dev);
3524 return 0;
3525}
3526
3527static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
3528{
3529 struct sd *sd = (struct sd *) gspca_dev;
3530
3531 *val = sd->brightness;
3532 return 0;
3533}
3534
3535static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
3536{
3537 struct sd *sd = (struct sd *) gspca_dev;
3538
3539 sd->contrast = val;
3540 if (gspca_dev->streaming)
3541 setcontrast(gspca_dev);
3542 return 0;
3543}
3544
3545static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
3546{
3547 struct sd *sd = (struct sd *) gspca_dev;
3548
3549 *val = sd->contrast;
3550 return 0;
3551}
3552
3553static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
3554{
3555 struct sd *sd = (struct sd *) gspca_dev;
3556
3557 sd->colors = val;
3558 if (gspca_dev->streaming)
3559 setcolors(gspca_dev);
3560 return 0;
3561}
3562
3563static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
3564{
3565 struct sd *sd = (struct sd *) gspca_dev;
3566
3567 *val = sd->colors;
3568 return 0;
3569}
3570
3095static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val) 3571static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val)
3096{ 3572{
3097 struct sd *sd = (struct sd *) gspca_dev; 3573 struct sd *sd = (struct sd *) gspca_dev;