diff options
author | Brian Johnson <brijohn@gmail.com> | 2010-03-16 12:58:27 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-05-17 23:50:08 -0400 |
commit | 7ddaac7fcb01eed38692f1bfa81f5f4348d848d7 (patch) | |
tree | c0fc6a74cc13feb2d15876f4635b41d61d9ab947 /drivers/media/video/gspca/sn9c20x.c | |
parent | 0c045eb752259d4176eabacbdf28a627644a071a (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/sn9c20x.c')
-rw-r--r-- | drivers/media/video/gspca/sn9c20x.c | 50 |
1 files changed, 40 insertions, 10 deletions
diff --git a/drivers/media/video/gspca/sn9c20x.c b/drivers/media/video/gspca/sn9c20x.c index 825d5b8dfd6f..06c75dbecaee 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 | ||
31 | MODULE_AUTHOR("Brian Johnson <brijohn@gmail.com>, " | 32 | MODULE_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 */ |
60 | struct sd { | 62 | struct sd { |
@@ -127,6 +129,25 @@ static int sd_getexposure(struct gspca_dev *gspca_dev, s32 *val); | |||
127 | static int sd_setautoexposure(struct gspca_dev *gspca_dev, s32 val); | 129 | static int sd_setautoexposure(struct gspca_dev *gspca_dev, s32 val); |
128 | static int sd_getautoexposure(struct gspca_dev *gspca_dev, s32 *val); | 130 | static int sd_getautoexposure(struct gspca_dev *gspca_dev, s32 *val); |
129 | 131 | ||
132 | static 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 | |||
130 | static const struct ctrl sd_ctrls[] = { | 151 | static 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 | ||
1497 | static int set_hvflip(struct gspca_dev *gspca_dev) | 1518 | static 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)}, |