aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/gspca/stk014.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/gspca/stk014.c')
-rw-r--r--drivers/media/video/gspca/stk014.c170
1 files changed, 114 insertions, 56 deletions
diff --git a/drivers/media/video/gspca/stk014.c b/drivers/media/video/gspca/stk014.c
index d8c203e99cd3..6832fe0f3403 100644
--- a/drivers/media/video/gspca/stk014.c
+++ b/drivers/media/video/gspca/stk014.c
@@ -23,8 +23,8 @@
23#include "gspca.h" 23#include "gspca.h"
24#include "jpeg.h" 24#include "jpeg.h"
25 25
26#define DRIVER_VERSION_NUMBER KERNEL_VERSION(0, 2, 7) 26#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 0)
27static const char version[] = "0.2.7"; 27static const char version[] = "2.1.0";
28 28
29MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>"); 29MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>");
30MODULE_DESCRIPTION("Syntek DV4000 (STK014) USB Camera Driver"); 30MODULE_DESCRIPTION("Syntek DV4000 (STK014) USB Camera Driver");
@@ -37,10 +37,10 @@ struct sd {
37 unsigned char brightness; 37 unsigned char brightness;
38 unsigned char contrast; 38 unsigned char contrast;
39 unsigned char colors; 39 unsigned char colors;
40 unsigned char lightfreq;
40}; 41};
41 42
42/* global parameters */ 43/* global parameters */
43static int lightfreq = 50;
44static int sd_quant = 7; /* <= 4 KO - 7: good (enough!) */ 44static int sd_quant = 7; /* <= 4 KO - 7: good (enough!) */
45 45
46/* V4L2 controls supported by the driver */ 46/* V4L2 controls supported by the driver */
@@ -50,6 +50,8 @@ static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
50static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); 50static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
51static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); 51static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
52static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); 52static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
53static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
54static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
53 55
54static struct ctrl sd_ctrls[] = { 56static struct ctrl sd_ctrls[] = {
55#define SD_BRIGHTNESS 0 57#define SD_BRIGHTNESS 0
@@ -94,6 +96,20 @@ static struct ctrl sd_ctrls[] = {
94 .set = sd_setcolors, 96 .set = sd_setcolors,
95 .get = sd_getcolors, 97 .get = sd_getcolors,
96 }, 98 },
99#define SD_FREQ 3
100 {
101 {
102 .id = V4L2_CID_POWER_LINE_FREQUENCY,
103 .type = V4L2_CTRL_TYPE_MENU,
104 .name = "Light frequency filter",
105 .minimum = 1,
106 .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */
107 .step = 1,
108 .default_value = 1,
109 },
110 .set = sd_setfreq,
111 .get = sd_getfreq,
112 },
97}; 113};
98 114
99static struct cam_mode vga_mode[] = { 115static struct cam_mode vga_mode[] = {
@@ -102,11 +118,11 @@ static struct cam_mode vga_mode[] = {
102}; 118};
103 119
104/* -- read a register -- */ 120/* -- read a register -- */
105static int reg_read(struct gspca_dev *gspca_dev, 121static int reg_r(struct gspca_dev *gspca_dev,
106 __u16 index, __u8 *buf) 122 __u16 index, __u8 *buf)
107{ 123{
108 int ret;
109 struct usb_device *dev = gspca_dev->dev; 124 struct usb_device *dev = gspca_dev->dev;
125 int ret;
110 126
111 ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), 127 ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
112 0x00, 128 0x00,
@@ -116,12 +132,12 @@ static int reg_read(struct gspca_dev *gspca_dev,
116 buf, 1, 132 buf, 1,
117 500); 133 500);
118 if (ret < 0) 134 if (ret < 0)
119 PDEBUG(D_ERR, "reg_read err %d", ret); 135 PDEBUG(D_ERR, "reg_r err %d", ret);
120 return ret; 136 return ret;
121} 137}
122 138
123/* -- write a register -- */ 139/* -- write a register -- */
124static int reg_write(struct gspca_dev *gspca_dev, 140static int reg_w(struct gspca_dev *gspca_dev,
125 __u16 index, __u16 value) 141 __u16 index, __u16 value)
126{ 142{
127 struct usb_device *dev = gspca_dev->dev; 143 struct usb_device *dev = gspca_dev->dev;
@@ -136,7 +152,7 @@ static int reg_write(struct gspca_dev *gspca_dev,
136 0, 152 0,
137 500); 153 500);
138 if (ret < 0) 154 if (ret < 0)
139 PDEBUG(D_ERR, "reg_write err %d", ret); 155 PDEBUG(D_ERR, "reg_w err %d", ret);
140 return ret; 156 return ret;
141} 157}
142 158
@@ -149,15 +165,15 @@ static int rcv_val(struct gspca_dev *gspca_dev,
149 int alen, ret; 165 int alen, ret;
150 unsigned char bulk_buf[4]; 166 unsigned char bulk_buf[4];
151 167
152 reg_write(gspca_dev, 0x634, (ads >> 16) & 0xff); 168 reg_w(gspca_dev, 0x634, (ads >> 16) & 0xff);
153 reg_write(gspca_dev, 0x635, (ads >> 8) & 0xff); 169 reg_w(gspca_dev, 0x635, (ads >> 8) & 0xff);
154 reg_write(gspca_dev, 0x636, ads & 0xff); 170 reg_w(gspca_dev, 0x636, ads & 0xff);
155 reg_write(gspca_dev, 0x637, 0); 171 reg_w(gspca_dev, 0x637, 0);
156 reg_write(gspca_dev, 0x638, len & 0xff); 172 reg_w(gspca_dev, 0x638, len & 0xff);
157 reg_write(gspca_dev, 0x639, len >> 8); 173 reg_w(gspca_dev, 0x639, len >> 8);
158 reg_write(gspca_dev, 0x63a, 0); 174 reg_w(gspca_dev, 0x63a, 0);
159 reg_write(gspca_dev, 0x63b, 0); 175 reg_w(gspca_dev, 0x63b, 0);
160 reg_write(gspca_dev, 0x630, 5); 176 reg_w(gspca_dev, 0x630, 5);
161 if (len > sizeof bulk_buf) 177 if (len > sizeof bulk_buf)
162 return -1; 178 return -1;
163 ret = usb_bulk_msg(dev, 179 ret = usb_bulk_msg(dev,
@@ -180,26 +196,26 @@ static int snd_val(struct gspca_dev *gspca_dev,
180 unsigned char bulk_buf[4]; 196 unsigned char bulk_buf[4];
181 197
182 if (ads == 0x003f08) { 198 if (ads == 0x003f08) {
183 ret = reg_read(gspca_dev, 0x0704, &value); 199 ret = reg_r(gspca_dev, 0x0704, &value);
184 if (ret < 0) 200 if (ret < 0)
185 goto ko; 201 goto ko;
186 ret = reg_read(gspca_dev, 0x0705, &seq); 202 ret = reg_r(gspca_dev, 0x0705, &seq);
187 if (ret < 0) 203 if (ret < 0)
188 goto ko; 204 goto ko;
189 ret = reg_read(gspca_dev, 0x0650, &value); 205 ret = reg_r(gspca_dev, 0x0650, &value);
190 if (ret < 0) 206 if (ret < 0)
191 goto ko; 207 goto ko;
192 reg_write(gspca_dev, 0x654, seq); 208 reg_w(gspca_dev, 0x654, seq);
193 } else 209 } else
194 reg_write(gspca_dev, 0x654, (ads >> 16) & 0xff); 210 reg_w(gspca_dev, 0x654, (ads >> 16) & 0xff);
195 reg_write(gspca_dev, 0x655, (ads >> 8) & 0xff); 211 reg_w(gspca_dev, 0x655, (ads >> 8) & 0xff);
196 reg_write(gspca_dev, 0x656, ads & 0xff); 212 reg_w(gspca_dev, 0x656, ads & 0xff);
197 reg_write(gspca_dev, 0x657, 0); 213 reg_w(gspca_dev, 0x657, 0);
198 reg_write(gspca_dev, 0x658, 0x04); /* size */ 214 reg_w(gspca_dev, 0x658, 0x04); /* size */
199 reg_write(gspca_dev, 0x659, 0); 215 reg_w(gspca_dev, 0x659, 0);
200 reg_write(gspca_dev, 0x65a, 0); 216 reg_w(gspca_dev, 0x65a, 0);
201 reg_write(gspca_dev, 0x65b, 0); 217 reg_w(gspca_dev, 0x65b, 0);
202 reg_write(gspca_dev, 0x650, 5); 218 reg_w(gspca_dev, 0x650, 5);
203 bulk_buf[0] = (val >> 24) & 0xff; 219 bulk_buf[0] = (val >> 24) & 0xff;
204 bulk_buf[1] = (val >> 16) & 0xff; 220 bulk_buf[1] = (val >> 16) & 0xff;
205 bulk_buf[2] = (val >> 8) & 0xff; 221 bulk_buf[2] = (val >> 8) & 0xff;
@@ -215,7 +231,7 @@ static int snd_val(struct gspca_dev *gspca_dev,
215 if (ads == 0x003f08) { 231 if (ads == 0x003f08) {
216 seq += 4; 232 seq += 4;
217 seq &= 0x3f; 233 seq &= 0x3f;
218 reg_write(gspca_dev, 0x705, seq); 234 reg_w(gspca_dev, 0x705, seq);
219 } 235 }
220 return ret; 236 return ret;
221ko: 237ko:
@@ -235,7 +251,6 @@ static void setbrightness(struct gspca_dev *gspca_dev)
235 struct sd *sd = (struct sd *) gspca_dev; 251 struct sd *sd = (struct sd *) gspca_dev;
236 int parval; 252 int parval;
237 253
238 PDEBUG(D_CONF, "brightness: %d", sd->brightness);
239 parval = 0x06000000 /* whiteness */ 254 parval = 0x06000000 /* whiteness */
240 + (sd->brightness << 16); 255 + (sd->brightness << 16);
241 set_par(gspca_dev, parval); 256 set_par(gspca_dev, parval);
@@ -246,7 +261,6 @@ static void setcontrast(struct gspca_dev *gspca_dev)
246 struct sd *sd = (struct sd *) gspca_dev; 261 struct sd *sd = (struct sd *) gspca_dev;
247 int parval; 262 int parval;
248 263
249 PDEBUG(D_CONF, "contrast: %d", sd->contrast);
250 parval = 0x07000000 /* contrast */ 264 parval = 0x07000000 /* contrast */
251 + (sd->contrast << 16); 265 + (sd->contrast << 16);
252 set_par(gspca_dev, parval); 266 set_par(gspca_dev, parval);
@@ -257,13 +271,20 @@ static void setcolors(struct gspca_dev *gspca_dev)
257 struct sd *sd = (struct sd *) gspca_dev; 271 struct sd *sd = (struct sd *) gspca_dev;
258 int parval; 272 int parval;
259 273
260 PDEBUG(D_CONF, "saturation: %d",
261 sd->colors);
262 parval = 0x08000000 /* saturation */ 274 parval = 0x08000000 /* saturation */
263 + (sd->colors << 16); 275 + (sd->colors << 16);
264 set_par(gspca_dev, parval); 276 set_par(gspca_dev, parval);
265} 277}
266 278
279static void setfreq(struct gspca_dev *gspca_dev)
280{
281 struct sd *sd = (struct sd *) gspca_dev;
282
283 set_par(gspca_dev, sd->lightfreq == 1
284 ? 0x33640000 /* 50 Hz */
285 : 0x33780000); /* 60 Hz */
286}
287
267/* this function is called at probe time */ 288/* this function is called at probe time */
268static int sd_config(struct gspca_dev *gspca_dev, 289static int sd_config(struct gspca_dev *gspca_dev,
269 const struct usb_device_id *id) 290 const struct usb_device_id *id)
@@ -278,6 +299,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
278 sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; 299 sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value;
279 sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; 300 sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value;
280 sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value; 301 sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value;
302 sd->lightfreq = sd_ctrls[SD_FREQ].qctrl.default_value;
281 return 0; 303 return 0;
282} 304}
283 305
@@ -289,7 +311,7 @@ static int sd_open(struct gspca_dev *gspca_dev)
289 311
290 /* check if the device responds */ 312 /* check if the device responds */
291 usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1); 313 usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1);
292 ret = reg_read(gspca_dev, 0x0740, &value); 314 ret = reg_r(gspca_dev, 0x0740, &value);
293 if (ret < 0) 315 if (ret < 0)
294 return ret; 316 return ret;
295 if (value != 0xff) { 317 if (value != 0xff) {
@@ -320,21 +342,24 @@ static void sd_start(struct gspca_dev *gspca_dev)
320 ret = usb_set_interface(gspca_dev->dev, 342 ret = usb_set_interface(gspca_dev->dev,
321 gspca_dev->iface, 343 gspca_dev->iface,
322 gspca_dev->alt); 344 gspca_dev->alt);
323 if (ret < 0) 345 if (ret < 0) {
346 PDEBUG(D_ERR|D_STREAM, "set intf %d %d failed",
347 gspca_dev->iface, gspca_dev->alt);
324 goto out; 348 goto out;
325 ret = reg_read(gspca_dev, 0x0630, &dum); 349 }
350 ret = reg_r(gspca_dev, 0x0630, &dum);
326 if (ret < 0) 351 if (ret < 0)
327 goto out; 352 goto out;
328 rcv_val(gspca_dev, 0x000020, 4); /* << (value ff ff ff ff) */ 353 rcv_val(gspca_dev, 0x000020, 4); /* << (value ff ff ff ff) */
329 ret = reg_read(gspca_dev, 0x0650, &dum); 354 ret = reg_r(gspca_dev, 0x0650, &dum);
330 if (ret < 0) 355 if (ret < 0)
331 goto out; 356 goto out;
332 snd_val(gspca_dev, 0x000020, 0xffffffff); 357 snd_val(gspca_dev, 0x000020, 0xffffffff);
333 reg_write(gspca_dev, 0x0620, 0); 358 reg_w(gspca_dev, 0x0620, 0);
334 reg_write(gspca_dev, 0x0630, 0); 359 reg_w(gspca_dev, 0x0630, 0);
335 reg_write(gspca_dev, 0x0640, 0); 360 reg_w(gspca_dev, 0x0640, 0);
336 reg_write(gspca_dev, 0x0650, 0); 361 reg_w(gspca_dev, 0x0650, 0);
337 reg_write(gspca_dev, 0x0660, 0); 362 reg_w(gspca_dev, 0x0660, 0);
338 setbrightness(gspca_dev); /* whiteness */ 363 setbrightness(gspca_dev); /* whiteness */
339 setcontrast(gspca_dev); /* contrast */ 364 setcontrast(gspca_dev); /* contrast */
340 setcolors(gspca_dev); /* saturation */ 365 setcolors(gspca_dev); /* saturation */
@@ -342,9 +367,7 @@ static void sd_start(struct gspca_dev *gspca_dev)
342 set_par(gspca_dev, 0x0a800000); /* Green ? */ 367 set_par(gspca_dev, 0x0a800000); /* Green ? */
343 set_par(gspca_dev, 0x0b800000); /* Blue ? */ 368 set_par(gspca_dev, 0x0b800000); /* Blue ? */
344 set_par(gspca_dev, 0x0d030000); /* Gamma ? */ 369 set_par(gspca_dev, 0x0d030000); /* Gamma ? */
345 set_par(gspca_dev, lightfreq == 60 370 setfreq(gspca_dev); /* light frequency */
346 ? 0x33780000 /* 60 Hz */
347 : 0x33640000); /* 50 Hz */
348 371
349 /* start the video flow */ 372 /* start the video flow */
350 set_par(gspca_dev, 0x01000000); 373 set_par(gspca_dev, 0x01000000);
@@ -363,15 +386,15 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
363 set_par(gspca_dev, 0x02000000); 386 set_par(gspca_dev, 0x02000000);
364 set_par(gspca_dev, 0x02000000); 387 set_par(gspca_dev, 0x02000000);
365 usb_set_interface(dev, gspca_dev->iface, 1); 388 usb_set_interface(dev, gspca_dev->iface, 1);
366 reg_read(gspca_dev, 0x0630, &value); 389 reg_r(gspca_dev, 0x0630, &value);
367 rcv_val(gspca_dev, 0x000020, 4); /* << (value ff ff ff ff) */ 390 rcv_val(gspca_dev, 0x000020, 4); /* << (value ff ff ff ff) */
368 reg_read(gspca_dev, 0x0650, &value); 391 reg_r(gspca_dev, 0x0650, &value);
369 snd_val(gspca_dev, 0x000020, 0xffffffff); 392 snd_val(gspca_dev, 0x000020, 0xffffffff);
370 reg_write(gspca_dev, 0x0620, 0); 393 reg_w(gspca_dev, 0x0620, 0);
371 reg_write(gspca_dev, 0x0630, 0); 394 reg_w(gspca_dev, 0x0630, 0);
372 reg_write(gspca_dev, 0x0640, 0); 395 reg_w(gspca_dev, 0x0640, 0);
373 reg_write(gspca_dev, 0x0650, 0); 396 reg_w(gspca_dev, 0x0650, 0);
374 reg_write(gspca_dev, 0x0660, 0); 397 reg_w(gspca_dev, 0x0660, 0);
375 PDEBUG(D_STREAM, "camera stopped"); 398 PDEBUG(D_STREAM, "camera stopped");
376} 399}
377 400
@@ -470,6 +493,42 @@ static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
470 return 0; 493 return 0;
471} 494}
472 495
496static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
497{
498 struct sd *sd = (struct sd *) gspca_dev;
499
500 sd->lightfreq = val;
501 if (gspca_dev->streaming)
502 setfreq(gspca_dev);
503 return 0;
504}
505
506static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
507{
508 struct sd *sd = (struct sd *) gspca_dev;
509
510 *val = sd->lightfreq;
511 return 0;
512}
513
514static int sd_querymenu(struct gspca_dev *gspca_dev,
515 struct v4l2_querymenu *menu)
516{
517 switch (menu->id) {
518 case V4L2_CID_POWER_LINE_FREQUENCY:
519 switch (menu->index) {
520 case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
521 strcpy(menu->name, "50 Hz");
522 return 0;
523 case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
524 strcpy(menu->name, "60 Hz");
525 return 0;
526 }
527 break;
528 }
529 return -EINVAL;
530}
531
473/* sub-driver description */ 532/* sub-driver description */
474static struct sd_desc sd_desc = { 533static struct sd_desc sd_desc = {
475 .name = MODULE_NAME, 534 .name = MODULE_NAME,
@@ -482,6 +541,7 @@ static struct sd_desc sd_desc = {
482 .stop0 = sd_stop0, 541 .stop0 = sd_stop0,
483 .close = sd_close, 542 .close = sd_close,
484 .pkt_scan = sd_pkt_scan, 543 .pkt_scan = sd_pkt_scan,
544 .querymenu = sd_querymenu,
485}; 545};
486 546
487/* -- module initialisation -- */ 547/* -- module initialisation -- */
@@ -524,7 +584,5 @@ static void __exit sd_mod_exit(void)
524module_init(sd_mod_init); 584module_init(sd_mod_init);
525module_exit(sd_mod_exit); 585module_exit(sd_mod_exit);
526 586
527module_param(lightfreq, int, 0644);
528MODULE_PARM_DESC(lightfreq, "Light frequency 50 or 60 Hz");
529module_param_named(quant, sd_quant, int, 0644); 587module_param_named(quant, sd_quant, int, 0644);
530MODULE_PARM_DESC(quant, "Quantization index (0..8)"); 588MODULE_PARM_DESC(quant, "Quantization index (0..8)");