aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/gspca
diff options
context:
space:
mode:
authorBrian Johnson <brijohn@gmail.com>2010-03-16 12:58:27 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-05-17 23:50:08 -0400
commit7ddaac7fcb01eed38692f1bfa81f5f4348d848d7 (patch)
treec0fc6a74cc13feb2d15876f4635b41d61d9ab947 /drivers/media/video/gspca
parent0c045eb752259d4176eabacbdf28a627644a071a (diff)
V4L/DVB: gspca - sn9c20x: Add upside down detection
Add support for detecting webcams that are mounted upside down in laptops. Currently the only two known are two MSI modesl using the 0c45:624f. Signed-off-by: Brian Johnson <brijohn@gmail.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/gspca')
-rw-r--r--drivers/media/video/gspca/sn9c20x.c50
1 files changed, 40 insertions, 10 deletions
diff --git a/drivers/media/video/gspca/sn9c20x.c b/drivers/media/video/gspca/sn9c20x.c
index 825d5b8dfd6..06c75dbecae 100644
--- a/drivers/media/video/gspca/sn9c20x.c
+++ b/drivers/media/video/gspca/sn9c20x.c
@@ -27,6 +27,7 @@
27#include "jpeg.h" 27#include "jpeg.h"
28 28
29#include <media/v4l2-chip-ident.h> 29#include <media/v4l2-chip-ident.h>
30#include <linux/dmi.h>
30 31
31MODULE_AUTHOR("Brian Johnson <brijohn@gmail.com>, " 32MODULE_AUTHOR("Brian Johnson <brijohn@gmail.com>, "
32 "microdia project <microdia@googlegroups.com>"); 33 "microdia project <microdia@googlegroups.com>");
@@ -55,6 +56,7 @@ MODULE_LICENSE("GPL");
55/* camera flags */ 56/* camera flags */
56#define HAS_BUTTON 0x1 57#define HAS_BUTTON 0x1
57#define LED_REVERSE 0x2 /* some cameras unset gpio to turn on leds */ 58#define LED_REVERSE 0x2 /* some cameras unset gpio to turn on leds */
59#define FLIP_DETECT 0x4
58 60
59/* specific webcam descriptor */ 61/* specific webcam descriptor */
60struct sd { 62struct sd {
@@ -127,6 +129,25 @@ static int sd_getexposure(struct gspca_dev *gspca_dev, s32 *val);
127static int sd_setautoexposure(struct gspca_dev *gspca_dev, s32 val); 129static int sd_setautoexposure(struct gspca_dev *gspca_dev, s32 val);
128static int sd_getautoexposure(struct gspca_dev *gspca_dev, s32 *val); 130static int sd_getautoexposure(struct gspca_dev *gspca_dev, s32 *val);
129 131
132static const struct dmi_system_id flip_dmi_table[] = {
133 {
134 .ident = "MSI MS-1034",
135 .matches = {
136 DMI_MATCH(DMI_SYS_VENDOR, "MICRO-STAR INT'L CO.,LTD."),
137 DMI_MATCH(DMI_PRODUCT_NAME, "MS-1034"),
138 DMI_MATCH(DMI_PRODUCT_VERSION, "0341")
139 }
140 },
141 {
142 .ident = "MSI MS-1632",
143 .matches = {
144 DMI_MATCH(DMI_BOARD_VENDOR, "MSI"),
145 DMI_MATCH(DMI_BOARD_NAME, "MS-1632")
146 }
147 },
148 {}
149};
150
130static const struct ctrl sd_ctrls[] = { 151static const struct ctrl sd_ctrls[] = {
131 { 152 {
132#define BRIGHTNESS_IDX 0 153#define BRIGHTNESS_IDX 0
@@ -1496,17 +1517,26 @@ static int set_redblue(struct gspca_dev *gspca_dev)
1496 1517
1497static int set_hvflip(struct gspca_dev *gspca_dev) 1518static int set_hvflip(struct gspca_dev *gspca_dev)
1498{ 1519{
1499 u8 value, tslb; 1520 u8 value, tslb, hflip, vflip;
1500 u16 value2; 1521 u16 value2;
1501 struct sd *sd = (struct sd *) gspca_dev; 1522 struct sd *sd = (struct sd *) gspca_dev;
1523
1524 if ((sd->flags & FLIP_DETECT) && dmi_check_system(flip_dmi_table)) {
1525 hflip = !sd->hflip;
1526 vflip = !sd->vflip;
1527 } else {
1528 hflip = sd->hflip;
1529 vflip = sd->vflip;
1530 }
1531
1502 switch (sd->sensor) { 1532 switch (sd->sensor) {
1503 case SENSOR_OV9650: 1533 case SENSOR_OV9650:
1504 i2c_r1(gspca_dev, 0x1e, &value); 1534 i2c_r1(gspca_dev, 0x1e, &value);
1505 value &= ~0x30; 1535 value &= ~0x30;
1506 tslb = 0x01; 1536 tslb = 0x01;
1507 if (sd->hflip) 1537 if (hflip)
1508 value |= 0x20; 1538 value |= 0x20;
1509 if (sd->vflip) { 1539 if (vflip) {
1510 value |= 0x10; 1540 value |= 0x10;
1511 tslb = 0x49; 1541 tslb = 0x49;
1512 } 1542 }
@@ -1517,9 +1547,9 @@ static int set_hvflip(struct gspca_dev *gspca_dev)
1517 case SENSOR_MT9V011: 1547 case SENSOR_MT9V011:
1518 i2c_r2(gspca_dev, 0x20, &value2); 1548 i2c_r2(gspca_dev, 0x20, &value2);
1519 value2 &= ~0xc0a0; 1549 value2 &= ~0xc0a0;
1520 if (sd->hflip) 1550 if (hflip)
1521 value2 |= 0x8080; 1551 value2 |= 0x8080;
1522 if (sd->vflip) 1552 if (vflip)
1523 value2 |= 0x4020; 1553 value2 |= 0x4020;
1524 i2c_w2(gspca_dev, 0x20, value2); 1554 i2c_w2(gspca_dev, 0x20, value2);
1525 break; 1555 break;
@@ -1527,18 +1557,18 @@ static int set_hvflip(struct gspca_dev *gspca_dev)
1527 case SENSOR_MT9V112: 1557 case SENSOR_MT9V112:
1528 i2c_r2(gspca_dev, 0x20, &value2); 1558 i2c_r2(gspca_dev, 0x20, &value2);
1529 value2 &= ~0x0003; 1559 value2 &= ~0x0003;
1530 if (sd->hflip) 1560 if (hflip)
1531 value2 |= 0x0002; 1561 value2 |= 0x0002;
1532 if (sd->vflip) 1562 if (vflip)
1533 value2 |= 0x0001; 1563 value2 |= 0x0001;
1534 i2c_w2(gspca_dev, 0x20, value2); 1564 i2c_w2(gspca_dev, 0x20, value2);
1535 break; 1565 break;
1536 case SENSOR_HV7131R: 1566 case SENSOR_HV7131R:
1537 i2c_r1(gspca_dev, 0x01, &value); 1567 i2c_r1(gspca_dev, 0x01, &value);
1538 value &= ~0x03; 1568 value &= ~0x03;
1539 if (sd->vflip) 1569 if (vflip)
1540 value |= 0x01; 1570 value |= 0x01;
1541 if (sd->hflip) 1571 if (hflip)
1542 value |= 0x02; 1572 value |= 0x02;
1543 i2c_w1(gspca_dev, 0x01, value); 1573 i2c_w1(gspca_dev, 0x01, value);
1544 break; 1574 break;
@@ -2371,7 +2401,7 @@ static const __devinitdata struct usb_device_id device_table[] = {
2371 {USB_DEVICE(0x0c45, 0x6248), SN9C20X(OV9655, 0x30, 0)}, 2401 {USB_DEVICE(0x0c45, 0x6248), SN9C20X(OV9655, 0x30, 0)},
2372 {USB_DEVICE(0x0c45, 0x624e), SN9C20X(SOI968, 0x30, 2402 {USB_DEVICE(0x0c45, 0x624e), SN9C20X(SOI968, 0x30,
2373 (HAS_BUTTON | LED_REVERSE))}, 2403 (HAS_BUTTON | LED_REVERSE))},
2374 {USB_DEVICE(0x0c45, 0x624f), SN9C20X(OV9650, 0x30, 0)}, 2404 {USB_DEVICE(0x0c45, 0x624f), SN9C20X(OV9650, 0x30, FLIP_DETECT)},
2375 {USB_DEVICE(0x0c45, 0x6251), SN9C20X(OV9650, 0x30, 0)}, 2405 {USB_DEVICE(0x0c45, 0x6251), SN9C20X(OV9650, 0x30, 0)},
2376 {USB_DEVICE(0x0c45, 0x6253), SN9C20X(OV9650, 0x30, 0)}, 2406 {USB_DEVICE(0x0c45, 0x6253), SN9C20X(OV9650, 0x30, 0)},
2377 {USB_DEVICE(0x0c45, 0x6260), SN9C20X(OV7670, 0x21, 0)}, 2407 {USB_DEVICE(0x0c45, 0x6260), SN9C20X(OV7670, 0x21, 0)},