diff options
Diffstat (limited to 'drivers/media/video/gspca/spca501.c')
-rw-r--r-- | drivers/media/video/gspca/spca501.c | 148 |
1 files changed, 99 insertions, 49 deletions
diff --git a/drivers/media/video/gspca/spca501.c b/drivers/media/video/gspca/spca501.c index e29954c1c38c..82e3e3e2ada1 100644 --- a/drivers/media/video/gspca/spca501.c +++ b/drivers/media/video/gspca/spca501.c | |||
@@ -34,6 +34,8 @@ struct sd { | |||
34 | unsigned short contrast; | 34 | unsigned short contrast; |
35 | __u8 brightness; | 35 | __u8 brightness; |
36 | __u8 colors; | 36 | __u8 colors; |
37 | __u8 blue_balance; | ||
38 | __u8 red_balance; | ||
37 | 39 | ||
38 | char subtype; | 40 | char subtype; |
39 | #define Arowana300KCMOSCamera 0 | 41 | #define Arowana300KCMOSCamera 0 |
@@ -52,6 +54,10 @@ static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); | |||
52 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); | 54 | static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); |
53 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); | 55 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); |
54 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); | 56 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); |
57 | static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val); | ||
58 | static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val); | ||
59 | static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val); | ||
60 | static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val); | ||
55 | 61 | ||
56 | static struct ctrl sd_ctrls[] = { | 62 | static struct ctrl sd_ctrls[] = { |
57 | #define MY_BRIGHTNESS 0 | 63 | #define MY_BRIGHTNESS 0 |
@@ -63,7 +69,7 @@ static struct ctrl sd_ctrls[] = { | |||
63 | .minimum = 0, | 69 | .minimum = 0, |
64 | .maximum = 127, | 70 | .maximum = 127, |
65 | .step = 1, | 71 | .step = 1, |
66 | .default_value = 63, | 72 | .default_value = 0, |
67 | }, | 73 | }, |
68 | .set = sd_setbrightness, | 74 | .set = sd_setbrightness, |
69 | .get = sd_getbrightness, | 75 | .get = sd_getbrightness, |
@@ -75,9 +81,9 @@ static struct ctrl sd_ctrls[] = { | |||
75 | .type = V4L2_CTRL_TYPE_INTEGER, | 81 | .type = V4L2_CTRL_TYPE_INTEGER, |
76 | .name = "Contrast", | 82 | .name = "Contrast", |
77 | .minimum = 0, | 83 | .minimum = 0, |
78 | .maximum = 0xffff, | 84 | .maximum = 64725, |
79 | .step = 1, | 85 | .step = 1, |
80 | .default_value = 0xaa00, | 86 | .default_value = 64725, |
81 | }, | 87 | }, |
82 | .set = sd_setcontrast, | 88 | .set = sd_setcontrast, |
83 | .get = sd_getcontrast, | 89 | .get = sd_getcontrast, |
@@ -91,14 +97,42 @@ static struct ctrl sd_ctrls[] = { | |||
91 | .minimum = 0, | 97 | .minimum = 0, |
92 | .maximum = 63, | 98 | .maximum = 63, |
93 | .step = 1, | 99 | .step = 1, |
94 | .default_value = 31, | 100 | .default_value = 20, |
95 | }, | 101 | }, |
96 | .set = sd_setcolors, | 102 | .set = sd_setcolors, |
97 | .get = sd_getcolors, | 103 | .get = sd_getcolors, |
98 | }, | 104 | }, |
105 | #define MY_BLUE_BALANCE 3 | ||
106 | { | ||
107 | { | ||
108 | .id = V4L2_CID_BLUE_BALANCE, | ||
109 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
110 | .name = "Blue Balance", | ||
111 | .minimum = 0, | ||
112 | .maximum = 127, | ||
113 | .step = 1, | ||
114 | .default_value = 0, | ||
115 | }, | ||
116 | .set = sd_setblue_balance, | ||
117 | .get = sd_getblue_balance, | ||
118 | }, | ||
119 | #define MY_RED_BALANCE 4 | ||
120 | { | ||
121 | { | ||
122 | .id = V4L2_CID_RED_BALANCE, | ||
123 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
124 | .name = "Red Balance", | ||
125 | .minimum = 0, | ||
126 | .maximum = 127, | ||
127 | .step = 1, | ||
128 | .default_value = 0, | ||
129 | }, | ||
130 | .set = sd_setred_balance, | ||
131 | .get = sd_getred_balance, | ||
132 | }, | ||
99 | }; | 133 | }; |
100 | 134 | ||
101 | static struct v4l2_pix_format vga_mode[] = { | 135 | static const struct v4l2_pix_format vga_mode[] = { |
102 | {160, 120, V4L2_PIX_FMT_SPCA501, V4L2_FIELD_NONE, | 136 | {160, 120, V4L2_PIX_FMT_SPCA501, V4L2_FIELD_NONE, |
103 | .bytesperline = 160, | 137 | .bytesperline = 160, |
104 | .sizeimage = 160 * 120 * 3 / 2, | 138 | .sizeimage = 160 * 120 * 3 / 2, |
@@ -1822,29 +1856,6 @@ static int reg_write(struct usb_device *dev, | |||
1822 | return ret; | 1856 | return ret; |
1823 | } | 1857 | } |
1824 | 1858 | ||
1825 | /* returns: negative is error, pos or zero is data */ | ||
1826 | static int reg_read(struct gspca_dev *gspca_dev, | ||
1827 | __u16 req, /* bRequest */ | ||
1828 | __u16 index, /* wIndex */ | ||
1829 | __u16 length) /* wLength (1 or 2 only) */ | ||
1830 | { | ||
1831 | int ret; | ||
1832 | |||
1833 | gspca_dev->usb_buf[1] = 0; | ||
1834 | ret = usb_control_msg(gspca_dev->dev, | ||
1835 | usb_rcvctrlpipe(gspca_dev->dev, 0), | ||
1836 | req, | ||
1837 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
1838 | 0, /* value */ | ||
1839 | index, | ||
1840 | gspca_dev->usb_buf, length, | ||
1841 | 500); /* timeout */ | ||
1842 | if (ret < 0) { | ||
1843 | PDEBUG(D_ERR, "reg_read err %d", ret); | ||
1844 | return -1; | ||
1845 | } | ||
1846 | return (gspca_dev->usb_buf[1] << 8) + gspca_dev->usb_buf[0]; | ||
1847 | } | ||
1848 | 1859 | ||
1849 | static int write_vector(struct gspca_dev *gspca_dev, | 1860 | static int write_vector(struct gspca_dev *gspca_dev, |
1850 | const __u16 data[][3]) | 1861 | const __u16 data[][3]) |
@@ -1869,18 +1880,11 @@ static void setbrightness(struct gspca_dev *gspca_dev) | |||
1869 | { | 1880 | { |
1870 | struct sd *sd = (struct sd *) gspca_dev; | 1881 | struct sd *sd = (struct sd *) gspca_dev; |
1871 | 1882 | ||
1872 | reg_write(gspca_dev->dev, SPCA501_REG_CCDSP, 0x11, sd->brightness); | ||
1873 | reg_write(gspca_dev->dev, SPCA501_REG_CCDSP, 0x12, sd->brightness); | 1883 | reg_write(gspca_dev->dev, SPCA501_REG_CCDSP, 0x12, sd->brightness); |
1874 | reg_write(gspca_dev->dev, SPCA501_REG_CCDSP, 0x13, sd->brightness); | ||
1875 | } | 1884 | } |
1876 | 1885 | ||
1877 | static void getbrightness(struct gspca_dev *gspca_dev) | 1886 | static void getbrightness(struct gspca_dev *gspca_dev) |
1878 | { | 1887 | { |
1879 | struct sd *sd = (struct sd *) gspca_dev; | ||
1880 | __u16 brightness; | ||
1881 | |||
1882 | brightness = reg_read(gspca_dev, SPCA501_REG_CCDSP, 0x11, 2); | ||
1883 | sd->brightness = brightness << 1; | ||
1884 | } | 1888 | } |
1885 | 1889 | ||
1886 | static void setcontrast(struct gspca_dev *gspca_dev) | 1890 | static void setcontrast(struct gspca_dev *gspca_dev) |
@@ -1895,7 +1899,6 @@ static void setcontrast(struct gspca_dev *gspca_dev) | |||
1895 | 1899 | ||
1896 | static void getcontrast(struct gspca_dev *gspca_dev) | 1900 | static void getcontrast(struct gspca_dev *gspca_dev) |
1897 | { | 1901 | { |
1898 | /* spca50x->contrast = 0xaa01; */ | ||
1899 | } | 1902 | } |
1900 | 1903 | ||
1901 | static void setcolors(struct gspca_dev *gspca_dev) | 1904 | static void setcolors(struct gspca_dev *gspca_dev) |
@@ -1907,11 +1910,20 @@ static void setcolors(struct gspca_dev *gspca_dev) | |||
1907 | 1910 | ||
1908 | static void getcolors(struct gspca_dev *gspca_dev) | 1911 | static void getcolors(struct gspca_dev *gspca_dev) |
1909 | { | 1912 | { |
1913 | } | ||
1914 | |||
1915 | static void setblue_balance(struct gspca_dev *gspca_dev) | ||
1916 | { | ||
1917 | struct sd *sd = (struct sd *) gspca_dev; | ||
1918 | |||
1919 | reg_write(gspca_dev->dev, SPCA501_REG_CCDSP, 0x11, sd->blue_balance); | ||
1920 | } | ||
1921 | |||
1922 | static void setred_balance(struct gspca_dev *gspca_dev) | ||
1923 | { | ||
1910 | struct sd *sd = (struct sd *) gspca_dev; | 1924 | struct sd *sd = (struct sd *) gspca_dev; |
1911 | 1925 | ||
1912 | sd->colors = reg_read(gspca_dev, SPCA501_REG_CCDSP, 0x0c, 2); | 1926 | reg_write(gspca_dev->dev, SPCA501_REG_CCDSP, 0x13, sd->red_balance); |
1913 | /* sd->hue = (reg_read(gspca_dev, SPCA501_REG_CCDSP, 0x13, */ | ||
1914 | /* 2) & 0xFF) << 8; */ | ||
1915 | } | 1927 | } |
1916 | 1928 | ||
1917 | /* this function is called at probe time */ | 1929 | /* this function is called at probe time */ |
@@ -1930,6 +1942,14 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
1930 | sd->contrast = sd_ctrls[MY_CONTRAST].qctrl.default_value; | 1942 | sd->contrast = sd_ctrls[MY_CONTRAST].qctrl.default_value; |
1931 | sd->colors = sd_ctrls[MY_COLOR].qctrl.default_value; | 1943 | sd->colors = sd_ctrls[MY_COLOR].qctrl.default_value; |
1932 | 1944 | ||
1945 | return 0; | ||
1946 | } | ||
1947 | |||
1948 | /* this function is called at probe and resume time */ | ||
1949 | static int sd_init(struct gspca_dev *gspca_dev) | ||
1950 | { | ||
1951 | struct sd *sd = (struct sd *) gspca_dev; | ||
1952 | |||
1933 | switch (sd->subtype) { | 1953 | switch (sd->subtype) { |
1934 | case Arowana300KCMOSCamera: | 1954 | case Arowana300KCMOSCamera: |
1935 | case SmileIntlCamera: | 1955 | case SmileIntlCamera: |
@@ -1948,15 +1968,17 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
1948 | goto error; | 1968 | goto error; |
1949 | break; | 1969 | break; |
1950 | } | 1970 | } |
1971 | PDEBUG(D_STREAM, "Initializing SPCA501 finished"); | ||
1951 | return 0; | 1972 | return 0; |
1952 | error: | 1973 | error: |
1953 | return -EINVAL; | 1974 | return -EINVAL; |
1954 | } | 1975 | } |
1955 | 1976 | ||
1956 | /* this function is called at probe and resume time */ | 1977 | static int sd_start(struct gspca_dev *gspca_dev) |
1957 | static int sd_init(struct gspca_dev *gspca_dev) | ||
1958 | { | 1978 | { |
1959 | struct sd *sd = (struct sd *) gspca_dev; | 1979 | struct sd *sd = (struct sd *) gspca_dev; |
1980 | struct usb_device *dev = gspca_dev->dev; | ||
1981 | int mode; | ||
1960 | 1982 | ||
1961 | switch (sd->subtype) { | 1983 | switch (sd->subtype) { |
1962 | case ThreeComHomeConnectLite: | 1984 | case ThreeComHomeConnectLite: |
@@ -1976,14 +1998,6 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
1976 | /* Generic 501 open data */ | 1998 | /* Generic 501 open data */ |
1977 | write_vector(gspca_dev, spca501_open_data); | 1999 | write_vector(gspca_dev, spca501_open_data); |
1978 | } | 2000 | } |
1979 | PDEBUG(D_STREAM, "Initializing SPCA501 finished"); | ||
1980 | return 0; | ||
1981 | } | ||
1982 | |||
1983 | static int sd_start(struct gspca_dev *gspca_dev) | ||
1984 | { | ||
1985 | struct usb_device *dev = gspca_dev->dev; | ||
1986 | int mode; | ||
1987 | 2001 | ||
1988 | /* memorize the wanted pixel format */ | 2002 | /* memorize the wanted pixel format */ |
1989 | mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; | 2003 | mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; |
@@ -2113,6 +2127,42 @@ static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) | |||
2113 | return 0; | 2127 | return 0; |
2114 | } | 2128 | } |
2115 | 2129 | ||
2130 | static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val) | ||
2131 | { | ||
2132 | struct sd *sd = (struct sd *) gspca_dev; | ||
2133 | |||
2134 | sd->blue_balance = val; | ||
2135 | if (gspca_dev->streaming) | ||
2136 | setblue_balance(gspca_dev); | ||
2137 | return 0; | ||
2138 | } | ||
2139 | |||
2140 | static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val) | ||
2141 | { | ||
2142 | struct sd *sd = (struct sd *) gspca_dev; | ||
2143 | |||
2144 | *val = sd->blue_balance; | ||
2145 | return 0; | ||
2146 | } | ||
2147 | |||
2148 | static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val) | ||
2149 | { | ||
2150 | struct sd *sd = (struct sd *) gspca_dev; | ||
2151 | |||
2152 | sd->red_balance = val; | ||
2153 | if (gspca_dev->streaming) | ||
2154 | setred_balance(gspca_dev); | ||
2155 | return 0; | ||
2156 | } | ||
2157 | |||
2158 | static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val) | ||
2159 | { | ||
2160 | struct sd *sd = (struct sd *) gspca_dev; | ||
2161 | |||
2162 | *val = sd->red_balance; | ||
2163 | return 0; | ||
2164 | } | ||
2165 | |||
2116 | /* sub-driver description */ | 2166 | /* sub-driver description */ |
2117 | static const struct sd_desc sd_desc = { | 2167 | static const struct sd_desc sd_desc = { |
2118 | .name = MODULE_NAME, | 2168 | .name = MODULE_NAME, |