diff options
Diffstat (limited to 'drivers/media/usb/stkwebcam/stk-webcam.c')
-rw-r--r-- | drivers/media/usb/stkwebcam/stk-webcam.c | 59 |
1 files changed, 48 insertions, 11 deletions
diff --git a/drivers/media/usb/stkwebcam/stk-webcam.c b/drivers/media/usb/stkwebcam/stk-webcam.c index 5d3c032d733c..4cbab085e348 100644 --- a/drivers/media/usb/stkwebcam/stk-webcam.c +++ b/drivers/media/usb/stkwebcam/stk-webcam.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/errno.h> | 28 | #include <linux/errno.h> |
29 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
30 | 30 | ||
31 | #include <linux/dmi.h> | ||
31 | #include <linux/usb.h> | 32 | #include <linux/usb.h> |
32 | #include <linux/mm.h> | 33 | #include <linux/mm.h> |
33 | #include <linux/vmalloc.h> | 34 | #include <linux/vmalloc.h> |
@@ -38,12 +39,12 @@ | |||
38 | #include "stk-webcam.h" | 39 | #include "stk-webcam.h" |
39 | 40 | ||
40 | 41 | ||
41 | static bool hflip; | 42 | static int hflip = -1; |
42 | module_param(hflip, bool, 0444); | 43 | module_param(hflip, int, 0444); |
43 | MODULE_PARM_DESC(hflip, "Horizontal image flip (mirror). Defaults to 0"); | 44 | MODULE_PARM_DESC(hflip, "Horizontal image flip (mirror). Defaults to 0"); |
44 | 45 | ||
45 | static bool vflip; | 46 | static int vflip = -1; |
46 | module_param(vflip, bool, 0444); | 47 | module_param(vflip, int, 0444); |
47 | MODULE_PARM_DESC(vflip, "Vertical image flip. Defaults to 0"); | 48 | MODULE_PARM_DESC(vflip, "Vertical image flip. Defaults to 0"); |
48 | 49 | ||
49 | static int debug; | 50 | static int debug; |
@@ -62,6 +63,19 @@ static struct usb_device_id stkwebcam_table[] = { | |||
62 | }; | 63 | }; |
63 | MODULE_DEVICE_TABLE(usb, stkwebcam_table); | 64 | MODULE_DEVICE_TABLE(usb, stkwebcam_table); |
64 | 65 | ||
66 | /* The stk webcam laptop module is mounted upside down in some laptops :( */ | ||
67 | static const struct dmi_system_id stk_upside_down_dmi_table[] = { | ||
68 | { | ||
69 | .ident = "ASUS G1", | ||
70 | .matches = { | ||
71 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), | ||
72 | DMI_MATCH(DMI_PRODUCT_NAME, "G1") | ||
73 | } | ||
74 | }, | ||
75 | {} | ||
76 | }; | ||
77 | |||
78 | |||
65 | /* | 79 | /* |
66 | * Basic stuff | 80 | * Basic stuff |
67 | */ | 81 | */ |
@@ -466,6 +480,7 @@ static int stk_setup_siobuf(struct stk_camera *dev, int index) | |||
466 | buf->dev = dev; | 480 | buf->dev = dev; |
467 | buf->v4lbuf.index = index; | 481 | buf->v4lbuf.index = index; |
468 | buf->v4lbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 482 | buf->v4lbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
483 | buf->v4lbuf.flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; | ||
469 | buf->v4lbuf.field = V4L2_FIELD_NONE; | 484 | buf->v4lbuf.field = V4L2_FIELD_NONE; |
470 | buf->v4lbuf.memory = V4L2_MEMORY_MMAP; | 485 | buf->v4lbuf.memory = V4L2_MEMORY_MMAP; |
471 | buf->v4lbuf.m.offset = 2*index*buf->v4lbuf.length; | 486 | buf->v4lbuf.m.offset = 2*index*buf->v4lbuf.length; |
@@ -816,10 +831,16 @@ static int stk_vidioc_g_ctrl(struct file *filp, | |||
816 | c->value = dev->vsettings.brightness; | 831 | c->value = dev->vsettings.brightness; |
817 | break; | 832 | break; |
818 | case V4L2_CID_HFLIP: | 833 | case V4L2_CID_HFLIP: |
819 | c->value = dev->vsettings.hflip; | 834 | if (dmi_check_system(stk_upside_down_dmi_table)) |
835 | c->value = !dev->vsettings.hflip; | ||
836 | else | ||
837 | c->value = dev->vsettings.hflip; | ||
820 | break; | 838 | break; |
821 | case V4L2_CID_VFLIP: | 839 | case V4L2_CID_VFLIP: |
822 | c->value = dev->vsettings.vflip; | 840 | if (dmi_check_system(stk_upside_down_dmi_table)) |
841 | c->value = !dev->vsettings.vflip; | ||
842 | else | ||
843 | c->value = dev->vsettings.vflip; | ||
823 | break; | 844 | break; |
824 | default: | 845 | default: |
825 | return -EINVAL; | 846 | return -EINVAL; |
@@ -836,10 +857,16 @@ static int stk_vidioc_s_ctrl(struct file *filp, | |||
836 | dev->vsettings.brightness = c->value; | 857 | dev->vsettings.brightness = c->value; |
837 | return stk_sensor_set_brightness(dev, c->value >> 8); | 858 | return stk_sensor_set_brightness(dev, c->value >> 8); |
838 | case V4L2_CID_HFLIP: | 859 | case V4L2_CID_HFLIP: |
839 | dev->vsettings.hflip = c->value; | 860 | if (dmi_check_system(stk_upside_down_dmi_table)) |
861 | dev->vsettings.hflip = !c->value; | ||
862 | else | ||
863 | dev->vsettings.hflip = c->value; | ||
840 | return 0; | 864 | return 0; |
841 | case V4L2_CID_VFLIP: | 865 | case V4L2_CID_VFLIP: |
842 | dev->vsettings.vflip = c->value; | 866 | if (dmi_check_system(stk_upside_down_dmi_table)) |
867 | dev->vsettings.vflip = !c->value; | ||
868 | else | ||
869 | dev->vsettings.vflip = c->value; | ||
843 | return 0; | 870 | return 0; |
844 | default: | 871 | default: |
845 | return -EINVAL; | 872 | return -EINVAL; |
@@ -1113,7 +1140,7 @@ static int stk_vidioc_dqbuf(struct file *filp, | |||
1113 | sbuf->v4lbuf.flags &= ~V4L2_BUF_FLAG_QUEUED; | 1140 | sbuf->v4lbuf.flags &= ~V4L2_BUF_FLAG_QUEUED; |
1114 | sbuf->v4lbuf.flags |= V4L2_BUF_FLAG_DONE; | 1141 | sbuf->v4lbuf.flags |= V4L2_BUF_FLAG_DONE; |
1115 | sbuf->v4lbuf.sequence = ++dev->sequence; | 1142 | sbuf->v4lbuf.sequence = ++dev->sequence; |
1116 | do_gettimeofday(&sbuf->v4lbuf.timestamp); | 1143 | v4l2_get_timestamp(&sbuf->v4lbuf.timestamp); |
1117 | 1144 | ||
1118 | *buf = sbuf->v4lbuf; | 1145 | *buf = sbuf->v4lbuf; |
1119 | return 0; | 1146 | return 0; |
@@ -1275,8 +1302,18 @@ static int stk_camera_probe(struct usb_interface *interface, | |||
1275 | dev->interface = interface; | 1302 | dev->interface = interface; |
1276 | usb_get_intf(interface); | 1303 | usb_get_intf(interface); |
1277 | 1304 | ||
1278 | dev->vsettings.vflip = vflip; | 1305 | if (hflip != -1) |
1279 | dev->vsettings.hflip = hflip; | 1306 | dev->vsettings.hflip = hflip; |
1307 | else if (dmi_check_system(stk_upside_down_dmi_table)) | ||
1308 | dev->vsettings.hflip = 1; | ||
1309 | else | ||
1310 | dev->vsettings.hflip = 0; | ||
1311 | if (vflip != -1) | ||
1312 | dev->vsettings.vflip = vflip; | ||
1313 | else if (dmi_check_system(stk_upside_down_dmi_table)) | ||
1314 | dev->vsettings.vflip = 1; | ||
1315 | else | ||
1316 | dev->vsettings.vflip = 0; | ||
1280 | dev->n_sbufs = 0; | 1317 | dev->n_sbufs = 0; |
1281 | set_present(dev); | 1318 | set_present(dev); |
1282 | 1319 | ||