diff options
author | Jean-Francois Moine <moinejf@free.fr> | 2009-01-08 14:29:38 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-03-30 11:42:30 -0400 |
commit | a0306bfa011d86899f3e88d35b6ffe525271bafc (patch) | |
tree | 05bca5b4a322b844028e7b2b58f51ee82c79f464 | |
parent | 3ab67baf36c1f5356afb6424aca77866d91a6b5b (diff) |
V4L/DVB (10347): gspca - mars: Optimize, rewrite initialization and add controls.
Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r-- | drivers/media/video/gspca/mars.c | 435 |
1 files changed, 243 insertions, 192 deletions
diff --git a/drivers/media/video/gspca/mars.c b/drivers/media/video/gspca/mars.c index 54c68ea7e546..e85ba1aa8bd3 100644 --- a/drivers/media/video/gspca/mars.c +++ b/drivers/media/video/gspca/mars.c | |||
@@ -32,16 +32,86 @@ MODULE_LICENSE("GPL"); | |||
32 | /* specific webcam descriptor */ | 32 | /* specific webcam descriptor */ |
33 | struct sd { | 33 | struct sd { |
34 | struct gspca_dev gspca_dev; /* !! must be the first item */ | 34 | struct gspca_dev gspca_dev; /* !! must be the first item */ |
35 | |||
36 | u8 brightness; | ||
37 | u8 colors; | ||
38 | u8 gamma; | ||
39 | u8 sharpness; | ||
35 | }; | 40 | }; |
36 | 41 | ||
37 | /* V4L2 controls supported by the driver */ | 42 | /* V4L2 controls supported by the driver */ |
43 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); | ||
44 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); | ||
45 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); | ||
46 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); | ||
47 | static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val); | ||
48 | static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val); | ||
49 | static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val); | ||
50 | static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val); | ||
51 | |||
38 | static struct ctrl sd_ctrls[] = { | 52 | static struct ctrl sd_ctrls[] = { |
53 | { | ||
54 | { | ||
55 | .id = V4L2_CID_BRIGHTNESS, | ||
56 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
57 | .name = "Brightness", | ||
58 | .minimum = 0, | ||
59 | .maximum = 30, | ||
60 | .step = 1, | ||
61 | #define BRIGHTNESS_DEF 15 | ||
62 | .default_value = BRIGHTNESS_DEF, | ||
63 | }, | ||
64 | .set = sd_setbrightness, | ||
65 | .get = sd_getbrightness, | ||
66 | }, | ||
67 | { | ||
68 | { | ||
69 | .id = V4L2_CID_SATURATION, | ||
70 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
71 | .name = "Color", | ||
72 | .minimum = 0, | ||
73 | .maximum = 220, | ||
74 | .step = 1, | ||
75 | #define COLOR_DEF 190 | ||
76 | .default_value = COLOR_DEF, | ||
77 | }, | ||
78 | .set = sd_setcolors, | ||
79 | .get = sd_getcolors, | ||
80 | }, | ||
81 | { | ||
82 | { | ||
83 | .id = V4L2_CID_GAMMA, | ||
84 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
85 | .name = "Gamma", | ||
86 | .minimum = 0, | ||
87 | .maximum = 3, | ||
88 | .step = 1, | ||
89 | #define GAMMA_DEF 1 | ||
90 | .default_value = GAMMA_DEF, | ||
91 | }, | ||
92 | .set = sd_setgamma, | ||
93 | .get = sd_getgamma, | ||
94 | }, | ||
95 | { | ||
96 | { | ||
97 | .id = V4L2_CID_SHARPNESS, | ||
98 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
99 | .name = "Sharpness", | ||
100 | .minimum = 0, | ||
101 | .maximum = 2, | ||
102 | .step = 1, | ||
103 | #define SHARPNESS_DEF 1 | ||
104 | .default_value = SHARPNESS_DEF, | ||
105 | }, | ||
106 | .set = sd_setsharpness, | ||
107 | .get = sd_getsharpness, | ||
108 | }, | ||
39 | }; | 109 | }; |
40 | 110 | ||
41 | static const struct v4l2_pix_format vga_mode[] = { | 111 | static const struct v4l2_pix_format vga_mode[] = { |
42 | {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | 112 | {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, |
43 | .bytesperline = 320, | 113 | .bytesperline = 320, |
44 | .sizeimage = 320 * 240 * 3 / 8 + 589, | 114 | .sizeimage = 320 * 240 * 3 / 8 + 590, |
45 | .colorspace = V4L2_COLORSPACE_JPEG, | 115 | .colorspace = V4L2_COLORSPACE_JPEG, |
46 | .priv = 2}, | 116 | .priv = 2}, |
47 | {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | 117 | {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, |
@@ -51,76 +121,62 @@ static const struct v4l2_pix_format vga_mode[] = { | |||
51 | .priv = 1}, | 121 | .priv = 1}, |
52 | }; | 122 | }; |
53 | 123 | ||
54 | /* MI Register table //elvis */ | 124 | static const __u8 mi_data[0x20] = { |
55 | enum { | 125 | /* 01 02 03 04 05 06 07 08 */ |
56 | REG_HW_MI_0, | 126 | 0x48, 0x22, 0x01, 0x47, 0x10, 0x00, 0x00, 0x00, |
57 | REG_HW_MI_1, | 127 | /* 09 0a 0b 0c 0d 0e 0f 10 */ |
58 | REG_HW_MI_2, | 128 | 0x00, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, |
59 | REG_HW_MI_3, | 129 | /* 11 12 13 14 15 16 17 18 */ |
60 | REG_HW_MI_4, | 130 | 0x30, 0x00, 0x04, 0x00, 0x06, 0x01, 0xe2, 0x02, |
61 | REG_HW_MI_5, | 131 | /* 19 1a 1b 1c 1d 1e 1f 20 */ |
62 | REG_HW_MI_6, | 132 | 0x82, 0x00, 0x20, 0x17, 0x80, 0x08, 0x0c, 0x00 |
63 | REG_HW_MI_7, | ||
64 | REG_HW_MI_9 = 0x09, | ||
65 | REG_HW_MI_B = 0x0B, | ||
66 | REG_HW_MI_C, | ||
67 | REG_HW_MI_D, | ||
68 | REG_HW_MI_1E = 0x1E, | ||
69 | REG_HW_MI_20 = 0x20, | ||
70 | REG_HW_MI_2B = 0x2B, | ||
71 | REG_HW_MI_2C, | ||
72 | REG_HW_MI_2D, | ||
73 | REG_HW_MI_2E, | ||
74 | REG_HW_MI_35 = 0x35, | ||
75 | REG_HW_MI_5F = 0x5f, | ||
76 | REG_HW_MI_60, | ||
77 | REG_HW_MI_61, | ||
78 | REG_HW_MI_62, | ||
79 | REG_HW_MI_63, | ||
80 | REG_HW_MI_64, | ||
81 | REG_HW_MI_F1 = 0xf1, | ||
82 | ATTR_TOTAL_MI_REG = 0xf2 | ||
83 | }; | 133 | }; |
84 | 134 | ||
85 | /* the bytes to write are in gspca_dev->usb_buf */ | 135 | /* write <len> bytes from gspca_dev->usb_buf */ |
86 | static int reg_w(struct gspca_dev *gspca_dev, | 136 | static int reg_w(struct gspca_dev *gspca_dev, |
87 | __u16 index, int len) | 137 | int len) |
88 | { | 138 | { |
89 | int rc; | 139 | int alen, ret; |
90 | 140 | ||
91 | rc = usb_control_msg(gspca_dev->dev, | 141 | ret = usb_bulk_msg(gspca_dev->dev, |
92 | usb_sndbulkpipe(gspca_dev->dev, 4), | 142 | usb_sndbulkpipe(gspca_dev->dev, 4), |
93 | 0x12, | 143 | gspca_dev->usb_buf, |
94 | 0xc8, /* ?? */ | 144 | len, |
95 | 0, /* value */ | 145 | &alen, |
96 | index, gspca_dev->usb_buf, len, 500); | 146 | 500); /* timeout in milliseconds */ |
97 | if (rc < 0) | 147 | if (ret < 0) |
98 | PDEBUG(D_ERR, "reg write [%02x] error %d", index, rc); | 148 | PDEBUG(D_ERR, "reg write [%02x] error %d", |
99 | return rc; | 149 | gspca_dev->usb_buf[0], ret); |
150 | return ret; | ||
100 | } | 151 | } |
101 | 152 | ||
102 | static void bulk_w(struct gspca_dev *gspca_dev, | 153 | static void mi_w(struct gspca_dev *gspca_dev, |
103 | __u16 *pch, | 154 | u8 addr, |
104 | __u16 Address) | 155 | u8 value) |
105 | { | 156 | { |
106 | gspca_dev->usb_buf[0] = 0x1f; | 157 | gspca_dev->usb_buf[0] = 0x1f; |
107 | gspca_dev->usb_buf[1] = 0; /* control byte */ | 158 | gspca_dev->usb_buf[1] = 0; /* control byte */ |
108 | gspca_dev->usb_buf[2] = Address; | 159 | gspca_dev->usb_buf[2] = addr; |
109 | gspca_dev->usb_buf[3] = *pch >> 8; /* high byte */ | 160 | gspca_dev->usb_buf[3] = value; |
110 | gspca_dev->usb_buf[4] = *pch; /* low byte */ | ||
111 | 161 | ||
112 | reg_w(gspca_dev, Address, 5); | 162 | reg_w(gspca_dev, 4); |
113 | } | 163 | } |
114 | 164 | ||
115 | /* this function is called at probe time */ | 165 | /* this function is called at probe time */ |
116 | static int sd_config(struct gspca_dev *gspca_dev, | 166 | static int sd_config(struct gspca_dev *gspca_dev, |
117 | const struct usb_device_id *id) | 167 | const struct usb_device_id *id) |
118 | { | 168 | { |
169 | struct sd *sd = (struct sd *) gspca_dev; | ||
119 | struct cam *cam; | 170 | struct cam *cam; |
120 | 171 | ||
121 | cam = &gspca_dev->cam; | 172 | cam = &gspca_dev->cam; |
122 | cam->cam_mode = vga_mode; | 173 | cam->cam_mode = vga_mode; |
123 | cam->nmodes = ARRAY_SIZE(vga_mode); | 174 | cam->nmodes = ARRAY_SIZE(vga_mode); |
175 | sd->brightness = BRIGHTNESS_DEF; | ||
176 | sd->colors = COLOR_DEF; | ||
177 | sd->gamma = GAMMA_DEF; | ||
178 | sd->sharpness = SHARPNESS_DEF; | ||
179 | gspca_dev->iface = 9; /* use the altsetting 08 */ | ||
124 | return 0; | 180 | return 0; |
125 | } | 181 | } |
126 | 182 | ||
@@ -132,24 +188,16 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
132 | 188 | ||
133 | static int sd_start(struct gspca_dev *gspca_dev) | 189 | static int sd_start(struct gspca_dev *gspca_dev) |
134 | { | 190 | { |
191 | struct sd *sd = (struct sd *) gspca_dev; | ||
135 | int err_code; | 192 | int err_code; |
136 | __u8 *data; | 193 | u8 *data; |
137 | __u16 *MI_buf; | 194 | int i, val; |
138 | int h_size, v_size; | ||
139 | int intpipe; | ||
140 | |||
141 | PDEBUG(D_STREAM, "camera start, iface %d, alt 8", gspca_dev->iface); | ||
142 | err_code = usb_set_interface(gspca_dev->dev, gspca_dev->iface, 8); | ||
143 | if (err_code < 0) { | ||
144 | PDEBUG(D_ERR|D_STREAM, "Set packet size: set interface error"); | ||
145 | return err_code; | ||
146 | } | ||
147 | 195 | ||
148 | data = gspca_dev->usb_buf; | 196 | data = gspca_dev->usb_buf; |
197 | |||
149 | data[0] = 0x01; /* address */ | 198 | data[0] = 0x01; /* address */ |
150 | data[1] = 0x01; | 199 | data[1] = 0x01; |
151 | 200 | err_code = reg_w(gspca_dev, 2); | |
152 | err_code = reg_w(gspca_dev, data[0], 2); | ||
153 | if (err_code < 0) | 201 | if (err_code < 0) |
154 | return err_code; | 202 | return err_code; |
155 | 203 | ||
@@ -159,30 +207,28 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
159 | data[0] = 0x00; /* address */ | 207 | data[0] = 0x00; /* address */ |
160 | data[1] = 0x0c | 0x01; /* reg 0 */ | 208 | data[1] = 0x0c | 0x01; /* reg 0 */ |
161 | data[2] = 0x01; /* reg 1 */ | 209 | data[2] = 0x01; /* reg 1 */ |
162 | h_size = gspca_dev->width; | 210 | data[3] = gspca_dev->width / 8; /* h_size , reg 2 */ |
163 | v_size = gspca_dev->height; | 211 | data[4] = gspca_dev->height / 8; /* v_size , reg 3 */ |
164 | data[3] = h_size / 8; /* h_size , reg 2 */ | ||
165 | data[4] = v_size / 8; /* v_size , reg 3 */ | ||
166 | data[5] = 0x30; /* reg 4, MI, PAS5101 : | 212 | data[5] = 0x30; /* reg 4, MI, PAS5101 : |
167 | * 0x30 for 24mhz , 0x28 for 12mhz */ | 213 | * 0x30 for 24mhz , 0x28 for 12mhz */ |
168 | data[6] = 4; /* reg 5, H start */ | 214 | data[6] = 0x02; /* reg 5, H start - was 0x04 */ |
169 | data[7] = 0xc0; /* reg 6, gamma 1.5 */ | 215 | data[7] = sd->gamma * 0x40; /* reg 0x06: gamma */ |
170 | data[8] = 3; /* reg 7, V start */ | 216 | data[8] = 0x01; /* reg 7, V start - was 0x03 */ |
171 | /* if (h_size == 320 ) */ | 217 | /* if (h_size == 320 ) */ |
172 | /* data[9]= 0x56; * reg 8, 24MHz, 2:1 scale down */ | 218 | /* data[9]= 0x56; * reg 8, 24MHz, 2:1 scale down */ |
173 | /* else */ | 219 | /* else */ |
174 | data[9] = 0x52; /* reg 8, 24MHz, no scale down */ | 220 | data[9] = 0x52; /* reg 8, 24MHz, no scale down */ |
175 | data[10] = 0x5d; /* reg 9, I2C device address | 221 | /*jfm: from win trace*/ |
176 | * [for PAS5101 (0x40)] [for MI (0x5d)] */ | 222 | data[10] = 0x18; |
177 | 223 | ||
178 | err_code = reg_w(gspca_dev, data[0], 11); | 224 | err_code = reg_w(gspca_dev, 11); |
179 | if (err_code < 0) | 225 | if (err_code < 0) |
180 | return err_code; | 226 | return err_code; |
181 | 227 | ||
182 | data[0] = 0x23; /* address */ | 228 | data[0] = 0x23; /* address */ |
183 | data[1] = 0x09; /* reg 35, append frame header */ | 229 | data[1] = 0x09; /* reg 35, append frame header */ |
184 | 230 | ||
185 | err_code = reg_w(gspca_dev, data[0], 2); | 231 | err_code = reg_w(gspca_dev, 2); |
186 | if (err_code < 0) | 232 | if (err_code < 0) |
187 | return err_code; | 233 | return err_code; |
188 | 234 | ||
@@ -193,137 +239,55 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
193 | /* else */ | 239 | /* else */ |
194 | data[1] = 50; /* 50 reg 60, pc-cam frame size | 240 | data[1] = 50; /* 50 reg 60, pc-cam frame size |
195 | * (unit: 4KB) 200KB */ | 241 | * (unit: 4KB) 200KB */ |
196 | err_code = reg_w(gspca_dev, data[0], 2); | 242 | err_code = reg_w(gspca_dev, 2); |
197 | if (err_code < 0) | 243 | if (err_code < 0) |
198 | return err_code; | 244 | return err_code; |
199 | 245 | ||
200 | if (0) { /* fixed dark-gain */ | ||
201 | data[1] = 0; /* reg 94, Y Gain (1.75) */ | ||
202 | data[2] = 0; /* reg 95, UV Gain (1.75) */ | ||
203 | data[3] = 0x3f; /* reg 96, Y Gain/UV Gain/disable | ||
204 | * auto dark-gain */ | ||
205 | data[4] = 0; /* reg 97, set fixed dark level */ | ||
206 | data[5] = 0; /* reg 98, don't care */ | ||
207 | } else { /* auto dark-gain */ | ||
208 | data[1] = 0; /* reg 94, Y Gain (auto) */ | ||
209 | data[2] = 0; /* reg 95, UV Gain (1.75) */ | ||
210 | data[3] = 0x78; /* reg 96, Y Gain/UV Gain/disable | ||
211 | * auto dark-gain */ | ||
212 | switch (gspca_dev->width) { | ||
213 | /* case 1280: */ | ||
214 | /* data[4] = 154; | ||
215 | * reg 97, %3 shadow point (unit: 256 pixel) */ | ||
216 | /* data[5] = 51; | ||
217 | * reg 98, %1 highlight point | ||
218 | * (uint: 256 pixel) */ | ||
219 | /* break; */ | ||
220 | default: | ||
221 | /* case 640: */ | ||
222 | data[4] = 36; /* reg 97, %3 shadow point | ||
223 | * (unit: 256 pixel) */ | ||
224 | data[5] = 12; /* reg 98, %1 highlight point | ||
225 | * (uint: 256 pixel) */ | ||
226 | break; | ||
227 | case 320: | ||
228 | data[4] = 9; /* reg 97, %3 shadow point | ||
229 | * (unit: 256 pixel) */ | ||
230 | data[5] = 3; /* reg 98, %1 highlight point | ||
231 | * (uint: 256 pixel) */ | ||
232 | break; | ||
233 | } | ||
234 | } | ||
235 | /* auto dark-gain */ | 246 | /* auto dark-gain */ |
236 | data[0] = 0x5e; /* address */ | 247 | data[0] = 0x5e; /* address */ |
237 | 248 | data[1] = 0; /* reg 94, Y Gain (auto) */ | |
238 | err_code = reg_w(gspca_dev, data[0], 6); | 249 | /*jfm: from win trace*/ |
250 | val = sd->colors * 0x40 + 0x400; | ||
251 | data[2] = val; /* reg 0x5f/0x60 (LE) = saturation */ | ||
252 | data[3] = val >> 8; | ||
253 | data[4] = sd->brightness; /* reg 0x61 = brightness */ | ||
254 | data[5] = 0x00; | ||
255 | |||
256 | err_code = reg_w(gspca_dev, 6); | ||
239 | if (err_code < 0) | 257 | if (err_code < 0) |
240 | return err_code; | 258 | return err_code; |
241 | 259 | ||
242 | data[0] = 0x67; | 260 | data[0] = 0x67; |
243 | data[1] = 0x13; /* reg 103, first pixel B, disable sharpness */ | 261 | /*jfm: from win trace*/ |
244 | err_code = reg_w(gspca_dev, data[0], 2); | 262 | data[1] = sd->sharpness * 4 + 3; |
263 | data[2] = 0x14; | ||
264 | err_code = reg_w(gspca_dev, 3); | ||
245 | if (err_code < 0) | 265 | if (err_code < 0) |
246 | return err_code; | 266 | return err_code; |
247 | 267 | ||
248 | /* | 268 | data[0] = 0x69; |
249 | * initialize the value of MI sensor... | 269 | data[1] = 0x2f; |
250 | */ | 270 | data[2] = 0x28; |
251 | MI_buf = kzalloc(ATTR_TOTAL_MI_REG * sizeof *MI_buf, GFP_KERNEL); | 271 | data[3] = 0x42; |
252 | MI_buf[REG_HW_MI_1] = 0x000a; | 272 | err_code = reg_w(gspca_dev, 4); |
253 | MI_buf[REG_HW_MI_2] = 0x000c; | 273 | if (err_code < 0) |
254 | MI_buf[REG_HW_MI_3] = 0x0405; | 274 | return err_code; |
255 | MI_buf[REG_HW_MI_4] = 0x0507; | 275 | |
256 | /* mi_Attr_Reg_[REG_HW_MI_5] = 0x01ff;//13 */ | 276 | data[0] = 0x63; |
257 | MI_buf[REG_HW_MI_5] = 0x0013; /* 13 */ | 277 | data[1] = 0x07; |
258 | MI_buf[REG_HW_MI_6] = 0x001f; /* vertical blanking */ | 278 | err_code = reg_w(gspca_dev, 2); |
259 | /* mi_Attr_Reg_[REG_HW_MI_6] = 0x0400; // vertical blanking */ | 279 | /*jfm: win trace - many writes here to reg 0x64*/ |
260 | MI_buf[REG_HW_MI_7] = 0x0002; | 280 | if (err_code < 0) |
261 | /* mi_Attr_Reg_[REG_HW_MI_9] = 0x015f; */ | 281 | return err_code; |
262 | /* mi_Attr_Reg_[REG_HW_MI_9] = 0x030f; */ | 282 | |
263 | MI_buf[REG_HW_MI_9] = 0x0374; | 283 | /* initialize the MI sensor */ |
264 | MI_buf[REG_HW_MI_B] = 0x0000; | 284 | for (i = 0; i < sizeof mi_data; i++) |
265 | MI_buf[REG_HW_MI_C] = 0x0000; | 285 | mi_w(gspca_dev, i + 1, mi_data[i]); |
266 | MI_buf[REG_HW_MI_D] = 0x0000; | ||
267 | MI_buf[REG_HW_MI_1E] = 0x8000; | ||
268 | /* mi_Attr_Reg_[REG_HW_MI_20] = 0x1104; */ | ||
269 | MI_buf[REG_HW_MI_20] = 0x1104; /* 0x111c; */ | ||
270 | MI_buf[REG_HW_MI_2B] = 0x0008; | ||
271 | /* mi_Attr_Reg_[REG_HW_MI_2C] = 0x000f; */ | ||
272 | MI_buf[REG_HW_MI_2C] = 0x001f; /* lita suggest */ | ||
273 | MI_buf[REG_HW_MI_2D] = 0x0008; | ||
274 | MI_buf[REG_HW_MI_2E] = 0x0008; | ||
275 | MI_buf[REG_HW_MI_35] = 0x0051; | ||
276 | MI_buf[REG_HW_MI_5F] = 0x0904; /* fail to write */ | ||
277 | MI_buf[REG_HW_MI_60] = 0x0000; | ||
278 | MI_buf[REG_HW_MI_61] = 0x0000; | ||
279 | MI_buf[REG_HW_MI_62] = 0x0498; | ||
280 | MI_buf[REG_HW_MI_63] = 0x0000; | ||
281 | MI_buf[REG_HW_MI_64] = 0x0000; | ||
282 | MI_buf[REG_HW_MI_F1] = 0x0001; | ||
283 | /* changing while setting up the different value of dx/dy */ | ||
284 | |||
285 | if (gspca_dev->width != 1280) { | ||
286 | MI_buf[0x01] = 0x010a; | ||
287 | MI_buf[0x02] = 0x014c; | ||
288 | MI_buf[0x03] = 0x01e5; | ||
289 | MI_buf[0x04] = 0x0287; | ||
290 | } | ||
291 | MI_buf[0x20] = 0x1104; | ||
292 | |||
293 | bulk_w(gspca_dev, MI_buf + 1, 1); | ||
294 | bulk_w(gspca_dev, MI_buf + 2, 2); | ||
295 | bulk_w(gspca_dev, MI_buf + 3, 3); | ||
296 | bulk_w(gspca_dev, MI_buf + 4, 4); | ||
297 | bulk_w(gspca_dev, MI_buf + 5, 5); | ||
298 | bulk_w(gspca_dev, MI_buf + 6, 6); | ||
299 | bulk_w(gspca_dev, MI_buf + 7, 7); | ||
300 | bulk_w(gspca_dev, MI_buf + 9, 9); | ||
301 | bulk_w(gspca_dev, MI_buf + 0x0b, 0x0b); | ||
302 | bulk_w(gspca_dev, MI_buf + 0x0c, 0x0c); | ||
303 | bulk_w(gspca_dev, MI_buf + 0x0d, 0x0d); | ||
304 | bulk_w(gspca_dev, MI_buf + 0x1e, 0x1e); | ||
305 | bulk_w(gspca_dev, MI_buf + 0x20, 0x20); | ||
306 | bulk_w(gspca_dev, MI_buf + 0x2b, 0x2b); | ||
307 | bulk_w(gspca_dev, MI_buf + 0x2c, 0x2c); | ||
308 | bulk_w(gspca_dev, MI_buf + 0x2d, 0x2d); | ||
309 | bulk_w(gspca_dev, MI_buf + 0x2e, 0x2e); | ||
310 | bulk_w(gspca_dev, MI_buf + 0x35, 0x35); | ||
311 | bulk_w(gspca_dev, MI_buf + 0x5f, 0x5f); | ||
312 | bulk_w(gspca_dev, MI_buf + 0x60, 0x60); | ||
313 | bulk_w(gspca_dev, MI_buf + 0x61, 0x61); | ||
314 | bulk_w(gspca_dev, MI_buf + 0x62, 0x62); | ||
315 | bulk_w(gspca_dev, MI_buf + 0x63, 0x63); | ||
316 | bulk_w(gspca_dev, MI_buf + 0x64, 0x64); | ||
317 | bulk_w(gspca_dev, MI_buf + 0xf1, 0xf1); | ||
318 | kfree(MI_buf); | ||
319 | |||
320 | intpipe = usb_sndintpipe(gspca_dev->dev, 0); | ||
321 | err_code = usb_clear_halt(gspca_dev->dev, intpipe); | ||
322 | 286 | ||
323 | data[0] = 0x00; | 287 | data[0] = 0x00; |
324 | data[1] = 0x4d; /* ISOC transfering enable... */ | 288 | data[1] = 0x4d; /* ISOC transfering enable... */ |
325 | reg_w(gspca_dev, data[0], 2); | 289 | reg_w(gspca_dev, 2); |
326 | return err_code; | 290 | return 0; |
327 | } | 291 | } |
328 | 292 | ||
329 | static void sd_stopN(struct gspca_dev *gspca_dev) | 293 | static void sd_stopN(struct gspca_dev *gspca_dev) |
@@ -332,7 +296,7 @@ static void sd_stopN(struct gspca_dev *gspca_dev) | |||
332 | 296 | ||
333 | gspca_dev->usb_buf[0] = 1; | 297 | gspca_dev->usb_buf[0] = 1; |
334 | gspca_dev->usb_buf[1] = 0; | 298 | gspca_dev->usb_buf[1] = 0; |
335 | result = reg_w(gspca_dev, gspca_dev->usb_buf[0], 2); | 299 | result = reg_w(gspca_dev, 2); |
336 | if (result < 0) | 300 | if (result < 0) |
337 | PDEBUG(D_ERR, "Camera Stop failed"); | 301 | PDEBUG(D_ERR, "Camera Stop failed"); |
338 | } | 302 | } |
@@ -358,7 +322,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
358 | || data[5 + p] == 0x65 | 322 | || data[5 + p] == 0x65 |
359 | || data[5 + p] == 0x66 | 323 | || data[5 + p] == 0x66 |
360 | || data[5 + p] == 0x67) { | 324 | || data[5 + p] == 0x67) { |
361 | PDEBUG(D_PACK, "sof offset: %d leng: %d", | 325 | PDEBUG(D_PACK, "sof offset: %d len: %d", |
362 | p, len); | 326 | p, len); |
363 | frame = gspca_frame_add(gspca_dev, LAST_PACKET, | 327 | frame = gspca_frame_add(gspca_dev, LAST_PACKET, |
364 | frame, data, 0); | 328 | frame, data, 0); |
@@ -374,6 +338,92 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
374 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); | 338 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); |
375 | } | 339 | } |
376 | 340 | ||
341 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) | ||
342 | { | ||
343 | struct sd *sd = (struct sd *) gspca_dev; | ||
344 | |||
345 | sd->brightness = val; | ||
346 | if (gspca_dev->streaming) { | ||
347 | gspca_dev->usb_buf[0] = 0x61; | ||
348 | gspca_dev->usb_buf[1] = val; | ||
349 | reg_w(gspca_dev, 2); | ||
350 | } | ||
351 | return 0; | ||
352 | } | ||
353 | |||
354 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) | ||
355 | { | ||
356 | struct sd *sd = (struct sd *) gspca_dev; | ||
357 | |||
358 | *val = sd->brightness; | ||
359 | return 0; | ||
360 | } | ||
361 | |||
362 | static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val) | ||
363 | { | ||
364 | struct sd *sd = (struct sd *) gspca_dev; | ||
365 | |||
366 | sd->colors = val; | ||
367 | if (gspca_dev->streaming) { | ||
368 | val = val * 0x40 + 0x400; | ||
369 | gspca_dev->usb_buf[0] = 0x5f; | ||
370 | gspca_dev->usb_buf[1] = val; | ||
371 | gspca_dev->usb_buf[2] = val >> 8; | ||
372 | reg_w(gspca_dev, 3); | ||
373 | } | ||
374 | return 0; | ||
375 | } | ||
376 | |||
377 | static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) | ||
378 | { | ||
379 | struct sd *sd = (struct sd *) gspca_dev; | ||
380 | |||
381 | *val = sd->colors; | ||
382 | return 0; | ||
383 | } | ||
384 | |||
385 | static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val) | ||
386 | { | ||
387 | struct sd *sd = (struct sd *) gspca_dev; | ||
388 | |||
389 | sd->gamma = val; | ||
390 | if (gspca_dev->streaming) { | ||
391 | gspca_dev->usb_buf[0] = 0x06; | ||
392 | gspca_dev->usb_buf[1] = val * 0x40; | ||
393 | reg_w(gspca_dev, 2); | ||
394 | } | ||
395 | return 0; | ||
396 | } | ||
397 | |||
398 | static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val) | ||
399 | { | ||
400 | struct sd *sd = (struct sd *) gspca_dev; | ||
401 | |||
402 | *val = sd->gamma; | ||
403 | return 0; | ||
404 | } | ||
405 | |||
406 | static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val) | ||
407 | { | ||
408 | struct sd *sd = (struct sd *) gspca_dev; | ||
409 | |||
410 | sd->sharpness = val; | ||
411 | if (gspca_dev->streaming) { | ||
412 | gspca_dev->usb_buf[0] = 0x67; | ||
413 | gspca_dev->usb_buf[1] = val * 4 + 3; | ||
414 | reg_w(gspca_dev, 2); | ||
415 | } | ||
416 | return 0; | ||
417 | } | ||
418 | |||
419 | static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val) | ||
420 | { | ||
421 | struct sd *sd = (struct sd *) gspca_dev; | ||
422 | |||
423 | *val = sd->sharpness; | ||
424 | return 0; | ||
425 | } | ||
426 | |||
377 | /* sub-driver description */ | 427 | /* sub-driver description */ |
378 | static const struct sd_desc sd_desc = { | 428 | static const struct sd_desc sd_desc = { |
379 | .name = MODULE_NAME, | 429 | .name = MODULE_NAME, |
@@ -416,6 +466,7 @@ static struct usb_driver sd_driver = { | |||
416 | static int __init sd_mod_init(void) | 466 | static int __init sd_mod_init(void) |
417 | { | 467 | { |
418 | int ret; | 468 | int ret; |
469 | |||
419 | ret = usb_register(&sd_driver); | 470 | ret = usb_register(&sd_driver); |
420 | if (ret < 0) | 471 | if (ret < 0) |
421 | return ret; | 472 | return ret; |