aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/gspca
diff options
context:
space:
mode:
authorJean-Francois Moine <moinejf@free.fr>2009-07-27 05:00:03 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-09-12 11:18:19 -0400
commite27188ee6bed7fae205dfeee0d22fc9fc83a3cb2 (patch)
tree5311ae8c549a9f9c10905a36ece7aaf131445492 /drivers/media/video/gspca
parent111815ef7e944d28aff9be7bee6e71a33c401a51 (diff)
V4L/DVB (12354): gspca - vc032x: H and V flip controls added for mi13x0_soc sensors
Also, H/V flip default values adjusted according to the webcam IDs. 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')
-rw-r--r--drivers/media/video/gspca/vc032x.c93
1 files changed, 53 insertions, 40 deletions
diff --git a/drivers/media/video/gspca/vc032x.c b/drivers/media/video/gspca/vc032x.c
index 1a50f8025bd1..d8e8bdc73fa4 100644
--- a/drivers/media/video/gspca/vc032x.c
+++ b/drivers/media/video/gspca/vc032x.c
@@ -52,7 +52,10 @@ struct sd {
52#define SENSOR_OV7670 6 52#define SENSOR_OV7670 6
53#define SENSOR_PO1200 7 53#define SENSOR_PO1200 7
54#define SENSOR_PO3130NC 8 54#define SENSOR_PO3130NC 8
55 u8 ninput; /* != 0 when 2 sensors - SamsungQ1 */ 55 u8 flags;
56#define FL_SAMSUNG 0x01 /* SamsungQ1 (2 sensors) */
57#define FL_HFLIP 0x02 /* mirrored by default */
58#define FL_VFLIP 0x04 /* vertical flipped by default */
56}; 59};
57 60
58/* V4L2 controls supported by the driver */ 61/* V4L2 controls supported by the driver */
@@ -66,7 +69,7 @@ static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val);
66static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val); 69static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val);
67 70
68static struct ctrl sd_ctrls[] = { 71static struct ctrl sd_ctrls[] = {
69/* next 2 controls work with ov7660 and ov7670 only */ 72/* next 2 controls work with some sensors only */
70#define HFLIP_IDX 0 73#define HFLIP_IDX 0
71 { 74 {
72 { 75 {
@@ -453,7 +456,7 @@ static const __u8 mi1310_socinitVGA_JPG[][4] = {
453 {0x5b, 0x00, 0x01, 0xbb}, 456 {0x5b, 0x00, 0x01, 0xbb},
454 {0x2f, 0xde, 0x20, 0xbb}, 457 {0x2f, 0xde, 0x20, 0xbb},
455 {0xf0, 0x00, 0x00, 0xbb}, 458 {0xf0, 0x00, 0x00, 0xbb},
456 {0x20, 0x03, 0x02, 0xbb}, 459 {0x20, 0x03, 0x02, 0xbb}, /* h/v flip */
457 {0xf0, 0x00, 0x01, 0xbb}, 460 {0xf0, 0x00, 0x01, 0xbb},
458 {0x05, 0x00, 0x07, 0xbb}, 461 {0x05, 0x00, 0x07, 0xbb},
459 {0x34, 0x00, 0x00, 0xbb}, 462 {0x34, 0x00, 0x00, 0xbb},
@@ -590,7 +593,8 @@ static const __u8 mi1310_socinitQVGA_JPG[][4] = {
590 {0xbc, 0x01, 0x01, 0xcc}, {0xf0, 0x00, 0x02, 0xbb}, 593 {0xbc, 0x01, 0x01, 0xcc}, {0xf0, 0x00, 0x02, 0xbb},
591 {0xc8, 0x9f, 0x0b, 0xbb}, {0x5b, 0x00, 0x01, 0xbb}, 594 {0xc8, 0x9f, 0x0b, 0xbb}, {0x5b, 0x00, 0x01, 0xbb},
592 {0x2f, 0xde, 0x20, 0xbb}, {0xf0, 0x00, 0x00, 0xbb}, 595 {0x2f, 0xde, 0x20, 0xbb}, {0xf0, 0x00, 0x00, 0xbb},
593 {0x20, 0x03, 0x02, 0xbb}, {0xf0, 0x00, 0x01, 0xbb}, 596 {0x20, 0x03, 0x02, 0xbb}, /* h/v flip */
597 {0xf0, 0x00, 0x01, 0xbb},
594 {0x05, 0x00, 0x07, 0xbb}, {0x34, 0x00, 0x00, 0xbb}, 598 {0x05, 0x00, 0x07, 0xbb}, {0x34, 0x00, 0x00, 0xbb},
595 {0x35, 0xff, 0x00, 0xbb}, {0xdc, 0x07, 0x02, 0xbb}, 599 {0x35, 0xff, 0x00, 0xbb}, {0xdc, 0x07, 0x02, 0xbb},
596 {0xdd, 0x3c, 0x18, 0xbb}, {0xde, 0x92, 0x6d, 0xbb}, 600 {0xdd, 0x3c, 0x18, 0xbb}, {0xde, 0x92, 0x6d, 0xbb},
@@ -677,7 +681,7 @@ static const u8 mi1310_soc_InitSXGA_JPG[][4] = {
677 {0xc8, 0x9f, 0x0b, 0xbb}, 681 {0xc8, 0x9f, 0x0b, 0xbb},
678 {0x5b, 0x00, 0x01, 0xbb}, 682 {0x5b, 0x00, 0x01, 0xbb},
679 {0xf0, 0x00, 0x00, 0xbb}, 683 {0xf0, 0x00, 0x00, 0xbb},
680 {0x20, 0x03, 0x03, 0xbb}, 684 {0x20, 0x03, 0x02, 0xbb}, /* h/v flip */
681 {0xf0, 0x00, 0x01, 0xbb}, 685 {0xf0, 0x00, 0x01, 0xbb},
682 {0x05, 0x00, 0x07, 0xbb}, 686 {0x05, 0x00, 0x07, 0xbb},
683 {0x34, 0x00, 0x00, 0xbb}, 687 {0x34, 0x00, 0x00, 0xbb},
@@ -1034,7 +1038,7 @@ static const u8 mi1320_soc_InitVGA[][4] = {
1034 {0x07, 0x00, 0xe0, 0xbb}, 1038 {0x07, 0x00, 0xe0, 0xbb},
1035 {0x08, 0x00, 0x0b, 0xbb}, 1039 {0x08, 0x00, 0x0b, 0xbb},
1036 {0x21, 0x00, 0x0c, 0xbb}, 1040 {0x21, 0x00, 0x0c, 0xbb},
1037 {0x20, 0x01, 0x03, 0xbb}, 1041 {0x20, 0x01, 0x03, 0xbb}, /* h/v flip */
1038 {0xbf, 0xc0, 0x26, 0xcc}, 1042 {0xbf, 0xc0, 0x26, 0xcc},
1039 {0xbf, 0xc1, 0x02, 0xcc}, 1043 {0xbf, 0xc1, 0x02, 0xcc},
1040 {0xbf, 0xcc, 0x04, 0xcc}, 1044 {0xbf, 0xcc, 0x04, 0xcc},
@@ -1044,7 +1048,7 @@ static const u8 mi1320_soc_InitVGA[][4] = {
1044 {0x06, 0x00, 0x11, 0xbb}, 1048 {0x06, 0x00, 0x11, 0xbb},
1045 {0x07, 0x01, 0x42, 0xbb}, 1049 {0x07, 0x01, 0x42, 0xbb},
1046 {0x08, 0x00, 0x11, 0xbb}, 1050 {0x08, 0x00, 0x11, 0xbb},
1047 {0x20, 0x01, 0x03, 0xbb}, 1051 {0x20, 0x01, 0x03, 0xbb}, /* h/v flip */
1048 {0x21, 0x80, 0x00, 0xbb}, 1052 {0x21, 0x80, 0x00, 0xbb},
1049 {0x22, 0x0d, 0x0f, 0xbb}, 1053 {0x22, 0x0d, 0x0f, 0xbb},
1050 {0x24, 0x80, 0x00, 0xbb}, 1054 {0x24, 0x80, 0x00, 0xbb},
@@ -1137,7 +1141,7 @@ static const u8 mi1320_soc_InitQVGA[][4] = {
1137 {0x07, 0x00, 0xe0, 0xbb}, 1141 {0x07, 0x00, 0xe0, 0xbb},
1138 {0x08, 0x00, 0x0b, 0xbb}, 1142 {0x08, 0x00, 0x0b, 0xbb},
1139 {0x21, 0x00, 0x0c, 0xbb}, 1143 {0x21, 0x00, 0x0c, 0xbb},
1140 {0x20, 0x01, 0x03, 0xbb}, 1144 {0x20, 0x01, 0x03, 0xbb}, /* h/v flip */
1141 {0xbf, 0xc0, 0x26, 0xcc}, 1145 {0xbf, 0xc0, 0x26, 0xcc},
1142 {0xbf, 0xc1, 0x02, 0xcc}, 1146 {0xbf, 0xc1, 0x02, 0xcc},
1143 {0xbf, 0xcc, 0x04, 0xcc}, 1147 {0xbf, 0xcc, 0x04, 0xcc},
@@ -1157,7 +1161,7 @@ static const u8 mi1320_soc_InitQVGA[][4] = {
1157 {0x06, 0x00, 0x11, 0xbb}, 1161 {0x06, 0x00, 0x11, 0xbb},
1158 {0x07, 0x01, 0x42, 0xbb}, 1162 {0x07, 0x01, 0x42, 0xbb},
1159 {0x08, 0x00, 0x11, 0xbb}, 1163 {0x08, 0x00, 0x11, 0xbb},
1160 {0x20, 0x01, 0x03, 0xbb}, 1164 {0x20, 0x01, 0x03, 0xbb}, /* h/v flip */
1161 {0x21, 0x80, 0x00, 0xbb}, 1165 {0x21, 0x80, 0x00, 0xbb},
1162 {0x22, 0x0d, 0x0f, 0xbb}, 1166 {0x22, 0x0d, 0x0f, 0xbb},
1163 {0x24, 0x80, 0x00, 0xbb}, 1167 {0x24, 0x80, 0x00, 0xbb},
@@ -1247,7 +1251,7 @@ static const u8 mi1320_soc_InitSXGA[][4] = {
1247 {0x00, 0x00, 0x20, 0xdd}, 1251 {0x00, 0x00, 0x20, 0xdd},
1248 {0xf0, 0x00, 0x00, 0xbb}, 1252 {0xf0, 0x00, 0x00, 0xbb},
1249 {0x00, 0x00, 0x30, 0xdd}, 1253 {0x00, 0x00, 0x30, 0xdd},
1250 {0x20, 0x01, 0x03, 0xbb}, 1254 {0x20, 0x01, 0x03, 0xbb}, /* h/v flip */
1251 {0x00, 0x00, 0x20, 0xdd}, 1255 {0x00, 0x00, 0x20, 0xdd},
1252 {0xbf, 0xc0, 0x26, 0xcc}, 1256 {0xbf, 0xc0, 0x26, 0xcc},
1253 {0xbf, 0xc1, 0x02, 0xcc}, 1257 {0xbf, 0xc1, 0x02, 0xcc},
@@ -1258,7 +1262,7 @@ static const u8 mi1320_soc_InitSXGA[][4] = {
1258 {0x06, 0x00, 0x11, 0xbb}, 1262 {0x06, 0x00, 0x11, 0xbb},
1259 {0x07, 0x01, 0x42, 0xbb}, 1263 {0x07, 0x01, 0x42, 0xbb},
1260 {0x08, 0x00, 0x11, 0xbb}, 1264 {0x08, 0x00, 0x11, 0xbb},
1261 {0x20, 0x01, 0x03, 0xbb}, 1265 {0x20, 0x01, 0x03, 0xbb}, /* h/v flip */
1262 {0x21, 0x80, 0x00, 0xbb}, 1266 {0x21, 0x80, 0x00, 0xbb},
1263 {0x22, 0x0d, 0x0f, 0xbb}, 1267 {0x22, 0x0d, 0x0f, 0xbb},
1264 {0x24, 0x80, 0x00, 0xbb}, 1268 {0x24, 0x80, 0x00, 0xbb},
@@ -1316,7 +1320,7 @@ static const u8 mi1320_soc_InitSXGA[][4] = {
1316 {0x06, 0x00, 0x11, 0xbb}, 1320 {0x06, 0x00, 0x11, 0xbb},
1317 {0x07, 0x00, 0x85, 0xbb}, 1321 {0x07, 0x00, 0x85, 0xbb},
1318 {0x08, 0x00, 0x27, 0xbb}, 1322 {0x08, 0x00, 0x27, 0xbb},
1319 {0x20, 0x01, 0x03, 0xbb}, 1323 {0x20, 0x01, 0x03, 0xbb}, /* h/v flip */
1320 {0x21, 0x80, 0x00, 0xbb}, 1324 {0x21, 0x80, 0x00, 0xbb},
1321 {0x22, 0x0d, 0x0f, 0xbb}, 1325 {0x22, 0x0d, 0x0f, 0xbb},
1322 {0x24, 0x80, 0x00, 0xbb}, 1326 {0x24, 0x80, 0x00, 0xbb},
@@ -2435,7 +2439,7 @@ static int vc032x_probe_sensor(struct gspca_dev *gspca_dev)
2435 const struct sensor_info *ptsensor_info; 2439 const struct sensor_info *ptsensor_info;
2436 2440
2437/*fixme: should also check the other sensor (back mi1320_soc, front mc501cb)*/ 2441/*fixme: should also check the other sensor (back mi1320_soc, front mc501cb)*/
2438 if (sd->ninput != 0) { 2442 if (sd->flags & FL_SAMSUNG) {
2439 reg_w(dev, 0xa0, 0x01, 0xb301); 2443 reg_w(dev, 0xa0, 0x01, 0xb301);
2440 reg_w(dev, 0x89, 0xf0ff, 0xffff); /* select the back sensor */ 2444 reg_w(dev, 0x89, 0xf0ff, 0xffff); /* select the back sensor */
2441 } 2445 }
@@ -2560,7 +2564,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
2560 2564
2561 cam = &gspca_dev->cam; 2565 cam = &gspca_dev->cam;
2562 sd->bridge = id->driver_info >> 8; 2566 sd->bridge = id->driver_info >> 8;
2563 sd->ninput = id->driver_info & 0xff; 2567 sd->flags = id->driver_info & 0xff;
2564 sensor = vc032x_probe_sensor(gspca_dev); 2568 sensor = vc032x_probe_sensor(gspca_dev);
2565 switch (sensor) { 2569 switch (sensor) {
2566 case -1: 2570 case -1:
@@ -2613,8 +2617,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
2613 case SENSOR_MI1320_SOC: 2617 case SENSOR_MI1320_SOC:
2614 cam->cam_mode = bi_mode; 2618 cam->cam_mode = bi_mode;
2615 cam->nmodes = ARRAY_SIZE(bi_mode); 2619 cam->nmodes = ARRAY_SIZE(bi_mode);
2616 cam->input_flags = V4L2_IN_ST_VFLIP |
2617 V4L2_IN_ST_HFLIP;
2618 break; 2620 break;
2619 default: 2621 default:
2620 cam->cam_mode = vc0323_mode; 2622 cam->cam_mode = vc0323_mode;
@@ -2626,14 +2628,14 @@ static int sd_config(struct gspca_dev *gspca_dev,
2626 2628
2627 sd->hflip = HFLIP_DEF; 2629 sd->hflip = HFLIP_DEF;
2628 sd->vflip = VFLIP_DEF; 2630 sd->vflip = VFLIP_DEF;
2629 if (sd->sensor == SENSOR_OV7670) { 2631 if (sd->sensor == SENSOR_OV7670)
2630 sd->hflip = 1; 2632 sd->flags |= FL_HFLIP | FL_VFLIP;
2631 sd->vflip = 1;
2632 }
2633 sd->lightfreq = FREQ_DEF; 2633 sd->lightfreq = FREQ_DEF;
2634 if (sd->sensor != SENSOR_OV7670) 2634 if (sd->sensor != SENSOR_OV7670)
2635 gspca_dev->ctrl_dis = (1 << LIGHTFREQ_IDX); 2635 gspca_dev->ctrl_dis = (1 << LIGHTFREQ_IDX);
2636 switch (sd->sensor) { 2636 switch (sd->sensor) {
2637 case SENSOR_MI1310_SOC:
2638 case SENSOR_MI1320_SOC:
2637 case SENSOR_OV7660: 2639 case SENSOR_OV7660:
2638 case SENSOR_OV7670: 2640 case SENSOR_OV7670:
2639 case SENSOR_PO1200: 2641 case SENSOR_PO1200:
@@ -2662,33 +2664,44 @@ static int sd_init(struct gspca_dev *gspca_dev)
2662 return 0; 2664 return 0;
2663} 2665}
2664 2666
2665/* for OV7660 and OV7670 only */ 2667/* some sensors only */
2666static void sethvflip(struct gspca_dev *gspca_dev) 2668static void sethvflip(struct gspca_dev *gspca_dev)
2667{ 2669{
2668 struct sd *sd = (struct sd *) gspca_dev; 2670 struct sd *sd = (struct sd *) gspca_dev;
2669 __u8 data; 2671 u8 data[2], hflip, vflip;
2670 2672
2673 hflip = sd->hflip;
2674 if (sd->flags & FL_HFLIP)
2675 hflip != hflip;
2676 vflip = sd->vflip;
2677 if (sd->flags & FL_VFLIP)
2678 vflip != vflip;
2671 switch (sd->sensor) { 2679 switch (sd->sensor) {
2672 case SENSOR_OV7660: 2680 case SENSOR_MI1310_SOC:
2673 data = 1; 2681 case SENSOR_MI1320_SOC:
2682 data[0] = data[1] = 0; /* select page 0 */
2683 i2c_write(gspca_dev, 0xf0, data, 2);
2684 data[0] = sd->sensor == SENSOR_MI1310_SOC ? 0x03 : 0x01;
2685 data[1] = 0x02 * hflip
2686 | 0x01 * vflip;
2687 i2c_write(gspca_dev, 0x20, data, 2);
2674 break; 2688 break;
2689 case SENSOR_OV7660:
2675 case SENSOR_OV7670: 2690 case SENSOR_OV7670:
2676 data = 7; 2691 data[0] = sd->sensor == SENSOR_OV7660 ? 0x01 : 0x07;
2692 data[0] |= OV7660_MVFP_MIRROR * hflip
2693 | OV7660_MVFP_VFLIP * vflip;
2694 i2c_write(gspca_dev, OV7660_REG_MVFP, data, 1);
2677 break; 2695 break;
2678 case SENSOR_PO1200: 2696 case SENSOR_PO1200:
2679 data = 0; 2697 data[0] = 0;
2680 i2c_write(gspca_dev, 0x03, &data, 1); 2698 i2c_write(gspca_dev, 0x03, data, 1);
2681 data = 0x80 * sd->hflip 2699 data[0] = 0x80 * hflip
2682 | 0x40 * sd->vflip 2700 | 0x40 * vflip
2683 | 0x06; 2701 | 0x06;
2684 i2c_write(gspca_dev, 0x1e, &data, 1); 2702 i2c_write(gspca_dev, 0x1e, data, 1);
2685 return; 2703 break;
2686 default:
2687 return;
2688 } 2704 }
2689 data |= OV7660_MVFP_MIRROR * sd->hflip
2690 | OV7660_MVFP_VFLIP * sd->vflip;
2691 i2c_write(gspca_dev, OV7660_REG_MVFP, &data, 1);
2692} 2705}
2693 2706
2694static void setlightfreq(struct gspca_dev *gspca_dev) 2707static void setlightfreq(struct gspca_dev *gspca_dev)
@@ -2730,7 +2743,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
2730 }; 2743 };
2731 2744
2732/*fixme: back sensor only*/ 2745/*fixme: back sensor only*/
2733 if (sd->ninput != 0) { 2746 if (sd->flags & FL_SAMSUNG) {
2734 reg_w(gspca_dev->dev, 0x89, 0xf0ff, 0xffff); 2747 reg_w(gspca_dev->dev, 0x89, 0xf0ff, 0xffff);
2735 reg_w(gspca_dev->dev, 0xa9, 0x8348, 0x000e); 2748 reg_w(gspca_dev->dev, 0xa9, 0x8348, 0x000e);
2736 reg_w(gspca_dev->dev, 0xa9, 0x0000, 0x001a); 2749 reg_w(gspca_dev->dev, 0xa9, 0x0000, 0x001a);
@@ -3024,7 +3037,7 @@ static const struct sd_desc sd_desc = {
3024 .driver_info = (BRIDGE_ ## bridge << 8) \ 3037 .driver_info = (BRIDGE_ ## bridge << 8) \
3025 | (flags) 3038 | (flags)
3026static const __devinitdata struct usb_device_id device_table[] = { 3039static const __devinitdata struct usb_device_id device_table[] = {
3027 {USB_DEVICE(0x041e, 0x405b), BF(VC0323, 0)}, 3040 {USB_DEVICE(0x041e, 0x405b), BF(VC0323, FL_VFLIP)},
3028 {USB_DEVICE(0x046d, 0x0892), BF(VC0321, 0)}, 3041 {USB_DEVICE(0x046d, 0x0892), BF(VC0321, 0)},
3029 {USB_DEVICE(0x046d, 0x0896), BF(VC0321, 0)}, 3042 {USB_DEVICE(0x046d, 0x0896), BF(VC0321, 0)},
3030 {USB_DEVICE(0x046d, 0x0897), BF(VC0321, 0)}, 3043 {USB_DEVICE(0x046d, 0x0897), BF(VC0321, 0)},
@@ -3033,7 +3046,7 @@ static const __devinitdata struct usb_device_id device_table[] = {
3033 {USB_DEVICE(0x0ac8, 0x0328), BF(VC0321, 0)}, 3046 {USB_DEVICE(0x0ac8, 0x0328), BF(VC0321, 0)},
3034 {USB_DEVICE(0x0ac8, 0xc001), BF(VC0321, 0)}, 3047 {USB_DEVICE(0x0ac8, 0xc001), BF(VC0321, 0)},
3035 {USB_DEVICE(0x0ac8, 0xc002), BF(VC0321, 0)}, 3048 {USB_DEVICE(0x0ac8, 0xc002), BF(VC0321, 0)},
3036 {USB_DEVICE(0x0ac8, 0xc301), BF(VC0323, 1)}, 3049 {USB_DEVICE(0x0ac8, 0xc301), BF(VC0323, FL_SAMSUNG)},
3037 {USB_DEVICE(0x15b8, 0x6001), BF(VC0323, 0)}, 3050 {USB_DEVICE(0x15b8, 0x6001), BF(VC0323, 0)},
3038 {USB_DEVICE(0x15b8, 0x6002), BF(VC0323, 0)}, 3051 {USB_DEVICE(0x15b8, 0x6002), BF(VC0323, 0)},
3039 {USB_DEVICE(0x17ef, 0x4802), BF(VC0323, 0)}, 3052 {USB_DEVICE(0x17ef, 0x4802), BF(VC0323, 0)},