mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-25 05:04:09 +08: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
@ -1,7 +1,7 @@
|
||||
c-qcam - Connectix Color QuickCam video4linux kernel driver
|
||||
|
||||
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
|
||||
|
||||
@ -45,21 +45,21 @@ configuration. The appropriate flags are:
|
||||
CONFIG_PNP_PARPORT M for autoprobe.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_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.
|
||||
To record and monitor the compilation, I use:
|
||||
|
||||
(make zlilo ; \
|
||||
make modules; \
|
||||
make modules_install ;
|
||||
make modules_install ;
|
||||
depmod -a ) &>log &
|
||||
less log # then a capital 'F' to watch the progress
|
||||
|
||||
|
||||
But that is my personal preference.
|
||||
|
||||
2.2 Configuration
|
||||
|
||||
|
||||
The configuration requires module configuration and device
|
||||
configuration. I like kmod or kerneld process with the
|
||||
/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.
|
||||
|
||||
|
||||
2.1 Module Configuration
|
||||
2.1 Module Configuration
|
||||
|
||||
Using modules requires a bit of work to install and pass the
|
||||
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
|
||||
should be able to read some identification from your quickcam with
|
||||
|
||||
modprobe -v parport
|
||||
modprobe -v parport_probe
|
||||
cat /proc/parport/PORTNUMBER/autoprobe
|
||||
modprobe -v parport
|
||||
modprobe -v parport_probe
|
||||
cat /proc/parport/PORTNUMBER/autoprobe
|
||||
Returns:
|
||||
CLASS:MEDIA;
|
||||
MODEL:Color QuickCam 2.0;
|
||||
@ -140,7 +140,7 @@ Returns:
|
||||
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,
|
||||
|
||||
modprobe -v c-qcam
|
||||
modprobe -v c-qcam
|
||||
or
|
||||
insmod -v c-qcam
|
||||
|
||||
@ -152,16 +152,16 @@ video4linux mailing list and archive for more current information.
|
||||
3.1 Checklist:
|
||||
|
||||
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?
|
||||
grep ^ /proc/parport/?/autoprobe
|
||||
Is a working c-qcam connected to the port?
|
||||
grep ^ /proc/parport/?/autoprobe
|
||||
|
||||
Do the /dev/video* files exist?
|
||||
ls -lad /dev/video
|
||||
Do the /dev/video* files exist?
|
||||
ls -lad /dev/video
|
||||
|
||||
Is the c-qcam module loaded?
|
||||
modprobe -v c-qcam ; lsmod
|
||||
Is the c-qcam module loaded?
|
||||
modprobe -v c-qcam ; lsmod
|
||||
|
||||
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
|
||||
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
|
||||
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.
|
||||
|
||||
|
||||
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
|
||||
first video device, /dev/video0 to standard output in portable pixmap
|
||||
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
|
||||
|
||||
-------------------- 8< ---------------- 8< -----------------------------
|
||||
@ -202,8 +202,8 @@ produced this picture of me at
|
||||
* Use as:
|
||||
* v4lgrab >image.ppm
|
||||
*
|
||||
* Copyright (C) 1998-05-03, Phil Blundell <philb@gnu.org>
|
||||
* Copied from http://www.tazenda.demon.co.uk/phil/vgrabber.c
|
||||
* Copyright (C) 1998-05-03, Phil Blundell <philb@gnu.org>
|
||||
* Copied from http://www.tazenda.demon.co.uk/phil/vgrabber.c
|
||||
* 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) \
|
||||
{ \
|
||||
switch (format) \
|
||||
{ \
|
||||
case VIDEO_PALETTE_GREY: \
|
||||
switch (depth) \
|
||||
{ \
|
||||
case 4: \
|
||||
case 6: \
|
||||
case 8: \
|
||||
(r) = (g) = (b) = (*buf++ << 8);\
|
||||
break; \
|
||||
\
|
||||
case 16: \
|
||||
(r) = (g) = (b) = \
|
||||
*((unsigned short *) buf); \
|
||||
buf += 2; \
|
||||
break; \
|
||||
} \
|
||||
break; \
|
||||
\
|
||||
\
|
||||
case VIDEO_PALETTE_RGB565: \
|
||||
{ \
|
||||
unsigned short tmp = *(unsigned short *)buf; \
|
||||
(r) = tmp&0xF800; \
|
||||
(g) = (tmp<<5)&0xFC00; \
|
||||
(b) = (tmp<<11)&0xF800; \
|
||||
buf += 2; \
|
||||
} \
|
||||
break; \
|
||||
\
|
||||
case VIDEO_PALETTE_RGB555: \
|
||||
(r) = (buf[0]&0xF8)<<8; \
|
||||
(g) = ((buf[0] << 5 | buf[1] >> 3)&0xF8)<<8; \
|
||||
(b) = ((buf[1] << 2 ) & 0xF8)<<8; \
|
||||
buf += 2; \
|
||||
break; \
|
||||
\
|
||||
case VIDEO_PALETTE_RGB24: \
|
||||
(r) = buf[0] << 8; (g) = buf[1] << 8; \
|
||||
(b) = buf[2] << 8; \
|
||||
buf += 3; \
|
||||
break; \
|
||||
\
|
||||
default: \
|
||||
fprintf(stderr, \
|
||||
"Format %d not yet supported\n", \
|
||||
format); \
|
||||
} \
|
||||
}
|
||||
switch (format) \
|
||||
{ \
|
||||
case VIDEO_PALETTE_GREY: \
|
||||
switch (depth) \
|
||||
{ \
|
||||
case 4: \
|
||||
case 6: \
|
||||
case 8: \
|
||||
(r) = (g) = (b) = (*buf++ << 8);\
|
||||
break; \
|
||||
\
|
||||
case 16: \
|
||||
(r) = (g) = (b) = \
|
||||
*((unsigned short *) buf); \
|
||||
buf += 2; \
|
||||
break; \
|
||||
} \
|
||||
break; \
|
||||
\
|
||||
\
|
||||
case VIDEO_PALETTE_RGB565: \
|
||||
{ \
|
||||
unsigned short tmp = *(unsigned short *)buf; \
|
||||
(r) = tmp&0xF800; \
|
||||
(g) = (tmp<<5)&0xFC00; \
|
||||
(b) = (tmp<<11)&0xF800; \
|
||||
buf += 2; \
|
||||
} \
|
||||
break; \
|
||||
\
|
||||
case VIDEO_PALETTE_RGB555: \
|
||||
(r) = (buf[0]&0xF8)<<8; \
|
||||
(g) = ((buf[0] << 5 | buf[1] >> 3)&0xF8)<<8; \
|
||||
(b) = ((buf[1] << 2 ) & 0xF8)<<8; \
|
||||
buf += 2; \
|
||||
break; \
|
||||
\
|
||||
case VIDEO_PALETTE_RGB24: \
|
||||
(r) = buf[0] << 8; (g) = buf[1] << 8; \
|
||||
(b) = buf[2] << 8; \
|
||||
buf += 3; \
|
||||
break; \
|
||||
\
|
||||
default: \
|
||||
fprintf(stderr, \
|
||||
"Format %d not yet supported\n", \
|
||||
format); \
|
||||
} \
|
||||
}
|
||||
|
||||
int get_brightness_adj(unsigned char *image, long size, int *brightness) {
|
||||
long i, tot = 0;
|
||||
@ -324,40 +324,40 @@ int main(int argc, char ** argv)
|
||||
if(ioctl(fd, VIDIOCSPICT, &vpic) < 0) {
|
||||
vpic.depth=6;
|
||||
if(ioctl(fd, VIDIOCSPICT, &vpic) < 0) {
|
||||
vpic.depth=4;
|
||||
if(ioctl(fd, VIDIOCSPICT, &vpic) < 0) {
|
||||
fprintf(stderr, "Unable to find a supported capture format.\n");
|
||||
close(fd);
|
||||
exit(1);
|
||||
}
|
||||
vpic.depth=4;
|
||||
if(ioctl(fd, VIDIOCSPICT, &vpic) < 0) {
|
||||
fprintf(stderr, "Unable to find a supported capture format.\n");
|
||||
close(fd);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
vpic.depth=24;
|
||||
vpic.palette=VIDEO_PALETTE_RGB24;
|
||||
|
||||
|
||||
if(ioctl(fd, VIDIOCSPICT, &vpic) < 0) {
|
||||
vpic.palette=VIDEO_PALETTE_RGB565;
|
||||
vpic.depth=16;
|
||||
|
||||
|
||||
if(ioctl(fd, VIDIOCSPICT, &vpic)==-1) {
|
||||
vpic.palette=VIDEO_PALETTE_RGB555;
|
||||
vpic.depth=15;
|
||||
|
||||
if(ioctl(fd, VIDIOCSPICT, &vpic)==-1) {
|
||||
fprintf(stderr, "Unable to find a supported capture format.\n");
|
||||
return -1;
|
||||
}
|
||||
vpic.palette=VIDEO_PALETTE_RGB555;
|
||||
vpic.depth=15;
|
||||
|
||||
if(ioctl(fd, VIDIOCSPICT, &vpic)==-1) {
|
||||
fprintf(stderr, "Unable to find a supported capture format.\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
buffer = malloc(win.width * win.height * bpp);
|
||||
if (!buffer) {
|
||||
fprintf(stderr, "Out of memory.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
do {
|
||||
int newbright;
|
||||
read(fd, buffer, win.width * win.height * bpp);
|
||||
@ -365,8 +365,8 @@ int main(int argc, char ** argv)
|
||||
if (f) {
|
||||
vpic.brightness += (newbright << 8);
|
||||
if(ioctl(fd, VIDIOCSPICT, &vpic)==-1) {
|
||||
perror("VIDIOSPICT");
|
||||
break;
|
||||
perror("VIDIOSPICT");
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (f);
|
||||
@ -381,7 +381,7 @@ int main(int argc, char ** argv)
|
||||
fputc(g>>8, stdout);
|
||||
fputc(b>>8, stdout);
|
||||
}
|
||||
|
||||
|
||||
close(fd);
|
||||
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
|
||||
append-line in lilo.conf:
|
||||
|
||||
append="parport=0x378,7,3"
|
||||
append="parport=0x378,7,3"
|
||||
|
||||
See Documentation/parport.txt for more information about the
|
||||
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
|
||||
with Isabel (http://isabel.dit.upm.es/)
|
||||
- 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]
|
||||
- Chris Whiteford <Chris@informinteractive.com> for fixes related to the
|
||||
1.02 firmware
|
||||
|
@ -28,7 +28,7 @@ Iomega Buz:
|
||||
* Philips saa7111 TV decoder
|
||||
* Philips saa7185 TV encoder
|
||||
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
|
||||
Norms: PAL, SECAM (720x576 @ 25 fps), NTSC (720x480 @ 29.97 fps)
|
||||
Card number: 7
|
||||
@ -39,7 +39,7 @@ Linux Media Labs LML33:
|
||||
* Brooktree bt819 TV decoder
|
||||
* Brooktree bt856 TV encoder
|
||||
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
|
||||
Norms: PAL (720x576 @ 25 fps), NTSC (720x480 @ 29.97 fps)
|
||||
Card number: 5
|
||||
@ -50,7 +50,7 @@ Linux Media Labs LML33R10:
|
||||
* Philips saa7114 TV decoder
|
||||
* Analog Devices adv7170 TV encoder
|
||||
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
|
||||
Norms: PAL (720x576 @ 25 fps), NTSC (720x480 @ 29.97 fps)
|
||||
Card number: 6
|
||||
@ -61,7 +61,7 @@ Pinnacle/Miro DC10(new):
|
||||
* Philips saa7110a TV decoder
|
||||
* Analog Devices adv7176 TV encoder
|
||||
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
|
||||
Norms: PAL, SECAM (768x576 @ 25 fps), NTSC (640x480 @ 29.97 fps)
|
||||
Card number: 1
|
||||
@ -84,7 +84,7 @@ Pinnacle/Miro DC10(old): *
|
||||
* Micronas vpx3220a TV decoder
|
||||
* mse3000 TV encoder or Analog Devices adv7176 TV encoder *
|
||||
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
|
||||
Norms: PAL, SECAM (768x576 @ 25 fps), NTSC (640x480 @ 29.97 fps)
|
||||
Card number: 0
|
||||
@ -96,7 +96,7 @@ Pinnacle/Miro DC30: *
|
||||
* Micronas vpx3225d/vpx3220a/vpx3216b TV decoder
|
||||
* Analog Devices adv7176 TV encoder
|
||||
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
|
||||
Norms: PAL, SECAM (768x576 @ 25 fps), NTSC (640x480 @ 29.97 fps)
|
||||
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
|
||||
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
|
||||
combination is supported by the driver. There are currently 11 different
|
||||
tv broadcast formats all aver the world.
|
||||
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
|
||||
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 says not much about about the colorsystem used !!!
|
||||
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
|
||||
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
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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 !
|
||||
|
||||
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://info.electronicwerkstatt.de/bereiche/fernsehtechnik/frequenzen_und_normen/Fernsehnormen/
|
||||
and http://www.cabl.com/restaurant/channel.html
|
||||
|
||||
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
|
||||
as NTSC 4.43 . The Datasheets also talk about NTSC 44, It seems as if it would
|
||||
be the same as NTSC 4.43.
|
||||
as NTSC 4.43 . The Datasheets also talk about NTSC 44, It seems as if it would
|
||||
be the same as NTSC 4.43.
|
||||
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.
|
||||
|
||||
But I did not defiantly find out what NTSC Comb is.
|
||||
|
||||
Philips saa7111 TV decoder
|
||||
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
|
||||
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
|
||||
|
||||
Philips saa7110a TV decoder
|
||||
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
|
||||
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
|
||||
|
||||
Brooktree bt819 TV decoder
|
||||
@ -206,7 +206,7 @@ was introduced in 1996, is used in the BUZ
|
||||
can generate: PAL B/G, NTSC M
|
||||
|
||||
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)
|
||||
|
||||
Analog Devices adv7170 TV Encoder
|
||||
@ -221,9 +221,9 @@ ITT mse3000 TV encoder
|
||||
was introduced in 1991, is used in the DC10 old
|
||||
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
|
||||
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
|
||||
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)
|
||||
Intel 440BX (early stepping)
|
||||
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 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.
|
||||
|
||||
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.
|
||||
|
||||
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;
|
||||
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
|
||||
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;
|
||||
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
|
||||
for calculations.
|
||||
|
||||
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
|
||||
here, so we don't need to do any fancy corrections for bits-per-pixel or such
|
||||
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
|
||||
here, so we don't need to do any fancy corrections for bits-per-pixel or such
|
||||
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.
|
||||
|
||||
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!
|
||||
|
||||
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:
|
||||
|
||||
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
|
||||
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
|
||||
option is silently overridden, and the -b128 option takes precedence, leaving
|
||||
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
|
||||
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
|
||||
option is silently overridden, and the -b128 option takes precedence, leaving
|
||||
us with the equivalence of -q32.
|
||||
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
than -q24 at -d1. (And PAL, and 704 pixels width...)
|
||||
|
||||
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 that actually grab at the specified -q value is the last one, which
|
||||
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 that actually grab at the specified -q value is the last one, which
|
||||
is clearly visible, looking at the file size.
|
||||
--
|
||||
|
||||
|
@ -14,13 +14,13 @@ Hauppauge Win/TV pci (version 405):
|
||||
|
||||
Microchip 24LC02B or
|
||||
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
|
||||
TDA9800: sound decoder
|
||||
Winbond W24257AS-35: 32Kx8 CMOS static RAM (Videotext buffer mem)
|
||||
14052B: analog switch for selection of sound source
|
||||
|
||||
PAL:
|
||||
PAL:
|
||||
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
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
- Start capturing by pressing "c" or by selecting it via a menu!!!
|
||||
|
||||
- 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
|
||||
XFree-3.2A! This solved the problem for most people.
|
||||
|
||||
@ -31,23 +31,23 @@
|
||||
(mostly with Trio 64 but also with some others)
|
||||
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.
|
||||
|
||||
|
||||
Since I do not know much (better make that almost nothing) about VGA card
|
||||
programming I do not know the reason for this.
|
||||
Looks like XFree does something different when setting up the video memory?
|
||||
Maybe somebody can enlighten me?
|
||||
Would be nice if somebody could get this to work with XFree since
|
||||
Accelerated X costs more than some of the grabber cards ...
|
||||
|
||||
Maybe somebody can enlighten me?
|
||||
Would be nice if somebody could get this to work with XFree since
|
||||
Accelerated X costs more than some of the grabber cards ...
|
||||
|
||||
Better linear frame buffer support for S3 cards will probably be in
|
||||
XFree 4.0.
|
||||
|
||||
|
||||
- Grabbing is not switched off when changing consoles with XFree.
|
||||
That's because XFree and some AcceleratedX versions do not send unmap
|
||||
events.
|
||||
|
||||
- Some popup windows (e.g. of the window manager) are not refreshed.
|
||||
|
||||
|
||||
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
|
||||
|
@ -38,9 +38,9 @@ tolerate.
|
||||
------------------------
|
||||
|
||||
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
|
||||
finish-ing the previous transaction.
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
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.
|
||||
|
||||
- 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
|
||||
components on their cards. (E.g. how the tuner type is detected)
|
||||
Without their card I could not have debugged the NTSC mode.
|
||||
|
||||
|
||||
- Hauppauge for telling how the sound input is selected and what components
|
||||
they do and will use on their radio cards.
|
||||
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"
|
||||
|
||||
Set Frequency: code = (freq*40) + 10486188
|
||||
foreach of the 24 bits in code,
|
||||
(from Least to Most Significant):
|
||||
to write a "zero" bit,
|
||||
BASE <-- 0x01 (audio mute, no stereo detect, radio
|
||||
foreach of the 24 bits in code,
|
||||
(from Least to Most Significant):
|
||||
to write a "zero" bit,
|
||||
BASE <-- 0x01 (audio mute, no stereo detect, radio
|
||||
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)
|
||||
to write a "one" bit,
|
||||
BASE <-- 0x05 (audio mute, no stereo detect, radio
|
||||
to write a "one" bit,
|
||||
BASE <-- 0x05 (audio mute, no stereo detect, radio
|
||||
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)
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
|
@ -26,7 +26,7 @@ is called VIDEO_PALETTE_YUV422 (16 bpp).
|
||||
A minimal test application (with source) is available from:
|
||||
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.
|
||||
|
||||
Good luck!
|
||||
|
@ -2,7 +2,7 @@ Driver for Trust Computer Products Framegrabber, version 0.6.1
|
||||
------ --- ----- -------- -------- ------------ ------- - - -
|
||||
|
||||
- ZORAN ------------------------------------------------------
|
||||
Author: Pauline Middelink <middelin@polyware.nl>
|
||||
Author: Pauline Middelink <middelin@polyware.nl>
|
||||
Date: 18 September 1999
|
||||
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
|
||||
be found in the source of zr36120. Look for tvcards. If your
|
||||
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!)
|
||||
Dont forget to set video_input to the number of inputs
|
||||
|
@ -50,5 +50,19 @@ config VIDEO_IR
|
||||
config VIDEO_TVEEPROM
|
||||
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
|
||||
|
||||
|
@ -50,14 +50,15 @@ void saa7146_res_free(struct saa7146_fh *fh, unsigned int bits)
|
||||
/********************************************************************************/
|
||||
/* 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));
|
||||
|
||||
BUG_ON(in_interrupt());
|
||||
|
||||
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);
|
||||
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)
|
||||
saa7146_dma_free(dev,buf);
|
||||
saa7146_dma_free(dev,q,buf);
|
||||
|
||||
if (STATE_NEEDS_INIT == buf->vb.state) {
|
||||
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_alloc(dev->pci, &buf->pt[2]);
|
||||
|
||||
err = videobuf_iolock(dev->pci,&buf->vb, NULL);
|
||||
err = videobuf_iolock(q,&buf->vb, NULL);
|
||||
if (err)
|
||||
goto oops;
|
||||
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:
|
||||
DEB_VBI(("error out.\n"));
|
||||
saa7146_dma_free(dev,buf);
|
||||
saa7146_dma_free(dev,q,buf);
|
||||
|
||||
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;
|
||||
|
||||
DEB_VBI(("vb:%p\n",vb));
|
||||
saa7146_dma_free(dev,buf);
|
||||
saa7146_dma_free(dev,q,buf);
|
||||
}
|
||||
|
||||
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 != fh->video_fmt.field ||
|
||||
buf->fmt != &fh->video_fmt) {
|
||||
saa7146_dma_free(dev,buf);
|
||||
saa7146_dma_free(dev,q,buf);
|
||||
}
|
||||
|
||||
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]);
|
||||
}
|
||||
|
||||
err = videobuf_iolock(dev->pci,&buf->vb, &vv->ov_fb);
|
||||
err = videobuf_iolock(q,&buf->vb, &vv->ov_fb);
|
||||
if (err)
|
||||
goto oops;
|
||||
err = saa7146_pgtable_build(dev,buf);
|
||||
@ -1318,7 +1318,7 @@ static int buffer_prepare(struct videobuf_queue *q,
|
||||
|
||||
oops:
|
||||
DEB_D(("error out.\n"));
|
||||
saa7146_dma_free(dev,buf);
|
||||
saa7146_dma_free(dev,q,buf);
|
||||
|
||||
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;
|
||||
|
||||
DEB_CAP(("vbuf:%p\n",vb));
|
||||
saa7146_dma_free(dev,buf);
|
||||
saa7146_dma_free(dev,q,buf);
|
||||
}
|
||||
|
||||
static struct videobuf_queue_ops video_qops = {
|
||||
|
@ -541,6 +541,7 @@ static struct usb_device_id flexcop_usb_table [] = {
|
||||
{ USB_DEVICE(0x0af7, 0x0101) },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE (usb, flexcop_usb_table);
|
||||
|
||||
/* usb specific object needed to register this driver with the usb subsystem */
|
||||
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
|
||||
|
||||
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;
|
||||
|
||||
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++) {
|
||||
|
||||
switch (msg[i].addr) {
|
||||
case 0x63:
|
||||
cxusb_gpio_tuner(d,0);
|
||||
break;
|
||||
default:
|
||||
cxusb_gpio_tuner(d,1);
|
||||
break;
|
||||
}
|
||||
if (d->udev->descriptor.idVendor == USB_VID_MEDION)
|
||||
switch (msg[i].addr) {
|
||||
case 0x63:
|
||||
cxusb_gpio_tuner(d,0);
|
||||
break;
|
||||
default:
|
||||
cxusb_gpio_tuner(d,1);
|
||||
break;
|
||||
}
|
||||
|
||||
/* read request */
|
||||
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;
|
||||
|
||||
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);
|
||||
|
||||
@ -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)
|
||||
break;
|
||||
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) &&
|
||||
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 + 3] = udev->descriptor.idProduct >> 8;
|
||||
|
||||
|
@ -6,6 +6,8 @@
|
||||
|
||||
extern int dvb_usb_cxusb_debug;
|
||||
#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 */
|
||||
#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
|
||||
src = 0x0020;
|
||||
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:
|
||||
dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG1\n");
|
||||
fm_matrix = 0x3000; // mono
|
||||
|
@ -16,31 +16,7 @@ config VIDEO_ADV_DEBUG
|
||||
V4L devices.
|
||||
In doubt, say N.
|
||||
|
||||
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.
|
||||
source "drivers/media/video/bt8xx/Kconfig"
|
||||
|
||||
config VIDEO_SAA6588
|
||||
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/em28xx/Kconfig"
|
||||
|
||||
config VIDEO_OVCAMCHIP
|
||||
tristate "OmniVision Camera Chip support"
|
||||
depends on VIDEO_DEV && I2C
|
||||
@ -391,4 +365,234 @@ config VIDEO_SAA7127
|
||||
To compile this driver as a module, choose M here: the
|
||||
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
|
||||
|
@ -2,9 +2,6 @@
|
||||
# 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
|
||||
zr36067-objs := zoran_procfs.o zoran_device.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_BT848) += bttv.o tvaudio.o \
|
||||
tda7432.o tda9875.o ir-kbd-i2c.o
|
||||
obj-$(CONFIG_VIDEO_BT848) += bt8xx/
|
||||
obj-$(CONFIG_VIDEO_BT848) += tvaudio.o tda7432.o tda9875.o ir-kbd-i2c.o
|
||||
obj-$(CONFIG_SOUND_TVMIXER) += tvmixer.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_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
|
||||
|
@ -1,9 +1,9 @@
|
||||
/*
|
||||
/*
|
||||
* adv7170 - adv7170, adv7171 video encoder driver version 0.0.1
|
||||
*
|
||||
* 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) 1999 Wolfgang Scherr <scherr@net4you.net>
|
||||
@ -173,7 +173,7 @@ adv7170_write_block (struct i2c_client *client,
|
||||
static const unsigned char init_NTSC[] = {
|
||||
0x00, 0x10, // MR0
|
||||
0x01, 0x20, // MR1
|
||||
0x02, 0x0e, // MR2 RTC control: bits 2 and 1
|
||||
0x02, 0x0e, // MR2 RTC control: bits 2 and 1
|
||||
0x03, 0x80, // MR3
|
||||
0x04, 0x30, // MR4
|
||||
0x05, 0x00, // Reserved
|
||||
@ -196,7 +196,7 @@ static const unsigned char init_NTSC[] = {
|
||||
0x16, 0x00, // CGMS_WSS_0
|
||||
0x17, 0x00, // CGMS_WSS_1
|
||||
0x18, 0x00, // CGMS_WSS_2
|
||||
0x19, 0x00, // Teletext Ctl
|
||||
0x19, 0x00, // Teletext Ctl
|
||||
};
|
||||
|
||||
static const unsigned char init_PAL[] = {
|
||||
@ -381,7 +381,7 @@ static unsigned short normal_i2c[] =
|
||||
};
|
||||
|
||||
static unsigned short ignore = I2C_CLIENT_END;
|
||||
|
||||
|
||||
static struct i2c_client_address_data addr_data = {
|
||||
.normal_i2c = normal_i2c,
|
||||
.probe = &ignore,
|
||||
|
@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* adv7175 - adv7175a video encoder driver version 0.0.3
|
||||
*
|
||||
* Copyright (C) 1998 Dave Perks <dperks@ibm.net>
|
||||
@ -233,7 +233,7 @@ adv7175_command (struct i2c_client *client,
|
||||
sizeof(init_common));
|
||||
adv7175_write(client, 0x07, TR0MODE | TR0RST);
|
||||
adv7175_write(client, 0x07, TR0MODE);
|
||||
break;
|
||||
break;
|
||||
|
||||
case ENCODER_GET_CAPABILITIES:
|
||||
{
|
||||
@ -399,7 +399,7 @@ static unsigned short normal_i2c[] =
|
||||
};
|
||||
|
||||
static unsigned short ignore = I2C_CLIENT_END;
|
||||
|
||||
|
||||
static struct i2c_client_address_data addr_data = {
|
||||
.normal_i2c = normal_i2c,
|
||||
.probe = &ignore,
|
||||
|
@ -161,39 +161,39 @@ void iic(int n, unsigned long addr, unsigned long data1, unsigned long data2,
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Slave Address */
|
||||
ar_outl(addr, PLDI2CDATA);
|
||||
/* Slave Address */
|
||||
ar_outl(addr, PLDI2CDATA);
|
||||
wait_for_vsync();
|
||||
|
||||
/* Start */
|
||||
ar_outl(1, PLDI2CCND);
|
||||
/* Start */
|
||||
ar_outl(1, PLDI2CCND);
|
||||
wait_acknowledge();
|
||||
|
||||
/* Transfer data 1 */
|
||||
ar_outl(data1, PLDI2CDATA);
|
||||
ar_outl(data1, PLDI2CDATA);
|
||||
wait_for_vsync();
|
||||
ar_outl(PLDI2CSTEN_STEN, PLDI2CSTEN);
|
||||
ar_outl(PLDI2CSTEN_STEN, PLDI2CSTEN);
|
||||
wait_acknowledge();
|
||||
|
||||
/* Transfer data 2 */
|
||||
ar_outl(data2, PLDI2CDATA);
|
||||
ar_outl(data2, PLDI2CDATA);
|
||||
wait_for_vsync();
|
||||
ar_outl(PLDI2CSTEN_STEN, PLDI2CSTEN);
|
||||
ar_outl(PLDI2CSTEN_STEN, PLDI2CSTEN);
|
||||
wait_acknowledge();
|
||||
|
||||
if (n == 3) {
|
||||
/* Transfer data 3 */
|
||||
ar_outl(data3, PLDI2CDATA);
|
||||
ar_outl(data3, PLDI2CDATA);
|
||||
wait_for_vsync();
|
||||
ar_outl(PLDI2CSTEN_STEN, PLDI2CSTEN);
|
||||
ar_outl(PLDI2CSTEN_STEN, PLDI2CSTEN);
|
||||
wait_acknowledge();
|
||||
}
|
||||
}
|
||||
|
||||
/* Stop */
|
||||
/* Stop */
|
||||
for (i = 0; i < 100; i++)
|
||||
cpu_relax();
|
||||
ar_outl(2, PLDI2CCND);
|
||||
ar_outl(2, PLDI2CCND);
|
||||
ar_outl(2, PLDI2CCND);
|
||||
ar_outl(2, PLDI2CCND);
|
||||
|
||||
while (ar_inl(PLDI2CSTS) & PLDI2CSTS_BB)
|
||||
cpu_relax();
|
||||
@ -204,24 +204,24 @@ void init_iic(void)
|
||||
{
|
||||
DEBUG(1, "init_iic:\n");
|
||||
|
||||
/*
|
||||
/*
|
||||
* ICU Setting (iic)
|
||||
*/
|
||||
/* I2C Setting */
|
||||
ar_outl(0x0, PLDI2CCR); /* I2CCR Disable */
|
||||
ar_outl(0x0300, PLDI2CMOD); /* I2CMOD ACK/8b-data/7b-addr/auto */
|
||||
ar_outl(0x1, PLDI2CACK); /* I2CACK ACK */
|
||||
/* I2C Setting */
|
||||
ar_outl(0x0, PLDI2CCR); /* I2CCR Disable */
|
||||
ar_outl(0x0300, PLDI2CMOD); /* I2CMOD ACK/8b-data/7b-addr/auto */
|
||||
ar_outl(0x1, PLDI2CACK); /* I2CACK ACK */
|
||||
|
||||
/* I2C CLK */
|
||||
/* 50MH-100k */
|
||||
/* 50MH-100k */
|
||||
if (freq == 75) {
|
||||
ar_outl(369, PLDI2CFREQ); /* BCLK = 75MHz */
|
||||
ar_outl(369, PLDI2CFREQ); /* BCLK = 75MHz */
|
||||
} else if (freq == 50) {
|
||||
ar_outl(244, PLDI2CFREQ); /* BCLK = 50MHz */
|
||||
} else {
|
||||
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.
|
||||
*/
|
||||
*/
|
||||
for (; tmout >= 0; tmout--) {
|
||||
l = ar_inl(ARVHCOUNT);
|
||||
if (l == exp_line)
|
||||
@ -562,8 +562,8 @@ static void ar_interrupt(int irq, void *dev, struct pt_regs *regs)
|
||||
/* operations for interlace mode */
|
||||
if ( line_count < (AR_HEIGHT_VGA/2) ) /* even line */
|
||||
line_number = (line_count << 1);
|
||||
else /* odd line */
|
||||
line_number =
|
||||
else /* odd line */
|
||||
line_number =
|
||||
(((line_count - (AR_HEIGHT_VGA/2)) << 1) + 1);
|
||||
} else {
|
||||
line_number = line_count;
|
||||
@ -651,7 +651,7 @@ static int ar_initialize(struct video_device *dev)
|
||||
cr |= ARVCR1_NORMAL;
|
||||
ar_outl(cr, ARVCR1);
|
||||
|
||||
/*
|
||||
/*
|
||||
* Initialize IIC so that CPU can communicate with 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.
|
||||
* device is named "video[0-64]".
|
||||
* video_register_device() initializes h/w using ar_initialize().
|
||||
*/
|
||||
*/
|
||||
if (video_register_device(ar->vdev, VFL_TYPE_GRABBER, video_nr) != 0) {
|
||||
/* return -1, -ENFILE(full) or others */
|
||||
printk("arv: register video (Colour AR) failed.\n");
|
||||
|
@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* bt819 - BT819A VideoStream Decoder (Rockwell Part)
|
||||
*
|
||||
* Copyright (C) 1999 Mike Bernson <mike@mlb.org>
|
||||
@ -6,7 +6,7 @@
|
||||
*
|
||||
* Modifications for LML33/DC10plus unified driver
|
||||
* Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>
|
||||
*
|
||||
*
|
||||
* Changes by Ronald Bultje <rbultje@ronald.bitfreak.net>
|
||||
* - 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?
|
||||
*/
|
||||
0x14, 0x00, /* 0x14 Vertial Scaling lsb */
|
||||
0x16, 0x07, /* 0x16 Video Timing Polarity
|
||||
0x16, 0x07, /* 0x16 Video Timing Polarity
|
||||
ACTIVE=active low
|
||||
FIELD: high=odd,
|
||||
FIELD: high=odd,
|
||||
vreset=active high,
|
||||
hreset=active high */
|
||||
0x18, 0x68, /* 0x18 AGC Delay */
|
||||
@ -497,7 +497,7 @@ static unsigned short normal_i2c[] = {
|
||||
};
|
||||
|
||||
static unsigned short ignore = I2C_CLIENT_END;
|
||||
|
||||
|
||||
static struct i2c_client_address_data addr_data = {
|
||||
.normal_i2c = normal_i2c,
|
||||
.probe = &ignore,
|
||||
|
@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* bt856 - BT856A Digital Video Encoder (Rockwell Part)
|
||||
*
|
||||
* 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 ignore = I2C_CLIENT_END;
|
||||
|
||||
|
||||
static struct i2c_client_address_data addr_data = {
|
||||
.normal_i2c = normal_i2c,
|
||||
.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/errno.h>
|
||||
#include <linux/slab.h>
|
||||
#include <media/audiochip.h>
|
||||
#include <media/v4l2-common.h>
|
||||
|
||||
#include "bttv.h"
|
||||
@ -39,7 +38,7 @@
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
/* 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_INSMOD;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -36,13 +36,15 @@
|
||||
#include <linux/kdev_t.h>
|
||||
#include "bttvp.h"
|
||||
#include <media/v4l2-common.h>
|
||||
#include <media/tvaudio.h>
|
||||
#include <media/msp3400.h>
|
||||
|
||||
#include <linux/dma-mapping.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <asm/byteorder.h>
|
||||
|
||||
#include "rds.h"
|
||||
#include <media/rds.h>
|
||||
|
||||
|
||||
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[] = {
|
||||
"audio: tuner", "audio: radio", "audio: extern",
|
||||
"audio: intern", "audio: off"
|
||||
"audio: intern", "audio: mute"
|
||||
};
|
||||
|
||||
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,
|
||||
bttv_tvcards[btv->c.type].gpiomask);
|
||||
signal = btread(BT848_DSTATUS) & BT848_DSTATUS_HLOC;
|
||||
|
||||
switch (mode) {
|
||||
case AUDIO_MUTE:
|
||||
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;
|
||||
btv->mute = mute;
|
||||
btv->audio = input;
|
||||
|
||||
val = bttv_tvcards[btv->c.type].audiomux[mux];
|
||||
gpio_bits(bttv_tvcards[btv->c.type].gpiomask,val);
|
||||
/* automute */
|
||||
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)
|
||||
bttv_gpio_tracking(btv,audio_modes[mux]);
|
||||
if (!in_interrupt())
|
||||
bttv_call_i2c_clients(btv,AUDC_SET_INPUT,&(i2c_mux));
|
||||
bttv_gpio_tracking(btv, audio_modes[mute ? 4 : input]);
|
||||
if (in_interrupt())
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
||||
i2c_vidiocschan(struct bttv *btv)
|
||||
{
|
||||
@ -1023,8 +1078,8 @@ set_input(struct bttv *btv, unsigned int input)
|
||||
} else {
|
||||
video_mux(btv,input);
|
||||
}
|
||||
audio_mux(btv,(input == bttv_tvcards[btv->c.type].tuner ?
|
||||
AUDIO_TUNER : AUDIO_EXTERN));
|
||||
audio_input(btv,(input == bttv_tvcards[btv->c.type].tuner ?
|
||||
TVAUDIO_INPUT_TUNER : TVAUDIO_INPUT_EXTERN));
|
||||
set_tvnorm(btv,btv->tvnorm);
|
||||
i2c_vidiocschan(btv);
|
||||
}
|
||||
@ -1236,10 +1291,10 @@ static int set_control(struct bttv *btv, struct v4l2_control *c)
|
||||
case V4L2_CID_AUDIO_MUTE:
|
||||
if (c->value) {
|
||||
va.flags |= VIDEO_AUDIO_MUTE;
|
||||
audio_mux(btv, AUDIO_MUTE);
|
||||
audio_mute(btv, 1);
|
||||
} else {
|
||||
va.flags &= ~VIDEO_AUDIO_MUTE;
|
||||
audio_mux(btv, AUDIO_UNMUTE);
|
||||
audio_mute(btv, 0);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -1397,7 +1452,7 @@ bttv_switch_overlay(struct bttv *btv, struct bttv_fh *fh,
|
||||
free_btres(btv,fh,RESOURCE_OVERLAY);
|
||||
if (NULL != old) {
|
||||
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);
|
||||
}
|
||||
dprintk("switch_overlay: done\n");
|
||||
@ -1407,7 +1462,8 @@ bttv_switch_overlay(struct bttv *btv, struct bttv_fh *fh,
|
||||
/* ----------------------------------------------------------------------- */
|
||||
/* 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,
|
||||
unsigned int width, unsigned int height,
|
||||
enum v4l2_field field)
|
||||
@ -1450,7 +1506,7 @@ static int bttv_prepare_buffer(struct bttv *btv, struct bttv_buffer *buf,
|
||||
/* alloc risc memory */
|
||||
if (STATE_NEEDS_INIT == buf->vb.state) {
|
||||
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;
|
||||
}
|
||||
|
||||
@ -1462,7 +1518,7 @@ static int bttv_prepare_buffer(struct bttv *btv, struct bttv_buffer *buf,
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
bttv_dma_free(btv,buf);
|
||||
bttv_dma_free(q,btv,buf);
|
||||
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_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);
|
||||
}
|
||||
|
||||
@ -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_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 = {
|
||||
@ -1653,7 +1709,7 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg)
|
||||
return -EINVAL;
|
||||
|
||||
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);
|
||||
|
||||
/* 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);
|
||||
if (t->audmode == V4L2_TUNER_MODE_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;
|
||||
else if (t->audmode == V4L2_TUNER_MODE_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)
|
||||
? V4L2_FIELD_INTERLACED
|
||||
: V4L2_FIELD_BOTTOM;
|
||||
retval = bttv_prepare_buffer(btv,buf,
|
||||
retval = bttv_prepare_buffer(&fh->cap,btv,buf,
|
||||
format_by_palette(vm->format),
|
||||
vm->width,vm->height,field);
|
||||
if (0 != retval)
|
||||
@ -2528,8 +2585,8 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
|
||||
retval = -EIO;
|
||||
/* fall through */
|
||||
case STATE_DONE:
|
||||
videobuf_dma_pci_sync(btv->c.pci,&buf->vb.dma);
|
||||
bttv_dma_free(btv,buf);
|
||||
videobuf_dma_sync(&fh->cap,&buf->vb.dma);
|
||||
bttv_dma_free(&fh->cap,btv,buf);
|
||||
break;
|
||||
default:
|
||||
retval = -EINVAL;
|
||||
@ -3162,8 +3219,8 @@ static int radio_open(struct inode *inode, struct file *file)
|
||||
|
||||
file->private_data = btv;
|
||||
|
||||
bttv_call_i2c_clients(btv,AUDC_SET_RADIO,&btv->tuner_type);
|
||||
audio_mux(btv,AUDIO_RADIO);
|
||||
bttv_call_i2c_clients(btv,AUDC_SET_RADIO,NULL);
|
||||
audio_input(btv,TVAUDIO_INPUT_RADIO);
|
||||
|
||||
mutex_unlock(&btv->lock);
|
||||
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);
|
||||
|
||||
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)) {
|
||||
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_hue(btv,32768);
|
||||
bt848_sat(btv,32768);
|
||||
audio_mux(btv,AUDIO_MUTE);
|
||||
audio_mute(btv, 1);
|
||||
set_input(btv,0);
|
||||
}
|
||||
|
@ -302,6 +302,10 @@ static int attach_inform(struct i2c_client *client)
|
||||
if (!client->driver->command)
|
||||
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) {
|
||||
struct tuner_setup tun_setup;
|
||||
|
@ -509,11 +509,11 @@ bttv_risc_hook(struct bttv *btv, int slot, struct btcx_riscmem *risc,
|
||||
}
|
||||
|
||||
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());
|
||||
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);
|
||||
btcx_riscmem_free(btv->c.pci,&buf->bottom);
|
||||
btcx_riscmem_free(btv->c.pci,&buf->top);
|
@ -96,7 +96,7 @@ static int vbi_buffer_prepare(struct videobuf_queue *q,
|
||||
return -EINVAL;
|
||||
|
||||
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;
|
||||
if (0 != (rc = vbi_buffer_risc(btv,buf,fh->lines)))
|
||||
goto fail;
|
||||
@ -109,7 +109,7 @@ static int vbi_buffer_prepare(struct videobuf_queue *q,
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
bttv_dma_free(btv,buf);
|
||||
bttv_dma_free(q,btv,buf);
|
||||
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);
|
||||
|
||||
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 = {
|
@ -18,6 +18,7 @@
|
||||
#include <linux/i2c.h>
|
||||
#include <media/ir-common.h>
|
||||
#include <media/ir-kbd-i2c.h>
|
||||
#include <media/i2c-addr.h>
|
||||
|
||||
/* ---------------------------------------------------------- */
|
||||
/* exported by bttv-cards.c */
|
||||
@ -168,25 +169,6 @@
|
||||
#define BTTV_BOARD_HAUPPAUGE_IMPACTVCB 0x8f
|
||||
#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 */
|
||||
#define PT2254_L_CHANNEL 0x10
|
||||
#define PT2254_R_CHANNEL 0x08
|
||||
@ -252,7 +234,8 @@ struct tvcard
|
||||
unsigned int digital_mode; // DIGITAL_MODE_CAMERA or DIGITAL_MODE_VIDEO
|
||||
u32 gpiomask;
|
||||
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 */
|
||||
|
||||
/* i2c audio flags */
|
@ -41,7 +41,6 @@
|
||||
|
||||
#include <linux/device.h>
|
||||
#include <media/video-buf.h>
|
||||
#include <media/audiochip.h>
|
||||
#include <media/tuner.h>
|
||||
#include <media/tveeprom.h>
|
||||
#include <media/ir-common.h>
|
||||
@ -190,7 +189,8 @@ int bttv_buffer_activate_video(struct bttv *btv,
|
||||
struct bttv_buffer_set *set);
|
||||
int bttv_buffer_activate_vbi(struct bttv *btv,
|
||||
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 */
|
||||
int bttv_overlay_risc(struct bttv *btv, struct bttv_overlay *ov,
|
||||
@ -298,6 +298,8 @@ struct bttv {
|
||||
int i2c_state, i2c_rc;
|
||||
int i2c_done;
|
||||
wait_queue_head_t i2c_queue;
|
||||
struct i2c_client *i2c_msp34xx_client;
|
||||
struct i2c_client *i2c_tvaudio_client;
|
||||
|
||||
/* video4linux (1) */
|
||||
struct video_device *video_dev;
|
||||
@ -320,6 +322,7 @@ struct bttv {
|
||||
/* video state */
|
||||
unsigned int input;
|
||||
unsigned int audio;
|
||||
unsigned int mute;
|
||||
unsigned long freq;
|
||||
int tvnorm,hue,contrast,bright,saturation;
|
||||
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)
|
||||
{
|
||||
struct qcam_device *q;
|
||||
|
||||
|
||||
q = kmalloc(sizeof(struct qcam_device), GFP_KERNEL);
|
||||
if(q==NULL)
|
||||
return NULL;
|
||||
@ -158,16 +158,16 @@ static struct qcam_device *qcam_init(struct parport *port)
|
||||
q->pport = port;
|
||||
q->pdev = parport_register_device(port, "bw-qcam", NULL, NULL,
|
||||
NULL, 0, NULL);
|
||||
if (q->pdev == NULL)
|
||||
if (q->pdev == NULL)
|
||||
{
|
||||
printk(KERN_ERR "bw-qcam: couldn't register for %s.\n",
|
||||
port->name);
|
||||
kfree(q);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
memcpy(&q->vdev, &qcam_template, sizeof(qcam_template));
|
||||
|
||||
|
||||
mutex_init(&q->lock);
|
||||
|
||||
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))
|
||||
{
|
||||
/* 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
|
||||
busy blocked until the camera responds, so
|
||||
setting it lower is much better for interactive
|
||||
response. */
|
||||
|
||||
|
||||
if(runs++>maxpoll)
|
||||
{
|
||||
msleep_interruptible(5);
|
||||
@ -255,12 +255,12 @@ static int qc_waithand(struct qcam_device *q, int val)
|
||||
while (((status = read_lpstatus(q)) & 8))
|
||||
{
|
||||
/* 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
|
||||
busy blocked until the camera responds, so
|
||||
setting it lower is much better for interactive
|
||||
response. */
|
||||
|
||||
|
||||
if(runs++>maxpoll)
|
||||
{
|
||||
msleep_interruptible(5);
|
||||
@ -282,17 +282,17 @@ static unsigned int qc_waithand2(struct qcam_device *q, int val)
|
||||
{
|
||||
unsigned int status;
|
||||
int runs=0;
|
||||
|
||||
do
|
||||
|
||||
do
|
||||
{
|
||||
status = read_lpdata(q);
|
||||
/* 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
|
||||
busy blocked until the camera responds, so
|
||||
setting it lower is much better for interactive
|
||||
response. */
|
||||
|
||||
|
||||
if(runs++>maxpoll)
|
||||
{
|
||||
msleep_interruptible(5);
|
||||
@ -321,7 +321,7 @@ static int qc_detect(struct qcam_device *q)
|
||||
|
||||
lastreg = reg = read_lpstatus(q) & 0xf0;
|
||||
|
||||
for (i = 0; i < 500; i++)
|
||||
for (i = 0; i < 500; i++)
|
||||
{
|
||||
reg = read_lpstatus(q) & 0xf0;
|
||||
if (reg != lastreg)
|
||||
@ -357,7 +357,7 @@ static int qc_detect(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:
|
||||
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:
|
||||
write_lpcontrol(q, 0x20);
|
||||
write_lpdata(q, 0x75);
|
||||
|
||||
|
||||
if (read_lpdata(q) != 0x75) {
|
||||
q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_BIDIR;
|
||||
} else {
|
||||
@ -398,8 +398,8 @@ static void qc_reset(struct qcam_device *q)
|
||||
static int qc_setscanmode(struct qcam_device *q)
|
||||
{
|
||||
int old_mode = q->mode;
|
||||
|
||||
switch (q->transfer_scale)
|
||||
|
||||
switch (q->transfer_scale)
|
||||
{
|
||||
case 1:
|
||||
q->mode = 0;
|
||||
@ -412,7 +412,7 @@ static int qc_setscanmode(struct qcam_device *q)
|
||||
break;
|
||||
}
|
||||
|
||||
switch (q->bpp)
|
||||
switch (q->bpp)
|
||||
{
|
||||
case 4:
|
||||
break;
|
||||
@ -421,7 +421,7 @@ static int qc_setscanmode(struct qcam_device *q)
|
||||
break;
|
||||
}
|
||||
|
||||
switch (q->port_mode & QC_MODE_MASK)
|
||||
switch (q->port_mode & QC_MODE_MASK)
|
||||
{
|
||||
case QC_BIDIR:
|
||||
q->mode += 1;
|
||||
@ -430,10 +430,10 @@ static int qc_setscanmode(struct qcam_device *q)
|
||||
case QC_UNIDIR:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (q->mode != old_mode)
|
||||
q->status |= QC_PARAM_CHANGE;
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -451,7 +451,7 @@ static void qc_set(struct qcam_device *q)
|
||||
/* Set the brightness. Yes, this is repetitive, but it works.
|
||||
* Shorter versions seem to fail subtly. Feel free to try :-). */
|
||||
/* I think the problem was in qc_command, not here -- bls */
|
||||
|
||||
|
||||
qc_command(q, 0xb);
|
||||
qc_command(q, q->brightness);
|
||||
|
||||
@ -502,13 +502,13 @@ static inline int qc_readbytes(struct qcam_device *q, char buffer[])
|
||||
unsigned int hi2, lo2;
|
||||
static int state = 0;
|
||||
|
||||
if (buffer == NULL)
|
||||
if (buffer == NULL)
|
||||
{
|
||||
state = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (q->port_mode & QC_MODE_MASK)
|
||||
|
||||
switch (q->port_mode & QC_MODE_MASK)
|
||||
{
|
||||
case QC_BIDIR: /* Bi-directional Port */
|
||||
write_lpcontrol(q, 0x26);
|
||||
@ -517,7 +517,7 @@ static inline int qc_readbytes(struct qcam_device *q, char buffer[])
|
||||
write_lpcontrol(q, 0x2e);
|
||||
lo2 = (qc_waithand2(q, 0) >> 1);
|
||||
hi2 = (read_lpstatus(q) >> 3) & 0x1f;
|
||||
switch (q->bpp)
|
||||
switch (q->bpp)
|
||||
{
|
||||
case 4:
|
||||
buffer[0] = lo & 0xf;
|
||||
@ -544,7 +544,7 @@ static inline int qc_readbytes(struct qcam_device *q, char buffer[])
|
||||
write_lpcontrol(q, 0xe);
|
||||
hi = (qc_waithand(q, 0) & 0xf0) >> 4;
|
||||
|
||||
switch (q->bpp)
|
||||
switch (q->bpp)
|
||||
{
|
||||
case 4:
|
||||
buffer[0] = lo;
|
||||
@ -552,7 +552,7 @@ static inline int qc_readbytes(struct qcam_device *q, char buffer[])
|
||||
ret = 2;
|
||||
break;
|
||||
case 6:
|
||||
switch (state)
|
||||
switch (state)
|
||||
{
|
||||
case 0:
|
||||
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;
|
||||
char invert;
|
||||
|
||||
if (q->mode == -1)
|
||||
if (q->mode == -1)
|
||||
return -ENXIO;
|
||||
|
||||
qc_command(q, 0x7);
|
||||
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, 0x26);
|
||||
@ -618,7 +618,7 @@ static long qc_capture(struct qcam_device * q, char __user *buf, unsigned long l
|
||||
write_lpcontrol(q, 0x2e);
|
||||
(void) qc_waithand(q, 0);
|
||||
}
|
||||
|
||||
|
||||
/* strange -- should be 15:63 below, but 4bpp is odd */
|
||||
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;
|
||||
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);
|
||||
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;
|
||||
if (buffer[k] == 0 && invert == 16)
|
||||
if (buffer[k] == 0 && invert == 16)
|
||||
{
|
||||
/* 4bpp is odd (again) -- inverter is 16, not 15, but output
|
||||
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;
|
||||
}
|
||||
(void) qc_readbytes(q, NULL); /* reset state machine */
|
||||
|
||||
|
||||
/* Grabbing an entire frame from the quickcam is a lengthy
|
||||
process. We don't (usually) want to busy-block the
|
||||
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, 6);
|
||||
@ -687,7 +687,7 @@ static int qcam_do_ioctl(struct inode *inode, struct file *file,
|
||||
{
|
||||
struct video_device *dev = video_devdata(file);
|
||||
struct qcam_device *qcam=(struct qcam_device *)dev;
|
||||
|
||||
|
||||
switch(cmd)
|
||||
{
|
||||
case VIDIOCGCAP:
|
||||
@ -762,7 +762,7 @@ static int qcam_do_ioctl(struct inode *inode, struct file *file,
|
||||
return -EINVAL;
|
||||
if(p->depth!=4 && p->depth!=6)
|
||||
return -EINVAL;
|
||||
|
||||
|
||||
/*
|
||||
* Now load the camera.
|
||||
*/
|
||||
@ -790,11 +790,11 @@ static int qcam_do_ioctl(struct inode *inode, struct file *file,
|
||||
return -EINVAL;
|
||||
if(vw->width<80||vw->width>320)
|
||||
return -EINVAL;
|
||||
|
||||
|
||||
qcam->width = 320;
|
||||
qcam->height = 240;
|
||||
qcam->transfer_scale = 4;
|
||||
|
||||
|
||||
if(vw->width>=160 && vw->height>=120)
|
||||
{
|
||||
qcam->transfer_scale = 2;
|
||||
@ -808,11 +808,11 @@ static int qcam_do_ioctl(struct inode *inode, struct file *file,
|
||||
mutex_lock(&qcam->lock);
|
||||
qc_setscanmode(qcam);
|
||||
mutex_unlock(&qcam->lock);
|
||||
|
||||
|
||||
/* We must update the camera before we grab. We could
|
||||
just have changed the grab size */
|
||||
qcam->status |= QC_PARAM_CHANGE;
|
||||
|
||||
|
||||
/* Ok we figured out what to use from our wide choice */
|
||||
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;
|
||||
int len;
|
||||
parport_claim_or_block(qcam->pdev);
|
||||
|
||||
|
||||
mutex_lock(&qcam->lock);
|
||||
|
||||
|
||||
qc_reset(qcam);
|
||||
|
||||
/* 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);
|
||||
|
||||
len=qc_capture(qcam, buf,count);
|
||||
|
||||
|
||||
mutex_unlock(&qcam->lock);
|
||||
|
||||
|
||||
parport_release(qcam->pdev);
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
static struct file_operations qcam_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = video_exclusive_open,
|
||||
@ -905,11 +905,11 @@ static int init_bwqcam(struct parport *port)
|
||||
qcam=qcam_init(port);
|
||||
if(qcam==NULL)
|
||||
return -ENODEV;
|
||||
|
||||
|
||||
parport_claim_or_block(qcam->pdev);
|
||||
|
||||
qc_reset(qcam);
|
||||
|
||||
|
||||
if(qc_detect(qcam)==0)
|
||||
{
|
||||
parport_release(qcam->pdev);
|
||||
@ -920,9 +920,9 @@ static int init_bwqcam(struct parport *port)
|
||||
qc_calibrate(qcam);
|
||||
|
||||
parport_release(qcam->pdev);
|
||||
|
||||
|
||||
printk(KERN_INFO "Connectix Quickcam on %s\n", qcam->pport->name);
|
||||
|
||||
|
||||
if(video_register_device(&qcam->vdev, VFL_TYPE_GRABBER, video_nr)==-1)
|
||||
{
|
||||
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");
|
||||
maxpoll = 5000;
|
||||
}
|
||||
|
||||
|
||||
if (yieldlines < 1) {
|
||||
printk("Connectix Quickcam yieldlines was less than 1. Using 1.\n");
|
||||
yieldlines = 1;
|
||||
|
@ -16,7 +16,7 @@
|
||||
*
|
||||
* The parport parameter controls which parports will be scanned.
|
||||
* 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
|
||||
* 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;
|
||||
}
|
||||
|
||||
static unsigned int qcam_await_ready1(struct qcam_device *qcam,
|
||||
static unsigned int qcam_await_ready1(struct qcam_device *qcam,
|
||||
int value)
|
||||
{
|
||||
unsigned long oldjiffies = jiffies;
|
||||
@ -98,7 +98,7 @@ static unsigned int qcam_await_ready1(struct qcam_device *qcam,
|
||||
if (qcam_ready1(qcam) == value)
|
||||
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 (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)
|
||||
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 (i = 0; i < 50; i++)
|
||||
{
|
||||
@ -157,12 +157,12 @@ static int qcam_write_data(struct qcam_device *qcam, unsigned int data)
|
||||
unsigned int idata;
|
||||
parport_write_data(qcam->pport, data);
|
||||
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);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -193,12 +193,12 @@ static int qc_detect(struct qcam_device *qcam)
|
||||
no device was found". Fix this one day. */
|
||||
if (qcam->pport->probe_info[0].class == PARPORT_CLASS_MEDIA
|
||||
&& 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")) {
|
||||
printk(KERN_DEBUG "QuickCam: Found by IEEE1284 probe.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
if (probe < 2)
|
||||
return 0;
|
||||
|
||||
@ -206,11 +206,11 @@ static int qc_detect(struct qcam_device *qcam)
|
||||
|
||||
/* look for a heartbeat */
|
||||
ostat = stat = parport_read_status(qcam->pport);
|
||||
for (i=0; i<250; i++)
|
||||
for (i=0; i<250; i++)
|
||||
{
|
||||
mdelay(1);
|
||||
stat = parport_read_status(qcam->pport);
|
||||
if (ostat != stat)
|
||||
if (ostat != stat)
|
||||
{
|
||||
if (++count >= 3) return 1;
|
||||
ostat = stat;
|
||||
@ -226,11 +226,11 @@ static int qc_detect(struct qcam_device *qcam)
|
||||
count = 0;
|
||||
|
||||
ostat = stat = parport_read_status(qcam->pport);
|
||||
for (i=0; i<250; i++)
|
||||
for (i=0; i<250; i++)
|
||||
{
|
||||
mdelay(1);
|
||||
stat = parport_read_status(qcam->pport);
|
||||
if (ostat != stat)
|
||||
if (ostat != stat)
|
||||
{
|
||||
if (++count >= 3) return 1;
|
||||
ostat = stat;
|
||||
@ -247,7 +247,7 @@ static void qc_reset(struct qcam_device *qcam)
|
||||
parport_write_control(qcam->pport, 0x8);
|
||||
mdelay(1);
|
||||
parport_write_control(qcam->pport, 0xc);
|
||||
mdelay(1);
|
||||
mdelay(1);
|
||||
}
|
||||
|
||||
/* Reset the QuickCam and program for brightness, contrast,
|
||||
@ -258,7 +258,7 @@ static void qc_setup(struct qcam_device *q)
|
||||
qc_reset(q);
|
||||
|
||||
/* 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
|
||||
CCD area *before* applying the selected decimation. */
|
||||
@ -272,12 +272,12 @@ static void qc_setup(struct qcam_device *q)
|
||||
/* Set contrast and white balance. */
|
||||
qcam_set(q, 0x19, q->contrast);
|
||||
qcam_set(q, 0x1f, q->whitebal);
|
||||
|
||||
|
||||
/* Set the speed. */
|
||||
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
|
||||
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))
|
||||
return -EIO;
|
||||
|
||||
|
||||
lines = q->height;
|
||||
pixelsperline = q->width;
|
||||
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 qcam_device *qcam=(struct qcam_device *)dev;
|
||||
|
||||
|
||||
switch(cmd)
|
||||
{
|
||||
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)
|
||||
return -EINVAL;
|
||||
|
||||
|
||||
/*
|
||||
* Now load the camera.
|
||||
*/
|
||||
@ -584,7 +584,7 @@ static int qcam_do_ioctl(struct inode *inode, struct file *file,
|
||||
|
||||
mutex_lock(&qcam->lock);
|
||||
parport_claim_or_block(qcam->pdev);
|
||||
qc_setup(qcam);
|
||||
qc_setup(qcam);
|
||||
parport_release(qcam->pdev);
|
||||
mutex_unlock(&qcam->lock);
|
||||
return 0;
|
||||
@ -601,11 +601,11 @@ static int qcam_do_ioctl(struct inode *inode, struct file *file,
|
||||
return -EINVAL;
|
||||
if(vw->width<80||vw->width>320)
|
||||
return -EINVAL;
|
||||
|
||||
|
||||
qcam->width = 80;
|
||||
qcam->height = 60;
|
||||
qcam->mode = QC_DECIMATION_4;
|
||||
|
||||
|
||||
if(vw->width>=160 && vw->height>=120)
|
||||
{
|
||||
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;
|
||||
}
|
||||
#endif
|
||||
/* Ok we figured out what to use from our
|
||||
/* Ok we figured out what to use from our
|
||||
wide choice */
|
||||
mutex_lock(&qcam->lock);
|
||||
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);
|
||||
parport_claim_or_block(qcam->pdev);
|
||||
/* Probably should have a semaphore against multiple users */
|
||||
len = qc_capture(qcam, buf,count);
|
||||
len = qc_capture(qcam, buf,count);
|
||||
parport_release(qcam->pdev);
|
||||
mutex_unlock(&qcam->lock);
|
||||
return len;
|
||||
@ -707,7 +707,7 @@ static struct video_device qcam_template=
|
||||
static struct qcam_device *qcam_init(struct parport *port)
|
||||
{
|
||||
struct qcam_device *q;
|
||||
|
||||
|
||||
q = kmalloc(sizeof(struct qcam_device), GFP_KERNEL);
|
||||
if(q==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;
|
||||
|
||||
if (q->pdev == NULL)
|
||||
if (q->pdev == NULL)
|
||||
{
|
||||
printk(KERN_ERR "c-qcam: couldn't register for %s.\n",
|
||||
port->name);
|
||||
kfree(q);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
memcpy(&q->vdev, &qcam_template, sizeof(qcam_template));
|
||||
|
||||
mutex_init(&q->lock);
|
||||
@ -766,11 +766,11 @@ static int init_cqcam(struct parport *port)
|
||||
qcam = qcam_init(port);
|
||||
if (qcam==NULL)
|
||||
return -ENODEV;
|
||||
|
||||
|
||||
parport_claim_or_block(qcam->pdev);
|
||||
|
||||
qc_reset(qcam);
|
||||
|
||||
|
||||
if (probe && qc_detect(qcam)==0)
|
||||
{
|
||||
parport_release(qcam->pdev);
|
||||
@ -782,7 +782,7 @@ static int init_cqcam(struct parport *port)
|
||||
qc_setup(qcam);
|
||||
|
||||
parport_release(qcam->pdev);
|
||||
|
||||
|
||||
if (video_register_device(&qcam->vdev, VFL_TYPE_GRABBER, video_nr)==-1)
|
||||
{
|
||||
printk(KERN_ERR "Unable to register Colour QuickCam on %s\n",
|
||||
@ -792,9 +792,9 @@ static int init_cqcam(struct parport *port)
|
||||
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);
|
||||
|
||||
|
||||
qcams[num_cams++] = qcam;
|
||||
|
||||
return 0;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -52,10 +52,10 @@
|
||||
struct cpia_camera_ops
|
||||
{
|
||||
/* 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);
|
||||
|
||||
|
||||
/* Registers callback function cb to be called with cbdata
|
||||
* when an image is ready. If cb is NULL, only single image grabs
|
||||
* should be used. cb should immediately call streamRead to read
|
||||
@ -63,8 +63,8 @@ struct cpia_camera_ops
|
||||
* otherwise 0.
|
||||
*/
|
||||
int (*registerCallback)(void *privdata, void (*cb)(void *cbdata),
|
||||
void *cbdata);
|
||||
|
||||
void *cbdata);
|
||||
|
||||
/* transferCmd sends commands to the camera. command MUST point to
|
||||
* 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
|
||||
@ -77,30 +77,30 @@ struct cpia_camera_ops
|
||||
* Returns negative value on error, otherwise 0.
|
||||
*/
|
||||
int (*streamStart)(void *privdata);
|
||||
|
||||
|
||||
/* streamStop terminates stream capture mode.
|
||||
* Returns negative value on error, otherwise 0.
|
||||
*/
|
||||
int (*streamStop)(void *privdata);
|
||||
|
||||
|
||||
/* streamRead reads a frame from the camera. buffer points to a
|
||||
* buffer large enough to hold a complete frame in kernel space.
|
||||
* noblock indicates if this should be a non blocking read.
|
||||
* buffer large enough to hold a complete frame in kernel space.
|
||||
* noblock indicates if this should be a non blocking read.
|
||||
* Returns the number of bytes read, or negative value on error.
|
||||
*/
|
||||
*/
|
||||
int (*streamRead)(void *privdata, u8 *buffer, int noblock);
|
||||
|
||||
|
||||
/* close disables the device until open() is called again.
|
||||
* Returns negative value on error, otherwise 0.
|
||||
*/
|
||||
int (*close)(void *privdata);
|
||||
|
||||
|
||||
/* If wait_for_stream_ready is non-zero, wait until the streamState
|
||||
* is STREAM_READY before calling streamRead.
|
||||
*/
|
||||
int wait_for_stream_ready;
|
||||
|
||||
/*
|
||||
/*
|
||||
* Used to maintain lowlevel module usage counts
|
||||
*/
|
||||
struct module *owner;
|
||||
@ -215,14 +215,14 @@ struct cam_params {
|
||||
u8 videoSize; /* CIF/QCIF */
|
||||
u8 subSample;
|
||||
u8 yuvOrder;
|
||||
} format;
|
||||
struct { /* Intel QX3 specific data */
|
||||
u8 qx3_detected; /* a QX3 is present */
|
||||
u8 toplight; /* top light lit , R/W */
|
||||
u8 bottomlight; /* bottom light lit, R/W */
|
||||
u8 button; /* snapshot button pressed (R/O) */
|
||||
u8 cradled; /* microscope is in cradle (R/O) */
|
||||
} qx3;
|
||||
} format;
|
||||
struct { /* Intel QX3 specific data */
|
||||
u8 qx3_detected; /* a QX3 is present */
|
||||
u8 toplight; /* top light lit , R/W */
|
||||
u8 bottomlight; /* bottom light lit, R/W */
|
||||
u8 button; /* snapshot button pressed (R/O) */
|
||||
u8 cradled; /* microscope is in cradle (R/O) */
|
||||
} qx3;
|
||||
struct {
|
||||
u8 colStart; /* skip first 8*colStart pixels */
|
||||
u8 colEnd; /* finish at 8*colEnd pixels */
|
||||
@ -247,13 +247,13 @@ enum v4l_camstates {
|
||||
struct cam_data {
|
||||
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 */
|
||||
void *lowlevel_data; /* private data for lowlevel driver */
|
||||
u8 *raw_image; /* buffer for raw image data */
|
||||
struct cpia_frame decompressed_frame;
|
||||
/* buffer to hold decompressed frame */
|
||||
int image_size; /* sizeof last decompressed image */
|
||||
/* buffer to hold decompressed frame */
|
||||
int image_size; /* sizeof last decompressed image */
|
||||
int open_count; /* # of process that have camera open */
|
||||
|
||||
/* camera status */
|
||||
@ -265,7 +265,7 @@ struct cam_data {
|
||||
struct mutex param_lock; /* params lock for this camera */
|
||||
struct cam_params params; /* camera settings */
|
||||
struct proc_dir_entry *proc_entry; /* /proc/cpia/videoX */
|
||||
|
||||
|
||||
/* v4l */
|
||||
int video_size; /* VIDEO_SIZE_ */
|
||||
volatile enum v4l_camstates camstate; /* v4l layer status */
|
||||
@ -277,7 +277,7 @@ struct cam_data {
|
||||
/* mmap interface */
|
||||
int curframe; /* the current frame to grab into */
|
||||
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 */
|
||||
|
||||
int first_frame;
|
||||
@ -424,7 +424,7 @@ void cpia_unregister_camera(struct cam_data *cam);
|
||||
#define DEB_BYTE(p)\
|
||||
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)&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__ */
|
||||
|
||||
|
@ -381,7 +381,7 @@ struct cpia2_fh {
|
||||
|
||||
struct camera_data {
|
||||
/* locks */
|
||||
struct semaphore busy_lock; /* guard against SMP multithreading */
|
||||
struct mutex busy_lock; /* guard against SMP multithreading */
|
||||
struct v4l2_prio_state prio;
|
||||
|
||||
/* camera status */
|
||||
|
@ -2238,7 +2238,7 @@ struct camera_data *cpia2_init_camera_struct(void)
|
||||
memset(cam, 0, sizeof(struct camera_data));
|
||||
|
||||
cam->present = 1;
|
||||
init_MUTEX(&cam->busy_lock);
|
||||
mutex_init(&cam->busy_lock);
|
||||
init_waitqueue_head(&cam->wq_stream);
|
||||
|
||||
return cam;
|
||||
@ -2371,12 +2371,12 @@ long cpia2_read(struct camera_data *cam,
|
||||
}
|
||||
|
||||
/* make this _really_ smp and multithread-safe */
|
||||
if (down_interruptible(&cam->busy_lock))
|
||||
if (mutex_lock_interruptible(&cam->busy_lock))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
if (!cam->present) {
|
||||
LOG("%s: camera removed\n",__FUNCTION__);
|
||||
up(&cam->busy_lock);
|
||||
mutex_unlock(&cam->busy_lock);
|
||||
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 */
|
||||
frame = cam->curbuff;
|
||||
if (noblock && frame->status != FRAME_READY) {
|
||||
up(&cam->busy_lock);
|
||||
mutex_unlock(&cam->busy_lock);
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
if(frame->status != FRAME_READY) {
|
||||
up(&cam->busy_lock);
|
||||
mutex_unlock(&cam->busy_lock);
|
||||
wait_event_interruptible(cam->wq_stream,
|
||||
!cam->present ||
|
||||
(frame = cam->curbuff)->status == FRAME_READY);
|
||||
if (signal_pending(current))
|
||||
return -ERESTARTSYS;
|
||||
/* make this _really_ smp and multithread-safe */
|
||||
if (down_interruptible(&cam->busy_lock)) {
|
||||
if (mutex_lock_interruptible(&cam->busy_lock)) {
|
||||
return -ERESTARTSYS;
|
||||
}
|
||||
if(!cam->present) {
|
||||
up(&cam->busy_lock);
|
||||
mutex_unlock(&cam->busy_lock);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* copy data to user space */
|
||||
if (frame->length > count) {
|
||||
up(&cam->busy_lock);
|
||||
mutex_unlock(&cam->busy_lock);
|
||||
return -EFAULT;
|
||||
}
|
||||
if (copy_to_user(buf, frame->data, frame->length)) {
|
||||
up(&cam->busy_lock);
|
||||
mutex_unlock(&cam->busy_lock);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
@ -2424,7 +2424,7 @@ long cpia2_read(struct camera_data *cam,
|
||||
|
||||
frame->status = FRAME_EMPTY;
|
||||
|
||||
up(&cam->busy_lock);
|
||||
mutex_unlock(&cam->busy_lock);
|
||||
return count;
|
||||
}
|
||||
|
||||
@ -2443,10 +2443,10 @@ unsigned int cpia2_poll(struct camera_data *cam, struct file *filp,
|
||||
return POLLERR;
|
||||
}
|
||||
|
||||
down(&cam->busy_lock);
|
||||
mutex_lock(&cam->busy_lock);
|
||||
|
||||
if(!cam->present) {
|
||||
up(&cam->busy_lock);
|
||||
mutex_unlock(&cam->busy_lock);
|
||||
return POLLHUP;
|
||||
}
|
||||
|
||||
@ -2456,16 +2456,16 @@ unsigned int cpia2_poll(struct camera_data *cam, struct file *filp,
|
||||
cam->params.camera_state.stream_mode);
|
||||
}
|
||||
|
||||
up(&cam->busy_lock);
|
||||
mutex_unlock(&cam->busy_lock);
|
||||
poll_wait(filp, &cam->wq_stream, wait);
|
||||
down(&cam->busy_lock);
|
||||
mutex_lock(&cam->busy_lock);
|
||||
|
||||
if(!cam->present)
|
||||
status = POLLHUP;
|
||||
else if(cam->curbuff->status == FRAME_READY)
|
||||
status = POLLIN | POLLRDNORM;
|
||||
|
||||
up(&cam->busy_lock);
|
||||
mutex_unlock(&cam->busy_lock);
|
||||
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);
|
||||
|
||||
/* make this _really_ smp-safe */
|
||||
if (down_interruptible(&cam->busy_lock))
|
||||
if (mutex_lock_interruptible(&cam->busy_lock))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
if (!cam->present) {
|
||||
up(&cam->busy_lock);
|
||||
mutex_unlock(&cam->busy_lock);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (size > cam->frame_size*cam->num_frames ||
|
||||
(start_offset % cam->frame_size) != 0 ||
|
||||
(start_offset+size > cam->frame_size*cam->num_frames)) {
|
||||
up(&cam->busy_lock);
|
||||
mutex_unlock(&cam->busy_lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -2507,7 +2507,7 @@ int cpia2_remap_buffer(struct camera_data *cam, struct vm_area_struct *vma)
|
||||
while (size > 0) {
|
||||
page = kvirt_to_pa(pos);
|
||||
if (remap_pfn_range(vma, start, page >> PAGE_SHIFT, PAGE_SIZE, PAGE_SHARED)) {
|
||||
up(&cam->busy_lock);
|
||||
mutex_unlock(&cam->busy_lock);
|
||||
return -EAGAIN;
|
||||
}
|
||||
start += PAGE_SIZE;
|
||||
@ -2519,7 +2519,7 @@ int cpia2_remap_buffer(struct camera_data *cam, struct vm_area_struct *vma)
|
||||
}
|
||||
|
||||
cam->mmapped = true;
|
||||
up(&cam->busy_lock);
|
||||
mutex_unlock(&cam->busy_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -255,7 +255,7 @@ static int cpia2_open(struct inode *inode, struct file *file)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if(down_interruptible(&cam->busy_lock))
|
||||
if(mutex_lock_interruptible(&cam->busy_lock))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
if(!cam->present) {
|
||||
@ -299,7 +299,7 @@ skip_init:
|
||||
cpia2_dbg_dump_registers(cam);
|
||||
|
||||
err_return:
|
||||
up(&cam->busy_lock);
|
||||
mutex_unlock(&cam->busy_lock);
|
||||
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 cpia2_fh *fh = file->private_data;
|
||||
|
||||
down(&cam->busy_lock);
|
||||
mutex_lock(&cam->busy_lock);
|
||||
|
||||
if (cam->present &&
|
||||
(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;
|
||||
}
|
||||
@ -523,11 +523,11 @@ static int sync(struct camera_data *cam, int frame_nr)
|
||||
return 0;
|
||||
}
|
||||
|
||||
up(&cam->busy_lock);
|
||||
mutex_unlock(&cam->busy_lock);
|
||||
wait_event_interruptible(cam->wq_stream,
|
||||
!cam->streaming ||
|
||||
frame->status == FRAME_READY);
|
||||
down(&cam->busy_lock);
|
||||
mutex_lock(&cam->busy_lock);
|
||||
if (signal_pending(current))
|
||||
return -ERESTARTSYS;
|
||||
if(!cam->present)
|
||||
@ -1544,11 +1544,11 @@ static int ioctl_dqbuf(void *arg,struct camera_data *cam, struct file *file)
|
||||
if(frame < 0) {
|
||||
/* Wait for a frame to become available */
|
||||
struct framebuf *cb=cam->curbuff;
|
||||
up(&cam->busy_lock);
|
||||
mutex_unlock(&cam->busy_lock);
|
||||
wait_event_interruptible(cam->wq_stream,
|
||||
!cam->present ||
|
||||
(cb=cam->curbuff)->status == FRAME_READY);
|
||||
down(&cam->busy_lock);
|
||||
mutex_lock(&cam->busy_lock);
|
||||
if (signal_pending(current))
|
||||
return -ERESTARTSYS;
|
||||
if(!cam->present)
|
||||
@ -1591,11 +1591,11 @@ static int cpia2_do_ioctl(struct inode *inode, struct file *file,
|
||||
return -ENOTTY;
|
||||
|
||||
/* make this _really_ smp-safe */
|
||||
if (down_interruptible(&cam->busy_lock))
|
||||
if (mutex_lock_interruptible(&cam->busy_lock))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
if (!cam->present) {
|
||||
up(&cam->busy_lock);
|
||||
mutex_unlock(&cam->busy_lock);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
@ -1608,7 +1608,7 @@ static int cpia2_do_ioctl(struct inode *inode, struct file *file,
|
||||
struct cpia2_fh *fh = file->private_data;
|
||||
retval = v4l2_prio_check(&cam->prio, &fh->prio);
|
||||
if(retval) {
|
||||
up(&cam->busy_lock);
|
||||
mutex_unlock(&cam->busy_lock);
|
||||
return retval;
|
||||
}
|
||||
break;
|
||||
@ -1618,7 +1618,7 @@ static int cpia2_do_ioctl(struct inode *inode, struct file *file,
|
||||
{
|
||||
struct cpia2_fh *fh = file->private_data;
|
||||
if(fh->prio != V4L2_PRIORITY_RECORD) {
|
||||
up(&cam->busy_lock);
|
||||
mutex_unlock(&cam->busy_lock);
|
||||
return -EBUSY;
|
||||
}
|
||||
break;
|
||||
@ -1847,7 +1847,7 @@ static int cpia2_do_ioctl(struct inode *inode, struct file *file,
|
||||
break;
|
||||
}
|
||||
|
||||
up(&cam->busy_lock);
|
||||
mutex_unlock(&cam->busy_lock);
|
||||
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
|
||||
***/
|
||||
static struct file_operations fops_template = {
|
||||
.owner= THIS_MODULE,
|
||||
.open= cpia2_open,
|
||||
.release= cpia2_close,
|
||||
.read= cpia2_v4l_read,
|
||||
.poll= cpia2_v4l_poll,
|
||||
.ioctl= cpia2_ioctl,
|
||||
.llseek= no_llseek,
|
||||
.mmap= cpia2_mmap,
|
||||
.owner = THIS_MODULE,
|
||||
.open = cpia2_open,
|
||||
.release = cpia2_close,
|
||||
.read = cpia2_v4l_read,
|
||||
.poll = cpia2_v4l_poll,
|
||||
.ioctl = cpia2_ioctl,
|
||||
.llseek = no_llseek,
|
||||
.compat_ioctl = v4l_compat_ioctl32,
|
||||
.mmap = cpia2_mmap,
|
||||
};
|
||||
|
||||
static struct video_device cpia2_template = {
|
||||
|
@ -23,7 +23,7 @@
|
||||
*/
|
||||
|
||||
/* define _CPIA_DEBUG_ for verbose debug output (see cpia.h) */
|
||||
/* #define _CPIA_DEBUG_ 1 */
|
||||
/* #define _CPIA_DEBUG_ 1 */
|
||||
|
||||
#include <linux/config.h>
|
||||
|
||||
@ -45,7 +45,7 @@
|
||||
|
||||
static int cpia_pp_open(void *privdata);
|
||||
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_streamStart(void *privdata);
|
||||
static int cpia_pp_streamStop(void *privdata);
|
||||
@ -93,7 +93,7 @@ struct pp_cam_entry {
|
||||
int stream_irq;
|
||||
};
|
||||
|
||||
static struct cpia_camera_ops cpia_pp_ops =
|
||||
static struct cpia_camera_ops cpia_pp_ops =
|
||||
{
|
||||
cpia_pp_open,
|
||||
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
|
||||
* Link Flag during negotiation */
|
||||
* Link Flag during negotiation */
|
||||
#define UPLOAD_FLAG 0x08
|
||||
#define NIBBLE_TRANSFER 0x01
|
||||
#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). */
|
||||
/* The standard kernel parport_ieee1284_read_nibble() fails with the CPiA... */
|
||||
|
||||
static size_t cpia_read_nibble (struct parport *port,
|
||||
void *buffer, size_t len,
|
||||
static size_t cpia_read_nibble (struct parport *port,
|
||||
void *buffer, size_t len,
|
||||
int flags)
|
||||
{
|
||||
/* adapted verbatim, with one change, from
|
||||
/* adapted verbatim, with one change, from
|
||||
parport_ieee1284_read_nibble() in drivers/parport/ieee1284-ops.c */
|
||||
|
||||
unsigned char *buf = buffer;
|
||||
int i;
|
||||
unsigned char byte = 0;
|
||||
|
||||
|
||||
len *= 2; /* in nibbles */
|
||||
for (i=0; i < len; i++) {
|
||||
unsigned char nibble;
|
||||
@ -158,12 +158,12 @@ static size_t cpia_read_nibble (struct parport *port,
|
||||
* after every second nibble to signal that more
|
||||
* data is available. (the total number of Bytes that
|
||||
* 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(),
|
||||
* 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.
|
||||
*/
|
||||
|
||||
@ -216,7 +216,7 @@ static size_t cpia_read_nibble (struct parport *port,
|
||||
/* Second nibble */
|
||||
byte |= nibble << 4;
|
||||
*buf++ = byte;
|
||||
} else
|
||||
} else
|
||||
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)
|
||||
* (See CPiA Data sheet p. 31)
|
||||
*
|
||||
* "Nibble Stream" mode used by CPiA for uploads to non-ECP ports is a
|
||||
* nonstandard variant of nibble mode which allows the same (mediocre)
|
||||
* data flow of 8 bits per cycle as software-enabled ECP by TRISTATE-capable
|
||||
* (See CPiA Data sheet p. 31)
|
||||
*
|
||||
* "Nibble Stream" mode used by CPiA for uploads to non-ECP ports is a
|
||||
* nonstandard variant of nibble mode which allows the same (mediocre)
|
||||
* data flow of 8 bits per cycle as software-enabled ECP by TRISTATE-capable
|
||||
* parallel ports, but works also for non-TRISTATE-capable ports.
|
||||
* (Standard nibble mode only send 4 bits per cycle)
|
||||
*
|
||||
*/
|
||||
|
||||
static size_t cpia_read_nibble_stream(struct parport *port,
|
||||
void *buffer, size_t len,
|
||||
static size_t cpia_read_nibble_stream(struct parport *port,
|
||||
void *buffer, size_t len,
|
||||
int flags)
|
||||
{
|
||||
int i;
|
||||
@ -260,7 +260,7 @@ static size_t cpia_read_nibble_stream(struct parport *port,
|
||||
unsigned char nibble[2], byte = 0;
|
||||
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 )
|
||||
break;
|
||||
|
||||
@ -268,7 +268,7 @@ static size_t cpia_read_nibble_stream(struct parport *port,
|
||||
parport_frob_control (port,
|
||||
PARPORT_CONTROL_AUTOFD,
|
||||
PARPORT_CONTROL_AUTOFD);
|
||||
|
||||
|
||||
/* Event 9: nAck goes low. */
|
||||
port->ieee1284.phase = IEEE1284_PH_REV_DATA;
|
||||
if (parport_wait_peripheral (port,
|
||||
@ -282,7 +282,7 @@ static size_t cpia_read_nibble_stream(struct parport *port,
|
||||
|
||||
/* Read lower nibble */
|
||||
nibble[0] = parport_read_status (port) >>3;
|
||||
|
||||
|
||||
/* Event 10: Set nAutoFd high. */
|
||||
parport_frob_control (port, PARPORT_CONTROL_AUTOFD, 0);
|
||||
|
||||
@ -295,10 +295,10 @@ static size_t cpia_read_nibble_stream(struct parport *port,
|
||||
port->name);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
/* Read upper nibble */
|
||||
nibble[1] = parport_read_status (port) >>3;
|
||||
|
||||
|
||||
/* reassemble the byte */
|
||||
for (j = 0; j < 2 ; j++ ) {
|
||||
nibble[j] &= ~8;
|
||||
@ -335,8 +335,8 @@ static void EndTransferMode(struct pp_cam_entry *cam)
|
||||
static int ForwardSetup(struct pp_cam_entry *cam)
|
||||
{
|
||||
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
|
||||
*/
|
||||
|
||||
@ -375,9 +375,9 @@ static int ReverseSetup(struct pp_cam_entry *cam, int extensibility)
|
||||
upload_mode = mode;
|
||||
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. */
|
||||
|
||||
|
||||
for(retry = 0; retry < 4; ++retry) {
|
||||
if(!parport_negotiate(cam->port, mode)) {
|
||||
break;
|
||||
@ -439,10 +439,10 @@ static int ReadPacket(struct pp_cam_entry *cam, u8 *packet, size_t size)
|
||||
|
||||
/* support for CPiA variant nibble reads */
|
||||
if(cam->port->ieee1284.mode == IEEE1284_MODE_NIBBLE) {
|
||||
if(cpia_read_nibble(cam->port, packet, size, 0) != size)
|
||||
retval = -EIO;
|
||||
if(cpia_read_nibble(cam->port, packet, size, 0) != size)
|
||||
retval = -EIO;
|
||||
} else {
|
||||
if(parport_read(cam->port, packet, size) != size)
|
||||
if(parport_read(cam->port, packet, size) != size)
|
||||
retval = -EIO;
|
||||
}
|
||||
EndTransferMode(cam);
|
||||
@ -542,18 +542,18 @@ static int cpia_pp_streamRead(void *privdata, u8 *buffer, int noblock)
|
||||
block_size = PARPORT_CHUNK_SIZE;
|
||||
while( !cam->image_complete ) {
|
||||
cond_resched();
|
||||
|
||||
|
||||
new_bytes = cpia_pp_read(cam->port, buffer, block_size );
|
||||
if( new_bytes <= 0 ) {
|
||||
break;
|
||||
}
|
||||
i=-1;
|
||||
while(++i<new_bytes && endseen<4) {
|
||||
if(*buffer==EOI) {
|
||||
endseen++;
|
||||
} else {
|
||||
endseen=0;
|
||||
}
|
||||
if(*buffer==EOI) {
|
||||
endseen++;
|
||||
} else {
|
||||
endseen=0;
|
||||
}
|
||||
buffer++;
|
||||
}
|
||||
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) {
|
||||
DBG("Error reading command result\n");
|
||||
return err;
|
||||
return err;
|
||||
}
|
||||
memcpy(data, buffer, databytes);
|
||||
} 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)
|
||||
{
|
||||
struct pp_cam_entry *cam = (struct pp_cam_entry *)privdata;
|
||||
|
||||
|
||||
if (cam == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
|
||||
if(cam->open_count == 0) {
|
||||
if (parport_claim(cam->pdev)) {
|
||||
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);
|
||||
udelay(50);
|
||||
parport_write_control(cam->port,
|
||||
PARPORT_CONTROL_SELECT
|
||||
| PARPORT_CONTROL_INIT);
|
||||
PARPORT_CONTROL_SELECT
|
||||
| PARPORT_CONTROL_INIT);
|
||||
}
|
||||
|
||||
|
||||
++cam->open_count;
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -663,7 +663,7 @@ static int cpia_pp_registerCallback(void *privdata, void (*cb)(void *cbdata), vo
|
||||
{
|
||||
struct pp_cam_entry *cam = privdata;
|
||||
int retval = 0;
|
||||
|
||||
|
||||
if(cam->port->irq != PARPORT_IRQ_NONE) {
|
||||
INIT_WORK(&cam->cb_task, cb, cbdata);
|
||||
} else {
|
||||
@ -707,9 +707,9 @@ static int cpia_pp_register(struct parport *port)
|
||||
LOG("failed to allocate camera structure\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
|
||||
pdev = parport_register_device(port, "cpia_pp", NULL, NULL,
|
||||
NULL, 0, cam);
|
||||
NULL, 0, cam);
|
||||
|
||||
if (!pdev) {
|
||||
LOG("failed to parport_register_device\n");
|
||||
@ -753,19 +753,19 @@ static void cpia_pp_detach (struct parport *port)
|
||||
}
|
||||
cpia = NULL;
|
||||
}
|
||||
spin_unlock( &cam_list_lock_pp );
|
||||
spin_unlock( &cam_list_lock_pp );
|
||||
|
||||
if (!cpia) {
|
||||
DBG("cpia_pp_detach failed to find cam_data in cam_list\n");
|
||||
return;
|
||||
}
|
||||
|
||||
cam = (struct pp_cam_entry *) cpia->lowlevel_data;
|
||||
|
||||
cam = (struct pp_cam_entry *) cpia->lowlevel_data;
|
||||
cpia_unregister_camera(cpia);
|
||||
if(cam->open_count > 0)
|
||||
if(cam->open_count > 0)
|
||||
cpia_pp_close(cam);
|
||||
parport_unregister_device(cam->pdev);
|
||||
cpia->lowlevel_data = NULL;
|
||||
cpia->lowlevel_data = NULL;
|
||||
kfree(cam);
|
||||
}
|
||||
|
||||
@ -805,14 +805,14 @@ static struct parport_driver cpia_pp_driver = {
|
||||
|
||||
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);
|
||||
|
||||
if(parport_nr[0] == PPCPIA_PARPORT_OFF) {
|
||||
printk(" disabled\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
spin_lock_init( &cam_list_lock_pp );
|
||||
|
||||
if (parport_register_driver (&cpia_pp_driver)) {
|
||||
|
@ -22,7 +22,7 @@
|
||||
*/
|
||||
|
||||
/* define _CPIA_DEBUG_ for verbose debug output (see cpia.h) */
|
||||
/* #define _CPIA_DEBUG_ 1 */
|
||||
/* #define _CPIA_DEBUG_ 1 */
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
@ -85,7 +85,7 @@ struct usb_cpia {
|
||||
|
||||
static int cpia_usb_open(void *privdata);
|
||||
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_streamStart(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->length = 0;
|
||||
}
|
||||
|
||||
|
||||
for (i = 0; i < urb->number_of_packets; i++) {
|
||||
int n = urb->iso_frame_desc[i].actual_length;
|
||||
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);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (n) {
|
||||
if ((ucpia->workbuff->length > 0) ||
|
||||
if ((ucpia->workbuff->length > 0) ||
|
||||
(0x19 == cdata[0] && 0x68 == cdata[1])) {
|
||||
memcpy(ucpia->workbuff->data + ucpia->workbuff->length, cdata, 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->status = FRAME_EMPTY;
|
||||
ucpia->workbuff->length = 0;
|
||||
|
||||
|
||||
if (waitqueue_active(&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 urb *urb;
|
||||
int ret, retval = 0, fx, err;
|
||||
|
||||
|
||||
if (!ucpia)
|
||||
return -EINVAL;
|
||||
|
||||
@ -191,7 +191,7 @@ static int cpia_usb_open(void *privdata)
|
||||
retval = -EINVAL;
|
||||
goto error_0;
|
||||
}
|
||||
|
||||
|
||||
ret = usb_set_interface(ucpia->dev, ucpia->iface, 3);
|
||||
if (ret < 0) {
|
||||
printk(KERN_ERR "cpia_usb_open: usb_set_interface error (ret = %d)\n", ret);
|
||||
@ -286,7 +286,7 @@ error_1:
|
||||
error_0:
|
||||
kfree (ucpia->sbuf[0].data);
|
||||
ucpia->sbuf[0].data = NULL;
|
||||
|
||||
|
||||
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),
|
||||
packet[1] + (packet[0] << 8),
|
||||
USB_TYPE_VENDOR | USB_RECIP_DEVICE,
|
||||
packet[2] + (packet[3] << 8),
|
||||
packet[2] + (packet[3] << 8),
|
||||
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),
|
||||
packet[1] + (packet[0] << 8),
|
||||
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);
|
||||
}
|
||||
|
||||
@ -393,7 +393,7 @@ static int cpia_usb_streamRead(void *privdata, u8 *frame, int noblock)
|
||||
|
||||
if (!ucpia || !ucpia->present)
|
||||
return -1;
|
||||
|
||||
|
||||
if (ucpia->curbuff->status != FRAME_READY)
|
||||
interruptible_sleep_on(&ucpia->wq_stream);
|
||||
else
|
||||
@ -403,7 +403,7 @@ static int cpia_usb_streamRead(void *privdata, u8 *frame, int noblock)
|
||||
|
||||
if (!mybuff)
|
||||
return -1;
|
||||
|
||||
|
||||
if (mybuff->status != FRAME_READY || mybuff->length < 4) {
|
||||
DBG("Something went wrong!\n");
|
||||
return -1;
|
||||
@ -411,7 +411,7 @@ static int cpia_usb_streamRead(void *privdata, u8 *frame, int noblock)
|
||||
|
||||
memcpy(frame, mybuff->data, mybuff->length);
|
||||
mybuff->status = FRAME_EMPTY;
|
||||
|
||||
|
||||
/* DBG("read done, %d bytes, Header: %x/%x, Footer: %x%x%x%x\n", */
|
||||
/* mybuff->length, frame[0], frame[1], */
|
||||
/* 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);
|
||||
ucpia->sbuf[1].data = NULL;
|
||||
|
||||
|
||||
if (ucpia->sbuf[0].urb) {
|
||||
usb_kill_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 cam_data *cam;
|
||||
int ret;
|
||||
|
||||
|
||||
/* A multi-config CPiA camera? */
|
||||
if (udev->descriptor.bNumConfigurations != 1)
|
||||
return -ENODEV;
|
||||
@ -539,7 +539,7 @@ static int cpia_probe(struct usb_interface *intf,
|
||||
|
||||
/* Before register_camera, important */
|
||||
ucpia->present = 1;
|
||||
|
||||
|
||||
cam = cpia_register_camera(&cpia_usb_ops, ucpia);
|
||||
if (!cam) {
|
||||
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 usb_cpia *ucpia;
|
||||
struct usb_device *udev;
|
||||
|
||||
|
||||
usb_set_intfdata(intf, NULL);
|
||||
if (!cam)
|
||||
return;
|
||||
@ -600,7 +600,7 @@ static void cpia_disconnect(struct usb_interface *intf)
|
||||
spin_lock( &cam_list_lock_usb );
|
||||
list_del(&cam->cam_data_list);
|
||||
spin_unlock( &cam_list_lock_usb );
|
||||
|
||||
|
||||
ucpia->present = 0;
|
||||
|
||||
cpia_unregister_camera(cam);
|
||||
@ -631,7 +631,7 @@ static void cpia_disconnect(struct usb_interface *intf)
|
||||
|
||||
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);
|
||||
|
||||
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,
|
||||
void *arg)
|
||||
{
|
||||
struct v4l2_audio *input = arg;
|
||||
struct v4l2_routing *route = arg;
|
||||
struct v4l2_control *ctrl = arg;
|
||||
|
||||
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
|
||||
placed in two modes, the first mode bypasses the PGA (gain),
|
||||
the second goes through the PGA. Hence there are three
|
||||
possible inputs to choose from. */
|
||||
if (input->index > 2) {
|
||||
v4l_err(client, "Invalid input %d.\n", input->index);
|
||||
if (route->input > 2) {
|
||||
v4l_err(client, "Invalid input %d.\n", route->input);
|
||||
return -EINVAL;
|
||||
}
|
||||
cs53l32a_write(client, 0x01, 0x01 + (input->index << 4));
|
||||
break;
|
||||
|
||||
case VIDIOC_G_AUDIO:
|
||||
memset(input, 0, sizeof(*input));
|
||||
input->index = (cs53l32a_read(client, 0x01) >> 4) & 3;
|
||||
cs53l32a_write(client, 0x01, 0x01 + (route->input << 4));
|
||||
break;
|
||||
|
||||
case VIDIOC_G_CTRL:
|
||||
|
@ -20,7 +20,7 @@
|
||||
#define __CS8420_H__
|
||||
|
||||
/* Initialization Sequence */
|
||||
|
||||
|
||||
static __u8 init8420[] = {
|
||||
1, 0x01, 2, 0x02, 3, 0x00, 4, 0x46,
|
||||
5, 0x24, 6, 0x84, 18, 0x18, 19, 0x13,
|
||||
|
@ -18,7 +18,6 @@
|
||||
|
||||
#include <linux/videodev2.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <media/audiochip.h>
|
||||
#include <media/v4l2-common.h>
|
||||
|
||||
#include "cx25840.h"
|
||||
|
@ -31,7 +31,6 @@
|
||||
#include <linux/slab.h>
|
||||
#include <linux/videodev2.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <media/audiochip.h>
|
||||
#include <media/v4l2-common.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, 0x402, 0x00);
|
||||
/* 8. */
|
||||
cx25840_write(client, 0x401, 0x18);
|
||||
cx25840_write(client, 0x4a2, 0x10);
|
||||
cx25840_write(client, 0x402, 0x04);
|
||||
cx25840_and_or(client, 0x401, ~0x18, 0);
|
||||
cx25840_and_or(client, 0x4a2, ~0x10, 0x10);
|
||||
/* steps 8c and 8d are done in change_input() */
|
||||
/* 10. */
|
||||
cx25840_write(client, 0x8d3, 0x1f);
|
||||
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);
|
||||
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
|
||||
instead of V4L2_STD_PAL. Someone needs to test this. */
|
||||
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_vbi_setup(client);
|
||||
return 0;
|
||||
@ -359,7 +378,14 @@ v4l2_std_id cx25840_get_v4lstd(struct i2c_client * client)
|
||||
}
|
||||
|
||||
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 0x3: return V4L2_STD_NTSC_443;
|
||||
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);
|
||||
}
|
||||
|
||||
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:
|
||||
input_change(client);
|
||||
break;
|
||||
@ -794,13 +810,14 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd,
|
||||
bilingual -> lang1 */
|
||||
cx25840_and_or(client, 0x809, ~0xf, 0x00);
|
||||
break;
|
||||
case V4L2_TUNER_MODE_STEREO:
|
||||
case V4L2_TUNER_MODE_LANG1:
|
||||
/* mono -> mono
|
||||
stereo -> stereo
|
||||
bilingual -> lang1 */
|
||||
cx25840_and_or(client, 0x809, ~0xf, 0x04);
|
||||
break;
|
||||
case V4L2_TUNER_MODE_STEREO:
|
||||
case V4L2_TUNER_MODE_LANG1_LANG2:
|
||||
/* mono -> mono
|
||||
stereo -> stereo
|
||||
bilingual -> lang1/lang2 */
|
||||
@ -808,7 +825,7 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd,
|
||||
break;
|
||||
case V4L2_TUNER_MODE_LANG2:
|
||||
/* mono -> mono
|
||||
stereo ->stereo
|
||||
stereo -> stereo
|
||||
bilingual -> lang2 */
|
||||
cx25840_and_or(client, 0x809, ~0xf, 0x01);
|
||||
break;
|
||||
|
@ -16,12 +16,13 @@ config VIDEO_CX88
|
||||
module will be called cx8800
|
||||
|
||||
config VIDEO_CX88_ALSA
|
||||
tristate "ALSA DMA audio support"
|
||||
tristate "Conexant 2388x DMA audio support"
|
||||
depends on VIDEO_CX88 && SND && EXPERIMENTAL
|
||||
select SND_PCM
|
||||
---help---
|
||||
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.
|
||||
To check if your board supports, use lspci -n.
|
||||
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);
|
||||
|
||||
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);
|
||||
btcx_riscmem_free(chip->pci,&chip->buf->risc);
|
||||
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,
|
||||
(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,
|
||||
|
@ -1341,7 +1341,7 @@ bb_buf_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
|
||||
enum v4l2_field field)
|
||||
{
|
||||
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
|
||||
@ -1354,8 +1354,7 @@ bb_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
|
||||
static void
|
||||
bb_buf_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
|
||||
{
|
||||
struct cx8802_fh *fh = q->priv_data;
|
||||
cx88_free_buffer(fh->dev->pci, (struct cx88_buffer*)vb);
|
||||
cx88_free_buffer(q, (struct cx88_buffer*)vb);
|
||||
}
|
||||
|
||||
static struct videobuf_queue_ops blackbird_qops = {
|
||||
|
@ -213,13 +213,13 @@ int cx88_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc,
|
||||
}
|
||||
|
||||
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());
|
||||
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);
|
||||
btcx_riscmem_free(pci, &buf->risc);
|
||||
btcx_riscmem_free((struct pci_dev *)q->dev, &buf->risc);
|
||||
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)
|
||||
{
|
||||
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)
|
||||
@ -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)
|
||||
{
|
||||
struct cx8802_dev *dev = q->priv_data;
|
||||
cx88_free_buffer(dev->pci, (struct cx88_buffer*)vb);
|
||||
cx88_free_buffer(q, (struct cx88_buffer*)vb);
|
||||
}
|
||||
|
||||
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,
|
||||
enum v4l2_field field)
|
||||
int cx8802_buf_prepare(struct videobuf_queue *q, struct cx8802_dev *dev,
|
||||
struct cx88_buffer *buf, enum v4l2_field field)
|
||||
{
|
||||
int size = dev->ts_packet_size * dev->ts_packet_count;
|
||||
int rc;
|
||||
@ -179,7 +179,7 @@ int cx8802_buf_prepare(struct cx8802_dev *dev, struct cx88_buffer *buf,
|
||||
buf->vb.size = size;
|
||||
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;
|
||||
cx88_risc_databuffer(dev->pci, &buf->risc,
|
||||
buf->vb.dma.sglist,
|
||||
@ -189,36 +189,36 @@ int cx8802_buf_prepare(struct cx8802_dev *dev, struct cx88_buffer *buf,
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
cx88_free_buffer(dev->pci,buf);
|
||||
cx88_free_buffer(q,buf);
|
||||
return rc;
|
||||
}
|
||||
|
||||
void cx8802_buf_queue(struct cx8802_dev *dev, struct cx88_buffer *buf)
|
||||
{
|
||||
struct cx88_buffer *prev;
|
||||
struct cx88_dmaqueue *q = &dev->mpegq;
|
||||
struct cx88_dmaqueue *cx88q = &dev->mpegq;
|
||||
|
||||
dprintk( 1, "cx8802_buf_queue\n" );
|
||||
/* add jump to stopper */
|
||||
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" );
|
||||
list_add_tail(&buf->vb.queue,&q->active);
|
||||
cx8802_start_dma(dev, q, buf);
|
||||
list_add_tail(&buf->vb.queue,&cx88q->active);
|
||||
cx8802_start_dma(dev, cx88q, buf);
|
||||
buf->vb.state = STATE_ACTIVE;
|
||||
buf->count = q->count++;
|
||||
mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
|
||||
buf->count = cx88q->count++;
|
||||
mod_timer(&cx88q->timeout, jiffies+BUFFER_TIMEOUT);
|
||||
dprintk(0,"[%p/%d] %s - first active\n",
|
||||
buf, buf->vb.i, __FUNCTION__);
|
||||
|
||||
} else {
|
||||
dprintk( 1, "queue is not empty - append to active\n" );
|
||||
prev = list_entry(q->active.prev, struct cx88_buffer, vb.queue);
|
||||
list_add_tail(&buf->vb.queue,&q->active);
|
||||
prev = list_entry(cx88q->active.prev, struct cx88_buffer, vb.queue);
|
||||
list_add_tail(&buf->vb.queue,&cx88q->active);
|
||||
buf->vb.state = STATE_ACTIVE;
|
||||
buf->count = q->count++;
|
||||
buf->count = cx88q->count++;
|
||||
prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
|
||||
dprintk( 1, "[%p/%d] %s - append to active\n",
|
||||
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);
|
||||
break;
|
||||
case V4L2_TUNER_MODE_STEREO:
|
||||
case V4L2_TUNER_MODE_LANG1_LANG2:
|
||||
set_audio_standard_BTSC(core, 0, EN_BTSC_FORCE_STEREO);
|
||||
break;
|
||||
}
|
||||
@ -905,6 +906,7 @@ void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual)
|
||||
EN_NICAM_FORCE_MONO2);
|
||||
break;
|
||||
case V4L2_TUNER_MODE_STEREO:
|
||||
case V4L2_TUNER_MODE_LANG1_LANG2:
|
||||
set_audio_standard_NICAM(core,
|
||||
EN_NICAM_FORCE_STEREO);
|
||||
break;
|
||||
@ -926,6 +928,7 @@ void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual)
|
||||
EN_A2_FORCE_MONO2);
|
||||
break;
|
||||
case V4L2_TUNER_MODE_STEREO:
|
||||
case V4L2_TUNER_MODE_LANG1_LANG2:
|
||||
set_audio_standard_A2(core,
|
||||
EN_A2_FORCE_STEREO);
|
||||
break;
|
||||
|
@ -175,7 +175,7 @@ vbi_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
|
||||
buf->vb.size = size;
|
||||
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;
|
||||
cx88_risc_buffer(dev->pci, &buf->risc,
|
||||
buf->vb.dma.sglist,
|
||||
@ -187,7 +187,7 @@ vbi_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
cx88_free_buffer(dev->pci,buf);
|
||||
cx88_free_buffer(q,buf);
|
||||
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)
|
||||
{
|
||||
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 = {
|
||||
|
@ -564,7 +564,7 @@ buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
|
||||
|
||||
if (STATE_NEEDS_INIT == buf->vb.state) {
|
||||
init_buffer = 1;
|
||||
if (0 != (rc = videobuf_iolock(dev->pci,&buf->vb,NULL)))
|
||||
if (0 != (rc = videobuf_iolock(q,&buf->vb,NULL)))
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@ -614,7 +614,7 @@ buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
cx88_free_buffer(dev->pci,buf);
|
||||
cx88_free_buffer(q,buf);
|
||||
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)
|
||||
{
|
||||
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 = {
|
||||
@ -1251,9 +1250,17 @@ int cx88_do_ioctl(struct inode *inode, struct file *file, int radio,
|
||||
{
|
||||
int err;
|
||||
|
||||
dprintk(2, "CORE IOCTL: 0x%x\n", cmd );
|
||||
if (video_debug > 1)
|
||||
v4l_print_ioctl(core->name,cmd);
|
||||
if (video_debug) {
|
||||
if (video_debug > 1) {
|
||||
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) {
|
||||
/* ---------- 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,
|
||||
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/tveeprom.h>
|
||||
#include <media/audiochip.h>
|
||||
#include <media/video-buf.h>
|
||||
#include <media/video-buf-dvb.h>
|
||||
|
||||
@ -485,7 +484,7 @@ extern int
|
||||
cx88_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc,
|
||||
u32 reg, u32 mask, u32 value);
|
||||
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,
|
||||
struct btcx_riscmem *risc);
|
||||
@ -577,8 +576,8 @@ void cx88_ir_irq(struct cx88_core *core);
|
||||
/* ----------------------------------------------------------- */
|
||||
/* cx88-mpeg.c */
|
||||
|
||||
int cx8802_buf_prepare(struct cx8802_dev *dev, struct cx88_buffer *buf,
|
||||
enum v4l2_field field);
|
||||
int cx8802_buf_prepare(struct videobuf_queue *q,struct cx8802_dev *dev,
|
||||
struct cx88_buffer *buf, enum v4l2_field field);
|
||||
void cx8802_buf_queue(struct cx8802_dev *dev, struct cx88_buffer *buf);
|
||||
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;
|
||||
}
|
||||
/*-------------------------------------------------------------------*/
|
||||
#ifdef DEBUG
|
||||
#ifdef DEBUG
|
||||
static void dump_urb (struct urb *urb)
|
||||
{
|
||||
dbg("urb :%p", urb);
|
||||
@ -136,7 +136,7 @@ static int dabusb_free_queue (struct list_head *q)
|
||||
for (p = q->next; p != q;) {
|
||||
b = list_entry (p, buff_t, buff_list);
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifdef DEBUG
|
||||
dump_urb(b->purb);
|
||||
#endif
|
||||
kfree(b->purb->transfer_buffer);
|
||||
@ -287,7 +287,7 @@ static int dabusb_bulk (pdabusb_t s, pbulk_transfer_t pb)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
if( ret == -EPIPE ) {
|
||||
warn("CLEAR_FEATURE request to remove STALL condition.");
|
||||
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;
|
||||
|
||||
dbg("Enter dabusb_loadmem (internal)");
|
||||
|
||||
|
||||
ret = dabusb_8051_reset (s, 1);
|
||||
while (ptr->Type == 0) {
|
||||
|
||||
@ -449,7 +449,7 @@ static int dabusb_startrek (pdabusb_t s)
|
||||
if (!list_empty (&s->free_buff_list)) {
|
||||
pbuff_t end;
|
||||
int ret;
|
||||
|
||||
|
||||
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);
|
||||
@ -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");
|
||||
goto err;
|
||||
}
|
||||
|
||||
|
||||
b = list_entry (s->rec_buff_list.next, buff_t, buff_list);
|
||||
purb = b->purb;
|
||||
|
||||
@ -783,9 +783,9 @@ static void dabusb_disconnect (struct usb_interface *intf)
|
||||
pdabusb_t s = usb_get_intfdata (intf);
|
||||
|
||||
dbg("dabusb_disconnect");
|
||||
|
||||
|
||||
init_waitqueue_entry(&__wait, current);
|
||||
|
||||
|
||||
usb_set_intfdata (intf, NULL);
|
||||
if (s) {
|
||||
usb_deregister_dev (intf, &dabusb_class);
|
||||
@ -797,7 +797,7 @@ static void dabusb_disconnect (struct usb_interface *intf)
|
||||
schedule();
|
||||
current->state = TASK_RUNNING;
|
||||
remove_wait_queue(&s->remove_ok, &__wait);
|
||||
|
||||
|
||||
s->usbdev = NULL;
|
||||
s->overruns = 0;
|
||||
}
|
@ -10,7 +10,7 @@ typedef struct
|
||||
#define DABUSB_VERSION 0x1000
|
||||
#define IOCTL_DAB_BULK _IOWR('d', 0x30, bulk_transfer_t)
|
||||
#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__
|
||||
|
||||
@ -36,7 +36,7 @@ typedef struct
|
||||
struct list_head rec_buff_list;
|
||||
} dabusb_t,*pdabusb_t;
|
||||
|
||||
typedef struct
|
||||
typedef struct
|
||||
{
|
||||
pdabusb_t s;
|
||||
struct urb *purb;
|
@ -37,28 +37,28 @@
|
||||
Markus: Updates for 2.6.x kernels, code layout changes, name sanitizing
|
||||
|
||||
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:
|
||||
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:
|
||||
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
|
||||
|
||||
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:
|
||||
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.
|
||||
|
||||
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
|
||||
|
||||
Version 0.2:
|
||||
Brad Hards <bradh@dynamite.com.au>: Fixes to make it work as non-module
|
||||
Version 0.2:
|
||||
Brad Hards <bradh@dynamite.com.au>: Fixes to make it work as non-module
|
||||
Markus: Copyright clarification
|
||||
|
||||
Version 0.01: Markus: initial release
|
||||
@ -163,11 +163,11 @@ static struct usb_driver usb_dsbr100_driver = {
|
||||
static int dsbr100_start(dsbr100_device *radio)
|
||||
{
|
||||
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,
|
||||
0x00, 0xC7, radio->transfer_buffer, 8, 300)<0 ||
|
||||
usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0),
|
||||
DSB100_ONOFF,
|
||||
DSB100_ONOFF,
|
||||
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
|
||||
0x01, 0x00, radio->transfer_buffer, 8, 300)<0)
|
||||
return -1;
|
||||
@ -179,11 +179,11 @@ static int dsbr100_start(dsbr100_device *radio)
|
||||
static int dsbr100_stop(dsbr100_device *radio)
|
||||
{
|
||||
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,
|
||||
0x16, 0x1C, radio->transfer_buffer, 8, 300)<0 ||
|
||||
usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0),
|
||||
DSB100_ONOFF,
|
||||
DSB100_ONOFF,
|
||||
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
|
||||
0x00, 0x00, radio->transfer_buffer, 8, 300)<0)
|
||||
return -1;
|
||||
@ -195,16 +195,16 @@ static int dsbr100_setfreq(dsbr100_device *radio, int freq)
|
||||
{
|
||||
freq = (freq/16*80)/1000+856;
|
||||
if (usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0),
|
||||
DSB100_TUNE,
|
||||
DSB100_TUNE,
|
||||
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 ||
|
||||
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,
|
||||
0x96, 0xB7, radio->transfer_buffer, 8, 300)<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,
|
||||
0x00, 0x24, radio->transfer_buffer, 8, 300)<0) {
|
||||
radio->stereo = -1;
|
||||
@ -219,7 +219,7 @@ sees a stereo signal or not. Pity. */
|
||||
static void dsbr100_getstat(dsbr100_device *radio)
|
||||
{
|
||||
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,
|
||||
0x00 , 0x24, radio->transfer_buffer, 8, 300)<0)
|
||||
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
|
||||
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)
|
||||
{
|
||||
dsbr100_device *radio;
|
||||
@ -243,7 +243,7 @@ static int usb_dsbr100_probe(struct usb_interface *intf,
|
||||
kfree(radio);
|
||||
return -ENOMEM;
|
||||
}
|
||||
memcpy(radio->videodev, &dsbr100_videodev_template,
|
||||
memcpy(radio->videodev, &dsbr100_videodev_template,
|
||||
sizeof(dsbr100_videodev_template));
|
||||
radio->removed = 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;
|
||||
|
||||
dsbr100_getstat(radio);
|
||||
if(v->tuner) /* Only 1 tuner */
|
||||
if(v->tuner) /* Only 1 tuner */
|
||||
return -EINVAL;
|
||||
v->rangelow = FREQ_MIN*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->step = 1;
|
||||
strcpy(v->name, "Radio");
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
case VIDIOCSAUDIO: {
|
||||
struct video_audio *v = arg;
|
||||
|
||||
if (v->audio)
|
||||
if (v->audio)
|
||||
return -EINVAL;
|
||||
if (v->flags&VIDEO_AUDIO_MUTE) {
|
||||
if (dsbr100_stop(radio)==-1)
|
@ -28,10 +28,10 @@
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/usb.h>
|
||||
#include <media/tuner.h>
|
||||
#include <media/audiochip.h>
|
||||
#include <media/msp3400.h>
|
||||
#include <media/tveeprom.h>
|
||||
#include <media/audiochip.h>
|
||||
#include <media/v4l2-common.h>
|
||||
#include "msp3400.h"
|
||||
|
||||
#include "em28xx.h"
|
||||
|
||||
@ -147,11 +147,12 @@ struct em28xx_board em28xx_boards[] = {
|
||||
.input = {{
|
||||
.type = EM28XX_VMUX_TELEVISION,
|
||||
.vmux = 0,
|
||||
.amux = 6,
|
||||
.amux = MSP_INPUT_DEFAULT,
|
||||
},{
|
||||
.type = EM28XX_VMUX_SVIDEO,
|
||||
.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] = {
|
||||
|
@ -38,6 +38,7 @@
|
||||
#include "em28xx.h"
|
||||
#include <media/tuner.h>
|
||||
#include <media/v4l2-common.h>
|
||||
#include <media/msp3400.h>
|
||||
|
||||
#define DRIVER_AUTHOR "Ludovico Cavedon <cavedon@sssup.it>, " \
|
||||
"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);
|
||||
|
||||
if (dev->has_msp34xx) {
|
||||
struct v4l2_routing route;
|
||||
|
||||
if (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;
|
||||
em28xx_audio_source(dev, ainput);
|
||||
} 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
|
||||
et61x251_attach_sensor(struct et61x251_device* cam,
|
||||
struct et61x251_sensor* sensor)
|
||||
struct et61x251_sensor* sensor)
|
||||
{
|
||||
memcpy(&cam->sensor, sensor, sizeof(struct et61x251_sensor));
|
||||
}
|
||||
@ -199,7 +199,7 @@ do { \
|
||||
dev_info(&cam->usbdev->dev, fmt "\n", ## args); \
|
||||
else if ((level) >= 3) \
|
||||
dev_info(&cam->usbdev->dev, "[%s:%d] " fmt "\n", \
|
||||
__FUNCTION__, __LINE__ , ## args); \
|
||||
__FUNCTION__, __LINE__ , ## args); \
|
||||
} \
|
||||
} while (0)
|
||||
# define KDBG(level, fmt, args...) \
|
||||
@ -209,7 +209,7 @@ do { \
|
||||
pr_info("et61x251: " fmt "\n", ## args); \
|
||||
else if ((level) == 3) \
|
||||
pr_debug("et61x251: [%s:%d] " fmt "\n", __FUNCTION__, \
|
||||
__LINE__ , ## args); \
|
||||
__LINE__ , ## args); \
|
||||
} \
|
||||
} while (0)
|
||||
# define V4LDBG(level, name, cmd) \
|
||||
@ -226,7 +226,7 @@ do { \
|
||||
#undef PDBG
|
||||
#define PDBG(fmt, args...) \
|
||||
dev_info(&cam->usbdev->dev, "[%s:%d] " fmt "\n", \
|
||||
__FUNCTION__, __LINE__ , ## args)
|
||||
__FUNCTION__, __LINE__ , ## args)
|
||||
|
||||
#undef PDBGG
|
||||
#define PDBGG(fmt, args...) do {;} while(0) /* placeholder */
|
@ -44,7 +44,7 @@
|
||||
/*****************************************************************************/
|
||||
|
||||
#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_AUTHOR_EMAIL "<luca.risolia@studio.unibo.it>"
|
||||
#define ET61X251_MODULE_LICENSE "GPL"
|
||||
@ -63,68 +63,68 @@ MODULE_LICENSE(ET61X251_MODULE_LICENSE);
|
||||
static short video_nr[] = {[0 ... ET61X251_MAX_DEVICES-1] = -1};
|
||||
module_param_array(video_nr, short, NULL, 0444);
|
||||
MODULE_PARM_DESC(video_nr,
|
||||
"\n<-1|n[,...]> Specify V4L2 minor mode number."
|
||||
"\n -1 = use next available (default)"
|
||||
"\n n = use minor number n (integer >= 0)"
|
||||
"\nYou can specify up to "
|
||||
__MODULE_STRING(ET61X251_MAX_DEVICES) " cameras this way."
|
||||
"\nFor example:"
|
||||
"\nvideo_nr=-1,2,-1 would assign minor number 2 to"
|
||||
"\nthe second registered camera and use auto for the first"
|
||||
"\none and for every other camera."
|
||||
"\n");
|
||||
"\n<-1|n[,...]> Specify V4L2 minor mode number."
|
||||
"\n -1 = use next available (default)"
|
||||
"\n n = use minor number n (integer >= 0)"
|
||||
"\nYou can specify up to "
|
||||
__MODULE_STRING(ET61X251_MAX_DEVICES) " cameras this way."
|
||||
"\nFor example:"
|
||||
"\nvideo_nr=-1,2,-1 would assign minor number 2 to"
|
||||
"\nthe second registered camera and use auto for the first"
|
||||
"\none and for every other camera."
|
||||
"\n");
|
||||
|
||||
static short force_munmap[] = {[0 ... ET61X251_MAX_DEVICES-1] =
|
||||
ET61X251_FORCE_MUNMAP};
|
||||
ET61X251_FORCE_MUNMAP};
|
||||
module_param_array(force_munmap, bool, NULL, 0444);
|
||||
MODULE_PARM_DESC(force_munmap,
|
||||
"\n<0|1[,...]> Force the application to unmap previously"
|
||||
"\nmapped buffer memory before calling any VIDIOC_S_CROP or"
|
||||
"\nVIDIOC_S_FMT ioctl's. Not all the applications support"
|
||||
"\nthis feature. This parameter is specific for each"
|
||||
"\ndetected camera."
|
||||
"\n 0 = do not force memory unmapping"
|
||||
"\n 1 = force memory unmapping (save memory)"
|
||||
"\nDefault value is "__MODULE_STRING(SN9C102_FORCE_MUNMAP)"."
|
||||
"\n");
|
||||
"\n<0|1[,...]> Force the application to unmap previously"
|
||||
"\nmapped buffer memory before calling any VIDIOC_S_CROP or"
|
||||
"\nVIDIOC_S_FMT ioctl's. Not all the applications support"
|
||||
"\nthis feature. This parameter is specific for each"
|
||||
"\ndetected camera."
|
||||
"\n 0 = do not force memory unmapping"
|
||||
"\n 1 = force memory unmapping (save memory)"
|
||||
"\nDefault value is "__MODULE_STRING(SN9C102_FORCE_MUNMAP)"."
|
||||
"\n");
|
||||
|
||||
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_PARM_DESC(frame_timeout,
|
||||
"\n<n[,...]> Timeout for a video frame in seconds."
|
||||
"\nThis parameter is specific for each detected camera."
|
||||
"\nDefault value is "
|
||||
__MODULE_STRING(ET61X251_FRAME_TIMEOUT)"."
|
||||
"\n");
|
||||
"\n<n[,...]> Timeout for a video frame in seconds."
|
||||
"\nThis parameter is specific for each detected camera."
|
||||
"\nDefault value is "
|
||||
__MODULE_STRING(ET61X251_FRAME_TIMEOUT)"."
|
||||
"\n");
|
||||
|
||||
#ifdef ET61X251_DEBUG
|
||||
static unsigned short debug = ET61X251_DEBUG_LEVEL;
|
||||
module_param(debug, ushort, 0644);
|
||||
MODULE_PARM_DESC(debug,
|
||||
"\n<n> Debugging information level, from 0 to 3:"
|
||||
"\n0 = none (use carefully)"
|
||||
"\n1 = critical errors"
|
||||
"\n2 = significant informations"
|
||||
"\n3 = more verbose messages"
|
||||
"\nLevel 3 is useful for testing only, when only "
|
||||
"one device is used."
|
||||
"\nDefault value is "__MODULE_STRING(ET61X251_DEBUG_LEVEL)"."
|
||||
"\n");
|
||||
"\n<n> Debugging information level, from 0 to 3:"
|
||||
"\n0 = none (use carefully)"
|
||||
"\n1 = critical errors"
|
||||
"\n2 = significant informations"
|
||||
"\n3 = more verbose messages"
|
||||
"\nLevel 3 is useful for testing only, when only "
|
||||
"one device is used."
|
||||
"\nDefault value is "__MODULE_STRING(ET61X251_DEBUG_LEVEL)"."
|
||||
"\n");
|
||||
#endif
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static u32
|
||||
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_rect* r = &(cam->sensor.cropcap.bounds);
|
||||
const size_t imagesize = cam->module_param.force_munmap ||
|
||||
io == IO_READ ?
|
||||
(p->width * p->height * p->priv) / 8 :
|
||||
(r->width * r->height * p->priv) / 8;
|
||||
io == IO_READ ?
|
||||
(p->width * p->height * p->priv) / 8 :
|
||||
(r->width * r->height * p->priv) / 8;
|
||||
void* buff = NULL;
|
||||
u32 i;
|
||||
|
||||
@ -216,7 +216,7 @@ int et61x251_write_reg(struct et61x251_device* cam, u8 value, u16 index)
|
||||
*buff = value;
|
||||
|
||||
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) {
|
||||
DBG(3, "Failed to write a register (value 0x%02X, index "
|
||||
"0x%02X, error %d)", value, index, res);
|
||||
@ -234,7 +234,7 @@ int et61x251_read_reg(struct et61x251_device* cam, u16 index)
|
||||
int res;
|
||||
|
||||
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)
|
||||
DBG(3, "Failed to read a register (index 0x%02X, error %d)",
|
||||
index, res);
|
||||
@ -269,7 +269,7 @@ et61x251_i2c_wait(struct et61x251_device* cam, struct et61x251_sensor* sensor)
|
||||
|
||||
int
|
||||
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;
|
||||
u8* data = cam->control_buffer;
|
||||
@ -280,14 +280,14 @@ et61x251_i2c_try_read(struct et61x251_device* cam,
|
||||
data[2] = cam->sensor.rsta | 0x10;
|
||||
data[3] = !(et61x251_read_reg(cam, 0x8b) & 0x02);
|
||||
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)
|
||||
err += res;
|
||||
|
||||
err += et61x251_i2c_wait(cam, sensor);
|
||||
|
||||
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)
|
||||
err += res;
|
||||
|
||||
@ -302,7 +302,7 @@ et61x251_i2c_try_read(struct et61x251_device* cam,
|
||||
|
||||
int
|
||||
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;
|
||||
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[2] = cam->sensor.rsta | 0x12;
|
||||
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)
|
||||
err += res;
|
||||
|
||||
data[0] = value;
|
||||
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)
|
||||
err += res;
|
||||
|
||||
@ -335,8 +335,8 @@ et61x251_i2c_try_write(struct et61x251_device* cam,
|
||||
|
||||
int
|
||||
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 data8, u8 address)
|
||||
u8 data3, u8 data4, u8 data5, u8 data6, u8 data7,
|
||||
u8 data8, u8 address)
|
||||
{
|
||||
struct usb_device* udev = cam->usbdev;
|
||||
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[6] = data8;
|
||||
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)
|
||||
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[2] = cam->sensor.rsta | 0x02 | (n << 4);
|
||||
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)
|
||||
err += res;
|
||||
|
||||
/* Start writing through the serial interface */
|
||||
data[0] = data1;
|
||||
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)
|
||||
err += res;
|
||||
|
||||
@ -432,11 +432,11 @@ static void et61x251_urb_complete(struct urb *urb, struct pt_regs* regs)
|
||||
|
||||
if (!(*f))
|
||||
(*f) = list_entry(cam->inqueue.next, struct et61x251_frame_t,
|
||||
frame);
|
||||
frame);
|
||||
|
||||
imagesize = (cam->sensor.pix_format.width *
|
||||
cam->sensor.pix_format.height *
|
||||
cam->sensor.pix_format.priv) / 8;
|
||||
cam->sensor.pix_format.height *
|
||||
cam->sensor.pix_format.priv) / 8;
|
||||
|
||||
for (i = 0; i < urb->number_of_packets; i++) {
|
||||
unsigned int len, status;
|
||||
@ -476,7 +476,7 @@ start_of_frame:
|
||||
if ((*f)->state == F_GRABBING) {
|
||||
if (sof && (*f)->buf.bytesused) {
|
||||
if (cam->sensor.pix_format.pixelformat ==
|
||||
V4L2_PIX_FMT_ET61X251)
|
||||
V4L2_PIX_FMT_ET61X251)
|
||||
goto end_of_frame;
|
||||
else {
|
||||
DBG(3, "Not expected SOF detected "
|
||||
@ -508,8 +508,8 @@ end_of_frame:
|
||||
list_move_tail(&(*f)->frame, &cam->outqueue);
|
||||
if (!list_empty(&cam->inqueue))
|
||||
(*f) = list_entry(cam->inqueue.next,
|
||||
struct et61x251_frame_t,
|
||||
frame);
|
||||
struct et61x251_frame_t,
|
||||
frame);
|
||||
else
|
||||
(*f) = NULL;
|
||||
spin_unlock(&cam->queue_lock);
|
||||
@ -521,7 +521,7 @@ end_of_frame:
|
||||
|
||||
if (sof &&
|
||||
cam->sensor.pix_format.pixelformat ==
|
||||
V4L2_PIX_FMT_ET61X251)
|
||||
V4L2_PIX_FMT_ET61X251)
|
||||
goto start_of_frame;
|
||||
}
|
||||
}
|
||||
@ -544,15 +544,15 @@ static int et61x251_start_transfer(struct et61x251_device* cam)
|
||||
struct usb_device *udev = cam->usbdev;
|
||||
struct urb* urb;
|
||||
const unsigned int wMaxPacketSize[] = {0, 256, 384, 512, 640, 768, 832,
|
||||
864, 896, 920, 956, 980, 1000,
|
||||
1022};
|
||||
864, 896, 920, 956, 980, 1000,
|
||||
1022};
|
||||
const unsigned int psz = wMaxPacketSize[ET61X251_ALTERNATE_SETTING];
|
||||
s8 i, j;
|
||||
int err = 0;
|
||||
|
||||
for (i = 0; i < ET61X251_URBS; i++) {
|
||||
cam->transfer_buffer[i] = kzalloc(ET61X251_ISO_PACKETS * psz,
|
||||
GFP_KERNEL);
|
||||
GFP_KERNEL);
|
||||
if (!cam->transfer_buffer[i]) {
|
||||
err = -ENOMEM;
|
||||
DBG(1, "Not enough memory");
|
||||
@ -653,9 +653,9 @@ static int et61x251_stream_interrupt(struct et61x251_device* cam)
|
||||
|
||||
cam->stream = STREAM_INTERRUPT;
|
||||
timeout = wait_event_timeout(cam->wait_stream,
|
||||
(cam->stream == STREAM_OFF) ||
|
||||
(cam->state & DEV_DISCONNECTED),
|
||||
ET61X251_URB_TIMEOUT);
|
||||
(cam->stream == STREAM_OFF) ||
|
||||
(cam->state & DEV_DISCONNECTED),
|
||||
ET61X251_URB_TIMEOUT);
|
||||
if (cam->state & DEV_DISCONNECTED)
|
||||
return -ENODEV;
|
||||
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
|
||||
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
|
||||
*/
|
||||
|
||||
@ -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,
|
||||
et61x251_show_reg, et61x251_store_reg);
|
||||
et61x251_show_reg, et61x251_store_reg);
|
||||
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,
|
||||
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,
|
||||
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)
|
||||
@ -990,7 +990,7 @@ static void et61x251_create_sysfs(struct et61x251_device* cam)
|
||||
|
||||
static int
|
||||
et61x251_set_pix_format(struct et61x251_device* cam,
|
||||
struct v4l2_pix_format* pix)
|
||||
struct v4l2_pix_format* pix)
|
||||
{
|
||||
int r, err = 0;
|
||||
|
||||
@ -1007,7 +1007,7 @@ et61x251_set_pix_format(struct et61x251_device* cam,
|
||||
|
||||
static int
|
||||
et61x251_set_compression(struct et61x251_device* cam,
|
||||
struct v4l2_jpegcompression* compression)
|
||||
struct v4l2_jpegcompression* compression)
|
||||
{
|
||||
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;
|
||||
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 +
|
||||
s->active_pixel.top),
|
||||
s->active_pixel.top),
|
||||
fmw_length = (u16)(rect->width),
|
||||
fmw_height = (u16)(rect->height);
|
||||
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_height & 0xff, 0x6c);
|
||||
err += et61x251_write_reg(cam, (fmw_sx >> 8) | ((fmw_sy & 0x300) >> 6)
|
||||
| ((fmw_length & 0x300) >> 4)
|
||||
| ((fmw_height & 0x300) >> 2), 0x6d);
|
||||
| ((fmw_length & 0x300) >> 4)
|
||||
| ((fmw_height & 0x300) >> 2), 0x6d);
|
||||
if (err)
|
||||
return -EIO;
|
||||
|
||||
@ -1203,8 +1203,8 @@ static int et61x251_open(struct inode* inode, struct file* filp)
|
||||
}
|
||||
mutex_unlock(&cam->dev_mutex);
|
||||
err = wait_event_interruptible_exclusive(cam->open,
|
||||
cam->state & DEV_DISCONNECTED
|
||||
|| !cam->users);
|
||||
cam->state & DEV_DISCONNECTED
|
||||
|| !cam->users);
|
||||
if (err) {
|
||||
up_read(&et61x251_disconnect);
|
||||
return err;
|
||||
@ -1277,7 +1277,7 @@ static int et61x251_release(struct inode* inode, struct file* filp)
|
||||
|
||||
static ssize_t
|
||||
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_frame_t* f, * i;
|
||||
@ -1310,7 +1310,7 @@ et61x251_read(struct file* filp, char __user * buf,
|
||||
|
||||
if (cam->io == IO_NONE) {
|
||||
if (!et61x251_request_buffers(cam, cam->nreadbuffers,
|
||||
IO_READ)) {
|
||||
IO_READ)) {
|
||||
DBG(1, "read() failed, not enough memory");
|
||||
mutex_unlock(&cam->fileop_mutex);
|
||||
return -ENOMEM;
|
||||
@ -1336,12 +1336,12 @@ et61x251_read(struct file* filp, char __user * buf,
|
||||
return -EAGAIN;
|
||||
}
|
||||
timeout = wait_event_interruptible_timeout
|
||||
( cam->wait_frame,
|
||||
(!list_empty(&cam->outqueue)) ||
|
||||
(cam->state & DEV_DISCONNECTED) ||
|
||||
(cam->state & DEV_MISCONFIGURED),
|
||||
cam->module_param.frame_timeout *
|
||||
1000 * msecs_to_jiffies(1) );
|
||||
( cam->wait_frame,
|
||||
(!list_empty(&cam->outqueue)) ||
|
||||
(cam->state & DEV_DISCONNECTED) ||
|
||||
(cam->state & DEV_MISCONFIGURED),
|
||||
cam->module_param.frame_timeout *
|
||||
1000 * msecs_to_jiffies(1) );
|
||||
if (timeout < 0) {
|
||||
mutex_unlock(&cam->fileop_mutex);
|
||||
return timeout;
|
||||
@ -1408,7 +1408,7 @@ static unsigned int et61x251_poll(struct file *filp, poll_table *wait)
|
||||
|
||||
if (cam->io == IO_NONE) {
|
||||
if (!et61x251_request_buffers(cam, cam->nreadbuffers,
|
||||
IO_READ)) {
|
||||
IO_READ)) {
|
||||
DBG(1, "poll() failed, not enough memory");
|
||||
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));
|
||||
unsigned long size = vma->vm_end - vma->vm_start,
|
||||
start = vma->vm_start;
|
||||
start = vma->vm_start;
|
||||
void *pos;
|
||||
u32 i;
|
||||
|
||||
@ -1533,13 +1533,13 @@ et61x251_vidioc_querycap(struct et61x251_device* cam, void __user * arg)
|
||||
.driver = "et61x251",
|
||||
.version = ET61X251_MODULE_VERSION_CODE,
|
||||
.capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE |
|
||||
V4L2_CAP_STREAMING,
|
||||
V4L2_CAP_STREAMING,
|
||||
};
|
||||
|
||||
strlcpy(cap.card, cam->v4ldev->name, sizeof(cap.card));
|
||||
if (usb_make_path(cam->usbdev, cap.bus_info, sizeof(cap.bus_info)) < 0)
|
||||
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)))
|
||||
return -EFAULT;
|
||||
@ -1871,7 +1871,7 @@ et61x251_vidioc_g_fmt(struct et61x251_device* cam, void __user * arg)
|
||||
return -EINVAL;
|
||||
|
||||
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->field = V4L2_FIELD_NONE;
|
||||
memcpy(&(format.fmt.pix), pfmt, sizeof(*pfmt));
|
||||
@ -1885,7 +1885,7 @@ et61x251_vidioc_g_fmt(struct et61x251_device* cam, void __user * arg)
|
||||
|
||||
static int
|
||||
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 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->colorspace = pfmt->colorspace;
|
||||
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->field = V4L2_FIELD_NONE;
|
||||
|
||||
@ -2020,7 +2020,7 @@ static int
|
||||
et61x251_vidioc_g_jpegcomp(struct et61x251_device* cam, void __user * arg)
|
||||
{
|
||||
if (copy_to_user(arg, &cam->compression,
|
||||
sizeof(cam->compression)))
|
||||
sizeof(cam->compression)))
|
||||
return -EFAULT;
|
||||
|
||||
return 0;
|
||||
@ -2169,7 +2169,7 @@ et61x251_vidioc_qbuf(struct et61x251_device* cam, void __user * arg)
|
||||
|
||||
static int
|
||||
et61x251_vidioc_dqbuf(struct et61x251_device* cam, struct file* filp,
|
||||
void __user * arg)
|
||||
void __user * arg)
|
||||
{
|
||||
struct v4l2_buffer b;
|
||||
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)
|
||||
return -EAGAIN;
|
||||
timeout = wait_event_interruptible_timeout
|
||||
( cam->wait_frame,
|
||||
(!list_empty(&cam->outqueue)) ||
|
||||
(cam->state & DEV_DISCONNECTED) ||
|
||||
(cam->state & DEV_MISCONFIGURED),
|
||||
cam->module_param.frame_timeout *
|
||||
1000 * msecs_to_jiffies(1) );
|
||||
( cam->wait_frame,
|
||||
(!list_empty(&cam->outqueue)) ||
|
||||
(cam->state & DEV_DISCONNECTED) ||
|
||||
(cam->state & DEV_MISCONFIGURED),
|
||||
cam->module_param.frame_timeout *
|
||||
1000 * msecs_to_jiffies(1) );
|
||||
if (timeout < 0)
|
||||
return timeout;
|
||||
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,
|
||||
unsigned int cmd, void __user * arg)
|
||||
unsigned int cmd, void __user * arg)
|
||||
{
|
||||
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,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
struct et61x251_device* cam = video_get_drvdata(video_devdata(filp));
|
||||
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);
|
||||
|
||||
err = video_register_device(cam->v4ldev, VFL_TYPE_GRABBER,
|
||||
video_nr[dev_nr]);
|
||||
video_nr[dev_nr]);
|
||||
if (err) {
|
||||
DBG(1, "V4L2 device registration failed");
|
||||
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
|
||||
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_read(struct et61x251_device*, u8 address);
|
||||
extern int et61x251_i2c_try_write(struct et61x251_device*,
|
||||
struct et61x251_sensor*, u8 address,
|
||||
u8 value);
|
||||
struct et61x251_sensor*, u8 address,
|
||||
u8 value);
|
||||
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,
|
||||
u8 data2, u8 data3, u8 data4, u8 data5,
|
||||
u8 data6, u8 data7, u8 data8, u8 address);
|
||||
u8 data2, u8 data3, u8 data4, u8 data5,
|
||||
u8 data6, u8 data7, u8 data8, u8 address);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
@ -100,13 +100,13 @@ struct et61x251_sensor {
|
||||
|
||||
int (*init)(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,
|
||||
const struct v4l2_control* ctrl);
|
||||
const struct v4l2_control* ctrl);
|
||||
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,
|
||||
const struct v4l2_pix_format* pix);
|
||||
const struct v4l2_pix_format* pix);
|
||||
|
||||
/* Private */
|
||||
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,
|
||||
const struct v4l2_control* ctrl)
|
||||
const struct v4l2_control* ctrl)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
switch (ctrl->id) {
|
||||
case V4L2_CID_GAIN:
|
||||
err += et61x251_i2c_raw_write(cam, 2, 0x20,
|
||||
0xf6-ctrl->value, 0, 0, 0,
|
||||
0, 0, 0, 0);
|
||||
0xf6-ctrl->value, 0, 0, 0,
|
||||
0, 0, 0, 0);
|
||||
break;
|
||||
case V4L2_CID_EXPOSURE:
|
||||
err += et61x251_i2c_raw_write(cam, 2, 0x40,
|
||||
0x47-ctrl->value, 0, 0, 0,
|
||||
0, 0, 0, 0);
|
||||
0x47-ctrl->value, 0, 0, 0,
|
||||
0, 0, 0, 0);
|
||||
break;
|
||||
default:
|
||||
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/videodev2.h>
|
||||
#include <media/v4l2-common.h>
|
||||
#include <media/audiochip.h>
|
||||
#include <media/tvaudio.h>
|
||||
#include <media/msp3400.h>
|
||||
#include <linux/kthread.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] = {
|
||||
/* 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 */
|
||||
{ 0x0320, 0x0000, 0x0200, -1, -1, 0x0300, 0x0020, 0x0100, 0x0320 },
|
||||
{ 0x0320, 0x0000, 0x0200, 0x0300, 0x0020, -1, -1, 0x0100, 0x0320 },
|
||||
/* SCART1 Output select */
|
||||
{ 0x0c40, 0x0440, 0x0400, 0x0c00, 0x0040, 0x0000, 0x0840, 0x0800, 0x0c40 },
|
||||
{ 0x0c40, 0x0440, 0x0400, 0x0000, 0x0840, 0x0c00, 0x0040, 0x0800, 0x0c40 },
|
||||
/* 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[] = {
|
||||
"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)
|
||||
{
|
||||
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 (-1 == scarts[out][in])
|
||||
if (in >= 0 && in <= 7 && out >= 0 && out <= 2) {
|
||||
if (-1 == scarts[out][in + 1])
|
||||
return;
|
||||
|
||||
state->acb &= ~scarts[out][SCART_MASK];
|
||||
state->acb |= scarts[out][in];
|
||||
state->acb &= ~scarts[out][0];
|
||||
state->acb |= scarts[out][in + 1];
|
||||
} else
|
||||
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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
struct msp_state *state = i2c_get_clientdata(client);
|
||||
u16 *sarg = arg;
|
||||
int scart = 0;
|
||||
|
||||
if (msp_debug >= 2)
|
||||
v4l_i2c_print_ioctl(client, 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:
|
||||
if (state->radio)
|
||||
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) {
|
||||
state->audmode = msp_mode_v4l1_to_v4l2(va->mode);
|
||||
msp_set_audmode(client);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -728,15 +659,6 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
|
||||
break;
|
||||
}
|
||||
|
||||
/* msp34xx specific */
|
||||
case MSP_SET_MATRIX:
|
||||
{
|
||||
struct msp_matrix *mspm = arg;
|
||||
|
||||
msp_set_scart(client, mspm->input, mspm->output);
|
||||
break;
|
||||
}
|
||||
|
||||
/* --- v4l2 ioctls --- */
|
||||
case VIDIOC_S_STD:
|
||||
{
|
||||
@ -750,90 +672,34 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
|
||||
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)
|
||||
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 */
|
||||
*rt = state->routing;
|
||||
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) {
|
||||
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;
|
||||
}
|
||||
if (scart) {
|
||||
state->rxsubchans = V4L2_TUNER_SUB_STEREO;
|
||||
msp_set_scart(client, scart, 0);
|
||||
msp_write_dsp(client, 0x000d, 0x1900);
|
||||
state->routing = *rt;
|
||||
if (state->opmode == OPMODE_AUTOSELECT) {
|
||||
val = msp_read_dem(client, 0x30) & ~0x100;
|
||||
msp_write_dem(client, 0x30, val | (tuner ? 0x100 : 0));
|
||||
} else {
|
||||
val = msp_read_dem(client, 0xbb) & ~0x100;
|
||||
msp_write_dem(client, 0xbb, val | (tuner ? 0x100 : 0));
|
||||
}
|
||||
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_wake_thread(client);
|
||||
break;
|
||||
@ -866,42 +732,6 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
|
||||
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:
|
||||
{
|
||||
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_LANG2) ? ", dual" : "");
|
||||
} 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",
|
||||
msp_standard_std_name(state->std),
|
||||
(state->rxsubchans & V4L2_TUNER_SUB_STEREO) ? "stereo" : "mono",
|
||||
(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);
|
||||
break;
|
||||
}
|
||||
@ -1063,6 +897,9 @@ static int msp_attach(struct i2c_adapter *adapter, int address, int kind)
|
||||
state->muted = 0;
|
||||
state->i2s_mode = 0;
|
||||
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);
|
||||
if (state->rev1 != -1)
|
||||
|
@ -1,8 +1,10 @@
|
||||
/*
|
||||
*/
|
||||
|
||||
#ifndef MSP3400_H
|
||||
#define MSP3400_H
|
||||
#ifndef MSP3400_DRIVER_H
|
||||
#define MSP3400_DRIVER_H
|
||||
|
||||
#include <media/msp3400.h>
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
@ -20,15 +22,14 @@
|
||||
#define MSP_MODE_BTSC 8
|
||||
#define MSP_MODE_EXTERN 9
|
||||
|
||||
#define SCART_MASK 0
|
||||
#define SCART_IN1 1
|
||||
#define SCART_IN2 2
|
||||
#define SCART_IN1_DA 3
|
||||
#define SCART_IN2_DA 4
|
||||
#define SCART_IN3 5
|
||||
#define SCART_IN4 6
|
||||
#define SCART_MONO 7
|
||||
#define SCART_MUTE 8
|
||||
#define SCART_IN1 0
|
||||
#define SCART_IN2 1
|
||||
#define SCART_IN3 2
|
||||
#define SCART_IN4 3
|
||||
#define SCART_IN1_DA 4
|
||||
#define SCART_IN2_DA 5
|
||||
#define SCART_MONO 6
|
||||
#define SCART_MUTE 7
|
||||
|
||||
#define SCART_DSP_IN 0
|
||||
#define SCART1_OUT 1
|
||||
@ -73,7 +74,7 @@ struct msp_state {
|
||||
int i2s_mode;
|
||||
int main, second; /* sound carrier */
|
||||
int input;
|
||||
int source; /* see msp34xxg_set_source */
|
||||
struct v4l2_routing routing;
|
||||
|
||||
/* v4l2 */
|
||||
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_mute(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);
|
||||
|
||||
/* msp3400-kthreads.c */
|
||||
const char *msp_standard_std_name(int std);
|
||||
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 msp3410d_thread(void *data);
|
||||
int msp34xxg_thread(void *data);
|
||||
void msp3400c_set_mode(struct i2c_client *client, int mode);
|
||||
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/videodev2.h>
|
||||
#include <media/v4l2-common.h>
|
||||
#include <media/audiochip.h>
|
||||
#include <media/msp3400.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/suspend.h>
|
||||
#include "msp3400.h"
|
||||
#include "msp3400-driver.h"
|
||||
|
||||
/* this one uses the automatic sound standard detection of newer msp34xx
|
||||
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" },
|
||||
{ 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)" },
|
||||
{ 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" },
|
||||
{ 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" },
|
||||
{ 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)" },
|
||||
{ 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" },
|
||||
{ 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" },
|
||||
@ -185,13 +187,14 @@ void msp3400c_set_mode(struct i2c_client *client, int mode)
|
||||
{
|
||||
struct msp_state *state = i2c_get_clientdata(client);
|
||||
struct msp3400c_init_data_dem *data = &msp3400c_init_data[mode];
|
||||
int tuner = (state->routing.input >> 3) & 1;
|
||||
int i;
|
||||
|
||||
v4l_dbg(1, msp_debug, client, "set_mode: %d\n", mode);
|
||||
state->mode = mode;
|
||||
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 */
|
||||
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);
|
||||
|
||||
msp_set_source(client, data->dsp_src);
|
||||
msp_write_dsp(client, 0x000e, data->dsp_matrix);
|
||||
/* set prescales */
|
||||
|
||||
if (state->has_nicam) {
|
||||
/* nicam prescale */
|
||||
msp_write_dsp(client, 0x0010, 0x5a00); /* was: 0x3000 */
|
||||
}
|
||||
/* volume prescale for SCART (AM mono input) */
|
||||
msp_write_dsp(client, 0x000d, 0x1900);
|
||||
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,
|
||||
nor do they support stereo BTSC. */
|
||||
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);
|
||||
char *modestr = (state->audmode >= 0 && state->audmode < 4) ?
|
||||
char *modestr = (state->audmode >= 0 && state->audmode < 5) ?
|
||||
strmode[state->audmode] : "unknown";
|
||||
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_LANG1:
|
||||
case V4L2_TUNER_MODE_LANG2:
|
||||
case V4L2_TUNER_MODE_LANG1_LANG2:
|
||||
msp_write_dsp(client, 0x000e, 0x3000);
|
||||
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));
|
||||
break;
|
||||
case V4L2_TUNER_MODE_STEREO:
|
||||
case V4L2_TUNER_MODE_LANG1_LANG2:
|
||||
msp3400c_set_carrier(client, MSP_CARRIER(7.2), MSP_CARRIER(7.02));
|
||||
break;
|
||||
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_AM_NICAM:
|
||||
v4l_dbg(1, msp_debug, client, "NICAM set_audmode: %s\n",modestr);
|
||||
msp3400c_set_carrier(client, state->second, state->main);
|
||||
if (state->nicam_on)
|
||||
src = 0x0100; /* NICAM */
|
||||
break;
|
||||
@ -293,6 +298,7 @@ static void msp3400c_set_audmode(struct i2c_client *client)
|
||||
/* switch audio */
|
||||
switch (state->audmode) {
|
||||
case V4L2_TUNER_MODE_STEREO:
|
||||
case V4L2_TUNER_MODE_LANG1_LANG2:
|
||||
src |= 0x0020;
|
||||
break;
|
||||
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);
|
||||
|
||||
if (msp3400c_detect_stereo(client)) {
|
||||
msp3400c_set_audmode(client);
|
||||
if (msp_detect_stereo(client)) {
|
||||
msp_set_audmode(client);
|
||||
}
|
||||
|
||||
if (msp_once)
|
||||
@ -464,7 +470,7 @@ int msp3400c_thread(void *data)
|
||||
|
||||
/* mute */
|
||||
msp_set_mute(client);
|
||||
msp3400c_set_mode(client, MSP_MODE_AM_DETECT /* +1 */ );
|
||||
msp3400c_set_mode(client, MSP_MODE_AM_DETECT);
|
||||
val1 = val2 = 0;
|
||||
max1 = max2 = -1;
|
||||
state->watch_stereo = 0;
|
||||
@ -572,8 +578,6 @@ int msp3400c_thread(void *data)
|
||||
state->second = msp3400c_carrier_detect_65[max2].cdo;
|
||||
msp3400c_set_mode(client, MSP_MODE_AM_NICAM);
|
||||
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;
|
||||
} else if (max2 == 0 && state->has_nicam) {
|
||||
/* D/K NICAM */
|
||||
@ -651,7 +655,8 @@ int msp3410d_thread(void *data)
|
||||
if (msp_sleep(state,200))
|
||||
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)
|
||||
std = 0x40;
|
||||
else
|
||||
@ -695,23 +700,19 @@ int msp3410d_thread(void *data)
|
||||
v4l_dbg(1, msp_debug, client, "autodetection failed,"
|
||||
" switching to backup standard: %s (0x%04x)\n",
|
||||
msp_stdlist[8].name ? msp_stdlist[8].name : "unknown",val);
|
||||
val = 0x0009;
|
||||
state->std = val = 0x0009;
|
||||
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 */
|
||||
switch (val) {
|
||||
case 0x0008: /* B/G NICAM */
|
||||
case 0x000a: /* I NICAM */
|
||||
if (val == 0x0008)
|
||||
state->mode = MSP_MODE_FM_NICAM1;
|
||||
else
|
||||
case 0x000b: /* D/K NICAM */
|
||||
if (val == 0x000a)
|
||||
state->mode = MSP_MODE_FM_NICAM2;
|
||||
else
|
||||
state->mode = MSP_MODE_FM_NICAM1;
|
||||
/* just turn on stereo */
|
||||
state->rxsubchans = V4L2_TUNER_SUB_STEREO;
|
||||
state->nicam_on = 1;
|
||||
@ -739,6 +740,7 @@ int msp3410d_thread(void *data)
|
||||
/* scart routing (this doesn't belong here I think) */
|
||||
msp_set_scart(client,SCART_IN2,0);
|
||||
break;
|
||||
case 0x0002:
|
||||
case 0x0003:
|
||||
case 0x0004:
|
||||
case 0x0005:
|
||||
@ -748,12 +750,19 @@ int msp3410d_thread(void *data)
|
||||
break;
|
||||
}
|
||||
|
||||
/* unmute, restore misc registers */
|
||||
msp_set_audio(client);
|
||||
msp_write_dsp(client, 0x13, state->acb);
|
||||
/* set various prescales */
|
||||
msp_write_dsp(client, 0x0d, 0x1900); /* scart */
|
||||
msp_write_dsp(client, 0x0e, 0x3000); /* FM */
|
||||
if (state->has_nicam)
|
||||
msp_write_dsp(client, 0x10, 0x5a00); /* nicam */
|
||||
|
||||
if (state->has_i2s_conf)
|
||||
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);
|
||||
|
||||
/* monitor tv audio mode, the first time don't wait
|
||||
@ -772,97 +781,154 @@ int msp3410d_thread(void *data)
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
|
||||
/* msp34xxG + (autoselect no-thread) */
|
||||
/* this one uses both automatic standard detection and automatic sound */
|
||||
/* select which are available in the newer G versions */
|
||||
/* 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
|
||||
/* msp34xxG + (autoselect no-thread)
|
||||
* this one uses both automatic standard detection and automatic sound
|
||||
* select which are available in the newer G versions
|
||||
* struct msp: only norm, acb and source are really used in this mode
|
||||
*/
|
||||
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);
|
||||
|
||||
/* fix matrix mode to stereo and let the msp choose what
|
||||
* to output according to 'source', as recommended
|
||||
* for MONO (source==0) downmixing set bit[7:0] to 0x30
|
||||
*/
|
||||
int value = (source & 0x07) << 8 | (source == 0 ? 0x30 : 0x20);
|
||||
if (state->radio) {
|
||||
v4l_dbg(1, msp_debug, client, "selected radio modus\n");
|
||||
return 0x0001;
|
||||
}
|
||||
|
||||
v4l_dbg(1, msp_debug, client, "set source to %d (0x%x)\n", source, value);
|
||||
msp_set_source(client, value);
|
||||
/*
|
||||
* set identification threshold. Personally, I
|
||||
* I set it to a higher value that the default
|
||||
* of 0x190 to ignore noisy stereo signals.
|
||||
* this needs tuning. (recommended range 0x00a0-0x03c0)
|
||||
* 0x7f0 = forced mono mode
|
||||
*/
|
||||
/* a2 threshold for stereo/bilingual */
|
||||
msp_write_dem(client, 0x22, msp_stereo_thresh);
|
||||
state->source = source;
|
||||
if (state->v4l2_std & V4L2_STD_PAL) {
|
||||
v4l_dbg(1, msp_debug, client, "selected PAL modus\n");
|
||||
return 0x7001;
|
||||
}
|
||||
if (state->v4l2_std == V4L2_STD_NTSC_M_JP) {
|
||||
v4l_dbg(1, msp_debug, client, "selected M (EIA-J) modus\n");
|
||||
return 0x4001;
|
||||
}
|
||||
if (state->v4l2_std == V4L2_STD_NTSC_M_KR) {
|
||||
v4l_dbg(1, msp_debug, client, "selected M (A2) modus\n");
|
||||
return 0x0001;
|
||||
}
|
||||
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
|
||||
* return 0 if it worked, -1 if it failed
|
||||
*/
|
||||
static int msp34xxg_reset(struct i2c_client *client)
|
||||
static void msp34xxg_set_source(struct i2c_client *client, u16 reg, int in)
|
||||
{
|
||||
struct msp_state *state = i2c_get_clientdata(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);
|
||||
int modus, std;
|
||||
u32 in = state->routing.input;
|
||||
|
||||
if (msp_reset(client))
|
||||
return -1;
|
||||
msp34xxg_set_source(client, 0x0008, (in >> 4) & 0xf);
|
||||
/* 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) */
|
||||
/* ACB, mute DSP input, mute SCART 1 */
|
||||
if (msp_write_dsp(client, 0x13, 0x0f20))
|
||||
return -1;
|
||||
msp_write_dsp(client, 0x13, 0x0f20);
|
||||
|
||||
if (state->has_i2s_conf)
|
||||
msp_write_dem(client, 0x40, state->i2s_mode);
|
||||
|
||||
/* step-by-step initialisation, as described in the manual */
|
||||
modus = msp_modus(client);
|
||||
if (state->radio)
|
||||
std = 0x40;
|
||||
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;
|
||||
modus = msp34xxg_modus(client);
|
||||
modus |= tuner ? 0x100 : 0;
|
||||
msp_write_dem(client, 0x30, modus);
|
||||
|
||||
/* write the dsps that may have an influence on
|
||||
standard/audio autodetection right now */
|
||||
msp34xxg_set_source(client, state->source);
|
||||
msp34xxg_set_sources(client);
|
||||
|
||||
/* AM/FM Prescale [15:8] 75khz deviation */
|
||||
if (msp_write_dsp(client, 0x0e, 0x3000))
|
||||
return -1;
|
||||
msp_write_dsp(client, 0x0d, 0x1900); /* scart */
|
||||
msp_write_dsp(client, 0x0e, 0x3000); /* FM */
|
||||
if (state->has_nicam)
|
||||
msp_write_dsp(client, 0x10, 0x5a00); /* nicam */
|
||||
|
||||
/* NICAM Prescale 9db gain (as recommended) */
|
||||
if (msp_write_dsp(client, 0x10, 0x5a00))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
/* set identification threshold. Personally, I
|
||||
* I set it to a higher value than the default
|
||||
* of 0x190 to ignore noisy stereo signals.
|
||||
* this needs tuning. (recommended range 0x00a0-0x03c0)
|
||||
* 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)
|
||||
{
|
||||
struct i2c_client *client = data;
|
||||
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");
|
||||
|
||||
state->source = 1; /* default */
|
||||
for (;;) {
|
||||
v4l_dbg(2, msp_debug, client, "msp34xxg thread: sleep\n");
|
||||
msp_sleep(state, -1);
|
||||
@ -876,12 +942,14 @@ int msp34xxg_thread(void *data)
|
||||
|
||||
/* setup the chip*/
|
||||
msp34xxg_reset(client);
|
||||
std = msp_standard;
|
||||
if (std != 0x01)
|
||||
state->std = state->radio ? 0x40 : msp_standard;
|
||||
if (state->std != 1)
|
||||
goto unmute;
|
||||
/* start autodetect */
|
||||
msp_write_dem(client, 0x20, state->std);
|
||||
|
||||
/* 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++) {
|
||||
if (msp_sleep(state, 100))
|
||||
goto restart;
|
||||
@ -889,20 +957,19 @@ int msp34xxg_thread(void *data)
|
||||
/* check results */
|
||||
val = msp_read_dem(client, 0x7e);
|
||||
if (val < 0x07ff) {
|
||||
std = val;
|
||||
state->std = val;
|
||||
break;
|
||||
}
|
||||
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");
|
||||
continue;
|
||||
}
|
||||
|
||||
unmute:
|
||||
state->std = std;
|
||||
v4l_dbg(1, msp_debug, client, "current standard: %s (0x%04x)\n",
|
||||
msp_standard_std_name(std), std);
|
||||
v4l_dbg(1, msp_debug, client, "detected standard: %s (0x%04x)\n",
|
||||
msp_standard_std_name(state->std), state->std);
|
||||
|
||||
/* unmute: dispatch sound to scart output, set scart volume */
|
||||
msp_set_audio(client);
|
||||
@ -911,20 +978,33 @@ int msp34xxg_thread(void *data)
|
||||
if (msp_write_dsp(client, 0x13, state->acb))
|
||||
return -1;
|
||||
|
||||
if (state->has_i2s_conf)
|
||||
msp_write_dem(client, 0x40, state->i2s_mode);
|
||||
/* the periodic stereo/SAP check is only relevant for
|
||||
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");
|
||||
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);
|
||||
|
||||
int status = msp_read_dem(client, 0x0200);
|
||||
int is_bilingual = status & 0x100;
|
||||
int is_stereo = status & 0x40;
|
||||
int oldrx = state->rxsubchans;
|
||||
|
||||
state->rxsubchans = 0;
|
||||
if (is_stereo)
|
||||
@ -932,42 +1012,31 @@ static void msp34xxg_detect_stereo(struct i2c_client *client)
|
||||
else
|
||||
state->rxsubchans = V4L2_TUNER_SUB_MONO;
|
||||
if (is_bilingual) {
|
||||
state->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
|
||||
/* I'm supposed to check whether it's SAP or not
|
||||
* and set only LANG2/SAP in this case. Yet, the MSP
|
||||
* does a lot of work to hide this and handle everything
|
||||
* 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.
|
||||
*/
|
||||
if (state->std == 0x20)
|
||||
state->rxsubchans |= V4L2_TUNER_SUB_SAP;
|
||||
else
|
||||
state->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
|
||||
}
|
||||
v4l_dbg(1, msp_debug, client, "status=0x%x, stereo=%d, bilingual=%d -> rxsubchans=%d\n",
|
||||
status, is_stereo, is_bilingual, state->rxsubchans);
|
||||
return (oldrx != state->rxsubchans);
|
||||
}
|
||||
|
||||
static void msp34xxg_set_audmode(struct i2c_client *client)
|
||||
{
|
||||
struct msp_state *state = i2c_get_clientdata(client);
|
||||
int source;
|
||||
|
||||
switch (state->audmode) {
|
||||
case V4L2_TUNER_MODE_MONO:
|
||||
source = 0; /* mono only */
|
||||
break;
|
||||
case V4L2_TUNER_MODE_STEREO:
|
||||
source = 1; /* stereo or A|B, see comment in msp34xxg_get_v4l2_stereo() */
|
||||
/* problem: that could also mean 2 (scart input) */
|
||||
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;
|
||||
if (state->std == 0x20) {
|
||||
if ((state->rxsubchans & V4L2_TUNER_SUB_SAP) &&
|
||||
(state->audmode == V4L2_TUNER_MODE_STEREO ||
|
||||
state->audmode == V4L2_TUNER_MODE_LANG2)) {
|
||||
msp_write_dem(client, 0x20, 0x21);
|
||||
} else {
|
||||
msp_write_dem(client, 0x20, 0x20);
|
||||
}
|
||||
}
|
||||
msp34xxg_set_source(client, source);
|
||||
|
||||
msp34xxg_set_sources(client);
|
||||
}
|
||||
|
||||
void msp_set_audmode(struct i2c_client *client)
|
||||
@ -977,7 +1046,6 @@ void msp_set_audmode(struct i2c_client *client)
|
||||
switch (state->opmode) {
|
||||
case OPMODE_MANUAL:
|
||||
case OPMODE_AUTODETECT:
|
||||
state->watch_stereo = 0;
|
||||
msp3400c_set_audmode(client);
|
||||
break;
|
||||
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);
|
||||
|
||||
switch (state->opmode) {
|
||||
case OPMODE_MANUAL:
|
||||
case OPMODE_AUTODETECT:
|
||||
msp3400c_detect_stereo(client);
|
||||
break;
|
||||
return msp3400c_detect_stereo(client);
|
||||
case OPMODE_AUTOSELECT:
|
||||
msp34xxg_detect_stereo(client);
|
||||
break;
|
||||
return msp34xxg_detect_stereo(client);
|
||||
}
|
||||
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 */
|
||||
list_for_each(item,&mxb->i2c_adapter.clients) {
|
||||
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;
|
||||
if( I2C_TEA6420_2 == client->addr )
|
||||
if( I2C_ADDR_TEA6420_2 == client->addr )
|
||||
mxb->tea6420_2 = client;
|
||||
if( I2C_TEA6415C_2 == client->addr )
|
||||
mxb->tea6415c = client;
|
||||
if( I2C_TDA9840 == client->addr )
|
||||
if( I2C_ADDR_TDA9840 == client->addr )
|
||||
mxb->tda9840 = client;
|
||||
if( I2C_SAA7111 == client->addr )
|
||||
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"));
|
||||
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: {
|
||||
mxb->cur_mode = V4L2_TUNER_MODE_LANG1;
|
||||
byte = TDA9840_SET_LANG1;
|
||||
|
@ -15,7 +15,7 @@
|
||||
*
|
||||
* Based on the Linux CPiA driver written by Peter Pregler,
|
||||
* Scott J. Bertin and Johannes Erdfelt.
|
||||
*
|
||||
*
|
||||
* Please see the file: Documentation/usb/ov511.txt
|
||||
* and the website at: http://alpha.dyndns.org/ov511
|
||||
* for more info.
|
||||
@ -433,7 +433,7 @@ reg_w_mask(struct usb_ov511 *ov,
|
||||
return (reg_w(ov, reg, newval));
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* Writes multiple (n) byte value to a single register. Only valid with certain
|
||||
* registers (0x30 and 0xc4 - 0xce).
|
||||
*/
|
||||
@ -629,7 +629,7 @@ ov511_i2c_write_internal(struct usb_ov511 *ov,
|
||||
/* Retry until idle */
|
||||
do
|
||||
rc = reg_r(ov, R511_I2C_CTL);
|
||||
while (rc > 0 && ((rc&1) == 0));
|
||||
while (rc > 0 && ((rc&1) == 0));
|
||||
if (rc < 0)
|
||||
break;
|
||||
|
||||
@ -1752,7 +1752,7 @@ sensor_set_picture(struct usb_ov511 *ov, struct video_picture *p)
|
||||
ov->whiteness = p->whiteness;
|
||||
|
||||
/* 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);
|
||||
if (FATAL_ERROR(rc))
|
||||
@ -1781,7 +1781,7 @@ sensor_get_picture(struct usb_ov511 *ov, struct video_picture *p)
|
||||
PDEBUG(4, "sensor_get_picture");
|
||||
|
||||
/* 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));
|
||||
if (FATAL_ERROR(rc))
|
||||
@ -2251,7 +2251,7 @@ mode_init_ov_sensor_regs(struct usb_ov511 *ov, int width, int height,
|
||||
|
||||
/******** Clock programming ********/
|
||||
|
||||
/* The OV6620 needs special handling. This prevents the
|
||||
/* The OV6620 needs special handling. This prevents the
|
||||
* severe banding that normally occurs */
|
||||
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 ret;
|
||||
int hwsbase, hwebase, vwsbase, vwebase, hwsize, vwsize;
|
||||
int hwsbase, hwebase, vwsbase, vwebase, hwsize, vwsize;
|
||||
int hoffset, voffset, hwscale = 0, vwscale = 0;
|
||||
|
||||
/* 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 */
|
||||
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) */
|
||||
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
|
||||
*
|
||||
*/
|
||||
*/
|
||||
static void
|
||||
yuv400raw_to_yuv400p(struct ov511_frame *frame,
|
||||
unsigned char *pIn0, unsigned char *pOut0)
|
||||
@ -2923,7 +2923,7 @@ yuv400raw_to_yuv400p(struct ov511_frame *frame,
|
||||
*
|
||||
* 0 1 ... 7
|
||||
* 8 9 ... 15
|
||||
* ...
|
||||
* ...
|
||||
* 56 57 ... 63
|
||||
*
|
||||
* 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
|
||||
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 fieldpix = fieldheight * frame->rawwidth;
|
||||
@ -3112,7 +3112,7 @@ ov51x_postprocess_grey(struct usb_ov511 *ov, struct ov511_frame *frame)
|
||||
frame->tempdata);
|
||||
|
||||
deinterlace(frame, RAWFMT_YUV400, frame->tempdata,
|
||||
frame->data);
|
||||
frame->data);
|
||||
} else {
|
||||
if (frame->compressed)
|
||||
decompress(ov, frame, frame->rawdata,
|
||||
@ -3136,7 +3136,7 @@ ov51x_postprocess_yuv420(struct usb_ov511 *ov, struct ov511_frame *frame)
|
||||
frame->tempdata);
|
||||
|
||||
deinterlace(frame, RAWFMT_YUV420, frame->tempdata,
|
||||
frame->data);
|
||||
frame->data);
|
||||
} else {
|
||||
if (frame->compressed)
|
||||
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->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,
|
||||
frame->bytes_recvd);
|
||||
|
||||
@ -3527,10 +3527,10 @@ ov51x_isoc_irq(struct urb *urb, struct pt_regs *regs)
|
||||
return;
|
||||
}
|
||||
|
||||
if (urb->status == -ENOENT || urb->status == -ECONNRESET) {
|
||||
PDEBUG(4, "URB unlinked");
|
||||
return;
|
||||
}
|
||||
if (urb->status == -ENOENT || urb->status == -ECONNRESET) {
|
||||
PDEBUG(4, "URB unlinked");
|
||||
return;
|
||||
}
|
||||
|
||||
if (urb->status != -EINPROGRESS && urb->status != 0) {
|
||||
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);
|
||||
|
||||
if (size > (((OV511_NUMFRAMES
|
||||
* MAX_DATA_SIZE(ov->maxwidth, ov->maxheight)
|
||||
+ PAGE_SIZE - 1) & ~(PAGE_SIZE - 1))))
|
||||
* MAX_DATA_SIZE(ov->maxwidth, ov->maxheight)
|
||||
+ PAGE_SIZE - 1) & ~(PAGE_SIZE - 1))))
|
||||
return -EINVAL;
|
||||
|
||||
if (mutex_lock_interruptible(&ov->lock))
|
||||
@ -5062,7 +5062,7 @@ ov6xx0_configure(struct usb_ov511 *ov)
|
||||
}
|
||||
|
||||
/* This initializes the KS0127 and KS0127B video decoders. */
|
||||
static int
|
||||
static int
|
||||
ks0127_configure(struct usb_ov511 *ov)
|
||||
{
|
||||
int rc;
|
||||
@ -5193,7 +5193,7 @@ saa7111a_configure(struct usb_ov511 *ov)
|
||||
return -1;
|
||||
|
||||
/* 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);
|
||||
|
||||
if (rc < 0) {
|
||||
@ -5216,13 +5216,13 @@ saa7111a_configure(struct usb_ov511 *ov)
|
||||
}
|
||||
|
||||
/* This initializes the OV511/OV511+ and the sensor */
|
||||
static int
|
||||
static int
|
||||
ov511_configure(struct usb_ov511 *ov)
|
||||
{
|
||||
static struct ov511_regvals aRegvalsInit511[] = {
|
||||
{ OV511_REG_BUS, R51x_SYS_RESET, 0x7f },
|
||||
{ OV511_REG_BUS, R51x_SYS_INIT, 0x01 },
|
||||
{ OV511_REG_BUS, R51x_SYS_RESET, 0x7f },
|
||||
{ OV511_REG_BUS, R51x_SYS_INIT, 0x01 },
|
||||
{ OV511_REG_BUS, R51x_SYS_RESET, 0x7f },
|
||||
{ OV511_REG_BUS, R51x_SYS_INIT, 0x01 },
|
||||
{ OV511_REG_BUS, R51x_SYS_RESET, 0x3f },
|
||||
{ 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("manufacturer, model, and this number of your camera.");
|
||||
err("Also include the output of the detection process.");
|
||||
}
|
||||
}
|
||||
|
||||
if (ov->customid == 70) /* USB Life TV (PAL/SECAM) */
|
||||
ov->pal = 1;
|
||||
@ -5336,17 +5336,17 @@ ov511_configure(struct usb_ov511 *ov)
|
||||
|
||||
if (i2c_w(ov, 0x10, 0x00) < 0) {
|
||||
err("Can't determine sensor slave IDs");
|
||||
goto error;
|
||||
goto error;
|
||||
} else {
|
||||
if (ks0127_configure(ov) < 0) {
|
||||
err("Failed to configure KS0127");
|
||||
goto error;
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (saa7111a_configure(ov) < 0) {
|
||||
err("Failed to configure SAA7111A");
|
||||
goto error;
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -5356,13 +5356,13 @@ ov511_configure(struct usb_ov511 *ov)
|
||||
} else {
|
||||
if (ov6xx0_configure(ov) < 0) {
|
||||
err("Failed to configure OV6xx0");
|
||||
goto error;
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (ov7xx0_configure(ov) < 0) {
|
||||
err("Failed to configure OV7xx0");
|
||||
goto error;
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
@ -5381,12 +5381,12 @@ ov518_configure(struct usb_ov511 *ov)
|
||||
/* For 518 and 518+ */
|
||||
static struct ov511_regvals aRegvalsInit518[] = {
|
||||
{ OV511_REG_BUS, R51x_SYS_RESET, 0x40 },
|
||||
{ OV511_REG_BUS, R51x_SYS_INIT, 0xe1 },
|
||||
{ OV511_REG_BUS, R51x_SYS_RESET, 0x3e },
|
||||
{ OV511_REG_BUS, R51x_SYS_INIT, 0xe1 },
|
||||
{ OV511_REG_BUS, R51x_SYS_RESET, 0x3e },
|
||||
{ OV511_REG_BUS, R51x_SYS_INIT, 0xe1 },
|
||||
{ OV511_REG_BUS, R51x_SYS_RESET, 0x00 },
|
||||
{ OV511_REG_BUS, R51x_SYS_INIT, 0xe1 },
|
||||
{ OV511_REG_BUS, 0x46, 0x00 },
|
||||
{ OV511_REG_BUS, 0x46, 0x00 },
|
||||
{ OV511_REG_BUS, 0x5d, 0x03 },
|
||||
{ OV511_DONE_BUS, 0x0, 0x00},
|
||||
};
|
||||
@ -5517,7 +5517,7 @@ ov518_configure(struct usb_ov511 *ov)
|
||||
|
||||
if (init_ov_sensor(ov) < 0) {
|
||||
err("Can't determine sensor slave IDs");
|
||||
goto error;
|
||||
goto error;
|
||||
} else {
|
||||
err("Detected unsupported OV8xx0 sensor");
|
||||
goto error;
|
||||
@ -5525,13 +5525,13 @@ ov518_configure(struct usb_ov511 *ov)
|
||||
} else {
|
||||
if (ov6xx0_configure(ov) < 0) {
|
||||
err("Failed to configure OV6xx0");
|
||||
goto error;
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (ov7xx0_configure(ov) < 0) {
|
||||
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);
|
||||
return sprintf(buf, "%d\n", ov->customid);
|
||||
}
|
||||
}
|
||||
static CLASS_DEVICE_ATTR(custom_id, S_IRUGO, show_custom_id, NULL);
|
||||
|
||||
static ssize_t show_model(struct class_device *cd, char *buf)
|
||||
{
|
||||
struct usb_ov511 *ov = cd_to_ov(cd);
|
||||
return sprintf(buf, "%s\n", ov->desc);
|
||||
}
|
||||
}
|
||||
static CLASS_DEVICE_ATTR(model, S_IRUGO, show_model, NULL);
|
||||
|
||||
static ssize_t show_bridge(struct class_device *cd, char *buf)
|
||||
{
|
||||
struct usb_ov511 *ov = cd_to_ov(cd);
|
||||
return sprintf(buf, "%s\n", symbolic(brglist, ov->bridge));
|
||||
}
|
||||
}
|
||||
static CLASS_DEVICE_ATTR(bridge, S_IRUGO, show_bridge, NULL);
|
||||
|
||||
static ssize_t show_sensor(struct class_device *cd, char *buf)
|
||||
{
|
||||
struct usb_ov511 *ov = cd_to_ov(cd);
|
||||
return sprintf(buf, "%s\n", symbolic(senlist, ov->sensor));
|
||||
}
|
||||
}
|
||||
static CLASS_DEVICE_ATTR(sensor, S_IRUGO, show_sensor, NULL);
|
||||
|
||||
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;
|
||||
sensor_get_brightness(ov, &x);
|
||||
return sprintf(buf, "%d\n", x >> 8);
|
||||
}
|
||||
}
|
||||
static CLASS_DEVICE_ATTR(brightness, S_IRUGO, show_brightness, NULL);
|
||||
|
||||
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;
|
||||
sensor_get_saturation(ov, &x);
|
||||
return sprintf(buf, "%d\n", x >> 8);
|
||||
}
|
||||
}
|
||||
static CLASS_DEVICE_ATTR(saturation, S_IRUGO, show_saturation, NULL);
|
||||
|
||||
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;
|
||||
sensor_get_contrast(ov, &x);
|
||||
return sprintf(buf, "%d\n", x >> 8);
|
||||
}
|
||||
}
|
||||
static CLASS_DEVICE_ATTR(contrast, S_IRUGO, show_contrast, NULL);
|
||||
|
||||
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;
|
||||
sensor_get_hue(ov, &x);
|
||||
return sprintf(buf, "%d\n", x >> 8);
|
||||
}
|
||||
}
|
||||
static CLASS_DEVICE_ATTR(hue, S_IRUGO, show_hue, NULL);
|
||||
|
||||
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;
|
||||
sensor_get_exposure(ov, &exp);
|
||||
return sprintf(buf, "%d\n", exp >> 8);
|
||||
}
|
||||
}
|
||||
static CLASS_DEVICE_ATTR(exposure, S_IRUGO, show_exposure, NULL);
|
||||
|
||||
static void ov_create_sysfs(struct video_device *vdev)
|
@ -130,7 +130,7 @@
|
||||
#define R511_COMP_QVY 0x76
|
||||
#define R511_COMP_QVUV 0x77
|
||||
#define R511_COMP_EN 0x78
|
||||
#define R511_COMP_LUT_EN 0x79
|
||||
#define R511_COMP_LUT_EN 0x79
|
||||
#define R511_COMP_LUT_BEGIN 0x80
|
||||
|
||||
/* --------------------------------- */
|
||||
@ -459,14 +459,14 @@ struct usb_ov511 {
|
||||
int subh; /* Pix Array subcapture height */
|
||||
|
||||
int curframe; /* Current receiving sbuf */
|
||||
struct ov511_frame frame[OV511_NUMFRAMES];
|
||||
struct ov511_frame frame[OV511_NUMFRAMES];
|
||||
|
||||
struct ov511_sbuf sbuf[OV511_NUMSBUF];
|
||||
|
||||
wait_queue_head_t wq; /* Processes waiting */
|
||||
|
||||
int snap_enabled; /* Snapshot mode enabled */
|
||||
|
||||
|
||||
int bridge; /* Type of bridge (BRG_*) */
|
||||
int bclass; /* Class of bridge (BCL_*) */
|
||||
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
|
||||
* 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)
|
||||
{
|
||||
int i;
|
@ -1,4 +1,4 @@
|
||||
ovcamchip-objs := ovcamchip_core.o ov6x20.o ov6x30.o ov7x10.o ov7x20.o \
|
||||
ov76be.o
|
||||
ov76be.o
|
||||
|
||||
obj-$(CONFIG_VIDEO_OVCAMCHIP) += ovcamchip.o
|
||||
|
@ -266,17 +266,17 @@ static int ovcamchip_detect(struct i2c_client *c)
|
||||
PDEBUG(3, "Testing for 0V6xx0");
|
||||
c->addr = OV6xx0_SID;
|
||||
if (init_camchip(c) < 0) {
|
||||
return -ENODEV;
|
||||
return -ENODEV;
|
||||
} else {
|
||||
if (ov6xx0_detect(c) < 0) {
|
||||
PERROR("Failed to init OV6xx0");
|
||||
return -EIO;
|
||||
return -EIO;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (ov7xx0_detect(c) < 0) {
|
||||
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);
|
||||
|
||||
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
|
||||
|
@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
planb - PlanB frame grabber driver
|
||||
|
||||
PlanB is used in the 7x00/8x00 series of PowerMacintosh
|
||||
@ -584,7 +584,7 @@ finish:
|
||||
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;
|
||||
int xc = clip->x, yc = clip->y;
|
||||
@ -758,7 +758,7 @@ static void cmd_buff(struct planb *pb)
|
||||
PLANB_SET(CH_SYNC));
|
||||
tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel),
|
||||
PLANB_SET(DMA_ABORT));
|
||||
|
||||
|
||||
/* odd field data: */
|
||||
jump = virt_to_bus(c1 + nlines / 2);
|
||||
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_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel),
|
||||
PLANB_SET(DMA_ABORT));
|
||||
|
||||
|
||||
/* odd field data: */
|
||||
jump_addr = c1 + TAB_FACTOR * nlines / 2;
|
||||
jump = virt_to_bus(jump_addr);
|
||||
@ -1383,7 +1383,7 @@ static int planb_open(struct video_device *dev, int mode)
|
||||
pb->user++;
|
||||
|
||||
DEBUG("PlanB: device opened\n");
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
struct planb *pb=(struct planb *)dev;
|
||||
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
{
|
||||
case VIDIOCGCAP:
|
||||
{
|
||||
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.audios = 0;
|
||||
b.maxwidth = PLANB_MAXPIXELS;
|
||||
b.maxheight = PLANB_MAXLINES;
|
||||
b.minwidth = 32; /* wild guess */
|
||||
b.minheight = 32;
|
||||
if (copy_to_user(arg,&b,sizeof(b)))
|
||||
return -EFAULT;
|
||||
b.maxheight = PLANB_MAXLINES;
|
||||
b.minwidth = 32; /* wild guess */
|
||||
b.minheight = 32;
|
||||
if (copy_to_user(arg,&b,sizeof(b)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
case VIDIOCSFBUF:
|
||||
{
|
||||
struct video_buffer v;
|
||||
struct video_buffer v;
|
||||
unsigned short bpp;
|
||||
unsigned int fmt;
|
||||
|
||||
DEBUG("PlanB: IOCTL VIDIOCSFBUF\n");
|
||||
|
||||
if (!capable(CAP_SYS_ADMIN)
|
||||
if (!capable(CAP_SYS_ADMIN)
|
||||
|| !capable(CAP_SYS_RAWIO))
|
||||
return -EPERM;
|
||||
if (copy_from_user(&v, arg,sizeof(v)))
|
||||
return -EFAULT;
|
||||
return -EPERM;
|
||||
if (copy_from_user(&v, arg,sizeof(v)))
|
||||
return -EFAULT;
|
||||
planb_lock(pb);
|
||||
switch(v.depth) {
|
||||
case 8:
|
||||
@ -1478,7 +1478,7 @@ static int planb_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
|
||||
break;
|
||||
default:
|
||||
planb_unlock(pb);
|
||||
return -EINVAL;
|
||||
return -EINVAL;
|
||||
}
|
||||
if (bpp * v.width > v.bytesperline) {
|
||||
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.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,
|
||||
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);
|
||||
}
|
||||
planb_unlock(pb);
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
case VIDIOCGFBUF:
|
||||
{
|
||||
struct video_buffer v;
|
||||
struct video_buffer v;
|
||||
|
||||
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.bytesperline = pb->win.bpl + pb->win.pad;
|
||||
if (copy_to_user(arg, &v, sizeof(v)))
|
||||
return -EFAULT;
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
case VIDIOCCAPTURE:
|
||||
{
|
||||
int i;
|
||||
|
||||
if(copy_from_user(&i, arg, sizeof(i)))
|
||||
return -EFAULT;
|
||||
if(copy_from_user(&i, arg, sizeof(i)))
|
||||
return -EFAULT;
|
||||
if(i==0) {
|
||||
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_clip clip;
|
||||
int i;
|
||||
|
||||
|
||||
DEBUG("PlanB: IOCTL VIDIOCSWIN\n");
|
||||
|
||||
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 0;
|
||||
}
|
||||
case VIDIOCSYNC: {
|
||||
case VIDIOCSYNC: {
|
||||
int i;
|
||||
|
||||
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);
|
||||
|
||||
if(i > (MAX_GBUFFERS - 1) || i < 0)
|
||||
return -EINVAL;
|
||||
if(i > (MAX_GBUFFERS - 1) || i < 0)
|
||||
return -EINVAL;
|
||||
chk_grab:
|
||||
switch (pb->frame_stat[i]) {
|
||||
case GBUFFER_UNUSED:
|
||||
return -EINVAL;
|
||||
switch (pb->frame_stat[i]) {
|
||||
case GBUFFER_UNUSED:
|
||||
return -EINVAL;
|
||||
case GBUFFER_GRABBING:
|
||||
IDEBUG("PlanB: waiting for grab"
|
||||
" done (%d)\n", i);
|
||||
interruptible_sleep_on(&pb->capq);
|
||||
interruptible_sleep_on(&pb->capq);
|
||||
if(signal_pending(current))
|
||||
return -EINTR;
|
||||
goto chk_grab;
|
||||
case GBUFFER_DONE:
|
||||
pb->frame_stat[i] = GBUFFER_UNUSED;
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
case GBUFFER_DONE:
|
||||
pb->frame_stat[i] = GBUFFER_UNUSED;
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
case VIDIOCMCAPTURE:
|
||||
case VIDIOCMCAPTURE:
|
||||
{
|
||||
struct video_mmap vm;
|
||||
struct video_mmap vm;
|
||||
volatile unsigned int status;
|
||||
|
||||
IDEBUG("PlanB: IOCTL VIDIOCMCAPTURE\n");
|
||||
|
||||
if(copy_from_user((void *) &vm,(void *)arg,sizeof(vm)))
|
||||
return -EFAULT;
|
||||
status = pb->frame_stat[vm.frame];
|
||||
if (status != GBUFFER_UNUSED)
|
||||
return -EBUSY;
|
||||
status = pb->frame_stat[vm.frame];
|
||||
if (status != GBUFFER_UNUSED)
|
||||
return -EBUSY;
|
||||
|
||||
return vgrab(pb, &vm);
|
||||
return vgrab(pb, &vm);
|
||||
}
|
||||
|
||||
|
||||
case VIDIOCGMBUF:
|
||||
{
|
||||
int i;
|
||||
@ -1811,7 +1811,7 @@ chk_grab:
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
case PLANBIOCGSAAREGS:
|
||||
{
|
||||
struct planb_saa_regs preg;
|
||||
@ -1828,7 +1828,7 @@ chk_grab:
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
case PLANBIOCSSAAREGS:
|
||||
{
|
||||
struct planb_saa_regs preg;
|
||||
@ -1842,7 +1842,7 @@ chk_grab:
|
||||
saa_set (preg.addr, preg.val, pb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
case PLANBIOCGSTAT:
|
||||
{
|
||||
struct planb_stat_regs pstat;
|
||||
@ -1859,7 +1859,7 @@ chk_grab:
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
case PLANBIOCSMODE: {
|
||||
int v;
|
||||
|
||||
@ -1985,10 +1985,10 @@ static int planb_mmap(struct vm_area_struct *vma, struct video_device *dev, cons
|
||||
{
|
||||
int i;
|
||||
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)
|
||||
return -EINVAL;
|
||||
return -EINVAL;
|
||||
if (!pb->rawbuf) {
|
||||
int err;
|
||||
if((err=grabbuf_alloc(pb)))
|
||||
@ -2091,10 +2091,10 @@ static int init_planb(struct planb *pb)
|
||||
/* clear interrupt mask */
|
||||
pb->intr_mask = PLANB_CLR_IRQ;
|
||||
|
||||
result = request_irq(pb->irq, planb_irq, 0, "PlanB", (void *)pb);
|
||||
if (result < 0) {
|
||||
if (result==-EINVAL)
|
||||
printk(KERN_ERR "PlanB: Bad irq number (%d) "
|
||||
result = request_irq(pb->irq, planb_irq, 0, "PlanB", (void *)pb);
|
||||
if (result < 0) {
|
||||
if (result==-EINVAL)
|
||||
printk(KERN_ERR "PlanB: Bad irq number (%d) "
|
||||
"or handler\n", (int)pb->irq);
|
||||
else if (result==-EBUSY)
|
||||
printk(KERN_ERR "PlanB: I don't know why, "
|
||||
@ -2102,7 +2102,7 @@ static int init_planb(struct planb *pb)
|
||||
return result;
|
||||
}
|
||||
disable_irq(pb->irq);
|
||||
|
||||
|
||||
/* Now add the template and register the device unit. */
|
||||
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)
|
||||
@ -2171,9 +2171,9 @@ static int find_planb(void)
|
||||
pb = &planbs[0];
|
||||
planb_num = 1;
|
||||
|
||||
if (planb_devices->n_addrs != 1) {
|
||||
printk (KERN_WARNING "PlanB: expecting 1 address for planb "
|
||||
"(got %d)", planb_devices->n_addrs);
|
||||
if (planb_devices->n_addrs != 1) {
|
||||
printk (KERN_WARNING "PlanB: expecting 1 address for planb "
|
||||
"(got %d)", planb_devices->n_addrs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2236,7 +2236,7 @@ static int find_planb(void)
|
||||
pb->planb_base = planb_regs;
|
||||
pb->planb_base_phys = (struct planb_registers *)new_base;
|
||||
pb->irq = irq;
|
||||
|
||||
|
||||
return planb_num;
|
||||
|
||||
err_out_disable:
|
||||
@ -2251,7 +2251,7 @@ static void release_planb(void)
|
||||
int i;
|
||||
struct planb *pb;
|
||||
|
||||
for (i=0;i<planb_num; i++)
|
||||
for (i=0;i<planb_num; i++)
|
||||
{
|
||||
pb=&planbs[i];
|
||||
|
||||
@ -2278,7 +2278,7 @@ static void release_planb(void)
|
||||
static int __init init_planbs(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
||||
if (find_planb()<=0)
|
||||
return -EIO;
|
||||
|
||||
@ -2288,9 +2288,9 @@ static int __init init_planbs(void)
|
||||
" with v4l\n", i);
|
||||
release_planb();
|
||||
return -EIO;
|
||||
}
|
||||
}
|
||||
printk(KERN_INFO "PlanB: registered device %d with v4l\n", i);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
planb - PlanB frame grabber driver
|
||||
|
||||
PlanB is used in the 7x00/8x00 series of PowerMacintosh
|
||||
@ -167,7 +167,7 @@ struct planb {
|
||||
struct video_device video_dev;
|
||||
struct video_picture picture; /* Current picture params */
|
||||
struct video_audio audio_dev; /* Current audio params */
|
||||
|
||||
|
||||
volatile struct planb_registers *planb_base; /* virt base of planb */
|
||||
struct planb_registers *planb_base_phys; /* phys base of planb */
|
||||
void *priv_space; /* Org. alloc. mem for kfree */
|
||||
@ -209,7 +209,7 @@ struct planb {
|
||||
int gwidth[MAX_GBUFFERS], gheight[MAX_GBUFFERS];
|
||||
unsigned int gfmt[MAX_GBUFFERS];
|
||||
int gnorm_switch[MAX_GBUFFERS];
|
||||
volatile unsigned int *frame_stat;
|
||||
volatile unsigned int *frame_stat;
|
||||
#define GBUFFER_UNUSED 0x00U
|
||||
#define GBUFFER_GRABBING 0x01U
|
||||
#define GBUFFER_DONE 0x02U
|
||||
|
@ -12,10 +12,10 @@
|
||||
* Most of this code is directly derived from his userspace driver.
|
||||
* His driver works so send any reports to alan@redhat.com unless the
|
||||
* userspace driver also doesn't work for you...
|
||||
*
|
||||
*
|
||||
* Changes:
|
||||
* 08/07/2003 Daniele Bellucci <bellucda@tiscali.it>
|
||||
* - pms_capture: report back -EFAULT
|
||||
* - pms_capture: report back -EFAULT
|
||||
*/
|
||||
|
||||
#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
|
||||
*/
|
||||
|
||||
|
||||
static int io_port = 0x250;
|
||||
static int data_port = 0x251;
|
||||
static int mem_base = 0xC8000;
|
||||
static void __iomem *mem;
|
||||
static int video_nr = -1;
|
||||
|
||||
|
||||
|
||||
|
||||
static inline void mvv_write(u8 index, u8 value)
|
||||
{
|
||||
@ -90,9 +90,9 @@ static int pms_i2c_stat(u8 slave)
|
||||
{
|
||||
int counter;
|
||||
int i;
|
||||
|
||||
|
||||
outb(0x28, io_port);
|
||||
|
||||
|
||||
counter=0;
|
||||
while((inb(data_port)&0x01)==0)
|
||||
if(counter++==256)
|
||||
@ -101,9 +101,9 @@ static int pms_i2c_stat(u8 slave)
|
||||
while((inb(data_port)&0x01)!=0)
|
||||
if(counter++==256)
|
||||
break;
|
||||
|
||||
|
||||
outb(slave, io_port);
|
||||
|
||||
|
||||
counter=0;
|
||||
while((inb(data_port)&0x01)==0)
|
||||
if(counter++==256)
|
||||
@ -112,7 +112,7 @@ static int pms_i2c_stat(u8 slave)
|
||||
while((inb(data_port)&0x01)!=0)
|
||||
if(counter++==256)
|
||||
break;
|
||||
|
||||
|
||||
for(i=0;i<12;i++)
|
||||
{
|
||||
char st=inb(data_port);
|
||||
@ -122,7 +122,7 @@ static int pms_i2c_stat(u8 slave)
|
||||
break;
|
||||
}
|
||||
outb(0x29, io_port);
|
||||
return inb(data_port);
|
||||
return inb(data_port);
|
||||
}
|
||||
|
||||
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 count;
|
||||
int i;
|
||||
|
||||
|
||||
for(i=0;i<i2c_count;i++)
|
||||
{
|
||||
if((i2cinfo[i].slave==slave) &&
|
||||
(i2cinfo[i].sub == sub))
|
||||
{
|
||||
if(i2cinfo[i].data==data)
|
||||
skip=1;
|
||||
i2cinfo[i].data=data;
|
||||
i=i2c_count+1;
|
||||
if(i2cinfo[i].data==data)
|
||||
skip=1;
|
||||
i2cinfo[i].data=data;
|
||||
i=i2c_count+1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(i==i2c_count && i2c_count<64)
|
||||
{
|
||||
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;
|
||||
i2c_count++;
|
||||
}
|
||||
|
||||
|
||||
if(skip)
|
||||
return 0;
|
||||
|
||||
|
||||
mvv_write(0x29, sub);
|
||||
mvv_write(0x2A, data);
|
||||
mvv_write(0x28, slave);
|
||||
|
||||
|
||||
outb(0x28, io_port);
|
||||
|
||||
|
||||
count=0;
|
||||
while((inb(data_port)&1)==0)
|
||||
if(count>255)
|
||||
@ -167,9 +167,9 @@ static int pms_i2c_write(u16 slave, u16 sub, u16 data)
|
||||
while((inb(data_port)&1)!=0)
|
||||
if(count>255)
|
||||
break;
|
||||
|
||||
|
||||
count=inb(data_port);
|
||||
|
||||
|
||||
if(count&2)
|
||||
return -1;
|
||||
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)
|
||||
{
|
||||
u8 tmp;
|
||||
|
||||
u8 tmp;
|
||||
|
||||
tmp=pms_i2c_read(slave, sub);
|
||||
tmp = (tmp&and)|or;
|
||||
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
|
||||
*/
|
||||
|
||||
|
||||
|
||||
static void pms_videosource(short source)
|
||||
{
|
||||
@ -234,8 +234,8 @@ static void pms_colour(short colour)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static void pms_contrast(short contrast)
|
||||
{
|
||||
switch(decoder)
|
||||
@ -269,14 +269,14 @@ static void pms_format(short format)
|
||||
{
|
||||
int target;
|
||||
standard = format;
|
||||
|
||||
|
||||
if(decoder==PHILIPS1)
|
||||
target=0x42;
|
||||
else if(decoder==PHILIPS2)
|
||||
target=0x8A;
|
||||
else
|
||||
return;
|
||||
|
||||
|
||||
switch(format)
|
||||
{
|
||||
case 0: /* Auto */
|
||||
@ -302,7 +302,7 @@ static void pms_format(short format)
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
@ -324,7 +324,7 @@ static void pms_hstart(short start)
|
||||
/*
|
||||
* Bandpass filters
|
||||
*/
|
||||
|
||||
|
||||
static void pms_bandpass(short pass)
|
||||
{
|
||||
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
|
||||
*/
|
||||
|
||||
|
||||
static void pms_vertdeci(unsigned short decinum, unsigned short deciden)
|
||||
{
|
||||
/* Knock it down by /5 once */
|
||||
@ -546,7 +546,7 @@ static void pms_horzdeci(short decinum, short deciden)
|
||||
decinum=512;
|
||||
deciden=640; /* 768 would be ideal */
|
||||
}
|
||||
|
||||
|
||||
while(((decinum|deciden)&1)==0)
|
||||
{
|
||||
decinum>>=1;
|
||||
@ -559,7 +559,7 @@ static void pms_horzdeci(short decinum, short deciden)
|
||||
}
|
||||
if(deciden==32)
|
||||
deciden--;
|
||||
|
||||
|
||||
mvv_write(0x24, 0x80|deciden);
|
||||
mvv_write(0x25, decinum);
|
||||
}
|
||||
@ -567,14 +567,14 @@ static void pms_horzdeci(short decinum, short deciden)
|
||||
static void pms_resolution(short width, short height)
|
||||
{
|
||||
int fg_height;
|
||||
|
||||
|
||||
fg_height=height;
|
||||
if(fg_height>280)
|
||||
fg_height=280;
|
||||
|
||||
|
||||
mvv_write(0x18, fg_height);
|
||||
mvv_write(0x19, fg_height>>8);
|
||||
|
||||
|
||||
if(standard==1)
|
||||
{
|
||||
mvv_write(0x1A, 0xFC);
|
||||
@ -598,7 +598,7 @@ static void pms_resolution(short width, short height)
|
||||
mvv_write(0x42, 0x00);
|
||||
mvv_write(0x43, 0x00);
|
||||
mvv_write(0x44, MVVMEMORYWIDTH);
|
||||
|
||||
|
||||
mvv_write(0x22, width+8);
|
||||
mvv_write(0x23, (width+8)>> 8);
|
||||
|
||||
@ -618,7 +618,7 @@ static void pms_resolution(short width, short height)
|
||||
/*
|
||||
* Set Input
|
||||
*/
|
||||
|
||||
|
||||
static void pms_vcrinput(short input)
|
||||
{
|
||||
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 */
|
||||
|
||||
/* 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 */
|
||||
|
||||
|
||||
/*
|
||||
* This is in truth a fifo, be very careful as if you
|
||||
* forgot this odd things will occur 8)
|
||||
*/
|
||||
|
||||
|
||||
memcpy_fromio(tmp, mem, dw+32); /* discard 16 word */
|
||||
cnt -= dev->height;
|
||||
while (cnt <= 0)
|
||||
{
|
||||
while (cnt <= 0)
|
||||
{
|
||||
/*
|
||||
* 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;
|
||||
if (copy_to_user(buf, tmp+32, dt))
|
||||
return len ? len : -EFAULT;
|
||||
buf += dt;
|
||||
buf += 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 pms_device *pd=(struct pms_device *)dev;
|
||||
|
||||
|
||||
switch(cmd)
|
||||
{
|
||||
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)))
|
||||
return -EINVAL;
|
||||
pd->picture= *p;
|
||||
|
||||
|
||||
/*
|
||||
* 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_hue(p->hue>>8);
|
||||
pms_colour(p->colour>>8);
|
||||
pms_contrast(p->contrast>>8);
|
||||
pms_contrast(p->contrast>>8);
|
||||
mutex_unlock(&pd->lock);
|
||||
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 pms_device *pd=(struct pms_device *)v;
|
||||
int len;
|
||||
|
||||
|
||||
mutex_lock(&pd->lock);
|
||||
len=pms_capture(pd, buf, (pd->picture.depth==16)?0:1,count);
|
||||
mutex_unlock(&pd->lock);
|
||||
@ -905,13 +905,13 @@ static struct pms_device pms_device;
|
||||
/*
|
||||
* Probe for and initialise the Mediavision PMS
|
||||
*/
|
||||
|
||||
|
||||
static int init_mediavision(void)
|
||||
{
|
||||
int id;
|
||||
int idec, decst;
|
||||
int i;
|
||||
|
||||
|
||||
unsigned char i2c_defs[]={
|
||||
0x4C,0x30,0x00,0xE8,
|
||||
0xB6,0xE2,0x00,0x00,
|
||||
@ -925,7 +925,7 @@ static int init_mediavision(void)
|
||||
mem = ioremap(mem_base, 0x800);
|
||||
if (!mem)
|
||||
return -ENOMEM;
|
||||
|
||||
|
||||
if (!request_region(0x9A01, 1, "Mediavision PMS config"))
|
||||
{
|
||||
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(io_port>>4, 0x9A01); /* Set IO port */
|
||||
|
||||
|
||||
|
||||
|
||||
id=mvv_read(3);
|
||||
decst=pms_i2c_stat(0x43);
|
||||
|
||||
|
||||
if(decst!=-1)
|
||||
idec=2;
|
||||
else if(pms_i2c_stat(0xb9)!=-1)
|
||||
idec=3;
|
||||
else if(pms_i2c_stat(0x8b)!=-1)
|
||||
idec=1;
|
||||
else
|
||||
else
|
||||
idec=0;
|
||||
|
||||
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
|
||||
*/
|
||||
|
||||
|
||||
mvv_write(0x04, mem_base>>12); /* Set the memory area */
|
||||
|
||||
|
||||
/* Ok now load the defaults */
|
||||
|
||||
|
||||
for(i=0;i<0x19;i++)
|
||||
{
|
||||
if(i2c_defs[i]==0xFF)
|
||||
@ -978,7 +978,7 @@ static int init_mediavision(void)
|
||||
else
|
||||
pms_i2c_write(0x8A, i, i2c_defs[i]);
|
||||
}
|
||||
|
||||
|
||||
pms_i2c_write(0xB8,0x00,0x12);
|
||||
pms_i2c_write(0xB8,0x04,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,0x0B,0x10);
|
||||
pms_i2c_write(0xB8,0x10,0x03);
|
||||
|
||||
|
||||
mvv_write(0x01, 0x00);
|
||||
mvv_write(0x05, 0xA0);
|
||||
mvv_write(0x08, 0x25);
|
||||
mvv_write(0x09, 0x00);
|
||||
mvv_write(0x0A, 0x20|MVVMEMORYWIDTH);
|
||||
|
||||
mvv_write(0x0A, 0x20|MVVMEMORYWIDTH);
|
||||
|
||||
mvv_write(0x10, 0x02);
|
||||
mvv_write(0x1E, 0x0C);
|
||||
mvv_write(0x1F, 0x03);
|
||||
mvv_write(0x26, 0x06);
|
||||
|
||||
|
||||
mvv_write(0x2B, 0x00);
|
||||
mvv_write(0x2C, 0x20);
|
||||
mvv_write(0x2D, 0x00);
|
||||
@ -1018,13 +1018,13 @@ static int init_mediavision(void)
|
||||
/*
|
||||
* Initialization and module stuff
|
||||
*/
|
||||
|
||||
|
||||
static int __init init_pms_cards(void)
|
||||
{
|
||||
printk(KERN_INFO "Mediavision Pro Movie Studio driver 0.02\n");
|
||||
|
||||
|
||||
data_port = io_port +1;
|
||||
|
||||
|
||||
if(init_mediavision())
|
||||
{
|
||||
printk(KERN_INFO "Board not found.\n");
|
||||
|
@ -15,6 +15,6 @@ default:
|
||||
endif
|
||||
|
||||
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
|
||||
|
@ -47,17 +47,17 @@ don't know how to set it properly in the driver. The options are:
|
||||
size
|
||||
Can be one of 'sqcif', 'qsif', 'qcif', 'sif', 'cif' or
|
||||
'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).
|
||||
|
||||
fps
|
||||
Specifies the desired framerate. Is an integer in the range of 4-30.
|
||||
|
||||
fbufs
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
reasonable. You can set it between 2 and 5.
|
||||
|
||||
mbufs
|
||||
@ -65,9 +65,9 @@ mbufs
|
||||
buffers to reserve for mmap(), VIDIOCCGMBUF, VIDIOCMCAPTURE and friends.
|
||||
The default is 2, which is adequate for most applications (double
|
||||
buffering).
|
||||
|
||||
|
||||
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
|
||||
slack when your program is behind. But you need a multi-threaded or
|
||||
forked program to really take advantage of these buffers.
|
||||
@ -88,15 +88,15 @@ power_save
|
||||
|
||||
compression (only useful with the plugin)
|
||||
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:
|
||||
0 = prefer uncompressed images; if the requested mode is not available
|
||||
in an uncompressed format, the driver will silently switch to low
|
||||
compression.
|
||||
in an uncompressed format, the driver will silently switch to low
|
||||
compression.
|
||||
1 = low compression.
|
||||
2 = medium compression.
|
||||
3 = high compression.
|
||||
|
||||
|
||||
High compression takes less bandwidth of course, but it could also
|
||||
introduce some unwanted artefacts. The default is 2, medium compression.
|
||||
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:
|
||||
|
||||
leds=500,500
|
||||
|
||||
|
||||
will blink the LED once every second. But with:
|
||||
|
||||
leds=0,0
|
||||
@ -123,7 +123,7 @@ leds
|
||||
when the camera is not used anymore.
|
||||
|
||||
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.
|
||||
|
||||
Finally: this parameters does not take effect UNTIL the first time you
|
||||
@ -144,35 +144,35 @@ dev_hint
|
||||
format:
|
||||
|
||||
[type[.serialnumber]:]node
|
||||
|
||||
|
||||
The square brackets mean that both the type and the serialnumber are
|
||||
optional, but a serialnumber cannot be specified without a type (which
|
||||
would be rather pointless). The serialnumber is separated from the type
|
||||
by a '.'; the node number by a ':'.
|
||||
|
||||
|
||||
This somewhat cryptic syntax is best explained by a few examples:
|
||||
|
||||
dev_hint=3,5 The first detected cam gets assigned
|
||||
/dev/video3, the second /dev/video5. Any
|
||||
other cameras will get the first free
|
||||
available slot (see below).
|
||||
/dev/video3, the second /dev/video5. Any
|
||||
other cameras will get the first free
|
||||
available slot (see below).
|
||||
|
||||
dev_hint=645:1,680:2 The PCA645 camera will get /dev/video1,
|
||||
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.
|
||||
and a PCVC680 /dev/video2.
|
||||
|
||||
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.
|
||||
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
|
||||
next 3 Philips cams will use /dev/video4
|
||||
through /dev/video6.
|
||||
|
||||
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).
|
||||
- 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.
|
||||
- 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
|
||||
@ -186,13 +186,13 @@ trace
|
||||
kernel log at debug level.
|
||||
|
||||
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.
|
||||
|
||||
Value Value Description Default
|
||||
(dec) (hex)
|
||||
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
|
||||
|
||||
@ -203,7 +203,7 @@ trace
|
||||
16 0x10 Memory allocation of buffers, etc. Off
|
||||
|
||||
32 0x20 Showing underflow, overflow and Dumping frame On
|
||||
messages
|
||||
messages
|
||||
|
||||
64 0x40 Show viewport and image sizes Off
|
||||
|
||||
@ -217,7 +217,7 @@ trace
|
||||
|
||||
|
||||
Example:
|
||||
|
||||
|
||||
# modprobe pwc size=cif fps=15 power_save=1
|
||||
|
||||
The fbufs, mbufs and trace parameters are global and apply to all connected
|
@ -31,17 +31,17 @@
|
||||
|
||||
/*
|
||||
Changes
|
||||
2001/08/03 Alvarado Added methods for changing white balance and
|
||||
red/green gains
|
||||
2001/08/03 Alvarado Added methods for changing white balance and
|
||||
red/green gains
|
||||
*/
|
||||
|
||||
/* Control functions for the cam; brightness, contrast, video mode, etc. */
|
||||
|
||||
#ifdef __KERNEL__
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/uaccess.h>
|
||||
#endif
|
||||
#include <asm/errno.h>
|
||||
|
||||
|
||||
#include "pwc.h"
|
||||
#include "pwc-ioctl.h"
|
||||
#include "pwc-uncompress.h"
|
||||
@ -116,13 +116,13 @@ static const char *size2name[PSZ_MAX] =
|
||||
"SIF",
|
||||
"CIF",
|
||||
"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.
|
||||
|
||||
|
||||
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 */
|
||||
0, 0, 0, 0, 4, /* 0-4 */
|
||||
5, 5, 7, 7, 10, /* 5-9 */
|
||||
10, 10, 12, 12, 15, /* 10-14 */
|
||||
15, 15, 15, 20, 20, /* 15-19 */
|
||||
20, 20, 20, 24, 24, /* 20-24 */
|
||||
24, 24, 24, 24, 24, /* 25-29 */
|
||||
24 /* 30 */
|
||||
10, 10, 12, 12, 15, /* 10-14 */
|
||||
15, 15, 15, 20, 20, /* 15-19 */
|
||||
20, 20, 20, 24, 24, /* 20-24 */
|
||||
24, 24, 24, 24, 24, /* 25-29 */
|
||||
24 /* 30 */
|
||||
};
|
||||
int frames2table[31] =
|
||||
int frames2table[31] =
|
||||
{ 0, 0, 0, 0, 0, /* 0-4 */
|
||||
1, 1, 1, 2, 2, /* 5-9 */
|
||||
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 /* 30 */
|
||||
};
|
||||
|
||||
|
||||
if (size < 0 || size > PSZ_CIF || frames < 4 || frames > 25)
|
||||
return -EINVAL;
|
||||
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)
|
||||
return -ENOENT; /* Not supported. */
|
||||
|
||||
memcpy(buf, pEntry->mode, 3);
|
||||
memcpy(buf, pEntry->mode, 3);
|
||||
ret = send_video_command(pdev->udev, pdev->vendpoint, buf, 3);
|
||||
if (ret < 0) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pdev->cmd_len = 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 */
|
||||
if (size == PSZ_VGA && frames == 5 && snapshot)
|
||||
{
|
||||
/* Only available in case the raw palette is selected or
|
||||
we have the decompressor available. This mode is
|
||||
only available in compressed form
|
||||
/* Only available in case the raw palette is selected or
|
||||
we have the decompressor available. This mode is
|
||||
only available in compressed form
|
||||
*/
|
||||
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;
|
||||
}
|
||||
else
|
||||
@ -368,9 +368,9 @@ static inline int set_video_mode_Kiara(struct pwc_device *pdev, int size, int fr
|
||||
}
|
||||
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.
|
||||
Skip this step when using RAW modes.
|
||||
Skip this step when using RAW modes.
|
||||
*/
|
||||
while (compression <= 3) {
|
||||
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. */
|
||||
|
||||
Debug("Using alternate setting %d.\n", pChoose->alternate);
|
||||
|
||||
|
||||
/* usb_control_msg won't take staticly allocated arrays as argument?? */
|
||||
memcpy(buf, pChoose->mode, 12);
|
||||
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 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);
|
||||
if (size < 0) {
|
||||
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);
|
||||
|
||||
ret = -EINVAL;
|
||||
ret = -EINVAL;
|
||||
switch(pdev->type) {
|
||||
case 645:
|
||||
case 646:
|
||||
@ -485,7 +485,7 @@ int pwc_set_video_mode(struct pwc_device *pdev, int width, int height, int frame
|
||||
case 690:
|
||||
ret = set_video_mode_Timon(pdev, size, frames, compression, snapshot);
|
||||
break;
|
||||
|
||||
|
||||
case 720:
|
||||
case 730:
|
||||
case 740:
|
||||
@ -517,7 +517,7 @@ int pwc_get_brightness(struct pwc_device *pdev)
|
||||
char buf;
|
||||
int ret;
|
||||
|
||||
ret = RecvControlMsg(GET_LUM_CTL, BRIGHTNESS_FORMATTER, 1);
|
||||
ret = RecvControlMsg(GET_LUM_CTL, BRIGHTNESS_FORMATTER, 1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
return buf << 9;
|
||||
@ -566,7 +566,7 @@ int pwc_get_gamma(struct pwc_device *pdev)
|
||||
{
|
||||
char buf;
|
||||
int ret;
|
||||
|
||||
|
||||
ret = RecvControlMsg(GET_LUM_CTL, GAMMA_FORMATTER, 1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
@ -622,14 +622,14 @@ static inline int pwc_set_agc(struct pwc_device *pdev, int mode, int value)
|
||||
{
|
||||
char buf;
|
||||
int ret;
|
||||
|
||||
|
||||
if (mode)
|
||||
buf = 0x0; /* auto */
|
||||
else
|
||||
buf = 0xff; /* fixed */
|
||||
|
||||
ret = SendControlMsg(SET_LUM_CTL, AGC_MODE_FORMATTER, 1);
|
||||
|
||||
|
||||
if (!mode && ret >= 0) {
|
||||
if (value < 0)
|
||||
value = 0;
|
||||
@ -647,7 +647,7 @@ static inline int pwc_get_agc(struct pwc_device *pdev, int *value)
|
||||
{
|
||||
unsigned char buf;
|
||||
int ret;
|
||||
|
||||
|
||||
ret = RecvControlMsg(GET_LUM_CTL, AGC_MODE_FORMATTER, 1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
@ -658,7 +658,7 @@ static inline int pwc_get_agc(struct pwc_device *pdev, int *value)
|
||||
return ret;
|
||||
if (buf > 0x3F)
|
||||
buf = 0x3F;
|
||||
*value = (buf << 10);
|
||||
*value = (buf << 10);
|
||||
}
|
||||
else { /* auto */
|
||||
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 */
|
||||
else
|
||||
buf[0] = 0xff; /* fixed */
|
||||
|
||||
|
||||
ret = SendControlMsg(SET_LUM_CTL, SHUTTER_MODE_FORMATTER, 1);
|
||||
|
||||
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);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* POWER */
|
||||
@ -765,22 +765,22 @@ static inline int pwc_restore_factory(struct pwc_device *pdev)
|
||||
* 02: fluorescent lighting
|
||||
* 03: manual
|
||||
* 04: auto
|
||||
*/
|
||||
*/
|
||||
static inline int pwc_set_awb(struct pwc_device *pdev, int mode)
|
||||
{
|
||||
char buf;
|
||||
int ret;
|
||||
|
||||
|
||||
if (mode < 0)
|
||||
mode = 0;
|
||||
|
||||
|
||||
if (mode > 4)
|
||||
mode = 4;
|
||||
|
||||
|
||||
buf = mode & 0x07; /* just the lowest three bits */
|
||||
|
||||
|
||||
ret = SendControlMsg(SET_CHROM_CTL, WB_MODE_FORMATTER, 1);
|
||||
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
return 0;
|
||||
@ -790,17 +790,17 @@ static inline int pwc_get_awb(struct pwc_device *pdev)
|
||||
{
|
||||
unsigned char buf;
|
||||
int ret;
|
||||
|
||||
|
||||
ret = RecvControlMsg(GET_CHROM_CTL, WB_MODE_FORMATTER, 1);
|
||||
|
||||
if (ret < 0)
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
return buf;
|
||||
}
|
||||
|
||||
static inline int pwc_set_red_gain(struct pwc_device *pdev, int value)
|
||||
{
|
||||
unsigned char buf;
|
||||
unsigned char buf;
|
||||
|
||||
if (value < 0)
|
||||
value = 0;
|
||||
@ -815,7 +815,7 @@ static inline int pwc_get_red_gain(struct pwc_device *pdev, int *value)
|
||||
{
|
||||
unsigned char buf;
|
||||
int ret;
|
||||
|
||||
|
||||
ret = RecvControlMsg(GET_CHROM_CTL, PRESET_MANUAL_RED_GAIN_FORMATTER, 1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
@ -841,7 +841,7 @@ static inline int pwc_get_blue_gain(struct pwc_device *pdev, int *value)
|
||||
{
|
||||
unsigned char buf;
|
||||
int ret;
|
||||
|
||||
|
||||
ret = RecvControlMsg(GET_CHROM_CTL, PRESET_MANUAL_BLUE_GAIN_FORMATTER, 1);
|
||||
if (ret < 0)
|
||||
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
|
||||
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.
|
||||
*/
|
||||
*/
|
||||
static inline int pwc_read_red_gain(struct pwc_device *pdev, int *value)
|
||||
{
|
||||
unsigned char buf;
|
||||
int ret;
|
||||
|
||||
|
||||
ret = RecvControlMsg(GET_STATUS_CTL, READ_RED_GAIN_FORMATTER, 1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
@ -870,7 +870,7 @@ static inline int pwc_read_blue_gain(struct pwc_device *pdev, int *value)
|
||||
{
|
||||
unsigned char buf;
|
||||
int ret;
|
||||
|
||||
|
||||
ret = RecvControlMsg(GET_STATUS_CTL, READ_BLUE_GAIN_FORMATTER, 1);
|
||||
if (ret < 0)
|
||||
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)
|
||||
{
|
||||
unsigned char buf;
|
||||
|
||||
|
||||
/* useful range is 0x01..0x20 */
|
||||
buf = speed / 0x7f0;
|
||||
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;
|
||||
int ret;
|
||||
|
||||
|
||||
ret = RecvControlMsg(GET_CHROM_CTL, AWB_CONTROL_SPEED_FORMATTER, 1);
|
||||
if (ret < 0)
|
||||
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)
|
||||
{
|
||||
unsigned char buf;
|
||||
|
||||
|
||||
/* useful range is 0x01..0x3F */
|
||||
buf = (delay >> 10);
|
||||
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;
|
||||
int ret;
|
||||
|
||||
|
||||
ret = RecvControlMsg(GET_CHROM_CTL, AWB_CONTROL_DELAY_FORMATTER, 1);
|
||||
if (ret < 0)
|
||||
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];
|
||||
int ret;
|
||||
|
||||
|
||||
if (pdev->type < 730) {
|
||||
*on_value = -1;
|
||||
*off_value = -1;
|
||||
@ -969,7 +969,7 @@ static inline int pwc_set_contour(struct pwc_device *pdev, int contour)
|
||||
{
|
||||
unsigned char buf;
|
||||
int ret;
|
||||
|
||||
|
||||
if (contour < 0)
|
||||
buf = 0xff; /* auto contour on */
|
||||
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);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
|
||||
if (contour < 0)
|
||||
return 0;
|
||||
if (contour > 0xffff)
|
||||
contour = 0xffff;
|
||||
|
||||
|
||||
buf = (contour >> 10); /* contour preset is [0..3f] */
|
||||
ret = SendControlMsg(SET_LUM_CTL, PRESET_CONTOUR_FORMATTER, 1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -994,7 +994,7 @@ static inline int pwc_get_contour(struct pwc_device *pdev, int *contour)
|
||||
{
|
||||
unsigned char buf;
|
||||
int ret;
|
||||
|
||||
|
||||
ret = RecvControlMsg(GET_LUM_CTL, AUTO_CONTOUR_FORMATTER, 1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
@ -1002,7 +1002,7 @@ static inline int pwc_get_contour(struct pwc_device *pdev, int *contour)
|
||||
if (buf == 0) {
|
||||
/* auto mode off, query current preset value */
|
||||
ret = RecvControlMsg(GET_LUM_CTL, PRESET_CONTOUR_FORMATTER, 1);
|
||||
if (ret < 0)
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
*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)
|
||||
{
|
||||
unsigned char buf;
|
||||
|
||||
|
||||
if (backlight)
|
||||
buf = 0xff;
|
||||
else
|
||||
@ -1027,7 +1027,7 @@ static inline int pwc_get_backlight(struct pwc_device *pdev, int *backlight)
|
||||
{
|
||||
int ret;
|
||||
unsigned char buf;
|
||||
|
||||
|
||||
ret = RecvControlMsg(GET_LUM_CTL, BACK_LIGHT_COMPENSATION_FORMATTER, 1);
|
||||
if (ret < 0)
|
||||
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)
|
||||
{
|
||||
unsigned char buf;
|
||||
|
||||
|
||||
if (flicker)
|
||||
buf = 0xff;
|
||||
else
|
||||
@ -1051,7 +1051,7 @@ static inline int pwc_get_flicker(struct pwc_device *pdev, int *flicker)
|
||||
{
|
||||
int ret;
|
||||
unsigned char buf;
|
||||
|
||||
|
||||
ret = RecvControlMsg(GET_LUM_CTL, FLICKERLESS_MODE_FORMATTER, 1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
@ -1076,7 +1076,7 @@ static inline int pwc_get_dynamic_noise(struct pwc_device *pdev, int *noise)
|
||||
{
|
||||
int ret;
|
||||
unsigned char buf;
|
||||
|
||||
|
||||
ret = RecvControlMsg(GET_LUM_CTL, DYNAMIC_NOISE_CONTROL_FORMATTER, 1);
|
||||
if (ret < 0)
|
||||
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)
|
||||
{
|
||||
unsigned char buf;
|
||||
|
||||
|
||||
buf = flags & 0x03; // only lower two bits are currently used
|
||||
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)
|
||||
{
|
||||
unsigned char buf[4];
|
||||
|
||||
|
||||
/* set new relative angle; angles are expressed in degrees * 100,
|
||||
but cam as .5 degree resolution, hence divide by 200. Also
|
||||
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;
|
||||
unsigned char buf[5];
|
||||
|
||||
|
||||
ret = RecvControlMsg(GET_MPT_CTL, PT_STATUS_FORMATTER, 5);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
@ -1129,14 +1129,14 @@ int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor)
|
||||
{
|
||||
unsigned char buf;
|
||||
int ret = -1, request;
|
||||
|
||||
|
||||
if (pdev->type < 675)
|
||||
request = SENSOR_TYPE_FORMATTER1;
|
||||
else if (pdev->type < 730)
|
||||
return -1; /* The Vesta series doesn't have this call */
|
||||
else
|
||||
request = SENSOR_TYPE_FORMATTER2;
|
||||
|
||||
|
||||
ret = RecvControlMsg(GET_STATUS_CTL, request, 1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
@ -1163,23 +1163,23 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg)
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case VIDIOCPWCSUSER:
|
||||
{
|
||||
if (pwc_save_user(pdev))
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case VIDIOCPWCFACTORY:
|
||||
{
|
||||
if (pwc_restore_factory(pdev))
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case VIDIOCPWCSCQUAL:
|
||||
{
|
||||
{
|
||||
int *qual = arg;
|
||||
|
||||
if (*qual < 0 || *qual > 3)
|
||||
@ -1190,14 +1190,14 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg)
|
||||
pdev->vcompression = *qual;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case VIDIOCPWCGCQUAL:
|
||||
{
|
||||
int *qual = arg;
|
||||
*qual = pdev->vcompression;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case VIDIOCPWCPROBE:
|
||||
{
|
||||
struct pwc_probe *probe = arg;
|
||||
@ -1220,27 +1220,27 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg)
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case VIDIOCPWCGAGC:
|
||||
{
|
||||
int *agc = arg;
|
||||
|
||||
|
||||
if (pwc_get_agc(pdev, agc))
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case VIDIOCPWCSSHUTTER:
|
||||
{
|
||||
int *shutter_speed = arg;
|
||||
ret = pwc_set_shutter_speed(pdev, *shutter_speed < 0 ? 1 : 0, *shutter_speed);
|
||||
break;
|
||||
}
|
||||
|
||||
case VIDIOCPWCSAWB:
|
||||
|
||||
case VIDIOCPWCSAWB:
|
||||
{
|
||||
struct pwc_whitebalance *wb = arg;
|
||||
|
||||
|
||||
ret = pwc_set_awb(pdev, wb->mode);
|
||||
if (ret >= 0 && wb->mode == PWC_WB_MANUAL) {
|
||||
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);
|
||||
if (ret < 0)
|
||||
break;
|
||||
ret = pwc_read_blue_gain(pdev, &wb->read_blue);
|
||||
if (ret < 0)
|
||||
break;
|
||||
ret = pwc_read_blue_gain(pdev, &wb->read_blue);
|
||||
if (ret < 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case VIDIOCPWCSAWBSPEED:
|
||||
{
|
||||
struct pwc_wb_speed *wbs = arg;
|
||||
|
||||
|
||||
if (wbs->control_speed > 0) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
case VIDIOCPWCGAWBSPEED:
|
||||
{
|
||||
struct pwc_wb_speed *wbs = arg;
|
||||
|
||||
|
||||
ret = pwc_get_wb_speed(pdev, &wbs->control_speed);
|
||||
if (ret < 0)
|
||||
break;
|
||||
@ -1304,7 +1304,7 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg)
|
||||
break;
|
||||
}
|
||||
|
||||
case VIDIOCPWCSLED:
|
||||
case VIDIOCPWCSLED:
|
||||
{
|
||||
struct pwc_leds *leds = arg;
|
||||
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);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case VIDIOCPWCGCONTOUR:
|
||||
{
|
||||
int *contour = arg;
|
||||
ret = pwc_get_contour(pdev, contour);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case VIDIOCPWCSBACKLIGHT:
|
||||
{
|
||||
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);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case VIDIOCPWCSFLICKER:
|
||||
{
|
||||
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);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case VIDIOCPWCSDYNNOISE:
|
||||
{
|
||||
int *dynnoise = arg;
|
||||
ret = pwc_set_dynamic_noise(pdev, *dynnoise);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case VIDIOCPWCGDYNNOISE:
|
||||
{
|
||||
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->height = pdev->image.y;
|
||||
break;
|
||||
}
|
||||
|
||||
case VIDIOCPWCMPTRESET:
|
||||
{
|
||||
if (pdev->features & FEATURE_MOTOR_PANTILT)
|
||||
{
|
||||
int *flags = arg;
|
||||
}
|
||||
|
||||
case VIDIOCPWCMPTRESET:
|
||||
{
|
||||
if (pdev->features & FEATURE_MOTOR_PANTILT)
|
||||
{
|
||||
int *flags = arg;
|
||||
|
||||
ret = pwc_mpt_reset(pdev, *flags);
|
||||
if (ret >= 0)
|
||||
{
|
||||
pdev->pan_angle = 0;
|
||||
pdev->tilt_angle = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = -ENXIO;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case VIDIOCPWCMPTGRANGE:
|
||||
{
|
||||
if (pdev->features & FEATURE_MOTOR_PANTILT)
|
||||
{
|
||||
struct pwc_mpt_range *range = arg;
|
||||
*range = pdev->angle_range;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = -ENXIO;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case VIDIOCPWCMPTSANGLE:
|
||||
{
|
||||
int new_pan, new_tilt;
|
||||
|
||||
if (pdev->features & FEATURE_MOTOR_PANTILT)
|
||||
{
|
||||
struct pwc_mpt_angles *angles = arg;
|
||||
if (ret >= 0)
|
||||
{
|
||||
pdev->pan_angle = 0;
|
||||
pdev->tilt_angle = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = -ENXIO;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case VIDIOCPWCMPTGRANGE:
|
||||
{
|
||||
if (pdev->features & FEATURE_MOTOR_PANTILT)
|
||||
{
|
||||
struct pwc_mpt_range *range = arg;
|
||||
*range = pdev->angle_range;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = -ENXIO;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case VIDIOCPWCMPTSANGLE:
|
||||
{
|
||||
int new_pan, new_tilt;
|
||||
|
||||
if (pdev->features & FEATURE_MOTOR_PANTILT)
|
||||
{
|
||||
struct pwc_mpt_angles *angles = arg;
|
||||
/* The camera can only set relative angles, so
|
||||
do some calculations when getting an absolute angle .
|
||||
*/
|
||||
if (angles->absolute)
|
||||
{
|
||||
new_pan = angles->pan;
|
||||
new_tilt = angles->tilt;
|
||||
}
|
||||
else
|
||||
{
|
||||
new_pan = pdev->pan_angle + angles->pan;
|
||||
new_tilt = pdev->tilt_angle + angles->tilt;
|
||||
new_pan = angles->pan;
|
||||
new_tilt = angles->tilt;
|
||||
}
|
||||
else
|
||||
{
|
||||
new_pan = pdev->pan_angle + angles->pan;
|
||||
new_tilt = pdev->tilt_angle + angles->tilt;
|
||||
}
|
||||
/* check absolute ranges */
|
||||
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;
|
||||
}
|
||||
if (ret == -EPIPE) /* stall -> out of range */
|
||||
ret = -ERANGE;
|
||||
ret = -ERANGE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = -ENXIO;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = -ENXIO;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case VIDIOCPWCMPTGANGLE:
|
||||
{
|
||||
|
||||
if (pdev->features & FEATURE_MOTOR_PANTILT)
|
||||
{
|
||||
struct pwc_mpt_angles *angles = arg;
|
||||
case VIDIOCPWCMPTGANGLE:
|
||||
{
|
||||
|
||||
angles->absolute = 1;
|
||||
angles->pan = pdev->pan_angle;
|
||||
angles->tilt = pdev->tilt_angle;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = -ENXIO;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case VIDIOCPWCMPTSTATUS:
|
||||
{
|
||||
if (pdev->features & FEATURE_MOTOR_PANTILT)
|
||||
{
|
||||
struct pwc_mpt_status *status = arg;
|
||||
ret = pwc_mpt_get_status(pdev, status);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = -ENXIO;
|
||||
}
|
||||
break;
|
||||
if (pdev->features & FEATURE_MOTOR_PANTILT)
|
||||
{
|
||||
struct pwc_mpt_angles *angles = arg;
|
||||
|
||||
angles->absolute = 1;
|
||||
angles->pan = pdev->pan_angle;
|
||||
angles->tilt = pdev->tilt_angle;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = -ENXIO;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case VIDIOCPWCMPTSTATUS:
|
||||
{
|
||||
if (pdev->features & FEATURE_MOTOR_PANTILT)
|
||||
{
|
||||
struct pwc_mpt_status *status = arg;
|
||||
ret = pwc_mpt_get_status(pdev, status);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = -ENXIO;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case VIDIOCPWCGVIDCMD:
|
||||
{
|
||||
struct pwc_video_command *cmd = arg;
|
||||
|
||||
cmd->type = pdev->type;
|
||||
|
||||
cmd->type = pdev->type;
|
||||
cmd->release = pdev->release;
|
||||
cmd->command_len = 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;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (ret > 0)
|
||||
return 0;
|
||||
return ret;
|
@ -25,18 +25,18 @@
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
/*
|
||||
This code forms the interface between the USB layers and the Philips
|
||||
specific stuff. Some adanved stuff of the driver falls under an
|
||||
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.
|
||||
|
||||
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
|
||||
any Linux kernel hacker, but I don't like uncomprehensible abbreviations
|
||||
without explanation).
|
||||
|
||||
|
||||
Oh yes, convention: to disctinguish between all the various pointers to
|
||||
device-structures, I use these names for the pointer variables:
|
||||
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...
|
||||
|
||||
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?"
|
||||
We have several options:
|
||||
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)
|
||||
3) Oops the kernel (this will have a negative effect on a user's uptime)
|
||||
4) Do something sensible.
|
||||
|
||||
|
||||
Of course, we go for option 4.
|
||||
|
||||
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
|
||||
succeeded. The pwc_device struct links back to both structures.
|
||||
|
||||
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
|
||||
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
|
||||
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
|
||||
opportunity. Crude, but it works.
|
||||
|
||||
|
||||
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
|
||||
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! :))
|
||||
*/
|
||||
|
||||
@ -203,14 +203,14 @@ static struct video_device pwc_template = {
|
||||
/* Here we want the physical address of the memory.
|
||||
* 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 |= adr & (PAGE_SIZE-1); /* restore the offset */
|
||||
ret = __pa(kva);
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void * rvmalloc(unsigned long size)
|
||||
@ -219,13 +219,13 @@ static void * rvmalloc(unsigned long size)
|
||||
unsigned long adr;
|
||||
|
||||
size=PAGE_ALIGN(size);
|
||||
mem=vmalloc_32(size);
|
||||
if (mem)
|
||||
mem=vmalloc_32(size);
|
||||
if (mem)
|
||||
{
|
||||
memset(mem, 0, size); /* Clear the ram out, no junk to the user */
|
||||
adr=(unsigned long) mem;
|
||||
while (size > 0)
|
||||
{
|
||||
adr=(unsigned long) mem;
|
||||
while (size > 0)
|
||||
{
|
||||
SetPageReserved(vmalloc_to_page((void *)adr));
|
||||
adr+=PAGE_SIZE;
|
||||
size-=PAGE_SIZE;
|
||||
@ -236,13 +236,13 @@ static void * rvmalloc(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;
|
||||
while ((long) size > 0)
|
||||
{
|
||||
adr=(unsigned long) mem;
|
||||
while ((long) size > 0)
|
||||
{
|
||||
ClearPageReserved(vmalloc_to_page((void *)adr));
|
||||
adr+=PAGE_SIZE;
|
||||
size-=PAGE_SIZE;
|
||||
@ -263,13 +263,13 @@ static int pwc_allocate_buffers(struct pwc_device *pdev)
|
||||
|
||||
if (pdev == NULL)
|
||||
return -ENXIO;
|
||||
|
||||
|
||||
#ifdef PWC_MAGIC
|
||||
if (pdev->magic != PWC_MAGIC) {
|
||||
Err("allocate_buffers(): magic failed.\n");
|
||||
return -ENXIO;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
/* Allocate Isochronous pipe buffers */
|
||||
for (i = 0; i < MAX_ISO_BUFS; i++) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Allocate decompressor table space */
|
||||
kbuf = NULL;
|
||||
switch (pdev->type)
|
||||
@ -320,7 +320,7 @@ static int pwc_allocate_buffers(struct pwc_device *pdev)
|
||||
case 730:
|
||||
case 740:
|
||||
case 750:
|
||||
#if 0
|
||||
#if 0
|
||||
Trace(TRACE_MEMORY,"private_data(%zu)\n",sizeof(struct pwc_dec23_private));
|
||||
kbuf = kmalloc(sizeof(struct pwc_dec23_private), GFP_KERNEL); /* Timon & Kiara */
|
||||
break;
|
||||
@ -329,11 +329,11 @@ static int pwc_allocate_buffers(struct pwc_device *pdev)
|
||||
/* TODO & FIXME */
|
||||
kbuf = kmalloc(sizeof(struct pwc_dec23_private), GFP_KERNEL);
|
||||
break;
|
||||
#endif
|
||||
#endif
|
||||
;
|
||||
}
|
||||
pdev->decompress_data = kbuf;
|
||||
|
||||
|
||||
/* Allocate image buffer; double buffer for mmap() */
|
||||
kbuf = rvmalloc(default_mbufs * pdev->len_per_image);
|
||||
if (kbuf == NULL) {
|
||||
@ -348,7 +348,7 @@ static int pwc_allocate_buffers(struct pwc_device *pdev)
|
||||
pdev->image_ptr[i] = NULL;
|
||||
|
||||
kbuf = NULL;
|
||||
|
||||
|
||||
Trace(TRACE_MEMORY, "<< pwc_allocate_buffers()\n");
|
||||
return 0;
|
||||
}
|
||||
@ -366,7 +366,7 @@ static void pwc_free_buffers(struct pwc_device *pdev)
|
||||
Err("free_buffers(): magic failed.\n");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Release Iso-pipe buffers */
|
||||
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);
|
||||
}
|
||||
pdev->image_data = NULL;
|
||||
|
||||
|
||||
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
|
||||
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
|
||||
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
|
||||
frame buffer.
|
||||
|
||||
@ -443,8 +443,8 @@ static void pwc_free_buffers(struct pwc_device *pdev)
|
||||
and a 'full' frame list:
|
||||
* Initially, all frame buffers but one are on the 'empty' list; the one
|
||||
remaining buffer is our initial fill frame.
|
||||
* 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
|
||||
* 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
|
||||
the head of the 'full' list.
|
||||
* When our fill buffer has been filled, it is appended to the 'full'
|
||||
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;
|
||||
}
|
||||
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.
|
||||
*/
|
||||
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;
|
||||
|
||||
/* vsync: 0 = don't copy data
|
||||
1 = sync-hunt
|
||||
2 = synched
|
||||
1 = sync-hunt
|
||||
2 = synched
|
||||
*/
|
||||
/* Compact data */
|
||||
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 */
|
||||
|
||||
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.
|
||||
Decompression is done in user time over there.
|
||||
*/
|
||||
if (pdev->vsync == 2) {
|
||||
/* 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
|
||||
/* 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
|
||||
however detected in the cam and a bit is set in the header.
|
||||
*/
|
||||
if (pdev->type == 730) {
|
||||
unsigned char *ptr = (unsigned char *)fbuf->data;
|
||||
|
||||
|
||||
if (ptr[1] == 1 && ptr[0] & 0x10) {
|
||||
#if PWC_DEBUG
|
||||
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");
|
||||
}
|
||||
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
|
||||
frame doesn't make sense anyway.
|
||||
So we get either this sequence:
|
||||
drop_bit set -> 4 byte frame -> short frame -> good frame
|
||||
So we get either this sequence:
|
||||
drop_bit set -> 4 byte frame -> short frame -> good frame
|
||||
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!
|
||||
*/
|
||||
if (fbuf->filled == 4)
|
||||
@ -830,7 +830,7 @@ static int pwc_isoc_init(struct pwc_device *pdev)
|
||||
intf = usb_ifnum_to_if(udev, 0);
|
||||
if (intf)
|
||||
idesc = usb_altnum_to_altsetting(intf, pdev->valternate);
|
||||
|
||||
|
||||
if (!idesc)
|
||||
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);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
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");
|
||||
return -ENFILE; /* Odd error, that should be noticeable */
|
||||
@ -875,18 +875,18 @@ static int pwc_isoc_init(struct pwc_device *pdev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* init URB structure */
|
||||
/* init URB structure */
|
||||
for (i = 0; i < MAX_ISO_BUFS; i++) {
|
||||
urb = pdev->sbuf[i].urb;
|
||||
|
||||
urb->interval = 1; // devik
|
||||
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_buffer = pdev->sbuf[i].data;
|
||||
urb->transfer_buffer_length = ISO_BUFFER_SIZE;
|
||||
urb->complete = pwc_isoc_handler;
|
||||
urb->context = pdev;
|
||||
urb->transfer_buffer = pdev->sbuf[i].data;
|
||||
urb->transfer_buffer_length = ISO_BUFFER_SIZE;
|
||||
urb->complete = pwc_isoc_handler;
|
||||
urb->context = pdev;
|
||||
urb->start_frame = 0;
|
||||
urb->number_of_packets = ISO_FRAMES_PER_DESC;
|
||||
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
|
||||
is signalled by EPIPE)
|
||||
is signalled by EPIPE)
|
||||
*/
|
||||
if (pdev->error_status && pdev->error_status != EPIPE) {
|
||||
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);
|
||||
/* Try to set video mode... */
|
||||
start = ret = pwc_set_video_mode(pdev, width, height, new_fps, new_compression, new_snapshot);
|
||||
if (ret) {
|
||||
Trace(TRACE_FLOW, "pwc_set_video_mode attempt 1 failed.\n");
|
||||
if (ret) {
|
||||
Trace(TRACE_FLOW, "pwc_set_video_mode attempt 1 failed.\n");
|
||||
/* 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);
|
||||
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)
|
||||
@ -987,18 +987,18 @@ static int pwc_video_open(struct inode *inode, struct file *file)
|
||||
struct pwc_device *pdev;
|
||||
|
||||
Trace(TRACE_OPEN, ">> video_open called(vdev = 0x%p).\n", vdev);
|
||||
|
||||
|
||||
pdev = (struct pwc_device *)vdev->priv;
|
||||
if (pdev == NULL)
|
||||
BUG();
|
||||
if (pdev->vopen)
|
||||
return -EBUSY;
|
||||
|
||||
|
||||
down(&pdev->modlock);
|
||||
if (!pdev->usb_init) {
|
||||
Trace(TRACE_OPEN, "Doing first time initialization.\n");
|
||||
pdev->usb_init = 1;
|
||||
|
||||
|
||||
if (pwc_trace & TRACE_OPEN)
|
||||
{
|
||||
/* Query sensor type */
|
||||
@ -1036,7 +1036,7 @@ static int pwc_video_open(struct inode *inode, struct file *file)
|
||||
/* Set LED on/off time */
|
||||
if (pwc_set_leds(pdev, led_on, led_off) < 0)
|
||||
Info("Failed to set LED on/off time.\n");
|
||||
|
||||
|
||||
pwc_construct(pdev); /* set min/max sizes correct */
|
||||
|
||||
/* So far, so good. Allocate memory. */
|
||||
@ -1046,7 +1046,7 @@ static int pwc_video_open(struct inode *inode, struct file *file)
|
||||
up(&pdev->modlock);
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
/* Reset buffers & parameters */
|
||||
pwc_reset_buffers(pdev);
|
||||
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);
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
i = pwc_isoc_init(pdev);
|
||||
if (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 ????
|
||||
* ANSWER: Not supported. You can't open the device more than once,
|
||||
despite what the V4L1 interface says. First, I don't see
|
||||
the need, second there's no mechanism of alerting the
|
||||
2nd/3rd/... process of events like changing image size.
|
||||
And I don't see the point of blocking that for the
|
||||
2nd/3rd/... process.
|
||||
In multi-threaded environments reading parallel from any
|
||||
device is tricky anyhow.
|
||||
despite what the V4L1 interface says. First, I don't see
|
||||
the need, second there's no mechanism of alerting the
|
||||
2nd/3rd/... process of events like changing image size.
|
||||
And I don't see the point of blocking that for the
|
||||
2nd/3rd/... process.
|
||||
In multi-threaded environments reading parallel from any
|
||||
device is tricky anyhow.
|
||||
*/
|
||||
|
||||
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;
|
||||
int noblock = file->f_flags & O_NONBLOCK;
|
||||
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);
|
||||
if (vdev == NULL)
|
||||
@ -1193,22 +1193,22 @@ static ssize_t pwc_video_read(struct file *file, char __user * buf,
|
||||
set_current_state(TASK_RUNNING);
|
||||
return -pdev->error_status ;
|
||||
}
|
||||
if (noblock) {
|
||||
remove_wait_queue(&pdev->frameq, &wait);
|
||||
set_current_state(TASK_RUNNING);
|
||||
return -EWOULDBLOCK;
|
||||
}
|
||||
if (signal_pending(current)) {
|
||||
remove_wait_queue(&pdev->frameq, &wait);
|
||||
set_current_state(TASK_RUNNING);
|
||||
return -ERESTARTSYS;
|
||||
}
|
||||
schedule();
|
||||
set_current_state(TASK_INTERRUPTIBLE);
|
||||
if (noblock) {
|
||||
remove_wait_queue(&pdev->frameq, &wait);
|
||||
set_current_state(TASK_RUNNING);
|
||||
return -EWOULDBLOCK;
|
||||
}
|
||||
if (signal_pending(current)) {
|
||||
remove_wait_queue(&pdev->frameq, &wait);
|
||||
set_current_state(TASK_RUNNING);
|
||||
return -ERESTARTSYS;
|
||||
}
|
||||
schedule();
|
||||
set_current_state(TASK_INTERRUPTIBLE);
|
||||
}
|
||||
remove_wait_queue(&pdev->frameq, &wait);
|
||||
set_current_state(TASK_RUNNING);
|
||||
|
||||
|
||||
/* Decompress and release frame */
|
||||
if (pwc_handle_frame(pdev))
|
||||
return -EFAULT;
|
||||
@ -1218,7 +1218,7 @@ static ssize_t pwc_video_read(struct file *file, char __user * buf,
|
||||
if (pdev->vpalette == VIDEO_PALETTE_RAW)
|
||||
bytes_to_read = pdev->frame_size;
|
||||
else
|
||||
bytes_to_read = pdev->view.size;
|
||||
bytes_to_read = pdev->view.size;
|
||||
|
||||
/* copy bytes to user space; we allow for partial reads */
|
||||
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;
|
||||
/*
|
||||
* FIXME: Suppose we are mid read
|
||||
ANSWER: No problem: the firmware of the camera
|
||||
can handle brightness/contrast/etc
|
||||
changes at _any_ time, and the palette
|
||||
is used exactly once in the uncompress
|
||||
routine.
|
||||
ANSWER: No problem: the firmware of the camera
|
||||
can handle brightness/contrast/etc
|
||||
changes at _any_ time, and the palette
|
||||
is used exactly once in the uncompress
|
||||
routine.
|
||||
*/
|
||||
pwc_set_brightness(pdev, p->brightness);
|
||||
pwc_set_contrast(pdev, p->contrast);
|
||||
@ -1373,21 +1373,21 @@ static int pwc_video_do_ioctl(struct inode *inode, struct file *file,
|
||||
break;
|
||||
}
|
||||
|
||||
/* Window/size parameters */
|
||||
/* Window/size parameters */
|
||||
case VIDIOCGWIN:
|
||||
{
|
||||
struct video_window *vw = arg;
|
||||
|
||||
|
||||
vw->x = 0;
|
||||
vw->y = 0;
|
||||
vw->width = pdev->view.x;
|
||||
vw->height = pdev->view.y;
|
||||
vw->chromakey = 0;
|
||||
vw->flags = (pdev->vframes << PWC_FPS_SHIFT) |
|
||||
(pdev->vsnapshot ? PWC_FPS_SNAPSHOT : 0);
|
||||
vw->flags = (pdev->vframes << PWC_FPS_SHIFT) |
|
||||
(pdev->vsnapshot ? PWC_FPS_SNAPSHOT : 0);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case VIDIOCSWIN:
|
||||
{
|
||||
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);
|
||||
if (ret)
|
||||
return ret;
|
||||
break;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
/* We don't have overlay support (yet) */
|
||||
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 */
|
||||
pdev->image_used[vm->frame] = 1;
|
||||
|
||||
/* Okay, we're done here. In the SYNC call we wait until a
|
||||
frame comes available, then expand image into the given
|
||||
/* Okay, we're done here. In the SYNC call we wait until a
|
||||
frame comes available, then expand image into the given
|
||||
buffer.
|
||||
In contrast to the CPiA cam the Philips cams deliver a
|
||||
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
|
||||
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
|
||||
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
|
||||
got filled! So you better not start a CAPTURE in
|
||||
the same frame immediately (use double buffering).
|
||||
This is not a problem for this cam, since it has
|
||||
extra intermediate buffers, but a hardware
|
||||
grabber card will then overwrite the buffer
|
||||
the same frame immediately (use double buffering).
|
||||
This is not a problem for this cam, since it has
|
||||
extra intermediate buffers, but a hardware
|
||||
grabber card will then overwrite the buffer
|
||||
you're working on.
|
||||
*/
|
||||
int *mbuf = arg;
|
||||
@ -1512,10 +1512,10 @@ static int pwc_video_do_ioctl(struct inode *inode, struct file *file,
|
||||
return -EINVAL;
|
||||
|
||||
/* Add ourselves to the frame wait-queue.
|
||||
|
||||
|
||||
FIXME: needs auditing for safety.
|
||||
QUESTION: In what respect? I think that using the
|
||||
frameq is safe now.
|
||||
frameq is safe now.
|
||||
*/
|
||||
add_wait_queue(&pdev->frameq, &wait);
|
||||
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);
|
||||
return -pdev->error_status;
|
||||
}
|
||||
|
||||
if (signal_pending(current)) {
|
||||
remove_wait_queue(&pdev->frameq, &wait);
|
||||
set_current_state(TASK_RUNNING);
|
||||
return -ERESTARTSYS;
|
||||
}
|
||||
schedule();
|
||||
set_current_state(TASK_INTERRUPTIBLE);
|
||||
|
||||
if (signal_pending(current)) {
|
||||
remove_wait_queue(&pdev->frameq, &wait);
|
||||
set_current_state(TASK_RUNNING);
|
||||
return -ERESTARTSYS;
|
||||
}
|
||||
schedule();
|
||||
set_current_state(TASK_INTERRUPTIBLE);
|
||||
}
|
||||
remove_wait_queue(&pdev->frameq, &wait);
|
||||
set_current_state(TASK_RUNNING);
|
||||
|
||||
/* The frame is ready. Expand in the image buffer
|
||||
requested by the user. I don't care if you
|
||||
mmap() 5 buffers and request data in this order:
|
||||
|
||||
/* The frame is ready. Expand in the image buffer
|
||||
requested by the user. I don't care if you
|
||||
mmap() 5 buffers and request data in this order:
|
||||
buffer 4 2 3 0 1 2 3 0 4 3 1 . . .
|
||||
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;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case VIDIOCGAUDIO:
|
||||
{
|
||||
struct video_audio *v = arg;
|
||||
|
||||
|
||||
strcpy(v->name, "Microphone");
|
||||
v->audio = -1; /* unknown audio minor */
|
||||
v->flags = 0;
|
||||
@ -1565,19 +1565,19 @@ static int pwc_video_do_ioctl(struct inode *inode, struct file *file,
|
||||
v->treble = 0;
|
||||
v->balance = 0x8000;
|
||||
v->step = 1;
|
||||
break;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case VIDIOCSAUDIO:
|
||||
{
|
||||
/* Dummy: nothing can be set */
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case VIDIOCGUNIT:
|
||||
{
|
||||
struct video_unit *vu = arg;
|
||||
|
||||
|
||||
vu->video = pdev->vdev->minor & 0x3F;
|
||||
vu->audio = -1; /* not known yet */
|
||||
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);
|
||||
} /* ..switch */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int pwc_video_ioctl(struct inode *inode, struct file *file,
|
||||
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 size = vma->vm_end-vma->vm_start;
|
||||
unsigned long page, pos;
|
||||
|
||||
|
||||
Trace(TRACE_MEMORY, "mmap(0x%p, 0x%lx, %lu) called.\n", vdev, start, size);
|
||||
pdev = vdev->priv;
|
||||
|
||||
|
||||
vma->vm_flags |= VM_IO;
|
||||
|
||||
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;
|
||||
|
||||
/* 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.idProduct),
|
||||
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.)";
|
||||
type_id = 730; /* Assuming CMOS */
|
||||
break;
|
||||
default:
|
||||
default:
|
||||
return -ENODEV;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (vendor_id == 0x055d) {
|
||||
/* I don't know the difference between the C10 and the C30;
|
||||
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;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
else if (vendor_id == 0x0d81) {
|
||||
switch(product_id) {
|
||||
@ -1856,7 +1856,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
else
|
||||
return -ENODEV; /* Not any of the know types; but the list keeps growing. */
|
||||
|
||||
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)
|
||||
{
|
||||
/* Logitech QuickCam Orbit
|
||||
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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
pdev->angle_range.pan_min = -7000;
|
||||
pdev->angle_range.pan_max = 7000;
|
||||
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 */
|
||||
if (hint < MAX_DEV_HINTS)
|
||||
if (hint < MAX_DEV_HINTS)
|
||||
device_hint[hint].pdev = 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");
|
||||
goto disconnect_out;
|
||||
}
|
||||
#ifdef PWC_MAGIC
|
||||
#ifdef PWC_MAGIC
|
||||
if (pdev->magic != PWC_MAGIC) {
|
||||
Err("pwc_disconnect() Magic number failed. Consult your scrolls and try again.\n");
|
||||
goto disconnect_out;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* We got unplugged; this is signalled by an EPIPE error code */
|
||||
if (pdev->vopen) {
|
||||
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];
|
||||
@ -2168,7 +2168,7 @@ static int __init usb_pwc_init(void)
|
||||
if (*dot != '\0') {
|
||||
/* There's a serial number as well */
|
||||
int k;
|
||||
|
||||
|
||||
dot++;
|
||||
k = 0;
|
||||
while (*dot != ':' && k < 29) {
|
||||
@ -2178,18 +2178,18 @@ static int __init usb_pwc_init(void)
|
||||
device_hint[i].serial_number[k] = '\0';
|
||||
}
|
||||
}
|
||||
#if PWC_DEBUG
|
||||
#if PWC_DEBUG
|
||||
Debug("device_hint[%d]:\n", i);
|
||||
Debug(" type : %d\n", device_hint[i].type);
|
||||
Debug(" serial# : %s\n", device_hint[i].serial_number);
|
||||
Debug(" node : %d\n", device_hint[i].device_node);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
else
|
||||
device_hint[i].type = 0; /* not filled */
|
||||
} /* ..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);
|
||||
}
|
||||
|
@ -33,10 +33,10 @@
|
||||
/*
|
||||
Changes
|
||||
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
|
||||
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.
|
||||
@ -45,10 +45,10 @@
|
||||
|
||||
The #define names are built up like follows:
|
||||
VIDIOC VIDeo IOCtl prefix
|
||||
PWC Philps WebCam
|
||||
G optional: Get
|
||||
S optional: Set
|
||||
... the function
|
||||
PWC Philps WebCam
|
||||
G optional: Get
|
||||
S optional: Set
|
||||
... the function
|
||||
*/
|
||||
|
||||
|
||||
@ -94,7 +94,7 @@ struct pwc_serial
|
||||
{
|
||||
char serial[30]; /* String with serial number. Contains terminating 0 */
|
||||
};
|
||||
|
||||
|
||||
/* pwc_whitebalance.mode values */
|
||||
#define PWC_WB_INDOOR 0
|
||||
#define PWC_WB_OUTDOOR 1
|
||||
@ -102,14 +102,14 @@ struct pwc_serial
|
||||
#define PWC_WB_MANUAL 3
|
||||
#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.
|
||||
*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
|
||||
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.
|
||||
'read_red' and 'read_blue' are read-only.
|
||||
*/
|
||||
*/
|
||||
struct pwc_whitebalance
|
||||
{
|
||||
int mode;
|
||||
@ -117,9 +117,9 @@ struct pwc_whitebalance
|
||||
int read_red, read_blue; /* R/O */
|
||||
};
|
||||
|
||||
/*
|
||||
/*
|
||||
'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.
|
||||
*/
|
||||
struct pwc_wb_speed
|
||||
@ -148,11 +148,11 @@ struct pwc_imagesize
|
||||
#define PWC_MPT_TILT 0x02
|
||||
#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
|
||||
be used with VIDIOCPWCSANGLE; VIDIOCPWCGANGLE always returns
|
||||
absolute angles.
|
||||
*/
|
||||
*/
|
||||
struct pwc_mpt_angles
|
||||
{
|
||||
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
|
||||
all the necessary information to initialize and use the decompressor
|
||||
routines in standalone applications.
|
||||
*/
|
||||
*/
|
||||
struct pwc_video_command
|
||||
{
|
||||
int type; /* camera type (645, 675, 730, etc.) */
|
||||
int release; /* release number */
|
||||
|
||||
int size; /* one of PSZ_* */
|
||||
int alternate;
|
||||
int size; /* one of PSZ_* */
|
||||
int alternate;
|
||||
int command_len; /* length of USB video command */
|
||||
unsigned char command_buf[13]; /* Actual USB video command */
|
||||
int bandlength; /* >0 = compressed */
|
||||
@ -264,7 +264,7 @@ struct pwc_video_command
|
||||
|
||||
/* Flickerless mode; = 0 off, otherwise on */
|
||||
#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 */
|
||||
#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 */
|
||||
#define VIDIOCPWCGREALSIZE _IOR('v', 210, struct pwc_imagesize)
|
||||
|
||||
/* Motorized pan & tilt functions */
|
||||
/* Motorized pan & tilt functions */
|
||||
#define VIDIOCPWCMPTRESET _IOW('v', 211, int)
|
||||
#define VIDIOCPWCMPTGRANGE _IOR('v', 211, struct pwc_mpt_range)
|
||||
#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.
|
||||
(C) 1999-2003 Nemosoft Unv.
|
||||
(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;
|
||||
|
||||
/* Make sure we don't go beyond our max size.
|
||||
NB: we have different limits for RAW and normal modes. In case
|
||||
you don't have the decompressor loaded or use RAW mode,
|
||||
the maximum viewable size is smaller.
|
||||
*/
|
||||
NB: we have different limits for RAW and normal modes. In case
|
||||
you don't have the decompressor loaded or use RAW mode,
|
||||
the maximum viewable size is smaller.
|
||||
*/
|
||||
if (pdev->vpalette == VIDEO_PALETTE_RAW)
|
||||
{
|
||||
if (width > pdev->abs_max.x || height > pdev->abs_max.y)
|
||||
{
|
||||
Debug("VIDEO_PALETTE_RAW: going beyond abs_max.\n");
|
||||
return -1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -88,8 +88,8 @@ void pwc_construct(struct pwc_device *pdev)
|
||||
pdev->view_min.y = 96;
|
||||
pdev->view_max.x = 352;
|
||||
pdev->view_max.y = 288;
|
||||
pdev->abs_max.x = 352;
|
||||
pdev->abs_max.y = 288;
|
||||
pdev->abs_max.x = 352;
|
||||
pdev->abs_max.y = 288;
|
||||
pdev->image_mask = 1 << PSZ_SQCIF | 1 << PSZ_QCIF | 1 << PSZ_CIF;
|
||||
pdev->vcinterface = 2;
|
||||
pdev->vendpoint = 4;
|
||||
@ -105,8 +105,8 @@ void pwc_construct(struct pwc_device *pdev)
|
||||
pdev->view_max.x = 640;
|
||||
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->abs_max.x = 640;
|
||||
pdev->abs_max.y = 480;
|
||||
pdev->abs_max.x = 640;
|
||||
pdev->abs_max.y = 480;
|
||||
pdev->vcinterface = 3;
|
||||
pdev->vendpoint = 4;
|
||||
pdev->frame_header_size = 0;
|
||||
@ -121,8 +121,8 @@ void pwc_construct(struct pwc_device *pdev)
|
||||
pdev->view_max.x = 640;
|
||||
pdev->view_max.y = 480;
|
||||
pdev->image_mask = 1 << PSZ_QSIF | 1 << PSZ_SIF | 1 << PSZ_VGA;
|
||||
pdev->abs_max.x = 640;
|
||||
pdev->abs_max.y = 480;
|
||||
pdev->abs_max.x = 640;
|
||||
pdev->abs_max.y = 480;
|
||||
pdev->vcinterface = 3;
|
||||
pdev->vendpoint = 5;
|
||||
pdev->frame_header_size = TOUCAM_HEADER_SIZE;
|
@ -54,7 +54,7 @@
|
||||
{0},
|
||||
},
|
||||
/* VGA */
|
||||
{
|
||||
{
|
||||
{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.
|
||||
*/
|
||||
int flags;
|
||||
|
||||
flags = PWCX_FLAG_PLANAR;
|
||||
if (pdev->vsize == PSZ_VGA && pdev->vframes == 5 && pdev->vsnapshot)
|
||||
|
||||
flags = PWCX_FLAG_PLANAR;
|
||||
if (pdev->vsize == PSZ_VGA && pdev->vframes == 5 && pdev->vsnapshot)
|
||||
{
|
||||
printk(KERN_ERR "pwc: Mode Bayer is not supported for now\n");
|
||||
flags |= PWCX_FLAG_BAYER;
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user