mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-04 16:15:11 +00:00
Merge master.kernel.org:/pub/scm/linux/kernel/git/mchehab/v4l-dvb
* master.kernel.org:/pub/scm/linux/kernel/git/mchehab/v4l-dvb: (33 commits) V4L/DVB (3604): V4l printk fix V4L/DVB (3599c): Whitespace cleanups under Documentation/video4linux V4L/DVB (3599b): Whitespace cleanups under drivers/media V4L/DVB (3599a): Move drivers/usb/media to drivers/media/video V4L/DVB (3599): Implement new routing commands for wm8775 and cs53l32a. V4L/DVB (3598): Add bit algorithm adapter for the Conexant CX2341X boards. V4L/DVB (3597): Vivi: fix warning: implicit declaration of function 'in_interrupt' V4L/DVB (3588): Remove VIDIOC_G/S_AUDOUT from msp3400 V4L/DVB (3587): Always wake thread after routing change. V4L/DVB (3584): Implement V4L2_TUNER_MODE_LANG1_LANG2 audio mode V4L/DVB (3582): Implement correct msp3400 input/output routing V4L/DVB (3581): Add new media/msp3400.h header containing the routing macros V4L/DVB (3580): Last round of msp3400 cleanups before adding routing commands V4L/DVB (3579): Move msp_modus to msp3400-kthreads, add JP and KR std detection V4L/DVB (3578): Make scart definitions easier to handle V4L/DVB (3577): Cleanup audio input handling V4L/DVB (3575): Cxusb: fix i2c debug messages for bluebird devices V4L/DVB (3574): Cxusb: fix debug messages V4L/DVB (3573): Cxusb: remove FIXME: comment in bluebird_patch_dvico_firmware_download V4L/DVB (3572): Cxusb: conditionalize gpio write for the medion box ...
This commit is contained in:
commit
368d17e068
206 changed files with 7248 additions and 4786 deletions
|
@ -1,7 +1,7 @@
|
||||||
c-qcam - Connectix Color QuickCam video4linux kernel driver
|
c-qcam - Connectix Color QuickCam video4linux kernel driver
|
||||||
|
|
||||||
Copyright (C) 1999 Dave Forrest <drf5n@virginia.edu>
|
Copyright (C) 1999 Dave Forrest <drf5n@virginia.edu>
|
||||||
released under GNU GPL.
|
released under GNU GPL.
|
||||||
|
|
||||||
1999-12-08 Dave Forrest, written with kernel version 2.2.12 in mind
|
1999-12-08 Dave Forrest, written with kernel version 2.2.12 in mind
|
||||||
|
|
||||||
|
@ -45,21 +45,21 @@ configuration. The appropriate flags are:
|
||||||
CONFIG_PNP_PARPORT M for autoprobe.o IEEE1284 readback module
|
CONFIG_PNP_PARPORT M for autoprobe.o IEEE1284 readback module
|
||||||
CONFIG_PRINTER_READBACK M for parport_probe.o IEEE1284 readback module
|
CONFIG_PRINTER_READBACK M for parport_probe.o IEEE1284 readback module
|
||||||
CONFIG_VIDEO_DEV M for videodev.o video4linux module
|
CONFIG_VIDEO_DEV M for videodev.o video4linux module
|
||||||
CONFIG_VIDEO_CQCAM M for c-qcam.o Color Quickcam module
|
CONFIG_VIDEO_CQCAM M for c-qcam.o Color Quickcam module
|
||||||
|
|
||||||
With these flags, the kernel should compile and install the modules.
|
With these flags, the kernel should compile and install the modules.
|
||||||
To record and monitor the compilation, I use:
|
To record and monitor the compilation, I use:
|
||||||
|
|
||||||
(make zlilo ; \
|
(make zlilo ; \
|
||||||
make modules; \
|
make modules; \
|
||||||
make modules_install ;
|
make modules_install ;
|
||||||
depmod -a ) &>log &
|
depmod -a ) &>log &
|
||||||
less log # then a capital 'F' to watch the progress
|
less log # then a capital 'F' to watch the progress
|
||||||
|
|
||||||
But that is my personal preference.
|
But that is my personal preference.
|
||||||
|
|
||||||
2.2 Configuration
|
2.2 Configuration
|
||||||
|
|
||||||
The configuration requires module configuration and device
|
The configuration requires module configuration and device
|
||||||
configuration. I like kmod or kerneld process with the
|
configuration. I like kmod or kerneld process with the
|
||||||
/etc/modprobe.conf file so the modules can automatically load/unload as
|
/etc/modprobe.conf file so the modules can automatically load/unload as
|
||||||
|
@ -68,7 +68,7 @@ using MAKEDEV, or need to be created. The following sections detail
|
||||||
these procedures.
|
these procedures.
|
||||||
|
|
||||||
|
|
||||||
2.1 Module Configuration
|
2.1 Module Configuration
|
||||||
|
|
||||||
Using modules requires a bit of work to install and pass the
|
Using modules requires a bit of work to install and pass the
|
||||||
parameters. Understand that entries in /etc/modprobe.conf of:
|
parameters. Understand that entries in /etc/modprobe.conf of:
|
||||||
|
@ -128,9 +128,9 @@ system (CONFIG_PROC_FS), the parallel printer support
|
||||||
(CONFIG_PRINTER), the IEEE 1284 system,(CONFIG_PRINTER_READBACK), you
|
(CONFIG_PRINTER), the IEEE 1284 system,(CONFIG_PRINTER_READBACK), you
|
||||||
should be able to read some identification from your quickcam with
|
should be able to read some identification from your quickcam with
|
||||||
|
|
||||||
modprobe -v parport
|
modprobe -v parport
|
||||||
modprobe -v parport_probe
|
modprobe -v parport_probe
|
||||||
cat /proc/parport/PORTNUMBER/autoprobe
|
cat /proc/parport/PORTNUMBER/autoprobe
|
||||||
Returns:
|
Returns:
|
||||||
CLASS:MEDIA;
|
CLASS:MEDIA;
|
||||||
MODEL:Color QuickCam 2.0;
|
MODEL:Color QuickCam 2.0;
|
||||||
|
@ -140,7 +140,7 @@ Returns:
|
||||||
and well. A common problem is that the current driver does not
|
and well. A common problem is that the current driver does not
|
||||||
reliably detect a c-qcam, even though one is attached. In this case,
|
reliably detect a c-qcam, even though one is attached. In this case,
|
||||||
|
|
||||||
modprobe -v c-qcam
|
modprobe -v c-qcam
|
||||||
or
|
or
|
||||||
insmod -v c-qcam
|
insmod -v c-qcam
|
||||||
|
|
||||||
|
@ -152,16 +152,16 @@ video4linux mailing list and archive for more current information.
|
||||||
3.1 Checklist:
|
3.1 Checklist:
|
||||||
|
|
||||||
Can you get an image?
|
Can you get an image?
|
||||||
v4lgrab >qcam.ppm ; wc qcam.ppm ; xv qcam.ppm
|
v4lgrab >qcam.ppm ; wc qcam.ppm ; xv qcam.ppm
|
||||||
|
|
||||||
Is a working c-qcam connected to the port?
|
Is a working c-qcam connected to the port?
|
||||||
grep ^ /proc/parport/?/autoprobe
|
grep ^ /proc/parport/?/autoprobe
|
||||||
|
|
||||||
Do the /dev/video* files exist?
|
Do the /dev/video* files exist?
|
||||||
ls -lad /dev/video
|
ls -lad /dev/video
|
||||||
|
|
||||||
Is the c-qcam module loaded?
|
Is the c-qcam module loaded?
|
||||||
modprobe -v c-qcam ; lsmod
|
modprobe -v c-qcam ; lsmod
|
||||||
|
|
||||||
Does the camera work with alternate programs? cqcam, etc?
|
Does the camera work with alternate programs? cqcam, etc?
|
||||||
|
|
||||||
|
@ -174,7 +174,7 @@ video4linux mailing list and archive for more current information.
|
||||||
isn't, you might try patching the c-qcam module to add a parport=xxx
|
isn't, you might try patching the c-qcam module to add a parport=xxx
|
||||||
option as in the bw-qcam module so you can specify the parallel port:
|
option as in the bw-qcam module so you can specify the parallel port:
|
||||||
|
|
||||||
insmod -v c-qcam parport=0
|
insmod -v c-qcam parport=0
|
||||||
|
|
||||||
And bypass the detection code, see ../../drivers/char/c-qcam.c and
|
And bypass the detection code, see ../../drivers/char/c-qcam.c and
|
||||||
look for the 'qc_detect' code and call.
|
look for the 'qc_detect' code and call.
|
||||||
|
@ -183,12 +183,12 @@ look for the 'qc_detect' code and call.
|
||||||
this work is documented at the video4linux2 site listed below.
|
this work is documented at the video4linux2 site listed below.
|
||||||
|
|
||||||
|
|
||||||
9.0 --- A sample program using v4lgrabber,
|
9.0 --- A sample program using v4lgrabber,
|
||||||
|
|
||||||
This program is a simple image grabber that will copy a frame from the
|
This program is a simple image grabber that will copy a frame from the
|
||||||
first video device, /dev/video0 to standard output in portable pixmap
|
first video device, /dev/video0 to standard output in portable pixmap
|
||||||
format (.ppm) Using this like: 'v4lgrab | convert - c-qcam.jpg'
|
format (.ppm) Using this like: 'v4lgrab | convert - c-qcam.jpg'
|
||||||
produced this picture of me at
|
produced this picture of me at
|
||||||
http://mug.sys.virginia.edu/~drf5n/extras/c-qcam.jpg
|
http://mug.sys.virginia.edu/~drf5n/extras/c-qcam.jpg
|
||||||
|
|
||||||
-------------------- 8< ---------------- 8< -----------------------------
|
-------------------- 8< ---------------- 8< -----------------------------
|
||||||
|
@ -202,8 +202,8 @@ produced this picture of me at
|
||||||
* Use as:
|
* Use as:
|
||||||
* v4lgrab >image.ppm
|
* v4lgrab >image.ppm
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998-05-03, Phil Blundell <philb@gnu.org>
|
* Copyright (C) 1998-05-03, Phil Blundell <philb@gnu.org>
|
||||||
* Copied from http://www.tazenda.demon.co.uk/phil/vgrabber.c
|
* Copied from http://www.tazenda.demon.co.uk/phil/vgrabber.c
|
||||||
* with minor modifications (Dave Forrest, drf5n@virginia.edu).
|
* with minor modifications (Dave Forrest, drf5n@virginia.edu).
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
@ -225,55 +225,55 @@ produced this picture of me at
|
||||||
|
|
||||||
#define READ_VIDEO_PIXEL(buf, format, depth, r, g, b) \
|
#define READ_VIDEO_PIXEL(buf, format, depth, r, g, b) \
|
||||||
{ \
|
{ \
|
||||||
switch (format) \
|
switch (format) \
|
||||||
{ \
|
{ \
|
||||||
case VIDEO_PALETTE_GREY: \
|
case VIDEO_PALETTE_GREY: \
|
||||||
switch (depth) \
|
switch (depth) \
|
||||||
{ \
|
{ \
|
||||||
case 4: \
|
case 4: \
|
||||||
case 6: \
|
case 6: \
|
||||||
case 8: \
|
case 8: \
|
||||||
(r) = (g) = (b) = (*buf++ << 8);\
|
(r) = (g) = (b) = (*buf++ << 8);\
|
||||||
break; \
|
break; \
|
||||||
\
|
\
|
||||||
case 16: \
|
case 16: \
|
||||||
(r) = (g) = (b) = \
|
(r) = (g) = (b) = \
|
||||||
*((unsigned short *) buf); \
|
*((unsigned short *) buf); \
|
||||||
buf += 2; \
|
buf += 2; \
|
||||||
break; \
|
break; \
|
||||||
} \
|
} \
|
||||||
break; \
|
break; \
|
||||||
\
|
\
|
||||||
\
|
\
|
||||||
case VIDEO_PALETTE_RGB565: \
|
case VIDEO_PALETTE_RGB565: \
|
||||||
{ \
|
{ \
|
||||||
unsigned short tmp = *(unsigned short *)buf; \
|
unsigned short tmp = *(unsigned short *)buf; \
|
||||||
(r) = tmp&0xF800; \
|
(r) = tmp&0xF800; \
|
||||||
(g) = (tmp<<5)&0xFC00; \
|
(g) = (tmp<<5)&0xFC00; \
|
||||||
(b) = (tmp<<11)&0xF800; \
|
(b) = (tmp<<11)&0xF800; \
|
||||||
buf += 2; \
|
buf += 2; \
|
||||||
} \
|
} \
|
||||||
break; \
|
break; \
|
||||||
\
|
\
|
||||||
case VIDEO_PALETTE_RGB555: \
|
case VIDEO_PALETTE_RGB555: \
|
||||||
(r) = (buf[0]&0xF8)<<8; \
|
(r) = (buf[0]&0xF8)<<8; \
|
||||||
(g) = ((buf[0] << 5 | buf[1] >> 3)&0xF8)<<8; \
|
(g) = ((buf[0] << 5 | buf[1] >> 3)&0xF8)<<8; \
|
||||||
(b) = ((buf[1] << 2 ) & 0xF8)<<8; \
|
(b) = ((buf[1] << 2 ) & 0xF8)<<8; \
|
||||||
buf += 2; \
|
buf += 2; \
|
||||||
break; \
|
break; \
|
||||||
\
|
\
|
||||||
case VIDEO_PALETTE_RGB24: \
|
case VIDEO_PALETTE_RGB24: \
|
||||||
(r) = buf[0] << 8; (g) = buf[1] << 8; \
|
(r) = buf[0] << 8; (g) = buf[1] << 8; \
|
||||||
(b) = buf[2] << 8; \
|
(b) = buf[2] << 8; \
|
||||||
buf += 3; \
|
buf += 3; \
|
||||||
break; \
|
break; \
|
||||||
\
|
\
|
||||||
default: \
|
default: \
|
||||||
fprintf(stderr, \
|
fprintf(stderr, \
|
||||||
"Format %d not yet supported\n", \
|
"Format %d not yet supported\n", \
|
||||||
format); \
|
format); \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
int get_brightness_adj(unsigned char *image, long size, int *brightness) {
|
int get_brightness_adj(unsigned char *image, long size, int *brightness) {
|
||||||
long i, tot = 0;
|
long i, tot = 0;
|
||||||
|
@ -324,40 +324,40 @@ int main(int argc, char ** argv)
|
||||||
if(ioctl(fd, VIDIOCSPICT, &vpic) < 0) {
|
if(ioctl(fd, VIDIOCSPICT, &vpic) < 0) {
|
||||||
vpic.depth=6;
|
vpic.depth=6;
|
||||||
if(ioctl(fd, VIDIOCSPICT, &vpic) < 0) {
|
if(ioctl(fd, VIDIOCSPICT, &vpic) < 0) {
|
||||||
vpic.depth=4;
|
vpic.depth=4;
|
||||||
if(ioctl(fd, VIDIOCSPICT, &vpic) < 0) {
|
if(ioctl(fd, VIDIOCSPICT, &vpic) < 0) {
|
||||||
fprintf(stderr, "Unable to find a supported capture format.\n");
|
fprintf(stderr, "Unable to find a supported capture format.\n");
|
||||||
close(fd);
|
close(fd);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
vpic.depth=24;
|
vpic.depth=24;
|
||||||
vpic.palette=VIDEO_PALETTE_RGB24;
|
vpic.palette=VIDEO_PALETTE_RGB24;
|
||||||
|
|
||||||
if(ioctl(fd, VIDIOCSPICT, &vpic) < 0) {
|
if(ioctl(fd, VIDIOCSPICT, &vpic) < 0) {
|
||||||
vpic.palette=VIDEO_PALETTE_RGB565;
|
vpic.palette=VIDEO_PALETTE_RGB565;
|
||||||
vpic.depth=16;
|
vpic.depth=16;
|
||||||
|
|
||||||
if(ioctl(fd, VIDIOCSPICT, &vpic)==-1) {
|
if(ioctl(fd, VIDIOCSPICT, &vpic)==-1) {
|
||||||
vpic.palette=VIDEO_PALETTE_RGB555;
|
vpic.palette=VIDEO_PALETTE_RGB555;
|
||||||
vpic.depth=15;
|
vpic.depth=15;
|
||||||
|
|
||||||
if(ioctl(fd, VIDIOCSPICT, &vpic)==-1) {
|
if(ioctl(fd, VIDIOCSPICT, &vpic)==-1) {
|
||||||
fprintf(stderr, "Unable to find a supported capture format.\n");
|
fprintf(stderr, "Unable to find a supported capture format.\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer = malloc(win.width * win.height * bpp);
|
buffer = malloc(win.width * win.height * bpp);
|
||||||
if (!buffer) {
|
if (!buffer) {
|
||||||
fprintf(stderr, "Out of memory.\n");
|
fprintf(stderr, "Out of memory.\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
int newbright;
|
int newbright;
|
||||||
read(fd, buffer, win.width * win.height * bpp);
|
read(fd, buffer, win.width * win.height * bpp);
|
||||||
|
@ -365,8 +365,8 @@ int main(int argc, char ** argv)
|
||||||
if (f) {
|
if (f) {
|
||||||
vpic.brightness += (newbright << 8);
|
vpic.brightness += (newbright << 8);
|
||||||
if(ioctl(fd, VIDIOCSPICT, &vpic)==-1) {
|
if(ioctl(fd, VIDIOCSPICT, &vpic)==-1) {
|
||||||
perror("VIDIOSPICT");
|
perror("VIDIOSPICT");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while (f);
|
} while (f);
|
||||||
|
@ -381,7 +381,7 @@ int main(int argc, char ** argv)
|
||||||
fputc(g>>8, stdout);
|
fputc(g>>8, stdout);
|
||||||
fputc(b>>8, stdout);
|
fputc(b>>8, stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
close(fd);
|
close(fd);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,7 +87,7 @@ hardware configuration of the parport. You can give the boot-parameter
|
||||||
at the LILO-prompt or specify it in lilo.conf. I use the following
|
at the LILO-prompt or specify it in lilo.conf. I use the following
|
||||||
append-line in lilo.conf:
|
append-line in lilo.conf:
|
||||||
|
|
||||||
append="parport=0x378,7,3"
|
append="parport=0x378,7,3"
|
||||||
|
|
||||||
See Documentation/parport.txt for more information about the
|
See Documentation/parport.txt for more information about the
|
||||||
configuration of the parport and the values given above. Do not simply
|
configuration of the parport and the values given above. Do not simply
|
||||||
|
@ -175,7 +175,7 @@ THANKS (in no particular order):
|
||||||
- Manuel J. Petit de Gabriel <mpetit@dit.upm.es> for providing help
|
- Manuel J. Petit de Gabriel <mpetit@dit.upm.es> for providing help
|
||||||
with Isabel (http://isabel.dit.upm.es/)
|
with Isabel (http://isabel.dit.upm.es/)
|
||||||
- Bas Huisman <bhuism@cs.utwente.nl> for writing the initial parport code
|
- Bas Huisman <bhuism@cs.utwente.nl> for writing the initial parport code
|
||||||
- Jarl Totland <Jarl.Totland@bdc.no> for setting up the mailing list
|
- Jarl Totland <Jarl.Totland@bdc.no> for setting up the mailing list
|
||||||
and maintaining the web-server[3]
|
and maintaining the web-server[3]
|
||||||
- Chris Whiteford <Chris@informinteractive.com> for fixes related to the
|
- Chris Whiteford <Chris@informinteractive.com> for fixes related to the
|
||||||
1.02 firmware
|
1.02 firmware
|
||||||
|
|
|
@ -28,7 +28,7 @@ Iomega Buz:
|
||||||
* Philips saa7111 TV decoder
|
* Philips saa7111 TV decoder
|
||||||
* Philips saa7185 TV encoder
|
* Philips saa7185 TV encoder
|
||||||
Drivers to use: videodev, i2c-core, i2c-algo-bit,
|
Drivers to use: videodev, i2c-core, i2c-algo-bit,
|
||||||
videocodec, saa7111, saa7185, zr36060, zr36067
|
videocodec, saa7111, saa7185, zr36060, zr36067
|
||||||
Inputs/outputs: Composite and S-video
|
Inputs/outputs: Composite and S-video
|
||||||
Norms: PAL, SECAM (720x576 @ 25 fps), NTSC (720x480 @ 29.97 fps)
|
Norms: PAL, SECAM (720x576 @ 25 fps), NTSC (720x480 @ 29.97 fps)
|
||||||
Card number: 7
|
Card number: 7
|
||||||
|
@ -39,7 +39,7 @@ Linux Media Labs LML33:
|
||||||
* Brooktree bt819 TV decoder
|
* Brooktree bt819 TV decoder
|
||||||
* Brooktree bt856 TV encoder
|
* Brooktree bt856 TV encoder
|
||||||
Drivers to use: videodev, i2c-core, i2c-algo-bit,
|
Drivers to use: videodev, i2c-core, i2c-algo-bit,
|
||||||
videocodec, bt819, bt856, zr36060, zr36067
|
videocodec, bt819, bt856, zr36060, zr36067
|
||||||
Inputs/outputs: Composite and S-video
|
Inputs/outputs: Composite and S-video
|
||||||
Norms: PAL (720x576 @ 25 fps), NTSC (720x480 @ 29.97 fps)
|
Norms: PAL (720x576 @ 25 fps), NTSC (720x480 @ 29.97 fps)
|
||||||
Card number: 5
|
Card number: 5
|
||||||
|
@ -50,7 +50,7 @@ Linux Media Labs LML33R10:
|
||||||
* Philips saa7114 TV decoder
|
* Philips saa7114 TV decoder
|
||||||
* Analog Devices adv7170 TV encoder
|
* Analog Devices adv7170 TV encoder
|
||||||
Drivers to use: videodev, i2c-core, i2c-algo-bit,
|
Drivers to use: videodev, i2c-core, i2c-algo-bit,
|
||||||
videocodec, saa7114, adv7170, zr36060, zr36067
|
videocodec, saa7114, adv7170, zr36060, zr36067
|
||||||
Inputs/outputs: Composite and S-video
|
Inputs/outputs: Composite and S-video
|
||||||
Norms: PAL (720x576 @ 25 fps), NTSC (720x480 @ 29.97 fps)
|
Norms: PAL (720x576 @ 25 fps), NTSC (720x480 @ 29.97 fps)
|
||||||
Card number: 6
|
Card number: 6
|
||||||
|
@ -61,7 +61,7 @@ Pinnacle/Miro DC10(new):
|
||||||
* Philips saa7110a TV decoder
|
* Philips saa7110a TV decoder
|
||||||
* Analog Devices adv7176 TV encoder
|
* Analog Devices adv7176 TV encoder
|
||||||
Drivers to use: videodev, i2c-core, i2c-algo-bit,
|
Drivers to use: videodev, i2c-core, i2c-algo-bit,
|
||||||
videocodec, saa7110, adv7175, zr36060, zr36067
|
videocodec, saa7110, adv7175, zr36060, zr36067
|
||||||
Inputs/outputs: Composite, S-video and Internal
|
Inputs/outputs: Composite, S-video and Internal
|
||||||
Norms: PAL, SECAM (768x576 @ 25 fps), NTSC (640x480 @ 29.97 fps)
|
Norms: PAL, SECAM (768x576 @ 25 fps), NTSC (640x480 @ 29.97 fps)
|
||||||
Card number: 1
|
Card number: 1
|
||||||
|
@ -84,7 +84,7 @@ Pinnacle/Miro DC10(old): *
|
||||||
* Micronas vpx3220a TV decoder
|
* Micronas vpx3220a TV decoder
|
||||||
* mse3000 TV encoder or Analog Devices adv7176 TV encoder *
|
* mse3000 TV encoder or Analog Devices adv7176 TV encoder *
|
||||||
Drivers to use: videodev, i2c-core, i2c-algo-bit,
|
Drivers to use: videodev, i2c-core, i2c-algo-bit,
|
||||||
videocodec, vpx3220, mse3000/adv7175, zr36050, zr36016, zr36067
|
videocodec, vpx3220, mse3000/adv7175, zr36050, zr36016, zr36067
|
||||||
Inputs/outputs: Composite, S-video and Internal
|
Inputs/outputs: Composite, S-video and Internal
|
||||||
Norms: PAL, SECAM (768x576 @ 25 fps), NTSC (640x480 @ 29.97 fps)
|
Norms: PAL, SECAM (768x576 @ 25 fps), NTSC (640x480 @ 29.97 fps)
|
||||||
Card number: 0
|
Card number: 0
|
||||||
|
@ -96,7 +96,7 @@ Pinnacle/Miro DC30: *
|
||||||
* Micronas vpx3225d/vpx3220a/vpx3216b TV decoder
|
* Micronas vpx3225d/vpx3220a/vpx3216b TV decoder
|
||||||
* Analog Devices adv7176 TV encoder
|
* Analog Devices adv7176 TV encoder
|
||||||
Drivers to use: videodev, i2c-core, i2c-algo-bit,
|
Drivers to use: videodev, i2c-core, i2c-algo-bit,
|
||||||
videocodec, vpx3220/vpx3224, adv7175, zr36050, zr36016, zr36067
|
videocodec, vpx3220/vpx3224, adv7175, zr36050, zr36016, zr36067
|
||||||
Inputs/outputs: Composite, S-video and Internal
|
Inputs/outputs: Composite, S-video and Internal
|
||||||
Norms: PAL, SECAM (768x576 @ 25 fps), NTSC (640x480 @ 29.97 fps)
|
Norms: PAL, SECAM (768x576 @ 25 fps), NTSC (640x480 @ 29.97 fps)
|
||||||
Card number: 3
|
Card number: 3
|
||||||
|
@ -123,11 +123,11 @@ Note: use encoder=X or decoder=X for non-default i2c chips (see i2c-id.h)
|
||||||
|
|
||||||
The best know TV standards are NTSC/PAL/SECAM. but for decoding a frame that
|
The best know TV standards are NTSC/PAL/SECAM. but for decoding a frame that
|
||||||
information is not enough. There are several formats of the TV standards.
|
information is not enough. There are several formats of the TV standards.
|
||||||
And not every TV decoder is able to handle every format. Also the every
|
And not every TV decoder is able to handle every format. Also the every
|
||||||
combination is supported by the driver. There are currently 11 different
|
combination is supported by the driver. There are currently 11 different
|
||||||
tv broadcast formats all aver the world.
|
tv broadcast formats all aver the world.
|
||||||
|
|
||||||
The CCIR defines parameters needed for broadcasting the signal.
|
The CCIR defines parameters needed for broadcasting the signal.
|
||||||
The CCIR has defined different standards: A,B,D,E,F,G,D,H,I,K,K1,L,M,N,...
|
The CCIR has defined different standards: A,B,D,E,F,G,D,H,I,K,K1,L,M,N,...
|
||||||
The CCIR says not much about about the colorsystem used !!!
|
The CCIR says not much about about the colorsystem used !!!
|
||||||
And talking about a colorsystem says not to much about how it is broadcast.
|
And talking about a colorsystem says not to much about how it is broadcast.
|
||||||
|
@ -136,18 +136,18 @@ The CCIR standards A,E,F are not used any more.
|
||||||
|
|
||||||
When you speak about NTSC, you usually mean the standard: CCIR - M using
|
When you speak about NTSC, you usually mean the standard: CCIR - M using
|
||||||
the NTSC colorsystem which is used in the USA, Japan, Mexico, Canada
|
the NTSC colorsystem which is used in the USA, Japan, Mexico, Canada
|
||||||
and a few others.
|
and a few others.
|
||||||
|
|
||||||
When you talk about PAL, you usually mean: CCIR - B/G using the PAL
|
When you talk about PAL, you usually mean: CCIR - B/G using the PAL
|
||||||
colorsystem which is used in many Countries.
|
colorsystem which is used in many Countries.
|
||||||
|
|
||||||
When you talk about SECAM, you mean: CCIR - L using the SECAM Colorsystem
|
When you talk about SECAM, you mean: CCIR - L using the SECAM Colorsystem
|
||||||
which is used in France, and a few others.
|
which is used in France, and a few others.
|
||||||
|
|
||||||
There the other version of SECAM, CCIR - D/K is used in Bulgaria, China,
|
There the other version of SECAM, CCIR - D/K is used in Bulgaria, China,
|
||||||
Slovakai, Hungary, Korea (Rep.), Poland, Rumania and a others.
|
Slovakai, Hungary, Korea (Rep.), Poland, Rumania and a others.
|
||||||
|
|
||||||
The CCIR - H uses the PAL colorsystem (sometimes SECAM) and is used in
|
The CCIR - H uses the PAL colorsystem (sometimes SECAM) and is used in
|
||||||
Egypt, Libya, Sri Lanka, Syrain Arab. Rep.
|
Egypt, Libya, Sri Lanka, Syrain Arab. Rep.
|
||||||
|
|
||||||
The CCIR - I uses the PAL colorsystem, and is used in Great Britain, Hong Kong,
|
The CCIR - I uses the PAL colorsystem, and is used in Great Britain, Hong Kong,
|
||||||
|
@ -158,30 +158,30 @@ and is used in Argentinia, Uruguay, an a few others
|
||||||
|
|
||||||
We do not talk about how the audio is broadcast !
|
We do not talk about how the audio is broadcast !
|
||||||
|
|
||||||
A rather good sites about the TV standards are:
|
A rather good sites about the TV standards are:
|
||||||
http://www.sony.jp/ServiceArea/Voltage_map/
|
http://www.sony.jp/ServiceArea/Voltage_map/
|
||||||
http://info.electronicwerkstatt.de/bereiche/fernsehtechnik/frequenzen_und_normen/Fernsehnormen/
|
http://info.electronicwerkstatt.de/bereiche/fernsehtechnik/frequenzen_und_normen/Fernsehnormen/
|
||||||
and http://www.cabl.com/restaurant/channel.html
|
and http://www.cabl.com/restaurant/channel.html
|
||||||
|
|
||||||
Other weird things around: NTSC 4.43 is a modificated NTSC, which is mainly
|
Other weird things around: NTSC 4.43 is a modificated NTSC, which is mainly
|
||||||
used in PAL VCR's that are able to play back NTSC. PAL 60 seems to be the same
|
used in PAL VCR's that are able to play back NTSC. PAL 60 seems to be the same
|
||||||
as NTSC 4.43 . The Datasheets also talk about NTSC 44, It seems as if it would
|
as NTSC 4.43 . The Datasheets also talk about NTSC 44, It seems as if it would
|
||||||
be the same as NTSC 4.43.
|
be the same as NTSC 4.43.
|
||||||
NTSC Combs seems to be a decoder mode where the decoder uses a comb filter
|
NTSC Combs seems to be a decoder mode where the decoder uses a comb filter
|
||||||
to split coma and luma instead of a Delay line.
|
to split coma and luma instead of a Delay line.
|
||||||
|
|
||||||
But I did not defiantly find out what NTSC Comb is.
|
But I did not defiantly find out what NTSC Comb is.
|
||||||
|
|
||||||
Philips saa7111 TV decoder
|
Philips saa7111 TV decoder
|
||||||
was introduced in 1997, is used in the BUZ and
|
was introduced in 1997, is used in the BUZ and
|
||||||
can handle: PAL B/G/H/I, PAL N, PAL M, NTSC M, NTSC N, NTSC 4.43 and SECAM
|
can handle: PAL B/G/H/I, PAL N, PAL M, NTSC M, NTSC N, NTSC 4.43 and SECAM
|
||||||
|
|
||||||
Philips saa7110a TV decoder
|
Philips saa7110a TV decoder
|
||||||
was introduced in 1995, is used in the Pinnacle/Miro DC10(new), DC10+ and
|
was introduced in 1995, is used in the Pinnacle/Miro DC10(new), DC10+ and
|
||||||
can handle: PAL B/G, NTSC M and SECAM
|
can handle: PAL B/G, NTSC M and SECAM
|
||||||
|
|
||||||
Philips saa7114 TV decoder
|
Philips saa7114 TV decoder
|
||||||
was introduced in 2000, is used in the LML33R10 and
|
was introduced in 2000, is used in the LML33R10 and
|
||||||
can handle: PAL B/G/D/H/I/N, PAL N, PAL M, NTSC M, NTSC 4.43 and SECAM
|
can handle: PAL B/G/D/H/I/N, PAL N, PAL M, NTSC M, NTSC 4.43 and SECAM
|
||||||
|
|
||||||
Brooktree bt819 TV decoder
|
Brooktree bt819 TV decoder
|
||||||
|
@ -206,7 +206,7 @@ was introduced in 1996, is used in the BUZ
|
||||||
can generate: PAL B/G, NTSC M
|
can generate: PAL B/G, NTSC M
|
||||||
|
|
||||||
Brooktree bt856 TV Encoder
|
Brooktree bt856 TV Encoder
|
||||||
was introduced in 1994, is used in the LML33
|
was introduced in 1994, is used in the LML33
|
||||||
can generate: PAL B/D/G/H/I/N, PAL M, NTSC M, PAL-N (Argentina)
|
can generate: PAL B/D/G/H/I/N, PAL M, NTSC M, PAL-N (Argentina)
|
||||||
|
|
||||||
Analog Devices adv7170 TV Encoder
|
Analog Devices adv7170 TV Encoder
|
||||||
|
@ -221,9 +221,9 @@ ITT mse3000 TV encoder
|
||||||
was introduced in 1991, is used in the DC10 old
|
was introduced in 1991, is used in the DC10 old
|
||||||
can generate: PAL , NTSC , SECAM
|
can generate: PAL , NTSC , SECAM
|
||||||
|
|
||||||
The adv717x, should be able to produce PAL N. But you find nothing PAL N
|
The adv717x, should be able to produce PAL N. But you find nothing PAL N
|
||||||
specific in the registers. Seem that you have to reuse a other standard
|
specific in the registers. Seem that you have to reuse a other standard
|
||||||
to generate PAL N, maybe it would work if you use the PAL M settings.
|
to generate PAL N, maybe it would work if you use the PAL M settings.
|
||||||
|
|
||||||
==========================
|
==========================
|
||||||
|
|
||||||
|
@ -261,7 +261,7 @@ Here's my experience of using LML33 and Buz on various motherboards:
|
||||||
|
|
||||||
VIA MVP3
|
VIA MVP3
|
||||||
Forget it. Pointless. Doesn't work.
|
Forget it. Pointless. Doesn't work.
|
||||||
Intel 430FX (Pentium 200)
|
Intel 430FX (Pentium 200)
|
||||||
LML33 perfect, Buz tolerable (3 or 4 frames dropped per movie)
|
LML33 perfect, Buz tolerable (3 or 4 frames dropped per movie)
|
||||||
Intel 440BX (early stepping)
|
Intel 440BX (early stepping)
|
||||||
LML33 tolerable. Buz starting to get annoying (6-10 frames/hour)
|
LML33 tolerable. Buz starting to get annoying (6-10 frames/hour)
|
||||||
|
@ -438,52 +438,52 @@ importance of buffer sizes:
|
||||||
> -q 25 -b 128 : 24.655.992
|
> -q 25 -b 128 : 24.655.992
|
||||||
> -q 25 -b 256 : 25.859.820
|
> -q 25 -b 256 : 25.859.820
|
||||||
|
|
||||||
I woke up, and can't go to sleep again. I'll kill some time explaining why
|
I woke up, and can't go to sleep again. I'll kill some time explaining why
|
||||||
this doesn't look strange to me.
|
this doesn't look strange to me.
|
||||||
|
|
||||||
Let's do some math using a width of 704 pixels. I'm not sure whether the Buz
|
Let's do some math using a width of 704 pixels. I'm not sure whether the Buz
|
||||||
actually use that number or not, but that's not too important right now.
|
actually use that number or not, but that's not too important right now.
|
||||||
|
|
||||||
704x288 pixels, one field, is 202752 pixels. Divided by 64 pixels per block;
|
704x288 pixels, one field, is 202752 pixels. Divided by 64 pixels per block;
|
||||||
3168 blocks per field. Each pixel consist of two bytes; 128 bytes per block;
|
3168 blocks per field. Each pixel consist of two bytes; 128 bytes per block;
|
||||||
1024 bits per block. 100% in the new driver mean 1:2 compression; the maximum
|
1024 bits per block. 100% in the new driver mean 1:2 compression; the maximum
|
||||||
output becomes 512 bits per block. Actually 510, but 512 is simpler to use
|
output becomes 512 bits per block. Actually 510, but 512 is simpler to use
|
||||||
for calculations.
|
for calculations.
|
||||||
|
|
||||||
Let's say that we specify d1q50. We thus want 256 bits per block; times 3168
|
Let's say that we specify d1q50. We thus want 256 bits per block; times 3168
|
||||||
becomes 811008 bits; 101376 bytes per field. We're talking raw bits and bytes
|
becomes 811008 bits; 101376 bytes per field. We're talking raw bits and bytes
|
||||||
here, so we don't need to do any fancy corrections for bits-per-pixel or such
|
here, so we don't need to do any fancy corrections for bits-per-pixel or such
|
||||||
things. 101376 bytes per field.
|
things. 101376 bytes per field.
|
||||||
|
|
||||||
d1 video contains two fields per frame. Those sum up to 202752 bytes per
|
d1 video contains two fields per frame. Those sum up to 202752 bytes per
|
||||||
frame, and one of those frames goes into each buffer.
|
frame, and one of those frames goes into each buffer.
|
||||||
|
|
||||||
But wait a second! -b128 gives 128kB buffers! It's not possible to cram
|
But wait a second! -b128 gives 128kB buffers! It's not possible to cram
|
||||||
202752 bytes of JPEG data into 128kB!
|
202752 bytes of JPEG data into 128kB!
|
||||||
|
|
||||||
This is what the driver notice and automatically compensate for in your
|
This is what the driver notice and automatically compensate for in your
|
||||||
examples. Let's do some math using this information:
|
examples. Let's do some math using this information:
|
||||||
|
|
||||||
128kB is 131072 bytes. In this buffer, we want to store two fields, which
|
128kB is 131072 bytes. In this buffer, we want to store two fields, which
|
||||||
leaves 65536 bytes for each field. Using 3168 blocks per field, we get
|
leaves 65536 bytes for each field. Using 3168 blocks per field, we get
|
||||||
20.68686868... available bytes per block; 165 bits. We can't allow the
|
20.68686868... available bytes per block; 165 bits. We can't allow the
|
||||||
request for 256 bits per block when there's only 165 bits available! The -q50
|
request for 256 bits per block when there's only 165 bits available! The -q50
|
||||||
option is silently overridden, and the -b128 option takes precedence, leaving
|
option is silently overridden, and the -b128 option takes precedence, leaving
|
||||||
us with the equivalence of -q32.
|
us with the equivalence of -q32.
|
||||||
|
|
||||||
This gives us a data rate of 165 bits per block, which, times 3168, sums up
|
This gives us a data rate of 165 bits per block, which, times 3168, sums up
|
||||||
to 65340 bytes per field, out of the allowed 65536. The current driver has
|
to 65340 bytes per field, out of the allowed 65536. The current driver has
|
||||||
another level of rate limiting; it won't accept -q values that fill more than
|
another level of rate limiting; it won't accept -q values that fill more than
|
||||||
6/8 of the specified buffers. (I'm not sure why. "Playing it safe" seem to be
|
6/8 of the specified buffers. (I'm not sure why. "Playing it safe" seem to be
|
||||||
a safe bet. Personally, I think I would have lowered requested-bits-per-block
|
a safe bet. Personally, I think I would have lowered requested-bits-per-block
|
||||||
by one, or something like that.) We can't use 165 bits per block, but have to
|
by one, or something like that.) We can't use 165 bits per block, but have to
|
||||||
lower it again, to 6/8 of the available buffer space: We end up with 124 bits
|
lower it again, to 6/8 of the available buffer space: We end up with 124 bits
|
||||||
per block, the equivalence of -q24. With 128kB buffers, you can't use greater
|
per block, the equivalence of -q24. With 128kB buffers, you can't use greater
|
||||||
than -q24 at -d1. (And PAL, and 704 pixels width...)
|
than -q24 at -d1. (And PAL, and 704 pixels width...)
|
||||||
|
|
||||||
The third example is limited to -q24 through the same process. The second
|
The third example is limited to -q24 through the same process. The second
|
||||||
example, using very similar calculations, is limited to -q48. The only
|
example, using very similar calculations, is limited to -q48. The only
|
||||||
example that actually grab at the specified -q value is the last one, which
|
example that actually grab at the specified -q value is the last one, which
|
||||||
is clearly visible, looking at the file size.
|
is clearly visible, looking at the file size.
|
||||||
--
|
--
|
||||||
|
|
||||||
|
|
|
@ -14,13 +14,13 @@ Hauppauge Win/TV pci (version 405):
|
||||||
|
|
||||||
Microchip 24LC02B or
|
Microchip 24LC02B or
|
||||||
Philips 8582E2Y: 256 Byte EEPROM with configuration information
|
Philips 8582E2Y: 256 Byte EEPROM with configuration information
|
||||||
I2C 0xa0-0xa1, (24LC02B also responds to 0xa2-0xaf)
|
I2C 0xa0-0xa1, (24LC02B also responds to 0xa2-0xaf)
|
||||||
Philips SAA5246AGP/E: Videotext decoder chip, I2C 0x22-0x23
|
Philips SAA5246AGP/E: Videotext decoder chip, I2C 0x22-0x23
|
||||||
TDA9800: sound decoder
|
TDA9800: sound decoder
|
||||||
Winbond W24257AS-35: 32Kx8 CMOS static RAM (Videotext buffer mem)
|
Winbond W24257AS-35: 32Kx8 CMOS static RAM (Videotext buffer mem)
|
||||||
14052B: analog switch for selection of sound source
|
14052B: analog switch for selection of sound source
|
||||||
|
|
||||||
PAL:
|
PAL:
|
||||||
TDA5737: VHF, hyperband and UHF mixer/oscillator for TV and VCR 3-band tuners
|
TDA5737: VHF, hyperband and UHF mixer/oscillator for TV and VCR 3-band tuners
|
||||||
TSA5522: 1.4 GHz I2C-bus controlled synthesizer, I2C 0xc2-0xc3
|
TSA5522: 1.4 GHz I2C-bus controlled synthesizer, I2C 0xc2-0xc3
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
- Start capturing by pressing "c" or by selecting it via a menu!!!
|
- Start capturing by pressing "c" or by selecting it via a menu!!!
|
||||||
|
|
||||||
- The memory of some S3 cards is not recognized right:
|
- The memory of some S3 cards is not recognized right:
|
||||||
|
|
||||||
First of all, if you are not using XFree-3.2 or newer, upgrade AT LEAST to
|
First of all, if you are not using XFree-3.2 or newer, upgrade AT LEAST to
|
||||||
XFree-3.2A! This solved the problem for most people.
|
XFree-3.2A! This solved the problem for most people.
|
||||||
|
|
||||||
|
@ -31,23 +31,23 @@
|
||||||
(mostly with Trio 64 but also with some others)
|
(mostly with Trio 64 but also with some others)
|
||||||
Get the free demo version of Accelerated X from www.xinside.com and try
|
Get the free demo version of Accelerated X from www.xinside.com and try
|
||||||
bttv with it. bttv seems to work with most S3 cards with Accelerated X.
|
bttv with it. bttv seems to work with most S3 cards with Accelerated X.
|
||||||
|
|
||||||
Since I do not know much (better make that almost nothing) about VGA card
|
Since I do not know much (better make that almost nothing) about VGA card
|
||||||
programming I do not know the reason for this.
|
programming I do not know the reason for this.
|
||||||
Looks like XFree does something different when setting up the video memory?
|
Looks like XFree does something different when setting up the video memory?
|
||||||
Maybe somebody can enlighten me?
|
Maybe somebody can enlighten me?
|
||||||
Would be nice if somebody could get this to work with XFree since
|
Would be nice if somebody could get this to work with XFree since
|
||||||
Accelerated X costs more than some of the grabber cards ...
|
Accelerated X costs more than some of the grabber cards ...
|
||||||
|
|
||||||
Better linear frame buffer support for S3 cards will probably be in
|
Better linear frame buffer support for S3 cards will probably be in
|
||||||
XFree 4.0.
|
XFree 4.0.
|
||||||
|
|
||||||
- Grabbing is not switched off when changing consoles with XFree.
|
- Grabbing is not switched off when changing consoles with XFree.
|
||||||
That's because XFree and some AcceleratedX versions do not send unmap
|
That's because XFree and some AcceleratedX versions do not send unmap
|
||||||
events.
|
events.
|
||||||
|
|
||||||
- Some popup windows (e.g. of the window manager) are not refreshed.
|
- Some popup windows (e.g. of the window manager) are not refreshed.
|
||||||
|
|
||||||
Disable backing store by starting X with the option "-bs"
|
Disable backing store by starting X with the option "-bs"
|
||||||
|
|
||||||
- When using 32 bpp in XFree or 24+8bpp mode in AccelX 3.1 the system
|
- When using 32 bpp in XFree or 24+8bpp mode in AccelX 3.1 the system
|
||||||
|
|
|
@ -38,9 +38,9 @@ tolerate.
|
||||||
------------------------
|
------------------------
|
||||||
|
|
||||||
When using the 430FX PCI, the following rules will ensure
|
When using the 430FX PCI, the following rules will ensure
|
||||||
compatibility:
|
compatibility:
|
||||||
|
|
||||||
(1) Deassert REQ at the same time as asserting FRAME.
|
(1) Deassert REQ at the same time as asserting FRAME.
|
||||||
(2) Do not reassert REQ to request another bus transaction until after
|
(2) Do not reassert REQ to request another bus transaction until after
|
||||||
finish-ing the previous transaction.
|
finish-ing the previous transaction.
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
Many thanks to:
|
Many thanks to:
|
||||||
|
|
||||||
- Markus Schroeder <schroedm@uni-duesseldorf.de> for information on the Bt848
|
- Markus Schroeder <schroedm@uni-duesseldorf.de> for information on the Bt848
|
||||||
and tuner programming and his control program xtvc.
|
and tuner programming and his control program xtvc.
|
||||||
|
|
||||||
- Martin Buck <martin-2.buck@student.uni-ulm.de> for his great Videotext
|
- Martin Buck <martin-2.buck@student.uni-ulm.de> for his great Videotext
|
||||||
|
@ -16,7 +16,7 @@ Many thanks to:
|
||||||
- MIRO for providing a free PCTV card and detailed information about the
|
- MIRO for providing a free PCTV card and detailed information about the
|
||||||
components on their cards. (E.g. how the tuner type is detected)
|
components on their cards. (E.g. how the tuner type is detected)
|
||||||
Without their card I could not have debugged the NTSC mode.
|
Without their card I could not have debugged the NTSC mode.
|
||||||
|
|
||||||
- Hauppauge for telling how the sound input is selected and what components
|
- Hauppauge for telling how the sound input is selected and what components
|
||||||
they do and will use on their radio cards.
|
they do and will use on their radio cards.
|
||||||
Also many thanks for faxing me the FM1216 data sheet.
|
Also many thanks for faxing me the FM1216 data sheet.
|
||||||
|
|
|
@ -131,17 +131,17 @@ Check Stereo: BASE <-- 0xd8 (current volume, stereo detect,
|
||||||
x=0xff ==> "not stereo", x=0xfd ==> "stereo detected"
|
x=0xff ==> "not stereo", x=0xfd ==> "stereo detected"
|
||||||
|
|
||||||
Set Frequency: code = (freq*40) + 10486188
|
Set Frequency: code = (freq*40) + 10486188
|
||||||
foreach of the 24 bits in code,
|
foreach of the 24 bits in code,
|
||||||
(from Least to Most Significant):
|
(from Least to Most Significant):
|
||||||
to write a "zero" bit,
|
to write a "zero" bit,
|
||||||
BASE <-- 0x01 (audio mute, no stereo detect, radio
|
BASE <-- 0x01 (audio mute, no stereo detect, radio
|
||||||
disable, "zero" bit phase 1, tuner adjust)
|
disable, "zero" bit phase 1, tuner adjust)
|
||||||
BASE <-- 0x03 (audio mute, no stereo detect, radio
|
BASE <-- 0x03 (audio mute, no stereo detect, radio
|
||||||
disable, "zero" bit phase 2, tuner adjust)
|
disable, "zero" bit phase 2, tuner adjust)
|
||||||
to write a "one" bit,
|
to write a "one" bit,
|
||||||
BASE <-- 0x05 (audio mute, no stereo detect, radio
|
BASE <-- 0x05 (audio mute, no stereo detect, radio
|
||||||
disable, "one" bit phase 1, tuner adjust)
|
disable, "one" bit phase 1, tuner adjust)
|
||||||
BASE <-- 0x07 (audio mute, no stereo detect, radio
|
BASE <-- 0x07 (audio mute, no stereo detect, radio
|
||||||
disable, "one" bit phase 2, tuner adjust)
|
disable, "one" bit phase 2, tuner adjust)
|
||||||
|
|
||||||
----------------------------------------------------------------------------
|
----------------------------------------------------------------------------
|
||||||
|
|
|
@ -26,7 +26,7 @@ is called VIDEO_PALETTE_YUV422 (16 bpp).
|
||||||
A minimal test application (with source) is available from:
|
A minimal test application (with source) is available from:
|
||||||
http://hem.fyristorg.com/mogul/w9966.html
|
http://hem.fyristorg.com/mogul/w9966.html
|
||||||
|
|
||||||
The slow framerate is due to missing DMA ECP read support in the
|
The slow framerate is due to missing DMA ECP read support in the
|
||||||
parport drivers. I might add working EPP support later.
|
parport drivers. I might add working EPP support later.
|
||||||
|
|
||||||
Good luck!
|
Good luck!
|
||||||
|
|
|
@ -2,7 +2,7 @@ Driver for Trust Computer Products Framegrabber, version 0.6.1
|
||||||
------ --- ----- -------- -------- ------------ ------- - - -
|
------ --- ----- -------- -------- ------------ ------- - - -
|
||||||
|
|
||||||
- ZORAN ------------------------------------------------------
|
- ZORAN ------------------------------------------------------
|
||||||
Author: Pauline Middelink <middelin@polyware.nl>
|
Author: Pauline Middelink <middelin@polyware.nl>
|
||||||
Date: 18 September 1999
|
Date: 18 September 1999
|
||||||
Version: 0.6.1
|
Version: 0.6.1
|
||||||
|
|
||||||
|
@ -115,7 +115,7 @@ After making/checking the devices do:
|
||||||
<n> is the cardtype of the card you have. The cardnumber can
|
<n> is the cardtype of the card you have. The cardnumber can
|
||||||
be found in the source of zr36120. Look for tvcards. If your
|
be found in the source of zr36120. Look for tvcards. If your
|
||||||
card is not there, please try if any other card gives some
|
card is not there, please try if any other card gives some
|
||||||
response, and mail me if you got a working tvcard addition.
|
response, and mail me if you got a working tvcard addition.
|
||||||
|
|
||||||
PS. <TVCard editors behold!)
|
PS. <TVCard editors behold!)
|
||||||
Dont forget to set video_input to the number of inputs
|
Dont forget to set video_input to the number of inputs
|
||||||
|
|
|
@ -50,5 +50,19 @@ config VIDEO_IR
|
||||||
config VIDEO_TVEEPROM
|
config VIDEO_TVEEPROM
|
||||||
tristate
|
tristate
|
||||||
|
|
||||||
|
config USB_DABUSB
|
||||||
|
tristate "DABUSB driver"
|
||||||
|
depends on USB
|
||||||
|
---help---
|
||||||
|
A Digital Audio Broadcasting (DAB) Receiver for USB and Linux
|
||||||
|
brought to you by the DAB-Team
|
||||||
|
<http://wwwbode.cs.tum.edu/Par/arch/dab/>. This driver can be taken
|
||||||
|
as an example for URB-based bulk, control, and isochronous
|
||||||
|
transactions. URB's are explained in
|
||||||
|
<Documentation/usb/URB.txt>.
|
||||||
|
|
||||||
|
To compile this driver as a module, choose M here: the
|
||||||
|
module will be called dabusb.
|
||||||
|
|
||||||
endmenu
|
endmenu
|
||||||
|
|
||||||
|
|
|
@ -50,14 +50,15 @@ void saa7146_res_free(struct saa7146_fh *fh, unsigned int bits)
|
||||||
/********************************************************************************/
|
/********************************************************************************/
|
||||||
/* common dma functions */
|
/* common dma functions */
|
||||||
|
|
||||||
void saa7146_dma_free(struct saa7146_dev *dev,struct saa7146_buf *buf)
|
void saa7146_dma_free(struct saa7146_dev *dev,struct videobuf_queue *q,
|
||||||
|
struct saa7146_buf *buf)
|
||||||
{
|
{
|
||||||
DEB_EE(("dev:%p, buf:%p\n",dev,buf));
|
DEB_EE(("dev:%p, buf:%p\n",dev,buf));
|
||||||
|
|
||||||
BUG_ON(in_interrupt());
|
BUG_ON(in_interrupt());
|
||||||
|
|
||||||
videobuf_waiton(&buf->vb,0,0);
|
videobuf_waiton(&buf->vb,0,0);
|
||||||
videobuf_dma_pci_unmap(dev->pci, &buf->vb.dma);
|
videobuf_dma_unmap(q, &buf->vb.dma);
|
||||||
videobuf_dma_free(&buf->vb.dma);
|
videobuf_dma_free(&buf->vb.dma);
|
||||||
buf->vb.state = STATE_NEEDS_INIT;
|
buf->vb.state = STATE_NEEDS_INIT;
|
||||||
}
|
}
|
||||||
|
|
|
@ -236,7 +236,7 @@ static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,e
|
||||||
}
|
}
|
||||||
|
|
||||||
if (buf->vb.size != size)
|
if (buf->vb.size != size)
|
||||||
saa7146_dma_free(dev,buf);
|
saa7146_dma_free(dev,q,buf);
|
||||||
|
|
||||||
if (STATE_NEEDS_INIT == buf->vb.state) {
|
if (STATE_NEEDS_INIT == buf->vb.state) {
|
||||||
buf->vb.width = llength;
|
buf->vb.width = llength;
|
||||||
|
@ -247,7 +247,7 @@ static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,e
|
||||||
saa7146_pgtable_free(dev->pci, &buf->pt[2]);
|
saa7146_pgtable_free(dev->pci, &buf->pt[2]);
|
||||||
saa7146_pgtable_alloc(dev->pci, &buf->pt[2]);
|
saa7146_pgtable_alloc(dev->pci, &buf->pt[2]);
|
||||||
|
|
||||||
err = videobuf_iolock(dev->pci,&buf->vb, NULL);
|
err = videobuf_iolock(q,&buf->vb, NULL);
|
||||||
if (err)
|
if (err)
|
||||||
goto oops;
|
goto oops;
|
||||||
err = saa7146_pgtable_build_single(dev->pci, &buf->pt[2], buf->vb.dma.sglist, buf->vb.dma.sglen);
|
err = saa7146_pgtable_build_single(dev->pci, &buf->pt[2], buf->vb.dma.sglist, buf->vb.dma.sglen);
|
||||||
|
@ -261,7 +261,7 @@ static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,e
|
||||||
|
|
||||||
oops:
|
oops:
|
||||||
DEB_VBI(("error out.\n"));
|
DEB_VBI(("error out.\n"));
|
||||||
saa7146_dma_free(dev,buf);
|
saa7146_dma_free(dev,q,buf);
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
@ -301,7 +301,7 @@ static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
|
||||||
struct saa7146_buf *buf = (struct saa7146_buf *)vb;
|
struct saa7146_buf *buf = (struct saa7146_buf *)vb;
|
||||||
|
|
||||||
DEB_VBI(("vb:%p\n",vb));
|
DEB_VBI(("vb:%p\n",vb));
|
||||||
saa7146_dma_free(dev,buf);
|
saa7146_dma_free(dev,q,buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct videobuf_queue_ops vbi_qops = {
|
static struct videobuf_queue_ops vbi_qops = {
|
||||||
|
|
|
@ -1275,7 +1275,7 @@ static int buffer_prepare(struct videobuf_queue *q,
|
||||||
buf->vb.field != field ||
|
buf->vb.field != field ||
|
||||||
buf->vb.field != fh->video_fmt.field ||
|
buf->vb.field != fh->video_fmt.field ||
|
||||||
buf->fmt != &fh->video_fmt) {
|
buf->fmt != &fh->video_fmt) {
|
||||||
saa7146_dma_free(dev,buf);
|
saa7146_dma_free(dev,q,buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (STATE_NEEDS_INIT == buf->vb.state) {
|
if (STATE_NEEDS_INIT == buf->vb.state) {
|
||||||
|
@ -1304,7 +1304,7 @@ static int buffer_prepare(struct videobuf_queue *q,
|
||||||
saa7146_pgtable_alloc(dev->pci, &buf->pt[0]);
|
saa7146_pgtable_alloc(dev->pci, &buf->pt[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
err = videobuf_iolock(dev->pci,&buf->vb, &vv->ov_fb);
|
err = videobuf_iolock(q,&buf->vb, &vv->ov_fb);
|
||||||
if (err)
|
if (err)
|
||||||
goto oops;
|
goto oops;
|
||||||
err = saa7146_pgtable_build(dev,buf);
|
err = saa7146_pgtable_build(dev,buf);
|
||||||
|
@ -1318,7 +1318,7 @@ static int buffer_prepare(struct videobuf_queue *q,
|
||||||
|
|
||||||
oops:
|
oops:
|
||||||
DEB_D(("error out.\n"));
|
DEB_D(("error out.\n"));
|
||||||
saa7146_dma_free(dev,buf);
|
saa7146_dma_free(dev,q,buf);
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
@ -1363,7 +1363,7 @@ static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
|
||||||
struct saa7146_buf *buf = (struct saa7146_buf *)vb;
|
struct saa7146_buf *buf = (struct saa7146_buf *)vb;
|
||||||
|
|
||||||
DEB_CAP(("vbuf:%p\n",vb));
|
DEB_CAP(("vbuf:%p\n",vb));
|
||||||
saa7146_dma_free(dev,buf);
|
saa7146_dma_free(dev,q,buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct videobuf_queue_ops video_qops = {
|
static struct videobuf_queue_ops video_qops = {
|
||||||
|
|
|
@ -541,6 +541,7 @@ static struct usb_device_id flexcop_usb_table [] = {
|
||||||
{ USB_DEVICE(0x0af7, 0x0101) },
|
{ USB_DEVICE(0x0af7, 0x0101) },
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
MODULE_DEVICE_TABLE (usb, flexcop_usb_table);
|
||||||
|
|
||||||
/* usb specific object needed to register this driver with the usb subsystem */
|
/* usb specific object needed to register this driver with the usb subsystem */
|
||||||
static struct usb_driver flexcop_usb_driver = {
|
static struct usb_driver flexcop_usb_driver = {
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
obj-$(CONFIG_DVB_BT8XX) += bt878.o dvb-bt8xx.o dst.o dst_ca.o
|
obj-$(CONFIG_DVB_BT8XX) += bt878.o dvb-bt8xx.o dst.o dst_ca.o
|
||||||
|
|
||||||
EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/video -Idrivers/media/dvb/frontends
|
EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/video/bt8xx -Idrivers/media/dvb/frontends
|
||||||
|
|
|
@ -81,18 +81,19 @@ static int cxusb_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num)
|
||||||
return -EAGAIN;
|
return -EAGAIN;
|
||||||
|
|
||||||
if (num > 2)
|
if (num > 2)
|
||||||
warn("more than 2 i2c messages at a time is not handled yet. TODO.");
|
warn("more than two i2c messages at a time is not handled yet. TODO.");
|
||||||
|
|
||||||
for (i = 0; i < num; i++) {
|
for (i = 0; i < num; i++) {
|
||||||
|
|
||||||
switch (msg[i].addr) {
|
if (d->udev->descriptor.idVendor == USB_VID_MEDION)
|
||||||
case 0x63:
|
switch (msg[i].addr) {
|
||||||
cxusb_gpio_tuner(d,0);
|
case 0x63:
|
||||||
break;
|
cxusb_gpio_tuner(d,0);
|
||||||
default:
|
break;
|
||||||
cxusb_gpio_tuner(d,1);
|
default:
|
||||||
break;
|
cxusb_gpio_tuner(d,1);
|
||||||
}
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/* read request */
|
/* read request */
|
||||||
if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) {
|
if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) {
|
||||||
|
@ -108,7 +109,7 @@ static int cxusb_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (ibuf[0] != 0x08)
|
if (ibuf[0] != 0x08)
|
||||||
deb_info("i2c read could have been failed\n");
|
deb_i2c("i2c read may have failed\n");
|
||||||
|
|
||||||
memcpy(msg[i+1].buf,&ibuf[1],msg[i+1].len);
|
memcpy(msg[i+1].buf,&ibuf[1],msg[i+1].len);
|
||||||
|
|
||||||
|
@ -122,7 +123,7 @@ static int cxusb_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num)
|
||||||
if (cxusb_ctrl_msg(d,CMD_I2C_WRITE, obuf, 2+msg[i].len, &ibuf,1) < 0)
|
if (cxusb_ctrl_msg(d,CMD_I2C_WRITE, obuf, 2+msg[i].len, &ibuf,1) < 0)
|
||||||
break;
|
break;
|
||||||
if (ibuf != 0x08)
|
if (ibuf != 0x08)
|
||||||
deb_info("i2c write could have been failed\n");
|
deb_i2c("i2c write may have failed\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -410,7 +411,6 @@ static int bluebird_patch_dvico_firmware_download(struct usb_device *udev, const
|
||||||
if (fw->data[BLUEBIRD_01_ID_OFFSET] == (USB_VID_DVICO & 0xff) &&
|
if (fw->data[BLUEBIRD_01_ID_OFFSET] == (USB_VID_DVICO & 0xff) &&
|
||||||
fw->data[BLUEBIRD_01_ID_OFFSET + 1] == USB_VID_DVICO >> 8) {
|
fw->data[BLUEBIRD_01_ID_OFFSET + 1] == USB_VID_DVICO >> 8) {
|
||||||
|
|
||||||
/* FIXME: are we allowed to change the fw-data ? */
|
|
||||||
fw->data[BLUEBIRD_01_ID_OFFSET + 2] = udev->descriptor.idProduct + 1;
|
fw->data[BLUEBIRD_01_ID_OFFSET + 2] = udev->descriptor.idProduct + 1;
|
||||||
fw->data[BLUEBIRD_01_ID_OFFSET + 3] = udev->descriptor.idProduct >> 8;
|
fw->data[BLUEBIRD_01_ID_OFFSET + 3] = udev->descriptor.idProduct >> 8;
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
|
|
||||||
extern int dvb_usb_cxusb_debug;
|
extern int dvb_usb_cxusb_debug;
|
||||||
#define deb_info(args...) dprintk(dvb_usb_cxusb_debug,0x01,args)
|
#define deb_info(args...) dprintk(dvb_usb_cxusb_debug,0x01,args)
|
||||||
|
#define deb_i2c(args...) if (d->udev->descriptor.idVendor == USB_VID_MEDION) \
|
||||||
|
dprintk(dvb_usb_cxusb_debug,0x01,args)
|
||||||
|
|
||||||
/* usb commands - some of it are guesses, don't have a reference yet */
|
/* usb commands - some of it are guesses, don't have a reference yet */
|
||||||
#define CMD_I2C_WRITE 0x08
|
#define CMD_I2C_WRITE 0x08
|
||||||
|
|
|
@ -369,6 +369,11 @@ static int av7110_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
|
||||||
fm_matrix = 0x3001; // stereo
|
fm_matrix = 0x3001; // stereo
|
||||||
src = 0x0020;
|
src = 0x0020;
|
||||||
break;
|
break;
|
||||||
|
case V4L2_TUNER_MODE_LANG1_LANG2:
|
||||||
|
dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG1_LANG2\n");
|
||||||
|
fm_matrix = 0x3000; // bilingual
|
||||||
|
src = 0x0020;
|
||||||
|
break;
|
||||||
case V4L2_TUNER_MODE_LANG1:
|
case V4L2_TUNER_MODE_LANG1:
|
||||||
dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG1\n");
|
dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG1\n");
|
||||||
fm_matrix = 0x3000; // mono
|
fm_matrix = 0x3000; // mono
|
||||||
|
|
|
@ -16,31 +16,7 @@ config VIDEO_ADV_DEBUG
|
||||||
V4L devices.
|
V4L devices.
|
||||||
In doubt, say N.
|
In doubt, say N.
|
||||||
|
|
||||||
config VIDEO_BT848
|
source "drivers/media/video/bt8xx/Kconfig"
|
||||||
tristate "BT848 Video For Linux"
|
|
||||||
depends on VIDEO_DEV && PCI && I2C
|
|
||||||
select I2C_ALGOBIT
|
|
||||||
select FW_LOADER
|
|
||||||
select VIDEO_BTCX
|
|
||||||
select VIDEO_BUF
|
|
||||||
select VIDEO_IR
|
|
||||||
select VIDEO_TUNER
|
|
||||||
select VIDEO_TVEEPROM
|
|
||||||
select VIDEO_MSP3400
|
|
||||||
---help---
|
|
||||||
Support for BT848 based frame grabber/overlay boards. This includes
|
|
||||||
the Miro, Hauppauge and STB boards. Please read the material in
|
|
||||||
<file:Documentation/video4linux/bttv/> for more information.
|
|
||||||
|
|
||||||
To compile this driver as a module, choose M here: the
|
|
||||||
module will be called bttv.
|
|
||||||
|
|
||||||
config VIDEO_BT848_DVB
|
|
||||||
bool "DVB/ATSC Support for bt878 based TV cards"
|
|
||||||
depends on VIDEO_BT848 && DVB_CORE
|
|
||||||
select DVB_BT8XX
|
|
||||||
---help---
|
|
||||||
This adds support for DVB/ATSC cards based on the BT878 chip.
|
|
||||||
|
|
||||||
config VIDEO_SAA6588
|
config VIDEO_SAA6588
|
||||||
tristate "SAA6588 Radio Chip RDS decoder support on BT848 cards"
|
tristate "SAA6588 Radio Chip RDS decoder support on BT848 cards"
|
||||||
|
@ -315,8 +291,6 @@ config VIDEO_HEXIUM_GEMINI
|
||||||
|
|
||||||
source "drivers/media/video/cx88/Kconfig"
|
source "drivers/media/video/cx88/Kconfig"
|
||||||
|
|
||||||
source "drivers/media/video/em28xx/Kconfig"
|
|
||||||
|
|
||||||
config VIDEO_OVCAMCHIP
|
config VIDEO_OVCAMCHIP
|
||||||
tristate "OmniVision Camera Chip support"
|
tristate "OmniVision Camera Chip support"
|
||||||
depends on VIDEO_DEV && I2C
|
depends on VIDEO_DEV && I2C
|
||||||
|
@ -391,4 +365,234 @@ config VIDEO_SAA7127
|
||||||
To compile this driver as a module, choose M here: the
|
To compile this driver as a module, choose M here: the
|
||||||
module will be called saa7127
|
module will be called saa7127
|
||||||
|
|
||||||
|
#
|
||||||
|
# USB Multimedia device configuration
|
||||||
|
#
|
||||||
|
|
||||||
|
menu "V4L USB devices"
|
||||||
|
depends on USB && VIDEO_DEV
|
||||||
|
|
||||||
|
source "drivers/media/video/em28xx/Kconfig"
|
||||||
|
|
||||||
|
config USB_VICAM
|
||||||
|
tristate "USB 3com HomeConnect (aka vicam) support (EXPERIMENTAL)"
|
||||||
|
depends on USB && VIDEO_DEV && EXPERIMENTAL
|
||||||
|
---help---
|
||||||
|
Say Y here if you have 3com homeconnect camera (vicam).
|
||||||
|
|
||||||
|
This driver uses the Video For Linux API. You must say Y or M to
|
||||||
|
"Video For Linux" (under Multimedia Devices) to use this driver.
|
||||||
|
Information on this API and pointers to "v4l" programs may be found
|
||||||
|
at <file:Documentation/video4linux/API.html>.
|
||||||
|
|
||||||
|
To compile this driver as a module, choose M here: the
|
||||||
|
module will be called vicam.
|
||||||
|
|
||||||
|
config USB_DSBR
|
||||||
|
tristate "D-Link USB FM radio support (EXPERIMENTAL)"
|
||||||
|
depends on USB && VIDEO_DEV && EXPERIMENTAL
|
||||||
|
---help---
|
||||||
|
Say Y here if you want to connect this type of radio to your
|
||||||
|
computer's USB port. Note that the audio is not digital, and
|
||||||
|
you must connect the line out connector to a sound card or a
|
||||||
|
set of speakers.
|
||||||
|
|
||||||
|
This driver uses the Video For Linux API. You must enable
|
||||||
|
(Y or M in config) Video For Linux (under Character Devices)
|
||||||
|
to use this driver. Information on this API and pointers to
|
||||||
|
"v4l" programs may be found at
|
||||||
|
<file:Documentation/video4linux/API.html>.
|
||||||
|
|
||||||
|
To compile this driver as a module, choose M here: the
|
||||||
|
module will be called dsbr100.
|
||||||
|
|
||||||
|
config USB_ET61X251
|
||||||
|
tristate "USB ET61X[12]51 PC Camera Controller support"
|
||||||
|
depends on USB && VIDEO_DEV
|
||||||
|
---help---
|
||||||
|
Say Y here if you want support for cameras based on Etoms ET61X151
|
||||||
|
or ET61X251 PC Camera Controllers.
|
||||||
|
|
||||||
|
See <file:Documentation/usb/et61x251.txt> for more informations.
|
||||||
|
|
||||||
|
This driver uses the Video For Linux API. You must say Y or M to
|
||||||
|
"Video For Linux" to use this driver.
|
||||||
|
|
||||||
|
To compile this driver as a module, choose M here: the
|
||||||
|
module will be called et61x251.
|
||||||
|
|
||||||
|
config USB_IBMCAM
|
||||||
|
tristate "USB IBM (Xirlink) C-it Camera support"
|
||||||
|
depends on USB && VIDEO_DEV
|
||||||
|
---help---
|
||||||
|
Say Y here if you want to connect a IBM "C-It" camera, also known as
|
||||||
|
"Xirlink PC Camera" to your computer's USB port. For more
|
||||||
|
information, read <file:Documentation/usb/ibmcam.txt>.
|
||||||
|
|
||||||
|
This driver uses the Video For Linux API. You must enable
|
||||||
|
(Y or M in config) Video For Linux (under Character Devices)
|
||||||
|
to use this driver. Information on this API and pointers to
|
||||||
|
"v4l" programs may be found at
|
||||||
|
<file:Documentation/video4linux/API.html>.
|
||||||
|
|
||||||
|
To compile this driver as a module, choose M here: the
|
||||||
|
module will be called ibmcam.
|
||||||
|
|
||||||
|
This camera has several configuration options which
|
||||||
|
can be specified when you load the module. Read
|
||||||
|
<file:Documentation/usb/ibmcam.txt> to learn more.
|
||||||
|
|
||||||
|
config USB_KONICAWC
|
||||||
|
tristate "USB Konica Webcam support"
|
||||||
|
depends on USB && VIDEO_DEV
|
||||||
|
---help---
|
||||||
|
Say Y here if you want support for webcams based on a Konica
|
||||||
|
chipset. This is known to work with the Intel YC76 webcam.
|
||||||
|
|
||||||
|
This driver uses the Video For Linux API. You must enable
|
||||||
|
(Y or M in config) Video For Linux (under Character Devices)
|
||||||
|
to use this driver. Information on this API and pointers to
|
||||||
|
"v4l" programs may be found at
|
||||||
|
<file:Documentation/video4linux/API.html>.
|
||||||
|
|
||||||
|
To compile this driver as a module, choose M here: the
|
||||||
|
module will be called konicawc.
|
||||||
|
|
||||||
|
config USB_OV511
|
||||||
|
tristate "USB OV511 Camera support"
|
||||||
|
depends on USB && VIDEO_DEV
|
||||||
|
---help---
|
||||||
|
Say Y here if you want to connect this type of camera to your
|
||||||
|
computer's USB port. See <file:Documentation/usb/ov511.txt> for more
|
||||||
|
information and for a list of supported cameras.
|
||||||
|
|
||||||
|
This driver uses the Video For Linux API. You must say Y or M to
|
||||||
|
"Video For Linux" (under Character Devices) to use this driver.
|
||||||
|
Information on this API and pointers to "v4l" programs may be found
|
||||||
|
at <file:Documentation/video4linux/API.html>.
|
||||||
|
|
||||||
|
To compile this driver as a module, choose M here: the
|
||||||
|
module will be called ov511.
|
||||||
|
|
||||||
|
config USB_SE401
|
||||||
|
tristate "USB SE401 Camera support"
|
||||||
|
depends on USB && VIDEO_DEV
|
||||||
|
---help---
|
||||||
|
Say Y here if you want to connect this type of camera to your
|
||||||
|
computer's USB port. See <file:Documentation/usb/se401.txt> for more
|
||||||
|
information and for a list of supported cameras.
|
||||||
|
|
||||||
|
This driver uses the Video For Linux API. You must say Y or M to
|
||||||
|
"Video For Linux" (under Multimedia Devices) to use this driver.
|
||||||
|
Information on this API and pointers to "v4l" programs may be found
|
||||||
|
at <file:Documentation/video4linux/API.html>.
|
||||||
|
|
||||||
|
To compile this driver as a module, choose M here: the
|
||||||
|
module will be called se401.
|
||||||
|
|
||||||
|
config USB_SN9C102
|
||||||
|
tristate "USB SN9C10x PC Camera Controller support"
|
||||||
|
depends on USB && VIDEO_DEV
|
||||||
|
---help---
|
||||||
|
Say Y here if you want support for cameras based on SONiX SN9C101,
|
||||||
|
SN9C102 or SN9C103 PC Camera Controllers.
|
||||||
|
|
||||||
|
See <file:Documentation/usb/sn9c102.txt> for more informations.
|
||||||
|
|
||||||
|
This driver uses the Video For Linux API. You must say Y or M to
|
||||||
|
"Video For Linux" to use this driver.
|
||||||
|
|
||||||
|
To compile this driver as a module, choose M here: the
|
||||||
|
module will be called sn9c102.
|
||||||
|
|
||||||
|
config USB_STV680
|
||||||
|
tristate "USB STV680 (Pencam) Camera support"
|
||||||
|
depends on USB && VIDEO_DEV
|
||||||
|
---help---
|
||||||
|
Say Y here if you want to connect this type of camera to your
|
||||||
|
computer's USB port. This includes the Pencam line of cameras.
|
||||||
|
See <file:Documentation/usb/stv680.txt> for more information and for
|
||||||
|
a list of supported cameras.
|
||||||
|
|
||||||
|
This driver uses the Video For Linux API. You must say Y or M to
|
||||||
|
"Video For Linux" (under Multimedia Devices) to use this driver.
|
||||||
|
Information on this API and pointers to "v4l" programs may be found
|
||||||
|
at <file:Documentation/video4linux/API.html>.
|
||||||
|
|
||||||
|
To compile this driver as a module, choose M here: the
|
||||||
|
module will be called stv680.
|
||||||
|
|
||||||
|
config USB_W9968CF
|
||||||
|
tristate "USB W996[87]CF JPEG Dual Mode Camera support"
|
||||||
|
depends on USB && VIDEO_DEV && I2C && VIDEO_OVCAMCHIP
|
||||||
|
---help---
|
||||||
|
Say Y here if you want support for cameras based on OV681 or
|
||||||
|
Winbond W9967CF/W9968CF JPEG USB Dual Mode Camera Chips.
|
||||||
|
|
||||||
|
This driver has an optional plugin, which is distributed as a
|
||||||
|
separate module only (released under GPL). It allows to use higher
|
||||||
|
resolutions and framerates, but cannot be included in the official
|
||||||
|
Linux kernel for performance purposes.
|
||||||
|
|
||||||
|
See <file:Documentation/usb/w9968cf.txt> for more informations.
|
||||||
|
|
||||||
|
This driver uses the Video For Linux and the I2C APIs. It needs the
|
||||||
|
OmniVision Camera Chip support as well. You must say Y or M to
|
||||||
|
"Video For Linux", "I2C Support" and "OmniVision Camera Chip
|
||||||
|
support" to use this driver.
|
||||||
|
|
||||||
|
To compile this driver as a module, choose M here: the
|
||||||
|
module will be called w9968cf.
|
||||||
|
|
||||||
|
config USB_ZC0301
|
||||||
|
tristate "USB ZC0301 Image Processor and Control Chip support"
|
||||||
|
depends on USB && VIDEO_DEV
|
||||||
|
---help---
|
||||||
|
Say Y here if you want support for cameras based on the ZC0301
|
||||||
|
Image Processor and Control Chip.
|
||||||
|
|
||||||
|
See <file:Documentation/usb/zc0301.txt> for more informations.
|
||||||
|
|
||||||
|
This driver uses the Video For Linux API. You must say Y or M to
|
||||||
|
"Video For Linux" to use this driver.
|
||||||
|
|
||||||
|
To compile this driver as a module, choose M here: the
|
||||||
|
module will be called zc0301.
|
||||||
|
|
||||||
|
config USB_PWC
|
||||||
|
tristate "USB Philips Cameras"
|
||||||
|
depends on USB && VIDEO_DEV
|
||||||
|
---help---
|
||||||
|
Say Y or M here if you want to use one of these Philips & OEM
|
||||||
|
webcams:
|
||||||
|
* Philips PCA645, PCA646
|
||||||
|
* Philips PCVC675, PCVC680, PCVC690
|
||||||
|
* Philips PCVC720/40, PCVC730, PCVC740, PCVC750
|
||||||
|
* Askey VC010
|
||||||
|
* Logitech QuickCam Pro 3000, 4000, 'Zoom', 'Notebook Pro'
|
||||||
|
and 'Orbit'/'Sphere'
|
||||||
|
* Samsung MPC-C10, MPC-C30
|
||||||
|
* Creative Webcam 5, Pro Ex
|
||||||
|
* SOTEC Afina Eye
|
||||||
|
* Visionite VCS-UC300, VCS-UM100
|
||||||
|
|
||||||
|
The PCA635, PCVC665 and PCVC720/20 are not supported by this driver
|
||||||
|
and never will be, but the 665 and 720/20 are supported by other
|
||||||
|
drivers.
|
||||||
|
|
||||||
|
See <file:Documentation/usb/philips.txt> for more information and
|
||||||
|
installation instructions.
|
||||||
|
|
||||||
|
The built-in microphone is enabled by selecting USB Audio support.
|
||||||
|
|
||||||
|
This driver uses the Video For Linux API. You must say Y or M to
|
||||||
|
"Video For Linux" (under Character Devices) to use this driver.
|
||||||
|
Information on this API and pointers to "v4l" programs may be found
|
||||||
|
at <file:Documentation/video4linux/API.html>.
|
||||||
|
|
||||||
|
To compile this driver as a module, choose M here: the
|
||||||
|
module will be called pwc.
|
||||||
|
|
||||||
|
endmenu # V4L USB devices
|
||||||
|
|
||||||
endmenu
|
endmenu
|
||||||
|
|
|
@ -2,9 +2,6 @@
|
||||||
# Makefile for the video capture/playback device drivers.
|
# Makefile for the video capture/playback device drivers.
|
||||||
#
|
#
|
||||||
|
|
||||||
bttv-objs := bttv-driver.o bttv-cards.o bttv-if.o \
|
|
||||||
bttv-risc.o bttv-vbi.o bttv-i2c.o bttv-gpio.o \
|
|
||||||
bttv-input.o
|
|
||||||
zoran-objs := zr36120.o zr36120_i2c.o zr36120_mem.o
|
zoran-objs := zr36120.o zr36120_i2c.o zr36120_mem.o
|
||||||
zr36067-objs := zoran_procfs.o zoran_device.o \
|
zr36067-objs := zoran_procfs.o zoran_device.o \
|
||||||
zoran_driver.o zoran_card.o
|
zoran_driver.o zoran_card.o
|
||||||
|
@ -15,8 +12,8 @@ msp3400-objs := msp3400-driver.o msp3400-kthreads.o
|
||||||
|
|
||||||
obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-common.o v4l1-compat.o compat_ioctl32.o
|
obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-common.o v4l1-compat.o compat_ioctl32.o
|
||||||
|
|
||||||
obj-$(CONFIG_VIDEO_BT848) += bttv.o tvaudio.o \
|
obj-$(CONFIG_VIDEO_BT848) += bt8xx/
|
||||||
tda7432.o tda9875.o ir-kbd-i2c.o
|
obj-$(CONFIG_VIDEO_BT848) += tvaudio.o tda7432.o tda9875.o ir-kbd-i2c.o
|
||||||
obj-$(CONFIG_SOUND_TVMIXER) += tvmixer.o
|
obj-$(CONFIG_SOUND_TVMIXER) += tvmixer.o
|
||||||
|
|
||||||
obj-$(CONFIG_VIDEO_ZR36120) += zoran.o
|
obj-$(CONFIG_VIDEO_ZR36120) += zoran.o
|
||||||
|
@ -68,4 +65,23 @@ obj-$(CONFIG_VIDEO_CX25840) += cx25840/
|
||||||
obj-$(CONFIG_VIDEO_SAA711X) += saa7115.o
|
obj-$(CONFIG_VIDEO_SAA711X) += saa7115.o
|
||||||
obj-$(CONFIG_VIDEO_SAA7127) += saa7127.o
|
obj-$(CONFIG_VIDEO_SAA7127) += saa7127.o
|
||||||
|
|
||||||
|
et61x251-objs := et61x251_core.o et61x251_tas5130d1b.o
|
||||||
|
zc0301-objs := zc0301_core.o zc0301_pas202bcb.o
|
||||||
|
|
||||||
|
obj-$(CONFIG_USB_DABUSB) += dabusb.o
|
||||||
|
obj-$(CONFIG_USB_DSBR) += dsbr100.o
|
||||||
|
obj-$(CONFIG_USB_OV511) += ov511.o
|
||||||
|
obj-$(CONFIG_USB_SE401) += se401.o
|
||||||
|
obj-$(CONFIG_USB_STV680) += stv680.o
|
||||||
|
obj-$(CONFIG_USB_W9968CF) += w9968cf.o
|
||||||
|
|
||||||
|
obj-$(CONFIG_USB_SN9C102) += sn9c102/
|
||||||
|
obj-$(CONFIG_USB_ET61X251) += et61x251/
|
||||||
|
obj-$(CONFIG_USB_PWC) += pwc/
|
||||||
|
obj-$(CONFIG_USB_ZC0301) += zc0301/
|
||||||
|
|
||||||
|
obj-$(CONFIG_USB_IBMCAM) += usbvideo/
|
||||||
|
obj-$(CONFIG_USB_KONICAWC) += usbvideo/
|
||||||
|
obj-$(CONFIG_USB_VICAM) += usbvideo/
|
||||||
|
|
||||||
EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core
|
EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
/*
|
/*
|
||||||
* adv7170 - adv7170, adv7171 video encoder driver version 0.0.1
|
* adv7170 - adv7170, adv7171 video encoder driver version 0.0.1
|
||||||
*
|
*
|
||||||
* Copyright (C) 2002 Maxim Yevtyushkin <max@linuxmedialabs.com>
|
* Copyright (C) 2002 Maxim Yevtyushkin <max@linuxmedialabs.com>
|
||||||
*
|
*
|
||||||
* Based on adv7176 driver by:
|
* Based on adv7176 driver by:
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998 Dave Perks <dperks@ibm.net>
|
* Copyright (C) 1998 Dave Perks <dperks@ibm.net>
|
||||||
* Copyright (C) 1999 Wolfgang Scherr <scherr@net4you.net>
|
* Copyright (C) 1999 Wolfgang Scherr <scherr@net4you.net>
|
||||||
|
@ -173,7 +173,7 @@ adv7170_write_block (struct i2c_client *client,
|
||||||
static const unsigned char init_NTSC[] = {
|
static const unsigned char init_NTSC[] = {
|
||||||
0x00, 0x10, // MR0
|
0x00, 0x10, // MR0
|
||||||
0x01, 0x20, // MR1
|
0x01, 0x20, // MR1
|
||||||
0x02, 0x0e, // MR2 RTC control: bits 2 and 1
|
0x02, 0x0e, // MR2 RTC control: bits 2 and 1
|
||||||
0x03, 0x80, // MR3
|
0x03, 0x80, // MR3
|
||||||
0x04, 0x30, // MR4
|
0x04, 0x30, // MR4
|
||||||
0x05, 0x00, // Reserved
|
0x05, 0x00, // Reserved
|
||||||
|
@ -196,7 +196,7 @@ static const unsigned char init_NTSC[] = {
|
||||||
0x16, 0x00, // CGMS_WSS_0
|
0x16, 0x00, // CGMS_WSS_0
|
||||||
0x17, 0x00, // CGMS_WSS_1
|
0x17, 0x00, // CGMS_WSS_1
|
||||||
0x18, 0x00, // CGMS_WSS_2
|
0x18, 0x00, // CGMS_WSS_2
|
||||||
0x19, 0x00, // Teletext Ctl
|
0x19, 0x00, // Teletext Ctl
|
||||||
};
|
};
|
||||||
|
|
||||||
static const unsigned char init_PAL[] = {
|
static const unsigned char init_PAL[] = {
|
||||||
|
@ -381,7 +381,7 @@ static unsigned short normal_i2c[] =
|
||||||
};
|
};
|
||||||
|
|
||||||
static unsigned short ignore = I2C_CLIENT_END;
|
static unsigned short ignore = I2C_CLIENT_END;
|
||||||
|
|
||||||
static struct i2c_client_address_data addr_data = {
|
static struct i2c_client_address_data addr_data = {
|
||||||
.normal_i2c = normal_i2c,
|
.normal_i2c = normal_i2c,
|
||||||
.probe = &ignore,
|
.probe = &ignore,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/*
|
||||||
* adv7175 - adv7175a video encoder driver version 0.0.3
|
* adv7175 - adv7175a video encoder driver version 0.0.3
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998 Dave Perks <dperks@ibm.net>
|
* Copyright (C) 1998 Dave Perks <dperks@ibm.net>
|
||||||
|
@ -233,7 +233,7 @@ adv7175_command (struct i2c_client *client,
|
||||||
sizeof(init_common));
|
sizeof(init_common));
|
||||||
adv7175_write(client, 0x07, TR0MODE | TR0RST);
|
adv7175_write(client, 0x07, TR0MODE | TR0RST);
|
||||||
adv7175_write(client, 0x07, TR0MODE);
|
adv7175_write(client, 0x07, TR0MODE);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ENCODER_GET_CAPABILITIES:
|
case ENCODER_GET_CAPABILITIES:
|
||||||
{
|
{
|
||||||
|
@ -399,7 +399,7 @@ static unsigned short normal_i2c[] =
|
||||||
};
|
};
|
||||||
|
|
||||||
static unsigned short ignore = I2C_CLIENT_END;
|
static unsigned short ignore = I2C_CLIENT_END;
|
||||||
|
|
||||||
static struct i2c_client_address_data addr_data = {
|
static struct i2c_client_address_data addr_data = {
|
||||||
.normal_i2c = normal_i2c,
|
.normal_i2c = normal_i2c,
|
||||||
.probe = &ignore,
|
.probe = &ignore,
|
||||||
|
|
|
@ -161,39 +161,39 @@ void iic(int n, unsigned long addr, unsigned long data1, unsigned long data2,
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* Slave Address */
|
/* Slave Address */
|
||||||
ar_outl(addr, PLDI2CDATA);
|
ar_outl(addr, PLDI2CDATA);
|
||||||
wait_for_vsync();
|
wait_for_vsync();
|
||||||
|
|
||||||
/* Start */
|
/* Start */
|
||||||
ar_outl(1, PLDI2CCND);
|
ar_outl(1, PLDI2CCND);
|
||||||
wait_acknowledge();
|
wait_acknowledge();
|
||||||
|
|
||||||
/* Transfer data 1 */
|
/* Transfer data 1 */
|
||||||
ar_outl(data1, PLDI2CDATA);
|
ar_outl(data1, PLDI2CDATA);
|
||||||
wait_for_vsync();
|
wait_for_vsync();
|
||||||
ar_outl(PLDI2CSTEN_STEN, PLDI2CSTEN);
|
ar_outl(PLDI2CSTEN_STEN, PLDI2CSTEN);
|
||||||
wait_acknowledge();
|
wait_acknowledge();
|
||||||
|
|
||||||
/* Transfer data 2 */
|
/* Transfer data 2 */
|
||||||
ar_outl(data2, PLDI2CDATA);
|
ar_outl(data2, PLDI2CDATA);
|
||||||
wait_for_vsync();
|
wait_for_vsync();
|
||||||
ar_outl(PLDI2CSTEN_STEN, PLDI2CSTEN);
|
ar_outl(PLDI2CSTEN_STEN, PLDI2CSTEN);
|
||||||
wait_acknowledge();
|
wait_acknowledge();
|
||||||
|
|
||||||
if (n == 3) {
|
if (n == 3) {
|
||||||
/* Transfer data 3 */
|
/* Transfer data 3 */
|
||||||
ar_outl(data3, PLDI2CDATA);
|
ar_outl(data3, PLDI2CDATA);
|
||||||
wait_for_vsync();
|
wait_for_vsync();
|
||||||
ar_outl(PLDI2CSTEN_STEN, PLDI2CSTEN);
|
ar_outl(PLDI2CSTEN_STEN, PLDI2CSTEN);
|
||||||
wait_acknowledge();
|
wait_acknowledge();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Stop */
|
/* Stop */
|
||||||
for (i = 0; i < 100; i++)
|
for (i = 0; i < 100; i++)
|
||||||
cpu_relax();
|
cpu_relax();
|
||||||
ar_outl(2, PLDI2CCND);
|
ar_outl(2, PLDI2CCND);
|
||||||
ar_outl(2, PLDI2CCND);
|
ar_outl(2, PLDI2CCND);
|
||||||
|
|
||||||
while (ar_inl(PLDI2CSTS) & PLDI2CSTS_BB)
|
while (ar_inl(PLDI2CSTS) & PLDI2CSTS_BB)
|
||||||
cpu_relax();
|
cpu_relax();
|
||||||
|
@ -204,24 +204,24 @@ void init_iic(void)
|
||||||
{
|
{
|
||||||
DEBUG(1, "init_iic:\n");
|
DEBUG(1, "init_iic:\n");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ICU Setting (iic)
|
* ICU Setting (iic)
|
||||||
*/
|
*/
|
||||||
/* I2C Setting */
|
/* I2C Setting */
|
||||||
ar_outl(0x0, PLDI2CCR); /* I2CCR Disable */
|
ar_outl(0x0, PLDI2CCR); /* I2CCR Disable */
|
||||||
ar_outl(0x0300, PLDI2CMOD); /* I2CMOD ACK/8b-data/7b-addr/auto */
|
ar_outl(0x0300, PLDI2CMOD); /* I2CMOD ACK/8b-data/7b-addr/auto */
|
||||||
ar_outl(0x1, PLDI2CACK); /* I2CACK ACK */
|
ar_outl(0x1, PLDI2CACK); /* I2CACK ACK */
|
||||||
|
|
||||||
/* I2C CLK */
|
/* I2C CLK */
|
||||||
/* 50MH-100k */
|
/* 50MH-100k */
|
||||||
if (freq == 75) {
|
if (freq == 75) {
|
||||||
ar_outl(369, PLDI2CFREQ); /* BCLK = 75MHz */
|
ar_outl(369, PLDI2CFREQ); /* BCLK = 75MHz */
|
||||||
} else if (freq == 50) {
|
} else if (freq == 50) {
|
||||||
ar_outl(244, PLDI2CFREQ); /* BCLK = 50MHz */
|
ar_outl(244, PLDI2CFREQ); /* BCLK = 50MHz */
|
||||||
} else {
|
} else {
|
||||||
ar_outl(244, PLDI2CFREQ); /* default: BCLK = 50MHz */
|
ar_outl(244, PLDI2CFREQ); /* default: BCLK = 50MHz */
|
||||||
}
|
}
|
||||||
ar_outl(0x1, PLDI2CCR); /* I2CCR Enable */
|
ar_outl(0x1, PLDI2CCR); /* I2CCR Enable */
|
||||||
}
|
}
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
|
@ -253,7 +253,7 @@ static inline void wait_for_vertical_sync(int exp_line)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* check HCOUNT because we cannot check vertical sync.
|
* check HCOUNT because we cannot check vertical sync.
|
||||||
*/
|
*/
|
||||||
for (; tmout >= 0; tmout--) {
|
for (; tmout >= 0; tmout--) {
|
||||||
l = ar_inl(ARVHCOUNT);
|
l = ar_inl(ARVHCOUNT);
|
||||||
if (l == exp_line)
|
if (l == exp_line)
|
||||||
|
@ -562,8 +562,8 @@ static void ar_interrupt(int irq, void *dev, struct pt_regs *regs)
|
||||||
/* operations for interlace mode */
|
/* operations for interlace mode */
|
||||||
if ( line_count < (AR_HEIGHT_VGA/2) ) /* even line */
|
if ( line_count < (AR_HEIGHT_VGA/2) ) /* even line */
|
||||||
line_number = (line_count << 1);
|
line_number = (line_count << 1);
|
||||||
else /* odd line */
|
else /* odd line */
|
||||||
line_number =
|
line_number =
|
||||||
(((line_count - (AR_HEIGHT_VGA/2)) << 1) + 1);
|
(((line_count - (AR_HEIGHT_VGA/2)) << 1) + 1);
|
||||||
} else {
|
} else {
|
||||||
line_number = line_count;
|
line_number = line_count;
|
||||||
|
@ -651,7 +651,7 @@ static int ar_initialize(struct video_device *dev)
|
||||||
cr |= ARVCR1_NORMAL;
|
cr |= ARVCR1_NORMAL;
|
||||||
ar_outl(cr, ARVCR1);
|
ar_outl(cr, ARVCR1);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize IIC so that CPU can communicate with AR LSI,
|
* Initialize IIC so that CPU can communicate with AR LSI,
|
||||||
* and send boot commands to AR LSI.
|
* and send boot commands to AR LSI.
|
||||||
*/
|
*/
|
||||||
|
@ -846,7 +846,7 @@ static int __init ar_init(void)
|
||||||
* so register video device as a frame grabber type.
|
* so register video device as a frame grabber type.
|
||||||
* device is named "video[0-64]".
|
* device is named "video[0-64]".
|
||||||
* video_register_device() initializes h/w using ar_initialize().
|
* video_register_device() initializes h/w using ar_initialize().
|
||||||
*/
|
*/
|
||||||
if (video_register_device(ar->vdev, VFL_TYPE_GRABBER, video_nr) != 0) {
|
if (video_register_device(ar->vdev, VFL_TYPE_GRABBER, video_nr) != 0) {
|
||||||
/* return -1, -ENFILE(full) or others */
|
/* return -1, -ENFILE(full) or others */
|
||||||
printk("arv: register video (Colour AR) failed.\n");
|
printk("arv: register video (Colour AR) failed.\n");
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/*
|
||||||
* bt819 - BT819A VideoStream Decoder (Rockwell Part)
|
* bt819 - BT819A VideoStream Decoder (Rockwell Part)
|
||||||
*
|
*
|
||||||
* Copyright (C) 1999 Mike Bernson <mike@mlb.org>
|
* Copyright (C) 1999 Mike Bernson <mike@mlb.org>
|
||||||
|
@ -6,7 +6,7 @@
|
||||||
*
|
*
|
||||||
* Modifications for LML33/DC10plus unified driver
|
* Modifications for LML33/DC10plus unified driver
|
||||||
* Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>
|
* Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>
|
||||||
*
|
*
|
||||||
* Changes by Ronald Bultje <rbultje@ronald.bitfreak.net>
|
* Changes by Ronald Bultje <rbultje@ronald.bitfreak.net>
|
||||||
* - moved over to linux>=2.4.x i2c protocol (9/9/2002)
|
* - moved over to linux>=2.4.x i2c protocol (9/9/2002)
|
||||||
*
|
*
|
||||||
|
@ -206,9 +206,9 @@ bt819_init (struct i2c_client *client)
|
||||||
Bug in the bt819 stepping on my board?
|
Bug in the bt819 stepping on my board?
|
||||||
*/
|
*/
|
||||||
0x14, 0x00, /* 0x14 Vertial Scaling lsb */
|
0x14, 0x00, /* 0x14 Vertial Scaling lsb */
|
||||||
0x16, 0x07, /* 0x16 Video Timing Polarity
|
0x16, 0x07, /* 0x16 Video Timing Polarity
|
||||||
ACTIVE=active low
|
ACTIVE=active low
|
||||||
FIELD: high=odd,
|
FIELD: high=odd,
|
||||||
vreset=active high,
|
vreset=active high,
|
||||||
hreset=active high */
|
hreset=active high */
|
||||||
0x18, 0x68, /* 0x18 AGC Delay */
|
0x18, 0x68, /* 0x18 AGC Delay */
|
||||||
|
@ -497,7 +497,7 @@ static unsigned short normal_i2c[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static unsigned short ignore = I2C_CLIENT_END;
|
static unsigned short ignore = I2C_CLIENT_END;
|
||||||
|
|
||||||
static struct i2c_client_address_data addr_data = {
|
static struct i2c_client_address_data addr_data = {
|
||||||
.normal_i2c = normal_i2c,
|
.normal_i2c = normal_i2c,
|
||||||
.probe = &ignore,
|
.probe = &ignore,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/*
|
||||||
* bt856 - BT856A Digital Video Encoder (Rockwell Part)
|
* bt856 - BT856A Digital Video Encoder (Rockwell Part)
|
||||||
*
|
*
|
||||||
* Copyright (C) 1999 Mike Bernson <mike@mlb.org>
|
* Copyright (C) 1999 Mike Bernson <mike@mlb.org>
|
||||||
|
@ -285,7 +285,7 @@ bt856_command (struct i2c_client *client,
|
||||||
static unsigned short normal_i2c[] = { I2C_BT856 >> 1, I2C_CLIENT_END };
|
static unsigned short normal_i2c[] = { I2C_BT856 >> 1, I2C_CLIENT_END };
|
||||||
|
|
||||||
static unsigned short ignore = I2C_CLIENT_END;
|
static unsigned short ignore = I2C_CLIENT_END;
|
||||||
|
|
||||||
static struct i2c_client_address_data addr_data = {
|
static struct i2c_client_address_data addr_data = {
|
||||||
.normal_i2c = normal_i2c,
|
.normal_i2c = normal_i2c,
|
||||||
.probe = &ignore,
|
.probe = &ignore,
|
||||||
|
|
25
drivers/media/video/bt8xx/Kconfig
Normal file
25
drivers/media/video/bt8xx/Kconfig
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
config VIDEO_BT848
|
||||||
|
tristate "BT848 Video For Linux"
|
||||||
|
depends on VIDEO_DEV && PCI && I2C
|
||||||
|
select I2C_ALGOBIT
|
||||||
|
select FW_LOADER
|
||||||
|
select VIDEO_BTCX
|
||||||
|
select VIDEO_BUF
|
||||||
|
select VIDEO_IR
|
||||||
|
select VIDEO_TUNER
|
||||||
|
select VIDEO_TVEEPROM
|
||||||
|
select VIDEO_MSP3400
|
||||||
|
---help---
|
||||||
|
Support for BT848 based frame grabber/overlay boards. This includes
|
||||||
|
the Miro, Hauppauge and STB boards. Please read the material in
|
||||||
|
<file:Documentation/video4linux/bttv/> for more information.
|
||||||
|
|
||||||
|
To compile this driver as a module, choose M here: the
|
||||||
|
module will be called bttv.
|
||||||
|
|
||||||
|
config VIDEO_BT848_DVB
|
||||||
|
bool "DVB/ATSC Support for bt878 based TV cards"
|
||||||
|
depends on VIDEO_BT848 && DVB_CORE
|
||||||
|
select DVB_BT8XX
|
||||||
|
---help---
|
||||||
|
This adds support for DVB/ATSC cards based on the BT878 chip.
|
12
drivers/media/video/bt8xx/Makefile
Normal file
12
drivers/media/video/bt8xx/Makefile
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
#
|
||||||
|
# Makefile for the video capture/playback device drivers.
|
||||||
|
#
|
||||||
|
|
||||||
|
bttv-objs := bttv-driver.o bttv-cards.o bttv-if.o \
|
||||||
|
bttv-risc.o bttv-vbi.o bttv-i2c.o bttv-gpio.o \
|
||||||
|
bttv-input.o
|
||||||
|
|
||||||
|
obj-$(CONFIG_VIDEO_BT848) += bttv.o
|
||||||
|
|
||||||
|
EXTRA_CFLAGS += -I$(src)/..
|
||||||
|
EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core
|
|
@ -30,7 +30,6 @@
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/errno.h>
|
#include <linux/errno.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <media/audiochip.h>
|
|
||||||
#include <media/v4l2-common.h>
|
#include <media/v4l2-common.h>
|
||||||
|
|
||||||
#include "bttv.h"
|
#include "bttv.h"
|
||||||
|
@ -39,7 +38,7 @@
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
|
|
||||||
/* Addresses to scan */
|
/* Addresses to scan */
|
||||||
static unsigned short normal_i2c[] = { I2C_BT832_ALT1>>1, I2C_BT832_ALT2>>1,
|
static unsigned short normal_i2c[] = { I2C_ADDR_BT832_ALT1>>1, I2C_ADDR_BT832_ALT2>>1,
|
||||||
I2C_CLIENT_END };
|
I2C_CLIENT_END };
|
||||||
I2C_CLIENT_INSMOD;
|
I2C_CLIENT_INSMOD;
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -36,13 +36,15 @@
|
||||||
#include <linux/kdev_t.h>
|
#include <linux/kdev_t.h>
|
||||||
#include "bttvp.h"
|
#include "bttvp.h"
|
||||||
#include <media/v4l2-common.h>
|
#include <media/v4l2-common.h>
|
||||||
|
#include <media/tvaudio.h>
|
||||||
|
#include <media/msp3400.h>
|
||||||
|
|
||||||
#include <linux/dma-mapping.h>
|
#include <linux/dma-mapping.h>
|
||||||
|
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
#include <asm/byteorder.h>
|
#include <asm/byteorder.h>
|
||||||
|
|
||||||
#include "rds.h"
|
#include <media/rds.h>
|
||||||
|
|
||||||
|
|
||||||
unsigned int bttv_num; /* number of Bt848s in use */
|
unsigned int bttv_num; /* number of Bt848s in use */
|
||||||
|
@ -926,45 +928,98 @@ video_mux(struct bttv *btv, unsigned int input)
|
||||||
|
|
||||||
static char *audio_modes[] = {
|
static char *audio_modes[] = {
|
||||||
"audio: tuner", "audio: radio", "audio: extern",
|
"audio: tuner", "audio: radio", "audio: extern",
|
||||||
"audio: intern", "audio: off"
|
"audio: intern", "audio: mute"
|
||||||
};
|
};
|
||||||
|
|
||||||
static int
|
static int
|
||||||
audio_mux(struct bttv *btv, int mode)
|
audio_mux(struct bttv *btv, int input, int mute)
|
||||||
{
|
{
|
||||||
int val,mux,i2c_mux,signal;
|
int gpio_val, signal;
|
||||||
|
struct v4l2_control ctrl;
|
||||||
|
struct i2c_client *c;
|
||||||
|
|
||||||
gpio_inout(bttv_tvcards[btv->c.type].gpiomask,
|
gpio_inout(bttv_tvcards[btv->c.type].gpiomask,
|
||||||
bttv_tvcards[btv->c.type].gpiomask);
|
bttv_tvcards[btv->c.type].gpiomask);
|
||||||
signal = btread(BT848_DSTATUS) & BT848_DSTATUS_HLOC;
|
signal = btread(BT848_DSTATUS) & BT848_DSTATUS_HLOC;
|
||||||
|
|
||||||
switch (mode) {
|
btv->mute = mute;
|
||||||
case AUDIO_MUTE:
|
btv->audio = input;
|
||||||
btv->audio |= AUDIO_MUTE;
|
|
||||||
break;
|
|
||||||
case AUDIO_UNMUTE:
|
|
||||||
btv->audio &= ~AUDIO_MUTE;
|
|
||||||
break;
|
|
||||||
case AUDIO_TUNER:
|
|
||||||
case AUDIO_RADIO:
|
|
||||||
case AUDIO_EXTERN:
|
|
||||||
case AUDIO_INTERN:
|
|
||||||
btv->audio &= AUDIO_MUTE;
|
|
||||||
btv->audio |= mode;
|
|
||||||
}
|
|
||||||
i2c_mux = mux = (btv->audio & AUDIO_MUTE) ? AUDIO_OFF : btv->audio;
|
|
||||||
if (btv->opt_automute && !signal && !btv->radio_user)
|
|
||||||
mux = AUDIO_OFF;
|
|
||||||
|
|
||||||
val = bttv_tvcards[btv->c.type].audiomux[mux];
|
/* automute */
|
||||||
gpio_bits(bttv_tvcards[btv->c.type].gpiomask,val);
|
mute = mute || (btv->opt_automute && !signal && !btv->radio_user);
|
||||||
|
|
||||||
|
if (mute)
|
||||||
|
gpio_val = bttv_tvcards[btv->c.type].gpiomute;
|
||||||
|
else
|
||||||
|
gpio_val = bttv_tvcards[btv->c.type].gpiomux[input];
|
||||||
|
|
||||||
|
gpio_bits(bttv_tvcards[btv->c.type].gpiomask, gpio_val);
|
||||||
if (bttv_gpio)
|
if (bttv_gpio)
|
||||||
bttv_gpio_tracking(btv,audio_modes[mux]);
|
bttv_gpio_tracking(btv, audio_modes[mute ? 4 : input]);
|
||||||
if (!in_interrupt())
|
if (in_interrupt())
|
||||||
bttv_call_i2c_clients(btv,AUDC_SET_INPUT,&(i2c_mux));
|
return 0;
|
||||||
|
|
||||||
|
ctrl.id = V4L2_CID_AUDIO_MUTE;
|
||||||
|
ctrl.value = btv->mute;
|
||||||
|
bttv_call_i2c_clients(btv, VIDIOC_S_CTRL, &ctrl);
|
||||||
|
c = btv->i2c_msp34xx_client;
|
||||||
|
if (c) {
|
||||||
|
struct v4l2_routing route;
|
||||||
|
|
||||||
|
/* Note: the inputs tuner/radio/extern/intern are translated
|
||||||
|
to msp routings. This assumes common behavior for all msp3400
|
||||||
|
based TV cards. When this assumption fails, then the
|
||||||
|
specific MSP routing must be added to the card table.
|
||||||
|
For now this is sufficient. */
|
||||||
|
switch (input) {
|
||||||
|
case TVAUDIO_INPUT_RADIO:
|
||||||
|
route.input = MSP_INPUT(MSP_IN_SCART_2, MSP_IN_TUNER_1,
|
||||||
|
MSP_DSP_OUT_SCART, MSP_DSP_OUT_SCART);
|
||||||
|
break;
|
||||||
|
case TVAUDIO_INPUT_EXTERN:
|
||||||
|
route.input = MSP_INPUT(MSP_IN_SCART_1, MSP_IN_TUNER_1,
|
||||||
|
MSP_DSP_OUT_SCART, MSP_DSP_OUT_SCART);
|
||||||
|
break;
|
||||||
|
case TVAUDIO_INPUT_INTERN:
|
||||||
|
/* Yes, this is the same input as for RADIO. I doubt
|
||||||
|
if this is ever used. The only board with an INTERN
|
||||||
|
input is the BTTV_BOARD_AVERMEDIA98. I wonder how
|
||||||
|
that was tested. My guess is that the whole INTERN
|
||||||
|
input does not work. */
|
||||||
|
route.input = MSP_INPUT(MSP_IN_SCART_2, MSP_IN_TUNER_1,
|
||||||
|
MSP_DSP_OUT_SCART, MSP_DSP_OUT_SCART);
|
||||||
|
break;
|
||||||
|
case TVAUDIO_INPUT_TUNER:
|
||||||
|
default:
|
||||||
|
route.input = MSP_INPUT_DEFAULT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
route.output = MSP_OUTPUT_DEFAULT;
|
||||||
|
c->driver->command(c, VIDIOC_INT_S_AUDIO_ROUTING, &route);
|
||||||
|
}
|
||||||
|
c = btv->i2c_tvaudio_client;
|
||||||
|
if (c) {
|
||||||
|
struct v4l2_routing route;
|
||||||
|
|
||||||
|
route.input = input;
|
||||||
|
route.output = 0;
|
||||||
|
c->driver->command(c, VIDIOC_INT_S_AUDIO_ROUTING, &route);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
audio_mute(struct bttv *btv, int mute)
|
||||||
|
{
|
||||||
|
return audio_mux(btv, btv->audio, mute);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
audio_input(struct bttv *btv, int input)
|
||||||
|
{
|
||||||
|
return audio_mux(btv, input, btv->mute);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
i2c_vidiocschan(struct bttv *btv)
|
i2c_vidiocschan(struct bttv *btv)
|
||||||
{
|
{
|
||||||
|
@ -1023,8 +1078,8 @@ set_input(struct bttv *btv, unsigned int input)
|
||||||
} else {
|
} else {
|
||||||
video_mux(btv,input);
|
video_mux(btv,input);
|
||||||
}
|
}
|
||||||
audio_mux(btv,(input == bttv_tvcards[btv->c.type].tuner ?
|
audio_input(btv,(input == bttv_tvcards[btv->c.type].tuner ?
|
||||||
AUDIO_TUNER : AUDIO_EXTERN));
|
TVAUDIO_INPUT_TUNER : TVAUDIO_INPUT_EXTERN));
|
||||||
set_tvnorm(btv,btv->tvnorm);
|
set_tvnorm(btv,btv->tvnorm);
|
||||||
i2c_vidiocschan(btv);
|
i2c_vidiocschan(btv);
|
||||||
}
|
}
|
||||||
|
@ -1236,10 +1291,10 @@ static int set_control(struct bttv *btv, struct v4l2_control *c)
|
||||||
case V4L2_CID_AUDIO_MUTE:
|
case V4L2_CID_AUDIO_MUTE:
|
||||||
if (c->value) {
|
if (c->value) {
|
||||||
va.flags |= VIDEO_AUDIO_MUTE;
|
va.flags |= VIDEO_AUDIO_MUTE;
|
||||||
audio_mux(btv, AUDIO_MUTE);
|
audio_mute(btv, 1);
|
||||||
} else {
|
} else {
|
||||||
va.flags &= ~VIDEO_AUDIO_MUTE;
|
va.flags &= ~VIDEO_AUDIO_MUTE;
|
||||||
audio_mux(btv, AUDIO_UNMUTE);
|
audio_mute(btv, 0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -1397,7 +1452,7 @@ bttv_switch_overlay(struct bttv *btv, struct bttv_fh *fh,
|
||||||
free_btres(btv,fh,RESOURCE_OVERLAY);
|
free_btres(btv,fh,RESOURCE_OVERLAY);
|
||||||
if (NULL != old) {
|
if (NULL != old) {
|
||||||
dprintk("switch_overlay: old=%p state is %d\n",old,old->vb.state);
|
dprintk("switch_overlay: old=%p state is %d\n",old,old->vb.state);
|
||||||
bttv_dma_free(btv, old);
|
bttv_dma_free(&fh->cap,btv, old);
|
||||||
kfree(old);
|
kfree(old);
|
||||||
}
|
}
|
||||||
dprintk("switch_overlay: done\n");
|
dprintk("switch_overlay: done\n");
|
||||||
|
@ -1407,7 +1462,8 @@ bttv_switch_overlay(struct bttv *btv, struct bttv_fh *fh,
|
||||||
/* ----------------------------------------------------------------------- */
|
/* ----------------------------------------------------------------------- */
|
||||||
/* video4linux (1) interface */
|
/* video4linux (1) interface */
|
||||||
|
|
||||||
static int bttv_prepare_buffer(struct bttv *btv, struct bttv_buffer *buf,
|
static int bttv_prepare_buffer(struct videobuf_queue *q,struct bttv *btv,
|
||||||
|
struct bttv_buffer *buf,
|
||||||
const struct bttv_format *fmt,
|
const struct bttv_format *fmt,
|
||||||
unsigned int width, unsigned int height,
|
unsigned int width, unsigned int height,
|
||||||
enum v4l2_field field)
|
enum v4l2_field field)
|
||||||
|
@ -1450,7 +1506,7 @@ static int bttv_prepare_buffer(struct bttv *btv, struct bttv_buffer *buf,
|
||||||
/* alloc risc memory */
|
/* alloc risc memory */
|
||||||
if (STATE_NEEDS_INIT == buf->vb.state) {
|
if (STATE_NEEDS_INIT == buf->vb.state) {
|
||||||
redo_dma_risc = 1;
|
redo_dma_risc = 1;
|
||||||
if (0 != (rc = videobuf_iolock(btv->c.pci,&buf->vb,&btv->fbuf)))
|
if (0 != (rc = videobuf_iolock(q,&buf->vb,&btv->fbuf)))
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1462,7 +1518,7 @@ static int bttv_prepare_buffer(struct bttv *btv, struct bttv_buffer *buf,
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
bttv_dma_free(btv,buf);
|
bttv_dma_free(q,btv,buf);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1486,7 +1542,7 @@ buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
|
||||||
struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb);
|
struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb);
|
||||||
struct bttv_fh *fh = q->priv_data;
|
struct bttv_fh *fh = q->priv_data;
|
||||||
|
|
||||||
return bttv_prepare_buffer(fh->btv, buf, fh->fmt,
|
return bttv_prepare_buffer(q,fh->btv, buf, fh->fmt,
|
||||||
fh->width, fh->height, field);
|
fh->width, fh->height, field);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1510,7 +1566,7 @@ static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
|
||||||
struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb);
|
struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb);
|
||||||
struct bttv_fh *fh = q->priv_data;
|
struct bttv_fh *fh = q->priv_data;
|
||||||
|
|
||||||
bttv_dma_free(fh->btv,buf);
|
bttv_dma_free(&fh->cap,fh->btv,buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct videobuf_queue_ops bttv_video_qops = {
|
static struct videobuf_queue_ops bttv_video_qops = {
|
||||||
|
@ -1653,7 +1709,7 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
mutex_lock(&btv->lock);
|
mutex_lock(&btv->lock);
|
||||||
audio_mux(btv, (v->flags&VIDEO_AUDIO_MUTE) ? AUDIO_MUTE : AUDIO_UNMUTE);
|
audio_mute(btv, (v->flags&VIDEO_AUDIO_MUTE) ? 1 : 0);
|
||||||
bttv_call_i2c_clients(btv,cmd,v);
|
bttv_call_i2c_clients(btv,cmd,v);
|
||||||
|
|
||||||
/* card specific hooks */
|
/* card specific hooks */
|
||||||
|
@ -1822,7 +1878,8 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg)
|
||||||
bttv_call_i2c_clients(btv, VIDIOCGAUDIO, &va);
|
bttv_call_i2c_clients(btv, VIDIOCGAUDIO, &va);
|
||||||
if (t->audmode == V4L2_TUNER_MODE_MONO)
|
if (t->audmode == V4L2_TUNER_MODE_MONO)
|
||||||
va.mode = VIDEO_SOUND_MONO;
|
va.mode = VIDEO_SOUND_MONO;
|
||||||
else if (t->audmode == V4L2_TUNER_MODE_STEREO)
|
else if (t->audmode == V4L2_TUNER_MODE_STEREO ||
|
||||||
|
t->audmode == V4L2_TUNER_MODE_LANG1_LANG2)
|
||||||
va.mode = VIDEO_SOUND_STEREO;
|
va.mode = VIDEO_SOUND_STEREO;
|
||||||
else if (t->audmode == V4L2_TUNER_MODE_LANG1)
|
else if (t->audmode == V4L2_TUNER_MODE_LANG1)
|
||||||
va.mode = VIDEO_SOUND_LANG1;
|
va.mode = VIDEO_SOUND_LANG1;
|
||||||
|
@ -2496,7 +2553,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
|
||||||
field = (vm->height > bttv_tvnorms[btv->tvnorm].sheight/2)
|
field = (vm->height > bttv_tvnorms[btv->tvnorm].sheight/2)
|
||||||
? V4L2_FIELD_INTERLACED
|
? V4L2_FIELD_INTERLACED
|
||||||
: V4L2_FIELD_BOTTOM;
|
: V4L2_FIELD_BOTTOM;
|
||||||
retval = bttv_prepare_buffer(btv,buf,
|
retval = bttv_prepare_buffer(&fh->cap,btv,buf,
|
||||||
format_by_palette(vm->format),
|
format_by_palette(vm->format),
|
||||||
vm->width,vm->height,field);
|
vm->width,vm->height,field);
|
||||||
if (0 != retval)
|
if (0 != retval)
|
||||||
|
@ -2528,8 +2585,8 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
|
||||||
retval = -EIO;
|
retval = -EIO;
|
||||||
/* fall through */
|
/* fall through */
|
||||||
case STATE_DONE:
|
case STATE_DONE:
|
||||||
videobuf_dma_pci_sync(btv->c.pci,&buf->vb.dma);
|
videobuf_dma_sync(&fh->cap,&buf->vb.dma);
|
||||||
bttv_dma_free(btv,buf);
|
bttv_dma_free(&fh->cap,btv,buf);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
retval = -EINVAL;
|
retval = -EINVAL;
|
||||||
|
@ -3162,8 +3219,8 @@ static int radio_open(struct inode *inode, struct file *file)
|
||||||
|
|
||||||
file->private_data = btv;
|
file->private_data = btv;
|
||||||
|
|
||||||
bttv_call_i2c_clients(btv,AUDC_SET_RADIO,&btv->tuner_type);
|
bttv_call_i2c_clients(btv,AUDC_SET_RADIO,NULL);
|
||||||
audio_mux(btv,AUDIO_RADIO);
|
audio_input(btv,TVAUDIO_INPUT_RADIO);
|
||||||
|
|
||||||
mutex_unlock(&btv->lock);
|
mutex_unlock(&btv->lock);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -3749,7 +3806,7 @@ static irqreturn_t bttv_irq(int irq, void *dev_id, struct pt_regs * regs)
|
||||||
bttv_irq_switch_video(btv);
|
bttv_irq_switch_video(btv);
|
||||||
|
|
||||||
if ((astat & BT848_INT_HLOCK) && btv->opt_automute)
|
if ((astat & BT848_INT_HLOCK) && btv->opt_automute)
|
||||||
audio_mux(btv, -1);
|
audio_mute(btv, btv->mute); /* trigger automute */
|
||||||
|
|
||||||
if (astat & (BT848_INT_SCERR|BT848_INT_OCERR)) {
|
if (astat & (BT848_INT_SCERR|BT848_INT_OCERR)) {
|
||||||
printk(KERN_INFO "bttv%d: %s%s @ %08x,",btv->c.nr,
|
printk(KERN_INFO "bttv%d: %s%s @ %08x,",btv->c.nr,
|
||||||
|
@ -4050,7 +4107,7 @@ static int __devinit bttv_probe(struct pci_dev *dev,
|
||||||
bt848_contrast(btv,32768);
|
bt848_contrast(btv,32768);
|
||||||
bt848_hue(btv,32768);
|
bt848_hue(btv,32768);
|
||||||
bt848_sat(btv,32768);
|
bt848_sat(btv,32768);
|
||||||
audio_mux(btv,AUDIO_MUTE);
|
audio_mute(btv, 1);
|
||||||
set_input(btv,0);
|
set_input(btv,0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -302,6 +302,10 @@ static int attach_inform(struct i2c_client *client)
|
||||||
if (!client->driver->command)
|
if (!client->driver->command)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
if (client->driver->id == I2C_DRIVERID_MSP3400)
|
||||||
|
btv->i2c_msp34xx_client = client;
|
||||||
|
if (client->driver->id == I2C_DRIVERID_TVAUDIO)
|
||||||
|
btv->i2c_tvaudio_client = client;
|
||||||
if (btv->tuner_type != UNSET) {
|
if (btv->tuner_type != UNSET) {
|
||||||
struct tuner_setup tun_setup;
|
struct tuner_setup tun_setup;
|
||||||
|
|
|
@ -509,11 +509,11 @@ bttv_risc_hook(struct bttv *btv, int slot, struct btcx_riscmem *risc,
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
bttv_dma_free(struct bttv *btv, struct bttv_buffer *buf)
|
bttv_dma_free(struct videobuf_queue *q,struct bttv *btv, struct bttv_buffer *buf)
|
||||||
{
|
{
|
||||||
BUG_ON(in_interrupt());
|
BUG_ON(in_interrupt());
|
||||||
videobuf_waiton(&buf->vb,0,0);
|
videobuf_waiton(&buf->vb,0,0);
|
||||||
videobuf_dma_pci_unmap(btv->c.pci, &buf->vb.dma);
|
videobuf_dma_unmap(q, &buf->vb.dma);
|
||||||
videobuf_dma_free(&buf->vb.dma);
|
videobuf_dma_free(&buf->vb.dma);
|
||||||
btcx_riscmem_free(btv->c.pci,&buf->bottom);
|
btcx_riscmem_free(btv->c.pci,&buf->bottom);
|
||||||
btcx_riscmem_free(btv->c.pci,&buf->top);
|
btcx_riscmem_free(btv->c.pci,&buf->top);
|
|
@ -96,7 +96,7 @@ static int vbi_buffer_prepare(struct videobuf_queue *q,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (STATE_NEEDS_INIT == buf->vb.state) {
|
if (STATE_NEEDS_INIT == buf->vb.state) {
|
||||||
if (0 != (rc = videobuf_iolock(btv->c.pci, &buf->vb, NULL)))
|
if (0 != (rc = videobuf_iolock(q, &buf->vb, NULL)))
|
||||||
goto fail;
|
goto fail;
|
||||||
if (0 != (rc = vbi_buffer_risc(btv,buf,fh->lines)))
|
if (0 != (rc = vbi_buffer_risc(btv,buf,fh->lines)))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
@ -109,7 +109,7 @@ static int vbi_buffer_prepare(struct videobuf_queue *q,
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
bttv_dma_free(btv,buf);
|
bttv_dma_free(q,btv,buf);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,7 +136,7 @@ static void vbi_buffer_release(struct videobuf_queue *q, struct videobuf_buffer
|
||||||
struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb);
|
struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb);
|
||||||
|
|
||||||
dprintk("free %p\n",vb);
|
dprintk("free %p\n",vb);
|
||||||
bttv_dma_free(fh->btv,buf);
|
bttv_dma_free(&fh->cap,fh->btv,buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct videobuf_queue_ops bttv_vbi_qops = {
|
struct videobuf_queue_ops bttv_vbi_qops = {
|
|
@ -18,6 +18,7 @@
|
||||||
#include <linux/i2c.h>
|
#include <linux/i2c.h>
|
||||||
#include <media/ir-common.h>
|
#include <media/ir-common.h>
|
||||||
#include <media/ir-kbd-i2c.h>
|
#include <media/ir-kbd-i2c.h>
|
||||||
|
#include <media/i2c-addr.h>
|
||||||
|
|
||||||
/* ---------------------------------------------------------- */
|
/* ---------------------------------------------------------- */
|
||||||
/* exported by bttv-cards.c */
|
/* exported by bttv-cards.c */
|
||||||
|
@ -168,25 +169,6 @@
|
||||||
#define BTTV_BOARD_HAUPPAUGE_IMPACTVCB 0x8f
|
#define BTTV_BOARD_HAUPPAUGE_IMPACTVCB 0x8f
|
||||||
#define BTTV_BOARD_MACHTV_MAGICTV 0x90
|
#define BTTV_BOARD_MACHTV_MAGICTV 0x90
|
||||||
|
|
||||||
/* i2c address list */
|
|
||||||
#define I2C_TSA5522 0xc2
|
|
||||||
#define I2C_TDA7432 0x8a
|
|
||||||
#define I2C_BT832_ALT1 0x88
|
|
||||||
#define I2C_BT832_ALT2 0x8a // alternate setting
|
|
||||||
#define I2C_TDA8425 0x82
|
|
||||||
#define I2C_TDA9840 0x84
|
|
||||||
#define I2C_TDA9850 0xb6 /* also used by 9855,9873 */
|
|
||||||
#define I2C_TDA9874 0xb0 /* also used by 9875 */
|
|
||||||
#define I2C_TDA9875 0xb0
|
|
||||||
#define I2C_HAUPEE 0xa0
|
|
||||||
#define I2C_STBEE 0xae
|
|
||||||
#define I2C_VHX 0xc0
|
|
||||||
#define I2C_MSP3400 0x80
|
|
||||||
#define I2C_MSP3400_ALT 0x88
|
|
||||||
#define I2C_TEA6300 0x80 /* also used by 6320 */
|
|
||||||
#define I2C_DPL3518 0x84
|
|
||||||
#define I2C_TDA9887 0x86
|
|
||||||
|
|
||||||
/* more card-specific defines */
|
/* more card-specific defines */
|
||||||
#define PT2254_L_CHANNEL 0x10
|
#define PT2254_L_CHANNEL 0x10
|
||||||
#define PT2254_R_CHANNEL 0x08
|
#define PT2254_R_CHANNEL 0x08
|
||||||
|
@ -252,7 +234,8 @@ struct tvcard
|
||||||
unsigned int digital_mode; // DIGITAL_MODE_CAMERA or DIGITAL_MODE_VIDEO
|
unsigned int digital_mode; // DIGITAL_MODE_CAMERA or DIGITAL_MODE_VIDEO
|
||||||
u32 gpiomask;
|
u32 gpiomask;
|
||||||
u32 muxsel[16];
|
u32 muxsel[16];
|
||||||
u32 audiomux[6]; /* Tuner, Radio, external, internal, mute, stereo */
|
u32 gpiomux[4]; /* Tuner, Radio, external, internal */
|
||||||
|
u32 gpiomute; /* GPIO mute setting */
|
||||||
u32 gpiomask2; /* GPIO MUX mask */
|
u32 gpiomask2; /* GPIO MUX mask */
|
||||||
|
|
||||||
/* i2c audio flags */
|
/* i2c audio flags */
|
|
@ -41,7 +41,6 @@
|
||||||
|
|
||||||
#include <linux/device.h>
|
#include <linux/device.h>
|
||||||
#include <media/video-buf.h>
|
#include <media/video-buf.h>
|
||||||
#include <media/audiochip.h>
|
|
||||||
#include <media/tuner.h>
|
#include <media/tuner.h>
|
||||||
#include <media/tveeprom.h>
|
#include <media/tveeprom.h>
|
||||||
#include <media/ir-common.h>
|
#include <media/ir-common.h>
|
||||||
|
@ -190,7 +189,8 @@ int bttv_buffer_activate_video(struct bttv *btv,
|
||||||
struct bttv_buffer_set *set);
|
struct bttv_buffer_set *set);
|
||||||
int bttv_buffer_activate_vbi(struct bttv *btv,
|
int bttv_buffer_activate_vbi(struct bttv *btv,
|
||||||
struct bttv_buffer *vbi);
|
struct bttv_buffer *vbi);
|
||||||
void bttv_dma_free(struct bttv *btv, struct bttv_buffer *buf);
|
void bttv_dma_free(struct videobuf_queue *q, struct bttv *btv,
|
||||||
|
struct bttv_buffer *buf);
|
||||||
|
|
||||||
/* overlay handling */
|
/* overlay handling */
|
||||||
int bttv_overlay_risc(struct bttv *btv, struct bttv_overlay *ov,
|
int bttv_overlay_risc(struct bttv *btv, struct bttv_overlay *ov,
|
||||||
|
@ -298,6 +298,8 @@ struct bttv {
|
||||||
int i2c_state, i2c_rc;
|
int i2c_state, i2c_rc;
|
||||||
int i2c_done;
|
int i2c_done;
|
||||||
wait_queue_head_t i2c_queue;
|
wait_queue_head_t i2c_queue;
|
||||||
|
struct i2c_client *i2c_msp34xx_client;
|
||||||
|
struct i2c_client *i2c_tvaudio_client;
|
||||||
|
|
||||||
/* video4linux (1) */
|
/* video4linux (1) */
|
||||||
struct video_device *video_dev;
|
struct video_device *video_dev;
|
||||||
|
@ -320,6 +322,7 @@ struct bttv {
|
||||||
/* video state */
|
/* video state */
|
||||||
unsigned int input;
|
unsigned int input;
|
||||||
unsigned int audio;
|
unsigned int audio;
|
||||||
|
unsigned int mute;
|
||||||
unsigned long freq;
|
unsigned long freq;
|
||||||
int tvnorm,hue,contrast,bright,saturation;
|
int tvnorm,hue,contrast,bright,saturation;
|
||||||
struct v4l2_framebuffer fbuf;
|
struct v4l2_framebuffer fbuf;
|
|
@ -150,7 +150,7 @@ static int qc_calibrate(struct qcam_device *q)
|
||||||
static struct qcam_device *qcam_init(struct parport *port)
|
static struct qcam_device *qcam_init(struct parport *port)
|
||||||
{
|
{
|
||||||
struct qcam_device *q;
|
struct qcam_device *q;
|
||||||
|
|
||||||
q = kmalloc(sizeof(struct qcam_device), GFP_KERNEL);
|
q = kmalloc(sizeof(struct qcam_device), GFP_KERNEL);
|
||||||
if(q==NULL)
|
if(q==NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -158,16 +158,16 @@ static struct qcam_device *qcam_init(struct parport *port)
|
||||||
q->pport = port;
|
q->pport = port;
|
||||||
q->pdev = parport_register_device(port, "bw-qcam", NULL, NULL,
|
q->pdev = parport_register_device(port, "bw-qcam", NULL, NULL,
|
||||||
NULL, 0, NULL);
|
NULL, 0, NULL);
|
||||||
if (q->pdev == NULL)
|
if (q->pdev == NULL)
|
||||||
{
|
{
|
||||||
printk(KERN_ERR "bw-qcam: couldn't register for %s.\n",
|
printk(KERN_ERR "bw-qcam: couldn't register for %s.\n",
|
||||||
port->name);
|
port->name);
|
||||||
kfree(q);
|
kfree(q);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(&q->vdev, &qcam_template, sizeof(qcam_template));
|
memcpy(&q->vdev, &qcam_template, sizeof(qcam_template));
|
||||||
|
|
||||||
mutex_init(&q->lock);
|
mutex_init(&q->lock);
|
||||||
|
|
||||||
q->port_mode = (QC_ANY | QC_NOTSET);
|
q->port_mode = (QC_ANY | QC_NOTSET);
|
||||||
|
@ -236,12 +236,12 @@ static int qc_waithand(struct qcam_device *q, int val)
|
||||||
while (!((status = read_lpstatus(q)) & 8))
|
while (!((status = read_lpstatus(q)) & 8))
|
||||||
{
|
{
|
||||||
/* 1000 is enough spins on the I/O for all normal
|
/* 1000 is enough spins on the I/O for all normal
|
||||||
cases, at that point we start to poll slowly
|
cases, at that point we start to poll slowly
|
||||||
until the camera wakes up. However, we are
|
until the camera wakes up. However, we are
|
||||||
busy blocked until the camera responds, so
|
busy blocked until the camera responds, so
|
||||||
setting it lower is much better for interactive
|
setting it lower is much better for interactive
|
||||||
response. */
|
response. */
|
||||||
|
|
||||||
if(runs++>maxpoll)
|
if(runs++>maxpoll)
|
||||||
{
|
{
|
||||||
msleep_interruptible(5);
|
msleep_interruptible(5);
|
||||||
|
@ -255,12 +255,12 @@ static int qc_waithand(struct qcam_device *q, int val)
|
||||||
while (((status = read_lpstatus(q)) & 8))
|
while (((status = read_lpstatus(q)) & 8))
|
||||||
{
|
{
|
||||||
/* 1000 is enough spins on the I/O for all normal
|
/* 1000 is enough spins on the I/O for all normal
|
||||||
cases, at that point we start to poll slowly
|
cases, at that point we start to poll slowly
|
||||||
until the camera wakes up. However, we are
|
until the camera wakes up. However, we are
|
||||||
busy blocked until the camera responds, so
|
busy blocked until the camera responds, so
|
||||||
setting it lower is much better for interactive
|
setting it lower is much better for interactive
|
||||||
response. */
|
response. */
|
||||||
|
|
||||||
if(runs++>maxpoll)
|
if(runs++>maxpoll)
|
||||||
{
|
{
|
||||||
msleep_interruptible(5);
|
msleep_interruptible(5);
|
||||||
|
@ -282,17 +282,17 @@ static unsigned int qc_waithand2(struct qcam_device *q, int val)
|
||||||
{
|
{
|
||||||
unsigned int status;
|
unsigned int status;
|
||||||
int runs=0;
|
int runs=0;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
status = read_lpdata(q);
|
status = read_lpdata(q);
|
||||||
/* 1000 is enough spins on the I/O for all normal
|
/* 1000 is enough spins on the I/O for all normal
|
||||||
cases, at that point we start to poll slowly
|
cases, at that point we start to poll slowly
|
||||||
until the camera wakes up. However, we are
|
until the camera wakes up. However, we are
|
||||||
busy blocked until the camera responds, so
|
busy blocked until the camera responds, so
|
||||||
setting it lower is much better for interactive
|
setting it lower is much better for interactive
|
||||||
response. */
|
response. */
|
||||||
|
|
||||||
if(runs++>maxpoll)
|
if(runs++>maxpoll)
|
||||||
{
|
{
|
||||||
msleep_interruptible(5);
|
msleep_interruptible(5);
|
||||||
|
@ -321,7 +321,7 @@ static int qc_detect(struct qcam_device *q)
|
||||||
|
|
||||||
lastreg = reg = read_lpstatus(q) & 0xf0;
|
lastreg = reg = read_lpstatus(q) & 0xf0;
|
||||||
|
|
||||||
for (i = 0; i < 500; i++)
|
for (i = 0; i < 500; i++)
|
||||||
{
|
{
|
||||||
reg = read_lpstatus(q) & 0xf0;
|
reg = read_lpstatus(q) & 0xf0;
|
||||||
if (reg != lastreg)
|
if (reg != lastreg)
|
||||||
|
@ -357,7 +357,7 @@ static int qc_detect(struct qcam_device *q)
|
||||||
|
|
||||||
static void qc_reset(struct qcam_device *q)
|
static void qc_reset(struct qcam_device *q)
|
||||||
{
|
{
|
||||||
switch (q->port_mode & QC_FORCE_MASK)
|
switch (q->port_mode & QC_FORCE_MASK)
|
||||||
{
|
{
|
||||||
case QC_FORCE_UNIDIR:
|
case QC_FORCE_UNIDIR:
|
||||||
q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_UNIDIR;
|
q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_UNIDIR;
|
||||||
|
@ -370,7 +370,7 @@ static void qc_reset(struct qcam_device *q)
|
||||||
case QC_ANY:
|
case QC_ANY:
|
||||||
write_lpcontrol(q, 0x20);
|
write_lpcontrol(q, 0x20);
|
||||||
write_lpdata(q, 0x75);
|
write_lpdata(q, 0x75);
|
||||||
|
|
||||||
if (read_lpdata(q) != 0x75) {
|
if (read_lpdata(q) != 0x75) {
|
||||||
q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_BIDIR;
|
q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_BIDIR;
|
||||||
} else {
|
} else {
|
||||||
|
@ -398,8 +398,8 @@ static void qc_reset(struct qcam_device *q)
|
||||||
static int qc_setscanmode(struct qcam_device *q)
|
static int qc_setscanmode(struct qcam_device *q)
|
||||||
{
|
{
|
||||||
int old_mode = q->mode;
|
int old_mode = q->mode;
|
||||||
|
|
||||||
switch (q->transfer_scale)
|
switch (q->transfer_scale)
|
||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
q->mode = 0;
|
q->mode = 0;
|
||||||
|
@ -412,7 +412,7 @@ static int qc_setscanmode(struct qcam_device *q)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (q->bpp)
|
switch (q->bpp)
|
||||||
{
|
{
|
||||||
case 4:
|
case 4:
|
||||||
break;
|
break;
|
||||||
|
@ -421,7 +421,7 @@ static int qc_setscanmode(struct qcam_device *q)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (q->port_mode & QC_MODE_MASK)
|
switch (q->port_mode & QC_MODE_MASK)
|
||||||
{
|
{
|
||||||
case QC_BIDIR:
|
case QC_BIDIR:
|
||||||
q->mode += 1;
|
q->mode += 1;
|
||||||
|
@ -430,10 +430,10 @@ static int qc_setscanmode(struct qcam_device *q)
|
||||||
case QC_UNIDIR:
|
case QC_UNIDIR:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (q->mode != old_mode)
|
if (q->mode != old_mode)
|
||||||
q->status |= QC_PARAM_CHANGE;
|
q->status |= QC_PARAM_CHANGE;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -451,7 +451,7 @@ static void qc_set(struct qcam_device *q)
|
||||||
/* Set the brightness. Yes, this is repetitive, but it works.
|
/* Set the brightness. Yes, this is repetitive, but it works.
|
||||||
* Shorter versions seem to fail subtly. Feel free to try :-). */
|
* Shorter versions seem to fail subtly. Feel free to try :-). */
|
||||||
/* I think the problem was in qc_command, not here -- bls */
|
/* I think the problem was in qc_command, not here -- bls */
|
||||||
|
|
||||||
qc_command(q, 0xb);
|
qc_command(q, 0xb);
|
||||||
qc_command(q, q->brightness);
|
qc_command(q, q->brightness);
|
||||||
|
|
||||||
|
@ -502,13 +502,13 @@ static inline int qc_readbytes(struct qcam_device *q, char buffer[])
|
||||||
unsigned int hi2, lo2;
|
unsigned int hi2, lo2;
|
||||||
static int state = 0;
|
static int state = 0;
|
||||||
|
|
||||||
if (buffer == NULL)
|
if (buffer == NULL)
|
||||||
{
|
{
|
||||||
state = 0;
|
state = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (q->port_mode & QC_MODE_MASK)
|
switch (q->port_mode & QC_MODE_MASK)
|
||||||
{
|
{
|
||||||
case QC_BIDIR: /* Bi-directional Port */
|
case QC_BIDIR: /* Bi-directional Port */
|
||||||
write_lpcontrol(q, 0x26);
|
write_lpcontrol(q, 0x26);
|
||||||
|
@ -517,7 +517,7 @@ static inline int qc_readbytes(struct qcam_device *q, char buffer[])
|
||||||
write_lpcontrol(q, 0x2e);
|
write_lpcontrol(q, 0x2e);
|
||||||
lo2 = (qc_waithand2(q, 0) >> 1);
|
lo2 = (qc_waithand2(q, 0) >> 1);
|
||||||
hi2 = (read_lpstatus(q) >> 3) & 0x1f;
|
hi2 = (read_lpstatus(q) >> 3) & 0x1f;
|
||||||
switch (q->bpp)
|
switch (q->bpp)
|
||||||
{
|
{
|
||||||
case 4:
|
case 4:
|
||||||
buffer[0] = lo & 0xf;
|
buffer[0] = lo & 0xf;
|
||||||
|
@ -544,7 +544,7 @@ static inline int qc_readbytes(struct qcam_device *q, char buffer[])
|
||||||
write_lpcontrol(q, 0xe);
|
write_lpcontrol(q, 0xe);
|
||||||
hi = (qc_waithand(q, 0) & 0xf0) >> 4;
|
hi = (qc_waithand(q, 0) & 0xf0) >> 4;
|
||||||
|
|
||||||
switch (q->bpp)
|
switch (q->bpp)
|
||||||
{
|
{
|
||||||
case 4:
|
case 4:
|
||||||
buffer[0] = lo;
|
buffer[0] = lo;
|
||||||
|
@ -552,7 +552,7 @@ static inline int qc_readbytes(struct qcam_device *q, char buffer[])
|
||||||
ret = 2;
|
ret = 2;
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
switch (state)
|
switch (state)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
buffer[0] = (lo << 2) | ((hi & 0xc) >> 2);
|
buffer[0] = (lo << 2) | ((hi & 0xc) >> 2);
|
||||||
|
@ -604,13 +604,13 @@ static long qc_capture(struct qcam_device * q, char __user *buf, unsigned long l
|
||||||
int shift=8-q->bpp;
|
int shift=8-q->bpp;
|
||||||
char invert;
|
char invert;
|
||||||
|
|
||||||
if (q->mode == -1)
|
if (q->mode == -1)
|
||||||
return -ENXIO;
|
return -ENXIO;
|
||||||
|
|
||||||
qc_command(q, 0x7);
|
qc_command(q, 0x7);
|
||||||
qc_command(q, q->mode);
|
qc_command(q, q->mode);
|
||||||
|
|
||||||
if ((q->port_mode & QC_MODE_MASK) == QC_BIDIR)
|
if ((q->port_mode & QC_MODE_MASK) == QC_BIDIR)
|
||||||
{
|
{
|
||||||
write_lpcontrol(q, 0x2e); /* turn port around */
|
write_lpcontrol(q, 0x2e); /* turn port around */
|
||||||
write_lpcontrol(q, 0x26);
|
write_lpcontrol(q, 0x26);
|
||||||
|
@ -618,7 +618,7 @@ static long qc_capture(struct qcam_device * q, char __user *buf, unsigned long l
|
||||||
write_lpcontrol(q, 0x2e);
|
write_lpcontrol(q, 0x2e);
|
||||||
(void) qc_waithand(q, 0);
|
(void) qc_waithand(q, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* strange -- should be 15:63 below, but 4bpp is odd */
|
/* strange -- should be 15:63 below, but 4bpp is odd */
|
||||||
invert = (q->bpp == 4) ? 16 : 63;
|
invert = (q->bpp == 4) ? 16 : 63;
|
||||||
|
|
||||||
|
@ -629,15 +629,15 @@ static long qc_capture(struct qcam_device * q, char __user *buf, unsigned long l
|
||||||
q->transfer_scale;
|
q->transfer_scale;
|
||||||
transperline = (transperline + divisor - 1) / divisor;
|
transperline = (transperline + divisor - 1) / divisor;
|
||||||
|
|
||||||
for (i = 0, yield = yieldlines; i < linestotrans; i++)
|
for (i = 0, yield = yieldlines; i < linestotrans; i++)
|
||||||
{
|
{
|
||||||
for (pixels_read = j = 0; j < transperline; j++)
|
for (pixels_read = j = 0; j < transperline; j++)
|
||||||
{
|
{
|
||||||
bytes = qc_readbytes(q, buffer);
|
bytes = qc_readbytes(q, buffer);
|
||||||
for (k = 0; k < bytes && (pixels_read + k) < pixels_per_line; k++)
|
for (k = 0; k < bytes && (pixels_read + k) < pixels_per_line; k++)
|
||||||
{
|
{
|
||||||
int o;
|
int o;
|
||||||
if (buffer[k] == 0 && invert == 16)
|
if (buffer[k] == 0 && invert == 16)
|
||||||
{
|
{
|
||||||
/* 4bpp is odd (again) -- inverter is 16, not 15, but output
|
/* 4bpp is odd (again) -- inverter is 16, not 15, but output
|
||||||
must be 0-15 -- bls */
|
must be 0-15 -- bls */
|
||||||
|
@ -653,7 +653,7 @@ static long qc_capture(struct qcam_device * q, char __user *buf, unsigned long l
|
||||||
pixels_read += bytes;
|
pixels_read += bytes;
|
||||||
}
|
}
|
||||||
(void) qc_readbytes(q, NULL); /* reset state machine */
|
(void) qc_readbytes(q, NULL); /* reset state machine */
|
||||||
|
|
||||||
/* Grabbing an entire frame from the quickcam is a lengthy
|
/* Grabbing an entire frame from the quickcam is a lengthy
|
||||||
process. We don't (usually) want to busy-block the
|
process. We don't (usually) want to busy-block the
|
||||||
processor for the entire frame. yieldlines is a module
|
processor for the entire frame. yieldlines is a module
|
||||||
|
@ -666,7 +666,7 @@ static long qc_capture(struct qcam_device * q, char __user *buf, unsigned long l
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((q->port_mode & QC_MODE_MASK) == QC_BIDIR)
|
if ((q->port_mode & QC_MODE_MASK) == QC_BIDIR)
|
||||||
{
|
{
|
||||||
write_lpcontrol(q, 2);
|
write_lpcontrol(q, 2);
|
||||||
write_lpcontrol(q, 6);
|
write_lpcontrol(q, 6);
|
||||||
|
@ -687,7 +687,7 @@ static int qcam_do_ioctl(struct inode *inode, struct file *file,
|
||||||
{
|
{
|
||||||
struct video_device *dev = video_devdata(file);
|
struct video_device *dev = video_devdata(file);
|
||||||
struct qcam_device *qcam=(struct qcam_device *)dev;
|
struct qcam_device *qcam=(struct qcam_device *)dev;
|
||||||
|
|
||||||
switch(cmd)
|
switch(cmd)
|
||||||
{
|
{
|
||||||
case VIDIOCGCAP:
|
case VIDIOCGCAP:
|
||||||
|
@ -762,7 +762,7 @@ static int qcam_do_ioctl(struct inode *inode, struct file *file,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if(p->depth!=4 && p->depth!=6)
|
if(p->depth!=4 && p->depth!=6)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Now load the camera.
|
* Now load the camera.
|
||||||
*/
|
*/
|
||||||
|
@ -790,11 +790,11 @@ static int qcam_do_ioctl(struct inode *inode, struct file *file,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if(vw->width<80||vw->width>320)
|
if(vw->width<80||vw->width>320)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
qcam->width = 320;
|
qcam->width = 320;
|
||||||
qcam->height = 240;
|
qcam->height = 240;
|
||||||
qcam->transfer_scale = 4;
|
qcam->transfer_scale = 4;
|
||||||
|
|
||||||
if(vw->width>=160 && vw->height>=120)
|
if(vw->width>=160 && vw->height>=120)
|
||||||
{
|
{
|
||||||
qcam->transfer_scale = 2;
|
qcam->transfer_scale = 2;
|
||||||
|
@ -808,11 +808,11 @@ static int qcam_do_ioctl(struct inode *inode, struct file *file,
|
||||||
mutex_lock(&qcam->lock);
|
mutex_lock(&qcam->lock);
|
||||||
qc_setscanmode(qcam);
|
qc_setscanmode(qcam);
|
||||||
mutex_unlock(&qcam->lock);
|
mutex_unlock(&qcam->lock);
|
||||||
|
|
||||||
/* We must update the camera before we grab. We could
|
/* We must update the camera before we grab. We could
|
||||||
just have changed the grab size */
|
just have changed the grab size */
|
||||||
qcam->status |= QC_PARAM_CHANGE;
|
qcam->status |= QC_PARAM_CHANGE;
|
||||||
|
|
||||||
/* Ok we figured out what to use from our wide choice */
|
/* Ok we figured out what to use from our wide choice */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -853,9 +853,9 @@ static ssize_t qcam_read(struct file *file, char __user *buf,
|
||||||
struct qcam_device *qcam=(struct qcam_device *)v;
|
struct qcam_device *qcam=(struct qcam_device *)v;
|
||||||
int len;
|
int len;
|
||||||
parport_claim_or_block(qcam->pdev);
|
parport_claim_or_block(qcam->pdev);
|
||||||
|
|
||||||
mutex_lock(&qcam->lock);
|
mutex_lock(&qcam->lock);
|
||||||
|
|
||||||
qc_reset(qcam);
|
qc_reset(qcam);
|
||||||
|
|
||||||
/* Update the camera parameters if we need to */
|
/* Update the camera parameters if we need to */
|
||||||
|
@ -863,13 +863,13 @@ static ssize_t qcam_read(struct file *file, char __user *buf,
|
||||||
qc_set(qcam);
|
qc_set(qcam);
|
||||||
|
|
||||||
len=qc_capture(qcam, buf,count);
|
len=qc_capture(qcam, buf,count);
|
||||||
|
|
||||||
mutex_unlock(&qcam->lock);
|
mutex_unlock(&qcam->lock);
|
||||||
|
|
||||||
parport_release(qcam->pdev);
|
parport_release(qcam->pdev);
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct file_operations qcam_fops = {
|
static struct file_operations qcam_fops = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.open = video_exclusive_open,
|
.open = video_exclusive_open,
|
||||||
|
@ -905,11 +905,11 @@ static int init_bwqcam(struct parport *port)
|
||||||
qcam=qcam_init(port);
|
qcam=qcam_init(port);
|
||||||
if(qcam==NULL)
|
if(qcam==NULL)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
parport_claim_or_block(qcam->pdev);
|
parport_claim_or_block(qcam->pdev);
|
||||||
|
|
||||||
qc_reset(qcam);
|
qc_reset(qcam);
|
||||||
|
|
||||||
if(qc_detect(qcam)==0)
|
if(qc_detect(qcam)==0)
|
||||||
{
|
{
|
||||||
parport_release(qcam->pdev);
|
parport_release(qcam->pdev);
|
||||||
|
@ -920,9 +920,9 @@ static int init_bwqcam(struct parport *port)
|
||||||
qc_calibrate(qcam);
|
qc_calibrate(qcam);
|
||||||
|
|
||||||
parport_release(qcam->pdev);
|
parport_release(qcam->pdev);
|
||||||
|
|
||||||
printk(KERN_INFO "Connectix Quickcam on %s\n", qcam->pport->name);
|
printk(KERN_INFO "Connectix Quickcam on %s\n", qcam->pport->name);
|
||||||
|
|
||||||
if(video_register_device(&qcam->vdev, VFL_TYPE_GRABBER, video_nr)==-1)
|
if(video_register_device(&qcam->vdev, VFL_TYPE_GRABBER, video_nr)==-1)
|
||||||
{
|
{
|
||||||
parport_unregister_device(qcam->pdev);
|
parport_unregister_device(qcam->pdev);
|
||||||
|
@ -1013,7 +1013,7 @@ static int __init init_bw_qcams(void)
|
||||||
printk("Connectix Quickcam max-poll was above 5000. Using 5000.\n");
|
printk("Connectix Quickcam max-poll was above 5000. Using 5000.\n");
|
||||||
maxpoll = 5000;
|
maxpoll = 5000;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (yieldlines < 1) {
|
if (yieldlines < 1) {
|
||||||
printk("Connectix Quickcam yieldlines was less than 1. Using 1.\n");
|
printk("Connectix Quickcam yieldlines was less than 1. Using 1.\n");
|
||||||
yieldlines = 1;
|
yieldlines = 1;
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
*
|
*
|
||||||
* The parport parameter controls which parports will be scanned.
|
* The parport parameter controls which parports will be scanned.
|
||||||
* Scanning all parports causes some printers to print a garbage page.
|
* Scanning all parports causes some printers to print a garbage page.
|
||||||
* -- March 14, 1999 Billy Donahue <billy@escape.com>
|
* -- March 14, 1999 Billy Donahue <billy@escape.com>
|
||||||
*
|
*
|
||||||
* Fixed data format to BGR, added force_rgb parameter. Added missing
|
* Fixed data format to BGR, added force_rgb parameter. Added missing
|
||||||
* parport_unregister_driver() on module removal.
|
* parport_unregister_driver() on module removal.
|
||||||
|
@ -88,7 +88,7 @@ static inline unsigned int qcam_ready2(struct qcam_device *qcam)
|
||||||
return (parport_read_data(qcam->pport) & 0x1)?1:0;
|
return (parport_read_data(qcam->pport) & 0x1)?1:0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned int qcam_await_ready1(struct qcam_device *qcam,
|
static unsigned int qcam_await_ready1(struct qcam_device *qcam,
|
||||||
int value)
|
int value)
|
||||||
{
|
{
|
||||||
unsigned long oldjiffies = jiffies;
|
unsigned long oldjiffies = jiffies;
|
||||||
|
@ -98,7 +98,7 @@ static unsigned int qcam_await_ready1(struct qcam_device *qcam,
|
||||||
if (qcam_ready1(qcam) == value)
|
if (qcam_ready1(qcam) == value)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* If the camera didn't respond within 1/25 second, poll slowly
|
/* If the camera didn't respond within 1/25 second, poll slowly
|
||||||
for a while. */
|
for a while. */
|
||||||
for (i = 0; i < 50; i++)
|
for (i = 0; i < 50; i++)
|
||||||
{
|
{
|
||||||
|
@ -123,7 +123,7 @@ static unsigned int qcam_await_ready2(struct qcam_device *qcam, int value)
|
||||||
if (qcam_ready2(qcam) == value)
|
if (qcam_ready2(qcam) == value)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* If the camera didn't respond within 1/25 second, poll slowly
|
/* If the camera didn't respond within 1/25 second, poll slowly
|
||||||
for a while. */
|
for a while. */
|
||||||
for (i = 0; i < 50; i++)
|
for (i = 0; i < 50; i++)
|
||||||
{
|
{
|
||||||
|
@ -157,12 +157,12 @@ static int qcam_write_data(struct qcam_device *qcam, unsigned int data)
|
||||||
unsigned int idata;
|
unsigned int idata;
|
||||||
parport_write_data(qcam->pport, data);
|
parport_write_data(qcam->pport, data);
|
||||||
idata = qcam_read_data(qcam);
|
idata = qcam_read_data(qcam);
|
||||||
if (data != idata)
|
if (data != idata)
|
||||||
{
|
{
|
||||||
printk(KERN_WARNING "cqcam: sent %x but received %x\n", data,
|
printk(KERN_WARNING "cqcam: sent %x but received %x\n", data,
|
||||||
idata);
|
idata);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -193,12 +193,12 @@ static int qc_detect(struct qcam_device *qcam)
|
||||||
no device was found". Fix this one day. */
|
no device was found". Fix this one day. */
|
||||||
if (qcam->pport->probe_info[0].class == PARPORT_CLASS_MEDIA
|
if (qcam->pport->probe_info[0].class == PARPORT_CLASS_MEDIA
|
||||||
&& qcam->pport->probe_info[0].model
|
&& qcam->pport->probe_info[0].model
|
||||||
&& !strcmp(qcam->pdev->port->probe_info[0].model,
|
&& !strcmp(qcam->pdev->port->probe_info[0].model,
|
||||||
"Color QuickCam 2.0")) {
|
"Color QuickCam 2.0")) {
|
||||||
printk(KERN_DEBUG "QuickCam: Found by IEEE1284 probe.\n");
|
printk(KERN_DEBUG "QuickCam: Found by IEEE1284 probe.\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (probe < 2)
|
if (probe < 2)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -206,11 +206,11 @@ static int qc_detect(struct qcam_device *qcam)
|
||||||
|
|
||||||
/* look for a heartbeat */
|
/* look for a heartbeat */
|
||||||
ostat = stat = parport_read_status(qcam->pport);
|
ostat = stat = parport_read_status(qcam->pport);
|
||||||
for (i=0; i<250; i++)
|
for (i=0; i<250; i++)
|
||||||
{
|
{
|
||||||
mdelay(1);
|
mdelay(1);
|
||||||
stat = parport_read_status(qcam->pport);
|
stat = parport_read_status(qcam->pport);
|
||||||
if (ostat != stat)
|
if (ostat != stat)
|
||||||
{
|
{
|
||||||
if (++count >= 3) return 1;
|
if (++count >= 3) return 1;
|
||||||
ostat = stat;
|
ostat = stat;
|
||||||
|
@ -226,11 +226,11 @@ static int qc_detect(struct qcam_device *qcam)
|
||||||
count = 0;
|
count = 0;
|
||||||
|
|
||||||
ostat = stat = parport_read_status(qcam->pport);
|
ostat = stat = parport_read_status(qcam->pport);
|
||||||
for (i=0; i<250; i++)
|
for (i=0; i<250; i++)
|
||||||
{
|
{
|
||||||
mdelay(1);
|
mdelay(1);
|
||||||
stat = parport_read_status(qcam->pport);
|
stat = parport_read_status(qcam->pport);
|
||||||
if (ostat != stat)
|
if (ostat != stat)
|
||||||
{
|
{
|
||||||
if (++count >= 3) return 1;
|
if (++count >= 3) return 1;
|
||||||
ostat = stat;
|
ostat = stat;
|
||||||
|
@ -247,7 +247,7 @@ static void qc_reset(struct qcam_device *qcam)
|
||||||
parport_write_control(qcam->pport, 0x8);
|
parport_write_control(qcam->pport, 0x8);
|
||||||
mdelay(1);
|
mdelay(1);
|
||||||
parport_write_control(qcam->pport, 0xc);
|
parport_write_control(qcam->pport, 0xc);
|
||||||
mdelay(1);
|
mdelay(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reset the QuickCam and program for brightness, contrast,
|
/* Reset the QuickCam and program for brightness, contrast,
|
||||||
|
@ -258,7 +258,7 @@ static void qc_setup(struct qcam_device *q)
|
||||||
qc_reset(q);
|
qc_reset(q);
|
||||||
|
|
||||||
/* Set the brightness. */
|
/* Set the brightness. */
|
||||||
qcam_set(q, 11, q->brightness);
|
qcam_set(q, 11, q->brightness);
|
||||||
|
|
||||||
/* Set the height and width. These refer to the actual
|
/* Set the height and width. These refer to the actual
|
||||||
CCD area *before* applying the selected decimation. */
|
CCD area *before* applying the selected decimation. */
|
||||||
|
@ -272,12 +272,12 @@ static void qc_setup(struct qcam_device *q)
|
||||||
/* Set contrast and white balance. */
|
/* Set contrast and white balance. */
|
||||||
qcam_set(q, 0x19, q->contrast);
|
qcam_set(q, 0x19, q->contrast);
|
||||||
qcam_set(q, 0x1f, q->whitebal);
|
qcam_set(q, 0x1f, q->whitebal);
|
||||||
|
|
||||||
/* Set the speed. */
|
/* Set the speed. */
|
||||||
qcam_set(q, 45, 2);
|
qcam_set(q, 45, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read some bytes from the camera and put them in the buffer.
|
/* Read some bytes from the camera and put them in the buffer.
|
||||||
nbytes should be a multiple of 3, because bidirectional mode gives
|
nbytes should be a multiple of 3, because bidirectional mode gives
|
||||||
us three bytes at a time. */
|
us three bytes at a time. */
|
||||||
|
|
||||||
|
@ -383,7 +383,7 @@ static long qc_capture(struct qcam_device *q, char __user *buf, unsigned long le
|
||||||
|
|
||||||
if (qcam_set(q, 7, (q->mode | (is_bi_dir?1:0)) + 1))
|
if (qcam_set(q, 7, (q->mode | (is_bi_dir?1:0)) + 1))
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
|
||||||
lines = q->height;
|
lines = q->height;
|
||||||
pixelsperline = q->width;
|
pixelsperline = q->width;
|
||||||
bitsperxfer = (is_bi_dir) ? 24 : 8;
|
bitsperxfer = (is_bi_dir) ? 24 : 8;
|
||||||
|
@ -499,7 +499,7 @@ static int qcam_do_ioctl(struct inode *inode, struct file *file,
|
||||||
{
|
{
|
||||||
struct video_device *dev = video_devdata(file);
|
struct video_device *dev = video_devdata(file);
|
||||||
struct qcam_device *qcam=(struct qcam_device *)dev;
|
struct qcam_device *qcam=(struct qcam_device *)dev;
|
||||||
|
|
||||||
switch(cmd)
|
switch(cmd)
|
||||||
{
|
{
|
||||||
case VIDIOCGCAP:
|
case VIDIOCGCAP:
|
||||||
|
@ -574,7 +574,7 @@ static int qcam_do_ioctl(struct inode *inode, struct file *file,
|
||||||
*/
|
*/
|
||||||
if (p->depth != 24 || p->palette != VIDEO_PALETTE_RGB24)
|
if (p->depth != 24 || p->palette != VIDEO_PALETTE_RGB24)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Now load the camera.
|
* Now load the camera.
|
||||||
*/
|
*/
|
||||||
|
@ -584,7 +584,7 @@ static int qcam_do_ioctl(struct inode *inode, struct file *file,
|
||||||
|
|
||||||
mutex_lock(&qcam->lock);
|
mutex_lock(&qcam->lock);
|
||||||
parport_claim_or_block(qcam->pdev);
|
parport_claim_or_block(qcam->pdev);
|
||||||
qc_setup(qcam);
|
qc_setup(qcam);
|
||||||
parport_release(qcam->pdev);
|
parport_release(qcam->pdev);
|
||||||
mutex_unlock(&qcam->lock);
|
mutex_unlock(&qcam->lock);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -601,11 +601,11 @@ static int qcam_do_ioctl(struct inode *inode, struct file *file,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if(vw->width<80||vw->width>320)
|
if(vw->width<80||vw->width>320)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
qcam->width = 80;
|
qcam->width = 80;
|
||||||
qcam->height = 60;
|
qcam->height = 60;
|
||||||
qcam->mode = QC_DECIMATION_4;
|
qcam->mode = QC_DECIMATION_4;
|
||||||
|
|
||||||
if(vw->width>=160 && vw->height>=120)
|
if(vw->width>=160 && vw->height>=120)
|
||||||
{
|
{
|
||||||
qcam->width = 160;
|
qcam->width = 160;
|
||||||
|
@ -627,7 +627,7 @@ static int qcam_do_ioctl(struct inode *inode, struct file *file,
|
||||||
qcam->mode = QC_BILLIONS | QC_DECIMATION_1;
|
qcam->mode = QC_BILLIONS | QC_DECIMATION_1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
/* Ok we figured out what to use from our
|
/* Ok we figured out what to use from our
|
||||||
wide choice */
|
wide choice */
|
||||||
mutex_lock(&qcam->lock);
|
mutex_lock(&qcam->lock);
|
||||||
parport_claim_or_block(qcam->pdev);
|
parport_claim_or_block(qcam->pdev);
|
||||||
|
@ -676,7 +676,7 @@ static ssize_t qcam_read(struct file *file, char __user *buf,
|
||||||
mutex_lock(&qcam->lock);
|
mutex_lock(&qcam->lock);
|
||||||
parport_claim_or_block(qcam->pdev);
|
parport_claim_or_block(qcam->pdev);
|
||||||
/* Probably should have a semaphore against multiple users */
|
/* Probably should have a semaphore against multiple users */
|
||||||
len = qc_capture(qcam, buf,count);
|
len = qc_capture(qcam, buf,count);
|
||||||
parport_release(qcam->pdev);
|
parport_release(qcam->pdev);
|
||||||
mutex_unlock(&qcam->lock);
|
mutex_unlock(&qcam->lock);
|
||||||
return len;
|
return len;
|
||||||
|
@ -707,7 +707,7 @@ static struct video_device qcam_template=
|
||||||
static struct qcam_device *qcam_init(struct parport *port)
|
static struct qcam_device *qcam_init(struct parport *port)
|
||||||
{
|
{
|
||||||
struct qcam_device *q;
|
struct qcam_device *q;
|
||||||
|
|
||||||
q = kmalloc(sizeof(struct qcam_device), GFP_KERNEL);
|
q = kmalloc(sizeof(struct qcam_device), GFP_KERNEL);
|
||||||
if(q==NULL)
|
if(q==NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -718,14 +718,14 @@ static struct qcam_device *qcam_init(struct parport *port)
|
||||||
|
|
||||||
q->bidirectional = (q->pport->modes & PARPORT_MODE_TRISTATE)?1:0;
|
q->bidirectional = (q->pport->modes & PARPORT_MODE_TRISTATE)?1:0;
|
||||||
|
|
||||||
if (q->pdev == NULL)
|
if (q->pdev == NULL)
|
||||||
{
|
{
|
||||||
printk(KERN_ERR "c-qcam: couldn't register for %s.\n",
|
printk(KERN_ERR "c-qcam: couldn't register for %s.\n",
|
||||||
port->name);
|
port->name);
|
||||||
kfree(q);
|
kfree(q);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(&q->vdev, &qcam_template, sizeof(qcam_template));
|
memcpy(&q->vdev, &qcam_template, sizeof(qcam_template));
|
||||||
|
|
||||||
mutex_init(&q->lock);
|
mutex_init(&q->lock);
|
||||||
|
@ -766,11 +766,11 @@ static int init_cqcam(struct parport *port)
|
||||||
qcam = qcam_init(port);
|
qcam = qcam_init(port);
|
||||||
if (qcam==NULL)
|
if (qcam==NULL)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
parport_claim_or_block(qcam->pdev);
|
parport_claim_or_block(qcam->pdev);
|
||||||
|
|
||||||
qc_reset(qcam);
|
qc_reset(qcam);
|
||||||
|
|
||||||
if (probe && qc_detect(qcam)==0)
|
if (probe && qc_detect(qcam)==0)
|
||||||
{
|
{
|
||||||
parport_release(qcam->pdev);
|
parport_release(qcam->pdev);
|
||||||
|
@ -782,7 +782,7 @@ static int init_cqcam(struct parport *port)
|
||||||
qc_setup(qcam);
|
qc_setup(qcam);
|
||||||
|
|
||||||
parport_release(qcam->pdev);
|
parport_release(qcam->pdev);
|
||||||
|
|
||||||
if (video_register_device(&qcam->vdev, VFL_TYPE_GRABBER, video_nr)==-1)
|
if (video_register_device(&qcam->vdev, VFL_TYPE_GRABBER, video_nr)==-1)
|
||||||
{
|
{
|
||||||
printk(KERN_ERR "Unable to register Colour QuickCam on %s\n",
|
printk(KERN_ERR "Unable to register Colour QuickCam on %s\n",
|
||||||
|
@ -792,9 +792,9 @@ static int init_cqcam(struct parport *port)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
printk(KERN_INFO "video%d: Colour QuickCam found on %s\n",
|
printk(KERN_INFO "video%d: Colour QuickCam found on %s\n",
|
||||||
qcam->vdev.minor, qcam->pport->name);
|
qcam->vdev.minor, qcam->pport->name);
|
||||||
|
|
||||||
qcams[num_cams++] = qcam;
|
qcams[num_cams++] = qcam;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -52,10 +52,10 @@
|
||||||
struct cpia_camera_ops
|
struct cpia_camera_ops
|
||||||
{
|
{
|
||||||
/* open sets privdata to point to structure for this camera.
|
/* open sets privdata to point to structure for this camera.
|
||||||
* Returns negative value on error, otherwise 0.
|
* Returns negative value on error, otherwise 0.
|
||||||
*/
|
*/
|
||||||
int (*open)(void *privdata);
|
int (*open)(void *privdata);
|
||||||
|
|
||||||
/* Registers callback function cb to be called with cbdata
|
/* Registers callback function cb to be called with cbdata
|
||||||
* when an image is ready. If cb is NULL, only single image grabs
|
* when an image is ready. If cb is NULL, only single image grabs
|
||||||
* should be used. cb should immediately call streamRead to read
|
* should be used. cb should immediately call streamRead to read
|
||||||
|
@ -63,8 +63,8 @@ struct cpia_camera_ops
|
||||||
* otherwise 0.
|
* otherwise 0.
|
||||||
*/
|
*/
|
||||||
int (*registerCallback)(void *privdata, void (*cb)(void *cbdata),
|
int (*registerCallback)(void *privdata, void (*cb)(void *cbdata),
|
||||||
void *cbdata);
|
void *cbdata);
|
||||||
|
|
||||||
/* transferCmd sends commands to the camera. command MUST point to
|
/* transferCmd sends commands to the camera. command MUST point to
|
||||||
* an 8 byte buffer in kernel space. data can be NULL if no extra
|
* an 8 byte buffer in kernel space. data can be NULL if no extra
|
||||||
* data is needed. The size of the data is given by the last 2
|
* data is needed. The size of the data is given by the last 2
|
||||||
|
@ -77,30 +77,30 @@ struct cpia_camera_ops
|
||||||
* Returns negative value on error, otherwise 0.
|
* Returns negative value on error, otherwise 0.
|
||||||
*/
|
*/
|
||||||
int (*streamStart)(void *privdata);
|
int (*streamStart)(void *privdata);
|
||||||
|
|
||||||
/* streamStop terminates stream capture mode.
|
/* streamStop terminates stream capture mode.
|
||||||
* Returns negative value on error, otherwise 0.
|
* Returns negative value on error, otherwise 0.
|
||||||
*/
|
*/
|
||||||
int (*streamStop)(void *privdata);
|
int (*streamStop)(void *privdata);
|
||||||
|
|
||||||
/* streamRead reads a frame from the camera. buffer points to a
|
/* streamRead reads a frame from the camera. buffer points to a
|
||||||
* buffer large enough to hold a complete frame in kernel space.
|
* buffer large enough to hold a complete frame in kernel space.
|
||||||
* noblock indicates if this should be a non blocking read.
|
* noblock indicates if this should be a non blocking read.
|
||||||
* Returns the number of bytes read, or negative value on error.
|
* Returns the number of bytes read, or negative value on error.
|
||||||
*/
|
*/
|
||||||
int (*streamRead)(void *privdata, u8 *buffer, int noblock);
|
int (*streamRead)(void *privdata, u8 *buffer, int noblock);
|
||||||
|
|
||||||
/* close disables the device until open() is called again.
|
/* close disables the device until open() is called again.
|
||||||
* Returns negative value on error, otherwise 0.
|
* Returns negative value on error, otherwise 0.
|
||||||
*/
|
*/
|
||||||
int (*close)(void *privdata);
|
int (*close)(void *privdata);
|
||||||
|
|
||||||
/* If wait_for_stream_ready is non-zero, wait until the streamState
|
/* If wait_for_stream_ready is non-zero, wait until the streamState
|
||||||
* is STREAM_READY before calling streamRead.
|
* is STREAM_READY before calling streamRead.
|
||||||
*/
|
*/
|
||||||
int wait_for_stream_ready;
|
int wait_for_stream_ready;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Used to maintain lowlevel module usage counts
|
* Used to maintain lowlevel module usage counts
|
||||||
*/
|
*/
|
||||||
struct module *owner;
|
struct module *owner;
|
||||||
|
@ -215,14 +215,14 @@ struct cam_params {
|
||||||
u8 videoSize; /* CIF/QCIF */
|
u8 videoSize; /* CIF/QCIF */
|
||||||
u8 subSample;
|
u8 subSample;
|
||||||
u8 yuvOrder;
|
u8 yuvOrder;
|
||||||
} format;
|
} format;
|
||||||
struct { /* Intel QX3 specific data */
|
struct { /* Intel QX3 specific data */
|
||||||
u8 qx3_detected; /* a QX3 is present */
|
u8 qx3_detected; /* a QX3 is present */
|
||||||
u8 toplight; /* top light lit , R/W */
|
u8 toplight; /* top light lit , R/W */
|
||||||
u8 bottomlight; /* bottom light lit, R/W */
|
u8 bottomlight; /* bottom light lit, R/W */
|
||||||
u8 button; /* snapshot button pressed (R/O) */
|
u8 button; /* snapshot button pressed (R/O) */
|
||||||
u8 cradled; /* microscope is in cradle (R/O) */
|
u8 cradled; /* microscope is in cradle (R/O) */
|
||||||
} qx3;
|
} qx3;
|
||||||
struct {
|
struct {
|
||||||
u8 colStart; /* skip first 8*colStart pixels */
|
u8 colStart; /* skip first 8*colStart pixels */
|
||||||
u8 colEnd; /* finish at 8*colEnd pixels */
|
u8 colEnd; /* finish at 8*colEnd pixels */
|
||||||
|
@ -247,13 +247,13 @@ enum v4l_camstates {
|
||||||
struct cam_data {
|
struct cam_data {
|
||||||
struct list_head cam_data_list;
|
struct list_head cam_data_list;
|
||||||
|
|
||||||
struct mutex busy_lock; /* guard against SMP multithreading */
|
struct mutex busy_lock; /* guard against SMP multithreading */
|
||||||
struct cpia_camera_ops *ops; /* lowlevel driver operations */
|
struct cpia_camera_ops *ops; /* lowlevel driver operations */
|
||||||
void *lowlevel_data; /* private data for lowlevel driver */
|
void *lowlevel_data; /* private data for lowlevel driver */
|
||||||
u8 *raw_image; /* buffer for raw image data */
|
u8 *raw_image; /* buffer for raw image data */
|
||||||
struct cpia_frame decompressed_frame;
|
struct cpia_frame decompressed_frame;
|
||||||
/* buffer to hold decompressed frame */
|
/* buffer to hold decompressed frame */
|
||||||
int image_size; /* sizeof last decompressed image */
|
int image_size; /* sizeof last decompressed image */
|
||||||
int open_count; /* # of process that have camera open */
|
int open_count; /* # of process that have camera open */
|
||||||
|
|
||||||
/* camera status */
|
/* camera status */
|
||||||
|
@ -265,7 +265,7 @@ struct cam_data {
|
||||||
struct mutex param_lock; /* params lock for this camera */
|
struct mutex param_lock; /* params lock for this camera */
|
||||||
struct cam_params params; /* camera settings */
|
struct cam_params params; /* camera settings */
|
||||||
struct proc_dir_entry *proc_entry; /* /proc/cpia/videoX */
|
struct proc_dir_entry *proc_entry; /* /proc/cpia/videoX */
|
||||||
|
|
||||||
/* v4l */
|
/* v4l */
|
||||||
int video_size; /* VIDEO_SIZE_ */
|
int video_size; /* VIDEO_SIZE_ */
|
||||||
volatile enum v4l_camstates camstate; /* v4l layer status */
|
volatile enum v4l_camstates camstate; /* v4l layer status */
|
||||||
|
@ -277,7 +277,7 @@ struct cam_data {
|
||||||
/* mmap interface */
|
/* mmap interface */
|
||||||
int curframe; /* the current frame to grab into */
|
int curframe; /* the current frame to grab into */
|
||||||
u8 *frame_buf; /* frame buffer data */
|
u8 *frame_buf; /* frame buffer data */
|
||||||
struct cpia_frame frame[FRAME_NUM];
|
struct cpia_frame frame[FRAME_NUM];
|
||||||
/* FRAME_NUM-buffering, so we need a array */
|
/* FRAME_NUM-buffering, so we need a array */
|
||||||
|
|
||||||
int first_frame;
|
int first_frame;
|
||||||
|
@ -424,7 +424,7 @@ void cpia_unregister_camera(struct cam_data *cam);
|
||||||
#define DEB_BYTE(p)\
|
#define DEB_BYTE(p)\
|
||||||
DBG("%1d %1d %1d %1d %1d %1d %1d %1d \n",\
|
DBG("%1d %1d %1d %1d %1d %1d %1d %1d \n",\
|
||||||
(p)&0x80?1:0, (p)&0x40?1:0, (p)&0x20?1:0, (p)&0x10?1:0,\
|
(p)&0x80?1:0, (p)&0x40?1:0, (p)&0x20?1:0, (p)&0x10?1:0,\
|
||||||
(p)&0x08?1:0, (p)&0x04?1:0, (p)&0x02?1:0, (p)&0x01?1:0);
|
(p)&0x08?1:0, (p)&0x04?1:0, (p)&0x02?1:0, (p)&0x01?1:0);
|
||||||
|
|
||||||
#endif /* __KERNEL__ */
|
#endif /* __KERNEL__ */
|
||||||
|
|
||||||
|
|
|
@ -381,7 +381,7 @@ struct cpia2_fh {
|
||||||
|
|
||||||
struct camera_data {
|
struct camera_data {
|
||||||
/* locks */
|
/* locks */
|
||||||
struct semaphore busy_lock; /* guard against SMP multithreading */
|
struct mutex busy_lock; /* guard against SMP multithreading */
|
||||||
struct v4l2_prio_state prio;
|
struct v4l2_prio_state prio;
|
||||||
|
|
||||||
/* camera status */
|
/* camera status */
|
||||||
|
|
|
@ -2238,7 +2238,7 @@ struct camera_data *cpia2_init_camera_struct(void)
|
||||||
memset(cam, 0, sizeof(struct camera_data));
|
memset(cam, 0, sizeof(struct camera_data));
|
||||||
|
|
||||||
cam->present = 1;
|
cam->present = 1;
|
||||||
init_MUTEX(&cam->busy_lock);
|
mutex_init(&cam->busy_lock);
|
||||||
init_waitqueue_head(&cam->wq_stream);
|
init_waitqueue_head(&cam->wq_stream);
|
||||||
|
|
||||||
return cam;
|
return cam;
|
||||||
|
@ -2371,12 +2371,12 @@ long cpia2_read(struct camera_data *cam,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* make this _really_ smp and multithread-safe */
|
/* make this _really_ smp and multithread-safe */
|
||||||
if (down_interruptible(&cam->busy_lock))
|
if (mutex_lock_interruptible(&cam->busy_lock))
|
||||||
return -ERESTARTSYS;
|
return -ERESTARTSYS;
|
||||||
|
|
||||||
if (!cam->present) {
|
if (!cam->present) {
|
||||||
LOG("%s: camera removed\n",__FUNCTION__);
|
LOG("%s: camera removed\n",__FUNCTION__);
|
||||||
up(&cam->busy_lock);
|
mutex_unlock(&cam->busy_lock);
|
||||||
return 0; /* EOF */
|
return 0; /* EOF */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2389,34 +2389,34 @@ long cpia2_read(struct camera_data *cam,
|
||||||
/* Copy cam->curbuff in case it changes while we're processing */
|
/* Copy cam->curbuff in case it changes while we're processing */
|
||||||
frame = cam->curbuff;
|
frame = cam->curbuff;
|
||||||
if (noblock && frame->status != FRAME_READY) {
|
if (noblock && frame->status != FRAME_READY) {
|
||||||
up(&cam->busy_lock);
|
mutex_unlock(&cam->busy_lock);
|
||||||
return -EAGAIN;
|
return -EAGAIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(frame->status != FRAME_READY) {
|
if(frame->status != FRAME_READY) {
|
||||||
up(&cam->busy_lock);
|
mutex_unlock(&cam->busy_lock);
|
||||||
wait_event_interruptible(cam->wq_stream,
|
wait_event_interruptible(cam->wq_stream,
|
||||||
!cam->present ||
|
!cam->present ||
|
||||||
(frame = cam->curbuff)->status == FRAME_READY);
|
(frame = cam->curbuff)->status == FRAME_READY);
|
||||||
if (signal_pending(current))
|
if (signal_pending(current))
|
||||||
return -ERESTARTSYS;
|
return -ERESTARTSYS;
|
||||||
/* make this _really_ smp and multithread-safe */
|
/* make this _really_ smp and multithread-safe */
|
||||||
if (down_interruptible(&cam->busy_lock)) {
|
if (mutex_lock_interruptible(&cam->busy_lock)) {
|
||||||
return -ERESTARTSYS;
|
return -ERESTARTSYS;
|
||||||
}
|
}
|
||||||
if(!cam->present) {
|
if(!cam->present) {
|
||||||
up(&cam->busy_lock);
|
mutex_unlock(&cam->busy_lock);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* copy data to user space */
|
/* copy data to user space */
|
||||||
if (frame->length > count) {
|
if (frame->length > count) {
|
||||||
up(&cam->busy_lock);
|
mutex_unlock(&cam->busy_lock);
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
}
|
}
|
||||||
if (copy_to_user(buf, frame->data, frame->length)) {
|
if (copy_to_user(buf, frame->data, frame->length)) {
|
||||||
up(&cam->busy_lock);
|
mutex_unlock(&cam->busy_lock);
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2424,7 +2424,7 @@ long cpia2_read(struct camera_data *cam,
|
||||||
|
|
||||||
frame->status = FRAME_EMPTY;
|
frame->status = FRAME_EMPTY;
|
||||||
|
|
||||||
up(&cam->busy_lock);
|
mutex_unlock(&cam->busy_lock);
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2443,10 +2443,10 @@ unsigned int cpia2_poll(struct camera_data *cam, struct file *filp,
|
||||||
return POLLERR;
|
return POLLERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
down(&cam->busy_lock);
|
mutex_lock(&cam->busy_lock);
|
||||||
|
|
||||||
if(!cam->present) {
|
if(!cam->present) {
|
||||||
up(&cam->busy_lock);
|
mutex_unlock(&cam->busy_lock);
|
||||||
return POLLHUP;
|
return POLLHUP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2456,16 +2456,16 @@ unsigned int cpia2_poll(struct camera_data *cam, struct file *filp,
|
||||||
cam->params.camera_state.stream_mode);
|
cam->params.camera_state.stream_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
up(&cam->busy_lock);
|
mutex_unlock(&cam->busy_lock);
|
||||||
poll_wait(filp, &cam->wq_stream, wait);
|
poll_wait(filp, &cam->wq_stream, wait);
|
||||||
down(&cam->busy_lock);
|
mutex_lock(&cam->busy_lock);
|
||||||
|
|
||||||
if(!cam->present)
|
if(!cam->present)
|
||||||
status = POLLHUP;
|
status = POLLHUP;
|
||||||
else if(cam->curbuff->status == FRAME_READY)
|
else if(cam->curbuff->status == FRAME_READY)
|
||||||
status = POLLIN | POLLRDNORM;
|
status = POLLIN | POLLRDNORM;
|
||||||
|
|
||||||
up(&cam->busy_lock);
|
mutex_unlock(&cam->busy_lock);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2488,18 +2488,18 @@ int cpia2_remap_buffer(struct camera_data *cam, struct vm_area_struct *vma)
|
||||||
DBG("mmap offset:%ld size:%ld\n", start_offset, size);
|
DBG("mmap offset:%ld size:%ld\n", start_offset, size);
|
||||||
|
|
||||||
/* make this _really_ smp-safe */
|
/* make this _really_ smp-safe */
|
||||||
if (down_interruptible(&cam->busy_lock))
|
if (mutex_lock_interruptible(&cam->busy_lock))
|
||||||
return -ERESTARTSYS;
|
return -ERESTARTSYS;
|
||||||
|
|
||||||
if (!cam->present) {
|
if (!cam->present) {
|
||||||
up(&cam->busy_lock);
|
mutex_unlock(&cam->busy_lock);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (size > cam->frame_size*cam->num_frames ||
|
if (size > cam->frame_size*cam->num_frames ||
|
||||||
(start_offset % cam->frame_size) != 0 ||
|
(start_offset % cam->frame_size) != 0 ||
|
||||||
(start_offset+size > cam->frame_size*cam->num_frames)) {
|
(start_offset+size > cam->frame_size*cam->num_frames)) {
|
||||||
up(&cam->busy_lock);
|
mutex_unlock(&cam->busy_lock);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2507,7 +2507,7 @@ int cpia2_remap_buffer(struct camera_data *cam, struct vm_area_struct *vma)
|
||||||
while (size > 0) {
|
while (size > 0) {
|
||||||
page = kvirt_to_pa(pos);
|
page = kvirt_to_pa(pos);
|
||||||
if (remap_pfn_range(vma, start, page >> PAGE_SHIFT, PAGE_SIZE, PAGE_SHARED)) {
|
if (remap_pfn_range(vma, start, page >> PAGE_SHIFT, PAGE_SIZE, PAGE_SHARED)) {
|
||||||
up(&cam->busy_lock);
|
mutex_unlock(&cam->busy_lock);
|
||||||
return -EAGAIN;
|
return -EAGAIN;
|
||||||
}
|
}
|
||||||
start += PAGE_SIZE;
|
start += PAGE_SIZE;
|
||||||
|
@ -2519,7 +2519,7 @@ int cpia2_remap_buffer(struct camera_data *cam, struct vm_area_struct *vma)
|
||||||
}
|
}
|
||||||
|
|
||||||
cam->mmapped = true;
|
cam->mmapped = true;
|
||||||
up(&cam->busy_lock);
|
mutex_unlock(&cam->busy_lock);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -255,7 +255,7 @@ static int cpia2_open(struct inode *inode, struct file *file)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(down_interruptible(&cam->busy_lock))
|
if(mutex_lock_interruptible(&cam->busy_lock))
|
||||||
return -ERESTARTSYS;
|
return -ERESTARTSYS;
|
||||||
|
|
||||||
if(!cam->present) {
|
if(!cam->present) {
|
||||||
|
@ -299,7 +299,7 @@ static int cpia2_open(struct inode *inode, struct file *file)
|
||||||
cpia2_dbg_dump_registers(cam);
|
cpia2_dbg_dump_registers(cam);
|
||||||
|
|
||||||
err_return:
|
err_return:
|
||||||
up(&cam->busy_lock);
|
mutex_unlock(&cam->busy_lock);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -314,7 +314,7 @@ static int cpia2_close(struct inode *inode, struct file *file)
|
||||||
struct camera_data *cam = video_get_drvdata(dev);
|
struct camera_data *cam = video_get_drvdata(dev);
|
||||||
struct cpia2_fh *fh = file->private_data;
|
struct cpia2_fh *fh = file->private_data;
|
||||||
|
|
||||||
down(&cam->busy_lock);
|
mutex_lock(&cam->busy_lock);
|
||||||
|
|
||||||
if (cam->present &&
|
if (cam->present &&
|
||||||
(cam->open_count == 1
|
(cam->open_count == 1
|
||||||
|
@ -347,7 +347,7 @@ static int cpia2_close(struct inode *inode, struct file *file)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
up(&cam->busy_lock);
|
mutex_unlock(&cam->busy_lock);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -523,11 +523,11 @@ static int sync(struct camera_data *cam, int frame_nr)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
up(&cam->busy_lock);
|
mutex_unlock(&cam->busy_lock);
|
||||||
wait_event_interruptible(cam->wq_stream,
|
wait_event_interruptible(cam->wq_stream,
|
||||||
!cam->streaming ||
|
!cam->streaming ||
|
||||||
frame->status == FRAME_READY);
|
frame->status == FRAME_READY);
|
||||||
down(&cam->busy_lock);
|
mutex_lock(&cam->busy_lock);
|
||||||
if (signal_pending(current))
|
if (signal_pending(current))
|
||||||
return -ERESTARTSYS;
|
return -ERESTARTSYS;
|
||||||
if(!cam->present)
|
if(!cam->present)
|
||||||
|
@ -1544,11 +1544,11 @@ static int ioctl_dqbuf(void *arg,struct camera_data *cam, struct file *file)
|
||||||
if(frame < 0) {
|
if(frame < 0) {
|
||||||
/* Wait for a frame to become available */
|
/* Wait for a frame to become available */
|
||||||
struct framebuf *cb=cam->curbuff;
|
struct framebuf *cb=cam->curbuff;
|
||||||
up(&cam->busy_lock);
|
mutex_unlock(&cam->busy_lock);
|
||||||
wait_event_interruptible(cam->wq_stream,
|
wait_event_interruptible(cam->wq_stream,
|
||||||
!cam->present ||
|
!cam->present ||
|
||||||
(cb=cam->curbuff)->status == FRAME_READY);
|
(cb=cam->curbuff)->status == FRAME_READY);
|
||||||
down(&cam->busy_lock);
|
mutex_lock(&cam->busy_lock);
|
||||||
if (signal_pending(current))
|
if (signal_pending(current))
|
||||||
return -ERESTARTSYS;
|
return -ERESTARTSYS;
|
||||||
if(!cam->present)
|
if(!cam->present)
|
||||||
|
@ -1591,11 +1591,11 @@ static int cpia2_do_ioctl(struct inode *inode, struct file *file,
|
||||||
return -ENOTTY;
|
return -ENOTTY;
|
||||||
|
|
||||||
/* make this _really_ smp-safe */
|
/* make this _really_ smp-safe */
|
||||||
if (down_interruptible(&cam->busy_lock))
|
if (mutex_lock_interruptible(&cam->busy_lock))
|
||||||
return -ERESTARTSYS;
|
return -ERESTARTSYS;
|
||||||
|
|
||||||
if (!cam->present) {
|
if (!cam->present) {
|
||||||
up(&cam->busy_lock);
|
mutex_unlock(&cam->busy_lock);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1608,7 +1608,7 @@ static int cpia2_do_ioctl(struct inode *inode, struct file *file,
|
||||||
struct cpia2_fh *fh = file->private_data;
|
struct cpia2_fh *fh = file->private_data;
|
||||||
retval = v4l2_prio_check(&cam->prio, &fh->prio);
|
retval = v4l2_prio_check(&cam->prio, &fh->prio);
|
||||||
if(retval) {
|
if(retval) {
|
||||||
up(&cam->busy_lock);
|
mutex_unlock(&cam->busy_lock);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1618,7 +1618,7 @@ static int cpia2_do_ioctl(struct inode *inode, struct file *file,
|
||||||
{
|
{
|
||||||
struct cpia2_fh *fh = file->private_data;
|
struct cpia2_fh *fh = file->private_data;
|
||||||
if(fh->prio != V4L2_PRIORITY_RECORD) {
|
if(fh->prio != V4L2_PRIORITY_RECORD) {
|
||||||
up(&cam->busy_lock);
|
mutex_unlock(&cam->busy_lock);
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1847,7 +1847,7 @@ static int cpia2_do_ioctl(struct inode *inode, struct file *file,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
up(&cam->busy_lock);
|
mutex_unlock(&cam->busy_lock);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1924,14 +1924,15 @@ static void reset_camera_struct_v4l(struct camera_data *cam)
|
||||||
* The v4l video device structure initialized for this device
|
* The v4l video device structure initialized for this device
|
||||||
***/
|
***/
|
||||||
static struct file_operations fops_template = {
|
static struct file_operations fops_template = {
|
||||||
.owner= THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.open= cpia2_open,
|
.open = cpia2_open,
|
||||||
.release= cpia2_close,
|
.release = cpia2_close,
|
||||||
.read= cpia2_v4l_read,
|
.read = cpia2_v4l_read,
|
||||||
.poll= cpia2_v4l_poll,
|
.poll = cpia2_v4l_poll,
|
||||||
.ioctl= cpia2_ioctl,
|
.ioctl = cpia2_ioctl,
|
||||||
.llseek= no_llseek,
|
.llseek = no_llseek,
|
||||||
.mmap= cpia2_mmap,
|
.compat_ioctl = v4l_compat_ioctl32,
|
||||||
|
.mmap = cpia2_mmap,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct video_device cpia2_template = {
|
static struct video_device cpia2_template = {
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* define _CPIA_DEBUG_ for verbose debug output (see cpia.h) */
|
/* define _CPIA_DEBUG_ for verbose debug output (see cpia.h) */
|
||||||
/* #define _CPIA_DEBUG_ 1 */
|
/* #define _CPIA_DEBUG_ 1 */
|
||||||
|
|
||||||
#include <linux/config.h>
|
#include <linux/config.h>
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@
|
||||||
|
|
||||||
static int cpia_pp_open(void *privdata);
|
static int cpia_pp_open(void *privdata);
|
||||||
static int cpia_pp_registerCallback(void *privdata, void (*cb) (void *cbdata),
|
static int cpia_pp_registerCallback(void *privdata, void (*cb) (void *cbdata),
|
||||||
void *cbdata);
|
void *cbdata);
|
||||||
static int cpia_pp_transferCmd(void *privdata, u8 *command, u8 *data);
|
static int cpia_pp_transferCmd(void *privdata, u8 *command, u8 *data);
|
||||||
static int cpia_pp_streamStart(void *privdata);
|
static int cpia_pp_streamStart(void *privdata);
|
||||||
static int cpia_pp_streamStop(void *privdata);
|
static int cpia_pp_streamStop(void *privdata);
|
||||||
|
@ -93,7 +93,7 @@ struct pp_cam_entry {
|
||||||
int stream_irq;
|
int stream_irq;
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct cpia_camera_ops cpia_pp_ops =
|
static struct cpia_camera_ops cpia_pp_ops =
|
||||||
{
|
{
|
||||||
cpia_pp_open,
|
cpia_pp_open,
|
||||||
cpia_pp_registerCallback,
|
cpia_pp_registerCallback,
|
||||||
|
@ -123,7 +123,7 @@ static void cpia_parport_disable_irq( struct parport *port ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Special CPiA PPC modes: These are invoked by using the 1284 Extensibility
|
/* Special CPiA PPC modes: These are invoked by using the 1284 Extensibility
|
||||||
* Link Flag during negotiation */
|
* Link Flag during negotiation */
|
||||||
#define UPLOAD_FLAG 0x08
|
#define UPLOAD_FLAG 0x08
|
||||||
#define NIBBLE_TRANSFER 0x01
|
#define NIBBLE_TRANSFER 0x01
|
||||||
#define ECP_TRANSFER 0x03
|
#define ECP_TRANSFER 0x03
|
||||||
|
@ -139,17 +139,17 @@ static void cpia_parport_disable_irq( struct parport *port ) {
|
||||||
/* CPiA nonstandard "Nibble" mode (no nDataAvail signal after each byte). */
|
/* CPiA nonstandard "Nibble" mode (no nDataAvail signal after each byte). */
|
||||||
/* The standard kernel parport_ieee1284_read_nibble() fails with the CPiA... */
|
/* The standard kernel parport_ieee1284_read_nibble() fails with the CPiA... */
|
||||||
|
|
||||||
static size_t cpia_read_nibble (struct parport *port,
|
static size_t cpia_read_nibble (struct parport *port,
|
||||||
void *buffer, size_t len,
|
void *buffer, size_t len,
|
||||||
int flags)
|
int flags)
|
||||||
{
|
{
|
||||||
/* adapted verbatim, with one change, from
|
/* adapted verbatim, with one change, from
|
||||||
parport_ieee1284_read_nibble() in drivers/parport/ieee1284-ops.c */
|
parport_ieee1284_read_nibble() in drivers/parport/ieee1284-ops.c */
|
||||||
|
|
||||||
unsigned char *buf = buffer;
|
unsigned char *buf = buffer;
|
||||||
int i;
|
int i;
|
||||||
unsigned char byte = 0;
|
unsigned char byte = 0;
|
||||||
|
|
||||||
len *= 2; /* in nibbles */
|
len *= 2; /* in nibbles */
|
||||||
for (i=0; i < len; i++) {
|
for (i=0; i < len; i++) {
|
||||||
unsigned char nibble;
|
unsigned char nibble;
|
||||||
|
@ -158,12 +158,12 @@ static size_t cpia_read_nibble (struct parport *port,
|
||||||
* after every second nibble to signal that more
|
* after every second nibble to signal that more
|
||||||
* data is available. (the total number of Bytes that
|
* data is available. (the total number of Bytes that
|
||||||
* should be sent is known; if too few are received, an error
|
* should be sent is known; if too few are received, an error
|
||||||
* will be recorded after a timeout).
|
* will be recorded after a timeout).
|
||||||
* This is incompatible with parport_ieee1284_read_nibble(),
|
* This is incompatible with parport_ieee1284_read_nibble(),
|
||||||
* which expects to find nFault LO after every second nibble.
|
* which expects to find nFault LO after every second nibble.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Solution: modify cpia_read_nibble to only check for
|
/* Solution: modify cpia_read_nibble to only check for
|
||||||
* nDataAvail before the first nibble is sent.
|
* nDataAvail before the first nibble is sent.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -216,7 +216,7 @@ static size_t cpia_read_nibble (struct parport *port,
|
||||||
/* Second nibble */
|
/* Second nibble */
|
||||||
byte |= nibble << 4;
|
byte |= nibble << 4;
|
||||||
*buf++ = byte;
|
*buf++ = byte;
|
||||||
} else
|
} else
|
||||||
byte = nibble;
|
byte = nibble;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -238,18 +238,18 @@ static size_t cpia_read_nibble (struct parport *port,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* CPiA nonstandard "Nibble Stream" mode (2 nibbles per cycle, instead of 1)
|
/* CPiA nonstandard "Nibble Stream" mode (2 nibbles per cycle, instead of 1)
|
||||||
* (See CPiA Data sheet p. 31)
|
* (See CPiA Data sheet p. 31)
|
||||||
*
|
*
|
||||||
* "Nibble Stream" mode used by CPiA for uploads to non-ECP ports is a
|
* "Nibble Stream" mode used by CPiA for uploads to non-ECP ports is a
|
||||||
* nonstandard variant of nibble mode which allows the same (mediocre)
|
* nonstandard variant of nibble mode which allows the same (mediocre)
|
||||||
* data flow of 8 bits per cycle as software-enabled ECP by TRISTATE-capable
|
* data flow of 8 bits per cycle as software-enabled ECP by TRISTATE-capable
|
||||||
* parallel ports, but works also for non-TRISTATE-capable ports.
|
* parallel ports, but works also for non-TRISTATE-capable ports.
|
||||||
* (Standard nibble mode only send 4 bits per cycle)
|
* (Standard nibble mode only send 4 bits per cycle)
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static size_t cpia_read_nibble_stream(struct parport *port,
|
static size_t cpia_read_nibble_stream(struct parport *port,
|
||||||
void *buffer, size_t len,
|
void *buffer, size_t len,
|
||||||
int flags)
|
int flags)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
@ -260,7 +260,7 @@ static size_t cpia_read_nibble_stream(struct parport *port,
|
||||||
unsigned char nibble[2], byte = 0;
|
unsigned char nibble[2], byte = 0;
|
||||||
int j;
|
int j;
|
||||||
|
|
||||||
/* Image Data is complete when 4 consecutive EOI bytes (0xff) are seen */
|
/* Image Data is complete when 4 consecutive EOI bytes (0xff) are seen */
|
||||||
if (endseen > 3 )
|
if (endseen > 3 )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -268,7 +268,7 @@ static size_t cpia_read_nibble_stream(struct parport *port,
|
||||||
parport_frob_control (port,
|
parport_frob_control (port,
|
||||||
PARPORT_CONTROL_AUTOFD,
|
PARPORT_CONTROL_AUTOFD,
|
||||||
PARPORT_CONTROL_AUTOFD);
|
PARPORT_CONTROL_AUTOFD);
|
||||||
|
|
||||||
/* Event 9: nAck goes low. */
|
/* Event 9: nAck goes low. */
|
||||||
port->ieee1284.phase = IEEE1284_PH_REV_DATA;
|
port->ieee1284.phase = IEEE1284_PH_REV_DATA;
|
||||||
if (parport_wait_peripheral (port,
|
if (parport_wait_peripheral (port,
|
||||||
|
@ -282,7 +282,7 @@ static size_t cpia_read_nibble_stream(struct parport *port,
|
||||||
|
|
||||||
/* Read lower nibble */
|
/* Read lower nibble */
|
||||||
nibble[0] = parport_read_status (port) >>3;
|
nibble[0] = parport_read_status (port) >>3;
|
||||||
|
|
||||||
/* Event 10: Set nAutoFd high. */
|
/* Event 10: Set nAutoFd high. */
|
||||||
parport_frob_control (port, PARPORT_CONTROL_AUTOFD, 0);
|
parport_frob_control (port, PARPORT_CONTROL_AUTOFD, 0);
|
||||||
|
|
||||||
|
@ -295,10 +295,10 @@ static size_t cpia_read_nibble_stream(struct parport *port,
|
||||||
port->name);
|
port->name);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read upper nibble */
|
/* Read upper nibble */
|
||||||
nibble[1] = parport_read_status (port) >>3;
|
nibble[1] = parport_read_status (port) >>3;
|
||||||
|
|
||||||
/* reassemble the byte */
|
/* reassemble the byte */
|
||||||
for (j = 0; j < 2 ; j++ ) {
|
for (j = 0; j < 2 ; j++ ) {
|
||||||
nibble[j] &= ~8;
|
nibble[j] &= ~8;
|
||||||
|
@ -335,8 +335,8 @@ static void EndTransferMode(struct pp_cam_entry *cam)
|
||||||
static int ForwardSetup(struct pp_cam_entry *cam)
|
static int ForwardSetup(struct pp_cam_entry *cam)
|
||||||
{
|
{
|
||||||
int retry;
|
int retry;
|
||||||
|
|
||||||
/* The CPiA uses ECP protocol for Downloads from the Host to the camera.
|
/* The CPiA uses ECP protocol for Downloads from the Host to the camera.
|
||||||
* This will be software-emulated if ECP hardware is not present
|
* This will be software-emulated if ECP hardware is not present
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -375,9 +375,9 @@ static int ReverseSetup(struct pp_cam_entry *cam, int extensibility)
|
||||||
upload_mode = mode;
|
upload_mode = mode;
|
||||||
if(extensibility) mode = UPLOAD_FLAG|transfer_mode|IEEE1284_EXT_LINK;
|
if(extensibility) mode = UPLOAD_FLAG|transfer_mode|IEEE1284_EXT_LINK;
|
||||||
|
|
||||||
/* the usual camera maximum response time is 10ms, but after
|
/* the usual camera maximum response time is 10ms, but after
|
||||||
* receiving some commands, it needs up to 40ms. */
|
* receiving some commands, it needs up to 40ms. */
|
||||||
|
|
||||||
for(retry = 0; retry < 4; ++retry) {
|
for(retry = 0; retry < 4; ++retry) {
|
||||||
if(!parport_negotiate(cam->port, mode)) {
|
if(!parport_negotiate(cam->port, mode)) {
|
||||||
break;
|
break;
|
||||||
|
@ -439,10 +439,10 @@ static int ReadPacket(struct pp_cam_entry *cam, u8 *packet, size_t size)
|
||||||
|
|
||||||
/* support for CPiA variant nibble reads */
|
/* support for CPiA variant nibble reads */
|
||||||
if(cam->port->ieee1284.mode == IEEE1284_MODE_NIBBLE) {
|
if(cam->port->ieee1284.mode == IEEE1284_MODE_NIBBLE) {
|
||||||
if(cpia_read_nibble(cam->port, packet, size, 0) != size)
|
if(cpia_read_nibble(cam->port, packet, size, 0) != size)
|
||||||
retval = -EIO;
|
retval = -EIO;
|
||||||
} else {
|
} else {
|
||||||
if(parport_read(cam->port, packet, size) != size)
|
if(parport_read(cam->port, packet, size) != size)
|
||||||
retval = -EIO;
|
retval = -EIO;
|
||||||
}
|
}
|
||||||
EndTransferMode(cam);
|
EndTransferMode(cam);
|
||||||
|
@ -542,18 +542,18 @@ static int cpia_pp_streamRead(void *privdata, u8 *buffer, int noblock)
|
||||||
block_size = PARPORT_CHUNK_SIZE;
|
block_size = PARPORT_CHUNK_SIZE;
|
||||||
while( !cam->image_complete ) {
|
while( !cam->image_complete ) {
|
||||||
cond_resched();
|
cond_resched();
|
||||||
|
|
||||||
new_bytes = cpia_pp_read(cam->port, buffer, block_size );
|
new_bytes = cpia_pp_read(cam->port, buffer, block_size );
|
||||||
if( new_bytes <= 0 ) {
|
if( new_bytes <= 0 ) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
i=-1;
|
i=-1;
|
||||||
while(++i<new_bytes && endseen<4) {
|
while(++i<new_bytes && endseen<4) {
|
||||||
if(*buffer==EOI) {
|
if(*buffer==EOI) {
|
||||||
endseen++;
|
endseen++;
|
||||||
} else {
|
} else {
|
||||||
endseen=0;
|
endseen=0;
|
||||||
}
|
}
|
||||||
buffer++;
|
buffer++;
|
||||||
}
|
}
|
||||||
read_bytes += i;
|
read_bytes += i;
|
||||||
|
@ -601,7 +601,7 @@ static int cpia_pp_transferCmd(void *privdata, u8 *command, u8 *data)
|
||||||
}
|
}
|
||||||
if((err = ReadPacket(cam, buffer, 8)) < 0) {
|
if((err = ReadPacket(cam, buffer, 8)) < 0) {
|
||||||
DBG("Error reading command result\n");
|
DBG("Error reading command result\n");
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
memcpy(data, buffer, databytes);
|
memcpy(data, buffer, databytes);
|
||||||
} else if(command[0] == DATA_OUT) {
|
} else if(command[0] == DATA_OUT) {
|
||||||
|
@ -631,10 +631,10 @@ static int cpia_pp_transferCmd(void *privdata, u8 *command, u8 *data)
|
||||||
static int cpia_pp_open(void *privdata)
|
static int cpia_pp_open(void *privdata)
|
||||||
{
|
{
|
||||||
struct pp_cam_entry *cam = (struct pp_cam_entry *)privdata;
|
struct pp_cam_entry *cam = (struct pp_cam_entry *)privdata;
|
||||||
|
|
||||||
if (cam == NULL)
|
if (cam == NULL)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if(cam->open_count == 0) {
|
if(cam->open_count == 0) {
|
||||||
if (parport_claim(cam->pdev)) {
|
if (parport_claim(cam->pdev)) {
|
||||||
DBG("failed to claim the port\n");
|
DBG("failed to claim the port\n");
|
||||||
|
@ -645,12 +645,12 @@ static int cpia_pp_open(void *privdata)
|
||||||
parport_write_control(cam->port, PARPORT_CONTROL_SELECT);
|
parport_write_control(cam->port, PARPORT_CONTROL_SELECT);
|
||||||
udelay(50);
|
udelay(50);
|
||||||
parport_write_control(cam->port,
|
parport_write_control(cam->port,
|
||||||
PARPORT_CONTROL_SELECT
|
PARPORT_CONTROL_SELECT
|
||||||
| PARPORT_CONTROL_INIT);
|
| PARPORT_CONTROL_INIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
++cam->open_count;
|
++cam->open_count;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -663,7 +663,7 @@ static int cpia_pp_registerCallback(void *privdata, void (*cb)(void *cbdata), vo
|
||||||
{
|
{
|
||||||
struct pp_cam_entry *cam = privdata;
|
struct pp_cam_entry *cam = privdata;
|
||||||
int retval = 0;
|
int retval = 0;
|
||||||
|
|
||||||
if(cam->port->irq != PARPORT_IRQ_NONE) {
|
if(cam->port->irq != PARPORT_IRQ_NONE) {
|
||||||
INIT_WORK(&cam->cb_task, cb, cbdata);
|
INIT_WORK(&cam->cb_task, cb, cbdata);
|
||||||
} else {
|
} else {
|
||||||
|
@ -707,9 +707,9 @@ static int cpia_pp_register(struct parport *port)
|
||||||
LOG("failed to allocate camera structure\n");
|
LOG("failed to allocate camera structure\n");
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
pdev = parport_register_device(port, "cpia_pp", NULL, NULL,
|
pdev = parport_register_device(port, "cpia_pp", NULL, NULL,
|
||||||
NULL, 0, cam);
|
NULL, 0, cam);
|
||||||
|
|
||||||
if (!pdev) {
|
if (!pdev) {
|
||||||
LOG("failed to parport_register_device\n");
|
LOG("failed to parport_register_device\n");
|
||||||
|
@ -753,19 +753,19 @@ static void cpia_pp_detach (struct parport *port)
|
||||||
}
|
}
|
||||||
cpia = NULL;
|
cpia = NULL;
|
||||||
}
|
}
|
||||||
spin_unlock( &cam_list_lock_pp );
|
spin_unlock( &cam_list_lock_pp );
|
||||||
|
|
||||||
if (!cpia) {
|
if (!cpia) {
|
||||||
DBG("cpia_pp_detach failed to find cam_data in cam_list\n");
|
DBG("cpia_pp_detach failed to find cam_data in cam_list\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
cam = (struct pp_cam_entry *) cpia->lowlevel_data;
|
cam = (struct pp_cam_entry *) cpia->lowlevel_data;
|
||||||
cpia_unregister_camera(cpia);
|
cpia_unregister_camera(cpia);
|
||||||
if(cam->open_count > 0)
|
if(cam->open_count > 0)
|
||||||
cpia_pp_close(cam);
|
cpia_pp_close(cam);
|
||||||
parport_unregister_device(cam->pdev);
|
parport_unregister_device(cam->pdev);
|
||||||
cpia->lowlevel_data = NULL;
|
cpia->lowlevel_data = NULL;
|
||||||
kfree(cam);
|
kfree(cam);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -805,14 +805,14 @@ static struct parport_driver cpia_pp_driver = {
|
||||||
|
|
||||||
int cpia_pp_init(void)
|
int cpia_pp_init(void)
|
||||||
{
|
{
|
||||||
printk(KERN_INFO "%s v%d.%d.%d\n",ABOUT,
|
printk(KERN_INFO "%s v%d.%d.%d\n",ABOUT,
|
||||||
CPIA_PP_MAJ_VER,CPIA_PP_MIN_VER,CPIA_PP_PATCH_VER);
|
CPIA_PP_MAJ_VER,CPIA_PP_MIN_VER,CPIA_PP_PATCH_VER);
|
||||||
|
|
||||||
if(parport_nr[0] == PPCPIA_PARPORT_OFF) {
|
if(parport_nr[0] == PPCPIA_PARPORT_OFF) {
|
||||||
printk(" disabled\n");
|
printk(" disabled\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
spin_lock_init( &cam_list_lock_pp );
|
spin_lock_init( &cam_list_lock_pp );
|
||||||
|
|
||||||
if (parport_register_driver (&cpia_pp_driver)) {
|
if (parport_register_driver (&cpia_pp_driver)) {
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* define _CPIA_DEBUG_ for verbose debug output (see cpia.h) */
|
/* define _CPIA_DEBUG_ for verbose debug output (see cpia.h) */
|
||||||
/* #define _CPIA_DEBUG_ 1 */
|
/* #define _CPIA_DEBUG_ 1 */
|
||||||
|
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
|
@ -85,7 +85,7 @@ struct usb_cpia {
|
||||||
|
|
||||||
static int cpia_usb_open(void *privdata);
|
static int cpia_usb_open(void *privdata);
|
||||||
static int cpia_usb_registerCallback(void *privdata, void (*cb) (void *cbdata),
|
static int cpia_usb_registerCallback(void *privdata, void (*cb) (void *cbdata),
|
||||||
void *cbdata);
|
void *cbdata);
|
||||||
static int cpia_usb_transferCmd(void *privdata, u8 *command, u8 *data);
|
static int cpia_usb_transferCmd(void *privdata, u8 *command, u8 *data);
|
||||||
static int cpia_usb_streamStart(void *privdata);
|
static int cpia_usb_streamStart(void *privdata);
|
||||||
static int cpia_usb_streamStop(void *privdata);
|
static int cpia_usb_streamStop(void *privdata);
|
||||||
|
@ -127,7 +127,7 @@ static void cpia_usb_complete(struct urb *urb, struct pt_regs *regs)
|
||||||
ucpia->workbuff->status = FRAME_READING;
|
ucpia->workbuff->status = FRAME_READING;
|
||||||
ucpia->workbuff->length = 0;
|
ucpia->workbuff->length = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < urb->number_of_packets; i++) {
|
for (i = 0; i < urb->number_of_packets; i++) {
|
||||||
int n = urb->iso_frame_desc[i].actual_length;
|
int n = urb->iso_frame_desc[i].actual_length;
|
||||||
int st = urb->iso_frame_desc[i].status;
|
int st = urb->iso_frame_desc[i].status;
|
||||||
|
@ -141,9 +141,9 @@ static void cpia_usb_complete(struct urb *urb, struct pt_regs *regs)
|
||||||
printk(KERN_DEBUG "cpia: scratch buf overflow!scr_len: %d, n: %d\n", ucpia->workbuff->length, n);
|
printk(KERN_DEBUG "cpia: scratch buf overflow!scr_len: %d, n: %d\n", ucpia->workbuff->length, n);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (n) {
|
if (n) {
|
||||||
if ((ucpia->workbuff->length > 0) ||
|
if ((ucpia->workbuff->length > 0) ||
|
||||||
(0x19 == cdata[0] && 0x68 == cdata[1])) {
|
(0x19 == cdata[0] && 0x68 == cdata[1])) {
|
||||||
memcpy(ucpia->workbuff->data + ucpia->workbuff->length, cdata, n);
|
memcpy(ucpia->workbuff->data + ucpia->workbuff->length, cdata, n);
|
||||||
ucpia->workbuff->length += n;
|
ucpia->workbuff->length += n;
|
||||||
|
@ -160,7 +160,7 @@ static void cpia_usb_complete(struct urb *urb, struct pt_regs *regs)
|
||||||
ucpia->workbuff = ucpia->workbuff->next;
|
ucpia->workbuff = ucpia->workbuff->next;
|
||||||
ucpia->workbuff->status = FRAME_EMPTY;
|
ucpia->workbuff->status = FRAME_EMPTY;
|
||||||
ucpia->workbuff->length = 0;
|
ucpia->workbuff->length = 0;
|
||||||
|
|
||||||
if (waitqueue_active(&ucpia->wq_stream))
|
if (waitqueue_active(&ucpia->wq_stream))
|
||||||
wake_up_interruptible(&ucpia->wq_stream);
|
wake_up_interruptible(&ucpia->wq_stream);
|
||||||
}
|
}
|
||||||
|
@ -178,7 +178,7 @@ static int cpia_usb_open(void *privdata)
|
||||||
struct usb_cpia *ucpia = (struct usb_cpia *) privdata;
|
struct usb_cpia *ucpia = (struct usb_cpia *) privdata;
|
||||||
struct urb *urb;
|
struct urb *urb;
|
||||||
int ret, retval = 0, fx, err;
|
int ret, retval = 0, fx, err;
|
||||||
|
|
||||||
if (!ucpia)
|
if (!ucpia)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
@ -191,7 +191,7 @@ static int cpia_usb_open(void *privdata)
|
||||||
retval = -EINVAL;
|
retval = -EINVAL;
|
||||||
goto error_0;
|
goto error_0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = usb_set_interface(ucpia->dev, ucpia->iface, 3);
|
ret = usb_set_interface(ucpia->dev, ucpia->iface, 3);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
printk(KERN_ERR "cpia_usb_open: usb_set_interface error (ret = %d)\n", ret);
|
printk(KERN_ERR "cpia_usb_open: usb_set_interface error (ret = %d)\n", ret);
|
||||||
|
@ -286,7 +286,7 @@ static int cpia_usb_open(void *privdata)
|
||||||
error_0:
|
error_0:
|
||||||
kfree (ucpia->sbuf[0].data);
|
kfree (ucpia->sbuf[0].data);
|
||||||
ucpia->sbuf[0].data = NULL;
|
ucpia->sbuf[0].data = NULL;
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -307,7 +307,7 @@ static int WritePacket(struct usb_device *udev, const u8 *packet, u8 *buf, size_
|
||||||
return usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
|
return usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
|
||||||
packet[1] + (packet[0] << 8),
|
packet[1] + (packet[0] << 8),
|
||||||
USB_TYPE_VENDOR | USB_RECIP_DEVICE,
|
USB_TYPE_VENDOR | USB_RECIP_DEVICE,
|
||||||
packet[2] + (packet[3] << 8),
|
packet[2] + (packet[3] << 8),
|
||||||
packet[4] + (packet[5] << 8), buf, size, 1000);
|
packet[4] + (packet[5] << 8), buf, size, 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -324,7 +324,7 @@ static int ReadPacket(struct usb_device *udev, u8 *packet, u8 *buf, size_t size)
|
||||||
return usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
|
return usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
|
||||||
packet[1] + (packet[0] << 8),
|
packet[1] + (packet[0] << 8),
|
||||||
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
|
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
|
||||||
packet[2] + (packet[3] << 8),
|
packet[2] + (packet[3] << 8),
|
||||||
packet[4] + (packet[5] << 8), buf, size, 1000);
|
packet[4] + (packet[5] << 8), buf, size, 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -393,7 +393,7 @@ static int cpia_usb_streamRead(void *privdata, u8 *frame, int noblock)
|
||||||
|
|
||||||
if (!ucpia || !ucpia->present)
|
if (!ucpia || !ucpia->present)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (ucpia->curbuff->status != FRAME_READY)
|
if (ucpia->curbuff->status != FRAME_READY)
|
||||||
interruptible_sleep_on(&ucpia->wq_stream);
|
interruptible_sleep_on(&ucpia->wq_stream);
|
||||||
else
|
else
|
||||||
|
@ -403,7 +403,7 @@ static int cpia_usb_streamRead(void *privdata, u8 *frame, int noblock)
|
||||||
|
|
||||||
if (!mybuff)
|
if (!mybuff)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (mybuff->status != FRAME_READY || mybuff->length < 4) {
|
if (mybuff->status != FRAME_READY || mybuff->length < 4) {
|
||||||
DBG("Something went wrong!\n");
|
DBG("Something went wrong!\n");
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -411,7 +411,7 @@ static int cpia_usb_streamRead(void *privdata, u8 *frame, int noblock)
|
||||||
|
|
||||||
memcpy(frame, mybuff->data, mybuff->length);
|
memcpy(frame, mybuff->data, mybuff->length);
|
||||||
mybuff->status = FRAME_EMPTY;
|
mybuff->status = FRAME_EMPTY;
|
||||||
|
|
||||||
/* DBG("read done, %d bytes, Header: %x/%x, Footer: %x%x%x%x\n", */
|
/* DBG("read done, %d bytes, Header: %x/%x, Footer: %x%x%x%x\n", */
|
||||||
/* mybuff->length, frame[0], frame[1], */
|
/* mybuff->length, frame[0], frame[1], */
|
||||||
/* frame[mybuff->length-4], frame[mybuff->length-3], */
|
/* frame[mybuff->length-4], frame[mybuff->length-3], */
|
||||||
|
@ -447,7 +447,7 @@ static void cpia_usb_free_resources(struct usb_cpia *ucpia, int try)
|
||||||
|
|
||||||
kfree(ucpia->sbuf[1].data);
|
kfree(ucpia->sbuf[1].data);
|
||||||
ucpia->sbuf[1].data = NULL;
|
ucpia->sbuf[1].data = NULL;
|
||||||
|
|
||||||
if (ucpia->sbuf[0].urb) {
|
if (ucpia->sbuf[0].urb) {
|
||||||
usb_kill_urb(ucpia->sbuf[0].urb);
|
usb_kill_urb(ucpia->sbuf[0].urb);
|
||||||
usb_free_urb(ucpia->sbuf[0].urb);
|
usb_free_urb(ucpia->sbuf[0].urb);
|
||||||
|
@ -490,7 +490,7 @@ static int cpia_probe(struct usb_interface *intf,
|
||||||
struct usb_cpia *ucpia;
|
struct usb_cpia *ucpia;
|
||||||
struct cam_data *cam;
|
struct cam_data *cam;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* A multi-config CPiA camera? */
|
/* A multi-config CPiA camera? */
|
||||||
if (udev->descriptor.bNumConfigurations != 1)
|
if (udev->descriptor.bNumConfigurations != 1)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
@ -539,7 +539,7 @@ static int cpia_probe(struct usb_interface *intf,
|
||||||
|
|
||||||
/* Before register_camera, important */
|
/* Before register_camera, important */
|
||||||
ucpia->present = 1;
|
ucpia->present = 1;
|
||||||
|
|
||||||
cam = cpia_register_camera(&cpia_usb_ops, ucpia);
|
cam = cpia_register_camera(&cpia_usb_ops, ucpia);
|
||||||
if (!cam) {
|
if (!cam) {
|
||||||
LOG("failed to cpia_register_camera\n");
|
LOG("failed to cpia_register_camera\n");
|
||||||
|
@ -591,7 +591,7 @@ static void cpia_disconnect(struct usb_interface *intf)
|
||||||
struct cam_data *cam = usb_get_intfdata(intf);
|
struct cam_data *cam = usb_get_intfdata(intf);
|
||||||
struct usb_cpia *ucpia;
|
struct usb_cpia *ucpia;
|
||||||
struct usb_device *udev;
|
struct usb_device *udev;
|
||||||
|
|
||||||
usb_set_intfdata(intf, NULL);
|
usb_set_intfdata(intf, NULL);
|
||||||
if (!cam)
|
if (!cam)
|
||||||
return;
|
return;
|
||||||
|
@ -600,7 +600,7 @@ static void cpia_disconnect(struct usb_interface *intf)
|
||||||
spin_lock( &cam_list_lock_usb );
|
spin_lock( &cam_list_lock_usb );
|
||||||
list_del(&cam->cam_data_list);
|
list_del(&cam->cam_data_list);
|
||||||
spin_unlock( &cam_list_lock_usb );
|
spin_unlock( &cam_list_lock_usb );
|
||||||
|
|
||||||
ucpia->present = 0;
|
ucpia->present = 0;
|
||||||
|
|
||||||
cpia_unregister_camera(cam);
|
cpia_unregister_camera(cam);
|
||||||
|
@ -631,7 +631,7 @@ static void cpia_disconnect(struct usb_interface *intf)
|
||||||
|
|
||||||
static int __init usb_cpia_init(void)
|
static int __init usb_cpia_init(void)
|
||||||
{
|
{
|
||||||
printk(KERN_INFO "%s v%d.%d.%d\n",ABOUT,
|
printk(KERN_INFO "%s v%d.%d.%d\n",ABOUT,
|
||||||
CPIA_USB_MAJ_VER,CPIA_USB_MIN_VER,CPIA_USB_PATCH_VER);
|
CPIA_USB_MAJ_VER,CPIA_USB_MIN_VER,CPIA_USB_PATCH_VER);
|
||||||
|
|
||||||
spin_lock_init(&cam_list_lock_usb);
|
spin_lock_init(&cam_list_lock_usb);
|
||||||
|
|
|
@ -59,25 +59,25 @@ static int cs53l32a_read(struct i2c_client *client, u8 reg)
|
||||||
static int cs53l32a_command(struct i2c_client *client, unsigned int cmd,
|
static int cs53l32a_command(struct i2c_client *client, unsigned int cmd,
|
||||||
void *arg)
|
void *arg)
|
||||||
{
|
{
|
||||||
struct v4l2_audio *input = arg;
|
struct v4l2_routing *route = arg;
|
||||||
struct v4l2_control *ctrl = arg;
|
struct v4l2_control *ctrl = arg;
|
||||||
|
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case VIDIOC_S_AUDIO:
|
case VIDIOC_INT_G_AUDIO_ROUTING:
|
||||||
|
route->input = (cs53l32a_read(client, 0x01) >> 4) & 3;
|
||||||
|
route->output = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case VIDIOC_INT_S_AUDIO_ROUTING:
|
||||||
/* There are 2 physical inputs, but the second input can be
|
/* There are 2 physical inputs, but the second input can be
|
||||||
placed in two modes, the first mode bypasses the PGA (gain),
|
placed in two modes, the first mode bypasses the PGA (gain),
|
||||||
the second goes through the PGA. Hence there are three
|
the second goes through the PGA. Hence there are three
|
||||||
possible inputs to choose from. */
|
possible inputs to choose from. */
|
||||||
if (input->index > 2) {
|
if (route->input > 2) {
|
||||||
v4l_err(client, "Invalid input %d.\n", input->index);
|
v4l_err(client, "Invalid input %d.\n", route->input);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
cs53l32a_write(client, 0x01, 0x01 + (input->index << 4));
|
cs53l32a_write(client, 0x01, 0x01 + (route->input << 4));
|
||||||
break;
|
|
||||||
|
|
||||||
case VIDIOC_G_AUDIO:
|
|
||||||
memset(input, 0, sizeof(*input));
|
|
||||||
input->index = (cs53l32a_read(client, 0x01) >> 4) & 3;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VIDIOC_G_CTRL:
|
case VIDIOC_G_CTRL:
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
#define __CS8420_H__
|
#define __CS8420_H__
|
||||||
|
|
||||||
/* Initialization Sequence */
|
/* Initialization Sequence */
|
||||||
|
|
||||||
static __u8 init8420[] = {
|
static __u8 init8420[] = {
|
||||||
1, 0x01, 2, 0x02, 3, 0x00, 4, 0x46,
|
1, 0x01, 2, 0x02, 3, 0x00, 4, 0x46,
|
||||||
5, 0x24, 6, 0x84, 18, 0x18, 19, 0x13,
|
5, 0x24, 6, 0x84, 18, 0x18, 19, 0x13,
|
||||||
|
|
|
@ -18,7 +18,6 @@
|
||||||
|
|
||||||
#include <linux/videodev2.h>
|
#include <linux/videodev2.h>
|
||||||
#include <linux/i2c.h>
|
#include <linux/i2c.h>
|
||||||
#include <media/audiochip.h>
|
|
||||||
#include <media/v4l2-common.h>
|
#include <media/v4l2-common.h>
|
||||||
|
|
||||||
#include "cx25840.h"
|
#include "cx25840.h"
|
||||||
|
|
|
@ -31,7 +31,6 @@
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/videodev2.h>
|
#include <linux/videodev2.h>
|
||||||
#include <linux/i2c.h>
|
#include <linux/i2c.h>
|
||||||
#include <media/audiochip.h>
|
|
||||||
#include <media/v4l2-common.h>
|
#include <media/v4l2-common.h>
|
||||||
|
|
||||||
#include "cx25840.h"
|
#include "cx25840.h"
|
||||||
|
@ -176,9 +175,9 @@ static void cx25840_initialize(struct i2c_client *client, int loadfw)
|
||||||
cx25840_write(client, 0x4a5, 0x00);
|
cx25840_write(client, 0x4a5, 0x00);
|
||||||
cx25840_write(client, 0x402, 0x00);
|
cx25840_write(client, 0x402, 0x00);
|
||||||
/* 8. */
|
/* 8. */
|
||||||
cx25840_write(client, 0x401, 0x18);
|
cx25840_and_or(client, 0x401, ~0x18, 0);
|
||||||
cx25840_write(client, 0x4a2, 0x10);
|
cx25840_and_or(client, 0x4a2, ~0x10, 0x10);
|
||||||
cx25840_write(client, 0x402, 0x04);
|
/* steps 8c and 8d are done in change_input() */
|
||||||
/* 10. */
|
/* 10. */
|
||||||
cx25840_write(client, 0x8d3, 0x1f);
|
cx25840_write(client, 0x8d3, 0x1f);
|
||||||
cx25840_write(client, 0x8e3, 0x03);
|
cx25840_write(client, 0x8e3, 0x03);
|
||||||
|
@ -209,6 +208,17 @@ static void input_change(struct i2c_client *client)
|
||||||
struct cx25840_state *state = i2c_get_clientdata(client);
|
struct cx25840_state *state = i2c_get_clientdata(client);
|
||||||
v4l2_std_id std = cx25840_get_v4lstd(client);
|
v4l2_std_id std = cx25840_get_v4lstd(client);
|
||||||
|
|
||||||
|
/* Follow step 8c and 8d of section 3.16 in the cx25840 datasheet */
|
||||||
|
if (std & V4L2_STD_SECAM) {
|
||||||
|
cx25840_write(client, 0x402, 0);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
cx25840_write(client, 0x402, 0x04);
|
||||||
|
cx25840_write(client, 0x49f, (std & V4L2_STD_NTSC) ? 0x14 : 0x11);
|
||||||
|
}
|
||||||
|
cx25840_and_or(client, 0x401, ~0x60, 0);
|
||||||
|
cx25840_and_or(client, 0x401, ~0x60, 0x60);
|
||||||
|
|
||||||
/* Note: perhaps V4L2_STD_PAL_M should be handled as V4L2_STD_NTSC
|
/* Note: perhaps V4L2_STD_PAL_M should be handled as V4L2_STD_NTSC
|
||||||
instead of V4L2_STD_PAL. Someone needs to test this. */
|
instead of V4L2_STD_PAL. Someone needs to test this. */
|
||||||
if (std & V4L2_STD_PAL) {
|
if (std & V4L2_STD_PAL) {
|
||||||
|
@ -343,6 +353,15 @@ static int set_v4lstd(struct i2c_client *client, v4l2_std_id std)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Follow step 9 of section 3.16 in the cx25840 datasheet.
|
||||||
|
Without this PAL may display a vertical ghosting effect.
|
||||||
|
This happens for example with the Yuan MPC622. */
|
||||||
|
if (fmt >= 4 && fmt < 8) {
|
||||||
|
/* Set format to NTSC-M */
|
||||||
|
cx25840_and_or(client, 0x400, ~0xf, 1);
|
||||||
|
/* Turn off LCOMB */
|
||||||
|
cx25840_and_or(client, 0x47b, ~6, 0);
|
||||||
|
}
|
||||||
cx25840_and_or(client, 0x400, ~0xf, fmt);
|
cx25840_and_or(client, 0x400, ~0xf, fmt);
|
||||||
cx25840_vbi_setup(client);
|
cx25840_vbi_setup(client);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -359,7 +378,14 @@ v4l2_std_id cx25840_get_v4lstd(struct i2c_client * client)
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (fmt) {
|
switch (fmt) {
|
||||||
case 0x1: return V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_KR;
|
case 0x1:
|
||||||
|
{
|
||||||
|
/* if the audio std is A2-M, then this is the South Korean
|
||||||
|
NTSC standard */
|
||||||
|
if (cx25840_read(client, 0x805) == 2)
|
||||||
|
return V4L2_STD_NTSC_M_KR;
|
||||||
|
return V4L2_STD_NTSC_M;
|
||||||
|
}
|
||||||
case 0x2: return V4L2_STD_NTSC_M_JP;
|
case 0x2: return V4L2_STD_NTSC_M_JP;
|
||||||
case 0x3: return V4L2_STD_NTSC_443;
|
case 0x3: return V4L2_STD_NTSC_443;
|
||||||
case 0x4: return V4L2_STD_PAL;
|
case 0x4: return V4L2_STD_PAL;
|
||||||
|
@ -737,16 +763,6 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd,
|
||||||
return set_input(client, state->vid_input, input->index);
|
return set_input(client, state->vid_input, input->index);
|
||||||
}
|
}
|
||||||
|
|
||||||
case VIDIOC_G_AUDIO:
|
|
||||||
{
|
|
||||||
struct v4l2_audio *input = arg;
|
|
||||||
|
|
||||||
memset(input, 0, sizeof(*input));
|
|
||||||
input->index = state->aud_input;
|
|
||||||
input->capability = V4L2_AUDCAP_STEREO;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case VIDIOC_S_FREQUENCY:
|
case VIDIOC_S_FREQUENCY:
|
||||||
input_change(client);
|
input_change(client);
|
||||||
break;
|
break;
|
||||||
|
@ -794,13 +810,14 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd,
|
||||||
bilingual -> lang1 */
|
bilingual -> lang1 */
|
||||||
cx25840_and_or(client, 0x809, ~0xf, 0x00);
|
cx25840_and_or(client, 0x809, ~0xf, 0x00);
|
||||||
break;
|
break;
|
||||||
|
case V4L2_TUNER_MODE_STEREO:
|
||||||
case V4L2_TUNER_MODE_LANG1:
|
case V4L2_TUNER_MODE_LANG1:
|
||||||
/* mono -> mono
|
/* mono -> mono
|
||||||
stereo -> stereo
|
stereo -> stereo
|
||||||
bilingual -> lang1 */
|
bilingual -> lang1 */
|
||||||
cx25840_and_or(client, 0x809, ~0xf, 0x04);
|
cx25840_and_or(client, 0x809, ~0xf, 0x04);
|
||||||
break;
|
break;
|
||||||
case V4L2_TUNER_MODE_STEREO:
|
case V4L2_TUNER_MODE_LANG1_LANG2:
|
||||||
/* mono -> mono
|
/* mono -> mono
|
||||||
stereo -> stereo
|
stereo -> stereo
|
||||||
bilingual -> lang1/lang2 */
|
bilingual -> lang1/lang2 */
|
||||||
|
@ -808,7 +825,7 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd,
|
||||||
break;
|
break;
|
||||||
case V4L2_TUNER_MODE_LANG2:
|
case V4L2_TUNER_MODE_LANG2:
|
||||||
/* mono -> mono
|
/* mono -> mono
|
||||||
stereo ->stereo
|
stereo -> stereo
|
||||||
bilingual -> lang2 */
|
bilingual -> lang2 */
|
||||||
cx25840_and_or(client, 0x809, ~0xf, 0x01);
|
cx25840_and_or(client, 0x809, ~0xf, 0x01);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -16,12 +16,13 @@ config VIDEO_CX88
|
||||||
module will be called cx8800
|
module will be called cx8800
|
||||||
|
|
||||||
config VIDEO_CX88_ALSA
|
config VIDEO_CX88_ALSA
|
||||||
tristate "ALSA DMA audio support"
|
tristate "Conexant 2388x DMA audio support"
|
||||||
depends on VIDEO_CX88 && SND && EXPERIMENTAL
|
depends on VIDEO_CX88 && SND && EXPERIMENTAL
|
||||||
select SND_PCM
|
select SND_PCM
|
||||||
---help---
|
---help---
|
||||||
This is a video4linux driver for direct (DMA) audio on
|
This is a video4linux driver for direct (DMA) audio on
|
||||||
Conexant 2388x based TV cards.
|
Conexant 2388x based TV cards using ALSA.
|
||||||
|
|
||||||
It only works with boards with function 01 enabled.
|
It only works with boards with function 01 enabled.
|
||||||
To check if your board supports, use lspci -n.
|
To check if your board supports, use lspci -n.
|
||||||
If supported, you should see 1471:8801 or 1471:8811
|
If supported, you should see 1471:8801 or 1471:8811
|
||||||
|
|
|
@ -303,7 +303,7 @@ static int dsp_buffer_free(snd_cx88_card_t *chip)
|
||||||
BUG_ON(!chip->dma_size);
|
BUG_ON(!chip->dma_size);
|
||||||
|
|
||||||
dprintk(2,"Freeing buffer\n");
|
dprintk(2,"Freeing buffer\n");
|
||||||
videobuf_dma_pci_unmap(chip->pci, &chip->dma_risc);
|
videobuf_pci_dma_unmap(chip->pci, &chip->dma_risc);
|
||||||
videobuf_dma_free(&chip->dma_risc);
|
videobuf_dma_free(&chip->dma_risc);
|
||||||
btcx_riscmem_free(chip->pci,&chip->buf->risc);
|
btcx_riscmem_free(chip->pci,&chip->buf->risc);
|
||||||
kfree(chip->buf);
|
kfree(chip->buf);
|
||||||
|
@ -429,7 +429,7 @@ static int snd_cx88_hw_params(struct snd_pcm_substream * substream,
|
||||||
videobuf_dma_init_kernel(&buf->vb.dma,PCI_DMA_FROMDEVICE,
|
videobuf_dma_init_kernel(&buf->vb.dma,PCI_DMA_FROMDEVICE,
|
||||||
(PAGE_ALIGN(buf->vb.size) >> PAGE_SHIFT));
|
(PAGE_ALIGN(buf->vb.size) >> PAGE_SHIFT));
|
||||||
|
|
||||||
videobuf_dma_pci_map(chip->pci,&buf->vb.dma);
|
videobuf_pci_dma_map(chip->pci,&buf->vb.dma);
|
||||||
|
|
||||||
|
|
||||||
cx88_risc_databuffer(chip->pci, &buf->risc,
|
cx88_risc_databuffer(chip->pci, &buf->risc,
|
||||||
|
|
|
@ -1341,7 +1341,7 @@ bb_buf_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
|
||||||
enum v4l2_field field)
|
enum v4l2_field field)
|
||||||
{
|
{
|
||||||
struct cx8802_fh *fh = q->priv_data;
|
struct cx8802_fh *fh = q->priv_data;
|
||||||
return cx8802_buf_prepare(fh->dev, (struct cx88_buffer*)vb, field);
|
return cx8802_buf_prepare(q, fh->dev, (struct cx88_buffer*)vb, field);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -1354,8 +1354,7 @@ bb_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
|
||||||
static void
|
static void
|
||||||
bb_buf_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
|
bb_buf_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
|
||||||
{
|
{
|
||||||
struct cx8802_fh *fh = q->priv_data;
|
cx88_free_buffer(q, (struct cx88_buffer*)vb);
|
||||||
cx88_free_buffer(fh->dev->pci, (struct cx88_buffer*)vb);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct videobuf_queue_ops blackbird_qops = {
|
static struct videobuf_queue_ops blackbird_qops = {
|
||||||
|
|
|
@ -213,13 +213,13 @@ int cx88_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc,
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
cx88_free_buffer(struct pci_dev *pci, struct cx88_buffer *buf)
|
cx88_free_buffer(struct videobuf_queue *q, struct cx88_buffer *buf)
|
||||||
{
|
{
|
||||||
BUG_ON(in_interrupt());
|
BUG_ON(in_interrupt());
|
||||||
videobuf_waiton(&buf->vb,0,0);
|
videobuf_waiton(&buf->vb,0,0);
|
||||||
videobuf_dma_pci_unmap(pci, &buf->vb.dma);
|
videobuf_dma_unmap(q, &buf->vb.dma);
|
||||||
videobuf_dma_free(&buf->vb.dma);
|
videobuf_dma_free(&buf->vb.dma);
|
||||||
btcx_riscmem_free(pci, &buf->risc);
|
btcx_riscmem_free((struct pci_dev *)q->dev, &buf->risc);
|
||||||
buf->vb.state = STATE_NEEDS_INIT;
|
buf->vb.state = STATE_NEEDS_INIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -90,7 +90,7 @@ static int dvb_buf_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
|
||||||
enum v4l2_field field)
|
enum v4l2_field field)
|
||||||
{
|
{
|
||||||
struct cx8802_dev *dev = q->priv_data;
|
struct cx8802_dev *dev = q->priv_data;
|
||||||
return cx8802_buf_prepare(dev, (struct cx88_buffer*)vb,field);
|
return cx8802_buf_prepare(q, dev, (struct cx88_buffer*)vb,field);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dvb_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
|
static void dvb_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
|
||||||
|
@ -101,8 +101,7 @@ static void dvb_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
|
||||||
|
|
||||||
static void dvb_buf_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
|
static void dvb_buf_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
|
||||||
{
|
{
|
||||||
struct cx8802_dev *dev = q->priv_data;
|
cx88_free_buffer(q, (struct cx88_buffer*)vb);
|
||||||
cx88_free_buffer(dev->pci, (struct cx88_buffer*)vb);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct videobuf_queue_ops dvb_qops = {
|
static struct videobuf_queue_ops dvb_qops = {
|
||||||
|
|
|
@ -163,8 +163,8 @@ static int cx8802_restart_queue(struct cx8802_dev *dev,
|
||||||
|
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
|
|
||||||
int cx8802_buf_prepare(struct cx8802_dev *dev, struct cx88_buffer *buf,
|
int cx8802_buf_prepare(struct videobuf_queue *q, struct cx8802_dev *dev,
|
||||||
enum v4l2_field field)
|
struct cx88_buffer *buf, enum v4l2_field field)
|
||||||
{
|
{
|
||||||
int size = dev->ts_packet_size * dev->ts_packet_count;
|
int size = dev->ts_packet_size * dev->ts_packet_count;
|
||||||
int rc;
|
int rc;
|
||||||
|
@ -179,7 +179,7 @@ int cx8802_buf_prepare(struct cx8802_dev *dev, struct cx88_buffer *buf,
|
||||||
buf->vb.size = size;
|
buf->vb.size = size;
|
||||||
buf->vb.field = field /*V4L2_FIELD_TOP*/;
|
buf->vb.field = field /*V4L2_FIELD_TOP*/;
|
||||||
|
|
||||||
if (0 != (rc = videobuf_iolock(dev->pci,&buf->vb,NULL)))
|
if (0 != (rc = videobuf_iolock(q,&buf->vb,NULL)))
|
||||||
goto fail;
|
goto fail;
|
||||||
cx88_risc_databuffer(dev->pci, &buf->risc,
|
cx88_risc_databuffer(dev->pci, &buf->risc,
|
||||||
buf->vb.dma.sglist,
|
buf->vb.dma.sglist,
|
||||||
|
@ -189,36 +189,36 @@ int cx8802_buf_prepare(struct cx8802_dev *dev, struct cx88_buffer *buf,
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
cx88_free_buffer(dev->pci,buf);
|
cx88_free_buffer(q,buf);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cx8802_buf_queue(struct cx8802_dev *dev, struct cx88_buffer *buf)
|
void cx8802_buf_queue(struct cx8802_dev *dev, struct cx88_buffer *buf)
|
||||||
{
|
{
|
||||||
struct cx88_buffer *prev;
|
struct cx88_buffer *prev;
|
||||||
struct cx88_dmaqueue *q = &dev->mpegq;
|
struct cx88_dmaqueue *cx88q = &dev->mpegq;
|
||||||
|
|
||||||
dprintk( 1, "cx8802_buf_queue\n" );
|
dprintk( 1, "cx8802_buf_queue\n" );
|
||||||
/* add jump to stopper */
|
/* add jump to stopper */
|
||||||
buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
|
buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
|
||||||
buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
|
buf->risc.jmp[1] = cpu_to_le32(cx88q->stopper.dma);
|
||||||
|
|
||||||
if (list_empty(&q->active)) {
|
if (list_empty(&cx88q->active)) {
|
||||||
dprintk( 0, "queue is empty - first active\n" );
|
dprintk( 0, "queue is empty - first active\n" );
|
||||||
list_add_tail(&buf->vb.queue,&q->active);
|
list_add_tail(&buf->vb.queue,&cx88q->active);
|
||||||
cx8802_start_dma(dev, q, buf);
|
cx8802_start_dma(dev, cx88q, buf);
|
||||||
buf->vb.state = STATE_ACTIVE;
|
buf->vb.state = STATE_ACTIVE;
|
||||||
buf->count = q->count++;
|
buf->count = cx88q->count++;
|
||||||
mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
|
mod_timer(&cx88q->timeout, jiffies+BUFFER_TIMEOUT);
|
||||||
dprintk(0,"[%p/%d] %s - first active\n",
|
dprintk(0,"[%p/%d] %s - first active\n",
|
||||||
buf, buf->vb.i, __FUNCTION__);
|
buf, buf->vb.i, __FUNCTION__);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
dprintk( 1, "queue is not empty - append to active\n" );
|
dprintk( 1, "queue is not empty - append to active\n" );
|
||||||
prev = list_entry(q->active.prev, struct cx88_buffer, vb.queue);
|
prev = list_entry(cx88q->active.prev, struct cx88_buffer, vb.queue);
|
||||||
list_add_tail(&buf->vb.queue,&q->active);
|
list_add_tail(&buf->vb.queue,&cx88q->active);
|
||||||
buf->vb.state = STATE_ACTIVE;
|
buf->vb.state = STATE_ACTIVE;
|
||||||
buf->count = q->count++;
|
buf->count = cx88q->count++;
|
||||||
prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
|
prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
|
||||||
dprintk( 1, "[%p/%d] %s - append to active\n",
|
dprintk( 1, "[%p/%d] %s - append to active\n",
|
||||||
buf, buf->vb.i, __FUNCTION__);
|
buf, buf->vb.i, __FUNCTION__);
|
||||||
|
|
|
@ -885,6 +885,7 @@ void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual)
|
||||||
set_audio_standard_BTSC(core, 1, EN_BTSC_FORCE_SAP);
|
set_audio_standard_BTSC(core, 1, EN_BTSC_FORCE_SAP);
|
||||||
break;
|
break;
|
||||||
case V4L2_TUNER_MODE_STEREO:
|
case V4L2_TUNER_MODE_STEREO:
|
||||||
|
case V4L2_TUNER_MODE_LANG1_LANG2:
|
||||||
set_audio_standard_BTSC(core, 0, EN_BTSC_FORCE_STEREO);
|
set_audio_standard_BTSC(core, 0, EN_BTSC_FORCE_STEREO);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -905,6 +906,7 @@ void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual)
|
||||||
EN_NICAM_FORCE_MONO2);
|
EN_NICAM_FORCE_MONO2);
|
||||||
break;
|
break;
|
||||||
case V4L2_TUNER_MODE_STEREO:
|
case V4L2_TUNER_MODE_STEREO:
|
||||||
|
case V4L2_TUNER_MODE_LANG1_LANG2:
|
||||||
set_audio_standard_NICAM(core,
|
set_audio_standard_NICAM(core,
|
||||||
EN_NICAM_FORCE_STEREO);
|
EN_NICAM_FORCE_STEREO);
|
||||||
break;
|
break;
|
||||||
|
@ -926,6 +928,7 @@ void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual)
|
||||||
EN_A2_FORCE_MONO2);
|
EN_A2_FORCE_MONO2);
|
||||||
break;
|
break;
|
||||||
case V4L2_TUNER_MODE_STEREO:
|
case V4L2_TUNER_MODE_STEREO:
|
||||||
|
case V4L2_TUNER_MODE_LANG1_LANG2:
|
||||||
set_audio_standard_A2(core,
|
set_audio_standard_A2(core,
|
||||||
EN_A2_FORCE_STEREO);
|
EN_A2_FORCE_STEREO);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -175,7 +175,7 @@ vbi_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
|
||||||
buf->vb.size = size;
|
buf->vb.size = size;
|
||||||
buf->vb.field = V4L2_FIELD_SEQ_TB;
|
buf->vb.field = V4L2_FIELD_SEQ_TB;
|
||||||
|
|
||||||
if (0 != (rc = videobuf_iolock(dev->pci,&buf->vb,NULL)))
|
if (0 != (rc = videobuf_iolock(q,&buf->vb,NULL)))
|
||||||
goto fail;
|
goto fail;
|
||||||
cx88_risc_buffer(dev->pci, &buf->risc,
|
cx88_risc_buffer(dev->pci, &buf->risc,
|
||||||
buf->vb.dma.sglist,
|
buf->vb.dma.sglist,
|
||||||
|
@ -187,7 +187,7 @@ vbi_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
cx88_free_buffer(dev->pci,buf);
|
cx88_free_buffer(q,buf);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -227,9 +227,8 @@ vbi_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
|
||||||
static void vbi_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
|
static void vbi_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
|
||||||
{
|
{
|
||||||
struct cx88_buffer *buf = container_of(vb,struct cx88_buffer,vb);
|
struct cx88_buffer *buf = container_of(vb,struct cx88_buffer,vb);
|
||||||
struct cx8800_fh *fh = q->priv_data;
|
|
||||||
|
|
||||||
cx88_free_buffer(fh->dev->pci,buf);
|
cx88_free_buffer(q,buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct videobuf_queue_ops cx8800_vbi_qops = {
|
struct videobuf_queue_ops cx8800_vbi_qops = {
|
||||||
|
|
|
@ -564,7 +564,7 @@ buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
|
||||||
|
|
||||||
if (STATE_NEEDS_INIT == buf->vb.state) {
|
if (STATE_NEEDS_INIT == buf->vb.state) {
|
||||||
init_buffer = 1;
|
init_buffer = 1;
|
||||||
if (0 != (rc = videobuf_iolock(dev->pci,&buf->vb,NULL)))
|
if (0 != (rc = videobuf_iolock(q,&buf->vb,NULL)))
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -614,7 +614,7 @@ buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
cx88_free_buffer(dev->pci,buf);
|
cx88_free_buffer(q,buf);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -671,9 +671,8 @@ buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
|
||||||
static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
|
static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
|
||||||
{
|
{
|
||||||
struct cx88_buffer *buf = container_of(vb,struct cx88_buffer,vb);
|
struct cx88_buffer *buf = container_of(vb,struct cx88_buffer,vb);
|
||||||
struct cx8800_fh *fh = q->priv_data;
|
|
||||||
|
|
||||||
cx88_free_buffer(fh->dev->pci,buf);
|
cx88_free_buffer(q,buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct videobuf_queue_ops cx8800_video_qops = {
|
static struct videobuf_queue_ops cx8800_video_qops = {
|
||||||
|
@ -1251,9 +1250,17 @@ int cx88_do_ioctl(struct inode *inode, struct file *file, int radio,
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
dprintk(2, "CORE IOCTL: 0x%x\n", cmd );
|
if (video_debug) {
|
||||||
if (video_debug > 1)
|
if (video_debug > 1) {
|
||||||
v4l_print_ioctl(core->name,cmd);
|
if (_IOC_DIR(cmd) & _IOC_WRITE)
|
||||||
|
v4l_printk_ioctl_arg("cx88(w)",cmd, arg);
|
||||||
|
else if (!_IOC_DIR(cmd) & _IOC_READ) {
|
||||||
|
v4l_print_ioctl("cx88", cmd);
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
v4l_print_ioctl(core->name,cmd);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
/* ---------- tv norms ---------- */
|
/* ---------- tv norms ---------- */
|
||||||
|
@ -1460,7 +1467,19 @@ int cx88_do_ioctl(struct inode *inode, struct file *file, int radio,
|
||||||
static int video_ioctl(struct inode *inode, struct file *file,
|
static int video_ioctl(struct inode *inode, struct file *file,
|
||||||
unsigned int cmd, unsigned long arg)
|
unsigned int cmd, unsigned long arg)
|
||||||
{
|
{
|
||||||
return video_usercopy(inode, file, cmd, arg, video_do_ioctl);
|
int retval;
|
||||||
|
|
||||||
|
retval=video_usercopy(inode, file, cmd, arg, video_do_ioctl);
|
||||||
|
|
||||||
|
if (video_debug > 1) {
|
||||||
|
if (retval < 0) {
|
||||||
|
v4l_print_ioctl("cx88(err)", cmd);
|
||||||
|
printk(KERN_DEBUG "cx88(err): errcode=%d\n",retval);
|
||||||
|
} else if (_IOC_DIR(cmd) & _IOC_READ)
|
||||||
|
v4l_printk_ioctl_arg("cx88(r)",cmd, (void *)arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------- */
|
/* ----------------------------------------------------------- */
|
||||||
|
|
|
@ -27,7 +27,6 @@
|
||||||
|
|
||||||
#include <media/tuner.h>
|
#include <media/tuner.h>
|
||||||
#include <media/tveeprom.h>
|
#include <media/tveeprom.h>
|
||||||
#include <media/audiochip.h>
|
|
||||||
#include <media/video-buf.h>
|
#include <media/video-buf.h>
|
||||||
#include <media/video-buf-dvb.h>
|
#include <media/video-buf-dvb.h>
|
||||||
|
|
||||||
|
@ -485,7 +484,7 @@ extern int
|
||||||
cx88_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc,
|
cx88_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc,
|
||||||
u32 reg, u32 mask, u32 value);
|
u32 reg, u32 mask, u32 value);
|
||||||
extern void
|
extern void
|
||||||
cx88_free_buffer(struct pci_dev *pci, struct cx88_buffer *buf);
|
cx88_free_buffer(struct videobuf_queue *q, struct cx88_buffer *buf);
|
||||||
|
|
||||||
extern void cx88_risc_disasm(struct cx88_core *core,
|
extern void cx88_risc_disasm(struct cx88_core *core,
|
||||||
struct btcx_riscmem *risc);
|
struct btcx_riscmem *risc);
|
||||||
|
@ -577,8 +576,8 @@ void cx88_ir_irq(struct cx88_core *core);
|
||||||
/* ----------------------------------------------------------- */
|
/* ----------------------------------------------------------- */
|
||||||
/* cx88-mpeg.c */
|
/* cx88-mpeg.c */
|
||||||
|
|
||||||
int cx8802_buf_prepare(struct cx8802_dev *dev, struct cx88_buffer *buf,
|
int cx8802_buf_prepare(struct videobuf_queue *q,struct cx8802_dev *dev,
|
||||||
enum v4l2_field field);
|
struct cx88_buffer *buf, enum v4l2_field field);
|
||||||
void cx8802_buf_queue(struct cx8802_dev *dev, struct cx88_buffer *buf);
|
void cx8802_buf_queue(struct cx8802_dev *dev, struct cx88_buffer *buf);
|
||||||
void cx8802_cancel_buffers(struct cx8802_dev *dev);
|
void cx8802_cancel_buffers(struct cx8802_dev *dev);
|
||||||
|
|
||||||
|
|
|
@ -86,7 +86,7 @@ static int dabusb_add_buf_tail (pdabusb_t s, struct list_head *dst, struct list_
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
/*-------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------*/
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
static void dump_urb (struct urb *urb)
|
static void dump_urb (struct urb *urb)
|
||||||
{
|
{
|
||||||
dbg("urb :%p", urb);
|
dbg("urb :%p", urb);
|
||||||
|
@ -136,7 +136,7 @@ static int dabusb_free_queue (struct list_head *q)
|
||||||
for (p = q->next; p != q;) {
|
for (p = q->next; p != q;) {
|
||||||
b = list_entry (p, buff_t, buff_list);
|
b = list_entry (p, buff_t, buff_list);
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
dump_urb(b->purb);
|
dump_urb(b->purb);
|
||||||
#endif
|
#endif
|
||||||
kfree(b->purb->transfer_buffer);
|
kfree(b->purb->transfer_buffer);
|
||||||
|
@ -287,7 +287,7 @@ static int dabusb_bulk (pdabusb_t s, pbulk_transfer_t pb)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( ret == -EPIPE ) {
|
if( ret == -EPIPE ) {
|
||||||
warn("CLEAR_FEATURE request to remove STALL condition.");
|
warn("CLEAR_FEATURE request to remove STALL condition.");
|
||||||
if(usb_clear_halt(s->usbdev, usb_pipeendpoint(pipe)))
|
if(usb_clear_halt(s->usbdev, usb_pipeendpoint(pipe)))
|
||||||
|
@ -328,7 +328,7 @@ static int dabusb_loadmem (pdabusb_t s, const char *fname)
|
||||||
PINTEL_HEX_RECORD ptr = firmware;
|
PINTEL_HEX_RECORD ptr = firmware;
|
||||||
|
|
||||||
dbg("Enter dabusb_loadmem (internal)");
|
dbg("Enter dabusb_loadmem (internal)");
|
||||||
|
|
||||||
ret = dabusb_8051_reset (s, 1);
|
ret = dabusb_8051_reset (s, 1);
|
||||||
while (ptr->Type == 0) {
|
while (ptr->Type == 0) {
|
||||||
|
|
||||||
|
@ -449,7 +449,7 @@ static int dabusb_startrek (pdabusb_t s)
|
||||||
if (!list_empty (&s->free_buff_list)) {
|
if (!list_empty (&s->free_buff_list)) {
|
||||||
pbuff_t end;
|
pbuff_t end;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
while (!dabusb_add_buf_tail (s, &s->rec_buff_list, &s->free_buff_list)) {
|
while (!dabusb_add_buf_tail (s, &s->rec_buff_list, &s->free_buff_list)) {
|
||||||
|
|
||||||
dbg("submitting: end:%p s->rec_buff_list:%p", s->rec_buff_list.prev, &s->rec_buff_list);
|
dbg("submitting: end:%p s->rec_buff_list:%p", s->rec_buff_list.prev, &s->rec_buff_list);
|
||||||
|
@ -506,7 +506,7 @@ static ssize_t dabusb_read (struct file *file, char __user *buf, size_t count, l
|
||||||
err("error: rec_buf_list is empty");
|
err("error: rec_buf_list is empty");
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
b = list_entry (s->rec_buff_list.next, buff_t, buff_list);
|
b = list_entry (s->rec_buff_list.next, buff_t, buff_list);
|
||||||
purb = b->purb;
|
purb = b->purb;
|
||||||
|
|
||||||
|
@ -783,9 +783,9 @@ static void dabusb_disconnect (struct usb_interface *intf)
|
||||||
pdabusb_t s = usb_get_intfdata (intf);
|
pdabusb_t s = usb_get_intfdata (intf);
|
||||||
|
|
||||||
dbg("dabusb_disconnect");
|
dbg("dabusb_disconnect");
|
||||||
|
|
||||||
init_waitqueue_entry(&__wait, current);
|
init_waitqueue_entry(&__wait, current);
|
||||||
|
|
||||||
usb_set_intfdata (intf, NULL);
|
usb_set_intfdata (intf, NULL);
|
||||||
if (s) {
|
if (s) {
|
||||||
usb_deregister_dev (intf, &dabusb_class);
|
usb_deregister_dev (intf, &dabusb_class);
|
||||||
|
@ -797,7 +797,7 @@ static void dabusb_disconnect (struct usb_interface *intf)
|
||||||
schedule();
|
schedule();
|
||||||
current->state = TASK_RUNNING;
|
current->state = TASK_RUNNING;
|
||||||
remove_wait_queue(&s->remove_ok, &__wait);
|
remove_wait_queue(&s->remove_ok, &__wait);
|
||||||
|
|
||||||
s->usbdev = NULL;
|
s->usbdev = NULL;
|
||||||
s->overruns = 0;
|
s->overruns = 0;
|
||||||
}
|
}
|
|
@ -10,7 +10,7 @@ typedef struct
|
||||||
#define DABUSB_VERSION 0x1000
|
#define DABUSB_VERSION 0x1000
|
||||||
#define IOCTL_DAB_BULK _IOWR('d', 0x30, bulk_transfer_t)
|
#define IOCTL_DAB_BULK _IOWR('d', 0x30, bulk_transfer_t)
|
||||||
#define IOCTL_DAB_OVERRUNS _IOR('d', 0x15, int)
|
#define IOCTL_DAB_OVERRUNS _IOR('d', 0x15, int)
|
||||||
#define IOCTL_DAB_VERSION _IOR('d', 0x3f, int)
|
#define IOCTL_DAB_VERSION _IOR('d', 0x3f, int)
|
||||||
|
|
||||||
#ifdef __KERNEL__
|
#ifdef __KERNEL__
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ typedef struct
|
||||||
struct list_head rec_buff_list;
|
struct list_head rec_buff_list;
|
||||||
} dabusb_t,*pdabusb_t;
|
} dabusb_t,*pdabusb_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
pdabusb_t s;
|
pdabusb_t s;
|
||||||
struct urb *purb;
|
struct urb *purb;
|
|
@ -37,28 +37,28 @@
|
||||||
Markus: Updates for 2.6.x kernels, code layout changes, name sanitizing
|
Markus: Updates for 2.6.x kernels, code layout changes, name sanitizing
|
||||||
|
|
||||||
Version 0.30:
|
Version 0.30:
|
||||||
Markus: Updates for 2.5.x kernel and more ISO compliant source
|
Markus: Updates for 2.5.x kernel and more ISO compliant source
|
||||||
|
|
||||||
Version 0.25:
|
Version 0.25:
|
||||||
PSL and Markus: Cleanup, radio now doesn't stop on device close
|
PSL and Markus: Cleanup, radio now doesn't stop on device close
|
||||||
|
|
||||||
Version 0.24:
|
Version 0.24:
|
||||||
Markus: Hope I got these silly VIDEO_TUNER_LOW issues finally
|
Markus: Hope I got these silly VIDEO_TUNER_LOW issues finally
|
||||||
right. Some minor cleanup, improved standalone compilation
|
right. Some minor cleanup, improved standalone compilation
|
||||||
|
|
||||||
Version 0.23:
|
Version 0.23:
|
||||||
Markus: Sign extension bug fixed by declaring transfer_buffer unsigned
|
Markus: Sign extension bug fixed by declaring transfer_buffer unsigned
|
||||||
|
|
||||||
Version 0.22:
|
Version 0.22:
|
||||||
Markus: Some (brown bag) cleanup in what VIDIOCSTUNER returns,
|
Markus: Some (brown bag) cleanup in what VIDIOCSTUNER returns,
|
||||||
thanks to Mike Cox for pointing the problem out.
|
thanks to Mike Cox for pointing the problem out.
|
||||||
|
|
||||||
Version 0.21:
|
Version 0.21:
|
||||||
Markus: Minor cleanup, warnings if something goes wrong, lame attempt
|
Markus: Minor cleanup, warnings if something goes wrong, lame attempt
|
||||||
to adhere to Documentation/CodingStyle
|
to adhere to Documentation/CodingStyle
|
||||||
|
|
||||||
Version 0.2:
|
Version 0.2:
|
||||||
Brad Hards <bradh@dynamite.com.au>: Fixes to make it work as non-module
|
Brad Hards <bradh@dynamite.com.au>: Fixes to make it work as non-module
|
||||||
Markus: Copyright clarification
|
Markus: Copyright clarification
|
||||||
|
|
||||||
Version 0.01: Markus: initial release
|
Version 0.01: Markus: initial release
|
||||||
|
@ -163,11 +163,11 @@ static struct usb_driver usb_dsbr100_driver = {
|
||||||
static int dsbr100_start(dsbr100_device *radio)
|
static int dsbr100_start(dsbr100_device *radio)
|
||||||
{
|
{
|
||||||
if (usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0),
|
if (usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0),
|
||||||
USB_REQ_GET_STATUS,
|
USB_REQ_GET_STATUS,
|
||||||
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
|
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
|
||||||
0x00, 0xC7, radio->transfer_buffer, 8, 300)<0 ||
|
0x00, 0xC7, radio->transfer_buffer, 8, 300)<0 ||
|
||||||
usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0),
|
usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0),
|
||||||
DSB100_ONOFF,
|
DSB100_ONOFF,
|
||||||
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
|
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
|
||||||
0x01, 0x00, radio->transfer_buffer, 8, 300)<0)
|
0x01, 0x00, radio->transfer_buffer, 8, 300)<0)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -179,11 +179,11 @@ static int dsbr100_start(dsbr100_device *radio)
|
||||||
static int dsbr100_stop(dsbr100_device *radio)
|
static int dsbr100_stop(dsbr100_device *radio)
|
||||||
{
|
{
|
||||||
if (usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0),
|
if (usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0),
|
||||||
USB_REQ_GET_STATUS,
|
USB_REQ_GET_STATUS,
|
||||||
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
|
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
|
||||||
0x16, 0x1C, radio->transfer_buffer, 8, 300)<0 ||
|
0x16, 0x1C, radio->transfer_buffer, 8, 300)<0 ||
|
||||||
usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0),
|
usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0),
|
||||||
DSB100_ONOFF,
|
DSB100_ONOFF,
|
||||||
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
|
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
|
||||||
0x00, 0x00, radio->transfer_buffer, 8, 300)<0)
|
0x00, 0x00, radio->transfer_buffer, 8, 300)<0)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -195,16 +195,16 @@ static int dsbr100_setfreq(dsbr100_device *radio, int freq)
|
||||||
{
|
{
|
||||||
freq = (freq/16*80)/1000+856;
|
freq = (freq/16*80)/1000+856;
|
||||||
if (usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0),
|
if (usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0),
|
||||||
DSB100_TUNE,
|
DSB100_TUNE,
|
||||||
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
|
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
|
||||||
(freq>>8)&0x00ff, freq&0xff,
|
(freq>>8)&0x00ff, freq&0xff,
|
||||||
radio->transfer_buffer, 8, 300)<0 ||
|
radio->transfer_buffer, 8, 300)<0 ||
|
||||||
usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0),
|
usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0),
|
||||||
USB_REQ_GET_STATUS,
|
USB_REQ_GET_STATUS,
|
||||||
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
|
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
|
||||||
0x96, 0xB7, radio->transfer_buffer, 8, 300)<0 ||
|
0x96, 0xB7, radio->transfer_buffer, 8, 300)<0 ||
|
||||||
usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0),
|
usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0),
|
||||||
USB_REQ_GET_STATUS,
|
USB_REQ_GET_STATUS,
|
||||||
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
|
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
|
||||||
0x00, 0x24, radio->transfer_buffer, 8, 300)<0) {
|
0x00, 0x24, radio->transfer_buffer, 8, 300)<0) {
|
||||||
radio->stereo = -1;
|
radio->stereo = -1;
|
||||||
|
@ -219,7 +219,7 @@ sees a stereo signal or not. Pity. */
|
||||||
static void dsbr100_getstat(dsbr100_device *radio)
|
static void dsbr100_getstat(dsbr100_device *radio)
|
||||||
{
|
{
|
||||||
if (usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0),
|
if (usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0),
|
||||||
USB_REQ_GET_STATUS,
|
USB_REQ_GET_STATUS,
|
||||||
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
|
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
|
||||||
0x00 , 0x24, radio->transfer_buffer, 8, 300)<0)
|
0x00 , 0x24, radio->transfer_buffer, 8, 300)<0)
|
||||||
radio->stereo = -1;
|
radio->stereo = -1;
|
||||||
|
@ -232,7 +232,7 @@ static void dsbr100_getstat(dsbr100_device *radio)
|
||||||
|
|
||||||
/* check if the device is present and register with v4l and
|
/* check if the device is present and register with v4l and
|
||||||
usb if it is */
|
usb if it is */
|
||||||
static int usb_dsbr100_probe(struct usb_interface *intf,
|
static int usb_dsbr100_probe(struct usb_interface *intf,
|
||||||
const struct usb_device_id *id)
|
const struct usb_device_id *id)
|
||||||
{
|
{
|
||||||
dsbr100_device *radio;
|
dsbr100_device *radio;
|
||||||
|
@ -243,7 +243,7 @@ static int usb_dsbr100_probe(struct usb_interface *intf,
|
||||||
kfree(radio);
|
kfree(radio);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
memcpy(radio->videodev, &dsbr100_videodev_template,
|
memcpy(radio->videodev, &dsbr100_videodev_template,
|
||||||
sizeof(dsbr100_videodev_template));
|
sizeof(dsbr100_videodev_template));
|
||||||
radio->removed = 0;
|
radio->removed = 0;
|
||||||
radio->users = 0;
|
radio->users = 0;
|
||||||
|
@ -310,7 +310,7 @@ static int usb_dsbr100_do_ioctl(struct inode *inode, struct file *file,
|
||||||
struct video_tuner *v = arg;
|
struct video_tuner *v = arg;
|
||||||
|
|
||||||
dsbr100_getstat(radio);
|
dsbr100_getstat(radio);
|
||||||
if(v->tuner) /* Only 1 tuner */
|
if(v->tuner) /* Only 1 tuner */
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
v->rangelow = FREQ_MIN*FREQ_MUL;
|
v->rangelow = FREQ_MIN*FREQ_MUL;
|
||||||
v->rangehigh = FREQ_MAX*FREQ_MUL;
|
v->rangehigh = FREQ_MAX*FREQ_MUL;
|
||||||
|
@ -355,12 +355,12 @@ static int usb_dsbr100_do_ioctl(struct inode *inode, struct file *file,
|
||||||
v->volume = 1;
|
v->volume = 1;
|
||||||
v->step = 1;
|
v->step = 1;
|
||||||
strcpy(v->name, "Radio");
|
strcpy(v->name, "Radio");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
case VIDIOCSAUDIO: {
|
case VIDIOCSAUDIO: {
|
||||||
struct video_audio *v = arg;
|
struct video_audio *v = arg;
|
||||||
|
|
||||||
if (v->audio)
|
if (v->audio)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (v->flags&VIDEO_AUDIO_MUTE) {
|
if (v->flags&VIDEO_AUDIO_MUTE) {
|
||||||
if (dsbr100_stop(radio)==-1)
|
if (dsbr100_stop(radio)==-1)
|
|
@ -28,10 +28,10 @@
|
||||||
#include <linux/i2c.h>
|
#include <linux/i2c.h>
|
||||||
#include <linux/usb.h>
|
#include <linux/usb.h>
|
||||||
#include <media/tuner.h>
|
#include <media/tuner.h>
|
||||||
#include <media/audiochip.h>
|
#include <media/msp3400.h>
|
||||||
#include <media/tveeprom.h>
|
#include <media/tveeprom.h>
|
||||||
|
#include <media/audiochip.h>
|
||||||
#include <media/v4l2-common.h>
|
#include <media/v4l2-common.h>
|
||||||
#include "msp3400.h"
|
|
||||||
|
|
||||||
#include "em28xx.h"
|
#include "em28xx.h"
|
||||||
|
|
||||||
|
@ -147,11 +147,12 @@ struct em28xx_board em28xx_boards[] = {
|
||||||
.input = {{
|
.input = {{
|
||||||
.type = EM28XX_VMUX_TELEVISION,
|
.type = EM28XX_VMUX_TELEVISION,
|
||||||
.vmux = 0,
|
.vmux = 0,
|
||||||
.amux = 6,
|
.amux = MSP_INPUT_DEFAULT,
|
||||||
},{
|
},{
|
||||||
.type = EM28XX_VMUX_SVIDEO,
|
.type = EM28XX_VMUX_SVIDEO,
|
||||||
.vmux = 2,
|
.vmux = 2,
|
||||||
.amux = 1,
|
.amux = MSP_INPUT(MSP_IN_SCART_1, MSP_IN_TUNER_1,
|
||||||
|
MSP_DSP_OUT_SCART, MSP_DSP_OUT_SCART),
|
||||||
}},
|
}},
|
||||||
},
|
},
|
||||||
[EM2820_BOARD_MSI_VOX_USB_2] = {
|
[EM2820_BOARD_MSI_VOX_USB_2] = {
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
#include "em28xx.h"
|
#include "em28xx.h"
|
||||||
#include <media/tuner.h>
|
#include <media/tuner.h>
|
||||||
#include <media/v4l2-common.h>
|
#include <media/v4l2-common.h>
|
||||||
|
#include <media/msp3400.h>
|
||||||
|
|
||||||
#define DRIVER_AUTHOR "Ludovico Cavedon <cavedon@sssup.it>, " \
|
#define DRIVER_AUTHOR "Ludovico Cavedon <cavedon@sssup.it>, " \
|
||||||
"Markus Rechberger <mrechberger@gmail.com>, " \
|
"Markus Rechberger <mrechberger@gmail.com>, " \
|
||||||
|
@ -216,9 +217,14 @@ static void video_mux(struct em28xx *dev, int index)
|
||||||
em28xx_videodbg("Setting input index=%d, vmux=%d, amux=%d\n",index,input,dev->ctl_ainput);
|
em28xx_videodbg("Setting input index=%d, vmux=%d, amux=%d\n",index,input,dev->ctl_ainput);
|
||||||
|
|
||||||
if (dev->has_msp34xx) {
|
if (dev->has_msp34xx) {
|
||||||
|
struct v4l2_routing route;
|
||||||
|
|
||||||
if (dev->i2s_speed)
|
if (dev->i2s_speed)
|
||||||
em28xx_i2c_call_clients(dev, VIDIOC_INT_I2S_CLOCK_FREQ, &dev->i2s_speed);
|
em28xx_i2c_call_clients(dev, VIDIOC_INT_I2S_CLOCK_FREQ, &dev->i2s_speed);
|
||||||
em28xx_i2c_call_clients(dev, VIDIOC_S_AUDIO, &dev->ctl_ainput);
|
route.input = dev->ctl_ainput;
|
||||||
|
route.output = MSP_OUTPUT(MSP_OUT_SCART1_DA);
|
||||||
|
/* Note: this is msp3400 specific */
|
||||||
|
em28xx_i2c_call_clients(dev, VIDIOC_INT_S_AUDIO_ROUTING, &route);
|
||||||
ainput = EM28XX_AUDIO_SRC_TUNER;
|
ainput = EM28XX_AUDIO_SRC_TUNER;
|
||||||
em28xx_audio_source(dev, ainput);
|
em28xx_audio_source(dev, ainput);
|
||||||
} else {
|
} else {
|
||||||
|
|
4
drivers/media/video/et61x251/Makefile
Normal file
4
drivers/media/video/et61x251/Makefile
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
et61x251-objs := et61x251_core.o et61x251_tas5130d1b.o
|
||||||
|
|
||||||
|
obj-$(CONFIG_USB_ET61X251) += et61x251.o
|
||||||
|
|
|
@ -180,7 +180,7 @@ et61x251_match_id(struct et61x251_device* cam, const struct usb_device_id *id)
|
||||||
|
|
||||||
void
|
void
|
||||||
et61x251_attach_sensor(struct et61x251_device* cam,
|
et61x251_attach_sensor(struct et61x251_device* cam,
|
||||||
struct et61x251_sensor* sensor)
|
struct et61x251_sensor* sensor)
|
||||||
{
|
{
|
||||||
memcpy(&cam->sensor, sensor, sizeof(struct et61x251_sensor));
|
memcpy(&cam->sensor, sensor, sizeof(struct et61x251_sensor));
|
||||||
}
|
}
|
||||||
|
@ -199,7 +199,7 @@ do { \
|
||||||
dev_info(&cam->usbdev->dev, fmt "\n", ## args); \
|
dev_info(&cam->usbdev->dev, fmt "\n", ## args); \
|
||||||
else if ((level) >= 3) \
|
else if ((level) >= 3) \
|
||||||
dev_info(&cam->usbdev->dev, "[%s:%d] " fmt "\n", \
|
dev_info(&cam->usbdev->dev, "[%s:%d] " fmt "\n", \
|
||||||
__FUNCTION__, __LINE__ , ## args); \
|
__FUNCTION__, __LINE__ , ## args); \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
# define KDBG(level, fmt, args...) \
|
# define KDBG(level, fmt, args...) \
|
||||||
|
@ -209,7 +209,7 @@ do { \
|
||||||
pr_info("et61x251: " fmt "\n", ## args); \
|
pr_info("et61x251: " fmt "\n", ## args); \
|
||||||
else if ((level) == 3) \
|
else if ((level) == 3) \
|
||||||
pr_debug("et61x251: [%s:%d] " fmt "\n", __FUNCTION__, \
|
pr_debug("et61x251: [%s:%d] " fmt "\n", __FUNCTION__, \
|
||||||
__LINE__ , ## args); \
|
__LINE__ , ## args); \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
# define V4LDBG(level, name, cmd) \
|
# define V4LDBG(level, name, cmd) \
|
||||||
|
@ -226,7 +226,7 @@ do { \
|
||||||
#undef PDBG
|
#undef PDBG
|
||||||
#define PDBG(fmt, args...) \
|
#define PDBG(fmt, args...) \
|
||||||
dev_info(&cam->usbdev->dev, "[%s:%d] " fmt "\n", \
|
dev_info(&cam->usbdev->dev, "[%s:%d] " fmt "\n", \
|
||||||
__FUNCTION__, __LINE__ , ## args)
|
__FUNCTION__, __LINE__ , ## args)
|
||||||
|
|
||||||
#undef PDBGG
|
#undef PDBGG
|
||||||
#define PDBGG(fmt, args...) do {;} while(0) /* placeholder */
|
#define PDBGG(fmt, args...) do {;} while(0) /* placeholder */
|
|
@ -44,7 +44,7 @@
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
#define ET61X251_MODULE_NAME "V4L2 driver for ET61X[12]51 " \
|
#define ET61X251_MODULE_NAME "V4L2 driver for ET61X[12]51 " \
|
||||||
"PC Camera Controllers"
|
"PC Camera Controllers"
|
||||||
#define ET61X251_MODULE_AUTHOR "(C) 2006 Luca Risolia"
|
#define ET61X251_MODULE_AUTHOR "(C) 2006 Luca Risolia"
|
||||||
#define ET61X251_AUTHOR_EMAIL "<luca.risolia@studio.unibo.it>"
|
#define ET61X251_AUTHOR_EMAIL "<luca.risolia@studio.unibo.it>"
|
||||||
#define ET61X251_MODULE_LICENSE "GPL"
|
#define ET61X251_MODULE_LICENSE "GPL"
|
||||||
|
@ -63,68 +63,68 @@ MODULE_LICENSE(ET61X251_MODULE_LICENSE);
|
||||||
static short video_nr[] = {[0 ... ET61X251_MAX_DEVICES-1] = -1};
|
static short video_nr[] = {[0 ... ET61X251_MAX_DEVICES-1] = -1};
|
||||||
module_param_array(video_nr, short, NULL, 0444);
|
module_param_array(video_nr, short, NULL, 0444);
|
||||||
MODULE_PARM_DESC(video_nr,
|
MODULE_PARM_DESC(video_nr,
|
||||||
"\n<-1|n[,...]> Specify V4L2 minor mode number."
|
"\n<-1|n[,...]> Specify V4L2 minor mode number."
|
||||||
"\n -1 = use next available (default)"
|
"\n -1 = use next available (default)"
|
||||||
"\n n = use minor number n (integer >= 0)"
|
"\n n = use minor number n (integer >= 0)"
|
||||||
"\nYou can specify up to "
|
"\nYou can specify up to "
|
||||||
__MODULE_STRING(ET61X251_MAX_DEVICES) " cameras this way."
|
__MODULE_STRING(ET61X251_MAX_DEVICES) " cameras this way."
|
||||||
"\nFor example:"
|
"\nFor example:"
|
||||||
"\nvideo_nr=-1,2,-1 would assign minor number 2 to"
|
"\nvideo_nr=-1,2,-1 would assign minor number 2 to"
|
||||||
"\nthe second registered camera and use auto for the first"
|
"\nthe second registered camera and use auto for the first"
|
||||||
"\none and for every other camera."
|
"\none and for every other camera."
|
||||||
"\n");
|
"\n");
|
||||||
|
|
||||||
static short force_munmap[] = {[0 ... ET61X251_MAX_DEVICES-1] =
|
static short force_munmap[] = {[0 ... ET61X251_MAX_DEVICES-1] =
|
||||||
ET61X251_FORCE_MUNMAP};
|
ET61X251_FORCE_MUNMAP};
|
||||||
module_param_array(force_munmap, bool, NULL, 0444);
|
module_param_array(force_munmap, bool, NULL, 0444);
|
||||||
MODULE_PARM_DESC(force_munmap,
|
MODULE_PARM_DESC(force_munmap,
|
||||||
"\n<0|1[,...]> Force the application to unmap previously"
|
"\n<0|1[,...]> Force the application to unmap previously"
|
||||||
"\nmapped buffer memory before calling any VIDIOC_S_CROP or"
|
"\nmapped buffer memory before calling any VIDIOC_S_CROP or"
|
||||||
"\nVIDIOC_S_FMT ioctl's. Not all the applications support"
|
"\nVIDIOC_S_FMT ioctl's. Not all the applications support"
|
||||||
"\nthis feature. This parameter is specific for each"
|
"\nthis feature. This parameter is specific for each"
|
||||||
"\ndetected camera."
|
"\ndetected camera."
|
||||||
"\n 0 = do not force memory unmapping"
|
"\n 0 = do not force memory unmapping"
|
||||||
"\n 1 = force memory unmapping (save memory)"
|
"\n 1 = force memory unmapping (save memory)"
|
||||||
"\nDefault value is "__MODULE_STRING(SN9C102_FORCE_MUNMAP)"."
|
"\nDefault value is "__MODULE_STRING(SN9C102_FORCE_MUNMAP)"."
|
||||||
"\n");
|
"\n");
|
||||||
|
|
||||||
static unsigned int frame_timeout[] = {[0 ... ET61X251_MAX_DEVICES-1] =
|
static unsigned int frame_timeout[] = {[0 ... ET61X251_MAX_DEVICES-1] =
|
||||||
ET61X251_FRAME_TIMEOUT};
|
ET61X251_FRAME_TIMEOUT};
|
||||||
module_param_array(frame_timeout, uint, NULL, 0644);
|
module_param_array(frame_timeout, uint, NULL, 0644);
|
||||||
MODULE_PARM_DESC(frame_timeout,
|
MODULE_PARM_DESC(frame_timeout,
|
||||||
"\n<n[,...]> Timeout for a video frame in seconds."
|
"\n<n[,...]> Timeout for a video frame in seconds."
|
||||||
"\nThis parameter is specific for each detected camera."
|
"\nThis parameter is specific for each detected camera."
|
||||||
"\nDefault value is "
|
"\nDefault value is "
|
||||||
__MODULE_STRING(ET61X251_FRAME_TIMEOUT)"."
|
__MODULE_STRING(ET61X251_FRAME_TIMEOUT)"."
|
||||||
"\n");
|
"\n");
|
||||||
|
|
||||||
#ifdef ET61X251_DEBUG
|
#ifdef ET61X251_DEBUG
|
||||||
static unsigned short debug = ET61X251_DEBUG_LEVEL;
|
static unsigned short debug = ET61X251_DEBUG_LEVEL;
|
||||||
module_param(debug, ushort, 0644);
|
module_param(debug, ushort, 0644);
|
||||||
MODULE_PARM_DESC(debug,
|
MODULE_PARM_DESC(debug,
|
||||||
"\n<n> Debugging information level, from 0 to 3:"
|
"\n<n> Debugging information level, from 0 to 3:"
|
||||||
"\n0 = none (use carefully)"
|
"\n0 = none (use carefully)"
|
||||||
"\n1 = critical errors"
|
"\n1 = critical errors"
|
||||||
"\n2 = significant informations"
|
"\n2 = significant informations"
|
||||||
"\n3 = more verbose messages"
|
"\n3 = more verbose messages"
|
||||||
"\nLevel 3 is useful for testing only, when only "
|
"\nLevel 3 is useful for testing only, when only "
|
||||||
"one device is used."
|
"one device is used."
|
||||||
"\nDefault value is "__MODULE_STRING(ET61X251_DEBUG_LEVEL)"."
|
"\nDefault value is "__MODULE_STRING(ET61X251_DEBUG_LEVEL)"."
|
||||||
"\n");
|
"\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
static u32
|
static u32
|
||||||
et61x251_request_buffers(struct et61x251_device* cam, u32 count,
|
et61x251_request_buffers(struct et61x251_device* cam, u32 count,
|
||||||
enum et61x251_io_method io)
|
enum et61x251_io_method io)
|
||||||
{
|
{
|
||||||
struct v4l2_pix_format* p = &(cam->sensor.pix_format);
|
struct v4l2_pix_format* p = &(cam->sensor.pix_format);
|
||||||
struct v4l2_rect* r = &(cam->sensor.cropcap.bounds);
|
struct v4l2_rect* r = &(cam->sensor.cropcap.bounds);
|
||||||
const size_t imagesize = cam->module_param.force_munmap ||
|
const size_t imagesize = cam->module_param.force_munmap ||
|
||||||
io == IO_READ ?
|
io == IO_READ ?
|
||||||
(p->width * p->height * p->priv) / 8 :
|
(p->width * p->height * p->priv) / 8 :
|
||||||
(r->width * r->height * p->priv) / 8;
|
(r->width * r->height * p->priv) / 8;
|
||||||
void* buff = NULL;
|
void* buff = NULL;
|
||||||
u32 i;
|
u32 i;
|
||||||
|
|
||||||
|
@ -216,7 +216,7 @@ int et61x251_write_reg(struct et61x251_device* cam, u8 value, u16 index)
|
||||||
*buff = value;
|
*buff = value;
|
||||||
|
|
||||||
res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00, 0x41,
|
res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00, 0x41,
|
||||||
0, index, buff, 1, ET61X251_CTRL_TIMEOUT);
|
0, index, buff, 1, ET61X251_CTRL_TIMEOUT);
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
DBG(3, "Failed to write a register (value 0x%02X, index "
|
DBG(3, "Failed to write a register (value 0x%02X, index "
|
||||||
"0x%02X, error %d)", value, index, res);
|
"0x%02X, error %d)", value, index, res);
|
||||||
|
@ -234,7 +234,7 @@ int et61x251_read_reg(struct et61x251_device* cam, u16 index)
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x00, 0xc1,
|
res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x00, 0xc1,
|
||||||
0, index, buff, 1, ET61X251_CTRL_TIMEOUT);
|
0, index, buff, 1, ET61X251_CTRL_TIMEOUT);
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
DBG(3, "Failed to read a register (index 0x%02X, error %d)",
|
DBG(3, "Failed to read a register (index 0x%02X, error %d)",
|
||||||
index, res);
|
index, res);
|
||||||
|
@ -269,7 +269,7 @@ et61x251_i2c_wait(struct et61x251_device* cam, struct et61x251_sensor* sensor)
|
||||||
|
|
||||||
int
|
int
|
||||||
et61x251_i2c_try_read(struct et61x251_device* cam,
|
et61x251_i2c_try_read(struct et61x251_device* cam,
|
||||||
struct et61x251_sensor* sensor, u8 address)
|
struct et61x251_sensor* sensor, u8 address)
|
||||||
{
|
{
|
||||||
struct usb_device* udev = cam->usbdev;
|
struct usb_device* udev = cam->usbdev;
|
||||||
u8* data = cam->control_buffer;
|
u8* data = cam->control_buffer;
|
||||||
|
@ -280,14 +280,14 @@ et61x251_i2c_try_read(struct et61x251_device* cam,
|
||||||
data[2] = cam->sensor.rsta | 0x10;
|
data[2] = cam->sensor.rsta | 0x10;
|
||||||
data[3] = !(et61x251_read_reg(cam, 0x8b) & 0x02);
|
data[3] = !(et61x251_read_reg(cam, 0x8b) & 0x02);
|
||||||
res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00, 0x41,
|
res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00, 0x41,
|
||||||
0, 0x88, data, 4, ET61X251_CTRL_TIMEOUT);
|
0, 0x88, data, 4, ET61X251_CTRL_TIMEOUT);
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
err += res;
|
err += res;
|
||||||
|
|
||||||
err += et61x251_i2c_wait(cam, sensor);
|
err += et61x251_i2c_wait(cam, sensor);
|
||||||
|
|
||||||
res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x00, 0xc1,
|
res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x00, 0xc1,
|
||||||
0, 0x80, data, 8, ET61X251_CTRL_TIMEOUT);
|
0, 0x80, data, 8, ET61X251_CTRL_TIMEOUT);
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
err += res;
|
err += res;
|
||||||
|
|
||||||
|
@ -302,7 +302,7 @@ et61x251_i2c_try_read(struct et61x251_device* cam,
|
||||||
|
|
||||||
int
|
int
|
||||||
et61x251_i2c_try_write(struct et61x251_device* cam,
|
et61x251_i2c_try_write(struct et61x251_device* cam,
|
||||||
struct et61x251_sensor* sensor, u8 address, u8 value)
|
struct et61x251_sensor* sensor, u8 address, u8 value)
|
||||||
{
|
{
|
||||||
struct usb_device* udev = cam->usbdev;
|
struct usb_device* udev = cam->usbdev;
|
||||||
u8* data = cam->control_buffer;
|
u8* data = cam->control_buffer;
|
||||||
|
@ -312,13 +312,13 @@ et61x251_i2c_try_write(struct et61x251_device* cam,
|
||||||
data[1] = cam->sensor.i2c_slave_id;
|
data[1] = cam->sensor.i2c_slave_id;
|
||||||
data[2] = cam->sensor.rsta | 0x12;
|
data[2] = cam->sensor.rsta | 0x12;
|
||||||
res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00, 0x41,
|
res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00, 0x41,
|
||||||
0, 0x88, data, 3, ET61X251_CTRL_TIMEOUT);
|
0, 0x88, data, 3, ET61X251_CTRL_TIMEOUT);
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
err += res;
|
err += res;
|
||||||
|
|
||||||
data[0] = value;
|
data[0] = value;
|
||||||
res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00, 0x41,
|
res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00, 0x41,
|
||||||
0, 0x80, data, 1, ET61X251_CTRL_TIMEOUT);
|
0, 0x80, data, 1, ET61X251_CTRL_TIMEOUT);
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
err += res;
|
err += res;
|
||||||
|
|
||||||
|
@ -335,8 +335,8 @@ et61x251_i2c_try_write(struct et61x251_device* cam,
|
||||||
|
|
||||||
int
|
int
|
||||||
et61x251_i2c_raw_write(struct et61x251_device* cam, u8 n, u8 data1, u8 data2,
|
et61x251_i2c_raw_write(struct et61x251_device* cam, u8 n, u8 data1, u8 data2,
|
||||||
u8 data3, u8 data4, u8 data5, u8 data6, u8 data7,
|
u8 data3, u8 data4, u8 data5, u8 data6, u8 data7,
|
||||||
u8 data8, u8 address)
|
u8 data8, u8 address)
|
||||||
{
|
{
|
||||||
struct usb_device* udev = cam->usbdev;
|
struct usb_device* udev = cam->usbdev;
|
||||||
u8* data = cam->control_buffer;
|
u8* data = cam->control_buffer;
|
||||||
|
@ -350,7 +350,7 @@ et61x251_i2c_raw_write(struct et61x251_device* cam, u8 n, u8 data1, u8 data2,
|
||||||
data[5] = data7;
|
data[5] = data7;
|
||||||
data[6] = data8;
|
data[6] = data8;
|
||||||
res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00, 0x41,
|
res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00, 0x41,
|
||||||
0, 0x81, data, n-1, ET61X251_CTRL_TIMEOUT);
|
0, 0x81, data, n-1, ET61X251_CTRL_TIMEOUT);
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
err += res;
|
err += res;
|
||||||
|
|
||||||
|
@ -358,14 +358,14 @@ et61x251_i2c_raw_write(struct et61x251_device* cam, u8 n, u8 data1, u8 data2,
|
||||||
data[1] = cam->sensor.i2c_slave_id;
|
data[1] = cam->sensor.i2c_slave_id;
|
||||||
data[2] = cam->sensor.rsta | 0x02 | (n << 4);
|
data[2] = cam->sensor.rsta | 0x02 | (n << 4);
|
||||||
res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00, 0x41,
|
res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00, 0x41,
|
||||||
0, 0x88, data, 3, ET61X251_CTRL_TIMEOUT);
|
0, 0x88, data, 3, ET61X251_CTRL_TIMEOUT);
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
err += res;
|
err += res;
|
||||||
|
|
||||||
/* Start writing through the serial interface */
|
/* Start writing through the serial interface */
|
||||||
data[0] = data1;
|
data[0] = data1;
|
||||||
res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00, 0x41,
|
res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00, 0x41,
|
||||||
0, 0x80, data, 1, ET61X251_CTRL_TIMEOUT);
|
0, 0x80, data, 1, ET61X251_CTRL_TIMEOUT);
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
err += res;
|
err += res;
|
||||||
|
|
||||||
|
@ -432,11 +432,11 @@ static void et61x251_urb_complete(struct urb *urb, struct pt_regs* regs)
|
||||||
|
|
||||||
if (!(*f))
|
if (!(*f))
|
||||||
(*f) = list_entry(cam->inqueue.next, struct et61x251_frame_t,
|
(*f) = list_entry(cam->inqueue.next, struct et61x251_frame_t,
|
||||||
frame);
|
frame);
|
||||||
|
|
||||||
imagesize = (cam->sensor.pix_format.width *
|
imagesize = (cam->sensor.pix_format.width *
|
||||||
cam->sensor.pix_format.height *
|
cam->sensor.pix_format.height *
|
||||||
cam->sensor.pix_format.priv) / 8;
|
cam->sensor.pix_format.priv) / 8;
|
||||||
|
|
||||||
for (i = 0; i < urb->number_of_packets; i++) {
|
for (i = 0; i < urb->number_of_packets; i++) {
|
||||||
unsigned int len, status;
|
unsigned int len, status;
|
||||||
|
@ -476,7 +476,7 @@ static void et61x251_urb_complete(struct urb *urb, struct pt_regs* regs)
|
||||||
if ((*f)->state == F_GRABBING) {
|
if ((*f)->state == F_GRABBING) {
|
||||||
if (sof && (*f)->buf.bytesused) {
|
if (sof && (*f)->buf.bytesused) {
|
||||||
if (cam->sensor.pix_format.pixelformat ==
|
if (cam->sensor.pix_format.pixelformat ==
|
||||||
V4L2_PIX_FMT_ET61X251)
|
V4L2_PIX_FMT_ET61X251)
|
||||||
goto end_of_frame;
|
goto end_of_frame;
|
||||||
else {
|
else {
|
||||||
DBG(3, "Not expected SOF detected "
|
DBG(3, "Not expected SOF detected "
|
||||||
|
@ -508,8 +508,8 @@ static void et61x251_urb_complete(struct urb *urb, struct pt_regs* regs)
|
||||||
list_move_tail(&(*f)->frame, &cam->outqueue);
|
list_move_tail(&(*f)->frame, &cam->outqueue);
|
||||||
if (!list_empty(&cam->inqueue))
|
if (!list_empty(&cam->inqueue))
|
||||||
(*f) = list_entry(cam->inqueue.next,
|
(*f) = list_entry(cam->inqueue.next,
|
||||||
struct et61x251_frame_t,
|
struct et61x251_frame_t,
|
||||||
frame);
|
frame);
|
||||||
else
|
else
|
||||||
(*f) = NULL;
|
(*f) = NULL;
|
||||||
spin_unlock(&cam->queue_lock);
|
spin_unlock(&cam->queue_lock);
|
||||||
|
@ -521,7 +521,7 @@ static void et61x251_urb_complete(struct urb *urb, struct pt_regs* regs)
|
||||||
|
|
||||||
if (sof &&
|
if (sof &&
|
||||||
cam->sensor.pix_format.pixelformat ==
|
cam->sensor.pix_format.pixelformat ==
|
||||||
V4L2_PIX_FMT_ET61X251)
|
V4L2_PIX_FMT_ET61X251)
|
||||||
goto start_of_frame;
|
goto start_of_frame;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -544,15 +544,15 @@ static int et61x251_start_transfer(struct et61x251_device* cam)
|
||||||
struct usb_device *udev = cam->usbdev;
|
struct usb_device *udev = cam->usbdev;
|
||||||
struct urb* urb;
|
struct urb* urb;
|
||||||
const unsigned int wMaxPacketSize[] = {0, 256, 384, 512, 640, 768, 832,
|
const unsigned int wMaxPacketSize[] = {0, 256, 384, 512, 640, 768, 832,
|
||||||
864, 896, 920, 956, 980, 1000,
|
864, 896, 920, 956, 980, 1000,
|
||||||
1022};
|
1022};
|
||||||
const unsigned int psz = wMaxPacketSize[ET61X251_ALTERNATE_SETTING];
|
const unsigned int psz = wMaxPacketSize[ET61X251_ALTERNATE_SETTING];
|
||||||
s8 i, j;
|
s8 i, j;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
for (i = 0; i < ET61X251_URBS; i++) {
|
for (i = 0; i < ET61X251_URBS; i++) {
|
||||||
cam->transfer_buffer[i] = kzalloc(ET61X251_ISO_PACKETS * psz,
|
cam->transfer_buffer[i] = kzalloc(ET61X251_ISO_PACKETS * psz,
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
if (!cam->transfer_buffer[i]) {
|
if (!cam->transfer_buffer[i]) {
|
||||||
err = -ENOMEM;
|
err = -ENOMEM;
|
||||||
DBG(1, "Not enough memory");
|
DBG(1, "Not enough memory");
|
||||||
|
@ -653,9 +653,9 @@ static int et61x251_stream_interrupt(struct et61x251_device* cam)
|
||||||
|
|
||||||
cam->stream = STREAM_INTERRUPT;
|
cam->stream = STREAM_INTERRUPT;
|
||||||
timeout = wait_event_timeout(cam->wait_stream,
|
timeout = wait_event_timeout(cam->wait_stream,
|
||||||
(cam->stream == STREAM_OFF) ||
|
(cam->stream == STREAM_OFF) ||
|
||||||
(cam->state & DEV_DISCONNECTED),
|
(cam->state & DEV_DISCONNECTED),
|
||||||
ET61X251_URB_TIMEOUT);
|
ET61X251_URB_TIMEOUT);
|
||||||
if (cam->state & DEV_DISCONNECTED)
|
if (cam->state & DEV_DISCONNECTED)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
else if (cam->stream != STREAM_OFF) {
|
else if (cam->stream != STREAM_OFF) {
|
||||||
|
@ -699,7 +699,7 @@ static u8 et61x251_strtou8(const char* buff, size_t len, ssize_t* count)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
NOTE 1: being inside one of the following methods implies that the v4l
|
NOTE 1: being inside one of the following methods implies that the v4l
|
||||||
device exists for sure (see kobjects and reference counters)
|
device exists for sure (see kobjects and reference counters)
|
||||||
NOTE 2: buffers are PAGE_SIZE long
|
NOTE 2: buffers are PAGE_SIZE long
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -964,13 +964,13 @@ et61x251_store_i2c_val(struct class_device* cd, const char* buf, size_t len)
|
||||||
|
|
||||||
|
|
||||||
static CLASS_DEVICE_ATTR(reg, S_IRUGO | S_IWUSR,
|
static CLASS_DEVICE_ATTR(reg, S_IRUGO | S_IWUSR,
|
||||||
et61x251_show_reg, et61x251_store_reg);
|
et61x251_show_reg, et61x251_store_reg);
|
||||||
static CLASS_DEVICE_ATTR(val, S_IRUGO | S_IWUSR,
|
static CLASS_DEVICE_ATTR(val, S_IRUGO | S_IWUSR,
|
||||||
et61x251_show_val, et61x251_store_val);
|
et61x251_show_val, et61x251_store_val);
|
||||||
static CLASS_DEVICE_ATTR(i2c_reg, S_IRUGO | S_IWUSR,
|
static CLASS_DEVICE_ATTR(i2c_reg, S_IRUGO | S_IWUSR,
|
||||||
et61x251_show_i2c_reg, et61x251_store_i2c_reg);
|
et61x251_show_i2c_reg, et61x251_store_i2c_reg);
|
||||||
static CLASS_DEVICE_ATTR(i2c_val, S_IRUGO | S_IWUSR,
|
static CLASS_DEVICE_ATTR(i2c_val, S_IRUGO | S_IWUSR,
|
||||||
et61x251_show_i2c_val, et61x251_store_i2c_val);
|
et61x251_show_i2c_val, et61x251_store_i2c_val);
|
||||||
|
|
||||||
|
|
||||||
static void et61x251_create_sysfs(struct et61x251_device* cam)
|
static void et61x251_create_sysfs(struct et61x251_device* cam)
|
||||||
|
@ -990,7 +990,7 @@ static void et61x251_create_sysfs(struct et61x251_device* cam)
|
||||||
|
|
||||||
static int
|
static int
|
||||||
et61x251_set_pix_format(struct et61x251_device* cam,
|
et61x251_set_pix_format(struct et61x251_device* cam,
|
||||||
struct v4l2_pix_format* pix)
|
struct v4l2_pix_format* pix)
|
||||||
{
|
{
|
||||||
int r, err = 0;
|
int r, err = 0;
|
||||||
|
|
||||||
|
@ -1007,7 +1007,7 @@ et61x251_set_pix_format(struct et61x251_device* cam,
|
||||||
|
|
||||||
static int
|
static int
|
||||||
et61x251_set_compression(struct et61x251_device* cam,
|
et61x251_set_compression(struct et61x251_device* cam,
|
||||||
struct v4l2_jpegcompression* compression)
|
struct v4l2_jpegcompression* compression)
|
||||||
{
|
{
|
||||||
int r, err = 0;
|
int r, err = 0;
|
||||||
|
|
||||||
|
@ -1049,9 +1049,9 @@ et61x251_set_crop(struct et61x251_device* cam, struct v4l2_rect* rect)
|
||||||
{
|
{
|
||||||
struct et61x251_sensor* s = &cam->sensor;
|
struct et61x251_sensor* s = &cam->sensor;
|
||||||
u16 fmw_sx = (u16)(rect->left - s->cropcap.bounds.left +
|
u16 fmw_sx = (u16)(rect->left - s->cropcap.bounds.left +
|
||||||
s->active_pixel.left),
|
s->active_pixel.left),
|
||||||
fmw_sy = (u16)(rect->top - s->cropcap.bounds.top +
|
fmw_sy = (u16)(rect->top - s->cropcap.bounds.top +
|
||||||
s->active_pixel.top),
|
s->active_pixel.top),
|
||||||
fmw_length = (u16)(rect->width),
|
fmw_length = (u16)(rect->width),
|
||||||
fmw_height = (u16)(rect->height);
|
fmw_height = (u16)(rect->height);
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
@ -1061,8 +1061,8 @@ et61x251_set_crop(struct et61x251_device* cam, struct v4l2_rect* rect)
|
||||||
err += et61x251_write_reg(cam, fmw_length & 0xff, 0x6b);
|
err += et61x251_write_reg(cam, fmw_length & 0xff, 0x6b);
|
||||||
err += et61x251_write_reg(cam, fmw_height & 0xff, 0x6c);
|
err += et61x251_write_reg(cam, fmw_height & 0xff, 0x6c);
|
||||||
err += et61x251_write_reg(cam, (fmw_sx >> 8) | ((fmw_sy & 0x300) >> 6)
|
err += et61x251_write_reg(cam, (fmw_sx >> 8) | ((fmw_sy & 0x300) >> 6)
|
||||||
| ((fmw_length & 0x300) >> 4)
|
| ((fmw_length & 0x300) >> 4)
|
||||||
| ((fmw_height & 0x300) >> 2), 0x6d);
|
| ((fmw_height & 0x300) >> 2), 0x6d);
|
||||||
if (err)
|
if (err)
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
|
||||||
|
@ -1203,8 +1203,8 @@ static int et61x251_open(struct inode* inode, struct file* filp)
|
||||||
}
|
}
|
||||||
mutex_unlock(&cam->dev_mutex);
|
mutex_unlock(&cam->dev_mutex);
|
||||||
err = wait_event_interruptible_exclusive(cam->open,
|
err = wait_event_interruptible_exclusive(cam->open,
|
||||||
cam->state & DEV_DISCONNECTED
|
cam->state & DEV_DISCONNECTED
|
||||||
|| !cam->users);
|
|| !cam->users);
|
||||||
if (err) {
|
if (err) {
|
||||||
up_read(&et61x251_disconnect);
|
up_read(&et61x251_disconnect);
|
||||||
return err;
|
return err;
|
||||||
|
@ -1277,7 +1277,7 @@ static int et61x251_release(struct inode* inode, struct file* filp)
|
||||||
|
|
||||||
static ssize_t
|
static ssize_t
|
||||||
et61x251_read(struct file* filp, char __user * buf,
|
et61x251_read(struct file* filp, char __user * buf,
|
||||||
size_t count, loff_t* f_pos)
|
size_t count, loff_t* f_pos)
|
||||||
{
|
{
|
||||||
struct et61x251_device* cam = video_get_drvdata(video_devdata(filp));
|
struct et61x251_device* cam = video_get_drvdata(video_devdata(filp));
|
||||||
struct et61x251_frame_t* f, * i;
|
struct et61x251_frame_t* f, * i;
|
||||||
|
@ -1310,7 +1310,7 @@ et61x251_read(struct file* filp, char __user * buf,
|
||||||
|
|
||||||
if (cam->io == IO_NONE) {
|
if (cam->io == IO_NONE) {
|
||||||
if (!et61x251_request_buffers(cam, cam->nreadbuffers,
|
if (!et61x251_request_buffers(cam, cam->nreadbuffers,
|
||||||
IO_READ)) {
|
IO_READ)) {
|
||||||
DBG(1, "read() failed, not enough memory");
|
DBG(1, "read() failed, not enough memory");
|
||||||
mutex_unlock(&cam->fileop_mutex);
|
mutex_unlock(&cam->fileop_mutex);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
@ -1336,12 +1336,12 @@ et61x251_read(struct file* filp, char __user * buf,
|
||||||
return -EAGAIN;
|
return -EAGAIN;
|
||||||
}
|
}
|
||||||
timeout = wait_event_interruptible_timeout
|
timeout = wait_event_interruptible_timeout
|
||||||
( cam->wait_frame,
|
( cam->wait_frame,
|
||||||
(!list_empty(&cam->outqueue)) ||
|
(!list_empty(&cam->outqueue)) ||
|
||||||
(cam->state & DEV_DISCONNECTED) ||
|
(cam->state & DEV_DISCONNECTED) ||
|
||||||
(cam->state & DEV_MISCONFIGURED),
|
(cam->state & DEV_MISCONFIGURED),
|
||||||
cam->module_param.frame_timeout *
|
cam->module_param.frame_timeout *
|
||||||
1000 * msecs_to_jiffies(1) );
|
1000 * msecs_to_jiffies(1) );
|
||||||
if (timeout < 0) {
|
if (timeout < 0) {
|
||||||
mutex_unlock(&cam->fileop_mutex);
|
mutex_unlock(&cam->fileop_mutex);
|
||||||
return timeout;
|
return timeout;
|
||||||
|
@ -1408,7 +1408,7 @@ static unsigned int et61x251_poll(struct file *filp, poll_table *wait)
|
||||||
|
|
||||||
if (cam->io == IO_NONE) {
|
if (cam->io == IO_NONE) {
|
||||||
if (!et61x251_request_buffers(cam, cam->nreadbuffers,
|
if (!et61x251_request_buffers(cam, cam->nreadbuffers,
|
||||||
IO_READ)) {
|
IO_READ)) {
|
||||||
DBG(1, "poll() failed, not enough memory");
|
DBG(1, "poll() failed, not enough memory");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
@ -1465,7 +1465,7 @@ static int et61x251_mmap(struct file* filp, struct vm_area_struct *vma)
|
||||||
{
|
{
|
||||||
struct et61x251_device* cam = video_get_drvdata(video_devdata(filp));
|
struct et61x251_device* cam = video_get_drvdata(video_devdata(filp));
|
||||||
unsigned long size = vma->vm_end - vma->vm_start,
|
unsigned long size = vma->vm_end - vma->vm_start,
|
||||||
start = vma->vm_start;
|
start = vma->vm_start;
|
||||||
void *pos;
|
void *pos;
|
||||||
u32 i;
|
u32 i;
|
||||||
|
|
||||||
|
@ -1533,13 +1533,13 @@ et61x251_vidioc_querycap(struct et61x251_device* cam, void __user * arg)
|
||||||
.driver = "et61x251",
|
.driver = "et61x251",
|
||||||
.version = ET61X251_MODULE_VERSION_CODE,
|
.version = ET61X251_MODULE_VERSION_CODE,
|
||||||
.capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE |
|
.capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE |
|
||||||
V4L2_CAP_STREAMING,
|
V4L2_CAP_STREAMING,
|
||||||
};
|
};
|
||||||
|
|
||||||
strlcpy(cap.card, cam->v4ldev->name, sizeof(cap.card));
|
strlcpy(cap.card, cam->v4ldev->name, sizeof(cap.card));
|
||||||
if (usb_make_path(cam->usbdev, cap.bus_info, sizeof(cap.bus_info)) < 0)
|
if (usb_make_path(cam->usbdev, cap.bus_info, sizeof(cap.bus_info)) < 0)
|
||||||
strlcpy(cap.bus_info, cam->usbdev->dev.bus_id,
|
strlcpy(cap.bus_info, cam->usbdev->dev.bus_id,
|
||||||
sizeof(cap.bus_info));
|
sizeof(cap.bus_info));
|
||||||
|
|
||||||
if (copy_to_user(arg, &cap, sizeof(cap)))
|
if (copy_to_user(arg, &cap, sizeof(cap)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
@ -1871,7 +1871,7 @@ et61x251_vidioc_g_fmt(struct et61x251_device* cam, void __user * arg)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
pfmt->bytesperline = (pfmt->pixelformat==V4L2_PIX_FMT_ET61X251)
|
pfmt->bytesperline = (pfmt->pixelformat==V4L2_PIX_FMT_ET61X251)
|
||||||
? 0 : (pfmt->width * pfmt->priv) / 8;
|
? 0 : (pfmt->width * pfmt->priv) / 8;
|
||||||
pfmt->sizeimage = pfmt->height * ((pfmt->width*pfmt->priv)/8);
|
pfmt->sizeimage = pfmt->height * ((pfmt->width*pfmt->priv)/8);
|
||||||
pfmt->field = V4L2_FIELD_NONE;
|
pfmt->field = V4L2_FIELD_NONE;
|
||||||
memcpy(&(format.fmt.pix), pfmt, sizeof(*pfmt));
|
memcpy(&(format.fmt.pix), pfmt, sizeof(*pfmt));
|
||||||
|
@ -1885,7 +1885,7 @@ et61x251_vidioc_g_fmt(struct et61x251_device* cam, void __user * arg)
|
||||||
|
|
||||||
static int
|
static int
|
||||||
et61x251_vidioc_try_s_fmt(struct et61x251_device* cam, unsigned int cmd,
|
et61x251_vidioc_try_s_fmt(struct et61x251_device* cam, unsigned int cmd,
|
||||||
void __user * arg)
|
void __user * arg)
|
||||||
{
|
{
|
||||||
struct et61x251_sensor* s = &cam->sensor;
|
struct et61x251_sensor* s = &cam->sensor;
|
||||||
struct v4l2_format format;
|
struct v4l2_format format;
|
||||||
|
@ -1947,7 +1947,7 @@ et61x251_vidioc_try_s_fmt(struct et61x251_device* cam, unsigned int cmd,
|
||||||
pix->priv = pfmt->priv; /* bpp */
|
pix->priv = pfmt->priv; /* bpp */
|
||||||
pix->colorspace = pfmt->colorspace;
|
pix->colorspace = pfmt->colorspace;
|
||||||
pix->bytesperline = (pix->pixelformat == V4L2_PIX_FMT_ET61X251)
|
pix->bytesperline = (pix->pixelformat == V4L2_PIX_FMT_ET61X251)
|
||||||
? 0 : (pix->width * pix->priv) / 8;
|
? 0 : (pix->width * pix->priv) / 8;
|
||||||
pix->sizeimage = pix->height * ((pix->width * pix->priv) / 8);
|
pix->sizeimage = pix->height * ((pix->width * pix->priv) / 8);
|
||||||
pix->field = V4L2_FIELD_NONE;
|
pix->field = V4L2_FIELD_NONE;
|
||||||
|
|
||||||
|
@ -2020,7 +2020,7 @@ static int
|
||||||
et61x251_vidioc_g_jpegcomp(struct et61x251_device* cam, void __user * arg)
|
et61x251_vidioc_g_jpegcomp(struct et61x251_device* cam, void __user * arg)
|
||||||
{
|
{
|
||||||
if (copy_to_user(arg, &cam->compression,
|
if (copy_to_user(arg, &cam->compression,
|
||||||
sizeof(cam->compression)))
|
sizeof(cam->compression)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -2169,7 +2169,7 @@ et61x251_vidioc_qbuf(struct et61x251_device* cam, void __user * arg)
|
||||||
|
|
||||||
static int
|
static int
|
||||||
et61x251_vidioc_dqbuf(struct et61x251_device* cam, struct file* filp,
|
et61x251_vidioc_dqbuf(struct et61x251_device* cam, struct file* filp,
|
||||||
void __user * arg)
|
void __user * arg)
|
||||||
{
|
{
|
||||||
struct v4l2_buffer b;
|
struct v4l2_buffer b;
|
||||||
struct et61x251_frame_t *f;
|
struct et61x251_frame_t *f;
|
||||||
|
@ -2188,12 +2188,12 @@ et61x251_vidioc_dqbuf(struct et61x251_device* cam, struct file* filp,
|
||||||
if (filp->f_flags & O_NONBLOCK)
|
if (filp->f_flags & O_NONBLOCK)
|
||||||
return -EAGAIN;
|
return -EAGAIN;
|
||||||
timeout = wait_event_interruptible_timeout
|
timeout = wait_event_interruptible_timeout
|
||||||
( cam->wait_frame,
|
( cam->wait_frame,
|
||||||
(!list_empty(&cam->outqueue)) ||
|
(!list_empty(&cam->outqueue)) ||
|
||||||
(cam->state & DEV_DISCONNECTED) ||
|
(cam->state & DEV_DISCONNECTED) ||
|
||||||
(cam->state & DEV_MISCONFIGURED),
|
(cam->state & DEV_MISCONFIGURED),
|
||||||
cam->module_param.frame_timeout *
|
cam->module_param.frame_timeout *
|
||||||
1000 * msecs_to_jiffies(1) );
|
1000 * msecs_to_jiffies(1) );
|
||||||
if (timeout < 0)
|
if (timeout < 0)
|
||||||
return timeout;
|
return timeout;
|
||||||
if (cam->state & DEV_DISCONNECTED)
|
if (cam->state & DEV_DISCONNECTED)
|
||||||
|
@ -2317,7 +2317,7 @@ et61x251_vidioc_s_parm(struct et61x251_device* cam, void __user * arg)
|
||||||
|
|
||||||
|
|
||||||
static int et61x251_ioctl_v4l2(struct inode* inode, struct file* filp,
|
static int et61x251_ioctl_v4l2(struct inode* inode, struct file* filp,
|
||||||
unsigned int cmd, void __user * arg)
|
unsigned int cmd, void __user * arg)
|
||||||
{
|
{
|
||||||
struct et61x251_device* cam = video_get_drvdata(video_devdata(filp));
|
struct et61x251_device* cam = video_get_drvdata(video_devdata(filp));
|
||||||
|
|
||||||
|
@ -2411,7 +2411,7 @@ static int et61x251_ioctl_v4l2(struct inode* inode, struct file* filp,
|
||||||
|
|
||||||
|
|
||||||
static int et61x251_ioctl(struct inode* inode, struct file* filp,
|
static int et61x251_ioctl(struct inode* inode, struct file* filp,
|
||||||
unsigned int cmd, unsigned long arg)
|
unsigned int cmd, unsigned long arg)
|
||||||
{
|
{
|
||||||
struct et61x251_device* cam = video_get_drvdata(video_devdata(filp));
|
struct et61x251_device* cam = video_get_drvdata(video_devdata(filp));
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
@ -2518,7 +2518,7 @@ et61x251_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
|
||||||
mutex_lock(&cam->dev_mutex);
|
mutex_lock(&cam->dev_mutex);
|
||||||
|
|
||||||
err = video_register_device(cam->v4ldev, VFL_TYPE_GRABBER,
|
err = video_register_device(cam->v4ldev, VFL_TYPE_GRABBER,
|
||||||
video_nr[dev_nr]);
|
video_nr[dev_nr]);
|
||||||
if (err) {
|
if (err) {
|
||||||
DBG(1, "V4L2 device registration failed");
|
DBG(1, "V4L2 device registration failed");
|
||||||
if (err == -ENFILE && video_nr[dev_nr] == -1)
|
if (err == -ENFILE && video_nr[dev_nr] == -1)
|
|
@ -47,7 +47,7 @@ et61x251_match_id(struct et61x251_device* cam, const struct usb_device_id *id);
|
||||||
|
|
||||||
extern void
|
extern void
|
||||||
et61x251_attach_sensor(struct et61x251_device* cam,
|
et61x251_attach_sensor(struct et61x251_device* cam,
|
||||||
struct et61x251_sensor* sensor);
|
struct et61x251_sensor* sensor);
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
@ -56,13 +56,13 @@ extern int et61x251_read_reg(struct et61x251_device*, u16 index);
|
||||||
extern int et61x251_i2c_write(struct et61x251_device*, u8 address, u8 value);
|
extern int et61x251_i2c_write(struct et61x251_device*, u8 address, u8 value);
|
||||||
extern int et61x251_i2c_read(struct et61x251_device*, u8 address);
|
extern int et61x251_i2c_read(struct et61x251_device*, u8 address);
|
||||||
extern int et61x251_i2c_try_write(struct et61x251_device*,
|
extern int et61x251_i2c_try_write(struct et61x251_device*,
|
||||||
struct et61x251_sensor*, u8 address,
|
struct et61x251_sensor*, u8 address,
|
||||||
u8 value);
|
u8 value);
|
||||||
extern int et61x251_i2c_try_read(struct et61x251_device*,
|
extern int et61x251_i2c_try_read(struct et61x251_device*,
|
||||||
struct et61x251_sensor*, u8 address);
|
struct et61x251_sensor*, u8 address);
|
||||||
extern int et61x251_i2c_raw_write(struct et61x251_device*, u8 n, u8 data1,
|
extern int et61x251_i2c_raw_write(struct et61x251_device*, u8 n, u8 data1,
|
||||||
u8 data2, u8 data3, u8 data4, u8 data5,
|
u8 data2, u8 data3, u8 data4, u8 data5,
|
||||||
u8 data6, u8 data7, u8 data8, u8 address);
|
u8 data6, u8 data7, u8 data8, u8 address);
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
@ -100,13 +100,13 @@ struct et61x251_sensor {
|
||||||
|
|
||||||
int (*init)(struct et61x251_device* cam);
|
int (*init)(struct et61x251_device* cam);
|
||||||
int (*get_ctrl)(struct et61x251_device* cam,
|
int (*get_ctrl)(struct et61x251_device* cam,
|
||||||
struct v4l2_control* ctrl);
|
struct v4l2_control* ctrl);
|
||||||
int (*set_ctrl)(struct et61x251_device* cam,
|
int (*set_ctrl)(struct et61x251_device* cam,
|
||||||
const struct v4l2_control* ctrl);
|
const struct v4l2_control* ctrl);
|
||||||
int (*set_crop)(struct et61x251_device* cam,
|
int (*set_crop)(struct et61x251_device* cam,
|
||||||
const struct v4l2_rect* rect);
|
const struct v4l2_rect* rect);
|
||||||
int (*set_pix_format)(struct et61x251_device* cam,
|
int (*set_pix_format)(struct et61x251_device* cam,
|
||||||
const struct v4l2_pix_format* pix);
|
const struct v4l2_pix_format* pix);
|
||||||
|
|
||||||
/* Private */
|
/* Private */
|
||||||
struct v4l2_queryctrl _qctrl[ET61X251_MAX_CTRLS];
|
struct v4l2_queryctrl _qctrl[ET61X251_MAX_CTRLS];
|
|
@ -46,20 +46,20 @@ static int tas5130d1b_init(struct et61x251_device* cam)
|
||||||
|
|
||||||
|
|
||||||
static int tas5130d1b_set_ctrl(struct et61x251_device* cam,
|
static int tas5130d1b_set_ctrl(struct et61x251_device* cam,
|
||||||
const struct v4l2_control* ctrl)
|
const struct v4l2_control* ctrl)
|
||||||
{
|
{
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
switch (ctrl->id) {
|
switch (ctrl->id) {
|
||||||
case V4L2_CID_GAIN:
|
case V4L2_CID_GAIN:
|
||||||
err += et61x251_i2c_raw_write(cam, 2, 0x20,
|
err += et61x251_i2c_raw_write(cam, 2, 0x20,
|
||||||
0xf6-ctrl->value, 0, 0, 0,
|
0xf6-ctrl->value, 0, 0, 0,
|
||||||
0, 0, 0, 0);
|
0, 0, 0, 0);
|
||||||
break;
|
break;
|
||||||
case V4L2_CID_EXPOSURE:
|
case V4L2_CID_EXPOSURE:
|
||||||
err += et61x251_i2c_raw_write(cam, 2, 0x40,
|
err += et61x251_i2c_raw_write(cam, 2, 0x40,
|
||||||
0x47-ctrl->value, 0, 0, 0,
|
0x47-ctrl->value, 0, 0, 0,
|
||||||
0, 0, 0, 0);
|
0, 0, 0, 0);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return -EINVAL;
|
return -EINVAL;
|
407
drivers/media/video/font.h
Normal file
407
drivers/media/video/font.h
Normal file
|
@ -0,0 +1,407 @@
|
||||||
|
static unsigned char rom8x16_bits[] = {
|
||||||
|
/* Character 0 (0x30):
|
||||||
|
ht=16, width=8
|
||||||
|
+--------+
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
| ***** |
|
||||||
|
|** ** |
|
||||||
|
|** ** |
|
||||||
|
|** *** |
|
||||||
|
|** **** |
|
||||||
|
|**** ** |
|
||||||
|
|*** ** |
|
||||||
|
|** ** |
|
||||||
|
|** ** |
|
||||||
|
| ***** |
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
+--------+ */
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
0x7c,
|
||||||
|
0xc6,
|
||||||
|
0xc6,
|
||||||
|
0xce,
|
||||||
|
0xde,
|
||||||
|
0xf6,
|
||||||
|
0xe6,
|
||||||
|
0xc6,
|
||||||
|
0xc6,
|
||||||
|
0x7c,
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
|
||||||
|
/* Character 1 (0x31):
|
||||||
|
ht=16, width=8
|
||||||
|
+--------+
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
| ** |
|
||||||
|
| **** |
|
||||||
|
| ** |
|
||||||
|
| ** |
|
||||||
|
| ** |
|
||||||
|
| ** |
|
||||||
|
| ** |
|
||||||
|
| ** |
|
||||||
|
| ** |
|
||||||
|
| ****** |
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
+--------+ */
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
0x18,
|
||||||
|
0x78,
|
||||||
|
0x18,
|
||||||
|
0x18,
|
||||||
|
0x18,
|
||||||
|
0x18,
|
||||||
|
0x18,
|
||||||
|
0x18,
|
||||||
|
0x18,
|
||||||
|
0x7e,
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
|
||||||
|
/* Character 2 (0x32):
|
||||||
|
ht=16, width=8
|
||||||
|
+--------+
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
| ***** |
|
||||||
|
|** ** |
|
||||||
|
|** ** |
|
||||||
|
| ** |
|
||||||
|
| ** |
|
||||||
|
| ** |
|
||||||
|
| ** |
|
||||||
|
| ** |
|
||||||
|
|** ** |
|
||||||
|
|******* |
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
+--------+ */
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
0x7c,
|
||||||
|
0xc6,
|
||||||
|
0xc6,
|
||||||
|
0x06,
|
||||||
|
0x0c,
|
||||||
|
0x18,
|
||||||
|
0x30,
|
||||||
|
0x60,
|
||||||
|
0xc6,
|
||||||
|
0xfe,
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
|
||||||
|
/* Character 3 (0x33):
|
||||||
|
ht=16, width=8
|
||||||
|
+--------+
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
| ***** |
|
||||||
|
|** ** |
|
||||||
|
| ** |
|
||||||
|
| ** |
|
||||||
|
| **** |
|
||||||
|
| ** |
|
||||||
|
| ** |
|
||||||
|
| ** |
|
||||||
|
|** ** |
|
||||||
|
| ***** |
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
+--------+ */
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
0x7c,
|
||||||
|
0xc6,
|
||||||
|
0x06,
|
||||||
|
0x06,
|
||||||
|
0x3c,
|
||||||
|
0x06,
|
||||||
|
0x06,
|
||||||
|
0x06,
|
||||||
|
0xc6,
|
||||||
|
0x7c,
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
|
||||||
|
/* Character 4 (0x34):
|
||||||
|
ht=16, width=8
|
||||||
|
+--------+
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
| ** |
|
||||||
|
| *** |
|
||||||
|
| **** |
|
||||||
|
| ** ** |
|
||||||
|
|** ** |
|
||||||
|
|** ** |
|
||||||
|
|******* |
|
||||||
|
| ** |
|
||||||
|
| ** |
|
||||||
|
| **** |
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
+--------+ */
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
0x0c,
|
||||||
|
0x1c,
|
||||||
|
0x3c,
|
||||||
|
0x6c,
|
||||||
|
0xcc,
|
||||||
|
0xcc,
|
||||||
|
0xfe,
|
||||||
|
0x0c,
|
||||||
|
0x0c,
|
||||||
|
0x1e,
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
|
||||||
|
/* Character 5 (0x35):
|
||||||
|
ht=16, width=8
|
||||||
|
+--------+
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
|******* |
|
||||||
|
|** |
|
||||||
|
|** |
|
||||||
|
|** |
|
||||||
|
|****** |
|
||||||
|
| ** |
|
||||||
|
| ** |
|
||||||
|
| ** |
|
||||||
|
|** ** |
|
||||||
|
| ***** |
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
+--------+ */
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
0xfe,
|
||||||
|
0xc0,
|
||||||
|
0xc0,
|
||||||
|
0xc0,
|
||||||
|
0xfc,
|
||||||
|
0x06,
|
||||||
|
0x06,
|
||||||
|
0x06,
|
||||||
|
0xc6,
|
||||||
|
0x7c,
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
|
||||||
|
/* Character 6 (0x36):
|
||||||
|
ht=16, width=8
|
||||||
|
+--------+
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
| ***** |
|
||||||
|
|** ** |
|
||||||
|
|** |
|
||||||
|
|** |
|
||||||
|
|****** |
|
||||||
|
|** ** |
|
||||||
|
|** ** |
|
||||||
|
|** ** |
|
||||||
|
|** ** |
|
||||||
|
| ***** |
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
+--------+ */
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
0x7c,
|
||||||
|
0xc6,
|
||||||
|
0xc0,
|
||||||
|
0xc0,
|
||||||
|
0xfc,
|
||||||
|
0xc6,
|
||||||
|
0xc6,
|
||||||
|
0xc6,
|
||||||
|
0xc6,
|
||||||
|
0x7c,
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
|
||||||
|
/* Character 7 (0x37):
|
||||||
|
ht=16, width=8
|
||||||
|
+--------+
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
|******* |
|
||||||
|
|** ** |
|
||||||
|
| ** |
|
||||||
|
| ** |
|
||||||
|
| ** |
|
||||||
|
| ** |
|
||||||
|
| ** |
|
||||||
|
| ** |
|
||||||
|
| ** |
|
||||||
|
| ** |
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
+--------+ */
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
0xfe,
|
||||||
|
0xc6,
|
||||||
|
0x06,
|
||||||
|
0x0c,
|
||||||
|
0x18,
|
||||||
|
0x30,
|
||||||
|
0x30,
|
||||||
|
0x30,
|
||||||
|
0x30,
|
||||||
|
0x30,
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
|
||||||
|
/* Character 8 (0x38):
|
||||||
|
ht=16, width=8
|
||||||
|
+--------+
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
| ***** |
|
||||||
|
|** ** |
|
||||||
|
|** ** |
|
||||||
|
|** ** |
|
||||||
|
| ***** |
|
||||||
|
|** ** |
|
||||||
|
|** ** |
|
||||||
|
|** ** |
|
||||||
|
|** ** |
|
||||||
|
| ***** |
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
+--------+ */
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
0x7c,
|
||||||
|
0xc6,
|
||||||
|
0xc6,
|
||||||
|
0xc6,
|
||||||
|
0x7c,
|
||||||
|
0xc6,
|
||||||
|
0xc6,
|
||||||
|
0xc6,
|
||||||
|
0xc6,
|
||||||
|
0x7c,
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
|
||||||
|
/* Character 9 (0x39):
|
||||||
|
ht=16, width=8
|
||||||
|
+--------+
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
| ***** |
|
||||||
|
|** ** |
|
||||||
|
|** ** |
|
||||||
|
|** ** |
|
||||||
|
|** ** |
|
||||||
|
| ****** |
|
||||||
|
| ** |
|
||||||
|
| ** |
|
||||||
|
|** ** |
|
||||||
|
| ***** |
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
+--------+ */
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
0x7c,
|
||||||
|
0xc6,
|
||||||
|
0xc6,
|
||||||
|
0xc6,
|
||||||
|
0xc6,
|
||||||
|
0x7e,
|
||||||
|
0x06,
|
||||||
|
0x06,
|
||||||
|
0xc6,
|
||||||
|
0x7c,
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
/* Character : (0x3a):
|
||||||
|
ht=16, width=8
|
||||||
|
+--------+
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
| ** |
|
||||||
|
| ** |
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
| ** |
|
||||||
|
| ** |
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
+--------+ */
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
0x0c,
|
||||||
|
0x0c,
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
0x0c,
|
||||||
|
0x0c,
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
};
|
|
@ -53,10 +53,11 @@
|
||||||
#include <linux/videodev.h>
|
#include <linux/videodev.h>
|
||||||
#include <linux/videodev2.h>
|
#include <linux/videodev2.h>
|
||||||
#include <media/v4l2-common.h>
|
#include <media/v4l2-common.h>
|
||||||
#include <media/audiochip.h>
|
#include <media/tvaudio.h>
|
||||||
|
#include <media/msp3400.h>
|
||||||
#include <linux/kthread.h>
|
#include <linux/kthread.h>
|
||||||
#include <linux/suspend.h>
|
#include <linux/suspend.h>
|
||||||
#include "msp3400.h"
|
#include "msp3400-driver.h"
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
@ -245,31 +246,31 @@ int msp_write_dsp(struct i2c_client *client, int addr, int val)
|
||||||
* ----------------------------------------------------------------------- */
|
* ----------------------------------------------------------------------- */
|
||||||
|
|
||||||
static int scarts[3][9] = {
|
static int scarts[3][9] = {
|
||||||
/* MASK IN1 IN2 IN1_DA IN2_DA IN3 IN4 MONO MUTE */
|
/* MASK IN1 IN2 IN3 IN4 IN1_DA IN2_DA MONO MUTE */
|
||||||
/* SCART DSP Input select */
|
/* SCART DSP Input select */
|
||||||
{ 0x0320, 0x0000, 0x0200, -1, -1, 0x0300, 0x0020, 0x0100, 0x0320 },
|
{ 0x0320, 0x0000, 0x0200, 0x0300, 0x0020, -1, -1, 0x0100, 0x0320 },
|
||||||
/* SCART1 Output select */
|
/* SCART1 Output select */
|
||||||
{ 0x0c40, 0x0440, 0x0400, 0x0c00, 0x0040, 0x0000, 0x0840, 0x0800, 0x0c40 },
|
{ 0x0c40, 0x0440, 0x0400, 0x0000, 0x0840, 0x0c00, 0x0040, 0x0800, 0x0c40 },
|
||||||
/* SCART2 Output select */
|
/* SCART2 Output select */
|
||||||
{ 0x3080, 0x1000, 0x1080, 0x0000, 0x0080, 0x2080, 0x3080, 0x2000, 0x3000 },
|
{ 0x3080, 0x1000, 0x1080, 0x2080, 0x3080, 0x0000, 0x0080, 0x2000, 0x3000 },
|
||||||
};
|
};
|
||||||
|
|
||||||
static char *scart_names[] = {
|
static char *scart_names[] = {
|
||||||
"mask", "in1", "in2", "in1 da", "in2 da", "in3", "in4", "mono", "mute"
|
"in1", "in2", "in3", "in4", "in1 da", "in2 da", "mono", "mute"
|
||||||
};
|
};
|
||||||
|
|
||||||
void msp_set_scart(struct i2c_client *client, int in, int out)
|
void msp_set_scart(struct i2c_client *client, int in, int out)
|
||||||
{
|
{
|
||||||
struct msp_state *state = i2c_get_clientdata(client);
|
struct msp_state *state = i2c_get_clientdata(client);
|
||||||
|
|
||||||
state->in_scart=in;
|
state->in_scart = in;
|
||||||
|
|
||||||
if (in >= 1 && in <= 8 && out >= 0 && out <= 2) {
|
if (in >= 0 && in <= 7 && out >= 0 && out <= 2) {
|
||||||
if (-1 == scarts[out][in])
|
if (-1 == scarts[out][in + 1])
|
||||||
return;
|
return;
|
||||||
|
|
||||||
state->acb &= ~scarts[out][SCART_MASK];
|
state->acb &= ~scarts[out][0];
|
||||||
state->acb |= scarts[out][in];
|
state->acb |= scarts[out][in + 1];
|
||||||
} else
|
} else
|
||||||
state->acb = 0xf60; /* Mute Input and SCART 1 Output */
|
state->acb = 0xf60; /* Mute Input and SCART 1 Output */
|
||||||
|
|
||||||
|
@ -336,37 +337,6 @@ void msp_set_audio(struct i2c_client *client)
|
||||||
msp_write_dsp(client, 0x0033, loudness);
|
msp_write_dsp(client, 0x0033, loudness);
|
||||||
}
|
}
|
||||||
|
|
||||||
int msp_modus(struct i2c_client *client)
|
|
||||||
{
|
|
||||||
struct msp_state *state = i2c_get_clientdata(client);
|
|
||||||
|
|
||||||
if (state->radio) {
|
|
||||||
v4l_dbg(1, msp_debug, client, "video mode selected to Radio\n");
|
|
||||||
return 0x0003;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state->v4l2_std & V4L2_STD_PAL) {
|
|
||||||
v4l_dbg(1, msp_debug, client, "video mode selected to PAL\n");
|
|
||||||
|
|
||||||
#if 1
|
|
||||||
/* experimental: not sure this works with all chip versions */
|
|
||||||
return 0x7003;
|
|
||||||
#else
|
|
||||||
/* previous value, try this if it breaks ... */
|
|
||||||
return 0x1003;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
if (state->v4l2_std & V4L2_STD_NTSC) {
|
|
||||||
v4l_dbg(1, msp_debug, client, "video mode selected to NTSC\n");
|
|
||||||
return 0x2003;
|
|
||||||
}
|
|
||||||
if (state->v4l2_std & V4L2_STD_SECAM) {
|
|
||||||
v4l_dbg(1, msp_debug, client, "video mode selected to SECAM\n");
|
|
||||||
return 0x0003;
|
|
||||||
}
|
|
||||||
return 0x0003;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------------ */
|
||||||
|
|
||||||
|
|
||||||
|
@ -585,51 +555,11 @@ static int msp_set_ctrl(struct i2c_client *client, struct v4l2_control *ctrl)
|
||||||
static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
|
static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
|
||||||
{
|
{
|
||||||
struct msp_state *state = i2c_get_clientdata(client);
|
struct msp_state *state = i2c_get_clientdata(client);
|
||||||
u16 *sarg = arg;
|
|
||||||
int scart = 0;
|
|
||||||
|
|
||||||
if (msp_debug >= 2)
|
if (msp_debug >= 2)
|
||||||
v4l_i2c_print_ioctl(client, cmd);
|
v4l_i2c_print_ioctl(client, cmd);
|
||||||
|
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case AUDC_SET_INPUT:
|
|
||||||
if (*sarg == state->input)
|
|
||||||
break;
|
|
||||||
state->input = *sarg;
|
|
||||||
switch (*sarg) {
|
|
||||||
case AUDIO_RADIO:
|
|
||||||
/* Hauppauge uses IN2 for the radio */
|
|
||||||
state->mode = MSP_MODE_FM_RADIO;
|
|
||||||
scart = SCART_IN2;
|
|
||||||
break;
|
|
||||||
case AUDIO_EXTERN_1:
|
|
||||||
/* IN1 is often used for external input ... */
|
|
||||||
state->mode = MSP_MODE_EXTERN;
|
|
||||||
scart = SCART_IN1;
|
|
||||||
break;
|
|
||||||
case AUDIO_EXTERN_2:
|
|
||||||
/* ... sometimes it is IN2 through ;) */
|
|
||||||
state->mode = MSP_MODE_EXTERN;
|
|
||||||
scart = SCART_IN2;
|
|
||||||
break;
|
|
||||||
case AUDIO_TUNER:
|
|
||||||
state->mode = -1;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
if (*sarg & AUDIO_MUTE)
|
|
||||||
msp_set_scart(client, SCART_MUTE, 0);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (scart) {
|
|
||||||
state->rxsubchans = V4L2_TUNER_SUB_STEREO;
|
|
||||||
msp_set_scart(client, scart, 0);
|
|
||||||
msp_write_dsp(client, 0x000d, 0x1900);
|
|
||||||
if (state->opmode != OPMODE_AUTOSELECT)
|
|
||||||
msp_set_audmode(client);
|
|
||||||
}
|
|
||||||
msp_wake_thread(client);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case AUDC_SET_RADIO:
|
case AUDC_SET_RADIO:
|
||||||
if (state->radio)
|
if (state->radio)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -692,6 +622,7 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
|
||||||
|
|
||||||
if (va->mode != 0 && state->radio == 0) {
|
if (va->mode != 0 && state->radio == 0) {
|
||||||
state->audmode = msp_mode_v4l1_to_v4l2(va->mode);
|
state->audmode = msp_mode_v4l1_to_v4l2(va->mode);
|
||||||
|
msp_set_audmode(client);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -728,15 +659,6 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* msp34xx specific */
|
|
||||||
case MSP_SET_MATRIX:
|
|
||||||
{
|
|
||||||
struct msp_matrix *mspm = arg;
|
|
||||||
|
|
||||||
msp_set_scart(client, mspm->input, mspm->output);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --- v4l2 ioctls --- */
|
/* --- v4l2 ioctls --- */
|
||||||
case VIDIOC_S_STD:
|
case VIDIOC_S_STD:
|
||||||
{
|
{
|
||||||
|
@ -750,90 +672,34 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
case VIDIOC_ENUMINPUT:
|
case VIDIOC_INT_G_AUDIO_ROUTING:
|
||||||
{
|
{
|
||||||
struct v4l2_input *i = arg;
|
struct v4l2_routing *rt = arg;
|
||||||
|
|
||||||
if (i->index != 0)
|
*rt = state->routing;
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
i->type = V4L2_INPUT_TYPE_TUNER;
|
|
||||||
switch (i->index) {
|
|
||||||
case AUDIO_RADIO:
|
|
||||||
strcpy(i->name, "Radio");
|
|
||||||
break;
|
|
||||||
case AUDIO_EXTERN_1:
|
|
||||||
strcpy(i->name, "Extern 1");
|
|
||||||
break;
|
|
||||||
case AUDIO_EXTERN_2:
|
|
||||||
strcpy(i->name, "Extern 2");
|
|
||||||
break;
|
|
||||||
case AUDIO_TUNER:
|
|
||||||
strcpy(i->name, "Television");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
case VIDIOC_G_AUDIO:
|
|
||||||
{
|
|
||||||
struct v4l2_audio *a = arg;
|
|
||||||
|
|
||||||
memset(a, 0, sizeof(*a));
|
|
||||||
|
|
||||||
switch (a->index) {
|
|
||||||
case AUDIO_RADIO:
|
|
||||||
strcpy(a->name, "Radio");
|
|
||||||
break;
|
|
||||||
case AUDIO_EXTERN_1:
|
|
||||||
strcpy(a->name, "Extern 1");
|
|
||||||
break;
|
|
||||||
case AUDIO_EXTERN_2:
|
|
||||||
strcpy(a->name, "Extern 2");
|
|
||||||
break;
|
|
||||||
case AUDIO_TUNER:
|
|
||||||
strcpy(a->name, "Television");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
a->capability = V4L2_AUDCAP_STEREO;
|
|
||||||
a->mode = 0; /* TODO: add support for AVL */
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case VIDIOC_S_AUDIO:
|
case VIDIOC_INT_S_AUDIO_ROUTING:
|
||||||
{
|
{
|
||||||
struct v4l2_audio *sarg = arg;
|
struct v4l2_routing *rt = arg;
|
||||||
|
int tuner = (rt->input >> 3) & 1;
|
||||||
|
int sc_in = rt->input & 0x7;
|
||||||
|
int sc1_out = rt->output & 0xf;
|
||||||
|
int sc2_out = (rt->output >> 4) & 0xf;
|
||||||
|
u16 val;
|
||||||
|
|
||||||
switch (sarg->index) {
|
state->routing = *rt;
|
||||||
case AUDIO_RADIO:
|
if (state->opmode == OPMODE_AUTOSELECT) {
|
||||||
/* Hauppauge uses IN2 for the radio */
|
val = msp_read_dem(client, 0x30) & ~0x100;
|
||||||
state->mode = MSP_MODE_FM_RADIO;
|
msp_write_dem(client, 0x30, val | (tuner ? 0x100 : 0));
|
||||||
scart = SCART_IN2;
|
} else {
|
||||||
break;
|
val = msp_read_dem(client, 0xbb) & ~0x100;
|
||||||
case AUDIO_EXTERN_1:
|
msp_write_dem(client, 0xbb, val | (tuner ? 0x100 : 0));
|
||||||
/* IN1 is often used for external input ... */
|
|
||||||
state->mode = MSP_MODE_EXTERN;
|
|
||||||
scart = SCART_IN1;
|
|
||||||
break;
|
|
||||||
case AUDIO_EXTERN_2:
|
|
||||||
/* ... sometimes it is IN2 through ;) */
|
|
||||||
state->mode = MSP_MODE_EXTERN;
|
|
||||||
scart = SCART_IN2;
|
|
||||||
break;
|
|
||||||
case AUDIO_TUNER:
|
|
||||||
state->mode = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (scart) {
|
|
||||||
state->rxsubchans = V4L2_TUNER_SUB_STEREO;
|
|
||||||
msp_set_scart(client, scart, 0);
|
|
||||||
msp_write_dsp(client, 0x000d, 0x1900);
|
|
||||||
}
|
}
|
||||||
|
msp_set_scart(client, sc_in, 0);
|
||||||
|
msp_set_scart(client, sc1_out, 1);
|
||||||
|
msp_set_scart(client, sc2_out, 2);
|
||||||
msp_set_audmode(client);
|
msp_set_audmode(client);
|
||||||
msp_wake_thread(client);
|
msp_wake_thread(client);
|
||||||
break;
|
break;
|
||||||
|
@ -866,42 +732,6 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case VIDIOC_G_AUDOUT:
|
|
||||||
{
|
|
||||||
struct v4l2_audioout *a = (struct v4l2_audioout *)arg;
|
|
||||||
int idx = a->index;
|
|
||||||
|
|
||||||
memset(a, 0, sizeof(*a));
|
|
||||||
|
|
||||||
switch (idx) {
|
|
||||||
case 0:
|
|
||||||
strcpy(a->name, "Scart1 Out");
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
strcpy(a->name, "Scart2 Out");
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
strcpy(a->name, "I2S Out");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case VIDIOC_S_AUDOUT:
|
|
||||||
{
|
|
||||||
struct v4l2_audioout *a = (struct v4l2_audioout *)arg;
|
|
||||||
|
|
||||||
if (a->index < 0 || a->index > 2)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
v4l_dbg(1, msp_debug, client, "Setting audio out on msp34xx to input %i\n", a->index);
|
|
||||||
msp_set_scart(client, state->in_scart, a->index + 1);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case VIDIOC_INT_I2S_CLOCK_FREQ:
|
case VIDIOC_INT_I2S_CLOCK_FREQ:
|
||||||
{
|
{
|
||||||
u32 *a = (u32 *)arg;
|
u32 *a = (u32 *)arg;
|
||||||
|
@ -979,12 +809,16 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
|
||||||
(state->rxsubchans & V4L2_TUNER_SUB_STEREO) ? "stereo" : "mono",
|
(state->rxsubchans & V4L2_TUNER_SUB_STEREO) ? "stereo" : "mono",
|
||||||
(state->rxsubchans & V4L2_TUNER_SUB_LANG2) ? ", dual" : "");
|
(state->rxsubchans & V4L2_TUNER_SUB_LANG2) ? ", dual" : "");
|
||||||
} else {
|
} else {
|
||||||
v4l_info(client, "Mode: %s\n", p);
|
if (state->opmode == OPMODE_AUTODETECT)
|
||||||
|
v4l_info(client, "Mode: %s\n", p);
|
||||||
v4l_info(client, "Standard: %s (%s%s)\n",
|
v4l_info(client, "Standard: %s (%s%s)\n",
|
||||||
msp_standard_std_name(state->std),
|
msp_standard_std_name(state->std),
|
||||||
(state->rxsubchans & V4L2_TUNER_SUB_STEREO) ? "stereo" : "mono",
|
(state->rxsubchans & V4L2_TUNER_SUB_STEREO) ? "stereo" : "mono",
|
||||||
(state->rxsubchans & V4L2_TUNER_SUB_LANG2) ? ", dual" : "");
|
(state->rxsubchans & V4L2_TUNER_SUB_LANG2) ? ", dual" : "");
|
||||||
}
|
}
|
||||||
|
v4l_info(client, "Audmode: 0x%04x\n", state->audmode);
|
||||||
|
v4l_info(client, "Routing: 0x%08x (input) 0x%08x (output)\n",
|
||||||
|
state->routing.input, state->routing.output);
|
||||||
v4l_info(client, "ACB: 0x%04x\n", state->acb);
|
v4l_info(client, "ACB: 0x%04x\n", state->acb);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1063,6 +897,9 @@ static int msp_attach(struct i2c_adapter *adapter, int address, int kind)
|
||||||
state->muted = 0;
|
state->muted = 0;
|
||||||
state->i2s_mode = 0;
|
state->i2s_mode = 0;
|
||||||
init_waitqueue_head(&state->wq);
|
init_waitqueue_head(&state->wq);
|
||||||
|
/* These are the reset input/output positions */
|
||||||
|
state->routing.input = MSP_INPUT_DEFAULT;
|
||||||
|
state->routing.output = MSP_OUTPUT_DEFAULT;
|
||||||
|
|
||||||
state->rev1 = msp_read_dsp(client, 0x1e);
|
state->rev1 = msp_read_dsp(client, 0x1e);
|
||||||
if (state->rev1 != -1)
|
if (state->rev1 != -1)
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
/*
|
/*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef MSP3400_H
|
#ifndef MSP3400_DRIVER_H
|
||||||
#define MSP3400_H
|
#define MSP3400_DRIVER_H
|
||||||
|
|
||||||
|
#include <media/msp3400.h>
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
@ -20,15 +22,14 @@
|
||||||
#define MSP_MODE_BTSC 8
|
#define MSP_MODE_BTSC 8
|
||||||
#define MSP_MODE_EXTERN 9
|
#define MSP_MODE_EXTERN 9
|
||||||
|
|
||||||
#define SCART_MASK 0
|
#define SCART_IN1 0
|
||||||
#define SCART_IN1 1
|
#define SCART_IN2 1
|
||||||
#define SCART_IN2 2
|
#define SCART_IN3 2
|
||||||
#define SCART_IN1_DA 3
|
#define SCART_IN4 3
|
||||||
#define SCART_IN2_DA 4
|
#define SCART_IN1_DA 4
|
||||||
#define SCART_IN3 5
|
#define SCART_IN2_DA 5
|
||||||
#define SCART_IN4 6
|
#define SCART_MONO 6
|
||||||
#define SCART_MONO 7
|
#define SCART_MUTE 7
|
||||||
#define SCART_MUTE 8
|
|
||||||
|
|
||||||
#define SCART_DSP_IN 0
|
#define SCART_DSP_IN 0
|
||||||
#define SCART1_OUT 1
|
#define SCART1_OUT 1
|
||||||
|
@ -73,7 +74,7 @@ struct msp_state {
|
||||||
int i2s_mode;
|
int i2s_mode;
|
||||||
int main, second; /* sound carrier */
|
int main, second; /* sound carrier */
|
||||||
int input;
|
int input;
|
||||||
int source; /* see msp34xxg_set_source */
|
struct v4l2_routing routing;
|
||||||
|
|
||||||
/* v4l2 */
|
/* v4l2 */
|
||||||
int audmode;
|
int audmode;
|
||||||
|
@ -99,17 +100,16 @@ int msp_reset(struct i2c_client *client);
|
||||||
void msp_set_scart(struct i2c_client *client, int in, int out);
|
void msp_set_scart(struct i2c_client *client, int in, int out);
|
||||||
void msp_set_mute(struct i2c_client *client);
|
void msp_set_mute(struct i2c_client *client);
|
||||||
void msp_set_audio(struct i2c_client *client);
|
void msp_set_audio(struct i2c_client *client);
|
||||||
int msp_modus(struct i2c_client *client);
|
|
||||||
int msp_sleep(struct msp_state *state, int timeout);
|
int msp_sleep(struct msp_state *state, int timeout);
|
||||||
|
|
||||||
/* msp3400-kthreads.c */
|
/* msp3400-kthreads.c */
|
||||||
const char *msp_standard_std_name(int std);
|
const char *msp_standard_std_name(int std);
|
||||||
void msp_set_audmode(struct i2c_client *client);
|
void msp_set_audmode(struct i2c_client *client);
|
||||||
void msp_detect_stereo(struct i2c_client *client);
|
int msp_detect_stereo(struct i2c_client *client);
|
||||||
int msp3400c_thread(void *data);
|
int msp3400c_thread(void *data);
|
||||||
int msp3410d_thread(void *data);
|
int msp3410d_thread(void *data);
|
||||||
int msp34xxg_thread(void *data);
|
int msp34xxg_thread(void *data);
|
||||||
void msp3400c_set_mode(struct i2c_client *client, int mode);
|
void msp3400c_set_mode(struct i2c_client *client, int mode);
|
||||||
void msp3400c_set_carrier(struct i2c_client *client, int cdo1, int cdo2);
|
void msp3400c_set_carrier(struct i2c_client *client, int cdo1, int cdo2);
|
||||||
|
|
||||||
#endif /* MSP3400_H */
|
#endif /* MSP3400_DRIVER_H */
|
|
@ -26,10 +26,10 @@
|
||||||
#include <linux/videodev.h>
|
#include <linux/videodev.h>
|
||||||
#include <linux/videodev2.h>
|
#include <linux/videodev2.h>
|
||||||
#include <media/v4l2-common.h>
|
#include <media/v4l2-common.h>
|
||||||
#include <media/audiochip.h>
|
#include <media/msp3400.h>
|
||||||
#include <linux/kthread.h>
|
#include <linux/kthread.h>
|
||||||
#include <linux/suspend.h>
|
#include <linux/suspend.h>
|
||||||
#include "msp3400.h"
|
#include "msp3400-driver.h"
|
||||||
|
|
||||||
/* this one uses the automatic sound standard detection of newer msp34xx
|
/* this one uses the automatic sound standard detection of newer msp34xx
|
||||||
chip versions */
|
chip versions */
|
||||||
|
@ -45,11 +45,13 @@ static struct {
|
||||||
{ 0x0004, MSP_CARRIER(6.5), MSP_CARRIER(6.2578125), "6.5/6.25 D/K1 Dual FM-Stereo" },
|
{ 0x0004, MSP_CARRIER(6.5), MSP_CARRIER(6.2578125), "6.5/6.25 D/K1 Dual FM-Stereo" },
|
||||||
{ 0x0005, MSP_CARRIER(6.5), MSP_CARRIER(6.7421875), "6.5/6.74 D/K2 Dual FM-Stereo" },
|
{ 0x0005, MSP_CARRIER(6.5), MSP_CARRIER(6.7421875), "6.5/6.74 D/K2 Dual FM-Stereo" },
|
||||||
{ 0x0006, MSP_CARRIER(6.5), MSP_CARRIER(6.5), "6.5 D/K FM-Mono (HDEV3)" },
|
{ 0x0006, MSP_CARRIER(6.5), MSP_CARRIER(6.5), "6.5 D/K FM-Mono (HDEV3)" },
|
||||||
|
{ 0x0007, MSP_CARRIER(6.5), MSP_CARRIER(5.7421875), "6.5/5.74 D/K3 Dual FM-Stereo" },
|
||||||
{ 0x0008, MSP_CARRIER(5.5), MSP_CARRIER(5.85), "5.5/5.85 B/G NICAM FM" },
|
{ 0x0008, MSP_CARRIER(5.5), MSP_CARRIER(5.85), "5.5/5.85 B/G NICAM FM" },
|
||||||
{ 0x0009, MSP_CARRIER(6.5), MSP_CARRIER(5.85), "6.5/5.85 L NICAM AM" },
|
{ 0x0009, MSP_CARRIER(6.5), MSP_CARRIER(5.85), "6.5/5.85 L NICAM AM" },
|
||||||
{ 0x000a, MSP_CARRIER(6.0), MSP_CARRIER(6.55), "6.0/6.55 I NICAM FM" },
|
{ 0x000a, MSP_CARRIER(6.0), MSP_CARRIER(6.55), "6.0/6.55 I NICAM FM" },
|
||||||
{ 0x000b, MSP_CARRIER(6.5), MSP_CARRIER(5.85), "6.5/5.85 D/K NICAM FM" },
|
{ 0x000b, MSP_CARRIER(6.5), MSP_CARRIER(5.85), "6.5/5.85 D/K NICAM FM" },
|
||||||
{ 0x000c, MSP_CARRIER(6.5), MSP_CARRIER(5.85), "6.5/5.85 D/K NICAM FM (HDEV2)" },
|
{ 0x000c, MSP_CARRIER(6.5), MSP_CARRIER(5.85), "6.5/5.85 D/K NICAM FM (HDEV2)" },
|
||||||
|
{ 0x000d, MSP_CARRIER(6.5), MSP_CARRIER(5.85), "6.5/5.85 D/K NICAM FM (HDEV3)" },
|
||||||
{ 0x0020, MSP_CARRIER(4.5), MSP_CARRIER(4.5), "4.5 M BTSC-Stereo" },
|
{ 0x0020, MSP_CARRIER(4.5), MSP_CARRIER(4.5), "4.5 M BTSC-Stereo" },
|
||||||
{ 0x0021, MSP_CARRIER(4.5), MSP_CARRIER(4.5), "4.5 M BTSC-Mono + SAP" },
|
{ 0x0021, MSP_CARRIER(4.5), MSP_CARRIER(4.5), "4.5 M BTSC-Mono + SAP" },
|
||||||
{ 0x0030, MSP_CARRIER(4.5), MSP_CARRIER(4.5), "4.5 M EIA-J Japan Stereo" },
|
{ 0x0030, MSP_CARRIER(4.5), MSP_CARRIER(4.5), "4.5 M EIA-J Japan Stereo" },
|
||||||
|
@ -185,13 +187,14 @@ void msp3400c_set_mode(struct i2c_client *client, int mode)
|
||||||
{
|
{
|
||||||
struct msp_state *state = i2c_get_clientdata(client);
|
struct msp_state *state = i2c_get_clientdata(client);
|
||||||
struct msp3400c_init_data_dem *data = &msp3400c_init_data[mode];
|
struct msp3400c_init_data_dem *data = &msp3400c_init_data[mode];
|
||||||
|
int tuner = (state->routing.input >> 3) & 1;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
v4l_dbg(1, msp_debug, client, "set_mode: %d\n", mode);
|
v4l_dbg(1, msp_debug, client, "set_mode: %d\n", mode);
|
||||||
state->mode = mode;
|
state->mode = mode;
|
||||||
state->rxsubchans = V4L2_TUNER_SUB_MONO;
|
state->rxsubchans = V4L2_TUNER_SUB_MONO;
|
||||||
|
|
||||||
msp_write_dem(client, 0x00bb, data->ad_cv);
|
msp_write_dem(client, 0x00bb, data->ad_cv | (tuner ? 0x100 : 0));
|
||||||
|
|
||||||
for (i = 5; i >= 0; i--) /* fir 1 */
|
for (i = 5; i >= 0; i--) /* fir 1 */
|
||||||
msp_write_dem(client, 0x0001, data->fir1[i]);
|
msp_write_dem(client, 0x0001, data->fir1[i]);
|
||||||
|
@ -207,21 +210,22 @@ void msp3400c_set_mode(struct i2c_client *client, int mode)
|
||||||
msp3400c_set_carrier(client, data->cdo1, data->cdo2);
|
msp3400c_set_carrier(client, data->cdo1, data->cdo2);
|
||||||
|
|
||||||
msp_set_source(client, data->dsp_src);
|
msp_set_source(client, data->dsp_src);
|
||||||
msp_write_dsp(client, 0x000e, data->dsp_matrix);
|
/* set prescales */
|
||||||
|
|
||||||
if (state->has_nicam) {
|
/* volume prescale for SCART (AM mono input) */
|
||||||
/* nicam prescale */
|
msp_write_dsp(client, 0x000d, 0x1900);
|
||||||
msp_write_dsp(client, 0x0010, 0x5a00); /* was: 0x3000 */
|
msp_write_dsp(client, 0x000e, data->dsp_matrix);
|
||||||
}
|
if (state->has_nicam) /* nicam prescale */
|
||||||
|
msp_write_dsp(client, 0x0010, 0x5a00);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set audio mode. Note that the pre-'G' models do not support BTSC+SAP,
|
/* Set audio mode. Note that the pre-'G' models do not support BTSC+SAP,
|
||||||
nor do they support stereo BTSC. */
|
nor do they support stereo BTSC. */
|
||||||
static void msp3400c_set_audmode(struct i2c_client *client)
|
static void msp3400c_set_audmode(struct i2c_client *client)
|
||||||
{
|
{
|
||||||
static char *strmode[] = { "mono", "stereo", "lang2", "lang1" };
|
static char *strmode[] = { "mono", "stereo", "lang2", "lang1", "lang1+lang2" };
|
||||||
struct msp_state *state = i2c_get_clientdata(client);
|
struct msp_state *state = i2c_get_clientdata(client);
|
||||||
char *modestr = (state->audmode >= 0 && state->audmode < 4) ?
|
char *modestr = (state->audmode >= 0 && state->audmode < 5) ?
|
||||||
strmode[state->audmode] : "unknown";
|
strmode[state->audmode] : "unknown";
|
||||||
int src = 0; /* channel source: FM/AM, nicam or SCART */
|
int src = 0; /* channel source: FM/AM, nicam or SCART */
|
||||||
|
|
||||||
|
@ -246,6 +250,7 @@ static void msp3400c_set_audmode(struct i2c_client *client)
|
||||||
case V4L2_TUNER_MODE_MONO:
|
case V4L2_TUNER_MODE_MONO:
|
||||||
case V4L2_TUNER_MODE_LANG1:
|
case V4L2_TUNER_MODE_LANG1:
|
||||||
case V4L2_TUNER_MODE_LANG2:
|
case V4L2_TUNER_MODE_LANG2:
|
||||||
|
case V4L2_TUNER_MODE_LANG1_LANG2:
|
||||||
msp_write_dsp(client, 0x000e, 0x3000);
|
msp_write_dsp(client, 0x000e, 0x3000);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -257,6 +262,7 @@ static void msp3400c_set_audmode(struct i2c_client *client)
|
||||||
msp3400c_set_carrier(client, MSP_CARRIER(6.5), MSP_CARRIER(6.5));
|
msp3400c_set_carrier(client, MSP_CARRIER(6.5), MSP_CARRIER(6.5));
|
||||||
break;
|
break;
|
||||||
case V4L2_TUNER_MODE_STEREO:
|
case V4L2_TUNER_MODE_STEREO:
|
||||||
|
case V4L2_TUNER_MODE_LANG1_LANG2:
|
||||||
msp3400c_set_carrier(client, MSP_CARRIER(7.2), MSP_CARRIER(7.02));
|
msp3400c_set_carrier(client, MSP_CARRIER(7.2), MSP_CARRIER(7.02));
|
||||||
break;
|
break;
|
||||||
case V4L2_TUNER_MODE_LANG1:
|
case V4L2_TUNER_MODE_LANG1:
|
||||||
|
@ -271,7 +277,6 @@ static void msp3400c_set_audmode(struct i2c_client *client)
|
||||||
case MSP_MODE_FM_NICAM2:
|
case MSP_MODE_FM_NICAM2:
|
||||||
case MSP_MODE_AM_NICAM:
|
case MSP_MODE_AM_NICAM:
|
||||||
v4l_dbg(1, msp_debug, client, "NICAM set_audmode: %s\n",modestr);
|
v4l_dbg(1, msp_debug, client, "NICAM set_audmode: %s\n",modestr);
|
||||||
msp3400c_set_carrier(client, state->second, state->main);
|
|
||||||
if (state->nicam_on)
|
if (state->nicam_on)
|
||||||
src = 0x0100; /* NICAM */
|
src = 0x0100; /* NICAM */
|
||||||
break;
|
break;
|
||||||
|
@ -293,6 +298,7 @@ static void msp3400c_set_audmode(struct i2c_client *client)
|
||||||
/* switch audio */
|
/* switch audio */
|
||||||
switch (state->audmode) {
|
switch (state->audmode) {
|
||||||
case V4L2_TUNER_MODE_STEREO:
|
case V4L2_TUNER_MODE_STEREO:
|
||||||
|
case V4L2_TUNER_MODE_LANG1_LANG2:
|
||||||
src |= 0x0020;
|
src |= 0x0020;
|
||||||
break;
|
break;
|
||||||
case V4L2_TUNER_MODE_MONO:
|
case V4L2_TUNER_MODE_MONO:
|
||||||
|
@ -427,8 +433,8 @@ static void watch_stereo(struct i2c_client *client)
|
||||||
{
|
{
|
||||||
struct msp_state *state = i2c_get_clientdata(client);
|
struct msp_state *state = i2c_get_clientdata(client);
|
||||||
|
|
||||||
if (msp3400c_detect_stereo(client)) {
|
if (msp_detect_stereo(client)) {
|
||||||
msp3400c_set_audmode(client);
|
msp_set_audmode(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (msp_once)
|
if (msp_once)
|
||||||
|
@ -464,7 +470,7 @@ int msp3400c_thread(void *data)
|
||||||
|
|
||||||
/* mute */
|
/* mute */
|
||||||
msp_set_mute(client);
|
msp_set_mute(client);
|
||||||
msp3400c_set_mode(client, MSP_MODE_AM_DETECT /* +1 */ );
|
msp3400c_set_mode(client, MSP_MODE_AM_DETECT);
|
||||||
val1 = val2 = 0;
|
val1 = val2 = 0;
|
||||||
max1 = max2 = -1;
|
max1 = max2 = -1;
|
||||||
state->watch_stereo = 0;
|
state->watch_stereo = 0;
|
||||||
|
@ -572,8 +578,6 @@ int msp3400c_thread(void *data)
|
||||||
state->second = msp3400c_carrier_detect_65[max2].cdo;
|
state->second = msp3400c_carrier_detect_65[max2].cdo;
|
||||||
msp3400c_set_mode(client, MSP_MODE_AM_NICAM);
|
msp3400c_set_mode(client, MSP_MODE_AM_NICAM);
|
||||||
msp3400c_set_carrier(client, state->second, state->main);
|
msp3400c_set_carrier(client, state->second, state->main);
|
||||||
/* volume prescale for SCART (AM mono input) */
|
|
||||||
msp_write_dsp(client, 0x000d, 0x1900);
|
|
||||||
state->watch_stereo = 1;
|
state->watch_stereo = 1;
|
||||||
} else if (max2 == 0 && state->has_nicam) {
|
} else if (max2 == 0 && state->has_nicam) {
|
||||||
/* D/K NICAM */
|
/* D/K NICAM */
|
||||||
|
@ -651,7 +655,8 @@ int msp3410d_thread(void *data)
|
||||||
if (msp_sleep(state,200))
|
if (msp_sleep(state,200))
|
||||||
goto restart;
|
goto restart;
|
||||||
|
|
||||||
/* start autodetect */
|
/* start autodetect. Note: autodetect is not supported for
|
||||||
|
NTSC-M and radio, hence we force the standard in those cases. */
|
||||||
if (state->radio)
|
if (state->radio)
|
||||||
std = 0x40;
|
std = 0x40;
|
||||||
else
|
else
|
||||||
|
@ -695,23 +700,19 @@ int msp3410d_thread(void *data)
|
||||||
v4l_dbg(1, msp_debug, client, "autodetection failed,"
|
v4l_dbg(1, msp_debug, client, "autodetection failed,"
|
||||||
" switching to backup standard: %s (0x%04x)\n",
|
" switching to backup standard: %s (0x%04x)\n",
|
||||||
msp_stdlist[8].name ? msp_stdlist[8].name : "unknown",val);
|
msp_stdlist[8].name ? msp_stdlist[8].name : "unknown",val);
|
||||||
val = 0x0009;
|
state->std = val = 0x0009;
|
||||||
msp_write_dem(client, 0x20, val);
|
msp_write_dem(client, 0x20, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set various prescales */
|
|
||||||
msp_write_dsp(client, 0x0d, 0x1900); /* scart */
|
|
||||||
msp_write_dsp(client, 0x0e, 0x2403); /* FM */
|
|
||||||
msp_write_dsp(client, 0x10, 0x5a00); /* nicam */
|
|
||||||
|
|
||||||
/* set stereo */
|
/* set stereo */
|
||||||
switch (val) {
|
switch (val) {
|
||||||
case 0x0008: /* B/G NICAM */
|
case 0x0008: /* B/G NICAM */
|
||||||
case 0x000a: /* I NICAM */
|
case 0x000a: /* I NICAM */
|
||||||
if (val == 0x0008)
|
case 0x000b: /* D/K NICAM */
|
||||||
state->mode = MSP_MODE_FM_NICAM1;
|
if (val == 0x000a)
|
||||||
else
|
|
||||||
state->mode = MSP_MODE_FM_NICAM2;
|
state->mode = MSP_MODE_FM_NICAM2;
|
||||||
|
else
|
||||||
|
state->mode = MSP_MODE_FM_NICAM1;
|
||||||
/* just turn on stereo */
|
/* just turn on stereo */
|
||||||
state->rxsubchans = V4L2_TUNER_SUB_STEREO;
|
state->rxsubchans = V4L2_TUNER_SUB_STEREO;
|
||||||
state->nicam_on = 1;
|
state->nicam_on = 1;
|
||||||
|
@ -739,6 +740,7 @@ int msp3410d_thread(void *data)
|
||||||
/* scart routing (this doesn't belong here I think) */
|
/* scart routing (this doesn't belong here I think) */
|
||||||
msp_set_scart(client,SCART_IN2,0);
|
msp_set_scart(client,SCART_IN2,0);
|
||||||
break;
|
break;
|
||||||
|
case 0x0002:
|
||||||
case 0x0003:
|
case 0x0003:
|
||||||
case 0x0004:
|
case 0x0004:
|
||||||
case 0x0005:
|
case 0x0005:
|
||||||
|
@ -748,12 +750,19 @@ int msp3410d_thread(void *data)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* unmute, restore misc registers */
|
/* set various prescales */
|
||||||
msp_set_audio(client);
|
msp_write_dsp(client, 0x0d, 0x1900); /* scart */
|
||||||
msp_write_dsp(client, 0x13, state->acb);
|
msp_write_dsp(client, 0x0e, 0x3000); /* FM */
|
||||||
|
if (state->has_nicam)
|
||||||
|
msp_write_dsp(client, 0x10, 0x5a00); /* nicam */
|
||||||
|
|
||||||
if (state->has_i2s_conf)
|
if (state->has_i2s_conf)
|
||||||
msp_write_dem(client, 0x40, state->i2s_mode);
|
msp_write_dem(client, 0x40, state->i2s_mode);
|
||||||
|
|
||||||
|
/* unmute, restore misc registers */
|
||||||
|
msp_set_audio(client);
|
||||||
|
|
||||||
|
msp_write_dsp(client, 0x13, state->acb);
|
||||||
msp3400c_set_audmode(client);
|
msp3400c_set_audmode(client);
|
||||||
|
|
||||||
/* monitor tv audio mode, the first time don't wait
|
/* monitor tv audio mode, the first time don't wait
|
||||||
|
@ -772,97 +781,154 @@ int msp3410d_thread(void *data)
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------- */
|
/* ----------------------------------------------------------------------- */
|
||||||
|
|
||||||
/* msp34xxG + (autoselect no-thread) */
|
/* msp34xxG + (autoselect no-thread)
|
||||||
/* this one uses both automatic standard detection and automatic sound */
|
* this one uses both automatic standard detection and automatic sound
|
||||||
/* select which are available in the newer G versions */
|
* select which are available in the newer G versions
|
||||||
/* struct msp: only norm, acb and source are really used in this mode */
|
* struct msp: only norm, acb and source are really used in this mode
|
||||||
|
|
||||||
/* set the same 'source' for the loudspeaker, scart and quasi-peak detector
|
|
||||||
* the value for source is the same as bit 15:8 of DSP registers 0x08,
|
|
||||||
* 0x0a and 0x0c: 0=mono, 1=stereo or A|B, 2=SCART, 3=stereo or A, 4=stereo or B
|
|
||||||
*
|
|
||||||
* this function replaces msp3400c_set_audmode
|
|
||||||
*/
|
*/
|
||||||
static void msp34xxg_set_source(struct i2c_client *client, int source)
|
|
||||||
|
static int msp34xxg_modus(struct i2c_client *client)
|
||||||
{
|
{
|
||||||
struct msp_state *state = i2c_get_clientdata(client);
|
struct msp_state *state = i2c_get_clientdata(client);
|
||||||
|
|
||||||
/* fix matrix mode to stereo and let the msp choose what
|
if (state->radio) {
|
||||||
* to output according to 'source', as recommended
|
v4l_dbg(1, msp_debug, client, "selected radio modus\n");
|
||||||
* for MONO (source==0) downmixing set bit[7:0] to 0x30
|
return 0x0001;
|
||||||
*/
|
}
|
||||||
int value = (source & 0x07) << 8 | (source == 0 ? 0x30 : 0x20);
|
|
||||||
|
|
||||||
v4l_dbg(1, msp_debug, client, "set source to %d (0x%x)\n", source, value);
|
if (state->v4l2_std & V4L2_STD_PAL) {
|
||||||
msp_set_source(client, value);
|
v4l_dbg(1, msp_debug, client, "selected PAL modus\n");
|
||||||
/*
|
return 0x7001;
|
||||||
* set identification threshold. Personally, I
|
}
|
||||||
* I set it to a higher value that the default
|
if (state->v4l2_std == V4L2_STD_NTSC_M_JP) {
|
||||||
* of 0x190 to ignore noisy stereo signals.
|
v4l_dbg(1, msp_debug, client, "selected M (EIA-J) modus\n");
|
||||||
* this needs tuning. (recommended range 0x00a0-0x03c0)
|
return 0x4001;
|
||||||
* 0x7f0 = forced mono mode
|
}
|
||||||
*/
|
if (state->v4l2_std == V4L2_STD_NTSC_M_KR) {
|
||||||
/* a2 threshold for stereo/bilingual */
|
v4l_dbg(1, msp_debug, client, "selected M (A2) modus\n");
|
||||||
msp_write_dem(client, 0x22, msp_stereo_thresh);
|
return 0x0001;
|
||||||
state->source = source;
|
}
|
||||||
|
if (state->v4l2_std & V4L2_STD_MN) {
|
||||||
|
v4l_dbg(1, msp_debug, client, "selected M (BTSC) modus\n");
|
||||||
|
return 0x2001;
|
||||||
|
}
|
||||||
|
if (state->v4l2_std & V4L2_STD_SECAM) {
|
||||||
|
v4l_dbg(1, msp_debug, client, "selected SECAM modus\n");
|
||||||
|
return 0x6001;
|
||||||
|
}
|
||||||
|
return 0x0001;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (re-)initialize the msp34xxg, according to the current norm in state->norm
|
static void msp34xxg_set_source(struct i2c_client *client, u16 reg, int in)
|
||||||
* return 0 if it worked, -1 if it failed
|
{
|
||||||
*/
|
struct msp_state *state = i2c_get_clientdata(client);
|
||||||
static int msp34xxg_reset(struct i2c_client *client)
|
int source, matrix;
|
||||||
|
|
||||||
|
switch (state->audmode) {
|
||||||
|
case V4L2_TUNER_MODE_MONO:
|
||||||
|
source = 0; /* mono only */
|
||||||
|
matrix = 0x30;
|
||||||
|
break;
|
||||||
|
case V4L2_TUNER_MODE_LANG1:
|
||||||
|
source = 3; /* stereo or A */
|
||||||
|
matrix = 0x00;
|
||||||
|
break;
|
||||||
|
case V4L2_TUNER_MODE_LANG2:
|
||||||
|
source = 4; /* stereo or B */
|
||||||
|
matrix = 0x10;
|
||||||
|
break;
|
||||||
|
case V4L2_TUNER_MODE_STEREO:
|
||||||
|
case V4L2_TUNER_MODE_LANG1_LANG2:
|
||||||
|
default:
|
||||||
|
source = 1; /* stereo or A|B */
|
||||||
|
matrix = 0x20;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (in == MSP_DSP_OUT_TUNER)
|
||||||
|
source = (source << 8) | 0x20;
|
||||||
|
/* the msp34x2g puts the MAIN_AVC, MAIN and AUX sources in 12, 13, 14
|
||||||
|
instead of 11, 12, 13. So we add one for that msp version. */
|
||||||
|
else if (in >= MSP_DSP_OUT_MAIN_AVC && state->has_dolby_pro_logic)
|
||||||
|
source = ((in + 1) << 8) | matrix;
|
||||||
|
else
|
||||||
|
source = (in << 8) | matrix;
|
||||||
|
|
||||||
|
v4l_dbg(1, msp_debug, client, "set source to %d (0x%x) for output %02x\n",
|
||||||
|
in, source, reg);
|
||||||
|
msp_write_dsp(client, reg, source);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void msp34xxg_set_sources(struct i2c_client *client)
|
||||||
{
|
{
|
||||||
struct msp_state *state = i2c_get_clientdata(client);
|
struct msp_state *state = i2c_get_clientdata(client);
|
||||||
int modus, std;
|
u32 in = state->routing.input;
|
||||||
|
|
||||||
if (msp_reset(client))
|
msp34xxg_set_source(client, 0x0008, (in >> 4) & 0xf);
|
||||||
return -1;
|
/* quasi-peak detector is set to same input as the loudspeaker (MAIN) */
|
||||||
|
msp34xxg_set_source(client, 0x000c, (in >> 4) & 0xf);
|
||||||
|
msp34xxg_set_source(client, 0x0009, (in >> 8) & 0xf);
|
||||||
|
msp34xxg_set_source(client, 0x000a, (in >> 12) & 0xf);
|
||||||
|
if (state->has_scart23_in_scart2_out)
|
||||||
|
msp34xxg_set_source(client, 0x0041, (in >> 16) & 0xf);
|
||||||
|
msp34xxg_set_source(client, 0x000b, (in >> 20) & 0xf);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (re-)initialize the msp34xxg */
|
||||||
|
static void msp34xxg_reset(struct i2c_client *client)
|
||||||
|
{
|
||||||
|
struct msp_state *state = i2c_get_clientdata(client);
|
||||||
|
int tuner = (state->routing.input >> 3) & 1;
|
||||||
|
int modus;
|
||||||
|
|
||||||
|
/* initialize std to 1 (autodetect) to signal that no standard is
|
||||||
|
selected yet. */
|
||||||
|
state->std = 1;
|
||||||
|
|
||||||
|
msp_reset(client);
|
||||||
|
|
||||||
/* make sure that input/output is muted (paranoid mode) */
|
/* make sure that input/output is muted (paranoid mode) */
|
||||||
/* ACB, mute DSP input, mute SCART 1 */
|
/* ACB, mute DSP input, mute SCART 1 */
|
||||||
if (msp_write_dsp(client, 0x13, 0x0f20))
|
msp_write_dsp(client, 0x13, 0x0f20);
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (state->has_i2s_conf)
|
if (state->has_i2s_conf)
|
||||||
msp_write_dem(client, 0x40, state->i2s_mode);
|
msp_write_dem(client, 0x40, state->i2s_mode);
|
||||||
|
|
||||||
/* step-by-step initialisation, as described in the manual */
|
/* step-by-step initialisation, as described in the manual */
|
||||||
modus = msp_modus(client);
|
modus = msp34xxg_modus(client);
|
||||||
if (state->radio)
|
modus |= tuner ? 0x100 : 0;
|
||||||
std = 0x40;
|
msp_write_dem(client, 0x30, modus);
|
||||||
else
|
|
||||||
std = (state->v4l2_std & V4L2_STD_NTSC) ? 0x20 : 1;
|
|
||||||
modus &= ~0x03; /* STATUS_CHANGE = 0 */
|
|
||||||
modus |= 0x01; /* AUTOMATIC_SOUND_DETECTION = 1 */
|
|
||||||
if (msp_write_dem(client, 0x30, modus))
|
|
||||||
return -1;
|
|
||||||
if (msp_write_dem(client, 0x20, std))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
/* write the dsps that may have an influence on
|
/* write the dsps that may have an influence on
|
||||||
standard/audio autodetection right now */
|
standard/audio autodetection right now */
|
||||||
msp34xxg_set_source(client, state->source);
|
msp34xxg_set_sources(client);
|
||||||
|
|
||||||
/* AM/FM Prescale [15:8] 75khz deviation */
|
msp_write_dsp(client, 0x0d, 0x1900); /* scart */
|
||||||
if (msp_write_dsp(client, 0x0e, 0x3000))
|
msp_write_dsp(client, 0x0e, 0x3000); /* FM */
|
||||||
return -1;
|
if (state->has_nicam)
|
||||||
|
msp_write_dsp(client, 0x10, 0x5a00); /* nicam */
|
||||||
|
|
||||||
/* NICAM Prescale 9db gain (as recommended) */
|
/* set identification threshold. Personally, I
|
||||||
if (msp_write_dsp(client, 0x10, 0x5a00))
|
* I set it to a higher value than the default
|
||||||
return -1;
|
* of 0x190 to ignore noisy stereo signals.
|
||||||
|
* this needs tuning. (recommended range 0x00a0-0x03c0)
|
||||||
return 0;
|
* 0x7f0 = forced mono mode
|
||||||
|
*
|
||||||
|
* a2 threshold for stereo/bilingual.
|
||||||
|
* Note: this register is part of the Manual/Compatibility mode.
|
||||||
|
* It is supported by all 'G'-family chips.
|
||||||
|
*/
|
||||||
|
msp_write_dem(client, 0x22, msp_stereo_thresh);
|
||||||
}
|
}
|
||||||
|
|
||||||
int msp34xxg_thread(void *data)
|
int msp34xxg_thread(void *data)
|
||||||
{
|
{
|
||||||
struct i2c_client *client = data;
|
struct i2c_client *client = data;
|
||||||
struct msp_state *state = i2c_get_clientdata(client);
|
struct msp_state *state = i2c_get_clientdata(client);
|
||||||
int val, std, i;
|
int val, i;
|
||||||
|
|
||||||
v4l_dbg(1, msp_debug, client, "msp34xxg daemon started\n");
|
v4l_dbg(1, msp_debug, client, "msp34xxg daemon started\n");
|
||||||
|
|
||||||
state->source = 1; /* default */
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
v4l_dbg(2, msp_debug, client, "msp34xxg thread: sleep\n");
|
v4l_dbg(2, msp_debug, client, "msp34xxg thread: sleep\n");
|
||||||
msp_sleep(state, -1);
|
msp_sleep(state, -1);
|
||||||
|
@ -876,12 +942,14 @@ int msp34xxg_thread(void *data)
|
||||||
|
|
||||||
/* setup the chip*/
|
/* setup the chip*/
|
||||||
msp34xxg_reset(client);
|
msp34xxg_reset(client);
|
||||||
std = msp_standard;
|
state->std = state->radio ? 0x40 : msp_standard;
|
||||||
if (std != 0x01)
|
if (state->std != 1)
|
||||||
goto unmute;
|
goto unmute;
|
||||||
|
/* start autodetect */
|
||||||
|
msp_write_dem(client, 0x20, state->std);
|
||||||
|
|
||||||
/* watch autodetect */
|
/* watch autodetect */
|
||||||
v4l_dbg(1, msp_debug, client, "triggered autodetect, waiting for result\n");
|
v4l_dbg(1, msp_debug, client, "started autodetect, waiting for result\n");
|
||||||
for (i = 0; i < 10; i++) {
|
for (i = 0; i < 10; i++) {
|
||||||
if (msp_sleep(state, 100))
|
if (msp_sleep(state, 100))
|
||||||
goto restart;
|
goto restart;
|
||||||
|
@ -889,20 +957,19 @@ int msp34xxg_thread(void *data)
|
||||||
/* check results */
|
/* check results */
|
||||||
val = msp_read_dem(client, 0x7e);
|
val = msp_read_dem(client, 0x7e);
|
||||||
if (val < 0x07ff) {
|
if (val < 0x07ff) {
|
||||||
std = val;
|
state->std = val;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
v4l_dbg(2, msp_debug, client, "detection still in progress\n");
|
v4l_dbg(2, msp_debug, client, "detection still in progress\n");
|
||||||
}
|
}
|
||||||
if (std == 1) {
|
if (state->std == 1) {
|
||||||
v4l_dbg(1, msp_debug, client, "detection still in progress after 10 tries. giving up.\n");
|
v4l_dbg(1, msp_debug, client, "detection still in progress after 10 tries. giving up.\n");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
unmute:
|
unmute:
|
||||||
state->std = std;
|
v4l_dbg(1, msp_debug, client, "detected standard: %s (0x%04x)\n",
|
||||||
v4l_dbg(1, msp_debug, client, "current standard: %s (0x%04x)\n",
|
msp_standard_std_name(state->std), state->std);
|
||||||
msp_standard_std_name(std), std);
|
|
||||||
|
|
||||||
/* unmute: dispatch sound to scart output, set scart volume */
|
/* unmute: dispatch sound to scart output, set scart volume */
|
||||||
msp_set_audio(client);
|
msp_set_audio(client);
|
||||||
|
@ -911,20 +978,33 @@ int msp34xxg_thread(void *data)
|
||||||
if (msp_write_dsp(client, 0x13, state->acb))
|
if (msp_write_dsp(client, 0x13, state->acb))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (state->has_i2s_conf)
|
/* the periodic stereo/SAP check is only relevant for
|
||||||
msp_write_dem(client, 0x40, state->i2s_mode);
|
the 0x20 standard (BTSC) */
|
||||||
|
if (state->std != 0x20)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
state->watch_stereo = 1;
|
||||||
|
|
||||||
|
/* monitor tv audio mode, the first time don't wait
|
||||||
|
in order to get a quick stereo/SAP update */
|
||||||
|
watch_stereo(client);
|
||||||
|
while (state->watch_stereo) {
|
||||||
|
watch_stereo(client);
|
||||||
|
if (msp_sleep(state, 5000))
|
||||||
|
goto restart;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
v4l_dbg(1, msp_debug, client, "thread: exit\n");
|
v4l_dbg(1, msp_debug, client, "thread: exit\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void msp34xxg_detect_stereo(struct i2c_client *client)
|
static int msp34xxg_detect_stereo(struct i2c_client *client)
|
||||||
{
|
{
|
||||||
struct msp_state *state = i2c_get_clientdata(client);
|
struct msp_state *state = i2c_get_clientdata(client);
|
||||||
|
|
||||||
int status = msp_read_dem(client, 0x0200);
|
int status = msp_read_dem(client, 0x0200);
|
||||||
int is_bilingual = status & 0x100;
|
int is_bilingual = status & 0x100;
|
||||||
int is_stereo = status & 0x40;
|
int is_stereo = status & 0x40;
|
||||||
|
int oldrx = state->rxsubchans;
|
||||||
|
|
||||||
state->rxsubchans = 0;
|
state->rxsubchans = 0;
|
||||||
if (is_stereo)
|
if (is_stereo)
|
||||||
|
@ -932,42 +1012,31 @@ static void msp34xxg_detect_stereo(struct i2c_client *client)
|
||||||
else
|
else
|
||||||
state->rxsubchans = V4L2_TUNER_SUB_MONO;
|
state->rxsubchans = V4L2_TUNER_SUB_MONO;
|
||||||
if (is_bilingual) {
|
if (is_bilingual) {
|
||||||
state->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
|
if (state->std == 0x20)
|
||||||
/* I'm supposed to check whether it's SAP or not
|
state->rxsubchans |= V4L2_TUNER_SUB_SAP;
|
||||||
* and set only LANG2/SAP in this case. Yet, the MSP
|
else
|
||||||
* does a lot of work to hide this and handle everything
|
state->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
|
||||||
* the same way. I don't want to work around it so unless
|
|
||||||
* this is a problem, I'll handle SAP just like lang1/lang2.
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
v4l_dbg(1, msp_debug, client, "status=0x%x, stereo=%d, bilingual=%d -> rxsubchans=%d\n",
|
v4l_dbg(1, msp_debug, client, "status=0x%x, stereo=%d, bilingual=%d -> rxsubchans=%d\n",
|
||||||
status, is_stereo, is_bilingual, state->rxsubchans);
|
status, is_stereo, is_bilingual, state->rxsubchans);
|
||||||
|
return (oldrx != state->rxsubchans);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void msp34xxg_set_audmode(struct i2c_client *client)
|
static void msp34xxg_set_audmode(struct i2c_client *client)
|
||||||
{
|
{
|
||||||
struct msp_state *state = i2c_get_clientdata(client);
|
struct msp_state *state = i2c_get_clientdata(client);
|
||||||
int source;
|
|
||||||
|
|
||||||
switch (state->audmode) {
|
if (state->std == 0x20) {
|
||||||
case V4L2_TUNER_MODE_MONO:
|
if ((state->rxsubchans & V4L2_TUNER_SUB_SAP) &&
|
||||||
source = 0; /* mono only */
|
(state->audmode == V4L2_TUNER_MODE_STEREO ||
|
||||||
break;
|
state->audmode == V4L2_TUNER_MODE_LANG2)) {
|
||||||
case V4L2_TUNER_MODE_STEREO:
|
msp_write_dem(client, 0x20, 0x21);
|
||||||
source = 1; /* stereo or A|B, see comment in msp34xxg_get_v4l2_stereo() */
|
} else {
|
||||||
/* problem: that could also mean 2 (scart input) */
|
msp_write_dem(client, 0x20, 0x20);
|
||||||
break;
|
}
|
||||||
case V4L2_TUNER_MODE_LANG1:
|
|
||||||
source = 3; /* stereo or A */
|
|
||||||
break;
|
|
||||||
case V4L2_TUNER_MODE_LANG2:
|
|
||||||
source = 4; /* stereo or B */
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
source = 1;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
msp34xxg_set_source(client, source);
|
|
||||||
|
msp34xxg_set_sources(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
void msp_set_audmode(struct i2c_client *client)
|
void msp_set_audmode(struct i2c_client *client)
|
||||||
|
@ -977,7 +1046,6 @@ void msp_set_audmode(struct i2c_client *client)
|
||||||
switch (state->opmode) {
|
switch (state->opmode) {
|
||||||
case OPMODE_MANUAL:
|
case OPMODE_MANUAL:
|
||||||
case OPMODE_AUTODETECT:
|
case OPMODE_AUTODETECT:
|
||||||
state->watch_stereo = 0;
|
|
||||||
msp3400c_set_audmode(client);
|
msp3400c_set_audmode(client);
|
||||||
break;
|
break;
|
||||||
case OPMODE_AUTOSELECT:
|
case OPMODE_AUTOSELECT:
|
||||||
|
@ -986,18 +1054,17 @@ void msp_set_audmode(struct i2c_client *client)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void msp_detect_stereo(struct i2c_client *client)
|
int msp_detect_stereo(struct i2c_client *client)
|
||||||
{
|
{
|
||||||
struct msp_state *state = i2c_get_clientdata(client);
|
struct msp_state *state = i2c_get_clientdata(client);
|
||||||
|
|
||||||
switch (state->opmode) {
|
switch (state->opmode) {
|
||||||
case OPMODE_MANUAL:
|
case OPMODE_MANUAL:
|
||||||
case OPMODE_AUTODETECT:
|
case OPMODE_AUTODETECT:
|
||||||
msp3400c_detect_stereo(client);
|
return msp3400c_detect_stereo(client);
|
||||||
break;
|
|
||||||
case OPMODE_AUTOSELECT:
|
case OPMODE_AUTOSELECT:
|
||||||
msp34xxg_detect_stereo(client);
|
return msp34xxg_detect_stereo(client);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -198,13 +198,13 @@ static int mxb_probe(struct saa7146_dev* dev)
|
||||||
/* loop through all i2c-devices on the bus and look who is there */
|
/* loop through all i2c-devices on the bus and look who is there */
|
||||||
list_for_each(item,&mxb->i2c_adapter.clients) {
|
list_for_each(item,&mxb->i2c_adapter.clients) {
|
||||||
client = list_entry(item, struct i2c_client, list);
|
client = list_entry(item, struct i2c_client, list);
|
||||||
if( I2C_TEA6420_1 == client->addr )
|
if( I2C_ADDR_TEA6420_1 == client->addr )
|
||||||
mxb->tea6420_1 = client;
|
mxb->tea6420_1 = client;
|
||||||
if( I2C_TEA6420_2 == client->addr )
|
if( I2C_ADDR_TEA6420_2 == client->addr )
|
||||||
mxb->tea6420_2 = client;
|
mxb->tea6420_2 = client;
|
||||||
if( I2C_TEA6415C_2 == client->addr )
|
if( I2C_TEA6415C_2 == client->addr )
|
||||||
mxb->tea6415c = client;
|
mxb->tea6415c = client;
|
||||||
if( I2C_TDA9840 == client->addr )
|
if( I2C_ADDR_TDA9840 == client->addr )
|
||||||
mxb->tda9840 = client;
|
mxb->tda9840 = client;
|
||||||
if( I2C_SAA7111 == client->addr )
|
if( I2C_SAA7111 == client->addr )
|
||||||
mxb->saa7111a = client;
|
mxb->saa7111a = client;
|
||||||
|
@ -790,6 +790,12 @@ static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
|
||||||
DEB_D(("VIDIOC_S_TUNER: V4L2_TUNER_MODE_STEREO\n"));
|
DEB_D(("VIDIOC_S_TUNER: V4L2_TUNER_MODE_STEREO\n"));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case V4L2_TUNER_MODE_LANG1_LANG2: {
|
||||||
|
mxb->cur_mode = V4L2_TUNER_MODE_LANG1_LANG2;
|
||||||
|
byte = TDA9840_SET_BOTH;
|
||||||
|
DEB_D(("VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG1_LANG2\n"));
|
||||||
|
break;
|
||||||
|
}
|
||||||
case V4L2_TUNER_MODE_LANG1: {
|
case V4L2_TUNER_MODE_LANG1: {
|
||||||
mxb->cur_mode = V4L2_TUNER_MODE_LANG1;
|
mxb->cur_mode = V4L2_TUNER_MODE_LANG1;
|
||||||
byte = TDA9840_SET_LANG1;
|
byte = TDA9840_SET_LANG1;
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
*
|
*
|
||||||
* Based on the Linux CPiA driver written by Peter Pregler,
|
* Based on the Linux CPiA driver written by Peter Pregler,
|
||||||
* Scott J. Bertin and Johannes Erdfelt.
|
* Scott J. Bertin and Johannes Erdfelt.
|
||||||
*
|
*
|
||||||
* Please see the file: Documentation/usb/ov511.txt
|
* Please see the file: Documentation/usb/ov511.txt
|
||||||
* and the website at: http://alpha.dyndns.org/ov511
|
* and the website at: http://alpha.dyndns.org/ov511
|
||||||
* for more info.
|
* for more info.
|
||||||
|
@ -433,7 +433,7 @@ reg_w_mask(struct usb_ov511 *ov,
|
||||||
return (reg_w(ov, reg, newval));
|
return (reg_w(ov, reg, newval));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Writes multiple (n) byte value to a single register. Only valid with certain
|
* Writes multiple (n) byte value to a single register. Only valid with certain
|
||||||
* registers (0x30 and 0xc4 - 0xce).
|
* registers (0x30 and 0xc4 - 0xce).
|
||||||
*/
|
*/
|
||||||
|
@ -629,7 +629,7 @@ ov511_i2c_write_internal(struct usb_ov511 *ov,
|
||||||
/* Retry until idle */
|
/* Retry until idle */
|
||||||
do
|
do
|
||||||
rc = reg_r(ov, R511_I2C_CTL);
|
rc = reg_r(ov, R511_I2C_CTL);
|
||||||
while (rc > 0 && ((rc&1) == 0));
|
while (rc > 0 && ((rc&1) == 0));
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -1752,7 +1752,7 @@ sensor_set_picture(struct usb_ov511 *ov, struct video_picture *p)
|
||||||
ov->whiteness = p->whiteness;
|
ov->whiteness = p->whiteness;
|
||||||
|
|
||||||
/* Don't return error if a setting is unsupported, or rest of settings
|
/* Don't return error if a setting is unsupported, or rest of settings
|
||||||
* will not be performed */
|
* will not be performed */
|
||||||
|
|
||||||
rc = sensor_set_contrast(ov, p->contrast);
|
rc = sensor_set_contrast(ov, p->contrast);
|
||||||
if (FATAL_ERROR(rc))
|
if (FATAL_ERROR(rc))
|
||||||
|
@ -1781,7 +1781,7 @@ sensor_get_picture(struct usb_ov511 *ov, struct video_picture *p)
|
||||||
PDEBUG(4, "sensor_get_picture");
|
PDEBUG(4, "sensor_get_picture");
|
||||||
|
|
||||||
/* Don't return error if a setting is unsupported, or rest of settings
|
/* Don't return error if a setting is unsupported, or rest of settings
|
||||||
* will not be performed */
|
* will not be performed */
|
||||||
|
|
||||||
rc = sensor_get_contrast(ov, &(p->contrast));
|
rc = sensor_get_contrast(ov, &(p->contrast));
|
||||||
if (FATAL_ERROR(rc))
|
if (FATAL_ERROR(rc))
|
||||||
|
@ -2251,7 +2251,7 @@ mode_init_ov_sensor_regs(struct usb_ov511 *ov, int width, int height,
|
||||||
|
|
||||||
/******** Clock programming ********/
|
/******** Clock programming ********/
|
||||||
|
|
||||||
/* The OV6620 needs special handling. This prevents the
|
/* The OV6620 needs special handling. This prevents the
|
||||||
* severe banding that normally occurs */
|
* severe banding that normally occurs */
|
||||||
if (ov->sensor == SEN_OV6620 || ov->sensor == SEN_OV6630)
|
if (ov->sensor == SEN_OV6620 || ov->sensor == SEN_OV6630)
|
||||||
{
|
{
|
||||||
|
@ -2326,7 +2326,7 @@ set_ov_sensor_window(struct usb_ov511 *ov, int width, int height, int mode,
|
||||||
int sub_flag)
|
int sub_flag)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
int hwsbase, hwebase, vwsbase, vwebase, hwsize, vwsize;
|
int hwsbase, hwebase, vwsbase, vwebase, hwsize, vwsize;
|
||||||
int hoffset, voffset, hwscale = 0, vwscale = 0;
|
int hoffset, voffset, hwscale = 0, vwscale = 0;
|
||||||
|
|
||||||
/* The different sensor ICs handle setting up of window differently.
|
/* The different sensor ICs handle setting up of window differently.
|
||||||
|
@ -2575,7 +2575,7 @@ ov518_mode_init_regs(struct usb_ov511 *ov,
|
||||||
/* OV518 needs U and V swapped */
|
/* OV518 needs U and V swapped */
|
||||||
i2c_w_mask(ov, 0x15, 0x00, 0x01);
|
i2c_w_mask(ov, 0x15, 0x00, 0x01);
|
||||||
|
|
||||||
if (mode == VIDEO_PALETTE_GREY) {
|
if (mode == VIDEO_PALETTE_GREY) {
|
||||||
/* Set 16-bit input format (UV data are ignored) */
|
/* Set 16-bit input format (UV data are ignored) */
|
||||||
reg_w_mask(ov, 0x20, 0x00, 0x08);
|
reg_w_mask(ov, 0x20, 0x00, 0x08);
|
||||||
|
|
||||||
|
@ -2894,7 +2894,7 @@ make_8x8(unsigned char *pIn, unsigned char *pOut, int w)
|
||||||
* ... ... ...
|
* ... ... ...
|
||||||
* 56 57 ... 63 120 121 ... 127 248 249 ... 255
|
* 56 57 ... 63 120 121 ... 127 248 249 ... 255
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
yuv400raw_to_yuv400p(struct ov511_frame *frame,
|
yuv400raw_to_yuv400p(struct ov511_frame *frame,
|
||||||
unsigned char *pIn0, unsigned char *pOut0)
|
unsigned char *pIn0, unsigned char *pOut0)
|
||||||
|
@ -2923,7 +2923,7 @@ yuv400raw_to_yuv400p(struct ov511_frame *frame,
|
||||||
*
|
*
|
||||||
* 0 1 ... 7
|
* 0 1 ... 7
|
||||||
* 8 9 ... 15
|
* 8 9 ... 15
|
||||||
* ...
|
* ...
|
||||||
* 56 57 ... 63
|
* 56 57 ... 63
|
||||||
*
|
*
|
||||||
* U and V are shipped at half resolution (1 U,V sample -> one 2x2 block).
|
* U and V are shipped at half resolution (1 U,V sample -> one 2x2 block).
|
||||||
|
@ -3034,7 +3034,7 @@ decompress(struct usb_ov511 *ov, struct ov511_frame *frame,
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
deinterlace(struct ov511_frame *frame, int rawformat,
|
deinterlace(struct ov511_frame *frame, int rawformat,
|
||||||
unsigned char *pIn0, unsigned char *pOut0)
|
unsigned char *pIn0, unsigned char *pOut0)
|
||||||
{
|
{
|
||||||
const int fieldheight = frame->rawheight / 2;
|
const int fieldheight = frame->rawheight / 2;
|
||||||
const int fieldpix = fieldheight * frame->rawwidth;
|
const int fieldpix = fieldheight * frame->rawwidth;
|
||||||
|
@ -3112,7 +3112,7 @@ ov51x_postprocess_grey(struct usb_ov511 *ov, struct ov511_frame *frame)
|
||||||
frame->tempdata);
|
frame->tempdata);
|
||||||
|
|
||||||
deinterlace(frame, RAWFMT_YUV400, frame->tempdata,
|
deinterlace(frame, RAWFMT_YUV400, frame->tempdata,
|
||||||
frame->data);
|
frame->data);
|
||||||
} else {
|
} else {
|
||||||
if (frame->compressed)
|
if (frame->compressed)
|
||||||
decompress(ov, frame, frame->rawdata,
|
decompress(ov, frame, frame->rawdata,
|
||||||
|
@ -3136,7 +3136,7 @@ ov51x_postprocess_yuv420(struct usb_ov511 *ov, struct ov511_frame *frame)
|
||||||
frame->tempdata);
|
frame->tempdata);
|
||||||
|
|
||||||
deinterlace(frame, RAWFMT_YUV420, frame->tempdata,
|
deinterlace(frame, RAWFMT_YUV420, frame->tempdata,
|
||||||
frame->data);
|
frame->data);
|
||||||
} else {
|
} else {
|
||||||
if (frame->compressed)
|
if (frame->compressed)
|
||||||
decompress(ov, frame, frame->rawdata, frame->data);
|
decompress(ov, frame, frame->rawdata, frame->data);
|
||||||
|
@ -3226,7 +3226,7 @@ ov511_move_data(struct usb_ov511 *ov, unsigned char *in, int n)
|
||||||
frame->rawwidth = ((int)(in[9]) + 1) * 8;
|
frame->rawwidth = ((int)(in[9]) + 1) * 8;
|
||||||
frame->rawheight = ((int)(in[10]) + 1) * 8;
|
frame->rawheight = ((int)(in[10]) + 1) * 8;
|
||||||
|
|
||||||
PDEBUG(4, "Frame end, frame=%d, pnum=%d, w=%d, h=%d, recvd=%d",
|
PDEBUG(4, "Frame end, frame=%d, pnum=%d, w=%d, h=%d, recvd=%d",
|
||||||
ov->curframe, pnum, frame->rawwidth, frame->rawheight,
|
ov->curframe, pnum, frame->rawwidth, frame->rawheight,
|
||||||
frame->bytes_recvd);
|
frame->bytes_recvd);
|
||||||
|
|
||||||
|
@ -3527,10 +3527,10 @@ ov51x_isoc_irq(struct urb *urb, struct pt_regs *regs)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (urb->status == -ENOENT || urb->status == -ECONNRESET) {
|
if (urb->status == -ENOENT || urb->status == -ECONNRESET) {
|
||||||
PDEBUG(4, "URB unlinked");
|
PDEBUG(4, "URB unlinked");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (urb->status != -EINPROGRESS && urb->status != 0) {
|
if (urb->status != -EINPROGRESS && urb->status != 0) {
|
||||||
err("ERROR: urb->status=%d: %s", urb->status,
|
err("ERROR: urb->status=%d: %s", urb->status,
|
||||||
|
@ -4627,8 +4627,8 @@ ov51x_v4l1_mmap(struct file *file, struct vm_area_struct *vma)
|
||||||
PDEBUG(4, "mmap: %ld (%lX) bytes", size, size);
|
PDEBUG(4, "mmap: %ld (%lX) bytes", size, size);
|
||||||
|
|
||||||
if (size > (((OV511_NUMFRAMES
|
if (size > (((OV511_NUMFRAMES
|
||||||
* MAX_DATA_SIZE(ov->maxwidth, ov->maxheight)
|
* MAX_DATA_SIZE(ov->maxwidth, ov->maxheight)
|
||||||
+ PAGE_SIZE - 1) & ~(PAGE_SIZE - 1))))
|
+ PAGE_SIZE - 1) & ~(PAGE_SIZE - 1))))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (mutex_lock_interruptible(&ov->lock))
|
if (mutex_lock_interruptible(&ov->lock))
|
||||||
|
@ -5062,7 +5062,7 @@ ov6xx0_configure(struct usb_ov511 *ov)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This initializes the KS0127 and KS0127B video decoders. */
|
/* This initializes the KS0127 and KS0127B video decoders. */
|
||||||
static int
|
static int
|
||||||
ks0127_configure(struct usb_ov511 *ov)
|
ks0127_configure(struct usb_ov511 *ov)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
@ -5193,7 +5193,7 @@ saa7111a_configure(struct usb_ov511 *ov)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* Detect version of decoder. This must be done after writing the
|
/* Detect version of decoder. This must be done after writing the
|
||||||
* initial regs or the decoder will lock up. */
|
* initial regs or the decoder will lock up. */
|
||||||
rc = i2c_r(ov, 0x00);
|
rc = i2c_r(ov, 0x00);
|
||||||
|
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
|
@ -5216,13 +5216,13 @@ saa7111a_configure(struct usb_ov511 *ov)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This initializes the OV511/OV511+ and the sensor */
|
/* This initializes the OV511/OV511+ and the sensor */
|
||||||
static int
|
static int
|
||||||
ov511_configure(struct usb_ov511 *ov)
|
ov511_configure(struct usb_ov511 *ov)
|
||||||
{
|
{
|
||||||
static struct ov511_regvals aRegvalsInit511[] = {
|
static struct ov511_regvals aRegvalsInit511[] = {
|
||||||
{ OV511_REG_BUS, R51x_SYS_RESET, 0x7f },
|
{ OV511_REG_BUS, R51x_SYS_RESET, 0x7f },
|
||||||
{ OV511_REG_BUS, R51x_SYS_INIT, 0x01 },
|
{ OV511_REG_BUS, R51x_SYS_INIT, 0x01 },
|
||||||
{ OV511_REG_BUS, R51x_SYS_RESET, 0x7f },
|
{ OV511_REG_BUS, R51x_SYS_RESET, 0x7f },
|
||||||
{ OV511_REG_BUS, R51x_SYS_INIT, 0x01 },
|
{ OV511_REG_BUS, R51x_SYS_INIT, 0x01 },
|
||||||
{ OV511_REG_BUS, R51x_SYS_RESET, 0x3f },
|
{ OV511_REG_BUS, R51x_SYS_RESET, 0x3f },
|
||||||
{ OV511_REG_BUS, R51x_SYS_INIT, 0x01 },
|
{ OV511_REG_BUS, R51x_SYS_INIT, 0x01 },
|
||||||
|
@ -5269,7 +5269,7 @@ ov511_configure(struct usb_ov511 *ov)
|
||||||
err("Please notify " EMAIL " of the name,");
|
err("Please notify " EMAIL " of the name,");
|
||||||
err("manufacturer, model, and this number of your camera.");
|
err("manufacturer, model, and this number of your camera.");
|
||||||
err("Also include the output of the detection process.");
|
err("Also include the output of the detection process.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ov->customid == 70) /* USB Life TV (PAL/SECAM) */
|
if (ov->customid == 70) /* USB Life TV (PAL/SECAM) */
|
||||||
ov->pal = 1;
|
ov->pal = 1;
|
||||||
|
@ -5336,17 +5336,17 @@ ov511_configure(struct usb_ov511 *ov)
|
||||||
|
|
||||||
if (i2c_w(ov, 0x10, 0x00) < 0) {
|
if (i2c_w(ov, 0x10, 0x00) < 0) {
|
||||||
err("Can't determine sensor slave IDs");
|
err("Can't determine sensor slave IDs");
|
||||||
goto error;
|
goto error;
|
||||||
} else {
|
} else {
|
||||||
if (ks0127_configure(ov) < 0) {
|
if (ks0127_configure(ov) < 0) {
|
||||||
err("Failed to configure KS0127");
|
err("Failed to configure KS0127");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (saa7111a_configure(ov) < 0) {
|
if (saa7111a_configure(ov) < 0) {
|
||||||
err("Failed to configure SAA7111A");
|
err("Failed to configure SAA7111A");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -5356,13 +5356,13 @@ ov511_configure(struct usb_ov511 *ov)
|
||||||
} else {
|
} else {
|
||||||
if (ov6xx0_configure(ov) < 0) {
|
if (ov6xx0_configure(ov) < 0) {
|
||||||
err("Failed to configure OV6xx0");
|
err("Failed to configure OV6xx0");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (ov7xx0_configure(ov) < 0) {
|
if (ov7xx0_configure(ov) < 0) {
|
||||||
err("Failed to configure OV7xx0");
|
err("Failed to configure OV7xx0");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5381,12 +5381,12 @@ ov518_configure(struct usb_ov511 *ov)
|
||||||
/* For 518 and 518+ */
|
/* For 518 and 518+ */
|
||||||
static struct ov511_regvals aRegvalsInit518[] = {
|
static struct ov511_regvals aRegvalsInit518[] = {
|
||||||
{ OV511_REG_BUS, R51x_SYS_RESET, 0x40 },
|
{ OV511_REG_BUS, R51x_SYS_RESET, 0x40 },
|
||||||
{ OV511_REG_BUS, R51x_SYS_INIT, 0xe1 },
|
{ OV511_REG_BUS, R51x_SYS_INIT, 0xe1 },
|
||||||
{ OV511_REG_BUS, R51x_SYS_RESET, 0x3e },
|
{ OV511_REG_BUS, R51x_SYS_RESET, 0x3e },
|
||||||
{ OV511_REG_BUS, R51x_SYS_INIT, 0xe1 },
|
{ OV511_REG_BUS, R51x_SYS_INIT, 0xe1 },
|
||||||
{ OV511_REG_BUS, R51x_SYS_RESET, 0x00 },
|
{ OV511_REG_BUS, R51x_SYS_RESET, 0x00 },
|
||||||
{ OV511_REG_BUS, R51x_SYS_INIT, 0xe1 },
|
{ OV511_REG_BUS, R51x_SYS_INIT, 0xe1 },
|
||||||
{ OV511_REG_BUS, 0x46, 0x00 },
|
{ OV511_REG_BUS, 0x46, 0x00 },
|
||||||
{ OV511_REG_BUS, 0x5d, 0x03 },
|
{ OV511_REG_BUS, 0x5d, 0x03 },
|
||||||
{ OV511_DONE_BUS, 0x0, 0x00},
|
{ OV511_DONE_BUS, 0x0, 0x00},
|
||||||
};
|
};
|
||||||
|
@ -5517,7 +5517,7 @@ ov518_configure(struct usb_ov511 *ov)
|
||||||
|
|
||||||
if (init_ov_sensor(ov) < 0) {
|
if (init_ov_sensor(ov) < 0) {
|
||||||
err("Can't determine sensor slave IDs");
|
err("Can't determine sensor slave IDs");
|
||||||
goto error;
|
goto error;
|
||||||
} else {
|
} else {
|
||||||
err("Detected unsupported OV8xx0 sensor");
|
err("Detected unsupported OV8xx0 sensor");
|
||||||
goto error;
|
goto error;
|
||||||
|
@ -5525,13 +5525,13 @@ ov518_configure(struct usb_ov511 *ov)
|
||||||
} else {
|
} else {
|
||||||
if (ov6xx0_configure(ov) < 0) {
|
if (ov6xx0_configure(ov) < 0) {
|
||||||
err("Failed to configure OV6xx0");
|
err("Failed to configure OV6xx0");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (ov7xx0_configure(ov) < 0) {
|
if (ov7xx0_configure(ov) < 0) {
|
||||||
err("Failed to configure OV7xx0");
|
err("Failed to configure OV7xx0");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5564,28 +5564,28 @@ static ssize_t show_custom_id(struct class_device *cd, char *buf)
|
||||||
{
|
{
|
||||||
struct usb_ov511 *ov = cd_to_ov(cd);
|
struct usb_ov511 *ov = cd_to_ov(cd);
|
||||||
return sprintf(buf, "%d\n", ov->customid);
|
return sprintf(buf, "%d\n", ov->customid);
|
||||||
}
|
}
|
||||||
static CLASS_DEVICE_ATTR(custom_id, S_IRUGO, show_custom_id, NULL);
|
static CLASS_DEVICE_ATTR(custom_id, S_IRUGO, show_custom_id, NULL);
|
||||||
|
|
||||||
static ssize_t show_model(struct class_device *cd, char *buf)
|
static ssize_t show_model(struct class_device *cd, char *buf)
|
||||||
{
|
{
|
||||||
struct usb_ov511 *ov = cd_to_ov(cd);
|
struct usb_ov511 *ov = cd_to_ov(cd);
|
||||||
return sprintf(buf, "%s\n", ov->desc);
|
return sprintf(buf, "%s\n", ov->desc);
|
||||||
}
|
}
|
||||||
static CLASS_DEVICE_ATTR(model, S_IRUGO, show_model, NULL);
|
static CLASS_DEVICE_ATTR(model, S_IRUGO, show_model, NULL);
|
||||||
|
|
||||||
static ssize_t show_bridge(struct class_device *cd, char *buf)
|
static ssize_t show_bridge(struct class_device *cd, char *buf)
|
||||||
{
|
{
|
||||||
struct usb_ov511 *ov = cd_to_ov(cd);
|
struct usb_ov511 *ov = cd_to_ov(cd);
|
||||||
return sprintf(buf, "%s\n", symbolic(brglist, ov->bridge));
|
return sprintf(buf, "%s\n", symbolic(brglist, ov->bridge));
|
||||||
}
|
}
|
||||||
static CLASS_DEVICE_ATTR(bridge, S_IRUGO, show_bridge, NULL);
|
static CLASS_DEVICE_ATTR(bridge, S_IRUGO, show_bridge, NULL);
|
||||||
|
|
||||||
static ssize_t show_sensor(struct class_device *cd, char *buf)
|
static ssize_t show_sensor(struct class_device *cd, char *buf)
|
||||||
{
|
{
|
||||||
struct usb_ov511 *ov = cd_to_ov(cd);
|
struct usb_ov511 *ov = cd_to_ov(cd);
|
||||||
return sprintf(buf, "%s\n", symbolic(senlist, ov->sensor));
|
return sprintf(buf, "%s\n", symbolic(senlist, ov->sensor));
|
||||||
}
|
}
|
||||||
static CLASS_DEVICE_ATTR(sensor, S_IRUGO, show_sensor, NULL);
|
static CLASS_DEVICE_ATTR(sensor, S_IRUGO, show_sensor, NULL);
|
||||||
|
|
||||||
static ssize_t show_brightness(struct class_device *cd, char *buf)
|
static ssize_t show_brightness(struct class_device *cd, char *buf)
|
||||||
|
@ -5597,7 +5597,7 @@ static ssize_t show_brightness(struct class_device *cd, char *buf)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
sensor_get_brightness(ov, &x);
|
sensor_get_brightness(ov, &x);
|
||||||
return sprintf(buf, "%d\n", x >> 8);
|
return sprintf(buf, "%d\n", x >> 8);
|
||||||
}
|
}
|
||||||
static CLASS_DEVICE_ATTR(brightness, S_IRUGO, show_brightness, NULL);
|
static CLASS_DEVICE_ATTR(brightness, S_IRUGO, show_brightness, NULL);
|
||||||
|
|
||||||
static ssize_t show_saturation(struct class_device *cd, char *buf)
|
static ssize_t show_saturation(struct class_device *cd, char *buf)
|
||||||
|
@ -5609,7 +5609,7 @@ static ssize_t show_saturation(struct class_device *cd, char *buf)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
sensor_get_saturation(ov, &x);
|
sensor_get_saturation(ov, &x);
|
||||||
return sprintf(buf, "%d\n", x >> 8);
|
return sprintf(buf, "%d\n", x >> 8);
|
||||||
}
|
}
|
||||||
static CLASS_DEVICE_ATTR(saturation, S_IRUGO, show_saturation, NULL);
|
static CLASS_DEVICE_ATTR(saturation, S_IRUGO, show_saturation, NULL);
|
||||||
|
|
||||||
static ssize_t show_contrast(struct class_device *cd, char *buf)
|
static ssize_t show_contrast(struct class_device *cd, char *buf)
|
||||||
|
@ -5621,7 +5621,7 @@ static ssize_t show_contrast(struct class_device *cd, char *buf)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
sensor_get_contrast(ov, &x);
|
sensor_get_contrast(ov, &x);
|
||||||
return sprintf(buf, "%d\n", x >> 8);
|
return sprintf(buf, "%d\n", x >> 8);
|
||||||
}
|
}
|
||||||
static CLASS_DEVICE_ATTR(contrast, S_IRUGO, show_contrast, NULL);
|
static CLASS_DEVICE_ATTR(contrast, S_IRUGO, show_contrast, NULL);
|
||||||
|
|
||||||
static ssize_t show_hue(struct class_device *cd, char *buf)
|
static ssize_t show_hue(struct class_device *cd, char *buf)
|
||||||
|
@ -5633,7 +5633,7 @@ static ssize_t show_hue(struct class_device *cd, char *buf)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
sensor_get_hue(ov, &x);
|
sensor_get_hue(ov, &x);
|
||||||
return sprintf(buf, "%d\n", x >> 8);
|
return sprintf(buf, "%d\n", x >> 8);
|
||||||
}
|
}
|
||||||
static CLASS_DEVICE_ATTR(hue, S_IRUGO, show_hue, NULL);
|
static CLASS_DEVICE_ATTR(hue, S_IRUGO, show_hue, NULL);
|
||||||
|
|
||||||
static ssize_t show_exposure(struct class_device *cd, char *buf)
|
static ssize_t show_exposure(struct class_device *cd, char *buf)
|
||||||
|
@ -5645,7 +5645,7 @@ static ssize_t show_exposure(struct class_device *cd, char *buf)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
sensor_get_exposure(ov, &exp);
|
sensor_get_exposure(ov, &exp);
|
||||||
return sprintf(buf, "%d\n", exp >> 8);
|
return sprintf(buf, "%d\n", exp >> 8);
|
||||||
}
|
}
|
||||||
static CLASS_DEVICE_ATTR(exposure, S_IRUGO, show_exposure, NULL);
|
static CLASS_DEVICE_ATTR(exposure, S_IRUGO, show_exposure, NULL);
|
||||||
|
|
||||||
static void ov_create_sysfs(struct video_device *vdev)
|
static void ov_create_sysfs(struct video_device *vdev)
|
|
@ -130,7 +130,7 @@
|
||||||
#define R511_COMP_QVY 0x76
|
#define R511_COMP_QVY 0x76
|
||||||
#define R511_COMP_QVUV 0x77
|
#define R511_COMP_QVUV 0x77
|
||||||
#define R511_COMP_EN 0x78
|
#define R511_COMP_EN 0x78
|
||||||
#define R511_COMP_LUT_EN 0x79
|
#define R511_COMP_LUT_EN 0x79
|
||||||
#define R511_COMP_LUT_BEGIN 0x80
|
#define R511_COMP_LUT_BEGIN 0x80
|
||||||
|
|
||||||
/* --------------------------------- */
|
/* --------------------------------- */
|
||||||
|
@ -459,14 +459,14 @@ struct usb_ov511 {
|
||||||
int subh; /* Pix Array subcapture height */
|
int subh; /* Pix Array subcapture height */
|
||||||
|
|
||||||
int curframe; /* Current receiving sbuf */
|
int curframe; /* Current receiving sbuf */
|
||||||
struct ov511_frame frame[OV511_NUMFRAMES];
|
struct ov511_frame frame[OV511_NUMFRAMES];
|
||||||
|
|
||||||
struct ov511_sbuf sbuf[OV511_NUMSBUF];
|
struct ov511_sbuf sbuf[OV511_NUMSBUF];
|
||||||
|
|
||||||
wait_queue_head_t wq; /* Processes waiting */
|
wait_queue_head_t wq; /* Processes waiting */
|
||||||
|
|
||||||
int snap_enabled; /* Snapshot mode enabled */
|
int snap_enabled; /* Snapshot mode enabled */
|
||||||
|
|
||||||
int bridge; /* Type of bridge (BRG_*) */
|
int bridge; /* Type of bridge (BRG_*) */
|
||||||
int bclass; /* Class of bridge (BCL_*) */
|
int bclass; /* Class of bridge (BCL_*) */
|
||||||
int sensor; /* Type of image sensor chip (SEN_*) */
|
int sensor; /* Type of image sensor chip (SEN_*) */
|
||||||
|
@ -512,7 +512,7 @@ struct symbolic_list {
|
||||||
/* Returns the name of the matching element in the symbolic_list array. The
|
/* Returns the name of the matching element in the symbolic_list array. The
|
||||||
* end of the list must be marked with an element that has a NULL name.
|
* end of the list must be marked with an element that has a NULL name.
|
||||||
*/
|
*/
|
||||||
static inline char *
|
static inline char *
|
||||||
symbolic(struct symbolic_list list[], int num)
|
symbolic(struct symbolic_list list[], int num)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
|
@ -1,4 +1,4 @@
|
||||||
ovcamchip-objs := ovcamchip_core.o ov6x20.o ov6x30.o ov7x10.o ov7x20.o \
|
ovcamchip-objs := ovcamchip_core.o ov6x20.o ov6x30.o ov7x10.o ov7x20.o \
|
||||||
ov76be.o
|
ov76be.o
|
||||||
|
|
||||||
obj-$(CONFIG_VIDEO_OVCAMCHIP) += ovcamchip.o
|
obj-$(CONFIG_VIDEO_OVCAMCHIP) += ovcamchip.o
|
||||||
|
|
|
@ -266,17 +266,17 @@ static int ovcamchip_detect(struct i2c_client *c)
|
||||||
PDEBUG(3, "Testing for 0V6xx0");
|
PDEBUG(3, "Testing for 0V6xx0");
|
||||||
c->addr = OV6xx0_SID;
|
c->addr = OV6xx0_SID;
|
||||||
if (init_camchip(c) < 0) {
|
if (init_camchip(c) < 0) {
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
} else {
|
} else {
|
||||||
if (ov6xx0_detect(c) < 0) {
|
if (ov6xx0_detect(c) < 0) {
|
||||||
PERROR("Failed to init OV6xx0");
|
PERROR("Failed to init OV6xx0");
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (ov7xx0_detect(c) < 0) {
|
if (ov7xx0_detect(c) < 0) {
|
||||||
PERROR("Failed to init OV7xx0");
|
PERROR("Failed to init OV7xx0");
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -82,6 +82,6 @@ extern int ov_write_regvals(struct i2c_client *c,
|
||||||
struct ovcamchip_regvals *rvals);
|
struct ovcamchip_regvals *rvals);
|
||||||
|
|
||||||
extern int ov_write_mask(struct i2c_client *c, unsigned char reg,
|
extern int ov_write_mask(struct i2c_client *c, unsigned char reg,
|
||||||
unsigned char value, unsigned char mask);
|
unsigned char value, unsigned char mask);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/*
|
||||||
planb - PlanB frame grabber driver
|
planb - PlanB frame grabber driver
|
||||||
|
|
||||||
PlanB is used in the 7x00/8x00 series of PowerMacintosh
|
PlanB is used in the 7x00/8x00 series of PowerMacintosh
|
||||||
|
@ -584,7 +584,7 @@ static void resume_overlay(struct planb *pb)
|
||||||
wake_up_interruptible(&pb->suspendq);
|
wake_up_interruptible(&pb->suspendq);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void add_clip(struct planb *pb, struct video_clip *clip)
|
static void add_clip(struct planb *pb, struct video_clip *clip)
|
||||||
{
|
{
|
||||||
volatile unsigned char *base;
|
volatile unsigned char *base;
|
||||||
int xc = clip->x, yc = clip->y;
|
int xc = clip->x, yc = clip->y;
|
||||||
|
@ -758,7 +758,7 @@ static void cmd_buff(struct planb *pb)
|
||||||
PLANB_SET(CH_SYNC));
|
PLANB_SET(CH_SYNC));
|
||||||
tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel),
|
tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel),
|
||||||
PLANB_SET(DMA_ABORT));
|
PLANB_SET(DMA_ABORT));
|
||||||
|
|
||||||
/* odd field data: */
|
/* odd field data: */
|
||||||
jump = virt_to_bus(c1 + nlines / 2);
|
jump = virt_to_bus(c1 + nlines / 2);
|
||||||
for (i=1; i < nlines; i += stepsize, c1++)
|
for (i=1; i < nlines; i += stepsize, c1++)
|
||||||
|
@ -1247,7 +1247,7 @@ static volatile struct dbdma_cmd *setup_grab_cmd(int fr, struct planb *pb)
|
||||||
tab_cmd_dbdma(c1, DBDMA_NOP | BR_IFCLR, virt_to_bus(c1-3)); c1++;
|
tab_cmd_dbdma(c1, DBDMA_NOP | BR_IFCLR, virt_to_bus(c1-3)); c1++;
|
||||||
tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel),
|
tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel),
|
||||||
PLANB_SET(DMA_ABORT));
|
PLANB_SET(DMA_ABORT));
|
||||||
|
|
||||||
/* odd field data: */
|
/* odd field data: */
|
||||||
jump_addr = c1 + TAB_FACTOR * nlines / 2;
|
jump_addr = c1 + TAB_FACTOR * nlines / 2;
|
||||||
jump = virt_to_bus(jump_addr);
|
jump = virt_to_bus(jump_addr);
|
||||||
|
@ -1383,7 +1383,7 @@ static int planb_open(struct video_device *dev, int mode)
|
||||||
pb->user++;
|
pb->user++;
|
||||||
|
|
||||||
DEBUG("PlanB: device opened\n");
|
DEBUG("PlanB: device opened\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void planb_close(struct video_device *dev)
|
static void planb_close(struct video_device *dev)
|
||||||
|
@ -1424,9 +1424,9 @@ static long planb_write(struct video_device *v, const char *buf,
|
||||||
static int planb_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
|
static int planb_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
|
||||||
{
|
{
|
||||||
struct planb *pb=(struct planb *)dev;
|
struct planb *pb=(struct planb *)dev;
|
||||||
|
|
||||||
switch (cmd)
|
switch (cmd)
|
||||||
{
|
{
|
||||||
case VIDIOCGCAP:
|
case VIDIOCGCAP:
|
||||||
{
|
{
|
||||||
struct video_capability b;
|
struct video_capability b;
|
||||||
|
@ -1440,26 +1440,26 @@ static int planb_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
|
||||||
b.channels = 2; /* composite & svhs */
|
b.channels = 2; /* composite & svhs */
|
||||||
b.audios = 0;
|
b.audios = 0;
|
||||||
b.maxwidth = PLANB_MAXPIXELS;
|
b.maxwidth = PLANB_MAXPIXELS;
|
||||||
b.maxheight = PLANB_MAXLINES;
|
b.maxheight = PLANB_MAXLINES;
|
||||||
b.minwidth = 32; /* wild guess */
|
b.minwidth = 32; /* wild guess */
|
||||||
b.minheight = 32;
|
b.minheight = 32;
|
||||||
if (copy_to_user(arg,&b,sizeof(b)))
|
if (copy_to_user(arg,&b,sizeof(b)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
case VIDIOCSFBUF:
|
case VIDIOCSFBUF:
|
||||||
{
|
{
|
||||||
struct video_buffer v;
|
struct video_buffer v;
|
||||||
unsigned short bpp;
|
unsigned short bpp;
|
||||||
unsigned int fmt;
|
unsigned int fmt;
|
||||||
|
|
||||||
DEBUG("PlanB: IOCTL VIDIOCSFBUF\n");
|
DEBUG("PlanB: IOCTL VIDIOCSFBUF\n");
|
||||||
|
|
||||||
if (!capable(CAP_SYS_ADMIN)
|
if (!capable(CAP_SYS_ADMIN)
|
||||||
|| !capable(CAP_SYS_RAWIO))
|
|| !capable(CAP_SYS_RAWIO))
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
if (copy_from_user(&v, arg,sizeof(v)))
|
if (copy_from_user(&v, arg,sizeof(v)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
planb_lock(pb);
|
planb_lock(pb);
|
||||||
switch(v.depth) {
|
switch(v.depth) {
|
||||||
case 8:
|
case 8:
|
||||||
|
@ -1478,7 +1478,7 @@ static int planb_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
planb_unlock(pb);
|
planb_unlock(pb);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
if (bpp * v.width > v.bytesperline) {
|
if (bpp * v.width > v.bytesperline) {
|
||||||
planb_unlock(pb);
|
planb_unlock(pb);
|
||||||
|
@ -1493,7 +1493,7 @@ static int planb_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
|
||||||
pb->win.bpl = pb->win.bpp * pb->win.swidth;
|
pb->win.bpl = pb->win.bpp * pb->win.swidth;
|
||||||
pb->win.pad = v.bytesperline - pb->win.bpl;
|
pb->win.pad = v.bytesperline - pb->win.bpl;
|
||||||
|
|
||||||
DEBUG("PlanB: Display at %p is %d by %d, bytedepth %d,"
|
DEBUG("PlanB: Display at %p is %d by %d, bytedepth %d,"
|
||||||
" bpl %d (+ %d)\n", v.base, v.width,v.height,
|
" bpl %d (+ %d)\n", v.base, v.width,v.height,
|
||||||
pb->win.bpp, pb->win.bpl, pb->win.pad);
|
pb->win.bpp, pb->win.bpl, pb->win.pad);
|
||||||
|
|
||||||
|
@ -1504,11 +1504,11 @@ static int planb_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
|
||||||
resume_overlay(pb);
|
resume_overlay(pb);
|
||||||
}
|
}
|
||||||
planb_unlock(pb);
|
planb_unlock(pb);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
case VIDIOCGFBUF:
|
case VIDIOCGFBUF:
|
||||||
{
|
{
|
||||||
struct video_buffer v;
|
struct video_buffer v;
|
||||||
|
|
||||||
DEBUG("PlanB: IOCTL VIDIOCGFBUF\n");
|
DEBUG("PlanB: IOCTL VIDIOCGFBUF\n");
|
||||||
|
|
||||||
|
@ -1518,15 +1518,15 @@ static int planb_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
|
||||||
v.depth = pb->win.depth;
|
v.depth = pb->win.depth;
|
||||||
v.bytesperline = pb->win.bpl + pb->win.pad;
|
v.bytesperline = pb->win.bpl + pb->win.pad;
|
||||||
if (copy_to_user(arg, &v, sizeof(v)))
|
if (copy_to_user(arg, &v, sizeof(v)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
case VIDIOCCAPTURE:
|
case VIDIOCCAPTURE:
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if(copy_from_user(&i, arg, sizeof(i)))
|
if(copy_from_user(&i, arg, sizeof(i)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
if(i==0) {
|
if(i==0) {
|
||||||
DEBUG("PlanB: IOCTL VIDIOCCAPTURE Stop\n");
|
DEBUG("PlanB: IOCTL VIDIOCCAPTURE Stop\n");
|
||||||
|
|
||||||
|
@ -1695,7 +1695,7 @@ static int planb_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
|
||||||
struct video_window vw;
|
struct video_window vw;
|
||||||
struct video_clip clip;
|
struct video_clip clip;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
DEBUG("PlanB: IOCTL VIDIOCSWIN\n");
|
DEBUG("PlanB: IOCTL VIDIOCSWIN\n");
|
||||||
|
|
||||||
if(copy_from_user(&vw,arg,sizeof(vw)))
|
if(copy_from_user(&vw,arg,sizeof(vw)))
|
||||||
|
@ -1749,7 +1749,7 @@ static int planb_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
case VIDIOCSYNC: {
|
case VIDIOCSYNC: {
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
IDEBUG("PlanB: IOCTL VIDIOCSYNC\n");
|
IDEBUG("PlanB: IOCTL VIDIOCSYNC\n");
|
||||||
|
@ -1759,42 +1759,42 @@ static int planb_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
|
||||||
|
|
||||||
IDEBUG("PlanB: sync to frame %d\n", i);
|
IDEBUG("PlanB: sync to frame %d\n", i);
|
||||||
|
|
||||||
if(i > (MAX_GBUFFERS - 1) || i < 0)
|
if(i > (MAX_GBUFFERS - 1) || i < 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
chk_grab:
|
chk_grab:
|
||||||
switch (pb->frame_stat[i]) {
|
switch (pb->frame_stat[i]) {
|
||||||
case GBUFFER_UNUSED:
|
case GBUFFER_UNUSED:
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
case GBUFFER_GRABBING:
|
case GBUFFER_GRABBING:
|
||||||
IDEBUG("PlanB: waiting for grab"
|
IDEBUG("PlanB: waiting for grab"
|
||||||
" done (%d)\n", i);
|
" done (%d)\n", i);
|
||||||
interruptible_sleep_on(&pb->capq);
|
interruptible_sleep_on(&pb->capq);
|
||||||
if(signal_pending(current))
|
if(signal_pending(current))
|
||||||
return -EINTR;
|
return -EINTR;
|
||||||
goto chk_grab;
|
goto chk_grab;
|
||||||
case GBUFFER_DONE:
|
case GBUFFER_DONE:
|
||||||
pb->frame_stat[i] = GBUFFER_UNUSED;
|
pb->frame_stat[i] = GBUFFER_UNUSED;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
case VIDIOCMCAPTURE:
|
case VIDIOCMCAPTURE:
|
||||||
{
|
{
|
||||||
struct video_mmap vm;
|
struct video_mmap vm;
|
||||||
volatile unsigned int status;
|
volatile unsigned int status;
|
||||||
|
|
||||||
IDEBUG("PlanB: IOCTL VIDIOCMCAPTURE\n");
|
IDEBUG("PlanB: IOCTL VIDIOCMCAPTURE\n");
|
||||||
|
|
||||||
if(copy_from_user((void *) &vm,(void *)arg,sizeof(vm)))
|
if(copy_from_user((void *) &vm,(void *)arg,sizeof(vm)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
status = pb->frame_stat[vm.frame];
|
status = pb->frame_stat[vm.frame];
|
||||||
if (status != GBUFFER_UNUSED)
|
if (status != GBUFFER_UNUSED)
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
|
|
||||||
return vgrab(pb, &vm);
|
return vgrab(pb, &vm);
|
||||||
}
|
}
|
||||||
|
|
||||||
case VIDIOCGMBUF:
|
case VIDIOCGMBUF:
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
@ -1811,7 +1811,7 @@ static int planb_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
case PLANBIOCGSAAREGS:
|
case PLANBIOCGSAAREGS:
|
||||||
{
|
{
|
||||||
struct planb_saa_regs preg;
|
struct planb_saa_regs preg;
|
||||||
|
@ -1828,7 +1828,7 @@ static int planb_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
case PLANBIOCSSAAREGS:
|
case PLANBIOCSSAAREGS:
|
||||||
{
|
{
|
||||||
struct planb_saa_regs preg;
|
struct planb_saa_regs preg;
|
||||||
|
@ -1842,7 +1842,7 @@ static int planb_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
|
||||||
saa_set (preg.addr, preg.val, pb);
|
saa_set (preg.addr, preg.val, pb);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
case PLANBIOCGSTAT:
|
case PLANBIOCGSTAT:
|
||||||
{
|
{
|
||||||
struct planb_stat_regs pstat;
|
struct planb_stat_regs pstat;
|
||||||
|
@ -1859,7 +1859,7 @@ static int planb_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
case PLANBIOCSMODE: {
|
case PLANBIOCSMODE: {
|
||||||
int v;
|
int v;
|
||||||
|
|
||||||
|
@ -1985,10 +1985,10 @@ static int planb_mmap(struct vm_area_struct *vma, struct video_device *dev, cons
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
struct planb *pb = (struct planb *)dev;
|
struct planb *pb = (struct planb *)dev;
|
||||||
unsigned long start = (unsigned long)adr;
|
unsigned long start = (unsigned long)adr;
|
||||||
|
|
||||||
if (size > MAX_GBUFFERS * PLANB_MAX_FBUF)
|
if (size > MAX_GBUFFERS * PLANB_MAX_FBUF)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (!pb->rawbuf) {
|
if (!pb->rawbuf) {
|
||||||
int err;
|
int err;
|
||||||
if((err=grabbuf_alloc(pb)))
|
if((err=grabbuf_alloc(pb)))
|
||||||
|
@ -2091,10 +2091,10 @@ static int init_planb(struct planb *pb)
|
||||||
/* clear interrupt mask */
|
/* clear interrupt mask */
|
||||||
pb->intr_mask = PLANB_CLR_IRQ;
|
pb->intr_mask = PLANB_CLR_IRQ;
|
||||||
|
|
||||||
result = request_irq(pb->irq, planb_irq, 0, "PlanB", (void *)pb);
|
result = request_irq(pb->irq, planb_irq, 0, "PlanB", (void *)pb);
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
if (result==-EINVAL)
|
if (result==-EINVAL)
|
||||||
printk(KERN_ERR "PlanB: Bad irq number (%d) "
|
printk(KERN_ERR "PlanB: Bad irq number (%d) "
|
||||||
"or handler\n", (int)pb->irq);
|
"or handler\n", (int)pb->irq);
|
||||||
else if (result==-EBUSY)
|
else if (result==-EBUSY)
|
||||||
printk(KERN_ERR "PlanB: I don't know why, "
|
printk(KERN_ERR "PlanB: I don't know why, "
|
||||||
|
@ -2102,7 +2102,7 @@ static int init_planb(struct planb *pb)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
disable_irq(pb->irq);
|
disable_irq(pb->irq);
|
||||||
|
|
||||||
/* Now add the template and register the device unit. */
|
/* Now add the template and register the device unit. */
|
||||||
memcpy(&pb->video_dev,&planb_template,sizeof(planb_template));
|
memcpy(&pb->video_dev,&planb_template,sizeof(planb_template));
|
||||||
|
|
||||||
|
@ -2143,7 +2143,7 @@ static int init_planb(struct planb *pb)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Scan for a PlanB controller, request the irq and map the io memory
|
* Scan for a PlanB controller, request the irq and map the io memory
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int find_planb(void)
|
static int find_planb(void)
|
||||||
|
@ -2171,9 +2171,9 @@ static int find_planb(void)
|
||||||
pb = &planbs[0];
|
pb = &planbs[0];
|
||||||
planb_num = 1;
|
planb_num = 1;
|
||||||
|
|
||||||
if (planb_devices->n_addrs != 1) {
|
if (planb_devices->n_addrs != 1) {
|
||||||
printk (KERN_WARNING "PlanB: expecting 1 address for planb "
|
printk (KERN_WARNING "PlanB: expecting 1 address for planb "
|
||||||
"(got %d)", planb_devices->n_addrs);
|
"(got %d)", planb_devices->n_addrs);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2236,7 +2236,7 @@ static int find_planb(void)
|
||||||
pb->planb_base = planb_regs;
|
pb->planb_base = planb_regs;
|
||||||
pb->planb_base_phys = (struct planb_registers *)new_base;
|
pb->planb_base_phys = (struct planb_registers *)new_base;
|
||||||
pb->irq = irq;
|
pb->irq = irq;
|
||||||
|
|
||||||
return planb_num;
|
return planb_num;
|
||||||
|
|
||||||
err_out_disable:
|
err_out_disable:
|
||||||
|
@ -2251,7 +2251,7 @@ static void release_planb(void)
|
||||||
int i;
|
int i;
|
||||||
struct planb *pb;
|
struct planb *pb;
|
||||||
|
|
||||||
for (i=0;i<planb_num; i++)
|
for (i=0;i<planb_num; i++)
|
||||||
{
|
{
|
||||||
pb=&planbs[i];
|
pb=&planbs[i];
|
||||||
|
|
||||||
|
@ -2278,7 +2278,7 @@ static void release_planb(void)
|
||||||
static int __init init_planbs(void)
|
static int __init init_planbs(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (find_planb()<=0)
|
if (find_planb()<=0)
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
|
||||||
|
@ -2288,9 +2288,9 @@ static int __init init_planbs(void)
|
||||||
" with v4l\n", i);
|
" with v4l\n", i);
|
||||||
release_planb();
|
release_planb();
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
printk(KERN_INFO "PlanB: registered device %d with v4l\n", i);
|
printk(KERN_INFO "PlanB: registered device %d with v4l\n", i);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/*
|
||||||
planb - PlanB frame grabber driver
|
planb - PlanB frame grabber driver
|
||||||
|
|
||||||
PlanB is used in the 7x00/8x00 series of PowerMacintosh
|
PlanB is used in the 7x00/8x00 series of PowerMacintosh
|
||||||
|
@ -167,7 +167,7 @@ struct planb {
|
||||||
struct video_device video_dev;
|
struct video_device video_dev;
|
||||||
struct video_picture picture; /* Current picture params */
|
struct video_picture picture; /* Current picture params */
|
||||||
struct video_audio audio_dev; /* Current audio params */
|
struct video_audio audio_dev; /* Current audio params */
|
||||||
|
|
||||||
volatile struct planb_registers *planb_base; /* virt base of planb */
|
volatile struct planb_registers *planb_base; /* virt base of planb */
|
||||||
struct planb_registers *planb_base_phys; /* phys base of planb */
|
struct planb_registers *planb_base_phys; /* phys base of planb */
|
||||||
void *priv_space; /* Org. alloc. mem for kfree */
|
void *priv_space; /* Org. alloc. mem for kfree */
|
||||||
|
@ -209,7 +209,7 @@ struct planb {
|
||||||
int gwidth[MAX_GBUFFERS], gheight[MAX_GBUFFERS];
|
int gwidth[MAX_GBUFFERS], gheight[MAX_GBUFFERS];
|
||||||
unsigned int gfmt[MAX_GBUFFERS];
|
unsigned int gfmt[MAX_GBUFFERS];
|
||||||
int gnorm_switch[MAX_GBUFFERS];
|
int gnorm_switch[MAX_GBUFFERS];
|
||||||
volatile unsigned int *frame_stat;
|
volatile unsigned int *frame_stat;
|
||||||
#define GBUFFER_UNUSED 0x00U
|
#define GBUFFER_UNUSED 0x00U
|
||||||
#define GBUFFER_GRABBING 0x01U
|
#define GBUFFER_GRABBING 0x01U
|
||||||
#define GBUFFER_DONE 0x02U
|
#define GBUFFER_DONE 0x02U
|
||||||
|
|
|
@ -12,10 +12,10 @@
|
||||||
* Most of this code is directly derived from his userspace driver.
|
* Most of this code is directly derived from his userspace driver.
|
||||||
* His driver works so send any reports to alan@redhat.com unless the
|
* His driver works so send any reports to alan@redhat.com unless the
|
||||||
* userspace driver also doesn't work for you...
|
* userspace driver also doesn't work for you...
|
||||||
*
|
*
|
||||||
* Changes:
|
* Changes:
|
||||||
* 08/07/2003 Daniele Bellucci <bellucda@tiscali.it>
|
* 08/07/2003 Daniele Bellucci <bellucda@tiscali.it>
|
||||||
* - pms_capture: report back -EFAULT
|
* - pms_capture: report back -EFAULT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
@ -66,14 +66,14 @@ static int standard = 0; /* 0 - auto 1 - ntsc 2 - pal 3 - secam */
|
||||||
/*
|
/*
|
||||||
* I/O ports and Shared Memory
|
* I/O ports and Shared Memory
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int io_port = 0x250;
|
static int io_port = 0x250;
|
||||||
static int data_port = 0x251;
|
static int data_port = 0x251;
|
||||||
static int mem_base = 0xC8000;
|
static int mem_base = 0xC8000;
|
||||||
static void __iomem *mem;
|
static void __iomem *mem;
|
||||||
static int video_nr = -1;
|
static int video_nr = -1;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static inline void mvv_write(u8 index, u8 value)
|
static inline void mvv_write(u8 index, u8 value)
|
||||||
{
|
{
|
||||||
|
@ -90,9 +90,9 @@ static int pms_i2c_stat(u8 slave)
|
||||||
{
|
{
|
||||||
int counter;
|
int counter;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
outb(0x28, io_port);
|
outb(0x28, io_port);
|
||||||
|
|
||||||
counter=0;
|
counter=0;
|
||||||
while((inb(data_port)&0x01)==0)
|
while((inb(data_port)&0x01)==0)
|
||||||
if(counter++==256)
|
if(counter++==256)
|
||||||
|
@ -101,9 +101,9 @@ static int pms_i2c_stat(u8 slave)
|
||||||
while((inb(data_port)&0x01)!=0)
|
while((inb(data_port)&0x01)!=0)
|
||||||
if(counter++==256)
|
if(counter++==256)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
outb(slave, io_port);
|
outb(slave, io_port);
|
||||||
|
|
||||||
counter=0;
|
counter=0;
|
||||||
while((inb(data_port)&0x01)==0)
|
while((inb(data_port)&0x01)==0)
|
||||||
if(counter++==256)
|
if(counter++==256)
|
||||||
|
@ -112,7 +112,7 @@ static int pms_i2c_stat(u8 slave)
|
||||||
while((inb(data_port)&0x01)!=0)
|
while((inb(data_port)&0x01)!=0)
|
||||||
if(counter++==256)
|
if(counter++==256)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
for(i=0;i<12;i++)
|
for(i=0;i<12;i++)
|
||||||
{
|
{
|
||||||
char st=inb(data_port);
|
char st=inb(data_port);
|
||||||
|
@ -122,7 +122,7 @@ static int pms_i2c_stat(u8 slave)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
outb(0x29, io_port);
|
outb(0x29, io_port);
|
||||||
return inb(data_port);
|
return inb(data_port);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pms_i2c_write(u16 slave, u16 sub, u16 data)
|
static int pms_i2c_write(u16 slave, u16 sub, u16 data)
|
||||||
|
@ -130,19 +130,19 @@ static int pms_i2c_write(u16 slave, u16 sub, u16 data)
|
||||||
int skip=0;
|
int skip=0;
|
||||||
int count;
|
int count;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for(i=0;i<i2c_count;i++)
|
for(i=0;i<i2c_count;i++)
|
||||||
{
|
{
|
||||||
if((i2cinfo[i].slave==slave) &&
|
if((i2cinfo[i].slave==slave) &&
|
||||||
(i2cinfo[i].sub == sub))
|
(i2cinfo[i].sub == sub))
|
||||||
{
|
{
|
||||||
if(i2cinfo[i].data==data)
|
if(i2cinfo[i].data==data)
|
||||||
skip=1;
|
skip=1;
|
||||||
i2cinfo[i].data=data;
|
i2cinfo[i].data=data;
|
||||||
i=i2c_count+1;
|
i=i2c_count+1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(i==i2c_count && i2c_count<64)
|
if(i==i2c_count && i2c_count<64)
|
||||||
{
|
{
|
||||||
i2cinfo[i2c_count].slave=slave;
|
i2cinfo[i2c_count].slave=slave;
|
||||||
|
@ -150,16 +150,16 @@ static int pms_i2c_write(u16 slave, u16 sub, u16 data)
|
||||||
i2cinfo[i2c_count].data=data;
|
i2cinfo[i2c_count].data=data;
|
||||||
i2c_count++;
|
i2c_count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(skip)
|
if(skip)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
mvv_write(0x29, sub);
|
mvv_write(0x29, sub);
|
||||||
mvv_write(0x2A, data);
|
mvv_write(0x2A, data);
|
||||||
mvv_write(0x28, slave);
|
mvv_write(0x28, slave);
|
||||||
|
|
||||||
outb(0x28, io_port);
|
outb(0x28, io_port);
|
||||||
|
|
||||||
count=0;
|
count=0;
|
||||||
while((inb(data_port)&1)==0)
|
while((inb(data_port)&1)==0)
|
||||||
if(count>255)
|
if(count>255)
|
||||||
|
@ -167,9 +167,9 @@ static int pms_i2c_write(u16 slave, u16 sub, u16 data)
|
||||||
while((inb(data_port)&1)!=0)
|
while((inb(data_port)&1)!=0)
|
||||||
if(count>255)
|
if(count>255)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
count=inb(data_port);
|
count=inb(data_port);
|
||||||
|
|
||||||
if(count&2)
|
if(count&2)
|
||||||
return -1;
|
return -1;
|
||||||
return count;
|
return count;
|
||||||
|
@ -189,8 +189,8 @@ static int pms_i2c_read(int slave, int sub)
|
||||||
|
|
||||||
static void pms_i2c_andor(int slave, int sub, int and, int or)
|
static void pms_i2c_andor(int slave, int sub, int and, int or)
|
||||||
{
|
{
|
||||||
u8 tmp;
|
u8 tmp;
|
||||||
|
|
||||||
tmp=pms_i2c_read(slave, sub);
|
tmp=pms_i2c_read(slave, sub);
|
||||||
tmp = (tmp&and)|or;
|
tmp = (tmp&and)|or;
|
||||||
pms_i2c_write(slave, sub, tmp);
|
pms_i2c_write(slave, sub, tmp);
|
||||||
|
@ -199,7 +199,7 @@ static void pms_i2c_andor(int slave, int sub, int and, int or)
|
||||||
/*
|
/*
|
||||||
* Control functions
|
* Control functions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
static void pms_videosource(short source)
|
static void pms_videosource(short source)
|
||||||
{
|
{
|
||||||
|
@ -234,8 +234,8 @@ static void pms_colour(short colour)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void pms_contrast(short contrast)
|
static void pms_contrast(short contrast)
|
||||||
{
|
{
|
||||||
switch(decoder)
|
switch(decoder)
|
||||||
|
@ -269,14 +269,14 @@ static void pms_format(short format)
|
||||||
{
|
{
|
||||||
int target;
|
int target;
|
||||||
standard = format;
|
standard = format;
|
||||||
|
|
||||||
if(decoder==PHILIPS1)
|
if(decoder==PHILIPS1)
|
||||||
target=0x42;
|
target=0x42;
|
||||||
else if(decoder==PHILIPS2)
|
else if(decoder==PHILIPS2)
|
||||||
target=0x8A;
|
target=0x8A;
|
||||||
else
|
else
|
||||||
return;
|
return;
|
||||||
|
|
||||||
switch(format)
|
switch(format)
|
||||||
{
|
{
|
||||||
case 0: /* Auto */
|
case 0: /* Auto */
|
||||||
|
@ -302,7 +302,7 @@ static void pms_format(short format)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* These features of the PMS card are not currently exposes. They
|
* These features of the PMS card are not currently exposes. They
|
||||||
* could become a private v4l ioctl for PMSCONFIG or somesuch if
|
* could become a private v4l ioctl for PMSCONFIG or somesuch if
|
||||||
* people need it. We also don't yet use the PMS interrupt.
|
* people need it. We also don't yet use the PMS interrupt.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -324,7 +324,7 @@ static void pms_hstart(short start)
|
||||||
/*
|
/*
|
||||||
* Bandpass filters
|
* Bandpass filters
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void pms_bandpass(short pass)
|
static void pms_bandpass(short pass)
|
||||||
{
|
{
|
||||||
if(decoder==PHILIPS2)
|
if(decoder==PHILIPS2)
|
||||||
|
@ -493,7 +493,7 @@ static void pms_vert(u8 deciden, u8 decinum)
|
||||||
/*
|
/*
|
||||||
* Turn 16bit ratios into best small ratio the chipset can grok
|
* Turn 16bit ratios into best small ratio the chipset can grok
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void pms_vertdeci(unsigned short decinum, unsigned short deciden)
|
static void pms_vertdeci(unsigned short decinum, unsigned short deciden)
|
||||||
{
|
{
|
||||||
/* Knock it down by /5 once */
|
/* Knock it down by /5 once */
|
||||||
|
@ -546,7 +546,7 @@ static void pms_horzdeci(short decinum, short deciden)
|
||||||
decinum=512;
|
decinum=512;
|
||||||
deciden=640; /* 768 would be ideal */
|
deciden=640; /* 768 would be ideal */
|
||||||
}
|
}
|
||||||
|
|
||||||
while(((decinum|deciden)&1)==0)
|
while(((decinum|deciden)&1)==0)
|
||||||
{
|
{
|
||||||
decinum>>=1;
|
decinum>>=1;
|
||||||
|
@ -559,7 +559,7 @@ static void pms_horzdeci(short decinum, short deciden)
|
||||||
}
|
}
|
||||||
if(deciden==32)
|
if(deciden==32)
|
||||||
deciden--;
|
deciden--;
|
||||||
|
|
||||||
mvv_write(0x24, 0x80|deciden);
|
mvv_write(0x24, 0x80|deciden);
|
||||||
mvv_write(0x25, decinum);
|
mvv_write(0x25, decinum);
|
||||||
}
|
}
|
||||||
|
@ -567,14 +567,14 @@ static void pms_horzdeci(short decinum, short deciden)
|
||||||
static void pms_resolution(short width, short height)
|
static void pms_resolution(short width, short height)
|
||||||
{
|
{
|
||||||
int fg_height;
|
int fg_height;
|
||||||
|
|
||||||
fg_height=height;
|
fg_height=height;
|
||||||
if(fg_height>280)
|
if(fg_height>280)
|
||||||
fg_height=280;
|
fg_height=280;
|
||||||
|
|
||||||
mvv_write(0x18, fg_height);
|
mvv_write(0x18, fg_height);
|
||||||
mvv_write(0x19, fg_height>>8);
|
mvv_write(0x19, fg_height>>8);
|
||||||
|
|
||||||
if(standard==1)
|
if(standard==1)
|
||||||
{
|
{
|
||||||
mvv_write(0x1A, 0xFC);
|
mvv_write(0x1A, 0xFC);
|
||||||
|
@ -598,7 +598,7 @@ static void pms_resolution(short width, short height)
|
||||||
mvv_write(0x42, 0x00);
|
mvv_write(0x42, 0x00);
|
||||||
mvv_write(0x43, 0x00);
|
mvv_write(0x43, 0x00);
|
||||||
mvv_write(0x44, MVVMEMORYWIDTH);
|
mvv_write(0x44, MVVMEMORYWIDTH);
|
||||||
|
|
||||||
mvv_write(0x22, width+8);
|
mvv_write(0x22, width+8);
|
||||||
mvv_write(0x23, (width+8)>> 8);
|
mvv_write(0x23, (width+8)>> 8);
|
||||||
|
|
||||||
|
@ -618,7 +618,7 @@ static void pms_resolution(short width, short height)
|
||||||
/*
|
/*
|
||||||
* Set Input
|
* Set Input
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void pms_vcrinput(short input)
|
static void pms_vcrinput(short input)
|
||||||
{
|
{
|
||||||
if(decoder==PHILIPS2)
|
if(decoder==PHILIPS2)
|
||||||
|
@ -643,20 +643,20 @@ static int pms_capture(struct pms_device *dev, char __user *buf, int rgb555, int
|
||||||
mvv_write(0x08,r8); /* capture rgb555/565, init DRAM, PC enable */
|
mvv_write(0x08,r8); /* capture rgb555/565, init DRAM, PC enable */
|
||||||
|
|
||||||
/* printf("%d %d %d %d %d %x %x\n",width,height,voff,nom,den,mvv_buf); */
|
/* printf("%d %d %d %d %d %x %x\n",width,height,voff,nom,den,mvv_buf); */
|
||||||
|
|
||||||
for (y = 0; y < dev->height; y++ )
|
for (y = 0; y < dev->height; y++ )
|
||||||
{
|
{
|
||||||
writeb(0, mem); /* synchronisiert neue Zeile */
|
writeb(0, mem); /* synchronisiert neue Zeile */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is in truth a fifo, be very careful as if you
|
* This is in truth a fifo, be very careful as if you
|
||||||
* forgot this odd things will occur 8)
|
* forgot this odd things will occur 8)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
memcpy_fromio(tmp, mem, dw+32); /* discard 16 word */
|
memcpy_fromio(tmp, mem, dw+32); /* discard 16 word */
|
||||||
cnt -= dev->height;
|
cnt -= dev->height;
|
||||||
while (cnt <= 0)
|
while (cnt <= 0)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Don't copy too far
|
* Don't copy too far
|
||||||
*/
|
*/
|
||||||
|
@ -666,7 +666,7 @@ static int pms_capture(struct pms_device *dev, char __user *buf, int rgb555, int
|
||||||
cnt += dev->height;
|
cnt += dev->height;
|
||||||
if (copy_to_user(buf, tmp+32, dt))
|
if (copy_to_user(buf, tmp+32, dt))
|
||||||
return len ? len : -EFAULT;
|
return len ? len : -EFAULT;
|
||||||
buf += dt;
|
buf += dt;
|
||||||
len += dt;
|
len += dt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -683,7 +683,7 @@ static int pms_do_ioctl(struct inode *inode, struct file *file,
|
||||||
{
|
{
|
||||||
struct video_device *dev = video_devdata(file);
|
struct video_device *dev = video_devdata(file);
|
||||||
struct pms_device *pd=(struct pms_device *)dev;
|
struct pms_device *pd=(struct pms_device *)dev;
|
||||||
|
|
||||||
switch(cmd)
|
switch(cmd)
|
||||||
{
|
{
|
||||||
case VIDIOCGCAP:
|
case VIDIOCGCAP:
|
||||||
|
@ -806,7 +806,7 @@ static int pms_do_ioctl(struct inode *inode, struct file *file,
|
||||||
||(p->palette==VIDEO_PALETTE_RGB555 && p->depth==15)))
|
||(p->palette==VIDEO_PALETTE_RGB555 && p->depth==15)))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
pd->picture= *p;
|
pd->picture= *p;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Now load the card.
|
* Now load the card.
|
||||||
*/
|
*/
|
||||||
|
@ -815,7 +815,7 @@ static int pms_do_ioctl(struct inode *inode, struct file *file,
|
||||||
pms_brightness(p->brightness>>8);
|
pms_brightness(p->brightness>>8);
|
||||||
pms_hue(p->hue>>8);
|
pms_hue(p->hue>>8);
|
||||||
pms_colour(p->colour>>8);
|
pms_colour(p->colour>>8);
|
||||||
pms_contrast(p->contrast>>8);
|
pms_contrast(p->contrast>>8);
|
||||||
mutex_unlock(&pd->lock);
|
mutex_unlock(&pd->lock);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -873,7 +873,7 @@ static ssize_t pms_read(struct file *file, char __user *buf,
|
||||||
struct video_device *v = video_devdata(file);
|
struct video_device *v = video_devdata(file);
|
||||||
struct pms_device *pd=(struct pms_device *)v;
|
struct pms_device *pd=(struct pms_device *)v;
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
mutex_lock(&pd->lock);
|
mutex_lock(&pd->lock);
|
||||||
len=pms_capture(pd, buf, (pd->picture.depth==16)?0:1,count);
|
len=pms_capture(pd, buf, (pd->picture.depth==16)?0:1,count);
|
||||||
mutex_unlock(&pd->lock);
|
mutex_unlock(&pd->lock);
|
||||||
|
@ -905,13 +905,13 @@ static struct pms_device pms_device;
|
||||||
/*
|
/*
|
||||||
* Probe for and initialise the Mediavision PMS
|
* Probe for and initialise the Mediavision PMS
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int init_mediavision(void)
|
static int init_mediavision(void)
|
||||||
{
|
{
|
||||||
int id;
|
int id;
|
||||||
int idec, decst;
|
int idec, decst;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
unsigned char i2c_defs[]={
|
unsigned char i2c_defs[]={
|
||||||
0x4C,0x30,0x00,0xE8,
|
0x4C,0x30,0x00,0xE8,
|
||||||
0xB6,0xE2,0x00,0x00,
|
0xB6,0xE2,0x00,0x00,
|
||||||
|
@ -925,7 +925,7 @@ static int init_mediavision(void)
|
||||||
mem = ioremap(mem_base, 0x800);
|
mem = ioremap(mem_base, 0x800);
|
||||||
if (!mem)
|
if (!mem)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
if (!request_region(0x9A01, 1, "Mediavision PMS config"))
|
if (!request_region(0x9A01, 1, "Mediavision PMS config"))
|
||||||
{
|
{
|
||||||
printk(KERN_WARNING "mediavision: unable to detect: 0x9A01 in use.\n");
|
printk(KERN_WARNING "mediavision: unable to detect: 0x9A01 in use.\n");
|
||||||
|
@ -941,18 +941,18 @@ static int init_mediavision(void)
|
||||||
}
|
}
|
||||||
outb(0xB8, 0x9A01); /* Unlock */
|
outb(0xB8, 0x9A01); /* Unlock */
|
||||||
outb(io_port>>4, 0x9A01); /* Set IO port */
|
outb(io_port>>4, 0x9A01); /* Set IO port */
|
||||||
|
|
||||||
|
|
||||||
id=mvv_read(3);
|
id=mvv_read(3);
|
||||||
decst=pms_i2c_stat(0x43);
|
decst=pms_i2c_stat(0x43);
|
||||||
|
|
||||||
if(decst!=-1)
|
if(decst!=-1)
|
||||||
idec=2;
|
idec=2;
|
||||||
else if(pms_i2c_stat(0xb9)!=-1)
|
else if(pms_i2c_stat(0xb9)!=-1)
|
||||||
idec=3;
|
idec=3;
|
||||||
else if(pms_i2c_stat(0x8b)!=-1)
|
else if(pms_i2c_stat(0x8b)!=-1)
|
||||||
idec=1;
|
idec=1;
|
||||||
else
|
else
|
||||||
idec=0;
|
idec=0;
|
||||||
|
|
||||||
printk(KERN_INFO "PMS type is %d\n", idec);
|
printk(KERN_INFO "PMS type is %d\n", idec);
|
||||||
|
@ -966,11 +966,11 @@ static int init_mediavision(void)
|
||||||
/*
|
/*
|
||||||
* Ok we have a PMS of some sort
|
* Ok we have a PMS of some sort
|
||||||
*/
|
*/
|
||||||
|
|
||||||
mvv_write(0x04, mem_base>>12); /* Set the memory area */
|
mvv_write(0x04, mem_base>>12); /* Set the memory area */
|
||||||
|
|
||||||
/* Ok now load the defaults */
|
/* Ok now load the defaults */
|
||||||
|
|
||||||
for(i=0;i<0x19;i++)
|
for(i=0;i<0x19;i++)
|
||||||
{
|
{
|
||||||
if(i2c_defs[i]==0xFF)
|
if(i2c_defs[i]==0xFF)
|
||||||
|
@ -978,7 +978,7 @@ static int init_mediavision(void)
|
||||||
else
|
else
|
||||||
pms_i2c_write(0x8A, i, i2c_defs[i]);
|
pms_i2c_write(0x8A, i, i2c_defs[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
pms_i2c_write(0xB8,0x00,0x12);
|
pms_i2c_write(0xB8,0x00,0x12);
|
||||||
pms_i2c_write(0xB8,0x04,0x00);
|
pms_i2c_write(0xB8,0x04,0x00);
|
||||||
pms_i2c_write(0xB8,0x07,0x00);
|
pms_i2c_write(0xB8,0x07,0x00);
|
||||||
|
@ -987,18 +987,18 @@ static int init_mediavision(void)
|
||||||
pms_i2c_write(0xB8,0x0A,0x00);
|
pms_i2c_write(0xB8,0x0A,0x00);
|
||||||
pms_i2c_write(0xB8,0x0B,0x10);
|
pms_i2c_write(0xB8,0x0B,0x10);
|
||||||
pms_i2c_write(0xB8,0x10,0x03);
|
pms_i2c_write(0xB8,0x10,0x03);
|
||||||
|
|
||||||
mvv_write(0x01, 0x00);
|
mvv_write(0x01, 0x00);
|
||||||
mvv_write(0x05, 0xA0);
|
mvv_write(0x05, 0xA0);
|
||||||
mvv_write(0x08, 0x25);
|
mvv_write(0x08, 0x25);
|
||||||
mvv_write(0x09, 0x00);
|
mvv_write(0x09, 0x00);
|
||||||
mvv_write(0x0A, 0x20|MVVMEMORYWIDTH);
|
mvv_write(0x0A, 0x20|MVVMEMORYWIDTH);
|
||||||
|
|
||||||
mvv_write(0x10, 0x02);
|
mvv_write(0x10, 0x02);
|
||||||
mvv_write(0x1E, 0x0C);
|
mvv_write(0x1E, 0x0C);
|
||||||
mvv_write(0x1F, 0x03);
|
mvv_write(0x1F, 0x03);
|
||||||
mvv_write(0x26, 0x06);
|
mvv_write(0x26, 0x06);
|
||||||
|
|
||||||
mvv_write(0x2B, 0x00);
|
mvv_write(0x2B, 0x00);
|
||||||
mvv_write(0x2C, 0x20);
|
mvv_write(0x2C, 0x20);
|
||||||
mvv_write(0x2D, 0x00);
|
mvv_write(0x2D, 0x00);
|
||||||
|
@ -1018,13 +1018,13 @@ static int init_mediavision(void)
|
||||||
/*
|
/*
|
||||||
* Initialization and module stuff
|
* Initialization and module stuff
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int __init init_pms_cards(void)
|
static int __init init_pms_cards(void)
|
||||||
{
|
{
|
||||||
printk(KERN_INFO "Mediavision Pro Movie Studio driver 0.02\n");
|
printk(KERN_INFO "Mediavision Pro Movie Studio driver 0.02\n");
|
||||||
|
|
||||||
data_port = io_port +1;
|
data_port = io_port +1;
|
||||||
|
|
||||||
if(init_mediavision())
|
if(init_mediavision())
|
||||||
{
|
{
|
||||||
printk(KERN_INFO "Board not found.\n");
|
printk(KERN_INFO "Board not found.\n");
|
||||||
|
|
|
@ -15,6 +15,6 @@ default:
|
||||||
endif
|
endif
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f *.[oas] .*.flags *.ko .*.cmd .*.d .*.tmp *.mod.c
|
rm -f *.[oas] .*.flags *.ko .*.cmd .*.d .*.tmp *.mod.c
|
||||||
rm -rf .tmp_versions
|
rm -rf .tmp_versions
|
||||||
|
|
|
@ -47,17 +47,17 @@ don't know how to set it properly in the driver. The options are:
|
||||||
size
|
size
|
||||||
Can be one of 'sqcif', 'qsif', 'qcif', 'sif', 'cif' or
|
Can be one of 'sqcif', 'qsif', 'qcif', 'sif', 'cif' or
|
||||||
'vga', for an image size of resp. 128x96, 160x120, 176x144,
|
'vga', for an image size of resp. 128x96, 160x120, 176x144,
|
||||||
320x240, 352x288 and 640x480 (of course, only for those cameras that
|
320x240, 352x288 and 640x480 (of course, only for those cameras that
|
||||||
support these resolutions).
|
support these resolutions).
|
||||||
|
|
||||||
fps
|
fps
|
||||||
Specifies the desired framerate. Is an integer in the range of 4-30.
|
Specifies the desired framerate. Is an integer in the range of 4-30.
|
||||||
|
|
||||||
fbufs
|
fbufs
|
||||||
This paramter specifies the number of internal buffers to use for storing
|
This paramter specifies the number of internal buffers to use for storing
|
||||||
frames from the cam. This will help if the process that reads images from
|
frames from the cam. This will help if the process that reads images from
|
||||||
the cam is a bit slow or momentarely busy. However, on slow machines it
|
the cam is a bit slow or momentarely busy. However, on slow machines it
|
||||||
only introduces lag, so choose carefully. The default is 3, which is
|
only introduces lag, so choose carefully. The default is 3, which is
|
||||||
reasonable. You can set it between 2 and 5.
|
reasonable. You can set it between 2 and 5.
|
||||||
|
|
||||||
mbufs
|
mbufs
|
||||||
|
@ -65,9 +65,9 @@ mbufs
|
||||||
buffers to reserve for mmap(), VIDIOCCGMBUF, VIDIOCMCAPTURE and friends.
|
buffers to reserve for mmap(), VIDIOCCGMBUF, VIDIOCMCAPTURE and friends.
|
||||||
The default is 2, which is adequate for most applications (double
|
The default is 2, which is adequate for most applications (double
|
||||||
buffering).
|
buffering).
|
||||||
|
|
||||||
Should you experience a lot of 'Dumping frame...' messages during
|
Should you experience a lot of 'Dumping frame...' messages during
|
||||||
grabbing with a tool that uses mmap(), you might want to increase if.
|
grabbing with a tool that uses mmap(), you might want to increase if.
|
||||||
However, it doesn't really buffer images, it just gives you a bit more
|
However, it doesn't really buffer images, it just gives you a bit more
|
||||||
slack when your program is behind. But you need a multi-threaded or
|
slack when your program is behind. But you need a multi-threaded or
|
||||||
forked program to really take advantage of these buffers.
|
forked program to really take advantage of these buffers.
|
||||||
|
@ -88,15 +88,15 @@ power_save
|
||||||
|
|
||||||
compression (only useful with the plugin)
|
compression (only useful with the plugin)
|
||||||
With this option you can control the compression factor that the camera
|
With this option you can control the compression factor that the camera
|
||||||
uses to squeeze the image through the USB bus. You can set the
|
uses to squeeze the image through the USB bus. You can set the
|
||||||
parameter between 0 and 3:
|
parameter between 0 and 3:
|
||||||
0 = prefer uncompressed images; if the requested mode is not available
|
0 = prefer uncompressed images; if the requested mode is not available
|
||||||
in an uncompressed format, the driver will silently switch to low
|
in an uncompressed format, the driver will silently switch to low
|
||||||
compression.
|
compression.
|
||||||
1 = low compression.
|
1 = low compression.
|
||||||
2 = medium compression.
|
2 = medium compression.
|
||||||
3 = high compression.
|
3 = high compression.
|
||||||
|
|
||||||
High compression takes less bandwidth of course, but it could also
|
High compression takes less bandwidth of course, but it could also
|
||||||
introduce some unwanted artefacts. The default is 2, medium compression.
|
introduce some unwanted artefacts. The default is 2, medium compression.
|
||||||
See the FAQ on the website for an overview of which modes require
|
See the FAQ on the website for an overview of which modes require
|
||||||
|
@ -112,7 +112,7 @@ leds
|
||||||
this is let the LED blink while the camera is in use. This:
|
this is let the LED blink while the camera is in use. This:
|
||||||
|
|
||||||
leds=500,500
|
leds=500,500
|
||||||
|
|
||||||
will blink the LED once every second. But with:
|
will blink the LED once every second. But with:
|
||||||
|
|
||||||
leds=0,0
|
leds=0,0
|
||||||
|
@ -123,7 +123,7 @@ leds
|
||||||
when the camera is not used anymore.
|
when the camera is not used anymore.
|
||||||
|
|
||||||
This parameter works only with the ToUCam range of cameras (720, 730, 740,
|
This parameter works only with the ToUCam range of cameras (720, 730, 740,
|
||||||
750) and OEMs. For other cameras this command is silently ignored, and
|
750) and OEMs. For other cameras this command is silently ignored, and
|
||||||
the LED cannot be controlled.
|
the LED cannot be controlled.
|
||||||
|
|
||||||
Finally: this parameters does not take effect UNTIL the first time you
|
Finally: this parameters does not take effect UNTIL the first time you
|
||||||
|
@ -144,35 +144,35 @@ dev_hint
|
||||||
format:
|
format:
|
||||||
|
|
||||||
[type[.serialnumber]:]node
|
[type[.serialnumber]:]node
|
||||||
|
|
||||||
The square brackets mean that both the type and the serialnumber are
|
The square brackets mean that both the type and the serialnumber are
|
||||||
optional, but a serialnumber cannot be specified without a type (which
|
optional, but a serialnumber cannot be specified without a type (which
|
||||||
would be rather pointless). The serialnumber is separated from the type
|
would be rather pointless). The serialnumber is separated from the type
|
||||||
by a '.'; the node number by a ':'.
|
by a '.'; the node number by a ':'.
|
||||||
|
|
||||||
This somewhat cryptic syntax is best explained by a few examples:
|
This somewhat cryptic syntax is best explained by a few examples:
|
||||||
|
|
||||||
dev_hint=3,5 The first detected cam gets assigned
|
dev_hint=3,5 The first detected cam gets assigned
|
||||||
/dev/video3, the second /dev/video5. Any
|
/dev/video3, the second /dev/video5. Any
|
||||||
other cameras will get the first free
|
other cameras will get the first free
|
||||||
available slot (see below).
|
available slot (see below).
|
||||||
|
|
||||||
dev_hint=645:1,680:2 The PCA645 camera will get /dev/video1,
|
dev_hint=645:1,680:2 The PCA645 camera will get /dev/video1,
|
||||||
and a PCVC680 /dev/video2.
|
and a PCVC680 /dev/video2.
|
||||||
|
|
||||||
dev_hint=645.0123:3,645.4567:0 The PCA645 camera with serialnumber
|
|
||||||
0123 goes to /dev/video3, the same
|
|
||||||
camera model with the 4567 serial
|
|
||||||
gets /dev/video0.
|
|
||||||
|
|
||||||
dev_hint=750:1,4,5,6 The PCVC750 camera will get /dev/video1, the
|
dev_hint=645.0123:3,645.4567:0 The PCA645 camera with serialnumber
|
||||||
next 3 Philips cams will use /dev/video4
|
0123 goes to /dev/video3, the same
|
||||||
through /dev/video6.
|
camera model with the 4567 serial
|
||||||
|
gets /dev/video0.
|
||||||
|
|
||||||
|
dev_hint=750:1,4,5,6 The PCVC750 camera will get /dev/video1, the
|
||||||
|
next 3 Philips cams will use /dev/video4
|
||||||
|
through /dev/video6.
|
||||||
|
|
||||||
Some points worth knowing:
|
Some points worth knowing:
|
||||||
- Serialnumbers are case sensitive and must be written full, including
|
- Serialnumbers are case sensitive and must be written full, including
|
||||||
leading zeroes (it's treated as a string).
|
leading zeroes (it's treated as a string).
|
||||||
- If a device node is already occupied, registration will fail and
|
- If a device node is already occupied, registration will fail and
|
||||||
the webcam is not available.
|
the webcam is not available.
|
||||||
- You can have up to 64 video devices; be sure to make enough device
|
- You can have up to 64 video devices; be sure to make enough device
|
||||||
nodes in /dev if you want to spread the numbers (this does not apply
|
nodes in /dev if you want to spread the numbers (this does not apply
|
||||||
|
@ -186,13 +186,13 @@ trace
|
||||||
kernel log at debug level.
|
kernel log at debug level.
|
||||||
|
|
||||||
The trace variable is a bitmask; each bit represents a certain feature.
|
The trace variable is a bitmask; each bit represents a certain feature.
|
||||||
If you want to trace something, look up the bit value(s) in the table
|
If you want to trace something, look up the bit value(s) in the table
|
||||||
below, add the values together and supply that to the trace variable.
|
below, add the values together and supply that to the trace variable.
|
||||||
|
|
||||||
Value Value Description Default
|
Value Value Description Default
|
||||||
(dec) (hex)
|
(dec) (hex)
|
||||||
1 0x1 Module initialization; this will log messages On
|
1 0x1 Module initialization; this will log messages On
|
||||||
while loading and unloading the module
|
while loading and unloading the module
|
||||||
|
|
||||||
2 0x2 probe() and disconnect() traces On
|
2 0x2 probe() and disconnect() traces On
|
||||||
|
|
||||||
|
@ -203,7 +203,7 @@ trace
|
||||||
16 0x10 Memory allocation of buffers, etc. Off
|
16 0x10 Memory allocation of buffers, etc. Off
|
||||||
|
|
||||||
32 0x20 Showing underflow, overflow and Dumping frame On
|
32 0x20 Showing underflow, overflow and Dumping frame On
|
||||||
messages
|
messages
|
||||||
|
|
||||||
64 0x40 Show viewport and image sizes Off
|
64 0x40 Show viewport and image sizes Off
|
||||||
|
|
||||||
|
@ -217,7 +217,7 @@ trace
|
||||||
|
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
# modprobe pwc size=cif fps=15 power_save=1
|
# modprobe pwc size=cif fps=15 power_save=1
|
||||||
|
|
||||||
The fbufs, mbufs and trace parameters are global and apply to all connected
|
The fbufs, mbufs and trace parameters are global and apply to all connected
|
|
@ -31,17 +31,17 @@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Changes
|
Changes
|
||||||
2001/08/03 Alvarado Added methods for changing white balance and
|
2001/08/03 Alvarado Added methods for changing white balance and
|
||||||
red/green gains
|
red/green gains
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Control functions for the cam; brightness, contrast, video mode, etc. */
|
/* Control functions for the cam; brightness, contrast, video mode, etc. */
|
||||||
|
|
||||||
#ifdef __KERNEL__
|
#ifdef __KERNEL__
|
||||||
#include <asm/uaccess.h>
|
#include <asm/uaccess.h>
|
||||||
#endif
|
#endif
|
||||||
#include <asm/errno.h>
|
#include <asm/errno.h>
|
||||||
|
|
||||||
#include "pwc.h"
|
#include "pwc.h"
|
||||||
#include "pwc-ioctl.h"
|
#include "pwc-ioctl.h"
|
||||||
#include "pwc-uncompress.h"
|
#include "pwc-uncompress.h"
|
||||||
|
@ -116,13 +116,13 @@ static const char *size2name[PSZ_MAX] =
|
||||||
"SIF",
|
"SIF",
|
||||||
"CIF",
|
"CIF",
|
||||||
"VGA",
|
"VGA",
|
||||||
};
|
};
|
||||||
|
|
||||||
/********/
|
/********/
|
||||||
|
|
||||||
/* Entries for the Nala (645/646) camera; the Nala doesn't have compression
|
/* Entries for the Nala (645/646) camera; the Nala doesn't have compression
|
||||||
preferences, so you either get compressed or non-compressed streams.
|
preferences, so you either get compressed or non-compressed streams.
|
||||||
|
|
||||||
An alternate value of 0 means this mode is not available at all.
|
An alternate value of 0 means this mode is not available at all.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -205,13 +205,13 @@ static inline int set_video_mode_Nala(struct pwc_device *pdev, int size, int fra
|
||||||
{ /* closest match of framerate */
|
{ /* closest match of framerate */
|
||||||
0, 0, 0, 0, 4, /* 0-4 */
|
0, 0, 0, 0, 4, /* 0-4 */
|
||||||
5, 5, 7, 7, 10, /* 5-9 */
|
5, 5, 7, 7, 10, /* 5-9 */
|
||||||
10, 10, 12, 12, 15, /* 10-14 */
|
10, 10, 12, 12, 15, /* 10-14 */
|
||||||
15, 15, 15, 20, 20, /* 15-19 */
|
15, 15, 15, 20, 20, /* 15-19 */
|
||||||
20, 20, 20, 24, 24, /* 20-24 */
|
20, 20, 20, 24, 24, /* 20-24 */
|
||||||
24, 24, 24, 24, 24, /* 25-29 */
|
24, 24, 24, 24, 24, /* 25-29 */
|
||||||
24 /* 30 */
|
24 /* 30 */
|
||||||
};
|
};
|
||||||
int frames2table[31] =
|
int frames2table[31] =
|
||||||
{ 0, 0, 0, 0, 0, /* 0-4 */
|
{ 0, 0, 0, 0, 0, /* 0-4 */
|
||||||
1, 1, 1, 2, 2, /* 5-9 */
|
1, 1, 1, 2, 2, /* 5-9 */
|
||||||
3, 3, 4, 4, 4, /* 10-14 */
|
3, 3, 4, 4, 4, /* 10-14 */
|
||||||
|
@ -220,7 +220,7 @@ static inline int set_video_mode_Nala(struct pwc_device *pdev, int size, int fra
|
||||||
7, 7, 7, 7, 7, /* 25-29 */
|
7, 7, 7, 7, 7, /* 25-29 */
|
||||||
7 /* 30 */
|
7 /* 30 */
|
||||||
};
|
};
|
||||||
|
|
||||||
if (size < 0 || size > PSZ_CIF || frames < 4 || frames > 25)
|
if (size < 0 || size > PSZ_CIF || frames < 4 || frames > 25)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
frames = frames2frames[frames];
|
frames = frames2frames[frames];
|
||||||
|
@ -232,7 +232,7 @@ static inline int set_video_mode_Nala(struct pwc_device *pdev, int size, int fra
|
||||||
if (pEntry->compressed)
|
if (pEntry->compressed)
|
||||||
return -ENOENT; /* Not supported. */
|
return -ENOENT; /* Not supported. */
|
||||||
|
|
||||||
memcpy(buf, pEntry->mode, 3);
|
memcpy(buf, pEntry->mode, 3);
|
||||||
ret = send_video_command(pdev->udev, pdev->vendpoint, buf, 3);
|
ret = send_video_command(pdev->udev, pdev->vendpoint, buf, 3);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
Debug("Failed to send video command... %d\n", ret);
|
Debug("Failed to send video command... %d\n", ret);
|
||||||
|
@ -257,7 +257,7 @@ static inline int set_video_mode_Nala(struct pwc_device *pdev, int size, int fra
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pdev->cmd_len = 3;
|
pdev->cmd_len = 3;
|
||||||
memcpy(pdev->cmd_buf, buf, 3);
|
memcpy(pdev->cmd_buf, buf, 3);
|
||||||
|
|
||||||
|
@ -352,13 +352,13 @@ static inline int set_video_mode_Kiara(struct pwc_device *pdev, int size, int fr
|
||||||
/* special case: VGA @ 5 fps and snapshot is raw bayer mode */
|
/* special case: VGA @ 5 fps and snapshot is raw bayer mode */
|
||||||
if (size == PSZ_VGA && frames == 5 && snapshot)
|
if (size == PSZ_VGA && frames == 5 && snapshot)
|
||||||
{
|
{
|
||||||
/* Only available in case the raw palette is selected or
|
/* Only available in case the raw palette is selected or
|
||||||
we have the decompressor available. This mode is
|
we have the decompressor available. This mode is
|
||||||
only available in compressed form
|
only available in compressed form
|
||||||
*/
|
*/
|
||||||
if (pdev->vpalette == VIDEO_PALETTE_RAW)
|
if (pdev->vpalette == VIDEO_PALETTE_RAW)
|
||||||
{
|
{
|
||||||
Info("Choosing VGA/5 BAYER mode (%d).\n", pdev->vpalette);
|
Info("Choosing VGA/5 BAYER mode (%d).\n", pdev->vpalette);
|
||||||
pChoose = &RawEntry;
|
pChoose = &RawEntry;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -368,9 +368,9 @@ static inline int set_video_mode_Kiara(struct pwc_device *pdev, int size, int fr
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Find a supported framerate with progressively higher compression ratios
|
/* Find a supported framerate with progressively higher compression ratios
|
||||||
if the preferred ratio is not available.
|
if the preferred ratio is not available.
|
||||||
Skip this step when using RAW modes.
|
Skip this step when using RAW modes.
|
||||||
*/
|
*/
|
||||||
while (compression <= 3) {
|
while (compression <= 3) {
|
||||||
pChoose = &Kiara_table[size][fps][compression];
|
pChoose = &Kiara_table[size][fps][compression];
|
||||||
|
@ -383,7 +383,7 @@ static inline int set_video_mode_Kiara(struct pwc_device *pdev, int size, int fr
|
||||||
return -ENOENT; /* Not supported. */
|
return -ENOENT; /* Not supported. */
|
||||||
|
|
||||||
Debug("Using alternate setting %d.\n", pChoose->alternate);
|
Debug("Using alternate setting %d.\n", pChoose->alternate);
|
||||||
|
|
||||||
/* usb_control_msg won't take staticly allocated arrays as argument?? */
|
/* usb_control_msg won't take staticly allocated arrays as argument?? */
|
||||||
memcpy(buf, pChoose->mode, 12);
|
memcpy(buf, pChoose->mode, 12);
|
||||||
if (snapshot)
|
if (snapshot)
|
||||||
|
@ -463,9 +463,9 @@ static void pwc_set_image_buffer_size(struct pwc_device *pdev)
|
||||||
*/
|
*/
|
||||||
int pwc_set_video_mode(struct pwc_device *pdev, int width, int height, int frames, int compression, int snapshot)
|
int pwc_set_video_mode(struct pwc_device *pdev, int width, int height, int frames, int compression, int snapshot)
|
||||||
{
|
{
|
||||||
int ret, size;
|
int ret, size;
|
||||||
|
|
||||||
Trace(TRACE_FLOW, "set_video_mode(%dx%d @ %d, palette %d).\n", width, height, frames, pdev->vpalette);
|
Trace(TRACE_FLOW, "set_video_mode(%dx%d @ %d, palette %d).\n", width, height, frames, pdev->vpalette);
|
||||||
size = pwc_decode_size(pdev, width, height);
|
size = pwc_decode_size(pdev, width, height);
|
||||||
if (size < 0) {
|
if (size < 0) {
|
||||||
Debug("Could not find suitable size.\n");
|
Debug("Could not find suitable size.\n");
|
||||||
|
@ -473,7 +473,7 @@ int pwc_set_video_mode(struct pwc_device *pdev, int width, int height, int frame
|
||||||
}
|
}
|
||||||
Debug("decode_size = %d.\n", size);
|
Debug("decode_size = %d.\n", size);
|
||||||
|
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
switch(pdev->type) {
|
switch(pdev->type) {
|
||||||
case 645:
|
case 645:
|
||||||
case 646:
|
case 646:
|
||||||
|
@ -485,7 +485,7 @@ int pwc_set_video_mode(struct pwc_device *pdev, int width, int height, int frame
|
||||||
case 690:
|
case 690:
|
||||||
ret = set_video_mode_Timon(pdev, size, frames, compression, snapshot);
|
ret = set_video_mode_Timon(pdev, size, frames, compression, snapshot);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 720:
|
case 720:
|
||||||
case 730:
|
case 730:
|
||||||
case 740:
|
case 740:
|
||||||
|
@ -517,7 +517,7 @@ int pwc_get_brightness(struct pwc_device *pdev)
|
||||||
char buf;
|
char buf;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = RecvControlMsg(GET_LUM_CTL, BRIGHTNESS_FORMATTER, 1);
|
ret = RecvControlMsg(GET_LUM_CTL, BRIGHTNESS_FORMATTER, 1);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
return buf << 9;
|
return buf << 9;
|
||||||
|
@ -566,7 +566,7 @@ int pwc_get_gamma(struct pwc_device *pdev)
|
||||||
{
|
{
|
||||||
char buf;
|
char buf;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = RecvControlMsg(GET_LUM_CTL, GAMMA_FORMATTER, 1);
|
ret = RecvControlMsg(GET_LUM_CTL, GAMMA_FORMATTER, 1);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -622,14 +622,14 @@ static inline int pwc_set_agc(struct pwc_device *pdev, int mode, int value)
|
||||||
{
|
{
|
||||||
char buf;
|
char buf;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (mode)
|
if (mode)
|
||||||
buf = 0x0; /* auto */
|
buf = 0x0; /* auto */
|
||||||
else
|
else
|
||||||
buf = 0xff; /* fixed */
|
buf = 0xff; /* fixed */
|
||||||
|
|
||||||
ret = SendControlMsg(SET_LUM_CTL, AGC_MODE_FORMATTER, 1);
|
ret = SendControlMsg(SET_LUM_CTL, AGC_MODE_FORMATTER, 1);
|
||||||
|
|
||||||
if (!mode && ret >= 0) {
|
if (!mode && ret >= 0) {
|
||||||
if (value < 0)
|
if (value < 0)
|
||||||
value = 0;
|
value = 0;
|
||||||
|
@ -647,7 +647,7 @@ static inline int pwc_get_agc(struct pwc_device *pdev, int *value)
|
||||||
{
|
{
|
||||||
unsigned char buf;
|
unsigned char buf;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = RecvControlMsg(GET_LUM_CTL, AGC_MODE_FORMATTER, 1);
|
ret = RecvControlMsg(GET_LUM_CTL, AGC_MODE_FORMATTER, 1);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -658,7 +658,7 @@ static inline int pwc_get_agc(struct pwc_device *pdev, int *value)
|
||||||
return ret;
|
return ret;
|
||||||
if (buf > 0x3F)
|
if (buf > 0x3F)
|
||||||
buf = 0x3F;
|
buf = 0x3F;
|
||||||
*value = (buf << 10);
|
*value = (buf << 10);
|
||||||
}
|
}
|
||||||
else { /* auto */
|
else { /* auto */
|
||||||
ret = RecvControlMsg(GET_STATUS_CTL, READ_AGC_FORMATTER, 1);
|
ret = RecvControlMsg(GET_STATUS_CTL, READ_AGC_FORMATTER, 1);
|
||||||
|
@ -683,7 +683,7 @@ static inline int pwc_set_shutter_speed(struct pwc_device *pdev, int mode, int v
|
||||||
buf[0] = 0x0; /* auto */
|
buf[0] = 0x0; /* auto */
|
||||||
else
|
else
|
||||||
buf[0] = 0xff; /* fixed */
|
buf[0] = 0xff; /* fixed */
|
||||||
|
|
||||||
ret = SendControlMsg(SET_LUM_CTL, SHUTTER_MODE_FORMATTER, 1);
|
ret = SendControlMsg(SET_LUM_CTL, SHUTTER_MODE_FORMATTER, 1);
|
||||||
|
|
||||||
if (!mode && ret >= 0) {
|
if (!mode && ret >= 0) {
|
||||||
|
@ -713,7 +713,7 @@ static inline int pwc_set_shutter_speed(struct pwc_device *pdev, int mode, int v
|
||||||
ret = SendControlMsg(SET_LUM_CTL, PRESET_SHUTTER_FORMATTER, 2);
|
ret = SendControlMsg(SET_LUM_CTL, PRESET_SHUTTER_FORMATTER, 2);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* POWER */
|
/* POWER */
|
||||||
|
@ -765,22 +765,22 @@ static inline int pwc_restore_factory(struct pwc_device *pdev)
|
||||||
* 02: fluorescent lighting
|
* 02: fluorescent lighting
|
||||||
* 03: manual
|
* 03: manual
|
||||||
* 04: auto
|
* 04: auto
|
||||||
*/
|
*/
|
||||||
static inline int pwc_set_awb(struct pwc_device *pdev, int mode)
|
static inline int pwc_set_awb(struct pwc_device *pdev, int mode)
|
||||||
{
|
{
|
||||||
char buf;
|
char buf;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (mode < 0)
|
if (mode < 0)
|
||||||
mode = 0;
|
mode = 0;
|
||||||
|
|
||||||
if (mode > 4)
|
if (mode > 4)
|
||||||
mode = 4;
|
mode = 4;
|
||||||
|
|
||||||
buf = mode & 0x07; /* just the lowest three bits */
|
buf = mode & 0x07; /* just the lowest three bits */
|
||||||
|
|
||||||
ret = SendControlMsg(SET_CHROM_CTL, WB_MODE_FORMATTER, 1);
|
ret = SendControlMsg(SET_CHROM_CTL, WB_MODE_FORMATTER, 1);
|
||||||
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -790,17 +790,17 @@ static inline int pwc_get_awb(struct pwc_device *pdev)
|
||||||
{
|
{
|
||||||
unsigned char buf;
|
unsigned char buf;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = RecvControlMsg(GET_CHROM_CTL, WB_MODE_FORMATTER, 1);
|
ret = RecvControlMsg(GET_CHROM_CTL, WB_MODE_FORMATTER, 1);
|
||||||
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int pwc_set_red_gain(struct pwc_device *pdev, int value)
|
static inline int pwc_set_red_gain(struct pwc_device *pdev, int value)
|
||||||
{
|
{
|
||||||
unsigned char buf;
|
unsigned char buf;
|
||||||
|
|
||||||
if (value < 0)
|
if (value < 0)
|
||||||
value = 0;
|
value = 0;
|
||||||
|
@ -815,7 +815,7 @@ static inline int pwc_get_red_gain(struct pwc_device *pdev, int *value)
|
||||||
{
|
{
|
||||||
unsigned char buf;
|
unsigned char buf;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = RecvControlMsg(GET_CHROM_CTL, PRESET_MANUAL_RED_GAIN_FORMATTER, 1);
|
ret = RecvControlMsg(GET_CHROM_CTL, PRESET_MANUAL_RED_GAIN_FORMATTER, 1);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -841,7 +841,7 @@ static inline int pwc_get_blue_gain(struct pwc_device *pdev, int *value)
|
||||||
{
|
{
|
||||||
unsigned char buf;
|
unsigned char buf;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = RecvControlMsg(GET_CHROM_CTL, PRESET_MANUAL_BLUE_GAIN_FORMATTER, 1);
|
ret = RecvControlMsg(GET_CHROM_CTL, PRESET_MANUAL_BLUE_GAIN_FORMATTER, 1);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -851,14 +851,14 @@ static inline int pwc_get_blue_gain(struct pwc_device *pdev, int *value)
|
||||||
|
|
||||||
|
|
||||||
/* The following two functions are different, since they only read the
|
/* The following two functions are different, since they only read the
|
||||||
internal red/blue gains, which may be different from the manual
|
internal red/blue gains, which may be different from the manual
|
||||||
gains set or read above.
|
gains set or read above.
|
||||||
*/
|
*/
|
||||||
static inline int pwc_read_red_gain(struct pwc_device *pdev, int *value)
|
static inline int pwc_read_red_gain(struct pwc_device *pdev, int *value)
|
||||||
{
|
{
|
||||||
unsigned char buf;
|
unsigned char buf;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = RecvControlMsg(GET_STATUS_CTL, READ_RED_GAIN_FORMATTER, 1);
|
ret = RecvControlMsg(GET_STATUS_CTL, READ_RED_GAIN_FORMATTER, 1);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -870,7 +870,7 @@ static inline int pwc_read_blue_gain(struct pwc_device *pdev, int *value)
|
||||||
{
|
{
|
||||||
unsigned char buf;
|
unsigned char buf;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = RecvControlMsg(GET_STATUS_CTL, READ_BLUE_GAIN_FORMATTER, 1);
|
ret = RecvControlMsg(GET_STATUS_CTL, READ_BLUE_GAIN_FORMATTER, 1);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -882,7 +882,7 @@ static inline int pwc_read_blue_gain(struct pwc_device *pdev, int *value)
|
||||||
static inline int pwc_set_wb_speed(struct pwc_device *pdev, int speed)
|
static inline int pwc_set_wb_speed(struct pwc_device *pdev, int speed)
|
||||||
{
|
{
|
||||||
unsigned char buf;
|
unsigned char buf;
|
||||||
|
|
||||||
/* useful range is 0x01..0x20 */
|
/* useful range is 0x01..0x20 */
|
||||||
buf = speed / 0x7f0;
|
buf = speed / 0x7f0;
|
||||||
return SendControlMsg(SET_CHROM_CTL, AWB_CONTROL_SPEED_FORMATTER, 1);
|
return SendControlMsg(SET_CHROM_CTL, AWB_CONTROL_SPEED_FORMATTER, 1);
|
||||||
|
@ -892,7 +892,7 @@ static inline int pwc_get_wb_speed(struct pwc_device *pdev, int *value)
|
||||||
{
|
{
|
||||||
unsigned char buf;
|
unsigned char buf;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = RecvControlMsg(GET_CHROM_CTL, AWB_CONTROL_SPEED_FORMATTER, 1);
|
ret = RecvControlMsg(GET_CHROM_CTL, AWB_CONTROL_SPEED_FORMATTER, 1);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -904,7 +904,7 @@ static inline int pwc_get_wb_speed(struct pwc_device *pdev, int *value)
|
||||||
static inline int pwc_set_wb_delay(struct pwc_device *pdev, int delay)
|
static inline int pwc_set_wb_delay(struct pwc_device *pdev, int delay)
|
||||||
{
|
{
|
||||||
unsigned char buf;
|
unsigned char buf;
|
||||||
|
|
||||||
/* useful range is 0x01..0x3F */
|
/* useful range is 0x01..0x3F */
|
||||||
buf = (delay >> 10);
|
buf = (delay >> 10);
|
||||||
return SendControlMsg(SET_CHROM_CTL, AWB_CONTROL_DELAY_FORMATTER, 1);
|
return SendControlMsg(SET_CHROM_CTL, AWB_CONTROL_DELAY_FORMATTER, 1);
|
||||||
|
@ -914,7 +914,7 @@ static inline int pwc_get_wb_delay(struct pwc_device *pdev, int *value)
|
||||||
{
|
{
|
||||||
unsigned char buf;
|
unsigned char buf;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = RecvControlMsg(GET_CHROM_CTL, AWB_CONTROL_DELAY_FORMATTER, 1);
|
ret = RecvControlMsg(GET_CHROM_CTL, AWB_CONTROL_DELAY_FORMATTER, 1);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -950,7 +950,7 @@ static int pwc_get_leds(struct pwc_device *pdev, int *on_value, int *off_value)
|
||||||
{
|
{
|
||||||
unsigned char buf[2];
|
unsigned char buf[2];
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (pdev->type < 730) {
|
if (pdev->type < 730) {
|
||||||
*on_value = -1;
|
*on_value = -1;
|
||||||
*off_value = -1;
|
*off_value = -1;
|
||||||
|
@ -969,7 +969,7 @@ static inline int pwc_set_contour(struct pwc_device *pdev, int contour)
|
||||||
{
|
{
|
||||||
unsigned char buf;
|
unsigned char buf;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (contour < 0)
|
if (contour < 0)
|
||||||
buf = 0xff; /* auto contour on */
|
buf = 0xff; /* auto contour on */
|
||||||
else
|
else
|
||||||
|
@ -977,16 +977,16 @@ static inline int pwc_set_contour(struct pwc_device *pdev, int contour)
|
||||||
ret = SendControlMsg(SET_LUM_CTL, AUTO_CONTOUR_FORMATTER, 1);
|
ret = SendControlMsg(SET_LUM_CTL, AUTO_CONTOUR_FORMATTER, 1);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
if (contour < 0)
|
if (contour < 0)
|
||||||
return 0;
|
return 0;
|
||||||
if (contour > 0xffff)
|
if (contour > 0xffff)
|
||||||
contour = 0xffff;
|
contour = 0xffff;
|
||||||
|
|
||||||
buf = (contour >> 10); /* contour preset is [0..3f] */
|
buf = (contour >> 10); /* contour preset is [0..3f] */
|
||||||
ret = SendControlMsg(SET_LUM_CTL, PRESET_CONTOUR_FORMATTER, 1);
|
ret = SendControlMsg(SET_LUM_CTL, PRESET_CONTOUR_FORMATTER, 1);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -994,7 +994,7 @@ static inline int pwc_get_contour(struct pwc_device *pdev, int *contour)
|
||||||
{
|
{
|
||||||
unsigned char buf;
|
unsigned char buf;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = RecvControlMsg(GET_LUM_CTL, AUTO_CONTOUR_FORMATTER, 1);
|
ret = RecvControlMsg(GET_LUM_CTL, AUTO_CONTOUR_FORMATTER, 1);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -1002,7 +1002,7 @@ static inline int pwc_get_contour(struct pwc_device *pdev, int *contour)
|
||||||
if (buf == 0) {
|
if (buf == 0) {
|
||||||
/* auto mode off, query current preset value */
|
/* auto mode off, query current preset value */
|
||||||
ret = RecvControlMsg(GET_LUM_CTL, PRESET_CONTOUR_FORMATTER, 1);
|
ret = RecvControlMsg(GET_LUM_CTL, PRESET_CONTOUR_FORMATTER, 1);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
*contour = buf << 10;
|
*contour = buf << 10;
|
||||||
}
|
}
|
||||||
|
@ -1015,7 +1015,7 @@ static inline int pwc_get_contour(struct pwc_device *pdev, int *contour)
|
||||||
static inline int pwc_set_backlight(struct pwc_device *pdev, int backlight)
|
static inline int pwc_set_backlight(struct pwc_device *pdev, int backlight)
|
||||||
{
|
{
|
||||||
unsigned char buf;
|
unsigned char buf;
|
||||||
|
|
||||||
if (backlight)
|
if (backlight)
|
||||||
buf = 0xff;
|
buf = 0xff;
|
||||||
else
|
else
|
||||||
|
@ -1027,7 +1027,7 @@ static inline int pwc_get_backlight(struct pwc_device *pdev, int *backlight)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
unsigned char buf;
|
unsigned char buf;
|
||||||
|
|
||||||
ret = RecvControlMsg(GET_LUM_CTL, BACK_LIGHT_COMPENSATION_FORMATTER, 1);
|
ret = RecvControlMsg(GET_LUM_CTL, BACK_LIGHT_COMPENSATION_FORMATTER, 1);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -1039,7 +1039,7 @@ static inline int pwc_get_backlight(struct pwc_device *pdev, int *backlight)
|
||||||
static inline int pwc_set_flicker(struct pwc_device *pdev, int flicker)
|
static inline int pwc_set_flicker(struct pwc_device *pdev, int flicker)
|
||||||
{
|
{
|
||||||
unsigned char buf;
|
unsigned char buf;
|
||||||
|
|
||||||
if (flicker)
|
if (flicker)
|
||||||
buf = 0xff;
|
buf = 0xff;
|
||||||
else
|
else
|
||||||
|
@ -1051,7 +1051,7 @@ static inline int pwc_get_flicker(struct pwc_device *pdev, int *flicker)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
unsigned char buf;
|
unsigned char buf;
|
||||||
|
|
||||||
ret = RecvControlMsg(GET_LUM_CTL, FLICKERLESS_MODE_FORMATTER, 1);
|
ret = RecvControlMsg(GET_LUM_CTL, FLICKERLESS_MODE_FORMATTER, 1);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -1076,7 +1076,7 @@ static inline int pwc_get_dynamic_noise(struct pwc_device *pdev, int *noise)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
unsigned char buf;
|
unsigned char buf;
|
||||||
|
|
||||||
ret = RecvControlMsg(GET_LUM_CTL, DYNAMIC_NOISE_CONTROL_FORMATTER, 1);
|
ret = RecvControlMsg(GET_LUM_CTL, DYNAMIC_NOISE_CONTROL_FORMATTER, 1);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -1087,7 +1087,7 @@ static inline int pwc_get_dynamic_noise(struct pwc_device *pdev, int *noise)
|
||||||
static int pwc_mpt_reset(struct pwc_device *pdev, int flags)
|
static int pwc_mpt_reset(struct pwc_device *pdev, int flags)
|
||||||
{
|
{
|
||||||
unsigned char buf;
|
unsigned char buf;
|
||||||
|
|
||||||
buf = flags & 0x03; // only lower two bits are currently used
|
buf = flags & 0x03; // only lower two bits are currently used
|
||||||
return SendControlMsg(SET_MPT_CTL, PT_RESET_CONTROL_FORMATTER, 1);
|
return SendControlMsg(SET_MPT_CTL, PT_RESET_CONTROL_FORMATTER, 1);
|
||||||
}
|
}
|
||||||
|
@ -1095,7 +1095,7 @@ static int pwc_mpt_reset(struct pwc_device *pdev, int flags)
|
||||||
static inline int pwc_mpt_set_angle(struct pwc_device *pdev, int pan, int tilt)
|
static inline int pwc_mpt_set_angle(struct pwc_device *pdev, int pan, int tilt)
|
||||||
{
|
{
|
||||||
unsigned char buf[4];
|
unsigned char buf[4];
|
||||||
|
|
||||||
/* set new relative angle; angles are expressed in degrees * 100,
|
/* set new relative angle; angles are expressed in degrees * 100,
|
||||||
but cam as .5 degree resolution, hence divide by 200. Also
|
but cam as .5 degree resolution, hence divide by 200. Also
|
||||||
the angle must be multiplied by 64 before it's send to
|
the angle must be multiplied by 64 before it's send to
|
||||||
|
@ -1114,7 +1114,7 @@ static inline int pwc_mpt_get_status(struct pwc_device *pdev, struct pwc_mpt_sta
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
unsigned char buf[5];
|
unsigned char buf[5];
|
||||||
|
|
||||||
ret = RecvControlMsg(GET_MPT_CTL, PT_STATUS_FORMATTER, 5);
|
ret = RecvControlMsg(GET_MPT_CTL, PT_STATUS_FORMATTER, 5);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -1129,14 +1129,14 @@ int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor)
|
||||||
{
|
{
|
||||||
unsigned char buf;
|
unsigned char buf;
|
||||||
int ret = -1, request;
|
int ret = -1, request;
|
||||||
|
|
||||||
if (pdev->type < 675)
|
if (pdev->type < 675)
|
||||||
request = SENSOR_TYPE_FORMATTER1;
|
request = SENSOR_TYPE_FORMATTER1;
|
||||||
else if (pdev->type < 730)
|
else if (pdev->type < 730)
|
||||||
return -1; /* The Vesta series doesn't have this call */
|
return -1; /* The Vesta series doesn't have this call */
|
||||||
else
|
else
|
||||||
request = SENSOR_TYPE_FORMATTER2;
|
request = SENSOR_TYPE_FORMATTER2;
|
||||||
|
|
||||||
ret = RecvControlMsg(GET_STATUS_CTL, request, 1);
|
ret = RecvControlMsg(GET_STATUS_CTL, request, 1);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -1163,23 +1163,23 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg)
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case VIDIOCPWCSUSER:
|
case VIDIOCPWCSUSER:
|
||||||
{
|
{
|
||||||
if (pwc_save_user(pdev))
|
if (pwc_save_user(pdev))
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case VIDIOCPWCFACTORY:
|
case VIDIOCPWCFACTORY:
|
||||||
{
|
{
|
||||||
if (pwc_restore_factory(pdev))
|
if (pwc_restore_factory(pdev))
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case VIDIOCPWCSCQUAL:
|
case VIDIOCPWCSCQUAL:
|
||||||
{
|
{
|
||||||
int *qual = arg;
|
int *qual = arg;
|
||||||
|
|
||||||
if (*qual < 0 || *qual > 3)
|
if (*qual < 0 || *qual > 3)
|
||||||
|
@ -1190,14 +1190,14 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg)
|
||||||
pdev->vcompression = *qual;
|
pdev->vcompression = *qual;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case VIDIOCPWCGCQUAL:
|
case VIDIOCPWCGCQUAL:
|
||||||
{
|
{
|
||||||
int *qual = arg;
|
int *qual = arg;
|
||||||
*qual = pdev->vcompression;
|
*qual = pdev->vcompression;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case VIDIOCPWCPROBE:
|
case VIDIOCPWCPROBE:
|
||||||
{
|
{
|
||||||
struct pwc_probe *probe = arg;
|
struct pwc_probe *probe = arg;
|
||||||
|
@ -1220,27 +1220,27 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg)
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case VIDIOCPWCGAGC:
|
case VIDIOCPWCGAGC:
|
||||||
{
|
{
|
||||||
int *agc = arg;
|
int *agc = arg;
|
||||||
|
|
||||||
if (pwc_get_agc(pdev, agc))
|
if (pwc_get_agc(pdev, agc))
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case VIDIOCPWCSSHUTTER:
|
case VIDIOCPWCSSHUTTER:
|
||||||
{
|
{
|
||||||
int *shutter_speed = arg;
|
int *shutter_speed = arg;
|
||||||
ret = pwc_set_shutter_speed(pdev, *shutter_speed < 0 ? 1 : 0, *shutter_speed);
|
ret = pwc_set_shutter_speed(pdev, *shutter_speed < 0 ? 1 : 0, *shutter_speed);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case VIDIOCPWCSAWB:
|
case VIDIOCPWCSAWB:
|
||||||
{
|
{
|
||||||
struct pwc_whitebalance *wb = arg;
|
struct pwc_whitebalance *wb = arg;
|
||||||
|
|
||||||
ret = pwc_set_awb(pdev, wb->mode);
|
ret = pwc_set_awb(pdev, wb->mode);
|
||||||
if (ret >= 0 && wb->mode == PWC_WB_MANUAL) {
|
if (ret >= 0 && wb->mode == PWC_WB_MANUAL) {
|
||||||
pwc_set_red_gain(pdev, wb->manual_red);
|
pwc_set_red_gain(pdev, wb->manual_red);
|
||||||
|
@ -1270,18 +1270,18 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg)
|
||||||
ret = pwc_read_red_gain(pdev, &wb->read_red);
|
ret = pwc_read_red_gain(pdev, &wb->read_red);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
break;
|
break;
|
||||||
ret = pwc_read_blue_gain(pdev, &wb->read_blue);
|
ret = pwc_read_blue_gain(pdev, &wb->read_blue);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case VIDIOCPWCSAWBSPEED:
|
case VIDIOCPWCSAWBSPEED:
|
||||||
{
|
{
|
||||||
struct pwc_wb_speed *wbs = arg;
|
struct pwc_wb_speed *wbs = arg;
|
||||||
|
|
||||||
if (wbs->control_speed > 0) {
|
if (wbs->control_speed > 0) {
|
||||||
ret = pwc_set_wb_speed(pdev, wbs->control_speed);
|
ret = pwc_set_wb_speed(pdev, wbs->control_speed);
|
||||||
}
|
}
|
||||||
|
@ -1290,11 +1290,11 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case VIDIOCPWCGAWBSPEED:
|
case VIDIOCPWCGAWBSPEED:
|
||||||
{
|
{
|
||||||
struct pwc_wb_speed *wbs = arg;
|
struct pwc_wb_speed *wbs = arg;
|
||||||
|
|
||||||
ret = pwc_get_wb_speed(pdev, &wbs->control_speed);
|
ret = pwc_get_wb_speed(pdev, &wbs->control_speed);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
break;
|
break;
|
||||||
|
@ -1304,7 +1304,7 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case VIDIOCPWCSLED:
|
case VIDIOCPWCSLED:
|
||||||
{
|
{
|
||||||
struct pwc_leds *leds = arg;
|
struct pwc_leds *leds = arg;
|
||||||
ret = pwc_set_leds(pdev, leds->led_on, leds->led_off);
|
ret = pwc_set_leds(pdev, leds->led_on, leds->led_off);
|
||||||
|
@ -1325,14 +1325,14 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg)
|
||||||
ret = pwc_set_contour(pdev, *contour);
|
ret = pwc_set_contour(pdev, *contour);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case VIDIOCPWCGCONTOUR:
|
case VIDIOCPWCGCONTOUR:
|
||||||
{
|
{
|
||||||
int *contour = arg;
|
int *contour = arg;
|
||||||
ret = pwc_get_contour(pdev, contour);
|
ret = pwc_get_contour(pdev, contour);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case VIDIOCPWCSBACKLIGHT:
|
case VIDIOCPWCSBACKLIGHT:
|
||||||
{
|
{
|
||||||
int *backlight = arg;
|
int *backlight = arg;
|
||||||
|
@ -1346,7 +1346,7 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg)
|
||||||
ret = pwc_get_backlight(pdev, backlight);
|
ret = pwc_get_backlight(pdev, backlight);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case VIDIOCPWCSFLICKER:
|
case VIDIOCPWCSFLICKER:
|
||||||
{
|
{
|
||||||
int *flicker = arg;
|
int *flicker = arg;
|
||||||
|
@ -1360,14 +1360,14 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg)
|
||||||
ret = pwc_get_flicker(pdev, flicker);
|
ret = pwc_get_flicker(pdev, flicker);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case VIDIOCPWCSDYNNOISE:
|
case VIDIOCPWCSDYNNOISE:
|
||||||
{
|
{
|
||||||
int *dynnoise = arg;
|
int *dynnoise = arg;
|
||||||
ret = pwc_set_dynamic_noise(pdev, *dynnoise);
|
ret = pwc_set_dynamic_noise(pdev, *dynnoise);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case VIDIOCPWCGDYNNOISE:
|
case VIDIOCPWCGDYNNOISE:
|
||||||
{
|
{
|
||||||
int *dynnoise = arg;
|
int *dynnoise = arg;
|
||||||
|
@ -1381,61 +1381,61 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg)
|
||||||
size->width = pdev->image.x;
|
size->width = pdev->image.x;
|
||||||
size->height = pdev->image.y;
|
size->height = pdev->image.y;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case VIDIOCPWCMPTRESET:
|
case VIDIOCPWCMPTRESET:
|
||||||
{
|
{
|
||||||
if (pdev->features & FEATURE_MOTOR_PANTILT)
|
if (pdev->features & FEATURE_MOTOR_PANTILT)
|
||||||
{
|
{
|
||||||
int *flags = arg;
|
int *flags = arg;
|
||||||
|
|
||||||
ret = pwc_mpt_reset(pdev, *flags);
|
ret = pwc_mpt_reset(pdev, *flags);
|
||||||
if (ret >= 0)
|
if (ret >= 0)
|
||||||
{
|
{
|
||||||
pdev->pan_angle = 0;
|
pdev->pan_angle = 0;
|
||||||
pdev->tilt_angle = 0;
|
pdev->tilt_angle = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ret = -ENXIO;
|
ret = -ENXIO;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case VIDIOCPWCMPTGRANGE:
|
case VIDIOCPWCMPTGRANGE:
|
||||||
{
|
{
|
||||||
if (pdev->features & FEATURE_MOTOR_PANTILT)
|
if (pdev->features & FEATURE_MOTOR_PANTILT)
|
||||||
{
|
{
|
||||||
struct pwc_mpt_range *range = arg;
|
struct pwc_mpt_range *range = arg;
|
||||||
*range = pdev->angle_range;
|
*range = pdev->angle_range;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ret = -ENXIO;
|
ret = -ENXIO;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case VIDIOCPWCMPTSANGLE:
|
case VIDIOCPWCMPTSANGLE:
|
||||||
{
|
{
|
||||||
int new_pan, new_tilt;
|
int new_pan, new_tilt;
|
||||||
|
|
||||||
if (pdev->features & FEATURE_MOTOR_PANTILT)
|
if (pdev->features & FEATURE_MOTOR_PANTILT)
|
||||||
{
|
{
|
||||||
struct pwc_mpt_angles *angles = arg;
|
struct pwc_mpt_angles *angles = arg;
|
||||||
/* The camera can only set relative angles, so
|
/* The camera can only set relative angles, so
|
||||||
do some calculations when getting an absolute angle .
|
do some calculations when getting an absolute angle .
|
||||||
*/
|
*/
|
||||||
if (angles->absolute)
|
if (angles->absolute)
|
||||||
{
|
{
|
||||||
new_pan = angles->pan;
|
new_pan = angles->pan;
|
||||||
new_tilt = angles->tilt;
|
new_tilt = angles->tilt;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
new_pan = pdev->pan_angle + angles->pan;
|
new_pan = pdev->pan_angle + angles->pan;
|
||||||
new_tilt = pdev->tilt_angle + angles->tilt;
|
new_tilt = pdev->tilt_angle + angles->tilt;
|
||||||
}
|
}
|
||||||
/* check absolute ranges */
|
/* check absolute ranges */
|
||||||
if (new_pan < pdev->angle_range.pan_min ||
|
if (new_pan < pdev->angle_range.pan_min ||
|
||||||
|
@ -1463,53 +1463,53 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg)
|
||||||
pdev->tilt_angle += new_tilt;
|
pdev->tilt_angle += new_tilt;
|
||||||
}
|
}
|
||||||
if (ret == -EPIPE) /* stall -> out of range */
|
if (ret == -EPIPE) /* stall -> out of range */
|
||||||
ret = -ERANGE;
|
ret = -ERANGE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ret = -ENXIO;
|
ret = -ENXIO;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case VIDIOCPWCMPTGANGLE:
|
case VIDIOCPWCMPTGANGLE:
|
||||||
{
|
{
|
||||||
|
|
||||||
if (pdev->features & FEATURE_MOTOR_PANTILT)
|
|
||||||
{
|
|
||||||
struct pwc_mpt_angles *angles = arg;
|
|
||||||
|
|
||||||
angles->absolute = 1;
|
if (pdev->features & FEATURE_MOTOR_PANTILT)
|
||||||
angles->pan = pdev->pan_angle;
|
{
|
||||||
angles->tilt = pdev->tilt_angle;
|
struct pwc_mpt_angles *angles = arg;
|
||||||
}
|
|
||||||
else
|
angles->absolute = 1;
|
||||||
{
|
angles->pan = pdev->pan_angle;
|
||||||
ret = -ENXIO;
|
angles->tilt = pdev->tilt_angle;
|
||||||
}
|
}
|
||||||
break;
|
else
|
||||||
}
|
{
|
||||||
|
ret = -ENXIO;
|
||||||
case VIDIOCPWCMPTSTATUS:
|
}
|
||||||
{
|
break;
|
||||||
if (pdev->features & FEATURE_MOTOR_PANTILT)
|
}
|
||||||
{
|
|
||||||
struct pwc_mpt_status *status = arg;
|
case VIDIOCPWCMPTSTATUS:
|
||||||
ret = pwc_mpt_get_status(pdev, status);
|
{
|
||||||
}
|
if (pdev->features & FEATURE_MOTOR_PANTILT)
|
||||||
else
|
{
|
||||||
{
|
struct pwc_mpt_status *status = arg;
|
||||||
ret = -ENXIO;
|
ret = pwc_mpt_get_status(pdev, status);
|
||||||
}
|
}
|
||||||
break;
|
else
|
||||||
|
{
|
||||||
|
ret = -ENXIO;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case VIDIOCPWCGVIDCMD:
|
case VIDIOCPWCGVIDCMD:
|
||||||
{
|
{
|
||||||
struct pwc_video_command *cmd = arg;
|
struct pwc_video_command *cmd = arg;
|
||||||
|
|
||||||
cmd->type = pdev->type;
|
cmd->type = pdev->type;
|
||||||
cmd->release = pdev->release;
|
cmd->release = pdev->release;
|
||||||
cmd->command_len = pdev->cmd_len;
|
cmd->command_len = pdev->cmd_len;
|
||||||
memcpy(&cmd->command_buf, pdev->cmd_buf, pdev->cmd_len);
|
memcpy(&cmd->command_buf, pdev->cmd_buf, pdev->cmd_len);
|
||||||
|
@ -1531,7 +1531,7 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg)
|
||||||
ret = -ENOIOCTLCMD;
|
ret = -ENOIOCTLCMD;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret > 0)
|
if (ret > 0)
|
||||||
return 0;
|
return 0;
|
||||||
return ret;
|
return ret;
|
|
@ -25,18 +25,18 @@
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This code forms the interface between the USB layers and the Philips
|
This code forms the interface between the USB layers and the Philips
|
||||||
specific stuff. Some adanved stuff of the driver falls under an
|
specific stuff. Some adanved stuff of the driver falls under an
|
||||||
NDA, signed between me and Philips B.V., Eindhoven, the Netherlands, and
|
NDA, signed between me and Philips B.V., Eindhoven, the Netherlands, and
|
||||||
is thus not distributed in source form. The binary pwcx.o module
|
is thus not distributed in source form. The binary pwcx.o module
|
||||||
contains the code that falls under the NDA.
|
contains the code that falls under the NDA.
|
||||||
|
|
||||||
In case you're wondering: 'pwc' stands for "Philips WebCam", but
|
In case you're wondering: 'pwc' stands for "Philips WebCam", but
|
||||||
I really didn't want to type 'philips_web_cam' every time (I'm lazy as
|
I really didn't want to type 'philips_web_cam' every time (I'm lazy as
|
||||||
any Linux kernel hacker, but I don't like uncomprehensible abbreviations
|
any Linux kernel hacker, but I don't like uncomprehensible abbreviations
|
||||||
without explanation).
|
without explanation).
|
||||||
|
|
||||||
Oh yes, convention: to disctinguish between all the various pointers to
|
Oh yes, convention: to disctinguish between all the various pointers to
|
||||||
device-structures, I use these names for the pointer variables:
|
device-structures, I use these names for the pointer variables:
|
||||||
udev: struct usb_device *
|
udev: struct usb_device *
|
||||||
|
@ -170,14 +170,14 @@ static struct video_device pwc_template = {
|
||||||
|
|
||||||
/* Okay, this is some magic that I worked out and the reasoning behind it...
|
/* Okay, this is some magic that I worked out and the reasoning behind it...
|
||||||
|
|
||||||
The biggest problem with any USB device is of course: "what to do
|
The biggest problem with any USB device is of course: "what to do
|
||||||
when the user unplugs the device while it is in use by an application?"
|
when the user unplugs the device while it is in use by an application?"
|
||||||
We have several options:
|
We have several options:
|
||||||
1) Curse them with the 7 plagues when they do (requires divine intervention)
|
1) Curse them with the 7 plagues when they do (requires divine intervention)
|
||||||
2) Tell them not to (won't work: they'll do it anyway)
|
2) Tell them not to (won't work: they'll do it anyway)
|
||||||
3) Oops the kernel (this will have a negative effect on a user's uptime)
|
3) Oops the kernel (this will have a negative effect on a user's uptime)
|
||||||
4) Do something sensible.
|
4) Do something sensible.
|
||||||
|
|
||||||
Of course, we go for option 4.
|
Of course, we go for option 4.
|
||||||
|
|
||||||
It happens that this device will be linked to two times, once from
|
It happens that this device will be linked to two times, once from
|
||||||
|
@ -185,15 +185,15 @@ static struct video_device pwc_template = {
|
||||||
pointers. This is done when the device is probed() and all initialization
|
pointers. This is done when the device is probed() and all initialization
|
||||||
succeeded. The pwc_device struct links back to both structures.
|
succeeded. The pwc_device struct links back to both structures.
|
||||||
|
|
||||||
When a device is unplugged while in use it will be removed from the
|
When a device is unplugged while in use it will be removed from the
|
||||||
list of known USB devices; I also de-register it as a V4L device, but
|
list of known USB devices; I also de-register it as a V4L device, but
|
||||||
unfortunately I can't free the memory since the struct is still in use
|
unfortunately I can't free the memory since the struct is still in use
|
||||||
by the file descriptor. This free-ing is then deferend until the first
|
by the file descriptor. This free-ing is then deferend until the first
|
||||||
opportunity. Crude, but it works.
|
opportunity. Crude, but it works.
|
||||||
|
|
||||||
A small 'advantage' is that if a user unplugs the cam and plugs it back
|
A small 'advantage' is that if a user unplugs the cam and plugs it back
|
||||||
in, it should get assigned the same video device minor, but unfortunately
|
in, it should get assigned the same video device minor, but unfortunately
|
||||||
it's non-trivial to re-link the cam back to the video device... (that
|
it's non-trivial to re-link the cam back to the video device... (that
|
||||||
would surely be magic! :))
|
would surely be magic! :))
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -203,14 +203,14 @@ static struct video_device pwc_template = {
|
||||||
/* Here we want the physical address of the memory.
|
/* Here we want the physical address of the memory.
|
||||||
* This is used when initializing the contents of the area.
|
* This is used when initializing the contents of the area.
|
||||||
*/
|
*/
|
||||||
static inline unsigned long kvirt_to_pa(unsigned long adr)
|
static inline unsigned long kvirt_to_pa(unsigned long adr)
|
||||||
{
|
{
|
||||||
unsigned long kva, ret;
|
unsigned long kva, ret;
|
||||||
|
|
||||||
kva = (unsigned long) page_address(vmalloc_to_page((void *)adr));
|
kva = (unsigned long) page_address(vmalloc_to_page((void *)adr));
|
||||||
kva |= adr & (PAGE_SIZE-1); /* restore the offset */
|
kva |= adr & (PAGE_SIZE-1); /* restore the offset */
|
||||||
ret = __pa(kva);
|
ret = __pa(kva);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void * rvmalloc(unsigned long size)
|
static void * rvmalloc(unsigned long size)
|
||||||
|
@ -219,13 +219,13 @@ static void * rvmalloc(unsigned long size)
|
||||||
unsigned long adr;
|
unsigned long adr;
|
||||||
|
|
||||||
size=PAGE_ALIGN(size);
|
size=PAGE_ALIGN(size);
|
||||||
mem=vmalloc_32(size);
|
mem=vmalloc_32(size);
|
||||||
if (mem)
|
if (mem)
|
||||||
{
|
{
|
||||||
memset(mem, 0, size); /* Clear the ram out, no junk to the user */
|
memset(mem, 0, size); /* Clear the ram out, no junk to the user */
|
||||||
adr=(unsigned long) mem;
|
adr=(unsigned long) mem;
|
||||||
while (size > 0)
|
while (size > 0)
|
||||||
{
|
{
|
||||||
SetPageReserved(vmalloc_to_page((void *)adr));
|
SetPageReserved(vmalloc_to_page((void *)adr));
|
||||||
adr+=PAGE_SIZE;
|
adr+=PAGE_SIZE;
|
||||||
size-=PAGE_SIZE;
|
size-=PAGE_SIZE;
|
||||||
|
@ -236,13 +236,13 @@ static void * rvmalloc(unsigned long size)
|
||||||
|
|
||||||
static void rvfree(void * mem, unsigned long size)
|
static void rvfree(void * mem, unsigned long size)
|
||||||
{
|
{
|
||||||
unsigned long adr;
|
unsigned long adr;
|
||||||
|
|
||||||
if (mem)
|
if (mem)
|
||||||
{
|
{
|
||||||
adr=(unsigned long) mem;
|
adr=(unsigned long) mem;
|
||||||
while ((long) size > 0)
|
while ((long) size > 0)
|
||||||
{
|
{
|
||||||
ClearPageReserved(vmalloc_to_page((void *)adr));
|
ClearPageReserved(vmalloc_to_page((void *)adr));
|
||||||
adr+=PAGE_SIZE;
|
adr+=PAGE_SIZE;
|
||||||
size-=PAGE_SIZE;
|
size-=PAGE_SIZE;
|
||||||
|
@ -263,13 +263,13 @@ static int pwc_allocate_buffers(struct pwc_device *pdev)
|
||||||
|
|
||||||
if (pdev == NULL)
|
if (pdev == NULL)
|
||||||
return -ENXIO;
|
return -ENXIO;
|
||||||
|
|
||||||
#ifdef PWC_MAGIC
|
#ifdef PWC_MAGIC
|
||||||
if (pdev->magic != PWC_MAGIC) {
|
if (pdev->magic != PWC_MAGIC) {
|
||||||
Err("allocate_buffers(): magic failed.\n");
|
Err("allocate_buffers(): magic failed.\n");
|
||||||
return -ENXIO;
|
return -ENXIO;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
/* Allocate Isochronous pipe buffers */
|
/* Allocate Isochronous pipe buffers */
|
||||||
for (i = 0; i < MAX_ISO_BUFS; i++) {
|
for (i = 0; i < MAX_ISO_BUFS; i++) {
|
||||||
if (pdev->sbuf[i].data == NULL) {
|
if (pdev->sbuf[i].data == NULL) {
|
||||||
|
@ -308,7 +308,7 @@ static int pwc_allocate_buffers(struct pwc_device *pdev)
|
||||||
memset(kbuf, 128, PWC_FRAME_SIZE);
|
memset(kbuf, 128, PWC_FRAME_SIZE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate decompressor table space */
|
/* Allocate decompressor table space */
|
||||||
kbuf = NULL;
|
kbuf = NULL;
|
||||||
switch (pdev->type)
|
switch (pdev->type)
|
||||||
|
@ -320,7 +320,7 @@ static int pwc_allocate_buffers(struct pwc_device *pdev)
|
||||||
case 730:
|
case 730:
|
||||||
case 740:
|
case 740:
|
||||||
case 750:
|
case 750:
|
||||||
#if 0
|
#if 0
|
||||||
Trace(TRACE_MEMORY,"private_data(%zu)\n",sizeof(struct pwc_dec23_private));
|
Trace(TRACE_MEMORY,"private_data(%zu)\n",sizeof(struct pwc_dec23_private));
|
||||||
kbuf = kmalloc(sizeof(struct pwc_dec23_private), GFP_KERNEL); /* Timon & Kiara */
|
kbuf = kmalloc(sizeof(struct pwc_dec23_private), GFP_KERNEL); /* Timon & Kiara */
|
||||||
break;
|
break;
|
||||||
|
@ -329,11 +329,11 @@ static int pwc_allocate_buffers(struct pwc_device *pdev)
|
||||||
/* TODO & FIXME */
|
/* TODO & FIXME */
|
||||||
kbuf = kmalloc(sizeof(struct pwc_dec23_private), GFP_KERNEL);
|
kbuf = kmalloc(sizeof(struct pwc_dec23_private), GFP_KERNEL);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
pdev->decompress_data = kbuf;
|
pdev->decompress_data = kbuf;
|
||||||
|
|
||||||
/* Allocate image buffer; double buffer for mmap() */
|
/* Allocate image buffer; double buffer for mmap() */
|
||||||
kbuf = rvmalloc(default_mbufs * pdev->len_per_image);
|
kbuf = rvmalloc(default_mbufs * pdev->len_per_image);
|
||||||
if (kbuf == NULL) {
|
if (kbuf == NULL) {
|
||||||
|
@ -348,7 +348,7 @@ static int pwc_allocate_buffers(struct pwc_device *pdev)
|
||||||
pdev->image_ptr[i] = NULL;
|
pdev->image_ptr[i] = NULL;
|
||||||
|
|
||||||
kbuf = NULL;
|
kbuf = NULL;
|
||||||
|
|
||||||
Trace(TRACE_MEMORY, "<< pwc_allocate_buffers()\n");
|
Trace(TRACE_MEMORY, "<< pwc_allocate_buffers()\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -366,7 +366,7 @@ static void pwc_free_buffers(struct pwc_device *pdev)
|
||||||
Err("free_buffers(): magic failed.\n");
|
Err("free_buffers(): magic failed.\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Release Iso-pipe buffers */
|
/* Release Iso-pipe buffers */
|
||||||
for (i = 0; i < MAX_ISO_BUFS; i++)
|
for (i = 0; i < MAX_ISO_BUFS; i++)
|
||||||
|
@ -403,17 +403,17 @@ static void pwc_free_buffers(struct pwc_device *pdev)
|
||||||
rvfree(pdev->image_data, default_mbufs * pdev->len_per_image);
|
rvfree(pdev->image_data, default_mbufs * pdev->len_per_image);
|
||||||
}
|
}
|
||||||
pdev->image_data = NULL;
|
pdev->image_data = NULL;
|
||||||
|
|
||||||
Trace(TRACE_MEMORY, "Leaving free_buffers().\n");
|
Trace(TRACE_MEMORY, "Leaving free_buffers().\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The frame & image buffer mess.
|
/* The frame & image buffer mess.
|
||||||
|
|
||||||
Yes, this is a mess. Well, it used to be simple, but alas... In this
|
Yes, this is a mess. Well, it used to be simple, but alas... In this
|
||||||
module, 3 buffers schemes are used to get the data from the USB bus to
|
module, 3 buffers schemes are used to get the data from the USB bus to
|
||||||
the user program. The first scheme involves the ISO buffers (called thus
|
the user program. The first scheme involves the ISO buffers (called thus
|
||||||
since they transport ISO data from the USB controller), and not really
|
since they transport ISO data from the USB controller), and not really
|
||||||
interesting. Suffices to say the data from this buffer is quickly
|
interesting. Suffices to say the data from this buffer is quickly
|
||||||
gathered in an interrupt handler (pwc_isoc_handler) and placed into the
|
gathered in an interrupt handler (pwc_isoc_handler) and placed into the
|
||||||
frame buffer.
|
frame buffer.
|
||||||
|
|
||||||
|
@ -443,8 +443,8 @@ static void pwc_free_buffers(struct pwc_device *pdev)
|
||||||
and a 'full' frame list:
|
and a 'full' frame list:
|
||||||
* Initially, all frame buffers but one are on the 'empty' list; the one
|
* Initially, all frame buffers but one are on the 'empty' list; the one
|
||||||
remaining buffer is our initial fill frame.
|
remaining buffer is our initial fill frame.
|
||||||
* If a frame is needed for filling, we try to take it from the 'empty'
|
* If a frame is needed for filling, we try to take it from the 'empty'
|
||||||
list, unless that list is empty, in which case we take the buffer at
|
list, unless that list is empty, in which case we take the buffer at
|
||||||
the head of the 'full' list.
|
the head of the 'full' list.
|
||||||
* When our fill buffer has been filled, it is appended to the 'full'
|
* When our fill buffer has been filled, it is appended to the 'full'
|
||||||
list.
|
list.
|
||||||
|
@ -646,7 +646,7 @@ static void pwc_isoc_handler(struct urb *urb, struct pt_regs *regs)
|
||||||
case -ETIMEDOUT: errmsg = "NAK (device does not respond)"; break;
|
case -ETIMEDOUT: errmsg = "NAK (device does not respond)"; break;
|
||||||
}
|
}
|
||||||
Trace(TRACE_FLOW, "pwc_isoc_handler() called with status %d [%s].\n", urb->status, errmsg);
|
Trace(TRACE_FLOW, "pwc_isoc_handler() called with status %d [%s].\n", urb->status, errmsg);
|
||||||
/* Give up after a number of contiguous errors on the USB bus.
|
/* Give up after a number of contiguous errors on the USB bus.
|
||||||
Appearantly something is wrong so we simulate an unplug event.
|
Appearantly something is wrong so we simulate an unplug event.
|
||||||
*/
|
*/
|
||||||
if (++pdev->visoc_errors > MAX_ISOC_ERRORS)
|
if (++pdev->visoc_errors > MAX_ISOC_ERRORS)
|
||||||
|
@ -673,8 +673,8 @@ static void pwc_isoc_handler(struct urb *urb, struct pt_regs *regs)
|
||||||
pdev->visoc_errors = 0;
|
pdev->visoc_errors = 0;
|
||||||
|
|
||||||
/* vsync: 0 = don't copy data
|
/* vsync: 0 = don't copy data
|
||||||
1 = sync-hunt
|
1 = sync-hunt
|
||||||
2 = synched
|
2 = synched
|
||||||
*/
|
*/
|
||||||
/* Compact data */
|
/* Compact data */
|
||||||
for (i = 0; i < urb->number_of_packets; i++) {
|
for (i = 0; i < urb->number_of_packets; i++) {
|
||||||
|
@ -701,18 +701,18 @@ static void pwc_isoc_handler(struct urb *urb, struct pt_regs *regs)
|
||||||
} /* ..flen > 0 */
|
} /* ..flen > 0 */
|
||||||
|
|
||||||
if (flen < pdev->vlast_packet_size) {
|
if (flen < pdev->vlast_packet_size) {
|
||||||
/* Shorter packet... We probably have the end of an image-frame;
|
/* Shorter packet... We probably have the end of an image-frame;
|
||||||
wake up read() process and let select()/poll() do something.
|
wake up read() process and let select()/poll() do something.
|
||||||
Decompression is done in user time over there.
|
Decompression is done in user time over there.
|
||||||
*/
|
*/
|
||||||
if (pdev->vsync == 2) {
|
if (pdev->vsync == 2) {
|
||||||
/* The ToUCam Fun CMOS sensor causes the firmware to send 2 or 3 bogus
|
/* The ToUCam Fun CMOS sensor causes the firmware to send 2 or 3 bogus
|
||||||
frames on the USB wire after an exposure change. This conditition is
|
frames on the USB wire after an exposure change. This conditition is
|
||||||
however detected in the cam and a bit is set in the header.
|
however detected in the cam and a bit is set in the header.
|
||||||
*/
|
*/
|
||||||
if (pdev->type == 730) {
|
if (pdev->type == 730) {
|
||||||
unsigned char *ptr = (unsigned char *)fbuf->data;
|
unsigned char *ptr = (unsigned char *)fbuf->data;
|
||||||
|
|
||||||
if (ptr[1] == 1 && ptr[0] & 0x10) {
|
if (ptr[1] == 1 && ptr[0] & 0x10) {
|
||||||
#if PWC_DEBUG
|
#if PWC_DEBUG
|
||||||
Debug("Hyundai CMOS sensor bug. Dropping frame %d.\n", fbuf->sequence);
|
Debug("Hyundai CMOS sensor bug. Dropping frame %d.\n", fbuf->sequence);
|
||||||
|
@ -733,13 +733,13 @@ static void pwc_isoc_handler(struct urb *urb, struct pt_regs *regs)
|
||||||
Info("Image is normal.\n");
|
Info("Image is normal.\n");
|
||||||
}
|
}
|
||||||
pdev->vmirror = ptr[0] & 0x03;
|
pdev->vmirror = ptr[0] & 0x03;
|
||||||
/* Sometimes the trailer of the 730 is still sent as a 4 byte packet
|
/* Sometimes the trailer of the 730 is still sent as a 4 byte packet
|
||||||
after a short frame; this condition is filtered out specifically. A 4 byte
|
after a short frame; this condition is filtered out specifically. A 4 byte
|
||||||
frame doesn't make sense anyway.
|
frame doesn't make sense anyway.
|
||||||
So we get either this sequence:
|
So we get either this sequence:
|
||||||
drop_bit set -> 4 byte frame -> short frame -> good frame
|
drop_bit set -> 4 byte frame -> short frame -> good frame
|
||||||
Or this one:
|
Or this one:
|
||||||
drop_bit set -> short frame -> good frame
|
drop_bit set -> short frame -> good frame
|
||||||
So we drop either 3 or 2 frames in all!
|
So we drop either 3 or 2 frames in all!
|
||||||
*/
|
*/
|
||||||
if (fbuf->filled == 4)
|
if (fbuf->filled == 4)
|
||||||
|
@ -830,7 +830,7 @@ static int pwc_isoc_init(struct pwc_device *pdev)
|
||||||
intf = usb_ifnum_to_if(udev, 0);
|
intf = usb_ifnum_to_if(udev, 0);
|
||||||
if (intf)
|
if (intf)
|
||||||
idesc = usb_altnum_to_altsetting(intf, pdev->valternate);
|
idesc = usb_altnum_to_altsetting(intf, pdev->valternate);
|
||||||
|
|
||||||
if (!idesc)
|
if (!idesc)
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
|
@ -841,7 +841,7 @@ static int pwc_isoc_init(struct pwc_device *pdev)
|
||||||
pdev->vmax_packet_size = le16_to_cpu(idesc->endpoint[i].desc.wMaxPacketSize);
|
pdev->vmax_packet_size = le16_to_cpu(idesc->endpoint[i].desc.wMaxPacketSize);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pdev->vmax_packet_size < 0 || pdev->vmax_packet_size > ISO_MAX_FRAME_SIZE) {
|
if (pdev->vmax_packet_size < 0 || pdev->vmax_packet_size > ISO_MAX_FRAME_SIZE) {
|
||||||
Err("Failed to find packet size for video endpoint in current alternate setting.\n");
|
Err("Failed to find packet size for video endpoint in current alternate setting.\n");
|
||||||
return -ENFILE; /* Odd error, that should be noticeable */
|
return -ENFILE; /* Odd error, that should be noticeable */
|
||||||
|
@ -875,18 +875,18 @@ static int pwc_isoc_init(struct pwc_device *pdev)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* init URB structure */
|
/* init URB structure */
|
||||||
for (i = 0; i < MAX_ISO_BUFS; i++) {
|
for (i = 0; i < MAX_ISO_BUFS; i++) {
|
||||||
urb = pdev->sbuf[i].urb;
|
urb = pdev->sbuf[i].urb;
|
||||||
|
|
||||||
urb->interval = 1; // devik
|
urb->interval = 1; // devik
|
||||||
urb->dev = udev;
|
urb->dev = udev;
|
||||||
urb->pipe = usb_rcvisocpipe(udev, pdev->vendpoint);
|
urb->pipe = usb_rcvisocpipe(udev, pdev->vendpoint);
|
||||||
urb->transfer_flags = URB_ISO_ASAP;
|
urb->transfer_flags = URB_ISO_ASAP;
|
||||||
urb->transfer_buffer = pdev->sbuf[i].data;
|
urb->transfer_buffer = pdev->sbuf[i].data;
|
||||||
urb->transfer_buffer_length = ISO_BUFFER_SIZE;
|
urb->transfer_buffer_length = ISO_BUFFER_SIZE;
|
||||||
urb->complete = pwc_isoc_handler;
|
urb->complete = pwc_isoc_handler;
|
||||||
urb->context = pdev;
|
urb->context = pdev;
|
||||||
urb->start_frame = 0;
|
urb->start_frame = 0;
|
||||||
urb->number_of_packets = ISO_FRAMES_PER_DESC;
|
urb->number_of_packets = ISO_FRAMES_PER_DESC;
|
||||||
for (j = 0; j < ISO_FRAMES_PER_DESC; j++) {
|
for (j = 0; j < ISO_FRAMES_PER_DESC; j++) {
|
||||||
|
@ -935,7 +935,7 @@ static void pwc_isoc_cleanup(struct pwc_device *pdev)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Stop camera, but only if we are sure the camera is still there (unplug
|
/* Stop camera, but only if we are sure the camera is still there (unplug
|
||||||
is signalled by EPIPE)
|
is signalled by EPIPE)
|
||||||
*/
|
*/
|
||||||
if (pdev->error_status && pdev->error_status != EPIPE) {
|
if (pdev->error_status && pdev->error_status != EPIPE) {
|
||||||
Trace(TRACE_OPEN, "Setting alternate interface 0.\n");
|
Trace(TRACE_OPEN, "Setting alternate interface 0.\n");
|
||||||
|
@ -956,12 +956,12 @@ int pwc_try_video_mode(struct pwc_device *pdev, int width, int height, int new_f
|
||||||
pwc_reset_buffers(pdev);
|
pwc_reset_buffers(pdev);
|
||||||
/* Try to set video mode... */
|
/* Try to set video mode... */
|
||||||
start = ret = pwc_set_video_mode(pdev, width, height, new_fps, new_compression, new_snapshot);
|
start = ret = pwc_set_video_mode(pdev, width, height, new_fps, new_compression, new_snapshot);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
Trace(TRACE_FLOW, "pwc_set_video_mode attempt 1 failed.\n");
|
Trace(TRACE_FLOW, "pwc_set_video_mode attempt 1 failed.\n");
|
||||||
/* That failed... restore old mode (we know that worked) */
|
/* That failed... restore old mode (we know that worked) */
|
||||||
start = pwc_set_video_mode(pdev, pdev->view.x, pdev->view.y, pdev->vframes, pdev->vcompression, pdev->vsnapshot);
|
start = pwc_set_video_mode(pdev, pdev->view.x, pdev->view.y, pdev->vframes, pdev->vcompression, pdev->vsnapshot);
|
||||||
if (start) {
|
if (start) {
|
||||||
Trace(TRACE_FLOW, "pwc_set_video_mode attempt 2 failed.\n");
|
Trace(TRACE_FLOW, "pwc_set_video_mode attempt 2 failed.\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (start == 0)
|
if (start == 0)
|
||||||
|
@ -987,18 +987,18 @@ static int pwc_video_open(struct inode *inode, struct file *file)
|
||||||
struct pwc_device *pdev;
|
struct pwc_device *pdev;
|
||||||
|
|
||||||
Trace(TRACE_OPEN, ">> video_open called(vdev = 0x%p).\n", vdev);
|
Trace(TRACE_OPEN, ">> video_open called(vdev = 0x%p).\n", vdev);
|
||||||
|
|
||||||
pdev = (struct pwc_device *)vdev->priv;
|
pdev = (struct pwc_device *)vdev->priv;
|
||||||
if (pdev == NULL)
|
if (pdev == NULL)
|
||||||
BUG();
|
BUG();
|
||||||
if (pdev->vopen)
|
if (pdev->vopen)
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
|
|
||||||
down(&pdev->modlock);
|
down(&pdev->modlock);
|
||||||
if (!pdev->usb_init) {
|
if (!pdev->usb_init) {
|
||||||
Trace(TRACE_OPEN, "Doing first time initialization.\n");
|
Trace(TRACE_OPEN, "Doing first time initialization.\n");
|
||||||
pdev->usb_init = 1;
|
pdev->usb_init = 1;
|
||||||
|
|
||||||
if (pwc_trace & TRACE_OPEN)
|
if (pwc_trace & TRACE_OPEN)
|
||||||
{
|
{
|
||||||
/* Query sensor type */
|
/* Query sensor type */
|
||||||
|
@ -1036,7 +1036,7 @@ static int pwc_video_open(struct inode *inode, struct file *file)
|
||||||
/* Set LED on/off time */
|
/* Set LED on/off time */
|
||||||
if (pwc_set_leds(pdev, led_on, led_off) < 0)
|
if (pwc_set_leds(pdev, led_on, led_off) < 0)
|
||||||
Info("Failed to set LED on/off time.\n");
|
Info("Failed to set LED on/off time.\n");
|
||||||
|
|
||||||
pwc_construct(pdev); /* set min/max sizes correct */
|
pwc_construct(pdev); /* set min/max sizes correct */
|
||||||
|
|
||||||
/* So far, so good. Allocate memory. */
|
/* So far, so good. Allocate memory. */
|
||||||
|
@ -1046,7 +1046,7 @@ static int pwc_video_open(struct inode *inode, struct file *file)
|
||||||
up(&pdev->modlock);
|
up(&pdev->modlock);
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reset buffers & parameters */
|
/* Reset buffers & parameters */
|
||||||
pwc_reset_buffers(pdev);
|
pwc_reset_buffers(pdev);
|
||||||
for (i = 0; i < default_mbufs; i++)
|
for (i = 0; i < default_mbufs; i++)
|
||||||
|
@ -1081,7 +1081,7 @@ static int pwc_video_open(struct inode *inode, struct file *file)
|
||||||
up(&pdev->modlock);
|
up(&pdev->modlock);
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
i = pwc_isoc_init(pdev);
|
i = pwc_isoc_init(pdev);
|
||||||
if (i) {
|
if (i) {
|
||||||
Trace(TRACE_OPEN, "Failed to init ISOC stuff = %d.\n", i);
|
Trace(TRACE_OPEN, "Failed to init ISOC stuff = %d.\n", i);
|
||||||
|
@ -1155,13 +1155,13 @@ static int pwc_video_close(struct inode *inode, struct file *file)
|
||||||
/*
|
/*
|
||||||
* FIXME: what about two parallel reads ????
|
* FIXME: what about two parallel reads ????
|
||||||
* ANSWER: Not supported. You can't open the device more than once,
|
* ANSWER: Not supported. You can't open the device more than once,
|
||||||
despite what the V4L1 interface says. First, I don't see
|
despite what the V4L1 interface says. First, I don't see
|
||||||
the need, second there's no mechanism of alerting the
|
the need, second there's no mechanism of alerting the
|
||||||
2nd/3rd/... process of events like changing image size.
|
2nd/3rd/... process of events like changing image size.
|
||||||
And I don't see the point of blocking that for the
|
And I don't see the point of blocking that for the
|
||||||
2nd/3rd/... process.
|
2nd/3rd/... process.
|
||||||
In multi-threaded environments reading parallel from any
|
In multi-threaded environments reading parallel from any
|
||||||
device is tricky anyhow.
|
device is tricky anyhow.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static ssize_t pwc_video_read(struct file *file, char __user * buf,
|
static ssize_t pwc_video_read(struct file *file, char __user * buf,
|
||||||
|
@ -1171,7 +1171,7 @@ static ssize_t pwc_video_read(struct file *file, char __user * buf,
|
||||||
struct pwc_device *pdev;
|
struct pwc_device *pdev;
|
||||||
int noblock = file->f_flags & O_NONBLOCK;
|
int noblock = file->f_flags & O_NONBLOCK;
|
||||||
DECLARE_WAITQUEUE(wait, current);
|
DECLARE_WAITQUEUE(wait, current);
|
||||||
int bytes_to_read;
|
int bytes_to_read;
|
||||||
|
|
||||||
Trace(TRACE_READ, "video_read(0x%p, %p, %zu) called.\n", vdev, buf, count);
|
Trace(TRACE_READ, "video_read(0x%p, %p, %zu) called.\n", vdev, buf, count);
|
||||||
if (vdev == NULL)
|
if (vdev == NULL)
|
||||||
|
@ -1193,22 +1193,22 @@ static ssize_t pwc_video_read(struct file *file, char __user * buf,
|
||||||
set_current_state(TASK_RUNNING);
|
set_current_state(TASK_RUNNING);
|
||||||
return -pdev->error_status ;
|
return -pdev->error_status ;
|
||||||
}
|
}
|
||||||
if (noblock) {
|
if (noblock) {
|
||||||
remove_wait_queue(&pdev->frameq, &wait);
|
remove_wait_queue(&pdev->frameq, &wait);
|
||||||
set_current_state(TASK_RUNNING);
|
set_current_state(TASK_RUNNING);
|
||||||
return -EWOULDBLOCK;
|
return -EWOULDBLOCK;
|
||||||
}
|
}
|
||||||
if (signal_pending(current)) {
|
if (signal_pending(current)) {
|
||||||
remove_wait_queue(&pdev->frameq, &wait);
|
remove_wait_queue(&pdev->frameq, &wait);
|
||||||
set_current_state(TASK_RUNNING);
|
set_current_state(TASK_RUNNING);
|
||||||
return -ERESTARTSYS;
|
return -ERESTARTSYS;
|
||||||
}
|
}
|
||||||
schedule();
|
schedule();
|
||||||
set_current_state(TASK_INTERRUPTIBLE);
|
set_current_state(TASK_INTERRUPTIBLE);
|
||||||
}
|
}
|
||||||
remove_wait_queue(&pdev->frameq, &wait);
|
remove_wait_queue(&pdev->frameq, &wait);
|
||||||
set_current_state(TASK_RUNNING);
|
set_current_state(TASK_RUNNING);
|
||||||
|
|
||||||
/* Decompress and release frame */
|
/* Decompress and release frame */
|
||||||
if (pwc_handle_frame(pdev))
|
if (pwc_handle_frame(pdev))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
@ -1218,7 +1218,7 @@ static ssize_t pwc_video_read(struct file *file, char __user * buf,
|
||||||
if (pdev->vpalette == VIDEO_PALETTE_RAW)
|
if (pdev->vpalette == VIDEO_PALETTE_RAW)
|
||||||
bytes_to_read = pdev->frame_size;
|
bytes_to_read = pdev->frame_size;
|
||||||
else
|
else
|
||||||
bytes_to_read = pdev->view.size;
|
bytes_to_read = pdev->view.size;
|
||||||
|
|
||||||
/* copy bytes to user space; we allow for partial reads */
|
/* copy bytes to user space; we allow for partial reads */
|
||||||
if (count + pdev->image_read_pos > bytes_to_read)
|
if (count + pdev->image_read_pos > bytes_to_read)
|
||||||
|
@ -1348,11 +1348,11 @@ static int pwc_video_do_ioctl(struct inode *inode, struct file *file,
|
||||||
struct video_picture *p = arg;
|
struct video_picture *p = arg;
|
||||||
/*
|
/*
|
||||||
* FIXME: Suppose we are mid read
|
* FIXME: Suppose we are mid read
|
||||||
ANSWER: No problem: the firmware of the camera
|
ANSWER: No problem: the firmware of the camera
|
||||||
can handle brightness/contrast/etc
|
can handle brightness/contrast/etc
|
||||||
changes at _any_ time, and the palette
|
changes at _any_ time, and the palette
|
||||||
is used exactly once in the uncompress
|
is used exactly once in the uncompress
|
||||||
routine.
|
routine.
|
||||||
*/
|
*/
|
||||||
pwc_set_brightness(pdev, p->brightness);
|
pwc_set_brightness(pdev, p->brightness);
|
||||||
pwc_set_contrast(pdev, p->contrast);
|
pwc_set_contrast(pdev, p->contrast);
|
||||||
|
@ -1373,21 +1373,21 @@ static int pwc_video_do_ioctl(struct inode *inode, struct file *file,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Window/size parameters */
|
/* Window/size parameters */
|
||||||
case VIDIOCGWIN:
|
case VIDIOCGWIN:
|
||||||
{
|
{
|
||||||
struct video_window *vw = arg;
|
struct video_window *vw = arg;
|
||||||
|
|
||||||
vw->x = 0;
|
vw->x = 0;
|
||||||
vw->y = 0;
|
vw->y = 0;
|
||||||
vw->width = pdev->view.x;
|
vw->width = pdev->view.x;
|
||||||
vw->height = pdev->view.y;
|
vw->height = pdev->view.y;
|
||||||
vw->chromakey = 0;
|
vw->chromakey = 0;
|
||||||
vw->flags = (pdev->vframes << PWC_FPS_SHIFT) |
|
vw->flags = (pdev->vframes << PWC_FPS_SHIFT) |
|
||||||
(pdev->vsnapshot ? PWC_FPS_SNAPSHOT : 0);
|
(pdev->vsnapshot ? PWC_FPS_SNAPSHOT : 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case VIDIOCSWIN:
|
case VIDIOCSWIN:
|
||||||
{
|
{
|
||||||
struct video_window *vw = arg;
|
struct video_window *vw = arg;
|
||||||
|
@ -1402,9 +1402,9 @@ static int pwc_video_do_ioctl(struct inode *inode, struct file *file,
|
||||||
ret = pwc_try_video_mode(pdev, vw->width, vw->height, fps, pdev->vcompression, snapshot);
|
ret = pwc_try_video_mode(pdev, vw->width, vw->height, fps, pdev->vcompression, snapshot);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We don't have overlay support (yet) */
|
/* We don't have overlay support (yet) */
|
||||||
case VIDIOCGFBUF:
|
case VIDIOCGFBUF:
|
||||||
{
|
{
|
||||||
|
@ -1471,8 +1471,8 @@ static int pwc_video_do_ioctl(struct inode *inode, struct file *file,
|
||||||
return -EBUSY; /* buffer wasn't available. Bummer */
|
return -EBUSY; /* buffer wasn't available. Bummer */
|
||||||
pdev->image_used[vm->frame] = 1;
|
pdev->image_used[vm->frame] = 1;
|
||||||
|
|
||||||
/* Okay, we're done here. In the SYNC call we wait until a
|
/* Okay, we're done here. In the SYNC call we wait until a
|
||||||
frame comes available, then expand image into the given
|
frame comes available, then expand image into the given
|
||||||
buffer.
|
buffer.
|
||||||
In contrast to the CPiA cam the Philips cams deliver a
|
In contrast to the CPiA cam the Philips cams deliver a
|
||||||
constant stream, almost like a grabber card. Also,
|
constant stream, almost like a grabber card. Also,
|
||||||
|
@ -1487,16 +1487,16 @@ static int pwc_video_do_ioctl(struct inode *inode, struct file *file,
|
||||||
{
|
{
|
||||||
/* The doc says: "Whenever a buffer is used it should
|
/* The doc says: "Whenever a buffer is used it should
|
||||||
call VIDIOCSYNC to free this frame up and continue."
|
call VIDIOCSYNC to free this frame up and continue."
|
||||||
|
|
||||||
The only odd thing about this whole procedure is
|
The only odd thing about this whole procedure is
|
||||||
that MCAPTURE flags the buffer as "in use", and
|
that MCAPTURE flags the buffer as "in use", and
|
||||||
SYNC immediately unmarks it, while it isn't
|
SYNC immediately unmarks it, while it isn't
|
||||||
after SYNC that you know that the buffer actually
|
after SYNC that you know that the buffer actually
|
||||||
got filled! So you better not start a CAPTURE in
|
got filled! So you better not start a CAPTURE in
|
||||||
the same frame immediately (use double buffering).
|
the same frame immediately (use double buffering).
|
||||||
This is not a problem for this cam, since it has
|
This is not a problem for this cam, since it has
|
||||||
extra intermediate buffers, but a hardware
|
extra intermediate buffers, but a hardware
|
||||||
grabber card will then overwrite the buffer
|
grabber card will then overwrite the buffer
|
||||||
you're working on.
|
you're working on.
|
||||||
*/
|
*/
|
||||||
int *mbuf = arg;
|
int *mbuf = arg;
|
||||||
|
@ -1512,10 +1512,10 @@ static int pwc_video_do_ioctl(struct inode *inode, struct file *file,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
/* Add ourselves to the frame wait-queue.
|
/* Add ourselves to the frame wait-queue.
|
||||||
|
|
||||||
FIXME: needs auditing for safety.
|
FIXME: needs auditing for safety.
|
||||||
QUESTION: In what respect? I think that using the
|
QUESTION: In what respect? I think that using the
|
||||||
frameq is safe now.
|
frameq is safe now.
|
||||||
*/
|
*/
|
||||||
add_wait_queue(&pdev->frameq, &wait);
|
add_wait_queue(&pdev->frameq, &wait);
|
||||||
while (pdev->full_frames == NULL) {
|
while (pdev->full_frames == NULL) {
|
||||||
|
@ -1524,21 +1524,21 @@ static int pwc_video_do_ioctl(struct inode *inode, struct file *file,
|
||||||
set_current_state(TASK_RUNNING);
|
set_current_state(TASK_RUNNING);
|
||||||
return -pdev->error_status;
|
return -pdev->error_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (signal_pending(current)) {
|
if (signal_pending(current)) {
|
||||||
remove_wait_queue(&pdev->frameq, &wait);
|
remove_wait_queue(&pdev->frameq, &wait);
|
||||||
set_current_state(TASK_RUNNING);
|
set_current_state(TASK_RUNNING);
|
||||||
return -ERESTARTSYS;
|
return -ERESTARTSYS;
|
||||||
}
|
}
|
||||||
schedule();
|
schedule();
|
||||||
set_current_state(TASK_INTERRUPTIBLE);
|
set_current_state(TASK_INTERRUPTIBLE);
|
||||||
}
|
}
|
||||||
remove_wait_queue(&pdev->frameq, &wait);
|
remove_wait_queue(&pdev->frameq, &wait);
|
||||||
set_current_state(TASK_RUNNING);
|
set_current_state(TASK_RUNNING);
|
||||||
|
|
||||||
/* The frame is ready. Expand in the image buffer
|
/* The frame is ready. Expand in the image buffer
|
||||||
requested by the user. I don't care if you
|
requested by the user. I don't care if you
|
||||||
mmap() 5 buffers and request data in this order:
|
mmap() 5 buffers and request data in this order:
|
||||||
buffer 4 2 3 0 1 2 3 0 4 3 1 . . .
|
buffer 4 2 3 0 1 2 3 0 4 3 1 . . .
|
||||||
Grabber hardware may not be so forgiving.
|
Grabber hardware may not be so forgiving.
|
||||||
*/
|
*/
|
||||||
|
@ -1551,11 +1551,11 @@ static int pwc_video_do_ioctl(struct inode *inode, struct file *file,
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case VIDIOCGAUDIO:
|
case VIDIOCGAUDIO:
|
||||||
{
|
{
|
||||||
struct video_audio *v = arg;
|
struct video_audio *v = arg;
|
||||||
|
|
||||||
strcpy(v->name, "Microphone");
|
strcpy(v->name, "Microphone");
|
||||||
v->audio = -1; /* unknown audio minor */
|
v->audio = -1; /* unknown audio minor */
|
||||||
v->flags = 0;
|
v->flags = 0;
|
||||||
|
@ -1565,19 +1565,19 @@ static int pwc_video_do_ioctl(struct inode *inode, struct file *file,
|
||||||
v->treble = 0;
|
v->treble = 0;
|
||||||
v->balance = 0x8000;
|
v->balance = 0x8000;
|
||||||
v->step = 1;
|
v->step = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case VIDIOCSAUDIO:
|
case VIDIOCSAUDIO:
|
||||||
{
|
{
|
||||||
/* Dummy: nothing can be set */
|
/* Dummy: nothing can be set */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case VIDIOCGUNIT:
|
case VIDIOCGUNIT:
|
||||||
{
|
{
|
||||||
struct video_unit *vu = arg;
|
struct video_unit *vu = arg;
|
||||||
|
|
||||||
vu->video = pdev->vdev->minor & 0x3F;
|
vu->video = pdev->vdev->minor & 0x3F;
|
||||||
vu->audio = -1; /* not known yet */
|
vu->audio = -1; /* not known yet */
|
||||||
vu->vbi = -1;
|
vu->vbi = -1;
|
||||||
|
@ -1589,7 +1589,7 @@ static int pwc_video_do_ioctl(struct inode *inode, struct file *file,
|
||||||
return pwc_ioctl(pdev, cmd, arg);
|
return pwc_ioctl(pdev, cmd, arg);
|
||||||
} /* ..switch */
|
} /* ..switch */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pwc_video_ioctl(struct inode *inode, struct file *file,
|
static int pwc_video_ioctl(struct inode *inode, struct file *file,
|
||||||
unsigned int cmd, unsigned long arg)
|
unsigned int cmd, unsigned long arg)
|
||||||
|
@ -1605,10 +1605,10 @@ static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma)
|
||||||
unsigned long start = vma->vm_start;
|
unsigned long start = vma->vm_start;
|
||||||
unsigned long size = vma->vm_end-vma->vm_start;
|
unsigned long size = vma->vm_end-vma->vm_start;
|
||||||
unsigned long page, pos;
|
unsigned long page, pos;
|
||||||
|
|
||||||
Trace(TRACE_MEMORY, "mmap(0x%p, 0x%lx, %lu) called.\n", vdev, start, size);
|
Trace(TRACE_MEMORY, "mmap(0x%p, 0x%lx, %lu) called.\n", vdev, start, size);
|
||||||
pdev = vdev->priv;
|
pdev = vdev->priv;
|
||||||
|
|
||||||
vma->vm_flags |= VM_IO;
|
vma->vm_flags |= VM_IO;
|
||||||
|
|
||||||
pos = (unsigned long)pdev->image_data;
|
pos = (unsigned long)pdev->image_data;
|
||||||
|
@ -1646,7 +1646,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
|
||||||
char serial_number[30], *name;
|
char serial_number[30], *name;
|
||||||
|
|
||||||
/* Check if we can handle this device */
|
/* Check if we can handle this device */
|
||||||
Trace(TRACE_PROBE, "probe() called [%04X %04X], if %d\n",
|
Trace(TRACE_PROBE, "probe() called [%04X %04X], if %d\n",
|
||||||
le16_to_cpu(udev->descriptor.idVendor),
|
le16_to_cpu(udev->descriptor.idVendor),
|
||||||
le16_to_cpu(udev->descriptor.idProduct),
|
le16_to_cpu(udev->descriptor.idProduct),
|
||||||
intf->altsetting->desc.bInterfaceNumber);
|
intf->altsetting->desc.bInterfaceNumber);
|
||||||
|
@ -1770,11 +1770,11 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
|
||||||
name = "Logitech QuickCam (res.)";
|
name = "Logitech QuickCam (res.)";
|
||||||
type_id = 730; /* Assuming CMOS */
|
type_id = 730; /* Assuming CMOS */
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (vendor_id == 0x055d) {
|
else if (vendor_id == 0x055d) {
|
||||||
/* I don't know the difference between the C10 and the C30;
|
/* I don't know the difference between the C10 and the C30;
|
||||||
I suppose the difference is the sensor, but both cameras
|
I suppose the difference is the sensor, but both cameras
|
||||||
|
@ -1837,7 +1837,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (vendor_id == 0x0d81) {
|
else if (vendor_id == 0x0d81) {
|
||||||
switch(product_id) {
|
switch(product_id) {
|
||||||
|
@ -1856,7 +1856,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return -ENODEV; /* Not any of the know types; but the list keeps growing. */
|
return -ENODEV; /* Not any of the know types; but the list keeps growing. */
|
||||||
|
|
||||||
memset(serial_number, 0, 30);
|
memset(serial_number, 0, 30);
|
||||||
|
@ -1880,9 +1880,9 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
|
||||||
if (vendor_id == 0x046D && product_id == 0x08B5)
|
if (vendor_id == 0x046D && product_id == 0x08B5)
|
||||||
{
|
{
|
||||||
/* Logitech QuickCam Orbit
|
/* Logitech QuickCam Orbit
|
||||||
The ranges have been determined experimentally; they may differ from cam to cam.
|
The ranges have been determined experimentally; they may differ from cam to cam.
|
||||||
Also, the exact ranges left-right and up-down are different for my cam
|
Also, the exact ranges left-right and up-down are different for my cam
|
||||||
*/
|
*/
|
||||||
pdev->angle_range.pan_min = -7000;
|
pdev->angle_range.pan_min = -7000;
|
||||||
pdev->angle_range.pan_max = 7000;
|
pdev->angle_range.pan_max = 7000;
|
||||||
pdev->angle_range.tilt_min = -3000;
|
pdev->angle_range.tilt_min = -3000;
|
||||||
|
@ -1939,7 +1939,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
|
||||||
}
|
}
|
||||||
|
|
||||||
/* occupy slot */
|
/* occupy slot */
|
||||||
if (hint < MAX_DEV_HINTS)
|
if (hint < MAX_DEV_HINTS)
|
||||||
device_hint[hint].pdev = pdev;
|
device_hint[hint].pdev = pdev;
|
||||||
|
|
||||||
Trace(TRACE_PROBE, "probe() function returning struct at 0x%p.\n", pdev);
|
Trace(TRACE_PROBE, "probe() function returning struct at 0x%p.\n", pdev);
|
||||||
|
@ -1968,13 +1968,13 @@ static void usb_pwc_disconnect(struct usb_interface *intf)
|
||||||
Err("pwc_disconnect() Woops: pointer mismatch udev/pdev.\n");
|
Err("pwc_disconnect() Woops: pointer mismatch udev/pdev.\n");
|
||||||
goto disconnect_out;
|
goto disconnect_out;
|
||||||
}
|
}
|
||||||
#ifdef PWC_MAGIC
|
#ifdef PWC_MAGIC
|
||||||
if (pdev->magic != PWC_MAGIC) {
|
if (pdev->magic != PWC_MAGIC) {
|
||||||
Err("pwc_disconnect() Magic number failed. Consult your scrolls and try again.\n");
|
Err("pwc_disconnect() Magic number failed. Consult your scrolls and try again.\n");
|
||||||
goto disconnect_out;
|
goto disconnect_out;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* We got unplugged; this is signalled by an EPIPE error code */
|
/* We got unplugged; this is signalled by an EPIPE error code */
|
||||||
if (pdev->vopen) {
|
if (pdev->vopen) {
|
||||||
Info("Disconnected while webcam is in use!\n");
|
Info("Disconnected while webcam is in use!\n");
|
||||||
|
@ -2017,8 +2017,8 @@ static int pwc_atoi(const char *s)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialization code & module stuff
|
* Initialization code & module stuff
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static char size[10];
|
static char size[10];
|
||||||
|
@ -2168,7 +2168,7 @@ static int __init usb_pwc_init(void)
|
||||||
if (*dot != '\0') {
|
if (*dot != '\0') {
|
||||||
/* There's a serial number as well */
|
/* There's a serial number as well */
|
||||||
int k;
|
int k;
|
||||||
|
|
||||||
dot++;
|
dot++;
|
||||||
k = 0;
|
k = 0;
|
||||||
while (*dot != ':' && k < 29) {
|
while (*dot != ':' && k < 29) {
|
||||||
|
@ -2178,18 +2178,18 @@ static int __init usb_pwc_init(void)
|
||||||
device_hint[i].serial_number[k] = '\0';
|
device_hint[i].serial_number[k] = '\0';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#if PWC_DEBUG
|
#if PWC_DEBUG
|
||||||
Debug("device_hint[%d]:\n", i);
|
Debug("device_hint[%d]:\n", i);
|
||||||
Debug(" type : %d\n", device_hint[i].type);
|
Debug(" type : %d\n", device_hint[i].type);
|
||||||
Debug(" serial# : %s\n", device_hint[i].serial_number);
|
Debug(" serial# : %s\n", device_hint[i].serial_number);
|
||||||
Debug(" node : %d\n", device_hint[i].device_node);
|
Debug(" node : %d\n", device_hint[i].device_node);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
device_hint[i].type = 0; /* not filled */
|
device_hint[i].type = 0; /* not filled */
|
||||||
} /* ..for MAX_DEV_HINTS */
|
} /* ..for MAX_DEV_HINTS */
|
||||||
|
|
||||||
Trace(TRACE_PROBE, "Registering driver at address 0x%p.\n", &pwc_driver);
|
Trace(TRACE_PROBE, "Registering driver at address 0x%p.\n", &pwc_driver);
|
||||||
return usb_register(&pwc_driver);
|
return usb_register(&pwc_driver);
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,10 +33,10 @@
|
||||||
/*
|
/*
|
||||||
Changes
|
Changes
|
||||||
2001/08/03 Alvarado Added ioctl constants to access methods for
|
2001/08/03 Alvarado Added ioctl constants to access methods for
|
||||||
changing white balance and red/blue gains
|
changing white balance and red/blue gains
|
||||||
2002/12/15 G. H. Fernandez-Toribio VIDIOCGREALSIZE
|
2002/12/15 G. H. Fernandez-Toribio VIDIOCGREALSIZE
|
||||||
2003/12/13 Nemosft Unv. Some modifications to make interfacing to
|
2003/12/13 Nemosft Unv. Some modifications to make interfacing to
|
||||||
PWCX easier
|
PWCX easier
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* These are private ioctl() commands, specific for the Philips webcams.
|
/* These are private ioctl() commands, specific for the Philips webcams.
|
||||||
|
@ -45,10 +45,10 @@
|
||||||
|
|
||||||
The #define names are built up like follows:
|
The #define names are built up like follows:
|
||||||
VIDIOC VIDeo IOCtl prefix
|
VIDIOC VIDeo IOCtl prefix
|
||||||
PWC Philps WebCam
|
PWC Philps WebCam
|
||||||
G optional: Get
|
G optional: Get
|
||||||
S optional: Set
|
S optional: Set
|
||||||
... the function
|
... the function
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
@ -94,7 +94,7 @@ struct pwc_serial
|
||||||
{
|
{
|
||||||
char serial[30]; /* String with serial number. Contains terminating 0 */
|
char serial[30]; /* String with serial number. Contains terminating 0 */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* pwc_whitebalance.mode values */
|
/* pwc_whitebalance.mode values */
|
||||||
#define PWC_WB_INDOOR 0
|
#define PWC_WB_INDOOR 0
|
||||||
#define PWC_WB_OUTDOOR 1
|
#define PWC_WB_OUTDOOR 1
|
||||||
|
@ -102,14 +102,14 @@ struct pwc_serial
|
||||||
#define PWC_WB_MANUAL 3
|
#define PWC_WB_MANUAL 3
|
||||||
#define PWC_WB_AUTO 4
|
#define PWC_WB_AUTO 4
|
||||||
|
|
||||||
/* Used with VIDIOCPWC[SG]AWB (Auto White Balance).
|
/* Used with VIDIOCPWC[SG]AWB (Auto White Balance).
|
||||||
Set mode to one of the PWC_WB_* values above.
|
Set mode to one of the PWC_WB_* values above.
|
||||||
*red and *blue are the respective gains of these colour components inside
|
*red and *blue are the respective gains of these colour components inside
|
||||||
the camera; range 0..65535
|
the camera; range 0..65535
|
||||||
When 'mode' == PWC_WB_MANUAL, 'manual_red' and 'manual_blue' are set or read;
|
When 'mode' == PWC_WB_MANUAL, 'manual_red' and 'manual_blue' are set or read;
|
||||||
otherwise undefined.
|
otherwise undefined.
|
||||||
'read_red' and 'read_blue' are read-only.
|
'read_red' and 'read_blue' are read-only.
|
||||||
*/
|
*/
|
||||||
struct pwc_whitebalance
|
struct pwc_whitebalance
|
||||||
{
|
{
|
||||||
int mode;
|
int mode;
|
||||||
|
@ -117,9 +117,9 @@ struct pwc_whitebalance
|
||||||
int read_red, read_blue; /* R/O */
|
int read_red, read_blue; /* R/O */
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
'control_speed' and 'control_delay' are used in automatic whitebalance mode,
|
'control_speed' and 'control_delay' are used in automatic whitebalance mode,
|
||||||
and tell the camera how fast it should react to changes in lighting, and
|
and tell the camera how fast it should react to changes in lighting, and
|
||||||
with how much delay. Valid values are 0..65535.
|
with how much delay. Valid values are 0..65535.
|
||||||
*/
|
*/
|
||||||
struct pwc_wb_speed
|
struct pwc_wb_speed
|
||||||
|
@ -148,11 +148,11 @@ struct pwc_imagesize
|
||||||
#define PWC_MPT_TILT 0x02
|
#define PWC_MPT_TILT 0x02
|
||||||
#define PWC_MPT_TIMEOUT 0x04 /* for status */
|
#define PWC_MPT_TIMEOUT 0x04 /* for status */
|
||||||
|
|
||||||
/* Set angles; when absolute != 0, the angle is absolute and the
|
/* Set angles; when absolute != 0, the angle is absolute and the
|
||||||
driver calculates the relative offset for you. This can only
|
driver calculates the relative offset for you. This can only
|
||||||
be used with VIDIOCPWCSANGLE; VIDIOCPWCGANGLE always returns
|
be used with VIDIOCPWCSANGLE; VIDIOCPWCGANGLE always returns
|
||||||
absolute angles.
|
absolute angles.
|
||||||
*/
|
*/
|
||||||
struct pwc_mpt_angles
|
struct pwc_mpt_angles
|
||||||
{
|
{
|
||||||
int absolute; /* write-only */
|
int absolute; /* write-only */
|
||||||
|
@ -179,14 +179,14 @@ struct pwc_mpt_status
|
||||||
/* This is used for out-of-kernel decompression. With it, you can get
|
/* This is used for out-of-kernel decompression. With it, you can get
|
||||||
all the necessary information to initialize and use the decompressor
|
all the necessary information to initialize and use the decompressor
|
||||||
routines in standalone applications.
|
routines in standalone applications.
|
||||||
*/
|
*/
|
||||||
struct pwc_video_command
|
struct pwc_video_command
|
||||||
{
|
{
|
||||||
int type; /* camera type (645, 675, 730, etc.) */
|
int type; /* camera type (645, 675, 730, etc.) */
|
||||||
int release; /* release number */
|
int release; /* release number */
|
||||||
|
|
||||||
int size; /* one of PSZ_* */
|
int size; /* one of PSZ_* */
|
||||||
int alternate;
|
int alternate;
|
||||||
int command_len; /* length of USB video command */
|
int command_len; /* length of USB video command */
|
||||||
unsigned char command_buf[13]; /* Actual USB video command */
|
unsigned char command_buf[13]; /* Actual USB video command */
|
||||||
int bandlength; /* >0 = compressed */
|
int bandlength; /* >0 = compressed */
|
||||||
|
@ -264,7 +264,7 @@ struct pwc_video_command
|
||||||
|
|
||||||
/* Flickerless mode; = 0 off, otherwise on */
|
/* Flickerless mode; = 0 off, otherwise on */
|
||||||
#define VIDIOCPWCSFLICKER _IOW('v', 208, int)
|
#define VIDIOCPWCSFLICKER _IOW('v', 208, int)
|
||||||
#define VIDIOCPWCGFLICKER _IOR('v', 208, int)
|
#define VIDIOCPWCGFLICKER _IOR('v', 208, int)
|
||||||
|
|
||||||
/* Dynamic noise reduction; 0 off, 3 = high noise reduction */
|
/* Dynamic noise reduction; 0 off, 3 = high noise reduction */
|
||||||
#define VIDIOCPWCSDYNNOISE _IOW('v', 209, int)
|
#define VIDIOCPWCSDYNNOISE _IOW('v', 209, int)
|
||||||
|
@ -273,7 +273,7 @@ struct pwc_video_command
|
||||||
/* Real image size as used by the camera; tells you whether or not there's a gray border around the image */
|
/* Real image size as used by the camera; tells you whether or not there's a gray border around the image */
|
||||||
#define VIDIOCPWCGREALSIZE _IOR('v', 210, struct pwc_imagesize)
|
#define VIDIOCPWCGREALSIZE _IOR('v', 210, struct pwc_imagesize)
|
||||||
|
|
||||||
/* Motorized pan & tilt functions */
|
/* Motorized pan & tilt functions */
|
||||||
#define VIDIOCPWCMPTRESET _IOW('v', 211, int)
|
#define VIDIOCPWCMPTRESET _IOW('v', 211, int)
|
||||||
#define VIDIOCPWCMPTGRANGE _IOR('v', 211, struct pwc_mpt_range)
|
#define VIDIOCPWCMPTGRANGE _IOR('v', 211, struct pwc_mpt_range)
|
||||||
#define VIDIOCPWCMPTSANGLE _IOW('v', 212, struct pwc_mpt_angles)
|
#define VIDIOCPWCMPTSANGLE _IOW('v', 212, struct pwc_mpt_angles)
|
318
drivers/media/video/pwc/pwc-kiara.c
Normal file
318
drivers/media/video/pwc/pwc-kiara.c
Normal file
|
@ -0,0 +1,318 @@
|
||||||
|
/* Linux driver for Philips webcam
|
||||||
|
(C) 2004 Luc Saillard (luc@saillard.org)
|
||||||
|
|
||||||
|
NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
|
||||||
|
driver and thus may have bugs that are not present in the original version.
|
||||||
|
Please send bug reports and support requests to <luc@saillard.org>.
|
||||||
|
The decompression routines have been implemented by reverse-engineering the
|
||||||
|
Nemosoft binary pwcx module. Caveat emptor.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* This tables contains entries for the 730/740/750 (Kiara) camera, with
|
||||||
|
4 different qualities (no compression, low, medium, high).
|
||||||
|
It lists the bandwidth requirements for said mode by its alternate interface
|
||||||
|
number. An alternate of 0 means that the mode is unavailable.
|
||||||
|
|
||||||
|
There are 6 * 4 * 4 entries:
|
||||||
|
6 different resolutions subqcif, qsif, qcif, sif, cif, vga
|
||||||
|
6 framerates: 5, 10, 15, 20, 25, 30
|
||||||
|
4 compression modi: none, low, medium, high
|
||||||
|
|
||||||
|
When an uncompressed mode is not available, the next available compressed mode
|
||||||
|
will be chosen (unless the decompressor is absent). Sometimes there are only
|
||||||
|
1 or 2 compressed modes available; in that case entries are duplicated.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "pwc-kiara.h"
|
||||||
|
#include "pwc-uncompress.h"
|
||||||
|
|
||||||
|
const struct Kiara_table_entry Kiara_table[PSZ_MAX][6][4] =
|
||||||
|
{
|
||||||
|
/* SQCIF */
|
||||||
|
{
|
||||||
|
/* 5 fps */
|
||||||
|
{
|
||||||
|
{0, },
|
||||||
|
{0, },
|
||||||
|
{0, },
|
||||||
|
{0, },
|
||||||
|
},
|
||||||
|
/* 10 fps */
|
||||||
|
{
|
||||||
|
{0, },
|
||||||
|
{0, },
|
||||||
|
{0, },
|
||||||
|
{0, },
|
||||||
|
},
|
||||||
|
/* 15 fps */
|
||||||
|
{
|
||||||
|
{0, },
|
||||||
|
{0, },
|
||||||
|
{0, },
|
||||||
|
{0, },
|
||||||
|
},
|
||||||
|
/* 20 fps */
|
||||||
|
{
|
||||||
|
{0, },
|
||||||
|
{0, },
|
||||||
|
{0, },
|
||||||
|
{0, },
|
||||||
|
},
|
||||||
|
/* 25 fps */
|
||||||
|
{
|
||||||
|
{0, },
|
||||||
|
{0, },
|
||||||
|
{0, },
|
||||||
|
{0, },
|
||||||
|
},
|
||||||
|
/* 30 fps */
|
||||||
|
{
|
||||||
|
{0, },
|
||||||
|
{0, },
|
||||||
|
{0, },
|
||||||
|
{0, },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
/* QSIF */
|
||||||
|
{
|
||||||
|
/* 5 fps */
|
||||||
|
{
|
||||||
|
{1, 146, 0, {0x1D, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x92, 0x00, 0x80}},
|
||||||
|
{1, 146, 0, {0x1D, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x92, 0x00, 0x80}},
|
||||||
|
{1, 146, 0, {0x1D, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x92, 0x00, 0x80}},
|
||||||
|
{1, 146, 0, {0x1D, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x92, 0x00, 0x80}},
|
||||||
|
},
|
||||||
|
/* 10 fps */
|
||||||
|
{
|
||||||
|
{2, 291, 0, {0x1C, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x23, 0x01, 0x80}},
|
||||||
|
{1, 192, 630, {0x14, 0xF4, 0x30, 0x13, 0xA9, 0x12, 0xE1, 0x17, 0x08, 0xC0, 0x00, 0x80}},
|
||||||
|
{1, 192, 630, {0x14, 0xF4, 0x30, 0x13, 0xA9, 0x12, 0xE1, 0x17, 0x08, 0xC0, 0x00, 0x80}},
|
||||||
|
{1, 192, 630, {0x14, 0xF4, 0x30, 0x13, 0xA9, 0x12, 0xE1, 0x17, 0x08, 0xC0, 0x00, 0x80}},
|
||||||
|
},
|
||||||
|
/* 15 fps */
|
||||||
|
{
|
||||||
|
{3, 437, 0, {0x1B, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0xB5, 0x01, 0x80}},
|
||||||
|
{2, 292, 640, {0x13, 0xF4, 0x30, 0x13, 0xF7, 0x13, 0x2F, 0x13, 0x20, 0x24, 0x01, 0x80}},
|
||||||
|
{2, 292, 640, {0x13, 0xF4, 0x30, 0x13, 0xF7, 0x13, 0x2F, 0x13, 0x20, 0x24, 0x01, 0x80}},
|
||||||
|
{1, 192, 420, {0x13, 0xF4, 0x30, 0x0D, 0x1B, 0x0C, 0x53, 0x1E, 0x18, 0xC0, 0x00, 0x80}},
|
||||||
|
},
|
||||||
|
/* 20 fps */
|
||||||
|
{
|
||||||
|
{4, 589, 0, {0x1A, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x4D, 0x02, 0x80}},
|
||||||
|
{3, 448, 730, {0x12, 0xF4, 0x30, 0x16, 0xC9, 0x16, 0x01, 0x0E, 0x18, 0xC0, 0x01, 0x80}},
|
||||||
|
{2, 292, 476, {0x12, 0xF4, 0x30, 0x0E, 0xD8, 0x0E, 0x10, 0x19, 0x18, 0x24, 0x01, 0x80}},
|
||||||
|
{1, 192, 312, {0x12, 0xF4, 0x50, 0x09, 0xB3, 0x08, 0xEB, 0x1E, 0x18, 0xC0, 0x00, 0x80}},
|
||||||
|
},
|
||||||
|
/* 25 fps */
|
||||||
|
{
|
||||||
|
{5, 703, 0, {0x19, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0xBF, 0x02, 0x80}},
|
||||||
|
{3, 447, 610, {0x11, 0xF4, 0x30, 0x13, 0x0B, 0x12, 0x43, 0x14, 0x28, 0xBF, 0x01, 0x80}},
|
||||||
|
{2, 292, 398, {0x11, 0xF4, 0x50, 0x0C, 0x6C, 0x0B, 0xA4, 0x1E, 0x28, 0x24, 0x01, 0x80}},
|
||||||
|
{1, 193, 262, {0x11, 0xF4, 0x50, 0x08, 0x23, 0x07, 0x5B, 0x1E, 0x28, 0xC1, 0x00, 0x80}},
|
||||||
|
},
|
||||||
|
/* 30 fps */
|
||||||
|
{
|
||||||
|
{8, 874, 0, {0x18, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x6A, 0x03, 0x80}},
|
||||||
|
{5, 704, 730, {0x10, 0xF4, 0x30, 0x16, 0xC9, 0x16, 0x01, 0x0E, 0x28, 0xC0, 0x02, 0x80}},
|
||||||
|
{3, 448, 492, {0x10, 0xF4, 0x30, 0x0F, 0x5D, 0x0E, 0x95, 0x15, 0x28, 0xC0, 0x01, 0x80}},
|
||||||
|
{2, 292, 320, {0x10, 0xF4, 0x50, 0x09, 0xFB, 0x09, 0x33, 0x1E, 0x28, 0x24, 0x01, 0x80}},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
/* QCIF */
|
||||||
|
{
|
||||||
|
/* 5 fps */
|
||||||
|
{
|
||||||
|
{0, },
|
||||||
|
{0, },
|
||||||
|
{0, },
|
||||||
|
{0, },
|
||||||
|
},
|
||||||
|
/* 10 fps */
|
||||||
|
{
|
||||||
|
{0, },
|
||||||
|
{0, },
|
||||||
|
{0, },
|
||||||
|
{0, },
|
||||||
|
},
|
||||||
|
/* 15 fps */
|
||||||
|
{
|
||||||
|
{0, },
|
||||||
|
{0, },
|
||||||
|
{0, },
|
||||||
|
{0, },
|
||||||
|
},
|
||||||
|
/* 20 fps */
|
||||||
|
{
|
||||||
|
{0, },
|
||||||
|
{0, },
|
||||||
|
{0, },
|
||||||
|
{0, },
|
||||||
|
},
|
||||||
|
/* 25 fps */
|
||||||
|
{
|
||||||
|
{0, },
|
||||||
|
{0, },
|
||||||
|
{0, },
|
||||||
|
{0, },
|
||||||
|
},
|
||||||
|
/* 30 fps */
|
||||||
|
{
|
||||||
|
{0, },
|
||||||
|
{0, },
|
||||||
|
{0, },
|
||||||
|
{0, },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
/* SIF */
|
||||||
|
{
|
||||||
|
/* 5 fps */
|
||||||
|
{
|
||||||
|
{4, 582, 0, {0x0D, 0xF4, 0x30, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x46, 0x02, 0x80}},
|
||||||
|
{3, 387, 1276, {0x05, 0xF4, 0x30, 0x27, 0xD8, 0x26, 0x48, 0x03, 0x10, 0x83, 0x01, 0x80}},
|
||||||
|
{2, 291, 960, {0x05, 0xF4, 0x30, 0x1D, 0xF2, 0x1C, 0x62, 0x04, 0x10, 0x23, 0x01, 0x80}},
|
||||||
|
{1, 191, 630, {0x05, 0xF4, 0x50, 0x13, 0xA9, 0x12, 0x19, 0x05, 0x18, 0xBF, 0x00, 0x80}},
|
||||||
|
},
|
||||||
|
/* 10 fps */
|
||||||
|
{
|
||||||
|
{0, },
|
||||||
|
{6, 775, 1278, {0x04, 0xF4, 0x30, 0x27, 0xE8, 0x26, 0x58, 0x05, 0x30, 0x07, 0x03, 0x80}},
|
||||||
|
{3, 447, 736, {0x04, 0xF4, 0x30, 0x16, 0xFB, 0x15, 0x6B, 0x05, 0x28, 0xBF, 0x01, 0x80}},
|
||||||
|
{2, 292, 480, {0x04, 0xF4, 0x70, 0x0E, 0xF9, 0x0D, 0x69, 0x09, 0x28, 0x24, 0x01, 0x80}},
|
||||||
|
},
|
||||||
|
/* 15 fps */
|
||||||
|
{
|
||||||
|
{0, },
|
||||||
|
{9, 955, 1050, {0x03, 0xF4, 0x30, 0x20, 0xCF, 0x1F, 0x3F, 0x06, 0x48, 0xBB, 0x03, 0x80}},
|
||||||
|
{4, 592, 650, {0x03, 0xF4, 0x30, 0x14, 0x44, 0x12, 0xB4, 0x08, 0x30, 0x50, 0x02, 0x80}},
|
||||||
|
{3, 448, 492, {0x03, 0xF4, 0x50, 0x0F, 0x52, 0x0D, 0xC2, 0x09, 0x38, 0xC0, 0x01, 0x80}},
|
||||||
|
},
|
||||||
|
/* 20 fps */
|
||||||
|
{
|
||||||
|
{0, },
|
||||||
|
{9, 958, 782, {0x02, 0xF4, 0x30, 0x18, 0x6A, 0x16, 0xDA, 0x0B, 0x58, 0xBE, 0x03, 0x80}},
|
||||||
|
{5, 703, 574, {0x02, 0xF4, 0x50, 0x11, 0xE7, 0x10, 0x57, 0x0B, 0x40, 0xBF, 0x02, 0x80}},
|
||||||
|
{3, 446, 364, {0x02, 0xF4, 0x90, 0x0B, 0x5C, 0x09, 0xCC, 0x0E, 0x38, 0xBE, 0x01, 0x80}},
|
||||||
|
},
|
||||||
|
/* 25 fps */
|
||||||
|
{
|
||||||
|
{0, },
|
||||||
|
{9, 958, 654, {0x01, 0xF4, 0x30, 0x14, 0x66, 0x12, 0xD6, 0x0B, 0x50, 0xBE, 0x03, 0x80}},
|
||||||
|
{6, 776, 530, {0x01, 0xF4, 0x50, 0x10, 0x8C, 0x0E, 0xFC, 0x0C, 0x48, 0x08, 0x03, 0x80}},
|
||||||
|
{4, 592, 404, {0x01, 0xF4, 0x70, 0x0C, 0x96, 0x0B, 0x06, 0x0B, 0x48, 0x50, 0x02, 0x80}},
|
||||||
|
},
|
||||||
|
/* 30 fps */
|
||||||
|
{
|
||||||
|
{0, },
|
||||||
|
{9, 957, 526, {0x00, 0xF4, 0x50, 0x10, 0x68, 0x0E, 0xD8, 0x0D, 0x58, 0xBD, 0x03, 0x80}},
|
||||||
|
{6, 775, 426, {0x00, 0xF4, 0x70, 0x0D, 0x48, 0x0B, 0xB8, 0x0F, 0x50, 0x07, 0x03, 0x80}},
|
||||||
|
{4, 590, 324, {0x00, 0x7A, 0x88, 0x0A, 0x1C, 0x08, 0xB4, 0x0E, 0x50, 0x4E, 0x02, 0x80}},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
/* CIF */
|
||||||
|
{
|
||||||
|
/* 5 fps */
|
||||||
|
{
|
||||||
|
{0, },
|
||||||
|
{0, },
|
||||||
|
{0, },
|
||||||
|
{0, },
|
||||||
|
},
|
||||||
|
/* 10 fps */
|
||||||
|
{
|
||||||
|
{0, },
|
||||||
|
{0, },
|
||||||
|
{0, },
|
||||||
|
{0, },
|
||||||
|
},
|
||||||
|
/* 15 fps */
|
||||||
|
{
|
||||||
|
{0, },
|
||||||
|
{0, },
|
||||||
|
{0, },
|
||||||
|
{0, },
|
||||||
|
},
|
||||||
|
/* 20 fps */
|
||||||
|
{
|
||||||
|
{0, },
|
||||||
|
{0, },
|
||||||
|
{0, },
|
||||||
|
{0, },
|
||||||
|
},
|
||||||
|
/* 25 fps */
|
||||||
|
{
|
||||||
|
{0, },
|
||||||
|
{0, },
|
||||||
|
{0, },
|
||||||
|
{0, },
|
||||||
|
},
|
||||||
|
/* 30 fps */
|
||||||
|
{
|
||||||
|
{0, },
|
||||||
|
{0, },
|
||||||
|
{0, },
|
||||||
|
{0, },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
/* VGA */
|
||||||
|
{
|
||||||
|
/* 5 fps */
|
||||||
|
{
|
||||||
|
{0, },
|
||||||
|
{6, 773, 1272, {0x25, 0xF4, 0x30, 0x27, 0xB6, 0x24, 0x96, 0x02, 0x30, 0x05, 0x03, 0x80}},
|
||||||
|
{4, 592, 976, {0x25, 0xF4, 0x50, 0x1E, 0x78, 0x1B, 0x58, 0x03, 0x30, 0x50, 0x02, 0x80}},
|
||||||
|
{3, 448, 738, {0x25, 0xF4, 0x90, 0x17, 0x0C, 0x13, 0xEC, 0x04, 0x30, 0xC0, 0x01, 0x80}},
|
||||||
|
},
|
||||||
|
/* 10 fps */
|
||||||
|
{
|
||||||
|
{0, },
|
||||||
|
{9, 956, 788, {0x24, 0xF4, 0x70, 0x18, 0x9C, 0x15, 0x7C, 0x03, 0x48, 0xBC, 0x03, 0x80}},
|
||||||
|
{6, 776, 640, {0x24, 0xF4, 0xB0, 0x13, 0xFC, 0x11, 0x2C, 0x04, 0x48, 0x08, 0x03, 0x80}},
|
||||||
|
{4, 592, 488, {0x24, 0x7A, 0xE8, 0x0F, 0x3C, 0x0C, 0x6C, 0x06, 0x48, 0x50, 0x02, 0x80}},
|
||||||
|
},
|
||||||
|
/* 15 fps */
|
||||||
|
{
|
||||||
|
{0, },
|
||||||
|
{9, 957, 526, {0x23, 0x7A, 0xE8, 0x10, 0x68, 0x0D, 0x98, 0x06, 0x58, 0xBD, 0x03, 0x80}},
|
||||||
|
{9, 957, 526, {0x23, 0x7A, 0xE8, 0x10, 0x68, 0x0D, 0x98, 0x06, 0x58, 0xBD, 0x03, 0x80}},
|
||||||
|
{8, 895, 492, {0x23, 0x7A, 0xE8, 0x0F, 0x5D, 0x0C, 0x8D, 0x06, 0x58, 0x7F, 0x03, 0x80}},
|
||||||
|
},
|
||||||
|
/* 20 fps */
|
||||||
|
{
|
||||||
|
{0, },
|
||||||
|
{0, },
|
||||||
|
{0, },
|
||||||
|
{0, },
|
||||||
|
},
|
||||||
|
/* 25 fps */
|
||||||
|
{
|
||||||
|
{0, },
|
||||||
|
{0, },
|
||||||
|
{0, },
|
||||||
|
{0, },
|
||||||
|
},
|
||||||
|
/* 30 fps */
|
||||||
|
{
|
||||||
|
{0, },
|
||||||
|
{0, },
|
||||||
|
{0, },
|
||||||
|
{0, },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* Linux driver for Philips webcam
|
/* Linux driver for Philips webcam
|
||||||
Various miscellaneous functions and tables.
|
Various miscellaneous functions and tables.
|
||||||
(C) 1999-2003 Nemosoft Unv.
|
(C) 1999-2003 Nemosoft Unv.
|
||||||
(C) 2004 Luc Saillard (luc@saillard.org)
|
(C) 2004 Luc Saillard (luc@saillard.org)
|
||||||
|
@ -44,17 +44,17 @@ int pwc_decode_size(struct pwc_device *pdev, int width, int height)
|
||||||
int i, find;
|
int i, find;
|
||||||
|
|
||||||
/* Make sure we don't go beyond our max size.
|
/* Make sure we don't go beyond our max size.
|
||||||
NB: we have different limits for RAW and normal modes. In case
|
NB: we have different limits for RAW and normal modes. In case
|
||||||
you don't have the decompressor loaded or use RAW mode,
|
you don't have the decompressor loaded or use RAW mode,
|
||||||
the maximum viewable size is smaller.
|
the maximum viewable size is smaller.
|
||||||
*/
|
*/
|
||||||
if (pdev->vpalette == VIDEO_PALETTE_RAW)
|
if (pdev->vpalette == VIDEO_PALETTE_RAW)
|
||||||
{
|
{
|
||||||
if (width > pdev->abs_max.x || height > pdev->abs_max.y)
|
if (width > pdev->abs_max.x || height > pdev->abs_max.y)
|
||||||
{
|
{
|
||||||
Debug("VIDEO_PALETTE_RAW: going beyond abs_max.\n");
|
Debug("VIDEO_PALETTE_RAW: going beyond abs_max.\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -88,8 +88,8 @@ void pwc_construct(struct pwc_device *pdev)
|
||||||
pdev->view_min.y = 96;
|
pdev->view_min.y = 96;
|
||||||
pdev->view_max.x = 352;
|
pdev->view_max.x = 352;
|
||||||
pdev->view_max.y = 288;
|
pdev->view_max.y = 288;
|
||||||
pdev->abs_max.x = 352;
|
pdev->abs_max.x = 352;
|
||||||
pdev->abs_max.y = 288;
|
pdev->abs_max.y = 288;
|
||||||
pdev->image_mask = 1 << PSZ_SQCIF | 1 << PSZ_QCIF | 1 << PSZ_CIF;
|
pdev->image_mask = 1 << PSZ_SQCIF | 1 << PSZ_QCIF | 1 << PSZ_CIF;
|
||||||
pdev->vcinterface = 2;
|
pdev->vcinterface = 2;
|
||||||
pdev->vendpoint = 4;
|
pdev->vendpoint = 4;
|
||||||
|
@ -105,8 +105,8 @@ void pwc_construct(struct pwc_device *pdev)
|
||||||
pdev->view_max.x = 640;
|
pdev->view_max.x = 640;
|
||||||
pdev->view_max.y = 480;
|
pdev->view_max.y = 480;
|
||||||
pdev->image_mask = 1 << PSZ_SQCIF | 1 << PSZ_QSIF | 1 << PSZ_QCIF | 1 << PSZ_SIF | 1 << PSZ_CIF | 1 << PSZ_VGA;
|
pdev->image_mask = 1 << PSZ_SQCIF | 1 << PSZ_QSIF | 1 << PSZ_QCIF | 1 << PSZ_SIF | 1 << PSZ_CIF | 1 << PSZ_VGA;
|
||||||
pdev->abs_max.x = 640;
|
pdev->abs_max.x = 640;
|
||||||
pdev->abs_max.y = 480;
|
pdev->abs_max.y = 480;
|
||||||
pdev->vcinterface = 3;
|
pdev->vcinterface = 3;
|
||||||
pdev->vendpoint = 4;
|
pdev->vendpoint = 4;
|
||||||
pdev->frame_header_size = 0;
|
pdev->frame_header_size = 0;
|
||||||
|
@ -121,8 +121,8 @@ void pwc_construct(struct pwc_device *pdev)
|
||||||
pdev->view_max.x = 640;
|
pdev->view_max.x = 640;
|
||||||
pdev->view_max.y = 480;
|
pdev->view_max.y = 480;
|
||||||
pdev->image_mask = 1 << PSZ_QSIF | 1 << PSZ_SIF | 1 << PSZ_VGA;
|
pdev->image_mask = 1 << PSZ_QSIF | 1 << PSZ_SIF | 1 << PSZ_VGA;
|
||||||
pdev->abs_max.x = 640;
|
pdev->abs_max.x = 640;
|
||||||
pdev->abs_max.y = 480;
|
pdev->abs_max.y = 480;
|
||||||
pdev->vcinterface = 3;
|
pdev->vcinterface = 3;
|
||||||
pdev->vendpoint = 5;
|
pdev->vendpoint = 5;
|
||||||
pdev->frame_header_size = TOUCAM_HEADER_SIZE;
|
pdev->frame_header_size = TOUCAM_HEADER_SIZE;
|
|
@ -54,7 +54,7 @@
|
||||||
{0},
|
{0},
|
||||||
},
|
},
|
||||||
/* VGA */
|
/* VGA */
|
||||||
{
|
{
|
||||||
{0},
|
{0},
|
||||||
{0},
|
{0},
|
||||||
{0},
|
{0},
|
316
drivers/media/video/pwc/pwc-timon.c
Normal file
316
drivers/media/video/pwc/pwc-timon.c
Normal file
|
@ -0,0 +1,316 @@
|
||||||
|
/* Linux driver for Philips webcam
|
||||||
|
(C) 2004 Luc Saillard (luc@saillard.org)
|
||||||
|
|
||||||
|
NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
|
||||||
|
driver and thus may have bugs that are not present in the original version.
|
||||||
|
Please send bug reports and support requests to <luc@saillard.org>.
|
||||||
|
The decompression routines have been implemented by reverse-engineering the
|
||||||
|
Nemosoft binary pwcx module. Caveat emptor.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* This tables contains entries for the 675/680/690 (Timon) camera, with
|
||||||
|
4 different qualities (no compression, low, medium, high).
|
||||||
|
It lists the bandwidth requirements for said mode by its alternate interface
|
||||||
|
number. An alternate of 0 means that the mode is unavailable.
|
||||||
|
|
||||||
|
There are 6 * 4 * 4 entries:
|
||||||
|
6 different resolutions subqcif, qsif, qcif, sif, cif, vga
|
||||||
|
6 framerates: 5, 10, 15, 20, 25, 30
|
||||||
|
4 compression modi: none, low, medium, high
|
||||||
|
|
||||||
|
When an uncompressed mode is not available, the next available compressed mode
|
||||||
|
will be chosen (unless the decompressor is absent). Sometimes there are only
|
||||||
|
1 or 2 compressed modes available; in that case entries are duplicated.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "pwc-timon.h"
|
||||||
|
|
||||||
|
const struct Timon_table_entry Timon_table[PSZ_MAX][6][4] =
|
||||||
|
{
|
||||||
|
/* SQCIF */
|
||||||
|
{
|
||||||
|
/* 5 fps */
|
||||||
|
{
|
||||||
|
{1, 140, 0, {0x05, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x8C, 0xFC, 0x80, 0x02}},
|
||||||
|
{1, 140, 0, {0x05, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x8C, 0xFC, 0x80, 0x02}},
|
||||||
|
{1, 140, 0, {0x05, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x8C, 0xFC, 0x80, 0x02}},
|
||||||
|
{1, 140, 0, {0x05, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x8C, 0xFC, 0x80, 0x02}},
|
||||||
|
},
|
||||||
|
/* 10 fps */
|
||||||
|
{
|
||||||
|
{2, 280, 0, {0x04, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x18, 0xA9, 0x80, 0x02}},
|
||||||
|
{2, 280, 0, {0x04, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x18, 0xA9, 0x80, 0x02}},
|
||||||
|
{2, 280, 0, {0x04, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x18, 0xA9, 0x80, 0x02}},
|
||||||
|
{2, 280, 0, {0x04, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x18, 0xA9, 0x80, 0x02}},
|
||||||
|
},
|
||||||
|
/* 15 fps */
|
||||||
|
{
|
||||||
|
{3, 410, 0, {0x03, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x9A, 0x71, 0x80, 0x02}},
|
||||||
|
{3, 410, 0, {0x03, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x9A, 0x71, 0x80, 0x02}},
|
||||||
|
{3, 410, 0, {0x03, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x9A, 0x71, 0x80, 0x02}},
|
||||||
|
{3, 410, 0, {0x03, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x9A, 0x71, 0x80, 0x02}},
|
||||||
|
},
|
||||||
|
/* 20 fps */
|
||||||
|
{
|
||||||
|
{4, 559, 0, {0x02, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x2F, 0x56, 0x80, 0x02}},
|
||||||
|
{4, 559, 0, {0x02, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x2F, 0x56, 0x80, 0x02}},
|
||||||
|
{4, 559, 0, {0x02, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x2F, 0x56, 0x80, 0x02}},
|
||||||
|
{4, 559, 0, {0x02, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x2F, 0x56, 0x80, 0x02}},
|
||||||
|
},
|
||||||
|
/* 25 fps */
|
||||||
|
{
|
||||||
|
{5, 659, 0, {0x01, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x93, 0x46, 0x80, 0x02}},
|
||||||
|
{5, 659, 0, {0x01, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x93, 0x46, 0x80, 0x02}},
|
||||||
|
{5, 659, 0, {0x01, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x93, 0x46, 0x80, 0x02}},
|
||||||
|
{5, 659, 0, {0x01, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x93, 0x46, 0x80, 0x02}},
|
||||||
|
},
|
||||||
|
/* 30 fps */
|
||||||
|
{
|
||||||
|
{7, 838, 0, {0x00, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x46, 0x3B, 0x80, 0x02}},
|
||||||
|
{7, 838, 0, {0x00, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x46, 0x3B, 0x80, 0x02}},
|
||||||
|
{7, 838, 0, {0x00, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x46, 0x3B, 0x80, 0x02}},
|
||||||
|
{7, 838, 0, {0x00, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x46, 0x3B, 0x80, 0x02}},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
/* QSIF */
|
||||||
|
{
|
||||||
|
/* 5 fps */
|
||||||
|
{
|
||||||
|
{1, 146, 0, {0x2D, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x92, 0xFC, 0xC0, 0x02}},
|
||||||
|
{1, 146, 0, {0x2D, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x92, 0xFC, 0xC0, 0x02}},
|
||||||
|
{1, 146, 0, {0x2D, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x92, 0xFC, 0xC0, 0x02}},
|
||||||
|
{1, 146, 0, {0x2D, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x92, 0xFC, 0xC0, 0x02}},
|
||||||
|
},
|
||||||
|
/* 10 fps */
|
||||||
|
{
|
||||||
|
{2, 291, 0, {0x2C, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x23, 0xA1, 0xC0, 0x02}},
|
||||||
|
{1, 191, 630, {0x2C, 0xF4, 0x05, 0x13, 0xA9, 0x12, 0xE1, 0x17, 0x08, 0xBF, 0xF4, 0xC0, 0x02}},
|
||||||
|
{1, 191, 630, {0x2C, 0xF4, 0x05, 0x13, 0xA9, 0x12, 0xE1, 0x17, 0x08, 0xBF, 0xF4, 0xC0, 0x02}},
|
||||||
|
{1, 191, 630, {0x2C, 0xF4, 0x05, 0x13, 0xA9, 0x12, 0xE1, 0x17, 0x08, 0xBF, 0xF4, 0xC0, 0x02}},
|
||||||
|
},
|
||||||
|
/* 15 fps */
|
||||||
|
{
|
||||||
|
{3, 437, 0, {0x2B, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0xB5, 0x6D, 0xC0, 0x02}},
|
||||||
|
{2, 291, 640, {0x2B, 0xF4, 0x05, 0x13, 0xF7, 0x13, 0x2F, 0x13, 0x08, 0x23, 0xA1, 0xC0, 0x02}},
|
||||||
|
{2, 291, 640, {0x2B, 0xF4, 0x05, 0x13, 0xF7, 0x13, 0x2F, 0x13, 0x08, 0x23, 0xA1, 0xC0, 0x02}},
|
||||||
|
{1, 191, 420, {0x2B, 0xF4, 0x0D, 0x0D, 0x1B, 0x0C, 0x53, 0x1E, 0x08, 0xBF, 0xF4, 0xC0, 0x02}},
|
||||||
|
},
|
||||||
|
/* 20 fps */
|
||||||
|
{
|
||||||
|
{4, 588, 0, {0x2A, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x4C, 0x52, 0xC0, 0x02}},
|
||||||
|
{3, 447, 730, {0x2A, 0xF4, 0x05, 0x16, 0xC9, 0x16, 0x01, 0x0E, 0x18, 0xBF, 0x69, 0xC0, 0x02}},
|
||||||
|
{2, 292, 476, {0x2A, 0xF4, 0x0D, 0x0E, 0xD8, 0x0E, 0x10, 0x19, 0x18, 0x24, 0xA1, 0xC0, 0x02}},
|
||||||
|
{1, 192, 312, {0x2A, 0xF4, 0x1D, 0x09, 0xB3, 0x08, 0xEB, 0x1E, 0x18, 0xC0, 0xF4, 0xC0, 0x02}},
|
||||||
|
},
|
||||||
|
/* 25 fps */
|
||||||
|
{
|
||||||
|
{5, 703, 0, {0x29, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0xBF, 0x42, 0xC0, 0x02}},
|
||||||
|
{3, 447, 610, {0x29, 0xF4, 0x05, 0x13, 0x0B, 0x12, 0x43, 0x14, 0x18, 0xBF, 0x69, 0xC0, 0x02}},
|
||||||
|
{2, 292, 398, {0x29, 0xF4, 0x0D, 0x0C, 0x6C, 0x0B, 0xA4, 0x1E, 0x18, 0x24, 0xA1, 0xC0, 0x02}},
|
||||||
|
{1, 192, 262, {0x29, 0xF4, 0x25, 0x08, 0x23, 0x07, 0x5B, 0x1E, 0x18, 0xC0, 0xF4, 0xC0, 0x02}},
|
||||||
|
},
|
||||||
|
/* 30 fps */
|
||||||
|
{
|
||||||
|
{8, 873, 0, {0x28, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x69, 0x37, 0xC0, 0x02}},
|
||||||
|
{5, 704, 774, {0x28, 0xF4, 0x05, 0x18, 0x21, 0x17, 0x59, 0x0F, 0x18, 0xC0, 0x42, 0xC0, 0x02}},
|
||||||
|
{3, 448, 492, {0x28, 0xF4, 0x05, 0x0F, 0x5D, 0x0E, 0x95, 0x15, 0x18, 0xC0, 0x69, 0xC0, 0x02}},
|
||||||
|
{2, 291, 320, {0x28, 0xF4, 0x1D, 0x09, 0xFB, 0x09, 0x33, 0x1E, 0x18, 0x23, 0xA1, 0xC0, 0x02}},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
/* QCIF */
|
||||||
|
{
|
||||||
|
/* 5 fps */
|
||||||
|
{
|
||||||
|
{1, 193, 0, {0x0D, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0xC1, 0xF4, 0xC0, 0x02}},
|
||||||
|
{1, 193, 0, {0x0D, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0xC1, 0xF4, 0xC0, 0x02}},
|
||||||
|
{1, 193, 0, {0x0D, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0xC1, 0xF4, 0xC0, 0x02}},
|
||||||
|
{1, 193, 0, {0x0D, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0xC1, 0xF4, 0xC0, 0x02}},
|
||||||
|
},
|
||||||
|
/* 10 fps */
|
||||||
|
{
|
||||||
|
{3, 385, 0, {0x0C, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x81, 0x79, 0xC0, 0x02}},
|
||||||
|
{2, 291, 800, {0x0C, 0xF4, 0x05, 0x18, 0xF4, 0x18, 0x18, 0x11, 0x08, 0x23, 0xA1, 0xC0, 0x02}},
|
||||||
|
{2, 291, 800, {0x0C, 0xF4, 0x05, 0x18, 0xF4, 0x18, 0x18, 0x11, 0x08, 0x23, 0xA1, 0xC0, 0x02}},
|
||||||
|
{1, 194, 532, {0x0C, 0xF4, 0x05, 0x10, 0x9A, 0x0F, 0xBE, 0x1B, 0x08, 0xC2, 0xF0, 0xC0, 0x02}},
|
||||||
|
},
|
||||||
|
/* 15 fps */
|
||||||
|
{
|
||||||
|
{4, 577, 0, {0x0B, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x41, 0x52, 0xC0, 0x02}},
|
||||||
|
{3, 447, 818, {0x0B, 0xF4, 0x05, 0x19, 0x89, 0x18, 0xAD, 0x0F, 0x10, 0xBF, 0x69, 0xC0, 0x02}},
|
||||||
|
{2, 292, 534, {0x0B, 0xF4, 0x05, 0x10, 0xA3, 0x0F, 0xC7, 0x19, 0x10, 0x24, 0xA1, 0xC0, 0x02}},
|
||||||
|
{1, 195, 356, {0x0B, 0xF4, 0x15, 0x0B, 0x11, 0x0A, 0x35, 0x1E, 0x10, 0xC3, 0xF0, 0xC0, 0x02}},
|
||||||
|
},
|
||||||
|
/* 20 fps */
|
||||||
|
{
|
||||||
|
{6, 776, 0, {0x0A, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x08, 0x3F, 0xC0, 0x02}},
|
||||||
|
{4, 591, 804, {0x0A, 0xF4, 0x05, 0x19, 0x1E, 0x18, 0x42, 0x0F, 0x18, 0x4F, 0x4E, 0xC0, 0x02}},
|
||||||
|
{3, 447, 608, {0x0A, 0xF4, 0x05, 0x12, 0xFD, 0x12, 0x21, 0x15, 0x18, 0xBF, 0x69, 0xC0, 0x02}},
|
||||||
|
{2, 291, 396, {0x0A, 0xF4, 0x15, 0x0C, 0x5E, 0x0B, 0x82, 0x1E, 0x18, 0x23, 0xA1, 0xC0, 0x02}},
|
||||||
|
},
|
||||||
|
/* 25 fps */
|
||||||
|
{
|
||||||
|
{9, 928, 0, {0x09, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0xA0, 0x33, 0xC0, 0x02}},
|
||||||
|
{5, 703, 800, {0x09, 0xF4, 0x05, 0x18, 0xF4, 0x18, 0x18, 0x10, 0x18, 0xBF, 0x42, 0xC0, 0x02}},
|
||||||
|
{3, 447, 508, {0x09, 0xF4, 0x0D, 0x0F, 0xD2, 0x0E, 0xF6, 0x1B, 0x18, 0xBF, 0x69, 0xC0, 0x02}},
|
||||||
|
{2, 292, 332, {0x09, 0xF4, 0x1D, 0x0A, 0x5A, 0x09, 0x7E, 0x1E, 0x18, 0x24, 0xA1, 0xC0, 0x02}},
|
||||||
|
},
|
||||||
|
/* 30 fps */
|
||||||
|
{
|
||||||
|
{0, },
|
||||||
|
{9, 956, 876, {0x08, 0xF4, 0x05, 0x1B, 0x58, 0x1A, 0x7C, 0x0E, 0x20, 0xBC, 0x33, 0x10, 0x02}},
|
||||||
|
{4, 592, 542, {0x08, 0xF4, 0x05, 0x10, 0xE4, 0x10, 0x08, 0x17, 0x20, 0x50, 0x4E, 0x10, 0x02}},
|
||||||
|
{2, 291, 266, {0x08, 0xF4, 0x25, 0x08, 0x48, 0x07, 0x6C, 0x1E, 0x20, 0x23, 0xA1, 0x10, 0x02}},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
/* SIF */
|
||||||
|
{
|
||||||
|
/* 5 fps */
|
||||||
|
{
|
||||||
|
{4, 582, 0, {0x35, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x46, 0x52, 0x60, 0x02}},
|
||||||
|
{3, 387, 1276, {0x35, 0xF4, 0x05, 0x27, 0xD8, 0x26, 0x48, 0x03, 0x10, 0x83, 0x79, 0x60, 0x02}},
|
||||||
|
{2, 291, 960, {0x35, 0xF4, 0x0D, 0x1D, 0xF2, 0x1C, 0x62, 0x04, 0x10, 0x23, 0xA1, 0x60, 0x02}},
|
||||||
|
{1, 191, 630, {0x35, 0xF4, 0x1D, 0x13, 0xA9, 0x12, 0x19, 0x05, 0x08, 0xBF, 0xF4, 0x60, 0x02}},
|
||||||
|
},
|
||||||
|
/* 10 fps */
|
||||||
|
{
|
||||||
|
{0, },
|
||||||
|
{6, 775, 1278, {0x34, 0xF4, 0x05, 0x27, 0xE8, 0x26, 0x58, 0x05, 0x30, 0x07, 0x3F, 0x10, 0x02}},
|
||||||
|
{3, 447, 736, {0x34, 0xF4, 0x15, 0x16, 0xFB, 0x15, 0x6B, 0x05, 0x18, 0xBF, 0x69, 0x10, 0x02}},
|
||||||
|
{2, 291, 480, {0x34, 0xF4, 0x2D, 0x0E, 0xF9, 0x0D, 0x69, 0x09, 0x18, 0x23, 0xA1, 0x10, 0x02}},
|
||||||
|
},
|
||||||
|
/* 15 fps */
|
||||||
|
{
|
||||||
|
{0, },
|
||||||
|
{9, 955, 1050, {0x33, 0xF4, 0x05, 0x20, 0xCF, 0x1F, 0x3F, 0x06, 0x48, 0xBB, 0x33, 0x10, 0x02}},
|
||||||
|
{4, 591, 650, {0x33, 0xF4, 0x15, 0x14, 0x44, 0x12, 0xB4, 0x08, 0x30, 0x4F, 0x4E, 0x10, 0x02}},
|
||||||
|
{3, 448, 492, {0x33, 0xF4, 0x25, 0x0F, 0x52, 0x0D, 0xC2, 0x09, 0x28, 0xC0, 0x69, 0x10, 0x02}},
|
||||||
|
},
|
||||||
|
/* 20 fps */
|
||||||
|
{
|
||||||
|
{0, },
|
||||||
|
{9, 958, 782, {0x32, 0xF4, 0x0D, 0x18, 0x6A, 0x16, 0xDA, 0x0B, 0x58, 0xBE, 0x33, 0xD0, 0x02}},
|
||||||
|
{5, 703, 574, {0x32, 0xF4, 0x1D, 0x11, 0xE7, 0x10, 0x57, 0x0B, 0x40, 0xBF, 0x42, 0xD0, 0x02}},
|
||||||
|
{3, 446, 364, {0x32, 0xF4, 0x3D, 0x0B, 0x5C, 0x09, 0xCC, 0x0E, 0x30, 0xBE, 0x69, 0xD0, 0x02}},
|
||||||
|
},
|
||||||
|
/* 25 fps */
|
||||||
|
{
|
||||||
|
{0, },
|
||||||
|
{9, 958, 654, {0x31, 0xF4, 0x15, 0x14, 0x66, 0x12, 0xD6, 0x0B, 0x50, 0xBE, 0x33, 0x90, 0x02}},
|
||||||
|
{6, 776, 530, {0x31, 0xF4, 0x25, 0x10, 0x8C, 0x0E, 0xFC, 0x0C, 0x48, 0x08, 0x3F, 0x90, 0x02}},
|
||||||
|
{4, 592, 404, {0x31, 0xF4, 0x35, 0x0C, 0x96, 0x0B, 0x06, 0x0B, 0x38, 0x50, 0x4E, 0x90, 0x02}},
|
||||||
|
},
|
||||||
|
/* 30 fps */
|
||||||
|
{
|
||||||
|
{0, },
|
||||||
|
{9, 957, 526, {0x30, 0xF4, 0x25, 0x10, 0x68, 0x0E, 0xD8, 0x0D, 0x58, 0xBD, 0x33, 0x60, 0x02}},
|
||||||
|
{6, 775, 426, {0x30, 0xF4, 0x35, 0x0D, 0x48, 0x0B, 0xB8, 0x0F, 0x50, 0x07, 0x3F, 0x60, 0x02}},
|
||||||
|
{4, 590, 324, {0x30, 0x7A, 0x4B, 0x0A, 0x1C, 0x08, 0xB4, 0x0E, 0x40, 0x4E, 0x52, 0x60, 0x02}},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
/* CIF */
|
||||||
|
{
|
||||||
|
/* 5 fps */
|
||||||
|
{
|
||||||
|
{6, 771, 0, {0x15, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x3F, 0x80, 0x02}},
|
||||||
|
{4, 465, 1278, {0x15, 0xF4, 0x05, 0x27, 0xEE, 0x26, 0x36, 0x03, 0x18, 0xD1, 0x65, 0x80, 0x02}},
|
||||||
|
{2, 291, 800, {0x15, 0xF4, 0x15, 0x18, 0xF4, 0x17, 0x3C, 0x05, 0x18, 0x23, 0xA1, 0x80, 0x02}},
|
||||||
|
{1, 193, 528, {0x15, 0xF4, 0x2D, 0x10, 0x7E, 0x0E, 0xC6, 0x0A, 0x18, 0xC1, 0xF4, 0x80, 0x02}},
|
||||||
|
},
|
||||||
|
/* 10 fps */
|
||||||
|
{
|
||||||
|
{0, },
|
||||||
|
{9, 932, 1278, {0x14, 0xF4, 0x05, 0x27, 0xEE, 0x26, 0x36, 0x04, 0x30, 0xA4, 0x33, 0x10, 0x02}},
|
||||||
|
{4, 591, 812, {0x14, 0xF4, 0x15, 0x19, 0x56, 0x17, 0x9E, 0x06, 0x28, 0x4F, 0x4E, 0x10, 0x02}},
|
||||||
|
{2, 291, 400, {0x14, 0xF4, 0x3D, 0x0C, 0x7A, 0x0A, 0xC2, 0x0E, 0x28, 0x23, 0xA1, 0x10, 0x02}},
|
||||||
|
},
|
||||||
|
/* 15 fps */
|
||||||
|
{
|
||||||
|
{0, },
|
||||||
|
{9, 956, 876, {0x13, 0xF4, 0x0D, 0x1B, 0x58, 0x19, 0xA0, 0x05, 0x38, 0xBC, 0x33, 0x60, 0x02}},
|
||||||
|
{5, 703, 644, {0x13, 0xF4, 0x1D, 0x14, 0x1C, 0x12, 0x64, 0x08, 0x38, 0xBF, 0x42, 0x60, 0x02}},
|
||||||
|
{3, 448, 410, {0x13, 0xF4, 0x3D, 0x0C, 0xC4, 0x0B, 0x0C, 0x0E, 0x38, 0xC0, 0x69, 0x60, 0x02}},
|
||||||
|
},
|
||||||
|
/* 20 fps */
|
||||||
|
{
|
||||||
|
{0, },
|
||||||
|
{9, 956, 650, {0x12, 0xF4, 0x1D, 0x14, 0x4A, 0x12, 0x92, 0x09, 0x48, 0xBC, 0x33, 0x10, 0x03}},
|
||||||
|
{6, 776, 528, {0x12, 0xF4, 0x2D, 0x10, 0x7E, 0x0E, 0xC6, 0x0A, 0x40, 0x08, 0x3F, 0x10, 0x03}},
|
||||||
|
{4, 591, 402, {0x12, 0xF4, 0x3D, 0x0C, 0x8F, 0x0A, 0xD7, 0x0E, 0x40, 0x4F, 0x4E, 0x10, 0x03}},
|
||||||
|
},
|
||||||
|
/* 25 fps */
|
||||||
|
{
|
||||||
|
{0, },
|
||||||
|
{9, 956, 544, {0x11, 0xF4, 0x25, 0x10, 0xF4, 0x0F, 0x3C, 0x0A, 0x48, 0xBC, 0x33, 0xC0, 0x02}},
|
||||||
|
{7, 840, 478, {0x11, 0xF4, 0x2D, 0x0E, 0xEB, 0x0D, 0x33, 0x0B, 0x48, 0x48, 0x3B, 0xC0, 0x02}},
|
||||||
|
{5, 703, 400, {0x11, 0xF4, 0x3D, 0x0C, 0x7A, 0x0A, 0xC2, 0x0E, 0x48, 0xBF, 0x42, 0xC0, 0x02}},
|
||||||
|
},
|
||||||
|
/* 30 fps */
|
||||||
|
{
|
||||||
|
{0, },
|
||||||
|
{9, 956, 438, {0x10, 0xF4, 0x35, 0x0D, 0xAC, 0x0B, 0xF4, 0x0D, 0x50, 0xBC, 0x33, 0x10, 0x02}},
|
||||||
|
{7, 838, 384, {0x10, 0xF4, 0x45, 0x0B, 0xFD, 0x0A, 0x45, 0x0F, 0x50, 0x46, 0x3B, 0x10, 0x02}},
|
||||||
|
{6, 773, 354, {0x10, 0x7A, 0x4B, 0x0B, 0x0C, 0x09, 0x80, 0x10, 0x50, 0x05, 0x3F, 0x10, 0x02}},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
/* VGA */
|
||||||
|
{
|
||||||
|
/* 5 fps */
|
||||||
|
{
|
||||||
|
{0, },
|
||||||
|
{6, 773, 1272, {0x1D, 0xF4, 0x15, 0x27, 0xB6, 0x24, 0x96, 0x02, 0x30, 0x05, 0x3F, 0x10, 0x02}},
|
||||||
|
{4, 592, 976, {0x1D, 0xF4, 0x25, 0x1E, 0x78, 0x1B, 0x58, 0x03, 0x30, 0x50, 0x4E, 0x10, 0x02}},
|
||||||
|
{3, 448, 738, {0x1D, 0xF4, 0x3D, 0x17, 0x0C, 0x13, 0xEC, 0x04, 0x30, 0xC0, 0x69, 0x10, 0x02}},
|
||||||
|
},
|
||||||
|
/* 10 fps */
|
||||||
|
{
|
||||||
|
{0, },
|
||||||
|
{9, 956, 788, {0x1C, 0xF4, 0x35, 0x18, 0x9C, 0x15, 0x7C, 0x03, 0x48, 0xBC, 0x33, 0x10, 0x02}},
|
||||||
|
{6, 776, 640, {0x1C, 0x7A, 0x53, 0x13, 0xFC, 0x11, 0x2C, 0x04, 0x48, 0x08, 0x3F, 0x10, 0x02}},
|
||||||
|
{4, 592, 488, {0x1C, 0x7A, 0x6B, 0x0F, 0x3C, 0x0C, 0x6C, 0x06, 0x48, 0x50, 0x4E, 0x10, 0x02}},
|
||||||
|
},
|
||||||
|
/* 15 fps */
|
||||||
|
{
|
||||||
|
{0, },
|
||||||
|
{9, 957, 526, {0x1B, 0x7A, 0x63, 0x10, 0x68, 0x0D, 0x98, 0x06, 0x58, 0xBD, 0x33, 0x80, 0x02}},
|
||||||
|
{9, 957, 526, {0x1B, 0x7A, 0x63, 0x10, 0x68, 0x0D, 0x98, 0x06, 0x58, 0xBD, 0x33, 0x80, 0x02}},
|
||||||
|
{8, 895, 492, {0x1B, 0x7A, 0x6B, 0x0F, 0x5D, 0x0C, 0x8D, 0x06, 0x58, 0x7F, 0x37, 0x80, 0x02}},
|
||||||
|
},
|
||||||
|
/* 20 fps */
|
||||||
|
{
|
||||||
|
{0, },
|
||||||
|
{0, },
|
||||||
|
{0, },
|
||||||
|
{0, },
|
||||||
|
},
|
||||||
|
/* 25 fps */
|
||||||
|
{
|
||||||
|
{0, },
|
||||||
|
{0, },
|
||||||
|
{0, },
|
||||||
|
{0, },
|
||||||
|
},
|
||||||
|
/* 30 fps */
|
||||||
|
{
|
||||||
|
{0, },
|
||||||
|
{0, },
|
||||||
|
{0, },
|
||||||
|
{0, },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
|
@ -109,9 +109,9 @@ int pwc_decompress(struct pwc_device *pdev)
|
||||||
in planar format immediately.
|
in planar format immediately.
|
||||||
*/
|
*/
|
||||||
int flags;
|
int flags;
|
||||||
|
|
||||||
flags = PWCX_FLAG_PLANAR;
|
flags = PWCX_FLAG_PLANAR;
|
||||||
if (pdev->vsize == PSZ_VGA && pdev->vframes == 5 && pdev->vsnapshot)
|
if (pdev->vsize == PSZ_VGA && pdev->vframes == 5 && pdev->vsnapshot)
|
||||||
{
|
{
|
||||||
printk(KERN_ERR "pwc: Mode Bayer is not supported for now\n");
|
printk(KERN_ERR "pwc: Mode Bayer is not supported for now\n");
|
||||||
flags |= PWCX_FLAG_BAYER;
|
flags |= PWCX_FLAG_BAYER;
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue