aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Verkuil <hverkuil@xs4all.nl>2010-12-25 05:44:33 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-12-29 05:17:08 -0500
commit39c3d488452ae206cfc8afda0db041ee55d01c3c (patch)
tree1223d621925b47412d5c2be10b2108e9926f66d2
parent71bb2876a3b2af8e6fd5ac20921ee0de9e07d809 (diff)
[media] cpia, stradis: remove deprecated V4L1 drivers
Nobody stepped in to convert these drivers to V4L2, so they are now removed from the kernel. Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r--Documentation/video4linux/README.cpia191
-rw-r--r--Documentation/video4linux/bttv/Cards4
-rw-r--r--MAINTAINERS6
-rw-r--r--drivers/staging/Kconfig4
-rw-r--r--drivers/staging/Makefile2
-rw-r--r--drivers/staging/cpia/Kconfig39
-rw-r--r--drivers/staging/cpia/Makefile5
-rw-r--r--drivers/staging/cpia/TODO8
-rw-r--r--drivers/staging/cpia/cpia.c4028
-rw-r--r--drivers/staging/cpia/cpia.h432
-rw-r--r--drivers/staging/cpia/cpia_pp.c869
-rw-r--r--drivers/staging/cpia/cpia_usb.c640
-rw-r--r--drivers/staging/stradis/Kconfig7
-rw-r--r--drivers/staging/stradis/Makefile3
-rw-r--r--drivers/staging/stradis/TODO6
-rw-r--r--drivers/staging/stradis/stradis.c2222
16 files changed, 0 insertions, 8466 deletions
diff --git a/Documentation/video4linux/README.cpia b/Documentation/video4linux/README.cpia
deleted file mode 100644
index 8a747fee661f..000000000000
--- a/Documentation/video4linux/README.cpia
+++ /dev/null
@@ -1,191 +0,0 @@
1This is a driver for the CPiA PPC2 driven parallel connected
2Camera. For example the Creative WebcamII is CPiA driven.
3
4 ) [1]Peter Pregler, Linz 2000, published under the [2]GNU GPL
5
6---------------------------------------------------------------------------
7
8USAGE:
9
10General:
11========
12
131) Make sure you have created the video devices (/dev/video*):
14
15- if you have a recent MAKEDEV do a 'cd /dev;./MAKEDEV video'
16- otherwise do a:
17
18cd /dev
19mknod video0 c 81 0
20ln -s video0 video
21
222) Compile the kernel (see below for the list of options to use),
23 configure your parport and reboot.
24
253) If all worked well you should get messages similar
26 to the following (your versions may be different) on the console:
27
28V4L-Driver for Vision CPiA based cameras v0.7.4
29parport0: read2 timeout.
30parport0: Multimedia device, VLSI Vision Ltd PPC2
31Parallel port driver for Vision CPiA based camera
32 CPIA Version: 1.20 (2.0)
33 CPIA PnP-ID: 0553:0002:0100
34 VP-Version: 1.0 0100
35 1 camera(s) found
36
37
38As modules:
39===========
40
41Make sure you have selected the following kernel options (you can
42select all stuff as modules):
43
44The cpia-stuff is in the section 'Character devices -> Video For Linux'.
45
46CONFIG_PARPORT=m
47CONFIG_PARPORT_PC=m
48CONFIG_PARPORT_PC_FIFO=y
49CONFIG_PARPORT_1284=y
50CONFIG_VIDEO_DEV=m
51CONFIG_VIDEO_CPIA=m
52CONFIG_VIDEO_CPIA_PP=m
53
54For autoloading of all those modules you need to tell module-init-tools
55some stuff. Add the following line to your module-init-tools config-file
56(e.g. /etc/modprobe.conf or wherever your distribution does store that
57stuff):
58
59options parport_pc io=0x378 irq=7 dma=3
60alias char-major-81 cpia_pp
61
62The first line tells the dma/irq channels to use. Those _must_ match
63the settings of your BIOS. Do NOT simply use the values above. See
64Documentation/parport.txt for more information about this. The second
65line associates the video-device file with the driver. Of cause you
66can also load the modules once upon boot (usually done in /etc/modules).
67
68Linked into the kernel:
69=======================
70
71Make sure you have selected the following kernel options. Note that
72you cannot compile the parport-stuff as modules and the cpia-driver
73statically (the other way round is okay though).
74
75The cpia-stuff is in the section 'Character devices -> Video For Linux'.
76
77CONFIG_PARPORT=y
78CONFIG_PARPORT_PC=y
79CONFIG_PARPORT_PC_FIFO=y
80CONFIG_PARPORT_1284=y
81CONFIG_VIDEO_DEV=y
82CONFIG_VIDEO_CPIA=y
83CONFIG_VIDEO_CPIA_PP=y
84
85To use DMA/irq you will need to tell the kernel upon boot time the
86hardware configuration of the parport. You can give the boot-parameter
87at the LILO-prompt or specify it in lilo.conf. I use the following
88append-line in lilo.conf:
89
90 append="parport=0x378,7,3"
91
92See Documentation/parport.txt for more information about the
93configuration of the parport and the values given above. Do not simply
94use the values given above.
95
96---------------------------------------------------------------------------
97FEATURES:
98
99- mmap/read v4l-interface (but no overlay)
100- image formats: CIF/QCIF, SIF/QSIF, various others used by isabel;
101 note: all sizes except CIF/QCIF are implemented by clipping, i.e.
102 pixels are not uploaded from the camera
103- palettes: VIDEO_PALETTE_GRAY, VIDEO_PALETTE_RGB565, VIDEO_PALETTE_RGB555,
104 VIDEO_PALETTE_RGB24, VIDEO_PALETTE_RGB32, VIDEO_PALETTE_YUYV,
105 VIDEO_PALETTE_UYVY, VIDEO_PALETTE_YUV422
106- state information (color balance, exposure, ...) is preserved between
107 device opens
108- complete control over camera via proc-interface (_all_ camera settings are
109 supported), there is also a python-gtk application available for this [3]
110- works under SMP (but the driver is completely serialized and synchronous)
111 so you get no benefit from SMP, but at least it does not crash your box
112- might work for non-Intel architecture, let us know about this
113
114---------------------------------------------------------------------------
115TESTED APPLICATIONS:
116
117- a simple test application based on Xt is available at [3]
118- another test-application based on gqcam-0.4 (uses GTK)
119- gqcam-0.6 should work
120- xawtv-3.x (also the webcam software)
121- xawtv-2.46
122- w3cam (cgi-interface and vidcat, e.g. you may try out 'vidcat |xv
123 -maxpect -root -quit +noresetroot -rmode 5 -')
124- vic, the MBONE video conferencing tool (version 2.8ucl4-1)
125- isabel 3R4beta (barely working, but AFAICT all the problems are on
126 their side)
127- camserv-0.40
128
129See [3] for pointers to v4l-applications.
130
131---------------------------------------------------------------------------
132KNOWN PROBLEMS:
133
134- some applications do not handle the image format correctly, you will
135 see strange horizontal stripes instead of a nice picture -> make sure
136 your application does use a supported image size or queries the driver
137 for the actually used size (reason behind this: the camera cannot
138 provide any image format, so if size NxM is requested the driver will
139 use a format to the closest fitting N1xM1, the application should now
140 query for this granted size, most applications do not).
141- all the todo ;)
142- if there is not enough light and the picture is too dark try to
143 adjust the SetSensorFPS setting, automatic frame rate adjustment
144 has its price
145- do not try out isabel 3R4beta (built 135), you will be disappointed
146
147---------------------------------------------------------------------------
148TODO:
149
150- multiple camera support (struct camera or something) - This should work,
151 but hasn't been tested yet.
152- architecture independence?
153- SMP-safe asynchronous mmap interface
154- nibble mode for old parport interfaces
155- streaming capture, this should give a performance gain
156
157---------------------------------------------------------------------------
158IMPLEMENTATION NOTES:
159
160The camera can act in two modes, streaming or grabbing. Right now a
161polling grab-scheme is used. Maybe interrupt driven streaming will be
162used for a asynchronous mmap interface in the next major release of the
163driver. This might give a better frame rate.
164
165---------------------------------------------------------------------------
166THANKS (in no particular order):
167
168- Scott J. Bertin <sbertin@mindspring.com> for cleanups, the proc-filesystem
169 and much more
170- Henry Bruce <whb@vvl.co.uk> for providing developers information about
171 the CPiA chip, I wish all companies would treat Linux as seriously
172- Karoly Erdei <Karoly.Erdei@risc.uni-linz.ac.at> and RISC-Linz for being
173 my boss ;) resp. my employer and for providing me the hardware and
174 allow me to devote some working time to this project
175- Manuel J. Petit de Gabriel <mpetit@dit.upm.es> for providing help
176 with Isabel (http://isabel.dit.upm.es/)
177- Bas Huisman <bhuism@cs.utwente.nl> for writing the initial parport code
178- Jarl Totland <Jarl.Totland@bdc.no> for setting up the mailing list
179 and maintaining the web-server[3]
180- Chris Whiteford <Chris@informinteractive.com> for fixes related to the
181 1.02 firmware
182- special kudos to all the tester whose machines crashed and/or
183 will crash. :)
184
185---------------------------------------------------------------------------
186REFERENCES
187
188 1. http://www.risc.uni-linz.ac.at/
189 mailto:Peter_Pregler@email.com
190 2. see the file COPYING in the top directory of the kernel tree
191 3. http://webcam.sourceforge.net/
diff --git a/Documentation/video4linux/bttv/Cards b/Documentation/video4linux/bttv/Cards
index 12217fc49725..db833ced2cb8 100644
--- a/Documentation/video4linux/bttv/Cards
+++ b/Documentation/video4linux/bttv/Cards
@@ -464,10 +464,6 @@ Siemens
464------- 464-------
465 Multimedia eXtension Board (MXB) (SAA7146, SAA7111) 465 Multimedia eXtension Board (MXB) (SAA7146, SAA7111)
466 466
467Stradis
468-------
469 SDM275,SDM250,SDM026,SDM025 (SAA7146, IBMMPEG2): MPEG2 decoder only
470
471Powercolor 467Powercolor
472---------- 468----------
473 MTV878 469 MTV878
diff --git a/MAINTAINERS b/MAINTAINERS
index 71e40f9118df..92203a35d233 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -5697,12 +5697,6 @@ M: Ion Badulescu <ionut@badula.org>
5697S: Odd Fixes 5697S: Odd Fixes
5698F: drivers/net/starfire* 5698F: drivers/net/starfire*
5699 5699
5700STRADIS MPEG-2 DECODER DRIVER
5701M: Nathan Laredo <laredo@gnu.org>
5702W: http://www.stradis.com/
5703S: Maintained
5704F: drivers/media/video/stradis.c
5705
5706SUN3/3X 5700SUN3/3X
5707M: Sam Creasey <sammy@sammy.net> 5701M: Sam Creasey <sammy@sammy.net>
5708W: http://sammy.net/sun3/ 5702W: http://sammy.net/sun3/
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index d9e3b6ddf682..7e7b27b3ddb0 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -51,10 +51,6 @@ source "drivers/staging/cx25821/Kconfig"
51 51
52source "drivers/staging/tm6000/Kconfig" 52source "drivers/staging/tm6000/Kconfig"
53 53
54source "drivers/staging/cpia/Kconfig"
55
56source "drivers/staging/stradis/Kconfig"
57
58source "drivers/staging/se401/Kconfig" 54source "drivers/staging/se401/Kconfig"
59 55
60source "drivers/staging/usbvideo/Kconfig" 56source "drivers/staging/usbvideo/Kconfig"
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index 8058a15b0cd7..72e0c839ea34 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -8,8 +8,6 @@ obj-$(CONFIG_SLICOSS) += slicoss/
8obj-$(CONFIG_VIDEO_GO7007) += go7007/ 8obj-$(CONFIG_VIDEO_GO7007) += go7007/
9obj-$(CONFIG_VIDEO_CX25821) += cx25821/ 9obj-$(CONFIG_VIDEO_CX25821) += cx25821/
10obj-$(CONFIG_VIDEO_TM6000) += tm6000/ 10obj-$(CONFIG_VIDEO_TM6000) += tm6000/
11obj-$(CONFIG_VIDEO_CPIA) += cpia/
12obj-$(CONFIG_VIDEO_STRADIS) += stradis/
13obj-$(CONFIG_USB_VICAM) += usbvideo/ 11obj-$(CONFIG_USB_VICAM) += usbvideo/
14obj-$(CONFIG_USB_SE401) += se401/ 12obj-$(CONFIG_USB_SE401) += se401/
15obj-$(CONFIG_LIRC_STAGING) += lirc/ 13obj-$(CONFIG_LIRC_STAGING) += lirc/
diff --git a/drivers/staging/cpia/Kconfig b/drivers/staging/cpia/Kconfig
deleted file mode 100644
index 205d247ad373..000000000000
--- a/drivers/staging/cpia/Kconfig
+++ /dev/null
@@ -1,39 +0,0 @@
1config VIDEO_CPIA
2 tristate "CPiA Video For Linux (DEPRECATED)"
3 depends on VIDEO_V4L1
4 default n
5 ---help---
6 This driver is DEPRECATED please use the gspca cpia1 module
7 instead. Note that you need atleast version 0.6.4 of libv4l for
8 the cpia1 gspca module.
9
10 This is the video4linux driver for cameras based on Vision's CPiA
11 (Colour Processor Interface ASIC), such as the Creative Labs Video
12 Blaster Webcam II. If you have one of these cameras, say Y here
13 and select parallel port and/or USB lowlevel support below,
14 otherwise say N. This will not work with the Creative Webcam III.
15
16 Please read <file:Documentation/video4linux/README.cpia> for more
17 information.
18
19 This driver is also available as a module (cpia).
20
21config VIDEO_CPIA_PP
22 tristate "CPiA Parallel Port Lowlevel Support"
23 depends on PARPORT_1284 && VIDEO_CPIA && PARPORT
24 help
25 This is the lowlevel parallel port support for cameras based on
26 Vision's CPiA (Colour Processor Interface ASIC), such as the
27 Creative Webcam II. If you have the parallel port version of one
28 of these cameras, say Y here, otherwise say N. It is also available
29 as a module (cpia_pp).
30
31config VIDEO_CPIA_USB
32 tristate "CPiA USB Lowlevel Support"
33 depends on VIDEO_CPIA && USB
34 help
35 This is the lowlevel USB support for cameras based on Vision's CPiA
36 (Colour Processor Interface ASIC), such as the Creative Webcam II.
37 If you have the USB version of one of these cameras, say Y here,
38 otherwise say N. This will not work with the Creative Webcam III.
39 It is also available as a module (cpia_usb).
diff --git a/drivers/staging/cpia/Makefile b/drivers/staging/cpia/Makefile
deleted file mode 100644
index 89e52f10d739..000000000000
--- a/drivers/staging/cpia/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
1obj-$(CONFIG_VIDEO_CPIA) += cpia.o
2obj-$(CONFIG_VIDEO_CPIA_PP) += cpia_pp.o
3obj-$(CONFIG_VIDEO_CPIA_USB) += cpia_usb.o
4
5EXTRA_CFLAGS += -Idrivers/media/video
diff --git a/drivers/staging/cpia/TODO b/drivers/staging/cpia/TODO
deleted file mode 100644
index ccb1c0775eec..000000000000
--- a/drivers/staging/cpia/TODO
+++ /dev/null
@@ -1,8 +0,0 @@
1This is an obsolete driver for some cpia-based webcams that use the parallel port.
2We couldn't find anyone with this hardware in order to port it to use V4L2.
3
4Also, parallel-port webcams are obsolete nowadays.
5
6If nobody take care on it, the driver will be removed for 2.6.38.
7
8Please send patches to linux-media@vger.kernel.org
diff --git a/drivers/staging/cpia/cpia.c b/drivers/staging/cpia/cpia.c
deleted file mode 100644
index 0e740b8dafc3..000000000000
--- a/drivers/staging/cpia/cpia.c
+++ /dev/null
@@ -1,4028 +0,0 @@
1/*
2 * cpia CPiA driver
3 *
4 * Supports CPiA based Video Camera's.
5 *
6 * (C) Copyright 1999-2000 Peter Pregler
7 * (C) Copyright 1999-2000 Scott J. Bertin
8 * (C) Copyright 1999-2000 Johannes Erdfelt <johannes@erdfelt.com>
9 * (C) Copyright 2000 STMicroelectronics
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25
26/* define _CPIA_DEBUG_ for verbose debug output (see cpia.h) */
27/* #define _CPIA_DEBUG_ 1 */
28
29
30#include <linux/module.h>
31#include <linux/init.h>
32#include <linux/fs.h>
33#include <linux/vmalloc.h>
34#include <linux/sched.h>
35#include <linux/seq_file.h>
36#include <linux/slab.h>
37#include <linux/proc_fs.h>
38#include <linux/ctype.h>
39#include <linux/pagemap.h>
40#include <linux/delay.h>
41#include <asm/io.h>
42#include <linux/mutex.h>
43
44#include "cpia.h"
45
46static int video_nr = -1;
47
48#ifdef MODULE
49module_param(video_nr, int, 0);
50MODULE_AUTHOR("Scott J. Bertin <sbertin@securenym.net> & Peter Pregler <Peter_Pregler@email.com> & Johannes Erdfelt <johannes@erdfelt.com>");
51MODULE_DESCRIPTION("V4L-driver for Vision CPiA based cameras");
52MODULE_LICENSE("GPL");
53MODULE_SUPPORTED_DEVICE("video");
54#endif
55
56static unsigned short colorspace_conv;
57module_param(colorspace_conv, ushort, 0444);
58MODULE_PARM_DESC(colorspace_conv,
59 " Colorspace conversion:"
60 "\n 0 = disable, 1 = enable"
61 "\n Default value is 0"
62 );
63
64#define ABOUT "V4L-Driver for Vision CPiA based cameras"
65
66#define CPIA_MODULE_CPIA (0<<5)
67#define CPIA_MODULE_SYSTEM (1<<5)
68#define CPIA_MODULE_VP_CTRL (5<<5)
69#define CPIA_MODULE_CAPTURE (6<<5)
70#define CPIA_MODULE_DEBUG (7<<5)
71
72#define INPUT (DATA_IN << 8)
73#define OUTPUT (DATA_OUT << 8)
74
75#define CPIA_COMMAND_GetCPIAVersion (INPUT | CPIA_MODULE_CPIA | 1)
76#define CPIA_COMMAND_GetPnPID (INPUT | CPIA_MODULE_CPIA | 2)
77#define CPIA_COMMAND_GetCameraStatus (INPUT | CPIA_MODULE_CPIA | 3)
78#define CPIA_COMMAND_GotoHiPower (OUTPUT | CPIA_MODULE_CPIA | 4)
79#define CPIA_COMMAND_GotoLoPower (OUTPUT | CPIA_MODULE_CPIA | 5)
80#define CPIA_COMMAND_GotoSuspend (OUTPUT | CPIA_MODULE_CPIA | 7)
81#define CPIA_COMMAND_GotoPassThrough (OUTPUT | CPIA_MODULE_CPIA | 8)
82#define CPIA_COMMAND_ModifyCameraStatus (OUTPUT | CPIA_MODULE_CPIA | 10)
83
84#define CPIA_COMMAND_ReadVCRegs (INPUT | CPIA_MODULE_SYSTEM | 1)
85#define CPIA_COMMAND_WriteVCReg (OUTPUT | CPIA_MODULE_SYSTEM | 2)
86#define CPIA_COMMAND_ReadMCPorts (INPUT | CPIA_MODULE_SYSTEM | 3)
87#define CPIA_COMMAND_WriteMCPort (OUTPUT | CPIA_MODULE_SYSTEM | 4)
88#define CPIA_COMMAND_SetBaudRate (OUTPUT | CPIA_MODULE_SYSTEM | 5)
89#define CPIA_COMMAND_SetECPTiming (OUTPUT | CPIA_MODULE_SYSTEM | 6)
90#define CPIA_COMMAND_ReadIDATA (INPUT | CPIA_MODULE_SYSTEM | 7)
91#define CPIA_COMMAND_WriteIDATA (OUTPUT | CPIA_MODULE_SYSTEM | 8)
92#define CPIA_COMMAND_GenericCall (OUTPUT | CPIA_MODULE_SYSTEM | 9)
93#define CPIA_COMMAND_I2CStart (OUTPUT | CPIA_MODULE_SYSTEM | 10)
94#define CPIA_COMMAND_I2CStop (OUTPUT | CPIA_MODULE_SYSTEM | 11)
95#define CPIA_COMMAND_I2CWrite (OUTPUT | CPIA_MODULE_SYSTEM | 12)
96#define CPIA_COMMAND_I2CRead (INPUT | CPIA_MODULE_SYSTEM | 13)
97
98#define CPIA_COMMAND_GetVPVersion (INPUT | CPIA_MODULE_VP_CTRL | 1)
99#define CPIA_COMMAND_ResetFrameCounter (INPUT | CPIA_MODULE_VP_CTRL | 2)
100#define CPIA_COMMAND_SetColourParams (OUTPUT | CPIA_MODULE_VP_CTRL | 3)
101#define CPIA_COMMAND_SetExposure (OUTPUT | CPIA_MODULE_VP_CTRL | 4)
102#define CPIA_COMMAND_SetColourBalance (OUTPUT | CPIA_MODULE_VP_CTRL | 6)
103#define CPIA_COMMAND_SetSensorFPS (OUTPUT | CPIA_MODULE_VP_CTRL | 7)
104#define CPIA_COMMAND_SetVPDefaults (OUTPUT | CPIA_MODULE_VP_CTRL | 8)
105#define CPIA_COMMAND_SetApcor (OUTPUT | CPIA_MODULE_VP_CTRL | 9)
106#define CPIA_COMMAND_SetFlickerCtrl (OUTPUT | CPIA_MODULE_VP_CTRL | 10)
107#define CPIA_COMMAND_SetVLOffset (OUTPUT | CPIA_MODULE_VP_CTRL | 11)
108#define CPIA_COMMAND_GetColourParams (INPUT | CPIA_MODULE_VP_CTRL | 16)
109#define CPIA_COMMAND_GetColourBalance (INPUT | CPIA_MODULE_VP_CTRL | 17)
110#define CPIA_COMMAND_GetExposure (INPUT | CPIA_MODULE_VP_CTRL | 18)
111#define CPIA_COMMAND_SetSensorMatrix (OUTPUT | CPIA_MODULE_VP_CTRL | 19)
112#define CPIA_COMMAND_ColourBars (OUTPUT | CPIA_MODULE_VP_CTRL | 25)
113#define CPIA_COMMAND_ReadVPRegs (INPUT | CPIA_MODULE_VP_CTRL | 30)
114#define CPIA_COMMAND_WriteVPReg (OUTPUT | CPIA_MODULE_VP_CTRL | 31)
115
116#define CPIA_COMMAND_GrabFrame (OUTPUT | CPIA_MODULE_CAPTURE | 1)
117#define CPIA_COMMAND_UploadFrame (OUTPUT | CPIA_MODULE_CAPTURE | 2)
118#define CPIA_COMMAND_SetGrabMode (OUTPUT | CPIA_MODULE_CAPTURE | 3)
119#define CPIA_COMMAND_InitStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 4)
120#define CPIA_COMMAND_FiniStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 5)
121#define CPIA_COMMAND_StartStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 6)
122#define CPIA_COMMAND_EndStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 7)
123#define CPIA_COMMAND_SetFormat (OUTPUT | CPIA_MODULE_CAPTURE | 8)
124#define CPIA_COMMAND_SetROI (OUTPUT | CPIA_MODULE_CAPTURE | 9)
125#define CPIA_COMMAND_SetCompression (OUTPUT | CPIA_MODULE_CAPTURE | 10)
126#define CPIA_COMMAND_SetCompressionTarget (OUTPUT | CPIA_MODULE_CAPTURE | 11)
127#define CPIA_COMMAND_SetYUVThresh (OUTPUT | CPIA_MODULE_CAPTURE | 12)
128#define CPIA_COMMAND_SetCompressionParams (OUTPUT | CPIA_MODULE_CAPTURE | 13)
129#define CPIA_COMMAND_DiscardFrame (OUTPUT | CPIA_MODULE_CAPTURE | 14)
130#define CPIA_COMMAND_GrabReset (OUTPUT | CPIA_MODULE_CAPTURE | 15)
131
132#define CPIA_COMMAND_OutputRS232 (OUTPUT | CPIA_MODULE_DEBUG | 1)
133#define CPIA_COMMAND_AbortProcess (OUTPUT | CPIA_MODULE_DEBUG | 4)
134#define CPIA_COMMAND_SetDramPage (OUTPUT | CPIA_MODULE_DEBUG | 5)
135#define CPIA_COMMAND_StartDramUpload (OUTPUT | CPIA_MODULE_DEBUG | 6)
136#define CPIA_COMMAND_StartDummyDtream (OUTPUT | CPIA_MODULE_DEBUG | 8)
137#define CPIA_COMMAND_AbortStream (OUTPUT | CPIA_MODULE_DEBUG | 9)
138#define CPIA_COMMAND_DownloadDRAM (OUTPUT | CPIA_MODULE_DEBUG | 10)
139#define CPIA_COMMAND_Null (OUTPUT | CPIA_MODULE_DEBUG | 11)
140
141enum {
142 FRAME_READY, /* Ready to grab into */
143 FRAME_GRABBING, /* In the process of being grabbed into */
144 FRAME_DONE, /* Finished grabbing, but not been synced yet */
145 FRAME_UNUSED, /* Unused (no MCAPTURE) */
146};
147
148#define COMMAND_NONE 0x0000
149#define COMMAND_SETCOMPRESSION 0x0001
150#define COMMAND_SETCOMPRESSIONTARGET 0x0002
151#define COMMAND_SETCOLOURPARAMS 0x0004
152#define COMMAND_SETFORMAT 0x0008
153#define COMMAND_PAUSE 0x0010
154#define COMMAND_RESUME 0x0020
155#define COMMAND_SETYUVTHRESH 0x0040
156#define COMMAND_SETECPTIMING 0x0080
157#define COMMAND_SETCOMPRESSIONPARAMS 0x0100
158#define COMMAND_SETEXPOSURE 0x0200
159#define COMMAND_SETCOLOURBALANCE 0x0400
160#define COMMAND_SETSENSORFPS 0x0800
161#define COMMAND_SETAPCOR 0x1000
162#define COMMAND_SETFLICKERCTRL 0x2000
163#define COMMAND_SETVLOFFSET 0x4000
164#define COMMAND_SETLIGHTS 0x8000
165
166#define ROUND_UP_EXP_FOR_FLICKER 15
167
168/* Constants for automatic frame rate adjustment */
169#define MAX_EXP 302
170#define MAX_EXP_102 255
171#define LOW_EXP 140
172#define VERY_LOW_EXP 70
173#define TC 94
174#define EXP_ACC_DARK 50
175#define EXP_ACC_LIGHT 90
176#define HIGH_COMP_102 160
177#define MAX_COMP 239
178#define DARK_TIME 3
179#define LIGHT_TIME 3
180
181/* Maximum number of 10ms loops to wait for the stream to become ready */
182#define READY_TIMEOUT 100
183
184/* Developer's Guide Table 5 p 3-34
185 * indexed by [mains][sensorFps.baserate][sensorFps.divisor]*/
186static u8 flicker_jumps[2][2][4] =
187{ { { 76, 38, 19, 9 }, { 92, 46, 23, 11 } },
188 { { 64, 32, 16, 8 }, { 76, 38, 19, 9} }
189};
190
191/* forward declaration of local function */
192static void reset_camera_struct(struct cam_data *cam);
193static int find_over_exposure(int brightness);
194static void set_flicker(struct cam_params *params, volatile u32 *command_flags,
195 int on);
196
197
198/**********************************************************************
199 *
200 * Memory management
201 *
202 **********************************************************************/
203static void *rvmalloc(unsigned long size)
204{
205 void *mem;
206 unsigned long adr;
207
208 size = PAGE_ALIGN(size);
209 mem = vmalloc_32(size);
210 if (!mem)
211 return NULL;
212
213 memset(mem, 0, size); /* Clear the ram out, no junk to the user */
214 adr = (unsigned long) mem;
215 while (size > 0) {
216 SetPageReserved(vmalloc_to_page((void *)adr));
217 adr += PAGE_SIZE;
218 size -= PAGE_SIZE;
219 }
220
221 return mem;
222}
223
224static void rvfree(void *mem, unsigned long size)
225{
226 unsigned long adr;
227
228 if (!mem)
229 return;
230
231 adr = (unsigned long) mem;
232 while ((long) size > 0) {
233 ClearPageReserved(vmalloc_to_page((void *)adr));
234 adr += PAGE_SIZE;
235 size -= PAGE_SIZE;
236 }
237 vfree(mem);
238}
239
240/**********************************************************************
241 *
242 * /proc interface
243 *
244 **********************************************************************/
245#ifdef CONFIG_PROC_FS
246static struct proc_dir_entry *cpia_proc_root=NULL;
247
248static int cpia_proc_show(struct seq_file *m, void *v)
249{
250 struct cam_data *cam = m->private;
251 int tmp;
252 char tmpstr[29];
253
254 seq_printf(m, "read-only\n-----------------------\n");
255 seq_printf(m, "V4L Driver version: %d.%d.%d\n",
256 CPIA_MAJ_VER, CPIA_MIN_VER, CPIA_PATCH_VER);
257 seq_printf(m, "CPIA Version: %d.%02d (%d.%d)\n",
258 cam->params.version.firmwareVersion,
259 cam->params.version.firmwareRevision,
260 cam->params.version.vcVersion,
261 cam->params.version.vcRevision);
262 seq_printf(m, "CPIA PnP-ID: %04x:%04x:%04x\n",
263 cam->params.pnpID.vendor, cam->params.pnpID.product,
264 cam->params.pnpID.deviceRevision);
265 seq_printf(m, "VP-Version: %d.%d %04x\n",
266 cam->params.vpVersion.vpVersion,
267 cam->params.vpVersion.vpRevision,
268 cam->params.vpVersion.cameraHeadID);
269
270 seq_printf(m, "system_state: %#04x\n",
271 cam->params.status.systemState);
272 seq_printf(m, "grab_state: %#04x\n",
273 cam->params.status.grabState);
274 seq_printf(m, "stream_state: %#04x\n",
275 cam->params.status.streamState);
276 seq_printf(m, "fatal_error: %#04x\n",
277 cam->params.status.fatalError);
278 seq_printf(m, "cmd_error: %#04x\n",
279 cam->params.status.cmdError);
280 seq_printf(m, "debug_flags: %#04x\n",
281 cam->params.status.debugFlags);
282 seq_printf(m, "vp_status: %#04x\n",
283 cam->params.status.vpStatus);
284 seq_printf(m, "error_code: %#04x\n",
285 cam->params.status.errorCode);
286 /* QX3 specific entries */
287 if (cam->params.qx3.qx3_detected) {
288 seq_printf(m, "button: %4d\n",
289 cam->params.qx3.button);
290 seq_printf(m, "cradled: %4d\n",
291 cam->params.qx3.cradled);
292 }
293 seq_printf(m, "video_size: %s\n",
294 cam->params.format.videoSize == VIDEOSIZE_CIF ?
295 "CIF " : "QCIF");
296 seq_printf(m, "roi: (%3d, %3d) to (%3d, %3d)\n",
297 cam->params.roi.colStart*8,
298 cam->params.roi.rowStart*4,
299 cam->params.roi.colEnd*8,
300 cam->params.roi.rowEnd*4);
301 seq_printf(m, "actual_fps: %3d\n", cam->fps);
302 seq_printf(m, "transfer_rate: %4dkB/s\n",
303 cam->transfer_rate);
304
305 seq_printf(m, "\nread-write\n");
306 seq_printf(m, "----------------------- current min"
307 " max default comment\n");
308 seq_printf(m, "brightness: %8d %8d %8d %8d\n",
309 cam->params.colourParams.brightness, 0, 100, 50);
310 if (cam->params.version.firmwareVersion == 1 &&
311 cam->params.version.firmwareRevision == 2)
312 /* 1-02 firmware limits contrast to 80 */
313 tmp = 80;
314 else
315 tmp = 96;
316
317 seq_printf(m, "contrast: %8d %8d %8d %8d"
318 " steps of 8\n",
319 cam->params.colourParams.contrast, 0, tmp, 48);
320 seq_printf(m, "saturation: %8d %8d %8d %8d\n",
321 cam->params.colourParams.saturation, 0, 100, 50);
322 tmp = (25000+5000*cam->params.sensorFps.baserate)/
323 (1<<cam->params.sensorFps.divisor);
324 seq_printf(m, "sensor_fps: %4d.%03d %8d %8d %8d\n",
325 tmp/1000, tmp%1000, 3, 30, 15);
326 seq_printf(m, "stream_start_line: %8d %8d %8d %8d\n",
327 2*cam->params.streamStartLine, 0,
328 cam->params.format.videoSize == VIDEOSIZE_CIF ? 288:144,
329 cam->params.format.videoSize == VIDEOSIZE_CIF ? 240:120);
330 seq_printf(m, "sub_sample: %8s %8s %8s %8s\n",
331 cam->params.format.subSample == SUBSAMPLE_420 ?
332 "420" : "422", "420", "422", "422");
333 seq_printf(m, "yuv_order: %8s %8s %8s %8s\n",
334 cam->params.format.yuvOrder == YUVORDER_YUYV ?
335 "YUYV" : "UYVY", "YUYV" , "UYVY", "YUYV");
336 seq_printf(m, "ecp_timing: %8s %8s %8s %8s\n",
337 cam->params.ecpTiming ? "slow" : "normal", "slow",
338 "normal", "normal");
339
340 if (cam->params.colourBalance.balanceMode == 2) {
341 sprintf(tmpstr, "auto");
342 } else {
343 sprintf(tmpstr, "manual");
344 }
345 seq_printf(m, "color_balance_mode: %8s %8s %8s"
346 " %8s\n", tmpstr, "manual", "auto", "auto");
347 seq_printf(m, "red_gain: %8d %8d %8d %8d\n",
348 cam->params.colourBalance.redGain, 0, 212, 32);
349 seq_printf(m, "green_gain: %8d %8d %8d %8d\n",
350 cam->params.colourBalance.greenGain, 0, 212, 6);
351 seq_printf(m, "blue_gain: %8d %8d %8d %8d\n",
352 cam->params.colourBalance.blueGain, 0, 212, 92);
353
354 if (cam->params.version.firmwareVersion == 1 &&
355 cam->params.version.firmwareRevision == 2)
356 /* 1-02 firmware limits gain to 2 */
357 sprintf(tmpstr, "%8d %8d %8d", 1, 2, 2);
358 else
359 sprintf(tmpstr, "%8d %8d %8d", 1, 8, 2);
360
361 if (cam->params.exposure.gainMode == 0)
362 seq_printf(m, "max_gain: unknown %28s"
363 " powers of 2\n", tmpstr);
364 else
365 seq_printf(m, "max_gain: %8d %28s"
366 " 1,2,4 or 8 \n",
367 1<<(cam->params.exposure.gainMode-1), tmpstr);
368
369 switch(cam->params.exposure.expMode) {
370 case 1:
371 case 3:
372 sprintf(tmpstr, "manual");
373 break;
374 case 2:
375 sprintf(tmpstr, "auto");
376 break;
377 default:
378 sprintf(tmpstr, "unknown");
379 break;
380 }
381 seq_printf(m, "exposure_mode: %8s %8s %8s"
382 " %8s\n", tmpstr, "manual", "auto", "auto");
383 seq_printf(m, "centre_weight: %8s %8s %8s %8s\n",
384 (2-cam->params.exposure.centreWeight) ? "on" : "off",
385 "off", "on", "on");
386 seq_printf(m, "gain: %8d %8d max_gain %8d 1,2,4,8 possible\n",
387 1<<cam->params.exposure.gain, 1, 1);
388 if (cam->params.version.firmwareVersion == 1 &&
389 cam->params.version.firmwareRevision == 2)
390 /* 1-02 firmware limits fineExp/2 to 127 */
391 tmp = 254;
392 else
393 tmp = 510;
394
395 seq_printf(m, "fine_exp: %8d %8d %8d %8d\n",
396 cam->params.exposure.fineExp*2, 0, tmp, 0);
397 if (cam->params.version.firmwareVersion == 1 &&
398 cam->params.version.firmwareRevision == 2)
399 /* 1-02 firmware limits coarseExpHi to 0 */
400 tmp = MAX_EXP_102;
401 else
402 tmp = MAX_EXP;
403
404 seq_printf(m, "coarse_exp: %8d %8d %8d"
405 " %8d\n", cam->params.exposure.coarseExpLo+
406 256*cam->params.exposure.coarseExpHi, 0, tmp, 185);
407 seq_printf(m, "red_comp: %8d %8d %8d %8d\n",
408 cam->params.exposure.redComp, COMP_RED, 255, COMP_RED);
409 seq_printf(m, "green1_comp: %8d %8d %8d %8d\n",
410 cam->params.exposure.green1Comp, COMP_GREEN1, 255,
411 COMP_GREEN1);
412 seq_printf(m, "green2_comp: %8d %8d %8d %8d\n",
413 cam->params.exposure.green2Comp, COMP_GREEN2, 255,
414 COMP_GREEN2);
415 seq_printf(m, "blue_comp: %8d %8d %8d %8d\n",
416 cam->params.exposure.blueComp, COMP_BLUE, 255, COMP_BLUE);
417
418 seq_printf(m, "apcor_gain1: %#8x %#8x %#8x %#8x\n",
419 cam->params.apcor.gain1, 0, 0xff, 0x1c);
420 seq_printf(m, "apcor_gain2: %#8x %#8x %#8x %#8x\n",
421 cam->params.apcor.gain2, 0, 0xff, 0x1a);
422 seq_printf(m, "apcor_gain4: %#8x %#8x %#8x %#8x\n",
423 cam->params.apcor.gain4, 0, 0xff, 0x2d);
424 seq_printf(m, "apcor_gain8: %#8x %#8x %#8x %#8x\n",
425 cam->params.apcor.gain8, 0, 0xff, 0x2a);
426 seq_printf(m, "vl_offset_gain1: %8d %8d %8d %8d\n",
427 cam->params.vlOffset.gain1, 0, 255, 24);
428 seq_printf(m, "vl_offset_gain2: %8d %8d %8d %8d\n",
429 cam->params.vlOffset.gain2, 0, 255, 28);
430 seq_printf(m, "vl_offset_gain4: %8d %8d %8d %8d\n",
431 cam->params.vlOffset.gain4, 0, 255, 30);
432 seq_printf(m, "vl_offset_gain8: %8d %8d %8d %8d\n",
433 cam->params.vlOffset.gain8, 0, 255, 30);
434 seq_printf(m, "flicker_control: %8s %8s %8s %8s\n",
435 cam->params.flickerControl.flickerMode ? "on" : "off",
436 "off", "on", "off");
437 seq_printf(m, "mains_frequency: %8d %8d %8d %8d"
438 " only 50/60\n",
439 cam->mainsFreq ? 60 : 50, 50, 60, 50);
440 if(cam->params.flickerControl.allowableOverExposure < 0)
441 seq_printf(m, "allowable_overexposure: %4dauto auto %8d auto\n",
442 -cam->params.flickerControl.allowableOverExposure,
443 255);
444 else
445 seq_printf(m, "allowable_overexposure: %8d auto %8d auto\n",
446 cam->params.flickerControl.allowableOverExposure,
447 255);
448 seq_printf(m, "compression_mode: ");
449 switch(cam->params.compression.mode) {
450 case CPIA_COMPRESSION_NONE:
451 seq_printf(m, "%8s", "none");
452 break;
453 case CPIA_COMPRESSION_AUTO:
454 seq_printf(m, "%8s", "auto");
455 break;
456 case CPIA_COMPRESSION_MANUAL:
457 seq_printf(m, "%8s", "manual");
458 break;
459 default:
460 seq_printf(m, "%8s", "unknown");
461 break;
462 }
463 seq_printf(m, " none,auto,manual auto\n");
464 seq_printf(m, "decimation_enable: %8s %8s %8s %8s\n",
465 cam->params.compression.decimation ==
466 DECIMATION_ENAB ? "on":"off", "off", "on",
467 "off");
468 seq_printf(m, "compression_target: %9s %9s %9s %9s\n",
469 cam->params.compressionTarget.frTargeting ==
470 CPIA_COMPRESSION_TARGET_FRAMERATE ?
471 "framerate":"quality",
472 "framerate", "quality", "quality");
473 seq_printf(m, "target_framerate: %8d %8d %8d %8d\n",
474 cam->params.compressionTarget.targetFR, 1, 30, 15);
475 seq_printf(m, "target_quality: %8d %8d %8d %8d\n",
476 cam->params.compressionTarget.targetQ, 1, 64, 5);
477 seq_printf(m, "y_threshold: %8d %8d %8d %8d\n",
478 cam->params.yuvThreshold.yThreshold, 0, 31, 6);
479 seq_printf(m, "uv_threshold: %8d %8d %8d %8d\n",
480 cam->params.yuvThreshold.uvThreshold, 0, 31, 6);
481 seq_printf(m, "hysteresis: %8d %8d %8d %8d\n",
482 cam->params.compressionParams.hysteresis, 0, 255, 3);
483 seq_printf(m, "threshold_max: %8d %8d %8d %8d\n",
484 cam->params.compressionParams.threshMax, 0, 255, 11);
485 seq_printf(m, "small_step: %8d %8d %8d %8d\n",
486 cam->params.compressionParams.smallStep, 0, 255, 1);
487 seq_printf(m, "large_step: %8d %8d %8d %8d\n",
488 cam->params.compressionParams.largeStep, 0, 255, 3);
489 seq_printf(m, "decimation_hysteresis: %8d %8d %8d %8d\n",
490 cam->params.compressionParams.decimationHysteresis,
491 0, 255, 2);
492 seq_printf(m, "fr_diff_step_thresh: %8d %8d %8d %8d\n",
493 cam->params.compressionParams.frDiffStepThresh,
494 0, 255, 5);
495 seq_printf(m, "q_diff_step_thresh: %8d %8d %8d %8d\n",
496 cam->params.compressionParams.qDiffStepThresh,
497 0, 255, 3);
498 seq_printf(m, "decimation_thresh_mod: %8d %8d %8d %8d\n",
499 cam->params.compressionParams.decimationThreshMod,
500 0, 255, 2);
501 /* QX3 specific entries */
502 if (cam->params.qx3.qx3_detected) {
503 seq_printf(m, "toplight: %8s %8s %8s %8s\n",
504 cam->params.qx3.toplight ? "on" : "off",
505 "off", "on", "off");
506 seq_printf(m, "bottomlight: %8s %8s %8s %8s\n",
507 cam->params.qx3.bottomlight ? "on" : "off",
508 "off", "on", "off");
509 }
510
511 return 0;
512}
513
514static int cpia_proc_open(struct inode *inode, struct file *file)
515{
516 return single_open(file, cpia_proc_show, PDE(inode)->data);
517}
518
519static int match(char *checkstr, char **buffer, size_t *count,
520 int *find_colon, int *err)
521{
522 int ret, colon_found = 1;
523 int len = strlen(checkstr);
524 ret = (len <= *count && strncmp(*buffer, checkstr, len) == 0);
525 if (ret) {
526 *buffer += len;
527 *count -= len;
528 if (*find_colon) {
529 colon_found = 0;
530 while (*count && (**buffer == ' ' || **buffer == '\t' ||
531 (!colon_found && **buffer == ':'))) {
532 if (**buffer == ':')
533 colon_found = 1;
534 --*count;
535 ++*buffer;
536 }
537 if (!*count || !colon_found)
538 *err = -EINVAL;
539 *find_colon = 0;
540 }
541 }
542 return ret;
543}
544
545static unsigned long int value(char **buffer, size_t *count, int *err)
546{
547 char *p;
548 unsigned long int ret;
549 ret = simple_strtoul(*buffer, &p, 0);
550 if (p == *buffer)
551 *err = -EINVAL;
552 else {
553 *count -= p - *buffer;
554 *buffer = p;
555 }
556 return ret;
557}
558
559static ssize_t cpia_proc_write(struct file *file, const char __user *buf,
560 size_t count, loff_t *pos)
561{
562 struct cam_data *cam = PDE(file->f_path.dentry->d_inode)->data;
563 struct cam_params new_params;
564 char *page, *buffer;
565 int retval, find_colon;
566 int size = count;
567 unsigned long val = 0;
568 u32 command_flags = 0;
569 u8 new_mains;
570
571 /*
572 * This code to copy from buf to page is shamelessly copied
573 * from the comx driver
574 */
575 if (count > PAGE_SIZE) {
576 printk(KERN_ERR "count is %zu > %d!!!\n", count, (int)PAGE_SIZE);
577 return -ENOSPC;
578 }
579
580 if (!(page = (char *)__get_free_page(GFP_KERNEL))) return -ENOMEM;
581
582 if(copy_from_user(page, buf, count))
583 {
584 retval = -EFAULT;
585 goto out;
586 }
587
588 if (page[count-1] == '\n')
589 page[count-1] = '\0';
590 else if (count < PAGE_SIZE)
591 page[count] = '\0';
592 else if (page[count]) {
593 retval = -EINVAL;
594 goto out;
595 }
596
597 buffer = page;
598
599 if (mutex_lock_interruptible(&cam->param_lock))
600 return -ERESTARTSYS;
601
602 /*
603 * Skip over leading whitespace
604 */
605 while (count && isspace(*buffer)) {
606 --count;
607 ++buffer;
608 }
609
610 memcpy(&new_params, &cam->params, sizeof(struct cam_params));
611 new_mains = cam->mainsFreq;
612
613#define MATCH(x) (match(x, &buffer, &count, &find_colon, &retval))
614#define VALUE (value(&buffer,&count, &retval))
615#define FIRMWARE_VERSION(x,y) (new_params.version.firmwareVersion == (x) && \
616 new_params.version.firmwareRevision == (y))
617
618 retval = 0;
619 while (count && !retval) {
620 find_colon = 1;
621 if (MATCH("brightness")) {
622 if (!retval)
623 val = VALUE;
624
625 if (!retval) {
626 if (val <= 100)
627 new_params.colourParams.brightness = val;
628 else
629 retval = -EINVAL;
630 }
631 command_flags |= COMMAND_SETCOLOURPARAMS;
632 if(new_params.flickerControl.allowableOverExposure < 0)
633 new_params.flickerControl.allowableOverExposure =
634 -find_over_exposure(new_params.colourParams.brightness);
635 if(new_params.flickerControl.flickerMode != 0)
636 command_flags |= COMMAND_SETFLICKERCTRL;
637
638 } else if (MATCH("contrast")) {
639 if (!retval)
640 val = VALUE;
641
642 if (!retval) {
643 if (val <= 100) {
644 /* contrast is in steps of 8, so round*/
645 val = ((val + 3) / 8) * 8;
646 /* 1-02 firmware limits contrast to 80*/
647 if (FIRMWARE_VERSION(1,2) && val > 80)
648 val = 80;
649
650 new_params.colourParams.contrast = val;
651 } else
652 retval = -EINVAL;
653 }
654 command_flags |= COMMAND_SETCOLOURPARAMS;
655 } else if (MATCH("saturation")) {
656 if (!retval)
657 val = VALUE;
658
659 if (!retval) {
660 if (val <= 100)
661 new_params.colourParams.saturation = val;
662 else
663 retval = -EINVAL;
664 }
665 command_flags |= COMMAND_SETCOLOURPARAMS;
666 } else if (MATCH("sensor_fps")) {
667 if (!retval)
668 val = VALUE;
669
670 if (!retval) {
671 /* find values so that sensorFPS is minimized,
672 * but >= val */
673 if (val > 30)
674 retval = -EINVAL;
675 else if (val > 25) {
676 new_params.sensorFps.divisor = 0;
677 new_params.sensorFps.baserate = 1;
678 } else if (val > 15) {
679 new_params.sensorFps.divisor = 0;
680 new_params.sensorFps.baserate = 0;
681 } else if (val > 12) {
682 new_params.sensorFps.divisor = 1;
683 new_params.sensorFps.baserate = 1;
684 } else if (val > 7) {
685 new_params.sensorFps.divisor = 1;
686 new_params.sensorFps.baserate = 0;
687 } else if (val > 6) {
688 new_params.sensorFps.divisor = 2;
689 new_params.sensorFps.baserate = 1;
690 } else if (val > 3) {
691 new_params.sensorFps.divisor = 2;
692 new_params.sensorFps.baserate = 0;
693 } else {
694 new_params.sensorFps.divisor = 3;
695 /* Either base rate would work here */
696 new_params.sensorFps.baserate = 1;
697 }
698 new_params.flickerControl.coarseJump =
699 flicker_jumps[new_mains]
700 [new_params.sensorFps.baserate]
701 [new_params.sensorFps.divisor];
702 if (new_params.flickerControl.flickerMode)
703 command_flags |= COMMAND_SETFLICKERCTRL;
704 }
705 command_flags |= COMMAND_SETSENSORFPS;
706 cam->exposure_status = EXPOSURE_NORMAL;
707 } else if (MATCH("stream_start_line")) {
708 if (!retval)
709 val = VALUE;
710
711 if (!retval) {
712 int max_line = 288;
713
714 if (new_params.format.videoSize == VIDEOSIZE_QCIF)
715 max_line = 144;
716 if (val <= max_line)
717 new_params.streamStartLine = val/2;
718 else
719 retval = -EINVAL;
720 }
721 } else if (MATCH("sub_sample")) {
722 if (!retval && MATCH("420"))
723 new_params.format.subSample = SUBSAMPLE_420;
724 else if (!retval && MATCH("422"))
725 new_params.format.subSample = SUBSAMPLE_422;
726 else
727 retval = -EINVAL;
728
729 command_flags |= COMMAND_SETFORMAT;
730 } else if (MATCH("yuv_order")) {
731 if (!retval && MATCH("YUYV"))
732 new_params.format.yuvOrder = YUVORDER_YUYV;
733 else if (!retval && MATCH("UYVY"))
734 new_params.format.yuvOrder = YUVORDER_UYVY;
735 else
736 retval = -EINVAL;
737
738 command_flags |= COMMAND_SETFORMAT;
739 } else if (MATCH("ecp_timing")) {
740 if (!retval && MATCH("normal"))
741 new_params.ecpTiming = 0;
742 else if (!retval && MATCH("slow"))
743 new_params.ecpTiming = 1;
744 else
745 retval = -EINVAL;
746
747 command_flags |= COMMAND_SETECPTIMING;
748 } else if (MATCH("color_balance_mode")) {
749 if (!retval && MATCH("manual"))
750 new_params.colourBalance.balanceMode = 3;
751 else if (!retval && MATCH("auto"))
752 new_params.colourBalance.balanceMode = 2;
753 else
754 retval = -EINVAL;
755
756 command_flags |= COMMAND_SETCOLOURBALANCE;
757 } else if (MATCH("red_gain")) {
758 if (!retval)
759 val = VALUE;
760
761 if (!retval) {
762 if (val <= 212) {
763 new_params.colourBalance.redGain = val;
764 new_params.colourBalance.balanceMode = 1;
765 } else
766 retval = -EINVAL;
767 }
768 command_flags |= COMMAND_SETCOLOURBALANCE;
769 } else if (MATCH("green_gain")) {
770 if (!retval)
771 val = VALUE;
772
773 if (!retval) {
774 if (val <= 212) {
775 new_params.colourBalance.greenGain = val;
776 new_params.colourBalance.balanceMode = 1;
777 } else
778 retval = -EINVAL;
779 }
780 command_flags |= COMMAND_SETCOLOURBALANCE;
781 } else if (MATCH("blue_gain")) {
782 if (!retval)
783 val = VALUE;
784
785 if (!retval) {
786 if (val <= 212) {
787 new_params.colourBalance.blueGain = val;
788 new_params.colourBalance.balanceMode = 1;
789 } else
790 retval = -EINVAL;
791 }
792 command_flags |= COMMAND_SETCOLOURBALANCE;
793 } else if (MATCH("max_gain")) {
794 if (!retval)
795 val = VALUE;
796
797 if (!retval) {
798 /* 1-02 firmware limits gain to 2 */
799 if (FIRMWARE_VERSION(1,2) && val > 2)
800 val = 2;
801 switch(val) {
802 case 1:
803 new_params.exposure.gainMode = 1;
804 break;
805 case 2:
806 new_params.exposure.gainMode = 2;
807 break;
808 case 4:
809 new_params.exposure.gainMode = 3;
810 break;
811 case 8:
812 new_params.exposure.gainMode = 4;
813 break;
814 default:
815 retval = -EINVAL;
816 break;
817 }
818 }
819 command_flags |= COMMAND_SETEXPOSURE;
820 } else if (MATCH("exposure_mode")) {
821 if (!retval && MATCH("auto"))
822 new_params.exposure.expMode = 2;
823 else if (!retval && MATCH("manual")) {
824 if (new_params.exposure.expMode == 2)
825 new_params.exposure.expMode = 3;
826 if(new_params.flickerControl.flickerMode != 0)
827 command_flags |= COMMAND_SETFLICKERCTRL;
828 new_params.flickerControl.flickerMode = 0;
829 } else
830 retval = -EINVAL;
831
832 command_flags |= COMMAND_SETEXPOSURE;
833 } else if (MATCH("centre_weight")) {
834 if (!retval && MATCH("on"))
835 new_params.exposure.centreWeight = 1;
836 else if (!retval && MATCH("off"))
837 new_params.exposure.centreWeight = 2;
838 else
839 retval = -EINVAL;
840
841 command_flags |= COMMAND_SETEXPOSURE;
842 } else if (MATCH("gain")) {
843 if (!retval)
844 val = VALUE;
845
846 if (!retval) {
847 switch(val) {
848 case 1:
849 new_params.exposure.gain = 0;
850 break;
851 case 2:
852 new_params.exposure.gain = 1;
853 break;
854 case 4:
855 new_params.exposure.gain = 2;
856 break;
857 case 8:
858 new_params.exposure.gain = 3;
859 break;
860 default:
861 retval = -EINVAL;
862 break;
863 }
864 new_params.exposure.expMode = 1;
865 if(new_params.flickerControl.flickerMode != 0)
866 command_flags |= COMMAND_SETFLICKERCTRL;
867 new_params.flickerControl.flickerMode = 0;
868 command_flags |= COMMAND_SETEXPOSURE;
869 if (new_params.exposure.gain >
870 new_params.exposure.gainMode-1)
871 retval = -EINVAL;
872 }
873 } else if (MATCH("fine_exp")) {
874 if (!retval)
875 val = VALUE/2;
876
877 if (!retval) {
878 if (val < 256) {
879 /* 1-02 firmware limits fineExp/2 to 127*/
880 if (FIRMWARE_VERSION(1,2) && val > 127)
881 val = 127;
882 new_params.exposure.fineExp = val;
883 new_params.exposure.expMode = 1;
884 command_flags |= COMMAND_SETEXPOSURE;
885 if(new_params.flickerControl.flickerMode != 0)
886 command_flags |= COMMAND_SETFLICKERCTRL;
887 new_params.flickerControl.flickerMode = 0;
888 command_flags |= COMMAND_SETFLICKERCTRL;
889 } else
890 retval = -EINVAL;
891 }
892 } else if (MATCH("coarse_exp")) {
893 if (!retval)
894 val = VALUE;
895
896 if (!retval) {
897 if (val <= MAX_EXP) {
898 if (FIRMWARE_VERSION(1,2) &&
899 val > MAX_EXP_102)
900 val = MAX_EXP_102;
901 new_params.exposure.coarseExpLo =
902 val & 0xff;
903 new_params.exposure.coarseExpHi =
904 val >> 8;
905 new_params.exposure.expMode = 1;
906 command_flags |= COMMAND_SETEXPOSURE;
907 if(new_params.flickerControl.flickerMode != 0)
908 command_flags |= COMMAND_SETFLICKERCTRL;
909 new_params.flickerControl.flickerMode = 0;
910 command_flags |= COMMAND_SETFLICKERCTRL;
911 } else
912 retval = -EINVAL;
913 }
914 } else if (MATCH("red_comp")) {
915 if (!retval)
916 val = VALUE;
917
918 if (!retval) {
919 if (val >= COMP_RED && val <= 255) {
920 new_params.exposure.redComp = val;
921 new_params.exposure.compMode = 1;
922 command_flags |= COMMAND_SETEXPOSURE;
923 } else
924 retval = -EINVAL;
925 }
926 } else if (MATCH("green1_comp")) {
927 if (!retval)
928 val = VALUE;
929
930 if (!retval) {
931 if (val >= COMP_GREEN1 && val <= 255) {
932 new_params.exposure.green1Comp = val;
933 new_params.exposure.compMode = 1;
934 command_flags |= COMMAND_SETEXPOSURE;
935 } else
936 retval = -EINVAL;
937 }
938 } else if (MATCH("green2_comp")) {
939 if (!retval)
940 val = VALUE;
941
942 if (!retval) {
943 if (val >= COMP_GREEN2 && val <= 255) {
944 new_params.exposure.green2Comp = val;
945 new_params.exposure.compMode = 1;
946 command_flags |= COMMAND_SETEXPOSURE;
947 } else
948 retval = -EINVAL;
949 }
950 } else if (MATCH("blue_comp")) {
951 if (!retval)
952 val = VALUE;
953
954 if (!retval) {
955 if (val >= COMP_BLUE && val <= 255) {
956 new_params.exposure.blueComp = val;
957 new_params.exposure.compMode = 1;
958 command_flags |= COMMAND_SETEXPOSURE;
959 } else
960 retval = -EINVAL;
961 }
962 } else if (MATCH("apcor_gain1")) {
963 if (!retval)
964 val = VALUE;
965
966 if (!retval) {
967 command_flags |= COMMAND_SETAPCOR;
968 if (val <= 0xff)
969 new_params.apcor.gain1 = val;
970 else
971 retval = -EINVAL;
972 }
973 } else if (MATCH("apcor_gain2")) {
974 if (!retval)
975 val = VALUE;
976
977 if (!retval) {
978 command_flags |= COMMAND_SETAPCOR;
979 if (val <= 0xff)
980 new_params.apcor.gain2 = val;
981 else
982 retval = -EINVAL;
983 }
984 } else if (MATCH("apcor_gain4")) {
985 if (!retval)
986 val = VALUE;
987
988 if (!retval) {
989 command_flags |= COMMAND_SETAPCOR;
990 if (val <= 0xff)
991 new_params.apcor.gain4 = val;
992 else
993 retval = -EINVAL;
994 }
995 } else if (MATCH("apcor_gain8")) {
996 if (!retval)
997 val = VALUE;
998
999 if (!retval) {
1000 command_flags |= COMMAND_SETAPCOR;
1001 if (val <= 0xff)
1002 new_params.apcor.gain8 = val;
1003 else
1004 retval = -EINVAL;
1005 }
1006 } else if (MATCH("vl_offset_gain1")) {
1007 if (!retval)
1008 val = VALUE;
1009
1010 if (!retval) {
1011 if (val <= 0xff)
1012 new_params.vlOffset.gain1 = val;
1013 else
1014 retval = -EINVAL;
1015 }
1016 command_flags |= COMMAND_SETVLOFFSET;
1017 } else if (MATCH("vl_offset_gain2")) {
1018 if (!retval)
1019 val = VALUE;
1020
1021 if (!retval) {
1022 if (val <= 0xff)
1023 new_params.vlOffset.gain2 = val;
1024 else
1025 retval = -EINVAL;
1026 }
1027 command_flags |= COMMAND_SETVLOFFSET;
1028 } else if (MATCH("vl_offset_gain4")) {
1029 if (!retval)
1030 val = VALUE;
1031
1032 if (!retval) {
1033 if (val <= 0xff)
1034 new_params.vlOffset.gain4 = val;
1035 else
1036 retval = -EINVAL;
1037 }
1038 command_flags |= COMMAND_SETVLOFFSET;
1039 } else if (MATCH("vl_offset_gain8")) {
1040 if (!retval)
1041 val = VALUE;
1042
1043 if (!retval) {
1044 if (val <= 0xff)
1045 new_params.vlOffset.gain8 = val;
1046 else
1047 retval = -EINVAL;
1048 }
1049 command_flags |= COMMAND_SETVLOFFSET;
1050 } else if (MATCH("flicker_control")) {
1051 if (!retval && MATCH("on")) {
1052 set_flicker(&new_params, &command_flags, 1);
1053 } else if (!retval && MATCH("off")) {
1054 set_flicker(&new_params, &command_flags, 0);
1055 } else
1056 retval = -EINVAL;
1057
1058 command_flags |= COMMAND_SETFLICKERCTRL;
1059 } else if (MATCH("mains_frequency")) {
1060 if (!retval && MATCH("50")) {
1061 new_mains = 0;
1062 new_params.flickerControl.coarseJump =
1063 flicker_jumps[new_mains]
1064 [new_params.sensorFps.baserate]
1065 [new_params.sensorFps.divisor];
1066 if (new_params.flickerControl.flickerMode)
1067 command_flags |= COMMAND_SETFLICKERCTRL;
1068 } else if (!retval && MATCH("60")) {
1069 new_mains = 1;
1070 new_params.flickerControl.coarseJump =
1071 flicker_jumps[new_mains]
1072 [new_params.sensorFps.baserate]
1073 [new_params.sensorFps.divisor];
1074 if (new_params.flickerControl.flickerMode)
1075 command_flags |= COMMAND_SETFLICKERCTRL;
1076 } else
1077 retval = -EINVAL;
1078 } else if (MATCH("allowable_overexposure")) {
1079 if (!retval && MATCH("auto")) {
1080 new_params.flickerControl.allowableOverExposure =
1081 -find_over_exposure(new_params.colourParams.brightness);
1082 if(new_params.flickerControl.flickerMode != 0)
1083 command_flags |= COMMAND_SETFLICKERCTRL;
1084 } else {
1085 if (!retval)
1086 val = VALUE;
1087
1088 if (!retval) {
1089 if (val <= 0xff) {
1090 new_params.flickerControl.
1091 allowableOverExposure = val;
1092 if(new_params.flickerControl.flickerMode != 0)
1093 command_flags |= COMMAND_SETFLICKERCTRL;
1094 } else
1095 retval = -EINVAL;
1096 }
1097 }
1098 } else if (MATCH("compression_mode")) {
1099 if (!retval && MATCH("none"))
1100 new_params.compression.mode =
1101 CPIA_COMPRESSION_NONE;
1102 else if (!retval && MATCH("auto"))
1103 new_params.compression.mode =
1104 CPIA_COMPRESSION_AUTO;
1105 else if (!retval && MATCH("manual"))
1106 new_params.compression.mode =
1107 CPIA_COMPRESSION_MANUAL;
1108 else
1109 retval = -EINVAL;
1110
1111 command_flags |= COMMAND_SETCOMPRESSION;
1112 } else if (MATCH("decimation_enable")) {
1113 if (!retval && MATCH("off"))
1114 new_params.compression.decimation = 0;
1115 else if (!retval && MATCH("on"))
1116 new_params.compression.decimation = 1;
1117 else
1118 retval = -EINVAL;
1119
1120 command_flags |= COMMAND_SETCOMPRESSION;
1121 } else if (MATCH("compression_target")) {
1122 if (!retval && MATCH("quality"))
1123 new_params.compressionTarget.frTargeting =
1124 CPIA_COMPRESSION_TARGET_QUALITY;
1125 else if (!retval && MATCH("framerate"))
1126 new_params.compressionTarget.frTargeting =
1127 CPIA_COMPRESSION_TARGET_FRAMERATE;
1128 else
1129 retval = -EINVAL;
1130
1131 command_flags |= COMMAND_SETCOMPRESSIONTARGET;
1132 } else if (MATCH("target_framerate")) {
1133 if (!retval)
1134 val = VALUE;
1135
1136 if (!retval) {
1137 if(val > 0 && val <= 30)
1138 new_params.compressionTarget.targetFR = val;
1139 else
1140 retval = -EINVAL;
1141 }
1142 command_flags |= COMMAND_SETCOMPRESSIONTARGET;
1143 } else if (MATCH("target_quality")) {
1144 if (!retval)
1145 val = VALUE;
1146
1147 if (!retval) {
1148 if(val > 0 && val <= 64)
1149 new_params.compressionTarget.targetQ = val;
1150 else
1151 retval = -EINVAL;
1152 }
1153 command_flags |= COMMAND_SETCOMPRESSIONTARGET;
1154 } else if (MATCH("y_threshold")) {
1155 if (!retval)
1156 val = VALUE;
1157
1158 if (!retval) {
1159 if (val < 32)
1160 new_params.yuvThreshold.yThreshold = val;
1161 else
1162 retval = -EINVAL;
1163 }
1164 command_flags |= COMMAND_SETYUVTHRESH;
1165 } else if (MATCH("uv_threshold")) {
1166 if (!retval)
1167 val = VALUE;
1168
1169 if (!retval) {
1170 if (val < 32)
1171 new_params.yuvThreshold.uvThreshold = val;
1172 else
1173 retval = -EINVAL;
1174 }
1175 command_flags |= COMMAND_SETYUVTHRESH;
1176 } else if (MATCH("hysteresis")) {
1177 if (!retval)
1178 val = VALUE;
1179
1180 if (!retval) {
1181 if (val <= 0xff)
1182 new_params.compressionParams.hysteresis = val;
1183 else
1184 retval = -EINVAL;
1185 }
1186 command_flags |= COMMAND_SETCOMPRESSIONPARAMS;
1187 } else if (MATCH("threshold_max")) {
1188 if (!retval)
1189 val = VALUE;
1190
1191 if (!retval) {
1192 if (val <= 0xff)
1193 new_params.compressionParams.threshMax = val;
1194 else
1195 retval = -EINVAL;
1196 }
1197 command_flags |= COMMAND_SETCOMPRESSIONPARAMS;
1198 } else if (MATCH("small_step")) {
1199 if (!retval)
1200 val = VALUE;
1201
1202 if (!retval) {
1203 if (val <= 0xff)
1204 new_params.compressionParams.smallStep = val;
1205 else
1206 retval = -EINVAL;
1207 }
1208 command_flags |= COMMAND_SETCOMPRESSIONPARAMS;
1209 } else if (MATCH("large_step")) {
1210 if (!retval)
1211 val = VALUE;
1212
1213 if (!retval) {
1214 if (val <= 0xff)
1215 new_params.compressionParams.largeStep = val;
1216 else
1217 retval = -EINVAL;
1218 }
1219 command_flags |= COMMAND_SETCOMPRESSIONPARAMS;
1220 } else if (MATCH("decimation_hysteresis")) {
1221 if (!retval)
1222 val = VALUE;
1223
1224 if (!retval) {
1225 if (val <= 0xff)
1226 new_params.compressionParams.decimationHysteresis = val;
1227 else
1228 retval = -EINVAL;
1229 }
1230 command_flags |= COMMAND_SETCOMPRESSIONPARAMS;
1231 } else if (MATCH("fr_diff_step_thresh")) {
1232 if (!retval)
1233 val = VALUE;
1234
1235 if (!retval) {
1236 if (val <= 0xff)
1237 new_params.compressionParams.frDiffStepThresh = val;
1238 else
1239 retval = -EINVAL;
1240 }
1241 command_flags |= COMMAND_SETCOMPRESSIONPARAMS;
1242 } else if (MATCH("q_diff_step_thresh")) {
1243 if (!retval)
1244 val = VALUE;
1245
1246 if (!retval) {
1247 if (val <= 0xff)
1248 new_params.compressionParams.qDiffStepThresh = val;
1249 else
1250 retval = -EINVAL;
1251 }
1252 command_flags |= COMMAND_SETCOMPRESSIONPARAMS;
1253 } else if (MATCH("decimation_thresh_mod")) {
1254 if (!retval)
1255 val = VALUE;
1256
1257 if (!retval) {
1258 if (val <= 0xff)
1259 new_params.compressionParams.decimationThreshMod = val;
1260 else
1261 retval = -EINVAL;
1262 }
1263 command_flags |= COMMAND_SETCOMPRESSIONPARAMS;
1264 } else if (MATCH("toplight")) {
1265 if (!retval && MATCH("on"))
1266 new_params.qx3.toplight = 1;
1267 else if (!retval && MATCH("off"))
1268 new_params.qx3.toplight = 0;
1269 else
1270 retval = -EINVAL;
1271 command_flags |= COMMAND_SETLIGHTS;
1272 } else if (MATCH("bottomlight")) {
1273 if (!retval && MATCH("on"))
1274 new_params.qx3.bottomlight = 1;
1275 else if (!retval && MATCH("off"))
1276 new_params.qx3.bottomlight = 0;
1277 else
1278 retval = -EINVAL;
1279 command_flags |= COMMAND_SETLIGHTS;
1280 } else {
1281 DBG("No match found\n");
1282 retval = -EINVAL;
1283 }
1284
1285 if (!retval) {
1286 while (count && isspace(*buffer) && *buffer != '\n') {
1287 --count;
1288 ++buffer;
1289 }
1290 if (count) {
1291 if (*buffer == '\0' && count != 1)
1292 retval = -EINVAL;
1293 else if (*buffer != '\n' && *buffer != ';' &&
1294 *buffer != '\0')
1295 retval = -EINVAL;
1296 else {
1297 --count;
1298 ++buffer;
1299 }
1300 }
1301 }
1302 }
1303#undef MATCH
1304#undef VALUE
1305#undef FIRMWARE_VERSION
1306 if (!retval) {
1307 if (command_flags & COMMAND_SETCOLOURPARAMS) {
1308 /* Adjust cam->vp to reflect these changes */
1309 cam->vp.brightness =
1310 new_params.colourParams.brightness*65535/100;
1311 cam->vp.contrast =
1312 new_params.colourParams.contrast*65535/100;
1313 cam->vp.colour =
1314 new_params.colourParams.saturation*65535/100;
1315 }
1316 if((command_flags & COMMAND_SETEXPOSURE) &&
1317 new_params.exposure.expMode == 2)
1318 cam->exposure_status = EXPOSURE_NORMAL;
1319
1320 memcpy(&cam->params, &new_params, sizeof(struct cam_params));
1321 cam->mainsFreq = new_mains;
1322 cam->cmd_queue |= command_flags;
1323 retval = size;
1324 } else
1325 DBG("error: %d\n", retval);
1326
1327 mutex_unlock(&cam->param_lock);
1328
1329out:
1330 free_page((unsigned long)page);
1331 return retval;
1332}
1333
1334static const struct file_operations cpia_proc_fops = {
1335 .owner = THIS_MODULE,
1336 .open = cpia_proc_open,
1337 .read = seq_read,
1338 .llseek = seq_lseek,
1339 .release = single_release,
1340 .write = cpia_proc_write,
1341};
1342
1343static void create_proc_cpia_cam(struct cam_data *cam)
1344{
1345 struct proc_dir_entry *ent;
1346
1347 if (!cpia_proc_root || !cam)
1348 return;
1349
1350 ent = proc_create_data(video_device_node_name(&cam->vdev),
1351 S_IRUGO|S_IWUSR, cpia_proc_root,
1352 &cpia_proc_fops, cam);
1353 if (!ent)
1354 return;
1355
1356 /*
1357 size of the proc entry is 3736 bytes for the standard webcam;
1358 the extra features of the QX3 microscope add 189 bytes.
1359 (we have not yet probed the camera to see which type it is).
1360 */
1361 ent->size = 3736 + 189;
1362 cam->proc_entry = ent;
1363}
1364
1365static void destroy_proc_cpia_cam(struct cam_data *cam)
1366{
1367 if (!cam || !cam->proc_entry)
1368 return;
1369
1370 remove_proc_entry(video_device_node_name(&cam->vdev), cpia_proc_root);
1371 cam->proc_entry = NULL;
1372}
1373
1374static void proc_cpia_create(void)
1375{
1376 cpia_proc_root = proc_mkdir("cpia", NULL);
1377
1378 if (!cpia_proc_root)
1379 LOG("Unable to initialise /proc/cpia\n");
1380}
1381
1382static void __exit proc_cpia_destroy(void)
1383{
1384 remove_proc_entry("cpia", NULL);
1385}
1386#endif /* CONFIG_PROC_FS */
1387
1388/* ----------------------- debug functions ---------------------- */
1389
1390#define printstatus(cam) \
1391 DBG("%02x %02x %02x %02x %02x %02x %02x %02x\n",\
1392 cam->params.status.systemState, cam->params.status.grabState, \
1393 cam->params.status.streamState, cam->params.status.fatalError, \
1394 cam->params.status.cmdError, cam->params.status.debugFlags, \
1395 cam->params.status.vpStatus, cam->params.status.errorCode);
1396
1397/* ----------------------- v4l helpers -------------------------- */
1398
1399/* supported frame palettes and depths */
1400static inline int valid_mode(u16 palette, u16 depth)
1401{
1402 if ((palette == VIDEO_PALETTE_YUV422 && depth == 16) ||
1403 (palette == VIDEO_PALETTE_YUYV && depth == 16))
1404 return 1;
1405
1406 if (colorspace_conv)
1407 return (palette == VIDEO_PALETTE_GREY && depth == 8) ||
1408 (palette == VIDEO_PALETTE_RGB555 && depth == 16) ||
1409 (palette == VIDEO_PALETTE_RGB565 && depth == 16) ||
1410 (palette == VIDEO_PALETTE_RGB24 && depth == 24) ||
1411 (palette == VIDEO_PALETTE_RGB32 && depth == 32) ||
1412 (palette == VIDEO_PALETTE_UYVY && depth == 16);
1413
1414 return 0;
1415}
1416
1417static int match_videosize( int width, int height )
1418{
1419 /* return the best match, where 'best' is as always
1420 * the largest that is not bigger than what is requested. */
1421 if (width>=352 && height>=288)
1422 return VIDEOSIZE_352_288; /* CIF */
1423
1424 if (width>=320 && height>=240)
1425 return VIDEOSIZE_320_240; /* SIF */
1426
1427 if (width>=288 && height>=216)
1428 return VIDEOSIZE_288_216;
1429
1430 if (width>=256 && height>=192)
1431 return VIDEOSIZE_256_192;
1432
1433 if (width>=224 && height>=168)
1434 return VIDEOSIZE_224_168;
1435
1436 if (width>=192 && height>=144)
1437 return VIDEOSIZE_192_144;
1438
1439 if (width>=176 && height>=144)
1440 return VIDEOSIZE_176_144; /* QCIF */
1441
1442 if (width>=160 && height>=120)
1443 return VIDEOSIZE_160_120; /* QSIF */
1444
1445 if (width>=128 && height>=96)
1446 return VIDEOSIZE_128_96;
1447
1448 if (width>=88 && height>=72)
1449 return VIDEOSIZE_88_72;
1450
1451 if (width>=64 && height>=48)
1452 return VIDEOSIZE_64_48;
1453
1454 if (width>=48 && height>=48)
1455 return VIDEOSIZE_48_48;
1456
1457 return -1;
1458}
1459
1460/* these are the capture sizes we support */
1461static void set_vw_size(struct cam_data *cam)
1462{
1463 /* the col/row/start/end values are the result of simple math */
1464 /* study the SetROI-command in cpia developers guide p 2-22 */
1465 /* streamStartLine is set to the recommended value in the cpia */
1466 /* developers guide p 3-37 */
1467 switch(cam->video_size) {
1468 case VIDEOSIZE_CIF:
1469 cam->vw.width = 352;
1470 cam->vw.height = 288;
1471 cam->params.format.videoSize=VIDEOSIZE_CIF;
1472 cam->params.roi.colStart=0;
1473 cam->params.roi.rowStart=0;
1474 cam->params.streamStartLine = 120;
1475 break;
1476 case VIDEOSIZE_SIF:
1477 cam->vw.width = 320;
1478 cam->vw.height = 240;
1479 cam->params.format.videoSize=VIDEOSIZE_CIF;
1480 cam->params.roi.colStart=2;
1481 cam->params.roi.rowStart=6;
1482 cam->params.streamStartLine = 120;
1483 break;
1484 case VIDEOSIZE_288_216:
1485 cam->vw.width = 288;
1486 cam->vw.height = 216;
1487 cam->params.format.videoSize=VIDEOSIZE_CIF;
1488 cam->params.roi.colStart=4;
1489 cam->params.roi.rowStart=9;
1490 cam->params.streamStartLine = 120;
1491 break;
1492 case VIDEOSIZE_256_192:
1493 cam->vw.width = 256;
1494 cam->vw.height = 192;
1495 cam->params.format.videoSize=VIDEOSIZE_CIF;
1496 cam->params.roi.colStart=6;
1497 cam->params.roi.rowStart=12;
1498 cam->params.streamStartLine = 120;
1499 break;
1500 case VIDEOSIZE_224_168:
1501 cam->vw.width = 224;
1502 cam->vw.height = 168;
1503 cam->params.format.videoSize=VIDEOSIZE_CIF;
1504 cam->params.roi.colStart=8;
1505 cam->params.roi.rowStart=15;
1506 cam->params.streamStartLine = 120;
1507 break;
1508 case VIDEOSIZE_192_144:
1509 cam->vw.width = 192;
1510 cam->vw.height = 144;
1511 cam->params.format.videoSize=VIDEOSIZE_CIF;
1512 cam->params.roi.colStart=10;
1513 cam->params.roi.rowStart=18;
1514 cam->params.streamStartLine = 120;
1515 break;
1516 case VIDEOSIZE_QCIF:
1517 cam->vw.width = 176;
1518 cam->vw.height = 144;
1519 cam->params.format.videoSize=VIDEOSIZE_QCIF;
1520 cam->params.roi.colStart=0;
1521 cam->params.roi.rowStart=0;
1522 cam->params.streamStartLine = 60;
1523 break;
1524 case VIDEOSIZE_QSIF:
1525 cam->vw.width = 160;
1526 cam->vw.height = 120;
1527 cam->params.format.videoSize=VIDEOSIZE_QCIF;
1528 cam->params.roi.colStart=1;
1529 cam->params.roi.rowStart=3;
1530 cam->params.streamStartLine = 60;
1531 break;
1532 case VIDEOSIZE_128_96:
1533 cam->vw.width = 128;
1534 cam->vw.height = 96;
1535 cam->params.format.videoSize=VIDEOSIZE_QCIF;
1536 cam->params.roi.colStart=3;
1537 cam->params.roi.rowStart=6;
1538 cam->params.streamStartLine = 60;
1539 break;
1540 case VIDEOSIZE_88_72:
1541 cam->vw.width = 88;
1542 cam->vw.height = 72;
1543 cam->params.format.videoSize=VIDEOSIZE_QCIF;
1544 cam->params.roi.colStart=5;
1545 cam->params.roi.rowStart=9;
1546 cam->params.streamStartLine = 60;
1547 break;
1548 case VIDEOSIZE_64_48:
1549 cam->vw.width = 64;
1550 cam->vw.height = 48;
1551 cam->params.format.videoSize=VIDEOSIZE_QCIF;
1552 cam->params.roi.colStart=7;
1553 cam->params.roi.rowStart=12;
1554 cam->params.streamStartLine = 60;
1555 break;
1556 case VIDEOSIZE_48_48:
1557 cam->vw.width = 48;
1558 cam->vw.height = 48;
1559 cam->params.format.videoSize=VIDEOSIZE_QCIF;
1560 cam->params.roi.colStart=8;
1561 cam->params.roi.rowStart=6;
1562 cam->params.streamStartLine = 60;
1563 break;
1564 default:
1565 LOG("bad videosize value: %d\n", cam->video_size);
1566 return;
1567 }
1568
1569 if(cam->vc.width == 0)
1570 cam->vc.width = cam->vw.width;
1571 if(cam->vc.height == 0)
1572 cam->vc.height = cam->vw.height;
1573
1574 cam->params.roi.colStart += cam->vc.x >> 3;
1575 cam->params.roi.colEnd = cam->params.roi.colStart +
1576 (cam->vc.width >> 3);
1577 cam->params.roi.rowStart += cam->vc.y >> 2;
1578 cam->params.roi.rowEnd = cam->params.roi.rowStart +
1579 (cam->vc.height >> 2);
1580
1581 return;
1582}
1583
1584static int allocate_frame_buf(struct cam_data *cam)
1585{
1586 int i;
1587
1588 cam->frame_buf = rvmalloc(FRAME_NUM * CPIA_MAX_FRAME_SIZE);
1589 if (!cam->frame_buf)
1590 return -ENOBUFS;
1591
1592 for (i = 0; i < FRAME_NUM; i++)
1593 cam->frame[i].data = cam->frame_buf + i * CPIA_MAX_FRAME_SIZE;
1594
1595 return 0;
1596}
1597
1598static int free_frame_buf(struct cam_data *cam)
1599{
1600 int i;
1601
1602 rvfree(cam->frame_buf, FRAME_NUM*CPIA_MAX_FRAME_SIZE);
1603 cam->frame_buf = NULL;
1604 for (i=0; i < FRAME_NUM; i++)
1605 cam->frame[i].data = NULL;
1606
1607 return 0;
1608}
1609
1610
1611static inline void free_frames(struct cpia_frame frame[FRAME_NUM])
1612{
1613 int i;
1614
1615 for (i=0; i < FRAME_NUM; i++)
1616 frame[i].state = FRAME_UNUSED;
1617 return;
1618}
1619
1620/**********************************************************************
1621 *
1622 * General functions
1623 *
1624 **********************************************************************/
1625/* send an arbitrary command to the camera */
1626static int do_command(struct cam_data *cam, u16 command, u8 a, u8 b, u8 c, u8 d)
1627{
1628 int retval, datasize;
1629 u8 cmd[8], data[8];
1630
1631 switch(command) {
1632 case CPIA_COMMAND_GetCPIAVersion:
1633 case CPIA_COMMAND_GetPnPID:
1634 case CPIA_COMMAND_GetCameraStatus:
1635 case CPIA_COMMAND_GetVPVersion:
1636 datasize=8;
1637 break;
1638 case CPIA_COMMAND_GetColourParams:
1639 case CPIA_COMMAND_GetColourBalance:
1640 case CPIA_COMMAND_GetExposure:
1641 mutex_lock(&cam->param_lock);
1642 datasize=8;
1643 break;
1644 case CPIA_COMMAND_ReadMCPorts:
1645 case CPIA_COMMAND_ReadVCRegs:
1646 datasize = 4;
1647 break;
1648 default:
1649 datasize=0;
1650 break;
1651 }
1652
1653 cmd[0] = command>>8;
1654 cmd[1] = command&0xff;
1655 cmd[2] = a;
1656 cmd[3] = b;
1657 cmd[4] = c;
1658 cmd[5] = d;
1659 cmd[6] = datasize;
1660 cmd[7] = 0;
1661
1662 retval = cam->ops->transferCmd(cam->lowlevel_data, cmd, data);
1663 if (retval) {
1664 DBG("%x - failed, retval=%d\n", command, retval);
1665 if (command == CPIA_COMMAND_GetColourParams ||
1666 command == CPIA_COMMAND_GetColourBalance ||
1667 command == CPIA_COMMAND_GetExposure)
1668 mutex_unlock(&cam->param_lock);
1669 } else {
1670 switch(command) {
1671 case CPIA_COMMAND_GetCPIAVersion:
1672 cam->params.version.firmwareVersion = data[0];
1673 cam->params.version.firmwareRevision = data[1];
1674 cam->params.version.vcVersion = data[2];
1675 cam->params.version.vcRevision = data[3];
1676 break;
1677 case CPIA_COMMAND_GetPnPID:
1678 cam->params.pnpID.vendor = data[0]+(((u16)data[1])<<8);
1679 cam->params.pnpID.product = data[2]+(((u16)data[3])<<8);
1680 cam->params.pnpID.deviceRevision =
1681 data[4]+(((u16)data[5])<<8);
1682 break;
1683 case CPIA_COMMAND_GetCameraStatus:
1684 cam->params.status.systemState = data[0];
1685 cam->params.status.grabState = data[1];
1686 cam->params.status.streamState = data[2];
1687 cam->params.status.fatalError = data[3];
1688 cam->params.status.cmdError = data[4];
1689 cam->params.status.debugFlags = data[5];
1690 cam->params.status.vpStatus = data[6];
1691 cam->params.status.errorCode = data[7];
1692 break;
1693 case CPIA_COMMAND_GetVPVersion:
1694 cam->params.vpVersion.vpVersion = data[0];
1695 cam->params.vpVersion.vpRevision = data[1];
1696 cam->params.vpVersion.cameraHeadID =
1697 data[2]+(((u16)data[3])<<8);
1698 break;
1699 case CPIA_COMMAND_GetColourParams:
1700 cam->params.colourParams.brightness = data[0];
1701 cam->params.colourParams.contrast = data[1];
1702 cam->params.colourParams.saturation = data[2];
1703 mutex_unlock(&cam->param_lock);
1704 break;
1705 case CPIA_COMMAND_GetColourBalance:
1706 cam->params.colourBalance.redGain = data[0];
1707 cam->params.colourBalance.greenGain = data[1];
1708 cam->params.colourBalance.blueGain = data[2];
1709 mutex_unlock(&cam->param_lock);
1710 break;
1711 case CPIA_COMMAND_GetExposure:
1712 cam->params.exposure.gain = data[0];
1713 cam->params.exposure.fineExp = data[1];
1714 cam->params.exposure.coarseExpLo = data[2];
1715 cam->params.exposure.coarseExpHi = data[3];
1716 cam->params.exposure.redComp = data[4];
1717 cam->params.exposure.green1Comp = data[5];
1718 cam->params.exposure.green2Comp = data[6];
1719 cam->params.exposure.blueComp = data[7];
1720 mutex_unlock(&cam->param_lock);
1721 break;
1722
1723 case CPIA_COMMAND_ReadMCPorts:
1724 if (!cam->params.qx3.qx3_detected)
1725 break;
1726 /* test button press */
1727 cam->params.qx3.button = ((data[1] & 0x02) == 0);
1728 if (cam->params.qx3.button) {
1729 /* button pressed - unlock the latch */
1730 do_command(cam,CPIA_COMMAND_WriteMCPort,3,0xDF,0xDF,0);
1731 do_command(cam,CPIA_COMMAND_WriteMCPort,3,0xFF,0xFF,0);
1732 }
1733
1734 /* test whether microscope is cradled */
1735 cam->params.qx3.cradled = ((data[2] & 0x40) == 0);
1736 break;
1737
1738 default:
1739 break;
1740 }
1741 }
1742 return retval;
1743}
1744
1745/* send a command to the camera with an additional data transaction */
1746static int do_command_extended(struct cam_data *cam, u16 command,
1747 u8 a, u8 b, u8 c, u8 d,
1748 u8 e, u8 f, u8 g, u8 h,
1749 u8 i, u8 j, u8 k, u8 l)
1750{
1751 int retval;
1752 u8 cmd[8], data[8];
1753
1754 cmd[0] = command>>8;
1755 cmd[1] = command&0xff;
1756 cmd[2] = a;
1757 cmd[3] = b;
1758 cmd[4] = c;
1759 cmd[5] = d;
1760 cmd[6] = 8;
1761 cmd[7] = 0;
1762 data[0] = e;
1763 data[1] = f;
1764 data[2] = g;
1765 data[3] = h;
1766 data[4] = i;
1767 data[5] = j;
1768 data[6] = k;
1769 data[7] = l;
1770
1771 retval = cam->ops->transferCmd(cam->lowlevel_data, cmd, data);
1772 if (retval)
1773 DBG("%x - failed\n", command);
1774
1775 return retval;
1776}
1777
1778/**********************************************************************
1779 *
1780 * Colorspace conversion
1781 *
1782 **********************************************************************/
1783#define LIMIT(x) ((((x)>0xffffff)?0xff0000:(((x)<=0xffff)?0:(x)&0xff0000))>>16)
1784
1785static int convert420(unsigned char *yuv, unsigned char *rgb, int out_fmt,
1786 int linesize, int mmap_kludge)
1787{
1788 int y, u, v, r, g, b, y1;
1789
1790 /* Odd lines use the same u and v as the previous line.
1791 * Because of compression, it is necessary to get this
1792 * information from the decoded image. */
1793 switch(out_fmt) {
1794 case VIDEO_PALETTE_RGB555:
1795 y = (*yuv++ - 16) * 76310;
1796 y1 = (*yuv - 16) * 76310;
1797 r = ((*(rgb+1-linesize)) & 0x7c) << 1;
1798 g = ((*(rgb-linesize)) & 0xe0) >> 4 |
1799 ((*(rgb+1-linesize)) & 0x03) << 6;
1800 b = ((*(rgb-linesize)) & 0x1f) << 3;
1801 u = (-53294 * r - 104635 * g + 157929 * b) / 5756495;
1802 v = (157968 * r - 132278 * g - 25690 * b) / 5366159;
1803 r = 104635 * v;
1804 g = -25690 * u - 53294 * v;
1805 b = 132278 * u;
1806 *rgb++ = ((LIMIT(g+y) & 0xf8) << 2) | (LIMIT(b+y) >> 3);
1807 *rgb++ = ((LIMIT(r+y) & 0xf8) >> 1) | (LIMIT(g+y) >> 6);
1808 *rgb++ = ((LIMIT(g+y1) & 0xf8) << 2) | (LIMIT(b+y1) >> 3);
1809 *rgb = ((LIMIT(r+y1) & 0xf8) >> 1) | (LIMIT(g+y1) >> 6);
1810 return 4;
1811 case VIDEO_PALETTE_RGB565:
1812 y = (*yuv++ - 16) * 76310;
1813 y1 = (*yuv - 16) * 76310;
1814 r = (*(rgb+1-linesize)) & 0xf8;
1815 g = ((*(rgb-linesize)) & 0xe0) >> 3 |
1816 ((*(rgb+1-linesize)) & 0x07) << 5;
1817 b = ((*(rgb-linesize)) & 0x1f) << 3;
1818 u = (-53294 * r - 104635 * g + 157929 * b) / 5756495;
1819 v = (157968 * r - 132278 * g - 25690 * b) / 5366159;
1820 r = 104635 * v;
1821 g = -25690 * u - 53294 * v;
1822 b = 132278 * u;
1823 *rgb++ = ((LIMIT(g+y) & 0xfc) << 3) | (LIMIT(b+y) >> 3);
1824 *rgb++ = (LIMIT(r+y) & 0xf8) | (LIMIT(g+y) >> 5);
1825 *rgb++ = ((LIMIT(g+y1) & 0xfc) << 3) | (LIMIT(b+y1) >> 3);
1826 *rgb = (LIMIT(r+y1) & 0xf8) | (LIMIT(g+y1) >> 5);
1827 return 4;
1828 break;
1829 case VIDEO_PALETTE_RGB24:
1830 case VIDEO_PALETTE_RGB32:
1831 y = (*yuv++ - 16) * 76310;
1832 y1 = (*yuv - 16) * 76310;
1833 if (mmap_kludge) {
1834 r = *(rgb+2-linesize);
1835 g = *(rgb+1-linesize);
1836 b = *(rgb-linesize);
1837 } else {
1838 r = *(rgb-linesize);
1839 g = *(rgb+1-linesize);
1840 b = *(rgb+2-linesize);
1841 }
1842 u = (-53294 * r - 104635 * g + 157929 * b) / 5756495;
1843 v = (157968 * r - 132278 * g - 25690 * b) / 5366159;
1844 r = 104635 * v;
1845 g = -25690 * u + -53294 * v;
1846 b = 132278 * u;
1847 if (mmap_kludge) {
1848 *rgb++ = LIMIT(b+y);
1849 *rgb++ = LIMIT(g+y);
1850 *rgb++ = LIMIT(r+y);
1851 if(out_fmt == VIDEO_PALETTE_RGB32)
1852 rgb++;
1853 *rgb++ = LIMIT(b+y1);
1854 *rgb++ = LIMIT(g+y1);
1855 *rgb = LIMIT(r+y1);
1856 } else {
1857 *rgb++ = LIMIT(r+y);
1858 *rgb++ = LIMIT(g+y);
1859 *rgb++ = LIMIT(b+y);
1860 if(out_fmt == VIDEO_PALETTE_RGB32)
1861 rgb++;
1862 *rgb++ = LIMIT(r+y1);
1863 *rgb++ = LIMIT(g+y1);
1864 *rgb = LIMIT(b+y1);
1865 }
1866 if(out_fmt == VIDEO_PALETTE_RGB32)
1867 return 8;
1868 return 6;
1869 case VIDEO_PALETTE_YUV422:
1870 case VIDEO_PALETTE_YUYV:
1871 y = *yuv++;
1872 u = *(rgb+1-linesize);
1873 y1 = *yuv;
1874 v = *(rgb+3-linesize);
1875 *rgb++ = y;
1876 *rgb++ = u;
1877 *rgb++ = y1;
1878 *rgb = v;
1879 return 4;
1880 case VIDEO_PALETTE_UYVY:
1881 u = *(rgb-linesize);
1882 y = *yuv++;
1883 v = *(rgb+2-linesize);
1884 y1 = *yuv;
1885 *rgb++ = u;
1886 *rgb++ = y;
1887 *rgb++ = v;
1888 *rgb = y1;
1889 return 4;
1890 case VIDEO_PALETTE_GREY:
1891 *rgb++ = *yuv++;
1892 *rgb = *yuv;
1893 return 2;
1894 default:
1895 DBG("Empty: %d\n", out_fmt);
1896 return 0;
1897 }
1898}
1899
1900
1901static int yuvconvert(unsigned char *yuv, unsigned char *rgb, int out_fmt,
1902 int in_uyvy, int mmap_kludge)
1903{
1904 int y, u, v, r, g, b, y1;
1905
1906 switch(out_fmt) {
1907 case VIDEO_PALETTE_RGB555:
1908 case VIDEO_PALETTE_RGB565:
1909 case VIDEO_PALETTE_RGB24:
1910 case VIDEO_PALETTE_RGB32:
1911 if (in_uyvy) {
1912 u = *yuv++ - 128;
1913 y = (*yuv++ - 16) * 76310;
1914 v = *yuv++ - 128;
1915 y1 = (*yuv - 16) * 76310;
1916 } else {
1917 y = (*yuv++ - 16) * 76310;
1918 u = *yuv++ - 128;
1919 y1 = (*yuv++ - 16) * 76310;
1920 v = *yuv - 128;
1921 }
1922 r = 104635 * v;
1923 g = -25690 * u + -53294 * v;
1924 b = 132278 * u;
1925 break;
1926 default:
1927 y = *yuv++;
1928 u = *yuv++;
1929 y1 = *yuv++;
1930 v = *yuv;
1931 /* Just to avoid compiler warnings */
1932 r = 0;
1933 g = 0;
1934 b = 0;
1935 break;
1936 }
1937 switch(out_fmt) {
1938 case VIDEO_PALETTE_RGB555:
1939 *rgb++ = ((LIMIT(g+y) & 0xf8) << 2) | (LIMIT(b+y) >> 3);
1940 *rgb++ = ((LIMIT(r+y) & 0xf8) >> 1) | (LIMIT(g+y) >> 6);
1941 *rgb++ = ((LIMIT(g+y1) & 0xf8) << 2) | (LIMIT(b+y1) >> 3);
1942 *rgb = ((LIMIT(r+y1) & 0xf8) >> 1) | (LIMIT(g+y1) >> 6);
1943 return 4;
1944 case VIDEO_PALETTE_RGB565:
1945 *rgb++ = ((LIMIT(g+y) & 0xfc) << 3) | (LIMIT(b+y) >> 3);
1946 *rgb++ = (LIMIT(r+y) & 0xf8) | (LIMIT(g+y) >> 5);
1947 *rgb++ = ((LIMIT(g+y1) & 0xfc) << 3) | (LIMIT(b+y1) >> 3);
1948 *rgb = (LIMIT(r+y1) & 0xf8) | (LIMIT(g+y1) >> 5);
1949 return 4;
1950 case VIDEO_PALETTE_RGB24:
1951 if (mmap_kludge) {
1952 *rgb++ = LIMIT(b+y);
1953 *rgb++ = LIMIT(g+y);
1954 *rgb++ = LIMIT(r+y);
1955 *rgb++ = LIMIT(b+y1);
1956 *rgb++ = LIMIT(g+y1);
1957 *rgb = LIMIT(r+y1);
1958 } else {
1959 *rgb++ = LIMIT(r+y);
1960 *rgb++ = LIMIT(g+y);
1961 *rgb++ = LIMIT(b+y);
1962 *rgb++ = LIMIT(r+y1);
1963 *rgb++ = LIMIT(g+y1);
1964 *rgb = LIMIT(b+y1);
1965 }
1966 return 6;
1967 case VIDEO_PALETTE_RGB32:
1968 if (mmap_kludge) {
1969 *rgb++ = LIMIT(b+y);
1970 *rgb++ = LIMIT(g+y);
1971 *rgb++ = LIMIT(r+y);
1972 rgb++;
1973 *rgb++ = LIMIT(b+y1);
1974 *rgb++ = LIMIT(g+y1);
1975 *rgb = LIMIT(r+y1);
1976 } else {
1977 *rgb++ = LIMIT(r+y);
1978 *rgb++ = LIMIT(g+y);
1979 *rgb++ = LIMIT(b+y);
1980 rgb++;
1981 *rgb++ = LIMIT(r+y1);
1982 *rgb++ = LIMIT(g+y1);
1983 *rgb = LIMIT(b+y1);
1984 }
1985 return 8;
1986 case VIDEO_PALETTE_GREY:
1987 *rgb++ = y;
1988 *rgb = y1;
1989 return 2;
1990 case VIDEO_PALETTE_YUV422:
1991 case VIDEO_PALETTE_YUYV:
1992 *rgb++ = y;
1993 *rgb++ = u;
1994 *rgb++ = y1;
1995 *rgb = v;
1996 return 4;
1997 case VIDEO_PALETTE_UYVY:
1998 *rgb++ = u;
1999 *rgb++ = y;
2000 *rgb++ = v;
2001 *rgb = y1;
2002 return 4;
2003 default:
2004 DBG("Empty: %d\n", out_fmt);
2005 return 0;
2006 }
2007}
2008
2009static int skipcount(int count, int fmt)
2010{
2011 switch(fmt) {
2012 case VIDEO_PALETTE_GREY:
2013 return count;
2014 case VIDEO_PALETTE_RGB555:
2015 case VIDEO_PALETTE_RGB565:
2016 case VIDEO_PALETTE_YUV422:
2017 case VIDEO_PALETTE_YUYV:
2018 case VIDEO_PALETTE_UYVY:
2019 return 2*count;
2020 case VIDEO_PALETTE_RGB24:
2021 return 3*count;
2022 case VIDEO_PALETTE_RGB32:
2023 return 4*count;
2024 default:
2025 return 0;
2026 }
2027}
2028
2029static int parse_picture(struct cam_data *cam, int size)
2030{
2031 u8 *obuf, *ibuf, *end_obuf;
2032 int ll, in_uyvy, compressed, decimation, even_line, origsize, out_fmt;
2033 int rows, cols, linesize, subsample_422;
2034
2035 /* make sure params don't change while we are decoding */
2036 mutex_lock(&cam->param_lock);
2037
2038 obuf = cam->decompressed_frame.data;
2039 end_obuf = obuf+CPIA_MAX_FRAME_SIZE;
2040 ibuf = cam->raw_image;
2041 origsize = size;
2042 out_fmt = cam->vp.palette;
2043
2044 if ((ibuf[0] != MAGIC_0) || (ibuf[1] != MAGIC_1)) {
2045 LOG("header not found\n");
2046 mutex_unlock(&cam->param_lock);
2047 return -1;
2048 }
2049
2050 if ((ibuf[16] != VIDEOSIZE_QCIF) && (ibuf[16] != VIDEOSIZE_CIF)) {
2051 LOG("wrong video size\n");
2052 mutex_unlock(&cam->param_lock);
2053 return -1;
2054 }
2055
2056 if (ibuf[17] != SUBSAMPLE_420 && ibuf[17] != SUBSAMPLE_422) {
2057 LOG("illegal subtype %d\n",ibuf[17]);
2058 mutex_unlock(&cam->param_lock);
2059 return -1;
2060 }
2061 subsample_422 = ibuf[17] == SUBSAMPLE_422;
2062
2063 if (ibuf[18] != YUVORDER_YUYV && ibuf[18] != YUVORDER_UYVY) {
2064 LOG("illegal yuvorder %d\n",ibuf[18]);
2065 mutex_unlock(&cam->param_lock);
2066 return -1;
2067 }
2068 in_uyvy = ibuf[18] == YUVORDER_UYVY;
2069
2070 if ((ibuf[24] != cam->params.roi.colStart) ||
2071 (ibuf[25] != cam->params.roi.colEnd) ||
2072 (ibuf[26] != cam->params.roi.rowStart) ||
2073 (ibuf[27] != cam->params.roi.rowEnd)) {
2074 LOG("ROI mismatch\n");
2075 mutex_unlock(&cam->param_lock);
2076 return -1;
2077 }
2078 cols = 8*(ibuf[25] - ibuf[24]);
2079 rows = 4*(ibuf[27] - ibuf[26]);
2080
2081
2082 if ((ibuf[28] != NOT_COMPRESSED) && (ibuf[28] != COMPRESSED)) {
2083 LOG("illegal compression %d\n",ibuf[28]);
2084 mutex_unlock(&cam->param_lock);
2085 return -1;
2086 }
2087 compressed = (ibuf[28] == COMPRESSED);
2088
2089 if (ibuf[29] != NO_DECIMATION && ibuf[29] != DECIMATION_ENAB) {
2090 LOG("illegal decimation %d\n",ibuf[29]);
2091 mutex_unlock(&cam->param_lock);
2092 return -1;
2093 }
2094 decimation = (ibuf[29] == DECIMATION_ENAB);
2095
2096 cam->params.yuvThreshold.yThreshold = ibuf[30];
2097 cam->params.yuvThreshold.uvThreshold = ibuf[31];
2098 cam->params.status.systemState = ibuf[32];
2099 cam->params.status.grabState = ibuf[33];
2100 cam->params.status.streamState = ibuf[34];
2101 cam->params.status.fatalError = ibuf[35];
2102 cam->params.status.cmdError = ibuf[36];
2103 cam->params.status.debugFlags = ibuf[37];
2104 cam->params.status.vpStatus = ibuf[38];
2105 cam->params.status.errorCode = ibuf[39];
2106 cam->fps = ibuf[41];
2107 mutex_unlock(&cam->param_lock);
2108
2109 linesize = skipcount(cols, out_fmt);
2110 ibuf += FRAME_HEADER_SIZE;
2111 size -= FRAME_HEADER_SIZE;
2112 ll = ibuf[0] | (ibuf[1] << 8);
2113 ibuf += 2;
2114 even_line = 1;
2115
2116 while (size > 0) {
2117 size -= (ll+2);
2118 if (size < 0) {
2119 LOG("Insufficient data in buffer\n");
2120 return -1;
2121 }
2122
2123 while (ll > 1) {
2124 if (!compressed || (compressed && !(*ibuf & 1))) {
2125 if(subsample_422 || even_line) {
2126 obuf += yuvconvert(ibuf, obuf, out_fmt,
2127 in_uyvy, cam->mmap_kludge);
2128 ibuf += 4;
2129 ll -= 4;
2130 } else {
2131 /* SUBSAMPLE_420 on an odd line */
2132 obuf += convert420(ibuf, obuf,
2133 out_fmt, linesize,
2134 cam->mmap_kludge);
2135 ibuf += 2;
2136 ll -= 2;
2137 }
2138 } else {
2139 /*skip compressed interval from previous frame*/
2140 obuf += skipcount(*ibuf >> 1, out_fmt);
2141 if (obuf > end_obuf) {
2142 LOG("Insufficient buffer size\n");
2143 return -1;
2144 }
2145 ++ibuf;
2146 ll--;
2147 }
2148 }
2149 if (ll == 1) {
2150 if (*ibuf != EOL) {
2151 DBG("EOL not found giving up after %d/%d"
2152 " bytes\n", origsize-size, origsize);
2153 return -1;
2154 }
2155
2156 ++ibuf; /* skip over EOL */
2157
2158 if ((size > 3) && (ibuf[0] == EOI) && (ibuf[1] == EOI) &&
2159 (ibuf[2] == EOI) && (ibuf[3] == EOI)) {
2160 size -= 4;
2161 break;
2162 }
2163
2164 if(decimation) {
2165 /* skip the odd lines for now */
2166 obuf += linesize;
2167 }
2168
2169 if (size > 1) {
2170 ll = ibuf[0] | (ibuf[1] << 8);
2171 ibuf += 2; /* skip over line length */
2172 }
2173 if(!decimation)
2174 even_line = !even_line;
2175 } else {
2176 LOG("line length was not 1 but %d after %d/%d bytes\n",
2177 ll, origsize-size, origsize);
2178 return -1;
2179 }
2180 }
2181
2182 if(decimation) {
2183 /* interpolate odd rows */
2184 int i, j;
2185 u8 *prev, *next;
2186 prev = cam->decompressed_frame.data;
2187 obuf = prev+linesize;
2188 next = obuf+linesize;
2189 for(i=1; i<rows-1; i+=2) {
2190 for(j=0; j<linesize; ++j) {
2191 *obuf++ = ((int)*prev++ + *next++) / 2;
2192 }
2193 prev += linesize;
2194 obuf += linesize;
2195 next += linesize;
2196 }
2197 /* last row is odd, just copy previous row */
2198 memcpy(obuf, prev, linesize);
2199 }
2200
2201 cam->decompressed_frame.count = obuf-cam->decompressed_frame.data;
2202
2203 return cam->decompressed_frame.count;
2204}
2205
2206/* InitStreamCap wrapper to select correct start line */
2207static inline int init_stream_cap(struct cam_data *cam)
2208{
2209 return do_command(cam, CPIA_COMMAND_InitStreamCap,
2210 0, cam->params.streamStartLine, 0, 0);
2211}
2212
2213
2214/* find_over_exposure
2215 * Finds a suitable value of OverExposure for use with SetFlickerCtrl
2216 * Some calculation is required because this value changes with the brightness
2217 * set with SetColourParameters
2218 *
2219 * Parameters: Brightness - last brightness value set with SetColourParameters
2220 *
2221 * Returns: OverExposure value to use with SetFlickerCtrl
2222 */
2223#define FLICKER_MAX_EXPOSURE 250
2224#define FLICKER_ALLOWABLE_OVER_EXPOSURE 146
2225#define FLICKER_BRIGHTNESS_CONSTANT 59
2226static int find_over_exposure(int brightness)
2227{
2228 int MaxAllowableOverExposure, OverExposure;
2229
2230 MaxAllowableOverExposure = FLICKER_MAX_EXPOSURE - brightness -
2231 FLICKER_BRIGHTNESS_CONSTANT;
2232
2233 if (MaxAllowableOverExposure < FLICKER_ALLOWABLE_OVER_EXPOSURE) {
2234 OverExposure = MaxAllowableOverExposure;
2235 } else {
2236 OverExposure = FLICKER_ALLOWABLE_OVER_EXPOSURE;
2237 }
2238
2239 return OverExposure;
2240}
2241#undef FLICKER_MAX_EXPOSURE
2242#undef FLICKER_ALLOWABLE_OVER_EXPOSURE
2243#undef FLICKER_BRIGHTNESS_CONSTANT
2244
2245/* update various camera modes and settings */
2246static void dispatch_commands(struct cam_data *cam)
2247{
2248 mutex_lock(&cam->param_lock);
2249 if (cam->cmd_queue==COMMAND_NONE) {
2250 mutex_unlock(&cam->param_lock);
2251 return;
2252 }
2253 DEB_BYTE(cam->cmd_queue);
2254 DEB_BYTE(cam->cmd_queue>>8);
2255 if (cam->cmd_queue & COMMAND_SETFORMAT) {
2256 do_command(cam, CPIA_COMMAND_SetFormat,
2257 cam->params.format.videoSize,
2258 cam->params.format.subSample,
2259 cam->params.format.yuvOrder, 0);
2260 do_command(cam, CPIA_COMMAND_SetROI,
2261 cam->params.roi.colStart, cam->params.roi.colEnd,
2262 cam->params.roi.rowStart, cam->params.roi.rowEnd);
2263 cam->first_frame = 1;
2264 }
2265
2266 if (cam->cmd_queue & COMMAND_SETCOLOURPARAMS)
2267 do_command(cam, CPIA_COMMAND_SetColourParams,
2268 cam->params.colourParams.brightness,
2269 cam->params.colourParams.contrast,
2270 cam->params.colourParams.saturation, 0);
2271
2272 if (cam->cmd_queue & COMMAND_SETAPCOR)
2273 do_command(cam, CPIA_COMMAND_SetApcor,
2274 cam->params.apcor.gain1,
2275 cam->params.apcor.gain2,
2276 cam->params.apcor.gain4,
2277 cam->params.apcor.gain8);
2278
2279 if (cam->cmd_queue & COMMAND_SETVLOFFSET)
2280 do_command(cam, CPIA_COMMAND_SetVLOffset,
2281 cam->params.vlOffset.gain1,
2282 cam->params.vlOffset.gain2,
2283 cam->params.vlOffset.gain4,
2284 cam->params.vlOffset.gain8);
2285
2286 if (cam->cmd_queue & COMMAND_SETEXPOSURE) {
2287 do_command_extended(cam, CPIA_COMMAND_SetExposure,
2288 cam->params.exposure.gainMode,
2289 1,
2290 cam->params.exposure.compMode,
2291 cam->params.exposure.centreWeight,
2292 cam->params.exposure.gain,
2293 cam->params.exposure.fineExp,
2294 cam->params.exposure.coarseExpLo,
2295 cam->params.exposure.coarseExpHi,
2296 cam->params.exposure.redComp,
2297 cam->params.exposure.green1Comp,
2298 cam->params.exposure.green2Comp,
2299 cam->params.exposure.blueComp);
2300 if(cam->params.exposure.expMode != 1) {
2301 do_command_extended(cam, CPIA_COMMAND_SetExposure,
2302 0,
2303 cam->params.exposure.expMode,
2304 0, 0,
2305 cam->params.exposure.gain,
2306 cam->params.exposure.fineExp,
2307 cam->params.exposure.coarseExpLo,
2308 cam->params.exposure.coarseExpHi,
2309 0, 0, 0, 0);
2310 }
2311 }
2312
2313 if (cam->cmd_queue & COMMAND_SETCOLOURBALANCE) {
2314 if (cam->params.colourBalance.balanceMode == 1) {
2315 do_command(cam, CPIA_COMMAND_SetColourBalance,
2316 1,
2317 cam->params.colourBalance.redGain,
2318 cam->params.colourBalance.greenGain,
2319 cam->params.colourBalance.blueGain);
2320 do_command(cam, CPIA_COMMAND_SetColourBalance,
2321 3, 0, 0, 0);
2322 }
2323 if (cam->params.colourBalance.balanceMode == 2) {
2324 do_command(cam, CPIA_COMMAND_SetColourBalance,
2325 2, 0, 0, 0);
2326 }
2327 if (cam->params.colourBalance.balanceMode == 3) {
2328 do_command(cam, CPIA_COMMAND_SetColourBalance,
2329 3, 0, 0, 0);
2330 }
2331 }
2332
2333 if (cam->cmd_queue & COMMAND_SETCOMPRESSIONTARGET)
2334 do_command(cam, CPIA_COMMAND_SetCompressionTarget,
2335 cam->params.compressionTarget.frTargeting,
2336 cam->params.compressionTarget.targetFR,
2337 cam->params.compressionTarget.targetQ, 0);
2338
2339 if (cam->cmd_queue & COMMAND_SETYUVTHRESH)
2340 do_command(cam, CPIA_COMMAND_SetYUVThresh,
2341 cam->params.yuvThreshold.yThreshold,
2342 cam->params.yuvThreshold.uvThreshold, 0, 0);
2343
2344 if (cam->cmd_queue & COMMAND_SETCOMPRESSIONPARAMS)
2345 do_command_extended(cam, CPIA_COMMAND_SetCompressionParams,
2346 0, 0, 0, 0,
2347 cam->params.compressionParams.hysteresis,
2348 cam->params.compressionParams.threshMax,
2349 cam->params.compressionParams.smallStep,
2350 cam->params.compressionParams.largeStep,
2351 cam->params.compressionParams.decimationHysteresis,
2352 cam->params.compressionParams.frDiffStepThresh,
2353 cam->params.compressionParams.qDiffStepThresh,
2354 cam->params.compressionParams.decimationThreshMod);
2355
2356 if (cam->cmd_queue & COMMAND_SETCOMPRESSION)
2357 do_command(cam, CPIA_COMMAND_SetCompression,
2358 cam->params.compression.mode,
2359 cam->params.compression.decimation, 0, 0);
2360
2361 if (cam->cmd_queue & COMMAND_SETSENSORFPS)
2362 do_command(cam, CPIA_COMMAND_SetSensorFPS,
2363 cam->params.sensorFps.divisor,
2364 cam->params.sensorFps.baserate, 0, 0);
2365
2366 if (cam->cmd_queue & COMMAND_SETFLICKERCTRL)
2367 do_command(cam, CPIA_COMMAND_SetFlickerCtrl,
2368 cam->params.flickerControl.flickerMode,
2369 cam->params.flickerControl.coarseJump,
2370 abs(cam->params.flickerControl.allowableOverExposure),
2371 0);
2372
2373 if (cam->cmd_queue & COMMAND_SETECPTIMING)
2374 do_command(cam, CPIA_COMMAND_SetECPTiming,
2375 cam->params.ecpTiming, 0, 0, 0);
2376
2377 if (cam->cmd_queue & COMMAND_PAUSE)
2378 do_command(cam, CPIA_COMMAND_EndStreamCap, 0, 0, 0, 0);
2379
2380 if (cam->cmd_queue & COMMAND_RESUME)
2381 init_stream_cap(cam);
2382
2383 if (cam->cmd_queue & COMMAND_SETLIGHTS && cam->params.qx3.qx3_detected)
2384 {
2385 int p1 = (cam->params.qx3.bottomlight == 0) << 1;
2386 int p2 = (cam->params.qx3.toplight == 0) << 3;
2387 do_command(cam, CPIA_COMMAND_WriteVCReg, 0x90, 0x8F, 0x50, 0);
2388 do_command(cam, CPIA_COMMAND_WriteMCPort, 2, 0, (p1|p2|0xE0), 0);
2389 }
2390
2391 cam->cmd_queue = COMMAND_NONE;
2392 mutex_unlock(&cam->param_lock);
2393 return;
2394}
2395
2396
2397
2398static void set_flicker(struct cam_params *params, volatile u32 *command_flags,
2399 int on)
2400{
2401 /* Everything in here is from the Windows driver */
2402#define FIRMWARE_VERSION(x,y) (params->version.firmwareVersion == (x) && \
2403 params->version.firmwareRevision == (y))
2404/* define for compgain calculation */
2405#if 0
2406#define COMPGAIN(base, curexp, newexp) \
2407 (u8) ((((float) base - 128.0) * ((float) curexp / (float) newexp)) + 128.5)
2408#define EXP_FROM_COMP(basecomp, curcomp, curexp) \
2409 (u16)((float)curexp * (float)(u8)(curcomp + 128) / (float)(u8)(basecomp - 128))
2410#else
2411 /* equivalent functions without floating point math */
2412#define COMPGAIN(base, curexp, newexp) \
2413 (u8)(128 + (((u32)(2*(base-128)*curexp + newexp)) / (2* newexp)) )
2414#define EXP_FROM_COMP(basecomp, curcomp, curexp) \
2415 (u16)(((u32)(curexp * (u8)(curcomp + 128)) / (u8)(basecomp - 128)))
2416#endif
2417
2418
2419 int currentexp = params->exposure.coarseExpLo +
2420 params->exposure.coarseExpHi*256;
2421 int startexp;
2422 if (on) {
2423 int cj = params->flickerControl.coarseJump;
2424 params->flickerControl.flickerMode = 1;
2425 params->flickerControl.disabled = 0;
2426 if(params->exposure.expMode != 2)
2427 *command_flags |= COMMAND_SETEXPOSURE;
2428 params->exposure.expMode = 2;
2429 currentexp = currentexp << params->exposure.gain;
2430 params->exposure.gain = 0;
2431 /* round down current exposure to nearest value */
2432 startexp = (currentexp + ROUND_UP_EXP_FOR_FLICKER) / cj;
2433 if(startexp < 1)
2434 startexp = 1;
2435 startexp = (startexp * cj) - 1;
2436 if(FIRMWARE_VERSION(1,2))
2437 while(startexp > MAX_EXP_102)
2438 startexp -= cj;
2439 else
2440 while(startexp > MAX_EXP)
2441 startexp -= cj;
2442 params->exposure.coarseExpLo = startexp & 0xff;
2443 params->exposure.coarseExpHi = startexp >> 8;
2444 if (currentexp > startexp) {
2445 if (currentexp > (2 * startexp))
2446 currentexp = 2 * startexp;
2447 params->exposure.redComp = COMPGAIN (COMP_RED, currentexp, startexp);
2448 params->exposure.green1Comp = COMPGAIN (COMP_GREEN1, currentexp, startexp);
2449 params->exposure.green2Comp = COMPGAIN (COMP_GREEN2, currentexp, startexp);
2450 params->exposure.blueComp = COMPGAIN (COMP_BLUE, currentexp, startexp);
2451 } else {
2452 params->exposure.redComp = COMP_RED;
2453 params->exposure.green1Comp = COMP_GREEN1;
2454 params->exposure.green2Comp = COMP_GREEN2;
2455 params->exposure.blueComp = COMP_BLUE;
2456 }
2457 if(FIRMWARE_VERSION(1,2))
2458 params->exposure.compMode = 0;
2459 else
2460 params->exposure.compMode = 1;
2461
2462 params->apcor.gain1 = 0x18;
2463 params->apcor.gain2 = 0x18;
2464 params->apcor.gain4 = 0x16;
2465 params->apcor.gain8 = 0x14;
2466 *command_flags |= COMMAND_SETAPCOR;
2467 } else {
2468 params->flickerControl.flickerMode = 0;
2469 params->flickerControl.disabled = 1;
2470 /* Coarse = average of equivalent coarse for each comp channel */
2471 startexp = EXP_FROM_COMP(COMP_RED, params->exposure.redComp, currentexp);
2472 startexp += EXP_FROM_COMP(COMP_GREEN1, params->exposure.green1Comp, currentexp);
2473 startexp += EXP_FROM_COMP(COMP_GREEN2, params->exposure.green2Comp, currentexp);
2474 startexp += EXP_FROM_COMP(COMP_BLUE, params->exposure.blueComp, currentexp);
2475 startexp = startexp >> 2;
2476 while(startexp > MAX_EXP &&
2477 params->exposure.gain < params->exposure.gainMode-1) {
2478 startexp = startexp >> 1;
2479 ++params->exposure.gain;
2480 }
2481 if(FIRMWARE_VERSION(1,2) && startexp > MAX_EXP_102)
2482 startexp = MAX_EXP_102;
2483 if(startexp > MAX_EXP)
2484 startexp = MAX_EXP;
2485 params->exposure.coarseExpLo = startexp&0xff;
2486 params->exposure.coarseExpHi = startexp >> 8;
2487 params->exposure.redComp = COMP_RED;
2488 params->exposure.green1Comp = COMP_GREEN1;
2489 params->exposure.green2Comp = COMP_GREEN2;
2490 params->exposure.blueComp = COMP_BLUE;
2491 params->exposure.compMode = 1;
2492 *command_flags |= COMMAND_SETEXPOSURE;
2493 params->apcor.gain1 = 0x18;
2494 params->apcor.gain2 = 0x16;
2495 params->apcor.gain4 = 0x24;
2496 params->apcor.gain8 = 0x34;
2497 *command_flags |= COMMAND_SETAPCOR;
2498 }
2499 params->vlOffset.gain1 = 20;
2500 params->vlOffset.gain2 = 24;
2501 params->vlOffset.gain4 = 26;
2502 params->vlOffset.gain8 = 26;
2503 *command_flags |= COMMAND_SETVLOFFSET;
2504#undef FIRMWARE_VERSION
2505#undef EXP_FROM_COMP
2506#undef COMPGAIN
2507}
2508
2509#define FIRMWARE_VERSION(x,y) (cam->params.version.firmwareVersion == (x) && \
2510 cam->params.version.firmwareRevision == (y))
2511/* monitor the exposure and adjust the sensor frame rate if needed */
2512static void monitor_exposure(struct cam_data *cam)
2513{
2514 u8 exp_acc, bcomp, gain, coarseL, cmd[8], data[8];
2515 int retval, light_exp, dark_exp, very_dark_exp;
2516 int old_exposure, new_exposure, framerate;
2517
2518 /* get necessary stats and register settings from camera */
2519 /* do_command can't handle this, so do it ourselves */
2520 cmd[0] = CPIA_COMMAND_ReadVPRegs>>8;
2521 cmd[1] = CPIA_COMMAND_ReadVPRegs&0xff;
2522 cmd[2] = 30;
2523 cmd[3] = 4;
2524 cmd[4] = 9;
2525 cmd[5] = 8;
2526 cmd[6] = 8;
2527 cmd[7] = 0;
2528 retval = cam->ops->transferCmd(cam->lowlevel_data, cmd, data);
2529 if (retval) {
2530 LOG("ReadVPRegs(30,4,9,8) - failed, retval=%d\n",
2531 retval);
2532 return;
2533 }
2534 exp_acc = data[0];
2535 bcomp = data[1];
2536 gain = data[2];
2537 coarseL = data[3];
2538
2539 mutex_lock(&cam->param_lock);
2540 light_exp = cam->params.colourParams.brightness +
2541 TC - 50 + EXP_ACC_LIGHT;
2542 if(light_exp > 255)
2543 light_exp = 255;
2544 dark_exp = cam->params.colourParams.brightness +
2545 TC - 50 - EXP_ACC_DARK;
2546 if(dark_exp < 0)
2547 dark_exp = 0;
2548 very_dark_exp = dark_exp/2;
2549
2550 old_exposure = cam->params.exposure.coarseExpHi * 256 +
2551 cam->params.exposure.coarseExpLo;
2552
2553 if(!cam->params.flickerControl.disabled) {
2554 /* Flicker control on */
2555 int max_comp = FIRMWARE_VERSION(1,2) ? MAX_COMP : HIGH_COMP_102;
2556 bcomp += 128; /* decode */
2557 if(bcomp >= max_comp && exp_acc < dark_exp) {
2558 /* dark */
2559 if(exp_acc < very_dark_exp) {
2560 /* very dark */
2561 if(cam->exposure_status == EXPOSURE_VERY_DARK)
2562 ++cam->exposure_count;
2563 else {
2564 cam->exposure_status = EXPOSURE_VERY_DARK;
2565 cam->exposure_count = 1;
2566 }
2567 } else {
2568 /* just dark */
2569 if(cam->exposure_status == EXPOSURE_DARK)
2570 ++cam->exposure_count;
2571 else {
2572 cam->exposure_status = EXPOSURE_DARK;
2573 cam->exposure_count = 1;
2574 }
2575 }
2576 } else if(old_exposure <= LOW_EXP || exp_acc > light_exp) {
2577 /* light */
2578 if(old_exposure <= VERY_LOW_EXP) {
2579 /* very light */
2580 if(cam->exposure_status == EXPOSURE_VERY_LIGHT)
2581 ++cam->exposure_count;
2582 else {
2583 cam->exposure_status = EXPOSURE_VERY_LIGHT;
2584 cam->exposure_count = 1;
2585 }
2586 } else {
2587 /* just light */
2588 if(cam->exposure_status == EXPOSURE_LIGHT)
2589 ++cam->exposure_count;
2590 else {
2591 cam->exposure_status = EXPOSURE_LIGHT;
2592 cam->exposure_count = 1;
2593 }
2594 }
2595 } else {
2596 /* not dark or light */
2597 cam->exposure_status = EXPOSURE_NORMAL;
2598 }
2599 } else {
2600 /* Flicker control off */
2601 if(old_exposure >= MAX_EXP && exp_acc < dark_exp) {
2602 /* dark */
2603 if(exp_acc < very_dark_exp) {
2604 /* very dark */
2605 if(cam->exposure_status == EXPOSURE_VERY_DARK)
2606 ++cam->exposure_count;
2607 else {
2608 cam->exposure_status = EXPOSURE_VERY_DARK;
2609 cam->exposure_count = 1;
2610 }
2611 } else {
2612 /* just dark */
2613 if(cam->exposure_status == EXPOSURE_DARK)
2614 ++cam->exposure_count;
2615 else {
2616 cam->exposure_status = EXPOSURE_DARK;
2617 cam->exposure_count = 1;
2618 }
2619 }
2620 } else if(old_exposure <= LOW_EXP || exp_acc > light_exp) {
2621 /* light */
2622 if(old_exposure <= VERY_LOW_EXP) {
2623 /* very light */
2624 if(cam->exposure_status == EXPOSURE_VERY_LIGHT)
2625 ++cam->exposure_count;
2626 else {
2627 cam->exposure_status = EXPOSURE_VERY_LIGHT;
2628 cam->exposure_count = 1;
2629 }
2630 } else {
2631 /* just light */
2632 if(cam->exposure_status == EXPOSURE_LIGHT)
2633 ++cam->exposure_count;
2634 else {
2635 cam->exposure_status = EXPOSURE_LIGHT;
2636 cam->exposure_count = 1;
2637 }
2638 }
2639 } else {
2640 /* not dark or light */
2641 cam->exposure_status = EXPOSURE_NORMAL;
2642 }
2643 }
2644
2645 framerate = cam->fps;
2646 if(framerate > 30 || framerate < 1)
2647 framerate = 1;
2648
2649 if(!cam->params.flickerControl.disabled) {
2650 /* Flicker control on */
2651 if((cam->exposure_status == EXPOSURE_VERY_DARK ||
2652 cam->exposure_status == EXPOSURE_DARK) &&
2653 cam->exposure_count >= DARK_TIME*framerate &&
2654 cam->params.sensorFps.divisor < 3) {
2655
2656 /* dark for too long */
2657 ++cam->params.sensorFps.divisor;
2658 cam->cmd_queue |= COMMAND_SETSENSORFPS;
2659
2660 cam->params.flickerControl.coarseJump =
2661 flicker_jumps[cam->mainsFreq]
2662 [cam->params.sensorFps.baserate]
2663 [cam->params.sensorFps.divisor];
2664 cam->cmd_queue |= COMMAND_SETFLICKERCTRL;
2665
2666 new_exposure = cam->params.flickerControl.coarseJump-1;
2667 while(new_exposure < old_exposure/2)
2668 new_exposure += cam->params.flickerControl.coarseJump;
2669 cam->params.exposure.coarseExpLo = new_exposure & 0xff;
2670 cam->params.exposure.coarseExpHi = new_exposure >> 8;
2671 cam->cmd_queue |= COMMAND_SETEXPOSURE;
2672 cam->exposure_status = EXPOSURE_NORMAL;
2673 LOG("Automatically decreasing sensor_fps\n");
2674
2675 } else if((cam->exposure_status == EXPOSURE_VERY_LIGHT ||
2676 cam->exposure_status == EXPOSURE_LIGHT) &&
2677 cam->exposure_count >= LIGHT_TIME*framerate &&
2678 cam->params.sensorFps.divisor > 0) {
2679
2680 /* light for too long */
2681 int max_exp = FIRMWARE_VERSION(1,2) ? MAX_EXP_102 : MAX_EXP ;
2682
2683 --cam->params.sensorFps.divisor;
2684 cam->cmd_queue |= COMMAND_SETSENSORFPS;
2685
2686 cam->params.flickerControl.coarseJump =
2687 flicker_jumps[cam->mainsFreq]
2688 [cam->params.sensorFps.baserate]
2689 [cam->params.sensorFps.divisor];
2690 cam->cmd_queue |= COMMAND_SETFLICKERCTRL;
2691
2692 new_exposure = cam->params.flickerControl.coarseJump-1;
2693 while(new_exposure < 2*old_exposure &&
2694 new_exposure+
2695 cam->params.flickerControl.coarseJump < max_exp)
2696 new_exposure += cam->params.flickerControl.coarseJump;
2697 cam->params.exposure.coarseExpLo = new_exposure & 0xff;
2698 cam->params.exposure.coarseExpHi = new_exposure >> 8;
2699 cam->cmd_queue |= COMMAND_SETEXPOSURE;
2700 cam->exposure_status = EXPOSURE_NORMAL;
2701 LOG("Automatically increasing sensor_fps\n");
2702 }
2703 } else {
2704 /* Flicker control off */
2705 if((cam->exposure_status == EXPOSURE_VERY_DARK ||
2706 cam->exposure_status == EXPOSURE_DARK) &&
2707 cam->exposure_count >= DARK_TIME*framerate &&
2708 cam->params.sensorFps.divisor < 3) {
2709
2710 /* dark for too long */
2711 ++cam->params.sensorFps.divisor;
2712 cam->cmd_queue |= COMMAND_SETSENSORFPS;
2713
2714 if(cam->params.exposure.gain > 0) {
2715 --cam->params.exposure.gain;
2716 cam->cmd_queue |= COMMAND_SETEXPOSURE;
2717 }
2718 cam->exposure_status = EXPOSURE_NORMAL;
2719 LOG("Automatically decreasing sensor_fps\n");
2720
2721 } else if((cam->exposure_status == EXPOSURE_VERY_LIGHT ||
2722 cam->exposure_status == EXPOSURE_LIGHT) &&
2723 cam->exposure_count >= LIGHT_TIME*framerate &&
2724 cam->params.sensorFps.divisor > 0) {
2725
2726 /* light for too long */
2727 --cam->params.sensorFps.divisor;
2728 cam->cmd_queue |= COMMAND_SETSENSORFPS;
2729
2730 if(cam->params.exposure.gain <
2731 cam->params.exposure.gainMode-1) {
2732 ++cam->params.exposure.gain;
2733 cam->cmd_queue |= COMMAND_SETEXPOSURE;
2734 }
2735 cam->exposure_status = EXPOSURE_NORMAL;
2736 LOG("Automatically increasing sensor_fps\n");
2737 }
2738 }
2739 mutex_unlock(&cam->param_lock);
2740}
2741
2742/*-----------------------------------------------------------------*/
2743/* if flicker is switched off, this function switches it back on.It checks,
2744 however, that conditions are suitable before restarting it.
2745 This should only be called for firmware version 1.2.
2746
2747 It also adjust the colour balance when an exposure step is detected - as
2748 long as flicker is running
2749*/
2750static void restart_flicker(struct cam_data *cam)
2751{
2752 int cam_exposure, old_exp;
2753 if(!FIRMWARE_VERSION(1,2))
2754 return;
2755 mutex_lock(&cam->param_lock);
2756 if(cam->params.flickerControl.flickerMode == 0 ||
2757 cam->raw_image[39] == 0) {
2758 mutex_unlock(&cam->param_lock);
2759 return;
2760 }
2761 cam_exposure = cam->raw_image[39]*2;
2762 old_exp = cam->params.exposure.coarseExpLo +
2763 cam->params.exposure.coarseExpHi*256;
2764 /*
2765 see how far away camera exposure is from a valid
2766 flicker exposure value
2767 */
2768 cam_exposure %= cam->params.flickerControl.coarseJump;
2769 if(!cam->params.flickerControl.disabled &&
2770 cam_exposure <= cam->params.flickerControl.coarseJump - 3) {
2771 /* Flicker control auto-disabled */
2772 cam->params.flickerControl.disabled = 1;
2773 }
2774
2775 if(cam->params.flickerControl.disabled &&
2776 cam->params.flickerControl.flickerMode &&
2777 old_exp > cam->params.flickerControl.coarseJump +
2778 ROUND_UP_EXP_FOR_FLICKER) {
2779 /* exposure is now high enough to switch
2780 flicker control back on */
2781 set_flicker(&cam->params, &cam->cmd_queue, 1);
2782 if((cam->cmd_queue & COMMAND_SETEXPOSURE) &&
2783 cam->params.exposure.expMode == 2)
2784 cam->exposure_status = EXPOSURE_NORMAL;
2785
2786 }
2787 mutex_unlock(&cam->param_lock);
2788}
2789#undef FIRMWARE_VERSION
2790
2791static int clear_stall(struct cam_data *cam)
2792{
2793 /* FIXME: Does this actually work? */
2794 LOG("Clearing stall\n");
2795
2796 cam->ops->streamRead(cam->lowlevel_data, cam->raw_image, 0);
2797 do_command(cam, CPIA_COMMAND_GetCameraStatus,0,0,0,0);
2798 return cam->params.status.streamState != STREAM_PAUSED;
2799}
2800
2801/* kernel thread function to read image from camera */
2802static int fetch_frame(void *data)
2803{
2804 int image_size, retry;
2805 struct cam_data *cam = (struct cam_data *)data;
2806 unsigned long oldjif, rate, diff;
2807
2808 /* Allow up to two bad images in a row to be read and
2809 * ignored before an error is reported */
2810 for (retry = 0; retry < 3; ++retry) {
2811 if (retry)
2812 DBG("retry=%d\n", retry);
2813
2814 if (!cam->ops)
2815 continue;
2816
2817 /* load first frame always uncompressed */
2818 if (cam->first_frame &&
2819 cam->params.compression.mode != CPIA_COMPRESSION_NONE) {
2820 do_command(cam, CPIA_COMMAND_SetCompression,
2821 CPIA_COMPRESSION_NONE,
2822 NO_DECIMATION, 0, 0);
2823 /* Trial & error - Discarding a frame prevents the
2824 first frame from having an error in the data. */
2825 do_command(cam, CPIA_COMMAND_DiscardFrame, 0, 0, 0, 0);
2826 }
2827
2828 /* init camera upload */
2829 if (do_command(cam, CPIA_COMMAND_GrabFrame, 0,
2830 cam->params.streamStartLine, 0, 0))
2831 continue;
2832
2833 if (cam->ops->wait_for_stream_ready) {
2834 /* loop until image ready */
2835 int count = 0;
2836 do_command(cam, CPIA_COMMAND_GetCameraStatus,0,0,0,0);
2837 while (cam->params.status.streamState != STREAM_READY) {
2838 if(++count > READY_TIMEOUT)
2839 break;
2840 if(cam->params.status.streamState ==
2841 STREAM_PAUSED) {
2842 /* Bad news */
2843 if(!clear_stall(cam))
2844 return -EIO;
2845 }
2846
2847 cond_resched();
2848
2849 /* sleep for 10 ms, hopefully ;) */
2850 msleep_interruptible(10);
2851 if (signal_pending(current))
2852 return -EINTR;
2853
2854 do_command(cam, CPIA_COMMAND_GetCameraStatus,
2855 0, 0, 0, 0);
2856 }
2857 if(cam->params.status.streamState != STREAM_READY) {
2858 continue;
2859 }
2860 }
2861
2862 cond_resched();
2863
2864 /* grab image from camera */
2865 oldjif = jiffies;
2866 image_size = cam->ops->streamRead(cam->lowlevel_data,
2867 cam->raw_image, 0);
2868 if (image_size <= 0) {
2869 DBG("streamRead failed: %d\n", image_size);
2870 continue;
2871 }
2872
2873 rate = image_size * HZ / 1024;
2874 diff = jiffies-oldjif;
2875 cam->transfer_rate = diff==0 ? rate : rate/diff;
2876 /* diff==0 ? unlikely but possible */
2877
2878 /* Switch flicker control back on if it got turned off */
2879 restart_flicker(cam);
2880
2881 /* If AEC is enabled, monitor the exposure and
2882 adjust the sensor frame rate if needed */
2883 if(cam->params.exposure.expMode == 2)
2884 monitor_exposure(cam);
2885
2886 /* camera idle now so dispatch queued commands */
2887 dispatch_commands(cam);
2888
2889 /* Update our knowledge of the camera state */
2890 do_command(cam, CPIA_COMMAND_GetColourBalance, 0, 0, 0, 0);
2891 do_command(cam, CPIA_COMMAND_GetExposure, 0, 0, 0, 0);
2892 do_command(cam, CPIA_COMMAND_ReadMCPorts, 0, 0, 0, 0);
2893
2894 /* decompress and convert image to by copying it from
2895 * raw_image to decompressed_frame
2896 */
2897
2898 cond_resched();
2899
2900 cam->image_size = parse_picture(cam, image_size);
2901 if (cam->image_size <= 0) {
2902 DBG("parse_picture failed %d\n", cam->image_size);
2903 if(cam->params.compression.mode !=
2904 CPIA_COMPRESSION_NONE) {
2905 /* Compression may not work right if we
2906 had a bad frame, get the next one
2907 uncompressed. */
2908 cam->first_frame = 1;
2909 do_command(cam, CPIA_COMMAND_SetGrabMode,
2910 CPIA_GRAB_SINGLE, 0, 0, 0);
2911 /* FIXME: Trial & error - need up to 70ms for
2912 the grab mode change to complete ? */
2913 msleep_interruptible(70);
2914 if (signal_pending(current))
2915 return -EINTR;
2916 }
2917 } else
2918 break;
2919 }
2920
2921 if (retry < 3) {
2922 /* FIXME: this only works for double buffering */
2923 if (cam->frame[cam->curframe].state == FRAME_READY) {
2924 memcpy(cam->frame[cam->curframe].data,
2925 cam->decompressed_frame.data,
2926 cam->decompressed_frame.count);
2927 cam->frame[cam->curframe].state = FRAME_DONE;
2928 } else
2929 cam->decompressed_frame.state = FRAME_DONE;
2930
2931 if (cam->first_frame) {
2932 cam->first_frame = 0;
2933 do_command(cam, CPIA_COMMAND_SetCompression,
2934 cam->params.compression.mode,
2935 cam->params.compression.decimation, 0, 0);
2936
2937 /* Switch from single-grab to continuous grab */
2938 do_command(cam, CPIA_COMMAND_SetGrabMode,
2939 CPIA_GRAB_CONTINUOUS, 0, 0, 0);
2940 }
2941 return 0;
2942 }
2943 return -EIO;
2944}
2945
2946static int capture_frame(struct cam_data *cam, struct video_mmap *vm)
2947{
2948 if (!cam->frame_buf) {
2949 /* we do lazy allocation */
2950 int err;
2951 if ((err = allocate_frame_buf(cam)))
2952 return err;
2953 }
2954
2955 cam->curframe = vm->frame;
2956 cam->frame[cam->curframe].state = FRAME_READY;
2957 return fetch_frame(cam);
2958}
2959
2960static int goto_high_power(struct cam_data *cam)
2961{
2962 if (do_command(cam, CPIA_COMMAND_GotoHiPower, 0, 0, 0, 0))
2963 return -EIO;
2964 msleep_interruptible(40); /* windows driver does it too */
2965 if(signal_pending(current))
2966 return -EINTR;
2967 if (do_command(cam, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0))
2968 return -EIO;
2969 if (cam->params.status.systemState == HI_POWER_STATE) {
2970 DBG("camera now in HIGH power state\n");
2971 return 0;
2972 }
2973 printstatus(cam);
2974 return -EIO;
2975}
2976
2977static int goto_low_power(struct cam_data *cam)
2978{
2979 if (do_command(cam, CPIA_COMMAND_GotoLoPower, 0, 0, 0, 0))
2980 return -1;
2981 if (do_command(cam, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0))
2982 return -1;
2983 if (cam->params.status.systemState == LO_POWER_STATE) {
2984 DBG("camera now in LOW power state\n");
2985 return 0;
2986 }
2987 printstatus(cam);
2988 return -1;
2989}
2990
2991static void save_camera_state(struct cam_data *cam)
2992{
2993 if(!(cam->cmd_queue & COMMAND_SETCOLOURBALANCE))
2994 do_command(cam, CPIA_COMMAND_GetColourBalance, 0, 0, 0, 0);
2995 if(!(cam->cmd_queue & COMMAND_SETEXPOSURE))
2996 do_command(cam, CPIA_COMMAND_GetExposure, 0, 0, 0, 0);
2997
2998 DBG("%d/%d/%d/%d/%d/%d/%d/%d\n",
2999 cam->params.exposure.gain,
3000 cam->params.exposure.fineExp,
3001 cam->params.exposure.coarseExpLo,
3002 cam->params.exposure.coarseExpHi,
3003 cam->params.exposure.redComp,
3004 cam->params.exposure.green1Comp,
3005 cam->params.exposure.green2Comp,
3006 cam->params.exposure.blueComp);
3007 DBG("%d/%d/%d\n",
3008 cam->params.colourBalance.redGain,
3009 cam->params.colourBalance.greenGain,
3010 cam->params.colourBalance.blueGain);
3011}
3012
3013static int set_camera_state(struct cam_data *cam)
3014{
3015 cam->cmd_queue = COMMAND_SETCOMPRESSION |
3016 COMMAND_SETCOMPRESSIONTARGET |
3017 COMMAND_SETCOLOURPARAMS |
3018 COMMAND_SETFORMAT |
3019 COMMAND_SETYUVTHRESH |
3020 COMMAND_SETECPTIMING |
3021 COMMAND_SETCOMPRESSIONPARAMS |
3022 COMMAND_SETEXPOSURE |
3023 COMMAND_SETCOLOURBALANCE |
3024 COMMAND_SETSENSORFPS |
3025 COMMAND_SETAPCOR |
3026 COMMAND_SETFLICKERCTRL |
3027 COMMAND_SETVLOFFSET;
3028
3029 do_command(cam, CPIA_COMMAND_SetGrabMode, CPIA_GRAB_SINGLE,0,0,0);
3030 dispatch_commands(cam);
3031
3032 /* Wait 6 frames for the sensor to get all settings and
3033 AEC/ACB to settle */
3034 msleep_interruptible(6*(cam->params.sensorFps.baserate ? 33 : 40) *
3035 (1 << cam->params.sensorFps.divisor) + 10);
3036
3037 if(signal_pending(current))
3038 return -EINTR;
3039
3040 save_camera_state(cam);
3041
3042 return 0;
3043}
3044
3045static void get_version_information(struct cam_data *cam)
3046{
3047 /* GetCPIAVersion */
3048 do_command(cam, CPIA_COMMAND_GetCPIAVersion, 0, 0, 0, 0);
3049
3050 /* GetPnPID */
3051 do_command(cam, CPIA_COMMAND_GetPnPID, 0, 0, 0, 0);
3052}
3053
3054/* initialize camera */
3055static int reset_camera(struct cam_data *cam)
3056{
3057 int err;
3058 /* Start the camera in low power mode */
3059 if (goto_low_power(cam)) {
3060 if (cam->params.status.systemState != WARM_BOOT_STATE)
3061 return -ENODEV;
3062
3063 /* FIXME: this is just dirty trial and error */
3064 err = goto_high_power(cam);
3065 if(err)
3066 return err;
3067 do_command(cam, CPIA_COMMAND_DiscardFrame, 0, 0, 0, 0);
3068 if (goto_low_power(cam))
3069 return -ENODEV;
3070 }
3071
3072 /* procedure described in developer's guide p3-28 */
3073
3074 /* Check the firmware version. */
3075 cam->params.version.firmwareVersion = 0;
3076 get_version_information(cam);
3077 if (cam->params.version.firmwareVersion != 1)
3078 return -ENODEV;
3079
3080 /* A bug in firmware 1-02 limits gainMode to 2 */
3081 if(cam->params.version.firmwareRevision <= 2 &&
3082 cam->params.exposure.gainMode > 2) {
3083 cam->params.exposure.gainMode = 2;
3084 }
3085
3086 /* set QX3 detected flag */
3087 cam->params.qx3.qx3_detected = (cam->params.pnpID.vendor == 0x0813 &&
3088 cam->params.pnpID.product == 0x0001);
3089
3090 /* The fatal error checking should be done after
3091 * the camera powers up (developer's guide p 3-38) */
3092
3093 /* Set streamState before transition to high power to avoid bug
3094 * in firmware 1-02 */
3095 do_command(cam, CPIA_COMMAND_ModifyCameraStatus, STREAMSTATE, 0,
3096 STREAM_NOT_READY, 0);
3097
3098 /* GotoHiPower */
3099 err = goto_high_power(cam);
3100 if (err)
3101 return err;
3102
3103 /* Check the camera status */
3104 if (do_command(cam, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0))
3105 return -EIO;
3106
3107 if (cam->params.status.fatalError) {
3108 DBG("fatal_error: %#04x\n",
3109 cam->params.status.fatalError);
3110 DBG("vp_status: %#04x\n",
3111 cam->params.status.vpStatus);
3112 if (cam->params.status.fatalError & ~(COM_FLAG|CPIA_FLAG)) {
3113 /* Fatal error in camera */
3114 return -EIO;
3115 } else if (cam->params.status.fatalError & (COM_FLAG|CPIA_FLAG)) {
3116 /* Firmware 1-02 may do this for parallel port cameras,
3117 * just clear the flags (developer's guide p 3-38) */
3118 do_command(cam, CPIA_COMMAND_ModifyCameraStatus,
3119 FATALERROR, ~(COM_FLAG|CPIA_FLAG), 0, 0);
3120 }
3121 }
3122
3123 /* Check the camera status again */
3124 if (cam->params.status.fatalError) {
3125 if (cam->params.status.fatalError)
3126 return -EIO;
3127 }
3128
3129 /* VPVersion can't be retrieved before the camera is in HiPower,
3130 * so get it here instead of in get_version_information. */
3131 do_command(cam, CPIA_COMMAND_GetVPVersion, 0, 0, 0, 0);
3132
3133 /* set camera to a known state */
3134 return set_camera_state(cam);
3135}
3136
3137static void put_cam(struct cpia_camera_ops* ops)
3138{
3139 module_put(ops->owner);
3140}
3141
3142/* ------------------------- V4L interface --------------------- */
3143static int cpia_open(struct file *file)
3144{
3145 struct video_device *dev = video_devdata(file);
3146 struct cam_data *cam = video_get_drvdata(dev);
3147 int err;
3148
3149 if (!cam) {
3150 DBG("Internal error, cam_data not found!\n");
3151 return -ENODEV;
3152 }
3153
3154 if (cam->open_count > 0) {
3155 DBG("Camera already open\n");
3156 return -EBUSY;
3157 }
3158
3159 if (!try_module_get(cam->ops->owner))
3160 return -ENODEV;
3161
3162 mutex_lock(&cam->busy_lock);
3163 err = -ENOMEM;
3164 if (!cam->raw_image) {
3165 cam->raw_image = rvmalloc(CPIA_MAX_IMAGE_SIZE);
3166 if (!cam->raw_image)
3167 goto oops;
3168 }
3169
3170 if (!cam->decompressed_frame.data) {
3171 cam->decompressed_frame.data = rvmalloc(CPIA_MAX_FRAME_SIZE);
3172 if (!cam->decompressed_frame.data)
3173 goto oops;
3174 }
3175
3176 /* open cpia */
3177 err = -ENODEV;
3178 if (cam->ops->open(cam->lowlevel_data))
3179 goto oops;
3180
3181 /* reset the camera */
3182 if ((err = reset_camera(cam)) != 0) {
3183 cam->ops->close(cam->lowlevel_data);
3184 goto oops;
3185 }
3186
3187 /* Set ownership of /proc/cpia/videoX to current user */
3188 if(cam->proc_entry)
3189 cam->proc_entry->uid = current_euid();
3190
3191 /* set mark for loading first frame uncompressed */
3192 cam->first_frame = 1;
3193
3194 /* init it to something */
3195 cam->mmap_kludge = 0;
3196
3197 ++cam->open_count;
3198 file->private_data = dev;
3199 mutex_unlock(&cam->busy_lock);
3200 return 0;
3201
3202 oops:
3203 if (cam->decompressed_frame.data) {
3204 rvfree(cam->decompressed_frame.data, CPIA_MAX_FRAME_SIZE);
3205 cam->decompressed_frame.data = NULL;
3206 }
3207 if (cam->raw_image) {
3208 rvfree(cam->raw_image, CPIA_MAX_IMAGE_SIZE);
3209 cam->raw_image = NULL;
3210 }
3211 mutex_unlock(&cam->busy_lock);
3212 put_cam(cam->ops);
3213 return err;
3214}
3215
3216static int cpia_close(struct file *file)
3217{
3218 struct video_device *dev = file->private_data;
3219 struct cam_data *cam = video_get_drvdata(dev);
3220
3221 if (cam->ops) {
3222 /* Return ownership of /proc/cpia/videoX to root */
3223 if(cam->proc_entry)
3224 cam->proc_entry->uid = 0;
3225
3226 /* save camera state for later open (developers guide ch 3.5.3) */
3227 save_camera_state(cam);
3228
3229 /* GotoLoPower */
3230 goto_low_power(cam);
3231
3232 /* Update the camera status */
3233 do_command(cam, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0);
3234
3235 /* cleanup internal state stuff */
3236 free_frames(cam->frame);
3237
3238 /* close cpia */
3239 cam->ops->close(cam->lowlevel_data);
3240
3241 put_cam(cam->ops);
3242 }
3243
3244 if (--cam->open_count == 0) {
3245 /* clean up capture-buffers */
3246 if (cam->raw_image) {
3247 rvfree(cam->raw_image, CPIA_MAX_IMAGE_SIZE);
3248 cam->raw_image = NULL;
3249 }
3250
3251 if (cam->decompressed_frame.data) {
3252 rvfree(cam->decompressed_frame.data, CPIA_MAX_FRAME_SIZE);
3253 cam->decompressed_frame.data = NULL;
3254 }
3255
3256 if (cam->frame_buf)
3257 free_frame_buf(cam);
3258
3259 if (!cam->ops)
3260 kfree(cam);
3261 }
3262 file->private_data = NULL;
3263
3264 return 0;
3265}
3266
3267static ssize_t cpia_read(struct file *file, char __user *buf,
3268 size_t count, loff_t *ppos)
3269{
3270 struct video_device *dev = file->private_data;
3271 struct cam_data *cam = video_get_drvdata(dev);
3272 int err;
3273
3274 /* make this _really_ smp and multithread-safe */
3275 if (mutex_lock_interruptible(&cam->busy_lock))
3276 return -EINTR;
3277
3278 if (!buf) {
3279 DBG("buf NULL\n");
3280 mutex_unlock(&cam->busy_lock);
3281 return -EINVAL;
3282 }
3283
3284 if (!count) {
3285 DBG("count 0\n");
3286 mutex_unlock(&cam->busy_lock);
3287 return 0;
3288 }
3289
3290 if (!cam->ops) {
3291 DBG("ops NULL\n");
3292 mutex_unlock(&cam->busy_lock);
3293 return -ENODEV;
3294 }
3295
3296 /* upload frame */
3297 cam->decompressed_frame.state = FRAME_READY;
3298 cam->mmap_kludge=0;
3299 if((err = fetch_frame(cam)) != 0) {
3300 DBG("ERROR from fetch_frame: %d\n", err);
3301 mutex_unlock(&cam->busy_lock);
3302 return err;
3303 }
3304 cam->decompressed_frame.state = FRAME_UNUSED;
3305
3306 /* copy data to user space */
3307 if (cam->decompressed_frame.count > count) {
3308 DBG("count wrong: %d, %lu\n", cam->decompressed_frame.count,
3309 (unsigned long) count);
3310 mutex_unlock(&cam->busy_lock);
3311 return -EFAULT;
3312 }
3313 if (copy_to_user(buf, cam->decompressed_frame.data,
3314 cam->decompressed_frame.count)) {
3315 DBG("copy_to_user failed\n");
3316 mutex_unlock(&cam->busy_lock);
3317 return -EFAULT;
3318 }
3319
3320 mutex_unlock(&cam->busy_lock);
3321 return cam->decompressed_frame.count;
3322}
3323
3324static long cpia_do_ioctl(struct file *file, unsigned int cmd, void *arg)
3325{
3326 struct video_device *dev = file->private_data;
3327 struct cam_data *cam = video_get_drvdata(dev);
3328 int retval = 0;
3329
3330 if (!cam || !cam->ops)
3331 return -ENODEV;
3332
3333 /* make this _really_ smp-safe */
3334 if (mutex_lock_interruptible(&cam->busy_lock))
3335 return -EINTR;
3336
3337 /* DBG("cpia_ioctl: %u\n", cmd); */
3338
3339 switch (cmd) {
3340 /* query capabilities */
3341 case VIDIOCGCAP:
3342 {
3343 struct video_capability *b = arg;
3344
3345 DBG("VIDIOCGCAP\n");
3346 strcpy(b->name, "CPiA Camera");
3347 b->type = VID_TYPE_CAPTURE | VID_TYPE_SUBCAPTURE;
3348 b->channels = 1;
3349 b->audios = 0;
3350 b->maxwidth = 352; /* VIDEOSIZE_CIF */
3351 b->maxheight = 288;
3352 b->minwidth = 48; /* VIDEOSIZE_48_48 */
3353 b->minheight = 48;
3354 break;
3355 }
3356
3357 /* get/set video source - we are a camera and nothing else */
3358 case VIDIOCGCHAN:
3359 {
3360 struct video_channel *v = arg;
3361
3362 DBG("VIDIOCGCHAN\n");
3363 if (v->channel != 0) {
3364 retval = -EINVAL;
3365 break;
3366 }
3367
3368 v->channel = 0;
3369 strcpy(v->name, "Camera");
3370 v->tuners = 0;
3371 v->flags = 0;
3372 v->type = VIDEO_TYPE_CAMERA;
3373 v->norm = 0;
3374 break;
3375 }
3376
3377 case VIDIOCSCHAN:
3378 {
3379 struct video_channel *v = arg;
3380
3381 DBG("VIDIOCSCHAN\n");
3382 if (v->channel != 0)
3383 retval = -EINVAL;
3384 break;
3385 }
3386
3387 /* image properties */
3388 case VIDIOCGPICT:
3389 {
3390 struct video_picture *pic = arg;
3391 DBG("VIDIOCGPICT\n");
3392 *pic = cam->vp;
3393 break;
3394 }
3395
3396 case VIDIOCSPICT:
3397 {
3398 struct video_picture *vp = arg;
3399
3400 DBG("VIDIOCSPICT\n");
3401
3402 /* check validity */
3403 DBG("palette: %d\n", vp->palette);
3404 DBG("depth: %d\n", vp->depth);
3405 if (!valid_mode(vp->palette, vp->depth)) {
3406 retval = -EINVAL;
3407 break;
3408 }
3409
3410 mutex_lock(&cam->param_lock);
3411 /* brightness, colour, contrast need no check 0-65535 */
3412 cam->vp = *vp;
3413 /* update cam->params.colourParams */
3414 cam->params.colourParams.brightness = vp->brightness*100/65535;
3415 cam->params.colourParams.contrast = vp->contrast*100/65535;
3416 cam->params.colourParams.saturation = vp->colour*100/65535;
3417 /* contrast is in steps of 8, so round */
3418 cam->params.colourParams.contrast =
3419 ((cam->params.colourParams.contrast + 3) / 8) * 8;
3420 if (cam->params.version.firmwareVersion == 1 &&
3421 cam->params.version.firmwareRevision == 2 &&
3422 cam->params.colourParams.contrast > 80) {
3423 /* 1-02 firmware limits contrast to 80 */
3424 cam->params.colourParams.contrast = 80;
3425 }
3426
3427 /* Adjust flicker control if necessary */
3428 if(cam->params.flickerControl.allowableOverExposure < 0)
3429 cam->params.flickerControl.allowableOverExposure =
3430 -find_over_exposure(cam->params.colourParams.brightness);
3431 if(cam->params.flickerControl.flickerMode != 0)
3432 cam->cmd_queue |= COMMAND_SETFLICKERCTRL;
3433
3434
3435 /* queue command to update camera */
3436 cam->cmd_queue |= COMMAND_SETCOLOURPARAMS;
3437 mutex_unlock(&cam->param_lock);
3438 DBG("VIDIOCSPICT: %d / %d // %d / %d / %d / %d\n",
3439 vp->depth, vp->palette, vp->brightness, vp->hue, vp->colour,
3440 vp->contrast);
3441 break;
3442 }
3443
3444 /* get/set capture window */
3445 case VIDIOCGWIN:
3446 {
3447 struct video_window *vw = arg;
3448 DBG("VIDIOCGWIN\n");
3449
3450 *vw = cam->vw;
3451 break;
3452 }
3453
3454 case VIDIOCSWIN:
3455 {
3456 /* copy_from_user, check validity, copy to internal structure */
3457 struct video_window *vw = arg;
3458 DBG("VIDIOCSWIN\n");
3459
3460 if (vw->clipcount != 0) { /* clipping not supported */
3461 retval = -EINVAL;
3462 break;
3463 }
3464 if (vw->clips != NULL) { /* clipping not supported */
3465 retval = -EINVAL;
3466 break;
3467 }
3468
3469 /* we set the video window to something smaller or equal to what
3470 * is requested by the user???
3471 */
3472 mutex_lock(&cam->param_lock);
3473 if (vw->width != cam->vw.width || vw->height != cam->vw.height) {
3474 int video_size = match_videosize(vw->width, vw->height);
3475
3476 if (video_size < 0) {
3477 retval = -EINVAL;
3478 mutex_unlock(&cam->param_lock);
3479 break;
3480 }
3481 cam->video_size = video_size;
3482
3483 /* video size is changing, reset the subcapture area */
3484 memset(&cam->vc, 0, sizeof(cam->vc));
3485
3486 set_vw_size(cam);
3487 DBG("%d / %d\n", cam->vw.width, cam->vw.height);
3488 cam->cmd_queue |= COMMAND_SETFORMAT;
3489 }
3490
3491 mutex_unlock(&cam->param_lock);
3492
3493 /* setformat ignored by camera during streaming,
3494 * so stop/dispatch/start */
3495 if (cam->cmd_queue & COMMAND_SETFORMAT) {
3496 DBG("\n");
3497 dispatch_commands(cam);
3498 }
3499 DBG("%d/%d:%d\n", cam->video_size,
3500 cam->vw.width, cam->vw.height);
3501 break;
3502 }
3503
3504 /* mmap interface */
3505 case VIDIOCGMBUF:
3506 {
3507 struct video_mbuf *vm = arg;
3508 int i;
3509
3510 DBG("VIDIOCGMBUF\n");
3511 memset(vm, 0, sizeof(*vm));
3512 vm->size = CPIA_MAX_FRAME_SIZE*FRAME_NUM;
3513 vm->frames = FRAME_NUM;
3514 for (i = 0; i < FRAME_NUM; i++)
3515 vm->offsets[i] = CPIA_MAX_FRAME_SIZE * i;
3516 break;
3517 }
3518
3519 case VIDIOCMCAPTURE:
3520 {
3521 struct video_mmap *vm = arg;
3522 int video_size;
3523
3524 DBG("VIDIOCMCAPTURE: %d / %d / %dx%d\n", vm->format, vm->frame,
3525 vm->width, vm->height);
3526 if (vm->frame<0||vm->frame>=FRAME_NUM) {
3527 retval = -EINVAL;
3528 break;
3529 }
3530
3531 /* set video format */
3532 cam->vp.palette = vm->format;
3533 switch(vm->format) {
3534 case VIDEO_PALETTE_GREY:
3535 cam->vp.depth=8;
3536 break;
3537 case VIDEO_PALETTE_RGB555:
3538 case VIDEO_PALETTE_RGB565:
3539 case VIDEO_PALETTE_YUV422:
3540 case VIDEO_PALETTE_YUYV:
3541 case VIDEO_PALETTE_UYVY:
3542 cam->vp.depth = 16;
3543 break;
3544 case VIDEO_PALETTE_RGB24:
3545 cam->vp.depth = 24;
3546 break;
3547 case VIDEO_PALETTE_RGB32:
3548 cam->vp.depth = 32;
3549 break;
3550 default:
3551 retval = -EINVAL;
3552 break;
3553 }
3554 if (retval)
3555 break;
3556
3557 /* set video size */
3558 video_size = match_videosize(vm->width, vm->height);
3559 if (video_size < 0) {
3560 retval = -EINVAL;
3561 break;
3562 }
3563 if (video_size != cam->video_size) {
3564 cam->video_size = video_size;
3565
3566 /* video size is changing, reset the subcapture area */
3567 memset(&cam->vc, 0, sizeof(cam->vc));
3568
3569 set_vw_size(cam);
3570 cam->cmd_queue |= COMMAND_SETFORMAT;
3571 dispatch_commands(cam);
3572 }
3573 /* according to v4l-spec we must start streaming here */
3574 cam->mmap_kludge = 1;
3575 retval = capture_frame(cam, vm);
3576
3577 break;
3578 }
3579
3580 case VIDIOCSYNC:
3581 {
3582 int *frame = arg;
3583
3584 //DBG("VIDIOCSYNC: %d\n", *frame);
3585
3586 if (*frame<0 || *frame >= FRAME_NUM) {
3587 retval = -EINVAL;
3588 break;
3589 }
3590
3591 switch (cam->frame[*frame].state) {
3592 case FRAME_UNUSED:
3593 case FRAME_READY:
3594 case FRAME_GRABBING:
3595 DBG("sync to unused frame %d\n", *frame);
3596 retval = -EINVAL;
3597 break;
3598
3599 case FRAME_DONE:
3600 cam->frame[*frame].state = FRAME_UNUSED;
3601 //DBG("VIDIOCSYNC: %d synced\n", *frame);
3602 break;
3603 }
3604 if (retval == -EINTR) {
3605 /* FIXME - xawtv does not handle this nice */
3606 retval = 0;
3607 }
3608 break;
3609 }
3610
3611 case VIDIOCGCAPTURE:
3612 {
3613 struct video_capture *vc = arg;
3614
3615 DBG("VIDIOCGCAPTURE\n");
3616
3617 *vc = cam->vc;
3618
3619 break;
3620 }
3621
3622 case VIDIOCSCAPTURE:
3623 {
3624 struct video_capture *vc = arg;
3625
3626 DBG("VIDIOCSCAPTURE\n");
3627
3628 if (vc->decimation != 0) { /* How should this be used? */
3629 retval = -EINVAL;
3630 break;
3631 }
3632 if (vc->flags != 0) { /* Even/odd grab not supported */
3633 retval = -EINVAL;
3634 break;
3635 }
3636
3637 /* Clip to the resolution we can set for the ROI
3638 (every 8 columns and 4 rows) */
3639 vc->x = vc->x & ~(__u32)7;
3640 vc->y = vc->y & ~(__u32)3;
3641 vc->width = vc->width & ~(__u32)7;
3642 vc->height = vc->height & ~(__u32)3;
3643
3644 if(vc->width == 0 || vc->height == 0 ||
3645 vc->x + vc->width > cam->vw.width ||
3646 vc->y + vc->height > cam->vw.height) {
3647 retval = -EINVAL;
3648 break;
3649 }
3650
3651 DBG("%d,%d/%dx%d\n", vc->x,vc->y,vc->width, vc->height);
3652
3653 mutex_lock(&cam->param_lock);
3654
3655 cam->vc.x = vc->x;
3656 cam->vc.y = vc->y;
3657 cam->vc.width = vc->width;
3658 cam->vc.height = vc->height;
3659
3660 set_vw_size(cam);
3661 cam->cmd_queue |= COMMAND_SETFORMAT;
3662
3663 mutex_unlock(&cam->param_lock);
3664
3665 /* setformat ignored by camera during streaming,
3666 * so stop/dispatch/start */
3667 dispatch_commands(cam);
3668 break;
3669 }
3670
3671 case VIDIOCGUNIT:
3672 {
3673 struct video_unit *vu = arg;
3674
3675 DBG("VIDIOCGUNIT\n");
3676
3677 vu->video = cam->vdev.minor;
3678 vu->vbi = VIDEO_NO_UNIT;
3679 vu->radio = VIDEO_NO_UNIT;
3680 vu->audio = VIDEO_NO_UNIT;
3681 vu->teletext = VIDEO_NO_UNIT;
3682
3683 break;
3684 }
3685
3686
3687 /* pointless to implement overlay with this camera */
3688 case VIDIOCCAPTURE:
3689 case VIDIOCGFBUF:
3690 case VIDIOCSFBUF:
3691 case VIDIOCKEY:
3692 /* tuner interface - we have none */
3693 case VIDIOCGTUNER:
3694 case VIDIOCSTUNER:
3695 case VIDIOCGFREQ:
3696 case VIDIOCSFREQ:
3697 /* audio interface - we have none */
3698 case VIDIOCGAUDIO:
3699 case VIDIOCSAUDIO:
3700 retval = -EINVAL;
3701 break;
3702 default:
3703 retval = -ENOIOCTLCMD;
3704 break;
3705 }
3706
3707 mutex_unlock(&cam->busy_lock);
3708 return retval;
3709}
3710
3711static long cpia_ioctl(struct file *file,
3712 unsigned int cmd, unsigned long arg)
3713{
3714 return video_usercopy(file, cmd, arg, cpia_do_ioctl);
3715}
3716
3717
3718/* FIXME */
3719static int cpia_mmap(struct file *file, struct vm_area_struct *vma)
3720{
3721 struct video_device *dev = file->private_data;
3722 unsigned long start = vma->vm_start;
3723 unsigned long size = vma->vm_end - vma->vm_start;
3724 unsigned long page, pos;
3725 struct cam_data *cam = video_get_drvdata(dev);
3726 int retval;
3727
3728 if (!cam || !cam->ops)
3729 return -ENODEV;
3730
3731 DBG("cpia_mmap: %ld\n", size);
3732
3733 if (size > FRAME_NUM*CPIA_MAX_FRAME_SIZE)
3734 return -EINVAL;
3735
3736 /* make this _really_ smp-safe */
3737 if (mutex_lock_interruptible(&cam->busy_lock))
3738 return -EINTR;
3739
3740 if (!cam->frame_buf) { /* we do lazy allocation */
3741 if ((retval = allocate_frame_buf(cam))) {
3742 mutex_unlock(&cam->busy_lock);
3743 return retval;
3744 }
3745 }
3746
3747 pos = (unsigned long)(cam->frame_buf);
3748 while (size > 0) {
3749 page = vmalloc_to_pfn((void *)pos);
3750 if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) {
3751 mutex_unlock(&cam->busy_lock);
3752 return -EAGAIN;
3753 }
3754 start += PAGE_SIZE;
3755 pos += PAGE_SIZE;
3756 if (size > PAGE_SIZE)
3757 size -= PAGE_SIZE;
3758 else
3759 size = 0;
3760 }
3761
3762 DBG("cpia_mmap: %ld\n", size);
3763 mutex_unlock(&cam->busy_lock);
3764
3765 return 0;
3766}
3767
3768static const struct v4l2_file_operations cpia_fops = {
3769 .owner = THIS_MODULE,
3770 .open = cpia_open,
3771 .release = cpia_close,
3772 .read = cpia_read,
3773 .mmap = cpia_mmap,
3774 .ioctl = cpia_ioctl,
3775};
3776
3777static struct video_device cpia_template = {
3778 .name = "CPiA Camera",
3779 .fops = &cpia_fops,
3780 .release = video_device_release_empty,
3781};
3782
3783/* initialise cam_data structure */
3784static void reset_camera_struct(struct cam_data *cam)
3785{
3786 /* The following parameter values are the defaults from
3787 * "Software Developer's Guide for CPiA Cameras". Any changes
3788 * to the defaults are noted in comments. */
3789 cam->params.colourParams.brightness = 50;
3790 cam->params.colourParams.contrast = 48;
3791 cam->params.colourParams.saturation = 50;
3792 cam->params.exposure.gainMode = 4;
3793 cam->params.exposure.expMode = 2; /* AEC */
3794 cam->params.exposure.compMode = 1;
3795 cam->params.exposure.centreWeight = 1;
3796 cam->params.exposure.gain = 0;
3797 cam->params.exposure.fineExp = 0;
3798 cam->params.exposure.coarseExpLo = 185;
3799 cam->params.exposure.coarseExpHi = 0;
3800 cam->params.exposure.redComp = COMP_RED;
3801 cam->params.exposure.green1Comp = COMP_GREEN1;
3802 cam->params.exposure.green2Comp = COMP_GREEN2;
3803 cam->params.exposure.blueComp = COMP_BLUE;
3804 cam->params.colourBalance.balanceMode = 2; /* ACB */
3805 cam->params.colourBalance.redGain = 32;
3806 cam->params.colourBalance.greenGain = 6;
3807 cam->params.colourBalance.blueGain = 92;
3808 cam->params.apcor.gain1 = 0x18;
3809 cam->params.apcor.gain2 = 0x16;
3810 cam->params.apcor.gain4 = 0x24;
3811 cam->params.apcor.gain8 = 0x34;
3812 cam->params.flickerControl.flickerMode = 0;
3813 cam->params.flickerControl.disabled = 1;
3814
3815 cam->params.flickerControl.coarseJump =
3816 flicker_jumps[cam->mainsFreq]
3817 [cam->params.sensorFps.baserate]
3818 [cam->params.sensorFps.divisor];
3819 cam->params.flickerControl.allowableOverExposure =
3820 -find_over_exposure(cam->params.colourParams.brightness);
3821 cam->params.vlOffset.gain1 = 20;
3822 cam->params.vlOffset.gain2 = 24;
3823 cam->params.vlOffset.gain4 = 26;
3824 cam->params.vlOffset.gain8 = 26;
3825 cam->params.compressionParams.hysteresis = 3;
3826 cam->params.compressionParams.threshMax = 11;
3827 cam->params.compressionParams.smallStep = 1;
3828 cam->params.compressionParams.largeStep = 3;
3829 cam->params.compressionParams.decimationHysteresis = 2;
3830 cam->params.compressionParams.frDiffStepThresh = 5;
3831 cam->params.compressionParams.qDiffStepThresh = 3;
3832 cam->params.compressionParams.decimationThreshMod = 2;
3833 /* End of default values from Software Developer's Guide */
3834
3835 cam->transfer_rate = 0;
3836 cam->exposure_status = EXPOSURE_NORMAL;
3837
3838 /* Set Sensor FPS to 15fps. This seems better than 30fps
3839 * for indoor lighting. */
3840 cam->params.sensorFps.divisor = 1;
3841 cam->params.sensorFps.baserate = 1;
3842
3843 cam->params.yuvThreshold.yThreshold = 6; /* From windows driver */
3844 cam->params.yuvThreshold.uvThreshold = 6; /* From windows driver */
3845
3846 cam->params.format.subSample = SUBSAMPLE_422;
3847 cam->params.format.yuvOrder = YUVORDER_YUYV;
3848
3849 cam->params.compression.mode = CPIA_COMPRESSION_AUTO;
3850 cam->params.compressionTarget.frTargeting =
3851 CPIA_COMPRESSION_TARGET_QUALITY;
3852 cam->params.compressionTarget.targetFR = 15; /* From windows driver */
3853 cam->params.compressionTarget.targetQ = 5; /* From windows driver */
3854
3855 cam->params.qx3.qx3_detected = 0;
3856 cam->params.qx3.toplight = 0;
3857 cam->params.qx3.bottomlight = 0;
3858 cam->params.qx3.button = 0;
3859 cam->params.qx3.cradled = 0;
3860
3861 cam->video_size = VIDEOSIZE_CIF;
3862
3863 cam->vp.colour = 32768; /* 50% */
3864 cam->vp.hue = 32768; /* 50% */
3865 cam->vp.brightness = 32768; /* 50% */
3866 cam->vp.contrast = 32768; /* 50% */
3867 cam->vp.whiteness = 0; /* not used -> grayscale only */
3868 cam->vp.depth = 24; /* to be set by user */
3869 cam->vp.palette = VIDEO_PALETTE_RGB24; /* to be set by user */
3870
3871 cam->vc.x = 0;
3872 cam->vc.y = 0;
3873 cam->vc.width = 0;
3874 cam->vc.height = 0;
3875
3876 cam->vw.x = 0;
3877 cam->vw.y = 0;
3878 set_vw_size(cam);
3879 cam->vw.chromakey = 0;
3880 cam->vw.flags = 0;
3881 cam->vw.clipcount = 0;
3882 cam->vw.clips = NULL;
3883
3884 cam->cmd_queue = COMMAND_NONE;
3885 cam->first_frame = 1;
3886
3887 return;
3888}
3889
3890/* initialize cam_data structure */
3891static void init_camera_struct(struct cam_data *cam,
3892 struct cpia_camera_ops *ops )
3893{
3894 int i;
3895
3896 /* Default everything to 0 */
3897 memset(cam, 0, sizeof(struct cam_data));
3898
3899 cam->ops = ops;
3900 mutex_init(&cam->param_lock);
3901 mutex_init(&cam->busy_lock);
3902
3903 reset_camera_struct(cam);
3904
3905 cam->proc_entry = NULL;
3906
3907 memcpy(&cam->vdev, &cpia_template, sizeof(cpia_template));
3908 video_set_drvdata(&cam->vdev, cam);
3909
3910 cam->curframe = 0;
3911 for (i = 0; i < FRAME_NUM; i++) {
3912 cam->frame[i].width = 0;
3913 cam->frame[i].height = 0;
3914 cam->frame[i].state = FRAME_UNUSED;
3915 cam->frame[i].data = NULL;
3916 }
3917 cam->decompressed_frame.width = 0;
3918 cam->decompressed_frame.height = 0;
3919 cam->decompressed_frame.state = FRAME_UNUSED;
3920 cam->decompressed_frame.data = NULL;
3921}
3922
3923struct cam_data *cpia_register_camera(struct cpia_camera_ops *ops, void *lowlevel)
3924{
3925 struct cam_data *camera;
3926
3927 if ((camera = kmalloc(sizeof(struct cam_data), GFP_KERNEL)) == NULL)
3928 return NULL;
3929
3930
3931 init_camera_struct( camera, ops );
3932 camera->lowlevel_data = lowlevel;
3933
3934 /* register v4l device */
3935 if (video_register_device(&camera->vdev, VFL_TYPE_GRABBER, video_nr) < 0) {
3936 kfree(camera);
3937 printk(KERN_DEBUG "video_register_device failed\n");
3938 return NULL;
3939 }
3940
3941 /* get version information from camera: open/reset/close */
3942
3943 /* open cpia */
3944 if (camera->ops->open(camera->lowlevel_data))
3945 return camera;
3946
3947 /* reset the camera */
3948 if (reset_camera(camera) != 0) {
3949 camera->ops->close(camera->lowlevel_data);
3950 return camera;
3951 }
3952
3953 /* close cpia */
3954 camera->ops->close(camera->lowlevel_data);
3955
3956#ifdef CONFIG_PROC_FS
3957 create_proc_cpia_cam(camera);
3958#endif
3959
3960 printk(KERN_INFO " CPiA Version: %d.%02d (%d.%d)\n",
3961 camera->params.version.firmwareVersion,
3962 camera->params.version.firmwareRevision,
3963 camera->params.version.vcVersion,
3964 camera->params.version.vcRevision);
3965 printk(KERN_INFO " CPiA PnP-ID: %04x:%04x:%04x\n",
3966 camera->params.pnpID.vendor,
3967 camera->params.pnpID.product,
3968 camera->params.pnpID.deviceRevision);
3969 printk(KERN_INFO " VP-Version: %d.%d %04x\n",
3970 camera->params.vpVersion.vpVersion,
3971 camera->params.vpVersion.vpRevision,
3972 camera->params.vpVersion.cameraHeadID);
3973
3974 return camera;
3975}
3976
3977void cpia_unregister_camera(struct cam_data *cam)
3978{
3979 DBG("unregistering video\n");
3980 video_unregister_device(&cam->vdev);
3981 if (cam->open_count) {
3982 put_cam(cam->ops);
3983 DBG("camera open -- setting ops to NULL\n");
3984 cam->ops = NULL;
3985 }
3986
3987#ifdef CONFIG_PROC_FS
3988 DBG("destroying /proc/cpia/%s\n", video_device_node_name(&cam->vdev));
3989 destroy_proc_cpia_cam(cam);
3990#endif
3991 if (!cam->open_count) {
3992 DBG("freeing camera\n");
3993 kfree(cam);
3994 }
3995}
3996
3997static int __init cpia_init(void)
3998{
3999 printk(KERN_INFO "%s v%d.%d.%d\n", ABOUT,
4000 CPIA_MAJ_VER, CPIA_MIN_VER, CPIA_PATCH_VER);
4001
4002 printk(KERN_WARNING "Since in-kernel colorspace conversion is not "
4003 "allowed, it is disabled by default now. Users should fix the "
4004 "applications in case they don't work without conversion "
4005 "reenabled by setting the 'colorspace_conv' module "
4006 "parameter to 1\n");
4007
4008#ifdef CONFIG_PROC_FS
4009 proc_cpia_create();
4010#endif
4011
4012 return 0;
4013}
4014
4015static void __exit cpia_exit(void)
4016{
4017#ifdef CONFIG_PROC_FS
4018 proc_cpia_destroy();
4019#endif
4020}
4021
4022module_init(cpia_init);
4023module_exit(cpia_exit);
4024
4025/* Exported symbols for modules. */
4026
4027EXPORT_SYMBOL(cpia_register_camera);
4028EXPORT_SYMBOL(cpia_unregister_camera);
diff --git a/drivers/staging/cpia/cpia.h b/drivers/staging/cpia/cpia.h
deleted file mode 100644
index 8f0cfee4b8a1..000000000000
--- a/drivers/staging/cpia/cpia.h
+++ /dev/null
@@ -1,432 +0,0 @@
1#ifndef cpia_h
2#define cpia_h
3
4/*
5 * CPiA Parallel Port Video4Linux driver
6 *
7 * Supports CPiA based parallel port Video Camera's.
8 *
9 * (C) Copyright 1999 Bas Huisman,
10 * Peter Pregler,
11 * Scott J. Bertin,
12 * VLSI Vision Ltd.
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 */
28
29#define CPIA_MAJ_VER 1
30#define CPIA_MIN_VER 2
31#define CPIA_PATCH_VER 3
32
33#define CPIA_PP_MAJ_VER CPIA_MAJ_VER
34#define CPIA_PP_MIN_VER CPIA_MIN_VER
35#define CPIA_PP_PATCH_VER CPIA_PATCH_VER
36
37#define CPIA_USB_MAJ_VER CPIA_MAJ_VER
38#define CPIA_USB_MIN_VER CPIA_MIN_VER
39#define CPIA_USB_PATCH_VER CPIA_PATCH_VER
40
41#define CPIA_MAX_FRAME_SIZE_UNALIGNED (352 * 288 * 4) /* CIF at RGB32 */
42#define CPIA_MAX_FRAME_SIZE ((CPIA_MAX_FRAME_SIZE_UNALIGNED + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)) /* align above to PAGE_SIZE */
43
44#ifdef __KERNEL__
45
46#include <asm/uaccess.h>
47#include <linux/videodev.h>
48#include <media/v4l2-common.h>
49#include <media/v4l2-ioctl.h>
50#include <linux/list.h>
51#include <linux/mutex.h>
52
53struct cpia_camera_ops
54{
55 /* open sets privdata to point to structure for this camera.
56 * Returns negative value on error, otherwise 0.
57 */
58 int (*open)(void *privdata);
59
60 /* Registers callback function cb to be called with cbdata
61 * when an image is ready. If cb is NULL, only single image grabs
62 * should be used. cb should immediately call streamRead to read
63 * the data or data may be lost. Returns negative value on error,
64 * otherwise 0.
65 */
66 int (*registerCallback)(void *privdata, void (*cb)(void *cbdata),
67 void *cbdata);
68
69 /* transferCmd sends commands to the camera. command MUST point to
70 * an 8 byte buffer in kernel space. data can be NULL if no extra
71 * data is needed. The size of the data is given by the last 2
72 * bytes of command. data must also point to memory in kernel space.
73 * Returns negative value on error, otherwise 0.
74 */
75 int (*transferCmd)(void *privdata, u8 *command, u8 *data);
76
77 /* streamStart initiates stream capture mode.
78 * Returns negative value on error, otherwise 0.
79 */
80 int (*streamStart)(void *privdata);
81
82 /* streamStop terminates stream capture mode.
83 * Returns negative value on error, otherwise 0.
84 */
85 int (*streamStop)(void *privdata);
86
87 /* streamRead reads a frame from the camera. buffer points to a
88 * buffer large enough to hold a complete frame in kernel space.
89 * noblock indicates if this should be a non blocking read.
90 * Returns the number of bytes read, or negative value on error.
91 */
92 int (*streamRead)(void *privdata, u8 *buffer, int noblock);
93
94 /* close disables the device until open() is called again.
95 * Returns negative value on error, otherwise 0.
96 */
97 int (*close)(void *privdata);
98
99 /* If wait_for_stream_ready is non-zero, wait until the streamState
100 * is STREAM_READY before calling streamRead.
101 */
102 int wait_for_stream_ready;
103
104 /*
105 * Used to maintain lowlevel module usage counts
106 */
107 struct module *owner;
108};
109
110struct cpia_frame {
111 u8 *data;
112 int count;
113 int width;
114 int height;
115 volatile int state;
116};
117
118struct cam_params {
119 struct {
120 u8 firmwareVersion;
121 u8 firmwareRevision;
122 u8 vcVersion;
123 u8 vcRevision;
124 } version;
125 struct {
126 u16 vendor;
127 u16 product;
128 u16 deviceRevision;
129 } pnpID;
130 struct {
131 u8 vpVersion;
132 u8 vpRevision;
133 u16 cameraHeadID;
134 } vpVersion;
135 struct {
136 u8 systemState;
137 u8 grabState;
138 u8 streamState;
139 u8 fatalError;
140 u8 cmdError;
141 u8 debugFlags;
142 u8 vpStatus;
143 u8 errorCode;
144 } status;
145 struct {
146 u8 brightness;
147 u8 contrast;
148 u8 saturation;
149 } colourParams;
150 struct {
151 u8 gainMode;
152 u8 expMode;
153 u8 compMode;
154 u8 centreWeight;
155 u8 gain;
156 u8 fineExp;
157 u8 coarseExpLo;
158 u8 coarseExpHi;
159 u8 redComp;
160 u8 green1Comp;
161 u8 green2Comp;
162 u8 blueComp;
163 } exposure;
164 struct {
165 u8 balanceMode;
166 u8 redGain;
167 u8 greenGain;
168 u8 blueGain;
169 } colourBalance;
170 struct {
171 u8 divisor;
172 u8 baserate;
173 } sensorFps;
174 struct {
175 u8 gain1;
176 u8 gain2;
177 u8 gain4;
178 u8 gain8;
179 } apcor;
180 struct {
181 u8 disabled;
182 u8 flickerMode;
183 u8 coarseJump;
184 int allowableOverExposure;
185 } flickerControl;
186 struct {
187 u8 gain1;
188 u8 gain2;
189 u8 gain4;
190 u8 gain8;
191 } vlOffset;
192 struct {
193 u8 mode;
194 u8 decimation;
195 } compression;
196 struct {
197 u8 frTargeting;
198 u8 targetFR;
199 u8 targetQ;
200 } compressionTarget;
201 struct {
202 u8 yThreshold;
203 u8 uvThreshold;
204 } yuvThreshold;
205 struct {
206 u8 hysteresis;
207 u8 threshMax;
208 u8 smallStep;
209 u8 largeStep;
210 u8 decimationHysteresis;
211 u8 frDiffStepThresh;
212 u8 qDiffStepThresh;
213 u8 decimationThreshMod;
214 } compressionParams;
215 struct {
216 u8 videoSize; /* CIF/QCIF */
217 u8 subSample;
218 u8 yuvOrder;
219 } format;
220 struct { /* Intel QX3 specific data */
221 u8 qx3_detected; /* a QX3 is present */
222 u8 toplight; /* top light lit , R/W */
223 u8 bottomlight; /* bottom light lit, R/W */
224 u8 button; /* snapshot button pressed (R/O) */
225 u8 cradled; /* microscope is in cradle (R/O) */
226 } qx3;
227 struct {
228 u8 colStart; /* skip first 8*colStart pixels */
229 u8 colEnd; /* finish at 8*colEnd pixels */
230 u8 rowStart; /* skip first 4*rowStart lines */
231 u8 rowEnd; /* finish at 4*rowEnd lines */
232 } roi;
233 u8 ecpTiming;
234 u8 streamStartLine;
235};
236
237enum v4l_camstates {
238 CPIA_V4L_IDLE = 0,
239 CPIA_V4L_ERROR,
240 CPIA_V4L_COMMAND,
241 CPIA_V4L_GRABBING,
242 CPIA_V4L_STREAMING,
243 CPIA_V4L_STREAMING_PAUSED,
244};
245
246#define FRAME_NUM 2 /* double buffering for now */
247
248struct cam_data {
249 struct list_head cam_data_list;
250
251 struct mutex busy_lock; /* guard against SMP multithreading */
252 struct cpia_camera_ops *ops; /* lowlevel driver operations */
253 void *lowlevel_data; /* private data for lowlevel driver */
254 u8 *raw_image; /* buffer for raw image data */
255 struct cpia_frame decompressed_frame;
256 /* buffer to hold decompressed frame */
257 int image_size; /* sizeof last decompressed image */
258 int open_count; /* # of process that have camera open */
259
260 /* camera status */
261 int fps; /* actual fps reported by the camera */
262 int transfer_rate; /* transfer rate from camera in kB/s */
263 u8 mainsFreq; /* for flicker control */
264
265 /* proc interface */
266 struct mutex param_lock; /* params lock for this camera */
267 struct cam_params params; /* camera settings */
268 struct proc_dir_entry *proc_entry; /* /proc/cpia/videoX */
269
270 /* v4l */
271 int video_size; /* VIDEO_SIZE_ */
272 volatile enum v4l_camstates camstate; /* v4l layer status */
273 struct video_device vdev; /* v4l videodev */
274 struct video_picture vp; /* v4l camera settings */
275 struct video_window vw; /* v4l capture area */
276 struct video_capture vc; /* v4l subcapture area */
277
278 /* mmap interface */
279 int curframe; /* the current frame to grab into */
280 u8 *frame_buf; /* frame buffer data */
281 struct cpia_frame frame[FRAME_NUM];
282 /* FRAME_NUM-buffering, so we need a array */
283
284 int first_frame;
285 int mmap_kludge; /* 'wrong' byte order for mmap */
286 volatile u32 cmd_queue; /* queued commands */
287 int exposure_status; /* EXPOSURE_* */
288 int exposure_count; /* number of frames at this status */
289};
290
291/* cpia_register_camera is called by low level driver for each camera.
292 * A unique camera number is returned, or a negative value on error */
293struct cam_data *cpia_register_camera(struct cpia_camera_ops *ops, void *lowlevel);
294
295/* cpia_unregister_camera is called by low level driver when a camera
296 * is removed. This must not fail. */
297void cpia_unregister_camera(struct cam_data *cam);
298
299/* raw CIF + 64 byte header + (2 bytes line_length + EOL) per line + 4*EOI +
300 * one byte 16bit DMA alignment
301 */
302#define CPIA_MAX_IMAGE_SIZE ((352*288*2)+64+(288*3)+5)
303
304/* constant value's */
305#define MAGIC_0 0x19
306#define MAGIC_1 0x68
307#define DATA_IN 0xC0
308#define DATA_OUT 0x40
309#define VIDEOSIZE_QCIF 0 /* 176x144 */
310#define VIDEOSIZE_CIF 1 /* 352x288 */
311#define VIDEOSIZE_SIF 2 /* 320x240 */
312#define VIDEOSIZE_QSIF 3 /* 160x120 */
313#define VIDEOSIZE_48_48 4 /* where no one has gone before, iconsize! */
314#define VIDEOSIZE_64_48 5
315#define VIDEOSIZE_128_96 6
316#define VIDEOSIZE_160_120 VIDEOSIZE_QSIF
317#define VIDEOSIZE_176_144 VIDEOSIZE_QCIF
318#define VIDEOSIZE_192_144 7
319#define VIDEOSIZE_224_168 8
320#define VIDEOSIZE_256_192 9
321#define VIDEOSIZE_288_216 10
322#define VIDEOSIZE_320_240 VIDEOSIZE_SIF
323#define VIDEOSIZE_352_288 VIDEOSIZE_CIF
324#define VIDEOSIZE_88_72 11 /* quarter CIF */
325#define SUBSAMPLE_420 0
326#define SUBSAMPLE_422 1
327#define YUVORDER_YUYV 0
328#define YUVORDER_UYVY 1
329#define NOT_COMPRESSED 0
330#define COMPRESSED 1
331#define NO_DECIMATION 0
332#define DECIMATION_ENAB 1
333#define EOI 0xff /* End Of Image */
334#define EOL 0xfd /* End Of Line */
335#define FRAME_HEADER_SIZE 64
336
337/* Image grab modes */
338#define CPIA_GRAB_SINGLE 0
339#define CPIA_GRAB_CONTINUOUS 1
340
341/* Compression parameters */
342#define CPIA_COMPRESSION_NONE 0
343#define CPIA_COMPRESSION_AUTO 1
344#define CPIA_COMPRESSION_MANUAL 2
345#define CPIA_COMPRESSION_TARGET_QUALITY 0
346#define CPIA_COMPRESSION_TARGET_FRAMERATE 1
347
348/* Return offsets for GetCameraState */
349#define SYSTEMSTATE 0
350#define GRABSTATE 1
351#define STREAMSTATE 2
352#define FATALERROR 3
353#define CMDERROR 4
354#define DEBUGFLAGS 5
355#define VPSTATUS 6
356#define ERRORCODE 7
357
358/* SystemState */
359#define UNINITIALISED_STATE 0
360#define PASS_THROUGH_STATE 1
361#define LO_POWER_STATE 2
362#define HI_POWER_STATE 3
363#define WARM_BOOT_STATE 4
364
365/* GrabState */
366#define GRAB_IDLE 0
367#define GRAB_ACTIVE 1
368#define GRAB_DONE 2
369
370/* StreamState */
371#define STREAM_NOT_READY 0
372#define STREAM_READY 1
373#define STREAM_OPEN 2
374#define STREAM_PAUSED 3
375#define STREAM_FINISHED 4
376
377/* Fatal Error, CmdError, and DebugFlags */
378#define CPIA_FLAG 1
379#define SYSTEM_FLAG 2
380#define INT_CTRL_FLAG 4
381#define PROCESS_FLAG 8
382#define COM_FLAG 16
383#define VP_CTRL_FLAG 32
384#define CAPTURE_FLAG 64
385#define DEBUG_FLAG 128
386
387/* VPStatus */
388#define VP_STATE_OK 0x00
389
390#define VP_STATE_FAILED_VIDEOINIT 0x01
391#define VP_STATE_FAILED_AECACBINIT 0x02
392#define VP_STATE_AEC_MAX 0x04
393#define VP_STATE_ACB_BMAX 0x08
394
395#define VP_STATE_ACB_RMIN 0x10
396#define VP_STATE_ACB_GMIN 0x20
397#define VP_STATE_ACB_RMAX 0x40
398#define VP_STATE_ACB_GMAX 0x80
399
400/* default (minimum) compensation values */
401#define COMP_RED 220
402#define COMP_GREEN1 214
403#define COMP_GREEN2 COMP_GREEN1
404#define COMP_BLUE 230
405
406/* exposure status */
407#define EXPOSURE_VERY_LIGHT 0
408#define EXPOSURE_LIGHT 1
409#define EXPOSURE_NORMAL 2
410#define EXPOSURE_DARK 3
411#define EXPOSURE_VERY_DARK 4
412
413/* ErrorCode */
414#define ERROR_FLICKER_BELOW_MIN_EXP 0x01 /*flicker exposure got below minimum exposure */
415#define ALOG(fmt,args...) printk(fmt, ##args)
416#define LOG(fmt,args...) ALOG(KERN_INFO __FILE__ ":%s(%d):" fmt, __func__ , __LINE__ , ##args)
417
418#ifdef _CPIA_DEBUG_
419#define ADBG(fmt,args...) printk(fmt, jiffies, ##args)
420#define DBG(fmt,args...) ADBG(KERN_DEBUG __FILE__" (%ld):%s(%d):" fmt, __func__, __LINE__ , ##args)
421#else
422#define DBG(fmn,args...) do {} while(0)
423#endif
424
425#define DEB_BYTE(p)\
426 DBG("%1d %1d %1d %1d %1d %1d %1d %1d \n",\
427 (p)&0x80?1:0, (p)&0x40?1:0, (p)&0x20?1:0, (p)&0x10?1:0,\
428 (p)&0x08?1:0, (p)&0x04?1:0, (p)&0x02?1:0, (p)&0x01?1:0);
429
430#endif /* __KERNEL__ */
431
432#endif /* cpia_h */
diff --git a/drivers/staging/cpia/cpia_pp.c b/drivers/staging/cpia/cpia_pp.c
deleted file mode 100644
index f5604c16a092..000000000000
--- a/drivers/staging/cpia/cpia_pp.c
+++ /dev/null
@@ -1,869 +0,0 @@
1/*
2 * cpia_pp CPiA Parallel Port driver
3 *
4 * Supports CPiA based parallel port Video Camera's.
5 *
6 * (C) Copyright 1999 Bas Huisman <bhuism@cs.utwente.nl>
7 * (C) Copyright 1999-2000 Scott J. Bertin <sbertin@securenym.net>,
8 * (C) Copyright 1999-2000 Peter Pregler <Peter_Pregler@email.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 */
24
25/* define _CPIA_DEBUG_ for verbose debug output (see cpia.h) */
26/* #define _CPIA_DEBUG_ 1 */
27
28
29#include <linux/module.h>
30#include <linux/init.h>
31
32#include <linux/kernel.h>
33#include <linux/parport.h>
34#include <linux/interrupt.h>
35#include <linux/delay.h>
36#include <linux/workqueue.h>
37#include <linux/sched.h>
38#include <linux/slab.h>
39
40#include <linux/kmod.h>
41
42/* #define _CPIA_DEBUG_ define for verbose debug output */
43#include "cpia.h"
44
45static int cpia_pp_open(void *privdata);
46static int cpia_pp_registerCallback(void *privdata, void (*cb) (void *cbdata),
47 void *cbdata);
48static int cpia_pp_transferCmd(void *privdata, u8 *command, u8 *data);
49static int cpia_pp_streamStart(void *privdata);
50static int cpia_pp_streamStop(void *privdata);
51static int cpia_pp_streamRead(void *privdata, u8 *buffer, int noblock);
52static int cpia_pp_close(void *privdata);
53
54
55#define ABOUT "Parallel port driver for Vision CPiA based cameras"
56
57#define PACKET_LENGTH 8
58
59/* Magic numbers for defining port-device mappings */
60#define PPCPIA_PARPORT_UNSPEC -4
61#define PPCPIA_PARPORT_AUTO -3
62#define PPCPIA_PARPORT_OFF -2
63#define PPCPIA_PARPORT_NONE -1
64
65static int parport_nr[PARPORT_MAX] = {[0 ... PARPORT_MAX - 1] = PPCPIA_PARPORT_UNSPEC};
66static char *parport[PARPORT_MAX] = {NULL,};
67
68MODULE_AUTHOR("B. Huisman <bhuism@cs.utwente.nl> & Peter Pregler <Peter_Pregler@email.com>");
69MODULE_DESCRIPTION("Parallel port driver for Vision CPiA based cameras");
70MODULE_LICENSE("GPL");
71
72module_param_array(parport, charp, NULL, 0);
73MODULE_PARM_DESC(parport, "'auto' or a list of parallel port numbers. Just like lp.");
74
75struct pp_cam_entry {
76 struct pardevice *pdev;
77 struct parport *port;
78 struct work_struct cb_task;
79 void (*cb_func)(void *cbdata);
80 void *cb_data;
81 int open_count;
82 wait_queue_head_t wq_stream;
83 /* image state flags */
84 int image_ready; /* we got an interrupt */
85 int image_complete; /* we have seen 4 EOI */
86
87 int streaming; /* we are in streaming mode */
88 int stream_irq;
89};
90
91static struct cpia_camera_ops cpia_pp_ops =
92{
93 cpia_pp_open,
94 cpia_pp_registerCallback,
95 cpia_pp_transferCmd,
96 cpia_pp_streamStart,
97 cpia_pp_streamStop,
98 cpia_pp_streamRead,
99 cpia_pp_close,
100 1,
101 THIS_MODULE
102};
103
104static LIST_HEAD(cam_list);
105static spinlock_t cam_list_lock_pp;
106
107/* FIXME */
108static void cpia_parport_enable_irq( struct parport *port ) {
109 parport_enable_irq(port);
110 mdelay(10);
111 return;
112}
113
114static void cpia_parport_disable_irq( struct parport *port ) {
115 parport_disable_irq(port);
116 mdelay(10);
117 return;
118}
119
120/* Special CPiA PPC modes: These are invoked by using the 1284 Extensibility
121 * Link Flag during negotiation */
122#define UPLOAD_FLAG 0x08
123#define NIBBLE_TRANSFER 0x01
124#define ECP_TRANSFER 0x03
125
126#define PARPORT_CHUNK_SIZE PAGE_SIZE
127
128
129static void cpia_pp_run_callback(struct work_struct *work)
130{
131 void (*cb_func)(void *cbdata);
132 void *cb_data;
133 struct pp_cam_entry *cam;
134
135 cam = container_of(work, struct pp_cam_entry, cb_task);
136 cb_func = cam->cb_func;
137 cb_data = cam->cb_data;
138
139 cb_func(cb_data);
140}
141
142/****************************************************************************
143 *
144 * CPiA-specific low-level parport functions for nibble uploads
145 *
146 ***************************************************************************/
147/* CPiA nonstandard "Nibble" mode (no nDataAvail signal after each byte). */
148/* The standard kernel parport_ieee1284_read_nibble() fails with the CPiA... */
149
150static size_t cpia_read_nibble (struct parport *port,
151 void *buffer, size_t len,
152 int flags)
153{
154 /* adapted verbatim, with one change, from
155 parport_ieee1284_read_nibble() in drivers/parport/ieee1284-ops.c */
156
157 unsigned char *buf = buffer;
158 int i;
159 unsigned char byte = 0;
160
161 len *= 2; /* in nibbles */
162 for (i=0; i < len; i++) {
163 unsigned char nibble;
164
165 /* The CPiA firmware suppresses the use of nDataAvail (nFault LO)
166 * after every second nibble to signal that more
167 * data is available. (the total number of Bytes that
168 * should be sent is known; if too few are received, an error
169 * will be recorded after a timeout).
170 * This is incompatible with parport_ieee1284_read_nibble(),
171 * which expects to find nFault LO after every second nibble.
172 */
173
174 /* Solution: modify cpia_read_nibble to only check for
175 * nDataAvail before the first nibble is sent.
176 */
177
178 /* Does the error line indicate end of data? */
179 if (((i /*& 1*/) == 0) &&
180 (parport_read_status(port) & PARPORT_STATUS_ERROR)) {
181 DBG("%s: No more nibble data (%d bytes)\n",
182 port->name, i/2);
183 goto end_of_data;
184 }
185
186 /* Event 7: Set nAutoFd low. */
187 parport_frob_control (port,
188 PARPORT_CONTROL_AUTOFD,
189 PARPORT_CONTROL_AUTOFD);
190
191 /* Event 9: nAck goes low. */
192 port->ieee1284.phase = IEEE1284_PH_REV_DATA;
193 if (parport_wait_peripheral (port,
194 PARPORT_STATUS_ACK, 0)) {
195 /* Timeout -- no more data? */
196 DBG("%s: Nibble timeout at event 9 (%d bytes)\n",
197 port->name, i/2);
198 parport_frob_control (port, PARPORT_CONTROL_AUTOFD, 0);
199 break;
200 }
201
202
203 /* Read a nibble. */
204 nibble = parport_read_status (port) >> 3;
205 nibble &= ~8;
206 if ((nibble & 0x10) == 0)
207 nibble |= 8;
208 nibble &= 0xf;
209
210 /* Event 10: Set nAutoFd high. */
211 parport_frob_control (port, PARPORT_CONTROL_AUTOFD, 0);
212
213 /* Event 11: nAck goes high. */
214 if (parport_wait_peripheral (port,
215 PARPORT_STATUS_ACK,
216 PARPORT_STATUS_ACK)) {
217 /* Timeout -- no more data? */
218 DBG("%s: Nibble timeout at event 11\n",
219 port->name);
220 break;
221 }
222
223 if (i & 1) {
224 /* Second nibble */
225 byte |= nibble << 4;
226 *buf++ = byte;
227 } else
228 byte = nibble;
229 }
230
231 if (i == len) {
232 /* Read the last nibble without checking data avail. */
233 if (parport_read_status (port) & PARPORT_STATUS_ERROR) {
234 end_of_data:
235 /* Go to reverse idle phase. */
236 parport_frob_control (port,
237 PARPORT_CONTROL_AUTOFD,
238 PARPORT_CONTROL_AUTOFD);
239 port->physport->ieee1284.phase = IEEE1284_PH_REV_IDLE;
240 }
241 else
242 port->physport->ieee1284.phase = IEEE1284_PH_HBUSY_DAVAIL;
243 }
244
245 return i/2;
246}
247
248/* CPiA nonstandard "Nibble Stream" mode (2 nibbles per cycle, instead of 1)
249 * (See CPiA Data sheet p. 31)
250 *
251 * "Nibble Stream" mode used by CPiA for uploads to non-ECP ports is a
252 * nonstandard variant of nibble mode which allows the same (mediocre)
253 * data flow of 8 bits per cycle as software-enabled ECP by TRISTATE-capable
254 * parallel ports, but works also for non-TRISTATE-capable ports.
255 * (Standard nibble mode only send 4 bits per cycle)
256 *
257 */
258
259static size_t cpia_read_nibble_stream(struct parport *port,
260 void *buffer, size_t len,
261 int flags)
262{
263 int i;
264 unsigned char *buf = buffer;
265 int endseen = 0;
266
267 for (i=0; i < len; i++) {
268 unsigned char nibble[2], byte = 0;
269 int j;
270
271 /* Image Data is complete when 4 consecutive EOI bytes (0xff) are seen */
272 if (endseen > 3 )
273 break;
274
275 /* Event 7: Set nAutoFd low. */
276 parport_frob_control (port,
277 PARPORT_CONTROL_AUTOFD,
278 PARPORT_CONTROL_AUTOFD);
279
280 /* Event 9: nAck goes low. */
281 port->ieee1284.phase = IEEE1284_PH_REV_DATA;
282 if (parport_wait_peripheral (port,
283 PARPORT_STATUS_ACK, 0)) {
284 /* Timeout -- no more data? */
285 DBG("%s: Nibble timeout at event 9 (%d bytes)\n",
286 port->name, i/2);
287 parport_frob_control (port, PARPORT_CONTROL_AUTOFD, 0);
288 break;
289 }
290
291 /* Read lower nibble */
292 nibble[0] = parport_read_status (port) >>3;
293
294 /* Event 10: Set nAutoFd high. */
295 parport_frob_control (port, PARPORT_CONTROL_AUTOFD, 0);
296
297 /* Event 11: nAck goes high. */
298 if (parport_wait_peripheral (port,
299 PARPORT_STATUS_ACK,
300 PARPORT_STATUS_ACK)) {
301 /* Timeout -- no more data? */
302 DBG("%s: Nibble timeout at event 11\n",
303 port->name);
304 break;
305 }
306
307 /* Read upper nibble */
308 nibble[1] = parport_read_status (port) >>3;
309
310 /* reassemble the byte */
311 for (j = 0; j < 2 ; j++ ) {
312 nibble[j] &= ~8;
313 if ((nibble[j] & 0x10) == 0)
314 nibble[j] |= 8;
315 nibble[j] &= 0xf;
316 }
317 byte = (nibble[0] |(nibble[1] << 4));
318 *buf++ = byte;
319
320 if(byte == EOI)
321 endseen++;
322 else
323 endseen = 0;
324 }
325 return i;
326}
327
328/****************************************************************************
329 *
330 * EndTransferMode
331 *
332 ***************************************************************************/
333static void EndTransferMode(struct pp_cam_entry *cam)
334{
335 parport_negotiate(cam->port, IEEE1284_MODE_COMPAT);
336}
337
338/****************************************************************************
339 *
340 * ForwardSetup
341 *
342 ***************************************************************************/
343static int ForwardSetup(struct pp_cam_entry *cam)
344{
345 int retry;
346
347 /* The CPiA uses ECP protocol for Downloads from the Host to the camera.
348 * This will be software-emulated if ECP hardware is not present
349 */
350
351 /* the usual camera maximum response time is 10ms, but after receiving
352 * some commands, it needs up to 40ms. (Data Sheet p. 32)*/
353
354 for(retry = 0; retry < 4; ++retry) {
355 if(!parport_negotiate(cam->port, IEEE1284_MODE_ECP)) {
356 break;
357 }
358 mdelay(10);
359 }
360 if(retry == 4) {
361 DBG("Unable to negotiate IEEE1284 ECP Download mode\n");
362 return -1;
363 }
364 return 0;
365}
366/****************************************************************************
367 *
368 * ReverseSetup
369 *
370 ***************************************************************************/
371static int ReverseSetup(struct pp_cam_entry *cam, int extensibility)
372{
373 int retry;
374 int upload_mode, mode = IEEE1284_MODE_ECP;
375 int transfer_mode = ECP_TRANSFER;
376
377 if (!(cam->port->modes & PARPORT_MODE_ECP) &&
378 !(cam->port->modes & PARPORT_MODE_TRISTATE)) {
379 mode = IEEE1284_MODE_NIBBLE;
380 transfer_mode = NIBBLE_TRANSFER;
381 }
382
383 upload_mode = mode;
384 if(extensibility) mode = UPLOAD_FLAG|transfer_mode|IEEE1284_EXT_LINK;
385
386 /* the usual camera maximum response time is 10ms, but after
387 * receiving some commands, it needs up to 40ms. */
388
389 for(retry = 0; retry < 4; ++retry) {
390 if(!parport_negotiate(cam->port, mode)) {
391 break;
392 }
393 mdelay(10);
394 }
395 if(retry == 4) {
396 if(extensibility)
397 DBG("Unable to negotiate upload extensibility mode\n");
398 else
399 DBG("Unable to negotiate upload mode\n");
400 return -1;
401 }
402 if(extensibility) cam->port->ieee1284.mode = upload_mode;
403 return 0;
404}
405
406/****************************************************************************
407 *
408 * WritePacket
409 *
410 ***************************************************************************/
411static int WritePacket(struct pp_cam_entry *cam, const u8 *packet, size_t size)
412{
413 int retval=0;
414 int size_written;
415
416 if (packet == NULL) {
417 return -EINVAL;
418 }
419 if (ForwardSetup(cam)) {
420 DBG("Write failed in setup\n");
421 return -EIO;
422 }
423 size_written = parport_write(cam->port, packet, size);
424 if(size_written != size) {
425 DBG("Write failed, wrote %d/%d\n", size_written, size);
426 retval = -EIO;
427 }
428 EndTransferMode(cam);
429 return retval;
430}
431
432/****************************************************************************
433 *
434 * ReadPacket
435 *
436 ***************************************************************************/
437static int ReadPacket(struct pp_cam_entry *cam, u8 *packet, size_t size)
438{
439 int retval=0;
440
441 if (packet == NULL) {
442 return -EINVAL;
443 }
444 if (ReverseSetup(cam, 0)) {
445 return -EIO;
446 }
447
448 /* support for CPiA variant nibble reads */
449 if(cam->port->ieee1284.mode == IEEE1284_MODE_NIBBLE) {
450 if(cpia_read_nibble(cam->port, packet, size, 0) != size)
451 retval = -EIO;
452 } else {
453 if(parport_read(cam->port, packet, size) != size)
454 retval = -EIO;
455 }
456 EndTransferMode(cam);
457 return retval;
458}
459
460/****************************************************************************
461 *
462 * cpia_pp_streamStart
463 *
464 ***************************************************************************/
465static int cpia_pp_streamStart(void *privdata)
466{
467 struct pp_cam_entry *cam = privdata;
468 DBG("\n");
469 cam->streaming=1;
470 cam->image_ready=0;
471 //if (ReverseSetup(cam,1)) return -EIO;
472 if(cam->stream_irq) cpia_parport_enable_irq(cam->port);
473 return 0;
474}
475
476/****************************************************************************
477 *
478 * cpia_pp_streamStop
479 *
480 ***************************************************************************/
481static int cpia_pp_streamStop(void *privdata)
482{
483 struct pp_cam_entry *cam = privdata;
484
485 DBG("\n");
486 cam->streaming=0;
487 cpia_parport_disable_irq(cam->port);
488 //EndTransferMode(cam);
489
490 return 0;
491}
492
493/****************************************************************************
494 *
495 * cpia_pp_streamRead
496 *
497 ***************************************************************************/
498static int cpia_pp_read(struct parport *port, u8 *buffer, int len)
499{
500 int bytes_read;
501
502 /* support for CPiA variant "nibble stream" reads */
503 if(port->ieee1284.mode == IEEE1284_MODE_NIBBLE)
504 bytes_read = cpia_read_nibble_stream(port,buffer,len,0);
505 else {
506 int new_bytes;
507 for(bytes_read=0; bytes_read<len; bytes_read += new_bytes) {
508 new_bytes = parport_read(port, buffer+bytes_read,
509 len-bytes_read);
510 if(new_bytes < 0) break;
511 }
512 }
513 return bytes_read;
514}
515
516static int cpia_pp_streamRead(void *privdata, u8 *buffer, int noblock)
517{
518 struct pp_cam_entry *cam = privdata;
519 int read_bytes = 0;
520 int i, endseen, block_size, new_bytes;
521
522 if(cam == NULL) {
523 DBG("Internal driver error: cam is NULL\n");
524 return -EINVAL;
525 }
526 if(buffer == NULL) {
527 DBG("Internal driver error: buffer is NULL\n");
528 return -EINVAL;
529 }
530 //if(cam->streaming) DBG("%d / %d\n", cam->image_ready, noblock);
531 if( cam->stream_irq ) {
532 DBG("%d\n", cam->image_ready);
533 cam->image_ready--;
534 }
535 cam->image_complete=0;
536 if (0/*cam->streaming*/) {
537 if(!cam->image_ready) {
538 if(noblock) return -EWOULDBLOCK;
539 interruptible_sleep_on(&cam->wq_stream);
540 if( signal_pending(current) ) return -EINTR;
541 DBG("%d\n", cam->image_ready);
542 }
543 } else {
544 if (ReverseSetup(cam, 1)) {
545 DBG("unable to ReverseSetup\n");
546 return -EIO;
547 }
548 }
549 endseen = 0;
550 block_size = PARPORT_CHUNK_SIZE;
551 while( !cam->image_complete ) {
552 cond_resched();
553
554 new_bytes = cpia_pp_read(cam->port, buffer, block_size );
555 if( new_bytes <= 0 ) {
556 break;
557 }
558 i=-1;
559 while(++i<new_bytes && endseen<4) {
560 if(*buffer==EOI) {
561 endseen++;
562 } else {
563 endseen=0;
564 }
565 buffer++;
566 }
567 read_bytes += i;
568 if( endseen==4 ) {
569 cam->image_complete=1;
570 break;
571 }
572 if( CPIA_MAX_IMAGE_SIZE-read_bytes <= PARPORT_CHUNK_SIZE ) {
573 block_size=CPIA_MAX_IMAGE_SIZE-read_bytes;
574 }
575 }
576 EndTransferMode(cam);
577 return cam->image_complete ? read_bytes : -EIO;
578}
579/****************************************************************************
580 *
581 * cpia_pp_transferCmd
582 *
583 ***************************************************************************/
584static int cpia_pp_transferCmd(void *privdata, u8 *command, u8 *data)
585{
586 int err;
587 int retval=0;
588 int databytes;
589 struct pp_cam_entry *cam = privdata;
590
591 if(cam == NULL) {
592 DBG("Internal driver error: cam is NULL\n");
593 return -EINVAL;
594 }
595 if(command == NULL) {
596 DBG("Internal driver error: command is NULL\n");
597 return -EINVAL;
598 }
599 databytes = (((int)command[7])<<8) | command[6];
600 if ((err = WritePacket(cam, command, PACKET_LENGTH)) < 0) {
601 DBG("Error writing command\n");
602 return err;
603 }
604 if(command[0] == DATA_IN) {
605 u8 buffer[8];
606 if(data == NULL) {
607 DBG("Internal driver error: data is NULL\n");
608 return -EINVAL;
609 }
610 if((err = ReadPacket(cam, buffer, 8)) < 0) {
611 DBG("Error reading command result\n");
612 return err;
613 }
614 memcpy(data, buffer, databytes);
615 } else if(command[0] == DATA_OUT) {
616 if(databytes > 0) {
617 if(data == NULL) {
618 DBG("Internal driver error: data is NULL\n");
619 retval = -EINVAL;
620 } else {
621 if((err=WritePacket(cam, data, databytes)) < 0){
622 DBG("Error writing command data\n");
623 return err;
624 }
625 }
626 }
627 } else {
628 DBG("Unexpected first byte of command: %x\n", command[0]);
629 retval = -EINVAL;
630 }
631 return retval;
632}
633
634/****************************************************************************
635 *
636 * cpia_pp_open
637 *
638 ***************************************************************************/
639static int cpia_pp_open(void *privdata)
640{
641 struct pp_cam_entry *cam = (struct pp_cam_entry *)privdata;
642
643 if (cam == NULL)
644 return -EINVAL;
645
646 if(cam->open_count == 0) {
647 if (parport_claim(cam->pdev)) {
648 DBG("failed to claim the port\n");
649 return -EBUSY;
650 }
651 parport_negotiate(cam->port, IEEE1284_MODE_COMPAT);
652 parport_data_forward(cam->port);
653 parport_write_control(cam->port, PARPORT_CONTROL_SELECT);
654 udelay(50);
655 parport_write_control(cam->port,
656 PARPORT_CONTROL_SELECT
657 | PARPORT_CONTROL_INIT);
658 }
659
660 ++cam->open_count;
661
662 return 0;
663}
664
665/****************************************************************************
666 *
667 * cpia_pp_registerCallback
668 *
669 ***************************************************************************/
670static int cpia_pp_registerCallback(void *privdata, void (*cb)(void *cbdata), void *cbdata)
671{
672 struct pp_cam_entry *cam = privdata;
673 int retval = 0;
674
675 if(cam->port->irq != PARPORT_IRQ_NONE) {
676 cam->cb_func = cb;
677 cam->cb_data = cbdata;
678 INIT_WORK(&cam->cb_task, cpia_pp_run_callback);
679 } else {
680 retval = -1;
681 }
682 return retval;
683}
684
685/****************************************************************************
686 *
687 * cpia_pp_close
688 *
689 ***************************************************************************/
690static int cpia_pp_close(void *privdata)
691{
692 struct pp_cam_entry *cam = privdata;
693 if (--cam->open_count == 0) {
694 parport_release(cam->pdev);
695 }
696 return 0;
697}
698
699/****************************************************************************
700 *
701 * cpia_pp_register
702 *
703 ***************************************************************************/
704static int cpia_pp_register(struct parport *port)
705{
706 struct pardevice *pdev = NULL;
707 struct pp_cam_entry *cam;
708 struct cam_data *cpia;
709
710 if (!(port->modes & PARPORT_MODE_PCSPP)) {
711 LOG("port is not supported by CPiA driver\n");
712 return -ENXIO;
713 }
714
715 cam = kzalloc(sizeof(struct pp_cam_entry), GFP_KERNEL);
716 if (cam == NULL) {
717 LOG("failed to allocate camera structure\n");
718 return -ENOMEM;
719 }
720
721 pdev = parport_register_device(port, "cpia_pp", NULL, NULL,
722 NULL, 0, cam);
723
724 if (!pdev) {
725 LOG("failed to parport_register_device\n");
726 kfree(cam);
727 return -ENXIO;
728 }
729
730 cam->pdev = pdev;
731 cam->port = port;
732 init_waitqueue_head(&cam->wq_stream);
733
734 cam->streaming = 0;
735 cam->stream_irq = 0;
736
737 if((cpia = cpia_register_camera(&cpia_pp_ops, cam)) == NULL) {
738 LOG("failed to cpia_register_camera\n");
739 parport_unregister_device(pdev);
740 kfree(cam);
741 return -ENXIO;
742 }
743 spin_lock( &cam_list_lock_pp );
744 list_add( &cpia->cam_data_list, &cam_list );
745 spin_unlock( &cam_list_lock_pp );
746
747 return 0;
748}
749
750static void cpia_pp_detach (struct parport *port)
751{
752 struct list_head *tmp;
753 struct cam_data *cpia = NULL;
754 struct pp_cam_entry *cam;
755
756 spin_lock( &cam_list_lock_pp );
757 list_for_each (tmp, &cam_list) {
758 cpia = list_entry(tmp, struct cam_data, cam_data_list);
759 cam = (struct pp_cam_entry *) cpia->lowlevel_data;
760 if (cam && cam->port->number == port->number) {
761 list_del(&cpia->cam_data_list);
762 break;
763 }
764 cpia = NULL;
765 }
766 spin_unlock( &cam_list_lock_pp );
767
768 if (!cpia) {
769 DBG("cpia_pp_detach failed to find cam_data in cam_list\n");
770 return;
771 }
772
773 cam = (struct pp_cam_entry *) cpia->lowlevel_data;
774 cpia_unregister_camera(cpia);
775 if(cam->open_count > 0)
776 cpia_pp_close(cam);
777 parport_unregister_device(cam->pdev);
778 cpia->lowlevel_data = NULL;
779 kfree(cam);
780}
781
782static void cpia_pp_attach (struct parport *port)
783{
784 unsigned int i;
785
786 switch (parport_nr[0])
787 {
788 case PPCPIA_PARPORT_UNSPEC:
789 case PPCPIA_PARPORT_AUTO:
790 if (port->probe_info[0].class != PARPORT_CLASS_MEDIA ||
791 port->probe_info[0].cmdset == NULL ||
792 strncmp(port->probe_info[0].cmdset, "CPIA_1", 6) != 0)
793 return;
794
795 cpia_pp_register(port);
796
797 break;
798
799 default:
800 for (i = 0; i < PARPORT_MAX; ++i) {
801 if (port->number == parport_nr[i]) {
802 cpia_pp_register(port);
803 break;
804 }
805 }
806 break;
807 }
808}
809
810static struct parport_driver cpia_pp_driver = {
811 .name = "cpia_pp",
812 .attach = cpia_pp_attach,
813 .detach = cpia_pp_detach,
814};
815
816static int __init cpia_pp_init(void)
817{
818 printk(KERN_INFO "%s v%d.%d.%d\n",ABOUT,
819 CPIA_PP_MAJ_VER,CPIA_PP_MIN_VER,CPIA_PP_PATCH_VER);
820
821 if(parport_nr[0] == PPCPIA_PARPORT_OFF) {
822 printk(" disabled\n");
823 return 0;
824 }
825
826 spin_lock_init( &cam_list_lock_pp );
827
828 if (parport_register_driver (&cpia_pp_driver)) {
829 LOG ("unable to register with parport\n");
830 return -EIO;
831 }
832 return 0;
833}
834
835static int __init cpia_init(void)
836{
837 if (parport[0]) {
838 /* The user gave some parameters. Let's see what they were. */
839 if (!strncmp(parport[0], "auto", 4)) {
840 parport_nr[0] = PPCPIA_PARPORT_AUTO;
841 } else {
842 int n;
843 for (n = 0; n < PARPORT_MAX && parport[n]; n++) {
844 if (!strncmp(parport[n], "none", 4)) {
845 parport_nr[n] = PPCPIA_PARPORT_NONE;
846 } else {
847 char *ep;
848 unsigned long r = simple_strtoul(parport[n], &ep, 0);
849 if (ep != parport[n]) {
850 parport_nr[n] = r;
851 } else {
852 LOG("bad port specifier `%s'\n", parport[n]);
853 return -ENODEV;
854 }
855 }
856 }
857 }
858 }
859 return cpia_pp_init();
860}
861
862static void __exit cpia_cleanup(void)
863{
864 parport_unregister_driver(&cpia_pp_driver);
865 return;
866}
867
868module_init(cpia_init);
869module_exit(cpia_cleanup);
diff --git a/drivers/staging/cpia/cpia_usb.c b/drivers/staging/cpia/cpia_usb.c
deleted file mode 100644
index 58d193ff591c..000000000000
--- a/drivers/staging/cpia/cpia_usb.c
+++ /dev/null
@@ -1,640 +0,0 @@
1/*
2 * cpia_usb CPiA USB driver
3 *
4 * Supports CPiA based parallel port Video Camera's.
5 *
6 * Copyright (C) 1999 Jochen Scharrlach <Jochen.Scharrlach@schwaben.de>
7 * Copyright (C) 1999, 2000 Johannes Erdfelt <johannes@erdfelt.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24/* define _CPIA_DEBUG_ for verbose debug output (see cpia.h) */
25/* #define _CPIA_DEBUG_ 1 */
26
27#include <linux/module.h>
28#include <linux/kernel.h>
29#include <linux/init.h>
30#include <linux/wait.h>
31#include <linux/list.h>
32#include <linux/slab.h>
33#include <linux/vmalloc.h>
34#include <linux/usb.h>
35
36#include "cpia.h"
37
38#define USB_REQ_CPIA_GRAB_FRAME 0xC1
39#define USB_REQ_CPIA_UPLOAD_FRAME 0xC2
40#define WAIT_FOR_NEXT_FRAME 0
41#define FORCE_FRAME_UPLOAD 1
42
43#define FRAMES_PER_DESC 10
44#define FRAME_SIZE_PER_DESC 960 /* Shouldn't be hardcoded */
45#define CPIA_NUMSBUF 2
46#define STREAM_BUF_SIZE (PAGE_SIZE * 4)
47#define SCRATCH_BUF_SIZE (STREAM_BUF_SIZE * 2)
48
49struct cpia_sbuf {
50 char *data;
51 struct urb *urb;
52};
53
54#define FRAMEBUF_LEN (CPIA_MAX_FRAME_SIZE+100)
55enum framebuf_status {
56 FRAME_EMPTY,
57 FRAME_READING,
58 FRAME_READY,
59 FRAME_ERROR,
60};
61
62struct framebuf {
63 int length;
64 enum framebuf_status status;
65 u8 data[FRAMEBUF_LEN];
66 struct framebuf *next;
67};
68
69struct usb_cpia {
70 /* Device structure */
71 struct usb_device *dev;
72
73 unsigned char iface;
74 wait_queue_head_t wq_stream;
75
76 int cursbuf; /* Current receiving sbuf */
77 struct cpia_sbuf sbuf[CPIA_NUMSBUF]; /* Double buffering */
78
79 int streaming;
80 int open;
81 int present;
82 struct framebuf *buffers[3];
83 struct framebuf *curbuff, *workbuff;
84};
85
86static int cpia_usb_open(void *privdata);
87static int cpia_usb_registerCallback(void *privdata, void (*cb) (void *cbdata),
88 void *cbdata);
89static int cpia_usb_transferCmd(void *privdata, u8 *command, u8 *data);
90static int cpia_usb_streamStart(void *privdata);
91static int cpia_usb_streamStop(void *privdata);
92static int cpia_usb_streamRead(void *privdata, u8 *frame, int noblock);
93static int cpia_usb_close(void *privdata);
94
95#define ABOUT "USB driver for Vision CPiA based cameras"
96
97static struct cpia_camera_ops cpia_usb_ops = {
98 cpia_usb_open,
99 cpia_usb_registerCallback,
100 cpia_usb_transferCmd,
101 cpia_usb_streamStart,
102 cpia_usb_streamStop,
103 cpia_usb_streamRead,
104 cpia_usb_close,
105 0,
106 THIS_MODULE
107};
108
109static LIST_HEAD(cam_list);
110static spinlock_t cam_list_lock_usb;
111
112static void cpia_usb_complete(struct urb *urb)
113{
114 int i;
115 char *cdata;
116 struct usb_cpia *ucpia;
117
118 if (!urb || !urb->context)
119 return;
120
121 ucpia = (struct usb_cpia *) urb->context;
122
123 if (!ucpia->dev || !ucpia->streaming || !ucpia->present || !ucpia->open)
124 return;
125
126 if (ucpia->workbuff->status == FRAME_EMPTY) {
127 ucpia->workbuff->status = FRAME_READING;
128 ucpia->workbuff->length = 0;
129 }
130
131 for (i = 0; i < urb->number_of_packets; i++) {
132 int n = urb->iso_frame_desc[i].actual_length;
133 int st = urb->iso_frame_desc[i].status;
134
135 cdata = urb->transfer_buffer + urb->iso_frame_desc[i].offset;
136
137 if (st)
138 printk(KERN_DEBUG "cpia data error: [%d] len=%d, status=%X\n", i, n, st);
139
140 if (FRAMEBUF_LEN < ucpia->workbuff->length + n) {
141 printk(KERN_DEBUG "cpia: scratch buf overflow!scr_len: %d, n: %d\n", ucpia->workbuff->length, n);
142 return;
143 }
144
145 if (n) {
146 if ((ucpia->workbuff->length > 0) ||
147 (0x19 == cdata[0] && 0x68 == cdata[1])) {
148 memcpy(ucpia->workbuff->data + ucpia->workbuff->length, cdata, n);
149 ucpia->workbuff->length += n;
150 } else
151 DBG("Ignoring packet!\n");
152 } else {
153 if (ucpia->workbuff->length > 4 &&
154 0xff == ucpia->workbuff->data[ucpia->workbuff->length-1] &&
155 0xff == ucpia->workbuff->data[ucpia->workbuff->length-2] &&
156 0xff == ucpia->workbuff->data[ucpia->workbuff->length-3] &&
157 0xff == ucpia->workbuff->data[ucpia->workbuff->length-4]) {
158 ucpia->workbuff->status = FRAME_READY;
159 ucpia->curbuff = ucpia->workbuff;
160 ucpia->workbuff = ucpia->workbuff->next;
161 ucpia->workbuff->status = FRAME_EMPTY;
162 ucpia->workbuff->length = 0;
163
164 if (waitqueue_active(&ucpia->wq_stream))
165 wake_up_interruptible(&ucpia->wq_stream);
166 }
167 }
168 }
169
170 /* resubmit */
171 urb->dev = ucpia->dev;
172 if ((i = usb_submit_urb(urb, GFP_ATOMIC)) != 0)
173 printk(KERN_ERR "%s: usb_submit_urb ret %d\n", __func__, i);
174}
175
176static int cpia_usb_open(void *privdata)
177{
178 struct usb_cpia *ucpia = (struct usb_cpia *) privdata;
179 struct urb *urb;
180 int ret, retval = 0, fx, err;
181
182 if (!ucpia)
183 return -EINVAL;
184
185 ucpia->sbuf[0].data = kmalloc(FRAMES_PER_DESC * FRAME_SIZE_PER_DESC, GFP_KERNEL);
186 if (!ucpia->sbuf[0].data)
187 return -EINVAL;
188
189 ucpia->sbuf[1].data = kmalloc(FRAMES_PER_DESC * FRAME_SIZE_PER_DESC, GFP_KERNEL);
190 if (!ucpia->sbuf[1].data) {
191 retval = -EINVAL;
192 goto error_0;
193 }
194
195 ret = usb_set_interface(ucpia->dev, ucpia->iface, 3);
196 if (ret < 0) {
197 printk(KERN_ERR "cpia_usb_open: usb_set_interface error (ret = %d)\n", ret);
198 retval = -EBUSY;
199 goto error_1;
200 }
201
202 ucpia->buffers[0]->status = FRAME_EMPTY;
203 ucpia->buffers[0]->length = 0;
204 ucpia->buffers[1]->status = FRAME_EMPTY;
205 ucpia->buffers[1]->length = 0;
206 ucpia->buffers[2]->status = FRAME_EMPTY;
207 ucpia->buffers[2]->length = 0;
208 ucpia->curbuff = ucpia->buffers[0];
209 ucpia->workbuff = ucpia->buffers[1];
210
211 /* We double buffer the Iso lists, and also know the polling
212 * interval is every frame (1 == (1 << (bInterval -1))).
213 */
214 urb = usb_alloc_urb(FRAMES_PER_DESC, GFP_KERNEL);
215 if (!urb) {
216 printk(KERN_ERR "cpia_init_isoc: usb_alloc_urb 0\n");
217 retval = -ENOMEM;
218 goto error_1;
219 }
220
221 ucpia->sbuf[0].urb = urb;
222 urb->dev = ucpia->dev;
223 urb->context = ucpia;
224 urb->pipe = usb_rcvisocpipe(ucpia->dev, 1);
225 urb->transfer_flags = URB_ISO_ASAP;
226 urb->transfer_buffer = ucpia->sbuf[0].data;
227 urb->complete = cpia_usb_complete;
228 urb->number_of_packets = FRAMES_PER_DESC;
229 urb->interval = 1;
230 urb->transfer_buffer_length = FRAME_SIZE_PER_DESC * FRAMES_PER_DESC;
231 for (fx = 0; fx < FRAMES_PER_DESC; fx++) {
232 urb->iso_frame_desc[fx].offset = FRAME_SIZE_PER_DESC * fx;
233 urb->iso_frame_desc[fx].length = FRAME_SIZE_PER_DESC;
234 }
235
236 urb = usb_alloc_urb(FRAMES_PER_DESC, GFP_KERNEL);
237 if (!urb) {
238 printk(KERN_ERR "cpia_init_isoc: usb_alloc_urb 1\n");
239 retval = -ENOMEM;
240 goto error_urb0;
241 }
242
243 ucpia->sbuf[1].urb = urb;
244 urb->dev = ucpia->dev;
245 urb->context = ucpia;
246 urb->pipe = usb_rcvisocpipe(ucpia->dev, 1);
247 urb->transfer_flags = URB_ISO_ASAP;
248 urb->transfer_buffer = ucpia->sbuf[1].data;
249 urb->complete = cpia_usb_complete;
250 urb->number_of_packets = FRAMES_PER_DESC;
251 urb->interval = 1;
252 urb->transfer_buffer_length = FRAME_SIZE_PER_DESC * FRAMES_PER_DESC;
253 for (fx = 0; fx < FRAMES_PER_DESC; fx++) {
254 urb->iso_frame_desc[fx].offset = FRAME_SIZE_PER_DESC * fx;
255 urb->iso_frame_desc[fx].length = FRAME_SIZE_PER_DESC;
256 }
257
258 /* queue the ISO urbs, and resubmit in the completion handler */
259 err = usb_submit_urb(ucpia->sbuf[0].urb, GFP_KERNEL);
260 if (err) {
261 printk(KERN_ERR "cpia_init_isoc: usb_submit_urb 0 ret %d\n",
262 err);
263 goto error_urb1;
264 }
265 err = usb_submit_urb(ucpia->sbuf[1].urb, GFP_KERNEL);
266 if (err) {
267 printk(KERN_ERR "cpia_init_isoc: usb_submit_urb 1 ret %d\n",
268 err);
269 goto error_urb1;
270 }
271
272 ucpia->streaming = 1;
273 ucpia->open = 1;
274
275 return 0;
276
277error_urb1: /* free urb 1 */
278 usb_free_urb(ucpia->sbuf[1].urb);
279 ucpia->sbuf[1].urb = NULL;
280error_urb0: /* free urb 0 */
281 usb_free_urb(ucpia->sbuf[0].urb);
282 ucpia->sbuf[0].urb = NULL;
283error_1:
284 kfree (ucpia->sbuf[1].data);
285 ucpia->sbuf[1].data = NULL;
286error_0:
287 kfree (ucpia->sbuf[0].data);
288 ucpia->sbuf[0].data = NULL;
289
290 return retval;
291}
292
293//
294// convenience functions
295//
296
297/****************************************************************************
298 *
299 * WritePacket
300 *
301 ***************************************************************************/
302static int WritePacket(struct usb_device *udev, const u8 *packet, u8 *buf, size_t size)
303{
304 if (!packet)
305 return -EINVAL;
306
307 return usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
308 packet[1] + (packet[0] << 8),
309 USB_TYPE_VENDOR | USB_RECIP_DEVICE,
310 packet[2] + (packet[3] << 8),
311 packet[4] + (packet[5] << 8), buf, size, 1000);
312}
313
314/****************************************************************************
315 *
316 * ReadPacket
317 *
318 ***************************************************************************/
319static int ReadPacket(struct usb_device *udev, u8 *packet, u8 *buf, size_t size)
320{
321 if (!packet || size <= 0)
322 return -EINVAL;
323
324 return usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
325 packet[1] + (packet[0] << 8),
326 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
327 packet[2] + (packet[3] << 8),
328 packet[4] + (packet[5] << 8), buf, size, 1000);
329}
330
331static int cpia_usb_transferCmd(void *privdata, u8 *command, u8 *data)
332{
333 int err = 0;
334 int databytes;
335 struct usb_cpia *ucpia = (struct usb_cpia *)privdata;
336 struct usb_device *udev = ucpia->dev;
337
338 if (!udev) {
339 DBG("Internal driver error: udev is NULL\n");
340 return -EINVAL;
341 }
342
343 if (!command) {
344 DBG("Internal driver error: command is NULL\n");
345 return -EINVAL;
346 }
347
348 databytes = (((int)command[7])<<8) | command[6];
349
350 if (command[0] == DATA_IN) {
351 u8 buffer[8];
352
353 if (!data) {
354 DBG("Internal driver error: data is NULL\n");
355 return -EINVAL;
356 }
357
358 err = ReadPacket(udev, command, buffer, 8);
359 if (err < 0)
360 return err;
361
362 memcpy(data, buffer, databytes);
363 } else if(command[0] == DATA_OUT)
364 WritePacket(udev, command, data, databytes);
365 else {
366 DBG("Unexpected first byte of command: %x\n", command[0]);
367 err = -EINVAL;
368 }
369
370 return 0;
371}
372
373static int cpia_usb_registerCallback(void *privdata, void (*cb) (void *cbdata),
374 void *cbdata)
375{
376 return -ENODEV;
377}
378
379static int cpia_usb_streamStart(void *privdata)
380{
381 return -ENODEV;
382}
383
384static int cpia_usb_streamStop(void *privdata)
385{
386 return -ENODEV;
387}
388
389static int cpia_usb_streamRead(void *privdata, u8 *frame, int noblock)
390{
391 struct usb_cpia *ucpia = (struct usb_cpia *) privdata;
392 struct framebuf *mybuff;
393
394 if (!ucpia || !ucpia->present)
395 return -1;
396
397 if (ucpia->curbuff->status != FRAME_READY)
398 interruptible_sleep_on(&ucpia->wq_stream);
399 else
400 DBG("Frame already waiting!\n");
401
402 mybuff = ucpia->curbuff;
403
404 if (!mybuff)
405 return -1;
406
407 if (mybuff->status != FRAME_READY || mybuff->length < 4) {
408 DBG("Something went wrong!\n");
409 return -1;
410 }
411
412 memcpy(frame, mybuff->data, mybuff->length);
413 mybuff->status = FRAME_EMPTY;
414
415/* DBG("read done, %d bytes, Header: %x/%x, Footer: %x%x%x%x\n", */
416/* mybuff->length, frame[0], frame[1], */
417/* frame[mybuff->length-4], frame[mybuff->length-3], */
418/* frame[mybuff->length-2], frame[mybuff->length-1]); */
419
420 return mybuff->length;
421}
422
423static void cpia_usb_free_resources(struct usb_cpia *ucpia, int try)
424{
425 if (!ucpia->streaming)
426 return;
427
428 ucpia->streaming = 0;
429
430 /* Set packet size to 0 */
431 if (try) {
432 int ret;
433
434 ret = usb_set_interface(ucpia->dev, ucpia->iface, 0);
435 if (ret < 0) {
436 printk(KERN_ERR "usb_set_interface error (ret = %d)\n", ret);
437 return;
438 }
439 }
440
441 /* Unschedule all of the iso td's */
442 if (ucpia->sbuf[1].urb) {
443 usb_kill_urb(ucpia->sbuf[1].urb);
444 usb_free_urb(ucpia->sbuf[1].urb);
445 ucpia->sbuf[1].urb = NULL;
446 }
447
448 kfree(ucpia->sbuf[1].data);
449 ucpia->sbuf[1].data = NULL;
450
451 if (ucpia->sbuf[0].urb) {
452 usb_kill_urb(ucpia->sbuf[0].urb);
453 usb_free_urb(ucpia->sbuf[0].urb);
454 ucpia->sbuf[0].urb = NULL;
455 }
456
457 kfree(ucpia->sbuf[0].data);
458 ucpia->sbuf[0].data = NULL;
459}
460
461static int cpia_usb_close(void *privdata)
462{
463 struct usb_cpia *ucpia = (struct usb_cpia *) privdata;
464
465 if(!ucpia)
466 return -ENODEV;
467
468 ucpia->open = 0;
469
470 /* ucpia->present = 0 protects against trying to reset the
471 * alt setting if camera is physically disconnected while open */
472 cpia_usb_free_resources(ucpia, ucpia->present);
473
474 return 0;
475}
476
477/* Probing and initializing */
478
479static int cpia_probe(struct usb_interface *intf,
480 const struct usb_device_id *id)
481{
482 struct usb_device *udev = interface_to_usbdev(intf);
483 struct usb_host_interface *interface;
484 struct usb_cpia *ucpia;
485 struct cam_data *cam;
486 int ret;
487
488 /* A multi-config CPiA camera? */
489 if (udev->descriptor.bNumConfigurations != 1)
490 return -ENODEV;
491
492 interface = intf->cur_altsetting;
493
494 printk(KERN_INFO "USB CPiA camera found\n");
495
496 ucpia = kzalloc(sizeof(*ucpia), GFP_KERNEL);
497 if (!ucpia) {
498 printk(KERN_ERR "couldn't kmalloc cpia struct\n");
499 return -ENOMEM;
500 }
501
502 ucpia->dev = udev;
503 ucpia->iface = interface->desc.bInterfaceNumber;
504 init_waitqueue_head(&ucpia->wq_stream);
505
506 ucpia->buffers[0] = vmalloc(sizeof(*ucpia->buffers[0]));
507 if (!ucpia->buffers[0]) {
508 printk(KERN_ERR "couldn't vmalloc frame buffer 0\n");
509 goto fail_alloc_0;
510 }
511
512 ucpia->buffers[1] = vmalloc(sizeof(*ucpia->buffers[1]));
513 if (!ucpia->buffers[1]) {
514 printk(KERN_ERR "couldn't vmalloc frame buffer 1\n");
515 goto fail_alloc_1;
516 }
517
518 ucpia->buffers[2] = vmalloc(sizeof(*ucpia->buffers[2]));
519 if (!ucpia->buffers[2]) {
520 printk(KERN_ERR "couldn't vmalloc frame buffer 2\n");
521 goto fail_alloc_2;
522 }
523
524 ucpia->buffers[0]->next = ucpia->buffers[1];
525 ucpia->buffers[1]->next = ucpia->buffers[2];
526 ucpia->buffers[2]->next = ucpia->buffers[0];
527
528 ret = usb_set_interface(udev, ucpia->iface, 0);
529 if (ret < 0) {
530 printk(KERN_ERR "cpia_probe: usb_set_interface error (ret = %d)\n", ret);
531 /* goto fail_all; */
532 }
533
534 /* Before register_camera, important */
535 ucpia->present = 1;
536
537 cam = cpia_register_camera(&cpia_usb_ops, ucpia);
538 if (!cam) {
539 LOG("failed to cpia_register_camera\n");
540 goto fail_all;
541 }
542
543 spin_lock( &cam_list_lock_usb );
544 list_add( &cam->cam_data_list, &cam_list );
545 spin_unlock( &cam_list_lock_usb );
546
547 usb_set_intfdata(intf, cam);
548 return 0;
549
550fail_all:
551 vfree(ucpia->buffers[2]);
552 ucpia->buffers[2] = NULL;
553fail_alloc_2:
554 vfree(ucpia->buffers[1]);
555 ucpia->buffers[1] = NULL;
556fail_alloc_1:
557 vfree(ucpia->buffers[0]);
558 ucpia->buffers[0] = NULL;
559fail_alloc_0:
560 kfree(ucpia);
561 return -EIO;
562}
563
564static void cpia_disconnect(struct usb_interface *intf);
565
566static struct usb_device_id cpia_id_table [] = {
567 { USB_DEVICE(0x0553, 0x0002) },
568 { USB_DEVICE(0x0813, 0x0001) },
569 { } /* Terminating entry */
570};
571
572MODULE_DEVICE_TABLE (usb, cpia_id_table);
573MODULE_LICENSE("GPL");
574
575
576static struct usb_driver cpia_driver = {
577 .name = "cpia",
578 .probe = cpia_probe,
579 .disconnect = cpia_disconnect,
580 .id_table = cpia_id_table,
581};
582
583static void cpia_disconnect(struct usb_interface *intf)
584{
585 struct cam_data *cam = usb_get_intfdata(intf);
586 struct usb_cpia *ucpia;
587
588 usb_set_intfdata(intf, NULL);
589 if (!cam)
590 return;
591
592 ucpia = (struct usb_cpia *) cam->lowlevel_data;
593 spin_lock( &cam_list_lock_usb );
594 list_del(&cam->cam_data_list);
595 spin_unlock( &cam_list_lock_usb );
596
597 ucpia->present = 0;
598
599 cpia_unregister_camera(cam);
600 if(ucpia->open)
601 cpia_usb_close(cam->lowlevel_data);
602
603 ucpia->curbuff->status = FRAME_ERROR;
604
605 if (waitqueue_active(&ucpia->wq_stream))
606 wake_up_interruptible(&ucpia->wq_stream);
607
608 ucpia->curbuff = ucpia->workbuff = NULL;
609
610 vfree(ucpia->buffers[2]);
611 ucpia->buffers[2] = NULL;
612
613 vfree(ucpia->buffers[1]);
614 ucpia->buffers[1] = NULL;
615
616 vfree(ucpia->buffers[0]);
617 ucpia->buffers[0] = NULL;
618
619 cam->lowlevel_data = NULL;
620 kfree(ucpia);
621}
622
623static int __init usb_cpia_init(void)
624{
625 printk(KERN_INFO "%s v%d.%d.%d\n",ABOUT,
626 CPIA_USB_MAJ_VER,CPIA_USB_MIN_VER,CPIA_USB_PATCH_VER);
627
628 spin_lock_init(&cam_list_lock_usb);
629 return usb_register(&cpia_driver);
630}
631
632static void __exit usb_cpia_cleanup(void)
633{
634 usb_deregister(&cpia_driver);
635}
636
637
638module_init (usb_cpia_init);
639module_exit (usb_cpia_cleanup);
640
diff --git a/drivers/staging/stradis/Kconfig b/drivers/staging/stradis/Kconfig
deleted file mode 100644
index 02f0fc504cf5..000000000000
--- a/drivers/staging/stradis/Kconfig
+++ /dev/null
@@ -1,7 +0,0 @@
1config VIDEO_STRADIS
2 tristate "Stradis 4:2:2 MPEG-2 video driver (DEPRECATED)"
3 depends on EXPERIMENTAL && PCI && VIDEO_V4L1 && VIRT_TO_BUS && BKL
4 help
5 Say Y here to enable support for the Stradis 4:2:2 MPEG-2 video
6 driver for PCI. There is a product page at
7 <http://www.stradis.com/>.
diff --git a/drivers/staging/stradis/Makefile b/drivers/staging/stradis/Makefile
deleted file mode 100644
index 0f1feab59e39..000000000000
--- a/drivers/staging/stradis/Makefile
+++ /dev/null
@@ -1,3 +0,0 @@
1obj-$(CONFIG_VIDEO_STRADIS) += stradis.o
2
3EXTRA_CFLAGS += -Idrivers/media/video
diff --git a/drivers/staging/stradis/TODO b/drivers/staging/stradis/TODO
deleted file mode 100644
index f48150fe2fa9..000000000000
--- a/drivers/staging/stradis/TODO
+++ /dev/null
@@ -1,6 +0,0 @@
1This is an obsolete driver for ancient stradis hardware.
2We couldn't find anyone with this hardware in order to port it to use V4L2.
3
4If nobody take care on it, the driver will be removed for 2.6.38.
5
6Please send patches to linux-media@vger.kernel.org
diff --git a/drivers/staging/stradis/stradis.c b/drivers/staging/stradis/stradis.c
deleted file mode 100644
index 807dd7eb748f..000000000000
--- a/drivers/staging/stradis/stradis.c
+++ /dev/null
@@ -1,2222 +0,0 @@
1/*
2 * stradis.c - stradis 4:2:2 mpeg decoder driver
3 *
4 * Stradis 4:2:2 MPEG-2 Decoder Driver
5 * Copyright (C) 1999 Nathan Laredo <laredo@gnu.org>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include <linux/module.h>
23#include <linux/delay.h>
24#include <linux/errno.h>
25#include <linux/fs.h>
26#include <linux/kernel.h>
27#include <linux/major.h>
28#include <linux/slab.h>
29#include <linux/smp_lock.h>
30#include <linux/mm.h>
31#include <linux/init.h>
32#include <linux/poll.h>
33#include <linux/pci.h>
34#include <linux/signal.h>
35#include <asm/io.h>
36#include <linux/ioport.h>
37#include <asm/pgtable.h>
38#include <asm/page.h>
39#include <linux/sched.h>
40#include <asm/types.h>
41#include <linux/types.h>
42#include <linux/interrupt.h>
43#include <asm/uaccess.h>
44#include <linux/vmalloc.h>
45#include <linux/videodev.h>
46#include <media/v4l2-common.h>
47#include <media/v4l2-ioctl.h>
48
49#include "saa7146.h"
50#include "saa7146reg.h"
51#include "ibmmpeg2.h"
52#include "saa7121.h"
53#include "cs8420.h"
54
55#define DEBUG(x) /* debug driver */
56#undef IDEBUG /* debug irq handler */
57#undef MDEBUG /* debug memory management */
58
59#define SAA7146_MAX 6
60
61static struct saa7146 saa7146s[SAA7146_MAX];
62
63static int saa_num; /* number of SAA7146s in use */
64
65static int video_nr = -1;
66module_param(video_nr, int, 0);
67MODULE_LICENSE("GPL");
68
69#define nDebNormal 0x00480000
70#define nDebNoInc 0x00480000
71#define nDebVideo 0xd0480000
72#define nDebAudio 0xd0400000
73#define nDebDMA 0x02c80000
74
75#define oDebNormal 0x13c80000
76#define oDebNoInc 0x13c80000
77#define oDebVideo 0xd1080000
78#define oDebAudio 0xd1080000
79#define oDebDMA 0x03080000
80
81#define NewCard (saa->boardcfg[3])
82#define ChipControl (saa->boardcfg[1])
83#define NTSCFirstActive (saa->boardcfg[4])
84#define PALFirstActive (saa->boardcfg[5])
85#define NTSCLastActive (saa->boardcfg[54])
86#define PALLastActive (saa->boardcfg[55])
87#define Have2MB (saa->boardcfg[18] & 0x40)
88#define HaveCS8420 (saa->boardcfg[18] & 0x04)
89#define IBMMPEGCD20 (saa->boardcfg[18] & 0x20)
90#define HaveCS3310 (saa->boardcfg[18] & 0x01)
91#define CS3310MaxLvl ((saa->boardcfg[30] << 8) | saa->boardcfg[31])
92#define HaveCS4341 (saa->boardcfg[40] == 2)
93#define SDIType (saa->boardcfg[27])
94#define CurrentMode (saa->boardcfg[2])
95
96#define debNormal (NewCard ? nDebNormal : oDebNormal)
97#define debNoInc (NewCard ? nDebNoInc : oDebNoInc)
98#define debVideo (NewCard ? nDebVideo : oDebVideo)
99#define debAudio (NewCard ? nDebAudio : oDebAudio)
100#define debDMA (NewCard ? nDebDMA : oDebDMA)
101
102#ifdef USE_RESCUE_EEPROM_SDM275
103static unsigned char rescue_eeprom[64] = {
104 0x00, 0x01, 0x04, 0x13, 0x26, 0x0f, 0x10, 0x00, 0x00, 0x00, 0x43, 0x63,
105 0x22, 0x01, 0x29, 0x15, 0x73, 0x00, 0x1f, 'd', 'e', 'c', 'x', 'l',
106 'd', 'v', 'a', 0x02, 0x00, 0x01, 0x00, 0xcc, 0xa4, 0x63, 0x09, 0xe2,
107 0x10, 0x00, 0x0a, 0x00, 0x02, 0x02, 'd', 'e', 'c', 'x', 'l', 'a',
108 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
109 0x00, 0x00, 0x00, 0x00,
110};
111#endif
112
113/* ----------------------------------------------------------------------- */
114/* Hardware I2C functions */
115static void I2CWipe(struct saa7146 *saa)
116{
117 int i;
118 /* set i2c to ~=100kHz, abort transfer, clear busy */
119 saawrite(0x600 | SAA7146_I2C_ABORT, SAA7146_I2C_STATUS);
120 saawrite((SAA7146_MC2_UPLD_I2C << 16) |
121 SAA7146_MC2_UPLD_I2C, SAA7146_MC2);
122 /* wait for i2c registers to be programmed */
123 for (i = 0; i < 1000 &&
124 !(saaread(SAA7146_MC2) & SAA7146_MC2_UPLD_I2C); i++)
125 schedule();
126 saawrite(0x600, SAA7146_I2C_STATUS);
127 saawrite((SAA7146_MC2_UPLD_I2C << 16) |
128 SAA7146_MC2_UPLD_I2C, SAA7146_MC2);
129 /* wait for i2c registers to be programmed */
130 for (i = 0; i < 1000 &&
131 !(saaread(SAA7146_MC2) & SAA7146_MC2_UPLD_I2C); i++)
132 schedule();
133 saawrite(0x600, SAA7146_I2C_STATUS);
134 saawrite((SAA7146_MC2_UPLD_I2C << 16) |
135 SAA7146_MC2_UPLD_I2C, SAA7146_MC2);
136 /* wait for i2c registers to be programmed */
137 for (i = 0; i < 1000 &&
138 !(saaread(SAA7146_MC2) & SAA7146_MC2_UPLD_I2C); i++)
139 schedule();
140}
141
142/* read I2C */
143static int I2CRead(struct saa7146 *saa, unsigned char addr,
144 unsigned char subaddr, int dosub)
145{
146 int i;
147
148 if (saaread(SAA7146_I2C_STATUS) & 0x3c)
149 I2CWipe(saa);
150 for (i = 0;
151 i < 1000 && (saaread(SAA7146_I2C_STATUS) & SAA7146_I2C_BUSY);
152 i++)
153 schedule();
154 if (i == 1000)
155 I2CWipe(saa);
156 if (dosub)
157 saawrite(((addr & 0xfe) << 24) | (((addr | 1) & 0xff) << 8) |
158 ((subaddr & 0xff) << 16) | 0xed, SAA7146_I2C_TRANSFER);
159 else
160 saawrite(((addr & 0xfe) << 24) | (((addr | 1) & 0xff) << 16) |
161 0xf1, SAA7146_I2C_TRANSFER);
162 saawrite((SAA7146_MC2_UPLD_I2C << 16) |
163 SAA7146_MC2_UPLD_I2C, SAA7146_MC2);
164 /* wait for i2c registers to be programmed */
165 for (i = 0; i < 1000 &&
166 !(saaread(SAA7146_MC2) & SAA7146_MC2_UPLD_I2C); i++)
167 schedule();
168 /* wait for valid data */
169 for (i = 0; i < 1000 &&
170 (saaread(SAA7146_I2C_STATUS) & SAA7146_I2C_BUSY); i++)
171 schedule();
172 if (saaread(SAA7146_I2C_STATUS) & SAA7146_I2C_ERR)
173 return -1;
174 if (i == 1000)
175 printk("i2c setup read timeout\n");
176 saawrite(0x41, SAA7146_I2C_TRANSFER);
177 saawrite((SAA7146_MC2_UPLD_I2C << 16) |
178 SAA7146_MC2_UPLD_I2C, SAA7146_MC2);
179 /* wait for i2c registers to be programmed */
180 for (i = 0; i < 1000 &&
181 !(saaread(SAA7146_MC2) & SAA7146_MC2_UPLD_I2C); i++)
182 schedule();
183 /* wait for valid data */
184 for (i = 0; i < 1000 &&
185 (saaread(SAA7146_I2C_TRANSFER) & SAA7146_I2C_BUSY); i++)
186 schedule();
187 if (saaread(SAA7146_I2C_TRANSFER) & SAA7146_I2C_ERR)
188 return -1;
189 if (i == 1000)
190 printk("i2c read timeout\n");
191 return ((saaread(SAA7146_I2C_TRANSFER) >> 24) & 0xff);
192}
193
194/* set both to write both bytes, reset it to write only b1 */
195
196static int I2CWrite(struct saa7146 *saa, unsigned char addr, unsigned char b1,
197 unsigned char b2, int both)
198{
199 int i;
200 u32 data;
201
202 if (saaread(SAA7146_I2C_STATUS) & 0x3c)
203 I2CWipe(saa);
204 for (i = 0; i < 1000 &&
205 (saaread(SAA7146_I2C_STATUS) & SAA7146_I2C_BUSY); i++)
206 schedule();
207 if (i == 1000)
208 I2CWipe(saa);
209 data = ((addr & 0xfe) << 24) | ((b1 & 0xff) << 16);
210 if (both)
211 data |= ((b2 & 0xff) << 8) | 0xe5;
212 else
213 data |= 0xd1;
214 saawrite(data, SAA7146_I2C_TRANSFER);
215 saawrite((SAA7146_MC2_UPLD_I2C << 16) | SAA7146_MC2_UPLD_I2C,
216 SAA7146_MC2);
217 return 0;
218}
219
220static void attach_inform(struct saa7146 *saa, int id)
221{
222 int i;
223
224 DEBUG(printk(KERN_DEBUG "stradis%d: i2c: device found=%02x\n", saa->nr,
225 id));
226 if (id == 0xa0) { /* we have rev2 or later board, fill in info */
227 for (i = 0; i < 64; i++)
228 saa->boardcfg[i] = I2CRead(saa, 0xa0, i, 1);
229#ifdef USE_RESCUE_EEPROM_SDM275
230 if (saa->boardcfg[0] != 0) {
231 printk("stradis%d: WARNING: EEPROM STORED VALUES HAVE "
232 "BEEN IGNORED\n", saa->nr);
233 for (i = 0; i < 64; i++)
234 saa->boardcfg[i] = rescue_eeprom[i];
235 }
236#endif
237 printk("stradis%d: config =", saa->nr);
238 for (i = 0; i < 51; i++) {
239 printk(" %02x", saa->boardcfg[i]);
240 }
241 printk("\n");
242 }
243}
244
245static void I2CBusScan(struct saa7146 *saa)
246{
247 int i;
248 for (i = 0; i < 0xff; i += 2)
249 if ((I2CRead(saa, i, 0, 0)) >= 0)
250 attach_inform(saa, i);
251}
252
253static int debiwait_maxwait;
254
255static int wait_for_debi_done(struct saa7146 *saa)
256{
257 int i;
258
259 /* wait for registers to be programmed */
260 for (i = 0; i < 100000 &&
261 !(saaread(SAA7146_MC2) & SAA7146_MC2_UPLD_DEBI); i++)
262 saaread(SAA7146_MC2);
263 /* wait for transfer to complete */
264 for (i = 0; i < 500000 &&
265 (saaread(SAA7146_PSR) & SAA7146_PSR_DEBI_S); i++)
266 saaread(SAA7146_MC2);
267
268 if (i > debiwait_maxwait)
269 printk("wait-for-debi-done maxwait: %d\n",
270 debiwait_maxwait = i);
271
272 if (i == 500000)
273 return -1;
274
275 return 0;
276}
277
278static int debiwrite(struct saa7146 *saa, u32 config, int addr,
279 u32 val, int count)
280{
281 u32 cmd;
282 if (count <= 0 || count > 32764)
283 return -1;
284 if (wait_for_debi_done(saa) < 0)
285 return -1;
286 saawrite(config, SAA7146_DEBI_CONFIG);
287 if (count <= 4) /* immediate transfer */
288 saawrite(val, SAA7146_DEBI_AD);
289 else /* block transfer */
290 saawrite(virt_to_bus(saa->dmadebi), SAA7146_DEBI_AD);
291 saawrite((cmd = (count << 17) | (addr & 0xffff)), SAA7146_DEBI_COMMAND);
292 saawrite((SAA7146_MC2_UPLD_DEBI << 16) | SAA7146_MC2_UPLD_DEBI,
293 SAA7146_MC2);
294 return 0;
295}
296
297static u32 debiread(struct saa7146 *saa, u32 config, int addr, int count)
298{
299 u32 result = 0;
300
301 if (count > 32764 || count <= 0)
302 return 0;
303 if (wait_for_debi_done(saa) < 0)
304 return 0;
305 saawrite(virt_to_bus(saa->dmadebi), SAA7146_DEBI_AD);
306 saawrite((count << 17) | 0x10000 | (addr & 0xffff),
307 SAA7146_DEBI_COMMAND);
308 saawrite(config, SAA7146_DEBI_CONFIG);
309 saawrite((SAA7146_MC2_UPLD_DEBI << 16) | SAA7146_MC2_UPLD_DEBI,
310 SAA7146_MC2);
311 if (count > 4) /* not an immediate transfer */
312 return count;
313 wait_for_debi_done(saa);
314 result = saaread(SAA7146_DEBI_AD);
315 if (count == 1)
316 result &= 0xff;
317 if (count == 2)
318 result &= 0xffff;
319 if (count == 3)
320 result &= 0xffffff;
321 return result;
322}
323
324static void do_irq_send_data(struct saa7146 *saa)
325{
326 int split, audbytes, vidbytes;
327
328 saawrite(SAA7146_PSR_PIN1, SAA7146_IER);
329 /* if special feature mode in effect, disable audio sending */
330 if (saa->playmode != VID_PLAY_NORMAL)
331 saa->audtail = saa->audhead = 0;
332 if (saa->audhead <= saa->audtail)
333 audbytes = saa->audtail - saa->audhead;
334 else
335 audbytes = 65536 - (saa->audhead - saa->audtail);
336 if (saa->vidhead <= saa->vidtail)
337 vidbytes = saa->vidtail - saa->vidhead;
338 else
339 vidbytes = 524288 - (saa->vidhead - saa->vidtail);
340 if (audbytes == 0 && vidbytes == 0 && saa->osdtail == saa->osdhead) {
341 saawrite(0, SAA7146_IER);
342 return;
343 }
344 /* if at least 1 block audio waiting and audio fifo isn't full */
345 if (audbytes >= 2048 && (debiread(saa, debNormal, IBM_MP2_AUD_FIFO, 2)
346 & 0xff) < 60) {
347 if (saa->audhead > saa->audtail)
348 split = 65536 - saa->audhead;
349 else
350 split = 0;
351 audbytes = 2048;
352 if (split > 0 && split < 2048) {
353 memcpy(saa->dmadebi, saa->audbuf + saa->audhead, split);
354 saa->audhead = 0;
355 audbytes -= split;
356 } else
357 split = 0;
358 memcpy(saa->dmadebi + split, saa->audbuf + saa->audhead,
359 audbytes);
360 saa->audhead += audbytes;
361 saa->audhead &= 0xffff;
362 debiwrite(saa, debAudio, (NewCard ? IBM_MP2_AUD_FIFO :
363 IBM_MP2_AUD_FIFOW), 0, 2048);
364 wake_up_interruptible(&saa->audq);
365 /* if at least 1 block video waiting and video fifo isn't full */
366 } else if (vidbytes >= 30720 && (debiread(saa, debNormal,
367 IBM_MP2_FIFO, 2)) < 16384) {
368 if (saa->vidhead > saa->vidtail)
369 split = 524288 - saa->vidhead;
370 else
371 split = 0;
372 vidbytes = 30720;
373 if (split > 0 && split < 30720) {
374 memcpy(saa->dmadebi, saa->vidbuf + saa->vidhead, split);
375 saa->vidhead = 0;
376 vidbytes -= split;
377 } else
378 split = 0;
379 memcpy(saa->dmadebi + split, saa->vidbuf + saa->vidhead,
380 vidbytes);
381 saa->vidhead += vidbytes;
382 saa->vidhead &= 0x7ffff;
383 debiwrite(saa, debVideo, (NewCard ? IBM_MP2_FIFO :
384 IBM_MP2_FIFOW), 0, 30720);
385 wake_up_interruptible(&saa->vidq);
386 }
387 saawrite(SAA7146_PSR_DEBI_S | SAA7146_PSR_PIN1, SAA7146_IER);
388}
389
390static void send_osd_data(struct saa7146 *saa)
391{
392 int size = saa->osdtail - saa->osdhead;
393 if (size > 30720)
394 size = 30720;
395 /* ensure some multiple of 8 bytes is transferred */
396 size = 8 * ((size + 8) >> 3);
397 if (size) {
398 debiwrite(saa, debNormal, IBM_MP2_OSD_ADDR,
399 (saa->osdhead >> 3), 2);
400 memcpy(saa->dmadebi, &saa->osdbuf[saa->osdhead], size);
401 saa->osdhead += size;
402 /* block transfer of next 8 bytes to ~32k bytes */
403 debiwrite(saa, debNormal, IBM_MP2_OSD_DATA, 0, size);
404 }
405 if (saa->osdhead >= saa->osdtail) {
406 saa->osdhead = saa->osdtail = 0;
407 debiwrite(saa, debNormal, IBM_MP2_MASK0, 0xc00c, 2);
408 }
409}
410
411static irqreturn_t saa7146_irq(int irq, void *dev_id)
412{
413 struct saa7146 *saa = dev_id;
414 u32 stat, astat;
415 int count;
416 int handled = 0;
417
418 count = 0;
419 while (1) {
420 /* get/clear interrupt status bits */
421 stat = saaread(SAA7146_ISR);
422 astat = stat & saaread(SAA7146_IER);
423 if (!astat)
424 break;
425 handled = 1;
426 saawrite(astat, SAA7146_ISR);
427 if (astat & SAA7146_PSR_DEBI_S) {
428 do_irq_send_data(saa);
429 }
430 if (astat & SAA7146_PSR_PIN1) {
431 int istat;
432 /* the following read will trigger DEBI_S */
433 istat = debiread(saa, debNormal, IBM_MP2_HOST_INT, 2);
434 if (istat & 1) {
435 saawrite(0, SAA7146_IER);
436 send_osd_data(saa);
437 saawrite(SAA7146_PSR_DEBI_S |
438 SAA7146_PSR_PIN1, SAA7146_IER);
439 }
440 if (istat & 0x20) { /* Video Start */
441 saa->vidinfo.frame_count++;
442 }
443 if (istat & 0x400) { /* Picture Start */
444 /* update temporal reference */
445 }
446 if (istat & 0x200) { /* Picture Resolution Change */
447 /* read new resolution */
448 }
449 if (istat & 0x100) { /* New User Data found */
450 /* read new user data */
451 }
452 if (istat & 0x1000) { /* new GOP/SMPTE */
453 /* read new SMPTE */
454 }
455 if (istat & 0x8000) { /* Sequence Start Code */
456 /* reset frame counter, load sizes */
457 saa->vidinfo.frame_count = 0;
458 saa->vidinfo.h_size = 704;
459 saa->vidinfo.v_size = 480;
460#if 0
461 if (saa->endmarkhead != saa->endmarktail) {
462 saa->audhead =
463 saa->endmark[saa->endmarkhead];
464 saa->endmarkhead++;
465 if (saa->endmarkhead >= MAX_MARKS)
466 saa->endmarkhead = 0;
467 }
468#endif
469 }
470 if (istat & 0x4000) { /* Sequence Error Code */
471 if (saa->endmarkhead != saa->endmarktail) {
472 saa->audhead =
473 saa->endmark[saa->endmarkhead];
474 saa->endmarkhead++;
475 if (saa->endmarkhead >= MAX_MARKS)
476 saa->endmarkhead = 0;
477 }
478 }
479 }
480#ifdef IDEBUG
481 if (astat & SAA7146_PSR_PPEF) {
482 IDEBUG(printk("stradis%d irq: PPEF\n", saa->nr));
483 }
484 if (astat & SAA7146_PSR_PABO) {
485 IDEBUG(printk("stradis%d irq: PABO\n", saa->nr));
486 }
487 if (astat & SAA7146_PSR_PPED) {
488 IDEBUG(printk("stradis%d irq: PPED\n", saa->nr));
489 }
490 if (astat & SAA7146_PSR_RPS_I1) {
491 IDEBUG(printk("stradis%d irq: RPS_I1\n", saa->nr));
492 }
493 if (astat & SAA7146_PSR_RPS_I0) {
494 IDEBUG(printk("stradis%d irq: RPS_I0\n", saa->nr));
495 }
496 if (astat & SAA7146_PSR_RPS_LATE1) {
497 IDEBUG(printk("stradis%d irq: RPS_LATE1\n", saa->nr));
498 }
499 if (astat & SAA7146_PSR_RPS_LATE0) {
500 IDEBUG(printk("stradis%d irq: RPS_LATE0\n", saa->nr));
501 }
502 if (astat & SAA7146_PSR_RPS_E1) {
503 IDEBUG(printk("stradis%d irq: RPS_E1\n", saa->nr));
504 }
505 if (astat & SAA7146_PSR_RPS_E0) {
506 IDEBUG(printk("stradis%d irq: RPS_E0\n", saa->nr));
507 }
508 if (astat & SAA7146_PSR_RPS_TO1) {
509 IDEBUG(printk("stradis%d irq: RPS_TO1\n", saa->nr));
510 }
511 if (astat & SAA7146_PSR_RPS_TO0) {
512 IDEBUG(printk("stradis%d irq: RPS_TO0\n", saa->nr));
513 }
514 if (astat & SAA7146_PSR_UPLD) {
515 IDEBUG(printk("stradis%d irq: UPLD\n", saa->nr));
516 }
517 if (astat & SAA7146_PSR_DEBI_E) {
518 IDEBUG(printk("stradis%d irq: DEBI_E\n", saa->nr));
519 }
520 if (astat & SAA7146_PSR_I2C_S) {
521 IDEBUG(printk("stradis%d irq: I2C_S\n", saa->nr));
522 }
523 if (astat & SAA7146_PSR_I2C_E) {
524 IDEBUG(printk("stradis%d irq: I2C_E\n", saa->nr));
525 }
526 if (astat & SAA7146_PSR_A2_IN) {
527 IDEBUG(printk("stradis%d irq: A2_IN\n", saa->nr));
528 }
529 if (astat & SAA7146_PSR_A2_OUT) {
530 IDEBUG(printk("stradis%d irq: A2_OUT\n", saa->nr));
531 }
532 if (astat & SAA7146_PSR_A1_IN) {
533 IDEBUG(printk("stradis%d irq: A1_IN\n", saa->nr));
534 }
535 if (astat & SAA7146_PSR_A1_OUT) {
536 IDEBUG(printk("stradis%d irq: A1_OUT\n", saa->nr));
537 }
538 if (astat & SAA7146_PSR_AFOU) {
539 IDEBUG(printk("stradis%d irq: AFOU\n", saa->nr));
540 }
541 if (astat & SAA7146_PSR_V_PE) {
542 IDEBUG(printk("stradis%d irq: V_PE\n", saa->nr));
543 }
544 if (astat & SAA7146_PSR_VFOU) {
545 IDEBUG(printk("stradis%d irq: VFOU\n", saa->nr));
546 }
547 if (astat & SAA7146_PSR_FIDA) {
548 IDEBUG(printk("stradis%d irq: FIDA\n", saa->nr));
549 }
550 if (astat & SAA7146_PSR_FIDB) {
551 IDEBUG(printk("stradis%d irq: FIDB\n", saa->nr));
552 }
553 if (astat & SAA7146_PSR_PIN3) {
554 IDEBUG(printk("stradis%d irq: PIN3\n", saa->nr));
555 }
556 if (astat & SAA7146_PSR_PIN2) {
557 IDEBUG(printk("stradis%d irq: PIN2\n", saa->nr));
558 }
559 if (astat & SAA7146_PSR_PIN0) {
560 IDEBUG(printk("stradis%d irq: PIN0\n", saa->nr));
561 }
562 if (astat & SAA7146_PSR_ECS) {
563 IDEBUG(printk("stradis%d irq: ECS\n", saa->nr));
564 }
565 if (astat & SAA7146_PSR_EC3S) {
566 IDEBUG(printk("stradis%d irq: EC3S\n", saa->nr));
567 }
568 if (astat & SAA7146_PSR_EC0S) {
569 IDEBUG(printk("stradis%d irq: EC0S\n", saa->nr));
570 }
571#endif
572 count++;
573 if (count > 15)
574 printk(KERN_WARNING "stradis%d: irq loop %d\n",
575 saa->nr, count);
576 if (count > 20) {
577 saawrite(0, SAA7146_IER);
578 printk(KERN_ERR
579 "stradis%d: IRQ loop cleared\n", saa->nr);
580 }
581 }
582 return IRQ_RETVAL(handled);
583}
584
585static int ibm_send_command(struct saa7146 *saa,
586 int command, int data, int chain)
587{
588 int i;
589
590 if (chain)
591 debiwrite(saa, debNormal, IBM_MP2_COMMAND, (command << 1)| 1,2);
592 else
593 debiwrite(saa, debNormal, IBM_MP2_COMMAND, command << 1, 2);
594 debiwrite(saa, debNormal, IBM_MP2_CMD_DATA, data, 2);
595 debiwrite(saa, debNormal, IBM_MP2_CMD_STAT, 1, 2);
596 for (i = 0; i < 100 &&
597 (debiread(saa, debNormal, IBM_MP2_CMD_STAT, 2) & 1); i++)
598 schedule();
599 if (i == 100)
600 return -1;
601 return 0;
602}
603
604static void cs4341_setlevel(struct saa7146 *saa, int left, int right)
605{
606 I2CWrite(saa, 0x22, 0x03, left > 94 ? 94 : left, 2);
607 I2CWrite(saa, 0x22, 0x04, right > 94 ? 94 : right, 2);
608}
609
610static void initialize_cs4341(struct saa7146 *saa)
611{
612 int i;
613 for (i = 0; i < 200; i++) {
614 /* auto mute off, power on, no de-emphasis */
615 /* I2S data up to 24-bit 64xFs internal SCLK */
616 I2CWrite(saa, 0x22, 0x01, 0x11, 2);
617 /* ATAPI mixer settings */
618 I2CWrite(saa, 0x22, 0x02, 0x49, 2);
619 /* attenuation left 3db */
620 I2CWrite(saa, 0x22, 0x03, 0x00, 2);
621 /* attenuation right 3db */
622 I2CWrite(saa, 0x22, 0x04, 0x00, 2);
623 I2CWrite(saa, 0x22, 0x01, 0x10, 2);
624 if (I2CRead(saa, 0x22, 0x02, 1) == 0x49)
625 break;
626 schedule();
627 }
628 printk("stradis%d: CS4341 initialized (%d)\n", saa->nr, i);
629 return;
630}
631
632static void initialize_cs8420(struct saa7146 *saa, int pro)
633{
634 int i;
635 u8 *sequence;
636 if (pro)
637 sequence = mode8420pro;
638 else
639 sequence = mode8420con;
640 for (i = 0; i < INIT8420LEN; i++)
641 I2CWrite(saa, 0x20, init8420[i * 2], init8420[i * 2 + 1], 2);
642 for (i = 0; i < MODE8420LEN; i++)
643 I2CWrite(saa, 0x20, sequence[i * 2], sequence[i * 2 + 1], 2);
644 printk("stradis%d: CS8420 initialized\n", saa->nr);
645}
646
647static void initialize_saa7121(struct saa7146 *saa, int dopal)
648{
649 int i, mod;
650 u8 *sequence;
651 if (dopal)
652 sequence = init7121pal;
653 else
654 sequence = init7121ntsc;
655 mod = saaread(SAA7146_PSR) & 0x08;
656 /* initialize PAL/NTSC video encoder */
657 for (i = 0; i < INIT7121LEN; i++) {
658 if (NewCard) { /* handle new card encoder differences */
659 if (sequence[i * 2] == 0x3a)
660 I2CWrite(saa, 0x88, 0x3a, 0x13, 2);
661 else if (sequence[i * 2] == 0x6b)
662 I2CWrite(saa, 0x88, 0x6b, 0x20, 2);
663 else if (sequence[i * 2] == 0x6c)
664 I2CWrite(saa, 0x88, 0x6c,
665 dopal ? 0x09 : 0xf5, 2);
666 else if (sequence[i * 2] == 0x6d)
667 I2CWrite(saa, 0x88, 0x6d,
668 dopal ? 0x20 : 0x00, 2);
669 else if (sequence[i * 2] == 0x7a)
670 I2CWrite(saa, 0x88, 0x7a,
671 dopal ? (PALFirstActive - 1) :
672 (NTSCFirstActive - 4), 2);
673 else if (sequence[i * 2] == 0x7b)
674 I2CWrite(saa, 0x88, 0x7b,
675 dopal ? PALLastActive :
676 NTSCLastActive, 2);
677 else
678 I2CWrite(saa, 0x88, sequence[i * 2],
679 sequence[i * 2 + 1], 2);
680 } else {
681 if (sequence[i * 2] == 0x6b && mod)
682 I2CWrite(saa, 0x88, 0x6b,
683 (sequence[i * 2 + 1] ^ 0x09), 2);
684 else if (sequence[i * 2] == 0x7a)
685 I2CWrite(saa, 0x88, 0x7a,
686 dopal ? (PALFirstActive - 1) :
687 (NTSCFirstActive - 4), 2);
688 else if (sequence[i * 2] == 0x7b)
689 I2CWrite(saa, 0x88, 0x7b,
690 dopal ? PALLastActive :
691 NTSCLastActive, 2);
692 else
693 I2CWrite(saa, 0x88, sequence[i * 2],
694 sequence[i * 2 + 1], 2);
695 }
696 }
697}
698
699static void set_genlock_offset(struct saa7146 *saa, int noffset)
700{
701 int nCode;
702 int PixelsPerLine = 858;
703 if (CurrentMode == VIDEO_MODE_PAL)
704 PixelsPerLine = 864;
705 if (noffset > 500)
706 noffset = 500;
707 else if (noffset < -500)
708 noffset = -500;
709 nCode = noffset + 0x100;
710 if (nCode == 1)
711 nCode = 0x401;
712 else if (nCode < 1)
713 nCode = 0x400 + PixelsPerLine + nCode;
714 debiwrite(saa, debNormal, XILINX_GLDELAY, nCode, 2);
715}
716
717static void set_out_format(struct saa7146 *saa, int mode)
718{
719 initialize_saa7121(saa, (mode == VIDEO_MODE_NTSC ? 0 : 1));
720 saa->boardcfg[2] = mode;
721 /* do not adjust analog video parameters here, use saa7121 init */
722 /* you will affect the SDI output on the new card */
723 if (mode == VIDEO_MODE_PAL) { /* PAL */
724 debiwrite(saa, debNormal, XILINX_CTL0, 0x0808, 2);
725 mdelay(50);
726 saawrite(0x012002c0, SAA7146_NUM_LINE_BYTE1);
727 if (NewCard) {
728 debiwrite(saa, debNormal, IBM_MP2_DISP_MODE, 0xe100, 2);
729 mdelay(50);
730 }
731 debiwrite(saa, debNormal, IBM_MP2_DISP_MODE,
732 NewCard ? 0xe500 : 0x6500, 2);
733 debiwrite(saa, debNormal, IBM_MP2_DISP_DLY,
734 (1 << 8) |
735 (NewCard ? PALFirstActive : PALFirstActive - 6), 2);
736 } else { /* NTSC */
737 debiwrite(saa, debNormal, XILINX_CTL0, 0x0800, 2);
738 mdelay(50);
739 saawrite(0x00f002c0, SAA7146_NUM_LINE_BYTE1);
740 debiwrite(saa, debNormal, IBM_MP2_DISP_MODE,
741 NewCard ? 0xe100 : 0x6100, 2);
742 debiwrite(saa, debNormal, IBM_MP2_DISP_DLY,
743 (1 << 8) |
744 (NewCard ? NTSCFirstActive : NTSCFirstActive - 6), 2);
745 }
746}
747
748/* Intialize bitmangler to map from a byte value to the mangled word that
749 * must be output to program the Xilinx part through the DEBI port.
750 * Xilinx Data Bit->DEBI Bit: 0->15 1->7 2->6 3->12 4->11 5->2 6->1 7->0
751 * transfer FPGA code, init IBM chip, transfer IBM microcode
752 * rev2 card mangles: 0->7 1->6 2->5 3->4 4->3 5->2 6->1 7->0
753 */
754static u16 bitmangler[256];
755
756static int initialize_fpga(struct video_code *bitdata)
757{
758 int i, num, startindex, failure = 0, loadtwo, loadfile = 0;
759 u16 *dmabuf;
760 u8 *newdma;
761 struct saa7146 *saa;
762
763 /* verify fpga code */
764 for (startindex = 0; startindex < bitdata->datasize; startindex++)
765 if (bitdata->data[startindex] == 255)
766 break;
767 if (startindex == bitdata->datasize) {
768 printk(KERN_INFO "stradis: bad fpga code\n");
769 return -1;
770 }
771 /* initialize all detected cards */
772 for (num = 0; num < saa_num; num++) {
773 saa = &saa7146s[num];
774 if (saa->boardcfg[0] > 20)
775 continue; /* card was programmed */
776 loadtwo = (saa->boardcfg[18] & 0x10);
777 if (!NewCard) /* we have an old board */
778 for (i = 0; i < 256; i++)
779 bitmangler[i] = ((i & 0x01) << 15) |
780 ((i & 0x02) << 6) | ((i & 0x04) << 4) |
781 ((i & 0x08) << 9) | ((i & 0x10) << 7) |
782 ((i & 0x20) >> 3) | ((i & 0x40) >> 5) |
783 ((i & 0x80) >> 7);
784 else /* else we have a new board */
785 for (i = 0; i < 256; i++)
786 bitmangler[i] = ((i & 0x01) << 7) |
787 ((i & 0x02) << 5) | ((i & 0x04) << 3) |
788 ((i & 0x08) << 1) | ((i & 0x10) >> 1) |
789 ((i & 0x20) >> 3) | ((i & 0x40) >> 5) |
790 ((i & 0x80) >> 7);
791
792 dmabuf = (u16 *) saa->dmadebi;
793 newdma = (u8 *) saa->dmadebi;
794 if (NewCard) { /* SDM2xxx */
795 if (!strncmp(bitdata->loadwhat, "decoder2", 8))
796 continue; /* fpga not for this card */
797 if (!strncmp(&saa->boardcfg[42], bitdata->loadwhat, 8))
798 loadfile = 1;
799 else if (loadtwo && !strncmp(&saa->boardcfg[19],
800 bitdata->loadwhat, 8))
801 loadfile = 2;
802 else if (!saa->boardcfg[42] && !strncmp("decxl",
803 bitdata->loadwhat, 8))
804 loadfile = 1; /* special */
805 else
806 continue; /* fpga not for this card */
807 if (loadfile != 1 && loadfile != 2)
808 continue; /* skip to next card */
809 if (saa->boardcfg[0] && loadfile == 1)
810 continue; /* skip to next card */
811 if (saa->boardcfg[0] != 1 && loadfile == 2)
812 continue; /* skip to next card */
813 saa->boardcfg[0]++; /* mark fpga handled */
814 printk("stradis%d: loading %s\n", saa->nr,
815 bitdata->loadwhat);
816 if (loadtwo && loadfile == 2)
817 goto send_fpga_stuff;
818 /* turn on the Audio interface to set PROG low */
819 saawrite(0x00400040, SAA7146_GPIO_CTRL);
820 saaread(SAA7146_PSR); /* ensure posted write */
821 /* wait for everyone to reset */
822 mdelay(10);
823 saawrite(0x00400000, SAA7146_GPIO_CTRL);
824 } else { /* original card */
825 if (strncmp(bitdata->loadwhat, "decoder2", 8))
826 continue; /* fpga not for this card */
827 /* Pull the Xilinx PROG signal WS3 low */
828 saawrite(0x02000200, SAA7146_MC1);
829 /* Turn on the Audio interface so can set PROG low */
830 saawrite(0x000000c0, SAA7146_ACON1);
831 /* Pull the Xilinx INIT signal (GPIO2) low */
832 saawrite(0x00400000, SAA7146_GPIO_CTRL);
833 /* Make sure everybody resets */
834 saaread(SAA7146_PSR); /* ensure posted write */
835 mdelay(10);
836 /* Release the Xilinx PROG signal */
837 saawrite(0x00000000, SAA7146_ACON1);
838 /* Turn off the Audio interface */
839 saawrite(0x02000000, SAA7146_MC1);
840 }
841 /* Release Xilinx INIT signal (WS2) */
842 saawrite(0x00000000, SAA7146_GPIO_CTRL);
843 /* Wait for the INIT to go High */
844 for (i = 0;
845 i < 10000 && !(saaread(SAA7146_PSR) & SAA7146_PSR_PIN2);
846 i++)
847 schedule();
848 if (i == 1000) {
849 printk(KERN_INFO "stradis%d: no fpga INIT\n", saa->nr);
850 return -1;
851 }
852send_fpga_stuff:
853 if (NewCard) {
854 for (i = startindex; i < bitdata->datasize; i++)
855 newdma[i - startindex] =
856 bitmangler[bitdata->data[i]];
857 debiwrite(saa, 0x01420000, 0, 0,
858 ((bitdata->datasize - startindex) + 5));
859 if (loadtwo && loadfile == 1) {
860 printk("stradis%d: awaiting 2nd FPGA bitfile\n",
861 saa->nr);
862 continue; /* skip to next card */
863 }
864 } else {
865 for (i = startindex; i < bitdata->datasize; i++)
866 dmabuf[i - startindex] =
867 bitmangler[bitdata->data[i]];
868 debiwrite(saa, 0x014a0000, 0, 0,
869 ((bitdata->datasize - startindex) + 5) * 2);
870 }
871 for (i = 0;
872 i < 1000 && !(saaread(SAA7146_PSR) & SAA7146_PSR_PIN2);
873 i++)
874 schedule();
875 if (i == 1000) {
876 printk(KERN_INFO "stradis%d: FPGA load failed\n",
877 saa->nr);
878 failure++;
879 continue;
880 }
881 if (!NewCard) {
882 /* Pull the Xilinx INIT signal (GPIO2) low */
883 saawrite(0x00400000, SAA7146_GPIO_CTRL);
884 saaread(SAA7146_PSR); /* ensure posted write */
885 mdelay(2);
886 saawrite(0x00000000, SAA7146_GPIO_CTRL);
887 mdelay(2);
888 }
889 printk(KERN_INFO "stradis%d: FPGA Loaded\n", saa->nr);
890 saa->boardcfg[0] = 26; /* mark fpga programmed */
891 /* set VXCO to its lowest frequency */
892 debiwrite(saa, debNormal, XILINX_PWM, 0, 2);
893 if (NewCard) {
894 /* mute CS3310 */
895 if (HaveCS3310)
896 debiwrite(saa, debNormal, XILINX_CS3310_CMPLT,
897 0, 2);
898 /* set VXCO to PWM mode, release reset, blank on */
899 debiwrite(saa, debNormal, XILINX_CTL0, 0xffc4, 2);
900 mdelay(10);
901 /* unmute CS3310 */
902 if (HaveCS3310)
903 debiwrite(saa, debNormal, XILINX_CTL0,
904 0x2020, 2);
905 }
906 /* set source Black */
907 debiwrite(saa, debNormal, XILINX_CTL0, 0x1707, 2);
908 saa->boardcfg[4] = 22; /* set NTSC First Active Line */
909 saa->boardcfg[5] = 23; /* set PAL First Active Line */
910 saa->boardcfg[54] = 2; /* set NTSC Last Active Line - 256 */
911 saa->boardcfg[55] = 54; /* set PAL Last Active Line - 256 */
912 set_out_format(saa, VIDEO_MODE_NTSC);
913 mdelay(50);
914 /* begin IBM chip init */
915 debiwrite(saa, debNormal, IBM_MP2_CHIP_CONTROL, 4, 2);
916 saaread(SAA7146_PSR); /* wait for reset */
917 mdelay(5);
918 debiwrite(saa, debNormal, IBM_MP2_CHIP_CONTROL, 0, 2);
919 debiread(saa, debNormal, IBM_MP2_CHIP_CONTROL, 2);
920 debiwrite(saa, debNormal, IBM_MP2_CHIP_CONTROL, 0x10, 2);
921 debiwrite(saa, debNormal, IBM_MP2_CMD_ADDR, 0, 2);
922 debiwrite(saa, debNormal, IBM_MP2_CHIP_MODE, 0x2e, 2);
923 if (NewCard) {
924 mdelay(5);
925 /* set i2s rate converter to 48KHz */
926 debiwrite(saa, debNormal, 0x80c0, 6, 2);
927 /* we must init CS8420 first since rev b pulls i2s */
928 /* master clock low and CS4341 needs i2s master to */
929 /* run the i2c port. */
930 if (HaveCS8420)
931 /* 0=consumer, 1=pro */
932 initialize_cs8420(saa, 0);
933
934 mdelay(5);
935 if (HaveCS4341)
936 initialize_cs4341(saa);
937 }
938 debiwrite(saa, debNormal, IBM_MP2_INFC_CTL, 0x48, 2);
939 debiwrite(saa, debNormal, IBM_MP2_BEEP_CTL, 0xa000, 2);
940 debiwrite(saa, debNormal, IBM_MP2_DISP_LBOR, 0, 2);
941 debiwrite(saa, debNormal, IBM_MP2_DISP_TBOR, 0, 2);
942 if (NewCard)
943 set_genlock_offset(saa, 0);
944 debiwrite(saa, debNormal, IBM_MP2_FRNT_ATTEN, 0, 2);
945#if 0
946 /* enable genlock */
947 debiwrite(saa, debNormal, XILINX_CTL0, 0x8000, 2);
948#else
949 /* disable genlock */
950 debiwrite(saa, debNormal, XILINX_CTL0, 0x8080, 2);
951#endif
952 }
953
954 return failure;
955}
956
957static int do_ibm_reset(struct saa7146 *saa)
958{
959 /* failure if decoder not previously programmed */
960 if (saa->boardcfg[0] < 37)
961 return -EIO;
962 /* mute CS3310 */
963 if (HaveCS3310)
964 debiwrite(saa, debNormal, XILINX_CS3310_CMPLT, 0, 2);
965 /* disable interrupts */
966 saawrite(0, SAA7146_IER);
967 saa->audhead = saa->audtail = 0;
968 saa->vidhead = saa->vidtail = 0;
969 /* tristate debi bus, disable debi transfers */
970 saawrite(0x00880000, SAA7146_MC1);
971 /* ensure posted write */
972 saaread(SAA7146_MC1);
973 mdelay(50);
974 /* re-enable debi transfers */
975 saawrite(0x00880088, SAA7146_MC1);
976 /* set source Black */
977 debiwrite(saa, debNormal, XILINX_CTL0, 0x1707, 2);
978 /* begin IBM chip init */
979 set_out_format(saa, CurrentMode);
980 debiwrite(saa, debNormal, IBM_MP2_CHIP_CONTROL, 4, 2);
981 saaread(SAA7146_PSR); /* wait for reset */
982 mdelay(5);
983 debiwrite(saa, debNormal, IBM_MP2_CHIP_CONTROL, 0, 2);
984 debiread(saa, debNormal, IBM_MP2_CHIP_CONTROL, 2);
985 debiwrite(saa, debNormal, IBM_MP2_CHIP_CONTROL, ChipControl, 2);
986 debiwrite(saa, debNormal, IBM_MP2_CHIP_MODE, 0x2e, 2);
987 if (NewCard) {
988 mdelay(5);
989 /* set i2s rate converter to 48KHz */
990 debiwrite(saa, debNormal, 0x80c0, 6, 2);
991 /* we must init CS8420 first since rev b pulls i2s */
992 /* master clock low and CS4341 needs i2s master to */
993 /* run the i2c port. */
994 if (HaveCS8420)
995 /* 0=consumer, 1=pro */
996 initialize_cs8420(saa, 1);
997
998 mdelay(5);
999 if (HaveCS4341)
1000 initialize_cs4341(saa);
1001 }
1002 debiwrite(saa, debNormal, IBM_MP2_INFC_CTL, 0x48, 2);
1003 debiwrite(saa, debNormal, IBM_MP2_BEEP_CTL, 0xa000, 2);
1004 debiwrite(saa, debNormal, IBM_MP2_DISP_LBOR, 0, 2);
1005 debiwrite(saa, debNormal, IBM_MP2_DISP_TBOR, 0, 2);
1006 if (NewCard)
1007 set_genlock_offset(saa, 0);
1008 debiwrite(saa, debNormal, IBM_MP2_FRNT_ATTEN, 0, 2);
1009 debiwrite(saa, debNormal, IBM_MP2_OSD_SIZE, 0x2000, 2);
1010 debiwrite(saa, debNormal, IBM_MP2_AUD_CTL, 0x4552, 2);
1011 if (ibm_send_command(saa, IBM_MP2_CONFIG_DECODER,
1012 (ChipControl == 0x43 ? 0xe800 : 0xe000), 1)) {
1013 printk(KERN_ERR "stradis%d: IBM config failed\n", saa->nr);
1014 }
1015 if (HaveCS3310) {
1016 int i = CS3310MaxLvl;
1017 debiwrite(saa, debNormal, XILINX_CS3310_CMPLT, ((i << 8)| i),2);
1018 }
1019 /* start video decoder */
1020 debiwrite(saa, debNormal, IBM_MP2_CHIP_CONTROL, ChipControl, 2);
1021 /* 256k vid, 3520 bytes aud */
1022 debiwrite(saa, debNormal, IBM_MP2_RB_THRESHOLD, 0x4037, 2);
1023 debiwrite(saa, debNormal, IBM_MP2_AUD_CTL, 0x4573, 2);
1024 ibm_send_command(saa, IBM_MP2_PLAY, 0, 0);
1025 /* enable buffer threshold irq */
1026 debiwrite(saa, debNormal, IBM_MP2_MASK0, 0xc00c, 2);
1027 /* clear pending interrupts */
1028 debiread(saa, debNormal, IBM_MP2_HOST_INT, 2);
1029 debiwrite(saa, debNormal, XILINX_CTL0, 0x1711, 2);
1030
1031 return 0;
1032}
1033
1034/* load the decoder microcode */
1035static int initialize_ibmmpeg2(struct video_code *microcode)
1036{
1037 int i, num;
1038 struct saa7146 *saa;
1039
1040 for (num = 0; num < saa_num; num++) {
1041 saa = &saa7146s[num];
1042 /* check that FPGA is loaded */
1043 debiwrite(saa, debNormal, IBM_MP2_OSD_SIZE, 0xa55a, 2);
1044 i = debiread(saa, debNormal, IBM_MP2_OSD_SIZE, 2);
1045 if (i != 0xa55a) {
1046 printk(KERN_INFO "stradis%d: %04x != 0xa55a\n",
1047 saa->nr, i);
1048#if 0
1049 return -1;
1050#endif
1051 }
1052 if (!strncmp(microcode->loadwhat, "decoder.vid", 11)) {
1053 if (saa->boardcfg[0] > 27)
1054 continue; /* skip to next card */
1055 /* load video control store */
1056 saa->boardcfg[1] = 0x13; /* no-sync default */
1057 debiwrite(saa, debNormal, IBM_MP2_WR_PROT, 1, 2);
1058 debiwrite(saa, debNormal, IBM_MP2_PROC_IADDR, 0, 2);
1059 for (i = 0; i < microcode->datasize / 2; i++)
1060 debiwrite(saa, debNormal, IBM_MP2_PROC_IDATA,
1061 (microcode->data[i * 2] << 8) |
1062 microcode->data[i * 2 + 1], 2);
1063 debiwrite(saa, debNormal, IBM_MP2_PROC_IADDR, 0, 2);
1064 debiwrite(saa, debNormal, IBM_MP2_WR_PROT, 0, 2);
1065 debiwrite(saa, debNormal, IBM_MP2_CHIP_CONTROL,
1066 ChipControl, 2);
1067 saa->boardcfg[0] = 28;
1068 }
1069 if (!strncmp(microcode->loadwhat, "decoder.aud", 11)) {
1070 if (saa->boardcfg[0] > 35)
1071 continue; /* skip to next card */
1072 /* load audio control store */
1073 debiwrite(saa, debNormal, IBM_MP2_WR_PROT, 1, 2);
1074 debiwrite(saa, debNormal, IBM_MP2_AUD_IADDR, 0, 2);
1075 for (i = 0; i < microcode->datasize; i++)
1076 debiwrite(saa, debNormal, IBM_MP2_AUD_IDATA,
1077 microcode->data[i], 1);
1078 debiwrite(saa, debNormal, IBM_MP2_AUD_IADDR, 0, 2);
1079 debiwrite(saa, debNormal, IBM_MP2_WR_PROT, 0, 2);
1080 debiwrite(saa, debNormal, IBM_MP2_OSD_SIZE, 0x2000, 2);
1081 debiwrite(saa, debNormal, IBM_MP2_AUD_CTL, 0x4552, 2);
1082 if (ibm_send_command(saa, IBM_MP2_CONFIG_DECODER,
1083 0xe000, 1)) {
1084 printk(KERN_ERR "stradis%d: IBM config "
1085 "failed\n", saa->nr);
1086 return -1;
1087 }
1088 /* set PWM to center value */
1089 if (NewCard) {
1090 debiwrite(saa, debNormal, XILINX_PWM,
1091 saa->boardcfg[14] +
1092 (saa->boardcfg[13] << 8), 2);
1093 } else
1094 debiwrite(saa, debNormal, XILINX_PWM, 0x46, 2);
1095
1096 if (HaveCS3310) {
1097 i = CS3310MaxLvl;
1098 debiwrite(saa, debNormal, XILINX_CS3310_CMPLT,
1099 (i << 8) | i, 2);
1100 }
1101 printk(KERN_INFO "stradis%d: IBM MPEGCD%d Inited\n",
1102 saa->nr, 18 + (debiread(saa, debNormal,
1103 IBM_MP2_CHIP_CONTROL, 2) >> 12));
1104 /* start video decoder */
1105 debiwrite(saa, debNormal, IBM_MP2_CHIP_CONTROL,
1106 ChipControl, 2);
1107 debiwrite(saa, debNormal, IBM_MP2_RB_THRESHOLD, 0x4037,
1108 2); /* 256k vid, 3520 bytes aud */
1109 debiwrite(saa, debNormal, IBM_MP2_AUD_CTL, 0x4573, 2);
1110 ibm_send_command(saa, IBM_MP2_PLAY, 0, 0);
1111 /* enable buffer threshold irq */
1112 debiwrite(saa, debNormal, IBM_MP2_MASK0, 0xc00c, 2);
1113 debiread(saa, debNormal, IBM_MP2_HOST_INT, 2);
1114 /* enable gpio irq */
1115 saawrite(0x00002000, SAA7146_GPIO_CTRL);
1116 /* enable decoder output to HPS */
1117 debiwrite(saa, debNormal, XILINX_CTL0, 0x1711, 2);
1118 saa->boardcfg[0] = 37;
1119 }
1120 }
1121
1122 return 0;
1123}
1124
1125static u32 palette2fmt[] = { /* some of these YUV translations are wrong */
1126 0xffffffff, 0x86000000, 0x87000000, 0x80000000, 0x8100000, 0x82000000,
1127 0x83000000, 0x00000000, 0x03000000, 0x03000000, 0x0a00000, 0x03000000,
1128 0x06000000, 0x00000000, 0x03000000, 0x0a000000, 0x0300000
1129};
1130static int bpp2fmt[4] = {
1131 VIDEO_PALETTE_HI240, VIDEO_PALETTE_RGB565, VIDEO_PALETTE_RGB24,
1132 VIDEO_PALETTE_RGB32
1133};
1134
1135/* I wish I could find a formula to calculate these... */
1136static u32 h_prescale[64] = {
1137 0x10000000, 0x18040202, 0x18080000, 0x380c0606, 0x38100204, 0x38140808,
1138 0x38180000, 0x381c0000, 0x3820161c, 0x38242a3b, 0x38281230, 0x382c4460,
1139 0x38301040, 0x38340080, 0x38380000, 0x383c0000, 0x3840fefe, 0x3844ee9f,
1140 0x3848ee9f, 0x384cee9f, 0x3850ee9f, 0x38542a3b, 0x38581230, 0x385c0000,
1141 0x38600000, 0x38640000, 0x38680000, 0x386c0000, 0x38700000, 0x38740000,
1142 0x38780000, 0x387c0000, 0x30800000, 0x38840000, 0x38880000, 0x388c0000,
1143 0x38900000, 0x38940000, 0x38980000, 0x389c0000, 0x38a00000, 0x38a40000,
1144 0x38a80000, 0x38ac0000, 0x38b00000, 0x38b40000, 0x38b80000, 0x38bc0000,
1145 0x38c00000, 0x38c40000, 0x38c80000, 0x38cc0000, 0x38d00000, 0x38d40000,
1146 0x38d80000, 0x38dc0000, 0x38e00000, 0x38e40000, 0x38e80000, 0x38ec0000,
1147 0x38f00000, 0x38f40000, 0x38f80000, 0x38fc0000,
1148};
1149static u32 v_gain[64] = {
1150 0x016000ff, 0x016100ff, 0x016100ff, 0x016200ff, 0x016200ff, 0x016200ff,
1151 0x016200ff, 0x016300ff, 0x016300ff, 0x016300ff, 0x016300ff, 0x016300ff,
1152 0x016300ff, 0x016300ff, 0x016300ff, 0x016400ff, 0x016400ff, 0x016400ff,
1153 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff,
1154 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff,
1155 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff,
1156 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff,
1157 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff,
1158 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff,
1159 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff,
1160 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff,
1161};
1162
1163static void saa7146_set_winsize(struct saa7146 *saa)
1164{
1165 u32 format;
1166 int offset, yacl, ysci;
1167 saa->win.color_fmt = format =
1168 (saa->win.depth == 15) ? palette2fmt[VIDEO_PALETTE_RGB555] :
1169 palette2fmt[bpp2fmt[(saa->win.bpp - 1) & 3]];
1170 offset = saa->win.x * saa->win.bpp + saa->win.y * saa->win.bpl;
1171 saawrite(saa->win.vidadr + offset, SAA7146_BASE_EVEN1);
1172 saawrite(saa->win.vidadr + offset + saa->win.bpl, SAA7146_BASE_ODD1);
1173 saawrite(saa->win.bpl * 2, SAA7146_PITCH1);
1174 saawrite(saa->win.vidadr + saa->win.bpl * saa->win.sheight,
1175 SAA7146_PROT_ADDR1);
1176 saawrite(0, SAA7146_PAGE1);
1177 saawrite(format | 0x60, SAA7146_CLIP_FORMAT_CTRL);
1178 offset = (704 / (saa->win.width - 1)) & 0x3f;
1179 saawrite(h_prescale[offset], SAA7146_HPS_H_PRESCALE);
1180 offset = (720896 / saa->win.width) / (offset + 1);
1181 saawrite((offset << 12) | 0x0c, SAA7146_HPS_H_SCALE);
1182 if (CurrentMode == VIDEO_MODE_NTSC) {
1183 yacl = /*(480 / saa->win.height - 1) & 0x3f */ 0;
1184 ysci = 1024 - (saa->win.height * 1024 / 480);
1185 } else {
1186 yacl = /*(576 / saa->win.height - 1) & 0x3f */ 0;
1187 ysci = 1024 - (saa->win.height * 1024 / 576);
1188 }
1189 saawrite((1 << 31) | (ysci << 21) | (yacl << 15), SAA7146_HPS_V_SCALE);
1190 saawrite(v_gain[yacl], SAA7146_HPS_V_GAIN);
1191 saawrite(((SAA7146_MC2_UPLD_DMA1 | SAA7146_MC2_UPLD_HPS_V |
1192 SAA7146_MC2_UPLD_HPS_H) << 16) | (SAA7146_MC2_UPLD_DMA1 |
1193 SAA7146_MC2_UPLD_HPS_V | SAA7146_MC2_UPLD_HPS_H), SAA7146_MC2);
1194}
1195
1196/* clip_draw_rectangle(cm,x,y,w,h) -- handle clipping an area
1197 * bitmap is fixed width, 128 bytes (1024 pixels represented)
1198 * arranged most-sigificant-bit-left in 32-bit words
1199 * based on saa7146 clipping hardware, it swaps bytes if LE
1200 * much of this makes up for egcs brain damage -- so if you
1201 * are wondering "why did he do this?" it is because the C
1202 * was adjusted to generate the optimal asm output without
1203 * writing non-portable __asm__ directives.
1204 */
1205
1206static void clip_draw_rectangle(u32 *clipmap, int x, int y, int w, int h)
1207{
1208 register int startword, endword;
1209 register u32 bitsleft, bitsright;
1210 u32 *temp;
1211 if (x < 0) {
1212 w += x;
1213 x = 0;
1214 }
1215 if (y < 0) {
1216 h += y;
1217 y = 0;
1218 }
1219 if (w <= 0 || h <= 0 || x > 1023 || y > 639)
1220 return; /* throw away bad clips */
1221 if (x + w > 1024)
1222 w = 1024 - x;
1223 if (y + h > 640)
1224 h = 640 - y;
1225 startword = (x >> 5);
1226 endword = ((x + w) >> 5);
1227 bitsleft = (0xffffffff >> (x & 31));
1228 bitsright = (0xffffffff << (~((x + w) - (endword << 5))));
1229 temp = &clipmap[(y << 5) + startword];
1230 w = endword - startword;
1231 if (!w) {
1232 bitsleft |= bitsright;
1233 for (y = 0; y < h; y++) {
1234 *temp |= bitsleft;
1235 temp += 32;
1236 }
1237 } else {
1238 for (y = 0; y < h; y++) {
1239 *temp++ |= bitsleft;
1240 for (x = 1; x < w; x++)
1241 *temp++ = 0xffffffff;
1242 *temp |= bitsright;
1243 temp += (32 - w);
1244 }
1245 }
1246}
1247
1248static void make_clip_tab(struct saa7146 *saa, struct video_clip *cr, int ncr)
1249{
1250 int i, width, height;
1251 u32 *clipmap;
1252
1253 clipmap = saa->dmavid2;
1254 if ((width = saa->win.width) > 1023)
1255 width = 1023; /* sanity check */
1256 if ((height = saa->win.height) > 640)
1257 height = 639; /* sanity check */
1258 if (ncr > 0) { /* rectangles pased */
1259 /* convert rectangular clips to a bitmap */
1260 memset(clipmap, 0, VIDEO_CLIPMAP_SIZE); /* clear map */
1261 for (i = 0; i < ncr; i++)
1262 clip_draw_rectangle(clipmap, cr[i].x, cr[i].y,
1263 cr[i].width, cr[i].height);
1264 }
1265 /* clip against viewing window AND screen
1266 so we do not have to rely on the user program
1267 */
1268 clip_draw_rectangle(clipmap, (saa->win.x + width > saa->win.swidth) ?
1269 (saa->win.swidth - saa->win.x) : width, 0, 1024, 768);
1270 clip_draw_rectangle(clipmap, 0,
1271 (saa->win.y + height > saa->win.sheight) ?
1272 (saa->win.sheight - saa->win.y) : height, 1024, 768);
1273 if (saa->win.x < 0)
1274 clip_draw_rectangle(clipmap, 0, 0, -saa->win.x, 768);
1275 if (saa->win.y < 0)
1276 clip_draw_rectangle(clipmap, 0, 0, 1024, -saa->win.y);
1277}
1278
1279static long saa_ioctl(struct file *file,
1280 unsigned int cmd, unsigned long argl)
1281{
1282 struct saa7146 *saa = file->private_data;
1283 void __user *arg = (void __user *)argl;
1284
1285 switch (cmd) {
1286 case VIDIOCGCAP:
1287 {
1288 struct video_capability b;
1289 memset(&b, 0, sizeof(b));
1290 strcpy(b.name, saa->video_dev.name);
1291 b.type = VID_TYPE_CAPTURE | VID_TYPE_OVERLAY |
1292 VID_TYPE_CLIPPING | VID_TYPE_FRAMERAM |
1293 VID_TYPE_SCALES;
1294 b.channels = 1;
1295 b.audios = 1;
1296 b.maxwidth = 768;
1297 b.maxheight = 576;
1298 b.minwidth = 32;
1299 b.minheight = 32;
1300 if (copy_to_user(arg, &b, sizeof(b)))
1301 return -EFAULT;
1302 return 0;
1303 }
1304 case VIDIOCGPICT:
1305 {
1306 struct video_picture p = saa->picture;
1307 if (saa->win.depth == 8)
1308 p.palette = VIDEO_PALETTE_HI240;
1309 if (saa->win.depth == 15)
1310 p.palette = VIDEO_PALETTE_RGB555;
1311 if (saa->win.depth == 16)
1312 p.palette = VIDEO_PALETTE_RGB565;
1313 if (saa->win.depth == 24)
1314 p.palette = VIDEO_PALETTE_RGB24;
1315 if (saa->win.depth == 32)
1316 p.palette = VIDEO_PALETTE_RGB32;
1317 if (copy_to_user(arg, &p, sizeof(p)))
1318 return -EFAULT;
1319 return 0;
1320 }
1321 case VIDIOCSPICT:
1322 {
1323 struct video_picture p;
1324 u32 format;
1325 if (copy_from_user(&p, arg, sizeof(p)))
1326 return -EFAULT;
1327 if (p.palette < ARRAY_SIZE(palette2fmt)) {
1328 format = palette2fmt[p.palette];
1329 saa->win.color_fmt = format;
1330 saawrite(format | 0x60,
1331 SAA7146_CLIP_FORMAT_CTRL);
1332 }
1333 saawrite(((p.brightness & 0xff00) << 16) |
1334 ((p.contrast & 0xfe00) << 7) |
1335 ((p.colour & 0xfe00) >> 9), SAA7146_BCS_CTRL);
1336 saa->picture = p;
1337 /* upload changed registers */
1338 saawrite(((SAA7146_MC2_UPLD_HPS_H |
1339 SAA7146_MC2_UPLD_HPS_V) << 16) |
1340 SAA7146_MC2_UPLD_HPS_H |
1341 SAA7146_MC2_UPLD_HPS_V, SAA7146_MC2);
1342 return 0;
1343 }
1344 case VIDIOCSWIN:
1345 {
1346 struct video_window vw;
1347 struct video_clip *vcp = NULL;
1348
1349 if (copy_from_user(&vw, arg, sizeof(vw)))
1350 return -EFAULT;
1351
1352 /* stop capture */
1353 if (vw.flags || vw.width < 16 || vw.height < 16) {
1354 saawrite((SAA7146_MC1_TR_E_1 << 16),
1355 SAA7146_MC1);
1356 return -EINVAL;
1357 }
1358 /* 32-bit align start and adjust width */
1359 if (saa->win.bpp < 4) {
1360 int i = vw.x;
1361 vw.x = (vw.x + 3) & ~3;
1362 i = vw.x - i;
1363 vw.width -= i;
1364 }
1365 saa->win.x = vw.x;
1366 saa->win.y = vw.y;
1367 saa->win.width = vw.width;
1368 if (saa->win.width > 768)
1369 saa->win.width = 768;
1370 saa->win.height = vw.height;
1371 if (CurrentMode == VIDEO_MODE_NTSC) {
1372 if (saa->win.height > 480)
1373 saa->win.height = 480;
1374 } else {
1375 if (saa->win.height > 576)
1376 saa->win.height = 576;
1377 }
1378
1379 /* stop capture */
1380 saawrite((SAA7146_MC1_TR_E_1 << 16), SAA7146_MC1);
1381 saa7146_set_winsize(saa);
1382
1383 /*
1384 * Do any clips.
1385 */
1386 if (vw.clipcount < 0) {
1387 if (copy_from_user(saa->dmavid2, vw.clips,
1388 VIDEO_CLIPMAP_SIZE))
1389 return -EFAULT;
1390 } else if (vw.clipcount > 16384) {
1391 return -EINVAL;
1392 } else if (vw.clipcount > 0) {
1393 vcp = vmalloc(sizeof(struct video_clip) *
1394 vw.clipcount);
1395 if (vcp == NULL)
1396 return -ENOMEM;
1397 if (copy_from_user(vcp, vw.clips,
1398 sizeof(struct video_clip) *
1399 vw.clipcount)) {
1400 vfree(vcp);
1401 return -EFAULT;
1402 }
1403 } else /* nothing clipped */
1404 memset(saa->dmavid2, 0, VIDEO_CLIPMAP_SIZE);
1405
1406 make_clip_tab(saa, vcp, vw.clipcount);
1407 if (vw.clipcount > 0)
1408 vfree(vcp);
1409
1410 /* start capture & clip dma if we have an address */
1411 if ((saa->cap & 3) && saa->win.vidadr != 0)
1412 saawrite(((SAA7146_MC1_TR_E_1 |
1413 SAA7146_MC1_TR_E_2) << 16) | 0xffff,
1414 SAA7146_MC1);
1415 return 0;
1416 }
1417 case VIDIOCGWIN:
1418 {
1419 struct video_window vw;
1420 memset(&vw, 0, sizeof(vw));
1421 vw.x = saa->win.x;
1422 vw.y = saa->win.y;
1423 vw.width = saa->win.width;
1424 vw.height = saa->win.height;
1425 vw.chromakey = 0;
1426 vw.flags = 0;
1427 if (copy_to_user(arg, &vw, sizeof(vw)))
1428 return -EFAULT;
1429 return 0;
1430 }
1431 case VIDIOCCAPTURE:
1432 {
1433 int v;
1434 if (copy_from_user(&v, arg, sizeof(v)))
1435 return -EFAULT;
1436 if (v == 0) {
1437 saa->cap &= ~1;
1438 saawrite((SAA7146_MC1_TR_E_1 << 16),
1439 SAA7146_MC1);
1440 } else {
1441 if (saa->win.vidadr == 0 || saa->win.width == 0
1442 || saa->win.height == 0)
1443 return -EINVAL;
1444 saa->cap |= 1;
1445 saawrite((SAA7146_MC1_TR_E_1 << 16) | 0xffff,
1446 SAA7146_MC1);
1447 }
1448 return 0;
1449 }
1450 case VIDIOCGFBUF:
1451 {
1452 struct video_buffer v;
1453 memset(&v, 0, sizeof(v));
1454 v.base = (void *)saa->win.vidadr;
1455 v.height = saa->win.sheight;
1456 v.width = saa->win.swidth;
1457 v.depth = saa->win.depth;
1458 v.bytesperline = saa->win.bpl;
1459 if (copy_to_user(arg, &v, sizeof(v)))
1460 return -EFAULT;
1461 return 0;
1462
1463 }
1464 case VIDIOCSFBUF:
1465 {
1466 struct video_buffer v;
1467 if (!capable(CAP_SYS_ADMIN))
1468 return -EPERM;
1469 if (copy_from_user(&v, arg, sizeof(v)))
1470 return -EFAULT;
1471 if (v.depth != 8 && v.depth != 15 && v.depth != 16 &&
1472 v.depth != 24 && v.depth != 32 && v.width > 16 &&
1473 v.height > 16 && v.bytesperline > 16)
1474 return -EINVAL;
1475 if (v.base)
1476 saa->win.vidadr = (unsigned long)v.base;
1477 saa->win.sheight = v.height;
1478 saa->win.swidth = v.width;
1479 saa->win.bpp = ((v.depth + 7) & 0x38) / 8;
1480 saa->win.depth = v.depth;
1481 saa->win.bpl = v.bytesperline;
1482
1483 DEBUG(printk("Display at %p is %d by %d, bytedepth %d, "
1484 "bpl %d\n", v.base, v.width, v.height,
1485 saa->win.bpp, saa->win.bpl));
1486 saa7146_set_winsize(saa);
1487 return 0;
1488 }
1489 case VIDIOCKEY:
1490 {
1491 /* Will be handled higher up .. */
1492 return 0;
1493 }
1494
1495 case VIDIOCGAUDIO:
1496 {
1497 struct video_audio v;
1498 memset(&v, 0, sizeof(v));
1499 v = saa->audio_dev;
1500 v.flags &= ~(VIDEO_AUDIO_MUTE | VIDEO_AUDIO_MUTABLE);
1501 v.flags |= VIDEO_AUDIO_MUTABLE | VIDEO_AUDIO_VOLUME;
1502 strcpy(v.name, "MPEG");
1503 v.mode = VIDEO_SOUND_STEREO;
1504 if (copy_to_user(arg, &v, sizeof(v)))
1505 return -EFAULT;
1506 return 0;
1507 }
1508 case VIDIOCSAUDIO:
1509 {
1510 struct video_audio v;
1511 int i;
1512 if (copy_from_user(&v, arg, sizeof(v)))
1513 return -EFAULT;
1514 i = (~(v.volume >> 8)) & 0xff;
1515 if (!HaveCS4341) {
1516 if (v.flags & VIDEO_AUDIO_MUTE)
1517 debiwrite(saa, debNormal,
1518 IBM_MP2_FRNT_ATTEN, 0xffff, 2);
1519 if (!(v.flags & VIDEO_AUDIO_MUTE))
1520 debiwrite(saa, debNormal,
1521 IBM_MP2_FRNT_ATTEN, 0x0000, 2);
1522 if (v.flags & VIDEO_AUDIO_VOLUME)
1523 debiwrite(saa, debNormal,
1524 IBM_MP2_FRNT_ATTEN,
1525 (i << 8) | i, 2);
1526 } else {
1527 if (v.flags & VIDEO_AUDIO_MUTE)
1528 cs4341_setlevel(saa, 0xff, 0xff);
1529 if (!(v.flags & VIDEO_AUDIO_MUTE))
1530 cs4341_setlevel(saa, 0, 0);
1531 if (v.flags & VIDEO_AUDIO_VOLUME)
1532 cs4341_setlevel(saa, i, i);
1533 }
1534 saa->audio_dev = v;
1535 return 0;
1536 }
1537
1538 case VIDIOCGUNIT:
1539 {
1540 struct video_unit vu;
1541 memset(&vu, 0, sizeof(vu));
1542 vu.video = saa->video_dev.minor;
1543 vu.vbi = VIDEO_NO_UNIT;
1544 vu.radio = VIDEO_NO_UNIT;
1545 vu.audio = VIDEO_NO_UNIT;
1546 vu.teletext = VIDEO_NO_UNIT;
1547 if (copy_to_user(arg, &vu, sizeof(vu)))
1548 return -EFAULT;
1549 return 0;
1550 }
1551 case VIDIOCSPLAYMODE:
1552 {
1553 struct video_play_mode pmode;
1554 if (copy_from_user((void *)&pmode, arg,
1555 sizeof(struct video_play_mode)))
1556 return -EFAULT;
1557 switch (pmode.mode) {
1558 case VID_PLAY_VID_OUT_MODE:
1559 if (pmode.p1 != VIDEO_MODE_NTSC &&
1560 pmode.p1 != VIDEO_MODE_PAL)
1561 return -EINVAL;
1562 set_out_format(saa, pmode.p1);
1563 return 0;
1564 case VID_PLAY_GENLOCK:
1565 debiwrite(saa, debNormal, XILINX_CTL0,
1566 pmode.p1 ? 0x8000 : 0x8080, 2);
1567 if (NewCard)
1568 set_genlock_offset(saa, pmode.p2);
1569 return 0;
1570 case VID_PLAY_NORMAL:
1571 debiwrite(saa, debNormal,
1572 IBM_MP2_CHIP_CONTROL, ChipControl, 2);
1573 ibm_send_command(saa, IBM_MP2_PLAY, 0, 0);
1574 saa->playmode = pmode.mode;
1575 return 0;
1576 case VID_PLAY_PAUSE:
1577 /* IBM removed the PAUSE command */
1578 /* they say use SINGLE_FRAME now */
1579 case VID_PLAY_SINGLE_FRAME:
1580 ibm_send_command(saa, IBM_MP2_SINGLE_FRAME,0,0);
1581 if (saa->playmode == pmode.mode) {
1582 debiwrite(saa, debNormal,
1583 IBM_MP2_CHIP_CONTROL,
1584 ChipControl, 2);
1585 }
1586 saa->playmode = pmode.mode;
1587 return 0;
1588 case VID_PLAY_FAST_FORWARD:
1589 ibm_send_command(saa, IBM_MP2_FAST_FORWARD,0,0);
1590 saa->playmode = pmode.mode;
1591 return 0;
1592 case VID_PLAY_SLOW_MOTION:
1593 ibm_send_command(saa, IBM_MP2_SLOW_MOTION,
1594 pmode.p1, 0);
1595 saa->playmode = pmode.mode;
1596 return 0;
1597 case VID_PLAY_IMMEDIATE_NORMAL:
1598 /* ensure transfers resume */
1599 debiwrite(saa, debNormal,
1600 IBM_MP2_CHIP_CONTROL, ChipControl, 2);
1601 ibm_send_command(saa, IBM_MP2_IMED_NORM_PLAY,
1602 0, 0);
1603 saa->playmode = VID_PLAY_NORMAL;
1604 return 0;
1605 case VID_PLAY_SWITCH_CHANNELS:
1606 saa->audhead = saa->audtail = 0;
1607 saa->vidhead = saa->vidtail = 0;
1608 ibm_send_command(saa, IBM_MP2_FREEZE_FRAME,0,1);
1609 ibm_send_command(saa, IBM_MP2_RESET_AUD_RATE,
1610 0, 1);
1611 debiwrite(saa, debNormal, IBM_MP2_CHIP_CONTROL,
1612 0, 2);
1613 ibm_send_command(saa, IBM_MP2_CHANNEL_SWITCH,
1614 0, 1);
1615 debiwrite(saa, debNormal, IBM_MP2_CHIP_CONTROL,
1616 ChipControl, 2);
1617 ibm_send_command(saa, IBM_MP2_PLAY, 0, 0);
1618 saa->playmode = VID_PLAY_NORMAL;
1619 return 0;
1620 case VID_PLAY_FREEZE_FRAME:
1621 ibm_send_command(saa, IBM_MP2_FREEZE_FRAME,0,0);
1622 saa->playmode = pmode.mode;
1623 return 0;
1624 case VID_PLAY_STILL_MODE:
1625 ibm_send_command(saa, IBM_MP2_SET_STILL_MODE,
1626 0, 0);
1627 saa->playmode = pmode.mode;
1628 return 0;
1629 case VID_PLAY_MASTER_MODE:
1630 if (pmode.p1 == VID_PLAY_MASTER_NONE)
1631 saa->boardcfg[1] = 0x13;
1632 else if (pmode.p1 == VID_PLAY_MASTER_VIDEO)
1633 saa->boardcfg[1] = 0x23;
1634 else if (pmode.p1 == VID_PLAY_MASTER_AUDIO)
1635 saa->boardcfg[1] = 0x43;
1636 else
1637 return -EINVAL;
1638 debiwrite(saa, debNormal,
1639 IBM_MP2_CHIP_CONTROL, ChipControl, 2);
1640 return 0;
1641 case VID_PLAY_ACTIVE_SCANLINES:
1642 if (CurrentMode == VIDEO_MODE_PAL) {
1643 if (pmode.p1 < 1 || pmode.p2 > 625)
1644 return -EINVAL;
1645 saa->boardcfg[5] = pmode.p1;
1646 saa->boardcfg[55] = (pmode.p1 +
1647 (pmode.p2 / 2) - 1) & 0xff;
1648 } else {
1649 if (pmode.p1 < 4 || pmode.p2 > 525)
1650 return -EINVAL;
1651 saa->boardcfg[4] = pmode.p1;
1652 saa->boardcfg[54] = (pmode.p1 +
1653 (pmode.p2 / 2) - 4) & 0xff;
1654 }
1655 set_out_format(saa, CurrentMode);
1656 case VID_PLAY_RESET:
1657 return do_ibm_reset(saa);
1658 case VID_PLAY_END_MARK:
1659 if (saa->endmarktail < saa->endmarkhead) {
1660 if (saa->endmarkhead -
1661 saa->endmarktail < 2)
1662 return -ENOSPC;
1663 } else if (saa->endmarkhead <=saa->endmarktail){
1664 if (saa->endmarktail - saa->endmarkhead
1665 > (MAX_MARKS - 2))
1666 return -ENOSPC;
1667 } else
1668 return -ENOSPC;
1669 saa->endmark[saa->endmarktail] = saa->audtail;
1670 saa->endmarktail++;
1671 if (saa->endmarktail >= MAX_MARKS)
1672 saa->endmarktail = 0;
1673 }
1674 return -EINVAL;
1675 }
1676 case VIDIOCSWRITEMODE:
1677 {
1678 int mode;
1679 if (copy_from_user((void *)&mode, arg, sizeof(int)))
1680 return -EFAULT;
1681 if (mode == VID_WRITE_MPEG_AUD ||
1682 mode == VID_WRITE_MPEG_VID ||
1683 mode == VID_WRITE_CC ||
1684 mode == VID_WRITE_TTX ||
1685 mode == VID_WRITE_OSD) {
1686 saa->writemode = mode;
1687 return 0;
1688 }
1689 return -EINVAL;
1690 }
1691 case VIDIOCSMICROCODE:
1692 {
1693 struct video_code ucode;
1694 __u8 *udata;
1695 int i;
1696 if (copy_from_user(&ucode, arg, sizeof(ucode)))
1697 return -EFAULT;
1698 if (ucode.datasize > 65536 || ucode.datasize < 1024 ||
1699 strncmp(ucode.loadwhat, "dec", 3))
1700 return -EINVAL;
1701 if ((udata = vmalloc(ucode.datasize)) == NULL)
1702 return -ENOMEM;
1703 if (copy_from_user(udata, ucode.data, ucode.datasize)) {
1704 vfree(udata);
1705 return -EFAULT;
1706 }
1707 ucode.data = udata;
1708 if (!strncmp(ucode.loadwhat, "decoder.aud", 11) ||
1709 !strncmp(ucode.loadwhat, "decoder.vid", 11))
1710 i = initialize_ibmmpeg2(&ucode);
1711 else
1712 i = initialize_fpga(&ucode);
1713 vfree(udata);
1714 if (i)
1715 return -EINVAL;
1716 return 0;
1717
1718 }
1719 case VIDIOCGCHAN: /* this makes xawtv happy */
1720 {
1721 struct video_channel v;
1722 if (copy_from_user(&v, arg, sizeof(v)))
1723 return -EFAULT;
1724 v.flags = VIDEO_VC_AUDIO;
1725 v.tuners = 0;
1726 v.type = VID_TYPE_MPEG_DECODER;
1727 v.norm = CurrentMode;
1728 strcpy(v.name, "MPEG2");
1729 if (copy_to_user(arg, &v, sizeof(v)))
1730 return -EFAULT;
1731 return 0;
1732 }
1733 case VIDIOCSCHAN: /* this makes xawtv happy */
1734 {
1735 struct video_channel v;
1736 if (copy_from_user(&v, arg, sizeof(v)))
1737 return -EFAULT;
1738 /* do nothing */
1739 return 0;
1740 }
1741 default:
1742 return -ENOIOCTLCMD;
1743 }
1744 return 0;
1745}
1746
1747static int saa_mmap(struct file *file, struct vm_area_struct *vma)
1748{
1749 struct saa7146 *saa = file->private_data;
1750 printk(KERN_DEBUG "stradis%d: saa_mmap called\n", saa->nr);
1751 return -EINVAL;
1752}
1753
1754static ssize_t saa_read(struct file *file, char __user * buf,
1755 size_t count, loff_t * ppos)
1756{
1757 return -EINVAL;
1758}
1759
1760static ssize_t saa_write(struct file *file, const char __user * buf,
1761 size_t count, loff_t * ppos)
1762{
1763 struct saa7146 *saa = file->private_data;
1764 unsigned long todo = count;
1765 int blocksize, split;
1766 unsigned long flags;
1767
1768 while (todo > 0) {
1769 if (saa->writemode == VID_WRITE_MPEG_AUD) {
1770 spin_lock_irqsave(&saa->lock, flags);
1771 if (saa->audhead <= saa->audtail)
1772 blocksize = 65536 -
1773 (saa->audtail - saa->audhead);
1774 else
1775 blocksize = saa->audhead - saa->audtail;
1776 spin_unlock_irqrestore(&saa->lock, flags);
1777 if (blocksize < 16384) {
1778 saawrite(SAA7146_PSR_DEBI_S |
1779 SAA7146_PSR_PIN1, SAA7146_IER);
1780 saawrite(SAA7146_PSR_PIN1, SAA7146_PSR);
1781 /* wait for buffer space to open */
1782 interruptible_sleep_on(&saa->audq);
1783 }
1784 spin_lock_irqsave(&saa->lock, flags);
1785 if (saa->audhead <= saa->audtail) {
1786 blocksize = 65536 -
1787 (saa->audtail - saa->audhead);
1788 split = 65536 - saa->audtail;
1789 } else {
1790 blocksize = saa->audhead - saa->audtail;
1791 split = 65536;
1792 }
1793 spin_unlock_irqrestore(&saa->lock, flags);
1794 blocksize--;
1795 if (blocksize > todo)
1796 blocksize = todo;
1797 /* double check that we really have space */
1798 if (!blocksize)
1799 return -ENOSPC;
1800 if (split < blocksize) {
1801 if (copy_from_user(saa->audbuf +
1802 saa->audtail, buf, split))
1803 return -EFAULT;
1804 buf += split;
1805 todo -= split;
1806 blocksize -= split;
1807 saa->audtail = 0;
1808 }
1809 if (copy_from_user(saa->audbuf + saa->audtail, buf,
1810 blocksize))
1811 return -EFAULT;
1812 saa->audtail += blocksize;
1813 todo -= blocksize;
1814 buf += blocksize;
1815 saa->audtail &= 0xffff;
1816 } else if (saa->writemode == VID_WRITE_MPEG_VID) {
1817 spin_lock_irqsave(&saa->lock, flags);
1818 if (saa->vidhead <= saa->vidtail)
1819 blocksize = 524288 -
1820 (saa->vidtail - saa->vidhead);
1821 else
1822 blocksize = saa->vidhead - saa->vidtail;
1823 spin_unlock_irqrestore(&saa->lock, flags);
1824 if (blocksize < 65536) {
1825 saawrite(SAA7146_PSR_DEBI_S |
1826 SAA7146_PSR_PIN1, SAA7146_IER);
1827 saawrite(SAA7146_PSR_PIN1, SAA7146_PSR);
1828 /* wait for buffer space to open */
1829 interruptible_sleep_on(&saa->vidq);
1830 }
1831 spin_lock_irqsave(&saa->lock, flags);
1832 if (saa->vidhead <= saa->vidtail) {
1833 blocksize = 524288 -
1834 (saa->vidtail - saa->vidhead);
1835 split = 524288 - saa->vidtail;
1836 } else {
1837 blocksize = saa->vidhead - saa->vidtail;
1838 split = 524288;
1839 }
1840 spin_unlock_irqrestore(&saa->lock, flags);
1841 blocksize--;
1842 if (blocksize > todo)
1843 blocksize = todo;
1844 /* double check that we really have space */
1845 if (!blocksize)
1846 return -ENOSPC;
1847 if (split < blocksize) {
1848 if (copy_from_user(saa->vidbuf +
1849 saa->vidtail, buf, split))
1850 return -EFAULT;
1851 buf += split;
1852 todo -= split;
1853 blocksize -= split;
1854 saa->vidtail = 0;
1855 }
1856 if (copy_from_user(saa->vidbuf + saa->vidtail, buf,
1857 blocksize))
1858 return -EFAULT;
1859 saa->vidtail += blocksize;
1860 todo -= blocksize;
1861 buf += blocksize;
1862 saa->vidtail &= 0x7ffff;
1863 } else if (saa->writemode == VID_WRITE_OSD) {
1864 if (count > 131072)
1865 return -ENOSPC;
1866 if (copy_from_user(saa->osdbuf, buf, count))
1867 return -EFAULT;
1868 buf += count;
1869 saa->osdhead = 0;
1870 saa->osdtail = count;
1871 debiwrite(saa, debNormal, IBM_MP2_OSD_ADDR, 0, 2);
1872 debiwrite(saa, debNormal, IBM_MP2_OSD_LINK_ADDR, 0, 2);
1873 debiwrite(saa, debNormal, IBM_MP2_MASK0, 0xc00d, 2);
1874 debiwrite(saa, debNormal, IBM_MP2_DISP_MODE,
1875 debiread(saa, debNormal,
1876 IBM_MP2_DISP_MODE, 2) | 1, 2);
1877 /* trigger osd data transfer */
1878 saawrite(SAA7146_PSR_DEBI_S |
1879 SAA7146_PSR_PIN1, SAA7146_IER);
1880 saawrite(SAA7146_PSR_PIN1, SAA7146_PSR);
1881 }
1882 }
1883 return count;
1884}
1885
1886static int saa_open(struct file *file)
1887{
1888 struct video_device *vdev = video_devdata(file);
1889 struct saa7146 *saa = container_of(vdev, struct saa7146, video_dev);
1890
1891 lock_kernel();
1892 file->private_data = saa;
1893
1894 saa->user++;
1895 if (saa->user > 1) {
1896 saa->user--;
1897 unlock_kernel();
1898 return 0; /* device open already, don't reset */
1899 }
1900 saa->writemode = VID_WRITE_MPEG_VID; /* default to video */
1901 unlock_kernel();
1902 return 0;
1903}
1904
1905static int saa_release(struct file *file)
1906{
1907 struct saa7146 *saa = file->private_data;
1908 saa->user--;
1909
1910 if (saa->user > 0) /* still someone using device */
1911 return 0;
1912 saawrite(0x007f0000, SAA7146_MC1); /* stop all overlay dma */
1913 return 0;
1914}
1915
1916static const struct v4l2_file_operations saa_fops = {
1917 .owner = THIS_MODULE,
1918 .open = saa_open,
1919 .release = saa_release,
1920 .ioctl = saa_ioctl,
1921 .read = saa_read,
1922 .write = saa_write,
1923 .mmap = saa_mmap,
1924};
1925
1926/* template for video_device-structure */
1927static struct video_device saa_template = {
1928 .name = "SAA7146A",
1929 .fops = &saa_fops,
1930 .release = video_device_release_empty,
1931};
1932
1933static int __devinit configure_saa7146(struct pci_dev *pdev, int num)
1934{
1935 int retval;
1936 struct saa7146 *saa = pci_get_drvdata(pdev);
1937
1938 saa->endmarkhead = saa->endmarktail = 0;
1939 saa->win.x = saa->win.y = 0;
1940 saa->win.width = saa->win.cropwidth = 720;
1941 saa->win.height = saa->win.cropheight = 480;
1942 saa->win.cropx = saa->win.cropy = 0;
1943 saa->win.bpp = 2;
1944 saa->win.depth = 16;
1945 saa->win.color_fmt = palette2fmt[VIDEO_PALETTE_RGB565];
1946 saa->win.bpl = 1024 * saa->win.bpp;
1947 saa->win.swidth = 1024;
1948 saa->win.sheight = 768;
1949 saa->picture.brightness = 32768;
1950 saa->picture.contrast = 38768;
1951 saa->picture.colour = 32768;
1952 saa->cap = 0;
1953 saa->nr = num;
1954 saa->playmode = VID_PLAY_NORMAL;
1955 memset(saa->boardcfg, 0, 64); /* clear board config area */
1956 saa->saa7146_mem = NULL;
1957 saa->dmavid1 = saa->dmavid2 = saa->dmavid3 = saa->dmaa1in =
1958 saa->dmaa1out = saa->dmaa2in = saa->dmaa2out =
1959 saa->pagevid1 = saa->pagevid2 = saa->pagevid3 = saa->pagea1in =
1960 saa->pagea1out = saa->pagea2in = saa->pagea2out =
1961 saa->pagedebi = saa->dmaRPS1 = saa->dmaRPS2 = saa->pageRPS1 =
1962 saa->pageRPS2 = NULL;
1963 saa->audbuf = saa->vidbuf = saa->osdbuf = saa->dmadebi = NULL;
1964 saa->audhead = saa->vidtail = 0;
1965
1966 init_waitqueue_head(&saa->i2cq);
1967 init_waitqueue_head(&saa->audq);
1968 init_waitqueue_head(&saa->debiq);
1969 init_waitqueue_head(&saa->vidq);
1970 spin_lock_init(&saa->lock);
1971
1972 retval = pci_enable_device(pdev);
1973 if (retval) {
1974 dev_err(&pdev->dev, "%d: pci_enable_device failed!\n", num);
1975 goto err;
1976 }
1977
1978 saa->id = pdev->device;
1979 saa->irq = pdev->irq;
1980 saa->saa7146_adr = pci_resource_start(pdev, 0);
1981 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &saa->revision);
1982
1983 saa->saa7146_mem = ioremap(saa->saa7146_adr, 0x200);
1984 if (saa->saa7146_mem == NULL) {
1985 dev_err(&pdev->dev, "%d: ioremap failed!\n", num);
1986 retval = -EIO;
1987 goto err;
1988 }
1989
1990 memcpy(&saa->video_dev, &saa_template, sizeof(saa_template));
1991 saawrite(0, SAA7146_IER); /* turn off all interrupts */
1992
1993 retval = request_irq(saa->irq, saa7146_irq, IRQF_SHARED | IRQF_DISABLED,
1994 "stradis", saa);
1995 if (retval == -EINVAL)
1996 dev_err(&pdev->dev, "%d: Bad irq number or handler\n", num);
1997 else if (retval == -EBUSY)
1998 dev_err(&pdev->dev, "%d: IRQ %ld busy, change your PnP config "
1999 "in BIOS\n", num, saa->irq);
2000 if (retval < 0)
2001 goto errio;
2002
2003 pci_set_master(pdev);
2004 retval = video_register_device(&saa->video_dev, VFL_TYPE_GRABBER,
2005 video_nr);
2006 if (retval < 0) {
2007 dev_err(&pdev->dev, "%d: error in registering video device!\n",
2008 num);
2009 goto errirq;
2010 }
2011
2012 return 0;
2013
2014errirq:
2015 free_irq(saa->irq, saa);
2016errio:
2017 iounmap(saa->saa7146_mem);
2018err:
2019 return retval;
2020}
2021
2022static int __devinit init_saa7146(struct pci_dev *pdev)
2023{
2024 struct saa7146 *saa = pci_get_drvdata(pdev);
2025
2026 saa->user = 0;
2027 /* reset the saa7146 */
2028 saawrite(0xffff0000, SAA7146_MC1);
2029 mdelay(5);
2030 /* enable debi and i2c transfers and pins */
2031 saawrite(((SAA7146_MC1_EDP | SAA7146_MC1_EI2C |
2032 SAA7146_MC1_TR_E_DEBI) << 16) | 0xffff, SAA7146_MC1);
2033 /* ensure proper state of chip */
2034 saawrite(0x00000000, SAA7146_PAGE1);
2035 saawrite(0x00f302c0, SAA7146_NUM_LINE_BYTE1);
2036 saawrite(0x00000000, SAA7146_PAGE2);
2037 saawrite(0x01400080, SAA7146_NUM_LINE_BYTE2);
2038 saawrite(0x00000000, SAA7146_DD1_INIT);
2039 saawrite(0x00000000, SAA7146_DD1_STREAM_B);
2040 saawrite(0x00000000, SAA7146_DD1_STREAM_A);
2041 saawrite(0x00000000, SAA7146_BRS_CTRL);
2042 saawrite(0x80400040, SAA7146_BCS_CTRL);
2043 saawrite(0x0000e000 /*| (1<<29) */ , SAA7146_HPS_CTRL);
2044 saawrite(0x00000060, SAA7146_CLIP_FORMAT_CTRL);
2045 saawrite(0x00000000, SAA7146_ACON1);
2046 saawrite(0x00000000, SAA7146_ACON2);
2047 saawrite(0x00000600, SAA7146_I2C_STATUS);
2048 saawrite(((SAA7146_MC2_UPLD_D1_B | SAA7146_MC2_UPLD_D1_A |
2049 SAA7146_MC2_UPLD_BRS | SAA7146_MC2_UPLD_HPS_H |
2050 SAA7146_MC2_UPLD_HPS_V | SAA7146_MC2_UPLD_DMA2 |
2051 SAA7146_MC2_UPLD_DMA1 | SAA7146_MC2_UPLD_I2C) << 16) | 0xffff,
2052 SAA7146_MC2);
2053 /* setup arbitration control registers */
2054 saawrite(0x1412121a, SAA7146_PCI_BT_V1);
2055
2056 /* allocate 32k dma buffer + 4k for page table */
2057 if ((saa->dmadebi = kmalloc(32768 + 4096, GFP_KERNEL)) == NULL) {
2058 dev_err(&pdev->dev, "%d: debi kmalloc failed\n", saa->nr);
2059 goto err;
2060 }
2061#if 0
2062 saa->pagedebi = saa->dmadebi + 32768; /* top 4k is for mmu */
2063 saawrite(virt_to_bus(saa->pagedebi) /*|0x800 */ , SAA7146_DEBI_PAGE);
2064 for (i = 0; i < 12; i++) /* setup mmu page table */
2065 saa->pagedebi[i] = virt_to_bus((saa->dmadebi + i * 4096));
2066#endif
2067 saa->audhead = saa->vidhead = saa->osdhead = 0;
2068 saa->audtail = saa->vidtail = saa->osdtail = 0;
2069 if (saa->vidbuf == NULL && (saa->vidbuf = vmalloc(524288)) == NULL) {
2070 dev_err(&pdev->dev, "%d: malloc failed\n", saa->nr);
2071 goto err;
2072 }
2073 if (saa->audbuf == NULL && (saa->audbuf = vmalloc(65536)) == NULL) {
2074 dev_err(&pdev->dev, "%d: malloc failed\n", saa->nr);
2075 goto errfree;
2076 }
2077 if (saa->osdbuf == NULL && (saa->osdbuf = vmalloc(131072)) == NULL) {
2078 dev_err(&pdev->dev, "%d: malloc failed\n", saa->nr);
2079 goto errfree;
2080 }
2081 /* allocate 81920 byte buffer for clipping */
2082 if ((saa->dmavid2 = kzalloc(VIDEO_CLIPMAP_SIZE, GFP_KERNEL)) == NULL) {
2083 dev_err(&pdev->dev, "%d: clip kmalloc failed\n", saa->nr);
2084 goto errfree;
2085 }
2086 /* setup clipping registers */
2087 saawrite(virt_to_bus(saa->dmavid2), SAA7146_BASE_EVEN2);
2088 saawrite(virt_to_bus(saa->dmavid2) + 128, SAA7146_BASE_ODD2);
2089 saawrite(virt_to_bus(saa->dmavid2) + VIDEO_CLIPMAP_SIZE,
2090 SAA7146_PROT_ADDR2);
2091 saawrite(256, SAA7146_PITCH2);
2092 saawrite(4, SAA7146_PAGE2); /* dma direction: read, no byteswap */
2093 saawrite(((SAA7146_MC2_UPLD_DMA2) << 16) | SAA7146_MC2_UPLD_DMA2,
2094 SAA7146_MC2);
2095 I2CBusScan(saa);
2096
2097 return 0;
2098errfree:
2099 vfree(saa->osdbuf);
2100 vfree(saa->audbuf);
2101 vfree(saa->vidbuf);
2102 saa->audbuf = saa->osdbuf = saa->vidbuf = NULL;
2103err:
2104 return -ENOMEM;
2105}
2106
2107static void stradis_release_saa(struct pci_dev *pdev)
2108{
2109 u8 command;
2110 struct saa7146 *saa = pci_get_drvdata(pdev);
2111
2112 /* turn off all capturing, DMA and IRQs */
2113 saawrite(0xffff0000, SAA7146_MC1); /* reset chip */
2114 saawrite(0, SAA7146_MC2);
2115 saawrite(0, SAA7146_IER);
2116 saawrite(0xffffffffUL, SAA7146_ISR);
2117
2118 /* disable PCI bus-mastering */
2119 pci_read_config_byte(pdev, PCI_COMMAND, &command);
2120 command &= ~PCI_COMMAND_MASTER;
2121 pci_write_config_byte(pdev, PCI_COMMAND, command);
2122
2123 /* unmap and free memory */
2124 saa->audhead = saa->audtail = saa->osdhead = 0;
2125 saa->vidhead = saa->vidtail = saa->osdtail = 0;
2126 vfree(saa->vidbuf);
2127 vfree(saa->audbuf);
2128 vfree(saa->osdbuf);
2129 kfree(saa->dmavid2);
2130 saa->audbuf = saa->vidbuf = saa->osdbuf = NULL;
2131 saa->dmavid2 = NULL;
2132 kfree(saa->dmadebi);
2133 kfree(saa->dmavid1);
2134 kfree(saa->dmavid3);
2135 kfree(saa->dmaa1in);
2136 kfree(saa->dmaa1out);
2137 kfree(saa->dmaa2in);
2138 kfree(saa->dmaa2out);
2139 kfree(saa->dmaRPS1);
2140 kfree(saa->dmaRPS2);
2141 free_irq(saa->irq, saa);
2142 if (saa->saa7146_mem)
2143 iounmap(saa->saa7146_mem);
2144 if (video_is_registered(&saa->video_dev))
2145 video_unregister_device(&saa->video_dev);
2146}
2147
2148static int __devinit stradis_probe(struct pci_dev *pdev,
2149 const struct pci_device_id *ent)
2150{
2151 int retval = -EINVAL;
2152
2153 if (saa_num >= SAA7146_MAX)
2154 goto err;
2155
2156 if (!pdev->subsystem_vendor)
2157 dev_info(&pdev->dev, "%d: rev1 decoder\n", saa_num);
2158 else
2159 dev_info(&pdev->dev, "%d: SDM2xx found\n", saa_num);
2160
2161 pci_set_drvdata(pdev, &saa7146s[saa_num]);
2162
2163 retval = configure_saa7146(pdev, saa_num);
2164 if (retval) {
2165 dev_err(&pdev->dev, "%d: error in configuring\n", saa_num);
2166 goto err;
2167 }
2168
2169 if (init_saa7146(pdev) < 0) {
2170 dev_err(&pdev->dev, "%d: error in initialization\n", saa_num);
2171 retval = -EIO;
2172 goto errrel;
2173 }
2174
2175 saa_num++;
2176
2177 return 0;
2178errrel:
2179 stradis_release_saa(pdev);
2180err:
2181 return retval;
2182}
2183
2184static void __devexit stradis_remove(struct pci_dev *pdev)
2185{
2186 stradis_release_saa(pdev);
2187}
2188
2189static struct pci_device_id stradis_pci_tbl[] = {
2190 { PCI_DEVICE(PCI_VENDOR_ID_PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7146) },
2191 { 0 }
2192};
2193
2194
2195static struct pci_driver stradis_driver = {
2196 .name = "stradis",
2197 .id_table = stradis_pci_tbl,
2198 .probe = stradis_probe,
2199 .remove = __devexit_p(stradis_remove)
2200};
2201
2202static int __init stradis_init(void)
2203{
2204 int retval;
2205
2206 saa_num = 0;
2207
2208 retval = pci_register_driver(&stradis_driver);
2209 if (retval)
2210 printk(KERN_ERR "stradis: Unable to register pci driver.\n");
2211
2212 return retval;
2213}
2214
2215static void __exit stradis_exit(void)
2216{
2217 pci_unregister_driver(&stradis_driver);
2218 printk(KERN_INFO "stradis: module cleanup complete\n");
2219}
2220
2221module_init(stradis_init);
2222module_exit(stradis_exit);