aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Verkuil <hverkuil@xs4all.nl>2010-05-10 02:51:02 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-06-01 00:19:04 -0400
commit483d67ff0a208b43f0b97fca91d3a142afaba7fa (patch)
tree96447b0b3ecac1492235b076c25330a3360a604a
parent67a3e12b05e055c0415c556a315a3d3eb637e29e (diff)
V4L/DVB: bw-qcam: convert to V4L2
Note: due to lack of hardware I was not able to test this conversion. But it is pretty straightforward, so I do not expect any problems. Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r--drivers/media/video/Kconfig2
-rw-r--r--drivers/media/video/bw-qcam.c759
-rw-r--r--drivers/media/video/bw-qcam.h69
3 files changed, 415 insertions, 415 deletions
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index ad9e6f9c22e9..42d198d5a87e 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -646,7 +646,7 @@ config VIDEO_PMS
646 646
647config VIDEO_BWQCAM 647config VIDEO_BWQCAM
648 tristate "Quickcam BW Video For Linux" 648 tristate "Quickcam BW Video For Linux"
649 depends on PARPORT && VIDEO_V4L1 649 depends on PARPORT && VIDEO_V4L2
650 help 650 help
651 Say Y have if you the black and white version of the QuickCam 651 Say Y have if you the black and white version of the QuickCam
652 camera. See the next option for the color version. 652 camera. See the next option for the color version.
diff --git a/drivers/media/video/bw-qcam.c b/drivers/media/video/bw-qcam.c
index 3c9e754d73a0..935e0c9a9674 100644
--- a/drivers/media/video/bw-qcam.c
+++ b/drivers/media/video/bw-qcam.c
@@ -66,19 +66,58 @@ OTHER DEALINGS IN THE SOFTWARE.
66#include <linux/delay.h> 66#include <linux/delay.h>
67#include <linux/errno.h> 67#include <linux/errno.h>
68#include <linux/fs.h> 68#include <linux/fs.h>
69#include <linux/init.h>
70#include <linux/kernel.h> 69#include <linux/kernel.h>
71#include <linux/slab.h> 70#include <linux/slab.h>
72#include <linux/mm.h> 71#include <linux/mm.h>
73#include <linux/parport.h> 72#include <linux/parport.h>
74#include <linux/sched.h> 73#include <linux/sched.h>
75#include <linux/videodev.h> 74#include <linux/version.h>
76#include <media/v4l2-common.h> 75#include <linux/videodev2.h>
77#include <media/v4l2-ioctl.h>
78#include <linux/mutex.h> 76#include <linux/mutex.h>
79#include <asm/uaccess.h> 77#include <asm/uaccess.h>
80 78#include <media/v4l2-common.h>
81#include "bw-qcam.h" 79#include <media/v4l2-ioctl.h>
80#include <media/v4l2-device.h>
81
82/* One from column A... */
83#define QC_NOTSET 0
84#define QC_UNIDIR 1
85#define QC_BIDIR 2
86#define QC_SERIAL 3
87
88/* ... and one from column B */
89#define QC_ANY 0x00
90#define QC_FORCE_UNIDIR 0x10
91#define QC_FORCE_BIDIR 0x20
92#define QC_FORCE_SERIAL 0x30
93/* in the port_mode member */
94
95#define QC_MODE_MASK 0x07
96#define QC_FORCE_MASK 0x70
97
98#define MAX_HEIGHT 243
99#define MAX_WIDTH 336
100
101/* Bit fields for status flags */
102#define QC_PARAM_CHANGE 0x01 /* Camera status change has occurred */
103
104struct qcam {
105 struct v4l2_device v4l2_dev;
106 struct video_device vdev;
107 struct pardevice *pdev;
108 struct parport *pport;
109 struct mutex lock;
110 int width, height;
111 int bpp;
112 int mode;
113 int contrast, brightness, whitebal;
114 int port_mode;
115 int transfer_scale;
116 int top, left;
117 int status;
118 unsigned int saved_bits;
119 unsigned long in_use;
120};
82 121
83static unsigned int maxpoll = 250; /* Maximum busy-loop count for qcam I/O */ 122static unsigned int maxpoll = 250; /* Maximum busy-loop count for qcam I/O */
84static unsigned int yieldlines = 4; /* Yield after this many during capture */ 123static unsigned int yieldlines = 4; /* Yield after this many during capture */
@@ -93,22 +132,26 @@ module_param(video_nr, int, 0);
93 * immediately attempt to initialize qcam */ 132 * immediately attempt to initialize qcam */
94module_param(force_init, int, 0); 133module_param(force_init, int, 0);
95 134
96static inline int read_lpstatus(struct qcam_device *q) 135#define MAX_CAMS 4
136static struct qcam *qcams[MAX_CAMS];
137static unsigned int num_cams;
138
139static inline int read_lpstatus(struct qcam *q)
97{ 140{
98 return parport_read_status(q->pport); 141 return parport_read_status(q->pport);
99} 142}
100 143
101static inline int read_lpdata(struct qcam_device *q) 144static inline int read_lpdata(struct qcam *q)
102{ 145{
103 return parport_read_data(q->pport); 146 return parport_read_data(q->pport);
104} 147}
105 148
106static inline void write_lpdata(struct qcam_device *q, int d) 149static inline void write_lpdata(struct qcam *q, int d)
107{ 150{
108 parport_write_data(q->pport, d); 151 parport_write_data(q->pport, d);
109} 152}
110 153
111static inline void write_lpcontrol(struct qcam_device *q, int d) 154static void write_lpcontrol(struct qcam *q, int d)
112{ 155{
113 if (d & 0x20) { 156 if (d & 0x20) {
114 /* Set bidirectional mode to reverse (data in) */ 157 /* Set bidirectional mode to reverse (data in) */
@@ -124,126 +167,11 @@ static inline void write_lpcontrol(struct qcam_device *q, int d)
124 parport_write_control(q->pport, d); 167 parport_write_control(q->pport, d);
125} 168}
126 169
127static int qc_waithand(struct qcam_device *q, int val);
128static int qc_command(struct qcam_device *q, int command);
129static int qc_readparam(struct qcam_device *q);
130static int qc_setscanmode(struct qcam_device *q);
131static int qc_readbytes(struct qcam_device *q, char buffer[]);
132
133static struct video_device qcam_template;
134
135static int qc_calibrate(struct qcam_device *q)
136{
137 /*
138 * Bugfix by Hanno Mueller hmueller@kabel.de, Mai 21 96
139 * The white balance is an individiual value for each
140 * quickcam.
141 */
142
143 int value;
144 int count = 0;
145
146 qc_command(q, 27); /* AutoAdjustOffset */
147 qc_command(q, 0); /* Dummy Parameter, ignored by the camera */
148
149 /* GetOffset (33) will read 255 until autocalibration */
150 /* is finished. After that, a value of 1-254 will be */
151 /* returned. */
152
153 do {
154 qc_command(q, 33);
155 value = qc_readparam(q);
156 mdelay(1);
157 schedule();
158 count++;
159 } while (value == 0xff && count < 2048);
160
161 q->whitebal = value;
162 return value;
163}
164
165/* Initialize the QuickCam driver control structure. This is where
166 * defaults are set for people who don't have a config file.*/
167
168static struct qcam_device *qcam_init(struct parport *port)
169{
170 struct qcam_device *q;
171
172 q = kmalloc(sizeof(struct qcam_device), GFP_KERNEL);
173 if (q == NULL)
174 return NULL;
175
176 q->pport = port;
177 q->pdev = parport_register_device(port, "bw-qcam", NULL, NULL,
178 NULL, 0, NULL);
179 if (q->pdev == NULL) {
180 printk(KERN_ERR "bw-qcam: couldn't register for %s.\n",
181 port->name);
182 kfree(q);
183 return NULL;
184 }
185
186 memcpy(&q->vdev, &qcam_template, sizeof(qcam_template));
187
188 mutex_init(&q->lock);
189
190 q->port_mode = (QC_ANY | QC_NOTSET);
191 q->width = 320;
192 q->height = 240;
193 q->bpp = 4;
194 q->transfer_scale = 2;
195 q->contrast = 192;
196 q->brightness = 180;
197 q->whitebal = 105;
198 q->top = 1;
199 q->left = 14;
200 q->mode = -1;
201 q->status = QC_PARAM_CHANGE;
202 return q;
203}
204
205
206/* qc_command is probably a bit of a misnomer -- it's used to send
207 * bytes *to* the camera. Generally, these bytes are either commands
208 * or arguments to commands, so the name fits, but it still bugs me a
209 * bit. See the documentation for a list of commands. */
210
211static int qc_command(struct qcam_device *q, int command)
212{
213 int n1, n2;
214 int cmd;
215
216 write_lpdata(q, command);
217 write_lpcontrol(q, 6);
218
219 n1 = qc_waithand(q, 1);
220
221 write_lpcontrol(q, 0xe);
222 n2 = qc_waithand(q, 0);
223
224 cmd = (n1 & 0xf0) | ((n2 & 0xf0) >> 4);
225 return cmd;
226}
227
228static int qc_readparam(struct qcam_device *q)
229{
230 int n1, n2;
231 int cmd;
232
233 write_lpcontrol(q, 6);
234 n1 = qc_waithand(q, 1);
235
236 write_lpcontrol(q, 0xe);
237 n2 = qc_waithand(q, 0);
238
239 cmd = (n1 & 0xf0) | ((n2 & 0xf0) >> 4);
240 return cmd;
241}
242 170
243/* qc_waithand busy-waits for a handshake signal from the QuickCam. 171/* qc_waithand busy-waits for a handshake signal from the QuickCam.
244 * Almost all communication with the camera requires handshaking. */ 172 * Almost all communication with the camera requires handshaking. */
245 173
246static int qc_waithand(struct qcam_device *q, int val) 174static int qc_waithand(struct qcam *q, int val)
247{ 175{
248 int status; 176 int status;
249 int runs = 0; 177 int runs = 0;
@@ -286,7 +214,7 @@ static int qc_waithand(struct qcam_device *q, int val)
286 * (bit 3 of status register). It also returns the last value read, 214 * (bit 3 of status register). It also returns the last value read,
287 * since this data is useful. */ 215 * since this data is useful. */
288 216
289static unsigned int qc_waithand2(struct qcam_device *q, int val) 217static unsigned int qc_waithand2(struct qcam *q, int val)
290{ 218{
291 unsigned int status; 219 unsigned int status;
292 int runs = 0; 220 int runs = 0;
@@ -309,6 +237,43 @@ static unsigned int qc_waithand2(struct qcam_device *q, int val)
309 return status; 237 return status;
310} 238}
311 239
240/* qc_command is probably a bit of a misnomer -- it's used to send
241 * bytes *to* the camera. Generally, these bytes are either commands
242 * or arguments to commands, so the name fits, but it still bugs me a
243 * bit. See the documentation for a list of commands. */
244
245static int qc_command(struct qcam *q, int command)
246{
247 int n1, n2;
248 int cmd;
249
250 write_lpdata(q, command);
251 write_lpcontrol(q, 6);
252
253 n1 = qc_waithand(q, 1);
254
255 write_lpcontrol(q, 0xe);
256 n2 = qc_waithand(q, 0);
257
258 cmd = (n1 & 0xf0) | ((n2 & 0xf0) >> 4);
259 return cmd;
260}
261
262static int qc_readparam(struct qcam *q)
263{
264 int n1, n2;
265 int cmd;
266
267 write_lpcontrol(q, 6);
268 n1 = qc_waithand(q, 1);
269
270 write_lpcontrol(q, 0xe);
271 n2 = qc_waithand(q, 0);
272
273 cmd = (n1 & 0xf0) | ((n2 & 0xf0) >> 4);
274 return cmd;
275}
276
312 277
313/* Try to detect a QuickCam. It appears to flash the upper 4 bits of 278/* Try to detect a QuickCam. It appears to flash the upper 4 bits of
314 the status register at 5-10 Hz. This is only used in the autoprobe 279 the status register at 5-10 Hz. This is only used in the autoprobe
@@ -317,7 +282,7 @@ static unsigned int qc_waithand2(struct qcam_device *q, int val)
317 almost completely safe, while their method screws up my printer if 282 almost completely safe, while their method screws up my printer if
318 I plug it in before the camera. */ 283 I plug it in before the camera. */
319 284
320static int qc_detect(struct qcam_device *q) 285static int qc_detect(struct qcam *q)
321{ 286{
322 int reg, lastreg; 287 int reg, lastreg;
323 int count = 0; 288 int count = 0;
@@ -358,41 +323,6 @@ static int qc_detect(struct qcam_device *q)
358 } 323 }
359} 324}
360 325
361
362/* Reset the QuickCam. This uses the same sequence the Windows
363 * QuickPic program uses. Someone with a bi-directional port should
364 * check that bi-directional mode is detected right, and then
365 * implement bi-directional mode in qc_readbyte(). */
366
367static void qc_reset(struct qcam_device *q)
368{
369 switch (q->port_mode & QC_FORCE_MASK) {
370 case QC_FORCE_UNIDIR:
371 q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_UNIDIR;
372 break;
373
374 case QC_FORCE_BIDIR:
375 q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_BIDIR;
376 break;
377
378 case QC_ANY:
379 write_lpcontrol(q, 0x20);
380 write_lpdata(q, 0x75);
381
382 if (read_lpdata(q) != 0x75)
383 q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_BIDIR;
384 else
385 q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_UNIDIR;
386 break;
387 }
388
389 write_lpcontrol(q, 0xb);
390 udelay(250);
391 write_lpcontrol(q, 0xe);
392 qc_setscanmode(q); /* in case port_mode changed */
393}
394
395
396/* Decide which scan mode to use. There's no real requirement that 326/* Decide which scan mode to use. There's no real requirement that
397 * the scanmode match the resolution in q->height and q-> width -- the 327 * the scanmode match the resolution in q->height and q-> width -- the
398 * camera takes the picture at the resolution specified in the 328 * camera takes the picture at the resolution specified in the
@@ -402,7 +332,7 @@ static void qc_reset(struct qcam_device *q)
402 * returned. If the scan is smaller, then the rest of the image 332 * returned. If the scan is smaller, then the rest of the image
403 * returned contains garbage. */ 333 * returned contains garbage. */
404 334
405static int qc_setscanmode(struct qcam_device *q) 335static int qc_setscanmode(struct qcam *q)
406{ 336{
407 int old_mode = q->mode; 337 int old_mode = q->mode;
408 338
@@ -442,10 +372,45 @@ static int qc_setscanmode(struct qcam_device *q)
442} 372}
443 373
444 374
375/* Reset the QuickCam. This uses the same sequence the Windows
376 * QuickPic program uses. Someone with a bi-directional port should
377 * check that bi-directional mode is detected right, and then
378 * implement bi-directional mode in qc_readbyte(). */
379
380static void qc_reset(struct qcam *q)
381{
382 switch (q->port_mode & QC_FORCE_MASK) {
383 case QC_FORCE_UNIDIR:
384 q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_UNIDIR;
385 break;
386
387 case QC_FORCE_BIDIR:
388 q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_BIDIR;
389 break;
390
391 case QC_ANY:
392 write_lpcontrol(q, 0x20);
393 write_lpdata(q, 0x75);
394
395 if (read_lpdata(q) != 0x75)
396 q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_BIDIR;
397 else
398 q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_UNIDIR;
399 break;
400 }
401
402 write_lpcontrol(q, 0xb);
403 udelay(250);
404 write_lpcontrol(q, 0xe);
405 qc_setscanmode(q); /* in case port_mode changed */
406}
407
408
409
445/* Reset the QuickCam and program for brightness, contrast, 410/* Reset the QuickCam and program for brightness, contrast,
446 * white-balance, and resolution. */ 411 * white-balance, and resolution. */
447 412
448static void qc_set(struct qcam_device *q) 413static void qc_set(struct qcam *q)
449{ 414{
450 int val; 415 int val;
451 int val2; 416 int val2;
@@ -499,7 +464,7 @@ static void qc_set(struct qcam_device *q)
499 the supplied buffer. It returns the number of bytes read, 464 the supplied buffer. It returns the number of bytes read,
500 or -1 on error. */ 465 or -1 on error. */
501 466
502static inline int qc_readbytes(struct qcam_device *q, char buffer[]) 467static inline int qc_readbytes(struct qcam *q, char buffer[])
503{ 468{
504 int ret = 1; 469 int ret = 1;
505 unsigned int hi, lo; 470 unsigned int hi, lo;
@@ -590,7 +555,7 @@ static inline int qc_readbytes(struct qcam_device *q, char buffer[])
590 * n=2^(bit depth)-1. Ask me for more details if you don't understand 555 * n=2^(bit depth)-1. Ask me for more details if you don't understand
591 * this. */ 556 * this. */
592 557
593static long qc_capture(struct qcam_device *q, char __user *buf, unsigned long len) 558static long qc_capture(struct qcam *q, char __user *buf, unsigned long len)
594{ 559{
595 int i, j, k, yield; 560 int i, j, k, yield;
596 int bytes; 561 int bytes;
@@ -674,171 +639,206 @@ static long qc_capture(struct qcam_device *q, char __user *buf, unsigned long le
674 * Video4linux interfacing 639 * Video4linux interfacing
675 */ 640 */
676 641
677static long qcam_do_ioctl(struct file *file, unsigned int cmd, void *arg) 642static int qcam_querycap(struct file *file, void *priv,
643 struct v4l2_capability *vcap)
678{ 644{
679 struct video_device *dev = video_devdata(file); 645 struct qcam *qcam = video_drvdata(file);
680 struct qcam_device *qcam = (struct qcam_device *)dev;
681
682 switch (cmd) {
683 case VIDIOCGCAP:
684 {
685 struct video_capability *b = arg;
686 strcpy(b->name, "Quickcam");
687 b->type = VID_TYPE_CAPTURE|VID_TYPE_SCALES|VID_TYPE_MONOCHROME;
688 b->channels = 1;
689 b->audios = 0;
690 b->maxwidth = 320;
691 b->maxheight = 240;
692 b->minwidth = 80;
693 b->minheight = 60;
694 return 0;
695 }
696 case VIDIOCGCHAN:
697 {
698 struct video_channel *v = arg;
699 if (v->channel != 0)
700 return -EINVAL;
701 v->flags = 0;
702 v->tuners = 0;
703 /* Good question.. its composite or SVHS so.. */
704 v->type = VIDEO_TYPE_CAMERA;
705 strcpy(v->name, "Camera");
706 return 0;
707 }
708 case VIDIOCSCHAN:
709 {
710 struct video_channel *v = arg;
711 if (v->channel != 0)
712 return -EINVAL;
713 return 0;
714 }
715 case VIDIOCGTUNER:
716 {
717 struct video_tuner *v = arg;
718 if (v->tuner)
719 return -EINVAL;
720 strcpy(v->name, "Format");
721 v->rangelow = 0;
722 v->rangehigh = 0;
723 v->flags = 0;
724 v->mode = VIDEO_MODE_AUTO;
725 return 0;
726 }
727 case VIDIOCSTUNER:
728 {
729 struct video_tuner *v = arg;
730 if (v->tuner)
731 return -EINVAL;
732 if (v->mode != VIDEO_MODE_AUTO)
733 return -EINVAL;
734 return 0;
735 }
736 case VIDIOCGPICT:
737 {
738 struct video_picture *p = arg;
739 p->colour = 0x8000;
740 p->hue = 0x8000;
741 p->brightness = qcam->brightness << 8;
742 p->contrast = qcam->contrast << 8;
743 p->whiteness = qcam->whitebal << 8;
744 p->depth = qcam->bpp;
745 p->palette = VIDEO_PALETTE_GREY;
746 return 0;
747 }
748 case VIDIOCSPICT:
749 {
750 struct video_picture *p = arg;
751 if (p->palette != VIDEO_PALETTE_GREY)
752 return -EINVAL;
753 if (p->depth != 4 && p->depth != 6)
754 return -EINVAL;
755
756 /*
757 * Now load the camera.
758 */
759
760 qcam->brightness = p->brightness >> 8;
761 qcam->contrast = p->contrast >> 8;
762 qcam->whitebal = p->whiteness >> 8;
763 qcam->bpp = p->depth;
764
765 mutex_lock(&qcam->lock);
766 qc_setscanmode(qcam);
767 mutex_unlock(&qcam->lock);
768 qcam->status |= QC_PARAM_CHANGE;
769 646
770 return 0; 647 strlcpy(vcap->driver, qcam->v4l2_dev.name, sizeof(vcap->driver));
771 } 648 strlcpy(vcap->card, "B&W Quickcam", sizeof(vcap->card));
772 case VIDIOCSWIN: 649 strlcpy(vcap->bus_info, "parport", sizeof(vcap->bus_info));
773 { 650 vcap->version = KERNEL_VERSION(0, 0, 2);
774 struct video_window *vw = arg; 651 vcap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE;
775 if (vw->flags) 652 return 0;
776 return -EINVAL; 653}
777 if (vw->clipcount)
778 return -EINVAL;
779 if (vw->height < 60 || vw->height > 240)
780 return -EINVAL;
781 if (vw->width < 80 || vw->width > 320)
782 return -EINVAL;
783
784 qcam->width = 320;
785 qcam->height = 240;
786 qcam->transfer_scale = 4;
787
788 if (vw->width >= 160 && vw->height >= 120)
789 qcam->transfer_scale = 2;
790 if (vw->width >= 320 && vw->height >= 240) {
791 qcam->width = 320;
792 qcam->height = 240;
793 qcam->transfer_scale = 1;
794 }
795 mutex_lock(&qcam->lock);
796 qc_setscanmode(qcam);
797 mutex_unlock(&qcam->lock);
798 654
799 /* We must update the camera before we grab. We could 655static int qcam_enum_input(struct file *file, void *fh, struct v4l2_input *vin)
800 just have changed the grab size */ 656{
801 qcam->status |= QC_PARAM_CHANGE; 657 if (vin->index > 0)
658 return -EINVAL;
659 strlcpy(vin->name, "Camera", sizeof(vin->name));
660 vin->type = V4L2_INPUT_TYPE_CAMERA;
661 vin->audioset = 0;
662 vin->tuner = 0;
663 vin->std = 0;
664 vin->status = 0;
665 return 0;
666}
802 667
803 /* Ok we figured out what to use from our wide choice */ 668static int qcam_g_input(struct file *file, void *fh, unsigned int *inp)
804 return 0; 669{
805 } 670 *inp = 0;
806 case VIDIOCGWIN: 671 return 0;
807 { 672}
808 struct video_window *vw = arg;
809 673
810 memset(vw, 0, sizeof(*vw)); 674static int qcam_s_input(struct file *file, void *fh, unsigned int inp)
811 vw->width = qcam->width / qcam->transfer_scale; 675{
812 vw->height = qcam->height / qcam->transfer_scale; 676 return (inp > 0) ? -EINVAL : 0;
813 return 0; 677}
814 } 678
815 case VIDIOCKEY: 679static int qcam_queryctrl(struct file *file, void *priv,
816 return 0; 680 struct v4l2_queryctrl *qc)
817 case VIDIOCCAPTURE: 681{
818 case VIDIOCGFBUF: 682 switch (qc->id) {
819 case VIDIOCSFBUF: 683 case V4L2_CID_BRIGHTNESS:
820 case VIDIOCGFREQ: 684 return v4l2_ctrl_query_fill(qc, 0, 255, 1, 180);
821 case VIDIOCSFREQ: 685 case V4L2_CID_CONTRAST:
822 case VIDIOCGAUDIO: 686 return v4l2_ctrl_query_fill(qc, 0, 255, 1, 192);
823 case VIDIOCSAUDIO: 687 case V4L2_CID_GAMMA:
824 return -EINVAL; 688 return v4l2_ctrl_query_fill(qc, 0, 255, 1, 105);
689 }
690 return -EINVAL;
691}
692
693static int qcam_g_ctrl(struct file *file, void *priv,
694 struct v4l2_control *ctrl)
695{
696 struct qcam *qcam = video_drvdata(file);
697 int ret = 0;
698
699 switch (ctrl->id) {
700 case V4L2_CID_BRIGHTNESS:
701 ctrl->value = qcam->brightness;
702 break;
703 case V4L2_CID_CONTRAST:
704 ctrl->value = qcam->contrast;
705 break;
706 case V4L2_CID_GAMMA:
707 ctrl->value = qcam->whitebal;
708 break;
825 default: 709 default:
826 return -ENOIOCTLCMD; 710 ret = -EINVAL;
711 break;
827 } 712 }
713 return ret;
714}
715
716static int qcam_s_ctrl(struct file *file, void *priv,
717 struct v4l2_control *ctrl)
718{
719 struct qcam *qcam = video_drvdata(file);
720 int ret = 0;
721
722 mutex_lock(&qcam->lock);
723 switch (ctrl->id) {
724 case V4L2_CID_BRIGHTNESS:
725 qcam->brightness = ctrl->value;
726 break;
727 case V4L2_CID_CONTRAST:
728 qcam->contrast = ctrl->value;
729 break;
730 case V4L2_CID_GAMMA:
731 qcam->whitebal = ctrl->value;
732 break;
733 default:
734 ret = -EINVAL;
735 break;
736 }
737 if (ret == 0) {
738 qc_setscanmode(qcam);
739 qcam->status |= QC_PARAM_CHANGE;
740 }
741 mutex_unlock(&qcam->lock);
742 return ret;
743}
744
745static int qcam_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
746{
747 struct qcam *qcam = video_drvdata(file);
748 struct v4l2_pix_format *pix = &fmt->fmt.pix;
749
750 pix->width = qcam->width / qcam->transfer_scale;
751 pix->height = qcam->height / qcam->transfer_scale;
752 pix->pixelformat = (qcam->bpp == 4) ? V4L2_PIX_FMT_Y4 : V4L2_PIX_FMT_Y6;
753 pix->field = V4L2_FIELD_NONE;
754 pix->bytesperline = qcam->width;
755 pix->sizeimage = qcam->width * qcam->height;
756 /* Just a guess */
757 pix->colorspace = V4L2_COLORSPACE_SRGB;
758 return 0;
759}
760
761static int qcam_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
762{
763 struct v4l2_pix_format *pix = &fmt->fmt.pix;
764
765 if (pix->height <= 60 || pix->width <= 80) {
766 pix->height = 60;
767 pix->width = 80;
768 } else if (pix->height <= 120 || pix->width <= 160) {
769 pix->height = 120;
770 pix->width = 160;
771 } else {
772 pix->height = 240;
773 pix->width = 320;
774 }
775 if (pix->pixelformat != V4L2_PIX_FMT_Y4 &&
776 pix->pixelformat != V4L2_PIX_FMT_Y6)
777 pix->pixelformat = V4L2_PIX_FMT_Y4;
778 pix->field = V4L2_FIELD_NONE;
779 pix->bytesperline = pix->width;
780 pix->sizeimage = pix->width * pix->height;
781 /* Just a guess */
782 pix->colorspace = V4L2_COLORSPACE_SRGB;
783 return 0;
784}
785
786static int qcam_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
787{
788 struct qcam *qcam = video_drvdata(file);
789 struct v4l2_pix_format *pix = &fmt->fmt.pix;
790 int ret = qcam_try_fmt_vid_cap(file, fh, fmt);
791
792 if (ret)
793 return ret;
794 qcam->width = 320;
795 qcam->height = 240;
796 if (pix->height == 60)
797 qcam->transfer_scale = 4;
798 else if (pix->height == 120)
799 qcam->transfer_scale = 2;
800 else
801 qcam->transfer_scale = 1;
802 if (pix->pixelformat == V4L2_PIX_FMT_Y6)
803 qcam->bpp = 6;
804 else
805 qcam->bpp = 4;
806
807 mutex_lock(&qcam->lock);
808 qc_setscanmode(qcam);
809 /* We must update the camera before we grab. We could
810 just have changed the grab size */
811 qcam->status |= QC_PARAM_CHANGE;
812 mutex_unlock(&qcam->lock);
828 return 0; 813 return 0;
829} 814}
830 815
831static long qcam_ioctl(struct file *file, 816static int qcam_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *fmt)
832 unsigned int cmd, unsigned long arg)
833{ 817{
834 return video_usercopy(file, cmd, arg, qcam_do_ioctl); 818 static struct v4l2_fmtdesc formats[] = {
819 { 0, 0, 0,
820 "4-Bit Monochrome", V4L2_PIX_FMT_Y4,
821 { 0, 0, 0, 0 }
822 },
823 { 0, 0, 0,
824 "6-Bit Monochrome", V4L2_PIX_FMT_Y6,
825 { 0, 0, 0, 0 }
826 },
827 };
828 enum v4l2_buf_type type = fmt->type;
829
830 if (fmt->index > 1)
831 return -EINVAL;
832
833 *fmt = formats[fmt->index];
834 fmt->type = type;
835 return 0;
835} 836}
836 837
837static ssize_t qcam_read(struct file *file, char __user *buf, 838static ssize_t qcam_read(struct file *file, char __user *buf,
838 size_t count, loff_t *ppos) 839 size_t count, loff_t *ppos)
839{ 840{
840 struct video_device *v = video_devdata(file); 841 struct qcam *qcam = video_drvdata(file);
841 struct qcam_device *qcam = (struct qcam_device *)v;
842 int len; 842 int len;
843 parport_claim_or_block(qcam->pdev); 843 parport_claim_or_block(qcam->pdev);
844 844
@@ -858,43 +858,112 @@ static ssize_t qcam_read(struct file *file, char __user *buf,
858 return len; 858 return len;
859} 859}
860 860
861static int qcam_exclusive_open(struct file *file) 861static const struct v4l2_file_operations qcam_fops = {
862 .owner = THIS_MODULE,
863 .ioctl = video_ioctl2,
864 .read = qcam_read,
865};
866
867static const struct v4l2_ioctl_ops qcam_ioctl_ops = {
868 .vidioc_querycap = qcam_querycap,
869 .vidioc_g_input = qcam_g_input,
870 .vidioc_s_input = qcam_s_input,
871 .vidioc_enum_input = qcam_enum_input,
872 .vidioc_queryctrl = qcam_queryctrl,
873 .vidioc_g_ctrl = qcam_g_ctrl,
874 .vidioc_s_ctrl = qcam_s_ctrl,
875 .vidioc_enum_fmt_vid_cap = qcam_enum_fmt_vid_cap,
876 .vidioc_g_fmt_vid_cap = qcam_g_fmt_vid_cap,
877 .vidioc_s_fmt_vid_cap = qcam_s_fmt_vid_cap,
878 .vidioc_try_fmt_vid_cap = qcam_try_fmt_vid_cap,
879};
880
881/* Initialize the QuickCam driver control structure. This is where
882 * defaults are set for people who don't have a config file.*/
883
884static struct qcam *qcam_init(struct parport *port)
862{ 885{
863 struct video_device *dev = video_devdata(file); 886 struct qcam *qcam;
864 struct qcam_device *qcam = (struct qcam_device *)dev; 887 struct v4l2_device *v4l2_dev;
888
889 qcam = kzalloc(sizeof(struct qcam), GFP_KERNEL);
890 if (qcam == NULL)
891 return NULL;
892
893 v4l2_dev = &qcam->v4l2_dev;
894 strlcpy(v4l2_dev->name, "bw-qcam", sizeof(v4l2_dev->name));
865 895
866 return test_and_set_bit(0, &qcam->in_use) ? -EBUSY : 0; 896 if (v4l2_device_register(NULL, v4l2_dev) < 0) {
897 v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
898 return NULL;
899 }
900
901 qcam->pport = port;
902 qcam->pdev = parport_register_device(port, "bw-qcam", NULL, NULL,
903 NULL, 0, NULL);
904 if (qcam->pdev == NULL) {
905 v4l2_err(v4l2_dev, "couldn't register for %s.\n", port->name);
906 kfree(qcam);
907 return NULL;
908 }
909
910 strlcpy(qcam->vdev.name, "Connectix QuickCam", sizeof(qcam->vdev.name));
911 qcam->vdev.v4l2_dev = v4l2_dev;
912 qcam->vdev.fops = &qcam_fops;
913 qcam->vdev.ioctl_ops = &qcam_ioctl_ops;
914 qcam->vdev.release = video_device_release_empty;
915 video_set_drvdata(&qcam->vdev, qcam);
916
917 mutex_init(&qcam->lock);
918
919 qcam->port_mode = (QC_ANY | QC_NOTSET);
920 qcam->width = 320;
921 qcam->height = 240;
922 qcam->bpp = 4;
923 qcam->transfer_scale = 2;
924 qcam->contrast = 192;
925 qcam->brightness = 180;
926 qcam->whitebal = 105;
927 qcam->top = 1;
928 qcam->left = 14;
929 qcam->mode = -1;
930 qcam->status = QC_PARAM_CHANGE;
931 return qcam;
867} 932}
868 933
869static int qcam_exclusive_release(struct file *file) 934static int qc_calibrate(struct qcam *q)
870{ 935{
871 struct video_device *dev = video_devdata(file); 936 /*
872 struct qcam_device *qcam = (struct qcam_device *)dev; 937 * Bugfix by Hanno Mueller hmueller@kabel.de, Mai 21 96
938 * The white balance is an individual value for each
939 * quickcam.
940 */
873 941
874 clear_bit(0, &qcam->in_use); 942 int value;
875 return 0; 943 int count = 0;
876}
877 944
878static const struct v4l2_file_operations qcam_fops = { 945 qc_command(q, 27); /* AutoAdjustOffset */
879 .owner = THIS_MODULE, 946 qc_command(q, 0); /* Dummy Parameter, ignored by the camera */
880 .open = qcam_exclusive_open,
881 .release = qcam_exclusive_release,
882 .ioctl = qcam_ioctl,
883 .read = qcam_read,
884};
885static struct video_device qcam_template = {
886 .name = "Connectix Quickcam",
887 .fops = &qcam_fops,
888 .release = video_device_release_empty,
889};
890 947
891#define MAX_CAMS 4 948 /* GetOffset (33) will read 255 until autocalibration */
892static struct qcam_device *qcams[MAX_CAMS]; 949 /* is finished. After that, a value of 1-254 will be */
893static unsigned int num_cams; 950 /* returned. */
951
952 do {
953 qc_command(q, 33);
954 value = qc_readparam(q);
955 mdelay(1);
956 schedule();
957 count++;
958 } while (value == 0xff && count < 2048);
959
960 q->whitebal = value;
961 return value;
962}
894 963
895static int init_bwqcam(struct parport *port) 964static int init_bwqcam(struct parport *port)
896{ 965{
897 struct qcam_device *qcam; 966 struct qcam *qcam;
898 967
899 if (num_cams == MAX_CAMS) { 968 if (num_cams == MAX_CAMS) {
900 printk(KERN_ERR "Too many Quickcams (max %d)\n", MAX_CAMS); 969 printk(KERN_ERR "Too many Quickcams (max %d)\n", MAX_CAMS);
@@ -919,7 +988,7 @@ static int init_bwqcam(struct parport *port)
919 988
920 parport_release(qcam->pdev); 989 parport_release(qcam->pdev);
921 990
922 printk(KERN_INFO "Connectix Quickcam on %s\n", qcam->pport->name); 991 v4l2_info(&qcam->v4l2_dev, "Connectix Quickcam on %s\n", qcam->pport->name);
923 992
924 if (video_register_device(&qcam->vdev, VFL_TYPE_GRABBER, video_nr) < 0) { 993 if (video_register_device(&qcam->vdev, VFL_TYPE_GRABBER, video_nr) < 0) {
925 parport_unregister_device(qcam->pdev); 994 parport_unregister_device(qcam->pdev);
@@ -932,7 +1001,7 @@ static int init_bwqcam(struct parport *port)
932 return 0; 1001 return 0;
933} 1002}
934 1003
935static void close_bwqcam(struct qcam_device *qcam) 1004static void close_bwqcam(struct qcam *qcam)
936{ 1005{
937 video_unregister_device(&qcam->vdev); 1006 video_unregister_device(&qcam->vdev);
938 parport_unregister_device(qcam->pdev); 1007 parport_unregister_device(qcam->pdev);
@@ -983,7 +1052,7 @@ static void bwqcam_detach(struct parport *port)
983{ 1052{
984 int i; 1053 int i;
985 for (i = 0; i < num_cams; i++) { 1054 for (i = 0; i < num_cams; i++) {
986 struct qcam_device *qcam = qcams[i]; 1055 struct qcam *qcam = qcams[i];
987 if (qcam && qcam->pdev->port == port) { 1056 if (qcam && qcam->pdev->port == port) {
988 qcams[i] = NULL; 1057 qcams[i] = NULL;
989 close_bwqcam(qcam); 1058 close_bwqcam(qcam);
diff --git a/drivers/media/video/bw-qcam.h b/drivers/media/video/bw-qcam.h
deleted file mode 100644
index 8a60c5de0935..000000000000
--- a/drivers/media/video/bw-qcam.h
+++ /dev/null
@@ -1,69 +0,0 @@
1/*
2 * Video4Linux bw-qcam driver
3 *
4 * Derived from code..
5 */
6
7/******************************************************************
8
9Copyright (C) 1996 by Scott Laird
10
11Permission is hereby granted, free of charge, to any person obtaining
12a copy of this software and associated documentation files (the
13"Software"), to deal in the Software without restriction, including
14without limitation the rights to use, copy, modify, merge, publish,
15distribute, sublicense, and/or sell copies of the Software, and to
16permit persons to whom the Software is furnished to do so, subject to
17the following conditions:
18
19The above copyright notice and this permission notice shall be
20included in all copies or substantial portions of the Software.
21
22THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
25IN NO EVENT SHALL SCOTT LAIRD BE LIABLE FOR ANY CLAIM, DAMAGES OR
26OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
27ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
28OTHER DEALINGS IN THE SOFTWARE.
29
30******************************************************************/
31
32/* One from column A... */
33#define QC_NOTSET 0
34#define QC_UNIDIR 1
35#define QC_BIDIR 2
36#define QC_SERIAL 3
37
38/* ... and one from column B */
39#define QC_ANY 0x00
40#define QC_FORCE_UNIDIR 0x10
41#define QC_FORCE_BIDIR 0x20
42#define QC_FORCE_SERIAL 0x30
43/* in the port_mode member */
44
45#define QC_MODE_MASK 0x07
46#define QC_FORCE_MASK 0x70
47
48#define MAX_HEIGHT 243
49#define MAX_WIDTH 336
50
51/* Bit fields for status flags */
52#define QC_PARAM_CHANGE 0x01 /* Camera status change has occurred */
53
54struct qcam_device {
55 struct video_device vdev;
56 struct pardevice *pdev;
57 struct parport *pport;
58 struct mutex lock;
59 int width, height;
60 int bpp;
61 int mode;
62 int contrast, brightness, whitebal;
63 int port_mode;
64 int transfer_scale;
65 int top, left;
66 int status;
67 unsigned int saved_bits;
68 unsigned long in_use;
69};