aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video')
-rw-r--r--drivers/media/video/Kconfig360
-rw-r--r--drivers/media/video/Makefile56
-rw-r--r--drivers/media/video/adv7170.c535
-rw-r--r--drivers/media/video/adv7175.c585
-rw-r--r--drivers/media/video/arv.c916
-rw-r--r--drivers/media/video/bt819.c660
-rw-r--r--drivers/media/video/bt832.c271
-rw-r--r--drivers/media/video/bt832.h305
-rw-r--r--drivers/media/video/bt848.h366
-rw-r--r--drivers/media/video/bt856.c442
-rw-r--r--drivers/media/video/btcx-risc.c262
-rw-r--r--drivers/media/video/btcx-risc.h35
-rw-r--r--drivers/media/video/bttv-cards.c4350
-rw-r--r--drivers/media/video/bttv-driver.c4116
-rw-r--r--drivers/media/video/bttv-gpio.c190
-rw-r--r--drivers/media/video/bttv-i2c.c461
-rw-r--r--drivers/media/video/bttv-if.c160
-rw-r--r--drivers/media/video/bttv-risc.c802
-rw-r--r--drivers/media/video/bttv-vbi.c235
-rw-r--r--drivers/media/video/bttv.h338
-rw-r--r--drivers/media/video/bttvp.h399
-rw-r--r--drivers/media/video/bw-qcam.c1027
-rw-r--r--drivers/media/video/bw-qcam.h68
-rw-r--r--drivers/media/video/c-qcam.c855
-rw-r--r--drivers/media/video/cpia.c4073
-rw-r--r--drivers/media/video/cpia.h430
-rw-r--r--drivers/media/video/cpia_pp.c886
-rw-r--r--drivers/media/video/cpia_usb.c662
-rw-r--r--drivers/media/video/cs8420.h50
-rw-r--r--drivers/media/video/cx88/Makefile11
-rw-r--r--drivers/media/video/cx88/cx88-blackbird.c911
-rw-r--r--drivers/media/video/cx88/cx88-cards.c938
-rw-r--r--drivers/media/video/cx88/cx88-core.c1239
-rw-r--r--drivers/media/video/cx88/cx88-dvb.c381
-rw-r--r--drivers/media/video/cx88/cx88-i2c.c213
-rw-r--r--drivers/media/video/cx88/cx88-input.c396
-rw-r--r--drivers/media/video/cx88/cx88-mpeg.c466
-rw-r--r--drivers/media/video/cx88/cx88-reg.h787
-rw-r--r--drivers/media/video/cx88/cx88-tvaudio.c1032
-rw-r--r--drivers/media/video/cx88/cx88-vbi.c248
-rw-r--r--drivers/media/video/cx88/cx88-video.c2277
-rw-r--r--drivers/media/video/cx88/cx88.h551
-rw-r--r--drivers/media/video/dpc7146.c401
-rw-r--r--drivers/media/video/hexium_gemini.c556
-rw-r--r--drivers/media/video/hexium_orion.c522
-rw-r--r--drivers/media/video/ibmmpeg2.h94
-rw-r--r--drivers/media/video/ir-kbd-gpio.c444
-rw-r--r--drivers/media/video/ir-kbd-i2c.c492
-rw-r--r--drivers/media/video/meye.c2041
-rw-r--r--drivers/media/video/meye.h318
-rw-r--r--drivers/media/video/msp3400.c1876
-rw-r--r--drivers/media/video/msp3400.h36
-rw-r--r--drivers/media/video/mt20xx.c558
-rw-r--r--drivers/media/video/mxb.c1035
-rw-r--r--drivers/media/video/mxb.h42
-rw-r--r--drivers/media/video/ovcamchip/Makefile4
-rw-r--r--drivers/media/video/ovcamchip/ov6x20.c415
-rw-r--r--drivers/media/video/ovcamchip/ov6x30.c374
-rw-r--r--drivers/media/video/ovcamchip/ov76be.c303
-rw-r--r--drivers/media/video/ovcamchip/ov7x10.c335
-rw-r--r--drivers/media/video/ovcamchip/ov7x20.c455
-rw-r--r--drivers/media/video/ovcamchip/ovcamchip_core.c444
-rw-r--r--drivers/media/video/ovcamchip/ovcamchip_priv.h87
-rw-r--r--drivers/media/video/planb.c2303
-rw-r--r--drivers/media/video/planb.h231
-rw-r--r--drivers/media/video/pms.c1060
-rw-r--r--drivers/media/video/saa5246a.c843
-rw-r--r--drivers/media/video/saa5246a.h364
-rw-r--r--drivers/media/video/saa5249.c725
-rw-r--r--drivers/media/video/saa7110.c623
-rw-r--r--drivers/media/video/saa7111.c627
-rw-r--r--drivers/media/video/saa7114.c1241
-rw-r--r--drivers/media/video/saa7121.h132
-rw-r--r--drivers/media/video/saa7134/Makefile11
-rw-r--r--drivers/media/video/saa7134/saa6752hs.c543
-rw-r--r--drivers/media/video/saa7134/saa7134-cards.c2018
-rw-r--r--drivers/media/video/saa7134/saa7134-core.c1237
-rw-r--r--drivers/media/video/saa7134/saa7134-dvb.c266
-rw-r--r--drivers/media/video/saa7134/saa7134-empress.c436
-rw-r--r--drivers/media/video/saa7134/saa7134-i2c.c453
-rw-r--r--drivers/media/video/saa7134/saa7134-input.c491
-rw-r--r--drivers/media/video/saa7134/saa7134-oss.c857
-rw-r--r--drivers/media/video/saa7134/saa7134-reg.h366
-rw-r--r--drivers/media/video/saa7134/saa7134-ts.c243
-rw-r--r--drivers/media/video/saa7134/saa7134-tvaudio.c1031
-rw-r--r--drivers/media/video/saa7134/saa7134-vbi.c270
-rw-r--r--drivers/media/video/saa7134/saa7134-video.c2406
-rw-r--r--drivers/media/video/saa7134/saa7134.h618
-rw-r--r--drivers/media/video/saa7146.h115
-rw-r--r--drivers/media/video/saa7146reg.h283
-rw-r--r--drivers/media/video/saa7185.c524
-rw-r--r--drivers/media/video/saa7196.h117
-rw-r--r--drivers/media/video/stradis.c2258
-rw-r--r--drivers/media/video/tda7432.c556
-rw-r--r--drivers/media/video/tda8290.c224
-rw-r--r--drivers/media/video/tda9840.c254
-rw-r--r--drivers/media/video/tda9840.h35
-rw-r--r--drivers/media/video/tda9875.c423
-rw-r--r--drivers/media/video/tda9887.c801
-rw-r--r--drivers/media/video/tea6415c.c223
-rw-r--r--drivers/media/video/tea6415c.h39
-rw-r--r--drivers/media/video/tea6420.c200
-rw-r--r--drivers/media/video/tea6420.h17
-rw-r--r--drivers/media/video/tuner-3036.c220
-rw-r--r--drivers/media/video/tuner-core.c443
-rw-r--r--drivers/media/video/tuner-simple.c474
-rw-r--r--drivers/media/video/tvaudio.c1740
-rw-r--r--drivers/media/video/tvaudio.h14
-rw-r--r--drivers/media/video/tveeprom.c587
-rw-r--r--drivers/media/video/tvmixer.c367
-rw-r--r--drivers/media/video/v4l1-compat.c1036
-rw-r--r--drivers/media/video/v4l2-common.c282
-rw-r--r--drivers/media/video/video-buf-dvb.c251
-rw-r--r--drivers/media/video/video-buf.c1290
-rw-r--r--drivers/media/video/videocodec.c490
-rw-r--r--drivers/media/video/videocodec.h358
-rw-r--r--drivers/media/video/videodev.c436
-rw-r--r--drivers/media/video/vino.c347
-rw-r--r--drivers/media/video/vino.h131
-rw-r--r--drivers/media/video/vpx3220.c754
-rw-r--r--drivers/media/video/w9966.c984
-rw-r--r--drivers/media/video/zoran.h515
-rw-r--r--drivers/media/video/zoran_card.c1583
-rw-r--r--drivers/media/video/zoran_card.h45
-rw-r--r--drivers/media/video/zoran_device.c1785
-rw-r--r--drivers/media/video/zoran_device.h91
-rw-r--r--drivers/media/video/zoran_driver.c4699
-rw-r--r--drivers/media/video/zoran_procfs.c233
-rw-r--r--drivers/media/video/zoran_procfs.h36
-rw-r--r--drivers/media/video/zr36016.c532
-rw-r--r--drivers/media/video/zr36016.h111
-rw-r--r--drivers/media/video/zr36050.c907
-rw-r--r--drivers/media/video/zr36050.h184
-rw-r--r--drivers/media/video/zr36057.h168
-rw-r--r--drivers/media/video/zr36060.c1016
-rw-r--r--drivers/media/video/zr36060.h220
-rw-r--r--drivers/media/video/zr36120.c2073
-rw-r--r--drivers/media/video/zr36120.h279
-rw-r--r--drivers/media/video/zr36120_i2c.c132
-rw-r--r--drivers/media/video/zr36120_mem.c79
-rw-r--r--drivers/media/video/zr36120_mem.h3
141 files changed, 94536 insertions, 0 deletions
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
new file mode 100644
index 00000000000..c1b3542dad8
--- /dev/null
+++ b/drivers/media/video/Kconfig
@@ -0,0 +1,360 @@
1#
2# Multimedia Video device configuration
3#
4
5menu "Video For Linux"
6 depends on VIDEO_DEV
7
8comment "Video Adapters"
9
10config VIDEO_BT848
11 tristate "BT848 Video For Linux"
12 depends on VIDEO_DEV && PCI && I2C
13 select I2C_ALGOBIT
14 select FW_LOADER
15 select VIDEO_BTCX
16 select VIDEO_BUF
17 select VIDEO_IR
18 select VIDEO_TUNER
19 select VIDEO_TVEEPROM
20 ---help---
21 Support for BT848 based frame grabber/overlay boards. This includes
22 the Miro, Hauppauge and STB boards. Please read the material in
23 <file:Documentation/video4linux/bttv/> for more information.
24
25 If you say Y or M here, you need to say Y or M to "I2C support" and
26 "I2C bit-banging interfaces" in the device drivers section.
27
28 To compile this driver as a module, choose M here: the
29 module will be called bttv.
30
31config VIDEO_PMS
32 tristate "Mediavision Pro Movie Studio Video For Linux"
33 depends on VIDEO_DEV && ISA
34 help
35 Say Y if you have such a thing.
36
37 To compile this driver as a module, choose M here: the
38 module will be called pms.
39
40config VIDEO_PLANB
41 tristate "PlanB Video-In on PowerMac"
42 depends on PPC_PMAC && VIDEO_DEV && BROKEN
43 help
44 PlanB is the V4L driver for the PowerMac 7x00/8x00 series video
45 input hardware. If you want to experiment with this, say Y.
46 Otherwise, or if you don't understand a word, say N. See
47 <http://www.cpu.lu/~mlan/linux/dev/planb.html> for more info.
48
49 Saying M will compile this driver as a module (planb).
50
51config VIDEO_BWQCAM
52 tristate "Quickcam BW Video For Linux"
53 depends on VIDEO_DEV && PARPORT
54 help
55 Say Y have if you the black and white version of the QuickCam
56 camera. See the next option for the color version.
57
58 To compile this driver as a module, choose M here: the
59 module will be called bw-qcam.
60
61config VIDEO_CQCAM
62 tristate "QuickCam Colour Video For Linux (EXPERIMENTAL)"
63 depends on EXPERIMENTAL && VIDEO_DEV && PARPORT
64 help
65 This is the video4linux driver for the colour version of the
66 Connectix QuickCam. If you have one of these cameras, say Y here,
67 otherwise say N. This driver does not work with the original
68 monochrome QuickCam, QuickCam VC or QuickClip. It is also available
69 as a module (c-qcam).
70 Read <file:Documentation/video4linux/CQcam.txt> for more information.
71
72config VIDEO_W9966
73 tristate "W9966CF Webcam (FlyCam Supra and others) Video For Linux"
74 depends on PARPORT_1284 && VIDEO_DEV && PARPORT
75 help
76 Video4linux driver for Winbond's w9966 based Webcams.
77 Currently tested with the LifeView FlyCam Supra.
78 If you have one of these cameras, say Y here
79 otherwise say N.
80 This driver is also available as a module (w9966).
81
82 Check out <file:Documentation/video4linux/w9966.txt> for more
83 information.
84
85config VIDEO_CPIA
86 tristate "CPiA Video For Linux"
87 depends on VIDEO_DEV
88 ---help---
89 This is the video4linux driver for cameras based on Vision's CPiA
90 (Colour Processor Interface ASIC), such as the Creative Labs Video
91 Blaster Webcam II. If you have one of these cameras, say Y here
92 and select parallel port and/or USB lowlevel support below,
93 otherwise say N. This will not work with the Creative Webcam III.
94
95 Please read <file:Documentation/video4linux/README.cpia> for more
96 information.
97
98 This driver is also available as a module (cpia).
99
100config VIDEO_CPIA_PP
101 tristate "CPiA Parallel Port Lowlevel Support"
102 depends on PARPORT_1284 && VIDEO_CPIA && PARPORT
103 help
104 This is the lowlevel parallel port support for cameras based on
105 Vision's CPiA (Colour Processor Interface ASIC), such as the
106 Creative Webcam II. If you have the parallel port version of one
107 of these cameras, say Y here, otherwise say N. It is also available
108 as a module (cpia_pp).
109
110config VIDEO_CPIA_USB
111 tristate "CPiA USB Lowlevel Support"
112 depends on VIDEO_CPIA && USB
113 help
114 This is the lowlevel USB support for cameras based on Vision's CPiA
115 (Colour Processor Interface ASIC), such as the Creative Webcam II.
116 If you have the USB version of one of these cameras, say Y here,
117 otherwise say N. This will not work with the Creative Webcam III.
118 It is also available as a module (cpia_usb).
119
120config VIDEO_SAA5246A
121 tristate "SAA5246A, SAA5281 Teletext processor"
122 depends on VIDEO_DEV && I2C
123 help
124 Support for I2C bus based teletext using the SAA5246A or SAA5281
125 chip. Useful only if you live in Europe.
126
127 To compile this driver as a module, choose M here: the
128 module will be called saa5246a.
129
130config VIDEO_SAA5249
131 tristate "SAA5249 Teletext processor"
132 depends on VIDEO_DEV && I2C
133 help
134 Support for I2C bus based teletext using the SAA5249 chip. At the
135 moment this is only useful on some European WinTV cards.
136
137 To compile this driver as a module, choose M here: the
138 module will be called saa5249.
139
140config TUNER_3036
141 tristate "SAB3036 tuner"
142 depends on VIDEO_DEV && I2C
143 help
144 Say Y here to include support for Philips SAB3036 compatible tuners.
145 If in doubt, say N.
146
147config VIDEO_VINO
148 tristate "SGI Vino Video For Linux (EXPERIMENTAL)"
149 depends on VIDEO_DEV && I2C && SGI_IP22 && EXPERIMENTAL
150 select I2C_ALGO_SGI
151 help
152 Say Y here to build in support for the Vino video input system found
153 on SGI Indy machines.
154
155config VIDEO_STRADIS
156 tristate "Stradis 4:2:2 MPEG-2 video driver (EXPERIMENTAL)"
157 depends on EXPERIMENTAL && VIDEO_DEV && PCI
158 help
159 Say Y here to enable support for the Stradis 4:2:2 MPEG-2 video
160 driver for PCI. There is a product page at
161 <http://www.stradis.com/decoder.html>.
162
163config VIDEO_ZORAN
164 tristate "Zoran ZR36057/36067 Video For Linux"
165 depends on VIDEO_DEV && PCI && I2C_ALGOBIT
166 help
167 Say Y for support for MJPEG capture cards based on the Zoran
168 36057/36067 PCI controller chipset. This includes the Iomega
169 Buz, Pinnacle DC10+ and the Linux Media Labs LML33. There is
170 a driver homepage at <http://mjpeg.sf.net/driver-zoran/>. For
171 more information, check <file:Documentation/video4linux/Zoran>.
172
173 To compile this driver as a module, choose M here: the
174 module will be called zr36067.
175
176config VIDEO_ZORAN_BUZ
177 tristate "Iomega Buz support"
178 depends on VIDEO_ZORAN
179 help
180 Support for the Iomega Buz MJPEG capture/playback card.
181
182config VIDEO_ZORAN_DC10
183 tristate "Pinnacle/Miro DC10(+) support"
184 depends on VIDEO_ZORAN
185 help
186 Support for the Pinnacle/Miro DC10(+) MJPEG capture/playback
187 card.
188
189config VIDEO_ZORAN_DC30
190 tristate "Pinnacle/Miro DC30(+) support"
191 depends on VIDEO_ZORAN
192 help
193 Support for the Pinnacle/Miro DC30(+) MJPEG capture/playback
194 card. This also supports really old DC10 cards based on the
195 zr36050 MJPEG codec and zr36016 VFE.
196
197config VIDEO_ZORAN_LML33
198 tristate "Linux Media Labs LML33 support"
199 depends on VIDEO_ZORAN
200 help
201 Support for the Linux Media Labs LML33 MJPEG capture/playback
202 card.
203
204config VIDEO_ZORAN_LML33R10
205 tristate "Linux Media Labs LML33R10 support"
206 depends on VIDEO_ZORAN
207 help
208 support for the Linux Media Labs LML33R10 MJPEG capture/playback
209 card.
210
211config VIDEO_ZR36120
212 tristate "Zoran ZR36120/36125 Video For Linux"
213 depends on VIDEO_DEV && PCI && I2C && BROKEN
214 help
215 Support for ZR36120/ZR36125 based frame grabber/overlay boards.
216 This includes the Victor II, WaveWatcher, Video Wonder, Maxi-TV,
217 and Buster boards. Please read the material in
218 <file:Documentation/video4linux/zr36120.txt> for more information.
219
220 To compile this driver as a module, choose M here: the
221 module will be called zr36120.
222
223config VIDEO_MEYE
224 tristate "Sony Vaio Picturebook Motion Eye Video For Linux"
225 depends on VIDEO_DEV && PCI && SONYPI
226 ---help---
227 This is the video4linux driver for the Motion Eye camera found
228 in the Vaio Picturebook laptops. Please read the material in
229 <file:Documentation/video4linux/meye.txt> for more information.
230
231 If you say Y or M here, you need to say Y or M to "Sony Programmable
232 I/O Control Device" in the character device section.
233
234 To compile this driver as a module, choose M here: the
235 module will be called meye.
236
237config VIDEO_SAA7134
238 tristate "Philips SAA7134 support"
239 depends on VIDEO_DEV && PCI && I2C
240 select VIDEO_BUF
241 select VIDEO_IR
242 select VIDEO_TUNER
243 ---help---
244 This is a video4linux driver for Philips SAA7130/7134 based
245 TV cards.
246
247 To compile this driver as a module, choose M here: the
248 module will be called saa7134.
249
250config VIDEO_SAA7134_DVB
251 tristate "DVB Support for saa7134 based TV cards"
252 depends on VIDEO_SAA7134 && DVB_CORE
253 select VIDEO_BUF_DVB
254 select DVB_MT352
255 ---help---
256 This adds support for DVB cards based on the
257 Philips saa7134 chip.
258
259config VIDEO_MXB
260 tristate "Siemens-Nixdorf 'Multimedia eXtension Board'"
261 depends on VIDEO_DEV && PCI
262 select VIDEO_SAA7146_VV
263 select VIDEO_TUNER
264 ---help---
265 This is a video4linux driver for the 'Multimedia eXtension Board'
266 TV card by Siemens-Nixdorf.
267
268 To compile this driver as a module, choose M here: the
269 module will be called mxb.
270
271config VIDEO_DPC
272 tristate "Philips-Semiconductors 'dpc7146 demonstration board'"
273 depends on VIDEO_DEV && PCI
274 select VIDEO_SAA7146_VV
275 ---help---
276 This is a video4linux driver for the 'dpc7146 demonstration
277 board' by Philips-Semiconductors. It's the reference design
278 for SAA7146 bases boards, so if you have some unsupported
279 saa7146 based, analog video card, chances are good that it
280 will work with this skeleton driver.
281
282 To compile this driver as a module, choose M here: the
283 module will be called dpc7146.
284
285config VIDEO_HEXIUM_ORION
286 tristate "Hexium HV-PCI6 and Orion frame grabber"
287 depends on VIDEO_DEV && PCI
288 select VIDEO_SAA7146_VV
289 ---help---
290 This is a video4linux driver for the Hexium HV-PCI6 and
291 Orion frame grabber cards by Hexium.
292
293 To compile this driver as a module, choose M here: the
294 module will be called hexium_orion.
295
296config VIDEO_HEXIUM_GEMINI
297 tristate "Hexium Gemini frame grabber"
298 depends on VIDEO_DEV && PCI
299 select VIDEO_SAA7146_VV
300 ---help---
301 This is a video4linux driver for the Hexium Gemini frame
302 grabber card by Hexium. Please note that the Gemini Dual
303 card is *not* fully supported.
304
305 To compile this driver as a module, choose M here: the
306 module will be called hexium_gemini.
307
308config VIDEO_CX88
309 tristate "Conexant 2388x (bt878 successor) support"
310 depends on VIDEO_DEV && PCI && I2C && EXPERIMENTAL
311 select I2C_ALGOBIT
312 select FW_LOADER
313 select VIDEO_BTCX
314 select VIDEO_BUF
315 select VIDEO_TUNER
316 select VIDEO_TVEEPROM
317 select VIDEO_IR
318 ---help---
319 This is a video4linux driver for Conexant 2388x based
320 TV cards.
321
322 To compile this driver as a module, choose M here: the
323 module will be called cx8800
324
325config VIDEO_CX88_DVB
326 tristate "DVB Support for cx2388x based TV cards"
327 depends on VIDEO_CX88 && DVB_CORE
328 select VIDEO_BUF_DVB
329 select DVB_MT352
330 select DVB_OR51132
331 ---help---
332 This adds support for DVB/ATSC cards based on the
333 Connexant 2388x chip.
334
335config VIDEO_OVCAMCHIP
336 tristate "OmniVision Camera Chip support"
337 depends on VIDEO_DEV && I2C
338 ---help---
339 Support for the OmniVision OV6xxx and OV7xxx series of camera chips.
340 This driver is intended to be used with the ov511 and w9968cf USB
341 camera drivers.
342
343 To compile this driver as a module, choose M here: the
344 module will be called ovcamchip
345
346config VIDEO_M32R_AR
347 tristate "AR devices"
348 depends on M32R
349 ---help---
350 This is a video4linux driver for the Renesas AR (Artificial Retina)
351 camera module.
352
353config VIDEO_M32R_AR_M64278
354 tristate "Use Colour AR module M64278(VGA)"
355 depends on VIDEO_M32R_AR
356 ---help---
357 Say Y here to use the Renesas M64278E-800 camera module,
358 which supports VGA(640x480 pixcels) size of images.
359
360endmenu
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
new file mode 100644
index 00000000000..2dc906fdfa5
--- /dev/null
+++ b/drivers/media/video/Makefile
@@ -0,0 +1,56 @@
1#
2# Makefile for the video capture/playback device drivers.
3#
4
5bttv-objs := bttv-driver.o bttv-cards.o bttv-if.o \
6 bttv-risc.o bttv-vbi.o bttv-i2c.o bttv-gpio.o
7zoran-objs := zr36120.o zr36120_i2c.o zr36120_mem.o
8zr36067-objs := zoran_procfs.o zoran_device.o \
9 zoran_driver.o zoran_card.o
10tuner-objs := tuner-core.o tuner-simple.o mt20xx.o tda8290.o
11
12obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-common.o v4l1-compat.o
13
14obj-$(CONFIG_VIDEO_BT848) += bttv.o msp3400.o tvaudio.o \
15 tda7432.o tda9875.o ir-kbd-i2c.o ir-kbd-gpio.o
16obj-$(CONFIG_SOUND_TVMIXER) += tvmixer.o
17
18obj-$(CONFIG_VIDEO_ZR36120) += zoran.o
19obj-$(CONFIG_VIDEO_SAA5246A) += saa5246a.o
20obj-$(CONFIG_VIDEO_SAA5249) += saa5249.o
21obj-$(CONFIG_VIDEO_CQCAM) += c-qcam.o
22obj-$(CONFIG_VIDEO_BWQCAM) += bw-qcam.o
23obj-$(CONFIG_VIDEO_W9966) += w9966.o
24obj-$(CONFIG_VIDEO_ZORAN_BUZ) += saa7111.o saa7185.o zr36060.o
25obj-$(CONFIG_VIDEO_ZORAN_DC10) += saa7110.o adv7175.o zr36060.o
26obj-$(CONFIG_VIDEO_ZORAN_DC30) += adv7175.o vpx3220.o zr36050.o \
27 zr36016.o
28obj-$(CONFIG_VIDEO_ZORAN_LML33) += bt819.o bt856.o zr36060.o
29obj-$(CONFIG_VIDEO_ZORAN_LML33R10) += saa7114.o adv7170.o zr36060.o
30obj-$(CONFIG_VIDEO_ZORAN) += zr36067.o videocodec.o
31obj-$(CONFIG_VIDEO_PMS) += pms.o
32obj-$(CONFIG_VIDEO_PLANB) += planb.o
33obj-$(CONFIG_VIDEO_VINO) += vino.o
34obj-$(CONFIG_VIDEO_STRADIS) += stradis.o
35obj-$(CONFIG_VIDEO_CPIA) += cpia.o
36obj-$(CONFIG_VIDEO_CPIA_PP) += cpia_pp.o
37obj-$(CONFIG_VIDEO_CPIA_USB) += cpia_usb.o
38obj-$(CONFIG_VIDEO_MEYE) += meye.o
39obj-$(CONFIG_VIDEO_SAA7134) += saa7134/
40obj-$(CONFIG_VIDEO_CX88) += cx88/
41obj-$(CONFIG_VIDEO_OVCAMCHIP) += ovcamchip/
42obj-$(CONFIG_VIDEO_MXB) += saa7111.o tuner.o tda9840.o tea6415c.o tea6420.o mxb.o
43obj-$(CONFIG_VIDEO_HEXIUM_ORION) += hexium_orion.o
44obj-$(CONFIG_VIDEO_HEXIUM_GEMINI) += hexium_gemini.o
45obj-$(CONFIG_VIDEO_DPC) += saa7111.o dpc7146.o
46obj-$(CONFIG_TUNER_3036) += tuner-3036.o
47
48obj-$(CONFIG_VIDEO_TUNER) += tuner.o tda9887.o
49obj-$(CONFIG_VIDEO_BUF) += video-buf.o
50obj-$(CONFIG_VIDEO_BUF_DVB) += video-buf-dvb.o
51obj-$(CONFIG_VIDEO_BTCX) += btcx-risc.o
52obj-$(CONFIG_VIDEO_TVEEPROM) += tveeprom.o
53
54obj-$(CONFIG_VIDEO_M32R_AR_M64278) += arv.o
55
56EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core
diff --git a/drivers/media/video/adv7170.c b/drivers/media/video/adv7170.c
new file mode 100644
index 00000000000..80254caa444
--- /dev/null
+++ b/drivers/media/video/adv7170.c
@@ -0,0 +1,535 @@
1/*
2 * adv7170 - adv7170, adv7171 video encoder driver version 0.0.1
3 *
4 * Copyright (C) 2002 Maxim Yevtyushkin <max@linuxmedialabs.com>
5 *
6 * Based on adv7176 driver by:
7 *
8 * Copyright (C) 1998 Dave Perks <dperks@ibm.net>
9 * Copyright (C) 1999 Wolfgang Scherr <scherr@net4you.net>
10 * Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>
11 * - some corrections for Pinnacle Systems Inc. DC10plus card.
12 *
13 * Changes by Ronald Bultje <rbultje@ronald.bitfreak.net>
14 * - moved over to linux>=2.4.x i2c protocol (1/1/2003)
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 */
30
31#include <linux/module.h>
32#include <linux/init.h>
33#include <linux/delay.h>
34#include <linux/errno.h>
35#include <linux/fs.h>
36#include <linux/kernel.h>
37#include <linux/major.h>
38#include <linux/slab.h>
39#include <linux/mm.h>
40#include <linux/pci.h>
41#include <linux/signal.h>
42#include <asm/io.h>
43#include <asm/pgtable.h>
44#include <asm/page.h>
45#include <linux/sched.h>
46#include <asm/segment.h>
47#include <linux/types.h>
48
49#include <linux/videodev.h>
50#include <asm/uaccess.h>
51
52MODULE_DESCRIPTION("Analog Devices ADV7170 video encoder driver");
53MODULE_AUTHOR("Maxim Yevtyushkin");
54MODULE_LICENSE("GPL");
55
56#include <linux/i2c.h>
57#include <linux/i2c-dev.h>
58
59#define I2C_NAME(x) (x)->name
60
61#include <linux/video_encoder.h>
62
63static int debug = 0;
64module_param(debug, int, 0);
65MODULE_PARM_DESC(debug, "Debug level (0-1)");
66
67#define dprintk(num, format, args...) \
68 do { \
69 if (debug >= num) \
70 printk(format, ##args); \
71 } while (0)
72
73/* ----------------------------------------------------------------------- */
74
75struct adv7170 {
76 unsigned char reg[128];
77
78 int norm;
79 int input;
80 int enable;
81 int bright;
82 int contrast;
83 int hue;
84 int sat;
85};
86
87#define I2C_ADV7170 0xd4
88#define I2C_ADV7171 0x54
89
90static char adv7170_name[] = "adv7170";
91static char adv7171_name[] = "adv7171";
92
93static char *inputs[] = { "pass_through", "play_back" };
94static char *norms[] = { "PAL", "NTSC" };
95
96/* ----------------------------------------------------------------------- */
97
98static inline int
99adv7170_write (struct i2c_client *client,
100 u8 reg,
101 u8 value)
102{
103 struct adv7170 *encoder = i2c_get_clientdata(client);
104
105 encoder->reg[reg] = value;
106 return i2c_smbus_write_byte_data(client, reg, value);
107}
108
109static inline int
110adv7170_read (struct i2c_client *client,
111 u8 reg)
112{
113 return i2c_smbus_read_byte_data(client, reg);
114}
115
116static int
117adv7170_write_block (struct i2c_client *client,
118 const u8 *data,
119 unsigned int len)
120{
121 int ret = -1;
122 u8 reg;
123
124 /* the adv7170 has an autoincrement function, use it if
125 * the adapter understands raw I2C */
126 if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
127 /* do raw I2C, not smbus compatible */
128 struct adv7170 *encoder = i2c_get_clientdata(client);
129 struct i2c_msg msg;
130 u8 block_data[32];
131
132 msg.addr = client->addr;
133 msg.flags = 0;
134 while (len >= 2) {
135 msg.buf = (char *) block_data;
136 msg.len = 0;
137 block_data[msg.len++] = reg = data[0];
138 do {
139 block_data[msg.len++] =
140 encoder->reg[reg++] = data[1];
141 len -= 2;
142 data += 2;
143 } while (len >= 2 && data[0] == reg &&
144 msg.len < 32);
145 if ((ret = i2c_transfer(client->adapter,
146 &msg, 1)) < 0)
147 break;
148 }
149 } else {
150 /* do some slow I2C emulation kind of thing */
151 while (len >= 2) {
152 reg = *data++;
153 if ((ret = adv7170_write(client, reg,
154 *data++)) < 0)
155 break;
156 len -= 2;
157 }
158 }
159
160 return ret;
161}
162
163/* ----------------------------------------------------------------------- */
164// Output filter: S-Video Composite
165
166#define MR050 0x11 //0x09
167#define MR060 0x14 //0x0c
168
169//---------------------------------------------------------------------------
170
171#define TR0MODE 0x4c
172#define TR0RST 0x80
173
174#define TR1CAPT 0x00
175#define TR1PLAY 0x00
176
177
178static const unsigned char init_NTSC[] = {
179 0x00, 0x10, // MR0
180 0x01, 0x20, // MR1
181 0x02, 0x0e, // MR2 RTC control: bits 2 and 1
182 0x03, 0x80, // MR3
183 0x04, 0x30, // MR4
184 0x05, 0x00, // Reserved
185 0x06, 0x00, // Reserved
186 0x07, TR0MODE, // TM0
187 0x08, TR1CAPT, // TM1
188 0x09, 0x16, // Fsc0
189 0x0a, 0x7c, // Fsc1
190 0x0b, 0xf0, // Fsc2
191 0x0c, 0x21, // Fsc3
192 0x0d, 0x00, // Subcarrier Phase
193 0x0e, 0x00, // Closed Capt. Ext 0
194 0x0f, 0x00, // Closed Capt. Ext 1
195 0x10, 0x00, // Closed Capt. 0
196 0x11, 0x00, // Closed Capt. 1
197 0x12, 0x00, // Pedestal Ctl 0
198 0x13, 0x00, // Pedestal Ctl 1
199 0x14, 0x00, // Pedestal Ctl 2
200 0x15, 0x00, // Pedestal Ctl 3
201 0x16, 0x00, // CGMS_WSS_0
202 0x17, 0x00, // CGMS_WSS_1
203 0x18, 0x00, // CGMS_WSS_2
204 0x19, 0x00, // Teletext Ctl
205};
206
207static const unsigned char init_PAL[] = {
208 0x00, 0x71, // MR0
209 0x01, 0x20, // MR1
210 0x02, 0x0e, // MR2 RTC control: bits 2 and 1
211 0x03, 0x80, // MR3
212 0x04, 0x30, // MR4
213 0x05, 0x00, // Reserved
214 0x06, 0x00, // Reserved
215 0x07, TR0MODE, // TM0
216 0x08, TR1CAPT, // TM1
217 0x09, 0xcb, // Fsc0
218 0x0a, 0x8a, // Fsc1
219 0x0b, 0x09, // Fsc2
220 0x0c, 0x2a, // Fsc3
221 0x0d, 0x00, // Subcarrier Phase
222 0x0e, 0x00, // Closed Capt. Ext 0
223 0x0f, 0x00, // Closed Capt. Ext 1
224 0x10, 0x00, // Closed Capt. 0
225 0x11, 0x00, // Closed Capt. 1
226 0x12, 0x00, // Pedestal Ctl 0
227 0x13, 0x00, // Pedestal Ctl 1
228 0x14, 0x00, // Pedestal Ctl 2
229 0x15, 0x00, // Pedestal Ctl 3
230 0x16, 0x00, // CGMS_WSS_0
231 0x17, 0x00, // CGMS_WSS_1
232 0x18, 0x00, // CGMS_WSS_2
233 0x19, 0x00, // Teletext Ctl
234};
235
236
237static int
238adv7170_command (struct i2c_client *client,
239 unsigned int cmd,
240 void * arg)
241{
242 struct adv7170 *encoder = i2c_get_clientdata(client);
243
244 switch (cmd) {
245
246 case 0:
247#if 0
248 /* This is just for testing!!! */
249 adv7170_write_block(client, init_common,
250 sizeof(init_common));
251 adv7170_write(client, 0x07, TR0MODE | TR0RST);
252 adv7170_write(client, 0x07, TR0MODE);
253#endif
254 break;
255
256 case ENCODER_GET_CAPABILITIES:
257 {
258 struct video_encoder_capability *cap = arg;
259
260 cap->flags = VIDEO_ENCODER_PAL |
261 VIDEO_ENCODER_NTSC;
262 cap->inputs = 2;
263 cap->outputs = 1;
264 }
265 break;
266
267 case ENCODER_SET_NORM:
268 {
269 int iarg = *(int *) arg;
270
271 dprintk(1, KERN_DEBUG "%s_command: set norm %d",
272 I2C_NAME(client), iarg);
273
274 switch (iarg) {
275
276 case VIDEO_MODE_NTSC:
277 adv7170_write_block(client, init_NTSC,
278 sizeof(init_NTSC));
279 if (encoder->input == 0)
280 adv7170_write(client, 0x02, 0x0e); // Enable genlock
281 adv7170_write(client, 0x07, TR0MODE | TR0RST);
282 adv7170_write(client, 0x07, TR0MODE);
283 break;
284
285 case VIDEO_MODE_PAL:
286 adv7170_write_block(client, init_PAL,
287 sizeof(init_PAL));
288 if (encoder->input == 0)
289 adv7170_write(client, 0x02, 0x0e); // Enable genlock
290 adv7170_write(client, 0x07, TR0MODE | TR0RST);
291 adv7170_write(client, 0x07, TR0MODE);
292 break;
293
294 default:
295 dprintk(1, KERN_ERR "%s: illegal norm: %d\n",
296 I2C_NAME(client), iarg);
297 return -EINVAL;
298
299 }
300 dprintk(1, KERN_DEBUG "%s: switched to %s\n", I2C_NAME(client),
301 norms[iarg]);
302 encoder->norm = iarg;
303 }
304 break;
305
306 case ENCODER_SET_INPUT:
307 {
308 int iarg = *(int *) arg;
309
310 /* RJ: *iarg = 0: input is from decoder
311 *iarg = 1: input is from ZR36060
312 *iarg = 2: color bar */
313
314 dprintk(1, KERN_DEBUG "%s_command: set input from %s\n",
315 I2C_NAME(client),
316 iarg == 0 ? "decoder" : "ZR36060");
317
318 switch (iarg) {
319
320 case 0:
321 adv7170_write(client, 0x01, 0x20);
322 adv7170_write(client, 0x08, TR1CAPT); /* TR1 */
323 adv7170_write(client, 0x02, 0x0e); // Enable genlock
324 adv7170_write(client, 0x07, TR0MODE | TR0RST);
325 adv7170_write(client, 0x07, TR0MODE);
326 //udelay(10);
327 break;
328
329 case 1:
330 adv7170_write(client, 0x01, 0x00);
331 adv7170_write(client, 0x08, TR1PLAY); /* TR1 */
332 adv7170_write(client, 0x02, 0x08);
333 adv7170_write(client, 0x07, TR0MODE | TR0RST);
334 adv7170_write(client, 0x07, TR0MODE);
335 //udelay(10);
336 break;
337
338 default:
339 dprintk(1, KERN_ERR "%s: illegal input: %d\n",
340 I2C_NAME(client), iarg);
341 return -EINVAL;
342
343 }
344 dprintk(1, KERN_DEBUG "%s: switched to %s\n", I2C_NAME(client),
345 inputs[iarg]);
346 encoder->input = iarg;
347 }
348 break;
349
350 case ENCODER_SET_OUTPUT:
351 {
352 int *iarg = arg;
353
354 /* not much choice of outputs */
355 if (*iarg != 0) {
356 return -EINVAL;
357 }
358 }
359 break;
360
361 case ENCODER_ENABLE_OUTPUT:
362 {
363 int *iarg = arg;
364
365 encoder->enable = !!*iarg;
366 }
367 break;
368
369 default:
370 return -EINVAL;
371 }
372
373 return 0;
374}
375
376/* ----------------------------------------------------------------------- */
377
378/*
379 * Generic i2c probe
380 * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
381 */
382static unsigned short normal_i2c[] =
383 { I2C_ADV7170 >> 1, (I2C_ADV7170 >> 1) + 1,
384 I2C_ADV7171 >> 1, (I2C_ADV7171 >> 1) + 1,
385 I2C_CLIENT_END
386};
387static unsigned short normal_i2c_range[] = { I2C_CLIENT_END };
388
389static unsigned short probe[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
390static unsigned short probe_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
391static unsigned short ignore[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
392static unsigned short ignore_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
393static unsigned short force[2] = { I2C_CLIENT_END , I2C_CLIENT_END };
394
395static struct i2c_client_address_data addr_data = {
396 .normal_i2c = normal_i2c,
397 .normal_i2c_range = normal_i2c_range,
398 .probe = probe,
399 .probe_range = probe_range,
400 .ignore = ignore,
401 .ignore_range = ignore_range,
402 .force = force
403};
404
405static struct i2c_driver i2c_driver_adv7170;
406
407static int
408adv7170_detect_client (struct i2c_adapter *adapter,
409 int address,
410 int kind)
411{
412 int i;
413 struct i2c_client *client;
414 struct adv7170 *encoder;
415 char *dname;
416
417 dprintk(1,
418 KERN_INFO
419 "adv7170.c: detecting adv7170 client on address 0x%x\n",
420 address << 1);
421
422 /* Check if the adapter supports the needed features */
423 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
424 return 0;
425
426 client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
427 if (client == 0)
428 return -ENOMEM;
429 memset(client, 0, sizeof(struct i2c_client));
430 client->addr = address;
431 client->adapter = adapter;
432 client->driver = &i2c_driver_adv7170;
433 client->flags = I2C_CLIENT_ALLOW_USE;
434 if ((client->addr == I2C_ADV7170 >> 1) ||
435 (client->addr == (I2C_ADV7170 >> 1) + 1)) {
436 dname = adv7170_name;
437 } else if ((client->addr == I2C_ADV7171 >> 1) ||
438 (client->addr == (I2C_ADV7171 >> 1) + 1)) {
439 dname = adv7171_name;
440 } else {
441 /* We should never get here!!! */
442 kfree(client);
443 return 0;
444 }
445 strlcpy(I2C_NAME(client), dname, sizeof(I2C_NAME(client)));
446
447 encoder = kmalloc(sizeof(struct adv7170), GFP_KERNEL);
448 if (encoder == NULL) {
449 kfree(client);
450 return -ENOMEM;
451 }
452 memset(encoder, 0, sizeof(struct adv7170));
453 encoder->norm = VIDEO_MODE_NTSC;
454 encoder->input = 0;
455 encoder->enable = 1;
456 i2c_set_clientdata(client, encoder);
457
458 i = i2c_attach_client(client);
459 if (i) {
460 kfree(client);
461 kfree(encoder);
462 return i;
463 }
464
465 i = adv7170_write_block(client, init_NTSC, sizeof(init_NTSC));
466 if (i >= 0) {
467 i = adv7170_write(client, 0x07, TR0MODE | TR0RST);
468 i = adv7170_write(client, 0x07, TR0MODE);
469 i = adv7170_read(client, 0x12);
470 dprintk(1, KERN_INFO "%s_attach: rev. %d at 0x%02x\n",
471 I2C_NAME(client), i & 1, client->addr << 1);
472 }
473 if (i < 0) {
474 dprintk(1, KERN_ERR "%s_attach: init error 0x%x\n",
475 I2C_NAME(client), i);
476 }
477
478 return 0;
479}
480
481static int
482adv7170_attach_adapter (struct i2c_adapter *adapter)
483{
484 dprintk(1,
485 KERN_INFO
486 "adv7170.c: starting probe for adapter %s (0x%x)\n",
487 I2C_NAME(adapter), adapter->id);
488 return i2c_probe(adapter, &addr_data, &adv7170_detect_client);
489}
490
491static int
492adv7170_detach_client (struct i2c_client *client)
493{
494 struct adv7170 *encoder = i2c_get_clientdata(client);
495 int err;
496
497 err = i2c_detach_client(client);
498 if (err) {
499 return err;
500 }
501
502 kfree(encoder);
503 kfree(client);
504
505 return 0;
506}
507
508/* ----------------------------------------------------------------------- */
509
510static struct i2c_driver i2c_driver_adv7170 = {
511 .owner = THIS_MODULE,
512 .name = "adv7170", /* name */
513
514 .id = I2C_DRIVERID_ADV7170,
515 .flags = I2C_DF_NOTIFY,
516
517 .attach_adapter = adv7170_attach_adapter,
518 .detach_client = adv7170_detach_client,
519 .command = adv7170_command,
520};
521
522static int __init
523adv7170_init (void)
524{
525 return i2c_add_driver(&i2c_driver_adv7170);
526}
527
528static void __exit
529adv7170_exit (void)
530{
531 i2c_del_driver(&i2c_driver_adv7170);
532}
533
534module_init(adv7170_init);
535module_exit(adv7170_exit);
diff --git a/drivers/media/video/adv7175.c b/drivers/media/video/adv7175.c
new file mode 100644
index 00000000000..95d0974b0ab
--- /dev/null
+++ b/drivers/media/video/adv7175.c
@@ -0,0 +1,585 @@
1/*
2 * adv7175 - adv7175a video encoder driver version 0.0.3
3 *
4 * Copyright (C) 1998 Dave Perks <dperks@ibm.net>
5 * Copyright (C) 1999 Wolfgang Scherr <scherr@net4you.net>
6 * Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>
7 * - some corrections for Pinnacle Systems Inc. DC10plus card.
8 *
9 * Changes by Ronald Bultje <rbultje@ronald.bitfreak.net>
10 * - moved over to linux>=2.4.x i2c protocol (9/9/2002)
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 */
26
27#include <linux/module.h>
28#include <linux/init.h>
29#include <linux/delay.h>
30#include <linux/errno.h>
31#include <linux/fs.h>
32#include <linux/kernel.h>
33#include <linux/major.h>
34#include <linux/slab.h>
35#include <linux/mm.h>
36#include <linux/pci.h>
37#include <linux/signal.h>
38#include <asm/io.h>
39#include <asm/pgtable.h>
40#include <asm/page.h>
41#include <linux/sched.h>
42#include <asm/segment.h>
43#include <linux/types.h>
44
45#include <linux/videodev.h>
46#include <asm/uaccess.h>
47
48MODULE_DESCRIPTION("Analog Devices ADV7175 video encoder driver");
49MODULE_AUTHOR("Dave Perks");
50MODULE_LICENSE("GPL");
51
52#include <linux/i2c.h>
53#include <linux/i2c-dev.h>
54
55#define I2C_NAME(s) (s)->name
56
57#include <linux/video_encoder.h>
58
59static int debug = 0;
60module_param(debug, int, 0);
61MODULE_PARM_DESC(debug, "Debug level (0-1)");
62
63#define dprintk(num, format, args...) \
64 do { \
65 if (debug >= num) \
66 printk(format, ##args); \
67 } while (0)
68
69/* ----------------------------------------------------------------------- */
70
71struct adv7175 {
72 unsigned char reg[128];
73
74 int norm;
75 int input;
76 int enable;
77 int bright;
78 int contrast;
79 int hue;
80 int sat;
81};
82
83#define I2C_ADV7175 0xd4
84#define I2C_ADV7176 0x54
85
86static char adv7175_name[] = "adv7175";
87static char adv7176_name[] = "adv7176";
88
89static char *inputs[] = { "pass_through", "play_back", "color_bar" };
90static char *norms[] = { "PAL", "NTSC", "SECAM->PAL (may not work!)" };
91
92/* ----------------------------------------------------------------------- */
93
94static inline int
95adv7175_write (struct i2c_client *client,
96 u8 reg,
97 u8 value)
98{
99 struct adv7175 *encoder = i2c_get_clientdata(client);
100
101 encoder->reg[reg] = value;
102 return i2c_smbus_write_byte_data(client, reg, value);
103}
104
105static inline int
106adv7175_read (struct i2c_client *client,
107 u8 reg)
108{
109 return i2c_smbus_read_byte_data(client, reg);
110}
111
112static int
113adv7175_write_block (struct i2c_client *client,
114 const u8 *data,
115 unsigned int len)
116{
117 int ret = -1;
118 u8 reg;
119
120 /* the adv7175 has an autoincrement function, use it if
121 * the adapter understands raw I2C */
122 if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
123 /* do raw I2C, not smbus compatible */
124 struct adv7175 *encoder = i2c_get_clientdata(client);
125 struct i2c_msg msg;
126 u8 block_data[32];
127
128 msg.addr = client->addr;
129 msg.flags = 0;
130 while (len >= 2) {
131 msg.buf = (char *) block_data;
132 msg.len = 0;
133 block_data[msg.len++] = reg = data[0];
134 do {
135 block_data[msg.len++] =
136 encoder->reg[reg++] = data[1];
137 len -= 2;
138 data += 2;
139 } while (len >= 2 && data[0] == reg &&
140 msg.len < 32);
141 if ((ret = i2c_transfer(client->adapter,
142 &msg, 1)) < 0)
143 break;
144 }
145 } else {
146 /* do some slow I2C emulation kind of thing */
147 while (len >= 2) {
148 reg = *data++;
149 if ((ret = adv7175_write(client, reg,
150 *data++)) < 0)
151 break;
152 len -= 2;
153 }
154 }
155
156 return ret;
157}
158
159static void
160set_subcarrier_freq (struct i2c_client *client,
161 int pass_through)
162{
163 /* for some reason pass_through NTSC needs
164 * a different sub-carrier freq to remain stable. */
165 if(pass_through)
166 adv7175_write(client, 0x02, 0x00);
167 else
168 adv7175_write(client, 0x02, 0x55);
169
170 adv7175_write(client, 0x03, 0x55);
171 adv7175_write(client, 0x04, 0x55);
172 adv7175_write(client, 0x05, 0x25);
173}
174
175#ifdef ENCODER_DUMP
176static void
177dump (struct i2c_client *client)
178{
179 struct adv7175 *encoder = i2c_get_clientdata(client);
180 int i, j;
181
182 printk(KERN_INFO "%s: registry dump\n", I2C_NAME(client));
183 for (i = 0; i < 182 / 8; i++) {
184 printk("%s: 0x%02x -", I2C_NAME(client), i * 8);
185 for (j = 0; j < 8; j++) {
186 printk(" 0x%02x", encoder->reg[i * 8 + j]);
187 }
188 printk("\n");
189 }
190}
191#endif
192
193/* ----------------------------------------------------------------------- */
194// Output filter: S-Video Composite
195
196#define MR050 0x11 //0x09
197#define MR060 0x14 //0x0c
198
199//---------------------------------------------------------------------------
200
201#define TR0MODE 0x46
202#define TR0RST 0x80
203
204#define TR1CAPT 0x80
205#define TR1PLAY 0x00
206
207static const unsigned char init_common[] = {
208
209 0x00, MR050, /* MR0, PAL enabled */
210 0x01, 0x00, /* MR1 */
211 0x02, 0x0c, /* subc. freq. */
212 0x03, 0x8c, /* subc. freq. */
213 0x04, 0x79, /* subc. freq. */
214 0x05, 0x26, /* subc. freq. */
215 0x06, 0x40, /* subc. phase */
216
217 0x07, TR0MODE, /* TR0, 16bit */
218 0x08, 0x21, /* */
219 0x09, 0x00, /* */
220 0x0a, 0x00, /* */
221 0x0b, 0x00, /* */
222 0x0c, TR1CAPT, /* TR1 */
223 0x0d, 0x4f, /* MR2 */
224 0x0e, 0x00, /* */
225 0x0f, 0x00, /* */
226 0x10, 0x00, /* */
227 0x11, 0x00, /* */
228};
229
230static const unsigned char init_pal[] = {
231 0x00, MR050, /* MR0, PAL enabled */
232 0x01, 0x00, /* MR1 */
233 0x02, 0x0c, /* subc. freq. */
234 0x03, 0x8c, /* subc. freq. */
235 0x04, 0x79, /* subc. freq. */
236 0x05, 0x26, /* subc. freq. */
237 0x06, 0x40, /* subc. phase */
238};
239
240static const unsigned char init_ntsc[] = {
241 0x00, MR060, /* MR0, NTSC enabled */
242 0x01, 0x00, /* MR1 */
243 0x02, 0x55, /* subc. freq. */
244 0x03, 0x55, /* subc. freq. */
245 0x04, 0x55, /* subc. freq. */
246 0x05, 0x25, /* subc. freq. */
247 0x06, 0x1a, /* subc. phase */
248};
249
250static int
251adv7175_command (struct i2c_client *client,
252 unsigned int cmd,
253 void *arg)
254{
255 struct adv7175 *encoder = i2c_get_clientdata(client);
256
257 switch (cmd) {
258
259 case 0:
260 /* This is just for testing!!! */
261 adv7175_write_block(client, init_common,
262 sizeof(init_common));
263 adv7175_write(client, 0x07, TR0MODE | TR0RST);
264 adv7175_write(client, 0x07, TR0MODE);
265 break;
266
267 case ENCODER_GET_CAPABILITIES:
268 {
269 struct video_encoder_capability *cap = arg;
270
271 cap->flags = VIDEO_ENCODER_PAL |
272 VIDEO_ENCODER_NTSC |
273 VIDEO_ENCODER_SECAM; /* well, hacky */
274 cap->inputs = 2;
275 cap->outputs = 1;
276 }
277 break;
278
279 case ENCODER_SET_NORM:
280 {
281 int iarg = *(int *) arg;
282
283 switch (iarg) {
284
285 case VIDEO_MODE_NTSC:
286 adv7175_write_block(client, init_ntsc,
287 sizeof(init_ntsc));
288 if (encoder->input == 0)
289 adv7175_write(client, 0x0d, 0x4f); // Enable genlock
290 adv7175_write(client, 0x07, TR0MODE | TR0RST);
291 adv7175_write(client, 0x07, TR0MODE);
292 break;
293
294 case VIDEO_MODE_PAL:
295 adv7175_write_block(client, init_pal,
296 sizeof(init_pal));
297 if (encoder->input == 0)
298 adv7175_write(client, 0x0d, 0x4f); // Enable genlock
299 adv7175_write(client, 0x07, TR0MODE | TR0RST);
300 adv7175_write(client, 0x07, TR0MODE);
301 break;
302
303 case VIDEO_MODE_SECAM: // WARNING! ADV7176 does not support SECAM.
304 /* This is an attempt to convert
305 * SECAM->PAL (typically it does not work
306 * due to genlock: when decoder is in SECAM
307 * and encoder in in PAL the subcarrier can
308 * not be syncronized with horizontal
309 * quency) */
310 adv7175_write_block(client, init_pal,
311 sizeof(init_pal));
312 if (encoder->input == 0)
313 adv7175_write(client, 0x0d, 0x49); // Disable genlock
314 adv7175_write(client, 0x07, TR0MODE | TR0RST);
315 adv7175_write(client, 0x07, TR0MODE);
316 break;
317 default:
318 dprintk(1, KERN_ERR "%s: illegal norm: %d\n",
319 I2C_NAME(client), iarg);
320 return -EINVAL;
321
322 }
323 dprintk(1, KERN_INFO "%s: switched to %s\n", I2C_NAME(client),
324 norms[iarg]);
325 encoder->norm = iarg;
326 }
327 break;
328
329 case ENCODER_SET_INPUT:
330 {
331 int iarg = *(int *) arg;
332
333 /* RJ: *iarg = 0: input is from SAA7110
334 *iarg = 1: input is from ZR36060
335 *iarg = 2: color bar */
336
337 switch (iarg) {
338
339 case 0:
340 adv7175_write(client, 0x01, 0x00);
341
342 if (encoder->norm == VIDEO_MODE_NTSC)
343 set_subcarrier_freq(client, 1);
344
345 adv7175_write(client, 0x0c, TR1CAPT); /* TR1 */
346 if (encoder->norm == VIDEO_MODE_SECAM)
347 adv7175_write(client, 0x0d, 0x49); // Disable genlock
348 else
349 adv7175_write(client, 0x0d, 0x4f); // Enable genlock
350 adv7175_write(client, 0x07, TR0MODE | TR0RST);
351 adv7175_write(client, 0x07, TR0MODE);
352 //udelay(10);
353 break;
354
355 case 1:
356 adv7175_write(client, 0x01, 0x00);
357
358 if (encoder->norm == VIDEO_MODE_NTSC)
359 set_subcarrier_freq(client, 0);
360
361 adv7175_write(client, 0x0c, TR1PLAY); /* TR1 */
362 adv7175_write(client, 0x0d, 0x49);
363 adv7175_write(client, 0x07, TR0MODE | TR0RST);
364 adv7175_write(client, 0x07, TR0MODE);
365 //udelay(10);
366 break;
367
368 case 2:
369 adv7175_write(client, 0x01, 0x80);
370
371 if (encoder->norm == VIDEO_MODE_NTSC)
372 set_subcarrier_freq(client, 0);
373
374 adv7175_write(client, 0x0d, 0x49);
375 adv7175_write(client, 0x07, TR0MODE | TR0RST);
376 adv7175_write(client, 0x07, TR0MODE);
377 //udelay(10);
378 break;
379
380 default:
381 dprintk(1, KERN_ERR "%s: illegal input: %d\n",
382 I2C_NAME(client), iarg);
383 return -EINVAL;
384
385 }
386 dprintk(1, KERN_INFO "%s: switched to %s\n", I2C_NAME(client),
387 inputs[iarg]);
388 encoder->input = iarg;
389 }
390 break;
391
392 case ENCODER_SET_OUTPUT:
393 {
394 int *iarg = arg;
395
396 /* not much choice of outputs */
397 if (*iarg != 0) {
398 return -EINVAL;
399 }
400 }
401 break;
402
403 case ENCODER_ENABLE_OUTPUT:
404 {
405 int *iarg = arg;
406
407 encoder->enable = !!*iarg;
408 }
409 break;
410
411#ifdef ENCODER_DUMP
412 case ENCODER_DUMP:
413 {
414 dump(client);
415 }
416 break;
417#endif
418
419 default:
420 return -EINVAL;
421 }
422
423 return 0;
424}
425
426/* ----------------------------------------------------------------------- */
427
428/*
429 * Generic i2c probe
430 * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
431 */
432static unsigned short normal_i2c[] =
433 { I2C_ADV7175 >> 1, (I2C_ADV7175 >> 1) + 1,
434 I2C_ADV7176 >> 1, (I2C_ADV7176 >> 1) + 1,
435 I2C_CLIENT_END
436};
437static unsigned short normal_i2c_range[] = { I2C_CLIENT_END };
438
439static unsigned short probe[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
440static unsigned short probe_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
441static unsigned short ignore[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
442static unsigned short ignore_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
443static unsigned short force[2] = { I2C_CLIENT_END , I2C_CLIENT_END };
444
445static struct i2c_client_address_data addr_data = {
446 .normal_i2c = normal_i2c,
447 .normal_i2c_range = normal_i2c_range,
448 .probe = probe,
449 .probe_range = probe_range,
450 .ignore = ignore,
451 .ignore_range = ignore_range,
452 .force = force
453};
454
455static struct i2c_driver i2c_driver_adv7175;
456
457static int
458adv7175_detect_client (struct i2c_adapter *adapter,
459 int address,
460 int kind)
461{
462 int i;
463 struct i2c_client *client;
464 struct adv7175 *encoder;
465 char *dname;
466
467 dprintk(1,
468 KERN_INFO
469 "adv7175.c: detecting adv7175 client on address 0x%x\n",
470 address << 1);
471
472 /* Check if the adapter supports the needed features */
473 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
474 return 0;
475
476 client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
477 if (client == 0)
478 return -ENOMEM;
479 memset(client, 0, sizeof(struct i2c_client));
480 client->addr = address;
481 client->adapter = adapter;
482 client->driver = &i2c_driver_adv7175;
483 client->flags = I2C_CLIENT_ALLOW_USE;
484 if ((client->addr == I2C_ADV7175 >> 1) ||
485 (client->addr == (I2C_ADV7175 >> 1) + 1)) {
486 dname = adv7175_name;
487 } else if ((client->addr == I2C_ADV7176 >> 1) ||
488 (client->addr == (I2C_ADV7176 >> 1) + 1)) {
489 dname = adv7176_name;
490 } else {
491 /* We should never get here!!! */
492 kfree(client);
493 return 0;
494 }
495 strlcpy(I2C_NAME(client), dname, sizeof(I2C_NAME(client)));
496
497 encoder = kmalloc(sizeof(struct adv7175), GFP_KERNEL);
498 if (encoder == NULL) {
499 kfree(client);
500 return -ENOMEM;
501 }
502 memset(encoder, 0, sizeof(struct adv7175));
503 encoder->norm = VIDEO_MODE_PAL;
504 encoder->input = 0;
505 encoder->enable = 1;
506 i2c_set_clientdata(client, encoder);
507
508 i = i2c_attach_client(client);
509 if (i) {
510 kfree(client);
511 kfree(encoder);
512 return i;
513 }
514
515 i = adv7175_write_block(client, init_common, sizeof(init_common));
516 if (i >= 0) {
517 i = adv7175_write(client, 0x07, TR0MODE | TR0RST);
518 i = adv7175_write(client, 0x07, TR0MODE);
519 i = adv7175_read(client, 0x12);
520 dprintk(1, KERN_INFO "%s_attach: rev. %d at 0x%x\n",
521 I2C_NAME(client), i & 1, client->addr << 1);
522 }
523 if (i < 0) {
524 dprintk(1, KERN_ERR "%s_attach: init error 0x%x\n",
525 I2C_NAME(client), i);
526 }
527
528 return 0;
529}
530
531static int
532adv7175_attach_adapter (struct i2c_adapter *adapter)
533{
534 dprintk(1,
535 KERN_INFO
536 "adv7175.c: starting probe for adapter %s (0x%x)\n",
537 I2C_NAME(adapter), adapter->id);
538 return i2c_probe(adapter, &addr_data, &adv7175_detect_client);
539}
540
541static int
542adv7175_detach_client (struct i2c_client *client)
543{
544 struct adv7175 *encoder = i2c_get_clientdata(client);
545 int err;
546
547 err = i2c_detach_client(client);
548 if (err) {
549 return err;
550 }
551
552 kfree(encoder);
553 kfree(client);
554
555 return 0;
556}
557
558/* ----------------------------------------------------------------------- */
559
560static struct i2c_driver i2c_driver_adv7175 = {
561 .owner = THIS_MODULE,
562 .name = "adv7175", /* name */
563
564 .id = I2C_DRIVERID_ADV7175,
565 .flags = I2C_DF_NOTIFY,
566
567 .attach_adapter = adv7175_attach_adapter,
568 .detach_client = adv7175_detach_client,
569 .command = adv7175_command,
570};
571
572static int __init
573adv7175_init (void)
574{
575 return i2c_add_driver(&i2c_driver_adv7175);
576}
577
578static void __exit
579adv7175_exit (void)
580{
581 i2c_del_driver(&i2c_driver_adv7175);
582}
583
584module_init(adv7175_init);
585module_exit(adv7175_exit);
diff --git a/drivers/media/video/arv.c b/drivers/media/video/arv.c
new file mode 100644
index 00000000000..87fd3a7bb39
--- /dev/null
+++ b/drivers/media/video/arv.c
@@ -0,0 +1,916 @@
1/*
2 * Colour AR M64278(VGA) driver for Video4Linux
3 *
4 * Copyright (C) 2003 Takeo Takahashi <takahashi.takeo@renesas.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 *
11 * Some code is taken from AR driver sample program for M3T-M32700UT.
12 *
13 * AR driver sample (M32R SDK):
14 * Copyright (c) 2003 RENESAS TECHNOROGY CORPORATION
15 * AND RENESAS SOLUTIONS CORPORATION
16 * All Rights Reserved.
17 *
18 * 2003-09-01: Support w3cam by Takeo Takahashi
19 */
20
21#include <linux/config.h>
22#include <linux/init.h>
23#include <linux/devfs_fs_kernel.h>
24#include <linux/module.h>
25#include <linux/version.h>
26#include <linux/delay.h>
27#include <linux/errno.h>
28#include <linux/fs.h>
29#include <linux/init.h>
30#include <linux/kernel.h>
31#include <linux/slab.h>
32#include <linux/mm.h>
33#include <linux/sched.h>
34#include <linux/videodev.h>
35
36#include <asm/semaphore.h>
37#include <asm/uaccess.h>
38#include <asm/m32r.h>
39#include <asm/io.h>
40#include <asm/dma.h>
41#include <asm/byteorder.h>
42
43#if 0
44#define DEBUG(n, args...) printk(args)
45#define CHECK_LOST 1
46#else
47#define DEBUG(n, args...)
48#define CHECK_LOST 0
49#endif
50
51/*
52 * USE_INT is always 0, interrupt mode is not available
53 * on linux due to lack of speed
54 */
55#define USE_INT 0 /* Don't modify */
56
57#define VERSION "0.03"
58
59#define ar_inl(addr) inl((unsigned long)(addr))
60#define ar_outl(val, addr) outl((unsigned long)(val),(unsigned long)(addr))
61
62extern struct cpuinfo_m32r boot_cpu_data;
63
64/*
65 * CCD pixel size
66 * Note that M32700UT does not support CIF mode, but QVGA is
67 * supported by M32700UT hardware using VGA mode of AR LSI.
68 *
69 * Supported: VGA (Normal mode, Interlace mode)
70 * QVGA (Always Interlace mode of VGA)
71 *
72 */
73#define AR_WIDTH_VGA 640
74#define AR_HEIGHT_VGA 480
75#define AR_WIDTH_QVGA 320
76#define AR_HEIGHT_QVGA 240
77#define MIN_AR_WIDTH AR_WIDTH_QVGA
78#define MIN_AR_HEIGHT AR_HEIGHT_QVGA
79#define MAX_AR_WIDTH AR_WIDTH_VGA
80#define MAX_AR_HEIGHT AR_HEIGHT_VGA
81
82/* bits & bytes per pixel */
83#define AR_BITS_PER_PIXEL 16
84#define AR_BYTES_PER_PIXEL (AR_BITS_PER_PIXEL/8)
85
86/* line buffer size */
87#define AR_LINE_BYTES_VGA (AR_WIDTH_VGA * AR_BYTES_PER_PIXEL)
88#define AR_LINE_BYTES_QVGA (AR_WIDTH_QVGA * AR_BYTES_PER_PIXEL)
89#define MAX_AR_LINE_BYTES AR_LINE_BYTES_VGA
90
91/* frame size & type */
92#define AR_FRAME_BYTES_VGA \
93 (AR_WIDTH_VGA * AR_HEIGHT_VGA * AR_BYTES_PER_PIXEL)
94#define AR_FRAME_BYTES_QVGA \
95 (AR_WIDTH_QVGA * AR_HEIGHT_QVGA * AR_BYTES_PER_PIXEL)
96#define MAX_AR_FRAME_BYTES \
97 (MAX_AR_WIDTH * MAX_AR_HEIGHT * AR_BYTES_PER_PIXEL)
98
99#define AR_MAX_FRAME 15
100
101/* capture size */
102#define AR_SIZE_VGA 0
103#define AR_SIZE_QVGA 1
104
105/* capture mode */
106#define AR_MODE_INTERLACE 0
107#define AR_MODE_NORMAL 1
108
109struct ar_device {
110 struct video_device *vdev;
111 unsigned int start_capture; /* duaring capture in INT. mode. */
112#if USE_INT
113 unsigned char *line_buff; /* DMA line buffer */
114#endif
115 unsigned char *frame[MAX_AR_HEIGHT]; /* frame data */
116 short size; /* capture size */
117 short mode; /* capture mode */
118 int width, height;
119 int frame_bytes, line_bytes;
120 wait_queue_head_t wait;
121 struct semaphore lock;
122};
123
124static int video_nr = -1; /* video device number (first free) */
125static unsigned char yuv[MAX_AR_FRAME_BYTES];
126
127/* module parameters */
128/* default frequency */
129#define DEFAULT_FREQ 50 /* 50 or 75 (MHz) is available as BCLK */
130static int freq = DEFAULT_FREQ; /* BCLK: available 50 or 70 (MHz) */
131static int vga = 0; /* default mode(0:QVGA mode, other:VGA mode) */
132static int vga_interlace = 0; /* 0 is normal mode for, else interlace mode */
133MODULE_PARM(freq, "i");
134MODULE_PARM(vga, "i");
135MODULE_PARM(vga_interlace, "i");
136
137static int ar_initialize(struct video_device *dev);
138
139static inline void wait_for_vsync(void)
140{
141 while (ar_inl(ARVCR0) & ARVCR0_VDS) /* wait for VSYNC */
142 cpu_relax();
143 while (!(ar_inl(ARVCR0) & ARVCR0_VDS)) /* wait for VSYNC */
144 cpu_relax();
145}
146
147static inline void wait_acknowledge(void)
148{
149 int i;
150
151 for (i = 0; i < 1000; i++)
152 cpu_relax();
153 while (ar_inl(PLDI2CSTS) & PLDI2CSTS_NOACK)
154 cpu_relax();
155}
156
157/*******************************************************************
158 * I2C functions
159 *******************************************************************/
160void iic(int n, unsigned long addr, unsigned long data1, unsigned long data2,
161 unsigned long data3)
162{
163 int i;
164
165 /* Slave Address */
166 ar_outl(addr, PLDI2CDATA);
167 wait_for_vsync();
168
169 /* Start */
170 ar_outl(1, PLDI2CCND);
171 wait_acknowledge();
172
173 /* Transfer data 1 */
174 ar_outl(data1, PLDI2CDATA);
175 wait_for_vsync();
176 ar_outl(PLDI2CSTEN_STEN, PLDI2CSTEN);
177 wait_acknowledge();
178
179 /* Transfer data 2 */
180 ar_outl(data2, PLDI2CDATA);
181 wait_for_vsync();
182 ar_outl(PLDI2CSTEN_STEN, PLDI2CSTEN);
183 wait_acknowledge();
184
185 if (n == 3) {
186 /* Transfer data 3 */
187 ar_outl(data3, PLDI2CDATA);
188 wait_for_vsync();
189 ar_outl(PLDI2CSTEN_STEN, PLDI2CSTEN);
190 wait_acknowledge();
191 }
192
193 /* Stop */
194 for (i = 0; i < 100; i++)
195 cpu_relax();
196 ar_outl(2, PLDI2CCND);
197 ar_outl(2, PLDI2CCND);
198
199 while (ar_inl(PLDI2CSTS) & PLDI2CSTS_BB)
200 cpu_relax();
201}
202
203
204void init_iic(void)
205{
206 DEBUG(1, "init_iic:\n");
207
208 /*
209 * ICU Setting (iic)
210 */
211 /* I2C Setting */
212 ar_outl(0x0, PLDI2CCR); /* I2CCR Disable */
213 ar_outl(0x0300, PLDI2CMOD); /* I2CMOD ACK/8b-data/7b-addr/auto */
214 ar_outl(0x1, PLDI2CACK); /* I2CACK ACK */
215
216 /* I2C CLK */
217 /* 50MH-100k */
218 if (freq == 75) {
219 ar_outl(369, PLDI2CFREQ); /* BCLK = 75MHz */
220 } else if (freq == 50) {
221 ar_outl(244, PLDI2CFREQ); /* BCLK = 50MHz */
222 } else {
223 ar_outl(244, PLDI2CFREQ); /* default: BCLK = 50MHz */
224 }
225 ar_outl(0x1, PLDI2CCR); /* I2CCR Enable */
226}
227
228/**************************************************************************
229 *
230 * Video4Linux Interface functions
231 *
232 **************************************************************************/
233
234static inline void disable_dma(void)
235{
236 ar_outl(0x8000, M32R_DMAEN_PORTL); /* disable DMA0 */
237}
238
239static inline void enable_dma(void)
240{
241 ar_outl(0x8080, M32R_DMAEN_PORTL); /* enable DMA0 */
242}
243
244static inline void clear_dma_status(void)
245{
246 ar_outl(0x8000, M32R_DMAEDET_PORTL); /* clear status */
247}
248
249static inline void wait_for_vertical_sync(int exp_line)
250{
251#if CHECK_LOST
252 int tmout = 10000; /* FIXME */
253 int l;
254
255 /*
256 * check HCOUNT because we cannot check vertical sync.
257 */
258 for (; tmout >= 0; tmout--) {
259 l = ar_inl(ARVHCOUNT);
260 if (l == exp_line)
261 break;
262 }
263 if (tmout < 0)
264 printk("arv: lost %d -> %d\n", exp_line, l);
265#else
266 while (ar_inl(ARVHCOUNT) != exp_line)
267 cpu_relax();
268#endif
269}
270
271static ssize_t ar_read(struct file *file, char *buf, size_t count, loff_t *ppos)
272{
273 struct video_device *v = video_devdata(file);
274 struct ar_device *ar = v->priv;
275 long ret = ar->frame_bytes; /* return read bytes */
276 unsigned long arvcr1 = 0;
277 unsigned long flags;
278 unsigned char *p;
279 int h, w;
280 unsigned char *py, *pu, *pv;
281#if ! USE_INT
282 int l;
283#endif
284
285 DEBUG(1, "ar_read()\n");
286
287 if (ar->size == AR_SIZE_QVGA)
288 arvcr1 |= ARVCR1_QVGA;
289 if (ar->mode == AR_MODE_NORMAL)
290 arvcr1 |= ARVCR1_NORMAL;
291
292 down(&ar->lock);
293
294#if USE_INT
295 local_irq_save(flags);
296 disable_dma();
297 ar_outl(0xa1871300, M32R_DMA0CR0_PORTL);
298 ar_outl(0x01000000, M32R_DMA0CR1_PORTL);
299
300 /* set AR FIFO address as source(BSEL5) */
301 ar_outl(ARDATA32, M32R_DMA0CSA_PORTL);
302 ar_outl(ARDATA32, M32R_DMA0RSA_PORTL);
303 ar_outl(ar->line_buff, M32R_DMA0CDA_PORTL); /* destination addr. */
304 ar_outl(ar->line_buff, M32R_DMA0RDA_PORTL); /* reload address */
305 ar_outl(ar->line_bytes, M32R_DMA0CBCUT_PORTL); /* byte count (bytes) */
306 ar_outl(ar->line_bytes, M32R_DMA0RBCUT_PORTL); /* reload count (bytes) */
307
308 /*
309 * Okey , kicks AR LSI to invoke an interrupt
310 */
311 ar->start_capture = 0;
312 ar_outl(arvcr1 | ARVCR1_HIEN, ARVCR1);
313 local_irq_restore(flags);
314 /* .... AR interrupts .... */
315 interruptible_sleep_on(&ar->wait);
316 if (signal_pending(current)) {
317 printk("arv: interrupted while get frame data.\n");
318 ret = -EINTR;
319 goto out_up;
320 }
321#else /* ! USE_INT */
322 /* polling */
323 ar_outl(arvcr1, ARVCR1);
324 disable_dma();
325 ar_outl(0x8000, M32R_DMAEDET_PORTL);
326 ar_outl(0xa0861300, M32R_DMA0CR0_PORTL);
327 ar_outl(0x01000000, M32R_DMA0CR1_PORTL);
328 ar_outl(ARDATA32, M32R_DMA0CSA_PORTL);
329 ar_outl(ARDATA32, M32R_DMA0RSA_PORTL);
330 ar_outl(ar->line_bytes, M32R_DMA0CBCUT_PORTL);
331 ar_outl(ar->line_bytes, M32R_DMA0RBCUT_PORTL);
332
333 local_irq_save(flags);
334 while (ar_inl(ARVHCOUNT) != 0) /* wait for 0 */
335 cpu_relax();
336 if (ar->mode == AR_MODE_INTERLACE && ar->size == AR_SIZE_VGA) {
337 for (h = 0; h < ar->height; h++) {
338 wait_for_vertical_sync(h);
339 if (h < (AR_HEIGHT_VGA/2))
340 l = h << 1;
341 else
342 l = (((h - (AR_HEIGHT_VGA/2)) << 1) + 1);
343 ar_outl(virt_to_phys(ar->frame[l]), M32R_DMA0CDA_PORTL);
344 enable_dma();
345 while (!(ar_inl(M32R_DMAEDET_PORTL) & 0x8000))
346 cpu_relax();
347 disable_dma();
348 clear_dma_status();
349 ar_outl(0xa0861300, M32R_DMA0CR0_PORTL);
350 }
351 } else {
352 for (h = 0; h < ar->height; h++) {
353 wait_for_vertical_sync(h);
354 ar_outl(virt_to_phys(ar->frame[h]), M32R_DMA0CDA_PORTL);
355 enable_dma();
356 while (!(ar_inl(M32R_DMAEDET_PORTL) & 0x8000))
357 cpu_relax();
358 disable_dma();
359 clear_dma_status();
360 ar_outl(0xa0861300, M32R_DMA0CR0_PORTL);
361 }
362 }
363 local_irq_restore(flags);
364#endif /* ! USE_INT */
365
366 /*
367 * convert YUV422 to YUV422P
368 * +--------------------+
369 * | Y0,Y1,... |
370 * | ..............Yn |
371 * +--------------------+
372 * | U0,U1,........Un |
373 * +--------------------+
374 * | V0,V1,........Vn |
375 * +--------------------+
376 */
377 py = yuv;
378 pu = py + (ar->frame_bytes / 2);
379 pv = pu + (ar->frame_bytes / 4);
380 for (h = 0; h < ar->height; h++) {
381 p = ar->frame[h];
382 for (w = 0; w < ar->line_bytes; w += 4) {
383 *py++ = *p++;
384 *pu++ = *p++;
385 *py++ = *p++;
386 *pv++ = *p++;
387 }
388 }
389 if (copy_to_user(buf, yuv, ar->frame_bytes)) {
390 printk("arv: failed while copy_to_user yuv.\n");
391 ret = -EFAULT;
392 goto out_up;
393 }
394 DEBUG(1, "ret = %d\n", ret);
395out_up:
396 up(&ar->lock);
397 return ret;
398}
399
400static int ar_do_ioctl(struct inode *inode, struct file *file,
401 unsigned int cmd, void *arg)
402{
403 struct video_device *dev = video_devdata(file);
404 struct ar_device *ar = dev->priv;
405
406 DEBUG(1, "ar_ioctl()\n");
407 switch(cmd) {
408 case VIDIOCGCAP:
409 {
410 struct video_capability *b = arg;
411 DEBUG(1, "VIDIOCGCAP:\n");
412 strcpy(b->name, ar->vdev->name);
413 b->type = VID_TYPE_CAPTURE;
414 b->channels = 0;
415 b->audios = 0;
416 b->maxwidth = MAX_AR_WIDTH;
417 b->maxheight = MAX_AR_HEIGHT;
418 b->minwidth = MIN_AR_WIDTH;
419 b->minheight = MIN_AR_HEIGHT;
420 return 0;
421 }
422 case VIDIOCGCHAN:
423 DEBUG(1, "VIDIOCGCHAN:\n");
424 return 0;
425 case VIDIOCSCHAN:
426 DEBUG(1, "VIDIOCSCHAN:\n");
427 return 0;
428 case VIDIOCGTUNER:
429 DEBUG(1, "VIDIOCGTUNER:\n");
430 return 0;
431 case VIDIOCSTUNER:
432 DEBUG(1, "VIDIOCSTUNER:\n");
433 return 0;
434 case VIDIOCGPICT:
435 DEBUG(1, "VIDIOCGPICT:\n");
436 return 0;
437 case VIDIOCSPICT:
438 DEBUG(1, "VIDIOCSPICT:\n");
439 return 0;
440 case VIDIOCCAPTURE:
441 DEBUG(1, "VIDIOCCAPTURE:\n");
442 return -EINVAL;
443 case VIDIOCGWIN:
444 {
445 struct video_window *w = arg;
446 DEBUG(1, "VIDIOCGWIN:\n");
447 memset(w, 0, sizeof(w));
448 w->width = ar->width;
449 w->height = ar->height;
450 return 0;
451 }
452 case VIDIOCSWIN:
453 {
454 struct video_window *w = arg;
455 DEBUG(1, "VIDIOCSWIN:\n");
456 if ((w->width != AR_WIDTH_VGA || w->height != AR_HEIGHT_VGA) &&
457 (w->width != AR_WIDTH_QVGA || w->height != AR_HEIGHT_QVGA))
458 return -EINVAL;
459
460 down(&ar->lock);
461 ar->width = w->width;
462 ar->height = w->height;
463 if (ar->width == AR_WIDTH_VGA) {
464 ar->size = AR_SIZE_VGA;
465 ar->frame_bytes = AR_FRAME_BYTES_VGA;
466 ar->line_bytes = AR_LINE_BYTES_VGA;
467 if (vga_interlace)
468 ar->mode = AR_MODE_INTERLACE;
469 else
470 ar->mode = AR_MODE_NORMAL;
471 } else {
472 ar->size = AR_SIZE_QVGA;
473 ar->frame_bytes = AR_FRAME_BYTES_QVGA;
474 ar->line_bytes = AR_LINE_BYTES_QVGA;
475 ar->mode = AR_MODE_INTERLACE;
476 }
477 up(&ar->lock);
478 return 0;
479 }
480 case VIDIOCGFBUF:
481 DEBUG(1, "VIDIOCGFBUF:\n");
482 return -EINVAL;
483 case VIDIOCSFBUF:
484 DEBUG(1, "VIDIOCSFBUF:\n");
485 return -EINVAL;
486 case VIDIOCKEY:
487 DEBUG(1, "VIDIOCKEY:\n");
488 return 0;
489 case VIDIOCGFREQ:
490 DEBUG(1, "VIDIOCGFREQ:\n");
491 return -EINVAL;
492 case VIDIOCSFREQ:
493 DEBUG(1, "VIDIOCSFREQ:\n");
494 return -EINVAL;
495 case VIDIOCGAUDIO:
496 DEBUG(1, "VIDIOCGAUDIO:\n");
497 return -EINVAL;
498 case VIDIOCSAUDIO:
499 DEBUG(1, "VIDIOCSAUDIO:\n");
500 return -EINVAL;
501 case VIDIOCSYNC:
502 DEBUG(1, "VIDIOCSYNC:\n");
503 return -EINVAL;
504 case VIDIOCMCAPTURE:
505 DEBUG(1, "VIDIOCMCAPTURE:\n");
506 return -EINVAL;
507 case VIDIOCGMBUF:
508 DEBUG(1, "VIDIOCGMBUF:\n");
509 return -EINVAL;
510 case VIDIOCGUNIT:
511 DEBUG(1, "VIDIOCGUNIT:\n");
512 return -EINVAL;
513 case VIDIOCGCAPTURE:
514 DEBUG(1, "VIDIOCGCAPTURE:\n");
515 return -EINVAL;
516 case VIDIOCSCAPTURE:
517 DEBUG(1, "VIDIOCSCAPTURE:\n");
518 return -EINVAL;
519 case VIDIOCSPLAYMODE:
520 DEBUG(1, "VIDIOCSPLAYMODE:\n");
521 return -EINVAL;
522 case VIDIOCSWRITEMODE:
523 DEBUG(1, "VIDIOCSWRITEMODE:\n");
524 return -EINVAL;
525 case VIDIOCGPLAYINFO:
526 DEBUG(1, "VIDIOCGPLAYINFO:\n");
527 return -EINVAL;
528 case VIDIOCSMICROCODE:
529 DEBUG(1, "VIDIOCSMICROCODE:\n");
530 return -EINVAL;
531 case VIDIOCGVBIFMT:
532 DEBUG(1, "VIDIOCGVBIFMT:\n");
533 return -EINVAL;
534 case VIDIOCSVBIFMT:
535 DEBUG(1, "VIDIOCSVBIFMT:\n");
536 return -EINVAL;
537 default:
538 DEBUG(1, "Unknown ioctl(0x%08x)\n", cmd);
539 return -ENOIOCTLCMD;
540 }
541 return 0;
542}
543
544static int ar_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
545 unsigned long arg)
546{
547 return video_usercopy(inode, file, cmd, arg, ar_do_ioctl);
548}
549
550#if USE_INT
551/*
552 * Interrupt handler
553 */
554static void ar_interrupt(int irq, void *dev, struct pt_regs *regs)
555{
556 struct ar_device *ar = dev;
557 unsigned int line_count;
558 unsigned int line_number;
559 unsigned int arvcr1;
560
561 line_count = ar_inl(ARVHCOUNT); /* line number */
562 if (ar->mode == AR_MODE_INTERLACE && ar->size == AR_SIZE_VGA) {
563 /* operations for interlace mode */
564 if ( line_count < (AR_HEIGHT_VGA/2) ) /* even line */
565 line_number = (line_count << 1);
566 else /* odd line */
567 line_number =
568 (((line_count - (AR_HEIGHT_VGA/2)) << 1) + 1);
569 } else {
570 line_number = line_count;
571 }
572
573 if (line_number == 0) {
574 /*
575 * It is an interrupt for line 0.
576 * we have to start capture.
577 */
578 disable_dma();
579#if 0
580 ar_outl(ar->line_buff, M32R_DMA0CDA_PORTL); /* needless? */
581#endif
582 memcpy(ar->frame[0], ar->line_buff, ar->line_bytes);
583#if 0
584 ar_outl(0xa1861300, M32R_DMA0CR0_PORTL);
585#endif
586 enable_dma();
587 ar->start_capture = 1; /* during capture */
588 return;
589 }
590
591 if (ar->start_capture == 1 && line_number <= (ar->height - 1)) {
592 disable_dma();
593 memcpy(ar->frame[line_number], ar->line_buff, ar->line_bytes);
594
595 /*
596 * if captured all line of a frame, disable AR interrupt
597 * and wake a process up.
598 */
599 if (line_number == (ar->height - 1)) { /* end of line */
600
601 ar->start_capture = 0;
602
603 /* disable AR interrupt request */
604 arvcr1 = ar_inl(ARVCR1);
605 arvcr1 &= ~ARVCR1_HIEN; /* clear int. flag */
606 ar_outl(arvcr1, ARVCR1); /* disable */
607 wake_up_interruptible(&ar->wait);
608 } else {
609#if 0
610 ar_outl(ar->line_buff, M32R_DMA0CDA_PORTL);
611 ar_outl(0xa1861300, M32R_DMA0CR0_PORTL);
612#endif
613 enable_dma();
614 }
615 }
616}
617#endif
618
619/*
620 * ar_initialize()
621 * ar_initialize() is called by video_register_device() and
622 * initializes AR LSI and peripherals.
623 *
624 * -1 is returned in all failures.
625 * 0 is returned in success.
626 *
627 */
628static int ar_initialize(struct video_device *dev)
629{
630 struct ar_device *ar = dev->priv;
631 unsigned long cr = 0;
632 int i,found=0;
633
634 DEBUG(1, "ar_initialize:\n");
635
636 /*
637 * initialize AR LSI
638 */
639 ar_outl(0, ARVCR0); /* assert reset of AR LSI */
640 for (i = 0; i < 0x18; i++) /* wait for over 10 cycles @ 27MHz */
641 cpu_relax();
642 ar_outl(ARVCR0_RST, ARVCR0); /* negate reset of AR LSI (enable) */
643 for (i = 0; i < 0x40d; i++) /* wait for over 420 cycles @ 27MHz */
644 cpu_relax();
645
646 /* AR uses INT3 of CPU as interrupt pin. */
647 ar_outl(ARINTSEL_INT3, ARINTSEL);
648
649 if (ar->size == AR_SIZE_QVGA)
650 cr |= ARVCR1_QVGA;
651 if (ar->mode == AR_MODE_NORMAL)
652 cr |= ARVCR1_NORMAL;
653 ar_outl(cr, ARVCR1);
654
655 /*
656 * Initialize IIC so that CPU can communicate with AR LSI,
657 * and send boot commands to AR LSI.
658 */
659 init_iic();
660
661 for (i = 0; i < 0x100000; i++) { /* > 0xa1d10, 56ms */
662 if ((ar_inl(ARVCR0) & ARVCR0_VDS)) { /* VSYNC */
663 found = 1;
664 break;
665 }
666 }
667
668 if (found == 0)
669 return -ENODEV;
670
671 printk("arv: Initializing ");
672
673 iic(2,0x78,0x11,0x01,0x00); /* start */
674 iic(3,0x78,0x12,0x00,0x06);
675 iic(3,0x78,0x12,0x12,0x30);
676 iic(3,0x78,0x12,0x15,0x58);
677 iic(3,0x78,0x12,0x17,0x30);
678 printk(".");
679 iic(3,0x78,0x12,0x1a,0x97);
680 iic(3,0x78,0x12,0x1b,0xff);
681 iic(3,0x78,0x12,0x1c,0xff);
682 iic(3,0x78,0x12,0x26,0x10);
683 iic(3,0x78,0x12,0x27,0x00);
684 printk(".");
685 iic(2,0x78,0x34,0x02,0x00);
686 iic(2,0x78,0x7a,0x10,0x00);
687 iic(2,0x78,0x80,0x39,0x00);
688 iic(2,0x78,0x81,0xe6,0x00);
689 iic(2,0x78,0x8d,0x00,0x00);
690 printk(".");
691 iic(2,0x78,0x8e,0x0c,0x00);
692 iic(2,0x78,0x8f,0x00,0x00);
693#if 0
694 iic(2,0x78,0x90,0x00,0x00); /* AWB on=1 off=0 */
695#endif
696 iic(2,0x78,0x93,0x01,0x00);
697 iic(2,0x78,0x94,0xcd,0x00);
698 iic(2,0x78,0x95,0x00,0x00);
699 printk(".");
700 iic(2,0x78,0x96,0xa0,0x00);
701 iic(2,0x78,0x97,0x00,0x00);
702 iic(2,0x78,0x98,0x60,0x00);
703 iic(2,0x78,0x99,0x01,0x00);
704 iic(2,0x78,0x9a,0x19,0x00);
705 printk(".");
706 iic(2,0x78,0x9b,0x02,0x00);
707 iic(2,0x78,0x9c,0xe8,0x00);
708 iic(2,0x78,0x9d,0x02,0x00);
709 iic(2,0x78,0x9e,0x2e,0x00);
710 iic(2,0x78,0xb8,0x78,0x00);
711 iic(2,0x78,0xba,0x05,0x00);
712#if 0
713 iic(2,0x78,0x83,0x8c,0x00); /* brightness */
714#endif
715 printk(".");
716
717 /* color correction */
718 iic(3,0x78,0x49,0x00,0x95); /* a */
719 iic(3,0x78,0x49,0x01,0x96); /* b */
720 iic(3,0x78,0x49,0x03,0x85); /* c */
721 iic(3,0x78,0x49,0x04,0x97); /* d */
722 iic(3,0x78,0x49,0x02,0x7e); /* e(Lo) */
723 iic(3,0x78,0x49,0x05,0xa4); /* f(Lo) */
724 iic(3,0x78,0x49,0x06,0x04); /* e(Hi) */
725 iic(3,0x78,0x49,0x07,0x04); /* e(Hi) */
726 iic(2,0x78,0x48,0x01,0x00); /* on=1 off=0 */
727
728 printk(".");
729 iic(2,0x78,0x11,0x00,0x00); /* end */
730 printk(" done\n");
731 return 0;
732}
733
734
735void ar_release(struct video_device *vfd)
736{
737 struct ar_device *ar = vfd->priv;
738 down(&ar->lock);
739 video_device_release(vfd);
740}
741
742/****************************************************************************
743 *
744 * Video4Linux Module functions
745 *
746 ****************************************************************************/
747static struct file_operations ar_fops = {
748 .owner = THIS_MODULE,
749 .open = video_exclusive_open,
750 .release = video_exclusive_release,
751 .read = ar_read,
752 .ioctl = ar_ioctl,
753 .llseek = no_llseek,
754};
755
756static struct video_device ar_template = {
757 .owner = THIS_MODULE,
758 .name = "Colour AR VGA",
759 .type = VID_TYPE_CAPTURE,
760 .hardware = VID_HARDWARE_ARV,
761 .fops = &ar_fops,
762 .release = ar_release,
763 .minor = -1,
764};
765
766#define ALIGN4(x) ((((int)(x)) & 0x3) == 0)
767static struct ar_device ardev;
768
769static int __init ar_init(void)
770{
771 struct ar_device *ar;
772 int ret;
773 int i;
774
775 DEBUG(1, "ar_init:\n");
776 ret = -EIO;
777 printk(KERN_INFO "arv: Colour AR VGA driver %s\n", VERSION);
778
779 ar = &ardev;
780 memset(ar, 0, sizeof(struct ar_device));
781
782#if USE_INT
783 /* allocate a DMA buffer for 1 line. */
784 ar->line_buff = kmalloc(MAX_AR_LINE_BYTES, GFP_KERNEL | GFP_DMA);
785 if (ar->line_buff == NULL || ! ALIGN4(ar->line_buff)) {
786 printk("arv: buffer allocation failed for DMA.\n");
787 ret = -ENOMEM;
788 goto out_end;
789 }
790#endif
791 /* allocate buffers for a frame */
792 for (i = 0; i < MAX_AR_HEIGHT; i++) {
793 ar->frame[i] = kmalloc(MAX_AR_LINE_BYTES, GFP_KERNEL);
794 if (ar->frame[i] == NULL || ! ALIGN4(ar->frame[i])) {
795 printk("arv: buffer allocation failed for frame.\n");
796 ret = -ENOMEM;
797 goto out_line_buff;
798 }
799 }
800
801 ar->vdev = video_device_alloc();
802 if (!ar->vdev) {
803 printk(KERN_ERR "arv: video_device_alloc() failed\n");
804 return -ENOMEM;
805 }
806 memcpy(ar->vdev, &ar_template, sizeof(ar_template));
807 ar->vdev->priv = ar;
808
809 if (vga) {
810 ar->width = AR_WIDTH_VGA;
811 ar->height = AR_HEIGHT_VGA;
812 ar->size = AR_SIZE_VGA;
813 ar->frame_bytes = AR_FRAME_BYTES_VGA;
814 ar->line_bytes = AR_LINE_BYTES_VGA;
815 if (vga_interlace)
816 ar->mode = AR_MODE_INTERLACE;
817 else
818 ar->mode = AR_MODE_NORMAL;
819 } else {
820 ar->width = AR_WIDTH_QVGA;
821 ar->height = AR_HEIGHT_QVGA;
822 ar->size = AR_SIZE_QVGA;
823 ar->frame_bytes = AR_FRAME_BYTES_QVGA;
824 ar->line_bytes = AR_LINE_BYTES_QVGA;
825 ar->mode = AR_MODE_INTERLACE;
826 }
827 init_MUTEX(&ar->lock);
828 init_waitqueue_head(&ar->wait);
829
830#if USE_INT
831 if (request_irq(M32R_IRQ_INT3, ar_interrupt, 0, "arv", ar)) {
832 printk("arv: request_irq(%d) failed.\n", M32R_IRQ_INT3);
833 ret = -EIO;
834 goto out_irq;
835 }
836#endif
837
838 if (ar_initialize(ar->vdev) != 0) {
839 printk("arv: M64278 not found.\n");
840 ret = -ENODEV;
841 goto out_dev;
842 }
843
844 /*
845 * ok, we can initialize h/w according to parameters,
846 * so register video device as a frame grabber type.
847 * device is named "video[0-64]".
848 * video_register_device() initializes h/w using ar_initialize().
849 */
850 if (video_register_device(ar->vdev, VFL_TYPE_GRABBER, video_nr) != 0) {
851 /* return -1, -ENFILE(full) or others */
852 printk("arv: register video (Colour AR) failed.\n");
853 ret = -ENODEV;
854 goto out_dev;
855 }
856
857 printk("video%d: Found M64278 VGA (IRQ %d, Freq %dMHz).\n",
858 ar->vdev->minor, M32R_IRQ_INT3, freq);
859
860 return 0;
861
862out_dev:
863#if USE_INT
864 free_irq(M32R_IRQ_INT3, ar);
865
866out_irq:
867#endif
868 for (i = 0; i < MAX_AR_HEIGHT; i++) {
869 if (ar->frame[i])
870 kfree(ar->frame[i]);
871 }
872
873out_line_buff:
874#if USE_INT
875 kfree(ar->line_buff);
876
877out_end:
878#endif
879 return ret;
880}
881
882
883static int __init ar_init_module(void)
884{
885 freq = (boot_cpu_data.bus_clock / 1000000);
886 printk("arv: Bus clock %d\n", freq);
887 if (freq != 50 && freq != 75)
888 freq = DEFAULT_FREQ;
889 return ar_init();
890}
891
892static void __exit ar_cleanup_module(void)
893{
894 struct ar_device *ar;
895 int i;
896
897 ar = &ardev;
898 video_unregister_device(ar->vdev);
899#if USE_INT
900 free_irq(M32R_IRQ_INT3, ar);
901#endif
902 for (i = 0; i < MAX_AR_HEIGHT; i++) {
903 if (ar->frame[i])
904 kfree(ar->frame[i]);
905 }
906#if USE_INT
907 kfree(ar->line_buff);
908#endif
909}
910
911module_init(ar_init_module);
912module_exit(ar_cleanup_module);
913
914MODULE_AUTHOR("Takeo Takahashi <takahashi.takeo@renesas.com>");
915MODULE_DESCRIPTION("Colour AR M64278(VGA) for Video4Linux");
916MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/bt819.c b/drivers/media/video/bt819.c
new file mode 100644
index 00000000000..cf0db2554a8
--- /dev/null
+++ b/drivers/media/video/bt819.c
@@ -0,0 +1,660 @@
1/*
2 * bt819 - BT819A VideoStream Decoder (Rockwell Part)
3 *
4 * Copyright (C) 1999 Mike Bernson <mike@mlb.org>
5 * Copyright (C) 1998 Dave Perks <dperks@ibm.net>
6 *
7 * Modifications for LML33/DC10plus unified driver
8 * Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>
9 *
10 * Changes by Ronald Bultje <rbultje@ronald.bitfreak.net>
11 * - moved over to linux>=2.4.x i2c protocol (9/9/2002)
12 *
13 * This code was modify/ported from the saa7111 driver written
14 * by Dave Perks.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 */
30
31#include <linux/module.h>
32#include <linux/init.h>
33#include <linux/delay.h>
34#include <linux/errno.h>
35#include <linux/fs.h>
36#include <linux/kernel.h>
37#include <linux/major.h>
38#include <linux/slab.h>
39#include <linux/mm.h>
40#include <linux/pci.h>
41#include <linux/signal.h>
42#include <asm/io.h>
43#include <asm/pgtable.h>
44#include <asm/page.h>
45#include <linux/sched.h>
46#include <asm/segment.h>
47#include <linux/types.h>
48
49#include <linux/videodev.h>
50#include <asm/uaccess.h>
51
52MODULE_DESCRIPTION("Brooktree-819 video decoder driver");
53MODULE_AUTHOR("Mike Bernson & Dave Perks");
54MODULE_LICENSE("GPL");
55
56#include <linux/i2c.h>
57#include <linux/i2c-dev.h>
58
59#define I2C_NAME(s) (s)->name
60
61#include <linux/video_decoder.h>
62
63static int debug = 0;
64module_param(debug, int, 0);
65MODULE_PARM_DESC(debug, "Debug level (0-1)");
66
67#define dprintk(num, format, args...) \
68 do { \
69 if (debug >= num) \
70 printk(format, ##args); \
71 } while (0)
72
73/* ----------------------------------------------------------------------- */
74
75struct bt819 {
76 unsigned char reg[32];
77
78 int initialized;
79 int norm;
80 int input;
81 int enable;
82 int bright;
83 int contrast;
84 int hue;
85 int sat;
86};
87
88struct timing {
89 int hactive;
90 int hdelay;
91 int vactive;
92 int vdelay;
93 int hscale;
94 int vscale;
95};
96
97/* for values, see the bt819 datasheet */
98static struct timing timing_data[] = {
99 {864 - 24, 20, 625 - 2, 1, 0x0504, 0x0000},
100 {858 - 24, 20, 525 - 2, 1, 0x00f8, 0x0000},
101};
102
103#define I2C_BT819 0x8a
104
105/* ----------------------------------------------------------------------- */
106
107static inline int
108bt819_write (struct i2c_client *client,
109 u8 reg,
110 u8 value)
111{
112 struct bt819 *decoder = i2c_get_clientdata(client);
113
114 decoder->reg[reg] = value;
115 return i2c_smbus_write_byte_data(client, reg, value);
116}
117
118static inline int
119bt819_setbit (struct i2c_client *client,
120 u8 reg,
121 u8 bit,
122 u8 value)
123{
124 struct bt819 *decoder = i2c_get_clientdata(client);
125
126 return bt819_write(client, reg,
127 (decoder->
128 reg[reg] & ~(1 << bit)) |
129 (value ? (1 << bit) : 0));
130}
131
132static int
133bt819_write_block (struct i2c_client *client,
134 const u8 *data,
135 unsigned int len)
136{
137 int ret = -1;
138 u8 reg;
139
140 /* the bt819 has an autoincrement function, use it if
141 * the adapter understands raw I2C */
142 if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
143 /* do raw I2C, not smbus compatible */
144 struct bt819 *decoder = i2c_get_clientdata(client);
145 struct i2c_msg msg;
146 u8 block_data[32];
147
148 msg.addr = client->addr;
149 msg.flags = 0;
150 while (len >= 2) {
151 msg.buf = (char *) block_data;
152 msg.len = 0;
153 block_data[msg.len++] = reg = data[0];
154 do {
155 block_data[msg.len++] =
156 decoder->reg[reg++] = data[1];
157 len -= 2;
158 data += 2;
159 } while (len >= 2 && data[0] == reg &&
160 msg.len < 32);
161 if ((ret = i2c_transfer(client->adapter,
162 &msg, 1)) < 0)
163 break;
164 }
165 } else {
166 /* do some slow I2C emulation kind of thing */
167 while (len >= 2) {
168 reg = *data++;
169 if ((ret = bt819_write(client, reg, *data++)) < 0)
170 break;
171 len -= 2;
172 }
173 }
174
175 return ret;
176}
177
178static inline int
179bt819_read (struct i2c_client *client,
180 u8 reg)
181{
182 return i2c_smbus_read_byte_data(client, reg);
183}
184
185static int
186bt819_init (struct i2c_client *client)
187{
188 struct bt819 *decoder = i2c_get_clientdata(client);
189
190 static unsigned char init[] = {
191 //0x1f, 0x00, /* Reset */
192 0x01, 0x59, /* 0x01 input format */
193 0x02, 0x00, /* 0x02 temporal decimation */
194 0x03, 0x12, /* 0x03 Cropping msb */
195 0x04, 0x16, /* 0x04 Vertical Delay, lsb */
196 0x05, 0xe0, /* 0x05 Vertical Active lsb */
197 0x06, 0x80, /* 0x06 Horizontal Delay lsb */
198 0x07, 0xd0, /* 0x07 Horizontal Active lsb */
199 0x08, 0x00, /* 0x08 Horizontal Scaling msb */
200 0x09, 0xf8, /* 0x09 Horizontal Scaling lsb */
201 0x0a, 0x00, /* 0x0a Brightness control */
202 0x0b, 0x30, /* 0x0b Miscellaneous control */
203 0x0c, 0xd8, /* 0x0c Luma Gain lsb */
204 0x0d, 0xfe, /* 0x0d Chroma Gain (U) lsb */
205 0x0e, 0xb4, /* 0x0e Chroma Gain (V) msb */
206 0x0f, 0x00, /* 0x0f Hue control */
207 0x12, 0x04, /* 0x12 Output Format */
208 0x13, 0x20, /* 0x13 Vertial Scaling msb 0x00
209 chroma comb OFF, line drop scaling, interlace scaling
210 BUG? Why does turning the chroma comb on fuck up color?
211 Bug in the bt819 stepping on my board?
212 */
213 0x14, 0x00, /* 0x14 Vertial Scaling lsb */
214 0x16, 0x07, /* 0x16 Video Timing Polarity
215 ACTIVE=active low
216 FIELD: high=odd,
217 vreset=active high,
218 hreset=active high */
219 0x18, 0x68, /* 0x18 AGC Delay */
220 0x19, 0x5d, /* 0x19 Burst Gate Delay */
221 0x1a, 0x80, /* 0x1a ADC Interface */
222 };
223
224 struct timing *timing = &timing_data[decoder->norm];
225
226 init[0x03 * 2 - 1] =
227 (((timing->vdelay >> 8) & 0x03) << 6) | (((timing->
228 vactive >> 8) &
229 0x03) << 4) |
230 (((timing->hdelay >> 8) & 0x03) << 2) | ((timing->
231 hactive >> 8) &
232 0x03);
233 init[0x04 * 2 - 1] = timing->vdelay & 0xff;
234 init[0x05 * 2 - 1] = timing->vactive & 0xff;
235 init[0x06 * 2 - 1] = timing->hdelay & 0xff;
236 init[0x07 * 2 - 1] = timing->hactive & 0xff;
237 init[0x08 * 2 - 1] = timing->hscale >> 8;
238 init[0x09 * 2 - 1] = timing->hscale & 0xff;
239 /* 0x15 in array is address 0x19 */
240 init[0x15 * 2 - 1] = (decoder->norm == 0) ? 115 : 93; /* Chroma burst delay */
241 /* reset */
242 bt819_write(client, 0x1f, 0x00);
243 mdelay(1);
244
245 /* init */
246 return bt819_write_block(client, init, sizeof(init));
247
248}
249
250/* ----------------------------------------------------------------------- */
251
252static int
253bt819_command (struct i2c_client *client,
254 unsigned int cmd,
255 void *arg)
256{
257 int temp;
258
259 struct bt819 *decoder = i2c_get_clientdata(client);
260
261 if (!decoder->initialized) { // First call to bt819_init could be
262 bt819_init(client); // without #FRST = 0
263 decoder->initialized = 1;
264 }
265
266 switch (cmd) {
267
268 case 0:
269 /* This is just for testing!!! */
270 bt819_init(client);
271 break;
272
273 case DECODER_GET_CAPABILITIES:
274 {
275 struct video_decoder_capability *cap = arg;
276
277 cap->flags = VIDEO_DECODER_PAL |
278 VIDEO_DECODER_NTSC |
279 VIDEO_DECODER_AUTO |
280 VIDEO_DECODER_CCIR;
281 cap->inputs = 8;
282 cap->outputs = 1;
283 }
284 break;
285
286 case DECODER_GET_STATUS:
287 {
288 int *iarg = arg;
289 int status;
290 int res;
291
292 status = bt819_read(client, 0x00);
293 res = 0;
294 if ((status & 0x80)) {
295 res |= DECODER_STATUS_GOOD;
296 }
297 switch (decoder->norm) {
298 case VIDEO_MODE_NTSC:
299 res |= DECODER_STATUS_NTSC;
300 break;
301 case VIDEO_MODE_PAL:
302 res |= DECODER_STATUS_PAL;
303 break;
304 default:
305 case VIDEO_MODE_AUTO:
306 if ((status & 0x10)) {
307 res |= DECODER_STATUS_PAL;
308 } else {
309 res |= DECODER_STATUS_NTSC;
310 }
311 break;
312 }
313 res |= DECODER_STATUS_COLOR;
314 *iarg = res;
315
316 dprintk(1, KERN_INFO "%s: get status %x\n", I2C_NAME(client),
317 *iarg);
318 }
319 break;
320
321 case DECODER_SET_NORM:
322 {
323 int *iarg = arg;
324 struct timing *timing = NULL;
325
326 dprintk(1, KERN_INFO "%s: set norm %x\n", I2C_NAME(client),
327 *iarg);
328
329 switch (*iarg) {
330 case VIDEO_MODE_NTSC:
331 bt819_setbit(client, 0x01, 0, 1);
332 bt819_setbit(client, 0x01, 1, 0);
333 bt819_setbit(client, 0x01, 5, 0);
334 bt819_write(client, 0x18, 0x68);
335 bt819_write(client, 0x19, 0x5d);
336 //bt819_setbit(client, 0x1a, 5, 1);
337 timing = &timing_data[VIDEO_MODE_NTSC];
338 break;
339 case VIDEO_MODE_PAL:
340 bt819_setbit(client, 0x01, 0, 1);
341 bt819_setbit(client, 0x01, 1, 1);
342 bt819_setbit(client, 0x01, 5, 1);
343 bt819_write(client, 0x18, 0x7f);
344 bt819_write(client, 0x19, 0x72);
345 //bt819_setbit(client, 0x1a, 5, 0);
346 timing = &timing_data[VIDEO_MODE_PAL];
347 break;
348 case VIDEO_MODE_AUTO:
349 bt819_setbit(client, 0x01, 0, 0);
350 bt819_setbit(client, 0x01, 1, 0);
351 break;
352 default:
353 dprintk(1,
354 KERN_ERR
355 "%s: unsupported norm %d\n",
356 I2C_NAME(client), *iarg);
357 return -EINVAL;
358 }
359
360 if (timing) {
361 bt819_write(client, 0x03,
362 (((timing->vdelay >> 8) & 0x03) << 6) |
363 (((timing->vactive >> 8) & 0x03) << 4) |
364 (((timing->hdelay >> 8) & 0x03) << 2) |
365 ((timing->hactive >> 8) & 0x03) );
366 bt819_write(client, 0x04, timing->vdelay & 0xff);
367 bt819_write(client, 0x05, timing->vactive & 0xff);
368 bt819_write(client, 0x06, timing->hdelay & 0xff);
369 bt819_write(client, 0x07, timing->hactive & 0xff);
370 bt819_write(client, 0x08, (timing->hscale >> 8) & 0xff);
371 bt819_write(client, 0x09, timing->hscale & 0xff);
372 }
373
374 decoder->norm = *iarg;
375 }
376 break;
377
378 case DECODER_SET_INPUT:
379 {
380 int *iarg = arg;
381
382 dprintk(1, KERN_INFO "%s: set input %x\n", I2C_NAME(client),
383 *iarg);
384
385 if (*iarg < 0 || *iarg > 7) {
386 return -EINVAL;
387 }
388
389 if (decoder->input != *iarg) {
390 decoder->input = *iarg;
391 /* select mode */
392 if (decoder->input == 0) {
393 bt819_setbit(client, 0x0b, 6, 0);
394 bt819_setbit(client, 0x1a, 1, 1);
395 } else {
396 bt819_setbit(client, 0x0b, 6, 1);
397 bt819_setbit(client, 0x1a, 1, 0);
398 }
399 }
400 }
401 break;
402
403 case DECODER_SET_OUTPUT:
404 {
405 int *iarg = arg;
406
407 dprintk(1, KERN_INFO "%s: set output %x\n", I2C_NAME(client),
408 *iarg);
409
410 /* not much choice of outputs */
411 if (*iarg != 0) {
412 return -EINVAL;
413 }
414 }
415 break;
416
417 case DECODER_ENABLE_OUTPUT:
418 {
419 int *iarg = arg;
420 int enable = (*iarg != 0);
421
422 dprintk(1, KERN_INFO "%s: enable output %x\n",
423 I2C_NAME(client), *iarg);
424
425 if (decoder->enable != enable) {
426 decoder->enable = enable;
427
428 if (decoder->enable) {
429 bt819_setbit(client, 0x16, 7, 0);
430 } else {
431 bt819_setbit(client, 0x16, 7, 1);
432 }
433 }
434 }
435 break;
436
437 case DECODER_SET_PICTURE:
438 {
439 struct video_picture *pic = arg;
440
441 dprintk(1,
442 KERN_INFO
443 "%s: set picture brightness %d contrast %d colour %d\n",
444 I2C_NAME(client), pic->brightness, pic->contrast,
445 pic->colour);
446
447
448 if (decoder->bright != pic->brightness) {
449 /* We want -128 to 127 we get 0-65535 */
450 decoder->bright = pic->brightness;
451 bt819_write(client, 0x0a,
452 (decoder->bright >> 8) - 128);
453 }
454
455 if (decoder->contrast != pic->contrast) {
456 /* We want 0 to 511 we get 0-65535 */
457 decoder->contrast = pic->contrast;
458 bt819_write(client, 0x0c,
459 (decoder->contrast >> 7) & 0xff);
460 bt819_setbit(client, 0x0b, 2,
461 ((decoder->contrast >> 15) & 0x01));
462 }
463
464 if (decoder->sat != pic->colour) {
465 /* We want 0 to 511 we get 0-65535 */
466 decoder->sat = pic->colour;
467 bt819_write(client, 0x0d,
468 (decoder->sat >> 7) & 0xff);
469 bt819_setbit(client, 0x0b, 1,
470 ((decoder->sat >> 15) & 0x01));
471
472 temp = (decoder->sat * 201) / 237;
473 bt819_write(client, 0x0e, (temp >> 7) & 0xff);
474 bt819_setbit(client, 0x0b, 0, (temp >> 15) & 0x01);
475 }
476
477 if (decoder->hue != pic->hue) {
478 /* We want -128 to 127 we get 0-65535 */
479 decoder->hue = pic->hue;
480 bt819_write(client, 0x0f,
481 128 - (decoder->hue >> 8));
482 }
483 }
484 break;
485
486 default:
487 return -EINVAL;
488 }
489
490 return 0;
491}
492
493/* ----------------------------------------------------------------------- */
494
495/*
496 * Generic i2c probe
497 * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
498 */
499static unsigned short normal_i2c[] = {
500 I2C_BT819 >> 1,
501 I2C_CLIENT_END,
502};
503static unsigned short normal_i2c_range[] = { I2C_CLIENT_END };
504
505static unsigned short probe[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
506static unsigned short probe_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
507static unsigned short ignore[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
508static unsigned short ignore_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
509static unsigned short force[2] = { I2C_CLIENT_END , I2C_CLIENT_END };
510
511static struct i2c_client_address_data addr_data = {
512 .normal_i2c = normal_i2c,
513 .normal_i2c_range = normal_i2c_range,
514 .probe = probe,
515 .probe_range = probe_range,
516 .ignore = ignore,
517 .ignore_range = ignore_range,
518 .force = force
519};
520
521static struct i2c_driver i2c_driver_bt819;
522
523static int
524bt819_detect_client (struct i2c_adapter *adapter,
525 int address,
526 int kind)
527{
528 int i, id;
529 struct bt819 *decoder;
530 struct i2c_client *client;
531
532 dprintk(1,
533 KERN_INFO
534 "saa7111.c: detecting bt819 client on address 0x%x\n",
535 address << 1);
536
537 /* Check if the adapter supports the needed features */
538 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
539 return 0;
540
541 client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
542 if (client == 0)
543 return -ENOMEM;
544 memset(client, 0, sizeof(struct i2c_client));
545 client->addr = address;
546 client->adapter = adapter;
547 client->driver = &i2c_driver_bt819;
548 client->flags = I2C_CLIENT_ALLOW_USE;
549
550 decoder = kmalloc(sizeof(struct bt819), GFP_KERNEL);
551 if (decoder == NULL) {
552 kfree(client);
553 return -ENOMEM;
554 }
555
556 memset(decoder, 0, sizeof(struct bt819));
557 decoder->norm = VIDEO_MODE_NTSC;
558 decoder->input = 0;
559 decoder->enable = 1;
560 decoder->bright = 32768;
561 decoder->contrast = 32768;
562 decoder->hue = 32768;
563 decoder->sat = 32768;
564 decoder->initialized = 0;
565 i2c_set_clientdata(client, decoder);
566
567 id = bt819_read(client, 0x17);
568 switch (id & 0xf0) {
569 case 0x70:
570 strlcpy(I2C_NAME(client), "bt819a", sizeof(I2C_NAME(client)));
571 break;
572 case 0x60:
573 strlcpy(I2C_NAME(client), "bt817a", sizeof(I2C_NAME(client)));
574 break;
575 case 0x20:
576 strlcpy(I2C_NAME(client), "bt815a", sizeof(I2C_NAME(client)));
577 break;
578 default:
579 dprintk(1,
580 KERN_ERR
581 "bt819: unknown chip version 0x%x (ver 0x%x)\n",
582 id & 0xf0, id & 0x0f);
583 kfree(decoder);
584 kfree(client);
585 return 0;
586 }
587
588 i = i2c_attach_client(client);
589 if (i) {
590 kfree(client);
591 kfree(decoder);
592 return i;
593 }
594
595 i = bt819_init(client);
596 if (i < 0) {
597 dprintk(1, KERN_ERR "%s_attach: init status %d\n",
598 I2C_NAME(client), i);
599 } else {
600 dprintk(1,
601 KERN_INFO
602 "%s_attach: chip version 0x%x at address 0x%x\n",
603 I2C_NAME(client), id & 0x0f,
604 client->addr << 1);
605 }
606
607 return 0;
608}
609
610static int
611bt819_attach_adapter (struct i2c_adapter *adapter)
612{
613 return i2c_probe(adapter, &addr_data, &bt819_detect_client);
614}
615
616static int
617bt819_detach_client (struct i2c_client *client)
618{
619 struct bt819 *decoder = i2c_get_clientdata(client);
620 int err;
621
622 err = i2c_detach_client(client);
623 if (err) {
624 return err;
625 }
626
627 kfree(decoder);
628 kfree(client);
629
630 return 0;
631}
632
633/* ----------------------------------------------------------------------- */
634
635static struct i2c_driver i2c_driver_bt819 = {
636 .owner = THIS_MODULE,
637 .name = "bt819",
638
639 .id = I2C_DRIVERID_BT819,
640 .flags = I2C_DF_NOTIFY,
641
642 .attach_adapter = bt819_attach_adapter,
643 .detach_client = bt819_detach_client,
644 .command = bt819_command,
645};
646
647static int __init
648bt819_init_module (void)
649{
650 return i2c_add_driver(&i2c_driver_bt819);
651}
652
653static void __exit
654bt819_exit (void)
655{
656 i2c_del_driver(&i2c_driver_bt819);
657}
658
659module_init(bt819_init_module);
660module_exit(bt819_exit);
diff --git a/drivers/media/video/bt832.c b/drivers/media/video/bt832.c
new file mode 100644
index 00000000000..efe605a113a
--- /dev/null
+++ b/drivers/media/video/bt832.c
@@ -0,0 +1,271 @@
1/* Driver for Bt832 CMOS Camera Video Processor
2 i2c-addresses: 0x88 or 0x8a
3
4 The BT832 interfaces to a Quartzsight Digital Camera (352x288, 25 or 30 fps)
5 via a 9 pin connector ( 4-wire SDATA, 2-wire i2c, SCLK, VCC, GND).
6 It outputs an 8-bit 4:2:2 YUV or YCrCb video signal which can be directly
7 connected to bt848/bt878 GPIO pins on this purpose.
8 (see: VLSI Vision Ltd. www.vvl.co.uk for camera datasheets)
9
10 Supported Cards:
11 - Pixelview Rev.4E: 0x8a
12 GPIO 0x400000 toggles Bt832 RESET, and the chip changes to i2c 0x88 !
13
14 (c) Gunther Mayer, 2002
15
16 STATUS:
17 - detect chip and hexdump
18 - reset chip and leave low power mode
19 - detect camera present
20
21 TODO:
22 - make it work (find correct setup for Bt832 and Bt878)
23*/
24
25#include <linux/module.h>
26#include <linux/kernel.h>
27#include <linux/i2c.h>
28#include <linux/types.h>
29#include <linux/videodev.h>
30#include <linux/init.h>
31#include <linux/errno.h>
32#include <linux/slab.h>
33
34#include "id.h"
35#include "audiochip.h"
36#include "bttv.h"
37#include "bt832.h"
38
39MODULE_LICENSE("GPL");
40
41/* Addresses to scan */
42static unsigned short normal_i2c[] = {I2C_CLIENT_END};
43static unsigned short normal_i2c_range[] = {I2C_BT832_ALT1>>1,I2C_BT832_ALT2>>1,I2C_CLIENT_END};
44I2C_CLIENT_INSMOD;
45
46/* ---------------------------------------------------------------------- */
47
48#define dprintk if (debug) printk
49
50static int bt832_detach(struct i2c_client *client);
51
52
53static struct i2c_driver driver;
54static struct i2c_client client_template;
55
56struct bt832 {
57 struct i2c_client client;
58};
59
60int bt832_hexdump(struct i2c_client *i2c_client_s, unsigned char *buf)
61{
62 int i,rc;
63 buf[0]=0x80; // start at register 0 with auto-increment
64 if (1 != (rc = i2c_master_send(i2c_client_s,buf,1)))
65 printk("bt832: i2c i/o error: rc == %d (should be 1)\n",rc);
66
67 for(i=0;i<65;i++)
68 buf[i]=0;
69 if (65 != (rc=i2c_master_recv(i2c_client_s,buf,65)))
70 printk("bt832: i2c i/o error: rc == %d (should be 65)\n",rc);
71
72 // Note: On READ the first byte is the current index
73 // (e.g. 0x80, what we just wrote)
74
75 if(1) {
76 int i;
77 printk("BT832 hexdump:\n");
78 for(i=1;i<65;i++) {
79 if(i!=1) {
80 if(((i-1)%8)==0) printk(" ");
81 if(((i-1)%16)==0) printk("\n");
82 }
83 printk(" %02x",buf[i]);
84 }
85 printk("\n");
86 }
87 return 0;
88}
89
90// Return: 1 (is a bt832), 0 (No bt832 here)
91int bt832_init(struct i2c_client *i2c_client_s)
92{
93 unsigned char *buf;
94 int rc;
95
96 buf=kmalloc(65,GFP_KERNEL);
97 bt832_hexdump(i2c_client_s,buf);
98
99 if(buf[0x40] != 0x31) {
100 printk("bt832: this i2c chip is no bt832 (id=%02x). Detaching.\n",buf[0x40]);
101 kfree(buf);
102 return 0;
103 }
104
105 printk("Write 0 tp VPSTATUS\n");
106 buf[0]=BT832_VP_STATUS; // Reg.52
107 buf[1]= 0x00;
108 if (2 != (rc = i2c_master_send(i2c_client_s,buf,2)))
109 printk("bt832: i2c i/o error VPS: rc == %d (should be 2)\n",rc);
110
111 bt832_hexdump(i2c_client_s,buf);
112
113
114 // Leave low power mode:
115 printk("Bt832: leave low power mode.\n");
116 buf[0]=BT832_CAM_SETUP0; //0x39 57
117 buf[1]=0x08;
118 if (2 != (rc = i2c_master_send(i2c_client_s,buf,2)))
119 printk("bt832: i2c i/o error LLPM: rc == %d (should be 2)\n",rc);
120
121 bt832_hexdump(i2c_client_s,buf);
122
123 printk("Write 0 tp VPSTATUS\n");
124 buf[0]=BT832_VP_STATUS; // Reg.52
125 buf[1]= 0x00;
126 if (2 != (rc = i2c_master_send(i2c_client_s,buf,2)))
127 printk("bt832: i2c i/o error VPS: rc == %d (should be 2)\n",rc);
128
129 bt832_hexdump(i2c_client_s,buf);
130
131
132 // Enable Output
133 printk("Enable Output\n");
134 buf[0]=BT832_VP_CONTROL1; // Reg.40
135 buf[1]= 0x27 & (~0x01); // Default | !skip
136 if (2 != (rc = i2c_master_send(i2c_client_s,buf,2)))
137 printk("bt832: i2c i/o error EO: rc == %d (should be 2)\n",rc);
138
139 bt832_hexdump(i2c_client_s,buf);
140
141#if 0
142 // Full 30/25 Frame rate
143 printk("Full 30/25 Frame rate\n");
144 buf[0]=BT832_VP_CONTROL0; // Reg.39
145 buf[1]= 0x00;
146 if (2 != (rc = i2c_master_send(i2c_client_s,buf,2)))
147 printk("bt832: i2c i/o error FFR: rc == %d (should be 2)\n",rc);
148
149 bt832_hexdump(i2c_client_s,buf);
150#endif
151
152#if 1
153 // for testing (even works when no camera attached)
154 printk("bt832: *** Generate NTSC M Bars *****\n");
155 buf[0]=BT832_VP_TESTCONTROL0; // Reg. 42
156 buf[1]=3; // Generate NTSC System M bars, Generate Frame timing internally
157 if (2 != (rc = i2c_master_send(i2c_client_s,buf,2)))
158 printk("bt832: i2c i/o error MBAR: rc == %d (should be 2)\n",rc);
159#endif
160
161 printk("Bt832: Camera Present: %s\n",
162 (buf[1+BT832_CAM_STATUS] & BT832_56_CAMERA_PRESENT) ? "yes":"no");
163
164 bt832_hexdump(i2c_client_s,buf);
165 kfree(buf);
166 return 1;
167}
168
169
170
171static int bt832_attach(struct i2c_adapter *adap, int addr,
172 unsigned short flags, int kind)
173{
174 struct bt832 *t;
175
176 printk("bt832_attach\n");
177
178 client_template.adapter = adap;
179 client_template.addr = addr;
180
181 printk("bt832: chip found @ 0x%x\n", addr<<1);
182
183 if (NULL == (t = kmalloc(sizeof(*t), GFP_KERNEL)))
184 return -ENOMEM;
185 memset(t,0,sizeof(*t));
186 t->client = client_template;
187 t->client.data = t;
188 i2c_attach_client(&t->client);
189
190 if(! bt832_init(&t->client)) {
191 bt832_detach(&t->client);
192 return -1;
193 }
194
195 return 0;
196}
197
198static int bt832_probe(struct i2c_adapter *adap)
199{
200 if (adap->class & I2C_CLASS_TV_ANALOG)
201 return i2c_probe(adap, &addr_data, bt832_attach);
202 return 0;
203}
204
205static int bt832_detach(struct i2c_client *client)
206{
207 struct bt832 *t = (struct bt832*)client->data;
208
209 printk("bt832: detach.\n");
210 i2c_detach_client(client);
211 kfree(t);
212 return 0;
213}
214
215static int
216bt832_command(struct i2c_client *client, unsigned int cmd, void *arg)
217{
218 struct bt832 *t = (struct bt832*)client->data;
219
220 printk("bt832: command %x\n",cmd);
221
222 switch (cmd) {
223 case BT832_HEXDUMP: {
224 unsigned char *buf;
225 buf=kmalloc(65,GFP_KERNEL);
226 bt832_hexdump(&t->client,buf);
227 kfree(buf);
228 }
229 break;
230 case BT832_REATTACH:
231 printk("bt832: re-attach\n");
232 i2c_del_driver(&driver);
233 i2c_add_driver(&driver);
234 break;
235 }
236 return 0;
237}
238
239/* ----------------------------------------------------------------------- */
240
241static struct i2c_driver driver = {
242 .owner = THIS_MODULE,
243 .name = "i2c bt832 driver",
244 .id = -1, /* FIXME */
245 .flags = I2C_DF_NOTIFY,
246 .attach_adapter = bt832_probe,
247 .detach_client = bt832_detach,
248 .command = bt832_command,
249};
250static struct i2c_client client_template =
251{
252 .name = "bt832",
253 .flags = I2C_CLIENT_ALLOW_USE,
254 .driver = &driver,
255};
256
257
258int bt832_init_module(void)
259{
260 i2c_add_driver(&driver);
261 return 0;
262}
263
264static void bt832_cleanup_module(void)
265{
266 i2c_del_driver(&driver);
267}
268
269module_init(bt832_init_module);
270module_exit(bt832_cleanup_module);
271
diff --git a/drivers/media/video/bt832.h b/drivers/media/video/bt832.h
new file mode 100644
index 00000000000..7a98c06e0e3
--- /dev/null
+++ b/drivers/media/video/bt832.h
@@ -0,0 +1,305 @@
1/* Bt832 CMOS Camera Video Processor (VP)
2
3 The Bt832 CMOS Camera Video Processor chip connects a Quartsight CMOS
4 color digital camera directly to video capture devices via an 8-bit,
5 4:2:2 YUV or YCrCb video interface.
6
7 i2c addresses: 0x88 or 0x8a
8 */
9
10/* The 64 registers: */
11
12// Input Processor
13#define BT832_OFFSET 0
14#define BT832_RCOMP 1
15#define BT832_G1COMP 2
16#define BT832_G2COMP 3
17#define BT832_BCOMP 4
18// Exposures:
19#define BT832_FINEH 5
20#define BT832_FINEL 6
21#define BT832_COARSEH 7
22#define BT832_COARSEL 8
23#define BT832_CAMGAIN 9
24// Main Processor:
25#define BT832_M00 10
26#define BT832_M01 11
27#define BT832_M02 12
28#define BT832_M10 13
29#define BT832_M11 14
30#define BT832_M12 15
31#define BT832_M20 16
32#define BT832_M21 17
33#define BT832_M22 18
34#define BT832_APCOR 19
35#define BT832_GAMCOR 20
36// Level Accumulator Inputs
37#define BT832_VPCONTROL2 21
38#define BT832_ZONECODE0 22
39#define BT832_ZONECODE1 23
40#define BT832_ZONECODE2 24
41#define BT832_ZONECODE3 25
42// Level Accumulator Outputs:
43#define BT832_RACC 26
44#define BT832_GACC 27
45#define BT832_BACC 28
46#define BT832_BLACKACC 29
47#define BT832_EXP_AGC 30
48#define BT832_LACC0 31
49#define BT832_LACC1 32
50#define BT832_LACC2 33
51#define BT832_LACC3 34
52#define BT832_LACC4 35
53#define BT832_LACC5 36
54#define BT832_LACC6 37
55#define BT832_LACC7 38
56// System:
57#define BT832_VP_CONTROL0 39
58#define BT832_VP_CONTROL1 40
59#define BT832_THRESH 41
60#define BT832_VP_TESTCONTROL0 42
61#define BT832_VP_DMCODE 43
62#define BT832_ACB_CONFIG 44
63#define BT832_ACB_GNBASE 45
64#define BT832_ACB_MU 46
65#define BT832_CAM_TEST0 47
66#define BT832_AEC_CONFIG 48
67#define BT832_AEC_TL 49
68#define BT832_AEC_TC 50
69#define BT832_AEC_TH 51
70// Status:
71#define BT832_VP_STATUS 52
72#define BT832_VP_LINECOUNT 53
73#define BT832_CAM_DEVICEL 54 // e.g. 0x19
74#define BT832_CAM_DEVICEH 55 // e.g. 0x40 == 0x194 Mask0, 0x194 = 404 decimal (VVL-404 camera)
75#define BT832_CAM_STATUS 56
76 #define BT832_56_CAMERA_PRESENT 0x20
77//Camera Setups:
78#define BT832_CAM_SETUP0 57
79#define BT832_CAM_SETUP1 58
80#define BT832_CAM_SETUP2 59
81#define BT832_CAM_SETUP3 60
82// System:
83#define BT832_DEFCOR 61
84#define BT832_VP_TESTCONTROL1 62
85#define BT832_DEVICE_ID 63
86# define BT832_DEVICE_ID__31 0x31 // Bt832 has ID 0x31
87
88/* STMicroelectronivcs VV5404 camera module
89 i2c: 0x20: sensor address
90 i2c: 0xa0: eeprom for ccd defect map
91 */
92#define VV5404_device_h 0x00 // 0x19
93#define VV5404_device_l 0x01 // 0x40
94#define VV5404_status0 0x02
95#define VV5404_linecountc 0x03 // current line counter
96#define VV5404_linecountl 0x04
97#define VV5404_setup0 0x10
98#define VV5404_setup1 0x11
99#define VV5404_setup2 0x12
100#define VV5404_setup4 0x14
101#define VV5404_setup5 0x15
102#define VV5404_fine_h 0x20 // fine exposure
103#define VV5404_fine_l 0x21
104#define VV5404_coarse_h 0x22 //coarse exposure
105#define VV5404_coarse_l 0x23
106#define VV5404_gain 0x24 // ADC pre-amp gain setting
107#define VV5404_clk_div 0x25
108#define VV5404_cr 0x76 // control register
109#define VV5404_as0 0x77 // ADC setup register
110
111
112// IOCTL
113#define BT832_HEXDUMP _IOR('b',1,int)
114#define BT832_REATTACH _IOR('b',2,int)
115
116/* from BT8x8VXD/capdrv/dialogs.cpp */
117
118/*
119typedef enum { SVI, Logitech, Rockwell } CAMERA;
120
121static COMBOBOX_ENTRY gwCameraOptions[] =
122{
123 { SVI, "Silicon Vision 512N" },
124 { Logitech, "Logitech VideoMan 1.3" },
125 { Rockwell, "Rockwell QuartzSight PCI 1.0" }
126};
127
128// SRAM table values
129//===========================================================================
130typedef enum { TGB_NTSC624, TGB_NTSC780, TGB_NTSC858, TGB_NTSC392 } TimeGenByte;
131
132BYTE SRAMTable[][ 60 ] =
133{
134 // TGB_NTSC624
135 {
136 0x33, // size of table = 51
137 0x0E, 0xC0, 0x00, 0x00, 0x90, 0x02, 0x03, 0x10, 0x03, 0x06,
138 0x10, 0x04, 0x12, 0x12, 0x05, 0x02, 0x13, 0x04, 0x19, 0x00,
139 0x04, 0x39, 0x00, 0x06, 0x59, 0x08, 0x03, 0x85, 0x08, 0x07,
140 0x03, 0x50, 0x00, 0x91, 0x40, 0x00, 0x11, 0x01, 0x01, 0x4D,
141 0x0D, 0x02, 0x03, 0x11, 0x01, 0x05, 0x37, 0x00, 0x37, 0x21, 0x00
142 },
143 // TGB_NTSC780
144 {
145 0x33, // size of table = 51
146 0x0e, 0xc0, 0x00, 0x00, 0x90, 0xe2, 0x03, 0x10, 0x03, 0x06,
147 0x10, 0x34, 0x12, 0x12, 0x65, 0x02, 0x13, 0x24, 0x19, 0x00,
148 0x24, 0x39, 0x00, 0x96, 0x59, 0x08, 0x93, 0x85, 0x08, 0x97,
149 0x03, 0x50, 0x50, 0xaf, 0x40, 0x30, 0x5f, 0x01, 0xf1, 0x7f,
150 0x0d, 0xf2, 0x03, 0x11, 0xf1, 0x05, 0x37, 0x30, 0x85, 0x21, 0x50
151 },
152 // TGB_NTSC858
153 {
154 0x33, // size of table = 51
155 0x0c, 0xc0, 0x00, 0x00, 0x90, 0xc2, 0x03, 0x10, 0x03, 0x06,
156 0x10, 0x34, 0x12, 0x12, 0x65, 0x02, 0x13, 0x24, 0x19, 0x00,
157 0x24, 0x39, 0x00, 0x96, 0x59, 0x08, 0x93, 0x83, 0x08, 0x97,
158 0x03, 0x50, 0x30, 0xc0, 0x40, 0x30, 0x86, 0x01, 0x01, 0xa6,
159 0x0d, 0x62, 0x03, 0x11, 0x61, 0x05, 0x37, 0x30, 0xac, 0x21, 0x50
160 },
161 // TGB_NTSC392
162 // This table has been modified to be used for Fusion Rev D
163 {
164 0x2A, // size of table = 42
165 0x06, 0x08, 0x04, 0x0a, 0xc0, 0x00, 0x18, 0x08, 0x03, 0x24,
166 0x08, 0x07, 0x02, 0x90, 0x02, 0x08, 0x10, 0x04, 0x0c, 0x10,
167 0x05, 0x2c, 0x11, 0x04, 0x55, 0x48, 0x00, 0x05, 0x50, 0x00,
168 0xbf, 0x0c, 0x02, 0x2f, 0x3d, 0x00, 0x2f, 0x3f, 0x00, 0xc3,
169 0x20, 0x00
170 }
171};
172
173//===========================================================================
174// This is the structure of the camera specifications
175//===========================================================================
176typedef struct tag_cameraSpec
177{
178 SignalFormat signal; // which digital signal format the camera has
179 VideoFormat vidFormat; // video standard
180 SyncVideoRef syncRef; // which sync video reference is used
181 State syncOutput; // enable sync output for sync video input?
182 DecInputClk iClk; // which input clock is used
183 TimeGenByte tgb; // which timing generator byte does the camera use
184 int HReset; // select 64, 48, 32, or 16 CLKx1 for HReset
185 PLLFreq pllFreq; // what synthesized frequency to set PLL to
186 VSIZEPARMS vSize; // video size the camera produces
187 int lineCount; // expected total number of half-line per frame - 1
188 BOOL interlace; // interlace signal?
189} CameraSpec;
190
191//===========================================================================
192// <UPDATE REQUIRED>
193// Camera specifications database. Update this table whenever camera spec
194// has been changed or added/deleted supported camera models
195//===========================================================================
196static CameraSpec dbCameraSpec[ N_CAMERAOPTIONS ] =
197{ // Silicon Vision 512N
198 { Signal_CCIR656, VFormat_NTSC, VRef_alignedCb, Off, DecClk_GPCLK, TGB_NTSC624, 64, KHz19636,
199 // Clkx1_HACTIVE, Clkx1_HDELAY, VActive, VDelay, linesPerField; lineCount, Interlace
200 { 512, 0x64, 480, 0x13, 240 }, 0, TRUE
201 },
202 // Logitech VideoMan 1.3
203 { Signal_CCIR656, VFormat_NTSC, VRef_alignedCb, Off, DecClk_GPCLK, TGB_NTSC780, 64, KHz24545,
204 // Clkx1_HACTIVE, Clkx1_HDELAY, VActive, VDelay, linesPerField; lineCount, Interlace
205 { 640, 0x80, 480, 0x1A, 240 }, 0, TRUE
206 },
207 // Rockwell QuartzSight
208 // Note: Fusion Rev D (rev ID 0x02) and later supports 16 pixels for HReset which is preferable.
209 // Use 32 for earlier version of hardware. Clkx1_HDELAY also changed from 0x27 to 0x20.
210 { Signal_CCIR656, VFormat_NTSC, VRef_alignedCb, Off, DecClk_GPCLK, TGB_NTSC392, 16, KHz28636,
211 // Clkx1_HACTIVE, Clkx1_HDELAY, VActive, VDelay, linesPerField; lineCount, Interlace
212 { 352, 0x20, 576, 0x08, 288 }, 607, FALSE
213 }
214};
215*/
216
217/*
218The corresponding APIs required to be invoked are:
219SetConnector( ConCamera, TRUE/FALSE );
220SetSignalFormat( spec.signal );
221SetVideoFormat( spec.vidFormat );
222SetSyncVideoRef( spec.syncRef );
223SetEnableSyncOutput( spec.syncOutput );
224SetTimGenByte( SRAMTable[ spec.tgb ], SRAMTableSize[ spec.tgb ] );
225SetHReset( spec.HReset );
226SetPLL( spec.pllFreq );
227SetDecInputClock( spec.iClk );
228SetVideoInfo( spec.vSize );
229SetTotalLineCount( spec.lineCount );
230SetInterlaceMode( spec.interlace );
231*/
232
233/* from web:
234 Video Sampling
235Digital video is a sampled form of analog video. The most common sampling schemes in use today are:
236 Pixel Clock Horiz Horiz Vert
237 Rate Total Active
238NTSC square pixel 12.27 MHz 780 640 525
239NTSC CCIR-601 13.5 MHz 858 720 525
240NTSC 4FSc 14.32 MHz 910 768 525
241PAL square pixel 14.75 MHz 944 768 625
242PAL CCIR-601 13.5 MHz 864 720 625
243PAL 4FSc 17.72 MHz 1135 948 625
244
245For the CCIR-601 standards, the sampling is based on a static orthogonal sampling grid. The luminance component (Y) is sampled at 13.5 MHz, while the two color difference signals, Cr and Cb are sampled at half that, or 6.75 MHz. The Cr and Cb samples are colocated with alternate Y samples, and they are taken at the same position on each line, such that one sample is coincident with the 50% point of the falling edge of analog sync. The samples are coded to either 8 or 10 bits per component.
246*/
247
248/* from DScaler:*/
249/*
250//===========================================================================
251// CCIR656 Digital Input Support: The tables were taken from DScaler proyect
252//
253// 13 Dec 2000 - Michael Eskin, Conexant Systems - Initial version
254//
255
256//===========================================================================
257// Timing generator SRAM table values for CCIR601 720x480 NTSC
258//===========================================================================
259// For NTSC CCIR656
260BYTE BtCard::SRAMTable_NTSC[] =
261{
262 // SRAM Timing Table for NTSC
263 0x0c, 0xc0, 0x00,
264 0x00, 0x90, 0xc2,
265 0x03, 0x10, 0x03,
266 0x06, 0x10, 0x34,
267 0x12, 0x12, 0x65,
268 0x02, 0x13, 0x24,
269 0x19, 0x00, 0x24,
270 0x39, 0x00, 0x96,
271 0x59, 0x08, 0x93,
272 0x83, 0x08, 0x97,
273 0x03, 0x50, 0x30,
274 0xc0, 0x40, 0x30,
275 0x86, 0x01, 0x01,
276 0xa6, 0x0d, 0x62,
277 0x03, 0x11, 0x61,
278 0x05, 0x37, 0x30,
279 0xac, 0x21, 0x50
280};
281
282//===========================================================================
283// Timing generator SRAM table values for CCIR601 720x576 NTSC
284//===========================================================================
285// For PAL CCIR656
286BYTE BtCard::SRAMTable_PAL[] =
287{
288 // SRAM Timing Table for PAL
289 0x36, 0x11, 0x01,
290 0x00, 0x90, 0x02,
291 0x05, 0x10, 0x04,
292 0x16, 0x14, 0x05,
293 0x11, 0x00, 0x04,
294 0x12, 0xc0, 0x00,
295 0x31, 0x00, 0x06,
296 0x51, 0x08, 0x03,
297 0x89, 0x08, 0x07,
298 0xc0, 0x44, 0x00,
299 0x81, 0x01, 0x01,
300 0xa9, 0x0d, 0x02,
301 0x02, 0x50, 0x03,
302 0x37, 0x3d, 0x00,
303 0xaf, 0x21, 0x00,
304};
305*/
diff --git a/drivers/media/video/bt848.h b/drivers/media/video/bt848.h
new file mode 100644
index 00000000000..0bcd95303bb
--- /dev/null
+++ b/drivers/media/video/bt848.h
@@ -0,0 +1,366 @@
1/*
2 bt848.h - Bt848 register offsets
3
4 Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19*/
20
21#ifndef _BT848_H_
22#define _BT848_H_
23
24#ifndef PCI_VENDOR_ID_BROOKTREE
25#define PCI_VENDOR_ID_BROOKTREE 0x109e
26#endif
27#ifndef PCI_DEVICE_ID_BT848
28#define PCI_DEVICE_ID_BT848 0x350
29#endif
30#ifndef PCI_DEVICE_ID_BT849
31#define PCI_DEVICE_ID_BT849 0x351
32#endif
33#ifndef PCI_DEVICE_ID_BT878
34#define PCI_DEVICE_ID_BT878 0x36e
35#endif
36#ifndef PCI_DEVICE_ID_BT879
37#define PCI_DEVICE_ID_BT879 0x36f
38#endif
39
40
41/* Brooktree 848 registers */
42
43#define BT848_DSTATUS 0x000
44#define BT848_DSTATUS_PRES (1<<7)
45#define BT848_DSTATUS_HLOC (1<<6)
46#define BT848_DSTATUS_FIELD (1<<5)
47#define BT848_DSTATUS_NUML (1<<4)
48#define BT848_DSTATUS_CSEL (1<<3)
49#define BT848_DSTATUS_PLOCK (1<<2)
50#define BT848_DSTATUS_LOF (1<<1)
51#define BT848_DSTATUS_COF (1<<0)
52
53#define BT848_IFORM 0x004
54#define BT848_IFORM_HACTIVE (1<<7)
55#define BT848_IFORM_MUXSEL (3<<5)
56#define BT848_IFORM_MUX0 (2<<5)
57#define BT848_IFORM_MUX1 (3<<5)
58#define BT848_IFORM_MUX2 (1<<5)
59#define BT848_IFORM_XTSEL (3<<3)
60#define BT848_IFORM_XT0 (1<<3)
61#define BT848_IFORM_XT1 (2<<3)
62#define BT848_IFORM_XTAUTO (3<<3)
63#define BT848_IFORM_XTBOTH (3<<3)
64#define BT848_IFORM_NTSC 1
65#define BT848_IFORM_NTSC_J 2
66#define BT848_IFORM_PAL_BDGHI 3
67#define BT848_IFORM_PAL_M 4
68#define BT848_IFORM_PAL_N 5
69#define BT848_IFORM_SECAM 6
70#define BT848_IFORM_PAL_NC 7
71#define BT848_IFORM_AUTO 0
72#define BT848_IFORM_NORM 7
73
74#define BT848_TDEC 0x008
75#define BT848_TDEC_DEC_FIELD (1<<7)
76#define BT848_TDEC_FLDALIGN (1<<6)
77#define BT848_TDEC_DEC_RAT (0x1f)
78
79#define BT848_E_CROP 0x00C
80#define BT848_O_CROP 0x08C
81
82#define BT848_E_VDELAY_LO 0x010
83#define BT848_O_VDELAY_LO 0x090
84
85#define BT848_E_VACTIVE_LO 0x014
86#define BT848_O_VACTIVE_LO 0x094
87
88#define BT848_E_HDELAY_LO 0x018
89#define BT848_O_HDELAY_LO 0x098
90
91#define BT848_E_HACTIVE_LO 0x01C
92#define BT848_O_HACTIVE_LO 0x09C
93
94#define BT848_E_HSCALE_HI 0x020
95#define BT848_O_HSCALE_HI 0x0A0
96
97#define BT848_E_HSCALE_LO 0x024
98#define BT848_O_HSCALE_LO 0x0A4
99
100#define BT848_BRIGHT 0x028
101
102#define BT848_E_CONTROL 0x02C
103#define BT848_O_CONTROL 0x0AC
104#define BT848_CONTROL_LNOTCH (1<<7)
105#define BT848_CONTROL_COMP (1<<6)
106#define BT848_CONTROL_LDEC (1<<5)
107#define BT848_CONTROL_CBSENSE (1<<4)
108#define BT848_CONTROL_CON_MSB (1<<2)
109#define BT848_CONTROL_SAT_U_MSB (1<<1)
110#define BT848_CONTROL_SAT_V_MSB (1<<0)
111
112#define BT848_CONTRAST_LO 0x030
113#define BT848_SAT_U_LO 0x034
114#define BT848_SAT_V_LO 0x038
115#define BT848_HUE 0x03C
116
117#define BT848_E_SCLOOP 0x040
118#define BT848_O_SCLOOP 0x0C0
119#define BT848_SCLOOP_CAGC (1<<6)
120#define BT848_SCLOOP_CKILL (1<<5)
121#define BT848_SCLOOP_HFILT_AUTO (0<<3)
122#define BT848_SCLOOP_HFILT_CIF (1<<3)
123#define BT848_SCLOOP_HFILT_QCIF (2<<3)
124#define BT848_SCLOOP_HFILT_ICON (3<<3)
125
126#define BT848_SCLOOP_PEAK (1<<7)
127#define BT848_SCLOOP_HFILT_MINP (1<<3)
128#define BT848_SCLOOP_HFILT_MEDP (2<<3)
129#define BT848_SCLOOP_HFILT_MAXP (3<<3)
130
131
132#define BT848_OFORM 0x048
133#define BT848_OFORM_RANGE (1<<7)
134#define BT848_OFORM_CORE0 (0<<5)
135#define BT848_OFORM_CORE8 (1<<5)
136#define BT848_OFORM_CORE16 (2<<5)
137#define BT848_OFORM_CORE32 (3<<5)
138
139#define BT848_E_VSCALE_HI 0x04C
140#define BT848_O_VSCALE_HI 0x0CC
141#define BT848_VSCALE_YCOMB (1<<7)
142#define BT848_VSCALE_COMB (1<<6)
143#define BT848_VSCALE_INT (1<<5)
144#define BT848_VSCALE_HI 15
145
146#define BT848_E_VSCALE_LO 0x050
147#define BT848_O_VSCALE_LO 0x0D0
148#define BT848_TEST 0x054
149#define BT848_ADELAY 0x060
150#define BT848_BDELAY 0x064
151
152#define BT848_ADC 0x068
153#define BT848_ADC_RESERVED (2<<6)
154#define BT848_ADC_SYNC_T (1<<5)
155#define BT848_ADC_AGC_EN (1<<4)
156#define BT848_ADC_CLK_SLEEP (1<<3)
157#define BT848_ADC_Y_SLEEP (1<<2)
158#define BT848_ADC_C_SLEEP (1<<1)
159#define BT848_ADC_CRUSH (1<<0)
160
161#define BT848_WC_UP 0x044
162#define BT848_WC_DOWN 0x078
163
164#define BT848_E_VTC 0x06C
165#define BT848_O_VTC 0x0EC
166#define BT848_VTC_HSFMT (1<<7)
167#define BT848_VTC_VFILT_2TAP 0
168#define BT848_VTC_VFILT_3TAP 1
169#define BT848_VTC_VFILT_4TAP 2
170#define BT848_VTC_VFILT_5TAP 3
171
172#define BT848_SRESET 0x07C
173
174#define BT848_COLOR_FMT 0x0D4
175#define BT848_COLOR_FMT_O_RGB32 (0<<4)
176#define BT848_COLOR_FMT_O_RGB24 (1<<4)
177#define BT848_COLOR_FMT_O_RGB16 (2<<4)
178#define BT848_COLOR_FMT_O_RGB15 (3<<4)
179#define BT848_COLOR_FMT_O_YUY2 (4<<4)
180#define BT848_COLOR_FMT_O_BtYUV (5<<4)
181#define BT848_COLOR_FMT_O_Y8 (6<<4)
182#define BT848_COLOR_FMT_O_RGB8 (7<<4)
183#define BT848_COLOR_FMT_O_YCrCb422 (8<<4)
184#define BT848_COLOR_FMT_O_YCrCb411 (9<<4)
185#define BT848_COLOR_FMT_O_RAW (14<<4)
186#define BT848_COLOR_FMT_E_RGB32 0
187#define BT848_COLOR_FMT_E_RGB24 1
188#define BT848_COLOR_FMT_E_RGB16 2
189#define BT848_COLOR_FMT_E_RGB15 3
190#define BT848_COLOR_FMT_E_YUY2 4
191#define BT848_COLOR_FMT_E_BtYUV 5
192#define BT848_COLOR_FMT_E_Y8 6
193#define BT848_COLOR_FMT_E_RGB8 7
194#define BT848_COLOR_FMT_E_YCrCb422 8
195#define BT848_COLOR_FMT_E_YCrCb411 9
196#define BT848_COLOR_FMT_E_RAW 14
197
198#define BT848_COLOR_FMT_RGB32 0x00
199#define BT848_COLOR_FMT_RGB24 0x11
200#define BT848_COLOR_FMT_RGB16 0x22
201#define BT848_COLOR_FMT_RGB15 0x33
202#define BT848_COLOR_FMT_YUY2 0x44
203#define BT848_COLOR_FMT_BtYUV 0x55
204#define BT848_COLOR_FMT_Y8 0x66
205#define BT848_COLOR_FMT_RGB8 0x77
206#define BT848_COLOR_FMT_YCrCb422 0x88
207#define BT848_COLOR_FMT_YCrCb411 0x99
208#define BT848_COLOR_FMT_RAW 0xee
209
210#define BT848_VTOTAL_LO 0xB0
211#define BT848_VTOTAL_HI 0xB4
212
213#define BT848_COLOR_CTL 0x0D8
214#define BT848_COLOR_CTL_EXT_FRMRATE (1<<7)
215#define BT848_COLOR_CTL_COLOR_BARS (1<<6)
216#define BT848_COLOR_CTL_RGB_DED (1<<5)
217#define BT848_COLOR_CTL_GAMMA (1<<4)
218#define BT848_COLOR_CTL_WSWAP_ODD (1<<3)
219#define BT848_COLOR_CTL_WSWAP_EVEN (1<<2)
220#define BT848_COLOR_CTL_BSWAP_ODD (1<<1)
221#define BT848_COLOR_CTL_BSWAP_EVEN (1<<0)
222
223#define BT848_CAP_CTL 0x0DC
224#define BT848_CAP_CTL_DITH_FRAME (1<<4)
225#define BT848_CAP_CTL_CAPTURE_VBI_ODD (1<<3)
226#define BT848_CAP_CTL_CAPTURE_VBI_EVEN (1<<2)
227#define BT848_CAP_CTL_CAPTURE_ODD (1<<1)
228#define BT848_CAP_CTL_CAPTURE_EVEN (1<<0)
229
230#define BT848_VBI_PACK_SIZE 0x0E0
231
232#define BT848_VBI_PACK_DEL 0x0E4
233#define BT848_VBI_PACK_DEL_VBI_HDELAY 0xfc
234#define BT848_VBI_PACK_DEL_EXT_FRAME 2
235#define BT848_VBI_PACK_DEL_VBI_PKT_HI 1
236
237
238#define BT848_INT_STAT 0x100
239#define BT848_INT_MASK 0x104
240
241#define BT848_INT_ETBF (1<<23)
242
243#define BT848_INT_RISCS (0xf<<28)
244#define BT848_INT_RISC_EN (1<<27)
245#define BT848_INT_RACK (1<<25)
246#define BT848_INT_FIELD (1<<24)
247#define BT848_INT_SCERR (1<<19)
248#define BT848_INT_OCERR (1<<18)
249#define BT848_INT_PABORT (1<<17)
250#define BT848_INT_RIPERR (1<<16)
251#define BT848_INT_PPERR (1<<15)
252#define BT848_INT_FDSR (1<<14)
253#define BT848_INT_FTRGT (1<<13)
254#define BT848_INT_FBUS (1<<12)
255#define BT848_INT_RISCI (1<<11)
256#define BT848_INT_GPINT (1<<9)
257#define BT848_INT_I2CDONE (1<<8)
258#define BT848_INT_VPRES (1<<5)
259#define BT848_INT_HLOCK (1<<4)
260#define BT848_INT_OFLOW (1<<3)
261#define BT848_INT_HSYNC (1<<2)
262#define BT848_INT_VSYNC (1<<1)
263#define BT848_INT_FMTCHG (1<<0)
264
265
266#define BT848_GPIO_DMA_CTL 0x10C
267#define BT848_GPIO_DMA_CTL_GPINTC (1<<15)
268#define BT848_GPIO_DMA_CTL_GPINTI (1<<14)
269#define BT848_GPIO_DMA_CTL_GPWEC (1<<13)
270#define BT848_GPIO_DMA_CTL_GPIOMODE (3<<11)
271#define BT848_GPIO_DMA_CTL_GPCLKMODE (1<<10)
272#define BT848_GPIO_DMA_CTL_PLTP23_4 (0<<6)
273#define BT848_GPIO_DMA_CTL_PLTP23_8 (1<<6)
274#define BT848_GPIO_DMA_CTL_PLTP23_16 (2<<6)
275#define BT848_GPIO_DMA_CTL_PLTP23_32 (3<<6)
276#define BT848_GPIO_DMA_CTL_PLTP1_4 (0<<4)
277#define BT848_GPIO_DMA_CTL_PLTP1_8 (1<<4)
278#define BT848_GPIO_DMA_CTL_PLTP1_16 (2<<4)
279#define BT848_GPIO_DMA_CTL_PLTP1_32 (3<<4)
280#define BT848_GPIO_DMA_CTL_PKTP_4 (0<<2)
281#define BT848_GPIO_DMA_CTL_PKTP_8 (1<<2)
282#define BT848_GPIO_DMA_CTL_PKTP_16 (2<<2)
283#define BT848_GPIO_DMA_CTL_PKTP_32 (3<<2)
284#define BT848_GPIO_DMA_CTL_RISC_ENABLE (1<<1)
285#define BT848_GPIO_DMA_CTL_FIFO_ENABLE (1<<0)
286
287#define BT848_I2C 0x110
288#define BT878_I2C_MODE (1<<7)
289#define BT878_I2C_RATE (1<<6)
290#define BT878_I2C_NOSTOP (1<<5)
291#define BT878_I2C_NOSTART (1<<4)
292#define BT848_I2C_DIV (0xf<<4)
293#define BT848_I2C_SYNC (1<<3)
294#define BT848_I2C_W3B (1<<2)
295#define BT848_I2C_SCL (1<<1)
296#define BT848_I2C_SDA (1<<0)
297
298#define BT848_RISC_STRT_ADD 0x114
299#define BT848_GPIO_OUT_EN 0x118
300#define BT848_GPIO_REG_INP 0x11C
301#define BT848_RISC_COUNT 0x120
302#define BT848_GPIO_DATA 0x200
303
304
305/* Bt848 RISC commands */
306
307/* only for the SYNC RISC command */
308#define BT848_FIFO_STATUS_FM1 0x06
309#define BT848_FIFO_STATUS_FM3 0x0e
310#define BT848_FIFO_STATUS_SOL 0x02
311#define BT848_FIFO_STATUS_EOL4 0x01
312#define BT848_FIFO_STATUS_EOL3 0x0d
313#define BT848_FIFO_STATUS_EOL2 0x09
314#define BT848_FIFO_STATUS_EOL1 0x05
315#define BT848_FIFO_STATUS_VRE 0x04
316#define BT848_FIFO_STATUS_VRO 0x0c
317#define BT848_FIFO_STATUS_PXV 0x00
318
319#define BT848_RISC_RESYNC (1<<15)
320
321/* WRITE and SKIP */
322/* disable which bytes of each DWORD */
323#define BT848_RISC_BYTE0 (1U<<12)
324#define BT848_RISC_BYTE1 (1U<<13)
325#define BT848_RISC_BYTE2 (1U<<14)
326#define BT848_RISC_BYTE3 (1U<<15)
327#define BT848_RISC_BYTE_ALL (0x0fU<<12)
328#define BT848_RISC_BYTE_NONE 0
329/* cause RISCI */
330#define BT848_RISC_IRQ (1U<<24)
331/* RISC command is last one in this line */
332#define BT848_RISC_EOL (1U<<26)
333/* RISC command is first one in this line */
334#define BT848_RISC_SOL (1U<<27)
335
336#define BT848_RISC_WRITE (0x01U<<28)
337#define BT848_RISC_SKIP (0x02U<<28)
338#define BT848_RISC_WRITEC (0x05U<<28)
339#define BT848_RISC_JUMP (0x07U<<28)
340#define BT848_RISC_SYNC (0x08U<<28)
341
342#define BT848_RISC_WRITE123 (0x09U<<28)
343#define BT848_RISC_SKIP123 (0x0aU<<28)
344#define BT848_RISC_WRITE1S23 (0x0bU<<28)
345
346
347/* Bt848A and higher only !! */
348#define BT848_TGLB 0x080
349#define BT848_TGCTRL 0x084
350#define BT848_FCAP 0x0E8
351#define BT848_PLL_F_LO 0x0F0
352#define BT848_PLL_F_HI 0x0F4
353
354#define BT848_PLL_XCI 0x0F8
355#define BT848_PLL_X (1<<7)
356#define BT848_PLL_C (1<<6)
357
358#define BT848_DVSIF 0x0FC
359
360/* Bt878 register */
361
362#define BT878_DEVCTRL 0x40
363#define BT878_EN_TBFX 0x02
364#define BT878_EN_VSFX 0x04
365
366#endif
diff --git a/drivers/media/video/bt856.c b/drivers/media/video/bt856.c
new file mode 100644
index 00000000000..72c7eb0f8c2
--- /dev/null
+++ b/drivers/media/video/bt856.c
@@ -0,0 +1,442 @@
1/*
2 * bt856 - BT856A Digital Video Encoder (Rockwell Part)
3 *
4 * Copyright (C) 1999 Mike Bernson <mike@mlb.org>
5 * Copyright (C) 1998 Dave Perks <dperks@ibm.net>
6 *
7 * Modifications for LML33/DC10plus unified driver
8 * Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>
9 *
10 * This code was modify/ported from the saa7111 driver written
11 * by Dave Perks.
12 *
13 * Changes by Ronald Bultje <rbultje@ronald.bitfreak.net>
14 * - moved over to linux>=2.4.x i2c protocol (9/9/2002)
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 */
30
31#include <linux/module.h>
32#include <linux/init.h>
33#include <linux/delay.h>
34#include <linux/errno.h>
35#include <linux/fs.h>
36#include <linux/kernel.h>
37#include <linux/major.h>
38#include <linux/slab.h>
39#include <linux/mm.h>
40#include <linux/pci.h>
41#include <linux/signal.h>
42#include <asm/io.h>
43#include <asm/pgtable.h>
44#include <asm/page.h>
45#include <linux/sched.h>
46#include <asm/segment.h>
47#include <linux/types.h>
48
49#include <linux/videodev.h>
50#include <asm/uaccess.h>
51
52MODULE_DESCRIPTION("Brooktree-856A video encoder driver");
53MODULE_AUTHOR("Mike Bernson & Dave Perks");
54MODULE_LICENSE("GPL");
55
56#include <linux/i2c.h>
57#include <linux/i2c-dev.h>
58
59#define I2C_NAME(s) (s)->name
60
61#include <linux/video_encoder.h>
62
63static int debug = 0;
64module_param(debug, int, 0);
65MODULE_PARM_DESC(debug, "Debug level (0-1)");
66
67#define dprintk(num, format, args...) \
68 do { \
69 if (debug >= num) \
70 printk(format, ##args); \
71 } while (0)
72
73/* ----------------------------------------------------------------------- */
74
75#define REG_OFFSET 0xCE
76
77struct bt856 {
78 unsigned char reg[32];
79
80 int norm;
81 int enable;
82 int bright;
83 int contrast;
84 int hue;
85 int sat;
86};
87
88#define I2C_BT856 0x88
89
90/* ----------------------------------------------------------------------- */
91
92static inline int
93bt856_write (struct i2c_client *client,
94 u8 reg,
95 u8 value)
96{
97 struct bt856 *encoder = i2c_get_clientdata(client);
98
99 encoder->reg[reg - REG_OFFSET] = value;
100 return i2c_smbus_write_byte_data(client, reg, value);
101}
102
103static inline int
104bt856_setbit (struct i2c_client *client,
105 u8 reg,
106 u8 bit,
107 u8 value)
108{
109 struct bt856 *encoder = i2c_get_clientdata(client);
110
111 return bt856_write(client, reg,
112 (encoder->
113 reg[reg - REG_OFFSET] & ~(1 << bit)) |
114 (value ? (1 << bit) : 0));
115}
116
117static void
118bt856_dump (struct i2c_client *client)
119{
120 int i;
121 struct bt856 *encoder = i2c_get_clientdata(client);
122
123 printk(KERN_INFO "%s: register dump:", I2C_NAME(client));
124 for (i = 0xd6; i <= 0xde; i += 2)
125 printk(" %02x", encoder->reg[i - REG_OFFSET]);
126 printk("\n");
127}
128
129/* ----------------------------------------------------------------------- */
130
131static int
132bt856_command (struct i2c_client *client,
133 unsigned int cmd,
134 void *arg)
135{
136 struct bt856 *encoder = i2c_get_clientdata(client);
137
138 switch (cmd) {
139
140 case 0:
141 /* This is just for testing!!! */
142 dprintk(1, KERN_INFO "bt856: init\n");
143 bt856_write(client, 0xdc, 0x18);
144 bt856_write(client, 0xda, 0);
145 bt856_write(client, 0xde, 0);
146
147 bt856_setbit(client, 0xdc, 3, 1);
148 //bt856_setbit(client, 0xdc, 6, 0);
149 bt856_setbit(client, 0xdc, 4, 1);
150
151 switch (encoder->norm) {
152
153 case VIDEO_MODE_NTSC:
154 bt856_setbit(client, 0xdc, 2, 0);
155 break;
156
157 case VIDEO_MODE_PAL:
158 bt856_setbit(client, 0xdc, 2, 1);
159 break;
160 }
161
162 bt856_setbit(client, 0xdc, 1, 1);
163 bt856_setbit(client, 0xde, 4, 0);
164 bt856_setbit(client, 0xde, 3, 1);
165 if (debug != 0)
166 bt856_dump(client);
167 break;
168
169 case ENCODER_GET_CAPABILITIES:
170 {
171 struct video_encoder_capability *cap = arg;
172
173 dprintk(1, KERN_INFO "%s: get capabilities\n",
174 I2C_NAME(client));
175
176 cap->flags = VIDEO_ENCODER_PAL |
177 VIDEO_ENCODER_NTSC |
178 VIDEO_ENCODER_CCIR;
179 cap->inputs = 2;
180 cap->outputs = 1;
181 }
182 break;
183
184 case ENCODER_SET_NORM:
185 {
186 int *iarg = arg;
187
188 dprintk(1, KERN_INFO "%s: set norm %d\n", I2C_NAME(client),
189 *iarg);
190
191 switch (*iarg) {
192
193 case VIDEO_MODE_NTSC:
194 bt856_setbit(client, 0xdc, 2, 0);
195 break;
196
197 case VIDEO_MODE_PAL:
198 bt856_setbit(client, 0xdc, 2, 1);
199 bt856_setbit(client, 0xda, 0, 0);
200 //bt856_setbit(client, 0xda, 0, 1);
201 break;
202
203 default:
204 return -EINVAL;
205
206 }
207 encoder->norm = *iarg;
208 if (debug != 0)
209 bt856_dump(client);
210 }
211 break;
212
213 case ENCODER_SET_INPUT:
214 {
215 int *iarg = arg;
216
217 dprintk(1, KERN_INFO "%s: set input %d\n", I2C_NAME(client),
218 *iarg);
219
220 /* We only have video bus.
221 * iarg = 0: input is from bt819
222 * iarg = 1: input is from ZR36060 */
223
224 switch (*iarg) {
225
226 case 0:
227 bt856_setbit(client, 0xde, 4, 0);
228 bt856_setbit(client, 0xde, 3, 1);
229 bt856_setbit(client, 0xdc, 3, 1);
230 bt856_setbit(client, 0xdc, 6, 0);
231 break;
232 case 1:
233 bt856_setbit(client, 0xde, 4, 0);
234 bt856_setbit(client, 0xde, 3, 1);
235 bt856_setbit(client, 0xdc, 3, 1);
236 bt856_setbit(client, 0xdc, 6, 1);
237 break;
238 case 2: // Color bar
239 bt856_setbit(client, 0xdc, 3, 0);
240 bt856_setbit(client, 0xde, 4, 1);
241 break;
242 default:
243 return -EINVAL;
244
245 }
246
247 if (debug != 0)
248 bt856_dump(client);
249 }
250 break;
251
252 case ENCODER_SET_OUTPUT:
253 {
254 int *iarg = arg;
255
256 dprintk(1, KERN_INFO "%s: set output %d\n", I2C_NAME(client),
257 *iarg);
258
259 /* not much choice of outputs */
260 if (*iarg != 0) {
261 return -EINVAL;
262 }
263 }
264 break;
265
266 case ENCODER_ENABLE_OUTPUT:
267 {
268 int *iarg = arg;
269
270 encoder->enable = !!*iarg;
271
272 dprintk(1, KERN_INFO "%s: enable output %d\n",
273 I2C_NAME(client), encoder->enable);
274 }
275 break;
276
277 default:
278 return -EINVAL;
279 }
280
281 return 0;
282}
283
284/* ----------------------------------------------------------------------- */
285
286/*
287 * Generic i2c probe
288 * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
289 */
290static unsigned short normal_i2c[] = { I2C_BT856 >> 1, I2C_CLIENT_END };
291static unsigned short normal_i2c_range[] = { I2C_CLIENT_END };
292
293static unsigned short probe[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
294static unsigned short probe_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
295static unsigned short ignore[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
296static unsigned short ignore_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
297static unsigned short force[2] = { I2C_CLIENT_END , I2C_CLIENT_END };
298
299static struct i2c_client_address_data addr_data = {
300 .normal_i2c = normal_i2c,
301 .normal_i2c_range = normal_i2c_range,
302 .probe = probe,
303 .probe_range = probe_range,
304 .ignore = ignore,
305 .ignore_range = ignore_range,
306 .force = force
307};
308
309static struct i2c_driver i2c_driver_bt856;
310
311static int
312bt856_detect_client (struct i2c_adapter *adapter,
313 int address,
314 int kind)
315{
316 int i;
317 struct i2c_client *client;
318 struct bt856 *encoder;
319
320 dprintk(1,
321 KERN_INFO
322 "bt856.c: detecting bt856 client on address 0x%x\n",
323 address << 1);
324
325 /* Check if the adapter supports the needed features */
326 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
327 return 0;
328
329 client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
330 if (client == 0)
331 return -ENOMEM;
332 memset(client, 0, sizeof(struct i2c_client));
333 client->addr = address;
334 client->adapter = adapter;
335 client->driver = &i2c_driver_bt856;
336 client->flags = I2C_CLIENT_ALLOW_USE;
337 strlcpy(I2C_NAME(client), "bt856", sizeof(I2C_NAME(client)));
338
339 encoder = kmalloc(sizeof(struct bt856), GFP_KERNEL);
340 if (encoder == NULL) {
341 kfree(client);
342 return -ENOMEM;
343 }
344 memset(encoder, 0, sizeof(struct bt856));
345 encoder->norm = VIDEO_MODE_NTSC;
346 encoder->enable = 1;
347 i2c_set_clientdata(client, encoder);
348
349 i = i2c_attach_client(client);
350 if (i) {
351 kfree(client);
352 kfree(encoder);
353 return i;
354 }
355
356 bt856_write(client, 0xdc, 0x18);
357 bt856_write(client, 0xda, 0);
358 bt856_write(client, 0xde, 0);
359
360 bt856_setbit(client, 0xdc, 3, 1);
361 //bt856_setbit(client, 0xdc, 6, 0);
362 bt856_setbit(client, 0xdc, 4, 1);
363
364 switch (encoder->norm) {
365
366 case VIDEO_MODE_NTSC:
367 bt856_setbit(client, 0xdc, 2, 0);
368 break;
369
370 case VIDEO_MODE_PAL:
371 bt856_setbit(client, 0xdc, 2, 1);
372 break;
373 }
374
375 bt856_setbit(client, 0xdc, 1, 1);
376 bt856_setbit(client, 0xde, 4, 0);
377 bt856_setbit(client, 0xde, 3, 1);
378
379 if (debug != 0)
380 bt856_dump(client);
381
382 dprintk(1, KERN_INFO "%s_attach: at address 0x%x\n", I2C_NAME(client),
383 client->addr << 1);
384
385 return 0;
386}
387
388static int
389bt856_attach_adapter (struct i2c_adapter *adapter)
390{
391 dprintk(1,
392 KERN_INFO
393 "bt856.c: starting probe for adapter %s (0x%x)\n",
394 I2C_NAME(adapter), adapter->id);
395 return i2c_probe(adapter, &addr_data, &bt856_detect_client);
396}
397
398static int
399bt856_detach_client (struct i2c_client *client)
400{
401 struct bt856 *encoder = i2c_get_clientdata(client);
402 int err;
403
404 err = i2c_detach_client(client);
405 if (err) {
406 return err;
407 }
408
409 kfree(encoder);
410 kfree(client);
411
412 return 0;
413}
414
415/* ----------------------------------------------------------------------- */
416
417static struct i2c_driver i2c_driver_bt856 = {
418 .owner = THIS_MODULE,
419 .name = "bt856",
420
421 .id = I2C_DRIVERID_BT856,
422 .flags = I2C_DF_NOTIFY,
423
424 .attach_adapter = bt856_attach_adapter,
425 .detach_client = bt856_detach_client,
426 .command = bt856_command,
427};
428
429static int __init
430bt856_init (void)
431{
432 return i2c_add_driver(&i2c_driver_bt856);
433}
434
435static void __exit
436bt856_exit (void)
437{
438 i2c_del_driver(&i2c_driver_bt856);
439}
440
441module_init(bt856_init);
442module_exit(bt856_exit);
diff --git a/drivers/media/video/btcx-risc.c b/drivers/media/video/btcx-risc.c
new file mode 100644
index 00000000000..7f2d515d287
--- /dev/null
+++ b/drivers/media/video/btcx-risc.c
@@ -0,0 +1,262 @@
1/*
2 $Id: btcx-risc.c,v 1.6 2005/02/21 13:57:59 kraxel Exp $
3
4 btcx-risc.c
5
6 bt848/bt878/cx2388x risc code generator.
7
8 (c) 2000-03 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
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
26#include <linux/module.h>
27#include <linux/moduleparam.h>
28#include <linux/init.h>
29#include <linux/pci.h>
30#include <linux/interrupt.h>
31#include <linux/videodev2.h>
32#include <asm/page.h>
33#include <asm/pgtable.h>
34
35#include "btcx-risc.h"
36
37MODULE_DESCRIPTION("some code shared by bttv and cx88xx drivers");
38MODULE_AUTHOR("Gerd Knorr");
39MODULE_LICENSE("GPL");
40
41static unsigned int debug = 0;
42module_param(debug, int, 0644);
43MODULE_PARM_DESC(debug,"debug messages, default is 0 (no)");
44
45/* ---------------------------------------------------------- */
46/* allocate/free risc memory */
47
48static int memcnt;
49
50void btcx_riscmem_free(struct pci_dev *pci,
51 struct btcx_riscmem *risc)
52{
53 if (NULL == risc->cpu)
54 return;
55 if (debug) {
56 memcnt--;
57 printk("btcx: riscmem free [%d] dma=%lx\n",
58 memcnt, (unsigned long)risc->dma);
59 }
60 pci_free_consistent(pci, risc->size, risc->cpu, risc->dma);
61 memset(risc,0,sizeof(*risc));
62}
63
64int btcx_riscmem_alloc(struct pci_dev *pci,
65 struct btcx_riscmem *risc,
66 unsigned int size)
67{
68 u32 *cpu;
69 dma_addr_t dma;
70
71 if (NULL != risc->cpu && risc->size < size)
72 btcx_riscmem_free(pci,risc);
73 if (NULL == risc->cpu) {
74 cpu = pci_alloc_consistent(pci, size, &dma);
75 if (NULL == cpu)
76 return -ENOMEM;
77 risc->cpu = cpu;
78 risc->dma = dma;
79 risc->size = size;
80 if (debug) {
81 memcnt++;
82 printk("btcx: riscmem alloc [%d] dma=%lx cpu=%p size=%d\n",
83 memcnt, (unsigned long)dma, cpu, size);
84 }
85 }
86 memset(risc->cpu,0,risc->size);
87 return 0;
88}
89
90/* ---------------------------------------------------------- */
91/* screen overlay helpers */
92
93int
94btcx_screen_clips(int swidth, int sheight, struct v4l2_rect *win,
95 struct v4l2_clip *clips, unsigned int n)
96{
97 if (win->left < 0) {
98 /* left */
99 clips[n].c.left = 0;
100 clips[n].c.top = 0;
101 clips[n].c.width = -win->left;
102 clips[n].c.height = win->height;
103 n++;
104 }
105 if (win->left + win->width > swidth) {
106 /* right */
107 clips[n].c.left = swidth - win->left;
108 clips[n].c.top = 0;
109 clips[n].c.width = win->width - clips[n].c.left;
110 clips[n].c.height = win->height;
111 n++;
112 }
113 if (win->top < 0) {
114 /* top */
115 clips[n].c.left = 0;
116 clips[n].c.top = 0;
117 clips[n].c.width = win->width;
118 clips[n].c.height = -win->top;
119 n++;
120 }
121 if (win->top + win->height > sheight) {
122 /* bottom */
123 clips[n].c.left = 0;
124 clips[n].c.top = sheight - win->top;
125 clips[n].c.width = win->width;
126 clips[n].c.height = win->height - clips[n].c.top;
127 n++;
128 }
129 return n;
130}
131
132int
133btcx_align(struct v4l2_rect *win, struct v4l2_clip *clips, unsigned int n, int mask)
134{
135 s32 nx,nw,dx;
136 unsigned int i;
137
138 /* fixup window */
139 nx = (win->left + mask) & ~mask;
140 nw = (win->width) & ~mask;
141 if (nx + nw > win->left + win->width)
142 nw -= mask+1;
143 dx = nx - win->left;
144 win->left = nx;
145 win->width = nw;
146 if (debug)
147 printk(KERN_DEBUG "btcx: window align %dx%d+%d+%d [dx=%d]\n",
148 win->width, win->height, win->left, win->top, dx);
149
150 /* fixup clips */
151 for (i = 0; i < n; i++) {
152 nx = (clips[i].c.left-dx) & ~mask;
153 nw = (clips[i].c.width) & ~mask;
154 if (nx + nw < clips[i].c.left-dx + clips[i].c.width)
155 nw += mask+1;
156 clips[i].c.left = nx;
157 clips[i].c.width = nw;
158 if (debug)
159 printk(KERN_DEBUG "btcx: clip align %dx%d+%d+%d\n",
160 clips[i].c.width, clips[i].c.height,
161 clips[i].c.left, clips[i].c.top);
162 }
163 return 0;
164}
165
166void
167btcx_sort_clips(struct v4l2_clip *clips, unsigned int nclips)
168{
169 struct v4l2_clip swap;
170 int i,j,n;
171
172 if (nclips < 2)
173 return;
174 for (i = nclips-2; i >= 0; i--) {
175 for (n = 0, j = 0; j <= i; j++) {
176 if (clips[j].c.left > clips[j+1].c.left) {
177 swap = clips[j];
178 clips[j] = clips[j+1];
179 clips[j+1] = swap;
180 n++;
181 }
182 }
183 if (0 == n)
184 break;
185 }
186}
187
188void
189btcx_calc_skips(int line, int width, unsigned int *maxy,
190 struct btcx_skiplist *skips, unsigned int *nskips,
191 const struct v4l2_clip *clips, unsigned int nclips)
192{
193 unsigned int clip,skip;
194 int end,maxline;
195
196 skip=0;
197 maxline = 9999;
198 for (clip = 0; clip < nclips; clip++) {
199
200 /* sanity checks */
201 if (clips[clip].c.left + clips[clip].c.width <= 0)
202 continue;
203 if (clips[clip].c.left > (signed)width)
204 break;
205
206 /* vertical range */
207 if (line > clips[clip].c.top+clips[clip].c.height-1)
208 continue;
209 if (line < clips[clip].c.top) {
210 if (maxline > clips[clip].c.top-1)
211 maxline = clips[clip].c.top-1;
212 continue;
213 }
214 if (maxline > clips[clip].c.top+clips[clip].c.height-1)
215 maxline = clips[clip].c.top+clips[clip].c.height-1;
216
217 /* horizontal range */
218 if (0 == skip || clips[clip].c.left > skips[skip-1].end) {
219 /* new one */
220 skips[skip].start = clips[clip].c.left;
221 if (skips[skip].start < 0)
222 skips[skip].start = 0;
223 skips[skip].end = clips[clip].c.left + clips[clip].c.width;
224 if (skips[skip].end > width)
225 skips[skip].end = width;
226 skip++;
227 } else {
228 /* overlaps -- expand last one */
229 end = clips[clip].c.left + clips[clip].c.width;
230 if (skips[skip-1].end < end)
231 skips[skip-1].end = end;
232 if (skips[skip-1].end > width)
233 skips[skip-1].end = width;
234 }
235 }
236 *nskips = skip;
237 *maxy = maxline;
238
239 if (debug) {
240 printk(KERN_DEBUG "btcx: skips line %d-%d:",line,maxline);
241 for (skip = 0; skip < *nskips; skip++) {
242 printk(" %d-%d",skips[skip].start,skips[skip].end);
243 }
244 printk("\n");
245 }
246}
247
248/* ---------------------------------------------------------- */
249
250EXPORT_SYMBOL(btcx_riscmem_alloc);
251EXPORT_SYMBOL(btcx_riscmem_free);
252
253EXPORT_SYMBOL(btcx_screen_clips);
254EXPORT_SYMBOL(btcx_align);
255EXPORT_SYMBOL(btcx_sort_clips);
256EXPORT_SYMBOL(btcx_calc_skips);
257
258/*
259 * Local variables:
260 * c-basic-offset: 8
261 * End:
262 */
diff --git a/drivers/media/video/btcx-risc.h b/drivers/media/video/btcx-risc.h
new file mode 100644
index 00000000000..41f60395a52
--- /dev/null
+++ b/drivers/media/video/btcx-risc.h
@@ -0,0 +1,35 @@
1/*
2 * $Id: btcx-risc.h,v 1.2 2004/09/15 16:15:24 kraxel Exp $
3 */
4struct btcx_riscmem {
5 unsigned int size;
6 u32 *cpu;
7 u32 *jmp;
8 dma_addr_t dma;
9};
10
11struct btcx_skiplist {
12 int start;
13 int end;
14};
15
16int btcx_riscmem_alloc(struct pci_dev *pci,
17 struct btcx_riscmem *risc,
18 unsigned int size);
19void btcx_riscmem_free(struct pci_dev *pci,
20 struct btcx_riscmem *risc);
21
22int btcx_screen_clips(int swidth, int sheight, struct v4l2_rect *win,
23 struct v4l2_clip *clips, unsigned int n);
24int btcx_align(struct v4l2_rect *win, struct v4l2_clip *clips,
25 unsigned int n, int mask);
26void btcx_sort_clips(struct v4l2_clip *clips, unsigned int nclips);
27void btcx_calc_skips(int line, int width, unsigned int *maxy,
28 struct btcx_skiplist *skips, unsigned int *nskips,
29 const struct v4l2_clip *clips, unsigned int nclips);
30
31/*
32 * Local variables:
33 * c-basic-offset: 8
34 * End:
35 */
diff --git a/drivers/media/video/bttv-cards.c b/drivers/media/video/bttv-cards.c
new file mode 100644
index 00000000000..abce874e71c
--- /dev/null
+++ b/drivers/media/video/bttv-cards.c
@@ -0,0 +1,4350 @@
1/*
2 $Id: bttv-cards.c,v 1.47 2005/02/22 14:06:32 kraxel Exp $
3
4 bttv-cards.c
5
6 this file has configuration informations - card-specific stuff
7 like the big tvcards array for the most part
8
9 Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
10 & Marcus Metzler (mocm@thp.uni-koeln.de)
11 (c) 1999-2001 Gerd Knorr <kraxel@goldbach.in-berlin.de>
12
13 This program is free software; you can redistribute it and/or modify
14 it under the terms of the GNU General Public License as published by
15 the Free Software Foundation; either version 2 of the License, or
16 (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26
27*/
28
29#include <linux/config.h>
30#include <linux/delay.h>
31#include <linux/module.h>
32#include <linux/moduleparam.h>
33#include <linux/kmod.h>
34#include <linux/init.h>
35#include <linux/pci.h>
36#include <linux/vmalloc.h>
37#include <linux/firmware.h>
38
39#include <asm/io.h>
40
41#include "bttvp.h"
42#if 0 /* not working yet */
43#include "bt832.h"
44#endif
45
46/* fwd decl */
47static void boot_msp34xx(struct bttv *btv, int pin);
48static void boot_bt832(struct bttv *btv);
49static void hauppauge_eeprom(struct bttv *btv);
50static void avermedia_eeprom(struct bttv *btv);
51static void osprey_eeprom(struct bttv *btv);
52static void modtec_eeprom(struct bttv *btv);
53static void init_PXC200(struct bttv *btv);
54
55static void winview_audio(struct bttv *btv, struct video_audio *v, int set);
56static void lt9415_audio(struct bttv *btv, struct video_audio *v, int set);
57static void avermedia_tvphone_audio(struct bttv *btv, struct video_audio *v,
58 int set);
59static void avermedia_tv_stereo_audio(struct bttv *btv, struct video_audio *v,
60 int set);
61static void terratv_audio(struct bttv *btv, struct video_audio *v, int set);
62static void gvbctv3pci_audio(struct bttv *btv, struct video_audio *v, int set);
63static void gvbctv5pci_audio(struct bttv *btv, struct video_audio *v, int set);
64static void winfast2000_audio(struct bttv *btv, struct video_audio *v, int set);
65static void pvbt878p9b_audio(struct bttv *btv, struct video_audio *v, int set);
66static void fv2000s_audio(struct bttv *btv, struct video_audio *v, int set);
67static void windvr_audio(struct bttv *btv, struct video_audio *v, int set);
68static void adtvk503_audio(struct bttv *btv, struct video_audio *v, int set);
69static void rv605_muxsel(struct bttv *btv, unsigned int input);
70static void eagle_muxsel(struct bttv *btv, unsigned int input);
71static void xguard_muxsel(struct bttv *btv, unsigned int input);
72static void ivc120_muxsel(struct bttv *btv, unsigned int input);
73static void gvc1100_muxsel(struct bttv *btv, unsigned int input);
74
75static void PXC200_muxsel(struct bttv *btv, unsigned int input);
76
77static void picolo_tetra_muxsel(struct bttv *btv, unsigned int input);
78static void picolo_tetra_init(struct bttv *btv);
79
80static void tibetCS16_muxsel(struct bttv *btv, unsigned int input);
81static void tibetCS16_init(struct bttv *btv);
82
83static void kodicom4400r_muxsel(struct bttv *btv, unsigned int input);
84static void kodicom4400r_init(struct bttv *btv);
85
86static void sigmaSLC_muxsel(struct bttv *btv, unsigned int input);
87static void sigmaSQ_muxsel(struct bttv *btv, unsigned int input);
88
89static int terratec_active_radio_upgrade(struct bttv *btv);
90static int tea5757_read(struct bttv *btv);
91static int tea5757_write(struct bttv *btv, int value);
92static void identify_by_eeprom(struct bttv *btv,
93 unsigned char eeprom_data[256]);
94static int __devinit pvr_boot(struct bttv *btv);
95
96/* config variables */
97static unsigned int triton1=0;
98static unsigned int vsfx=0;
99static unsigned int latency = UNSET;
100static unsigned int no_overlay=-1;
101
102static unsigned int card[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = UNSET };
103static unsigned int pll[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = UNSET };
104static unsigned int tuner[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = UNSET };
105static unsigned int svhs[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = UNSET };
106static unsigned int remote[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = UNSET };
107static struct bttv *master[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = NULL };
108#ifdef MODULE
109static unsigned int autoload = 1;
110#else
111static unsigned int autoload = 0;
112#endif
113static unsigned int gpiomask = UNSET;
114static unsigned int audioall = UNSET;
115static unsigned int audiomux[5] = { [ 0 ... 4 ] = UNSET };
116
117/* insmod options */
118module_param(triton1, int, 0444);
119module_param(vsfx, int, 0444);
120module_param(no_overlay, int, 0444);
121module_param(latency, int, 0444);
122module_param(gpiomask, int, 0444);
123module_param(audioall, int, 0444);
124module_param(autoload, int, 0444);
125
126module_param_array(card, int, NULL, 0444);
127module_param_array(pll, int, NULL, 0444);
128module_param_array(tuner, int, NULL, 0444);
129module_param_array(svhs, int, NULL, 0444);
130module_param_array(remote, int, NULL, 0444);
131module_param_array(audiomux, int, NULL, 0444);
132
133MODULE_PARM_DESC(triton1,"set ETBF pci config bit "
134 "[enable bug compatibility for triton1 + others]");
135MODULE_PARM_DESC(vsfx,"set VSFX pci config bit "
136 "[yet another chipset flaw workaround]");
137MODULE_PARM_DESC(latency,"pci latency timer");
138MODULE_PARM_DESC(card,"specify TV/grabber card model, see CARDLIST file for a list");
139MODULE_PARM_DESC(pll,"specify installed crystal (0=none, 28=28 MHz, 35=35 MHz)");
140MODULE_PARM_DESC(tuner,"specify installed tuner type");
141MODULE_PARM_DESC(autoload,"automatically load i2c modules like tuner.o, default is 1 (yes)");
142
143/* ----------------------------------------------------------------------- */
144/* list of card IDs for bt878+ cards */
145
146static struct CARD {
147 unsigned id;
148 int cardnr;
149 char *name;
150} cards[] __devinitdata = {
151 { 0x13eb0070, BTTV_HAUPPAUGE878, "Hauppauge WinTV" },
152 { 0x39000070, BTTV_HAUPPAUGE878, "Hauppauge WinTV-D" },
153 { 0x45000070, BTTV_HAUPPAUGEPVR, "Hauppauge WinTV/PVR" },
154 { 0xff000070, BTTV_OSPREY1x0, "Osprey-100" },
155 { 0xff010070, BTTV_OSPREY2x0_SVID,"Osprey-200" },
156 { 0xff020070, BTTV_OSPREY500, "Osprey-500" },
157 { 0xff030070, BTTV_OSPREY2000, "Osprey-2000" },
158 { 0xff040070, BTTV_OSPREY540, "Osprey-540" },
159
160 { 0x00011002, BTTV_ATI_TVWONDER, "ATI TV Wonder" },
161 { 0x00031002, BTTV_ATI_TVWONDERVE,"ATI TV Wonder/VE" },
162
163 { 0x6606107d, BTTV_WINFAST2000, "Leadtek WinFast TV 2000" },
164 { 0x6607107d, BTTV_WINFASTVC100, "Leadtek WinFast VC 100" },
165 { 0x6609107d, BTTV_WINFAST2000, "Leadtek TV 2000 XP" },
166 { 0x263610b4, BTTV_STB2, "STB TV PCI FM, Gateway P/N 6000704" },
167 { 0x264510b4, BTTV_STB2, "STB TV PCI FM, Gateway P/N 6000704" },
168 { 0x402010fc, BTTV_GVBCTV3PCI, "I-O Data Co. GV-BCTV3/PCI" },
169 { 0x405010fc, BTTV_GVBCTV4PCI, "I-O Data Co. GV-BCTV4/PCI" },
170 { 0x407010fc, BTTV_GVBCTV5PCI, "I-O Data Co. GV-BCTV5/PCI" },
171 { 0xd01810fc, BTTV_GVBCTV5PCI, "I-O Data Co. GV-BCTV5/PCI" },
172
173 { 0x001211bd, BTTV_PINNACLE, "Pinnacle PCTV" },
174 // some cards ship with byteswapped IDs ...
175 { 0x1200bd11, BTTV_PINNACLE, "Pinnacle PCTV [bswap]" },
176 { 0xff00bd11, BTTV_PINNACLE, "Pinnacle PCTV [bswap]" },
177 // this seems to happen as well ...
178 { 0xff1211bd, BTTV_PINNACLE, "Pinnacle PCTV" },
179
180 { 0x3000121a, BTTV_VOODOOTV_FM, "3Dfx VoodooTV FM/ VoodooTV 200" },
181 { 0x263710b4, BTTV_VOODOOTV_FM, "3Dfx VoodooTV FM/ VoodooTV 200" },
182 { 0x3060121a, BTTV_STB2, "3Dfx VoodooTV 100/ STB OEM" },
183
184 { 0x3000144f, BTTV_MAGICTVIEW063, "(Askey Magic/others) TView99 CPH06x" },
185 { 0xa005144f, BTTV_MAGICTVIEW063, "CPH06X TView99-Card" },
186 { 0x3002144f, BTTV_MAGICTVIEW061, "(Askey Magic/others) TView99 CPH05x" },
187 { 0x3005144f, BTTV_MAGICTVIEW061, "(Askey Magic/others) TView99 CPH061/06L (T1/LC)" },
188 { 0x5000144f, BTTV_MAGICTVIEW061, "Askey CPH050" },
189 { 0x300014ff, BTTV_MAGICTVIEW061, "TView 99 (CPH061)" },
190 { 0x300214ff, BTTV_PHOEBE_TVMAS, "Phoebe TV Master (CPH060)" },
191
192 { 0x00011461, BTTV_AVPHONE98, "AVerMedia TVPhone98" },
193 { 0x00021461, BTTV_AVERMEDIA98, "AVermedia TVCapture 98" },
194 { 0x00031461, BTTV_AVPHONE98, "AVerMedia TVPhone98" },
195 { 0x00041461, BTTV_AVERMEDIA98, "AVerMedia TVCapture 98" },
196 { 0x03001461, BTTV_AVERMEDIA98, "VDOMATE TV TUNER CARD" },
197
198 { 0x1117153b, BTTV_TERRATVALUE, "Terratec TValue (Philips PAL B/G)" },
199 { 0x1118153b, BTTV_TERRATVALUE, "Terratec TValue (Temic PAL B/G)" },
200 { 0x1119153b, BTTV_TERRATVALUE, "Terratec TValue (Philips PAL I)" },
201 { 0x111a153b, BTTV_TERRATVALUE, "Terratec TValue (Temic PAL I)" },
202
203 { 0x1123153b, BTTV_TERRATVRADIO, "Terratec TV Radio+" },
204 { 0x1127153b, BTTV_TERRATV, "Terratec TV+ (V1.05)" },
205 // clashes with FlyVideo
206 //{ 0x18521852, BTTV_TERRATV, "Terratec TV+ (V1.10)" },
207 { 0x1134153b, BTTV_TERRATVALUE, "Terratec TValue (LR102)" },
208 { 0x1135153b, BTTV_TERRATVALUER, "Terratec TValue Radio" }, // LR102
209 { 0x5018153b, BTTV_TERRATVALUE, "Terratec TValue" }, // ??
210 { 0xff3b153b, BTTV_TERRATVALUER, "Terratec TValue Radio" }, // ??
211
212 { 0x400015b0, BTTV_ZOLTRIX_GENIE, "Zoltrix Genie TV" },
213 { 0x400a15b0, BTTV_ZOLTRIX_GENIE, "Zoltrix Genie TV" },
214 { 0x400d15b0, BTTV_ZOLTRIX_GENIE, "Zoltrix Genie TV / Radio" },
215 { 0x401015b0, BTTV_ZOLTRIX_GENIE, "Zoltrix Genie TV / Radio" },
216 { 0x401615b0, BTTV_ZOLTRIX_GENIE, "Zoltrix Genie TV / Radio" },
217
218 { 0x1430aa00, BTTV_PV143, "Provideo PV143A" },
219 { 0x1431aa00, BTTV_PV143, "Provideo PV143B" },
220 { 0x1432aa00, BTTV_PV143, "Provideo PV143C" },
221 { 0x1433aa00, BTTV_PV143, "Provideo PV143D" },
222 { 0x1433aa03, BTTV_PV143, "Security Eyes" },
223
224 { 0x1460aa00, BTTV_PV150, "Provideo PV150A-1" },
225 { 0x1461aa01, BTTV_PV150, "Provideo PV150A-2" },
226 { 0x1462aa02, BTTV_PV150, "Provideo PV150A-3" },
227 { 0x1463aa03, BTTV_PV150, "Provideo PV150A-4" },
228
229 { 0x1464aa04, BTTV_PV150, "Provideo PV150B-1" },
230 { 0x1465aa05, BTTV_PV150, "Provideo PV150B-2" },
231 { 0x1466aa06, BTTV_PV150, "Provideo PV150B-3" },
232 { 0x1467aa07, BTTV_PV150, "Provideo PV150B-4" },
233
234 { 0xa132ff00, BTTV_IVC100, "IVC-100" },
235 { 0xa1550000, BTTV_IVC200, "IVC-200" },
236 { 0xa1550001, BTTV_IVC200, "IVC-200" },
237 { 0xa1550002, BTTV_IVC200, "IVC-200" },
238 { 0xa1550003, BTTV_IVC200, "IVC-200" },
239 { 0xa1550100, BTTV_IVC200, "IVC-200G" },
240 { 0xa1550101, BTTV_IVC200, "IVC-200G" },
241 { 0xa1550102, BTTV_IVC200, "IVC-200G" },
242 { 0xa1550103, BTTV_IVC200, "IVC-200G" },
243 { 0xa182ff00, BTTV_IVC120, "IVC-120G" },
244 { 0xa182ff01, BTTV_IVC120, "IVC-120G" },
245 { 0xa182ff02, BTTV_IVC120, "IVC-120G" },
246 { 0xa182ff03, BTTV_IVC120, "IVC-120G" },
247 { 0xa182ff04, BTTV_IVC120, "IVC-120G" },
248 { 0xa182ff05, BTTV_IVC120, "IVC-120G" },
249 { 0xa182ff06, BTTV_IVC120, "IVC-120G" },
250 { 0xa182ff07, BTTV_IVC120, "IVC-120G" },
251 { 0xa182ff08, BTTV_IVC120, "IVC-120G" },
252 { 0xa182ff09, BTTV_IVC120, "IVC-120G" },
253 { 0xa182ff0a, BTTV_IVC120, "IVC-120G" },
254 { 0xa182ff0b, BTTV_IVC120, "IVC-120G" },
255 { 0xa182ff0c, BTTV_IVC120, "IVC-120G" },
256 { 0xa182ff0d, BTTV_IVC120, "IVC-120G" },
257 { 0xa182ff0e, BTTV_IVC120, "IVC-120G" },
258 { 0xa182ff0f, BTTV_IVC120, "IVC-120G" },
259
260 { 0x41424344, BTTV_GRANDTEC, "GrandTec Multi Capture" },
261 { 0x01020304, BTTV_XGUARD, "Grandtec Grand X-Guard" },
262
263 { 0x18501851, BTTV_CHRONOS_VS2, "FlyVideo 98 (LR50)/ Chronos Video Shuttle II" },
264 { 0xa0501851, BTTV_CHRONOS_VS2, "FlyVideo 98 (LR50)/ Chronos Video Shuttle II" },
265 { 0x18511851, BTTV_FLYVIDEO98EZ, "FlyVideo 98EZ (LR51)/ CyberMail AV" },
266 { 0x18521852, BTTV_TYPHOON_TVIEW, "FlyVideo 98FM (LR50)/ Typhoon TView TV/FM Tuner" },
267 { 0x41a0a051, BTTV_FLYVIDEO_98FM, "Lifeview FlyVideo 98 LR50 Rev Q" },
268 { 0x18501f7f, BTTV_FLYVIDEO_98, "Lifeview Flyvideo 98" },
269
270 { 0x010115cb, BTTV_GMV1, "AG GMV1" },
271 { 0x010114c7, BTTV_MODTEC_205, "Modular Technology MM201/MM202/MM205/MM210/MM215 PCTV" },
272
273 { 0x10b42636, BTTV_HAUPPAUGE878, "STB ???" },
274 { 0x217d6606, BTTV_WINFAST2000, "Leadtek WinFast TV 2000" },
275 { 0xfff6f6ff, BTTV_WINFAST2000, "Leadtek WinFast TV 2000" },
276 { 0x03116000, BTTV_SENSORAY311, "Sensoray 311" },
277 { 0x00790e11, BTTV_WINDVR, "Canopus WinDVR PCI" },
278 { 0xa0fca1a0, BTTV_ZOLTRIX, "Face to Face Tvmax" },
279 { 0x20007063, BTTV_PC_HDTV, "pcHDTV HD-2000 TV"},
280 { 0x82b2aa6a, BTTV_SIMUS_GVC1100, "SIMUS GVC1100" },
281 { 0x146caa0c, BTTV_PV951, "ituner spectra8" },
282 { 0x200a1295, BTTV_PXC200, "ImageNation PXC200A" },
283
284 { 0x40111554, BTTV_PV_BT878P_9B, "Prolink Pixelview PV-BT" },
285 { 0x17de0a01, BTTV_KWORLD, "Mecer TV/FM/Video Tuner" },
286
287 { 0x01051805, BTTV_PICOLO_TETRA_CHIP, "Picolo Tetra Chip #1" },
288 { 0x01061805, BTTV_PICOLO_TETRA_CHIP, "Picolo Tetra Chip #2" },
289 { 0x01071805, BTTV_PICOLO_TETRA_CHIP, "Picolo Tetra Chip #3" },
290 { 0x01081805, BTTV_PICOLO_TETRA_CHIP, "Picolo Tetra Chip #4" },
291
292 // likely broken, vendor id doesn't match the other magic views ...
293 //{ 0xa0fca04f, BTTV_MAGICTVIEW063, "Guillemot Maxi TV Video 3" },
294
295 // DVB cards (using pci function .1 for mpeg data xfer)
296 { 0x01010071, BTTV_NEBULA_DIGITV, "Nebula Electronics DigiTV" },
297 { 0x07611461, BTTV_AVDVBT_761, "AverMedia AverTV DVB-T 761" },
298 { 0x001c11bd, BTTV_PINNACLESAT, "Pinnacle PCTV Sat" },
299 { 0x002611bd, BTTV_TWINHAN_DST, "Pinnacle PCTV SAT CI" },
300 { 0x00011822, BTTV_TWINHAN_DST, "Twinhan VisionPlus DVB" },
301 { 0xfc00270f, BTTV_TWINHAN_DST, "ChainTech digitop DST-1000 DVB-S" },
302 { 0x07711461, BTTV_AVDVBT_771, "AVermedia AverTV DVB-T 771" },
303 { 0xdb1018ac, BTTV_DVICO_DVBT_LITE, "DVICO FusionHDTV DVB-T Lite" },
304
305 { 0, -1, NULL }
306};
307
308/* ----------------------------------------------------------------------- */
309/* array with description for bt848 / bt878 tv/grabber cards */
310
311struct tvcard bttv_tvcards[] = {
312{
313/* ---- card 0x00 ---------------------------------- */
314 .name = " *** UNKNOWN/GENERIC *** ",
315 .video_inputs = 4,
316 .audio_inputs = 1,
317 .tuner = 0,
318 .svhs = 2,
319 .muxsel = { 2, 3, 1, 0},
320 .tuner_type = -1,
321},{
322 .name = "MIRO PCTV",
323 .video_inputs = 4,
324 .audio_inputs = 1,
325 .tuner = 0,
326 .svhs = 2,
327 .gpiomask = 15,
328 .muxsel = { 2, 3, 1, 1},
329 .audiomux = { 2, 0, 0, 0, 10},
330 .needs_tvaudio = 1,
331 .tuner_type = -1,
332},{
333 .name = "Hauppauge (bt848)",
334 .video_inputs = 4,
335 .audio_inputs = 1,
336 .tuner = 0,
337 .svhs = 2,
338 .gpiomask = 7,
339 .muxsel = { 2, 3, 1, 1},
340 .audiomux = { 0, 1, 2, 3, 4},
341 .needs_tvaudio = 1,
342 .tuner_type = -1,
343},{
344 .name = "STB, Gateway P/N 6000699 (bt848)",
345 .video_inputs = 3,
346 .audio_inputs = 1,
347 .tuner = 0,
348 .svhs = 2,
349 .gpiomask = 7,
350 .muxsel = { 2, 3, 1, 1},
351 .audiomux = { 4, 0, 2, 3, 1},
352 .no_msp34xx = 1,
353 .needs_tvaudio = 1,
354 .tuner_type = TUNER_PHILIPS_NTSC,
355 .pll = PLL_28,
356 .has_radio = 1,
357},{
358
359/* ---- card 0x04 ---------------------------------- */
360 .name = "Intel Create and Share PCI/ Smart Video Recorder III",
361 .video_inputs = 4,
362 .audio_inputs = 0,
363 .tuner = -1,
364 .svhs = 2,
365 .gpiomask = 0,
366 .muxsel = { 2, 3, 1, 1},
367 .audiomux = { 0 },
368 .needs_tvaudio = 0,
369 .tuner_type = 4,
370},{
371 .name = "Diamond DTV2000",
372 .video_inputs = 4,
373 .audio_inputs = 1,
374 .tuner = 0,
375 .svhs = 2,
376 .gpiomask = 3,
377 .muxsel = { 2, 3, 1, 0},
378 .audiomux = { 0, 1, 0, 1, 3},
379 .needs_tvaudio = 1,
380 .tuner_type = -1,
381},{
382 .name = "AVerMedia TVPhone",
383 .video_inputs = 3,
384 .audio_inputs = 1,
385 .tuner = 0,
386 .svhs = 3,
387 .muxsel = { 2, 3, 1, 1},
388 .gpiomask = 0x0f,
389 .audiomux = { 0x0c, 0x04, 0x08, 0x04, 0},
390 /* 0x04 for some cards ?? */
391 .needs_tvaudio = 1,
392 .tuner_type = -1,
393 .audio_hook = avermedia_tvphone_audio,
394 .has_remote = 1,
395},{
396 .name = "MATRIX-Vision MV-Delta",
397 .video_inputs = 5,
398 .audio_inputs = 1,
399 .tuner = -1,
400 .svhs = 3,
401 .gpiomask = 0,
402 .muxsel = { 2, 3, 1, 0, 0},
403 .audiomux = {0 },
404 .needs_tvaudio = 1,
405 .tuner_type = -1,
406},{
407
408/* ---- card 0x08 ---------------------------------- */
409 .name = "Lifeview FlyVideo II (Bt848) LR26 / MAXI TV Video PCI2 LR26",
410 .video_inputs = 4,
411 .audio_inputs = 1,
412 .tuner = 0,
413 .svhs = 2,
414 .gpiomask = 0xc00,
415 .muxsel = { 2, 3, 1, 1},
416 .audiomux = { 0, 0xc00, 0x800, 0x400, 0xc00, 0},
417 .needs_tvaudio = 1,
418 .pll = PLL_28,
419 .tuner_type = -1,
420},{
421 .name = "IMS/IXmicro TurboTV",
422 .video_inputs = 3,
423 .audio_inputs = 1,
424 .tuner = 0,
425 .svhs = 2,
426 .gpiomask = 3,
427 .muxsel = { 2, 3, 1, 1},
428 .audiomux = { 1, 1, 2, 3, 0},
429 .needs_tvaudio = 0,
430 .pll = PLL_28,
431 .tuner_type = TUNER_TEMIC_PAL,
432},{
433 .name = "Hauppauge (bt878)",
434 .video_inputs = 4,
435 .audio_inputs = 1,
436 .tuner = 0,
437 .svhs = 2,
438 .gpiomask = 0x0f, /* old: 7 */
439 .muxsel = { 2, 0, 1, 1},
440 .audiomux = { 0, 1, 2, 3, 4},
441 .needs_tvaudio = 1,
442 .pll = PLL_28,
443 .tuner_type = -1,
444},{
445 .name = "MIRO PCTV pro",
446 .video_inputs = 3,
447 .audio_inputs = 1,
448 .tuner = 0,
449 .svhs = 2,
450 .gpiomask = 0x3014f,
451 .muxsel = { 2, 3, 1, 1},
452 .audiomux = { 0x20001,0x10001, 0, 0,10},
453 .needs_tvaudio = 1,
454 .tuner_type = -1,
455},{
456
457/* ---- card 0x0c ---------------------------------- */
458 .name = "ADS Technologies Channel Surfer TV (bt848)",
459 .video_inputs = 3,
460 .audio_inputs = 1,
461 .tuner = 0,
462 .svhs = 2,
463 .gpiomask = 15,
464 .muxsel = { 2, 3, 1, 1},
465 .audiomux = { 13, 14, 11, 7, 0, 0},
466 .needs_tvaudio = 1,
467 .tuner_type = -1,
468},{
469 .name = "AVerMedia TVCapture 98",
470 .video_inputs = 3,
471 .audio_inputs = 4,
472 .tuner = 0,
473 .svhs = 2,
474 .gpiomask = 15,
475 .muxsel = { 2, 3, 1, 1},
476 .audiomux = { 13, 14, 11, 7, 0, 0},
477 .needs_tvaudio = 1,
478 .msp34xx_alt = 1,
479 .pll = PLL_28,
480 .tuner_type = TUNER_PHILIPS_PAL,
481 .audio_hook = avermedia_tv_stereo_audio,
482},{
483 .name = "Aimslab Video Highway Xtreme (VHX)",
484 .video_inputs = 3,
485 .audio_inputs = 1,
486 .tuner = 0,
487 .svhs = 2,
488 .gpiomask = 7,
489 .muxsel = { 2, 3, 1, 1},
490 .audiomux = { 0, 2, 1, 3, 4}, /* old: { 0, 1, 2, 3, 4} */
491 .needs_tvaudio = 1,
492 .pll = PLL_28,
493 .tuner_type = -1,
494},{
495 .name = "Zoltrix TV-Max",
496 .video_inputs = 3,
497 .audio_inputs = 1,
498 .tuner = 0,
499 .svhs = 2,
500 .gpiomask = 15,
501 .muxsel = { 2, 3, 1, 1},
502 .audiomux = {0 , 0, 1 , 0, 10},
503 .needs_tvaudio = 1,
504 .tuner_type = -1,
505},{
506
507/* ---- card 0x10 ---------------------------------- */
508 .name = "Prolink Pixelview PlayTV (bt878)",
509 .video_inputs = 3,
510 .audio_inputs = 1,
511 .tuner = 0,
512 .svhs = 2,
513 .gpiomask = 0x01fe00,
514 .muxsel = { 2, 3, 1, 1},
515#if 0
516 // old
517 .audiomux = { 0x01c000, 0, 0x018000, 0x014000, 0x002000, 0 },
518#else
519 // 2003-10-20 by "Anton A. Arapov" <arapov@mail.ru>
520 .audiomux = { 0x001e00, 0, 0x018000, 0x014000, 0x002000, 0 },
521#endif
522 .needs_tvaudio = 1,
523 .pll = PLL_28,
524 .tuner_type = -1,
525},{
526 .name = "Leadtek WinView 601",
527 .video_inputs = 3,
528 .audio_inputs = 1,
529 .tuner = 0,
530 .svhs = 2,
531 .gpiomask = 0x8300f8,
532 .muxsel = { 2, 3, 1, 1,0},
533 .audiomux = { 0x4fa007,0xcfa007,0xcfa007,0xcfa007,0xcfa007,0xcfa007},
534 .needs_tvaudio = 1,
535 .tuner_type = -1,
536 .audio_hook = winview_audio,
537 .has_radio = 1,
538},{
539 .name = "AVEC Intercapture",
540 .video_inputs = 3,
541 .audio_inputs = 2,
542 .tuner = 0,
543 .svhs = 2,
544 .gpiomask = 0,
545 .muxsel = {2, 3, 1, 1},
546 .audiomux = {1, 0, 0, 0, 0},
547 .needs_tvaudio = 1,
548 .tuner_type = -1,
549},{
550 .name = "Lifeview FlyVideo II EZ /FlyKit LR38 Bt848 (capture only)",
551 .video_inputs = 4,
552 .audio_inputs = 1,
553 .tuner = -1,
554 .svhs = -1,
555 .gpiomask = 0x8dff00,
556 .muxsel = { 2, 3, 1, 1},
557 .audiomux = { 0 },
558 .no_msp34xx = 1,
559 .tuner_type = -1,
560},{
561
562/* ---- card 0x14 ---------------------------------- */
563 .name = "CEI Raffles Card",
564 .video_inputs = 3,
565 .audio_inputs = 3,
566 .tuner = 0,
567 .svhs = 2,
568 .muxsel = {2, 3, 1, 1},
569 .tuner_type = -1,
570},{
571 .name = "Lifeview FlyVideo 98/ Lucky Star Image World ConferenceTV LR50",
572 .video_inputs = 4,
573 .audio_inputs = 2, // tuner, line in
574 .tuner = 0,
575 .svhs = 2,
576 .gpiomask = 0x1800,
577 .muxsel = { 2, 3, 1, 1},
578 .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800},
579 .pll = PLL_28,
580 .tuner_type = TUNER_PHILIPS_PAL_I,
581},{
582 .name = "Askey CPH050/ Phoebe Tv Master + FM",
583 .video_inputs = 3,
584 .audio_inputs = 1,
585 .tuner = 0,
586 .svhs = 2,
587 .gpiomask = 0xc00,
588 .muxsel = { 2, 3, 1, 1},
589 .audiomux = {0, 1, 0x800, 0x400, 0xc00, 0},
590 .needs_tvaudio = 1,
591 .pll = PLL_28,
592 .tuner_type = -1,
593},{
594 .name = "Modular Technology MM201/MM202/MM205/MM210/MM215 PCTV, bt878",
595 .video_inputs = 3,
596 .audio_inputs = 1,
597 .tuner = 0,
598 .svhs = -1,
599 .gpiomask = 7,
600 .muxsel = { 2, 3, -1 },
601 .digital_mode = DIGITAL_MODE_CAMERA,
602 .audiomux = { 0, 0, 0, 0, 0 },
603 .no_msp34xx = 1,
604 .pll = PLL_28,
605 .tuner_type = TUNER_ALPS_TSBB5_PAL_I,
606},{
607
608/* ---- card 0x18 ---------------------------------- */
609 .name = "Askey CPH05X/06X (bt878) [many vendors]",
610 .video_inputs = 3,
611 .audio_inputs = 1,
612 .tuner = 0,
613 .svhs = 2,
614 .gpiomask = 0xe00,
615 .muxsel = { 2, 3, 1, 1},
616 .audiomux = {0x400, 0x400, 0x400, 0x400, 0xc00},
617 .needs_tvaudio = 1,
618 .pll = PLL_28,
619 .tuner_type = -1,
620 .has_remote = 1,
621},{
622 .name = "Terratec TerraTV+ Version 1.0 (Bt848)/ Terra TValue Version 1.0/ Vobis TV-Boostar",
623 .video_inputs = 3,
624 .audio_inputs = 1,
625 .tuner = 0,
626 .svhs = 2,
627 .gpiomask = 0x1f0fff,
628 .muxsel = { 2, 3, 1, 1},
629 .audiomux = { 0x20000, 0x30000, 0x10000, 0, 0x40000},
630 .needs_tvaudio = 0,
631 .tuner_type = TUNER_PHILIPS_PAL,
632 .audio_hook = terratv_audio,
633},{
634 .name = "Hauppauge WinCam newer (bt878)",
635 .video_inputs = 4,
636 .audio_inputs = 1,
637 .tuner = 0,
638 .svhs = 3,
639 .gpiomask = 7,
640 .muxsel = { 2, 0, 1, 1},
641 .audiomux = { 0, 1, 2, 3, 4},
642 .needs_tvaudio = 1,
643 .tuner_type = -1,
644},{
645 .name = "Lifeview FlyVideo 98/ MAXI TV Video PCI2 LR50",
646 .video_inputs = 4,
647 .audio_inputs = 2,
648 .tuner = 0,
649 .svhs = 2,
650 .gpiomask = 0x1800,
651 .muxsel = { 2, 3, 1, 1},
652 .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800},
653 .pll = PLL_28,
654 .tuner_type = TUNER_PHILIPS_SECAM,
655},{
656
657/* ---- card 0x1c ---------------------------------- */
658 .name = "Terratec TerraTV+ Version 1.1 (bt878)",
659 .video_inputs = 3,
660 .audio_inputs = 1,
661 .tuner = 0,
662 .svhs = 2,
663 .gpiomask = 0x1f0fff,
664 .muxsel = { 2, 3, 1, 1},
665 .audiomux = { 0x20000, 0x30000, 0x10000, 0x00000, 0x40000},
666 .needs_tvaudio = 0,
667 .tuner_type = TUNER_PHILIPS_PAL,
668 .audio_hook = terratv_audio,
669 /* GPIO wiring:
670 External 20 pin connector (for Active Radio Upgrade board)
671 gpio00: i2c-sda
672 gpio01: i2c-scl
673 gpio02: om5610-data
674 gpio03: om5610-clk
675 gpio04: om5610-wre
676 gpio05: om5610-stereo
677 gpio06: rds6588-davn
678 gpio07: Pin 7 n.c.
679 gpio08: nIOW
680 gpio09+10: nIOR, nSEL ?? (bt878)
681 gpio09: nIOR (bt848)
682 gpio10: nSEL (bt848)
683 Sound Routing:
684 gpio16: u2-A0 (1st 4052bt)
685 gpio17: u2-A1
686 gpio18: u2-nEN
687 gpio19: u4-A0 (2nd 4052)
688 gpio20: u4-A1
689 u4-nEN - GND
690 Btspy:
691 00000 : Cdrom (internal audio input)
692 10000 : ext. Video audio input
693 20000 : TV Mono
694 a0000 : TV Mono/2
695 1a0000 : TV Stereo
696 30000 : Radio
697 40000 : Mute
698 */
699
700},{
701 /* Jannik Fritsch <jannik@techfak.uni-bielefeld.de> */
702 .name = "Imagenation PXC200",
703 .video_inputs = 5,
704 .audio_inputs = 1,
705 .tuner = -1,
706 .svhs = 1, /* was: 4 */
707 .gpiomask = 0,
708 .muxsel = { 2, 3, 1, 0, 0},
709 .audiomux = { 0 },
710 .needs_tvaudio = 1,
711 .tuner_type = -1,
712 .muxsel_hook = PXC200_muxsel,
713
714},{
715 .name = "Lifeview FlyVideo 98 LR50",
716 .video_inputs = 4,
717 .audio_inputs = 1,
718 .tuner = 0,
719 .svhs = 2,
720 .gpiomask = 0x1800, //0x8dfe00
721 .muxsel = { 2, 3, 1, 1},
722 .audiomux = { 0, 0x0800, 0x1000, 0x1000, 0x1800, 0 },
723 .pll = PLL_28,
724 .tuner_type = -1,
725},{
726 .name = "Formac iProTV, Formac ProTV I (bt848)",
727 .video_inputs = 4,
728 .audio_inputs = 1,
729 .tuner = 0,
730 .svhs = 3,
731 .gpiomask = 1,
732 .muxsel = { 2, 3, 1, 1},
733 .audiomux = { 1, 0, 0, 0, 0 },
734 .pll = PLL_28,
735 .tuner_type = TUNER_PHILIPS_PAL,
736},{
737
738/* ---- card 0x20 ---------------------------------- */
739 .name = "Intel Create and Share PCI/ Smart Video Recorder III",
740 .video_inputs = 4,
741 .audio_inputs = 0,
742 .tuner = -1,
743 .svhs = 2,
744 .gpiomask = 0,
745 .muxsel = { 2, 3, 1, 1},
746 .audiomux = { 0 },
747 .needs_tvaudio = 0,
748 .tuner_type = 4,
749},{
750 .name = "Terratec TerraTValue Version Bt878",
751 .video_inputs = 3,
752 .audio_inputs = 1,
753 .tuner = 0,
754 .svhs = 2,
755 .gpiomask = 0xffff00,
756 .muxsel = { 2, 3, 1, 1},
757 .audiomux = { 0x500, 0, 0x300, 0x900, 0x900},
758 .needs_tvaudio = 1,
759 .pll = PLL_28,
760 .tuner_type = TUNER_PHILIPS_PAL,
761},{
762 .name = "Leadtek WinFast 2000/ WinFast 2000 XP",
763 .video_inputs = 4,
764 .audio_inputs = 1,
765 .tuner = 0,
766 .svhs = 2,
767 .muxsel = { 2, 3, 1, 1, 0}, // TV, CVid, SVid, CVid over SVid connector
768#if 0
769 .gpiomask = 0xc33000,
770 .audiomux = { 0x422000,0x1000,0x0000,0x620000,0x800000 },
771#else
772 /* Alexander Varakin <avarakin@hotmail.com> [stereo version] */
773 .gpiomask = 0xb33000,
774 .audiomux = { 0x122000,0x1000,0x0000,0x620000,0x800000 },
775#endif
776 /* Audio Routing for "WinFast 2000 XP" (no tv stereo !)
777 gpio23 -- hef4052:nEnable (0x800000)
778 gpio12 -- hef4052:A1
779 gpio13 -- hef4052:A0
780 0x0000: external audio
781 0x1000: FM
782 0x2000: TV
783 0x3000: n.c.
784 Note: There exists another variant "Winfast 2000" with tv stereo !?
785 Note: eeprom only contains FF and pci subsystem id 107d:6606
786 */
787 .needs_tvaudio = 0,
788 .pll = PLL_28,
789 .has_radio = 1,
790 .tuner_type = 5, // default for now, gpio reads BFFF06 for Pal bg+dk
791 .audio_hook = winfast2000_audio,
792 .has_remote = 1,
793},{
794 .name = "Lifeview FlyVideo 98 LR50 / Chronos Video Shuttle II",
795 .video_inputs = 4,
796 .audio_inputs = 3,
797 .tuner = 0,
798 .svhs = 2,
799 .gpiomask = 0x1800,
800 .muxsel = { 2, 3, 1, 1},
801 .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800},
802 .pll = PLL_28,
803 .tuner_type = -1,
804},{
805
806/* ---- card 0x24 ---------------------------------- */
807 .name = "Lifeview FlyVideo 98FM LR50 / Typhoon TView TV/FM Tuner",
808 .video_inputs = 4,
809 .audio_inputs = 3,
810 .tuner = 0,
811 .svhs = 2,
812 .gpiomask = 0x1800,
813 .muxsel = { 2, 3, 1, 1},
814 .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800, 0 },
815 .pll = PLL_28,
816 .tuner_type = -1,
817 .has_radio = 1,
818},{
819 .name = "Prolink PixelView PlayTV pro",
820 .video_inputs = 3,
821 .audio_inputs = 1,
822 .tuner = 0,
823 .svhs = 2,
824 .gpiomask = 0xff,
825 .muxsel = { 2, 3, 1, 1 },
826 .audiomux = { 0x21, 0x20, 0x24, 0x2c, 0x29, 0x29 },
827 .no_msp34xx = 1,
828 .pll = PLL_28,
829 .tuner_type = -1,
830},{
831 .name = "Askey CPH06X TView99",
832 .video_inputs = 4,
833 .audio_inputs = 1,
834 .tuner = 0,
835 .svhs = 2,
836 .gpiomask = 0x551e00,
837 .muxsel = { 2, 3, 1, 0},
838 .audiomux = { 0x551400, 0x551200, 0, 0, 0x551c00, 0x551200 },
839 .needs_tvaudio = 1,
840 .pll = PLL_28,
841 .tuner_type = 1,
842 .has_remote = 1,
843},{
844 .name = "Pinnacle PCTV Studio/Rave",
845 .video_inputs = 3,
846 .audio_inputs = 1,
847 .tuner = 0,
848 .svhs = 2,
849 .gpiomask = 0x03000F,
850 .muxsel = { 2, 3, 1, 1},
851 .audiomux = { 2, 0xd0001, 0, 0, 1},
852 .needs_tvaudio = 0,
853 .pll = PLL_28,
854 .tuner_type = -1,
855},{
856
857/* ---- card 0x28 ---------------------------------- */
858 .name = "STB TV PCI FM, Gateway P/N 6000704 (bt878), 3Dfx VoodooTV 100",
859 .video_inputs = 3,
860 .audio_inputs = 1,
861 .tuner = 0,
862 .svhs = 2,
863 .gpiomask = 7,
864 .muxsel = { 2, 3, 1, 1},
865 .audiomux = { 4, 0, 2, 3, 1},
866 .no_msp34xx = 1,
867 .needs_tvaudio = 1,
868 .tuner_type = TUNER_PHILIPS_NTSC,
869 .pll = PLL_28,
870 .has_radio = 1,
871},{
872 .name = "AVerMedia TVPhone 98",
873 .video_inputs = 3,
874 .audio_inputs = 4,
875 .tuner = 0,
876 .svhs = 2,
877 .gpiomask = 15,
878 .muxsel = { 2, 3, 1, 1},
879 .audiomux = { 13, 4, 11, 7, 0, 0},
880 .needs_tvaudio = 1,
881 .pll = PLL_28,
882 .tuner_type = -1,
883 .has_radio = 1,
884 .audio_hook = avermedia_tvphone_audio,
885},{
886 .name = "ProVideo PV951", /* pic16c54 */
887 .video_inputs = 3,
888 .audio_inputs = 1,
889 .tuner = 0,
890 .svhs = 2,
891 .gpiomask = 0,
892 .muxsel = { 2, 3, 1, 1},
893 .audiomux = { 0, 0, 0, 0, 0},
894 .needs_tvaudio = 1,
895 .no_msp34xx = 1,
896 .pll = PLL_28,
897 .tuner_type = 1,
898},{
899 .name = "Little OnAir TV",
900 .video_inputs = 3,
901 .audio_inputs = 1,
902 .tuner = 0,
903 .svhs = 2,
904 .gpiomask = 0xe00b,
905 .muxsel = {2, 3, 1, 1},
906 .audiomux = {0xff9ff6, 0xff9ff6, 0xff1ff7, 0, 0xff3ffc},
907 .no_msp34xx = 1,
908 .tuner_type = -1,
909},{
910
911/* ---- card 0x2c ---------------------------------- */
912 .name = "Sigma TVII-FM",
913 .video_inputs = 2,
914 .audio_inputs = 1,
915 .tuner = 0,
916 .svhs = -1,
917 .gpiomask = 3,
918 .muxsel = {2, 3, 1, 1},
919 .audiomux = {1, 1, 0, 2, 3},
920 .no_msp34xx = 1,
921 .pll = PLL_NONE,
922 .tuner_type = -1,
923},{
924 .name = "MATRIX-Vision MV-Delta 2",
925 .video_inputs = 5,
926 .audio_inputs = 1,
927 .tuner = -1,
928 .svhs = 3,
929 .gpiomask = 0,
930 .muxsel = { 2, 3, 1, 0, 0},
931 .audiomux = {0 },
932 .no_msp34xx = 1,
933 .pll = PLL_28,
934 .tuner_type = -1,
935},{
936 .name = "Zoltrix Genie TV/FM",
937 .video_inputs = 3,
938 .audio_inputs = 1,
939 .tuner = 0,
940 .svhs = 2,
941 .gpiomask = 0xbcf03f,
942 .muxsel = { 2, 3, 1, 1},
943 .audiomux = { 0xbc803f, 0xbc903f, 0xbcb03f, 0, 0xbcb03f},
944 .no_msp34xx = 1,
945 .pll = PLL_28,
946 .tuner_type = 21,
947},{
948 .name = "Terratec TV/Radio+",
949 .video_inputs = 3,
950 .audio_inputs = 1,
951 .tuner = 0,
952 .svhs = 2,
953 .gpiomask = 0x70000,
954 .muxsel = { 2, 3, 1, 1},
955 .audiomux = { 0x20000, 0x30000, 0x10000, 0, 0x40000, 0x20000 },
956 .needs_tvaudio = 1,
957 .no_msp34xx = 1,
958 .pll = PLL_35,
959 .tuner_type = 1,
960 .has_radio = 1,
961},{
962
963/* ---- card 0x30 ---------------------------------- */
964 .name = "Askey CPH03x/ Dynalink Magic TView",
965 .video_inputs = 3,
966 .audio_inputs = 1,
967 .tuner = 0,
968 .svhs = 2,
969 .gpiomask = 15,
970 .muxsel = { 2, 3, 1, 1},
971 .audiomux = {2,0,0,0,1},
972 .needs_tvaudio = 1,
973 .pll = PLL_28,
974 .tuner_type = -1,
975},{
976 .name = "IODATA GV-BCTV3/PCI",
977 .video_inputs = 3,
978 .audio_inputs = 1,
979 .tuner = 0,
980 .svhs = 2,
981 .gpiomask = 0x010f00,
982 .muxsel = {2, 3, 0, 0},
983 .audiomux = {0x10000, 0, 0x10000, 0, 0, 0},
984 .no_msp34xx = 1,
985 .pll = PLL_28,
986 .tuner_type = TUNER_ALPS_TSHC6_NTSC,
987 .audio_hook = gvbctv3pci_audio,
988},{
989 .name = "Prolink PV-BT878P+4E / PixelView PlayTV PAK / Lenco MXTV-9578 CP",
990 .video_inputs = 5,
991 .audio_inputs = 1,
992 .tuner = 0,
993 .svhs = 3,
994 .gpiomask = 0xAA0000,
995 .muxsel = { 2,3,1,1,-1 },
996 .digital_mode = DIGITAL_MODE_CAMERA,
997 .audiomux = { 0x20000, 0, 0x80000, 0x80000, 0xa8000, 0x46000 },
998 .no_msp34xx = 1,
999 .pll = PLL_28,
1000 .tuner_type = TUNER_PHILIPS_PAL_I,
1001 .has_remote = 1,
1002 /* GPIO wiring: (different from Rev.4C !)
1003 GPIO17: U4.A0 (first hef4052bt)
1004 GPIO19: U4.A1
1005 GPIO20: U5.A1 (second hef4052bt)
1006 GPIO21: U4.nEN
1007 GPIO22: BT832 Reset Line
1008 GPIO23: A5,A0, U5,nEN
1009 Note: At i2c=0x8a is a Bt832 chip, which changes to 0x88 after being reset via GPIO22
1010 */
1011},{
1012 .name = "Eagle Wireless Capricorn2 (bt878A)",
1013 .video_inputs = 4,
1014 .audio_inputs = 1,
1015 .tuner = 0,
1016 .svhs = 2,
1017 .gpiomask = 7,
1018 .muxsel = { 2, 0, 1, 1},
1019 .audiomux = { 0, 1, 2, 3, 4},
1020 .pll = PLL_28,
1021 .tuner_type = -1 /* TUNER_ALPS_TMDH2_NTSC */,
1022},{
1023
1024/* ---- card 0x34 ---------------------------------- */
1025 /* David Härdeman <david@2gen.com> */
1026 .name = "Pinnacle PCTV Studio Pro",
1027 .video_inputs = 4,
1028 .audio_inputs = 1,
1029 .tuner = 0,
1030 .svhs = 3,
1031 .gpiomask = 0x03000F,
1032 .muxsel = { 2, 3, 1, 1},
1033 .audiomux = { 1, 0xd0001, 0, 0, 10},
1034 /* sound path (5 sources):
1035 MUX1 (mask 0x03), Enable Pin 0x08 (0=enable, 1=disable)
1036 0= ext. Audio IN
1037 1= from MUX2
1038 2= Mono TV sound from Tuner
1039 3= not connected
1040 MUX2 (mask 0x30000):
1041 0,2,3= from MSP34xx
1042 1= FM stereo Radio from Tuner */
1043 .needs_tvaudio = 0,
1044 .pll = PLL_28,
1045 .tuner_type = -1,
1046},{
1047 /* Claas Langbehn <claas@bigfoot.com>,
1048 Sven Grothklags <sven@upb.de> */
1049 .name = "Typhoon TView RDS + FM Stereo / KNC1 TV Station RDS",
1050 .video_inputs = 4,
1051 .audio_inputs = 3,
1052 .tuner = 0,
1053 .svhs = 2,
1054 .gpiomask = 0x1c,
1055 .muxsel = { 2, 3, 1, 1},
1056 .audiomux = { 0, 0, 0x10, 8, 4 },
1057 .needs_tvaudio = 1,
1058 .pll = PLL_28,
1059 .tuner_type = TUNER_PHILIPS_PAL,
1060 .has_radio = 1,
1061},{
1062 /* Tim Röstermundt <rosterm@uni-muenster.de>
1063 in de.comp.os.unix.linux.hardware:
1064 options bttv card=0 pll=1 radio=1 gpiomask=0x18e0
1065 audiomux=0x44c71f,0x44d71f,0,0x44d71f,0x44dfff
1066 options tuner type=5 */
1067 .name = "Lifeview FlyVideo 2000 /FlyVideo A2/ Lifetec LT 9415 TV [LR90]",
1068 .video_inputs = 4,
1069 .audio_inputs = 1,
1070 .tuner = 0,
1071 .svhs = 2,
1072 .gpiomask = 0x18e0,
1073 .muxsel = { 2, 3, 1, 1},
1074 .audiomux = { 0x0000,0x0800,0x1000,0x1000,0x18e0 },
1075 /* For cards with tda9820/tda9821:
1076 0x0000: Tuner normal stereo
1077 0x0080: Tuner A2 SAP (second audio program = Zweikanalton)
1078 0x0880: Tuner A2 stereo */
1079 .pll = PLL_28,
1080 .tuner_type = -1,
1081},{
1082 /* Miguel Angel Alvarez <maacruz@navegalia.com>
1083 old Easy TV BT848 version (model CPH031) */
1084 .name = "Askey CPH031/ BESTBUY Easy TV",
1085 .video_inputs = 4,
1086 .audio_inputs = 1,
1087 .tuner = 0,
1088 .svhs = 2,
1089 .gpiomask = 0xF,
1090 .muxsel = { 2, 3, 1, 0},
1091 .audiomux = { 2, 0, 0, 0, 10},
1092 .needs_tvaudio = 0,
1093 .pll = PLL_28,
1094 .tuner_type = TUNER_TEMIC_PAL,
1095},{
1096
1097/* ---- card 0x38 ---------------------------------- */
1098 /* Gordon Heydon <gjheydon@bigfoot.com ('98) */
1099 .name = "Lifeview FlyVideo 98FM LR50",
1100 .video_inputs = 4,
1101 .audio_inputs = 3,
1102 .tuner = 0,
1103 .svhs = 2,
1104 .gpiomask = 0x1800,
1105 .muxsel = { 2, 3, 1, 1},
1106 .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800, 0 },
1107 .pll = PLL_28,
1108 .tuner_type = 5,
1109},{
1110 /* This is the ultimate cheapo capture card
1111 * just a BT848A on a small PCB!
1112 * Steve Hosgood <steve@equiinet.com> */
1113 .name = "GrandTec 'Grand Video Capture' (Bt848)",
1114 .video_inputs = 2,
1115 .audio_inputs = 0,
1116 .tuner = -1,
1117 .svhs = 1,
1118 .gpiomask = 0,
1119 .muxsel = { 3, 1 },
1120 .audiomux = { 0 },
1121 .needs_tvaudio = 0,
1122 .no_msp34xx = 1,
1123 .pll = PLL_35,
1124 .tuner_type = -1,
1125},{
1126 /* Daniel Herrington <daniel.herrington@home.com> */
1127 .name = "Askey CPH060/ Phoebe TV Master Only (No FM)",
1128 .video_inputs = 3,
1129 .audio_inputs = 1,
1130 .tuner = 0,
1131 .svhs = 2,
1132 .gpiomask = 0xe00,
1133 .muxsel = { 2, 3, 1, 1},
1134 .audiomux = { 0x400, 0x400, 0x400, 0x400, 0x800, 0x400 },
1135 .needs_tvaudio = 1,
1136 .pll = PLL_28,
1137 .tuner_type = TUNER_TEMIC_4036FY5_NTSC,
1138},{
1139 /* Matti Mottus <mottus@physic.ut.ee> */
1140 .name = "Askey CPH03x TV Capturer",
1141 .video_inputs = 4,
1142 .audio_inputs = 1,
1143 .tuner = 0,
1144 .svhs = 2,
1145 .gpiomask = 0x03000F,
1146 .muxsel = { 2, 3, 1, 0},
1147 .audiomux = { 2,0,0,0,1 },
1148 .pll = PLL_28,
1149 .tuner_type = 0,
1150},{
1151
1152/* ---- card 0x3c ---------------------------------- */
1153 /* Philip Blundell <philb@gnu.org> */
1154 .name = "Modular Technology MM100PCTV",
1155 .video_inputs = 2,
1156 .audio_inputs = 2,
1157 .tuner = 0,
1158 .svhs = -1,
1159 .gpiomask = 11,
1160 .muxsel = { 2, 3, 1, 1},
1161 .audiomux = { 2, 0, 0, 1, 8},
1162 .pll = PLL_35,
1163 .tuner_type = TUNER_TEMIC_PAL,
1164
1165},{
1166 /* Adrian Cox <adrian@humboldt.co.uk */
1167 .name = "AG Electronics GMV1",
1168 .video_inputs = 2,
1169 .audio_inputs = 0,
1170 .tuner = -1,
1171 .svhs = 1,
1172 .gpiomask = 0xF,
1173 .muxsel = { 2, 2},
1174 .audiomux = { },
1175 .no_msp34xx = 1,
1176 .needs_tvaudio = 0,
1177 .pll = PLL_28,
1178 .tuner_type = -1,
1179},{
1180 /* Miguel Angel Alvarez <maacruz@navegalia.com>
1181 new Easy TV BT878 version (model CPH061)
1182 special thanks to Informatica Mieres for providing the card */
1183 .name = "Askey CPH061/ BESTBUY Easy TV (bt878)",
1184 .video_inputs = 3,
1185 .audio_inputs = 2,
1186 .tuner = 0,
1187 .svhs = 2,
1188 .gpiomask = 0xFF,
1189 .muxsel = { 2, 3, 1, 0},
1190 .audiomux = { 1, 0, 4, 4, 9},
1191 .needs_tvaudio = 0,
1192 .pll = PLL_28,
1193 .tuner_type = TUNER_PHILIPS_PAL,
1194},{
1195 /* Lukas Gebauer <geby@volny.cz> */
1196 .name = "ATI TV-Wonder",
1197 .video_inputs = 3,
1198 .audio_inputs = 1,
1199 .tuner = 0,
1200 .svhs = 2,
1201 .gpiomask = 0xf03f,
1202 .muxsel = { 2, 3, 1, 0 },
1203 .audiomux = { 0xbffe, 0, 0xbfff, 0, 0xbffe},
1204 .pll = PLL_28,
1205 .tuner_type = TUNER_TEMIC_4006FN5_MULTI_PAL,
1206},{
1207
1208/* ---- card 0x40 ---------------------------------- */
1209 /* Lukas Gebauer <geby@volny.cz> */
1210 .name = "ATI TV-Wonder VE",
1211 .video_inputs = 2,
1212 .audio_inputs = 1,
1213 .tuner = 0,
1214 .svhs = -1,
1215 .gpiomask = 1,
1216 .muxsel = { 2, 3, 0, 1},
1217 .audiomux = { 0, 0, 1, 0, 0},
1218 .no_msp34xx = 1,
1219 .pll = PLL_28,
1220 .tuner_type = TUNER_TEMIC_4006FN5_MULTI_PAL,
1221},{
1222 /* DeeJay <deejay@westel900.net (2000S) */
1223 .name = "Lifeview FlyVideo 2000S LR90",
1224 .video_inputs = 3,
1225 .audio_inputs = 3,
1226 .tuner = 0,
1227 .svhs = 2,
1228 .gpiomask = 0x18e0,
1229 .muxsel = { 2, 3, 0, 1},
1230 /* Radio changed from 1e80 to 0x800 to make
1231 FlyVideo2000S in .hu happy (gm)*/
1232 /* -dk-???: set mute=0x1800 for tda9874h daughterboard */
1233 .audiomux = { 0x0000,0x0800,0x1000,0x1000,0x1800, 0x1080 },
1234 .audio_hook = fv2000s_audio,
1235 .no_msp34xx = 1,
1236 .no_tda9875 = 1,
1237 .needs_tvaudio = 1,
1238 .pll = PLL_28,
1239 .tuner_type = 5,
1240},{
1241 .name = "Terratec TValueRadio",
1242 .video_inputs = 3,
1243 .audio_inputs = 1,
1244 .tuner = 0,
1245 .svhs = 2,
1246 .gpiomask = 0xffff00,
1247 .muxsel = { 2, 3, 1, 1},
1248 .audiomux = { 0x500, 0x500, 0x300, 0x900, 0x900},
1249 .needs_tvaudio = 1,
1250 .pll = PLL_28,
1251 .tuner_type = TUNER_PHILIPS_PAL,
1252 .has_radio = 1,
1253},{
1254 /* TANAKA Kei <peg00625@nifty.com> */
1255 .name = "IODATA GV-BCTV4/PCI",
1256 .video_inputs = 3,
1257 .audio_inputs = 1,
1258 .tuner = 0,
1259 .svhs = 2,
1260 .gpiomask = 0x010f00,
1261 .muxsel = {2, 3, 0, 0},
1262 .audiomux = {0x10000, 0, 0x10000, 0, 0, 0},
1263 .no_msp34xx = 1,
1264 .pll = PLL_28,
1265 .tuner_type = TUNER_SHARP_2U5JF5540_NTSC,
1266 .audio_hook = gvbctv3pci_audio,
1267},{
1268
1269/* ---- card 0x44 ---------------------------------- */
1270 .name = "3Dfx VoodooTV FM (Euro), VoodooTV 200 (USA)",
1271 // try "insmod msp3400 simple=0" if you have
1272 // sound problems with this card.
1273 .video_inputs = 4,
1274 .audio_inputs = 1,
1275 .tuner = 0,
1276 .svhs = -1,
1277 .gpiomask = 0x4f8a00,
1278 // 0x100000: 1=MSP enabled (0=disable again)
1279 // 0x010000: Connected to "S0" on tda9880 (0=Pal/BG, 1=NTSC)
1280 .audiomux = {0x947fff, 0x987fff,0x947fff,0x947fff, 0x947fff},
1281 // tvtuner, radio, external,internal, mute, stereo
1282 /* tuner, Composit, SVid, Composit-on-Svid-adapter*/
1283 .muxsel = { 2, 3 ,0 ,1},
1284 .tuner_type = TUNER_MT2032,
1285 .pll = PLL_28,
1286 .has_radio = 1,
1287},{
1288 /* Philip Blundell <pb@nexus.co.uk> */
1289 .name = "Active Imaging AIMMS",
1290 .video_inputs = 1,
1291 .audio_inputs = 0,
1292 .tuner = -1,
1293 .tuner_type = -1,
1294 .pll = PLL_28,
1295 .muxsel = { 2 },
1296 .gpiomask = 0
1297},{
1298 /* Tomasz Pyra <hellfire@sedez.iq.pl> */
1299 .name = "Prolink Pixelview PV-BT878P+ (Rev.4C,8E)",
1300 .video_inputs = 3,
1301 .audio_inputs = 4,
1302 .tuner = 0,
1303 .svhs = 2,
1304 .gpiomask = 15,
1305 .muxsel = { 2, 3, 1, 1},
1306 .audiomux = { 0, 0, 11, 7, 13, 0}, // TV and Radio with same GPIO !
1307 .needs_tvaudio = 1,
1308 .pll = PLL_28,
1309 .tuner_type = 25,
1310 .has_remote = 1,
1311 /* GPIO wiring:
1312 GPIO0: U4.A0 (hef4052bt)
1313 GPIO1: U4.A1
1314 GPIO2: U4.A1 (second hef4052bt)
1315 GPIO3: U4.nEN, U5.A0, A5.nEN
1316 GPIO8-15: vrd866b ?
1317 */
1318},{
1319 .name = "Lifeview FlyVideo 98EZ (capture only) LR51",
1320 .video_inputs = 4,
1321 .audio_inputs = 0,
1322 .tuner = -1,
1323 .svhs = 2,
1324 .muxsel = { 2, 3, 1, 1}, // AV1, AV2, SVHS, CVid adapter on SVHS
1325 .pll = PLL_28,
1326 .no_msp34xx = 1,
1327},{
1328
1329/* ---- card 0x48 ---------------------------------- */
1330 /* Dariusz Kowalewski <darekk@automex.pl> */
1331 .name = "Prolink Pixelview PV-BT878P+9B (PlayTV Pro rev.9B FM+NICAM)",
1332 .video_inputs = 4,
1333 .audio_inputs = 1,
1334 .tuner = 0,
1335 .svhs = 2,
1336 .gpiomask = 0x3f,
1337 .muxsel = { 2, 3, 1, 1 },
1338 .audiomux = { 0x01, 0x00, 0x03, 0x03, 0x09, 0x02 },
1339 .needs_tvaudio = 1,
1340 .no_msp34xx = 1,
1341 .no_tda9875 = 1,
1342 .pll = PLL_28,
1343 .tuner_type = 5,
1344 .audio_hook = pvbt878p9b_audio, // Note: not all cards have stereo
1345 .has_radio = 1, // Note: not all cards have radio
1346 .has_remote = 1,
1347 /* GPIO wiring:
1348 GPIO0: A0 hef4052
1349 GPIO1: A1 hef4052
1350 GPIO3: nEN hef4052
1351 GPIO8-15: vrd866b
1352 GPIO20,22,23: R30,R29,R28
1353 */
1354},{
1355 /* Clay Kunz <ckunz@mail.arc.nasa.gov> */
1356 /* you must jumper JP5 for the card to work */
1357 .name = "Sensoray 311",
1358 .video_inputs = 5,
1359 .audio_inputs = 0,
1360 .tuner = -1,
1361 .svhs = 4,
1362 .gpiomask = 0,
1363 .muxsel = { 2, 3, 1, 0, 0},
1364 .audiomux = { 0 },
1365 .needs_tvaudio = 0,
1366 .tuner_type = -1,
1367},{
1368 /* Miguel Freitas <miguel@cetuc.puc-rio.br> */
1369 .name = "RemoteVision MX (RV605)",
1370 .video_inputs = 16,
1371 .audio_inputs = 0,
1372 .tuner = -1,
1373 .svhs = -1,
1374 .gpiomask = 0x00,
1375 .gpiomask2 = 0x07ff,
1376 .muxsel = { 0x33, 0x13, 0x23, 0x43, 0xf3, 0x73, 0xe3, 0x03,
1377 0xd3, 0xb3, 0xc3, 0x63, 0x93, 0x53, 0x83, 0xa3 },
1378 .no_msp34xx = 1,
1379 .no_tda9875 = 1,
1380 .tuner_type = -1,
1381 .muxsel_hook = rv605_muxsel,
1382},{
1383 .name = "Powercolor MTV878/ MTV878R/ MTV878F",
1384 .video_inputs = 3,
1385 .audio_inputs = 2,
1386 .tuner = 0,
1387 .svhs = 2,
1388 .gpiomask = 0x1C800F, // Bit0-2: Audio select, 8-12:remote control 14:remote valid 15:remote reset
1389 .muxsel = { 2, 1, 1, },
1390 .audiomux = { 0, 1, 2, 2, 4 },
1391 .needs_tvaudio = 0,
1392 .tuner_type = TUNER_PHILIPS_PAL,
1393 .pll = PLL_28,
1394 .has_radio = 1,
1395},{
1396
1397/* ---- card 0x4c ---------------------------------- */
1398 /* Masaki Suzuki <masaki@btree.org> */
1399 .name = "Canopus WinDVR PCI (COMPAQ Presario 3524JP, 5112JP)",
1400 .video_inputs = 3,
1401 .audio_inputs = 1,
1402 .tuner = 0,
1403 .svhs = 2,
1404 .gpiomask = 0x140007,
1405 .muxsel = { 2, 3, 1, 1 },
1406 .audiomux = { 0, 1, 2, 3, 4, 0 },
1407 .tuner_type = TUNER_PHILIPS_NTSC,
1408 .audio_hook = windvr_audio,
1409},{
1410 .name = "GrandTec Multi Capture Card (Bt878)",
1411 .video_inputs = 4,
1412 .audio_inputs = 0,
1413 .tuner = -1,
1414 .svhs = -1,
1415 .gpiomask = 0,
1416 .muxsel = { 2, 3, 1, 0 },
1417 .audiomux = { 0 },
1418 .needs_tvaudio = 0,
1419 .no_msp34xx = 1,
1420 .pll = PLL_28,
1421 .tuner_type = -1,
1422},{
1423 .name = "Jetway TV/Capture JW-TV878-FBK, Kworld KW-TV878RF",
1424 .video_inputs = 4,
1425 .audio_inputs = 3,
1426 .tuner = 0,
1427 .svhs = 2,
1428 .gpiomask = 7,
1429 .muxsel = { 2, 3, 1, 1 }, // Tuner, SVid, SVHS, SVid to SVHS connector
1430 .audiomux = { 0 ,0 ,4, 4,4,4},// Yes, this tuner uses the same audio output for TV and FM radio!
1431 // This card lacks external Audio In, so we mute it on Ext. & Int.
1432 // The PCB can take a sbx1637/sbx1673, wiring unknown.
1433 // This card lacks PCI subsystem ID, sigh.
1434 // audiomux=1: lower volume, 2+3: mute
1435 // btwincap uses 0x80000/0x80003
1436 .needs_tvaudio = 0,
1437 .no_msp34xx = 1,
1438 .pll = PLL_28,
1439 .tuner_type = 5, // Samsung TCPA9095PC27A (BG+DK), philips compatible, w/FM, stereo and
1440 // radio signal strength indicators work fine.
1441 .has_radio = 1,
1442 /* GPIO Info:
1443 GPIO0,1: HEF4052 A0,A1
1444 GPIO2: HEF4052 nENABLE
1445 GPIO3-7: n.c.
1446 GPIO8-13: IRDC357 data0-5 (data6 n.c. ?) [chip not present on my card]
1447 GPIO14,15: ??
1448 GPIO16-21: n.c.
1449 GPIO22,23: ??
1450 ?? : mtu8b56ep microcontroller for IR (GPIO wiring unknown)*/
1451},{
1452 /* Arthur Tetzlaff-Deas, DSP Design Ltd <software@dspdesign.com> */
1453 .name = "DSP Design TCVIDEO",
1454 .video_inputs = 4,
1455 .svhs = -1,
1456 .muxsel = { 2, 3, 1, 0},
1457 .pll = PLL_28,
1458 .tuner_type = -1,
1459},{
1460
1461 /* ---- card 0x50 ---------------------------------- */
1462 .name = "Hauppauge WinTV PVR",
1463 .video_inputs = 4,
1464 .audio_inputs = 1,
1465 .tuner = 0,
1466 .svhs = 2,
1467 .muxsel = { 2, 0, 1, 1},
1468 .needs_tvaudio = 1,
1469 .pll = PLL_28,
1470 .tuner_type = -1,
1471
1472 .gpiomask = 7,
1473 .audiomux = {7},
1474},{
1475 .name = "IODATA GV-BCTV5/PCI",
1476 .video_inputs = 3,
1477 .audio_inputs = 1,
1478 .tuner = 0,
1479 .svhs = 2,
1480 .gpiomask = 0x0f0f80,
1481 .muxsel = {2, 3, 1, 0},
1482 .audiomux = {0x030000, 0x010000, 0, 0, 0x020000, 0},
1483 .no_msp34xx = 1,
1484 .pll = PLL_28,
1485 .tuner_type = TUNER_PHILIPS_NTSC_M,
1486 .audio_hook = gvbctv5pci_audio,
1487 .has_radio = 1,
1488},{
1489 .name = "Osprey 100/150 (878)", /* 0x1(2|3)-45C6-C1 */
1490 .video_inputs = 4, /* id-inputs-clock */
1491 .audio_inputs = 0,
1492 .tuner = -1,
1493 .svhs = 3,
1494 .muxsel = { 3, 2, 0, 1 },
1495 .pll = PLL_28,
1496 .tuner_type = -1,
1497 .no_msp34xx = 1,
1498 .no_tda9875 = 1,
1499 .no_tda7432 = 1,
1500},{
1501 .name = "Osprey 100/150 (848)", /* 0x04-54C0-C1 & older boards */
1502 .video_inputs = 3,
1503 .audio_inputs = 0,
1504 .tuner = -1,
1505 .svhs = 2,
1506 .muxsel = { 2, 3, 1 },
1507 .pll = PLL_28,
1508 .tuner_type = -1,
1509 .no_msp34xx = 1,
1510 .no_tda9875 = 1,
1511 .no_tda7432 = 1,
1512},{
1513
1514 /* ---- card 0x54 ---------------------------------- */
1515 .name = "Osprey 101 (848)", /* 0x05-40C0-C1 */
1516 .video_inputs = 2,
1517 .audio_inputs = 0,
1518 .tuner = -1,
1519 .svhs = 1,
1520 .muxsel = { 3, 1 },
1521 .pll = PLL_28,
1522 .tuner_type = -1,
1523 .no_msp34xx = 1,
1524 .no_tda9875 = 1,
1525 .no_tda7432 = 1,
1526},{
1527 .name = "Osprey 101/151", /* 0x1(4|5)-0004-C4 */
1528 .video_inputs = 1,
1529 .audio_inputs = 0,
1530 .tuner = -1,
1531 .svhs = -1,
1532 .muxsel = { 0 },
1533 .pll = PLL_28,
1534 .tuner_type = -1,
1535 .no_msp34xx = 1,
1536 .no_tda9875 = 1,
1537 .no_tda7432 = 1,
1538},{
1539 .name = "Osprey 101/151 w/ svid", /* 0x(16|17|20)-00C4-C1 */
1540 .video_inputs = 2,
1541 .audio_inputs = 0,
1542 .tuner = -1,
1543 .svhs = 1,
1544 .muxsel = { 0, 1 },
1545 .pll = PLL_28,
1546 .tuner_type = -1,
1547 .no_msp34xx = 1,
1548 .no_tda9875 = 1,
1549 .no_tda7432 = 1,
1550},{
1551 .name = "Osprey 200/201/250/251", /* 0x1(8|9|E|F)-0004-C4 */
1552 .video_inputs = 1,
1553 .audio_inputs = 1,
1554 .tuner = -1,
1555 .svhs = -1,
1556 .muxsel = { 0 },
1557 .pll = PLL_28,
1558 .tuner_type = -1,
1559 .no_msp34xx = 1,
1560 .no_tda9875 = 1,
1561 .no_tda7432 = 1,
1562},{
1563
1564 /* ---- card 0x58 ---------------------------------- */
1565 .name = "Osprey 200/250", /* 0x1(A|B)-00C4-C1 */
1566 .video_inputs = 2,
1567 .audio_inputs = 1,
1568 .tuner = -1,
1569 .svhs = 1,
1570 .muxsel = { 0, 1 },
1571 .pll = PLL_28,
1572 .tuner_type = -1,
1573 .no_msp34xx = 1,
1574 .no_tda9875 = 1,
1575 .no_tda7432 = 1,
1576},{
1577 .name = "Osprey 210/220", /* 0x1(A|B)-04C0-C1 */
1578 .video_inputs = 2,
1579 .audio_inputs = 1,
1580 .tuner = -1,
1581 .svhs = 1,
1582 .muxsel = { 2, 3 },
1583 .pll = PLL_28,
1584 .tuner_type = -1,
1585 .no_msp34xx = 1,
1586 .no_tda9875 = 1,
1587 .no_tda7432 = 1,
1588},{
1589 .name = "Osprey 500", /* 500 */
1590 .video_inputs = 2,
1591 .audio_inputs = 1,
1592 .tuner = -1,
1593 .svhs = 1,
1594 .muxsel = { 2, 3 },
1595 .pll = PLL_28,
1596 .tuner_type = -1,
1597 .no_msp34xx = 1,
1598 .no_tda9875 = 1,
1599 .no_tda7432 = 1,
1600},{
1601 .name = "Osprey 540", /* 540 */
1602 .video_inputs = 4,
1603 .audio_inputs = 1,
1604 .tuner = -1,
1605#if 0 /* TODO ... */
1606 .svhs = OSPREY540_SVID_ANALOG,
1607 .muxsel = { [OSPREY540_COMP_ANALOG] = 2,
1608 [OSPREY540_SVID_ANALOG] = 3, },
1609#endif
1610 .pll = PLL_28,
1611 .tuner_type = -1,
1612 .no_msp34xx = 1,
1613 .no_tda9875 = 1,
1614 .no_tda7432 = 1,
1615#if 0 /* TODO ... */
1616 .muxsel_hook = osprey_540_muxsel,
1617 .picture_hook = osprey_540_set_picture,
1618#endif
1619},{
1620
1621 /* ---- card 0x5C ---------------------------------- */
1622 .name = "Osprey 2000", /* 2000 */
1623 .video_inputs = 2,
1624 .audio_inputs = 1,
1625 .tuner = -1,
1626 .svhs = 1,
1627 .muxsel = { 2, 3 },
1628 .pll = PLL_28,
1629 .tuner_type = -1,
1630 .no_msp34xx = 1,
1631 .no_tda9875 = 1,
1632 .no_tda7432 = 1, /* must avoid, conflicts with the bt860 */
1633},{
1634 /* M G Berberich <berberic@forwiss.uni-passau.de> */
1635 .name = "IDS Eagle",
1636 .video_inputs = 4,
1637 .audio_inputs = 0,
1638 .tuner = -1,
1639 .tuner_type = -1,
1640 .svhs = -1,
1641 .gpiomask = 0,
1642 .muxsel = { 0, 1, 2, 3 },
1643 .muxsel_hook = eagle_muxsel,
1644 .no_msp34xx = 1,
1645 .no_tda9875 = 1,
1646 .pll = PLL_28,
1647},{
1648 .name = "Pinnacle PCTV Sat",
1649 .video_inputs = 2,
1650 .audio_inputs = 0,
1651 .svhs = 1,
1652 .tuner = -1,
1653 .tuner_type = -1,
1654 .no_msp34xx = 1,
1655 .no_tda9875 = 1,
1656 .no_tda7432 = 1,
1657 .gpiomask = 0x01,
1658 .audiomux = { 0, 0, 0, 0, 1 },
1659 .muxsel = { 3, 0, 1, 2},
1660 .needs_tvaudio = 0,
1661 .pll = PLL_28,
1662 .no_gpioirq = 1,
1663 .has_dvb = 1,
1664},{
1665 .name = "Formac ProTV II (bt878)",
1666 .video_inputs = 4,
1667 .audio_inputs = 1,
1668 .tuner = 0,
1669 .svhs = 3,
1670 .gpiomask = 2,
1671 // TV, Comp1, Composite over SVID con, SVID
1672 .muxsel = { 2, 3, 1, 1},
1673 .audiomux = { 2, 2, 0, 0, 0 },
1674 .pll = PLL_28,
1675 .has_radio = 1,
1676 .tuner_type = TUNER_PHILIPS_PAL,
1677 /* sound routing:
1678 GPIO=0x00,0x01,0x03: mute (?)
1679 0x02: both TV and radio (tuner: FM1216/I)
1680 The card has onboard audio connectors labeled "cdrom" and "board",
1681 not soldered here, though unknown wiring.
1682 Card lacks: external audio in, pci subsystem id.
1683 */
1684},{
1685
1686 /* ---- card 0x60 ---------------------------------- */
1687 .name = "MachTV",
1688 .video_inputs = 3,
1689 .audio_inputs = 1,
1690 .tuner = 0,
1691 .svhs = -1,
1692 .gpiomask = 7,
1693 .muxsel = { 2, 3, 1, 1},
1694 .audiomux = { 0, 1, 2, 3, 4},
1695 .needs_tvaudio = 1,
1696 .tuner_type = 5,
1697 .pll = 1,
1698},{
1699 .name = "Euresys Picolo",
1700 .video_inputs = 3,
1701 .audio_inputs = 0,
1702 .tuner = -1,
1703 .svhs = 2,
1704 .gpiomask = 0,
1705 .no_msp34xx = 1,
1706 .no_tda9875 = 1,
1707 .no_tda7432 = 1,
1708 .muxsel = { 2, 0, 1},
1709 .pll = PLL_28,
1710},{
1711 /* Luc Van Hoeylandt <luc@e-magic.be> */
1712 .name = "ProVideo PV150", /* 0x4f */
1713 .video_inputs = 2,
1714 .audio_inputs = 0,
1715 .tuner = -1,
1716 .svhs = -1,
1717 .gpiomask = 0,
1718 .muxsel = { 2, 3 },
1719 .audiomux = { 0 },
1720 .needs_tvaudio = 0,
1721 .no_msp34xx = 1,
1722 .pll = PLL_28,
1723 .tuner_type = -1,
1724},{
1725 /* Hiroshi Takekawa <sian@big.or.jp> */
1726 /* This card lacks subsystem ID */
1727 .name = "AD-TVK503", /* 0x63 */
1728 .video_inputs = 4,
1729 .audio_inputs = 1,
1730 .tuner = 0,
1731 .svhs = 2,
1732 .gpiomask = 0x001e8007,
1733 .muxsel = { 2, 3, 1, 0 },
1734 /* Tuner, Radio, external, internal, off, on */
1735 .audiomux = { 0x08, 0x0f, 0x0a, 0x08, 0x0f, 0x08 },
1736 .needs_tvaudio = 0,
1737 .no_msp34xx = 1,
1738 .pll = PLL_28,
1739 .tuner_type = 2,
1740 .audio_hook = adtvk503_audio,
1741},{
1742
1743 /* ---- card 0x64 ---------------------------------- */
1744 .name = "Hercules Smart TV Stereo",
1745 .video_inputs = 4,
1746 .audio_inputs = 1,
1747 .tuner = 0,
1748 .svhs = 2,
1749 .gpiomask = 0x00,
1750 .muxsel = { 2, 3, 1, 1 },
1751 .needs_tvaudio = 1,
1752 .no_msp34xx = 1,
1753 .pll = PLL_28,
1754 .tuner_type = 5,
1755 /* Notes:
1756 - card lacks subsystem ID
1757 - stereo variant w/ daughter board with tda9874a @0xb0
1758 - Audio Routing:
1759 always from tda9874 independent of GPIO (?)
1760 external line in: unknown
1761 - Other chips: em78p156elp @ 0x96 (probably IR remote control)
1762 hef4053 (instead 4052) for unknown function
1763 */
1764},{
1765 .name = "Pace TV & Radio Card",
1766 .video_inputs = 4,
1767 .audio_inputs = 1,
1768 .tuner = 0,
1769 .svhs = 2,
1770 .muxsel = { 2, 3, 1, 1}, // Tuner, CVid, SVid, CVid over SVid connector
1771 .gpiomask = 0,
1772 .no_tda9875 = 1,
1773 .no_tda7432 = 1,
1774 .tuner_type = 1,
1775 .has_radio = 1,
1776 .pll = PLL_28,
1777 /* Bt878, Bt832, FI1246 tuner; no pci subsystem id
1778 only internal line out: (4pin header) RGGL
1779 Radio must be decoded by msp3410d (not routed through)*/
1780 // .digital_mode = DIGITAL_MODE_CAMERA, // todo!
1781},{
1782 /* Chris Willing <chris@vislab.usyd.edu.au> */
1783 .name = "IVC-200",
1784 .video_inputs = 1,
1785 .audio_inputs = 0,
1786 .tuner = -1,
1787 .tuner_type = -1,
1788 .svhs = -1,
1789 .gpiomask = 0xdf,
1790 .muxsel = { 2 },
1791 .pll = PLL_28,
1792},{
1793 .name = "Grand X-Guard / Trust 814PCI",
1794 .video_inputs = 16,
1795 .audio_inputs = 0,
1796 .tuner = -1,
1797 .svhs = -1,
1798 .tuner_type = 4,
1799 .gpiomask2 = 0xff,
1800 .muxsel = { 2,2,2,2, 3,3,3,3, 1,1,1,1, 0,0,0,0 },
1801 .muxsel_hook = xguard_muxsel,
1802 .no_msp34xx = 1,
1803 .no_tda9875 = 1,
1804 .no_tda7432 = 1,
1805 .pll = PLL_28,
1806},{
1807
1808 /* ---- card 0x68 ---------------------------------- */
1809 .name = "Nebula Electronics DigiTV",
1810 .video_inputs = 1,
1811 .tuner = -1,
1812 .svhs = -1,
1813 .muxsel = { 2, 3, 1, 0},
1814 .no_msp34xx = 1,
1815 .no_tda9875 = 1,
1816 .no_tda7432 = 1,
1817 .pll = PLL_28,
1818 .tuner_type = -1,
1819 .has_dvb = 1,
1820 .no_gpioirq = 1,
1821},{
1822 /* Jorge Boncompte - DTI2 <jorge@dti2.net> */
1823 .name = "ProVideo PV143",
1824 .video_inputs = 4,
1825 .audio_inputs = 0,
1826 .tuner = -1,
1827 .svhs = -1,
1828 .gpiomask = 0,
1829 .muxsel = { 2, 3, 1, 0 },
1830 .audiomux = { 0 },
1831 .needs_tvaudio = 0,
1832 .no_msp34xx = 1,
1833 .pll = PLL_28,
1834 .tuner_type = -1,
1835},{
1836 /* M.Klahr@phytec.de */
1837 .name = "PHYTEC VD-009-X1 MiniDIN (bt878)",
1838 .video_inputs = 4,
1839 .audio_inputs = 0,
1840 .tuner = -1, /* card has no tuner */
1841 .svhs = 3,
1842 .gpiomask = 0x00,
1843 .muxsel = { 2, 3, 1, 0},
1844 .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */
1845 .needs_tvaudio = 1,
1846 .pll = PLL_28,
1847 .tuner_type = -1,
1848},{
1849 .name = "PHYTEC VD-009-X1 Combi (bt878)",
1850 .video_inputs = 4,
1851 .audio_inputs = 0,
1852 .tuner = -1, /* card has no tuner */
1853 .svhs = 3,
1854 .gpiomask = 0x00,
1855 .muxsel = { 2, 3, 1, 1},
1856 .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */
1857 .needs_tvaudio = 1,
1858 .pll = PLL_28,
1859 .tuner_type = -1,
1860},{
1861
1862 /* ---- card 0x6c ---------------------------------- */
1863 .name = "PHYTEC VD-009 MiniDIN (bt878)",
1864 .video_inputs = 10,
1865 .audio_inputs = 0,
1866 .tuner = -1, /* card has no tuner */
1867 .svhs = 9,
1868 .gpiomask = 0x00,
1869 .gpiomask2 = 0x03, /* gpiomask2 defines the bits used to switch audio
1870 via the upper nibble of muxsel. here: used for
1871 xternal video-mux */
1872 .muxsel = { 0x02, 0x12, 0x22, 0x32, 0x03, 0x13, 0x23, 0x33, 0x01, 0x00 },
1873 .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */
1874 .needs_tvaudio = 1,
1875 .pll = PLL_28,
1876 .tuner_type = -1,
1877},{
1878 .name = "PHYTEC VD-009 Combi (bt878)",
1879 .video_inputs = 10,
1880 .audio_inputs = 0,
1881 .tuner = -1, /* card has no tuner */
1882 .svhs = 9,
1883 .gpiomask = 0x00,
1884 .gpiomask2 = 0x03, /* gpiomask2 defines the bits used to switch audio
1885 via the upper nibble of muxsel. here: used for
1886 xternal video-mux */
1887 .muxsel = { 0x02, 0x12, 0x22, 0x32, 0x03, 0x13, 0x23, 0x33, 0x01, 0x01 },
1888 .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */
1889 .needs_tvaudio = 1,
1890 .pll = PLL_28,
1891 .tuner_type = -1,
1892},{
1893 .name = "IVC-100",
1894 .video_inputs = 4,
1895 .audio_inputs = 0,
1896 .tuner = -1,
1897 .tuner_type = -1,
1898 .svhs = -1,
1899 .gpiomask = 0xdf,
1900 .muxsel = { 2, 3, 1, 0 },
1901 .pll = PLL_28,
1902},{
1903 /* IVC-120G - Alan Garfield <alan@fromorbit.com> */
1904 .name = "IVC-120G",
1905 .video_inputs = 16,
1906 .audio_inputs = 0, /* card has no audio */
1907 .tuner = -1, /* card has no tuner */
1908 .tuner_type = -1,
1909 .svhs = -1, /* card has no svhs */
1910 .needs_tvaudio = 0,
1911 .no_msp34xx = 1,
1912 .no_tda9875 = 1,
1913 .no_tda7432 = 1,
1914 .gpiomask = 0x00,
1915 .muxsel = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
1916 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10 },
1917 .muxsel_hook = ivc120_muxsel,
1918 .pll = PLL_28,
1919},{
1920
1921 /* ---- card 0x70 ---------------------------------- */
1922 .name = "pcHDTV HD-2000 TV",
1923 .video_inputs = 4,
1924 .audio_inputs = 1,
1925 .tuner = 0,
1926 .svhs = 2,
1927 .muxsel = { 2, 3, 1, 0},
1928 .tuner_type = TUNER_PHILIPS_ATSC,
1929 .has_dvb = 1,
1930},{
1931 .name = "Twinhan DST + clones",
1932 .no_msp34xx = 1,
1933 .no_tda9875 = 1,
1934 .no_tda7432 = 1,
1935 .tuner_type = TUNER_ABSENT,
1936 .no_video = 1,
1937 .has_dvb = 1,
1938},{
1939 .name = "Winfast VC100",
1940 .video_inputs = 3,
1941 .audio_inputs = 0,
1942 .svhs = 1,
1943 .tuner = -1, // no tuner
1944 .muxsel = { 3, 1, 1, 3}, // Vid In, SVid In, Vid over SVid in connector
1945 .no_msp34xx = 1,
1946 .no_tda9875 = 1,
1947 .no_tda7432 = 1,
1948 .tuner_type = TUNER_ABSENT,
1949 .no_video = 1,
1950 .pll = PLL_28,
1951},{
1952 .name = "Teppro TEV-560/InterVision IV-560",
1953 .video_inputs = 3,
1954 .audio_inputs = 1,
1955 .tuner = 0,
1956 .svhs = 2,
1957 .gpiomask = 3,
1958 .muxsel = { 2, 3, 1, 1},
1959 .audiomux = { 1, 1, 1, 1, 0},
1960 .needs_tvaudio = 1,
1961 .tuner_type = TUNER_PHILIPS_PAL,
1962 .pll = PLL_35,
1963},{
1964
1965 /* ---- card 0x74 ---------------------------------- */
1966 .name = "SIMUS GVC1100",
1967 .video_inputs = 4,
1968 .audio_inputs = 0,
1969 .tuner = -1,
1970 .svhs = -1,
1971 .tuner_type = -1,
1972 .pll = PLL_28,
1973 .muxsel = { 2, 2, 2, 2},
1974 .gpiomask = 0x3F,
1975 .muxsel_hook = gvc1100_muxsel,
1976},{
1977 /* Carlos Silva r3pek@r3pek.homelinux.org || card 0x75 */
1978 .name = "NGS NGSTV+",
1979 .video_inputs = 3,
1980 .tuner = 0,
1981 .svhs = 2,
1982 .gpiomask = 0x008007,
1983 .muxsel = {2, 3, 0, 0},
1984 .audiomux = {0, 0, 0, 0, 0x000003, 0},
1985 .pll = PLL_28,
1986 .tuner_type = TUNER_PHILIPS_PAL,
1987 .has_remote = 1,
1988},{
1989 /* http://linuxmedialabs.com */
1990 .name = "LMLBT4",
1991 .video_inputs = 4, /* IN1,IN2,IN3,IN4 */
1992 .audio_inputs = 0,
1993 .tuner = -1,
1994 .svhs = -1,
1995 .muxsel = { 2, 3, 1, 0 },
1996 .no_msp34xx = 1,
1997 .no_tda9875 = 1,
1998 .no_tda7432 = 1,
1999 .needs_tvaudio = 0,
2000},{
2001 /* Helmroos Harri <harri.helmroos@pp.inet.fi> */
2002 .name = "Tekram M205 PRO",
2003 .video_inputs = 3,
2004 .audio_inputs = 1,
2005 .tuner = 0,
2006 .tuner_type = TUNER_PHILIPS_PAL,
2007 .svhs = 2,
2008 .needs_tvaudio = 0,
2009 .gpiomask = 0x68,
2010 .muxsel = { 2, 3, 1},
2011 .audiomux = { 0x68, 0x68, 0x61, 0x61, 0x00 },
2012 .pll = PLL_28,
2013},{
2014
2015 /* ---- card 0x78 ---------------------------------- */
2016 /* Javier Cendan Ares <jcendan@lycos.es> */
2017 /* bt878 TV + FM without subsystem ID */
2018 .name = "Conceptronic CONTVFMi",
2019 .video_inputs = 3,
2020 .audio_inputs = 1,
2021 .tuner = 0,
2022 .svhs = 2,
2023 .gpiomask = 0x008007,
2024 .muxsel = { 2, 3, 1, 1 },
2025 .audiomux = { 0, 1, 2, 2, 3 },
2026 .needs_tvaudio = 0,
2027 .pll = PLL_28,
2028 .tuner_type = TUNER_PHILIPS_PAL,
2029 .has_remote = 1,
2030 .has_radio = 1,
2031},{
2032 /*Eric DEBIEF <debief@telemsa.com>*/
2033 /*EURESYS Picolo Tetra : 4 Conexant Fusion 878A, no audio, video input set with analog multiplexers GPIO controled*/
2034 /* adds picolo_tetra_muxsel(), picolo_tetra_init(), the folowing declaration strucure, and #define BTTV_PICOLO_TETRA_CHIP*/
2035 /*0x79 in bttv.h*/
2036 .name = "Euresys Picolo Tetra",
2037 .video_inputs = 4,
2038 .audio_inputs = 0,
2039 .tuner = -1,
2040 .svhs = -1,
2041 .gpiomask = 0,
2042 .gpiomask2 = 0x3C<<16,/*Set the GPIO[18]->GPIO[21] as output pin.==> drive the video inputs through analog multiplexers*/
2043 .no_msp34xx = 1,
2044 .no_tda9875 = 1,
2045 .no_tda7432 = 1,
2046 .muxsel = {2,2,2,2},/*878A input is always MUX0, see above.*/
2047 .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */
2048 .pll = PLL_28,
2049 .needs_tvaudio = 0,
2050 .muxsel_hook = picolo_tetra_muxsel,/*Required as it doesn't follow the classic input selection policy*/
2051},{
2052 /* Spirit TV Tuner from http://spiritmodems.com.au */
2053 /* Stafford Goodsell <surge@goliath.homeunix.org> */
2054 .name = "Spirit TV Tuner",
2055 .video_inputs = 3,
2056 .audio_inputs = 1,
2057 .tuner = 0,
2058 .svhs = 2,
2059 .gpiomask = 0x0000000f,
2060 .muxsel = { 2, 1, 1 },
2061 .audiomux = { 0x02, 0x00, 0x00, 0x00, 0x00},
2062 .tuner_type = TUNER_TEMIC_PAL,
2063 .no_msp34xx = 1,
2064 .no_tda9875 = 1,
2065},{
2066 /* Wolfram Joost <wojo@frokaschwei.de> */
2067 .name = "AVerMedia AVerTV DVB-T 771",
2068 .video_inputs = 2,
2069 .svhs = 1,
2070 .tuner = -1,
2071 .tuner_type = TUNER_ABSENT,
2072 .muxsel = { 3 , 3 },
2073 .no_msp34xx = 1,
2074 .no_tda9875 = 1,
2075 .no_tda7432 = 1,
2076 .pll = PLL_28,
2077 .has_dvb = 1,
2078 .no_gpioirq = 1,
2079 .has_remote = 1,
2080},{
2081 /* ---- card 0x7c ---------------------------------- */
2082 /* Matt Jesson <dvb@jesson.eclipse.co.uk> */
2083 /* Based on the Nebula card data - added remote and new card number - BTTV_AVDVBT_761, see also ir-kbd-gpio.c */
2084 .name = "AverMedia AverTV DVB-T 761",
2085 .video_inputs = 2,
2086 .tuner = -1,
2087 .svhs = 1,
2088 .muxsel = { 3, 1, 2, 0}, /* Comp0, S-Video, ?, ? */
2089 .no_msp34xx = 1,
2090 .no_tda9875 = 1,
2091 .no_tda7432 = 1,
2092 .pll = PLL_28,
2093 .tuner_type = -1,
2094 .has_dvb = 1,
2095 .no_gpioirq = 1,
2096 .has_remote = 1,
2097},{
2098 /* andre.schwarz@matrix-vision.de */
2099 .name = "MATRIX Vision Sigma-SQ",
2100 .video_inputs = 16,
2101 .audio_inputs = 0,
2102 .tuner = -1,
2103 .svhs = -1,
2104 .gpiomask = 0x0,
2105 .muxsel = { 2, 2, 2, 2, 2, 2, 2, 2,
2106 3, 3, 3, 3, 3, 3, 3, 3 },
2107 .muxsel_hook = sigmaSQ_muxsel,
2108 .audiomux = { 0 },
2109 .no_msp34xx = 1,
2110 .pll = PLL_28,
2111 .tuner_type = -1,
2112},{
2113 /* andre.schwarz@matrix-vision.de */
2114 .name = "MATRIX Vision Sigma-SLC",
2115 .video_inputs = 4,
2116 .audio_inputs = 0,
2117 .tuner = -1,
2118 .svhs = -1,
2119 .gpiomask = 0x0,
2120 .muxsel = { 2, 2, 2, 2 },
2121 .muxsel_hook = sigmaSLC_muxsel,
2122 .audiomux = { 0 },
2123 .no_msp34xx = 1,
2124 .pll = PLL_28,
2125 .tuner_type = -1,
2126},{
2127 /* BTTV_APAC_VIEWCOMP */
2128 /* Attila Kondoros <attila.kondoros@chello.hu> */
2129 /* bt878 TV + FM 0x00000000 subsystem ID */
2130 .name = "APAC Viewcomp 878(AMAX)",
2131 .video_inputs = 2,
2132 .audio_inputs = 1,
2133 .tuner = 0,
2134 .svhs = -1,
2135 .gpiomask = 0xFF,
2136 .muxsel = { 2, 3, 1, 1},
2137 .audiomux = { 2, 0, 0, 0, 10},
2138 .needs_tvaudio = 0,
2139 .pll = PLL_28,
2140 .tuner_type = TUNER_PHILIPS_PAL,
2141 .has_remote = 1, /* miniremote works, see ir-kbd-gpio.c */
2142 .has_radio = 1, /* not every card has radio */
2143},{
2144
2145 /* ---- card 0x80 ---------------------------------- */
2146 /* Chris Pascoe <c.pascoe@itee.uq.edu.au> */
2147 .name = "DVICO FusionHDTV DVB-T Lite",
2148 .tuner = -1,
2149 .no_msp34xx = 1,
2150 .no_tda9875 = 1,
2151 .no_tda7432 = 1,
2152 .pll = PLL_28,
2153 .no_video = 1,
2154 .has_dvb = 1,
2155 .tuner_type = -1,
2156},{
2157 /* Steven <photon38@pchome.com.tw> */
2158 .name = "V-Gear MyVCD",
2159 .video_inputs = 3,
2160 .audio_inputs = 1,
2161 .tuner = 0,
2162 .svhs = 2,
2163 .gpiomask = 0x3f,
2164 .muxsel = {2, 3, 1, 0},
2165 .audiomux = {0x31, 0x31, 0x31, 0x31, 0x31, 0x31},
2166 .no_msp34xx = 1,
2167 .pll = PLL_28,
2168 .tuner_type = TUNER_PHILIPS_NTSC_M,
2169 .has_radio = 0,
2170 // .has_remote = 1,
2171},{
2172 /* Rick C <cryptdragoon@gmail.com> */
2173 .name = "Super TV Tuner",
2174 .video_inputs = 4,
2175 .audio_inputs = 1,
2176 .tuner = 0,
2177 .svhs = 2,
2178 .muxsel = { 2, 3, 1, 0},
2179 .tuner_type = TUNER_PHILIPS_NTSC,
2180 .gpiomask = 0x008007,
2181 .audiomux = { 0, 0x000001,0,0, 0},
2182 .needs_tvaudio = 1,
2183 .has_radio = 1,
2184},{
2185 /* Chris Fanning <video4linux@haydon.net> */
2186 .name = "Tibet Systems 'Progress DVR' CS16",
2187 .video_inputs = 16,
2188 .audio_inputs = 0,
2189 .tuner = -1,
2190 .svhs = -1,
2191 .muxsel = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
2192 .pll = PLL_28,
2193 .no_msp34xx = 1,
2194 .no_tda9875 = 1,
2195 .no_tda7432 = 1,
2196 .tuner_type = -1,
2197 .muxsel_hook = tibetCS16_muxsel,
2198},
2199{
2200 /* Bill Brack <wbrack@mmm.com.hk> */
2201 /*
2202 * Note that, because of the card's wiring, the "master"
2203 * BT878A chip (i.e. the one which controls the analog switch
2204 * and must use this card type) is the 2nd one detected. The
2205 * other 3 chips should use card type 0x85, whose description
2206 * follows this one. There is a EEPROM on the card (which is
2207 * connected to the I2C of one of those other chips), but is
2208 * not currently handled. There is also a facility for a
2209 * "monitor", which is also not currently implemented.
2210 */
2211 .name = "Kodicom 4400R (master)",
2212 .video_inputs = 16,
2213 .audio_inputs = 0,
2214 .tuner = -1,
2215 .tuner_type = -1,
2216 .svhs = -1,
2217 /* GPIO bits 0-9 used for analog switch:
2218 * 00 - 03: camera selector
2219 * 04 - 06: channel (controller) selector
2220 * 07: data (1->on, 0->off)
2221 * 08: strobe
2222 * 09: reset
2223 * bit 16 is input from sync separator for the channel
2224 */
2225 .gpiomask = 0x0003ff,
2226 .no_gpioirq = 1,
2227 .muxsel = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
2228 .pll = PLL_28,
2229 .no_msp34xx = 1,
2230 .no_tda7432 = 1,
2231 .no_tda9875 = 1,
2232 .muxsel_hook = kodicom4400r_muxsel,
2233},
2234{
2235 /* Bill Brack <wbrack@mmm.com.hk> */
2236 /* Note that, for reasons unknown, the "master" BT878A chip (i.e. the
2237 * one which controls the analog switch, and must use the card type)
2238 * is the 2nd one detected. The other 3 chips should use this card
2239 * type
2240 */
2241 .name = "Kodicom 4400R (slave)",
2242 .video_inputs = 16,
2243 .audio_inputs = 0,
2244 .tuner = -1,
2245 .tuner_type = -1,
2246 .svhs = -1,
2247 .gpiomask = 0x010000,
2248 .no_gpioirq = 1,
2249 .muxsel = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
2250 .pll = PLL_28,
2251 .no_msp34xx = 1,
2252 .no_tda7432 = 1,
2253 .no_tda9875 = 1,
2254 .muxsel_hook = kodicom4400r_muxsel,
2255}};
2256
2257static const unsigned int bttv_num_tvcards = ARRAY_SIZE(bttv_tvcards);
2258
2259/* ----------------------------------------------------------------------- */
2260
2261static unsigned char eeprom_data[256];
2262
2263/*
2264 * identify card
2265 */
2266void __devinit bttv_idcard(struct bttv *btv)
2267{
2268 unsigned int gpiobits;
2269 int i,type;
2270 unsigned short tmp;
2271
2272 /* read PCI subsystem ID */
2273 pci_read_config_word(btv->c.pci, PCI_SUBSYSTEM_ID, &tmp);
2274 btv->cardid = tmp << 16;
2275 pci_read_config_word(btv->c.pci, PCI_SUBSYSTEM_VENDOR_ID, &tmp);
2276 btv->cardid |= tmp;
2277
2278 if (0 != btv->cardid && 0xffffffff != btv->cardid) {
2279 /* look for the card */
2280 for (type = -1, i = 0; cards[i].id != 0; i++)
2281 if (cards[i].id == btv->cardid)
2282 type = i;
2283
2284 if (type != -1) {
2285 /* found it */
2286 printk(KERN_INFO "bttv%d: detected: %s [card=%d], "
2287 "PCI subsystem ID is %04x:%04x\n",
2288 btv->c.nr,cards[type].name,cards[type].cardnr,
2289 btv->cardid & 0xffff,
2290 (btv->cardid >> 16) & 0xffff);
2291 btv->c.type = cards[type].cardnr;
2292 } else {
2293 /* 404 */
2294 printk(KERN_INFO "bttv%d: subsystem: %04x:%04x (UNKNOWN)\n",
2295 btv->c.nr, btv->cardid & 0xffff,
2296 (btv->cardid >> 16) & 0xffff);
2297 printk(KERN_DEBUG "please mail id, board name and "
2298 "the correct card= insmod option to kraxel@bytesex.org\n");
2299 }
2300 }
2301
2302 /* let the user override the autodetected type */
2303 if (card[btv->c.nr] < bttv_num_tvcards)
2304 btv->c.type=card[btv->c.nr];
2305
2306 /* print which card config we are using */
2307 printk(KERN_INFO "bttv%d: using: %s [card=%d,%s]\n",btv->c.nr,
2308 bttv_tvcards[btv->c.type].name, btv->c.type,
2309 card[btv->c.nr] < bttv_num_tvcards
2310 ? "insmod option" : "autodetected");
2311
2312 /* overwrite gpio stuff ?? */
2313 if (UNSET == audioall && UNSET == audiomux[0])
2314 return;
2315
2316 if (UNSET != audiomux[0]) {
2317 gpiobits = 0;
2318 for (i = 0; i < 5; i++) {
2319 bttv_tvcards[btv->c.type].audiomux[i] = audiomux[i];
2320 gpiobits |= audiomux[i];
2321 }
2322 } else {
2323 gpiobits = audioall;
2324 for (i = 0; i < 5; i++) {
2325 bttv_tvcards[btv->c.type].audiomux[i] = audioall;
2326 }
2327 }
2328 bttv_tvcards[btv->c.type].gpiomask = (UNSET != gpiomask) ? gpiomask : gpiobits;
2329 printk(KERN_INFO "bttv%d: gpio config override: mask=0x%x, mux=",
2330 btv->c.nr,bttv_tvcards[btv->c.type].gpiomask);
2331 for (i = 0; i < 5; i++) {
2332 printk("%s0x%x", i ? "," : "", bttv_tvcards[btv->c.type].audiomux[i]);
2333 }
2334 printk("\n");
2335}
2336
2337/*
2338 * (most) board specific initialisations goes here
2339 */
2340
2341/* Some Modular Technology cards have an eeprom, but no subsystem ID */
2342void identify_by_eeprom(struct bttv *btv, unsigned char eeprom_data[256])
2343{
2344 int type = -1;
2345
2346 if (0 == strncmp(eeprom_data,"GET MM20xPCTV",13))
2347 type = BTTV_MODTEC_205;
2348 else if (0 == strncmp(eeprom_data+20,"Picolo",7))
2349 type = BTTV_EURESYS_PICOLO;
2350 else if (eeprom_data[0] == 0x84 && eeprom_data[2]== 0)
2351 type = BTTV_HAUPPAUGE; /* old bt848 */
2352
2353 if (-1 != type) {
2354 btv->c.type = type;
2355 printk("bttv%d: detected by eeprom: %s [card=%d]\n",
2356 btv->c.nr, bttv_tvcards[btv->c.type].name, btv->c.type);
2357 }
2358}
2359
2360static void flyvideo_gpio(struct bttv *btv)
2361{
2362 int gpio,has_remote,has_radio,is_capture_only,is_lr90,has_tda9820_tda9821;
2363 int tuner=-1,ttype;
2364
2365 gpio_inout(0xffffff, 0);
2366 udelay(8); // without this we would see the 0x1800 mask
2367 gpio = gpio_read();
2368 /* FIXME: must restore OUR_EN ??? */
2369
2370 // all cards provide GPIO info, some have an additional eeprom
2371 // LR50: GPIO coding can be found lower right CP1 .. CP9
2372 // CP9=GPIO23 .. CP1=GPIO15; when OPEN, the corresponding GPIO reads 1.
2373 // GPIO14-12: n.c.
2374 // LR90: GP9=GPIO23 .. GP1=GPIO15 (right above the bt878)
2375
2376 // lowest 3 bytes are remote control codes (no handshake needed)
2377 // xxxFFF: No remote control chip soldered
2378 // xxxF00(LR26/LR50), xxxFE0(LR90): Remote control chip (LVA001 or CF45) soldered
2379 // Note: Some bits are Audio_Mask !
2380
2381 ttype=(gpio&0x0f0000)>>16;
2382 switch(ttype) {
2383 case 0x0: tuner=2; // NTSC, e.g. TPI8NSR11P
2384 break;
2385 case 0x2: tuner=39;// LG NTSC (newer TAPC series) TAPC-H701P
2386 break;
2387 case 0x4: tuner=5; // Philips PAL TPI8PSB02P, TPI8PSB12P, TPI8PSB12D or FI1216, FM1216
2388 break;
2389 case 0x6: tuner=37; // LG PAL (newer TAPC series) TAPC-G702P
2390 break;
2391 case 0xC: tuner=3; // Philips SECAM(+PAL) FQ1216ME or FI1216MF
2392 break;
2393 default:
2394 printk(KERN_INFO "bttv%d: FlyVideo_gpio: unknown tuner type.\n", btv->c.nr);
2395 }
2396
2397 has_remote = gpio & 0x800000;
2398 has_radio = gpio & 0x400000;
2399 // unknown 0x200000;
2400 // unknown2 0x100000;
2401 is_capture_only = !(gpio & 0x008000); //GPIO15
2402 has_tda9820_tda9821 = !(gpio & 0x004000);
2403 is_lr90 = !(gpio & 0x002000); // else LR26/LR50 (LR38/LR51 f. capture only)
2404 // gpio & 0x001000 // output bit for audio routing
2405
2406 if(is_capture_only)
2407 tuner=4; // No tuner present
2408
2409 printk(KERN_INFO "bttv%d: FlyVideo Radio=%s RemoteControl=%s Tuner=%d gpio=0x%06x\n",
2410 btv->c.nr, has_radio? "yes":"no ", has_remote? "yes":"no ", tuner, gpio);
2411 printk(KERN_INFO "bttv%d: FlyVideo LR90=%s tda9821/tda9820=%s capture_only=%s\n",
2412 btv->c.nr, is_lr90?"yes":"no ", has_tda9820_tda9821?"yes":"no ",
2413 is_capture_only?"yes":"no ");
2414
2415 if(tuner!= -1) // only set if known tuner autodetected, else let insmod option through
2416 btv->tuner_type = tuner;
2417 btv->has_radio = has_radio;
2418
2419 // LR90 Audio Routing is done by 2 hef4052, so Audio_Mask has 4 bits: 0x001c80
2420 // LR26/LR50 only has 1 hef4052, Audio_Mask 0x000c00
2421 // Audio options: from tuner, from tda9821/tda9821(mono,stereo,sap), from tda9874, ext., mute
2422 if(has_tda9820_tda9821) btv->audio_hook = lt9415_audio;
2423 //todo: if(has_tda9874) btv->audio_hook = fv2000s_audio;
2424}
2425
2426static int miro_tunermap[] = { 0,6,2,3, 4,5,6,0, 3,0,4,5, 5,2,16,1,
2427 14,2,17,1, 4,1,4,3, 1,2,16,1, 4,4,4,4 };
2428static int miro_fmtuner[] = { 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,1,
2429 1,1,1,1, 1,1,1,0, 0,0,0,0, 0,1,0,0 };
2430
2431static void miro_pinnacle_gpio(struct bttv *btv)
2432{
2433 int id,msp,gpio;
2434 char *info;
2435
2436 gpio_inout(0xffffff, 0);
2437 gpio = gpio_read();
2438 id = ((gpio>>10) & 63) -1;
2439 msp = bttv_I2CRead(btv, I2C_MSP3400, "MSP34xx");
2440 if (id < 32) {
2441 btv->tuner_type = miro_tunermap[id];
2442 if (0 == (gpio & 0x20)) {
2443 btv->has_radio = 1;
2444 if (!miro_fmtuner[id]) {
2445 btv->has_matchbox = 1;
2446 btv->mbox_we = (1<<6);
2447 btv->mbox_most = (1<<7);
2448 btv->mbox_clk = (1<<8);
2449 btv->mbox_data = (1<<9);
2450 btv->mbox_mask = (1<<6)|(1<<7)|(1<<8)|(1<<9);
2451 }
2452 } else {
2453 btv->has_radio = 0;
2454 }
2455 if (-1 != msp) {
2456 if (btv->c.type == BTTV_MIRO)
2457 btv->c.type = BTTV_MIROPRO;
2458 if (btv->c.type == BTTV_PINNACLE)
2459 btv->c.type = BTTV_PINNACLEPRO;
2460 }
2461 printk(KERN_INFO
2462 "bttv%d: miro: id=%d tuner=%d radio=%s stereo=%s\n",
2463 btv->c.nr, id+1, btv->tuner_type,
2464 !btv->has_radio ? "no" :
2465 (btv->has_matchbox ? "matchbox" : "fmtuner"),
2466 (-1 == msp) ? "no" : "yes");
2467 } else {
2468 /* new cards with microtune tuner */
2469 id = 63 - id;
2470 btv->has_radio = 0;
2471 switch (id) {
2472 case 1:
2473 info = "PAL / mono";
2474 break;
2475 case 2:
2476 info = "PAL+SECAM / stereo";
2477 btv->has_radio = 1;
2478 break;
2479 case 3:
2480 info = "NTSC / stereo";
2481 btv->has_radio = 1;
2482 break;
2483 case 4:
2484 info = "PAL+SECAM / mono";
2485 break;
2486 case 5:
2487 info = "NTSC / mono";
2488 break;
2489 case 6:
2490 info = "NTSC / stereo";
2491 break;
2492 case 7:
2493 info = "PAL / stereo";
2494 break;
2495 default:
2496 info = "oops: unknown card";
2497 break;
2498 }
2499 if (-1 != msp)
2500 btv->c.type = BTTV_PINNACLEPRO;
2501 printk(KERN_INFO
2502 "bttv%d: pinnacle/mt: id=%d info=\"%s\" radio=%s\n",
2503 btv->c.nr, id, info, btv->has_radio ? "yes" : "no");
2504 btv->tuner_type = 33;
2505 btv->pinnacle_id = id;
2506 }
2507}
2508
2509/* GPIO21 L: Buffer aktiv, H: Buffer inaktiv */
2510#define LM1882_SYNC_DRIVE 0x200000L
2511
2512static void init_ids_eagle(struct bttv *btv)
2513{
2514 gpio_inout(0xffffff,0xFFFF37);
2515 gpio_write(0x200020);
2516
2517 /* flash strobe inverter ?! */
2518 gpio_write(0x200024);
2519
2520 /* switch sync drive off */
2521 gpio_bits(LM1882_SYNC_DRIVE,LM1882_SYNC_DRIVE);
2522
2523 /* set BT848 muxel to 2 */
2524 btaor((2)<<5, ~(2<<5), BT848_IFORM);
2525}
2526
2527/* Muxsel helper for the IDS Eagle.
2528 * the eagles does not use the standard muxsel-bits but
2529 * has its own multiplexer */
2530static void eagle_muxsel(struct bttv *btv, unsigned int input)
2531{
2532 btaor((2)<<5, ~(3<<5), BT848_IFORM);
2533 gpio_bits(3,bttv_tvcards[btv->c.type].muxsel[input&7]);
2534
2535#if 0
2536 /* svhs */
2537 /* wake chroma ADC */
2538 btand(~BT848_ADC_C_SLEEP, BT848_ADC);
2539 /* set to YC video */
2540 btor(BT848_CONTROL_COMP, BT848_E_CONTROL);
2541 btor(BT848_CONTROL_COMP, BT848_O_CONTROL);
2542#else
2543 /* composite */
2544 /* set chroma ADC to sleep */
2545 btor(BT848_ADC_C_SLEEP, BT848_ADC);
2546 /* set to composite video */
2547 btand(~BT848_CONTROL_COMP, BT848_E_CONTROL);
2548 btand(~BT848_CONTROL_COMP, BT848_O_CONTROL);
2549#endif
2550
2551 /* switch sync drive off */
2552 gpio_bits(LM1882_SYNC_DRIVE,LM1882_SYNC_DRIVE);
2553}
2554
2555static void gvc1100_muxsel(struct bttv *btv, unsigned int input)
2556{
2557 static const int masks[] = {0x30, 0x01, 0x12, 0x23};
2558 gpio_write(masks[input%4]);
2559}
2560
2561/* LMLBT4x initialization - to allow access to GPIO bits for sensors input and
2562 alarms output
2563
2564 GPIObit | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
2565 assignment | TI | O3|INx| O2| O1|IN4|IN3|IN2|IN1| | |
2566
2567 IN - sensor inputs, INx - sensor inputs and TI XORed together
2568 O1,O2,O3 - alarm outputs (relays)
2569
2570 OUT ENABLE 1 1 0 . 1 1 0 0 . 0 0 0 0 = 0x6C0
2571
2572*/
2573
2574static void init_lmlbt4x(struct bttv *btv)
2575{
2576 printk(KERN_DEBUG "LMLBT4x init\n");
2577 btwrite(0x000000, BT848_GPIO_REG_INP);
2578 gpio_inout(0xffffff, 0x0006C0);
2579 gpio_write(0x000000);
2580}
2581
2582static void sigmaSQ_muxsel(struct bttv *btv, unsigned int input)
2583{
2584 unsigned int inmux = input % 8;
2585 gpio_inout( 0xf, 0xf );
2586 gpio_bits( 0xf, inmux );
2587}
2588
2589static void sigmaSLC_muxsel(struct bttv *btv, unsigned int input)
2590{
2591 unsigned int inmux = input % 4;
2592 gpio_inout( 3<<9, 3<<9 );
2593 gpio_bits( 3<<9, inmux<<9 );
2594}
2595
2596/* ----------------------------------------------------------------------- */
2597
2598static void bttv_reset_audio(struct bttv *btv)
2599{
2600 /*
2601 * BT878A has a audio-reset register.
2602 * 1. This register is an audio reset function but it is in
2603 * function-0 (video capture) address space.
2604 * 2. It is enough to do this once per power-up of the card.
2605 * 3. There is a typo in the Conexant doc -- it is not at
2606 * 0x5B, but at 0x058. (B is an odd-number, obviously a typo!).
2607 * --//Shrikumar 030609
2608 */
2609 if (btv->id != 878)
2610 return;
2611
2612 if (bttv_debug)
2613 printk("bttv%d: BT878A ARESET\n",btv->c.nr);
2614 btwrite((1<<7), 0x058);
2615 udelay(10);
2616 btwrite( 0, 0x058);
2617}
2618
2619/* initialization part one -- before registering i2c bus */
2620void __devinit bttv_init_card1(struct bttv *btv)
2621{
2622 switch (btv->c.type) {
2623 case BTTV_HAUPPAUGE:
2624 case BTTV_HAUPPAUGE878:
2625 boot_msp34xx(btv,5);
2626 break;
2627 case BTTV_VOODOOTV_FM:
2628 boot_msp34xx(btv,20);
2629 break;
2630 case BTTV_AVERMEDIA98:
2631 boot_msp34xx(btv,11);
2632 break;
2633 case BTTV_HAUPPAUGEPVR:
2634 pvr_boot(btv);
2635 break;
2636 case BTTV_TWINHAN_DST:
2637 case BTTV_AVDVBT_771:
2638 btv->use_i2c_hw = 1;
2639 break;
2640 }
2641 if (!bttv_tvcards[btv->c.type].has_dvb)
2642 bttv_reset_audio(btv);
2643}
2644
2645/* initialization part two -- after registering i2c bus */
2646void __devinit bttv_init_card2(struct bttv *btv)
2647{
2648 int tda9887;
2649 btv->tuner_type = -1;
2650
2651 if (BTTV_UNKNOWN == btv->c.type) {
2652 bttv_readee(btv,eeprom_data,0xa0);
2653 identify_by_eeprom(btv,eeprom_data);
2654 }
2655
2656 switch (btv->c.type) {
2657 case BTTV_MIRO:
2658 case BTTV_MIROPRO:
2659 case BTTV_PINNACLE:
2660 case BTTV_PINNACLEPRO:
2661 /* miro/pinnacle */
2662 miro_pinnacle_gpio(btv);
2663 break;
2664 case BTTV_FLYVIDEO_98:
2665 case BTTV_MAXI:
2666 case BTTV_LIFE_FLYKIT:
2667 case BTTV_FLYVIDEO:
2668 case BTTV_TYPHOON_TVIEW:
2669 case BTTV_CHRONOS_VS2:
2670 case BTTV_FLYVIDEO_98FM:
2671 case BTTV_FLYVIDEO2000:
2672 case BTTV_FLYVIDEO98EZ:
2673 case BTTV_CONFERENCETV:
2674 case BTTV_LIFETEC_9415:
2675 flyvideo_gpio(btv);
2676 break;
2677 case BTTV_HAUPPAUGE:
2678 case BTTV_HAUPPAUGE878:
2679 case BTTV_HAUPPAUGEPVR:
2680 /* pick up some config infos from the eeprom */
2681 bttv_readee(btv,eeprom_data,0xa0);
2682 hauppauge_eeprom(btv);
2683 break;
2684 case BTTV_AVERMEDIA98:
2685 case BTTV_AVPHONE98:
2686 bttv_readee(btv,eeprom_data,0xa0);
2687 avermedia_eeprom(btv);
2688 break;
2689 case BTTV_PXC200:
2690 init_PXC200(btv);
2691 break;
2692 case BTTV_PICOLO_TETRA_CHIP:
2693 picolo_tetra_init(btv);
2694 break;
2695 case BTTV_VHX:
2696 btv->has_radio = 1;
2697 btv->has_matchbox = 1;
2698 btv->mbox_we = 0x20;
2699 btv->mbox_most = 0;
2700 btv->mbox_clk = 0x08;
2701 btv->mbox_data = 0x10;
2702 btv->mbox_mask = 0x38;
2703 break;
2704 case BTTV_VOBIS_BOOSTAR:
2705 case BTTV_TERRATV:
2706 terratec_active_radio_upgrade(btv);
2707 break;
2708 case BTTV_MAGICTVIEW061:
2709 if (btv->cardid == 0x3002144f) {
2710 btv->has_radio=1;
2711 printk("bttv%d: radio detected by subsystem id (CPH05x)\n",btv->c.nr);
2712 }
2713 break;
2714 case BTTV_STB2:
2715 if (btv->cardid == 0x3060121a) {
2716 /* Fix up entry for 3DFX VoodooTV 100,
2717 which is an OEM STB card variant. */
2718 btv->has_radio=0;
2719 btv->tuner_type=TUNER_TEMIC_NTSC;
2720 }
2721 break;
2722 case BTTV_OSPREY1x0:
2723 case BTTV_OSPREY1x0_848:
2724 case BTTV_OSPREY101_848:
2725 case BTTV_OSPREY1x1:
2726 case BTTV_OSPREY1x1_SVID:
2727 case BTTV_OSPREY2xx:
2728 case BTTV_OSPREY2x0_SVID:
2729 case BTTV_OSPREY2x0:
2730 case BTTV_OSPREY500:
2731 case BTTV_OSPREY540:
2732 case BTTV_OSPREY2000:
2733 bttv_readee(btv,eeprom_data,0xa0);
2734 osprey_eeprom(btv);
2735 break;
2736 case BTTV_IDS_EAGLE:
2737 init_ids_eagle(btv);
2738 break;
2739 case BTTV_MODTEC_205:
2740 bttv_readee(btv,eeprom_data,0xa0);
2741 modtec_eeprom(btv);
2742 break;
2743 case BTTV_LMLBT4:
2744 init_lmlbt4x(btv);
2745 break;
2746 case BTTV_TIBET_CS16:
2747 tibetCS16_init(btv);
2748 break;
2749 case BTTV_KODICOM_4400R:
2750 kodicom4400r_init(btv);
2751 break;
2752 }
2753
2754 /* pll configuration */
2755 if (!(btv->id==848 && btv->revision==0x11)) {
2756 /* defaults from card list */
2757 if (PLL_28 == bttv_tvcards[btv->c.type].pll) {
2758 btv->pll.pll_ifreq=28636363;
2759 btv->pll.pll_crystal=BT848_IFORM_XT0;
2760 }
2761 if (PLL_35 == bttv_tvcards[btv->c.type].pll) {
2762 btv->pll.pll_ifreq=35468950;
2763 btv->pll.pll_crystal=BT848_IFORM_XT1;
2764 }
2765 /* insmod options can override */
2766 switch (pll[btv->c.nr]) {
2767 case 0: /* none */
2768 btv->pll.pll_crystal = 0;
2769 btv->pll.pll_ifreq = 0;
2770 btv->pll.pll_ofreq = 0;
2771 break;
2772 case 1: /* 28 MHz */
2773 case 28:
2774 btv->pll.pll_ifreq = 28636363;
2775 btv->pll.pll_ofreq = 0;
2776 btv->pll.pll_crystal = BT848_IFORM_XT0;
2777 break;
2778 case 2: /* 35 MHz */
2779 case 35:
2780 btv->pll.pll_ifreq = 35468950;
2781 btv->pll.pll_ofreq = 0;
2782 btv->pll.pll_crystal = BT848_IFORM_XT1;
2783 break;
2784 }
2785 }
2786 btv->pll.pll_current = -1;
2787
2788 bttv_reset_audio(btv);
2789
2790 /* tuner configuration (from card list / autodetect / insmod option) */
2791 if (UNSET != bttv_tvcards[btv->c.type].tuner_type)
2792 if(UNSET == btv->tuner_type)
2793 btv->tuner_type = bttv_tvcards[btv->c.type].tuner_type;
2794 if (UNSET != tuner[btv->c.nr])
2795 btv->tuner_type = tuner[btv->c.nr];
2796 printk("bttv%d: using tuner=%d\n",btv->c.nr,btv->tuner_type);
2797 if (btv->pinnacle_id != UNSET)
2798 bttv_call_i2c_clients(btv,AUDC_CONFIG_PINNACLE,
2799 &btv->pinnacle_id);
2800 if (btv->tuner_type != UNSET)
2801 bttv_call_i2c_clients(btv,TUNER_SET_TYPE,&btv->tuner_type);
2802 btv->svhs = bttv_tvcards[btv->c.type].svhs;
2803 if (svhs[btv->c.nr] != UNSET)
2804 btv->svhs = svhs[btv->c.nr];
2805 if (remote[btv->c.nr] != UNSET)
2806 btv->has_remote = remote[btv->c.nr];
2807
2808 if (bttv_tvcards[btv->c.type].has_radio)
2809 btv->has_radio=1;
2810 if (bttv_tvcards[btv->c.type].has_remote)
2811 btv->has_remote=1;
2812 if (bttv_tvcards[btv->c.type].no_gpioirq)
2813 btv->gpioirq=0;
2814 if (bttv_tvcards[btv->c.type].audio_hook)
2815 btv->audio_hook=bttv_tvcards[btv->c.type].audio_hook;
2816
2817 if (bttv_tvcards[btv->c.type].digital_mode == DIGITAL_MODE_CAMERA) {
2818 /* detect Bt832 chip for quartzsight digital camera */
2819 if ((bttv_I2CRead(btv, I2C_BT832_ALT1, "Bt832") >=0) ||
2820 (bttv_I2CRead(btv, I2C_BT832_ALT2, "Bt832") >=0))
2821 boot_bt832(btv);
2822 }
2823
2824 if (!autoload)
2825 return;
2826
2827 /* try to detect audio/fader chips */
2828 if (!bttv_tvcards[btv->c.type].no_msp34xx &&
2829 bttv_I2CRead(btv, I2C_MSP3400, "MSP34xx") >=0)
2830 request_module("msp3400");
2831
2832 if (bttv_tvcards[btv->c.type].msp34xx_alt &&
2833 bttv_I2CRead(btv, I2C_MSP3400_ALT, "MSP34xx (alternate address)") >=0)
2834 request_module("msp3400");
2835
2836 if (!bttv_tvcards[btv->c.type].no_tda9875 &&
2837 bttv_I2CRead(btv, I2C_TDA9875, "TDA9875") >=0)
2838 request_module("tda9875");
2839
2840 if (!bttv_tvcards[btv->c.type].no_tda7432 &&
2841 bttv_I2CRead(btv, I2C_TDA7432, "TDA7432") >=0)
2842 request_module("tda7432");
2843
2844 if (bttv_tvcards[btv->c.type].needs_tvaudio)
2845 request_module("tvaudio");
2846
2847 /* tuner modules */
2848 tda9887 = 0;
2849 if (btv->pinnacle_id != UNSET)
2850 tda9887 = 1;
2851 if (0 == tda9887 && 0 == bttv_tvcards[btv->c.type].has_dvb &&
2852 bttv_I2CRead(btv, I2C_TDA9887, "TDA9887") >=0)
2853 tda9887 = 1;
2854 if((btv->tuner_type == TUNER_PHILIPS_FM1216ME_MK3) ||
2855 (btv->tuner_type == TUNER_PHILIPS_FM1236_MK3) ||
2856 (btv->tuner_type == TUNER_PHILIPS_FM1256_IH3) ||
2857 tda9887)
2858 request_module("tda9887");
2859 if (btv->tuner_type != UNSET)
2860 request_module("tuner");
2861}
2862
2863
2864/* ----------------------------------------------------------------------- */
2865
2866static void modtec_eeprom(struct bttv *btv)
2867{
2868 if( strncmp(&(eeprom_data[0x1e]),"Temic 4066 FY5",14) ==0) {
2869 btv->tuner_type=TUNER_TEMIC_4066FY5_PAL_I;
2870 printk("bttv%d: Modtec: Tuner autodetected by eeprom: %s\n",
2871 btv->c.nr,&eeprom_data[0x1e]);
2872 } else if (strncmp(&(eeprom_data[0x1e]),"Alps TSBB5",10) ==0) {
2873 btv->tuner_type=TUNER_ALPS_TSBB5_PAL_I;
2874 printk("bttv%d: Modtec: Tuner autodetected by eeprom: %s\n",
2875 btv->c.nr,&eeprom_data[0x1e]);
2876 } else if (strncmp(&(eeprom_data[0x1e]),"Philips FM1246",14) ==0) {
2877 btv->tuner_type=TUNER_PHILIPS_NTSC;
2878 printk("bttv%d: Modtec: Tuner autodetected by eeprom: %s\n",
2879 btv->c.nr,&eeprom_data[0x1e]);
2880 } else {
2881 printk("bttv%d: Modtec: Unknown TunerString: %s\n",
2882 btv->c.nr,&eeprom_data[0x1e]);
2883 }
2884}
2885
2886static void __devinit hauppauge_eeprom(struct bttv *btv)
2887{
2888 struct tveeprom tv;
2889
2890 tveeprom_hauppauge_analog(&tv, eeprom_data);
2891 btv->tuner_type = tv.tuner_type;
2892 btv->has_radio = tv.has_radio;
2893}
2894
2895static int terratec_active_radio_upgrade(struct bttv *btv)
2896{
2897 int freq;
2898
2899 btv->has_radio = 1;
2900 btv->has_matchbox = 1;
2901 btv->mbox_we = 0x10;
2902 btv->mbox_most = 0x20;
2903 btv->mbox_clk = 0x08;
2904 btv->mbox_data = 0x04;
2905 btv->mbox_mask = 0x3c;
2906
2907 btv->mbox_iow = 1 << 8;
2908 btv->mbox_ior = 1 << 9;
2909 btv->mbox_csel = 1 << 10;
2910
2911 freq=88000/62.5;
2912 tea5757_write(btv, 5 * freq + 0x358); // write 0x1ed8
2913 if (0x1ed8 == tea5757_read(btv)) {
2914 printk("bttv%d: Terratec Active Radio Upgrade found.\n",
2915 btv->c.nr);
2916 btv->has_radio = 1;
2917 btv->has_matchbox = 1;
2918 } else {
2919 btv->has_radio = 0;
2920 btv->has_matchbox = 0;
2921 }
2922 return 0;
2923}
2924
2925
2926/* ----------------------------------------------------------------------- */
2927
2928/*
2929 * minimal bootstrap for the WinTV/PVR -- upload altera firmware.
2930 *
2931 * The hcwamc.rbf firmware file is on the Hauppauge driver CD. Have
2932 * a look at Pvr/pvr45xxx.EXE (self-extracting zip archive, can be
2933 * unpacked with unzip).
2934 */
2935#define PVR_GPIO_DELAY 10
2936
2937#define BTTV_ALT_DATA 0x000001
2938#define BTTV_ALT_DCLK 0x100000
2939#define BTTV_ALT_NCONFIG 0x800000
2940
2941static int __devinit pvr_altera_load(struct bttv *btv, u8 *micro, u32 microlen)
2942{
2943 u32 n;
2944 u8 bits;
2945 int i;
2946
2947 gpio_inout(0xffffff,BTTV_ALT_DATA|BTTV_ALT_DCLK|BTTV_ALT_NCONFIG);
2948 gpio_write(0);
2949 udelay(PVR_GPIO_DELAY);
2950
2951 gpio_write(BTTV_ALT_NCONFIG);
2952 udelay(PVR_GPIO_DELAY);
2953
2954 for (n = 0; n < microlen; n++) {
2955 bits = micro[n];
2956 for ( i = 0 ; i < 8 ; i++ ) {
2957 gpio_bits(BTTV_ALT_DCLK,0);
2958 if (bits & 0x01)
2959 gpio_bits(BTTV_ALT_DATA,BTTV_ALT_DATA);
2960 else
2961 gpio_bits(BTTV_ALT_DATA,0);
2962 gpio_bits(BTTV_ALT_DCLK,BTTV_ALT_DCLK);
2963 bits >>= 1;
2964 }
2965 }
2966 gpio_bits(BTTV_ALT_DCLK,0);
2967 udelay(PVR_GPIO_DELAY);
2968
2969 /* begin Altera init loop (Not necessary,but doesn't hurt) */
2970 for (i = 0 ; i < 30 ; i++) {
2971 gpio_bits(BTTV_ALT_DCLK,0);
2972 gpio_bits(BTTV_ALT_DCLK,BTTV_ALT_DCLK);
2973 }
2974 gpio_bits(BTTV_ALT_DCLK,0);
2975 return 0;
2976}
2977
2978static int __devinit pvr_boot(struct bttv *btv)
2979{
2980 const struct firmware *fw_entry;
2981 int rc;
2982
2983 rc = request_firmware(&fw_entry, "hcwamc.rbf", &btv->c.pci->dev);
2984 if (rc != 0) {
2985 printk(KERN_WARNING "bttv%d: no altera firmware [via hotplug]\n",
2986 btv->c.nr);
2987 return rc;
2988 }
2989 rc = pvr_altera_load(btv, fw_entry->data, fw_entry->size);
2990 printk(KERN_INFO "bttv%d: altera firmware upload %s\n",
2991 btv->c.nr, (rc < 0) ? "failed" : "ok");
2992 release_firmware(fw_entry);
2993 return rc;
2994}
2995
2996/* ----------------------------------------------------------------------- */
2997/* some osprey specific stuff */
2998
2999static void __devinit osprey_eeprom(struct bttv *btv)
3000{
3001 int i = 0;
3002 unsigned char *ee = eeprom_data;
3003 unsigned long serial = 0;
3004
3005 if (btv->c.type == 0) {
3006 /* this might be an antique... check for MMAC label in eeprom */
3007 if ((ee[0]=='M') && (ee[1]=='M') && (ee[2]=='A') && (ee[3]=='C')) {
3008 unsigned char checksum = 0;
3009 for (i =0; i<21; i++)
3010 checksum += ee[i];
3011 if (checksum != ee[21])
3012 return;
3013 btv->c.type = BTTV_OSPREY1x0_848;
3014 for (i = 12; i < 21; i++)
3015 serial *= 10, serial += ee[i] - '0';
3016 }
3017 } else {
3018 unsigned short type;
3019 int offset = 4*16;
3020
3021 for(; offset < 8*16; offset += 16) {
3022 unsigned short checksum = 0;
3023 /* verify the checksum */
3024 for(i = 0; i<14; i++) checksum += ee[i+offset];
3025 checksum = ~checksum; /* no idea why */
3026 if ((((checksum>>8)&0x0FF) == ee[offset+14]) &&
3027 ((checksum & 0x0FF) == ee[offset+15])) {
3028 break;
3029 }
3030 }
3031
3032 if (offset >= 8*16)
3033 return;
3034
3035 /* found a valid descriptor */
3036 type = (ee[offset+4]<<8) | (ee[offset+5]);
3037
3038 switch(type) {
3039
3040 /* 848 based */
3041 case 0x0004:
3042 btv->c.type = BTTV_OSPREY1x0_848;
3043 break;
3044 case 0x0005:
3045 btv->c.type = BTTV_OSPREY101_848;
3046 break;
3047
3048 /* 878 based */
3049 case 0x0012:
3050 case 0x0013:
3051 btv->c.type = BTTV_OSPREY1x0;
3052 break;
3053 case 0x0014:
3054 case 0x0015:
3055 btv->c.type = BTTV_OSPREY1x1;
3056 break;
3057 case 0x0016:
3058 case 0x0017:
3059 case 0x0020:
3060 btv->c.type = BTTV_OSPREY1x1_SVID;
3061 break;
3062 case 0x0018:
3063 case 0x0019:
3064 case 0x001E:
3065 case 0x001F:
3066 btv->c.type = BTTV_OSPREY2xx;
3067 break;
3068 case 0x001A:
3069 case 0x001B:
3070 btv->c.type = BTTV_OSPREY2x0_SVID;
3071 break;
3072 case 0x0040:
3073 btv->c.type = BTTV_OSPREY500;
3074 break;
3075 case 0x0050:
3076 case 0x0056:
3077 btv->c.type = BTTV_OSPREY540;
3078 /* bttv_osprey_540_init(btv); */
3079 break;
3080 case 0x0060:
3081 case 0x0070:
3082 btv->c.type = BTTV_OSPREY2x0;
3083 //enable output on select control lines
3084 gpio_inout(0xffffff,0x000303);
3085 break;
3086 default:
3087 /* unknown...leave generic, but get serial # */
3088 break;
3089 }
3090 serial = (ee[offset+6] << 24)
3091 | (ee[offset+7] << 16)
3092 | (ee[offset+8] << 8)
3093 | (ee[offset+9]);
3094 }
3095
3096 printk(KERN_INFO "bttv%d: osprey eeprom: card=%d name=%s serial=%ld\n",
3097 btv->c.nr, btv->c.type, bttv_tvcards[btv->c.type].name,serial);
3098}
3099
3100/* ----------------------------------------------------------------------- */
3101/* AVermedia specific stuff, from bktr_card.c */
3102
3103static int tuner_0_table[] = {
3104 TUNER_PHILIPS_NTSC, TUNER_PHILIPS_PAL /* PAL-BG*/,
3105 TUNER_PHILIPS_PAL, TUNER_PHILIPS_PAL /* PAL-I*/,
3106 TUNER_PHILIPS_PAL, TUNER_PHILIPS_PAL,
3107 TUNER_PHILIPS_SECAM, TUNER_PHILIPS_SECAM,
3108 TUNER_PHILIPS_SECAM, TUNER_PHILIPS_PAL,
3109 TUNER_PHILIPS_FM1216ME_MK3 };
3110#if 0
3111int tuner_0_fm_table[] = {
3112 PHILIPS_FR1236_NTSC, PHILIPS_FR1216_PAL,
3113 PHILIPS_FR1216_PAL, PHILIPS_FR1216_PAL,
3114 PHILIPS_FR1216_PAL, PHILIPS_FR1216_PAL,
3115 PHILIPS_FR1236_SECAM, PHILIPS_FR1236_SECAM,
3116 PHILIPS_FR1236_SECAM, PHILIPS_FR1216_PAL};
3117#endif
3118
3119static int tuner_1_table[] = {
3120 TUNER_TEMIC_NTSC, TUNER_TEMIC_PAL,
3121 TUNER_TEMIC_PAL, TUNER_TEMIC_PAL,
3122 TUNER_TEMIC_PAL, TUNER_TEMIC_PAL,
3123 TUNER_TEMIC_4012FY5, TUNER_TEMIC_4012FY5, //TUNER_TEMIC_SECAM
3124 TUNER_TEMIC_4012FY5, TUNER_TEMIC_PAL};
3125
3126static void __devinit avermedia_eeprom(struct bttv *btv)
3127{
3128 int tuner_make,tuner_tv_fm,tuner_format,tuner=0;
3129
3130 tuner_make = (eeprom_data[0x41] & 0x7);
3131 tuner_tv_fm = (eeprom_data[0x41] & 0x18) >> 3;
3132 tuner_format = (eeprom_data[0x42] & 0xf0) >> 4;
3133 btv->has_remote = (eeprom_data[0x42] & 0x01);
3134
3135 if (tuner_make == 0 || tuner_make == 2)
3136 if(tuner_format <=0x0a)
3137 tuner = tuner_0_table[tuner_format];
3138 if (tuner_make == 1)
3139 if(tuner_format <=9)
3140 tuner = tuner_1_table[tuner_format];
3141
3142 if (tuner_make == 4)
3143 if(tuner_format == 0x09)
3144 tuner = TUNER_LG_NTSC_NEW_TAPC; // TAPC-G702P
3145
3146 printk(KERN_INFO "bttv%d: Avermedia eeprom[0x%02x%02x]: tuner=",
3147 btv->c.nr,eeprom_data[0x41],eeprom_data[0x42]);
3148 if(tuner) {
3149 btv->tuner_type=tuner;
3150 printk("%d",tuner);
3151 } else
3152 printk("Unknown type");
3153 printk(" radio:%s remote control:%s\n",
3154 tuner_tv_fm ? "yes" : "no",
3155 btv->has_remote ? "yes" : "no");
3156}
3157
3158/* used on Voodoo TV/FM (Voodoo 200), S0 wired to 0x10000 */
3159void bttv_tda9880_setnorm(struct bttv *btv, int norm)
3160{
3161 // fix up our card entry
3162 if(norm==VIDEO_MODE_NTSC) {
3163 bttv_tvcards[BTTV_VOODOOTV_FM].audiomux[0]=0x957fff;
3164 bttv_tvcards[BTTV_VOODOOTV_FM].audiomux[4]=0x957fff;
3165 dprintk("bttv_tda9880_setnorm to NTSC\n");
3166 }
3167 else {
3168 bttv_tvcards[BTTV_VOODOOTV_FM].audiomux[0]=0x947fff;
3169 bttv_tvcards[BTTV_VOODOOTV_FM].audiomux[4]=0x947fff;
3170 dprintk("bttv_tda9880_setnorm to PAL\n");
3171 }
3172 // set GPIO according
3173 gpio_bits(bttv_tvcards[btv->c.type].gpiomask,
3174 bttv_tvcards[btv->c.type].audiomux[btv->audio]);
3175}
3176
3177
3178/*
3179 * reset/enable the MSP on some Hauppauge cards
3180 * Thanks to Kyösti Mälkki (kmalkki@cc.hut.fi)!
3181 *
3182 * Hauppauge: pin 5
3183 * Voodoo: pin 20
3184 */
3185static void __devinit boot_msp34xx(struct bttv *btv, int pin)
3186{
3187 int mask = (1 << pin);
3188
3189 gpio_inout(mask,mask);
3190 gpio_bits(mask,0);
3191 udelay(2500);
3192 gpio_bits(mask,mask);
3193
3194 if (bttv_gpio)
3195 bttv_gpio_tracking(btv,"msp34xx");
3196 if (bttv_verbose)
3197 printk(KERN_INFO "bttv%d: Hauppauge/Voodoo msp34xx: reset line "
3198 "init [%d]\n", btv->c.nr, pin);
3199}
3200
3201static void __devinit boot_bt832(struct bttv *btv)
3202{
3203#if 0 /* not working yet */
3204 int resetbit=0;
3205
3206 switch (btv->c.type) {
3207 case BTTV_PXELVWPLTVPAK:
3208 resetbit = 0x400000;
3209 break;
3210 case BTTV_MODTEC_205:
3211 resetbit = 1<<9;
3212 break;
3213 default:
3214 BUG();
3215 }
3216
3217 request_module("bt832");
3218 bttv_call_i2c_clients(btv, BT832_HEXDUMP, NULL);
3219
3220 printk("bttv%d: Reset Bt832 [line=0x%x]\n",btv->c.nr,resetbit);
3221 gpio_write(0);
3222 gpio_inout(resetbit, resetbit);
3223 udelay(5);
3224 gpio_bits(resetbit, resetbit);
3225 udelay(5);
3226 gpio_bits(resetbit, 0);
3227 udelay(5);
3228
3229 // bt832 on pixelview changes from i2c 0x8a to 0x88 after
3230 // being reset as above. So we must follow by this:
3231 bttv_call_i2c_clients(btv, BT832_REATTACH, NULL);
3232#endif
3233}
3234
3235/* ----------------------------------------------------------------------- */
3236/* Imagenation L-Model PXC200 Framegrabber */
3237/* This is basically the same procedure as
3238 * used by Alessandro Rubini in his pxc200
3239 * driver, but using BTTV functions */
3240
3241static void __devinit init_PXC200(struct bttv *btv)
3242{
3243 static int vals[] __devinitdata = { 0x08, 0x09, 0x0a, 0x0b, 0x0d, 0x0d,
3244 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
3245 0x00 };
3246 unsigned int i;
3247 int tmp;
3248 u32 val;
3249
3250 /* Initialise GPIO-connevted stuff */
3251 gpio_inout(0xffffff, (1<<13));
3252 gpio_write(0);
3253 udelay(3);
3254 gpio_write(1<<13);
3255 /* GPIO inputs are pulled up, so no need to drive
3256 * reset pin any longer */
3257 gpio_bits(0xffffff, 0);
3258 if (bttv_gpio)
3259 bttv_gpio_tracking(btv,"pxc200");
3260
3261 /* we could/should try and reset/control the AD pots? but
3262 right now we simply turned off the crushing. Without
3263 this the AGC drifts drifts
3264 remember the EN is reverse logic -->
3265 setting BT848_ADC_AGC_EN disable the AGC
3266 tboult@eecs.lehigh.edu
3267 */
3268
3269 btwrite(BT848_ADC_RESERVED|BT848_ADC_AGC_EN, BT848_ADC);
3270
3271 /* Initialise MAX517 DAC */
3272 printk(KERN_INFO "Setting DAC reference voltage level ...\n");
3273 bttv_I2CWrite(btv,0x5E,0,0x80,1);
3274
3275 /* Initialise 12C508 PIC */
3276 /* The I2CWrite and I2CRead commmands are actually to the
3277 * same chips - but the R/W bit is included in the address
3278 * argument so the numbers are different */
3279
3280
3281 printk(KERN_INFO "Initialising 12C508 PIC chip ...\n");
3282
3283 /* First of all, enable the clock line. This is used in the PXC200-F */
3284 val = btread(BT848_GPIO_DMA_CTL);
3285 val |= BT848_GPIO_DMA_CTL_GPCLKMODE;
3286 btwrite(val, BT848_GPIO_DMA_CTL);
3287
3288 /* Then, push to 0 the reset pin long enough to reset the *
3289 * device same as above for the reset line, but not the same
3290 * value sent to the GPIO-connected stuff
3291 * which one is the good one? */
3292 gpio_inout(0xffffff,(1<<2));
3293 gpio_write(0);
3294 udelay(10);
3295 gpio_write(1<<2);
3296
3297 for (i = 0; i < ARRAY_SIZE(vals); i++) {
3298 tmp=bttv_I2CWrite(btv,0x1E,0,vals[i],1);
3299 if (tmp != -1) {
3300 printk(KERN_INFO
3301 "I2C Write(%2.2x) = %i\nI2C Read () = %2.2x\n\n",
3302 vals[i],tmp,bttv_I2CRead(btv,0x1F,NULL));
3303 }
3304 }
3305
3306 printk(KERN_INFO "PXC200 Initialised.\n");
3307}
3308
3309
3310/* ----------------------------------------------------------------------- */
3311/* Miro Pro radio stuff -- the tea5757 is connected to some GPIO ports */
3312/*
3313 * Copyright (c) 1999 Csaba Halasz <qgehali@uni-miskolc.hu>
3314 * This code is placed under the terms of the GNU General Public License
3315 *
3316 * Brutally hacked by Dan Sheridan <dan.sheridan@contact.org.uk> djs52 8/3/00
3317 */
3318
3319static void bus_low(struct bttv *btv, int bit)
3320{
3321 if (btv->mbox_ior) {
3322 gpio_bits(btv->mbox_ior | btv->mbox_iow | btv->mbox_csel,
3323 btv->mbox_ior | btv->mbox_iow | btv->mbox_csel);
3324 udelay(5);
3325 }
3326
3327 gpio_bits(bit,0);
3328 udelay(5);
3329
3330 if (btv->mbox_ior) {
3331 gpio_bits(btv->mbox_iow | btv->mbox_csel, 0);
3332 udelay(5);
3333 }
3334}
3335
3336static void bus_high(struct bttv *btv, int bit)
3337{
3338 if (btv->mbox_ior) {
3339 gpio_bits(btv->mbox_ior | btv->mbox_iow | btv->mbox_csel,
3340 btv->mbox_ior | btv->mbox_iow | btv->mbox_csel);
3341 udelay(5);
3342 }
3343
3344 gpio_bits(bit,bit);
3345 udelay(5);
3346
3347 if (btv->mbox_ior) {
3348 gpio_bits(btv->mbox_iow | btv->mbox_csel, 0);
3349 udelay(5);
3350 }
3351}
3352
3353static int bus_in(struct bttv *btv, int bit)
3354{
3355 if (btv->mbox_ior) {
3356 gpio_bits(btv->mbox_ior | btv->mbox_iow | btv->mbox_csel,
3357 btv->mbox_ior | btv->mbox_iow | btv->mbox_csel);
3358 udelay(5);
3359
3360 gpio_bits(btv->mbox_iow | btv->mbox_csel, 0);
3361 udelay(5);
3362 }
3363 return gpio_read() & (bit);
3364}
3365
3366/* TEA5757 register bits */
3367#define TEA_FREQ 0:14
3368#define TEA_BUFFER 15:15
3369
3370#define TEA_SIGNAL_STRENGTH 16:17
3371
3372#define TEA_PORT1 18:18
3373#define TEA_PORT0 19:19
3374
3375#define TEA_BAND 20:21
3376#define TEA_BAND_FM 0
3377#define TEA_BAND_MW 1
3378#define TEA_BAND_LW 2
3379#define TEA_BAND_SW 3
3380
3381#define TEA_MONO 22:22
3382#define TEA_ALLOW_STEREO 0
3383#define TEA_FORCE_MONO 1
3384
3385#define TEA_SEARCH_DIRECTION 23:23
3386#define TEA_SEARCH_DOWN 0
3387#define TEA_SEARCH_UP 1
3388
3389#define TEA_STATUS 24:24
3390#define TEA_STATUS_TUNED 0
3391#define TEA_STATUS_SEARCHING 1
3392
3393/* Low-level stuff */
3394static int tea5757_read(struct bttv *btv)
3395{
3396 unsigned long timeout;
3397 int value = 0;
3398 int i;
3399
3400 /* better safe than sorry */
3401 gpio_inout(btv->mbox_mask, btv->mbox_clk | btv->mbox_we);
3402
3403 if (btv->mbox_ior) {
3404 gpio_bits(btv->mbox_ior | btv->mbox_iow | btv->mbox_csel,
3405 btv->mbox_ior | btv->mbox_iow | btv->mbox_csel);
3406 udelay(5);
3407 }
3408
3409 if (bttv_gpio)
3410 bttv_gpio_tracking(btv,"tea5757 read");
3411
3412 bus_low(btv,btv->mbox_we);
3413 bus_low(btv,btv->mbox_clk);
3414
3415 udelay(10);
3416 timeout= jiffies + HZ;
3417
3418 // wait for DATA line to go low; error if it doesn't
3419 while (bus_in(btv,btv->mbox_data) && time_before(jiffies, timeout))
3420 schedule();
3421 if (bus_in(btv,btv->mbox_data)) {
3422 printk(KERN_WARNING "bttv%d: tea5757: read timeout\n",btv->c.nr);
3423 return -1;
3424 }
3425
3426 dprintk("bttv%d: tea5757:",btv->c.nr);
3427 for(i = 0; i < 24; i++)
3428 {
3429 udelay(5);
3430 bus_high(btv,btv->mbox_clk);
3431 udelay(5);
3432 dprintk("%c",(bus_in(btv,btv->mbox_most) == 0)?'T':'-');
3433 bus_low(btv,btv->mbox_clk);
3434 value <<= 1;
3435 value |= (bus_in(btv,btv->mbox_data) == 0)?0:1; /* MSB first */
3436 dprintk("%c", (bus_in(btv,btv->mbox_most) == 0)?'S':'M');
3437 }
3438 dprintk("\nbttv%d: tea5757: read 0x%X\n", btv->c.nr, value);
3439 return value;
3440}
3441
3442static int tea5757_write(struct bttv *btv, int value)
3443{
3444 int i;
3445 int reg = value;
3446
3447 gpio_inout(btv->mbox_mask, btv->mbox_clk | btv->mbox_we | btv->mbox_data);
3448
3449 if (btv->mbox_ior) {
3450 gpio_bits(btv->mbox_ior | btv->mbox_iow | btv->mbox_csel,
3451 btv->mbox_ior | btv->mbox_iow | btv->mbox_csel);
3452 udelay(5);
3453 }
3454 if (bttv_gpio)
3455 bttv_gpio_tracking(btv,"tea5757 write");
3456
3457 dprintk("bttv%d: tea5757: write 0x%X\n", btv->c.nr, value);
3458 bus_low(btv,btv->mbox_clk);
3459 bus_high(btv,btv->mbox_we);
3460 for(i = 0; i < 25; i++)
3461 {
3462 if (reg & 0x1000000)
3463 bus_high(btv,btv->mbox_data);
3464 else
3465 bus_low(btv,btv->mbox_data);
3466 reg <<= 1;
3467 bus_high(btv,btv->mbox_clk);
3468 udelay(10);
3469 bus_low(btv,btv->mbox_clk);
3470 udelay(10);
3471 }
3472 bus_low(btv,btv->mbox_we); /* unmute !!! */
3473 return 0;
3474}
3475
3476void tea5757_set_freq(struct bttv *btv, unsigned short freq)
3477{
3478 dprintk("tea5757_set_freq %d\n",freq);
3479 tea5757_write(btv, 5 * freq + 0x358); /* add 10.7MHz (see docs) */
3480#if 0
3481 /* breaks Miro PCTV */
3482 value = tea5757_read(btv);
3483 dprintk("bttv%d: tea5757 readback=0x%x\n",btv->c.nr,value);
3484#endif
3485}
3486
3487
3488/* ----------------------------------------------------------------------- */
3489/* winview */
3490
3491void winview_audio(struct bttv *btv, struct video_audio *v, int set)
3492{
3493 /* PT2254A programming Jon Tombs, jon@gte.esi.us.es */
3494 int bits_out, loops, vol, data;
3495
3496 if (!set) {
3497 /* Fixed by Leandro Lucarella <luca@linuxmendoza.org.ar (07/31/01) */
3498 v->flags |= VIDEO_AUDIO_VOLUME;
3499 return;
3500 }
3501
3502 /* 32 levels logarithmic */
3503 vol = 32 - ((v->volume>>11));
3504 /* units */
3505 bits_out = (PT2254_DBS_IN_2>>(vol%5));
3506 /* tens */
3507 bits_out |= (PT2254_DBS_IN_10>>(vol/5));
3508 bits_out |= PT2254_L_CHANNEL | PT2254_R_CHANNEL;
3509 data = gpio_read();
3510 data &= ~(WINVIEW_PT2254_CLK| WINVIEW_PT2254_DATA|
3511 WINVIEW_PT2254_STROBE);
3512 for (loops = 17; loops >= 0 ; loops--) {
3513 if (bits_out & (1<<loops))
3514 data |= WINVIEW_PT2254_DATA;
3515 else
3516 data &= ~WINVIEW_PT2254_DATA;
3517 gpio_write(data);
3518 udelay(5);
3519 data |= WINVIEW_PT2254_CLK;
3520 gpio_write(data);
3521 udelay(5);
3522 data &= ~WINVIEW_PT2254_CLK;
3523 gpio_write(data);
3524 }
3525 data |= WINVIEW_PT2254_STROBE;
3526 data &= ~WINVIEW_PT2254_DATA;
3527 gpio_write(data);
3528 udelay(10);
3529 data &= ~WINVIEW_PT2254_STROBE;
3530 gpio_write(data);
3531}
3532
3533/* ----------------------------------------------------------------------- */
3534/* mono/stereo control for various cards (which don't use i2c chips but */
3535/* connect something to the GPIO pins */
3536
3537static void
3538gvbctv3pci_audio(struct bttv *btv, struct video_audio *v, int set)
3539{
3540 unsigned int con = 0;
3541
3542 if (set) {
3543 gpio_inout(0x300, 0x300);
3544 if (v->mode & VIDEO_SOUND_LANG1)
3545 con = 0x000;
3546 if (v->mode & VIDEO_SOUND_LANG2)
3547 con = 0x300;
3548 if (v->mode & VIDEO_SOUND_STEREO)
3549 con = 0x200;
3550// if (v->mode & VIDEO_SOUND_MONO)
3551// con = 0x100;
3552 gpio_bits(0x300, con);
3553 } else {
3554 v->mode = VIDEO_SOUND_STEREO |
3555 VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
3556 }
3557}
3558
3559static void
3560gvbctv5pci_audio(struct bttv *btv, struct video_audio *v, int set)
3561{
3562 unsigned int val, con;
3563
3564#if BTTV_VERSION_CODE > KERNEL_VERSION(0,8,0)
3565 if (btv->radio_user)
3566 return;
3567#else
3568 if (btv->radio)
3569 return;
3570#endif
3571
3572 val = gpio_read();
3573 if (set) {
3574 con = 0x000;
3575 if (v->mode & VIDEO_SOUND_LANG2) {
3576 if (v->mode & VIDEO_SOUND_LANG1) {
3577 /* LANG1 + LANG2 */
3578 con = 0x100;
3579 }
3580 else {
3581 /* LANG2 */
3582 con = 0x300;
3583 }
3584 }
3585 if (con != (val & 0x300)) {
3586 gpio_bits(0x300, con);
3587 if (bttv_gpio)
3588 bttv_gpio_tracking(btv,"gvbctv5pci");
3589 }
3590 } else {
3591 switch (val & 0x70) {
3592 case 0x10:
3593 v->mode = VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
3594 break;
3595 case 0x30:
3596 v->mode = VIDEO_SOUND_LANG2;
3597 break;
3598 case 0x50:
3599 v->mode = VIDEO_SOUND_LANG1;
3600 break;
3601 case 0x60:
3602 v->mode = VIDEO_SOUND_STEREO;
3603 break;
3604 case 0x70:
3605 v->mode = VIDEO_SOUND_MONO;
3606 break;
3607 default:
3608 v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO |
3609 VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
3610 }
3611 }
3612}
3613
3614/*
3615 * Mario Medina Nussbaum <medisoft@alohabbs.org.mx>
3616 * I discover that on BT848_GPIO_DATA address a byte 0xcce enable stereo,
3617 * 0xdde enables mono and 0xccd enables sap
3618 *
3619 * Petr Vandrovec <VANDROVE@vc.cvut.cz>
3620 * P.S.: At least mask in line above is wrong - GPIO pins 3,2 select
3621 * input/output sound connection, so both must be set for output mode.
3622 *
3623 * Looks like it's needed only for the "tvphone", the "tvphone 98"
3624 * handles this with a tda9840
3625 *
3626 */
3627static void
3628avermedia_tvphone_audio(struct bttv *btv, struct video_audio *v, int set)
3629{
3630 int val = 0;
3631
3632 if (set) {
3633 if (v->mode & VIDEO_SOUND_LANG2) /* SAP */
3634 val = 0x02;
3635 if (v->mode & VIDEO_SOUND_STEREO)
3636 val = 0x01;
3637 if (val) {
3638 gpio_bits(0x03,val);
3639 if (bttv_gpio)
3640 bttv_gpio_tracking(btv,"avermedia");
3641 }
3642 } else {
3643 v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO |
3644 VIDEO_SOUND_LANG1;
3645 return;
3646 }
3647}
3648
3649static void
3650avermedia_tv_stereo_audio(struct bttv *btv, struct video_audio *v, int set)
3651{
3652 int val = 0;
3653
3654 if (set) {
3655 if (v->mode & VIDEO_SOUND_LANG2) /* SAP */
3656 val = 0x01;
3657 if (v->mode & VIDEO_SOUND_STEREO) /* STEREO */
3658 val = 0x02;
3659 btaor(val, ~0x03, BT848_GPIO_DATA);
3660 if (bttv_gpio)
3661 bttv_gpio_tracking(btv,"avermedia");
3662 } else {
3663 v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO |
3664 VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
3665 return;
3666 }
3667}
3668
3669/* Lifetec 9415 handling */
3670static void
3671lt9415_audio(struct bttv *btv, struct video_audio *v, int set)
3672{
3673 int val = 0;
3674
3675 if (gpio_read() & 0x4000) {
3676 v->mode = VIDEO_SOUND_MONO;
3677 return;
3678 }
3679
3680 if (set) {
3681 if (v->mode & VIDEO_SOUND_LANG2) /* A2 SAP */
3682 val = 0x0080;
3683 if (v->mode & VIDEO_SOUND_STEREO) /* A2 stereo */
3684 val = 0x0880;
3685 if ((v->mode & VIDEO_SOUND_LANG1) ||
3686 (v->mode & VIDEO_SOUND_MONO))
3687 val = 0;
3688 gpio_bits(0x0880, val);
3689 if (bttv_gpio)
3690 bttv_gpio_tracking(btv,"lt9415");
3691 } else {
3692 /* autodetect doesn't work with this card :-( */
3693 v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO |
3694 VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
3695 return;
3696 }
3697}
3698
3699// TDA9821 on TerraTV+ Bt848, Bt878
3700static void
3701terratv_audio(struct bttv *btv, struct video_audio *v, int set)
3702{
3703 unsigned int con = 0;
3704
3705 if (set) {
3706 gpio_inout(0x180000,0x180000);
3707 if (v->mode & VIDEO_SOUND_LANG2)
3708 con = 0x080000;
3709 if (v->mode & VIDEO_SOUND_STEREO)
3710 con = 0x180000;
3711 gpio_bits(0x180000, con);
3712 if (bttv_gpio)
3713 bttv_gpio_tracking(btv,"terratv");
3714 } else {
3715 v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO |
3716 VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
3717 }
3718}
3719
3720static void
3721winfast2000_audio(struct bttv *btv, struct video_audio *v, int set)
3722{
3723 unsigned long val = 0;
3724
3725 if (set) {
3726 /*btor (0xc32000, BT848_GPIO_OUT_EN);*/
3727 if (v->mode & VIDEO_SOUND_MONO) /* Mono */
3728 val = 0x420000;
3729 if (v->mode & VIDEO_SOUND_LANG1) /* Mono */
3730 val = 0x420000;
3731 if (v->mode & VIDEO_SOUND_LANG2) /* SAP */
3732 val = 0x410000;
3733 if (v->mode & VIDEO_SOUND_STEREO) /* Stereo */
3734 val = 0x020000;
3735 if (val) {
3736 gpio_bits(0x430000, val);
3737 if (bttv_gpio)
3738 bttv_gpio_tracking(btv,"winfast2000");
3739 }
3740 } else {
3741 v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO |
3742 VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
3743 }
3744}
3745
3746/*
3747 * Dariusz Kowalewski <darekk@automex.pl>
3748 * sound control for Prolink PV-BT878P+9B (PixelView PlayTV Pro FM+NICAM
3749 * revision 9B has on-board TDA9874A sound decoder).
3750 *
3751 * Note: There are card variants without tda9874a. Forcing the "stereo sound route"
3752 * will mute this cards.
3753 */
3754static void
3755pvbt878p9b_audio(struct bttv *btv, struct video_audio *v, int set)
3756{
3757 unsigned int val = 0;
3758
3759#if BTTV_VERSION_CODE > KERNEL_VERSION(0,8,0)
3760 if (btv->radio_user)
3761 return;
3762#else
3763 if (btv->radio)
3764 return;
3765#endif
3766
3767 if (set) {
3768 if (v->mode & VIDEO_SOUND_MONO) {
3769 val = 0x01;
3770 }
3771 if ((v->mode & (VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2))
3772 || (v->mode & VIDEO_SOUND_STEREO)) {
3773 val = 0x02;
3774 }
3775 if (val) {
3776 gpio_bits(0x03,val);
3777 if (bttv_gpio)
3778 bttv_gpio_tracking(btv,"pvbt878p9b");
3779 }
3780 } else {
3781 v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO |
3782 VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
3783 }
3784}
3785
3786/*
3787 * Dariusz Kowalewski <darekk@automex.pl>
3788 * sound control for FlyVideo 2000S (with tda9874 decoder)
3789 * based on pvbt878p9b_audio() - this is not tested, please fix!!!
3790 */
3791static void
3792fv2000s_audio(struct bttv *btv, struct video_audio *v, int set)
3793{
3794 unsigned int val = 0xffff;
3795
3796#if BTTV_VERSION_CODE > KERNEL_VERSION(0,8,0)
3797 if (btv->radio_user)
3798 return;
3799#else
3800 if (btv->radio)
3801 return;
3802#endif
3803 if (set) {
3804 if (v->mode & VIDEO_SOUND_MONO) {
3805 val = 0x0000;
3806 }
3807 if ((v->mode & (VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2))
3808 || (v->mode & VIDEO_SOUND_STEREO)) {
3809 val = 0x1080; //-dk-???: 0x0880, 0x0080, 0x1800 ...
3810 }
3811 if (val != 0xffff) {
3812 gpio_bits(0x1800, val);
3813 if (bttv_gpio)
3814 bttv_gpio_tracking(btv,"fv2000s");
3815 }
3816 } else {
3817 v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO |
3818 VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
3819 }
3820}
3821
3822/*
3823 * sound control for Canopus WinDVR PCI
3824 * Masaki Suzuki <masaki@btree.org>
3825 */
3826static void
3827windvr_audio(struct bttv *btv, struct video_audio *v, int set)
3828{
3829 unsigned long val = 0;
3830
3831 if (set) {
3832 if (v->mode & VIDEO_SOUND_MONO)
3833 val = 0x040000;
3834 if (v->mode & VIDEO_SOUND_LANG1)
3835 val = 0;
3836 if (v->mode & VIDEO_SOUND_LANG2)
3837 val = 0x100000;
3838 if (v->mode & VIDEO_SOUND_STEREO)
3839 val = 0;
3840 if (val) {
3841 gpio_bits(0x140000, val);
3842 if (bttv_gpio)
3843 bttv_gpio_tracking(btv,"windvr");
3844 }
3845 } else {
3846 v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO |
3847 VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
3848 }
3849}
3850
3851/*
3852 * sound control for AD-TVK503
3853 * Hiroshi Takekawa <sian@big.or.jp>
3854 */
3855static void
3856adtvk503_audio(struct bttv *btv, struct video_audio *v, int set)
3857{
3858 unsigned int con = 0xffffff;
3859
3860 //btaor(0x1e0000, ~0x1e0000, BT848_GPIO_OUT_EN);
3861
3862 if (set) {
3863 //btor(***, BT848_GPIO_OUT_EN);
3864 if (v->mode & VIDEO_SOUND_LANG1)
3865 con = 0x00000000;
3866 if (v->mode & VIDEO_SOUND_LANG2)
3867 con = 0x00180000;
3868 if (v->mode & VIDEO_SOUND_STEREO)
3869 con = 0x00000000;
3870 if (v->mode & VIDEO_SOUND_MONO)
3871 con = 0x00060000;
3872 if (con != 0xffffff) {
3873 gpio_bits(0x1e0000,con);
3874 if (bttv_gpio)
3875 bttv_gpio_tracking(btv, "adtvk503");
3876 }
3877 } else {
3878 v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO |
3879 VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
3880 }
3881}
3882
3883/* RemoteVision MX (rv605) muxsel helper [Miguel Freitas]
3884 *
3885 * This is needed because rv605 don't use a normal multiplex, but a crosspoint
3886 * switch instead (CD22M3494E). This IC can have multiple active connections
3887 * between Xn (input) and Yn (output) pins. We need to clear any existing
3888 * connection prior to establish a new one, pulsing the STROBE pin.
3889 *
3890 * The board hardwire Y0 (xpoint) to MUX1 and MUXOUT to Yin.
3891 * GPIO pins are wired as:
3892 * GPIO[0:3] - AX[0:3] (xpoint) - P1[0:3] (microcontroler)
3893 * GPIO[4:6] - AY[0:2] (xpoint) - P1[4:6] (microcontroler)
3894 * GPIO[7] - DATA (xpoint) - P1[7] (microcontroler)
3895 * GPIO[8] - - P3[5] (microcontroler)
3896 * GPIO[9] - RESET (xpoint) - P3[6] (microcontroler)
3897 * GPIO[10] - STROBE (xpoint) - P3[7] (microcontroler)
3898 * GPINTR - - P3[4] (microcontroler)
3899 *
3900 * The microcontroler is a 80C32 like. It should be possible to change xpoint
3901 * configuration either directly (as we are doing) or using the microcontroler
3902 * which is also wired to I2C interface. I have no further info on the
3903 * microcontroler features, one would need to disassembly the firmware.
3904 * note: the vendor refused to give any information on this product, all
3905 * that stuff was found using a multimeter! :)
3906 */
3907static void rv605_muxsel(struct bttv *btv, unsigned int input)
3908{
3909 /* reset all conections */
3910 gpio_bits(0x200,0x200);
3911 mdelay(1);
3912 gpio_bits(0x200,0x000);
3913 mdelay(1);
3914
3915 /* create a new conection */
3916 gpio_bits(0x480,0x080);
3917 gpio_bits(0x480,0x480);
3918 mdelay(1);
3919 gpio_bits(0x480,0x080);
3920 mdelay(1);
3921}
3922
3923/* Tibet Systems 'Progress DVR' CS16 muxsel helper [Chris Fanning]
3924 *
3925 * The CS16 (available on eBay cheap) is a PCI board with four Fusion
3926 * 878A chips, a PCI bridge, an Atmel microcontroller, four sync seperator
3927 * chips, ten eight input analog multiplexors, a not chip and a few
3928 * other components.
3929 *
3930 * 16 inputs on a secondary bracket are provided and can be selected
3931 * from each of the four capture chips. Two of the eight input
3932 * multiplexors are used to select from any of the 16 input signals.
3933 *
3934 * Unsupported hardware capabilities:
3935 * . A video output monitor on the secondary bracket can be selected from
3936 * one of the 878A chips.
3937 * . Another passthrough but I haven't spent any time investigating it.
3938 * . Digital I/O (logic level connected to GPIO) is available from an
3939 * onboard header.
3940 *
3941 * The on chip input mux should always be set to 2.
3942 * GPIO[16:19] - Video input selection
3943 * GPIO[0:3] - Video output monitor select (only available from one 878A)
3944 * GPIO[?:?] - Digital I/O.
3945 *
3946 * There is an ATMEL microcontroller with an 8031 core on board. I have not
3947 * determined what function (if any) it provides. With the microcontroller
3948 * and sync seperator chips a guess is that it might have to do with video
3949 * switching and maybe some digital I/O.
3950 */
3951static void tibetCS16_muxsel(struct bttv *btv, unsigned int input)
3952{
3953 /* video mux */
3954 gpio_bits(0x0f0000, input << 16);
3955}
3956
3957static void tibetCS16_init(struct bttv *btv)
3958{
3959 /* enable gpio bits, mask obtained via btSpy */
3960 gpio_inout(0xffffff, 0x0f7fff);
3961 gpio_write(0x0f7fff);
3962}
3963
3964/*
3965 * The following routines for the Kodicom-4400r get a little mind-twisting.
3966 * There is a "master" controller and three "slave" controllers, together
3967 * an analog switch which connects any of 16 cameras to any of the BT87A's.
3968 * The analog switch is controlled by the "master", but the detection order
3969 * of the four BT878A chips is in an order which I just don't understand.
3970 * The "master" is actually the second controller to be detected. The
3971 * logic on the board uses logical numbers for the 4 controlers, but
3972 * those numbers are different from the detection sequence. When working
3973 * with the analog switch, we need to "map" from the detection sequence
3974 * over to the board's logical controller number. This mapping sequence
3975 * is {3, 0, 2, 1}, i.e. the first controller to be detected is logical
3976 * unit 3, the second (which is the master) is logical unit 0, etc.
3977 * We need to maintain the status of the analog switch (which of the 16
3978 * cameras is connected to which of the 4 controllers). Rather than
3979 * add to the bttv structure for this, we use the data reserved for
3980 * the mbox (unused for this card type).
3981 */
3982
3983/*
3984 * First a routine to set the analog switch, which controls which camera
3985 * is routed to which controller. The switch comprises an X-address
3986 * (gpio bits 0-3, representing the camera, ranging from 0-15), and a
3987 * Y-address (gpio bits 4-6, representing the controller, ranging from 0-3).
3988 * A data value (gpio bit 7) of '1' enables the switch, and '0' disables
3989 * the switch. A STROBE bit (gpio bit 8) latches the data value into the
3990 * specified address. The idea is to set the address and data, then bring
3991 * STROBE high, and finally bring STROBE back to low.
3992 */
3993static void kodicom4400r_write(struct bttv *btv,
3994 unsigned char xaddr,
3995 unsigned char yaddr,
3996 unsigned char data) {
3997 unsigned int udata;
3998
3999 udata = (data << 7) | ((yaddr&3) << 4) | (xaddr&0xf);
4000 gpio_bits(0x1ff, udata); /* write ADDR and DAT */
4001 gpio_bits(0x1ff, udata | (1 << 8)); /* strobe high */
4002 gpio_bits(0x1ff, udata); /* strobe low */
4003}
4004
4005/*
4006 * Next the mux select. Both the "master" and "slave" 'cards' (controllers)
4007 * use this routine. The routine finds the "master" for the card, maps
4008 * the controller number from the detected position over to the logical
4009 * number, writes the appropriate data to the analog switch, and housekeeps
4010 * the local copy of the switch information. The parameter 'input' is the
4011 * requested camera number (0 - 15).
4012 */
4013static void kodicom4400r_muxsel(struct bttv *btv, unsigned int input)
4014{
4015 char *sw_status;
4016 int xaddr, yaddr;
4017 struct bttv *mctlr;
4018 static unsigned char map[4] = {3, 0, 2, 1};
4019
4020 mctlr = master[btv->c.nr];
4021 if (mctlr == NULL) { /* ignore if master not yet detected */
4022 return;
4023 }
4024 yaddr = (btv->c.nr - mctlr->c.nr + 1) & 3; /* the '&' is for safety */
4025 yaddr = map[yaddr];
4026 sw_status = (char *)(&mctlr->mbox_we);
4027 xaddr = input & 0xf;
4028 /* Check if the controller/camera pair has changed, else ignore */
4029 if (sw_status[yaddr] != xaddr)
4030 {
4031 /* "open" the old switch, "close" the new one, save the new */
4032 kodicom4400r_write(mctlr, sw_status[yaddr], yaddr, 0);
4033 sw_status[yaddr] = xaddr;
4034 kodicom4400r_write(mctlr, xaddr, yaddr, 1);
4035 }
4036}
4037
4038/*
4039 * During initialisation, we need to reset the analog switch. We
4040 * also preset the switch to map the 4 connectors on the card to the
4041 * *user's* (see above description of kodicom4400r_muxsel) channels
4042 * 0 through 3
4043 */
4044static void kodicom4400r_init(struct bttv *btv)
4045{
4046 char *sw_status = (char *)(&btv->mbox_we);
4047 int ix;
4048
4049 gpio_inout(0x0003ff, 0x0003ff);
4050 gpio_write(1 << 9); /* reset MUX */
4051 gpio_write(0);
4052 /* Preset camera 0 to the 4 controllers */
4053 for (ix=0; ix<4; ix++) {
4054 sw_status[ix] = ix;
4055 kodicom4400r_write(btv, ix, ix, 1);
4056 }
4057 /*
4058 * Since this is the "master", we need to set up the
4059 * other three controller chips' pointers to this structure
4060 * for later use in the muxsel routine.
4061 */
4062 if ((btv->c.nr<1) || (btv->c.nr>BTTV_MAX-3))
4063 return;
4064 master[btv->c.nr-1] = btv;
4065 master[btv->c.nr] = btv;
4066 master[btv->c.nr+1] = btv;
4067 master[btv->c.nr+2] = btv;
4068}
4069
4070// The Grandtec X-Guard framegrabber card uses two Dual 4-channel
4071// video multiplexers to provide up to 16 video inputs. These
4072// multiplexers are controlled by the lower 8 GPIO pins of the
4073// bt878. The multiplexers probably Pericom PI5V331Q or similar.
4074
4075// xxx0 is pin xxx of multiplexer U5,
4076// yyy1 is pin yyy of multiplexer U2
4077
4078#define ENA0 0x01
4079#define ENB0 0x02
4080#define ENA1 0x04
4081#define ENB1 0x08
4082
4083#define IN10 0x10
4084#define IN00 0x20
4085#define IN11 0x40
4086#define IN01 0x80
4087
4088static void xguard_muxsel(struct bttv *btv, unsigned int input)
4089{
4090 static const int masks[] = {
4091 ENB0, ENB0|IN00, ENB0|IN10, ENB0|IN00|IN10,
4092 ENA0, ENA0|IN00, ENA0|IN10, ENA0|IN00|IN10,
4093 ENB1, ENB1|IN01, ENB1|IN11, ENB1|IN01|IN11,
4094 ENA1, ENA1|IN01, ENA1|IN11, ENA1|IN01|IN11,
4095 };
4096 gpio_write(masks[input%16]);
4097}
4098static void picolo_tetra_init(struct bttv *btv)
4099{
4100 /*This is the video input redirection fonctionality : I DID NOT USED IT. */
4101 btwrite (0x08<<16,BT848_GPIO_DATA);/*GPIO[19] [==> 4053 B+C] set to 1 */
4102 btwrite (0x04<<16,BT848_GPIO_DATA);/*GPIO[18] [==> 4053 A] set to 1*/
4103}
4104static void picolo_tetra_muxsel (struct bttv* btv, unsigned int input)
4105{
4106
4107 dprintk (KERN_DEBUG "bttv%d : picolo_tetra_muxsel => input = %d\n",btv->c.nr,input);
4108 /*Just set the right path in the analog multiplexers : channel 1 -> 4 ==> Analog Mux ==> MUX0*/
4109 /*GPIO[20]&GPIO[21] used to choose the right input*/
4110 btwrite (input<<20,BT848_GPIO_DATA);
4111
4112}
4113
4114/*
4115 * ivc120_muxsel [Added by Alan Garfield <alan@fromorbit.com>]
4116 *
4117 * The IVC120G security card has 4 i2c controlled TDA8540 matrix
4118 * swichers to provide 16 channels to MUX0. The TDA8540's have
4119 * 4 indepedant outputs and as such the IVC120G also has the
4120 * optional "Monitor Out" bus. This allows the card to be looking
4121 * at one input while the monitor is looking at another.
4122 *
4123 * Since I've couldn't be bothered figuring out how to add an
4124 * independant muxsel for the monitor bus, I've just set it to
4125 * whatever the card is looking at.
4126 *
4127 * OUT0 of the TDA8540's is connected to MUX0 (0x03)
4128 * OUT1 of the TDA8540's is connected to "Monitor Out" (0x0C)
4129 *
4130 * TDA8540_ALT3 IN0-3 = Channel 13 - 16 (0x03)
4131 * TDA8540_ALT4 IN0-3 = Channel 1 - 4 (0x03)
4132 * TDA8540_ALT5 IN0-3 = Channel 5 - 8 (0x03)
4133 * TDA8540_ALT6 IN0-3 = Channel 9 - 12 (0x03)
4134 *
4135 */
4136
4137/* All 7 possible sub-ids for the TDA8540 Matrix Switcher */
4138#define I2C_TDA8540 0x90
4139#define I2C_TDA8540_ALT1 0x92
4140#define I2C_TDA8540_ALT2 0x94
4141#define I2C_TDA8540_ALT3 0x96
4142#define I2C_TDA8540_ALT4 0x98
4143#define I2C_TDA8540_ALT5 0x9a
4144#define I2C_TDA8540_ALT6 0x9c
4145
4146static void ivc120_muxsel(struct bttv *btv, unsigned int input)
4147{
4148 // Simple maths
4149 int key = input % 4;
4150 int matrix = input / 4;
4151
4152 dprintk("bttv%d: ivc120_muxsel: Input - %02d | TDA - %02d | In - %02d\n",
4153 btv->c.nr, input, matrix, key);
4154
4155 // Handles the input selection on the TDA8540's
4156 bttv_I2CWrite(btv, I2C_TDA8540_ALT3, 0x00,
4157 ((matrix == 3) ? (key | key << 2) : 0x00), 1);
4158 bttv_I2CWrite(btv, I2C_TDA8540_ALT4, 0x00,
4159 ((matrix == 0) ? (key | key << 2) : 0x00), 1);
4160 bttv_I2CWrite(btv, I2C_TDA8540_ALT5, 0x00,
4161 ((matrix == 1) ? (key | key << 2) : 0x00), 1);
4162 bttv_I2CWrite(btv, I2C_TDA8540_ALT6, 0x00,
4163 ((matrix == 2) ? (key | key << 2) : 0x00), 1);
4164
4165 // Handles the output enables on the TDA8540's
4166 bttv_I2CWrite(btv, I2C_TDA8540_ALT3, 0x02,
4167 ((matrix == 3) ? 0x03 : 0x00), 1); // 13 - 16
4168 bttv_I2CWrite(btv, I2C_TDA8540_ALT4, 0x02,
4169 ((matrix == 0) ? 0x03 : 0x00), 1); // 1-4
4170 bttv_I2CWrite(btv, I2C_TDA8540_ALT5, 0x02,
4171 ((matrix == 1) ? 0x03 : 0x00), 1); // 5-8
4172 bttv_I2CWrite(btv, I2C_TDA8540_ALT6, 0x02,
4173 ((matrix == 2) ? 0x03 : 0x00), 1); // 9-12
4174
4175 // Selects MUX0 for input on the 878
4176 btaor((0)<<5, ~(3<<5), BT848_IFORM);
4177}
4178
4179
4180/* PXC200 muxsel helper
4181 * luke@syseng.anu.edu.au
4182 * another transplant
4183 * from Alessandro Rubini (rubini@linux.it)
4184 *
4185 * There are 4 kinds of cards:
4186 * PXC200L which is bt848
4187 * PXC200F which is bt848 with PIC controlling mux
4188 * PXC200AL which is bt878
4189 * PXC200AF which is bt878 with PIC controlling mux
4190 */
4191#define PX_CFG_PXC200F 0x01
4192#define PX_FLAG_PXC200A 0x00001000 /* a pxc200A is bt-878 based */
4193#define PX_I2C_PIC 0x0f
4194#define PX_PXC200A_CARDID 0x200a1295
4195#define PX_I2C_CMD_CFG 0x00
4196
4197static void PXC200_muxsel(struct bttv *btv, unsigned int input)
4198{
4199 int rc;
4200 long mux;
4201 int bitmask;
4202 unsigned char buf[2];
4203
4204 /* Read PIC config to determine if this is a PXC200F */
4205 /* PX_I2C_CMD_CFG*/
4206 buf[0]=0;
4207 buf[1]=0;
4208 rc=bttv_I2CWrite(btv,(PX_I2C_PIC<<1),buf[0],buf[1],1);
4209 if (rc) {
4210 printk(KERN_DEBUG "bttv%d: PXC200_muxsel: pic cfg write failed:%d\n", btv->c.nr,rc);
4211 /* not PXC ? do nothing */
4212 return;
4213 }
4214
4215 rc=bttv_I2CRead(btv,(PX_I2C_PIC<<1),NULL);
4216 if (!(rc & PX_CFG_PXC200F)) {
4217 printk(KERN_DEBUG "bttv%d: PXC200_muxsel: not PXC200F rc:%d \n", btv->c.nr,rc);
4218 return;
4219 }
4220
4221
4222 /* The multiplexer in the 200F is handled by the GPIO port */
4223 /* get correct mapping between inputs */
4224 /* mux = bttv_tvcards[btv->type].muxsel[input] & 3; */
4225 /* ** not needed!? */
4226 mux = input;
4227
4228 /* make sure output pins are enabled */
4229 /* bitmask=0x30f; */
4230 bitmask=0x302;
4231 /* check whether we have a PXC200A */
4232 if (btv->cardid == PX_PXC200A_CARDID) {
4233 bitmask ^= 0x180; /* use 7 and 9, not 8 and 9 */
4234 bitmask |= 7<<4; /* the DAC */
4235 }
4236 btwrite(bitmask, BT848_GPIO_OUT_EN);
4237
4238 bitmask = btread(BT848_GPIO_DATA);
4239 if (btv->cardid == PX_PXC200A_CARDID)
4240 bitmask = (bitmask & ~0x280) | ((mux & 2) << 8) | ((mux & 1) << 7);
4241 else /* older device */
4242 bitmask = (bitmask & ~0x300) | ((mux & 3) << 8);
4243 btwrite(bitmask,BT848_GPIO_DATA);
4244
4245 /*
4246 * Was "to be safe, set the bt848 to input 0"
4247 * Actually, since it's ok at load time, better not messing
4248 * with these bits (on PXC200AF you need to set mux 2 here)
4249 *
4250 * needed because bttv-driver sets mux before calling this function
4251 */
4252 if (btv->cardid == PX_PXC200A_CARDID)
4253 btaor(2<<5, ~BT848_IFORM_MUXSEL, BT848_IFORM);
4254 else /* older device */
4255 btand(~BT848_IFORM_MUXSEL,BT848_IFORM);
4256
4257 printk(KERN_DEBUG "bttv%d: setting input channel to:%d\n", btv->c.nr,(int)mux);
4258}
4259
4260/* ----------------------------------------------------------------------- */
4261/* motherboard chipset specific stuff */
4262
4263void __devinit bttv_check_chipset(void)
4264{
4265 int pcipci_fail = 0;
4266 struct pci_dev *dev = NULL;
4267
4268 if (pci_pci_problems & PCIPCI_FAIL)
4269 pcipci_fail = 1;
4270 if (pci_pci_problems & (PCIPCI_TRITON|PCIPCI_NATOMA|PCIPCI_VIAETBF))
4271 triton1 = 1;
4272 if (pci_pci_problems & PCIPCI_VSFX)
4273 vsfx = 1;
4274#ifdef PCIPCI_ALIMAGIK
4275 if (pci_pci_problems & PCIPCI_ALIMAGIK)
4276 latency = 0x0A;
4277#endif
4278
4279#if 0
4280 /* print which chipset we have */
4281 while ((dev = pci_find_class(PCI_CLASS_BRIDGE_HOST << 8,dev)))
4282 printk(KERN_INFO "bttv: Host bridge is %s\n",pci_name(dev));
4283#endif
4284
4285 /* print warnings about any quirks found */
4286 if (triton1)
4287 printk(KERN_INFO "bttv: Host bridge needs ETBF enabled.\n");
4288 if (vsfx)
4289 printk(KERN_INFO "bttv: Host bridge needs VSFX enabled.\n");
4290 if (pcipci_fail) {
4291 printk(KERN_WARNING "bttv: BT848 and your chipset may not work together.\n");
4292 if (UNSET == no_overlay) {
4293 printk(KERN_WARNING "bttv: going to disable overlay.\n");
4294 no_overlay = 1;
4295 }
4296 }
4297 if (UNSET != latency)
4298 printk(KERN_INFO "bttv: pci latency fixup [%d]\n",latency);
4299
4300 while ((dev = pci_find_device(PCI_VENDOR_ID_INTEL,
4301 PCI_DEVICE_ID_INTEL_82441, dev))) {
4302 unsigned char b;
4303 pci_read_config_byte(dev, 0x53, &b);
4304 if (bttv_debug)
4305 printk(KERN_INFO "bttv: Host bridge: 82441FX Natoma, "
4306 "bufcon=0x%02x\n",b);
4307 }
4308}
4309
4310int __devinit bttv_handle_chipset(struct bttv *btv)
4311{
4312 unsigned char command;
4313
4314 if (!triton1 && !vsfx && UNSET == latency)
4315 return 0;
4316
4317 if (bttv_verbose) {
4318 if (triton1)
4319 printk(KERN_INFO "bttv%d: enabling ETBF (430FX/VP3 compatibilty)\n",btv->c.nr);
4320 if (vsfx && btv->id >= 878)
4321 printk(KERN_INFO "bttv%d: enabling VSFX\n",btv->c.nr);
4322 if (UNSET != latency)
4323 printk(KERN_INFO "bttv%d: setting pci timer to %d\n",
4324 btv->c.nr,latency);
4325 }
4326
4327 if (btv->id < 878) {
4328 /* bt848 (mis)uses a bit in the irq mask for etbf */
4329 if (triton1)
4330 btv->triton1 = BT848_INT_ETBF;
4331 } else {
4332 /* bt878 has a bit in the pci config space for it */
4333 pci_read_config_byte(btv->c.pci, BT878_DEVCTRL, &command);
4334 if (triton1)
4335 command |= BT878_EN_TBFX;
4336 if (vsfx)
4337 command |= BT878_EN_VSFX;
4338 pci_write_config_byte(btv->c.pci, BT878_DEVCTRL, command);
4339 }
4340 if (UNSET != latency)
4341 pci_write_config_byte(btv->c.pci, PCI_LATENCY_TIMER, latency);
4342 return 0;
4343}
4344
4345
4346/*
4347 * Local variables:
4348 * c-basic-offset: 8
4349 * End:
4350 */
diff --git a/drivers/media/video/bttv-driver.c b/drivers/media/video/bttv-driver.c
new file mode 100644
index 00000000000..c13f222fe6b
--- /dev/null
+++ b/drivers/media/video/bttv-driver.c
@@ -0,0 +1,4116 @@
1/*
2 $Id: bttv-driver.c,v 1.37 2005/02/21 13:57:59 kraxel Exp $
3
4 bttv - Bt848 frame grabber driver
5
6 Copyright (C) 1996,97,98 Ralph Metzler <rjkm@thp.uni-koeln.de>
7 & Marcus Metzler <mocm@thp.uni-koeln.de>
8 (c) 1999-2002 Gerd Knorr <kraxel@bytesex.org>
9
10 some v4l2 code lines are taken from Justin's bttv2 driver which is
11 (c) 2000 Justin Schoeman <justin@suntiger.ee.up.ac.za>
12
13 This program is free software; you can redistribute it and/or modify
14 it under the terms of the GNU General Public License as published by
15 the Free Software Foundation; either version 2 of the License, or
16 (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26*/
27
28#include <linux/init.h>
29#include <linux/module.h>
30#include <linux/moduleparam.h>
31#include <linux/delay.h>
32#include <linux/errno.h>
33#include <linux/fs.h>
34#include <linux/kernel.h>
35#include <linux/sched.h>
36#include <linux/interrupt.h>
37#include <linux/kdev_t.h>
38
39#include <asm/io.h>
40#include <asm/byteorder.h>
41
42#include "bttvp.h"
43
44unsigned int bttv_num; /* number of Bt848s in use */
45struct bttv bttvs[BTTV_MAX];
46
47unsigned int bttv_debug = 0;
48unsigned int bttv_verbose = 1;
49unsigned int bttv_gpio = 0;
50
51/* config variables */
52#ifdef __BIG_ENDIAN
53static unsigned int bigendian=1;
54#else
55static unsigned int bigendian=0;
56#endif
57static unsigned int radio[BTTV_MAX];
58static unsigned int irq_debug = 0;
59static unsigned int gbuffers = 8;
60static unsigned int gbufsize = 0x208000;
61
62static int video_nr = -1;
63static int radio_nr = -1;
64static int vbi_nr = -1;
65static int debug_latency = 0;
66
67static unsigned int fdsr = 0;
68
69/* options */
70static unsigned int combfilter = 0;
71static unsigned int lumafilter = 0;
72static unsigned int automute = 1;
73static unsigned int chroma_agc = 0;
74static unsigned int adc_crush = 1;
75static unsigned int whitecrush_upper = 0xCF;
76static unsigned int whitecrush_lower = 0x7F;
77static unsigned int vcr_hack = 0;
78static unsigned int irq_iswitch = 0;
79
80/* API features (turn on/off stuff for testing) */
81static unsigned int v4l2 = 1;
82
83
84/* insmod args */
85module_param(bttv_verbose, int, 0644);
86module_param(bttv_gpio, int, 0644);
87module_param(bttv_debug, int, 0644);
88module_param(irq_debug, int, 0644);
89module_param(debug_latency, int, 0644);
90
91module_param(fdsr, int, 0444);
92module_param(video_nr, int, 0444);
93module_param(radio_nr, int, 0444);
94module_param(vbi_nr, int, 0444);
95module_param(gbuffers, int, 0444);
96module_param(gbufsize, int, 0444);
97
98module_param(v4l2, int, 0644);
99module_param(bigendian, int, 0644);
100module_param(irq_iswitch, int, 0644);
101module_param(combfilter, int, 0444);
102module_param(lumafilter, int, 0444);
103module_param(automute, int, 0444);
104module_param(chroma_agc, int, 0444);
105module_param(adc_crush, int, 0444);
106module_param(whitecrush_upper, int, 0444);
107module_param(whitecrush_lower, int, 0444);
108module_param(vcr_hack, int, 0444);
109
110module_param_array(radio, int, NULL, 0444);
111
112MODULE_PARM_DESC(radio,"The TV card supports radio, default is 0 (no)");
113MODULE_PARM_DESC(bigendian,"byte order of the framebuffer, default is native endian");
114MODULE_PARM_DESC(bttv_verbose,"verbose startup messages, default is 1 (yes)");
115MODULE_PARM_DESC(bttv_gpio,"log gpio changes, default is 0 (no)");
116MODULE_PARM_DESC(bttv_debug,"debug messages, default is 0 (no)");
117MODULE_PARM_DESC(irq_debug,"irq handler debug messages, default is 0 (no)");
118MODULE_PARM_DESC(gbuffers,"number of capture buffers. range 2-32, default 8");
119MODULE_PARM_DESC(gbufsize,"size of the capture buffers, default is 0x208000");
120MODULE_PARM_DESC(automute,"mute audio on bad/missing video signal, default is 1 (yes)");
121MODULE_PARM_DESC(chroma_agc,"enables the AGC of chroma signal, default is 0 (no)");
122MODULE_PARM_DESC(adc_crush,"enables the luminance ADC crush, default is 1 (yes)");
123MODULE_PARM_DESC(whitecrush_upper,"sets the white crush upper value, default is 207");
124MODULE_PARM_DESC(whitecrush_lower,"sets the white crush lower value, default is 127");
125MODULE_PARM_DESC(vcr_hack,"enables the VCR hack (improves synch on poor VCR tapes), default is 0 (no)");
126MODULE_PARM_DESC(irq_iswitch,"switch inputs in irq handler");
127
128MODULE_DESCRIPTION("bttv - v4l/v4l2 driver module for bt848/878 based cards");
129MODULE_AUTHOR("Ralph Metzler & Marcus Metzler & Gerd Knorr");
130MODULE_LICENSE("GPL");
131
132/* ----------------------------------------------------------------------- */
133/* sysfs */
134
135static ssize_t show_card(struct class_device *cd, char *buf)
136{
137 struct video_device *vfd = to_video_device(cd);
138 struct bttv *btv = dev_get_drvdata(vfd->dev);
139 return sprintf(buf, "%d\n", btv ? btv->c.type : UNSET);
140}
141static CLASS_DEVICE_ATTR(card, S_IRUGO, show_card, NULL);
142
143/* ----------------------------------------------------------------------- */
144/* static data */
145
146/* special timing tables from conexant... */
147static u8 SRAM_Table[][60] =
148{
149 /* PAL digital input over GPIO[7:0] */
150 {
151 45, // 45 bytes following
152 0x36,0x11,0x01,0x00,0x90,0x02,0x05,0x10,0x04,0x16,
153 0x12,0x05,0x11,0x00,0x04,0x12,0xC0,0x00,0x31,0x00,
154 0x06,0x51,0x08,0x03,0x89,0x08,0x07,0xC0,0x44,0x00,
155 0x81,0x01,0x01,0xA9,0x0D,0x02,0x02,0x50,0x03,0x37,
156 0x37,0x00,0xAF,0x21,0x00
157 },
158 /* NTSC digital input over GPIO[7:0] */
159 {
160 51, // 51 bytes following
161 0x0C,0xC0,0x00,0x00,0x90,0x02,0x03,0x10,0x03,0x06,
162 0x10,0x04,0x12,0x12,0x05,0x02,0x13,0x04,0x19,0x00,
163 0x04,0x39,0x00,0x06,0x59,0x08,0x03,0x83,0x08,0x07,
164 0x03,0x50,0x00,0xC0,0x40,0x00,0x86,0x01,0x01,0xA6,
165 0x0D,0x02,0x03,0x11,0x01,0x05,0x37,0x00,0xAC,0x21,
166 0x00,
167 },
168 // TGB_NTSC392 // quartzsight
169 // This table has been modified to be used for Fusion Rev D
170 {
171 0x2A, // size of table = 42
172 0x06, 0x08, 0x04, 0x0a, 0xc0, 0x00, 0x18, 0x08, 0x03, 0x24,
173 0x08, 0x07, 0x02, 0x90, 0x02, 0x08, 0x10, 0x04, 0x0c, 0x10,
174 0x05, 0x2c, 0x11, 0x04, 0x55, 0x48, 0x00, 0x05, 0x50, 0x00,
175 0xbf, 0x0c, 0x02, 0x2f, 0x3d, 0x00, 0x2f, 0x3f, 0x00, 0xc3,
176 0x20, 0x00
177 }
178};
179
180const struct bttv_tvnorm bttv_tvnorms[] = {
181 /* PAL-BDGHI */
182 /* max. active video is actually 922, but 924 is divisible by 4 and 3! */
183 /* actually, max active PAL with HSCALE=0 is 948, NTSC is 768 - nil */
184 {
185 .v4l2_id = V4L2_STD_PAL,
186 .name = "PAL",
187 .Fsc = 35468950,
188 .swidth = 924,
189 .sheight = 576,
190 .totalwidth = 1135,
191 .adelay = 0x7f,
192 .bdelay = 0x72,
193 .iform = (BT848_IFORM_PAL_BDGHI|BT848_IFORM_XT1),
194 .scaledtwidth = 1135,
195 .hdelayx1 = 186,
196 .hactivex1 = 924,
197 .vdelay = 0x20,
198 .vbipack = 255,
199 .sram = 0,
200 },{
201 .v4l2_id = V4L2_STD_NTSC_M,
202 .name = "NTSC",
203 .Fsc = 28636363,
204 .swidth = 768,
205 .sheight = 480,
206 .totalwidth = 910,
207 .adelay = 0x68,
208 .bdelay = 0x5d,
209 .iform = (BT848_IFORM_NTSC|BT848_IFORM_XT0),
210 .scaledtwidth = 910,
211 .hdelayx1 = 128,
212 .hactivex1 = 910,
213 .vdelay = 0x1a,
214 .vbipack = 144,
215 .sram = 1,
216 },{
217 .v4l2_id = V4L2_STD_SECAM,
218 .name = "SECAM",
219 .Fsc = 35468950,
220 .swidth = 924,
221 .sheight = 576,
222 .totalwidth = 1135,
223 .adelay = 0x7f,
224 .bdelay = 0xb0,
225 .iform = (BT848_IFORM_SECAM|BT848_IFORM_XT1),
226 .scaledtwidth = 1135,
227 .hdelayx1 = 186,
228 .hactivex1 = 922,
229 .vdelay = 0x20,
230 .vbipack = 255,
231 .sram = 0, /* like PAL, correct? */
232 },{
233 .v4l2_id = V4L2_STD_PAL_Nc,
234 .name = "PAL-Nc",
235 .Fsc = 28636363,
236 .swidth = 640,
237 .sheight = 576,
238 .totalwidth = 910,
239 .adelay = 0x68,
240 .bdelay = 0x5d,
241 .iform = (BT848_IFORM_PAL_NC|BT848_IFORM_XT0),
242 .scaledtwidth = 780,
243 .hdelayx1 = 130,
244 .hactivex1 = 734,
245 .vdelay = 0x1a,
246 .vbipack = 144,
247 .sram = -1,
248 },{
249 .v4l2_id = V4L2_STD_PAL_M,
250 .name = "PAL-M",
251 .Fsc = 28636363,
252 .swidth = 640,
253 .sheight = 480,
254 .totalwidth = 910,
255 .adelay = 0x68,
256 .bdelay = 0x5d,
257 .iform = (BT848_IFORM_PAL_M|BT848_IFORM_XT0),
258 .scaledtwidth = 780,
259 .hdelayx1 = 135,
260 .hactivex1 = 754,
261 .vdelay = 0x1a,
262 .vbipack = 144,
263 .sram = -1,
264 },{
265 .v4l2_id = V4L2_STD_PAL_N,
266 .name = "PAL-N",
267 .Fsc = 35468950,
268 .swidth = 768,
269 .sheight = 576,
270 .totalwidth = 1135,
271 .adelay = 0x7f,
272 .bdelay = 0x72,
273 .iform = (BT848_IFORM_PAL_N|BT848_IFORM_XT1),
274 .scaledtwidth = 944,
275 .hdelayx1 = 186,
276 .hactivex1 = 922,
277 .vdelay = 0x20,
278 .vbipack = 144,
279 .sram = -1,
280 },{
281 .v4l2_id = V4L2_STD_NTSC_M_JP,
282 .name = "NTSC-JP",
283 .Fsc = 28636363,
284 .swidth = 640,
285 .sheight = 480,
286 .totalwidth = 910,
287 .adelay = 0x68,
288 .bdelay = 0x5d,
289 .iform = (BT848_IFORM_NTSC_J|BT848_IFORM_XT0),
290 .scaledtwidth = 780,
291 .hdelayx1 = 135,
292 .hactivex1 = 754,
293 .vdelay = 0x16,
294 .vbipack = 144,
295 .sram = -1,
296 },{
297 /* that one hopefully works with the strange timing
298 * which video recorders produce when playing a NTSC
299 * tape on a PAL TV ... */
300 .v4l2_id = V4L2_STD_PAL_60,
301 .name = "PAL-60",
302 .Fsc = 35468950,
303 .swidth = 924,
304 .sheight = 480,
305 .totalwidth = 1135,
306 .adelay = 0x7f,
307 .bdelay = 0x72,
308 .iform = (BT848_IFORM_PAL_BDGHI|BT848_IFORM_XT1),
309 .scaledtwidth = 1135,
310 .hdelayx1 = 186,
311 .hactivex1 = 924,
312 .vdelay = 0x1a,
313 .vbipack = 255,
314 .vtotal = 524,
315 .sram = -1,
316 }
317};
318static const unsigned int BTTV_TVNORMS = ARRAY_SIZE(bttv_tvnorms);
319
320/* ----------------------------------------------------------------------- */
321/* bttv format list
322 packed pixel formats must come first */
323static const struct bttv_format bttv_formats[] = {
324 {
325 .name = "8 bpp, gray",
326 .palette = VIDEO_PALETTE_GREY,
327 .fourcc = V4L2_PIX_FMT_GREY,
328 .btformat = BT848_COLOR_FMT_Y8,
329 .depth = 8,
330 .flags = FORMAT_FLAGS_PACKED,
331 },{
332 .name = "8 bpp, dithered color",
333 .palette = VIDEO_PALETTE_HI240,
334 .fourcc = V4L2_PIX_FMT_HI240,
335 .btformat = BT848_COLOR_FMT_RGB8,
336 .depth = 8,
337 .flags = FORMAT_FLAGS_PACKED | FORMAT_FLAGS_DITHER,
338 },{
339 .name = "15 bpp RGB, le",
340 .palette = VIDEO_PALETTE_RGB555,
341 .fourcc = V4L2_PIX_FMT_RGB555,
342 .btformat = BT848_COLOR_FMT_RGB15,
343 .depth = 16,
344 .flags = FORMAT_FLAGS_PACKED,
345 },{
346 .name = "15 bpp RGB, be",
347 .palette = -1,
348 .fourcc = V4L2_PIX_FMT_RGB555X,
349 .btformat = BT848_COLOR_FMT_RGB15,
350 .btswap = 0x03, /* byteswap */
351 .depth = 16,
352 .flags = FORMAT_FLAGS_PACKED,
353 },{
354 .name = "16 bpp RGB, le",
355 .palette = VIDEO_PALETTE_RGB565,
356 .fourcc = V4L2_PIX_FMT_RGB565,
357 .btformat = BT848_COLOR_FMT_RGB16,
358 .depth = 16,
359 .flags = FORMAT_FLAGS_PACKED,
360 },{
361 .name = "16 bpp RGB, be",
362 .palette = -1,
363 .fourcc = V4L2_PIX_FMT_RGB565X,
364 .btformat = BT848_COLOR_FMT_RGB16,
365 .btswap = 0x03, /* byteswap */
366 .depth = 16,
367 .flags = FORMAT_FLAGS_PACKED,
368 },{
369 .name = "24 bpp RGB, le",
370 .palette = VIDEO_PALETTE_RGB24,
371 .fourcc = V4L2_PIX_FMT_BGR24,
372 .btformat = BT848_COLOR_FMT_RGB24,
373 .depth = 24,
374 .flags = FORMAT_FLAGS_PACKED,
375 },{
376 .name = "32 bpp RGB, le",
377 .palette = VIDEO_PALETTE_RGB32,
378 .fourcc = V4L2_PIX_FMT_BGR32,
379 .btformat = BT848_COLOR_FMT_RGB32,
380 .depth = 32,
381 .flags = FORMAT_FLAGS_PACKED,
382 },{
383 .name = "32 bpp RGB, be",
384 .palette = -1,
385 .fourcc = V4L2_PIX_FMT_RGB32,
386 .btformat = BT848_COLOR_FMT_RGB32,
387 .btswap = 0x0f, /* byte+word swap */
388 .depth = 32,
389 .flags = FORMAT_FLAGS_PACKED,
390 },{
391 .name = "4:2:2, packed, YUYV",
392 .palette = VIDEO_PALETTE_YUV422,
393 .fourcc = V4L2_PIX_FMT_YUYV,
394 .btformat = BT848_COLOR_FMT_YUY2,
395 .depth = 16,
396 .flags = FORMAT_FLAGS_PACKED,
397 },{
398 .name = "4:2:2, packed, YUYV",
399 .palette = VIDEO_PALETTE_YUYV,
400 .fourcc = V4L2_PIX_FMT_YUYV,
401 .btformat = BT848_COLOR_FMT_YUY2,
402 .depth = 16,
403 .flags = FORMAT_FLAGS_PACKED,
404 },{
405 .name = "4:2:2, packed, UYVY",
406 .palette = VIDEO_PALETTE_UYVY,
407 .fourcc = V4L2_PIX_FMT_UYVY,
408 .btformat = BT848_COLOR_FMT_YUY2,
409 .btswap = 0x03, /* byteswap */
410 .depth = 16,
411 .flags = FORMAT_FLAGS_PACKED,
412 },{
413 .name = "4:2:2, planar, Y-Cb-Cr",
414 .palette = VIDEO_PALETTE_YUV422P,
415 .fourcc = V4L2_PIX_FMT_YUV422P,
416 .btformat = BT848_COLOR_FMT_YCrCb422,
417 .depth = 16,
418 .flags = FORMAT_FLAGS_PLANAR,
419 .hshift = 1,
420 .vshift = 0,
421 },{
422 .name = "4:2:0, planar, Y-Cb-Cr",
423 .palette = VIDEO_PALETTE_YUV420P,
424 .fourcc = V4L2_PIX_FMT_YUV420,
425 .btformat = BT848_COLOR_FMT_YCrCb422,
426 .depth = 12,
427 .flags = FORMAT_FLAGS_PLANAR,
428 .hshift = 1,
429 .vshift = 1,
430 },{
431 .name = "4:2:0, planar, Y-Cr-Cb",
432 .palette = -1,
433 .fourcc = V4L2_PIX_FMT_YVU420,
434 .btformat = BT848_COLOR_FMT_YCrCb422,
435 .depth = 12,
436 .flags = FORMAT_FLAGS_PLANAR | FORMAT_FLAGS_CrCb,
437 .hshift = 1,
438 .vshift = 1,
439 },{
440 .name = "4:1:1, planar, Y-Cb-Cr",
441 .palette = VIDEO_PALETTE_YUV411P,
442 .fourcc = V4L2_PIX_FMT_YUV411P,
443 .btformat = BT848_COLOR_FMT_YCrCb411,
444 .depth = 12,
445 .flags = FORMAT_FLAGS_PLANAR,
446 .hshift = 2,
447 .vshift = 0,
448 },{
449 .name = "4:1:0, planar, Y-Cb-Cr",
450 .palette = VIDEO_PALETTE_YUV410P,
451 .fourcc = V4L2_PIX_FMT_YUV410,
452 .btformat = BT848_COLOR_FMT_YCrCb411,
453 .depth = 9,
454 .flags = FORMAT_FLAGS_PLANAR,
455 .hshift = 2,
456 .vshift = 2,
457 },{
458 .name = "4:1:0, planar, Y-Cr-Cb",
459 .palette = -1,
460 .fourcc = V4L2_PIX_FMT_YVU410,
461 .btformat = BT848_COLOR_FMT_YCrCb411,
462 .depth = 9,
463 .flags = FORMAT_FLAGS_PLANAR | FORMAT_FLAGS_CrCb,
464 .hshift = 2,
465 .vshift = 2,
466 },{
467 .name = "raw scanlines",
468 .palette = VIDEO_PALETTE_RAW,
469 .fourcc = -1,
470 .btformat = BT848_COLOR_FMT_RAW,
471 .depth = 8,
472 .flags = FORMAT_FLAGS_RAW,
473 }
474};
475static const unsigned int BTTV_FORMATS = ARRAY_SIZE(bttv_formats);
476
477/* ----------------------------------------------------------------------- */
478
479#define V4L2_CID_PRIVATE_CHROMA_AGC (V4L2_CID_PRIVATE_BASE + 0)
480#define V4L2_CID_PRIVATE_COMBFILTER (V4L2_CID_PRIVATE_BASE + 1)
481#define V4L2_CID_PRIVATE_AUTOMUTE (V4L2_CID_PRIVATE_BASE + 2)
482#define V4L2_CID_PRIVATE_LUMAFILTER (V4L2_CID_PRIVATE_BASE + 3)
483#define V4L2_CID_PRIVATE_AGC_CRUSH (V4L2_CID_PRIVATE_BASE + 4)
484#define V4L2_CID_PRIVATE_VCR_HACK (V4L2_CID_PRIVATE_BASE + 5)
485#define V4L2_CID_PRIVATE_WHITECRUSH_UPPER (V4L2_CID_PRIVATE_BASE + 6)
486#define V4L2_CID_PRIVATE_WHITECRUSH_LOWER (V4L2_CID_PRIVATE_BASE + 7)
487#define V4L2_CID_PRIVATE_LASTP1 (V4L2_CID_PRIVATE_BASE + 8)
488
489static const struct v4l2_queryctrl no_ctl = {
490 .name = "42",
491 .flags = V4L2_CTRL_FLAG_DISABLED,
492};
493static const struct v4l2_queryctrl bttv_ctls[] = {
494 /* --- video --- */
495 {
496 .id = V4L2_CID_BRIGHTNESS,
497 .name = "Brightness",
498 .minimum = 0,
499 .maximum = 65535,
500 .step = 256,
501 .default_value = 32768,
502 .type = V4L2_CTRL_TYPE_INTEGER,
503 },{
504 .id = V4L2_CID_CONTRAST,
505 .name = "Contrast",
506 .minimum = 0,
507 .maximum = 65535,
508 .step = 128,
509 .default_value = 32768,
510 .type = V4L2_CTRL_TYPE_INTEGER,
511 },{
512 .id = V4L2_CID_SATURATION,
513 .name = "Saturation",
514 .minimum = 0,
515 .maximum = 65535,
516 .step = 128,
517 .default_value = 32768,
518 .type = V4L2_CTRL_TYPE_INTEGER,
519 },{
520 .id = V4L2_CID_HUE,
521 .name = "Hue",
522 .minimum = 0,
523 .maximum = 65535,
524 .step = 256,
525 .default_value = 32768,
526 .type = V4L2_CTRL_TYPE_INTEGER,
527 },
528 /* --- audio --- */
529 {
530 .id = V4L2_CID_AUDIO_MUTE,
531 .name = "Mute",
532 .minimum = 0,
533 .maximum = 1,
534 .type = V4L2_CTRL_TYPE_BOOLEAN,
535 },{
536 .id = V4L2_CID_AUDIO_VOLUME,
537 .name = "Volume",
538 .minimum = 0,
539 .maximum = 65535,
540 .step = 65535/100,
541 .default_value = 65535,
542 .type = V4L2_CTRL_TYPE_INTEGER,
543 },{
544 .id = V4L2_CID_AUDIO_BALANCE,
545 .name = "Balance",
546 .minimum = 0,
547 .maximum = 65535,
548 .step = 65535/100,
549 .default_value = 32768,
550 .type = V4L2_CTRL_TYPE_INTEGER,
551 },{
552 .id = V4L2_CID_AUDIO_BASS,
553 .name = "Bass",
554 .minimum = 0,
555 .maximum = 65535,
556 .step = 65535/100,
557 .default_value = 32768,
558 .type = V4L2_CTRL_TYPE_INTEGER,
559 },{
560 .id = V4L2_CID_AUDIO_TREBLE,
561 .name = "Treble",
562 .minimum = 0,
563 .maximum = 65535,
564 .step = 65535/100,
565 .default_value = 32768,
566 .type = V4L2_CTRL_TYPE_INTEGER,
567 },
568 /* --- private --- */
569 {
570 .id = V4L2_CID_PRIVATE_CHROMA_AGC,
571 .name = "chroma agc",
572 .minimum = 0,
573 .maximum = 1,
574 .type = V4L2_CTRL_TYPE_BOOLEAN,
575 },{
576 .id = V4L2_CID_PRIVATE_COMBFILTER,
577 .name = "combfilter",
578 .minimum = 0,
579 .maximum = 1,
580 .type = V4L2_CTRL_TYPE_BOOLEAN,
581 },{
582 .id = V4L2_CID_PRIVATE_AUTOMUTE,
583 .name = "automute",
584 .minimum = 0,
585 .maximum = 1,
586 .type = V4L2_CTRL_TYPE_BOOLEAN,
587 },{
588 .id = V4L2_CID_PRIVATE_LUMAFILTER,
589 .name = "luma decimation filter",
590 .minimum = 0,
591 .maximum = 1,
592 .type = V4L2_CTRL_TYPE_BOOLEAN,
593 },{
594 .id = V4L2_CID_PRIVATE_AGC_CRUSH,
595 .name = "agc crush",
596 .minimum = 0,
597 .maximum = 1,
598 .type = V4L2_CTRL_TYPE_BOOLEAN,
599 },{
600 .id = V4L2_CID_PRIVATE_VCR_HACK,
601 .name = "vcr hack",
602 .minimum = 0,
603 .maximum = 1,
604 .type = V4L2_CTRL_TYPE_BOOLEAN,
605 },{
606 .id = V4L2_CID_PRIVATE_WHITECRUSH_UPPER,
607 .name = "whitecrush upper",
608 .minimum = 0,
609 .maximum = 255,
610 .step = 1,
611 .default_value = 0xCF,
612 .type = V4L2_CTRL_TYPE_INTEGER,
613 },{
614 .id = V4L2_CID_PRIVATE_WHITECRUSH_LOWER,
615 .name = "whitecrush lower",
616 .minimum = 0,
617 .maximum = 255,
618 .step = 1,
619 .default_value = 0x7F,
620 .type = V4L2_CTRL_TYPE_INTEGER,
621 }
622
623};
624static const int BTTV_CTLS = ARRAY_SIZE(bttv_ctls);
625
626/* ----------------------------------------------------------------------- */
627/* resource management */
628
629static
630int check_alloc_btres(struct bttv *btv, struct bttv_fh *fh, int bit)
631{
632 if (fh->resources & bit)
633 /* have it already allocated */
634 return 1;
635
636 /* is it free? */
637 down(&btv->reslock);
638 if (btv->resources & bit) {
639 /* no, someone else uses it */
640 up(&btv->reslock);
641 return 0;
642 }
643 /* it's free, grab it */
644 fh->resources |= bit;
645 btv->resources |= bit;
646 up(&btv->reslock);
647 return 1;
648}
649
650static
651int check_btres(struct bttv_fh *fh, int bit)
652{
653 return (fh->resources & bit);
654}
655
656static
657int locked_btres(struct bttv *btv, int bit)
658{
659 return (btv->resources & bit);
660}
661
662static
663void free_btres(struct bttv *btv, struct bttv_fh *fh, int bits)
664{
665#if 1 /* DEBUG */
666 if ((fh->resources & bits) != bits) {
667 /* trying to free ressources not allocated by us ... */
668 printk("bttv: BUG! (btres)\n");
669 }
670#endif
671 down(&btv->reslock);
672 fh->resources &= ~bits;
673 btv->resources &= ~bits;
674 up(&btv->reslock);
675}
676
677/* ----------------------------------------------------------------------- */
678/* If Bt848a or Bt849, use PLL for PAL/SECAM and crystal for NTSC */
679
680/* Frequency = (F_input / PLL_X) * PLL_I.PLL_F/PLL_C
681 PLL_X = Reference pre-divider (0=1, 1=2)
682 PLL_C = Post divider (0=6, 1=4)
683 PLL_I = Integer input
684 PLL_F = Fractional input
685
686 F_input = 28.636363 MHz:
687 PAL (CLKx2 = 35.46895 MHz): PLL_X = 1, PLL_I = 0x0E, PLL_F = 0xDCF9, PLL_C = 0
688*/
689
690static void set_pll_freq(struct bttv *btv, unsigned int fin, unsigned int fout)
691{
692 unsigned char fl, fh, fi;
693
694 /* prevent overflows */
695 fin/=4;
696 fout/=4;
697
698 fout*=12;
699 fi=fout/fin;
700
701 fout=(fout%fin)*256;
702 fh=fout/fin;
703
704 fout=(fout%fin)*256;
705 fl=fout/fin;
706
707 btwrite(fl, BT848_PLL_F_LO);
708 btwrite(fh, BT848_PLL_F_HI);
709 btwrite(fi|BT848_PLL_X, BT848_PLL_XCI);
710}
711
712static void set_pll(struct bttv *btv)
713{
714 int i;
715
716 if (!btv->pll.pll_crystal)
717 return;
718
719 if (btv->pll.pll_ofreq == btv->pll.pll_current) {
720 dprintk("bttv%d: PLL: no change required\n",btv->c.nr);
721 return;
722 }
723
724 if (btv->pll.pll_ifreq == btv->pll.pll_ofreq) {
725 /* no PLL needed */
726 if (btv->pll.pll_current == 0)
727 return;
728 vprintk(KERN_INFO "bttv%d: PLL can sleep, using XTAL (%d).\n",
729 btv->c.nr,btv->pll.pll_ifreq);
730 btwrite(0x00,BT848_TGCTRL);
731 btwrite(0x00,BT848_PLL_XCI);
732 btv->pll.pll_current = 0;
733 return;
734 }
735
736 vprintk(KERN_INFO "bttv%d: PLL: %d => %d ",btv->c.nr,
737 btv->pll.pll_ifreq, btv->pll.pll_ofreq);
738 set_pll_freq(btv, btv->pll.pll_ifreq, btv->pll.pll_ofreq);
739
740 for (i=0; i<10; i++) {
741 /* Let other people run while the PLL stabilizes */
742 vprintk(".");
743 msleep(10);
744
745 if (btread(BT848_DSTATUS) & BT848_DSTATUS_PLOCK) {
746 btwrite(0,BT848_DSTATUS);
747 } else {
748 btwrite(0x08,BT848_TGCTRL);
749 btv->pll.pll_current = btv->pll.pll_ofreq;
750 vprintk(" ok\n");
751 return;
752 }
753 }
754 btv->pll.pll_current = -1;
755 vprintk("failed\n");
756 return;
757}
758
759/* used to switch between the bt848's analog/digital video capture modes */
760static void bt848A_set_timing(struct bttv *btv)
761{
762 int i, len;
763 int table_idx = bttv_tvnorms[btv->tvnorm].sram;
764 int fsc = bttv_tvnorms[btv->tvnorm].Fsc;
765
766 if (UNSET == bttv_tvcards[btv->c.type].muxsel[btv->input]) {
767 dprintk("bttv%d: load digital timing table (table_idx=%d)\n",
768 btv->c.nr,table_idx);
769
770 /* timing change...reset timing generator address */
771 btwrite(0x00, BT848_TGCTRL);
772 btwrite(0x02, BT848_TGCTRL);
773 btwrite(0x00, BT848_TGCTRL);
774
775 len=SRAM_Table[table_idx][0];
776 for(i = 1; i <= len; i++)
777 btwrite(SRAM_Table[table_idx][i],BT848_TGLB);
778 btv->pll.pll_ofreq = 27000000;
779
780 set_pll(btv);
781 btwrite(0x11, BT848_TGCTRL);
782 btwrite(0x41, BT848_DVSIF);
783 } else {
784 btv->pll.pll_ofreq = fsc;
785 set_pll(btv);
786 btwrite(0x0, BT848_DVSIF);
787 }
788}
789
790/* ----------------------------------------------------------------------- */
791
792static void bt848_bright(struct bttv *btv, int bright)
793{
794 int value;
795
796 // printk("bttv: set bright: %d\n",bright); // DEBUG
797 btv->bright = bright;
798
799 /* We want -128 to 127 we get 0-65535 */
800 value = (bright >> 8) - 128;
801 btwrite(value & 0xff, BT848_BRIGHT);
802}
803
804static void bt848_hue(struct bttv *btv, int hue)
805{
806 int value;
807
808 btv->hue = hue;
809
810 /* -128 to 127 */
811 value = (hue >> 8) - 128;
812 btwrite(value & 0xff, BT848_HUE);
813}
814
815static void bt848_contrast(struct bttv *btv, int cont)
816{
817 int value,hibit;
818
819 btv->contrast = cont;
820
821 /* 0-511 */
822 value = (cont >> 7);
823 hibit = (value >> 6) & 4;
824 btwrite(value & 0xff, BT848_CONTRAST_LO);
825 btaor(hibit, ~4, BT848_E_CONTROL);
826 btaor(hibit, ~4, BT848_O_CONTROL);
827}
828
829static void bt848_sat(struct bttv *btv, int color)
830{
831 int val_u,val_v,hibits;
832
833 btv->saturation = color;
834
835 /* 0-511 for the color */
836 val_u = color >> 7;
837 val_v = ((color>>7)*180L)/254;
838 hibits = (val_u >> 7) & 2;
839 hibits |= (val_v >> 8) & 1;
840 btwrite(val_u & 0xff, BT848_SAT_U_LO);
841 btwrite(val_v & 0xff, BT848_SAT_V_LO);
842 btaor(hibits, ~3, BT848_E_CONTROL);
843 btaor(hibits, ~3, BT848_O_CONTROL);
844}
845
846/* ----------------------------------------------------------------------- */
847
848static int
849video_mux(struct bttv *btv, unsigned int input)
850{
851 int mux,mask2;
852
853 if (input >= bttv_tvcards[btv->c.type].video_inputs)
854 return -EINVAL;
855
856 /* needed by RemoteVideo MX */
857 mask2 = bttv_tvcards[btv->c.type].gpiomask2;
858 if (mask2)
859 gpio_inout(mask2,mask2);
860
861 if (input == btv->svhs) {
862 btor(BT848_CONTROL_COMP, BT848_E_CONTROL);
863 btor(BT848_CONTROL_COMP, BT848_O_CONTROL);
864 } else {
865 btand(~BT848_CONTROL_COMP, BT848_E_CONTROL);
866 btand(~BT848_CONTROL_COMP, BT848_O_CONTROL);
867 }
868 mux = bttv_tvcards[btv->c.type].muxsel[input] & 3;
869 btaor(mux<<5, ~(3<<5), BT848_IFORM);
870 dprintk(KERN_DEBUG "bttv%d: video mux: input=%d mux=%d\n",
871 btv->c.nr,input,mux);
872
873 /* card specific hook */
874 if(bttv_tvcards[btv->c.type].muxsel_hook)
875 bttv_tvcards[btv->c.type].muxsel_hook (btv, input);
876 return 0;
877}
878
879static char *audio_modes[] = {
880 "audio: tuner", "audio: radio", "audio: extern",
881 "audio: intern", "audio: off"
882};
883
884static int
885audio_mux(struct bttv *btv, int mode)
886{
887 int val,mux,i2c_mux,signal;
888
889 gpio_inout(bttv_tvcards[btv->c.type].gpiomask,
890 bttv_tvcards[btv->c.type].gpiomask);
891 signal = btread(BT848_DSTATUS) & BT848_DSTATUS_HLOC;
892
893 switch (mode) {
894 case AUDIO_MUTE:
895 btv->audio |= AUDIO_MUTE;
896 break;
897 case AUDIO_UNMUTE:
898 btv->audio &= ~AUDIO_MUTE;
899 break;
900 case AUDIO_TUNER:
901 case AUDIO_RADIO:
902 case AUDIO_EXTERN:
903 case AUDIO_INTERN:
904 btv->audio &= AUDIO_MUTE;
905 btv->audio |= mode;
906 }
907 i2c_mux = mux = (btv->audio & AUDIO_MUTE) ? AUDIO_OFF : btv->audio;
908 if (btv->opt_automute && !signal && !btv->radio_user)
909 mux = AUDIO_OFF;
910#if 0
911 printk("bttv%d: amux: mode=%d audio=%d signal=%s mux=%d/%d irq=%s\n",
912 btv->c.nr, mode, btv->audio, signal ? "yes" : "no",
913 mux, i2c_mux, in_interrupt() ? "yes" : "no");
914#endif
915
916 val = bttv_tvcards[btv->c.type].audiomux[mux];
917 gpio_bits(bttv_tvcards[btv->c.type].gpiomask,val);
918 if (bttv_gpio)
919 bttv_gpio_tracking(btv,audio_modes[mux]);
920 if (!in_interrupt())
921 bttv_call_i2c_clients(btv,AUDC_SET_INPUT,&(i2c_mux));
922 return 0;
923}
924
925static void
926i2c_vidiocschan(struct bttv *btv)
927{
928 struct video_channel c;
929
930 memset(&c,0,sizeof(c));
931 c.norm = btv->tvnorm;
932 c.channel = btv->input;
933 bttv_call_i2c_clients(btv,VIDIOCSCHAN,&c);
934 if (btv->c.type == BTTV_VOODOOTV_FM)
935 bttv_tda9880_setnorm(btv,c.norm);
936}
937
938static int
939set_tvnorm(struct bttv *btv, unsigned int norm)
940{
941 const struct bttv_tvnorm *tvnorm;
942
943 if (norm < 0 || norm >= BTTV_TVNORMS)
944 return -EINVAL;
945
946 btv->tvnorm = norm;
947 tvnorm = &bttv_tvnorms[norm];
948
949 btwrite(tvnorm->adelay, BT848_ADELAY);
950 btwrite(tvnorm->bdelay, BT848_BDELAY);
951 btaor(tvnorm->iform,~(BT848_IFORM_NORM|BT848_IFORM_XTBOTH),
952 BT848_IFORM);
953 btwrite(tvnorm->vbipack, BT848_VBI_PACK_SIZE);
954 btwrite(1, BT848_VBI_PACK_DEL);
955 bt848A_set_timing(btv);
956
957 switch (btv->c.type) {
958 case BTTV_VOODOOTV_FM:
959 bttv_tda9880_setnorm(btv,norm);
960 break;
961#if 0
962 case BTTV_OSPREY540:
963 osprey_540_set_norm(btv,norm);
964 break;
965#endif
966 }
967 return 0;
968}
969
970static void
971set_input(struct bttv *btv, unsigned int input)
972{
973 unsigned long flags;
974
975 btv->input = input;
976 if (irq_iswitch) {
977 spin_lock_irqsave(&btv->s_lock,flags);
978 if (btv->curr.frame_irq) {
979 /* active capture -> delayed input switch */
980 btv->new_input = input;
981 } else {
982 video_mux(btv,input);
983 }
984 spin_unlock_irqrestore(&btv->s_lock,flags);
985 } else {
986 video_mux(btv,input);
987 }
988 audio_mux(btv,(input == bttv_tvcards[btv->c.type].tuner ?
989 AUDIO_TUNER : AUDIO_EXTERN));
990 set_tvnorm(btv,btv->tvnorm);
991 i2c_vidiocschan(btv);
992}
993
994static void init_irqreg(struct bttv *btv)
995{
996 /* clear status */
997 btwrite(0xfffffUL, BT848_INT_STAT);
998
999 if (bttv_tvcards[btv->c.type].no_video) {
1000 /* i2c only */
1001 btwrite(BT848_INT_I2CDONE,
1002 BT848_INT_MASK);
1003 } else {
1004 /* full video */
1005 btwrite((btv->triton1) |
1006 (btv->gpioirq ? BT848_INT_GPINT : 0) |
1007 BT848_INT_SCERR |
1008 (fdsr ? BT848_INT_FDSR : 0) |
1009 BT848_INT_RISCI|BT848_INT_OCERR|BT848_INT_VPRES|
1010 BT848_INT_FMTCHG|BT848_INT_HLOCK|
1011 BT848_INT_I2CDONE,
1012 BT848_INT_MASK);
1013 }
1014}
1015
1016static void init_bt848(struct bttv *btv)
1017{
1018 int val;
1019
1020 if (bttv_tvcards[btv->c.type].no_video) {
1021 /* very basic init only */
1022 init_irqreg(btv);
1023 return;
1024 }
1025
1026 btwrite(0x00, BT848_CAP_CTL);
1027 btwrite(BT848_COLOR_CTL_GAMMA, BT848_COLOR_CTL);
1028 btwrite(BT848_IFORM_XTAUTO | BT848_IFORM_AUTO, BT848_IFORM);
1029
1030 /* set planar and packed mode trigger points and */
1031 /* set rising edge of inverted GPINTR pin as irq trigger */
1032 btwrite(BT848_GPIO_DMA_CTL_PKTP_32|
1033 BT848_GPIO_DMA_CTL_PLTP1_16|
1034 BT848_GPIO_DMA_CTL_PLTP23_16|
1035 BT848_GPIO_DMA_CTL_GPINTC|
1036 BT848_GPIO_DMA_CTL_GPINTI,
1037 BT848_GPIO_DMA_CTL);
1038
1039 val = btv->opt_chroma_agc ? BT848_SCLOOP_CAGC : 0;
1040 btwrite(val, BT848_E_SCLOOP);
1041 btwrite(val, BT848_O_SCLOOP);
1042
1043 btwrite(0x20, BT848_E_VSCALE_HI);
1044 btwrite(0x20, BT848_O_VSCALE_HI);
1045 btwrite(BT848_ADC_RESERVED | (btv->opt_adc_crush ? BT848_ADC_CRUSH : 0),
1046 BT848_ADC);
1047
1048 btwrite(whitecrush_upper, BT848_WC_UP);
1049 btwrite(whitecrush_lower, BT848_WC_DOWN);
1050
1051 if (btv->opt_lumafilter) {
1052 btwrite(0, BT848_E_CONTROL);
1053 btwrite(0, BT848_O_CONTROL);
1054 } else {
1055 btwrite(BT848_CONTROL_LDEC, BT848_E_CONTROL);
1056 btwrite(BT848_CONTROL_LDEC, BT848_O_CONTROL);
1057 }
1058
1059 bt848_bright(btv, btv->bright);
1060 bt848_hue(btv, btv->hue);
1061 bt848_contrast(btv, btv->contrast);
1062 bt848_sat(btv, btv->saturation);
1063
1064 /* interrupt */
1065 init_irqreg(btv);
1066}
1067
1068static void bttv_reinit_bt848(struct bttv *btv)
1069{
1070 unsigned long flags;
1071
1072 if (bttv_verbose)
1073 printk(KERN_INFO "bttv%d: reset, reinitialize\n",btv->c.nr);
1074 spin_lock_irqsave(&btv->s_lock,flags);
1075 btv->errors=0;
1076 bttv_set_dma(btv,0);
1077 spin_unlock_irqrestore(&btv->s_lock,flags);
1078
1079 init_bt848(btv);
1080 btv->pll.pll_current = -1;
1081 set_input(btv,btv->input);
1082}
1083
1084static int get_control(struct bttv *btv, struct v4l2_control *c)
1085{
1086 struct video_audio va;
1087 int i;
1088
1089 for (i = 0; i < BTTV_CTLS; i++)
1090 if (bttv_ctls[i].id == c->id)
1091 break;
1092 if (i == BTTV_CTLS)
1093 return -EINVAL;
1094 if (i >= 4 && i <= 8) {
1095 memset(&va,0,sizeof(va));
1096 bttv_call_i2c_clients(btv, VIDIOCGAUDIO, &va);
1097 if (btv->audio_hook)
1098 btv->audio_hook(btv,&va,0);
1099 }
1100 switch (c->id) {
1101 case V4L2_CID_BRIGHTNESS:
1102 c->value = btv->bright;
1103 break;
1104 case V4L2_CID_HUE:
1105 c->value = btv->hue;
1106 break;
1107 case V4L2_CID_CONTRAST:
1108 c->value = btv->contrast;
1109 break;
1110 case V4L2_CID_SATURATION:
1111 c->value = btv->saturation;
1112 break;
1113
1114 case V4L2_CID_AUDIO_MUTE:
1115 c->value = (VIDEO_AUDIO_MUTE & va.flags) ? 1 : 0;
1116 break;
1117 case V4L2_CID_AUDIO_VOLUME:
1118 c->value = va.volume;
1119 break;
1120 case V4L2_CID_AUDIO_BALANCE:
1121 c->value = va.balance;
1122 break;
1123 case V4L2_CID_AUDIO_BASS:
1124 c->value = va.bass;
1125 break;
1126 case V4L2_CID_AUDIO_TREBLE:
1127 c->value = va.treble;
1128 break;
1129
1130 case V4L2_CID_PRIVATE_CHROMA_AGC:
1131 c->value = btv->opt_chroma_agc;
1132 break;
1133 case V4L2_CID_PRIVATE_COMBFILTER:
1134 c->value = btv->opt_combfilter;
1135 break;
1136 case V4L2_CID_PRIVATE_LUMAFILTER:
1137 c->value = btv->opt_lumafilter;
1138 break;
1139 case V4L2_CID_PRIVATE_AUTOMUTE:
1140 c->value = btv->opt_automute;
1141 break;
1142 case V4L2_CID_PRIVATE_AGC_CRUSH:
1143 c->value = btv->opt_adc_crush;
1144 break;
1145 case V4L2_CID_PRIVATE_VCR_HACK:
1146 c->value = btv->opt_vcr_hack;
1147 break;
1148 case V4L2_CID_PRIVATE_WHITECRUSH_UPPER:
1149 c->value = btv->opt_whitecrush_upper;
1150 break;
1151 case V4L2_CID_PRIVATE_WHITECRUSH_LOWER:
1152 c->value = btv->opt_whitecrush_lower;
1153 break;
1154 default:
1155 return -EINVAL;
1156 }
1157 return 0;
1158}
1159
1160static int set_control(struct bttv *btv, struct v4l2_control *c)
1161{
1162 struct video_audio va;
1163 int i,val;
1164
1165 for (i = 0; i < BTTV_CTLS; i++)
1166 if (bttv_ctls[i].id == c->id)
1167 break;
1168 if (i == BTTV_CTLS)
1169 return -EINVAL;
1170 if (i >= 4 && i <= 8) {
1171 memset(&va,0,sizeof(va));
1172 bttv_call_i2c_clients(btv, VIDIOCGAUDIO, &va);
1173 if (btv->audio_hook)
1174 btv->audio_hook(btv,&va,0);
1175 }
1176 switch (c->id) {
1177 case V4L2_CID_BRIGHTNESS:
1178 bt848_bright(btv,c->value);
1179 break;
1180 case V4L2_CID_HUE:
1181 bt848_hue(btv,c->value);
1182 break;
1183 case V4L2_CID_CONTRAST:
1184 bt848_contrast(btv,c->value);
1185 break;
1186 case V4L2_CID_SATURATION:
1187 bt848_sat(btv,c->value);
1188 break;
1189 case V4L2_CID_AUDIO_MUTE:
1190 if (c->value) {
1191 va.flags |= VIDEO_AUDIO_MUTE;
1192 audio_mux(btv, AUDIO_MUTE);
1193 } else {
1194 va.flags &= ~VIDEO_AUDIO_MUTE;
1195 audio_mux(btv, AUDIO_UNMUTE);
1196 }
1197 break;
1198
1199 case V4L2_CID_AUDIO_VOLUME:
1200 va.volume = c->value;
1201 break;
1202 case V4L2_CID_AUDIO_BALANCE:
1203 va.balance = c->value;
1204 break;
1205 case V4L2_CID_AUDIO_BASS:
1206 va.bass = c->value;
1207 break;
1208 case V4L2_CID_AUDIO_TREBLE:
1209 va.treble = c->value;
1210 break;
1211
1212 case V4L2_CID_PRIVATE_CHROMA_AGC:
1213 btv->opt_chroma_agc = c->value;
1214 val = btv->opt_chroma_agc ? BT848_SCLOOP_CAGC : 0;
1215 btwrite(val, BT848_E_SCLOOP);
1216 btwrite(val, BT848_O_SCLOOP);
1217 break;
1218 case V4L2_CID_PRIVATE_COMBFILTER:
1219 btv->opt_combfilter = c->value;
1220 break;
1221 case V4L2_CID_PRIVATE_LUMAFILTER:
1222 btv->opt_lumafilter = c->value;
1223 if (btv->opt_lumafilter) {
1224 btand(~BT848_CONTROL_LDEC, BT848_E_CONTROL);
1225 btand(~BT848_CONTROL_LDEC, BT848_O_CONTROL);
1226 } else {
1227 btor(BT848_CONTROL_LDEC, BT848_E_CONTROL);
1228 btor(BT848_CONTROL_LDEC, BT848_O_CONTROL);
1229 }
1230 break;
1231 case V4L2_CID_PRIVATE_AUTOMUTE:
1232 btv->opt_automute = c->value;
1233 break;
1234 case V4L2_CID_PRIVATE_AGC_CRUSH:
1235 btv->opt_adc_crush = c->value;
1236 btwrite(BT848_ADC_RESERVED | (btv->opt_adc_crush ? BT848_ADC_CRUSH : 0),
1237 BT848_ADC);
1238 break;
1239 case V4L2_CID_PRIVATE_VCR_HACK:
1240 btv->opt_vcr_hack = c->value;
1241 break;
1242 case V4L2_CID_PRIVATE_WHITECRUSH_UPPER:
1243 btv->opt_whitecrush_upper = c->value;
1244 btwrite(c->value, BT848_WC_UP);
1245 break;
1246 case V4L2_CID_PRIVATE_WHITECRUSH_LOWER:
1247 btv->opt_whitecrush_lower = c->value;
1248 btwrite(c->value, BT848_WC_DOWN);
1249 break;
1250 default:
1251 return -EINVAL;
1252 }
1253 if (i >= 4 && i <= 8) {
1254 bttv_call_i2c_clients(btv, VIDIOCSAUDIO, &va);
1255 if (btv->audio_hook)
1256 btv->audio_hook(btv,&va,1);
1257 }
1258 return 0;
1259}
1260
1261/* ----------------------------------------------------------------------- */
1262
1263void bttv_gpio_tracking(struct bttv *btv, char *comment)
1264{
1265 unsigned int outbits, data;
1266 outbits = btread(BT848_GPIO_OUT_EN);
1267 data = btread(BT848_GPIO_DATA);
1268 printk(KERN_DEBUG "bttv%d: gpio: en=%08x, out=%08x in=%08x [%s]\n",
1269 btv->c.nr,outbits,data & outbits, data & ~outbits, comment);
1270}
1271
1272static void bttv_field_count(struct bttv *btv)
1273{
1274 int need_count = 0;
1275
1276 if (btv->users)
1277 need_count++;
1278
1279 if (need_count) {
1280 /* start field counter */
1281 btor(BT848_INT_VSYNC,BT848_INT_MASK);
1282 } else {
1283 /* stop field counter */
1284 btand(~BT848_INT_VSYNC,BT848_INT_MASK);
1285 btv->field_count = 0;
1286 }
1287}
1288
1289static const struct bttv_format*
1290format_by_palette(int palette)
1291{
1292 unsigned int i;
1293
1294 for (i = 0; i < BTTV_FORMATS; i++) {
1295 if (-1 == bttv_formats[i].palette)
1296 continue;
1297 if (bttv_formats[i].palette == palette)
1298 return bttv_formats+i;
1299 }
1300 return NULL;
1301}
1302
1303static const struct bttv_format*
1304format_by_fourcc(int fourcc)
1305{
1306 unsigned int i;
1307
1308 for (i = 0; i < BTTV_FORMATS; i++) {
1309 if (-1 == bttv_formats[i].fourcc)
1310 continue;
1311 if (bttv_formats[i].fourcc == fourcc)
1312 return bttv_formats+i;
1313 }
1314 return NULL;
1315}
1316
1317/* ----------------------------------------------------------------------- */
1318/* misc helpers */
1319
1320static int
1321bttv_switch_overlay(struct bttv *btv, struct bttv_fh *fh,
1322 struct bttv_buffer *new)
1323{
1324 struct bttv_buffer *old;
1325 unsigned long flags;
1326 int retval = 0;
1327
1328 dprintk("switch_overlay: enter [new=%p]\n",new);
1329 if (new)
1330 new->vb.state = STATE_DONE;
1331 spin_lock_irqsave(&btv->s_lock,flags);
1332 old = btv->screen;
1333 btv->screen = new;
1334 btv->loop_irq |= 1;
1335 bttv_set_dma(btv, 0x03);
1336 spin_unlock_irqrestore(&btv->s_lock,flags);
1337 if (NULL == new)
1338 free_btres(btv,fh,RESOURCE_OVERLAY);
1339 if (NULL != old) {
1340 dprintk("switch_overlay: old=%p state is %d\n",old,old->vb.state);
1341 bttv_dma_free(btv, old);
1342 kfree(old);
1343 }
1344 dprintk("switch_overlay: done\n");
1345 return retval;
1346}
1347
1348/* ----------------------------------------------------------------------- */
1349/* video4linux (1) interface */
1350
1351static int bttv_prepare_buffer(struct bttv *btv, struct bttv_buffer *buf,
1352 const struct bttv_format *fmt,
1353 unsigned int width, unsigned int height,
1354 enum v4l2_field field)
1355{
1356 int redo_dma_risc = 0;
1357 int rc;
1358
1359 /* check settings */
1360 if (NULL == fmt)
1361 return -EINVAL;
1362 if (fmt->btformat == BT848_COLOR_FMT_RAW) {
1363 width = RAW_BPL;
1364 height = RAW_LINES*2;
1365 if (width*height > buf->vb.bsize)
1366 return -EINVAL;
1367 buf->vb.size = buf->vb.bsize;
1368 } else {
1369 if (width < 48 ||
1370 height < 32 ||
1371 width > bttv_tvnorms[btv->tvnorm].swidth ||
1372 height > bttv_tvnorms[btv->tvnorm].sheight)
1373 return -EINVAL;
1374 buf->vb.size = (width * height * fmt->depth) >> 3;
1375 if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size)
1376 return -EINVAL;
1377 }
1378
1379 /* alloc + fill struct bttv_buffer (if changed) */
1380 if (buf->vb.width != width || buf->vb.height != height ||
1381 buf->vb.field != field ||
1382 buf->tvnorm != btv->tvnorm || buf->fmt != fmt) {
1383 buf->vb.width = width;
1384 buf->vb.height = height;
1385 buf->vb.field = field;
1386 buf->tvnorm = btv->tvnorm;
1387 buf->fmt = fmt;
1388 redo_dma_risc = 1;
1389 }
1390
1391 /* alloc risc memory */
1392 if (STATE_NEEDS_INIT == buf->vb.state) {
1393 redo_dma_risc = 1;
1394 if (0 != (rc = videobuf_iolock(btv->c.pci,&buf->vb,&btv->fbuf)))
1395 goto fail;
1396 }
1397
1398 if (redo_dma_risc)
1399 if (0 != (rc = bttv_buffer_risc(btv,buf)))
1400 goto fail;
1401
1402 buf->vb.state = STATE_PREPARED;
1403 return 0;
1404
1405 fail:
1406 bttv_dma_free(btv,buf);
1407 return rc;
1408}
1409
1410static int
1411buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
1412{
1413 struct bttv_fh *fh = q->priv_data;
1414
1415 *size = fh->fmt->depth*fh->width*fh->height >> 3;
1416 if (0 == *count)
1417 *count = gbuffers;
1418 while (*size * *count > gbuffers * gbufsize)
1419 (*count)--;
1420 return 0;
1421}
1422
1423static int
1424buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
1425 enum v4l2_field field)
1426{
1427 struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb);
1428 struct bttv_fh *fh = q->priv_data;
1429
1430 return bttv_prepare_buffer(fh->btv, buf, fh->fmt,
1431 fh->width, fh->height, field);
1432}
1433
1434static void
1435buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
1436{
1437 struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb);
1438 struct bttv_fh *fh = q->priv_data;
1439 struct bttv *btv = fh->btv;
1440
1441 buf->vb.state = STATE_QUEUED;
1442 list_add_tail(&buf->vb.queue,&btv->capture);
1443 if (!btv->curr.frame_irq) {
1444 btv->loop_irq |= 1;
1445 bttv_set_dma(btv, 0x03);
1446 }
1447}
1448
1449static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
1450{
1451 struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb);
1452 struct bttv_fh *fh = q->priv_data;
1453
1454 bttv_dma_free(fh->btv,buf);
1455}
1456
1457static struct videobuf_queue_ops bttv_video_qops = {
1458 .buf_setup = buffer_setup,
1459 .buf_prepare = buffer_prepare,
1460 .buf_queue = buffer_queue,
1461 .buf_release = buffer_release,
1462};
1463
1464static const char *v4l1_ioctls[] = {
1465 "?", "CGAP", "GCHAN", "SCHAN", "GTUNER", "STUNER", "GPICT", "SPICT",
1466 "CCAPTURE", "GWIN", "SWIN", "GFBUF", "SFBUF", "KEY", "GFREQ",
1467 "SFREQ", "GAUDIO", "SAUDIO", "SYNC", "MCAPTURE", "GMBUF", "GUNIT",
1468 "GCAPTURE", "SCAPTURE", "SPLAYMODE", "SWRITEMODE", "GPLAYINFO",
1469 "SMICROCODE", "GVBIFMT", "SVBIFMT" };
1470#define V4L1_IOCTLS ARRAY_SIZE(v4l1_ioctls)
1471
1472static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg)
1473{
1474 switch (cmd) {
1475 case BTTV_VERSION:
1476 return BTTV_VERSION_CODE;
1477
1478 /* *** v4l1 *** ************************************************ */
1479 case VIDIOCGFREQ:
1480 {
1481 unsigned long *freq = arg;
1482 *freq = btv->freq;
1483 return 0;
1484 }
1485 case VIDIOCSFREQ:
1486 {
1487 unsigned long *freq = arg;
1488 down(&btv->lock);
1489 btv->freq=*freq;
1490 bttv_call_i2c_clients(btv,VIDIOCSFREQ,freq);
1491 if (btv->has_matchbox && btv->radio_user)
1492 tea5757_set_freq(btv,*freq);
1493 up(&btv->lock);
1494 return 0;
1495 }
1496
1497 case VIDIOCGTUNER:
1498 {
1499 struct video_tuner *v = arg;
1500
1501 if (UNSET == bttv_tvcards[btv->c.type].tuner)
1502 return -EINVAL;
1503 if (v->tuner) /* Only tuner 0 */
1504 return -EINVAL;
1505 strcpy(v->name, "Television");
1506 v->rangelow = 0;
1507 v->rangehigh = 0x7FFFFFFF;
1508 v->flags = VIDEO_TUNER_PAL|VIDEO_TUNER_NTSC|VIDEO_TUNER_SECAM;
1509 v->mode = btv->tvnorm;
1510 v->signal = (btread(BT848_DSTATUS)&BT848_DSTATUS_HLOC) ? 0xFFFF : 0;
1511 bttv_call_i2c_clients(btv,cmd,v);
1512 return 0;
1513 }
1514 case VIDIOCSTUNER:
1515 {
1516 struct video_tuner *v = arg;
1517
1518 if (v->tuner) /* Only tuner 0 */
1519 return -EINVAL;
1520 if (v->mode >= BTTV_TVNORMS)
1521 return -EINVAL;
1522
1523 down(&btv->lock);
1524 set_tvnorm(btv,v->mode);
1525 bttv_call_i2c_clients(btv,cmd,v);
1526 up(&btv->lock);
1527 return 0;
1528 }
1529
1530 case VIDIOCGCHAN:
1531 {
1532 struct video_channel *v = arg;
1533 unsigned int channel = v->channel;
1534
1535 if (channel >= bttv_tvcards[btv->c.type].video_inputs)
1536 return -EINVAL;
1537 v->tuners=0;
1538 v->flags = VIDEO_VC_AUDIO;
1539 v->type = VIDEO_TYPE_CAMERA;
1540 v->norm = btv->tvnorm;
1541 if (channel == bttv_tvcards[btv->c.type].tuner) {
1542 strcpy(v->name,"Television");
1543 v->flags|=VIDEO_VC_TUNER;
1544 v->type=VIDEO_TYPE_TV;
1545 v->tuners=1;
1546 } else if (channel == btv->svhs) {
1547 strcpy(v->name,"S-Video");
1548 } else {
1549 sprintf(v->name,"Composite%d",channel);
1550 }
1551 return 0;
1552 }
1553 case VIDIOCSCHAN:
1554 {
1555 struct video_channel *v = arg;
1556 unsigned int channel = v->channel;
1557
1558 if (channel >= bttv_tvcards[btv->c.type].video_inputs)
1559 return -EINVAL;
1560 if (v->norm >= BTTV_TVNORMS)
1561 return -EINVAL;
1562
1563 down(&btv->lock);
1564 if (channel == btv->input &&
1565 v->norm == btv->tvnorm) {
1566 /* nothing to do */
1567 up(&btv->lock);
1568 return 0;
1569 }
1570
1571 btv->tvnorm = v->norm;
1572 set_input(btv,v->channel);
1573 up(&btv->lock);
1574 return 0;
1575 }
1576
1577 case VIDIOCGAUDIO:
1578 {
1579 struct video_audio *v = arg;
1580
1581 memset(v,0,sizeof(*v));
1582 strcpy(v->name,"Television");
1583 v->flags |= VIDEO_AUDIO_MUTABLE;
1584 v->mode = VIDEO_SOUND_MONO;
1585
1586 down(&btv->lock);
1587 bttv_call_i2c_clients(btv,cmd,v);
1588
1589 /* card specific hooks */
1590 if (btv->audio_hook)
1591 btv->audio_hook(btv,v,0);
1592
1593 up(&btv->lock);
1594 return 0;
1595 }
1596 case VIDIOCSAUDIO:
1597 {
1598 struct video_audio *v = arg;
1599 unsigned int audio = v->audio;
1600
1601 if (audio >= bttv_tvcards[btv->c.type].audio_inputs)
1602 return -EINVAL;
1603
1604 down(&btv->lock);
1605 audio_mux(btv, (v->flags&VIDEO_AUDIO_MUTE) ? AUDIO_MUTE : AUDIO_UNMUTE);
1606 bttv_call_i2c_clients(btv,cmd,v);
1607
1608 /* card specific hooks */
1609 if (btv->audio_hook)
1610 btv->audio_hook(btv,v,1);
1611
1612 up(&btv->lock);
1613 return 0;
1614 }
1615
1616 /* *** v4l2 *** ************************************************ */
1617 case VIDIOC_ENUMSTD:
1618 {
1619 struct v4l2_standard *e = arg;
1620 unsigned int index = e->index;
1621
1622 if (index >= BTTV_TVNORMS)
1623 return -EINVAL;
1624 v4l2_video_std_construct(e, bttv_tvnorms[e->index].v4l2_id,
1625 bttv_tvnorms[e->index].name);
1626 e->index = index;
1627 return 0;
1628 }
1629 case VIDIOC_G_STD:
1630 {
1631 v4l2_std_id *id = arg;
1632 *id = bttv_tvnorms[btv->tvnorm].v4l2_id;
1633 return 0;
1634 }
1635 case VIDIOC_S_STD:
1636 {
1637 v4l2_std_id *id = arg;
1638 unsigned int i;
1639
1640 for (i = 0; i < BTTV_TVNORMS; i++)
1641 if (*id & bttv_tvnorms[i].v4l2_id)
1642 break;
1643 if (i == BTTV_TVNORMS)
1644 return -EINVAL;
1645
1646 down(&btv->lock);
1647 set_tvnorm(btv,i);
1648 i2c_vidiocschan(btv);
1649 up(&btv->lock);
1650 return 0;
1651 }
1652 case VIDIOC_QUERYSTD:
1653 {
1654 v4l2_std_id *id = arg;
1655
1656 if (btread(BT848_DSTATUS) & BT848_DSTATUS_NUML)
1657 *id = V4L2_STD_625_50;
1658 else
1659 *id = V4L2_STD_525_60;
1660 return 0;
1661 }
1662
1663 case VIDIOC_ENUMINPUT:
1664 {
1665 struct v4l2_input *i = arg;
1666 unsigned int n;
1667
1668 n = i->index;
1669 if (n >= bttv_tvcards[btv->c.type].video_inputs)
1670 return -EINVAL;
1671 memset(i,0,sizeof(*i));
1672 i->index = n;
1673 i->type = V4L2_INPUT_TYPE_CAMERA;
1674 i->audioset = 1;
1675 if (i->index == bttv_tvcards[btv->c.type].tuner) {
1676 sprintf(i->name, "Television");
1677 i->type = V4L2_INPUT_TYPE_TUNER;
1678 i->tuner = 0;
1679 } else if (i->index == btv->svhs) {
1680 sprintf(i->name, "S-Video");
1681 } else {
1682 sprintf(i->name,"Composite%d",i->index);
1683 }
1684 if (i->index == btv->input) {
1685 __u32 dstatus = btread(BT848_DSTATUS);
1686 if (0 == (dstatus & BT848_DSTATUS_PRES))
1687 i->status |= V4L2_IN_ST_NO_SIGNAL;
1688 if (0 == (dstatus & BT848_DSTATUS_HLOC))
1689 i->status |= V4L2_IN_ST_NO_H_LOCK;
1690 }
1691 for (n = 0; n < BTTV_TVNORMS; n++)
1692 i->std |= bttv_tvnorms[n].v4l2_id;
1693 return 0;
1694 }
1695 case VIDIOC_G_INPUT:
1696 {
1697 int *i = arg;
1698 *i = btv->input;
1699 return 0;
1700 }
1701 case VIDIOC_S_INPUT:
1702 {
1703 unsigned int *i = arg;
1704
1705 if (*i > bttv_tvcards[btv->c.type].video_inputs)
1706 return -EINVAL;
1707 down(&btv->lock);
1708 set_input(btv,*i);
1709 up(&btv->lock);
1710 return 0;
1711 }
1712
1713 case VIDIOC_G_TUNER:
1714 {
1715 struct v4l2_tuner *t = arg;
1716
1717 if (UNSET == bttv_tvcards[btv->c.type].tuner)
1718 return -EINVAL;
1719 if (0 != t->index)
1720 return -EINVAL;
1721 down(&btv->lock);
1722 memset(t,0,sizeof(*t));
1723 strcpy(t->name, "Television");
1724 t->type = V4L2_TUNER_ANALOG_TV;
1725 t->rangehigh = 0xffffffffUL;
1726 t->capability = V4L2_TUNER_CAP_NORM;
1727 t->rxsubchans = V4L2_TUNER_SUB_MONO;
1728 if (btread(BT848_DSTATUS)&BT848_DSTATUS_HLOC)
1729 t->signal = 0xffff;
1730 {
1731 /* Hmmm ... */
1732 struct video_audio va;
1733 memset(&va, 0, sizeof(struct video_audio));
1734 bttv_call_i2c_clients(btv, VIDIOCGAUDIO, &va);
1735 if (btv->audio_hook)
1736 btv->audio_hook(btv,&va,0);
1737 if(va.mode & VIDEO_SOUND_STEREO) {
1738 t->audmode = V4L2_TUNER_MODE_STEREO;
1739 t->rxsubchans |= V4L2_TUNER_SUB_STEREO;
1740 }
1741 if(va.mode & VIDEO_SOUND_LANG1) {
1742 t->audmode = V4L2_TUNER_MODE_LANG1;
1743 t->rxsubchans = V4L2_TUNER_SUB_LANG1
1744 | V4L2_TUNER_SUB_LANG2;
1745 }
1746 }
1747 /* FIXME: fill capability+audmode */
1748 up(&btv->lock);
1749 return 0;
1750 }
1751 case VIDIOC_S_TUNER:
1752 {
1753 struct v4l2_tuner *t = arg;
1754
1755 if (UNSET == bttv_tvcards[btv->c.type].tuner)
1756 return -EINVAL;
1757 if (0 != t->index)
1758 return -EINVAL;
1759 down(&btv->lock);
1760 {
1761 struct video_audio va;
1762 memset(&va, 0, sizeof(struct video_audio));
1763 bttv_call_i2c_clients(btv, VIDIOCGAUDIO, &va);
1764 if (t->audmode == V4L2_TUNER_MODE_MONO)
1765 va.mode = VIDEO_SOUND_MONO;
1766 else if (t->audmode == V4L2_TUNER_MODE_STEREO)
1767 va.mode = VIDEO_SOUND_STEREO;
1768 else if (t->audmode == V4L2_TUNER_MODE_LANG1)
1769 va.mode = VIDEO_SOUND_LANG1;
1770 else if (t->audmode == V4L2_TUNER_MODE_LANG2)
1771 va.mode = VIDEO_SOUND_LANG2;
1772 bttv_call_i2c_clients(btv, VIDIOCSAUDIO, &va);
1773 if (btv->audio_hook)
1774 btv->audio_hook(btv,&va,1);
1775 }
1776 up(&btv->lock);
1777 return 0;
1778 }
1779
1780 case VIDIOC_G_FREQUENCY:
1781 {
1782 struct v4l2_frequency *f = arg;
1783
1784 memset(f,0,sizeof(*f));
1785 f->type = V4L2_TUNER_ANALOG_TV;
1786 f->frequency = btv->freq;
1787 return 0;
1788 }
1789 case VIDIOC_S_FREQUENCY:
1790 {
1791 struct v4l2_frequency *f = arg;
1792
1793 if (unlikely(f->tuner != 0))
1794 return -EINVAL;
1795 if (unlikely(f->type != V4L2_TUNER_ANALOG_TV))
1796 return -EINVAL;
1797 down(&btv->lock);
1798 btv->freq = f->frequency;
1799 bttv_call_i2c_clients(btv,VIDIOCSFREQ,&btv->freq);
1800 if (btv->has_matchbox && btv->radio_user)
1801 tea5757_set_freq(btv,btv->freq);
1802 up(&btv->lock);
1803 return 0;
1804 }
1805
1806 default:
1807 return -ENOIOCTLCMD;
1808
1809 }
1810 return 0;
1811}
1812
1813static int verify_window(const struct bttv_tvnorm *tvn,
1814 struct v4l2_window *win, int fixup)
1815{
1816 enum v4l2_field field;
1817 int maxw, maxh;
1818
1819 if (win->w.width < 48 || win->w.height < 32)
1820 return -EINVAL;
1821 if (win->clipcount > 2048)
1822 return -EINVAL;
1823
1824 field = win->field;
1825 maxw = tvn->swidth;
1826 maxh = tvn->sheight;
1827
1828 if (V4L2_FIELD_ANY == field) {
1829 field = (win->w.height > maxh/2)
1830 ? V4L2_FIELD_INTERLACED
1831 : V4L2_FIELD_TOP;
1832 }
1833 switch (field) {
1834 case V4L2_FIELD_TOP:
1835 case V4L2_FIELD_BOTTOM:
1836 maxh = maxh / 2;
1837 break;
1838 case V4L2_FIELD_INTERLACED:
1839 break;
1840 default:
1841 return -EINVAL;
1842 }
1843
1844 if (!fixup && (win->w.width > maxw || win->w.height > maxh))
1845 return -EINVAL;
1846
1847 if (win->w.width > maxw)
1848 win->w.width = maxw;
1849 if (win->w.height > maxh)
1850 win->w.height = maxh;
1851 win->field = field;
1852 return 0;
1853}
1854
1855static int setup_window(struct bttv_fh *fh, struct bttv *btv,
1856 struct v4l2_window *win, int fixup)
1857{
1858 struct v4l2_clip *clips = NULL;
1859 int n,size,retval = 0;
1860
1861 if (NULL == fh->ovfmt)
1862 return -EINVAL;
1863 if (!(fh->ovfmt->flags & FORMAT_FLAGS_PACKED))
1864 return -EINVAL;
1865 retval = verify_window(&bttv_tvnorms[btv->tvnorm],win,fixup);
1866 if (0 != retval)
1867 return retval;
1868
1869 /* copy clips -- luckily v4l1 + v4l2 are binary
1870 compatible here ...*/
1871 n = win->clipcount;
1872 size = sizeof(*clips)*(n+4);
1873 clips = kmalloc(size,GFP_KERNEL);
1874 if (NULL == clips)
1875 return -ENOMEM;
1876 if (n > 0) {
1877 if (copy_from_user(clips,win->clips,sizeof(struct v4l2_clip)*n)) {
1878 kfree(clips);
1879 return -EFAULT;
1880 }
1881 }
1882 /* clip against screen */
1883 if (NULL != btv->fbuf.base)
1884 n = btcx_screen_clips(btv->fbuf.fmt.width, btv->fbuf.fmt.height,
1885 &win->w, clips, n);
1886 btcx_sort_clips(clips,n);
1887
1888 /* 4-byte alignments */
1889 switch (fh->ovfmt->depth) {
1890 case 8:
1891 case 24:
1892 btcx_align(&win->w, clips, n, 3);
1893 break;
1894 case 16:
1895 btcx_align(&win->w, clips, n, 1);
1896 break;
1897 case 32:
1898 /* no alignment fixups needed */
1899 break;
1900 default:
1901 BUG();
1902 }
1903
1904 down(&fh->cap.lock);
1905 if (fh->ov.clips)
1906 kfree(fh->ov.clips);
1907 fh->ov.clips = clips;
1908 fh->ov.nclips = n;
1909
1910 fh->ov.w = win->w;
1911 fh->ov.field = win->field;
1912 fh->ov.setup_ok = 1;
1913 btv->init.ov.w.width = win->w.width;
1914 btv->init.ov.w.height = win->w.height;
1915 btv->init.ov.field = win->field;
1916
1917 /* update overlay if needed */
1918 retval = 0;
1919 if (check_btres(fh, RESOURCE_OVERLAY)) {
1920 struct bttv_buffer *new;
1921
1922 new = videobuf_alloc(sizeof(*new));
1923 bttv_overlay_risc(btv, &fh->ov, fh->ovfmt, new);
1924 retval = bttv_switch_overlay(btv,fh,new);
1925 }
1926 up(&fh->cap.lock);
1927 return retval;
1928}
1929
1930/* ----------------------------------------------------------------------- */
1931
1932static struct videobuf_queue* bttv_queue(struct bttv_fh *fh)
1933{
1934 struct videobuf_queue* q = NULL;
1935
1936 switch (fh->type) {
1937 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1938 q = &fh->cap;
1939 break;
1940 case V4L2_BUF_TYPE_VBI_CAPTURE:
1941 q = &fh->vbi;
1942 break;
1943 default:
1944 BUG();
1945 }
1946 return q;
1947}
1948
1949static int bttv_resource(struct bttv_fh *fh)
1950{
1951 int res = 0;
1952
1953 switch (fh->type) {
1954 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1955 res = RESOURCE_VIDEO;
1956 break;
1957 case V4L2_BUF_TYPE_VBI_CAPTURE:
1958 res = RESOURCE_VBI;
1959 break;
1960 default:
1961 BUG();
1962 }
1963 return res;
1964}
1965
1966static int bttv_switch_type(struct bttv_fh *fh, enum v4l2_buf_type type)
1967{
1968 struct videobuf_queue *q = bttv_queue(fh);
1969 int res = bttv_resource(fh);
1970
1971 if (check_btres(fh,res))
1972 return -EBUSY;
1973 if (videobuf_queue_is_busy(q))
1974 return -EBUSY;
1975 fh->type = type;
1976 return 0;
1977}
1978
1979static int bttv_g_fmt(struct bttv_fh *fh, struct v4l2_format *f)
1980{
1981 switch (f->type) {
1982 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1983 memset(&f->fmt.pix,0,sizeof(struct v4l2_pix_format));
1984 f->fmt.pix.width = fh->width;
1985 f->fmt.pix.height = fh->height;
1986 f->fmt.pix.field = fh->cap.field;
1987 f->fmt.pix.pixelformat = fh->fmt->fourcc;
1988 f->fmt.pix.bytesperline =
1989 (f->fmt.pix.width * fh->fmt->depth) >> 3;
1990 f->fmt.pix.sizeimage =
1991 f->fmt.pix.height * f->fmt.pix.bytesperline;
1992 return 0;
1993 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
1994 memset(&f->fmt.win,0,sizeof(struct v4l2_window));
1995 f->fmt.win.w = fh->ov.w;
1996 f->fmt.win.field = fh->ov.field;
1997 return 0;
1998 case V4L2_BUF_TYPE_VBI_CAPTURE:
1999 bttv_vbi_get_fmt(fh,f);
2000 return 0;
2001 default:
2002 return -EINVAL;
2003 }
2004}
2005
2006static int bttv_try_fmt(struct bttv_fh *fh, struct bttv *btv,
2007 struct v4l2_format *f)
2008{
2009 switch (f->type) {
2010 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
2011 {
2012 const struct bttv_format *fmt;
2013 enum v4l2_field field;
2014 unsigned int maxw,maxh;
2015
2016 fmt = format_by_fourcc(f->fmt.pix.pixelformat);
2017 if (NULL == fmt)
2018 return -EINVAL;
2019
2020 /* fixup format */
2021 maxw = bttv_tvnorms[btv->tvnorm].swidth;
2022 maxh = bttv_tvnorms[btv->tvnorm].sheight;
2023 field = f->fmt.pix.field;
2024 if (V4L2_FIELD_ANY == field)
2025 field = (f->fmt.pix.height > maxh/2)
2026 ? V4L2_FIELD_INTERLACED
2027 : V4L2_FIELD_BOTTOM;
2028 if (V4L2_FIELD_SEQ_BT == field)
2029 field = V4L2_FIELD_SEQ_TB;
2030 switch (field) {
2031 case V4L2_FIELD_TOP:
2032 case V4L2_FIELD_BOTTOM:
2033 case V4L2_FIELD_ALTERNATE:
2034 maxh = maxh/2;
2035 break;
2036 case V4L2_FIELD_INTERLACED:
2037 break;
2038 case V4L2_FIELD_SEQ_TB:
2039 if (fmt->flags & FORMAT_FLAGS_PLANAR)
2040 return -EINVAL;
2041 break;
2042 default:
2043 return -EINVAL;
2044 }
2045
2046 /* update data for the application */
2047 f->fmt.pix.field = field;
2048 if (f->fmt.pix.width < 48)
2049 f->fmt.pix.width = 48;
2050 if (f->fmt.pix.height < 32)
2051 f->fmt.pix.height = 32;
2052 if (f->fmt.pix.width > maxw)
2053 f->fmt.pix.width = maxw;
2054 if (f->fmt.pix.height > maxh)
2055 f->fmt.pix.height = maxh;
2056 f->fmt.pix.width &= ~0x03;
2057 f->fmt.pix.bytesperline =
2058 (f->fmt.pix.width * fmt->depth) >> 3;
2059 f->fmt.pix.sizeimage =
2060 f->fmt.pix.height * f->fmt.pix.bytesperline;
2061
2062 return 0;
2063 }
2064 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
2065 return verify_window(&bttv_tvnorms[btv->tvnorm],
2066 &f->fmt.win, 1);
2067 case V4L2_BUF_TYPE_VBI_CAPTURE:
2068 bttv_vbi_try_fmt(fh,f);
2069 return 0;
2070 default:
2071 return -EINVAL;
2072 }
2073}
2074
2075static int bttv_s_fmt(struct bttv_fh *fh, struct bttv *btv,
2076 struct v4l2_format *f)
2077{
2078 int retval;
2079
2080 switch (f->type) {
2081 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
2082 {
2083 const struct bttv_format *fmt;
2084
2085 retval = bttv_switch_type(fh,f->type);
2086 if (0 != retval)
2087 return retval;
2088 retval = bttv_try_fmt(fh,btv,f);
2089 if (0 != retval)
2090 return retval;
2091 fmt = format_by_fourcc(f->fmt.pix.pixelformat);
2092
2093 /* update our state informations */
2094 down(&fh->cap.lock);
2095 fh->fmt = fmt;
2096 fh->cap.field = f->fmt.pix.field;
2097 fh->cap.last = V4L2_FIELD_NONE;
2098 fh->width = f->fmt.pix.width;
2099 fh->height = f->fmt.pix.height;
2100 btv->init.fmt = fmt;
2101 btv->init.width = f->fmt.pix.width;
2102 btv->init.height = f->fmt.pix.height;
2103 up(&fh->cap.lock);
2104
2105 return 0;
2106 }
2107 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
2108 return setup_window(fh, btv, &f->fmt.win, 1);
2109 case V4L2_BUF_TYPE_VBI_CAPTURE:
2110 retval = bttv_switch_type(fh,f->type);
2111 if (0 != retval)
2112 return retval;
2113 if (locked_btres(fh->btv, RESOURCE_VBI))
2114 return -EBUSY;
2115 bttv_vbi_try_fmt(fh,f);
2116 bttv_vbi_setlines(fh,btv,f->fmt.vbi.count[0]);
2117 bttv_vbi_get_fmt(fh,f);
2118 return 0;
2119 default:
2120 return -EINVAL;
2121 }
2122}
2123
2124static int bttv_do_ioctl(struct inode *inode, struct file *file,
2125 unsigned int cmd, void *arg)
2126{
2127 struct bttv_fh *fh = file->private_data;
2128 struct bttv *btv = fh->btv;
2129 unsigned long flags;
2130 int retval = 0;
2131
2132 if (bttv_debug > 1) {
2133 switch (_IOC_TYPE(cmd)) {
2134 case 'v':
2135 printk("bttv%d: ioctl 0x%x (v4l1, VIDIOC%s)\n",
2136 btv->c.nr, cmd, (_IOC_NR(cmd) < V4L1_IOCTLS) ?
2137 v4l1_ioctls[_IOC_NR(cmd)] : "???");
2138 break;
2139 case 'V':
2140 printk("bttv%d: ioctl 0x%x (v4l2, %s)\n",
2141 btv->c.nr, cmd, v4l2_ioctl_names[_IOC_NR(cmd)]);
2142 break;
2143 default:
2144 printk("bttv%d: ioctl 0x%x (???)\n",
2145 btv->c.nr, cmd);
2146 }
2147 }
2148 if (btv->errors)
2149 bttv_reinit_bt848(btv);
2150
2151 switch (cmd) {
2152 case VIDIOCSFREQ:
2153 case VIDIOCSTUNER:
2154 case VIDIOCSCHAN:
2155 case VIDIOC_S_CTRL:
2156 case VIDIOC_S_STD:
2157 case VIDIOC_S_INPUT:
2158 case VIDIOC_S_TUNER:
2159 case VIDIOC_S_FREQUENCY:
2160 retval = v4l2_prio_check(&btv->prio,&fh->prio);
2161 if (0 != retval)
2162 return retval;
2163 };
2164
2165 switch (cmd) {
2166
2167 /* *** v4l1 *** ************************************************ */
2168 case VIDIOCGCAP:
2169 {
2170 struct video_capability *cap = arg;
2171
2172 memset(cap,0,sizeof(*cap));
2173 strcpy(cap->name,btv->video_dev->name);
2174 if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) {
2175 /* vbi */
2176 cap->type = VID_TYPE_TUNER|VID_TYPE_TELETEXT;
2177 } else {
2178 /* others */
2179 cap->type = VID_TYPE_CAPTURE|
2180 VID_TYPE_TUNER|
2181 VID_TYPE_OVERLAY|
2182 VID_TYPE_CLIPPING|
2183 VID_TYPE_SCALES;
2184 cap->maxwidth = bttv_tvnorms[btv->tvnorm].swidth;
2185 cap->maxheight = bttv_tvnorms[btv->tvnorm].sheight;
2186 cap->minwidth = 48;
2187 cap->minheight = 32;
2188 }
2189 cap->channels = bttv_tvcards[btv->c.type].video_inputs;
2190 cap->audios = bttv_tvcards[btv->c.type].audio_inputs;
2191 return 0;
2192 }
2193
2194 case VIDIOCGPICT:
2195 {
2196 struct video_picture *pic = arg;
2197
2198 memset(pic,0,sizeof(*pic));
2199 pic->brightness = btv->bright;
2200 pic->contrast = btv->contrast;
2201 pic->hue = btv->hue;
2202 pic->colour = btv->saturation;
2203 if (fh->fmt) {
2204 pic->depth = fh->fmt->depth;
2205 pic->palette = fh->fmt->palette;
2206 }
2207 return 0;
2208 }
2209 case VIDIOCSPICT:
2210 {
2211 struct video_picture *pic = arg;
2212 const struct bttv_format *fmt;
2213
2214 fmt = format_by_palette(pic->palette);
2215 if (NULL == fmt)
2216 return -EINVAL;
2217 down(&fh->cap.lock);
2218 if (fmt->depth != pic->depth) {
2219 retval = -EINVAL;
2220 goto fh_unlock_and_return;
2221 }
2222 fh->ovfmt = fmt;
2223 fh->fmt = fmt;
2224 btv->init.ovfmt = fmt;
2225 btv->init.fmt = fmt;
2226 if (bigendian) {
2227 /* dirty hack time: swap bytes for overlay if the
2228 display adaptor is big endian (insmod option) */
2229 if (fmt->palette == VIDEO_PALETTE_RGB555 ||
2230 fmt->palette == VIDEO_PALETTE_RGB565 ||
2231 fmt->palette == VIDEO_PALETTE_RGB32) {
2232 fh->ovfmt = fmt+1;
2233 }
2234 }
2235 bt848_bright(btv,pic->brightness);
2236 bt848_contrast(btv,pic->contrast);
2237 bt848_hue(btv,pic->hue);
2238 bt848_sat(btv,pic->colour);
2239 up(&fh->cap.lock);
2240 return 0;
2241 }
2242
2243 case VIDIOCGWIN:
2244 {
2245 struct video_window *win = arg;
2246
2247 memset(win,0,sizeof(*win));
2248 win->x = fh->ov.w.left;
2249 win->y = fh->ov.w.top;
2250 win->width = fh->ov.w.width;
2251 win->height = fh->ov.w.height;
2252 return 0;
2253 }
2254 case VIDIOCSWIN:
2255 {
2256 struct video_window *win = arg;
2257 struct v4l2_window w2;
2258
2259 w2.field = V4L2_FIELD_ANY;
2260 w2.w.left = win->x;
2261 w2.w.top = win->y;
2262 w2.w.width = win->width;
2263 w2.w.height = win->height;
2264 w2.clipcount = win->clipcount;
2265 w2.clips = (struct v4l2_clip __user *)win->clips;
2266 retval = setup_window(fh, btv, &w2, 0);
2267 if (0 == retval) {
2268 /* on v4l1 this ioctl affects the read() size too */
2269 fh->width = fh->ov.w.width;
2270 fh->height = fh->ov.w.height;
2271 btv->init.width = fh->ov.w.width;
2272 btv->init.height = fh->ov.w.height;
2273 }
2274 return retval;
2275 }
2276
2277 case VIDIOCGFBUF:
2278 {
2279 struct video_buffer *fbuf = arg;
2280
2281 fbuf->base = btv->fbuf.base;
2282 fbuf->width = btv->fbuf.fmt.width;
2283 fbuf->height = btv->fbuf.fmt.height;
2284 fbuf->bytesperline = btv->fbuf.fmt.bytesperline;
2285 if (fh->ovfmt)
2286 fbuf->depth = fh->ovfmt->depth;
2287 return 0;
2288 }
2289 case VIDIOCSFBUF:
2290 {
2291 struct video_buffer *fbuf = arg;
2292 const struct bttv_format *fmt;
2293 unsigned long end;
2294
2295 if(!capable(CAP_SYS_ADMIN) &&
2296 !capable(CAP_SYS_RAWIO))
2297 return -EPERM;
2298 end = (unsigned long)fbuf->base +
2299 fbuf->height * fbuf->bytesperline;
2300 down(&fh->cap.lock);
2301 retval = -EINVAL;
2302
2303 switch (fbuf->depth) {
2304 case 8:
2305 fmt = format_by_palette(VIDEO_PALETTE_HI240);
2306 break;
2307 case 16:
2308 fmt = format_by_palette(VIDEO_PALETTE_RGB565);
2309 break;
2310 case 24:
2311 fmt = format_by_palette(VIDEO_PALETTE_RGB24);
2312 break;
2313 case 32:
2314 fmt = format_by_palette(VIDEO_PALETTE_RGB32);
2315 break;
2316 case 15:
2317 fbuf->depth = 16;
2318 fmt = format_by_palette(VIDEO_PALETTE_RGB555);
2319 break;
2320 default:
2321 fmt = NULL;
2322 break;
2323 }
2324 if (NULL == fmt)
2325 goto fh_unlock_and_return;
2326
2327 fh->ovfmt = fmt;
2328 fh->fmt = fmt;
2329 btv->init.ovfmt = fmt;
2330 btv->init.fmt = fmt;
2331 btv->fbuf.base = fbuf->base;
2332 btv->fbuf.fmt.width = fbuf->width;
2333 btv->fbuf.fmt.height = fbuf->height;
2334 if (fbuf->bytesperline)
2335 btv->fbuf.fmt.bytesperline = fbuf->bytesperline;
2336 else
2337 btv->fbuf.fmt.bytesperline = btv->fbuf.fmt.width*fbuf->depth/8;
2338 up(&fh->cap.lock);
2339 return 0;
2340 }
2341
2342 case VIDIOCCAPTURE:
2343 case VIDIOC_OVERLAY:
2344 {
2345 struct bttv_buffer *new;
2346 int *on = arg;
2347
2348 if (*on) {
2349 /* verify args */
2350 if (NULL == btv->fbuf.base)
2351 return -EINVAL;
2352 if (!fh->ov.setup_ok) {
2353 dprintk("bttv%d: overlay: !setup_ok\n",btv->c.nr);
2354 return -EINVAL;
2355 }
2356 }
2357
2358 if (!check_alloc_btres(btv,fh,RESOURCE_OVERLAY))
2359 return -EBUSY;
2360
2361 down(&fh->cap.lock);
2362 if (*on) {
2363 fh->ov.tvnorm = btv->tvnorm;
2364 new = videobuf_alloc(sizeof(*new));
2365 bttv_overlay_risc(btv, &fh->ov, fh->ovfmt, new);
2366 } else {
2367 new = NULL;
2368 }
2369
2370 /* switch over */
2371 retval = bttv_switch_overlay(btv,fh,new);
2372 up(&fh->cap.lock);
2373 return retval;
2374 }
2375
2376 case VIDIOCGMBUF:
2377 {
2378 struct video_mbuf *mbuf = arg;
2379 unsigned int i;
2380
2381 down(&fh->cap.lock);
2382 retval = videobuf_mmap_setup(&fh->cap,gbuffers,gbufsize,
2383 V4L2_MEMORY_MMAP);
2384 if (retval < 0)
2385 goto fh_unlock_and_return;
2386 memset(mbuf,0,sizeof(*mbuf));
2387 mbuf->frames = gbuffers;
2388 mbuf->size = gbuffers * gbufsize;
2389 for (i = 0; i < gbuffers; i++)
2390 mbuf->offsets[i] = i * gbufsize;
2391 up(&fh->cap.lock);
2392 return 0;
2393 }
2394 case VIDIOCMCAPTURE:
2395 {
2396 struct video_mmap *vm = arg;
2397 struct bttv_buffer *buf;
2398 enum v4l2_field field;
2399
2400 if (vm->frame >= VIDEO_MAX_FRAME)
2401 return -EINVAL;
2402
2403 down(&fh->cap.lock);
2404 retval = -EINVAL;
2405 buf = (struct bttv_buffer *)fh->cap.bufs[vm->frame];
2406 if (NULL == buf)
2407 goto fh_unlock_and_return;
2408 if (0 == buf->vb.baddr)
2409 goto fh_unlock_and_return;
2410 if (buf->vb.state == STATE_QUEUED ||
2411 buf->vb.state == STATE_ACTIVE)
2412 goto fh_unlock_and_return;
2413
2414 field = (vm->height > bttv_tvnorms[btv->tvnorm].sheight/2)
2415 ? V4L2_FIELD_INTERLACED
2416 : V4L2_FIELD_BOTTOM;
2417 retval = bttv_prepare_buffer(btv,buf,
2418 format_by_palette(vm->format),
2419 vm->width,vm->height,field);
2420 if (0 != retval)
2421 goto fh_unlock_and_return;
2422 spin_lock_irqsave(&btv->s_lock,flags);
2423 buffer_queue(&fh->cap,&buf->vb);
2424 spin_unlock_irqrestore(&btv->s_lock,flags);
2425 up(&fh->cap.lock);
2426 return 0;
2427 }
2428 case VIDIOCSYNC:
2429 {
2430 int *frame = arg;
2431 struct bttv_buffer *buf;
2432
2433 if (*frame >= VIDEO_MAX_FRAME)
2434 return -EINVAL;
2435
2436 down(&fh->cap.lock);
2437 retval = -EINVAL;
2438 buf = (struct bttv_buffer *)fh->cap.bufs[*frame];
2439 if (NULL == buf)
2440 goto fh_unlock_and_return;
2441 retval = videobuf_waiton(&buf->vb,0,1);
2442 if (0 != retval)
2443 goto fh_unlock_and_return;
2444 switch (buf->vb.state) {
2445 case STATE_ERROR:
2446 retval = -EIO;
2447 /* fall through */
2448 case STATE_DONE:
2449 videobuf_dma_pci_sync(btv->c.pci,&buf->vb.dma);
2450 bttv_dma_free(btv,buf);
2451 break;
2452 default:
2453 retval = -EINVAL;
2454 break;
2455 }
2456 up(&fh->cap.lock);
2457 return retval;
2458 }
2459
2460 case VIDIOCGVBIFMT:
2461 {
2462 struct vbi_format *fmt = (void *) arg;
2463 struct v4l2_format fmt2;
2464
2465 if (fh->type != V4L2_BUF_TYPE_VBI_CAPTURE) {
2466 retval = bttv_switch_type(fh,V4L2_BUF_TYPE_VBI_CAPTURE);
2467 if (0 != retval)
2468 return retval;
2469 }
2470 bttv_vbi_get_fmt(fh, &fmt2);
2471
2472 memset(fmt,0,sizeof(*fmt));
2473 fmt->sampling_rate = fmt2.fmt.vbi.sampling_rate;
2474 fmt->samples_per_line = fmt2.fmt.vbi.samples_per_line;
2475 fmt->sample_format = VIDEO_PALETTE_RAW;
2476 fmt->start[0] = fmt2.fmt.vbi.start[0];
2477 fmt->count[0] = fmt2.fmt.vbi.count[0];
2478 fmt->start[1] = fmt2.fmt.vbi.start[1];
2479 fmt->count[1] = fmt2.fmt.vbi.count[1];
2480 if (fmt2.fmt.vbi.flags & VBI_UNSYNC)
2481 fmt->flags |= V4L2_VBI_UNSYNC;
2482 if (fmt2.fmt.vbi.flags & VBI_INTERLACED)
2483 fmt->flags |= V4L2_VBI_INTERLACED;
2484 return 0;
2485 }
2486 case VIDIOCSVBIFMT:
2487 {
2488 struct vbi_format *fmt = (void *) arg;
2489 struct v4l2_format fmt2;
2490
2491 retval = bttv_switch_type(fh,V4L2_BUF_TYPE_VBI_CAPTURE);
2492 if (0 != retval)
2493 return retval;
2494 bttv_vbi_get_fmt(fh, &fmt2);
2495
2496 if (fmt->sampling_rate != fmt2.fmt.vbi.sampling_rate ||
2497 fmt->samples_per_line != fmt2.fmt.vbi.samples_per_line ||
2498 fmt->sample_format != VIDEO_PALETTE_RAW ||
2499 fmt->start[0] != fmt2.fmt.vbi.start[0] ||
2500 fmt->start[1] != fmt2.fmt.vbi.start[1] ||
2501 fmt->count[0] != fmt->count[1] ||
2502 fmt->count[0] < 1 ||
2503 fmt->count[0] > 32 /* VBI_MAXLINES */)
2504 return -EINVAL;
2505
2506 bttv_vbi_setlines(fh,btv,fmt->count[0]);
2507 return 0;
2508 }
2509
2510 case BTTV_VERSION:
2511 case VIDIOCGFREQ:
2512 case VIDIOCSFREQ:
2513 case VIDIOCGTUNER:
2514 case VIDIOCSTUNER:
2515 case VIDIOCGCHAN:
2516 case VIDIOCSCHAN:
2517 case VIDIOCGAUDIO:
2518 case VIDIOCSAUDIO:
2519 return bttv_common_ioctls(btv,cmd,arg);
2520
2521 /* *** v4l2 *** ************************************************ */
2522 case VIDIOC_QUERYCAP:
2523 {
2524 struct v4l2_capability *cap = arg;
2525
2526 if (0 == v4l2)
2527 return -EINVAL;
2528 strcpy(cap->driver,"bttv");
2529 strlcpy(cap->card,btv->video_dev->name,sizeof(cap->card));
2530 sprintf(cap->bus_info,"PCI:%s",pci_name(btv->c.pci));
2531 cap->version = BTTV_VERSION_CODE;
2532 cap->capabilities =
2533 V4L2_CAP_VIDEO_CAPTURE |
2534 V4L2_CAP_VIDEO_OVERLAY |
2535 V4L2_CAP_VBI_CAPTURE |
2536 V4L2_CAP_READWRITE |
2537 V4L2_CAP_STREAMING;
2538 if (bttv_tvcards[btv->c.type].tuner != UNSET &&
2539 bttv_tvcards[btv->c.type].tuner != TUNER_ABSENT)
2540 cap->capabilities |= V4L2_CAP_TUNER;
2541 return 0;
2542 }
2543
2544 case VIDIOC_ENUM_FMT:
2545 {
2546 struct v4l2_fmtdesc *f = arg;
2547 enum v4l2_buf_type type;
2548 unsigned int i;
2549 int index;
2550
2551 type = f->type;
2552 if (V4L2_BUF_TYPE_VBI_CAPTURE == type) {
2553 /* vbi */
2554 index = f->index;
2555 if (0 != index)
2556 return -EINVAL;
2557 memset(f,0,sizeof(*f));
2558 f->index = index;
2559 f->type = type;
2560 f->pixelformat = V4L2_PIX_FMT_GREY;
2561 strcpy(f->description,"vbi data");
2562 return 0;
2563 }
2564
2565 /* video capture + overlay */
2566 index = -1;
2567 for (i = 0; i < BTTV_FORMATS; i++) {
2568 if (bttv_formats[i].fourcc != -1)
2569 index++;
2570 if ((unsigned int)index == f->index)
2571 break;
2572 }
2573 if (BTTV_FORMATS == i)
2574 return -EINVAL;
2575
2576 switch (f->type) {
2577 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
2578 break;
2579 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
2580 if (!(bttv_formats[i].flags & FORMAT_FLAGS_PACKED))
2581 return -EINVAL;
2582 break;
2583 default:
2584 return -EINVAL;
2585 }
2586 memset(f,0,sizeof(*f));
2587 f->index = index;
2588 f->type = type;
2589 f->pixelformat = bttv_formats[i].fourcc;
2590 strlcpy(f->description,bttv_formats[i].name,sizeof(f->description));
2591 return 0;
2592 }
2593
2594 case VIDIOC_TRY_FMT:
2595 {
2596 struct v4l2_format *f = arg;
2597 return bttv_try_fmt(fh,btv,f);
2598 }
2599 case VIDIOC_G_FMT:
2600 {
2601 struct v4l2_format *f = arg;
2602 return bttv_g_fmt(fh,f);
2603 }
2604 case VIDIOC_S_FMT:
2605 {
2606 struct v4l2_format *f = arg;
2607 return bttv_s_fmt(fh,btv,f);
2608 }
2609
2610 case VIDIOC_G_FBUF:
2611 {
2612 struct v4l2_framebuffer *fb = arg;
2613
2614 *fb = btv->fbuf;
2615 fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING;
2616 if (fh->ovfmt)
2617 fb->fmt.pixelformat = fh->ovfmt->fourcc;
2618 return 0;
2619 }
2620 case VIDIOC_S_FBUF:
2621 {
2622 struct v4l2_framebuffer *fb = arg;
2623 const struct bttv_format *fmt;
2624
2625 if(!capable(CAP_SYS_ADMIN) &&
2626 !capable(CAP_SYS_RAWIO))
2627 return -EPERM;
2628
2629 /* check args */
2630 fmt = format_by_fourcc(fb->fmt.pixelformat);
2631 if (NULL == fmt)
2632 return -EINVAL;
2633 if (0 == (fmt->flags & FORMAT_FLAGS_PACKED))
2634 return -EINVAL;
2635
2636 down(&fh->cap.lock);
2637 retval = -EINVAL;
2638 if (fb->flags & V4L2_FBUF_FLAG_OVERLAY) {
2639 if (fb->fmt.width > bttv_tvnorms[btv->tvnorm].swidth)
2640 goto fh_unlock_and_return;
2641 if (fb->fmt.height > bttv_tvnorms[btv->tvnorm].sheight)
2642 goto fh_unlock_and_return;
2643 }
2644
2645 /* ok, accept it */
2646 btv->fbuf.base = fb->base;
2647 btv->fbuf.fmt.width = fb->fmt.width;
2648 btv->fbuf.fmt.height = fb->fmt.height;
2649 if (0 != fb->fmt.bytesperline)
2650 btv->fbuf.fmt.bytesperline = fb->fmt.bytesperline;
2651 else
2652 btv->fbuf.fmt.bytesperline = btv->fbuf.fmt.width*fmt->depth/8;
2653
2654 retval = 0;
2655 fh->ovfmt = fmt;
2656 btv->init.ovfmt = fmt;
2657 if (fb->flags & V4L2_FBUF_FLAG_OVERLAY) {
2658 fh->ov.w.left = 0;
2659 fh->ov.w.top = 0;
2660 fh->ov.w.width = fb->fmt.width;
2661 fh->ov.w.height = fb->fmt.height;
2662 btv->init.ov.w.width = fb->fmt.width;
2663 btv->init.ov.w.height = fb->fmt.height;
2664 if (fh->ov.clips)
2665 kfree(fh->ov.clips);
2666 fh->ov.clips = NULL;
2667 fh->ov.nclips = 0;
2668
2669 if (check_btres(fh, RESOURCE_OVERLAY)) {
2670 struct bttv_buffer *new;
2671
2672 new = videobuf_alloc(sizeof(*new));
2673 bttv_overlay_risc(btv,&fh->ov,fh->ovfmt,new);
2674 retval = bttv_switch_overlay(btv,fh,new);
2675 }
2676 }
2677 up(&fh->cap.lock);
2678 return retval;
2679 }
2680
2681 case VIDIOC_REQBUFS:
2682 return videobuf_reqbufs(bttv_queue(fh),arg);
2683
2684 case VIDIOC_QUERYBUF:
2685 return videobuf_querybuf(bttv_queue(fh),arg);
2686
2687 case VIDIOC_QBUF:
2688 return videobuf_qbuf(bttv_queue(fh),arg);
2689
2690 case VIDIOC_DQBUF:
2691 return videobuf_dqbuf(bttv_queue(fh),arg,
2692 file->f_flags & O_NONBLOCK);
2693
2694 case VIDIOC_STREAMON:
2695 {
2696 int res = bttv_resource(fh);
2697
2698 if (!check_alloc_btres(btv,fh,res))
2699 return -EBUSY;
2700 return videobuf_streamon(bttv_queue(fh));
2701 }
2702 case VIDIOC_STREAMOFF:
2703 {
2704 int res = bttv_resource(fh);
2705
2706 retval = videobuf_streamoff(bttv_queue(fh));
2707 if (retval < 0)
2708 return retval;
2709 free_btres(btv,fh,res);
2710 return 0;
2711 }
2712
2713 case VIDIOC_QUERYCTRL:
2714 {
2715 struct v4l2_queryctrl *c = arg;
2716 int i;
2717
2718 if ((c->id < V4L2_CID_BASE ||
2719 c->id >= V4L2_CID_LASTP1) &&
2720 (c->id < V4L2_CID_PRIVATE_BASE ||
2721 c->id >= V4L2_CID_PRIVATE_LASTP1))
2722 return -EINVAL;
2723 for (i = 0; i < BTTV_CTLS; i++)
2724 if (bttv_ctls[i].id == c->id)
2725 break;
2726 if (i == BTTV_CTLS) {
2727 *c = no_ctl;
2728 return 0;
2729 }
2730 *c = bttv_ctls[i];
2731 if (i >= 4 && i <= 8) {
2732 struct video_audio va;
2733 memset(&va,0,sizeof(va));
2734 bttv_call_i2c_clients(btv, VIDIOCGAUDIO, &va);
2735 if (btv->audio_hook)
2736 btv->audio_hook(btv,&va,0);
2737 switch (bttv_ctls[i].id) {
2738 case V4L2_CID_AUDIO_VOLUME:
2739 if (!(va.flags & VIDEO_AUDIO_VOLUME))
2740 *c = no_ctl;
2741 break;
2742 case V4L2_CID_AUDIO_BALANCE:
2743 if (!(va.flags & VIDEO_AUDIO_BALANCE))
2744 *c = no_ctl;
2745 break;
2746 case V4L2_CID_AUDIO_BASS:
2747 if (!(va.flags & VIDEO_AUDIO_BASS))
2748 *c = no_ctl;
2749 break;
2750 case V4L2_CID_AUDIO_TREBLE:
2751 if (!(va.flags & VIDEO_AUDIO_TREBLE))
2752 *c = no_ctl;
2753 break;
2754 }
2755 }
2756 return 0;
2757 }
2758 case VIDIOC_G_CTRL:
2759 return get_control(btv,arg);
2760 case VIDIOC_S_CTRL:
2761 return set_control(btv,arg);
2762 case VIDIOC_G_PARM:
2763 {
2764 struct v4l2_streamparm *parm = arg;
2765 struct v4l2_standard s;
2766 if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
2767 return -EINVAL;
2768 memset(parm,0,sizeof(*parm));
2769 v4l2_video_std_construct(&s, bttv_tvnorms[btv->tvnorm].v4l2_id,
2770 bttv_tvnorms[btv->tvnorm].name);
2771 parm->parm.capture.timeperframe = s.frameperiod;
2772 return 0;
2773 }
2774
2775 case VIDIOC_G_PRIORITY:
2776 {
2777 enum v4l2_priority *p = arg;
2778
2779 *p = v4l2_prio_max(&btv->prio);
2780 return 0;
2781 }
2782 case VIDIOC_S_PRIORITY:
2783 {
2784 enum v4l2_priority *prio = arg;
2785
2786 return v4l2_prio_change(&btv->prio, &fh->prio, *prio);
2787 }
2788
2789 case VIDIOC_ENUMSTD:
2790 case VIDIOC_G_STD:
2791 case VIDIOC_S_STD:
2792 case VIDIOC_ENUMINPUT:
2793 case VIDIOC_G_INPUT:
2794 case VIDIOC_S_INPUT:
2795 case VIDIOC_G_TUNER:
2796 case VIDIOC_S_TUNER:
2797 case VIDIOC_G_FREQUENCY:
2798 case VIDIOC_S_FREQUENCY:
2799 return bttv_common_ioctls(btv,cmd,arg);
2800
2801 default:
2802 return -ENOIOCTLCMD;
2803 }
2804 return 0;
2805
2806 fh_unlock_and_return:
2807 up(&fh->cap.lock);
2808 return retval;
2809}
2810
2811static int bttv_ioctl(struct inode *inode, struct file *file,
2812 unsigned int cmd, unsigned long arg)
2813{
2814 struct bttv_fh *fh = file->private_data;
2815
2816 switch (cmd) {
2817 case BTTV_VBISIZE:
2818 bttv_switch_type(fh,V4L2_BUF_TYPE_VBI_CAPTURE);
2819 return fh->lines * 2 * 2048;
2820 default:
2821 return video_usercopy(inode, file, cmd, arg, bttv_do_ioctl);
2822 }
2823}
2824
2825static ssize_t bttv_read(struct file *file, char __user *data,
2826 size_t count, loff_t *ppos)
2827{
2828 struct bttv_fh *fh = file->private_data;
2829 int retval = 0;
2830
2831 if (fh->btv->errors)
2832 bttv_reinit_bt848(fh->btv);
2833 dprintk("bttv%d: read count=%d type=%s\n",
2834 fh->btv->c.nr,(int)count,v4l2_type_names[fh->type]);
2835
2836 switch (fh->type) {
2837 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
2838 if (locked_btres(fh->btv,RESOURCE_VIDEO))
2839 return -EBUSY;
2840 retval = videobuf_read_one(&fh->cap, data, count, ppos,
2841 file->f_flags & O_NONBLOCK);
2842 break;
2843 case V4L2_BUF_TYPE_VBI_CAPTURE:
2844 if (!check_alloc_btres(fh->btv,fh,RESOURCE_VBI))
2845 return -EBUSY;
2846 retval = videobuf_read_stream(&fh->vbi, data, count, ppos, 1,
2847 file->f_flags & O_NONBLOCK);
2848 break;
2849 default:
2850 BUG();
2851 }
2852 return retval;
2853}
2854
2855static unsigned int bttv_poll(struct file *file, poll_table *wait)
2856{
2857 struct bttv_fh *fh = file->private_data;
2858 struct bttv_buffer *buf;
2859 enum v4l2_field field;
2860
2861 if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) {
2862 if (!check_alloc_btres(fh->btv,fh,RESOURCE_VBI))
2863 return POLLERR;
2864 return videobuf_poll_stream(file, &fh->vbi, wait);
2865 }
2866
2867 if (check_btres(fh,RESOURCE_VIDEO)) {
2868 /* streaming capture */
2869 if (list_empty(&fh->cap.stream))
2870 return POLLERR;
2871 buf = list_entry(fh->cap.stream.next,struct bttv_buffer,vb.stream);
2872 } else {
2873 /* read() capture */
2874 down(&fh->cap.lock);
2875 if (NULL == fh->cap.read_buf) {
2876 /* need to capture a new frame */
2877 if (locked_btres(fh->btv,RESOURCE_VIDEO)) {
2878 up(&fh->cap.lock);
2879 return POLLERR;
2880 }
2881 fh->cap.read_buf = videobuf_alloc(fh->cap.msize);
2882 if (NULL == fh->cap.read_buf) {
2883 up(&fh->cap.lock);
2884 return POLLERR;
2885 }
2886 fh->cap.read_buf->memory = V4L2_MEMORY_USERPTR;
2887 field = videobuf_next_field(&fh->cap);
2888 if (0 != fh->cap.ops->buf_prepare(&fh->cap,fh->cap.read_buf,field)) {
2889 up(&fh->cap.lock);
2890 return POLLERR;
2891 }
2892 fh->cap.ops->buf_queue(&fh->cap,fh->cap.read_buf);
2893 fh->cap.read_off = 0;
2894 }
2895 up(&fh->cap.lock);
2896 buf = (struct bttv_buffer*)fh->cap.read_buf;
2897 }
2898
2899 poll_wait(file, &buf->vb.done, wait);
2900 if (buf->vb.state == STATE_DONE ||
2901 buf->vb.state == STATE_ERROR)
2902 return POLLIN|POLLRDNORM;
2903 return 0;
2904}
2905
2906static int bttv_open(struct inode *inode, struct file *file)
2907{
2908 int minor = iminor(inode);
2909 struct bttv *btv = NULL;
2910 struct bttv_fh *fh;
2911 enum v4l2_buf_type type = 0;
2912 unsigned int i;
2913
2914 dprintk(KERN_DEBUG "bttv: open minor=%d\n",minor);
2915
2916 for (i = 0; i < bttv_num; i++) {
2917 if (bttvs[i].video_dev &&
2918 bttvs[i].video_dev->minor == minor) {
2919 btv = &bttvs[i];
2920 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2921 break;
2922 }
2923 if (bttvs[i].vbi_dev &&
2924 bttvs[i].vbi_dev->minor == minor) {
2925 btv = &bttvs[i];
2926 type = V4L2_BUF_TYPE_VBI_CAPTURE;
2927 break;
2928 }
2929 }
2930 if (NULL == btv)
2931 return -ENODEV;
2932
2933 dprintk(KERN_DEBUG "bttv%d: open called (type=%s)\n",
2934 btv->c.nr,v4l2_type_names[type]);
2935
2936 /* allocate per filehandle data */
2937 fh = kmalloc(sizeof(*fh),GFP_KERNEL);
2938 if (NULL == fh)
2939 return -ENOMEM;
2940 file->private_data = fh;
2941 *fh = btv->init;
2942 fh->type = type;
2943 fh->ov.setup_ok = 0;
2944 v4l2_prio_open(&btv->prio,&fh->prio);
2945
2946 videobuf_queue_init(&fh->cap, &bttv_video_qops,
2947 btv->c.pci, &btv->s_lock,
2948 V4L2_BUF_TYPE_VIDEO_CAPTURE,
2949 V4L2_FIELD_INTERLACED,
2950 sizeof(struct bttv_buffer),
2951 fh);
2952 videobuf_queue_init(&fh->vbi, &bttv_vbi_qops,
2953 btv->c.pci, &btv->s_lock,
2954 V4L2_BUF_TYPE_VBI_CAPTURE,
2955 V4L2_FIELD_SEQ_TB,
2956 sizeof(struct bttv_buffer),
2957 fh);
2958 i2c_vidiocschan(btv);
2959
2960 btv->users++;
2961 if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type)
2962 bttv_vbi_setlines(fh,btv,16);
2963 bttv_field_count(btv);
2964 return 0;
2965}
2966
2967static int bttv_release(struct inode *inode, struct file *file)
2968{
2969 struct bttv_fh *fh = file->private_data;
2970 struct bttv *btv = fh->btv;
2971
2972 /* turn off overlay */
2973 if (check_btres(fh, RESOURCE_OVERLAY))
2974 bttv_switch_overlay(btv,fh,NULL);
2975
2976 /* stop video capture */
2977 if (check_btres(fh, RESOURCE_VIDEO)) {
2978 videobuf_streamoff(&fh->cap);
2979 free_btres(btv,fh,RESOURCE_VIDEO);
2980 }
2981 if (fh->cap.read_buf) {
2982 buffer_release(&fh->cap,fh->cap.read_buf);
2983 kfree(fh->cap.read_buf);
2984 }
2985
2986 /* stop vbi capture */
2987 if (check_btres(fh, RESOURCE_VBI)) {
2988 if (fh->vbi.streaming)
2989 videobuf_streamoff(&fh->vbi);
2990 if (fh->vbi.reading)
2991 videobuf_read_stop(&fh->vbi);
2992 free_btres(btv,fh,RESOURCE_VBI);
2993 }
2994
2995 /* free stuff */
2996 videobuf_mmap_free(&fh->cap);
2997 videobuf_mmap_free(&fh->vbi);
2998 v4l2_prio_close(&btv->prio,&fh->prio);
2999 file->private_data = NULL;
3000 kfree(fh);
3001
3002 btv->users--;
3003 bttv_field_count(btv);
3004 return 0;
3005}
3006
3007static int
3008bttv_mmap(struct file *file, struct vm_area_struct *vma)
3009{
3010 struct bttv_fh *fh = file->private_data;
3011
3012 dprintk("bttv%d: mmap type=%s 0x%lx+%ld\n",
3013 fh->btv->c.nr, v4l2_type_names[fh->type],
3014 vma->vm_start, vma->vm_end - vma->vm_start);
3015 return videobuf_mmap_mapper(bttv_queue(fh),vma);
3016}
3017
3018static struct file_operations bttv_fops =
3019{
3020 .owner = THIS_MODULE,
3021 .open = bttv_open,
3022 .release = bttv_release,
3023 .ioctl = bttv_ioctl,
3024 .llseek = no_llseek,
3025 .read = bttv_read,
3026 .mmap = bttv_mmap,
3027 .poll = bttv_poll,
3028};
3029
3030static struct video_device bttv_video_template =
3031{
3032 .name = "UNSET",
3033 .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER|VID_TYPE_OVERLAY|
3034 VID_TYPE_CLIPPING|VID_TYPE_SCALES,
3035 .hardware = VID_HARDWARE_BT848,
3036 .fops = &bttv_fops,
3037 .minor = -1,
3038};
3039
3040static struct video_device bttv_vbi_template =
3041{
3042 .name = "bt848/878 vbi",
3043 .type = VID_TYPE_TUNER|VID_TYPE_TELETEXT,
3044 .hardware = VID_HARDWARE_BT848,
3045 .fops = &bttv_fops,
3046 .minor = -1,
3047};
3048
3049/* ----------------------------------------------------------------------- */
3050/* radio interface */
3051
3052static int radio_open(struct inode *inode, struct file *file)
3053{
3054 int minor = iminor(inode);
3055 struct bttv *btv = NULL;
3056 unsigned int i;
3057
3058 dprintk("bttv: open minor=%d\n",minor);
3059
3060 for (i = 0; i < bttv_num; i++) {
3061 if (bttvs[i].radio_dev->minor == minor) {
3062 btv = &bttvs[i];
3063 break;
3064 }
3065 }
3066 if (NULL == btv)
3067 return -ENODEV;
3068
3069 dprintk("bttv%d: open called (radio)\n",btv->c.nr);
3070 down(&btv->lock);
3071 if (btv->radio_user) {
3072 up(&btv->lock);
3073 return -EBUSY;
3074 }
3075 btv->radio_user++;
3076 file->private_data = btv;
3077
3078 i2c_vidiocschan(btv);
3079 bttv_call_i2c_clients(btv,AUDC_SET_RADIO,&btv->tuner_type);
3080 audio_mux(btv,AUDIO_RADIO);
3081
3082 up(&btv->lock);
3083 return 0;
3084}
3085
3086static int radio_release(struct inode *inode, struct file *file)
3087{
3088 struct bttv *btv = file->private_data;
3089
3090 btv->radio_user--;
3091 return 0;
3092}
3093
3094static int radio_do_ioctl(struct inode *inode, struct file *file,
3095 unsigned int cmd, void *arg)
3096{
3097 struct bttv *btv = file->private_data;
3098
3099 switch (cmd) {
3100 case VIDIOCGCAP:
3101 {
3102 struct video_capability *cap = arg;
3103
3104 memset(cap,0,sizeof(*cap));
3105 strcpy(cap->name,btv->radio_dev->name);
3106 cap->type = VID_TYPE_TUNER;
3107 cap->channels = 1;
3108 cap->audios = 1;
3109 return 0;
3110 }
3111
3112 case VIDIOCGTUNER:
3113 {
3114 struct video_tuner *v = arg;
3115
3116 if(v->tuner)
3117 return -EINVAL;
3118 memset(v,0,sizeof(*v));
3119 strcpy(v->name, "Radio");
3120 /* japan: 76.0 MHz - 89.9 MHz
3121 western europe: 87.5 MHz - 108.0 MHz
3122 russia: 65.0 MHz - 108.0 MHz */
3123 v->rangelow=(int)(65*16);
3124 v->rangehigh=(int)(108*16);
3125 bttv_call_i2c_clients(btv,cmd,v);
3126 return 0;
3127 }
3128 case VIDIOCSTUNER:
3129 /* nothing to do */
3130 return 0;
3131
3132 case BTTV_VERSION:
3133 case VIDIOCGFREQ:
3134 case VIDIOCSFREQ:
3135 case VIDIOCGAUDIO:
3136 case VIDIOCSAUDIO:
3137 return bttv_common_ioctls(btv,cmd,arg);
3138
3139 default:
3140 return -ENOIOCTLCMD;
3141 }
3142 return 0;
3143}
3144
3145static int radio_ioctl(struct inode *inode, struct file *file,
3146 unsigned int cmd, unsigned long arg)
3147{
3148 return video_usercopy(inode, file, cmd, arg, radio_do_ioctl);
3149}
3150
3151static struct file_operations radio_fops =
3152{
3153 .owner = THIS_MODULE,
3154 .open = radio_open,
3155 .release = radio_release,
3156 .ioctl = radio_ioctl,
3157 .llseek = no_llseek,
3158};
3159
3160static struct video_device radio_template =
3161{
3162 .name = "bt848/878 radio",
3163 .type = VID_TYPE_TUNER,
3164 .hardware = VID_HARDWARE_BT848,
3165 .fops = &radio_fops,
3166 .minor = -1,
3167};
3168
3169/* ----------------------------------------------------------------------- */
3170/* some debug code */
3171
3172int bttv_risc_decode(u32 risc)
3173{
3174 static char *instr[16] = {
3175 [ BT848_RISC_WRITE >> 28 ] = "write",
3176 [ BT848_RISC_SKIP >> 28 ] = "skip",
3177 [ BT848_RISC_WRITEC >> 28 ] = "writec",
3178 [ BT848_RISC_JUMP >> 28 ] = "jump",
3179 [ BT848_RISC_SYNC >> 28 ] = "sync",
3180 [ BT848_RISC_WRITE123 >> 28 ] = "write123",
3181 [ BT848_RISC_SKIP123 >> 28 ] = "skip123",
3182 [ BT848_RISC_WRITE1S23 >> 28 ] = "write1s23",
3183 };
3184 static int incr[16] = {
3185 [ BT848_RISC_WRITE >> 28 ] = 2,
3186 [ BT848_RISC_JUMP >> 28 ] = 2,
3187 [ BT848_RISC_SYNC >> 28 ] = 2,
3188 [ BT848_RISC_WRITE123 >> 28 ] = 5,
3189 [ BT848_RISC_SKIP123 >> 28 ] = 2,
3190 [ BT848_RISC_WRITE1S23 >> 28 ] = 3,
3191 };
3192 static char *bits[] = {
3193 "be0", "be1", "be2", "be3/resync",
3194 "set0", "set1", "set2", "set3",
3195 "clr0", "clr1", "clr2", "clr3",
3196 "irq", "res", "eol", "sol",
3197 };
3198 int i;
3199
3200 printk("0x%08x [ %s", risc,
3201 instr[risc >> 28] ? instr[risc >> 28] : "INVALID");
3202 for (i = ARRAY_SIZE(bits)-1; i >= 0; i--)
3203 if (risc & (1 << (i + 12)))
3204 printk(" %s",bits[i]);
3205 printk(" count=%d ]\n", risc & 0xfff);
3206 return incr[risc >> 28] ? incr[risc >> 28] : 1;
3207}
3208
3209void bttv_risc_disasm(struct bttv *btv,
3210 struct btcx_riscmem *risc)
3211{
3212 unsigned int i,j,n;
3213
3214 printk("%s: risc disasm: %p [dma=0x%08lx]\n",
3215 btv->c.name, risc->cpu, (unsigned long)risc->dma);
3216 for (i = 0; i < (risc->size >> 2); i += n) {
3217 printk("%s: 0x%lx: ", btv->c.name,
3218 (unsigned long)(risc->dma + (i<<2)));
3219 n = bttv_risc_decode(risc->cpu[i]);
3220 for (j = 1; j < n; j++)
3221 printk("%s: 0x%lx: 0x%08x [ arg #%d ]\n",
3222 btv->c.name, (unsigned long)(risc->dma + ((i+j)<<2)),
3223 risc->cpu[i+j], j);
3224 if (0 == risc->cpu[i])
3225 break;
3226 }
3227}
3228
3229static void bttv_print_riscaddr(struct bttv *btv)
3230{
3231 printk(" main: %08Lx\n",
3232 (unsigned long long)btv->main.dma);
3233 printk(" vbi : o=%08Lx e=%08Lx\n",
3234 btv->cvbi ? (unsigned long long)btv->cvbi->top.dma : 0,
3235 btv->cvbi ? (unsigned long long)btv->cvbi->bottom.dma : 0);
3236 printk(" cap : o=%08Lx e=%08Lx\n",
3237 btv->curr.top ? (unsigned long long)btv->curr.top->top.dma : 0,
3238 btv->curr.bottom ? (unsigned long long)btv->curr.bottom->bottom.dma : 0);
3239 printk(" scr : o=%08Lx e=%08Lx\n",
3240 btv->screen ? (unsigned long long)btv->screen->top.dma : 0,
3241 btv->screen ? (unsigned long long)btv->screen->bottom.dma : 0);
3242 bttv_risc_disasm(btv, &btv->main);
3243}
3244
3245/* ----------------------------------------------------------------------- */
3246/* irq handler */
3247
3248static char *irq_name[] = {
3249 "FMTCHG", // format change detected (525 vs. 625)
3250 "VSYNC", // vertical sync (new field)
3251 "HSYNC", // horizontal sync
3252 "OFLOW", // chroma/luma AGC overflow
3253 "HLOCK", // horizontal lock changed
3254 "VPRES", // video presence changed
3255 "6", "7",
3256 "I2CDONE", // hw irc operation finished
3257 "GPINT", // gpio port triggered irq
3258 "10",
3259 "RISCI", // risc instruction triggered irq
3260 "FBUS", // pixel data fifo dropped data (high pci bus latencies)
3261 "FTRGT", // pixel data fifo overrun
3262 "FDSR", // fifo data stream resyncronisation
3263 "PPERR", // parity error (data transfer)
3264 "RIPERR", // parity error (read risc instructions)
3265 "PABORT", // pci abort
3266 "OCERR", // risc instruction error
3267 "SCERR", // syncronisation error
3268};
3269
3270static void bttv_print_irqbits(u32 print, u32 mark)
3271{
3272 unsigned int i;
3273
3274 printk("bits:");
3275 for (i = 0; i < ARRAY_SIZE(irq_name); i++) {
3276 if (print & (1 << i))
3277 printk(" %s",irq_name[i]);
3278 if (mark & (1 << i))
3279 printk("*");
3280 }
3281}
3282
3283static void bttv_irq_debug_low_latency(struct bttv *btv, u32 rc)
3284{
3285 printk("bttv%d: irq: skipped frame [main=%lx,o_vbi=%lx,o_field=%lx,rc=%lx]\n",
3286 btv->c.nr,
3287 (unsigned long)btv->main.dma,
3288 (unsigned long)btv->main.cpu[RISC_SLOT_O_VBI+1],
3289 (unsigned long)btv->main.cpu[RISC_SLOT_O_FIELD+1],
3290 (unsigned long)rc);
3291
3292 if (0 == (btread(BT848_DSTATUS) & BT848_DSTATUS_HLOC)) {
3293 printk("bttv%d: Oh, there (temporarely?) is no input signal. "
3294 "Ok, then this is harmless, don't worry ;)\n",
3295 btv->c.nr);
3296 return;
3297 }
3298 printk("bttv%d: Uhm. Looks like we have unusual high IRQ latencies.\n",
3299 btv->c.nr);
3300 printk("bttv%d: Lets try to catch the culpit red-handed ...\n",
3301 btv->c.nr);
3302 dump_stack();
3303}
3304
3305static int
3306bttv_irq_next_video(struct bttv *btv, struct bttv_buffer_set *set)
3307{
3308 struct bttv_buffer *item;
3309
3310 memset(set,0,sizeof(*set));
3311
3312 /* capture request ? */
3313 if (!list_empty(&btv->capture)) {
3314 set->frame_irq = 1;
3315 item = list_entry(btv->capture.next, struct bttv_buffer, vb.queue);
3316 if (V4L2_FIELD_HAS_TOP(item->vb.field))
3317 set->top = item;
3318 if (V4L2_FIELD_HAS_BOTTOM(item->vb.field))
3319 set->bottom = item;
3320
3321 /* capture request for other field ? */
3322 if (!V4L2_FIELD_HAS_BOTH(item->vb.field) &&
3323 (item->vb.queue.next != &btv->capture)) {
3324 item = list_entry(item->vb.queue.next, struct bttv_buffer, vb.queue);
3325 if (!V4L2_FIELD_HAS_BOTH(item->vb.field)) {
3326 if (NULL == set->top &&
3327 V4L2_FIELD_TOP == item->vb.field) {
3328 set->top = item;
3329 }
3330 if (NULL == set->bottom &&
3331 V4L2_FIELD_BOTTOM == item->vb.field) {
3332 set->bottom = item;
3333 }
3334 if (NULL != set->top && NULL != set->bottom)
3335 set->top_irq = 2;
3336 }
3337 }
3338 }
3339
3340 /* screen overlay ? */
3341 if (NULL != btv->screen) {
3342 if (V4L2_FIELD_HAS_BOTH(btv->screen->vb.field)) {
3343 if (NULL == set->top && NULL == set->bottom) {
3344 set->top = btv->screen;
3345 set->bottom = btv->screen;
3346 }
3347 } else {
3348 if (V4L2_FIELD_TOP == btv->screen->vb.field &&
3349 NULL == set->top) {
3350 set->top = btv->screen;
3351 }
3352 if (V4L2_FIELD_BOTTOM == btv->screen->vb.field &&
3353 NULL == set->bottom) {
3354 set->bottom = btv->screen;
3355 }
3356 }
3357 }
3358
3359 dprintk("bttv%d: next set: top=%p bottom=%p [screen=%p,irq=%d,%d]\n",
3360 btv->c.nr,set->top, set->bottom,
3361 btv->screen,set->frame_irq,set->top_irq);
3362 return 0;
3363}
3364
3365static void
3366bttv_irq_wakeup_video(struct bttv *btv, struct bttv_buffer_set *wakeup,
3367 struct bttv_buffer_set *curr, unsigned int state)
3368{
3369 struct timeval ts;
3370
3371 do_gettimeofday(&ts);
3372
3373 if (wakeup->top == wakeup->bottom) {
3374 if (NULL != wakeup->top && curr->top != wakeup->top) {
3375 if (irq_debug > 1)
3376 printk("bttv%d: wakeup: both=%p\n",btv->c.nr,wakeup->top);
3377 wakeup->top->vb.ts = ts;
3378 wakeup->top->vb.field_count = btv->field_count;
3379 wakeup->top->vb.state = state;
3380 wake_up(&wakeup->top->vb.done);
3381 }
3382 } else {
3383 if (NULL != wakeup->top && curr->top != wakeup->top) {
3384 if (irq_debug > 1)
3385 printk("bttv%d: wakeup: top=%p\n",btv->c.nr,wakeup->top);
3386 wakeup->top->vb.ts = ts;
3387 wakeup->top->vb.field_count = btv->field_count;
3388 wakeup->top->vb.state = state;
3389 wake_up(&wakeup->top->vb.done);
3390 }
3391 if (NULL != wakeup->bottom && curr->bottom != wakeup->bottom) {
3392 if (irq_debug > 1)
3393 printk("bttv%d: wakeup: bottom=%p\n",btv->c.nr,wakeup->bottom);
3394 wakeup->bottom->vb.ts = ts;
3395 wakeup->bottom->vb.field_count = btv->field_count;
3396 wakeup->bottom->vb.state = state;
3397 wake_up(&wakeup->bottom->vb.done);
3398 }
3399 }
3400}
3401
3402static void
3403bttv_irq_wakeup_vbi(struct bttv *btv, struct bttv_buffer *wakeup,
3404 unsigned int state)
3405{
3406 struct timeval ts;
3407
3408 if (NULL == wakeup)
3409 return;
3410
3411 do_gettimeofday(&ts);
3412 wakeup->vb.ts = ts;
3413 wakeup->vb.field_count = btv->field_count;
3414 wakeup->vb.state = state;
3415 wake_up(&wakeup->vb.done);
3416}
3417
3418static void bttv_irq_timeout(unsigned long data)
3419{
3420 struct bttv *btv = (struct bttv *)data;
3421 struct bttv_buffer_set old,new;
3422 struct bttv_buffer *ovbi;
3423 struct bttv_buffer *item;
3424 unsigned long flags;
3425
3426 if (bttv_verbose) {
3427 printk(KERN_INFO "bttv%d: timeout: drop=%d irq=%d/%d, risc=%08x, ",
3428 btv->c.nr, btv->framedrop, btv->irq_me, btv->irq_total,
3429 btread(BT848_RISC_COUNT));
3430 bttv_print_irqbits(btread(BT848_INT_STAT),0);
3431 printk("\n");
3432 }
3433
3434 spin_lock_irqsave(&btv->s_lock,flags);
3435
3436 /* deactivate stuff */
3437 memset(&new,0,sizeof(new));
3438 old = btv->curr;
3439 ovbi = btv->cvbi;
3440 btv->curr = new;
3441 btv->cvbi = NULL;
3442 btv->loop_irq = 0;
3443 bttv_buffer_activate_video(btv, &new);
3444 bttv_buffer_activate_vbi(btv, NULL);
3445 bttv_set_dma(btv, 0);
3446
3447 /* wake up */
3448 bttv_irq_wakeup_video(btv, &old, &new, STATE_ERROR);
3449 bttv_irq_wakeup_vbi(btv, ovbi, STATE_ERROR);
3450
3451 /* cancel all outstanding capture / vbi requests */
3452 while (!list_empty(&btv->capture)) {
3453 item = list_entry(btv->capture.next, struct bttv_buffer, vb.queue);
3454 list_del(&item->vb.queue);
3455 item->vb.state = STATE_ERROR;
3456 wake_up(&item->vb.done);
3457 }
3458 while (!list_empty(&btv->vcapture)) {
3459 item = list_entry(btv->vcapture.next, struct bttv_buffer, vb.queue);
3460 list_del(&item->vb.queue);
3461 item->vb.state = STATE_ERROR;
3462 wake_up(&item->vb.done);
3463 }
3464
3465 btv->errors++;
3466 spin_unlock_irqrestore(&btv->s_lock,flags);
3467}
3468
3469static void
3470bttv_irq_wakeup_top(struct bttv *btv)
3471{
3472 struct bttv_buffer *wakeup = btv->curr.top;
3473
3474 if (NULL == wakeup)
3475 return;
3476
3477 spin_lock(&btv->s_lock);
3478 btv->curr.top_irq = 0;
3479 btv->curr.top = NULL;
3480 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL, 0);
3481
3482 do_gettimeofday(&wakeup->vb.ts);
3483 wakeup->vb.field_count = btv->field_count;
3484 wakeup->vb.state = STATE_DONE;
3485 wake_up(&wakeup->vb.done);
3486 spin_unlock(&btv->s_lock);
3487}
3488
3489static inline int is_active(struct btcx_riscmem *risc, u32 rc)
3490{
3491 if (rc < risc->dma)
3492 return 0;
3493 if (rc > risc->dma + risc->size)
3494 return 0;
3495 return 1;
3496}
3497
3498static void
3499bttv_irq_switch_video(struct bttv *btv)
3500{
3501 struct bttv_buffer_set new;
3502 struct bttv_buffer_set old;
3503 dma_addr_t rc;
3504
3505 spin_lock(&btv->s_lock);
3506
3507 /* new buffer set */
3508 bttv_irq_next_video(btv, &new);
3509 rc = btread(BT848_RISC_COUNT);
3510 if ((btv->curr.top && is_active(&btv->curr.top->top, rc)) ||
3511 (btv->curr.bottom && is_active(&btv->curr.bottom->bottom, rc))) {
3512 btv->framedrop++;
3513 if (debug_latency)
3514 bttv_irq_debug_low_latency(btv, rc);
3515 spin_unlock(&btv->s_lock);
3516 return;
3517 }
3518
3519 /* switch over */
3520 old = btv->curr;
3521 btv->curr = new;
3522 btv->loop_irq &= ~1;
3523 bttv_buffer_activate_video(btv, &new);
3524 bttv_set_dma(btv, 0);
3525
3526 /* switch input */
3527 if (UNSET != btv->new_input) {
3528 video_mux(btv,btv->new_input);
3529 btv->new_input = UNSET;
3530 }
3531
3532 /* wake up finished buffers */
3533 bttv_irq_wakeup_video(btv, &old, &new, STATE_DONE);
3534 spin_unlock(&btv->s_lock);
3535}
3536
3537static void
3538bttv_irq_switch_vbi(struct bttv *btv)
3539{
3540 struct bttv_buffer *new = NULL;
3541 struct bttv_buffer *old;
3542 u32 rc;
3543
3544 spin_lock(&btv->s_lock);
3545
3546 if (!list_empty(&btv->vcapture))
3547 new = list_entry(btv->vcapture.next, struct bttv_buffer, vb.queue);
3548 old = btv->cvbi;
3549
3550 rc = btread(BT848_RISC_COUNT);
3551 if (NULL != old && (is_active(&old->top, rc) ||
3552 is_active(&old->bottom, rc))) {
3553 btv->framedrop++;
3554 if (debug_latency)
3555 bttv_irq_debug_low_latency(btv, rc);
3556 spin_unlock(&btv->s_lock);
3557 return;
3558 }
3559
3560 /* switch */
3561 btv->cvbi = new;
3562 btv->loop_irq &= ~4;
3563 bttv_buffer_activate_vbi(btv, new);
3564 bttv_set_dma(btv, 0);
3565
3566 bttv_irq_wakeup_vbi(btv, old, STATE_DONE);
3567 spin_unlock(&btv->s_lock);
3568}
3569
3570static irqreturn_t bttv_irq(int irq, void *dev_id, struct pt_regs * regs)
3571{
3572 u32 stat,astat;
3573 u32 dstat;
3574 int count;
3575 struct bttv *btv;
3576 int handled = 0;
3577
3578 btv=(struct bttv *)dev_id;
3579 count=0;
3580 while (1) {
3581 /* get/clear interrupt status bits */
3582 stat=btread(BT848_INT_STAT);
3583 astat=stat&btread(BT848_INT_MASK);
3584 if (!astat)
3585 break;
3586 handled = 1;
3587 btwrite(stat,BT848_INT_STAT);
3588
3589 /* get device status bits */
3590 dstat=btread(BT848_DSTATUS);
3591
3592 if (irq_debug) {
3593 printk(KERN_DEBUG "bttv%d: irq loop=%d fc=%d "
3594 "riscs=%x, riscc=%08x, ",
3595 btv->c.nr, count, btv->field_count,
3596 stat>>28, btread(BT848_RISC_COUNT));
3597 bttv_print_irqbits(stat,astat);
3598 if (stat & BT848_INT_HLOCK)
3599 printk(" HLOC => %s", (dstat & BT848_DSTATUS_HLOC)
3600 ? "yes" : "no");
3601 if (stat & BT848_INT_VPRES)
3602 printk(" PRES => %s", (dstat & BT848_DSTATUS_PRES)
3603 ? "yes" : "no");
3604 if (stat & BT848_INT_FMTCHG)
3605 printk(" NUML => %s", (dstat & BT848_DSTATUS_NUML)
3606 ? "625" : "525");
3607 printk("\n");
3608 }
3609
3610 if (astat&BT848_INT_VSYNC)
3611 btv->field_count++;
3612
3613 if (astat & BT848_INT_GPINT) {
3614 wake_up(&btv->gpioq);
3615 bttv_gpio_irq(&btv->c);
3616 }
3617
3618 if (astat & BT848_INT_I2CDONE) {
3619 btv->i2c_done = stat;
3620 wake_up(&btv->i2c_queue);
3621 }
3622
3623 if ((astat & BT848_INT_RISCI) && (stat & (4<<28)))
3624 bttv_irq_switch_vbi(btv);
3625
3626 if ((astat & BT848_INT_RISCI) && (stat & (2<<28)))
3627 bttv_irq_wakeup_top(btv);
3628
3629 if ((astat & BT848_INT_RISCI) && (stat & (1<<28)))
3630 bttv_irq_switch_video(btv);
3631
3632 if ((astat & BT848_INT_HLOCK) && btv->opt_automute)
3633 audio_mux(btv, -1);
3634
3635 if (astat & (BT848_INT_SCERR|BT848_INT_OCERR)) {
3636 printk(KERN_INFO "bttv%d: %s%s @ %08x,",btv->c.nr,
3637 (astat & BT848_INT_SCERR) ? "SCERR" : "",
3638 (astat & BT848_INT_OCERR) ? "OCERR" : "",
3639 btread(BT848_RISC_COUNT));
3640 bttv_print_irqbits(stat,astat);
3641 printk("\n");
3642 if (bttv_debug)
3643 bttv_print_riscaddr(btv);
3644 }
3645 if (fdsr && astat & BT848_INT_FDSR) {
3646 printk(KERN_INFO "bttv%d: FDSR @ %08x\n",
3647 btv->c.nr,btread(BT848_RISC_COUNT));
3648 if (bttv_debug)
3649 bttv_print_riscaddr(btv);
3650 }
3651
3652 count++;
3653 if (count > 4) {
3654 btwrite(0, BT848_INT_MASK);
3655 printk(KERN_ERR
3656 "bttv%d: IRQ lockup, cleared int mask [", btv->c.nr);
3657 bttv_print_irqbits(stat,astat);
3658 printk("]\n");
3659 }
3660 }
3661 btv->irq_total++;
3662 if (handled)
3663 btv->irq_me++;
3664 return IRQ_RETVAL(handled);
3665}
3666
3667
3668/* ----------------------------------------------------------------------- */
3669/* initialitation */
3670
3671static struct video_device *vdev_init(struct bttv *btv,
3672 struct video_device *template,
3673 char *type)
3674{
3675 struct video_device *vfd;
3676
3677 vfd = video_device_alloc();
3678 if (NULL == vfd)
3679 return NULL;
3680 *vfd = *template;
3681 vfd->minor = -1;
3682 vfd->dev = &btv->c.pci->dev;
3683 vfd->release = video_device_release;
3684 snprintf(vfd->name, sizeof(vfd->name), "BT%d%s %s (%s)",
3685 btv->id, (btv->id==848 && btv->revision==0x12) ? "A" : "",
3686 type, bttv_tvcards[btv->c.type].name);
3687 return vfd;
3688}
3689
3690static void bttv_unregister_video(struct bttv *btv)
3691{
3692 if (btv->video_dev) {
3693 if (-1 != btv->video_dev->minor)
3694 video_unregister_device(btv->video_dev);
3695 else
3696 video_device_release(btv->video_dev);
3697 btv->video_dev = NULL;
3698 }
3699 if (btv->vbi_dev) {
3700 if (-1 != btv->vbi_dev->minor)
3701 video_unregister_device(btv->vbi_dev);
3702 else
3703 video_device_release(btv->vbi_dev);
3704 btv->vbi_dev = NULL;
3705 }
3706 if (btv->radio_dev) {
3707 if (-1 != btv->radio_dev->minor)
3708 video_unregister_device(btv->radio_dev);
3709 else
3710 video_device_release(btv->radio_dev);
3711 btv->radio_dev = NULL;
3712 }
3713}
3714
3715/* register video4linux devices */
3716static int __devinit bttv_register_video(struct bttv *btv)
3717{
3718 /* video */
3719 btv->video_dev = vdev_init(btv, &bttv_video_template, "video");
3720 if (NULL == btv->video_dev)
3721 goto err;
3722 if (video_register_device(btv->video_dev,VFL_TYPE_GRABBER,video_nr)<0)
3723 goto err;
3724 printk(KERN_INFO "bttv%d: registered device video%d\n",
3725 btv->c.nr,btv->video_dev->minor & 0x1f);
3726 video_device_create_file(btv->video_dev, &class_device_attr_card);
3727
3728 /* vbi */
3729 btv->vbi_dev = vdev_init(btv, &bttv_vbi_template, "vbi");
3730 if (NULL == btv->vbi_dev)
3731 goto err;
3732 if (video_register_device(btv->vbi_dev,VFL_TYPE_VBI,vbi_nr)<0)
3733 goto err;
3734 printk(KERN_INFO "bttv%d: registered device vbi%d\n",
3735 btv->c.nr,btv->vbi_dev->minor & 0x1f);
3736
3737 if (!btv->has_radio)
3738 return 0;
3739 /* radio */
3740 btv->radio_dev = vdev_init(btv, &radio_template, "radio");
3741 if (NULL == btv->radio_dev)
3742 goto err;
3743 if (video_register_device(btv->radio_dev, VFL_TYPE_RADIO,radio_nr)<0)
3744 goto err;
3745 printk(KERN_INFO "bttv%d: registered device radio%d\n",
3746 btv->c.nr,btv->radio_dev->minor & 0x1f);
3747
3748 /* all done */
3749 return 0;
3750
3751 err:
3752 bttv_unregister_video(btv);
3753 return -1;
3754}
3755
3756
3757/* on OpenFirmware machines (PowerMac at least), PCI memory cycle */
3758/* response on cards with no firmware is not enabled by OF */
3759static void pci_set_command(struct pci_dev *dev)
3760{
3761#if defined(__powerpc__)
3762 unsigned int cmd;
3763
3764 pci_read_config_dword(dev, PCI_COMMAND, &cmd);
3765 cmd = (cmd | PCI_COMMAND_MEMORY );
3766 pci_write_config_dword(dev, PCI_COMMAND, cmd);
3767#endif
3768}
3769
3770static int __devinit bttv_probe(struct pci_dev *dev,
3771 const struct pci_device_id *pci_id)
3772{
3773 int result;
3774 unsigned char lat;
3775 struct bttv *btv;
3776
3777 if (bttv_num == BTTV_MAX)
3778 return -ENOMEM;
3779 printk(KERN_INFO "bttv: Bt8xx card found (%d).\n", bttv_num);
3780 btv=&bttvs[bttv_num];
3781 memset(btv,0,sizeof(*btv));
3782 btv->c.nr = bttv_num;
3783 sprintf(btv->c.name,"bttv%d",btv->c.nr);
3784
3785 /* initialize structs / fill in defaults */
3786 init_MUTEX(&btv->lock);
3787 init_MUTEX(&btv->reslock);
3788 spin_lock_init(&btv->s_lock);
3789 spin_lock_init(&btv->gpio_lock);
3790 init_waitqueue_head(&btv->gpioq);
3791 init_waitqueue_head(&btv->i2c_queue);
3792 INIT_LIST_HEAD(&btv->c.subs);
3793 INIT_LIST_HEAD(&btv->capture);
3794 INIT_LIST_HEAD(&btv->vcapture);
3795 v4l2_prio_init(&btv->prio);
3796
3797 init_timer(&btv->timeout);
3798 btv->timeout.function = bttv_irq_timeout;
3799 btv->timeout.data = (unsigned long)btv;
3800
3801 btv->i2c_rc = -1;
3802 btv->tuner_type = UNSET;
3803 btv->pinnacle_id = UNSET;
3804 btv->new_input = UNSET;
3805 btv->gpioirq = 1;
3806 btv->has_radio=radio[btv->c.nr];
3807
3808 /* pci stuff (init, get irq/mmio, ... */
3809 btv->c.pci = dev;
3810 btv->id = dev->device;
3811 if (pci_enable_device(dev)) {
3812 printk(KERN_WARNING "bttv%d: Can't enable device.\n",
3813 btv->c.nr);
3814 return -EIO;
3815 }
3816 if (pci_set_dma_mask(dev, 0xffffffff)) {
3817 printk(KERN_WARNING "bttv%d: No suitable DMA available.\n",
3818 btv->c.nr);
3819 return -EIO;
3820 }
3821 if (!request_mem_region(pci_resource_start(dev,0),
3822 pci_resource_len(dev,0),
3823 btv->c.name)) {
3824 printk(KERN_WARNING "bttv%d: can't request iomem (0x%lx).\n",
3825 btv->c.nr, pci_resource_start(dev,0));
3826 return -EBUSY;
3827 }
3828 pci_set_master(dev);
3829 pci_set_command(dev);
3830 pci_set_drvdata(dev,btv);
3831 if (!pci_dma_supported(dev,0xffffffff)) {
3832 printk("bttv%d: Oops: no 32bit PCI DMA ???\n", btv->c.nr);
3833 result = -EIO;
3834 goto fail1;
3835 }
3836
3837 pci_read_config_byte(dev, PCI_CLASS_REVISION, &btv->revision);
3838 pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
3839 printk(KERN_INFO "bttv%d: Bt%d (rev %d) at %s, ",
3840 bttv_num,btv->id, btv->revision, pci_name(dev));
3841 printk("irq: %d, latency: %d, mmio: 0x%lx\n",
3842 btv->c.pci->irq, lat, pci_resource_start(dev,0));
3843 schedule();
3844
3845 btv->bt848_mmio=ioremap(pci_resource_start(dev,0), 0x1000);
3846 if (NULL == ioremap(pci_resource_start(dev,0), 0x1000)) {
3847 printk("bttv%d: ioremap() failed\n", btv->c.nr);
3848 result = -EIO;
3849 goto fail1;
3850 }
3851
3852 /* identify card */
3853 bttv_idcard(btv);
3854
3855 /* disable irqs, register irq handler */
3856 btwrite(0, BT848_INT_MASK);
3857 result = request_irq(btv->c.pci->irq, bttv_irq,
3858 SA_SHIRQ | SA_INTERRUPT,btv->c.name,(void *)btv);
3859 if (result < 0) {
3860 printk(KERN_ERR "bttv%d: can't get IRQ %d\n",
3861 bttv_num,btv->c.pci->irq);
3862 goto fail1;
3863 }
3864
3865 if (0 != bttv_handle_chipset(btv)) {
3866 result = -EIO;
3867 goto fail2;
3868 }
3869
3870 /* init options from insmod args */
3871 btv->opt_combfilter = combfilter;
3872 btv->opt_lumafilter = lumafilter;
3873 btv->opt_automute = automute;
3874 btv->opt_chroma_agc = chroma_agc;
3875 btv->opt_adc_crush = adc_crush;
3876 btv->opt_vcr_hack = vcr_hack;
3877 btv->opt_whitecrush_upper = whitecrush_upper;
3878 btv->opt_whitecrush_lower = whitecrush_lower;
3879
3880 /* fill struct bttv with some useful defaults */
3881 btv->init.btv = btv;
3882 btv->init.ov.w.width = 320;
3883 btv->init.ov.w.height = 240;
3884 btv->init.fmt = format_by_palette(VIDEO_PALETTE_RGB24);
3885 btv->init.width = 320;
3886 btv->init.height = 240;
3887 btv->init.lines = 16;
3888 btv->input = 0;
3889
3890 /* initialize hardware */
3891 if (bttv_gpio)
3892 bttv_gpio_tracking(btv,"pre-init");
3893
3894 bttv_risc_init_main(btv);
3895 init_bt848(btv);
3896
3897 /* gpio */
3898 btwrite(0x00, BT848_GPIO_REG_INP);
3899 btwrite(0x00, BT848_GPIO_OUT_EN);
3900 if (bttv_verbose)
3901 bttv_gpio_tracking(btv,"init");
3902
3903 /* needs to be done before i2c is registered */
3904 bttv_init_card1(btv);
3905
3906 /* register i2c + gpio */
3907 init_bttv_i2c(btv);
3908
3909 /* some card-specific stuff (needs working i2c) */
3910 bttv_init_card2(btv);
3911 init_irqreg(btv);
3912
3913 /* register video4linux + input */
3914 if (!bttv_tvcards[btv->c.type].no_video) {
3915 bttv_register_video(btv);
3916 bt848_bright(btv,32768);
3917 bt848_contrast(btv,32768);
3918 bt848_hue(btv,32768);
3919 bt848_sat(btv,32768);
3920 audio_mux(btv,AUDIO_MUTE);
3921 set_input(btv,0);
3922 }
3923
3924 /* add subdevices */
3925 if (btv->has_remote)
3926 bttv_sub_add_device(&btv->c, "remote");
3927 if (bttv_tvcards[btv->c.type].has_dvb)
3928 bttv_sub_add_device(&btv->c, "dvb");
3929
3930 /* everything is fine */
3931 bttv_num++;
3932 return 0;
3933
3934 fail2:
3935 free_irq(btv->c.pci->irq,btv);
3936
3937 fail1:
3938 if (btv->bt848_mmio)
3939 iounmap(btv->bt848_mmio);
3940 release_mem_region(pci_resource_start(btv->c.pci,0),
3941 pci_resource_len(btv->c.pci,0));
3942 pci_set_drvdata(dev,NULL);
3943 return result;
3944}
3945
3946static void __devexit bttv_remove(struct pci_dev *pci_dev)
3947{
3948 struct bttv *btv = pci_get_drvdata(pci_dev);
3949
3950 if (bttv_verbose)
3951 printk("bttv%d: unloading\n",btv->c.nr);
3952
3953 /* shutdown everything (DMA+IRQs) */
3954 btand(~15, BT848_GPIO_DMA_CTL);
3955 btwrite(0, BT848_INT_MASK);
3956 btwrite(~0x0, BT848_INT_STAT);
3957 btwrite(0x0, BT848_GPIO_OUT_EN);
3958 if (bttv_gpio)
3959 bttv_gpio_tracking(btv,"cleanup");
3960
3961 /* tell gpio modules we are leaving ... */
3962 btv->shutdown=1;
3963 wake_up(&btv->gpioq);
3964 bttv_sub_del_devices(&btv->c);
3965
3966 /* unregister i2c_bus + input */
3967 fini_bttv_i2c(btv);
3968
3969 /* unregister video4linux */
3970 bttv_unregister_video(btv);
3971
3972 /* free allocated memory */
3973 btcx_riscmem_free(btv->c.pci,&btv->main);
3974
3975 /* free ressources */
3976 free_irq(btv->c.pci->irq,btv);
3977 iounmap(btv->bt848_mmio);
3978 release_mem_region(pci_resource_start(btv->c.pci,0),
3979 pci_resource_len(btv->c.pci,0));
3980
3981 pci_set_drvdata(pci_dev, NULL);
3982 return;
3983}
3984
3985static int bttv_suspend(struct pci_dev *pci_dev, pm_message_t state)
3986{
3987 struct bttv *btv = pci_get_drvdata(pci_dev);
3988 struct bttv_buffer_set idle;
3989 unsigned long flags;
3990
3991 dprintk("bttv%d: suspend %d\n", btv->c.nr, state);
3992
3993 /* stop dma + irqs */
3994 spin_lock_irqsave(&btv->s_lock,flags);
3995 memset(&idle, 0, sizeof(idle));
3996 btv->state.video = btv->curr;
3997 btv->state.vbi = btv->cvbi;
3998 btv->state.loop_irq = btv->loop_irq;
3999 btv->curr = idle;
4000 btv->loop_irq = 0;
4001 bttv_buffer_activate_video(btv, &idle);
4002 bttv_buffer_activate_vbi(btv, NULL);
4003 bttv_set_dma(btv, 0);
4004 btwrite(0, BT848_INT_MASK);
4005 spin_unlock_irqrestore(&btv->s_lock,flags);
4006
4007 /* save bt878 state */
4008 btv->state.gpio_enable = btread(BT848_GPIO_OUT_EN);
4009 btv->state.gpio_data = gpio_read();
4010
4011 /* save pci state */
4012 pci_save_state(pci_dev);
4013 if (0 != pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state))) {
4014 pci_disable_device(pci_dev);
4015 btv->state.disabled = 1;
4016 }
4017 return 0;
4018}
4019
4020static int bttv_resume(struct pci_dev *pci_dev)
4021{
4022 struct bttv *btv = pci_get_drvdata(pci_dev);
4023 unsigned long flags;
4024
4025 dprintk("bttv%d: resume\n", btv->c.nr);
4026
4027 /* restore pci state */
4028 if (btv->state.disabled) {
4029 pci_enable_device(pci_dev);
4030 btv->state.disabled = 0;
4031 }
4032 pci_set_power_state(pci_dev, PCI_D0);
4033 pci_restore_state(pci_dev);
4034
4035 /* restore bt878 state */
4036 bttv_reinit_bt848(btv);
4037 gpio_inout(0xffffff, btv->state.gpio_enable);
4038 gpio_write(btv->state.gpio_data);
4039
4040 /* restart dma */
4041 spin_lock_irqsave(&btv->s_lock,flags);
4042 btv->curr = btv->state.video;
4043 btv->cvbi = btv->state.vbi;
4044 btv->loop_irq = btv->state.loop_irq;
4045 bttv_buffer_activate_video(btv, &btv->curr);
4046 bttv_buffer_activate_vbi(btv, btv->cvbi);
4047 bttv_set_dma(btv, 0);
4048 spin_unlock_irqrestore(&btv->s_lock,flags);
4049 return 0;
4050}
4051
4052static struct pci_device_id bttv_pci_tbl[] = {
4053 {PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT848,
4054 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
4055 {PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT849,
4056 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
4057 {PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT878,
4058 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
4059 {PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT879,
4060 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
4061 {0,}
4062};
4063
4064MODULE_DEVICE_TABLE(pci, bttv_pci_tbl);
4065
4066static struct pci_driver bttv_pci_driver = {
4067 .name = "bttv",
4068 .id_table = bttv_pci_tbl,
4069 .probe = bttv_probe,
4070 .remove = __devexit_p(bttv_remove),
4071 .suspend = bttv_suspend,
4072 .resume = bttv_resume,
4073};
4074
4075static int bttv_init_module(void)
4076{
4077 bttv_num = 0;
4078
4079 printk(KERN_INFO "bttv: driver version %d.%d.%d loaded\n",
4080 (BTTV_VERSION_CODE >> 16) & 0xff,
4081 (BTTV_VERSION_CODE >> 8) & 0xff,
4082 BTTV_VERSION_CODE & 0xff);
4083#ifdef SNAPSHOT
4084 printk(KERN_INFO "bttv: snapshot date %04d-%02d-%02d\n",
4085 SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100);
4086#endif
4087 if (gbuffers < 2 || gbuffers > VIDEO_MAX_FRAME)
4088 gbuffers = 2;
4089 if (gbufsize < 0 || gbufsize > BTTV_MAX_FBUF)
4090 gbufsize = BTTV_MAX_FBUF;
4091 gbufsize = (gbufsize + PAGE_SIZE - 1) & PAGE_MASK;
4092 if (bttv_verbose)
4093 printk(KERN_INFO "bttv: using %d buffers with %dk (%d pages) each for capture\n",
4094 gbuffers, gbufsize >> 10, gbufsize >> PAGE_SHIFT);
4095
4096 bttv_check_chipset();
4097
4098 bus_register(&bttv_sub_bus_type);
4099 return pci_module_init(&bttv_pci_driver);
4100}
4101
4102static void bttv_cleanup_module(void)
4103{
4104 pci_unregister_driver(&bttv_pci_driver);
4105 bus_unregister(&bttv_sub_bus_type);
4106 return;
4107}
4108
4109module_init(bttv_init_module);
4110module_exit(bttv_cleanup_module);
4111
4112/*
4113 * Local variables:
4114 * c-basic-offset: 8
4115 * End:
4116 */
diff --git a/drivers/media/video/bttv-gpio.c b/drivers/media/video/bttv-gpio.c
new file mode 100644
index 00000000000..77320cdf205
--- /dev/null
+++ b/drivers/media/video/bttv-gpio.c
@@ -0,0 +1,190 @@
1/*
2 $Id: bttv-gpio.c,v 1.7 2005/02/16 12:14:10 kraxel Exp $
3
4 bttv-gpio.c -- gpio sub drivers
5
6 sysfs-based sub driver interface for bttv
7 mainly intented for gpio access
8
9
10 Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
11 & Marcus Metzler (mocm@thp.uni-koeln.de)
12 (c) 1999-2003 Gerd Knorr <kraxel@bytesex.org>
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
30#include <linux/module.h>
31#include <linux/init.h>
32#include <linux/delay.h>
33#include <linux/device.h>
34#include <asm/io.h>
35
36#include "bttvp.h"
37
38/* ----------------------------------------------------------------------- */
39/* internal: the bttv "bus" */
40
41static int bttv_sub_bus_match(struct device *dev, struct device_driver *drv)
42{
43 struct bttv_sub_driver *sub = to_bttv_sub_drv(drv);
44 int len = strlen(sub->wanted);
45
46 if (0 == strncmp(dev->bus_id, sub->wanted, len))
47 return 1;
48 return 0;
49}
50
51struct bus_type bttv_sub_bus_type = {
52 .name = "bttv-sub",
53 .match = &bttv_sub_bus_match,
54};
55EXPORT_SYMBOL(bttv_sub_bus_type);
56
57static void release_sub_device(struct device *dev)
58{
59 struct bttv_sub_device *sub = to_bttv_sub_dev(dev);
60 kfree(sub);
61}
62
63int bttv_sub_add_device(struct bttv_core *core, char *name)
64{
65 struct bttv_sub_device *sub;
66 int err;
67
68 sub = kmalloc(sizeof(*sub),GFP_KERNEL);
69 if (NULL == sub)
70 return -ENOMEM;
71 memset(sub,0,sizeof(*sub));
72
73 sub->core = core;
74 sub->dev.parent = &core->pci->dev;
75 sub->dev.bus = &bttv_sub_bus_type;
76 sub->dev.release = release_sub_device;
77 snprintf(sub->dev.bus_id,sizeof(sub->dev.bus_id),"%s%d",
78 name, core->nr);
79
80 err = device_register(&sub->dev);
81 if (0 != err) {
82 kfree(sub);
83 return err;
84 }
85 printk("bttv%d: add subdevice \"%s\"\n", core->nr, sub->dev.bus_id);
86 list_add_tail(&sub->list,&core->subs);
87 return 0;
88}
89
90int bttv_sub_del_devices(struct bttv_core *core)
91{
92 struct bttv_sub_device *sub;
93 struct list_head *item,*save;
94
95 list_for_each_safe(item,save,&core->subs) {
96 sub = list_entry(item,struct bttv_sub_device,list);
97 list_del(&sub->list);
98 device_unregister(&sub->dev);
99 }
100 return 0;
101}
102
103void bttv_gpio_irq(struct bttv_core *core)
104{
105 struct bttv_sub_driver *drv;
106 struct bttv_sub_device *dev;
107 struct list_head *item;
108
109 list_for_each(item,&core->subs) {
110 dev = list_entry(item,struct bttv_sub_device,list);
111 drv = to_bttv_sub_drv(dev->dev.driver);
112 if (drv && drv->gpio_irq)
113 drv->gpio_irq(dev);
114 }
115}
116
117/* ----------------------------------------------------------------------- */
118/* external: sub-driver register/unregister */
119
120int bttv_sub_register(struct bttv_sub_driver *sub, char *wanted)
121{
122 sub->drv.bus = &bttv_sub_bus_type;
123 snprintf(sub->wanted,sizeof(sub->wanted),"%s",wanted);
124 return driver_register(&sub->drv);
125}
126EXPORT_SYMBOL(bttv_sub_register);
127
128int bttv_sub_unregister(struct bttv_sub_driver *sub)
129{
130 driver_unregister(&sub->drv);
131 return 0;
132}
133EXPORT_SYMBOL(bttv_sub_unregister);
134
135/* ----------------------------------------------------------------------- */
136/* external: gpio access functions */
137
138void bttv_gpio_inout(struct bttv_core *core, u32 mask, u32 outbits)
139{
140 struct bttv *btv = container_of(core, struct bttv, c);
141 unsigned long flags;
142 u32 data;
143
144 spin_lock_irqsave(&btv->gpio_lock,flags);
145 data = btread(BT848_GPIO_OUT_EN);
146 data = data & ~mask;
147 data = data | (mask & outbits);
148 btwrite(data,BT848_GPIO_OUT_EN);
149 spin_unlock_irqrestore(&btv->gpio_lock,flags);
150}
151EXPORT_SYMBOL(bttv_gpio_inout);
152
153u32 bttv_gpio_read(struct bttv_core *core)
154{
155 struct bttv *btv = container_of(core, struct bttv, c);
156 u32 value;
157
158 value = btread(BT848_GPIO_DATA);
159 return value;
160}
161EXPORT_SYMBOL(bttv_gpio_read);
162
163void bttv_gpio_write(struct bttv_core *core, u32 value)
164{
165 struct bttv *btv = container_of(core, struct bttv, c);
166
167 btwrite(value,BT848_GPIO_DATA);
168}
169EXPORT_SYMBOL(bttv_gpio_write);
170
171void bttv_gpio_bits(struct bttv_core *core, u32 mask, u32 bits)
172{
173 struct bttv *btv = container_of(core, struct bttv, c);
174 unsigned long flags;
175 u32 data;
176
177 spin_lock_irqsave(&btv->gpio_lock,flags);
178 data = btread(BT848_GPIO_DATA);
179 data = data & ~mask;
180 data = data | (mask & bits);
181 btwrite(data,BT848_GPIO_DATA);
182 spin_unlock_irqrestore(&btv->gpio_lock,flags);
183}
184EXPORT_SYMBOL(bttv_gpio_bits);
185
186/*
187 * Local variables:
188 * c-basic-offset: 8
189 * End:
190 */
diff --git a/drivers/media/video/bttv-i2c.c b/drivers/media/video/bttv-i2c.c
new file mode 100644
index 00000000000..e42f1ec13f3
--- /dev/null
+++ b/drivers/media/video/bttv-i2c.c
@@ -0,0 +1,461 @@
1/*
2 $Id: bttv-i2c.c,v 1.18 2005/02/16 12:14:10 kraxel Exp $
3
4 bttv-i2c.c -- all the i2c code is here
5
6 bttv - Bt848 frame grabber driver
7
8 Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
9 & Marcus Metzler (mocm@thp.uni-koeln.de)
10 (c) 1999-2003 Gerd Knorr <kraxel@bytesex.org>
11
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
16
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25
26*/
27
28#include <linux/module.h>
29#include <linux/moduleparam.h>
30#include <linux/init.h>
31#include <linux/delay.h>
32#include <asm/io.h>
33
34#include "bttvp.h"
35
36static struct i2c_algo_bit_data bttv_i2c_algo_bit_template;
37static struct i2c_adapter bttv_i2c_adap_sw_template;
38static struct i2c_adapter bttv_i2c_adap_hw_template;
39static struct i2c_client bttv_i2c_client_template;
40
41static int attach_inform(struct i2c_client *client);
42
43static int i2c_debug = 0;
44static int i2c_hw = 0;
45static int i2c_scan = 0;
46module_param(i2c_debug, int, 0644);
47module_param(i2c_hw, int, 0444);
48module_param(i2c_scan, int, 0444);
49MODULE_PARM_DESC(i2c_scan,"scan i2c bus at insmod time");
50
51/* ----------------------------------------------------------------------- */
52/* I2C functions - bitbanging adapter (software i2c) */
53
54static void bttv_bit_setscl(void *data, int state)
55{
56 struct bttv *btv = (struct bttv*)data;
57
58 if (state)
59 btv->i2c_state |= 0x02;
60 else
61 btv->i2c_state &= ~0x02;
62 btwrite(btv->i2c_state, BT848_I2C);
63 btread(BT848_I2C);
64}
65
66static void bttv_bit_setsda(void *data, int state)
67{
68 struct bttv *btv = (struct bttv*)data;
69
70 if (state)
71 btv->i2c_state |= 0x01;
72 else
73 btv->i2c_state &= ~0x01;
74 btwrite(btv->i2c_state, BT848_I2C);
75 btread(BT848_I2C);
76}
77
78static int bttv_bit_getscl(void *data)
79{
80 struct bttv *btv = (struct bttv*)data;
81 int state;
82
83 state = btread(BT848_I2C) & 0x02 ? 1 : 0;
84 return state;
85}
86
87static int bttv_bit_getsda(void *data)
88{
89 struct bttv *btv = (struct bttv*)data;
90 int state;
91
92 state = btread(BT848_I2C) & 0x01;
93 return state;
94}
95
96static struct i2c_algo_bit_data bttv_i2c_algo_bit_template = {
97 .setsda = bttv_bit_setsda,
98 .setscl = bttv_bit_setscl,
99 .getsda = bttv_bit_getsda,
100 .getscl = bttv_bit_getscl,
101 .udelay = 16,
102 .mdelay = 10,
103 .timeout = 200,
104};
105
106static struct i2c_adapter bttv_i2c_adap_sw_template = {
107 .owner = THIS_MODULE,
108#ifdef I2C_CLASS_TV_ANALOG
109 .class = I2C_CLASS_TV_ANALOG,
110#endif
111 I2C_DEVNAME("bt848"),
112 .id = I2C_HW_B_BT848,
113 .client_register = attach_inform,
114};
115
116/* ----------------------------------------------------------------------- */
117/* I2C functions - hardware i2c */
118
119static int algo_control(struct i2c_adapter *adapter,
120 unsigned int cmd, unsigned long arg)
121{
122 return 0;
123}
124
125static u32 functionality(struct i2c_adapter *adap)
126{
127 return I2C_FUNC_SMBUS_EMUL;
128}
129
130static int
131bttv_i2c_wait_done(struct bttv *btv)
132{
133 DECLARE_WAITQUEUE(wait, current);
134 int rc = 0;
135
136 add_wait_queue(&btv->i2c_queue, &wait);
137 if (0 == btv->i2c_done)
138 msleep_interruptible(20);
139 remove_wait_queue(&btv->i2c_queue, &wait);
140
141 if (0 == btv->i2c_done)
142 /* timeout */
143 rc = -EIO;
144 if (btv->i2c_done & BT848_INT_RACK)
145 rc = 1;
146 btv->i2c_done = 0;
147 return rc;
148}
149
150#define I2C_HW (BT878_I2C_MODE | BT848_I2C_SYNC |\
151 BT848_I2C_SCL | BT848_I2C_SDA)
152
153static int
154bttv_i2c_sendbytes(struct bttv *btv, const struct i2c_msg *msg, int last)
155{
156 u32 xmit;
157 int retval,cnt;
158
159 /* sanity checks */
160 if (0 == msg->len)
161 return -EINVAL;
162
163 /* start, address + first byte */
164 xmit = (msg->addr << 25) | (msg->buf[0] << 16) | I2C_HW;
165 if (msg->len > 1 || !last)
166 xmit |= BT878_I2C_NOSTOP;
167 btwrite(xmit, BT848_I2C);
168 retval = bttv_i2c_wait_done(btv);
169 if (retval < 0)
170 goto err;
171 if (retval == 0)
172 goto eio;
173 if (i2c_debug) {
174 printk(" <W %02x %02x", msg->addr << 1, msg->buf[0]);
175 if (!(xmit & BT878_I2C_NOSTOP))
176 printk(" >\n");
177 }
178
179 for (cnt = 1; cnt < msg->len; cnt++ ) {
180 /* following bytes */
181 xmit = (msg->buf[cnt] << 24) | I2C_HW | BT878_I2C_NOSTART;
182 if (cnt < msg->len-1 || !last)
183 xmit |= BT878_I2C_NOSTOP;
184 btwrite(xmit, BT848_I2C);
185 retval = bttv_i2c_wait_done(btv);
186 if (retval < 0)
187 goto err;
188 if (retval == 0)
189 goto eio;
190 if (i2c_debug) {
191 printk(" %02x", msg->buf[cnt]);
192 if (!(xmit & BT878_I2C_NOSTOP))
193 printk(" >\n");
194 }
195 }
196 return msg->len;
197
198 eio:
199 retval = -EIO;
200 err:
201 if (i2c_debug)
202 printk(" ERR: %d\n",retval);
203 return retval;
204}
205
206static int
207bttv_i2c_readbytes(struct bttv *btv, const struct i2c_msg *msg, int last)
208{
209 u32 xmit;
210 u32 cnt;
211 int retval;
212
213 for(cnt = 0; cnt < msg->len; cnt++) {
214 xmit = (msg->addr << 25) | (1 << 24) | I2C_HW;
215 if (cnt < msg->len-1)
216 xmit |= BT848_I2C_W3B;
217 if (cnt < msg->len-1 || !last)
218 xmit |= BT878_I2C_NOSTOP;
219 if (cnt)
220 xmit |= BT878_I2C_NOSTART;
221 btwrite(xmit, BT848_I2C);
222 retval = bttv_i2c_wait_done(btv);
223 if (retval < 0)
224 goto err;
225 if (retval == 0)
226 goto eio;
227 msg->buf[cnt] = ((u32)btread(BT848_I2C) >> 8) & 0xff;
228 if (i2c_debug) {
229 if (!(xmit & BT878_I2C_NOSTART))
230 printk(" <R %02x", (msg->addr << 1) +1);
231 printk(" =%02x", msg->buf[cnt]);
232 if (!(xmit & BT878_I2C_NOSTOP))
233 printk(" >\n");
234 }
235 }
236 return msg->len;
237
238 eio:
239 retval = -EIO;
240 err:
241 if (i2c_debug)
242 printk(" ERR: %d\n",retval);
243 return retval;
244}
245
246static int bttv_i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num)
247{
248 struct bttv *btv = i2c_get_adapdata(i2c_adap);
249 int retval = 0;
250 int i;
251
252 if (i2c_debug)
253 printk("bt-i2c:");
254 btwrite(BT848_INT_I2CDONE|BT848_INT_RACK, BT848_INT_STAT);
255 for (i = 0 ; i < num; i++) {
256 if (msgs[i].flags & I2C_M_RD) {
257 /* read */
258 retval = bttv_i2c_readbytes(btv, &msgs[i], i+1 == num);
259 if (retval < 0)
260 goto err;
261 } else {
262 /* write */
263 retval = bttv_i2c_sendbytes(btv, &msgs[i], i+1 == num);
264 if (retval < 0)
265 goto err;
266 }
267 }
268 return num;
269
270 err:
271 return retval;
272}
273
274static struct i2c_algorithm bttv_algo = {
275 .name = "bt878",
276 .id = I2C_ALGO_BIT | I2C_HW_B_BT848 /* FIXME */,
277 .master_xfer = bttv_i2c_xfer,
278 .algo_control = algo_control,
279 .functionality = functionality,
280};
281
282static struct i2c_adapter bttv_i2c_adap_hw_template = {
283 .owner = THIS_MODULE,
284#ifdef I2C_CLASS_TV_ANALOG
285 .class = I2C_CLASS_TV_ANALOG,
286#endif
287 I2C_DEVNAME("bt878"),
288 .id = I2C_ALGO_BIT | I2C_HW_B_BT848 /* FIXME */,
289 .algo = &bttv_algo,
290 .client_register = attach_inform,
291};
292
293/* ----------------------------------------------------------------------- */
294/* I2C functions - common stuff */
295
296static int attach_inform(struct i2c_client *client)
297{
298 struct bttv *btv = i2c_get_adapdata(client->adapter);
299
300 if (btv->tuner_type != UNSET)
301 bttv_call_i2c_clients(btv,TUNER_SET_TYPE,&btv->tuner_type);
302 if (btv->pinnacle_id != UNSET)
303 bttv_call_i2c_clients(btv,AUDC_CONFIG_PINNACLE,
304 &btv->pinnacle_id);
305 if (bttv_debug)
306 printk("bttv%d: i2c attach [client=%s]\n",
307 btv->c.nr, i2c_clientname(client));
308 return 0;
309}
310
311void bttv_call_i2c_clients(struct bttv *btv, unsigned int cmd, void *arg)
312{
313 if (0 != btv->i2c_rc)
314 return;
315 i2c_clients_command(&btv->c.i2c_adap, cmd, arg);
316}
317
318static struct i2c_client bttv_i2c_client_template = {
319 I2C_DEVNAME("bttv internal"),
320};
321
322
323/* read I2C */
324int bttv_I2CRead(struct bttv *btv, unsigned char addr, char *probe_for)
325{
326 unsigned char buffer = 0;
327
328 if (0 != btv->i2c_rc)
329 return -1;
330 if (bttv_verbose && NULL != probe_for)
331 printk(KERN_INFO "bttv%d: i2c: checking for %s @ 0x%02x... ",
332 btv->c.nr,probe_for,addr);
333 btv->i2c_client.addr = addr >> 1;
334 if (1 != i2c_master_recv(&btv->i2c_client, &buffer, 1)) {
335 if (NULL != probe_for) {
336 if (bttv_verbose)
337 printk("not found\n");
338 } else
339 printk(KERN_WARNING "bttv%d: i2c read 0x%x: error\n",
340 btv->c.nr,addr);
341 return -1;
342 }
343 if (bttv_verbose && NULL != probe_for)
344 printk("found\n");
345 return buffer;
346}
347
348/* write I2C */
349int bttv_I2CWrite(struct bttv *btv, unsigned char addr, unsigned char b1,
350 unsigned char b2, int both)
351{
352 unsigned char buffer[2];
353 int bytes = both ? 2 : 1;
354
355 if (0 != btv->i2c_rc)
356 return -1;
357 btv->i2c_client.addr = addr >> 1;
358 buffer[0] = b1;
359 buffer[1] = b2;
360 if (bytes != i2c_master_send(&btv->i2c_client, buffer, bytes))
361 return -1;
362 return 0;
363}
364
365/* read EEPROM content */
366void __devinit bttv_readee(struct bttv *btv, unsigned char *eedata, int addr)
367{
368 btv->i2c_client.addr = addr >> 1;
369 tveeprom_read(&btv->i2c_client, eedata, 256);
370}
371
372static char *i2c_devs[128] = {
373 [ 0x30 >> 1 ] = "IR (hauppauge)",
374 [ 0x80 >> 1 ] = "msp34xx",
375 [ 0x86 >> 1 ] = "tda9887",
376 [ 0xa0 >> 1 ] = "eeprom",
377 [ 0xc0 >> 1 ] = "tuner (analog)",
378 [ 0xc2 >> 1 ] = "tuner (analog)",
379};
380
381static void do_i2c_scan(char *name, struct i2c_client *c)
382{
383 unsigned char buf;
384 int i,rc;
385
386 for (i = 0; i < 128; i++) {
387 c->addr = i;
388 rc = i2c_master_recv(c,&buf,0);
389 if (rc < 0)
390 continue;
391 printk("%s: i2c scan: found device @ 0x%x [%s]\n",
392 name, i << 1, i2c_devs[i] ? i2c_devs[i] : "???");
393 }
394}
395
396/* init + register i2c algo-bit adapter */
397int __devinit init_bttv_i2c(struct bttv *btv)
398{
399 memcpy(&btv->i2c_client, &bttv_i2c_client_template,
400 sizeof(bttv_i2c_client_template));
401
402 if (i2c_hw)
403 btv->use_i2c_hw = 1;
404 if (btv->use_i2c_hw) {
405 /* bt878 */
406 memcpy(&btv->c.i2c_adap, &bttv_i2c_adap_hw_template,
407 sizeof(bttv_i2c_adap_hw_template));
408 } else {
409 /* bt848 */
410 memcpy(&btv->c.i2c_adap, &bttv_i2c_adap_sw_template,
411 sizeof(bttv_i2c_adap_sw_template));
412 memcpy(&btv->i2c_algo, &bttv_i2c_algo_bit_template,
413 sizeof(bttv_i2c_algo_bit_template));
414 btv->i2c_algo.data = btv;
415 btv->c.i2c_adap.algo_data = &btv->i2c_algo;
416 }
417
418 btv->c.i2c_adap.dev.parent = &btv->c.pci->dev;
419 snprintf(btv->c.i2c_adap.name, sizeof(btv->c.i2c_adap.name),
420 "bt%d #%d [%s]", btv->id, btv->c.nr,
421 btv->use_i2c_hw ? "hw" : "sw");
422
423 i2c_set_adapdata(&btv->c.i2c_adap, btv);
424 btv->i2c_client.adapter = &btv->c.i2c_adap;
425
426#ifdef I2C_CLASS_TV_ANALOG
427 if (bttv_tvcards[btv->c.type].no_video)
428 btv->c.i2c_adap.class &= ~I2C_CLASS_TV_ANALOG;
429 if (bttv_tvcards[btv->c.type].has_dvb)
430 btv->c.i2c_adap.class |= I2C_CLASS_TV_DIGITAL;
431#endif
432
433 if (btv->use_i2c_hw) {
434 btv->i2c_rc = i2c_add_adapter(&btv->c.i2c_adap);
435 } else {
436 bttv_bit_setscl(btv,1);
437 bttv_bit_setsda(btv,1);
438 btv->i2c_rc = i2c_bit_add_bus(&btv->c.i2c_adap);
439 }
440 if (0 == btv->i2c_rc && i2c_scan)
441 do_i2c_scan(btv->c.name,&btv->i2c_client);
442 return btv->i2c_rc;
443}
444
445int __devexit fini_bttv_i2c(struct bttv *btv)
446{
447 if (0 != btv->i2c_rc)
448 return 0;
449
450 if (btv->use_i2c_hw) {
451 return i2c_del_adapter(&btv->c.i2c_adap);
452 } else {
453 return i2c_bit_del_bus(&btv->c.i2c_adap);
454 }
455}
456
457/*
458 * Local variables:
459 * c-basic-offset: 8
460 * End:
461 */
diff --git a/drivers/media/video/bttv-if.c b/drivers/media/video/bttv-if.c
new file mode 100644
index 00000000000..f7b5543a96a
--- /dev/null
+++ b/drivers/media/video/bttv-if.c
@@ -0,0 +1,160 @@
1/*
2 $Id: bttv-if.c,v 1.4 2004/11/17 18:47:47 kraxel Exp $
3
4 bttv-if.c -- old gpio interface to other kernel modules
5 don't use in new code, will go away in 2.7
6 have a look at bttv-gpio.c instead.
7
8 bttv - Bt848 frame grabber driver
9
10 Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
11 & Marcus Metzler (mocm@thp.uni-koeln.de)
12 (c) 1999-2003 Gerd Knorr <kraxel@bytesex.org>
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
30#include <linux/module.h>
31#include <linux/init.h>
32#include <linux/delay.h>
33#include <asm/io.h>
34
35#include "bttvp.h"
36
37EXPORT_SYMBOL(bttv_get_cardinfo);
38EXPORT_SYMBOL(bttv_get_pcidev);
39EXPORT_SYMBOL(bttv_get_id);
40EXPORT_SYMBOL(bttv_gpio_enable);
41EXPORT_SYMBOL(bttv_read_gpio);
42EXPORT_SYMBOL(bttv_write_gpio);
43EXPORT_SYMBOL(bttv_get_gpio_queue);
44EXPORT_SYMBOL(bttv_i2c_call);
45
46/* ----------------------------------------------------------------------- */
47/* Exported functions - for other modules which want to access the */
48/* gpio ports (IR for example) */
49/* see bttv.h for comments */
50
51int bttv_get_cardinfo(unsigned int card, int *type, unsigned *cardid)
52{
53 printk("The bttv_* interface is obsolete and will go away,\n"
54 "please use the new, sysfs based interface instead.\n");
55 if (card >= bttv_num) {
56 return -1;
57 }
58 *type = bttvs[card].c.type;
59 *cardid = bttvs[card].cardid;
60 return 0;
61}
62
63struct pci_dev* bttv_get_pcidev(unsigned int card)
64{
65 if (card >= bttv_num)
66 return NULL;
67 return bttvs[card].c.pci;
68}
69
70int bttv_get_id(unsigned int card)
71{
72 printk("The bttv_* interface is obsolete and will go away,\n"
73 "please use the new, sysfs based interface instead.\n");
74 if (card >= bttv_num) {
75 return -1;
76 }
77 return bttvs[card].c.type;
78}
79
80
81int bttv_gpio_enable(unsigned int card, unsigned long mask, unsigned long data)
82{
83 struct bttv *btv;
84
85 if (card >= bttv_num) {
86 return -EINVAL;
87 }
88
89 btv = &bttvs[card];
90 gpio_inout(mask,data);
91 if (bttv_gpio)
92 bttv_gpio_tracking(btv,"extern enable");
93 return 0;
94}
95
96int bttv_read_gpio(unsigned int card, unsigned long *data)
97{
98 struct bttv *btv;
99
100 if (card >= bttv_num) {
101 return -EINVAL;
102 }
103
104 btv = &bttvs[card];
105
106 if(btv->shutdown) {
107 return -ENODEV;
108 }
109
110/* prior setting BT848_GPIO_REG_INP is (probably) not needed
111 because we set direct input on init */
112 *data = gpio_read();
113 return 0;
114}
115
116int bttv_write_gpio(unsigned int card, unsigned long mask, unsigned long data)
117{
118 struct bttv *btv;
119
120 if (card >= bttv_num) {
121 return -EINVAL;
122 }
123
124 btv = &bttvs[card];
125
126/* prior setting BT848_GPIO_REG_INP is (probably) not needed
127 because direct input is set on init */
128 gpio_bits(mask,data);
129 if (bttv_gpio)
130 bttv_gpio_tracking(btv,"extern write");
131 return 0;
132}
133
134wait_queue_head_t* bttv_get_gpio_queue(unsigned int card)
135{
136 struct bttv *btv;
137
138 if (card >= bttv_num) {
139 return NULL;
140 }
141
142 btv = &bttvs[card];
143 if (bttvs[card].shutdown) {
144 return NULL;
145 }
146 return &btv->gpioq;
147}
148
149void bttv_i2c_call(unsigned int card, unsigned int cmd, void *arg)
150{
151 if (card >= bttv_num)
152 return;
153 bttv_call_i2c_clients(&bttvs[card], cmd, arg);
154}
155
156/*
157 * Local variables:
158 * c-basic-offset: 8
159 * End:
160 */
diff --git a/drivers/media/video/bttv-risc.c b/drivers/media/video/bttv-risc.c
new file mode 100644
index 00000000000..bdc5ce6c43b
--- /dev/null
+++ b/drivers/media/video/bttv-risc.c
@@ -0,0 +1,802 @@
1/*
2 $Id: bttv-risc.c,v 1.10 2004/11/19 18:07:12 kraxel Exp $
3
4 bttv-risc.c -- interfaces to other kernel modules
5
6 bttv risc code handling
7 - memory management
8 - generation
9
10 (c) 2000-2003 Gerd Knorr <kraxel@bytesex.org>
11
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
16
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25
26*/
27
28#include <linux/module.h>
29#include <linux/init.h>
30#include <linux/pci.h>
31#include <linux/vmalloc.h>
32#include <linux/interrupt.h>
33#include <asm/page.h>
34#include <asm/pgtable.h>
35
36#include "bttvp.h"
37
38#define VCR_HACK_LINES 4
39
40/* ---------------------------------------------------------- */
41/* risc code generators */
42
43int
44bttv_risc_packed(struct bttv *btv, struct btcx_riscmem *risc,
45 struct scatterlist *sglist,
46 unsigned int offset, unsigned int bpl,
47 unsigned int padding, unsigned int lines)
48{
49 u32 instructions,line,todo;
50 struct scatterlist *sg;
51 u32 *rp;
52 int rc;
53
54 /* estimate risc mem: worst case is one write per page border +
55 one write per scan line + sync + jump (all 2 dwords) */
56 instructions = (bpl * lines) / PAGE_SIZE + lines;
57 instructions += 2;
58 if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,instructions*8)) < 0)
59 return rc;
60
61 /* sync instruction */
62 rp = risc->cpu;
63 *(rp++) = cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1);
64 *(rp++) = cpu_to_le32(0);
65
66 /* scan lines */
67 sg = sglist;
68 for (line = 0; line < lines; line++) {
69 if ((btv->opt_vcr_hack) &&
70 (line >= (lines - VCR_HACK_LINES)))
71 continue;
72 while (offset && offset >= sg_dma_len(sg)) {
73 offset -= sg_dma_len(sg);
74 sg++;
75 }
76 if (bpl <= sg_dma_len(sg)-offset) {
77 /* fits into current chunk */
78 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_SOL|
79 BT848_RISC_EOL|bpl);
80 *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
81 offset+=bpl;
82 } else {
83 /* scanline needs to be splitted */
84 todo = bpl;
85 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_SOL|
86 (sg_dma_len(sg)-offset));
87 *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
88 todo -= (sg_dma_len(sg)-offset);
89 offset = 0;
90 sg++;
91 while (todo > sg_dma_len(sg)) {
92 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|
93 sg_dma_len(sg));
94 *(rp++)=cpu_to_le32(sg_dma_address(sg));
95 todo -= sg_dma_len(sg);
96 sg++;
97 }
98 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_EOL|
99 todo);
100 *(rp++)=cpu_to_le32(sg_dma_address(sg));
101 offset += todo;
102 }
103 offset += padding;
104 }
105
106 /* save pointer to jmp instruction address */
107 risc->jmp = rp;
108 BUG_ON((risc->jmp - risc->cpu + 2) / 4 > risc->size);
109 return 0;
110}
111
112static int
113bttv_risc_planar(struct bttv *btv, struct btcx_riscmem *risc,
114 struct scatterlist *sglist,
115 unsigned int yoffset, unsigned int ybpl,
116 unsigned int ypadding, unsigned int ylines,
117 unsigned int uoffset, unsigned int voffset,
118 unsigned int hshift, unsigned int vshift,
119 unsigned int cpadding)
120{
121 unsigned int instructions,line,todo,ylen,chroma;
122 u32 *rp,ri;
123 struct scatterlist *ysg;
124 struct scatterlist *usg;
125 struct scatterlist *vsg;
126 int topfield = (0 == yoffset);
127 int rc;
128
129 /* estimate risc mem: worst case is one write per page border +
130 one write per scan line (5 dwords)
131 plus sync + jump (2 dwords) */
132 instructions = (ybpl * ylines * 2) / PAGE_SIZE + ylines;
133 instructions += 2;
134 if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,instructions*4*5)) < 0)
135 return rc;
136
137 /* sync instruction */
138 rp = risc->cpu;
139 *(rp++) = cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM3);
140 *(rp++) = cpu_to_le32(0);
141
142 /* scan lines */
143 ysg = sglist;
144 usg = sglist;
145 vsg = sglist;
146 for (line = 0; line < ylines; line++) {
147 if ((btv->opt_vcr_hack) &&
148 (line >= (ylines - VCR_HACK_LINES)))
149 continue;
150 switch (vshift) {
151 case 0:
152 chroma = 1;
153 break;
154 case 1:
155 if (topfield)
156 chroma = ((line & 1) == 0);
157 else
158 chroma = ((line & 1) == 1);
159 break;
160 case 2:
161 if (topfield)
162 chroma = ((line & 3) == 0);
163 else
164 chroma = ((line & 3) == 2);
165 break;
166 default:
167 chroma = 0;
168 break;
169 }
170
171 for (todo = ybpl; todo > 0; todo -= ylen) {
172 /* go to next sg entry if needed */
173 while (yoffset && yoffset >= sg_dma_len(ysg)) {
174 yoffset -= sg_dma_len(ysg);
175 ysg++;
176 }
177 while (uoffset && uoffset >= sg_dma_len(usg)) {
178 uoffset -= sg_dma_len(usg);
179 usg++;
180 }
181 while (voffset && voffset >= sg_dma_len(vsg)) {
182 voffset -= sg_dma_len(vsg);
183 vsg++;
184 }
185
186 /* calculate max number of bytes we can write */
187 ylen = todo;
188 if (yoffset + ylen > sg_dma_len(ysg))
189 ylen = sg_dma_len(ysg) - yoffset;
190 if (chroma) {
191 if (uoffset + (ylen>>hshift) > sg_dma_len(usg))
192 ylen = (sg_dma_len(usg) - uoffset) << hshift;
193 if (voffset + (ylen>>hshift) > sg_dma_len(vsg))
194 ylen = (sg_dma_len(vsg) - voffset) << hshift;
195 ri = BT848_RISC_WRITE123;
196 } else {
197 ri = BT848_RISC_WRITE1S23;
198 }
199 if (ybpl == todo)
200 ri |= BT848_RISC_SOL;
201 if (ylen == todo)
202 ri |= BT848_RISC_EOL;
203
204 /* write risc instruction */
205 *(rp++)=cpu_to_le32(ri | ylen);
206 *(rp++)=cpu_to_le32(((ylen >> hshift) << 16) |
207 (ylen >> hshift));
208 *(rp++)=cpu_to_le32(sg_dma_address(ysg)+yoffset);
209 yoffset += ylen;
210 if (chroma) {
211 *(rp++)=cpu_to_le32(sg_dma_address(usg)+uoffset);
212 uoffset += ylen >> hshift;
213 *(rp++)=cpu_to_le32(sg_dma_address(vsg)+voffset);
214 voffset += ylen >> hshift;
215 }
216 }
217 yoffset += ypadding;
218 if (chroma) {
219 uoffset += cpadding;
220 voffset += cpadding;
221 }
222 }
223
224 /* save pointer to jmp instruction address */
225 risc->jmp = rp;
226 BUG_ON((risc->jmp - risc->cpu + 2) / 4 > risc->size);
227 return 0;
228}
229
230static int
231bttv_risc_overlay(struct bttv *btv, struct btcx_riscmem *risc,
232 const struct bttv_format *fmt, struct bttv_overlay *ov,
233 int skip_even, int skip_odd)
234{
235 int instructions,rc,line,maxy,start,end,skip,nskips;
236 struct btcx_skiplist *skips;
237 u32 *rp,ri,ra;
238 u32 addr;
239
240 /* skip list for window clipping */
241 if (NULL == (skips = kmalloc(sizeof(*skips) * ov->nclips,GFP_KERNEL)))
242 return -ENOMEM;
243
244 /* estimate risc mem: worst case is (clip+1) * lines instructions
245 + sync + jump (all 2 dwords) */
246 instructions = (ov->nclips + 1) *
247 ((skip_even || skip_odd) ? ov->w.height>>1 : ov->w.height);
248 instructions += 2;
249 if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,instructions*8)) < 0) {
250 kfree(skips);
251 return rc;
252 }
253
254 /* sync instruction */
255 rp = risc->cpu;
256 *(rp++) = cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1);
257 *(rp++) = cpu_to_le32(0);
258
259 addr = (unsigned long)btv->fbuf.base;
260 addr += btv->fbuf.fmt.bytesperline * ov->w.top;
261 addr += (fmt->depth >> 3) * ov->w.left;
262
263 /* scan lines */
264 for (maxy = -1, line = 0; line < ov->w.height;
265 line++, addr += btv->fbuf.fmt.bytesperline) {
266 if ((btv->opt_vcr_hack) &&
267 (line >= (ov->w.height - VCR_HACK_LINES)))
268 continue;
269 if ((line%2) == 0 && skip_even)
270 continue;
271 if ((line%2) == 1 && skip_odd)
272 continue;
273
274 /* calculate clipping */
275 if (line > maxy)
276 btcx_calc_skips(line, ov->w.width, &maxy,
277 skips, &nskips, ov->clips, ov->nclips);
278
279 /* write out risc code */
280 for (start = 0, skip = 0; start < ov->w.width; start = end) {
281 if (skip >= nskips) {
282 ri = BT848_RISC_WRITE;
283 end = ov->w.width;
284 } else if (start < skips[skip].start) {
285 ri = BT848_RISC_WRITE;
286 end = skips[skip].start;
287 } else {
288 ri = BT848_RISC_SKIP;
289 end = skips[skip].end;
290 skip++;
291 }
292 if (BT848_RISC_WRITE == ri)
293 ra = addr + (fmt->depth>>3)*start;
294 else
295 ra = 0;
296
297 if (0 == start)
298 ri |= BT848_RISC_SOL;
299 if (ov->w.width == end)
300 ri |= BT848_RISC_EOL;
301 ri |= (fmt->depth>>3) * (end-start);
302
303 *(rp++)=cpu_to_le32(ri);
304 if (0 != ra)
305 *(rp++)=cpu_to_le32(ra);
306 }
307 }
308
309 /* save pointer to jmp instruction address */
310 risc->jmp = rp;
311 BUG_ON((risc->jmp - risc->cpu + 2) / 4 > risc->size);
312 kfree(skips);
313 return 0;
314}
315
316/* ---------------------------------------------------------- */
317
318static void
319bttv_calc_geo(struct bttv *btv, struct bttv_geometry *geo,
320 int width, int height, int interleaved, int norm)
321{
322 const struct bttv_tvnorm *tvnorm = &bttv_tvnorms[norm];
323 u32 xsf, sr;
324 int vdelay;
325
326 int swidth = tvnorm->swidth;
327 int totalwidth = tvnorm->totalwidth;
328 int scaledtwidth = tvnorm->scaledtwidth;
329
330 if (bttv_tvcards[btv->c.type].muxsel[btv->input] < 0) {
331 swidth = 720;
332 totalwidth = 858;
333 scaledtwidth = 858;
334 }
335
336 vdelay = tvnorm->vdelay;
337#if 0 /* FIXME */
338 if (vdelay < btv->vbi.lines*2)
339 vdelay = btv->vbi.lines*2;
340#endif
341
342 xsf = (width*scaledtwidth)/swidth;
343 geo->hscale = ((totalwidth*4096UL)/xsf-4096);
344 geo->hdelay = tvnorm->hdelayx1;
345 geo->hdelay = (geo->hdelay*width)/swidth;
346 geo->hdelay &= 0x3fe;
347 sr = ((tvnorm->sheight >> (interleaved?0:1))*512)/height - 512;
348 geo->vscale = (0x10000UL-sr) & 0x1fff;
349 geo->crop = ((width>>8)&0x03) | ((geo->hdelay>>6)&0x0c) |
350 ((tvnorm->sheight>>4)&0x30) | ((vdelay>>2)&0xc0);
351 geo->vscale |= interleaved ? (BT848_VSCALE_INT<<8) : 0;
352 geo->vdelay = vdelay;
353 geo->width = width;
354 geo->sheight = tvnorm->sheight;
355 geo->vtotal = tvnorm->vtotal;
356
357 if (btv->opt_combfilter) {
358 geo->vtc = (width < 193) ? 2 : ((width < 385) ? 1 : 0);
359 geo->comb = (width < 769) ? 1 : 0;
360 } else {
361 geo->vtc = 0;
362 geo->comb = 0;
363 }
364}
365
366static void
367bttv_apply_geo(struct bttv *btv, struct bttv_geometry *geo, int odd)
368{
369 int off = odd ? 0x80 : 0x00;
370
371 if (geo->comb)
372 btor(BT848_VSCALE_COMB, BT848_E_VSCALE_HI+off);
373 else
374 btand(~BT848_VSCALE_COMB, BT848_E_VSCALE_HI+off);
375
376 btwrite(geo->vtc, BT848_E_VTC+off);
377 btwrite(geo->hscale >> 8, BT848_E_HSCALE_HI+off);
378 btwrite(geo->hscale & 0xff, BT848_E_HSCALE_LO+off);
379 btaor((geo->vscale>>8), 0xe0, BT848_E_VSCALE_HI+off);
380 btwrite(geo->vscale & 0xff, BT848_E_VSCALE_LO+off);
381 btwrite(geo->width & 0xff, BT848_E_HACTIVE_LO+off);
382 btwrite(geo->hdelay & 0xff, BT848_E_HDELAY_LO+off);
383 btwrite(geo->sheight & 0xff, BT848_E_VACTIVE_LO+off);
384 btwrite(geo->vdelay & 0xff, BT848_E_VDELAY_LO+off);
385 btwrite(geo->crop, BT848_E_CROP+off);
386 btwrite(geo->vtotal>>8, BT848_VTOTAL_HI);
387 btwrite(geo->vtotal & 0xff, BT848_VTOTAL_LO);
388}
389
390/* ---------------------------------------------------------- */
391/* risc group / risc main loop / dma management */
392
393void
394bttv_set_dma(struct bttv *btv, int override)
395{
396 unsigned long cmd;
397 int capctl;
398
399 btv->cap_ctl = 0;
400 if (NULL != btv->curr.top) btv->cap_ctl |= 0x02;
401 if (NULL != btv->curr.bottom) btv->cap_ctl |= 0x01;
402 if (NULL != btv->cvbi) btv->cap_ctl |= 0x0c;
403
404 capctl = 0;
405 capctl |= (btv->cap_ctl & 0x03) ? 0x03 : 0x00; /* capture */
406 capctl |= (btv->cap_ctl & 0x0c) ? 0x0c : 0x00; /* vbi data */
407 capctl |= override;
408
409 d2printk(KERN_DEBUG
410 "bttv%d: capctl=%x lirq=%d top=%08Lx/%08Lx even=%08Lx/%08Lx\n",
411 btv->c.nr,capctl,btv->loop_irq,
412 btv->cvbi ? (unsigned long long)btv->cvbi->top.dma : 0,
413 btv->curr.top ? (unsigned long long)btv->curr.top->top.dma : 0,
414 btv->cvbi ? (unsigned long long)btv->cvbi->bottom.dma : 0,
415 btv->curr.bottom ? (unsigned long long)btv->curr.bottom->bottom.dma : 0);
416
417 cmd = BT848_RISC_JUMP;
418 if (btv->loop_irq) {
419 cmd |= BT848_RISC_IRQ;
420 cmd |= (btv->loop_irq & 0x0f) << 16;
421 cmd |= (~btv->loop_irq & 0x0f) << 20;
422 }
423 if (btv->curr.frame_irq || btv->loop_irq || btv->cvbi) {
424 mod_timer(&btv->timeout, jiffies+BTTV_TIMEOUT);
425 } else {
426 del_timer(&btv->timeout);
427 }
428 btv->main.cpu[RISC_SLOT_LOOP] = cpu_to_le32(cmd);
429
430 btaor(capctl, ~0x0f, BT848_CAP_CTL);
431 if (capctl) {
432 if (btv->dma_on)
433 return;
434 btwrite(btv->main.dma, BT848_RISC_STRT_ADD);
435 btor(3, BT848_GPIO_DMA_CTL);
436 btv->dma_on = 1;
437 } else {
438 if (!btv->dma_on)
439 return;
440 btand(~3, BT848_GPIO_DMA_CTL);
441 btv->dma_on = 0;
442 }
443 return;
444}
445
446int
447bttv_risc_init_main(struct bttv *btv)
448{
449 int rc;
450
451 if ((rc = btcx_riscmem_alloc(btv->c.pci,&btv->main,PAGE_SIZE)) < 0)
452 return rc;
453 dprintk(KERN_DEBUG "bttv%d: risc main @ %08Lx\n",
454 btv->c.nr,(unsigned long long)btv->main.dma);
455
456 btv->main.cpu[0] = cpu_to_le32(BT848_RISC_SYNC | BT848_RISC_RESYNC |
457 BT848_FIFO_STATUS_VRE);
458 btv->main.cpu[1] = cpu_to_le32(0);
459 btv->main.cpu[2] = cpu_to_le32(BT848_RISC_JUMP);
460 btv->main.cpu[3] = cpu_to_le32(btv->main.dma + (4<<2));
461
462 /* top field */
463 btv->main.cpu[4] = cpu_to_le32(BT848_RISC_JUMP);
464 btv->main.cpu[5] = cpu_to_le32(btv->main.dma + (6<<2));
465 btv->main.cpu[6] = cpu_to_le32(BT848_RISC_JUMP);
466 btv->main.cpu[7] = cpu_to_le32(btv->main.dma + (8<<2));
467
468 btv->main.cpu[8] = cpu_to_le32(BT848_RISC_SYNC | BT848_RISC_RESYNC |
469 BT848_FIFO_STATUS_VRO);
470 btv->main.cpu[9] = cpu_to_le32(0);
471
472 /* bottom field */
473 btv->main.cpu[10] = cpu_to_le32(BT848_RISC_JUMP);
474 btv->main.cpu[11] = cpu_to_le32(btv->main.dma + (12<<2));
475 btv->main.cpu[12] = cpu_to_le32(BT848_RISC_JUMP);
476 btv->main.cpu[13] = cpu_to_le32(btv->main.dma + (14<<2));
477
478 /* jump back to top field */
479 btv->main.cpu[14] = cpu_to_le32(BT848_RISC_JUMP);
480 btv->main.cpu[15] = cpu_to_le32(btv->main.dma + (0<<2));
481
482 return 0;
483}
484
485int
486bttv_risc_hook(struct bttv *btv, int slot, struct btcx_riscmem *risc,
487 int irqflags)
488{
489 unsigned long cmd;
490 unsigned long next = btv->main.dma + ((slot+2) << 2);
491
492 if (NULL == risc) {
493 d2printk(KERN_DEBUG "bttv%d: risc=%p slot[%d]=NULL\n",
494 btv->c.nr,risc,slot);
495 btv->main.cpu[slot+1] = cpu_to_le32(next);
496 } else {
497 d2printk(KERN_DEBUG "bttv%d: risc=%p slot[%d]=%08Lx irq=%d\n",
498 btv->c.nr,risc,slot,(unsigned long long)risc->dma,irqflags);
499 cmd = BT848_RISC_JUMP;
500 if (irqflags) {
501 cmd |= BT848_RISC_IRQ;
502 cmd |= (irqflags & 0x0f) << 16;
503 cmd |= (~irqflags & 0x0f) << 20;
504 }
505 risc->jmp[0] = cpu_to_le32(cmd);
506 risc->jmp[1] = cpu_to_le32(next);
507 btv->main.cpu[slot+1] = cpu_to_le32(risc->dma);
508 }
509 return 0;
510}
511
512void
513bttv_dma_free(struct bttv *btv, struct bttv_buffer *buf)
514{
515 if (in_interrupt())
516 BUG();
517 videobuf_waiton(&buf->vb,0,0);
518 videobuf_dma_pci_unmap(btv->c.pci, &buf->vb.dma);
519 videobuf_dma_free(&buf->vb.dma);
520 btcx_riscmem_free(btv->c.pci,&buf->bottom);
521 btcx_riscmem_free(btv->c.pci,&buf->top);
522 buf->vb.state = STATE_NEEDS_INIT;
523}
524
525int
526bttv_buffer_activate_vbi(struct bttv *btv,
527 struct bttv_buffer *vbi)
528{
529 /* vbi capture */
530 if (vbi) {
531 vbi->vb.state = STATE_ACTIVE;
532 list_del(&vbi->vb.queue);
533 bttv_risc_hook(btv, RISC_SLOT_O_VBI, &vbi->top, 0);
534 bttv_risc_hook(btv, RISC_SLOT_E_VBI, &vbi->bottom, 4);
535 } else {
536 bttv_risc_hook(btv, RISC_SLOT_O_VBI, NULL, 0);
537 bttv_risc_hook(btv, RISC_SLOT_E_VBI, NULL, 0);
538 }
539 return 0;
540}
541
542int
543bttv_buffer_activate_video(struct bttv *btv,
544 struct bttv_buffer_set *set)
545{
546 /* video capture */
547 if (NULL != set->top && NULL != set->bottom) {
548 if (set->top == set->bottom) {
549 set->top->vb.state = STATE_ACTIVE;
550 if (set->top->vb.queue.next)
551 list_del(&set->top->vb.queue);
552 } else {
553 set->top->vb.state = STATE_ACTIVE;
554 set->bottom->vb.state = STATE_ACTIVE;
555 if (set->top->vb.queue.next)
556 list_del(&set->top->vb.queue);
557 if (set->bottom->vb.queue.next)
558 list_del(&set->bottom->vb.queue);
559 }
560 bttv_apply_geo(btv, &set->top->geo, 1);
561 bttv_apply_geo(btv, &set->bottom->geo,0);
562 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, &set->top->top,
563 set->top_irq);
564 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, &set->bottom->bottom,
565 set->frame_irq);
566 btaor((set->top->btformat & 0xf0) | (set->bottom->btformat & 0x0f),
567 ~0xff, BT848_COLOR_FMT);
568 btaor((set->top->btswap & 0x0a) | (set->bottom->btswap & 0x05),
569 ~0x0f, BT848_COLOR_CTL);
570 } else if (NULL != set->top) {
571 set->top->vb.state = STATE_ACTIVE;
572 if (set->top->vb.queue.next)
573 list_del(&set->top->vb.queue);
574 bttv_apply_geo(btv, &set->top->geo,1);
575 bttv_apply_geo(btv, &set->top->geo,0);
576 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, &set->top->top,
577 set->frame_irq);
578 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, NULL, 0);
579 btaor(set->top->btformat & 0xff, ~0xff, BT848_COLOR_FMT);
580 btaor(set->top->btswap & 0x0f, ~0x0f, BT848_COLOR_CTL);
581 } else if (NULL != set->bottom) {
582 set->bottom->vb.state = STATE_ACTIVE;
583 if (set->bottom->vb.queue.next)
584 list_del(&set->bottom->vb.queue);
585 bttv_apply_geo(btv, &set->bottom->geo,1);
586 bttv_apply_geo(btv, &set->bottom->geo,0);
587 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL, 0);
588 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, &set->bottom->bottom,
589 set->frame_irq);
590 btaor(set->bottom->btformat & 0xff, ~0xff, BT848_COLOR_FMT);
591 btaor(set->bottom->btswap & 0x0f, ~0x0f, BT848_COLOR_CTL);
592 } else {
593 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL, 0);
594 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, NULL, 0);
595 }
596 return 0;
597}
598
599/* ---------------------------------------------------------- */
600
601/* calculate geometry, build risc code */
602int
603bttv_buffer_risc(struct bttv *btv, struct bttv_buffer *buf)
604{
605 const struct bttv_tvnorm *tvnorm = bttv_tvnorms + buf->tvnorm;
606
607 dprintk(KERN_DEBUG
608 "bttv%d: buffer field: %s format: %s size: %dx%d\n",
609 btv->c.nr, v4l2_field_names[buf->vb.field],
610 buf->fmt->name, buf->vb.width, buf->vb.height);
611
612 /* packed pixel modes */
613 if (buf->fmt->flags & FORMAT_FLAGS_PACKED) {
614 int bpl = (buf->fmt->depth >> 3) * buf->vb.width;
615 int bpf = bpl * (buf->vb.height >> 1);
616
617 bttv_calc_geo(btv,&buf->geo,buf->vb.width,buf->vb.height,
618 V4L2_FIELD_HAS_BOTH(buf->vb.field),buf->tvnorm);
619
620 switch (buf->vb.field) {
621 case V4L2_FIELD_TOP:
622 bttv_risc_packed(btv,&buf->top,buf->vb.dma.sglist,
623 0,bpl,0,buf->vb.height);
624 break;
625 case V4L2_FIELD_BOTTOM:
626 bttv_risc_packed(btv,&buf->bottom,buf->vb.dma.sglist,
627 0,bpl,0,buf->vb.height);
628 break;
629 case V4L2_FIELD_INTERLACED:
630 bttv_risc_packed(btv,&buf->top,buf->vb.dma.sglist,
631 0,bpl,bpl,buf->vb.height >> 1);
632 bttv_risc_packed(btv,&buf->bottom,buf->vb.dma.sglist,
633 bpl,bpl,bpl,buf->vb.height >> 1);
634 break;
635 case V4L2_FIELD_SEQ_TB:
636 bttv_risc_packed(btv,&buf->top,buf->vb.dma.sglist,
637 0,bpl,0,buf->vb.height >> 1);
638 bttv_risc_packed(btv,&buf->bottom,buf->vb.dma.sglist,
639 bpf,bpl,0,buf->vb.height >> 1);
640 break;
641 default:
642 BUG();
643 }
644 }
645
646 /* planar modes */
647 if (buf->fmt->flags & FORMAT_FLAGS_PLANAR) {
648 int uoffset, voffset;
649 int ypadding, cpadding, lines;
650
651 /* calculate chroma offsets */
652 uoffset = buf->vb.width * buf->vb.height;
653 voffset = buf->vb.width * buf->vb.height;
654 if (buf->fmt->flags & FORMAT_FLAGS_CrCb) {
655 /* Y-Cr-Cb plane order */
656 uoffset >>= buf->fmt->hshift;
657 uoffset >>= buf->fmt->vshift;
658 uoffset += voffset;
659 } else {
660 /* Y-Cb-Cr plane order */
661 voffset >>= buf->fmt->hshift;
662 voffset >>= buf->fmt->vshift;
663 voffset += uoffset;
664 }
665
666 switch (buf->vb.field) {
667 case V4L2_FIELD_TOP:
668 bttv_calc_geo(btv,&buf->geo,buf->vb.width,
669 buf->vb.height,0,buf->tvnorm);
670 bttv_risc_planar(btv, &buf->top, buf->vb.dma.sglist,
671 0,buf->vb.width,0,buf->vb.height,
672 uoffset,voffset,buf->fmt->hshift,
673 buf->fmt->vshift,0);
674 break;
675 case V4L2_FIELD_BOTTOM:
676 bttv_calc_geo(btv,&buf->geo,buf->vb.width,
677 buf->vb.height,0,buf->tvnorm);
678 bttv_risc_planar(btv, &buf->bottom, buf->vb.dma.sglist,
679 0,buf->vb.width,0,buf->vb.height,
680 uoffset,voffset,buf->fmt->hshift,
681 buf->fmt->vshift,0);
682 break;
683 case V4L2_FIELD_INTERLACED:
684 bttv_calc_geo(btv,&buf->geo,buf->vb.width,
685 buf->vb.height,1,buf->tvnorm);
686 lines = buf->vb.height >> 1;
687 ypadding = buf->vb.width;
688 cpadding = buf->vb.width >> buf->fmt->hshift;
689 bttv_risc_planar(btv,&buf->top,
690 buf->vb.dma.sglist,
691 0,buf->vb.width,ypadding,lines,
692 uoffset,voffset,
693 buf->fmt->hshift,
694 buf->fmt->vshift,
695 cpadding);
696 bttv_risc_planar(btv,&buf->bottom,
697 buf->vb.dma.sglist,
698 ypadding,buf->vb.width,ypadding,lines,
699 uoffset+cpadding,
700 voffset+cpadding,
701 buf->fmt->hshift,
702 buf->fmt->vshift,
703 cpadding);
704 break;
705 case V4L2_FIELD_SEQ_TB:
706 bttv_calc_geo(btv,&buf->geo,buf->vb.width,
707 buf->vb.height,1,buf->tvnorm);
708 lines = buf->vb.height >> 1;
709 ypadding = buf->vb.width;
710 cpadding = buf->vb.width >> buf->fmt->hshift;
711 bttv_risc_planar(btv,&buf->top,
712 buf->vb.dma.sglist,
713 0,buf->vb.width,0,lines,
714 uoffset >> 1,
715 voffset >> 1,
716 buf->fmt->hshift,
717 buf->fmt->vshift,
718 0);
719 bttv_risc_planar(btv,&buf->bottom,
720 buf->vb.dma.sglist,
721 lines * ypadding,buf->vb.width,0,lines,
722 lines * ypadding + (uoffset >> 1),
723 lines * ypadding + (voffset >> 1),
724 buf->fmt->hshift,
725 buf->fmt->vshift,
726 0);
727 break;
728 default:
729 BUG();
730 }
731 }
732
733 /* raw data */
734 if (buf->fmt->flags & FORMAT_FLAGS_RAW) {
735 /* build risc code */
736 buf->vb.field = V4L2_FIELD_SEQ_TB;
737 bttv_calc_geo(btv,&buf->geo,tvnorm->swidth,tvnorm->sheight,
738 1,buf->tvnorm);
739 bttv_risc_packed(btv, &buf->top, buf->vb.dma.sglist,
740 0, RAW_BPL, 0, RAW_LINES);
741 bttv_risc_packed(btv, &buf->bottom, buf->vb.dma.sglist,
742 buf->vb.size/2 , RAW_BPL, 0, RAW_LINES);
743 }
744
745 /* copy format info */
746 buf->btformat = buf->fmt->btformat;
747 buf->btswap = buf->fmt->btswap;
748 return 0;
749}
750
751/* ---------------------------------------------------------- */
752
753/* calculate geometry, build risc code */
754int
755bttv_overlay_risc(struct bttv *btv,
756 struct bttv_overlay *ov,
757 const struct bttv_format *fmt,
758 struct bttv_buffer *buf)
759{
760 /* check interleave, bottom+top fields */
761 dprintk(KERN_DEBUG
762 "bttv%d: overlay fields: %s format: %s size: %dx%d\n",
763 btv->c.nr, v4l2_field_names[buf->vb.field],
764 fmt->name,ov->w.width,ov->w.height);
765
766 /* calculate geometry */
767 bttv_calc_geo(btv,&buf->geo,ov->w.width,ov->w.height,
768 V4L2_FIELD_HAS_BOTH(ov->field), ov->tvnorm);
769
770 /* build risc code */
771 switch (ov->field) {
772 case V4L2_FIELD_TOP:
773 bttv_risc_overlay(btv, &buf->top, fmt, ov, 0, 0);
774 break;
775 case V4L2_FIELD_BOTTOM:
776 bttv_risc_overlay(btv, &buf->bottom, fmt, ov, 0, 0);
777 break;
778 case V4L2_FIELD_INTERLACED:
779#if 0
780 bttv_risc_overlay(btv, &buf->top, fmt, ov, 1, 0);
781 bttv_risc_overlay(btv, &buf->bottom, fmt, ov, 0, 1);
782#else
783 bttv_risc_overlay(btv, &buf->top, fmt, ov, 0, 1);
784 bttv_risc_overlay(btv, &buf->bottom, fmt, ov, 1, 0);
785#endif
786 break;
787 default:
788 BUG();
789 }
790
791 /* copy format info */
792 buf->btformat = fmt->btformat;
793 buf->btswap = fmt->btswap;
794 buf->vb.field = ov->field;
795 return 0;
796}
797
798/*
799 * Local variables:
800 * c-basic-offset: 8
801 * End:
802 */
diff --git a/drivers/media/video/bttv-vbi.c b/drivers/media/video/bttv-vbi.c
new file mode 100644
index 00000000000..06f3e62b3e8
--- /dev/null
+++ b/drivers/media/video/bttv-vbi.c
@@ -0,0 +1,235 @@
1/*
2 $Id: bttv-vbi.c,v 1.9 2005/01/13 17:22:33 kraxel Exp $
3
4 bttv - Bt848 frame grabber driver
5 vbi interface
6
7 (c) 2002 Gerd Knorr <kraxel@bytesex.org>
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#include <linux/module.h>
25#include <linux/moduleparam.h>
26#include <linux/errno.h>
27#include <linux/fs.h>
28#include <linux/kernel.h>
29#include <linux/sched.h>
30#include <linux/interrupt.h>
31#include <linux/kdev_t.h>
32#include <asm/io.h>
33#include "bttvp.h"
34
35#define VBI_DEFLINES 16
36#define VBI_MAXLINES 32
37
38static unsigned int vbibufs = 4;
39static unsigned int vbi_debug = 0;
40
41module_param(vbibufs, int, 0444);
42module_param(vbi_debug, int, 0644);
43MODULE_PARM_DESC(vbibufs,"number of vbi buffers, range 2-32, default 4");
44MODULE_PARM_DESC(vbi_debug,"vbi code debug messages, default is 0 (no)");
45
46#ifdef dprintk
47# undef dprintk
48#endif
49#define dprintk(fmt, arg...) if (vbi_debug) \
50 printk(KERN_DEBUG "bttv%d/vbi: " fmt, btv->c.nr , ## arg)
51
52/* ----------------------------------------------------------------------- */
53/* vbi risc code + mm */
54
55static int
56vbi_buffer_risc(struct bttv *btv, struct bttv_buffer *buf, int lines)
57{
58 int bpl = 2048;
59
60 bttv_risc_packed(btv, &buf->top, buf->vb.dma.sglist,
61 0, bpl-4, 4, lines);
62 bttv_risc_packed(btv, &buf->bottom, buf->vb.dma.sglist,
63 lines * bpl, bpl-4, 4, lines);
64 return 0;
65}
66
67static int vbi_buffer_setup(struct videobuf_queue *q,
68 unsigned int *count, unsigned int *size)
69{
70 struct bttv_fh *fh = q->priv_data;
71 struct bttv *btv = fh->btv;
72
73 if (0 == *count)
74 *count = vbibufs;
75 *size = fh->lines * 2 * 2048;
76 dprintk("setup: lines=%d\n",fh->lines);
77 return 0;
78}
79
80static int vbi_buffer_prepare(struct videobuf_queue *q,
81 struct videobuf_buffer *vb,
82 enum v4l2_field field)
83{
84 struct bttv_fh *fh = q->priv_data;
85 struct bttv *btv = fh->btv;
86 struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb);
87 int rc;
88
89 buf->vb.size = fh->lines * 2 * 2048;
90 if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size)
91 return -EINVAL;
92
93 if (STATE_NEEDS_INIT == buf->vb.state) {
94 if (0 != (rc = videobuf_iolock(btv->c.pci, &buf->vb, NULL)))
95 goto fail;
96 if (0 != (rc = vbi_buffer_risc(btv,buf,fh->lines)))
97 goto fail;
98 }
99 buf->vb.state = STATE_PREPARED;
100 buf->vb.field = field;
101 dprintk("buf prepare %p: top=%p bottom=%p field=%s\n",
102 vb, &buf->top, &buf->bottom,
103 v4l2_field_names[buf->vb.field]);
104 return 0;
105
106 fail:
107 bttv_dma_free(btv,buf);
108 return rc;
109}
110
111static void
112vbi_buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
113{
114 struct bttv_fh *fh = q->priv_data;
115 struct bttv *btv = fh->btv;
116 struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb);
117
118 dprintk("queue %p\n",vb);
119 buf->vb.state = STATE_QUEUED;
120 list_add_tail(&buf->vb.queue,&btv->vcapture);
121 if (NULL == btv->cvbi) {
122 fh->btv->loop_irq |= 4;
123 bttv_set_dma(btv,0x0c);
124 }
125}
126
127static void vbi_buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
128{
129 struct bttv_fh *fh = q->priv_data;
130 struct bttv *btv = fh->btv;
131 struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb);
132
133 dprintk("free %p\n",vb);
134 bttv_dma_free(fh->btv,buf);
135}
136
137struct videobuf_queue_ops bttv_vbi_qops = {
138 .buf_setup = vbi_buffer_setup,
139 .buf_prepare = vbi_buffer_prepare,
140 .buf_queue = vbi_buffer_queue,
141 .buf_release = vbi_buffer_release,
142};
143
144/* ----------------------------------------------------------------------- */
145
146void bttv_vbi_setlines(struct bttv_fh *fh, struct bttv *btv, int lines)
147{
148 int vdelay;
149
150 if (lines < 1)
151 lines = 1;
152 if (lines > VBI_MAXLINES)
153 lines = VBI_MAXLINES;
154 fh->lines = lines;
155
156 vdelay = btread(BT848_E_VDELAY_LO);
157 if (vdelay < lines*2) {
158 vdelay = lines*2;
159 btwrite(vdelay,BT848_E_VDELAY_LO);
160 btwrite(vdelay,BT848_O_VDELAY_LO);
161 }
162}
163
164void bttv_vbi_try_fmt(struct bttv_fh *fh, struct v4l2_format *f)
165{
166 const struct bttv_tvnorm *tvnorm;
167 u32 start0,start1;
168 s32 count0,count1,count;
169
170 tvnorm = &bttv_tvnorms[fh->btv->tvnorm];
171 f->type = V4L2_BUF_TYPE_VBI_CAPTURE;
172 f->fmt.vbi.sampling_rate = tvnorm->Fsc;
173 f->fmt.vbi.samples_per_line = 2048;
174 f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
175 f->fmt.vbi.offset = 244;
176 f->fmt.vbi.flags = 0;
177 switch (fh->btv->tvnorm) {
178 case 1: /* NTSC */
179 start0 = 10;
180 start1 = 273;
181 break;
182 case 0: /* PAL */
183 case 2: /* SECAM */
184 default:
185 start0 = 7;
186 start1 = 320;
187 }
188
189 count0 = (f->fmt.vbi.start[0] + f->fmt.vbi.count[0]) - start0;
190 count1 = (f->fmt.vbi.start[1] + f->fmt.vbi.count[1]) - start1;
191 count = max(count0,count1);
192 if (count > VBI_MAXLINES)
193 count = VBI_MAXLINES;
194 if (count < 1)
195 count = 1;
196
197 f->fmt.vbi.start[0] = start0;
198 f->fmt.vbi.start[1] = start1;
199 f->fmt.vbi.count[0] = count;
200 f->fmt.vbi.count[1] = count;
201}
202
203void bttv_vbi_get_fmt(struct bttv_fh *fh, struct v4l2_format *f)
204{
205 const struct bttv_tvnorm *tvnorm;
206
207 tvnorm = &bttv_tvnorms[fh->btv->tvnorm];
208 memset(f,0,sizeof(*f));
209 f->type = V4L2_BUF_TYPE_VBI_CAPTURE;
210 f->fmt.vbi.sampling_rate = tvnorm->Fsc;
211 f->fmt.vbi.samples_per_line = 2048;
212 f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
213 f->fmt.vbi.offset = 244;
214 f->fmt.vbi.count[0] = fh->lines;
215 f->fmt.vbi.count[1] = fh->lines;
216 f->fmt.vbi.flags = 0;
217 switch (fh->btv->tvnorm) {
218 case 1: /* NTSC */
219 f->fmt.vbi.start[0] = 10;
220 f->fmt.vbi.start[1] = 273;
221 break;
222 case 0: /* PAL */
223 case 2: /* SECAM */
224 default:
225 f->fmt.vbi.start[0] = 7;
226 f->fmt.vbi.start[1] = 319;
227 }
228}
229
230/* ----------------------------------------------------------------------- */
231/*
232 * Local variables:
233 * c-basic-offset: 8
234 * End:
235 */
diff --git a/drivers/media/video/bttv.h b/drivers/media/video/bttv.h
new file mode 100644
index 00000000000..8322b66e090
--- /dev/null
+++ b/drivers/media/video/bttv.h
@@ -0,0 +1,338 @@
1/*
2 * $Id: bttv.h,v 1.17 2005/02/22 14:06:32 kraxel Exp $
3 *
4 * bttv - Bt848 frame grabber driver
5 *
6 * card ID's and external interfaces of the bttv driver
7 * basically stuff needed by other drivers (i2c, lirc, ...)
8 * and is supported not to change much over time.
9 *
10 * Copyright (C) 1996,97 Ralph Metzler (rjkm@thp.uni-koeln.de)
11 * (c) 1999,2000 Gerd Knorr <kraxel@goldbach.in-berlin.de>
12 *
13 */
14
15#ifndef _BTTV_H_
16#define _BTTV_H_
17
18#include <linux/videodev.h>
19#include <linux/i2c.h>
20
21/* ---------------------------------------------------------- */
22/* exported by bttv-cards.c */
23
24#define BTTV_UNKNOWN 0x00
25#define BTTV_MIRO 0x01
26#define BTTV_HAUPPAUGE 0x02
27#define BTTV_STB 0x03
28#define BTTV_INTEL 0x04
29#define BTTV_DIAMOND 0x05
30#define BTTV_AVERMEDIA 0x06
31#define BTTV_MATRIX_VISION 0x07
32#define BTTV_FLYVIDEO 0x08
33#define BTTV_TURBOTV 0x09
34#define BTTV_HAUPPAUGE878 0x0a
35#define BTTV_MIROPRO 0x0b
36#define BTTV_ADSTECH_TV 0x0c
37#define BTTV_AVERMEDIA98 0x0d
38#define BTTV_VHX 0x0e
39#define BTTV_ZOLTRIX 0x0f
40#define BTTV_PIXVIEWPLAYTV 0x10
41#define BTTV_WINVIEW_601 0x11
42#define BTTV_AVEC_INTERCAP 0x12
43#define BTTV_LIFE_FLYKIT 0x13
44#define BTTV_CEI_RAFFLES 0x14
45#define BTTV_CONFERENCETV 0x15
46#define BTTV_PHOEBE_TVMAS 0x16
47#define BTTV_MODTEC_205 0x17
48#define BTTV_MAGICTVIEW061 0x18
49#define BTTV_VOBIS_BOOSTAR 0x19
50#define BTTV_HAUPPAUG_WCAM 0x1a
51#define BTTV_MAXI 0x1b
52#define BTTV_TERRATV 0x1c
53#define BTTV_PXC200 0x1d
54#define BTTV_FLYVIDEO_98 0x1e
55#define BTTV_IPROTV 0x1f
56#define BTTV_INTEL_C_S_PCI 0x20
57#define BTTV_TERRATVALUE 0x21
58#define BTTV_WINFAST2000 0x22
59#define BTTV_CHRONOS_VS2 0x23
60#define BTTV_TYPHOON_TVIEW 0x24
61#define BTTV_PXELVWPLTVPRO 0x25
62#define BTTV_MAGICTVIEW063 0x26
63#define BTTV_PINNACLE 0x27
64#define BTTV_STB2 0x28
65#define BTTV_AVPHONE98 0x29
66#define BTTV_PV951 0x2a
67#define BTTV_ONAIR_TV 0x2b
68#define BTTV_SIGMA_TVII_FM 0x2c
69#define BTTV_MATRIX_VISION2 0x2d
70#define BTTV_ZOLTRIX_GENIE 0x2e
71#define BTTV_TERRATVRADIO 0x2f
72#define BTTV_DYNALINK 0x30
73#define BTTV_GVBCTV3PCI 0x31
74#define BTTV_PXELVWPLTVPAK 0x32
75#define BTTV_EAGLE 0x33
76#define BTTV_PINNACLEPRO 0x34
77#define BTTV_TVIEW_RDS_FM 0x35
78#define BTTV_LIFETEC_9415 0x36
79#define BTTV_BESTBUY_EASYTV 0x37
80#define BTTV_FLYVIDEO_98FM 0x38
81#define BTTV_GMV1 0x3d
82#define BTTV_BESTBUY_EASYTV2 0x3e
83#define BTTV_ATI_TVWONDER 0x3f
84#define BTTV_ATI_TVWONDERVE 0x40
85#define BTTV_FLYVIDEO2000 0x41
86#define BTTV_TERRATVALUER 0x42
87#define BTTV_GVBCTV4PCI 0x43
88#define BTTV_VOODOOTV_FM 0x44
89#define BTTV_AIMMS 0x45
90#define BTTV_PV_BT878P_PLUS 0x46
91#define BTTV_FLYVIDEO98EZ 0x47
92#define BTTV_PV_BT878P_9B 0x48
93#define BTTV_SENSORAY311 0x49
94#define BTTV_RV605 0x4a
95#define BTTV_WINDVR 0x4c
96#define BTTV_GRANDTEC 0x4d
97#define BTTV_KWORLD 0x4e
98#define BTTV_HAUPPAUGEPVR 0x50
99#define BTTV_GVBCTV5PCI 0x51
100#define BTTV_OSPREY1x0 0x52
101#define BTTV_OSPREY1x0_848 0x53
102#define BTTV_OSPREY101_848 0x54
103#define BTTV_OSPREY1x1 0x55
104#define BTTV_OSPREY1x1_SVID 0x56
105#define BTTV_OSPREY2xx 0x57
106#define BTTV_OSPREY2x0_SVID 0x58
107#define BTTV_OSPREY2x0 0x59
108#define BTTV_OSPREY500 0x5a
109#define BTTV_OSPREY540 0x5b
110#define BTTV_OSPREY2000 0x5c
111#define BTTV_IDS_EAGLE 0x5d
112#define BTTV_PINNACLESAT 0x5e
113#define BTTV_FORMAC_PROTV 0x5f
114#define BTTV_EURESYS_PICOLO 0x61
115#define BTTV_PV150 0x62
116#define BTTV_AD_TVK503 0x63
117#define BTTV_IVC200 0x66
118#define BTTV_XGUARD 0x67
119#define BTTV_NEBULA_DIGITV 0x68
120#define BTTV_PV143 0x69
121#define BTTV_IVC100 0x6e
122#define BTTV_IVC120 0x6f
123#define BTTV_PC_HDTV 0x70
124#define BTTV_TWINHAN_DST 0x71
125#define BTTV_WINFASTVC100 0x72
126#define BTTV_SIMUS_GVC1100 0x74
127#define BTTV_NGSTV_PLUS 0x75
128#define BTTV_LMLBT4 0x76
129#define BTTV_PICOLO_TETRA_CHIP 0x79
130#define BTTV_AVDVBT_771 0x7b
131#define BTTV_AVDVBT_761 0x7c
132#define BTTV_MATRIX_VISIONSQ 0x7d
133#define BTTV_MATRIX_VISIONSLC 0x7e
134#define BTTV_APAC_VIEWCOMP 0x7f
135#define BTTV_DVICO_DVBT_LITE 0x80
136#define BTTV_TIBET_CS16 0x83
137#define BTTV_KODICOM_4400R 0x84
138
139/* i2c address list */
140#define I2C_TSA5522 0xc2
141#define I2C_TDA7432 0x8a
142#define I2C_BT832_ALT1 0x88
143#define I2C_BT832_ALT2 0x8a // alternate setting
144#define I2C_TDA8425 0x82
145#define I2C_TDA9840 0x84
146#define I2C_TDA9850 0xb6 /* also used by 9855,9873 */
147#define I2C_TDA9874 0xb0 /* also used by 9875 */
148#define I2C_TDA9875 0xb0
149#define I2C_HAUPEE 0xa0
150#define I2C_STBEE 0xae
151#define I2C_VHX 0xc0
152#define I2C_MSP3400 0x80
153#define I2C_MSP3400_ALT 0x88
154#define I2C_TEA6300 0x80 /* also used by 6320 */
155#define I2C_DPL3518 0x84
156#define I2C_TDA9887 0x86
157
158/* more card-specific defines */
159#define PT2254_L_CHANNEL 0x10
160#define PT2254_R_CHANNEL 0x08
161#define PT2254_DBS_IN_2 0x400
162#define PT2254_DBS_IN_10 0x20000
163#define WINVIEW_PT2254_CLK 0x40
164#define WINVIEW_PT2254_DATA 0x20
165#define WINVIEW_PT2254_STROBE 0x80
166
167/* digital_mode */
168#define DIGITAL_MODE_VIDEO 1
169#define DIGITAL_MODE_CAMERA 2
170
171struct bttv_core {
172 /* device structs */
173 struct pci_dev *pci;
174 struct i2c_adapter i2c_adap;
175 struct list_head subs; /* struct bttv_sub_device */
176
177 /* device config */
178 unsigned int nr; /* dev nr (for printk("bttv%d: ..."); */
179 unsigned int type; /* card type (pointer into tvcards[]) */
180 char name[8]; /* dev name */
181};
182
183struct bttv;
184
185struct tvcard
186{
187 char *name;
188 unsigned int video_inputs;
189 unsigned int audio_inputs;
190 unsigned int tuner;
191 unsigned int svhs;
192 unsigned int digital_mode; // DIGITAL_MODE_CAMERA or DIGITAL_MODE_VIDEO
193 u32 gpiomask;
194 u32 muxsel[16];
195 u32 audiomux[6]; /* Tuner, Radio, external, internal, mute, stereo */
196 u32 gpiomask2; /* GPIO MUX mask */
197
198 /* i2c audio flags */
199 unsigned int no_msp34xx:1;
200 unsigned int no_tda9875:1;
201 unsigned int no_tda7432:1;
202 unsigned int needs_tvaudio:1;
203 unsigned int msp34xx_alt:1;
204
205 /* flag: video pci function is unused */
206 unsigned int no_video:1;
207 unsigned int has_dvb:1;
208 unsigned int has_remote:1;
209 unsigned int no_gpioirq:1;
210
211 /* other settings */
212 unsigned int pll;
213#define PLL_NONE 0
214#define PLL_28 1
215#define PLL_35 2
216
217 unsigned int tuner_type;
218 unsigned int has_radio;
219 void (*audio_hook)(struct bttv *btv, struct video_audio *v, int set);
220 void (*muxsel_hook)(struct bttv *btv, unsigned int input);
221};
222
223extern struct tvcard bttv_tvcards[];
224
225/* identification / initialization of the card */
226extern void bttv_idcard(struct bttv *btv);
227extern void bttv_init_card1(struct bttv *btv);
228extern void bttv_init_card2(struct bttv *btv);
229
230/* card-specific funtions */
231extern void tea5757_set_freq(struct bttv *btv, unsigned short freq);
232extern void bttv_tda9880_setnorm(struct bttv *btv, int norm);
233
234/* extra tweaks for some chipsets */
235extern void bttv_check_chipset(void);
236extern int bttv_handle_chipset(struct bttv *btv);
237
238/* ---------------------------------------------------------- */
239/* exported by bttv-if.c */
240
241/* this obsolete -- please use the sysfs-based
242 interface below for new code */
243
244/* returns card type + card ID (for bt878-based ones)
245 for possible values see lines below beginning with #define BTTV_UNKNOWN
246 returns negative value if error occurred
247*/
248extern int bttv_get_cardinfo(unsigned int card, int *type,
249 unsigned int *cardid);
250extern struct pci_dev* bttv_get_pcidev(unsigned int card);
251
252/* obsolete, use bttv_get_cardinfo instead */
253extern int bttv_get_id(unsigned int card);
254
255/* sets GPOE register (BT848_GPIO_OUT_EN) to new value:
256 data | (current_GPOE_value & ~mask)
257 returns negative value if error occurred
258*/
259extern int bttv_gpio_enable(unsigned int card,
260 unsigned long mask, unsigned long data);
261
262/* fills data with GPDATA register contents
263 returns negative value if error occurred
264*/
265extern int bttv_read_gpio(unsigned int card, unsigned long *data);
266
267/* sets GPDATA register to new value:
268 (data & mask) | (current_GPDATA_value & ~mask)
269 returns negative value if error occurred
270*/
271extern int bttv_write_gpio(unsigned int card,
272 unsigned long mask, unsigned long data);
273
274/* returns pointer to task queue which can be used as parameter to
275 interruptible_sleep_on
276 in interrupt handler if BT848_INT_GPINT bit is set - this queue is activated
277 (wake_up_interruptible) and following call to the function bttv_read_gpio
278 should return new value of GPDATA,
279 returns NULL value if error occurred or queue is not available
280 WARNING: because there is no buffer for GPIO data, one MUST
281 process data ASAP
282*/
283extern wait_queue_head_t* bttv_get_gpio_queue(unsigned int card);
284
285/* call i2c clients
286*/
287extern void bttv_i2c_call(unsigned int card, unsigned int cmd, void *arg);
288
289
290
291/* ---------------------------------------------------------- */
292/* sysfs/driver-moded based gpio access interface */
293
294
295struct bttv_sub_device {
296 struct device dev;
297 struct bttv_core *core;
298 struct list_head list;
299};
300#define to_bttv_sub_dev(x) container_of((x), struct bttv_sub_device, dev)
301
302struct bttv_sub_driver {
303 struct device_driver drv;
304 char wanted[BUS_ID_SIZE];
305 void (*gpio_irq)(struct bttv_sub_device *sub);
306};
307#define to_bttv_sub_drv(x) container_of((x), struct bttv_sub_driver, drv)
308
309int bttv_sub_register(struct bttv_sub_driver *drv, char *wanted);
310int bttv_sub_unregister(struct bttv_sub_driver *drv);
311
312/* gpio access functions */
313void bttv_gpio_inout(struct bttv_core *core, u32 mask, u32 outbits);
314u32 bttv_gpio_read(struct bttv_core *core);
315void bttv_gpio_write(struct bttv_core *core, u32 value);
316void bttv_gpio_bits(struct bttv_core *core, u32 mask, u32 bits);
317
318#define gpio_inout(mask,bits) bttv_gpio_inout(&btv->c, mask, bits)
319#define gpio_read() bttv_gpio_read(&btv->c)
320#define gpio_write(value) bttv_gpio_write(&btv->c, value)
321#define gpio_bits(mask,bits) bttv_gpio_bits(&btv->c, mask, bits)
322
323
324/* ---------------------------------------------------------- */
325/* i2c */
326
327extern void bttv_call_i2c_clients(struct bttv *btv, unsigned int cmd, void *arg);
328extern int bttv_I2CRead(struct bttv *btv, unsigned char addr, char *probe_for);
329extern int bttv_I2CWrite(struct bttv *btv, unsigned char addr, unsigned char b1,
330 unsigned char b2, int both);
331extern void bttv_readee(struct bttv *btv, unsigned char *eedata, int addr);
332
333#endif /* _BTTV_H_ */
334/*
335 * Local variables:
336 * c-basic-offset: 8
337 * End:
338 */
diff --git a/drivers/media/video/bttvp.h b/drivers/media/video/bttvp.h
new file mode 100644
index 00000000000..1a9ba7e1cf5
--- /dev/null
+++ b/drivers/media/video/bttvp.h
@@ -0,0 +1,399 @@
1/*
2 $Id: bttvp.h,v 1.17 2005/02/16 12:14:10 kraxel Exp $
3
4 bttv - Bt848 frame grabber driver
5
6 bttv's *private* header file -- nobody other than bttv itself
7 should ever include this file.
8
9 (c) 2000-2002 Gerd Knorr <kraxel@bytesex.org>
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#ifndef _BTTVP_H_
27#define _BTTVP_H_
28
29#include <linux/version.h>
30#define BTTV_VERSION_CODE KERNEL_VERSION(0,9,15)
31
32#include <linux/types.h>
33#include <linux/wait.h>
34#include <linux/i2c.h>
35#include <linux/i2c-algo-bit.h>
36#include <linux/videodev.h>
37#include <linux/pci.h>
38#include <linux/input.h>
39#include <asm/scatterlist.h>
40#include <asm/io.h>
41
42#include <linux/device.h>
43#include <media/video-buf.h>
44#include <media/audiochip.h>
45#include <media/tuner.h>
46#include <media/tveeprom.h>
47#include <media/ir-common.h>
48
49#include "bt848.h"
50#include "bttv.h"
51#include "btcx-risc.h"
52
53#ifdef __KERNEL__
54
55#define FORMAT_FLAGS_DITHER 0x01
56#define FORMAT_FLAGS_PACKED 0x02
57#define FORMAT_FLAGS_PLANAR 0x04
58#define FORMAT_FLAGS_RAW 0x08
59#define FORMAT_FLAGS_CrCb 0x10
60
61#define RISC_SLOT_O_VBI 4
62#define RISC_SLOT_O_FIELD 6
63#define RISC_SLOT_E_VBI 10
64#define RISC_SLOT_E_FIELD 12
65#define RISC_SLOT_LOOP 14
66
67#define RESOURCE_OVERLAY 1
68#define RESOURCE_VIDEO 2
69#define RESOURCE_VBI 4
70
71#define RAW_LINES 640
72#define RAW_BPL 1024
73
74#define UNSET (-1U)
75
76/* ---------------------------------------------------------- */
77
78struct bttv_tvnorm {
79 int v4l2_id;
80 char *name;
81 u32 Fsc;
82 u16 swidth, sheight; /* scaled standard width, height */
83 u16 totalwidth;
84 u8 adelay, bdelay, iform;
85 u32 scaledtwidth;
86 u16 hdelayx1, hactivex1;
87 u16 vdelay;
88 u8 vbipack;
89 u16 vtotal;
90 int sram;
91};
92extern const struct bttv_tvnorm bttv_tvnorms[];
93
94struct bttv_format {
95 char *name;
96 int palette; /* video4linux 1 */
97 int fourcc; /* video4linux 2 */
98 int btformat; /* BT848_COLOR_FMT_* */
99 int btswap; /* BT848_COLOR_CTL_* */
100 int depth; /* bit/pixel */
101 int flags;
102 int hshift,vshift; /* for planar modes */
103};
104
105/* ---------------------------------------------------------- */
106
107struct bttv_geometry {
108 u8 vtc,crop,comb;
109 u16 width,hscale,hdelay;
110 u16 sheight,vscale,vdelay,vtotal;
111};
112
113struct bttv_buffer {
114 /* common v4l buffer stuff -- must be first */
115 struct videobuf_buffer vb;
116
117 /* bttv specific */
118 const struct bttv_format *fmt;
119 int tvnorm;
120 int btformat;
121 int btswap;
122 struct bttv_geometry geo;
123 struct btcx_riscmem top;
124 struct btcx_riscmem bottom;
125};
126
127struct bttv_buffer_set {
128 struct bttv_buffer *top; /* top field buffer */
129 struct bttv_buffer *bottom; /* bottom field buffer */
130 unsigned int top_irq;
131 unsigned int frame_irq;
132};
133
134struct bttv_overlay {
135 int tvnorm;
136 struct v4l2_rect w;
137 enum v4l2_field field;
138 struct v4l2_clip *clips;
139 int nclips;
140 int setup_ok;
141};
142
143struct bttv_fh {
144 struct bttv *btv;
145 int resources;
146#ifdef VIDIOC_G_PRIORITY
147 enum v4l2_priority prio;
148#endif
149 enum v4l2_buf_type type;
150
151 /* video capture */
152 struct videobuf_queue cap;
153 const struct bttv_format *fmt;
154 int width;
155 int height;
156
157 /* current settings */
158 const struct bttv_format *ovfmt;
159 struct bttv_overlay ov;
160
161 /* video overlay */
162 struct videobuf_queue vbi;
163 int lines;
164};
165
166/* ---------------------------------------------------------- */
167/* bttv-risc.c */
168
169/* risc code generators - capture */
170int bttv_risc_packed(struct bttv *btv, struct btcx_riscmem *risc,
171 struct scatterlist *sglist,
172 unsigned int offset, unsigned int bpl,
173 unsigned int pitch, unsigned int lines);
174
175/* control dma register + risc main loop */
176void bttv_set_dma(struct bttv *btv, int override);
177int bttv_risc_init_main(struct bttv *btv);
178int bttv_risc_hook(struct bttv *btv, int slot, struct btcx_riscmem *risc,
179 int irqflags);
180
181/* capture buffer handling */
182int bttv_buffer_risc(struct bttv *btv, struct bttv_buffer *buf);
183int bttv_buffer_activate_video(struct bttv *btv,
184 struct bttv_buffer_set *set);
185int bttv_buffer_activate_vbi(struct bttv *btv,
186 struct bttv_buffer *vbi);
187void bttv_dma_free(struct bttv *btv, struct bttv_buffer *buf);
188
189/* overlay handling */
190int bttv_overlay_risc(struct bttv *btv, struct bttv_overlay *ov,
191 const struct bttv_format *fmt,
192 struct bttv_buffer *buf);
193
194
195/* ---------------------------------------------------------- */
196/* bttv-vbi.c */
197
198void bttv_vbi_try_fmt(struct bttv_fh *fh, struct v4l2_format *f);
199void bttv_vbi_get_fmt(struct bttv_fh *fh, struct v4l2_format *f);
200void bttv_vbi_setlines(struct bttv_fh *fh, struct bttv *btv, int lines);
201
202extern struct videobuf_queue_ops bttv_vbi_qops;
203
204/* ---------------------------------------------------------- */
205/* bttv-gpio.c */
206
207
208extern struct bus_type bttv_sub_bus_type;
209int bttv_sub_add_device(struct bttv_core *core, char *name);
210int bttv_sub_del_devices(struct bttv_core *core);
211void bttv_gpio_irq(struct bttv_core *core);
212
213
214/* ---------------------------------------------------------- */
215/* bttv-driver.c */
216
217/* insmod options */
218extern unsigned int bttv_verbose;
219extern unsigned int bttv_debug;
220extern unsigned int bttv_gpio;
221extern void bttv_gpio_tracking(struct bttv *btv, char *comment);
222extern int init_bttv_i2c(struct bttv *btv);
223extern int fini_bttv_i2c(struct bttv *btv);
224
225#define vprintk if (bttv_verbose) printk
226#define dprintk if (bttv_debug >= 1) printk
227#define d2printk if (bttv_debug >= 2) printk
228
229/* our devices */
230#define BTTV_MAX 16
231extern unsigned int bttv_num;
232
233#define BTTV_MAX_FBUF 0x208000
234#define VBIBUF_SIZE (2048*VBI_MAXLINES*2)
235#define BTTV_TIMEOUT (HZ/2) /* 0.5 seconds */
236#define BTTV_FREE_IDLE (HZ) /* one second */
237
238
239struct bttv_pll_info {
240 unsigned int pll_ifreq; /* PLL input frequency */
241 unsigned int pll_ofreq; /* PLL output frequency */
242 unsigned int pll_crystal; /* Crystal used for input */
243 unsigned int pll_current; /* Currently programmed ofreq */
244};
245
246/* for gpio-connected remote control */
247struct bttv_input {
248 struct input_dev dev;
249 struct ir_input_state ir;
250 char name[32];
251 char phys[32];
252 u32 mask_keycode;
253 u32 mask_keydown;
254};
255
256struct bttv_suspend_state {
257 u32 gpio_enable;
258 u32 gpio_data;
259 int disabled;
260 int loop_irq;
261 struct bttv_buffer_set video;
262 struct bttv_buffer *vbi;
263};
264
265struct bttv {
266 struct bttv_core c;
267
268 /* pci device config */
269 unsigned short id;
270 unsigned char revision;
271 unsigned char __iomem *bt848_mmio; /* pointer to mmio */
272
273 /* card configuration info */
274 unsigned int cardid; /* pci subsystem id (bt878 based ones) */
275 unsigned int tuner_type; /* tuner chip type */
276 unsigned int pinnacle_id;
277 unsigned int svhs;
278 struct bttv_pll_info pll;
279 int triton1;
280 int gpioirq;
281 int use_i2c_hw;
282
283 /* old gpio interface */
284 wait_queue_head_t gpioq;
285 int shutdown;
286 void (*audio_hook)(struct bttv *btv, struct video_audio *v, int set);
287
288 /* new gpio interface */
289 spinlock_t gpio_lock;
290
291 /* i2c layer */
292 struct i2c_algo_bit_data i2c_algo;
293 struct i2c_client i2c_client;
294 int i2c_state, i2c_rc;
295 int i2c_done;
296 wait_queue_head_t i2c_queue;
297
298 /* video4linux (1) */
299 struct video_device *video_dev;
300 struct video_device *radio_dev;
301 struct video_device *vbi_dev;
302
303 /* infrared remote */
304 int has_remote;
305 struct bttv_input *remote;
306
307 /* locking */
308 spinlock_t s_lock;
309 struct semaphore lock;
310 int resources;
311 struct semaphore reslock;
312#ifdef VIDIOC_G_PRIORITY
313 struct v4l2_prio_state prio;
314#endif
315
316 /* video state */
317 unsigned int input;
318 unsigned int audio;
319 unsigned long freq;
320 int tvnorm,hue,contrast,bright,saturation;
321 struct v4l2_framebuffer fbuf;
322 unsigned int field_count;
323
324 /* various options */
325 int opt_combfilter;
326 int opt_lumafilter;
327 int opt_automute;
328 int opt_chroma_agc;
329 int opt_adc_crush;
330 int opt_vcr_hack;
331 int opt_whitecrush_upper;
332 int opt_whitecrush_lower;
333
334 /* radio data/state */
335 int has_radio;
336 int radio_user;
337
338 /* miro/pinnacle + Aimslab VHX
339 philips matchbox (tea5757 radio tuner) support */
340 int has_matchbox;
341 int mbox_we;
342 int mbox_data;
343 int mbox_clk;
344 int mbox_most;
345 int mbox_mask;
346
347 /* ISA stuff (Terratec Active Radio Upgrade) */
348 int mbox_ior;
349 int mbox_iow;
350 int mbox_csel;
351
352 /* risc memory management data
353 - must aquire s_lock before changing these
354 - only the irq handler is supported to touch top + bottom + vcurr */
355 struct btcx_riscmem main;
356 struct bttv_buffer *screen; /* overlay */
357 struct list_head capture; /* video capture queue */
358 struct list_head vcapture; /* vbi capture queue */
359 struct bttv_buffer_set curr; /* active buffers */
360 struct bttv_buffer *cvbi; /* active vbi buffer */
361 int loop_irq;
362 int new_input;
363
364 unsigned long cap_ctl;
365 unsigned long dma_on;
366 struct timer_list timeout;
367 struct bttv_suspend_state state;
368
369 /* stats */
370 unsigned int errors;
371 unsigned int framedrop;
372 unsigned int irq_total;
373 unsigned int irq_me;
374
375 unsigned int users;
376 struct bttv_fh init;
377};
378extern struct bttv bttvs[BTTV_MAX];
379
380/* private ioctls */
381#define BTTV_VERSION _IOR('v' , BASE_VIDIOCPRIVATE+6, int)
382#define BTTV_VBISIZE _IOR('v' , BASE_VIDIOCPRIVATE+8, int)
383
384#endif
385
386#define btwrite(dat,adr) writel((dat), btv->bt848_mmio+(adr))
387#define btread(adr) readl(btv->bt848_mmio+(adr))
388
389#define btand(dat,adr) btwrite((dat) & btread(adr), adr)
390#define btor(dat,adr) btwrite((dat) | btread(adr), adr)
391#define btaor(dat,mask,adr) btwrite((dat) | ((mask) & btread(adr)), adr)
392
393#endif /* _BTTVP_H_ */
394
395/*
396 * Local variables:
397 * c-basic-offset: 8
398 * End:
399 */
diff --git a/drivers/media/video/bw-qcam.c b/drivers/media/video/bw-qcam.c
new file mode 100644
index 00000000000..0065d0c240d
--- /dev/null
+++ b/drivers/media/video/bw-qcam.c
@@ -0,0 +1,1027 @@
1/*
2 * QuickCam Driver For Video4Linux.
3 *
4 * Video4Linux conversion work by Alan Cox.
5 * Parport compatibility by Phil Blundell.
6 * Busy loop avoidance by Mark Cooke.
7 *
8 * Module parameters:
9 *
10 * maxpoll=<1 - 5000>
11 *
12 * When polling the QuickCam for a response, busy-wait for a
13 * maximum of this many loops. The default of 250 gives little
14 * impact on interactive response.
15 *
16 * NOTE: If this parameter is set too high, the processor
17 * will busy wait until this loop times out, and then
18 * slowly poll for a further 5 seconds before failing
19 * the transaction. You have been warned.
20 *
21 * yieldlines=<1 - 250>
22 *
23 * When acquiring a frame from the camera, the data gathering
24 * loop will yield back to the scheduler after completing
25 * this many lines. The default of 4 provides a trade-off
26 * between increased frame acquisition time and impact on
27 * interactive response.
28 */
29
30/* qcam-lib.c -- Library for programming with the Connectix QuickCam.
31 * See the included documentation for usage instructions and details
32 * of the protocol involved. */
33
34
35/* Version 0.5, August 4, 1996 */
36/* Version 0.7, August 27, 1996 */
37/* Version 0.9, November 17, 1996 */
38
39
40/******************************************************************
41
42Copyright (C) 1996 by Scott Laird
43
44Permission is hereby granted, free of charge, to any person obtaining
45a copy of this software and associated documentation files (the
46"Software"), to deal in the Software without restriction, including
47without limitation the rights to use, copy, modify, merge, publish,
48distribute, sublicense, and/or sell copies of the Software, and to
49permit persons to whom the Software is furnished to do so, subject to
50the following conditions:
51
52The above copyright notice and this permission notice shall be
53included in all copies or substantial portions of the Software.
54
55THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
56EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
57MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
58IN NO EVENT SHALL SCOTT LAIRD BE LIABLE FOR ANY CLAIM, DAMAGES OR
59OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
60ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
61OTHER DEALINGS IN THE SOFTWARE.
62
63******************************************************************/
64
65#include <linux/module.h>
66#include <linux/delay.h>
67#include <linux/errno.h>
68#include <linux/fs.h>
69#include <linux/init.h>
70#include <linux/kernel.h>
71#include <linux/slab.h>
72#include <linux/mm.h>
73#include <linux/parport.h>
74#include <linux/sched.h>
75#include <linux/videodev.h>
76#include <asm/semaphore.h>
77#include <asm/uaccess.h>
78
79#include "bw-qcam.h"
80
81static unsigned int maxpoll=250; /* Maximum busy-loop count for qcam I/O */
82static unsigned int yieldlines=4; /* Yield after this many during capture */
83static int video_nr = -1;
84
85module_param(maxpoll, int, 0);
86module_param(yieldlines, int, 0);
87module_param(video_nr, int, 0);
88
89static inline int read_lpstatus(struct qcam_device *q)
90{
91 return parport_read_status(q->pport);
92}
93
94static inline int read_lpdata(struct qcam_device *q)
95{
96 return parport_read_data(q->pport);
97}
98
99static inline void write_lpdata(struct qcam_device *q, int d)
100{
101 parport_write_data(q->pport, d);
102}
103
104static inline void write_lpcontrol(struct qcam_device *q, int d)
105{
106 parport_write_control(q->pport, d);
107}
108
109static int qc_waithand(struct qcam_device *q, int val);
110static int qc_command(struct qcam_device *q, int command);
111static int qc_readparam(struct qcam_device *q);
112static int qc_setscanmode(struct qcam_device *q);
113static int qc_readbytes(struct qcam_device *q, char buffer[]);
114
115static struct video_device qcam_template;
116
117static int qc_calibrate(struct qcam_device *q)
118{
119 /*
120 * Bugfix by Hanno Mueller hmueller@kabel.de, Mai 21 96
121 * The white balance is an individiual value for each
122 * quickcam.
123 */
124
125 int value;
126 int count = 0;
127
128 qc_command(q, 27); /* AutoAdjustOffset */
129 qc_command(q, 0); /* Dummy Parameter, ignored by the camera */
130
131 /* GetOffset (33) will read 255 until autocalibration */
132 /* is finished. After that, a value of 1-254 will be */
133 /* returned. */
134
135 do {
136 qc_command(q, 33);
137 value = qc_readparam(q);
138 mdelay(1);
139 schedule();
140 count++;
141 } while (value == 0xff && count<2048);
142
143 q->whitebal = value;
144 return value;
145}
146
147/* Initialize the QuickCam driver control structure. This is where
148 * defaults are set for people who don't have a config file.*/
149
150static struct qcam_device *qcam_init(struct parport *port)
151{
152 struct qcam_device *q;
153
154 q = kmalloc(sizeof(struct qcam_device), GFP_KERNEL);
155 if(q==NULL)
156 return NULL;
157
158 q->pport = port;
159 q->pdev = parport_register_device(port, "bw-qcam", NULL, NULL,
160 NULL, 0, NULL);
161 if (q->pdev == NULL)
162 {
163 printk(KERN_ERR "bw-qcam: couldn't register for %s.\n",
164 port->name);
165 kfree(q);
166 return NULL;
167 }
168
169 memcpy(&q->vdev, &qcam_template, sizeof(qcam_template));
170
171 init_MUTEX(&q->lock);
172
173 q->port_mode = (QC_ANY | QC_NOTSET);
174 q->width = 320;
175 q->height = 240;
176 q->bpp = 4;
177 q->transfer_scale = 2;
178 q->contrast = 192;
179 q->brightness = 180;
180 q->whitebal = 105;
181 q->top = 1;
182 q->left = 14;
183 q->mode = -1;
184 q->status = QC_PARAM_CHANGE;
185 return q;
186}
187
188
189/* qc_command is probably a bit of a misnomer -- it's used to send
190 * bytes *to* the camera. Generally, these bytes are either commands
191 * or arguments to commands, so the name fits, but it still bugs me a
192 * bit. See the documentation for a list of commands. */
193
194static int qc_command(struct qcam_device *q, int command)
195{
196 int n1, n2;
197 int cmd;
198
199 write_lpdata(q, command);
200 write_lpcontrol(q, 6);
201
202 n1 = qc_waithand(q, 1);
203
204 write_lpcontrol(q, 0xe);
205 n2 = qc_waithand(q, 0);
206
207 cmd = (n1 & 0xf0) | ((n2 & 0xf0) >> 4);
208 return cmd;
209}
210
211static int qc_readparam(struct qcam_device *q)
212{
213 int n1, n2;
214 int cmd;
215
216 write_lpcontrol(q, 6);
217 n1 = qc_waithand(q, 1);
218
219 write_lpcontrol(q, 0xe);
220 n2 = qc_waithand(q, 0);
221
222 cmd = (n1 & 0xf0) | ((n2 & 0xf0) >> 4);
223 return cmd;
224}
225
226/* qc_waithand busy-waits for a handshake signal from the QuickCam.
227 * Almost all communication with the camera requires handshaking. */
228
229static int qc_waithand(struct qcam_device *q, int val)
230{
231 int status;
232 int runs=0;
233
234 if (val)
235 {
236 while (!((status = read_lpstatus(q)) & 8))
237 {
238 /* 1000 is enough spins on the I/O for all normal
239 cases, at that point we start to poll slowly
240 until the camera wakes up. However, we are
241 busy blocked until the camera responds, so
242 setting it lower is much better for interactive
243 response. */
244
245 if(runs++>maxpoll)
246 {
247 msleep_interruptible(5);
248 }
249 if(runs>(maxpoll+1000)) /* 5 seconds */
250 return -1;
251 }
252 }
253 else
254 {
255 while (((status = read_lpstatus(q)) & 8))
256 {
257 /* 1000 is enough spins on the I/O for all normal
258 cases, at that point we start to poll slowly
259 until the camera wakes up. However, we are
260 busy blocked until the camera responds, so
261 setting it lower is much better for interactive
262 response. */
263
264 if(runs++>maxpoll)
265 {
266 msleep_interruptible(5);
267 }
268 if(runs++>(maxpoll+1000)) /* 5 seconds */
269 return -1;
270 }
271 }
272
273 return status;
274}
275
276/* Waithand2 is used when the qcam is in bidirectional mode, and the
277 * handshaking signal is CamRdy2 (bit 0 of data reg) instead of CamRdy1
278 * (bit 3 of status register). It also returns the last value read,
279 * since this data is useful. */
280
281static unsigned int qc_waithand2(struct qcam_device *q, int val)
282{
283 unsigned int status;
284 int runs=0;
285
286 do
287 {
288 status = read_lpdata(q);
289 /* 1000 is enough spins on the I/O for all normal
290 cases, at that point we start to poll slowly
291 until the camera wakes up. However, we are
292 busy blocked until the camera responds, so
293 setting it lower is much better for interactive
294 response. */
295
296 if(runs++>maxpoll)
297 {
298 msleep_interruptible(5);
299 }
300 if(runs++>(maxpoll+1000)) /* 5 seconds */
301 return 0;
302 }
303 while ((status & 1) != val);
304
305 return status;
306}
307
308
309/* Try to detect a QuickCam. It appears to flash the upper 4 bits of
310 the status register at 5-10 Hz. This is only used in the autoprobe
311 code. Be aware that this isn't the way Connectix detects the
312 camera (they send a reset and try to handshake), but this should be
313 almost completely safe, while their method screws up my printer if
314 I plug it in before the camera. */
315
316static int qc_detect(struct qcam_device *q)
317{
318 int reg, lastreg;
319 int count = 0;
320 int i;
321
322 lastreg = reg = read_lpstatus(q) & 0xf0;
323
324 for (i = 0; i < 500; i++)
325 {
326 reg = read_lpstatus(q) & 0xf0;
327 if (reg != lastreg)
328 count++;
329 lastreg = reg;
330 mdelay(2);
331 }
332
333
334#if 0
335 /* Force camera detection during testing. Sometimes the camera
336 won't be flashing these bits. Possibly unloading the module
337 in the middle of a grab? Or some timeout condition?
338 I've seen this parameter as low as 19 on my 450Mhz box - mpc */
339 printk("Debugging: QCam detection counter <30-200 counts as detected>: %d\n", count);
340 return 1;
341#endif
342
343 /* Be (even more) liberal in what you accept... */
344
345/* if (count > 30 && count < 200) */
346 if (count > 20 && count < 300)
347 return 1; /* found */
348 else
349 return 0; /* not found */
350}
351
352
353/* Reset the QuickCam. This uses the same sequence the Windows
354 * QuickPic program uses. Someone with a bi-directional port should
355 * check that bi-directional mode is detected right, and then
356 * implement bi-directional mode in qc_readbyte(). */
357
358static void qc_reset(struct qcam_device *q)
359{
360 switch (q->port_mode & QC_FORCE_MASK)
361 {
362 case QC_FORCE_UNIDIR:
363 q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_UNIDIR;
364 break;
365
366 case QC_FORCE_BIDIR:
367 q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_BIDIR;
368 break;
369
370 case QC_ANY:
371 write_lpcontrol(q, 0x20);
372 write_lpdata(q, 0x75);
373
374 if (read_lpdata(q) != 0x75) {
375 q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_BIDIR;
376 } else {
377 q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_UNIDIR;
378 }
379 break;
380 }
381
382 write_lpcontrol(q, 0xb);
383 udelay(250);
384 write_lpcontrol(q, 0xe);
385 qc_setscanmode(q); /* in case port_mode changed */
386}
387
388
389/* Decide which scan mode to use. There's no real requirement that
390 * the scanmode match the resolution in q->height and q-> width -- the
391 * camera takes the picture at the resolution specified in the
392 * "scanmode" and then returns the image at the resolution specified
393 * with the resolution commands. If the scan is bigger than the
394 * requested resolution, the upper-left hand corner of the scan is
395 * returned. If the scan is smaller, then the rest of the image
396 * returned contains garbage. */
397
398static int qc_setscanmode(struct qcam_device *q)
399{
400 int old_mode = q->mode;
401
402 switch (q->transfer_scale)
403 {
404 case 1:
405 q->mode = 0;
406 break;
407 case 2:
408 q->mode = 4;
409 break;
410 case 4:
411 q->mode = 8;
412 break;
413 }
414
415 switch (q->bpp)
416 {
417 case 4:
418 break;
419 case 6:
420 q->mode += 2;
421 break;
422 }
423
424 switch (q->port_mode & QC_MODE_MASK)
425 {
426 case QC_BIDIR:
427 q->mode += 1;
428 break;
429 case QC_NOTSET:
430 case QC_UNIDIR:
431 break;
432 }
433
434 if (q->mode != old_mode)
435 q->status |= QC_PARAM_CHANGE;
436
437 return 0;
438}
439
440
441/* Reset the QuickCam and program for brightness, contrast,
442 * white-balance, and resolution. */
443
444static void qc_set(struct qcam_device *q)
445{
446 int val;
447 int val2;
448
449 qc_reset(q);
450
451 /* Set the brightness. Yes, this is repetitive, but it works.
452 * Shorter versions seem to fail subtly. Feel free to try :-). */
453 /* I think the problem was in qc_command, not here -- bls */
454
455 qc_command(q, 0xb);
456 qc_command(q, q->brightness);
457
458 val = q->height / q->transfer_scale;
459 qc_command(q, 0x11);
460 qc_command(q, val);
461 if ((q->port_mode & QC_MODE_MASK) == QC_UNIDIR && q->bpp == 6) {
462 /* The normal "transfers per line" calculation doesn't seem to work
463 as expected here (and yet it works fine in qc_scan). No idea
464 why this case is the odd man out. Fortunately, Laird's original
465 working version gives me a good way to guess at working values.
466 -- bls */
467 val = q->width;
468 val2 = q->transfer_scale * 4;
469 } else {
470 val = q->width * q->bpp;
471 val2 = (((q->port_mode & QC_MODE_MASK) == QC_BIDIR) ? 24 : 8) *
472 q->transfer_scale;
473 }
474 val = (val + val2 - 1) / val2;
475 qc_command(q, 0x13);
476 qc_command(q, val);
477
478 /* Setting top and left -- bls */
479 qc_command(q, 0xd);
480 qc_command(q, q->top);
481 qc_command(q, 0xf);
482 qc_command(q, q->left / 2);
483
484 qc_command(q, 0x19);
485 qc_command(q, q->contrast);
486 qc_command(q, 0x1f);
487 qc_command(q, q->whitebal);
488
489 /* Clear flag that we must update the grabbing parameters on the camera
490 before we grab the next frame */
491 q->status &= (~QC_PARAM_CHANGE);
492}
493
494/* Qc_readbytes reads some bytes from the QC and puts them in
495 the supplied buffer. It returns the number of bytes read,
496 or -1 on error. */
497
498static inline int qc_readbytes(struct qcam_device *q, char buffer[])
499{
500 int ret=1;
501 unsigned int hi, lo;
502 unsigned int hi2, lo2;
503 static int state = 0;
504
505 if (buffer == NULL)
506 {
507 state = 0;
508 return 0;
509 }
510
511 switch (q->port_mode & QC_MODE_MASK)
512 {
513 case QC_BIDIR: /* Bi-directional Port */
514 write_lpcontrol(q, 0x26);
515 lo = (qc_waithand2(q, 1) >> 1);
516 hi = (read_lpstatus(q) >> 3) & 0x1f;
517 write_lpcontrol(q, 0x2e);
518 lo2 = (qc_waithand2(q, 0) >> 1);
519 hi2 = (read_lpstatus(q) >> 3) & 0x1f;
520 switch (q->bpp)
521 {
522 case 4:
523 buffer[0] = lo & 0xf;
524 buffer[1] = ((lo & 0x70) >> 4) | ((hi & 1) << 3);
525 buffer[2] = (hi & 0x1e) >> 1;
526 buffer[3] = lo2 & 0xf;
527 buffer[4] = ((lo2 & 0x70) >> 4) | ((hi2 & 1) << 3);
528 buffer[5] = (hi2 & 0x1e) >> 1;
529 ret = 6;
530 break;
531 case 6:
532 buffer[0] = lo & 0x3f;
533 buffer[1] = ((lo & 0x40) >> 6) | (hi << 1);
534 buffer[2] = lo2 & 0x3f;
535 buffer[3] = ((lo2 & 0x40) >> 6) | (hi2 << 1);
536 ret = 4;
537 break;
538 }
539 break;
540
541 case QC_UNIDIR: /* Unidirectional Port */
542 write_lpcontrol(q, 6);
543 lo = (qc_waithand(q, 1) & 0xf0) >> 4;
544 write_lpcontrol(q, 0xe);
545 hi = (qc_waithand(q, 0) & 0xf0) >> 4;
546
547 switch (q->bpp)
548 {
549 case 4:
550 buffer[0] = lo;
551 buffer[1] = hi;
552 ret = 2;
553 break;
554 case 6:
555 switch (state)
556 {
557 case 0:
558 buffer[0] = (lo << 2) | ((hi & 0xc) >> 2);
559 q->saved_bits = (hi & 3) << 4;
560 state = 1;
561 ret = 1;
562 break;
563 case 1:
564 buffer[0] = lo | q->saved_bits;
565 q->saved_bits = hi << 2;
566 state = 2;
567 ret = 1;
568 break;
569 case 2:
570 buffer[0] = ((lo & 0xc) >> 2) | q->saved_bits;
571 buffer[1] = ((lo & 3) << 4) | hi;
572 state = 0;
573 ret = 2;
574 break;
575 }
576 break;
577 }
578 break;
579 }
580 return ret;
581}
582
583/* requests a scan from the camera. It sends the correct instructions
584 * to the camera and then reads back the correct number of bytes. In
585 * previous versions of this routine the return structure contained
586 * the raw output from the camera, and there was a 'qc_convertscan'
587 * function that converted that to a useful format. In version 0.3 I
588 * rolled qc_convertscan into qc_scan and now I only return the
589 * converted scan. The format is just an one-dimensional array of
590 * characters, one for each pixel, with 0=black up to n=white, where
591 * n=2^(bit depth)-1. Ask me for more details if you don't understand
592 * this. */
593
594static long qc_capture(struct qcam_device * q, char __user *buf, unsigned long len)
595{
596 int i, j, k, yield;
597 int bytes;
598 int linestotrans, transperline;
599 int divisor;
600 int pixels_per_line;
601 int pixels_read = 0;
602 int got=0;
603 char buffer[6];
604 int shift=8-q->bpp;
605 char invert;
606
607 if (q->mode == -1)
608 return -ENXIO;
609
610 qc_command(q, 0x7);
611 qc_command(q, q->mode);
612
613 if ((q->port_mode & QC_MODE_MASK) == QC_BIDIR)
614 {
615 write_lpcontrol(q, 0x2e); /* turn port around */
616 write_lpcontrol(q, 0x26);
617 (void) qc_waithand(q, 1);
618 write_lpcontrol(q, 0x2e);
619 (void) qc_waithand(q, 0);
620 }
621
622 /* strange -- should be 15:63 below, but 4bpp is odd */
623 invert = (q->bpp == 4) ? 16 : 63;
624
625 linestotrans = q->height / q->transfer_scale;
626 pixels_per_line = q->width / q->transfer_scale;
627 transperline = q->width * q->bpp;
628 divisor = (((q->port_mode & QC_MODE_MASK) == QC_BIDIR) ? 24 : 8) *
629 q->transfer_scale;
630 transperline = (transperline + divisor - 1) / divisor;
631
632 for (i = 0, yield = yieldlines; i < linestotrans; i++)
633 {
634 for (pixels_read = j = 0; j < transperline; j++)
635 {
636 bytes = qc_readbytes(q, buffer);
637 for (k = 0; k < bytes && (pixels_read + k) < pixels_per_line; k++)
638 {
639 int o;
640 if (buffer[k] == 0 && invert == 16)
641 {
642 /* 4bpp is odd (again) -- inverter is 16, not 15, but output
643 must be 0-15 -- bls */
644 buffer[k] = 16;
645 }
646 o=i*pixels_per_line + pixels_read + k;
647 if(o<len)
648 {
649 got++;
650 put_user((invert - buffer[k])<<shift, buf+o);
651 }
652 }
653 pixels_read += bytes;
654 }
655 (void) qc_readbytes(q, NULL); /* reset state machine */
656
657 /* Grabbing an entire frame from the quickcam is a lengthy
658 process. We don't (usually) want to busy-block the
659 processor for the entire frame. yieldlines is a module
660 parameter. If we yield every line, the minimum frame
661 time will be 240 / 200 = 1.2 seconds. The compile-time
662 default is to yield every 4 lines. */
663 if (i >= yield) {
664 msleep_interruptible(5);
665 yield = i + yieldlines;
666 }
667 }
668
669 if ((q->port_mode & QC_MODE_MASK) == QC_BIDIR)
670 {
671 write_lpcontrol(q, 2);
672 write_lpcontrol(q, 6);
673 udelay(3);
674 write_lpcontrol(q, 0xe);
675 }
676 if(got<len)
677 return got;
678 return len;
679}
680
681/*
682 * Video4linux interfacing
683 */
684
685static int qcam_do_ioctl(struct inode *inode, struct file *file,
686 unsigned int cmd, void *arg)
687{
688 struct video_device *dev = video_devdata(file);
689 struct qcam_device *qcam=(struct qcam_device *)dev;
690
691 switch(cmd)
692 {
693 case VIDIOCGCAP:
694 {
695 struct video_capability *b = arg;
696 strcpy(b->name, "Quickcam");
697 b->type = VID_TYPE_CAPTURE|VID_TYPE_SCALES|VID_TYPE_MONOCHROME;
698 b->channels = 1;
699 b->audios = 0;
700 b->maxwidth = 320;
701 b->maxheight = 240;
702 b->minwidth = 80;
703 b->minheight = 60;
704 return 0;
705 }
706 case VIDIOCGCHAN:
707 {
708 struct video_channel *v = arg;
709 if(v->channel!=0)
710 return -EINVAL;
711 v->flags=0;
712 v->tuners=0;
713 /* Good question.. its composite or SVHS so.. */
714 v->type = VIDEO_TYPE_CAMERA;
715 strcpy(v->name, "Camera");
716 return 0;
717 }
718 case VIDIOCSCHAN:
719 {
720 struct video_channel *v = arg;
721 if(v->channel!=0)
722 return -EINVAL;
723 return 0;
724 }
725 case VIDIOCGTUNER:
726 {
727 struct video_tuner *v = arg;
728 if(v->tuner)
729 return -EINVAL;
730 strcpy(v->name, "Format");
731 v->rangelow=0;
732 v->rangehigh=0;
733 v->flags= 0;
734 v->mode = VIDEO_MODE_AUTO;
735 return 0;
736 }
737 case VIDIOCSTUNER:
738 {
739 struct video_tuner *v = arg;
740 if(v->tuner)
741 return -EINVAL;
742 if(v->mode!=VIDEO_MODE_AUTO)
743 return -EINVAL;
744 return 0;
745 }
746 case VIDIOCGPICT:
747 {
748 struct video_picture *p = arg;
749 p->colour=0x8000;
750 p->hue=0x8000;
751 p->brightness=qcam->brightness<<8;
752 p->contrast=qcam->contrast<<8;
753 p->whiteness=qcam->whitebal<<8;
754 p->depth=qcam->bpp;
755 p->palette=VIDEO_PALETTE_GREY;
756 return 0;
757 }
758 case VIDIOCSPICT:
759 {
760 struct video_picture *p = arg;
761 if(p->palette!=VIDEO_PALETTE_GREY)
762 return -EINVAL;
763 if(p->depth!=4 && p->depth!=6)
764 return -EINVAL;
765
766 /*
767 * Now load the camera.
768 */
769
770 qcam->brightness = p->brightness>>8;
771 qcam->contrast = p->contrast>>8;
772 qcam->whitebal = p->whiteness>>8;
773 qcam->bpp = p->depth;
774
775 down(&qcam->lock);
776 qc_setscanmode(qcam);
777 up(&qcam->lock);
778 qcam->status |= QC_PARAM_CHANGE;
779
780 return 0;
781 }
782 case VIDIOCSWIN:
783 {
784 struct video_window *vw = arg;
785 if(vw->flags)
786 return -EINVAL;
787 if(vw->clipcount)
788 return -EINVAL;
789 if(vw->height<60||vw->height>240)
790 return -EINVAL;
791 if(vw->width<80||vw->width>320)
792 return -EINVAL;
793
794 qcam->width = 320;
795 qcam->height = 240;
796 qcam->transfer_scale = 4;
797
798 if(vw->width>=160 && vw->height>=120)
799 {
800 qcam->transfer_scale = 2;
801 }
802 if(vw->width>=320 && vw->height>=240)
803 {
804 qcam->width = 320;
805 qcam->height = 240;
806 qcam->transfer_scale = 1;
807 }
808 down(&qcam->lock);
809 qc_setscanmode(qcam);
810 up(&qcam->lock);
811
812 /* We must update the camera before we grab. We could
813 just have changed the grab size */
814 qcam->status |= QC_PARAM_CHANGE;
815
816 /* Ok we figured out what to use from our wide choice */
817 return 0;
818 }
819 case VIDIOCGWIN:
820 {
821 struct video_window *vw = arg;
822 memset(vw, 0, sizeof(*vw));
823 vw->width=qcam->width/qcam->transfer_scale;
824 vw->height=qcam->height/qcam->transfer_scale;
825 return 0;
826 }
827 case VIDIOCKEY:
828 return 0;
829 case VIDIOCCAPTURE:
830 case VIDIOCGFBUF:
831 case VIDIOCSFBUF:
832 case VIDIOCGFREQ:
833 case VIDIOCSFREQ:
834 case VIDIOCGAUDIO:
835 case VIDIOCSAUDIO:
836 return -EINVAL;
837 default:
838 return -ENOIOCTLCMD;
839 }
840 return 0;
841}
842
843static int qcam_ioctl(struct inode *inode, struct file *file,
844 unsigned int cmd, unsigned long arg)
845{
846 return video_usercopy(inode, file, cmd, arg, qcam_do_ioctl);
847}
848
849static ssize_t qcam_read(struct file *file, char __user *buf,
850 size_t count, loff_t *ppos)
851{
852 struct video_device *v = video_devdata(file);
853 struct qcam_device *qcam=(struct qcam_device *)v;
854 int len;
855 parport_claim_or_block(qcam->pdev);
856
857 down(&qcam->lock);
858
859 qc_reset(qcam);
860
861 /* Update the camera parameters if we need to */
862 if (qcam->status & QC_PARAM_CHANGE)
863 qc_set(qcam);
864
865 len=qc_capture(qcam, buf,count);
866
867 up(&qcam->lock);
868
869 parport_release(qcam->pdev);
870 return len;
871}
872
873static struct file_operations qcam_fops = {
874 .owner = THIS_MODULE,
875 .open = video_exclusive_open,
876 .release = video_exclusive_release,
877 .ioctl = qcam_ioctl,
878 .read = qcam_read,
879 .llseek = no_llseek,
880};
881static struct video_device qcam_template=
882{
883 .owner = THIS_MODULE,
884 .name = "Connectix Quickcam",
885 .type = VID_TYPE_CAPTURE,
886 .hardware = VID_HARDWARE_QCAM_BW,
887 .fops = &qcam_fops,
888};
889
890#define MAX_CAMS 4
891static struct qcam_device *qcams[MAX_CAMS];
892static unsigned int num_cams = 0;
893
894static int init_bwqcam(struct parport *port)
895{
896 struct qcam_device *qcam;
897
898 if (num_cams == MAX_CAMS)
899 {
900 printk(KERN_ERR "Too many Quickcams (max %d)\n", MAX_CAMS);
901 return -ENOSPC;
902 }
903
904 qcam=qcam_init(port);
905 if(qcam==NULL)
906 return -ENODEV;
907
908 parport_claim_or_block(qcam->pdev);
909
910 qc_reset(qcam);
911
912 if(qc_detect(qcam)==0)
913 {
914 parport_release(qcam->pdev);
915 parport_unregister_device(qcam->pdev);
916 kfree(qcam);
917 return -ENODEV;
918 }
919 qc_calibrate(qcam);
920
921 parport_release(qcam->pdev);
922
923 printk(KERN_INFO "Connectix Quickcam on %s\n", qcam->pport->name);
924
925 if(video_register_device(&qcam->vdev, VFL_TYPE_GRABBER, video_nr)==-1)
926 {
927 parport_unregister_device(qcam->pdev);
928 kfree(qcam);
929 return -ENODEV;
930 }
931
932 qcams[num_cams++] = qcam;
933
934 return 0;
935}
936
937static void close_bwqcam(struct qcam_device *qcam)
938{
939 video_unregister_device(&qcam->vdev);
940 parport_unregister_device(qcam->pdev);
941 kfree(qcam);
942}
943
944/* The parport parameter controls which parports will be scanned.
945 * Scanning all parports causes some printers to print a garbage page.
946 * -- March 14, 1999 Billy Donahue <billy@escape.com> */
947#ifdef MODULE
948static char *parport[MAX_CAMS] = { NULL, };
949module_param_array(parport, charp, NULL, 0);
950#endif
951
952static int accept_bwqcam(struct parport *port)
953{
954#ifdef MODULE
955 int n;
956
957 if (parport[0] && strncmp(parport[0], "auto", 4) != 0) {
958 /* user gave parport parameters */
959 for(n=0; parport[n] && n<MAX_CAMS; n++){
960 char *ep;
961 unsigned long r;
962 r = simple_strtoul(parport[n], &ep, 0);
963 if (ep == parport[n]) {
964 printk(KERN_ERR
965 "bw-qcam: bad port specifier \"%s\"\n",
966 parport[n]);
967 continue;
968 }
969 if (r == port->number)
970 return 1;
971 }
972 return 0;
973 }
974#endif
975 return 1;
976}
977
978static void bwqcam_attach(struct parport *port)
979{
980 if (accept_bwqcam(port))
981 init_bwqcam(port);
982}
983
984static void bwqcam_detach(struct parport *port)
985{
986 int i;
987 for (i = 0; i < num_cams; i++) {
988 struct qcam_device *qcam = qcams[i];
989 if (qcam && qcam->pdev->port == port) {
990 qcams[i] = NULL;
991 close_bwqcam(qcam);
992 }
993 }
994}
995
996static struct parport_driver bwqcam_driver = {
997 .name = "bw-qcam",
998 .attach = bwqcam_attach,
999 .detach = bwqcam_detach,
1000};
1001
1002static void __exit exit_bw_qcams(void)
1003{
1004 parport_unregister_driver(&bwqcam_driver);
1005}
1006
1007static int __init init_bw_qcams(void)
1008{
1009#ifdef MODULE
1010 /* Do some sanity checks on the module parameters. */
1011 if (maxpoll > 5000) {
1012 printk("Connectix Quickcam max-poll was above 5000. Using 5000.\n");
1013 maxpoll = 5000;
1014 }
1015
1016 if (yieldlines < 1) {
1017 printk("Connectix Quickcam yieldlines was less than 1. Using 1.\n");
1018 yieldlines = 1;
1019 }
1020#endif
1021 return parport_register_driver(&bwqcam_driver);
1022}
1023
1024module_init(init_bw_qcams);
1025module_exit(exit_bw_qcams);
1026
1027MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/bw-qcam.h b/drivers/media/video/bw-qcam.h
new file mode 100644
index 00000000000..723e8ad9e56
--- /dev/null
+++ b/drivers/media/video/bw-qcam.h
@@ -0,0 +1,68 @@
1/*
2 * Video4Linux bw-qcam driver
3 *
4 * Derived from code..
5 */
6
7/******************************************************************
8
9Copyright (C) 1996 by Scott Laird
10
11Permission is hereby granted, free of charge, to any person obtaining
12a copy of this software and associated documentation files (the
13"Software"), to deal in the Software without restriction, including
14without limitation the rights to use, copy, modify, merge, publish,
15distribute, sublicense, and/or sell copies of the Software, and to
16permit persons to whom the Software is furnished to do so, subject to
17the following conditions:
18
19The above copyright notice and this permission notice shall be
20included in all copies or substantial portions of the Software.
21
22THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
25IN NO EVENT SHALL SCOTT LAIRD BE LIABLE FOR ANY CLAIM, DAMAGES OR
26OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
27ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
28OTHER DEALINGS IN THE SOFTWARE.
29
30******************************************************************/
31
32/* One from column A... */
33#define QC_NOTSET 0
34#define QC_UNIDIR 1
35#define QC_BIDIR 2
36#define QC_SERIAL 3
37
38/* ... and one from column B */
39#define QC_ANY 0x00
40#define QC_FORCE_UNIDIR 0x10
41#define QC_FORCE_BIDIR 0x20
42#define QC_FORCE_SERIAL 0x30
43/* in the port_mode member */
44
45#define QC_MODE_MASK 0x07
46#define QC_FORCE_MASK 0x70
47
48#define MAX_HEIGHT 243
49#define MAX_WIDTH 336
50
51/* Bit fields for status flags */
52#define QC_PARAM_CHANGE 0x01 /* Camera status change has occurred */
53
54struct qcam_device {
55 struct video_device vdev;
56 struct pardevice *pdev;
57 struct parport *pport;
58 struct semaphore lock;
59 int width, height;
60 int bpp;
61 int mode;
62 int contrast, brightness, whitebal;
63 int port_mode;
64 int transfer_scale;
65 int top, left;
66 int status;
67 unsigned int saved_bits;
68};
diff --git a/drivers/media/video/c-qcam.c b/drivers/media/video/c-qcam.c
new file mode 100644
index 00000000000..75442ec49f3
--- /dev/null
+++ b/drivers/media/video/c-qcam.c
@@ -0,0 +1,855 @@
1/*
2 * Video4Linux Colour QuickCam driver
3 * Copyright 1997-2000 Philip Blundell <philb@gnu.org>
4 *
5 * Module parameters:
6 *
7 * parport=auto -- probe all parports (default)
8 * parport=0 -- parport0 becomes qcam1
9 * parport=2,0,1 -- parports 2,0,1 are tried in that order
10 *
11 * probe=0 -- do no probing, assume camera is present
12 * probe=1 -- use IEEE-1284 autoprobe data only (default)
13 * probe=2 -- probe aggressively for cameras
14 *
15 * force_rgb=1 -- force data format to RGB (default is BGR)
16 *
17 * The parport parameter controls which parports will be scanned.
18 * Scanning all parports causes some printers to print a garbage page.
19 * -- March 14, 1999 Billy Donahue <billy@escape.com>
20 *
21 * Fixed data format to BGR, added force_rgb parameter. Added missing
22 * parport_unregister_driver() on module removal.
23 * -- May 28, 2000 Claudio Matsuoka <claudio@conectiva.com>
24 */
25
26#include <linux/module.h>
27#include <linux/delay.h>
28#include <linux/errno.h>
29#include <linux/fs.h>
30#include <linux/init.h>
31#include <linux/kernel.h>
32#include <linux/slab.h>
33#include <linux/mm.h>
34#include <linux/parport.h>
35#include <linux/sched.h>
36#include <linux/videodev.h>
37#include <asm/semaphore.h>
38#include <asm/uaccess.h>
39
40struct qcam_device {
41 struct video_device vdev;
42 struct pardevice *pdev;
43 struct parport *pport;
44 int width, height;
45 int ccd_width, ccd_height;
46 int mode;
47 int contrast, brightness, whitebal;
48 int top, left;
49 unsigned int bidirectional;
50 struct semaphore lock;
51};
52
53/* cameras maximum */
54#define MAX_CAMS 4
55
56/* The three possible QuickCam modes */
57#define QC_MILLIONS 0x18
58#define QC_BILLIONS 0x10
59#define QC_THOUSANDS 0x08 /* with VIDEC compression (not supported) */
60
61/* The three possible decimations */
62#define QC_DECIMATION_1 0
63#define QC_DECIMATION_2 2
64#define QC_DECIMATION_4 4
65
66#define BANNER "Colour QuickCam for Video4Linux v0.05"
67
68static int parport[MAX_CAMS] = { [1 ... MAX_CAMS-1] = -1 };
69static int probe = 2;
70static int force_rgb = 0;
71static int video_nr = -1;
72
73static inline void qcam_set_ack(struct qcam_device *qcam, unsigned int i)
74{
75 /* note: the QC specs refer to the PCAck pin by voltage, not
76 software level. PC ports have builtin inverters. */
77 parport_frob_control(qcam->pport, 8, i?8:0);
78}
79
80static inline unsigned int qcam_ready1(struct qcam_device *qcam)
81{
82 return (parport_read_status(qcam->pport) & 0x8)?1:0;
83}
84
85static inline unsigned int qcam_ready2(struct qcam_device *qcam)
86{
87 return (parport_read_data(qcam->pport) & 0x1)?1:0;
88}
89
90static unsigned int qcam_await_ready1(struct qcam_device *qcam,
91 int value)
92{
93 unsigned long oldjiffies = jiffies;
94 unsigned int i;
95
96 for (oldjiffies = jiffies; (jiffies - oldjiffies) < (HZ/25); )
97 if (qcam_ready1(qcam) == value)
98 return 0;
99
100 /* If the camera didn't respond within 1/25 second, poll slowly
101 for a while. */
102 for (i = 0; i < 50; i++)
103 {
104 if (qcam_ready1(qcam) == value)
105 return 0;
106 msleep_interruptible(100);
107 }
108
109 /* Probably somebody pulled the plug out. Not much we can do. */
110 printk(KERN_ERR "c-qcam: ready1 timeout (%d) %x %x\n", value,
111 parport_read_status(qcam->pport),
112 parport_read_control(qcam->pport));
113 return 1;
114}
115
116static unsigned int qcam_await_ready2(struct qcam_device *qcam, int value)
117{
118 unsigned long oldjiffies = jiffies;
119 unsigned int i;
120
121 for (oldjiffies = jiffies; (jiffies - oldjiffies) < (HZ/25); )
122 if (qcam_ready2(qcam) == value)
123 return 0;
124
125 /* If the camera didn't respond within 1/25 second, poll slowly
126 for a while. */
127 for (i = 0; i < 50; i++)
128 {
129 if (qcam_ready2(qcam) == value)
130 return 0;
131 msleep_interruptible(100);
132 }
133
134 /* Probably somebody pulled the plug out. Not much we can do. */
135 printk(KERN_ERR "c-qcam: ready2 timeout (%d) %x %x %x\n", value,
136 parport_read_status(qcam->pport),
137 parport_read_control(qcam->pport),
138 parport_read_data(qcam->pport));
139 return 1;
140}
141
142static int qcam_read_data(struct qcam_device *qcam)
143{
144 unsigned int idata;
145 qcam_set_ack(qcam, 0);
146 if (qcam_await_ready1(qcam, 1)) return -1;
147 idata = parport_read_status(qcam->pport) & 0xf0;
148 qcam_set_ack(qcam, 1);
149 if (qcam_await_ready1(qcam, 0)) return -1;
150 idata |= (parport_read_status(qcam->pport) >> 4);
151 return idata;
152}
153
154static int qcam_write_data(struct qcam_device *qcam, unsigned int data)
155{
156 unsigned int idata;
157 parport_write_data(qcam->pport, data);
158 idata = qcam_read_data(qcam);
159 if (data != idata)
160 {
161 printk(KERN_WARNING "cqcam: sent %x but received %x\n", data,
162 idata);
163 return 1;
164 }
165 return 0;
166}
167
168static inline int qcam_set(struct qcam_device *qcam, unsigned int cmd, unsigned int data)
169{
170 if (qcam_write_data(qcam, cmd))
171 return -1;
172 if (qcam_write_data(qcam, data))
173 return -1;
174 return 0;
175}
176
177static inline int qcam_get(struct qcam_device *qcam, unsigned int cmd)
178{
179 if (qcam_write_data(qcam, cmd))
180 return -1;
181 return qcam_read_data(qcam);
182}
183
184static int qc_detect(struct qcam_device *qcam)
185{
186 unsigned int stat, ostat, i, count = 0;
187
188 /* The probe routine below is not very reliable. The IEEE-1284
189 probe takes precedence. */
190 /* XXX Currently parport provides no way to distinguish between
191 "the IEEE probe was not done" and "the probe was done, but
192 no device was found". Fix this one day. */
193 if (qcam->pport->probe_info[0].class == PARPORT_CLASS_MEDIA
194 && qcam->pport->probe_info[0].model
195 && !strcmp(qcam->pdev->port->probe_info[0].model,
196 "Color QuickCam 2.0")) {
197 printk(KERN_DEBUG "QuickCam: Found by IEEE1284 probe.\n");
198 return 1;
199 }
200
201 if (probe < 2)
202 return 0;
203
204 parport_write_control(qcam->pport, 0xc);
205
206 /* look for a heartbeat */
207 ostat = stat = parport_read_status(qcam->pport);
208 for (i=0; i<250; i++)
209 {
210 mdelay(1);
211 stat = parport_read_status(qcam->pport);
212 if (ostat != stat)
213 {
214 if (++count >= 3) return 1;
215 ostat = stat;
216 }
217 }
218
219 /* Reset the camera and try again */
220 parport_write_control(qcam->pport, 0xc);
221 parport_write_control(qcam->pport, 0x8);
222 mdelay(1);
223 parport_write_control(qcam->pport, 0xc);
224 mdelay(1);
225 count = 0;
226
227 ostat = stat = parport_read_status(qcam->pport);
228 for (i=0; i<250; i++)
229 {
230 mdelay(1);
231 stat = parport_read_status(qcam->pport);
232 if (ostat != stat)
233 {
234 if (++count >= 3) return 1;
235 ostat = stat;
236 }
237 }
238
239 /* no (or flatline) camera, give up */
240 return 0;
241}
242
243static void qc_reset(struct qcam_device *qcam)
244{
245 parport_write_control(qcam->pport, 0xc);
246 parport_write_control(qcam->pport, 0x8);
247 mdelay(1);
248 parport_write_control(qcam->pport, 0xc);
249 mdelay(1);
250}
251
252/* Reset the QuickCam and program for brightness, contrast,
253 * white-balance, and resolution. */
254
255static void qc_setup(struct qcam_device *q)
256{
257 qc_reset(q);
258
259 /* Set the brightness. */
260 qcam_set(q, 11, q->brightness);
261
262 /* Set the height and width. These refer to the actual
263 CCD area *before* applying the selected decimation. */
264 qcam_set(q, 17, q->ccd_height);
265 qcam_set(q, 19, q->ccd_width / 2);
266
267 /* Set top and left. */
268 qcam_set(q, 0xd, q->top);
269 qcam_set(q, 0xf, q->left);
270
271 /* Set contrast and white balance. */
272 qcam_set(q, 0x19, q->contrast);
273 qcam_set(q, 0x1f, q->whitebal);
274
275 /* Set the speed. */
276 qcam_set(q, 45, 2);
277}
278
279/* Read some bytes from the camera and put them in the buffer.
280 nbytes should be a multiple of 3, because bidirectional mode gives
281 us three bytes at a time. */
282
283static unsigned int qcam_read_bytes(struct qcam_device *q, unsigned char *buf, unsigned int nbytes)
284{
285 unsigned int bytes = 0;
286
287 qcam_set_ack(q, 0);
288 if (q->bidirectional)
289 {
290 /* It's a bidirectional port */
291 while (bytes < nbytes)
292 {
293 unsigned int lo1, hi1, lo2, hi2;
294 unsigned char r, g, b;
295
296 if (qcam_await_ready2(q, 1)) return bytes;
297 lo1 = parport_read_data(q->pport) >> 1;
298 hi1 = ((parport_read_status(q->pport) >> 3) & 0x1f) ^ 0x10;
299 qcam_set_ack(q, 1);
300 if (qcam_await_ready2(q, 0)) return bytes;
301 lo2 = parport_read_data(q->pport) >> 1;
302 hi2 = ((parport_read_status(q->pport) >> 3) & 0x1f) ^ 0x10;
303 qcam_set_ack(q, 0);
304 r = (lo1 | ((hi1 & 1)<<7));
305 g = ((hi1 & 0x1e)<<3) | ((hi2 & 0x1e)>>1);
306 b = (lo2 | ((hi2 & 1)<<7));
307 if (force_rgb) {
308 buf[bytes++] = r;
309 buf[bytes++] = g;
310 buf[bytes++] = b;
311 } else {
312 buf[bytes++] = b;
313 buf[bytes++] = g;
314 buf[bytes++] = r;
315 }
316 }
317 }
318 else
319 {
320 /* It's a unidirectional port */
321 int i = 0, n = bytes;
322 unsigned char rgb[3];
323
324 while (bytes < nbytes)
325 {
326 unsigned int hi, lo;
327
328 if (qcam_await_ready1(q, 1)) return bytes;
329 hi = (parport_read_status(q->pport) & 0xf0);
330 qcam_set_ack(q, 1);
331 if (qcam_await_ready1(q, 0)) return bytes;
332 lo = (parport_read_status(q->pport) & 0xf0);
333 qcam_set_ack(q, 0);
334 /* flip some bits */
335 rgb[(i = bytes++ % 3)] = (hi | (lo >> 4)) ^ 0x88;
336 if (i >= 2) {
337get_fragment:
338 if (force_rgb) {
339 buf[n++] = rgb[0];
340 buf[n++] = rgb[1];
341 buf[n++] = rgb[2];
342 } else {
343 buf[n++] = rgb[2];
344 buf[n++] = rgb[1];
345 buf[n++] = rgb[0];
346 }
347 }
348 }
349 if (i) {
350 i = 0;
351 goto get_fragment;
352 }
353 }
354 return bytes;
355}
356
357#define BUFSZ 150
358
359static long qc_capture(struct qcam_device *q, char __user *buf, unsigned long len)
360{
361 unsigned lines, pixelsperline, bitsperxfer;
362 unsigned int is_bi_dir = q->bidirectional;
363 size_t wantlen, outptr = 0;
364 char tmpbuf[BUFSZ];
365
366 if (!access_ok(VERIFY_WRITE, buf, len))
367 return -EFAULT;
368
369 /* Wait for camera to become ready */
370 for (;;)
371 {
372 int i = qcam_get(q, 41);
373 if (i == -1) {
374 qc_setup(q);
375 return -EIO;
376 }
377 if ((i & 0x80) == 0)
378 break;
379 else
380 schedule();
381 }
382
383 if (qcam_set(q, 7, (q->mode | (is_bi_dir?1:0)) + 1))
384 return -EIO;
385
386 lines = q->height;
387 pixelsperline = q->width;
388 bitsperxfer = (is_bi_dir) ? 24 : 8;
389
390 if (is_bi_dir)
391 {
392 /* Turn the port around */
393 parport_data_reverse(q->pport);
394 mdelay(3);
395 qcam_set_ack(q, 0);
396 if (qcam_await_ready1(q, 1)) {
397 qc_setup(q);
398 return -EIO;
399 }
400 qcam_set_ack(q, 1);
401 if (qcam_await_ready1(q, 0)) {
402 qc_setup(q);
403 return -EIO;
404 }
405 }
406
407 wantlen = lines * pixelsperline * 24 / 8;
408
409 while (wantlen)
410 {
411 size_t t, s;
412 s = (wantlen > BUFSZ)?BUFSZ:wantlen;
413 t = qcam_read_bytes(q, tmpbuf, s);
414 if (outptr < len)
415 {
416 size_t sz = len - outptr;
417 if (sz > t) sz = t;
418 if (__copy_to_user(buf+outptr, tmpbuf, sz))
419 break;
420 outptr += sz;
421 }
422 wantlen -= t;
423 if (t < s)
424 break;
425 cond_resched();
426 }
427
428 len = outptr;
429
430 if (wantlen)
431 {
432 printk("qcam: short read.\n");
433 if (is_bi_dir)
434 parport_data_forward(q->pport);
435 qc_setup(q);
436 return len;
437 }
438
439 if (is_bi_dir)
440 {
441 int l;
442 do {
443 l = qcam_read_bytes(q, tmpbuf, 3);
444 cond_resched();
445 } while (l && (tmpbuf[0] == 0x7e || tmpbuf[1] == 0x7e || tmpbuf[2] == 0x7e));
446 if (force_rgb) {
447 if (tmpbuf[0] != 0xe || tmpbuf[1] != 0x0 || tmpbuf[2] != 0xf)
448 printk("qcam: bad EOF\n");
449 } else {
450 if (tmpbuf[0] != 0xf || tmpbuf[1] != 0x0 || tmpbuf[2] != 0xe)
451 printk("qcam: bad EOF\n");
452 }
453 qcam_set_ack(q, 0);
454 if (qcam_await_ready1(q, 1))
455 {
456 printk("qcam: no ack after EOF\n");
457 parport_data_forward(q->pport);
458 qc_setup(q);
459 return len;
460 }
461 parport_data_forward(q->pport);
462 mdelay(3);
463 qcam_set_ack(q, 1);
464 if (qcam_await_ready1(q, 0))
465 {
466 printk("qcam: no ack to port turnaround\n");
467 qc_setup(q);
468 return len;
469 }
470 }
471 else
472 {
473 int l;
474 do {
475 l = qcam_read_bytes(q, tmpbuf, 1);
476 cond_resched();
477 } while (l && tmpbuf[0] == 0x7e);
478 l = qcam_read_bytes(q, tmpbuf+1, 2);
479 if (force_rgb) {
480 if (tmpbuf[0] != 0xe || tmpbuf[1] != 0x0 || tmpbuf[2] != 0xf)
481 printk("qcam: bad EOF\n");
482 } else {
483 if (tmpbuf[0] != 0xf || tmpbuf[1] != 0x0 || tmpbuf[2] != 0xe)
484 printk("qcam: bad EOF\n");
485 }
486 }
487
488 qcam_write_data(q, 0);
489 return len;
490}
491
492/*
493 * Video4linux interfacing
494 */
495
496static int qcam_do_ioctl(struct inode *inode, struct file *file,
497 unsigned int cmd, void *arg)
498{
499 struct video_device *dev = video_devdata(file);
500 struct qcam_device *qcam=(struct qcam_device *)dev;
501
502 switch(cmd)
503 {
504 case VIDIOCGCAP:
505 {
506 struct video_capability *b = arg;
507 strcpy(b->name, "Quickcam");
508 b->type = VID_TYPE_CAPTURE|VID_TYPE_SCALES;
509 b->channels = 1;
510 b->audios = 0;
511 b->maxwidth = 320;
512 b->maxheight = 240;
513 b->minwidth = 80;
514 b->minheight = 60;
515 return 0;
516 }
517 case VIDIOCGCHAN:
518 {
519 struct video_channel *v = arg;
520 if(v->channel!=0)
521 return -EINVAL;
522 v->flags=0;
523 v->tuners=0;
524 /* Good question.. its composite or SVHS so.. */
525 v->type = VIDEO_TYPE_CAMERA;
526 strcpy(v->name, "Camera");
527 return 0;
528 }
529 case VIDIOCSCHAN:
530 {
531 struct video_channel *v = arg;
532 if(v->channel!=0)
533 return -EINVAL;
534 return 0;
535 }
536 case VIDIOCGTUNER:
537 {
538 struct video_tuner *v = arg;
539 if(v->tuner)
540 return -EINVAL;
541 memset(v,0,sizeof(*v));
542 strcpy(v->name, "Format");
543 v->mode = VIDEO_MODE_AUTO;
544 return 0;
545 }
546 case VIDIOCSTUNER:
547 {
548 struct video_tuner *v = arg;
549 if(v->tuner)
550 return -EINVAL;
551 if(v->mode!=VIDEO_MODE_AUTO)
552 return -EINVAL;
553 return 0;
554 }
555 case VIDIOCGPICT:
556 {
557 struct video_picture *p = arg;
558 p->colour=0x8000;
559 p->hue=0x8000;
560 p->brightness=qcam->brightness<<8;
561 p->contrast=qcam->contrast<<8;
562 p->whiteness=qcam->whitebal<<8;
563 p->depth=24;
564 p->palette=VIDEO_PALETTE_RGB24;
565 return 0;
566 }
567 case VIDIOCSPICT:
568 {
569 struct video_picture *p = arg;
570
571 /*
572 * Sanity check args
573 */
574 if (p->depth != 24 || p->palette != VIDEO_PALETTE_RGB24)
575 return -EINVAL;
576
577 /*
578 * Now load the camera.
579 */
580 qcam->brightness = p->brightness>>8;
581 qcam->contrast = p->contrast>>8;
582 qcam->whitebal = p->whiteness>>8;
583
584 down(&qcam->lock);
585 parport_claim_or_block(qcam->pdev);
586 qc_setup(qcam);
587 parport_release(qcam->pdev);
588 up(&qcam->lock);
589 return 0;
590 }
591 case VIDIOCSWIN:
592 {
593 struct video_window *vw = arg;
594
595 if(vw->flags)
596 return -EINVAL;
597 if(vw->clipcount)
598 return -EINVAL;
599 if(vw->height<60||vw->height>240)
600 return -EINVAL;
601 if(vw->width<80||vw->width>320)
602 return -EINVAL;
603
604 qcam->width = 80;
605 qcam->height = 60;
606 qcam->mode = QC_DECIMATION_4;
607
608 if(vw->width>=160 && vw->height>=120)
609 {
610 qcam->width = 160;
611 qcam->height = 120;
612 qcam->mode = QC_DECIMATION_2;
613 }
614 if(vw->width>=320 && vw->height>=240)
615 {
616 qcam->width = 320;
617 qcam->height = 240;
618 qcam->mode = QC_DECIMATION_1;
619 }
620 qcam->mode |= QC_MILLIONS;
621#if 0
622 if(vw->width>=640 && vw->height>=480)
623 {
624 qcam->width = 640;
625 qcam->height = 480;
626 qcam->mode = QC_BILLIONS | QC_DECIMATION_1;
627 }
628#endif
629 /* Ok we figured out what to use from our
630 wide choice */
631 down(&qcam->lock);
632 parport_claim_or_block(qcam->pdev);
633 qc_setup(qcam);
634 parport_release(qcam->pdev);
635 up(&qcam->lock);
636 return 0;
637 }
638 case VIDIOCGWIN:
639 {
640 struct video_window *vw = arg;
641 memset(vw, 0, sizeof(*vw));
642 vw->width=qcam->width;
643 vw->height=qcam->height;
644 return 0;
645 }
646 case VIDIOCKEY:
647 return 0;
648 case VIDIOCCAPTURE:
649 case VIDIOCGFBUF:
650 case VIDIOCSFBUF:
651 case VIDIOCGFREQ:
652 case VIDIOCSFREQ:
653 case VIDIOCGAUDIO:
654 case VIDIOCSAUDIO:
655 return -EINVAL;
656 default:
657 return -ENOIOCTLCMD;
658 }
659 return 0;
660}
661
662static int qcam_ioctl(struct inode *inode, struct file *file,
663 unsigned int cmd, unsigned long arg)
664{
665 return video_usercopy(inode, file, cmd, arg, qcam_do_ioctl);
666}
667
668static ssize_t qcam_read(struct file *file, char __user *buf,
669 size_t count, loff_t *ppos)
670{
671 struct video_device *v = video_devdata(file);
672 struct qcam_device *qcam=(struct qcam_device *)v;
673 int len;
674
675 down(&qcam->lock);
676 parport_claim_or_block(qcam->pdev);
677 /* Probably should have a semaphore against multiple users */
678 len = qc_capture(qcam, buf,count);
679 parport_release(qcam->pdev);
680 up(&qcam->lock);
681 return len;
682}
683
684/* video device template */
685static struct file_operations qcam_fops = {
686 .owner = THIS_MODULE,
687 .open = video_exclusive_open,
688 .release = video_exclusive_release,
689 .ioctl = qcam_ioctl,
690 .read = qcam_read,
691 .llseek = no_llseek,
692};
693
694static struct video_device qcam_template=
695{
696 .owner = THIS_MODULE,
697 .name = "Colour QuickCam",
698 .type = VID_TYPE_CAPTURE,
699 .hardware = VID_HARDWARE_QCAM_C,
700 .fops = &qcam_fops,
701};
702
703/* Initialize the QuickCam driver control structure. */
704
705static struct qcam_device *qcam_init(struct parport *port)
706{
707 struct qcam_device *q;
708
709 q = kmalloc(sizeof(struct qcam_device), GFP_KERNEL);
710 if(q==NULL)
711 return NULL;
712
713 q->pport = port;
714 q->pdev = parport_register_device(port, "c-qcam", NULL, NULL,
715 NULL, 0, NULL);
716
717 q->bidirectional = (q->pport->modes & PARPORT_MODE_TRISTATE)?1:0;
718
719 if (q->pdev == NULL)
720 {
721 printk(KERN_ERR "c-qcam: couldn't register for %s.\n",
722 port->name);
723 kfree(q);
724 return NULL;
725 }
726
727 memcpy(&q->vdev, &qcam_template, sizeof(qcam_template));
728
729 init_MUTEX(&q->lock);
730 q->width = q->ccd_width = 320;
731 q->height = q->ccd_height = 240;
732 q->mode = QC_MILLIONS | QC_DECIMATION_1;
733 q->contrast = 192;
734 q->brightness = 240;
735 q->whitebal = 128;
736 q->top = 1;
737 q->left = 14;
738 return q;
739}
740
741static struct qcam_device *qcams[MAX_CAMS];
742static unsigned int num_cams = 0;
743
744static int init_cqcam(struct parport *port)
745{
746 struct qcam_device *qcam;
747
748 if (parport[0] != -1)
749 {
750 /* The user gave specific instructions */
751 int i, found = 0;
752 for (i = 0; i < MAX_CAMS && parport[i] != -1; i++)
753 {
754 if (parport[0] == port->number)
755 found = 1;
756 }
757 if (!found)
758 return -ENODEV;
759 }
760
761 if (num_cams == MAX_CAMS)
762 return -ENOSPC;
763
764 qcam = qcam_init(port);
765 if (qcam==NULL)
766 return -ENODEV;
767
768 parport_claim_or_block(qcam->pdev);
769
770 qc_reset(qcam);
771
772 if (probe && qc_detect(qcam)==0)
773 {
774 parport_release(qcam->pdev);
775 parport_unregister_device(qcam->pdev);
776 kfree(qcam);
777 return -ENODEV;
778 }
779
780 qc_setup(qcam);
781
782 parport_release(qcam->pdev);
783
784 if (video_register_device(&qcam->vdev, VFL_TYPE_GRABBER, video_nr)==-1)
785 {
786 printk(KERN_ERR "Unable to register Colour QuickCam on %s\n",
787 qcam->pport->name);
788 parport_unregister_device(qcam->pdev);
789 kfree(qcam);
790 return -ENODEV;
791 }
792
793 printk(KERN_INFO "video%d: Colour QuickCam found on %s\n",
794 qcam->vdev.minor, qcam->pport->name);
795
796 qcams[num_cams++] = qcam;
797
798 return 0;
799}
800
801static void close_cqcam(struct qcam_device *qcam)
802{
803 video_unregister_device(&qcam->vdev);
804 parport_unregister_device(qcam->pdev);
805 kfree(qcam);
806}
807
808static void cq_attach(struct parport *port)
809{
810 init_cqcam(port);
811}
812
813static void cq_detach(struct parport *port)
814{
815 /* Write this some day. */
816}
817
818static struct parport_driver cqcam_driver = {
819 .name = "cqcam",
820 .attach = cq_attach,
821 .detach = cq_detach,
822};
823
824static int __init cqcam_init (void)
825{
826 printk(BANNER "\n");
827
828 return parport_register_driver(&cqcam_driver);
829}
830
831static void __exit cqcam_cleanup (void)
832{
833 unsigned int i;
834
835 for (i = 0; i < num_cams; i++)
836 close_cqcam(qcams[i]);
837
838 parport_unregister_driver(&cqcam_driver);
839}
840
841MODULE_AUTHOR("Philip Blundell <philb@gnu.org>");
842MODULE_DESCRIPTION(BANNER);
843MODULE_LICENSE("GPL");
844
845/* FIXME: parport=auto would never have worked, surely? --RR */
846MODULE_PARM_DESC(parport ,"parport=<auto|n[,n]...> for port detection method\n\
847probe=<0|1|2> for camera detection method\n\
848force_rgb=<0|1> for RGB data format (default BGR)");
849module_param_array(parport, int, NULL, 0);
850module_param(probe, int, 0);
851module_param(force_rgb, bool, 0);
852module_param(video_nr, int, 0);
853
854module_init(cqcam_init);
855module_exit(cqcam_cleanup);
diff --git a/drivers/media/video/cpia.c b/drivers/media/video/cpia.c
new file mode 100644
index 00000000000..8c08b7f1ad2
--- /dev/null
+++ b/drivers/media/video/cpia.c
@@ -0,0 +1,4073 @@
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#include <linux/config.h>
30
31#include <linux/module.h>
32#include <linux/moduleparam.h>
33#include <linux/init.h>
34#include <linux/fs.h>
35#include <linux/vmalloc.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 <asm/semaphore.h>
43
44#ifdef CONFIG_KMOD
45#include <linux/kmod.h>
46#endif
47
48#include "cpia.h"
49
50#ifdef CONFIG_VIDEO_CPIA_PP
51extern int cpia_pp_init(void);
52#endif
53#ifdef CONFIG_VIDEO_CPIA_USB
54extern int cpia_usb_init(void);
55#endif
56
57static int video_nr = -1;
58
59#ifdef MODULE
60module_param(video_nr, int, 0);
61MODULE_AUTHOR("Scott J. Bertin <sbertin@securenym.net> & Peter Pregler <Peter_Pregler@email.com> & Johannes Erdfelt <johannes@erdfeld.com>");
62MODULE_DESCRIPTION("V4L-driver for Vision CPiA based cameras");
63MODULE_LICENSE("GPL");
64MODULE_SUPPORTED_DEVICE("video");
65#endif
66
67static unsigned short colorspace_conv = 0;
68module_param(colorspace_conv, ushort, 0444);
69MODULE_PARM_DESC(colorspace_conv,
70 "\n<n> Colorspace conversion:"
71 "\n0 = disable"
72 "\n1 = enable"
73 "\nDefault value is 0"
74 "\n");
75
76#define ABOUT "V4L-Driver for Vision CPiA based cameras"
77
78#ifndef VID_HARDWARE_CPIA
79#define VID_HARDWARE_CPIA 24 /* FIXME -> from linux/videodev.h */
80#endif
81
82#define CPIA_MODULE_CPIA (0<<5)
83#define CPIA_MODULE_SYSTEM (1<<5)
84#define CPIA_MODULE_VP_CTRL (5<<5)
85#define CPIA_MODULE_CAPTURE (6<<5)
86#define CPIA_MODULE_DEBUG (7<<5)
87
88#define INPUT (DATA_IN << 8)
89#define OUTPUT (DATA_OUT << 8)
90
91#define CPIA_COMMAND_GetCPIAVersion (INPUT | CPIA_MODULE_CPIA | 1)
92#define CPIA_COMMAND_GetPnPID (INPUT | CPIA_MODULE_CPIA | 2)
93#define CPIA_COMMAND_GetCameraStatus (INPUT | CPIA_MODULE_CPIA | 3)
94#define CPIA_COMMAND_GotoHiPower (OUTPUT | CPIA_MODULE_CPIA | 4)
95#define CPIA_COMMAND_GotoLoPower (OUTPUT | CPIA_MODULE_CPIA | 5)
96#define CPIA_COMMAND_GotoSuspend (OUTPUT | CPIA_MODULE_CPIA | 7)
97#define CPIA_COMMAND_GotoPassThrough (OUTPUT | CPIA_MODULE_CPIA | 8)
98#define CPIA_COMMAND_ModifyCameraStatus (OUTPUT | CPIA_MODULE_CPIA | 10)
99
100#define CPIA_COMMAND_ReadVCRegs (INPUT | CPIA_MODULE_SYSTEM | 1)
101#define CPIA_COMMAND_WriteVCReg (OUTPUT | CPIA_MODULE_SYSTEM | 2)
102#define CPIA_COMMAND_ReadMCPorts (INPUT | CPIA_MODULE_SYSTEM | 3)
103#define CPIA_COMMAND_WriteMCPort (OUTPUT | CPIA_MODULE_SYSTEM | 4)
104#define CPIA_COMMAND_SetBaudRate (OUTPUT | CPIA_MODULE_SYSTEM | 5)
105#define CPIA_COMMAND_SetECPTiming (OUTPUT | CPIA_MODULE_SYSTEM | 6)
106#define CPIA_COMMAND_ReadIDATA (INPUT | CPIA_MODULE_SYSTEM | 7)
107#define CPIA_COMMAND_WriteIDATA (OUTPUT | CPIA_MODULE_SYSTEM | 8)
108#define CPIA_COMMAND_GenericCall (OUTPUT | CPIA_MODULE_SYSTEM | 9)
109#define CPIA_COMMAND_I2CStart (OUTPUT | CPIA_MODULE_SYSTEM | 10)
110#define CPIA_COMMAND_I2CStop (OUTPUT | CPIA_MODULE_SYSTEM | 11)
111#define CPIA_COMMAND_I2CWrite (OUTPUT | CPIA_MODULE_SYSTEM | 12)
112#define CPIA_COMMAND_I2CRead (INPUT | CPIA_MODULE_SYSTEM | 13)
113
114#define CPIA_COMMAND_GetVPVersion (INPUT | CPIA_MODULE_VP_CTRL | 1)
115#define CPIA_COMMAND_ResetFrameCounter (INPUT | CPIA_MODULE_VP_CTRL | 2)
116#define CPIA_COMMAND_SetColourParams (OUTPUT | CPIA_MODULE_VP_CTRL | 3)
117#define CPIA_COMMAND_SetExposure (OUTPUT | CPIA_MODULE_VP_CTRL | 4)
118#define CPIA_COMMAND_SetColourBalance (OUTPUT | CPIA_MODULE_VP_CTRL | 6)
119#define CPIA_COMMAND_SetSensorFPS (OUTPUT | CPIA_MODULE_VP_CTRL | 7)
120#define CPIA_COMMAND_SetVPDefaults (OUTPUT | CPIA_MODULE_VP_CTRL | 8)
121#define CPIA_COMMAND_SetApcor (OUTPUT | CPIA_MODULE_VP_CTRL | 9)
122#define CPIA_COMMAND_SetFlickerCtrl (OUTPUT | CPIA_MODULE_VP_CTRL | 10)
123#define CPIA_COMMAND_SetVLOffset (OUTPUT | CPIA_MODULE_VP_CTRL | 11)
124#define CPIA_COMMAND_GetColourParams (INPUT | CPIA_MODULE_VP_CTRL | 16)
125#define CPIA_COMMAND_GetColourBalance (INPUT | CPIA_MODULE_VP_CTRL | 17)
126#define CPIA_COMMAND_GetExposure (INPUT | CPIA_MODULE_VP_CTRL | 18)
127#define CPIA_COMMAND_SetSensorMatrix (OUTPUT | CPIA_MODULE_VP_CTRL | 19)
128#define CPIA_COMMAND_ColourBars (OUTPUT | CPIA_MODULE_VP_CTRL | 25)
129#define CPIA_COMMAND_ReadVPRegs (INPUT | CPIA_MODULE_VP_CTRL | 30)
130#define CPIA_COMMAND_WriteVPReg (OUTPUT | CPIA_MODULE_VP_CTRL | 31)
131
132#define CPIA_COMMAND_GrabFrame (OUTPUT | CPIA_MODULE_CAPTURE | 1)
133#define CPIA_COMMAND_UploadFrame (OUTPUT | CPIA_MODULE_CAPTURE | 2)
134#define CPIA_COMMAND_SetGrabMode (OUTPUT | CPIA_MODULE_CAPTURE | 3)
135#define CPIA_COMMAND_InitStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 4)
136#define CPIA_COMMAND_FiniStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 5)
137#define CPIA_COMMAND_StartStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 6)
138#define CPIA_COMMAND_EndStreamCap (OUTPUT | CPIA_MODULE_CAPTURE | 7)
139#define CPIA_COMMAND_SetFormat (OUTPUT | CPIA_MODULE_CAPTURE | 8)
140#define CPIA_COMMAND_SetROI (OUTPUT | CPIA_MODULE_CAPTURE | 9)
141#define CPIA_COMMAND_SetCompression (OUTPUT | CPIA_MODULE_CAPTURE | 10)
142#define CPIA_COMMAND_SetCompressionTarget (OUTPUT | CPIA_MODULE_CAPTURE | 11)
143#define CPIA_COMMAND_SetYUVThresh (OUTPUT | CPIA_MODULE_CAPTURE | 12)
144#define CPIA_COMMAND_SetCompressionParams (OUTPUT | CPIA_MODULE_CAPTURE | 13)
145#define CPIA_COMMAND_DiscardFrame (OUTPUT | CPIA_MODULE_CAPTURE | 14)
146#define CPIA_COMMAND_GrabReset (OUTPUT | CPIA_MODULE_CAPTURE | 15)
147
148#define CPIA_COMMAND_OutputRS232 (OUTPUT | CPIA_MODULE_DEBUG | 1)
149#define CPIA_COMMAND_AbortProcess (OUTPUT | CPIA_MODULE_DEBUG | 4)
150#define CPIA_COMMAND_SetDramPage (OUTPUT | CPIA_MODULE_DEBUG | 5)
151#define CPIA_COMMAND_StartDramUpload (OUTPUT | CPIA_MODULE_DEBUG | 6)
152#define CPIA_COMMAND_StartDummyDtream (OUTPUT | CPIA_MODULE_DEBUG | 8)
153#define CPIA_COMMAND_AbortStream (OUTPUT | CPIA_MODULE_DEBUG | 9)
154#define CPIA_COMMAND_DownloadDRAM (OUTPUT | CPIA_MODULE_DEBUG | 10)
155#define CPIA_COMMAND_Null (OUTPUT | CPIA_MODULE_DEBUG | 11)
156
157enum {
158 FRAME_READY, /* Ready to grab into */
159 FRAME_GRABBING, /* In the process of being grabbed into */
160 FRAME_DONE, /* Finished grabbing, but not been synced yet */
161 FRAME_UNUSED, /* Unused (no MCAPTURE) */
162};
163
164#define COMMAND_NONE 0x0000
165#define COMMAND_SETCOMPRESSION 0x0001
166#define COMMAND_SETCOMPRESSIONTARGET 0x0002
167#define COMMAND_SETCOLOURPARAMS 0x0004
168#define COMMAND_SETFORMAT 0x0008
169#define COMMAND_PAUSE 0x0010
170#define COMMAND_RESUME 0x0020
171#define COMMAND_SETYUVTHRESH 0x0040
172#define COMMAND_SETECPTIMING 0x0080
173#define COMMAND_SETCOMPRESSIONPARAMS 0x0100
174#define COMMAND_SETEXPOSURE 0x0200
175#define COMMAND_SETCOLOURBALANCE 0x0400
176#define COMMAND_SETSENSORFPS 0x0800
177#define COMMAND_SETAPCOR 0x1000
178#define COMMAND_SETFLICKERCTRL 0x2000
179#define COMMAND_SETVLOFFSET 0x4000
180#define COMMAND_SETLIGHTS 0x8000
181
182#define ROUND_UP_EXP_FOR_FLICKER 15
183
184/* Constants for automatic frame rate adjustment */
185#define MAX_EXP 302
186#define MAX_EXP_102 255
187#define LOW_EXP 140
188#define VERY_LOW_EXP 70
189#define TC 94
190#define EXP_ACC_DARK 50
191#define EXP_ACC_LIGHT 90
192#define HIGH_COMP_102 160
193#define MAX_COMP 239
194#define DARK_TIME 3
195#define LIGHT_TIME 3
196
197/* Maximum number of 10ms loops to wait for the stream to become ready */
198#define READY_TIMEOUT 100
199
200/* Developer's Guide Table 5 p 3-34
201 * indexed by [mains][sensorFps.baserate][sensorFps.divisor]*/
202static u8 flicker_jumps[2][2][4] =
203{ { { 76, 38, 19, 9 }, { 92, 46, 23, 11 } },
204 { { 64, 32, 16, 8 }, { 76, 38, 19, 9} }
205};
206
207/* forward declaration of local function */
208static void reset_camera_struct(struct cam_data *cam);
209static int find_over_exposure(int brightness);
210static void set_flicker(struct cam_params *params, volatile u32 *command_flags,
211 int on);
212
213
214/**********************************************************************
215 *
216 * Memory management
217 *
218 **********************************************************************/
219static void *rvmalloc(unsigned long size)
220{
221 void *mem;
222 unsigned long adr;
223
224 size = PAGE_ALIGN(size);
225 mem = vmalloc_32(size);
226 if (!mem)
227 return NULL;
228
229 memset(mem, 0, size); /* Clear the ram out, no junk to the user */
230 adr = (unsigned long) mem;
231 while (size > 0) {
232 SetPageReserved(vmalloc_to_page((void *)adr));
233 adr += PAGE_SIZE;
234 size -= PAGE_SIZE;
235 }
236
237 return mem;
238}
239
240static void rvfree(void *mem, unsigned long size)
241{
242 unsigned long adr;
243
244 if (!mem)
245 return;
246
247 adr = (unsigned long) mem;
248 while ((long) size > 0) {
249 ClearPageReserved(vmalloc_to_page((void *)adr));
250 adr += PAGE_SIZE;
251 size -= PAGE_SIZE;
252 }
253 vfree(mem);
254}
255
256/**********************************************************************
257 *
258 * /proc interface
259 *
260 **********************************************************************/
261#ifdef CONFIG_PROC_FS
262static struct proc_dir_entry *cpia_proc_root=NULL;
263
264static int cpia_read_proc(char *page, char **start, off_t off,
265 int count, int *eof, void *data)
266{
267 char *out = page;
268 int len, tmp;
269 struct cam_data *cam = data;
270 char tmpstr[29];
271
272 /* IMPORTANT: This output MUST be kept under PAGE_SIZE
273 * or we need to get more sophisticated. */
274
275 out += sprintf(out, "read-only\n-----------------------\n");
276 out += sprintf(out, "V4L Driver version: %d.%d.%d\n",
277 CPIA_MAJ_VER, CPIA_MIN_VER, CPIA_PATCH_VER);
278 out += sprintf(out, "CPIA Version: %d.%02d (%d.%d)\n",
279 cam->params.version.firmwareVersion,
280 cam->params.version.firmwareRevision,
281 cam->params.version.vcVersion,
282 cam->params.version.vcRevision);
283 out += sprintf(out, "CPIA PnP-ID: %04x:%04x:%04x\n",
284 cam->params.pnpID.vendor, cam->params.pnpID.product,
285 cam->params.pnpID.deviceRevision);
286 out += sprintf(out, "VP-Version: %d.%d %04x\n",
287 cam->params.vpVersion.vpVersion,
288 cam->params.vpVersion.vpRevision,
289 cam->params.vpVersion.cameraHeadID);
290
291 out += sprintf(out, "system_state: %#04x\n",
292 cam->params.status.systemState);
293 out += sprintf(out, "grab_state: %#04x\n",
294 cam->params.status.grabState);
295 out += sprintf(out, "stream_state: %#04x\n",
296 cam->params.status.streamState);
297 out += sprintf(out, "fatal_error: %#04x\n",
298 cam->params.status.fatalError);
299 out += sprintf(out, "cmd_error: %#04x\n",
300 cam->params.status.cmdError);
301 out += sprintf(out, "debug_flags: %#04x\n",
302 cam->params.status.debugFlags);
303 out += sprintf(out, "vp_status: %#04x\n",
304 cam->params.status.vpStatus);
305 out += sprintf(out, "error_code: %#04x\n",
306 cam->params.status.errorCode);
307 /* QX3 specific entries */
308 if (cam->params.qx3.qx3_detected) {
309 out += sprintf(out, "button: %4d\n",
310 cam->params.qx3.button);
311 out += sprintf(out, "cradled: %4d\n",
312 cam->params.qx3.cradled);
313 }
314 out += sprintf(out, "video_size: %s\n",
315 cam->params.format.videoSize == VIDEOSIZE_CIF ?
316 "CIF " : "QCIF");
317 out += sprintf(out, "roi: (%3d, %3d) to (%3d, %3d)\n",
318 cam->params.roi.colStart*8,
319 cam->params.roi.rowStart*4,
320 cam->params.roi.colEnd*8,
321 cam->params.roi.rowEnd*4);
322 out += sprintf(out, "actual_fps: %3d\n", cam->fps);
323 out += sprintf(out, "transfer_rate: %4dkB/s\n",
324 cam->transfer_rate);
325
326 out += sprintf(out, "\nread-write\n");
327 out += sprintf(out, "----------------------- current min"
328 " max default comment\n");
329 out += sprintf(out, "brightness: %8d %8d %8d %8d\n",
330 cam->params.colourParams.brightness, 0, 100, 50);
331 if (cam->params.version.firmwareVersion == 1 &&
332 cam->params.version.firmwareRevision == 2)
333 /* 1-02 firmware limits contrast to 80 */
334 tmp = 80;
335 else
336 tmp = 96;
337
338 out += sprintf(out, "contrast: %8d %8d %8d %8d"
339 " steps of 8\n",
340 cam->params.colourParams.contrast, 0, tmp, 48);
341 out += sprintf(out, "saturation: %8d %8d %8d %8d\n",
342 cam->params.colourParams.saturation, 0, 100, 50);
343 tmp = (25000+5000*cam->params.sensorFps.baserate)/
344 (1<<cam->params.sensorFps.divisor);
345 out += sprintf(out, "sensor_fps: %4d.%03d %8d %8d %8d\n",
346 tmp/1000, tmp%1000, 3, 30, 15);
347 out += sprintf(out, "stream_start_line: %8d %8d %8d %8d\n",
348 2*cam->params.streamStartLine, 0,
349 cam->params.format.videoSize == VIDEOSIZE_CIF ? 288:144,
350 cam->params.format.videoSize == VIDEOSIZE_CIF ? 240:120);
351 out += sprintf(out, "sub_sample: %8s %8s %8s %8s\n",
352 cam->params.format.subSample == SUBSAMPLE_420 ?
353 "420" : "422", "420", "422", "422");
354 out += sprintf(out, "yuv_order: %8s %8s %8s %8s\n",
355 cam->params.format.yuvOrder == YUVORDER_YUYV ?
356 "YUYV" : "UYVY", "YUYV" , "UYVY", "YUYV");
357 out += sprintf(out, "ecp_timing: %8s %8s %8s %8s\n",
358 cam->params.ecpTiming ? "slow" : "normal", "slow",
359 "normal", "normal");
360
361 if (cam->params.colourBalance.balanceMode == 2) {
362 sprintf(tmpstr, "auto");
363 } else {
364 sprintf(tmpstr, "manual");
365 }
366 out += sprintf(out, "color_balance_mode: %8s %8s %8s"
367 " %8s\n", tmpstr, "manual", "auto", "auto");
368 out += sprintf(out, "red_gain: %8d %8d %8d %8d\n",
369 cam->params.colourBalance.redGain, 0, 212, 32);
370 out += sprintf(out, "green_gain: %8d %8d %8d %8d\n",
371 cam->params.colourBalance.greenGain, 0, 212, 6);
372 out += sprintf(out, "blue_gain: %8d %8d %8d %8d\n",
373 cam->params.colourBalance.blueGain, 0, 212, 92);
374
375 if (cam->params.version.firmwareVersion == 1 &&
376 cam->params.version.firmwareRevision == 2)
377 /* 1-02 firmware limits gain to 2 */
378 sprintf(tmpstr, "%8d %8d %8d", 1, 2, 2);
379 else
380 sprintf(tmpstr, "%8d %8d %8d", 1, 8, 2);
381
382 if (cam->params.exposure.gainMode == 0)
383 out += sprintf(out, "max_gain: unknown %28s"
384 " powers of 2\n", tmpstr);
385 else
386 out += sprintf(out, "max_gain: %8d %28s"
387 " 1,2,4 or 8 \n",
388 1<<(cam->params.exposure.gainMode-1), tmpstr);
389
390 switch(cam->params.exposure.expMode) {
391 case 1:
392 case 3:
393 sprintf(tmpstr, "manual");
394 break;
395 case 2:
396 sprintf(tmpstr, "auto");
397 break;
398 default:
399 sprintf(tmpstr, "unknown");
400 break;
401 }
402 out += sprintf(out, "exposure_mode: %8s %8s %8s"
403 " %8s\n", tmpstr, "manual", "auto", "auto");
404 out += sprintf(out, "centre_weight: %8s %8s %8s %8s\n",
405 (2-cam->params.exposure.centreWeight) ? "on" : "off",
406 "off", "on", "on");
407 out += sprintf(out, "gain: %8d %8d max_gain %8d 1,2,4,8 possible\n",
408 1<<cam->params.exposure.gain, 1, 1);
409 if (cam->params.version.firmwareVersion == 1 &&
410 cam->params.version.firmwareRevision == 2)
411 /* 1-02 firmware limits fineExp/2 to 127 */
412 tmp = 254;
413 else
414 tmp = 510;
415
416 out += sprintf(out, "fine_exp: %8d %8d %8d %8d\n",
417 cam->params.exposure.fineExp*2, 0, tmp, 0);
418 if (cam->params.version.firmwareVersion == 1 &&
419 cam->params.version.firmwareRevision == 2)
420 /* 1-02 firmware limits coarseExpHi to 0 */
421 tmp = MAX_EXP_102;
422 else
423 tmp = MAX_EXP;
424
425 out += sprintf(out, "coarse_exp: %8d %8d %8d"
426 " %8d\n", cam->params.exposure.coarseExpLo+
427 256*cam->params.exposure.coarseExpHi, 0, tmp, 185);
428 out += sprintf(out, "red_comp: %8d %8d %8d %8d\n",
429 cam->params.exposure.redComp, COMP_RED, 255, COMP_RED);
430 out += sprintf(out, "green1_comp: %8d %8d %8d %8d\n",
431 cam->params.exposure.green1Comp, COMP_GREEN1, 255,
432 COMP_GREEN1);
433 out += sprintf(out, "green2_comp: %8d %8d %8d %8d\n",
434 cam->params.exposure.green2Comp, COMP_GREEN2, 255,
435 COMP_GREEN2);
436 out += sprintf(out, "blue_comp: %8d %8d %8d %8d\n",
437 cam->params.exposure.blueComp, COMP_BLUE, 255, COMP_BLUE);
438
439 out += sprintf(out, "apcor_gain1: %#8x %#8x %#8x %#8x\n",
440 cam->params.apcor.gain1, 0, 0xff, 0x1c);
441 out += sprintf(out, "apcor_gain2: %#8x %#8x %#8x %#8x\n",
442 cam->params.apcor.gain2, 0, 0xff, 0x1a);
443 out += sprintf(out, "apcor_gain4: %#8x %#8x %#8x %#8x\n",
444 cam->params.apcor.gain4, 0, 0xff, 0x2d);
445 out += sprintf(out, "apcor_gain8: %#8x %#8x %#8x %#8x\n",
446 cam->params.apcor.gain8, 0, 0xff, 0x2a);
447 out += sprintf(out, "vl_offset_gain1: %8d %8d %8d %8d\n",
448 cam->params.vlOffset.gain1, 0, 255, 24);
449 out += sprintf(out, "vl_offset_gain2: %8d %8d %8d %8d\n",
450 cam->params.vlOffset.gain2, 0, 255, 28);
451 out += sprintf(out, "vl_offset_gain4: %8d %8d %8d %8d\n",
452 cam->params.vlOffset.gain4, 0, 255, 30);
453 out += sprintf(out, "vl_offset_gain8: %8d %8d %8d %8d\n",
454 cam->params.vlOffset.gain8, 0, 255, 30);
455 out += sprintf(out, "flicker_control: %8s %8s %8s %8s\n",
456 cam->params.flickerControl.flickerMode ? "on" : "off",
457 "off", "on", "off");
458 out += sprintf(out, "mains_frequency: %8d %8d %8d %8d"
459 " only 50/60\n",
460 cam->mainsFreq ? 60 : 50, 50, 60, 50);
461 if(cam->params.flickerControl.allowableOverExposure < 0)
462 out += sprintf(out, "allowable_overexposure: %4dauto auto %8d auto\n",
463 -cam->params.flickerControl.allowableOverExposure,
464 255);
465 else
466 out += sprintf(out, "allowable_overexposure: %8d auto %8d auto\n",
467 cam->params.flickerControl.allowableOverExposure,
468 255);
469 out += sprintf(out, "compression_mode: ");
470 switch(cam->params.compression.mode) {
471 case CPIA_COMPRESSION_NONE:
472 out += sprintf(out, "%8s", "none");
473 break;
474 case CPIA_COMPRESSION_AUTO:
475 out += sprintf(out, "%8s", "auto");
476 break;
477 case CPIA_COMPRESSION_MANUAL:
478 out += sprintf(out, "%8s", "manual");
479 break;
480 default:
481 out += sprintf(out, "%8s", "unknown");
482 break;
483 }
484 out += sprintf(out, " none,auto,manual auto\n");
485 out += sprintf(out, "decimation_enable: %8s %8s %8s %8s\n",
486 cam->params.compression.decimation ==
487 DECIMATION_ENAB ? "on":"off", "off", "on",
488 "off");
489 out += sprintf(out, "compression_target: %9s %9s %9s %9s\n",
490 cam->params.compressionTarget.frTargeting ==
491 CPIA_COMPRESSION_TARGET_FRAMERATE ?
492 "framerate":"quality",
493 "framerate", "quality", "quality");
494 out += sprintf(out, "target_framerate: %8d %8d %8d %8d\n",
495 cam->params.compressionTarget.targetFR, 1, 30, 15);
496 out += sprintf(out, "target_quality: %8d %8d %8d %8d\n",
497 cam->params.compressionTarget.targetQ, 1, 64, 5);
498 out += sprintf(out, "y_threshold: %8d %8d %8d %8d\n",
499 cam->params.yuvThreshold.yThreshold, 0, 31, 6);
500 out += sprintf(out, "uv_threshold: %8d %8d %8d %8d\n",
501 cam->params.yuvThreshold.uvThreshold, 0, 31, 6);
502 out += sprintf(out, "hysteresis: %8d %8d %8d %8d\n",
503 cam->params.compressionParams.hysteresis, 0, 255, 3);
504 out += sprintf(out, "threshold_max: %8d %8d %8d %8d\n",
505 cam->params.compressionParams.threshMax, 0, 255, 11);
506 out += sprintf(out, "small_step: %8d %8d %8d %8d\n",
507 cam->params.compressionParams.smallStep, 0, 255, 1);
508 out += sprintf(out, "large_step: %8d %8d %8d %8d\n",
509 cam->params.compressionParams.largeStep, 0, 255, 3);
510 out += sprintf(out, "decimation_hysteresis: %8d %8d %8d %8d\n",
511 cam->params.compressionParams.decimationHysteresis,
512 0, 255, 2);
513 out += sprintf(out, "fr_diff_step_thresh: %8d %8d %8d %8d\n",
514 cam->params.compressionParams.frDiffStepThresh,
515 0, 255, 5);
516 out += sprintf(out, "q_diff_step_thresh: %8d %8d %8d %8d\n",
517 cam->params.compressionParams.qDiffStepThresh,
518 0, 255, 3);
519 out += sprintf(out, "decimation_thresh_mod: %8d %8d %8d %8d\n",
520 cam->params.compressionParams.decimationThreshMod,
521 0, 255, 2);
522 /* QX3 specific entries */
523 if (cam->params.qx3.qx3_detected) {
524 out += sprintf(out, "toplight: %8s %8s %8s %8s\n",
525 cam->params.qx3.toplight ? "on" : "off",
526 "off", "on", "off");
527 out += sprintf(out, "bottomlight: %8s %8s %8s %8s\n",
528 cam->params.qx3.bottomlight ? "on" : "off",
529 "off", "on", "off");
530 }
531
532 len = out - page;
533 len -= off;
534 if (len < count) {
535 *eof = 1;
536 if (len <= 0) return 0;
537 } else
538 len = count;
539
540 *start = page + off;
541 return len;
542}
543
544
545static int match(char *checkstr, char **buffer, unsigned long *count,
546 int *find_colon, int *err)
547{
548 int ret, colon_found = 1;
549 int len = strlen(checkstr);
550 ret = (len <= *count && strncmp(*buffer, checkstr, len) == 0);
551 if (ret) {
552 *buffer += len;
553 *count -= len;
554 if (*find_colon) {
555 colon_found = 0;
556 while (*count && (**buffer == ' ' || **buffer == '\t' ||
557 (!colon_found && **buffer == ':'))) {
558 if (**buffer == ':')
559 colon_found = 1;
560 --*count;
561 ++*buffer;
562 }
563 if (!*count || !colon_found)
564 *err = -EINVAL;
565 *find_colon = 0;
566 }
567 }
568 return ret;
569}
570
571static unsigned long int value(char **buffer, unsigned long *count, int *err)
572{
573 char *p;
574 unsigned long int ret;
575 ret = simple_strtoul(*buffer, &p, 0);
576 if (p == *buffer)
577 *err = -EINVAL;
578 else {
579 *count -= p - *buffer;
580 *buffer = p;
581 }
582 return ret;
583}
584
585static int cpia_write_proc(struct file *file, const char __user *buf,
586 unsigned long count, void *data)
587{
588 struct cam_data *cam = data;
589 struct cam_params new_params;
590 char *page, *buffer;
591 int retval, find_colon;
592 int size = count;
593 unsigned long val = 0;
594 u32 command_flags = 0;
595 u8 new_mains;
596
597 /*
598 * This code to copy from buf to page is shamelessly copied
599 * from the comx driver
600 */
601 if (count > PAGE_SIZE) {
602 printk(KERN_ERR "count is %lu > %d!!!\n", count, (int)PAGE_SIZE);
603 return -ENOSPC;
604 }
605
606 if (!(page = (char *)__get_free_page(GFP_KERNEL))) return -ENOMEM;
607
608 if(copy_from_user(page, buf, count))
609 {
610 retval = -EFAULT;
611 goto out;
612 }
613
614 if (page[count-1] == '\n')
615 page[count-1] = '\0';
616 else if (count < PAGE_SIZE)
617 page[count] = '\0';
618 else if (page[count]) {
619 retval = -EINVAL;
620 goto out;
621 }
622
623 buffer = page;
624
625 if (down_interruptible(&cam->param_lock))
626 return -ERESTARTSYS;
627
628 /*
629 * Skip over leading whitespace
630 */
631 while (count && isspace(*buffer)) {
632 --count;
633 ++buffer;
634 }
635
636 memcpy(&new_params, &cam->params, sizeof(struct cam_params));
637 new_mains = cam->mainsFreq;
638
639#define MATCH(x) (match(x, &buffer, &count, &find_colon, &retval))
640#define VALUE (value(&buffer,&count, &retval))
641#define FIRMWARE_VERSION(x,y) (new_params.version.firmwareVersion == (x) && \
642 new_params.version.firmwareRevision == (y))
643
644 retval = 0;
645 while (count && !retval) {
646 find_colon = 1;
647 if (MATCH("brightness")) {
648 if (!retval)
649 val = VALUE;
650
651 if (!retval) {
652 if (val <= 100)
653 new_params.colourParams.brightness = val;
654 else
655 retval = -EINVAL;
656 }
657 command_flags |= COMMAND_SETCOLOURPARAMS;
658 if(new_params.flickerControl.allowableOverExposure < 0)
659 new_params.flickerControl.allowableOverExposure =
660 -find_over_exposure(new_params.colourParams.brightness);
661 if(new_params.flickerControl.flickerMode != 0)
662 command_flags |= COMMAND_SETFLICKERCTRL;
663
664 } else if (MATCH("contrast")) {
665 if (!retval)
666 val = VALUE;
667
668 if (!retval) {
669 if (val <= 100) {
670 /* contrast is in steps of 8, so round*/
671 val = ((val + 3) / 8) * 8;
672 /* 1-02 firmware limits contrast to 80*/
673 if (FIRMWARE_VERSION(1,2) && val > 80)
674 val = 80;
675
676 new_params.colourParams.contrast = val;
677 } else
678 retval = -EINVAL;
679 }
680 command_flags |= COMMAND_SETCOLOURPARAMS;
681 } else if (MATCH("saturation")) {
682 if (!retval)
683 val = VALUE;
684
685 if (!retval) {
686 if (val <= 100)
687 new_params.colourParams.saturation = val;
688 else
689 retval = -EINVAL;
690 }
691 command_flags |= COMMAND_SETCOLOURPARAMS;
692 } else if (MATCH("sensor_fps")) {
693 if (!retval)
694 val = VALUE;
695
696 if (!retval) {
697 /* find values so that sensorFPS is minimized,
698 * but >= val */
699 if (val > 30)
700 retval = -EINVAL;
701 else if (val > 25) {
702 new_params.sensorFps.divisor = 0;
703 new_params.sensorFps.baserate = 1;
704 } else if (val > 15) {
705 new_params.sensorFps.divisor = 0;
706 new_params.sensorFps.baserate = 0;
707 } else if (val > 12) {
708 new_params.sensorFps.divisor = 1;
709 new_params.sensorFps.baserate = 1;
710 } else if (val > 7) {
711 new_params.sensorFps.divisor = 1;
712 new_params.sensorFps.baserate = 0;
713 } else if (val > 6) {
714 new_params.sensorFps.divisor = 2;
715 new_params.sensorFps.baserate = 1;
716 } else if (val > 3) {
717 new_params.sensorFps.divisor = 2;
718 new_params.sensorFps.baserate = 0;
719 } else {
720 new_params.sensorFps.divisor = 3;
721 /* Either base rate would work here */
722 new_params.sensorFps.baserate = 1;
723 }
724 new_params.flickerControl.coarseJump =
725 flicker_jumps[new_mains]
726 [new_params.sensorFps.baserate]
727 [new_params.sensorFps.divisor];
728 if (new_params.flickerControl.flickerMode)
729 command_flags |= COMMAND_SETFLICKERCTRL;
730 }
731 command_flags |= COMMAND_SETSENSORFPS;
732 cam->exposure_status = EXPOSURE_NORMAL;
733 } else if (MATCH("stream_start_line")) {
734 if (!retval)
735 val = VALUE;
736
737 if (!retval) {
738 int max_line = 288;
739
740 if (new_params.format.videoSize == VIDEOSIZE_QCIF)
741 max_line = 144;
742 if (val <= max_line)
743 new_params.streamStartLine = val/2;
744 else
745 retval = -EINVAL;
746 }
747 } else if (MATCH("sub_sample")) {
748 if (!retval && MATCH("420"))
749 new_params.format.subSample = SUBSAMPLE_420;
750 else if (!retval && MATCH("422"))
751 new_params.format.subSample = SUBSAMPLE_422;
752 else
753 retval = -EINVAL;
754
755 command_flags |= COMMAND_SETFORMAT;
756 } else if (MATCH("yuv_order")) {
757 if (!retval && MATCH("YUYV"))
758 new_params.format.yuvOrder = YUVORDER_YUYV;
759 else if (!retval && MATCH("UYVY"))
760 new_params.format.yuvOrder = YUVORDER_UYVY;
761 else
762 retval = -EINVAL;
763
764 command_flags |= COMMAND_SETFORMAT;
765 } else if (MATCH("ecp_timing")) {
766 if (!retval && MATCH("normal"))
767 new_params.ecpTiming = 0;
768 else if (!retval && MATCH("slow"))
769 new_params.ecpTiming = 1;
770 else
771 retval = -EINVAL;
772
773 command_flags |= COMMAND_SETECPTIMING;
774 } else if (MATCH("color_balance_mode")) {
775 if (!retval && MATCH("manual"))
776 new_params.colourBalance.balanceMode = 3;
777 else if (!retval && MATCH("auto"))
778 new_params.colourBalance.balanceMode = 2;
779 else
780 retval = -EINVAL;
781
782 command_flags |= COMMAND_SETCOLOURBALANCE;
783 } else if (MATCH("red_gain")) {
784 if (!retval)
785 val = VALUE;
786
787 if (!retval) {
788 if (val <= 212) {
789 new_params.colourBalance.redGain = val;
790 new_params.colourBalance.balanceMode = 1;
791 } else
792 retval = -EINVAL;
793 }
794 command_flags |= COMMAND_SETCOLOURBALANCE;
795 } else if (MATCH("green_gain")) {
796 if (!retval)
797 val = VALUE;
798
799 if (!retval) {
800 if (val <= 212) {
801 new_params.colourBalance.greenGain = val;
802 new_params.colourBalance.balanceMode = 1;
803 } else
804 retval = -EINVAL;
805 }
806 command_flags |= COMMAND_SETCOLOURBALANCE;
807 } else if (MATCH("blue_gain")) {
808 if (!retval)
809 val = VALUE;
810
811 if (!retval) {
812 if (val <= 212) {
813 new_params.colourBalance.blueGain = val;
814 new_params.colourBalance.balanceMode = 1;
815 } else
816 retval = -EINVAL;
817 }
818 command_flags |= COMMAND_SETCOLOURBALANCE;
819 } else if (MATCH("max_gain")) {
820 if (!retval)
821 val = VALUE;
822
823 if (!retval) {
824 /* 1-02 firmware limits gain to 2 */
825 if (FIRMWARE_VERSION(1,2) && val > 2)
826 val = 2;
827 switch(val) {
828 case 1:
829 new_params.exposure.gainMode = 1;
830 break;
831 case 2:
832 new_params.exposure.gainMode = 2;
833 break;
834 case 4:
835 new_params.exposure.gainMode = 3;
836 break;
837 case 8:
838 new_params.exposure.gainMode = 4;
839 break;
840 default:
841 retval = -EINVAL;
842 break;
843 }
844 }
845 command_flags |= COMMAND_SETEXPOSURE;
846 } else if (MATCH("exposure_mode")) {
847 if (!retval && MATCH("auto"))
848 new_params.exposure.expMode = 2;
849 else if (!retval && MATCH("manual")) {
850 if (new_params.exposure.expMode == 2)
851 new_params.exposure.expMode = 3;
852 if(new_params.flickerControl.flickerMode != 0)
853 command_flags |= COMMAND_SETFLICKERCTRL;
854 new_params.flickerControl.flickerMode = 0;
855 } else
856 retval = -EINVAL;
857
858 command_flags |= COMMAND_SETEXPOSURE;
859 } else if (MATCH("centre_weight")) {
860 if (!retval && MATCH("on"))
861 new_params.exposure.centreWeight = 1;
862 else if (!retval && MATCH("off"))
863 new_params.exposure.centreWeight = 2;
864 else
865 retval = -EINVAL;
866
867 command_flags |= COMMAND_SETEXPOSURE;
868 } else if (MATCH("gain")) {
869 if (!retval)
870 val = VALUE;
871
872 if (!retval) {
873 switch(val) {
874 case 1:
875 new_params.exposure.gain = 0;
876 break;
877 case 2:
878 new_params.exposure.gain = 1;
879 break;
880 case 4:
881 new_params.exposure.gain = 2;
882 break;
883 case 8:
884 new_params.exposure.gain = 3;
885 break;
886 default:
887 retval = -EINVAL;
888 break;
889 }
890 new_params.exposure.expMode = 1;
891 if(new_params.flickerControl.flickerMode != 0)
892 command_flags |= COMMAND_SETFLICKERCTRL;
893 new_params.flickerControl.flickerMode = 0;
894 command_flags |= COMMAND_SETEXPOSURE;
895 if (new_params.exposure.gain >
896 new_params.exposure.gainMode-1)
897 retval = -EINVAL;
898 }
899 } else if (MATCH("fine_exp")) {
900 if (!retval)
901 val = VALUE/2;
902
903 if (!retval) {
904 if (val < 256) {
905 /* 1-02 firmware limits fineExp/2 to 127*/
906 if (FIRMWARE_VERSION(1,2) && val > 127)
907 val = 127;
908 new_params.exposure.fineExp = val;
909 new_params.exposure.expMode = 1;
910 command_flags |= COMMAND_SETEXPOSURE;
911 if(new_params.flickerControl.flickerMode != 0)
912 command_flags |= COMMAND_SETFLICKERCTRL;
913 new_params.flickerControl.flickerMode = 0;
914 command_flags |= COMMAND_SETFLICKERCTRL;
915 } else
916 retval = -EINVAL;
917 }
918 } else if (MATCH("coarse_exp")) {
919 if (!retval)
920 val = VALUE;
921
922 if (!retval) {
923 if (val <= MAX_EXP) {
924 if (FIRMWARE_VERSION(1,2) &&
925 val > MAX_EXP_102)
926 val = MAX_EXP_102;
927 new_params.exposure.coarseExpLo =
928 val & 0xff;
929 new_params.exposure.coarseExpHi =
930 val >> 8;
931 new_params.exposure.expMode = 1;
932 command_flags |= COMMAND_SETEXPOSURE;
933 if(new_params.flickerControl.flickerMode != 0)
934 command_flags |= COMMAND_SETFLICKERCTRL;
935 new_params.flickerControl.flickerMode = 0;
936 command_flags |= COMMAND_SETFLICKERCTRL;
937 } else
938 retval = -EINVAL;
939 }
940 } else if (MATCH("red_comp")) {
941 if (!retval)
942 val = VALUE;
943
944 if (!retval) {
945 if (val >= COMP_RED && val <= 255) {
946 new_params.exposure.redComp = val;
947 new_params.exposure.compMode = 1;
948 command_flags |= COMMAND_SETEXPOSURE;
949 } else
950 retval = -EINVAL;
951 }
952 } else if (MATCH("green1_comp")) {
953 if (!retval)
954 val = VALUE;
955
956 if (!retval) {
957 if (val >= COMP_GREEN1 && val <= 255) {
958 new_params.exposure.green1Comp = val;
959 new_params.exposure.compMode = 1;
960 command_flags |= COMMAND_SETEXPOSURE;
961 } else
962 retval = -EINVAL;
963 }
964 } else if (MATCH("green2_comp")) {
965 if (!retval)
966 val = VALUE;
967
968 if (!retval) {
969 if (val >= COMP_GREEN2 && val <= 255) {
970 new_params.exposure.green2Comp = val;
971 new_params.exposure.compMode = 1;
972 command_flags |= COMMAND_SETEXPOSURE;
973 } else
974 retval = -EINVAL;
975 }
976 } else if (MATCH("blue_comp")) {
977 if (!retval)
978 val = VALUE;
979
980 if (!retval) {
981 if (val >= COMP_BLUE && val <= 255) {
982 new_params.exposure.blueComp = val;
983 new_params.exposure.compMode = 1;
984 command_flags |= COMMAND_SETEXPOSURE;
985 } else
986 retval = -EINVAL;
987 }
988 } else if (MATCH("apcor_gain1")) {
989 if (!retval)
990 val = VALUE;
991
992 if (!retval) {
993 command_flags |= COMMAND_SETAPCOR;
994 if (val <= 0xff)
995 new_params.apcor.gain1 = val;
996 else
997 retval = -EINVAL;
998 }
999 } else if (MATCH("apcor_gain2")) {
1000 if (!retval)
1001 val = VALUE;
1002
1003 if (!retval) {
1004 command_flags |= COMMAND_SETAPCOR;
1005 if (val <= 0xff)
1006 new_params.apcor.gain2 = val;
1007 else
1008 retval = -EINVAL;
1009 }
1010 } else if (MATCH("apcor_gain4")) {
1011 if (!retval)
1012 val = VALUE;
1013
1014 if (!retval) {
1015 command_flags |= COMMAND_SETAPCOR;
1016 if (val <= 0xff)
1017 new_params.apcor.gain4 = val;
1018 else
1019 retval = -EINVAL;
1020 }
1021 } else if (MATCH("apcor_gain8")) {
1022 if (!retval)
1023 val = VALUE;
1024
1025 if (!retval) {
1026 command_flags |= COMMAND_SETAPCOR;
1027 if (val <= 0xff)
1028 new_params.apcor.gain8 = val;
1029 else
1030 retval = -EINVAL;
1031 }
1032 } else if (MATCH("vl_offset_gain1")) {
1033 if (!retval)
1034 val = VALUE;
1035
1036 if (!retval) {
1037 if (val <= 0xff)
1038 new_params.vlOffset.gain1 = val;
1039 else
1040 retval = -EINVAL;
1041 }
1042 command_flags |= COMMAND_SETVLOFFSET;
1043 } else if (MATCH("vl_offset_gain2")) {
1044 if (!retval)
1045 val = VALUE;
1046
1047 if (!retval) {
1048 if (val <= 0xff)
1049 new_params.vlOffset.gain2 = val;
1050 else
1051 retval = -EINVAL;
1052 }
1053 command_flags |= COMMAND_SETVLOFFSET;
1054 } else if (MATCH("vl_offset_gain4")) {
1055 if (!retval)
1056 val = VALUE;
1057
1058 if (!retval) {
1059 if (val <= 0xff)
1060 new_params.vlOffset.gain4 = val;
1061 else
1062 retval = -EINVAL;
1063 }
1064 command_flags |= COMMAND_SETVLOFFSET;
1065 } else if (MATCH("vl_offset_gain8")) {
1066 if (!retval)
1067 val = VALUE;
1068
1069 if (!retval) {
1070 if (val <= 0xff)
1071 new_params.vlOffset.gain8 = val;
1072 else
1073 retval = -EINVAL;
1074 }
1075 command_flags |= COMMAND_SETVLOFFSET;
1076 } else if (MATCH("flicker_control")) {
1077 if (!retval && MATCH("on")) {
1078 set_flicker(&new_params, &command_flags, 1);
1079 } else if (!retval && MATCH("off")) {
1080 set_flicker(&new_params, &command_flags, 0);
1081 } else
1082 retval = -EINVAL;
1083
1084 command_flags |= COMMAND_SETFLICKERCTRL;
1085 } else if (MATCH("mains_frequency")) {
1086 if (!retval && MATCH("50")) {
1087 new_mains = 0;
1088 new_params.flickerControl.coarseJump =
1089 flicker_jumps[new_mains]
1090 [new_params.sensorFps.baserate]
1091 [new_params.sensorFps.divisor];
1092 if (new_params.flickerControl.flickerMode)
1093 command_flags |= COMMAND_SETFLICKERCTRL;
1094 } else if (!retval && MATCH("60")) {
1095 new_mains = 1;
1096 new_params.flickerControl.coarseJump =
1097 flicker_jumps[new_mains]
1098 [new_params.sensorFps.baserate]
1099 [new_params.sensorFps.divisor];
1100 if (new_params.flickerControl.flickerMode)
1101 command_flags |= COMMAND_SETFLICKERCTRL;
1102 } else
1103 retval = -EINVAL;
1104 } else if (MATCH("allowable_overexposure")) {
1105 if (!retval && MATCH("auto")) {
1106 new_params.flickerControl.allowableOverExposure =
1107 -find_over_exposure(new_params.colourParams.brightness);
1108 if(new_params.flickerControl.flickerMode != 0)
1109 command_flags |= COMMAND_SETFLICKERCTRL;
1110 } else {
1111 if (!retval)
1112 val = VALUE;
1113
1114 if (!retval) {
1115 if (val <= 0xff) {
1116 new_params.flickerControl.
1117 allowableOverExposure = val;
1118 if(new_params.flickerControl.flickerMode != 0)
1119 command_flags |= COMMAND_SETFLICKERCTRL;
1120 } else
1121 retval = -EINVAL;
1122 }
1123 }
1124 } else if (MATCH("compression_mode")) {
1125 if (!retval && MATCH("none"))
1126 new_params.compression.mode =
1127 CPIA_COMPRESSION_NONE;
1128 else if (!retval && MATCH("auto"))
1129 new_params.compression.mode =
1130 CPIA_COMPRESSION_AUTO;
1131 else if (!retval && MATCH("manual"))
1132 new_params.compression.mode =
1133 CPIA_COMPRESSION_MANUAL;
1134 else
1135 retval = -EINVAL;
1136
1137 command_flags |= COMMAND_SETCOMPRESSION;
1138 } else if (MATCH("decimation_enable")) {
1139 if (!retval && MATCH("off"))
1140 new_params.compression.decimation = 0;
1141 else if (!retval && MATCH("on"))
1142 new_params.compression.decimation = 1;
1143 else
1144 retval = -EINVAL;
1145
1146 command_flags |= COMMAND_SETCOMPRESSION;
1147 } else if (MATCH("compression_target")) {
1148 if (!retval && MATCH("quality"))
1149 new_params.compressionTarget.frTargeting =
1150 CPIA_COMPRESSION_TARGET_QUALITY;
1151 else if (!retval && MATCH("framerate"))
1152 new_params.compressionTarget.frTargeting =
1153 CPIA_COMPRESSION_TARGET_FRAMERATE;
1154 else
1155 retval = -EINVAL;
1156
1157 command_flags |= COMMAND_SETCOMPRESSIONTARGET;
1158 } else if (MATCH("target_framerate")) {
1159 if (!retval)
1160 val = VALUE;
1161
1162 if (!retval) {
1163 if(val > 0 && val <= 30)
1164 new_params.compressionTarget.targetFR = val;
1165 else
1166 retval = -EINVAL;
1167 }
1168 command_flags |= COMMAND_SETCOMPRESSIONTARGET;
1169 } else if (MATCH("target_quality")) {
1170 if (!retval)
1171 val = VALUE;
1172
1173 if (!retval) {
1174 if(val > 0 && val <= 64)
1175 new_params.compressionTarget.targetQ = val;
1176 else
1177 retval = -EINVAL;
1178 }
1179 command_flags |= COMMAND_SETCOMPRESSIONTARGET;
1180 } else if (MATCH("y_threshold")) {
1181 if (!retval)
1182 val = VALUE;
1183
1184 if (!retval) {
1185 if (val < 32)
1186 new_params.yuvThreshold.yThreshold = val;
1187 else
1188 retval = -EINVAL;
1189 }
1190 command_flags |= COMMAND_SETYUVTHRESH;
1191 } else if (MATCH("uv_threshold")) {
1192 if (!retval)
1193 val = VALUE;
1194
1195 if (!retval) {
1196 if (val < 32)
1197 new_params.yuvThreshold.uvThreshold = val;
1198 else
1199 retval = -EINVAL;
1200 }
1201 command_flags |= COMMAND_SETYUVTHRESH;
1202 } else if (MATCH("hysteresis")) {
1203 if (!retval)
1204 val = VALUE;
1205
1206 if (!retval) {
1207 if (val <= 0xff)
1208 new_params.compressionParams.hysteresis = val;
1209 else
1210 retval = -EINVAL;
1211 }
1212 command_flags |= COMMAND_SETCOMPRESSIONPARAMS;
1213 } else if (MATCH("threshold_max")) {
1214 if (!retval)
1215 val = VALUE;
1216
1217 if (!retval) {
1218 if (val <= 0xff)
1219 new_params.compressionParams.threshMax = val;
1220 else
1221 retval = -EINVAL;
1222 }
1223 command_flags |= COMMAND_SETCOMPRESSIONPARAMS;
1224 } else if (MATCH("small_step")) {
1225 if (!retval)
1226 val = VALUE;
1227
1228 if (!retval) {
1229 if (val <= 0xff)
1230 new_params.compressionParams.smallStep = val;
1231 else
1232 retval = -EINVAL;
1233 }
1234 command_flags |= COMMAND_SETCOMPRESSIONPARAMS;
1235 } else if (MATCH("large_step")) {
1236 if (!retval)
1237 val = VALUE;
1238
1239 if (!retval) {
1240 if (val <= 0xff)
1241 new_params.compressionParams.largeStep = val;
1242 else
1243 retval = -EINVAL;
1244 }
1245 command_flags |= COMMAND_SETCOMPRESSIONPARAMS;
1246 } else if (MATCH("decimation_hysteresis")) {
1247 if (!retval)
1248 val = VALUE;
1249
1250 if (!retval) {
1251 if (val <= 0xff)
1252 new_params.compressionParams.decimationHysteresis = val;
1253 else
1254 retval = -EINVAL;
1255 }
1256 command_flags |= COMMAND_SETCOMPRESSIONPARAMS;
1257 } else if (MATCH("fr_diff_step_thresh")) {
1258 if (!retval)
1259 val = VALUE;
1260
1261 if (!retval) {
1262 if (val <= 0xff)
1263 new_params.compressionParams.frDiffStepThresh = val;
1264 else
1265 retval = -EINVAL;
1266 }
1267 command_flags |= COMMAND_SETCOMPRESSIONPARAMS;
1268 } else if (MATCH("q_diff_step_thresh")) {
1269 if (!retval)
1270 val = VALUE;
1271
1272 if (!retval) {
1273 if (val <= 0xff)
1274 new_params.compressionParams.qDiffStepThresh = val;
1275 else
1276 retval = -EINVAL;
1277 }
1278 command_flags |= COMMAND_SETCOMPRESSIONPARAMS;
1279 } else if (MATCH("decimation_thresh_mod")) {
1280 if (!retval)
1281 val = VALUE;
1282
1283 if (!retval) {
1284 if (val <= 0xff)
1285 new_params.compressionParams.decimationThreshMod = val;
1286 else
1287 retval = -EINVAL;
1288 }
1289 command_flags |= COMMAND_SETCOMPRESSIONPARAMS;
1290 } else if (MATCH("toplight")) {
1291 if (!retval && MATCH("on"))
1292 new_params.qx3.toplight = 1;
1293 else if (!retval && MATCH("off"))
1294 new_params.qx3.toplight = 0;
1295 else
1296 retval = -EINVAL;
1297 command_flags |= COMMAND_SETLIGHTS;
1298 } else if (MATCH("bottomlight")) {
1299 if (!retval && MATCH("on"))
1300 new_params.qx3.bottomlight = 1;
1301 else if (!retval && MATCH("off"))
1302 new_params.qx3.bottomlight = 0;
1303 else
1304 retval = -EINVAL;
1305 command_flags |= COMMAND_SETLIGHTS;
1306 } else {
1307 DBG("No match found\n");
1308 retval = -EINVAL;
1309 }
1310
1311 if (!retval) {
1312 while (count && isspace(*buffer) && *buffer != '\n') {
1313 --count;
1314 ++buffer;
1315 }
1316 if (count) {
1317 if (*buffer == '\0' && count != 1)
1318 retval = -EINVAL;
1319 else if (*buffer != '\n' && *buffer != ';' &&
1320 *buffer != '\0')
1321 retval = -EINVAL;
1322 else {
1323 --count;
1324 ++buffer;
1325 }
1326 }
1327 }
1328 }
1329#undef MATCH
1330#undef VALUE
1331#undef FIRMWARE_VERSION
1332 if (!retval) {
1333 if (command_flags & COMMAND_SETCOLOURPARAMS) {
1334 /* Adjust cam->vp to reflect these changes */
1335 cam->vp.brightness =
1336 new_params.colourParams.brightness*65535/100;
1337 cam->vp.contrast =
1338 new_params.colourParams.contrast*65535/100;
1339 cam->vp.colour =
1340 new_params.colourParams.saturation*65535/100;
1341 }
1342 if((command_flags & COMMAND_SETEXPOSURE) &&
1343 new_params.exposure.expMode == 2)
1344 cam->exposure_status = EXPOSURE_NORMAL;
1345
1346 memcpy(&cam->params, &new_params, sizeof(struct cam_params));
1347 cam->mainsFreq = new_mains;
1348 cam->cmd_queue |= command_flags;
1349 retval = size;
1350 } else
1351 DBG("error: %d\n", retval);
1352
1353 up(&cam->param_lock);
1354
1355out:
1356 free_page((unsigned long)page);
1357 return retval;
1358}
1359
1360static void create_proc_cpia_cam(struct cam_data *cam)
1361{
1362 char name[7];
1363 struct proc_dir_entry *ent;
1364
1365 if (!cpia_proc_root || !cam)
1366 return;
1367
1368 sprintf(name, "video%d", cam->vdev.minor);
1369
1370 ent = create_proc_entry(name, S_IFREG|S_IRUGO|S_IWUSR, cpia_proc_root);
1371 if (!ent)
1372 return;
1373
1374 ent->data = cam;
1375 ent->read_proc = cpia_read_proc;
1376 ent->write_proc = cpia_write_proc;
1377 /*
1378 size of the proc entry is 3736 bytes for the standard webcam;
1379 the extra features of the QX3 microscope add 189 bytes.
1380 (we have not yet probed the camera to see which type it is).
1381 */
1382 ent->size = 3736 + 189;
1383 cam->proc_entry = ent;
1384}
1385
1386static void destroy_proc_cpia_cam(struct cam_data *cam)
1387{
1388 char name[7];
1389
1390 if (!cam || !cam->proc_entry)
1391 return;
1392
1393 sprintf(name, "video%d", cam->vdev.minor);
1394 remove_proc_entry(name, cpia_proc_root);
1395 cam->proc_entry = NULL;
1396}
1397
1398static void proc_cpia_create(void)
1399{
1400 cpia_proc_root = create_proc_entry("cpia", S_IFDIR, NULL);
1401
1402 if (cpia_proc_root)
1403 cpia_proc_root->owner = THIS_MODULE;
1404 else
1405 LOG("Unable to initialise /proc/cpia\n");
1406}
1407
1408static void __exit proc_cpia_destroy(void)
1409{
1410 remove_proc_entry("cpia", NULL);
1411}
1412#endif /* CONFIG_PROC_FS */
1413
1414/* ----------------------- debug functions ---------------------- */
1415
1416#define printstatus(cam) \
1417 DBG("%02x %02x %02x %02x %02x %02x %02x %02x\n",\
1418 cam->params.status.systemState, cam->params.status.grabState, \
1419 cam->params.status.streamState, cam->params.status.fatalError, \
1420 cam->params.status.cmdError, cam->params.status.debugFlags, \
1421 cam->params.status.vpStatus, cam->params.status.errorCode);
1422
1423/* ----------------------- v4l helpers -------------------------- */
1424
1425/* supported frame palettes and depths */
1426static inline int valid_mode(u16 palette, u16 depth)
1427{
1428 if ((palette == VIDEO_PALETTE_YUV422 && depth == 16) ||
1429 (palette == VIDEO_PALETTE_YUYV && depth == 16))
1430 return 1;
1431
1432 if (colorspace_conv)
1433 return (palette == VIDEO_PALETTE_GREY && depth == 8) ||
1434 (palette == VIDEO_PALETTE_RGB555 && depth == 16) ||
1435 (palette == VIDEO_PALETTE_RGB565 && depth == 16) ||
1436 (palette == VIDEO_PALETTE_RGB24 && depth == 24) ||
1437 (palette == VIDEO_PALETTE_RGB32 && depth == 32) ||
1438 (palette == VIDEO_PALETTE_UYVY && depth == 16);
1439
1440 return 0;
1441}
1442
1443static int match_videosize( int width, int height )
1444{
1445 /* return the best match, where 'best' is as always
1446 * the largest that is not bigger than what is requested. */
1447 if (width>=352 && height>=288)
1448 return VIDEOSIZE_352_288; /* CIF */
1449
1450 if (width>=320 && height>=240)
1451 return VIDEOSIZE_320_240; /* SIF */
1452
1453 if (width>=288 && height>=216)
1454 return VIDEOSIZE_288_216;
1455
1456 if (width>=256 && height>=192)
1457 return VIDEOSIZE_256_192;
1458
1459 if (width>=224 && height>=168)
1460 return VIDEOSIZE_224_168;
1461
1462 if (width>=192 && height>=144)
1463 return VIDEOSIZE_192_144;
1464
1465 if (width>=176 && height>=144)
1466 return VIDEOSIZE_176_144; /* QCIF */
1467
1468 if (width>=160 && height>=120)
1469 return VIDEOSIZE_160_120; /* QSIF */
1470
1471 if (width>=128 && height>=96)
1472 return VIDEOSIZE_128_96;
1473
1474 if (width>=88 && height>=72)
1475 return VIDEOSIZE_88_72;
1476
1477 if (width>=64 && height>=48)
1478 return VIDEOSIZE_64_48;
1479
1480 if (width>=48 && height>=48)
1481 return VIDEOSIZE_48_48;
1482
1483 return -1;
1484}
1485
1486/* these are the capture sizes we support */
1487static void set_vw_size(struct cam_data *cam)
1488{
1489 /* the col/row/start/end values are the result of simple math */
1490 /* study the SetROI-command in cpia developers guide p 2-22 */
1491 /* streamStartLine is set to the recommended value in the cpia */
1492 /* developers guide p 3-37 */
1493 switch(cam->video_size) {
1494 case VIDEOSIZE_CIF:
1495 cam->vw.width = 352;
1496 cam->vw.height = 288;
1497 cam->params.format.videoSize=VIDEOSIZE_CIF;
1498 cam->params.roi.colStart=0;
1499 cam->params.roi.rowStart=0;
1500 cam->params.streamStartLine = 120;
1501 break;
1502 case VIDEOSIZE_SIF:
1503 cam->vw.width = 320;
1504 cam->vw.height = 240;
1505 cam->params.format.videoSize=VIDEOSIZE_CIF;
1506 cam->params.roi.colStart=2;
1507 cam->params.roi.rowStart=6;
1508 cam->params.streamStartLine = 120;
1509 break;
1510 case VIDEOSIZE_288_216:
1511 cam->vw.width = 288;
1512 cam->vw.height = 216;
1513 cam->params.format.videoSize=VIDEOSIZE_CIF;
1514 cam->params.roi.colStart=4;
1515 cam->params.roi.rowStart=9;
1516 cam->params.streamStartLine = 120;
1517 break;
1518 case VIDEOSIZE_256_192:
1519 cam->vw.width = 256;
1520 cam->vw.height = 192;
1521 cam->params.format.videoSize=VIDEOSIZE_CIF;
1522 cam->params.roi.colStart=6;
1523 cam->params.roi.rowStart=12;
1524 cam->params.streamStartLine = 120;
1525 break;
1526 case VIDEOSIZE_224_168:
1527 cam->vw.width = 224;
1528 cam->vw.height = 168;
1529 cam->params.format.videoSize=VIDEOSIZE_CIF;
1530 cam->params.roi.colStart=8;
1531 cam->params.roi.rowStart=15;
1532 cam->params.streamStartLine = 120;
1533 break;
1534 case VIDEOSIZE_192_144:
1535 cam->vw.width = 192;
1536 cam->vw.height = 144;
1537 cam->params.format.videoSize=VIDEOSIZE_CIF;
1538 cam->params.roi.colStart=10;
1539 cam->params.roi.rowStart=18;
1540 cam->params.streamStartLine = 120;
1541 break;
1542 case VIDEOSIZE_QCIF:
1543 cam->vw.width = 176;
1544 cam->vw.height = 144;
1545 cam->params.format.videoSize=VIDEOSIZE_QCIF;
1546 cam->params.roi.colStart=0;
1547 cam->params.roi.rowStart=0;
1548 cam->params.streamStartLine = 60;
1549 break;
1550 case VIDEOSIZE_QSIF:
1551 cam->vw.width = 160;
1552 cam->vw.height = 120;
1553 cam->params.format.videoSize=VIDEOSIZE_QCIF;
1554 cam->params.roi.colStart=1;
1555 cam->params.roi.rowStart=3;
1556 cam->params.streamStartLine = 60;
1557 break;
1558 case VIDEOSIZE_128_96:
1559 cam->vw.width = 128;
1560 cam->vw.height = 96;
1561 cam->params.format.videoSize=VIDEOSIZE_QCIF;
1562 cam->params.roi.colStart=3;
1563 cam->params.roi.rowStart=6;
1564 cam->params.streamStartLine = 60;
1565 break;
1566 case VIDEOSIZE_88_72:
1567 cam->vw.width = 88;
1568 cam->vw.height = 72;
1569 cam->params.format.videoSize=VIDEOSIZE_QCIF;
1570 cam->params.roi.colStart=5;
1571 cam->params.roi.rowStart=9;
1572 cam->params.streamStartLine = 60;
1573 break;
1574 case VIDEOSIZE_64_48:
1575 cam->vw.width = 64;
1576 cam->vw.height = 48;
1577 cam->params.format.videoSize=VIDEOSIZE_QCIF;
1578 cam->params.roi.colStart=7;
1579 cam->params.roi.rowStart=12;
1580 cam->params.streamStartLine = 60;
1581 break;
1582 case VIDEOSIZE_48_48:
1583 cam->vw.width = 48;
1584 cam->vw.height = 48;
1585 cam->params.format.videoSize=VIDEOSIZE_QCIF;
1586 cam->params.roi.colStart=8;
1587 cam->params.roi.rowStart=6;
1588 cam->params.streamStartLine = 60;
1589 break;
1590 default:
1591 LOG("bad videosize value: %d\n", cam->video_size);
1592 return;
1593 }
1594
1595 if(cam->vc.width == 0)
1596 cam->vc.width = cam->vw.width;
1597 if(cam->vc.height == 0)
1598 cam->vc.height = cam->vw.height;
1599
1600 cam->params.roi.colStart += cam->vc.x >> 3;
1601 cam->params.roi.colEnd = cam->params.roi.colStart +
1602 (cam->vc.width >> 3);
1603 cam->params.roi.rowStart += cam->vc.y >> 2;
1604 cam->params.roi.rowEnd = cam->params.roi.rowStart +
1605 (cam->vc.height >> 2);
1606
1607 return;
1608}
1609
1610static int allocate_frame_buf(struct cam_data *cam)
1611{
1612 int i;
1613
1614 cam->frame_buf = rvmalloc(FRAME_NUM * CPIA_MAX_FRAME_SIZE);
1615 if (!cam->frame_buf)
1616 return -ENOBUFS;
1617
1618 for (i = 0; i < FRAME_NUM; i++)
1619 cam->frame[i].data = cam->frame_buf + i * CPIA_MAX_FRAME_SIZE;
1620
1621 return 0;
1622}
1623
1624static int free_frame_buf(struct cam_data *cam)
1625{
1626 int i;
1627
1628 rvfree(cam->frame_buf, FRAME_NUM*CPIA_MAX_FRAME_SIZE);
1629 cam->frame_buf = NULL;
1630 for (i=0; i < FRAME_NUM; i++)
1631 cam->frame[i].data = NULL;
1632
1633 return 0;
1634}
1635
1636
1637static inline void free_frames(struct cpia_frame frame[FRAME_NUM])
1638{
1639 int i;
1640
1641 for (i=0; i < FRAME_NUM; i++)
1642 frame[i].state = FRAME_UNUSED;
1643 return;
1644}
1645
1646/**********************************************************************
1647 *
1648 * General functions
1649 *
1650 **********************************************************************/
1651/* send an arbitrary command to the camera */
1652static int do_command(struct cam_data *cam, u16 command, u8 a, u8 b, u8 c, u8 d)
1653{
1654 int retval, datasize;
1655 u8 cmd[8], data[8];
1656
1657 switch(command) {
1658 case CPIA_COMMAND_GetCPIAVersion:
1659 case CPIA_COMMAND_GetPnPID:
1660 case CPIA_COMMAND_GetCameraStatus:
1661 case CPIA_COMMAND_GetVPVersion:
1662 datasize=8;
1663 break;
1664 case CPIA_COMMAND_GetColourParams:
1665 case CPIA_COMMAND_GetColourBalance:
1666 case CPIA_COMMAND_GetExposure:
1667 down(&cam->param_lock);
1668 datasize=8;
1669 break;
1670 case CPIA_COMMAND_ReadMCPorts:
1671 case CPIA_COMMAND_ReadVCRegs:
1672 datasize = 4;
1673 break;
1674 default:
1675 datasize=0;
1676 break;
1677 }
1678
1679 cmd[0] = command>>8;
1680 cmd[1] = command&0xff;
1681 cmd[2] = a;
1682 cmd[3] = b;
1683 cmd[4] = c;
1684 cmd[5] = d;
1685 cmd[6] = datasize;
1686 cmd[7] = 0;
1687
1688 retval = cam->ops->transferCmd(cam->lowlevel_data, cmd, data);
1689 if (retval) {
1690 DBG("%x - failed, retval=%d\n", command, retval);
1691 if (command == CPIA_COMMAND_GetColourParams ||
1692 command == CPIA_COMMAND_GetColourBalance ||
1693 command == CPIA_COMMAND_GetExposure)
1694 up(&cam->param_lock);
1695 } else {
1696 switch(command) {
1697 case CPIA_COMMAND_GetCPIAVersion:
1698 cam->params.version.firmwareVersion = data[0];
1699 cam->params.version.firmwareRevision = data[1];
1700 cam->params.version.vcVersion = data[2];
1701 cam->params.version.vcRevision = data[3];
1702 break;
1703 case CPIA_COMMAND_GetPnPID:
1704 cam->params.pnpID.vendor = data[0]+(((u16)data[1])<<8);
1705 cam->params.pnpID.product = data[2]+(((u16)data[3])<<8);
1706 cam->params.pnpID.deviceRevision =
1707 data[4]+(((u16)data[5])<<8);
1708 break;
1709 case CPIA_COMMAND_GetCameraStatus:
1710 cam->params.status.systemState = data[0];
1711 cam->params.status.grabState = data[1];
1712 cam->params.status.streamState = data[2];
1713 cam->params.status.fatalError = data[3];
1714 cam->params.status.cmdError = data[4];
1715 cam->params.status.debugFlags = data[5];
1716 cam->params.status.vpStatus = data[6];
1717 cam->params.status.errorCode = data[7];
1718 break;
1719 case CPIA_COMMAND_GetVPVersion:
1720 cam->params.vpVersion.vpVersion = data[0];
1721 cam->params.vpVersion.vpRevision = data[1];
1722 cam->params.vpVersion.cameraHeadID =
1723 data[2]+(((u16)data[3])<<8);
1724 break;
1725 case CPIA_COMMAND_GetColourParams:
1726 cam->params.colourParams.brightness = data[0];
1727 cam->params.colourParams.contrast = data[1];
1728 cam->params.colourParams.saturation = data[2];
1729 up(&cam->param_lock);
1730 break;
1731 case CPIA_COMMAND_GetColourBalance:
1732 cam->params.colourBalance.redGain = data[0];
1733 cam->params.colourBalance.greenGain = data[1];
1734 cam->params.colourBalance.blueGain = data[2];
1735 up(&cam->param_lock);
1736 break;
1737 case CPIA_COMMAND_GetExposure:
1738 cam->params.exposure.gain = data[0];
1739 cam->params.exposure.fineExp = data[1];
1740 cam->params.exposure.coarseExpLo = data[2];
1741 cam->params.exposure.coarseExpHi = data[3];
1742 cam->params.exposure.redComp = data[4];
1743 cam->params.exposure.green1Comp = data[5];
1744 cam->params.exposure.green2Comp = data[6];
1745 cam->params.exposure.blueComp = data[7];
1746 up(&cam->param_lock);
1747 break;
1748
1749 case CPIA_COMMAND_ReadMCPorts:
1750 if (!cam->params.qx3.qx3_detected)
1751 break;
1752 /* test button press */
1753 cam->params.qx3.button = ((data[1] & 0x02) == 0);
1754 if (cam->params.qx3.button) {
1755 /* button pressed - unlock the latch */
1756 do_command(cam,CPIA_COMMAND_WriteMCPort,3,0xDF,0xDF,0);
1757 do_command(cam,CPIA_COMMAND_WriteMCPort,3,0xFF,0xFF,0);
1758 }
1759
1760 /* test whether microscope is cradled */
1761 cam->params.qx3.cradled = ((data[2] & 0x40) == 0);
1762 break;
1763
1764 default:
1765 break;
1766 }
1767 }
1768 return retval;
1769}
1770
1771/* send a command to the camera with an additional data transaction */
1772static int do_command_extended(struct cam_data *cam, u16 command,
1773 u8 a, u8 b, u8 c, u8 d,
1774 u8 e, u8 f, u8 g, u8 h,
1775 u8 i, u8 j, u8 k, u8 l)
1776{
1777 int retval;
1778 u8 cmd[8], data[8];
1779
1780 cmd[0] = command>>8;
1781 cmd[1] = command&0xff;
1782 cmd[2] = a;
1783 cmd[3] = b;
1784 cmd[4] = c;
1785 cmd[5] = d;
1786 cmd[6] = 8;
1787 cmd[7] = 0;
1788 data[0] = e;
1789 data[1] = f;
1790 data[2] = g;
1791 data[3] = h;
1792 data[4] = i;
1793 data[5] = j;
1794 data[6] = k;
1795 data[7] = l;
1796
1797 retval = cam->ops->transferCmd(cam->lowlevel_data, cmd, data);
1798 if (retval)
1799 DBG("%x - failed\n", command);
1800
1801 return retval;
1802}
1803
1804/**********************************************************************
1805 *
1806 * Colorspace conversion
1807 *
1808 **********************************************************************/
1809#define LIMIT(x) ((((x)>0xffffff)?0xff0000:(((x)<=0xffff)?0:(x)&0xff0000))>>16)
1810
1811static int convert420(unsigned char *yuv, unsigned char *rgb, int out_fmt,
1812 int linesize, int mmap_kludge)
1813{
1814 int y, u, v, r, g, b, y1;
1815
1816 /* Odd lines use the same u and v as the previous line.
1817 * Because of compression, it is necessary to get this
1818 * information from the decoded image. */
1819 switch(out_fmt) {
1820 case VIDEO_PALETTE_RGB555:
1821 y = (*yuv++ - 16) * 76310;
1822 y1 = (*yuv - 16) * 76310;
1823 r = ((*(rgb+1-linesize)) & 0x7c) << 1;
1824 g = ((*(rgb-linesize)) & 0xe0) >> 4 |
1825 ((*(rgb+1-linesize)) & 0x03) << 6;
1826 b = ((*(rgb-linesize)) & 0x1f) << 3;
1827 u = (-53294 * r - 104635 * g + 157929 * b) / 5756495;
1828 v = (157968 * r - 132278 * g - 25690 * b) / 5366159;
1829 r = 104635 * v;
1830 g = -25690 * u - 53294 * v;
1831 b = 132278 * u;
1832 *rgb++ = ((LIMIT(g+y) & 0xf8) << 2) | (LIMIT(b+y) >> 3);
1833 *rgb++ = ((LIMIT(r+y) & 0xf8) >> 1) | (LIMIT(g+y) >> 6);
1834 *rgb++ = ((LIMIT(g+y1) & 0xf8) << 2) | (LIMIT(b+y1) >> 3);
1835 *rgb = ((LIMIT(r+y1) & 0xf8) >> 1) | (LIMIT(g+y1) >> 6);
1836 return 4;
1837 case VIDEO_PALETTE_RGB565:
1838 y = (*yuv++ - 16) * 76310;
1839 y1 = (*yuv - 16) * 76310;
1840 r = (*(rgb+1-linesize)) & 0xf8;
1841 g = ((*(rgb-linesize)) & 0xe0) >> 3 |
1842 ((*(rgb+1-linesize)) & 0x07) << 5;
1843 b = ((*(rgb-linesize)) & 0x1f) << 3;
1844 u = (-53294 * r - 104635 * g + 157929 * b) / 5756495;
1845 v = (157968 * r - 132278 * g - 25690 * b) / 5366159;
1846 r = 104635 * v;
1847 g = -25690 * u - 53294 * v;
1848 b = 132278 * u;
1849 *rgb++ = ((LIMIT(g+y) & 0xfc) << 3) | (LIMIT(b+y) >> 3);
1850 *rgb++ = (LIMIT(r+y) & 0xf8) | (LIMIT(g+y) >> 5);
1851 *rgb++ = ((LIMIT(g+y1) & 0xfc) << 3) | (LIMIT(b+y1) >> 3);
1852 *rgb = (LIMIT(r+y1) & 0xf8) | (LIMIT(g+y1) >> 5);
1853 return 4;
1854 break;
1855 case VIDEO_PALETTE_RGB24:
1856 case VIDEO_PALETTE_RGB32:
1857 y = (*yuv++ - 16) * 76310;
1858 y1 = (*yuv - 16) * 76310;
1859 if (mmap_kludge) {
1860 r = *(rgb+2-linesize);
1861 g = *(rgb+1-linesize);
1862 b = *(rgb-linesize);
1863 } else {
1864 r = *(rgb-linesize);
1865 g = *(rgb+1-linesize);
1866 b = *(rgb+2-linesize);
1867 }
1868 u = (-53294 * r - 104635 * g + 157929 * b) / 5756495;
1869 v = (157968 * r - 132278 * g - 25690 * b) / 5366159;
1870 r = 104635 * v;
1871 g = -25690 * u + -53294 * v;
1872 b = 132278 * u;
1873 if (mmap_kludge) {
1874 *rgb++ = LIMIT(b+y);
1875 *rgb++ = LIMIT(g+y);
1876 *rgb++ = LIMIT(r+y);
1877 if(out_fmt == VIDEO_PALETTE_RGB32)
1878 rgb++;
1879 *rgb++ = LIMIT(b+y1);
1880 *rgb++ = LIMIT(g+y1);
1881 *rgb = LIMIT(r+y1);
1882 } else {
1883 *rgb++ = LIMIT(r+y);
1884 *rgb++ = LIMIT(g+y);
1885 *rgb++ = LIMIT(b+y);
1886 if(out_fmt == VIDEO_PALETTE_RGB32)
1887 rgb++;
1888 *rgb++ = LIMIT(r+y1);
1889 *rgb++ = LIMIT(g+y1);
1890 *rgb = LIMIT(b+y1);
1891 }
1892 if(out_fmt == VIDEO_PALETTE_RGB32)
1893 return 8;
1894 return 6;
1895 case VIDEO_PALETTE_YUV422:
1896 case VIDEO_PALETTE_YUYV:
1897 y = *yuv++;
1898 u = *(rgb+1-linesize);
1899 y1 = *yuv;
1900 v = *(rgb+3-linesize);
1901 *rgb++ = y;
1902 *rgb++ = u;
1903 *rgb++ = y1;
1904 *rgb = v;
1905 return 4;
1906 case VIDEO_PALETTE_UYVY:
1907 u = *(rgb-linesize);
1908 y = *yuv++;
1909 v = *(rgb+2-linesize);
1910 y1 = *yuv;
1911 *rgb++ = u;
1912 *rgb++ = y;
1913 *rgb++ = v;
1914 *rgb = y1;
1915 return 4;
1916 case VIDEO_PALETTE_GREY:
1917 *rgb++ = *yuv++;
1918 *rgb = *yuv;
1919 return 2;
1920 default:
1921 DBG("Empty: %d\n", out_fmt);
1922 return 0;
1923 }
1924}
1925
1926
1927static int yuvconvert(unsigned char *yuv, unsigned char *rgb, int out_fmt,
1928 int in_uyvy, int mmap_kludge)
1929{
1930 int y, u, v, r, g, b, y1;
1931
1932 switch(out_fmt) {
1933 case VIDEO_PALETTE_RGB555:
1934 case VIDEO_PALETTE_RGB565:
1935 case VIDEO_PALETTE_RGB24:
1936 case VIDEO_PALETTE_RGB32:
1937 if (in_uyvy) {
1938 u = *yuv++ - 128;
1939 y = (*yuv++ - 16) * 76310;
1940 v = *yuv++ - 128;
1941 y1 = (*yuv - 16) * 76310;
1942 } else {
1943 y = (*yuv++ - 16) * 76310;
1944 u = *yuv++ - 128;
1945 y1 = (*yuv++ - 16) * 76310;
1946 v = *yuv - 128;
1947 }
1948 r = 104635 * v;
1949 g = -25690 * u + -53294 * v;
1950 b = 132278 * u;
1951 break;
1952 default:
1953 y = *yuv++;
1954 u = *yuv++;
1955 y1 = *yuv++;
1956 v = *yuv;
1957 /* Just to avoid compiler warnings */
1958 r = 0;
1959 g = 0;
1960 b = 0;
1961 break;
1962 }
1963 switch(out_fmt) {
1964 case VIDEO_PALETTE_RGB555:
1965 *rgb++ = ((LIMIT(g+y) & 0xf8) << 2) | (LIMIT(b+y) >> 3);
1966 *rgb++ = ((LIMIT(r+y) & 0xf8) >> 1) | (LIMIT(g+y) >> 6);
1967 *rgb++ = ((LIMIT(g+y1) & 0xf8) << 2) | (LIMIT(b+y1) >> 3);
1968 *rgb = ((LIMIT(r+y1) & 0xf8) >> 1) | (LIMIT(g+y1) >> 6);
1969 return 4;
1970 case VIDEO_PALETTE_RGB565:
1971 *rgb++ = ((LIMIT(g+y) & 0xfc) << 3) | (LIMIT(b+y) >> 3);
1972 *rgb++ = (LIMIT(r+y) & 0xf8) | (LIMIT(g+y) >> 5);
1973 *rgb++ = ((LIMIT(g+y1) & 0xfc) << 3) | (LIMIT(b+y1) >> 3);
1974 *rgb = (LIMIT(r+y1) & 0xf8) | (LIMIT(g+y1) >> 5);
1975 return 4;
1976 case VIDEO_PALETTE_RGB24:
1977 if (mmap_kludge) {
1978 *rgb++ = LIMIT(b+y);
1979 *rgb++ = LIMIT(g+y);
1980 *rgb++ = LIMIT(r+y);
1981 *rgb++ = LIMIT(b+y1);
1982 *rgb++ = LIMIT(g+y1);
1983 *rgb = LIMIT(r+y1);
1984 } else {
1985 *rgb++ = LIMIT(r+y);
1986 *rgb++ = LIMIT(g+y);
1987 *rgb++ = LIMIT(b+y);
1988 *rgb++ = LIMIT(r+y1);
1989 *rgb++ = LIMIT(g+y1);
1990 *rgb = LIMIT(b+y1);
1991 }
1992 return 6;
1993 case VIDEO_PALETTE_RGB32:
1994 if (mmap_kludge) {
1995 *rgb++ = LIMIT(b+y);
1996 *rgb++ = LIMIT(g+y);
1997 *rgb++ = LIMIT(r+y);
1998 rgb++;
1999 *rgb++ = LIMIT(b+y1);
2000 *rgb++ = LIMIT(g+y1);
2001 *rgb = LIMIT(r+y1);
2002 } else {
2003 *rgb++ = LIMIT(r+y);
2004 *rgb++ = LIMIT(g+y);
2005 *rgb++ = LIMIT(b+y);
2006 rgb++;
2007 *rgb++ = LIMIT(r+y1);
2008 *rgb++ = LIMIT(g+y1);
2009 *rgb = LIMIT(b+y1);
2010 }
2011 return 8;
2012 case VIDEO_PALETTE_GREY:
2013 *rgb++ = y;
2014 *rgb = y1;
2015 return 2;
2016 case VIDEO_PALETTE_YUV422:
2017 case VIDEO_PALETTE_YUYV:
2018 *rgb++ = y;
2019 *rgb++ = u;
2020 *rgb++ = y1;
2021 *rgb = v;
2022 return 4;
2023 case VIDEO_PALETTE_UYVY:
2024 *rgb++ = u;
2025 *rgb++ = y;
2026 *rgb++ = v;
2027 *rgb = y1;
2028 return 4;
2029 default:
2030 DBG("Empty: %d\n", out_fmt);
2031 return 0;
2032 }
2033}
2034
2035static int skipcount(int count, int fmt)
2036{
2037 switch(fmt) {
2038 case VIDEO_PALETTE_GREY:
2039 return count;
2040 case VIDEO_PALETTE_RGB555:
2041 case VIDEO_PALETTE_RGB565:
2042 case VIDEO_PALETTE_YUV422:
2043 case VIDEO_PALETTE_YUYV:
2044 case VIDEO_PALETTE_UYVY:
2045 return 2*count;
2046 case VIDEO_PALETTE_RGB24:
2047 return 3*count;
2048 case VIDEO_PALETTE_RGB32:
2049 return 4*count;
2050 default:
2051 return 0;
2052 }
2053}
2054
2055static int parse_picture(struct cam_data *cam, int size)
2056{
2057 u8 *obuf, *ibuf, *end_obuf;
2058 int ll, in_uyvy, compressed, decimation, even_line, origsize, out_fmt;
2059 int rows, cols, linesize, subsample_422;
2060
2061 /* make sure params don't change while we are decoding */
2062 down(&cam->param_lock);
2063
2064 obuf = cam->decompressed_frame.data;
2065 end_obuf = obuf+CPIA_MAX_FRAME_SIZE;
2066 ibuf = cam->raw_image;
2067 origsize = size;
2068 out_fmt = cam->vp.palette;
2069
2070 if ((ibuf[0] != MAGIC_0) || (ibuf[1] != MAGIC_1)) {
2071 LOG("header not found\n");
2072 up(&cam->param_lock);
2073 return -1;
2074 }
2075
2076 if ((ibuf[16] != VIDEOSIZE_QCIF) && (ibuf[16] != VIDEOSIZE_CIF)) {
2077 LOG("wrong video size\n");
2078 up(&cam->param_lock);
2079 return -1;
2080 }
2081
2082 if (ibuf[17] != SUBSAMPLE_420 && ibuf[17] != SUBSAMPLE_422) {
2083 LOG("illegal subtype %d\n",ibuf[17]);
2084 up(&cam->param_lock);
2085 return -1;
2086 }
2087 subsample_422 = ibuf[17] == SUBSAMPLE_422;
2088
2089 if (ibuf[18] != YUVORDER_YUYV && ibuf[18] != YUVORDER_UYVY) {
2090 LOG("illegal yuvorder %d\n",ibuf[18]);
2091 up(&cam->param_lock);
2092 return -1;
2093 }
2094 in_uyvy = ibuf[18] == YUVORDER_UYVY;
2095
2096 if ((ibuf[24] != cam->params.roi.colStart) ||
2097 (ibuf[25] != cam->params.roi.colEnd) ||
2098 (ibuf[26] != cam->params.roi.rowStart) ||
2099 (ibuf[27] != cam->params.roi.rowEnd)) {
2100 LOG("ROI mismatch\n");
2101 up(&cam->param_lock);
2102 return -1;
2103 }
2104 cols = 8*(ibuf[25] - ibuf[24]);
2105 rows = 4*(ibuf[27] - ibuf[26]);
2106
2107
2108 if ((ibuf[28] != NOT_COMPRESSED) && (ibuf[28] != COMPRESSED)) {
2109 LOG("illegal compression %d\n",ibuf[28]);
2110 up(&cam->param_lock);
2111 return -1;
2112 }
2113 compressed = (ibuf[28] == COMPRESSED);
2114
2115 if (ibuf[29] != NO_DECIMATION && ibuf[29] != DECIMATION_ENAB) {
2116 LOG("illegal decimation %d\n",ibuf[29]);
2117 up(&cam->param_lock);
2118 return -1;
2119 }
2120 decimation = (ibuf[29] == DECIMATION_ENAB);
2121
2122 cam->params.yuvThreshold.yThreshold = ibuf[30];
2123 cam->params.yuvThreshold.uvThreshold = ibuf[31];
2124 cam->params.status.systemState = ibuf[32];
2125 cam->params.status.grabState = ibuf[33];
2126 cam->params.status.streamState = ibuf[34];
2127 cam->params.status.fatalError = ibuf[35];
2128 cam->params.status.cmdError = ibuf[36];
2129 cam->params.status.debugFlags = ibuf[37];
2130 cam->params.status.vpStatus = ibuf[38];
2131 cam->params.status.errorCode = ibuf[39];
2132 cam->fps = ibuf[41];
2133 up(&cam->param_lock);
2134
2135 linesize = skipcount(cols, out_fmt);
2136 ibuf += FRAME_HEADER_SIZE;
2137 size -= FRAME_HEADER_SIZE;
2138 ll = ibuf[0] | (ibuf[1] << 8);
2139 ibuf += 2;
2140 even_line = 1;
2141
2142 while (size > 0) {
2143 size -= (ll+2);
2144 if (size < 0) {
2145 LOG("Insufficient data in buffer\n");
2146 return -1;
2147 }
2148
2149 while (ll > 1) {
2150 if (!compressed || (compressed && !(*ibuf & 1))) {
2151 if(subsample_422 || even_line) {
2152 obuf += yuvconvert(ibuf, obuf, out_fmt,
2153 in_uyvy, cam->mmap_kludge);
2154 ibuf += 4;
2155 ll -= 4;
2156 } else {
2157 /* SUBSAMPLE_420 on an odd line */
2158 obuf += convert420(ibuf, obuf,
2159 out_fmt, linesize,
2160 cam->mmap_kludge);
2161 ibuf += 2;
2162 ll -= 2;
2163 }
2164 } else {
2165 /*skip compressed interval from previous frame*/
2166 obuf += skipcount(*ibuf >> 1, out_fmt);
2167 if (obuf > end_obuf) {
2168 LOG("Insufficient buffer size\n");
2169 return -1;
2170 }
2171 ++ibuf;
2172 ll--;
2173 }
2174 }
2175 if (ll == 1) {
2176 if (*ibuf != EOL) {
2177 DBG("EOL not found giving up after %d/%d"
2178 " bytes\n", origsize-size, origsize);
2179 return -1;
2180 }
2181
2182 ++ibuf; /* skip over EOL */
2183
2184 if ((size > 3) && (ibuf[0] == EOI) && (ibuf[1] == EOI) &&
2185 (ibuf[2] == EOI) && (ibuf[3] == EOI)) {
2186 size -= 4;
2187 break;
2188 }
2189
2190 if(decimation) {
2191 /* skip the odd lines for now */
2192 obuf += linesize;
2193 }
2194
2195 if (size > 1) {
2196 ll = ibuf[0] | (ibuf[1] << 8);
2197 ibuf += 2; /* skip over line length */
2198 }
2199 if(!decimation)
2200 even_line = !even_line;
2201 } else {
2202 LOG("line length was not 1 but %d after %d/%d bytes\n",
2203 ll, origsize-size, origsize);
2204 return -1;
2205 }
2206 }
2207
2208 if(decimation) {
2209 /* interpolate odd rows */
2210 int i, j;
2211 u8 *prev, *next;
2212 prev = cam->decompressed_frame.data;
2213 obuf = prev+linesize;
2214 next = obuf+linesize;
2215 for(i=1; i<rows-1; i+=2) {
2216 for(j=0; j<linesize; ++j) {
2217 *obuf++ = ((int)*prev++ + *next++) / 2;
2218 }
2219 prev += linesize;
2220 obuf += linesize;
2221 next += linesize;
2222 }
2223 /* last row is odd, just copy previous row */
2224 memcpy(obuf, prev, linesize);
2225 }
2226
2227 cam->decompressed_frame.count = obuf-cam->decompressed_frame.data;
2228
2229 return cam->decompressed_frame.count;
2230}
2231
2232/* InitStreamCap wrapper to select correct start line */
2233static inline int init_stream_cap(struct cam_data *cam)
2234{
2235 return do_command(cam, CPIA_COMMAND_InitStreamCap,
2236 0, cam->params.streamStartLine, 0, 0);
2237}
2238
2239
2240/* find_over_exposure
2241 * Finds a suitable value of OverExposure for use with SetFlickerCtrl
2242 * Some calculation is required because this value changes with the brightness
2243 * set with SetColourParameters
2244 *
2245 * Parameters: Brightness - last brightness value set with SetColourParameters
2246 *
2247 * Returns: OverExposure value to use with SetFlickerCtrl
2248 */
2249#define FLICKER_MAX_EXPOSURE 250
2250#define FLICKER_ALLOWABLE_OVER_EXPOSURE 146
2251#define FLICKER_BRIGHTNESS_CONSTANT 59
2252static int find_over_exposure(int brightness)
2253{
2254 int MaxAllowableOverExposure, OverExposure;
2255
2256 MaxAllowableOverExposure = FLICKER_MAX_EXPOSURE - brightness -
2257 FLICKER_BRIGHTNESS_CONSTANT;
2258
2259 if (MaxAllowableOverExposure < FLICKER_ALLOWABLE_OVER_EXPOSURE) {
2260 OverExposure = MaxAllowableOverExposure;
2261 } else {
2262 OverExposure = FLICKER_ALLOWABLE_OVER_EXPOSURE;
2263 }
2264
2265 return OverExposure;
2266}
2267#undef FLICKER_MAX_EXPOSURE
2268#undef FLICKER_ALLOWABLE_OVER_EXPOSURE
2269#undef FLICKER_BRIGHTNESS_CONSTANT
2270
2271/* update various camera modes and settings */
2272static void dispatch_commands(struct cam_data *cam)
2273{
2274 down(&cam->param_lock);
2275 if (cam->cmd_queue==COMMAND_NONE) {
2276 up(&cam->param_lock);
2277 return;
2278 }
2279 DEB_BYTE(cam->cmd_queue);
2280 DEB_BYTE(cam->cmd_queue>>8);
2281 if (cam->cmd_queue & COMMAND_SETFORMAT) {
2282 do_command(cam, CPIA_COMMAND_SetFormat,
2283 cam->params.format.videoSize,
2284 cam->params.format.subSample,
2285 cam->params.format.yuvOrder, 0);
2286 do_command(cam, CPIA_COMMAND_SetROI,
2287 cam->params.roi.colStart, cam->params.roi.colEnd,
2288 cam->params.roi.rowStart, cam->params.roi.rowEnd);
2289 cam->first_frame = 1;
2290 }
2291
2292 if (cam->cmd_queue & COMMAND_SETCOLOURPARAMS)
2293 do_command(cam, CPIA_COMMAND_SetColourParams,
2294 cam->params.colourParams.brightness,
2295 cam->params.colourParams.contrast,
2296 cam->params.colourParams.saturation, 0);
2297
2298 if (cam->cmd_queue & COMMAND_SETAPCOR)
2299 do_command(cam, CPIA_COMMAND_SetApcor,
2300 cam->params.apcor.gain1,
2301 cam->params.apcor.gain2,
2302 cam->params.apcor.gain4,
2303 cam->params.apcor.gain8);
2304
2305 if (cam->cmd_queue & COMMAND_SETVLOFFSET)
2306 do_command(cam, CPIA_COMMAND_SetVLOffset,
2307 cam->params.vlOffset.gain1,
2308 cam->params.vlOffset.gain2,
2309 cam->params.vlOffset.gain4,
2310 cam->params.vlOffset.gain8);
2311
2312 if (cam->cmd_queue & COMMAND_SETEXPOSURE) {
2313 do_command_extended(cam, CPIA_COMMAND_SetExposure,
2314 cam->params.exposure.gainMode,
2315 1,
2316 cam->params.exposure.compMode,
2317 cam->params.exposure.centreWeight,
2318 cam->params.exposure.gain,
2319 cam->params.exposure.fineExp,
2320 cam->params.exposure.coarseExpLo,
2321 cam->params.exposure.coarseExpHi,
2322 cam->params.exposure.redComp,
2323 cam->params.exposure.green1Comp,
2324 cam->params.exposure.green2Comp,
2325 cam->params.exposure.blueComp);
2326 if(cam->params.exposure.expMode != 1) {
2327 do_command_extended(cam, CPIA_COMMAND_SetExposure,
2328 0,
2329 cam->params.exposure.expMode,
2330 0, 0,
2331 cam->params.exposure.gain,
2332 cam->params.exposure.fineExp,
2333 cam->params.exposure.coarseExpLo,
2334 cam->params.exposure.coarseExpHi,
2335 0, 0, 0, 0);
2336 }
2337 }
2338
2339 if (cam->cmd_queue & COMMAND_SETCOLOURBALANCE) {
2340 if (cam->params.colourBalance.balanceMode == 1) {
2341 do_command(cam, CPIA_COMMAND_SetColourBalance,
2342 1,
2343 cam->params.colourBalance.redGain,
2344 cam->params.colourBalance.greenGain,
2345 cam->params.colourBalance.blueGain);
2346 do_command(cam, CPIA_COMMAND_SetColourBalance,
2347 3, 0, 0, 0);
2348 }
2349 if (cam->params.colourBalance.balanceMode == 2) {
2350 do_command(cam, CPIA_COMMAND_SetColourBalance,
2351 2, 0, 0, 0);
2352 }
2353 if (cam->params.colourBalance.balanceMode == 3) {
2354 do_command(cam, CPIA_COMMAND_SetColourBalance,
2355 3, 0, 0, 0);
2356 }
2357 }
2358
2359 if (cam->cmd_queue & COMMAND_SETCOMPRESSIONTARGET)
2360 do_command(cam, CPIA_COMMAND_SetCompressionTarget,
2361 cam->params.compressionTarget.frTargeting,
2362 cam->params.compressionTarget.targetFR,
2363 cam->params.compressionTarget.targetQ, 0);
2364
2365 if (cam->cmd_queue & COMMAND_SETYUVTHRESH)
2366 do_command(cam, CPIA_COMMAND_SetYUVThresh,
2367 cam->params.yuvThreshold.yThreshold,
2368 cam->params.yuvThreshold.uvThreshold, 0, 0);
2369
2370 if (cam->cmd_queue & COMMAND_SETCOMPRESSIONPARAMS)
2371 do_command_extended(cam, CPIA_COMMAND_SetCompressionParams,
2372 0, 0, 0, 0,
2373 cam->params.compressionParams.hysteresis,
2374 cam->params.compressionParams.threshMax,
2375 cam->params.compressionParams.smallStep,
2376 cam->params.compressionParams.largeStep,
2377 cam->params.compressionParams.decimationHysteresis,
2378 cam->params.compressionParams.frDiffStepThresh,
2379 cam->params.compressionParams.qDiffStepThresh,
2380 cam->params.compressionParams.decimationThreshMod);
2381
2382 if (cam->cmd_queue & COMMAND_SETCOMPRESSION)
2383 do_command(cam, CPIA_COMMAND_SetCompression,
2384 cam->params.compression.mode,
2385 cam->params.compression.decimation, 0, 0);
2386
2387 if (cam->cmd_queue & COMMAND_SETSENSORFPS)
2388 do_command(cam, CPIA_COMMAND_SetSensorFPS,
2389 cam->params.sensorFps.divisor,
2390 cam->params.sensorFps.baserate, 0, 0);
2391
2392 if (cam->cmd_queue & COMMAND_SETFLICKERCTRL)
2393 do_command(cam, CPIA_COMMAND_SetFlickerCtrl,
2394 cam->params.flickerControl.flickerMode,
2395 cam->params.flickerControl.coarseJump,
2396 abs(cam->params.flickerControl.allowableOverExposure),
2397 0);
2398
2399 if (cam->cmd_queue & COMMAND_SETECPTIMING)
2400 do_command(cam, CPIA_COMMAND_SetECPTiming,
2401 cam->params.ecpTiming, 0, 0, 0);
2402
2403 if (cam->cmd_queue & COMMAND_PAUSE)
2404 do_command(cam, CPIA_COMMAND_EndStreamCap, 0, 0, 0, 0);
2405
2406 if (cam->cmd_queue & COMMAND_RESUME)
2407 init_stream_cap(cam);
2408
2409 if (cam->cmd_queue & COMMAND_SETLIGHTS && cam->params.qx3.qx3_detected)
2410 {
2411 int p1 = (cam->params.qx3.bottomlight == 0) << 1;
2412 int p2 = (cam->params.qx3.toplight == 0) << 3;
2413 do_command(cam, CPIA_COMMAND_WriteVCReg, 0x90, 0x8F, 0x50, 0);
2414 do_command(cam, CPIA_COMMAND_WriteMCPort, 2, 0, (p1|p2|0xE0), 0);
2415 }
2416
2417 cam->cmd_queue = COMMAND_NONE;
2418 up(&cam->param_lock);
2419 return;
2420}
2421
2422
2423
2424static void set_flicker(struct cam_params *params, volatile u32 *command_flags,
2425 int on)
2426{
2427 /* Everything in here is from the Windows driver */
2428#define FIRMWARE_VERSION(x,y) (params->version.firmwareVersion == (x) && \
2429 params->version.firmwareRevision == (y))
2430/* define for compgain calculation */
2431#if 0
2432#define COMPGAIN(base, curexp, newexp) \
2433 (u8) ((((float) base - 128.0) * ((float) curexp / (float) newexp)) + 128.5)
2434#define EXP_FROM_COMP(basecomp, curcomp, curexp) \
2435 (u16)((float)curexp * (float)(u8)(curcomp + 128) / (float)(u8)(basecomp - 128))
2436#else
2437 /* equivalent functions without floating point math */
2438#define COMPGAIN(base, curexp, newexp) \
2439 (u8)(128 + (((u32)(2*(base-128)*curexp + newexp)) / (2* newexp)) )
2440#define EXP_FROM_COMP(basecomp, curcomp, curexp) \
2441 (u16)(((u32)(curexp * (u8)(curcomp + 128)) / (u8)(basecomp - 128)))
2442#endif
2443
2444
2445 int currentexp = params->exposure.coarseExpLo +
2446 params->exposure.coarseExpHi*256;
2447 int startexp;
2448 if (on) {
2449 int cj = params->flickerControl.coarseJump;
2450 params->flickerControl.flickerMode = 1;
2451 params->flickerControl.disabled = 0;
2452 if(params->exposure.expMode != 2)
2453 *command_flags |= COMMAND_SETEXPOSURE;
2454 params->exposure.expMode = 2;
2455 currentexp = currentexp << params->exposure.gain;
2456 params->exposure.gain = 0;
2457 /* round down current exposure to nearest value */
2458 startexp = (currentexp + ROUND_UP_EXP_FOR_FLICKER) / cj;
2459 if(startexp < 1)
2460 startexp = 1;
2461 startexp = (startexp * cj) - 1;
2462 if(FIRMWARE_VERSION(1,2))
2463 while(startexp > MAX_EXP_102)
2464 startexp -= cj;
2465 else
2466 while(startexp > MAX_EXP)
2467 startexp -= cj;
2468 params->exposure.coarseExpLo = startexp & 0xff;
2469 params->exposure.coarseExpHi = startexp >> 8;
2470 if (currentexp > startexp) {
2471 if (currentexp > (2 * startexp))
2472 currentexp = 2 * startexp;
2473 params->exposure.redComp = COMPGAIN (COMP_RED, currentexp, startexp);
2474 params->exposure.green1Comp = COMPGAIN (COMP_GREEN1, currentexp, startexp);
2475 params->exposure.green2Comp = COMPGAIN (COMP_GREEN2, currentexp, startexp);
2476 params->exposure.blueComp = COMPGAIN (COMP_BLUE, currentexp, startexp);
2477 } else {
2478 params->exposure.redComp = COMP_RED;
2479 params->exposure.green1Comp = COMP_GREEN1;
2480 params->exposure.green2Comp = COMP_GREEN2;
2481 params->exposure.blueComp = COMP_BLUE;
2482 }
2483 if(FIRMWARE_VERSION(1,2))
2484 params->exposure.compMode = 0;
2485 else
2486 params->exposure.compMode = 1;
2487
2488 params->apcor.gain1 = 0x18;
2489 params->apcor.gain2 = 0x18;
2490 params->apcor.gain4 = 0x16;
2491 params->apcor.gain8 = 0x14;
2492 *command_flags |= COMMAND_SETAPCOR;
2493 } else {
2494 params->flickerControl.flickerMode = 0;
2495 params->flickerControl.disabled = 1;
2496 /* Coarse = average of equivalent coarse for each comp channel */
2497 startexp = EXP_FROM_COMP(COMP_RED, params->exposure.redComp, currentexp);
2498 startexp += EXP_FROM_COMP(COMP_GREEN1, params->exposure.green1Comp, currentexp);
2499 startexp += EXP_FROM_COMP(COMP_GREEN2, params->exposure.green2Comp, currentexp);
2500 startexp += EXP_FROM_COMP(COMP_BLUE, params->exposure.blueComp, currentexp);
2501 startexp = startexp >> 2;
2502 while(startexp > MAX_EXP &&
2503 params->exposure.gain < params->exposure.gainMode-1) {
2504 startexp = startexp >> 1;
2505 ++params->exposure.gain;
2506 }
2507 if(FIRMWARE_VERSION(1,2) && startexp > MAX_EXP_102)
2508 startexp = MAX_EXP_102;
2509 if(startexp > MAX_EXP)
2510 startexp = MAX_EXP;
2511 params->exposure.coarseExpLo = startexp&0xff;
2512 params->exposure.coarseExpHi = startexp >> 8;
2513 params->exposure.redComp = COMP_RED;
2514 params->exposure.green1Comp = COMP_GREEN1;
2515 params->exposure.green2Comp = COMP_GREEN2;
2516 params->exposure.blueComp = COMP_BLUE;
2517 params->exposure.compMode = 1;
2518 *command_flags |= COMMAND_SETEXPOSURE;
2519 params->apcor.gain1 = 0x18;
2520 params->apcor.gain2 = 0x16;
2521 params->apcor.gain4 = 0x24;
2522 params->apcor.gain8 = 0x34;
2523 *command_flags |= COMMAND_SETAPCOR;
2524 }
2525 params->vlOffset.gain1 = 20;
2526 params->vlOffset.gain2 = 24;
2527 params->vlOffset.gain4 = 26;
2528 params->vlOffset.gain8 = 26;
2529 *command_flags |= COMMAND_SETVLOFFSET;
2530#undef FIRMWARE_VERSION
2531#undef EXP_FROM_COMP
2532#undef COMPGAIN
2533}
2534
2535#define FIRMWARE_VERSION(x,y) (cam->params.version.firmwareVersion == (x) && \
2536 cam->params.version.firmwareRevision == (y))
2537/* monitor the exposure and adjust the sensor frame rate if needed */
2538static void monitor_exposure(struct cam_data *cam)
2539{
2540 u8 exp_acc, bcomp, gain, coarseL, cmd[8], data[8];
2541 int retval, light_exp, dark_exp, very_dark_exp;
2542 int old_exposure, new_exposure, framerate;
2543
2544 /* get necessary stats and register settings from camera */
2545 /* do_command can't handle this, so do it ourselves */
2546 cmd[0] = CPIA_COMMAND_ReadVPRegs>>8;
2547 cmd[1] = CPIA_COMMAND_ReadVPRegs&0xff;
2548 cmd[2] = 30;
2549 cmd[3] = 4;
2550 cmd[4] = 9;
2551 cmd[5] = 8;
2552 cmd[6] = 8;
2553 cmd[7] = 0;
2554 retval = cam->ops->transferCmd(cam->lowlevel_data, cmd, data);
2555 if (retval) {
2556 LOG("ReadVPRegs(30,4,9,8) - failed, retval=%d\n",
2557 retval);
2558 return;
2559 }
2560 exp_acc = data[0];
2561 bcomp = data[1];
2562 gain = data[2];
2563 coarseL = data[3];
2564
2565 down(&cam->param_lock);
2566 light_exp = cam->params.colourParams.brightness +
2567 TC - 50 + EXP_ACC_LIGHT;
2568 if(light_exp > 255)
2569 light_exp = 255;
2570 dark_exp = cam->params.colourParams.brightness +
2571 TC - 50 - EXP_ACC_DARK;
2572 if(dark_exp < 0)
2573 dark_exp = 0;
2574 very_dark_exp = dark_exp/2;
2575
2576 old_exposure = cam->params.exposure.coarseExpHi * 256 +
2577 cam->params.exposure.coarseExpLo;
2578
2579 if(!cam->params.flickerControl.disabled) {
2580 /* Flicker control on */
2581 int max_comp = FIRMWARE_VERSION(1,2) ? MAX_COMP : HIGH_COMP_102;
2582 bcomp += 128; /* decode */
2583 if(bcomp >= max_comp && exp_acc < dark_exp) {
2584 /* dark */
2585 if(exp_acc < very_dark_exp) {
2586 /* very dark */
2587 if(cam->exposure_status == EXPOSURE_VERY_DARK)
2588 ++cam->exposure_count;
2589 else {
2590 cam->exposure_status = EXPOSURE_VERY_DARK;
2591 cam->exposure_count = 1;
2592 }
2593 } else {
2594 /* just dark */
2595 if(cam->exposure_status == EXPOSURE_DARK)
2596 ++cam->exposure_count;
2597 else {
2598 cam->exposure_status = EXPOSURE_DARK;
2599 cam->exposure_count = 1;
2600 }
2601 }
2602 } else if(old_exposure <= LOW_EXP || exp_acc > light_exp) {
2603 /* light */
2604 if(old_exposure <= VERY_LOW_EXP) {
2605 /* very light */
2606 if(cam->exposure_status == EXPOSURE_VERY_LIGHT)
2607 ++cam->exposure_count;
2608 else {
2609 cam->exposure_status = EXPOSURE_VERY_LIGHT;
2610 cam->exposure_count = 1;
2611 }
2612 } else {
2613 /* just light */
2614 if(cam->exposure_status == EXPOSURE_LIGHT)
2615 ++cam->exposure_count;
2616 else {
2617 cam->exposure_status = EXPOSURE_LIGHT;
2618 cam->exposure_count = 1;
2619 }
2620 }
2621 } else {
2622 /* not dark or light */
2623 cam->exposure_status = EXPOSURE_NORMAL;
2624 }
2625 } else {
2626 /* Flicker control off */
2627 if(old_exposure >= MAX_EXP && exp_acc < dark_exp) {
2628 /* dark */
2629 if(exp_acc < very_dark_exp) {
2630 /* very dark */
2631 if(cam->exposure_status == EXPOSURE_VERY_DARK)
2632 ++cam->exposure_count;
2633 else {
2634 cam->exposure_status = EXPOSURE_VERY_DARK;
2635 cam->exposure_count = 1;
2636 }
2637 } else {
2638 /* just dark */
2639 if(cam->exposure_status == EXPOSURE_DARK)
2640 ++cam->exposure_count;
2641 else {
2642 cam->exposure_status = EXPOSURE_DARK;
2643 cam->exposure_count = 1;
2644 }
2645 }
2646 } else if(old_exposure <= LOW_EXP || exp_acc > light_exp) {
2647 /* light */
2648 if(old_exposure <= VERY_LOW_EXP) {
2649 /* very light */
2650 if(cam->exposure_status == EXPOSURE_VERY_LIGHT)
2651 ++cam->exposure_count;
2652 else {
2653 cam->exposure_status = EXPOSURE_VERY_LIGHT;
2654 cam->exposure_count = 1;
2655 }
2656 } else {
2657 /* just light */
2658 if(cam->exposure_status == EXPOSURE_LIGHT)
2659 ++cam->exposure_count;
2660 else {
2661 cam->exposure_status = EXPOSURE_LIGHT;
2662 cam->exposure_count = 1;
2663 }
2664 }
2665 } else {
2666 /* not dark or light */
2667 cam->exposure_status = EXPOSURE_NORMAL;
2668 }
2669 }
2670
2671 framerate = cam->fps;
2672 if(framerate > 30 || framerate < 1)
2673 framerate = 1;
2674
2675 if(!cam->params.flickerControl.disabled) {
2676 /* Flicker control on */
2677 if((cam->exposure_status == EXPOSURE_VERY_DARK ||
2678 cam->exposure_status == EXPOSURE_DARK) &&
2679 cam->exposure_count >= DARK_TIME*framerate &&
2680 cam->params.sensorFps.divisor < 3) {
2681
2682 /* dark for too long */
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 < old_exposure/2)
2694 new_exposure += cam->params.flickerControl.coarseJump;
2695 cam->params.exposure.coarseExpLo = new_exposure & 0xff;
2696 cam->params.exposure.coarseExpHi = new_exposure >> 8;
2697 cam->cmd_queue |= COMMAND_SETEXPOSURE;
2698 cam->exposure_status = EXPOSURE_NORMAL;
2699 LOG("Automatically decreasing sensor_fps\n");
2700
2701 } else if((cam->exposure_status == EXPOSURE_VERY_LIGHT ||
2702 cam->exposure_status == EXPOSURE_LIGHT) &&
2703 cam->exposure_count >= LIGHT_TIME*framerate &&
2704 cam->params.sensorFps.divisor > 0) {
2705
2706 /* light for too long */
2707 int max_exp = FIRMWARE_VERSION(1,2) ? MAX_EXP_102 : MAX_EXP ;
2708
2709 --cam->params.sensorFps.divisor;
2710 cam->cmd_queue |= COMMAND_SETSENSORFPS;
2711
2712 cam->params.flickerControl.coarseJump =
2713 flicker_jumps[cam->mainsFreq]
2714 [cam->params.sensorFps.baserate]
2715 [cam->params.sensorFps.divisor];
2716 cam->cmd_queue |= COMMAND_SETFLICKERCTRL;
2717
2718 new_exposure = cam->params.flickerControl.coarseJump-1;
2719 while(new_exposure < 2*old_exposure &&
2720 new_exposure+
2721 cam->params.flickerControl.coarseJump < max_exp)
2722 new_exposure += cam->params.flickerControl.coarseJump;
2723 cam->params.exposure.coarseExpLo = new_exposure & 0xff;
2724 cam->params.exposure.coarseExpHi = new_exposure >> 8;
2725 cam->cmd_queue |= COMMAND_SETEXPOSURE;
2726 cam->exposure_status = EXPOSURE_NORMAL;
2727 LOG("Automatically increasing sensor_fps\n");
2728 }
2729 } else {
2730 /* Flicker control off */
2731 if((cam->exposure_status == EXPOSURE_VERY_DARK ||
2732 cam->exposure_status == EXPOSURE_DARK) &&
2733 cam->exposure_count >= DARK_TIME*framerate &&
2734 cam->params.sensorFps.divisor < 3) {
2735
2736 /* dark for too long */
2737 ++cam->params.sensorFps.divisor;
2738 cam->cmd_queue |= COMMAND_SETSENSORFPS;
2739
2740 if(cam->params.exposure.gain > 0) {
2741 --cam->params.exposure.gain;
2742 cam->cmd_queue |= COMMAND_SETEXPOSURE;
2743 }
2744 cam->exposure_status = EXPOSURE_NORMAL;
2745 LOG("Automatically decreasing sensor_fps\n");
2746
2747 } else if((cam->exposure_status == EXPOSURE_VERY_LIGHT ||
2748 cam->exposure_status == EXPOSURE_LIGHT) &&
2749 cam->exposure_count >= LIGHT_TIME*framerate &&
2750 cam->params.sensorFps.divisor > 0) {
2751
2752 /* light for too long */
2753 --cam->params.sensorFps.divisor;
2754 cam->cmd_queue |= COMMAND_SETSENSORFPS;
2755
2756 if(cam->params.exposure.gain <
2757 cam->params.exposure.gainMode-1) {
2758 ++cam->params.exposure.gain;
2759 cam->cmd_queue |= COMMAND_SETEXPOSURE;
2760 }
2761 cam->exposure_status = EXPOSURE_NORMAL;
2762 LOG("Automatically increasing sensor_fps\n");
2763 }
2764 }
2765 up(&cam->param_lock);
2766}
2767
2768/*-----------------------------------------------------------------*/
2769/* if flicker is switched off, this function switches it back on.It checks,
2770 however, that conditions are suitable before restarting it.
2771 This should only be called for firmware version 1.2.
2772
2773 It also adjust the colour balance when an exposure step is detected - as
2774 long as flicker is running
2775*/
2776static void restart_flicker(struct cam_data *cam)
2777{
2778 int cam_exposure, old_exp;
2779 if(!FIRMWARE_VERSION(1,2))
2780 return;
2781 down(&cam->param_lock);
2782 if(cam->params.flickerControl.flickerMode == 0 ||
2783 cam->raw_image[39] == 0) {
2784 up(&cam->param_lock);
2785 return;
2786 }
2787 cam_exposure = cam->raw_image[39]*2;
2788 old_exp = cam->params.exposure.coarseExpLo +
2789 cam->params.exposure.coarseExpHi*256;
2790 /*
2791 see how far away camera exposure is from a valid
2792 flicker exposure value
2793 */
2794 cam_exposure %= cam->params.flickerControl.coarseJump;
2795 if(!cam->params.flickerControl.disabled &&
2796 cam_exposure <= cam->params.flickerControl.coarseJump - 3) {
2797 /* Flicker control auto-disabled */
2798 cam->params.flickerControl.disabled = 1;
2799 }
2800
2801 if(cam->params.flickerControl.disabled &&
2802 cam->params.flickerControl.flickerMode &&
2803 old_exp > cam->params.flickerControl.coarseJump +
2804 ROUND_UP_EXP_FOR_FLICKER) {
2805 /* exposure is now high enough to switch
2806 flicker control back on */
2807 set_flicker(&cam->params, &cam->cmd_queue, 1);
2808 if((cam->cmd_queue & COMMAND_SETEXPOSURE) &&
2809 cam->params.exposure.expMode == 2)
2810 cam->exposure_status = EXPOSURE_NORMAL;
2811
2812 }
2813 up(&cam->param_lock);
2814}
2815#undef FIRMWARE_VERSION
2816
2817static int clear_stall(struct cam_data *cam)
2818{
2819 /* FIXME: Does this actually work? */
2820 LOG("Clearing stall\n");
2821
2822 cam->ops->streamRead(cam->lowlevel_data, cam->raw_image, 0);
2823 do_command(cam, CPIA_COMMAND_GetCameraStatus,0,0,0,0);
2824 return cam->params.status.streamState != STREAM_PAUSED;
2825}
2826
2827/* kernel thread function to read image from camera */
2828static int fetch_frame(void *data)
2829{
2830 int image_size, retry;
2831 struct cam_data *cam = (struct cam_data *)data;
2832 unsigned long oldjif, rate, diff;
2833
2834 /* Allow up to two bad images in a row to be read and
2835 * ignored before an error is reported */
2836 for (retry = 0; retry < 3; ++retry) {
2837 if (retry)
2838 DBG("retry=%d\n", retry);
2839
2840 if (!cam->ops)
2841 continue;
2842
2843 /* load first frame always uncompressed */
2844 if (cam->first_frame &&
2845 cam->params.compression.mode != CPIA_COMPRESSION_NONE) {
2846 do_command(cam, CPIA_COMMAND_SetCompression,
2847 CPIA_COMPRESSION_NONE,
2848 NO_DECIMATION, 0, 0);
2849 /* Trial & error - Discarding a frame prevents the
2850 first frame from having an error in the data. */
2851 do_command(cam, CPIA_COMMAND_DiscardFrame, 0, 0, 0, 0);
2852 }
2853
2854 /* init camera upload */
2855 if (do_command(cam, CPIA_COMMAND_GrabFrame, 0,
2856 cam->params.streamStartLine, 0, 0))
2857 continue;
2858
2859 if (cam->ops->wait_for_stream_ready) {
2860 /* loop until image ready */
2861 int count = 0;
2862 do_command(cam, CPIA_COMMAND_GetCameraStatus,0,0,0,0);
2863 while (cam->params.status.streamState != STREAM_READY) {
2864 if(++count > READY_TIMEOUT)
2865 break;
2866 if(cam->params.status.streamState ==
2867 STREAM_PAUSED) {
2868 /* Bad news */
2869 if(!clear_stall(cam))
2870 return -EIO;
2871 }
2872
2873 cond_resched();
2874
2875 /* sleep for 10 ms, hopefully ;) */
2876 msleep_interruptible(10);
2877 if (signal_pending(current))
2878 return -EINTR;
2879
2880 do_command(cam, CPIA_COMMAND_GetCameraStatus,
2881 0, 0, 0, 0);
2882 }
2883 if(cam->params.status.streamState != STREAM_READY) {
2884 continue;
2885 }
2886 }
2887
2888 cond_resched();
2889
2890 /* grab image from camera */
2891 oldjif = jiffies;
2892 image_size = cam->ops->streamRead(cam->lowlevel_data,
2893 cam->raw_image, 0);
2894 if (image_size <= 0) {
2895 DBG("streamRead failed: %d\n", image_size);
2896 continue;
2897 }
2898
2899 rate = image_size * HZ / 1024;
2900 diff = jiffies-oldjif;
2901 cam->transfer_rate = diff==0 ? rate : rate/diff;
2902 /* diff==0 ? unlikely but possible */
2903
2904 /* Switch flicker control back on if it got turned off */
2905 restart_flicker(cam);
2906
2907 /* If AEC is enabled, monitor the exposure and
2908 adjust the sensor frame rate if needed */
2909 if(cam->params.exposure.expMode == 2)
2910 monitor_exposure(cam);
2911
2912 /* camera idle now so dispatch queued commands */
2913 dispatch_commands(cam);
2914
2915 /* Update our knowledge of the camera state */
2916 do_command(cam, CPIA_COMMAND_GetColourBalance, 0, 0, 0, 0);
2917 do_command(cam, CPIA_COMMAND_GetExposure, 0, 0, 0, 0);
2918 do_command(cam, CPIA_COMMAND_ReadMCPorts, 0, 0, 0, 0);
2919
2920 /* decompress and convert image to by copying it from
2921 * raw_image to decompressed_frame
2922 */
2923
2924 cond_resched();
2925
2926 cam->image_size = parse_picture(cam, image_size);
2927 if (cam->image_size <= 0) {
2928 DBG("parse_picture failed %d\n", cam->image_size);
2929 if(cam->params.compression.mode !=
2930 CPIA_COMPRESSION_NONE) {
2931 /* Compression may not work right if we
2932 had a bad frame, get the next one
2933 uncompressed. */
2934 cam->first_frame = 1;
2935 do_command(cam, CPIA_COMMAND_SetGrabMode,
2936 CPIA_GRAB_SINGLE, 0, 0, 0);
2937 /* FIXME: Trial & error - need up to 70ms for
2938 the grab mode change to complete ? */
2939 msleep_interruptible(70);
2940 if (signal_pending(current))
2941 return -EINTR;
2942 }
2943 } else
2944 break;
2945 }
2946
2947 if (retry < 3) {
2948 /* FIXME: this only works for double buffering */
2949 if (cam->frame[cam->curframe].state == FRAME_READY) {
2950 memcpy(cam->frame[cam->curframe].data,
2951 cam->decompressed_frame.data,
2952 cam->decompressed_frame.count);
2953 cam->frame[cam->curframe].state = FRAME_DONE;
2954 } else
2955 cam->decompressed_frame.state = FRAME_DONE;
2956
2957 if (cam->first_frame) {
2958 cam->first_frame = 0;
2959 do_command(cam, CPIA_COMMAND_SetCompression,
2960 cam->params.compression.mode,
2961 cam->params.compression.decimation, 0, 0);
2962
2963 /* Switch from single-grab to continuous grab */
2964 do_command(cam, CPIA_COMMAND_SetGrabMode,
2965 CPIA_GRAB_CONTINUOUS, 0, 0, 0);
2966 }
2967 return 0;
2968 }
2969 return -EIO;
2970}
2971
2972static int capture_frame(struct cam_data *cam, struct video_mmap *vm)
2973{
2974 if (!cam->frame_buf) {
2975 /* we do lazy allocation */
2976 int err;
2977 if ((err = allocate_frame_buf(cam)))
2978 return err;
2979 }
2980
2981 cam->curframe = vm->frame;
2982 cam->frame[cam->curframe].state = FRAME_READY;
2983 return fetch_frame(cam);
2984}
2985
2986static int goto_high_power(struct cam_data *cam)
2987{
2988 if (do_command(cam, CPIA_COMMAND_GotoHiPower, 0, 0, 0, 0))
2989 return -EIO;
2990 msleep_interruptible(40); /* windows driver does it too */
2991 if(signal_pending(current))
2992 return -EINTR;
2993 if (do_command(cam, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0))
2994 return -EIO;
2995 if (cam->params.status.systemState == HI_POWER_STATE) {
2996 DBG("camera now in HIGH power state\n");
2997 return 0;
2998 }
2999 printstatus(cam);
3000 return -EIO;
3001}
3002
3003static int goto_low_power(struct cam_data *cam)
3004{
3005 if (do_command(cam, CPIA_COMMAND_GotoLoPower, 0, 0, 0, 0))
3006 return -1;
3007 if (do_command(cam, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0))
3008 return -1;
3009 if (cam->params.status.systemState == LO_POWER_STATE) {
3010 DBG("camera now in LOW power state\n");
3011 return 0;
3012 }
3013 printstatus(cam);
3014 return -1;
3015}
3016
3017static void save_camera_state(struct cam_data *cam)
3018{
3019 if(!(cam->cmd_queue & COMMAND_SETCOLOURBALANCE))
3020 do_command(cam, CPIA_COMMAND_GetColourBalance, 0, 0, 0, 0);
3021 if(!(cam->cmd_queue & COMMAND_SETEXPOSURE))
3022 do_command(cam, CPIA_COMMAND_GetExposure, 0, 0, 0, 0);
3023
3024 DBG("%d/%d/%d/%d/%d/%d/%d/%d\n",
3025 cam->params.exposure.gain,
3026 cam->params.exposure.fineExp,
3027 cam->params.exposure.coarseExpLo,
3028 cam->params.exposure.coarseExpHi,
3029 cam->params.exposure.redComp,
3030 cam->params.exposure.green1Comp,
3031 cam->params.exposure.green2Comp,
3032 cam->params.exposure.blueComp);
3033 DBG("%d/%d/%d\n",
3034 cam->params.colourBalance.redGain,
3035 cam->params.colourBalance.greenGain,
3036 cam->params.colourBalance.blueGain);
3037}
3038
3039static int set_camera_state(struct cam_data *cam)
3040{
3041 cam->cmd_queue = COMMAND_SETCOMPRESSION |
3042 COMMAND_SETCOMPRESSIONTARGET |
3043 COMMAND_SETCOLOURPARAMS |
3044 COMMAND_SETFORMAT |
3045 COMMAND_SETYUVTHRESH |
3046 COMMAND_SETECPTIMING |
3047 COMMAND_SETCOMPRESSIONPARAMS |
3048 COMMAND_SETEXPOSURE |
3049 COMMAND_SETCOLOURBALANCE |
3050 COMMAND_SETSENSORFPS |
3051 COMMAND_SETAPCOR |
3052 COMMAND_SETFLICKERCTRL |
3053 COMMAND_SETVLOFFSET;
3054
3055 do_command(cam, CPIA_COMMAND_SetGrabMode, CPIA_GRAB_SINGLE,0,0,0);
3056 dispatch_commands(cam);
3057
3058 /* Wait 6 frames for the sensor to get all settings and
3059 AEC/ACB to settle */
3060 msleep_interruptible(6*(cam->params.sensorFps.baserate ? 33 : 40) *
3061 (1 << cam->params.sensorFps.divisor) + 10);
3062
3063 if(signal_pending(current))
3064 return -EINTR;
3065
3066 save_camera_state(cam);
3067
3068 return 0;
3069}
3070
3071static void get_version_information(struct cam_data *cam)
3072{
3073 /* GetCPIAVersion */
3074 do_command(cam, CPIA_COMMAND_GetCPIAVersion, 0, 0, 0, 0);
3075
3076 /* GetPnPID */
3077 do_command(cam, CPIA_COMMAND_GetPnPID, 0, 0, 0, 0);
3078}
3079
3080/* initialize camera */
3081static int reset_camera(struct cam_data *cam)
3082{
3083 int err;
3084 /* Start the camera in low power mode */
3085 if (goto_low_power(cam)) {
3086 if (cam->params.status.systemState != WARM_BOOT_STATE)
3087 return -ENODEV;
3088
3089 /* FIXME: this is just dirty trial and error */
3090 err = goto_high_power(cam);
3091 if(err)
3092 return err;
3093 do_command(cam, CPIA_COMMAND_DiscardFrame, 0, 0, 0, 0);
3094 if (goto_low_power(cam))
3095 return -ENODEV;
3096 }
3097
3098 /* procedure described in developer's guide p3-28 */
3099
3100 /* Check the firmware version. */
3101 cam->params.version.firmwareVersion = 0;
3102 get_version_information(cam);
3103 if (cam->params.version.firmwareVersion != 1)
3104 return -ENODEV;
3105
3106 /* A bug in firmware 1-02 limits gainMode to 2 */
3107 if(cam->params.version.firmwareRevision <= 2 &&
3108 cam->params.exposure.gainMode > 2) {
3109 cam->params.exposure.gainMode = 2;
3110 }
3111
3112 /* set QX3 detected flag */
3113 cam->params.qx3.qx3_detected = (cam->params.pnpID.vendor == 0x0813 &&
3114 cam->params.pnpID.product == 0x0001);
3115
3116 /* The fatal error checking should be done after
3117 * the camera powers up (developer's guide p 3-38) */
3118
3119 /* Set streamState before transition to high power to avoid bug
3120 * in firmware 1-02 */
3121 do_command(cam, CPIA_COMMAND_ModifyCameraStatus, STREAMSTATE, 0,
3122 STREAM_NOT_READY, 0);
3123
3124 /* GotoHiPower */
3125 err = goto_high_power(cam);
3126 if (err)
3127 return err;
3128
3129 /* Check the camera status */
3130 if (do_command(cam, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0))
3131 return -EIO;
3132
3133 if (cam->params.status.fatalError) {
3134 DBG("fatal_error: %#04x\n",
3135 cam->params.status.fatalError);
3136 DBG("vp_status: %#04x\n",
3137 cam->params.status.vpStatus);
3138 if (cam->params.status.fatalError & ~(COM_FLAG|CPIA_FLAG)) {
3139 /* Fatal error in camera */
3140 return -EIO;
3141 } else if (cam->params.status.fatalError & (COM_FLAG|CPIA_FLAG)) {
3142 /* Firmware 1-02 may do this for parallel port cameras,
3143 * just clear the flags (developer's guide p 3-38) */
3144 do_command(cam, CPIA_COMMAND_ModifyCameraStatus,
3145 FATALERROR, ~(COM_FLAG|CPIA_FLAG), 0, 0);
3146 }
3147 }
3148
3149 /* Check the camera status again */
3150 if (cam->params.status.fatalError) {
3151 if (cam->params.status.fatalError)
3152 return -EIO;
3153 }
3154
3155 /* VPVersion can't be retrieved before the camera is in HiPower,
3156 * so get it here instead of in get_version_information. */
3157 do_command(cam, CPIA_COMMAND_GetVPVersion, 0, 0, 0, 0);
3158
3159 /* set camera to a known state */
3160 return set_camera_state(cam);
3161}
3162
3163static void put_cam(struct cpia_camera_ops* ops)
3164{
3165 if (ops->owner)
3166 module_put(ops->owner);
3167}
3168
3169/* ------------------------- V4L interface --------------------- */
3170static int cpia_open(struct inode *inode, struct file *file)
3171{
3172 struct video_device *dev = video_devdata(file);
3173 struct cam_data *cam = dev->priv;
3174 int err;
3175
3176 if (!cam) {
3177 DBG("Internal error, cam_data not found!\n");
3178 return -ENODEV;
3179 }
3180
3181 if (cam->open_count > 0) {
3182 DBG("Camera already open\n");
3183 return -EBUSY;
3184 }
3185
3186 if (!try_module_get(cam->ops->owner))
3187 return -ENODEV;
3188
3189 down(&cam->busy_lock);
3190 err = -ENOMEM;
3191 if (!cam->raw_image) {
3192 cam->raw_image = rvmalloc(CPIA_MAX_IMAGE_SIZE);
3193 if (!cam->raw_image)
3194 goto oops;
3195 }
3196
3197 if (!cam->decompressed_frame.data) {
3198 cam->decompressed_frame.data = rvmalloc(CPIA_MAX_FRAME_SIZE);
3199 if (!cam->decompressed_frame.data)
3200 goto oops;
3201 }
3202
3203 /* open cpia */
3204 err = -ENODEV;
3205 if (cam->ops->open(cam->lowlevel_data))
3206 goto oops;
3207
3208 /* reset the camera */
3209 if ((err = reset_camera(cam)) != 0) {
3210 cam->ops->close(cam->lowlevel_data);
3211 goto oops;
3212 }
3213
3214 err = -EINTR;
3215 if(signal_pending(current))
3216 goto oops;
3217
3218 /* Set ownership of /proc/cpia/videoX to current user */
3219 if(cam->proc_entry)
3220 cam->proc_entry->uid = current->uid;
3221
3222 /* set mark for loading first frame uncompressed */
3223 cam->first_frame = 1;
3224
3225 /* init it to something */
3226 cam->mmap_kludge = 0;
3227
3228 ++cam->open_count;
3229 file->private_data = dev;
3230 up(&cam->busy_lock);
3231 return 0;
3232
3233 oops:
3234 if (cam->decompressed_frame.data) {
3235 rvfree(cam->decompressed_frame.data, CPIA_MAX_FRAME_SIZE);
3236 cam->decompressed_frame.data = NULL;
3237 }
3238 if (cam->raw_image) {
3239 rvfree(cam->raw_image, CPIA_MAX_IMAGE_SIZE);
3240 cam->raw_image = NULL;
3241 }
3242 up(&cam->busy_lock);
3243 put_cam(cam->ops);
3244 return err;
3245}
3246
3247static int cpia_close(struct inode *inode, struct file *file)
3248{
3249 struct video_device *dev = file->private_data;
3250 struct cam_data *cam = dev->priv;
3251
3252 if (cam->ops) {
3253 /* Return ownership of /proc/cpia/videoX to root */
3254 if(cam->proc_entry)
3255 cam->proc_entry->uid = 0;
3256
3257 /* save camera state for later open (developers guide ch 3.5.3) */
3258 save_camera_state(cam);
3259
3260 /* GotoLoPower */
3261 goto_low_power(cam);
3262
3263 /* Update the camera status */
3264 do_command(cam, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0);
3265
3266 /* cleanup internal state stuff */
3267 free_frames(cam->frame);
3268
3269 /* close cpia */
3270 cam->ops->close(cam->lowlevel_data);
3271
3272 put_cam(cam->ops);
3273 }
3274
3275 if (--cam->open_count == 0) {
3276 /* clean up capture-buffers */
3277 if (cam->raw_image) {
3278 rvfree(cam->raw_image, CPIA_MAX_IMAGE_SIZE);
3279 cam->raw_image = NULL;
3280 }
3281
3282 if (cam->decompressed_frame.data) {
3283 rvfree(cam->decompressed_frame.data, CPIA_MAX_FRAME_SIZE);
3284 cam->decompressed_frame.data = NULL;
3285 }
3286
3287 if (cam->frame_buf)
3288 free_frame_buf(cam);
3289
3290 if (!cam->ops)
3291 kfree(cam);
3292 }
3293 file->private_data = NULL;
3294
3295 return 0;
3296}
3297
3298static ssize_t cpia_read(struct file *file, char __user *buf,
3299 size_t count, loff_t *ppos)
3300{
3301 struct video_device *dev = file->private_data;
3302 struct cam_data *cam = dev->priv;
3303 int err;
3304
3305 /* make this _really_ smp and multithread-safe */
3306 if (down_interruptible(&cam->busy_lock))
3307 return -EINTR;
3308
3309 if (!buf) {
3310 DBG("buf NULL\n");
3311 up(&cam->busy_lock);
3312 return -EINVAL;
3313 }
3314
3315 if (!count) {
3316 DBG("count 0\n");
3317 up(&cam->busy_lock);
3318 return 0;
3319 }
3320
3321 if (!cam->ops) {
3322 DBG("ops NULL\n");
3323 up(&cam->busy_lock);
3324 return -ENODEV;
3325 }
3326
3327 /* upload frame */
3328 cam->decompressed_frame.state = FRAME_READY;
3329 cam->mmap_kludge=0;
3330 if((err = fetch_frame(cam)) != 0) {
3331 DBG("ERROR from fetch_frame: %d\n", err);
3332 up(&cam->busy_lock);
3333 return err;
3334 }
3335 cam->decompressed_frame.state = FRAME_UNUSED;
3336
3337 /* copy data to user space */
3338 if (cam->decompressed_frame.count > count) {
3339 DBG("count wrong: %d, %lu\n", cam->decompressed_frame.count,
3340 (unsigned long) count);
3341 up(&cam->busy_lock);
3342 return -EFAULT;
3343 }
3344 if (copy_to_user(buf, cam->decompressed_frame.data,
3345 cam->decompressed_frame.count)) {
3346 DBG("copy_to_user failed\n");
3347 up(&cam->busy_lock);
3348 return -EFAULT;
3349 }
3350
3351 up(&cam->busy_lock);
3352 return cam->decompressed_frame.count;
3353}
3354
3355static int cpia_do_ioctl(struct inode *inode, struct file *file,
3356 unsigned int ioctlnr, void *arg)
3357{
3358 struct video_device *dev = file->private_data;
3359 struct cam_data *cam = dev->priv;
3360 int retval = 0;
3361
3362 if (!cam || !cam->ops)
3363 return -ENODEV;
3364
3365 /* make this _really_ smp-safe */
3366 if (down_interruptible(&cam->busy_lock))
3367 return -EINTR;
3368
3369 //DBG("cpia_ioctl: %u\n", ioctlnr);
3370
3371 switch (ioctlnr) {
3372 /* query capabilites */
3373 case VIDIOCGCAP:
3374 {
3375 struct video_capability *b = arg;
3376
3377 DBG("VIDIOCGCAP\n");
3378 strcpy(b->name, "CPiA Camera");
3379 b->type = VID_TYPE_CAPTURE | VID_TYPE_SUBCAPTURE;
3380 b->channels = 1;
3381 b->audios = 0;
3382 b->maxwidth = 352; /* VIDEOSIZE_CIF */
3383 b->maxheight = 288;
3384 b->minwidth = 48; /* VIDEOSIZE_48_48 */
3385 b->minheight = 48;
3386 break;
3387 }
3388
3389 /* get/set video source - we are a camera and nothing else */
3390 case VIDIOCGCHAN:
3391 {
3392 struct video_channel *v = arg;
3393
3394 DBG("VIDIOCGCHAN\n");
3395 if (v->channel != 0) {
3396 retval = -EINVAL;
3397 break;
3398 }
3399
3400 v->channel = 0;
3401 strcpy(v->name, "Camera");
3402 v->tuners = 0;
3403 v->flags = 0;
3404 v->type = VIDEO_TYPE_CAMERA;
3405 v->norm = 0;
3406 break;
3407 }
3408
3409 case VIDIOCSCHAN:
3410 {
3411 struct video_channel *v = arg;
3412
3413 DBG("VIDIOCSCHAN\n");
3414 if (v->channel != 0)
3415 retval = -EINVAL;
3416 break;
3417 }
3418
3419 /* image properties */
3420 case VIDIOCGPICT:
3421 {
3422 struct video_picture *pic = arg;
3423 DBG("VIDIOCGPICT\n");
3424 *pic = cam->vp;
3425 break;
3426 }
3427
3428 case VIDIOCSPICT:
3429 {
3430 struct video_picture *vp = arg;
3431
3432 DBG("VIDIOCSPICT\n");
3433
3434 /* check validity */
3435 DBG("palette: %d\n", vp->palette);
3436 DBG("depth: %d\n", vp->depth);
3437 if (!valid_mode(vp->palette, vp->depth)) {
3438 retval = -EINVAL;
3439 break;
3440 }
3441
3442 down(&cam->param_lock);
3443 /* brightness, colour, contrast need no check 0-65535 */
3444 cam->vp = *vp;
3445 /* update cam->params.colourParams */
3446 cam->params.colourParams.brightness = vp->brightness*100/65535;
3447 cam->params.colourParams.contrast = vp->contrast*100/65535;
3448 cam->params.colourParams.saturation = vp->colour*100/65535;
3449 /* contrast is in steps of 8, so round */
3450 cam->params.colourParams.contrast =
3451 ((cam->params.colourParams.contrast + 3) / 8) * 8;
3452 if (cam->params.version.firmwareVersion == 1 &&
3453 cam->params.version.firmwareRevision == 2 &&
3454 cam->params.colourParams.contrast > 80) {
3455 /* 1-02 firmware limits contrast to 80 */
3456 cam->params.colourParams.contrast = 80;
3457 }
3458
3459 /* Adjust flicker control if necessary */
3460 if(cam->params.flickerControl.allowableOverExposure < 0)
3461 cam->params.flickerControl.allowableOverExposure =
3462 -find_over_exposure(cam->params.colourParams.brightness);
3463 if(cam->params.flickerControl.flickerMode != 0)
3464 cam->cmd_queue |= COMMAND_SETFLICKERCTRL;
3465
3466
3467 /* queue command to update camera */
3468 cam->cmd_queue |= COMMAND_SETCOLOURPARAMS;
3469 up(&cam->param_lock);
3470 DBG("VIDIOCSPICT: %d / %d // %d / %d / %d / %d\n",
3471 vp->depth, vp->palette, vp->brightness, vp->hue, vp->colour,
3472 vp->contrast);
3473 break;
3474 }
3475
3476 /* get/set capture window */
3477 case VIDIOCGWIN:
3478 {
3479 struct video_window *vw = arg;
3480 DBG("VIDIOCGWIN\n");
3481
3482 *vw = cam->vw;
3483 break;
3484 }
3485
3486 case VIDIOCSWIN:
3487 {
3488 /* copy_from_user, check validity, copy to internal structure */
3489 struct video_window *vw = arg;
3490 DBG("VIDIOCSWIN\n");
3491
3492 if (vw->clipcount != 0) { /* clipping not supported */
3493 retval = -EINVAL;
3494 break;
3495 }
3496 if (vw->clips != NULL) { /* clipping not supported */
3497 retval = -EINVAL;
3498 break;
3499 }
3500
3501 /* we set the video window to something smaller or equal to what
3502 * is requested by the user???
3503 */
3504 down(&cam->param_lock);
3505 if (vw->width != cam->vw.width || vw->height != cam->vw.height) {
3506 int video_size = match_videosize(vw->width, vw->height);
3507
3508 if (video_size < 0) {
3509 retval = -EINVAL;
3510 up(&cam->param_lock);
3511 break;
3512 }
3513 cam->video_size = video_size;
3514
3515 /* video size is changing, reset the subcapture area */
3516 memset(&cam->vc, 0, sizeof(cam->vc));
3517
3518 set_vw_size(cam);
3519 DBG("%d / %d\n", cam->vw.width, cam->vw.height);
3520 cam->cmd_queue |= COMMAND_SETFORMAT;
3521 }
3522
3523 up(&cam->param_lock);
3524
3525 /* setformat ignored by camera during streaming,
3526 * so stop/dispatch/start */
3527 if (cam->cmd_queue & COMMAND_SETFORMAT) {
3528 DBG("\n");
3529 dispatch_commands(cam);
3530 }
3531 DBG("%d/%d:%d\n", cam->video_size,
3532 cam->vw.width, cam->vw.height);
3533 break;
3534 }
3535
3536 /* mmap interface */
3537 case VIDIOCGMBUF:
3538 {
3539 struct video_mbuf *vm = arg;
3540 int i;
3541
3542 DBG("VIDIOCGMBUF\n");
3543 memset(vm, 0, sizeof(*vm));
3544 vm->size = CPIA_MAX_FRAME_SIZE*FRAME_NUM;
3545 vm->frames = FRAME_NUM;
3546 for (i = 0; i < FRAME_NUM; i++)
3547 vm->offsets[i] = CPIA_MAX_FRAME_SIZE * i;
3548 break;
3549 }
3550
3551 case VIDIOCMCAPTURE:
3552 {
3553 struct video_mmap *vm = arg;
3554 int video_size;
3555
3556 DBG("VIDIOCMCAPTURE: %d / %d / %dx%d\n", vm->format, vm->frame,
3557 vm->width, vm->height);
3558 if (vm->frame<0||vm->frame>=FRAME_NUM) {
3559 retval = -EINVAL;
3560 break;
3561 }
3562
3563 /* set video format */
3564 cam->vp.palette = vm->format;
3565 switch(vm->format) {
3566 case VIDEO_PALETTE_GREY:
3567 cam->vp.depth=8;
3568 break;
3569 case VIDEO_PALETTE_RGB555:
3570 case VIDEO_PALETTE_RGB565:
3571 case VIDEO_PALETTE_YUV422:
3572 case VIDEO_PALETTE_YUYV:
3573 case VIDEO_PALETTE_UYVY:
3574 cam->vp.depth = 16;
3575 break;
3576 case VIDEO_PALETTE_RGB24:
3577 cam->vp.depth = 24;
3578 break;
3579 case VIDEO_PALETTE_RGB32:
3580 cam->vp.depth = 32;
3581 break;
3582 default:
3583 retval = -EINVAL;
3584 break;
3585 }
3586 if (retval)
3587 break;
3588
3589 /* set video size */
3590 video_size = match_videosize(vm->width, vm->height);
3591 if (video_size < 0) {
3592 retval = -EINVAL;
3593 break;
3594 }
3595 if (video_size != cam->video_size) {
3596 cam->video_size = video_size;
3597
3598 /* video size is changing, reset the subcapture area */
3599 memset(&cam->vc, 0, sizeof(cam->vc));
3600
3601 set_vw_size(cam);
3602 cam->cmd_queue |= COMMAND_SETFORMAT;
3603 dispatch_commands(cam);
3604 }
3605 /* according to v4l-spec we must start streaming here */
3606 cam->mmap_kludge = 1;
3607 retval = capture_frame(cam, vm);
3608
3609 break;
3610 }
3611
3612 case VIDIOCSYNC:
3613 {
3614 int *frame = arg;
3615
3616 //DBG("VIDIOCSYNC: %d\n", *frame);
3617
3618 if (*frame<0 || *frame >= FRAME_NUM) {
3619 retval = -EINVAL;
3620 break;
3621 }
3622
3623 switch (cam->frame[*frame].state) {
3624 case FRAME_UNUSED:
3625 case FRAME_READY:
3626 case FRAME_GRABBING:
3627 DBG("sync to unused frame %d\n", *frame);
3628 retval = -EINVAL;
3629 break;
3630
3631 case FRAME_DONE:
3632 cam->frame[*frame].state = FRAME_UNUSED;
3633 //DBG("VIDIOCSYNC: %d synced\n", *frame);
3634 break;
3635 }
3636 if (retval == -EINTR) {
3637 /* FIXME - xawtv does not handle this nice */
3638 retval = 0;
3639 }
3640 break;
3641 }
3642
3643 case VIDIOCGCAPTURE:
3644 {
3645 struct video_capture *vc = arg;
3646
3647 DBG("VIDIOCGCAPTURE\n");
3648
3649 *vc = cam->vc;
3650
3651 break;
3652 }
3653
3654 case VIDIOCSCAPTURE:
3655 {
3656 struct video_capture *vc = arg;
3657
3658 DBG("VIDIOCSCAPTURE\n");
3659
3660 if (vc->decimation != 0) { /* How should this be used? */
3661 retval = -EINVAL;
3662 break;
3663 }
3664 if (vc->flags != 0) { /* Even/odd grab not supported */
3665 retval = -EINVAL;
3666 break;
3667 }
3668
3669 /* Clip to the resolution we can set for the ROI
3670 (every 8 columns and 4 rows) */
3671 vc->x = vc->x & ~(__u32)7;
3672 vc->y = vc->y & ~(__u32)3;
3673 vc->width = vc->width & ~(__u32)7;
3674 vc->height = vc->height & ~(__u32)3;
3675
3676 if(vc->width == 0 || vc->height == 0 ||
3677 vc->x + vc->width > cam->vw.width ||
3678 vc->y + vc->height > cam->vw.height) {
3679 retval = -EINVAL;
3680 break;
3681 }
3682
3683 DBG("%d,%d/%dx%d\n", vc->x,vc->y,vc->width, vc->height);
3684
3685 down(&cam->param_lock);
3686
3687 cam->vc.x = vc->x;
3688 cam->vc.y = vc->y;
3689 cam->vc.width = vc->width;
3690 cam->vc.height = vc->height;
3691
3692 set_vw_size(cam);
3693 cam->cmd_queue |= COMMAND_SETFORMAT;
3694
3695 up(&cam->param_lock);
3696
3697 /* setformat ignored by camera during streaming,
3698 * so stop/dispatch/start */
3699 dispatch_commands(cam);
3700 break;
3701 }
3702
3703 case VIDIOCGUNIT:
3704 {
3705 struct video_unit *vu = arg;
3706
3707 DBG("VIDIOCGUNIT\n");
3708
3709 vu->video = cam->vdev.minor;
3710 vu->vbi = VIDEO_NO_UNIT;
3711 vu->radio = VIDEO_NO_UNIT;
3712 vu->audio = VIDEO_NO_UNIT;
3713 vu->teletext = VIDEO_NO_UNIT;
3714
3715 break;
3716 }
3717
3718
3719 /* pointless to implement overlay with this camera */
3720 case VIDIOCCAPTURE:
3721 case VIDIOCGFBUF:
3722 case VIDIOCSFBUF:
3723 case VIDIOCKEY:
3724 /* tuner interface - we have none */
3725 case VIDIOCGTUNER:
3726 case VIDIOCSTUNER:
3727 case VIDIOCGFREQ:
3728 case VIDIOCSFREQ:
3729 /* audio interface - we have none */
3730 case VIDIOCGAUDIO:
3731 case VIDIOCSAUDIO:
3732 retval = -EINVAL;
3733 break;
3734 default:
3735 retval = -ENOIOCTLCMD;
3736 break;
3737 }
3738
3739 up(&cam->busy_lock);
3740 return retval;
3741}
3742
3743static int cpia_ioctl(struct inode *inode, struct file *file,
3744 unsigned int cmd, unsigned long arg)
3745{
3746 return video_usercopy(inode, file, cmd, arg, cpia_do_ioctl);
3747}
3748
3749
3750/* FIXME */
3751static int cpia_mmap(struct file *file, struct vm_area_struct *vma)
3752{
3753 struct video_device *dev = file->private_data;
3754 unsigned long start = vma->vm_start;
3755 unsigned long size = vma->vm_end - vma->vm_start;
3756 unsigned long page, pos;
3757 struct cam_data *cam = dev->priv;
3758 int retval;
3759
3760 if (!cam || !cam->ops)
3761 return -ENODEV;
3762
3763 DBG("cpia_mmap: %ld\n", size);
3764
3765 if (size > FRAME_NUM*CPIA_MAX_FRAME_SIZE)
3766 return -EINVAL;
3767
3768 if (!cam || !cam->ops)
3769 return -ENODEV;
3770
3771 /* make this _really_ smp-safe */
3772 if (down_interruptible(&cam->busy_lock))
3773 return -EINTR;
3774
3775 if (!cam->frame_buf) { /* we do lazy allocation */
3776 if ((retval = allocate_frame_buf(cam))) {
3777 up(&cam->busy_lock);
3778 return retval;
3779 }
3780 }
3781
3782 pos = (unsigned long)(cam->frame_buf);
3783 while (size > 0) {
3784 page = vmalloc_to_pfn((void *)pos);
3785 if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) {
3786 up(&cam->busy_lock);
3787 return -EAGAIN;
3788 }
3789 start += PAGE_SIZE;
3790 pos += PAGE_SIZE;
3791 if (size > PAGE_SIZE)
3792 size -= PAGE_SIZE;
3793 else
3794 size = 0;
3795 }
3796
3797 DBG("cpia_mmap: %ld\n", size);
3798 up(&cam->busy_lock);
3799
3800 return 0;
3801}
3802
3803static struct file_operations cpia_fops = {
3804 .owner = THIS_MODULE,
3805 .open = cpia_open,
3806 .release = cpia_close,
3807 .read = cpia_read,
3808 .mmap = cpia_mmap,
3809 .ioctl = cpia_ioctl,
3810 .llseek = no_llseek,
3811};
3812
3813static struct video_device cpia_template = {
3814 .owner = THIS_MODULE,
3815 .name = "CPiA Camera",
3816 .type = VID_TYPE_CAPTURE,
3817 .hardware = VID_HARDWARE_CPIA,
3818 .fops = &cpia_fops,
3819};
3820
3821/* initialise cam_data structure */
3822static void reset_camera_struct(struct cam_data *cam)
3823{
3824 /* The following parameter values are the defaults from
3825 * "Software Developer's Guide for CPiA Cameras". Any changes
3826 * to the defaults are noted in comments. */
3827 cam->params.colourParams.brightness = 50;
3828 cam->params.colourParams.contrast = 48;
3829 cam->params.colourParams.saturation = 50;
3830 cam->params.exposure.gainMode = 4;
3831 cam->params.exposure.expMode = 2; /* AEC */
3832 cam->params.exposure.compMode = 1;
3833 cam->params.exposure.centreWeight = 1;
3834 cam->params.exposure.gain = 0;
3835 cam->params.exposure.fineExp = 0;
3836 cam->params.exposure.coarseExpLo = 185;
3837 cam->params.exposure.coarseExpHi = 0;
3838 cam->params.exposure.redComp = COMP_RED;
3839 cam->params.exposure.green1Comp = COMP_GREEN1;
3840 cam->params.exposure.green2Comp = COMP_GREEN2;
3841 cam->params.exposure.blueComp = COMP_BLUE;
3842 cam->params.colourBalance.balanceMode = 2; /* ACB */
3843 cam->params.colourBalance.redGain = 32;
3844 cam->params.colourBalance.greenGain = 6;
3845 cam->params.colourBalance.blueGain = 92;
3846 cam->params.apcor.gain1 = 0x18;
3847 cam->params.apcor.gain2 = 0x16;
3848 cam->params.apcor.gain4 = 0x24;
3849 cam->params.apcor.gain8 = 0x34;
3850 cam->params.flickerControl.flickerMode = 0;
3851 cam->params.flickerControl.disabled = 1;
3852
3853 cam->params.flickerControl.coarseJump =
3854 flicker_jumps[cam->mainsFreq]
3855 [cam->params.sensorFps.baserate]
3856 [cam->params.sensorFps.divisor];
3857 cam->params.flickerControl.allowableOverExposure =
3858 -find_over_exposure(cam->params.colourParams.brightness);
3859 cam->params.vlOffset.gain1 = 20;
3860 cam->params.vlOffset.gain2 = 24;
3861 cam->params.vlOffset.gain4 = 26;
3862 cam->params.vlOffset.gain8 = 26;
3863 cam->params.compressionParams.hysteresis = 3;
3864 cam->params.compressionParams.threshMax = 11;
3865 cam->params.compressionParams.smallStep = 1;
3866 cam->params.compressionParams.largeStep = 3;
3867 cam->params.compressionParams.decimationHysteresis = 2;
3868 cam->params.compressionParams.frDiffStepThresh = 5;
3869 cam->params.compressionParams.qDiffStepThresh = 3;
3870 cam->params.compressionParams.decimationThreshMod = 2;
3871 /* End of default values from Software Developer's Guide */
3872
3873 cam->transfer_rate = 0;
3874 cam->exposure_status = EXPOSURE_NORMAL;
3875
3876 /* Set Sensor FPS to 15fps. This seems better than 30fps
3877 * for indoor lighting. */
3878 cam->params.sensorFps.divisor = 1;
3879 cam->params.sensorFps.baserate = 1;
3880
3881 cam->params.yuvThreshold.yThreshold = 6; /* From windows driver */
3882 cam->params.yuvThreshold.uvThreshold = 6; /* From windows driver */
3883
3884 cam->params.format.subSample = SUBSAMPLE_422;
3885 cam->params.format.yuvOrder = YUVORDER_YUYV;
3886
3887 cam->params.compression.mode = CPIA_COMPRESSION_AUTO;
3888 cam->params.compressionTarget.frTargeting =
3889 CPIA_COMPRESSION_TARGET_QUALITY;
3890 cam->params.compressionTarget.targetFR = 15; /* From windows driver */
3891 cam->params.compressionTarget.targetQ = 5; /* From windows driver */
3892
3893 cam->params.qx3.qx3_detected = 0;
3894 cam->params.qx3.toplight = 0;
3895 cam->params.qx3.bottomlight = 0;
3896 cam->params.qx3.button = 0;
3897 cam->params.qx3.cradled = 0;
3898
3899 cam->video_size = VIDEOSIZE_CIF;
3900
3901 cam->vp.colour = 32768; /* 50% */
3902 cam->vp.hue = 32768; /* 50% */
3903 cam->vp.brightness = 32768; /* 50% */
3904 cam->vp.contrast = 32768; /* 50% */
3905 cam->vp.whiteness = 0; /* not used -> grayscale only */
3906 cam->vp.depth = 24; /* to be set by user */
3907 cam->vp.palette = VIDEO_PALETTE_RGB24; /* to be set by user */
3908
3909 cam->vc.x = 0;
3910 cam->vc.y = 0;
3911 cam->vc.width = 0;
3912 cam->vc.height = 0;
3913
3914 cam->vw.x = 0;
3915 cam->vw.y = 0;
3916 set_vw_size(cam);
3917 cam->vw.chromakey = 0;
3918 cam->vw.flags = 0;
3919 cam->vw.clipcount = 0;
3920 cam->vw.clips = NULL;
3921
3922 cam->cmd_queue = COMMAND_NONE;
3923 cam->first_frame = 1;
3924
3925 return;
3926}
3927
3928/* initialize cam_data structure */
3929static void init_camera_struct(struct cam_data *cam,
3930 struct cpia_camera_ops *ops )
3931{
3932 int i;
3933
3934 /* Default everything to 0 */
3935 memset(cam, 0, sizeof(struct cam_data));
3936
3937 cam->ops = ops;
3938 init_MUTEX(&cam->param_lock);
3939 init_MUTEX(&cam->busy_lock);
3940
3941 reset_camera_struct(cam);
3942
3943 cam->proc_entry = NULL;
3944
3945 memcpy(&cam->vdev, &cpia_template, sizeof(cpia_template));
3946 cam->vdev.priv = cam;
3947
3948 cam->curframe = 0;
3949 for (i = 0; i < FRAME_NUM; i++) {
3950 cam->frame[i].width = 0;
3951 cam->frame[i].height = 0;
3952 cam->frame[i].state = FRAME_UNUSED;
3953 cam->frame[i].data = NULL;
3954 }
3955 cam->decompressed_frame.width = 0;
3956 cam->decompressed_frame.height = 0;
3957 cam->decompressed_frame.state = FRAME_UNUSED;
3958 cam->decompressed_frame.data = NULL;
3959}
3960
3961struct cam_data *cpia_register_camera(struct cpia_camera_ops *ops, void *lowlevel)
3962{
3963 struct cam_data *camera;
3964
3965 if ((camera = kmalloc(sizeof(struct cam_data), GFP_KERNEL)) == NULL)
3966 return NULL;
3967
3968
3969 init_camera_struct( camera, ops );
3970 camera->lowlevel_data = lowlevel;
3971
3972 /* register v4l device */
3973 if (video_register_device(&camera->vdev, VFL_TYPE_GRABBER, video_nr) == -1) {
3974 kfree(camera);
3975 printk(KERN_DEBUG "video_register_device failed\n");
3976 return NULL;
3977 }
3978
3979 /* get version information from camera: open/reset/close */
3980
3981 /* open cpia */
3982 if (camera->ops->open(camera->lowlevel_data))
3983 return camera;
3984
3985 /* reset the camera */
3986 if (reset_camera(camera) != 0) {
3987 camera->ops->close(camera->lowlevel_data);
3988 return camera;
3989 }
3990
3991 /* close cpia */
3992 camera->ops->close(camera->lowlevel_data);
3993
3994#ifdef CONFIG_PROC_FS
3995 create_proc_cpia_cam(camera);
3996#endif
3997
3998 printk(KERN_INFO " CPiA Version: %d.%02d (%d.%d)\n",
3999 camera->params.version.firmwareVersion,
4000 camera->params.version.firmwareRevision,
4001 camera->params.version.vcVersion,
4002 camera->params.version.vcRevision);
4003 printk(KERN_INFO " CPiA PnP-ID: %04x:%04x:%04x\n",
4004 camera->params.pnpID.vendor,
4005 camera->params.pnpID.product,
4006 camera->params.pnpID.deviceRevision);
4007 printk(KERN_INFO " VP-Version: %d.%d %04x\n",
4008 camera->params.vpVersion.vpVersion,
4009 camera->params.vpVersion.vpRevision,
4010 camera->params.vpVersion.cameraHeadID);
4011
4012 return camera;
4013}
4014
4015void cpia_unregister_camera(struct cam_data *cam)
4016{
4017 DBG("unregistering video\n");
4018 video_unregister_device(&cam->vdev);
4019 if (cam->open_count) {
4020 put_cam(cam->ops);
4021 DBG("camera open -- setting ops to NULL\n");
4022 cam->ops = NULL;
4023 }
4024
4025#ifdef CONFIG_PROC_FS
4026 DBG("destroying /proc/cpia/video%d\n", cam->vdev.minor);
4027 destroy_proc_cpia_cam(cam);
4028#endif
4029 if (!cam->open_count) {
4030 DBG("freeing camera\n");
4031 kfree(cam);
4032 }
4033}
4034
4035static int __init cpia_init(void)
4036{
4037 printk(KERN_INFO "%s v%d.%d.%d\n", ABOUT,
4038 CPIA_MAJ_VER, CPIA_MIN_VER, CPIA_PATCH_VER);
4039
4040 printk(KERN_WARNING "Since in-kernel colorspace conversion is not "
4041 "allowed, it is disabled by default now. Users should fix the "
4042 "applications in case they don't work without conversion "
4043 "reenabled by setting the 'colorspace_conv' module "
4044 "parameter to 1");
4045
4046#ifdef CONFIG_PROC_FS
4047 proc_cpia_create();
4048#endif
4049
4050#ifdef CONFIG_VIDEO_CPIA_PP
4051 cpia_pp_init();
4052#endif
4053#ifdef CONFIG_VIDEO_CPIA_USB
4054 cpia_usb_init();
4055#endif
4056
4057 return 0;
4058}
4059
4060static void __exit cpia_exit(void)
4061{
4062#ifdef CONFIG_PROC_FS
4063 proc_cpia_destroy();
4064#endif
4065}
4066
4067module_init(cpia_init);
4068module_exit(cpia_exit);
4069
4070/* Exported symbols for modules. */
4071
4072EXPORT_SYMBOL(cpia_register_camera);
4073EXPORT_SYMBOL(cpia_unregister_camera);
diff --git a/drivers/media/video/cpia.h b/drivers/media/video/cpia.h
new file mode 100644
index 00000000000..f629b693ee6
--- /dev/null
+++ b/drivers/media/video/cpia.h
@@ -0,0 +1,430 @@
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 <linux/list.h>
49#include <linux/smp_lock.h>
50
51struct cpia_camera_ops
52{
53 /* open sets privdata to point to structure for this camera.
54 * Returns negative value on error, otherwise 0.
55 */
56 int (*open)(void *privdata);
57
58 /* Registers callback function cb to be called with cbdata
59 * when an image is ready. If cb is NULL, only single image grabs
60 * should be used. cb should immediately call streamRead to read
61 * the data or data may be lost. Returns negative value on error,
62 * otherwise 0.
63 */
64 int (*registerCallback)(void *privdata, void (*cb)(void *cbdata),
65 void *cbdata);
66
67 /* transferCmd sends commands to the camera. command MUST point to
68 * an 8 byte buffer in kernel space. data can be NULL if no extra
69 * data is needed. The size of the data is given by the last 2
70 * bytes of command. data must also point to memory in kernel space.
71 * Returns negative value on error, otherwise 0.
72 */
73 int (*transferCmd)(void *privdata, u8 *command, u8 *data);
74
75 /* streamStart initiates stream capture mode.
76 * Returns negative value on error, otherwise 0.
77 */
78 int (*streamStart)(void *privdata);
79
80 /* streamStop terminates stream capture mode.
81 * Returns negative value on error, otherwise 0.
82 */
83 int (*streamStop)(void *privdata);
84
85 /* streamRead reads a frame from the camera. buffer points to a
86 * buffer large enough to hold a complete frame in kernel space.
87 * noblock indicates if this should be a non blocking read.
88 * Returns the number of bytes read, or negative value on error.
89 */
90 int (*streamRead)(void *privdata, u8 *buffer, int noblock);
91
92 /* close disables the device until open() is called again.
93 * Returns negative value on error, otherwise 0.
94 */
95 int (*close)(void *privdata);
96
97 /* If wait_for_stream_ready is non-zero, wait until the streamState
98 * is STREAM_READY before calling streamRead.
99 */
100 int wait_for_stream_ready;
101
102 /*
103 * Used to maintain lowlevel module usage counts
104 */
105 struct module *owner;
106};
107
108struct cpia_frame {
109 u8 *data;
110 int count;
111 int width;
112 int height;
113 volatile int state;
114};
115
116struct cam_params {
117 struct {
118 u8 firmwareVersion;
119 u8 firmwareRevision;
120 u8 vcVersion;
121 u8 vcRevision;
122 } version;
123 struct {
124 u16 vendor;
125 u16 product;
126 u16 deviceRevision;
127 } pnpID;
128 struct {
129 u8 vpVersion;
130 u8 vpRevision;
131 u16 cameraHeadID;
132 } vpVersion;
133 struct {
134 u8 systemState;
135 u8 grabState;
136 u8 streamState;
137 u8 fatalError;
138 u8 cmdError;
139 u8 debugFlags;
140 u8 vpStatus;
141 u8 errorCode;
142 } status;
143 struct {
144 u8 brightness;
145 u8 contrast;
146 u8 saturation;
147 } colourParams;
148 struct {
149 u8 gainMode;
150 u8 expMode;
151 u8 compMode;
152 u8 centreWeight;
153 u8 gain;
154 u8 fineExp;
155 u8 coarseExpLo;
156 u8 coarseExpHi;
157 u8 redComp;
158 u8 green1Comp;
159 u8 green2Comp;
160 u8 blueComp;
161 } exposure;
162 struct {
163 u8 balanceMode;
164 u8 redGain;
165 u8 greenGain;
166 u8 blueGain;
167 } colourBalance;
168 struct {
169 u8 divisor;
170 u8 baserate;
171 } sensorFps;
172 struct {
173 u8 gain1;
174 u8 gain2;
175 u8 gain4;
176 u8 gain8;
177 } apcor;
178 struct {
179 u8 disabled;
180 u8 flickerMode;
181 u8 coarseJump;
182 int allowableOverExposure;
183 } flickerControl;
184 struct {
185 u8 gain1;
186 u8 gain2;
187 u8 gain4;
188 u8 gain8;
189 } vlOffset;
190 struct {
191 u8 mode;
192 u8 decimation;
193 } compression;
194 struct {
195 u8 frTargeting;
196 u8 targetFR;
197 u8 targetQ;
198 } compressionTarget;
199 struct {
200 u8 yThreshold;
201 u8 uvThreshold;
202 } yuvThreshold;
203 struct {
204 u8 hysteresis;
205 u8 threshMax;
206 u8 smallStep;
207 u8 largeStep;
208 u8 decimationHysteresis;
209 u8 frDiffStepThresh;
210 u8 qDiffStepThresh;
211 u8 decimationThreshMod;
212 } compressionParams;
213 struct {
214 u8 videoSize; /* CIF/QCIF */
215 u8 subSample;
216 u8 yuvOrder;
217 } format;
218 struct { /* Intel QX3 specific data */
219 u8 qx3_detected; /* a QX3 is present */
220 u8 toplight; /* top light lit , R/W */
221 u8 bottomlight; /* bottom light lit, R/W */
222 u8 button; /* snapshot button pressed (R/O) */
223 u8 cradled; /* microscope is in cradle (R/O) */
224 } qx3;
225 struct {
226 u8 colStart; /* skip first 8*colStart pixels */
227 u8 colEnd; /* finish at 8*colEnd pixels */
228 u8 rowStart; /* skip first 4*rowStart lines */
229 u8 rowEnd; /* finish at 4*rowEnd lines */
230 } roi;
231 u8 ecpTiming;
232 u8 streamStartLine;
233};
234
235enum v4l_camstates {
236 CPIA_V4L_IDLE = 0,
237 CPIA_V4L_ERROR,
238 CPIA_V4L_COMMAND,
239 CPIA_V4L_GRABBING,
240 CPIA_V4L_STREAMING,
241 CPIA_V4L_STREAMING_PAUSED,
242};
243
244#define FRAME_NUM 2 /* double buffering for now */
245
246struct cam_data {
247 struct list_head cam_data_list;
248
249 struct semaphore busy_lock; /* guard against SMP multithreading */
250 struct cpia_camera_ops *ops; /* lowlevel driver operations */
251 void *lowlevel_data; /* private data for lowlevel driver */
252 u8 *raw_image; /* buffer for raw image data */
253 struct cpia_frame decompressed_frame;
254 /* buffer to hold decompressed frame */
255 int image_size; /* sizeof last decompressed image */
256 int open_count; /* # of process that have camera open */
257
258 /* camera status */
259 int fps; /* actual fps reported by the camera */
260 int transfer_rate; /* transfer rate from camera in kB/s */
261 u8 mainsFreq; /* for flicker control */
262
263 /* proc interface */
264 struct semaphore param_lock; /* params lock for this camera */
265 struct cam_params params; /* camera settings */
266 struct proc_dir_entry *proc_entry; /* /proc/cpia/videoX */
267
268 /* v4l */
269 int video_size; /* VIDEO_SIZE_ */
270 volatile enum v4l_camstates camstate; /* v4l layer status */
271 struct video_device vdev; /* v4l videodev */
272 struct video_picture vp; /* v4l camera settings */
273 struct video_window vw; /* v4l capture area */
274 struct video_capture vc; /* v4l subcapture area */
275
276 /* mmap interface */
277 int curframe; /* the current frame to grab into */
278 u8 *frame_buf; /* frame buffer data */
279 struct cpia_frame frame[FRAME_NUM];
280 /* FRAME_NUM-buffering, so we need a array */
281
282 int first_frame;
283 int mmap_kludge; /* 'wrong' byte order for mmap */
284 volatile u32 cmd_queue; /* queued commands */
285 int exposure_status; /* EXPOSURE_* */
286 int exposure_count; /* number of frames at this status */
287};
288
289/* cpia_register_camera is called by low level driver for each camera.
290 * A unique camera number is returned, or a negative value on error */
291struct cam_data *cpia_register_camera(struct cpia_camera_ops *ops, void *lowlevel);
292
293/* cpia_unregister_camera is called by low level driver when a camera
294 * is removed. This must not fail. */
295void cpia_unregister_camera(struct cam_data *cam);
296
297/* raw CIF + 64 byte header + (2 bytes line_length + EOL) per line + 4*EOI +
298 * one byte 16bit DMA alignment
299 */
300#define CPIA_MAX_IMAGE_SIZE ((352*288*2)+64+(288*3)+5)
301
302/* constant value's */
303#define MAGIC_0 0x19
304#define MAGIC_1 0x68
305#define DATA_IN 0xC0
306#define DATA_OUT 0x40
307#define VIDEOSIZE_QCIF 0 /* 176x144 */
308#define VIDEOSIZE_CIF 1 /* 352x288 */
309#define VIDEOSIZE_SIF 2 /* 320x240 */
310#define VIDEOSIZE_QSIF 3 /* 160x120 */
311#define VIDEOSIZE_48_48 4 /* where no one has gone before, iconsize! */
312#define VIDEOSIZE_64_48 5
313#define VIDEOSIZE_128_96 6
314#define VIDEOSIZE_160_120 VIDEOSIZE_QSIF
315#define VIDEOSIZE_176_144 VIDEOSIZE_QCIF
316#define VIDEOSIZE_192_144 7
317#define VIDEOSIZE_224_168 8
318#define VIDEOSIZE_256_192 9
319#define VIDEOSIZE_288_216 10
320#define VIDEOSIZE_320_240 VIDEOSIZE_SIF
321#define VIDEOSIZE_352_288 VIDEOSIZE_CIF
322#define VIDEOSIZE_88_72 11 /* quarter CIF */
323#define SUBSAMPLE_420 0
324#define SUBSAMPLE_422 1
325#define YUVORDER_YUYV 0
326#define YUVORDER_UYVY 1
327#define NOT_COMPRESSED 0
328#define COMPRESSED 1
329#define NO_DECIMATION 0
330#define DECIMATION_ENAB 1
331#define EOI 0xff /* End Of Image */
332#define EOL 0xfd /* End Of Line */
333#define FRAME_HEADER_SIZE 64
334
335/* Image grab modes */
336#define CPIA_GRAB_SINGLE 0
337#define CPIA_GRAB_CONTINUOUS 1
338
339/* Compression parameters */
340#define CPIA_COMPRESSION_NONE 0
341#define CPIA_COMPRESSION_AUTO 1
342#define CPIA_COMPRESSION_MANUAL 2
343#define CPIA_COMPRESSION_TARGET_QUALITY 0
344#define CPIA_COMPRESSION_TARGET_FRAMERATE 1
345
346/* Return offsets for GetCameraState */
347#define SYSTEMSTATE 0
348#define GRABSTATE 1
349#define STREAMSTATE 2
350#define FATALERROR 3
351#define CMDERROR 4
352#define DEBUGFLAGS 5
353#define VPSTATUS 6
354#define ERRORCODE 7
355
356/* SystemState */
357#define UNINITIALISED_STATE 0
358#define PASS_THROUGH_STATE 1
359#define LO_POWER_STATE 2
360#define HI_POWER_STATE 3
361#define WARM_BOOT_STATE 4
362
363/* GrabState */
364#define GRAB_IDLE 0
365#define GRAB_ACTIVE 1
366#define GRAB_DONE 2
367
368/* StreamState */
369#define STREAM_NOT_READY 0
370#define STREAM_READY 1
371#define STREAM_OPEN 2
372#define STREAM_PAUSED 3
373#define STREAM_FINISHED 4
374
375/* Fatal Error, CmdError, and DebugFlags */
376#define CPIA_FLAG 1
377#define SYSTEM_FLAG 2
378#define INT_CTRL_FLAG 4
379#define PROCESS_FLAG 8
380#define COM_FLAG 16
381#define VP_CTRL_FLAG 32
382#define CAPTURE_FLAG 64
383#define DEBUG_FLAG 128
384
385/* VPStatus */
386#define VP_STATE_OK 0x00
387
388#define VP_STATE_FAILED_VIDEOINIT 0x01
389#define VP_STATE_FAILED_AECACBINIT 0x02
390#define VP_STATE_AEC_MAX 0x04
391#define VP_STATE_ACB_BMAX 0x08
392
393#define VP_STATE_ACB_RMIN 0x10
394#define VP_STATE_ACB_GMIN 0x20
395#define VP_STATE_ACB_RMAX 0x40
396#define VP_STATE_ACB_GMAX 0x80
397
398/* default (minimum) compensation values */
399#define COMP_RED 220
400#define COMP_GREEN1 214
401#define COMP_GREEN2 COMP_GREEN1
402#define COMP_BLUE 230
403
404/* exposure status */
405#define EXPOSURE_VERY_LIGHT 0
406#define EXPOSURE_LIGHT 1
407#define EXPOSURE_NORMAL 2
408#define EXPOSURE_DARK 3
409#define EXPOSURE_VERY_DARK 4
410
411/* ErrorCode */
412#define ERROR_FLICKER_BELOW_MIN_EXP 0x01 /*flicker exposure got below minimum exposure */
413#define ALOG(fmt,args...) printk(fmt, ##args)
414#define LOG(fmt,args...) ALOG(KERN_INFO __FILE__ ":%s(%d):" fmt, __FUNCTION__ , __LINE__ , ##args)
415
416#ifdef _CPIA_DEBUG_
417#define ADBG(fmt,args...) printk(fmt, jiffies, ##args)
418#define DBG(fmt,args...) ADBG(KERN_DEBUG __FILE__" (%ld):%s(%d):" fmt, __FUNCTION__, __LINE__ , ##args)
419#else
420#define DBG(fmn,args...) do {} while(0)
421#endif
422
423#define DEB_BYTE(p)\
424 DBG("%1d %1d %1d %1d %1d %1d %1d %1d \n",\
425 (p)&0x80?1:0, (p)&0x40?1:0, (p)&0x20?1:0, (p)&0x10?1:0,\
426 (p)&0x08?1:0, (p)&0x04?1:0, (p)&0x02?1:0, (p)&0x01?1:0);
427
428#endif /* __KERNEL__ */
429
430#endif /* cpia_h */
diff --git a/drivers/media/video/cpia_pp.c b/drivers/media/video/cpia_pp.c
new file mode 100644
index 00000000000..ddf184f95d8
--- /dev/null
+++ b/drivers/media/video/cpia_pp.c
@@ -0,0 +1,886 @@
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#include <linux/config.h>
29
30#include <linux/module.h>
31#include <linux/init.h>
32
33#include <linux/kernel.h>
34#include <linux/parport.h>
35#include <linux/interrupt.h>
36#include <linux/delay.h>
37#include <linux/workqueue.h>
38#include <linux/smp_lock.h>
39#include <linux/sched.h>
40
41#include <linux/kmod.h>
42
43/* #define _CPIA_DEBUG_ define for verbose debug output */
44#include "cpia.h"
45
46static int cpia_pp_open(void *privdata);
47static int cpia_pp_registerCallback(void *privdata, void (*cb) (void *cbdata),
48 void *cbdata);
49static int cpia_pp_transferCmd(void *privdata, u8 *command, u8 *data);
50static int cpia_pp_streamStart(void *privdata);
51static int cpia_pp_streamStop(void *privdata);
52static int cpia_pp_streamRead(void *privdata, u8 *buffer, int noblock);
53static int cpia_pp_close(void *privdata);
54
55
56#define ABOUT "Parallel port driver for Vision CPiA based cameras"
57
58#define PACKET_LENGTH 8
59
60/* Magic numbers for defining port-device mappings */
61#define PPCPIA_PARPORT_UNSPEC -4
62#define PPCPIA_PARPORT_AUTO -3
63#define PPCPIA_PARPORT_OFF -2
64#define PPCPIA_PARPORT_NONE -1
65
66#ifdef MODULE
67static int parport_nr[PARPORT_MAX] = {[0 ... PARPORT_MAX - 1] = PPCPIA_PARPORT_UNSPEC};
68static char *parport[PARPORT_MAX] = {NULL,};
69
70MODULE_AUTHOR("B. Huisman <bhuism@cs.utwente.nl> & Peter Pregler <Peter_Pregler@email.com>");
71MODULE_DESCRIPTION("Parallel port driver for Vision CPiA based cameras");
72MODULE_LICENSE("GPL");
73
74module_param_array(parport, charp, NULL, 0);
75MODULE_PARM_DESC(parport, "'auto' or a list of parallel port numbers. Just like lp.");
76#else
77static int parport_nr[PARPORT_MAX] __initdata =
78 {[0 ... PARPORT_MAX - 1] = PPCPIA_PARPORT_UNSPEC};
79static int parport_ptr = 0;
80#endif
81
82struct pp_cam_entry {
83 struct pardevice *pdev;
84 struct parport *port;
85 struct work_struct cb_task;
86 int open_count;
87 wait_queue_head_t wq_stream;
88 /* image state flags */
89 int image_ready; /* we got an interrupt */
90 int image_complete; /* we have seen 4 EOI */
91
92 int streaming; /* we are in streaming mode */
93 int stream_irq;
94};
95
96static struct cpia_camera_ops cpia_pp_ops =
97{
98 cpia_pp_open,
99 cpia_pp_registerCallback,
100 cpia_pp_transferCmd,
101 cpia_pp_streamStart,
102 cpia_pp_streamStop,
103 cpia_pp_streamRead,
104 cpia_pp_close,
105 1,
106 THIS_MODULE
107};
108
109static LIST_HEAD(cam_list);
110static spinlock_t cam_list_lock_pp;
111
112/* FIXME */
113static void cpia_parport_enable_irq( struct parport *port ) {
114 parport_enable_irq(port);
115 mdelay(10);
116 return;
117}
118
119static void cpia_parport_disable_irq( struct parport *port ) {
120 parport_disable_irq(port);
121 mdelay(10);
122 return;
123}
124
125/* Special CPiA PPC modes: These are invoked by using the 1284 Extensibility
126 * Link Flag during negotiation */
127#define UPLOAD_FLAG 0x08
128#define NIBBLE_TRANSFER 0x01
129#define ECP_TRANSFER 0x03
130
131#define PARPORT_CHUNK_SIZE PAGE_SIZE
132
133
134/****************************************************************************
135 *
136 * CPiA-specific low-level parport functions for nibble uploads
137 *
138 ***************************************************************************/
139/* CPiA nonstandard "Nibble" mode (no nDataAvail signal after each byte). */
140/* The standard kernel parport_ieee1284_read_nibble() fails with the CPiA... */
141
142static size_t cpia_read_nibble (struct parport *port,
143 void *buffer, size_t len,
144 int flags)
145{
146 /* adapted verbatim, with one change, from
147 parport_ieee1284_read_nibble() in drivers/parport/ieee1284-ops.c */
148
149 unsigned char *buf = buffer;
150 int i;
151 unsigned char byte = 0;
152
153 len *= 2; /* in nibbles */
154 for (i=0; i < len; i++) {
155 unsigned char nibble;
156
157 /* The CPiA firmware suppresses the use of nDataAvail (nFault LO)
158 * after every second nibble to signal that more
159 * data is available. (the total number of Bytes that
160 * should be sent is known; if too few are received, an error
161 * will be recorded after a timeout).
162 * This is incompatible with parport_ieee1284_read_nibble(),
163 * which expects to find nFault LO after every second nibble.
164 */
165
166 /* Solution: modify cpia_read_nibble to only check for
167 * nDataAvail before the first nibble is sent.
168 */
169
170 /* Does the error line indicate end of data? */
171 if (((i /*& 1*/) == 0) &&
172 (parport_read_status(port) & PARPORT_STATUS_ERROR)) {
173 port->physport->ieee1284.phase = IEEE1284_PH_HBUSY_DNA;
174 DBG("%s: No more nibble data (%d bytes)\n",
175 port->name, i/2);
176
177 /* Go to reverse idle phase. */
178 parport_frob_control (port,
179 PARPORT_CONTROL_AUTOFD,
180 PARPORT_CONTROL_AUTOFD);
181 port->physport->ieee1284.phase = IEEE1284_PH_REV_IDLE;
182 break;
183 }
184
185 /* Event 7: Set nAutoFd low. */
186 parport_frob_control (port,
187 PARPORT_CONTROL_AUTOFD,
188 PARPORT_CONTROL_AUTOFD);
189
190 /* Event 9: nAck goes low. */
191 port->ieee1284.phase = IEEE1284_PH_REV_DATA;
192 if (parport_wait_peripheral (port,
193 PARPORT_STATUS_ACK, 0)) {
194 /* Timeout -- no more data? */
195 DBG("%s: Nibble timeout at event 9 (%d bytes)\n",
196 port->name, i/2);
197 parport_frob_control (port, PARPORT_CONTROL_AUTOFD, 0);
198 break;
199 }
200
201
202 /* Read a nibble. */
203 nibble = parport_read_status (port) >> 3;
204 nibble &= ~8;
205 if ((nibble & 0x10) == 0)
206 nibble |= 8;
207 nibble &= 0xf;
208
209 /* Event 10: Set nAutoFd high. */
210 parport_frob_control (port, PARPORT_CONTROL_AUTOFD, 0);
211
212 /* Event 11: nAck goes high. */
213 if (parport_wait_peripheral (port,
214 PARPORT_STATUS_ACK,
215 PARPORT_STATUS_ACK)) {
216 /* Timeout -- no more data? */
217 DBG("%s: Nibble timeout at event 11\n",
218 port->name);
219 break;
220 }
221
222 if (i & 1) {
223 /* Second nibble */
224 byte |= nibble << 4;
225 *buf++ = byte;
226 } else
227 byte = nibble;
228 }
229
230 i /= 2; /* i is now in bytes */
231
232 if (i == len) {
233 /* Read the last nibble without checking data avail. */
234 port = port->physport;
235 if (parport_read_status (port) & PARPORT_STATUS_ERROR)
236 port->ieee1284.phase = IEEE1284_PH_HBUSY_DNA;
237 else
238 port->ieee1284.phase = IEEE1284_PH_HBUSY_DAVAIL;
239 }
240
241 return i;
242}
243
244/* CPiA nonstandard "Nibble Stream" mode (2 nibbles per cycle, instead of 1)
245 * (See CPiA Data sheet p. 31)
246 *
247 * "Nibble Stream" mode used by CPiA for uploads to non-ECP ports is a
248 * nonstandard variant of nibble mode which allows the same (mediocre)
249 * data flow of 8 bits per cycle as software-enabled ECP by TRISTATE-capable
250 * parallel ports, but works also for non-TRISTATE-capable ports.
251 * (Standard nibble mode only send 4 bits per cycle)
252 *
253 */
254
255static size_t cpia_read_nibble_stream(struct parport *port,
256 void *buffer, size_t len,
257 int flags)
258{
259 int i;
260 unsigned char *buf = buffer;
261 int endseen = 0;
262
263 for (i=0; i < len; i++) {
264 unsigned char nibble[2], byte = 0;
265 int j;
266
267 /* Image Data is complete when 4 consecutive EOI bytes (0xff) are seen */
268 if (endseen > 3 )
269 break;
270
271 /* Event 7: Set nAutoFd low. */
272 parport_frob_control (port,
273 PARPORT_CONTROL_AUTOFD,
274 PARPORT_CONTROL_AUTOFD);
275
276 /* Event 9: nAck goes low. */
277 port->ieee1284.phase = IEEE1284_PH_REV_DATA;
278 if (parport_wait_peripheral (port,
279 PARPORT_STATUS_ACK, 0)) {
280 /* Timeout -- no more data? */
281 DBG("%s: Nibble timeout at event 9 (%d bytes)\n",
282 port->name, i/2);
283 parport_frob_control (port, PARPORT_CONTROL_AUTOFD, 0);
284 break;
285 }
286
287 /* Read lower nibble */
288 nibble[0] = parport_read_status (port) >>3;
289
290 /* Event 10: Set nAutoFd high. */
291 parport_frob_control (port, PARPORT_CONTROL_AUTOFD, 0);
292
293 /* Event 11: nAck goes high. */
294 if (parport_wait_peripheral (port,
295 PARPORT_STATUS_ACK,
296 PARPORT_STATUS_ACK)) {
297 /* Timeout -- no more data? */
298 DBG("%s: Nibble timeout at event 11\n",
299 port->name);
300 break;
301 }
302
303 /* Read upper nibble */
304 nibble[1] = parport_read_status (port) >>3;
305
306 /* reassemble the byte */
307 for (j = 0; j < 2 ; j++ ) {
308 nibble[j] &= ~8;
309 if ((nibble[j] & 0x10) == 0)
310 nibble[j] |= 8;
311 nibble[j] &= 0xf;
312 }
313 byte = (nibble[0] |(nibble[1] << 4));
314 *buf++ = byte;
315
316 if(byte == EOI)
317 endseen++;
318 else
319 endseen = 0;
320 }
321 return i;
322}
323
324/****************************************************************************
325 *
326 * EndTransferMode
327 *
328 ***************************************************************************/
329static void EndTransferMode(struct pp_cam_entry *cam)
330{
331 parport_negotiate(cam->port, IEEE1284_MODE_COMPAT);
332}
333
334/****************************************************************************
335 *
336 * ForwardSetup
337 *
338 ***************************************************************************/
339static int ForwardSetup(struct pp_cam_entry *cam)
340{
341 int retry;
342
343 /* The CPiA uses ECP protocol for Downloads from the Host to the camera.
344 * This will be software-emulated if ECP hardware is not present
345 */
346
347 /* the usual camera maximum response time is 10ms, but after receiving
348 * some commands, it needs up to 40ms. (Data Sheet p. 32)*/
349
350 for(retry = 0; retry < 4; ++retry) {
351 if(!parport_negotiate(cam->port, IEEE1284_MODE_ECP)) {
352 break;
353 }
354 mdelay(10);
355 }
356 if(retry == 4) {
357 DBG("Unable to negotiate IEEE1284 ECP Download mode\n");
358 return -1;
359 }
360 return 0;
361}
362/****************************************************************************
363 *
364 * ReverseSetup
365 *
366 ***************************************************************************/
367static int ReverseSetup(struct pp_cam_entry *cam, int extensibility)
368{
369 int retry;
370 int upload_mode, mode = IEEE1284_MODE_ECP;
371 int transfer_mode = ECP_TRANSFER;
372
373 if (!(cam->port->modes & PARPORT_MODE_ECP) &&
374 !(cam->port->modes & PARPORT_MODE_TRISTATE)) {
375 mode = IEEE1284_MODE_NIBBLE;
376 transfer_mode = NIBBLE_TRANSFER;
377 }
378
379 upload_mode = mode;
380 if(extensibility) mode = UPLOAD_FLAG|transfer_mode|IEEE1284_EXT_LINK;
381
382 /* the usual camera maximum response time is 10ms, but after
383 * receiving some commands, it needs up to 40ms. */
384
385 for(retry = 0; retry < 4; ++retry) {
386 if(!parport_negotiate(cam->port, mode)) {
387 break;
388 }
389 mdelay(10);
390 }
391 if(retry == 4) {
392 if(extensibility)
393 DBG("Unable to negotiate upload extensibility mode\n");
394 else
395 DBG("Unable to negotiate upload mode\n");
396 return -1;
397 }
398 if(extensibility) cam->port->ieee1284.mode = upload_mode;
399 return 0;
400}
401
402/****************************************************************************
403 *
404 * WritePacket
405 *
406 ***************************************************************************/
407static int WritePacket(struct pp_cam_entry *cam, const u8 *packet, size_t size)
408{
409 int retval=0;
410 int size_written;
411
412 if (packet == NULL) {
413 return -EINVAL;
414 }
415 if (ForwardSetup(cam)) {
416 DBG("Write failed in setup\n");
417 return -EIO;
418 }
419 size_written = parport_write(cam->port, packet, size);
420 if(size_written != size) {
421 DBG("Write failed, wrote %d/%d\n", size_written, size);
422 retval = -EIO;
423 }
424 EndTransferMode(cam);
425 return retval;
426}
427
428/****************************************************************************
429 *
430 * ReadPacket
431 *
432 ***************************************************************************/
433static int ReadPacket(struct pp_cam_entry *cam, u8 *packet, size_t size)
434{
435 int retval=0;
436
437 if (packet == NULL) {
438 return -EINVAL;
439 }
440 if (ReverseSetup(cam, 0)) {
441 return -EIO;
442 }
443
444 /* support for CPiA variant nibble reads */
445 if(cam->port->ieee1284.mode == IEEE1284_MODE_NIBBLE) {
446 if(cpia_read_nibble(cam->port, packet, size, 0) != size)
447 retval = -EIO;
448 } else {
449 if(parport_read(cam->port, packet, size) != size)
450 retval = -EIO;
451 }
452 EndTransferMode(cam);
453 return retval;
454}
455
456/****************************************************************************
457 *
458 * cpia_pp_streamStart
459 *
460 ***************************************************************************/
461static int cpia_pp_streamStart(void *privdata)
462{
463 struct pp_cam_entry *cam = privdata;
464 DBG("\n");
465 cam->streaming=1;
466 cam->image_ready=0;
467 //if (ReverseSetup(cam,1)) return -EIO;
468 if(cam->stream_irq) cpia_parport_enable_irq(cam->port);
469 return 0;
470}
471
472/****************************************************************************
473 *
474 * cpia_pp_streamStop
475 *
476 ***************************************************************************/
477static int cpia_pp_streamStop(void *privdata)
478{
479 struct pp_cam_entry *cam = privdata;
480
481 DBG("\n");
482 cam->streaming=0;
483 cpia_parport_disable_irq(cam->port);
484 //EndTransferMode(cam);
485
486 return 0;
487}
488
489/****************************************************************************
490 *
491 * cpia_pp_streamRead
492 *
493 ***************************************************************************/
494static int cpia_pp_read(struct parport *port, u8 *buffer, int len)
495{
496 int bytes_read;
497
498 /* support for CPiA variant "nibble stream" reads */
499 if(port->ieee1284.mode == IEEE1284_MODE_NIBBLE)
500 bytes_read = cpia_read_nibble_stream(port,buffer,len,0);
501 else {
502 int new_bytes;
503 for(bytes_read=0; bytes_read<len; bytes_read += new_bytes) {
504 new_bytes = parport_read(port, buffer+bytes_read,
505 len-bytes_read);
506 if(new_bytes < 0) break;
507 }
508 }
509 return bytes_read;
510}
511
512static int cpia_pp_streamRead(void *privdata, u8 *buffer, int noblock)
513{
514 struct pp_cam_entry *cam = privdata;
515 int read_bytes = 0;
516 int i, endseen, block_size, new_bytes;
517
518 if(cam == NULL) {
519 DBG("Internal driver error: cam is NULL\n");
520 return -EINVAL;
521 }
522 if(buffer == NULL) {
523 DBG("Internal driver error: buffer is NULL\n");
524 return -EINVAL;
525 }
526 //if(cam->streaming) DBG("%d / %d\n", cam->image_ready, noblock);
527 if( cam->stream_irq ) {
528 DBG("%d\n", cam->image_ready);
529 cam->image_ready--;
530 }
531 cam->image_complete=0;
532 if (0/*cam->streaming*/) {
533 if(!cam->image_ready) {
534 if(noblock) return -EWOULDBLOCK;
535 interruptible_sleep_on(&cam->wq_stream);
536 if( signal_pending(current) ) return -EINTR;
537 DBG("%d\n", cam->image_ready);
538 }
539 } else {
540 if (ReverseSetup(cam, 1)) {
541 DBG("unable to ReverseSetup\n");
542 return -EIO;
543 }
544 }
545 endseen = 0;
546 block_size = PARPORT_CHUNK_SIZE;
547 while( !cam->image_complete ) {
548 cond_resched();
549
550 new_bytes = cpia_pp_read(cam->port, buffer, block_size );
551 if( new_bytes <= 0 ) {
552 break;
553 }
554 i=-1;
555 while(++i<new_bytes && endseen<4) {
556 if(*buffer==EOI) {
557 endseen++;
558 } else {
559 endseen=0;
560 }
561 buffer++;
562 }
563 read_bytes += i;
564 if( endseen==4 ) {
565 cam->image_complete=1;
566 break;
567 }
568 if( CPIA_MAX_IMAGE_SIZE-read_bytes <= PARPORT_CHUNK_SIZE ) {
569 block_size=CPIA_MAX_IMAGE_SIZE-read_bytes;
570 }
571 }
572 EndTransferMode(cam);
573 return cam->image_complete ? read_bytes : -EIO;
574}
575/****************************************************************************
576 *
577 * cpia_pp_transferCmd
578 *
579 ***************************************************************************/
580static int cpia_pp_transferCmd(void *privdata, u8 *command, u8 *data)
581{
582 int err;
583 int retval=0;
584 int databytes;
585 struct pp_cam_entry *cam = privdata;
586
587 if(cam == NULL) {
588 DBG("Internal driver error: cam is NULL\n");
589 return -EINVAL;
590 }
591 if(command == NULL) {
592 DBG("Internal driver error: command is NULL\n");
593 return -EINVAL;
594 }
595 databytes = (((int)command[7])<<8) | command[6];
596 if ((err = WritePacket(cam, command, PACKET_LENGTH)) < 0) {
597 DBG("Error writing command\n");
598 return err;
599 }
600 if(command[0] == DATA_IN) {
601 u8 buffer[8];
602 if(data == NULL) {
603 DBG("Internal driver error: data is NULL\n");
604 return -EINVAL;
605 }
606 if((err = ReadPacket(cam, buffer, 8)) < 0) {
607 DBG("Error reading command result\n");
608 return err;
609 }
610 memcpy(data, buffer, databytes);
611 } else if(command[0] == DATA_OUT) {
612 if(databytes > 0) {
613 if(data == NULL) {
614 DBG("Internal driver error: data is NULL\n");
615 retval = -EINVAL;
616 } else {
617 if((err=WritePacket(cam, data, databytes)) < 0){
618 DBG("Error writing command data\n");
619 return err;
620 }
621 }
622 }
623 } else {
624 DBG("Unexpected first byte of command: %x\n", command[0]);
625 retval = -EINVAL;
626 }
627 return retval;
628}
629
630/****************************************************************************
631 *
632 * cpia_pp_open
633 *
634 ***************************************************************************/
635static int cpia_pp_open(void *privdata)
636{
637 struct pp_cam_entry *cam = (struct pp_cam_entry *)privdata;
638
639 if (cam == NULL)
640 return -EINVAL;
641
642 if(cam->open_count == 0) {
643 if (parport_claim(cam->pdev)) {
644 DBG("failed to claim the port\n");
645 return -EBUSY;
646 }
647 parport_negotiate(cam->port, IEEE1284_MODE_COMPAT);
648 parport_data_forward(cam->port);
649 parport_write_control(cam->port, PARPORT_CONTROL_SELECT);
650 udelay(50);
651 parport_write_control(cam->port,
652 PARPORT_CONTROL_SELECT
653 | PARPORT_CONTROL_INIT);
654 }
655
656 ++cam->open_count;
657
658 return 0;
659}
660
661/****************************************************************************
662 *
663 * cpia_pp_registerCallback
664 *
665 ***************************************************************************/
666static int cpia_pp_registerCallback(void *privdata, void (*cb)(void *cbdata), void *cbdata)
667{
668 struct pp_cam_entry *cam = privdata;
669 int retval = 0;
670
671 if(cam->port->irq != PARPORT_IRQ_NONE) {
672 INIT_WORK(&cam->cb_task, cb, cbdata);
673 } else {
674 retval = -1;
675 }
676 return retval;
677}
678
679/****************************************************************************
680 *
681 * cpia_pp_close
682 *
683 ***************************************************************************/
684static int cpia_pp_close(void *privdata)
685{
686 struct pp_cam_entry *cam = privdata;
687 if (--cam->open_count == 0) {
688 parport_release(cam->pdev);
689 }
690 return 0;
691}
692
693/****************************************************************************
694 *
695 * cpia_pp_register
696 *
697 ***************************************************************************/
698static int cpia_pp_register(struct parport *port)
699{
700 struct pardevice *pdev = NULL;
701 struct pp_cam_entry *cam;
702 struct cam_data *cpia;
703
704 if (!(port->modes & PARPORT_MODE_PCSPP)) {
705 LOG("port is not supported by CPiA driver\n");
706 return -ENXIO;
707 }
708
709 cam = kmalloc(sizeof(struct pp_cam_entry), GFP_KERNEL);
710 if (cam == NULL) {
711 LOG("failed to allocate camera structure\n");
712 return -ENOMEM;
713 }
714 memset(cam,0,sizeof(struct pp_cam_entry));
715
716 pdev = parport_register_device(port, "cpia_pp", NULL, NULL,
717 NULL, 0, cam);
718
719 if (!pdev) {
720 LOG("failed to parport_register_device\n");
721 kfree(cam);
722 return -ENXIO;
723 }
724
725 cam->pdev = pdev;
726 cam->port = port;
727 init_waitqueue_head(&cam->wq_stream);
728
729 cam->streaming = 0;
730 cam->stream_irq = 0;
731
732 if((cpia = cpia_register_camera(&cpia_pp_ops, cam)) == NULL) {
733 LOG("failed to cpia_register_camera\n");
734 parport_unregister_device(pdev);
735 kfree(cam);
736 return -ENXIO;
737 }
738 spin_lock( &cam_list_lock_pp );
739 list_add( &cpia->cam_data_list, &cam_list );
740 spin_unlock( &cam_list_lock_pp );
741
742 return 0;
743}
744
745static void cpia_pp_detach (struct parport *port)
746{
747 struct list_head *tmp;
748 struct cam_data *cpia = NULL;
749 struct pp_cam_entry *cam;
750
751 spin_lock( &cam_list_lock_pp );
752 list_for_each (tmp, &cam_list) {
753 cpia = list_entry(tmp, struct cam_data, cam_data_list);
754 cam = (struct pp_cam_entry *) cpia->lowlevel_data;
755 if (cam && cam->port->number == port->number) {
756 list_del(&cpia->cam_data_list);
757 break;
758 }
759 cpia = NULL;
760 }
761 spin_unlock( &cam_list_lock_pp );
762
763 if (!cpia) {
764 DBG("cpia_pp_detach failed to find cam_data in cam_list\n");
765 return;
766 }
767
768 cam = (struct pp_cam_entry *) cpia->lowlevel_data;
769 cpia_unregister_camera(cpia);
770 if(cam->open_count > 0)
771 cpia_pp_close(cam);
772 parport_unregister_device(cam->pdev);
773 cpia->lowlevel_data = NULL;
774 kfree(cam);
775}
776
777static void cpia_pp_attach (struct parport *port)
778{
779 unsigned int i;
780
781 switch (parport_nr[0])
782 {
783 case PPCPIA_PARPORT_UNSPEC:
784 case PPCPIA_PARPORT_AUTO:
785 if (port->probe_info[0].class != PARPORT_CLASS_MEDIA ||
786 port->probe_info[0].cmdset == NULL ||
787 strncmp(port->probe_info[0].cmdset, "CPIA_1", 6) != 0)
788 return;
789
790 cpia_pp_register(port);
791
792 break;
793
794 default:
795 for (i = 0; i < PARPORT_MAX; ++i) {
796 if (port->number == parport_nr[i]) {
797 cpia_pp_register(port);
798 break;
799 }
800 }
801 break;
802 }
803}
804
805static struct parport_driver cpia_pp_driver = {
806 .name = "cpia_pp",
807 .attach = cpia_pp_attach,
808 .detach = cpia_pp_detach,
809};
810
811int cpia_pp_init(void)
812{
813 printk(KERN_INFO "%s v%d.%d.%d\n",ABOUT,
814 CPIA_PP_MAJ_VER,CPIA_PP_MIN_VER,CPIA_PP_PATCH_VER);
815
816 if(parport_nr[0] == PPCPIA_PARPORT_OFF) {
817 printk(" disabled\n");
818 return 0;
819 }
820
821 spin_lock_init( &cam_list_lock_pp );
822
823 if (parport_register_driver (&cpia_pp_driver)) {
824 LOG ("unable to register with parport\n");
825 return -EIO;
826 }
827 return 0;
828}
829
830#ifdef MODULE
831int init_module(void)
832{
833 if (parport[0]) {
834 /* The user gave some parameters. Let's see what they were. */
835 if (!strncmp(parport[0], "auto", 4)) {
836 parport_nr[0] = PPCPIA_PARPORT_AUTO;
837 } else {
838 int n;
839 for (n = 0; n < PARPORT_MAX && parport[n]; n++) {
840 if (!strncmp(parport[n], "none", 4)) {
841 parport_nr[n] = PPCPIA_PARPORT_NONE;
842 } else {
843 char *ep;
844 unsigned long r = simple_strtoul(parport[n], &ep, 0);
845 if (ep != parport[n]) {
846 parport_nr[n] = r;
847 } else {
848 LOG("bad port specifier `%s'\n", parport[n]);
849 return -ENODEV;
850 }
851 }
852 }
853 }
854 }
855 return cpia_pp_init();
856}
857
858void cleanup_module(void)
859{
860 parport_unregister_driver (&cpia_pp_driver);
861 return;
862}
863
864#else /* !MODULE */
865
866static int __init cpia_pp_setup(char *str)
867{
868 if (!strncmp(str, "parport", 7)) {
869 int n = simple_strtoul(str + 7, NULL, 10);
870 if (parport_ptr < PARPORT_MAX) {
871 parport_nr[parport_ptr++] = n;
872 } else {
873 LOG("too many ports, %s ignored.\n", str);
874 }
875 } else if (!strcmp(str, "auto")) {
876 parport_nr[0] = PPCPIA_PARPORT_AUTO;
877 } else if (!strcmp(str, "none")) {
878 parport_nr[parport_ptr++] = PPCPIA_PARPORT_NONE;
879 }
880
881 return 0;
882}
883
884__setup("cpia_pp=", cpia_pp_setup);
885
886#endif /* !MODULE */
diff --git a/drivers/media/video/cpia_usb.c b/drivers/media/video/cpia_usb.c
new file mode 100644
index 00000000000..cdda423386c
--- /dev/null
+++ b/drivers/media/video/cpia_usb.c
@@ -0,0 +1,662 @@
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, struct pt_regs *regs)
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", __FUNCTION__, 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 if (ucpia->sbuf[1].data) {
449 kfree(ucpia->sbuf[1].data);
450 ucpia->sbuf[1].data = NULL;
451 }
452
453 if (ucpia->sbuf[0].urb) {
454 usb_kill_urb(ucpia->sbuf[0].urb);
455 usb_free_urb(ucpia->sbuf[0].urb);
456 ucpia->sbuf[0].urb = NULL;
457 }
458
459 if (ucpia->sbuf[0].data) {
460 kfree(ucpia->sbuf[0].data);
461 ucpia->sbuf[0].data = NULL;
462 }
463}
464
465static int cpia_usb_close(void *privdata)
466{
467 struct usb_cpia *ucpia = (struct usb_cpia *) privdata;
468
469 if(!ucpia)
470 return -ENODEV;
471
472 ucpia->open = 0;
473
474 /* ucpia->present = 0 protects against trying to reset the
475 * alt setting if camera is physically disconnected while open */
476 cpia_usb_free_resources(ucpia, ucpia->present);
477
478 return 0;
479}
480
481int cpia_usb_init(void)
482{
483 /* return -ENODEV; */
484 return 0;
485}
486
487/* Probing and initializing */
488
489static int cpia_probe(struct usb_interface *intf,
490 const struct usb_device_id *id)
491{
492 struct usb_device *udev = interface_to_usbdev(intf);
493 struct usb_host_interface *interface;
494 struct usb_cpia *ucpia;
495 struct cam_data *cam;
496 int ret;
497
498 /* A multi-config CPiA camera? */
499 if (udev->descriptor.bNumConfigurations != 1)
500 return -ENODEV;
501
502 interface = intf->cur_altsetting;
503
504 printk(KERN_INFO "USB CPiA camera found\n");
505
506 ucpia = kmalloc(sizeof(*ucpia), GFP_KERNEL);
507 if (!ucpia) {
508 printk(KERN_ERR "couldn't kmalloc cpia struct\n");
509 return -ENOMEM;
510 }
511
512 memset(ucpia, 0, sizeof(*ucpia));
513
514 ucpia->dev = udev;
515 ucpia->iface = interface->desc.bInterfaceNumber;
516 init_waitqueue_head(&ucpia->wq_stream);
517
518 ucpia->buffers[0] = vmalloc(sizeof(*ucpia->buffers[0]));
519 if (!ucpia->buffers[0]) {
520 printk(KERN_ERR "couldn't vmalloc frame buffer 0\n");
521 goto fail_alloc_0;
522 }
523
524 ucpia->buffers[1] = vmalloc(sizeof(*ucpia->buffers[1]));
525 if (!ucpia->buffers[1]) {
526 printk(KERN_ERR "couldn't vmalloc frame buffer 1\n");
527 goto fail_alloc_1;
528 }
529
530 ucpia->buffers[2] = vmalloc(sizeof(*ucpia->buffers[2]));
531 if (!ucpia->buffers[2]) {
532 printk(KERN_ERR "couldn't vmalloc frame buffer 2\n");
533 goto fail_alloc_2;
534 }
535
536 ucpia->buffers[0]->next = ucpia->buffers[1];
537 ucpia->buffers[1]->next = ucpia->buffers[2];
538 ucpia->buffers[2]->next = ucpia->buffers[0];
539
540 ret = usb_set_interface(udev, ucpia->iface, 0);
541 if (ret < 0) {
542 printk(KERN_ERR "cpia_probe: usb_set_interface error (ret = %d)\n", ret);
543 /* goto fail_all; */
544 }
545
546 /* Before register_camera, important */
547 ucpia->present = 1;
548
549 cam = cpia_register_camera(&cpia_usb_ops, ucpia);
550 if (!cam) {
551 LOG("failed to cpia_register_camera\n");
552 goto fail_all;
553 }
554
555 spin_lock( &cam_list_lock_usb );
556 list_add( &cam->cam_data_list, &cam_list );
557 spin_unlock( &cam_list_lock_usb );
558
559 usb_set_intfdata(intf, cam);
560 return 0;
561
562fail_all:
563 vfree(ucpia->buffers[2]);
564 ucpia->buffers[2] = NULL;
565fail_alloc_2:
566 vfree(ucpia->buffers[1]);
567 ucpia->buffers[1] = NULL;
568fail_alloc_1:
569 vfree(ucpia->buffers[0]);
570 ucpia->buffers[0] = NULL;
571fail_alloc_0:
572 kfree(ucpia);
573 return -EIO;
574}
575
576static void cpia_disconnect(struct usb_interface *intf);
577
578static struct usb_device_id cpia_id_table [] = {
579 { USB_DEVICE(0x0553, 0x0002) },
580 { USB_DEVICE(0x0813, 0x0001) },
581 { } /* Terminating entry */
582};
583
584MODULE_DEVICE_TABLE (usb, cpia_id_table);
585MODULE_LICENSE("GPL");
586
587
588static struct usb_driver cpia_driver = {
589 .owner = THIS_MODULE,
590 .name = "cpia",
591 .probe = cpia_probe,
592 .disconnect = cpia_disconnect,
593 .id_table = cpia_id_table,
594};
595
596static void cpia_disconnect(struct usb_interface *intf)
597{
598 struct cam_data *cam = usb_get_intfdata(intf);
599 struct usb_cpia *ucpia;
600 struct usb_device *udev;
601
602 usb_set_intfdata(intf, NULL);
603 if (!cam)
604 return;
605
606 ucpia = (struct usb_cpia *) cam->lowlevel_data;
607 spin_lock( &cam_list_lock_usb );
608 list_del(&cam->cam_data_list);
609 spin_unlock( &cam_list_lock_usb );
610
611 ucpia->present = 0;
612
613 cpia_unregister_camera(cam);
614 if(ucpia->open)
615 cpia_usb_close(cam->lowlevel_data);
616
617 ucpia->curbuff->status = FRAME_ERROR;
618
619 if (waitqueue_active(&ucpia->wq_stream))
620 wake_up_interruptible(&ucpia->wq_stream);
621
622 udev = interface_to_usbdev(intf);
623
624 ucpia->curbuff = ucpia->workbuff = NULL;
625
626 if (ucpia->buffers[2]) {
627 vfree(ucpia->buffers[2]);
628 ucpia->buffers[2] = NULL;
629 }
630
631 if (ucpia->buffers[1]) {
632 vfree(ucpia->buffers[1]);
633 ucpia->buffers[1] = NULL;
634 }
635
636 if (ucpia->buffers[0]) {
637 vfree(ucpia->buffers[0]);
638 ucpia->buffers[0] = NULL;
639 }
640
641 cam->lowlevel_data = NULL;
642 kfree(ucpia);
643}
644
645static int __init usb_cpia_init(void)
646{
647 printk(KERN_INFO "%s v%d.%d.%d\n",ABOUT,
648 CPIA_USB_MAJ_VER,CPIA_USB_MIN_VER,CPIA_USB_PATCH_VER);
649
650 spin_lock_init(&cam_list_lock_usb);
651 return usb_register(&cpia_driver);
652}
653
654static void __exit usb_cpia_cleanup(void)
655{
656 usb_deregister(&cpia_driver);
657}
658
659
660module_init (usb_cpia_init);
661module_exit (usb_cpia_cleanup);
662
diff --git a/drivers/media/video/cs8420.h b/drivers/media/video/cs8420.h
new file mode 100644
index 00000000000..2b22f3a38de
--- /dev/null
+++ b/drivers/media/video/cs8420.h
@@ -0,0 +1,50 @@
1/* cs8420.h - cs8420 initializations
2 Copyright (C) 1999 Nathan Laredo (laredo@gnu.org)
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 */
19#ifndef __CS8420_H__
20#define __CS8420_H__
21
22/* Initialization Sequence */
23
24static __u8 init8420[] = {
25 1, 0x01, 2, 0x02, 3, 0x00, 4, 0x46,
26 5, 0x24, 6, 0x84, 18, 0x18, 19, 0x13,
27};
28
29#define INIT8420LEN (sizeof(init8420)/2)
30
31static __u8 mode8420pro[] = { /* professional output mode */
32 32, 0xa1, 33, 0x00, 34, 0x00, 35, 0x00,
33 36, 0x00, 37, 0x00, 38, 0x00, 39, 0x00,
34 40, 0x00, 41, 0x00, 42, 0x00, 43, 0x00,
35 44, 0x00, 45, 0x00, 46, 0x00, 47, 0x00,
36 48, 0x00, 49, 0x00, 50, 0x00, 51, 0x00,
37 52, 0x00, 53, 0x00, 54, 0x00, 55, 0x00,
38};
39#define MODE8420LEN (sizeof(mode8420pro)/2)
40
41static __u8 mode8420con[] = { /* consumer output mode */
42 32, 0x20, 33, 0x00, 34, 0x00, 35, 0x48,
43 36, 0x00, 37, 0x00, 38, 0x00, 39, 0x00,
44 40, 0x00, 41, 0x00, 42, 0x00, 43, 0x00,
45 44, 0x00, 45, 0x00, 46, 0x00, 47, 0x00,
46 48, 0x00, 49, 0x00, 50, 0x00, 51, 0x00,
47 52, 0x00, 53, 0x00, 54, 0x00, 55, 0x00,
48};
49
50#endif
diff --git a/drivers/media/video/cx88/Makefile b/drivers/media/video/cx88/Makefile
new file mode 100644
index 00000000000..606d0348da2
--- /dev/null
+++ b/drivers/media/video/cx88/Makefile
@@ -0,0 +1,11 @@
1cx88xx-objs := cx88-cards.o cx88-core.o cx88-i2c.o cx88-tvaudio.o \
2 cx88-input.o
3cx8800-objs := cx88-video.o cx88-vbi.o
4cx8802-objs := cx88-mpeg.o
5
6obj-$(CONFIG_VIDEO_CX88) += cx88xx.o cx8800.o cx8802.o cx88-blackbird.o
7obj-$(CONFIG_VIDEO_CX88_DVB) += cx88-dvb.o
8
9EXTRA_CFLAGS += -I$(src)/..
10EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core
11EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/frontends
diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c
new file mode 100644
index 00000000000..46d6778b863
--- /dev/null
+++ b/drivers/media/video/cx88/cx88-blackbird.c
@@ -0,0 +1,911 @@
1/*
2 * $Id: cx88-blackbird.c,v 1.26 2005/03/07 15:58:05 kraxel Exp $
3 *
4 * Support for a cx23416 mpeg encoder via cx2388x host port.
5 * "blackbird" reference design.
6 *
7 * (c) 2004 Jelle Foks <jelle@foks.8m.com>
8 * (c) 2004 Gerd Knorr <kraxel@bytesex.org>
9 *
10 * Includes parts from the ivtv driver( http://ivtv.sourceforge.net/),
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 */
26
27#include <linux/module.h>
28#include <linux/moduleparam.h>
29#include <linux/init.h>
30#include <linux/fs.h>
31#include <linux/delay.h>
32#include <linux/device.h>
33#include <linux/firmware.h>
34
35#include "cx88.h"
36
37MODULE_DESCRIPTION("driver for cx2388x/cx23416 based mpeg encoder cards");
38MODULE_AUTHOR("Jelle Foks <jelle@foks.8m.com>");
39MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
40MODULE_LICENSE("GPL");
41
42static unsigned int mpegbufs = 8;
43module_param(mpegbufs,int,0644);
44MODULE_PARM_DESC(mpegbufs,"number of mpeg buffers, range 2-32");
45
46static unsigned int debug = 0;
47module_param(debug,int,0644);
48MODULE_PARM_DESC(debug,"enable debug messages [blackbird]");
49
50#define dprintk(level,fmt, arg...) if (debug >= level) \
51 printk(KERN_DEBUG "%s/2-bb: " fmt, dev->core->name , ## arg)
52
53static LIST_HEAD(cx8802_devlist);
54
55/* ------------------------------------------------------------------ */
56
57#define BLACKBIRD_FIRM_ENC_FILENAME "blackbird-fw-enc.bin"
58#define BLACKBIRD_FIRM_IMAGE_SIZE 256*1024
59
60/* defines below are from ivtv-driver.h */
61
62#define IVTV_CMD_HW_BLOCKS_RST 0xFFFFFFFF
63
64/*Firmware API commands*/
65#define IVTV_API_ENC_PING_FW 0x00000080
66#define IVTV_API_ENC_GETVER 0x000000C4
67#define IVTV_API_ENC_HALT_FW 0x000000C3
68#define IVTV_API_STD_TIMEOUT 0x00010000 /*units??*/
69//#define IVTV_API_ASSIGN_PGM_INDEX_INFO 0x000000c7
70#define IVTV_API_ASSIGN_STREAM_TYPE 0x000000b9
71#define IVTV_API_ASSIGN_OUTPUT_PORT 0x000000bb
72#define IVTV_API_ASSIGN_FRAMERATE 0x0000008f
73#define IVTV_API_ASSIGN_FRAME_SIZE 0x00000091
74#define IVTV_API_ASSIGN_ASPECT_RATIO 0x00000099
75#define IVTV_API_ASSIGN_BITRATES 0x00000095
76#define IVTV_API_ASSIGN_GOP_PROPERTIES 0x00000097
77#define IVTV_API_ASSIGN_3_2_PULLDOWN 0x000000b1
78#define IVTV_API_ASSIGN_GOP_CLOSURE 0x000000c5
79#define IVTV_API_ASSIGN_AUDIO_PROPERTIES 0x000000bd
80#define IVTV_API_ASSIGN_DNR_FILTER_MODE 0x0000009b
81#define IVTV_API_ASSIGN_DNR_FILTER_PROPS 0x0000009d
82#define IVTV_API_ASSIGN_CORING_LEVELS 0x0000009f
83#define IVTV_API_ASSIGN_SPATIAL_FILTER_TYPE 0x000000a1
84#define IVTV_API_ASSIGN_FRAME_DROP_RATE 0x000000d0
85#define IVTV_API_ASSIGN_PLACEHOLDER 0x000000d8
86#define IVTV_API_MUTE_VIDEO 0x000000d9
87#define IVTV_API_MUTE_AUDIO 0x000000da
88#define IVTV_API_INITIALIZE_INPUT 0x000000cd
89#define IVTV_API_REFRESH_INPUT 0x000000d3
90#define IVTV_API_ASSIGN_NUM_VSYNC_LINES 0x000000d6
91#define IVTV_API_BEGIN_CAPTURE 0x00000081
92//#define IVTV_API_PAUSE_ENCODER 0x000000d2
93//#define IVTV_API_EVENT_NOTIFICATION 0x000000d5
94#define IVTV_API_END_CAPTURE 0x00000082
95
96/* Registers */
97#define IVTV_REG_ENC_SDRAM_REFRESH (0x07F8 /*| IVTV_REG_OFFSET*/)
98#define IVTV_REG_ENC_SDRAM_PRECHARGE (0x07FC /*| IVTV_REG_OFFSET*/)
99#define IVTV_REG_SPU (0x9050 /*| IVTV_REG_OFFSET*/)
100#define IVTV_REG_HW_BLOCKS (0x9054 /*| IVTV_REG_OFFSET*/)
101#define IVTV_REG_VPU (0x9058 /*| IVTV_REG_OFFSET*/)
102#define IVTV_REG_APU (0xA064 /*| IVTV_REG_OFFSET*/)
103
104/* ------------------------------------------------------------------ */
105
106static void host_setup(struct cx88_core *core)
107{
108 /* toggle reset of the host */
109 cx_write(MO_GPHST_SOFT_RST, 1);
110 udelay(100);
111 cx_write(MO_GPHST_SOFT_RST, 0);
112 udelay(100);
113
114 /* host port setup */
115 cx_write(MO_GPHST_WSC, 0x44444444U);
116 cx_write(MO_GPHST_XFR, 0);
117 cx_write(MO_GPHST_WDTH, 15);
118 cx_write(MO_GPHST_HDSHK, 0);
119 cx_write(MO_GPHST_MUX16, 0x44448888U);
120 cx_write(MO_GPHST_MODE, 0);
121}
122
123/* ------------------------------------------------------------------ */
124
125#define P1_MDATA0 0x390000
126#define P1_MDATA1 0x390001
127#define P1_MDATA2 0x390002
128#define P1_MDATA3 0x390003
129#define P1_MADDR2 0x390004
130#define P1_MADDR1 0x390005
131#define P1_MADDR0 0x390006
132#define P1_RDATA0 0x390008
133#define P1_RDATA1 0x390009
134#define P1_RDATA2 0x39000A
135#define P1_RDATA3 0x39000B
136#define P1_RADDR0 0x39000C
137#define P1_RADDR1 0x39000D
138#define P1_RRDWR 0x39000E
139
140static int wait_ready_gpio0_bit1(struct cx88_core *core, u32 state)
141{
142 unsigned long timeout = jiffies + msecs_to_jiffies(1);
143 u32 gpio0,need;
144
145 need = state ? 2 : 0;
146 for (;;) {
147 gpio0 = cx_read(MO_GP0_IO) & 2;
148 if (need == gpio0)
149 return 0;
150 if (time_after(jiffies,timeout))
151 return -1;
152 udelay(1);
153 }
154}
155
156static int memory_write(struct cx88_core *core, u32 address, u32 value)
157{
158 /* Warning: address is dword address (4 bytes) */
159 cx_writeb(P1_MDATA0, (unsigned int)value);
160 cx_writeb(P1_MDATA1, (unsigned int)(value >> 8));
161 cx_writeb(P1_MDATA2, (unsigned int)(value >> 16));
162 cx_writeb(P1_MDATA3, (unsigned int)(value >> 24));
163 cx_writeb(P1_MADDR2, (unsigned int)(address >> 16) | 0x40);
164 cx_writeb(P1_MADDR1, (unsigned int)(address >> 8));
165 cx_writeb(P1_MADDR0, (unsigned int)address);
166 cx_read(P1_MDATA0);
167 cx_read(P1_MADDR0);
168
169 return wait_ready_gpio0_bit1(core,1);
170}
171
172static int memory_read(struct cx88_core *core, u32 address, u32 *value)
173{
174 int retval;
175 u32 val;
176
177 /* Warning: address is dword address (4 bytes) */
178 cx_writeb(P1_MADDR2, (unsigned int)(address >> 16) & ~0xC0);
179 cx_writeb(P1_MADDR1, (unsigned int)(address >> 8));
180 cx_writeb(P1_MADDR0, (unsigned int)address);
181 cx_read(P1_MADDR0);
182
183 retval = wait_ready_gpio0_bit1(core,1);
184
185 cx_writeb(P1_MDATA3, 0);
186 val = (unsigned char)cx_read(P1_MDATA3) << 24;
187 cx_writeb(P1_MDATA2, 0);
188 val |= (unsigned char)cx_read(P1_MDATA2) << 16;
189 cx_writeb(P1_MDATA1, 0);
190 val |= (unsigned char)cx_read(P1_MDATA1) << 8;
191 cx_writeb(P1_MDATA0, 0);
192 val |= (unsigned char)cx_read(P1_MDATA0);
193
194 *value = val;
195 return retval;
196}
197
198static int register_write(struct cx88_core *core, u32 address, u32 value)
199{
200 cx_writeb(P1_RDATA0, (unsigned int)value);
201 cx_writeb(P1_RDATA1, (unsigned int)(value >> 8));
202 cx_writeb(P1_RDATA2, (unsigned int)(value >> 16));
203 cx_writeb(P1_RDATA3, (unsigned int)(value >> 24));
204 cx_writeb(P1_RADDR0, (unsigned int)address);
205 cx_writeb(P1_RADDR1, (unsigned int)(address >> 8));
206 cx_writeb(P1_RRDWR, 1);
207 cx_read(P1_RDATA0);
208 cx_read(P1_RADDR0);
209
210 return wait_ready_gpio0_bit1(core,1);
211}
212
213
214static int register_read(struct cx88_core *core, u32 address, u32 *value)
215{
216 int retval;
217 u32 val;
218
219 cx_writeb(P1_RADDR0, (unsigned int)address);
220 cx_writeb(P1_RADDR1, (unsigned int)(address >> 8));
221 cx_writeb(P1_RRDWR, 0);
222 cx_read(P1_RADDR0);
223
224 retval = wait_ready_gpio0_bit1(core,1);
225 val = (unsigned char)cx_read(P1_RDATA0);
226 val |= (unsigned char)cx_read(P1_RDATA1) << 8;
227 val |= (unsigned char)cx_read(P1_RDATA2) << 16;
228 val |= (unsigned char)cx_read(P1_RDATA3) << 24;
229
230 *value = val;
231 return retval;
232}
233
234/* ------------------------------------------------------------------ */
235
236/* We don't need to call the API often, so using just one mailbox will probably suffice */
237static int blackbird_api_cmd(struct cx8802_dev *dev, u32 command,
238 u32 inputcnt, u32 outputcnt, ...)
239{
240 unsigned long timeout;
241 u32 value, flag, retval;
242 int i;
243 va_list args;
244 va_start(args, outputcnt);
245
246 dprintk(1,"%s: 0x%X\n", __FUNCTION__, command);
247
248 /* this may not be 100% safe if we can't read any memory location
249 without side effects */
250 memory_read(dev->core, dev->mailbox - 4, &value);
251 if (value != 0x12345678) {
252 dprintk(0, "Firmware and/or mailbox pointer not initialized or corrupted\n");
253 return -1;
254 }
255
256 memory_read(dev->core, dev->mailbox, &flag);
257 if (flag) {
258 dprintk(0, "ERROR: Mailbox appears to be in use (%x)\n", flag);
259 return -1;
260 }
261
262 flag |= 1; /* tell 'em we're working on it */
263 memory_write(dev->core, dev->mailbox, flag);
264
265 /* write command + args + fill remaining with zeros */
266 memory_write(dev->core, dev->mailbox + 1, command); /* command code */
267 memory_write(dev->core, dev->mailbox + 3, IVTV_API_STD_TIMEOUT); /* timeout */
268 for (i = 0; i < inputcnt ; i++) {
269 value = va_arg(args, int);
270 memory_write(dev->core, dev->mailbox + 4 + i, value);
271 dprintk(1, "API Input %d = %d\n", i, value);
272 }
273 for (; i < 16 ; i++)
274 memory_write(dev->core, dev->mailbox + 4 + i, 0);
275
276 flag |= 3; /* tell 'em we're done writing */
277 memory_write(dev->core, dev->mailbox, flag);
278
279 /* wait for firmware to handle the API command */
280 timeout = jiffies + msecs_to_jiffies(10);
281 for (;;) {
282 memory_read(dev->core, dev->mailbox, &flag);
283 if (0 != (flag & 4))
284 break;
285 if (time_after(jiffies,timeout)) {
286 dprintk(0, "ERROR: API Mailbox timeout\n");
287 return -1;
288 }
289 udelay(10);
290 }
291
292 /* read output values */
293 for (i = 0; i < outputcnt ; i++) {
294 int *vptr = va_arg(args, int *);
295 memory_read(dev->core, dev->mailbox + 4 + i, vptr);
296 dprintk(1, "API Output %d = %d\n", i, *vptr);
297 }
298 va_end(args);
299
300 memory_read(dev->core, dev->mailbox + 2, &retval);
301 dprintk(1, "API result = %d\n",retval);
302
303 flag = 0;
304 memory_write(dev->core, dev->mailbox, flag);
305 return retval;
306}
307
308
309static int blackbird_find_mailbox(struct cx8802_dev *dev)
310{
311 u32 signature[4]={0x12345678, 0x34567812, 0x56781234, 0x78123456};
312 int signaturecnt=0;
313 u32 value;
314 int i;
315
316 for (i = 0; i < BLACKBIRD_FIRM_IMAGE_SIZE; i++) {
317 memory_read(dev->core, i, &value);
318 if (value == signature[signaturecnt])
319 signaturecnt++;
320 else
321 signaturecnt = 0;
322 if (4 == signaturecnt) {
323 dprintk(1, "Mailbox signature found\n");
324 return i+1;
325 }
326 }
327 dprintk(0, "Mailbox signature values not found!\n");
328 return -1;
329}
330
331static int blackbird_load_firmware(struct cx8802_dev *dev)
332{
333 static const unsigned char magic[8] = {
334 0xa7, 0x0d, 0x00, 0x00, 0x66, 0xbb, 0x55, 0xaa
335 };
336 const struct firmware *firmware;
337 int i, retval = 0;
338 u32 value = 0;
339 u32 checksum = 0;
340 u32 *dataptr;
341
342 retval = register_write(dev->core, IVTV_REG_VPU, 0xFFFFFFED);
343 retval |= register_write(dev->core, IVTV_REG_HW_BLOCKS, IVTV_CMD_HW_BLOCKS_RST);
344 retval |= register_write(dev->core, IVTV_REG_ENC_SDRAM_REFRESH, 0x80000640);
345 retval |= register_write(dev->core, IVTV_REG_ENC_SDRAM_PRECHARGE, 0x1A);
346 msleep(1);
347 retval |= register_write(dev->core, IVTV_REG_APU, 0);
348
349 if (retval < 0)
350 dprintk(0, "Error with register_write\n");
351
352 retval = request_firmware(&firmware, BLACKBIRD_FIRM_ENC_FILENAME,
353 &dev->pci->dev);
354 if (retval != 0) {
355 dprintk(0, "ERROR: Hotplug firmware request failed (%s).\n",
356 BLACKBIRD_FIRM_ENC_FILENAME);
357 dprintk(0, "Please fix your hotplug setup, the board will "
358 "not work without firmware loaded!\n");
359 return -1;
360 }
361
362 if (firmware->size != BLACKBIRD_FIRM_IMAGE_SIZE) {
363 dprintk(0, "ERROR: Firmware size mismatch (have %zd, expected %d)\n",
364 firmware->size, BLACKBIRD_FIRM_IMAGE_SIZE);
365 return -1;
366 }
367
368 if (0 != memcmp(firmware->data, magic, 8)) {
369 dprintk(0, "ERROR: Firmware magic mismatch, wrong file?\n");
370 return -1;
371 }
372
373 /* transfer to the chip */
374 dprintk(1,"Loading firmware ...\n");
375 dataptr = (u32*)firmware->data;
376 for (i = 0; i < (firmware->size >> 2); i++) {
377 value = *dataptr;
378 checksum += ~value;
379 memory_write(dev->core, i, value);
380 dataptr++;
381 }
382
383 /* read back to verify with the checksum */
384 for (i--; i >= 0; i--) {
385 memory_read(dev->core, i, &value);
386 checksum -= ~value;
387 }
388 if (checksum) {
389 dprintk(0, "ERROR: Firmware load failed (checksum mismatch).\n");
390 return -1;
391 }
392 release_firmware(firmware);
393 dprintk(0, "Firmware upload successful.\n");
394
395 retval |= register_write(dev->core, IVTV_REG_HW_BLOCKS, IVTV_CMD_HW_BLOCKS_RST);
396 retval |= register_read(dev->core, IVTV_REG_SPU, &value);
397 retval |= register_write(dev->core, IVTV_REG_SPU, value & 0xFFFFFFFE);
398 msleep(1);
399
400 retval |= register_read(dev->core, IVTV_REG_VPU, &value);
401 retval |= register_write(dev->core, IVTV_REG_VPU, value & 0xFFFFFFE8);
402
403 if (retval < 0)
404 dprintk(0, "Error with register_write\n");
405 return 0;
406}
407
408static void blackbird_codec_settings(struct cx8802_dev *dev)
409{
410 int bitrate_mode = 1;
411 int bitrate = 7500000;
412 int bitrate_peak = 7500000;
413
414 /* assign stream type */
415 blackbird_api_cmd(dev, IVTV_API_ASSIGN_STREAM_TYPE, 1, 0, 0); /* program stream */
416 //blackbird_api_cmd(dev, IVTV_API_ASSIGN_STREAM_TYPE, 1, 0, 2); /* MPEG1 stream */
417 //blackbird_api_cmd(dev, IVTV_API_ASSIGN_STREAM_TYPE, 1, 0, 3); /* PES A/V */
418 //blackbird_api_cmd(dev, IVTV_API_ASSIGN_STREAM_TYPE, 1, 0, 10); /* DVD stream */
419
420 /* assign output port */
421 blackbird_api_cmd(dev, IVTV_API_ASSIGN_OUTPUT_PORT, 1, 0, 1); /* 1 = Host */
422
423 /* assign framerate */
424 blackbird_api_cmd(dev, IVTV_API_ASSIGN_FRAMERATE, 1, 0, 0);
425
426 /* assign frame size */
427 blackbird_api_cmd(dev, IVTV_API_ASSIGN_FRAME_SIZE, 2, 0,
428 dev->height, dev->width);
429
430 /* assign aspect ratio */
431 blackbird_api_cmd(dev, IVTV_API_ASSIGN_ASPECT_RATIO, 1, 0, 2);
432
433 /* assign bitrates */
434 blackbird_api_cmd(dev, IVTV_API_ASSIGN_BITRATES, 5, 0,
435 bitrate_mode, /* mode */
436 bitrate, /* bps */
437 bitrate_peak / 400, /* peak/400 */
438 0, 0x70); /* encoding buffer, ckennedy */
439
440 /* assign gop properties */
441 blackbird_api_cmd(dev, IVTV_API_ASSIGN_GOP_PROPERTIES, 2, 0, 15, 3);
442 //blackbird_api_cmd(dev, IVTV_API_ASSIGN_GOP_PROPERTIES, 2, 0, 2, 1);
443
444 /* assign 3 2 pulldown */
445 blackbird_api_cmd(dev, IVTV_API_ASSIGN_3_2_PULLDOWN, 1, 0, 0);
446
447 /* note: it's not necessary to set the samplerate, the mpeg encoder seems to autodetect/adjust */
448 blackbird_api_cmd(dev, IVTV_API_ASSIGN_AUDIO_PROPERTIES, 1, 0, (2<<2) | (8<<4));
449
450 /* assign gop closure */
451 blackbird_api_cmd(dev, IVTV_API_ASSIGN_GOP_CLOSURE, 1, 0, 0);
452
453 /* assign audio properties */
454 blackbird_api_cmd(dev, IVTV_API_ASSIGN_AUDIO_PROPERTIES, 1, 0, 0 | (2 << 2) | (14 << 4));
455
456 /* assign dnr filter mode */
457 blackbird_api_cmd(dev, IVTV_API_ASSIGN_DNR_FILTER_MODE, 2, 0, 0, 0);
458
459 /* assign dnr filter props*/
460 blackbird_api_cmd(dev, IVTV_API_ASSIGN_DNR_FILTER_PROPS, 2, 0, 0, 0);
461
462 /* assign coring levels (luma_h, luma_l, chroma_h, chroma_l) */
463 blackbird_api_cmd(dev, IVTV_API_ASSIGN_CORING_LEVELS, 4, 0, 0, 255, 0, 255);
464
465 /* assign spatial filter type: luma_t: 1 = horiz_only, chroma_t: 1 = horiz_only */
466 blackbird_api_cmd(dev, IVTV_API_ASSIGN_SPATIAL_FILTER_TYPE, 2, 0, 1, 1);
467
468 /* assign frame drop rate */
469 blackbird_api_cmd(dev, IVTV_API_ASSIGN_FRAME_DROP_RATE, 1, 0, 0);
470}
471
472static int blackbird_initialize_codec(struct cx8802_dev *dev)
473{
474 struct cx88_core *core = dev->core;
475 int version;
476 int retval;
477
478 dprintk(1,"Initialize codec\n");
479 retval = blackbird_api_cmd(dev, IVTV_API_ENC_PING_FW, 0, 0); /* ping */
480 if (retval < 0) {
481 /* ping was not successful, reset and upload firmware */
482 cx_write(MO_SRST_IO, 0); /* SYS_RSTO=0 */
483 msleep(1);
484 cx_write(MO_SRST_IO, 1); /* SYS_RSTO=1 */
485 msleep(1);
486 retval = blackbird_load_firmware(dev);
487 if (retval < 0)
488 return retval;
489
490 dev->mailbox = blackbird_find_mailbox(dev);
491 if (dev->mailbox < 0)
492 return -1;
493
494 retval = blackbird_api_cmd(dev, IVTV_API_ENC_PING_FW, 0, 0); /* ping */
495 if (retval < 0) {
496 dprintk(0, "ERROR: Firmware ping failed!\n");
497 return -1;
498 }
499
500 retval = blackbird_api_cmd(dev, IVTV_API_ENC_GETVER, 0, 1, &version);
501 if (retval < 0) {
502 dprintk(0, "ERROR: Firmware get encoder version failed!\n");
503 return -1;
504 }
505 dprintk(0, "Firmware version is 0x%08x\n", version);
506 }
507 msleep(1);
508
509 cx_write(MO_PINMUX_IO, 0x88); /* 656-8bit IO and enable MPEG parallel IO */
510 cx_clear(MO_INPUT_FORMAT, 0x100); /* chroma subcarrier lock to normal? */
511 cx_write(MO_VBOS_CONTROL, 0x84A00); /* no 656 mode, 8-bit pixels, disable VBI */
512 cx_clear(MO_OUTPUT_FORMAT, 0x0008); /* Normal Y-limits to let the mpeg encoder sync */
513
514#if 0 /* FIXME */
515 set_scale(dev, 720, 480, V4L2_FIELD_INTERLACED);
516#endif
517 blackbird_codec_settings(dev);
518 msleep(1);
519
520 //blackbird_api_cmd(dev, IVTV_API_ASSIGN_NUM_VSYNC_LINES, 4, 0, 0xef, 0xef);
521 blackbird_api_cmd(dev, IVTV_API_ASSIGN_NUM_VSYNC_LINES, 4, 0, 0xf0, 0xf0);
522 //blackbird_api_cmd(dev, IVTV_API_ASSIGN_NUM_VSYNC_LINES, 4, 0, 0x180, 0x180);
523 blackbird_api_cmd(dev, IVTV_API_ASSIGN_PLACEHOLDER, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
524
525 blackbird_api_cmd(dev, IVTV_API_INITIALIZE_INPUT, 0, 0); /* initialize the video input */
526
527 msleep(1);
528
529 blackbird_api_cmd(dev, IVTV_API_MUTE_VIDEO, 1, 0, 0);
530 msleep(1);
531 blackbird_api_cmd(dev, IVTV_API_MUTE_AUDIO, 1, 0, 0);
532 msleep(1);
533
534 blackbird_api_cmd(dev, IVTV_API_BEGIN_CAPTURE, 2, 0, 0, 0x13); /* start capturing to the host interface */
535 //blackbird_api_cmd(dev, IVTV_API_BEGIN_CAPTURE, 2, 0, 0, 0); /* start capturing to the host interface */
536 msleep(1);
537
538 blackbird_api_cmd(dev, IVTV_API_REFRESH_INPUT, 0,0);
539 return 0;
540}
541
542/* ------------------------------------------------------------------ */
543
544static int bb_buf_setup(struct videobuf_queue *q,
545 unsigned int *count, unsigned int *size)
546{
547 struct cx8802_fh *fh = q->priv_data;
548
549 fh->dev->ts_packet_size = 512;
550 fh->dev->ts_packet_count = 100;
551
552 *size = fh->dev->ts_packet_size * fh->dev->ts_packet_count;
553 if (0 == *count)
554 *count = mpegbufs;
555 if (*count < 2)
556 *count = 2;
557 if (*count > 32)
558 *count = 32;
559 return 0;
560}
561
562static int
563bb_buf_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
564 enum v4l2_field field)
565{
566 struct cx8802_fh *fh = q->priv_data;
567 return cx8802_buf_prepare(fh->dev, (struct cx88_buffer*)vb);
568}
569
570static void
571bb_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
572{
573 struct cx8802_fh *fh = q->priv_data;
574 cx8802_buf_queue(fh->dev, (struct cx88_buffer*)vb);
575}
576
577static void
578bb_buf_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
579{
580 struct cx8802_fh *fh = q->priv_data;
581 cx88_free_buffer(fh->dev->pci, (struct cx88_buffer*)vb);
582}
583
584static struct videobuf_queue_ops blackbird_qops = {
585 .buf_setup = bb_buf_setup,
586 .buf_prepare = bb_buf_prepare,
587 .buf_queue = bb_buf_queue,
588 .buf_release = bb_buf_release,
589};
590
591/* ------------------------------------------------------------------ */
592
593static int mpeg_do_ioctl(struct inode *inode, struct file *file,
594 unsigned int cmd, void *arg)
595{
596 struct cx8802_fh *fh = file->private_data;
597 struct cx8802_dev *dev = fh->dev;
598
599 if (debug > 1)
600 cx88_print_ioctl(dev->core->name,cmd);
601
602 switch (cmd) {
603
604 /* --- capture ioctls ---------------------------------------- */
605 case VIDIOC_ENUM_FMT:
606 {
607 struct v4l2_fmtdesc *f = arg;
608 int index;
609
610 index = f->index;
611 if (index != 0)
612 return -EINVAL;
613
614 memset(f,0,sizeof(*f));
615 f->index = index;
616 strlcpy(f->description, "MPEG TS", sizeof(f->description));
617 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
618 f->pixelformat = V4L2_PIX_FMT_MPEG;
619 return 0;
620 }
621 case VIDIOC_G_FMT:
622 case VIDIOC_S_FMT:
623 case VIDIOC_TRY_FMT:
624 {
625 /* FIXME -- quick'n'dirty for exactly one size ... */
626 struct v4l2_format *f = arg;
627
628 memset(f,0,sizeof(*f));
629 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
630 f->fmt.pix.width = dev->width;
631 f->fmt.pix.height = dev->height;
632 f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
633 f->fmt.pix.sizeimage = 1024 * 512 /* FIXME: BUFFER_SIZE */;
634 }
635
636 /* --- streaming capture ------------------------------------- */
637 case VIDIOC_REQBUFS:
638 return videobuf_reqbufs(&fh->mpegq, arg);
639
640 case VIDIOC_QUERYBUF:
641 return videobuf_querybuf(&fh->mpegq, arg);
642
643 case VIDIOC_QBUF:
644 return videobuf_qbuf(&fh->mpegq, arg);
645
646 case VIDIOC_DQBUF:
647 return videobuf_dqbuf(&fh->mpegq, arg,
648 file->f_flags & O_NONBLOCK);
649
650 case VIDIOC_STREAMON:
651 return videobuf_streamon(&fh->mpegq);
652
653 case VIDIOC_STREAMOFF:
654 return videobuf_streamoff(&fh->mpegq);
655
656 default:
657 return -EINVAL;
658 }
659 return 0;
660}
661
662static int mpeg_ioctl(struct inode *inode, struct file *file,
663 unsigned int cmd, unsigned long arg)
664{
665 return video_usercopy(inode, file, cmd, arg, mpeg_do_ioctl);
666}
667
668static int mpeg_open(struct inode *inode, struct file *file)
669{
670 int minor = iminor(inode);
671 struct cx8802_dev *h,*dev = NULL;
672 struct cx8802_fh *fh;
673 struct list_head *list;
674
675 list_for_each(list,&cx8802_devlist) {
676 h = list_entry(list, struct cx8802_dev, devlist);
677 if (h->mpeg_dev->minor == minor)
678 dev = h;
679 }
680 if (NULL == dev)
681 return -ENODEV;
682
683 if (blackbird_initialize_codec(dev) < 0)
684 return -EINVAL;
685 dprintk(1,"open minor=%d\n",minor);
686
687 /* allocate + initialize per filehandle data */
688 fh = kmalloc(sizeof(*fh),GFP_KERNEL);
689 if (NULL == fh)
690 return -ENOMEM;
691 memset(fh,0,sizeof(*fh));
692 file->private_data = fh;
693 fh->dev = dev;
694
695 /* FIXME: locking against other video device */
696 cx88_set_scale(dev->core, dev->width, dev->height,
697 V4L2_FIELD_INTERLACED);
698
699 videobuf_queue_init(&fh->mpegq, &blackbird_qops,
700 dev->pci, &dev->slock,
701 V4L2_BUF_TYPE_VIDEO_CAPTURE,
702 V4L2_FIELD_TOP,
703 sizeof(struct cx88_buffer),
704 fh);
705 return 0;
706}
707
708static int mpeg_release(struct inode *inode, struct file *file)
709{
710 struct cx8802_fh *fh = file->private_data;
711
712 blackbird_api_cmd(fh->dev, IVTV_API_END_CAPTURE, 3, 0, 1, 0, 0x13);
713
714 /* stop mpeg capture */
715 if (fh->mpegq.streaming)
716 videobuf_streamoff(&fh->mpegq);
717 if (fh->mpegq.reading)
718 videobuf_read_stop(&fh->mpegq);
719
720 videobuf_mmap_free(&fh->mpegq);
721 file->private_data = NULL;
722 kfree(fh);
723 return 0;
724}
725
726static ssize_t
727mpeg_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
728{
729 struct cx8802_fh *fh = file->private_data;
730
731 return videobuf_read_stream(&fh->mpegq, data, count, ppos, 0,
732 file->f_flags & O_NONBLOCK);
733}
734
735static unsigned int
736mpeg_poll(struct file *file, struct poll_table_struct *wait)
737{
738 struct cx8802_fh *fh = file->private_data;
739
740 return videobuf_poll_stream(file, &fh->mpegq, wait);
741}
742
743static int
744mpeg_mmap(struct file *file, struct vm_area_struct * vma)
745{
746 struct cx8802_fh *fh = file->private_data;
747
748 return videobuf_mmap_mapper(&fh->mpegq, vma);
749}
750
751static struct file_operations mpeg_fops =
752{
753 .owner = THIS_MODULE,
754 .open = mpeg_open,
755 .release = mpeg_release,
756 .read = mpeg_read,
757 .poll = mpeg_poll,
758 .mmap = mpeg_mmap,
759 .ioctl = mpeg_ioctl,
760 .llseek = no_llseek,
761};
762
763static struct video_device cx8802_mpeg_template =
764{
765 .name = "cx8802",
766 .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER|VID_TYPE_SCALES|VID_TYPE_MPEG_ENCODER,
767 .hardware = 0,
768 .fops = &mpeg_fops,
769 .minor = -1,
770};
771
772/* ------------------------------------------------------------------ */
773
774static void blackbird_unregister_video(struct cx8802_dev *dev)
775{
776 if (dev->mpeg_dev) {
777 if (-1 != dev->mpeg_dev->minor)
778 video_unregister_device(dev->mpeg_dev);
779 else
780 video_device_release(dev->mpeg_dev);
781 dev->mpeg_dev = NULL;
782 }
783}
784
785static int blackbird_register_video(struct cx8802_dev *dev)
786{
787 int err;
788
789 dev->mpeg_dev = cx88_vdev_init(dev->core,dev->pci,
790 &cx8802_mpeg_template,"mpeg");
791 err = video_register_device(dev->mpeg_dev,VFL_TYPE_GRABBER, -1);
792 if (err < 0) {
793 printk(KERN_INFO "%s/2: can't register mpeg device\n",
794 dev->core->name);
795 return err;
796 }
797 printk(KERN_INFO "%s/2: registered device video%d [mpeg]\n",
798 dev->core->name,dev->mpeg_dev->minor & 0x1f);
799 return 0;
800}
801
802/* ----------------------------------------------------------- */
803
804static int __devinit blackbird_probe(struct pci_dev *pci_dev,
805 const struct pci_device_id *pci_id)
806{
807 struct cx8802_dev *dev;
808 struct cx88_core *core;
809 int err;
810
811 /* general setup */
812 core = cx88_core_get(pci_dev);
813 if (NULL == core)
814 return -EINVAL;
815
816 err = -ENODEV;
817 if (!cx88_boards[core->board].blackbird)
818 goto fail_core;
819
820 err = -ENOMEM;
821 dev = kmalloc(sizeof(*dev),GFP_KERNEL);
822 if (NULL == dev)
823 goto fail_core;
824 memset(dev,0,sizeof(*dev));
825 dev->pci = pci_dev;
826 dev->core = core;
827 dev->width = 720;
828 dev->height = 480;
829
830 err = cx8802_init_common(dev);
831 if (0 != err)
832 goto fail_free;
833
834 /* blackbird stuff */
835 printk("%s/2: cx23416 based mpeg encoder (blackbird reference design)\n",
836 core->name);
837 host_setup(dev->core);
838
839 list_add_tail(&dev->devlist,&cx8802_devlist);
840 blackbird_register_video(dev);
841 return 0;
842
843 fail_free:
844 kfree(dev);
845 fail_core:
846 cx88_core_put(core,pci_dev);
847 return err;
848}
849
850static void __devexit blackbird_remove(struct pci_dev *pci_dev)
851{
852 struct cx8802_dev *dev = pci_get_drvdata(pci_dev);
853
854 /* blackbird */
855 blackbird_unregister_video(dev);
856 list_del(&dev->devlist);
857
858 /* common */
859 cx8802_fini_common(dev);
860 cx88_core_put(dev->core,dev->pci);
861 kfree(dev);
862}
863
864static struct pci_device_id cx8802_pci_tbl[] = {
865 {
866 .vendor = 0x14f1,
867 .device = 0x8802,
868 .subvendor = PCI_ANY_ID,
869 .subdevice = PCI_ANY_ID,
870 },{
871 /* --- end of list --- */
872 }
873};
874MODULE_DEVICE_TABLE(pci, cx8802_pci_tbl);
875
876static struct pci_driver blackbird_pci_driver = {
877 .name = "cx88-blackbird",
878 .id_table = cx8802_pci_tbl,
879 .probe = blackbird_probe,
880 .remove = __devexit_p(blackbird_remove),
881 .suspend = cx8802_suspend_common,
882 .resume = cx8802_resume_common,
883};
884
885static int blackbird_init(void)
886{
887 printk(KERN_INFO "cx2388x blackbird driver version %d.%d.%d loaded\n",
888 (CX88_VERSION_CODE >> 16) & 0xff,
889 (CX88_VERSION_CODE >> 8) & 0xff,
890 CX88_VERSION_CODE & 0xff);
891#ifdef SNAPSHOT
892 printk(KERN_INFO "cx2388x: snapshot date %04d-%02d-%02d\n",
893 SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100);
894#endif
895 return pci_register_driver(&blackbird_pci_driver);
896}
897
898static void blackbird_fini(void)
899{
900 pci_unregister_driver(&blackbird_pci_driver);
901}
902
903module_init(blackbird_init);
904module_exit(blackbird_fini);
905
906/* ----------------------------------------------------------- */
907/*
908 * Local variables:
909 * c-basic-offset: 8
910 * End:
911 */
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c
new file mode 100644
index 00000000000..367624822d7
--- /dev/null
+++ b/drivers/media/video/cx88/cx88-cards.c
@@ -0,0 +1,938 @@
1/*
2 * $Id: cx88-cards.c,v 1.66 2005/03/04 09:12:23 kraxel Exp $
3 *
4 * device driver for Conexant 2388x based TV cards
5 * card-specific stuff.
6 *
7 * (c) 2003 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
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#include <linux/init.h>
25#include <linux/module.h>
26#include <linux/pci.h>
27#include <linux/delay.h>
28
29#include "cx88.h"
30
31/* ------------------------------------------------------------------ */
32/* board config info */
33
34struct cx88_board cx88_boards[] = {
35 [CX88_BOARD_UNKNOWN] = {
36 .name = "UNKNOWN/GENERIC",
37 .tuner_type = UNSET,
38 .input = {{
39 .type = CX88_VMUX_COMPOSITE1,
40 .vmux = 0,
41 },{
42 .type = CX88_VMUX_COMPOSITE2,
43 .vmux = 1,
44 },{
45 .type = CX88_VMUX_COMPOSITE3,
46 .vmux = 2,
47 },{
48 .type = CX88_VMUX_COMPOSITE4,
49 .vmux = 3,
50 }},
51 },
52 [CX88_BOARD_HAUPPAUGE] = {
53 .name = "Hauppauge WinTV 34xxx models",
54 .tuner_type = UNSET,
55 .tda9887_conf = TDA9887_PRESENT,
56 .input = {{
57 .type = CX88_VMUX_TELEVISION,
58 .vmux = 0,
59 .gpio0 = 0xff00, // internal decoder
60 },{
61 .type = CX88_VMUX_DEBUG,
62 .vmux = 0,
63 .gpio0 = 0xff01, // mono from tuner chip
64 },{
65 .type = CX88_VMUX_COMPOSITE1,
66 .vmux = 1,
67 .gpio0 = 0xff02,
68 },{
69 .type = CX88_VMUX_SVIDEO,
70 .vmux = 2,
71 .gpio0 = 0xff02,
72 }},
73 .radio = {
74 .type = CX88_RADIO,
75 .gpio0 = 0xff01,
76 },
77 },
78 [CX88_BOARD_GDI] = {
79 .name = "GDI Black Gold",
80 .tuner_type = UNSET,
81 .input = {{
82 .type = CX88_VMUX_TELEVISION,
83 .vmux = 0,
84 }},
85 },
86 [CX88_BOARD_PIXELVIEW] = {
87 .name = "PixelView",
88 .tuner_type = 5,
89 .input = {{
90 .type = CX88_VMUX_TELEVISION,
91 .vmux = 0,
92 .gpio0 = 0xff00, // internal decoder
93 },{
94 .type = CX88_VMUX_COMPOSITE1,
95 .vmux = 1,
96 },{
97 .type = CX88_VMUX_SVIDEO,
98 .vmux = 2,
99 }},
100 .radio = {
101 .type = CX88_RADIO,
102 .gpio0 = 0xff10,
103 },
104 },
105 [CX88_BOARD_ATI_WONDER_PRO] = {
106 .name = "ATI TV Wonder Pro",
107 .tuner_type = 44,
108 .tda9887_conf = TDA9887_PRESENT | TDA9887_INTERCARRIER,
109 .input = {{
110 .type = CX88_VMUX_TELEVISION,
111 .vmux = 0,
112 .gpio0 = 0x03ff,
113 },{
114 .type = CX88_VMUX_COMPOSITE1,
115 .vmux = 1,
116 .gpio0 = 0x03fe,
117 },{
118 .type = CX88_VMUX_SVIDEO,
119 .vmux = 2,
120 .gpio0 = 0x03fe,
121 }},
122 },
123 [CX88_BOARD_WINFAST2000XP_EXPERT] = {
124 .name = "Leadtek Winfast 2000XP Expert",
125 .tuner_type = 44,
126 .tda9887_conf = TDA9887_PRESENT,
127 .input = {{
128 .type = CX88_VMUX_TELEVISION,
129 .vmux = 0,
130 .gpio0 = 0x00F5e700,
131 .gpio1 = 0x00003004,
132 .gpio2 = 0x00F5e700,
133 .gpio3 = 0x02000000,
134 },{
135 .type = CX88_VMUX_COMPOSITE1,
136 .vmux = 1,
137 .gpio0 = 0x00F5c700,
138 .gpio1 = 0x00003004,
139 .gpio2 = 0x00F5c700,
140 .gpio3 = 0x02000000,
141 },{
142 .type = CX88_VMUX_SVIDEO,
143 .vmux = 2,
144 .gpio0 = 0x00F5c700,
145 .gpio1 = 0x00003004,
146 .gpio2 = 0x00F5c700,
147 .gpio3 = 0x02000000,
148 }},
149 .radio = {
150 .type = CX88_RADIO,
151 .gpio0 = 0x00F5d700,
152 .gpio1 = 0x00003004,
153 .gpio2 = 0x00F5d700,
154 .gpio3 = 0x02000000,
155 },
156 },
157 [CX88_BOARD_AVERTV_303] = {
158 .name = "AverTV Studio 303 (M126)",
159 .tuner_type = 38,
160 .tda9887_conf = TDA9887_PRESENT,
161 .input = {{
162 .type = CX88_VMUX_TELEVISION,
163 .vmux = 0,
164 .gpio1 = 0x309f,
165 },{
166 .type = CX88_VMUX_COMPOSITE1,
167 .vmux = 1,
168 .gpio1 = 0x305f,
169 },{
170 .type = CX88_VMUX_SVIDEO,
171 .vmux = 2,
172 .gpio1 = 0x305f,
173 }},
174 .radio = {
175 .type = CX88_RADIO,
176 },
177 },
178 [CX88_BOARD_MSI_TVANYWHERE_MASTER] = {
179 // added gpio values thanks to Michal
180 // values for PAL from DScaler
181 .name = "MSI TV-@nywhere Master",
182 .tuner_type = 33,
183 .tda9887_conf = TDA9887_PRESENT,
184 .input = {{
185 .type = CX88_VMUX_TELEVISION,
186 .vmux = 0,
187 .gpio0 = 0x000040bf,
188 .gpio1 = 0x000080c0,
189 .gpio2 = 0x0000ff40,
190 },{
191 .type = CX88_VMUX_COMPOSITE1,
192 .vmux = 1,
193 .gpio0 = 0x000040bf,
194 .gpio1 = 0x000080c0,
195 .gpio2 = 0x0000ff40,
196 },{
197 .type = CX88_VMUX_SVIDEO,
198 .vmux = 2,
199 .gpio0 = 0x000040bf,
200 .gpio1 = 0x000080c0,
201 .gpio2 = 0x0000ff40,
202 }},
203 .radio = {
204 .type = CX88_RADIO,
205 },
206 },
207 [CX88_BOARD_WINFAST_DV2000] = {
208 .name = "Leadtek Winfast DV2000",
209 .tuner_type = 38,
210 .tda9887_conf = TDA9887_PRESENT,
211 .input = {{
212 .type = CX88_VMUX_TELEVISION,
213 .vmux = 0,
214 .gpio0 = 0x0035e700,
215 .gpio1 = 0x00003004,
216 .gpio2 = 0x0035e700,
217 .gpio3 = 0x02000000,
218 },{
219
220 .type = CX88_VMUX_COMPOSITE1,
221 .vmux = 1,
222 .gpio0 = 0x0035c700,
223 .gpio1 = 0x00003004,
224 .gpio2 = 0x0035c700,
225 .gpio3 = 0x02000000,
226 },{
227 .type = CX88_VMUX_SVIDEO,
228 .vmux = 2,
229 .gpio0 = 0x0035c700,
230 .gpio1 = 0x0035c700,
231 .gpio2 = 0x02000000,
232 .gpio3 = 0x02000000,
233 }},
234 .radio = {
235 .type = CX88_RADIO,
236 .gpio0 = 0x0035d700,
237 .gpio1 = 0x00007004,
238 .gpio2 = 0x0035d700,
239 .gpio3 = 0x02000000,
240 },
241 },
242 [CX88_BOARD_LEADTEK_PVR2000] = {
243 // gpio values for PAL version from regspy by DScaler
244 .name = "Leadtek PVR 2000",
245 .tuner_type = 38,
246 .tda9887_conf = TDA9887_PRESENT,
247 .input = {{
248 .type = CX88_VMUX_TELEVISION,
249 .vmux = 0,
250 .gpio0 = 0x0000bde6,
251 },{
252 .type = CX88_VMUX_COMPOSITE1,
253 .vmux = 1,
254 .gpio0 = 0x0000bde6,
255 },{
256 .type = CX88_VMUX_SVIDEO,
257 .vmux = 2,
258 .gpio0 = 0x0000bde6,
259 }},
260 .radio = {
261 .type = CX88_RADIO,
262 .gpio0 = 0x0000bd62,
263 },
264 .blackbird = 1,
265 },
266 [CX88_BOARD_IODATA_GVVCP3PCI] = {
267 .name = "IODATA GV-VCP3/PCI",
268 .tuner_type = TUNER_ABSENT,
269 .input = {{
270 .type = CX88_VMUX_COMPOSITE1,
271 .vmux = 0,
272 },{
273 .type = CX88_VMUX_COMPOSITE2,
274 .vmux = 1,
275 },{
276 .type = CX88_VMUX_SVIDEO,
277 .vmux = 2,
278 }},
279 },
280 [CX88_BOARD_PROLINK_PLAYTVPVR] = {
281 .name = "Prolink PlayTV PVR",
282 .tuner_type = 43,
283 .tda9887_conf = TDA9887_PRESENT,
284 .input = {{
285 .type = CX88_VMUX_TELEVISION,
286 .vmux = 0,
287 .gpio0 = 0xff00,
288 },{
289 .type = CX88_VMUX_COMPOSITE1,
290 .vmux = 1,
291 .gpio0 = 0xff03,
292 },{
293 .type = CX88_VMUX_SVIDEO,
294 .vmux = 2,
295 .gpio0 = 0xff03,
296 }},
297 .radio = {
298 .type = CX88_RADIO,
299 .gpio0 = 0xff00,
300 },
301 },
302 [CX88_BOARD_ASUS_PVR_416] = {
303 .name = "ASUS PVR-416",
304 .tuner_type = 43,
305 .tda9887_conf = TDA9887_PRESENT,
306 .input = {{
307 .type = CX88_VMUX_TELEVISION,
308 .vmux = 0,
309 .gpio0 = 0x0000fde6,
310 },{
311 .type = CX88_VMUX_SVIDEO,
312 .vmux = 2,
313 .gpio0 = 0x0000fde6, // 0x0000fda6 L,R RCA audio in?
314 }},
315 .radio = {
316 .type = CX88_RADIO,
317 .gpio0 = 0x0000fde2,
318 },
319 .blackbird = 1,
320 },
321 [CX88_BOARD_MSI_TVANYWHERE] = {
322 .name = "MSI TV-@nywhere",
323 .tuner_type = 33,
324 .tda9887_conf = TDA9887_PRESENT,
325 .input = {{
326 .type = CX88_VMUX_TELEVISION,
327 .vmux = 0,
328 .gpio0 = 0x00000fbf,
329 .gpio2 = 0x0000fc08,
330 },{
331 .type = CX88_VMUX_COMPOSITE1,
332 .vmux = 1,
333 .gpio0 = 0x00000fbf,
334 .gpio2 = 0x0000fc68,
335 },{
336 .type = CX88_VMUX_SVIDEO,
337 .vmux = 2,
338 .gpio0 = 0x00000fbf,
339 .gpio2 = 0x0000fc68,
340 }},
341 },
342 [CX88_BOARD_KWORLD_DVB_T] = {
343 .name = "KWorld/VStream XPert DVB-T",
344 .tuner_type = TUNER_ABSENT,
345 .input = {{
346 .type = CX88_VMUX_COMPOSITE1,
347 .vmux = 1,
348 .gpio0 = 0x0700,
349 .gpio2 = 0x0101,
350 },{
351 .type = CX88_VMUX_SVIDEO,
352 .vmux = 2,
353 .gpio0 = 0x0700,
354 .gpio2 = 0x0101,
355 }},
356 .dvb = 1,
357 },
358 [CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1] = {
359 .name = "DVICO FusionHDTV DVB-T1",
360 .tuner_type = TUNER_ABSENT, /* No analog tuner */
361 .input = {{
362 .type = CX88_VMUX_COMPOSITE1,
363 .vmux = 1,
364 .gpio0 = 0x000027df,
365 },{
366 .type = CX88_VMUX_SVIDEO,
367 .vmux = 2,
368 .gpio0 = 0x000027df,
369 }},
370 .dvb = 1,
371 },
372 [CX88_BOARD_KWORLD_LTV883] = {
373 .name = "KWorld LTV883RF",
374 .tuner_type = 48,
375 .input = {{
376 .type = CX88_VMUX_TELEVISION,
377 .vmux = 0,
378 .gpio0 = 0x07f8,
379 },{
380 .type = CX88_VMUX_DEBUG,
381 .vmux = 0,
382 .gpio0 = 0x07f9, // mono from tuner chip
383 },{
384 .type = CX88_VMUX_COMPOSITE1,
385 .vmux = 1,
386 .gpio0 = 0x000007fa,
387 },{
388 .type = CX88_VMUX_SVIDEO,
389 .vmux = 2,
390 .gpio0 = 0x000007fa,
391 }},
392 .radio = {
393 .type = CX88_RADIO,
394 .gpio0 = 0x000007f8,
395 },
396 },
397 [CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD] = {
398 .name = "DViCO - FusionHDTV 3 Gold",
399 .tuner_type = TUNER_MICROTUNE_4042FI5,
400 /*
401 GPIO[0] resets DT3302 DTV receiver
402 0 - reset asserted
403 1 - normal operation
404 GPIO[1] mutes analog audio output connector
405 0 - enable selected source
406 1 - mute
407 GPIO[2] selects source for analog audio output connector
408 0 - analog audio input connector on tab
409 1 - analog DAC output from CX23881 chip
410 GPIO[3] selects RF input connector on tuner module
411 0 - RF connector labeled CABLE
412 1 - RF connector labeled ANT
413 */
414 .input = {{
415 .type = CX88_VMUX_TELEVISION,
416 .vmux = 0,
417 .gpio0 = 0x0f0d,
418 },{
419 .type = CX88_VMUX_CABLE,
420 .vmux = 0,
421 .gpio0 = 0x0f05,
422 },{
423 .type = CX88_VMUX_COMPOSITE1,
424 .vmux = 1,
425 .gpio0 = 0x0f00,
426 },{
427 .type = CX88_VMUX_SVIDEO,
428 .vmux = 2,
429 .gpio0 = 0x0f00,
430 }},
431#if 0
432 .ts = {
433 .type = CX88_TS,
434 .gpio0 = 0x00000f01, /* Hooked to tuner reset bit */
435 }
436#endif
437 },
438 [CX88_BOARD_HAUPPAUGE_DVB_T1] = {
439 .name = "Hauppauge Nova-T DVB-T",
440 .tuner_type = TUNER_ABSENT,
441 .input = {{
442 .type = CX88_VMUX_DVB,
443 .vmux = 0,
444 }},
445 .dvb = 1,
446 },
447 [CX88_BOARD_CONEXANT_DVB_T1] = {
448 .name = "Conexant DVB-T reference design",
449 .tuner_type = TUNER_ABSENT,
450 .input = {{
451 .type = CX88_VMUX_DVB,
452 .vmux = 0,
453 }},
454 .dvb = 1,
455 },
456 [CX88_BOARD_PROVIDEO_PV259] = {
457 .name = "Provideo PV259",
458 .tuner_type = TUNER_PHILIPS_FQ1216ME,
459 .input = {{
460 .type = CX88_VMUX_TELEVISION,
461 .vmux = 0,
462 }},
463 .blackbird = 1,
464 },
465 [CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS] = {
466 .name = "DVICO FusionHDTV DVB-T Plus",
467 .tuner_type = TUNER_ABSENT, /* No analog tuner */
468 .input = {{
469 .type = CX88_VMUX_COMPOSITE1,
470 .vmux = 1,
471 .gpio0 = 0x000027df,
472 },{
473 .type = CX88_VMUX_SVIDEO,
474 .vmux = 2,
475 .gpio0 = 0x000027df,
476 }},
477 .dvb = 1,
478 },
479 [CX88_BOARD_DNTV_LIVE_DVB_T] = {
480 .name = "digitalnow DNTV Live! DVB-T",
481 .tuner_type = TUNER_ABSENT,
482 .input = {{
483 .type = CX88_VMUX_COMPOSITE1,
484 .vmux = 1,
485 .gpio0 = 0x00000700,
486 .gpio2 = 0x00000101,
487 },{
488 .type = CX88_VMUX_SVIDEO,
489 .vmux = 2,
490 .gpio0 = 0x00000700,
491 .gpio2 = 0x00000101,
492 }},
493 .dvb = 1,
494 },
495 [CX88_BOARD_PCHDTV_HD3000] = {
496 .name = "pcHDTV HD3000 HDTV",
497 .tuner_type = TUNER_THOMSON_DTT7610,
498 .input = {{
499 .type = CX88_VMUX_TELEVISION,
500 .vmux = 0,
501 .gpio0 = 0x00008484,
502 .gpio1 = 0x00000000,
503 .gpio2 = 0x00000000,
504 .gpio3 = 0x00000000,
505 },{
506 .type = CX88_VMUX_COMPOSITE1,
507 .vmux = 1,
508 .gpio0 = 0x00008400,
509 .gpio1 = 0x00000000,
510 .gpio2 = 0x00000000,
511 .gpio3 = 0x00000000,
512 },{
513 .type = CX88_VMUX_SVIDEO,
514 .vmux = 2,
515 .gpio0 = 0x00008400,
516 .gpio1 = 0x00000000,
517 .gpio2 = 0x00000000,
518 .gpio3 = 0x00000000,
519 }},
520 .radio = {
521 .type = CX88_RADIO,
522 .vmux = 2,
523 .gpio0 = 0x00008400,
524 .gpio1 = 0x00000000,
525 .gpio2 = 0x00000000,
526 .gpio3 = 0x00000000,
527 },
528 .dvb = 1,
529 },
530 [CX88_BOARD_HAUPPAUGE_ROSLYN] = {
531 // entry added by Kaustubh D. Bhalerao <bhalerao.1@osu.edu>
532 // GPIO values obtained from regspy, courtesy Sean Covel
533 .name = "Hauppauge WinTV 28xxx (Roslyn) models",
534 .tuner_type = UNSET,
535 .input = {{
536 .type = CX88_VMUX_TELEVISION,
537 .vmux = 0,
538 .gpio0 = 0xed12, // internal decoder
539 .gpio2 = 0x00ff,
540 },{
541 .type = CX88_VMUX_DEBUG,
542 .vmux = 0,
543 .gpio0 = 0xff01, // mono from tuner chip
544 },{
545 .type = CX88_VMUX_COMPOSITE1,
546 .vmux = 1,
547 .gpio0 = 0xff02,
548 },{
549 .type = CX88_VMUX_SVIDEO,
550 .vmux = 2,
551 .gpio0 = 0xed92,
552 .gpio2 = 0x00ff,
553 }},
554 .radio = {
555 .type = CX88_RADIO,
556 .gpio0 = 0xed96,
557 .gpio2 = 0x00ff,
558 },
559 .blackbird = 1,
560 },
561 [CX88_BOARD_DIGITALLOGIC_MEC] = {
562 /* params copied over from Leadtek PVR 2000 */
563 .name = "Digital-Logic MICROSPACE Entertainment Center (MEC)",
564 /* not sure yet about the tuner type */
565 .tuner_type = 38,
566 .tda9887_conf = TDA9887_PRESENT,
567 .input = {{
568 .type = CX88_VMUX_TELEVISION,
569 .vmux = 0,
570 .gpio0 = 0x0000bde6,
571 },{
572 .type = CX88_VMUX_COMPOSITE1,
573 .vmux = 1,
574 .gpio0 = 0x0000bde6,
575 },{
576 .type = CX88_VMUX_SVIDEO,
577 .vmux = 2,
578 .gpio0 = 0x0000bde6,
579 }},
580 .radio = {
581 .type = CX88_RADIO,
582 .gpio0 = 0x0000bd62,
583 },
584 .blackbird = 1,
585 },
586 [CX88_BOARD_IODATA_GVBCTV7E] = {
587 .name = "IODATA GV/BCTV7E",
588 .tuner_type = TUNER_PHILIPS_FQ1286,
589 .tda9887_conf = TDA9887_PRESENT,
590 .input = {{
591 .type = CX88_VMUX_TELEVISION,
592 .vmux = 1,
593 .gpio1 = 0x0000e03f,
594 },{
595 .type = CX88_VMUX_COMPOSITE1,
596 .vmux = 2,
597 .gpio1 = 0x0000e07f,
598 },{
599 .type = CX88_VMUX_SVIDEO,
600 .vmux = 3,
601 .gpio1 = 0x0000e07f,
602 }}
603 },
604};
605const unsigned int cx88_bcount = ARRAY_SIZE(cx88_boards);
606
607/* ------------------------------------------------------------------ */
608/* PCI subsystem IDs */
609
610struct cx88_subid cx88_subids[] = {
611 {
612 .subvendor = 0x0070,
613 .subdevice = 0x3400,
614 .card = CX88_BOARD_HAUPPAUGE,
615 },{
616 .subvendor = 0x0070,
617 .subdevice = 0x3401,
618 .card = CX88_BOARD_HAUPPAUGE,
619 },{
620 .subvendor = 0x14c7,
621 .subdevice = 0x0106,
622 .card = CX88_BOARD_GDI,
623 },{
624 .subvendor = 0x14c7,
625 .subdevice = 0x0107, /* with mpeg encoder */
626 .card = CX88_BOARD_GDI,
627 },{
628 .subvendor = PCI_VENDOR_ID_ATI,
629 .subdevice = 0x00f8,
630 .card = CX88_BOARD_ATI_WONDER_PRO,
631 },{
632 .subvendor = 0x107d,
633 .subdevice = 0x6611,
634 .card = CX88_BOARD_WINFAST2000XP_EXPERT,
635 },{
636 .subvendor = 0x107d,
637 .subdevice = 0x6613, /* NTSC */
638 .card = CX88_BOARD_WINFAST2000XP_EXPERT,
639 },{
640 .subvendor = 0x107d,
641 .subdevice = 0x6620,
642 .card = CX88_BOARD_WINFAST_DV2000,
643 },{
644 .subvendor = 0x107d,
645 .subdevice = 0x663b,
646 .card = CX88_BOARD_LEADTEK_PVR2000,
647 },{
648 .subvendor = 0x107d,
649 .subdevice = 0x663C,
650 .card = CX88_BOARD_LEADTEK_PVR2000,
651 },{
652 .subvendor = 0x1461,
653 .subdevice = 0x000b,
654 .card = CX88_BOARD_AVERTV_303,
655 },{
656 .subvendor = 0x1462,
657 .subdevice = 0x8606,
658 .card = CX88_BOARD_MSI_TVANYWHERE_MASTER,
659 },{
660 .subvendor = 0x10fc,
661 .subdevice = 0xd003,
662 .card = CX88_BOARD_IODATA_GVVCP3PCI,
663 },{
664 .subvendor = 0x1043,
665 .subdevice = 0x4823, /* with mpeg encoder */
666 .card = CX88_BOARD_ASUS_PVR_416,
667 },{
668 .subvendor = 0x17de,
669 .subdevice = 0x08a6,
670 .card = CX88_BOARD_KWORLD_DVB_T,
671 },{
672 .subvendor = 0x18ac,
673 .subdevice = 0xd810,
674 .card = CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD,
675 },{
676 .subvendor = 0x18AC,
677 .subdevice = 0xDB00,
678 .card = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1,
679 },{
680 .subvendor = 0x0070,
681 .subdevice = 0x9002,
682 .card = CX88_BOARD_HAUPPAUGE_DVB_T1,
683 },{
684 .subvendor = 0x14f1,
685 .subdevice = 0x0187,
686 .card = CX88_BOARD_CONEXANT_DVB_T1,
687 },{
688 .subvendor = 0x1540,
689 .subdevice = 0x2580,
690 .card = CX88_BOARD_PROVIDEO_PV259,
691 },{
692 .subvendor = 0x18AC,
693 .subdevice = 0xDB10,
694 .card = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS,
695 },{
696 .subvendor = 0x1554,
697 .subdevice = 0x4811,
698 .card = CX88_BOARD_PIXELVIEW,
699 },{
700 .subvendor = 0x7063,
701 .subdevice = 0x3000, /* HD-3000 card */
702 .card = CX88_BOARD_PCHDTV_HD3000,
703 },{
704 .subvendor = 0x17DE,
705 .subdevice = 0xA8A6,
706 .card = CX88_BOARD_DNTV_LIVE_DVB_T,
707 },{
708 .subvendor = 0x0070,
709 .subdevice = 0x2801,
710 .card = CX88_BOARD_HAUPPAUGE_ROSLYN,
711 },{
712 .subvendor = 0x14F1,
713 .subdevice = 0x0342,
714 .card = CX88_BOARD_DIGITALLOGIC_MEC,
715 },{
716 .subvendor = 0x10fc,
717 .subdevice = 0xd035,
718 .card = CX88_BOARD_IODATA_GVBCTV7E,
719 }
720};
721const unsigned int cx88_idcount = ARRAY_SIZE(cx88_subids);
722
723/* ----------------------------------------------------------------------- */
724/* some leadtek specific stuff */
725
726static void __devinit leadtek_eeprom(struct cx88_core *core, u8 *eeprom_data)
727{
728 /* This is just for the "Winfast 2000XP Expert" board ATM; I don't have data on
729 * any others.
730 *
731 * Byte 0 is 1 on the NTSC board.
732 */
733
734 if (eeprom_data[4] != 0x7d ||
735 eeprom_data[5] != 0x10 ||
736 eeprom_data[7] != 0x66) {
737 printk(KERN_WARNING "%s: Leadtek eeprom invalid.\n",
738 core->name);
739 return;
740 }
741
742 core->has_radio = 1;
743 core->tuner_type = (eeprom_data[6] == 0x13) ? 43 : 38;
744
745 printk(KERN_INFO "%s: Leadtek Winfast 2000XP Expert config: "
746 "tuner=%d, eeprom[0]=0x%02x\n",
747 core->name, core->tuner_type, eeprom_data[0]);
748}
749
750
751/* ----------------------------------------------------------------------- */
752
753static void hauppauge_eeprom(struct cx88_core *core, u8 *eeprom_data)
754{
755 struct tveeprom tv;
756
757 tveeprom_hauppauge_analog(&tv, eeprom_data);
758 core->tuner_type = tv.tuner_type;
759 core->has_radio = tv.has_radio;
760}
761
762static int hauppauge_eeprom_dvb(struct cx88_core *core, u8 *ee)
763{
764 int model;
765 int tuner;
766
767 /* Make sure we support the board model */
768 model = ee[0x1f] << 24 | ee[0x1e] << 16 | ee[0x1d] << 8 | ee[0x1c];
769 switch(model) {
770 case 90002:
771 case 90500:
772 case 90501:
773 /* known */
774 break;
775 default:
776 printk("%s: warning: unknown hauppauge model #%d\n",
777 core->name, model);
778 break;
779 }
780
781 /* Make sure we support the tuner */
782 tuner = ee[0x2d];
783 switch(tuner) {
784 case 0x4B: /* dtt 7595 */
785 case 0x4C: /* dtt 7592 */
786 break;
787 default:
788 printk("%s: error: unknown hauppauge tuner 0x%02x\n",
789 core->name, tuner);
790 return -ENODEV;
791 }
792 printk(KERN_INFO "%s: hauppauge eeprom: model=%d, tuner=%d\n",
793 core->name, model, tuner);
794 return 0;
795}
796
797/* ----------------------------------------------------------------------- */
798/* some GDI (was: Modular Technology) specific stuff */
799
800static struct {
801 int id;
802 int fm;
803 char *name;
804} gdi_tuner[] = {
805 [ 0x01 ] = { .id = TUNER_ABSENT,
806 .name = "NTSC_M" },
807 [ 0x02 ] = { .id = TUNER_ABSENT,
808 .name = "PAL_B" },
809 [ 0x03 ] = { .id = TUNER_ABSENT,
810 .name = "PAL_I" },
811 [ 0x04 ] = { .id = TUNER_ABSENT,
812 .name = "PAL_D" },
813 [ 0x05 ] = { .id = TUNER_ABSENT,
814 .name = "SECAM" },
815
816 [ 0x10 ] = { .id = TUNER_ABSENT,
817 .fm = 1,
818 .name = "TEMIC_4049" },
819 [ 0x11 ] = { .id = TUNER_TEMIC_4136FY5,
820 .name = "TEMIC_4136" },
821 [ 0x12 ] = { .id = TUNER_ABSENT,
822 .name = "TEMIC_4146" },
823
824 [ 0x20 ] = { .id = TUNER_PHILIPS_FQ1216ME,
825 .fm = 1,
826 .name = "PHILIPS_FQ1216_MK3" },
827 [ 0x21 ] = { .id = TUNER_ABSENT, .fm = 1,
828 .name = "PHILIPS_FQ1236_MK3" },
829 [ 0x22 ] = { .id = TUNER_ABSENT,
830 .name = "PHILIPS_FI1236_MK3" },
831 [ 0x23 ] = { .id = TUNER_ABSENT,
832 .name = "PHILIPS_FI1216_MK3" },
833};
834
835static void gdi_eeprom(struct cx88_core *core, u8 *eeprom_data)
836{
837 char *name = (eeprom_data[0x0d] < ARRAY_SIZE(gdi_tuner))
838 ? gdi_tuner[eeprom_data[0x0d]].name : NULL;
839
840 printk(KERN_INFO "%s: GDI: tuner=%s\n", core->name,
841 name ? name : "unknown");
842 if (NULL == name)
843 return;
844 core->tuner_type = gdi_tuner[eeprom_data[0x0d]].id;
845 core->has_radio = gdi_tuner[eeprom_data[0x0d]].fm;
846}
847
848/* ----------------------------------------------------------------------- */
849
850void cx88_card_list(struct cx88_core *core, struct pci_dev *pci)
851{
852 int i;
853
854 if (0 == pci->subsystem_vendor &&
855 0 == pci->subsystem_device) {
856 printk("%s: Your board has no valid PCI Subsystem ID and thus can't\n"
857 "%s: be autodetected. Please pass card=<n> insmod option to\n"
858 "%s: workaround that. Redirect complaints to the vendor of\n"
859 "%s: the TV card. Best regards,\n"
860 "%s: -- tux\n",
861 core->name,core->name,core->name,core->name,core->name);
862 } else {
863 printk("%s: Your board isn't known (yet) to the driver. You can\n"
864 "%s: try to pick one of the existing card configs via\n"
865 "%s: card=<n> insmod option. Updating to the latest\n"
866 "%s: version might help as well.\n",
867 core->name,core->name,core->name,core->name);
868 }
869 printk("%s: Here is a list of valid choices for the card=<n> insmod option:\n",
870 core->name);
871 for (i = 0; i < cx88_bcount; i++)
872 printk("%s: card=%d -> %s\n",
873 core->name, i, cx88_boards[i].name);
874}
875
876void cx88_card_setup(struct cx88_core *core)
877{
878 static u8 eeprom[128];
879
880 if (0 == core->i2c_rc) {
881 core->i2c_client.addr = 0xa0 >> 1;
882 tveeprom_read(&core->i2c_client,eeprom,sizeof(eeprom));
883 }
884
885 switch (core->board) {
886 case CX88_BOARD_HAUPPAUGE:
887 case CX88_BOARD_HAUPPAUGE_ROSLYN:
888 if (0 == core->i2c_rc)
889 hauppauge_eeprom(core,eeprom+8);
890 break;
891 case CX88_BOARD_GDI:
892 if (0 == core->i2c_rc)
893 gdi_eeprom(core,eeprom);
894 break;
895 case CX88_BOARD_WINFAST2000XP_EXPERT:
896 if (0 == core->i2c_rc)
897 leadtek_eeprom(core,eeprom);
898 break;
899 case CX88_BOARD_HAUPPAUGE_DVB_T1:
900 if (0 == core->i2c_rc)
901 hauppauge_eeprom_dvb(core,eeprom);
902 break;
903 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1:
904 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS:
905 /* GPIO0:0 is hooked to mt352 reset pin */
906 cx_set(MO_GP0_IO, 0x00000101);
907 cx_clear(MO_GP0_IO, 0x00000001);
908 msleep(1);
909 cx_set(MO_GP0_IO, 0x00000101);
910 break;
911 case CX88_BOARD_KWORLD_DVB_T:
912 case CX88_BOARD_DNTV_LIVE_DVB_T:
913 cx_set(MO_GP0_IO, 0x00000707);
914 cx_set(MO_GP2_IO, 0x00000101);
915 cx_clear(MO_GP2_IO, 0x00000001);
916 msleep(1);
917 cx_clear(MO_GP0_IO, 0x00000007);
918 cx_set(MO_GP2_IO, 0x00000101);
919 break;
920 }
921 if (cx88_boards[core->board].radio.type == CX88_RADIO)
922 core->has_radio = 1;
923}
924
925/* ------------------------------------------------------------------ */
926
927EXPORT_SYMBOL(cx88_boards);
928EXPORT_SYMBOL(cx88_bcount);
929EXPORT_SYMBOL(cx88_subids);
930EXPORT_SYMBOL(cx88_idcount);
931EXPORT_SYMBOL(cx88_card_list);
932EXPORT_SYMBOL(cx88_card_setup);
933
934/*
935 * Local variables:
936 * c-basic-offset: 8
937 * End:
938 */
diff --git a/drivers/media/video/cx88/cx88-core.c b/drivers/media/video/cx88/cx88-core.c
new file mode 100644
index 00000000000..26a6138015c
--- /dev/null
+++ b/drivers/media/video/cx88/cx88-core.c
@@ -0,0 +1,1239 @@
1/*
2 * $Id: cx88-core.c,v 1.24 2005/01/19 12:01:55 kraxel Exp $
3 *
4 * device driver for Conexant 2388x based TV cards
5 * driver core
6 *
7 * (c) 2003 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
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#include <linux/init.h>
25#include <linux/list.h>
26#include <linux/module.h>
27#include <linux/moduleparam.h>
28#include <linux/kernel.h>
29#include <linux/slab.h>
30#include <linux/kmod.h>
31#include <linux/sound.h>
32#include <linux/interrupt.h>
33#include <linux/pci.h>
34#include <linux/delay.h>
35#include <linux/videodev.h>
36
37#include "cx88.h"
38
39MODULE_DESCRIPTION("v4l2 driver module for cx2388x based TV cards");
40MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
41MODULE_LICENSE("GPL");
42
43/* ------------------------------------------------------------------ */
44
45static unsigned int core_debug = 0;
46module_param(core_debug,int,0644);
47MODULE_PARM_DESC(core_debug,"enable debug messages [core]");
48
49static unsigned int latency = UNSET;
50module_param(latency,int,0444);
51MODULE_PARM_DESC(latency,"pci latency timer");
52
53static unsigned int tuner[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET };
54static unsigned int card[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET };
55
56module_param_array(tuner, int, NULL, 0444);
57module_param_array(card, int, NULL, 0444);
58
59MODULE_PARM_DESC(tuner,"tuner type");
60MODULE_PARM_DESC(card,"card type");
61
62static unsigned int nicam = 0;
63module_param(nicam,int,0644);
64MODULE_PARM_DESC(nicam,"tv audio is nicam");
65
66static unsigned int nocomb = 0;
67module_param(nocomb,int,0644);
68MODULE_PARM_DESC(nocomb,"disable comb filter");
69
70#define dprintk(level,fmt, arg...) if (core_debug >= level) \
71 printk(KERN_DEBUG "%s: " fmt, core->name , ## arg)
72
73static unsigned int cx88_devcount;
74static LIST_HEAD(cx88_devlist);
75static DECLARE_MUTEX(devlist);
76
77/* ------------------------------------------------------------------ */
78/* debug help functions */
79
80static const char *v4l1_ioctls[] = {
81 "0", "CGAP", "GCHAN", "SCHAN", "GTUNER", "STUNER", "GPICT", "SPICT",
82 "CCAPTURE", "GWIN", "SWIN", "GFBUF", "SFBUF", "KEY", "GFREQ",
83 "SFREQ", "GAUDIO", "SAUDIO", "SYNC", "MCAPTURE", "GMBUF", "GUNIT",
84 "GCAPTURE", "SCAPTURE", "SPLAYMODE", "SWRITEMODE", "GPLAYINFO",
85 "SMICROCODE", "GVBIFMT", "SVBIFMT" };
86#define V4L1_IOCTLS ARRAY_SIZE(v4l1_ioctls)
87
88static const char *v4l2_ioctls[] = {
89 "QUERYCAP", "1", "ENUM_PIXFMT", "ENUM_FBUFFMT", "G_FMT", "S_FMT",
90 "G_COMP", "S_COMP", "REQBUFS", "QUERYBUF", "G_FBUF", "S_FBUF",
91 "G_WIN", "S_WIN", "PREVIEW", "QBUF", "16", "DQBUF", "STREAMON",
92 "STREAMOFF", "G_PERF", "G_PARM", "S_PARM", "G_STD", "S_STD",
93 "ENUMSTD", "ENUMINPUT", "G_CTRL", "S_CTRL", "G_TUNER", "S_TUNER",
94 "G_FREQ", "S_FREQ", "G_AUDIO", "S_AUDIO", "35", "QUERYCTRL",
95 "QUERYMENU", "G_INPUT", "S_INPUT", "ENUMCVT", "41", "42", "43",
96 "44", "45", "G_OUTPUT", "S_OUTPUT", "ENUMOUTPUT", "G_AUDOUT",
97 "S_AUDOUT", "ENUMFX", "G_EFFECT", "S_EFFECT", "G_MODULATOR",
98 "S_MODULATOR"
99};
100#define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
101
102void cx88_print_ioctl(char *name, unsigned int cmd)
103{
104 char *dir;
105
106 switch (_IOC_DIR(cmd)) {
107 case _IOC_NONE: dir = "--"; break;
108 case _IOC_READ: dir = "r-"; break;
109 case _IOC_WRITE: dir = "-w"; break;
110 case _IOC_READ | _IOC_WRITE: dir = "rw"; break;
111 default: dir = "??"; break;
112 }
113 switch (_IOC_TYPE(cmd)) {
114 case 'v':
115 printk(KERN_DEBUG "%s: ioctl 0x%08x (v4l1, %s, VIDIOC%s)\n",
116 name, cmd, dir, (_IOC_NR(cmd) < V4L1_IOCTLS) ?
117 v4l1_ioctls[_IOC_NR(cmd)] : "???");
118 break;
119 case 'V':
120 printk(KERN_DEBUG "%s: ioctl 0x%08x (v4l2, %s, VIDIOC_%s)\n",
121 name, cmd, dir, (_IOC_NR(cmd) < V4L2_IOCTLS) ?
122 v4l2_ioctls[_IOC_NR(cmd)] : "???");
123 break;
124 default:
125 printk(KERN_DEBUG "%s: ioctl 0x%08x (???, %s, #%d)\n",
126 name, cmd, dir, _IOC_NR(cmd));
127 }
128}
129
130/* ------------------------------------------------------------------ */
131#define NO_SYNC_LINE (-1U)
132
133static u32* cx88_risc_field(u32 *rp, struct scatterlist *sglist,
134 unsigned int offset, u32 sync_line,
135 unsigned int bpl, unsigned int padding,
136 unsigned int lines)
137{
138 struct scatterlist *sg;
139 unsigned int line,todo;
140
141 /* sync instruction */
142 if (sync_line != NO_SYNC_LINE)
143 *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line);
144
145 /* scan lines */
146 sg = sglist;
147 for (line = 0; line < lines; line++) {
148 while (offset && offset >= sg_dma_len(sg)) {
149 offset -= sg_dma_len(sg);
150 sg++;
151 }
152 if (bpl <= sg_dma_len(sg)-offset) {
153 /* fits into current chunk */
154 *(rp++)=cpu_to_le32(RISC_WRITE|RISC_SOL|RISC_EOL|bpl);
155 *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
156 offset+=bpl;
157 } else {
158 /* scanline needs to be splitted */
159 todo = bpl;
160 *(rp++)=cpu_to_le32(RISC_WRITE|RISC_SOL|
161 (sg_dma_len(sg)-offset));
162 *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
163 todo -= (sg_dma_len(sg)-offset);
164 offset = 0;
165 sg++;
166 while (todo > sg_dma_len(sg)) {
167 *(rp++)=cpu_to_le32(RISC_WRITE|
168 sg_dma_len(sg));
169 *(rp++)=cpu_to_le32(sg_dma_address(sg));
170 todo -= sg_dma_len(sg);
171 sg++;
172 }
173 *(rp++)=cpu_to_le32(RISC_WRITE|RISC_EOL|todo);
174 *(rp++)=cpu_to_le32(sg_dma_address(sg));
175 offset += todo;
176 }
177 offset += padding;
178 }
179
180 return rp;
181}
182
183int cx88_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc,
184 struct scatterlist *sglist,
185 unsigned int top_offset, unsigned int bottom_offset,
186 unsigned int bpl, unsigned int padding, unsigned int lines)
187{
188 u32 instructions,fields;
189 u32 *rp;
190 int rc;
191
192 fields = 0;
193 if (UNSET != top_offset)
194 fields++;
195 if (UNSET != bottom_offset)
196 fields++;
197
198 /* estimate risc mem: worst case is one write per page border +
199 one write per scan line + syncs + jump (all 2 dwords) */
200 instructions = (bpl * lines * fields) / PAGE_SIZE + lines * fields;
201 instructions += 3 + 4;
202 if ((rc = btcx_riscmem_alloc(pci,risc,instructions*8)) < 0)
203 return rc;
204
205 /* write risc instructions */
206 rp = risc->cpu;
207 if (UNSET != top_offset)
208 rp = cx88_risc_field(rp, sglist, top_offset, 0,
209 bpl, padding, lines);
210 if (UNSET != bottom_offset)
211 rp = cx88_risc_field(rp, sglist, bottom_offset, 0x200,
212 bpl, padding, lines);
213
214 /* save pointer to jmp instruction address */
215 risc->jmp = rp;
216 BUG_ON((risc->jmp - risc->cpu + 2) / 4 > risc->size);
217 return 0;
218}
219
220int cx88_risc_databuffer(struct pci_dev *pci, struct btcx_riscmem *risc,
221 struct scatterlist *sglist, unsigned int bpl,
222 unsigned int lines)
223{
224 u32 instructions;
225 u32 *rp;
226 int rc;
227
228 /* estimate risc mem: worst case is one write per page border +
229 one write per scan line + syncs + jump (all 2 dwords) */
230 instructions = (bpl * lines) / PAGE_SIZE + lines;
231 instructions += 3 + 4;
232 if ((rc = btcx_riscmem_alloc(pci,risc,instructions*8)) < 0)
233 return rc;
234
235 /* write risc instructions */
236 rp = risc->cpu;
237 rp = cx88_risc_field(rp, sglist, 0, NO_SYNC_LINE, bpl, 0, lines);
238
239 /* save pointer to jmp instruction address */
240 risc->jmp = rp;
241 BUG_ON((risc->jmp - risc->cpu + 2) / 4 > risc->size);
242 return 0;
243}
244
245int cx88_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc,
246 u32 reg, u32 mask, u32 value)
247{
248 u32 *rp;
249 int rc;
250
251 if ((rc = btcx_riscmem_alloc(pci, risc, 4*16)) < 0)
252 return rc;
253
254 /* write risc instructions */
255 rp = risc->cpu;
256 *(rp++) = cpu_to_le32(RISC_WRITECR | RISC_IRQ2 | RISC_IMM);
257 *(rp++) = cpu_to_le32(reg);
258 *(rp++) = cpu_to_le32(value);
259 *(rp++) = cpu_to_le32(mask);
260 *(rp++) = cpu_to_le32(RISC_JUMP);
261 *(rp++) = cpu_to_le32(risc->dma);
262 return 0;
263}
264
265void
266cx88_free_buffer(struct pci_dev *pci, struct cx88_buffer *buf)
267{
268 if (in_interrupt())
269 BUG();
270 videobuf_waiton(&buf->vb,0,0);
271 videobuf_dma_pci_unmap(pci, &buf->vb.dma);
272 videobuf_dma_free(&buf->vb.dma);
273 btcx_riscmem_free(pci, &buf->risc);
274 buf->vb.state = STATE_NEEDS_INIT;
275}
276
277/* ------------------------------------------------------------------ */
278/* our SRAM memory layout */
279
280/* we are going to put all thr risc programs into host memory, so we
281 * can use the whole SDRAM for the DMA fifos. To simplify things, we
282 * use a static memory layout. That surely will waste memory in case
283 * we don't use all DMA channels at the same time (which will be the
284 * case most of the time). But that still gives us enougth FIFO space
285 * to be able to deal with insane long pci latencies ...
286 *
287 * FIFO space allocations:
288 * channel 21 (y video) - 10.0k
289 * channel 22 (u video) - 2.0k
290 * channel 23 (v video) - 2.0k
291 * channel 24 (vbi) - 4.0k
292 * channels 25+26 (audio) - 0.5k
293 * channel 28 (mpeg) - 4.0k
294 * TOTAL = 25.5k
295 *
296 * Every channel has 160 bytes control data (64 bytes instruction
297 * queue and 6 CDT entries), which is close to 2k total.
298 *
299 * Address layout:
300 * 0x0000 - 0x03ff CMDs / reserved
301 * 0x0400 - 0x0bff instruction queues + CDs
302 * 0x0c00 - FIFOs
303 */
304
305struct sram_channel cx88_sram_channels[] = {
306 [SRAM_CH21] = {
307 .name = "video y / packed",
308 .cmds_start = 0x180040,
309 .ctrl_start = 0x180400,
310 .cdt = 0x180400 + 64,
311 .fifo_start = 0x180c00,
312 .fifo_size = 0x002800,
313 .ptr1_reg = MO_DMA21_PTR1,
314 .ptr2_reg = MO_DMA21_PTR2,
315 .cnt1_reg = MO_DMA21_CNT1,
316 .cnt2_reg = MO_DMA21_CNT2,
317 },
318 [SRAM_CH22] = {
319 .name = "video u",
320 .cmds_start = 0x180080,
321 .ctrl_start = 0x1804a0,
322 .cdt = 0x1804a0 + 64,
323 .fifo_start = 0x183400,
324 .fifo_size = 0x000800,
325 .ptr1_reg = MO_DMA22_PTR1,
326 .ptr2_reg = MO_DMA22_PTR2,
327 .cnt1_reg = MO_DMA22_CNT1,
328 .cnt2_reg = MO_DMA22_CNT2,
329 },
330 [SRAM_CH23] = {
331 .name = "video v",
332 .cmds_start = 0x1800c0,
333 .ctrl_start = 0x180540,
334 .cdt = 0x180540 + 64,
335 .fifo_start = 0x183c00,
336 .fifo_size = 0x000800,
337 .ptr1_reg = MO_DMA23_PTR1,
338 .ptr2_reg = MO_DMA23_PTR2,
339 .cnt1_reg = MO_DMA23_CNT1,
340 .cnt2_reg = MO_DMA23_CNT2,
341 },
342 [SRAM_CH24] = {
343 .name = "vbi",
344 .cmds_start = 0x180100,
345 .ctrl_start = 0x1805e0,
346 .cdt = 0x1805e0 + 64,
347 .fifo_start = 0x184400,
348 .fifo_size = 0x001000,
349 .ptr1_reg = MO_DMA24_PTR1,
350 .ptr2_reg = MO_DMA24_PTR2,
351 .cnt1_reg = MO_DMA24_CNT1,
352 .cnt2_reg = MO_DMA24_CNT2,
353 },
354 [SRAM_CH25] = {
355 .name = "audio from",
356 .cmds_start = 0x180140,
357 .ctrl_start = 0x180680,
358 .cdt = 0x180680 + 64,
359 .fifo_start = 0x185400,
360 .fifo_size = 0x000200,
361 .ptr1_reg = MO_DMA25_PTR1,
362 .ptr2_reg = MO_DMA25_PTR2,
363 .cnt1_reg = MO_DMA25_CNT1,
364 .cnt2_reg = MO_DMA25_CNT2,
365 },
366 [SRAM_CH26] = {
367 .name = "audio to",
368 .cmds_start = 0x180180,
369 .ctrl_start = 0x180720,
370 .cdt = 0x180680 + 64, /* same as audio IN */
371 .fifo_start = 0x185400, /* same as audio IN */
372 .fifo_size = 0x000200, /* same as audio IN */
373 .ptr1_reg = MO_DMA26_PTR1,
374 .ptr2_reg = MO_DMA26_PTR2,
375 .cnt1_reg = MO_DMA26_CNT1,
376 .cnt2_reg = MO_DMA26_CNT2,
377 },
378 [SRAM_CH28] = {
379 .name = "mpeg",
380 .cmds_start = 0x180200,
381 .ctrl_start = 0x1807C0,
382 .cdt = 0x1807C0 + 64,
383 .fifo_start = 0x185600,
384 .fifo_size = 0x001000,
385 .ptr1_reg = MO_DMA28_PTR1,
386 .ptr2_reg = MO_DMA28_PTR2,
387 .cnt1_reg = MO_DMA28_CNT1,
388 .cnt2_reg = MO_DMA28_CNT2,
389 },
390};
391
392int cx88_sram_channel_setup(struct cx88_core *core,
393 struct sram_channel *ch,
394 unsigned int bpl, u32 risc)
395{
396 unsigned int i,lines;
397 u32 cdt;
398
399 bpl = (bpl + 7) & ~7; /* alignment */
400 cdt = ch->cdt;
401 lines = ch->fifo_size / bpl;
402 if (lines > 6)
403 lines = 6;
404 BUG_ON(lines < 2);
405
406 /* write CDT */
407 for (i = 0; i < lines; i++)
408 cx_write(cdt + 16*i, ch->fifo_start + bpl*i);
409
410 /* write CMDS */
411 cx_write(ch->cmds_start + 0, risc);
412 cx_write(ch->cmds_start + 4, cdt);
413 cx_write(ch->cmds_start + 8, (lines*16) >> 3);
414 cx_write(ch->cmds_start + 12, ch->ctrl_start);
415 cx_write(ch->cmds_start + 16, 64 >> 2);
416 for (i = 20; i < 64; i += 4)
417 cx_write(ch->cmds_start + i, 0);
418
419 /* fill registers */
420 cx_write(ch->ptr1_reg, ch->fifo_start);
421 cx_write(ch->ptr2_reg, cdt);
422 cx_write(ch->cnt1_reg, (bpl >> 3) -1);
423 cx_write(ch->cnt2_reg, (lines*16) >> 3);
424
425 dprintk(2,"sram setup %s: bpl=%d lines=%d\n", ch->name, bpl, lines);
426 return 0;
427}
428
429/* ------------------------------------------------------------------ */
430/* debug helper code */
431
432int cx88_risc_decode(u32 risc)
433{
434 static char *instr[16] = {
435 [ RISC_SYNC >> 28 ] = "sync",
436 [ RISC_WRITE >> 28 ] = "write",
437 [ RISC_WRITEC >> 28 ] = "writec",
438 [ RISC_READ >> 28 ] = "read",
439 [ RISC_READC >> 28 ] = "readc",
440 [ RISC_JUMP >> 28 ] = "jump",
441 [ RISC_SKIP >> 28 ] = "skip",
442 [ RISC_WRITERM >> 28 ] = "writerm",
443 [ RISC_WRITECM >> 28 ] = "writecm",
444 [ RISC_WRITECR >> 28 ] = "writecr",
445 };
446 static int incr[16] = {
447 [ RISC_WRITE >> 28 ] = 2,
448 [ RISC_JUMP >> 28 ] = 2,
449 [ RISC_WRITERM >> 28 ] = 3,
450 [ RISC_WRITECM >> 28 ] = 3,
451 [ RISC_WRITECR >> 28 ] = 4,
452 };
453 static char *bits[] = {
454 "12", "13", "14", "resync",
455 "cnt0", "cnt1", "18", "19",
456 "20", "21", "22", "23",
457 "irq1", "irq2", "eol", "sol",
458 };
459 int i;
460
461 printk("0x%08x [ %s", risc,
462 instr[risc >> 28] ? instr[risc >> 28] : "INVALID");
463 for (i = ARRAY_SIZE(bits)-1; i >= 0; i--)
464 if (risc & (1 << (i + 12)))
465 printk(" %s",bits[i]);
466 printk(" count=%d ]\n", risc & 0xfff);
467 return incr[risc >> 28] ? incr[risc >> 28] : 1;
468}
469
470#if 0 /* currently unused, but useful for debugging */
471void cx88_risc_disasm(struct cx88_core *core,
472 struct btcx_riscmem *risc)
473{
474 unsigned int i,j,n;
475
476 printk("%s: risc disasm: %p [dma=0x%08lx]\n",
477 core->name, risc->cpu, (unsigned long)risc->dma);
478 for (i = 0; i < (risc->size >> 2); i += n) {
479 printk("%s: %04d: ", core->name, i);
480 n = cx88_risc_decode(risc->cpu[i]);
481 for (j = 1; j < n; j++)
482 printk("%s: %04d: 0x%08x [ arg #%d ]\n",
483 core->name, i+j, risc->cpu[i+j], j);
484 if (risc->cpu[i] == RISC_JUMP)
485 break;
486 }
487}
488#endif
489
490void cx88_sram_channel_dump(struct cx88_core *core,
491 struct sram_channel *ch)
492{
493 static char *name[] = {
494 "initial risc",
495 "cdt base",
496 "cdt size",
497 "iq base",
498 "iq size",
499 "risc pc",
500 "iq wr ptr",
501 "iq rd ptr",
502 "cdt current",
503 "pci target",
504 "line / byte",
505 };
506 u32 risc;
507 unsigned int i,j,n;
508
509 printk("%s: %s - dma channel status dump\n",
510 core->name,ch->name);
511 for (i = 0; i < ARRAY_SIZE(name); i++)
512 printk("%s: cmds: %-12s: 0x%08x\n",
513 core->name,name[i],
514 cx_read(ch->cmds_start + 4*i));
515 for (i = 0; i < 4; i++) {
516 risc = cx_read(ch->cmds_start + 4 * (i+11));
517 printk("%s: risc%d: ", core->name, i);
518 cx88_risc_decode(risc);
519 }
520 for (i = 0; i < 16; i += n) {
521 risc = cx_read(ch->ctrl_start + 4 * i);
522 printk("%s: iq %x: ", core->name, i);
523 n = cx88_risc_decode(risc);
524 for (j = 1; j < n; j++) {
525 risc = cx_read(ch->ctrl_start + 4 * (i+j));
526 printk("%s: iq %x: 0x%08x [ arg #%d ]\n",
527 core->name, i+j, risc, j);
528 }
529 }
530
531 printk("%s: fifo: 0x%08x -> 0x%x\n",
532 core->name, ch->fifo_start, ch->fifo_start+ch->fifo_size);
533 printk("%s: ctrl: 0x%08x -> 0x%x\n",
534 core->name, ch->ctrl_start, ch->ctrl_start+6*16);
535 printk("%s: ptr1_reg: 0x%08x\n",
536 core->name,cx_read(ch->ptr1_reg));
537 printk("%s: ptr2_reg: 0x%08x\n",
538 core->name,cx_read(ch->ptr2_reg));
539 printk("%s: cnt1_reg: 0x%08x\n",
540 core->name,cx_read(ch->cnt1_reg));
541 printk("%s: cnt2_reg: 0x%08x\n",
542 core->name,cx_read(ch->cnt2_reg));
543}
544
545char *cx88_pci_irqs[32] = {
546 "vid", "aud", "ts", "vip", "hst", "5", "6", "tm1",
547 "src_dma", "dst_dma", "risc_rd_err", "risc_wr_err",
548 "brdg_err", "src_dma_err", "dst_dma_err", "ipb_dma_err",
549 "i2c", "i2c_rack", "ir_smp", "gpio0", "gpio1"
550};
551char *cx88_vid_irqs[32] = {
552 "y_risci1", "u_risci1", "v_risci1", "vbi_risc1",
553 "y_risci2", "u_risci2", "v_risci2", "vbi_risc2",
554 "y_oflow", "u_oflow", "v_oflow", "vbi_oflow",
555 "y_sync", "u_sync", "v_sync", "vbi_sync",
556 "opc_err", "par_err", "rip_err", "pci_abort",
557};
558char *cx88_mpeg_irqs[32] = {
559 "ts_risci1", NULL, NULL, NULL,
560 "ts_risci2", NULL, NULL, NULL,
561 "ts_oflow", NULL, NULL, NULL,
562 "ts_sync", NULL, NULL, NULL,
563 "opc_err", "par_err", "rip_err", "pci_abort",
564 "ts_err?",
565};
566
567void cx88_print_irqbits(char *name, char *tag, char **strings,
568 u32 bits, u32 mask)
569{
570 unsigned int i;
571
572 printk(KERN_DEBUG "%s: %s [0x%x]", name, tag, bits);
573 for (i = 0; i < 32; i++) {
574 if (!(bits & (1 << i)))
575 continue;
576 if (strings[i])
577 printk(" %s", strings[i]);
578 else
579 printk(" %d", i);
580 if (!(mask & (1 << i)))
581 continue;
582 printk("*");
583 }
584 printk("\n");
585}
586
587/* ------------------------------------------------------------------ */
588
589int cx88_core_irq(struct cx88_core *core, u32 status)
590{
591 int handled = 0;
592
593 if (status & (1<<18)) {
594 cx88_ir_irq(core);
595 handled++;
596 }
597 if (!handled)
598 cx88_print_irqbits(core->name, "irq pci",
599 cx88_pci_irqs, status,
600 core->pci_irqmask);
601 return handled;
602}
603
604void cx88_wakeup(struct cx88_core *core,
605 struct cx88_dmaqueue *q, u32 count)
606{
607 struct cx88_buffer *buf;
608 int bc;
609
610 for (bc = 0;; bc++) {
611 if (list_empty(&q->active))
612 break;
613 buf = list_entry(q->active.next,
614 struct cx88_buffer, vb.queue);
615#if 0
616 if (buf->count > count)
617 break;
618#else
619 /* count comes from the hw and is is 16bit wide --
620 * this trick handles wrap-arounds correctly for
621 * up to 32767 buffers in flight... */
622 if ((s16) (count - buf->count) < 0)
623 break;
624#endif
625 do_gettimeofday(&buf->vb.ts);
626 dprintk(2,"[%p/%d] wakeup reg=%d buf=%d\n",buf,buf->vb.i,
627 count, buf->count);
628 buf->vb.state = STATE_DONE;
629 list_del(&buf->vb.queue);
630 wake_up(&buf->vb.done);
631 }
632 if (list_empty(&q->active)) {
633 del_timer(&q->timeout);
634 } else {
635 mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
636 }
637 if (bc != 1)
638 printk("%s: %d buffers handled (should be 1)\n",__FUNCTION__,bc);
639}
640
641void cx88_shutdown(struct cx88_core *core)
642{
643 /* disable RISC controller + IRQs */
644 cx_write(MO_DEV_CNTRL2, 0);
645
646 /* stop dma transfers */
647 cx_write(MO_VID_DMACNTRL, 0x0);
648 cx_write(MO_AUD_DMACNTRL, 0x0);
649 cx_write(MO_TS_DMACNTRL, 0x0);
650 cx_write(MO_VIP_DMACNTRL, 0x0);
651 cx_write(MO_GPHST_DMACNTRL, 0x0);
652
653 /* stop interrupts */
654 cx_write(MO_PCI_INTMSK, 0x0);
655 cx_write(MO_VID_INTMSK, 0x0);
656 cx_write(MO_AUD_INTMSK, 0x0);
657 cx_write(MO_TS_INTMSK, 0x0);
658 cx_write(MO_VIP_INTMSK, 0x0);
659 cx_write(MO_GPHST_INTMSK, 0x0);
660
661 /* stop capturing */
662 cx_write(VID_CAPTURE_CONTROL, 0);
663}
664
665int cx88_reset(struct cx88_core *core)
666{
667 dprintk(1,"%s\n",__FUNCTION__);
668 cx88_shutdown(core);
669
670 /* clear irq status */
671 cx_write(MO_VID_INTSTAT, 0xFFFFFFFF); // Clear PIV int
672 cx_write(MO_PCI_INTSTAT, 0xFFFFFFFF); // Clear PCI int
673 cx_write(MO_INT1_STAT, 0xFFFFFFFF); // Clear RISC int
674
675 /* wait a bit */
676 msleep(100);
677
678 /* init sram */
679 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH21], 720*4, 0);
680 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH22], 128, 0);
681 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH23], 128, 0);
682 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH24], 128, 0);
683 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH25], 128, 0);
684 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH26], 128, 0);
685 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH28], 188*4, 0);
686
687 /* misc init ... */
688 cx_write(MO_INPUT_FORMAT, ((1 << 13) | // agc enable
689 (1 << 12) | // agc gain
690 (1 << 11) | // adaptibe agc
691 (0 << 10) | // chroma agc
692 (0 << 9) | // ckillen
693 (7)));
694
695 /* setup image format */
696 cx_andor(MO_COLOR_CTRL, 0x4000, 0x4000);
697
698 /* setup FIFO Threshholds */
699 cx_write(MO_PDMA_STHRSH, 0x0807);
700 cx_write(MO_PDMA_DTHRSH, 0x0807);
701
702 /* fixes flashing of image */
703 cx_write(MO_AGC_SYNC_TIP1, 0x0380000F);
704 cx_write(MO_AGC_BACK_VBI, 0x00E00555);
705
706 cx_write(MO_VID_INTSTAT, 0xFFFFFFFF); // Clear PIV int
707 cx_write(MO_PCI_INTSTAT, 0xFFFFFFFF); // Clear PCI int
708 cx_write(MO_INT1_STAT, 0xFFFFFFFF); // Clear RISC int
709
710 /* Reset on-board parts */
711 cx_write(MO_SRST_IO, 0);
712 msleep(10);
713 cx_write(MO_SRST_IO, 1);
714
715 return 0;
716}
717
718/* ------------------------------------------------------------------ */
719
720static unsigned int inline norm_swidth(struct cx88_tvnorm *norm)
721{
722 return (norm->id & V4L2_STD_625_50) ? 922 : 754;
723}
724
725static unsigned int inline norm_hdelay(struct cx88_tvnorm *norm)
726{
727 return (norm->id & V4L2_STD_625_50) ? 186 : 135;
728}
729
730static unsigned int inline norm_vdelay(struct cx88_tvnorm *norm)
731{
732 return (norm->id & V4L2_STD_625_50) ? 0x24 : 0x18;
733}
734
735static unsigned int inline norm_fsc8(struct cx88_tvnorm *norm)
736{
737 static const unsigned int ntsc = 28636360;
738 static const unsigned int pal = 35468950;
739
740 return (norm->id & V4L2_STD_625_50) ? pal : ntsc;
741}
742
743static unsigned int inline norm_notchfilter(struct cx88_tvnorm *norm)
744{
745 return (norm->id & V4L2_STD_625_50)
746 ? HLNotchFilter135PAL
747 : HLNotchFilter135NTSC;
748}
749
750static unsigned int inline norm_htotal(struct cx88_tvnorm *norm)
751{
752 return (norm->id & V4L2_STD_625_50) ? 1135 : 910;
753}
754
755static unsigned int inline norm_vbipack(struct cx88_tvnorm *norm)
756{
757 return (norm->id & V4L2_STD_625_50) ? 511 : 288;
758}
759
760int cx88_set_scale(struct cx88_core *core, unsigned int width, unsigned int height,
761 enum v4l2_field field)
762{
763 unsigned int swidth = norm_swidth(core->tvnorm);
764 unsigned int sheight = norm_maxh(core->tvnorm);
765 u32 value;
766
767 dprintk(1,"set_scale: %dx%d [%s%s,%s]\n", width, height,
768 V4L2_FIELD_HAS_TOP(field) ? "T" : "",
769 V4L2_FIELD_HAS_BOTTOM(field) ? "B" : "",
770 core->tvnorm->name);
771 if (!V4L2_FIELD_HAS_BOTH(field))
772 height *= 2;
773
774 // recalc H delay and scale registers
775 value = (width * norm_hdelay(core->tvnorm)) / swidth;
776 value &= 0x3fe;
777 cx_write(MO_HDELAY_EVEN, value);
778 cx_write(MO_HDELAY_ODD, value);
779 dprintk(1,"set_scale: hdelay 0x%04x\n", value);
780
781 value = (swidth * 4096 / width) - 4096;
782 cx_write(MO_HSCALE_EVEN, value);
783 cx_write(MO_HSCALE_ODD, value);
784 dprintk(1,"set_scale: hscale 0x%04x\n", value);
785
786 cx_write(MO_HACTIVE_EVEN, width);
787 cx_write(MO_HACTIVE_ODD, width);
788 dprintk(1,"set_scale: hactive 0x%04x\n", width);
789
790 // recalc V scale Register (delay is constant)
791 cx_write(MO_VDELAY_EVEN, norm_vdelay(core->tvnorm));
792 cx_write(MO_VDELAY_ODD, norm_vdelay(core->tvnorm));
793 dprintk(1,"set_scale: vdelay 0x%04x\n", norm_vdelay(core->tvnorm));
794
795 value = (0x10000 - (sheight * 512 / height - 512)) & 0x1fff;
796 cx_write(MO_VSCALE_EVEN, value);
797 cx_write(MO_VSCALE_ODD, value);
798 dprintk(1,"set_scale: vscale 0x%04x\n", value);
799
800 cx_write(MO_VACTIVE_EVEN, sheight);
801 cx_write(MO_VACTIVE_ODD, sheight);
802 dprintk(1,"set_scale: vactive 0x%04x\n", sheight);
803
804 // setup filters
805 value = 0;
806 value |= (1 << 19); // CFILT (default)
807 if (core->tvnorm->id & V4L2_STD_SECAM) {
808 value |= (1 << 15);
809 value |= (1 << 16);
810 }
811 if (INPUT(core->input)->type == CX88_VMUX_SVIDEO)
812 value |= (1 << 13) | (1 << 5);
813 if (V4L2_FIELD_INTERLACED == field)
814 value |= (1 << 3); // VINT (interlaced vertical scaling)
815 if (width < 385)
816 value |= (1 << 0); // 3-tap interpolation
817 if (width < 193)
818 value |= (1 << 1); // 5-tap interpolation
819 if (nocomb)
820 value |= (3 << 5); // disable comb filter
821
822 cx_write(MO_FILTER_EVEN, value);
823 cx_write(MO_FILTER_ODD, value);
824 dprintk(1,"set_scale: filter 0x%04x\n", value);
825
826 return 0;
827}
828
829static const u32 xtal = 28636363;
830
831static int set_pll(struct cx88_core *core, int prescale, u32 ofreq)
832{
833 static u32 pre[] = { 0, 0, 0, 3, 2, 1 };
834 u64 pll;
835 u32 reg;
836 int i;
837
838 if (prescale < 2)
839 prescale = 2;
840 if (prescale > 5)
841 prescale = 5;
842
843 pll = ofreq * 8 * prescale * (u64)(1 << 20);
844 do_div(pll,xtal);
845 reg = (pll & 0x3ffffff) | (pre[prescale] << 26);
846 if (((reg >> 20) & 0x3f) < 14) {
847 printk("%s/0: pll out of range\n",core->name);
848 return -1;
849 }
850
851 dprintk(1,"set_pll: MO_PLL_REG 0x%08x [old=0x%08x,freq=%d]\n",
852 reg, cx_read(MO_PLL_REG), ofreq);
853 cx_write(MO_PLL_REG, reg);
854 for (i = 0; i < 100; i++) {
855 reg = cx_read(MO_DEVICE_STATUS);
856 if (reg & (1<<2)) {
857 dprintk(1,"pll locked [pre=%d,ofreq=%d]\n",
858 prescale,ofreq);
859 return 0;
860 }
861 dprintk(1,"pll not locked yet, waiting ...\n");
862 msleep(10);
863 }
864 dprintk(1,"pll NOT locked [pre=%d,ofreq=%d]\n",prescale,ofreq);
865 return -1;
866}
867
868static int set_tvaudio(struct cx88_core *core)
869{
870 struct cx88_tvnorm *norm = core->tvnorm;
871
872 if (CX88_VMUX_TELEVISION != INPUT(core->input)->type)
873 return 0;
874
875 if (V4L2_STD_PAL_BG & norm->id) {
876 core->tvaudio = nicam ? WW_NICAM_BGDKL : WW_A2_BG;
877
878 } else if (V4L2_STD_PAL_DK & norm->id) {
879 core->tvaudio = nicam ? WW_NICAM_BGDKL : WW_A2_DK;
880
881 } else if (V4L2_STD_PAL_I & norm->id) {
882 core->tvaudio = WW_NICAM_I;
883
884 } else if (V4L2_STD_SECAM_L & norm->id) {
885 core->tvaudio = WW_SYSTEM_L_AM;
886
887 } else if (V4L2_STD_SECAM_DK & norm->id) {
888 core->tvaudio = WW_A2_DK;
889
890 } else if ((V4L2_STD_NTSC_M & norm->id) ||
891 (V4L2_STD_PAL_M & norm->id)) {
892 core->tvaudio = WW_BTSC;
893
894 } else if (V4L2_STD_NTSC_M_JP & norm->id) {
895 core->tvaudio = WW_EIAJ;
896
897 } else {
898 printk("%s/0: tvaudio support needs work for this tv norm [%s], sorry\n",
899 core->name, norm->name);
900 core->tvaudio = 0;
901 return 0;
902 }
903
904 cx_andor(MO_AFECFG_IO, 0x1f, 0x0);
905 cx88_set_tvaudio(core);
906 // cx88_set_stereo(dev,V4L2_TUNER_MODE_STEREO);
907
908 cx_write(MO_AUDD_LNGTH, 128); /* fifo size */
909 cx_write(MO_AUDR_LNGTH, 128); /* fifo size */
910 cx_write(MO_AUD_DMACNTRL, 0x03); /* need audio fifo */
911 return 0;
912}
913
914int cx88_set_tvnorm(struct cx88_core *core, struct cx88_tvnorm *norm)
915{
916 u32 fsc8;
917 u32 adc_clock;
918 u32 vdec_clock;
919 u32 step_db,step_dr;
920 u64 tmp64;
921 u32 bdelay,agcdelay,htotal;
922
923 core->tvnorm = norm;
924 fsc8 = norm_fsc8(norm);
925 adc_clock = xtal;
926 vdec_clock = fsc8;
927 step_db = fsc8;
928 step_dr = fsc8;
929
930 if (norm->id & V4L2_STD_SECAM) {
931 step_db = 4250000 * 8;
932 step_dr = 4406250 * 8;
933 }
934
935 dprintk(1,"set_tvnorm: \"%s\" fsc8=%d adc=%d vdec=%d db/dr=%d/%d\n",
936 norm->name, fsc8, adc_clock, vdec_clock, step_db, step_dr);
937 set_pll(core,2,vdec_clock);
938
939 dprintk(1,"set_tvnorm: MO_INPUT_FORMAT 0x%08x [old=0x%08x]\n",
940 norm->cxiformat, cx_read(MO_INPUT_FORMAT) & 0x0f);
941 cx_andor(MO_INPUT_FORMAT, 0xf, norm->cxiformat);
942
943#if 1
944 // FIXME: as-is from DScaler
945 dprintk(1,"set_tvnorm: MO_OUTPUT_FORMAT 0x%08x [old=0x%08x]\n",
946 norm->cxoformat, cx_read(MO_OUTPUT_FORMAT));
947 cx_write(MO_OUTPUT_FORMAT, norm->cxoformat);
948#endif
949
950 // MO_SCONV_REG = adc clock / video dec clock * 2^17
951 tmp64 = adc_clock * (u64)(1 << 17);
952 do_div(tmp64, vdec_clock);
953 dprintk(1,"set_tvnorm: MO_SCONV_REG 0x%08x [old=0x%08x]\n",
954 (u32)tmp64, cx_read(MO_SCONV_REG));
955 cx_write(MO_SCONV_REG, (u32)tmp64);
956
957 // MO_SUB_STEP = 8 * fsc / video dec clock * 2^22
958 tmp64 = step_db * (u64)(1 << 22);
959 do_div(tmp64, vdec_clock);
960 dprintk(1,"set_tvnorm: MO_SUB_STEP 0x%08x [old=0x%08x]\n",
961 (u32)tmp64, cx_read(MO_SUB_STEP));
962 cx_write(MO_SUB_STEP, (u32)tmp64);
963
964 // MO_SUB_STEP_DR = 8 * 4406250 / video dec clock * 2^22
965 tmp64 = step_dr * (u64)(1 << 22);
966 do_div(tmp64, vdec_clock);
967 dprintk(1,"set_tvnorm: MO_SUB_STEP_DR 0x%08x [old=0x%08x]\n",
968 (u32)tmp64, cx_read(MO_SUB_STEP_DR));
969 cx_write(MO_SUB_STEP_DR, (u32)tmp64);
970
971 // bdelay + agcdelay
972 bdelay = vdec_clock * 65 / 20000000 + 21;
973 agcdelay = vdec_clock * 68 / 20000000 + 15;
974 dprintk(1,"set_tvnorm: MO_AGC_BURST 0x%08x [old=0x%08x,bdelay=%d,agcdelay=%d]\n",
975 (bdelay << 8) | agcdelay, cx_read(MO_AGC_BURST), bdelay, agcdelay);
976 cx_write(MO_AGC_BURST, (bdelay << 8) | agcdelay);
977
978 // htotal
979 tmp64 = norm_htotal(norm) * (u64)vdec_clock;
980 do_div(tmp64, fsc8);
981 htotal = (u32)tmp64 | (norm_notchfilter(norm) << 11);
982 dprintk(1,"set_tvnorm: MO_HTOTAL 0x%08x [old=0x%08x,htotal=%d]\n",
983 htotal, cx_read(MO_HTOTAL), (u32)tmp64);
984 cx_write(MO_HTOTAL, htotal);
985
986 // vbi stuff
987 cx_write(MO_VBI_PACKET, ((1 << 11) | /* (norm_vdelay(norm) << 11) | */
988 norm_vbipack(norm)));
989
990 // this is needed as well to set all tvnorm parameter
991 cx88_set_scale(core, 320, 240, V4L2_FIELD_INTERLACED);
992
993 // audio
994 set_tvaudio(core);
995
996 // tell i2c chips
997#ifdef V4L2_I2C_CLIENTS
998 cx88_call_i2c_clients(core,VIDIOC_S_STD,&norm->id);
999#else
1000 {
1001 struct video_channel c;
1002 memset(&c,0,sizeof(c));
1003 c.channel = core->input;
1004 c.norm = VIDEO_MODE_PAL;
1005 if ((norm->id & (V4L2_STD_NTSC_M|V4L2_STD_NTSC_M_JP)))
1006 c.norm = VIDEO_MODE_NTSC;
1007 if (norm->id & V4L2_STD_SECAM)
1008 c.norm = VIDEO_MODE_SECAM;
1009 cx88_call_i2c_clients(core,VIDIOCSCHAN,&c);
1010 }
1011#endif
1012
1013 // done
1014 return 0;
1015}
1016
1017/* ------------------------------------------------------------------ */
1018
1019static int cx88_pci_quirks(char *name, struct pci_dev *pci)
1020{
1021 unsigned int lat = UNSET;
1022 u8 ctrl = 0;
1023 u8 value;
1024
1025 /* check pci quirks */
1026 if (pci_pci_problems & PCIPCI_TRITON) {
1027 printk(KERN_INFO "%s: quirk: PCIPCI_TRITON -- set TBFX\n",
1028 name);
1029 ctrl |= CX88X_EN_TBFX;
1030 }
1031 if (pci_pci_problems & PCIPCI_NATOMA) {
1032 printk(KERN_INFO "%s: quirk: PCIPCI_NATOMA -- set TBFX\n",
1033 name);
1034 ctrl |= CX88X_EN_TBFX;
1035 }
1036 if (pci_pci_problems & PCIPCI_VIAETBF) {
1037 printk(KERN_INFO "%s: quirk: PCIPCI_VIAETBF -- set TBFX\n",
1038 name);
1039 ctrl |= CX88X_EN_TBFX;
1040 }
1041 if (pci_pci_problems & PCIPCI_VSFX) {
1042 printk(KERN_INFO "%s: quirk: PCIPCI_VSFX -- set VSFX\n",
1043 name);
1044 ctrl |= CX88X_EN_VSFX;
1045 }
1046#ifdef PCIPCI_ALIMAGIK
1047 if (pci_pci_problems & PCIPCI_ALIMAGIK) {
1048 printk(KERN_INFO "%s: quirk: PCIPCI_ALIMAGIK -- latency fixup\n",
1049 name);
1050 lat = 0x0A;
1051 }
1052#endif
1053
1054 /* check insmod options */
1055 if (UNSET != latency)
1056 lat = latency;
1057
1058 /* apply stuff */
1059 if (ctrl) {
1060 pci_read_config_byte(pci, CX88X_DEVCTRL, &value);
1061 value |= ctrl;
1062 pci_write_config_byte(pci, CX88X_DEVCTRL, value);
1063 }
1064 if (UNSET != lat) {
1065 printk(KERN_INFO "%s: setting pci latency timer to %d\n",
1066 name, latency);
1067 pci_write_config_byte(pci, PCI_LATENCY_TIMER, latency);
1068 }
1069 return 0;
1070}
1071
1072/* ------------------------------------------------------------------ */
1073
1074struct video_device *cx88_vdev_init(struct cx88_core *core,
1075 struct pci_dev *pci,
1076 struct video_device *template,
1077 char *type)
1078{
1079 struct video_device *vfd;
1080
1081 vfd = video_device_alloc();
1082 if (NULL == vfd)
1083 return NULL;
1084 *vfd = *template;
1085 vfd->minor = -1;
1086 vfd->dev = &pci->dev;
1087 vfd->release = video_device_release;
1088 snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)",
1089 core->name, type, cx88_boards[core->board].name);
1090 return vfd;
1091}
1092
1093static int get_ressources(struct cx88_core *core, struct pci_dev *pci)
1094{
1095 if (request_mem_region(pci_resource_start(pci,0),
1096 pci_resource_len(pci,0),
1097 core->name))
1098 return 0;
1099 printk(KERN_ERR "%s: can't get MMIO memory @ 0x%lx\n",
1100 core->name,pci_resource_start(pci,0));
1101 return -EBUSY;
1102}
1103
1104struct cx88_core* cx88_core_get(struct pci_dev *pci)
1105{
1106 struct cx88_core *core;
1107 struct list_head *item;
1108 int i;
1109
1110 down(&devlist);
1111 list_for_each(item,&cx88_devlist) {
1112 core = list_entry(item, struct cx88_core, devlist);
1113 if (pci->bus->number != core->pci_bus)
1114 continue;
1115 if (PCI_SLOT(pci->devfn) != core->pci_slot)
1116 continue;
1117
1118 if (0 != get_ressources(core,pci))
1119 goto fail_unlock;
1120 atomic_inc(&core->refcount);
1121 up(&devlist);
1122 return core;
1123 }
1124 core = kmalloc(sizeof(*core),GFP_KERNEL);
1125 if (NULL == core)
1126 goto fail_unlock;
1127
1128 memset(core,0,sizeof(*core));
1129 atomic_inc(&core->refcount);
1130 core->pci_bus = pci->bus->number;
1131 core->pci_slot = PCI_SLOT(pci->devfn);
1132 core->pci_irqmask = 0x00fc00;
1133
1134 core->nr = cx88_devcount++;
1135 sprintf(core->name,"cx88[%d]",core->nr);
1136 if (0 != get_ressources(core,pci)) {
1137 cx88_devcount--;
1138 goto fail_free;
1139 }
1140 list_add_tail(&core->devlist,&cx88_devlist);
1141
1142 /* PCI stuff */
1143 cx88_pci_quirks(core->name, pci);
1144 core->lmmio = ioremap(pci_resource_start(pci,0),
1145 pci_resource_len(pci,0));
1146 core->bmmio = (u8 __iomem *)core->lmmio;
1147
1148 /* board config */
1149 core->board = UNSET;
1150 if (card[core->nr] < cx88_bcount)
1151 core->board = card[core->nr];
1152 for (i = 0; UNSET == core->board && i < cx88_idcount; i++)
1153 if (pci->subsystem_vendor == cx88_subids[i].subvendor &&
1154 pci->subsystem_device == cx88_subids[i].subdevice)
1155 core->board = cx88_subids[i].card;
1156 if (UNSET == core->board) {
1157 core->board = CX88_BOARD_UNKNOWN;
1158 cx88_card_list(core,pci);
1159 }
1160 printk(KERN_INFO "%s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n",
1161 core->name,pci->subsystem_vendor,
1162 pci->subsystem_device,cx88_boards[core->board].name,
1163 core->board, card[core->nr] == core->board ?
1164 "insmod option" : "autodetected");
1165
1166 core->tuner_type = tuner[core->nr];
1167 if (UNSET == core->tuner_type)
1168 core->tuner_type = cx88_boards[core->board].tuner_type;
1169 core->tda9887_conf = cx88_boards[core->board].tda9887_conf;
1170
1171 /* init hardware */
1172 cx88_reset(core);
1173 cx88_i2c_init(core,pci);
1174 cx88_card_setup(core);
1175 cx88_ir_init(core,pci);
1176
1177 up(&devlist);
1178 return core;
1179
1180fail_free:
1181 kfree(core);
1182fail_unlock:
1183 up(&devlist);
1184 return NULL;
1185}
1186
1187void cx88_core_put(struct cx88_core *core, struct pci_dev *pci)
1188{
1189 release_mem_region(pci_resource_start(pci,0),
1190 pci_resource_len(pci,0));
1191
1192 if (!atomic_dec_and_test(&core->refcount))
1193 return;
1194
1195 down(&devlist);
1196 cx88_ir_fini(core);
1197 if (0 == core->i2c_rc)
1198 i2c_bit_del_bus(&core->i2c_adap);
1199 list_del(&core->devlist);
1200 iounmap(core->lmmio);
1201 cx88_devcount--;
1202 up(&devlist);
1203 kfree(core);
1204}
1205
1206/* ------------------------------------------------------------------ */
1207
1208EXPORT_SYMBOL(cx88_print_ioctl);
1209EXPORT_SYMBOL(cx88_pci_irqs);
1210EXPORT_SYMBOL(cx88_vid_irqs);
1211EXPORT_SYMBOL(cx88_mpeg_irqs);
1212EXPORT_SYMBOL(cx88_print_irqbits);
1213
1214EXPORT_SYMBOL(cx88_core_irq);
1215EXPORT_SYMBOL(cx88_wakeup);
1216EXPORT_SYMBOL(cx88_reset);
1217EXPORT_SYMBOL(cx88_shutdown);
1218
1219EXPORT_SYMBOL(cx88_risc_buffer);
1220EXPORT_SYMBOL(cx88_risc_databuffer);
1221EXPORT_SYMBOL(cx88_risc_stopper);
1222EXPORT_SYMBOL(cx88_free_buffer);
1223
1224EXPORT_SYMBOL(cx88_sram_channels);
1225EXPORT_SYMBOL(cx88_sram_channel_setup);
1226EXPORT_SYMBOL(cx88_sram_channel_dump);
1227
1228EXPORT_SYMBOL(cx88_set_tvnorm);
1229EXPORT_SYMBOL(cx88_set_scale);
1230
1231EXPORT_SYMBOL(cx88_vdev_init);
1232EXPORT_SYMBOL(cx88_core_get);
1233EXPORT_SYMBOL(cx88_core_put);
1234
1235/*
1236 * Local variables:
1237 * c-basic-offset: 8
1238 * End:
1239 */
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c
new file mode 100644
index 00000000000..bc6f18c4535
--- /dev/null
+++ b/drivers/media/video/cx88/cx88-dvb.c
@@ -0,0 +1,381 @@
1/*
2 * $Id: cx88-dvb.c,v 1.31 2005/03/07 15:58:05 kraxel Exp $
3 *
4 * device driver for Conexant 2388x based TV cards
5 * MPEG Transport Stream (DVB) routines
6 *
7 * (c) 2004 Chris Pascoe <c.pascoe@itee.uq.edu.au>
8 * (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
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#include <linux/module.h>
26#include <linux/init.h>
27#include <linux/device.h>
28#include <linux/fs.h>
29#include <linux/kthread.h>
30#include <linux/file.h>
31#include <linux/suspend.h>
32
33/* those two frontends need merging via linuxtv cvs ... */
34#define HAVE_CX22702 0
35#define HAVE_OR51132 1
36
37#include "cx88.h"
38#include "dvb-pll.h"
39#include "mt352.h"
40#include "mt352_priv.h"
41#if HAVE_CX22702
42# include "cx22702.h"
43#endif
44#if HAVE_OR51132
45# include "or51132.h"
46#endif
47
48MODULE_DESCRIPTION("driver for cx2388x based DVB cards");
49MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>");
50MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
51MODULE_LICENSE("GPL");
52
53static unsigned int debug = 0;
54module_param(debug, int, 0644);
55MODULE_PARM_DESC(debug,"enable debug messages [dvb]");
56
57#define dprintk(level,fmt, arg...) if (debug >= level) \
58 printk(KERN_DEBUG "%s/2-dvb: " fmt, dev->core->name , ## arg)
59
60/* ------------------------------------------------------------------ */
61
62static int dvb_buf_setup(struct videobuf_queue *q,
63 unsigned int *count, unsigned int *size)
64{
65 struct cx8802_dev *dev = q->priv_data;
66
67 dev->ts_packet_size = 188 * 4;
68 dev->ts_packet_count = 32;
69
70 *size = dev->ts_packet_size * dev->ts_packet_count;
71 *count = 32;
72 return 0;
73}
74
75static int dvb_buf_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
76 enum v4l2_field field)
77{
78 struct cx8802_dev *dev = q->priv_data;
79 return cx8802_buf_prepare(dev, (struct cx88_buffer*)vb);
80}
81
82static void dvb_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
83{
84 struct cx8802_dev *dev = q->priv_data;
85 cx8802_buf_queue(dev, (struct cx88_buffer*)vb);
86}
87
88static void dvb_buf_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
89{
90 struct cx8802_dev *dev = q->priv_data;
91 cx88_free_buffer(dev->pci, (struct cx88_buffer*)vb);
92}
93
94struct videobuf_queue_ops dvb_qops = {
95 .buf_setup = dvb_buf_setup,
96 .buf_prepare = dvb_buf_prepare,
97 .buf_queue = dvb_buf_queue,
98 .buf_release = dvb_buf_release,
99};
100
101/* ------------------------------------------------------------------ */
102
103static int dvico_fusionhdtv_demod_init(struct dvb_frontend* fe)
104{
105 static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x39 };
106 static u8 reset [] = { RESET, 0x80 };
107 static u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 };
108 static u8 agc_cfg [] = { AGC_TARGET, 0x24, 0x20 };
109 static u8 gpp_ctl_cfg [] = { GPP_CTL, 0x33 };
110 static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };
111
112 mt352_write(fe, clock_config, sizeof(clock_config));
113 udelay(200);
114 mt352_write(fe, reset, sizeof(reset));
115 mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
116
117 mt352_write(fe, agc_cfg, sizeof(agc_cfg));
118 mt352_write(fe, gpp_ctl_cfg, sizeof(gpp_ctl_cfg));
119 mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
120 return 0;
121}
122
123static int dntv_live_dvbt_demod_init(struct dvb_frontend* fe)
124{
125 static u8 clock_config [] = { 0x89, 0x38, 0x39 };
126 static u8 reset [] = { 0x50, 0x80 };
127 static u8 adc_ctl_1_cfg [] = { 0x8E, 0x40 };
128 static u8 agc_cfg [] = { 0x67, 0x10, 0x23, 0x00, 0xFF, 0xFF,
129 0x00, 0xFF, 0x00, 0x40, 0x40 };
130 static u8 dntv_extra[] = { 0xB5, 0x7A };
131 static u8 capt_range_cfg[] = { 0x75, 0x32 };
132
133 mt352_write(fe, clock_config, sizeof(clock_config));
134 udelay(2000);
135 mt352_write(fe, reset, sizeof(reset));
136 mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
137
138 mt352_write(fe, agc_cfg, sizeof(agc_cfg));
139 udelay(2000);
140 mt352_write(fe, dntv_extra, sizeof(dntv_extra));
141 mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
142
143 return 0;
144}
145
146static int mt352_pll_set(struct dvb_frontend* fe,
147 struct dvb_frontend_parameters* params,
148 u8* pllbuf)
149{
150 struct cx8802_dev *dev= fe->dvb->priv;
151
152 pllbuf[0] = dev->core->pll_addr << 1;
153 dvb_pll_configure(dev->core->pll_desc, pllbuf+1,
154 params->frequency,
155 params->u.ofdm.bandwidth);
156 return 0;
157}
158
159static struct mt352_config dvico_fusionhdtv = {
160 .demod_address = 0x0F,
161 .demod_init = dvico_fusionhdtv_demod_init,
162 .pll_set = mt352_pll_set,
163};
164
165static struct mt352_config dntv_live_dvbt_config = {
166 .demod_address = 0x0f,
167 .demod_init = dntv_live_dvbt_demod_init,
168 .pll_set = mt352_pll_set,
169};
170
171#if HAVE_CX22702
172static struct cx22702_config connexant_refboard_config = {
173 .demod_address = 0x43,
174 .pll_address = 0x60,
175 .pll_desc = &dvb_pll_thomson_dtt7579,
176};
177
178static struct cx22702_config hauppauge_novat_config = {
179 .demod_address = 0x43,
180 .pll_address = 0x61,
181 .pll_desc = &dvb_pll_thomson_dtt759x,
182};
183#endif
184
185#if HAVE_OR51132
186static int or51132_set_ts_param(struct dvb_frontend* fe,
187 int is_punctured)
188{
189 struct cx8802_dev *dev= fe->dvb->priv;
190 dev->ts_gen_cntrl = is_punctured ? 0x04 : 0x00;
191 return 0;
192}
193
194struct or51132_config pchdtv_hd3000 = {
195 .demod_address = 0x15,
196 .pll_address = 0x61,
197 .pll_desc = &dvb_pll_thomson_dtt7610,
198 .set_ts_params = or51132_set_ts_param,
199};
200#endif
201
202static int dvb_register(struct cx8802_dev *dev)
203{
204 /* init struct videobuf_dvb */
205 dev->dvb.name = dev->core->name;
206 dev->ts_gen_cntrl = 0x0c;
207
208 /* init frontend */
209 switch (dev->core->board) {
210#if HAVE_CX22702
211 case CX88_BOARD_HAUPPAUGE_DVB_T1:
212 dev->dvb.frontend = cx22702_attach(&hauppauge_novat_config,
213 &dev->core->i2c_adap);
214 break;
215 case CX88_BOARD_CONEXANT_DVB_T1:
216 dev->dvb.frontend = cx22702_attach(&connexant_refboard_config,
217 &dev->core->i2c_adap);
218 break;
219#endif
220 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1:
221 dev->core->pll_addr = 0x61;
222 dev->core->pll_desc = &dvb_pll_lg_z201;
223 dev->dvb.frontend = mt352_attach(&dvico_fusionhdtv,
224 &dev->core->i2c_adap);
225 break;
226 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS:
227 dev->core->pll_addr = 0x60;
228 dev->core->pll_desc = &dvb_pll_thomson_dtt7579;
229 dev->dvb.frontend = mt352_attach(&dvico_fusionhdtv,
230 &dev->core->i2c_adap);
231 break;
232 case CX88_BOARD_KWORLD_DVB_T:
233 case CX88_BOARD_DNTV_LIVE_DVB_T:
234 dev->core->pll_addr = 0x61;
235 dev->core->pll_desc = &dvb_pll_unknown_1;
236 dev->dvb.frontend = mt352_attach(&dntv_live_dvbt_config,
237 &dev->core->i2c_adap);
238 break;
239#if HAVE_OR51132
240 case CX88_BOARD_PCHDTV_HD3000:
241 dev->dvb.frontend = or51132_attach(&pchdtv_hd3000,
242 &dev->core->i2c_adap);
243 break;
244#endif
245 default:
246 printk("%s: The frontend of your DVB/ATSC card isn't supported yet\n"
247 "%s: you might want to look out for patches here:\n"
248 "%s: http://dl.bytesex.org/patches/\n",
249 dev->core->name, dev->core->name, dev->core->name);
250 break;
251 }
252 if (NULL == dev->dvb.frontend) {
253 printk("%s: frontend initialization failed\n",dev->core->name);
254 return -1;
255 }
256
257 if (dev->core->pll_desc) {
258 dev->dvb.frontend->ops->info.frequency_min = dev->core->pll_desc->min;
259 dev->dvb.frontend->ops->info.frequency_max = dev->core->pll_desc->max;
260 }
261
262 /* Copy the board name into the DVB structure */
263 strlcpy(dev->dvb.frontend->ops->info.name,
264 cx88_boards[dev->core->board].name,
265 sizeof(dev->dvb.frontend->ops->info.name));
266
267 /* register everything */
268 return videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev);
269}
270
271/* ----------------------------------------------------------- */
272
273static int __devinit dvb_probe(struct pci_dev *pci_dev,
274 const struct pci_device_id *pci_id)
275{
276 struct cx8802_dev *dev;
277 struct cx88_core *core;
278 int err;
279
280 /* general setup */
281 core = cx88_core_get(pci_dev);
282 if (NULL == core)
283 return -EINVAL;
284
285 err = -ENODEV;
286 if (!cx88_boards[core->board].dvb)
287 goto fail_core;
288
289 err = -ENOMEM;
290 dev = kmalloc(sizeof(*dev),GFP_KERNEL);
291 if (NULL == dev)
292 goto fail_core;
293 memset(dev,0,sizeof(*dev));
294 dev->pci = pci_dev;
295 dev->core = core;
296
297 err = cx8802_init_common(dev);
298 if (0 != err)
299 goto fail_free;
300
301 /* dvb stuff */
302 printk("%s/2: cx2388x based dvb card\n", core->name);
303 videobuf_queue_init(&dev->dvb.dvbq, &dvb_qops,
304 dev->pci, &dev->slock,
305 V4L2_BUF_TYPE_VIDEO_CAPTURE,
306 V4L2_FIELD_TOP,
307 sizeof(struct cx88_buffer),
308 dev);
309 err = dvb_register(dev);
310 if (0 != err)
311 goto fail_free;
312 return 0;
313
314 fail_free:
315 kfree(dev);
316 fail_core:
317 cx88_core_put(core,pci_dev);
318 return err;
319}
320
321static void __devexit dvb_remove(struct pci_dev *pci_dev)
322{
323 struct cx8802_dev *dev = pci_get_drvdata(pci_dev);
324
325 /* dvb */
326 videobuf_dvb_unregister(&dev->dvb);
327
328 /* common */
329 cx8802_fini_common(dev);
330 cx88_core_put(dev->core,dev->pci);
331 kfree(dev);
332}
333
334static struct pci_device_id cx8802_pci_tbl[] = {
335 {
336 .vendor = 0x14f1,
337 .device = 0x8802,
338 .subvendor = PCI_ANY_ID,
339 .subdevice = PCI_ANY_ID,
340 },{
341 /* --- end of list --- */
342 }
343};
344MODULE_DEVICE_TABLE(pci, cx8802_pci_tbl);
345
346static struct pci_driver dvb_pci_driver = {
347 .name = "cx88-dvb",
348 .id_table = cx8802_pci_tbl,
349 .probe = dvb_probe,
350 .remove = __devexit_p(dvb_remove),
351 .suspend = cx8802_suspend_common,
352 .resume = cx8802_resume_common,
353};
354
355static int dvb_init(void)
356{
357 printk(KERN_INFO "cx2388x dvb driver version %d.%d.%d loaded\n",
358 (CX88_VERSION_CODE >> 16) & 0xff,
359 (CX88_VERSION_CODE >> 8) & 0xff,
360 CX88_VERSION_CODE & 0xff);
361#ifdef SNAPSHOT
362 printk(KERN_INFO "cx2388x: snapshot date %04d-%02d-%02d\n",
363 SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100);
364#endif
365 return pci_register_driver(&dvb_pci_driver);
366}
367
368static void dvb_fini(void)
369{
370 pci_unregister_driver(&dvb_pci_driver);
371}
372
373module_init(dvb_init);
374module_exit(dvb_fini);
375
376/*
377 * Local variables:
378 * c-basic-offset: 8
379 * compile-command: "make DVB=1"
380 * End:
381 */
diff --git a/drivers/media/video/cx88/cx88-i2c.c b/drivers/media/video/cx88/cx88-i2c.c
new file mode 100644
index 00000000000..60800172c02
--- /dev/null
+++ b/drivers/media/video/cx88/cx88-i2c.c
@@ -0,0 +1,213 @@
1/*
2 $Id: cx88-i2c.c,v 1.20 2005/02/15 15:59:35 kraxel Exp $
3
4 cx88-i2c.c -- all the i2c code is here
5
6 Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
7 & Marcus Metzler (mocm@thp.uni-koeln.de)
8 (c) 2002 Yurij Sysoev <yurij@naturesoft.net>
9 (c) 1999-2003 Gerd Knorr <kraxel@bytesex.org>
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
27#include <linux/module.h>
28#include <linux/moduleparam.h>
29#include <linux/init.h>
30
31#include <asm/io.h>
32
33#include "cx88.h"
34
35static unsigned int i2c_debug = 0;
36module_param(i2c_debug, int, 0644);
37MODULE_PARM_DESC(i2c_debug,"enable debug messages [i2c]");
38
39static unsigned int i2c_scan = 0;
40module_param(i2c_scan, int, 0444);
41MODULE_PARM_DESC(i2c_scan,"scan i2c bus at insmod time");
42
43#define dprintk(level,fmt, arg...) if (i2c_debug >= level) \
44 printk(KERN_DEBUG "%s: " fmt, core->name , ## arg)
45
46/* ----------------------------------------------------------------------- */
47
48void cx8800_bit_setscl(void *data, int state)
49{
50 struct cx88_core *core = data;
51
52 if (state)
53 core->i2c_state |= 0x02;
54 else
55 core->i2c_state &= ~0x02;
56 cx_write(MO_I2C, core->i2c_state);
57 cx_read(MO_I2C);
58}
59
60void cx8800_bit_setsda(void *data, int state)
61{
62 struct cx88_core *core = data;
63
64 if (state)
65 core->i2c_state |= 0x01;
66 else
67 core->i2c_state &= ~0x01;
68 cx_write(MO_I2C, core->i2c_state);
69 cx_read(MO_I2C);
70}
71
72static int cx8800_bit_getscl(void *data)
73{
74 struct cx88_core *core = data;
75 u32 state;
76
77 state = cx_read(MO_I2C);
78 return state & 0x02 ? 1 : 0;
79}
80
81static int cx8800_bit_getsda(void *data)
82{
83 struct cx88_core *core = data;
84 u32 state;
85
86 state = cx_read(MO_I2C);
87 return state & 0x01;
88}
89
90/* ----------------------------------------------------------------------- */
91
92static int attach_inform(struct i2c_client *client)
93{
94 struct cx88_core *core = i2c_get_adapdata(client->adapter);
95
96 dprintk(1, "i2c attach [addr=0x%x,client=%s]\n",
97 client->addr, i2c_clientname(client));
98 if (!client->driver->command)
99 return 0;
100
101 if (core->tuner_type != UNSET)
102 client->driver->command(client, TUNER_SET_TYPE, &core->tuner_type);
103 if (core->tda9887_conf)
104 client->driver->command(client, TDA9887_SET_CONFIG, &core->tda9887_conf);
105 return 0;
106}
107
108static int detach_inform(struct i2c_client *client)
109{
110 struct cx88_core *core = i2c_get_adapdata(client->adapter);
111
112 dprintk(1, "i2c detach [client=%s]\n", i2c_clientname(client));
113 return 0;
114}
115
116void cx88_call_i2c_clients(struct cx88_core *core, unsigned int cmd, void *arg)
117{
118 if (0 != core->i2c_rc)
119 return;
120 i2c_clients_command(&core->i2c_adap, cmd, arg);
121}
122
123static struct i2c_algo_bit_data cx8800_i2c_algo_template = {
124 .setsda = cx8800_bit_setsda,
125 .setscl = cx8800_bit_setscl,
126 .getsda = cx8800_bit_getsda,
127 .getscl = cx8800_bit_getscl,
128 .udelay = 16,
129 .mdelay = 10,
130 .timeout = 200,
131};
132
133/* ----------------------------------------------------------------------- */
134
135static struct i2c_adapter cx8800_i2c_adap_template = {
136 I2C_DEVNAME("cx2388x"),
137 .owner = THIS_MODULE,
138 .id = I2C_HW_B_CX2388x,
139 .client_register = attach_inform,
140 .client_unregister = detach_inform,
141};
142
143static struct i2c_client cx8800_i2c_client_template = {
144 I2C_DEVNAME("cx88xx internal"),
145};
146
147static char *i2c_devs[128] = {
148 [ 0x86 >> 1 ] = "tda9887/cx22702",
149 [ 0xa0 >> 1 ] = "eeprom",
150 [ 0xc0 >> 1 ] = "tuner (analog)",
151 [ 0xc2 >> 1 ] = "tuner (analog/dvb)",
152};
153
154static void do_i2c_scan(char *name, struct i2c_client *c)
155{
156 unsigned char buf;
157 int i,rc;
158
159 for (i = 0; i < 128; i++) {
160 c->addr = i;
161 rc = i2c_master_recv(c,&buf,0);
162 if (rc < 0)
163 continue;
164 printk("%s: i2c scan: found device @ 0x%x [%s]\n",
165 name, i << 1, i2c_devs[i] ? i2c_devs[i] : "???");
166 }
167}
168
169/* init + register i2c algo-bit adapter */
170int cx88_i2c_init(struct cx88_core *core, struct pci_dev *pci)
171{
172 memcpy(&core->i2c_adap, &cx8800_i2c_adap_template,
173 sizeof(core->i2c_adap));
174 memcpy(&core->i2c_algo, &cx8800_i2c_algo_template,
175 sizeof(core->i2c_algo));
176 memcpy(&core->i2c_client, &cx8800_i2c_client_template,
177 sizeof(core->i2c_client));
178
179 if (core->tuner_type != TUNER_ABSENT)
180 core->i2c_adap.class |= I2C_CLASS_TV_ANALOG;
181 if (cx88_boards[core->board].dvb)
182 core->i2c_adap.class |= I2C_CLASS_TV_DIGITAL;
183
184 core->i2c_adap.dev.parent = &pci->dev;
185 strlcpy(core->i2c_adap.name,core->name,sizeof(core->i2c_adap.name));
186 core->i2c_algo.data = core;
187 i2c_set_adapdata(&core->i2c_adap,core);
188 core->i2c_adap.algo_data = &core->i2c_algo;
189 core->i2c_client.adapter = &core->i2c_adap;
190
191 cx8800_bit_setscl(core,1);
192 cx8800_bit_setsda(core,1);
193
194 core->i2c_rc = i2c_bit_add_bus(&core->i2c_adap);
195 if (0 == core->i2c_rc) {
196 dprintk(1, "i2c register ok\n");
197 if (i2c_scan)
198 do_i2c_scan(core->name,&core->i2c_client);
199 } else
200 printk("%s: i2c register FAILED\n", core->name);
201 return core->i2c_rc;
202}
203
204/* ----------------------------------------------------------------------- */
205
206EXPORT_SYMBOL(cx88_call_i2c_clients);
207EXPORT_SYMBOL(cx88_i2c_init);
208
209/*
210 * Local variables:
211 * c-basic-offset: 8
212 * End:
213 */
diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c
new file mode 100644
index 00000000000..af6ad8cdbdb
--- /dev/null
+++ b/drivers/media/video/cx88/cx88-input.c
@@ -0,0 +1,396 @@
1/*
2 * $Id: cx88-input.c,v 1.9 2005/03/04 09:12:23 kraxel Exp $
3 *
4 * Device driver for GPIO attached remote control interfaces
5 * on Conexant 2388x based TV/DVB cards.
6 *
7 * Copyright (c) 2003 Pavel Machek
8 * Copyright (c) 2004 Gerd Knorr
9 * Copyright (c) 2004 Chris Pascoe
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 */
25
26#include <linux/init.h>
27#include <linux/delay.h>
28#include <linux/input.h>
29#include <linux/pci.h>
30#include <linux/module.h>
31#include <linux/moduleparam.h>
32
33#include <media/ir-common.h>
34
35#include "cx88.h"
36
37/* ---------------------------------------------------------------------- */
38
39/* DigitalNow DNTV Live DVB-T Remote */
40static IR_KEYTAB_TYPE ir_codes_dntv_live_dvb_t[IR_KEYTAB_SIZE] = {
41 [ 0x00 ] = KEY_ESC, // 'go up a level?'
42 [ 0x01 ] = KEY_KP1, // '1'
43 [ 0x02 ] = KEY_KP2, // '2'
44 [ 0x03 ] = KEY_KP3, // '3'
45 [ 0x04 ] = KEY_KP4, // '4'
46 [ 0x05 ] = KEY_KP5, // '5'
47 [ 0x06 ] = KEY_KP6, // '6'
48 [ 0x07 ] = KEY_KP7, // '7'
49 [ 0x08 ] = KEY_KP8, // '8'
50 [ 0x09 ] = KEY_KP9, // '9'
51 [ 0x0a ] = KEY_KP0, // '0'
52 [ 0x0b ] = KEY_TUNER, // 'tv/fm'
53 [ 0x0c ] = KEY_SEARCH, // 'scan'
54 [ 0x0d ] = KEY_STOP, // 'stop'
55 [ 0x0e ] = KEY_PAUSE, // 'pause'
56 [ 0x0f ] = KEY_LIST, // 'source'
57
58 [ 0x10 ] = KEY_MUTE, // 'mute'
59 [ 0x11 ] = KEY_REWIND, // 'backward <<'
60 [ 0x12 ] = KEY_POWER, // 'power'
61 [ 0x13 ] = KEY_S, // 'snap'
62 [ 0x14 ] = KEY_AUDIO, // 'stereo'
63 [ 0x15 ] = KEY_CLEAR, // 'reset'
64 [ 0x16 ] = KEY_PLAY, // 'play'
65 [ 0x17 ] = KEY_ENTER, // 'enter'
66 [ 0x18 ] = KEY_ZOOM, // 'full screen'
67 [ 0x19 ] = KEY_FASTFORWARD, // 'forward >>'
68 [ 0x1a ] = KEY_CHANNELUP, // 'channel +'
69 [ 0x1b ] = KEY_VOLUMEUP, // 'volume +'
70 [ 0x1c ] = KEY_INFO, // 'preview'
71 [ 0x1d ] = KEY_RECORD, // 'record'
72 [ 0x1e ] = KEY_CHANNELDOWN, // 'channel -'
73 [ 0x1f ] = KEY_VOLUMEDOWN, // 'volume -'
74};
75
76/* ---------------------------------------------------------------------- */
77
78/* IO-DATA BCTV7E Remote */
79static IR_KEYTAB_TYPE ir_codes_iodata_bctv7e[IR_KEYTAB_SIZE] = {
80 [ 0x40 ] = KEY_TV, // TV
81 [ 0x20 ] = KEY_RADIO, // FM
82 [ 0x60 ] = KEY_EPG, // EPG
83 [ 0x00 ] = KEY_POWER, // power
84
85 [ 0x50 ] = KEY_KP1, // 1
86 [ 0x30 ] = KEY_KP2, // 2
87 [ 0x70 ] = KEY_KP3, // 3
88 [ 0x10 ] = KEY_L, // Live
89
90 [ 0x48 ] = KEY_KP4, // 4
91 [ 0x28 ] = KEY_KP5, // 5
92 [ 0x68 ] = KEY_KP6, // 6
93 [ 0x08 ] = KEY_T, // Time Shift
94
95 [ 0x58 ] = KEY_KP7, // 7
96 [ 0x38 ] = KEY_KP8, // 8
97 [ 0x78 ] = KEY_KP9, // 9
98 [ 0x18 ] = KEY_PLAYPAUSE, // Play
99
100 [ 0x44 ] = KEY_KP0, // 10
101 [ 0x24 ] = KEY_ENTER, // 11
102 [ 0x64 ] = KEY_ESC, // 12
103 [ 0x04 ] = KEY_M, // Multi
104
105 [ 0x54 ] = KEY_VIDEO, // VIDEO
106 [ 0x34 ] = KEY_CHANNELUP, // channel +
107 [ 0x74 ] = KEY_VOLUMEUP, // volume +
108 [ 0x14 ] = KEY_MUTE, // Mute
109
110 [ 0x4c ] = KEY_S, // SVIDEO
111 [ 0x2c ] = KEY_CHANNELDOWN, // channel -
112 [ 0x6c ] = KEY_VOLUMEDOWN, // volume -
113 [ 0x0c ] = KEY_ZOOM, // Zoom
114
115 [ 0x5c ] = KEY_PAUSE, // pause
116 [ 0x3c ] = KEY_C, // || (red)
117 [ 0x7c ] = KEY_RECORD, // recording
118 [ 0x1c ] = KEY_STOP, // stop
119
120 [ 0x41 ] = KEY_REWIND, // backward <<
121 [ 0x21 ] = KEY_PLAY, // play
122 [ 0x61 ] = KEY_FASTFORWARD, // forward >>
123 [ 0x01 ] = KEY_NEXT, // skip >|
124};
125
126/* ---------------------------------------------------------------------- */
127
128struct cx88_IR {
129 struct cx88_core *core;
130 struct input_dev input;
131 struct ir_input_state ir;
132 char name[32];
133 char phys[32];
134
135 /* sample from gpio pin 16 */
136 int sampling;
137 u32 samples[16];
138 int scount;
139 unsigned long release;
140
141 /* poll external decoder */
142 int polling;
143 struct work_struct work;
144 struct timer_list timer;
145 u32 gpio_addr;
146 u32 last_gpio;
147 u32 mask_keycode;
148 u32 mask_keydown;
149 u32 mask_keyup;
150};
151
152static int ir_debug = 0;
153module_param(ir_debug, int, 0644); /* debug level [IR] */
154MODULE_PARM_DESC(ir_debug, "enable debug messages [IR]");
155
156#define ir_dprintk(fmt, arg...) if (ir_debug) \
157 printk(KERN_DEBUG "%s IR: " fmt , ir->core->name, ## arg)
158
159/* ---------------------------------------------------------------------- */
160
161static void cx88_ir_handle_key(struct cx88_IR *ir)
162{
163 struct cx88_core *core = ir->core;
164 u32 gpio, data;
165
166 /* read gpio value */
167 gpio = cx_read(ir->gpio_addr);
168 if (ir->polling) {
169 if (ir->last_gpio == gpio)
170 return;
171 ir->last_gpio = gpio;
172 }
173
174 /* extract data */
175 data = ir_extract_bits(gpio, ir->mask_keycode);
176 ir_dprintk("irq gpio=0x%x code=%d | %s%s%s\n",
177 gpio, data,
178 ir->polling ? "poll" : "irq",
179 (gpio & ir->mask_keydown) ? " down" : "",
180 (gpio & ir->mask_keyup) ? " up" : "");
181
182 if (ir->mask_keydown) {
183 /* bit set on keydown */
184 if (gpio & ir->mask_keydown) {
185 ir_input_keydown(&ir->input,&ir->ir,data,data);
186 } else {
187 ir_input_nokey(&ir->input,&ir->ir);
188 }
189
190 } else if (ir->mask_keyup) {
191 /* bit cleared on keydown */
192 if (0 == (gpio & ir->mask_keyup)) {
193 ir_input_keydown(&ir->input,&ir->ir,data,data);
194 } else {
195 ir_input_nokey(&ir->input,&ir->ir);
196 }
197
198 } else {
199 /* can't distinguish keydown/up :-/ */
200 ir_input_keydown(&ir->input,&ir->ir,data,data);
201 ir_input_nokey(&ir->input,&ir->ir);
202 }
203}
204
205static void ir_timer(unsigned long data)
206{
207 struct cx88_IR *ir = (struct cx88_IR*)data;
208
209 schedule_work(&ir->work);
210}
211
212static void cx88_ir_work(void *data)
213{
214 struct cx88_IR *ir = data;
215 unsigned long timeout;
216
217 cx88_ir_handle_key(ir);
218 timeout = jiffies + (ir->polling * HZ / 1000);
219 mod_timer(&ir->timer, timeout);
220}
221
222/* ---------------------------------------------------------------------- */
223
224int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
225{
226 struct cx88_IR *ir;
227 IR_KEYTAB_TYPE *ir_codes = NULL;
228 int ir_type = IR_TYPE_OTHER;
229
230 ir = kmalloc(sizeof(*ir),GFP_KERNEL);
231 if (NULL == ir)
232 return -ENOMEM;
233 memset(ir,0,sizeof(*ir));
234
235 /* detect & configure */
236 switch (core->board) {
237 case CX88_BOARD_DNTV_LIVE_DVB_T:
238 ir_codes = ir_codes_dntv_live_dvb_t;
239 ir->gpio_addr = MO_GP1_IO;
240 ir->mask_keycode = 0x1f;
241 ir->mask_keyup = 0x60;
242 ir->polling = 50; // ms
243 break;
244 case CX88_BOARD_HAUPPAUGE:
245 case CX88_BOARD_HAUPPAUGE_DVB_T1:
246 ir_codes = ir_codes_hauppauge_new;
247 ir_type = IR_TYPE_RC5;
248 ir->sampling = 1;
249 break;
250 case CX88_BOARD_WINFAST2000XP_EXPERT:
251 ir_codes = ir_codes_winfast;
252 ir->gpio_addr = MO_GP0_IO;
253 ir->mask_keycode = 0x8f8;
254 ir->mask_keyup = 0x100;
255 ir->polling = 1; // ms
256 break;
257 case CX88_BOARD_IODATA_GVBCTV7E:
258 ir_codes = ir_codes_iodata_bctv7e;
259 ir->gpio_addr = MO_GP0_IO;
260 ir->mask_keycode = 0xfd;
261 ir->mask_keydown = 0x02;
262 ir->polling = 5; // ms
263 break;
264 }
265 if (NULL == ir_codes) {
266 kfree(ir);
267 return -ENODEV;
268 }
269
270 /* init input device */
271 snprintf(ir->name, sizeof(ir->name), "cx88 IR (%s)",
272 cx88_boards[core->board].name);
273 snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0",
274 pci_name(pci));
275
276 ir_input_init(&ir->input, &ir->ir, ir_type, ir_codes);
277 ir->input.name = ir->name;
278 ir->input.phys = ir->phys;
279 ir->input.id.bustype = BUS_PCI;
280 ir->input.id.version = 1;
281 if (pci->subsystem_vendor) {
282 ir->input.id.vendor = pci->subsystem_vendor;
283 ir->input.id.product = pci->subsystem_device;
284 } else {
285 ir->input.id.vendor = pci->vendor;
286 ir->input.id.product = pci->device;
287 }
288
289 /* record handles to ourself */
290 ir->core = core;
291 core->ir = ir;
292
293 if (ir->polling) {
294 INIT_WORK(&ir->work, cx88_ir_work, ir);
295 init_timer(&ir->timer);
296 ir->timer.function = ir_timer;
297 ir->timer.data = (unsigned long)ir;
298 schedule_work(&ir->work);
299 }
300 if (ir->sampling) {
301 core->pci_irqmask |= (1<<18); // IR_SMP_INT
302 cx_write(MO_DDS_IO, 0xa80a80); // 4 kHz sample rate
303 cx_write(MO_DDSCFG_IO, 0x5); // enable
304 }
305
306 /* all done */
307 input_register_device(&ir->input);
308 printk("%s: registered IR remote control\n", core->name);
309
310 return 0;
311}
312
313int cx88_ir_fini(struct cx88_core *core)
314{
315 struct cx88_IR *ir = core->ir;
316
317 /* skip detach on non attached boards */
318 if (NULL == ir)
319 return 0;
320
321 if (ir->polling) {
322 del_timer(&ir->timer);
323 flush_scheduled_work();
324 }
325
326 input_unregister_device(&ir->input);
327 kfree(ir);
328
329 /* done */
330 core->ir = NULL;
331 return 0;
332}
333
334/* ---------------------------------------------------------------------- */
335
336void cx88_ir_irq(struct cx88_core *core)
337{
338 struct cx88_IR *ir = core->ir;
339 u32 samples,rc5;
340 int i;
341
342 if (NULL == ir)
343 return;
344 if (!ir->sampling)
345 return;
346
347 samples = cx_read(MO_SAMPLE_IO);
348 if (0 != samples && 0xffffffff != samples) {
349 /* record sample data */
350 if (ir->scount < ARRAY_SIZE(ir->samples))
351 ir->samples[ir->scount++] = samples;
352 return;
353 }
354 if (!ir->scount) {
355 /* nothing to sample */
356 if (ir->ir.keypressed && time_after(jiffies,ir->release))
357 ir_input_nokey(&ir->input,&ir->ir);
358 return;
359 }
360
361 /* have a complete sample */
362 if (ir->scount < ARRAY_SIZE(ir->samples))
363 ir->samples[ir->scount++] = samples;
364 for (i = 0; i < ir->scount; i++)
365 ir->samples[i] = ~ir->samples[i];
366 if (ir_debug)
367 ir_dump_samples(ir->samples,ir->scount);
368
369 /* decode it */
370 switch (core->board) {
371 case CX88_BOARD_HAUPPAUGE:
372 case CX88_BOARD_HAUPPAUGE_DVB_T1:
373 rc5 = ir_decode_biphase(ir->samples,ir->scount,5,7);
374 ir_dprintk("biphase decoded: %x\n",rc5);
375 if ((rc5 & 0xfffff000) != 0x3000)
376 break;
377 ir_input_keydown(&ir->input, &ir->ir, rc5 & 0x3f, rc5);
378 ir->release = jiffies + msecs_to_jiffies(120);
379 break;
380 }
381
382 ir->scount = 0;
383 return;
384}
385
386/* ---------------------------------------------------------------------- */
387
388MODULE_AUTHOR("Gerd Knorr, Pavel Machek, Chris Pascoe");
389MODULE_DESCRIPTION("input driver for cx88 GPIO-based IR remote controls");
390MODULE_LICENSE("GPL");
391
392/*
393 * Local variables:
394 * c-basic-offset: 8
395 * End:
396 */
diff --git a/drivers/media/video/cx88/cx88-mpeg.c b/drivers/media/video/cx88/cx88-mpeg.c
new file mode 100644
index 00000000000..07aae1899e1
--- /dev/null
+++ b/drivers/media/video/cx88/cx88-mpeg.c
@@ -0,0 +1,466 @@
1/*
2 * $Id: cx88-mpeg.c,v 1.25 2005/03/07 14:18:00 kraxel Exp $
3 *
4 * Support for the mpeg transport stream transfers
5 * PCI function #2 of the cx2388x.
6 *
7 * (c) 2004 Jelle Foks <jelle@foks.8m.com>
8 * (c) 2004 Chris Pascoe <c.pascoe@itee.uq.edu.au>
9 * (c) 2004 Gerd Knorr <kraxel@bytesex.org>
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#include <linux/module.h>
27#include <linux/moduleparam.h>
28#include <linux/init.h>
29#include <linux/device.h>
30#include <linux/interrupt.h>
31#include <asm/delay.h>
32
33#include "cx88.h"
34
35/* ------------------------------------------------------------------ */
36
37MODULE_DESCRIPTION("mpeg driver for cx2388x based TV cards");
38MODULE_AUTHOR("Jelle Foks <jelle@foks.8m.com>");
39MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>");
40MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
41MODULE_LICENSE("GPL");
42
43static unsigned int debug = 0;
44module_param(debug,int,0644);
45MODULE_PARM_DESC(debug,"enable debug messages [mpeg]");
46
47#define dprintk(level,fmt, arg...) if (debug >= level) \
48 printk(KERN_DEBUG "%s/2: " fmt, dev->core->name , ## arg)
49
50/* ------------------------------------------------------------------ */
51
52static int cx8802_start_dma(struct cx8802_dev *dev,
53 struct cx88_dmaqueue *q,
54 struct cx88_buffer *buf)
55{
56 struct cx88_core *core = dev->core;
57
58 dprintk(1, "cx8802_start_mpegport_dma %d\n", buf->vb.width);
59
60 /* setup fifo + format */
61 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH28],
62 dev->ts_packet_size, buf->risc.dma);
63
64 /* write TS length to chip */
65 cx_write(MO_TS_LNGTH, buf->vb.width);
66
67#if 1
68 /* FIXME: this needs a review.
69 * also: move to cx88-blackbird + cx88-dvb source files? */
70
71 if (cx88_boards[core->board].dvb) {
72 /* negedge driven & software reset */
73 cx_write(TS_GEN_CNTRL, 0x40);
74 udelay(100);
75 cx_write(MO_PINMUX_IO, 0x00);
76 cx_write(TS_HW_SOP_CNTRL,47<<16|188<<4|0x00);
77 cx_write(TS_SOP_STAT,0x00);
78 cx_write(TS_GEN_CNTRL, dev->ts_gen_cntrl);
79 udelay(100);
80 }
81
82 if (cx88_boards[core->board].blackbird) {
83 cx_write(MO_PINMUX_IO, 0x88); /* enable MPEG parallel IO */
84
85 // cx_write(TS_F2_CMD_STAT_MM, 0x2900106); /* F2_CMD_STAT_MM defaults + master + memory space */
86 cx_write(TS_GEN_CNTRL, 0x46); /* punctured clock TS & posedge driven & software reset */
87 udelay(100);
88
89 cx_write(TS_HW_SOP_CNTRL, 0x408); /* mpeg start byte */
90 //cx_write(TS_HW_SOP_CNTRL, 0x2F0BC0); /* mpeg start byte ts: 0x2F0BC0 ? */
91 cx_write(TS_VALERR_CNTRL, 0x2000);
92
93 cx_write(TS_GEN_CNTRL, 0x06); /* punctured clock TS & posedge driven */
94 udelay(100);
95 }
96#endif
97
98 /* reset counter */
99 cx_write(MO_TS_GPCNTRL, GP_COUNT_CONTROL_RESET);
100 q->count = 1;
101
102 /* enable irqs */
103 cx_set(MO_PCI_INTMSK, core->pci_irqmask | 0x04);
104 cx_write(MO_TS_INTMSK, 0x1f0011);
105
106 /* start dma */
107 cx_write(MO_DEV_CNTRL2, (1<<5)); /* FIXME: s/write/set/ ??? */
108 cx_write(MO_TS_DMACNTRL, 0x11);
109 return 0;
110}
111
112static int cx8802_stop_dma(struct cx8802_dev *dev)
113{
114 struct cx88_core *core = dev->core;
115
116 /* stop dma */
117 cx_clear(MO_TS_DMACNTRL, 0x11);
118
119 /* disable irqs */
120 cx_clear(MO_PCI_INTMSK, 0x000004);
121 cx_clear(MO_TS_INTMSK, 0x1f0011);
122
123 /* Reset the controller */
124 cx_write(TS_GEN_CNTRL, 0xcd);
125 return 0;
126}
127
128static int cx8802_restart_queue(struct cx8802_dev *dev,
129 struct cx88_dmaqueue *q)
130{
131 struct cx88_buffer *buf;
132 struct list_head *item;
133
134 if (list_empty(&q->active))
135 return 0;
136
137 buf = list_entry(q->active.next, struct cx88_buffer, vb.queue);
138 dprintk(2,"restart_queue [%p/%d]: restart dma\n",
139 buf, buf->vb.i);
140 cx8802_start_dma(dev, q, buf);
141 list_for_each(item,&q->active) {
142 buf = list_entry(item, struct cx88_buffer, vb.queue);
143 buf->count = q->count++;
144 }
145 mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
146 return 0;
147}
148
149/* ------------------------------------------------------------------ */
150
151int cx8802_buf_prepare(struct cx8802_dev *dev, struct cx88_buffer *buf)
152{
153 int size = dev->ts_packet_size * dev->ts_packet_count;
154 int rc;
155
156 dprintk(1, "%s: %p\n", __FUNCTION__, buf);
157 if (0 != buf->vb.baddr && buf->vb.bsize < size)
158 return -EINVAL;
159
160 if (STATE_NEEDS_INIT == buf->vb.state) {
161 buf->vb.width = dev->ts_packet_size;
162 buf->vb.height = dev->ts_packet_count;
163 buf->vb.size = size;
164 buf->vb.field = V4L2_FIELD_TOP;
165
166 if (0 != (rc = videobuf_iolock(dev->pci,&buf->vb,NULL)))
167 goto fail;
168 cx88_risc_databuffer(dev->pci, &buf->risc,
169 buf->vb.dma.sglist,
170 buf->vb.width, buf->vb.height);
171 }
172 buf->vb.state = STATE_PREPARED;
173 return 0;
174
175 fail:
176 cx88_free_buffer(dev->pci,buf);
177 return rc;
178}
179
180void cx8802_buf_queue(struct cx8802_dev *dev, struct cx88_buffer *buf)
181{
182 struct cx88_buffer *prev;
183 struct cx88_dmaqueue *q = &dev->mpegq;
184
185 /* add jump to stopper */
186 buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
187 buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
188
189 if (list_empty(&q->active)) {
190 list_add_tail(&buf->vb.queue,&q->active);
191 cx8802_start_dma(dev, q, buf);
192 buf->vb.state = STATE_ACTIVE;
193 buf->count = q->count++;
194 mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
195 dprintk(2,"[%p/%d] %s - first active\n",
196 buf, buf->vb.i, __FUNCTION__);
197
198 } else {
199 prev = list_entry(q->active.prev, struct cx88_buffer, vb.queue);
200 list_add_tail(&buf->vb.queue,&q->active);
201 buf->vb.state = STATE_ACTIVE;
202 buf->count = q->count++;
203 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
204 dprintk(2,"[%p/%d] %s - append to active\n",
205 buf, buf->vb.i, __FUNCTION__);
206 }
207}
208
209/* ----------------------------------------------------------- */
210
211static void do_cancel_buffers(struct cx8802_dev *dev, char *reason, int restart)
212{
213 struct cx88_dmaqueue *q = &dev->mpegq;
214 struct cx88_buffer *buf;
215 unsigned long flags;
216
217 spin_lock_irqsave(&dev->slock,flags);
218 while (!list_empty(&q->active)) {
219 buf = list_entry(q->active.next, struct cx88_buffer, vb.queue);
220 list_del(&buf->vb.queue);
221 buf->vb.state = STATE_ERROR;
222 wake_up(&buf->vb.done);
223 dprintk(1,"[%p/%d] %s - dma=0x%08lx\n",
224 buf, buf->vb.i, reason, (unsigned long)buf->risc.dma);
225 }
226 if (restart)
227 cx8802_restart_queue(dev,q);
228 spin_unlock_irqrestore(&dev->slock,flags);
229}
230
231void cx8802_cancel_buffers(struct cx8802_dev *dev)
232{
233 struct cx88_dmaqueue *q = &dev->mpegq;
234
235 del_timer_sync(&q->timeout);
236 cx8802_stop_dma(dev);
237 do_cancel_buffers(dev,"cancel",0);
238}
239
240static void cx8802_timeout(unsigned long data)
241{
242 struct cx8802_dev *dev = (struct cx8802_dev*)data;
243
244 dprintk(1, "%s\n",__FUNCTION__);
245
246 if (debug)
247 cx88_sram_channel_dump(dev->core, &cx88_sram_channels[SRAM_CH28]);
248 cx8802_stop_dma(dev);
249 do_cancel_buffers(dev,"timeout",1);
250}
251
252static void cx8802_mpeg_irq(struct cx8802_dev *dev)
253{
254 struct cx88_core *core = dev->core;
255 u32 status, mask, count;
256
257 status = cx_read(MO_TS_INTSTAT);
258 mask = cx_read(MO_TS_INTMSK);
259 if (0 == (status & mask))
260 return;
261
262 cx_write(MO_TS_INTSTAT, status);
263 if (debug || (status & mask & ~0xff))
264 cx88_print_irqbits(core->name, "irq mpeg ",
265 cx88_mpeg_irqs, status, mask);
266
267 /* risc op code error */
268 if (status & (1 << 16)) {
269 printk(KERN_WARNING "%s: mpeg risc op code error\n",core->name);
270 cx_clear(MO_TS_DMACNTRL, 0x11);
271 cx88_sram_channel_dump(dev->core, &cx88_sram_channels[SRAM_CH28]);
272 }
273
274 /* risc1 y */
275 if (status & 0x01) {
276 spin_lock(&dev->slock);
277 count = cx_read(MO_TS_GPCNT);
278 cx88_wakeup(dev->core, &dev->mpegq, count);
279 spin_unlock(&dev->slock);
280 }
281
282 /* risc2 y */
283 if (status & 0x10) {
284 spin_lock(&dev->slock);
285 cx8802_restart_queue(dev,&dev->mpegq);
286 spin_unlock(&dev->slock);
287 }
288
289 /* other general errors */
290 if (status & 0x1f0100) {
291 spin_lock(&dev->slock);
292 cx8802_stop_dma(dev);
293 cx8802_restart_queue(dev,&dev->mpegq);
294 spin_unlock(&dev->slock);
295 }
296}
297
298static irqreturn_t cx8802_irq(int irq, void *dev_id, struct pt_regs *regs)
299{
300 struct cx8802_dev *dev = dev_id;
301 struct cx88_core *core = dev->core;
302 u32 status;
303 int loop, handled = 0;
304
305 for (loop = 0; loop < 10; loop++) {
306 status = cx_read(MO_PCI_INTSTAT) & (core->pci_irqmask | 0x04);
307 if (0 == status)
308 goto out;
309 handled = 1;
310 cx_write(MO_PCI_INTSTAT, status);
311
312 if (status & core->pci_irqmask)
313 cx88_core_irq(core,status);
314 if (status & 0x04)
315 cx8802_mpeg_irq(dev);
316 };
317 if (10 == loop) {
318 printk(KERN_WARNING "%s/0: irq loop -- clearing mask\n",
319 core->name);
320 cx_write(MO_PCI_INTMSK,0);
321 }
322
323 out:
324 return IRQ_RETVAL(handled);
325}
326
327/* ----------------------------------------------------------- */
328/* exported stuff */
329
330int cx8802_init_common(struct cx8802_dev *dev)
331{
332 struct cx88_core *core = dev->core;
333 int err;
334
335 /* pci init */
336 if (pci_enable_device(dev->pci))
337 return -EIO;
338 pci_set_master(dev->pci);
339 if (!pci_dma_supported(dev->pci,0xffffffff)) {
340 printk("%s/2: Oops: no 32bit PCI DMA ???\n",dev->core->name);
341 return -EIO;
342 }
343
344 pci_read_config_byte(dev->pci, PCI_CLASS_REVISION, &dev->pci_rev);
345 pci_read_config_byte(dev->pci, PCI_LATENCY_TIMER, &dev->pci_lat);
346 printk(KERN_INFO "%s/2: found at %s, rev: %d, irq: %d, "
347 "latency: %d, mmio: 0x%lx\n", dev->core->name,
348 pci_name(dev->pci), dev->pci_rev, dev->pci->irq,
349 dev->pci_lat,pci_resource_start(dev->pci,0));
350
351 /* initialize driver struct */
352 init_MUTEX(&dev->lock);
353 spin_lock_init(&dev->slock);
354
355 /* init dma queue */
356 INIT_LIST_HEAD(&dev->mpegq.active);
357 INIT_LIST_HEAD(&dev->mpegq.queued);
358 dev->mpegq.timeout.function = cx8802_timeout;
359 dev->mpegq.timeout.data = (unsigned long)dev;
360 init_timer(&dev->mpegq.timeout);
361 cx88_risc_stopper(dev->pci,&dev->mpegq.stopper,
362 MO_TS_DMACNTRL,0x11,0x00);
363
364 /* get irq */
365 err = request_irq(dev->pci->irq, cx8802_irq,
366 SA_SHIRQ | SA_INTERRUPT, dev->core->name, dev);
367 if (err < 0) {
368 printk(KERN_ERR "%s: can't get IRQ %d\n",
369 dev->core->name, dev->pci->irq);
370 return err;
371 }
372 cx_set(MO_PCI_INTMSK, core->pci_irqmask);
373
374 /* everything worked */
375 pci_set_drvdata(dev->pci,dev);
376 return 0;
377}
378
379void cx8802_fini_common(struct cx8802_dev *dev)
380{
381 cx8802_stop_dma(dev);
382 pci_disable_device(dev->pci);
383
384 /* unregister stuff */
385 free_irq(dev->pci->irq, dev);
386 pci_set_drvdata(dev->pci, NULL);
387
388 /* free memory */
389 btcx_riscmem_free(dev->pci,&dev->mpegq.stopper);
390}
391
392/* ----------------------------------------------------------- */
393
394int cx8802_suspend_common(struct pci_dev *pci_dev, pm_message_t state)
395{
396 struct cx8802_dev *dev = pci_get_drvdata(pci_dev);
397 struct cx88_core *core = dev->core;
398
399 /* stop mpeg dma */
400 spin_lock(&dev->slock);
401 if (!list_empty(&dev->mpegq.active)) {
402 printk("%s: suspend mpeg\n", core->name);
403 cx8802_stop_dma(dev);
404 del_timer(&dev->mpegq.timeout);
405 }
406 spin_unlock(&dev->slock);
407
408#if 1
409 /* FIXME -- shutdown device */
410 cx88_shutdown(dev->core);
411#endif
412
413 pci_save_state(pci_dev);
414 if (0 != pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state))) {
415 pci_disable_device(pci_dev);
416 dev->state.disabled = 1;
417 }
418 return 0;
419}
420
421int cx8802_resume_common(struct pci_dev *pci_dev)
422{
423 struct cx8802_dev *dev = pci_get_drvdata(pci_dev);
424 struct cx88_core *core = dev->core;
425
426 if (dev->state.disabled) {
427 pci_enable_device(pci_dev);
428 dev->state.disabled = 0;
429 }
430 pci_set_power_state(pci_dev, PCI_D0);
431 pci_restore_state(pci_dev);
432
433#if 1
434 /* FIXME: re-initialize hardware */
435 cx88_reset(dev->core);
436#endif
437
438 /* restart video+vbi capture */
439 spin_lock(&dev->slock);
440 if (!list_empty(&dev->mpegq.active)) {
441 printk("%s: resume mpeg\n", core->name);
442 cx8802_restart_queue(dev,&dev->mpegq);
443 }
444 spin_unlock(&dev->slock);
445
446 return 0;
447}
448
449/* ----------------------------------------------------------- */
450
451EXPORT_SYMBOL(cx8802_buf_prepare);
452EXPORT_SYMBOL(cx8802_buf_queue);
453EXPORT_SYMBOL(cx8802_cancel_buffers);
454
455EXPORT_SYMBOL(cx8802_init_common);
456EXPORT_SYMBOL(cx8802_fini_common);
457
458EXPORT_SYMBOL(cx8802_suspend_common);
459EXPORT_SYMBOL(cx8802_resume_common);
460
461/* ----------------------------------------------------------- */
462/*
463 * Local variables:
464 * c-basic-offset: 8
465 * End:
466 */
diff --git a/drivers/media/video/cx88/cx88-reg.h b/drivers/media/video/cx88/cx88-reg.h
new file mode 100644
index 00000000000..8638ce57d84
--- /dev/null
+++ b/drivers/media/video/cx88/cx88-reg.h
@@ -0,0 +1,787 @@
1/*
2 $Id: cx88-reg.h,v 1.6 2004/10/13 10:39:00 kraxel Exp $
3
4 cx88x-hw.h - CX2388x register offsets
5
6 Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
7 2001 Michael Eskin
8 2002 Yurij Sysoev <yurij@naturesoft.net>
9 2003 Gerd Knorr <kraxel@bytesex.org>
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#ifndef _CX88_REG_H_
27#define _CX88_REG_H_
28
29/* ---------------------------------------------------------------------- */
30/* PCI IDs and config space */
31
32#ifndef PCI_VENDOR_ID_CONEXANT
33# define PCI_VENDOR_ID_CONEXANT 0x14F1
34#endif
35#ifndef PCI_DEVICE_ID_CX2300_VID
36# define PCI_DEVICE_ID_CX2300_VID 0x8800
37#endif
38
39#define CX88X_DEVCTRL 0x40
40#define CX88X_EN_TBFX 0x02
41#define CX88X_EN_VSFX 0x04
42
43
44/* ---------------------------------------------------------------------- */
45/* DMA Controller registers */
46
47#define MO_PDMA_STHRSH 0x200000 // Source threshold
48#define MO_PDMA_STADRS 0x200004 // Source target address
49#define MO_PDMA_SIADRS 0x200008 // Source internal address
50#define MO_PDMA_SCNTRL 0x20000C // Source control
51#define MO_PDMA_DTHRSH 0x200010 // Destination threshold
52#define MO_PDMA_DTADRS 0x200014 // Destination target address
53#define MO_PDMA_DIADRS 0x200018 // Destination internal address
54#define MO_PDMA_DCNTRL 0x20001C // Destination control
55#define MO_LD_SSID 0x200030 // Load subsystem ID
56#define MO_DEV_CNTRL2 0x200034 // Device control
57#define MO_PCI_INTMSK 0x200040 // PCI interrupt mask
58#define MO_PCI_INTSTAT 0x200044 // PCI interrupt status
59#define MO_PCI_INTMSTAT 0x200048 // PCI interrupt masked status
60#define MO_VID_INTMSK 0x200050 // Video interrupt mask
61#define MO_VID_INTSTAT 0x200054 // Video interrupt status
62#define MO_VID_INTMSTAT 0x200058 // Video interrupt masked status
63#define MO_VID_INTSSTAT 0x20005C // Video interrupt set status
64#define MO_AUD_INTMSK 0x200060 // Audio interrupt mask
65#define MO_AUD_INTSTAT 0x200064 // Audio interrupt status
66#define MO_AUD_INTMSTAT 0x200068 // Audio interrupt masked status
67#define MO_AUD_INTSSTAT 0x20006C // Audio interrupt set status
68#define MO_TS_INTMSK 0x200070 // Transport stream interrupt mask
69#define MO_TS_INTSTAT 0x200074 // Transport stream interrupt status
70#define MO_TS_INTMSTAT 0x200078 // Transport stream interrupt mask status
71#define MO_TS_INTSSTAT 0x20007C // Transport stream interrupt set status
72#define MO_VIP_INTMSK 0x200080 // VIP interrupt mask
73#define MO_VIP_INTSTAT 0x200084 // VIP interrupt status
74#define MO_VIP_INTMSTAT 0x200088 // VIP interrupt masked status
75#define MO_VIP_INTSSTAT 0x20008C // VIP interrupt set status
76#define MO_GPHST_INTMSK 0x200090 // Host interrupt mask
77#define MO_GPHST_INTSTAT 0x200094 // Host interrupt status
78#define MO_GPHST_INTMSTAT 0x200098 // Host interrupt masked status
79#define MO_GPHST_INTSSTAT 0x20009C // Host interrupt set status
80
81// DMA Channels 1-6 belong to SPIPE
82#define MO_DMA7_PTR1 0x300018 // {24}RW* DMA Current Ptr : Ch#7
83#define MO_DMA8_PTR1 0x30001C // {24}RW* DMA Current Ptr : Ch#8
84
85// DMA Channels 9-20 belong to SPIPE
86#define MO_DMA21_PTR1 0x300080 // {24}R0* DMA Current Ptr : Ch#21
87#define MO_DMA22_PTR1 0x300084 // {24}R0* DMA Current Ptr : Ch#22
88#define MO_DMA23_PTR1 0x300088 // {24}R0* DMA Current Ptr : Ch#23
89#define MO_DMA24_PTR1 0x30008C // {24}R0* DMA Current Ptr : Ch#24
90#define MO_DMA25_PTR1 0x300090 // {24}R0* DMA Current Ptr : Ch#25
91#define MO_DMA26_PTR1 0x300094 // {24}R0* DMA Current Ptr : Ch#26
92#define MO_DMA27_PTR1 0x300098 // {24}R0* DMA Current Ptr : Ch#27
93#define MO_DMA28_PTR1 0x30009C // {24}R0* DMA Current Ptr : Ch#28
94#define MO_DMA29_PTR1 0x3000A0 // {24}R0* DMA Current Ptr : Ch#29
95#define MO_DMA30_PTR1 0x3000A4 // {24}R0* DMA Current Ptr : Ch#30
96#define MO_DMA31_PTR1 0x3000A8 // {24}R0* DMA Current Ptr : Ch#31
97#define MO_DMA32_PTR1 0x3000AC // {24}R0* DMA Current Ptr : Ch#32
98
99#define MO_DMA21_PTR2 0x3000C0 // {24}RW* DMA Tab Ptr : Ch#21
100#define MO_DMA22_PTR2 0x3000C4 // {24}RW* DMA Tab Ptr : Ch#22
101#define MO_DMA23_PTR2 0x3000C8 // {24}RW* DMA Tab Ptr : Ch#23
102#define MO_DMA24_PTR2 0x3000CC // {24}RW* DMA Tab Ptr : Ch#24
103#define MO_DMA25_PTR2 0x3000D0 // {24}RW* DMA Tab Ptr : Ch#25
104#define MO_DMA26_PTR2 0x3000D4 // {24}RW* DMA Tab Ptr : Ch#26
105#define MO_DMA27_PTR2 0x3000D8 // {24}RW* DMA Tab Ptr : Ch#27
106#define MO_DMA28_PTR2 0x3000DC // {24}RW* DMA Tab Ptr : Ch#28
107#define MO_DMA29_PTR2 0x3000E0 // {24}RW* DMA Tab Ptr : Ch#29
108#define MO_DMA30_PTR2 0x3000E4 // {24}RW* DMA Tab Ptr : Ch#30
109#define MO_DMA31_PTR2 0x3000E8 // {24}RW* DMA Tab Ptr : Ch#31
110#define MO_DMA32_PTR2 0x3000EC // {24}RW* DMA Tab Ptr : Ch#32
111
112#define MO_DMA21_CNT1 0x300100 // {11}RW* DMA Buffer Size : Ch#21
113#define MO_DMA22_CNT1 0x300104 // {11}RW* DMA Buffer Size : Ch#22
114#define MO_DMA23_CNT1 0x300108 // {11}RW* DMA Buffer Size : Ch#23
115#define MO_DMA24_CNT1 0x30010C // {11}RW* DMA Buffer Size : Ch#24
116#define MO_DMA25_CNT1 0x300110 // {11}RW* DMA Buffer Size : Ch#25
117#define MO_DMA26_CNT1 0x300114 // {11}RW* DMA Buffer Size : Ch#26
118#define MO_DMA27_CNT1 0x300118 // {11}RW* DMA Buffer Size : Ch#27
119#define MO_DMA28_CNT1 0x30011C // {11}RW* DMA Buffer Size : Ch#28
120#define MO_DMA29_CNT1 0x300120 // {11}RW* DMA Buffer Size : Ch#29
121#define MO_DMA30_CNT1 0x300124 // {11}RW* DMA Buffer Size : Ch#30
122#define MO_DMA31_CNT1 0x300128 // {11}RW* DMA Buffer Size : Ch#31
123#define MO_DMA32_CNT1 0x30012C // {11}RW* DMA Buffer Size : Ch#32
124
125#define MO_DMA21_CNT2 0x300140 // {11}RW* DMA Table Size : Ch#21
126#define MO_DMA22_CNT2 0x300144 // {11}RW* DMA Table Size : Ch#22
127#define MO_DMA23_CNT2 0x300148 // {11}RW* DMA Table Size : Ch#23
128#define MO_DMA24_CNT2 0x30014C // {11}RW* DMA Table Size : Ch#24
129#define MO_DMA25_CNT2 0x300150 // {11}RW* DMA Table Size : Ch#25
130#define MO_DMA26_CNT2 0x300154 // {11}RW* DMA Table Size : Ch#26
131#define MO_DMA27_CNT2 0x300158 // {11}RW* DMA Table Size : Ch#27
132#define MO_DMA28_CNT2 0x30015C // {11}RW* DMA Table Size : Ch#28
133#define MO_DMA29_CNT2 0x300160 // {11}RW* DMA Table Size : Ch#29
134#define MO_DMA30_CNT2 0x300164 // {11}RW* DMA Table Size : Ch#30
135#define MO_DMA31_CNT2 0x300168 // {11}RW* DMA Table Size : Ch#31
136#define MO_DMA32_CNT2 0x30016C // {11}RW* DMA Table Size : Ch#32
137
138
139/* ---------------------------------------------------------------------- */
140/* Video registers */
141
142#define MO_VIDY_DMA 0x310000 // {64}RWp Video Y
143#define MO_VIDU_DMA 0x310008 // {64}RWp Video U
144#define MO_VIDV_DMA 0x310010 // {64}RWp Video V
145#define MO_VBI_DMA 0x310018 // {64}RWp VBI (Vertical blanking interval)
146
147#define MO_DEVICE_STATUS 0x310100
148#define MO_INPUT_FORMAT 0x310104
149#define MO_AGC_BURST 0x31010c
150#define MO_CONTR_BRIGHT 0x310110
151#define MO_UV_SATURATION 0x310114
152#define MO_HUE 0x310118
153#define MO_HTOTAL 0x310120
154#define MO_HDELAY_EVEN 0x310124
155#define MO_HDELAY_ODD 0x310128
156#define MO_VDELAY_ODD 0x31012c
157#define MO_VDELAY_EVEN 0x310130
158#define MO_HACTIVE_EVEN 0x31013c
159#define MO_HACTIVE_ODD 0x310140
160#define MO_VACTIVE_EVEN 0x310144
161#define MO_VACTIVE_ODD 0x310148
162#define MO_HSCALE_EVEN 0x31014c
163#define MO_HSCALE_ODD 0x310150
164#define MO_VSCALE_EVEN 0x310154
165#define MO_FILTER_EVEN 0x31015c
166#define MO_VSCALE_ODD 0x310158
167#define MO_FILTER_ODD 0x310160
168#define MO_OUTPUT_FORMAT 0x310164
169
170#define MO_PLL_REG 0x310168 // PLL register
171#define MO_PLL_ADJ_CTRL 0x31016c // PLL adjust control register
172#define MO_SCONV_REG 0x310170 // sample rate conversion register
173#define MO_SCONV_FIFO 0x310174 // sample rate conversion fifo
174#define MO_SUB_STEP 0x310178 // subcarrier step size
175#define MO_SUB_STEP_DR 0x31017c // subcarrier step size for DR line
176
177#define MO_CAPTURE_CTRL 0x310180 // capture control
178#define MO_COLOR_CTRL 0x310184
179#define MO_VBI_PACKET 0x310188 // vbi packet size / delay
180#define MO_FIELD_COUNT 0x310190 // field counter
181#define MO_VIP_CONFIG 0x310194
182#define MO_VBOS_CONTROL 0x3101a8
183
184#define MO_AGC_BACK_VBI 0x310200
185#define MO_AGC_SYNC_TIP1 0x310208
186
187#define MO_VIDY_GPCNT 0x31C020 // {16}RO Video Y general purpose counter
188#define MO_VIDU_GPCNT 0x31C024 // {16}RO Video U general purpose counter
189#define MO_VIDV_GPCNT 0x31C028 // {16}RO Video V general purpose counter
190#define MO_VBI_GPCNT 0x31C02C // {16}RO VBI general purpose counter
191#define MO_VIDY_GPCNTRL 0x31C030 // {2}WO Video Y general purpose control
192#define MO_VIDU_GPCNTRL 0x31C034 // {2}WO Video U general purpose control
193#define MO_VIDV_GPCNTRL 0x31C038 // {2}WO Video V general purpose control
194#define MO_VBI_GPCNTRL 0x31C03C // {2}WO VBI general purpose counter
195#define MO_VID_DMACNTRL 0x31C040 // {8}RW Video DMA control
196#define MO_VID_XFR_STAT 0x31C044 // {1}RO Video transfer status
197
198
199/* ---------------------------------------------------------------------- */
200/* audio registers */
201
202#define MO_AUDD_DMA 0x320000 // {64}RWp Audio downstream
203#define MO_AUDU_DMA 0x320008 // {64}RWp Audio upstream
204#define MO_AUDR_DMA 0x320010 // {64}RWp Audio RDS (downstream)
205#define MO_AUDD_GPCNT 0x32C020 // {16}RO Audio down general purpose counter
206#define MO_AUDU_GPCNT 0x32C024 // {16}RO Audio up general purpose counter
207#define MO_AUDR_GPCNT 0x32C028 // {16}RO Audio RDS general purpose counter
208#define MO_AUDD_GPCNTRL 0x32C030 // {2}WO Audio down general purpose control
209#define MO_AUDU_GPCNTRL 0x32C034 // {2}WO Audio up general purpose control
210#define MO_AUDR_GPCNTRL 0x32C038 // {2}WO Audio RDS general purpose control
211#define MO_AUD_DMACNTRL 0x32C040 // {6}RW Audio DMA control
212#define MO_AUD_XFR_STAT 0x32C044 // {1}RO Audio transfer status
213#define MO_AUDD_LNGTH 0x32C048 // {12}RW Audio down line length
214#define MO_AUDR_LNGTH 0x32C04C // {12}RW Audio RDS line length
215
216#define AUD_INIT 0x320100
217#define AUD_INIT_LD 0x320104
218#define AUD_SOFT_RESET 0x320108
219#define AUD_I2SINPUTCNTL 0x320120
220#define AUD_BAUDRATE 0x320124
221#define AUD_I2SOUTPUTCNTL 0x320128
222#define AAGC_HYST 0x320134
223#define AAGC_GAIN 0x320138
224#define AAGC_DEF 0x32013c
225#define AUD_IIR1_0_SEL 0x320150
226#define AUD_IIR1_0_SHIFT 0x320154
227#define AUD_IIR1_1_SEL 0x320158
228#define AUD_IIR1_1_SHIFT 0x32015c
229#define AUD_IIR1_2_SEL 0x320160
230#define AUD_IIR1_2_SHIFT 0x320164
231#define AUD_IIR1_3_SEL 0x320168
232#define AUD_IIR1_3_SHIFT 0x32016c
233#define AUD_IIR1_4_SEL 0x320170
234#define AUD_IIR1_4_SHIFT 0x32017c
235#define AUD_IIR1_5_SEL 0x320180
236#define AUD_IIR1_5_SHIFT 0x320184
237#define AUD_IIR2_0_SEL 0x320190
238#define AUD_IIR2_0_SHIFT 0x320194
239#define AUD_IIR2_1_SEL 0x320198
240#define AUD_IIR2_1_SHIFT 0x32019c
241#define AUD_IIR2_2_SEL 0x3201a0
242#define AUD_IIR2_2_SHIFT 0x3201a4
243#define AUD_IIR2_3_SEL 0x3201a8
244#define AUD_IIR2_3_SHIFT 0x3201ac
245#define AUD_IIR3_0_SEL 0x3201c0
246#define AUD_IIR3_0_SHIFT 0x3201c4
247#define AUD_IIR3_1_SEL 0x3201c8
248#define AUD_IIR3_1_SHIFT 0x3201cc
249#define AUD_IIR3_2_SEL 0x3201d0
250#define AUD_IIR3_2_SHIFT 0x3201d4
251#define AUD_IIR4_0_SEL 0x3201e0
252#define AUD_IIR4_0_SHIFT 0x3201e4
253#define AUD_IIR4_1_SEL 0x3201e8
254#define AUD_IIR4_1_SHIFT 0x3201ec
255#define AUD_IIR4_2_SEL 0x3201f0
256#define AUD_IIR4_2_SHIFT 0x3201f4
257#define AUD_IIR4_0_CA0 0x320200
258#define AUD_IIR4_0_CA1 0x320204
259#define AUD_IIR4_0_CA2 0x320208
260#define AUD_IIR4_0_CB0 0x32020c
261#define AUD_IIR4_0_CB1 0x320210
262#define AUD_IIR4_1_CA0 0x320214
263#define AUD_IIR4_1_CA1 0x320218
264#define AUD_IIR4_1_CA2 0x32021c
265#define AUD_IIR4_1_CB0 0x320220
266#define AUD_IIR4_1_CB1 0x320224
267#define AUD_IIR4_2_CA0 0x320228
268#define AUD_IIR4_2_CA1 0x32022c
269#define AUD_IIR4_2_CA2 0x320230
270#define AUD_IIR4_2_CB0 0x320234
271#define AUD_IIR4_2_CB1 0x320238
272#define AUD_HP_MD_IIR4_1 0x320250
273#define AUD_HP_PROG_IIR4_1 0x320254
274#define AUD_FM_MODE_ENABLE 0x320258
275#define AUD_POLY0_DDS_CONSTANT 0x320270
276#define AUD_DN0_FREQ 0x320274
277#define AUD_DN1_FREQ 0x320278
278#define AUD_DN1_FREQ_SHIFT 0x32027c
279#define AUD_DN1_AFC 0x320280
280#define AUD_DN1_SRC_SEL 0x320284
281#define AUD_DN1_SHFT 0x320288
282#define AUD_DN2_FREQ 0x32028c
283#define AUD_DN2_FREQ_SHIFT 0x320290
284#define AUD_DN2_AFC 0x320294
285#define AUD_DN2_SRC_SEL 0x320298
286#define AUD_DN2_SHFT 0x32029c
287#define AUD_CRDC0_SRC_SEL 0x320300
288#define AUD_CRDC0_SHIFT 0x320304
289#define AUD_CORDIC_SHIFT_0 0x320308
290#define AUD_CRDC1_SRC_SEL 0x32030c
291#define AUD_CRDC1_SHIFT 0x320310
292#define AUD_CORDIC_SHIFT_1 0x320314
293#define AUD_DCOC_0_SRC 0x320320
294#define AUD_DCOC0_SHIFT 0x320324
295#define AUD_DCOC_0_SHIFT_IN0 0x320328
296#define AUD_DCOC_0_SHIFT_IN1 0x32032c
297#define AUD_DCOC_1_SRC 0x320330
298#define AUD_DCOC1_SHIFT 0x320334
299#define AUD_DCOC_1_SHIFT_IN0 0x320338
300#define AUD_DCOC_1_SHIFT_IN1 0x32033c
301#define AUD_DCOC_2_SRC 0x320340
302#define AUD_DCOC2_SHIFT 0x320344
303#define AUD_DCOC_2_SHIFT_IN0 0x320348
304#define AUD_DCOC_2_SHIFT_IN1 0x32034c
305#define AUD_DCOC_PASS_IN 0x320350
306#define AUD_PDET_SRC 0x320370
307#define AUD_PDET_SHIFT 0x320374
308#define AUD_PILOT_BQD_1_K0 0x320380
309#define AUD_PILOT_BQD_1_K1 0x320384
310#define AUD_PILOT_BQD_1_K2 0x320388
311#define AUD_PILOT_BQD_1_K3 0x32038c
312#define AUD_PILOT_BQD_1_K4 0x320390
313#define AUD_PILOT_BQD_2_K0 0x320394
314#define AUD_PILOT_BQD_2_K1 0x320398
315#define AUD_PILOT_BQD_2_K2 0x32039c
316#define AUD_PILOT_BQD_2_K3 0x3203a0
317#define AUD_PILOT_BQD_2_K4 0x3203a4
318#define AUD_THR_FR 0x3203c0
319#define AUD_X_PROG 0x3203c4
320#define AUD_Y_PROG 0x3203c8
321#define AUD_HARMONIC_MULT 0x3203cc
322#define AUD_C1_UP_THR 0x3203d0
323#define AUD_C1_LO_THR 0x3203d4
324#define AUD_C2_UP_THR 0x3203d8
325#define AUD_C2_LO_THR 0x3203dc
326#define AUD_PLL_EN 0x320400
327#define AUD_PLL_SRC 0x320404
328#define AUD_PLL_SHIFT 0x320408
329#define AUD_PLL_IF_SEL 0x32040c
330#define AUD_PLL_IF_SHIFT 0x320410
331#define AUD_BIQUAD_PLL_K0 0x320414
332#define AUD_BIQUAD_PLL_K1 0x320418
333#define AUD_BIQUAD_PLL_K2 0x32041c
334#define AUD_BIQUAD_PLL_K3 0x320420
335#define AUD_BIQUAD_PLL_K4 0x320424
336#define AUD_DEEMPH0_SRC_SEL 0x320440
337#define AUD_DEEMPH0_SHIFT 0x320444
338#define AUD_DEEMPH0_G0 0x320448
339#define AUD_DEEMPH0_A0 0x32044c
340#define AUD_DEEMPH0_B0 0x320450
341#define AUD_DEEMPH0_A1 0x320454
342#define AUD_DEEMPH0_B1 0x320458
343#define AUD_DEEMPH1_SRC_SEL 0x32045c
344#define AUD_DEEMPH1_SHIFT 0x320460
345#define AUD_DEEMPH1_G0 0x320464
346#define AUD_DEEMPH1_A0 0x320468
347#define AUD_DEEMPH1_B0 0x32046c
348#define AUD_DEEMPH1_A1 0x320470
349#define AUD_DEEMPH1_B1 0x320474
350#define AUD_OUT0_SEL 0x320490
351#define AUD_OUT0_SHIFT 0x320494
352#define AUD_OUT1_SEL 0x320498
353#define AUD_OUT1_SHIFT 0x32049c
354#define AUD_RDSI_SEL 0x3204a0
355#define AUD_RDSI_SHIFT 0x3204a4
356#define AUD_RDSQ_SEL 0x3204a8
357#define AUD_RDSQ_SHIFT 0x3204ac
358#define AUD_DBX_IN_GAIN 0x320500
359#define AUD_DBX_WBE_GAIN 0x320504
360#define AUD_DBX_SE_GAIN 0x320508
361#define AUD_DBX_RMS_WBE 0x32050c
362#define AUD_DBX_RMS_SE 0x320510
363#define AUD_DBX_SE_BYPASS 0x320514
364#define AUD_FAWDETCTL 0x320530
365#define AUD_FAWDETWINCTL 0x320534
366#define AUD_DEEMPHGAIN_R 0x320538
367#define AUD_DEEMPHNUMER1_R 0x32053c
368#define AUD_DEEMPHNUMER2_R 0x320540
369#define AUD_DEEMPHDENOM1_R 0x320544
370#define AUD_DEEMPHDENOM2_R 0x320548
371#define AUD_ERRLOGPERIOD_R 0x32054c
372#define AUD_ERRINTRPTTHSHLD1_R 0x320550
373#define AUD_ERRINTRPTTHSHLD2_R 0x320554
374#define AUD_ERRINTRPTTHSHLD3_R 0x320558
375#define AUD_NICAM_STATUS1 0x32055c
376#define AUD_NICAM_STATUS2 0x320560
377#define AUD_ERRLOG1 0x320564
378#define AUD_ERRLOG2 0x320568
379#define AUD_ERRLOG3 0x32056c
380#define AUD_DAC_BYPASS_L 0x320580
381#define AUD_DAC_BYPASS_R 0x320584
382#define AUD_DAC_BYPASS_CTL 0x320588
383#define AUD_CTL 0x32058c
384#define AUD_STATUS 0x320590
385#define AUD_VOL_CTL 0x320594
386#define AUD_BAL_CTL 0x320598
387#define AUD_START_TIMER 0x3205b0
388#define AUD_MODE_CHG_TIMER 0x3205b4
389#define AUD_POLYPH80SCALEFAC 0x3205b8
390#define AUD_DMD_RA_DDS 0x3205bc
391#define AUD_I2S_RA_DDS 0x3205c0
392#define AUD_RATE_THRES_DMD 0x3205d0
393#define AUD_RATE_THRES_I2S 0x3205d4
394#define AUD_RATE_ADJ1 0x3205d8
395#define AUD_RATE_ADJ2 0x3205dc
396#define AUD_RATE_ADJ3 0x3205e0
397#define AUD_RATE_ADJ4 0x3205e4
398#define AUD_RATE_ADJ5 0x3205e8
399#define AUD_APB_IN_RATE_ADJ 0x3205ec
400#define AUD_PHASE_FIX_CTL 0x3205f0
401#define AUD_PLL_PRESCALE 0x320600
402#define AUD_PLL_DDS 0x320604
403#define AUD_PLL_INT 0x320608
404#define AUD_PLL_FRAC 0x32060c
405#define AUD_PLL_JTAG 0x320620
406#define AUD_PLL_SPMP 0x320624
407#define AUD_AFE_12DB_EN 0x320628
408
409// Audio QAM Register Addresses
410#define AUD_PDF_DDS_CNST_BYTE2 0x320d01
411#define AUD_PDF_DDS_CNST_BYTE1 0x320d02
412#define AUD_PDF_DDS_CNST_BYTE0 0x320d03
413#define AUD_PHACC_FREQ_8MSB 0x320d2a
414#define AUD_PHACC_FREQ_8LSB 0x320d2b
415#define AUD_QAM_MODE 0x320d04
416
417
418/* ---------------------------------------------------------------------- */
419/* transport stream registers */
420
421#define MO_TS_DMA 0x330000 // {64}RWp Transport stream downstream
422#define MO_TS_GPCNT 0x33C020 // {16}RO TS general purpose counter
423#define MO_TS_GPCNTRL 0x33C030 // {2}WO TS general purpose control
424#define MO_TS_DMACNTRL 0x33C040 // {6}RW TS DMA control
425#define MO_TS_XFR_STAT 0x33C044 // {1}RO TS transfer status
426#define MO_TS_LNGTH 0x33C048 // {12}RW TS line length
427
428#define TS_HW_SOP_CNTRL 0x33C04C
429#define TS_GEN_CNTRL 0x33C050
430#define TS_BD_PKT_STAT 0x33C054
431#define TS_SOP_STAT 0x33C058
432#define TS_FIFO_OVFL_STAT 0x33C05C
433#define TS_VALERR_CNTRL 0x33C060
434
435
436/* ---------------------------------------------------------------------- */
437/* VIP registers */
438
439#define MO_VIPD_DMA 0x340000 // {64}RWp VIP downstream
440#define MO_VIPU_DMA 0x340008 // {64}RWp VIP upstream
441#define MO_VIPD_GPCNT 0x34C020 // {16}RO VIP down general purpose counter
442#define MO_VIPU_GPCNT 0x34C024 // {16}RO VIP up general purpose counter
443#define MO_VIPD_GPCNTRL 0x34C030 // {2}WO VIP down general purpose control
444#define MO_VIPU_GPCNTRL 0x34C034 // {2}WO VIP up general purpose control
445#define MO_VIP_DMACNTRL 0x34C040 // {6}RW VIP DMA control
446#define MO_VIP_XFR_STAT 0x34C044 // {1}RO VIP transfer status
447#define MO_VIP_CFG 0x340048 // VIP configuration
448#define MO_VIPU_CNTRL 0x34004C // VIP upstream control #1
449#define MO_VIPD_CNTRL 0x340050 // VIP downstream control #2
450#define MO_VIPD_LNGTH 0x340054 // VIP downstream line length
451#define MO_VIP_BRSTLN 0x340058 // VIP burst length
452#define MO_VIP_INTCNTRL 0x34C05C // VIP Interrupt Control
453#define MO_VIP_XFTERM 0x340060 // VIP transfer terminate
454
455
456/* ---------------------------------------------------------------------- */
457/* misc registers */
458
459#define MO_M2M_DMA 0x350000 // {64}RWp Mem2Mem DMA Bfr
460#define MO_GP0_IO 0x350010 // {32}RW* GPIOoutput enablesdata I/O
461#define MO_GP1_IO 0x350014 // {32}RW* GPIOoutput enablesdata I/O
462#define MO_GP2_IO 0x350018 // {32}RW* GPIOoutput enablesdata I/O
463#define MO_GP3_IO 0x35001C // {32}RW* GPIO Mode/Ctrloutput enables
464#define MO_GPIO 0x350020 // {32}RW* GPIO I2C Ctrldata I/O
465#define MO_GPOE 0x350024 // {32}RW GPIO I2C Ctrloutput enables
466#define MO_GP_ISM 0x350028 // {16}WO GPIO Intr Sens/Pol
467
468#define MO_PLL_B 0x35C008 // {32}RW* PLL Control for ASB bus clks
469#define MO_M2M_CNT 0x35C024 // {32}RW Mem2Mem DMA Cnt
470#define MO_M2M_XSUM 0x35C028 // {32}RO M2M XOR-Checksum
471#define MO_CRC 0x35C02C // {16}RW CRC16 init/result
472#define MO_CRC_D 0x35C030 // {32}WO CRC16 new data in
473#define MO_TM_CNT_LDW 0x35C034 // {32}RO Timer : Counter low dword
474#define MO_TM_CNT_UW 0x35C038 // {16}RO Timer : Counter high word
475#define MO_TM_LMT_LDW 0x35C03C // {32}RW Timer : Limit low dword
476#define MO_TM_LMT_UW 0x35C040 // {32}RW Timer : Limit high word
477#define MO_PINMUX_IO 0x35C044 // {8}RW Pin Mux Control
478#define MO_TSTSEL_IO 0x35C048 // {2}RW Pin Mux Control
479#define MO_AFECFG_IO 0x35C04C // AFE configuration reg
480#define MO_DDS_IO 0x35C050 // DDS Increment reg
481#define MO_DDSCFG_IO 0x35C054 // DDS Configuration reg
482#define MO_SAMPLE_IO 0x35C058 // IRIn sample reg
483#define MO_SRST_IO 0x35C05C // Output system reset reg
484
485#define MO_INT1_MSK 0x35C060 // DMA RISC interrupt mask
486#define MO_INT1_STAT 0x35C064 // DMA RISC interrupt status
487#define MO_INT1_MSTAT 0x35C068 // DMA RISC interrupt masked status
488
489
490/* ---------------------------------------------------------------------- */
491/* i2c bus registers */
492
493#define MO_I2C 0x368000 // I2C data/control
494#define MO_I2C_DIV (0xf<<4)
495#define MO_I2C_SYNC (1<<3)
496#define MO_I2C_W3B (1<<2)
497#define MO_I2C_SCL (1<<1)
498#define MO_I2C_SDA (1<<0)
499
500
501/* ---------------------------------------------------------------------- */
502/* general purpose host registers */
503/* FIXME: tyops? s/0x35/0x38/ ?? */
504
505#define MO_GPHSTD_DMA 0x350000 // {64}RWp Host downstream
506#define MO_GPHSTU_DMA 0x350008 // {64}RWp Host upstream
507#define MO_GPHSTU_CNTRL 0x380048 // Host upstream control #1
508#define MO_GPHSTD_CNTRL 0x38004C // Host downstream control #2
509#define MO_GPHSTD_LNGTH 0x380050 // Host downstream line length
510#define MO_GPHST_WSC 0x380054 // Host wait state control
511#define MO_GPHST_XFR 0x380058 // Host transfer control
512#define MO_GPHST_WDTH 0x38005C // Host interface width
513#define MO_GPHST_HDSHK 0x380060 // Host peripheral handshake
514#define MO_GPHST_MUX16 0x380064 // Host muxed 16-bit transfer parameters
515#define MO_GPHST_MODE 0x380068 // Host mode select
516
517#define MO_GPHSTD_GPCNT 0x35C020 // Host down general purpose counter
518#define MO_GPHSTU_GPCNT 0x35C024 // Host up general purpose counter
519#define MO_GPHSTD_GPCNTRL 0x38C030 // Host down general purpose control
520#define MO_GPHSTU_GPCNTRL 0x38C034 // Host up general purpose control
521#define MO_GPHST_DMACNTRL 0x38C040 // Host DMA control
522#define MO_GPHST_XFR_STAT 0x38C044 // Host transfer status
523#define MO_GPHST_SOFT_RST 0x38C06C // Host software reset
524
525
526/* ---------------------------------------------------------------------- */
527/* RISC instructions */
528
529#define RISC_SYNC 0x80000000
530#define RISC_SYNC_ODD 0x80000000
531#define RISC_SYNC_EVEN 0x80000200
532#define RISC_RESYNC 0x80008000
533#define RISC_RESYNC_ODD 0x80008000
534#define RISC_RESYNC_EVEN 0x80008200
535#define RISC_WRITE 0x10000000
536#define RISC_WRITEC 0x50000000
537#define RISC_READ 0x90000000
538#define RISC_READC 0xA0000000
539#define RISC_JUMP 0x70000000
540#define RISC_SKIP 0x20000000
541#define RISC_WRITERM 0xB0000000
542#define RISC_WRITECM 0xC0000000
543#define RISC_WRITECR 0xD0000000
544#define RISC_IMM 0x00000001
545
546#define RISC_SOL 0x08000000
547#define RISC_EOL 0x04000000
548
549#define RISC_IRQ2 0x02000000
550#define RISC_IRQ1 0x01000000
551
552#define RISC_CNT_NONE 0x00000000
553#define RISC_CNT_INC 0x00010000
554#define RISC_CNT_RSVR 0x00020000
555#define RISC_CNT_RESET 0x00030000
556#define RISC_JMP_SRP 0x01
557
558
559/* ---------------------------------------------------------------------- */
560/* various constants */
561
562#define SEL_BTSC 0x01
563#define SEL_EIAJ 0x02
564#define SEL_A2 0x04
565#define SEL_SAP 0x08
566#define SEL_NICAM 0x10
567#define SEL_FMRADIO 0x20
568
569// AUD_CTL
570#define EN_BTSC_FORCE_MONO 0
571#define EN_BTSC_FORCE_STEREO 1
572#define EN_BTSC_FORCE_SAP 2
573#define EN_BTSC_AUTO_STEREO 3
574#define EN_BTSC_AUTO_SAP 4
575
576#define EN_A2_FORCE_MONO1 8
577#define EN_A2_FORCE_MONO2 9
578#define EN_A2_FORCE_STEREO 10
579#define EN_A2_AUTO_MONO2 11
580#define EN_A2_AUTO_STEREO 12
581
582#define EN_EIAJ_FORCE_MONO1 16
583#define EN_EIAJ_FORCE_MONO2 17
584#define EN_EIAJ_FORCE_STEREO 18
585#define EN_EIAJ_AUTO_MONO2 19
586#define EN_EIAJ_AUTO_STEREO 20
587
588#define EN_NICAM_FORCE_MONO1 32
589#define EN_NICAM_FORCE_MONO2 33
590#define EN_NICAM_FORCE_STEREO 34
591#define EN_NICAM_AUTO_MONO2 35
592#define EN_NICAM_AUTO_STEREO 36
593
594#define EN_FMRADIO_FORCE_MONO 24
595#define EN_FMRADIO_FORCE_STEREO 25
596#define EN_FMRADIO_AUTO_STEREO 26
597
598#define EN_NICAM_AUTO_FALLBACK 0x00000040
599#define EN_FMRADIO_EN_RDS 0x00000200
600#define EN_NICAM_TRY_AGAIN_BIT 0x00000400
601#define EN_DAC_ENABLE 0x00001000
602#define EN_I2SOUT_ENABLE 0x00002000
603#define EN_I2SIN_STR2DAC 0x00004000
604#define EN_I2SIN_ENABLE 0x00008000
605
606#if 0
607/* old */
608#define EN_DMTRX_SUMDIFF 0x00000800
609#define EN_DMTRX_SUMR 0x00000880
610#define EN_DMTRX_LR 0x00000900
611#define EN_DMTRX_MONO 0x00000980
612#else
613/* dscaler cvs */
614#define EN_DMTRX_SUMDIFF (0 << 7)
615#define EN_DMTRX_SUMR (1 << 7)
616#define EN_DMTRX_LR (2 << 7)
617#define EN_DMTRX_MONO (3 << 7)
618#define EN_DMTRX_BYPASS (1 << 11)
619#endif
620
621// Video
622#define VID_CAPTURE_CONTROL 0x310180
623
624#define CX23880_CAP_CTL_CAPTURE_VBI_ODD (1<<3)
625#define CX23880_CAP_CTL_CAPTURE_VBI_EVEN (1<<2)
626#define CX23880_CAP_CTL_CAPTURE_ODD (1<<1)
627#define CX23880_CAP_CTL_CAPTURE_EVEN (1<<0)
628
629#define VideoInputMux0 0x0
630#define VideoInputMux1 0x1
631#define VideoInputMux2 0x2
632#define VideoInputMux3 0x3
633#define VideoInputTuner 0x0
634#define VideoInputComposite 0x1
635#define VideoInputSVideo 0x2
636#define VideoInputOther 0x3
637
638#define Xtal0 0x1
639#define Xtal1 0x2
640#define XtalAuto 0x3
641
642#define VideoFormatAuto 0x0
643#define VideoFormatNTSC 0x1
644#define VideoFormatNTSCJapan 0x2
645#define VideoFormatNTSC443 0x3
646#define VideoFormatPAL 0x4
647#define VideoFormatPALB 0x4
648#define VideoFormatPALD 0x4
649#define VideoFormatPALG 0x4
650#define VideoFormatPALH 0x4
651#define VideoFormatPALI 0x4
652#define VideoFormatPALBDGHI 0x4
653#define VideoFormatPALM 0x5
654#define VideoFormatPALN 0x6
655#define VideoFormatPALNC 0x7
656#define VideoFormatPAL60 0x8
657#define VideoFormatSECAM 0x9
658
659#define VideoFormatAuto27MHz 0x10
660#define VideoFormatNTSC27MHz 0x11
661#define VideoFormatNTSCJapan27MHz 0x12
662#define VideoFormatNTSC44327MHz 0x13
663#define VideoFormatPAL27MHz 0x14
664#define VideoFormatPALB27MHz 0x14
665#define VideoFormatPALD27MHz 0x14
666#define VideoFormatPALG27MHz 0x14
667#define VideoFormatPALH27MHz 0x14
668#define VideoFormatPALI27MHz 0x14
669#define VideoFormatPALBDGHI27MHz 0x14
670#define VideoFormatPALM27MHz 0x15
671#define VideoFormatPALN27MHz 0x16
672#define VideoFormatPALNC27MHz 0x17
673#define VideoFormatPAL6027MHz 0x18
674#define VideoFormatSECAM27MHz 0x19
675
676#define NominalUSECAM 0x87
677#define NominalVSECAM 0x85
678#define NominalUNTSC 0xFE
679#define NominalVNTSC 0xB4
680
681#define NominalContrast 0xD8
682
683#define HFilterAutoFormat 0x0
684#define HFilterCIF 0x1
685#define HFilterQCIF 0x2
686#define HFilterICON 0x3
687
688#define VFilter2TapInterpolate 0
689#define VFilter3TapInterpolate 1
690#define VFilter4TapInterpolate 2
691#define VFilter5TapInterpolate 3
692#define VFilter2TapNoInterpolate 4
693#define VFilter3TapNoInterpolate 5
694#define VFilter4TapNoInterpolate 6
695#define VFilter5TapNoInterpolate 7
696
697#define ColorFormatRGB32 0x0000
698#define ColorFormatRGB24 0x0011
699#define ColorFormatRGB16 0x0022
700#define ColorFormatRGB15 0x0033
701#define ColorFormatYUY2 0x0044
702#define ColorFormatBTYUV 0x0055
703#define ColorFormatY8 0x0066
704#define ColorFormatRGB8 0x0077
705#define ColorFormatPL422 0x0088
706#define ColorFormatPL411 0x0099
707#define ColorFormatYUV12 0x00AA
708#define ColorFormatYUV9 0x00BB
709#define ColorFormatRAW 0x00EE
710#define ColorFormatBSWAP 0x0300
711#define ColorFormatWSWAP 0x0c00
712#define ColorFormatEvenMask 0x050f
713#define ColorFormatOddMask 0x0af0
714#define ColorFormatGamma 0x1000
715
716#define Interlaced 0x1
717#define NonInterlaced 0x0
718
719#define FieldEven 0x1
720#define FieldOdd 0x0
721
722#define TGReadWriteMode 0x0
723#define TGEnableMode 0x1
724
725#define DV_CbAlign 0x0
726#define DV_Y0Align 0x1
727#define DV_CrAlign 0x2
728#define DV_Y1Align 0x3
729
730#define DVF_Analog 0x0
731#define DVF_CCIR656 0x1
732#define DVF_ByteStream 0x2
733#define DVF_ExtVSYNC 0x4
734#define DVF_ExtField 0x5
735
736#define CHANNEL_VID_Y 0x1
737#define CHANNEL_VID_U 0x2
738#define CHANNEL_VID_V 0x3
739#define CHANNEL_VID_VBI 0x4
740#define CHANNEL_AUD_DN 0x5
741#define CHANNEL_AUD_UP 0x6
742#define CHANNEL_AUD_RDS_DN 0x7
743#define CHANNEL_MPEG_DN 0x8
744#define CHANNEL_VIP_DN 0x9
745#define CHANNEL_VIP_UP 0xA
746#define CHANNEL_HOST_DN 0xB
747#define CHANNEL_HOST_UP 0xC
748#define CHANNEL_FIRST 0x1
749#define CHANNEL_LAST 0xC
750
751#define GP_COUNT_CONTROL_NONE 0x0
752#define GP_COUNT_CONTROL_INC 0x1
753#define GP_COUNT_CONTROL_RESERVED 0x2
754#define GP_COUNT_CONTROL_RESET 0x3
755
756#define PLL_PRESCALE_BY_2 2
757#define PLL_PRESCALE_BY_3 3
758#define PLL_PRESCALE_BY_4 4
759#define PLL_PRESCALE_BY_5 5
760
761#define HLNotchFilter4xFsc 0
762#define HLNotchFilterSquare 1
763#define HLNotchFilter135NTSC 2
764#define HLNotchFilter135PAL 3
765
766#define NTSC_8x_SUB_CARRIER 28.63636E6
767#define PAL_8x_SUB_CARRIER 35.46895E6
768
769// Default analog settings
770#define DEFAULT_HUE_NTSC 0x00
771#define DEFAULT_BRIGHTNESS_NTSC 0x00
772#define DEFAULT_CONTRAST_NTSC 0x39
773#define DEFAULT_SAT_U_NTSC 0x7F
774#define DEFAULT_SAT_V_NTSC 0x5A
775
776typedef enum
777{
778 SOURCE_TUNER = 0,
779 SOURCE_COMPOSITE,
780 SOURCE_SVIDEO,
781 SOURCE_OTHER1,
782 SOURCE_OTHER2,
783 SOURCE_COMPVIASVIDEO,
784 SOURCE_CCIR656
785} VIDEOSOURCETYPE;
786
787#endif /* _CX88_REG_H_ */
diff --git a/drivers/media/video/cx88/cx88-tvaudio.c b/drivers/media/video/cx88/cx88-tvaudio.c
new file mode 100644
index 00000000000..f2a9475a2fe
--- /dev/null
+++ b/drivers/media/video/cx88/cx88-tvaudio.c
@@ -0,0 +1,1032 @@
1/*
2 $Id: cx88-tvaudio.c,v 1.34 2005/03/07 16:10:51 kraxel Exp $
3
4 cx88x-audio.c - Conexant CX23880/23881 audio downstream driver driver
5
6 (c) 2001 Michael Eskin, Tom Zakrajsek [Windows version]
7 (c) 2002 Yurij Sysoev <yurij@naturesoft.net>
8 (c) 2003 Gerd Knorr <kraxel@bytesex.org>
9
10 -----------------------------------------------------------------------
11
12 Lot of voodoo here. Even the data sheet doesn't help to
13 understand what is going on here, the documentation for the audio
14 part of the cx2388x chip is *very* bad.
15
16 Some of this comes from party done linux driver sources I got from
17 [undocumented].
18
19 Some comes from the dscaler sources, one of the dscaler driver guy works
20 for Conexant ...
21
22 -----------------------------------------------------------------------
23
24 This program is free software; you can redistribute it and/or modify
25 it under the terms of the GNU General Public License as published by
26 the Free Software Foundation; either version 2 of the License, or
27 (at your option) any later version.
28
29 This program is distributed in the hope that it will be useful,
30 but WITHOUT ANY WARRANTY; without even the implied warranty of
31 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32 GNU General Public License for more details.
33
34 You should have received a copy of the GNU General Public License
35 along with this program; if not, write to the Free Software
36 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
37*/
38
39#include <linux/module.h>
40#include <linux/moduleparam.h>
41#include <linux/errno.h>
42#include <linux/kernel.h>
43#include <linux/slab.h>
44#include <linux/mm.h>
45#include <linux/poll.h>
46#include <linux/pci.h>
47#include <linux/signal.h>
48#include <linux/ioport.h>
49#include <linux/sched.h>
50#include <linux/types.h>
51#include <linux/interrupt.h>
52#include <linux/vmalloc.h>
53#include <linux/init.h>
54#include <linux/smp_lock.h>
55#include <linux/delay.h>
56#include <linux/kthread.h>
57
58#include "cx88.h"
59
60static unsigned int audio_debug = 0;
61module_param(audio_debug,int,0644);
62MODULE_PARM_DESC(audio_debug,"enable debug messages [audio]");
63
64#define dprintk(fmt, arg...) if (audio_debug) \
65 printk(KERN_DEBUG "%s/0: " fmt, core->name , ## arg)
66
67/* ----------------------------------------------------------- */
68
69static char *aud_ctl_names[64] =
70{
71 [ EN_BTSC_FORCE_MONO ] = "BTSC_FORCE_MONO",
72 [ EN_BTSC_FORCE_STEREO ] = "BTSC_FORCE_STEREO",
73 [ EN_BTSC_FORCE_SAP ] = "BTSC_FORCE_SAP",
74 [ EN_BTSC_AUTO_STEREO ] = "BTSC_AUTO_STEREO",
75 [ EN_BTSC_AUTO_SAP ] = "BTSC_AUTO_SAP",
76 [ EN_A2_FORCE_MONO1 ] = "A2_FORCE_MONO1",
77 [ EN_A2_FORCE_MONO2 ] = "A2_FORCE_MONO2",
78 [ EN_A2_FORCE_STEREO ] = "A2_FORCE_STEREO",
79 [ EN_A2_AUTO_MONO2 ] = "A2_AUTO_MONO2",
80 [ EN_A2_AUTO_STEREO ] = "A2_AUTO_STEREO",
81 [ EN_EIAJ_FORCE_MONO1 ] = "EIAJ_FORCE_MONO1",
82 [ EN_EIAJ_FORCE_MONO2 ] = "EIAJ_FORCE_MONO2",
83 [ EN_EIAJ_FORCE_STEREO ] = "EIAJ_FORCE_STEREO",
84 [ EN_EIAJ_AUTO_MONO2 ] = "EIAJ_AUTO_MONO2",
85 [ EN_EIAJ_AUTO_STEREO ] = "EIAJ_AUTO_STEREO",
86 [ EN_NICAM_FORCE_MONO1 ] = "NICAM_FORCE_MONO1",
87 [ EN_NICAM_FORCE_MONO2 ] = "NICAM_FORCE_MONO2",
88 [ EN_NICAM_FORCE_STEREO ] = "NICAM_FORCE_STEREO",
89 [ EN_NICAM_AUTO_MONO2 ] = "NICAM_AUTO_MONO2",
90 [ EN_NICAM_AUTO_STEREO ] = "NICAM_AUTO_STEREO",
91 [ EN_FMRADIO_FORCE_MONO ] = "FMRADIO_FORCE_MONO",
92 [ EN_FMRADIO_FORCE_STEREO ] = "FMRADIO_FORCE_STEREO",
93 [ EN_FMRADIO_AUTO_STEREO ] = "FMRADIO_AUTO_STEREO",
94};
95
96struct rlist {
97 u32 reg;
98 u32 val;
99};
100
101static void set_audio_registers(struct cx88_core *core,
102 const struct rlist *l)
103{
104 int i;
105
106 for (i = 0; l[i].reg; i++) {
107 switch (l[i].reg) {
108 case AUD_PDF_DDS_CNST_BYTE2:
109 case AUD_PDF_DDS_CNST_BYTE1:
110 case AUD_PDF_DDS_CNST_BYTE0:
111 case AUD_QAM_MODE:
112 case AUD_PHACC_FREQ_8MSB:
113 case AUD_PHACC_FREQ_8LSB:
114 cx_writeb(l[i].reg, l[i].val);
115 break;
116 default:
117 cx_write(l[i].reg, l[i].val);
118 break;
119 }
120 }
121}
122
123static void set_audio_start(struct cx88_core *core,
124 u32 mode, u32 ctl)
125{
126 // mute
127 cx_write(AUD_VOL_CTL, (1 << 6));
128
129 // increase level of input by 12dB
130 cx_write(AUD_AFE_12DB_EN, 0x0001);
131
132 // start programming
133 cx_write(AUD_CTL, 0x0000);
134 cx_write(AUD_INIT, mode);
135 cx_write(AUD_INIT_LD, 0x0001);
136 cx_write(AUD_SOFT_RESET, 0x0001);
137
138 cx_write(AUD_CTL, ctl);
139}
140
141static void set_audio_finish(struct cx88_core *core)
142{
143 u32 volume;
144
145 if (cx88_boards[core->board].blackbird) {
146 // 'pass-thru mode': this enables the i2s output to the mpeg encoder
147 cx_set(AUD_CTL, 0x2000);
148 cx_write(AUD_I2SOUTPUTCNTL, 1);
149 //cx_write(AUD_APB_IN_RATE_ADJ, 0);
150 }
151
152 // finish programming
153 cx_write(AUD_SOFT_RESET, 0x0000);
154
155 // start audio processing
156 cx_set(AUD_CTL, EN_DAC_ENABLE);
157
158 // unmute
159 volume = cx_sread(SHADOW_AUD_VOL_CTL);
160 cx_swrite(SHADOW_AUD_VOL_CTL, AUD_VOL_CTL, volume);
161}
162
163/* ----------------------------------------------------------- */
164
165static void set_audio_standard_BTSC(struct cx88_core *core, unsigned int sap)
166{
167 static const struct rlist btsc[] = {
168 /* from dscaler */
169 { AUD_OUT1_SEL, 0x00000013 },
170 { AUD_OUT1_SHIFT, 0x00000000 },
171 { AUD_POLY0_DDS_CONSTANT, 0x0012010c },
172 { AUD_DMD_RA_DDS, 0x00c3e7aa },
173 { AUD_DBX_IN_GAIN, 0x00004734 },
174 { AUD_DBX_WBE_GAIN, 0x00004640 },
175 { AUD_DBX_SE_GAIN, 0x00008d31 },
176 { AUD_DCOC_0_SRC, 0x0000001a },
177 { AUD_IIR1_4_SEL, 0x00000021 },
178 { AUD_DCOC_PASS_IN, 0x00000003 },
179 { AUD_DCOC_0_SHIFT_IN0, 0x0000000a },
180 { AUD_DCOC_0_SHIFT_IN1, 0x00000008 },
181 { AUD_DCOC_1_SHIFT_IN0, 0x0000000a },
182 { AUD_DCOC_1_SHIFT_IN1, 0x00000008 },
183 { AUD_DN0_FREQ, 0x0000283b },
184 { AUD_DN2_SRC_SEL, 0x00000008 },
185 { AUD_DN2_FREQ, 0x00003000 },
186 { AUD_DN2_AFC, 0x00000002 },
187 { AUD_DN2_SHFT, 0x00000000 },
188 { AUD_IIR2_2_SEL, 0x00000020 },
189 { AUD_IIR2_2_SHIFT, 0x00000000 },
190 { AUD_IIR2_3_SEL, 0x0000001f },
191 { AUD_IIR2_3_SHIFT, 0x00000000 },
192 { AUD_CRDC1_SRC_SEL, 0x000003ce },
193 { AUD_CRDC1_SHIFT, 0x00000000 },
194 { AUD_CORDIC_SHIFT_1, 0x00000007 },
195 { AUD_DCOC_1_SRC, 0x0000001b },
196 { AUD_DCOC1_SHIFT, 0x00000000 },
197 { AUD_RDSI_SEL, 0x00000008 },
198 { AUD_RDSQ_SEL, 0x00000008 },
199 { AUD_RDSI_SHIFT, 0x00000000 },
200 { AUD_RDSQ_SHIFT, 0x00000000 },
201 { AUD_POLYPH80SCALEFAC, 0x00000003 },
202 { /* end of list */ },
203 };
204 static const struct rlist btsc_sap[] = {
205 { AUD_DBX_IN_GAIN, 0x00007200 },
206 { AUD_DBX_WBE_GAIN, 0x00006200 },
207 { AUD_DBX_SE_GAIN, 0x00006200 },
208 { AUD_IIR1_1_SEL, 0x00000000 },
209 { AUD_IIR1_3_SEL, 0x00000001 },
210 { AUD_DN1_SRC_SEL, 0x00000007 },
211 { AUD_IIR1_4_SHIFT, 0x00000006 },
212 { AUD_IIR2_1_SHIFT, 0x00000000 },
213 { AUD_IIR2_2_SHIFT, 0x00000000 },
214 { AUD_IIR3_0_SHIFT, 0x00000000 },
215 { AUD_IIR3_1_SHIFT, 0x00000000 },
216 { AUD_IIR3_0_SEL, 0x0000000d },
217 { AUD_IIR3_1_SEL, 0x0000000e },
218 { AUD_DEEMPH1_SRC_SEL, 0x00000014 },
219 { AUD_DEEMPH1_SHIFT, 0x00000000 },
220 { AUD_DEEMPH1_G0, 0x00004000 },
221 { AUD_DEEMPH1_A0, 0x00000000 },
222 { AUD_DEEMPH1_B0, 0x00000000 },
223 { AUD_DEEMPH1_A1, 0x00000000 },
224 { AUD_DEEMPH1_B1, 0x00000000 },
225 { AUD_OUT0_SEL, 0x0000003f },
226 { AUD_OUT1_SEL, 0x0000003f },
227 { AUD_DN1_AFC, 0x00000002 },
228 { AUD_DCOC_0_SHIFT_IN0, 0x0000000a },
229 { AUD_DCOC_0_SHIFT_IN1, 0x00000008 },
230 { AUD_DCOC_1_SHIFT_IN0, 0x0000000a },
231 { AUD_DCOC_1_SHIFT_IN1, 0x00000008 },
232 { AUD_IIR1_0_SEL, 0x0000001d },
233 { AUD_IIR1_2_SEL, 0x0000001e },
234 { AUD_IIR2_1_SEL, 0x00000002 },
235 { AUD_IIR2_2_SEL, 0x00000004 },
236 { AUD_IIR3_2_SEL, 0x0000000f },
237 { AUD_DCOC2_SHIFT, 0x00000001 },
238 { AUD_IIR3_2_SHIFT, 0x00000001 },
239 { AUD_DEEMPH0_SRC_SEL, 0x00000014 },
240 { AUD_CORDIC_SHIFT_1, 0x00000006 },
241 { AUD_POLY0_DDS_CONSTANT, 0x000e4db2 },
242 { AUD_DMD_RA_DDS, 0x00f696e6 },
243 { AUD_IIR2_3_SEL, 0x00000025 },
244 { AUD_IIR1_4_SEL, 0x00000021 },
245 { AUD_DN1_FREQ, 0x0000c965 },
246 { AUD_DCOC_PASS_IN, 0x00000003 },
247 { AUD_DCOC_0_SRC, 0x0000001a },
248 { AUD_DCOC_1_SRC, 0x0000001b },
249 { AUD_DCOC1_SHIFT, 0x00000000 },
250 { AUD_RDSI_SEL, 0x00000009 },
251 { AUD_RDSQ_SEL, 0x00000009 },
252 { AUD_RDSI_SHIFT, 0x00000000 },
253 { AUD_RDSQ_SHIFT, 0x00000000 },
254 { AUD_POLYPH80SCALEFAC, 0x00000003 },
255 { /* end of list */ },
256 };
257
258 // dscaler: exactly taken from driver,
259 // dscaler: don't know why to set EN_FMRADIO_EN_RDS
260 if (sap) {
261 dprintk("%s SAP (status: unknown)\n",__FUNCTION__);
262 set_audio_start(core, 0x0001,
263 EN_FMRADIO_EN_RDS | EN_BTSC_FORCE_SAP);
264 set_audio_registers(core, btsc_sap);
265 } else {
266 dprintk("%s (status: known-good)\n",__FUNCTION__);
267 set_audio_start(core, 0x0001,
268 EN_FMRADIO_EN_RDS | EN_BTSC_AUTO_STEREO);
269 set_audio_registers(core, btsc);
270 }
271 set_audio_finish(core);
272}
273
274#if 0
275static void set_audio_standard_NICAM(struct cx88_core *core)
276{
277 static const struct rlist nicam_common[] = {
278 /* from dscaler */
279 { AUD_RATE_ADJ1, 0x00000010 },
280 { AUD_RATE_ADJ2, 0x00000040 },
281 { AUD_RATE_ADJ3, 0x00000100 },
282 { AUD_RATE_ADJ4, 0x00000400 },
283 { AUD_RATE_ADJ5, 0x00001000 },
284 // { AUD_DMD_RA_DDS, 0x00c0d5ce },
285
286 // Deemphasis 1:
287 { AUD_DEEMPHGAIN_R, 0x000023c2 },
288 { AUD_DEEMPHNUMER1_R, 0x0002a7bc },
289 { AUD_DEEMPHNUMER2_R, 0x0003023e },
290 { AUD_DEEMPHDENOM1_R, 0x0000f3d0 },
291 { AUD_DEEMPHDENOM2_R, 0x00000000 },
292
293#if 0
294 // Deemphasis 2: (other tv norm?)
295 { AUD_DEEMPHGAIN_R, 0x0000c600 },
296 { AUD_DEEMPHNUMER1_R, 0x00066738 },
297 { AUD_DEEMPHNUMER2_R, 0x00066739 },
298 { AUD_DEEMPHDENOM1_R, 0x0001e88c },
299 { AUD_DEEMPHDENOM2_R, 0x0001e88c },
300#endif
301
302 { AUD_DEEMPHDENOM2_R, 0x00000000 },
303 { AUD_ERRLOGPERIOD_R, 0x00000fff },
304 { AUD_ERRINTRPTTHSHLD1_R, 0x000003ff },
305 { AUD_ERRINTRPTTHSHLD2_R, 0x000000ff },
306 { AUD_ERRINTRPTTHSHLD3_R, 0x0000003f },
307 { AUD_POLYPH80SCALEFAC, 0x00000003 },
308
309 // setup QAM registers
310 { AUD_PDF_DDS_CNST_BYTE2, 0x06 },
311 { AUD_PDF_DDS_CNST_BYTE1, 0x82 },
312 { AUD_PDF_DDS_CNST_BYTE0, 0x16 },
313 { AUD_QAM_MODE, 0x05 },
314
315 { /* end of list */ },
316 };
317 static const struct rlist nicam_pal_i[] = {
318 { AUD_PDF_DDS_CNST_BYTE0, 0x12 },
319 { AUD_PHACC_FREQ_8MSB, 0x3a },
320 { AUD_PHACC_FREQ_8LSB, 0x93 },
321
322 { /* end of list */ },
323 };
324 static const struct rlist nicam_default[] = {
325 { AUD_PDF_DDS_CNST_BYTE0, 0x16 },
326 { AUD_PHACC_FREQ_8MSB, 0x34 },
327 { AUD_PHACC_FREQ_8LSB, 0x4c },
328
329 { /* end of list */ },
330 };
331
332 set_audio_start(core, 0x0010,
333 EN_DMTRX_LR | EN_DMTRX_BYPASS | EN_NICAM_AUTO_STEREO);
334 set_audio_registers(core, nicam_common);
335 switch (core->tvaudio) {
336 case WW_NICAM_I:
337 dprintk("%s PAL-I NICAM (status: unknown)\n",__FUNCTION__);
338 set_audio_registers(core, nicam_pal_i);
339 break;
340 case WW_NICAM_BGDKL:
341 dprintk("%s PAL-BGDK NICAM (status: unknown)\n",__FUNCTION__);
342 set_audio_registers(core, nicam_default);
343 break;
344 };
345 set_audio_finish(core);
346}
347#endif
348
349static void set_audio_standard_NICAM_L(struct cx88_core *core, int stereo)
350{
351 /* This is probably weird..
352 * Let's operate and find out. */
353
354 static const struct rlist nicam_l_mono[] = {
355 { AUD_ERRLOGPERIOD_R, 0x00000064 },
356 { AUD_ERRINTRPTTHSHLD1_R, 0x00000FFF },
357 { AUD_ERRINTRPTTHSHLD2_R, 0x0000001F },
358 { AUD_ERRINTRPTTHSHLD3_R, 0x0000000F },
359
360 { AUD_PDF_DDS_CNST_BYTE2, 0x48 },
361 { AUD_PDF_DDS_CNST_BYTE1, 0x3D },
362 { AUD_QAM_MODE, 0x00 },
363 { AUD_PDF_DDS_CNST_BYTE0, 0xf5 },
364 { AUD_PHACC_FREQ_8MSB, 0x3a },
365 { AUD_PHACC_FREQ_8LSB, 0x4a },
366
367 { AUD_DEEMPHGAIN_R, 0x6680 },
368 { AUD_DEEMPHNUMER1_R, 0x353DE },
369 { AUD_DEEMPHNUMER2_R, 0x1B1 },
370 { AUD_DEEMPHDENOM1_R, 0x0F3D0 },
371 { AUD_DEEMPHDENOM2_R, 0x0 },
372 { AUD_FM_MODE_ENABLE, 0x7 },
373 { AUD_POLYPH80SCALEFAC, 0x3 },
374 { AUD_AFE_12DB_EN, 0x1 },
375 { AAGC_GAIN, 0x0 },
376 { AAGC_HYST, 0x18 },
377 { AAGC_DEF, 0x20 },
378 { AUD_DN0_FREQ, 0x0 },
379 { AUD_POLY0_DDS_CONSTANT, 0x0E4DB2 },
380 { AUD_DCOC_0_SRC, 0x21 },
381 { AUD_IIR1_0_SEL, 0x0 },
382 { AUD_IIR1_0_SHIFT, 0x7 },
383 { AUD_IIR1_1_SEL, 0x2 },
384 { AUD_IIR1_1_SHIFT, 0x0 },
385 { AUD_DCOC_1_SRC, 0x3 },
386 { AUD_DCOC1_SHIFT, 0x0 },
387 { AUD_DCOC_PASS_IN, 0x0 },
388 { AUD_IIR1_2_SEL, 0x23 },
389 { AUD_IIR1_2_SHIFT, 0x0 },
390 { AUD_IIR1_3_SEL, 0x4 },
391 { AUD_IIR1_3_SHIFT, 0x7 },
392 { AUD_IIR1_4_SEL, 0x5 },
393 { AUD_IIR1_4_SHIFT, 0x7 },
394 { AUD_IIR3_0_SEL, 0x7 },
395 { AUD_IIR3_0_SHIFT, 0x0 },
396 { AUD_DEEMPH0_SRC_SEL, 0x11 },
397 { AUD_DEEMPH0_SHIFT, 0x0 },
398 { AUD_DEEMPH0_G0, 0x7000 },
399 { AUD_DEEMPH0_A0, 0x0 },
400 { AUD_DEEMPH0_B0, 0x0 },
401 { AUD_DEEMPH0_A1, 0x0 },
402 { AUD_DEEMPH0_B1, 0x0 },
403 { AUD_DEEMPH1_SRC_SEL, 0x11 },
404 { AUD_DEEMPH1_SHIFT, 0x0 },
405 { AUD_DEEMPH1_G0, 0x7000 },
406 { AUD_DEEMPH1_A0, 0x0 },
407 { AUD_DEEMPH1_B0, 0x0 },
408 { AUD_DEEMPH1_A1, 0x0 },
409 { AUD_DEEMPH1_B1, 0x0 },
410 { AUD_OUT0_SEL, 0x3F },
411 { AUD_OUT1_SEL, 0x3F },
412 { AUD_DMD_RA_DDS, 0x0F5C285 },
413 { AUD_PLL_INT, 0x1E },
414 { AUD_PLL_DDS, 0x0 },
415 { AUD_PLL_FRAC, 0x0E542 },
416
417 // setup QAM registers
418 { AUD_RATE_ADJ1, 0x00000100 },
419 { AUD_RATE_ADJ2, 0x00000200 },
420 { AUD_RATE_ADJ3, 0x00000300 },
421 { AUD_RATE_ADJ4, 0x00000400 },
422 { AUD_RATE_ADJ5, 0x00000500 },
423 { AUD_RATE_THRES_DMD, 0x000000C0 },
424 { /* end of list */ },
425 };
426
427 static const struct rlist nicam_l[] = {
428 // setup QAM registers
429 { AUD_RATE_ADJ1, 0x00000060 },
430 { AUD_RATE_ADJ2, 0x000000F9 },
431 { AUD_RATE_ADJ3, 0x000001CC },
432 { AUD_RATE_ADJ4, 0x000002B3 },
433 { AUD_RATE_ADJ5, 0x00000726 },
434 { AUD_DEEMPHDENOM1_R, 0x0000F3D0 },
435 { AUD_DEEMPHDENOM2_R, 0x00000000 },
436 { AUD_ERRLOGPERIOD_R, 0x00000064 },
437 { AUD_ERRINTRPTTHSHLD1_R, 0x00000FFF },
438 { AUD_ERRINTRPTTHSHLD2_R, 0x0000001F },
439 { AUD_ERRINTRPTTHSHLD3_R, 0x0000000F },
440 { AUD_POLYPH80SCALEFAC, 0x00000003 },
441 { AUD_DMD_RA_DDS, 0x00C00000 },
442 { AUD_PLL_INT, 0x0000001E },
443 { AUD_PLL_DDS, 0x00000000 },
444 { AUD_PLL_FRAC, 0x0000E542 },
445 { AUD_START_TIMER, 0x00000000 },
446 { AUD_DEEMPHNUMER1_R, 0x000353DE },
447 { AUD_DEEMPHNUMER2_R, 0x000001B1 },
448 { AUD_PDF_DDS_CNST_BYTE2, 0x06 },
449 { AUD_PDF_DDS_CNST_BYTE1, 0x82 },
450 { AUD_QAM_MODE, 0x05 },
451 { AUD_PDF_DDS_CNST_BYTE0, 0x12 },
452 { AUD_PHACC_FREQ_8MSB, 0x34 },
453 { AUD_PHACC_FREQ_8LSB, 0x4C },
454 { AUD_DEEMPHGAIN_R, 0x00006680 },
455 { AUD_RATE_THRES_DMD, 0x000000C0 },
456 { /* end of list */ },
457 } ;
458 dprintk("%s (status: devel), stereo : %d\n",__FUNCTION__,stereo);
459
460 if (!stereo) {
461 /* AM mono sound */
462 set_audio_start(core, 0x0004,
463 0x100c /* FIXME again */);
464 set_audio_registers(core, nicam_l_mono);
465 } else {
466 set_audio_start(core, 0x0010,
467 0x1924 /* FIXME again */);
468 set_audio_registers(core, nicam_l);
469 }
470 set_audio_finish(core);
471
472}
473
474static void set_audio_standard_PAL_I(struct cx88_core *core, int stereo)
475{
476 static const struct rlist pal_i_fm_mono[] = {
477 {AUD_ERRLOGPERIOD_R, 0x00000064},
478 {AUD_ERRINTRPTTHSHLD1_R, 0x00000fff},
479 {AUD_ERRINTRPTTHSHLD2_R, 0x0000001f},
480 {AUD_ERRINTRPTTHSHLD3_R, 0x0000000f},
481 {AUD_PDF_DDS_CNST_BYTE2, 0x06},
482 {AUD_PDF_DDS_CNST_BYTE1, 0x82},
483 {AUD_PDF_DDS_CNST_BYTE0, 0x12},
484 {AUD_QAM_MODE, 0x05},
485 {AUD_PHACC_FREQ_8MSB, 0x3a},
486 {AUD_PHACC_FREQ_8LSB, 0x93},
487 {AUD_DMD_RA_DDS, 0x002a4f2f},
488 {AUD_PLL_INT, 0x0000001e},
489 {AUD_PLL_DDS, 0x00000004},
490 {AUD_PLL_FRAC, 0x0000e542},
491 {AUD_RATE_ADJ1, 0x00000100},
492 {AUD_RATE_ADJ2, 0x00000200},
493 {AUD_RATE_ADJ3, 0x00000300},
494 {AUD_RATE_ADJ4, 0x00000400},
495 {AUD_RATE_ADJ5, 0x00000500},
496 {AUD_THR_FR, 0x00000000},
497 {AUD_PILOT_BQD_1_K0, 0x0000755b},
498 {AUD_PILOT_BQD_1_K1, 0x00551340},
499 {AUD_PILOT_BQD_1_K2, 0x006d30be},
500 {AUD_PILOT_BQD_1_K3, 0xffd394af},
501 {AUD_PILOT_BQD_1_K4, 0x00400000},
502 {AUD_PILOT_BQD_2_K0, 0x00040000},
503 {AUD_PILOT_BQD_2_K1, 0x002a4841},
504 {AUD_PILOT_BQD_2_K2, 0x00400000},
505 {AUD_PILOT_BQD_2_K3, 0x00000000},
506 {AUD_PILOT_BQD_2_K4, 0x00000000},
507 {AUD_MODE_CHG_TIMER, 0x00000060},
508 {AUD_AFE_12DB_EN, 0x00000001},
509 {AAGC_HYST, 0x0000000a},
510 {AUD_CORDIC_SHIFT_0, 0x00000007},
511 {AUD_CORDIC_SHIFT_1, 0x00000007},
512 {AUD_C1_UP_THR, 0x00007000},
513 {AUD_C1_LO_THR, 0x00005400},
514 {AUD_C2_UP_THR, 0x00005400},
515 {AUD_C2_LO_THR, 0x00003000},
516 {AUD_DCOC_0_SRC, 0x0000001a},
517 {AUD_DCOC0_SHIFT, 0x00000000},
518 {AUD_DCOC_0_SHIFT_IN0, 0x0000000a},
519 {AUD_DCOC_0_SHIFT_IN1, 0x00000008},
520 {AUD_DCOC_PASS_IN, 0x00000003},
521 {AUD_IIR3_0_SEL, 0x00000021},
522 {AUD_DN2_AFC, 0x00000002},
523 {AUD_DCOC_1_SRC, 0x0000001b},
524 {AUD_DCOC1_SHIFT, 0x00000000},
525 {AUD_DCOC_1_SHIFT_IN0, 0x0000000a},
526 {AUD_DCOC_1_SHIFT_IN1, 0x00000008},
527 {AUD_IIR3_1_SEL, 0x00000023},
528 {AUD_DN0_FREQ, 0x000035a3},
529 {AUD_DN2_FREQ, 0x000029c7},
530 {AUD_CRDC0_SRC_SEL, 0x00000511},
531 {AUD_IIR1_0_SEL, 0x00000001},
532 {AUD_IIR1_1_SEL, 0x00000000},
533 {AUD_IIR3_2_SEL, 0x00000003},
534 {AUD_IIR3_2_SHIFT, 0x00000000},
535 {AUD_IIR3_0_SEL, 0x00000002},
536 {AUD_IIR2_0_SEL, 0x00000021},
537 {AUD_IIR2_0_SHIFT, 0x00000002},
538 {AUD_DEEMPH0_SRC_SEL, 0x0000000b},
539 {AUD_DEEMPH1_SRC_SEL, 0x0000000b},
540 {AUD_POLYPH80SCALEFAC, 0x00000001},
541 {AUD_START_TIMER, 0x00000000},
542 { /* end of list */ },
543 };
544
545 static const struct rlist pal_i_nicam[] = {
546 { AUD_RATE_ADJ1, 0x00000010 },
547 { AUD_RATE_ADJ2, 0x00000040 },
548 { AUD_RATE_ADJ3, 0x00000100 },
549 { AUD_RATE_ADJ4, 0x00000400 },
550 { AUD_RATE_ADJ5, 0x00001000 },
551 // { AUD_DMD_RA_DDS, 0x00c0d5ce },
552 { AUD_DEEMPHGAIN_R, 0x000023c2 },
553 { AUD_DEEMPHNUMER1_R, 0x0002a7bc },
554 { AUD_DEEMPHNUMER2_R, 0x0003023e },
555 { AUD_DEEMPHDENOM1_R, 0x0000f3d0 },
556 { AUD_DEEMPHDENOM2_R, 0x00000000 },
557 { AUD_DEEMPHDENOM2_R, 0x00000000 },
558 { AUD_ERRLOGPERIOD_R, 0x00000fff },
559 { AUD_ERRINTRPTTHSHLD1_R, 0x000003ff },
560 { AUD_ERRINTRPTTHSHLD2_R, 0x000000ff },
561 { AUD_ERRINTRPTTHSHLD3_R, 0x0000003f },
562 { AUD_POLYPH80SCALEFAC, 0x00000003 },
563 { AUD_PDF_DDS_CNST_BYTE2, 0x06 },
564 { AUD_PDF_DDS_CNST_BYTE1, 0x82 },
565 { AUD_PDF_DDS_CNST_BYTE0, 0x16 },
566 { AUD_QAM_MODE, 0x05 },
567 { AUD_PDF_DDS_CNST_BYTE0, 0x12 },
568 { AUD_PHACC_FREQ_8MSB, 0x3a },
569 { AUD_PHACC_FREQ_8LSB, 0x93 },
570 { /* end of list */ },
571 };
572
573 dprintk("%s (status: devel), stereo : %d\n",__FUNCTION__,stereo);
574
575 if (!stereo) {
576 // FM mono
577 set_audio_start(core, 0x0004, EN_DMTRX_SUMDIFF | EN_A2_FORCE_MONO1);
578 set_audio_registers(core, pal_i_fm_mono);
579 } else {
580 // Nicam Stereo
581 set_audio_start(core, 0x0010, EN_DMTRX_LR | EN_DMTRX_BYPASS | EN_NICAM_AUTO_STEREO);
582 set_audio_registers(core, pal_i_nicam);
583 }
584 set_audio_finish(core);
585}
586
587static void set_audio_standard_A2(struct cx88_core *core)
588{
589 /* from dscaler cvs */
590 static const struct rlist a2_common[] = {
591 { AUD_PDF_DDS_CNST_BYTE2, 0x06 },
592 { AUD_PDF_DDS_CNST_BYTE1, 0x82 },
593 { AUD_PDF_DDS_CNST_BYTE0, 0x12 },
594 { AUD_QAM_MODE, 0x05 },
595 { AUD_PHACC_FREQ_8MSB, 0x34 },
596 { AUD_PHACC_FREQ_8LSB, 0x4c },
597
598 { AUD_RATE_ADJ1, 0x00001000 },
599 { AUD_RATE_ADJ2, 0x00002000 },
600 { AUD_RATE_ADJ3, 0x00003000 },
601 { AUD_RATE_ADJ4, 0x00004000 },
602 { AUD_RATE_ADJ5, 0x00005000 },
603 { AUD_THR_FR, 0x00000000 },
604 { AAGC_HYST, 0x0000001a },
605 { AUD_PILOT_BQD_1_K0, 0x0000755b },
606 { AUD_PILOT_BQD_1_K1, 0x00551340 },
607 { AUD_PILOT_BQD_1_K2, 0x006d30be },
608 { AUD_PILOT_BQD_1_K3, 0xffd394af },
609 { AUD_PILOT_BQD_1_K4, 0x00400000 },
610 { AUD_PILOT_BQD_2_K0, 0x00040000 },
611 { AUD_PILOT_BQD_2_K1, 0x002a4841 },
612 { AUD_PILOT_BQD_2_K2, 0x00400000 },
613 { AUD_PILOT_BQD_2_K3, 0x00000000 },
614 { AUD_PILOT_BQD_2_K4, 0x00000000 },
615 { AUD_MODE_CHG_TIMER, 0x00000040 },
616 { AUD_START_TIMER, 0x00000200 },
617 { AUD_AFE_12DB_EN, 0x00000000 },
618 { AUD_CORDIC_SHIFT_0, 0x00000007 },
619 { AUD_CORDIC_SHIFT_1, 0x00000007 },
620 { AUD_DEEMPH0_G0, 0x00000380 },
621 { AUD_DEEMPH1_G0, 0x00000380 },
622 { AUD_DCOC_0_SRC, 0x0000001a },
623 { AUD_DCOC0_SHIFT, 0x00000000 },
624 { AUD_DCOC_0_SHIFT_IN0, 0x0000000a },
625 { AUD_DCOC_0_SHIFT_IN1, 0x00000008 },
626 { AUD_DCOC_PASS_IN, 0x00000003 },
627 { AUD_IIR3_0_SEL, 0x00000021 },
628 { AUD_DN2_AFC, 0x00000002 },
629 { AUD_DCOC_1_SRC, 0x0000001b },
630 { AUD_DCOC1_SHIFT, 0x00000000 },
631 { AUD_DCOC_1_SHIFT_IN0, 0x0000000a },
632 { AUD_DCOC_1_SHIFT_IN1, 0x00000008 },
633 { AUD_IIR3_1_SEL, 0x00000023 },
634 { AUD_RDSI_SEL, 0x00000017 },
635 { AUD_RDSI_SHIFT, 0x00000000 },
636 { AUD_RDSQ_SEL, 0x00000017 },
637 { AUD_RDSQ_SHIFT, 0x00000000 },
638 { AUD_POLYPH80SCALEFAC, 0x00000001 },
639
640 { /* end of list */ },
641 };
642
643 static const struct rlist a2_table1[] = {
644 // PAL-BG
645 { AUD_DMD_RA_DDS, 0x002a73bd },
646 { AUD_C1_UP_THR, 0x00007000 },
647 { AUD_C1_LO_THR, 0x00005400 },
648 { AUD_C2_UP_THR, 0x00005400 },
649 { AUD_C2_LO_THR, 0x00003000 },
650 { /* end of list */ },
651 };
652 static const struct rlist a2_table2[] = {
653 // PAL-DK
654 { AUD_DMD_RA_DDS, 0x002a73bd },
655 { AUD_C1_UP_THR, 0x00007000 },
656 { AUD_C1_LO_THR, 0x00005400 },
657 { AUD_C2_UP_THR, 0x00005400 },
658 { AUD_C2_LO_THR, 0x00003000 },
659 { AUD_DN0_FREQ, 0x00003a1c },
660 { AUD_DN2_FREQ, 0x0000d2e0 },
661 { /* end of list */ },
662 };
663 static const struct rlist a2_table3[] = {
664 // unknown, probably NTSC-M
665 { AUD_DMD_RA_DDS, 0x002a2873 },
666 { AUD_C1_UP_THR, 0x00003c00 },
667 { AUD_C1_LO_THR, 0x00003000 },
668 { AUD_C2_UP_THR, 0x00006000 },
669 { AUD_C2_LO_THR, 0x00003c00 },
670 { AUD_DN0_FREQ, 0x00002836 },
671 { AUD_DN1_FREQ, 0x00003418 },
672 { AUD_DN2_FREQ, 0x000029c7 },
673 { AUD_POLY0_DDS_CONSTANT, 0x000a7540 },
674 { /* end of list */ },
675 };
676
677 set_audio_start(core, 0x0004, EN_DMTRX_SUMDIFF | EN_A2_AUTO_STEREO);
678 set_audio_registers(core, a2_common);
679 switch (core->tvaudio) {
680 case WW_A2_BG:
681 dprintk("%s PAL-BG A2 (status: known-good)\n",__FUNCTION__);
682 set_audio_registers(core, a2_table1);
683 break;
684 case WW_A2_DK:
685 dprintk("%s PAL-DK A2 (status: known-good)\n",__FUNCTION__);
686 set_audio_registers(core, a2_table2);
687 break;
688 case WW_A2_M:
689 dprintk("%s NTSC-M A2 (status: unknown)\n",__FUNCTION__);
690 set_audio_registers(core, a2_table3);
691 break;
692 };
693 set_audio_finish(core);
694}
695
696static void set_audio_standard_EIAJ(struct cx88_core *core)
697{
698 static const struct rlist eiaj[] = {
699 /* TODO: eiaj register settings are not there yet ... */
700
701 { /* end of list */ },
702 };
703 dprintk("%s (status: unknown)\n",__FUNCTION__);
704
705 set_audio_start(core, 0x0002, EN_EIAJ_AUTO_STEREO);
706 set_audio_registers(core, eiaj);
707 set_audio_finish(core);
708}
709
710static void set_audio_standard_FM(struct cx88_core *core)
711{
712#if 0 /* FIXME */
713 switch (dev->audio_properties.FM_deemphasis)
714 {
715 case WW_FM_DEEMPH_50:
716 //Set De-emphasis filter coefficients for 50 usec
717 cx_write(AUD_DEEMPH0_G0, 0x0C45);
718 cx_write(AUD_DEEMPH0_A0, 0x6262);
719 cx_write(AUD_DEEMPH0_B0, 0x1C29);
720 cx_write(AUD_DEEMPH0_A1, 0x3FC66);
721 cx_write(AUD_DEEMPH0_B1, 0x399A);
722
723 cx_write(AUD_DEEMPH1_G0, 0x0D80);
724 cx_write(AUD_DEEMPH1_A0, 0x6262);
725 cx_write(AUD_DEEMPH1_B0, 0x1C29);
726 cx_write(AUD_DEEMPH1_A1, 0x3FC66);
727 cx_write(AUD_DEEMPH1_B1, 0x399A);
728
729 break;
730
731 case WW_FM_DEEMPH_75:
732 //Set De-emphasis filter coefficients for 75 usec
733 cx_write(AUD_DEEMPH0_G0, 0x91B );
734 cx_write(AUD_DEEMPH0_A0, 0x6B68);
735 cx_write(AUD_DEEMPH0_B0, 0x11EC);
736 cx_write(AUD_DEEMPH0_A1, 0x3FC66);
737 cx_write(AUD_DEEMPH0_B1, 0x399A);
738
739 cx_write(AUD_DEEMPH1_G0, 0xAA0 );
740 cx_write(AUD_DEEMPH1_A0, 0x6B68);
741 cx_write(AUD_DEEMPH1_B0, 0x11EC);
742 cx_write(AUD_DEEMPH1_A1, 0x3FC66);
743 cx_write(AUD_DEEMPH1_B1, 0x399A);
744
745 break;
746 }
747#endif
748
749 dprintk("%s (status: unknown)\n",__FUNCTION__);
750 set_audio_start(core, 0x0020, EN_FMRADIO_AUTO_STEREO);
751
752 // AB: 10/2/01: this register is not being reset appropriately on occasion.
753 cx_write(AUD_POLYPH80SCALEFAC,3);
754
755 set_audio_finish(core);
756}
757
758/* ----------------------------------------------------------- */
759
760void cx88_set_tvaudio(struct cx88_core *core)
761{
762 switch (core->tvaudio) {
763 case WW_BTSC:
764 set_audio_standard_BTSC(core,0);
765 break;
766 case WW_NICAM_BGDKL:
767 set_audio_standard_NICAM_L(core,0);
768 break;
769 case WW_NICAM_I:
770 set_audio_standard_PAL_I(core,0);
771 break;
772 case WW_A2_BG:
773 case WW_A2_DK:
774 case WW_A2_M:
775 set_audio_standard_A2(core);
776 break;
777 case WW_EIAJ:
778 set_audio_standard_EIAJ(core);
779 break;
780 case WW_FM:
781 set_audio_standard_FM(core);
782 break;
783 case WW_SYSTEM_L_AM:
784 set_audio_standard_NICAM_L(core, 1);
785 break;
786 case WW_NONE:
787 default:
788 printk("%s/0: unknown tv audio mode [%d]\n",
789 core->name, core->tvaudio);
790 break;
791 }
792 return;
793}
794
795void cx88_newstation(struct cx88_core *core)
796{
797 core->audiomode_manual = UNSET;
798
799 switch (core->tvaudio) {
800 case WW_SYSTEM_L_AM:
801 /* try nicam ... */
802 core->audiomode_current = V4L2_TUNER_MODE_STEREO;
803 set_audio_standard_NICAM_L(core, 1);
804 break;
805 }
806}
807
808void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t)
809{
810 static char *m[] = {"stereo", "dual mono", "mono", "sap"};
811 static char *p[] = {"no pilot", "pilot c1", "pilot c2", "?"};
812 u32 reg,mode,pilot;
813
814 reg = cx_read(AUD_STATUS);
815 mode = reg & 0x03;
816 pilot = (reg >> 2) & 0x03;
817
818 if (core->astat != reg)
819 dprintk("AUD_STATUS: 0x%x [%s/%s] ctl=%s\n",
820 reg, m[mode], p[pilot],
821 aud_ctl_names[cx_read(AUD_CTL) & 63]);
822 core->astat = reg;
823
824 t->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_SAP |
825 V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2;
826 t->rxsubchans = V4L2_TUNER_SUB_MONO;
827 t->audmode = V4L2_TUNER_MODE_MONO;
828
829 switch (core->tvaudio) {
830 case WW_BTSC:
831 t->capability = V4L2_TUNER_CAP_STEREO |
832 V4L2_TUNER_CAP_SAP;
833 t->rxsubchans = V4L2_TUNER_SUB_STEREO;
834 if (1 == pilot) {
835 /* SAP */
836 t->rxsubchans |= V4L2_TUNER_SUB_SAP;
837 }
838 break;
839 case WW_A2_BG:
840 case WW_A2_DK:
841 case WW_A2_M:
842 if (1 == pilot) {
843 /* stereo */
844 t->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
845 if (0 == mode)
846 t->audmode = V4L2_TUNER_MODE_STEREO;
847 }
848 if (2 == pilot) {
849 /* dual language -- FIXME */
850 t->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
851 t->audmode = V4L2_TUNER_MODE_LANG1;
852 }
853 break;
854 case WW_NICAM_BGDKL:
855 if (0 == mode) {
856 t->audmode = V4L2_TUNER_MODE_STEREO;
857 t->rxsubchans |= V4L2_TUNER_SUB_STEREO;
858 }
859 break;
860 case WW_SYSTEM_L_AM:
861 if (0x0 == mode && !(cx_read(AUD_INIT) & 0x04)) {
862 t->audmode = V4L2_TUNER_MODE_STEREO;
863 t->rxsubchans |= V4L2_TUNER_SUB_STEREO;
864 }
865 break ;
866 default:
867 /* nothing */
868 break;
869 }
870 return;
871}
872
873void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual)
874{
875 u32 ctl = UNSET;
876 u32 mask = UNSET;
877
878 if (manual) {
879 core->audiomode_manual = mode;
880 } else {
881 if (UNSET != core->audiomode_manual)
882 return;
883 }
884 core->audiomode_current = mode;
885
886 switch (core->tvaudio) {
887 case WW_BTSC:
888 switch (mode) {
889 case V4L2_TUNER_MODE_MONO:
890 ctl = EN_BTSC_FORCE_MONO;
891 mask = 0x3f;
892 break;
893 case V4L2_TUNER_MODE_SAP:
894 ctl = EN_BTSC_FORCE_SAP;
895 mask = 0x3f;
896 break;
897 case V4L2_TUNER_MODE_STEREO:
898 ctl = EN_BTSC_AUTO_STEREO;
899 mask = 0x3f;
900 break;
901 }
902 break;
903 case WW_A2_BG:
904 case WW_A2_DK:
905 case WW_A2_M:
906 switch (mode) {
907 case V4L2_TUNER_MODE_MONO:
908 case V4L2_TUNER_MODE_LANG1:
909 ctl = EN_A2_FORCE_MONO1;
910 mask = 0x3f;
911 break;
912 case V4L2_TUNER_MODE_LANG2:
913 ctl = EN_A2_AUTO_MONO2;
914 mask = 0x3f;
915 break;
916 case V4L2_TUNER_MODE_STEREO:
917 ctl = EN_A2_AUTO_STEREO | EN_DMTRX_SUMR;
918 mask = 0x8bf;
919 break;
920 }
921 break;
922 case WW_NICAM_BGDKL:
923 switch (mode) {
924 case V4L2_TUNER_MODE_MONO:
925 ctl = EN_NICAM_FORCE_MONO1;
926 mask = 0x3f;
927 break;
928 case V4L2_TUNER_MODE_LANG1:
929 ctl = EN_NICAM_AUTO_MONO2;
930 mask = 0x3f;
931 break;
932 case V4L2_TUNER_MODE_STEREO:
933 ctl = EN_NICAM_FORCE_STEREO | EN_DMTRX_LR;
934 mask = 0x93f;
935 break;
936 }
937 break;
938 case WW_SYSTEM_L_AM:
939 switch (mode) {
940 case V4L2_TUNER_MODE_MONO:
941 case V4L2_TUNER_MODE_LANG1: /* FIXME */
942 set_audio_standard_NICAM_L(core, 0);
943 break;
944 case V4L2_TUNER_MODE_STEREO:
945 set_audio_standard_NICAM_L(core, 1);
946 break;
947 }
948 break;
949 case WW_NICAM_I:
950 switch (mode) {
951 case V4L2_TUNER_MODE_MONO:
952 case V4L2_TUNER_MODE_LANG1:
953 set_audio_standard_PAL_I(core, 0);
954 break;
955 case V4L2_TUNER_MODE_STEREO:
956 set_audio_standard_PAL_I(core, 1);
957 break;
958 }
959 break;
960 case WW_FM:
961 switch (mode) {
962 case V4L2_TUNER_MODE_MONO:
963 ctl = EN_FMRADIO_FORCE_MONO;
964 mask = 0x3f;
965 break;
966 case V4L2_TUNER_MODE_STEREO:
967 ctl = EN_FMRADIO_AUTO_STEREO;
968 mask = 0x3f;
969 break;
970 }
971 break;
972 }
973
974 if (UNSET != ctl) {
975 dprintk("cx88_set_stereo: mask 0x%x, ctl 0x%x "
976 "[status=0x%x,ctl=0x%x,vol=0x%x]\n",
977 mask, ctl, cx_read(AUD_STATUS),
978 cx_read(AUD_CTL), cx_sread(SHADOW_AUD_VOL_CTL));
979 cx_andor(AUD_CTL, mask, ctl);
980 }
981 return;
982}
983
984int cx88_audio_thread(void *data)
985{
986 struct cx88_core *core = data;
987 struct v4l2_tuner t;
988 u32 mode = 0;
989
990 dprintk("cx88: tvaudio thread started\n");
991 for (;;) {
992 msleep_interruptible(1000);
993 if (kthread_should_stop())
994 break;
995
996 /* just monitor the audio status for now ... */
997 memset(&t,0,sizeof(t));
998 cx88_get_stereo(core,&t);
999
1000 if (UNSET != core->audiomode_manual)
1001 /* manually set, don't do anything. */
1002 continue;
1003
1004 /* monitor signal */
1005 if (t.rxsubchans & V4L2_TUNER_SUB_STEREO)
1006 mode = V4L2_TUNER_MODE_STEREO;
1007 else
1008 mode = V4L2_TUNER_MODE_MONO;
1009 if (mode == core->audiomode_current)
1010 continue;
1011
1012 /* automatically switch to best available mode */
1013 cx88_set_stereo(core, mode, 0);
1014 }
1015
1016 dprintk("cx88: tvaudio thread exiting\n");
1017 return 0;
1018}
1019
1020/* ----------------------------------------------------------- */
1021
1022EXPORT_SYMBOL(cx88_set_tvaudio);
1023EXPORT_SYMBOL(cx88_newstation);
1024EXPORT_SYMBOL(cx88_set_stereo);
1025EXPORT_SYMBOL(cx88_get_stereo);
1026EXPORT_SYMBOL(cx88_audio_thread);
1027
1028/*
1029 * Local variables:
1030 * c-basic-offset: 8
1031 * End:
1032 */
diff --git a/drivers/media/video/cx88/cx88-vbi.c b/drivers/media/video/cx88/cx88-vbi.c
new file mode 100644
index 00000000000..471e508b074
--- /dev/null
+++ b/drivers/media/video/cx88/cx88-vbi.c
@@ -0,0 +1,248 @@
1/*
2 * $Id: cx88-vbi.c,v 1.16 2004/12/10 12:33:39 kraxel Exp $
3 */
4#include <linux/kernel.h>
5#include <linux/module.h>
6#include <linux/moduleparam.h>
7#include <linux/init.h>
8#include <linux/slab.h>
9
10#include "cx88.h"
11
12static unsigned int vbibufs = 4;
13module_param(vbibufs,int,0644);
14MODULE_PARM_DESC(vbibufs,"number of vbi buffers, range 2-32");
15
16static unsigned int vbi_debug = 0;
17module_param(vbi_debug,int,0644);
18MODULE_PARM_DESC(vbi_debug,"enable debug messages [vbi]");
19
20#define dprintk(level,fmt, arg...) if (vbi_debug >= level) \
21 printk(KERN_DEBUG "%s: " fmt, dev->core->name , ## arg)
22
23/* ------------------------------------------------------------------ */
24
25void cx8800_vbi_fmt(struct cx8800_dev *dev, struct v4l2_format *f)
26{
27 memset(&f->fmt.vbi,0,sizeof(f->fmt.vbi));
28
29 f->fmt.vbi.samples_per_line = VBI_LINE_LENGTH;
30 f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
31 f->fmt.vbi.offset = 244;
32 f->fmt.vbi.count[0] = VBI_LINE_COUNT;
33 f->fmt.vbi.count[1] = VBI_LINE_COUNT;
34
35 if (dev->core->tvnorm->id & V4L2_STD_525_60) {
36 /* ntsc */
37 f->fmt.vbi.sampling_rate = 28636363;
38 f->fmt.vbi.start[0] = 10 -1;
39 f->fmt.vbi.start[1] = 273 -1;
40
41 } else if (dev->core->tvnorm->id & V4L2_STD_625_50) {
42 /* pal */
43 f->fmt.vbi.sampling_rate = 35468950;
44 f->fmt.vbi.start[0] = 7 -1;
45 f->fmt.vbi.start[1] = 319 -1;
46 }
47}
48
49int cx8800_start_vbi_dma(struct cx8800_dev *dev,
50 struct cx88_dmaqueue *q,
51 struct cx88_buffer *buf)
52{
53 struct cx88_core *core = dev->core;
54
55 /* setup fifo + format */
56 cx88_sram_channel_setup(dev->core, &cx88_sram_channels[SRAM_CH24],
57 buf->vb.width, buf->risc.dma);
58
59 cx_write(MO_VBOS_CONTROL, ( (1 << 18) | // comb filter delay fixup
60 (1 << 15) | // enable vbi capture
61 (1 << 11) ));
62
63 /* reset counter */
64 cx_write(MO_VBI_GPCNTRL, GP_COUNT_CONTROL_RESET);
65 q->count = 1;
66
67 /* enable irqs */
68 cx_set(MO_PCI_INTMSK, core->pci_irqmask | 0x01);
69 cx_set(MO_VID_INTMSK, 0x0f0088);
70
71 /* enable capture */
72 cx_set(VID_CAPTURE_CONTROL,0x18);
73
74 /* start dma */
75 cx_set(MO_DEV_CNTRL2, (1<<5));
76 cx_set(MO_VID_DMACNTRL, 0x88);
77
78 return 0;
79}
80
81int cx8800_stop_vbi_dma(struct cx8800_dev *dev)
82{
83 struct cx88_core *core = dev->core;
84
85 /* stop dma */
86 cx_clear(MO_VID_DMACNTRL, 0x88);
87
88 /* disable capture */
89 cx_clear(VID_CAPTURE_CONTROL,0x18);
90
91 /* disable irqs */
92 cx_clear(MO_PCI_INTMSK, 0x000001);
93 cx_clear(MO_VID_INTMSK, 0x0f0088);
94 return 0;
95}
96
97int cx8800_restart_vbi_queue(struct cx8800_dev *dev,
98 struct cx88_dmaqueue *q)
99{
100 struct cx88_buffer *buf;
101 struct list_head *item;
102
103 if (list_empty(&q->active))
104 return 0;
105
106 buf = list_entry(q->active.next, struct cx88_buffer, vb.queue);
107 dprintk(2,"restart_queue [%p/%d]: restart dma\n",
108 buf, buf->vb.i);
109 cx8800_start_vbi_dma(dev, q, buf);
110 list_for_each(item,&q->active) {
111 buf = list_entry(item, struct cx88_buffer, vb.queue);
112 buf->count = q->count++;
113 }
114 mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
115 return 0;
116}
117
118void cx8800_vbi_timeout(unsigned long data)
119{
120 struct cx8800_dev *dev = (struct cx8800_dev*)data;
121 struct cx88_core *core = dev->core;
122 struct cx88_dmaqueue *q = &dev->vbiq;
123 struct cx88_buffer *buf;
124 unsigned long flags;
125
126 cx88_sram_channel_dump(dev->core, &cx88_sram_channels[SRAM_CH24]);
127
128 cx_clear(MO_VID_DMACNTRL, 0x88);
129 cx_clear(VID_CAPTURE_CONTROL, 0x18);
130
131 spin_lock_irqsave(&dev->slock,flags);
132 while (!list_empty(&q->active)) {
133 buf = list_entry(q->active.next, struct cx88_buffer, vb.queue);
134 list_del(&buf->vb.queue);
135 buf->vb.state = STATE_ERROR;
136 wake_up(&buf->vb.done);
137 printk("%s/0: [%p/%d] timeout - dma=0x%08lx\n", dev->core->name,
138 buf, buf->vb.i, (unsigned long)buf->risc.dma);
139 }
140 cx8800_restart_vbi_queue(dev,q);
141 spin_unlock_irqrestore(&dev->slock,flags);
142}
143
144/* ------------------------------------------------------------------ */
145
146static int
147vbi_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
148{
149 *size = VBI_LINE_COUNT * VBI_LINE_LENGTH * 2;
150 if (0 == *count)
151 *count = vbibufs;
152 if (*count < 2)
153 *count = 2;
154 if (*count > 32)
155 *count = 32;
156 return 0;
157}
158
159static int
160vbi_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
161 enum v4l2_field field)
162{
163 struct cx8800_fh *fh = q->priv_data;
164 struct cx8800_dev *dev = fh->dev;
165 struct cx88_buffer *buf = container_of(vb,struct cx88_buffer,vb);
166 unsigned int size;
167 int rc;
168
169 size = VBI_LINE_COUNT * VBI_LINE_LENGTH * 2;
170 if (0 != buf->vb.baddr && buf->vb.bsize < size)
171 return -EINVAL;
172
173 if (STATE_NEEDS_INIT == buf->vb.state) {
174 buf->vb.width = VBI_LINE_LENGTH;
175 buf->vb.height = VBI_LINE_COUNT;
176 buf->vb.size = size;
177 buf->vb.field = V4L2_FIELD_SEQ_TB;
178
179 if (0 != (rc = videobuf_iolock(dev->pci,&buf->vb,NULL)))
180 goto fail;
181 cx88_risc_buffer(dev->pci, &buf->risc,
182 buf->vb.dma.sglist,
183 0, buf->vb.width * buf->vb.height,
184 buf->vb.width, 0,
185 buf->vb.height);
186 }
187 buf->vb.state = STATE_PREPARED;
188 return 0;
189
190 fail:
191 cx88_free_buffer(dev->pci,buf);
192 return rc;
193}
194
195static void
196vbi_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
197{
198 struct cx88_buffer *buf = container_of(vb,struct cx88_buffer,vb);
199 struct cx88_buffer *prev;
200 struct cx8800_fh *fh = vq->priv_data;
201 struct cx8800_dev *dev = fh->dev;
202 struct cx88_dmaqueue *q = &dev->vbiq;
203
204 /* add jump to stopper */
205 buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
206 buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
207
208 if (list_empty(&q->active)) {
209 list_add_tail(&buf->vb.queue,&q->active);
210 cx8800_start_vbi_dma(dev, q, buf);
211 buf->vb.state = STATE_ACTIVE;
212 buf->count = q->count++;
213 mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
214 dprintk(2,"[%p/%d] vbi_queue - first active\n",
215 buf, buf->vb.i);
216
217 } else {
218 prev = list_entry(q->active.prev, struct cx88_buffer, vb.queue);
219 list_add_tail(&buf->vb.queue,&q->active);
220 buf->vb.state = STATE_ACTIVE;
221 buf->count = q->count++;
222 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
223 dprintk(2,"[%p/%d] buffer_queue - append to active\n",
224 buf, buf->vb.i);
225 }
226}
227
228static void vbi_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
229{
230 struct cx88_buffer *buf = container_of(vb,struct cx88_buffer,vb);
231 struct cx8800_fh *fh = q->priv_data;
232
233 cx88_free_buffer(fh->dev->pci,buf);
234}
235
236struct videobuf_queue_ops cx8800_vbi_qops = {
237 .buf_setup = vbi_setup,
238 .buf_prepare = vbi_prepare,
239 .buf_queue = vbi_queue,
240 .buf_release = vbi_release,
241};
242
243/* ------------------------------------------------------------------ */
244/*
245 * Local variables:
246 * c-basic-offset: 8
247 * End:
248 */
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c
new file mode 100644
index 00000000000..701f594e181
--- /dev/null
+++ b/drivers/media/video/cx88/cx88-video.c
@@ -0,0 +1,2277 @@
1/*
2 * $Id: cx88-video.c,v 1.58 2005/03/07 15:58:05 kraxel Exp $
3 *
4 * device driver for Conexant 2388x based TV cards
5 * video4linux video interface
6 *
7 * (c) 2003-04 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
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#include <linux/init.h>
25#include <linux/list.h>
26#include <linux/module.h>
27#include <linux/moduleparam.h>
28#include <linux/kmod.h>
29#include <linux/kernel.h>
30#include <linux/slab.h>
31#include <linux/interrupt.h>
32#include <linux/delay.h>
33#include <linux/kthread.h>
34#include <asm/div64.h>
35
36#include "cx88.h"
37
38MODULE_DESCRIPTION("v4l2 driver module for cx2388x based TV cards");
39MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
40MODULE_LICENSE("GPL");
41
42/* ------------------------------------------------------------------ */
43
44static unsigned int video_nr[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET };
45static unsigned int vbi_nr[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET };
46static unsigned int radio_nr[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET };
47
48module_param_array(video_nr, int, NULL, 0444);
49module_param_array(vbi_nr, int, NULL, 0444);
50module_param_array(radio_nr, int, NULL, 0444);
51
52MODULE_PARM_DESC(video_nr,"video device numbers");
53MODULE_PARM_DESC(vbi_nr,"vbi device numbers");
54MODULE_PARM_DESC(radio_nr,"radio device numbers");
55
56static unsigned int video_debug = 0;
57module_param(video_debug,int,0644);
58MODULE_PARM_DESC(video_debug,"enable debug messages [video]");
59
60static unsigned int irq_debug = 0;
61module_param(irq_debug,int,0644);
62MODULE_PARM_DESC(irq_debug,"enable debug messages [IRQ handler]");
63
64static unsigned int vid_limit = 16;
65module_param(vid_limit,int,0644);
66MODULE_PARM_DESC(vid_limit,"capture memory limit in megabytes");
67
68#define dprintk(level,fmt, arg...) if (video_debug >= level) \
69 printk(KERN_DEBUG "%s/0: " fmt, dev->core->name , ## arg)
70
71/* ------------------------------------------------------------------ */
72
73static LIST_HEAD(cx8800_devlist);
74
75/* ------------------------------------------------------------------- */
76/* static data */
77
78static struct cx88_tvnorm tvnorms[] = {
79 {
80 .name = "NTSC-M",
81 .id = V4L2_STD_NTSC_M,
82 .cxiformat = VideoFormatNTSC,
83 .cxoformat = 0x181f0008,
84 },{
85 .name = "NTSC-JP",
86 .id = V4L2_STD_NTSC_M_JP,
87 .cxiformat = VideoFormatNTSCJapan,
88 .cxoformat = 0x181f0008,
89#if 0
90 },{
91 .name = "NTSC-4.43",
92 .id = FIXME,
93 .cxiformat = VideoFormatNTSC443,
94 .cxoformat = 0x181f0008,
95#endif
96 },{
97 .name = "PAL-BG",
98 .id = V4L2_STD_PAL_BG,
99 .cxiformat = VideoFormatPAL,
100 .cxoformat = 0x181f0008,
101 },{
102 .name = "PAL-DK",
103 .id = V4L2_STD_PAL_DK,
104 .cxiformat = VideoFormatPAL,
105 .cxoformat = 0x181f0008,
106 },{
107 .name = "PAL-I",
108 .id = V4L2_STD_PAL_I,
109 .cxiformat = VideoFormatPAL,
110 .cxoformat = 0x181f0008,
111 },{
112 .name = "PAL-M",
113 .id = V4L2_STD_PAL_M,
114 .cxiformat = VideoFormatPALM,
115 .cxoformat = 0x1c1f0008,
116 },{
117 .name = "PAL-N",
118 .id = V4L2_STD_PAL_N,
119 .cxiformat = VideoFormatPALN,
120 .cxoformat = 0x1c1f0008,
121 },{
122 .name = "PAL-Nc",
123 .id = V4L2_STD_PAL_Nc,
124 .cxiformat = VideoFormatPALNC,
125 .cxoformat = 0x1c1f0008,
126 },{
127 .name = "PAL-60",
128 .id = V4L2_STD_PAL_60,
129 .cxiformat = VideoFormatPAL60,
130 .cxoformat = 0x181f0008,
131 },{
132 .name = "SECAM-L",
133 .id = V4L2_STD_SECAM_L,
134 .cxiformat = VideoFormatSECAM,
135 .cxoformat = 0x181f0008,
136 },{
137 .name = "SECAM-DK",
138 .id = V4L2_STD_SECAM_DK,
139 .cxiformat = VideoFormatSECAM,
140 .cxoformat = 0x181f0008,
141 }
142};
143
144static struct cx8800_fmt formats[] = {
145 {
146 .name = "8 bpp, gray",
147 .fourcc = V4L2_PIX_FMT_GREY,
148 .cxformat = ColorFormatY8,
149 .depth = 8,
150 .flags = FORMAT_FLAGS_PACKED,
151 },{
152 .name = "15 bpp RGB, le",
153 .fourcc = V4L2_PIX_FMT_RGB555,
154 .cxformat = ColorFormatRGB15,
155 .depth = 16,
156 .flags = FORMAT_FLAGS_PACKED,
157 },{
158 .name = "15 bpp RGB, be",
159 .fourcc = V4L2_PIX_FMT_RGB555X,
160 .cxformat = ColorFormatRGB15 | ColorFormatBSWAP,
161 .depth = 16,
162 .flags = FORMAT_FLAGS_PACKED,
163 },{
164 .name = "16 bpp RGB, le",
165 .fourcc = V4L2_PIX_FMT_RGB565,
166 .cxformat = ColorFormatRGB16,
167 .depth = 16,
168 .flags = FORMAT_FLAGS_PACKED,
169 },{
170 .name = "16 bpp RGB, be",
171 .fourcc = V4L2_PIX_FMT_RGB565X,
172 .cxformat = ColorFormatRGB16 | ColorFormatBSWAP,
173 .depth = 16,
174 .flags = FORMAT_FLAGS_PACKED,
175 },{
176 .name = "24 bpp RGB, le",
177 .fourcc = V4L2_PIX_FMT_BGR24,
178 .cxformat = ColorFormatRGB24,
179 .depth = 24,
180 .flags = FORMAT_FLAGS_PACKED,
181 },{
182 .name = "32 bpp RGB, le",
183 .fourcc = V4L2_PIX_FMT_BGR32,
184 .cxformat = ColorFormatRGB32,
185 .depth = 32,
186 .flags = FORMAT_FLAGS_PACKED,
187 },{
188 .name = "32 bpp RGB, be",
189 .fourcc = V4L2_PIX_FMT_RGB32,
190 .cxformat = ColorFormatRGB32 | ColorFormatBSWAP | ColorFormatWSWAP,
191 .depth = 32,
192 .flags = FORMAT_FLAGS_PACKED,
193 },{
194 .name = "4:2:2, packed, YUYV",
195 .fourcc = V4L2_PIX_FMT_YUYV,
196 .cxformat = ColorFormatYUY2,
197 .depth = 16,
198 .flags = FORMAT_FLAGS_PACKED,
199 },{
200 .name = "4:2:2, packed, UYVY",
201 .fourcc = V4L2_PIX_FMT_UYVY,
202 .cxformat = ColorFormatYUY2 | ColorFormatBSWAP,
203 .depth = 16,
204 .flags = FORMAT_FLAGS_PACKED,
205 },
206};
207
208static struct cx8800_fmt* format_by_fourcc(unsigned int fourcc)
209{
210 unsigned int i;
211
212 for (i = 0; i < ARRAY_SIZE(formats); i++)
213 if (formats[i].fourcc == fourcc)
214 return formats+i;
215 return NULL;
216}
217
218/* ------------------------------------------------------------------- */
219
220static const struct v4l2_queryctrl no_ctl = {
221 .name = "42",
222 .flags = V4L2_CTRL_FLAG_DISABLED,
223};
224
225static struct cx88_ctrl cx8800_ctls[] = {
226 /* --- video --- */
227 {
228 .v = {
229 .id = V4L2_CID_BRIGHTNESS,
230 .name = "Brightness",
231 .minimum = 0x00,
232 .maximum = 0xff,
233 .step = 1,
234 .default_value = 0,
235 .type = V4L2_CTRL_TYPE_INTEGER,
236 },
237 .off = 128,
238 .reg = MO_CONTR_BRIGHT,
239 .mask = 0x00ff,
240 .shift = 0,
241 },{
242 .v = {
243 .id = V4L2_CID_CONTRAST,
244 .name = "Contrast",
245 .minimum = 0,
246 .maximum = 0xff,
247 .step = 1,
248 .default_value = 0,
249 .type = V4L2_CTRL_TYPE_INTEGER,
250 },
251 .reg = MO_CONTR_BRIGHT,
252 .mask = 0xff00,
253 .shift = 8,
254 },{
255 .v = {
256 .id = V4L2_CID_HUE,
257 .name = "Hue",
258 .minimum = 0,
259 .maximum = 0xff,
260 .step = 1,
261 .default_value = 0,
262 .type = V4L2_CTRL_TYPE_INTEGER,
263 },
264 .off = 0,
265 .reg = MO_HUE,
266 .mask = 0x00ff,
267 .shift = 0,
268 },{
269 /* strictly, this only describes only U saturation.
270 * V saturation is handled specially through code.
271 */
272 .v = {
273 .id = V4L2_CID_SATURATION,
274 .name = "Saturation",
275 .minimum = 0,
276 .maximum = 0xff,
277 .step = 1,
278 .default_value = 0,
279 .type = V4L2_CTRL_TYPE_INTEGER,
280 },
281 .off = 0,
282 .reg = MO_UV_SATURATION,
283 .mask = 0x00ff,
284 .shift = 0,
285 },{
286 /* --- audio --- */
287 .v = {
288 .id = V4L2_CID_AUDIO_MUTE,
289 .name = "Mute",
290 .minimum = 0,
291 .maximum = 1,
292 .type = V4L2_CTRL_TYPE_BOOLEAN,
293 },
294 .reg = AUD_VOL_CTL,
295 .sreg = SHADOW_AUD_VOL_CTL,
296 .mask = (1 << 6),
297 .shift = 6,
298 },{
299 .v = {
300 .id = V4L2_CID_AUDIO_VOLUME,
301 .name = "Volume",
302 .minimum = 0,
303 .maximum = 0x3f,
304 .step = 1,
305 .default_value = 0,
306 .type = V4L2_CTRL_TYPE_INTEGER,
307 },
308 .reg = AUD_VOL_CTL,
309 .sreg = SHADOW_AUD_VOL_CTL,
310 .mask = 0x3f,
311 .shift = 0,
312 },{
313 .v = {
314 .id = V4L2_CID_AUDIO_BALANCE,
315 .name = "Balance",
316 .minimum = 0,
317 .maximum = 0x7f,
318 .step = 1,
319 .default_value = 0x40,
320 .type = V4L2_CTRL_TYPE_INTEGER,
321 },
322 .reg = AUD_BAL_CTL,
323 .sreg = SHADOW_AUD_BAL_CTL,
324 .mask = 0x7f,
325 .shift = 0,
326 }
327};
328const int CX8800_CTLS = ARRAY_SIZE(cx8800_ctls);
329
330/* ------------------------------------------------------------------- */
331/* resource management */
332
333static int res_get(struct cx8800_dev *dev, struct cx8800_fh *fh, unsigned int bit)
334{
335 if (fh->resources & bit)
336 /* have it already allocated */
337 return 1;
338
339 /* is it free? */
340 down(&dev->lock);
341 if (dev->resources & bit) {
342 /* no, someone else uses it */
343 up(&dev->lock);
344 return 0;
345 }
346 /* it's free, grab it */
347 fh->resources |= bit;
348 dev->resources |= bit;
349 dprintk(1,"res: get %d\n",bit);
350 up(&dev->lock);
351 return 1;
352}
353
354static
355int res_check(struct cx8800_fh *fh, unsigned int bit)
356{
357 return (fh->resources & bit);
358}
359
360static
361int res_locked(struct cx8800_dev *dev, unsigned int bit)
362{
363 return (dev->resources & bit);
364}
365
366static
367void res_free(struct cx8800_dev *dev, struct cx8800_fh *fh, unsigned int bits)
368{
369 if ((fh->resources & bits) != bits)
370 BUG();
371
372 down(&dev->lock);
373 fh->resources &= ~bits;
374 dev->resources &= ~bits;
375 dprintk(1,"res: put %d\n",bits);
376 up(&dev->lock);
377}
378
379/* ------------------------------------------------------------------ */
380
381static int video_mux(struct cx8800_dev *dev, unsigned int input)
382{
383 struct cx88_core *core = dev->core;
384
385 dprintk(1,"video_mux: %d [vmux=%d,gpio=0x%x,0x%x,0x%x,0x%x]\n",
386 input, INPUT(input)->vmux,
387 INPUT(input)->gpio0,INPUT(input)->gpio1,
388 INPUT(input)->gpio2,INPUT(input)->gpio3);
389 dev->core->input = input;
390 cx_andor(MO_INPUT_FORMAT, 0x03 << 14, INPUT(input)->vmux << 14);
391 cx_write(MO_GP3_IO, INPUT(input)->gpio3);
392 cx_write(MO_GP0_IO, INPUT(input)->gpio0);
393 cx_write(MO_GP1_IO, INPUT(input)->gpio1);
394 cx_write(MO_GP2_IO, INPUT(input)->gpio2);
395
396 switch (INPUT(input)->type) {
397 case CX88_VMUX_SVIDEO:
398 cx_set(MO_AFECFG_IO, 0x00000001);
399 cx_set(MO_INPUT_FORMAT, 0x00010010);
400 cx_set(MO_FILTER_EVEN, 0x00002020);
401 cx_set(MO_FILTER_ODD, 0x00002020);
402 break;
403 default:
404 cx_clear(MO_AFECFG_IO, 0x00000001);
405 cx_clear(MO_INPUT_FORMAT, 0x00010010);
406 cx_clear(MO_FILTER_EVEN, 0x00002020);
407 cx_clear(MO_FILTER_ODD, 0x00002020);
408 break;
409 }
410 return 0;
411}
412
413/* ------------------------------------------------------------------ */
414
415static int start_video_dma(struct cx8800_dev *dev,
416 struct cx88_dmaqueue *q,
417 struct cx88_buffer *buf)
418{
419 struct cx88_core *core = dev->core;
420
421 /* setup fifo + format */
422 cx88_sram_channel_setup(dev->core, &cx88_sram_channels[SRAM_CH21],
423 buf->bpl, buf->risc.dma);
424 cx88_set_scale(dev->core, buf->vb.width, buf->vb.height, buf->vb.field);
425 cx_write(MO_COLOR_CTRL, buf->fmt->cxformat | ColorFormatGamma);
426
427 /* reset counter */
428 cx_write(MO_VIDY_GPCNTRL,GP_COUNT_CONTROL_RESET);
429 q->count = 1;
430
431 /* enable irqs */
432 cx_set(MO_PCI_INTMSK, core->pci_irqmask | 0x01);
433 cx_set(MO_VID_INTMSK, 0x0f0011);
434
435 /* enable capture */
436 cx_set(VID_CAPTURE_CONTROL,0x06);
437
438 /* start dma */
439 cx_set(MO_DEV_CNTRL2, (1<<5));
440 cx_set(MO_VID_DMACNTRL, 0x11);
441
442 return 0;
443}
444
445static int stop_video_dma(struct cx8800_dev *dev)
446{
447 struct cx88_core *core = dev->core;
448
449 /* stop dma */
450 cx_clear(MO_VID_DMACNTRL, 0x11);
451
452 /* disable capture */
453 cx_clear(VID_CAPTURE_CONTROL,0x06);
454
455 /* disable irqs */
456 cx_clear(MO_PCI_INTMSK, 0x000001);
457 cx_clear(MO_VID_INTMSK, 0x0f0011);
458 return 0;
459}
460
461static int restart_video_queue(struct cx8800_dev *dev,
462 struct cx88_dmaqueue *q)
463{
464 struct cx88_buffer *buf, *prev;
465 struct list_head *item;
466
467 if (!list_empty(&q->active)) {
468 buf = list_entry(q->active.next, struct cx88_buffer, vb.queue);
469 dprintk(2,"restart_queue [%p/%d]: restart dma\n",
470 buf, buf->vb.i);
471 start_video_dma(dev, q, buf);
472 list_for_each(item,&q->active) {
473 buf = list_entry(item, struct cx88_buffer, vb.queue);
474 buf->count = q->count++;
475 }
476 mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
477 return 0;
478 }
479
480 prev = NULL;
481 for (;;) {
482 if (list_empty(&q->queued))
483 return 0;
484 buf = list_entry(q->queued.next, struct cx88_buffer, vb.queue);
485 if (NULL == prev) {
486 list_del(&buf->vb.queue);
487 list_add_tail(&buf->vb.queue,&q->active);
488 start_video_dma(dev, q, buf);
489 buf->vb.state = STATE_ACTIVE;
490 buf->count = q->count++;
491 mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
492 dprintk(2,"[%p/%d] restart_queue - first active\n",
493 buf,buf->vb.i);
494
495 } else if (prev->vb.width == buf->vb.width &&
496 prev->vb.height == buf->vb.height &&
497 prev->fmt == buf->fmt) {
498 list_del(&buf->vb.queue);
499 list_add_tail(&buf->vb.queue,&q->active);
500 buf->vb.state = STATE_ACTIVE;
501 buf->count = q->count++;
502 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
503 dprintk(2,"[%p/%d] restart_queue - move to active\n",
504 buf,buf->vb.i);
505 } else {
506 return 0;
507 }
508 prev = buf;
509 }
510}
511
512/* ------------------------------------------------------------------ */
513
514static int
515buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
516{
517 struct cx8800_fh *fh = q->priv_data;
518
519 *size = fh->fmt->depth*fh->width*fh->height >> 3;
520 if (0 == *count)
521 *count = 32;
522 while (*size * *count > vid_limit * 1024 * 1024)
523 (*count)--;
524 return 0;
525}
526
527static int
528buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
529 enum v4l2_field field)
530{
531 struct cx8800_fh *fh = q->priv_data;
532 struct cx8800_dev *dev = fh->dev;
533 struct cx88_buffer *buf = container_of(vb,struct cx88_buffer,vb);
534 int rc, init_buffer = 0;
535
536 BUG_ON(NULL == fh->fmt);
537 if (fh->width < 48 || fh->width > norm_maxw(dev->core->tvnorm) ||
538 fh->height < 32 || fh->height > norm_maxh(dev->core->tvnorm))
539 return -EINVAL;
540 buf->vb.size = (fh->width * fh->height * fh->fmt->depth) >> 3;
541 if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size)
542 return -EINVAL;
543
544 if (buf->fmt != fh->fmt ||
545 buf->vb.width != fh->width ||
546 buf->vb.height != fh->height ||
547 buf->vb.field != field) {
548 buf->fmt = fh->fmt;
549 buf->vb.width = fh->width;
550 buf->vb.height = fh->height;
551 buf->vb.field = field;
552 init_buffer = 1;
553 }
554
555 if (STATE_NEEDS_INIT == buf->vb.state) {
556 init_buffer = 1;
557 if (0 != (rc = videobuf_iolock(dev->pci,&buf->vb,NULL)))
558 goto fail;
559 }
560
561 if (init_buffer) {
562 buf->bpl = buf->vb.width * buf->fmt->depth >> 3;
563 switch (buf->vb.field) {
564 case V4L2_FIELD_TOP:
565 cx88_risc_buffer(dev->pci, &buf->risc,
566 buf->vb.dma.sglist, 0, UNSET,
567 buf->bpl, 0, buf->vb.height);
568 break;
569 case V4L2_FIELD_BOTTOM:
570 cx88_risc_buffer(dev->pci, &buf->risc,
571 buf->vb.dma.sglist, UNSET, 0,
572 buf->bpl, 0, buf->vb.height);
573 break;
574 case V4L2_FIELD_INTERLACED:
575 cx88_risc_buffer(dev->pci, &buf->risc,
576 buf->vb.dma.sglist, 0, buf->bpl,
577 buf->bpl, buf->bpl,
578 buf->vb.height >> 1);
579 break;
580 case V4L2_FIELD_SEQ_TB:
581 cx88_risc_buffer(dev->pci, &buf->risc,
582 buf->vb.dma.sglist,
583 0, buf->bpl * (buf->vb.height >> 1),
584 buf->bpl, 0,
585 buf->vb.height >> 1);
586 break;
587 case V4L2_FIELD_SEQ_BT:
588 cx88_risc_buffer(dev->pci, &buf->risc,
589 buf->vb.dma.sglist,
590 buf->bpl * (buf->vb.height >> 1), 0,
591 buf->bpl, 0,
592 buf->vb.height >> 1);
593 break;
594 default:
595 BUG();
596 }
597 }
598 dprintk(2,"[%p/%d] buffer_prepare - %dx%d %dbpp \"%s\" - dma=0x%08lx\n",
599 buf, buf->vb.i,
600 fh->width, fh->height, fh->fmt->depth, fh->fmt->name,
601 (unsigned long)buf->risc.dma);
602
603 buf->vb.state = STATE_PREPARED;
604 return 0;
605
606 fail:
607 cx88_free_buffer(dev->pci,buf);
608 return rc;
609}
610
611static void
612buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
613{
614 struct cx88_buffer *buf = container_of(vb,struct cx88_buffer,vb);
615 struct cx88_buffer *prev;
616 struct cx8800_fh *fh = vq->priv_data;
617 struct cx8800_dev *dev = fh->dev;
618 struct cx88_dmaqueue *q = &dev->vidq;
619
620 /* add jump to stopper */
621 buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
622 buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
623
624 if (!list_empty(&q->queued)) {
625 list_add_tail(&buf->vb.queue,&q->queued);
626 buf->vb.state = STATE_QUEUED;
627 dprintk(2,"[%p/%d] buffer_queue - append to queued\n",
628 buf, buf->vb.i);
629
630 } else if (list_empty(&q->active)) {
631 list_add_tail(&buf->vb.queue,&q->active);
632 start_video_dma(dev, q, buf);
633 buf->vb.state = STATE_ACTIVE;
634 buf->count = q->count++;
635 mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
636 dprintk(2,"[%p/%d] buffer_queue - first active\n",
637 buf, buf->vb.i);
638
639 } else {
640 prev = list_entry(q->active.prev, struct cx88_buffer, vb.queue);
641 if (prev->vb.width == buf->vb.width &&
642 prev->vb.height == buf->vb.height &&
643 prev->fmt == buf->fmt) {
644 list_add_tail(&buf->vb.queue,&q->active);
645 buf->vb.state = STATE_ACTIVE;
646 buf->count = q->count++;
647 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
648 dprintk(2,"[%p/%d] buffer_queue - append to active\n",
649 buf, buf->vb.i);
650
651 } else {
652 list_add_tail(&buf->vb.queue,&q->queued);
653 buf->vb.state = STATE_QUEUED;
654 dprintk(2,"[%p/%d] buffer_queue - first queued\n",
655 buf, buf->vb.i);
656 }
657 }
658}
659
660static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
661{
662 struct cx88_buffer *buf = container_of(vb,struct cx88_buffer,vb);
663 struct cx8800_fh *fh = q->priv_data;
664
665 cx88_free_buffer(fh->dev->pci,buf);
666}
667
668struct videobuf_queue_ops cx8800_video_qops = {
669 .buf_setup = buffer_setup,
670 .buf_prepare = buffer_prepare,
671 .buf_queue = buffer_queue,
672 .buf_release = buffer_release,
673};
674
675/* ------------------------------------------------------------------ */
676
677#if 0 /* overlay support not finished yet */
678static u32* ov_risc_field(struct cx8800_dev *dev, struct cx8800_fh *fh,
679 u32 *rp, struct btcx_skiplist *skips,
680 u32 sync_line, int skip_even, int skip_odd)
681{
682 int line,maxy,start,end,skip,nskips;
683 u32 ri,ra;
684 u32 addr;
685
686 /* sync instruction */
687 *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line);
688
689 addr = (unsigned long)dev->fbuf.base;
690 addr += dev->fbuf.fmt.bytesperline * fh->win.w.top;
691 addr += (fh->fmt->depth >> 3) * fh->win.w.left;
692
693 /* scan lines */
694 for (maxy = -1, line = 0; line < fh->win.w.height;
695 line++, addr += dev->fbuf.fmt.bytesperline) {
696 if ((line%2) == 0 && skip_even)
697 continue;
698 if ((line%2) == 1 && skip_odd)
699 continue;
700
701 /* calculate clipping */
702 if (line > maxy)
703 btcx_calc_skips(line, fh->win.w.width, &maxy,
704 skips, &nskips, fh->clips, fh->nclips);
705
706 /* write out risc code */
707 for (start = 0, skip = 0; start < fh->win.w.width; start = end) {
708 if (skip >= nskips) {
709 ri = RISC_WRITE;
710 end = fh->win.w.width;
711 } else if (start < skips[skip].start) {
712 ri = RISC_WRITE;
713 end = skips[skip].start;
714 } else {
715 ri = RISC_SKIP;
716 end = skips[skip].end;
717 skip++;
718 }
719 if (RISC_WRITE == ri)
720 ra = addr + (fh->fmt->depth>>3)*start;
721 else
722 ra = 0;
723
724 if (0 == start)
725 ri |= RISC_SOL;
726 if (fh->win.w.width == end)
727 ri |= RISC_EOL;
728 ri |= (fh->fmt->depth>>3) * (end-start);
729
730 *(rp++)=cpu_to_le32(ri);
731 if (0 != ra)
732 *(rp++)=cpu_to_le32(ra);
733 }
734 }
735 kfree(skips);
736 return rp;
737}
738
739static int ov_risc_frame(struct cx8800_dev *dev, struct cx8800_fh *fh,
740 struct cx88_buffer *buf)
741{
742 struct btcx_skiplist *skips;
743 u32 instructions,fields;
744 u32 *rp;
745 int rc;
746
747 /* skip list for window clipping */
748 if (NULL == (skips = kmalloc(sizeof(*skips) * fh->nclips,GFP_KERNEL)))
749 return -ENOMEM;
750
751 fields = 0;
752 if (V4L2_FIELD_HAS_TOP(fh->win.field))
753 fields++;
754 if (V4L2_FIELD_HAS_BOTTOM(fh->win.field))
755 fields++;
756
757 /* estimate risc mem: worst case is (clip+1) * lines instructions
758 + syncs + jump (all 2 dwords) */
759 instructions = (fh->nclips+1) * fh->win.w.height;
760 instructions += 3 + 4;
761 if ((rc = btcx_riscmem_alloc(dev->pci,&buf->risc,instructions*8)) < 0) {
762 kfree(skips);
763 return rc;
764 }
765
766 /* write risc instructions */
767 rp = buf->risc.cpu;
768 switch (fh->win.field) {
769 case V4L2_FIELD_TOP:
770 rp = ov_risc_field(dev, fh, rp, skips, 0, 0, 0);
771 break;
772 case V4L2_FIELD_BOTTOM:
773 rp = ov_risc_field(dev, fh, rp, skips, 0x200, 0, 0);
774 break;
775 case V4L2_FIELD_INTERLACED:
776 rp = ov_risc_field(dev, fh, rp, skips, 0, 0, 1);
777 rp = ov_risc_field(dev, fh, rp, skips, 0x200, 1, 0);
778 break;
779 default:
780 BUG();
781 }
782
783 /* save pointer to jmp instruction address */
784 buf->risc.jmp = rp;
785 kfree(skips);
786 return 0;
787}
788
789static int verify_window(struct cx8800_dev *dev, struct v4l2_window *win)
790{
791 enum v4l2_field field;
792 int maxw, maxh;
793
794 if (NULL == dev->fbuf.base)
795 return -EINVAL;
796 if (win->w.width < 48 || win->w.height < 32)
797 return -EINVAL;
798 if (win->clipcount > 2048)
799 return -EINVAL;
800
801 field = win->field;
802 maxw = norm_maxw(core->tvnorm);
803 maxh = norm_maxh(core->tvnorm);
804
805 if (V4L2_FIELD_ANY == field) {
806 field = (win->w.height > maxh/2)
807 ? V4L2_FIELD_INTERLACED
808 : V4L2_FIELD_TOP;
809 }
810 switch (field) {
811 case V4L2_FIELD_TOP:
812 case V4L2_FIELD_BOTTOM:
813 maxh = maxh / 2;
814 break;
815 case V4L2_FIELD_INTERLACED:
816 break;
817 default:
818 return -EINVAL;
819 }
820
821 win->field = field;
822 if (win->w.width > maxw)
823 win->w.width = maxw;
824 if (win->w.height > maxh)
825 win->w.height = maxh;
826 return 0;
827}
828
829static int setup_window(struct cx8800_dev *dev, struct cx8800_fh *fh,
830 struct v4l2_window *win)
831{
832 struct v4l2_clip *clips = NULL;
833 int n,size,retval = 0;
834
835 if (NULL == fh->fmt)
836 return -EINVAL;
837 retval = verify_window(dev,win);
838 if (0 != retval)
839 return retval;
840
841 /* copy clips -- luckily v4l1 + v4l2 are binary
842 compatible here ...*/
843 n = win->clipcount;
844 size = sizeof(*clips)*(n+4);
845 clips = kmalloc(size,GFP_KERNEL);
846 if (NULL == clips)
847 return -ENOMEM;
848 if (n > 0) {
849 if (copy_from_user(clips,win->clips,sizeof(struct v4l2_clip)*n)) {
850 kfree(clips);
851 return -EFAULT;
852 }
853 }
854
855 /* clip against screen */
856 if (NULL != dev->fbuf.base)
857 n = btcx_screen_clips(dev->fbuf.fmt.width, dev->fbuf.fmt.height,
858 &win->w, clips, n);
859 btcx_sort_clips(clips,n);
860
861 /* 4-byte alignments */
862 switch (fh->fmt->depth) {
863 case 8:
864 case 24:
865 btcx_align(&win->w, clips, n, 3);
866 break;
867 case 16:
868 btcx_align(&win->w, clips, n, 1);
869 break;
870 case 32:
871 /* no alignment fixups needed */
872 break;
873 default:
874 BUG();
875 }
876
877 down(&fh->vidq.lock);
878 if (fh->clips)
879 kfree(fh->clips);
880 fh->clips = clips;
881 fh->nclips = n;
882 fh->win = *win;
883#if 0
884 fh->ov.setup_ok = 1;
885#endif
886
887 /* update overlay if needed */
888 retval = 0;
889#if 0
890 if (check_btres(fh, RESOURCE_OVERLAY)) {
891 struct bttv_buffer *new;
892
893 new = videobuf_alloc(sizeof(*new));
894 bttv_overlay_risc(btv, &fh->ov, fh->ovfmt, new);
895 retval = bttv_switch_overlay(btv,fh,new);
896 }
897#endif
898 up(&fh->vidq.lock);
899 return retval;
900}
901#endif
902
903/* ------------------------------------------------------------------ */
904
905static struct videobuf_queue* get_queue(struct cx8800_fh *fh)
906{
907 switch (fh->type) {
908 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
909 return &fh->vidq;
910 case V4L2_BUF_TYPE_VBI_CAPTURE:
911 return &fh->vbiq;
912 default:
913 BUG();
914 return NULL;
915 }
916}
917
918static int get_ressource(struct cx8800_fh *fh)
919{
920 switch (fh->type) {
921 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
922 return RESOURCE_VIDEO;
923 case V4L2_BUF_TYPE_VBI_CAPTURE:
924 return RESOURCE_VBI;
925 default:
926 BUG();
927 return 0;
928 }
929}
930
931static int video_open(struct inode *inode, struct file *file)
932{
933 int minor = iminor(inode);
934 struct cx8800_dev *h,*dev = NULL;
935 struct cx8800_fh *fh;
936 struct list_head *list;
937 enum v4l2_buf_type type = 0;
938 int radio = 0;
939
940 list_for_each(list,&cx8800_devlist) {
941 h = list_entry(list, struct cx8800_dev, devlist);
942 if (h->video_dev->minor == minor) {
943 dev = h;
944 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
945 }
946 if (h->vbi_dev->minor == minor) {
947 dev = h;
948 type = V4L2_BUF_TYPE_VBI_CAPTURE;
949 }
950 if (h->radio_dev &&
951 h->radio_dev->minor == minor) {
952 radio = 1;
953 dev = h;
954 }
955 }
956 if (NULL == dev)
957 return -ENODEV;
958
959 dprintk(1,"open minor=%d radio=%d type=%s\n",
960 minor,radio,v4l2_type_names[type]);
961
962 /* allocate + initialize per filehandle data */
963 fh = kmalloc(sizeof(*fh),GFP_KERNEL);
964 if (NULL == fh)
965 return -ENOMEM;
966 memset(fh,0,sizeof(*fh));
967 file->private_data = fh;
968 fh->dev = dev;
969 fh->radio = radio;
970 fh->type = type;
971 fh->width = 320;
972 fh->height = 240;
973 fh->fmt = format_by_fourcc(V4L2_PIX_FMT_BGR24);
974
975 videobuf_queue_init(&fh->vidq, &cx8800_video_qops,
976 dev->pci, &dev->slock,
977 V4L2_BUF_TYPE_VIDEO_CAPTURE,
978 V4L2_FIELD_INTERLACED,
979 sizeof(struct cx88_buffer),
980 fh);
981 videobuf_queue_init(&fh->vbiq, &cx8800_vbi_qops,
982 dev->pci, &dev->slock,
983 V4L2_BUF_TYPE_VBI_CAPTURE,
984 V4L2_FIELD_SEQ_TB,
985 sizeof(struct cx88_buffer),
986 fh);
987
988 if (fh->radio) {
989 struct cx88_core *core = dev->core;
990 int board = core->board;
991 dprintk(1,"video_open: setting radio device\n");
992 cx_write(MO_GP0_IO, cx88_boards[board].radio.gpio0);
993 cx_write(MO_GP1_IO, cx88_boards[board].radio.gpio1);
994 cx_write(MO_GP2_IO, cx88_boards[board].radio.gpio2);
995 cx_write(MO_GP3_IO, cx88_boards[board].radio.gpio3);
996 dev->core->tvaudio = WW_FM;
997 cx88_set_tvaudio(core);
998 cx88_set_stereo(core,V4L2_TUNER_MODE_STEREO,1);
999 cx88_call_i2c_clients(dev->core,AUDC_SET_RADIO,NULL);
1000 }
1001
1002 return 0;
1003}
1004
1005static ssize_t
1006video_read(struct file *file, char *data, size_t count, loff_t *ppos)
1007{
1008 struct cx8800_fh *fh = file->private_data;
1009
1010 switch (fh->type) {
1011 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1012 if (res_locked(fh->dev,RESOURCE_VIDEO))
1013 return -EBUSY;
1014 return videobuf_read_one(&fh->vidq, data, count, ppos,
1015 file->f_flags & O_NONBLOCK);
1016 case V4L2_BUF_TYPE_VBI_CAPTURE:
1017 if (!res_get(fh->dev,fh,RESOURCE_VBI))
1018 return -EBUSY;
1019 return videobuf_read_stream(&fh->vbiq, data, count, ppos, 1,
1020 file->f_flags & O_NONBLOCK);
1021 default:
1022 BUG();
1023 return 0;
1024 }
1025}
1026
1027static unsigned int
1028video_poll(struct file *file, struct poll_table_struct *wait)
1029{
1030 struct cx8800_fh *fh = file->private_data;
1031 struct cx88_buffer *buf;
1032
1033 if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) {
1034 if (!res_get(fh->dev,fh,RESOURCE_VBI))
1035 return POLLERR;
1036 return videobuf_poll_stream(file, &fh->vbiq, wait);
1037 }
1038
1039 if (res_check(fh,RESOURCE_VIDEO)) {
1040 /* streaming capture */
1041 if (list_empty(&fh->vidq.stream))
1042 return POLLERR;
1043 buf = list_entry(fh->vidq.stream.next,struct cx88_buffer,vb.stream);
1044 } else {
1045 /* read() capture */
1046 buf = (struct cx88_buffer*)fh->vidq.read_buf;
1047 if (NULL == buf)
1048 return POLLERR;
1049 }
1050 poll_wait(file, &buf->vb.done, wait);
1051 if (buf->vb.state == STATE_DONE ||
1052 buf->vb.state == STATE_ERROR)
1053 return POLLIN|POLLRDNORM;
1054 return 0;
1055}
1056
1057static int video_release(struct inode *inode, struct file *file)
1058{
1059 struct cx8800_fh *fh = file->private_data;
1060 struct cx8800_dev *dev = fh->dev;
1061
1062 /* turn off overlay */
1063 if (res_check(fh, RESOURCE_OVERLAY)) {
1064 /* FIXME */
1065 res_free(dev,fh,RESOURCE_OVERLAY);
1066 }
1067
1068 /* stop video capture */
1069 if (res_check(fh, RESOURCE_VIDEO)) {
1070 videobuf_queue_cancel(&fh->vidq);
1071 res_free(dev,fh,RESOURCE_VIDEO);
1072 }
1073 if (fh->vidq.read_buf) {
1074 buffer_release(&fh->vidq,fh->vidq.read_buf);
1075 kfree(fh->vidq.read_buf);
1076 }
1077
1078 /* stop vbi capture */
1079 if (res_check(fh, RESOURCE_VBI)) {
1080 if (fh->vbiq.streaming)
1081 videobuf_streamoff(&fh->vbiq);
1082 if (fh->vbiq.reading)
1083 videobuf_read_stop(&fh->vbiq);
1084 res_free(dev,fh,RESOURCE_VBI);
1085 }
1086
1087 videobuf_mmap_free(&fh->vidq);
1088 videobuf_mmap_free(&fh->vbiq);
1089 file->private_data = NULL;
1090 kfree(fh);
1091 return 0;
1092}
1093
1094static int
1095video_mmap(struct file *file, struct vm_area_struct * vma)
1096{
1097 struct cx8800_fh *fh = file->private_data;
1098
1099 return videobuf_mmap_mapper(get_queue(fh), vma);
1100}
1101
1102/* ------------------------------------------------------------------ */
1103
1104static int get_control(struct cx8800_dev *dev, struct v4l2_control *ctl)
1105{
1106 struct cx88_core *core = dev->core;
1107 struct cx88_ctrl *c = NULL;
1108 u32 value;
1109 int i;
1110
1111 for (i = 0; i < CX8800_CTLS; i++)
1112 if (cx8800_ctls[i].v.id == ctl->id)
1113 c = &cx8800_ctls[i];
1114 if (NULL == c)
1115 return -EINVAL;
1116
1117 value = c->sreg ? cx_sread(c->sreg) : cx_read(c->reg);
1118 switch (ctl->id) {
1119 case V4L2_CID_AUDIO_BALANCE:
1120 ctl->value = (value & 0x40) ? (value & 0x3f) : (0x40 - (value & 0x3f));
1121 break;
1122 case V4L2_CID_AUDIO_VOLUME:
1123 ctl->value = 0x3f - (value & 0x3f);
1124 break;
1125 default:
1126 ctl->value = ((value + (c->off << c->shift)) & c->mask) >> c->shift;
1127 break;
1128 }
1129 return 0;
1130}
1131
1132static int set_control(struct cx8800_dev *dev, struct v4l2_control *ctl)
1133{
1134 struct cx88_core *core = dev->core;
1135 struct cx88_ctrl *c = NULL;
1136 u32 v_sat_value;
1137 u32 value;
1138 int i;
1139
1140 for (i = 0; i < CX8800_CTLS; i++)
1141 if (cx8800_ctls[i].v.id == ctl->id)
1142 c = &cx8800_ctls[i];
1143 if (NULL == c)
1144 return -EINVAL;
1145
1146 if (ctl->value < c->v.minimum)
1147 return -ERANGE;
1148 if (ctl->value > c->v.maximum)
1149 return -ERANGE;
1150 switch (ctl->id) {
1151 case V4L2_CID_AUDIO_BALANCE:
1152 value = (ctl->value < 0x40) ? (0x40 - ctl->value) : ctl->value;
1153 break;
1154 case V4L2_CID_AUDIO_VOLUME:
1155 value = 0x3f - (ctl->value & 0x3f);
1156 break;
1157 case V4L2_CID_SATURATION:
1158 /* special v_sat handling */
1159 v_sat_value = ctl->value - (0x7f - 0x5a);
1160 if (v_sat_value > 0xff)
1161 v_sat_value = 0xff;
1162 if (v_sat_value < 0x00)
1163 v_sat_value = 0x00;
1164 cx_andor(MO_UV_SATURATION, 0xff00, v_sat_value << 8);
1165 /* fall through to default route for u_sat */
1166 default:
1167 value = ((ctl->value - c->off) << c->shift) & c->mask;
1168 break;
1169 }
1170 dprintk(1,"set_control id=0x%X reg=0x%x val=0x%x%s\n",
1171 ctl->id, c->reg, value, c->sreg ? " [shadowed]" : "");
1172 if (c->sreg) {
1173 cx_sandor(c->sreg, c->reg, c->mask, value);
1174 } else {
1175 cx_andor(c->reg, c->mask, value);
1176 }
1177 return 0;
1178}
1179
1180static void init_controls(struct cx8800_dev *dev)
1181{
1182 static struct v4l2_control mute = {
1183 .id = V4L2_CID_AUDIO_MUTE,
1184 .value = 1,
1185 };
1186 static struct v4l2_control volume = {
1187 .id = V4L2_CID_AUDIO_VOLUME,
1188 .value = 0x3f,
1189 };
1190
1191 set_control(dev,&mute);
1192 set_control(dev,&volume);
1193}
1194
1195/* ------------------------------------------------------------------ */
1196
1197static int cx8800_g_fmt(struct cx8800_dev *dev, struct cx8800_fh *fh,
1198 struct v4l2_format *f)
1199{
1200 switch (f->type) {
1201 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1202 memset(&f->fmt.pix,0,sizeof(f->fmt.pix));
1203 f->fmt.pix.width = fh->width;
1204 f->fmt.pix.height = fh->height;
1205 f->fmt.pix.field = fh->vidq.field;
1206 f->fmt.pix.pixelformat = fh->fmt->fourcc;
1207 f->fmt.pix.bytesperline =
1208 (f->fmt.pix.width * fh->fmt->depth) >> 3;
1209 f->fmt.pix.sizeimage =
1210 f->fmt.pix.height * f->fmt.pix.bytesperline;
1211 return 0;
1212 case V4L2_BUF_TYPE_VBI_CAPTURE:
1213 cx8800_vbi_fmt(dev, f);
1214 return 0;
1215 default:
1216 return -EINVAL;
1217 }
1218}
1219
1220static int cx8800_try_fmt(struct cx8800_dev *dev, struct cx8800_fh *fh,
1221 struct v4l2_format *f)
1222{
1223 switch (f->type) {
1224 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1225 {
1226 struct cx8800_fmt *fmt;
1227 enum v4l2_field field;
1228 unsigned int maxw, maxh;
1229
1230 fmt = format_by_fourcc(f->fmt.pix.pixelformat);
1231 if (NULL == fmt)
1232 return -EINVAL;
1233
1234 field = f->fmt.pix.field;
1235 maxw = norm_maxw(dev->core->tvnorm);
1236 maxh = norm_maxh(dev->core->tvnorm);
1237
1238 if (V4L2_FIELD_ANY == field) {
1239 field = (f->fmt.pix.height > maxh/2)
1240 ? V4L2_FIELD_INTERLACED
1241 : V4L2_FIELD_BOTTOM;
1242 }
1243
1244 switch (field) {
1245 case V4L2_FIELD_TOP:
1246 case V4L2_FIELD_BOTTOM:
1247 maxh = maxh / 2;
1248 break;
1249 case V4L2_FIELD_INTERLACED:
1250 break;
1251 default:
1252 return -EINVAL;
1253 }
1254
1255 f->fmt.pix.field = field;
1256 if (f->fmt.pix.height < 32)
1257 f->fmt.pix.height = 32;
1258 if (f->fmt.pix.height > maxh)
1259 f->fmt.pix.height = maxh;
1260 if (f->fmt.pix.width < 48)
1261 f->fmt.pix.width = 48;
1262 if (f->fmt.pix.width > maxw)
1263 f->fmt.pix.width = maxw;
1264 f->fmt.pix.width &= ~0x03;
1265 f->fmt.pix.bytesperline =
1266 (f->fmt.pix.width * fmt->depth) >> 3;
1267 f->fmt.pix.sizeimage =
1268 f->fmt.pix.height * f->fmt.pix.bytesperline;
1269
1270 return 0;
1271 }
1272 case V4L2_BUF_TYPE_VBI_CAPTURE:
1273 cx8800_vbi_fmt(dev, f);
1274 return 0;
1275 default:
1276 return -EINVAL;
1277 }
1278}
1279
1280static int cx8800_s_fmt(struct cx8800_dev *dev, struct cx8800_fh *fh,
1281 struct v4l2_format *f)
1282{
1283 int err;
1284
1285 switch (f->type) {
1286 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1287 err = cx8800_try_fmt(dev,fh,f);
1288 if (0 != err)
1289 return err;
1290
1291 fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
1292 fh->width = f->fmt.pix.width;
1293 fh->height = f->fmt.pix.height;
1294 fh->vidq.field = f->fmt.pix.field;
1295 return 0;
1296 case V4L2_BUF_TYPE_VBI_CAPTURE:
1297 cx8800_vbi_fmt(dev, f);
1298 return 0;
1299 default:
1300 return -EINVAL;
1301 }
1302}
1303
1304/*
1305 * This function is _not_ called directly, but from
1306 * video_generic_ioctl (and maybe others). userspace
1307 * copying is done already, arg is a kernel pointer.
1308 */
1309static int video_do_ioctl(struct inode *inode, struct file *file,
1310 unsigned int cmd, void *arg)
1311{
1312 struct cx8800_fh *fh = file->private_data;
1313 struct cx8800_dev *dev = fh->dev;
1314 struct cx88_core *core = dev->core;
1315#if 0
1316 unsigned long flags;
1317#endif
1318 int err;
1319
1320 if (video_debug > 1)
1321 cx88_print_ioctl(core->name,cmd);
1322 switch (cmd) {
1323 case VIDIOC_QUERYCAP:
1324 {
1325 struct v4l2_capability *cap = arg;
1326
1327 memset(cap,0,sizeof(*cap));
1328 strcpy(cap->driver, "cx8800");
1329 strlcpy(cap->card, cx88_boards[core->board].name,
1330 sizeof(cap->card));
1331 sprintf(cap->bus_info,"PCI:%s",pci_name(dev->pci));
1332 cap->version = CX88_VERSION_CODE;
1333 cap->capabilities =
1334 V4L2_CAP_VIDEO_CAPTURE |
1335 V4L2_CAP_READWRITE |
1336 V4L2_CAP_STREAMING |
1337 V4L2_CAP_VBI_CAPTURE |
1338#if 0
1339 V4L2_CAP_VIDEO_OVERLAY |
1340#endif
1341 0;
1342 if (UNSET != core->tuner_type)
1343 cap->capabilities |= V4L2_CAP_TUNER;
1344 return 0;
1345 }
1346
1347 /* ---------- tv norms ---------- */
1348 case VIDIOC_ENUMSTD:
1349 {
1350 struct v4l2_standard *e = arg;
1351 unsigned int i;
1352
1353 i = e->index;
1354 if (i >= ARRAY_SIZE(tvnorms))
1355 return -EINVAL;
1356 err = v4l2_video_std_construct(e, tvnorms[e->index].id,
1357 tvnorms[e->index].name);
1358 e->index = i;
1359 if (err < 0)
1360 return err;
1361 return 0;
1362 }
1363 case VIDIOC_G_STD:
1364 {
1365 v4l2_std_id *id = arg;
1366
1367 *id = core->tvnorm->id;
1368 return 0;
1369 }
1370 case VIDIOC_S_STD:
1371 {
1372 v4l2_std_id *id = arg;
1373 unsigned int i;
1374
1375 for(i = 0; i < ARRAY_SIZE(tvnorms); i++)
1376 if (*id & tvnorms[i].id)
1377 break;
1378 if (i == ARRAY_SIZE(tvnorms))
1379 return -EINVAL;
1380
1381 down(&dev->lock);
1382 cx88_set_tvnorm(dev->core,&tvnorms[i]);
1383 up(&dev->lock);
1384 return 0;
1385 }
1386
1387 /* ------ input switching ---------- */
1388 case VIDIOC_ENUMINPUT:
1389 {
1390 static const char *iname[] = {
1391 [ CX88_VMUX_COMPOSITE1 ] = "Composite1",
1392 [ CX88_VMUX_COMPOSITE2 ] = "Composite2",
1393 [ CX88_VMUX_COMPOSITE3 ] = "Composite3",
1394 [ CX88_VMUX_COMPOSITE4 ] = "Composite4",
1395 [ CX88_VMUX_SVIDEO ] = "S-Video",
1396 [ CX88_VMUX_TELEVISION ] = "Television",
1397 [ CX88_VMUX_CABLE ] = "Cable TV",
1398 [ CX88_VMUX_DVB ] = "DVB",
1399 [ CX88_VMUX_DEBUG ] = "for debug only",
1400 };
1401 struct v4l2_input *i = arg;
1402 unsigned int n;
1403
1404 n = i->index;
1405 if (n >= 4)
1406 return -EINVAL;
1407 if (0 == INPUT(n)->type)
1408 return -EINVAL;
1409 memset(i,0,sizeof(*i));
1410 i->index = n;
1411 i->type = V4L2_INPUT_TYPE_CAMERA;
1412 strcpy(i->name,iname[INPUT(n)->type]);
1413 if ((CX88_VMUX_TELEVISION == INPUT(n)->type) ||
1414 (CX88_VMUX_CABLE == INPUT(n)->type))
1415 i->type = V4L2_INPUT_TYPE_TUNER;
1416 for (n = 0; n < ARRAY_SIZE(tvnorms); n++)
1417 i->std |= tvnorms[n].id;
1418 return 0;
1419 }
1420 case VIDIOC_G_INPUT:
1421 {
1422 unsigned int *i = arg;
1423
1424 *i = dev->core->input;
1425 return 0;
1426 }
1427 case VIDIOC_S_INPUT:
1428 {
1429 unsigned int *i = arg;
1430
1431 if (*i >= 4)
1432 return -EINVAL;
1433 down(&dev->lock);
1434 cx88_newstation(core);
1435 video_mux(dev,*i);
1436 up(&dev->lock);
1437 return 0;
1438 }
1439
1440
1441#if 0
1442 /* needs review */
1443 case VIDIOC_G_AUDIO:
1444 {
1445 struct v4l2_audio *a = arg;
1446 unsigned int n = a->index;
1447
1448 memset(a,0,sizeof(*a));
1449 a->index = n;
1450 switch (n) {
1451 case 0:
1452 if ((CX88_VMUX_TELEVISION == INPUT(n)->type)
1453 || (CX88_VMUX_CABLE == INPUT(n)->type)) {
1454 strcpy(a->name,"Television");
1455 // FIXME figure out if stereo received and set V4L2_AUDCAP_STEREO.
1456 return 0;
1457 }
1458 break;
1459 case 1:
1460 if (CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD == core->board) {
1461 strcpy(a->name,"Line In");
1462 a->capability = V4L2_AUDCAP_STEREO;
1463 return 0;
1464 }
1465 break;
1466 }
1467 // Audio input not available.
1468 return -EINVAL;
1469 }
1470#endif
1471
1472 /* --- capture ioctls ---------------------------------------- */
1473 case VIDIOC_ENUM_FMT:
1474 {
1475 struct v4l2_fmtdesc *f = arg;
1476 enum v4l2_buf_type type;
1477 unsigned int index;
1478
1479 index = f->index;
1480 type = f->type;
1481 switch (type) {
1482 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1483 if (index >= ARRAY_SIZE(formats))
1484 return -EINVAL;
1485 memset(f,0,sizeof(*f));
1486 f->index = index;
1487 f->type = type;
1488 strlcpy(f->description,formats[index].name,sizeof(f->description));
1489 f->pixelformat = formats[index].fourcc;
1490 break;
1491 default:
1492 return -EINVAL;
1493 }
1494 return 0;
1495 }
1496 case VIDIOC_G_FMT:
1497 {
1498 struct v4l2_format *f = arg;
1499 return cx8800_g_fmt(dev,fh,f);
1500 }
1501 case VIDIOC_S_FMT:
1502 {
1503 struct v4l2_format *f = arg;
1504 return cx8800_s_fmt(dev,fh,f);
1505 }
1506 case VIDIOC_TRY_FMT:
1507 {
1508 struct v4l2_format *f = arg;
1509 return cx8800_try_fmt(dev,fh,f);
1510 }
1511
1512 /* --- controls ---------------------------------------------- */
1513 case VIDIOC_QUERYCTRL:
1514 {
1515 struct v4l2_queryctrl *c = arg;
1516 int i;
1517
1518 if (c->id < V4L2_CID_BASE ||
1519 c->id >= V4L2_CID_LASTP1)
1520 return -EINVAL;
1521 for (i = 0; i < CX8800_CTLS; i++)
1522 if (cx8800_ctls[i].v.id == c->id)
1523 break;
1524 if (i == CX8800_CTLS) {
1525 *c = no_ctl;
1526 return 0;
1527 }
1528 *c = cx8800_ctls[i].v;
1529 return 0;
1530 }
1531 case VIDIOC_G_CTRL:
1532 return get_control(dev,arg);
1533 case VIDIOC_S_CTRL:
1534 return set_control(dev,arg);
1535
1536 /* --- tuner ioctls ------------------------------------------ */
1537 case VIDIOC_G_TUNER:
1538 {
1539 struct v4l2_tuner *t = arg;
1540 u32 reg;
1541
1542 if (UNSET == core->tuner_type)
1543 return -EINVAL;
1544 if (0 != t->index)
1545 return -EINVAL;
1546
1547 memset(t,0,sizeof(*t));
1548 strcpy(t->name, "Television");
1549 t->type = V4L2_TUNER_ANALOG_TV;
1550 t->capability = V4L2_TUNER_CAP_NORM;
1551 t->rangehigh = 0xffffffffUL;
1552
1553 cx88_get_stereo(core ,t);
1554 reg = cx_read(MO_DEVICE_STATUS);
1555 t->signal = (reg & (1<<5)) ? 0xffff : 0x0000;
1556 return 0;
1557 }
1558 case VIDIOC_S_TUNER:
1559 {
1560 struct v4l2_tuner *t = arg;
1561
1562 if (UNSET == core->tuner_type)
1563 return -EINVAL;
1564 if (0 != t->index)
1565 return -EINVAL;
1566 cx88_set_stereo(core, t->audmode, 1);
1567 return 0;
1568 }
1569 case VIDIOC_G_FREQUENCY:
1570 {
1571 struct v4l2_frequency *f = arg;
1572
1573 if (UNSET == core->tuner_type)
1574 return -EINVAL;
1575 if (f->tuner != 0)
1576 return -EINVAL;
1577 memset(f,0,sizeof(*f));
1578 f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
1579 f->frequency = dev->freq;
1580 return 0;
1581 }
1582 case VIDIOC_S_FREQUENCY:
1583 {
1584 struct v4l2_frequency *f = arg;
1585
1586 if (UNSET == core->tuner_type)
1587 return -EINVAL;
1588 if (f->tuner != 0)
1589 return -EINVAL;
1590 if (0 == fh->radio && f->type != V4L2_TUNER_ANALOG_TV)
1591 return -EINVAL;
1592 if (1 == fh->radio && f->type != V4L2_TUNER_RADIO)
1593 return -EINVAL;
1594 down(&dev->lock);
1595 dev->freq = f->frequency;
1596 cx88_newstation(core);
1597#ifdef V4L2_I2C_CLIENTS
1598 cx88_call_i2c_clients(dev->core,VIDIOC_S_FREQUENCY,f);
1599#else
1600 cx88_call_i2c_clients(dev->core,VIDIOCSFREQ,&dev->freq);
1601#endif
1602 up(&dev->lock);
1603 return 0;
1604 }
1605
1606 /* --- streaming capture ------------------------------------- */
1607 case VIDIOCGMBUF:
1608 {
1609 struct video_mbuf *mbuf = arg;
1610 struct videobuf_queue *q;
1611 struct v4l2_requestbuffers req;
1612 unsigned int i;
1613
1614 q = get_queue(fh);
1615 memset(&req,0,sizeof(req));
1616 req.type = q->type;
1617 req.count = 8;
1618 req.memory = V4L2_MEMORY_MMAP;
1619 err = videobuf_reqbufs(q,&req);
1620 if (err < 0)
1621 return err;
1622 memset(mbuf,0,sizeof(*mbuf));
1623 mbuf->frames = req.count;
1624 mbuf->size = 0;
1625 for (i = 0; i < mbuf->frames; i++) {
1626 mbuf->offsets[i] = q->bufs[i]->boff;
1627 mbuf->size += q->bufs[i]->bsize;
1628 }
1629 return 0;
1630 }
1631 case VIDIOC_REQBUFS:
1632 return videobuf_reqbufs(get_queue(fh), arg);
1633
1634 case VIDIOC_QUERYBUF:
1635 return videobuf_querybuf(get_queue(fh), arg);
1636
1637 case VIDIOC_QBUF:
1638 return videobuf_qbuf(get_queue(fh), arg);
1639
1640 case VIDIOC_DQBUF:
1641 return videobuf_dqbuf(get_queue(fh), arg,
1642 file->f_flags & O_NONBLOCK);
1643
1644 case VIDIOC_STREAMON:
1645 {
1646 int res = get_ressource(fh);
1647
1648 if (!res_get(dev,fh,res))
1649 return -EBUSY;
1650 return videobuf_streamon(get_queue(fh));
1651 }
1652 case VIDIOC_STREAMOFF:
1653 {
1654 int res = get_ressource(fh);
1655
1656 err = videobuf_streamoff(get_queue(fh));
1657 if (err < 0)
1658 return err;
1659 res_free(dev,fh,res);
1660 return 0;
1661 }
1662
1663 default:
1664 return v4l_compat_translate_ioctl(inode,file,cmd,arg,
1665 video_do_ioctl);
1666 }
1667 return 0;
1668}
1669
1670static int video_ioctl(struct inode *inode, struct file *file,
1671 unsigned int cmd, unsigned long arg)
1672{
1673 return video_usercopy(inode, file, cmd, arg, video_do_ioctl);
1674}
1675
1676/* ----------------------------------------------------------- */
1677
1678static int radio_do_ioctl(struct inode *inode, struct file *file,
1679 unsigned int cmd, void *arg)
1680{
1681 struct cx8800_fh *fh = file->private_data;
1682 struct cx8800_dev *dev = fh->dev;
1683 struct cx88_core *core = dev->core;
1684
1685 if (video_debug > 1)
1686 cx88_print_ioctl(core->name,cmd);
1687
1688 switch (cmd) {
1689 case VIDIOC_QUERYCAP:
1690 {
1691 struct v4l2_capability *cap = arg;
1692
1693 memset(cap,0,sizeof(*cap));
1694 strcpy(cap->driver, "cx8800");
1695 strlcpy(cap->card, cx88_boards[core->board].name,
1696 sizeof(cap->card));
1697 sprintf(cap->bus_info,"PCI:%s", pci_name(dev->pci));
1698 cap->version = CX88_VERSION_CODE;
1699 cap->capabilities = V4L2_CAP_TUNER;
1700 return 0;
1701 }
1702 case VIDIOC_G_TUNER:
1703 {
1704 struct v4l2_tuner *t = arg;
1705
1706 if (t->index > 0)
1707 return -EINVAL;
1708
1709 memset(t,0,sizeof(*t));
1710 strcpy(t->name, "Radio");
1711 t->rangelow = (int)(65*16);
1712 t->rangehigh = (int)(108*16);
1713
1714#ifdef V4L2_I2C_CLIENTS
1715 cx88_call_i2c_clients(dev->core,VIDIOC_G_TUNER,t);
1716#else
1717 {
1718 struct video_tuner vt;
1719 memset(&vt,0,sizeof(vt));
1720 cx88_call_i2c_clients(dev,VIDIOCGTUNER,&vt);
1721 t->signal = vt.signal;
1722 }
1723#endif
1724 return 0;
1725 }
1726 case VIDIOC_ENUMINPUT:
1727 {
1728 struct v4l2_input *i = arg;
1729
1730 if (i->index != 0)
1731 return -EINVAL;
1732 strcpy(i->name,"Radio");
1733 i->type = V4L2_INPUT_TYPE_TUNER;
1734 return 0;
1735 }
1736 case VIDIOC_G_INPUT:
1737 {
1738 int *i = arg;
1739 *i = 0;
1740 return 0;
1741 }
1742 case VIDIOC_G_AUDIO:
1743 {
1744 struct v4l2_audio *a = arg;
1745
1746 memset(a,0,sizeof(*a));
1747 strcpy(a->name,"Radio");
1748 return 0;
1749 }
1750 case VIDIOC_G_STD:
1751 {
1752 v4l2_std_id *id = arg;
1753 *id = 0;
1754 return 0;
1755 }
1756 case VIDIOC_S_AUDIO:
1757 case VIDIOC_S_TUNER:
1758 case VIDIOC_S_INPUT:
1759 case VIDIOC_S_STD:
1760 return 0;
1761
1762 case VIDIOC_QUERYCTRL:
1763 {
1764 struct v4l2_queryctrl *c = arg;
1765 int i;
1766
1767 if (c->id < V4L2_CID_BASE ||
1768 c->id >= V4L2_CID_LASTP1)
1769 return -EINVAL;
1770 if (c->id == V4L2_CID_AUDIO_MUTE) {
1771 for (i = 0; i < CX8800_CTLS; i++)
1772 if (cx8800_ctls[i].v.id == c->id)
1773 break;
1774 *c = cx8800_ctls[i].v;
1775 } else
1776 *c = no_ctl;
1777 return 0;
1778 }
1779
1780
1781 case VIDIOC_G_CTRL:
1782 case VIDIOC_S_CTRL:
1783 case VIDIOC_G_FREQUENCY:
1784 case VIDIOC_S_FREQUENCY:
1785 return video_do_ioctl(inode,file,cmd,arg);
1786
1787 default:
1788 return v4l_compat_translate_ioctl(inode,file,cmd,arg,
1789 radio_do_ioctl);
1790 }
1791 return 0;
1792};
1793
1794static int radio_ioctl(struct inode *inode, struct file *file,
1795 unsigned int cmd, unsigned long arg)
1796{
1797 return video_usercopy(inode, file, cmd, arg, radio_do_ioctl);
1798};
1799
1800/* ----------------------------------------------------------- */
1801
1802static void cx8800_vid_timeout(unsigned long data)
1803{
1804 struct cx8800_dev *dev = (struct cx8800_dev*)data;
1805 struct cx88_core *core = dev->core;
1806 struct cx88_dmaqueue *q = &dev->vidq;
1807 struct cx88_buffer *buf;
1808 unsigned long flags;
1809
1810 cx88_sram_channel_dump(dev->core, &cx88_sram_channels[SRAM_CH21]);
1811
1812 cx_clear(MO_VID_DMACNTRL, 0x11);
1813 cx_clear(VID_CAPTURE_CONTROL, 0x06);
1814
1815 spin_lock_irqsave(&dev->slock,flags);
1816 while (!list_empty(&q->active)) {
1817 buf = list_entry(q->active.next, struct cx88_buffer, vb.queue);
1818 list_del(&buf->vb.queue);
1819 buf->vb.state = STATE_ERROR;
1820 wake_up(&buf->vb.done);
1821 printk("%s/0: [%p/%d] timeout - dma=0x%08lx\n", core->name,
1822 buf, buf->vb.i, (unsigned long)buf->risc.dma);
1823 }
1824 restart_video_queue(dev,q);
1825 spin_unlock_irqrestore(&dev->slock,flags);
1826}
1827
1828static void cx8800_vid_irq(struct cx8800_dev *dev)
1829{
1830 struct cx88_core *core = dev->core;
1831 u32 status, mask, count;
1832
1833 status = cx_read(MO_VID_INTSTAT);
1834 mask = cx_read(MO_VID_INTMSK);
1835 if (0 == (status & mask))
1836 return;
1837 cx_write(MO_VID_INTSTAT, status);
1838 if (irq_debug || (status & mask & ~0xff))
1839 cx88_print_irqbits(core->name, "irq vid",
1840 cx88_vid_irqs, status, mask);
1841
1842 /* risc op code error */
1843 if (status & (1 << 16)) {
1844 printk(KERN_WARNING "%s/0: video risc op code error\n",core->name);
1845 cx_clear(MO_VID_DMACNTRL, 0x11);
1846 cx_clear(VID_CAPTURE_CONTROL, 0x06);
1847 cx88_sram_channel_dump(dev->core, &cx88_sram_channels[SRAM_CH21]);
1848 }
1849
1850 /* risc1 y */
1851 if (status & 0x01) {
1852 spin_lock(&dev->slock);
1853 count = cx_read(MO_VIDY_GPCNT);
1854 cx88_wakeup(dev->core, &dev->vidq, count);
1855 spin_unlock(&dev->slock);
1856 }
1857
1858 /* risc1 vbi */
1859 if (status & 0x08) {
1860 spin_lock(&dev->slock);
1861 count = cx_read(MO_VBI_GPCNT);
1862 cx88_wakeup(dev->core, &dev->vbiq, count);
1863 spin_unlock(&dev->slock);
1864 }
1865
1866 /* risc2 y */
1867 if (status & 0x10) {
1868 dprintk(2,"stopper video\n");
1869 spin_lock(&dev->slock);
1870 restart_video_queue(dev,&dev->vidq);
1871 spin_unlock(&dev->slock);
1872 }
1873
1874 /* risc2 vbi */
1875 if (status & 0x80) {
1876 dprintk(2,"stopper vbi\n");
1877 spin_lock(&dev->slock);
1878 cx8800_restart_vbi_queue(dev,&dev->vbiq);
1879 spin_unlock(&dev->slock);
1880 }
1881}
1882
1883static irqreturn_t cx8800_irq(int irq, void *dev_id, struct pt_regs *regs)
1884{
1885 struct cx8800_dev *dev = dev_id;
1886 struct cx88_core *core = dev->core;
1887 u32 status;
1888 int loop, handled = 0;
1889
1890 for (loop = 0; loop < 10; loop++) {
1891 status = cx_read(MO_PCI_INTSTAT) & (core->pci_irqmask | 0x01);
1892 if (0 == status)
1893 goto out;
1894 cx_write(MO_PCI_INTSTAT, status);
1895 handled = 1;
1896
1897 if (status & core->pci_irqmask)
1898 cx88_core_irq(core,status);
1899 if (status & 0x01)
1900 cx8800_vid_irq(dev);
1901 };
1902 if (10 == loop) {
1903 printk(KERN_WARNING "%s/0: irq loop -- clearing mask\n",
1904 core->name);
1905 cx_write(MO_PCI_INTMSK,0);
1906 }
1907
1908 out:
1909 return IRQ_RETVAL(handled);
1910}
1911
1912/* ----------------------------------------------------------- */
1913/* exported stuff */
1914
1915static struct file_operations video_fops =
1916{
1917 .owner = THIS_MODULE,
1918 .open = video_open,
1919 .release = video_release,
1920 .read = video_read,
1921 .poll = video_poll,
1922 .mmap = video_mmap,
1923 .ioctl = video_ioctl,
1924 .llseek = no_llseek,
1925};
1926
1927struct video_device cx8800_video_template =
1928{
1929 .name = "cx8800-video",
1930 .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER|VID_TYPE_SCALES,
1931 .hardware = 0,
1932 .fops = &video_fops,
1933 .minor = -1,
1934};
1935
1936struct video_device cx8800_vbi_template =
1937{
1938 .name = "cx8800-vbi",
1939 .type = VID_TYPE_TELETEXT|VID_TYPE_TUNER,
1940 .hardware = 0,
1941 .fops = &video_fops,
1942 .minor = -1,
1943};
1944
1945static struct file_operations radio_fops =
1946{
1947 .owner = THIS_MODULE,
1948 .open = video_open,
1949 .release = video_release,
1950 .ioctl = radio_ioctl,
1951 .llseek = no_llseek,
1952};
1953
1954struct video_device cx8800_radio_template =
1955{
1956 .name = "cx8800-radio",
1957 .type = VID_TYPE_TUNER,
1958 .hardware = 0,
1959 .fops = &radio_fops,
1960 .minor = -1,
1961};
1962
1963/* ----------------------------------------------------------- */
1964
1965static void cx8800_unregister_video(struct cx8800_dev *dev)
1966{
1967 if (dev->radio_dev) {
1968 if (-1 != dev->radio_dev->minor)
1969 video_unregister_device(dev->radio_dev);
1970 else
1971 video_device_release(dev->radio_dev);
1972 dev->radio_dev = NULL;
1973 }
1974 if (dev->vbi_dev) {
1975 if (-1 != dev->vbi_dev->minor)
1976 video_unregister_device(dev->vbi_dev);
1977 else
1978 video_device_release(dev->vbi_dev);
1979 dev->vbi_dev = NULL;
1980 }
1981 if (dev->video_dev) {
1982 if (-1 != dev->video_dev->minor)
1983 video_unregister_device(dev->video_dev);
1984 else
1985 video_device_release(dev->video_dev);
1986 dev->video_dev = NULL;
1987 }
1988}
1989
1990static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
1991 const struct pci_device_id *pci_id)
1992{
1993 struct cx8800_dev *dev;
1994 struct cx88_core *core;
1995 int err;
1996
1997 dev = kmalloc(sizeof(*dev),GFP_KERNEL);
1998 if (NULL == dev)
1999 return -ENOMEM;
2000 memset(dev,0,sizeof(*dev));
2001
2002 /* pci init */
2003 dev->pci = pci_dev;
2004 if (pci_enable_device(pci_dev)) {
2005 err = -EIO;
2006 goto fail_free;
2007 }
2008 core = cx88_core_get(dev->pci);
2009 if (NULL == core) {
2010 err = -EINVAL;
2011 goto fail_free;
2012 }
2013 dev->core = core;
2014
2015 /* print pci info */
2016 pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev);
2017 pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat);
2018 printk(KERN_INFO "%s/0: found at %s, rev: %d, irq: %d, "
2019 "latency: %d, mmio: 0x%lx\n", core->name,
2020 pci_name(pci_dev), dev->pci_rev, pci_dev->irq,
2021 dev->pci_lat,pci_resource_start(pci_dev,0));
2022
2023 pci_set_master(pci_dev);
2024 if (!pci_dma_supported(pci_dev,0xffffffff)) {
2025 printk("%s/0: Oops: no 32bit PCI DMA ???\n",core->name);
2026 err = -EIO;
2027 goto fail_core;
2028 }
2029
2030 /* initialize driver struct */
2031 init_MUTEX(&dev->lock);
2032 spin_lock_init(&dev->slock);
2033 core->tvnorm = tvnorms;
2034
2035 /* init video dma queues */
2036 INIT_LIST_HEAD(&dev->vidq.active);
2037 INIT_LIST_HEAD(&dev->vidq.queued);
2038 dev->vidq.timeout.function = cx8800_vid_timeout;
2039 dev->vidq.timeout.data = (unsigned long)dev;
2040 init_timer(&dev->vidq.timeout);
2041 cx88_risc_stopper(dev->pci,&dev->vidq.stopper,
2042 MO_VID_DMACNTRL,0x11,0x00);
2043
2044 /* init vbi dma queues */
2045 INIT_LIST_HEAD(&dev->vbiq.active);
2046 INIT_LIST_HEAD(&dev->vbiq.queued);
2047 dev->vbiq.timeout.function = cx8800_vbi_timeout;
2048 dev->vbiq.timeout.data = (unsigned long)dev;
2049 init_timer(&dev->vbiq.timeout);
2050 cx88_risc_stopper(dev->pci,&dev->vbiq.stopper,
2051 MO_VID_DMACNTRL,0x88,0x00);
2052
2053 /* get irq */
2054 err = request_irq(pci_dev->irq, cx8800_irq,
2055 SA_SHIRQ | SA_INTERRUPT, core->name, dev);
2056 if (err < 0) {
2057 printk(KERN_ERR "%s: can't get IRQ %d\n",
2058 core->name,pci_dev->irq);
2059 goto fail_core;
2060 }
2061 cx_set(MO_PCI_INTMSK, core->pci_irqmask);
2062
2063 /* load and configure helper modules */
2064 if (TUNER_ABSENT != core->tuner_type)
2065 request_module("tuner");
2066 if (core->tda9887_conf)
2067 request_module("tda9887");
2068 if (core->tuner_type != UNSET)
2069 cx88_call_i2c_clients(dev->core,TUNER_SET_TYPE,&core->tuner_type);
2070 if (core->tda9887_conf)
2071 cx88_call_i2c_clients(dev->core,TDA9887_SET_CONFIG,&core->tda9887_conf);
2072
2073 /* register v4l devices */
2074 dev->video_dev = cx88_vdev_init(core,dev->pci,
2075 &cx8800_video_template,"video");
2076 err = video_register_device(dev->video_dev,VFL_TYPE_GRABBER,
2077 video_nr[core->nr]);
2078 if (err < 0) {
2079 printk(KERN_INFO "%s: can't register video device\n",
2080 core->name);
2081 goto fail_unreg;
2082 }
2083 printk(KERN_INFO "%s/0: registered device video%d [v4l2]\n",
2084 core->name,dev->video_dev->minor & 0x1f);
2085
2086 dev->vbi_dev = cx88_vdev_init(core,dev->pci,&cx8800_vbi_template,"vbi");
2087 err = video_register_device(dev->vbi_dev,VFL_TYPE_VBI,
2088 vbi_nr[core->nr]);
2089 if (err < 0) {
2090 printk(KERN_INFO "%s/0: can't register vbi device\n",
2091 core->name);
2092 goto fail_unreg;
2093 }
2094 printk(KERN_INFO "%s/0: registered device vbi%d\n",
2095 core->name,dev->vbi_dev->minor & 0x1f);
2096
2097 if (core->has_radio) {
2098 dev->radio_dev = cx88_vdev_init(core,dev->pci,
2099 &cx8800_radio_template,"radio");
2100 err = video_register_device(dev->radio_dev,VFL_TYPE_RADIO,
2101 radio_nr[core->nr]);
2102 if (err < 0) {
2103 printk(KERN_INFO "%s/0: can't register radio device\n",
2104 core->name);
2105 goto fail_unreg;
2106 }
2107 printk(KERN_INFO "%s/0: registered device radio%d\n",
2108 core->name,dev->radio_dev->minor & 0x1f);
2109 }
2110
2111 /* everything worked */
2112 list_add_tail(&dev->devlist,&cx8800_devlist);
2113 pci_set_drvdata(pci_dev,dev);
2114
2115 /* initial device configuration */
2116 down(&dev->lock);
2117 init_controls(dev);
2118 cx88_set_tvnorm(dev->core,tvnorms);
2119 video_mux(dev,0);
2120 up(&dev->lock);
2121
2122 /* start tvaudio thread */
2123 if (core->tuner_type != TUNER_ABSENT)
2124 core->kthread = kthread_run(cx88_audio_thread, core, "cx88 tvaudio");
2125 return 0;
2126
2127fail_unreg:
2128 cx8800_unregister_video(dev);
2129 free_irq(pci_dev->irq, dev);
2130fail_core:
2131 cx88_core_put(core,dev->pci);
2132fail_free:
2133 kfree(dev);
2134 return err;
2135}
2136
2137static void __devexit cx8800_finidev(struct pci_dev *pci_dev)
2138{
2139 struct cx8800_dev *dev = pci_get_drvdata(pci_dev);
2140
2141 /* stop thread */
2142 if (dev->core->kthread) {
2143 kthread_stop(dev->core->kthread);
2144 dev->core->kthread = NULL;
2145 }
2146
2147 cx88_shutdown(dev->core); /* FIXME */
2148 pci_disable_device(pci_dev);
2149
2150 /* unregister stuff */
2151
2152 free_irq(pci_dev->irq, dev);
2153 cx8800_unregister_video(dev);
2154 pci_set_drvdata(pci_dev, NULL);
2155
2156 /* free memory */
2157 btcx_riscmem_free(dev->pci,&dev->vidq.stopper);
2158 list_del(&dev->devlist);
2159 cx88_core_put(dev->core,dev->pci);
2160 kfree(dev);
2161}
2162
2163static int cx8800_suspend(struct pci_dev *pci_dev, pm_message_t state)
2164{
2165 struct cx8800_dev *dev = pci_get_drvdata(pci_dev);
2166 struct cx88_core *core = dev->core;
2167
2168 /* stop video+vbi capture */
2169 spin_lock(&dev->slock);
2170 if (!list_empty(&dev->vidq.active)) {
2171 printk("%s: suspend video\n", core->name);
2172 stop_video_dma(dev);
2173 del_timer(&dev->vidq.timeout);
2174 }
2175 if (!list_empty(&dev->vbiq.active)) {
2176 printk("%s: suspend vbi\n", core->name);
2177 cx8800_stop_vbi_dma(dev);
2178 del_timer(&dev->vbiq.timeout);
2179 }
2180 spin_unlock(&dev->slock);
2181
2182#if 1
2183 /* FIXME -- shutdown device */
2184 cx88_shutdown(dev->core);
2185#endif
2186
2187 pci_save_state(pci_dev);
2188 if (0 != pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state))) {
2189 pci_disable_device(pci_dev);
2190 dev->state.disabled = 1;
2191 }
2192 return 0;
2193}
2194
2195static int cx8800_resume(struct pci_dev *pci_dev)
2196{
2197 struct cx8800_dev *dev = pci_get_drvdata(pci_dev);
2198 struct cx88_core *core = dev->core;
2199
2200 if (dev->state.disabled) {
2201 pci_enable_device(pci_dev);
2202 dev->state.disabled = 0;
2203 }
2204 pci_set_power_state(pci_dev, PCI_D0);
2205 pci_restore_state(pci_dev);
2206
2207#if 1
2208 /* FIXME: re-initialize hardware */
2209 cx88_reset(dev->core);
2210#endif
2211
2212 /* restart video+vbi capture */
2213 spin_lock(&dev->slock);
2214 if (!list_empty(&dev->vidq.active)) {
2215 printk("%s: resume video\n", core->name);
2216 restart_video_queue(dev,&dev->vidq);
2217 }
2218 if (!list_empty(&dev->vbiq.active)) {
2219 printk("%s: resume vbi\n", core->name);
2220 cx8800_restart_vbi_queue(dev,&dev->vbiq);
2221 }
2222 spin_unlock(&dev->slock);
2223
2224 return 0;
2225}
2226
2227/* ----------------------------------------------------------- */
2228
2229struct pci_device_id cx8800_pci_tbl[] = {
2230 {
2231 .vendor = 0x14f1,
2232 .device = 0x8800,
2233 .subvendor = PCI_ANY_ID,
2234 .subdevice = PCI_ANY_ID,
2235 },{
2236 /* --- end of list --- */
2237 }
2238};
2239MODULE_DEVICE_TABLE(pci, cx8800_pci_tbl);
2240
2241static struct pci_driver cx8800_pci_driver = {
2242 .name = "cx8800",
2243 .id_table = cx8800_pci_tbl,
2244 .probe = cx8800_initdev,
2245 .remove = __devexit_p(cx8800_finidev),
2246
2247 .suspend = cx8800_suspend,
2248 .resume = cx8800_resume,
2249};
2250
2251static int cx8800_init(void)
2252{
2253 printk(KERN_INFO "cx2388x v4l2 driver version %d.%d.%d loaded\n",
2254 (CX88_VERSION_CODE >> 16) & 0xff,
2255 (CX88_VERSION_CODE >> 8) & 0xff,
2256 CX88_VERSION_CODE & 0xff);
2257#ifdef SNAPSHOT
2258 printk(KERN_INFO "cx2388x: snapshot date %04d-%02d-%02d\n",
2259 SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100);
2260#endif
2261 return pci_register_driver(&cx8800_pci_driver);
2262}
2263
2264static void cx8800_fini(void)
2265{
2266 pci_unregister_driver(&cx8800_pci_driver);
2267}
2268
2269module_init(cx8800_init);
2270module_exit(cx8800_fini);
2271
2272/* ----------------------------------------------------------- */
2273/*
2274 * Local variables:
2275 * c-basic-offset: 8
2276 * End:
2277 */
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h
new file mode 100644
index 00000000000..b351d9eae61
--- /dev/null
+++ b/drivers/media/video/cx88/cx88.h
@@ -0,0 +1,551 @@
1/*
2 * $Id: cx88.h,v 1.56 2005/03/04 09:12:23 kraxel Exp $
3 *
4 * v4l2 device driver for cx2388x based TV cards
5 *
6 * (c) 2003,04 Gerd Knorr <kraxel@bytesex.org> [SUSE Labs]
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#include <linux/pci.h>
24#include <linux/i2c.h>
25#include <linux/i2c-algo-bit.h>
26#include <linux/videodev.h>
27#include <linux/kdev_t.h>
28
29#include <media/tuner.h>
30#include <media/tveeprom.h>
31#include <media/audiochip.h>
32#include <media/video-buf.h>
33#include <media/video-buf-dvb.h>
34
35#include "btcx-risc.h"
36#include "cx88-reg.h"
37
38#include <linux/version.h>
39#define CX88_VERSION_CODE KERNEL_VERSION(0,0,4)
40
41#ifndef TRUE
42# define TRUE (1==1)
43#endif
44#ifndef FALSE
45# define FALSE (1==0)
46#endif
47#define UNSET (-1U)
48
49#define CX88_MAXBOARDS 8
50
51/* ----------------------------------------------------------- */
52/* defines and enums */
53
54#define V4L2_I2C_CLIENTS 1
55
56#define FORMAT_FLAGS_PACKED 0x01
57#define FORMAT_FLAGS_PLANAR 0x02
58
59#define VBI_LINE_COUNT 17
60#define VBI_LINE_LENGTH 2048
61
62/* need "shadow" registers for some write-only ones ... */
63#define SHADOW_AUD_VOL_CTL 1
64#define SHADOW_AUD_BAL_CTL 2
65#define SHADOW_MAX 2
66
67/* ----------------------------------------------------------- */
68/* tv norms */
69
70struct cx88_tvnorm {
71 char *name;
72 v4l2_std_id id;
73 u32 cxiformat;
74 u32 cxoformat;
75};
76
77static unsigned int inline norm_maxw(struct cx88_tvnorm *norm)
78{
79 return (norm->id & V4L2_STD_625_50) ? 768 : 640;
80// return (norm->id & V4L2_STD_625_50) ? 720 : 640;
81}
82
83static unsigned int inline norm_maxh(struct cx88_tvnorm *norm)
84{
85 return (norm->id & V4L2_STD_625_50) ? 576 : 480;
86}
87
88/* ----------------------------------------------------------- */
89/* static data */
90
91struct cx8800_fmt {
92 char *name;
93 u32 fourcc; /* v4l2 format id */
94 int depth;
95 int flags;
96 u32 cxformat;
97};
98
99struct cx88_ctrl {
100 struct v4l2_queryctrl v;
101 u32 off;
102 u32 reg;
103 u32 sreg;
104 u32 mask;
105 u32 shift;
106};
107
108/* ----------------------------------------------------------- */
109/* SRAM memory management data (see cx88-core.c) */
110
111#define SRAM_CH21 0 /* video */
112#define SRAM_CH22 1
113#define SRAM_CH23 2
114#define SRAM_CH24 3 /* vbi */
115#define SRAM_CH25 4 /* audio */
116#define SRAM_CH26 5
117#define SRAM_CH28 6 /* mpeg */
118/* more */
119
120struct sram_channel {
121 char *name;
122 u32 cmds_start;
123 u32 ctrl_start;
124 u32 cdt;
125 u32 fifo_start;
126 u32 fifo_size;
127 u32 ptr1_reg;
128 u32 ptr2_reg;
129 u32 cnt1_reg;
130 u32 cnt2_reg;
131};
132extern struct sram_channel cx88_sram_channels[];
133
134/* ----------------------------------------------------------- */
135/* card configuration */
136
137#define CX88_BOARD_NOAUTO UNSET
138#define CX88_BOARD_UNKNOWN 0
139#define CX88_BOARD_HAUPPAUGE 1
140#define CX88_BOARD_GDI 2
141#define CX88_BOARD_PIXELVIEW 3
142#define CX88_BOARD_ATI_WONDER_PRO 4
143#define CX88_BOARD_WINFAST2000XP_EXPERT 5
144#define CX88_BOARD_AVERTV_303 6
145#define CX88_BOARD_MSI_TVANYWHERE_MASTER 7
146#define CX88_BOARD_WINFAST_DV2000 8
147#define CX88_BOARD_LEADTEK_PVR2000 9
148#define CX88_BOARD_IODATA_GVVCP3PCI 10
149#define CX88_BOARD_PROLINK_PLAYTVPVR 11
150#define CX88_BOARD_ASUS_PVR_416 12
151#define CX88_BOARD_MSI_TVANYWHERE 13
152#define CX88_BOARD_KWORLD_DVB_T 14
153#define CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1 15
154#define CX88_BOARD_KWORLD_LTV883 16
155#define CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD 17
156#define CX88_BOARD_HAUPPAUGE_DVB_T1 18
157#define CX88_BOARD_CONEXANT_DVB_T1 19
158#define CX88_BOARD_PROVIDEO_PV259 20
159#define CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS 21
160#define CX88_BOARD_PCHDTV_HD3000 22
161#define CX88_BOARD_DNTV_LIVE_DVB_T 23
162#define CX88_BOARD_HAUPPAUGE_ROSLYN 24
163#define CX88_BOARD_DIGITALLOGIC_MEC 25
164#define CX88_BOARD_IODATA_GVBCTV7E 26
165
166enum cx88_itype {
167 CX88_VMUX_COMPOSITE1 = 1,
168 CX88_VMUX_COMPOSITE2,
169 CX88_VMUX_COMPOSITE3,
170 CX88_VMUX_COMPOSITE4,
171 CX88_VMUX_SVIDEO,
172 CX88_VMUX_TELEVISION,
173 CX88_VMUX_CABLE,
174 CX88_VMUX_DVB,
175 CX88_VMUX_DEBUG,
176 CX88_RADIO,
177};
178
179struct cx88_input {
180 enum cx88_itype type;
181 unsigned int vmux;
182 u32 gpio0, gpio1, gpio2, gpio3;
183};
184
185struct cx88_board {
186 char *name;
187 unsigned int tuner_type;
188 int tda9887_conf;
189 struct cx88_input input[8];
190 struct cx88_input radio;
191 int blackbird:1;
192 int dvb:1;
193};
194
195struct cx88_subid {
196 u16 subvendor;
197 u16 subdevice;
198 u32 card;
199};
200
201#define INPUT(nr) (&cx88_boards[core->board].input[nr])
202
203/* ----------------------------------------------------------- */
204/* device / file handle status */
205
206#define RESOURCE_OVERLAY 1
207#define RESOURCE_VIDEO 2
208#define RESOURCE_VBI 4
209
210#define BUFFER_TIMEOUT (HZ/2) /* 0.5 seconds */
211//#define BUFFER_TIMEOUT (HZ*2)
212
213/* buffer for one video frame */
214struct cx88_buffer {
215 /* common v4l buffer stuff -- must be first */
216 struct videobuf_buffer vb;
217
218 /* cx88 specific */
219 unsigned int bpl;
220 struct btcx_riscmem risc;
221 struct cx8800_fmt *fmt;
222 u32 count;
223};
224
225struct cx88_dmaqueue {
226 struct list_head active;
227 struct list_head queued;
228 struct timer_list timeout;
229 struct btcx_riscmem stopper;
230 u32 count;
231};
232
233struct cx88_core {
234 struct list_head devlist;
235 atomic_t refcount;
236
237 /* board name */
238 int nr;
239 char name[32];
240
241 /* pci stuff */
242 int pci_bus;
243 int pci_slot;
244 u32 __iomem *lmmio;
245 u8 __iomem *bmmio;
246 u32 shadow[SHADOW_MAX];
247 int pci_irqmask;
248
249 /* i2c i/o */
250 struct i2c_adapter i2c_adap;
251 struct i2c_algo_bit_data i2c_algo;
252 struct i2c_client i2c_client;
253 u32 i2c_state, i2c_rc;
254
255 /* config info -- analog */
256 unsigned int board;
257 unsigned int tuner_type;
258 unsigned int tda9887_conf;
259 unsigned int has_radio;
260
261 /* config info -- dvb */
262 struct dvb_pll_desc *pll_desc;
263 unsigned int pll_addr;
264
265 /* state info */
266 struct task_struct *kthread;
267 struct cx88_tvnorm *tvnorm;
268 u32 tvaudio;
269 u32 audiomode_manual;
270 u32 audiomode_current;
271 u32 input;
272 u32 astat;
273
274 /* IR remote control state */
275 struct cx88_IR *ir;
276};
277
278struct cx8800_dev;
279struct cx8802_dev;
280
281/* ----------------------------------------------------------- */
282/* function 0: video stuff */
283
284struct cx8800_fh {
285 struct cx8800_dev *dev;
286 enum v4l2_buf_type type;
287 int radio;
288 unsigned int resources;
289
290 /* video overlay */
291 struct v4l2_window win;
292 struct v4l2_clip *clips;
293 unsigned int nclips;
294
295 /* video capture */
296 struct cx8800_fmt *fmt;
297 unsigned int width,height;
298 struct videobuf_queue vidq;
299
300 /* vbi capture */
301 struct videobuf_queue vbiq;
302};
303
304struct cx8800_suspend_state {
305 int disabled;
306};
307
308struct cx8800_dev {
309 struct cx88_core *core;
310 struct list_head devlist;
311 struct semaphore lock;
312 spinlock_t slock;
313
314 /* various device info */
315 unsigned int resources;
316 struct video_device *video_dev;
317 struct video_device *vbi_dev;
318 struct video_device *radio_dev;
319
320 /* pci i/o */
321 struct pci_dev *pci;
322 unsigned char pci_rev,pci_lat;
323
324#if 0
325 /* video overlay */
326 struct v4l2_framebuffer fbuf;
327 struct cx88_buffer *screen;
328#endif
329
330 /* capture queues */
331 struct cx88_dmaqueue vidq;
332 struct cx88_dmaqueue vbiq;
333
334 /* various v4l controls */
335 u32 freq;
336
337 /* other global state info */
338 struct cx8800_suspend_state state;
339};
340
341/* ----------------------------------------------------------- */
342/* function 1: audio/alsa stuff */
343
344struct cx8801_dev {
345 struct cx88_core *core;
346
347 /* pci i/o */
348 struct pci_dev *pci;
349 unsigned char pci_rev,pci_lat;
350};
351
352/* ----------------------------------------------------------- */
353/* function 2: mpeg stuff */
354
355struct cx8802_fh {
356 struct cx8802_dev *dev;
357 struct videobuf_queue mpegq;
358};
359
360struct cx8802_suspend_state {
361 int disabled;
362};
363
364struct cx8802_dev {
365 struct cx88_core *core;
366 struct semaphore lock;
367 spinlock_t slock;
368
369 /* pci i/o */
370 struct pci_dev *pci;
371 unsigned char pci_rev,pci_lat;
372
373 /* dma queues */
374 struct cx88_dmaqueue mpegq;
375 u32 ts_packet_size;
376 u32 ts_packet_count;
377
378 /* other global state info */
379 struct cx8802_suspend_state state;
380
381 /* for blackbird only */
382 struct list_head devlist;
383 struct video_device *mpeg_dev;
384 u32 mailbox;
385 int width;
386 int height;
387
388 /* for dvb only */
389 struct videobuf_dvb dvb;
390 void* fe_handle;
391 int (*fe_release)(void *handle);
392
393 /* for switching modulation types */
394 unsigned char ts_gen_cntrl;
395};
396
397/* ----------------------------------------------------------- */
398
399#define cx_read(reg) readl(core->lmmio + ((reg)>>2))
400#define cx_write(reg,value) writel((value), core->lmmio + ((reg)>>2))
401#define cx_writeb(reg,value) writeb((value), core->bmmio + (reg))
402
403#define cx_andor(reg,mask,value) \
404 writel((readl(core->lmmio+((reg)>>2)) & ~(mask)) |\
405 ((value) & (mask)), core->lmmio+((reg)>>2))
406#define cx_set(reg,bit) cx_andor((reg),(bit),(bit))
407#define cx_clear(reg,bit) cx_andor((reg),(bit),0)
408
409#define cx_wait(d) { if (need_resched()) schedule(); else udelay(d); }
410
411/* shadow registers */
412#define cx_sread(sreg) (core->shadow[sreg])
413#define cx_swrite(sreg,reg,value) \
414 (core->shadow[sreg] = value, \
415 writel(core->shadow[sreg], core->lmmio + ((reg)>>2)))
416#define cx_sandor(sreg,reg,mask,value) \
417 (core->shadow[sreg] = (core->shadow[sreg] & ~(mask)) | ((value) & (mask)), \
418 writel(core->shadow[sreg], core->lmmio + ((reg)>>2)))
419
420/* ----------------------------------------------------------- */
421/* cx88-core.c */
422
423extern char *cx88_pci_irqs[32];
424extern char *cx88_vid_irqs[32];
425extern char *cx88_mpeg_irqs[32];
426extern void cx88_print_irqbits(char *name, char *tag, char **strings,
427 u32 bits, u32 mask);
428extern void cx88_print_ioctl(char *name, unsigned int cmd);
429
430extern int cx88_core_irq(struct cx88_core *core, u32 status);
431extern void cx88_wakeup(struct cx88_core *core,
432 struct cx88_dmaqueue *q, u32 count);
433extern void cx88_shutdown(struct cx88_core *core);
434extern int cx88_reset(struct cx88_core *core);
435
436extern int
437cx88_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc,
438 struct scatterlist *sglist,
439 unsigned int top_offset, unsigned int bottom_offset,
440 unsigned int bpl, unsigned int padding, unsigned int lines);
441extern int
442cx88_risc_databuffer(struct pci_dev *pci, struct btcx_riscmem *risc,
443 struct scatterlist *sglist, unsigned int bpl,
444 unsigned int lines);
445extern int
446cx88_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc,
447 u32 reg, u32 mask, u32 value);
448extern void
449cx88_free_buffer(struct pci_dev *pci, struct cx88_buffer *buf);
450
451extern void cx88_risc_disasm(struct cx88_core *core,
452 struct btcx_riscmem *risc);
453extern int cx88_sram_channel_setup(struct cx88_core *core,
454 struct sram_channel *ch,
455 unsigned int bpl, u32 risc);
456extern void cx88_sram_channel_dump(struct cx88_core *core,
457 struct sram_channel *ch);
458
459extern int cx88_set_scale(struct cx88_core *core, unsigned int width,
460 unsigned int height, enum v4l2_field field);
461extern int cx88_set_tvnorm(struct cx88_core *core, struct cx88_tvnorm *norm);
462
463extern struct video_device *cx88_vdev_init(struct cx88_core *core,
464 struct pci_dev *pci,
465 struct video_device *template,
466 char *type);
467extern struct cx88_core* cx88_core_get(struct pci_dev *pci);
468extern void cx88_core_put(struct cx88_core *core,
469 struct pci_dev *pci);
470
471/* ----------------------------------------------------------- */
472/* cx88-vbi.c */
473
474void cx8800_vbi_fmt(struct cx8800_dev *dev, struct v4l2_format *f);
475int cx8800_start_vbi_dma(struct cx8800_dev *dev,
476 struct cx88_dmaqueue *q,
477 struct cx88_buffer *buf);
478int cx8800_stop_vbi_dma(struct cx8800_dev *dev);
479int cx8800_restart_vbi_queue(struct cx8800_dev *dev,
480 struct cx88_dmaqueue *q);
481void cx8800_vbi_timeout(unsigned long data);
482
483extern struct videobuf_queue_ops cx8800_vbi_qops;
484
485/* ----------------------------------------------------------- */
486/* cx88-i2c.c */
487
488extern int cx88_i2c_init(struct cx88_core *core, struct pci_dev *pci);
489extern void cx88_call_i2c_clients(struct cx88_core *core,
490 unsigned int cmd, void *arg);
491
492
493/* ----------------------------------------------------------- */
494/* cx88-cards.c */
495
496extern struct cx88_board cx88_boards[];
497extern const unsigned int cx88_bcount;
498
499extern struct cx88_subid cx88_subids[];
500extern const unsigned int cx88_idcount;
501
502extern void cx88_card_list(struct cx88_core *core, struct pci_dev *pci);
503extern void cx88_card_setup(struct cx88_core *core);
504
505/* ----------------------------------------------------------- */
506/* cx88-tvaudio.c */
507
508#define WW_NONE 1
509#define WW_BTSC 2
510#define WW_NICAM_I 3
511#define WW_NICAM_BGDKL 4
512#define WW_A1 5
513#define WW_A2_BG 6
514#define WW_A2_DK 7
515#define WW_A2_M 8
516#define WW_EIAJ 9
517#define WW_SYSTEM_L_AM 10
518#define WW_I2SPT 11
519#define WW_FM 12
520
521void cx88_set_tvaudio(struct cx88_core *core);
522void cx88_newstation(struct cx88_core *core);
523void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t);
524void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual);
525int cx88_audio_thread(void *data);
526
527/* ----------------------------------------------------------- */
528/* cx88-input.c */
529
530int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci);
531int cx88_ir_fini(struct cx88_core *core);
532void cx88_ir_irq(struct cx88_core *core);
533
534/* ----------------------------------------------------------- */
535/* cx88-mpeg.c */
536
537int cx8802_buf_prepare(struct cx8802_dev *dev, struct cx88_buffer *buf);
538void cx8802_buf_queue(struct cx8802_dev *dev, struct cx88_buffer *buf);
539void cx8802_cancel_buffers(struct cx8802_dev *dev);
540
541int cx8802_init_common(struct cx8802_dev *dev);
542void cx8802_fini_common(struct cx8802_dev *dev);
543
544int cx8802_suspend_common(struct pci_dev *pci_dev, pm_message_t state);
545int cx8802_resume_common(struct pci_dev *pci_dev);
546
547/*
548 * Local variables:
549 * c-basic-offset: 8
550 * End:
551 */
diff --git a/drivers/media/video/dpc7146.c b/drivers/media/video/dpc7146.c
new file mode 100644
index 00000000000..da9481198c5
--- /dev/null
+++ b/drivers/media/video/dpc7146.c
@@ -0,0 +1,401 @@
1/*
2 dpc7146.c - v4l2 driver for the dpc7146 demonstration board
3
4 Copyright (C) 2000-2003 Michael Hunold <michael@mihu.de>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19*/
20
21#define DEBUG_VARIABLE debug
22
23#include <media/saa7146_vv.h>
24#include <linux/video_decoder.h> /* for saa7111a */
25
26#define I2C_SAA7111A 0x24
27
28/* All unused bytes are reserverd. */
29#define SAA711X_CHIP_VERSION 0x00
30#define SAA711X_ANALOG_INPUT_CONTROL_1 0x02
31#define SAA711X_ANALOG_INPUT_CONTROL_2 0x03
32#define SAA711X_ANALOG_INPUT_CONTROL_3 0x04
33#define SAA711X_ANALOG_INPUT_CONTROL_4 0x05
34#define SAA711X_HORIZONTAL_SYNC_START 0x06
35#define SAA711X_HORIZONTAL_SYNC_STOP 0x07
36#define SAA711X_SYNC_CONTROL 0x08
37#define SAA711X_LUMINANCE_CONTROL 0x09
38#define SAA711X_LUMINANCE_BRIGHTNESS 0x0A
39#define SAA711X_LUMINANCE_CONTRAST 0x0B
40#define SAA711X_CHROMA_SATURATION 0x0C
41#define SAA711X_CHROMA_HUE_CONTROL 0x0D
42#define SAA711X_CHROMA_CONTROL 0x0E
43#define SAA711X_FORMAT_DELAY_CONTROL 0x10
44#define SAA711X_OUTPUT_CONTROL_1 0x11
45#define SAA711X_OUTPUT_CONTROL_2 0x12
46#define SAA711X_OUTPUT_CONTROL_3 0x13
47#define SAA711X_V_GATE_1_START 0x15
48#define SAA711X_V_GATE_1_STOP 0x16
49#define SAA711X_V_GATE_1_MSB 0x17
50#define SAA711X_TEXT_SLICER_STATUS 0x1A
51#define SAA711X_DECODED_BYTES_OF_TS_1 0x1B
52#define SAA711X_DECODED_BYTES_OF_TS_2 0x1C
53#define SAA711X_STATUS_BYTE 0x1F
54
55#define DPC_BOARD_CAN_DO_VBI(dev) (dev->revision != 0)
56
57static int debug = 0;
58module_param(debug, int, 0);
59MODULE_PARM_DESC(debug, "debug verbosity");
60
61static int dpc_num = 0;
62
63#define DPC_INPUTS 2
64static struct v4l2_input dpc_inputs[DPC_INPUTS] = {
65 { 0, "Port A", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
66 { 1, "Port B", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
67};
68
69#define DPC_AUDIOS 0
70
71static struct saa7146_extension_ioctls ioctls[] = {
72 { VIDIOC_G_INPUT, SAA7146_EXCLUSIVE },
73 { VIDIOC_S_INPUT, SAA7146_EXCLUSIVE },
74 { VIDIOC_ENUMINPUT, SAA7146_EXCLUSIVE },
75 { VIDIOC_S_STD, SAA7146_AFTER },
76 { 0, 0 }
77};
78
79struct dpc
80{
81 struct video_device *video_dev;
82 struct video_device *vbi_dev;
83
84 struct i2c_adapter i2c_adapter;
85 struct i2c_client *saa7111a;
86
87 int cur_input; /* current input */
88};
89
90/* fixme: add vbi stuff here */
91static int dpc_probe(struct saa7146_dev* dev)
92{
93 struct dpc* dpc = NULL;
94 struct i2c_client *client;
95 struct list_head *item;
96
97 dpc = (struct dpc*)kmalloc(sizeof(struct dpc), GFP_KERNEL);
98 if( NULL == dpc ) {
99 printk("dpc_v4l2.o: dpc_probe: not enough kernel memory.\n");
100 return -ENOMEM;
101 }
102 memset(dpc, 0x0, sizeof(struct dpc));
103
104 /* FIXME: enable i2c-port pins, video-port-pins
105 video port pins should be enabled here ?! */
106 saa7146_write(dev, MC1, (MASK_08 | MASK_24 | MASK_10 | MASK_26));
107
108 dpc->i2c_adapter = (struct i2c_adapter) {
109 .class = I2C_CLASS_TV_ANALOG,
110 .name = "dpc7146",
111 };
112 saa7146_i2c_adapter_prepare(dev, &dpc->i2c_adapter, SAA7146_I2C_BUS_BIT_RATE_480);
113 if(i2c_add_adapter(&dpc->i2c_adapter) < 0) {
114 DEB_S(("cannot register i2c-device. skipping.\n"));
115 kfree(dpc);
116 return -EFAULT;
117 }
118
119 /* loop through all i2c-devices on the bus and look who is there */
120 list_for_each(item,&dpc->i2c_adapter.clients) {
121 client = list_entry(item, struct i2c_client, list);
122 if( I2C_SAA7111A == client->addr )
123 dpc->saa7111a = client;
124 }
125
126 /* check if all devices are present */
127 if( 0 == dpc->saa7111a ) {
128 DEB_D(("dpc_v4l2.o: dpc_attach failed for this device.\n"));
129 i2c_del_adapter(&dpc->i2c_adapter);
130 kfree(dpc);
131 return -ENODEV;
132 }
133
134 /* all devices are present, probe was successful */
135 DEB_D(("dpc_v4l2.o: dpc_probe succeeded for this device.\n"));
136
137 /* we store the pointer in our private data field */
138 dev->ext_priv = dpc;
139
140 return 0;
141}
142
143/* bring hardware to a sane state. this has to be done, just in case someone
144 wants to capture from this device before it has been properly initialized.
145 the capture engine would badly fail, because no valid signal arrives on the
146 saa7146, thus leading to timeouts and stuff. */
147static int dpc_init_done(struct saa7146_dev* dev)
148{
149 struct dpc* dpc = (struct dpc*)dev->ext_priv;
150
151 DEB_D(("dpc_v4l2.o: dpc_init_done called.\n"));
152
153 /* initialize the helper ics to useful values */
154 i2c_smbus_write_byte_data(dpc->saa7111a, 0x00, 0x11);
155
156 i2c_smbus_write_byte_data(dpc->saa7111a, 0x02, 0xc0);
157 i2c_smbus_write_byte_data(dpc->saa7111a, 0x03, 0x30);
158 i2c_smbus_write_byte_data(dpc->saa7111a, 0x04, 0x00);
159 i2c_smbus_write_byte_data(dpc->saa7111a, 0x05, 0x00);
160 i2c_smbus_write_byte_data(dpc->saa7111a, 0x06, 0xde);
161 i2c_smbus_write_byte_data(dpc->saa7111a, 0x07, 0xad);
162 i2c_smbus_write_byte_data(dpc->saa7111a, 0x08, 0xa8);
163 i2c_smbus_write_byte_data(dpc->saa7111a, 0x09, 0x00);
164 i2c_smbus_write_byte_data(dpc->saa7111a, 0x0a, 0x80);
165 i2c_smbus_write_byte_data(dpc->saa7111a, 0x0b, 0x47);
166 i2c_smbus_write_byte_data(dpc->saa7111a, 0x0c, 0x40);
167 i2c_smbus_write_byte_data(dpc->saa7111a, 0x0d, 0x00);
168 i2c_smbus_write_byte_data(dpc->saa7111a, 0x0e, 0x03);
169
170 i2c_smbus_write_byte_data(dpc->saa7111a, 0x10, 0xd0);
171 i2c_smbus_write_byte_data(dpc->saa7111a, 0x11, 0x1c);
172 i2c_smbus_write_byte_data(dpc->saa7111a, 0x12, 0xc1);
173 i2c_smbus_write_byte_data(dpc->saa7111a, 0x13, 0x30);
174
175 i2c_smbus_write_byte_data(dpc->saa7111a, 0x1f, 0x81);
176
177 return 0;
178}
179
180static struct saa7146_ext_vv vv_data;
181
182/* this function only gets called when the probing was successful */
183static int dpc_attach(struct saa7146_dev* dev, struct saa7146_pci_extension_data *info)
184{
185 struct dpc* dpc = (struct dpc*)dev->ext_priv;
186
187 DEB_D(("dpc_v4l2.o: dpc_attach called.\n"));
188
189 /* checking for i2c-devices can be omitted here, because we
190 already did this in "dpc_vl42_probe" */
191
192 saa7146_vv_init(dev,&vv_data);
193 if( 0 != saa7146_register_device(&dpc->video_dev, dev, "dpc", VFL_TYPE_GRABBER)) {
194 ERR(("cannot register capture v4l2 device. skipping.\n"));
195 return -1;
196 }
197
198 /* initialization stuff (vbi) (only for revision > 0 and for extensions which want it)*/
199 if( 0 != DPC_BOARD_CAN_DO_VBI(dev)) {
200 if( 0 != saa7146_register_device(&dpc->vbi_dev, dev, "dpc", VFL_TYPE_VBI)) {
201 ERR(("cannot register vbi v4l2 device. skipping.\n"));
202 }
203 }
204
205 i2c_use_client(dpc->saa7111a);
206
207 printk("dpc: found 'dpc7146 demonstration board'-%d.\n",dpc_num);
208 dpc_num++;
209
210 /* the rest */
211 dpc->cur_input = 0;
212 dpc_init_done(dev);
213
214 return 0;
215}
216
217static int dpc_detach(struct saa7146_dev* dev)
218{
219 struct dpc* dpc = (struct dpc*)dev->ext_priv;
220
221 DEB_EE(("dev:%p\n",dev));
222
223 i2c_release_client(dpc->saa7111a);
224
225 saa7146_unregister_device(&dpc->video_dev,dev);
226 if( 0 != DPC_BOARD_CAN_DO_VBI(dev)) {
227 saa7146_unregister_device(&dpc->vbi_dev,dev);
228 }
229 saa7146_vv_release(dev);
230
231 dpc_num--;
232
233 i2c_del_adapter(&dpc->i2c_adapter);
234 kfree(dpc);
235 return 0;
236}
237
238#ifdef axa
239int dpc_vbi_bypass(struct saa7146_dev* dev)
240{
241 struct dpc* dpc = (struct dpc*)dev->ext_priv;
242
243 int i = 1;
244
245 /* switch bypass in saa7111a */
246 if ( 0 != dpc->saa7111a->driver->command(dpc->saa7111a,SAA711X_VBI_BYPASS, &i)) {
247 printk("dpc_v4l2.o: VBI_BYPASS: could not address saa7111a.\n");
248 return -1;
249 }
250
251 return 0;
252}
253#endif
254
255static int dpc_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
256{
257 struct saa7146_dev *dev = fh->dev;
258 struct dpc* dpc = (struct dpc*)dev->ext_priv;
259/*
260 struct saa7146_vv *vv = dev->vv_data;
261*/
262 switch(cmd)
263 {
264 case VIDIOC_ENUMINPUT:
265 {
266 struct v4l2_input *i = arg;
267 DEB_EE(("VIDIOC_ENUMINPUT %d.\n",i->index));
268
269 if( i->index < 0 || i->index >= DPC_INPUTS) {
270 return -EINVAL;
271 }
272
273 memcpy(i, &dpc_inputs[i->index], sizeof(struct v4l2_input));
274
275 DEB_D(("dpc_v4l2.o: v4l2_ioctl: VIDIOC_ENUMINPUT %d.\n",i->index));
276 return 0;
277 }
278 case VIDIOC_G_INPUT:
279 {
280 int *input = (int *)arg;
281 *input = dpc->cur_input;
282
283 DEB_D(("dpc_v4l2.o: VIDIOC_G_INPUT: %d\n",*input));
284 return 0;
285 }
286 case VIDIOC_S_INPUT:
287 {
288 int input = *(int *)arg;
289
290 if (input < 0 || input >= DPC_INPUTS) {
291 return -EINVAL;
292 }
293
294 dpc->cur_input = input;
295
296 /* fixme: switch input here, switch audio, too! */
297// saa7146_set_hps_source_and_sync(dev, input_port_selection[input].hps_source, input_port_selection[input].hps_sync);
298 printk("dpc_v4l2.o: VIDIOC_S_INPUT: fixme switch input.\n");
299
300 return 0;
301 }
302 default:
303/*
304 DEB_D(("dpc_v4l2.o: v4l2_ioctl does not handle this ioctl.\n"));
305*/
306 return -ENOIOCTLCMD;
307 }
308 return 0;
309}
310
311static int std_callback(struct saa7146_dev* dev, struct saa7146_standard *std)
312{
313 return 0;
314}
315
316static struct saa7146_standard standard[] = {
317 {
318 .name = "PAL", .id = V4L2_STD_PAL,
319 .v_offset = 0x17, .v_field = 288,
320 .h_offset = 0x14, .h_pixels = 680,
321 .v_max_out = 576, .h_max_out = 768,
322 }, {
323 .name = "NTSC", .id = V4L2_STD_NTSC,
324 .v_offset = 0x16, .v_field = 240,
325 .h_offset = 0x06, .h_pixels = 708,
326 .v_max_out = 480, .h_max_out = 640,
327 }, {
328 .name = "SECAM", .id = V4L2_STD_SECAM,
329 .v_offset = 0x14, .v_field = 288,
330 .h_offset = 0x14, .h_pixels = 720,
331 .v_max_out = 576, .h_max_out = 768,
332 }
333};
334
335static struct saa7146_extension extension;
336
337static struct saa7146_pci_extension_data dpc = {
338 .ext_priv = "Multimedia eXtension Board",
339 .ext = &extension,
340};
341
342static struct pci_device_id pci_tbl[] = {
343 {
344 .vendor = PCI_VENDOR_ID_PHILIPS,
345 .device = PCI_DEVICE_ID_PHILIPS_SAA7146,
346 .subvendor = 0x0000,
347 .subdevice = 0x0000,
348 .driver_data = (unsigned long)&dpc,
349 }, {
350 .vendor = 0,
351 }
352};
353
354MODULE_DEVICE_TABLE(pci, pci_tbl);
355
356static struct saa7146_ext_vv vv_data = {
357 .inputs = DPC_INPUTS,
358 .capabilities = V4L2_CAP_VBI_CAPTURE,
359 .stds = &standard[0],
360 .num_stds = sizeof(standard)/sizeof(struct saa7146_standard),
361 .std_callback = &std_callback,
362 .ioctls = &ioctls[0],
363 .ioctl = dpc_ioctl,
364};
365
366static struct saa7146_extension extension = {
367 .name = "dpc7146 demonstration board",
368 .flags = SAA7146_USE_I2C_IRQ,
369
370 .pci_tbl = &pci_tbl[0],
371 .module = THIS_MODULE,
372
373 .probe = dpc_probe,
374 .attach = dpc_attach,
375 .detach = dpc_detach,
376
377 .irq_mask = 0,
378 .irq_func = NULL,
379};
380
381static int __init dpc_init_module(void)
382{
383 if( 0 != saa7146_register_extension(&extension)) {
384 DEB_S(("failed to register extension.\n"));
385 return -ENODEV;
386 }
387
388 return 0;
389}
390
391static void __exit dpc_cleanup_module(void)
392{
393 saa7146_unregister_extension(&extension);
394}
395
396module_init(dpc_init_module);
397module_exit(dpc_cleanup_module);
398
399MODULE_DESCRIPTION("video4linux-2 driver for the 'dpc7146 demonstration board'");
400MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
401MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/hexium_gemini.c b/drivers/media/video/hexium_gemini.c
new file mode 100644
index 00000000000..c9b00eafefd
--- /dev/null
+++ b/drivers/media/video/hexium_gemini.c
@@ -0,0 +1,556 @@
1/*
2 hexium_gemini.c - v4l2 driver for Hexium Gemini frame grabber cards
3
4 Visit http://www.mihu.de/linux/saa7146/ and follow the link
5 to "hexium" for further details about this card.
6
7 Copyright (C) 2003 Michael Hunold <michael@mihu.de>
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 DEBUG_VARIABLE debug
25
26#include <media/saa7146_vv.h>
27
28static int debug = 0;
29module_param(debug, int, 0);
30MODULE_PARM_DESC(debug, "debug verbosity");
31
32/* global variables */
33static int hexium_num = 0;
34
35#define HEXIUM_GEMINI 4
36#define HEXIUM_GEMINI_DUAL 5
37
38#define HEXIUM_INPUTS 9
39static struct v4l2_input hexium_inputs[HEXIUM_INPUTS] = {
40 { 0, "CVBS 1", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
41 { 1, "CVBS 2", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
42 { 2, "CVBS 3", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
43 { 3, "CVBS 4", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
44 { 4, "CVBS 5", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
45 { 5, "CVBS 6", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
46 { 6, "Y/C 1", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
47 { 7, "Y/C 2", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
48 { 8, "Y/C 3", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
49};
50
51#define HEXIUM_AUDIOS 0
52
53struct hexium_data
54{
55 s8 adr;
56 u8 byte;
57};
58
59static struct saa7146_extension_ioctls ioctls[] = {
60 { VIDIOC_G_INPUT, SAA7146_EXCLUSIVE },
61 { VIDIOC_S_INPUT, SAA7146_EXCLUSIVE },
62 { VIDIOC_QUERYCTRL, SAA7146_BEFORE },
63 { VIDIOC_ENUMINPUT, SAA7146_EXCLUSIVE },
64 { VIDIOC_S_STD, SAA7146_AFTER },
65 { VIDIOC_G_CTRL, SAA7146_BEFORE },
66 { VIDIOC_S_CTRL, SAA7146_BEFORE },
67 { 0, 0 }
68};
69
70#define HEXIUM_CONTROLS 1
71static struct v4l2_queryctrl hexium_controls[] = {
72 { V4L2_CID_PRIVATE_BASE, V4L2_CTRL_TYPE_BOOLEAN, "B/W", 0, 1, 1, 0, 0 },
73};
74
75#define HEXIUM_GEMINI_V_1_0 1
76#define HEXIUM_GEMINI_DUAL_V_1_0 2
77
78struct hexium
79{
80 int type;
81
82 struct video_device *video_dev;
83 struct i2c_adapter i2c_adapter;
84
85 int cur_input; /* current input */
86 v4l2_std_id cur_std; /* current standard */
87 int cur_bw; /* current black/white status */
88};
89
90/* Samsung KS0127B decoder default registers */
91static u8 hexium_ks0127b[0x100]={
92/*00*/ 0x00,0x52,0x30,0x40,0x01,0x0C,0x2A,0x10,
93/*08*/ 0x00,0x00,0x00,0x60,0x00,0x00,0x0F,0x06,
94/*10*/ 0x00,0x00,0xE4,0xC0,0x00,0x00,0x00,0x00,
95/*18*/ 0x14,0x9B,0xFE,0xFF,0xFC,0xFF,0x03,0x22,
96/*20*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
97/*28*/ 0x00,0x00,0x00,0x00,0x00,0x2C,0x9B,0x00,
98/*30*/ 0x00,0x00,0x10,0x80,0x80,0x10,0x80,0x80,
99/*38*/ 0x01,0x04,0x00,0x00,0x00,0x29,0xC0,0x00,
100/*40*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
101/*48*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
102/*50*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
103/*58*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
104/*60*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
105/*68*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
106/*70*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
107/*78*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
108/*80*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
109/*88*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
110/*90*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
111/*98*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
112/*A0*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
113/*A8*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
114/*B0*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
115/*B8*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
116/*C0*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
117/*C8*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
118/*D0*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
119/*D8*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
120/*E0*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
121/*E8*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
122/*F0*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
123/*F8*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
124};
125
126static struct hexium_data hexium_pal[] = {
127 { 0x01, 0x52 }, { 0x12, 0x64 }, { 0x2D, 0x2C }, { 0x2E, 0x9B }, { -1 , 0xFF }
128};
129
130static struct hexium_data hexium_pal_bw[] = {
131 { 0x01, 0x52 }, { 0x12, 0x64 }, { 0x2D, 0x2C }, { 0x2E, 0x9B }, { -1 , 0xFF }
132};
133
134static struct hexium_data hexium_ntsc[] = {
135 { 0x01, 0x53 }, { 0x12, 0x04 }, { 0x2D, 0x23 }, { 0x2E, 0x81 }, { -1 , 0xFF }
136};
137
138static struct hexium_data hexium_ntsc_bw[] = {
139 { 0x01, 0x53 }, { 0x12, 0x04 }, { 0x2D, 0x23 }, { 0x2E, 0x81 }, { -1 , 0xFF }
140};
141
142static struct hexium_data hexium_secam[] = {
143 { 0x01, 0x52 }, { 0x12, 0x64 }, { 0x2D, 0x2C }, { 0x2E, 0x9B }, { -1 , 0xFF }
144};
145
146static struct hexium_data hexium_input_select[] = {
147 { 0x02, 0x60 },
148 { 0x02, 0x64 },
149 { 0x02, 0x61 },
150 { 0x02, 0x65 },
151 { 0x02, 0x62 },
152 { 0x02, 0x66 },
153 { 0x02, 0x68 },
154 { 0x02, 0x69 },
155 { 0x02, 0x6A },
156};
157
158/* fixme: h_offset = 0 for Hexium Gemini *Dual*, which
159 are currently *not* supported*/
160static struct saa7146_standard hexium_standards[] = {
161 {
162 .name = "PAL", .id = V4L2_STD_PAL,
163 .v_offset = 28, .v_field = 288,
164 .h_offset = 1, .h_pixels = 680,
165 .v_max_out = 576, .h_max_out = 768,
166 }, {
167 .name = "NTSC", .id = V4L2_STD_NTSC,
168 .v_offset = 28, .v_field = 240,
169 .h_offset = 1, .h_pixels = 640,
170 .v_max_out = 480, .h_max_out = 640,
171 }, {
172 .name = "SECAM", .id = V4L2_STD_SECAM,
173 .v_offset = 28, .v_field = 288,
174 .h_offset = 1, .h_pixels = 720,
175 .v_max_out = 576, .h_max_out = 768,
176 }
177};
178
179/* bring hardware to a sane state. this has to be done, just in case someone
180 wants to capture from this device before it has been properly initialized.
181 the capture engine would badly fail, because no valid signal arrives on the
182 saa7146, thus leading to timeouts and stuff. */
183static int hexium_init_done(struct saa7146_dev *dev)
184{
185 struct hexium *hexium = (struct hexium *) dev->ext_priv;
186 union i2c_smbus_data data;
187 int i = 0;
188
189 DEB_D(("hexium_init_done called.\n"));
190
191 /* initialize the helper ics to useful values */
192 for (i = 0; i < sizeof(hexium_ks0127b); i++) {
193 data.byte = hexium_ks0127b[i];
194 if (0 != i2c_smbus_xfer(&hexium->i2c_adapter, 0x6c, 0, I2C_SMBUS_WRITE, i, I2C_SMBUS_BYTE_DATA, &data)) {
195 printk("hexium_gemini: hexium_init_done() failed for address 0x%02x\n", i);
196 }
197 }
198
199 return 0;
200}
201
202static int hexium_set_input(struct hexium *hexium, int input)
203{
204 union i2c_smbus_data data;
205
206 DEB_D((".\n"));
207
208 data.byte = hexium_input_select[input].byte;
209 if (0 != i2c_smbus_xfer(&hexium->i2c_adapter, 0x6c, 0, I2C_SMBUS_WRITE, hexium_input_select[input].adr, I2C_SMBUS_BYTE_DATA, &data)) {
210 return -1;
211 }
212
213 return 0;
214}
215
216static int hexium_set_standard(struct hexium *hexium, struct hexium_data *vdec)
217{
218 union i2c_smbus_data data;
219 int i = 0;
220
221 DEB_D((".\n"));
222
223 while (vdec[i].adr != -1) {
224 data.byte = vdec[i].byte;
225 if (0 != i2c_smbus_xfer(&hexium->i2c_adapter, 0x6c, 0, I2C_SMBUS_WRITE, vdec[i].adr, I2C_SMBUS_BYTE_DATA, &data)) {
226 printk("hexium_init_done: hexium_set_standard() failed for address 0x%02x\n", i);
227 return -1;
228 }
229 i++;
230 }
231 return 0;
232}
233
234static struct saa7146_ext_vv vv_data;
235
236/* this function only gets called when the probing was successful */
237static int hexium_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
238{
239 struct hexium *hexium = (struct hexium *) dev->ext_priv;
240
241 DEB_EE((".\n"));
242
243 hexium = (struct hexium *) kmalloc(sizeof(struct hexium), GFP_KERNEL);
244 if (NULL == hexium) {
245 printk("hexium_gemini: not enough kernel memory in hexium_attach().\n");
246 return -ENOMEM;
247 }
248 memset(hexium, 0x0, sizeof(struct hexium));
249 dev->ext_priv = hexium;
250
251 /* enable i2c-port pins */
252 saa7146_write(dev, MC1, (MASK_08 | MASK_24 | MASK_10 | MASK_26));
253
254 hexium->i2c_adapter = (struct i2c_adapter) {
255 .class = I2C_CLASS_TV_ANALOG,
256 .name = "hexium gemini",
257 };
258 saa7146_i2c_adapter_prepare(dev, &hexium->i2c_adapter, SAA7146_I2C_BUS_BIT_RATE_480);
259 if (i2c_add_adapter(&hexium->i2c_adapter) < 0) {
260 DEB_S(("cannot register i2c-device. skipping.\n"));
261 kfree(hexium);
262 return -EFAULT;
263 }
264
265 /* set HWControl GPIO number 2 */
266 saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTHI);
267
268 saa7146_write(dev, DD1_INIT, 0x07000700);
269 saa7146_write(dev, DD1_STREAM_B, 0x00000000);
270 saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
271
272 /* the rest */
273 hexium->cur_input = 0;
274 hexium_init_done(dev);
275
276 hexium_set_standard(hexium, hexium_pal);
277 hexium->cur_std = V4L2_STD_PAL;
278
279 hexium_set_input(hexium, 0);
280 hexium->cur_input = 0;
281
282 saa7146_vv_init(dev, &vv_data);
283 if (0 != saa7146_register_device(&hexium->video_dev, dev, "hexium gemini", VFL_TYPE_GRABBER)) {
284 printk("hexium_gemini: cannot register capture v4l2 device. skipping.\n");
285 return -1;
286 }
287
288 printk("hexium_gemini: found 'hexium gemini' frame grabber-%d.\n", hexium_num);
289 hexium_num++;
290
291 return 0;
292}
293
294static int hexium_detach(struct saa7146_dev *dev)
295{
296 struct hexium *hexium = (struct hexium *) dev->ext_priv;
297
298 DEB_EE(("dev:%p\n", dev));
299
300 saa7146_unregister_device(&hexium->video_dev, dev);
301 saa7146_vv_release(dev);
302
303 hexium_num--;
304
305 i2c_del_adapter(&hexium->i2c_adapter);
306 kfree(hexium);
307 return 0;
308}
309
310static int hexium_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
311{
312 struct saa7146_dev *dev = fh->dev;
313 struct hexium *hexium = (struct hexium *) dev->ext_priv;
314/*
315 struct saa7146_vv *vv = dev->vv_data;
316*/
317 switch (cmd) {
318 case VIDIOC_ENUMINPUT:
319 {
320 struct v4l2_input *i = arg;
321 DEB_EE(("VIDIOC_ENUMINPUT %d.\n", i->index));
322
323 if (i->index < 0 || i->index >= HEXIUM_INPUTS) {
324 return -EINVAL;
325 }
326
327 memcpy(i, &hexium_inputs[i->index], sizeof(struct v4l2_input));
328
329 DEB_D(("v4l2_ioctl: VIDIOC_ENUMINPUT %d.\n", i->index));
330 return 0;
331 }
332 case VIDIOC_G_INPUT:
333 {
334 int *input = (int *) arg;
335 *input = hexium->cur_input;
336
337 DEB_D(("VIDIOC_G_INPUT: %d\n", *input));
338 return 0;
339 }
340 case VIDIOC_S_INPUT:
341 {
342 int input = *(int *) arg;
343
344 DEB_EE(("VIDIOC_S_INPUT %d.\n", input));
345
346 if (input < 0 || input >= HEXIUM_INPUTS) {
347 return -EINVAL;
348 }
349
350 hexium->cur_input = input;
351 hexium_set_input(hexium, input);
352
353 return 0;
354 }
355 /* the saa7146 provides some controls (brightness, contrast, saturation)
356 which gets registered *after* this function. because of this we have
357 to return with a value != 0 even if the function succeded.. */
358 case VIDIOC_QUERYCTRL:
359 {
360 struct v4l2_queryctrl *qc = arg;
361 int i;
362
363 for (i = HEXIUM_CONTROLS - 1; i >= 0; i--) {
364 if (hexium_controls[i].id == qc->id) {
365 *qc = hexium_controls[i];
366 DEB_D(("VIDIOC_QUERYCTRL %d.\n", qc->id));
367 return 0;
368 }
369 }
370 return -EAGAIN;
371 }
372 case VIDIOC_G_CTRL:
373 {
374 struct v4l2_control *vc = arg;
375 int i;
376
377 for (i = HEXIUM_CONTROLS - 1; i >= 0; i--) {
378 if (hexium_controls[i].id == vc->id) {
379 break;
380 }
381 }
382
383 if (i < 0) {
384 return -EAGAIN;
385 }
386
387 switch (vc->id) {
388 case V4L2_CID_PRIVATE_BASE:{
389 vc->value = hexium->cur_bw;
390 DEB_D(("VIDIOC_G_CTRL BW:%d.\n", vc->value));
391 return 0;
392 }
393 }
394 return -EINVAL;
395 }
396
397 case VIDIOC_S_CTRL:
398 {
399 struct v4l2_control *vc = arg;
400 int i = 0;
401
402 for (i = HEXIUM_CONTROLS - 1; i >= 0; i--) {
403 if (hexium_controls[i].id == vc->id) {
404 break;
405 }
406 }
407
408 if (i < 0) {
409 return -EAGAIN;
410 }
411
412 switch (vc->id) {
413 case V4L2_CID_PRIVATE_BASE:{
414 hexium->cur_bw = vc->value;
415 break;
416 }
417 }
418
419 DEB_D(("VIDIOC_S_CTRL BW:%d.\n", hexium->cur_bw));
420
421 if (0 == hexium->cur_bw && V4L2_STD_PAL == hexium->cur_std) {
422 hexium_set_standard(hexium, hexium_pal);
423 return 0;
424 }
425 if (0 == hexium->cur_bw && V4L2_STD_NTSC == hexium->cur_std) {
426 hexium_set_standard(hexium, hexium_ntsc);
427 return 0;
428 }
429 if (0 == hexium->cur_bw && V4L2_STD_SECAM == hexium->cur_std) {
430 hexium_set_standard(hexium, hexium_secam);
431 return 0;
432 }
433 if (1 == hexium->cur_bw && V4L2_STD_PAL == hexium->cur_std) {
434 hexium_set_standard(hexium, hexium_pal_bw);
435 return 0;
436 }
437 if (1 == hexium->cur_bw && V4L2_STD_NTSC == hexium->cur_std) {
438 hexium_set_standard(hexium, hexium_ntsc_bw);
439 return 0;
440 }
441 if (1 == hexium->cur_bw && V4L2_STD_SECAM == hexium->cur_std) {
442 /* fixme: is there no bw secam mode? */
443 return -EINVAL;
444 }
445
446 return -EINVAL;
447 }
448 default:
449/*
450 DEB_D(("hexium_ioctl() does not handle this ioctl.\n"));
451*/
452 return -ENOIOCTLCMD;
453 }
454 return 0;
455}
456
457static int std_callback(struct saa7146_dev *dev, struct saa7146_standard *std)
458{
459 struct hexium *hexium = (struct hexium *) dev->ext_priv;
460
461 if (V4L2_STD_PAL == std->id) {
462 hexium_set_standard(hexium, hexium_pal);
463 hexium->cur_std = V4L2_STD_PAL;
464 return 0;
465 } else if (V4L2_STD_NTSC == std->id) {
466 hexium_set_standard(hexium, hexium_ntsc);
467 hexium->cur_std = V4L2_STD_NTSC;
468 return 0;
469 } else if (V4L2_STD_SECAM == std->id) {
470 hexium_set_standard(hexium, hexium_secam);
471 hexium->cur_std = V4L2_STD_SECAM;
472 return 0;
473 }
474
475 return -1;
476}
477
478static struct saa7146_extension hexium_extension;
479
480static struct saa7146_pci_extension_data hexium_gemini_4bnc = {
481 .ext_priv = "Hexium Gemini (4 BNC)",
482 .ext = &hexium_extension,
483};
484
485static struct saa7146_pci_extension_data hexium_gemini_dual_4bnc = {
486 .ext_priv = "Hexium Gemini Dual (4 BNC)",
487 .ext = &hexium_extension,
488};
489
490static struct pci_device_id pci_tbl[] = {
491 {
492 .vendor = PCI_VENDOR_ID_PHILIPS,
493 .device = PCI_DEVICE_ID_PHILIPS_SAA7146,
494 .subvendor = 0x17c8,
495 .subdevice = 0x2401,
496 .driver_data = (unsigned long) &hexium_gemini_4bnc,
497 },
498 {
499 .vendor = PCI_VENDOR_ID_PHILIPS,
500 .device = PCI_DEVICE_ID_PHILIPS_SAA7146,
501 .subvendor = 0x17c8,
502 .subdevice = 0x2402,
503 .driver_data = (unsigned long) &hexium_gemini_dual_4bnc,
504 },
505 {
506 .vendor = 0,
507 }
508};
509
510MODULE_DEVICE_TABLE(pci, pci_tbl);
511
512static struct saa7146_ext_vv vv_data = {
513 .inputs = HEXIUM_INPUTS,
514 .capabilities = 0,
515 .stds = &hexium_standards[0],
516 .num_stds = sizeof(hexium_standards) / sizeof(struct saa7146_standard),
517 .std_callback = &std_callback,
518 .ioctls = &ioctls[0],
519 .ioctl = hexium_ioctl,
520};
521
522static struct saa7146_extension hexium_extension = {
523 .name = "hexium gemini",
524 .flags = SAA7146_USE_I2C_IRQ,
525
526 .pci_tbl = &pci_tbl[0],
527 .module = THIS_MODULE,
528
529 .attach = hexium_attach,
530 .detach = hexium_detach,
531
532 .irq_mask = 0,
533 .irq_func = NULL,
534};
535
536static int __init hexium_init_module(void)
537{
538 if (0 != saa7146_register_extension(&hexium_extension)) {
539 DEB_S(("failed to register extension.\n"));
540 return -ENODEV;
541 }
542
543 return 0;
544}
545
546static void __exit hexium_cleanup_module(void)
547{
548 saa7146_unregister_extension(&hexium_extension);
549}
550
551module_init(hexium_init_module);
552module_exit(hexium_cleanup_module);
553
554MODULE_DESCRIPTION("video4linux-2 driver for Hexium Gemini frame grabber cards");
555MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
556MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/hexium_orion.c b/drivers/media/video/hexium_orion.c
new file mode 100644
index 00000000000..42a9414155c
--- /dev/null
+++ b/drivers/media/video/hexium_orion.c
@@ -0,0 +1,522 @@
1/*
2 hexium_orion.c - v4l2 driver for the Hexium Orion frame grabber cards
3
4 Visit http://www.mihu.de/linux/saa7146/ and follow the link
5 to "hexium" for further details about this card.
6
7 Copyright (C) 2003 Michael Hunold <michael@mihu.de>
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 DEBUG_VARIABLE debug
25
26#include <media/saa7146_vv.h>
27
28static int debug = 0;
29module_param(debug, int, 0);
30MODULE_PARM_DESC(debug, "debug verbosity");
31
32/* global variables */
33static int hexium_num = 0;
34
35#define HEXIUM_HV_PCI6_ORION 1
36#define HEXIUM_ORION_1SVHS_3BNC 2
37#define HEXIUM_ORION_4BNC 3
38
39#define HEXIUM_INPUTS 9
40static struct v4l2_input hexium_inputs[HEXIUM_INPUTS] = {
41 { 0, "CVBS 1", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
42 { 1, "CVBS 2", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
43 { 2, "CVBS 3", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
44 { 3, "CVBS 4", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
45 { 4, "CVBS 5", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
46 { 5, "CVBS 6", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
47 { 6, "Y/C 1", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
48 { 7, "Y/C 2", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
49 { 8, "Y/C 3", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
50};
51
52#define HEXIUM_AUDIOS 0
53
54struct hexium_data
55{
56 s8 adr;
57 u8 byte;
58};
59
60static struct saa7146_extension_ioctls ioctls[] = {
61 { VIDIOC_G_INPUT, SAA7146_EXCLUSIVE },
62 { VIDIOC_S_INPUT, SAA7146_EXCLUSIVE },
63 { VIDIOC_ENUMINPUT, SAA7146_EXCLUSIVE },
64 { VIDIOC_S_STD, SAA7146_AFTER },
65 { 0, 0 }
66};
67
68struct hexium
69{
70 int type;
71 struct video_device *video_dev;
72 struct i2c_adapter i2c_adapter;
73
74 int cur_input; /* current input */
75};
76
77/* Philips SAA7110 decoder default registers */
78static u8 hexium_saa7110[53]={
79/*00*/ 0x4C,0x3C,0x0D,0xEF,0xBD,0xF0,0x00,0x00,
80/*08*/ 0xF8,0xF8,0x60,0x60,0x40,0x86,0x18,0x90,
81/*10*/ 0x00,0x2C,0x40,0x46,0x42,0x1A,0xFF,0xDA,
82/*18*/ 0xF0,0x8B,0x00,0x00,0x00,0x00,0x00,0x00,
83/*20*/ 0xD9,0x17,0x40,0x41,0x80,0x41,0x80,0x4F,
84/*28*/ 0xFE,0x01,0x0F,0x0F,0x03,0x01,0x81,0x03,
85/*30*/ 0x44,0x75,0x01,0x8C,0x03
86};
87
88static struct {
89 struct hexium_data data[8];
90} hexium_input_select[] = {
91{
92 { /* cvbs 1 */
93 { 0x06, 0x00 },
94 { 0x20, 0xD9 },
95 { 0x21, 0x17 }, // 0x16,
96 { 0x22, 0x40 },
97 { 0x2C, 0x03 },
98 { 0x30, 0x44 },
99 { 0x31, 0x75 }, // ??
100 { 0x21, 0x16 }, // 0x03,
101 }
102}, {
103 { /* cvbs 2 */
104 { 0x06, 0x00 },
105 { 0x20, 0x78 },
106 { 0x21, 0x07 }, // 0x03,
107 { 0x22, 0xD2 },
108 { 0x2C, 0x83 },
109 { 0x30, 0x60 },
110 { 0x31, 0xB5 }, // ?
111 { 0x21, 0x03 },
112 }
113}, {
114 { /* cvbs 3 */
115 { 0x06, 0x00 },
116 { 0x20, 0xBA },
117 { 0x21, 0x07 }, // 0x05,
118 { 0x22, 0x91 },
119 { 0x2C, 0x03 },
120 { 0x30, 0x60 },
121 { 0x31, 0xB5 }, // ??
122 { 0x21, 0x05 }, // 0x03,
123 }
124}, {
125 { /* cvbs 4 */
126 { 0x06, 0x00 },
127 { 0x20, 0xD8 },
128 { 0x21, 0x17 }, // 0x16,
129 { 0x22, 0x40 },
130 { 0x2C, 0x03 },
131 { 0x30, 0x44 },
132 { 0x31, 0x75 }, // ??
133 { 0x21, 0x16 }, // 0x03,
134 }
135}, {
136 { /* cvbs 5 */
137 { 0x06, 0x00 },
138 { 0x20, 0xB8 },
139 { 0x21, 0x07 }, // 0x05,
140 { 0x22, 0x91 },
141 { 0x2C, 0x03 },
142 { 0x30, 0x60 },
143 { 0x31, 0xB5 }, // ??
144 { 0x21, 0x05 }, // 0x03,
145 }
146}, {
147 { /* cvbs 6 */
148 { 0x06, 0x00 },
149 { 0x20, 0x7C },
150 { 0x21, 0x07 }, // 0x03
151 { 0x22, 0xD2 },
152 { 0x2C, 0x83 },
153 { 0x30, 0x60 },
154 { 0x31, 0xB5 }, // ??
155 { 0x21, 0x03 },
156 }
157}, {
158 { /* y/c 1 */
159 { 0x06, 0x80 },
160 { 0x20, 0x59 },
161 { 0x21, 0x17 },
162 { 0x22, 0x42 },
163 { 0x2C, 0xA3 },
164 { 0x30, 0x44 },
165 { 0x31, 0x75 },
166 { 0x21, 0x12 },
167 }
168}, {
169 { /* y/c 2 */
170 { 0x06, 0x80 },
171 { 0x20, 0x9A },
172 { 0x21, 0x17 },
173 { 0x22, 0xB1 },
174 { 0x2C, 0x13 },
175 { 0x30, 0x60 },
176 { 0x31, 0xB5 },
177 { 0x21, 0x14 },
178 }
179}, {
180 { /* y/c 3 */
181 { 0x06, 0x80 },
182 { 0x20, 0x3C },
183 { 0x21, 0x27 },
184 { 0x22, 0xC1 },
185 { 0x2C, 0x23 },
186 { 0x30, 0x44 },
187 { 0x31, 0x75 },
188 { 0x21, 0x21 },
189 }
190}
191};
192
193static struct saa7146_standard hexium_standards[] = {
194 {
195 .name = "PAL", .id = V4L2_STD_PAL,
196 .v_offset = 16, .v_field = 288,
197 .h_offset = 1, .h_pixels = 680,
198 .v_max_out = 576, .h_max_out = 768,
199 }, {
200 .name = "NTSC", .id = V4L2_STD_NTSC,
201 .v_offset = 16, .v_field = 240,
202 .h_offset = 1, .h_pixels = 640,
203 .v_max_out = 480, .h_max_out = 640,
204 }, {
205 .name = "SECAM", .id = V4L2_STD_SECAM,
206 .v_offset = 16, .v_field = 288,
207 .h_offset = 1, .h_pixels = 720,
208 .v_max_out = 576, .h_max_out = 768,
209 }
210};
211
212/* this is only called for old HV-PCI6/Orion cards
213 without eeprom */
214static int hexium_probe(struct saa7146_dev *dev)
215{
216 struct hexium *hexium = NULL;
217 union i2c_smbus_data data;
218 int err = 0;
219
220 DEB_EE((".\n"));
221
222 /* there are no hexium orion cards with revision 0 saa7146s */
223 if (0 == dev->revision) {
224 return -EFAULT;
225 }
226
227 hexium = (struct hexium *) kmalloc(sizeof(struct hexium), GFP_KERNEL);
228 if (NULL == hexium) {
229 printk("hexium_orion: hexium_probe: not enough kernel memory.\n");
230 return -ENOMEM;
231 }
232 memset(hexium, 0x0, sizeof(struct hexium));
233
234 /* enable i2c-port pins */
235 saa7146_write(dev, MC1, (MASK_08 | MASK_24 | MASK_10 | MASK_26));
236
237 saa7146_write(dev, DD1_INIT, 0x01000100);
238 saa7146_write(dev, DD1_STREAM_B, 0x00000000);
239 saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
240
241 hexium->i2c_adapter = (struct i2c_adapter) {
242 .class = I2C_CLASS_TV_ANALOG,
243 .name = "hexium orion",
244 };
245 saa7146_i2c_adapter_prepare(dev, &hexium->i2c_adapter, SAA7146_I2C_BUS_BIT_RATE_480);
246 if (i2c_add_adapter(&hexium->i2c_adapter) < 0) {
247 DEB_S(("cannot register i2c-device. skipping.\n"));
248 kfree(hexium);
249 return -EFAULT;
250 }
251
252 /* set SAA7110 control GPIO 0 */
253 saa7146_setgpio(dev, 0, SAA7146_GPIO_OUTHI);
254 /* set HWControl GPIO number 2 */
255 saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTHI);
256
257 mdelay(10);
258
259 /* detect newer Hexium Orion cards by subsystem ids */
260 if (0x17c8 == dev->pci->subsystem_vendor && 0x0101 == dev->pci->subsystem_device) {
261 printk("hexium_orion: device is a Hexium Orion w/ 1 SVHS + 3 BNC inputs.\n");
262 /* we store the pointer in our private data field */
263 dev->ext_priv = hexium;
264 hexium->type = HEXIUM_ORION_1SVHS_3BNC;
265 return 0;
266 }
267
268 if (0x17c8 == dev->pci->subsystem_vendor && 0x2101 == dev->pci->subsystem_device) {
269 printk("hexium_orion: device is a Hexium Orion w/ 4 BNC inputs.\n");
270 /* we store the pointer in our private data field */
271 dev->ext_priv = hexium;
272 hexium->type = HEXIUM_ORION_4BNC;
273 return 0;
274 }
275
276 /* check if this is an old hexium Orion card by looking at
277 a saa7110 at address 0x4e */
278 if (0 == (err = i2c_smbus_xfer(&hexium->i2c_adapter, 0x4e, 0, I2C_SMBUS_READ, 0x00, I2C_SMBUS_BYTE_DATA, &data))) {
279 printk("hexium_orion: device is a Hexium HV-PCI6/Orion (old).\n");
280 /* we store the pointer in our private data field */
281 dev->ext_priv = hexium;
282 hexium->type = HEXIUM_HV_PCI6_ORION;
283 return 0;
284 }
285
286 i2c_del_adapter(&hexium->i2c_adapter);
287 kfree(hexium);
288 return -EFAULT;
289}
290
291/* bring hardware to a sane state. this has to be done, just in case someone
292 wants to capture from this device before it has been properly initialized.
293 the capture engine would badly fail, because no valid signal arrives on the
294 saa7146, thus leading to timeouts and stuff. */
295static int hexium_init_done(struct saa7146_dev *dev)
296{
297 struct hexium *hexium = (struct hexium *) dev->ext_priv;
298 union i2c_smbus_data data;
299 int i = 0;
300
301 DEB_D(("hexium_init_done called.\n"));
302
303 /* initialize the helper ics to useful values */
304 for (i = 0; i < sizeof(hexium_saa7110); i++) {
305 data.byte = hexium_saa7110[i];
306 if (0 != i2c_smbus_xfer(&hexium->i2c_adapter, 0x4e, 0, I2C_SMBUS_WRITE, i, I2C_SMBUS_BYTE_DATA, &data)) {
307 printk("hexium_orion: failed for address 0x%02x\n", i);
308 }
309 }
310
311 return 0;
312}
313
314static int hexium_set_input(struct hexium *hexium, int input)
315{
316 union i2c_smbus_data data;
317 int i = 0;
318
319 DEB_D((".\n"));
320
321 for (i = 0; i < 8; i++) {
322 int adr = hexium_input_select[input].data[i].adr;
323 data.byte = hexium_input_select[input].data[i].byte;
324 if (0 != i2c_smbus_xfer(&hexium->i2c_adapter, 0x4e, 0, I2C_SMBUS_WRITE, adr, I2C_SMBUS_BYTE_DATA, &data)) {
325 return -1;
326 }
327 printk("%d: 0x%02x => 0x%02x\n",input, adr,data.byte);
328 }
329
330 return 0;
331}
332
333static struct saa7146_ext_vv vv_data;
334
335/* this function only gets called when the probing was successful */
336static int hexium_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
337{
338 struct hexium *hexium = (struct hexium *) dev->ext_priv;
339
340 DEB_EE((".\n"));
341
342 saa7146_vv_init(dev, &vv_data);
343 if (0 != saa7146_register_device(&hexium->video_dev, dev, "hexium orion", VFL_TYPE_GRABBER)) {
344 printk("hexium_orion: cannot register capture v4l2 device. skipping.\n");
345 return -1;
346 }
347
348 printk("hexium_orion: found 'hexium orion' frame grabber-%d.\n", hexium_num);
349 hexium_num++;
350
351 /* the rest */
352 hexium->cur_input = 0;
353 hexium_init_done(dev);
354
355 return 0;
356}
357
358static int hexium_detach(struct saa7146_dev *dev)
359{
360 struct hexium *hexium = (struct hexium *) dev->ext_priv;
361
362 DEB_EE(("dev:%p\n", dev));
363
364 saa7146_unregister_device(&hexium->video_dev, dev);
365 saa7146_vv_release(dev);
366
367 hexium_num--;
368
369 i2c_del_adapter(&hexium->i2c_adapter);
370 kfree(hexium);
371 return 0;
372}
373
374static int hexium_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
375{
376 struct saa7146_dev *dev = fh->dev;
377 struct hexium *hexium = (struct hexium *) dev->ext_priv;
378/*
379 struct saa7146_vv *vv = dev->vv_data;
380*/
381 switch (cmd) {
382 case VIDIOC_ENUMINPUT:
383 {
384 struct v4l2_input *i = arg;
385 DEB_EE(("VIDIOC_ENUMINPUT %d.\n", i->index));
386
387 if (i->index < 0 || i->index >= HEXIUM_INPUTS) {
388 return -EINVAL;
389 }
390
391 memcpy(i, &hexium_inputs[i->index], sizeof(struct v4l2_input));
392
393 DEB_D(("v4l2_ioctl: VIDIOC_ENUMINPUT %d.\n", i->index));
394 return 0;
395 }
396 case VIDIOC_G_INPUT:
397 {
398 int *input = (int *) arg;
399 *input = hexium->cur_input;
400
401 DEB_D(("VIDIOC_G_INPUT: %d\n", *input));
402 return 0;
403 }
404 case VIDIOC_S_INPUT:
405 {
406 int input = *(int *) arg;
407
408 if (input < 0 || input >= HEXIUM_INPUTS) {
409 return -EINVAL;
410 }
411
412 hexium->cur_input = input;
413 hexium_set_input(hexium, input);
414
415 return 0;
416 }
417 default:
418/*
419 DEB_D(("hexium_ioctl() does not handle this ioctl.\n"));
420*/
421 return -ENOIOCTLCMD;
422 }
423 return 0;
424}
425
426static int std_callback(struct saa7146_dev *dev, struct saa7146_standard *std)
427{
428 return 0;
429}
430
431static struct saa7146_extension extension;
432
433static struct saa7146_pci_extension_data hexium_hv_pci6 = {
434 .ext_priv = "Hexium HV-PCI6 / Orion",
435 .ext = &extension,
436};
437
438static struct saa7146_pci_extension_data hexium_orion_1svhs_3bnc = {
439 .ext_priv = "Hexium HV-PCI6 / Orion (1 SVHS/3 BNC)",
440 .ext = &extension,
441};
442
443static struct saa7146_pci_extension_data hexium_orion_4bnc = {
444 .ext_priv = "Hexium HV-PCI6 / Orion (4 BNC)",
445 .ext = &extension,
446};
447
448static struct pci_device_id pci_tbl[] = {
449 {
450 .vendor = PCI_VENDOR_ID_PHILIPS,
451 .device = PCI_DEVICE_ID_PHILIPS_SAA7146,
452 .subvendor = 0x0000,
453 .subdevice = 0x0000,
454 .driver_data = (unsigned long) &hexium_hv_pci6,
455 },
456 {
457 .vendor = PCI_VENDOR_ID_PHILIPS,
458 .device = PCI_DEVICE_ID_PHILIPS_SAA7146,
459 .subvendor = 0x17c8,
460 .subdevice = 0x0101,
461 .driver_data = (unsigned long) &hexium_orion_1svhs_3bnc,
462 },
463 {
464 .vendor = PCI_VENDOR_ID_PHILIPS,
465 .device = PCI_DEVICE_ID_PHILIPS_SAA7146,
466 .subvendor = 0x17c8,
467 .subdevice = 0x2101,
468 .driver_data = (unsigned long) &hexium_orion_4bnc,
469 },
470 {
471 .vendor = 0,
472 }
473};
474
475MODULE_DEVICE_TABLE(pci, pci_tbl);
476
477static struct saa7146_ext_vv vv_data = {
478 .inputs = HEXIUM_INPUTS,
479 .capabilities = 0,
480 .stds = &hexium_standards[0],
481 .num_stds = sizeof(hexium_standards) / sizeof(struct saa7146_standard),
482 .std_callback = &std_callback,
483 .ioctls = &ioctls[0],
484 .ioctl = hexium_ioctl,
485};
486
487static struct saa7146_extension extension = {
488 .name = "hexium HV-PCI6/Orion",
489 .flags = 0, // SAA7146_USE_I2C_IRQ,
490
491 .pci_tbl = &pci_tbl[0],
492 .module = THIS_MODULE,
493
494 .probe = hexium_probe,
495 .attach = hexium_attach,
496 .detach = hexium_detach,
497
498 .irq_mask = 0,
499 .irq_func = NULL,
500};
501
502static int __init hexium_init_module(void)
503{
504 if (0 != saa7146_register_extension(&extension)) {
505 DEB_S(("failed to register extension.\n"));
506 return -ENODEV;
507 }
508
509 return 0;
510}
511
512static void __exit hexium_cleanup_module(void)
513{
514 saa7146_unregister_extension(&extension);
515}
516
517module_init(hexium_init_module);
518module_exit(hexium_cleanup_module);
519
520MODULE_DESCRIPTION("video4linux-2 driver for Hexium Orion frame grabber cards");
521MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
522MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/ibmmpeg2.h b/drivers/media/video/ibmmpeg2.h
new file mode 100644
index 00000000000..68e10387c49
--- /dev/null
+++ b/drivers/media/video/ibmmpeg2.h
@@ -0,0 +1,94 @@
1/* ibmmpeg2.h - IBM MPEGCD21 definitions */
2
3#ifndef __IBM_MPEG2__
4#define __IBM_MPEG2__
5
6/* Define all MPEG Decoder registers */
7/* Chip Control and Status */
8#define IBM_MP2_CHIP_CONTROL 0x200*2
9#define IBM_MP2_CHIP_MODE 0x201*2
10/* Timer Control and Status */
11#define IBM_MP2_SYNC_STC2 0x202*2
12#define IBM_MP2_SYNC_STC1 0x203*2
13#define IBM_MP2_SYNC_STC0 0x204*2
14#define IBM_MP2_SYNC_PTS2 0x205*2
15#define IBM_MP2_SYNC_PTS1 0x206*2
16#define IBM_MP2_SYNC_PTS0 0x207*2
17/* Video FIFO Control */
18#define IBM_MP2_FIFO 0x208*2
19#define IBM_MP2_FIFOW 0x100*2
20#define IBM_MP2_FIFO_STAT 0x209*2
21#define IBM_MP2_RB_THRESHOLD 0x22b*2
22/* Command buffer */
23#define IBM_MP2_COMMAND 0x20a*2
24#define IBM_MP2_CMD_DATA 0x20b*2
25#define IBM_MP2_CMD_STAT 0x20c*2
26#define IBM_MP2_CMD_ADDR 0x20d*2
27/* Internal Processor Control and Status */
28#define IBM_MP2_PROC_IADDR 0x20e*2
29#define IBM_MP2_PROC_IDATA 0x20f*2
30#define IBM_MP2_WR_PROT 0x235*2
31/* DRAM Access */
32#define IBM_MP2_DRAM_ADDR 0x210*2
33#define IBM_MP2_DRAM_DATA 0x212*2
34#define IBM_MP2_DRAM_CMD_STAT 0x213*2
35#define IBM_MP2_BLOCK_SIZE 0x23b*2
36#define IBM_MP2_SRC_ADDR 0x23c*2
37/* Onscreen Display */
38#define IBM_MP2_OSD_ADDR 0x214*2
39#define IBM_MP2_OSD_DATA 0x215*2
40#define IBM_MP2_OSD_MODE 0x217*2
41#define IBM_MP2_OSD_LINK_ADDR 0x229*2
42#define IBM_MP2_OSD_SIZE 0x22a*2
43/* Interrupt Control */
44#define IBM_MP2_HOST_INT 0x218*2
45#define IBM_MP2_MASK0 0x219*2
46#define IBM_MP2_HOST_INT1 0x23e*2
47#define IBM_MP2_MASK1 0x23f*2
48/* Audio Control */
49#define IBM_MP2_AUD_IADDR 0x21a*2
50#define IBM_MP2_AUD_IDATA 0x21b*2
51#define IBM_MP2_AUD_FIFO 0x21c*2
52#define IBM_MP2_AUD_FIFOW 0x101*2
53#define IBM_MP2_AUD_CTL 0x21d*2
54#define IBM_MP2_BEEP_CTL 0x21e*2
55#define IBM_MP2_FRNT_ATTEN 0x22d*2
56/* Display Control */
57#define IBM_MP2_DISP_MODE 0x220*2
58#define IBM_MP2_DISP_DLY 0x221*2
59#define IBM_MP2_VBI_CTL 0x222*2
60#define IBM_MP2_DISP_LBOR 0x223*2
61#define IBM_MP2_DISP_TBOR 0x224*2
62/* Polarity Control */
63#define IBM_MP2_INFC_CTL 0x22c*2
64
65/* control commands */
66#define IBM_MP2_PLAY 0
67#define IBM_MP2_PAUSE 1
68#define IBM_MP2_SINGLE_FRAME 2
69#define IBM_MP2_FAST_FORWARD 3
70#define IBM_MP2_SLOW_MOTION 4
71#define IBM_MP2_IMED_NORM_PLAY 5
72#define IBM_MP2_RESET_WINDOW 6
73#define IBM_MP2_FREEZE_FRAME 7
74#define IBM_MP2_RESET_VID_RATE 8
75#define IBM_MP2_CONFIG_DECODER 9
76#define IBM_MP2_CHANNEL_SWITCH 10
77#define IBM_MP2_RESET_AUD_RATE 11
78#define IBM_MP2_PRE_OP_CHN_SW 12
79#define IBM_MP2_SET_STILL_MODE 14
80
81/* Define Xilinx FPGA Internal Registers */
82
83/* general control register 0 */
84#define XILINX_CTL0 0x600
85/* genlock delay resister 1 */
86#define XILINX_GLDELAY 0x602
87/* send 16 bits to CS3310 port */
88#define XILINX_CS3310 0x604
89/* send 16 bits to CS3310 and complete */
90#define XILINX_CS3310_CMPLT 0x60c
91/* pulse width modulator control */
92#define XILINX_PWM 0x606
93
94#endif
diff --git a/drivers/media/video/ir-kbd-gpio.c b/drivers/media/video/ir-kbd-gpio.c
new file mode 100644
index 00000000000..ab6620de4b3
--- /dev/null
+++ b/drivers/media/video/ir-kbd-gpio.c
@@ -0,0 +1,444 @@
1/*
2 * $Id: ir-kbd-gpio.c,v 1.12 2005/02/22 12:28:40 kraxel Exp $
3 *
4 * Copyright (c) 2003 Gerd Knorr
5 * Copyright (c) 2003 Pavel Machek
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22#include <linux/module.h>
23#include <linux/moduleparam.h>
24#include <linux/init.h>
25#include <linux/delay.h>
26#include <linux/interrupt.h>
27#include <linux/input.h>
28#include <linux/pci.h>
29
30#include <media/ir-common.h>
31
32#include "bttv.h"
33
34/* ---------------------------------------------------------------------- */
35
36static IR_KEYTAB_TYPE ir_codes_avermedia[IR_KEYTAB_SIZE] = {
37 [ 34 ] = KEY_KP0,
38 [ 40 ] = KEY_KP1,
39 [ 24 ] = KEY_KP2,
40 [ 56 ] = KEY_KP3,
41 [ 36 ] = KEY_KP4,
42 [ 20 ] = KEY_KP5,
43 [ 52 ] = KEY_KP6,
44 [ 44 ] = KEY_KP7,
45 [ 28 ] = KEY_KP8,
46 [ 60 ] = KEY_KP9,
47
48 [ 48 ] = KEY_EJECTCD, // Unmarked on my controller
49 [ 0 ] = KEY_POWER,
50 [ 18 ] = BTN_LEFT, // DISPLAY/L
51 [ 50 ] = BTN_RIGHT, // LOOP/R
52 [ 10 ] = KEY_MUTE,
53 [ 38 ] = KEY_RECORD,
54 [ 22 ] = KEY_PAUSE,
55 [ 54 ] = KEY_STOP,
56 [ 30 ] = KEY_VOLUMEDOWN,
57 [ 62 ] = KEY_VOLUMEUP,
58
59 [ 32 ] = KEY_TUNER, // TV/FM
60 [ 16 ] = KEY_CD,
61 [ 8 ] = KEY_VIDEO,
62 [ 4 ] = KEY_AUDIO,
63 [ 12 ] = KEY_ZOOM, // full screen
64 [ 2 ] = KEY_INFO, // preview
65 [ 42 ] = KEY_SEARCH, // autoscan
66 [ 26 ] = KEY_STOP, // freeze
67 [ 58 ] = KEY_RECORD, // capture
68 [ 6 ] = KEY_PLAY, // unmarked
69 [ 46 ] = KEY_RED, // unmarked
70 [ 14 ] = KEY_GREEN, // unmarked
71
72 [ 33 ] = KEY_YELLOW, // unmarked
73 [ 17 ] = KEY_CHANNELDOWN,
74 [ 49 ] = KEY_CHANNELUP,
75 [ 1 ] = KEY_BLUE, // unmarked
76};
77
78/* Matt Jesson <dvb@jesson.eclipse.co.uk */
79static IR_KEYTAB_TYPE ir_codes_avermedia_dvbt[IR_KEYTAB_SIZE] = {
80 [ 0x28 ] = KEY_KP0, //'0' / 'enter'
81 [ 0x22 ] = KEY_KP1, //'1'
82 [ 0x12 ] = KEY_KP2, //'2' / 'up arrow'
83 [ 0x32 ] = KEY_KP3, //'3'
84 [ 0x24 ] = KEY_KP4, //'4' / 'left arrow'
85 [ 0x14 ] = KEY_KP5, //'5'
86 [ 0x34 ] = KEY_KP6, //'6' / 'right arrow'
87 [ 0x26 ] = KEY_KP7, //'7'
88 [ 0x16 ] = KEY_KP8, //'8' / 'down arrow'
89 [ 0x36 ] = KEY_KP9, //'9'
90
91 [ 0x20 ] = KEY_LIST, // 'source'
92 [ 0x10 ] = KEY_TEXT, // 'teletext'
93 [ 0x00 ] = KEY_POWER, // 'power'
94 [ 0x04 ] = KEY_AUDIO, // 'audio'
95 [ 0x06 ] = KEY_ZOOM, // 'full screen'
96 [ 0x18 ] = KEY_VIDEO, // 'display'
97 [ 0x38 ] = KEY_SEARCH, // 'loop'
98 [ 0x08 ] = KEY_INFO, // 'preview'
99 [ 0x2a ] = KEY_REWIND, // 'backward <<'
100 [ 0x1a ] = KEY_FASTFORWARD, // 'forward >>'
101 [ 0x3a ] = KEY_RECORD, // 'capture'
102 [ 0x0a ] = KEY_MUTE, // 'mute'
103 [ 0x2c ] = KEY_RECORD, // 'record'
104 [ 0x1c ] = KEY_PAUSE, // 'pause'
105 [ 0x3c ] = KEY_STOP, // 'stop'
106 [ 0x0c ] = KEY_PLAY, // 'play'
107 [ 0x2e ] = KEY_RED, // 'red'
108 [ 0x01 ] = KEY_BLUE, // 'blue' / 'cancel'
109 [ 0x0e ] = KEY_YELLOW, // 'yellow' / 'ok'
110 [ 0x21 ] = KEY_GREEN, // 'green'
111 [ 0x11 ] = KEY_CHANNELDOWN, // 'channel -'
112 [ 0x31 ] = KEY_CHANNELUP, // 'channel +'
113 [ 0x1e ] = KEY_VOLUMEDOWN, // 'volume -'
114 [ 0x3e ] = KEY_VOLUMEUP, // 'volume +'
115};
116
117static IR_KEYTAB_TYPE ir_codes_pixelview[IR_KEYTAB_SIZE] = {
118 [ 2 ] = KEY_KP0,
119 [ 1 ] = KEY_KP1,
120 [ 11 ] = KEY_KP2,
121 [ 27 ] = KEY_KP3,
122 [ 5 ] = KEY_KP4,
123 [ 9 ] = KEY_KP5,
124 [ 21 ] = KEY_KP6,
125 [ 6 ] = KEY_KP7,
126 [ 10 ] = KEY_KP8,
127 [ 18 ] = KEY_KP9,
128
129 [ 3 ] = KEY_TUNER, // TV/FM
130 [ 7 ] = KEY_SEARCH, // scan
131 [ 28 ] = KEY_ZOOM, // full screen
132 [ 30 ] = KEY_POWER,
133 [ 23 ] = KEY_VOLUMEDOWN,
134 [ 31 ] = KEY_VOLUMEUP,
135 [ 20 ] = KEY_CHANNELDOWN,
136 [ 22 ] = KEY_CHANNELUP,
137 [ 24 ] = KEY_MUTE,
138
139 [ 0 ] = KEY_LIST, // source
140 [ 19 ] = KEY_INFO, // loop
141 [ 16 ] = KEY_LAST, // +100
142 [ 13 ] = KEY_CLEAR, // reset
143 [ 12 ] = BTN_RIGHT, // fun++
144 [ 4 ] = BTN_LEFT, // fun--
145 [ 14 ] = KEY_GOTO, // function
146 [ 15 ] = KEY_STOP, // freeze
147};
148
149/* Attila Kondoros <attila.kondoros@chello.hu> */
150static IR_KEYTAB_TYPE ir_codes_apac_viewcomp[IR_KEYTAB_SIZE] = {
151
152 [ 1 ] = KEY_KP1,
153 [ 2 ] = KEY_KP2,
154 [ 3 ] = KEY_KP3,
155 [ 4 ] = KEY_KP4,
156 [ 5 ] = KEY_KP5,
157 [ 6 ] = KEY_KP6,
158 [ 7 ] = KEY_KP7,
159 [ 8 ] = KEY_KP8,
160 [ 9 ] = KEY_KP9,
161 [ 0 ] = KEY_KP0,
162 [ 23 ] = KEY_LAST, // +100
163 [ 10 ] = KEY_LIST, // recall
164
165
166 [ 28 ] = KEY_TUNER, // TV/FM
167 [ 21 ] = KEY_SEARCH, // scan
168 [ 18 ] = KEY_POWER, // power
169 [ 31 ] = KEY_VOLUMEDOWN, // vol up
170 [ 27 ] = KEY_VOLUMEUP, // vol down
171 [ 30 ] = KEY_CHANNELDOWN, // chn up
172 [ 26 ] = KEY_CHANNELUP, // chn down
173
174 [ 17 ] = KEY_VIDEO, // video
175 [ 15 ] = KEY_ZOOM, // full screen
176 [ 19 ] = KEY_MUTE, // mute/unmute
177 [ 16 ] = KEY_TEXT, // min
178
179 [ 13 ] = KEY_STOP, // freeze
180 [ 14 ] = KEY_RECORD, // record
181 [ 29 ] = KEY_PLAYPAUSE, // stop
182 [ 25 ] = KEY_PLAY, // play
183
184 [ 22 ] = KEY_GOTO, // osd
185 [ 20 ] = KEY_REFRESH, // default
186 [ 12 ] = KEY_KPPLUS, // fine tune >>>>
187 [ 24 ] = KEY_KPMINUS // fine tune <<<<
188};
189
190/* ---------------------------------------------------------------------- */
191
192struct IR {
193 struct bttv_sub_device *sub;
194 struct input_dev input;
195 struct ir_input_state ir;
196 char name[32];
197 char phys[32];
198 u32 mask_keycode;
199 u32 mask_keydown;
200 u32 mask_keyup;
201
202 int polling;
203 u32 last_gpio;
204 struct work_struct work;
205 struct timer_list timer;
206};
207
208static int debug;
209module_param(debug, int, 0644); /* debug level (0,1,2) */
210
211#define DEVNAME "ir-kbd-gpio"
212#define dprintk(fmt, arg...) if (debug) \
213 printk(KERN_DEBUG DEVNAME ": " fmt , ## arg)
214
215static void ir_irq(struct bttv_sub_device *sub);
216static int ir_probe(struct device *dev);
217static int ir_remove(struct device *dev);
218
219static struct bttv_sub_driver driver = {
220 .drv = {
221 .name = DEVNAME,
222 .probe = ir_probe,
223 .remove = ir_remove,
224 },
225 .gpio_irq = ir_irq,
226};
227
228/* ---------------------------------------------------------------------- */
229
230static void ir_handle_key(struct IR *ir)
231{
232 u32 gpio,data;
233
234 /* read gpio value */
235 gpio = bttv_gpio_read(ir->sub->core);
236 if (ir->polling) {
237 if (ir->last_gpio == gpio)
238 return;
239 ir->last_gpio = gpio;
240 }
241
242 /* extract data */
243 data = ir_extract_bits(gpio, ir->mask_keycode);
244 dprintk(DEVNAME ": irq gpio=0x%x code=%d | %s%s%s\n",
245 gpio, data,
246 ir->polling ? "poll" : "irq",
247 (gpio & ir->mask_keydown) ? " down" : "",
248 (gpio & ir->mask_keyup) ? " up" : "");
249
250 if (ir->mask_keydown) {
251 /* bit set on keydown */
252 if (gpio & ir->mask_keydown) {
253 ir_input_keydown(&ir->input,&ir->ir,data,data);
254 } else {
255 ir_input_nokey(&ir->input,&ir->ir);
256 }
257
258 } else if (ir->mask_keyup) {
259 /* bit cleared on keydown */
260 if (0 == (gpio & ir->mask_keyup)) {
261 ir_input_keydown(&ir->input,&ir->ir,data,data);
262 } else {
263 ir_input_nokey(&ir->input,&ir->ir);
264 }
265
266 } else {
267 /* can't disturgissh keydown/up :-/ */
268 ir_input_keydown(&ir->input,&ir->ir,data,data);
269 ir_input_nokey(&ir->input,&ir->ir);
270 }
271}
272
273static void ir_irq(struct bttv_sub_device *sub)
274{
275 struct IR *ir = dev_get_drvdata(&sub->dev);
276
277 if (!ir->polling)
278 ir_handle_key(ir);
279}
280
281static void ir_timer(unsigned long data)
282{
283 struct IR *ir = (struct IR*)data;
284
285 schedule_work(&ir->work);
286}
287
288static void ir_work(void *data)
289{
290 struct IR *ir = data;
291 unsigned long timeout;
292
293 ir_handle_key(ir);
294 timeout = jiffies + (ir->polling * HZ / 1000);
295 mod_timer(&ir->timer, timeout);
296}
297
298/* ---------------------------------------------------------------------- */
299
300static int ir_probe(struct device *dev)
301{
302 struct bttv_sub_device *sub = to_bttv_sub_dev(dev);
303 struct IR *ir;
304 IR_KEYTAB_TYPE *ir_codes = NULL;
305 int ir_type = IR_TYPE_OTHER;
306
307 ir = kmalloc(sizeof(*ir),GFP_KERNEL);
308 if (NULL == ir)
309 return -ENOMEM;
310 memset(ir,0,sizeof(*ir));
311
312 /* detect & configure */
313 switch (sub->core->type) {
314 case BTTV_AVERMEDIA:
315 case BTTV_AVPHONE98:
316 case BTTV_AVERMEDIA98:
317 ir_codes = ir_codes_avermedia;
318 ir->mask_keycode = 0xf88000;
319 ir->mask_keydown = 0x010000;
320 ir->polling = 50; // ms
321 break;
322
323 case BTTV_AVDVBT_761:
324 case BTTV_AVDVBT_771:
325 ir_codes = ir_codes_avermedia_dvbt;
326 ir->mask_keycode = 0x0f00c0;
327 ir->mask_keydown = 0x000020;
328 ir->polling = 50; // ms
329 break;
330
331 case BTTV_PXELVWPLTVPAK:
332 ir_codes = ir_codes_pixelview;
333 ir->mask_keycode = 0x003e00;
334 ir->mask_keyup = 0x010000;
335 ir->polling = 50; // ms
336 break;
337 case BTTV_PV_BT878P_9B:
338 case BTTV_PV_BT878P_PLUS:
339 ir_codes = ir_codes_pixelview;
340 ir->mask_keycode = 0x001f00;
341 ir->mask_keyup = 0x008000;
342 ir->polling = 50; // ms
343 break;
344
345 case BTTV_WINFAST2000:
346 ir_codes = ir_codes_winfast;
347 ir->mask_keycode = 0x1f8;
348 break;
349 case BTTV_MAGICTVIEW061:
350 case BTTV_MAGICTVIEW063:
351 ir_codes = ir_codes_winfast;
352 ir->mask_keycode = 0x0008e000;
353 ir->mask_keydown = 0x00200000;
354 break;
355 case BTTV_APAC_VIEWCOMP:
356 ir_codes = ir_codes_apac_viewcomp;
357 ir->mask_keycode = 0x001f00;
358 ir->mask_keyup = 0x008000;
359 ir->polling = 50; // ms
360 break;
361 }
362 if (NULL == ir_codes) {
363 kfree(ir);
364 return -ENODEV;
365 }
366
367 /* init hardware-specific stuff */
368 bttv_gpio_inout(sub->core, ir->mask_keycode | ir->mask_keydown, 0);
369 ir->sub = sub;
370
371 /* init input device */
372 snprintf(ir->name, sizeof(ir->name), "bttv IR (card=%d)",
373 sub->core->type);
374 snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0",
375 pci_name(sub->core->pci));
376
377 ir_input_init(&ir->input, &ir->ir, ir_type, ir_codes);
378 ir->input.name = ir->name;
379 ir->input.phys = ir->phys;
380 ir->input.id.bustype = BUS_PCI;
381 ir->input.id.version = 1;
382 if (sub->core->pci->subsystem_vendor) {
383 ir->input.id.vendor = sub->core->pci->subsystem_vendor;
384 ir->input.id.product = sub->core->pci->subsystem_device;
385 } else {
386 ir->input.id.vendor = sub->core->pci->vendor;
387 ir->input.id.product = sub->core->pci->device;
388 }
389
390 if (ir->polling) {
391 INIT_WORK(&ir->work, ir_work, ir);
392 init_timer(&ir->timer);
393 ir->timer.function = ir_timer;
394 ir->timer.data = (unsigned long)ir;
395 schedule_work(&ir->work);
396 }
397
398 /* all done */
399 dev_set_drvdata(dev,ir);
400 input_register_device(&ir->input);
401 printk(DEVNAME ": %s detected at %s\n",ir->input.name,ir->input.phys);
402
403 return 0;
404}
405
406static int ir_remove(struct device *dev)
407{
408 struct IR *ir = dev_get_drvdata(dev);
409
410 if (ir->polling) {
411 del_timer(&ir->timer);
412 flush_scheduled_work();
413 }
414
415 input_unregister_device(&ir->input);
416 kfree(ir);
417 return 0;
418}
419
420/* ---------------------------------------------------------------------- */
421
422MODULE_AUTHOR("Gerd Knorr, Pavel Machek");
423MODULE_DESCRIPTION("input driver for bt8x8 gpio IR remote controls");
424MODULE_LICENSE("GPL");
425
426static int ir_init(void)
427{
428 return bttv_sub_register(&driver, "remote");
429}
430
431static void ir_fini(void)
432{
433 bttv_sub_unregister(&driver);
434}
435
436module_init(ir_init);
437module_exit(ir_fini);
438
439
440/*
441 * Local variables:
442 * c-basic-offset: 8
443 * End:
444 */
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c
new file mode 100644
index 00000000000..92664f75d32
--- /dev/null
+++ b/drivers/media/video/ir-kbd-i2c.c
@@ -0,0 +1,492 @@
1/*
2 * $Id: ir-kbd-i2c.c,v 1.10 2004/12/09 12:51:35 kraxel Exp $
3 *
4 * keyboard input driver for i2c IR remote controls
5 *
6 * Copyright (c) 2000-2003 Gerd Knorr <kraxel@bytesex.org>
7 * modified for PixelView (BT878P+W/FM) by
8 * Michal Kochanowicz <mkochano@pld.org.pl>
9 * Christoph Bartelmus <lirc@bartelmus.de>
10 * modified for KNC ONE TV Station/Anubis Typhoon TView Tuner by
11 * Ulrich Mueller <ulrich.mueller42@web.de>
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 *
27 */
28
29#include <linux/module.h>
30#include <linux/moduleparam.h>
31#include <linux/init.h>
32#include <linux/kernel.h>
33#include <linux/sched.h>
34#include <linux/string.h>
35#include <linux/timer.h>
36#include <linux/delay.h>
37#include <linux/errno.h>
38#include <linux/slab.h>
39#include <linux/i2c.h>
40#include <linux/workqueue.h>
41
42#include <asm/semaphore.h>
43
44#include <media/ir-common.h>
45
46/* Mark Phalan <phalanm@o2.ie> */
47static IR_KEYTAB_TYPE ir_codes_pv951[IR_KEYTAB_SIZE] = {
48 [ 0 ] = KEY_KP0,
49 [ 1 ] = KEY_KP1,
50 [ 2 ] = KEY_KP2,
51 [ 3 ] = KEY_KP3,
52 [ 4 ] = KEY_KP4,
53 [ 5 ] = KEY_KP5,
54 [ 6 ] = KEY_KP6,
55 [ 7 ] = KEY_KP7,
56 [ 8 ] = KEY_KP8,
57 [ 9 ] = KEY_KP9,
58
59 [ 18 ] = KEY_POWER,
60 [ 16 ] = KEY_MUTE,
61 [ 31 ] = KEY_VOLUMEDOWN,
62 [ 27 ] = KEY_VOLUMEUP,
63 [ 26 ] = KEY_CHANNELUP,
64 [ 30 ] = KEY_CHANNELDOWN,
65 [ 14 ] = KEY_PAGEUP,
66 [ 29 ] = KEY_PAGEDOWN,
67 [ 19 ] = KEY_SOUND,
68
69 [ 24 ] = KEY_KPPLUSMINUS, // CH +/-
70 [ 22 ] = KEY_SUBTITLE, // CC
71 [ 13 ] = KEY_TEXT, // TTX
72 [ 11 ] = KEY_TV, // AIR/CBL
73 [ 17 ] = KEY_PC, // PC/TV
74 [ 23 ] = KEY_OK, // CH RTN
75 [ 25 ] = KEY_MODE, // FUNC
76 [ 12 ] = KEY_SEARCH, // AUTOSCAN
77
78 /* Not sure what to do with these ones! */
79 [ 15 ] = KEY_SELECT, // SOURCE
80 [ 10 ] = KEY_KPPLUS, // +100
81 [ 20 ] = KEY_KPEQUAL, // SYNC
82 [ 28 ] = KEY_MEDIA, // PC/TV
83};
84
85static IR_KEYTAB_TYPE ir_codes_purpletv[IR_KEYTAB_SIZE] = {
86 [ 0x3 ] = KEY_POWER,
87 [ 0x6f ] = KEY_MUTE,
88 [ 0x10 ] = KEY_BACKSPACE, // Recall
89
90 [ 0x11 ] = KEY_KP0,
91 [ 0x4 ] = KEY_KP1,
92 [ 0x5 ] = KEY_KP2,
93 [ 0x6 ] = KEY_KP3,
94 [ 0x8 ] = KEY_KP4,
95 [ 0x9 ] = KEY_KP5,
96 [ 0xa ] = KEY_KP6,
97 [ 0xc ] = KEY_KP7,
98 [ 0xd ] = KEY_KP8,
99 [ 0xe ] = KEY_KP9,
100 [ 0x12 ] = KEY_KPDOT, // 100+
101
102 [ 0x7 ] = KEY_VOLUMEUP,
103 [ 0xb ] = KEY_VOLUMEDOWN,
104 [ 0x1a ] = KEY_KPPLUS,
105 [ 0x18 ] = KEY_KPMINUS,
106 [ 0x15 ] = KEY_UP,
107 [ 0x1d ] = KEY_DOWN,
108 [ 0xf ] = KEY_CHANNELUP,
109 [ 0x13 ] = KEY_CHANNELDOWN,
110 [ 0x48 ] = KEY_ZOOM,
111
112 [ 0x1b ] = KEY_VIDEO, // Video source
113#if 0
114 [ 0x1f ] = KEY_S, // Snapshot
115#endif
116 [ 0x49 ] = KEY_LANGUAGE, // MTS Select
117 [ 0x19 ] = KEY_SEARCH, // Auto Scan
118
119 [ 0x4b ] = KEY_RECORD,
120 [ 0x46 ] = KEY_PLAY,
121 [ 0x45 ] = KEY_PAUSE, // Pause
122 [ 0x44 ] = KEY_STOP,
123#if 0
124 [ 0x43 ] = KEY_T, // Time Shift
125 [ 0x47 ] = KEY_Y, // Time Shift OFF
126 [ 0x4a ] = KEY_O, // TOP
127 [ 0x17 ] = KEY_F, // SURF CH
128#endif
129 [ 0x40 ] = KEY_FORWARD, // Forward ?
130 [ 0x42 ] = KEY_REWIND, // Backward ?
131
132};
133
134struct IR;
135struct IR {
136 struct i2c_client c;
137 struct input_dev input;
138 struct ir_input_state ir;
139
140 struct work_struct work;
141 struct timer_list timer;
142 char phys[32];
143 int (*get_key)(struct IR*, u32*, u32*);
144};
145
146/* ----------------------------------------------------------------------- */
147/* insmod parameters */
148
149static int debug;
150module_param(debug, int, 0644); /* debug level (0,1,2) */
151
152#define DEVNAME "ir-kbd-i2c"
153#define dprintk(level, fmt, arg...) if (debug >= level) \
154 printk(KERN_DEBUG DEVNAME ": " fmt , ## arg)
155
156/* ----------------------------------------------------------------------- */
157
158static int get_key_haup(struct IR *ir, u32 *ir_key, u32 *ir_raw)
159{
160 unsigned char buf[3];
161 int start, toggle, dev, code;
162
163 /* poll IR chip */
164 if (3 != i2c_master_recv(&ir->c,buf,3))
165 return -EIO;
166
167 /* split rc5 data block ... */
168 start = (buf[0] >> 6) & 3;
169 toggle = (buf[0] >> 5) & 1;
170 dev = buf[0] & 0x1f;
171 code = (buf[1] >> 2) & 0x3f;
172
173 if (3 != start)
174 /* no key pressed */
175 return 0;
176 dprintk(1,"ir hauppauge (rc5): s%d t%d dev=%d code=%d\n",
177 start, toggle, dev, code);
178
179 /* return key */
180 *ir_key = code;
181 *ir_raw = (start << 12) | (toggle << 11) | (dev << 6) | code;
182 return 1;
183}
184
185static int get_key_pixelview(struct IR *ir, u32 *ir_key, u32 *ir_raw)
186{
187 unsigned char b;
188
189 /* poll IR chip */
190 if (1 != i2c_master_recv(&ir->c,&b,1)) {
191 dprintk(1,"read error\n");
192 return -EIO;
193 }
194 *ir_key = b;
195 *ir_raw = b;
196 return 1;
197}
198
199static int get_key_pv951(struct IR *ir, u32 *ir_key, u32 *ir_raw)
200{
201 unsigned char b;
202
203 /* poll IR chip */
204 if (1 != i2c_master_recv(&ir->c,&b,1)) {
205 dprintk(1,"read error\n");
206 return -EIO;
207 }
208
209 /* ignore 0xaa */
210 if (b==0xaa)
211 return 0;
212 dprintk(2,"key %02x\n", b);
213
214 *ir_key = b;
215 *ir_raw = b;
216 return 1;
217}
218
219static int get_key_knc1(struct IR *ir, u32 *ir_key, u32 *ir_raw)
220{
221 unsigned char b;
222
223 /* poll IR chip */
224 if (1 != i2c_master_recv(&ir->c,&b,1)) {
225 dprintk(1,"read error\n");
226 return -EIO;
227 }
228
229 /* it seems that 0xFE indicates that a button is still hold
230 down, while 0xFF indicates that no button is hold
231 down. 0xFE sequences are sometimes interrupted by 0xFF */
232
233 dprintk(2,"key %02x\n", b);
234
235 if (b == 0xFF)
236 return 0;
237
238 if (b == 0xFE)
239 /* keep old data */
240 return 1;
241
242 *ir_key = b;
243 *ir_raw = b;
244 return 1;
245}
246
247static int get_key_purpletv(struct IR *ir, u32 *ir_key, u32 *ir_raw)
248{
249 unsigned char b;
250
251 /* poll IR chip */
252 if (1 != i2c_master_recv(&ir->c,&b,1)) {
253 dprintk(1,"read error\n");
254 return -EIO;
255 }
256
257 /* no button press */
258 if (b==0)
259 return 0;
260
261 /* repeating */
262 if (b & 0x80)
263 return 1;
264
265 *ir_key = b;
266 *ir_raw = b;
267 return 1;
268}
269/* ----------------------------------------------------------------------- */
270
271static void ir_key_poll(struct IR *ir)
272{
273 static u32 ir_key, ir_raw;
274 int rc;
275
276 dprintk(2,"ir_poll_key\n");
277 rc = ir->get_key(ir, &ir_key, &ir_raw);
278 if (rc < 0) {
279 dprintk(2,"error\n");
280 return;
281 }
282
283 if (0 == rc) {
284 ir_input_nokey(&ir->input,&ir->ir);
285 } else {
286 ir_input_keydown(&ir->input,&ir->ir, ir_key, ir_raw);
287 }
288}
289
290static void ir_timer(unsigned long data)
291{
292 struct IR *ir = (struct IR*)data;
293 schedule_work(&ir->work);
294}
295
296static void ir_work(void *data)
297{
298 struct IR *ir = data;
299 ir_key_poll(ir);
300 mod_timer(&ir->timer, jiffies+HZ/10);
301}
302
303/* ----------------------------------------------------------------------- */
304
305static int ir_attach(struct i2c_adapter *adap, int addr,
306 unsigned short flags, int kind);
307static int ir_detach(struct i2c_client *client);
308static int ir_probe(struct i2c_adapter *adap);
309
310static struct i2c_driver driver = {
311 .name = "ir remote kbd driver",
312 .id = I2C_DRIVERID_EXP3, /* FIXME */
313 .flags = I2C_DF_NOTIFY,
314 .attach_adapter = ir_probe,
315 .detach_client = ir_detach,
316};
317
318static struct i2c_client client_template =
319{
320 I2C_DEVNAME("unset"),
321 .driver = &driver
322};
323
324static int ir_attach(struct i2c_adapter *adap, int addr,
325 unsigned short flags, int kind)
326{
327 IR_KEYTAB_TYPE *ir_codes = NULL;
328 char *name;
329 int ir_type;
330 struct IR *ir;
331
332 if (NULL == (ir = kmalloc(sizeof(struct IR),GFP_KERNEL)))
333 return -ENOMEM;
334 memset(ir,0,sizeof(*ir));
335 ir->c = client_template;
336
337 i2c_set_clientdata(&ir->c, ir);
338 ir->c.adapter = adap;
339 ir->c.addr = addr;
340
341 switch(addr) {
342 case 0x64:
343 name = "Pixelview";
344 ir->get_key = get_key_pixelview;
345 ir_type = IR_TYPE_OTHER;
346 ir_codes = ir_codes_empty;
347 break;
348 case 0x4b:
349 name = "PV951";
350 ir->get_key = get_key_pv951;
351 ir_type = IR_TYPE_OTHER;
352 ir_codes = ir_codes_pv951;
353 break;
354 case 0x18:
355 case 0x1a:
356 name = "Hauppauge";
357 ir->get_key = get_key_haup;
358 ir_type = IR_TYPE_RC5;
359 ir_codes = ir_codes_rc5_tv;
360 break;
361 case 0x30:
362 name = "KNC One";
363 ir->get_key = get_key_knc1;
364 ir_type = IR_TYPE_OTHER;
365 ir_codes = ir_codes_empty;
366 break;
367 case 0x7a:
368 name = "Purple TV";
369 ir->get_key = get_key_purpletv;
370 ir_type = IR_TYPE_OTHER;
371 ir_codes = ir_codes_purpletv;
372 break;
373 default:
374 /* shouldn't happen */
375 printk(DEVNAME ": Huh? unknown i2c address (0x%02x)?\n",addr);
376 kfree(ir);
377 return -1;
378 }
379
380 /* register i2c device */
381 i2c_attach_client(&ir->c);
382 snprintf(ir->c.name, sizeof(ir->c.name), "i2c IR (%s)", name);
383 snprintf(ir->phys, sizeof(ir->phys), "%s/%s/ir0",
384 ir->c.adapter->dev.bus_id,
385 ir->c.dev.bus_id);
386
387 /* init + register input device */
388 ir_input_init(&ir->input,&ir->ir,ir_type,ir_codes);
389 ir->input.id.bustype = BUS_I2C;
390 ir->input.name = ir->c.name;
391 ir->input.phys = ir->phys;
392 input_register_device(&ir->input);
393 printk(DEVNAME ": %s detected at %s [%s]\n",
394 ir->input.name,ir->input.phys,adap->name);
395
396 /* start polling via eventd */
397 INIT_WORK(&ir->work, ir_work, ir);
398 init_timer(&ir->timer);
399 ir->timer.function = ir_timer;
400 ir->timer.data = (unsigned long)ir;
401 schedule_work(&ir->work);
402
403 return 0;
404}
405
406static int ir_detach(struct i2c_client *client)
407{
408 struct IR *ir = i2c_get_clientdata(client);
409
410 /* kill outstanding polls */
411 del_timer(&ir->timer);
412 flush_scheduled_work();
413
414 /* unregister devices */
415 input_unregister_device(&ir->input);
416 i2c_detach_client(&ir->c);
417
418 /* free memory */
419 kfree(ir);
420 return 0;
421}
422
423static int ir_probe(struct i2c_adapter *adap)
424{
425
426 /* The external IR receiver is at i2c address 0x34 (0x35 for
427 reads). Future Hauppauge cards will have an internal
428 receiver at 0x30 (0x31 for reads). In theory, both can be
429 fitted, and Hauppauge suggest an external overrides an
430 internal.
431
432 That's why we probe 0x1a (~0x34) first. CB
433 */
434
435 static const int probe_bttv[] = { 0x1a, 0x18, 0x4b, 0x64, 0x30, -1};
436 static const int probe_saa7134[] = { 0x7a, -1 };
437 const int *probe = NULL;
438 struct i2c_client c; char buf; int i,rc;
439
440 switch (adap->id) {
441 case I2C_ALGO_BIT | I2C_HW_B_BT848:
442 probe = probe_bttv;
443 break;
444 case I2C_ALGO_SAA7134:
445 probe = probe_saa7134;
446 break;
447 }
448 if (NULL == probe)
449 return 0;
450
451 memset(&c,0,sizeof(c));
452 c.adapter = adap;
453 for (i = 0; -1 != probe[i]; i++) {
454 c.addr = probe[i];
455 rc = i2c_master_recv(&c,&buf,1);
456 dprintk(1,"probe 0x%02x @ %s: %s\n",
457 probe[i], adap->name,
458 (1 == rc) ? "yes" : "no");
459 if (1 == rc) {
460 ir_attach(adap,probe[i],0,0);
461 break;
462 }
463 }
464 return 0;
465}
466
467/* ----------------------------------------------------------------------- */
468
469MODULE_AUTHOR("Gerd Knorr, Michal Kochanowicz, Christoph Bartelmus, Ulrich Mueller");
470MODULE_DESCRIPTION("input driver for i2c IR remote controls");
471MODULE_LICENSE("GPL");
472
473static int __init ir_init(void)
474{
475 return i2c_add_driver(&driver);
476}
477
478static void __exit ir_fini(void)
479{
480 i2c_del_driver(&driver);
481}
482
483module_init(ir_init);
484module_exit(ir_fini);
485
486/*
487 * Overrides for Emacs so that we follow Linus's tabbing style.
488 * ---------------------------------------------------------------------------
489 * Local variables:
490 * c-basic-offset: 8
491 * End:
492 */
diff --git a/drivers/media/video/meye.c b/drivers/media/video/meye.c
new file mode 100644
index 00000000000..be72c2ce242
--- /dev/null
+++ b/drivers/media/video/meye.c
@@ -0,0 +1,2041 @@
1/*
2 * Motion Eye video4linux driver for Sony Vaio PictureBook
3 *
4 * Copyright (C) 2001-2004 Stelian Pop <stelian@popies.net>
5 *
6 * Copyright (C) 2001-2002 Alcôve <www.alcove.com>
7 *
8 * Copyright (C) 2000 Andrew Tridgell <tridge@valinux.com>
9 *
10 * Earlier work by Werner Almesberger, Paul `Rusty' Russell and Paul Mackerras.
11 *
12 * Some parts borrowed from various video4linux drivers, especially
13 * bttv-driver.c and zoran.c, see original files for credits.
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 */
29#include <linux/config.h>
30#include <linux/module.h>
31#include <linux/pci.h>
32#include <linux/sched.h>
33#include <linux/init.h>
34#include <linux/videodev.h>
35#include <asm/uaccess.h>
36#include <asm/io.h>
37#include <linux/delay.h>
38#include <linux/interrupt.h>
39#include <linux/vmalloc.h>
40
41#include "meye.h"
42#include <linux/meye.h>
43
44MODULE_AUTHOR("Stelian Pop <stelian@popies.net>");
45MODULE_DESCRIPTION("v4l/v4l2 driver for the MotionEye camera");
46MODULE_LICENSE("GPL");
47MODULE_VERSION(MEYE_DRIVER_VERSION);
48
49/* force usage of V4L1 API */
50static int forcev4l1; /* = 0 */
51module_param(forcev4l1, int, 0644);
52MODULE_PARM_DESC(forcev4l1, "force use of V4L1 instead of V4L2");
53
54/* number of grab buffers */
55static unsigned int gbuffers = 2;
56module_param(gbuffers, int, 0444);
57MODULE_PARM_DESC(gbuffers, "number of capture buffers, default is 2 (32 max)");
58
59/* size of a grab buffer */
60static unsigned int gbufsize = MEYE_MAX_BUFSIZE;
61module_param(gbufsize, int, 0444);
62MODULE_PARM_DESC(gbufsize, "size of the capture buffers, default is 614400"
63 " (will be rounded up to a page multiple)");
64
65/* /dev/videoX registration number */
66static int video_nr = -1;
67module_param(video_nr, int, 0444);
68MODULE_PARM_DESC(video_nr, "video device to register (0=/dev/video0, etc)");
69
70/* driver structure - only one possible */
71static struct meye meye;
72
73/****************************************************************************/
74/* Memory allocation routines (stolen from bttv-driver.c) */
75/****************************************************************************/
76static void *rvmalloc(unsigned long size)
77{
78 void *mem;
79 unsigned long adr;
80
81 size = PAGE_ALIGN(size);
82 mem = vmalloc_32(size);
83 if (mem) {
84 memset(mem, 0, size);
85 adr = (unsigned long) mem;
86 while (size > 0) {
87 SetPageReserved(vmalloc_to_page((void *)adr));
88 adr += PAGE_SIZE;
89 size -= PAGE_SIZE;
90 }
91 }
92 return mem;
93}
94
95static void rvfree(void * mem, unsigned long size)
96{
97 unsigned long adr;
98
99 if (mem) {
100 adr = (unsigned long) mem;
101 while ((long) size > 0) {
102 ClearPageReserved(vmalloc_to_page((void *)adr));
103 adr += PAGE_SIZE;
104 size -= PAGE_SIZE;
105 }
106 vfree(mem);
107 }
108}
109
110/*
111 * return a page table pointing to N pages of locked memory
112 *
113 * NOTE: The meye device expects DMA addresses on 32 bits, we build
114 * a table of 1024 entries = 4 bytes * 1024 = 4096 bytes.
115 */
116static int ptable_alloc(void)
117{
118 u32 *pt;
119 int i;
120
121 memset(meye.mchip_ptable, 0, sizeof(meye.mchip_ptable));
122
123 /* give only 32 bit DMA addresses */
124 if (dma_set_mask(&meye.mchip_dev->dev, 0xffffffff))
125 return -1;
126
127 meye.mchip_ptable_toc = dma_alloc_coherent(&meye.mchip_dev->dev,
128 PAGE_SIZE,
129 &meye.mchip_dmahandle,
130 GFP_KERNEL);
131 if (!meye.mchip_ptable_toc) {
132 meye.mchip_dmahandle = 0;
133 return -1;
134 }
135
136 pt = meye.mchip_ptable_toc;
137 for (i = 0; i < MCHIP_NB_PAGES; i++) {
138 dma_addr_t dma;
139 meye.mchip_ptable[i] = dma_alloc_coherent(&meye.mchip_dev->dev,
140 PAGE_SIZE,
141 &dma,
142 GFP_KERNEL);
143 if (!meye.mchip_ptable[i]) {
144 int j;
145 pt = meye.mchip_ptable_toc;
146 for (j = 0; j < i; ++j) {
147 dma = (dma_addr_t) *pt;
148 dma_free_coherent(&meye.mchip_dev->dev,
149 PAGE_SIZE,
150 meye.mchip_ptable[j], dma);
151 pt++;
152 }
153 dma_free_coherent(&meye.mchip_dev->dev,
154 PAGE_SIZE,
155 meye.mchip_ptable_toc,
156 meye.mchip_dmahandle);
157 meye.mchip_ptable_toc = NULL;
158 meye.mchip_dmahandle = 0;
159 return -1;
160 }
161 *pt = (u32) dma;
162 pt++;
163 }
164 return 0;
165}
166
167static void ptable_free(void)
168{
169 u32 *pt;
170 int i;
171
172 pt = meye.mchip_ptable_toc;
173 for (i = 0; i < MCHIP_NB_PAGES; i++) {
174 dma_addr_t dma = (dma_addr_t) *pt;
175 if (meye.mchip_ptable[i])
176 dma_free_coherent(&meye.mchip_dev->dev,
177 PAGE_SIZE,
178 meye.mchip_ptable[i], dma);
179 pt++;
180 }
181
182 if (meye.mchip_ptable_toc)
183 dma_free_coherent(&meye.mchip_dev->dev,
184 PAGE_SIZE,
185 meye.mchip_ptable_toc,
186 meye.mchip_dmahandle);
187
188 memset(meye.mchip_ptable, 0, sizeof(meye.mchip_ptable));
189 meye.mchip_ptable_toc = NULL;
190 meye.mchip_dmahandle = 0;
191}
192
193/* copy data from ptable into buf */
194static void ptable_copy(u8 *buf, int start, int size, int pt_pages)
195{
196 int i;
197
198 for (i = 0; i < (size / PAGE_SIZE) * PAGE_SIZE; i += PAGE_SIZE) {
199 memcpy(buf + i, meye.mchip_ptable[start++], PAGE_SIZE);
200 if (start >= pt_pages)
201 start = 0;
202 }
203 memcpy(buf + i, meye.mchip_ptable[start], size % PAGE_SIZE);
204}
205
206/****************************************************************************/
207/* JPEG tables at different qualities to load into the VRJ chip */
208/****************************************************************************/
209
210/* return a set of quantisation tables based on a quality from 1 to 10 */
211static u16 *jpeg_quantisation_tables(int *length, int quality)
212{
213 static u16 jpeg_tables[][70] = { {
214 0xdbff, 0x4300, 0xff00, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
215 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
216 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
217 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
218 0xffff, 0xffff, 0xffff,
219 0xdbff, 0x4300, 0xff01, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
220 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
221 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
222 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
223 0xffff, 0xffff, 0xffff,
224 },
225 {
226 0xdbff, 0x4300, 0x5000, 0x3c37, 0x3c46, 0x5032, 0x4146, 0x5a46,
227 0x5055, 0x785f, 0x82c8, 0x6e78, 0x786e, 0xaff5, 0x91b9, 0xffc8,
228 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
229 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
230 0xffff, 0xffff, 0xffff,
231 0xdbff, 0x4300, 0x5501, 0x5a5a, 0x6978, 0xeb78, 0x8282, 0xffeb,
232 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
233 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
234 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
235 0xffff, 0xffff, 0xffff,
236 },
237 {
238 0xdbff, 0x4300, 0x2800, 0x1e1c, 0x1e23, 0x2819, 0x2123, 0x2d23,
239 0x282b, 0x3c30, 0x4164, 0x373c, 0x3c37, 0x587b, 0x495d, 0x9164,
240 0x9980, 0x8f96, 0x8c80, 0xa08a, 0xe6b4, 0xa0c3, 0xdaaa, 0x8aad,
241 0xc88c, 0xcbff, 0xeeda, 0xfff5, 0xffff, 0xc19b, 0xffff, 0xfaff,
242 0xe6ff, 0xfffd, 0xfff8,
243 0xdbff, 0x4300, 0x2b01, 0x2d2d, 0x353c, 0x763c, 0x4141, 0xf876,
244 0x8ca5, 0xf8a5, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8,
245 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8,
246 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8,
247 0xf8f8, 0xf8f8, 0xfff8,
248 },
249 {
250 0xdbff, 0x4300, 0x1b00, 0x1412, 0x1417, 0x1b11, 0x1617, 0x1e17,
251 0x1b1c, 0x2820, 0x2b42, 0x2528, 0x2825, 0x3a51, 0x303d, 0x6042,
252 0x6555, 0x5f64, 0x5d55, 0x6a5b, 0x9978, 0x6a81, 0x9071, 0x5b73,
253 0x855d, 0x86b5, 0x9e90, 0xaba3, 0xabad, 0x8067, 0xc9bc, 0xa6ba,
254 0x99c7, 0xaba8, 0xffa4,
255 0xdbff, 0x4300, 0x1c01, 0x1e1e, 0x2328, 0x4e28, 0x2b2b, 0xa44e,
256 0x5d6e, 0xa46e, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4,
257 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4,
258 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4,
259 0xa4a4, 0xa4a4, 0xffa4,
260 },
261 {
262 0xdbff, 0x4300, 0x1400, 0x0f0e, 0x0f12, 0x140d, 0x1012, 0x1712,
263 0x1415, 0x1e18, 0x2132, 0x1c1e, 0x1e1c, 0x2c3d, 0x242e, 0x4932,
264 0x4c40, 0x474b, 0x4640, 0x5045, 0x735a, 0x5062, 0x6d55, 0x4556,
265 0x6446, 0x6588, 0x776d, 0x817b, 0x8182, 0x604e, 0x978d, 0x7d8c,
266 0x7396, 0x817e, 0xff7c,
267 0xdbff, 0x4300, 0x1501, 0x1717, 0x1a1e, 0x3b1e, 0x2121, 0x7c3b,
268 0x4653, 0x7c53, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c,
269 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c,
270 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c,
271 0x7c7c, 0x7c7c, 0xff7c,
272 },
273 {
274 0xdbff, 0x4300, 0x1000, 0x0c0b, 0x0c0e, 0x100a, 0x0d0e, 0x120e,
275 0x1011, 0x1813, 0x1a28, 0x1618, 0x1816, 0x2331, 0x1d25, 0x3a28,
276 0x3d33, 0x393c, 0x3833, 0x4037, 0x5c48, 0x404e, 0x5744, 0x3745,
277 0x5038, 0x516d, 0x5f57, 0x6762, 0x6768, 0x4d3e, 0x7971, 0x6470,
278 0x5c78, 0x6765, 0xff63,
279 0xdbff, 0x4300, 0x1101, 0x1212, 0x1518, 0x2f18, 0x1a1a, 0x632f,
280 0x3842, 0x6342, 0x6363, 0x6363, 0x6363, 0x6363, 0x6363, 0x6363,
281 0x6363, 0x6363, 0x6363, 0x6363, 0x6363, 0x6363, 0x6363, 0x6363,
282 0x6363, 0x6363, 0x6363, 0x6363, 0x6363, 0x6363, 0x6363, 0x6363,
283 0x6363, 0x6363, 0xff63,
284 },
285 {
286 0xdbff, 0x4300, 0x0d00, 0x0a09, 0x0a0b, 0x0d08, 0x0a0b, 0x0e0b,
287 0x0d0e, 0x130f, 0x1520, 0x1213, 0x1312, 0x1c27, 0x171e, 0x2e20,
288 0x3129, 0x2e30, 0x2d29, 0x332c, 0x4a3a, 0x333e, 0x4636, 0x2c37,
289 0x402d, 0x4157, 0x4c46, 0x524e, 0x5253, 0x3e32, 0x615a, 0x505a,
290 0x4a60, 0x5251, 0xff4f,
291 0xdbff, 0x4300, 0x0e01, 0x0e0e, 0x1113, 0x2613, 0x1515, 0x4f26,
292 0x2d35, 0x4f35, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f,
293 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f,
294 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f,
295 0x4f4f, 0x4f4f, 0xff4f,
296 },
297 {
298 0xdbff, 0x4300, 0x0a00, 0x0707, 0x0708, 0x0a06, 0x0808, 0x0b08,
299 0x0a0a, 0x0e0b, 0x1018, 0x0d0e, 0x0e0d, 0x151d, 0x1116, 0x2318,
300 0x251f, 0x2224, 0x221f, 0x2621, 0x372b, 0x262f, 0x3429, 0x2129,
301 0x3022, 0x3141, 0x3934, 0x3e3b, 0x3e3e, 0x2e25, 0x4944, 0x3c43,
302 0x3748, 0x3e3d, 0xff3b,
303 0xdbff, 0x4300, 0x0a01, 0x0b0b, 0x0d0e, 0x1c0e, 0x1010, 0x3b1c,
304 0x2228, 0x3b28, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b,
305 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b,
306 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b,
307 0x3b3b, 0x3b3b, 0xff3b,
308 },
309 {
310 0xdbff, 0x4300, 0x0600, 0x0504, 0x0506, 0x0604, 0x0506, 0x0706,
311 0x0607, 0x0a08, 0x0a10, 0x090a, 0x0a09, 0x0e14, 0x0c0f, 0x1710,
312 0x1814, 0x1718, 0x1614, 0x1a16, 0x251d, 0x1a1f, 0x231b, 0x161c,
313 0x2016, 0x202c, 0x2623, 0x2927, 0x292a, 0x1f19, 0x302d, 0x282d,
314 0x2530, 0x2928, 0xff28,
315 0xdbff, 0x4300, 0x0701, 0x0707, 0x080a, 0x130a, 0x0a0a, 0x2813,
316 0x161a, 0x281a, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828,
317 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828,
318 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828,
319 0x2828, 0x2828, 0xff28,
320 },
321 {
322 0xdbff, 0x4300, 0x0300, 0x0202, 0x0203, 0x0302, 0x0303, 0x0403,
323 0x0303, 0x0504, 0x0508, 0x0405, 0x0504, 0x070a, 0x0607, 0x0c08,
324 0x0c0a, 0x0b0c, 0x0b0a, 0x0d0b, 0x120e, 0x0d10, 0x110e, 0x0b0e,
325 0x100b, 0x1016, 0x1311, 0x1514, 0x1515, 0x0f0c, 0x1817, 0x1416,
326 0x1218, 0x1514, 0xff14,
327 0xdbff, 0x4300, 0x0301, 0x0404, 0x0405, 0x0905, 0x0505, 0x1409,
328 0x0b0d, 0x140d, 0x1414, 0x1414, 0x1414, 0x1414, 0x1414, 0x1414,
329 0x1414, 0x1414, 0x1414, 0x1414, 0x1414, 0x1414, 0x1414, 0x1414,
330 0x1414, 0x1414, 0x1414, 0x1414, 0x1414, 0x1414, 0x1414, 0x1414,
331 0x1414, 0x1414, 0xff14,
332 },
333 {
334 0xdbff, 0x4300, 0x0100, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101,
335 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101,
336 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101,
337 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101,
338 0x0101, 0x0101, 0xff01,
339 0xdbff, 0x4300, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101,
340 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101,
341 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101,
342 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101,
343 0x0101, 0x0101, 0xff01,
344 } };
345
346 if (quality < 0 || quality > 10) {
347 printk(KERN_WARNING
348 "meye: invalid quality level %d - using 8\n", quality);
349 quality = 8;
350 }
351
352 *length = ARRAY_SIZE(jpeg_tables[quality]);
353 return jpeg_tables[quality];
354}
355
356/* return a generic set of huffman tables */
357static u16 *jpeg_huffman_tables(int *length)
358{
359 static u16 tables[] = {
360 0xC4FF, 0xB500, 0x0010, 0x0102, 0x0303, 0x0402, 0x0503, 0x0405,
361 0x0004, 0x0100, 0x017D, 0x0302, 0x0400, 0x0511, 0x2112, 0x4131,
362 0x1306, 0x6151, 0x2207, 0x1471, 0x8132, 0xA191, 0x2308, 0xB142,
363 0x15C1, 0xD152, 0x24F0, 0x6233, 0x8272, 0x0A09, 0x1716, 0x1918,
364 0x251A, 0x2726, 0x2928, 0x342A, 0x3635, 0x3837, 0x3A39, 0x4443,
365 0x4645, 0x4847, 0x4A49, 0x5453, 0x5655, 0x5857, 0x5A59, 0x6463,
366 0x6665, 0x6867, 0x6A69, 0x7473, 0x7675, 0x7877, 0x7A79, 0x8483,
367 0x8685, 0x8887, 0x8A89, 0x9392, 0x9594, 0x9796, 0x9998, 0xA29A,
368 0xA4A3, 0xA6A5, 0xA8A7, 0xAAA9, 0xB3B2, 0xB5B4, 0xB7B6, 0xB9B8,
369 0xC2BA, 0xC4C3, 0xC6C5, 0xC8C7, 0xCAC9, 0xD3D2, 0xD5D4, 0xD7D6,
370 0xD9D8, 0xE1DA, 0xE3E2, 0xE5E4, 0xE7E6, 0xE9E8, 0xF1EA, 0xF3F2,
371 0xF5F4, 0xF7F6, 0xF9F8, 0xFFFA,
372 0xC4FF, 0xB500, 0x0011, 0x0102, 0x0402, 0x0304, 0x0704, 0x0405,
373 0x0004, 0x0201, 0x0077, 0x0201, 0x1103, 0x0504, 0x3121, 0x1206,
374 0x5141, 0x6107, 0x1371, 0x3222, 0x0881, 0x4214, 0xA191, 0xC1B1,
375 0x2309, 0x5233, 0x15F0, 0x7262, 0x0AD1, 0x2416, 0xE134, 0xF125,
376 0x1817, 0x1A19, 0x2726, 0x2928, 0x352A, 0x3736, 0x3938, 0x433A,
377 0x4544, 0x4746, 0x4948, 0x534A, 0x5554, 0x5756, 0x5958, 0x635A,
378 0x6564, 0x6766, 0x6968, 0x736A, 0x7574, 0x7776, 0x7978, 0x827A,
379 0x8483, 0x8685, 0x8887, 0x8A89, 0x9392, 0x9594, 0x9796, 0x9998,
380 0xA29A, 0xA4A3, 0xA6A5, 0xA8A7, 0xAAA9, 0xB3B2, 0xB5B4, 0xB7B6,
381 0xB9B8, 0xC2BA, 0xC4C3, 0xC6C5, 0xC8C7, 0xCAC9, 0xD3D2, 0xD5D4,
382 0xD7D6, 0xD9D8, 0xE2DA, 0xE4E3, 0xE6E5, 0xE8E7, 0xEAE9, 0xF3F2,
383 0xF5F4, 0xF7F6, 0xF9F8, 0xFFFA,
384 0xC4FF, 0x1F00, 0x0000, 0x0501, 0x0101, 0x0101, 0x0101, 0x0000,
385 0x0000, 0x0000, 0x0000, 0x0201, 0x0403, 0x0605, 0x0807, 0x0A09,
386 0xFF0B,
387 0xC4FF, 0x1F00, 0x0001, 0x0103, 0x0101, 0x0101, 0x0101, 0x0101,
388 0x0000, 0x0000, 0x0000, 0x0201, 0x0403, 0x0605, 0x0807, 0x0A09,
389 0xFF0B
390 };
391
392 *length = ARRAY_SIZE(tables);
393 return tables;
394}
395
396/****************************************************************************/
397/* MCHIP low-level functions */
398/****************************************************************************/
399
400/* returns the horizontal capture size */
401static inline int mchip_hsize(void)
402{
403 return meye.params.subsample ? 320 : 640;
404}
405
406/* returns the vertical capture size */
407static inline int mchip_vsize(void)
408{
409 return meye.params.subsample ? 240 : 480;
410}
411
412/* waits for a register to be available */
413static void mchip_sync(int reg)
414{
415 u32 status;
416 int i;
417
418 if (reg == MCHIP_MM_FIFO_DATA) {
419 for (i = 0; i < MCHIP_REG_TIMEOUT; i++) {
420 status = readl(meye.mchip_mmregs +
421 MCHIP_MM_FIFO_STATUS);
422 if (!(status & MCHIP_MM_FIFO_WAIT)) {
423 printk(KERN_WARNING "meye: fifo not ready\n");
424 return;
425 }
426 if (status & MCHIP_MM_FIFO_READY)
427 return;
428 udelay(1);
429 }
430 } else if (reg > 0x80) {
431 u32 mask = (reg < 0x100) ? MCHIP_HIC_STATUS_MCC_RDY
432 : MCHIP_HIC_STATUS_VRJ_RDY;
433 for (i = 0; i < MCHIP_REG_TIMEOUT; i++) {
434 status = readl(meye.mchip_mmregs + MCHIP_HIC_STATUS);
435 if (status & mask)
436 return;
437 udelay(1);
438 }
439 } else
440 return;
441 printk(KERN_WARNING
442 "meye: mchip_sync() timeout on reg 0x%x status=0x%x\n",
443 reg, status);
444}
445
446/* sets a value into the register */
447static inline void mchip_set(int reg, u32 v)
448{
449 mchip_sync(reg);
450 writel(v, meye.mchip_mmregs + reg);
451}
452
453/* get the register value */
454static inline u32 mchip_read(int reg)
455{
456 mchip_sync(reg);
457 return readl(meye.mchip_mmregs + reg);
458}
459
460/* wait for a register to become a particular value */
461static inline int mchip_delay(u32 reg, u32 v)
462{
463 int n = 10;
464 while (--n && mchip_read(reg) != v)
465 udelay(1);
466 return n;
467}
468
469/* setup subsampling */
470static void mchip_subsample(void)
471{
472 mchip_set(MCHIP_MCC_R_SAMPLING, meye.params.subsample);
473 mchip_set(MCHIP_MCC_R_XRANGE, mchip_hsize());
474 mchip_set(MCHIP_MCC_R_YRANGE, mchip_vsize());
475 mchip_set(MCHIP_MCC_B_XRANGE, mchip_hsize());
476 mchip_set(MCHIP_MCC_B_YRANGE, mchip_vsize());
477 mchip_delay(MCHIP_HIC_STATUS, MCHIP_HIC_STATUS_IDLE);
478}
479
480/* set the framerate into the mchip */
481static void mchip_set_framerate(void)
482{
483 mchip_set(MCHIP_HIC_S_RATE, meye.params.framerate);
484}
485
486/* load some huffman and quantisation tables into the VRJ chip ready
487 for JPEG compression */
488static void mchip_load_tables(void)
489{
490 int i;
491 int length;
492 u16 *tables;
493
494 tables = jpeg_huffman_tables(&length);
495 for (i = 0; i < length; i++)
496 writel(tables[i], meye.mchip_mmregs + MCHIP_VRJ_TABLE_DATA);
497
498 tables = jpeg_quantisation_tables(&length, meye.params.quality);
499 for (i = 0; i < length; i++)
500 writel(tables[i], meye.mchip_mmregs + MCHIP_VRJ_TABLE_DATA);
501}
502
503/* setup the VRJ parameters in the chip */
504static void mchip_vrj_setup(u8 mode)
505{
506 mchip_set(MCHIP_VRJ_BUS_MODE, 5);
507 mchip_set(MCHIP_VRJ_SIGNAL_ACTIVE_LEVEL, 0x1f);
508 mchip_set(MCHIP_VRJ_PDAT_USE, 1);
509 mchip_set(MCHIP_VRJ_IRQ_FLAG, 0xa0);
510 mchip_set(MCHIP_VRJ_MODE_SPECIFY, mode);
511 mchip_set(MCHIP_VRJ_NUM_LINES, mchip_vsize());
512 mchip_set(MCHIP_VRJ_NUM_PIXELS, mchip_hsize());
513 mchip_set(MCHIP_VRJ_NUM_COMPONENTS, 0x1b);
514 mchip_set(MCHIP_VRJ_LIMIT_COMPRESSED_LO, 0xFFFF);
515 mchip_set(MCHIP_VRJ_LIMIT_COMPRESSED_HI, 0xFFFF);
516 mchip_set(MCHIP_VRJ_COMP_DATA_FORMAT, 0xC);
517 mchip_set(MCHIP_VRJ_RESTART_INTERVAL, 0);
518 mchip_set(MCHIP_VRJ_SOF1, 0x601);
519 mchip_set(MCHIP_VRJ_SOF2, 0x1502);
520 mchip_set(MCHIP_VRJ_SOF3, 0x1503);
521 mchip_set(MCHIP_VRJ_SOF4, 0x1596);
522 mchip_set(MCHIP_VRJ_SOS, 0x0ed0);
523
524 mchip_load_tables();
525}
526
527/* sets the DMA parameters into the chip */
528static void mchip_dma_setup(dma_addr_t dma_addr)
529{
530 int i;
531
532 mchip_set(MCHIP_MM_PT_ADDR, (u32)dma_addr);
533 for (i = 0; i < 4; i++)
534 mchip_set(MCHIP_MM_FIR(i), 0);
535 meye.mchip_fnum = 0;
536}
537
538/* setup for DMA transfers - also zeros the framebuffer */
539static int mchip_dma_alloc(void)
540{
541 if (!meye.mchip_dmahandle)
542 if (ptable_alloc())
543 return -1;
544 return 0;
545}
546
547/* frees the DMA buffer */
548static void mchip_dma_free(void)
549{
550 if (meye.mchip_dmahandle) {
551 mchip_dma_setup(0);
552 ptable_free();
553 }
554}
555
556/* stop any existing HIC action and wait for any dma to complete then
557 reset the dma engine */
558static void mchip_hic_stop(void)
559{
560 int i, j;
561
562 meye.mchip_mode = MCHIP_HIC_MODE_NOOP;
563 if (!(mchip_read(MCHIP_HIC_STATUS) & MCHIP_HIC_STATUS_BUSY))
564 return;
565 for (i = 0; i < 20; ++i) {
566 mchip_set(MCHIP_HIC_CMD, MCHIP_HIC_CMD_STOP);
567 mchip_delay(MCHIP_HIC_CMD, 0);
568 for (j = 0; j < 100; ++j) {
569 if (mchip_delay(MCHIP_HIC_STATUS,
570 MCHIP_HIC_STATUS_IDLE))
571 return;
572 msleep(1);
573 }
574 printk(KERN_ERR "meye: need to reset HIC!\n");
575
576 mchip_set(MCHIP_HIC_CTL, MCHIP_HIC_CTL_SOFT_RESET);
577 msleep(250);
578 }
579 printk(KERN_ERR "meye: resetting HIC hanged!\n");
580}
581
582/****************************************************************************/
583/* MCHIP frame processing functions */
584/****************************************************************************/
585
586/* get the next ready frame from the dma engine */
587static u32 mchip_get_frame(void)
588{
589 u32 v;
590
591 v = mchip_read(MCHIP_MM_FIR(meye.mchip_fnum));
592 return v;
593}
594
595/* frees the current frame from the dma engine */
596static void mchip_free_frame(void)
597{
598 mchip_set(MCHIP_MM_FIR(meye.mchip_fnum), 0);
599 meye.mchip_fnum++;
600 meye.mchip_fnum %= 4;
601}
602
603/* read one frame from the framebuffer assuming it was captured using
604 a uncompressed transfer */
605static void mchip_cont_read_frame(u32 v, u8 *buf, int size)
606{
607 int pt_id;
608
609 pt_id = (v >> 17) & 0x3FF;
610
611 ptable_copy(buf, pt_id, size, MCHIP_NB_PAGES);
612}
613
614/* read a compressed frame from the framebuffer */
615static int mchip_comp_read_frame(u32 v, u8 *buf, int size)
616{
617 int pt_start, pt_end, trailer;
618 int fsize;
619 int i;
620
621 pt_start = (v >> 19) & 0xFF;
622 pt_end = (v >> 11) & 0xFF;
623 trailer = (v >> 1) & 0x3FF;
624
625 if (pt_end < pt_start)
626 fsize = (MCHIP_NB_PAGES_MJPEG - pt_start) * PAGE_SIZE +
627 pt_end * PAGE_SIZE + trailer * 4;
628 else
629 fsize = (pt_end - pt_start) * PAGE_SIZE + trailer * 4;
630
631 if (fsize > size) {
632 printk(KERN_WARNING "meye: oversized compressed frame %d\n",
633 fsize);
634 return -1;
635 }
636
637 ptable_copy(buf, pt_start, fsize, MCHIP_NB_PAGES_MJPEG);
638
639#ifdef MEYE_JPEG_CORRECTION
640
641 /* Some mchip generated jpeg frames are incorrect. In most
642 * (all ?) of those cases, the final EOI (0xff 0xd9) marker
643 * is not present at the end of the frame.
644 *
645 * Since adding the final marker is not enough to restore
646 * the jpeg integrity, we drop the frame.
647 */
648
649 for (i = fsize - 1; i > 0 && buf[i] == 0xff; i--) ;
650
651 if (i < 2 || buf[i - 1] != 0xff || buf[i] != 0xd9)
652 return -1;
653
654#endif
655
656 return fsize;
657}
658
659/* take a picture into SDRAM */
660static void mchip_take_picture(void)
661{
662 int i;
663
664 mchip_hic_stop();
665 mchip_subsample();
666 mchip_dma_setup(meye.mchip_dmahandle);
667
668 mchip_set(MCHIP_HIC_MODE, MCHIP_HIC_MODE_STILL_CAP);
669 mchip_set(MCHIP_HIC_CMD, MCHIP_HIC_CMD_START);
670
671 mchip_delay(MCHIP_HIC_CMD, 0);
672
673 for (i = 0; i < 100; ++i) {
674 if (mchip_delay(MCHIP_HIC_STATUS, MCHIP_HIC_STATUS_IDLE))
675 break;
676 msleep(1);
677 }
678}
679
680/* dma a previously taken picture into a buffer */
681static void mchip_get_picture(u8 *buf, int bufsize)
682{
683 u32 v;
684 int i;
685
686 mchip_set(MCHIP_HIC_MODE, MCHIP_HIC_MODE_STILL_OUT);
687 mchip_set(MCHIP_HIC_CMD, MCHIP_HIC_CMD_START);
688
689 mchip_delay(MCHIP_HIC_CMD, 0);
690 for (i = 0; i < 100; ++i) {
691 if (mchip_delay(MCHIP_HIC_STATUS, MCHIP_HIC_STATUS_IDLE))
692 break;
693 msleep(1);
694 }
695 for (i = 0; i < 4; ++i) {
696 v = mchip_get_frame();
697 if (v & MCHIP_MM_FIR_RDY) {
698 mchip_cont_read_frame(v, buf, bufsize);
699 break;
700 }
701 mchip_free_frame();
702 }
703}
704
705/* start continuous dma capture */
706static void mchip_continuous_start(void)
707{
708 mchip_hic_stop();
709 mchip_subsample();
710 mchip_set_framerate();
711 mchip_dma_setup(meye.mchip_dmahandle);
712
713 meye.mchip_mode = MCHIP_HIC_MODE_CONT_OUT;
714
715 mchip_set(MCHIP_HIC_MODE, MCHIP_HIC_MODE_CONT_OUT);
716 mchip_set(MCHIP_HIC_CMD, MCHIP_HIC_CMD_START);
717
718 mchip_delay(MCHIP_HIC_CMD, 0);
719}
720
721/* compress one frame into a buffer */
722static int mchip_compress_frame(u8 *buf, int bufsize)
723{
724 u32 v;
725 int len = -1, i;
726
727 mchip_vrj_setup(0x3f);
728 udelay(50);
729
730 mchip_set(MCHIP_HIC_MODE, MCHIP_HIC_MODE_STILL_COMP);
731 mchip_set(MCHIP_HIC_CMD, MCHIP_HIC_CMD_START);
732
733 mchip_delay(MCHIP_HIC_CMD, 0);
734 for (i = 0; i < 100; ++i) {
735 if (mchip_delay(MCHIP_HIC_STATUS, MCHIP_HIC_STATUS_IDLE))
736 break;
737 msleep(1);
738 }
739
740 for (i = 0; i < 4; ++i) {
741 v = mchip_get_frame();
742 if (v & MCHIP_MM_FIR_RDY) {
743 len = mchip_comp_read_frame(v, buf, bufsize);
744 break;
745 }
746 mchip_free_frame();
747 }
748 return len;
749}
750
751#if 0
752/* uncompress one image into a buffer */
753static int mchip_uncompress_frame(u8 *img, int imgsize, u8 *buf, int bufsize)
754{
755 mchip_vrj_setup(0x3f);
756 udelay(50);
757
758 mchip_set(MCHIP_HIC_MODE, MCHIP_HIC_MODE_STILL_DECOMP);
759 mchip_set(MCHIP_HIC_CMD, MCHIP_HIC_CMD_START);
760
761 mchip_delay(MCHIP_HIC_CMD, 0);
762
763 return mchip_comp_read_frame(buf, bufsize);
764}
765#endif
766
767/* start continuous compressed capture */
768static void mchip_cont_compression_start(void)
769{
770 mchip_hic_stop();
771 mchip_vrj_setup(0x3f);
772 mchip_subsample();
773 mchip_set_framerate();
774 mchip_dma_setup(meye.mchip_dmahandle);
775
776 meye.mchip_mode = MCHIP_HIC_MODE_CONT_COMP;
777
778 mchip_set(MCHIP_HIC_MODE, MCHIP_HIC_MODE_CONT_COMP);
779 mchip_set(MCHIP_HIC_CMD, MCHIP_HIC_CMD_START);
780
781 mchip_delay(MCHIP_HIC_CMD, 0);
782}
783
784/****************************************************************************/
785/* Interrupt handling */
786/****************************************************************************/
787
788static irqreturn_t meye_irq(int irq, void *dev_id, struct pt_regs *regs)
789{
790 u32 v;
791 int reqnr;
792 static int sequence = 0;
793
794 v = mchip_read(MCHIP_MM_INTA);
795
796 if (meye.mchip_mode != MCHIP_HIC_MODE_CONT_OUT &&
797 meye.mchip_mode != MCHIP_HIC_MODE_CONT_COMP)
798 return IRQ_NONE;
799
800again:
801 v = mchip_get_frame();
802 if (!(v & MCHIP_MM_FIR_RDY))
803 return IRQ_HANDLED;
804
805 if (meye.mchip_mode == MCHIP_HIC_MODE_CONT_OUT) {
806 if (kfifo_get(meye.grabq, (unsigned char *)&reqnr,
807 sizeof(int)) != sizeof(int)) {
808 mchip_free_frame();
809 return IRQ_HANDLED;
810 }
811 mchip_cont_read_frame(v, meye.grab_fbuffer + gbufsize * reqnr,
812 mchip_hsize() * mchip_vsize() * 2);
813 meye.grab_buffer[reqnr].size = mchip_hsize() * mchip_vsize() * 2;
814 meye.grab_buffer[reqnr].state = MEYE_BUF_DONE;
815 do_gettimeofday(&meye.grab_buffer[reqnr].timestamp);
816 meye.grab_buffer[reqnr].sequence = sequence++;
817 kfifo_put(meye.doneq, (unsigned char *)&reqnr, sizeof(int));
818 wake_up_interruptible(&meye.proc_list);
819 } else {
820 int size;
821 size = mchip_comp_read_frame(v, meye.grab_temp, gbufsize);
822 if (size == -1) {
823 mchip_free_frame();
824 goto again;
825 }
826 if (kfifo_get(meye.grabq, (unsigned char *)&reqnr,
827 sizeof(int)) != sizeof(int)) {
828 mchip_free_frame();
829 goto again;
830 }
831 memcpy(meye.grab_fbuffer + gbufsize * reqnr, meye.grab_temp,
832 size);
833 meye.grab_buffer[reqnr].size = size;
834 meye.grab_buffer[reqnr].state = MEYE_BUF_DONE;
835 do_gettimeofday(&meye.grab_buffer[reqnr].timestamp);
836 meye.grab_buffer[reqnr].sequence = sequence++;
837 kfifo_put(meye.doneq, (unsigned char *)&reqnr, sizeof(int));
838 wake_up_interruptible(&meye.proc_list);
839 }
840 mchip_free_frame();
841 goto again;
842}
843
844/****************************************************************************/
845/* video4linux integration */
846/****************************************************************************/
847
848static int meye_open(struct inode *inode, struct file *file)
849{
850 int i, err;
851
852 err = video_exclusive_open(inode, file);
853 if (err < 0)
854 return err;
855
856 mchip_hic_stop();
857
858 if (mchip_dma_alloc()) {
859 printk(KERN_ERR "meye: mchip framebuffer allocation failed\n");
860 video_exclusive_release(inode, file);
861 return -ENOBUFS;
862 }
863
864 for (i = 0; i < MEYE_MAX_BUFNBRS; i++)
865 meye.grab_buffer[i].state = MEYE_BUF_UNUSED;
866 kfifo_reset(meye.grabq);
867 kfifo_reset(meye.doneq);
868 return 0;
869}
870
871static int meye_release(struct inode *inode, struct file *file)
872{
873 mchip_hic_stop();
874 mchip_dma_free();
875 video_exclusive_release(inode, file);
876 return 0;
877}
878
879static int meye_do_ioctl(struct inode *inode, struct file *file,
880 unsigned int cmd, void *arg)
881{
882 switch (cmd) {
883
884 case VIDIOCGCAP: {
885 struct video_capability *b = arg;
886 strcpy(b->name,meye.video_dev->name);
887 b->type = VID_TYPE_CAPTURE;
888 b->channels = 1;
889 b->audios = 0;
890 b->maxwidth = 640;
891 b->maxheight = 480;
892 b->minwidth = 320;
893 b->minheight = 240;
894 break;
895 }
896
897 case VIDIOCGCHAN: {
898 struct video_channel *v = arg;
899 v->flags = 0;
900 v->tuners = 0;
901 v->type = VIDEO_TYPE_CAMERA;
902 if (v->channel != 0)
903 return -EINVAL;
904 strcpy(v->name,"Camera");
905 break;
906 }
907
908 case VIDIOCSCHAN: {
909 struct video_channel *v = arg;
910 if (v->channel != 0)
911 return -EINVAL;
912 break;
913 }
914
915 case VIDIOCGPICT: {
916 struct video_picture *p = arg;
917 *p = meye.picture;
918 break;
919 }
920
921 case VIDIOCSPICT: {
922 struct video_picture *p = arg;
923 if (p->depth != 16)
924 return -EINVAL;
925 if (p->palette != VIDEO_PALETTE_YUV422)
926 return -EINVAL;
927 down(&meye.lock);
928 sonypi_camera_command(SONYPI_COMMAND_SETCAMERABRIGHTNESS,
929 p->brightness >> 10);
930 sonypi_camera_command(SONYPI_COMMAND_SETCAMERAHUE,
931 p->hue >> 10);
932 sonypi_camera_command(SONYPI_COMMAND_SETCAMERACOLOR,
933 p->colour >> 10);
934 sonypi_camera_command(SONYPI_COMMAND_SETCAMERACONTRAST,
935 p->contrast >> 10);
936 meye.picture = *p;
937 up(&meye.lock);
938 break;
939 }
940
941 case VIDIOCSYNC: {
942 int *i = arg;
943 int unused;
944
945 if (*i < 0 || *i >= gbuffers)
946 return -EINVAL;
947
948 down(&meye.lock);
949
950 switch (meye.grab_buffer[*i].state) {
951
952 case MEYE_BUF_UNUSED:
953 up(&meye.lock);
954 return -EINVAL;
955 case MEYE_BUF_USING:
956 if (file->f_flags & O_NONBLOCK) {
957 up(&meye.lock);
958 return -EAGAIN;
959 }
960 if (wait_event_interruptible(meye.proc_list,
961 (meye.grab_buffer[*i].state != MEYE_BUF_USING))) {
962 up(&meye.lock);
963 return -EINTR;
964 }
965 /* fall through */
966 case MEYE_BUF_DONE:
967 meye.grab_buffer[*i].state = MEYE_BUF_UNUSED;
968 kfifo_get(meye.doneq, (unsigned char *)&unused, sizeof(int));
969 }
970 up(&meye.lock);
971 break;
972 }
973
974 case VIDIOCMCAPTURE: {
975 struct video_mmap *vm = arg;
976 int restart = 0;
977
978 if (vm->frame >= gbuffers || vm->frame < 0)
979 return -EINVAL;
980 if (vm->format != VIDEO_PALETTE_YUV422)
981 return -EINVAL;
982 if (vm->height * vm->width * 2 > gbufsize)
983 return -EINVAL;
984 if (!meye.grab_fbuffer)
985 return -EINVAL;
986 if (meye.grab_buffer[vm->frame].state != MEYE_BUF_UNUSED)
987 return -EBUSY;
988
989 down(&meye.lock);
990 if (vm->width == 640 && vm->height == 480) {
991 if (meye.params.subsample) {
992 meye.params.subsample = 0;
993 restart = 1;
994 }
995 } else if (vm->width == 320 && vm->height == 240) {
996 if (!meye.params.subsample) {
997 meye.params.subsample = 1;
998 restart = 1;
999 }
1000 } else {
1001 up(&meye.lock);
1002 return -EINVAL;
1003 }
1004
1005 if (restart || meye.mchip_mode != MCHIP_HIC_MODE_CONT_OUT)
1006 mchip_continuous_start();
1007 meye.grab_buffer[vm->frame].state = MEYE_BUF_USING;
1008 kfifo_put(meye.grabq, (unsigned char *)&vm->frame, sizeof(int));
1009 up(&meye.lock);
1010 break;
1011 }
1012
1013 case VIDIOCGMBUF: {
1014 struct video_mbuf *vm = arg;
1015 int i;
1016
1017 memset(vm, 0 , sizeof(*vm));
1018 vm->size = gbufsize * gbuffers;
1019 vm->frames = gbuffers;
1020 for (i = 0; i < gbuffers; i++)
1021 vm->offsets[i] = i * gbufsize;
1022 break;
1023 }
1024
1025 case MEYEIOC_G_PARAMS: {
1026 struct meye_params *p = arg;
1027 *p = meye.params;
1028 break;
1029 }
1030
1031 case MEYEIOC_S_PARAMS: {
1032 struct meye_params *jp = arg;
1033 if (jp->subsample > 1)
1034 return -EINVAL;
1035 if (jp->quality > 10)
1036 return -EINVAL;
1037 if (jp->sharpness > 63 || jp->agc > 63 || jp->picture > 63)
1038 return -EINVAL;
1039 if (jp->framerate > 31)
1040 return -EINVAL;
1041 down(&meye.lock);
1042 if (meye.params.subsample != jp->subsample ||
1043 meye.params.quality != jp->quality)
1044 mchip_hic_stop(); /* need restart */
1045 meye.params = *jp;
1046 sonypi_camera_command(SONYPI_COMMAND_SETCAMERASHARPNESS,
1047 meye.params.sharpness);
1048 sonypi_camera_command(SONYPI_COMMAND_SETCAMERAAGC,
1049 meye.params.agc);
1050 sonypi_camera_command(SONYPI_COMMAND_SETCAMERAPICTURE,
1051 meye.params.picture);
1052 up(&meye.lock);
1053 break;
1054 }
1055
1056 case MEYEIOC_QBUF_CAPT: {
1057 int *nb = arg;
1058
1059 if (!meye.grab_fbuffer)
1060 return -EINVAL;
1061 if (*nb >= gbuffers)
1062 return -EINVAL;
1063 if (*nb < 0) {
1064 /* stop capture */
1065 mchip_hic_stop();
1066 return 0;
1067 }
1068 if (meye.grab_buffer[*nb].state != MEYE_BUF_UNUSED)
1069 return -EBUSY;
1070 down(&meye.lock);
1071 if (meye.mchip_mode != MCHIP_HIC_MODE_CONT_COMP)
1072 mchip_cont_compression_start();
1073 meye.grab_buffer[*nb].state = MEYE_BUF_USING;
1074 kfifo_put(meye.grabq, (unsigned char *)nb, sizeof(int));
1075 up(&meye.lock);
1076 break;
1077 }
1078
1079 case MEYEIOC_SYNC: {
1080 int *i = arg;
1081 int unused;
1082
1083 if (*i < 0 || *i >= gbuffers)
1084 return -EINVAL;
1085
1086 down(&meye.lock);
1087 switch (meye.grab_buffer[*i].state) {
1088
1089 case MEYE_BUF_UNUSED:
1090 up(&meye.lock);
1091 return -EINVAL;
1092 case MEYE_BUF_USING:
1093 if (file->f_flags & O_NONBLOCK) {
1094 up(&meye.lock);
1095 return -EAGAIN;
1096 }
1097 if (wait_event_interruptible(meye.proc_list,
1098 (meye.grab_buffer[*i].state != MEYE_BUF_USING))) {
1099 up(&meye.lock);
1100 return -EINTR;
1101 }
1102 /* fall through */
1103 case MEYE_BUF_DONE:
1104 meye.grab_buffer[*i].state = MEYE_BUF_UNUSED;
1105 kfifo_get(meye.doneq, (unsigned char *)&unused, sizeof(int));
1106 }
1107 *i = meye.grab_buffer[*i].size;
1108 up(&meye.lock);
1109 break;
1110 }
1111
1112 case MEYEIOC_STILLCAPT: {
1113
1114 if (!meye.grab_fbuffer)
1115 return -EINVAL;
1116 if (meye.grab_buffer[0].state != MEYE_BUF_UNUSED)
1117 return -EBUSY;
1118 down(&meye.lock);
1119 meye.grab_buffer[0].state = MEYE_BUF_USING;
1120 mchip_take_picture();
1121 mchip_get_picture(
1122 meye.grab_fbuffer,
1123 mchip_hsize() * mchip_vsize() * 2);
1124 meye.grab_buffer[0].state = MEYE_BUF_DONE;
1125 up(&meye.lock);
1126 break;
1127 }
1128
1129 case MEYEIOC_STILLJCAPT: {
1130 int *len = arg;
1131
1132 if (!meye.grab_fbuffer)
1133 return -EINVAL;
1134 if (meye.grab_buffer[0].state != MEYE_BUF_UNUSED)
1135 return -EBUSY;
1136 down(&meye.lock);
1137 meye.grab_buffer[0].state = MEYE_BUF_USING;
1138 *len = -1;
1139 while (*len == -1) {
1140 mchip_take_picture();
1141 *len = mchip_compress_frame(meye.grab_fbuffer, gbufsize);
1142 }
1143 meye.grab_buffer[0].state = MEYE_BUF_DONE;
1144 up(&meye.lock);
1145 break;
1146 }
1147
1148 case VIDIOC_QUERYCAP: {
1149 struct v4l2_capability *cap = arg;
1150
1151 if (forcev4l1)
1152 return -EINVAL;
1153
1154 memset(cap, 0, sizeof(*cap));
1155 strcpy(cap->driver, "meye");
1156 strcpy(cap->card, "meye");
1157 sprintf(cap->bus_info, "PCI:%s", pci_name(meye.mchip_dev));
1158 cap->version = (MEYE_DRIVER_MAJORVERSION << 8) +
1159 MEYE_DRIVER_MINORVERSION;
1160 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE |
1161 V4L2_CAP_STREAMING;
1162 break;
1163 }
1164
1165 case VIDIOC_ENUMINPUT: {
1166 struct v4l2_input *i = arg;
1167
1168 if (i->index != 0)
1169 return -EINVAL;
1170 memset(i, 0, sizeof(*i));
1171 i->index = 0;
1172 strcpy(i->name, "Camera");
1173 i->type = V4L2_INPUT_TYPE_CAMERA;
1174 break;
1175 }
1176
1177 case VIDIOC_G_INPUT: {
1178 int *i = arg;
1179
1180 *i = 0;
1181 break;
1182 }
1183
1184 case VIDIOC_S_INPUT: {
1185 int *i = arg;
1186
1187 if (*i != 0)
1188 return -EINVAL;
1189 break;
1190 }
1191
1192 case VIDIOC_QUERYCTRL: {
1193 struct v4l2_queryctrl *c = arg;
1194
1195 switch (c->id) {
1196
1197 case V4L2_CID_BRIGHTNESS:
1198 c->type = V4L2_CTRL_TYPE_INTEGER;
1199 strcpy(c->name, "Brightness");
1200 c->minimum = 0;
1201 c->maximum = 63;
1202 c->step = 1;
1203 c->default_value = 32;
1204 c->flags = 0;
1205 break;
1206 case V4L2_CID_HUE:
1207 c->type = V4L2_CTRL_TYPE_INTEGER;
1208 strcpy(c->name, "Hue");
1209 c->minimum = 0;
1210 c->maximum = 63;
1211 c->step = 1;
1212 c->default_value = 32;
1213 c->flags = 0;
1214 break;
1215 case V4L2_CID_CONTRAST:
1216 c->type = V4L2_CTRL_TYPE_INTEGER;
1217 strcpy(c->name, "Contrast");
1218 c->minimum = 0;
1219 c->maximum = 63;
1220 c->step = 1;
1221 c->default_value = 32;
1222 c->flags = 0;
1223 break;
1224 case V4L2_CID_SATURATION:
1225 c->type = V4L2_CTRL_TYPE_INTEGER;
1226 strcpy(c->name, "Saturation");
1227 c->minimum = 0;
1228 c->maximum = 63;
1229 c->step = 1;
1230 c->default_value = 32;
1231 c->flags = 0;
1232 break;
1233 case V4L2_CID_AGC:
1234 c->type = V4L2_CTRL_TYPE_INTEGER;
1235 strcpy(c->name, "Agc");
1236 c->minimum = 0;
1237 c->maximum = 63;
1238 c->step = 1;
1239 c->default_value = 48;
1240 c->flags = 0;
1241 break;
1242 case V4L2_CID_SHARPNESS:
1243 c->type = V4L2_CTRL_TYPE_INTEGER;
1244 strcpy(c->name, "Sharpness");
1245 c->minimum = 0;
1246 c->maximum = 63;
1247 c->step = 1;
1248 c->default_value = 32;
1249 c->flags = 0;
1250 break;
1251 case V4L2_CID_PICTURE:
1252 c->type = V4L2_CTRL_TYPE_INTEGER;
1253 strcpy(c->name, "Picture");
1254 c->minimum = 0;
1255 c->maximum = 63;
1256 c->step = 1;
1257 c->default_value = 0;
1258 c->flags = 0;
1259 break;
1260 case V4L2_CID_JPEGQUAL:
1261 c->type = V4L2_CTRL_TYPE_INTEGER;
1262 strcpy(c->name, "JPEG quality");
1263 c->minimum = 0;
1264 c->maximum = 10;
1265 c->step = 1;
1266 c->default_value = 8;
1267 c->flags = 0;
1268 break;
1269 case V4L2_CID_FRAMERATE:
1270 c->type = V4L2_CTRL_TYPE_INTEGER;
1271 strcpy(c->name, "Framerate");
1272 c->minimum = 0;
1273 c->maximum = 31;
1274 c->step = 1;
1275 c->default_value = 0;
1276 c->flags = 0;
1277 break;
1278 default:
1279 return -EINVAL;
1280 }
1281 break;
1282 }
1283
1284 case VIDIOC_S_CTRL: {
1285 struct v4l2_control *c = arg;
1286
1287 down(&meye.lock);
1288 switch (c->id) {
1289 case V4L2_CID_BRIGHTNESS:
1290 sonypi_camera_command(
1291 SONYPI_COMMAND_SETCAMERABRIGHTNESS, c->value);
1292 meye.picture.brightness = c->value << 10;
1293 break;
1294 case V4L2_CID_HUE:
1295 sonypi_camera_command(
1296 SONYPI_COMMAND_SETCAMERAHUE, c->value);
1297 meye.picture.hue = c->value << 10;
1298 break;
1299 case V4L2_CID_CONTRAST:
1300 sonypi_camera_command(
1301 SONYPI_COMMAND_SETCAMERACONTRAST, c->value);
1302 meye.picture.contrast = c->value << 10;
1303 break;
1304 case V4L2_CID_SATURATION:
1305 sonypi_camera_command(
1306 SONYPI_COMMAND_SETCAMERACOLOR, c->value);
1307 meye.picture.colour = c->value << 10;
1308 break;
1309 case V4L2_CID_AGC:
1310 sonypi_camera_command(
1311 SONYPI_COMMAND_SETCAMERAAGC, c->value);
1312 meye.params.agc = c->value;
1313 break;
1314 case V4L2_CID_SHARPNESS:
1315 sonypi_camera_command(
1316 SONYPI_COMMAND_SETCAMERASHARPNESS, c->value);
1317 meye.params.sharpness = c->value;
1318 break;
1319 case V4L2_CID_PICTURE:
1320 sonypi_camera_command(
1321 SONYPI_COMMAND_SETCAMERAPICTURE, c->value);
1322 meye.params.picture = c->value;
1323 break;
1324 case V4L2_CID_JPEGQUAL:
1325 meye.params.quality = c->value;
1326 break;
1327 case V4L2_CID_FRAMERATE:
1328 meye.params.framerate = c->value;
1329 break;
1330 default:
1331 up(&meye.lock);
1332 return -EINVAL;
1333 }
1334 up(&meye.lock);
1335 break;
1336 }
1337
1338 case VIDIOC_G_CTRL: {
1339 struct v4l2_control *c = arg;
1340
1341 down(&meye.lock);
1342 switch (c->id) {
1343 case V4L2_CID_BRIGHTNESS:
1344 c->value = meye.picture.brightness >> 10;
1345 break;
1346 case V4L2_CID_HUE:
1347 c->value = meye.picture.hue >> 10;
1348 break;
1349 case V4L2_CID_CONTRAST:
1350 c->value = meye.picture.contrast >> 10;
1351 break;
1352 case V4L2_CID_SATURATION:
1353 c->value = meye.picture.colour >> 10;
1354 break;
1355 case V4L2_CID_AGC:
1356 c->value = meye.params.agc;
1357 break;
1358 case V4L2_CID_SHARPNESS:
1359 c->value = meye.params.sharpness;
1360 break;
1361 case V4L2_CID_PICTURE:
1362 c->value = meye.params.picture;
1363 break;
1364 case V4L2_CID_JPEGQUAL:
1365 c->value = meye.params.quality;
1366 break;
1367 case V4L2_CID_FRAMERATE:
1368 c->value = meye.params.framerate;
1369 break;
1370 default:
1371 up(&meye.lock);
1372 return -EINVAL;
1373 }
1374 up(&meye.lock);
1375 break;
1376 }
1377
1378 case VIDIOC_ENUM_FMT: {
1379 struct v4l2_fmtdesc *f = arg;
1380
1381 if (f->index > 1)
1382 return -EINVAL;
1383 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1384 return -EINVAL;
1385 if (f->index == 0) {
1386 /* standard YUV 422 capture */
1387 memset(f, 0, sizeof(*f));
1388 f->index = 0;
1389 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1390 f->flags = 0;
1391 strcpy(f->description, "YUV422");
1392 f->pixelformat = V4L2_PIX_FMT_YUYV;
1393 } else {
1394 /* compressed MJPEG capture */
1395 memset(f, 0, sizeof(*f));
1396 f->index = 1;
1397 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1398 f->flags = V4L2_FMT_FLAG_COMPRESSED;
1399 strcpy(f->description, "MJPEG");
1400 f->pixelformat = V4L2_PIX_FMT_MJPEG;
1401 }
1402 break;
1403 }
1404
1405 case VIDIOC_TRY_FMT: {
1406 struct v4l2_format *f = arg;
1407
1408 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1409 return -EINVAL;
1410 if (f->fmt.pix.pixelformat != V4L2_PIX_FMT_YUYV &&
1411 f->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG)
1412 return -EINVAL;
1413 if (f->fmt.pix.field != V4L2_FIELD_ANY &&
1414 f->fmt.pix.field != V4L2_FIELD_NONE)
1415 return -EINVAL;
1416 f->fmt.pix.field = V4L2_FIELD_NONE;
1417 if (f->fmt.pix.width <= 320) {
1418 f->fmt.pix.width = 320;
1419 f->fmt.pix.height = 240;
1420 } else {
1421 f->fmt.pix.width = 640;
1422 f->fmt.pix.height = 480;
1423 }
1424 f->fmt.pix.bytesperline = f->fmt.pix.width * 2;
1425 f->fmt.pix.sizeimage = f->fmt.pix.height *
1426 f->fmt.pix.bytesperline;
1427 f->fmt.pix.colorspace = 0;
1428 f->fmt.pix.priv = 0;
1429 break;
1430 }
1431
1432 case VIDIOC_G_FMT: {
1433 struct v4l2_format *f = arg;
1434
1435 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1436 return -EINVAL;
1437 memset(&f->fmt.pix, 0, sizeof(struct v4l2_pix_format));
1438 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1439 switch (meye.mchip_mode) {
1440 case MCHIP_HIC_MODE_CONT_OUT:
1441 default:
1442 f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
1443 break;
1444 case MCHIP_HIC_MODE_CONT_COMP:
1445 f->fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG;
1446 break;
1447 }
1448 f->fmt.pix.field = V4L2_FIELD_NONE;
1449 f->fmt.pix.width = mchip_hsize();
1450 f->fmt.pix.height = mchip_vsize();
1451 f->fmt.pix.bytesperline = f->fmt.pix.width * 2;
1452 f->fmt.pix.sizeimage = f->fmt.pix.height *
1453 f->fmt.pix.bytesperline;
1454 f->fmt.pix.colorspace = 0;
1455 f->fmt.pix.priv = 0;
1456 break;
1457 }
1458
1459 case VIDIOC_S_FMT: {
1460 struct v4l2_format *f = arg;
1461
1462 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1463 return -EINVAL;
1464 if (f->fmt.pix.pixelformat != V4L2_PIX_FMT_YUYV &&
1465 f->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG)
1466 return -EINVAL;
1467 if (f->fmt.pix.field != V4L2_FIELD_ANY &&
1468 f->fmt.pix.field != V4L2_FIELD_NONE)
1469 return -EINVAL;
1470 f->fmt.pix.field = V4L2_FIELD_NONE;
1471 down(&meye.lock);
1472 if (f->fmt.pix.width <= 320) {
1473 f->fmt.pix.width = 320;
1474 f->fmt.pix.height = 240;
1475 meye.params.subsample = 1;
1476 } else {
1477 f->fmt.pix.width = 640;
1478 f->fmt.pix.height = 480;
1479 meye.params.subsample = 0;
1480 }
1481 switch (f->fmt.pix.pixelformat) {
1482 case V4L2_PIX_FMT_YUYV:
1483 meye.mchip_mode = MCHIP_HIC_MODE_CONT_OUT;
1484 break;
1485 case V4L2_PIX_FMT_MJPEG:
1486 meye.mchip_mode = MCHIP_HIC_MODE_CONT_COMP;
1487 break;
1488 }
1489 up(&meye.lock);
1490 f->fmt.pix.bytesperline = f->fmt.pix.width * 2;
1491 f->fmt.pix.sizeimage = f->fmt.pix.height *
1492 f->fmt.pix.bytesperline;
1493 f->fmt.pix.colorspace = 0;
1494 f->fmt.pix.priv = 0;
1495
1496 break;
1497 }
1498
1499 case VIDIOC_REQBUFS: {
1500 struct v4l2_requestbuffers *req = arg;
1501 int i;
1502
1503 if (req->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1504 return -EINVAL;
1505 if (req->memory != V4L2_MEMORY_MMAP)
1506 return -EINVAL;
1507 if (meye.grab_fbuffer && req->count == gbuffers) {
1508 /* already allocated, no modifications */
1509 break;
1510 }
1511 down(&meye.lock);
1512 if (meye.grab_fbuffer) {
1513 for (i = 0; i < gbuffers; i++)
1514 if (meye.vma_use_count[i]) {
1515 up(&meye.lock);
1516 return -EINVAL;
1517 }
1518 rvfree(meye.grab_fbuffer, gbuffers * gbufsize);
1519 meye.grab_fbuffer = NULL;
1520 }
1521 gbuffers = max(2, min((int)req->count, MEYE_MAX_BUFNBRS));
1522 req->count = gbuffers;
1523 meye.grab_fbuffer = rvmalloc(gbuffers * gbufsize);
1524 if (!meye.grab_fbuffer) {
1525 printk(KERN_ERR "meye: v4l framebuffer allocation"
1526 " failed\n");
1527 up(&meye.lock);
1528 return -ENOMEM;
1529 }
1530 for (i = 0; i < gbuffers; i++)
1531 meye.vma_use_count[i] = 0;
1532 up(&meye.lock);
1533 break;
1534 }
1535
1536 case VIDIOC_QUERYBUF: {
1537 struct v4l2_buffer *buf = arg;
1538 int index = buf->index;
1539
1540 if (index < 0 || index >= gbuffers)
1541 return -EINVAL;
1542 memset(buf, 0, sizeof(*buf));
1543 buf->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1544 buf->index = index;
1545 buf->bytesused = meye.grab_buffer[index].size;
1546 buf->flags = V4L2_BUF_FLAG_MAPPED;
1547 if (meye.grab_buffer[index].state == MEYE_BUF_USING)
1548 buf->flags |= V4L2_BUF_FLAG_QUEUED;
1549 if (meye.grab_buffer[index].state == MEYE_BUF_DONE)
1550 buf->flags |= V4L2_BUF_FLAG_DONE;
1551 buf->field = V4L2_FIELD_NONE;
1552 buf->timestamp = meye.grab_buffer[index].timestamp;
1553 buf->sequence = meye.grab_buffer[index].sequence;
1554 buf->memory = V4L2_MEMORY_MMAP;
1555 buf->m.offset = index * gbufsize;
1556 buf->length = gbufsize;
1557 break;
1558 }
1559
1560 case VIDIOC_QBUF: {
1561 struct v4l2_buffer *buf = arg;
1562
1563 if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1564 return -EINVAL;
1565 if (buf->memory != V4L2_MEMORY_MMAP)
1566 return -EINVAL;
1567 if (buf->index < 0 || buf->index >= gbuffers)
1568 return -EINVAL;
1569 if (meye.grab_buffer[buf->index].state != MEYE_BUF_UNUSED)
1570 return -EINVAL;
1571 down(&meye.lock);
1572 buf->flags |= V4L2_BUF_FLAG_QUEUED;
1573 buf->flags &= ~V4L2_BUF_FLAG_DONE;
1574 meye.grab_buffer[buf->index].state = MEYE_BUF_USING;
1575 kfifo_put(meye.grabq, (unsigned char *)&buf->index, sizeof(int));
1576 up(&meye.lock);
1577 break;
1578 }
1579
1580 case VIDIOC_DQBUF: {
1581 struct v4l2_buffer *buf = arg;
1582 int reqnr;
1583
1584 if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1585 return -EINVAL;
1586 if (buf->memory != V4L2_MEMORY_MMAP)
1587 return -EINVAL;
1588
1589 down(&meye.lock);
1590 if (kfifo_len(meye.doneq) == 0 && file->f_flags & O_NONBLOCK) {
1591 up(&meye.lock);
1592 return -EAGAIN;
1593 }
1594 if (wait_event_interruptible(meye.proc_list,
1595 kfifo_len(meye.doneq) != 0) < 0) {
1596 up(&meye.lock);
1597 return -EINTR;
1598 }
1599 if (!kfifo_get(meye.doneq, (unsigned char *)&reqnr,
1600 sizeof(int))) {
1601 up(&meye.lock);
1602 return -EBUSY;
1603 }
1604 if (meye.grab_buffer[reqnr].state != MEYE_BUF_DONE) {
1605 up(&meye.lock);
1606 return -EINVAL;
1607 }
1608 buf->index = reqnr;
1609 buf->bytesused = meye.grab_buffer[reqnr].size;
1610 buf->flags = V4L2_BUF_FLAG_MAPPED;
1611 buf->field = V4L2_FIELD_NONE;
1612 buf->timestamp = meye.grab_buffer[reqnr].timestamp;
1613 buf->sequence = meye.grab_buffer[reqnr].sequence;
1614 buf->memory = V4L2_MEMORY_MMAP;
1615 buf->m.offset = reqnr * gbufsize;
1616 buf->length = gbufsize;
1617 meye.grab_buffer[reqnr].state = MEYE_BUF_UNUSED;
1618 up(&meye.lock);
1619 break;
1620 }
1621
1622 case VIDIOC_STREAMON: {
1623 down(&meye.lock);
1624 switch (meye.mchip_mode) {
1625 case MCHIP_HIC_MODE_CONT_OUT:
1626 mchip_continuous_start();
1627 break;
1628 case MCHIP_HIC_MODE_CONT_COMP:
1629 mchip_cont_compression_start();
1630 break;
1631 default:
1632 up(&meye.lock);
1633 return -EINVAL;
1634 }
1635 up(&meye.lock);
1636 break;
1637 }
1638
1639 case VIDIOC_STREAMOFF: {
1640 int i;
1641
1642 down(&meye.lock);
1643 mchip_hic_stop();
1644 kfifo_reset(meye.grabq);
1645 kfifo_reset(meye.doneq);
1646 for (i = 0; i < MEYE_MAX_BUFNBRS; i++)
1647 meye.grab_buffer[i].state = MEYE_BUF_UNUSED;
1648 up(&meye.lock);
1649 break;
1650 }
1651
1652 /*
1653 * XXX what about private snapshot ioctls ?
1654 * Do they need to be converted to V4L2 ?
1655 */
1656
1657 default:
1658 return -ENOIOCTLCMD;
1659 }
1660
1661 return 0;
1662}
1663
1664static int meye_ioctl(struct inode *inode, struct file *file,
1665 unsigned int cmd, unsigned long arg)
1666{
1667 return video_usercopy(inode, file, cmd, arg, meye_do_ioctl);
1668}
1669
1670static unsigned int meye_poll(struct file *file, poll_table *wait)
1671{
1672 unsigned int res = 0;
1673
1674 down(&meye.lock);
1675 poll_wait(file, &meye.proc_list, wait);
1676 if (kfifo_len(meye.doneq))
1677 res = POLLIN | POLLRDNORM;
1678 up(&meye.lock);
1679 return res;
1680}
1681
1682static void meye_vm_open(struct vm_area_struct *vma)
1683{
1684 int idx = (int)vma->vm_private_data;
1685 meye.vma_use_count[idx]++;
1686}
1687
1688static void meye_vm_close(struct vm_area_struct *vma)
1689{
1690 int idx = (int)vma->vm_private_data;
1691 meye.vma_use_count[idx]--;
1692}
1693
1694static struct vm_operations_struct meye_vm_ops = {
1695 .open = meye_vm_open,
1696 .close = meye_vm_close,
1697};
1698
1699static int meye_mmap(struct file *file, struct vm_area_struct *vma)
1700{
1701 unsigned long start = vma->vm_start;
1702 unsigned long size = vma->vm_end - vma->vm_start;
1703 unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
1704 unsigned long page, pos;
1705
1706 down(&meye.lock);
1707 if (size > gbuffers * gbufsize) {
1708 up(&meye.lock);
1709 return -EINVAL;
1710 }
1711 if (!meye.grab_fbuffer) {
1712 int i;
1713
1714 /* lazy allocation */
1715 meye.grab_fbuffer = rvmalloc(gbuffers*gbufsize);
1716 if (!meye.grab_fbuffer) {
1717 printk(KERN_ERR "meye: v4l framebuffer allocation failed\n");
1718 up(&meye.lock);
1719 return -ENOMEM;
1720 }
1721 for (i = 0; i < gbuffers; i++)
1722 meye.vma_use_count[i] = 0;
1723 }
1724 pos = (unsigned long)meye.grab_fbuffer + offset;
1725
1726 while (size > 0) {
1727 page = vmalloc_to_pfn((void *)pos);
1728 if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) {
1729 up(&meye.lock);
1730 return -EAGAIN;
1731 }
1732 start += PAGE_SIZE;
1733 pos += PAGE_SIZE;
1734 if (size > PAGE_SIZE)
1735 size -= PAGE_SIZE;
1736 else
1737 size = 0;
1738 }
1739
1740 vma->vm_ops = &meye_vm_ops;
1741 vma->vm_flags &= ~VM_IO; /* not I/O memory */
1742 vma->vm_flags |= VM_RESERVED; /* avoid to swap out this VMA */
1743 vma->vm_private_data = (void *) (offset / gbufsize);
1744 meye_vm_open(vma);
1745
1746 up(&meye.lock);
1747 return 0;
1748}
1749
1750static struct file_operations meye_fops = {
1751 .owner = THIS_MODULE,
1752 .open = meye_open,
1753 .release = meye_release,
1754 .mmap = meye_mmap,
1755 .ioctl = meye_ioctl,
1756 .poll = meye_poll,
1757 .llseek = no_llseek,
1758};
1759
1760static struct video_device meye_template = {
1761 .owner = THIS_MODULE,
1762 .name = "meye",
1763 .type = VID_TYPE_CAPTURE,
1764 .hardware = VID_HARDWARE_MEYE,
1765 .fops = &meye_fops,
1766 .release = video_device_release,
1767 .minor = -1,
1768};
1769
1770#ifdef CONFIG_PM
1771static int meye_suspend(struct pci_dev *pdev, u32 state)
1772{
1773 pci_save_state(pdev);
1774 meye.pm_mchip_mode = meye.mchip_mode;
1775 mchip_hic_stop();
1776 mchip_set(MCHIP_MM_INTA, 0x0);
1777 return 0;
1778}
1779
1780static int meye_resume(struct pci_dev *pdev)
1781{
1782 pci_restore_state(pdev);
1783 pci_write_config_word(meye.mchip_dev, MCHIP_PCI_SOFTRESET_SET, 1);
1784
1785 mchip_delay(MCHIP_HIC_CMD, 0);
1786 mchip_delay(MCHIP_HIC_STATUS, MCHIP_HIC_STATUS_IDLE);
1787 msleep(1);
1788 mchip_set(MCHIP_VRJ_SOFT_RESET, 1);
1789 msleep(1);
1790 mchip_set(MCHIP_MM_PCI_MODE, 5);
1791 msleep(1);
1792 mchip_set(MCHIP_MM_INTA, MCHIP_MM_INTA_HIC_1_MASK);
1793
1794 switch (meye.pm_mchip_mode) {
1795 case MCHIP_HIC_MODE_CONT_OUT:
1796 mchip_continuous_start();
1797 break;
1798 case MCHIP_HIC_MODE_CONT_COMP:
1799 mchip_cont_compression_start();
1800 break;
1801 }
1802 return 0;
1803}
1804#endif
1805
1806static int __devinit meye_probe(struct pci_dev *pcidev,
1807 const struct pci_device_id *ent)
1808{
1809 int ret = -EBUSY;
1810 unsigned long mchip_adr;
1811 u8 revision;
1812
1813 if (meye.mchip_dev != NULL) {
1814 printk(KERN_ERR "meye: only one device allowed!\n");
1815 goto outnotdev;
1816 }
1817
1818 meye.mchip_dev = pcidev;
1819 meye.video_dev = video_device_alloc();
1820 if (!meye.video_dev) {
1821 printk(KERN_ERR "meye: video_device_alloc() failed!\n");
1822 goto outnotdev;
1823 }
1824
1825 ret = -ENOMEM;
1826 meye.grab_temp = vmalloc(MCHIP_NB_PAGES_MJPEG * PAGE_SIZE);
1827 if (!meye.grab_temp) {
1828 printk(KERN_ERR "meye: grab buffer allocation failed\n");
1829 goto outvmalloc;
1830 }
1831
1832 spin_lock_init(&meye.grabq_lock);
1833 meye.grabq = kfifo_alloc(sizeof(int) * MEYE_MAX_BUFNBRS, GFP_KERNEL,
1834 &meye.grabq_lock);
1835 if (IS_ERR(meye.grabq)) {
1836 printk(KERN_ERR "meye: fifo allocation failed\n");
1837 goto outkfifoalloc1;
1838 }
1839 spin_lock_init(&meye.doneq_lock);
1840 meye.doneq = kfifo_alloc(sizeof(int) * MEYE_MAX_BUFNBRS, GFP_KERNEL,
1841 &meye.doneq_lock);
1842 if (IS_ERR(meye.doneq)) {
1843 printk(KERN_ERR "meye: fifo allocation failed\n");
1844 goto outkfifoalloc2;
1845 }
1846
1847 memcpy(meye.video_dev, &meye_template, sizeof(meye_template));
1848 meye.video_dev->dev = &meye.mchip_dev->dev;
1849
1850 if ((ret = sonypi_camera_command(SONYPI_COMMAND_SETCAMERA, 1))) {
1851 printk(KERN_ERR "meye: unable to power on the camera\n");
1852 printk(KERN_ERR "meye: did you enable the camera in "
1853 "sonypi using the module options ?\n");
1854 goto outsonypienable;
1855 }
1856
1857 ret = -EIO;
1858 if ((ret = pci_enable_device(meye.mchip_dev))) {
1859 printk(KERN_ERR "meye: pci_enable_device failed\n");
1860 goto outenabledev;
1861 }
1862
1863 mchip_adr = pci_resource_start(meye.mchip_dev,0);
1864 if (!mchip_adr) {
1865 printk(KERN_ERR "meye: mchip has no device base address\n");
1866 goto outregions;
1867 }
1868 if (!request_mem_region(pci_resource_start(meye.mchip_dev, 0),
1869 pci_resource_len(meye.mchip_dev, 0),
1870 "meye")) {
1871 printk(KERN_ERR "meye: request_mem_region failed\n");
1872 goto outregions;
1873 }
1874 meye.mchip_mmregs = ioremap(mchip_adr, MCHIP_MM_REGS);
1875 if (!meye.mchip_mmregs) {
1876 printk(KERN_ERR "meye: ioremap failed\n");
1877 goto outremap;
1878 }
1879
1880 meye.mchip_irq = pcidev->irq;
1881 if (request_irq(meye.mchip_irq, meye_irq,
1882 SA_INTERRUPT | SA_SHIRQ, "meye", meye_irq)) {
1883 printk(KERN_ERR "meye: request_irq failed\n");
1884 goto outreqirq;
1885 }
1886
1887 pci_read_config_byte(meye.mchip_dev, PCI_REVISION_ID, &revision);
1888 pci_write_config_byte(meye.mchip_dev, PCI_CACHE_LINE_SIZE, 8);
1889 pci_write_config_byte(meye.mchip_dev, PCI_LATENCY_TIMER, 64);
1890
1891 pci_set_master(meye.mchip_dev);
1892
1893 /* Ask the camera to perform a soft reset. */
1894 pci_write_config_word(meye.mchip_dev, MCHIP_PCI_SOFTRESET_SET, 1);
1895
1896 mchip_delay(MCHIP_HIC_CMD, 0);
1897 mchip_delay(MCHIP_HIC_STATUS, MCHIP_HIC_STATUS_IDLE);
1898
1899 msleep(1);
1900 mchip_set(MCHIP_VRJ_SOFT_RESET, 1);
1901
1902 msleep(1);
1903 mchip_set(MCHIP_MM_PCI_MODE, 5);
1904
1905 msleep(1);
1906 mchip_set(MCHIP_MM_INTA, MCHIP_MM_INTA_HIC_1_MASK);
1907
1908 if (video_register_device(meye.video_dev, VFL_TYPE_GRABBER,
1909 video_nr) < 0) {
1910 printk(KERN_ERR "meye: video_register_device failed\n");
1911 goto outvideoreg;
1912 }
1913
1914 init_MUTEX(&meye.lock);
1915 init_waitqueue_head(&meye.proc_list);
1916 meye.picture.depth = 16;
1917 meye.picture.palette = VIDEO_PALETTE_YUV422;
1918 meye.picture.brightness = 32 << 10;
1919 meye.picture.hue = 32 << 10;
1920 meye.picture.colour = 32 << 10;
1921 meye.picture.contrast = 32 << 10;
1922 meye.picture.whiteness = 0;
1923 meye.params.subsample = 0;
1924 meye.params.quality = 8;
1925 meye.params.sharpness = 32;
1926 meye.params.agc = 48;
1927 meye.params.picture = 0;
1928 meye.params.framerate = 0;
1929
1930 sonypi_camera_command(SONYPI_COMMAND_SETCAMERABRIGHTNESS, 32);
1931 sonypi_camera_command(SONYPI_COMMAND_SETCAMERAHUE, 32);
1932 sonypi_camera_command(SONYPI_COMMAND_SETCAMERACOLOR, 32);
1933 sonypi_camera_command(SONYPI_COMMAND_SETCAMERACONTRAST, 32);
1934 sonypi_camera_command(SONYPI_COMMAND_SETCAMERASHARPNESS, 32);
1935 sonypi_camera_command(SONYPI_COMMAND_SETCAMERAPICTURE, 0);
1936 sonypi_camera_command(SONYPI_COMMAND_SETCAMERAAGC, 48);
1937
1938 printk(KERN_INFO "meye: Motion Eye Camera Driver v%s.\n",
1939 MEYE_DRIVER_VERSION);
1940 printk(KERN_INFO "meye: mchip KL5A72002 rev. %d, base %lx, irq %d\n",
1941 revision, mchip_adr, meye.mchip_irq);
1942
1943 return 0;
1944
1945outvideoreg:
1946 free_irq(meye.mchip_irq, meye_irq);
1947outreqirq:
1948 iounmap(meye.mchip_mmregs);
1949outremap:
1950 release_mem_region(pci_resource_start(meye.mchip_dev, 0),
1951 pci_resource_len(meye.mchip_dev, 0));
1952outregions:
1953 pci_disable_device(meye.mchip_dev);
1954outenabledev:
1955 sonypi_camera_command(SONYPI_COMMAND_SETCAMERA, 0);
1956outsonypienable:
1957 kfifo_free(meye.doneq);
1958outkfifoalloc2:
1959 kfifo_free(meye.grabq);
1960outkfifoalloc1:
1961 vfree(meye.grab_temp);
1962outvmalloc:
1963 video_device_release(meye.video_dev);
1964outnotdev:
1965 return ret;
1966}
1967
1968static void __devexit meye_remove(struct pci_dev *pcidev)
1969{
1970 video_unregister_device(meye.video_dev);
1971
1972 mchip_hic_stop();
1973
1974 mchip_dma_free();
1975
1976 /* disable interrupts */
1977 mchip_set(MCHIP_MM_INTA, 0x0);
1978
1979 free_irq(meye.mchip_irq, meye_irq);
1980
1981 iounmap(meye.mchip_mmregs);
1982
1983 release_mem_region(pci_resource_start(meye.mchip_dev, 0),
1984 pci_resource_len(meye.mchip_dev, 0));
1985
1986 pci_disable_device(meye.mchip_dev);
1987
1988 sonypi_camera_command(SONYPI_COMMAND_SETCAMERA, 0);
1989
1990 kfifo_free(meye.doneq);
1991 kfifo_free(meye.grabq);
1992
1993 vfree(meye.grab_temp);
1994
1995 if (meye.grab_fbuffer) {
1996 rvfree(meye.grab_fbuffer, gbuffers*gbufsize);
1997 meye.grab_fbuffer = NULL;
1998 }
1999
2000 printk(KERN_INFO "meye: removed\n");
2001}
2002
2003static struct pci_device_id meye_pci_tbl[] = {
2004 { PCI_VENDOR_ID_KAWASAKI, PCI_DEVICE_ID_MCHIP_KL5A72002,
2005 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
2006 { }
2007};
2008
2009MODULE_DEVICE_TABLE(pci, meye_pci_tbl);
2010
2011static struct pci_driver meye_driver = {
2012 .name = "meye",
2013 .id_table = meye_pci_tbl,
2014 .probe = meye_probe,
2015 .remove = __devexit_p(meye_remove),
2016#ifdef CONFIG_PM
2017 .suspend = meye_suspend,
2018 .resume = meye_resume,
2019#endif
2020};
2021
2022static int __init meye_init(void)
2023{
2024 gbuffers = max(2, min((int)gbuffers, MEYE_MAX_BUFNBRS));
2025 if (gbufsize < 0 || gbufsize > MEYE_MAX_BUFSIZE)
2026 gbufsize = MEYE_MAX_BUFSIZE;
2027 gbufsize = PAGE_ALIGN(gbufsize);
2028 printk(KERN_INFO "meye: using %d buffers with %dk (%dk total)"
2029 "for capture\n",
2030 gbuffers,
2031 gbufsize / 1024, gbuffers * gbufsize / 1024);
2032 return pci_register_driver(&meye_driver);
2033}
2034
2035static void __exit meye_exit(void)
2036{
2037 pci_unregister_driver(&meye_driver);
2038}
2039
2040module_init(meye_init);
2041module_exit(meye_exit);
diff --git a/drivers/media/video/meye.h b/drivers/media/video/meye.h
new file mode 100644
index 00000000000..e8cd897b0d2
--- /dev/null
+++ b/drivers/media/video/meye.h
@@ -0,0 +1,318 @@
1/*
2 * Motion Eye video4linux driver for Sony Vaio PictureBook
3 *
4 * Copyright (C) 2001-2004 Stelian Pop <stelian@popies.net>
5 *
6 * Copyright (C) 2001-2002 Alcôve <www.alcove.com>
7 *
8 * Copyright (C) 2000 Andrew Tridgell <tridge@valinux.com>
9 *
10 * Earlier work by Werner Almesberger, Paul `Rusty' Russell and Paul Mackerras.
11 *
12 * Some parts borrowed from various video4linux drivers, especially
13 * bttv-driver.c and zoran.c, see original files for credits.
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 */
29
30#ifndef _MEYE_PRIV_H_
31#define _MEYE_PRIV_H_
32
33#define MEYE_DRIVER_MAJORVERSION 1
34#define MEYE_DRIVER_MINORVERSION 13
35
36#define MEYE_DRIVER_VERSION __stringify(MEYE_DRIVER_MAJORVERSION) "." \
37 __stringify(MEYE_DRIVER_MINORVERSION)
38
39#include <linux/config.h>
40#include <linux/types.h>
41#include <linux/pci.h>
42#include <linux/kfifo.h>
43
44/****************************************************************************/
45/* Motion JPEG chip registers */
46/****************************************************************************/
47
48/* Motion JPEG chip PCI configuration registers */
49#define MCHIP_PCI_POWER_CSR 0x54
50#define MCHIP_PCI_MCORE_STATUS 0x60 /* see HIC_STATUS */
51#define MCHIP_PCI_HOSTUSEREQ_SET 0x64
52#define MCHIP_PCI_HOSTUSEREQ_CLR 0x68
53#define MCHIP_PCI_LOWPOWER_SET 0x6c
54#define MCHIP_PCI_LOWPOWER_CLR 0x70
55#define MCHIP_PCI_SOFTRESET_SET 0x74
56
57/* Motion JPEG chip memory mapped registers */
58#define MCHIP_MM_REGS 0x200 /* 512 bytes */
59#define MCHIP_REG_TIMEOUT 1000 /* reg access, ~us */
60#define MCHIP_MCC_VRJ_TIMEOUT 1000 /* MCC & VRJ access */
61
62#define MCHIP_MM_PCI_MODE 0x00 /* PCI access mode */
63#define MCHIP_MM_PCI_MODE_RETRY 0x00000001 /* retry mode */
64#define MCHIP_MM_PCI_MODE_MASTER 0x00000002 /* master access */
65#define MCHIP_MM_PCI_MODE_READ_LINE 0x00000004 /* read line */
66
67#define MCHIP_MM_INTA 0x04 /* Int status/mask */
68#define MCHIP_MM_INTA_MCC 0x00000001 /* MCC interrupt */
69#define MCHIP_MM_INTA_VRJ 0x00000002 /* VRJ interrupt */
70#define MCHIP_MM_INTA_HIC_1 0x00000004 /* one frame done */
71#define MCHIP_MM_INTA_HIC_1_MASK 0x00000400 /* 1: enable */
72#define MCHIP_MM_INTA_HIC_END 0x00000008 /* all frames done */
73#define MCHIP_MM_INTA_HIC_END_MASK 0x00000800
74#define MCHIP_MM_INTA_JPEG 0x00000010 /* decompress. error */
75#define MCHIP_MM_INTA_JPEG_MASK 0x00001000
76#define MCHIP_MM_INTA_CAPTURE 0x00000020 /* capture end */
77#define MCHIP_MM_INTA_PCI_ERR 0x00000040 /* PCI error */
78#define MCHIP_MM_INTA_PCI_ERR_MASK 0x00004000
79
80#define MCHIP_MM_PT_ADDR 0x08 /* page table address*/
81 /* n*4kB */
82#define MCHIP_NB_PAGES 1024 /* pages for display */
83#define MCHIP_NB_PAGES_MJPEG 256 /* pages for mjpeg */
84
85#define MCHIP_MM_FIR(n) (0x0c+(n)*4) /* Frame info 0-3 */
86#define MCHIP_MM_FIR_RDY 0x00000001 /* frame ready */
87#define MCHIP_MM_FIR_FAILFR_MASK 0xf8000000 /* # of failed frames */
88#define MCHIP_MM_FIR_FAILFR_SHIFT 27
89
90 /* continuous comp/decomp mode */
91#define MCHIP_MM_FIR_C_ENDL_MASK 0x000007fe /* end DW [10] */
92#define MCHIP_MM_FIR_C_ENDL_SHIFT 1
93#define MCHIP_MM_FIR_C_ENDP_MASK 0x0007f800 /* end page [8] */
94#define MCHIP_MM_FIR_C_ENDP_SHIFT 11
95#define MCHIP_MM_FIR_C_STARTP_MASK 0x07f80000 /* start page [8] */
96#define MCHIP_MM_FIR_C_STARTP_SHIFT 19
97
98 /* continuous picture output mode */
99#define MCHIP_MM_FIR_O_STARTP_MASK 0x7ffe0000 /* start page [10] */
100#define MCHIP_MM_FIR_O_STARTP_SHIFT 17
101
102#define MCHIP_MM_FIFO_DATA 0x1c /* PCI TGT FIFO data */
103#define MCHIP_MM_FIFO_STATUS 0x20 /* PCI TGT FIFO stat */
104#define MCHIP_MM_FIFO_MASK 0x00000003
105#define MCHIP_MM_FIFO_WAIT_OR_READY 0x00000002 /* Bits common to WAIT & READY*/
106#define MCHIP_MM_FIFO_IDLE 0x0 /* HIC idle */
107#define MCHIP_MM_FIFO_IDLE1 0x1 /* idem ??? */
108#define MCHIP_MM_FIFO_WAIT 0x2 /* wait request */
109#define MCHIP_MM_FIFO_READY 0x3 /* data ready */
110
111#define MCHIP_HIC_HOST_USEREQ 0x40 /* host uses MCORE */
112
113#define MCHIP_HIC_TP_BUSY 0x44 /* taking picture */
114
115#define MCHIP_HIC_PIC_SAVED 0x48 /* pic in SDRAM */
116
117#define MCHIP_HIC_LOWPOWER 0x4c /* clock stopped */
118
119#define MCHIP_HIC_CTL 0x50 /* HIC control */
120#define MCHIP_HIC_CTL_SOFT_RESET 0x00000001 /* MCORE reset */
121#define MCHIP_HIC_CTL_MCORE_RDY 0x00000002 /* MCORE ready */
122
123#define MCHIP_HIC_CMD 0x54 /* HIC command */
124#define MCHIP_HIC_CMD_BITS 0x00000003 /* cmd width=[1:0]*/
125#define MCHIP_HIC_CMD_NOOP 0x0
126#define MCHIP_HIC_CMD_START 0x1
127#define MCHIP_HIC_CMD_STOP 0x2
128
129#define MCHIP_HIC_MODE 0x58
130#define MCHIP_HIC_MODE_NOOP 0x0
131#define MCHIP_HIC_MODE_STILL_CAP 0x1 /* still pic capt */
132#define MCHIP_HIC_MODE_DISPLAY 0x2 /* display */
133#define MCHIP_HIC_MODE_STILL_COMP 0x3 /* still pic comp. */
134#define MCHIP_HIC_MODE_STILL_DECOMP 0x4 /* still pic decomp. */
135#define MCHIP_HIC_MODE_CONT_COMP 0x5 /* cont capt+comp */
136#define MCHIP_HIC_MODE_CONT_DECOMP 0x6 /* cont decomp+disp */
137#define MCHIP_HIC_MODE_STILL_OUT 0x7 /* still pic output */
138#define MCHIP_HIC_MODE_CONT_OUT 0x8 /* cont output */
139
140#define MCHIP_HIC_STATUS 0x5c
141#define MCHIP_HIC_STATUS_MCC_RDY 0x00000001 /* MCC reg acc ok */
142#define MCHIP_HIC_STATUS_VRJ_RDY 0x00000002 /* VRJ reg acc ok */
143#define MCHIP_HIC_STATUS_IDLE 0x00000003
144#define MCHIP_HIC_STATUS_CAPDIS 0x00000004 /* cap/disp in prog */
145#define MCHIP_HIC_STATUS_COMPDEC 0x00000008 /* (de)comp in prog */
146#define MCHIP_HIC_STATUS_BUSY 0x00000010 /* HIC busy */
147
148#define MCHIP_HIC_S_RATE 0x60 /* MJPEG # frames */
149
150#define MCHIP_HIC_PCI_VFMT 0x64 /* video format */
151#define MCHIP_HIC_PCI_VFMT_YVYU 0x00000001 /* 0: V Y' U Y */
152 /* 1: Y' V Y U */
153
154#define MCHIP_MCC_CMD 0x80 /* MCC commands */
155#define MCHIP_MCC_CMD_INITIAL 0x0 /* idle ? */
156#define MCHIP_MCC_CMD_IIC_START_SET 0x1
157#define MCHIP_MCC_CMD_IIC_END_SET 0x2
158#define MCHIP_MCC_CMD_FM_WRITE 0x3 /* frame memory */
159#define MCHIP_MCC_CMD_FM_READ 0x4
160#define MCHIP_MCC_CMD_FM_STOP 0x5
161#define MCHIP_MCC_CMD_CAPTURE 0x6
162#define MCHIP_MCC_CMD_DISPLAY 0x7
163#define MCHIP_MCC_CMD_END_DISP 0x8
164#define MCHIP_MCC_CMD_STILL_COMP 0x9
165#define MCHIP_MCC_CMD_STILL_DECOMP 0xa
166#define MCHIP_MCC_CMD_STILL_OUTPUT 0xb
167#define MCHIP_MCC_CMD_CONT_OUTPUT 0xc
168#define MCHIP_MCC_CMD_CONT_COMP 0xd
169#define MCHIP_MCC_CMD_CONT_DECOMP 0xe
170#define MCHIP_MCC_CMD_RESET 0xf /* MCC reset */
171
172#define MCHIP_MCC_IIC_WR 0x84
173
174#define MCHIP_MCC_MCC_WR 0x88
175
176#define MCHIP_MCC_MCC_RD 0x8c
177
178#define MCHIP_MCC_STATUS 0x90
179#define MCHIP_MCC_STATUS_CAPT 0x00000001 /* capturing */
180#define MCHIP_MCC_STATUS_DISP 0x00000002 /* displaying */
181#define MCHIP_MCC_STATUS_COMP 0x00000004 /* compressing */
182#define MCHIP_MCC_STATUS_DECOMP 0x00000008 /* decompressing */
183#define MCHIP_MCC_STATUS_MCC_WR 0x00000010 /* register ready */
184#define MCHIP_MCC_STATUS_MCC_RD 0x00000020 /* register ready */
185#define MCHIP_MCC_STATUS_IIC_WR 0x00000040 /* register ready */
186#define MCHIP_MCC_STATUS_OUTPUT 0x00000080 /* output in prog */
187
188#define MCHIP_MCC_SIG_POLARITY 0x94
189#define MCHIP_MCC_SIG_POL_VS_H 0x00000001 /* VS active-high */
190#define MCHIP_MCC_SIG_POL_HS_H 0x00000002 /* HS active-high */
191#define MCHIP_MCC_SIG_POL_DOE_H 0x00000004 /* DOE active-high */
192
193#define MCHIP_MCC_IRQ 0x98
194#define MCHIP_MCC_IRQ_CAPDIS_STRT 0x00000001 /* cap/disp started */
195#define MCHIP_MCC_IRQ_CAPDIS_STRT_MASK 0x00000010
196#define MCHIP_MCC_IRQ_CAPDIS_END 0x00000002 /* cap/disp ended */
197#define MCHIP_MCC_IRQ_CAPDIS_END_MASK 0x00000020
198#define MCHIP_MCC_IRQ_COMPDEC_STRT 0x00000004 /* (de)comp started */
199#define MCHIP_MCC_IRQ_COMPDEC_STRT_MASK 0x00000040
200#define MCHIP_MCC_IRQ_COMPDEC_END 0x00000008 /* (de)comp ended */
201#define MCHIP_MCC_IRQ_COMPDEC_END_MASK 0x00000080
202
203#define MCHIP_MCC_HSTART 0x9c /* video in */
204#define MCHIP_MCC_VSTART 0xa0
205#define MCHIP_MCC_HCOUNT 0xa4
206#define MCHIP_MCC_VCOUNT 0xa8
207#define MCHIP_MCC_R_XBASE 0xac /* capt/disp */
208#define MCHIP_MCC_R_YBASE 0xb0
209#define MCHIP_MCC_R_XRANGE 0xb4
210#define MCHIP_MCC_R_YRANGE 0xb8
211#define MCHIP_MCC_B_XBASE 0xbc /* comp/decomp */
212#define MCHIP_MCC_B_YBASE 0xc0
213#define MCHIP_MCC_B_XRANGE 0xc4
214#define MCHIP_MCC_B_YRANGE 0xc8
215
216#define MCHIP_MCC_R_SAMPLING 0xcc /* 1: 1:4 */
217
218#define MCHIP_VRJ_CMD 0x100 /* VRJ commands */
219
220/* VRJ registers (see table 12.2.4) */
221#define MCHIP_VRJ_COMPRESSED_DATA 0x1b0
222#define MCHIP_VRJ_PIXEL_DATA 0x1b8
223
224#define MCHIP_VRJ_BUS_MODE 0x100
225#define MCHIP_VRJ_SIGNAL_ACTIVE_LEVEL 0x108
226#define MCHIP_VRJ_PDAT_USE 0x110
227#define MCHIP_VRJ_MODE_SPECIFY 0x118
228#define MCHIP_VRJ_LIMIT_COMPRESSED_LO 0x120
229#define MCHIP_VRJ_LIMIT_COMPRESSED_HI 0x124
230#define MCHIP_VRJ_COMP_DATA_FORMAT 0x128
231#define MCHIP_VRJ_TABLE_DATA 0x140
232#define MCHIP_VRJ_RESTART_INTERVAL 0x148
233#define MCHIP_VRJ_NUM_LINES 0x150
234#define MCHIP_VRJ_NUM_PIXELS 0x158
235#define MCHIP_VRJ_NUM_COMPONENTS 0x160
236#define MCHIP_VRJ_SOF1 0x168
237#define MCHIP_VRJ_SOF2 0x170
238#define MCHIP_VRJ_SOF3 0x178
239#define MCHIP_VRJ_SOF4 0x180
240#define MCHIP_VRJ_SOS 0x188
241#define MCHIP_VRJ_SOFT_RESET 0x190
242
243#define MCHIP_VRJ_STATUS 0x1c0
244#define MCHIP_VRJ_STATUS_BUSY 0x00001
245#define MCHIP_VRJ_STATUS_COMP_ACCESS 0x00002
246#define MCHIP_VRJ_STATUS_PIXEL_ACCESS 0x00004
247#define MCHIP_VRJ_STATUS_ERROR 0x00008
248
249#define MCHIP_VRJ_IRQ_FLAG 0x1c8
250#define MCHIP_VRJ_ERROR_REPORT 0x1d8
251
252#define MCHIP_VRJ_START_COMMAND 0x1a0
253
254/****************************************************************************/
255/* Driver definitions. */
256/****************************************************************************/
257
258/* Sony Programmable I/O Controller for accessing the camera commands */
259#include <linux/sonypi.h>
260
261/* private API definitions */
262#include <linux/meye.h>
263
264/* Enable jpg software correction */
265#define MEYE_JPEG_CORRECTION 1
266
267/* Maximum size of a buffer */
268#define MEYE_MAX_BUFSIZE 614400 /* 640 * 480 * 2 */
269
270/* Maximum number of buffers */
271#define MEYE_MAX_BUFNBRS 32
272
273/* State of a buffer */
274#define MEYE_BUF_UNUSED 0 /* not used */
275#define MEYE_BUF_USING 1 /* currently grabbing / playing */
276#define MEYE_BUF_DONE 2 /* done */
277
278/* grab buffer */
279struct meye_grab_buffer {
280 int state; /* state of buffer */
281 unsigned long size; /* size of jpg frame */
282 struct timeval timestamp; /* timestamp */
283 unsigned long sequence; /* sequence number */
284};
285
286/* size of kfifos containings buffer indices */
287#define MEYE_QUEUE_SIZE MEYE_MAX_BUFNBRS
288
289/* Motion Eye device structure */
290struct meye {
291 struct pci_dev *mchip_dev; /* pci device */
292 u8 mchip_irq; /* irq */
293 u8 mchip_mode; /* actual mchip mode: HIC_MODE... */
294 u8 mchip_fnum; /* current mchip frame number */
295 unsigned char __iomem *mchip_mmregs;/* mchip: memory mapped registers */
296 u8 *mchip_ptable[MCHIP_NB_PAGES];/* mchip: ptable */
297 void *mchip_ptable_toc; /* mchip: ptable toc */
298 dma_addr_t mchip_dmahandle; /* mchip: dma handle to ptable toc */
299 unsigned char *grab_fbuffer; /* capture framebuffer */
300 unsigned char *grab_temp; /* temporary buffer */
301 /* list of buffers */
302 struct meye_grab_buffer grab_buffer[MEYE_MAX_BUFNBRS];
303 int vma_use_count[MEYE_MAX_BUFNBRS]; /* mmap count */
304 struct semaphore lock; /* semaphore for open/mmap... */
305 struct kfifo *grabq; /* queue for buffers to be grabbed */
306 spinlock_t grabq_lock; /* lock protecting the queue */
307 struct kfifo *doneq; /* queue for grabbed buffers */
308 spinlock_t doneq_lock; /* lock protecting the queue */
309 wait_queue_head_t proc_list; /* wait queue */
310 struct video_device *video_dev; /* video device parameters */
311 struct video_picture picture; /* video picture parameters */
312 struct meye_params params; /* additional parameters */
313#ifdef CONFIG_PM
314 u8 pm_mchip_mode; /* old mchip mode */
315#endif
316};
317
318#endif
diff --git a/drivers/media/video/msp3400.c b/drivers/media/video/msp3400.c
new file mode 100644
index 00000000000..d996ec99caf
--- /dev/null
+++ b/drivers/media/video/msp3400.c
@@ -0,0 +1,1876 @@
1/*
2 * programming the msp34* sound processor family
3 *
4 * (c) 1997-2001 Gerd Knorr <kraxel@bytesex.org>
5 *
6 * what works and what doesn't:
7 *
8 * AM-Mono
9 * Support for Hauppauge cards added (decoding handled by tuner) added by
10 * Frederic Crozat <fcrozat@mail.dotcom.fr>
11 *
12 * FM-Mono
13 * should work. The stereo modes are backward compatible to FM-mono,
14 * therefore FM-Mono should be allways available.
15 *
16 * FM-Stereo (B/G, used in germany)
17 * should work, with autodetect
18 *
19 * FM-Stereo (satellite)
20 * should work, no autodetect (i.e. default is mono, but you can
21 * switch to stereo -- untested)
22 *
23 * NICAM (B/G, L , used in UK, Scandinavia, Spain and France)
24 * should work, with autodetect. Support for NICAM was added by
25 * Pekka Pietikainen <pp@netppl.fi>
26 *
27 *
28 * TODO:
29 * - better SAT support
30 *
31 *
32 * 980623 Thomas Sailer (sailer@ife.ee.ethz.ch)
33 * using soundcore instead of OSS
34 *
35 */
36
37#include <linux/config.h>
38#include <linux/module.h>
39#include <linux/moduleparam.h>
40#include <linux/kernel.h>
41#include <linux/sched.h>
42#include <linux/string.h>
43#include <linux/timer.h>
44#include <linux/delay.h>
45#include <linux/errno.h>
46#include <linux/slab.h>
47#include <linux/i2c.h>
48#include <linux/videodev.h>
49#include <linux/init.h>
50#include <linux/smp_lock.h>
51#include <linux/kthread.h>
52#include <linux/suspend.h>
53#include <asm/semaphore.h>
54#include <asm/pgtable.h>
55
56#include <media/audiochip.h>
57#include <media/id.h>
58#include "msp3400.h"
59
60#define OPMODE_AUTO -1
61#define OPMODE_MANUAL 0
62#define OPMODE_SIMPLE 1 /* use short programming (>= msp3410 only) */
63#define OPMODE_SIMPLER 2 /* use shorter programming (>= msp34xxG) */
64
65/* insmod parameters */
66static int opmode = OPMODE_AUTO;
67static int debug = 0; /* debug output */
68static int once = 0; /* no continous stereo monitoring */
69static int amsound = 0; /* hard-wire AM sound at 6.5 Hz (france),
70 the autoscan seems work well only with FM... */
71static int standard = 1; /* Override auto detect of audio standard, if needed. */
72static int dolby = 0;
73
74static int stereo_threshold = 0x190; /* a2 threshold for stereo/bilingual
75 (msp34xxg only) 0x00a0-0x03c0 */
76
77struct msp3400c {
78 int rev1,rev2;
79
80 int opmode;
81 int mode;
82 int norm;
83 int nicam_on;
84 int acb;
85 int main, second; /* sound carrier */
86 int input;
87 int source; /* see msp34xxg_set_source */
88
89 /* v4l2 */
90 int audmode;
91 int rxsubchans;
92
93 int muted;
94 int volume, balance;
95 int bass, treble;
96
97 /* thread */
98 struct task_struct *kthread;
99 wait_queue_head_t wq;
100 int restart:1;
101 int watch_stereo:1;
102};
103
104#define HAVE_NICAM(msp) (((msp->rev2>>8) & 0xff) != 00)
105#define HAVE_SIMPLE(msp) ((msp->rev1 & 0xff) >= 'D'-'@')
106#define HAVE_SIMPLER(msp) ((msp->rev1 & 0xff) >= 'G'-'@')
107#define HAVE_RADIO(msp) ((msp->rev1 & 0xff) >= 'G'-'@')
108
109#define VIDEO_MODE_RADIO 16 /* norm magic for radio mode */
110
111/* ---------------------------------------------------------------------- */
112
113#define dprintk if (debug >= 1) printk
114#define d2printk if (debug >= 2) printk
115
116/* read-only */
117module_param(opmode, int, 0444);
118
119/* read-write */
120module_param(once, int, 0644);
121module_param(debug, int, 0644);
122module_param(stereo_threshold, int, 0644);
123module_param(standard, int, 0644);
124module_param(amsound, int, 0644);
125module_param(dolby, int, 0644);
126
127MODULE_PARM_DESC(once, "No continuous stereo monitoring");
128MODULE_PARM_DESC(debug, "Enable debug messages");
129MODULE_PARM_DESC(standard, "Specify audio standard: 32 = NTSC, 64 = radio, Default: Autodetect");
130MODULE_PARM_DESC(amsound, "Hardwire AM sound at 6.5Hz (France), FM can autoscan");
131
132MODULE_DESCRIPTION("device driver for msp34xx TV sound processor");
133MODULE_AUTHOR("Gerd Knorr");
134MODULE_LICENSE("Dual BSD/GPL"); /* FreeBSD uses this too */
135
136/* ---------------------------------------------------------------------- */
137
138#define I2C_MSP3400C 0x80
139#define I2C_MSP3400C_ALT 0x88
140
141#define I2C_MSP3400C_DEM 0x10
142#define I2C_MSP3400C_DFP 0x12
143
144/* Addresses to scan */
145static unsigned short normal_i2c[] = {
146 I2C_MSP3400C >> 1,
147 I2C_MSP3400C_ALT >> 1,
148 I2C_CLIENT_END
149};
150static unsigned short normal_i2c_range[] = {I2C_CLIENT_END,I2C_CLIENT_END};
151I2C_CLIENT_INSMOD;
152
153/* ----------------------------------------------------------------------- */
154/* functions for talking to the MSP3400C Sound processor */
155
156static int msp3400c_reset(struct i2c_client *client)
157{
158 /* reset and read revision code */
159 static char reset_off[3] = { 0x00, 0x80, 0x00 };
160 static char reset_on[3] = { 0x00, 0x00, 0x00 };
161 static char write[3] = { I2C_MSP3400C_DFP + 1, 0x00, 0x1e };
162 char read[2];
163 struct i2c_msg reset[2] = {
164 { client->addr, I2C_M_IGNORE_NAK, 3, reset_off },
165 { client->addr, I2C_M_IGNORE_NAK, 3, reset_on },
166 };
167 struct i2c_msg test[2] = {
168 { client->addr, 0, 3, write },
169 { client->addr, I2C_M_RD, 2, read },
170 };
171
172 if ( (1 != i2c_transfer(client->adapter,&reset[0],1)) ||
173 (1 != i2c_transfer(client->adapter,&reset[1],1)) ||
174 (2 != i2c_transfer(client->adapter,test,2)) ) {
175 printk(KERN_ERR "msp3400: chip reset failed\n");
176 return -1;
177 }
178 return 0;
179}
180
181static int
182msp3400c_read(struct i2c_client *client, int dev, int addr)
183{
184 int err;
185
186 unsigned char write[3];
187 unsigned char read[2];
188 struct i2c_msg msgs[2] = {
189 { client->addr, 0, 3, write },
190 { client->addr, I2C_M_RD, 2, read }
191 };
192 write[0] = dev+1;
193 write[1] = addr >> 8;
194 write[2] = addr & 0xff;
195
196 for (err = 0; err < 3;) {
197 if (2 == i2c_transfer(client->adapter,msgs,2))
198 break;
199 err++;
200 printk(KERN_WARNING "msp34xx: I/O error #%d (read 0x%02x/0x%02x)\n",
201 err, dev, addr);
202 msleep(10);
203 }
204 if (3 == err) {
205 printk(KERN_WARNING "msp34xx: giving up, reseting chip. Sound will go off, sorry folks :-|\n");
206 msp3400c_reset(client);
207 return -1;
208 }
209 return read[0] << 8 | read[1];
210}
211
212static int
213msp3400c_write(struct i2c_client *client, int dev, int addr, int val)
214{
215 int err;
216 unsigned char buffer[5];
217
218 buffer[0] = dev;
219 buffer[1] = addr >> 8;
220 buffer[2] = addr & 0xff;
221 buffer[3] = val >> 8;
222 buffer[4] = val & 0xff;
223
224 for (err = 0; err < 3;) {
225 if (5 == i2c_master_send(client, buffer, 5))
226 break;
227 err++;
228 printk(KERN_WARNING "msp34xx: I/O error #%d (write 0x%02x/0x%02x)\n",
229 err, dev, addr);
230 msleep(10);
231 }
232 if (3 == err) {
233 printk(KERN_WARNING "msp34xx: giving up, reseting chip. Sound will go off, sorry folks :-|\n");
234 msp3400c_reset(client);
235 return -1;
236 }
237 return 0;
238}
239
240/* ------------------------------------------------------------------------ */
241
242/* This macro is allowed for *constants* only, gcc must calculate it
243 at compile time. Remember -- no floats in kernel mode */
244#define MSP_CARRIER(freq) ((int)((float)(freq/18.432)*(1<<24)))
245
246#define MSP_MODE_AM_DETECT 0
247#define MSP_MODE_FM_RADIO 2
248#define MSP_MODE_FM_TERRA 3
249#define MSP_MODE_FM_SAT 4
250#define MSP_MODE_FM_NICAM1 5
251#define MSP_MODE_FM_NICAM2 6
252#define MSP_MODE_AM_NICAM 7
253#define MSP_MODE_BTSC 8
254#define MSP_MODE_EXTERN 9
255
256static struct MSP_INIT_DATA_DEM {
257 int fir1[6];
258 int fir2[6];
259 int cdo1;
260 int cdo2;
261 int ad_cv;
262 int mode_reg;
263 int dfp_src;
264 int dfp_matrix;
265} msp_init_data[] = {
266 /* AM (for carrier detect / msp3400) */
267 { { 75, 19, 36, 35, 39, 40 }, { 75, 19, 36, 35, 39, 40 },
268 MSP_CARRIER(5.5), MSP_CARRIER(5.5),
269 0x00d0, 0x0500, 0x0020, 0x3000},
270
271 /* AM (for carrier detect / msp3410) */
272 { { -1, -1, -8, 2, 59, 126 }, { -1, -1, -8, 2, 59, 126 },
273 MSP_CARRIER(5.5), MSP_CARRIER(5.5),
274 0x00d0, 0x0100, 0x0020, 0x3000},
275
276 /* FM Radio */
277 { { -8, -8, 4, 6, 78, 107 }, { -8, -8, 4, 6, 78, 107 },
278 MSP_CARRIER(10.7), MSP_CARRIER(10.7),
279 0x00d0, 0x0480, 0x0020, 0x3000 },
280
281 /* Terrestial FM-mono + FM-stereo */
282 { { 3, 18, 27, 48, 66, 72 }, { 3, 18, 27, 48, 66, 72 },
283 MSP_CARRIER(5.5), MSP_CARRIER(5.5),
284 0x00d0, 0x0480, 0x0030, 0x3000},
285
286 /* Sat FM-mono */
287 { { 1, 9, 14, 24, 33, 37 }, { 3, 18, 27, 48, 66, 72 },
288 MSP_CARRIER(6.5), MSP_CARRIER(6.5),
289 0x00c6, 0x0480, 0x0000, 0x3000},
290
291 /* NICAM/FM -- B/G (5.5/5.85), D/K (6.5/5.85) */
292 { { -2, -8, -10, 10, 50, 86 }, { 3, 18, 27, 48, 66, 72 },
293 MSP_CARRIER(5.5), MSP_CARRIER(5.5),
294 0x00d0, 0x0040, 0x0120, 0x3000},
295
296 /* NICAM/FM -- I (6.0/6.552) */
297 { { 2, 4, -6, -4, 40, 94 }, { 3, 18, 27, 48, 66, 72 },
298 MSP_CARRIER(6.0), MSP_CARRIER(6.0),
299 0x00d0, 0x0040, 0x0120, 0x3000},
300
301 /* NICAM/AM -- L (6.5/5.85) */
302 { { -2, -8, -10, 10, 50, 86 }, { -4, -12, -9, 23, 79, 126 },
303 MSP_CARRIER(6.5), MSP_CARRIER(6.5),
304 0x00c6, 0x0140, 0x0120, 0x7c03},
305};
306
307struct CARRIER_DETECT {
308 int cdo;
309 char *name;
310};
311
312static struct CARRIER_DETECT carrier_detect_main[] = {
313 /* main carrier */
314 { MSP_CARRIER(4.5), "4.5 NTSC" },
315 { MSP_CARRIER(5.5), "5.5 PAL B/G" },
316 { MSP_CARRIER(6.0), "6.0 PAL I" },
317 { MSP_CARRIER(6.5), "6.5 PAL D/K + SAT + SECAM" }
318};
319
320static struct CARRIER_DETECT carrier_detect_55[] = {
321 /* PAL B/G */
322 { MSP_CARRIER(5.7421875), "5.742 PAL B/G FM-stereo" },
323 { MSP_CARRIER(5.85), "5.85 PAL B/G NICAM" }
324};
325
326static struct CARRIER_DETECT carrier_detect_65[] = {
327 /* PAL SAT / SECAM */
328 { MSP_CARRIER(5.85), "5.85 PAL D/K + SECAM NICAM" },
329 { MSP_CARRIER(6.2578125), "6.25 PAL D/K1 FM-stereo" },
330 { MSP_CARRIER(6.7421875), "6.74 PAL D/K2 FM-stereo" },
331 { MSP_CARRIER(7.02), "7.02 PAL SAT FM-stereo s/b" },
332 { MSP_CARRIER(7.20), "7.20 PAL SAT FM-stereo s" },
333 { MSP_CARRIER(7.38), "7.38 PAL SAT FM-stereo b" },
334};
335
336#define CARRIER_COUNT(x) (sizeof(x)/sizeof(struct CARRIER_DETECT))
337
338/* ----------------------------------------------------------------------- */
339
340static int scarts[3][9] = {
341 /* MASK IN1 IN2 IN1_DA IN2_DA IN3 IN4 MONO MUTE */
342 { 0x0320, 0x0000, 0x0200, -1, -1, 0x0300, 0x0020, 0x0100, 0x0320 },
343 { 0x0c40, 0x0440, 0x0400, 0x0c00, 0x0040, 0x0000, 0x0840, 0x0800, 0x0c40 },
344 { 0x3080, 0x1000, 0x1080, 0x0000, 0x0080, 0x2080, 0x3080, 0x2000, 0x3000 },
345};
346
347static char *scart_names[] = {
348 "mask", "in1", "in2", "in1 da", "in2 da", "in3", "in4", "mono", "mute"
349};
350
351static void
352msp3400c_set_scart(struct i2c_client *client, int in, int out)
353{
354 struct msp3400c *msp = i2c_get_clientdata(client);
355
356 if (-1 == scarts[out][in])
357 return;
358
359 dprintk(KERN_DEBUG
360 "msp34xx: scart switch: %s => %d\n",scart_names[in],out);
361 msp->acb &= ~scarts[out][SCART_MASK];
362 msp->acb |= scarts[out][in];
363 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0013, msp->acb);
364}
365
366/* ------------------------------------------------------------------------ */
367
368static void msp3400c_setcarrier(struct i2c_client *client, int cdo1, int cdo2)
369{
370 msp3400c_write(client,I2C_MSP3400C_DEM, 0x0093, cdo1 & 0xfff);
371 msp3400c_write(client,I2C_MSP3400C_DEM, 0x009b, cdo1 >> 12);
372 msp3400c_write(client,I2C_MSP3400C_DEM, 0x00a3, cdo2 & 0xfff);
373 msp3400c_write(client,I2C_MSP3400C_DEM, 0x00ab, cdo2 >> 12);
374 msp3400c_write(client,I2C_MSP3400C_DEM, 0x0056, 0); /*LOAD_REG_1/2*/
375}
376
377static void msp3400c_setvolume(struct i2c_client *client,
378 int muted, int volume, int balance)
379{
380 int val = 0, bal = 0;
381
382 if (!muted) {
383 val = (volume * 0x7F / 65535) << 8;
384 }
385 if (val) {
386 bal = (balance / 256) - 128;
387 }
388 dprintk(KERN_DEBUG
389 "msp34xx: setvolume: mute=%s %d:%d v=0x%02x b=0x%02x\n",
390 muted ? "on" : "off", volume, balance, val>>8, bal);
391 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0000, val); /* loudspeaker */
392 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0006, val); /* headphones */
393 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0007,
394 muted ? 0x01 : (val | 0x01));
395 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0001, bal << 8);
396}
397
398static void msp3400c_setbass(struct i2c_client *client, int bass)
399{
400 int val = ((bass-32768) * 0x60 / 65535) << 8;
401
402 dprintk(KERN_DEBUG "msp34xx: setbass: %d 0x%02x\n",bass, val>>8);
403 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0002, val); /* loudspeaker */
404}
405
406static void msp3400c_settreble(struct i2c_client *client, int treble)
407{
408 int val = ((treble-32768) * 0x60 / 65535) << 8;
409
410 dprintk(KERN_DEBUG "msp34xx: settreble: %d 0x%02x\n",treble, val>>8);
411 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0003, val); /* loudspeaker */
412}
413
414static void msp3400c_setmode(struct i2c_client *client, int type)
415{
416 struct msp3400c *msp = i2c_get_clientdata(client);
417 int i;
418
419 dprintk(KERN_DEBUG "msp3400: setmode: %d\n",type);
420 msp->mode = type;
421 msp->audmode = V4L2_TUNER_MODE_MONO;
422 msp->rxsubchans = V4L2_TUNER_SUB_MONO;
423
424 msp3400c_write(client,I2C_MSP3400C_DEM, 0x00bb, /* ad_cv */
425 msp_init_data[type].ad_cv);
426
427 for (i = 5; i >= 0; i--) /* fir 1 */
428 msp3400c_write(client,I2C_MSP3400C_DEM, 0x0001,
429 msp_init_data[type].fir1[i]);
430
431 msp3400c_write(client,I2C_MSP3400C_DEM, 0x0005, 0x0004); /* fir 2 */
432 msp3400c_write(client,I2C_MSP3400C_DEM, 0x0005, 0x0040);
433 msp3400c_write(client,I2C_MSP3400C_DEM, 0x0005, 0x0000);
434 for (i = 5; i >= 0; i--)
435 msp3400c_write(client,I2C_MSP3400C_DEM, 0x0005,
436 msp_init_data[type].fir2[i]);
437
438 msp3400c_write(client,I2C_MSP3400C_DEM, 0x0083, /* MODE_REG */
439 msp_init_data[type].mode_reg);
440
441 msp3400c_setcarrier(client, msp_init_data[type].cdo1,
442 msp_init_data[type].cdo2);
443
444 msp3400c_write(client,I2C_MSP3400C_DEM, 0x0056, 0); /*LOAD_REG_1/2*/
445
446 if (dolby) {
447 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0008,
448 0x0520); /* I2S1 */
449 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0009,
450 0x0620); /* I2S2 */
451 msp3400c_write(client,I2C_MSP3400C_DFP, 0x000b,
452 msp_init_data[type].dfp_src);
453 } else {
454 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0008,
455 msp_init_data[type].dfp_src);
456 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0009,
457 msp_init_data[type].dfp_src);
458 msp3400c_write(client,I2C_MSP3400C_DFP, 0x000b,
459 msp_init_data[type].dfp_src);
460 }
461 msp3400c_write(client,I2C_MSP3400C_DFP, 0x000a,
462 msp_init_data[type].dfp_src);
463 msp3400c_write(client,I2C_MSP3400C_DFP, 0x000e,
464 msp_init_data[type].dfp_matrix);
465
466 if (HAVE_NICAM(msp)) {
467 /* nicam prescale */
468 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0010, 0x5a00); /* was: 0x3000 */
469 }
470}
471
472static int best_audio_mode(int rxsubchans)
473{
474 if (rxsubchans & V4L2_TUNER_SUB_STEREO)
475 return V4L2_TUNER_MODE_STEREO;
476 if (rxsubchans & V4L2_TUNER_SUB_LANG1)
477 return V4L2_TUNER_MODE_LANG1;
478 if (rxsubchans & V4L2_TUNER_SUB_LANG2)
479 return V4L2_TUNER_MODE_LANG2;
480 return V4L2_TUNER_MODE_MONO;
481}
482
483/* turn on/off nicam + stereo */
484static void msp3400c_set_audmode(struct i2c_client *client, int audmode)
485{
486 static char *strmode[16] = {
487#if __GNUC__ >= 3
488 [ 0 ... 15 ] = "invalid",
489#endif
490 [ V4L2_TUNER_MODE_MONO ] = "mono",
491 [ V4L2_TUNER_MODE_STEREO ] = "stereo",
492 [ V4L2_TUNER_MODE_LANG1 ] = "lang1",
493 [ V4L2_TUNER_MODE_LANG2 ] = "lang2",
494 };
495 struct msp3400c *msp = i2c_get_clientdata(client);
496 int nicam=0; /* channel source: FM/AM or nicam */
497 int src=0;
498
499 BUG_ON(msp->opmode == OPMODE_SIMPLER);
500 msp->audmode = audmode;
501
502 /* switch demodulator */
503 switch (msp->mode) {
504 case MSP_MODE_FM_TERRA:
505 dprintk(KERN_DEBUG "msp3400: FM setstereo: %s\n",
506 strmode[audmode]);
507 msp3400c_setcarrier(client,msp->second,msp->main);
508 switch (audmode) {
509 case V4L2_TUNER_MODE_STEREO:
510 msp3400c_write(client,I2C_MSP3400C_DFP, 0x000e, 0x3001);
511 break;
512 case V4L2_TUNER_MODE_MONO:
513 case V4L2_TUNER_MODE_LANG1:
514 case V4L2_TUNER_MODE_LANG2:
515 msp3400c_write(client,I2C_MSP3400C_DFP, 0x000e, 0x3000);
516 break;
517 }
518 break;
519 case MSP_MODE_FM_SAT:
520 dprintk(KERN_DEBUG "msp3400: SAT setstereo: %s\n",
521 strmode[audmode]);
522 switch (audmode) {
523 case V4L2_TUNER_MODE_MONO:
524 msp3400c_setcarrier(client, MSP_CARRIER(6.5), MSP_CARRIER(6.5));
525 break;
526 case V4L2_TUNER_MODE_STEREO:
527 msp3400c_setcarrier(client, MSP_CARRIER(7.2), MSP_CARRIER(7.02));
528 break;
529 case V4L2_TUNER_MODE_LANG1:
530 msp3400c_setcarrier(client, MSP_CARRIER(7.38), MSP_CARRIER(7.02));
531 break;
532 case V4L2_TUNER_MODE_LANG2:
533 msp3400c_setcarrier(client, MSP_CARRIER(7.38), MSP_CARRIER(7.02));
534 break;
535 }
536 break;
537 case MSP_MODE_FM_NICAM1:
538 case MSP_MODE_FM_NICAM2:
539 case MSP_MODE_AM_NICAM:
540 dprintk(KERN_DEBUG "msp3400: NICAM setstereo: %s\n",
541 strmode[audmode]);
542 msp3400c_setcarrier(client,msp->second,msp->main);
543 if (msp->nicam_on)
544 nicam=0x0100;
545 break;
546 case MSP_MODE_BTSC:
547 dprintk(KERN_DEBUG "msp3400: BTSC setstereo: %s\n",
548 strmode[audmode]);
549 nicam=0x0300;
550 break;
551 case MSP_MODE_EXTERN:
552 dprintk(KERN_DEBUG "msp3400: extern setstereo: %s\n",
553 strmode[audmode]);
554 nicam = 0x0200;
555 break;
556 case MSP_MODE_FM_RADIO:
557 dprintk(KERN_DEBUG "msp3400: FM-Radio setstereo: %s\n",
558 strmode[audmode]);
559 break;
560 default:
561 dprintk(KERN_DEBUG "msp3400: mono setstereo\n");
562 return;
563 }
564
565 /* switch audio */
566 switch (audmode) {
567 case V4L2_TUNER_MODE_STEREO:
568 src = 0x0020 | nicam;
569#if 0
570 /* spatial effect */
571 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0005,0x4000);
572#endif
573 break;
574 case V4L2_TUNER_MODE_MONO:
575 if (msp->mode == MSP_MODE_AM_NICAM) {
576 dprintk("msp3400: switching to AM mono\n");
577 /* AM mono decoding is handled by tuner, not MSP chip */
578 /* SCART switching control register */
579 msp3400c_set_scart(client,SCART_MONO,0);
580 src = 0x0200;
581 break;
582 }
583 case V4L2_TUNER_MODE_LANG1:
584 src = 0x0000 | nicam;
585 break;
586 case V4L2_TUNER_MODE_LANG2:
587 src = 0x0010 | nicam;
588 break;
589 }
590 dprintk(KERN_DEBUG
591 "msp3400: setstereo final source/matrix = 0x%x\n", src);
592
593 if (dolby) {
594 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0008,0x0520);
595 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0009,0x0620);
596 msp3400c_write(client,I2C_MSP3400C_DFP, 0x000a,src);
597 msp3400c_write(client,I2C_MSP3400C_DFP, 0x000b,src);
598 } else {
599 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0008,src);
600 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0009,src);
601 msp3400c_write(client,I2C_MSP3400C_DFP, 0x000a,src);
602 msp3400c_write(client,I2C_MSP3400C_DFP, 0x000b,src);
603 }
604}
605
606static void
607msp3400c_print_mode(struct msp3400c *msp)
608{
609 if (msp->main == msp->second) {
610 printk(KERN_DEBUG "msp3400: mono sound carrier: %d.%03d MHz\n",
611 msp->main/910000,(msp->main/910)%1000);
612 } else {
613 printk(KERN_DEBUG "msp3400: main sound carrier: %d.%03d MHz\n",
614 msp->main/910000,(msp->main/910)%1000);
615 }
616 if (msp->mode == MSP_MODE_FM_NICAM1 ||
617 msp->mode == MSP_MODE_FM_NICAM2)
618 printk(KERN_DEBUG "msp3400: NICAM/FM carrier : %d.%03d MHz\n",
619 msp->second/910000,(msp->second/910)%1000);
620 if (msp->mode == MSP_MODE_AM_NICAM)
621 printk(KERN_DEBUG "msp3400: NICAM/AM carrier : %d.%03d MHz\n",
622 msp->second/910000,(msp->second/910)%1000);
623 if (msp->mode == MSP_MODE_FM_TERRA &&
624 msp->main != msp->second) {
625 printk(KERN_DEBUG "msp3400: FM-stereo carrier : %d.%03d MHz\n",
626 msp->second/910000,(msp->second/910)%1000);
627 }
628}
629
630/* ----------------------------------------------------------------------- */
631
632struct REGISTER_DUMP {
633 int addr;
634 char *name;
635};
636
637static int
638autodetect_stereo(struct i2c_client *client)
639{
640 struct msp3400c *msp = i2c_get_clientdata(client);
641 int val;
642 int rxsubchans = msp->rxsubchans;
643 int newnicam = msp->nicam_on;
644 int update = 0;
645
646 switch (msp->mode) {
647 case MSP_MODE_FM_TERRA:
648 val = msp3400c_read(client, I2C_MSP3400C_DFP, 0x18);
649 if (val > 32767)
650 val -= 65536;
651 dprintk(KERN_DEBUG
652 "msp34xx: stereo detect register: %d\n",val);
653 if (val > 4096) {
654 rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO;
655 } else if (val < -4096) {
656 rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
657 } else {
658 rxsubchans = V4L2_TUNER_SUB_MONO;
659 }
660 newnicam = 0;
661 break;
662 case MSP_MODE_FM_NICAM1:
663 case MSP_MODE_FM_NICAM2:
664 case MSP_MODE_AM_NICAM:
665 val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x23);
666 dprintk(KERN_DEBUG
667 "msp34xx: nicam sync=%d, mode=%d\n",
668 val & 1, (val & 0x1e) >> 1);
669
670 if (val & 1) {
671 /* nicam synced */
672 switch ((val & 0x1e) >> 1) {
673 case 0:
674 case 8:
675 rxsubchans = V4L2_TUNER_SUB_STEREO;
676 break;
677 case 1:
678 case 9:
679 rxsubchans = V4L2_TUNER_SUB_MONO
680 | V4L2_TUNER_SUB_LANG1;
681 break;
682 case 2:
683 case 10:
684 rxsubchans = V4L2_TUNER_SUB_MONO
685 | V4L2_TUNER_SUB_LANG1
686 | V4L2_TUNER_SUB_LANG2;
687 break;
688 default:
689 rxsubchans = V4L2_TUNER_SUB_MONO;
690 break;
691 }
692 newnicam=1;
693 } else {
694 newnicam = 0;
695 rxsubchans = V4L2_TUNER_SUB_MONO;
696 }
697 break;
698 case MSP_MODE_BTSC:
699 val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x200);
700 dprintk(KERN_DEBUG
701 "msp3410: status=0x%x (pri=%s, sec=%s, %s%s%s)\n",
702 val,
703 (val & 0x0002) ? "no" : "yes",
704 (val & 0x0004) ? "no" : "yes",
705 (val & 0x0040) ? "stereo" : "mono",
706 (val & 0x0080) ? ", nicam 2nd mono" : "",
707 (val & 0x0100) ? ", bilingual/SAP" : "");
708 rxsubchans = V4L2_TUNER_SUB_MONO;
709 if (val & 0x0040) rxsubchans |= V4L2_TUNER_SUB_STEREO;
710 if (val & 0x0100) rxsubchans |= V4L2_TUNER_SUB_LANG1;
711 break;
712 }
713 if (rxsubchans != msp->rxsubchans) {
714 update = 1;
715 dprintk(KERN_DEBUG "msp34xx: watch: rxsubchans %d => %d\n",
716 msp->rxsubchans,rxsubchans);
717 msp->rxsubchans = rxsubchans;
718 }
719 if (newnicam != msp->nicam_on) {
720 update = 1;
721 dprintk(KERN_DEBUG "msp34xx: watch: nicam %d => %d\n",
722 msp->nicam_on,newnicam);
723 msp->nicam_on = newnicam;
724 }
725 return update;
726}
727
728/*
729 * A kernel thread for msp3400 control -- we don't want to block the
730 * in the ioctl while doing the sound carrier & stereo detect
731 */
732
733static int msp34xx_sleep(struct msp3400c *msp, int timeout)
734{
735 DECLARE_WAITQUEUE(wait, current);
736
737again:
738 add_wait_queue(&msp->wq, &wait);
739 if (!kthread_should_stop()) {
740 if (timeout < 0) {
741 set_current_state(TASK_INTERRUPTIBLE);
742 schedule();
743 } else {
744#if 0
745 /* hmm, that one doesn't return on wakeup ... */
746 msleep_interruptible(timeout);
747#else
748 set_current_state(TASK_INTERRUPTIBLE);
749 schedule_timeout(msecs_to_jiffies(timeout));
750#endif
751 }
752 }
753
754 remove_wait_queue(&msp->wq, &wait);
755
756 if (try_to_freeze(PF_FREEZE))
757 goto again;
758
759 return msp->restart;
760}
761
762/* stereo/multilang monitoring */
763static void watch_stereo(struct i2c_client *client)
764{
765 struct msp3400c *msp = i2c_get_clientdata(client);
766
767 if (autodetect_stereo(client))
768 msp3400c_set_audmode(client,best_audio_mode(msp->rxsubchans));
769 if (once)
770 msp->watch_stereo = 0;
771}
772
773static int msp3400c_thread(void *data)
774{
775 struct i2c_client *client = data;
776 struct msp3400c *msp = i2c_get_clientdata(client);
777 struct CARRIER_DETECT *cd;
778 int count, max1,max2,val1,val2, val,this;
779
780 printk("msp3400: kthread started\n");
781 for (;;) {
782 d2printk("msp3400: thread: sleep\n");
783 msp34xx_sleep(msp,-1);
784 d2printk("msp3400: thread: wakeup\n");
785
786 restart:
787 dprintk("msp3410: thread: restart scan\n");
788 msp->restart = 0;
789 if (kthread_should_stop())
790 break;
791
792 if (VIDEO_MODE_RADIO == msp->norm ||
793 MSP_MODE_EXTERN == msp->mode) {
794 /* no carrier scan, just unmute */
795 printk("msp3400: thread: no carrier scan\n");
796 msp3400c_setvolume(client, msp->muted,
797 msp->volume, msp->balance);
798 continue;
799 }
800
801 /* mute */
802 msp3400c_setvolume(client, msp->muted, 0, 0);
803 msp3400c_setmode(client, MSP_MODE_AM_DETECT /* +1 */ );
804 val1 = val2 = 0;
805 max1 = max2 = -1;
806 msp->watch_stereo = 0;
807
808 /* some time for the tuner to sync */
809 if (msp34xx_sleep(msp,200))
810 goto restart;
811
812 /* carrier detect pass #1 -- main carrier */
813 cd = carrier_detect_main; count = CARRIER_COUNT(carrier_detect_main);
814
815 if (amsound && (msp->norm == VIDEO_MODE_SECAM)) {
816 /* autodetect doesn't work well with AM ... */
817 max1 = 3;
818 count = 0;
819 dprintk("msp3400: AM sound override\n");
820 }
821
822 for (this = 0; this < count; this++) {
823 msp3400c_setcarrier(client, cd[this].cdo,cd[this].cdo);
824 if (msp34xx_sleep(msp,100))
825 goto restart;
826 val = msp3400c_read(client, I2C_MSP3400C_DFP, 0x1b);
827 if (val > 32767)
828 val -= 65536;
829 if (val1 < val)
830 val1 = val, max1 = this;
831 dprintk("msp3400: carrier1 val: %5d / %s\n", val,cd[this].name);
832 }
833
834 /* carrier detect pass #2 -- second (stereo) carrier */
835 switch (max1) {
836 case 1: /* 5.5 */
837 cd = carrier_detect_55;
838 count = CARRIER_COUNT(carrier_detect_55);
839 break;
840 case 3: /* 6.5 */
841 cd = carrier_detect_65;
842 count = CARRIER_COUNT(carrier_detect_65);
843 break;
844 case 0: /* 4.5 */
845 case 2: /* 6.0 */
846 default:
847 cd = NULL; count = 0;
848 break;
849 }
850
851 if (amsound && (msp->norm == VIDEO_MODE_SECAM)) {
852 /* autodetect doesn't work well with AM ... */
853 cd = NULL; count = 0; max2 = 0;
854 }
855 for (this = 0; this < count; this++) {
856 msp3400c_setcarrier(client, cd[this].cdo,cd[this].cdo);
857 if (msp34xx_sleep(msp,100))
858 goto restart;
859 val = msp3400c_read(client, I2C_MSP3400C_DFP, 0x1b);
860 if (val > 32767)
861 val -= 65536;
862 if (val2 < val)
863 val2 = val, max2 = this;
864 dprintk("msp3400: carrier2 val: %5d / %s\n", val,cd[this].name);
865 }
866
867 /* programm the msp3400 according to the results */
868 msp->main = carrier_detect_main[max1].cdo;
869 switch (max1) {
870 case 1: /* 5.5 */
871 if (max2 == 0) {
872 /* B/G FM-stereo */
873 msp->second = carrier_detect_55[max2].cdo;
874 msp3400c_setmode(client, MSP_MODE_FM_TERRA);
875 msp->nicam_on = 0;
876 msp3400c_set_audmode(client, V4L2_TUNER_MODE_MONO);
877 msp->watch_stereo = 1;
878 } else if (max2 == 1 && HAVE_NICAM(msp)) {
879 /* B/G NICAM */
880 msp->second = carrier_detect_55[max2].cdo;
881 msp3400c_setmode(client, MSP_MODE_FM_NICAM1);
882 msp->nicam_on = 1;
883 msp3400c_setcarrier(client, msp->second, msp->main);
884 msp->watch_stereo = 1;
885 } else {
886 goto no_second;
887 }
888 break;
889 case 2: /* 6.0 */
890 /* PAL I NICAM */
891 msp->second = MSP_CARRIER(6.552);
892 msp3400c_setmode(client, MSP_MODE_FM_NICAM2);
893 msp->nicam_on = 1;
894 msp3400c_setcarrier(client, msp->second, msp->main);
895 msp->watch_stereo = 1;
896 break;
897 case 3: /* 6.5 */
898 if (max2 == 1 || max2 == 2) {
899 /* D/K FM-stereo */
900 msp->second = carrier_detect_65[max2].cdo;
901 msp3400c_setmode(client, MSP_MODE_FM_TERRA);
902 msp->nicam_on = 0;
903 msp3400c_set_audmode(client, V4L2_TUNER_MODE_MONO);
904 msp->watch_stereo = 1;
905 } else if (max2 == 0 &&
906 msp->norm == VIDEO_MODE_SECAM) {
907 /* L NICAM or AM-mono */
908 msp->second = carrier_detect_65[max2].cdo;
909 msp3400c_setmode(client, MSP_MODE_AM_NICAM);
910 msp->nicam_on = 0;
911 msp3400c_set_audmode(client, V4L2_TUNER_MODE_MONO);
912 msp3400c_setcarrier(client, msp->second, msp->main);
913 /* volume prescale for SCART (AM mono input) */
914 msp3400c_write(client,I2C_MSP3400C_DFP, 0x000d, 0x1900);
915 msp->watch_stereo = 1;
916 } else if (max2 == 0 && HAVE_NICAM(msp)) {
917 /* D/K NICAM */
918 msp->second = carrier_detect_65[max2].cdo;
919 msp3400c_setmode(client, MSP_MODE_FM_NICAM1);
920 msp->nicam_on = 1;
921 msp3400c_setcarrier(client, msp->second, msp->main);
922 msp->watch_stereo = 1;
923 } else {
924 goto no_second;
925 }
926 break;
927 case 0: /* 4.5 */
928 default:
929 no_second:
930 msp->second = carrier_detect_main[max1].cdo;
931 msp3400c_setmode(client, MSP_MODE_FM_TERRA);
932 msp->nicam_on = 0;
933 msp3400c_setcarrier(client, msp->second, msp->main);
934 msp->rxsubchans = V4L2_TUNER_SUB_MONO;
935 msp3400c_set_audmode(client, V4L2_TUNER_MODE_MONO);
936 break;
937 }
938
939 /* unmute */
940 msp3400c_setvolume(client, msp->muted,
941 msp->volume, msp->balance);
942 if (debug)
943 msp3400c_print_mode(msp);
944
945 /* monitor tv audio mode */
946 while (msp->watch_stereo) {
947 if (msp34xx_sleep(msp,5000))
948 goto restart;
949 watch_stereo(client);
950 }
951 }
952 dprintk(KERN_DEBUG "msp3400: thread: exit\n");
953 return 0;
954}
955
956/* ----------------------------------------------------------------------- */
957/* this one uses the automatic sound standard detection of newer */
958/* msp34xx chip versions */
959
960static struct MODES {
961 int retval;
962 int main, second;
963 char *name;
964} modelist[] = {
965 { 0x0000, 0, 0, "ERROR" },
966 { 0x0001, 0, 0, "autodetect start" },
967 { 0x0002, MSP_CARRIER(4.5), MSP_CARRIER(4.72), "4.5/4.72 M Dual FM-Stereo" },
968 { 0x0003, MSP_CARRIER(5.5), MSP_CARRIER(5.7421875), "5.5/5.74 B/G Dual FM-Stereo" },
969 { 0x0004, MSP_CARRIER(6.5), MSP_CARRIER(6.2578125), "6.5/6.25 D/K1 Dual FM-Stereo" },
970 { 0x0005, MSP_CARRIER(6.5), MSP_CARRIER(6.7421875), "6.5/6.74 D/K2 Dual FM-Stereo" },
971 { 0x0006, MSP_CARRIER(6.5), MSP_CARRIER(6.5), "6.5 D/K FM-Mono (HDEV3)" },
972 { 0x0008, MSP_CARRIER(5.5), MSP_CARRIER(5.85), "5.5/5.85 B/G NICAM FM" },
973 { 0x0009, MSP_CARRIER(6.5), MSP_CARRIER(5.85), "6.5/5.85 L NICAM AM" },
974 { 0x000a, MSP_CARRIER(6.0), MSP_CARRIER(6.55), "6.0/6.55 I NICAM FM" },
975 { 0x000b, MSP_CARRIER(6.5), MSP_CARRIER(5.85), "6.5/5.85 D/K NICAM FM" },
976 { 0x000c, MSP_CARRIER(6.5), MSP_CARRIER(5.85), "6.5/5.85 D/K NICAM FM (HDEV2)" },
977 { 0x0020, MSP_CARRIER(4.5), MSP_CARRIER(4.5), "4.5 M BTSC-Stereo" },
978 { 0x0021, MSP_CARRIER(4.5), MSP_CARRIER(4.5), "4.5 M BTSC-Mono + SAP" },
979 { 0x0030, MSP_CARRIER(4.5), MSP_CARRIER(4.5), "4.5 M EIA-J Japan Stereo" },
980 { 0x0040, MSP_CARRIER(10.7), MSP_CARRIER(10.7), "10.7 FM-Stereo Radio" },
981 { 0x0050, MSP_CARRIER(6.5), MSP_CARRIER(6.5), "6.5 SAT-Mono" },
982 { 0x0051, MSP_CARRIER(7.02), MSP_CARRIER(7.20), "7.02/7.20 SAT-Stereo" },
983 { 0x0060, MSP_CARRIER(7.2), MSP_CARRIER(7.2), "7.2 SAT ADR" },
984 { -1, 0, 0, NULL }, /* EOF */
985};
986
987static inline const char *msp34xx_standard_mode_name(int mode)
988{
989 int i;
990 for (i = 0; modelist[i].name != NULL; i++)
991 if (modelist[i].retval == mode)
992 return modelist[i].name;
993 return "unknown";
994}
995
996static int msp34xx_modus(int norm)
997{
998 switch (norm) {
999 case VIDEO_MODE_PAL:
1000 return 0x1003;
1001 case VIDEO_MODE_NTSC: /* BTSC */
1002 return 0x2003;
1003 case VIDEO_MODE_SECAM:
1004 return 0x0003;
1005 case VIDEO_MODE_RADIO:
1006 return 0x0003;
1007 case VIDEO_MODE_AUTO:
1008 return 0x2003;
1009 default:
1010 return 0x0003;
1011 }
1012}
1013
1014static int msp34xx_standard(int norm)
1015{
1016 switch (norm) {
1017 case VIDEO_MODE_PAL:
1018 return 1;
1019 case VIDEO_MODE_NTSC: /* BTSC */
1020 return 0x0020;
1021 case VIDEO_MODE_SECAM:
1022 return 1;
1023 case VIDEO_MODE_RADIO:
1024 return 0x0040;
1025 default:
1026 return 1;
1027 }
1028}
1029
1030static int msp3410d_thread(void *data)
1031{
1032 struct i2c_client *client = data;
1033 struct msp3400c *msp = i2c_get_clientdata(client);
1034 int mode,val,i,std;
1035
1036 printk("msp3410: daemon started\n");
1037 for (;;) {
1038 d2printk(KERN_DEBUG "msp3410: thread: sleep\n");
1039 msp34xx_sleep(msp,-1);
1040 d2printk(KERN_DEBUG "msp3410: thread: wakeup\n");
1041
1042 restart:
1043 dprintk("msp3410: thread: restart scan\n");
1044 msp->restart = 0;
1045 if (kthread_should_stop())
1046 break;
1047
1048 if (msp->mode == MSP_MODE_EXTERN) {
1049 /* no carrier scan needed, just unmute */
1050 dprintk(KERN_DEBUG "msp3410: thread: no carrier scan\n");
1051 msp3400c_setvolume(client, msp->muted,
1052 msp->volume, msp->balance);
1053 continue;
1054 }
1055
1056 /* put into sane state (and mute) */
1057 msp3400c_reset(client);
1058
1059 /* some time for the tuner to sync */
1060 if (msp34xx_sleep(msp,200))
1061 goto restart;
1062
1063 /* start autodetect */
1064 mode = msp34xx_modus(msp->norm);
1065 std = msp34xx_standard(msp->norm);
1066 msp3400c_write(client, I2C_MSP3400C_DEM, 0x30, mode);
1067 msp3400c_write(client, I2C_MSP3400C_DEM, 0x20, std);
1068 msp->watch_stereo = 0;
1069
1070 if (debug)
1071 printk(KERN_DEBUG "msp3410: setting mode: %s (0x%04x)\n",
1072 msp34xx_standard_mode_name(std) ,std);
1073
1074 if (std != 1) {
1075 /* programmed some specific mode */
1076 val = std;
1077 } else {
1078 /* triggered autodetect */
1079 for (;;) {
1080 if (msp34xx_sleep(msp,100))
1081 goto restart;
1082
1083 /* check results */
1084 val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x7e);
1085 if (val < 0x07ff)
1086 break;
1087 dprintk(KERN_DEBUG "msp3410: detection still in progress\n");
1088 }
1089 }
1090 for (i = 0; modelist[i].name != NULL; i++)
1091 if (modelist[i].retval == val)
1092 break;
1093 dprintk(KERN_DEBUG "msp3410: current mode: %s (0x%04x)\n",
1094 modelist[i].name ? modelist[i].name : "unknown",
1095 val);
1096 msp->main = modelist[i].main;
1097 msp->second = modelist[i].second;
1098
1099 if (amsound && (msp->norm == VIDEO_MODE_SECAM) && (val != 0x0009)) {
1100 /* autodetection has failed, let backup */
1101 dprintk(KERN_DEBUG "msp3410: autodetection failed,"
1102 " switching to backup mode: %s (0x%04x)\n",
1103 modelist[8].name ? modelist[8].name : "unknown",val);
1104 val = 0x0009;
1105 msp3400c_write(client, I2C_MSP3400C_DEM, 0x20, val);
1106 }
1107
1108 /* set various prescales */
1109 msp3400c_write(client, I2C_MSP3400C_DFP, 0x0d, 0x1900); /* scart */
1110 msp3400c_write(client, I2C_MSP3400C_DFP, 0x0e, 0x2403); /* FM */
1111 msp3400c_write(client, I2C_MSP3400C_DFP, 0x10, 0x5a00); /* nicam */
1112
1113 /* set stereo */
1114 switch (val) {
1115 case 0x0008: /* B/G NICAM */
1116 case 0x000a: /* I NICAM */
1117 if (val == 0x0008)
1118 msp->mode = MSP_MODE_FM_NICAM1;
1119 else
1120 msp->mode = MSP_MODE_FM_NICAM2;
1121 /* just turn on stereo */
1122 msp->rxsubchans = V4L2_TUNER_SUB_STEREO;
1123 msp->nicam_on = 1;
1124 msp->watch_stereo = 1;
1125 msp3400c_set_audmode(client,V4L2_TUNER_MODE_STEREO);
1126 break;
1127 case 0x0009:
1128 msp->mode = MSP_MODE_AM_NICAM;
1129 msp->rxsubchans = V4L2_TUNER_SUB_MONO;
1130 msp->nicam_on = 1;
1131 msp3400c_set_audmode(client,V4L2_TUNER_MODE_MONO);
1132 msp->watch_stereo = 1;
1133 break;
1134 case 0x0020: /* BTSC */
1135 /* just turn on stereo */
1136 msp->mode = MSP_MODE_BTSC;
1137 msp->rxsubchans = V4L2_TUNER_SUB_STEREO;
1138 msp->nicam_on = 0;
1139 msp->watch_stereo = 1;
1140 msp3400c_set_audmode(client,V4L2_TUNER_MODE_STEREO);
1141 break;
1142 case 0x0040: /* FM radio */
1143 msp->mode = MSP_MODE_FM_RADIO;
1144 msp->rxsubchans = V4L2_TUNER_SUB_STEREO;
1145 msp->audmode = V4L2_TUNER_MODE_STEREO;
1146 msp->nicam_on = 0;
1147 msp->watch_stereo = 0;
1148 /* not needed in theory if HAVE_RADIO(), but
1149 short programming enables carrier mute */
1150 msp3400c_setmode(client,MSP_MODE_FM_RADIO);
1151 msp3400c_setcarrier(client, MSP_CARRIER(10.7),
1152 MSP_CARRIER(10.7));
1153 /* scart routing */
1154 msp3400c_set_scart(client,SCART_IN2,0);
1155#if 0
1156 /* radio from SCART_IN2 */
1157 msp3400c_write(client,I2C_MSP3400C_DFP, 0x08, 0x0220);
1158 msp3400c_write(client,I2C_MSP3400C_DFP, 0x09, 0x0220);
1159 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0b, 0x0220);
1160#else
1161 /* msp34xx does radio decoding */
1162 msp3400c_write(client,I2C_MSP3400C_DFP, 0x08, 0x0020);
1163 msp3400c_write(client,I2C_MSP3400C_DFP, 0x09, 0x0020);
1164 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0b, 0x0020);
1165#endif
1166 break;
1167 case 0x0003:
1168 case 0x0004:
1169 case 0x0005:
1170 msp->mode = MSP_MODE_FM_TERRA;
1171 msp->rxsubchans = V4L2_TUNER_SUB_MONO;
1172 msp->audmode = V4L2_TUNER_MODE_MONO;
1173 msp->nicam_on = 0;
1174 msp->watch_stereo = 1;
1175 break;
1176 }
1177
1178 /* unmute, restore misc registers */
1179 msp3400c_setbass(client, msp->bass);
1180 msp3400c_settreble(client, msp->treble);
1181 msp3400c_setvolume(client, msp->muted,
1182 msp->volume, msp->balance);
1183 msp3400c_write(client, I2C_MSP3400C_DFP, 0x0013, msp->acb);
1184
1185 /* monitor tv audio mode */
1186 while (msp->watch_stereo) {
1187 if (msp34xx_sleep(msp,5000))
1188 goto restart;
1189 watch_stereo(client);
1190 }
1191 }
1192 dprintk(KERN_DEBUG "msp3410: thread: exit\n");
1193 return 0;
1194}
1195
1196/* ----------------------------------------------------------------------- */
1197/* msp34xxG + (simpler no-thread) */
1198/* this one uses both automatic standard detection and automatic sound */
1199/* select which are available in the newer G versions */
1200/* struct msp: only norm, acb and source are really used in this mode */
1201
1202static void msp34xxg_set_source(struct i2c_client *client, int source);
1203
1204/* (re-)initialize the msp34xxg, according to the current norm in msp->norm
1205 * return 0 if it worked, -1 if it failed
1206 */
1207static int msp34xxg_init(struct i2c_client *client)
1208{
1209 struct msp3400c *msp = i2c_get_clientdata(client);
1210 int modus,std;
1211
1212 if (msp3400c_reset(client))
1213 return -1;
1214
1215 /* make sure that input/output is muted (paranoid mode) */
1216 if (msp3400c_write(client,
1217 I2C_MSP3400C_DFP,
1218 0x13, /* ACB */
1219 0x0f20 /* mute DSP input, mute SCART 1 */))
1220 return -1;
1221
1222 /* step-by-step initialisation, as described in the manual */
1223 modus = msp34xx_modus(msp->norm);
1224 std = msp34xx_standard(msp->norm);
1225 modus &= ~0x03; /* STATUS_CHANGE=0 */
1226 modus |= 0x01; /* AUTOMATIC_SOUND_DETECTION=1 */
1227 if (msp3400c_write(client,
1228 I2C_MSP3400C_DEM,
1229 0x30/*MODUS*/,
1230 modus))
1231 return -1;
1232 if (msp3400c_write(client,
1233 I2C_MSP3400C_DEM,
1234 0x20/*stanard*/,
1235 std))
1236 return -1;
1237
1238 /* write the dfps that may have an influence on
1239 standard/audio autodetection right now */
1240 msp34xxg_set_source(client, msp->source);
1241
1242 if (msp3400c_write(client, I2C_MSP3400C_DFP,
1243 0x0e, /* AM/FM Prescale */
1244 0x3000 /* default: [15:8] 75khz deviation */))
1245 return -1;
1246
1247 if (msp3400c_write(client, I2C_MSP3400C_DFP,
1248 0x10, /* NICAM Prescale */
1249 0x5a00 /* default: 9db gain (as recommended) */))
1250 return -1;
1251
1252 if (msp3400c_write(client,
1253 I2C_MSP3400C_DEM,
1254 0x20, /* STANDARD SELECT */
1255 standard /* default: 0x01 for automatic standard select*/))
1256 return -1;
1257 return 0;
1258}
1259
1260static int msp34xxg_thread(void *data)
1261{
1262 struct i2c_client *client = data;
1263 struct msp3400c *msp = i2c_get_clientdata(client);
1264 int val, std, i;
1265
1266 printk("msp34xxg: daemon started\n");
1267 for (;;) {
1268 d2printk(KERN_DEBUG "msp34xxg: thread: sleep\n");
1269 msp34xx_sleep(msp,-1);
1270 d2printk(KERN_DEBUG "msp34xxg: thread: wakeup\n");
1271
1272 restart:
1273 dprintk("msp34xxg: thread: restart scan\n");
1274 msp->restart = 0;
1275 if (kthread_should_stop())
1276 break;
1277
1278 /* setup the chip*/
1279 msp34xxg_init(client);
1280 std = standard;
1281 if (std != 0x01)
1282 goto unmute;
1283
1284 /* watch autodetect */
1285 dprintk("msp34xxg: triggered autodetect, waiting for result\n");
1286 for (i = 0; i < 10; i++) {
1287 if (msp34xx_sleep(msp,100))
1288 goto restart;
1289
1290 /* check results */
1291 val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x7e);
1292 if (val < 0x07ff) {
1293 std = val;
1294 break;
1295 }
1296 dprintk("msp34xxg: detection still in progress\n");
1297 }
1298 if (0x01 == std) {
1299 dprintk("msp34xxg: detection still in progress after 10 tries. giving up.\n");
1300 continue;
1301 }
1302
1303 unmute:
1304 dprintk("msp34xxg: current mode: %s (0x%04x)\n",
1305 msp34xx_standard_mode_name(std), std);
1306
1307 /* unmute: dispatch sound to scart output, set scart volume */
1308 dprintk("msp34xxg: unmute\n");
1309
1310 msp3400c_setbass(client, msp->bass);
1311 msp3400c_settreble(client, msp->treble);
1312 msp3400c_setvolume(client, msp->muted, msp->volume, msp->balance);
1313
1314 /* restore ACB */
1315 if (msp3400c_write(client,
1316 I2C_MSP3400C_DFP,
1317 0x13, /* ACB */
1318 msp->acb))
1319 return -1;
1320 }
1321 dprintk(KERN_DEBUG "msp34xxg: thread: exit\n");
1322 return 0;
1323}
1324
1325/* set the same 'source' for the loudspeaker, scart and quasi-peak detector
1326 * the value for source is the same as bit 15:8 of DFP registers 0x08,
1327 * 0x0a and 0x0c: 0=mono, 1=stereo or A|B, 2=SCART, 3=stereo or A, 4=stereo or B
1328 *
1329 * this function replaces msp3400c_setstereo
1330 */
1331static void msp34xxg_set_source(struct i2c_client *client, int source)
1332{
1333 struct msp3400c *msp = i2c_get_clientdata(client);
1334
1335 /* fix matrix mode to stereo and let the msp choose what
1336 * to output according to 'source', as recommended
1337 */
1338 int value = (source&0x07)<<8|(source==0 ? 0x00:0x20);
1339 dprintk("msp34xxg: set source to %d (0x%x)\n", source, value);
1340 msp3400c_write(client,
1341 I2C_MSP3400C_DFP,
1342 0x08, /* Loudspeaker Output */
1343 value);
1344 msp3400c_write(client,
1345 I2C_MSP3400C_DFP,
1346 0x0a, /* SCART1 DA Output */
1347 value);
1348 msp3400c_write(client,
1349 I2C_MSP3400C_DFP,
1350 0x0c, /* Quasi-peak detector */
1351 value);
1352 /*
1353 * set identification threshold. Personally, I
1354 * I set it to a higher value that the default
1355 * of 0x190 to ignore noisy stereo signals.
1356 * this needs tuning. (recommended range 0x00a0-0x03c0)
1357 * 0x7f0 = forced mono mode
1358 */
1359 msp3400c_write(client,
1360 I2C_MSP3400C_DEM,
1361 0x22, /* a2 threshold for stereo/bilingual */
1362 source==0 ? 0x7f0:stereo_threshold);
1363 msp->source=source;
1364}
1365
1366static void msp34xxg_detect_stereo(struct i2c_client *client)
1367{
1368 struct msp3400c *msp = i2c_get_clientdata(client);
1369
1370 int status = msp3400c_read(client,
1371 I2C_MSP3400C_DEM,
1372 0x0200 /* STATUS */);
1373 int is_bilingual = status&0x100;
1374 int is_stereo = status&0x40;
1375
1376 msp->rxsubchans = 0;
1377 if (is_stereo)
1378 msp->rxsubchans |= V4L2_TUNER_SUB_STEREO;
1379 else
1380 msp->rxsubchans |= V4L2_TUNER_SUB_MONO;
1381 if (is_bilingual) {
1382 msp->rxsubchans |= V4L2_TUNER_SUB_LANG1|V4L2_TUNER_SUB_LANG2;
1383 /* I'm supposed to check whether it's SAP or not
1384 * and set only LANG2/SAP in this case. Yet, the MSP
1385 * does a lot of work to hide this and handle everything
1386 * the same way. I don't want to work around it so unless
1387 * this is a problem, I'll handle SAP just like lang1/lang2.
1388 */
1389 }
1390 dprintk("msp34xxg: status=0x%x, stereo=%d, bilingual=%d -> rxsubchans=%d\n",
1391 status, is_stereo, is_bilingual, msp->rxsubchans);
1392}
1393
1394static void msp34xxg_set_audmode(struct i2c_client *client, int audmode)
1395{
1396 struct msp3400c *msp = i2c_get_clientdata(client);
1397 int source = 0;
1398
1399 switch (audmode) {
1400 case V4L2_TUNER_MODE_MONO:
1401 source=0; /* mono only */
1402 break;
1403 case V4L2_TUNER_MODE_STEREO:
1404 source=1; /* stereo or A|B, see comment in msp34xxg_get_v4l2_stereo() */
1405 /* problem: that could also mean 2 (scart input) */
1406 break;
1407 case V4L2_TUNER_MODE_LANG1:
1408 source=3; /* stereo or A */
1409 break;
1410 case V4L2_TUNER_MODE_LANG2:
1411 source=4; /* stereo or B */
1412 break;
1413 default: /* doing nothing: a safe, sane default */
1414 audmode = 0;
1415 return;
1416 }
1417 msp->audmode = audmode;
1418 msp34xxg_set_source(client, source);
1419}
1420
1421
1422/* ----------------------------------------------------------------------- */
1423
1424static int msp_attach(struct i2c_adapter *adap, int addr, int kind);
1425static int msp_detach(struct i2c_client *client);
1426static int msp_probe(struct i2c_adapter *adap);
1427static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg);
1428
1429static int msp_suspend(struct device * dev, u32 state, u32 level);
1430static int msp_resume(struct device * dev, u32 level);
1431
1432static void msp_wake_thread(struct i2c_client *client);
1433
1434static struct i2c_driver driver = {
1435 .owner = THIS_MODULE,
1436 .name = "i2c msp3400 driver",
1437 .id = I2C_DRIVERID_MSP3400,
1438 .flags = I2C_DF_NOTIFY,
1439 .attach_adapter = msp_probe,
1440 .detach_client = msp_detach,
1441 .command = msp_command,
1442 .driver = {
1443 .suspend = msp_suspend,
1444 .resume = msp_resume,
1445 },
1446};
1447
1448static struct i2c_client client_template =
1449{
1450 I2C_DEVNAME("(unset)"),
1451 .flags = I2C_CLIENT_ALLOW_USE,
1452 .driver = &driver,
1453};
1454
1455static int msp_attach(struct i2c_adapter *adap, int addr, int kind)
1456{
1457 struct msp3400c *msp;
1458 struct i2c_client *c;
1459 int (*thread_func)(void *data) = NULL;
1460
1461 client_template.adapter = adap;
1462 client_template.addr = addr;
1463
1464 if (-1 == msp3400c_reset(&client_template)) {
1465 dprintk("msp3400: no chip found\n");
1466 return -1;
1467 }
1468
1469 if (NULL == (c = kmalloc(sizeof(struct i2c_client),GFP_KERNEL)))
1470 return -ENOMEM;
1471 memcpy(c,&client_template,sizeof(struct i2c_client));
1472 if (NULL == (msp = kmalloc(sizeof(struct msp3400c),GFP_KERNEL))) {
1473 kfree(c);
1474 return -ENOMEM;
1475 }
1476
1477 memset(msp,0,sizeof(struct msp3400c));
1478 msp->volume = 58880; /* 0db gain */
1479 msp->balance = 32768;
1480 msp->bass = 32768;
1481 msp->treble = 32768;
1482 msp->input = -1;
1483 msp->muted = 1;
1484
1485 i2c_set_clientdata(c, msp);
1486 init_waitqueue_head(&msp->wq);
1487
1488 if (-1 == msp3400c_reset(c)) {
1489 kfree(msp);
1490 kfree(c);
1491 dprintk("msp3400: no chip found\n");
1492 return -1;
1493 }
1494
1495 msp->rev1 = msp3400c_read(c, I2C_MSP3400C_DFP, 0x1e);
1496 if (-1 != msp->rev1)
1497 msp->rev2 = msp3400c_read(c, I2C_MSP3400C_DFP, 0x1f);
1498 if ((-1 == msp->rev1) || (0 == msp->rev1 && 0 == msp->rev2)) {
1499 kfree(msp);
1500 kfree(c);
1501 printk("msp3400: error while reading chip version\n");
1502 return -1;
1503 }
1504
1505#if 0
1506 /* this will turn on a 1kHz beep - might be useful for debugging... */
1507 msp3400c_write(c,I2C_MSP3400C_DFP, 0x0014, 0x1040);
1508#endif
1509 msp3400c_setvolume(c, msp->muted, msp->volume, msp->balance);
1510
1511 snprintf(c->name, sizeof(c->name), "MSP34%02d%c-%c%d",
1512 (msp->rev2>>8)&0xff, (msp->rev1&0xff)+'@',
1513 ((msp->rev1>>8)&0xff)+'@', msp->rev2&0x1f);
1514
1515 msp->opmode = opmode;
1516 if (OPMODE_AUTO == msp->opmode) {
1517#if 0 /* seems to work for ivtv only, disable by default for now ... */
1518 if (HAVE_SIMPLER(msp))
1519 msp->opmode = OPMODE_SIMPLER;
1520 else
1521#endif
1522 if (HAVE_SIMPLE(msp))
1523 msp->opmode = OPMODE_SIMPLE;
1524 else
1525 msp->opmode = OPMODE_MANUAL;
1526 }
1527
1528 /* hello world :-) */
1529 printk(KERN_INFO "msp34xx: init: chip=%s",i2c_clientname(c));
1530 if (HAVE_NICAM(msp))
1531 printk(" +nicam");
1532 if (HAVE_SIMPLE(msp))
1533 printk(" +simple");
1534 if (HAVE_SIMPLER(msp))
1535 printk(" +simpler");
1536 if (HAVE_RADIO(msp))
1537 printk(" +radio");
1538
1539 /* version-specific initialization */
1540 switch (msp->opmode) {
1541 case OPMODE_MANUAL:
1542 printk(" mode=manual");
1543 thread_func = msp3400c_thread;
1544 break;
1545 case OPMODE_SIMPLE:
1546 printk(" mode=simple");
1547 thread_func = msp3410d_thread;
1548 break;
1549 case OPMODE_SIMPLER:
1550 printk(" mode=simpler");
1551 thread_func = msp34xxg_thread;
1552 break;
1553 }
1554 printk("\n");
1555
1556 /* startup control thread if needed */
1557 if (thread_func) {
1558 msp->kthread = kthread_run(thread_func, c, "msp34xx");
1559 if (NULL == msp->kthread)
1560 printk(KERN_WARNING "msp34xx: kernel_thread() failed\n");
1561 msp_wake_thread(c);
1562 }
1563
1564 /* done */
1565 i2c_attach_client(c);
1566 return 0;
1567}
1568
1569static int msp_detach(struct i2c_client *client)
1570{
1571 struct msp3400c *msp = i2c_get_clientdata(client);
1572
1573 /* shutdown control thread */
1574 if (msp->kthread >= 0) {
1575 msp->restart = 1;
1576 kthread_stop(msp->kthread);
1577 }
1578 msp3400c_reset(client);
1579
1580 i2c_detach_client(client);
1581 kfree(msp);
1582 kfree(client);
1583 return 0;
1584}
1585
1586static int msp_probe(struct i2c_adapter *adap)
1587{
1588 if (adap->class & I2C_CLASS_TV_ANALOG)
1589 return i2c_probe(adap, &addr_data, msp_attach);
1590 return 0;
1591}
1592
1593static void msp_wake_thread(struct i2c_client *client)
1594{
1595 struct msp3400c *msp = i2c_get_clientdata(client);
1596
1597 if (NULL == msp->kthread)
1598 return;
1599 msp3400c_setvolume(client,msp->muted,0,0);
1600 msp->watch_stereo = 0;
1601 msp->restart = 1;
1602 wake_up_interruptible(&msp->wq);
1603}
1604
1605/* ----------------------------------------------------------------------- */
1606
1607static int mode_v4l2_to_v4l1(int rxsubchans)
1608{
1609 int mode = 0;
1610
1611 if (rxsubchans & V4L2_TUNER_SUB_STEREO)
1612 mode |= VIDEO_SOUND_STEREO;
1613 if (rxsubchans & V4L2_TUNER_SUB_LANG2)
1614 mode |= VIDEO_SOUND_LANG2;
1615 if (rxsubchans & V4L2_TUNER_SUB_LANG1)
1616 mode |= VIDEO_SOUND_LANG1;
1617 if (0 == mode)
1618 mode |= VIDEO_SOUND_MONO;
1619 return mode;
1620}
1621
1622static int mode_v4l1_to_v4l2(int mode)
1623{
1624 if (mode & VIDEO_SOUND_STEREO)
1625 return V4L2_TUNER_MODE_STEREO;
1626 if (mode & VIDEO_SOUND_LANG2)
1627 return V4L2_TUNER_MODE_LANG2;
1628 if (mode & VIDEO_SOUND_LANG1)
1629 return V4L2_TUNER_MODE_LANG1;
1630 return V4L2_TUNER_MODE_MONO;
1631}
1632
1633static void msp_any_detect_stereo(struct i2c_client *client)
1634{
1635 struct msp3400c *msp = i2c_get_clientdata(client);
1636
1637 switch (msp->opmode) {
1638 case OPMODE_MANUAL:
1639 case OPMODE_SIMPLE:
1640 autodetect_stereo(client);
1641 break;
1642 case OPMODE_SIMPLER:
1643 msp34xxg_detect_stereo(client);
1644 break;
1645 }
1646}
1647
1648static void msp_any_set_audmode(struct i2c_client *client, int audmode)
1649{
1650 struct msp3400c *msp = i2c_get_clientdata(client);
1651
1652 switch (msp->opmode) {
1653 case OPMODE_MANUAL:
1654 case OPMODE_SIMPLE:
1655 msp->watch_stereo = 0;
1656 msp3400c_set_audmode(client, audmode);
1657 break;
1658 case OPMODE_SIMPLER:
1659 msp34xxg_set_audmode(client, audmode);
1660 break;
1661 }
1662}
1663
1664static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
1665{
1666 struct msp3400c *msp = i2c_get_clientdata(client);
1667 __u16 *sarg = arg;
1668 int scart = 0;
1669
1670 switch (cmd) {
1671
1672 case AUDC_SET_INPUT:
1673 dprintk(KERN_DEBUG "msp34xx: AUDC_SET_INPUT(%d)\n",*sarg);
1674 if (*sarg == msp->input)
1675 break;
1676 msp->input = *sarg;
1677 switch (*sarg) {
1678 case AUDIO_RADIO:
1679 /* Hauppauge uses IN2 for the radio */
1680 msp->mode = MSP_MODE_FM_RADIO;
1681 scart = SCART_IN2;
1682 break;
1683 case AUDIO_EXTERN_1:
1684 /* IN1 is often used for external input ... */
1685 msp->mode = MSP_MODE_EXTERN;
1686 scart = SCART_IN1;
1687 break;
1688 case AUDIO_EXTERN_2:
1689 /* ... sometimes it is IN2 through ;) */
1690 msp->mode = MSP_MODE_EXTERN;
1691 scart = SCART_IN2;
1692 break;
1693 case AUDIO_TUNER:
1694 msp->mode = -1;
1695 break;
1696 default:
1697 if (*sarg & AUDIO_MUTE)
1698 msp3400c_set_scart(client,SCART_MUTE,0);
1699 break;
1700 }
1701 if (scart) {
1702 msp->rxsubchans = V4L2_TUNER_SUB_STEREO;
1703 msp->audmode = V4L2_TUNER_MODE_STEREO;
1704 msp3400c_set_scart(client,scart,0);
1705 msp3400c_write(client,I2C_MSP3400C_DFP,0x000d,0x1900);
1706 if (msp->opmode != OPMODE_SIMPLER)
1707 msp3400c_set_audmode(client, msp->audmode);
1708 }
1709 msp_wake_thread(client);
1710 break;
1711
1712 case AUDC_SET_RADIO:
1713 dprintk(KERN_DEBUG "msp34xx: AUDC_SET_RADIO\n");
1714 msp->norm = VIDEO_MODE_RADIO;
1715 dprintk(KERN_DEBUG "msp34xx: switching to radio mode\n");
1716 msp->watch_stereo = 0;
1717 switch (msp->opmode) {
1718 case OPMODE_MANUAL:
1719 /* set msp3400 to FM radio mode */
1720 msp3400c_setmode(client,MSP_MODE_FM_RADIO);
1721 msp3400c_setcarrier(client, MSP_CARRIER(10.7),
1722 MSP_CARRIER(10.7));
1723 msp3400c_setvolume(client, msp->muted,
1724 msp->volume, msp->balance);
1725 break;
1726 case OPMODE_SIMPLE:
1727 case OPMODE_SIMPLER:
1728 /* the thread will do for us */
1729 msp_wake_thread(client);
1730 break;
1731 }
1732 break;
1733
1734 /* --- v4l ioctls --- */
1735 /* take care: bttv does userspace copying, we'll get a
1736 kernel pointer here... */
1737 case VIDIOCGAUDIO:
1738 {
1739 struct video_audio *va = arg;
1740
1741 dprintk(KERN_DEBUG "msp34xx: VIDIOCGAUDIO\n");
1742 va->flags |= VIDEO_AUDIO_VOLUME |
1743 VIDEO_AUDIO_BASS |
1744 VIDEO_AUDIO_TREBLE |
1745 VIDEO_AUDIO_MUTABLE;
1746 if (msp->muted)
1747 va->flags |= VIDEO_AUDIO_MUTE;
1748
1749 va->volume = msp->volume;
1750 va->balance = (va->volume) ? msp->balance : 32768;
1751 va->bass = msp->bass;
1752 va->treble = msp->treble;
1753
1754 msp_any_detect_stereo(client);
1755 va->mode = mode_v4l2_to_v4l1(msp->rxsubchans);
1756 break;
1757 }
1758 case VIDIOCSAUDIO:
1759 {
1760 struct video_audio *va = arg;
1761
1762 dprintk(KERN_DEBUG "msp34xx: VIDIOCSAUDIO\n");
1763 msp->muted = (va->flags & VIDEO_AUDIO_MUTE);
1764 msp->volume = va->volume;
1765 msp->balance = va->balance;
1766 msp->bass = va->bass;
1767 msp->treble = va->treble;
1768
1769 msp3400c_setvolume(client, msp->muted,
1770 msp->volume, msp->balance);
1771 msp3400c_setbass(client,msp->bass);
1772 msp3400c_settreble(client,msp->treble);
1773
1774 if (va->mode != 0 && msp->norm != VIDEO_MODE_RADIO)
1775 msp_any_set_audmode(client,mode_v4l1_to_v4l2(va->mode));
1776 break;
1777 }
1778 case VIDIOCSCHAN:
1779 {
1780 struct video_channel *vc = arg;
1781
1782 dprintk(KERN_DEBUG "msp34xx: VIDIOCSCHAN (norm=%d)\n",vc->norm);
1783 msp->norm = vc->norm;
1784 msp_wake_thread(client);
1785 break;
1786 }
1787
1788 case VIDIOCSFREQ:
1789 case VIDIOC_S_FREQUENCY:
1790 {
1791 /* new channel -- kick audio carrier scan */
1792 dprintk(KERN_DEBUG "msp34xx: VIDIOCSFREQ\n");
1793 msp_wake_thread(client);
1794 break;
1795 }
1796
1797 /* --- v4l2 ioctls --- */
1798 case VIDIOC_G_TUNER:
1799 {
1800 struct v4l2_tuner *vt = arg;
1801
1802 msp_any_detect_stereo(client);
1803 vt->audmode = msp->audmode;
1804 vt->rxsubchans = msp->rxsubchans;
1805 vt->capability = V4L2_TUNER_CAP_STEREO |
1806 V4L2_TUNER_CAP_LANG1|
1807 V4L2_TUNER_CAP_LANG2;
1808 break;
1809 }
1810 case VIDIOC_S_TUNER:
1811 {
1812 struct v4l2_tuner *vt=(struct v4l2_tuner *)arg;
1813
1814 /* only set audmode */
1815 if (vt->audmode != -1 && vt->audmode != 0)
1816 msp_any_set_audmode(client, vt->audmode);
1817 break;
1818 }
1819
1820 /* msp34xx specific */
1821 case MSP_SET_MATRIX:
1822 {
1823 struct msp_matrix *mspm = arg;
1824
1825 dprintk(KERN_DEBUG "msp34xx: MSP_SET_MATRIX\n");
1826 msp3400c_set_scart(client, mspm->input, mspm->output);
1827 break;
1828 }
1829
1830 default:
1831 /* nothing */
1832 break;
1833 }
1834 return 0;
1835}
1836
1837static int msp_suspend(struct device * dev, u32 state, u32 level)
1838{
1839 struct i2c_client *c = container_of(dev, struct i2c_client, dev);
1840
1841 dprintk("msp34xx: suspend\n");
1842 msp3400c_reset(c);
1843 return 0;
1844}
1845
1846static int msp_resume(struct device * dev, u32 level)
1847{
1848 struct i2c_client *c = container_of(dev, struct i2c_client, dev);
1849
1850 dprintk("msp34xx: resume\n");
1851 msp_wake_thread(c);
1852 return 0;
1853}
1854
1855/* ----------------------------------------------------------------------- */
1856
1857static int __init msp3400_init_module(void)
1858{
1859 return i2c_add_driver(&driver);
1860}
1861
1862static void __exit msp3400_cleanup_module(void)
1863{
1864 i2c_del_driver(&driver);
1865}
1866
1867module_init(msp3400_init_module);
1868module_exit(msp3400_cleanup_module);
1869
1870/*
1871 * Overrides for Emacs so that we follow Linus's tabbing style.
1872 * ---------------------------------------------------------------------------
1873 * Local variables:
1874 * c-basic-offset: 8
1875 * End:
1876 */
diff --git a/drivers/media/video/msp3400.h b/drivers/media/video/msp3400.h
new file mode 100644
index 00000000000..d70a954e13a
--- /dev/null
+++ b/drivers/media/video/msp3400.h
@@ -0,0 +1,36 @@
1#ifndef MSP3400_H
2#define MSP3400_H
3
4/* ---------------------------------------------------------------------- */
5
6struct msp_dfpreg {
7 int reg;
8 int value;
9};
10
11struct msp_matrix {
12 int input;
13 int output;
14};
15
16#define MSP_SET_DFPREG _IOW('m',15,struct msp_dfpreg)
17#define MSP_GET_DFPREG _IOW('m',16,struct msp_dfpreg)
18
19/* ioctl for MSP_SET_MATRIX will have to be registered */
20#define MSP_SET_MATRIX _IOW('m',17,struct msp_matrix)
21
22#define SCART_MASK 0
23#define SCART_IN1 1
24#define SCART_IN2 2
25#define SCART_IN1_DA 3
26#define SCART_IN2_DA 4
27#define SCART_IN3 5
28#define SCART_IN4 6
29#define SCART_MONO 7
30#define SCART_MUTE 8
31
32#define SCART_DSP_IN 0
33#define SCART1_OUT 1
34#define SCART2_OUT 2
35
36#endif /* MSP3400_H */
diff --git a/drivers/media/video/mt20xx.c b/drivers/media/video/mt20xx.c
new file mode 100644
index 00000000000..95ad17b7f38
--- /dev/null
+++ b/drivers/media/video/mt20xx.c
@@ -0,0 +1,558 @@
1/*
2 * $Id: mt20xx.c,v 1.4 2005/03/04 09:24:56 kraxel Exp $
3 *
4 * i2c tv tuner chip device driver
5 * controls microtune tuners, mt2032 + mt2050 at the moment.
6 */
7#include <linux/delay.h>
8#include <linux/i2c.h>
9#include <linux/videodev.h>
10#include <linux/moduleparam.h>
11#include <media/tuner.h>
12
13/* ---------------------------------------------------------------------- */
14
15static unsigned int optimize_vco = 1;
16module_param(optimize_vco, int, 0644);
17
18static unsigned int tv_antenna = 1;
19module_param(tv_antenna, int, 0644);
20
21static unsigned int radio_antenna = 0;
22module_param(radio_antenna, int, 0644);
23
24/* ---------------------------------------------------------------------- */
25
26#define MT2032 0x04
27#define MT2030 0x06
28#define MT2040 0x07
29#define MT2050 0x42
30
31static char *microtune_part[] = {
32 [ MT2030 ] = "MT2030",
33 [ MT2032 ] = "MT2032",
34 [ MT2040 ] = "MT2040",
35 [ MT2050 ] = "MT2050",
36};
37
38// IsSpurInBand()?
39static int mt2032_spurcheck(struct i2c_client *c,
40 int f1, int f2, int spectrum_from,int spectrum_to)
41{
42 struct tuner *t = i2c_get_clientdata(c);
43 int n1=1,n2,f;
44
45 f1=f1/1000; //scale to kHz to avoid 32bit overflows
46 f2=f2/1000;
47 spectrum_from/=1000;
48 spectrum_to/=1000;
49
50 tuner_dbg("spurcheck f1=%d f2=%d from=%d to=%d\n",
51 f1,f2,spectrum_from,spectrum_to);
52
53 do {
54 n2=-n1;
55 f=n1*(f1-f2);
56 do {
57 n2--;
58 f=f-f2;
59 tuner_dbg("spurtest n1=%d n2=%d ftest=%d\n",n1,n2,f);
60
61 if( (f>spectrum_from) && (f<spectrum_to))
62 tuner_dbg("mt2032 spurcheck triggered: %d\n",n1);
63 } while ( (f>(f2-spectrum_to)) || (n2>-5));
64 n1++;
65 } while (n1<5);
66
67 return 1;
68}
69
70static int mt2032_compute_freq(struct i2c_client *c,
71 unsigned int rfin,
72 unsigned int if1, unsigned int if2,
73 unsigned int spectrum_from,
74 unsigned int spectrum_to,
75 unsigned char *buf,
76 int *ret_sel,
77 unsigned int xogc) //all in Hz
78{
79 struct tuner *t = i2c_get_clientdata(c);
80 unsigned int fref,lo1,lo1n,lo1a,s,sel,lo1freq, desired_lo1,
81 desired_lo2,lo2,lo2n,lo2a,lo2num,lo2freq;
82
83 fref= 5250 *1000; //5.25MHz
84 desired_lo1=rfin+if1;
85
86 lo1=(2*(desired_lo1/1000)+(fref/1000)) / (2*fref/1000);
87 lo1n=lo1/8;
88 lo1a=lo1-(lo1n*8);
89
90 s=rfin/1000/1000+1090;
91
92 if(optimize_vco) {
93 if(s>1890) sel=0;
94 else if(s>1720) sel=1;
95 else if(s>1530) sel=2;
96 else if(s>1370) sel=3;
97 else sel=4; // >1090
98 }
99 else {
100 if(s>1790) sel=0; // <1958
101 else if(s>1617) sel=1;
102 else if(s>1449) sel=2;
103 else if(s>1291) sel=3;
104 else sel=4; // >1090
105 }
106 *ret_sel=sel;
107
108 lo1freq=(lo1a+8*lo1n)*fref;
109
110 tuner_dbg("mt2032: rfin=%d lo1=%d lo1n=%d lo1a=%d sel=%d, lo1freq=%d\n",
111 rfin,lo1,lo1n,lo1a,sel,lo1freq);
112
113 desired_lo2=lo1freq-rfin-if2;
114 lo2=(desired_lo2)/fref;
115 lo2n=lo2/8;
116 lo2a=lo2-(lo2n*8);
117 lo2num=((desired_lo2/1000)%(fref/1000))* 3780/(fref/1000); //scale to fit in 32bit arith
118 lo2freq=(lo2a+8*lo2n)*fref + lo2num*(fref/1000)/3780*1000;
119
120 tuner_dbg("mt2032: rfin=%d lo2=%d lo2n=%d lo2a=%d num=%d lo2freq=%d\n",
121 rfin,lo2,lo2n,lo2a,lo2num,lo2freq);
122
123 if(lo1a<0 || lo1a>7 || lo1n<17 ||lo1n>48 || lo2a<0 ||lo2a >7 ||lo2n<17 || lo2n>30) {
124 tuner_info("mt2032: frequency parameters out of range: %d %d %d %d\n",
125 lo1a, lo1n, lo2a,lo2n);
126 return(-1);
127 }
128
129 mt2032_spurcheck(c, lo1freq, desired_lo2, spectrum_from, spectrum_to);
130 // should recalculate lo1 (one step up/down)
131
132 // set up MT2032 register map for transfer over i2c
133 buf[0]=lo1n-1;
134 buf[1]=lo1a | (sel<<4);
135 buf[2]=0x86; // LOGC
136 buf[3]=0x0f; //reserved
137 buf[4]=0x1f;
138 buf[5]=(lo2n-1) | (lo2a<<5);
139 if(rfin >400*1000*1000)
140 buf[6]=0xe4;
141 else
142 buf[6]=0xf4; // set PKEN per rev 1.2
143 buf[7]=8+xogc;
144 buf[8]=0xc3; //reserved
145 buf[9]=0x4e; //reserved
146 buf[10]=0xec; //reserved
147 buf[11]=(lo2num&0xff);
148 buf[12]=(lo2num>>8) |0x80; // Lo2RST
149
150 return 0;
151}
152
153static int mt2032_check_lo_lock(struct i2c_client *c)
154{
155 struct tuner *t = i2c_get_clientdata(c);
156 int try,lock=0;
157 unsigned char buf[2];
158
159 for(try=0;try<10;try++) {
160 buf[0]=0x0e;
161 i2c_master_send(c,buf,1);
162 i2c_master_recv(c,buf,1);
163 tuner_dbg("mt2032 Reg.E=0x%02x\n",buf[0]);
164 lock=buf[0] &0x06;
165
166 if (lock==6)
167 break;
168
169 tuner_dbg("mt2032: pll wait 1ms for lock (0x%2x)\n",buf[0]);
170 udelay(1000);
171 }
172 return lock;
173}
174
175static int mt2032_optimize_vco(struct i2c_client *c,int sel,int lock)
176{
177 struct tuner *t = i2c_get_clientdata(c);
178 unsigned char buf[2];
179 int tad1;
180
181 buf[0]=0x0f;
182 i2c_master_send(c,buf,1);
183 i2c_master_recv(c,buf,1);
184 tuner_dbg("mt2032 Reg.F=0x%02x\n",buf[0]);
185 tad1=buf[0]&0x07;
186
187 if(tad1 ==0) return lock;
188 if(tad1 ==1) return lock;
189
190 if(tad1==2) {
191 if(sel==0)
192 return lock;
193 else sel--;
194 }
195 else {
196 if(sel<4)
197 sel++;
198 else
199 return lock;
200 }
201
202 tuner_dbg("mt2032 optimize_vco: sel=%d\n",sel);
203
204 buf[0]=0x0f;
205 buf[1]=sel;
206 i2c_master_send(c,buf,2);
207 lock=mt2032_check_lo_lock(c);
208 return lock;
209}
210
211
212static void mt2032_set_if_freq(struct i2c_client *c, unsigned int rfin,
213 unsigned int if1, unsigned int if2,
214 unsigned int from, unsigned int to)
215{
216 unsigned char buf[21];
217 int lint_try,ret,sel,lock=0;
218 struct tuner *t = i2c_get_clientdata(c);
219
220 tuner_dbg("mt2032_set_if_freq rfin=%d if1=%d if2=%d from=%d to=%d\n",
221 rfin,if1,if2,from,to);
222
223 buf[0]=0;
224 ret=i2c_master_send(c,buf,1);
225 i2c_master_recv(c,buf,21);
226
227 buf[0]=0;
228 ret=mt2032_compute_freq(c,rfin,if1,if2,from,to,&buf[1],&sel,t->xogc);
229 if (ret<0)
230 return;
231
232 // send only the relevant registers per Rev. 1.2
233 buf[0]=0;
234 ret=i2c_master_send(c,buf,4);
235 buf[5]=5;
236 ret=i2c_master_send(c,buf+5,4);
237 buf[11]=11;
238 ret=i2c_master_send(c,buf+11,3);
239 if(ret!=3)
240 tuner_warn("i2c i/o error: rc == %d (should be 3)\n",ret);
241
242 // wait for PLLs to lock (per manual), retry LINT if not.
243 for(lint_try=0; lint_try<2; lint_try++) {
244 lock=mt2032_check_lo_lock(c);
245
246 if(optimize_vco)
247 lock=mt2032_optimize_vco(c,sel,lock);
248 if(lock==6) break;
249
250 tuner_dbg("mt2032: re-init PLLs by LINT\n");
251 buf[0]=7;
252 buf[1]=0x80 +8+t->xogc; // set LINT to re-init PLLs
253 i2c_master_send(c,buf,2);
254 mdelay(10);
255 buf[1]=8+t->xogc;
256 i2c_master_send(c,buf,2);
257 }
258
259 if (lock!=6)
260 tuner_warn("MT2032 Fatal Error: PLLs didn't lock.\n");
261
262 buf[0]=2;
263 buf[1]=0x20; // LOGC for optimal phase noise
264 ret=i2c_master_send(c,buf,2);
265 if (ret!=2)
266 tuner_warn("i2c i/o error: rc == %d (should be 2)\n",ret);
267}
268
269
270static void mt2032_set_tv_freq(struct i2c_client *c, unsigned int freq)
271{
272 struct tuner *t = i2c_get_clientdata(c);
273 int if2,from,to;
274
275 // signal bandwidth and picture carrier
276 if (t->std & V4L2_STD_525_60) {
277 // NTSC
278 from = 40750*1000;
279 to = 46750*1000;
280 if2 = 45750*1000;
281 } else {
282 // PAL
283 from = 32900*1000;
284 to = 39900*1000;
285 if2 = 38900*1000;
286 }
287
288 mt2032_set_if_freq(c, freq*62500 /* freq*1000*1000/16 */,
289 1090*1000*1000, if2, from, to);
290}
291
292static void mt2032_set_radio_freq(struct i2c_client *c, unsigned int freq)
293{
294 struct tuner *t = i2c_get_clientdata(c);
295 int if2 = t->radio_if2;
296
297 // per Manual for FM tuning: first if center freq. 1085 MHz
298 mt2032_set_if_freq(c, freq*62500 /* freq*1000*1000/16 */,
299 1085*1000*1000,if2,if2,if2);
300}
301
302// Initalization as described in "MT203x Programming Procedures", Rev 1.2, Feb.2001
303static int mt2032_init(struct i2c_client *c)
304{
305 struct tuner *t = i2c_get_clientdata(c);
306 unsigned char buf[21];
307 int ret,xogc,xok=0;
308
309 // Initialize Registers per spec.
310 buf[1]=2; // Index to register 2
311 buf[2]=0xff;
312 buf[3]=0x0f;
313 buf[4]=0x1f;
314 ret=i2c_master_send(c,buf+1,4);
315
316 buf[5]=6; // Index register 6
317 buf[6]=0xe4;
318 buf[7]=0x8f;
319 buf[8]=0xc3;
320 buf[9]=0x4e;
321 buf[10]=0xec;
322 ret=i2c_master_send(c,buf+5,6);
323
324 buf[12]=13; // Index register 13
325 buf[13]=0x32;
326 ret=i2c_master_send(c,buf+12,2);
327
328 // Adjust XOGC (register 7), wait for XOK
329 xogc=7;
330 do {
331 tuner_dbg("mt2032: xogc = 0x%02x\n",xogc&0x07);
332 mdelay(10);
333 buf[0]=0x0e;
334 i2c_master_send(c,buf,1);
335 i2c_master_recv(c,buf,1);
336 xok=buf[0]&0x01;
337 tuner_dbg("mt2032: xok = 0x%02x\n",xok);
338 if (xok == 1) break;
339
340 xogc--;
341 tuner_dbg("mt2032: xogc = 0x%02x\n",xogc&0x07);
342 if (xogc == 3) {
343 xogc=4; // min. 4 per spec
344 break;
345 }
346 buf[0]=0x07;
347 buf[1]=0x88 + xogc;
348 ret=i2c_master_send(c,buf,2);
349 if (ret!=2)
350 tuner_warn("i2c i/o error: rc == %d (should be 2)\n",ret);
351 } while (xok != 1 );
352 t->xogc=xogc;
353
354 t->tv_freq = mt2032_set_tv_freq;
355 t->radio_freq = mt2032_set_radio_freq;
356 return(1);
357}
358
359static void mt2050_set_antenna(struct i2c_client *c, unsigned char antenna)
360{
361 struct tuner *t = i2c_get_clientdata(c);
362 unsigned char buf[2];
363 int ret;
364
365 buf[0] = 6;
366 buf[1] = antenna ? 0x11 : 0x10;
367 ret=i2c_master_send(c,buf,2);
368 tuner_dbg("mt2050: enabled antenna connector %d\n", antenna);
369}
370
371static void mt2050_set_if_freq(struct i2c_client *c,unsigned int freq, unsigned int if2)
372{
373 struct tuner *t = i2c_get_clientdata(c);
374 unsigned int if1=1218*1000*1000;
375 unsigned int f_lo1,f_lo2,lo1,lo2,f_lo1_modulo,f_lo2_modulo,num1,num2,div1a,div1b,div2a,div2b;
376 int ret;
377 unsigned char buf[6];
378
379 tuner_dbg("mt2050_set_if_freq freq=%d if1=%d if2=%d\n",
380 freq,if1,if2);
381
382 f_lo1=freq+if1;
383 f_lo1=(f_lo1/1000000)*1000000;
384
385 f_lo2=f_lo1-freq-if2;
386 f_lo2=(f_lo2/50000)*50000;
387
388 lo1=f_lo1/4000000;
389 lo2=f_lo2/4000000;
390
391 f_lo1_modulo= f_lo1-(lo1*4000000);
392 f_lo2_modulo= f_lo2-(lo2*4000000);
393
394 num1=4*f_lo1_modulo/4000000;
395 num2=4096*(f_lo2_modulo/1000)/4000;
396
397 // todo spurchecks
398
399 div1a=(lo1/12)-1;
400 div1b=lo1-(div1a+1)*12;
401
402 div2a=(lo2/8)-1;
403 div2b=lo2-(div2a+1)*8;
404
405 if (tuner_debug > 1) {
406 tuner_dbg("lo1 lo2 = %d %d\n", lo1, lo2);
407 tuner_dbg("num1 num2 div1a div1b div2a div2b= %x %x %x %x %x %x\n",
408 num1,num2,div1a,div1b,div2a,div2b);
409 }
410
411 buf[0]=1;
412 buf[1]= 4*div1b + num1;
413 if(freq<275*1000*1000) buf[1] = buf[1]|0x80;
414
415 buf[2]=div1a;
416 buf[3]=32*div2b + num2/256;
417 buf[4]=num2-(num2/256)*256;
418 buf[5]=div2a;
419 if(num2!=0) buf[5]=buf[5]|0x40;
420
421 if (tuner_debug > 1) {
422 int i;
423 tuner_dbg("bufs is: ");
424 for(i=0;i<6;i++)
425 printk("%x ",buf[i]);
426 printk("\n");
427 }
428
429 ret=i2c_master_send(c,buf,6);
430 if (ret!=6)
431 tuner_warn("i2c i/o error: rc == %d (should be 6)\n",ret);
432}
433
434static void mt2050_set_tv_freq(struct i2c_client *c, unsigned int freq)
435{
436 struct tuner *t = i2c_get_clientdata(c);
437 unsigned int if2;
438
439 if (t->std & V4L2_STD_525_60) {
440 // NTSC
441 if2 = 45750*1000;
442 } else {
443 // PAL
444 if2 = 38900*1000;
445 }
446 if (V4L2_TUNER_DIGITAL_TV == t->mode) {
447 // DVB (pinnacle 300i)
448 if2 = 36150*1000;
449 }
450 mt2050_set_if_freq(c, freq*62500, if2);
451 mt2050_set_antenna(c, tv_antenna);
452}
453
454static void mt2050_set_radio_freq(struct i2c_client *c, unsigned int freq)
455{
456 struct tuner *t = i2c_get_clientdata(c);
457 int if2 = t->radio_if2;
458
459 mt2050_set_if_freq(c, freq*62500, if2);
460 mt2050_set_antenna(c, radio_antenna);
461}
462
463static int mt2050_init(struct i2c_client *c)
464{
465 struct tuner *t = i2c_get_clientdata(c);
466 unsigned char buf[2];
467 int ret;
468
469 buf[0]=6;
470 buf[1]=0x10;
471 ret=i2c_master_send(c,buf,2); // power
472
473 buf[0]=0x0f;
474 buf[1]=0x0f;
475 ret=i2c_master_send(c,buf,2); // m1lo
476
477 buf[0]=0x0d;
478 ret=i2c_master_send(c,buf,1);
479 i2c_master_recv(c,buf,1);
480
481 tuner_dbg("mt2050: sro is %x\n",buf[0]);
482 t->tv_freq = mt2050_set_tv_freq;
483 t->radio_freq = mt2050_set_radio_freq;
484 return 0;
485}
486
487int microtune_init(struct i2c_client *c)
488{
489 struct tuner *t = i2c_get_clientdata(c);
490 char *name;
491 unsigned char buf[21];
492 int company_code;
493
494 memset(buf,0,sizeof(buf));
495 t->tv_freq = NULL;
496 t->radio_freq = NULL;
497 name = "unknown";
498
499 i2c_master_send(c,buf,1);
500 i2c_master_recv(c,buf,21);
501 if (tuner_debug) {
502 int i;
503 tuner_dbg("MT20xx hexdump:");
504 for(i=0;i<21;i++) {
505 printk(" %02x",buf[i]);
506 if(((i+1)%8)==0) printk(" ");
507 }
508 printk("\n");
509 }
510 company_code = buf[0x11] << 8 | buf[0x12];
511 tuner_info("microtune: companycode=%04x part=%02x rev=%02x\n",
512 company_code,buf[0x13],buf[0x14]);
513
514#if 0
515 /* seems to cause more problems than it solves ... */
516 switch (company_code) {
517 case 0x30bf:
518 case 0x3cbf:
519 case 0x3dbf:
520 case 0x4d54:
521 case 0x8e81:
522 case 0x8e91:
523 /* ok (?) */
524 break;
525 default:
526 tuner_warn("tuner: microtune: unknown companycode\n");
527 return 0;
528 }
529#endif
530
531 if (buf[0x13] < ARRAY_SIZE(microtune_part) &&
532 NULL != microtune_part[buf[0x13]])
533 name = microtune_part[buf[0x13]];
534 switch (buf[0x13]) {
535 case MT2032:
536 mt2032_init(c);
537 break;
538 case MT2050:
539 mt2050_init(c);
540 break;
541 default:
542 tuner_info("microtune %s found, not (yet?) supported, sorry :-/\n",
543 name);
544 return 0;
545 }
546
547 strlcpy(c->name, name, sizeof(c->name));
548 tuner_info("microtune %s found, OK\n",name);
549 return 0;
550}
551
552/*
553 * Overrides for Emacs so that we follow Linus's tabbing style.
554 * ---------------------------------------------------------------------------
555 * Local variables:
556 * c-basic-offset: 8
557 * End:
558 */
diff --git a/drivers/media/video/mxb.c b/drivers/media/video/mxb.c
new file mode 100644
index 00000000000..70bf1f1fad5
--- /dev/null
+++ b/drivers/media/video/mxb.c
@@ -0,0 +1,1035 @@
1/*
2 mxb - v4l2 driver for the Multimedia eXtension Board
3
4 Copyright (C) 1998-2003 Michael Hunold <michael@mihu.de>
5
6 Visit http://www.mihu.de/linux/saa7146/mxb/
7 for further details about this card.
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 DEBUG_VARIABLE debug
25
26#include <media/saa7146_vv.h>
27#include <media/tuner.h>
28#include <linux/video_decoder.h>
29
30#include "mxb.h"
31#include "tea6415c.h"
32#include "tea6420.h"
33#include "tda9840.h"
34
35#define I2C_SAA7111 0x24
36
37#define MXB_BOARD_CAN_DO_VBI(dev) (dev->revision != 0)
38
39/* global variable */
40static int mxb_num = 0;
41
42/* initial frequence the tuner will be tuned to.
43 in verden (lower saxony, germany) 4148 is a
44 channel called "phoenix" */
45static int freq = 4148;
46module_param(freq, int, 0644);
47MODULE_PARM_DESC(freq, "initial frequency the tuner will be tuned to while setup");
48
49static int debug = 0;
50module_param(debug, int, 0644);
51MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off).");
52
53#define MXB_INPUTS 4
54enum { TUNER, AUX1, AUX3, AUX3_YC };
55
56static struct v4l2_input mxb_inputs[MXB_INPUTS] = {
57 { TUNER, "Tuner", V4L2_INPUT_TYPE_TUNER, 1, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
58 { AUX1, "AUX1", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
59 { AUX3, "AUX3 Composite", V4L2_INPUT_TYPE_CAMERA, 4, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
60 { AUX3_YC, "AUX3 S-Video", V4L2_INPUT_TYPE_CAMERA, 4, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
61};
62
63/* this array holds the information, which port of the saa7146 each
64 input actually uses. the mxb uses port 0 for every input */
65static struct {
66 int hps_source;
67 int hps_sync;
68} input_port_selection[MXB_INPUTS] = {
69 { SAA7146_HPS_SOURCE_PORT_A, SAA7146_HPS_SYNC_PORT_A },
70 { SAA7146_HPS_SOURCE_PORT_A, SAA7146_HPS_SYNC_PORT_A },
71 { SAA7146_HPS_SOURCE_PORT_A, SAA7146_HPS_SYNC_PORT_A },
72 { SAA7146_HPS_SOURCE_PORT_A, SAA7146_HPS_SYNC_PORT_A },
73};
74
75/* this array holds the information of the audio source (mxb_audios),
76 which has to be switched corresponding to the video source (mxb_channels) */
77static int video_audio_connect[MXB_INPUTS] =
78 { 0, 1, 3, 3 };
79
80/* these are the necessary input-output-pins for bringing one audio source
81(see above) to the CD-output */
82static struct tea6420_multiplex TEA6420_cd[MXB_AUDIOS+1][2] =
83 {
84 {{1,1,0},{1,1,0}}, /* Tuner */
85 {{5,1,0},{6,1,0}}, /* AUX 1 */
86 {{4,1,0},{6,1,0}}, /* AUX 2 */
87 {{3,1,0},{6,1,0}}, /* AUX 3 */
88 {{1,1,0},{3,1,0}}, /* Radio */
89 {{1,1,0},{2,1,0}}, /* CD-Rom */
90 {{6,1,0},{6,1,0}} /* Mute */
91 };
92
93/* these are the necessary input-output-pins for bringing one audio source
94(see above) to the line-output */
95static struct tea6420_multiplex TEA6420_line[MXB_AUDIOS+1][2] =
96 {
97 {{2,3,0},{1,2,0}},
98 {{5,3,0},{6,2,0}},
99 {{4,3,0},{6,2,0}},
100 {{3,3,0},{6,2,0}},
101 {{2,3,0},{3,2,0}},
102 {{2,3,0},{2,2,0}},
103 {{6,3,0},{6,2,0}} /* Mute */
104 };
105
106#define MAXCONTROLS 1
107static struct v4l2_queryctrl mxb_controls[] = {
108 { V4L2_CID_AUDIO_MUTE, V4L2_CTRL_TYPE_BOOLEAN, "Mute", 0, 1, 1, 0, 0 },
109};
110
111static struct saa7146_extension_ioctls ioctls[] = {
112 { VIDIOC_ENUMINPUT, SAA7146_EXCLUSIVE },
113 { VIDIOC_G_INPUT, SAA7146_EXCLUSIVE },
114 { VIDIOC_S_INPUT, SAA7146_EXCLUSIVE },
115 { VIDIOC_QUERYCTRL, SAA7146_BEFORE },
116 { VIDIOC_G_CTRL, SAA7146_BEFORE },
117 { VIDIOC_S_CTRL, SAA7146_BEFORE },
118 { VIDIOC_G_TUNER, SAA7146_EXCLUSIVE },
119 { VIDIOC_S_TUNER, SAA7146_EXCLUSIVE },
120 { VIDIOC_G_FREQUENCY, SAA7146_EXCLUSIVE },
121 { VIDIOC_S_FREQUENCY, SAA7146_EXCLUSIVE },
122 { VIDIOC_G_AUDIO, SAA7146_EXCLUSIVE },
123 { VIDIOC_S_AUDIO, SAA7146_EXCLUSIVE },
124 { MXB_S_AUDIO_CD, SAA7146_EXCLUSIVE }, /* custom control */
125 { MXB_S_AUDIO_LINE, SAA7146_EXCLUSIVE }, /* custom control */
126 { 0, 0 }
127};
128
129struct mxb
130{
131 struct video_device *video_dev;
132 struct video_device *vbi_dev;
133
134 struct i2c_adapter i2c_adapter;
135
136 struct i2c_client* saa7111a;
137 struct i2c_client* tda9840;
138 struct i2c_client* tea6415c;
139 struct i2c_client* tuner;
140 struct i2c_client* tea6420_1;
141 struct i2c_client* tea6420_2;
142
143 int cur_mode; /* current audio mode (mono, stereo, ...) */
144 int cur_input; /* current input */
145 int cur_freq; /* current frequency the tuner is tuned to */
146 int cur_mute; /* current mute status */
147};
148
149static struct saa7146_extension extension;
150
151static int mxb_probe(struct saa7146_dev* dev)
152{
153 struct mxb* mxb = NULL;
154 struct i2c_client *client;
155 struct list_head *item;
156 int result;
157
158 if ((result = request_module("saa7111")) < 0) {
159 printk("mxb: saa7111 i2c module not available.\n");
160 return -ENODEV;
161 }
162 if ((result = request_module("tuner")) < 0) {
163 printk("mxb: tuner i2c module not available.\n");
164 return -ENODEV;
165 }
166 if ((result = request_module("tea6420")) < 0) {
167 printk("mxb: tea6420 i2c module not available.\n");
168 return -ENODEV;
169 }
170 if ((result = request_module("tea6415c")) < 0) {
171 printk("mxb: tea6415c i2c module not available.\n");
172 return -ENODEV;
173 }
174 if ((result = request_module("tda9840")) < 0) {
175 printk("mxb: tda9840 i2c module not available.\n");
176 return -ENODEV;
177 }
178
179 mxb = (struct mxb*)kmalloc(sizeof(struct mxb), GFP_KERNEL);
180 if( NULL == mxb ) {
181 DEB_D(("not enough kernel memory.\n"));
182 return -ENOMEM;
183 }
184 memset(mxb, 0x0, sizeof(struct mxb));
185
186 mxb->i2c_adapter = (struct i2c_adapter) {
187 .class = I2C_CLASS_TV_ANALOG,
188 .name = "mxb",
189 };
190
191 saa7146_i2c_adapter_prepare(dev, &mxb->i2c_adapter, SAA7146_I2C_BUS_BIT_RATE_480);
192 if(i2c_add_adapter(&mxb->i2c_adapter) < 0) {
193 DEB_S(("cannot register i2c-device. skipping.\n"));
194 kfree(mxb);
195 return -EFAULT;
196 }
197
198 /* loop through all i2c-devices on the bus and look who is there */
199 list_for_each(item,&mxb->i2c_adapter.clients) {
200 client = list_entry(item, struct i2c_client, list);
201 if( I2C_TEA6420_1 == client->addr )
202 mxb->tea6420_1 = client;
203 if( I2C_TEA6420_2 == client->addr )
204 mxb->tea6420_2 = client;
205 if( I2C_TEA6415C_2 == client->addr )
206 mxb->tea6415c = client;
207 if( I2C_TDA9840 == client->addr )
208 mxb->tda9840 = client;
209 if( I2C_SAA7111 == client->addr )
210 mxb->saa7111a = client;
211 if( 0x60 == client->addr )
212 mxb->tuner = client;
213 }
214
215 /* check if all devices are present */
216 if( 0 == mxb->tea6420_1 || 0 == mxb->tea6420_2 || 0 == mxb->tea6415c
217 || 0 == mxb->tda9840 || 0 == mxb->saa7111a || 0 == mxb->tuner ) {
218
219 printk("mxb: did not find all i2c devices. aborting\n");
220 i2c_del_adapter(&mxb->i2c_adapter);
221 kfree(mxb);
222 return -ENODEV;
223 }
224
225 /* all devices are present, probe was successful */
226
227 /* we store the pointer in our private data field */
228 dev->ext_priv = mxb;
229
230 return 0;
231}
232
233/* some init data for the saa7740, the so-called 'sound arena module'.
234 there are no specs available, so we simply use some init values */
235static struct {
236 int length;
237 char data[9];
238} mxb_saa7740_init[] = {
239 { 3, { 0x80, 0x00, 0x00 } },{ 3, { 0x80, 0x89, 0x00 } },
240 { 3, { 0x80, 0xb0, 0x0a } },{ 3, { 0x00, 0x00, 0x00 } },
241 { 3, { 0x49, 0x00, 0x00 } },{ 3, { 0x4a, 0x00, 0x00 } },
242 { 3, { 0x4b, 0x00, 0x00 } },{ 3, { 0x4c, 0x00, 0x00 } },
243 { 3, { 0x4d, 0x00, 0x00 } },{ 3, { 0x4e, 0x00, 0x00 } },
244 { 3, { 0x4f, 0x00, 0x00 } },{ 3, { 0x50, 0x00, 0x00 } },
245 { 3, { 0x51, 0x00, 0x00 } },{ 3, { 0x52, 0x00, 0x00 } },
246 { 3, { 0x53, 0x00, 0x00 } },{ 3, { 0x54, 0x00, 0x00 } },
247 { 3, { 0x55, 0x00, 0x00 } },{ 3, { 0x56, 0x00, 0x00 } },
248 { 3, { 0x57, 0x00, 0x00 } },{ 3, { 0x58, 0x00, 0x00 } },
249 { 3, { 0x59, 0x00, 0x00 } },{ 3, { 0x5a, 0x00, 0x00 } },
250 { 3, { 0x5b, 0x00, 0x00 } },{ 3, { 0x5c, 0x00, 0x00 } },
251 { 3, { 0x5d, 0x00, 0x00 } },{ 3, { 0x5e, 0x00, 0x00 } },
252 { 3, { 0x5f, 0x00, 0x00 } },{ 3, { 0x60, 0x00, 0x00 } },
253 { 3, { 0x61, 0x00, 0x00 } },{ 3, { 0x62, 0x00, 0x00 } },
254 { 3, { 0x63, 0x00, 0x00 } },{ 3, { 0x64, 0x00, 0x00 } },
255 { 3, { 0x65, 0x00, 0x00 } },{ 3, { 0x66, 0x00, 0x00 } },
256 { 3, { 0x67, 0x00, 0x00 } },{ 3, { 0x68, 0x00, 0x00 } },
257 { 3, { 0x69, 0x00, 0x00 } },{ 3, { 0x6a, 0x00, 0x00 } },
258 { 3, { 0x6b, 0x00, 0x00 } },{ 3, { 0x6c, 0x00, 0x00 } },
259 { 3, { 0x6d, 0x00, 0x00 } },{ 3, { 0x6e, 0x00, 0x00 } },
260 { 3, { 0x6f, 0x00, 0x00 } },{ 3, { 0x70, 0x00, 0x00 } },
261 { 3, { 0x71, 0x00, 0x00 } },{ 3, { 0x72, 0x00, 0x00 } },
262 { 3, { 0x73, 0x00, 0x00 } },{ 3, { 0x74, 0x00, 0x00 } },
263 { 3, { 0x75, 0x00, 0x00 } },{ 3, { 0x76, 0x00, 0x00 } },
264 { 3, { 0x77, 0x00, 0x00 } },{ 3, { 0x41, 0x00, 0x42 } },
265 { 3, { 0x42, 0x10, 0x42 } },{ 3, { 0x43, 0x20, 0x42 } },
266 { 3, { 0x44, 0x30, 0x42 } },{ 3, { 0x45, 0x00, 0x01 } },
267 { 3, { 0x46, 0x00, 0x01 } },{ 3, { 0x47, 0x00, 0x01 } },
268 { 3, { 0x48, 0x00, 0x01 } },
269 { 9, { 0x01, 0x03, 0xc5, 0x5c, 0x7a, 0x85, 0x01, 0x00, 0x54 } },
270 { 9, { 0x21, 0x03, 0xc5, 0x5c, 0x7a, 0x85, 0x01, 0x00, 0x54 } },
271 { 9, { 0x09, 0x0b, 0xb4, 0x6b, 0x74, 0x85, 0x95, 0x00, 0x34 } },
272 { 9, { 0x29, 0x0b, 0xb4, 0x6b, 0x74, 0x85, 0x95, 0x00, 0x34 } },
273 { 9, { 0x11, 0x17, 0x43, 0x62, 0x68, 0x89, 0xd1, 0xff, 0xb0 } },
274 { 9, { 0x31, 0x17, 0x43, 0x62, 0x68, 0x89, 0xd1, 0xff, 0xb0 } },
275 { 9, { 0x19, 0x20, 0x62, 0x51, 0x5a, 0x95, 0x19, 0x01, 0x50 } },
276 { 9, { 0x39, 0x20, 0x62, 0x51, 0x5a, 0x95, 0x19, 0x01, 0x50 } },
277 { 9, { 0x05, 0x3e, 0xd2, 0x69, 0x4e, 0x9a, 0x51, 0x00, 0xf0 } },
278 { 9, { 0x25, 0x3e, 0xd2, 0x69, 0x4e, 0x9a, 0x51, 0x00, 0xf0 } },
279 { 9, { 0x0d, 0x3d, 0xa1, 0x40, 0x7d, 0x9f, 0x29, 0xfe, 0x14 } },
280 { 9, { 0x2d, 0x3d, 0xa1, 0x40, 0x7d, 0x9f, 0x29, 0xfe, 0x14 } },
281 { 9, { 0x15, 0x73, 0xa1, 0x50, 0x5d, 0xa6, 0xf5, 0xfe, 0x38 } },
282 { 9, { 0x35, 0x73, 0xa1, 0x50, 0x5d, 0xa6, 0xf5, 0xfe, 0x38 } },
283 { 9, { 0x1d, 0xed, 0xd0, 0x68, 0x29, 0xb4, 0xe1, 0x00, 0xb8 } },
284 { 9, { 0x3d, 0xed, 0xd0, 0x68, 0x29, 0xb4, 0xe1, 0x00, 0xb8 } },
285 { 3, { 0x80, 0xb3, 0x0a } },
286 {-1, { 0} }
287};
288
289static const unsigned char mxb_saa7111_init[] = {
290 0x00, 0x00, /* 00 - ID byte */
291 0x01, 0x00, /* 01 - reserved */
292
293 /*front end */
294 0x02, 0xd8, /* 02 - FUSE=x, GUDL=x, MODE=x */
295 0x03, 0x23, /* 03 - HLNRS=0, VBSL=1, WPOFF=0, HOLDG=0, GAFIX=0, GAI1=256, GAI2=256 */
296 0x04, 0x00, /* 04 - GAI1=256 */
297 0x05, 0x00, /* 05 - GAI2=256 */
298
299 /* decoder */
300 0x06, 0xf0, /* 06 - HSB at xx(50Hz) / xx(60Hz) pixels after end of last line */
301 0x07, 0x30, /* 07 - HSS at xx(50Hz) / xx(60Hz) pixels after end of last line */
302 0x08, 0xa8, /* 08 - AUFD=x, FSEL=x, EXFIL=x, VTRC=x, HPLL=x, VNOI=x */
303 0x09, 0x02, /* 09 - BYPS=x, PREF=x, BPSS=x, VBLB=x, UPTCV=x, APER=x */
304 0x0a, 0x80, /* 0a - BRIG=128 */
305 0x0b, 0x47, /* 0b - CONT=1.109 */
306 0x0c, 0x40, /* 0c - SATN=1.0 */
307 0x0d, 0x00, /* 0d - HUE=0 */
308 0x0e, 0x01, /* 0e - CDTO=0, CSTD=0, DCCF=0, FCTC=0, CHBW=1 */
309 0x0f, 0x00, /* 0f - reserved */
310 0x10, 0xd0, /* 10 - OFTS=x, HDEL=x, VRLN=x, YDEL=x */
311 0x11, 0x8c, /* 11 - GPSW=x, CM99=x, FECO=x, COMPO=x, OEYC=1, OEHV=1, VIPB=0, COLO=0 */
312 0x12, 0x80, /* 12 - xx output control 2 */
313 0x13, 0x30, /* 13 - xx output control 3 */
314 0x14, 0x00, /* 14 - reserved */
315 0x15, 0x15, /* 15 - VBI */
316 0x16, 0x04, /* 16 - VBI */
317 0x17, 0x00, /* 17 - VBI */
318};
319
320/* bring hardware to a sane state. this has to be done, just in case someone
321 wants to capture from this device before it has been properly initialized.
322 the capture engine would badly fail, because no valid signal arrives on the
323 saa7146, thus leading to timeouts and stuff. */
324static int mxb_init_done(struct saa7146_dev* dev)
325{
326 struct mxb* mxb = (struct mxb*)dev->ext_priv;
327 struct video_decoder_init init;
328 struct i2c_msg msg;
329
330 int i = 0, err = 0;
331 struct tea6415c_multiplex vm;
332
333 /* select video mode in saa7111a */
334 i = VIDEO_MODE_PAL;
335 /* fixme: currently pointless: gets overwritten by configuration below */
336 mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_NORM, &i);
337
338 /* write configuration to saa7111a */
339 init.data = mxb_saa7111_init;
340 init.len = sizeof(mxb_saa7111_init);
341 mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_INIT, &init);
342
343 /* select tuner-output on saa7111a */
344 i = 0;
345 mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_INPUT, &i);
346
347 /* enable vbi bypass */
348 i = 1;
349 mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_VBI_BYPASS, &i);
350
351 /* select a tuner type */
352 i = 5;
353 mxb->tuner->driver->command(mxb->tuner,TUNER_SET_TYPE, &i);
354
355 /* mute audio on tea6420s */
356 mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_line[6][0]);
357 mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_line[6][1]);
358 mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_cd[6][0]);
359 mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_cd[6][1]);
360
361 /* switch to tuner-channel on tea6415c*/
362 vm.out = 17;
363 vm.in = 3;
364 mxb->tea6415c->driver->command(mxb->tea6415c,TEA6415C_SWITCH, &vm);
365
366 /* select tuner-output on multicable on tea6415c*/
367 vm.in = 3;
368 vm.out = 13;
369 mxb->tea6415c->driver->command(mxb->tea6415c,TEA6415C_SWITCH, &vm);
370
371 /* tune in some frequency on tuner */
372 mxb->tuner->driver->command(mxb->tuner, VIDIOCSFREQ, &freq);
373
374 /* the rest for mxb */
375 mxb->cur_input = 0;
376 mxb->cur_freq = freq;
377 mxb->cur_mute = 1;
378
379 mxb->cur_mode = V4L2_TUNER_MODE_STEREO;
380 mxb->tda9840->driver->command(mxb->tda9840, TDA9840_SWITCH, &mxb->cur_mode);
381
382 /* check if the saa7740 (aka 'sound arena module') is present
383 on the mxb. if so, we must initialize it. due to lack of
384 informations about the saa7740, the values were reverse
385 engineered. */
386 msg.addr = 0x1b;
387 msg.flags = 0;
388 msg.len = mxb_saa7740_init[0].length;
389 msg.buf = &mxb_saa7740_init[0].data[0];
390
391 if( 1 == (err = i2c_transfer(&mxb->i2c_adapter, &msg, 1))) {
392 /* the sound arena module is a pos, that's probably the reason
393 philips refuses to hand out a datasheet for the saa7740...
394 it seems to screw up the i2c bus, so we disable fast irq
395 based i2c transactions here and rely on the slow and safe
396 polling method ... */
397 extension.flags &= ~SAA7146_USE_I2C_IRQ;
398 for(i = 1;;i++) {
399 if( -1 == mxb_saa7740_init[i].length ) {
400 break;
401 }
402
403 msg.len = mxb_saa7740_init[i].length;
404 msg.buf = &mxb_saa7740_init[i].data[0];
405 if( 1 != (err = i2c_transfer(&mxb->i2c_adapter, &msg, 1))) {
406 DEB_D(("failed to initialize 'sound arena module'.\n"));
407 goto err;
408 }
409 }
410 INFO(("'sound arena module' detected.\n"));
411 }
412err:
413 /* the rest for saa7146: you should definitely set some basic values
414 for the input-port handling of the saa7146. */
415
416 /* ext->saa has been filled by the core driver */
417
418 /* some stuff is done via variables */
419 saa7146_set_hps_source_and_sync(dev, input_port_selection[mxb->cur_input].hps_source, input_port_selection[mxb->cur_input].hps_sync);
420
421 /* some stuff is done via direct write to the registers */
422
423 /* this is ugly, but because of the fact that this is completely
424 hardware dependend, it should be done directly... */
425 saa7146_write(dev, DD1_STREAM_B, 0x00000000);
426 saa7146_write(dev, DD1_INIT, 0x02000200);
427 saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
428
429 return 0;
430}
431
432/* interrupt-handler. this gets called when irq_mask is != 0.
433 it must clear the interrupt-bits in irq_mask it has handled */
434/*
435void mxb_irq_bh(struct saa7146_dev* dev, u32* irq_mask)
436{
437 struct mxb* mxb = (struct mxb*)dev->ext_priv;
438}
439*/
440
441static struct saa7146_ext_vv vv_data;
442
443/* this function only gets called when the probing was successful */
444static int mxb_attach(struct saa7146_dev* dev, struct saa7146_pci_extension_data *info)
445{
446 struct mxb* mxb = (struct mxb*)dev->ext_priv;
447
448 DEB_EE(("dev:%p\n",dev));
449
450 /* checking for i2c-devices can be omitted here, because we
451 already did this in "mxb_vl42_probe" */
452
453 saa7146_vv_init(dev,&vv_data);
454 if( 0 != saa7146_register_device(&mxb->video_dev, dev, "mxb", VFL_TYPE_GRABBER)) {
455 ERR(("cannot register capture v4l2 device. skipping.\n"));
456 return -1;
457 }
458
459 /* initialization stuff (vbi) (only for revision > 0 and for extensions which want it)*/
460 if( 0 != MXB_BOARD_CAN_DO_VBI(dev)) {
461 if( 0 != saa7146_register_device(&mxb->vbi_dev, dev, "mxb", VFL_TYPE_VBI)) {
462 ERR(("cannot register vbi v4l2 device. skipping.\n"));
463 }
464 }
465
466 i2c_use_client(mxb->tea6420_1);
467 i2c_use_client(mxb->tea6420_2);
468 i2c_use_client(mxb->tea6415c);
469 i2c_use_client(mxb->tda9840);
470 i2c_use_client(mxb->saa7111a);
471 i2c_use_client(mxb->tuner);
472
473 printk("mxb: found 'Multimedia eXtension Board'-%d.\n",mxb_num);
474
475 mxb_num++;
476 mxb_init_done(dev);
477 return 0;
478}
479
480static int mxb_detach(struct saa7146_dev* dev)
481{
482 struct mxb* mxb = (struct mxb*)dev->ext_priv;
483
484 DEB_EE(("dev:%p\n",dev));
485
486 i2c_release_client(mxb->tea6420_1);
487 i2c_release_client(mxb->tea6420_2);
488 i2c_release_client(mxb->tea6415c);
489 i2c_release_client(mxb->tda9840);
490 i2c_release_client(mxb->saa7111a);
491 i2c_release_client(mxb->tuner);
492
493 saa7146_unregister_device(&mxb->video_dev,dev);
494 if( 0 != MXB_BOARD_CAN_DO_VBI(dev)) {
495 saa7146_unregister_device(&mxb->vbi_dev,dev);
496 }
497 saa7146_vv_release(dev);
498
499 mxb_num--;
500
501 i2c_del_adapter(&mxb->i2c_adapter);
502 kfree(mxb);
503
504 return 0;
505}
506
507static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
508{
509 struct saa7146_dev *dev = fh->dev;
510 struct mxb* mxb = (struct mxb*)dev->ext_priv;
511 struct saa7146_vv *vv = dev->vv_data;
512
513 switch(cmd) {
514 case VIDIOC_ENUMINPUT:
515 {
516 struct v4l2_input *i = arg;
517
518 DEB_EE(("VIDIOC_ENUMINPUT %d.\n",i->index));
519 if( i->index < 0 || i->index >= MXB_INPUTS) {
520 return -EINVAL;
521 }
522 memcpy(i, &mxb_inputs[i->index], sizeof(struct v4l2_input));
523
524 return 0;
525 }
526 /* the saa7146 provides some controls (brightness, contrast, saturation)
527 which gets registered *after* this function. because of this we have
528 to return with a value != 0 even if the function succeded.. */
529 case VIDIOC_QUERYCTRL:
530 {
531 struct v4l2_queryctrl *qc = arg;
532 int i;
533
534 for (i = MAXCONTROLS - 1; i >= 0; i--) {
535 if (mxb_controls[i].id == qc->id) {
536 *qc = mxb_controls[i];
537 DEB_D(("VIDIOC_QUERYCTRL %d.\n",qc->id));
538 return 0;
539 }
540 }
541 return -EAGAIN;
542 }
543 case VIDIOC_G_CTRL:
544 {
545 struct v4l2_control *vc = arg;
546 int i;
547
548 for (i = MAXCONTROLS - 1; i >= 0; i--) {
549 if (mxb_controls[i].id == vc->id) {
550 break;
551 }
552 }
553
554 if( i < 0 ) {
555 return -EAGAIN;
556 }
557
558 switch (vc->id ) {
559 case V4L2_CID_AUDIO_MUTE: {
560 vc->value = mxb->cur_mute;
561 DEB_D(("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d.\n",vc->value));
562 return 0;
563 }
564 }
565
566 DEB_EE(("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d.\n",vc->value));
567 return 0;
568 }
569
570 case VIDIOC_S_CTRL:
571 {
572 struct v4l2_control *vc = arg;
573 int i = 0;
574
575 for (i = MAXCONTROLS - 1; i >= 0; i--) {
576 if (mxb_controls[i].id == vc->id) {
577 break;
578 }
579 }
580
581 if( i < 0 ) {
582 return -EAGAIN;
583 }
584
585 switch (vc->id ) {
586 case V4L2_CID_AUDIO_MUTE: {
587 mxb->cur_mute = vc->value;
588 if( 0 == vc->value ) {
589 /* switch the audio-source */
590 mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_line[video_audio_connect[mxb->cur_input]][0]);
591 mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_line[video_audio_connect[mxb->cur_input]][1]);
592 } else {
593 mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_line[6][0]);
594 mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_line[6][1]);
595 }
596 DEB_EE(("VIDIOC_S_CTRL, V4L2_CID_AUDIO_MUTE: %d.\n",vc->value));
597 break;
598 }
599 }
600 return 0;
601 }
602 case VIDIOC_G_INPUT:
603 {
604 int *input = (int *)arg;
605 *input = mxb->cur_input;
606
607 DEB_EE(("VIDIOC_G_INPUT %d.\n",*input));
608 return 0;
609 }
610 case VIDIOC_S_INPUT:
611 {
612 int input = *(int *)arg;
613 struct tea6415c_multiplex vm;
614 int i = 0;
615
616 DEB_EE(("VIDIOC_S_INPUT %d.\n",input));
617
618 if (input < 0 || input >= MXB_INPUTS) {
619 return -EINVAL;
620 }
621
622 /* fixme: locke das setzen des inputs mit hilfe des mutexes
623 down(&dev->lock);
624 video_mux(dev,*i);
625 up(&dev->lock);
626 */
627
628 /* fixme: check if streaming capture
629 if ( 0 != dev->streaming ) {
630 DEB_D(("VIDIOC_S_INPUT illegal while streaming.\n"));
631 return -EPERM;
632 }
633 */
634
635 mxb->cur_input = input;
636
637 saa7146_set_hps_source_and_sync(dev, input_port_selection[input].hps_source, input_port_selection[input].hps_sync);
638
639 /* prepare switching of tea6415c and saa7111a;
640 have a look at the 'background'-file for further informations */
641 switch( input ) {
642
643 case TUNER:
644 {
645 i = 0;
646 vm.in = 3;
647 vm.out = 17;
648
649 if ( 0 != mxb->tea6415c->driver->command(mxb->tea6415c,TEA6415C_SWITCH, &vm)) {
650 printk("VIDIOC_S_INPUT: could not address tea6415c #1\n");
651 return -EFAULT;
652 }
653 /* connect tuner-output always to multicable */
654 vm.in = 3;
655 vm.out = 13;
656 break;
657 }
658 case AUX3_YC:
659 {
660 /* nothing to be done here. aux3_yc is
661 directly connected to the saa711a */
662 i = 5;
663 break;
664 }
665 case AUX3:
666 {
667 /* nothing to be done here. aux3 is
668 directly connected to the saa711a */
669 i = 1;
670 break;
671 }
672 case AUX1:
673 {
674 i = 0;
675 vm.in = 1;
676 vm.out = 17;
677 break;
678 }
679 }
680
681 /* switch video in tea6415c only if necessary */
682 switch( input ) {
683 case TUNER:
684 case AUX1:
685 {
686 if ( 0 != mxb->tea6415c->driver->command(mxb->tea6415c,TEA6415C_SWITCH, &vm)) {
687 printk("VIDIOC_S_INPUT: could not address tea6415c #3\n");
688 return -EFAULT;
689 }
690 break;
691 }
692 default:
693 {
694 break;
695 }
696 }
697
698 /* switch video in saa7111a */
699 if ( 0 != mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_INPUT, &i)) {
700 printk("VIDIOC_S_INPUT: could not address saa7111a #1.\n");
701 }
702
703 /* switch the audio-source only if necessary */
704 if( 0 == mxb->cur_mute ) {
705 mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_line[video_audio_connect[input]][0]);
706 mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_line[video_audio_connect[input]][1]);
707 }
708
709 return 0;
710 }
711 case VIDIOC_G_TUNER:
712 {
713 struct v4l2_tuner *t = arg;
714 int byte = 0;
715
716 if( 0 != t->index ) {
717 DEB_D(("VIDIOC_G_TUNER: channel %d does not have a tuner attached.\n", t->index));
718 return -EINVAL;
719 }
720
721 DEB_EE(("VIDIOC_G_TUNER: %d\n", t->index));
722
723 memset(t,0,sizeof(*t));
724 strcpy(t->name, "Television");
725
726 t->type = V4L2_TUNER_ANALOG_TV;
727 t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
728 t->rangelow = 772; /* 48.25 MHZ / 62.5 kHz = 772, see fi1216mk2-specs, page 2 */
729 t->rangehigh = 13684; /* 855.25 MHz / 62.5 kHz = 13684 */
730 /* FIXME: add the real signal strength here */
731 t->signal = 0xffff;
732 t->afc = 0;
733
734 mxb->tda9840->driver->command(mxb->tda9840,TDA9840_DETECT, &byte);
735 t->audmode = mxb->cur_mode;
736
737 if( byte < 0 ) {
738 t->rxsubchans = V4L2_TUNER_SUB_MONO;
739 } else {
740 switch(byte) {
741 case TDA9840_MONO_DETECT: {
742 t->rxsubchans = V4L2_TUNER_SUB_MONO;
743 DEB_D(("VIDIOC_G_TUNER: V4L2_TUNER_MODE_MONO.\n"));
744 break;
745 }
746 case TDA9840_DUAL_DETECT: {
747 t->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
748 DEB_D(("VIDIOC_G_TUNER: V4L2_TUNER_MODE_LANG1.\n"));
749 break;
750 }
751 case TDA9840_STEREO_DETECT: {
752 t->rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO;
753 DEB_D(("VIDIOC_G_TUNER: V4L2_TUNER_MODE_STEREO.\n"));
754 break;
755 }
756 default: { /* TDA9840_INCORRECT_DETECT */
757 t->rxsubchans = V4L2_TUNER_MODE_MONO;
758 DEB_D(("VIDIOC_G_TUNER: TDA9840_INCORRECT_DETECT => V4L2_TUNER_MODE_MONO\n"));
759 break;
760 }
761 }
762 }
763
764 return 0;
765 }
766 case VIDIOC_S_TUNER:
767 {
768 struct v4l2_tuner *t = arg;
769 int result = 0;
770 int byte = 0;
771
772 if( 0 != t->index ) {
773 DEB_D(("VIDIOC_S_TUNER: channel %d does not have a tuner attached.\n",t->index));
774 return -EINVAL;
775 }
776
777 switch(t->audmode) {
778 case V4L2_TUNER_MODE_STEREO: {
779 mxb->cur_mode = V4L2_TUNER_MODE_STEREO;
780 byte = TDA9840_SET_STEREO;
781 DEB_D(("VIDIOC_S_TUNER: V4L2_TUNER_MODE_STEREO\n"));
782 break;
783 }
784 case V4L2_TUNER_MODE_LANG1: {
785 mxb->cur_mode = V4L2_TUNER_MODE_LANG1;
786 byte = TDA9840_SET_LANG1;
787 DEB_D(("VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG1\n"));
788 break;
789 }
790 case V4L2_TUNER_MODE_LANG2: {
791 mxb->cur_mode = V4L2_TUNER_MODE_LANG2;
792 byte = TDA9840_SET_LANG2;
793 DEB_D(("VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG2\n"));
794 break;
795 }
796 default: { /* case V4L2_TUNER_MODE_MONO: {*/
797 mxb->cur_mode = V4L2_TUNER_MODE_MONO;
798 byte = TDA9840_SET_MONO;
799 DEB_D(("VIDIOC_S_TUNER: TDA9840_SET_MONO\n"));
800 break;
801 }
802 }
803
804 if( 0 != (result = mxb->tda9840->driver->command(mxb->tda9840, TDA9840_SWITCH, &byte))) {
805 printk("VIDIOC_S_TUNER error. result:%d, byte:%d\n",result,byte);
806 }
807
808 return 0;
809 }
810 case VIDIOC_G_FREQUENCY:
811 {
812 struct v4l2_frequency *f = arg;
813
814 if(0 != mxb->cur_input) {
815 DEB_D(("VIDIOC_G_FREQ: channel %d does not have a tuner!\n",mxb->cur_input));
816 return -EINVAL;
817 }
818
819 memset(f,0,sizeof(*f));
820 f->type = V4L2_TUNER_ANALOG_TV;
821 f->frequency = mxb->cur_freq;
822
823 DEB_EE(("VIDIOC_G_FREQ: freq:0x%08x.\n", mxb->cur_freq));
824 return 0;
825 }
826 case VIDIOC_S_FREQUENCY:
827 {
828 struct v4l2_frequency *f = arg;
829 int t_locked = 0;
830 int v_byte = 0;
831
832 if (0 != f->tuner)
833 return -EINVAL;
834
835 if (V4L2_TUNER_ANALOG_TV != f->type)
836 return -EINVAL;
837
838 if(0 != mxb->cur_input) {
839 DEB_D(("VIDIOC_S_FREQ: channel %d does not have a tuner!\n",mxb->cur_input));
840 return -EINVAL;
841 }
842
843 DEB_EE(("VIDIOC_S_FREQUENCY: freq:0x%08x.\n",f->frequency));
844
845 mxb->cur_freq = f->frequency;
846
847 /* tune in desired frequency */
848 mxb->tuner->driver->command(mxb->tuner, VIDIOCSFREQ, &mxb->cur_freq);
849
850 /* check if pll of tuner & saa7111a is locked */
851// mxb->tuner->driver->command(mxb->tuner,TUNER_IS_LOCKED, &t_locked);
852 mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_GET_STATUS, &v_byte);
853
854 /* not locked -- anything to do here ? */
855 if( 0 == t_locked || 0 == (v_byte & DECODER_STATUS_GOOD)) {
856 }
857
858 /* hack: changing the frequency should invalidate the vbi-counter (=> alevt) */
859 spin_lock(&dev->slock);
860 vv->vbi_fieldcount = 0;
861 spin_unlock(&dev->slock);
862
863 return 0;
864 }
865 case MXB_S_AUDIO_CD:
866 {
867 int i = *(int*)arg;
868
869 if( i < 0 || i >= MXB_AUDIOS ) {
870 DEB_D(("illegal argument to MXB_S_AUDIO_CD: i:%d.\n",i));
871 return -EINVAL;
872 }
873
874 DEB_EE(("MXB_S_AUDIO_CD: i:%d.\n",i));
875
876 mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_cd[i][0]);
877 mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_cd[i][1]);
878
879 return 0;
880 }
881 case MXB_S_AUDIO_LINE:
882 {
883 int i = *(int*)arg;
884
885 if( i < 0 || i >= MXB_AUDIOS ) {
886 DEB_D(("illegal argument to MXB_S_AUDIO_LINE: i:%d.\n",i));
887 return -EINVAL;
888 }
889
890 DEB_EE(("MXB_S_AUDIO_LINE: i:%d.\n",i));
891 mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_line[i][0]);
892 mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_line[i][1]);
893
894 return 0;
895 }
896 case VIDIOC_G_AUDIO:
897 {
898 struct v4l2_audio *a = arg;
899
900 if( a->index < 0 || a->index > MXB_INPUTS ) {
901 DEB_D(("VIDIOC_G_AUDIO %d out of range.\n",a->index));
902 return -EINVAL;
903 }
904
905 DEB_EE(("VIDIOC_G_AUDIO %d.\n",a->index));
906 memcpy(a, &mxb_audios[video_audio_connect[mxb->cur_input]], sizeof(struct v4l2_audio));
907
908 return 0;
909 }
910 case VIDIOC_S_AUDIO:
911 {
912 struct v4l2_audio *a = arg;
913 DEB_D(("VIDIOC_S_AUDIO %d.\n",a->index));
914 return 0;
915 }
916 default:
917/*
918 DEB2(printk("does not handle this ioctl.\n"));
919*/
920 return -ENOIOCTLCMD;
921 }
922 return 0;
923}
924
925static int std_callback(struct saa7146_dev* dev, struct saa7146_standard *std)
926{
927 struct mxb* mxb = (struct mxb*)dev->ext_priv;
928 int zero = 0;
929 int one = 1;
930
931 if(V4L2_STD_PAL_I == std->id ) {
932 DEB_D(("VIDIOC_S_STD: setting mxb for PAL_I.\n"));
933 /* set the 7146 gpio register -- I don't know what this does exactly */
934 saa7146_write(dev, GPIO_CTRL, 0x00404050);
935 /* unset the 7111 gpio register -- I don't know what this does exactly */
936 mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_GPIO, &zero);
937 } else {
938 DEB_D(("VIDIOC_S_STD: setting mxb for PAL/NTSC/SECAM.\n"));
939 /* set the 7146 gpio register -- I don't know what this does exactly */
940 saa7146_write(dev, GPIO_CTRL, 0x00404050);
941 /* set the 7111 gpio register -- I don't know what this does exactly */
942 mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_GPIO, &one);
943 }
944 return 0;
945}
946
947static struct saa7146_standard standard[] = {
948 {
949 .name = "PAL-BG", .id = V4L2_STD_PAL_BG,
950 .v_offset = 0x17, .v_field = 288,
951 .h_offset = 0x14, .h_pixels = 680,
952 .v_max_out = 576, .h_max_out = 768,
953 }, {
954 .name = "PAL-I", .id = V4L2_STD_PAL_I,
955 .v_offset = 0x17, .v_field = 288,
956 .h_offset = 0x14, .h_pixels = 680,
957 .v_max_out = 576, .h_max_out = 768,
958 }, {
959 .name = "NTSC", .id = V4L2_STD_NTSC,
960 .v_offset = 0x16, .v_field = 240,
961 .h_offset = 0x06, .h_pixels = 708,
962 .v_max_out = 480, .h_max_out = 640,
963 }, {
964 .name = "SECAM", .id = V4L2_STD_SECAM,
965 .v_offset = 0x14, .v_field = 288,
966 .h_offset = 0x14, .h_pixels = 720,
967 .v_max_out = 576, .h_max_out = 768,
968 }
969};
970
971static struct saa7146_pci_extension_data mxb = {
972 .ext_priv = "Multimedia eXtension Board",
973 .ext = &extension,
974};
975
976static struct pci_device_id pci_tbl[] = {
977 {
978 .vendor = PCI_VENDOR_ID_PHILIPS,
979 .device = PCI_DEVICE_ID_PHILIPS_SAA7146,
980 .subvendor = 0x0000,
981 .subdevice = 0x0000,
982 .driver_data = (unsigned long)&mxb,
983 }, {
984 .vendor = 0,
985 }
986};
987
988MODULE_DEVICE_TABLE(pci, pci_tbl);
989
990static struct saa7146_ext_vv vv_data = {
991 .inputs = MXB_INPUTS,
992 .capabilities = V4L2_CAP_TUNER | V4L2_CAP_VBI_CAPTURE,
993 .stds = &standard[0],
994 .num_stds = sizeof(standard)/sizeof(struct saa7146_standard),
995 .std_callback = &std_callback,
996 .ioctls = &ioctls[0],
997 .ioctl = mxb_ioctl,
998};
999
1000static struct saa7146_extension extension = {
1001 .name = MXB_IDENTIFIER,
1002 .flags = SAA7146_USE_I2C_IRQ,
1003
1004 .pci_tbl = &pci_tbl[0],
1005 .module = THIS_MODULE,
1006
1007 .probe = mxb_probe,
1008 .attach = mxb_attach,
1009 .detach = mxb_detach,
1010
1011 .irq_mask = 0,
1012 .irq_func = NULL,
1013};
1014
1015static int __init mxb_init_module(void)
1016{
1017 if( 0 != saa7146_register_extension(&extension)) {
1018 DEB_S(("failed to register extension.\n"));
1019 return -ENODEV;
1020 }
1021
1022 return 0;
1023}
1024
1025static void __exit mxb_cleanup_module(void)
1026{
1027 saa7146_unregister_extension(&extension);
1028}
1029
1030module_init(mxb_init_module);
1031module_exit(mxb_cleanup_module);
1032
1033MODULE_DESCRIPTION("video4linux-2 driver for the Siemens-Nixdorf 'Multimedia eXtension board'");
1034MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
1035MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/mxb.h b/drivers/media/video/mxb.h
new file mode 100644
index 00000000000..2332ed5f7c6
--- /dev/null
+++ b/drivers/media/video/mxb.h
@@ -0,0 +1,42 @@
1#ifndef __MXB__
2#define __MXB__
3
4#define BASE_VIDIOC_MXB 10
5
6#define MXB_S_AUDIO_CD _IOW ('V', BASE_VIDIOC_PRIVATE+BASE_VIDIOC_MXB+0, int)
7#define MXB_S_AUDIO_LINE _IOW ('V', BASE_VIDIOC_PRIVATE+BASE_VIDIOC_MXB+1, int)
8
9#define MXB_IDENTIFIER "Multimedia eXtension Board"
10
11#define MXB_AUDIOS 6
12
13/* these are the available audio sources, which can switched
14 to the line- and cd-output individually */
15static struct v4l2_audio mxb_audios[MXB_AUDIOS] = {
16 {
17 .index = 0,
18 .name = "Tuner",
19 .capability = V4L2_AUDCAP_STEREO,
20 } , {
21 .index = 1,
22 .name = "AUX1",
23 .capability = V4L2_AUDCAP_STEREO,
24 } , {
25 .index = 2,
26 .name = "AUX2",
27 .capability = V4L2_AUDCAP_STEREO,
28 } , {
29 .index = 3,
30 .name = "AUX3",
31 .capability = V4L2_AUDCAP_STEREO,
32 } , {
33 .index = 4,
34 .name = "Radio (X9)",
35 .capability = V4L2_AUDCAP_STEREO,
36 } , {
37 .index = 5,
38 .name = "CD-ROM (X10)",
39 .capability = V4L2_AUDCAP_STEREO,
40 }
41};
42#endif
diff --git a/drivers/media/video/ovcamchip/Makefile b/drivers/media/video/ovcamchip/Makefile
new file mode 100644
index 00000000000..bca41ad93de
--- /dev/null
+++ b/drivers/media/video/ovcamchip/Makefile
@@ -0,0 +1,4 @@
1ovcamchip-objs := ovcamchip_core.o ov6x20.o ov6x30.o ov7x10.o ov7x20.o \
2 ov76be.o
3
4obj-$(CONFIG_VIDEO_OVCAMCHIP) += ovcamchip.o
diff --git a/drivers/media/video/ovcamchip/ov6x20.c b/drivers/media/video/ovcamchip/ov6x20.c
new file mode 100644
index 00000000000..3433619ad93
--- /dev/null
+++ b/drivers/media/video/ovcamchip/ov6x20.c
@@ -0,0 +1,415 @@
1/* OmniVision OV6620/OV6120 Camera Chip Support Code
2 *
3 * Copyright (c) 1999-2004 Mark McClelland <mark@alpha.dyndns.org>
4 * http://alpha.dyndns.org/ov511/
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. NO WARRANTY OF ANY KIND is expressed or implied.
10 */
11
12#define DEBUG
13
14#include <linux/slab.h>
15#include "ovcamchip_priv.h"
16
17/* Registers */
18#define REG_GAIN 0x00 /* gain [5:0] */
19#define REG_BLUE 0x01 /* blue gain */
20#define REG_RED 0x02 /* red gain */
21#define REG_SAT 0x03 /* saturation */
22#define REG_CNT 0x05 /* Y contrast */
23#define REG_BRT 0x06 /* Y brightness */
24#define REG_WB_BLUE 0x0C /* WB blue ratio [5:0] */
25#define REG_WB_RED 0x0D /* WB red ratio [5:0] */
26#define REG_EXP 0x10 /* exposure */
27
28/* Window parameters */
29#define HWSBASE 0x38
30#define HWEBASE 0x3A
31#define VWSBASE 0x05
32#define VWEBASE 0x06
33
34struct ov6x20 {
35 int auto_brt;
36 int auto_exp;
37 int backlight;
38 int bandfilt;
39 int mirror;
40};
41
42/* Initial values for use with OV511/OV511+ cameras */
43static struct ovcamchip_regvals regvals_init_6x20_511[] = {
44 { 0x12, 0x80 }, /* reset */
45 { 0x11, 0x01 },
46 { 0x03, 0x60 },
47 { 0x05, 0x7f }, /* For when autoadjust is off */
48 { 0x07, 0xa8 },
49 { 0x0c, 0x24 },
50 { 0x0d, 0x24 },
51 { 0x0f, 0x15 }, /* COMS */
52 { 0x10, 0x75 }, /* AEC Exposure time */
53 { 0x12, 0x24 }, /* Enable AGC and AWB */
54 { 0x14, 0x04 },
55 { 0x16, 0x03 },
56 { 0x26, 0xb2 }, /* BLC enable */
57 /* 0x28: 0x05 Selects RGB format if RGB on */
58 { 0x28, 0x05 },
59 { 0x2a, 0x04 }, /* Disable framerate adjust */
60 { 0x2d, 0x99 },
61 { 0x33, 0xa0 }, /* Color Processing Parameter */
62 { 0x34, 0xd2 }, /* Max A/D range */
63 { 0x38, 0x8b },
64 { 0x39, 0x40 },
65
66 { 0x3c, 0x39 }, /* Enable AEC mode changing */
67 { 0x3c, 0x3c }, /* Change AEC mode */
68 { 0x3c, 0x24 }, /* Disable AEC mode changing */
69
70 { 0x3d, 0x80 },
71 /* These next two registers (0x4a, 0x4b) are undocumented. They
72 * control the color balance */
73 { 0x4a, 0x80 },
74 { 0x4b, 0x80 },
75 { 0x4d, 0xd2 }, /* This reduces noise a bit */
76 { 0x4e, 0xc1 },
77 { 0x4f, 0x04 },
78 { 0xff, 0xff }, /* END MARKER */
79};
80
81/* Initial values for use with OV518 cameras */
82static struct ovcamchip_regvals regvals_init_6x20_518[] = {
83 { 0x12, 0x80 }, /* Do a reset */
84 { 0x03, 0xc0 }, /* Saturation */
85 { 0x05, 0x8a }, /* Contrast */
86 { 0x0c, 0x24 }, /* AWB blue */
87 { 0x0d, 0x24 }, /* AWB red */
88 { 0x0e, 0x8d }, /* Additional 2x gain */
89 { 0x0f, 0x25 }, /* Black expanding level = 1.3V */
90 { 0x11, 0x01 }, /* Clock div. */
91 { 0x12, 0x24 }, /* Enable AGC and AWB */
92 { 0x13, 0x01 }, /* (default) */
93 { 0x14, 0x80 }, /* Set reserved bit 7 */
94 { 0x15, 0x01 }, /* (default) */
95 { 0x16, 0x03 }, /* (default) */
96 { 0x17, 0x38 }, /* (default) */
97 { 0x18, 0xea }, /* (default) */
98 { 0x19, 0x04 },
99 { 0x1a, 0x93 },
100 { 0x1b, 0x00 }, /* (default) */
101 { 0x1e, 0xc4 }, /* (default) */
102 { 0x1f, 0x04 }, /* (default) */
103 { 0x20, 0x20 }, /* Enable 1st stage aperture correction */
104 { 0x21, 0x10 }, /* Y offset */
105 { 0x22, 0x88 }, /* U offset */
106 { 0x23, 0xc0 }, /* Set XTAL power level */
107 { 0x24, 0x53 }, /* AEC bright ratio */
108 { 0x25, 0x7a }, /* AEC black ratio */
109 { 0x26, 0xb2 }, /* BLC enable */
110 { 0x27, 0xa2 }, /* Full output range */
111 { 0x28, 0x01 }, /* (default) */
112 { 0x29, 0x00 }, /* (default) */
113 { 0x2a, 0x84 }, /* (default) */
114 { 0x2b, 0xa8 }, /* Set custom frame rate */
115 { 0x2c, 0xa0 }, /* (reserved) */
116 { 0x2d, 0x95 }, /* Enable banding filter */
117 { 0x2e, 0x88 }, /* V offset */
118 { 0x33, 0x22 }, /* Luminance gamma on */
119 { 0x34, 0xc7 }, /* A/D bias */
120 { 0x36, 0x12 }, /* (reserved) */
121 { 0x37, 0x63 }, /* (reserved) */
122 { 0x38, 0x8b }, /* Quick AEC/AEB */
123 { 0x39, 0x00 }, /* (default) */
124 { 0x3a, 0x0f }, /* (default) */
125 { 0x3b, 0x3c }, /* (default) */
126 { 0x3c, 0x5c }, /* AEC controls */
127 { 0x3d, 0x80 }, /* Drop 1 (bad) frame when AEC change */
128 { 0x3e, 0x80 }, /* (default) */
129 { 0x3f, 0x02 }, /* (default) */
130 { 0x40, 0x10 }, /* (reserved) */
131 { 0x41, 0x10 }, /* (reserved) */
132 { 0x42, 0x00 }, /* (reserved) */
133 { 0x43, 0x7f }, /* (reserved) */
134 { 0x44, 0x80 }, /* (reserved) */
135 { 0x45, 0x1c }, /* (reserved) */
136 { 0x46, 0x1c }, /* (reserved) */
137 { 0x47, 0x80 }, /* (reserved) */
138 { 0x48, 0x5f }, /* (reserved) */
139 { 0x49, 0x00 }, /* (reserved) */
140 { 0x4a, 0x00 }, /* Color balance (undocumented) */
141 { 0x4b, 0x80 }, /* Color balance (undocumented) */
142 { 0x4c, 0x58 }, /* (reserved) */
143 { 0x4d, 0xd2 }, /* U *= .938, V *= .838 */
144 { 0x4e, 0xa0 }, /* (default) */
145 { 0x4f, 0x04 }, /* UV 3-point average */
146 { 0x50, 0xff }, /* (reserved) */
147 { 0x51, 0x58 }, /* (reserved) */
148 { 0x52, 0xc0 }, /* (reserved) */
149 { 0x53, 0x42 }, /* (reserved) */
150 { 0x27, 0xa6 }, /* Enable manual offset adj. (reg 21 & 22) */
151 { 0x12, 0x20 },
152 { 0x12, 0x24 },
153
154 { 0xff, 0xff }, /* END MARKER */
155};
156
157/* This initializes the OV6x20 camera chip and relevant variables. */
158static int ov6x20_init(struct i2c_client *c)
159{
160 struct ovcamchip *ov = i2c_get_clientdata(c);
161 struct ov6x20 *s;
162 int rc;
163
164 DDEBUG(4, &c->dev, "entered");
165
166 switch (c->adapter->id) {
167 case I2C_ALGO_SMBUS | I2C_HW_SMBUS_OV511:
168 rc = ov_write_regvals(c, regvals_init_6x20_511);
169 break;
170 case I2C_ALGO_SMBUS | I2C_HW_SMBUS_OV518:
171 rc = ov_write_regvals(c, regvals_init_6x20_518);
172 break;
173 default:
174 dev_err(&c->dev, "ov6x20: Unsupported adapter\n");
175 rc = -ENODEV;
176 }
177
178 if (rc < 0)
179 return rc;
180
181 ov->spriv = s = kmalloc(sizeof *s, GFP_KERNEL);
182 if (!s)
183 return -ENOMEM;
184 memset(s, 0, sizeof *s);
185
186 s->auto_brt = 1;
187 s->auto_exp = 1;
188
189 return rc;
190}
191
192static int ov6x20_free(struct i2c_client *c)
193{
194 struct ovcamchip *ov = i2c_get_clientdata(c);
195
196 kfree(ov->spriv);
197 return 0;
198}
199
200static int ov6x20_set_control(struct i2c_client *c,
201 struct ovcamchip_control *ctl)
202{
203 struct ovcamchip *ov = i2c_get_clientdata(c);
204 struct ov6x20 *s = ov->spriv;
205 int rc;
206 int v = ctl->value;
207
208 switch (ctl->id) {
209 case OVCAMCHIP_CID_CONT:
210 rc = ov_write(c, REG_CNT, v >> 8);
211 break;
212 case OVCAMCHIP_CID_BRIGHT:
213 rc = ov_write(c, REG_BRT, v >> 8);
214 break;
215 case OVCAMCHIP_CID_SAT:
216 rc = ov_write(c, REG_SAT, v >> 8);
217 break;
218 case OVCAMCHIP_CID_HUE:
219 rc = ov_write(c, REG_RED, 0xFF - (v >> 8));
220 if (rc < 0)
221 goto out;
222
223 rc = ov_write(c, REG_BLUE, v >> 8);
224 break;
225 case OVCAMCHIP_CID_EXP:
226 rc = ov_write(c, REG_EXP, v);
227 break;
228 case OVCAMCHIP_CID_FREQ:
229 {
230 int sixty = (v == 60);
231
232 rc = ov_write(c, 0x2b, sixty?0xa8:0x28);
233 if (rc < 0)
234 goto out;
235
236 rc = ov_write(c, 0x2a, sixty?0x84:0xa4);
237 break;
238 }
239 case OVCAMCHIP_CID_BANDFILT:
240 rc = ov_write_mask(c, 0x2d, v?0x04:0x00, 0x04);
241 s->bandfilt = v;
242 break;
243 case OVCAMCHIP_CID_AUTOBRIGHT:
244 rc = ov_write_mask(c, 0x2d, v?0x10:0x00, 0x10);
245 s->auto_brt = v;
246 break;
247 case OVCAMCHIP_CID_AUTOEXP:
248 rc = ov_write_mask(c, 0x13, v?0x01:0x00, 0x01);
249 s->auto_exp = v;
250 break;
251 case OVCAMCHIP_CID_BACKLIGHT:
252 {
253 rc = ov_write_mask(c, 0x4e, v?0xe0:0xc0, 0xe0);
254 if (rc < 0)
255 goto out;
256
257 rc = ov_write_mask(c, 0x29, v?0x08:0x00, 0x08);
258 if (rc < 0)
259 goto out;
260
261 rc = ov_write_mask(c, 0x0e, v?0x80:0x00, 0x80);
262 s->backlight = v;
263 break;
264 }
265 case OVCAMCHIP_CID_MIRROR:
266 rc = ov_write_mask(c, 0x12, v?0x40:0x00, 0x40);
267 s->mirror = v;
268 break;
269 default:
270 DDEBUG(2, &c->dev, "control not supported: %d", ctl->id);
271 return -EPERM;
272 }
273
274out:
275 DDEBUG(3, &c->dev, "id=%d, arg=%d, rc=%d", ctl->id, v, rc);
276 return rc;
277}
278
279static int ov6x20_get_control(struct i2c_client *c,
280 struct ovcamchip_control *ctl)
281{
282 struct ovcamchip *ov = i2c_get_clientdata(c);
283 struct ov6x20 *s = ov->spriv;
284 int rc = 0;
285 unsigned char val = 0;
286
287 switch (ctl->id) {
288 case OVCAMCHIP_CID_CONT:
289 rc = ov_read(c, REG_CNT, &val);
290 ctl->value = val << 8;
291 break;
292 case OVCAMCHIP_CID_BRIGHT:
293 rc = ov_read(c, REG_BRT, &val);
294 ctl->value = val << 8;
295 break;
296 case OVCAMCHIP_CID_SAT:
297 rc = ov_read(c, REG_SAT, &val);
298 ctl->value = val << 8;
299 break;
300 case OVCAMCHIP_CID_HUE:
301 rc = ov_read(c, REG_BLUE, &val);
302 ctl->value = val << 8;
303 break;
304 case OVCAMCHIP_CID_EXP:
305 rc = ov_read(c, REG_EXP, &val);
306 ctl->value = val;
307 break;
308 case OVCAMCHIP_CID_BANDFILT:
309 ctl->value = s->bandfilt;
310 break;
311 case OVCAMCHIP_CID_AUTOBRIGHT:
312 ctl->value = s->auto_brt;
313 break;
314 case OVCAMCHIP_CID_AUTOEXP:
315 ctl->value = s->auto_exp;
316 break;
317 case OVCAMCHIP_CID_BACKLIGHT:
318 ctl->value = s->backlight;
319 break;
320 case OVCAMCHIP_CID_MIRROR:
321 ctl->value = s->mirror;
322 break;
323 default:
324 DDEBUG(2, &c->dev, "control not supported: %d", ctl->id);
325 return -EPERM;
326 }
327
328 DDEBUG(3, &c->dev, "id=%d, arg=%d, rc=%d", ctl->id, ctl->value, rc);
329 return rc;
330}
331
332static int ov6x20_mode_init(struct i2c_client *c, struct ovcamchip_window *win)
333{
334 /******** QCIF-specific regs ********/
335
336 ov_write(c, 0x14, win->quarter?0x24:0x04);
337
338 /******** Palette-specific regs ********/
339
340 /* OV518 needs 8 bit multiplexed in color mode, and 16 bit in B&W */
341 if (c->adapter->id == (I2C_ALGO_SMBUS | I2C_HW_SMBUS_OV518)) {
342 if (win->format == VIDEO_PALETTE_GREY)
343 ov_write_mask(c, 0x13, 0x00, 0x20);
344 else
345 ov_write_mask(c, 0x13, 0x20, 0x20);
346 } else {
347 if (win->format == VIDEO_PALETTE_GREY)
348 ov_write_mask(c, 0x13, 0x20, 0x20);
349 else
350 ov_write_mask(c, 0x13, 0x00, 0x20);
351 }
352
353 /******** Clock programming ********/
354
355 /* The OV6620 needs special handling. This prevents the
356 * severe banding that normally occurs */
357
358 /* Clock down */
359 ov_write(c, 0x2a, 0x04);
360
361 ov_write(c, 0x11, win->clockdiv);
362
363 ov_write(c, 0x2a, 0x84);
364 /* This next setting is critical. It seems to improve
365 * the gain or the contrast. The "reserved" bits seem
366 * to have some effect in this case. */
367 ov_write(c, 0x2d, 0x85); /* FIXME: This messes up banding filter */
368
369 return 0;
370}
371
372static int ov6x20_set_window(struct i2c_client *c, struct ovcamchip_window *win)
373{
374 int ret, hwscale, vwscale;
375
376 ret = ov6x20_mode_init(c, win);
377 if (ret < 0)
378 return ret;
379
380 if (win->quarter) {
381 hwscale = 0;
382 vwscale = 0;
383 } else {
384 hwscale = 1;
385 vwscale = 1; /* The datasheet says 0; it's wrong */
386 }
387
388 ov_write(c, 0x17, HWSBASE + (win->x >> hwscale));
389 ov_write(c, 0x18, HWEBASE + ((win->x + win->width) >> hwscale));
390 ov_write(c, 0x19, VWSBASE + (win->y >> vwscale));
391 ov_write(c, 0x1a, VWEBASE + ((win->y + win->height) >> vwscale));
392
393 return 0;
394}
395
396static int ov6x20_command(struct i2c_client *c, unsigned int cmd, void *arg)
397{
398 switch (cmd) {
399 case OVCAMCHIP_CMD_S_CTRL:
400 return ov6x20_set_control(c, arg);
401 case OVCAMCHIP_CMD_G_CTRL:
402 return ov6x20_get_control(c, arg);
403 case OVCAMCHIP_CMD_S_MODE:
404 return ov6x20_set_window(c, arg);
405 default:
406 DDEBUG(2, &c->dev, "command not supported: %d", cmd);
407 return -ENOIOCTLCMD;
408 }
409}
410
411struct ovcamchip_ops ov6x20_ops = {
412 .init = ov6x20_init,
413 .free = ov6x20_free,
414 .command = ov6x20_command,
415};
diff --git a/drivers/media/video/ovcamchip/ov6x30.c b/drivers/media/video/ovcamchip/ov6x30.c
new file mode 100644
index 00000000000..44a842379b4
--- /dev/null
+++ b/drivers/media/video/ovcamchip/ov6x30.c
@@ -0,0 +1,374 @@
1/* OmniVision OV6630/OV6130 Camera Chip Support Code
2 *
3 * Copyright (c) 1999-2004 Mark McClelland <mark@alpha.dyndns.org>
4 * http://alpha.dyndns.org/ov511/
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. NO WARRANTY OF ANY KIND is expressed or implied.
10 */
11
12#define DEBUG
13
14#include <linux/slab.h>
15#include "ovcamchip_priv.h"
16
17/* Registers */
18#define REG_GAIN 0x00 /* gain [5:0] */
19#define REG_BLUE 0x01 /* blue gain */
20#define REG_RED 0x02 /* red gain */
21#define REG_SAT 0x03 /* saturation [7:3] */
22#define REG_CNT 0x05 /* Y contrast [3:0] */
23#define REG_BRT 0x06 /* Y brightness */
24#define REG_SHARP 0x07 /* sharpness */
25#define REG_WB_BLUE 0x0C /* WB blue ratio [5:0] */
26#define REG_WB_RED 0x0D /* WB red ratio [5:0] */
27#define REG_EXP 0x10 /* exposure */
28
29/* Window parameters */
30#define HWSBASE 0x38
31#define HWEBASE 0x3A
32#define VWSBASE 0x05
33#define VWEBASE 0x06
34
35struct ov6x30 {
36 int auto_brt;
37 int auto_exp;
38 int backlight;
39 int bandfilt;
40 int mirror;
41};
42
43static struct ovcamchip_regvals regvals_init_6x30[] = {
44 { 0x12, 0x80 }, /* reset */
45 { 0x00, 0x1f }, /* Gain */
46 { 0x01, 0x99 }, /* Blue gain */
47 { 0x02, 0x7c }, /* Red gain */
48 { 0x03, 0xc0 }, /* Saturation */
49 { 0x05, 0x0a }, /* Contrast */
50 { 0x06, 0x95 }, /* Brightness */
51 { 0x07, 0x2d }, /* Sharpness */
52 { 0x0c, 0x20 },
53 { 0x0d, 0x20 },
54 { 0x0e, 0x20 },
55 { 0x0f, 0x05 },
56 { 0x10, 0x9a }, /* "exposure check" */
57 { 0x11, 0x00 }, /* Pixel clock = fastest */
58 { 0x12, 0x24 }, /* Enable AGC and AWB */
59 { 0x13, 0x21 },
60 { 0x14, 0x80 },
61 { 0x15, 0x01 },
62 { 0x16, 0x03 },
63 { 0x17, 0x38 },
64 { 0x18, 0xea },
65 { 0x19, 0x04 },
66 { 0x1a, 0x93 },
67 { 0x1b, 0x00 },
68 { 0x1e, 0xc4 },
69 { 0x1f, 0x04 },
70 { 0x20, 0x20 },
71 { 0x21, 0x10 },
72 { 0x22, 0x88 },
73 { 0x23, 0xc0 }, /* Crystal circuit power level */
74 { 0x25, 0x9a }, /* Increase AEC black pixel ratio */
75 { 0x26, 0xb2 }, /* BLC enable */
76 { 0x27, 0xa2 },
77 { 0x28, 0x00 },
78 { 0x29, 0x00 },
79 { 0x2a, 0x84 }, /* (keep) */
80 { 0x2b, 0xa8 }, /* (keep) */
81 { 0x2c, 0xa0 },
82 { 0x2d, 0x95 }, /* Enable auto-brightness */
83 { 0x2e, 0x88 },
84 { 0x33, 0x26 },
85 { 0x34, 0x03 },
86 { 0x36, 0x8f },
87 { 0x37, 0x80 },
88 { 0x38, 0x83 },
89 { 0x39, 0x80 },
90 { 0x3a, 0x0f },
91 { 0x3b, 0x3c },
92 { 0x3c, 0x1a },
93 { 0x3d, 0x80 },
94 { 0x3e, 0x80 },
95 { 0x3f, 0x0e },
96 { 0x40, 0x00 }, /* White bal */
97 { 0x41, 0x00 }, /* White bal */
98 { 0x42, 0x80 },
99 { 0x43, 0x3f }, /* White bal */
100 { 0x44, 0x80 },
101 { 0x45, 0x20 },
102 { 0x46, 0x20 },
103 { 0x47, 0x80 },
104 { 0x48, 0x7f },
105 { 0x49, 0x00 },
106 { 0x4a, 0x00 },
107 { 0x4b, 0x80 },
108 { 0x4c, 0xd0 },
109 { 0x4d, 0x10 }, /* U = 0.563u, V = 0.714v */
110 { 0x4e, 0x40 },
111 { 0x4f, 0x07 }, /* UV average mode, color killer: strongest */
112 { 0x50, 0xff },
113 { 0x54, 0x23 }, /* Max AGC gain: 18dB */
114 { 0x55, 0xff },
115 { 0x56, 0x12 },
116 { 0x57, 0x81 }, /* (default) */
117 { 0x58, 0x75 },
118 { 0x59, 0x01 }, /* AGC dark current compensation: +1 */
119 { 0x5a, 0x2c },
120 { 0x5b, 0x0f }, /* AWB chrominance levels */
121 { 0x5c, 0x10 },
122 { 0x3d, 0x80 },
123 { 0x27, 0xa6 },
124 /* Toggle AWB off and on */
125 { 0x12, 0x20 },
126 { 0x12, 0x24 },
127
128 { 0xff, 0xff }, /* END MARKER */
129};
130
131/* This initializes the OV6x30 camera chip and relevant variables. */
132static int ov6x30_init(struct i2c_client *c)
133{
134 struct ovcamchip *ov = i2c_get_clientdata(c);
135 struct ov6x30 *s;
136 int rc;
137
138 DDEBUG(4, &c->dev, "entered");
139
140 rc = ov_write_regvals(c, regvals_init_6x30);
141 if (rc < 0)
142 return rc;
143
144 ov->spriv = s = kmalloc(sizeof *s, GFP_KERNEL);
145 if (!s)
146 return -ENOMEM;
147 memset(s, 0, sizeof *s);
148
149 s->auto_brt = 1;
150 s->auto_exp = 1;
151
152 return rc;
153}
154
155static int ov6x30_free(struct i2c_client *c)
156{
157 struct ovcamchip *ov = i2c_get_clientdata(c);
158
159 kfree(ov->spriv);
160 return 0;
161}
162
163static int ov6x30_set_control(struct i2c_client *c,
164 struct ovcamchip_control *ctl)
165{
166 struct ovcamchip *ov = i2c_get_clientdata(c);
167 struct ov6x30 *s = ov->spriv;
168 int rc;
169 int v = ctl->value;
170
171 switch (ctl->id) {
172 case OVCAMCHIP_CID_CONT:
173 rc = ov_write_mask(c, REG_CNT, v >> 12, 0x0f);
174 break;
175 case OVCAMCHIP_CID_BRIGHT:
176 rc = ov_write(c, REG_BRT, v >> 8);
177 break;
178 case OVCAMCHIP_CID_SAT:
179 rc = ov_write(c, REG_SAT, v >> 8);
180 break;
181 case OVCAMCHIP_CID_HUE:
182 rc = ov_write(c, REG_RED, 0xFF - (v >> 8));
183 if (rc < 0)
184 goto out;
185
186 rc = ov_write(c, REG_BLUE, v >> 8);
187 break;
188 case OVCAMCHIP_CID_EXP:
189 rc = ov_write(c, REG_EXP, v);
190 break;
191 case OVCAMCHIP_CID_FREQ:
192 {
193 int sixty = (v == 60);
194
195 rc = ov_write(c, 0x2b, sixty?0xa8:0x28);
196 if (rc < 0)
197 goto out;
198
199 rc = ov_write(c, 0x2a, sixty?0x84:0xa4);
200 break;
201 }
202 case OVCAMCHIP_CID_BANDFILT:
203 rc = ov_write_mask(c, 0x2d, v?0x04:0x00, 0x04);
204 s->bandfilt = v;
205 break;
206 case OVCAMCHIP_CID_AUTOBRIGHT:
207 rc = ov_write_mask(c, 0x2d, v?0x10:0x00, 0x10);
208 s->auto_brt = v;
209 break;
210 case OVCAMCHIP_CID_AUTOEXP:
211 rc = ov_write_mask(c, 0x28, v?0x00:0x10, 0x10);
212 s->auto_exp = v;
213 break;
214 case OVCAMCHIP_CID_BACKLIGHT:
215 {
216 rc = ov_write_mask(c, 0x4e, v?0x80:0x60, 0xe0);
217 if (rc < 0)
218 goto out;
219
220 rc = ov_write_mask(c, 0x29, v?0x08:0x00, 0x08);
221 if (rc < 0)
222 goto out;
223
224 rc = ov_write_mask(c, 0x28, v?0x02:0x00, 0x02);
225 s->backlight = v;
226 break;
227 }
228 case OVCAMCHIP_CID_MIRROR:
229 rc = ov_write_mask(c, 0x12, v?0x40:0x00, 0x40);
230 s->mirror = v;
231 break;
232 default:
233 DDEBUG(2, &c->dev, "control not supported: %d", ctl->id);
234 return -EPERM;
235 }
236
237out:
238 DDEBUG(3, &c->dev, "id=%d, arg=%d, rc=%d", ctl->id, v, rc);
239 return rc;
240}
241
242static int ov6x30_get_control(struct i2c_client *c,
243 struct ovcamchip_control *ctl)
244{
245 struct ovcamchip *ov = i2c_get_clientdata(c);
246 struct ov6x30 *s = ov->spriv;
247 int rc = 0;
248 unsigned char val = 0;
249
250 switch (ctl->id) {
251 case OVCAMCHIP_CID_CONT:
252 rc = ov_read(c, REG_CNT, &val);
253 ctl->value = (val & 0x0f) << 12;
254 break;
255 case OVCAMCHIP_CID_BRIGHT:
256 rc = ov_read(c, REG_BRT, &val);
257 ctl->value = val << 8;
258 break;
259 case OVCAMCHIP_CID_SAT:
260 rc = ov_read(c, REG_SAT, &val);
261 ctl->value = val << 8;
262 break;
263 case OVCAMCHIP_CID_HUE:
264 rc = ov_read(c, REG_BLUE, &val);
265 ctl->value = val << 8;
266 break;
267 case OVCAMCHIP_CID_EXP:
268 rc = ov_read(c, REG_EXP, &val);
269 ctl->value = val;
270 break;
271 case OVCAMCHIP_CID_BANDFILT:
272 ctl->value = s->bandfilt;
273 break;
274 case OVCAMCHIP_CID_AUTOBRIGHT:
275 ctl->value = s->auto_brt;
276 break;
277 case OVCAMCHIP_CID_AUTOEXP:
278 ctl->value = s->auto_exp;
279 break;
280 case OVCAMCHIP_CID_BACKLIGHT:
281 ctl->value = s->backlight;
282 break;
283 case OVCAMCHIP_CID_MIRROR:
284 ctl->value = s->mirror;
285 break;
286 default:
287 DDEBUG(2, &c->dev, "control not supported: %d", ctl->id);
288 return -EPERM;
289 }
290
291 DDEBUG(3, &c->dev, "id=%d, arg=%d, rc=%d", ctl->id, ctl->value, rc);
292 return rc;
293}
294
295static int ov6x30_mode_init(struct i2c_client *c, struct ovcamchip_window *win)
296{
297 /******** QCIF-specific regs ********/
298
299 ov_write_mask(c, 0x14, win->quarter?0x20:0x00, 0x20);
300
301 /******** Palette-specific regs ********/
302
303 if (win->format == VIDEO_PALETTE_GREY) {
304 if (c->adapter->id == (I2C_ALGO_SMBUS | I2C_HW_SMBUS_OV518)) {
305 /* Do nothing - we're already in 8-bit mode */
306 } else {
307 ov_write_mask(c, 0x13, 0x20, 0x20);
308 }
309 } else {
310 /* The OV518 needs special treatment. Although both the OV518
311 * and the OV6630 support a 16-bit video bus, only the 8 bit Y
312 * bus is actually used. The UV bus is tied to ground.
313 * Therefore, the OV6630 needs to be in 8-bit multiplexed
314 * output mode */
315
316 if (c->adapter->id == (I2C_ALGO_SMBUS | I2C_HW_SMBUS_OV518)) {
317 /* Do nothing - we want to stay in 8-bit mode */
318 /* Warning: Messing with reg 0x13 breaks OV518 color */
319 } else {
320 ov_write_mask(c, 0x13, 0x00, 0x20);
321 }
322 }
323
324 /******** Clock programming ********/
325
326 ov_write(c, 0x11, win->clockdiv);
327
328 return 0;
329}
330
331static int ov6x30_set_window(struct i2c_client *c, struct ovcamchip_window *win)
332{
333 int ret, hwscale, vwscale;
334
335 ret = ov6x30_mode_init(c, win);
336 if (ret < 0)
337 return ret;
338
339 if (win->quarter) {
340 hwscale = 0;
341 vwscale = 0;
342 } else {
343 hwscale = 1;
344 vwscale = 1; /* The datasheet says 0; it's wrong */
345 }
346
347 ov_write(c, 0x17, HWSBASE + (win->x >> hwscale));
348 ov_write(c, 0x18, HWEBASE + ((win->x + win->width) >> hwscale));
349 ov_write(c, 0x19, VWSBASE + (win->y >> vwscale));
350 ov_write(c, 0x1a, VWEBASE + ((win->y + win->height) >> vwscale));
351
352 return 0;
353}
354
355static int ov6x30_command(struct i2c_client *c, unsigned int cmd, void *arg)
356{
357 switch (cmd) {
358 case OVCAMCHIP_CMD_S_CTRL:
359 return ov6x30_set_control(c, arg);
360 case OVCAMCHIP_CMD_G_CTRL:
361 return ov6x30_get_control(c, arg);
362 case OVCAMCHIP_CMD_S_MODE:
363 return ov6x30_set_window(c, arg);
364 default:
365 DDEBUG(2, &c->dev, "command not supported: %d", cmd);
366 return -ENOIOCTLCMD;
367 }
368}
369
370struct ovcamchip_ops ov6x30_ops = {
371 .init = ov6x30_init,
372 .free = ov6x30_free,
373 .command = ov6x30_command,
374};
diff --git a/drivers/media/video/ovcamchip/ov76be.c b/drivers/media/video/ovcamchip/ov76be.c
new file mode 100644
index 00000000000..29bbdc05e3b
--- /dev/null
+++ b/drivers/media/video/ovcamchip/ov76be.c
@@ -0,0 +1,303 @@
1/* OmniVision OV76BE Camera Chip Support Code
2 *
3 * Copyright (c) 1999-2004 Mark McClelland <mark@alpha.dyndns.org>
4 * http://alpha.dyndns.org/ov511/
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. NO WARRANTY OF ANY KIND is expressed or implied.
10 */
11
12#define DEBUG
13
14#include <linux/slab.h>
15#include "ovcamchip_priv.h"
16
17/* OV7610 registers: Since the OV76BE is undocumented, we'll settle for these
18 * for now. */
19#define REG_GAIN 0x00 /* gain [5:0] */
20#define REG_BLUE 0x01 /* blue channel balance */
21#define REG_RED 0x02 /* red channel balance */
22#define REG_SAT 0x03 /* saturation */
23#define REG_CNT 0x05 /* Y contrast */
24#define REG_BRT 0x06 /* Y brightness */
25#define REG_BLUE_BIAS 0x0C /* blue channel bias [5:0] */
26#define REG_RED_BIAS 0x0D /* red channel bias [5:0] */
27#define REG_GAMMA_COEFF 0x0E /* gamma settings */
28#define REG_WB_RANGE 0x0F /* AEC/ALC/S-AWB settings */
29#define REG_EXP 0x10 /* manual exposure setting */
30#define REG_CLOCK 0x11 /* polarity/clock prescaler */
31#define REG_FIELD_DIVIDE 0x16 /* field interval/mode settings */
32#define REG_HWIN_START 0x17 /* horizontal window start */
33#define REG_HWIN_END 0x18 /* horizontal window end */
34#define REG_VWIN_START 0x19 /* vertical window start */
35#define REG_VWIN_END 0x1A /* vertical window end */
36#define REG_PIXEL_SHIFT 0x1B /* pixel shift */
37#define REG_YOFFSET 0x21 /* Y channel offset */
38#define REG_UOFFSET 0x22 /* U channel offset */
39#define REG_ECW 0x24 /* exposure white level for AEC */
40#define REG_ECB 0x25 /* exposure black level for AEC */
41#define REG_FRAMERATE_H 0x2A /* frame rate MSB + misc */
42#define REG_FRAMERATE_L 0x2B /* frame rate LSB */
43#define REG_ALC 0x2C /* Auto Level Control settings */
44#define REG_VOFFSET 0x2E /* V channel offset adjustment */
45#define REG_ARRAY_BIAS 0x2F /* array bias -- don't change */
46#define REG_YGAMMA 0x33 /* misc gamma settings [7:6] */
47#define REG_BIAS_ADJUST 0x34 /* misc bias settings */
48
49/* Window parameters */
50#define HWSBASE 0x38
51#define HWEBASE 0x3a
52#define VWSBASE 0x05
53#define VWEBASE 0x05
54
55struct ov76be {
56 int auto_brt;
57 int auto_exp;
58 int bandfilt;
59 int mirror;
60};
61
62/* NOTE: These are the same as the 7x10 settings, but should eventually be
63 * optimized for the OV76BE */
64static struct ovcamchip_regvals regvals_init_76be[] = {
65 { 0x10, 0xff },
66 { 0x16, 0x03 },
67 { 0x28, 0x24 },
68 { 0x2b, 0xac },
69 { 0x12, 0x00 },
70 { 0x38, 0x81 },
71 { 0x28, 0x24 }, /* 0c */
72 { 0x0f, 0x85 }, /* lg's setting */
73 { 0x15, 0x01 },
74 { 0x20, 0x1c },
75 { 0x23, 0x2a },
76 { 0x24, 0x10 },
77 { 0x25, 0x8a },
78 { 0x26, 0xa2 },
79 { 0x27, 0xc2 },
80 { 0x2a, 0x04 },
81 { 0x2c, 0xfe },
82 { 0x2d, 0x93 },
83 { 0x30, 0x71 },
84 { 0x31, 0x60 },
85 { 0x32, 0x26 },
86 { 0x33, 0x20 },
87 { 0x34, 0x48 },
88 { 0x12, 0x24 },
89 { 0x11, 0x01 },
90 { 0x0c, 0x24 },
91 { 0x0d, 0x24 },
92 { 0xff, 0xff }, /* END MARKER */
93};
94
95/* This initializes the OV76be camera chip and relevant variables. */
96static int ov76be_init(struct i2c_client *c)
97{
98 struct ovcamchip *ov = i2c_get_clientdata(c);
99 struct ov76be *s;
100 int rc;
101
102 DDEBUG(4, &c->dev, "entered");
103
104 rc = ov_write_regvals(c, regvals_init_76be);
105 if (rc < 0)
106 return rc;
107
108 ov->spriv = s = kmalloc(sizeof *s, GFP_KERNEL);
109 if (!s)
110 return -ENOMEM;
111 memset(s, 0, sizeof *s);
112
113 s->auto_brt = 1;
114 s->auto_exp = 1;
115
116 return rc;
117}
118
119static int ov76be_free(struct i2c_client *c)
120{
121 struct ovcamchip *ov = i2c_get_clientdata(c);
122
123 kfree(ov->spriv);
124 return 0;
125}
126
127static int ov76be_set_control(struct i2c_client *c,
128 struct ovcamchip_control *ctl)
129{
130 struct ovcamchip *ov = i2c_get_clientdata(c);
131 struct ov76be *s = ov->spriv;
132 int rc;
133 int v = ctl->value;
134
135 switch (ctl->id) {
136 case OVCAMCHIP_CID_BRIGHT:
137 rc = ov_write(c, REG_BRT, v >> 8);
138 break;
139 case OVCAMCHIP_CID_SAT:
140 rc = ov_write(c, REG_SAT, v >> 8);
141 break;
142 case OVCAMCHIP_CID_EXP:
143 rc = ov_write(c, REG_EXP, v);
144 break;
145 case OVCAMCHIP_CID_FREQ:
146 {
147 int sixty = (v == 60);
148
149 rc = ov_write_mask(c, 0x2a, sixty?0x00:0x80, 0x80);
150 if (rc < 0)
151 goto out;
152
153 rc = ov_write(c, 0x2b, sixty?0x00:0xac);
154 if (rc < 0)
155 goto out;
156
157 rc = ov_write_mask(c, 0x76, 0x01, 0x01);
158 break;
159 }
160 case OVCAMCHIP_CID_BANDFILT:
161 rc = ov_write_mask(c, 0x2d, v?0x04:0x00, 0x04);
162 s->bandfilt = v;
163 break;
164 case OVCAMCHIP_CID_AUTOBRIGHT:
165 rc = ov_write_mask(c, 0x2d, v?0x10:0x00, 0x10);
166 s->auto_brt = v;
167 break;
168 case OVCAMCHIP_CID_AUTOEXP:
169 rc = ov_write_mask(c, 0x13, v?0x01:0x00, 0x01);
170 s->auto_exp = v;
171 break;
172 case OVCAMCHIP_CID_MIRROR:
173 rc = ov_write_mask(c, 0x12, v?0x40:0x00, 0x40);
174 s->mirror = v;
175 break;
176 default:
177 DDEBUG(2, &c->dev, "control not supported: %d", ctl->id);
178 return -EPERM;
179 }
180
181out:
182 DDEBUG(3, &c->dev, "id=%d, arg=%d, rc=%d", ctl->id, v, rc);
183 return rc;
184}
185
186static int ov76be_get_control(struct i2c_client *c,
187 struct ovcamchip_control *ctl)
188{
189 struct ovcamchip *ov = i2c_get_clientdata(c);
190 struct ov76be *s = ov->spriv;
191 int rc = 0;
192 unsigned char val = 0;
193
194 switch (ctl->id) {
195 case OVCAMCHIP_CID_BRIGHT:
196 rc = ov_read(c, REG_BRT, &val);
197 ctl->value = val << 8;
198 break;
199 case OVCAMCHIP_CID_SAT:
200 rc = ov_read(c, REG_SAT, &val);
201 ctl->value = val << 8;
202 break;
203 case OVCAMCHIP_CID_EXP:
204 rc = ov_read(c, REG_EXP, &val);
205 ctl->value = val;
206 break;
207 case OVCAMCHIP_CID_BANDFILT:
208 ctl->value = s->bandfilt;
209 break;
210 case OVCAMCHIP_CID_AUTOBRIGHT:
211 ctl->value = s->auto_brt;
212 break;
213 case OVCAMCHIP_CID_AUTOEXP:
214 ctl->value = s->auto_exp;
215 break;
216 case OVCAMCHIP_CID_MIRROR:
217 ctl->value = s->mirror;
218 break;
219 default:
220 DDEBUG(2, &c->dev, "control not supported: %d", ctl->id);
221 return -EPERM;
222 }
223
224 DDEBUG(3, &c->dev, "id=%d, arg=%d, rc=%d", ctl->id, ctl->value, rc);
225 return rc;
226}
227
228static int ov76be_mode_init(struct i2c_client *c, struct ovcamchip_window *win)
229{
230 int qvga = win->quarter;
231
232 /******** QVGA-specific regs ********/
233
234 ov_write(c, 0x14, qvga?0xa4:0x84);
235
236 /******** Palette-specific regs ********/
237
238 if (win->format == VIDEO_PALETTE_GREY) {
239 ov_write_mask(c, 0x0e, 0x40, 0x40);
240 ov_write_mask(c, 0x13, 0x20, 0x20);
241 } else {
242 ov_write_mask(c, 0x0e, 0x00, 0x40);
243 ov_write_mask(c, 0x13, 0x00, 0x20);
244 }
245
246 /******** Clock programming ********/
247
248 ov_write(c, 0x11, win->clockdiv);
249
250 /******** Resolution-specific ********/
251
252 if (win->width == 640 && win->height == 480)
253 ov_write(c, 0x35, 0x9e);
254 else
255 ov_write(c, 0x35, 0x1e);
256
257 return 0;
258}
259
260static int ov76be_set_window(struct i2c_client *c, struct ovcamchip_window *win)
261{
262 int ret, hwscale, vwscale;
263
264 ret = ov76be_mode_init(c, win);
265 if (ret < 0)
266 return ret;
267
268 if (win->quarter) {
269 hwscale = 1;
270 vwscale = 0;
271 } else {
272 hwscale = 2;
273 vwscale = 1;
274 }
275
276 ov_write(c, 0x17, HWSBASE + (win->x >> hwscale));
277 ov_write(c, 0x18, HWEBASE + ((win->x + win->width) >> hwscale));
278 ov_write(c, 0x19, VWSBASE + (win->y >> vwscale));
279 ov_write(c, 0x1a, VWEBASE + ((win->y + win->height) >> vwscale));
280
281 return 0;
282}
283
284static int ov76be_command(struct i2c_client *c, unsigned int cmd, void *arg)
285{
286 switch (cmd) {
287 case OVCAMCHIP_CMD_S_CTRL:
288 return ov76be_set_control(c, arg);
289 case OVCAMCHIP_CMD_G_CTRL:
290 return ov76be_get_control(c, arg);
291 case OVCAMCHIP_CMD_S_MODE:
292 return ov76be_set_window(c, arg);
293 default:
294 DDEBUG(2, &c->dev, "command not supported: %d", cmd);
295 return -ENOIOCTLCMD;
296 }
297}
298
299struct ovcamchip_ops ov76be_ops = {
300 .init = ov76be_init,
301 .free = ov76be_free,
302 .command = ov76be_command,
303};
diff --git a/drivers/media/video/ovcamchip/ov7x10.c b/drivers/media/video/ovcamchip/ov7x10.c
new file mode 100644
index 00000000000..6c383d4b14f
--- /dev/null
+++ b/drivers/media/video/ovcamchip/ov7x10.c
@@ -0,0 +1,335 @@
1/* OmniVision OV7610/OV7110 Camera Chip Support Code
2 *
3 * Copyright (c) 1999-2004 Mark McClelland <mark@alpha.dyndns.org>
4 * http://alpha.dyndns.org/ov511/
5 *
6 * Color fixes by by Orion Sky Lawlor <olawlor@acm.org> (2/26/2000)
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version. NO WARRANTY OF ANY KIND is expressed or implied.
12 */
13
14#define DEBUG
15
16#include <linux/slab.h>
17#include "ovcamchip_priv.h"
18
19/* Registers */
20#define REG_GAIN 0x00 /* gain [5:0] */
21#define REG_BLUE 0x01 /* blue channel balance */
22#define REG_RED 0x02 /* red channel balance */
23#define REG_SAT 0x03 /* saturation */
24#define REG_CNT 0x05 /* Y contrast */
25#define REG_BRT 0x06 /* Y brightness */
26#define REG_BLUE_BIAS 0x0C /* blue channel bias [5:0] */
27#define REG_RED_BIAS 0x0D /* red channel bias [5:0] */
28#define REG_GAMMA_COEFF 0x0E /* gamma settings */
29#define REG_WB_RANGE 0x0F /* AEC/ALC/S-AWB settings */
30#define REG_EXP 0x10 /* manual exposure setting */
31#define REG_CLOCK 0x11 /* polarity/clock prescaler */
32#define REG_FIELD_DIVIDE 0x16 /* field interval/mode settings */
33#define REG_HWIN_START 0x17 /* horizontal window start */
34#define REG_HWIN_END 0x18 /* horizontal window end */
35#define REG_VWIN_START 0x19 /* vertical window start */
36#define REG_VWIN_END 0x1A /* vertical window end */
37#define REG_PIXEL_SHIFT 0x1B /* pixel shift */
38#define REG_YOFFSET 0x21 /* Y channel offset */
39#define REG_UOFFSET 0x22 /* U channel offset */
40#define REG_ECW 0x24 /* exposure white level for AEC */
41#define REG_ECB 0x25 /* exposure black level for AEC */
42#define REG_FRAMERATE_H 0x2A /* frame rate MSB + misc */
43#define REG_FRAMERATE_L 0x2B /* frame rate LSB */
44#define REG_ALC 0x2C /* Auto Level Control settings */
45#define REG_VOFFSET 0x2E /* V channel offset adjustment */
46#define REG_ARRAY_BIAS 0x2F /* array bias -- don't change */
47#define REG_YGAMMA 0x33 /* misc gamma settings [7:6] */
48#define REG_BIAS_ADJUST 0x34 /* misc bias settings */
49
50/* Window parameters */
51#define HWSBASE 0x38
52#define HWEBASE 0x3a
53#define VWSBASE 0x05
54#define VWEBASE 0x05
55
56struct ov7x10 {
57 int auto_brt;
58 int auto_exp;
59 int bandfilt;
60 int mirror;
61};
62
63/* Lawrence Glaister <lg@jfm.bc.ca> reports:
64 *
65 * Register 0x0f in the 7610 has the following effects:
66 *
67 * 0x85 (AEC method 1): Best overall, good contrast range
68 * 0x45 (AEC method 2): Very overexposed
69 * 0xa5 (spec sheet default): Ok, but the black level is
70 * shifted resulting in loss of contrast
71 * 0x05 (old driver setting): very overexposed, too much
72 * contrast
73 */
74static struct ovcamchip_regvals regvals_init_7x10[] = {
75 { 0x10, 0xff },
76 { 0x16, 0x03 },
77 { 0x28, 0x24 },
78 { 0x2b, 0xac },
79 { 0x12, 0x00 },
80 { 0x38, 0x81 },
81 { 0x28, 0x24 }, /* 0c */
82 { 0x0f, 0x85 }, /* lg's setting */
83 { 0x15, 0x01 },
84 { 0x20, 0x1c },
85 { 0x23, 0x2a },
86 { 0x24, 0x10 },
87 { 0x25, 0x8a },
88 { 0x26, 0xa2 },
89 { 0x27, 0xc2 },
90 { 0x2a, 0x04 },
91 { 0x2c, 0xfe },
92 { 0x2d, 0x93 },
93 { 0x30, 0x71 },
94 { 0x31, 0x60 },
95 { 0x32, 0x26 },
96 { 0x33, 0x20 },
97 { 0x34, 0x48 },
98 { 0x12, 0x24 },
99 { 0x11, 0x01 },
100 { 0x0c, 0x24 },
101 { 0x0d, 0x24 },
102 { 0xff, 0xff }, /* END MARKER */
103};
104
105/* This initializes the OV7x10 camera chip and relevant variables. */
106static int ov7x10_init(struct i2c_client *c)
107{
108 struct ovcamchip *ov = i2c_get_clientdata(c);
109 struct ov7x10 *s;
110 int rc;
111
112 DDEBUG(4, &c->dev, "entered");
113
114 rc = ov_write_regvals(c, regvals_init_7x10);
115 if (rc < 0)
116 return rc;
117
118 ov->spriv = s = kmalloc(sizeof *s, GFP_KERNEL);
119 if (!s)
120 return -ENOMEM;
121 memset(s, 0, sizeof *s);
122
123 s->auto_brt = 1;
124 s->auto_exp = 1;
125
126 return rc;
127}
128
129static int ov7x10_free(struct i2c_client *c)
130{
131 struct ovcamchip *ov = i2c_get_clientdata(c);
132
133 kfree(ov->spriv);
134 return 0;
135}
136
137static int ov7x10_set_control(struct i2c_client *c,
138 struct ovcamchip_control *ctl)
139{
140 struct ovcamchip *ov = i2c_get_clientdata(c);
141 struct ov7x10 *s = ov->spriv;
142 int rc;
143 int v = ctl->value;
144
145 switch (ctl->id) {
146 case OVCAMCHIP_CID_CONT:
147 rc = ov_write(c, REG_CNT, v >> 8);
148 break;
149 case OVCAMCHIP_CID_BRIGHT:
150 rc = ov_write(c, REG_BRT, v >> 8);
151 break;
152 case OVCAMCHIP_CID_SAT:
153 rc = ov_write(c, REG_SAT, v >> 8);
154 break;
155 case OVCAMCHIP_CID_HUE:
156 rc = ov_write(c, REG_RED, 0xFF - (v >> 8));
157 if (rc < 0)
158 goto out;
159
160 rc = ov_write(c, REG_BLUE, v >> 8);
161 break;
162 case OVCAMCHIP_CID_EXP:
163 rc = ov_write(c, REG_EXP, v);
164 break;
165 case OVCAMCHIP_CID_FREQ:
166 {
167 int sixty = (v == 60);
168
169 rc = ov_write_mask(c, 0x2a, sixty?0x00:0x80, 0x80);
170 if (rc < 0)
171 goto out;
172
173 rc = ov_write(c, 0x2b, sixty?0x00:0xac);
174 if (rc < 0)
175 goto out;
176
177 rc = ov_write_mask(c, 0x13, 0x10, 0x10);
178 if (rc < 0)
179 goto out;
180
181 rc = ov_write_mask(c, 0x13, 0x00, 0x10);
182 break;
183 }
184 case OVCAMCHIP_CID_BANDFILT:
185 rc = ov_write_mask(c, 0x2d, v?0x04:0x00, 0x04);
186 s->bandfilt = v;
187 break;
188 case OVCAMCHIP_CID_AUTOBRIGHT:
189 rc = ov_write_mask(c, 0x2d, v?0x10:0x00, 0x10);
190 s->auto_brt = v;
191 break;
192 case OVCAMCHIP_CID_AUTOEXP:
193 rc = ov_write_mask(c, 0x29, v?0x00:0x80, 0x80);
194 s->auto_exp = v;
195 break;
196 case OVCAMCHIP_CID_MIRROR:
197 rc = ov_write_mask(c, 0x12, v?0x40:0x00, 0x40);
198 s->mirror = v;
199 break;
200 default:
201 DDEBUG(2, &c->dev, "control not supported: %d", ctl->id);
202 return -EPERM;
203 }
204
205out:
206 DDEBUG(3, &c->dev, "id=%d, arg=%d, rc=%d", ctl->id, v, rc);
207 return rc;
208}
209
210static int ov7x10_get_control(struct i2c_client *c,
211 struct ovcamchip_control *ctl)
212{
213 struct ovcamchip *ov = i2c_get_clientdata(c);
214 struct ov7x10 *s = ov->spriv;
215 int rc = 0;
216 unsigned char val = 0;
217
218 switch (ctl->id) {
219 case OVCAMCHIP_CID_CONT:
220 rc = ov_read(c, REG_CNT, &val);
221 ctl->value = val << 8;
222 break;
223 case OVCAMCHIP_CID_BRIGHT:
224 rc = ov_read(c, REG_BRT, &val);
225 ctl->value = val << 8;
226 break;
227 case OVCAMCHIP_CID_SAT:
228 rc = ov_read(c, REG_SAT, &val);
229 ctl->value = val << 8;
230 break;
231 case OVCAMCHIP_CID_HUE:
232 rc = ov_read(c, REG_BLUE, &val);
233 ctl->value = val << 8;
234 break;
235 case OVCAMCHIP_CID_EXP:
236 rc = ov_read(c, REG_EXP, &val);
237 ctl->value = val;
238 break;
239 case OVCAMCHIP_CID_BANDFILT:
240 ctl->value = s->bandfilt;
241 break;
242 case OVCAMCHIP_CID_AUTOBRIGHT:
243 ctl->value = s->auto_brt;
244 break;
245 case OVCAMCHIP_CID_AUTOEXP:
246 ctl->value = s->auto_exp;
247 break;
248 case OVCAMCHIP_CID_MIRROR:
249 ctl->value = s->mirror;
250 break;
251 default:
252 DDEBUG(2, &c->dev, "control not supported: %d", ctl->id);
253 return -EPERM;
254 }
255
256 DDEBUG(3, &c->dev, "id=%d, arg=%d, rc=%d", ctl->id, ctl->value, rc);
257 return rc;
258}
259
260static int ov7x10_mode_init(struct i2c_client *c, struct ovcamchip_window *win)
261{
262 int qvga = win->quarter;
263
264 /******** QVGA-specific regs ********/
265
266 ov_write(c, 0x14, qvga?0x24:0x04);
267
268 /******** Palette-specific regs ********/
269
270 if (win->format == VIDEO_PALETTE_GREY) {
271 ov_write_mask(c, 0x0e, 0x40, 0x40);
272 ov_write_mask(c, 0x13, 0x20, 0x20);
273 } else {
274 ov_write_mask(c, 0x0e, 0x00, 0x40);
275 ov_write_mask(c, 0x13, 0x00, 0x20);
276 }
277
278 /******** Clock programming ********/
279
280 ov_write(c, 0x11, win->clockdiv);
281
282 /******** Resolution-specific ********/
283
284 if (win->width == 640 && win->height == 480)
285 ov_write(c, 0x35, 0x9e);
286 else
287 ov_write(c, 0x35, 0x1e);
288
289 return 0;
290}
291
292static int ov7x10_set_window(struct i2c_client *c, struct ovcamchip_window *win)
293{
294 int ret, hwscale, vwscale;
295
296 ret = ov7x10_mode_init(c, win);
297 if (ret < 0)
298 return ret;
299
300 if (win->quarter) {
301 hwscale = 1;
302 vwscale = 0;
303 } else {
304 hwscale = 2;
305 vwscale = 1;
306 }
307
308 ov_write(c, 0x17, HWSBASE + (win->x >> hwscale));
309 ov_write(c, 0x18, HWEBASE + ((win->x + win->width) >> hwscale));
310 ov_write(c, 0x19, VWSBASE + (win->y >> vwscale));
311 ov_write(c, 0x1a, VWEBASE + ((win->y + win->height) >> vwscale));
312
313 return 0;
314}
315
316static int ov7x10_command(struct i2c_client *c, unsigned int cmd, void *arg)
317{
318 switch (cmd) {
319 case OVCAMCHIP_CMD_S_CTRL:
320 return ov7x10_set_control(c, arg);
321 case OVCAMCHIP_CMD_G_CTRL:
322 return ov7x10_get_control(c, arg);
323 case OVCAMCHIP_CMD_S_MODE:
324 return ov7x10_set_window(c, arg);
325 default:
326 DDEBUG(2, &c->dev, "command not supported: %d", cmd);
327 return -ENOIOCTLCMD;
328 }
329}
330
331struct ovcamchip_ops ov7x10_ops = {
332 .init = ov7x10_init,
333 .free = ov7x10_free,
334 .command = ov7x10_command,
335};
diff --git a/drivers/media/video/ovcamchip/ov7x20.c b/drivers/media/video/ovcamchip/ov7x20.c
new file mode 100644
index 00000000000..3c8c48f338b
--- /dev/null
+++ b/drivers/media/video/ovcamchip/ov7x20.c
@@ -0,0 +1,455 @@
1/* OmniVision OV7620/OV7120 Camera Chip Support Code
2 *
3 * Copyright (c) 1999-2004 Mark McClelland <mark@alpha.dyndns.org>
4 * http://alpha.dyndns.org/ov511/
5 *
6 * OV7620 fixes by Charl P. Botha <cpbotha@ieee.org>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version. NO WARRANTY OF ANY KIND is expressed or implied.
12 */
13
14#define DEBUG
15
16#include <linux/slab.h>
17#include "ovcamchip_priv.h"
18
19/* Registers */
20#define REG_GAIN 0x00 /* gain [5:0] */
21#define REG_BLUE 0x01 /* blue gain */
22#define REG_RED 0x02 /* red gain */
23#define REG_SAT 0x03 /* saturation */
24#define REG_BRT 0x06 /* Y brightness */
25#define REG_SHARP 0x07 /* analog sharpness */
26#define REG_BLUE_BIAS 0x0C /* WB blue ratio [5:0] */
27#define REG_RED_BIAS 0x0D /* WB red ratio [5:0] */
28#define REG_EXP 0x10 /* exposure */
29
30/* Default control settings. Values are in terms of V4L2 controls. */
31#define OV7120_DFL_BRIGHT 0x60
32#define OV7620_DFL_BRIGHT 0x60
33#define OV7120_DFL_SAT 0xb0
34#define OV7620_DFL_SAT 0xc0
35#define DFL_AUTO_EXP 1
36#define DFL_AUTO_GAIN 1
37#define OV7120_DFL_GAIN 0x00
38#define OV7620_DFL_GAIN 0x00
39/* NOTE: Since autoexposure is the default, these aren't programmed into the
40 * OV7x20 chip. They are just here because V4L2 expects a default */
41#define OV7120_DFL_EXP 0x7f
42#define OV7620_DFL_EXP 0x7f
43
44/* Window parameters */
45#define HWSBASE 0x2F /* From 7620.SET (spec is wrong) */
46#define HWEBASE 0x2F
47#define VWSBASE 0x05
48#define VWEBASE 0x05
49
50struct ov7x20 {
51 int auto_brt;
52 int auto_exp;
53 int auto_gain;
54 int backlight;
55 int bandfilt;
56 int mirror;
57};
58
59/* Contrast look-up table */
60static unsigned char ctab[] = {
61 0x01, 0x05, 0x09, 0x11, 0x15, 0x35, 0x37, 0x57,
62 0x5b, 0xa5, 0xa7, 0xc7, 0xc9, 0xcf, 0xef, 0xff
63};
64
65/* Settings for (Black & White) OV7120 camera chip */
66static struct ovcamchip_regvals regvals_init_7120[] = {
67 { 0x12, 0x80 }, /* reset */
68 { 0x13, 0x00 }, /* Autoadjust off */
69 { 0x12, 0x20 }, /* Disable AWB */
70 { 0x13, DFL_AUTO_GAIN?0x01:0x00 }, /* Autoadjust on (if desired) */
71 { 0x00, OV7120_DFL_GAIN },
72 { 0x01, 0x80 },
73 { 0x02, 0x80 },
74 { 0x03, OV7120_DFL_SAT },
75 { 0x06, OV7120_DFL_BRIGHT },
76 { 0x07, 0x00 },
77 { 0x0c, 0x20 },
78 { 0x0d, 0x20 },
79 { 0x11, 0x01 },
80 { 0x14, 0x84 },
81 { 0x15, 0x01 },
82 { 0x16, 0x03 },
83 { 0x17, 0x2f },
84 { 0x18, 0xcf },
85 { 0x19, 0x06 },
86 { 0x1a, 0xf5 },
87 { 0x1b, 0x00 },
88 { 0x20, 0x08 },
89 { 0x21, 0x80 },
90 { 0x22, 0x80 },
91 { 0x23, 0x00 },
92 { 0x26, 0xa0 },
93 { 0x27, 0xfa },
94 { 0x28, 0x20 }, /* DON'T set bit 6. It is for the OV7620 only */
95 { 0x29, DFL_AUTO_EXP?0x00:0x80 },
96 { 0x2a, 0x10 },
97 { 0x2b, 0x00 },
98 { 0x2c, 0x88 },
99 { 0x2d, 0x95 },
100 { 0x2e, 0x80 },
101 { 0x2f, 0x44 },
102 { 0x60, 0x20 },
103 { 0x61, 0x02 },
104 { 0x62, 0x5f },
105 { 0x63, 0xd5 },
106 { 0x64, 0x57 },
107 { 0x65, 0x83 }, /* OV says "don't change this value" */
108 { 0x66, 0x55 },
109 { 0x67, 0x92 },
110 { 0x68, 0xcf },
111 { 0x69, 0x76 },
112 { 0x6a, 0x22 },
113 { 0x6b, 0xe2 },
114 { 0x6c, 0x40 },
115 { 0x6d, 0x48 },
116 { 0x6e, 0x80 },
117 { 0x6f, 0x0d },
118 { 0x70, 0x89 },
119 { 0x71, 0x00 },
120 { 0x72, 0x14 },
121 { 0x73, 0x54 },
122 { 0x74, 0xa0 },
123 { 0x75, 0x8e },
124 { 0x76, 0x00 },
125 { 0x77, 0xff },
126 { 0x78, 0x80 },
127 { 0x79, 0x80 },
128 { 0x7a, 0x80 },
129 { 0x7b, 0xe6 },
130 { 0x7c, 0x00 },
131 { 0x24, 0x3a },
132 { 0x25, 0x60 },
133 { 0xff, 0xff }, /* END MARKER */
134};
135
136/* Settings for (color) OV7620 camera chip */
137static struct ovcamchip_regvals regvals_init_7620[] = {
138 { 0x12, 0x80 }, /* reset */
139 { 0x00, OV7620_DFL_GAIN },
140 { 0x01, 0x80 },
141 { 0x02, 0x80 },
142 { 0x03, OV7620_DFL_SAT },
143 { 0x06, OV7620_DFL_BRIGHT },
144 { 0x07, 0x00 },
145 { 0x0c, 0x24 },
146 { 0x0c, 0x24 },
147 { 0x0d, 0x24 },
148 { 0x11, 0x01 },
149 { 0x12, 0x24 },
150 { 0x13, DFL_AUTO_GAIN?0x01:0x00 },
151 { 0x14, 0x84 },
152 { 0x15, 0x01 },
153 { 0x16, 0x03 },
154 { 0x17, 0x2f },
155 { 0x18, 0xcf },
156 { 0x19, 0x06 },
157 { 0x1a, 0xf5 },
158 { 0x1b, 0x00 },
159 { 0x20, 0x18 },
160 { 0x21, 0x80 },
161 { 0x22, 0x80 },
162 { 0x23, 0x00 },
163 { 0x26, 0xa2 },
164 { 0x27, 0xea },
165 { 0x28, 0x20 },
166 { 0x29, DFL_AUTO_EXP?0x00:0x80 },
167 { 0x2a, 0x10 },
168 { 0x2b, 0x00 },
169 { 0x2c, 0x88 },
170 { 0x2d, 0x91 },
171 { 0x2e, 0x80 },
172 { 0x2f, 0x44 },
173 { 0x60, 0x27 },
174 { 0x61, 0x02 },
175 { 0x62, 0x5f },
176 { 0x63, 0xd5 },
177 { 0x64, 0x57 },
178 { 0x65, 0x83 },
179 { 0x66, 0x55 },
180 { 0x67, 0x92 },
181 { 0x68, 0xcf },
182 { 0x69, 0x76 },
183 { 0x6a, 0x22 },
184 { 0x6b, 0x00 },
185 { 0x6c, 0x02 },
186 { 0x6d, 0x44 },
187 { 0x6e, 0x80 },
188 { 0x6f, 0x1d },
189 { 0x70, 0x8b },
190 { 0x71, 0x00 },
191 { 0x72, 0x14 },
192 { 0x73, 0x54 },
193 { 0x74, 0x00 },
194 { 0x75, 0x8e },
195 { 0x76, 0x00 },
196 { 0x77, 0xff },
197 { 0x78, 0x80 },
198 { 0x79, 0x80 },
199 { 0x7a, 0x80 },
200 { 0x7b, 0xe2 },
201 { 0x7c, 0x00 },
202 { 0xff, 0xff }, /* END MARKER */
203};
204
205/* Returns index into the specified look-up table, with 'n' elements, for which
206 * the value is greater than or equal to "val". If a match isn't found, (n-1)
207 * is returned. The entries in the table must be in ascending order. */
208static inline int ov7x20_lut_find(unsigned char lut[], int n, unsigned char val)
209{
210 int i = 0;
211
212 while (lut[i] < val && i < n)
213 i++;
214
215 return i;
216}
217
218/* This initializes the OV7x20 camera chip and relevant variables. */
219static int ov7x20_init(struct i2c_client *c)
220{
221 struct ovcamchip *ov = i2c_get_clientdata(c);
222 struct ov7x20 *s;
223 int rc;
224
225 DDEBUG(4, &c->dev, "entered");
226
227 if (ov->mono)
228 rc = ov_write_regvals(c, regvals_init_7120);
229 else
230 rc = ov_write_regvals(c, regvals_init_7620);
231
232 if (rc < 0)
233 return rc;
234
235 ov->spriv = s = kmalloc(sizeof *s, GFP_KERNEL);
236 if (!s)
237 return -ENOMEM;
238 memset(s, 0, sizeof *s);
239
240 s->auto_brt = 1;
241 s->auto_exp = DFL_AUTO_EXP;
242 s->auto_gain = DFL_AUTO_GAIN;
243
244 return 0;
245}
246
247static int ov7x20_free(struct i2c_client *c)
248{
249 struct ovcamchip *ov = i2c_get_clientdata(c);
250
251 kfree(ov->spriv);
252 return 0;
253}
254
255static int ov7x20_set_v4l1_control(struct i2c_client *c,
256 struct ovcamchip_control *ctl)
257{
258 struct ovcamchip *ov = i2c_get_clientdata(c);
259 struct ov7x20 *s = ov->spriv;
260 int rc;
261 int v = ctl->value;
262
263 switch (ctl->id) {
264 case OVCAMCHIP_CID_CONT:
265 {
266 /* Use Y gamma control instead. Bit 0 enables it. */
267 rc = ov_write(c, 0x64, ctab[v >> 12]);
268 break;
269 }
270 case OVCAMCHIP_CID_BRIGHT:
271 /* 7620 doesn't like manual changes when in auto mode */
272 if (!s->auto_brt)
273 rc = ov_write(c, REG_BRT, v >> 8);
274 else
275 rc = 0;
276 break;
277 case OVCAMCHIP_CID_SAT:
278 rc = ov_write(c, REG_SAT, v >> 8);
279 break;
280 case OVCAMCHIP_CID_EXP:
281 if (!s->auto_exp)
282 rc = ov_write(c, REG_EXP, v);
283 else
284 rc = -EBUSY;
285 break;
286 case OVCAMCHIP_CID_FREQ:
287 {
288 int sixty = (v == 60);
289
290 rc = ov_write_mask(c, 0x2a, sixty?0x00:0x80, 0x80);
291 if (rc < 0)
292 goto out;
293
294 rc = ov_write(c, 0x2b, sixty?0x00:0xac);
295 if (rc < 0)
296 goto out;
297
298 rc = ov_write_mask(c, 0x76, 0x01, 0x01);
299 break;
300 }
301 case OVCAMCHIP_CID_BANDFILT:
302 rc = ov_write_mask(c, 0x2d, v?0x04:0x00, 0x04);
303 s->bandfilt = v;
304 break;
305 case OVCAMCHIP_CID_AUTOBRIGHT:
306 rc = ov_write_mask(c, 0x2d, v?0x10:0x00, 0x10);
307 s->auto_brt = v;
308 break;
309 case OVCAMCHIP_CID_AUTOEXP:
310 rc = ov_write_mask(c, 0x13, v?0x01:0x00, 0x01);
311 s->auto_exp = v;
312 break;
313 case OVCAMCHIP_CID_BACKLIGHT:
314 {
315 rc = ov_write_mask(c, 0x68, v?0xe0:0xc0, 0xe0);
316 if (rc < 0)
317 goto out;
318
319 rc = ov_write_mask(c, 0x29, v?0x08:0x00, 0x08);
320 if (rc < 0)
321 goto out;
322
323 rc = ov_write_mask(c, 0x28, v?0x02:0x00, 0x02);
324 s->backlight = v;
325 break;
326 }
327 case OVCAMCHIP_CID_MIRROR:
328 rc = ov_write_mask(c, 0x12, v?0x40:0x00, 0x40);
329 s->mirror = v;
330 break;
331 default:
332 DDEBUG(2, &c->dev, "control not supported: %d", ctl->id);
333 return -EPERM;
334 }
335
336out:
337 DDEBUG(3, &c->dev, "id=%d, arg=%d, rc=%d", ctl->id, v, rc);
338 return rc;
339}
340
341static int ov7x20_get_v4l1_control(struct i2c_client *c,
342 struct ovcamchip_control *ctl)
343{
344 struct ovcamchip *ov = i2c_get_clientdata(c);
345 struct ov7x20 *s = ov->spriv;
346 int rc = 0;
347 unsigned char val = 0;
348
349 switch (ctl->id) {
350 case OVCAMCHIP_CID_CONT:
351 rc = ov_read(c, 0x64, &val);
352 ctl->value = ov7x20_lut_find(ctab, 16, val) << 12;
353 break;
354 case OVCAMCHIP_CID_BRIGHT:
355 rc = ov_read(c, REG_BRT, &val);
356 ctl->value = val << 8;
357 break;
358 case OVCAMCHIP_CID_SAT:
359 rc = ov_read(c, REG_SAT, &val);
360 ctl->value = val << 8;
361 break;
362 case OVCAMCHIP_CID_EXP:
363 rc = ov_read(c, REG_EXP, &val);
364 ctl->value = val;
365 break;
366 case OVCAMCHIP_CID_BANDFILT:
367 ctl->value = s->bandfilt;
368 break;
369 case OVCAMCHIP_CID_AUTOBRIGHT:
370 ctl->value = s->auto_brt;
371 break;
372 case OVCAMCHIP_CID_AUTOEXP:
373 ctl->value = s->auto_exp;
374 break;
375 case OVCAMCHIP_CID_BACKLIGHT:
376 ctl->value = s->backlight;
377 break;
378 case OVCAMCHIP_CID_MIRROR:
379 ctl->value = s->mirror;
380 break;
381 default:
382 DDEBUG(2, &c->dev, "control not supported: %d", ctl->id);
383 return -EPERM;
384 }
385
386 DDEBUG(3, &c->dev, "id=%d, arg=%d, rc=%d", ctl->id, ctl->value, rc);
387 return rc;
388}
389
390static int ov7x20_mode_init(struct i2c_client *c, struct ovcamchip_window *win)
391{
392 struct ovcamchip *ov = i2c_get_clientdata(c);
393 int qvga = win->quarter;
394
395 /******** QVGA-specific regs ********/
396 ov_write_mask(c, 0x14, qvga?0x20:0x00, 0x20);
397 ov_write_mask(c, 0x28, qvga?0x00:0x20, 0x20);
398 ov_write(c, 0x24, qvga?0x20:0x3a);
399 ov_write(c, 0x25, qvga?0x30:0x60);
400 ov_write_mask(c, 0x2d, qvga?0x40:0x00, 0x40);
401 if (!ov->mono)
402 ov_write_mask(c, 0x67, qvga?0xf0:0x90, 0xf0);
403 ov_write_mask(c, 0x74, qvga?0x20:0x00, 0x20);
404
405 /******** Clock programming ********/
406
407 ov_write(c, 0x11, win->clockdiv);
408
409 return 0;
410}
411
412static int ov7x20_set_window(struct i2c_client *c, struct ovcamchip_window *win)
413{
414 int ret, hwscale, vwscale;
415
416 ret = ov7x20_mode_init(c, win);
417 if (ret < 0)
418 return ret;
419
420 if (win->quarter) {
421 hwscale = 1;
422 vwscale = 0;
423 } else {
424 hwscale = 2;
425 vwscale = 1;
426 }
427
428 ov_write(c, 0x17, HWSBASE + (win->x >> hwscale));
429 ov_write(c, 0x18, HWEBASE + ((win->x + win->width) >> hwscale));
430 ov_write(c, 0x19, VWSBASE + (win->y >> vwscale));
431 ov_write(c, 0x1a, VWEBASE + ((win->y + win->height) >> vwscale));
432
433 return 0;
434}
435
436static int ov7x20_command(struct i2c_client *c, unsigned int cmd, void *arg)
437{
438 switch (cmd) {
439 case OVCAMCHIP_CMD_S_CTRL:
440 return ov7x20_set_v4l1_control(c, arg);
441 case OVCAMCHIP_CMD_G_CTRL:
442 return ov7x20_get_v4l1_control(c, arg);
443 case OVCAMCHIP_CMD_S_MODE:
444 return ov7x20_set_window(c, arg);
445 default:
446 DDEBUG(2, &c->dev, "command not supported: %d", cmd);
447 return -ENOIOCTLCMD;
448 }
449}
450
451struct ovcamchip_ops ov7x20_ops = {
452 .init = ov7x20_init,
453 .free = ov7x20_free,
454 .command = ov7x20_command,
455};
diff --git a/drivers/media/video/ovcamchip/ovcamchip_core.c b/drivers/media/video/ovcamchip/ovcamchip_core.c
new file mode 100644
index 00000000000..54dd5612d3b
--- /dev/null
+++ b/drivers/media/video/ovcamchip/ovcamchip_core.c
@@ -0,0 +1,444 @@
1/* Shared Code for OmniVision Camera Chip Drivers
2 *
3 * Copyright (c) 2004 Mark McClelland <mark@alpha.dyndns.org>
4 * http://alpha.dyndns.org/ov511/
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. NO WARRANTY OF ANY KIND is expressed or implied.
10 */
11
12#define DEBUG
13
14#include <linux/init.h>
15#include <linux/module.h>
16#include <linux/moduleparam.h>
17#include <linux/slab.h>
18#include <linux/delay.h>
19#include "ovcamchip_priv.h"
20
21#define DRIVER_VERSION "v2.27 for Linux 2.6"
22#define DRIVER_AUTHOR "Mark McClelland <mark@alpha.dyndns.org>"
23#define DRIVER_DESC "OV camera chip I2C driver"
24
25#define PINFO(fmt, args...) printk(KERN_INFO "ovcamchip: " fmt "\n" , ## args);
26#define PERROR(fmt, args...) printk(KERN_ERR "ovcamchip: " fmt "\n" , ## args);
27
28#ifdef DEBUG
29int ovcamchip_debug = 0;
30static int debug;
31module_param(debug, int, 0);
32MODULE_PARM_DESC(debug,
33 "Debug level: 0=none, 1=inits, 2=warning, 3=config, 4=functions, 5=all");
34#endif
35
36/* By default, let bridge driver tell us if chip is monochrome. mono=0
37 * will ignore that and always treat chips as color. mono=1 will force
38 * monochrome mode for all chips. */
39static int mono = -1;
40module_param(mono, int, 0);
41MODULE_PARM_DESC(mono,
42 "1=chips are monochrome (OVx1xx), 0=force color, -1=autodetect (default)");
43
44MODULE_AUTHOR(DRIVER_AUTHOR);
45MODULE_DESCRIPTION(DRIVER_DESC);
46MODULE_LICENSE("GPL");
47
48/* Registers common to all chips, that are needed for detection */
49#define GENERIC_REG_ID_HIGH 0x1C /* manufacturer ID MSB */
50#define GENERIC_REG_ID_LOW 0x1D /* manufacturer ID LSB */
51#define GENERIC_REG_COM_I 0x29 /* misc ID bits */
52
53extern struct ovcamchip_ops ov6x20_ops;
54extern struct ovcamchip_ops ov6x30_ops;
55extern struct ovcamchip_ops ov7x10_ops;
56extern struct ovcamchip_ops ov7x20_ops;
57extern struct ovcamchip_ops ov76be_ops;
58
59static char *chip_names[NUM_CC_TYPES] = {
60 [CC_UNKNOWN] = "Unknown chip",
61 [CC_OV76BE] = "OV76BE",
62 [CC_OV7610] = "OV7610",
63 [CC_OV7620] = "OV7620",
64 [CC_OV7620AE] = "OV7620AE",
65 [CC_OV6620] = "OV6620",
66 [CC_OV6630] = "OV6630",
67 [CC_OV6630AE] = "OV6630AE",
68 [CC_OV6630AF] = "OV6630AF",
69};
70
71/* Forward declarations */
72static struct i2c_driver driver;
73static struct i2c_client client_template;
74
75/* ----------------------------------------------------------------------- */
76
77int ov_write_regvals(struct i2c_client *c, struct ovcamchip_regvals *rvals)
78{
79 int rc;
80
81 while (rvals->reg != 0xff) {
82 rc = ov_write(c, rvals->reg, rvals->val);
83 if (rc < 0)
84 return rc;
85 rvals++;
86 }
87
88 return 0;
89}
90
91/* Writes bits at positions specified by mask to an I2C reg. Bits that are in
92 * the same position as 1's in "mask" are cleared and set to "value". Bits
93 * that are in the same position as 0's in "mask" are preserved, regardless
94 * of their respective state in "value".
95 */
96int ov_write_mask(struct i2c_client *c,
97 unsigned char reg,
98 unsigned char value,
99 unsigned char mask)
100{
101 int rc;
102 unsigned char oldval, newval;
103
104 if (mask == 0xff) {
105 newval = value;
106 } else {
107 rc = ov_read(c, reg, &oldval);
108 if (rc < 0)
109 return rc;
110
111 oldval &= (~mask); /* Clear the masked bits */
112 value &= mask; /* Enforce mask on value */
113 newval = oldval | value; /* Set the desired bits */
114 }
115
116 return ov_write(c, reg, newval);
117}
118
119/* ----------------------------------------------------------------------- */
120
121/* Reset the chip and ensure that I2C is synchronized. Returns <0 if failure.
122 */
123static int init_camchip(struct i2c_client *c)
124{
125 int i, success;
126 unsigned char high, low;
127
128 /* Reset the chip */
129 ov_write(c, 0x12, 0x80);
130
131 /* Wait for it to initialize */
132 msleep(150);
133
134 for (i = 0, success = 0; i < I2C_DETECT_RETRIES && !success; i++) {
135 if (ov_read(c, GENERIC_REG_ID_HIGH, &high) >= 0) {
136 if (ov_read(c, GENERIC_REG_ID_LOW, &low) >= 0) {
137 if (high == 0x7F && low == 0xA2) {
138 success = 1;
139 continue;
140 }
141 }
142 }
143
144 /* Reset the chip */
145 ov_write(c, 0x12, 0x80);
146
147 /* Wait for it to initialize */
148 msleep(150);
149
150 /* Dummy read to sync I2C */
151 ov_read(c, 0x00, &low);
152 }
153
154 if (!success)
155 return -EIO;
156
157 PDEBUG(1, "I2C synced in %d attempt(s)", i);
158
159 return 0;
160}
161
162/* This detects the OV7610, OV7620, or OV76BE chip. */
163static int ov7xx0_detect(struct i2c_client *c)
164{
165 struct ovcamchip *ov = i2c_get_clientdata(c);
166 int rc;
167 unsigned char val;
168
169 PDEBUG(4, "");
170
171 /* Detect chip (sub)type */
172 rc = ov_read(c, GENERIC_REG_COM_I, &val);
173 if (rc < 0) {
174 PERROR("Error detecting ov7xx0 type");
175 return rc;
176 }
177
178 if ((val & 3) == 3) {
179 PINFO("Camera chip is an OV7610");
180 ov->subtype = CC_OV7610;
181 } else if ((val & 3) == 1) {
182 rc = ov_read(c, 0x15, &val);
183 if (rc < 0) {
184 PERROR("Error detecting ov7xx0 type");
185 return rc;
186 }
187
188 if (val & 1) {
189 PINFO("Camera chip is an OV7620AE");
190 /* OV7620 is a close enough match for now. There are
191 * some definite differences though, so this should be
192 * fixed */
193 ov->subtype = CC_OV7620;
194 } else {
195 PINFO("Camera chip is an OV76BE");
196 ov->subtype = CC_OV76BE;
197 }
198 } else if ((val & 3) == 0) {
199 PINFO("Camera chip is an OV7620");
200 ov->subtype = CC_OV7620;
201 } else {
202 PERROR("Unknown camera chip version: %d", val & 3);
203 return -ENOSYS;
204 }
205
206 if (ov->subtype == CC_OV76BE)
207 ov->sops = &ov76be_ops;
208 else if (ov->subtype == CC_OV7620)
209 ov->sops = &ov7x20_ops;
210 else
211 ov->sops = &ov7x10_ops;
212
213 return 0;
214}
215
216/* This detects the OV6620, OV6630, OV6630AE, or OV6630AF chip. */
217static int ov6xx0_detect(struct i2c_client *c)
218{
219 struct ovcamchip *ov = i2c_get_clientdata(c);
220 int rc;
221 unsigned char val;
222
223 PDEBUG(4, "");
224
225 /* Detect chip (sub)type */
226 rc = ov_read(c, GENERIC_REG_COM_I, &val);
227 if (rc < 0) {
228 PERROR("Error detecting ov6xx0 type");
229 return -1;
230 }
231
232 if ((val & 3) == 0) {
233 ov->subtype = CC_OV6630;
234 PINFO("Camera chip is an OV6630");
235 } else if ((val & 3) == 1) {
236 ov->subtype = CC_OV6620;
237 PINFO("Camera chip is an OV6620");
238 } else if ((val & 3) == 2) {
239 ov->subtype = CC_OV6630;
240 PINFO("Camera chip is an OV6630AE");
241 } else if ((val & 3) == 3) {
242 ov->subtype = CC_OV6630;
243 PINFO("Camera chip is an OV6630AF");
244 }
245
246 if (ov->subtype == CC_OV6620)
247 ov->sops = &ov6x20_ops;
248 else
249 ov->sops = &ov6x30_ops;
250
251 return 0;
252}
253
254static int ovcamchip_detect(struct i2c_client *c)
255{
256 /* Ideally we would just try a single register write and see if it NAKs.
257 * That isn't possible since the OV518 can't report I2C transaction
258 * failures. So, we have to try to initialize the chip (i.e. reset it
259 * and check the ID registers) to detect its presence. */
260
261 /* Test for 7xx0 */
262 PDEBUG(3, "Testing for 0V7xx0");
263 c->addr = OV7xx0_SID;
264 if (init_camchip(c) < 0) {
265 /* Test for 6xx0 */
266 PDEBUG(3, "Testing for 0V6xx0");
267 c->addr = OV6xx0_SID;
268 if (init_camchip(c) < 0) {
269 return -ENODEV;
270 } else {
271 if (ov6xx0_detect(c) < 0) {
272 PERROR("Failed to init OV6xx0");
273 return -EIO;
274 }
275 }
276 } else {
277 if (ov7xx0_detect(c) < 0) {
278 PERROR("Failed to init OV7xx0");
279 return -EIO;
280 }
281 }
282
283 return 0;
284}
285
286/* ----------------------------------------------------------------------- */
287
288static int ovcamchip_attach(struct i2c_adapter *adap)
289{
290 int rc = 0;
291 struct ovcamchip *ov;
292 struct i2c_client *c;
293
294 /* I2C is not a PnP bus, so we can never be certain that we're talking
295 * to the right chip. To prevent damage to EEPROMS and such, only
296 * attach to adapters that are known to contain OV camera chips. */
297
298 switch (adap->id) {
299 case (I2C_ALGO_SMBUS | I2C_HW_SMBUS_OV511):
300 case (I2C_ALGO_SMBUS | I2C_HW_SMBUS_OV518):
301 case (I2C_ALGO_SMBUS | I2C_HW_SMBUS_OVFX2):
302 case (I2C_ALGO_SMBUS | I2C_HW_SMBUS_W9968CF):
303 PDEBUG(1, "Adapter ID 0x%06x accepted", adap->id);
304 break;
305 default:
306 PDEBUG(1, "Adapter ID 0x%06x rejected", adap->id);
307 return -ENODEV;
308 }
309
310 c = kmalloc(sizeof *c, GFP_KERNEL);
311 if (!c) {
312 rc = -ENOMEM;
313 goto no_client;
314 }
315 memcpy(c, &client_template, sizeof *c);
316 c->adapter = adap;
317 strcpy(i2c_clientname(c), "OV????");
318
319 ov = kmalloc(sizeof *ov, GFP_KERNEL);
320 if (!ov) {
321 rc = -ENOMEM;
322 goto no_ov;
323 }
324 memset(ov, 0, sizeof *ov);
325 i2c_set_clientdata(c, ov);
326
327 rc = ovcamchip_detect(c);
328 if (rc < 0)
329 goto error;
330
331 strcpy(i2c_clientname(c), chip_names[ov->subtype]);
332
333 PDEBUG(1, "Camera chip detection complete");
334
335 i2c_attach_client(c);
336
337 return rc;
338error:
339 kfree(ov);
340no_ov:
341 kfree(c);
342no_client:
343 PDEBUG(1, "returning %d", rc);
344 return rc;
345}
346
347static int ovcamchip_detach(struct i2c_client *c)
348{
349 struct ovcamchip *ov = i2c_get_clientdata(c);
350 int rc;
351
352 rc = ov->sops->free(c);
353 if (rc < 0)
354 return rc;
355
356 i2c_detach_client(c);
357
358 kfree(ov);
359 kfree(c);
360 return 0;
361}
362
363static int ovcamchip_command(struct i2c_client *c, unsigned int cmd, void *arg)
364{
365 struct ovcamchip *ov = i2c_get_clientdata(c);
366
367 if (!ov->initialized &&
368 cmd != OVCAMCHIP_CMD_Q_SUBTYPE &&
369 cmd != OVCAMCHIP_CMD_INITIALIZE) {
370 dev_err(&c->dev, "ERROR: Camera chip not initialized yet!\n");
371 return -EPERM;
372 }
373
374 switch (cmd) {
375 case OVCAMCHIP_CMD_Q_SUBTYPE:
376 {
377 *(int *)arg = ov->subtype;
378 return 0;
379 }
380 case OVCAMCHIP_CMD_INITIALIZE:
381 {
382 int rc;
383
384 if (mono == -1)
385 ov->mono = *(int *)arg;
386 else
387 ov->mono = mono;
388
389 if (ov->mono) {
390 if (ov->subtype != CC_OV7620)
391 dev_warn(&c->dev, "Warning: Monochrome not "
392 "implemented for this chip\n");
393 else
394 dev_info(&c->dev, "Initializing chip as "
395 "monochrome\n");
396 }
397
398 rc = ov->sops->init(c);
399 if (rc < 0)
400 return rc;
401
402 ov->initialized = 1;
403 return 0;
404 }
405 default:
406 return ov->sops->command(c, cmd, arg);
407 }
408}
409
410/* ----------------------------------------------------------------------- */
411
412static struct i2c_driver driver = {
413 .owner = THIS_MODULE,
414 .name = "ovcamchip",
415 .id = I2C_DRIVERID_OVCAMCHIP,
416 .class = I2C_CLASS_CAM_DIGITAL,
417 .flags = I2C_DF_NOTIFY,
418 .attach_adapter = ovcamchip_attach,
419 .detach_client = ovcamchip_detach,
420 .command = ovcamchip_command,
421};
422
423static struct i2c_client client_template = {
424 I2C_DEVNAME("(unset)"),
425 .driver = &driver,
426};
427
428static int __init ovcamchip_init(void)
429{
430#ifdef DEBUG
431 ovcamchip_debug = debug;
432#endif
433
434 PINFO(DRIVER_VERSION " : " DRIVER_DESC);
435 return i2c_add_driver(&driver);
436}
437
438static void __exit ovcamchip_exit(void)
439{
440 i2c_del_driver(&driver);
441}
442
443module_init(ovcamchip_init);
444module_exit(ovcamchip_exit);
diff --git a/drivers/media/video/ovcamchip/ovcamchip_priv.h b/drivers/media/video/ovcamchip/ovcamchip_priv.h
new file mode 100644
index 00000000000..575e612a554
--- /dev/null
+++ b/drivers/media/video/ovcamchip/ovcamchip_priv.h
@@ -0,0 +1,87 @@
1/* OmniVision* camera chip driver private definitions for core code and
2 * chip-specific code
3 *
4 * Copyright (c) 1999-2004 Mark McClelland
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. NO WARRANTY OF ANY KIND is expressed or implied.
10 *
11 * * OmniVision is a trademark of OmniVision Technologies, Inc. This driver
12 * is not sponsored or developed by them.
13 */
14
15#ifndef __LINUX_OVCAMCHIP_PRIV_H
16#define __LINUX_OVCAMCHIP_PRIV_H
17
18#include <media/ovcamchip.h>
19
20#ifdef DEBUG
21extern int ovcamchip_debug;
22#endif
23
24#define PDEBUG(level, fmt, args...) \
25 if (ovcamchip_debug >= (level)) pr_debug("[%s:%d] " fmt "\n", \
26 __FUNCTION__, __LINE__ , ## args)
27
28#define DDEBUG(level, dev, fmt, args...) \
29 if (ovcamchip_debug >= (level)) dev_dbg(dev, "[%s:%d] " fmt "\n", \
30 __FUNCTION__, __LINE__ , ## args)
31
32/* Number of times to retry chip detection. Increase this if you are getting
33 * "Failed to init camera chip" */
34#define I2C_DETECT_RETRIES 10
35
36struct ovcamchip_regvals {
37 unsigned char reg;
38 unsigned char val;
39};
40
41struct ovcamchip_ops {
42 int (*init)(struct i2c_client *);
43 int (*free)(struct i2c_client *);
44 int (*command)(struct i2c_client *, unsigned int, void *);
45};
46
47struct ovcamchip {
48 struct ovcamchip_ops *sops;
49 void *spriv; /* Private data for OV7x10.c etc... */
50 int subtype; /* = SEN_OV7610 etc... */
51 int mono; /* Monochrome chip? (invalid until init) */
52 int initialized; /* OVCAMCHIP_CMD_INITIALIZE was successful */
53};
54
55/* --------------------------------- */
56/* I2C I/O */
57/* --------------------------------- */
58
59static inline int ov_read(struct i2c_client *c, unsigned char reg,
60 unsigned char *value)
61{
62 int rc;
63
64 rc = i2c_smbus_read_byte_data(c, reg);
65 *value = (unsigned char) rc;
66 return rc;
67}
68
69static inline int ov_write(struct i2c_client *c, unsigned char reg,
70 unsigned char value )
71{
72 return i2c_smbus_write_byte_data(c, reg, value);
73}
74
75/* --------------------------------- */
76/* FUNCTION PROTOTYPES */
77/* --------------------------------- */
78
79/* Functions in ovcamchip_core.c */
80
81extern int ov_write_regvals(struct i2c_client *c,
82 struct ovcamchip_regvals *rvals);
83
84extern int ov_write_mask(struct i2c_client *c, unsigned char reg,
85 unsigned char value, unsigned char mask);
86
87#endif
diff --git a/drivers/media/video/planb.c b/drivers/media/video/planb.c
new file mode 100644
index 00000000000..b19c33434ea
--- /dev/null
+++ b/drivers/media/video/planb.c
@@ -0,0 +1,2303 @@
1/*
2 planb - PlanB frame grabber driver
3
4 PlanB is used in the 7x00/8x00 series of PowerMacintosh
5 Computers as video input DMA controller.
6
7 Copyright (C) 1998 Michel Lanners (mlan@cpu.lu)
8
9 Based largely on the bttv driver by Ralph Metzler (rjkm@thp.uni-koeln.de)
10
11 Additional debugging and coding by Takashi Oe (toe@unlserve.unl.edu)
12
13 This program is free software; you can redistribute it and/or modify
14 it under the terms of the GNU General Public License as published by
15 the Free Software Foundation; either version 2 of the License, or
16 (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26*/
27
28/* $Id: planb.c,v 1.18 1999/05/02 17:36:34 mlan Exp $ */
29
30#include <linux/init.h>
31#include <linux/errno.h>
32#include <linux/module.h>
33#include <linux/kernel.h>
34#include <linux/major.h>
35#include <linux/slab.h>
36#include <linux/types.h>
37#include <linux/pci.h>
38#include <linux/delay.h>
39#include <linux/vmalloc.h>
40#include <linux/mm.h>
41#include <linux/sched.h>
42#include <linux/videodev.h>
43#include <linux/wait.h>
44#include <asm/uaccess.h>
45#include <asm/io.h>
46#include <asm/prom.h>
47#include <asm/dbdma.h>
48#include <asm/pgtable.h>
49#include <asm/page.h>
50#include <asm/irq.h>
51#include <asm/semaphore.h>
52
53#include "planb.h"
54#include "saa7196.h"
55
56/* Would you mind for some ugly debugging? */
57#if 0
58#define DEBUG(x...) printk(KERN_DEBUG ## x) /* Debug driver */
59#else
60#define DEBUG(x...) /* Don't debug driver */
61#endif
62
63#if 0
64#define IDEBUG(x...) printk(KERN_DEBUG ## x) /* Debug interrupt part */
65#else
66#define IDEBUG(x...) /* Don't debug interrupt part */
67#endif
68
69/* Ever seen a Mac with more than 1 of these? */
70#define PLANB_MAX 1
71
72static int planb_num;
73static struct planb planbs[PLANB_MAX];
74static volatile struct planb_registers *planb_regs;
75
76static int def_norm = PLANB_DEF_NORM; /* default norm */
77static int video_nr = -1;
78
79MODULE_PARM(def_norm, "i");
80MODULE_PARM_DESC(def_norm, "Default startup norm (0=PAL, 1=NTSC, 2=SECAM)");
81MODULE_PARM(video_nr,"i");
82MODULE_LICENSE("GPL");
83
84
85/* ------------------ PlanB Exported Functions ------------------ */
86static long planb_write(struct video_device *, const char *, unsigned long, int);
87static long planb_read(struct video_device *, char *, unsigned long, int);
88static int planb_open(struct video_device *, int);
89static void planb_close(struct video_device *);
90static int planb_ioctl(struct video_device *, unsigned int, void *);
91static int planb_init_done(struct video_device *);
92static int planb_mmap(struct video_device *, const char *, unsigned long);
93static void planb_irq(int, void *, struct pt_regs *);
94static void release_planb(void);
95int init_planbs(struct video_init *);
96
97/* ------------------ PlanB Internal Functions ------------------ */
98static int planb_prepare_open(struct planb *);
99static void planb_prepare_close(struct planb *);
100static void saa_write_reg(unsigned char, unsigned char);
101static unsigned char saa_status(int, struct planb *);
102static void saa_set(unsigned char, unsigned char, struct planb *);
103static void saa_init_regs(struct planb *);
104static int grabbuf_alloc(struct planb *);
105static int vgrab(struct planb *, struct video_mmap *);
106static void add_clip(struct planb *, struct video_clip *);
107static void fill_cmd_buff(struct planb *);
108static void cmd_buff(struct planb *);
109static volatile struct dbdma_cmd *setup_grab_cmd(int, struct planb *);
110static void overlay_start(struct planb *);
111static void overlay_stop(struct planb *);
112static inline void tab_cmd_dbdma(volatile struct dbdma_cmd *, unsigned short,
113 unsigned int);
114static inline void tab_cmd_store(volatile struct dbdma_cmd *, unsigned int,
115 unsigned int);
116static inline void tab_cmd_gen(volatile struct dbdma_cmd *, unsigned short,
117 unsigned short, unsigned int, unsigned int);
118static int init_planb(struct planb *);
119static int find_planb(void);
120static void planb_pre_capture(int, int, struct planb *);
121static volatile struct dbdma_cmd *cmd_geo_setup(volatile struct dbdma_cmd *,
122 int, int, int, int, int, struct planb *);
123static inline void planb_dbdma_stop(volatile struct dbdma_regs *);
124static unsigned int saa_geo_setup(int, int, int, int, struct planb *);
125static inline int overlay_is_active(struct planb *);
126
127/*******************************/
128/* Memory management functions */
129/*******************************/
130
131static int grabbuf_alloc(struct planb *pb)
132{
133 int i, npage;
134
135 npage = MAX_GBUFFERS * ((PLANB_MAX_FBUF / PAGE_SIZE + 1)
136#ifndef PLANB_GSCANLINE
137 + MAX_LNUM
138#endif /* PLANB_GSCANLINE */
139 );
140 if ((pb->rawbuf = (unsigned char**) kmalloc (npage
141 * sizeof(unsigned long), GFP_KERNEL)) == 0)
142 return -ENOMEM;
143 for (i = 0; i < npage; i++) {
144 pb->rawbuf[i] = (unsigned char *)__get_free_pages(GFP_KERNEL
145 |GFP_DMA, 0);
146 if (!pb->rawbuf[i])
147 break;
148 SetPageReserved(virt_to_page(pb->rawbuf[i]));
149 }
150 if (i-- < npage) {
151 printk(KERN_DEBUG "PlanB: init_grab: grab buffer not allocated\n");
152 for (; i > 0; i--) {
153 ClearPageReserved(virt_to_page(pb->rawbuf[i]));
154 free_pages((unsigned long)pb->rawbuf[i], 0);
155 }
156 kfree(pb->rawbuf);
157 return -ENOBUFS;
158 }
159 pb->rawbuf_size = npage;
160 return 0;
161}
162
163/*****************************/
164/* Hardware access functions */
165/*****************************/
166
167static void saa_write_reg(unsigned char addr, unsigned char val)
168{
169 planb_regs->saa_addr = addr; eieio();
170 planb_regs->saa_regval = val; eieio();
171 return;
172}
173
174/* return status byte 0 or 1: */
175static unsigned char saa_status(int byte, struct planb *pb)
176{
177 saa_regs[pb->win.norm][SAA7196_STDC] =
178 (saa_regs[pb->win.norm][SAA7196_STDC] & ~2) | ((byte & 1) << 1);
179 saa_write_reg (SAA7196_STDC, saa_regs[pb->win.norm][SAA7196_STDC]);
180
181 /* Let's wait 30msec for this one */
182 msleep_interruptible(30);
183
184 return (unsigned char)in_8 (&planb_regs->saa_status);
185}
186
187static void saa_set(unsigned char addr, unsigned char val, struct planb *pb)
188{
189 if(saa_regs[pb->win.norm][addr] != val) {
190 saa_regs[pb->win.norm][addr] = val;
191 saa_write_reg (addr, val);
192 }
193 return;
194}
195
196static void saa_init_regs(struct planb *pb)
197{
198 int i;
199
200 for (i = 0; i < SAA7196_NUMREGS; i++)
201 saa_write_reg (i, saa_regs[pb->win.norm][i]);
202}
203
204static unsigned int saa_geo_setup(int width, int height, int interlace, int bpp,
205 struct planb *pb)
206{
207 int ht, norm = pb->win.norm;
208
209 switch(bpp) {
210 case 2:
211 /* RGB555+a 1x16-bit + 16-bit transparent */
212 saa_regs[norm][SAA7196_FMTS] &= ~0x3;
213 break;
214 case 1:
215 case 4:
216 /* RGB888 1x24-bit + 8-bit transparent */
217 saa_regs[norm][SAA7196_FMTS] &= ~0x1;
218 saa_regs[norm][SAA7196_FMTS] |= 0x2;
219 break;
220 default:
221 return -EINVAL;
222 }
223 ht = (interlace ? height / 2 : height);
224 saa_regs[norm][SAA7196_OUTPIX] = (unsigned char) (width & 0x00ff);
225 saa_regs[norm][SAA7196_HFILT] = (saa_regs[norm][SAA7196_HFILT] & ~0x3)
226 | (width >> 8 & 0x3);
227 saa_regs[norm][SAA7196_OUTLINE] = (unsigned char) (ht & 0xff);
228 saa_regs[norm][SAA7196_VYP] = (saa_regs[norm][SAA7196_VYP] & ~0x3)
229 | (ht >> 8 & 0x3);
230 /* feed both fields if interlaced, or else feed only even fields */
231 saa_regs[norm][SAA7196_FMTS] = (interlace) ?
232 (saa_regs[norm][SAA7196_FMTS] & ~0x60)
233 : (saa_regs[norm][SAA7196_FMTS] | 0x60);
234 /* transparent mode; extended format enabled */
235 saa_regs[norm][SAA7196_DPATH] |= 0x3;
236
237 return 0;
238}
239
240/***************************/
241/* DBDMA support functions */
242/***************************/
243
244static inline void planb_dbdma_restart(volatile struct dbdma_regs *ch)
245{
246 out_le32(&ch->control, PLANB_CLR(RUN));
247 out_le32(&ch->control, PLANB_SET(RUN|WAKE) | PLANB_CLR(PAUSE));
248}
249
250static inline void planb_dbdma_stop(volatile struct dbdma_regs *ch)
251{
252 int i = 0;
253
254 out_le32(&ch->control, PLANB_CLR(RUN) | PLANB_SET(FLUSH));
255 while((in_le32(&ch->status) == (ACTIVE | FLUSH)) && (i < 999)) {
256 IDEBUG("PlanB: waiting for DMA to stop\n");
257 i++;
258 }
259}
260
261static inline void tab_cmd_dbdma(volatile struct dbdma_cmd *ch,
262 unsigned short command, unsigned int cmd_dep)
263{
264 st_le16(&ch->command, command);
265 st_le32(&ch->cmd_dep, cmd_dep);
266}
267
268static inline void tab_cmd_store(volatile struct dbdma_cmd *ch,
269 unsigned int phy_addr, unsigned int cmd_dep)
270{
271 st_le16(&ch->command, STORE_WORD | KEY_SYSTEM);
272 st_le16(&ch->req_count, 4);
273 st_le32(&ch->phy_addr, phy_addr);
274 st_le32(&ch->cmd_dep, cmd_dep);
275}
276
277static inline void tab_cmd_gen(volatile struct dbdma_cmd *ch,
278 unsigned short command, unsigned short req_count,
279 unsigned int phy_addr, unsigned int cmd_dep)
280{
281 st_le16(&ch->command, command);
282 st_le16(&ch->req_count, req_count);
283 st_le32(&ch->phy_addr, phy_addr);
284 st_le32(&ch->cmd_dep, cmd_dep);
285}
286
287static volatile struct dbdma_cmd *cmd_geo_setup(
288 volatile struct dbdma_cmd *c1, int width, int height, int interlace,
289 int bpp, int clip, struct planb *pb)
290{
291 int norm = pb->win.norm;
292
293 if((saa_geo_setup(width, height, interlace, bpp, pb)) != 0)
294 return (volatile struct dbdma_cmd *)NULL;
295 tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_addr),
296 SAA7196_FMTS);
297 tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_regval),
298 saa_regs[norm][SAA7196_FMTS]);
299 tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_addr),
300 SAA7196_DPATH);
301 tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_regval),
302 saa_regs[norm][SAA7196_DPATH]);
303 tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->even),
304 bpp | ((clip)? PLANB_CLIPMASK: 0));
305 tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->odd),
306 bpp | ((clip)? PLANB_CLIPMASK: 0));
307 tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_addr),
308 SAA7196_OUTPIX);
309 tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_regval),
310 saa_regs[norm][SAA7196_OUTPIX]);
311 tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_addr),
312 SAA7196_HFILT);
313 tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_regval),
314 saa_regs[norm][SAA7196_HFILT]);
315 tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_addr),
316 SAA7196_OUTLINE);
317 tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_regval),
318 saa_regs[norm][SAA7196_OUTLINE]);
319 tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_addr),
320 SAA7196_VYP);
321 tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_regval),
322 saa_regs[norm][SAA7196_VYP]);
323 return c1;
324}
325
326/******************************/
327/* misc. supporting functions */
328/******************************/
329
330static inline void planb_lock(struct planb *pb)
331{
332 down(&pb->lock);
333}
334
335static inline void planb_unlock(struct planb *pb)
336{
337 up(&pb->lock);
338}
339
340/***************/
341/* Driver Core */
342/***************/
343
344static int planb_prepare_open(struct planb *pb)
345{
346 int i, size;
347
348 /* allocate memory for two plus alpha command buffers (size: max lines,
349 plus 40 commands handling, plus 1 alignment), plus dummy command buf,
350 plus clipmask buffer, plus frame grabbing status */
351 size = (pb->tab_size*(2+MAX_GBUFFERS*TAB_FACTOR)+1+MAX_GBUFFERS
352 * PLANB_DUMMY)*sizeof(struct dbdma_cmd)
353 +(PLANB_MAXLINES*((PLANB_MAXPIXELS+7)& ~7))/8
354 +MAX_GBUFFERS*sizeof(unsigned int);
355 if ((pb->priv_space = kmalloc (size, GFP_KERNEL)) == 0)
356 return -ENOMEM;
357 memset ((void *) pb->priv_space, 0, size);
358 pb->overlay_last1 = pb->ch1_cmd = (volatile struct dbdma_cmd *)
359 DBDMA_ALIGN (pb->priv_space);
360 pb->overlay_last2 = pb->ch2_cmd = pb->ch1_cmd + pb->tab_size;
361 pb->ch1_cmd_phys = virt_to_bus(pb->ch1_cmd);
362 pb->cap_cmd[0] = pb->ch2_cmd + pb->tab_size;
363 pb->pre_cmd[0] = pb->cap_cmd[0] + pb->tab_size * TAB_FACTOR;
364 for (i = 1; i < MAX_GBUFFERS; i++) {
365 pb->cap_cmd[i] = pb->pre_cmd[i-1] + PLANB_DUMMY;
366 pb->pre_cmd[i] = pb->cap_cmd[i] + pb->tab_size * TAB_FACTOR;
367 }
368 pb->frame_stat=(volatile unsigned int *)(pb->pre_cmd[MAX_GBUFFERS-1]
369 + PLANB_DUMMY);
370 pb->mask = (unsigned char *)(pb->frame_stat+MAX_GBUFFERS);
371
372 pb->rawbuf = NULL;
373 pb->rawbuf_size = 0;
374 pb->grabbing = 0;
375 for (i = 0; i < MAX_GBUFFERS; i++) {
376 pb->frame_stat[i] = GBUFFER_UNUSED;
377 pb->gwidth[i] = 0;
378 pb->gheight[i] = 0;
379 pb->gfmt[i] = 0;
380 pb->gnorm_switch[i] = 0;
381#ifndef PLANB_GSCANLINE
382 pb->lsize[i] = 0;
383 pb->lnum[i] = 0;
384#endif /* PLANB_GSCANLINE */
385 }
386 pb->gcount = 0;
387 pb->suspend = 0;
388 pb->last_fr = -999;
389 pb->prev_last_fr = -999;
390
391 /* Reset DMA controllers */
392 planb_dbdma_stop(&pb->planb_base->ch2);
393 planb_dbdma_stop(&pb->planb_base->ch1);
394
395 return 0;
396}
397
398static void planb_prepare_close(struct planb *pb)
399{
400 int i;
401
402 /* make sure the dma's are idle */
403 planb_dbdma_stop(&pb->planb_base->ch2);
404 planb_dbdma_stop(&pb->planb_base->ch1);
405 /* free kernel memory of command buffers */
406 if(pb->priv_space != 0) {
407 kfree (pb->priv_space);
408 pb->priv_space = 0;
409 pb->cmd_buff_inited = 0;
410 }
411 if(pb->rawbuf) {
412 for (i = 0; i < pb->rawbuf_size; i++) {
413 ClearPageReserved(virt_to_page(pb->rawbuf[i]));
414 free_pages((unsigned long)pb->rawbuf[i], 0);
415 }
416 kfree(pb->rawbuf);
417 }
418 pb->rawbuf = NULL;
419}
420
421/*****************************/
422/* overlay support functions */
423/*****************************/
424
425static inline int overlay_is_active(struct planb *pb)
426{
427 unsigned int size = pb->tab_size * sizeof(struct dbdma_cmd);
428 unsigned int caddr = (unsigned)in_le32(&pb->planb_base->ch1.cmdptr);
429
430 return (in_le32(&pb->overlay_last1->cmd_dep) == pb->ch1_cmd_phys)
431 && (caddr < (pb->ch1_cmd_phys + size))
432 && (caddr >= (unsigned)pb->ch1_cmd_phys);
433}
434
435static void overlay_start(struct planb *pb)
436{
437
438 DEBUG("PlanB: overlay_start()\n");
439
440 if(ACTIVE & in_le32(&pb->planb_base->ch1.status)) {
441
442 DEBUG("PlanB: presumably, grabbing is in progress...\n");
443
444 planb_dbdma_stop(&pb->planb_base->ch2);
445 out_le32 (&pb->planb_base->ch2.cmdptr,
446 virt_to_bus(pb->ch2_cmd));
447 planb_dbdma_restart(&pb->planb_base->ch2);
448 st_le16 (&pb->ch1_cmd->command, DBDMA_NOP);
449 tab_cmd_dbdma(pb->last_cmd[pb->last_fr],
450 DBDMA_NOP | BR_ALWAYS,
451 virt_to_bus(pb->ch1_cmd));
452 eieio();
453 pb->prev_last_fr = pb->last_fr;
454 pb->last_fr = -2;
455 if(!(ACTIVE & in_le32(&pb->planb_base->ch1.status))) {
456 IDEBUG("PlanB: became inactive "
457 "in the mean time... reactivating\n");
458 planb_dbdma_stop(&pb->planb_base->ch1);
459 out_le32 (&pb->planb_base->ch1.cmdptr,
460 virt_to_bus(pb->ch1_cmd));
461 planb_dbdma_restart(&pb->planb_base->ch1);
462 }
463 } else {
464
465 DEBUG("PlanB: currently idle, so can do whatever\n");
466
467 planb_dbdma_stop(&pb->planb_base->ch2);
468 planb_dbdma_stop(&pb->planb_base->ch1);
469 st_le32 (&pb->planb_base->ch2.cmdptr,
470 virt_to_bus(pb->ch2_cmd));
471 st_le32 (&pb->planb_base->ch1.cmdptr,
472 virt_to_bus(pb->ch1_cmd));
473 out_le16 (&pb->ch1_cmd->command, DBDMA_NOP);
474 planb_dbdma_restart(&pb->planb_base->ch2);
475 planb_dbdma_restart(&pb->planb_base->ch1);
476 pb->last_fr = -1;
477 }
478 return;
479}
480
481static void overlay_stop(struct planb *pb)
482{
483 DEBUG("PlanB: overlay_stop()\n");
484
485 if(pb->last_fr == -1) {
486
487 DEBUG("PlanB: no grabbing, it seems...\n");
488
489 planb_dbdma_stop(&pb->planb_base->ch2);
490 planb_dbdma_stop(&pb->planb_base->ch1);
491 pb->last_fr = -999;
492 } else if(pb->last_fr == -2) {
493 unsigned int cmd_dep;
494 tab_cmd_dbdma(pb->cap_cmd[pb->prev_last_fr], DBDMA_STOP, 0);
495 eieio();
496 cmd_dep = (unsigned int)in_le32(&pb->overlay_last1->cmd_dep);
497 if(overlay_is_active(pb)) {
498
499 DEBUG("PlanB: overlay is currently active\n");
500
501 planb_dbdma_stop(&pb->planb_base->ch2);
502 planb_dbdma_stop(&pb->planb_base->ch1);
503 if(cmd_dep != pb->ch1_cmd_phys) {
504 out_le32(&pb->planb_base->ch1.cmdptr,
505 virt_to_bus(pb->overlay_last1));
506 planb_dbdma_restart(&pb->planb_base->ch1);
507 }
508 }
509 pb->last_fr = pb->prev_last_fr;
510 pb->prev_last_fr = -999;
511 }
512 return;
513}
514
515static void suspend_overlay(struct planb *pb)
516{
517 int fr = -1;
518 struct dbdma_cmd last;
519
520 DEBUG("PlanB: suspend_overlay: %d\n", pb->suspend);
521
522 if(pb->suspend++)
523 return;
524 if(ACTIVE & in_le32(&pb->planb_base->ch1.status)) {
525 if(pb->last_fr == -2) {
526 fr = pb->prev_last_fr;
527 memcpy(&last, (void*)pb->last_cmd[fr], sizeof(last));
528 tab_cmd_dbdma(pb->last_cmd[fr], DBDMA_STOP, 0);
529 }
530 if(overlay_is_active(pb)) {
531 planb_dbdma_stop(&pb->planb_base->ch2);
532 planb_dbdma_stop(&pb->planb_base->ch1);
533 pb->suspended.overlay = 1;
534 pb->suspended.frame = fr;
535 memcpy(&pb->suspended.cmd, &last, sizeof(last));
536 return;
537 }
538 }
539 pb->suspended.overlay = 0;
540 pb->suspended.frame = fr;
541 memcpy(&pb->suspended.cmd, &last, sizeof(last));
542 return;
543}
544
545static void resume_overlay(struct planb *pb)
546{
547
548 DEBUG("PlanB: resume_overlay: %d\n", pb->suspend);
549
550 if(pb->suspend > 1)
551 return;
552 if(pb->suspended.frame != -1) {
553 memcpy((void*)pb->last_cmd[pb->suspended.frame],
554 &pb->suspended.cmd, sizeof(pb->suspended.cmd));
555 }
556 if(ACTIVE & in_le32(&pb->planb_base->ch1.status)) {
557 goto finish;
558 }
559 if(pb->suspended.overlay) {
560
561 DEBUG("PlanB: overlay being resumed\n");
562
563 st_le16 (&pb->ch1_cmd->command, DBDMA_NOP);
564 st_le16 (&pb->ch2_cmd->command, DBDMA_NOP);
565 /* Set command buffer addresses */
566 st_le32(&pb->planb_base->ch1.cmdptr,
567 virt_to_bus(pb->overlay_last1));
568 out_le32(&pb->planb_base->ch2.cmdptr,
569 virt_to_bus(pb->overlay_last2));
570 /* Start the DMA controller */
571 out_le32 (&pb->planb_base->ch2.control,
572 PLANB_CLR(PAUSE) | PLANB_SET(RUN|WAKE));
573 out_le32 (&pb->planb_base->ch1.control,
574 PLANB_CLR(PAUSE) | PLANB_SET(RUN|WAKE));
575 } else if(pb->suspended.frame != -1) {
576 out_le32(&pb->planb_base->ch1.cmdptr,
577 virt_to_bus(pb->last_cmd[pb->suspended.frame]));
578 out_le32 (&pb->planb_base->ch1.control,
579 PLANB_CLR(PAUSE) | PLANB_SET(RUN|WAKE));
580 }
581
582finish:
583 pb->suspend--;
584 wake_up_interruptible(&pb->suspendq);
585}
586
587static void add_clip(struct planb *pb, struct video_clip *clip)
588{
589 volatile unsigned char *base;
590 int xc = clip->x, yc = clip->y;
591 int wc = clip->width, hc = clip->height;
592 int ww = pb->win.width, hw = pb->win.height;
593 int x, y, xtmp1, xtmp2;
594
595 DEBUG("PlanB: clip %dx%d+%d+%d\n", wc, hc, xc, yc);
596
597 if(xc < 0) {
598 wc += xc;
599 xc = 0;
600 }
601 if(yc < 0) {
602 hc += yc;
603 yc = 0;
604 }
605 if(xc + wc > ww)
606 wc = ww - xc;
607 if(wc <= 0) /* Nothing to do */
608 return;
609 if(yc + hc > hw)
610 hc = hw - yc;
611
612 for (y = yc; y < yc+hc; y++) {
613 xtmp1=xc>>3;
614 xtmp2=(xc+wc)>>3;
615 base = pb->mask + y*96;
616 if(xc != 0 || wc >= 8)
617 *(base + xtmp1) &= (unsigned char)(0x00ff &
618 (0xff00 >> (xc&7)));
619 for (x = xtmp1 + 1; x < xtmp2; x++) {
620 *(base + x) = 0;
621 }
622 if(xc < (ww & ~0x7))
623 *(base + xtmp2) &= (unsigned char)(0x00ff >>
624 ((xc+wc) & 7));
625 }
626
627 return;
628}
629
630static void fill_cmd_buff(struct planb *pb)
631{
632 int restore = 0;
633 volatile struct dbdma_cmd last;
634
635 DEBUG("PlanB: fill_cmd_buff()\n");
636
637 if(pb->overlay_last1 != pb->ch1_cmd) {
638 restore = 1;
639 last = *(pb->overlay_last1);
640 }
641 memset ((void *) pb->ch1_cmd, 0, 2 * pb->tab_size
642 * sizeof(struct dbdma_cmd));
643 cmd_buff (pb);
644 if(restore)
645 *(pb->overlay_last1) = last;
646 if(pb->suspended.overlay) {
647 unsigned long jump_addr = in_le32(&pb->overlay_last1->cmd_dep);
648 if(jump_addr != pb->ch1_cmd_phys) {
649 int i;
650
651 DEBUG("PlanB: adjusting ch1's jump address\n");
652
653 for(i = 0; i < MAX_GBUFFERS; i++) {
654 if(pb->need_pre_capture[i]) {
655 if(jump_addr == virt_to_bus(pb->pre_cmd[i]))
656 goto found;
657 } else {
658 if(jump_addr == virt_to_bus(pb->cap_cmd[i]))
659 goto found;
660 }
661 }
662
663 DEBUG("PlanB: not found...\n");
664
665 goto out;
666found:
667 if(pb->need_pre_capture[i])
668 out_le32(&pb->pre_cmd[i]->phy_addr,
669 virt_to_bus(pb->overlay_last1));
670 else
671 out_le32(&pb->cap_cmd[i]->phy_addr,
672 virt_to_bus(pb->overlay_last1));
673 }
674 }
675out:
676 pb->cmd_buff_inited = 1;
677
678 return;
679}
680
681static void cmd_buff(struct planb *pb)
682{
683 int i, bpp, count, nlines, stepsize, interlace;
684 unsigned long base, jump, addr_com, addr_dep;
685 volatile struct dbdma_cmd *c1 = pb->ch1_cmd;
686 volatile struct dbdma_cmd *c2 = pb->ch2_cmd;
687
688 interlace = pb->win.interlace;
689 bpp = pb->win.bpp;
690 count = (bpp * ((pb->win.x + pb->win.width > pb->win.swidth) ?
691 (pb->win.swidth - pb->win.x) : pb->win.width));
692 nlines = ((pb->win.y + pb->win.height > pb->win.sheight) ?
693 (pb->win.sheight - pb->win.y) : pb->win.height);
694
695 /* Do video in: */
696
697 /* Preamble commands: */
698 addr_com = virt_to_bus(c1);
699 addr_dep = virt_to_bus(&c1->cmd_dep);
700 tab_cmd_dbdma(c1++, DBDMA_NOP, 0);
701 jump = virt_to_bus(c1+16); /* 14 by cmd_geo_setup() and 2 for padding */
702 if((c1 = cmd_geo_setup(c1, pb->win.width, pb->win.height, interlace,
703 bpp, 1, pb)) == NULL) {
704 printk(KERN_WARNING "PlanB: encountered serious problems\n");
705 tab_cmd_dbdma(pb->ch1_cmd + 1, DBDMA_STOP, 0);
706 tab_cmd_dbdma(pb->ch2_cmd + 1, DBDMA_STOP, 0);
707 return;
708 }
709 tab_cmd_store(c1++, addr_com, (unsigned)(DBDMA_NOP | BR_ALWAYS) << 16);
710 tab_cmd_store(c1++, addr_dep, jump);
711 tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.wait_sel),
712 PLANB_SET(FIELD_SYNC));
713 /* (1) wait for field sync to be set */
714 tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFCLR, 0);
715 tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel),
716 PLANB_SET(ODD_FIELD));
717 /* wait for field sync to be cleared */
718 tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFSET, 0);
719 /* if not odd field, wait until field sync is set again */
720 tab_cmd_dbdma(c1, DBDMA_NOP | BR_IFSET, virt_to_bus(c1-3)); c1++;
721 /* assert ch_sync to ch2 */
722 tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch2.control),
723 PLANB_SET(CH_SYNC));
724 tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel),
725 PLANB_SET(DMA_ABORT));
726
727 base = (pb->frame_buffer_phys + pb->offset + pb->win.y * (pb->win.bpl
728 + pb->win.pad) + pb->win.x * bpp);
729
730 if (interlace) {
731 stepsize = 2;
732 jump = virt_to_bus(c1 + (nlines + 1) / 2);
733 } else {
734 stepsize = 1;
735 jump = virt_to_bus(c1 + nlines);
736 }
737
738 /* even field data: */
739 for (i=0; i < nlines; i += stepsize, c1++)
740 tab_cmd_gen(c1, INPUT_MORE | KEY_STREAM0 | BR_IFSET,
741 count, base + i * (pb->win.bpl + pb->win.pad), jump);
742
743 /* For non-interlaced, we use even fields only */
744 if (!interlace)
745 goto cmd_tab_data_end;
746
747 /* Resync to odd field */
748 /* (2) wait for field sync to be set */
749 tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFCLR, 0);
750 tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel),
751 PLANB_SET(ODD_FIELD));
752 /* wait for field sync to be cleared */
753 tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFSET, 0);
754 /* if not odd field, wait until field sync is set again */
755 tab_cmd_dbdma(c1, DBDMA_NOP | BR_IFCLR, virt_to_bus(c1-3)); c1++;
756 /* assert ch_sync to ch2 */
757 tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch2.control),
758 PLANB_SET(CH_SYNC));
759 tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel),
760 PLANB_SET(DMA_ABORT));
761
762 /* odd field data: */
763 jump = virt_to_bus(c1 + nlines / 2);
764 for (i=1; i < nlines; i += stepsize, c1++)
765 tab_cmd_gen(c1, INPUT_MORE | KEY_STREAM0 | BR_IFSET, count,
766 base + i * (pb->win.bpl + pb->win.pad), jump);
767
768 /* And jump back to the start */
769cmd_tab_data_end:
770 pb->overlay_last1 = c1; /* keep a pointer to the last command */
771 tab_cmd_dbdma(c1, DBDMA_NOP | BR_ALWAYS, virt_to_bus(pb->ch1_cmd));
772
773 /* Clipmask command buffer */
774
775 /* Preamble commands: */
776 tab_cmd_dbdma(c2++, DBDMA_NOP, 0);
777 tab_cmd_store(c2++, (unsigned)(&pb->planb_base_phys->ch2.wait_sel),
778 PLANB_SET(CH_SYNC));
779 /* wait until ch1 asserts ch_sync */
780 tab_cmd_dbdma(c2++, DBDMA_NOP | WAIT_IFCLR, 0);
781 /* clear ch_sync asserted by ch1 */
782 tab_cmd_store(c2++, (unsigned)(&pb->planb_base_phys->ch2.control),
783 PLANB_CLR(CH_SYNC));
784 tab_cmd_store(c2++, (unsigned)(&pb->planb_base_phys->ch2.wait_sel),
785 PLANB_SET(FIELD_SYNC));
786 tab_cmd_store(c2++, (unsigned)(&pb->planb_base_phys->ch2.br_sel),
787 PLANB_SET(ODD_FIELD));
788
789 /* jump to end of even field if appropriate */
790 /* this points to (interlace)? pos. C: pos. B */
791 jump = (interlace) ? virt_to_bus(c2 + (nlines + 1) / 2 + 2):
792 virt_to_bus(c2 + nlines + 2);
793 /* if odd field, skip over to odd field clipmasking */
794 tab_cmd_dbdma(c2++, DBDMA_NOP | BR_IFSET, jump);
795
796 /* even field mask: */
797 tab_cmd_store(c2++, (unsigned)(&pb->planb_base_phys->ch2.br_sel),
798 PLANB_SET(DMA_ABORT));
799 /* this points to pos. B */
800 jump = (interlace) ? virt_to_bus(c2 + nlines + 1):
801 virt_to_bus(c2 + nlines);
802 base = virt_to_bus(pb->mask);
803 for (i=0; i < nlines; i += stepsize, c2++)
804 tab_cmd_gen(c2, OUTPUT_MORE | KEY_STREAM0 | BR_IFSET, 96,
805 base + i * 96, jump);
806
807 /* For non-interlaced, we use only even fields */
808 if(!interlace)
809 goto cmd_tab_mask_end;
810
811 /* odd field mask: */
812/* C */ tab_cmd_store(c2++, (unsigned)(&pb->planb_base_phys->ch2.br_sel),
813 PLANB_SET(DMA_ABORT));
814 /* this points to pos. B */
815 jump = virt_to_bus(c2 + nlines / 2);
816 base = virt_to_bus(pb->mask);
817 for (i=1; i < nlines; i += 2, c2++) /* abort if set */
818 tab_cmd_gen(c2, OUTPUT_MORE | KEY_STREAM0 | BR_IFSET, 96,
819 base + i * 96, jump);
820
821 /* Inform channel 1 and jump back to start */
822cmd_tab_mask_end:
823 /* ok, I just realized this is kind of flawed. */
824 /* this part is reached only after odd field clipmasking. */
825 /* wanna clean up? */
826 /* wait for field sync to be set */
827 /* corresponds to fsync (1) of ch1 */
828/* B */ tab_cmd_dbdma(c2++, DBDMA_NOP | WAIT_IFCLR, 0);
829 /* restart ch1, meant to clear any dead bit or something */
830 tab_cmd_store(c2++, (unsigned)(&pb->planb_base_phys->ch1.control),
831 PLANB_CLR(RUN));
832 tab_cmd_store(c2++, (unsigned)(&pb->planb_base_phys->ch1.control),
833 PLANB_SET(RUN));
834 pb->overlay_last2 = c2; /* keep a pointer to the last command */
835 /* start over even field clipmasking */
836 tab_cmd_dbdma(c2, DBDMA_NOP | BR_ALWAYS, virt_to_bus(pb->ch2_cmd));
837
838 eieio();
839 return;
840}
841
842/*********************************/
843/* grabdisplay support functions */
844/*********************************/
845
846static int palette2fmt[] = {
847 0,
848 PLANB_GRAY,
849 0,
850 0,
851 0,
852 PLANB_COLOUR32,
853 PLANB_COLOUR15,
854 0,
855 0,
856 0,
857 0,
858 0,
859 0,
860 0,
861 0,
862};
863
864#define PLANB_PALETTE_MAX 15
865
866static int vgrab(struct planb *pb, struct video_mmap *mp)
867{
868 unsigned int fr = mp->frame;
869 unsigned int format;
870
871 if(pb->rawbuf==NULL) {
872 int err;
873 if((err=grabbuf_alloc(pb)))
874 return err;
875 }
876
877 IDEBUG("PlanB: grab %d: %dx%d(%u)\n", pb->grabbing,
878 mp->width, mp->height, fr);
879
880 if(pb->grabbing >= MAX_GBUFFERS)
881 return -ENOBUFS;
882 if(fr > (MAX_GBUFFERS - 1) || fr < 0)
883 return -EINVAL;
884 if(mp->height <= 0 || mp->width <= 0)
885 return -EINVAL;
886 if(mp->format < 0 || mp->format >= PLANB_PALETTE_MAX)
887 return -EINVAL;
888 if((format = palette2fmt[mp->format]) == 0)
889 return -EINVAL;
890 if (mp->height * mp->width * format > PLANB_MAX_FBUF) /* format = bpp */
891 return -EINVAL;
892
893 planb_lock(pb);
894 if(mp->width != pb->gwidth[fr] || mp->height != pb->gheight[fr] ||
895 format != pb->gfmt[fr] || (pb->gnorm_switch[fr])) {
896 int i;
897#ifndef PLANB_GSCANLINE
898 unsigned int osize = pb->gwidth[fr] * pb->gheight[fr]
899 * pb->gfmt[fr];
900 unsigned int nsize = mp->width * mp->height * format;
901#endif
902
903 IDEBUG("PlanB: gwidth = %d, gheight = %d, mp->format = %u\n",
904 mp->width, mp->height, mp->format);
905
906#ifndef PLANB_GSCANLINE
907 if(pb->gnorm_switch[fr])
908 nsize = 0;
909 if (nsize < osize) {
910 for(i = pb->gbuf_idx[fr]; osize > 0; i++) {
911 memset((void *)pb->rawbuf[i], 0, PAGE_SIZE);
912 osize -= PAGE_SIZE;
913 }
914 }
915 for(i = pb->l_fr_addr_idx[fr]; i < pb->l_fr_addr_idx[fr]
916 + pb->lnum[fr]; i++)
917 memset((void *)pb->rawbuf[i], 0, PAGE_SIZE);
918#else
919/* XXX TODO */
920/*
921 if(pb->gnorm_switch[fr])
922 memset((void *)pb->gbuffer[fr], 0,
923 pb->gbytes_per_line * pb->gheight[fr]);
924 else {
925 if(mp->
926 for(i = 0; i < pb->gheight[fr]; i++) {
927 memset((void *)(pb->gbuffer[fr]
928 + pb->gbytes_per_line * i
929 }
930 }
931*/
932#endif
933 pb->gwidth[fr] = mp->width;
934 pb->gheight[fr] = mp->height;
935 pb->gfmt[fr] = format;
936 pb->last_cmd[fr] = setup_grab_cmd(fr, pb);
937 planb_pre_capture(fr, pb->gfmt[fr], pb); /* gfmt = bpp */
938 pb->need_pre_capture[fr] = 1;
939 pb->gnorm_switch[fr] = 0;
940 } else
941 pb->need_pre_capture[fr] = 0;
942 pb->frame_stat[fr] = GBUFFER_GRABBING;
943 if(!(ACTIVE & in_le32(&pb->planb_base->ch1.status))) {
944
945 IDEBUG("PlanB: ch1 inactive, initiating grabbing\n");
946
947 planb_dbdma_stop(&pb->planb_base->ch1);
948 if(pb->need_pre_capture[fr]) {
949
950 IDEBUG("PlanB: padding pre-capture sequence\n");
951
952 out_le32 (&pb->planb_base->ch1.cmdptr,
953 virt_to_bus(pb->pre_cmd[fr]));
954 } else {
955 tab_cmd_dbdma(pb->last_cmd[fr], DBDMA_STOP, 0);
956 tab_cmd_dbdma(pb->cap_cmd[fr], DBDMA_NOP, 0);
957 /* let's be on the safe side. here is not timing critical. */
958 tab_cmd_dbdma((pb->cap_cmd[fr] + 1), DBDMA_NOP, 0);
959 out_le32 (&pb->planb_base->ch1.cmdptr,
960 virt_to_bus(pb->cap_cmd[fr]));
961 }
962 planb_dbdma_restart(&pb->planb_base->ch1);
963 pb->last_fr = fr;
964 } else {
965 int i;
966
967 IDEBUG("PlanB: ch1 active, grabbing being queued\n");
968
969 if((pb->last_fr == -1) || ((pb->last_fr == -2) &&
970 overlay_is_active(pb))) {
971
972 IDEBUG("PlanB: overlay is active, grabbing defered\n");
973
974 tab_cmd_dbdma(pb->last_cmd[fr],
975 DBDMA_NOP | BR_ALWAYS,
976 virt_to_bus(pb->ch1_cmd));
977 if(pb->need_pre_capture[fr]) {
978
979 IDEBUG("PlanB: padding pre-capture sequence\n");
980
981 tab_cmd_store(pb->pre_cmd[fr],
982 virt_to_bus(&pb->overlay_last1->cmd_dep),
983 virt_to_bus(pb->ch1_cmd));
984 eieio();
985 out_le32 (&pb->overlay_last1->cmd_dep,
986 virt_to_bus(pb->pre_cmd[fr]));
987 } else {
988 tab_cmd_store(pb->cap_cmd[fr],
989 virt_to_bus(&pb->overlay_last1->cmd_dep),
990 virt_to_bus(pb->ch1_cmd));
991 tab_cmd_dbdma((pb->cap_cmd[fr] + 1),
992 DBDMA_NOP, 0);
993 eieio();
994 out_le32 (&pb->overlay_last1->cmd_dep,
995 virt_to_bus(pb->cap_cmd[fr]));
996 }
997 for(i = 0; overlay_is_active(pb) && i < 999; i++)
998 IDEBUG("PlanB: waiting for overlay done\n");
999 tab_cmd_dbdma(pb->ch1_cmd, DBDMA_NOP, 0);
1000 pb->prev_last_fr = fr;
1001 pb->last_fr = -2;
1002 } else if(pb->last_fr == -2) {
1003
1004 IDEBUG("PlanB: mixed mode detected, grabbing"
1005 " will be done before activating overlay\n");
1006
1007 tab_cmd_dbdma(pb->ch1_cmd, DBDMA_NOP, 0);
1008 if(pb->need_pre_capture[fr]) {
1009
1010 IDEBUG("PlanB: padding pre-capture sequence\n");
1011
1012 tab_cmd_dbdma(pb->last_cmd[pb->prev_last_fr],
1013 DBDMA_NOP | BR_ALWAYS,
1014 virt_to_bus(pb->pre_cmd[fr]));
1015 eieio();
1016 } else {
1017 tab_cmd_dbdma(pb->cap_cmd[fr], DBDMA_NOP, 0);
1018 if(pb->gwidth[pb->prev_last_fr] !=
1019 pb->gwidth[fr]
1020 || pb->gheight[pb->prev_last_fr] !=
1021 pb->gheight[fr]
1022 || pb->gfmt[pb->prev_last_fr] !=
1023 pb->gfmt[fr])
1024 tab_cmd_dbdma((pb->cap_cmd[fr] + 1),
1025 DBDMA_NOP, 0);
1026 else
1027 tab_cmd_dbdma((pb->cap_cmd[fr] + 1),
1028 DBDMA_NOP | BR_ALWAYS,
1029 virt_to_bus(pb->cap_cmd[fr] + 16));
1030 tab_cmd_dbdma(pb->last_cmd[pb->prev_last_fr],
1031 DBDMA_NOP | BR_ALWAYS,
1032 virt_to_bus(pb->cap_cmd[fr]));
1033 eieio();
1034 }
1035 tab_cmd_dbdma(pb->last_cmd[fr],
1036 DBDMA_NOP | BR_ALWAYS,
1037 virt_to_bus(pb->ch1_cmd));
1038 eieio();
1039 pb->prev_last_fr = fr;
1040 pb->last_fr = -2;
1041 } else {
1042
1043 IDEBUG("PlanB: active grabbing session detected\n");
1044
1045 if(pb->need_pre_capture[fr]) {
1046
1047 IDEBUG("PlanB: padding pre-capture sequence\n");
1048
1049 tab_cmd_dbdma(pb->last_cmd[pb->last_fr],
1050 DBDMA_NOP | BR_ALWAYS,
1051 virt_to_bus(pb->pre_cmd[fr]));
1052 eieio();
1053 } else {
1054 tab_cmd_dbdma(pb->last_cmd[fr], DBDMA_STOP, 0);
1055 tab_cmd_dbdma(pb->cap_cmd[fr], DBDMA_NOP, 0);
1056 if(pb->gwidth[pb->last_fr] != pb->gwidth[fr]
1057 || pb->gheight[pb->last_fr] !=
1058 pb->gheight[fr]
1059 || pb->gfmt[pb->last_fr] !=
1060 pb->gfmt[fr])
1061 tab_cmd_dbdma((pb->cap_cmd[fr] + 1),
1062 DBDMA_NOP, 0);
1063 else
1064 tab_cmd_dbdma((pb->cap_cmd[fr] + 1),
1065 DBDMA_NOP | BR_ALWAYS,
1066 virt_to_bus(pb->cap_cmd[fr] + 16));
1067 tab_cmd_dbdma(pb->last_cmd[pb->last_fr],
1068 DBDMA_NOP | BR_ALWAYS,
1069 virt_to_bus(pb->cap_cmd[fr]));
1070 eieio();
1071 }
1072 pb->last_fr = fr;
1073 }
1074 if(!(ACTIVE & in_le32(&pb->planb_base->ch1.status))) {
1075
1076 IDEBUG("PlanB: became inactive in the mean time..."
1077 "reactivating\n");
1078
1079 planb_dbdma_stop(&pb->planb_base->ch1);
1080 out_le32 (&pb->planb_base->ch1.cmdptr,
1081 virt_to_bus(pb->cap_cmd[fr]));
1082 planb_dbdma_restart(&pb->planb_base->ch1);
1083 }
1084 }
1085 pb->grabbing++;
1086 planb_unlock(pb);
1087
1088 return 0;
1089}
1090
1091static void planb_pre_capture(int fr, int bpp, struct planb *pb)
1092{
1093 volatile struct dbdma_cmd *c1 = pb->pre_cmd[fr];
1094 int interlace = (pb->gheight[fr] > pb->maxlines/2)? 1: 0;
1095
1096 tab_cmd_dbdma(c1++, DBDMA_NOP, 0);
1097 if((c1 = cmd_geo_setup(c1, pb->gwidth[fr], pb->gheight[fr], interlace,
1098 bpp, 0, pb)) == NULL) {
1099 printk(KERN_WARNING "PlanB: encountered some problems\n");
1100 tab_cmd_dbdma(pb->pre_cmd[fr] + 1, DBDMA_STOP, 0);
1101 return;
1102 }
1103 /* Sync to even field */
1104 tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.wait_sel),
1105 PLANB_SET(FIELD_SYNC));
1106 tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFCLR, 0);
1107 tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel),
1108 PLANB_SET(ODD_FIELD));
1109 tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFSET, 0);
1110 tab_cmd_dbdma(c1, DBDMA_NOP | BR_IFSET, virt_to_bus(c1-3)); c1++;
1111 tab_cmd_dbdma(c1++, DBDMA_NOP | INTR_ALWAYS, 0);
1112 tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel),
1113 PLANB_SET(DMA_ABORT));
1114 /* For non-interlaced, we use even fields only */
1115 if (pb->gheight[fr] <= pb->maxlines/2)
1116 goto cmd_tab_data_end;
1117 /* Sync to odd field */
1118 tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFCLR, 0);
1119 tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel),
1120 PLANB_SET(ODD_FIELD));
1121 tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFSET, 0);
1122 tab_cmd_dbdma(c1, DBDMA_NOP | BR_IFCLR, virt_to_bus(c1-3)); c1++;
1123 tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel),
1124 PLANB_SET(DMA_ABORT));
1125cmd_tab_data_end:
1126 tab_cmd_dbdma(c1, DBDMA_NOP | BR_ALWAYS, virt_to_bus(pb->cap_cmd[fr]));
1127
1128 eieio();
1129}
1130
1131static volatile struct dbdma_cmd *setup_grab_cmd(int fr, struct planb *pb)
1132{
1133 int i, bpp, count, nlines, stepsize, interlace;
1134#ifdef PLANB_GSCANLINE
1135 int scanline;
1136#else
1137 int nlpp, leftover1;
1138 unsigned long base;
1139#endif
1140 unsigned long jump;
1141 int pagei;
1142 volatile struct dbdma_cmd *c1;
1143 volatile struct dbdma_cmd *jump_addr;
1144
1145 c1 = pb->cap_cmd[fr];
1146 interlace = (pb->gheight[fr] > pb->maxlines/2)? 1: 0;
1147 bpp = pb->gfmt[fr]; /* gfmt = bpp */
1148 count = bpp * pb->gwidth[fr];
1149 nlines = pb->gheight[fr];
1150#ifdef PLANB_GSCANLINE
1151 scanline = pb->gbytes_per_line;
1152#else
1153 pb->lsize[fr] = count;
1154 pb->lnum[fr] = 0;
1155#endif
1156
1157 /* Do video in: */
1158
1159 /* Preamble commands: */
1160 tab_cmd_dbdma(c1++, DBDMA_NOP, 0);
1161 tab_cmd_dbdma(c1, DBDMA_NOP | BR_ALWAYS, virt_to_bus(c1 + 16)); c1++;
1162 if((c1 = cmd_geo_setup(c1, pb->gwidth[fr], pb->gheight[fr], interlace,
1163 bpp, 0, pb)) == NULL) {
1164 printk(KERN_WARNING "PlanB: encountered serious problems\n");
1165 tab_cmd_dbdma(pb->cap_cmd[fr] + 1, DBDMA_STOP, 0);
1166 return (pb->cap_cmd[fr] + 2);
1167 }
1168 tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.wait_sel),
1169 PLANB_SET(FIELD_SYNC));
1170 tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFCLR, 0);
1171 tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel),
1172 PLANB_SET(ODD_FIELD));
1173 tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFSET, 0);
1174 tab_cmd_dbdma(c1, DBDMA_NOP | BR_IFSET, virt_to_bus(c1-3)); c1++;
1175 tab_cmd_dbdma(c1++, DBDMA_NOP | INTR_ALWAYS, 0);
1176 tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel),
1177 PLANB_SET(DMA_ABORT));
1178
1179 if (interlace) {
1180 stepsize = 2;
1181 jump_addr = c1 + TAB_FACTOR * (nlines + 1) / 2;
1182 } else {
1183 stepsize = 1;
1184 jump_addr = c1 + TAB_FACTOR * nlines;
1185 }
1186 jump = virt_to_bus(jump_addr);
1187
1188 /* even field data: */
1189
1190 pagei = pb->gbuf_idx[fr];
1191#ifdef PLANB_GSCANLINE
1192 for (i = 0; i < nlines; i += stepsize) {
1193 tab_cmd_gen(c1++, INPUT_MORE | BR_IFSET, count,
1194 virt_to_bus(pb->rawbuf[pagei
1195 + i * scanline / PAGE_SIZE]), jump);
1196 }
1197#else
1198 i = 0;
1199 leftover1 = 0;
1200 do {
1201 int j;
1202
1203 base = virt_to_bus(pb->rawbuf[pagei]);
1204 nlpp = (PAGE_SIZE - leftover1) / count / stepsize;
1205 for(j = 0; j < nlpp && i < nlines; j++, i += stepsize, c1++)
1206 tab_cmd_gen(c1, INPUT_MORE | KEY_STREAM0 | BR_IFSET,
1207 count, base + count * j * stepsize + leftover1, jump);
1208 if(i < nlines) {
1209 int lov0 = PAGE_SIZE - count * nlpp * stepsize - leftover1;
1210
1211 if(lov0 == 0)
1212 leftover1 = 0;
1213 else {
1214 if(lov0 >= count) {
1215 tab_cmd_gen(c1++, INPUT_MORE | BR_IFSET, count, base
1216 + count * nlpp * stepsize + leftover1, jump);
1217 } else {
1218 pb->l_to_addr[fr][pb->lnum[fr]] = pb->rawbuf[pagei]
1219 + count * nlpp * stepsize + leftover1;
1220 pb->l_to_next_idx[fr][pb->lnum[fr]] = pagei + 1;
1221 pb->l_to_next_size[fr][pb->lnum[fr]] = count - lov0;
1222 tab_cmd_gen(c1++, INPUT_MORE | BR_IFSET, count,
1223 virt_to_bus(pb->rawbuf[pb->l_fr_addr_idx[fr]
1224 + pb->lnum[fr]]), jump);
1225 if(++pb->lnum[fr] > MAX_LNUM)
1226 pb->lnum[fr]--;
1227 }
1228 leftover1 = count * stepsize - lov0;
1229 i += stepsize;
1230 }
1231 }
1232 pagei++;
1233 } while(i < nlines);
1234 tab_cmd_dbdma(c1, DBDMA_NOP | BR_ALWAYS, jump);
1235 c1 = jump_addr;
1236#endif /* PLANB_GSCANLINE */
1237
1238 /* For non-interlaced, we use even fields only */
1239 if (!interlace)
1240 goto cmd_tab_data_end;
1241
1242 /* Sync to odd field */
1243 tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFCLR, 0);
1244 tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel),
1245 PLANB_SET(ODD_FIELD));
1246 tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFSET, 0);
1247 tab_cmd_dbdma(c1, DBDMA_NOP | BR_IFCLR, virt_to_bus(c1-3)); c1++;
1248 tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel),
1249 PLANB_SET(DMA_ABORT));
1250
1251 /* odd field data: */
1252 jump_addr = c1 + TAB_FACTOR * nlines / 2;
1253 jump = virt_to_bus(jump_addr);
1254#ifdef PLANB_GSCANLINE
1255 for (i = 1; i < nlines; i += stepsize) {
1256 tab_cmd_gen(c1++, INPUT_MORE | BR_IFSET, count,
1257 virt_to_bus(pb->rawbuf[pagei
1258 + i * scanline / PAGE_SIZE]), jump);
1259 }
1260#else
1261 i = 1;
1262 leftover1 = 0;
1263 pagei = pb->gbuf_idx[fr];
1264 if(nlines <= 1)
1265 goto skip;
1266 do {
1267 int j;
1268
1269 base = virt_to_bus(pb->rawbuf[pagei]);
1270 nlpp = (PAGE_SIZE - leftover1) / count / stepsize;
1271 if(leftover1 >= count) {
1272 tab_cmd_gen(c1++, INPUT_MORE | KEY_STREAM0 | BR_IFSET, count,
1273 base + leftover1 - count, jump);
1274 i += stepsize;
1275 }
1276 for(j = 0; j < nlpp && i < nlines; j++, i += stepsize, c1++)
1277 tab_cmd_gen(c1, INPUT_MORE | KEY_STREAM0 | BR_IFSET, count,
1278 base + count * (j * stepsize + 1) + leftover1, jump);
1279 if(i < nlines) {
1280 int lov0 = PAGE_SIZE - count * nlpp * stepsize - leftover1;
1281
1282 if(lov0 == 0)
1283 leftover1 = 0;
1284 else {
1285 if(lov0 > count) {
1286 pb->l_to_addr[fr][pb->lnum[fr]] = pb->rawbuf[pagei]
1287 + count * (nlpp * stepsize + 1) + leftover1;
1288 pb->l_to_next_idx[fr][pb->lnum[fr]] = pagei + 1;
1289 pb->l_to_next_size[fr][pb->lnum[fr]] = count * stepsize
1290 - lov0;
1291 tab_cmd_gen(c1++, INPUT_MORE | BR_IFSET, count,
1292 virt_to_bus(pb->rawbuf[pb->l_fr_addr_idx[fr]
1293 + pb->lnum[fr]]), jump);
1294 if(++pb->lnum[fr] > MAX_LNUM)
1295 pb->lnum[fr]--;
1296 i += stepsize;
1297 }
1298 leftover1 = count * stepsize - lov0;
1299 }
1300 }
1301 pagei++;
1302 } while(i < nlines);
1303skip:
1304 tab_cmd_dbdma(c1, DBDMA_NOP | BR_ALWAYS, jump);
1305 c1 = jump_addr;
1306#endif /* PLANB_GSCANLINE */
1307
1308cmd_tab_data_end:
1309 tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->intr_stat),
1310 (fr << 9) | PLANB_FRM_IRQ | PLANB_GEN_IRQ);
1311 /* stop it */
1312 tab_cmd_dbdma(c1, DBDMA_STOP, 0);
1313
1314 eieio();
1315 return c1;
1316}
1317
1318static void planb_irq(int irq, void *dev_id, struct pt_regs * regs)
1319{
1320 unsigned int stat, astat;
1321 struct planb *pb = (struct planb *)dev_id;
1322
1323 IDEBUG("PlanB: planb_irq()\n");
1324
1325 /* get/clear interrupt status bits */
1326 eieio();
1327 stat = in_le32(&pb->planb_base->intr_stat);
1328 astat = stat & pb->intr_mask;
1329 out_le32(&pb->planb_base->intr_stat, PLANB_FRM_IRQ
1330 & ~astat & stat & ~PLANB_GEN_IRQ);
1331 IDEBUG("PlanB: stat = %X, astat = %X\n", stat, astat);
1332
1333 if(astat & PLANB_FRM_IRQ) {
1334 unsigned int fr = stat >> 9;
1335#ifndef PLANB_GSCANLINE
1336 int i;
1337#endif
1338 IDEBUG("PlanB: PLANB_FRM_IRQ\n");
1339
1340 pb->gcount++;
1341
1342 IDEBUG("PlanB: grab %d: fr = %d, gcount = %d\n",
1343 pb->grabbing, fr, pb->gcount);
1344#ifndef PLANB_GSCANLINE
1345 IDEBUG("PlanB: %d * %d bytes are being copied over\n",
1346 pb->lnum[fr], pb->lsize[fr]);
1347 for(i = 0; i < pb->lnum[fr]; i++) {
1348 int first = pb->lsize[fr] - pb->l_to_next_size[fr][i];
1349
1350 memcpy(pb->l_to_addr[fr][i],
1351 pb->rawbuf[pb->l_fr_addr_idx[fr] + i],
1352 first);
1353 memcpy(pb->rawbuf[pb->l_to_next_idx[fr][i]],
1354 pb->rawbuf[pb->l_fr_addr_idx[fr] + i] + first,
1355 pb->l_to_next_size[fr][i]);
1356 }
1357#endif
1358 pb->frame_stat[fr] = GBUFFER_DONE;
1359 pb->grabbing--;
1360 wake_up_interruptible(&pb->capq);
1361 return;
1362 }
1363 /* incorrect interrupts? */
1364 pb->intr_mask = PLANB_CLR_IRQ;
1365 out_le32(&pb->planb_base->intr_stat, PLANB_CLR_IRQ);
1366 printk(KERN_ERR "PlanB: IRQ lockup, cleared intrrupts"
1367 " unconditionally\n");
1368}
1369
1370/*******************************
1371 * Device Operations functions *
1372 *******************************/
1373
1374static int planb_open(struct video_device *dev, int mode)
1375{
1376 struct planb *pb = (struct planb *)dev;
1377
1378 if (pb->user == 0) {
1379 int err;
1380 if((err = planb_prepare_open(pb)) != 0)
1381 return err;
1382 }
1383 pb->user++;
1384
1385 DEBUG("PlanB: device opened\n");
1386 return 0;
1387}
1388
1389static void planb_close(struct video_device *dev)
1390{
1391 struct planb *pb = (struct planb *)dev;
1392
1393 if(pb->user < 1) /* ??? */
1394 return;
1395 planb_lock(pb);
1396 if (pb->user == 1) {
1397 if (pb->overlay) {
1398 planb_dbdma_stop(&pb->planb_base->ch2);
1399 planb_dbdma_stop(&pb->planb_base->ch1);
1400 pb->overlay = 0;
1401 }
1402 planb_prepare_close(pb);
1403 }
1404 pb->user--;
1405 planb_unlock(pb);
1406
1407 DEBUG("PlanB: device closed\n");
1408}
1409
1410static long planb_read(struct video_device *v, char *buf, unsigned long count,
1411 int nonblock)
1412{
1413 DEBUG("planb: read request\n");
1414 return -EINVAL;
1415}
1416
1417static long planb_write(struct video_device *v, const char *buf,
1418 unsigned long count, int nonblock)
1419{
1420 DEBUG("planb: write request\n");
1421 return -EINVAL;
1422}
1423
1424static int planb_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
1425{
1426 struct planb *pb=(struct planb *)dev;
1427
1428 switch (cmd)
1429 {
1430 case VIDIOCGCAP:
1431 {
1432 struct video_capability b;
1433
1434 DEBUG("PlanB: IOCTL VIDIOCGCAP\n");
1435
1436 strcpy (b.name, pb->video_dev.name);
1437 b.type = VID_TYPE_OVERLAY | VID_TYPE_CLIPPING |
1438 VID_TYPE_FRAMERAM | VID_TYPE_SCALES |
1439 VID_TYPE_CAPTURE;
1440 b.channels = 2; /* composite & svhs */
1441 b.audios = 0;
1442 b.maxwidth = PLANB_MAXPIXELS;
1443 b.maxheight = PLANB_MAXLINES;
1444 b.minwidth = 32; /* wild guess */
1445 b.minheight = 32;
1446 if (copy_to_user(arg,&b,sizeof(b)))
1447 return -EFAULT;
1448 return 0;
1449 }
1450 case VIDIOCSFBUF:
1451 {
1452 struct video_buffer v;
1453 unsigned short bpp;
1454 unsigned int fmt;
1455
1456 DEBUG("PlanB: IOCTL VIDIOCSFBUF\n");
1457
1458 if (!capable(CAP_SYS_ADMIN)
1459 || !capable(CAP_SYS_RAWIO))
1460 return -EPERM;
1461 if (copy_from_user(&v, arg,sizeof(v)))
1462 return -EFAULT;
1463 planb_lock(pb);
1464 switch(v.depth) {
1465 case 8:
1466 bpp = 1;
1467 fmt = PLANB_GRAY;
1468 break;
1469 case 15:
1470 case 16:
1471 bpp = 2;
1472 fmt = PLANB_COLOUR15;
1473 break;
1474 case 24:
1475 case 32:
1476 bpp = 4;
1477 fmt = PLANB_COLOUR32;
1478 break;
1479 default:
1480 planb_unlock(pb);
1481 return -EINVAL;
1482 }
1483 if (bpp * v.width > v.bytesperline) {
1484 planb_unlock(pb);
1485 return -EINVAL;
1486 }
1487 pb->win.bpp = bpp;
1488 pb->win.color_fmt = fmt;
1489 pb->frame_buffer_phys = (unsigned long) v.base;
1490 pb->win.sheight = v.height;
1491 pb->win.swidth = v.width;
1492 pb->picture.depth = pb->win.depth = v.depth;
1493 pb->win.bpl = pb->win.bpp * pb->win.swidth;
1494 pb->win.pad = v.bytesperline - pb->win.bpl;
1495
1496 DEBUG("PlanB: Display at %p is %d by %d, bytedepth %d,"
1497 " bpl %d (+ %d)\n", v.base, v.width,v.height,
1498 pb->win.bpp, pb->win.bpl, pb->win.pad);
1499
1500 pb->cmd_buff_inited = 0;
1501 if(pb->overlay) {
1502 suspend_overlay(pb);
1503 fill_cmd_buff(pb);
1504 resume_overlay(pb);
1505 }
1506 planb_unlock(pb);
1507 return 0;
1508 }
1509 case VIDIOCGFBUF:
1510 {
1511 struct video_buffer v;
1512
1513 DEBUG("PlanB: IOCTL VIDIOCGFBUF\n");
1514
1515 v.base = (void *)pb->frame_buffer_phys;
1516 v.height = pb->win.sheight;
1517 v.width = pb->win.swidth;
1518 v.depth = pb->win.depth;
1519 v.bytesperline = pb->win.bpl + pb->win.pad;
1520 if (copy_to_user(arg, &v, sizeof(v)))
1521 return -EFAULT;
1522 return 0;
1523 }
1524 case VIDIOCCAPTURE:
1525 {
1526 int i;
1527
1528 if(copy_from_user(&i, arg, sizeof(i)))
1529 return -EFAULT;
1530 if(i==0) {
1531 DEBUG("PlanB: IOCTL VIDIOCCAPTURE Stop\n");
1532
1533 if (!(pb->overlay))
1534 return 0;
1535 planb_lock(pb);
1536 pb->overlay = 0;
1537 overlay_stop(pb);
1538 planb_unlock(pb);
1539 } else {
1540 DEBUG("PlanB: IOCTL VIDIOCCAPTURE Start\n");
1541
1542 if (pb->frame_buffer_phys == 0 ||
1543 pb->win.width == 0 ||
1544 pb->win.height == 0)
1545 return -EINVAL;
1546 if (pb->overlay)
1547 return 0;
1548 planb_lock(pb);
1549 pb->overlay = 1;
1550 if(!(pb->cmd_buff_inited))
1551 fill_cmd_buff(pb);
1552 overlay_start(pb);
1553 planb_unlock(pb);
1554 }
1555 return 0;
1556 }
1557 case VIDIOCGCHAN:
1558 {
1559 struct video_channel v;
1560
1561 DEBUG("PlanB: IOCTL VIDIOCGCHAN\n");
1562
1563 if(copy_from_user(&v, arg,sizeof(v)))
1564 return -EFAULT;
1565 v.flags = 0;
1566 v.tuners = 0;
1567 v.type = VIDEO_TYPE_CAMERA;
1568 v.norm = pb->win.norm;
1569 switch(v.channel)
1570 {
1571 case 0:
1572 strcpy(v.name,"Composite");
1573 break;
1574 case 1:
1575 strcpy(v.name,"SVHS");
1576 break;
1577 default:
1578 return -EINVAL;
1579 break;
1580 }
1581 if(copy_to_user(arg,&v,sizeof(v)))
1582 return -EFAULT;
1583
1584 return 0;
1585 }
1586 case VIDIOCSCHAN:
1587 {
1588 struct video_channel v;
1589
1590 DEBUG("PlanB: IOCTL VIDIOCSCHAN\n");
1591
1592 if(copy_from_user(&v, arg, sizeof(v)))
1593 return -EFAULT;
1594
1595 if (v.norm != pb->win.norm) {
1596 int i, maxlines;
1597
1598 switch (v.norm)
1599 {
1600 case VIDEO_MODE_PAL:
1601 case VIDEO_MODE_SECAM:
1602 maxlines = PLANB_MAXLINES;
1603 break;
1604 case VIDEO_MODE_NTSC:
1605 maxlines = PLANB_NTSC_MAXLINES;
1606 break;
1607 default:
1608 return -EINVAL;
1609 break;
1610 }
1611 planb_lock(pb);
1612 /* empty the grabbing queue */
1613 wait_event(pb->capq, !pb->grabbing);
1614 pb->maxlines = maxlines;
1615 pb->win.norm = v.norm;
1616 /* Stop overlay if running */
1617 suspend_overlay(pb);
1618 for(i = 0; i < MAX_GBUFFERS; i++)
1619 pb->gnorm_switch[i] = 1;
1620 /* I know it's an overkill, but.... */
1621 fill_cmd_buff(pb);
1622 /* ok, now init it accordingly */
1623 saa_init_regs (pb);
1624 /* restart overlay if it was running */
1625 resume_overlay(pb);
1626 planb_unlock(pb);
1627 }
1628
1629 switch(v.channel)
1630 {
1631 case 0: /* Composite */
1632 saa_set (SAA7196_IOCC,
1633 ((saa_regs[pb->win.norm][SAA7196_IOCC] &
1634 ~7) | 3), pb);
1635 break;
1636 case 1: /* SVHS */
1637 saa_set (SAA7196_IOCC,
1638 ((saa_regs[pb->win.norm][SAA7196_IOCC] &
1639 ~7) | 4), pb);
1640 break;
1641 default:
1642 return -EINVAL;
1643 break;
1644 }
1645
1646 return 0;
1647 }
1648 case VIDIOCGPICT:
1649 {
1650 struct video_picture vp = pb->picture;
1651
1652 DEBUG("PlanB: IOCTL VIDIOCGPICT\n");
1653
1654 switch(pb->win.color_fmt) {
1655 case PLANB_GRAY:
1656 vp.palette = VIDEO_PALETTE_GREY;
1657 case PLANB_COLOUR15:
1658 vp.palette = VIDEO_PALETTE_RGB555;
1659 break;
1660 case PLANB_COLOUR32:
1661 vp.palette = VIDEO_PALETTE_RGB32;
1662 break;
1663 default:
1664 vp.palette = 0;
1665 break;
1666 }
1667
1668 if(copy_to_user(arg,&vp,sizeof(vp)))
1669 return -EFAULT;
1670 return 0;
1671 }
1672 case VIDIOCSPICT:
1673 {
1674 struct video_picture vp;
1675
1676 DEBUG("PlanB: IOCTL VIDIOCSPICT\n");
1677
1678 if(copy_from_user(&vp,arg,sizeof(vp)))
1679 return -EFAULT;
1680 pb->picture = vp;
1681 /* Should we do sanity checks here? */
1682 saa_set (SAA7196_BRIG, (unsigned char)
1683 ((pb->picture.brightness) >> 8), pb);
1684 saa_set (SAA7196_HUEC, (unsigned char)
1685 ((pb->picture.hue) >> 8) ^ 0x80, pb);
1686 saa_set (SAA7196_CSAT, (unsigned char)
1687 ((pb->picture.colour) >> 9), pb);
1688 saa_set (SAA7196_CONT, (unsigned char)
1689 ((pb->picture.contrast) >> 9), pb);
1690
1691 return 0;
1692 }
1693 case VIDIOCSWIN:
1694 {
1695 struct video_window vw;
1696 struct video_clip clip;
1697 int i;
1698
1699 DEBUG("PlanB: IOCTL VIDIOCSWIN\n");
1700
1701 if(copy_from_user(&vw,arg,sizeof(vw)))
1702 return -EFAULT;
1703
1704 planb_lock(pb);
1705 /* Stop overlay if running */
1706 suspend_overlay(pb);
1707 pb->win.interlace = (vw.height > pb->maxlines/2)? 1: 0;
1708 if (pb->win.x != vw.x ||
1709 pb->win.y != vw.y ||
1710 pb->win.width != vw.width ||
1711 pb->win.height != vw.height ||
1712 !pb->cmd_buff_inited) {
1713 pb->win.x = vw.x;
1714 pb->win.y = vw.y;
1715 pb->win.width = vw.width;
1716 pb->win.height = vw.height;
1717 fill_cmd_buff(pb);
1718 }
1719 /* Reset clip mask */
1720 memset ((void *) pb->mask, 0xff, (pb->maxlines
1721 * ((PLANB_MAXPIXELS + 7) & ~7)) / 8);
1722 /* Add any clip rects */
1723 for (i = 0; i < vw.clipcount; i++) {
1724 if (copy_from_user(&clip, vw.clips + i,
1725 sizeof(struct video_clip)))
1726 return -EFAULT;
1727 add_clip(pb, &clip);
1728 }
1729 /* restart overlay if it was running */
1730 resume_overlay(pb);
1731 planb_unlock(pb);
1732 return 0;
1733 }
1734 case VIDIOCGWIN:
1735 {
1736 struct video_window vw;
1737
1738 DEBUG("PlanB: IOCTL VIDIOCGWIN\n");
1739
1740 vw.x=pb->win.x;
1741 vw.y=pb->win.y;
1742 vw.width=pb->win.width;
1743 vw.height=pb->win.height;
1744 vw.chromakey=0;
1745 vw.flags=0;
1746 if(pb->win.interlace)
1747 vw.flags|=VIDEO_WINDOW_INTERLACE;
1748 if(copy_to_user(arg,&vw,sizeof(vw)))
1749 return -EFAULT;
1750 return 0;
1751 }
1752 case VIDIOCSYNC: {
1753 int i;
1754
1755 IDEBUG("PlanB: IOCTL VIDIOCSYNC\n");
1756
1757 if(copy_from_user((void *)&i,arg,sizeof(int)))
1758 return -EFAULT;
1759
1760 IDEBUG("PlanB: sync to frame %d\n", i);
1761
1762 if(i > (MAX_GBUFFERS - 1) || i < 0)
1763 return -EINVAL;
1764chk_grab:
1765 switch (pb->frame_stat[i]) {
1766 case GBUFFER_UNUSED:
1767 return -EINVAL;
1768 case GBUFFER_GRABBING:
1769 IDEBUG("PlanB: waiting for grab"
1770 " done (%d)\n", i);
1771 interruptible_sleep_on(&pb->capq);
1772 if(signal_pending(current))
1773 return -EINTR;
1774 goto chk_grab;
1775 case GBUFFER_DONE:
1776 pb->frame_stat[i] = GBUFFER_UNUSED;
1777 break;
1778 }
1779 return 0;
1780 }
1781
1782 case VIDIOCMCAPTURE:
1783 {
1784 struct video_mmap vm;
1785 volatile unsigned int status;
1786
1787 IDEBUG("PlanB: IOCTL VIDIOCMCAPTURE\n");
1788
1789 if(copy_from_user((void *) &vm,(void *)arg,sizeof(vm)))
1790 return -EFAULT;
1791 status = pb->frame_stat[vm.frame];
1792 if (status != GBUFFER_UNUSED)
1793 return -EBUSY;
1794
1795 return vgrab(pb, &vm);
1796 }
1797
1798 case VIDIOCGMBUF:
1799 {
1800 int i;
1801 struct video_mbuf vm;
1802
1803 DEBUG("PlanB: IOCTL VIDIOCGMBUF\n");
1804
1805 memset(&vm, 0 , sizeof(vm));
1806 vm.size = PLANB_MAX_FBUF * MAX_GBUFFERS;
1807 vm.frames = MAX_GBUFFERS;
1808 for(i = 0; i<MAX_GBUFFERS; i++)
1809 vm.offsets[i] = PLANB_MAX_FBUF * i;
1810 if(copy_to_user((void *)arg, (void *)&vm, sizeof(vm)))
1811 return -EFAULT;
1812 return 0;
1813 }
1814
1815 case PLANBIOCGSAAREGS:
1816 {
1817 struct planb_saa_regs preg;
1818
1819 DEBUG("PlanB: IOCTL PLANBIOCGSAAREGS\n");
1820
1821 if(copy_from_user(&preg, arg, sizeof(preg)))
1822 return -EFAULT;
1823 if(preg.addr >= SAA7196_NUMREGS)
1824 return -EINVAL;
1825 preg.val = saa_regs[pb->win.norm][preg.addr];
1826 if(copy_to_user((void *)arg, (void *)&preg,
1827 sizeof(preg)))
1828 return -EFAULT;
1829 return 0;
1830 }
1831
1832 case PLANBIOCSSAAREGS:
1833 {
1834 struct planb_saa_regs preg;
1835
1836 DEBUG("PlanB: IOCTL PLANBIOCSSAAREGS\n");
1837
1838 if(copy_from_user(&preg, arg, sizeof(preg)))
1839 return -EFAULT;
1840 if(preg.addr >= SAA7196_NUMREGS)
1841 return -EINVAL;
1842 saa_set (preg.addr, preg.val, pb);
1843 return 0;
1844 }
1845
1846 case PLANBIOCGSTAT:
1847 {
1848 struct planb_stat_regs pstat;
1849
1850 DEBUG("PlanB: IOCTL PLANBIOCGSTAT\n");
1851
1852 pstat.ch1_stat = in_le32(&pb->planb_base->ch1.status);
1853 pstat.ch2_stat = in_le32(&pb->planb_base->ch2.status);
1854 pstat.saa_stat0 = saa_status(0, pb);
1855 pstat.saa_stat1 = saa_status(1, pb);
1856
1857 if(copy_to_user((void *)arg, (void *)&pstat,
1858 sizeof(pstat)))
1859 return -EFAULT;
1860 return 0;
1861 }
1862
1863 case PLANBIOCSMODE: {
1864 int v;
1865
1866 DEBUG("PlanB: IOCTL PLANBIOCSMODE\n");
1867
1868 if(copy_from_user(&v, arg, sizeof(v)))
1869 return -EFAULT;
1870
1871 switch(v)
1872 {
1873 case PLANB_TV_MODE:
1874 saa_set (SAA7196_STDC,
1875 (saa_regs[pb->win.norm][SAA7196_STDC] &
1876 0x7f), pb);
1877 break;
1878 case PLANB_VTR_MODE:
1879 saa_set (SAA7196_STDC,
1880 (saa_regs[pb->win.norm][SAA7196_STDC] |
1881 0x80), pb);
1882 break;
1883 default:
1884 return -EINVAL;
1885 break;
1886 }
1887 pb->win.mode = v;
1888 return 0;
1889 }
1890 case PLANBIOCGMODE: {
1891 int v=pb->win.mode;
1892
1893 DEBUG("PlanB: IOCTL PLANBIOCGMODE\n");
1894
1895 if(copy_to_user(arg,&v,sizeof(v)))
1896 return -EFAULT;
1897 return 0;
1898 }
1899#ifdef PLANB_GSCANLINE
1900 case PLANBG_GRAB_BPL: {
1901 int v=pb->gbytes_per_line;
1902
1903 DEBUG("PlanB: IOCTL PLANBG_GRAB_BPL\n");
1904
1905 if(copy_to_user(arg,&v,sizeof(v)))
1906 return -EFAULT;
1907 return 0;
1908 }
1909#endif /* PLANB_GSCANLINE */
1910 case PLANB_INTR_DEBUG: {
1911 int i;
1912
1913 DEBUG("PlanB: IOCTL PLANB_INTR_DEBUG\n");
1914
1915 if(copy_from_user(&i, arg, sizeof(i)))
1916 return -EFAULT;
1917
1918 /* avoid hang ups all together */
1919 for (i = 0; i < MAX_GBUFFERS; i++) {
1920 if(pb->frame_stat[i] == GBUFFER_GRABBING) {
1921 pb->frame_stat[i] = GBUFFER_DONE;
1922 }
1923 }
1924 if(pb->grabbing)
1925 pb->grabbing--;
1926 wake_up_interruptible(&pb->capq);
1927 return 0;
1928 }
1929 case PLANB_INV_REGS: {
1930 int i;
1931 struct planb_any_regs any;
1932
1933 DEBUG("PlanB: IOCTL PLANB_INV_REGS\n");
1934
1935 if(copy_from_user(&any, arg, sizeof(any)))
1936 return -EFAULT;
1937 if(any.offset < 0 || any.offset + any.bytes > 0x400)
1938 return -EINVAL;
1939 if(any.bytes > 128)
1940 return -EINVAL;
1941 for (i = 0; i < any.bytes; i++) {
1942 any.data[i] =
1943 in_8((unsigned char *)pb->planb_base
1944 + any.offset + i);
1945 }
1946 if(copy_to_user(arg,&any,sizeof(any)))
1947 return -EFAULT;
1948 return 0;
1949 }
1950 default:
1951 {
1952 DEBUG("PlanB: Unimplemented IOCTL\n");
1953 return -ENOIOCTLCMD;
1954 }
1955 /* Some IOCTLs are currently unsupported on PlanB */
1956 case VIDIOCGTUNER: {
1957 DEBUG("PlanB: IOCTL VIDIOCGTUNER\n");
1958 goto unimplemented; }
1959 case VIDIOCSTUNER: {
1960 DEBUG("PlanB: IOCTL VIDIOCSTUNER\n");
1961 goto unimplemented; }
1962 case VIDIOCSFREQ: {
1963 DEBUG("PlanB: IOCTL VIDIOCSFREQ\n");
1964 goto unimplemented; }
1965 case VIDIOCGFREQ: {
1966 DEBUG("PlanB: IOCTL VIDIOCGFREQ\n");
1967 goto unimplemented; }
1968 case VIDIOCKEY: {
1969 DEBUG("PlanB: IOCTL VIDIOCKEY\n");
1970 goto unimplemented; }
1971 case VIDIOCSAUDIO: {
1972 DEBUG("PlanB: IOCTL VIDIOCSAUDIO\n");
1973 goto unimplemented; }
1974 case VIDIOCGAUDIO: {
1975 DEBUG("PlanB: IOCTL VIDIOCGAUDIO\n");
1976 goto unimplemented; }
1977unimplemented:
1978 DEBUG(" Unimplemented\n");
1979 return -ENOIOCTLCMD;
1980 }
1981 return 0;
1982}
1983
1984static int planb_mmap(struct vm_area_struct *vma, struct video_device *dev, const char *adr, unsigned long size)
1985{
1986 int i;
1987 struct planb *pb = (struct planb *)dev;
1988 unsigned long start = (unsigned long)adr;
1989
1990 if (size > MAX_GBUFFERS * PLANB_MAX_FBUF)
1991 return -EINVAL;
1992 if (!pb->rawbuf) {
1993 int err;
1994 if((err=grabbuf_alloc(pb)))
1995 return err;
1996 }
1997 for (i = 0; i < pb->rawbuf_size; i++) {
1998 unsigned long pfn;
1999
2000 pfn = virt_to_phys((void *)pb->rawbuf[i]) >> PAGE_SHIFT;
2001 if (remap_pfn_range(vma, start, pfn, PAGE_SIZE, PAGE_SHARED))
2002 return -EAGAIN;
2003 start += PAGE_SIZE;
2004 if (size <= PAGE_SIZE)
2005 break;
2006 size -= PAGE_SIZE;
2007 }
2008 return 0;
2009}
2010
2011static struct video_device planb_template=
2012{
2013 .owner = THIS_MODULE,
2014 .name = PLANB_DEVICE_NAME,
2015 .type = VID_TYPE_OVERLAY,
2016 .hardware = VID_HARDWARE_PLANB,
2017 .open = planb_open,
2018 .close = planb_close,
2019 .read = planb_read,
2020 .write = planb_write,
2021 .ioctl = planb_ioctl,
2022 .mmap = planb_mmap, /* mmap? */
2023};
2024
2025static int init_planb(struct planb *pb)
2026{
2027 unsigned char saa_rev;
2028 int i, result;
2029
2030 memset ((void *) &pb->win, 0, sizeof (struct planb_window));
2031 /* Simple sanity check */
2032 if(def_norm >= NUM_SUPPORTED_NORM || def_norm < 0) {
2033 printk(KERN_ERR "PlanB: Option(s) invalid\n");
2034 return -2;
2035 }
2036 pb->win.norm = def_norm;
2037 pb->win.mode = PLANB_TV_MODE; /* TV mode */
2038 pb->win.interlace=1;
2039 pb->win.x=0;
2040 pb->win.y=0;
2041 pb->win.width=768; /* 640 */
2042 pb->win.height=576; /* 480 */
2043 pb->maxlines=576;
2044#if 0
2045 btv->win.cropwidth=768; /* 640 */
2046 btv->win.cropheight=576; /* 480 */
2047 btv->win.cropx=0;
2048 btv->win.cropy=0;
2049#endif
2050 pb->win.pad=0;
2051 pb->win.bpp=4;
2052 pb->win.depth=32;
2053 pb->win.color_fmt=PLANB_COLOUR32;
2054 pb->win.bpl=1024*pb->win.bpp;
2055 pb->win.swidth=1024;
2056 pb->win.sheight=768;
2057#ifdef PLANB_GSCANLINE
2058 if((pb->gbytes_per_line = PLANB_MAXPIXELS * 4) > PAGE_SIZE
2059 || (pb->gbytes_per_line <= 0))
2060 return -3;
2061 else {
2062 /* page align pb->gbytes_per_line for DMA purpose */
2063 for(i = PAGE_SIZE; pb->gbytes_per_line < (i>>1);)
2064 i>>=1;
2065 pb->gbytes_per_line = i;
2066 }
2067#endif
2068 pb->tab_size = PLANB_MAXLINES + 40;
2069 pb->suspend = 0;
2070 init_MUTEX(&pb->lock);
2071 pb->ch1_cmd = 0;
2072 pb->ch2_cmd = 0;
2073 pb->mask = 0;
2074 pb->priv_space = 0;
2075 pb->offset = 0;
2076 pb->user = 0;
2077 pb->overlay = 0;
2078 init_waitqueue_head(&pb->suspendq);
2079 pb->cmd_buff_inited = 0;
2080 pb->frame_buffer_phys = 0;
2081
2082 /* Reset DMA controllers */
2083 planb_dbdma_stop(&pb->planb_base->ch2);
2084 planb_dbdma_stop(&pb->planb_base->ch1);
2085
2086 saa_rev = (saa_status(0, pb) & 0xf0) >> 4;
2087 printk(KERN_INFO "PlanB: SAA7196 video processor rev. %d\n", saa_rev);
2088 /* Initialize the SAA registers in memory and on chip */
2089 saa_init_regs (pb);
2090
2091 /* clear interrupt mask */
2092 pb->intr_mask = PLANB_CLR_IRQ;
2093
2094 result = request_irq(pb->irq, planb_irq, 0, "PlanB", (void *)pb);
2095 if (result < 0) {
2096 if (result==-EINVAL)
2097 printk(KERN_ERR "PlanB: Bad irq number (%d) "
2098 "or handler\n", (int)pb->irq);
2099 else if (result==-EBUSY)
2100 printk(KERN_ERR "PlanB: I don't know why, "
2101 "but IRQ %d is busy\n", (int)pb->irq);
2102 return result;
2103 }
2104 disable_irq(pb->irq);
2105
2106 /* Now add the template and register the device unit. */
2107 memcpy(&pb->video_dev,&planb_template,sizeof(planb_template));
2108
2109 pb->picture.brightness=0x90<<8;
2110 pb->picture.contrast = 0x70 << 8;
2111 pb->picture.colour = 0x70<<8;
2112 pb->picture.hue = 0x8000;
2113 pb->picture.whiteness = 0;
2114 pb->picture.depth = pb->win.depth;
2115
2116 pb->frame_stat=NULL;
2117 init_waitqueue_head(&pb->capq);
2118 for(i=0; i<MAX_GBUFFERS; i++) {
2119 pb->gbuf_idx[i] = PLANB_MAX_FBUF * i / PAGE_SIZE;
2120 pb->gwidth[i]=0;
2121 pb->gheight[i]=0;
2122 pb->gfmt[i]=0;
2123 pb->cap_cmd[i]=NULL;
2124#ifndef PLANB_GSCANLINE
2125 pb->l_fr_addr_idx[i] = MAX_GBUFFERS * (PLANB_MAX_FBUF
2126 / PAGE_SIZE + 1) + MAX_LNUM * i;
2127 pb->lsize[i] = 0;
2128 pb->lnum[i] = 0;
2129#endif
2130 }
2131 pb->rawbuf=NULL;
2132 pb->grabbing=0;
2133
2134 /* enable interrupts */
2135 out_le32(&pb->planb_base->intr_stat, PLANB_CLR_IRQ);
2136 pb->intr_mask = PLANB_FRM_IRQ;
2137 enable_irq(pb->irq);
2138
2139 if(video_register_device(&pb->video_dev, VFL_TYPE_GRABBER, video_nr)<0)
2140 return -1;
2141
2142 return 0;
2143}
2144
2145/*
2146 * Scan for a PlanB controller, request the irq and map the io memory
2147 */
2148
2149static int find_planb(void)
2150{
2151 struct planb *pb;
2152 struct device_node *planb_devices;
2153 unsigned char dev_fn, confreg, bus;
2154 unsigned int old_base, new_base;
2155 unsigned int irq;
2156 struct pci_dev *pdev;
2157 int rc;
2158
2159 if (_machine != _MACH_Pmac)
2160 return 0;
2161
2162 planb_devices = find_devices("planb");
2163 if (planb_devices == 0) {
2164 planb_num=0;
2165 printk(KERN_WARNING "PlanB: no device found!\n");
2166 return planb_num;
2167 }
2168
2169 if (planb_devices->next != NULL)
2170 printk(KERN_ERR "Warning: only using first PlanB device!\n");
2171 pb = &planbs[0];
2172 planb_num = 1;
2173
2174 if (planb_devices->n_addrs != 1) {
2175 printk (KERN_WARNING "PlanB: expecting 1 address for planb "
2176 "(got %d)", planb_devices->n_addrs);
2177 return 0;
2178 }
2179
2180 if (planb_devices->n_intrs == 0) {
2181 printk(KERN_WARNING "PlanB: no intrs for device %s\n",
2182 planb_devices->full_name);
2183 return 0;
2184 } else {
2185 irq = planb_devices->intrs[0].line;
2186 }
2187
2188 /* Initialize PlanB's PCI registers */
2189
2190 /* There is a bug with the way OF assigns addresses
2191 to the devices behind the chaos bridge.
2192 control needs only 0x1000 of space, but decodes only
2193 the upper 16 bits. It therefore occupies a full 64K.
2194 OF assigns the planb controller memory within this space;
2195 so we need to change that here in order to access planb. */
2196
2197 /* We remap to 0xf1000000 in hope that nobody uses it ! */
2198
2199 bus = (planb_devices->addrs[0].space >> 16) & 0xff;
2200 dev_fn = (planb_devices->addrs[0].space >> 8) & 0xff;
2201 confreg = planb_devices->addrs[0].space & 0xff;
2202 old_base = planb_devices->addrs[0].address;
2203 new_base = 0xf1000000;
2204
2205 DEBUG("PlanB: Found on bus %d, dev %d, func %d, "
2206 "membase 0x%x (base reg. 0x%x)\n",
2207 bus, PCI_SLOT(dev_fn), PCI_FUNC(dev_fn), old_base, confreg);
2208
2209 pdev = pci_find_slot (bus, dev_fn);
2210 if (!pdev) {
2211 printk(KERN_ERR "planb: cannot find slot\n");
2212 goto err_out;
2213 }
2214
2215 /* Enable response in memory space, bus mastering,
2216 use memory write and invalidate */
2217 rc = pci_enable_device(pdev);
2218 if (rc) {
2219 printk(KERN_ERR "planb: cannot enable PCI device %s\n",
2220 pci_name(pdev));
2221 goto err_out;
2222 }
2223 rc = pci_set_mwi(pdev);
2224 if (rc) {
2225 printk(KERN_ERR "planb: cannot enable MWI on PCI device %s\n",
2226 pci_name(pdev));
2227 goto err_out_disable;
2228 }
2229 pci_set_master(pdev);
2230
2231 /* Set the new base address */
2232 pci_write_config_dword (pdev, confreg, new_base);
2233
2234 planb_regs = (volatile struct planb_registers *)
2235 ioremap (new_base, 0x400);
2236 pb->planb_base = planb_regs;
2237 pb->planb_base_phys = (struct planb_registers *)new_base;
2238 pb->irq = irq;
2239
2240 return planb_num;
2241
2242err_out_disable:
2243 pci_disable_device(pdev);
2244err_out:
2245 /* FIXME handle error */ /* comment moved from pci_find_slot, above */
2246 return 0;
2247}
2248
2249static void release_planb(void)
2250{
2251 int i;
2252 struct planb *pb;
2253
2254 for (i=0;i<planb_num; i++)
2255 {
2256 pb=&planbs[i];
2257
2258 /* stop and flash DMAs unconditionally */
2259 planb_dbdma_stop(&pb->planb_base->ch2);
2260 planb_dbdma_stop(&pb->planb_base->ch1);
2261
2262 /* clear and free interrupts */
2263 pb->intr_mask = PLANB_CLR_IRQ;
2264 out_le32 (&pb->planb_base->intr_stat, PLANB_CLR_IRQ);
2265 free_irq(pb->irq, pb);
2266
2267 /* make sure all allocated memory are freed */
2268 planb_prepare_close(pb);
2269
2270 printk(KERN_INFO "PlanB: unregistering with v4l\n");
2271 video_unregister_device(&pb->video_dev);
2272
2273 /* note that iounmap() does nothing on the PPC right now */
2274 iounmap ((void *)pb->planb_base);
2275 }
2276}
2277
2278static int __init init_planbs(void)
2279{
2280 int i;
2281
2282 if (find_planb()<=0)
2283 return -EIO;
2284
2285 for (i=0; i<planb_num; i++) {
2286 if (init_planb(&planbs[i])<0) {
2287 printk(KERN_ERR "PlanB: error registering device %d"
2288 " with v4l\n", i);
2289 release_planb();
2290 return -EIO;
2291 }
2292 printk(KERN_INFO "PlanB: registered device %d with v4l\n", i);
2293 }
2294 return 0;
2295}
2296
2297static void __exit exit_planbs(void)
2298{
2299 release_planb();
2300}
2301
2302module_init(init_planbs);
2303module_exit(exit_planbs);
diff --git a/drivers/media/video/planb.h b/drivers/media/video/planb.h
new file mode 100644
index 00000000000..8a0faad1611
--- /dev/null
+++ b/drivers/media/video/planb.h
@@ -0,0 +1,231 @@
1/*
2 planb - PlanB frame grabber driver
3
4 PlanB is used in the 7x00/8x00 series of PowerMacintosh
5 Computers as video input DMA controller.
6
7 Copyright (C) 1998 Michel Lanners (mlan@cpu.lu)
8
9 Based largely on the bttv driver by Ralph Metzler (rjkm@thp.uni-koeln.de)
10
11 Additional debugging and coding by Takashi Oe (toe@unlserve.unl.edu)
12
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/* $Id: planb.h,v 1.13 1999/05/03 19:28:56 mlan Exp $ */
30
31#ifndef _PLANB_H_
32#define _PLANB_H_
33
34#ifdef __KERNEL__
35#include <asm/dbdma.h>
36#include "saa7196.h"
37#endif /* __KERNEL__ */
38
39#define PLANB_DEVICE_NAME "Apple PlanB Video-In"
40#define PLANB_REV "1.0"
41
42#ifdef __KERNEL__
43//#define PLANB_GSCANLINE /* use this if apps have the notion of */
44 /* grab buffer scanline */
45/* This should be safe for both PAL and NTSC */
46#define PLANB_MAXPIXELS 768
47#define PLANB_MAXLINES 576
48#define PLANB_NTSC_MAXLINES 480
49
50/* Uncomment your preferred norm ;-) */
51#define PLANB_DEF_NORM VIDEO_MODE_PAL
52//#define PLANB_DEF_NORM VIDEO_MODE_NTSC
53//#define PLANB_DEF_NORM VIDEO_MODE_SECAM
54
55/* fields settings */
56#define PLANB_GRAY 0x1 /* 8-bit mono? */
57#define PLANB_COLOUR15 0x2 /* 16-bit mode */
58#define PLANB_COLOUR32 0x4 /* 32-bit mode */
59#define PLANB_CLIPMASK 0x8 /* hardware clipmasking */
60
61/* misc. flags for PlanB DMA operation */
62#define CH_SYNC 0x1 /* synchronize channels (set by ch1;
63 cleared by ch2) */
64#define FIELD_SYNC 0x2 /* used for the start of each field
65 (0 -> 1 -> 0 for ch1; 0 -> 1 for ch2) */
66#define EVEN_FIELD 0x0 /* even field is detected if unset */
67#define DMA_ABORT 0x2 /* error or just out of sync if set */
68#define ODD_FIELD 0x4 /* odd field is detected if set */
69
70/* for capture operations */
71#define MAX_GBUFFERS 2
72/* note PLANB_MAX_FBUF must be divisible by PAGE_SIZE */
73#ifdef PLANB_GSCANLINE
74#define PLANB_MAX_FBUF 0x240000 /* 576 * 1024 * 4 */
75#define TAB_FACTOR (1)
76#else
77#define PLANB_MAX_FBUF 0x1b0000 /* 576 * 768 * 4 */
78#define TAB_FACTOR (2)
79#endif
80#endif /* __KERNEL__ */
81
82struct planb_saa_regs {
83 unsigned char addr;
84 unsigned char val;
85};
86
87struct planb_stat_regs {
88 unsigned int ch1_stat;
89 unsigned int ch2_stat;
90 unsigned char saa_stat0;
91 unsigned char saa_stat1;
92};
93
94struct planb_any_regs {
95 unsigned int offset;
96 unsigned int bytes;
97 unsigned char data[128];
98};
99
100/* planb private ioctls */
101#define PLANBIOCGSAAREGS _IOWR('v', BASE_VIDIOCPRIVATE, struct planb_saa_regs) /* Read a saa7196 reg value */
102#define PLANBIOCSSAAREGS _IOW('v', BASE_VIDIOCPRIVATE + 1, struct planb_saa_regs) /* Set a saa7196 reg value */
103#define PLANBIOCGSTAT _IOR('v', BASE_VIDIOCPRIVATE + 2, struct planb_stat_regs) /* Read planb status */
104#define PLANB_TV_MODE 1
105#define PLANB_VTR_MODE 2
106#define PLANBIOCGMODE _IOR('v', BASE_VIDIOCPRIVATE + 3, int) /* Get TV/VTR mode */
107#define PLANBIOCSMODE _IOW('v', BASE_VIDIOCPRIVATE + 4, int) /* Set TV/VTR mode */
108
109#ifdef PLANB_GSCANLINE
110#define PLANBG_GRAB_BPL _IOR('v', BASE_VIDIOCPRIVATE + 5, int) /* # of bytes per scanline in grab buffer */
111#endif
112
113/* call wake_up_interruptible() with appropriate actions */
114#define PLANB_INTR_DEBUG _IOW('v', BASE_VIDIOCPRIVATE + 20, int)
115/* investigate which reg does what */
116#define PLANB_INV_REGS _IOWR('v', BASE_VIDIOCPRIVATE + 21, struct planb_any_regs)
117
118#ifdef __KERNEL__
119
120/* Potentially useful macros */
121#define PLANB_SET(x) ((x) << 16 | (x))
122#define PLANB_CLR(x) ((x) << 16)
123
124/* This represents the physical register layout */
125struct planb_registers {
126 volatile struct dbdma_regs ch1; /* 0x00: video in */
127 volatile unsigned int even; /* 0x40: even field setting */
128 volatile unsigned int odd; /* 0x44; odd field setting */
129 unsigned int pad1[14]; /* empty? */
130 volatile struct dbdma_regs ch2; /* 0x80: clipmask out */
131 unsigned int pad2[16]; /* 0xc0: empty? */
132 volatile unsigned int reg3; /* 0x100: ???? */
133 volatile unsigned int intr_stat; /* 0x104: irq status */
134#define PLANB_CLR_IRQ 0x00 /* clear Plan B interrupt */
135#define PLANB_GEN_IRQ 0x01 /* assert Plan B interrupt */
136#define PLANB_FRM_IRQ 0x0100 /* end of frame */
137 unsigned int pad3[1]; /* empty? */
138 volatile unsigned int reg5; /* 0x10c: ??? */
139 unsigned int pad4[60]; /* empty? */
140 volatile unsigned char saa_addr; /* 0x200: SAA subadr */
141 char pad5[3];
142 volatile unsigned char saa_regval; /* SAA7196 write reg. val */
143 char pad6[3];
144 volatile unsigned char saa_status; /* SAA7196 status byte */
145 /* There is more unused stuff here */
146};
147
148struct planb_window {
149 int x, y;
150 ushort width, height;
151 ushort bpp, bpl, depth, pad;
152 ushort swidth, sheight;
153 int norm;
154 int interlace;
155 u32 color_fmt;
156 int chromakey;
157 int mode; /* used to switch between TV/VTR modes */
158};
159
160struct planb_suspend {
161 int overlay;
162 int frame;
163 struct dbdma_cmd cmd;
164};
165
166struct planb {
167 struct video_device video_dev;
168 struct video_picture picture; /* Current picture params */
169 struct video_audio audio_dev; /* Current audio params */
170
171 volatile struct planb_registers *planb_base; /* virt base of planb */
172 struct planb_registers *planb_base_phys; /* phys base of planb */
173 void *priv_space; /* Org. alloc. mem for kfree */
174 int user;
175 unsigned int tab_size;
176 int maxlines;
177 struct semaphore lock;
178 unsigned int irq; /* interrupt number */
179 volatile unsigned int intr_mask;
180
181 int overlay; /* overlay running? */
182 struct planb_window win;
183 unsigned long frame_buffer_phys; /* We need phys for DMA */
184 int offset; /* offset of pixel 1 */
185 volatile struct dbdma_cmd *ch1_cmd; /* Video In DMA cmd buffer */
186 volatile struct dbdma_cmd *ch2_cmd; /* Clip Out DMA cmd buffer */
187 volatile struct dbdma_cmd *overlay_last1;
188 volatile struct dbdma_cmd *overlay_last2;
189 unsigned long ch1_cmd_phys;
190 volatile unsigned char *mask; /* Clipmask buffer */
191 int suspend;
192 wait_queue_head_t suspendq;
193 struct planb_suspend suspended;
194 int cmd_buff_inited; /* cmd buffer inited? */
195
196 int grabbing;
197 unsigned int gcount;
198 wait_queue_head_t capq;
199 int last_fr;
200 int prev_last_fr;
201 unsigned char **rawbuf;
202 int rawbuf_size;
203 int gbuf_idx[MAX_GBUFFERS];
204 volatile struct dbdma_cmd *cap_cmd[MAX_GBUFFERS];
205 volatile struct dbdma_cmd *last_cmd[MAX_GBUFFERS];
206 volatile struct dbdma_cmd *pre_cmd[MAX_GBUFFERS];
207 int need_pre_capture[MAX_GBUFFERS];
208#define PLANB_DUMMY 40 /* # of command buf's allocated for pre-capture seq. */
209 int gwidth[MAX_GBUFFERS], gheight[MAX_GBUFFERS];
210 unsigned int gfmt[MAX_GBUFFERS];
211 int gnorm_switch[MAX_GBUFFERS];
212 volatile unsigned int *frame_stat;
213#define GBUFFER_UNUSED 0x00U
214#define GBUFFER_GRABBING 0x01U
215#define GBUFFER_DONE 0x02U
216#ifdef PLANB_GSCANLINE
217 int gbytes_per_line;
218#else
219#define MAX_LNUM 431 /* change this if PLANB_MAXLINES or */
220 /* PLANB_MAXPIXELS changes */
221 int l_fr_addr_idx[MAX_GBUFFERS];
222 unsigned char *l_to_addr[MAX_GBUFFERS][MAX_LNUM];
223 int l_to_next_idx[MAX_GBUFFERS][MAX_LNUM];
224 int l_to_next_size[MAX_GBUFFERS][MAX_LNUM];
225 int lsize[MAX_GBUFFERS], lnum[MAX_GBUFFERS];
226#endif
227};
228
229#endif /* __KERNEL__ */
230
231#endif /* _PLANB_H_ */
diff --git a/drivers/media/video/pms.c b/drivers/media/video/pms.c
new file mode 100644
index 00000000000..2504207b2e3
--- /dev/null
+++ b/drivers/media/video/pms.c
@@ -0,0 +1,1060 @@
1/*
2 * Media Vision Pro Movie Studio
3 * or
4 * "all you need is an I2C bus some RAM and a prayer"
5 *
6 * This draws heavily on code
7 *
8 * (c) Wolfgang Koehler, wolf@first.gmd.de, Dec. 1994
9 * Kiefernring 15
10 * 14478 Potsdam, Germany
11 *
12 * Most of this code is directly derived from his userspace driver.
13 * His driver works so send any reports to alan@redhat.com unless the
14 * userspace driver also doesn't work for you...
15 *
16 * Changes:
17 * 08/07/2003 Daniele Bellucci <bellucda@tiscali.it>
18 * - pms_capture: report back -EFAULT
19 */
20
21#include <linux/module.h>
22#include <linux/delay.h>
23#include <linux/errno.h>
24#include <linux/fs.h>
25#include <linux/kernel.h>
26#include <linux/slab.h>
27#include <linux/mm.h>
28#include <linux/ioport.h>
29#include <linux/init.h>
30#include <asm/io.h>
31#include <linux/sched.h>
32#include <linux/videodev.h>
33#include <asm/uaccess.h>
34
35
36#define MOTOROLA 1
37#define PHILIPS2 2
38#define PHILIPS1 3
39#define MVVMEMORYWIDTH 0x40 /* 512 bytes */
40
41struct pms_device
42{
43 struct video_device v;
44 struct video_picture picture;
45 int height;
46 int width;
47 struct semaphore lock;
48};
49
50struct i2c_info
51{
52 u8 slave;
53 u8 sub;
54 u8 data;
55 u8 hits;
56};
57
58static int i2c_count = 0;
59static struct i2c_info i2cinfo[64];
60
61static int decoder = PHILIPS2;
62static int standard = 0; /* 0 - auto 1 - ntsc 2 - pal 3 - secam */
63
64/*
65 * I/O ports and Shared Memory
66 */
67
68static int io_port = 0x250;
69static int data_port = 0x251;
70static int mem_base = 0xC8000;
71static void __iomem *mem;
72static int video_nr = -1;
73
74
75
76static inline void mvv_write(u8 index, u8 value)
77{
78 outw(index|(value<<8), io_port);
79}
80
81static inline u8 mvv_read(u8 index)
82{
83 outb(index, io_port);
84 return inb(data_port);
85}
86
87static int pms_i2c_stat(u8 slave)
88{
89 int counter;
90 int i;
91
92 outb(0x28, io_port);
93
94 counter=0;
95 while((inb(data_port)&0x01)==0)
96 if(counter++==256)
97 break;
98
99 while((inb(data_port)&0x01)!=0)
100 if(counter++==256)
101 break;
102
103 outb(slave, io_port);
104
105 counter=0;
106 while((inb(data_port)&0x01)==0)
107 if(counter++==256)
108 break;
109
110 while((inb(data_port)&0x01)!=0)
111 if(counter++==256)
112 break;
113
114 for(i=0;i<12;i++)
115 {
116 char st=inb(data_port);
117 if((st&2)!=0)
118 return -1;
119 if((st&1)==0)
120 break;
121 }
122 outb(0x29, io_port);
123 return inb(data_port);
124}
125
126static int pms_i2c_write(u16 slave, u16 sub, u16 data)
127{
128 int skip=0;
129 int count;
130 int i;
131
132 for(i=0;i<i2c_count;i++)
133 {
134 if((i2cinfo[i].slave==slave) &&
135 (i2cinfo[i].sub == sub))
136 {
137 if(i2cinfo[i].data==data)
138 skip=1;
139 i2cinfo[i].data=data;
140 i=i2c_count+1;
141 }
142 }
143
144 if(i==i2c_count && i2c_count<64)
145 {
146 i2cinfo[i2c_count].slave=slave;
147 i2cinfo[i2c_count].sub=sub;
148 i2cinfo[i2c_count].data=data;
149 i2c_count++;
150 }
151
152 if(skip)
153 return 0;
154
155 mvv_write(0x29, sub);
156 mvv_write(0x2A, data);
157 mvv_write(0x28, slave);
158
159 outb(0x28, io_port);
160
161 count=0;
162 while((inb(data_port)&1)==0)
163 if(count>255)
164 break;
165 while((inb(data_port)&1)!=0)
166 if(count>255)
167 break;
168
169 count=inb(data_port);
170
171 if(count&2)
172 return -1;
173 return count;
174}
175
176static int pms_i2c_read(int slave, int sub)
177{
178 int i=0;
179 for(i=0;i<i2c_count;i++)
180 {
181 if(i2cinfo[i].slave==slave && i2cinfo[i].sub==sub)
182 return i2cinfo[i].data;
183 }
184 return 0;
185}
186
187
188static void pms_i2c_andor(int slave, int sub, int and, int or)
189{
190 u8 tmp;
191
192 tmp=pms_i2c_read(slave, sub);
193 tmp = (tmp&and)|or;
194 pms_i2c_write(slave, sub, tmp);
195}
196
197/*
198 * Control functions
199 */
200
201
202static void pms_videosource(short source)
203{
204 mvv_write(0x2E, source?0x31:0x30);
205}
206
207static void pms_hue(short hue)
208{
209 switch(decoder)
210 {
211 case MOTOROLA:
212 pms_i2c_write(0x8A, 0x00, hue);
213 break;
214 case PHILIPS2:
215 pms_i2c_write(0x8A, 0x07, hue);
216 break;
217 case PHILIPS1:
218 pms_i2c_write(0x42, 0x07, hue);
219 break;
220 }
221}
222
223static void pms_colour(short colour)
224{
225 switch(decoder)
226 {
227 case MOTOROLA:
228 pms_i2c_write(0x8A, 0x00, colour);
229 break;
230 case PHILIPS1:
231 pms_i2c_write(0x42, 0x12, colour);
232 break;
233 }
234}
235
236
237static void pms_contrast(short contrast)
238{
239 switch(decoder)
240 {
241 case MOTOROLA:
242 pms_i2c_write(0x8A, 0x00, contrast);
243 break;
244 case PHILIPS1:
245 pms_i2c_write(0x42, 0x13, contrast);
246 break;
247 }
248}
249
250static void pms_brightness(short brightness)
251{
252 switch(decoder)
253 {
254 case MOTOROLA:
255 pms_i2c_write(0x8A, 0x00, brightness);
256 pms_i2c_write(0x8A, 0x00, brightness);
257 pms_i2c_write(0x8A, 0x00, brightness);
258 break;
259 case PHILIPS1:
260 pms_i2c_write(0x42, 0x19, brightness);
261 break;
262 }
263}
264
265
266static void pms_format(short format)
267{
268 int target;
269 standard = format;
270
271 if(decoder==PHILIPS1)
272 target=0x42;
273 else if(decoder==PHILIPS2)
274 target=0x8A;
275 else
276 return;
277
278 switch(format)
279 {
280 case 0: /* Auto */
281 pms_i2c_andor(target, 0x0D, 0xFE,0x00);
282 pms_i2c_andor(target, 0x0F, 0x3F,0x80);
283 break;
284 case 1: /* NTSC */
285 pms_i2c_andor(target, 0x0D, 0xFE, 0x00);
286 pms_i2c_andor(target, 0x0F, 0x3F, 0x40);
287 break;
288 case 2: /* PAL */
289 pms_i2c_andor(target, 0x0D, 0xFE, 0x00);
290 pms_i2c_andor(target, 0x0F, 0x3F, 0x00);
291 break;
292 case 3: /* SECAM */
293 pms_i2c_andor(target, 0x0D, 0xFE, 0x01);
294 pms_i2c_andor(target, 0x0F, 0x3F, 0x00);
295 break;
296 }
297}
298
299#ifdef FOR_FUTURE_EXPANSION
300
301/*
302 * These features of the PMS card are not currently exposes. They
303 * could become a private v4l ioctl for PMSCONFIG or somesuch if
304 * people need it. We also don't yet use the PMS interrupt.
305 */
306
307static void pms_hstart(short start)
308{
309 switch(decoder)
310 {
311 case PHILIPS1:
312 pms_i2c_write(0x8A, 0x05, start);
313 pms_i2c_write(0x8A, 0x18, start);
314 break;
315 case PHILIPS2:
316 pms_i2c_write(0x42, 0x05, start);
317 pms_i2c_write(0x42, 0x18, start);
318 break;
319 }
320}
321
322/*
323 * Bandpass filters
324 */
325
326static void pms_bandpass(short pass)
327{
328 if(decoder==PHILIPS2)
329 pms_i2c_andor(0x8A, 0x06, 0xCF, (pass&0x03)<<4);
330 else if(decoder==PHILIPS1)
331 pms_i2c_andor(0x42, 0x06, 0xCF, (pass&0x03)<<4);
332}
333
334static void pms_antisnow(short snow)
335{
336 if(decoder==PHILIPS2)
337 pms_i2c_andor(0x8A, 0x06, 0xF3, (snow&0x03)<<2);
338 else if(decoder==PHILIPS1)
339 pms_i2c_andor(0x42, 0x06, 0xF3, (snow&0x03)<<2);
340}
341
342static void pms_sharpness(short sharp)
343{
344 if(decoder==PHILIPS2)
345 pms_i2c_andor(0x8A, 0x06, 0xFC, sharp&0x03);
346 else if(decoder==PHILIPS1)
347 pms_i2c_andor(0x42, 0x06, 0xFC, sharp&0x03);
348}
349
350static void pms_chromaagc(short agc)
351{
352 if(decoder==PHILIPS2)
353 pms_i2c_andor(0x8A, 0x0C, 0x9F, (agc&0x03)<<5);
354 else if(decoder==PHILIPS1)
355 pms_i2c_andor(0x42, 0x0C, 0x9F, (agc&0x03)<<5);
356}
357
358static void pms_vertnoise(short noise)
359{
360 if(decoder==PHILIPS2)
361 pms_i2c_andor(0x8A, 0x10, 0xFC, noise&3);
362 else if(decoder==PHILIPS1)
363 pms_i2c_andor(0x42, 0x10, 0xFC, noise&3);
364}
365
366static void pms_forcecolour(short colour)
367{
368 if(decoder==PHILIPS2)
369 pms_i2c_andor(0x8A, 0x0C, 0x7F, (colour&1)<<7);
370 else if(decoder==PHILIPS1)
371 pms_i2c_andor(0x42, 0x0C, 0x7, (colour&1)<<7);
372}
373
374static void pms_antigamma(short gamma)
375{
376 if(decoder==PHILIPS2)
377 pms_i2c_andor(0xB8, 0x00, 0x7F, (gamma&1)<<7);
378 else if(decoder==PHILIPS1)
379 pms_i2c_andor(0x42, 0x20, 0x7, (gamma&1)<<7);
380}
381
382static void pms_prefilter(short filter)
383{
384 if(decoder==PHILIPS2)
385 pms_i2c_andor(0x8A, 0x06, 0xBF, (filter&1)<<6);
386 else if(decoder==PHILIPS1)
387 pms_i2c_andor(0x42, 0x06, 0xBF, (filter&1)<<6);
388}
389
390static void pms_hfilter(short filter)
391{
392 if(decoder==PHILIPS2)
393 pms_i2c_andor(0xB8, 0x04, 0x1F, (filter&7)<<5);
394 else if(decoder==PHILIPS1)
395 pms_i2c_andor(0x42, 0x24, 0x1F, (filter&7)<<5);
396}
397
398static void pms_vfilter(short filter)
399{
400 if(decoder==PHILIPS2)
401 pms_i2c_andor(0xB8, 0x08, 0x9F, (filter&3)<<5);
402 else if(decoder==PHILIPS1)
403 pms_i2c_andor(0x42, 0x28, 0x9F, (filter&3)<<5);
404}
405
406static void pms_killcolour(short colour)
407{
408 if(decoder==PHILIPS2)
409 {
410 pms_i2c_andor(0x8A, 0x08, 0x07, (colour&0x1F)<<3);
411 pms_i2c_andor(0x8A, 0x09, 0x07, (colour&0x1F)<<3);
412 }
413 else if(decoder==PHILIPS1)
414 {
415 pms_i2c_andor(0x42, 0x08, 0x07, (colour&0x1F)<<3);
416 pms_i2c_andor(0x42, 0x09, 0x07, (colour&0x1F)<<3);
417 }
418}
419
420static void pms_chromagain(short chroma)
421{
422 if(decoder==PHILIPS2)
423 {
424 pms_i2c_write(0x8A, 0x11, chroma);
425 }
426 else if(decoder==PHILIPS1)
427 {
428 pms_i2c_write(0x42, 0x11, chroma);
429 }
430}
431
432
433static void pms_spacialcompl(short data)
434{
435 mvv_write(0x3B, data);
436}
437
438static void pms_spacialcomph(short data)
439{
440 mvv_write(0x3A, data);
441}
442
443static void pms_vstart(short start)
444{
445 mvv_write(0x16, start);
446 mvv_write(0x17, (start>>8)&0x01);
447}
448
449#endif
450
451static void pms_secamcross(short cross)
452{
453 if(decoder==PHILIPS2)
454 pms_i2c_andor(0x8A, 0x0F, 0xDF, (cross&1)<<5);
455 else if(decoder==PHILIPS1)
456 pms_i2c_andor(0x42, 0x0F, 0xDF, (cross&1)<<5);
457}
458
459
460static void pms_swsense(short sense)
461{
462 if(decoder==PHILIPS2)
463 {
464 pms_i2c_write(0x8A, 0x0A, sense);
465 pms_i2c_write(0x8A, 0x0B, sense);
466 }
467 else if(decoder==PHILIPS1)
468 {
469 pms_i2c_write(0x42, 0x0A, sense);
470 pms_i2c_write(0x42, 0x0B, sense);
471 }
472}
473
474
475static void pms_framerate(short frr)
476{
477 int fps=(standard==1)?30:25;
478 if(frr==0)
479 return;
480 fps=fps/frr;
481 mvv_write(0x14,0x80|fps);
482 mvv_write(0x15,1);
483}
484
485static void pms_vert(u8 deciden, u8 decinum)
486{
487 mvv_write(0x1C, deciden); /* Denominator */
488 mvv_write(0x1D, decinum); /* Numerator */
489}
490
491/*
492 * Turn 16bit ratios into best small ratio the chipset can grok
493 */
494
495static void pms_vertdeci(unsigned short decinum, unsigned short deciden)
496{
497 /* Knock it down by /5 once */
498 if(decinum%5==0)
499 {
500 deciden/=5;
501 decinum/=5;
502 }
503 /*
504 * 3's
505 */
506 while(decinum%3==0 && deciden%3==0)
507 {
508 deciden/=3;
509 decinum/=3;
510 }
511 /*
512 * 2's
513 */
514 while(decinum%2==0 && deciden%2==0)
515 {
516 decinum/=2;
517 deciden/=2;
518 }
519 /*
520 * Fudgyify
521 */
522 while(deciden>32)
523 {
524 deciden/=2;
525 decinum=(decinum+1)/2;
526 }
527 if(deciden==32)
528 deciden--;
529 pms_vert(deciden,decinum);
530}
531
532static void pms_horzdeci(short decinum, short deciden)
533{
534 if(decinum<=512)
535 {
536 if(decinum%5==0)
537 {
538 decinum/=5;
539 deciden/=5;
540 }
541 }
542 else
543 {
544 decinum=512;
545 deciden=640; /* 768 would be ideal */
546 }
547
548 while(((decinum|deciden)&1)==0)
549 {
550 decinum>>=1;
551 deciden>>=1;
552 }
553 while(deciden>32)
554 {
555 deciden>>=1;
556 decinum=(decinum+1)>>1;
557 }
558 if(deciden==32)
559 deciden--;
560
561 mvv_write(0x24, 0x80|deciden);
562 mvv_write(0x25, decinum);
563}
564
565static void pms_resolution(short width, short height)
566{
567 int fg_height;
568
569 fg_height=height;
570 if(fg_height>280)
571 fg_height=280;
572
573 mvv_write(0x18, fg_height);
574 mvv_write(0x19, fg_height>>8);
575
576 if(standard==1)
577 {
578 mvv_write(0x1A, 0xFC);
579 mvv_write(0x1B, 0x00);
580 if(height>fg_height)
581 pms_vertdeci(240,240);
582 else
583 pms_vertdeci(fg_height,240);
584 }
585 else
586 {
587 mvv_write(0x1A, 0x1A);
588 mvv_write(0x1B, 0x01);
589 if(fg_height>256)
590 pms_vertdeci(270,270);
591 else
592 pms_vertdeci(fg_height, 270);
593 }
594 mvv_write(0x12,0);
595 mvv_write(0x13, MVVMEMORYWIDTH);
596 mvv_write(0x42, 0x00);
597 mvv_write(0x43, 0x00);
598 mvv_write(0x44, MVVMEMORYWIDTH);
599
600 mvv_write(0x22, width+8);
601 mvv_write(0x23, (width+8)>> 8);
602
603 if(standard==1)
604 pms_horzdeci(width,640);
605 else
606 pms_horzdeci(width+8, 768);
607
608 mvv_write(0x30, mvv_read(0x30)&0xFE);
609 mvv_write(0x08, mvv_read(0x08)|0x01);
610 mvv_write(0x01, mvv_read(0x01)&0xFD);
611 mvv_write(0x32, 0x00);
612 mvv_write(0x33, MVVMEMORYWIDTH);
613}
614
615
616/*
617 * Set Input
618 */
619
620static void pms_vcrinput(short input)
621{
622 if(decoder==PHILIPS2)
623 pms_i2c_andor(0x8A,0x0D,0x7F,(input&1)<<7);
624 else if(decoder==PHILIPS1)
625 pms_i2c_andor(0x42,0x0D,0x7F,(input&1)<<7);
626}
627
628
629static int pms_capture(struct pms_device *dev, char __user *buf, int rgb555, int count)
630{
631 int y;
632 int dw = 2*dev->width;
633
634 char tmp[dw+32]; /* using a temp buffer is faster than direct */
635 int cnt = 0;
636 int len=0;
637 unsigned char r8 = 0x5; /* value for reg8 */
638
639 if (rgb555)
640 r8 |= 0x20; /* else use untranslated rgb = 565 */
641 mvv_write(0x08,r8); /* capture rgb555/565, init DRAM, PC enable */
642
643/* printf("%d %d %d %d %d %x %x\n",width,height,voff,nom,den,mvv_buf); */
644
645 for (y = 0; y < dev->height; y++ )
646 {
647 writeb(0, mem); /* synchronisiert neue Zeile */
648
649 /*
650 * This is in truth a fifo, be very careful as if you
651 * forgot this odd things will occur 8)
652 */
653
654 memcpy_fromio(tmp, mem, dw+32); /* discard 16 word */
655 cnt -= dev->height;
656 while (cnt <= 0)
657 {
658 /*
659 * Don't copy too far
660 */
661 int dt=dw;
662 if(dt+len>count)
663 dt=count-len;
664 cnt += dev->height;
665 if (copy_to_user(buf, tmp+32, dt))
666 return len ? len : -EFAULT;
667 buf += dt;
668 len += dt;
669 }
670 }
671 return len;
672}
673
674
675/*
676 * Video4linux interfacing
677 */
678
679static int pms_do_ioctl(struct inode *inode, struct file *file,
680 unsigned int cmd, void *arg)
681{
682 struct video_device *dev = video_devdata(file);
683 struct pms_device *pd=(struct pms_device *)dev;
684
685 switch(cmd)
686 {
687 case VIDIOCGCAP:
688 {
689 struct video_capability *b = arg;
690 strcpy(b->name, "Mediavision PMS");
691 b->type = VID_TYPE_CAPTURE|VID_TYPE_SCALES;
692 b->channels = 4;
693 b->audios = 0;
694 b->maxwidth = 640;
695 b->maxheight = 480;
696 b->minwidth = 16;
697 b->minheight = 16;
698 return 0;
699 }
700 case VIDIOCGCHAN:
701 {
702 struct video_channel *v = arg;
703 if(v->channel<0 || v->channel>3)
704 return -EINVAL;
705 v->flags=0;
706 v->tuners=1;
707 /* Good question.. its composite or SVHS so.. */
708 v->type = VIDEO_TYPE_CAMERA;
709 switch(v->channel)
710 {
711 case 0:
712 strcpy(v->name, "Composite");break;
713 case 1:
714 strcpy(v->name, "SVideo");break;
715 case 2:
716 strcpy(v->name, "Composite(VCR)");break;
717 case 3:
718 strcpy(v->name, "SVideo(VCR)");break;
719 }
720 return 0;
721 }
722 case VIDIOCSCHAN:
723 {
724 struct video_channel *v = arg;
725 if(v->channel<0 || v->channel>3)
726 return -EINVAL;
727 down(&pd->lock);
728 pms_videosource(v->channel&1);
729 pms_vcrinput(v->channel>>1);
730 up(&pd->lock);
731 return 0;
732 }
733 case VIDIOCGTUNER:
734 {
735 struct video_tuner *v = arg;
736 if(v->tuner)
737 return -EINVAL;
738 strcpy(v->name, "Format");
739 v->rangelow=0;
740 v->rangehigh=0;
741 v->flags= VIDEO_TUNER_PAL|VIDEO_TUNER_NTSC|VIDEO_TUNER_SECAM;
742 switch(standard)
743 {
744 case 0:
745 v->mode = VIDEO_MODE_AUTO;
746 break;
747 case 1:
748 v->mode = VIDEO_MODE_NTSC;
749 break;
750 case 2:
751 v->mode = VIDEO_MODE_PAL;
752 break;
753 case 3:
754 v->mode = VIDEO_MODE_SECAM;
755 break;
756 }
757 return 0;
758 }
759 case VIDIOCSTUNER:
760 {
761 struct video_tuner *v = arg;
762 if(v->tuner)
763 return -EINVAL;
764 down(&pd->lock);
765 switch(v->mode)
766 {
767 case VIDEO_MODE_AUTO:
768 pms_framerate(25);
769 pms_secamcross(0);
770 pms_format(0);
771 break;
772 case VIDEO_MODE_NTSC:
773 pms_framerate(30);
774 pms_secamcross(0);
775 pms_format(1);
776 break;
777 case VIDEO_MODE_PAL:
778 pms_framerate(25);
779 pms_secamcross(0);
780 pms_format(2);
781 break;
782 case VIDEO_MODE_SECAM:
783 pms_framerate(25);
784 pms_secamcross(1);
785 pms_format(2);
786 break;
787 default:
788 up(&pd->lock);
789 return -EINVAL;
790 }
791 up(&pd->lock);
792 return 0;
793 }
794 case VIDIOCGPICT:
795 {
796 struct video_picture *p = arg;
797 *p = pd->picture;
798 return 0;
799 }
800 case VIDIOCSPICT:
801 {
802 struct video_picture *p = arg;
803 if(!((p->palette==VIDEO_PALETTE_RGB565 && p->depth==16)
804 ||(p->palette==VIDEO_PALETTE_RGB555 && p->depth==15)))
805 return -EINVAL;
806 pd->picture= *p;
807
808 /*
809 * Now load the card.
810 */
811
812 down(&pd->lock);
813 pms_brightness(p->brightness>>8);
814 pms_hue(p->hue>>8);
815 pms_colour(p->colour>>8);
816 pms_contrast(p->contrast>>8);
817 up(&pd->lock);
818 return 0;
819 }
820 case VIDIOCSWIN:
821 {
822 struct video_window *vw = arg;
823 if(vw->flags)
824 return -EINVAL;
825 if(vw->clipcount)
826 return -EINVAL;
827 if(vw->height<16||vw->height>480)
828 return -EINVAL;
829 if(vw->width<16||vw->width>640)
830 return -EINVAL;
831 pd->width=vw->width;
832 pd->height=vw->height;
833 down(&pd->lock);
834 pms_resolution(pd->width, pd->height);
835 up(&pd->lock); /* Ok we figured out what to use from our wide choice */
836 return 0;
837 }
838 case VIDIOCGWIN:
839 {
840 struct video_window *vw = arg;
841 memset(vw,0,sizeof(*vw));
842 vw->width=pd->width;
843 vw->height=pd->height;
844 return 0;
845 }
846 case VIDIOCKEY:
847 return 0;
848 case VIDIOCCAPTURE:
849 case VIDIOCGFBUF:
850 case VIDIOCSFBUF:
851 case VIDIOCGFREQ:
852 case VIDIOCSFREQ:
853 case VIDIOCGAUDIO:
854 case VIDIOCSAUDIO:
855 return -EINVAL;
856 default:
857 return -ENOIOCTLCMD;
858 }
859 return 0;
860}
861
862static int pms_ioctl(struct inode *inode, struct file *file,
863 unsigned int cmd, unsigned long arg)
864{
865 return video_usercopy(inode, file, cmd, arg, pms_do_ioctl);
866}
867
868static ssize_t pms_read(struct file *file, char __user *buf,
869 size_t count, loff_t *ppos)
870{
871 struct video_device *v = video_devdata(file);
872 struct pms_device *pd=(struct pms_device *)v;
873 int len;
874
875 down(&pd->lock);
876 len=pms_capture(pd, buf, (pd->picture.depth==16)?0:1,count);
877 up(&pd->lock);
878 return len;
879}
880
881static struct file_operations pms_fops = {
882 .owner = THIS_MODULE,
883 .open = video_exclusive_open,
884 .release = video_exclusive_release,
885 .ioctl = pms_ioctl,
886 .read = pms_read,
887 .llseek = no_llseek,
888};
889
890static struct video_device pms_template=
891{
892 .owner = THIS_MODULE,
893 .name = "Mediavision PMS",
894 .type = VID_TYPE_CAPTURE,
895 .hardware = VID_HARDWARE_PMS,
896 .fops = &pms_fops,
897};
898
899static struct pms_device pms_device;
900
901
902/*
903 * Probe for and initialise the Mediavision PMS
904 */
905
906static int init_mediavision(void)
907{
908 int id;
909 int idec, decst;
910 int i;
911
912 unsigned char i2c_defs[]={
913 0x4C,0x30,0x00,0xE8,
914 0xB6,0xE2,0x00,0x00,
915 0xFF,0xFF,0x00,0x00,
916 0x00,0x00,0x78,0x98,
917 0x00,0x00,0x00,0x00,
918 0x34,0x0A,0xF4,0xCE,
919 0xE4
920 };
921
922 mem = ioremap(mem_base, 0x800);
923 if (!mem)
924 return -ENOMEM;
925
926 if (!request_region(0x9A01, 1, "Mediavision PMS config"))
927 {
928 printk(KERN_WARNING "mediavision: unable to detect: 0x9A01 in use.\n");
929 iounmap(mem);
930 return -EBUSY;
931 }
932 if (!request_region(io_port, 3, "Mediavision PMS"))
933 {
934 printk(KERN_WARNING "mediavision: I/O port %d in use.\n", io_port);
935 release_region(0x9A01, 1);
936 iounmap(mem);
937 return -EBUSY;
938 }
939 outb(0xB8, 0x9A01); /* Unlock */
940 outb(io_port>>4, 0x9A01); /* Set IO port */
941
942
943 id=mvv_read(3);
944 decst=pms_i2c_stat(0x43);
945
946 if(decst!=-1)
947 idec=2;
948 else if(pms_i2c_stat(0xb9)!=-1)
949 idec=3;
950 else if(pms_i2c_stat(0x8b)!=-1)
951 idec=1;
952 else
953 idec=0;
954
955 printk(KERN_INFO "PMS type is %d\n", idec);
956 if(idec == 0) {
957 release_region(io_port, 3);
958 release_region(0x9A01, 1);
959 iounmap(mem);
960 return -ENODEV;
961 }
962
963 /*
964 * Ok we have a PMS of some sort
965 */
966
967 mvv_write(0x04, mem_base>>12); /* Set the memory area */
968
969 /* Ok now load the defaults */
970
971 for(i=0;i<0x19;i++)
972 {
973 if(i2c_defs[i]==0xFF)
974 pms_i2c_andor(0x8A, i, 0x07,0x00);
975 else
976 pms_i2c_write(0x8A, i, i2c_defs[i]);
977 }
978
979 pms_i2c_write(0xB8,0x00,0x12);
980 pms_i2c_write(0xB8,0x04,0x00);
981 pms_i2c_write(0xB8,0x07,0x00);
982 pms_i2c_write(0xB8,0x08,0x00);
983 pms_i2c_write(0xB8,0x09,0xFF);
984 pms_i2c_write(0xB8,0x0A,0x00);
985 pms_i2c_write(0xB8,0x0B,0x10);
986 pms_i2c_write(0xB8,0x10,0x03);
987
988 mvv_write(0x01, 0x00);
989 mvv_write(0x05, 0xA0);
990 mvv_write(0x08, 0x25);
991 mvv_write(0x09, 0x00);
992 mvv_write(0x0A, 0x20|MVVMEMORYWIDTH);
993
994 mvv_write(0x10, 0x02);
995 mvv_write(0x1E, 0x0C);
996 mvv_write(0x1F, 0x03);
997 mvv_write(0x26, 0x06);
998
999 mvv_write(0x2B, 0x00);
1000 mvv_write(0x2C, 0x20);
1001 mvv_write(0x2D, 0x00);
1002 mvv_write(0x2F, 0x70);
1003 mvv_write(0x32, 0x00);
1004 mvv_write(0x33, MVVMEMORYWIDTH);
1005 mvv_write(0x34, 0x00);
1006 mvv_write(0x35, 0x00);
1007 mvv_write(0x3A, 0x80);
1008 mvv_write(0x3B, 0x10);
1009 mvv_write(0x20, 0x00);
1010 mvv_write(0x21, 0x00);
1011 mvv_write(0x30, 0x22);
1012 return 0;
1013}
1014
1015/*
1016 * Initialization and module stuff
1017 */
1018
1019static int __init init_pms_cards(void)
1020{
1021 printk(KERN_INFO "Mediavision Pro Movie Studio driver 0.02\n");
1022
1023 data_port = io_port +1;
1024
1025 if(init_mediavision())
1026 {
1027 printk(KERN_INFO "Board not found.\n");
1028 return -ENODEV;
1029 }
1030 memcpy(&pms_device, &pms_template, sizeof(pms_template));
1031 init_MUTEX(&pms_device.lock);
1032 pms_device.height=240;
1033 pms_device.width=320;
1034 pms_swsense(75);
1035 pms_resolution(320,240);
1036 return video_register_device((struct video_device *)&pms_device, VFL_TYPE_GRABBER, video_nr);
1037}
1038
1039module_param(io_port, int, 0);
1040module_param(mem_base, int, 0);
1041module_param(video_nr, int, 0);
1042MODULE_LICENSE("GPL");
1043
1044
1045static void __exit shutdown_mediavision(void)
1046{
1047 release_region(io_port,3);
1048 release_region(0x9A01, 1);
1049}
1050
1051static void __exit cleanup_pms_module(void)
1052{
1053 shutdown_mediavision();
1054 video_unregister_device((struct video_device *)&pms_device);
1055 iounmap(mem);
1056}
1057
1058module_init(init_pms_cards);
1059module_exit(cleanup_pms_module);
1060
diff --git a/drivers/media/video/saa5246a.c b/drivers/media/video/saa5246a.c
new file mode 100644
index 00000000000..ba69f09cbdd
--- /dev/null
+++ b/drivers/media/video/saa5246a.c
@@ -0,0 +1,843 @@
1/*
2 * Driver for the SAA5246A or SAA5281 Teletext (=Videotext) decoder chips from
3 * Philips.
4 *
5 * Only capturing of Teletext pages is tested. The videotext chips also have a
6 * TV output but my hardware doesn't use it. For this reason this driver does
7 * not support changing any TV display settings.
8 *
9 * Copyright (C) 2004 Michael Geng <linux@MichaelGeng.de>
10 *
11 * Derived from
12 *
13 * saa5249 driver
14 * Copyright (C) 1998 Richard Guenther
15 * <richard.guenther@student.uni-tuebingen.de>
16 *
17 * with changes by
18 * Alan Cox <Alan.Cox@linux.org>
19 *
20 * and
21 *
22 * vtx.c
23 * Copyright (C) 1994-97 Martin Buck <martin-2.buck@student.uni-ulm.de>
24 *
25 * This program is free software; you can redistribute it and/or modify
26 * it under the terms of the GNU General Public License as published by
27 * the Free Software Foundation; either version 2 of the License, or
28 * (at your option) any later version.
29 *
30 * This program is distributed in the hope that it will be useful,
31 * but WITHOUT ANY WARRANTY; without even the implied warranty of
32 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33 * GNU General Public License for more details.
34 *
35 * You should have received a copy of the GNU General Public License
36 * along with this program; if not, write to the Free Software
37 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
38 * USA.
39 */
40
41#include <linux/module.h>
42#include <linux/kernel.h>
43#include <linux/sched.h>
44#include <linux/mm.h>
45#include <linux/init.h>
46#include <linux/i2c.h>
47#include <linux/videotext.h>
48#include <linux/videodev.h>
49#include "saa5246a.h"
50
51MODULE_AUTHOR("Michael Geng <linux@MichaelGeng.de>");
52MODULE_DESCRIPTION("Philips SAA5246A, SAA5281 Teletext decoder driver");
53MODULE_LICENSE("GPL");
54
55struct saa5246a_device
56{
57 u8 pgbuf[NUM_DAUS][VTX_VIRTUALSIZE];
58 int is_searching[NUM_DAUS];
59 struct i2c_client *client;
60 struct semaphore lock;
61};
62
63static struct video_device saa_template; /* Declared near bottom */
64
65/* Addresses to scan */
66static unsigned short normal_i2c[] = { I2C_ADDRESS, I2C_CLIENT_END };
67static unsigned short normal_i2c_range[] = { I2C_CLIENT_END };
68I2C_CLIENT_INSMOD;
69
70static struct i2c_client client_template;
71
72static int saa5246a_attach(struct i2c_adapter *adap, int addr, int kind)
73{
74 int pgbuf;
75 int err;
76 struct i2c_client *client;
77 struct video_device *vd;
78 struct saa5246a_device *t;
79
80 printk(KERN_INFO "saa5246a: teletext chip found.\n");
81 client=kmalloc(sizeof(*client), GFP_KERNEL);
82 if(client==NULL)
83 return -ENOMEM;
84 client_template.adapter = adap;
85 client_template.addr = addr;
86 memcpy(client, &client_template, sizeof(*client));
87 t = kmalloc(sizeof(*t), GFP_KERNEL);
88 if(t==NULL)
89 {
90 kfree(client);
91 return -ENOMEM;
92 }
93 memset(t, 0, sizeof(*t));
94 strlcpy(client->name, IF_NAME, I2C_NAME_SIZE);
95 init_MUTEX(&t->lock);
96
97 /*
98 * Now create a video4linux device
99 */
100
101 vd = video_device_alloc();
102 if(vd==NULL)
103 {
104 kfree(t);
105 kfree(client);
106 return -ENOMEM;
107 }
108 i2c_set_clientdata(client, vd);
109 memcpy(vd, &saa_template, sizeof(*vd));
110
111 for (pgbuf = 0; pgbuf < NUM_DAUS; pgbuf++)
112 {
113 memset(t->pgbuf[pgbuf], ' ', sizeof(t->pgbuf[0]));
114 t->is_searching[pgbuf] = FALSE;
115 }
116 vd->priv=t;
117
118
119 /*
120 * Register it
121 */
122
123 if((err=video_register_device(vd, VFL_TYPE_VTX,-1))<0)
124 {
125 kfree(t);
126 kfree(client);
127 video_device_release(vd);
128 return err;
129 }
130 t->client = client;
131 i2c_attach_client(client);
132 return 0;
133}
134
135/*
136 * We do most of the hard work when we become a device on the i2c.
137 */
138static int saa5246a_probe(struct i2c_adapter *adap)
139{
140 if (adap->class & I2C_CLASS_TV_ANALOG)
141 return i2c_probe(adap, &addr_data, saa5246a_attach);
142 return 0;
143}
144
145static int saa5246a_detach(struct i2c_client *client)
146{
147 struct video_device *vd = i2c_get_clientdata(client);
148 i2c_detach_client(client);
149 video_unregister_device(vd);
150 kfree(vd->priv);
151 kfree(client);
152 return 0;
153}
154
155static int saa5246a_command(struct i2c_client *device, unsigned int cmd,
156 void *arg)
157{
158 return -EINVAL;
159}
160
161/*
162 * I2C interfaces
163 */
164
165static struct i2c_driver i2c_driver_videotext =
166{
167 .owner = THIS_MODULE,
168 .name = IF_NAME, /* name */
169 .id = I2C_DRIVERID_SAA5249, /* in i2c.h */
170 .flags = I2C_DF_NOTIFY,
171 .attach_adapter = saa5246a_probe,
172 .detach_client = saa5246a_detach,
173 .command = saa5246a_command
174};
175
176static struct i2c_client client_template = {
177 .driver = &i2c_driver_videotext,
178 .name = "(unset)",
179};
180
181static int i2c_sendbuf(struct saa5246a_device *t, int reg, int count, u8 *data)
182{
183 char buf[64];
184
185 buf[0] = reg;
186 memcpy(buf+1, data, count);
187
188 if(i2c_master_send(t->client, buf, count+1)==count+1)
189 return 0;
190 return -1;
191}
192
193static int i2c_senddata(struct saa5246a_device *t, ...)
194{
195 unsigned char buf[64];
196 int v;
197 int ct=0;
198 va_list argp;
199 va_start(argp,t);
200
201 while((v=va_arg(argp,int))!=-1)
202 buf[ct++]=v;
203 return i2c_sendbuf(t, buf[0], ct-1, buf+1);
204}
205
206/* Get count number of bytes from I²C-device at address adr, store them in buf.
207 * Start & stop handshaking is done by this routine, ack will be sent after the
208 * last byte to inhibit further sending of data. If uaccess is TRUE, data is
209 * written to user-space with put_user. Returns -1 if I²C-device didn't send
210 * acknowledge, 0 otherwise
211 */
212static int i2c_getdata(struct saa5246a_device *t, int count, u8 *buf)
213{
214 if(i2c_master_recv(t->client, buf, count)!=count)
215 return -1;
216 return 0;
217}
218
219/* When a page is found then the not FOUND bit in one of the status registers
220 * of the SAA5264A chip is cleared. Unfortunately this bit is not set
221 * automatically when a new page is requested. Instead this function must be
222 * called after a page has been requested.
223 *
224 * Return value: 0 if successful
225 */
226static int saa5246a_clear_found_bit(struct saa5246a_device *t,
227 unsigned char dau_no)
228{
229 unsigned char row_25_column_8;
230
231 if (i2c_senddata(t, SAA5246A_REGISTER_R8,
232
233 dau_no |
234 R8_DO_NOT_CLEAR_MEMORY,
235
236 R9_CURSER_ROW_25,
237
238 R10_CURSER_COLUMN_8,
239
240 COMMAND_END) ||
241 i2c_getdata(t, 1, &row_25_column_8))
242 {
243 return -EIO;
244 }
245 row_25_column_8 |= ROW25_COLUMN8_PAGE_NOT_FOUND;
246 if (i2c_senddata(t, SAA5246A_REGISTER_R8,
247
248 dau_no |
249 R8_DO_NOT_CLEAR_MEMORY,
250
251 R9_CURSER_ROW_25,
252
253 R10_CURSER_COLUMN_8,
254
255 row_25_column_8,
256
257 COMMAND_END))
258 {
259 return -EIO;
260 }
261
262 return 0;
263}
264
265/* Requests one videotext page as described in req. The fields of req are
266 * checked and an error is returned if something is invalid.
267 *
268 * Return value: 0 if successful
269 */
270static int saa5246a_request_page(struct saa5246a_device *t,
271 vtx_pagereq_t *req)
272{
273 if (req->pagemask < 0 || req->pagemask >= PGMASK_MAX)
274 return -EINVAL;
275 if (req->pagemask & PGMASK_PAGE)
276 if (req->page < 0 || req->page > PAGE_MAX)
277 return -EINVAL;
278 if (req->pagemask & PGMASK_HOUR)
279 if (req->hour < 0 || req->hour > HOUR_MAX)
280 return -EINVAL;
281 if (req->pagemask & PGMASK_MINUTE)
282 if (req->minute < 0 || req->minute > MINUTE_MAX)
283 return -EINVAL;
284 if (req->pgbuf < 0 || req->pgbuf >= NUM_DAUS)
285 return -EINVAL;
286
287 if (i2c_senddata(t, SAA5246A_REGISTER_R2,
288
289 R2_IN_R3_SELECT_PAGE_HUNDREDS |
290 req->pgbuf << 4 |
291 R2_BANK_0 |
292 R2_HAMMING_CHECK_OFF,
293
294 HUNDREDS_OF_PAGE(req->page) |
295 R3_HOLD_PAGE |
296 (req->pagemask & PG_HUND ?
297 R3_PAGE_HUNDREDS_DO_CARE :
298 R3_PAGE_HUNDREDS_DO_NOT_CARE),
299
300 TENS_OF_PAGE(req->page) |
301 (req->pagemask & PG_TEN ?
302 R3_PAGE_TENS_DO_CARE :
303 R3_PAGE_TENS_DO_NOT_CARE),
304
305 UNITS_OF_PAGE(req->page) |
306 (req->pagemask & PG_UNIT ?
307 R3_PAGE_UNITS_DO_CARE :
308 R3_PAGE_UNITS_DO_NOT_CARE),
309
310 TENS_OF_HOUR(req->hour) |
311 (req->pagemask & HR_TEN ?
312 R3_HOURS_TENS_DO_CARE :
313 R3_HOURS_TENS_DO_NOT_CARE),
314
315 UNITS_OF_HOUR(req->hour) |
316 (req->pagemask & HR_UNIT ?
317 R3_HOURS_UNITS_DO_CARE :
318 R3_HOURS_UNITS_DO_NOT_CARE),
319
320 TENS_OF_MINUTE(req->minute) |
321 (req->pagemask & MIN_TEN ?
322 R3_MINUTES_TENS_DO_CARE :
323 R3_MINUTES_TENS_DO_NOT_CARE),
324
325 UNITS_OF_MINUTE(req->minute) |
326 (req->pagemask & MIN_UNIT ?
327 R3_MINUTES_UNITS_DO_CARE :
328 R3_MINUTES_UNITS_DO_NOT_CARE),
329
330 COMMAND_END) || i2c_senddata(t, SAA5246A_REGISTER_R2,
331
332 R2_IN_R3_SELECT_PAGE_HUNDREDS |
333 req->pgbuf << 4 |
334 R2_BANK_0 |
335 R2_HAMMING_CHECK_OFF,
336
337 HUNDREDS_OF_PAGE(req->page) |
338 R3_UPDATE_PAGE |
339 (req->pagemask & PG_HUND ?
340 R3_PAGE_HUNDREDS_DO_CARE :
341 R3_PAGE_HUNDREDS_DO_NOT_CARE),
342
343 COMMAND_END))
344 {
345 return -EIO;
346 }
347
348 t->is_searching[req->pgbuf] = TRUE;
349 return 0;
350}
351
352/* This routine decodes the page number from the infobits contained in line 25.
353 *
354 * Parameters:
355 * infobits: must be bits 0 to 9 of column 25
356 *
357 * Return value: page number coded in hexadecimal, i. e. page 123 is coded 0x123
358 */
359static inline int saa5246a_extract_pagenum_from_infobits(
360 unsigned char infobits[10])
361{
362 int page_hundreds, page_tens, page_units;
363
364 page_units = infobits[0] & ROW25_COLUMN0_PAGE_UNITS;
365 page_tens = infobits[1] & ROW25_COLUMN1_PAGE_TENS;
366 page_hundreds = infobits[8] & ROW25_COLUMN8_PAGE_HUNDREDS;
367
368 /* page 0x.. means page 8.. */
369 if (page_hundreds == 0)
370 page_hundreds = 8;
371
372 return((page_hundreds << 8) | (page_tens << 4) | page_units);
373}
374
375/* Decodes the hour from the infobits contained in line 25.
376 *
377 * Parameters:
378 * infobits: must be bits 0 to 9 of column 25
379 *
380 * Return: hour coded in hexadecimal, i. e. 12h is coded 0x12
381 */
382static inline int saa5246a_extract_hour_from_infobits(
383 unsigned char infobits[10])
384{
385 int hour_tens, hour_units;
386
387 hour_units = infobits[4] & ROW25_COLUMN4_HOUR_UNITS;
388 hour_tens = infobits[5] & ROW25_COLUMN5_HOUR_TENS;
389
390 return((hour_tens << 4) | hour_units);
391}
392
393/* Decodes the minutes from the infobits contained in line 25.
394 *
395 * Parameters:
396 * infobits: must be bits 0 to 9 of column 25
397 *
398 * Return: minutes coded in hexadecimal, i. e. 10min is coded 0x10
399 */
400static inline int saa5246a_extract_minutes_from_infobits(
401 unsigned char infobits[10])
402{
403 int minutes_tens, minutes_units;
404
405 minutes_units = infobits[2] & ROW25_COLUMN2_MINUTES_UNITS;
406 minutes_tens = infobits[3] & ROW25_COLUMN3_MINUTES_TENS;
407
408 return((minutes_tens << 4) | minutes_units);
409}
410
411/* Reads the status bits contained in the first 10 columns of the first line
412 * and extracts the information into info.
413 *
414 * Return value: 0 if successful
415 */
416static inline int saa5246a_get_status(struct saa5246a_device *t,
417 vtx_pageinfo_t *info, unsigned char dau_no)
418{
419 unsigned char infobits[10];
420 int column;
421
422 if (dau_no >= NUM_DAUS)
423 return -EINVAL;
424
425 if (i2c_senddata(t, SAA5246A_REGISTER_R8,
426
427 dau_no |
428 R8_DO_NOT_CLEAR_MEMORY,
429
430 R9_CURSER_ROW_25,
431
432 R10_CURSER_COLUMN_0,
433
434 COMMAND_END) ||
435 i2c_getdata(t, 10, infobits))
436 {
437 return -EIO;
438 }
439
440 info->pagenum = saa5246a_extract_pagenum_from_infobits(infobits);
441 info->hour = saa5246a_extract_hour_from_infobits(infobits);
442 info->minute = saa5246a_extract_minutes_from_infobits(infobits);
443 info->charset = ((infobits[7] & ROW25_COLUMN7_CHARACTER_SET) >> 1);
444 info->delete = !!(infobits[3] & ROW25_COLUMN3_DELETE_PAGE);
445 info->headline = !!(infobits[5] & ROW25_COLUMN5_INSERT_HEADLINE);
446 info->subtitle = !!(infobits[5] & ROW25_COLUMN5_INSERT_SUBTITLE);
447 info->supp_header = !!(infobits[6] & ROW25_COLUMN6_SUPPRESS_HEADER);
448 info->update = !!(infobits[6] & ROW25_COLUMN6_UPDATE_PAGE);
449 info->inter_seq = !!(infobits[6] & ROW25_COLUMN6_INTERRUPTED_SEQUENCE);
450 info->dis_disp = !!(infobits[6] & ROW25_COLUMN6_SUPPRESS_DISPLAY);
451 info->serial = !!(infobits[7] & ROW25_COLUMN7_SERIAL_MODE);
452 info->notfound = !!(infobits[8] & ROW25_COLUMN8_PAGE_NOT_FOUND);
453 info->pblf = !!(infobits[9] & ROW25_COLUMN9_PAGE_BEING_LOOKED_FOR);
454 info->hamming = 0;
455 for (column = 0; column <= 7; column++) {
456 if (infobits[column] & ROW25_COLUMN0_TO_7_HAMMING_ERROR) {
457 info->hamming = 1;
458 break;
459 }
460 }
461 if (!info->hamming && !info->notfound)
462 t->is_searching[dau_no] = FALSE;
463 return 0;
464}
465
466/* Reads 1 videotext page buffer of the SAA5246A.
467 *
468 * req is used both as input and as output. It contains information which part
469 * must be read. The videotext page is copied into req->buffer.
470 *
471 * Return value: 0 if successful
472 */
473static inline int saa5246a_get_page(struct saa5246a_device *t,
474 vtx_pagereq_t *req)
475{
476 int start, end, size;
477 char *buf;
478 int err;
479
480 if (req->pgbuf < 0 || req->pgbuf >= NUM_DAUS ||
481 req->start < 0 || req->start > req->end || req->end >= VTX_PAGESIZE)
482 return -EINVAL;
483
484 buf = kmalloc(VTX_PAGESIZE, GFP_KERNEL);
485 if (!buf)
486 return -ENOMEM;
487
488 /* Read "normal" part of page */
489 err = -EIO;
490
491 end = min(req->end, VTX_PAGESIZE - 1);
492 if (i2c_senddata(t, SAA5246A_REGISTER_R8,
493 req->pgbuf | R8_DO_NOT_CLEAR_MEMORY,
494 ROW(req->start), COLUMN(req->start), COMMAND_END))
495 goto out;
496 if (i2c_getdata(t, end - req->start + 1, buf))
497 goto out;
498 err = -EFAULT;
499 if (copy_to_user(req->buffer, buf, end - req->start + 1))
500 goto out;
501
502 /* Always get the time from buffer 4, since this stupid SAA5246A only
503 * updates the currently displayed buffer...
504 */
505 if (REQ_CONTAINS_TIME(req)) {
506 start = max(req->start, POS_TIME_START);
507 end = min(req->end, POS_TIME_END);
508 size = end - start + 1;
509 err = -EINVAL;
510 if (size < 0)
511 goto out;
512 err = -EIO;
513 if (i2c_senddata(t, SAA5246A_REGISTER_R8,
514 R8_ACTIVE_CHAPTER_4 | R8_DO_NOT_CLEAR_MEMORY,
515 R9_CURSER_ROW_0, start, COMMAND_END))
516 goto out;
517 if (i2c_getdata(t, size, buf))
518 goto out;
519 err = -EFAULT;
520 if (copy_to_user(req->buffer + start - req->start, buf, size))
521 goto out;
522 }
523 /* Insert the header from buffer 4 only, if acquisition circuit is still searching for a page */
524 if (REQ_CONTAINS_HEADER(req) && t->is_searching[req->pgbuf]) {
525 start = max(req->start, POS_HEADER_START);
526 end = min(req->end, POS_HEADER_END);
527 size = end - start + 1;
528 err = -EINVAL;
529 if (size < 0)
530 goto out;
531 err = -EIO;
532 if (i2c_senddata(t, SAA5246A_REGISTER_R8,
533 R8_ACTIVE_CHAPTER_4 | R8_DO_NOT_CLEAR_MEMORY,
534 R9_CURSER_ROW_0, start, COMMAND_END))
535 goto out;
536 if (i2c_getdata(t, end - start + 1, buf))
537 goto out;
538 err = -EFAULT;
539 if (copy_to_user(req->buffer + start - req->start, buf, size))
540 goto out;
541 }
542 err = 0;
543out:
544 kfree(buf);
545 return err;
546}
547
548/* Stops the acquisition circuit given in dau_no. The page buffer associated
549 * with this acquisition circuit will no more be updated. The other daus are
550 * not affected.
551 *
552 * Return value: 0 if successful
553 */
554static inline int saa5246a_stop_dau(struct saa5246a_device *t,
555 unsigned char dau_no)
556{
557 if (dau_no >= NUM_DAUS)
558 return -EINVAL;
559 if (i2c_senddata(t, SAA5246A_REGISTER_R2,
560
561 R2_IN_R3_SELECT_PAGE_HUNDREDS |
562 dau_no << 4 |
563 R2_BANK_0 |
564 R2_HAMMING_CHECK_OFF,
565
566 R3_PAGE_HUNDREDS_0 |
567 R3_HOLD_PAGE |
568 R3_PAGE_HUNDREDS_DO_NOT_CARE,
569
570 COMMAND_END))
571 {
572 return -EIO;
573 }
574 t->is_searching[dau_no] = FALSE;
575 return 0;
576}
577
578/* Handles ioctls defined in videotext.h
579 *
580 * Returns 0 if successful
581 */
582static int do_saa5246a_ioctl(struct inode *inode, struct file *file,
583 unsigned int cmd, void *arg)
584{
585 struct video_device *vd = video_devdata(file);
586 struct saa5246a_device *t=vd->priv;
587 switch(cmd)
588 {
589 case VTXIOCGETINFO:
590 {
591 vtx_info_t *info = arg;
592
593 info->version_major = MAJOR_VERSION;
594 info->version_minor = MINOR_VERSION;
595 info->numpages = NUM_DAUS;
596 return 0;
597 }
598
599 case VTXIOCCLRPAGE:
600 {
601 vtx_pagereq_t *req = arg;
602
603 if (req->pgbuf < 0 || req->pgbuf >= NUM_DAUS)
604 return -EINVAL;
605 memset(t->pgbuf[req->pgbuf], ' ', sizeof(t->pgbuf[0]));
606 return 0;
607 }
608
609 case VTXIOCCLRFOUND:
610 {
611 vtx_pagereq_t *req = arg;
612
613 if (req->pgbuf < 0 || req->pgbuf >= NUM_DAUS)
614 return -EINVAL;
615 return(saa5246a_clear_found_bit(t, req->pgbuf));
616 }
617
618 case VTXIOCPAGEREQ:
619 {
620 vtx_pagereq_t *req = arg;
621
622 return(saa5246a_request_page(t, req));
623 }
624
625 case VTXIOCGETSTAT:
626 {
627 vtx_pagereq_t *req = arg;
628 vtx_pageinfo_t info;
629 int rval;
630
631 if ((rval = saa5246a_get_status(t, &info, req->pgbuf)))
632 return rval;
633 if(copy_to_user(req->buffer, &info,
634 sizeof(vtx_pageinfo_t)))
635 return -EFAULT;
636 return 0;
637 }
638
639 case VTXIOCGETPAGE:
640 {
641 vtx_pagereq_t *req = arg;
642
643 return(saa5246a_get_page(t, req));
644 }
645
646 case VTXIOCSTOPDAU:
647 {
648 vtx_pagereq_t *req = arg;
649
650 return(saa5246a_stop_dau(t, req->pgbuf));
651 }
652
653 case VTXIOCPUTPAGE:
654 case VTXIOCSETDISP:
655 case VTXIOCPUTSTAT:
656 return 0;
657
658 case VTXIOCCLRCACHE:
659 {
660 return 0;
661 }
662
663 case VTXIOCSETVIRT:
664 {
665 /* I do not know what "virtual mode" means */
666 return 0;
667 }
668 }
669 return -EINVAL;
670}
671
672/*
673 * Translates old vtx IOCTLs to new ones
674 *
675 * This keeps new kernel versions compatible with old userspace programs.
676 */
677static inline unsigned int vtx_fix_command(unsigned int cmd)
678{
679 switch (cmd) {
680 case VTXIOCGETINFO_OLD:
681 cmd = VTXIOCGETINFO;
682 break;
683 case VTXIOCCLRPAGE_OLD:
684 cmd = VTXIOCCLRPAGE;
685 break;
686 case VTXIOCCLRFOUND_OLD:
687 cmd = VTXIOCCLRFOUND;
688 break;
689 case VTXIOCPAGEREQ_OLD:
690 cmd = VTXIOCPAGEREQ;
691 break;
692 case VTXIOCGETSTAT_OLD:
693 cmd = VTXIOCGETSTAT;
694 break;
695 case VTXIOCGETPAGE_OLD:
696 cmd = VTXIOCGETPAGE;
697 break;
698 case VTXIOCSTOPDAU_OLD:
699 cmd = VTXIOCSTOPDAU;
700 break;
701 case VTXIOCPUTPAGE_OLD:
702 cmd = VTXIOCPUTPAGE;
703 break;
704 case VTXIOCSETDISP_OLD:
705 cmd = VTXIOCSETDISP;
706 break;
707 case VTXIOCPUTSTAT_OLD:
708 cmd = VTXIOCPUTSTAT;
709 break;
710 case VTXIOCCLRCACHE_OLD:
711 cmd = VTXIOCCLRCACHE;
712 break;
713 case VTXIOCSETVIRT_OLD:
714 cmd = VTXIOCSETVIRT;
715 break;
716 }
717 return cmd;
718}
719
720/*
721 * Handle the locking
722 */
723static int saa5246a_ioctl(struct inode *inode, struct file *file,
724 unsigned int cmd, unsigned long arg)
725{
726 struct video_device *vd = video_devdata(file);
727 struct saa5246a_device *t = vd->priv;
728 int err;
729
730 cmd = vtx_fix_command(cmd);
731 down(&t->lock);
732 err = video_usercopy(inode, file, cmd, arg, do_saa5246a_ioctl);
733 up(&t->lock);
734 return err;
735}
736
737static int saa5246a_open(struct inode *inode, struct file *file)
738{
739 struct video_device *vd = video_devdata(file);
740 struct saa5246a_device *t = vd->priv;
741 int err;
742
743 err = video_exclusive_open(inode,file);
744 if (err < 0)
745 return err;
746
747 if (t->client==NULL) {
748 err = -ENODEV;
749 goto fail;
750 }
751
752 if (i2c_senddata(t, SAA5246A_REGISTER_R0,
753
754 R0_SELECT_R11 |
755 R0_PLL_TIME_CONSTANT_LONG |
756 R0_ENABLE_nODD_EVEN_OUTPUT |
757 R0_ENABLE_HDR_POLL |
758 R0_DO_NOT_FORCE_nODD_EVEN_LOW_IF_PICTURE_DISPLAYED |
759 R0_NO_FREE_RUN_PLL |
760 R0_NO_AUTOMATIC_FASTEXT_PROMPT,
761
762 R1_NON_INTERLACED_312_312_LINES |
763 R1_DEW |
764 R1_EXTENDED_PACKET_DISABLE |
765 R1_DAUS_ALL_ON |
766 R1_8_BITS_NO_PARITY |
767 R1_VCS_TO_SCS,
768
769 COMMAND_END) ||
770 i2c_senddata(t, SAA5246A_REGISTER_R4,
771
772 /* We do not care much for the TV display but nevertheless we
773 * need the currently displayed page later because only on that
774 * page the time is updated. */
775 R4_DISPLAY_PAGE_4,
776
777 COMMAND_END))
778 {
779 err = -EIO;
780 goto fail;
781 }
782
783 return 0;
784
785fail:
786 video_exclusive_release(inode,file);
787 return err;
788}
789
790static int saa5246a_release(struct inode *inode, struct file *file)
791{
792 struct video_device *vd = video_devdata(file);
793 struct saa5246a_device *t = vd->priv;
794
795 /* Stop all acquisition circuits. */
796 i2c_senddata(t, SAA5246A_REGISTER_R1,
797
798 R1_INTERLACED_312_AND_HALF_312_AND_HALF_LINES |
799 R1_DEW |
800 R1_EXTENDED_PACKET_DISABLE |
801 R1_DAUS_ALL_OFF |
802 R1_8_BITS_NO_PARITY |
803 R1_VCS_TO_SCS,
804
805 COMMAND_END);
806 video_exclusive_release(inode,file);
807 return 0;
808}
809
810static int __init init_saa_5246a (void)
811{
812 printk(KERN_INFO
813 "SAA5246A (or compatible) Teletext decoder driver version %d.%d\n",
814 MAJOR_VERSION, MINOR_VERSION);
815 return i2c_add_driver(&i2c_driver_videotext);
816}
817
818static void __exit cleanup_saa_5246a (void)
819{
820 i2c_del_driver(&i2c_driver_videotext);
821}
822
823module_init(init_saa_5246a);
824module_exit(cleanup_saa_5246a);
825
826static struct file_operations saa_fops = {
827 .owner = THIS_MODULE,
828 .open = saa5246a_open,
829 .release = saa5246a_release,
830 .ioctl = saa5246a_ioctl,
831 .llseek = no_llseek,
832};
833
834static struct video_device saa_template =
835{
836 .owner = THIS_MODULE,
837 .name = IF_NAME,
838 .type = VID_TYPE_TELETEXT,
839 .hardware = VID_HARDWARE_SAA5249,
840 .fops = &saa_fops,
841 .release = video_device_release,
842 .minor = -1,
843};
diff --git a/drivers/media/video/saa5246a.h b/drivers/media/video/saa5246a.h
new file mode 100644
index 00000000000..7b91112304e
--- /dev/null
+++ b/drivers/media/video/saa5246a.h
@@ -0,0 +1,364 @@
1/*
2 Driver for the SAA5246A or SAA5281 Teletext (=Videotext) decoder chips from
3 Philips.
4
5 Copyright (C) 2004 Michael Geng (linux@MichaelGeng.de)
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#ifndef __SAA5246A_H__
23#define __SAA5246A_H__
24
25#define MAJOR_VERSION 1 /* driver major version number */
26#define MINOR_VERSION 8 /* driver minor version number */
27
28#define IF_NAME "SAA5246A"
29
30#define I2C_ADDRESS 17
31
32/* Number of DAUs = number of pages that can be searched at the same time. */
33#define NUM_DAUS 4
34
35#define NUM_ROWS_PER_PAGE 40
36
37/* first column is 0 (not 1) */
38#define POS_TIME_START 32
39#define POS_TIME_END 39
40
41#define POS_HEADER_START 7
42#define POS_HEADER_END 31
43
44/* Returns TRUE if the part of the videotext page described with req contains
45 (at least parts of) the time field */
46#define REQ_CONTAINS_TIME(p_req) \
47 ((p_req)->start <= POS_TIME_END && \
48 (p_req)->end >= POS_TIME_START)
49
50/* Returns TRUE if the part of the videotext page described with req contains
51 (at least parts of) the page header */
52#define REQ_CONTAINS_HEADER(p_req) \
53 ((p_req)->start <= POS_HEADER_END && \
54 (p_req)->end >= POS_HEADER_START)
55
56#ifndef FALSE
57#define FALSE 0
58#define TRUE 1
59#endif
60
61/*****************************************************************************/
62/* Mode register numbers of the SAA5246A */
63/*****************************************************************************/
64#define SAA5246A_REGISTER_R0 0
65#define SAA5246A_REGISTER_R1 1
66#define SAA5246A_REGISTER_R2 2
67#define SAA5246A_REGISTER_R3 3
68#define SAA5246A_REGISTER_R4 4
69#define SAA5246A_REGISTER_R5 5
70#define SAA5246A_REGISTER_R6 6
71#define SAA5246A_REGISTER_R7 7
72#define SAA5246A_REGISTER_R8 8
73#define SAA5246A_REGISTER_R9 9
74#define SAA5246A_REGISTER_R10 10
75#define SAA5246A_REGISTER_R11 11
76#define SAA5246A_REGISTER_R11B 11
77
78/* SAA5246A mode registers often autoincrement to the next register.
79 Therefore we use variable argument lists. The following macro indicates
80 the end of a command list. */
81#define COMMAND_END (- 1)
82
83/*****************************************************************************/
84/* Contents of the mode registers of the SAA5246A */
85/*****************************************************************************/
86/* Register R0 (Advanced Control) */
87#define R0_SELECT_R11 0x00
88#define R0_SELECT_R11B 0x01
89
90#define R0_PLL_TIME_CONSTANT_LONG 0x00
91#define R0_PLL_TIME_CONSTANT_SHORT 0x02
92
93#define R0_ENABLE_nODD_EVEN_OUTPUT 0x00
94#define R0_DISABLE_nODD_EVEN_OUTPUT 0x04
95
96#define R0_ENABLE_HDR_POLL 0x00
97#define R0_DISABLE_HDR_POLL 0x10
98
99#define R0_DO_NOT_FORCE_nODD_EVEN_LOW_IF_PICTURE_DISPLAYED 0x00
100#define R0_FORCE_nODD_EVEN_LOW_IF_PICTURE_DISPLAYED 0x20
101
102#define R0_NO_FREE_RUN_PLL 0x00
103#define R0_FREE_RUN_PLL 0x40
104
105#define R0_NO_AUTOMATIC_FASTEXT_PROMPT 0x00
106#define R0_AUTOMATIC_FASTEXT_PROMPT 0x80
107
108/* Register R1 (Mode) */
109#define R1_INTERLACED_312_AND_HALF_312_AND_HALF_LINES 0x00
110#define R1_NON_INTERLACED_312_313_LINES 0x01
111#define R1_NON_INTERLACED_312_312_LINES 0x02
112#define R1_FFB_LEADING_EDGE_IN_FIRST_BROAD_PULSE 0x03
113#define R1_FFB_LEADING_EDGE_IN_SECOND_BROAD_PULSE 0x07
114
115#define R1_DEW 0x00
116#define R1_FULL_FIELD 0x08
117
118#define R1_EXTENDED_PACKET_DISABLE 0x00
119#define R1_EXTENDED_PACKET_ENABLE 0x10
120
121#define R1_DAUS_ALL_ON 0x00
122#define R1_DAUS_ALL_OFF 0x20
123
124#define R1_7_BITS_PLUS_PARITY 0x00
125#define R1_8_BITS_NO_PARITY 0x40
126
127#define R1_VCS_TO_SCS 0x00
128#define R1_NO_VCS_TO_SCS 0x80
129
130/* Register R2 (Page request address) */
131#define R2_IN_R3_SELECT_PAGE_HUNDREDS 0x00
132#define R2_IN_R3_SELECT_PAGE_TENS 0x01
133#define R2_IN_R3_SELECT_PAGE_UNITS 0x02
134#define R2_IN_R3_SELECT_HOURS_TENS 0x03
135#define R2_IN_R3_SELECT_HOURS_UNITS 0x04
136#define R2_IN_R3_SELECT_MINUTES_TENS 0x05
137#define R2_IN_R3_SELECT_MINUTES_UNITS 0x06
138
139#define R2_DAU_0 0x00
140#define R2_DAU_1 0x10
141#define R2_DAU_2 0x20
142#define R2_DAU_3 0x30
143
144#define R2_BANK_0 0x00
145#define R2_BANK 1 0x40
146
147#define R2_HAMMING_CHECK_ON 0x80
148#define R2_HAMMING_CHECK_OFF 0x00
149
150/* Register R3 (Page request data) */
151#define R3_PAGE_HUNDREDS_0 0x00
152#define R3_PAGE_HUNDREDS_1 0x01
153#define R3_PAGE_HUNDREDS_2 0x02
154#define R3_PAGE_HUNDREDS_3 0x03
155#define R3_PAGE_HUNDREDS_4 0x04
156#define R3_PAGE_HUNDREDS_5 0x05
157#define R3_PAGE_HUNDREDS_6 0x06
158#define R3_PAGE_HUNDREDS_7 0x07
159
160#define R3_HOLD_PAGE 0x00
161#define R3_UPDATE_PAGE 0x08
162
163#define R3_PAGE_HUNDREDS_DO_NOT_CARE 0x00
164#define R3_PAGE_HUNDREDS_DO_CARE 0x10
165
166#define R3_PAGE_TENS_DO_NOT_CARE 0x00
167#define R3_PAGE_TENS_DO_CARE 0x10
168
169#define R3_PAGE_UNITS_DO_NOT_CARE 0x00
170#define R3_PAGE_UNITS_DO_CARE 0x10
171
172#define R3_HOURS_TENS_DO_NOT_CARE 0x00
173#define R3_HOURS_TENS_DO_CARE 0x10
174
175#define R3_HOURS_UNITS_DO_NOT_CARE 0x00
176#define R3_HOURS_UNITS_DO_CARE 0x10
177
178#define R3_MINUTES_TENS_DO_NOT_CARE 0x00
179#define R3_MINUTES_TENS_DO_CARE 0x10
180
181#define R3_MINUTES_UNITS_DO_NOT_CARE 0x00
182#define R3_MINUTES_UNITS_DO_CARE 0x10
183
184/* Register R4 (Display chapter) */
185#define R4_DISPLAY_PAGE_0 0x00
186#define R4_DISPLAY_PAGE_1 0x01
187#define R4_DISPLAY_PAGE_2 0x02
188#define R4_DISPLAY_PAGE_3 0x03
189#define R4_DISPLAY_PAGE_4 0x04
190#define R4_DISPLAY_PAGE_5 0x05
191#define R4_DISPLAY_PAGE_6 0x06
192#define R4_DISPLAY_PAGE_7 0x07
193
194/* Register R5 (Normal display control) */
195#define R5_PICTURE_INSIDE_BOXING_OFF 0x00
196#define R5_PICTURE_INSIDE_BOXING_ON 0x01
197
198#define R5_PICTURE_OUTSIDE_BOXING_OFF 0x00
199#define R5_PICTURE_OUTSIDE_BOXING_ON 0x02
200
201#define R5_TEXT_INSIDE_BOXING_OFF 0x00
202#define R5_TEXT_INSIDE_BOXING_ON 0x04
203
204#define R5_TEXT_OUTSIDE_BOXING_OFF 0x00
205#define R5_TEXT_OUTSIDE_BOXING_ON 0x08
206
207#define R5_CONTRAST_REDUCTION_INSIDE_BOXING_OFF 0x00
208#define R5_CONTRAST_REDUCTION_INSIDE_BOXING_ON 0x10
209
210#define R5_CONTRAST_REDUCTION_OUTSIDE_BOXING_OFF 0x00
211#define R5_CONTRAST_REDUCTION_OUTSIDE_BOXING_ON 0x20
212
213#define R5_BACKGROUND_COLOR_INSIDE_BOXING_OFF 0x00
214#define R5_BACKGROUND_COLOR_INSIDE_BOXING_ON 0x40
215
216#define R5_BACKGROUND_COLOR_OUTSIDE_BOXING_OFF 0x00
217#define R5_BACKGROUND_COLOR_OUTSIDE_BOXING_ON 0x80
218
219/* Register R6 (Newsflash display) */
220#define R6_NEWSFLASH_PICTURE_INSIDE_BOXING_OFF 0x00
221#define R6_NEWSFLASH_PICTURE_INSIDE_BOXING_ON 0x01
222
223#define R6_NEWSFLASH_PICTURE_OUTSIDE_BOXING_OFF 0x00
224#define R6_NEWSFLASH_PICTURE_OUTSIDE_BOXING_ON 0x02
225
226#define R6_NEWSFLASH_TEXT_INSIDE_BOXING_OFF 0x00
227#define R6_NEWSFLASH_TEXT_INSIDE_BOXING_ON 0x04
228
229#define R6_NEWSFLASH_TEXT_OUTSIDE_BOXING_OFF 0x00
230#define R6_NEWSFLASH_TEXT_OUTSIDE_BOXING_ON 0x08
231
232#define R6_NEWSFLASH_CONTRAST_REDUCTION_INSIDE_BOXING_OFF 0x00
233#define R6_NEWSFLASH_CONTRAST_REDUCTION_INSIDE_BOXING_ON 0x10
234
235#define R6_NEWSFLASH_CONTRAST_REDUCTION_OUTSIDE_BOXING_OFF 0x00
236#define R6_NEWSFLASH_CONTRAST_REDUCTION_OUTSIDE_BOXING_ON 0x20
237
238#define R6_NEWSFLASH_BACKGROUND_COLOR_INSIDE_BOXING_OFF 0x00
239#define R6_NEWSFLASH_BACKGROUND_COLOR_INSIDE_BOXING_ON 0x40
240
241#define R6_NEWSFLASH_BACKGROUND_COLOR_OUTSIDE_BOXING_OFF 0x00
242#define R6_NEWSFLASH_BACKGROUND_COLOR_OUTSIDE_BOXING_ON 0x80
243
244/* Register R7 (Display mode) */
245#define R7_BOX_OFF_ROW_0 0x00
246#define R7_BOX_ON_ROW_0 0x01
247
248#define R7_BOX_OFF_ROW_1_TO_23 0x00
249#define R7_BOX_ON_ROW_1_TO_23 0x02
250
251#define R7_BOX_OFF_ROW_24 0x00
252#define R7_BOX_ON_ROW_24 0x04
253
254#define R7_SINGLE_HEIGHT 0x00
255#define R7_DOUBLE_HEIGHT 0x08
256
257#define R7_TOP_HALF 0x00
258#define R7_BOTTOM_HALF 0x10
259
260#define R7_REVEAL_OFF 0x00
261#define R7_REVEAL_ON 0x20
262
263#define R7_CURSER_OFF 0x00
264#define R7_CURSER_ON 0x40
265
266#define R7_STATUS_BOTTOM 0x00
267#define R7_STATUS_TOP 0x80
268
269/* Register R8 (Active chapter) */
270#define R8_ACTIVE_CHAPTER_0 0x00
271#define R8_ACTIVE_CHAPTER_1 0x01
272#define R8_ACTIVE_CHAPTER_2 0x02
273#define R8_ACTIVE_CHAPTER_3 0x03
274#define R8_ACTIVE_CHAPTER_4 0x04
275#define R8_ACTIVE_CHAPTER_5 0x05
276#define R8_ACTIVE_CHAPTER_6 0x06
277#define R8_ACTIVE_CHAPTER_7 0x07
278
279#define R8_CLEAR_MEMORY 0x08
280#define R8_DO_NOT_CLEAR_MEMORY 0x00
281
282/* Register R9 (Curser row) */
283#define R9_CURSER_ROW_0 0x00
284#define R9_CURSER_ROW_1 0x01
285#define R9_CURSER_ROW_2 0x02
286#define R9_CURSER_ROW_25 0x19
287
288/* Register R10 (Curser column) */
289#define R10_CURSER_COLUMN_0 0x00
290#define R10_CURSER_COLUMN_6 0x06
291#define R10_CURSER_COLUMN_8 0x08
292
293/*****************************************************************************/
294/* Row 25 control data in column 0 to 9 */
295/*****************************************************************************/
296#define ROW25_COLUMN0_PAGE_UNITS 0x0F
297
298#define ROW25_COLUMN1_PAGE_TENS 0x0F
299
300#define ROW25_COLUMN2_MINUTES_UNITS 0x0F
301
302#define ROW25_COLUMN3_MINUTES_TENS 0x07
303#define ROW25_COLUMN3_DELETE_PAGE 0x08
304
305#define ROW25_COLUMN4_HOUR_UNITS 0x0F
306
307#define ROW25_COLUMN5_HOUR_TENS 0x03
308#define ROW25_COLUMN5_INSERT_HEADLINE 0x04
309#define ROW25_COLUMN5_INSERT_SUBTITLE 0x08
310
311#define ROW25_COLUMN6_SUPPRESS_HEADER 0x01
312#define ROW25_COLUMN6_UPDATE_PAGE 0x02
313#define ROW25_COLUMN6_INTERRUPTED_SEQUENCE 0x04
314#define ROW25_COLUMN6_SUPPRESS_DISPLAY 0x08
315
316#define ROW25_COLUMN7_SERIAL_MODE 0x01
317#define ROW25_COLUMN7_CHARACTER_SET 0x0E
318
319#define ROW25_COLUMN8_PAGE_HUNDREDS 0x07
320#define ROW25_COLUMN8_PAGE_NOT_FOUND 0x10
321
322#define ROW25_COLUMN9_PAGE_BEING_LOOKED_FOR 0x20
323
324#define ROW25_COLUMN0_TO_7_HAMMING_ERROR 0x10
325
326/*****************************************************************************/
327/* Helper macros for extracting page, hour and minute digits */
328/*****************************************************************************/
329/* BYTE_POS 0 is at row 0, column 0,
330 BYTE_POS 1 is at row 0, column 1,
331 BYTE_POS 40 is at row 1, column 0, (with NUM_ROWS_PER_PAGE = 40)
332 BYTE_POS 41 is at row 1, column 1, (with NUM_ROWS_PER_PAGE = 40),
333 ... */
334#define ROW(BYTE_POS) (BYTE_POS / NUM_ROWS_PER_PAGE)
335#define COLUMN(BYTE_POS) (BYTE_POS % NUM_ROWS_PER_PAGE)
336
337/*****************************************************************************/
338/* Helper macros for extracting page, hour and minute digits */
339/*****************************************************************************/
340/* Macros for extracting hundreds, tens and units of a page number which
341 must be in the range 0 ... 0x799.
342 Note that page is coded in hexadecimal, i.e. 0x123 means page 123.
343 page 0x.. means page 8.. */
344#define HUNDREDS_OF_PAGE(page) (((page) / 0x100) & 0x7)
345#define TENS_OF_PAGE(page) (((page) / 0x10) & 0xF)
346#define UNITS_OF_PAGE(page) ((page) & 0xF)
347
348/* Macros for extracting tens and units of a hour information which
349 must be in the range 0 ... 0x24.
350 Note that hour is coded in hexadecimal, i.e. 0x12 means 12 hours */
351#define TENS_OF_HOUR(hour) ((hour) / 0x10)
352#define UNITS_OF_HOUR(hour) ((hour) & 0xF)
353
354/* Macros for extracting tens and units of a minute information which
355 must be in the range 0 ... 0x59.
356 Note that minute is coded in hexadecimal, i.e. 0x12 means 12 minutes */
357#define TENS_OF_MINUTE(minute) ((minute) / 0x10)
358#define UNITS_OF_MINUTE(minute) ((minute) & 0xF)
359
360#define HOUR_MAX 0x23
361#define MINUTE_MAX 0x59
362#define PAGE_MAX 0x8FF
363
364#endif /* __SAA5246A_H__ */
diff --git a/drivers/media/video/saa5249.c b/drivers/media/video/saa5249.c
new file mode 100644
index 00000000000..d74caa139f0
--- /dev/null
+++ b/drivers/media/video/saa5249.c
@@ -0,0 +1,725 @@
1/*
2 * Modified in order to keep it compatible both with new and old videotext IOCTLs by
3 * Michael Geng <linux@MichaelGeng.de>
4 *
5 * Cleaned up to use existing videodev interface and allow the idea
6 * of multiple teletext decoders on the video4linux iface. Changed i2c
7 * to cover addressing clashes on device busses. It's also rebuilt so
8 * you can add arbitary multiple teletext devices to Linux video4linux
9 * now (well 32 anyway).
10 *
11 * Alan Cox <Alan.Cox@linux.org>
12 *
13 * The original driver was heavily modified to match the i2c interface
14 * It was truncated to use the WinTV boards, too.
15 *
16 * Copyright (c) 1998 Richard Guenther <richard.guenther@student.uni-tuebingen.de>
17 *
18 * $Id: saa5249.c,v 1.1 1998/03/30 22:23:23 alan Exp $
19 *
20 * Derived From
21 *
22 * vtx.c:
23 * This is a loadable character-device-driver for videotext-interfaces
24 * (aka teletext). Please check the Makefile/README for a list of supported
25 * interfaces.
26 *
27 * Copyright (c) 1994-97 Martin Buck <martin-2.buck@student.uni-ulm.de>
28 *
29 *
30 * This program is free software; you can redistribute it and/or modify
31 * it under the terms of the GNU General Public License as published by
32 * the Free Software Foundation; either version 2 of the License, or
33 * (at your option) any later version.
34 *
35 * This program is distributed in the hope that it will be useful,
36 * but WITHOUT ANY WARRANTY; without even the implied warranty of
37 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
38 * GNU General Public License for more details.
39 *
40 * You should have received a copy of the GNU General Public License
41 * along with this program; if not, write to the Free Software
42 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
43 * USA.
44 */
45
46#include <linux/module.h>
47#include <linux/kernel.h>
48#include <linux/sched.h>
49#include <linux/mm.h>
50#include <linux/errno.h>
51#include <linux/delay.h>
52#include <linux/ioport.h>
53#include <linux/slab.h>
54#include <linux/init.h>
55#include <stdarg.h>
56#include <linux/i2c.h>
57#include <linux/videotext.h>
58#include <linux/videodev.h>
59
60#include <asm/io.h>
61#include <asm/uaccess.h>
62
63#define VTX_VER_MAJ 1
64#define VTX_VER_MIN 8
65
66
67
68#define NUM_DAUS 4
69#define NUM_BUFS 8
70#define IF_NAME "SAA5249"
71
72static const int disp_modes[8][3] =
73{
74 { 0x46, 0x03, 0x03 }, /* DISPOFF */
75 { 0x46, 0xcc, 0xcc }, /* DISPNORM */
76 { 0x44, 0x0f, 0x0f }, /* DISPTRANS */
77 { 0x46, 0xcc, 0x46 }, /* DISPINS */
78 { 0x44, 0x03, 0x03 }, /* DISPOFF, interlaced */
79 { 0x44, 0xcc, 0xcc }, /* DISPNORM, interlaced */
80 { 0x44, 0x0f, 0x0f }, /* DISPTRANS, interlaced */
81 { 0x44, 0xcc, 0x46 } /* DISPINS, interlaced */
82};
83
84
85
86#define PAGE_WAIT (300*HZ/1000) /* Time between requesting page and */
87 /* checking status bits */
88#define PGBUF_EXPIRE (15*HZ) /* Time to wait before retransmitting */
89 /* page regardless of infobits */
90typedef struct {
91 u8 pgbuf[VTX_VIRTUALSIZE]; /* Page-buffer */
92 u8 laststat[10]; /* Last value of infobits for DAU */
93 u8 sregs[7]; /* Page-request registers */
94 unsigned long expire; /* Time when page will be expired */
95 unsigned clrfound : 1; /* VTXIOCCLRFOUND has been called */
96 unsigned stopped : 1; /* VTXIOCSTOPDAU has been called */
97} vdau_t;
98
99struct saa5249_device
100{
101 vdau_t vdau[NUM_DAUS]; /* Data for virtual DAUs (the 5249 only has one */
102 /* real DAU, so we have to simulate some more) */
103 int vtx_use_count;
104 int is_searching[NUM_DAUS];
105 int disp_mode;
106 int virtual_mode;
107 struct i2c_client *client;
108 struct semaphore lock;
109};
110
111
112#define CCTWR 34 /* I²C write/read-address of vtx-chip */
113#define CCTRD 35
114#define NOACK_REPEAT 10 /* Retry access this many times on failure */
115#define CLEAR_DELAY (HZ/20) /* Time required to clear a page */
116#define READY_TIMEOUT (30*HZ/1000) /* Time to wait for ready signal of I²C-bus interface */
117#define INIT_DELAY 500 /* Time in usec to wait at initialization of CEA interface */
118#define START_DELAY 10 /* Time in usec to wait before starting write-cycle (CEA) */
119
120#define VTX_DEV_MINOR 0
121
122/* General defines and debugging support */
123
124#ifndef FALSE
125#define FALSE 0
126#define TRUE 1
127#endif
128
129#define RESCHED do { cond_resched(); } while(0)
130
131static struct video_device saa_template; /* Declared near bottom */
132
133/* Addresses to scan */
134static unsigned short normal_i2c[] = {34>>1,I2C_CLIENT_END};
135static unsigned short normal_i2c_range[] = {I2C_CLIENT_END};
136I2C_CLIENT_INSMOD;
137
138static struct i2c_client client_template;
139
140static int saa5249_attach(struct i2c_adapter *adap, int addr, int kind)
141{
142 int pgbuf;
143 int err;
144 struct i2c_client *client;
145 struct video_device *vd;
146 struct saa5249_device *t;
147
148 printk(KERN_INFO "saa5249: teletext chip found.\n");
149 client=kmalloc(sizeof(*client), GFP_KERNEL);
150 if(client==NULL)
151 return -ENOMEM;
152 client_template.adapter = adap;
153 client_template.addr = addr;
154 memcpy(client, &client_template, sizeof(*client));
155 t = kmalloc(sizeof(*t), GFP_KERNEL);
156 if(t==NULL)
157 {
158 kfree(client);
159 return -ENOMEM;
160 }
161 memset(t, 0, sizeof(*t));
162 strlcpy(client->name, IF_NAME, I2C_NAME_SIZE);
163 init_MUTEX(&t->lock);
164
165 /*
166 * Now create a video4linux device
167 */
168
169 vd = (struct video_device *)kmalloc(sizeof(struct video_device), GFP_KERNEL);
170 if(vd==NULL)
171 {
172 kfree(t);
173 kfree(client);
174 return -ENOMEM;
175 }
176 i2c_set_clientdata(client, vd);
177 memcpy(vd, &saa_template, sizeof(*vd));
178
179 for (pgbuf = 0; pgbuf < NUM_DAUS; pgbuf++)
180 {
181 memset(t->vdau[pgbuf].pgbuf, ' ', sizeof(t->vdau[0].pgbuf));
182 memset(t->vdau[pgbuf].sregs, 0, sizeof(t->vdau[0].sregs));
183 memset(t->vdau[pgbuf].laststat, 0, sizeof(t->vdau[0].laststat));
184 t->vdau[pgbuf].expire = 0;
185 t->vdau[pgbuf].clrfound = TRUE;
186 t->vdau[pgbuf].stopped = TRUE;
187 t->is_searching[pgbuf] = FALSE;
188 }
189 vd->priv=t;
190
191
192 /*
193 * Register it
194 */
195
196 if((err=video_register_device(vd, VFL_TYPE_VTX,-1))<0)
197 {
198 kfree(t);
199 kfree(vd);
200 kfree(client);
201 return err;
202 }
203 t->client = client;
204 i2c_attach_client(client);
205 return 0;
206}
207
208/*
209 * We do most of the hard work when we become a device on the i2c.
210 */
211
212static int saa5249_probe(struct i2c_adapter *adap)
213{
214 if (adap->class & I2C_CLASS_TV_ANALOG)
215 return i2c_probe(adap, &addr_data, saa5249_attach);
216 return 0;
217}
218
219static int saa5249_detach(struct i2c_client *client)
220{
221 struct video_device *vd = i2c_get_clientdata(client);
222 i2c_detach_client(client);
223 video_unregister_device(vd);
224 kfree(vd->priv);
225 kfree(vd);
226 kfree(client);
227 return 0;
228}
229
230static int saa5249_command(struct i2c_client *device,
231 unsigned int cmd, void *arg)
232{
233 return -EINVAL;
234}
235
236/* new I2C driver support */
237
238static struct i2c_driver i2c_driver_videotext =
239{
240 .owner = THIS_MODULE,
241 .name = IF_NAME, /* name */
242 .id = I2C_DRIVERID_SAA5249, /* in i2c.h */
243 .flags = I2C_DF_NOTIFY,
244 .attach_adapter = saa5249_probe,
245 .detach_client = saa5249_detach,
246 .command = saa5249_command
247};
248
249static struct i2c_client client_template = {
250 .driver = &i2c_driver_videotext,
251 .name = "(unset)",
252};
253
254/*
255 * Wait the given number of jiffies (10ms). This calls the scheduler, so the actual
256 * delay may be longer.
257 */
258
259static void jdelay(unsigned long delay)
260{
261 sigset_t oldblocked = current->blocked;
262
263 spin_lock_irq(&current->sighand->siglock);
264 sigfillset(&current->blocked);
265 recalc_sigpending();
266 spin_unlock_irq(&current->sighand->siglock);
267 msleep_interruptible(jiffies_to_msecs(delay));
268
269 spin_lock_irq(&current->sighand->siglock);
270 current->blocked = oldblocked;
271 recalc_sigpending();
272 spin_unlock_irq(&current->sighand->siglock);
273}
274
275
276/*
277 * I2C interfaces
278 */
279
280static int i2c_sendbuf(struct saa5249_device *t, int reg, int count, u8 *data)
281{
282 char buf[64];
283
284 buf[0] = reg;
285 memcpy(buf+1, data, count);
286
287 if(i2c_master_send(t->client, buf, count+1)==count+1)
288 return 0;
289 return -1;
290}
291
292static int i2c_senddata(struct saa5249_device *t, ...)
293{
294 unsigned char buf[64];
295 int v;
296 int ct=0;
297 va_list argp;
298 va_start(argp,t);
299
300 while((v=va_arg(argp,int))!=-1)
301 buf[ct++]=v;
302 return i2c_sendbuf(t, buf[0], ct-1, buf+1);
303}
304
305/* Get count number of bytes from I²C-device at address adr, store them in buf. Start & stop
306 * handshaking is done by this routine, ack will be sent after the last byte to inhibit further
307 * sending of data. If uaccess is TRUE, data is written to user-space with put_user.
308 * Returns -1 if I²C-device didn't send acknowledge, 0 otherwise
309 */
310
311static int i2c_getdata(struct saa5249_device *t, int count, u8 *buf)
312{
313 if(i2c_master_recv(t->client, buf, count)!=count)
314 return -1;
315 return 0;
316}
317
318
319/*
320 * Standard character-device-driver functions
321 */
322
323static int do_saa5249_ioctl(struct inode *inode, struct file *file,
324 unsigned int cmd, void *arg)
325{
326 static int virtual_mode = FALSE;
327 struct video_device *vd = video_devdata(file);
328 struct saa5249_device *t=vd->priv;
329
330 switch(cmd)
331 {
332 case VTXIOCGETINFO:
333 {
334 vtx_info_t *info = arg;
335 info->version_major = VTX_VER_MAJ;
336 info->version_minor = VTX_VER_MIN;
337 info->numpages = NUM_DAUS;
338 /*info->cct_type = CCT_TYPE;*/
339 return 0;
340 }
341
342 case VTXIOCCLRPAGE:
343 {
344 vtx_pagereq_t *req = arg;
345
346 if (req->pgbuf < 0 || req->pgbuf >= NUM_DAUS)
347 return -EINVAL;
348 memset(t->vdau[req->pgbuf].pgbuf, ' ', sizeof(t->vdau[0].pgbuf));
349 t->vdau[req->pgbuf].clrfound = TRUE;
350 return 0;
351 }
352
353 case VTXIOCCLRFOUND:
354 {
355 vtx_pagereq_t *req = arg;
356
357 if (req->pgbuf < 0 || req->pgbuf >= NUM_DAUS)
358 return -EINVAL;
359 t->vdau[req->pgbuf].clrfound = TRUE;
360 return 0;
361 }
362
363 case VTXIOCPAGEREQ:
364 {
365 vtx_pagereq_t *req = arg;
366 if (!(req->pagemask & PGMASK_PAGE))
367 req->page = 0;
368 if (!(req->pagemask & PGMASK_HOUR))
369 req->hour = 0;
370 if (!(req->pagemask & PGMASK_MINUTE))
371 req->minute = 0;
372 if (req->page < 0 || req->page > 0x8ff) /* 7FF ?? */
373 return -EINVAL;
374 req->page &= 0x7ff;
375 if (req->hour < 0 || req->hour > 0x3f || req->minute < 0 || req->minute > 0x7f ||
376 req->pagemask < 0 || req->pagemask >= PGMASK_MAX || req->pgbuf < 0 || req->pgbuf >= NUM_DAUS)
377 return -EINVAL;
378 t->vdau[req->pgbuf].sregs[0] = (req->pagemask & PG_HUND ? 0x10 : 0) | (req->page / 0x100);
379 t->vdau[req->pgbuf].sregs[1] = (req->pagemask & PG_TEN ? 0x10 : 0) | ((req->page / 0x10) & 0xf);
380 t->vdau[req->pgbuf].sregs[2] = (req->pagemask & PG_UNIT ? 0x10 : 0) | (req->page & 0xf);
381 t->vdau[req->pgbuf].sregs[3] = (req->pagemask & HR_TEN ? 0x10 : 0) | (req->hour / 0x10);
382 t->vdau[req->pgbuf].sregs[4] = (req->pagemask & HR_UNIT ? 0x10 : 0) | (req->hour & 0xf);
383 t->vdau[req->pgbuf].sregs[5] = (req->pagemask & MIN_TEN ? 0x10 : 0) | (req->minute / 0x10);
384 t->vdau[req->pgbuf].sregs[6] = (req->pagemask & MIN_UNIT ? 0x10 : 0) | (req->minute & 0xf);
385 t->vdau[req->pgbuf].stopped = FALSE;
386 t->vdau[req->pgbuf].clrfound = TRUE;
387 t->is_searching[req->pgbuf] = TRUE;
388 return 0;
389 }
390
391 case VTXIOCGETSTAT:
392 {
393 vtx_pagereq_t *req = arg;
394 u8 infobits[10];
395 vtx_pageinfo_t info;
396 int a;
397
398 if (req->pgbuf < 0 || req->pgbuf >= NUM_DAUS)
399 return -EINVAL;
400 if (!t->vdau[req->pgbuf].stopped)
401 {
402 if (i2c_senddata(t, 2, 0, -1) ||
403 i2c_sendbuf(t, 3, sizeof(t->vdau[0].sregs), t->vdau[req->pgbuf].sregs) ||
404 i2c_senddata(t, 8, 0, 25, 0, ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', -1) ||
405 i2c_senddata(t, 2, 0, t->vdau[req->pgbuf].sregs[0] | 8, -1) ||
406 i2c_senddata(t, 8, 0, 25, 0, -1))
407 return -EIO;
408 jdelay(PAGE_WAIT);
409 if (i2c_getdata(t, 10, infobits))
410 return -EIO;
411
412 if (!(infobits[8] & 0x10) && !(infobits[7] & 0xf0) && /* check FOUND-bit */
413 (memcmp(infobits, t->vdau[req->pgbuf].laststat, sizeof(infobits)) ||
414 time_after_eq(jiffies, t->vdau[req->pgbuf].expire)))
415 { /* check if new page arrived */
416 if (i2c_senddata(t, 8, 0, 0, 0, -1) ||
417 i2c_getdata(t, VTX_PAGESIZE, t->vdau[req->pgbuf].pgbuf))
418 return -EIO;
419 t->vdau[req->pgbuf].expire = jiffies + PGBUF_EXPIRE;
420 memset(t->vdau[req->pgbuf].pgbuf + VTX_PAGESIZE, ' ', VTX_VIRTUALSIZE - VTX_PAGESIZE);
421 if (t->virtual_mode)
422 {
423 /* Packet X/24 */
424 if (i2c_senddata(t, 8, 0, 0x20, 0, -1) ||
425 i2c_getdata(t, 40, t->vdau[req->pgbuf].pgbuf + VTX_PAGESIZE + 20 * 40))
426 return -EIO;
427 /* Packet X/27/0 */
428 if (i2c_senddata(t, 8, 0, 0x21, 0, -1) ||
429 i2c_getdata(t, 40, t->vdau[req->pgbuf].pgbuf + VTX_PAGESIZE + 16 * 40))
430 return -EIO;
431 /* Packet 8/30/0...8/30/15
432 * FIXME: AFAIK, the 5249 does hamming-decoding for some bytes in packet 8/30,
433 * so we should undo this here.
434 */
435 if (i2c_senddata(t, 8, 0, 0x22, 0, -1) ||
436 i2c_getdata(t, 40, t->vdau[req->pgbuf].pgbuf + VTX_PAGESIZE + 23 * 40))
437 return -EIO;
438 }
439 t->vdau[req->pgbuf].clrfound = FALSE;
440 memcpy(t->vdau[req->pgbuf].laststat, infobits, sizeof(infobits));
441 }
442 else
443 {
444 memcpy(infobits, t->vdau[req->pgbuf].laststat, sizeof(infobits));
445 }
446 }
447 else
448 {
449 memcpy(infobits, t->vdau[req->pgbuf].laststat, sizeof(infobits));
450 }
451
452 info.pagenum = ((infobits[8] << 8) & 0x700) | ((infobits[1] << 4) & 0xf0) | (infobits[0] & 0x0f);
453 if (info.pagenum < 0x100)
454 info.pagenum += 0x800;
455 info.hour = ((infobits[5] << 4) & 0x30) | (infobits[4] & 0x0f);
456 info.minute = ((infobits[3] << 4) & 0x70) | (infobits[2] & 0x0f);
457 info.charset = ((infobits[7] >> 1) & 7);
458 info.delete = !!(infobits[3] & 8);
459 info.headline = !!(infobits[5] & 4);
460 info.subtitle = !!(infobits[5] & 8);
461 info.supp_header = !!(infobits[6] & 1);
462 info.update = !!(infobits[6] & 2);
463 info.inter_seq = !!(infobits[6] & 4);
464 info.dis_disp = !!(infobits[6] & 8);
465 info.serial = !!(infobits[7] & 1);
466 info.notfound = !!(infobits[8] & 0x10);
467 info.pblf = !!(infobits[9] & 0x20);
468 info.hamming = 0;
469 for (a = 0; a <= 7; a++)
470 {
471 if (infobits[a] & 0xf0)
472 {
473 info.hamming = 1;
474 break;
475 }
476 }
477 if (t->vdau[req->pgbuf].clrfound)
478 info.notfound = 1;
479 if(copy_to_user(req->buffer, &info, sizeof(vtx_pageinfo_t)))
480 return -EFAULT;
481 if (!info.hamming && !info.notfound)
482 {
483 t->is_searching[req->pgbuf] = FALSE;
484 }
485 return 0;
486 }
487
488 case VTXIOCGETPAGE:
489 {
490 vtx_pagereq_t *req = arg;
491 int start, end;
492
493 if (req->pgbuf < 0 || req->pgbuf >= NUM_DAUS || req->start < 0 ||
494 req->start > req->end || req->end >= (virtual_mode ? VTX_VIRTUALSIZE : VTX_PAGESIZE))
495 return -EINVAL;
496 if(copy_to_user(req->buffer, &t->vdau[req->pgbuf].pgbuf[req->start], req->end - req->start + 1))
497 return -EFAULT;
498
499 /*
500 * Always read the time directly from SAA5249
501 */
502
503 if (req->start <= 39 && req->end >= 32)
504 {
505 int len;
506 char buf[16];
507 start = max(req->start, 32);
508 end = min(req->end, 39);
509 len=end-start+1;
510 if (i2c_senddata(t, 8, 0, 0, start, -1) ||
511 i2c_getdata(t, len, buf))
512 return -EIO;
513 if(copy_to_user(req->buffer+start-req->start, buf, len))
514 return -EFAULT;
515 }
516 /* Insert the current header if DAU is still searching for a page */
517 if (req->start <= 31 && req->end >= 7 && t->is_searching[req->pgbuf])
518 {
519 char buf[32];
520 int len;
521 start = max(req->start, 7);
522 end = min(req->end, 31);
523 len=end-start+1;
524 if (i2c_senddata(t, 8, 0, 0, start, -1) ||
525 i2c_getdata(t, len, buf))
526 return -EIO;
527 if(copy_to_user(req->buffer+start-req->start, buf, len))
528 return -EFAULT;
529 }
530 return 0;
531 }
532
533 case VTXIOCSTOPDAU:
534 {
535 vtx_pagereq_t *req = arg;
536
537 if (req->pgbuf < 0 || req->pgbuf >= NUM_DAUS)
538 return -EINVAL;
539 t->vdau[req->pgbuf].stopped = TRUE;
540 t->is_searching[req->pgbuf] = FALSE;
541 return 0;
542 }
543
544 case VTXIOCPUTPAGE:
545 case VTXIOCSETDISP:
546 case VTXIOCPUTSTAT:
547 return 0;
548
549 case VTXIOCCLRCACHE:
550 {
551 if (i2c_senddata(t, 0, NUM_DAUS, 0, 8, -1) || i2c_senddata(t, 11,
552 ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',
553 ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ', -1))
554 return -EIO;
555 if (i2c_senddata(t, 3, 0x20, -1))
556 return -EIO;
557 jdelay(10 * CLEAR_DELAY); /* I have no idea how long we have to wait here */
558 return 0;
559 }
560
561 case VTXIOCSETVIRT:
562 {
563 /* The SAA5249 has virtual-row reception turned on always */
564 t->virtual_mode = (int)(long)arg;
565 return 0;
566 }
567 }
568 return -EINVAL;
569}
570
571/*
572 * Translates old vtx IOCTLs to new ones
573 *
574 * This keeps new kernel versions compatible with old userspace programs.
575 */
576static inline unsigned int vtx_fix_command(unsigned int cmd)
577{
578 switch (cmd) {
579 case VTXIOCGETINFO_OLD:
580 cmd = VTXIOCGETINFO;
581 break;
582 case VTXIOCCLRPAGE_OLD:
583 cmd = VTXIOCCLRPAGE;
584 break;
585 case VTXIOCCLRFOUND_OLD:
586 cmd = VTXIOCCLRFOUND;
587 break;
588 case VTXIOCPAGEREQ_OLD:
589 cmd = VTXIOCPAGEREQ;
590 break;
591 case VTXIOCGETSTAT_OLD:
592 cmd = VTXIOCGETSTAT;
593 break;
594 case VTXIOCGETPAGE_OLD:
595 cmd = VTXIOCGETPAGE;
596 break;
597 case VTXIOCSTOPDAU_OLD:
598 cmd = VTXIOCSTOPDAU;
599 break;
600 case VTXIOCPUTPAGE_OLD:
601 cmd = VTXIOCPUTPAGE;
602 break;
603 case VTXIOCSETDISP_OLD:
604 cmd = VTXIOCSETDISP;
605 break;
606 case VTXIOCPUTSTAT_OLD:
607 cmd = VTXIOCPUTSTAT;
608 break;
609 case VTXIOCCLRCACHE_OLD:
610 cmd = VTXIOCCLRCACHE;
611 break;
612 case VTXIOCSETVIRT_OLD:
613 cmd = VTXIOCSETVIRT;
614 break;
615 }
616 return cmd;
617}
618
619/*
620 * Handle the locking
621 */
622
623static int saa5249_ioctl(struct inode *inode, struct file *file,
624 unsigned int cmd, unsigned long arg)
625{
626 struct video_device *vd = video_devdata(file);
627 struct saa5249_device *t=vd->priv;
628 int err;
629
630 cmd = vtx_fix_command(cmd);
631 down(&t->lock);
632 err = video_usercopy(inode,file,cmd,arg,do_saa5249_ioctl);
633 up(&t->lock);
634 return err;
635}
636
637static int saa5249_open(struct inode *inode, struct file *file)
638{
639 struct video_device *vd = video_devdata(file);
640 struct saa5249_device *t=vd->priv;
641 int err,pgbuf;
642
643 err = video_exclusive_open(inode,file);
644 if (err < 0)
645 return err;
646
647 if (t->client==NULL) {
648 err = -ENODEV;
649 goto fail;
650 }
651
652 if (i2c_senddata(t, 0, 0, -1) || /* Select R11 */
653 /* Turn off parity checks (we do this ourselves) */
654 i2c_senddata(t, 1, disp_modes[t->disp_mode][0], 0, -1) ||
655 /* Display TV-picture, no virtual rows */
656 i2c_senddata(t, 4, NUM_DAUS, disp_modes[t->disp_mode][1], disp_modes[t->disp_mode][2], 7, -1)) /* Set display to page 4 */
657
658 {
659 err = -EIO;
660 goto fail;
661 }
662
663 for (pgbuf = 0; pgbuf < NUM_DAUS; pgbuf++)
664 {
665 memset(t->vdau[pgbuf].pgbuf, ' ', sizeof(t->vdau[0].pgbuf));
666 memset(t->vdau[pgbuf].sregs, 0, sizeof(t->vdau[0].sregs));
667 memset(t->vdau[pgbuf].laststat, 0, sizeof(t->vdau[0].laststat));
668 t->vdau[pgbuf].expire = 0;
669 t->vdau[pgbuf].clrfound = TRUE;
670 t->vdau[pgbuf].stopped = TRUE;
671 t->is_searching[pgbuf] = FALSE;
672 }
673 t->virtual_mode=FALSE;
674 return 0;
675
676 fail:
677 video_exclusive_release(inode,file);
678 return err;
679}
680
681
682
683static int saa5249_release(struct inode *inode, struct file *file)
684{
685 struct video_device *vd = video_devdata(file);
686 struct saa5249_device *t=vd->priv;
687 i2c_senddata(t, 1, 0x20, -1); /* Turn off CCT */
688 i2c_senddata(t, 5, 3, 3, -1); /* Turn off TV-display */
689 video_exclusive_release(inode,file);
690 return 0;
691}
692
693static int __init init_saa_5249 (void)
694{
695 printk(KERN_INFO "SAA5249 driver (" IF_NAME " interface) for VideoText version %d.%d\n",
696 VTX_VER_MAJ, VTX_VER_MIN);
697 return i2c_add_driver(&i2c_driver_videotext);
698}
699
700static void __exit cleanup_saa_5249 (void)
701{
702 i2c_del_driver(&i2c_driver_videotext);
703}
704
705module_init(init_saa_5249);
706module_exit(cleanup_saa_5249);
707
708static struct file_operations saa_fops = {
709 .owner = THIS_MODULE,
710 .open = saa5249_open,
711 .release = saa5249_release,
712 .ioctl = saa5249_ioctl,
713 .llseek = no_llseek,
714};
715
716static struct video_device saa_template =
717{
718 .owner = THIS_MODULE,
719 .name = IF_NAME,
720 .type = VID_TYPE_TELETEXT, /*| VID_TYPE_TUNER ?? */
721 .hardware = VID_HARDWARE_SAA5249,
722 .fops = &saa_fops,
723};
724
725MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/saa7110.c b/drivers/media/video/saa7110.c
new file mode 100644
index 00000000000..64273b43853
--- /dev/null
+++ b/drivers/media/video/saa7110.c
@@ -0,0 +1,623 @@
1/*
2 * saa7110 - Philips SAA7110(A) video decoder driver
3 *
4 * Copyright (C) 1998 Pauline Middelink <middelin@polyware.nl>
5 *
6 * Copyright (C) 1999 Wolfgang Scherr <scherr@net4you.net>
7 * Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>
8 * - some corrections for Pinnacle Systems Inc. DC10plus card.
9 *
10 * Changes by Ronald Bultje <rbultje@ronald.bitfreak.net>
11 * - moved over to linux>=2.4.x i2c protocol (1/1/2003)
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 */
27
28#include <linux/module.h>
29#include <linux/init.h>
30#include <linux/types.h>
31#include <linux/delay.h>
32#include <linux/slab.h>
33#include <linux/wait.h>
34#include <asm/io.h>
35#include <asm/uaccess.h>
36
37MODULE_DESCRIPTION("Philips SAA7110 video decoder driver");
38MODULE_AUTHOR("Pauline Middelink");
39MODULE_LICENSE("GPL");
40
41#include <linux/i2c.h>
42#include <linux/i2c-dev.h>
43
44#define I2C_NAME(s) (s)->name
45
46#include <linux/videodev.h>
47#include <linux/video_decoder.h>
48
49static int debug = 0;
50module_param(debug, int, 0);
51MODULE_PARM_DESC(debug, "Debug level (0-1)");
52
53#define dprintk(num, format, args...) \
54 do { \
55 if (debug >= num) \
56 printk(format, ##args); \
57 } while (0)
58
59#define SAA7110_MAX_INPUT 9 /* 6 CVBS, 3 SVHS */
60#define SAA7110_MAX_OUTPUT 0 /* its a decoder only */
61
62#define I2C_SAA7110 0x9C /* or 0x9E */
63
64#define SAA7110_NR_REG 0x35
65
66struct saa7110 {
67 u8 reg[SAA7110_NR_REG];
68
69 int norm;
70 int input;
71 int enable;
72 int bright;
73 int contrast;
74 int hue;
75 int sat;
76
77 wait_queue_head_t wq;
78};
79
80/* ----------------------------------------------------------------------- */
81/* I2C support functions */
82/* ----------------------------------------------------------------------- */
83
84static int
85saa7110_write (struct i2c_client *client,
86 u8 reg,
87 u8 value)
88{
89 struct saa7110 *decoder = i2c_get_clientdata(client);
90
91 decoder->reg[reg] = value;
92 return i2c_smbus_write_byte_data(client, reg, value);
93}
94
95static int
96saa7110_write_block (struct i2c_client *client,
97 const u8 *data,
98 unsigned int len)
99{
100 int ret = -1;
101 u8 reg = *data; /* first register to write to */
102
103 /* Sanity check */
104 if (reg + (len - 1) > SAA7110_NR_REG)
105 return ret;
106
107 /* the saa7110 has an autoincrement function, use it if
108 * the adapter understands raw I2C */
109 if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
110 struct saa7110 *decoder = i2c_get_clientdata(client);
111 struct i2c_msg msg;
112
113 msg.len = len;
114 msg.buf = (char *) data;
115 msg.addr = client->addr;
116 msg.flags = 0;
117 ret = i2c_transfer(client->adapter, &msg, 1);
118
119 /* Cache the written data */
120 memcpy(decoder->reg + reg, data + 1, len - 1);
121 } else {
122 for (++data, --len; len; len--) {
123 if ((ret = saa7110_write(client, reg++,
124 *data++)) < 0)
125 break;
126 }
127 }
128
129 return ret;
130}
131
132static inline int
133saa7110_read (struct i2c_client *client)
134{
135 return i2c_smbus_read_byte(client);
136}
137
138/* ----------------------------------------------------------------------- */
139/* SAA7110 functions */
140/* ----------------------------------------------------------------------- */
141
142#define FRESP_06H_COMPST 0x03 //0x13
143#define FRESP_06H_SVIDEO 0x83 //0xC0
144
145
146static int
147saa7110_selmux (struct i2c_client *client,
148 int chan)
149{
150 static const unsigned char modes[9][8] = {
151 /* mode 0 */
152 {FRESP_06H_COMPST, 0xD9, 0x17, 0x40, 0x03,
153 0x44, 0x75, 0x16},
154 /* mode 1 */
155 {FRESP_06H_COMPST, 0xD8, 0x17, 0x40, 0x03,
156 0x44, 0x75, 0x16},
157 /* mode 2 */
158 {FRESP_06H_COMPST, 0xBA, 0x07, 0x91, 0x03,
159 0x60, 0xB5, 0x05},
160 /* mode 3 */
161 {FRESP_06H_COMPST, 0xB8, 0x07, 0x91, 0x03,
162 0x60, 0xB5, 0x05},
163 /* mode 4 */
164 {FRESP_06H_COMPST, 0x7C, 0x07, 0xD2, 0x83,
165 0x60, 0xB5, 0x03},
166 /* mode 5 */
167 {FRESP_06H_COMPST, 0x78, 0x07, 0xD2, 0x83,
168 0x60, 0xB5, 0x03},
169 /* mode 6 */
170 {FRESP_06H_SVIDEO, 0x59, 0x17, 0x42, 0xA3,
171 0x44, 0x75, 0x12},
172 /* mode 7 */
173 {FRESP_06H_SVIDEO, 0x9A, 0x17, 0xB1, 0x13,
174 0x60, 0xB5, 0x14},
175 /* mode 8 */
176 {FRESP_06H_SVIDEO, 0x3C, 0x27, 0xC1, 0x23,
177 0x44, 0x75, 0x21}
178 };
179 struct saa7110 *decoder = i2c_get_clientdata(client);
180 const unsigned char *ptr = modes[chan];
181
182 saa7110_write(client, 0x06, ptr[0]); /* Luminance control */
183 saa7110_write(client, 0x20, ptr[1]); /* Analog Control #1 */
184 saa7110_write(client, 0x21, ptr[2]); /* Analog Control #2 */
185 saa7110_write(client, 0x22, ptr[3]); /* Mixer Control #1 */
186 saa7110_write(client, 0x2C, ptr[4]); /* Mixer Control #2 */
187 saa7110_write(client, 0x30, ptr[5]); /* ADCs gain control */
188 saa7110_write(client, 0x31, ptr[6]); /* Mixer Control #3 */
189 saa7110_write(client, 0x21, ptr[7]); /* Analog Control #2 */
190 decoder->input = chan;
191
192 return 0;
193}
194
195static const unsigned char initseq[1 + SAA7110_NR_REG] = {
196 0, 0x4C, 0x3C, 0x0D, 0xEF, 0xBD, 0xF2, 0x03, 0x00,
197 /* 0x08 */ 0xF8, 0xF8, 0x60, 0x60, 0x00, 0x86, 0x18, 0x90,
198 /* 0x10 */ 0x00, 0x59, 0x40, 0x46, 0x42, 0x1A, 0xFF, 0xDA,
199 /* 0x18 */ 0xF2, 0x8B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
200 /* 0x20 */ 0xD9, 0x16, 0x40, 0x41, 0x80, 0x41, 0x80, 0x4F,
201 /* 0x28 */ 0xFE, 0x01, 0xCF, 0x0F, 0x03, 0x01, 0x03, 0x0C,
202 /* 0x30 */ 0x44, 0x71, 0x02, 0x8C, 0x02
203};
204
205static int
206determine_norm (struct i2c_client *client)
207{
208 DEFINE_WAIT(wait);
209 struct saa7110 *decoder = i2c_get_clientdata(client);
210 int status;
211
212 /* mode changed, start automatic detection */
213 saa7110_write_block(client, initseq, sizeof(initseq));
214 saa7110_selmux(client, decoder->input);
215 prepare_to_wait(&decoder->wq, &wait, TASK_UNINTERRUPTIBLE);
216 schedule_timeout(HZ/4);
217 finish_wait(&decoder->wq, &wait);
218 status = saa7110_read(client);
219 if (status & 0x40) {
220 dprintk(1, KERN_INFO "%s: status=0x%02x (no signal)\n",
221 I2C_NAME(client), status);
222 return decoder->norm; // no change
223 }
224 if ((status & 3) == 0) {
225 saa7110_write(client, 0x06, 0x83);
226 if (status & 0x20) {
227 dprintk(1,
228 KERN_INFO
229 "%s: status=0x%02x (NTSC/no color)\n",
230 I2C_NAME(client), status);
231 //saa7110_write(client,0x2E,0x81);
232 return VIDEO_MODE_NTSC;
233 }
234 dprintk(1, KERN_INFO "%s: status=0x%02x (PAL/no color)\n",
235 I2C_NAME(client), status);
236 //saa7110_write(client,0x2E,0x9A);
237 return VIDEO_MODE_PAL;
238 }
239 //saa7110_write(client,0x06,0x03);
240 if (status & 0x20) { /* 60Hz */
241 dprintk(1, KERN_INFO "%s: status=0x%02x (NTSC)\n",
242 I2C_NAME(client), status);
243 saa7110_write(client, 0x0D, 0x86);
244 saa7110_write(client, 0x0F, 0x50);
245 saa7110_write(client, 0x11, 0x2C);
246 //saa7110_write(client,0x2E,0x81);
247 return VIDEO_MODE_NTSC;
248 }
249
250 /* 50Hz -> PAL/SECAM */
251 saa7110_write(client, 0x0D, 0x86);
252 saa7110_write(client, 0x0F, 0x10);
253 saa7110_write(client, 0x11, 0x59);
254 //saa7110_write(client,0x2E,0x9A);
255
256 prepare_to_wait(&decoder->wq, &wait, TASK_UNINTERRUPTIBLE);
257 schedule_timeout(HZ/4);
258 finish_wait(&decoder->wq, &wait);
259
260 status = saa7110_read(client);
261 if ((status & 0x03) == 0x01) {
262 dprintk(1, KERN_INFO "%s: status=0x%02x (SECAM)\n",
263 I2C_NAME(client), status);
264 saa7110_write(client, 0x0D, 0x87);
265 return VIDEO_MODE_SECAM;
266 }
267 dprintk(1, KERN_INFO "%s: status=0x%02x (PAL)\n", I2C_NAME(client),
268 status);
269 return VIDEO_MODE_PAL;
270}
271
272static int
273saa7110_command (struct i2c_client *client,
274 unsigned int cmd,
275 void *arg)
276{
277 struct saa7110 *decoder = i2c_get_clientdata(client);
278 int v;
279
280 switch (cmd) {
281 case 0:
282 //saa7110_write_block(client, initseq, sizeof(initseq));
283 break;
284
285 case DECODER_GET_CAPABILITIES:
286 {
287 struct video_decoder_capability *dc = arg;
288
289 dc->flags =
290 VIDEO_DECODER_PAL | VIDEO_DECODER_NTSC |
291 VIDEO_DECODER_SECAM | VIDEO_DECODER_AUTO;
292 dc->inputs = SAA7110_MAX_INPUT;
293 dc->outputs = SAA7110_MAX_OUTPUT;
294 }
295 break;
296
297 case DECODER_GET_STATUS:
298 {
299 int status;
300 int res = 0;
301
302 status = saa7110_read(client);
303 dprintk(1, KERN_INFO "%s: status=0x%02x norm=%d\n",
304 I2C_NAME(client), status, decoder->norm);
305 if (!(status & 0x40))
306 res |= DECODER_STATUS_GOOD;
307 if (status & 0x03)
308 res |= DECODER_STATUS_COLOR;
309
310 switch (decoder->norm) {
311 case VIDEO_MODE_NTSC:
312 res |= DECODER_STATUS_NTSC;
313 break;
314 case VIDEO_MODE_PAL:
315 res |= DECODER_STATUS_PAL;
316 break;
317 case VIDEO_MODE_SECAM:
318 res |= DECODER_STATUS_SECAM;
319 break;
320 }
321 *(int *) arg = res;
322 }
323 break;
324
325 case DECODER_SET_NORM:
326 v = *(int *) arg;
327 if (decoder->norm != v) {
328 decoder->norm = v;
329 //saa7110_write(client, 0x06, 0x03);
330 switch (v) {
331 case VIDEO_MODE_NTSC:
332 saa7110_write(client, 0x0D, 0x86);
333 saa7110_write(client, 0x0F, 0x50);
334 saa7110_write(client, 0x11, 0x2C);
335 //saa7110_write(client, 0x2E, 0x81);
336 dprintk(1,
337 KERN_INFO "%s: switched to NTSC\n",
338 I2C_NAME(client));
339 break;
340 case VIDEO_MODE_PAL:
341 saa7110_write(client, 0x0D, 0x86);
342 saa7110_write(client, 0x0F, 0x10);
343 saa7110_write(client, 0x11, 0x59);
344 //saa7110_write(client, 0x2E, 0x9A);
345 dprintk(1,
346 KERN_INFO "%s: switched to PAL\n",
347 I2C_NAME(client));
348 break;
349 case VIDEO_MODE_SECAM:
350 saa7110_write(client, 0x0D, 0x87);
351 saa7110_write(client, 0x0F, 0x10);
352 saa7110_write(client, 0x11, 0x59);
353 //saa7110_write(client, 0x2E, 0x9A);
354 dprintk(1,
355 KERN_INFO
356 "%s: switched to SECAM\n",
357 I2C_NAME(client));
358 break;
359 case VIDEO_MODE_AUTO:
360 dprintk(1,
361 KERN_INFO
362 "%s: TV standard detection...\n",
363 I2C_NAME(client));
364 decoder->norm = determine_norm(client);
365 *(int *) arg = decoder->norm;
366 break;
367 default:
368 return -EPERM;
369 }
370 }
371 break;
372
373 case DECODER_SET_INPUT:
374 v = *(int *) arg;
375 if (v < 0 || v > SAA7110_MAX_INPUT) {
376 dprintk(1,
377 KERN_INFO "%s: input=%d not available\n",
378 I2C_NAME(client), v);
379 return -EINVAL;
380 }
381 if (decoder->input != v) {
382 saa7110_selmux(client, v);
383 dprintk(1, KERN_INFO "%s: switched to input=%d\n",
384 I2C_NAME(client), v);
385 }
386 break;
387
388 case DECODER_SET_OUTPUT:
389 v = *(int *) arg;
390 /* not much choice of outputs */
391 if (v != 0)
392 return -EINVAL;
393 break;
394
395 case DECODER_ENABLE_OUTPUT:
396 v = *(int *) arg;
397 if (decoder->enable != v) {
398 decoder->enable = v;
399 saa7110_write(client, 0x0E, v ? 0x18 : 0x80);
400 dprintk(1, KERN_INFO "%s: YUV %s\n", I2C_NAME(client),
401 v ? "on" : "off");
402 }
403 break;
404
405 case DECODER_SET_PICTURE:
406 {
407 struct video_picture *pic = arg;
408
409 if (decoder->bright != pic->brightness) {
410 /* We want 0 to 255 we get 0-65535 */
411 decoder->bright = pic->brightness;
412 saa7110_write(client, 0x19, decoder->bright >> 8);
413 }
414 if (decoder->contrast != pic->contrast) {
415 /* We want 0 to 127 we get 0-65535 */
416 decoder->contrast = pic->contrast;
417 saa7110_write(client, 0x13,
418 decoder->contrast >> 9);
419 }
420 if (decoder->sat != pic->colour) {
421 /* We want 0 to 127 we get 0-65535 */
422 decoder->sat = pic->colour;
423 saa7110_write(client, 0x12, decoder->sat >> 9);
424 }
425 if (decoder->hue != pic->hue) {
426 /* We want -128 to 127 we get 0-65535 */
427 decoder->hue = pic->hue;
428 saa7110_write(client, 0x07,
429 (decoder->hue >> 8) - 128);
430 }
431 }
432 break;
433
434 case DECODER_DUMP:
435 for (v = 0; v < 0x34; v += 16) {
436 int j;
437 dprintk(1, KERN_INFO "%s: %03x\n", I2C_NAME(client),
438 v);
439 for (j = 0; j < 16; j++) {
440 dprintk(1, KERN_INFO " %02x",
441 decoder->reg[v + j]);
442 }
443 dprintk(1, KERN_INFO "\n");
444 }
445 break;
446
447 default:
448 dprintk(1, KERN_INFO "unknown saa7110_command??(%d)\n",
449 cmd);
450 return -EINVAL;
451 }
452 return 0;
453}
454
455/* ----------------------------------------------------------------------- */
456
457/*
458 * Generic i2c probe
459 * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
460 */
461static unsigned short normal_i2c[] = {
462 I2C_SAA7110 >> 1,
463 (I2C_SAA7110 >> 1) + 1,
464 I2C_CLIENT_END
465};
466static unsigned short normal_i2c_range[] = { I2C_CLIENT_END };
467
468static unsigned short probe[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
469static unsigned short probe_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
470static unsigned short ignore[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
471static unsigned short ignore_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
472static unsigned short force[2] = { I2C_CLIENT_END , I2C_CLIENT_END };
473
474static struct i2c_client_address_data addr_data = {
475 .normal_i2c = normal_i2c,
476 .normal_i2c_range = normal_i2c_range,
477 .probe = probe,
478 .probe_range = probe_range,
479 .ignore = ignore,
480 .ignore_range = ignore_range,
481 .force = force
482};
483
484static struct i2c_driver i2c_driver_saa7110;
485
486static int
487saa7110_detect_client (struct i2c_adapter *adapter,
488 int address,
489 int kind)
490{
491 struct i2c_client *client;
492 struct saa7110 *decoder;
493 int rv;
494
495 dprintk(1,
496 KERN_INFO
497 "saa7110.c: detecting saa7110 client on address 0x%x\n",
498 address << 1);
499
500 /* Check if the adapter supports the needed features */
501 if (!i2c_check_functionality
502 (adapter,
503 I2C_FUNC_SMBUS_READ_BYTE | I2C_FUNC_SMBUS_WRITE_BYTE_DATA))
504 return 0;
505
506 client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
507 if (client == 0)
508 return -ENOMEM;
509 memset(client, 0, sizeof(struct i2c_client));
510 client->addr = address;
511 client->adapter = adapter;
512 client->driver = &i2c_driver_saa7110;
513 client->flags = I2C_CLIENT_ALLOW_USE;
514 strlcpy(I2C_NAME(client), "saa7110", sizeof(I2C_NAME(client)));
515
516 decoder = kmalloc(sizeof(struct saa7110), GFP_KERNEL);
517 if (decoder == 0) {
518 kfree(client);
519 return -ENOMEM;
520 }
521 memset(decoder, 0, sizeof(struct saa7110));
522 decoder->norm = VIDEO_MODE_PAL;
523 decoder->input = 0;
524 decoder->enable = 1;
525 decoder->bright = 32768;
526 decoder->contrast = 32768;
527 decoder->hue = 32768;
528 decoder->sat = 32768;
529 init_waitqueue_head(&decoder->wq);
530 i2c_set_clientdata(client, decoder);
531
532 rv = i2c_attach_client(client);
533 if (rv) {
534 kfree(client);
535 kfree(decoder);
536 return rv;
537 }
538
539 rv = saa7110_write_block(client, initseq, sizeof(initseq));
540 if (rv < 0)
541 dprintk(1, KERN_ERR "%s_attach: init status %d\n",
542 I2C_NAME(client), rv);
543 else {
544 int ver, status;
545 saa7110_write(client, 0x21, 0x10);
546 saa7110_write(client, 0x0e, 0x18);
547 saa7110_write(client, 0x0D, 0x04);
548 ver = saa7110_read(client);
549 saa7110_write(client, 0x0D, 0x06);
550 //mdelay(150);
551 status = saa7110_read(client);
552 dprintk(1,
553 KERN_INFO
554 "%s_attach: SAA7110A version %x at 0x%02x, status=0x%02x\n",
555 I2C_NAME(client), ver, client->addr << 1, status);
556 saa7110_write(client, 0x0D, 0x86);
557 saa7110_write(client, 0x0F, 0x10);
558 saa7110_write(client, 0x11, 0x59);
559 //saa7110_write(client, 0x2E, 0x9A);
560 }
561
562 //saa7110_selmux(client,0);
563 //determine_norm(client);
564 /* setup and implicit mode 0 select has been performed */
565
566 return 0;
567}
568
569static int
570saa7110_attach_adapter (struct i2c_adapter *adapter)
571{
572 dprintk(1,
573 KERN_INFO
574 "saa7110.c: starting probe for adapter %s (0x%x)\n",
575 I2C_NAME(adapter), adapter->id);
576 return i2c_probe(adapter, &addr_data, &saa7110_detect_client);
577}
578
579static int
580saa7110_detach_client (struct i2c_client *client)
581{
582 struct saa7110 *decoder = i2c_get_clientdata(client);
583 int err;
584
585 err = i2c_detach_client(client);
586 if (err) {
587 return err;
588 }
589
590 kfree(decoder);
591 kfree(client);
592
593 return 0;
594}
595
596/* ----------------------------------------------------------------------- */
597
598static struct i2c_driver i2c_driver_saa7110 = {
599 .owner = THIS_MODULE,
600 .name = "saa7110",
601
602 .id = I2C_DRIVERID_SAA7110,
603 .flags = I2C_DF_NOTIFY,
604
605 .attach_adapter = saa7110_attach_adapter,
606 .detach_client = saa7110_detach_client,
607 .command = saa7110_command,
608};
609
610static int __init
611saa7110_init (void)
612{
613 return i2c_add_driver(&i2c_driver_saa7110);
614}
615
616static void __exit
617saa7110_exit (void)
618{
619 i2c_del_driver(&i2c_driver_saa7110);
620}
621
622module_init(saa7110_init);
623module_exit(saa7110_exit);
diff --git a/drivers/media/video/saa7111.c b/drivers/media/video/saa7111.c
new file mode 100644
index 00000000000..0a873112ae2
--- /dev/null
+++ b/drivers/media/video/saa7111.c
@@ -0,0 +1,627 @@
1/*
2 * saa7111 - Philips SAA7111A video decoder driver version 0.0.3
3 *
4 * Copyright (C) 1998 Dave Perks <dperks@ibm.net>
5 *
6 * Slight changes for video timing and attachment output by
7 * Wolfgang Scherr <scherr@net4you.net>
8 *
9 * Changes by Ronald Bultje <rbultje@ronald.bitfreak.net>
10 * - moved over to linux>=2.4.x i2c protocol (1/1/2003)
11 *
12 * Changes by Michael Hunold <michael@mihu.de>
13 * - implemented DECODER_SET_GPIO, DECODER_INIT, DECODER_SET_VBI_BYPASS
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 */
29
30#include <linux/module.h>
31#include <linux/init.h>
32#include <linux/delay.h>
33#include <linux/errno.h>
34#include <linux/fs.h>
35#include <linux/kernel.h>
36#include <linux/major.h>
37#include <linux/slab.h>
38#include <linux/mm.h>
39#include <linux/pci.h>
40#include <linux/signal.h>
41#include <asm/io.h>
42#include <asm/pgtable.h>
43#include <asm/page.h>
44#include <linux/sched.h>
45#include <asm/segment.h>
46#include <linux/types.h>
47
48#include <linux/videodev.h>
49#include <asm/uaccess.h>
50
51MODULE_DESCRIPTION("Philips SAA7111 video decoder driver");
52MODULE_AUTHOR("Dave Perks");
53MODULE_LICENSE("GPL");
54
55#include <linux/i2c.h>
56#include <linux/i2c-dev.h>
57
58#define I2C_NAME(s) (s)->name
59
60#include <linux/video_decoder.h>
61
62static int debug = 0;
63module_param(debug, int, 0644);
64MODULE_PARM_DESC(debug, "Debug level (0-1)");
65
66#define dprintk(num, format, args...) \
67 do { \
68 if (debug >= num) \
69 printk(format, ##args); \
70 } while (0)
71
72/* ----------------------------------------------------------------------- */
73
74struct saa7111 {
75 unsigned char reg[32];
76
77 int norm;
78 int input;
79 int enable;
80 int bright;
81 int contrast;
82 int hue;
83 int sat;
84};
85
86#define I2C_SAA7111 0x48
87
88/* ----------------------------------------------------------------------- */
89
90static inline int
91saa7111_write (struct i2c_client *client,
92 u8 reg,
93 u8 value)
94{
95 struct saa7111 *decoder = i2c_get_clientdata(client);
96
97 decoder->reg[reg] = value;
98 return i2c_smbus_write_byte_data(client, reg, value);
99}
100
101static int
102saa7111_write_block (struct i2c_client *client,
103 const u8 *data,
104 unsigned int len)
105{
106 int ret = -1;
107 u8 reg;
108
109 /* the saa7111 has an autoincrement function, use it if
110 * the adapter understands raw I2C */
111 if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
112 /* do raw I2C, not smbus compatible */
113 struct saa7111 *decoder = i2c_get_clientdata(client);
114 struct i2c_msg msg;
115 u8 block_data[32];
116
117 msg.addr = client->addr;
118 msg.flags = 0;
119 while (len >= 2) {
120 msg.buf = (char *) block_data;
121 msg.len = 0;
122 block_data[msg.len++] = reg = data[0];
123 do {
124 block_data[msg.len++] =
125 decoder->reg[reg++] = data[1];
126 len -= 2;
127 data += 2;
128 } while (len >= 2 && data[0] == reg &&
129 msg.len < 32);
130 if ((ret = i2c_transfer(client->adapter,
131 &msg, 1)) < 0)
132 break;
133 }
134 } else {
135 /* do some slow I2C emulation kind of thing */
136 while (len >= 2) {
137 reg = *data++;
138 if ((ret = saa7111_write(client, reg,
139 *data++)) < 0)
140 break;
141 len -= 2;
142 }
143 }
144
145 return ret;
146}
147
148static int
149saa7111_init_decoder (struct i2c_client *client,
150 struct video_decoder_init *init)
151{
152 return saa7111_write_block(client, init->data, init->len);
153}
154
155static inline int
156saa7111_read (struct i2c_client *client,
157 u8 reg)
158{
159 return i2c_smbus_read_byte_data(client, reg);
160}
161
162/* ----------------------------------------------------------------------- */
163
164static const unsigned char saa7111_i2c_init[] = {
165 0x00, 0x00, /* 00 - ID byte */
166 0x01, 0x00, /* 01 - reserved */
167
168 /*front end */
169 0x02, 0xd0, /* 02 - FUSE=3, GUDL=2, MODE=0 */
170 0x03, 0x23, /* 03 - HLNRS=0, VBSL=1, WPOFF=0,
171 * HOLDG=0, GAFIX=0, GAI1=256, GAI2=256 */
172 0x04, 0x00, /* 04 - GAI1=256 */
173 0x05, 0x00, /* 05 - GAI2=256 */
174
175 /* decoder */
176 0x06, 0xf3, /* 06 - HSB at 13(50Hz) / 17(60Hz)
177 * pixels after end of last line */
178 /*0x07, 0x13, * 07 - HSS at 113(50Hz) / 117(60Hz) pixels
179 * after end of last line */
180 0x07, 0xe8, /* 07 - HSS seems to be needed to
181 * work with NTSC, too */
182 0x08, 0xc8, /* 08 - AUFD=1, FSEL=1, EXFIL=0,
183 * VTRC=1, HPLL=0, VNOI=0 */
184 0x09, 0x01, /* 09 - BYPS=0, PREF=0, BPSS=0,
185 * VBLB=0, UPTCV=0, APER=1 */
186 0x0a, 0x80, /* 0a - BRIG=128 */
187 0x0b, 0x47, /* 0b - CONT=1.109 */
188 0x0c, 0x40, /* 0c - SATN=1.0 */
189 0x0d, 0x00, /* 0d - HUE=0 */
190 0x0e, 0x01, /* 0e - CDTO=0, CSTD=0, DCCF=0,
191 * FCTC=0, CHBW=1 */
192 0x0f, 0x00, /* 0f - reserved */
193 0x10, 0x48, /* 10 - OFTS=1, HDEL=0, VRLN=1, YDEL=0 */
194 0x11, 0x1c, /* 11 - GPSW=0, CM99=0, FECO=0, COMPO=1,
195 * OEYC=1, OEHV=1, VIPB=0, COLO=0 */
196 0x12, 0x00, /* 12 - output control 2 */
197 0x13, 0x00, /* 13 - output control 3 */
198 0x14, 0x00, /* 14 - reserved */
199 0x15, 0x00, /* 15 - VBI */
200 0x16, 0x00, /* 16 - VBI */
201 0x17, 0x00, /* 17 - VBI */
202};
203
204static int
205saa7111_command (struct i2c_client *client,
206 unsigned int cmd,
207 void *arg)
208{
209 struct saa7111 *decoder = i2c_get_clientdata(client);
210
211 switch (cmd) {
212
213 case 0:
214 case DECODER_INIT:
215 {
216 struct video_decoder_init *init = arg;
217 if (NULL != init)
218 return saa7111_init_decoder(client, init);
219 else {
220 struct video_decoder_init vdi;
221 vdi.data = saa7111_i2c_init;
222 vdi.len = sizeof(saa7111_i2c_init);
223 return saa7111_init_decoder(client, &vdi);
224 }
225 }
226
227 case DECODER_DUMP:
228 {
229 int i;
230
231 for (i = 0; i < 32; i += 16) {
232 int j;
233
234 printk(KERN_DEBUG "%s: %03x", I2C_NAME(client), i);
235 for (j = 0; j < 16; ++j) {
236 printk(" %02x",
237 saa7111_read(client, i + j));
238 }
239 printk("\n");
240 }
241 }
242 break;
243
244 case DECODER_GET_CAPABILITIES:
245 {
246 struct video_decoder_capability *cap = arg;
247
248 cap->flags = VIDEO_DECODER_PAL |
249 VIDEO_DECODER_NTSC |
250 VIDEO_DECODER_SECAM |
251 VIDEO_DECODER_AUTO |
252 VIDEO_DECODER_CCIR;
253 cap->inputs = 8;
254 cap->outputs = 1;
255 }
256 break;
257
258 case DECODER_GET_STATUS:
259 {
260 int *iarg = arg;
261 int status;
262 int res;
263
264 status = saa7111_read(client, 0x1f);
265 dprintk(1, KERN_DEBUG "%s status: 0x%02x\n", I2C_NAME(client),
266 status);
267 res = 0;
268 if ((status & (1 << 6)) == 0) {
269 res |= DECODER_STATUS_GOOD;
270 }
271 switch (decoder->norm) {
272 case VIDEO_MODE_NTSC:
273 res |= DECODER_STATUS_NTSC;
274 break;
275 case VIDEO_MODE_PAL:
276 res |= DECODER_STATUS_PAL;
277 break;
278 case VIDEO_MODE_SECAM:
279 res |= DECODER_STATUS_SECAM;
280 break;
281 default:
282 case VIDEO_MODE_AUTO:
283 if ((status & (1 << 5)) != 0) {
284 res |= DECODER_STATUS_NTSC;
285 } else {
286 res |= DECODER_STATUS_PAL;
287 }
288 break;
289 }
290 if ((status & (1 << 0)) != 0) {
291 res |= DECODER_STATUS_COLOR;
292 }
293 *iarg = res;
294 }
295 break;
296
297 case DECODER_SET_GPIO:
298 {
299 int *iarg = arg;
300 if (0 != *iarg) {
301 saa7111_write(client, 0x11,
302 (decoder->reg[0x11] | 0x80));
303 } else {
304 saa7111_write(client, 0x11,
305 (decoder->reg[0x11] & 0x7f));
306 }
307 break;
308 }
309
310 case DECODER_SET_VBI_BYPASS:
311 {
312 int *iarg = arg;
313 if (0 != *iarg) {
314 saa7111_write(client, 0x13,
315 (decoder->reg[0x13] & 0xf0) | 0x0a);
316 } else {
317 saa7111_write(client, 0x13,
318 (decoder->reg[0x13] & 0xf0));
319 }
320 break;
321 }
322
323 case DECODER_SET_NORM:
324 {
325 int *iarg = arg;
326
327 switch (*iarg) {
328
329 case VIDEO_MODE_NTSC:
330 saa7111_write(client, 0x08,
331 (decoder->reg[0x08] & 0x3f) | 0x40);
332 saa7111_write(client, 0x0e,
333 (decoder->reg[0x0e] & 0x8f));
334 break;
335
336 case VIDEO_MODE_PAL:
337 saa7111_write(client, 0x08,
338 (decoder->reg[0x08] & 0x3f) | 0x00);
339 saa7111_write(client, 0x0e,
340 (decoder->reg[0x0e] & 0x8f));
341 break;
342
343 case VIDEO_MODE_SECAM:
344 saa7111_write(client, 0x08,
345 (decoder->reg[0x08] & 0x3f) | 0x00);
346 saa7111_write(client, 0x0e,
347 (decoder->reg[0x0e] & 0x8f) | 0x50);
348 break;
349
350 case VIDEO_MODE_AUTO:
351 saa7111_write(client, 0x08,
352 (decoder->reg[0x08] & 0x3f) | 0x80);
353 saa7111_write(client, 0x0e,
354 (decoder->reg[0x0e] & 0x8f));
355 break;
356
357 default:
358 return -EINVAL;
359
360 }
361 decoder->norm = *iarg;
362 }
363 break;
364
365 case DECODER_SET_INPUT:
366 {
367 int *iarg = arg;
368
369 if (*iarg < 0 || *iarg > 7) {
370 return -EINVAL;
371 }
372
373 if (decoder->input != *iarg) {
374 decoder->input = *iarg;
375 /* select mode */
376 saa7111_write(client, 0x02,
377 (decoder->
378 reg[0x02] & 0xf8) | decoder->input);
379 /* bypass chrominance trap for modes 4..7 */
380 saa7111_write(client, 0x09,
381 (decoder->
382 reg[0x09] & 0x7f) | ((decoder->
383 input >
384 3) ? 0x80 :
385 0));
386 }
387 }
388 break;
389
390 case DECODER_SET_OUTPUT:
391 {
392 int *iarg = arg;
393
394 /* not much choice of outputs */
395 if (*iarg != 0) {
396 return -EINVAL;
397 }
398 }
399 break;
400
401 case DECODER_ENABLE_OUTPUT:
402 {
403 int *iarg = arg;
404 int enable = (*iarg != 0);
405
406 if (decoder->enable != enable) {
407 decoder->enable = enable;
408
409 /* RJ: If output should be disabled (for
410 * playing videos), we also need a open PLL.
411 * The input is set to 0 (where no input
412 * source is connected), although this
413 * is not necessary.
414 *
415 * If output should be enabled, we have to
416 * reverse the above.
417 */
418
419 if (decoder->enable) {
420 saa7111_write(client, 0x02,
421 (decoder->
422 reg[0x02] & 0xf8) |
423 decoder->input);
424 saa7111_write(client, 0x08,
425 (decoder->reg[0x08] & 0xfb));
426 saa7111_write(client, 0x11,
427 (decoder->
428 reg[0x11] & 0xf3) | 0x0c);
429 } else {
430 saa7111_write(client, 0x02,
431 (decoder->reg[0x02] & 0xf8));
432 saa7111_write(client, 0x08,
433 (decoder->
434 reg[0x08] & 0xfb) | 0x04);
435 saa7111_write(client, 0x11,
436 (decoder->reg[0x11] & 0xf3));
437 }
438 }
439 }
440 break;
441
442 case DECODER_SET_PICTURE:
443 {
444 struct video_picture *pic = arg;
445
446 if (decoder->bright != pic->brightness) {
447 /* We want 0 to 255 we get 0-65535 */
448 decoder->bright = pic->brightness;
449 saa7111_write(client, 0x0a, decoder->bright >> 8);
450 }
451 if (decoder->contrast != pic->contrast) {
452 /* We want 0 to 127 we get 0-65535 */
453 decoder->contrast = pic->contrast;
454 saa7111_write(client, 0x0b,
455 decoder->contrast >> 9);
456 }
457 if (decoder->sat != pic->colour) {
458 /* We want 0 to 127 we get 0-65535 */
459 decoder->sat = pic->colour;
460 saa7111_write(client, 0x0c, decoder->sat >> 9);
461 }
462 if (decoder->hue != pic->hue) {
463 /* We want -128 to 127 we get 0-65535 */
464 decoder->hue = pic->hue;
465 saa7111_write(client, 0x0d,
466 (decoder->hue - 32768) >> 8);
467 }
468 }
469 break;
470
471 default:
472 return -EINVAL;
473 }
474
475 return 0;
476}
477
478/* ----------------------------------------------------------------------- */
479
480/*
481 * Generic i2c probe
482 * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
483 */
484static unsigned short normal_i2c[] = { I2C_SAA7111 >> 1, I2C_CLIENT_END };
485static unsigned short normal_i2c_range[] = { I2C_CLIENT_END };
486
487static unsigned short probe[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
488static unsigned short probe_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
489static unsigned short ignore[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
490static unsigned short ignore_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
491static unsigned short force[2] = { I2C_CLIENT_END , I2C_CLIENT_END };
492
493static struct i2c_client_address_data addr_data = {
494 .normal_i2c = normal_i2c,
495 .normal_i2c_range = normal_i2c_range,
496 .probe = probe,
497 .probe_range = probe_range,
498 .ignore = ignore,
499 .ignore_range = ignore_range,
500 .force = force
501};
502
503static struct i2c_driver i2c_driver_saa7111;
504
505static int
506saa7111_detect_client (struct i2c_adapter *adapter,
507 int address,
508 int kind)
509{
510 int i;
511 struct i2c_client *client;
512 struct saa7111 *decoder;
513 struct video_decoder_init vdi;
514
515 dprintk(1,
516 KERN_INFO
517 "saa7111.c: detecting saa7111 client on address 0x%x\n",
518 address << 1);
519
520 /* Check if the adapter supports the needed features */
521 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
522 return 0;
523
524 client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
525 if (client == 0)
526 return -ENOMEM;
527 memset(client, 0, sizeof(struct i2c_client));
528 client->addr = address;
529 client->adapter = adapter;
530 client->driver = &i2c_driver_saa7111;
531 client->flags = I2C_CLIENT_ALLOW_USE;
532 strlcpy(I2C_NAME(client), "saa7111", sizeof(I2C_NAME(client)));
533
534 decoder = kmalloc(sizeof(struct saa7111), GFP_KERNEL);
535 if (decoder == NULL) {
536 kfree(client);
537 return -ENOMEM;
538 }
539 memset(decoder, 0, sizeof(struct saa7111));
540 decoder->norm = VIDEO_MODE_NTSC;
541 decoder->input = 0;
542 decoder->enable = 1;
543 decoder->bright = 32768;
544 decoder->contrast = 32768;
545 decoder->hue = 32768;
546 decoder->sat = 32768;
547 i2c_set_clientdata(client, decoder);
548
549 i = i2c_attach_client(client);
550 if (i) {
551 kfree(client);
552 kfree(decoder);
553 return i;
554 }
555
556 vdi.data = saa7111_i2c_init;
557 vdi.len = sizeof(saa7111_i2c_init);
558 i = saa7111_init_decoder(client, &vdi);
559 if (i < 0) {
560 dprintk(1, KERN_ERR "%s_attach error: init status %d\n",
561 I2C_NAME(client), i);
562 } else {
563 dprintk(1,
564 KERN_INFO
565 "%s_attach: chip version %x at address 0x%x\n",
566 I2C_NAME(client), saa7111_read(client, 0x00) >> 4,
567 client->addr << 1);
568 }
569
570 return 0;
571}
572
573static int
574saa7111_attach_adapter (struct i2c_adapter *adapter)
575{
576 dprintk(1,
577 KERN_INFO
578 "saa7111.c: starting probe for adapter %s (0x%x)\n",
579 I2C_NAME(adapter), adapter->id);
580 return i2c_probe(adapter, &addr_data, &saa7111_detect_client);
581}
582
583static int
584saa7111_detach_client (struct i2c_client *client)
585{
586 struct saa7111 *decoder = i2c_get_clientdata(client);
587 int err;
588
589 err = i2c_detach_client(client);
590 if (err) {
591 return err;
592 }
593
594 kfree(decoder);
595 kfree(client);
596
597 return 0;
598}
599
600/* ----------------------------------------------------------------------- */
601
602static struct i2c_driver i2c_driver_saa7111 = {
603 .owner = THIS_MODULE,
604 .name = "saa7111",
605
606 .id = I2C_DRIVERID_SAA7111A,
607 .flags = I2C_DF_NOTIFY,
608
609 .attach_adapter = saa7111_attach_adapter,
610 .detach_client = saa7111_detach_client,
611 .command = saa7111_command,
612};
613
614static int __init
615saa7111_init (void)
616{
617 return i2c_add_driver(&i2c_driver_saa7111);
618}
619
620static void __exit
621saa7111_exit (void)
622{
623 i2c_del_driver(&i2c_driver_saa7111);
624}
625
626module_init(saa7111_init);
627module_exit(saa7111_exit);
diff --git a/drivers/media/video/saa7114.c b/drivers/media/video/saa7114.c
new file mode 100644
index 00000000000..e73023695e5
--- /dev/null
+++ b/drivers/media/video/saa7114.c
@@ -0,0 +1,1241 @@
1/*
2 * saa7114 - Philips SAA7114H video decoder driver version 0.0.1
3 *
4 * Copyright (C) 2002 Maxim Yevtyushkin <max@linuxmedialabs.com>
5 *
6 * Based on saa7111 driver by Dave Perks
7 *
8 * Copyright (C) 1998 Dave Perks <dperks@ibm.net>
9 *
10 * Slight changes for video timing and attachment output by
11 * Wolfgang Scherr <scherr@net4you.net>
12 *
13 * Changes by Ronald Bultje <rbultje@ronald.bitfreak.net>
14 * - moved over to linux>=2.4.x i2c protocol (1/1/2003)
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 */
30
31#include <linux/module.h>
32#include <linux/init.h>
33#include <linux/delay.h>
34#include <linux/errno.h>
35#include <linux/fs.h>
36#include <linux/kernel.h>
37#include <linux/major.h>
38
39#include <linux/slab.h>
40
41#include <linux/mm.h>
42#include <linux/pci.h>
43#include <linux/signal.h>
44#include <asm/io.h>
45#include <asm/pgtable.h>
46#include <asm/page.h>
47#include <linux/sched.h>
48#include <asm/segment.h>
49#include <linux/types.h>
50
51#include <linux/videodev.h>
52#include <asm/uaccess.h>
53
54MODULE_DESCRIPTION("Philips SAA7114H video decoder driver");
55MODULE_AUTHOR("Maxim Yevtyushkin");
56MODULE_LICENSE("GPL");
57
58#include <linux/i2c.h>
59#include <linux/i2c-dev.h>
60
61#define I2C_NAME(x) (x)->name
62
63#include <linux/video_decoder.h>
64
65static int debug = 0;
66module_param(debug, int, 0);
67MODULE_PARM_DESC(debug, "Debug level (0-1)");
68
69#define dprintk(num, format, args...) \
70 do { \
71 if (debug >= num) \
72 printk(format, ##args); \
73 } while (0)
74
75/* ----------------------------------------------------------------------- */
76
77struct saa7114 {
78 unsigned char reg[0xf0 * 2];
79
80 int norm;
81 int input;
82 int enable;
83 int bright;
84 int contrast;
85 int hue;
86 int sat;
87 int playback;
88};
89
90#define I2C_SAA7114 0x42
91#define I2C_SAA7114A 0x40
92
93#define I2C_DELAY 10
94
95
96//#define SAA_7114_NTSC_HSYNC_START (-3)
97//#define SAA_7114_NTSC_HSYNC_STOP (-18)
98
99#define SAA_7114_NTSC_HSYNC_START (-17)
100#define SAA_7114_NTSC_HSYNC_STOP (-32)
101
102//#define SAA_7114_NTSC_HOFFSET (5)
103#define SAA_7114_NTSC_HOFFSET (6)
104#define SAA_7114_NTSC_VOFFSET (10)
105#define SAA_7114_NTSC_WIDTH (720)
106#define SAA_7114_NTSC_HEIGHT (250)
107
108#define SAA_7114_SECAM_HSYNC_START (-17)
109#define SAA_7114_SECAM_HSYNC_STOP (-32)
110
111#define SAA_7114_SECAM_HOFFSET (2)
112#define SAA_7114_SECAM_VOFFSET (10)
113#define SAA_7114_SECAM_WIDTH (720)
114#define SAA_7114_SECAM_HEIGHT (300)
115
116#define SAA_7114_PAL_HSYNC_START (-17)
117#define SAA_7114_PAL_HSYNC_STOP (-32)
118
119#define SAA_7114_PAL_HOFFSET (2)
120#define SAA_7114_PAL_VOFFSET (10)
121#define SAA_7114_PAL_WIDTH (720)
122#define SAA_7114_PAL_HEIGHT (300)
123
124
125
126#define SAA_7114_VERTICAL_CHROMA_OFFSET 0 //0x50504040
127#define SAA_7114_VERTICAL_LUMA_OFFSET 0
128
129#define REG_ADDR(x) (((x) << 1) + 1)
130#define LOBYTE(x) ((unsigned char)((x) & 0xff))
131#define HIBYTE(x) ((unsigned char)(((x) >> 8) & 0xff))
132#define LOWORD(x) ((unsigned short int)((x) & 0xffff))
133#define HIWORD(x) ((unsigned short int)(((x) >> 16) & 0xffff))
134
135
136/* ----------------------------------------------------------------------- */
137
138static inline int
139saa7114_write (struct i2c_client *client,
140 u8 reg,
141 u8 value)
142{
143 /*struct saa7114 *decoder = i2c_get_clientdata(client);*/
144
145 /*decoder->reg[reg] = value;*/
146 return i2c_smbus_write_byte_data(client, reg, value);
147}
148
149static int
150saa7114_write_block (struct i2c_client *client,
151 const u8 *data,
152 unsigned int len)
153{
154 int ret = -1;
155 u8 reg;
156
157 /* the saa7114 has an autoincrement function, use it if
158 * the adapter understands raw I2C */
159 if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
160 /* do raw I2C, not smbus compatible */
161 /*struct saa7114 *decoder = i2c_get_clientdata(client);*/
162 struct i2c_msg msg;
163 u8 block_data[32];
164
165 msg.addr = client->addr;
166 msg.flags = 0;
167 while (len >= 2) {
168 msg.buf = (char *) block_data;
169 msg.len = 0;
170 block_data[msg.len++] = reg = data[0];
171 do {
172 block_data[msg.len++] =
173 /*decoder->reg[reg++] =*/ data[1];
174 len -= 2;
175 data += 2;
176 } while (len >= 2 && data[0] == reg &&
177 msg.len < 32);
178 if ((ret = i2c_transfer(client->adapter,
179 &msg, 1)) < 0)
180 break;
181 }
182 } else {
183 /* do some slow I2C emulation kind of thing */
184 while (len >= 2) {
185 reg = *data++;
186 if ((ret = saa7114_write(client, reg,
187 *data++)) < 0)
188 break;
189 len -= 2;
190 }
191 }
192
193 return ret;
194}
195
196static inline int
197saa7114_read (struct i2c_client *client,
198 u8 reg)
199{
200 return i2c_smbus_read_byte_data(client, reg);
201}
202
203/* ----------------------------------------------------------------------- */
204
205// initially set NTSC, composite
206
207
208static const unsigned char init[] = {
209 0x00, 0x00, /* 00 - ID byte , chip version,
210 * read only */
211 0x01, 0x08, /* 01 - X,X,X,X, IDEL3 to IDEL0 -
212 * horizontal increment delay,
213 * recommended position */
214 0x02, 0x00, /* 02 - FUSE=3, GUDL=2, MODE=0 ;
215 * input control */
216 0x03, 0x10, /* 03 - HLNRS=0, VBSL=1, WPOFF=0,
217 * HOLDG=0, GAFIX=0, GAI1=256, GAI2=256 */
218 0x04, 0x90, /* 04 - GAI1=256 */
219 0x05, 0x90, /* 05 - GAI2=256 */
220 0x06, SAA_7114_NTSC_HSYNC_START, /* 06 - HSB: hsync start,
221 * depends on the video standard */
222 0x07, SAA_7114_NTSC_HSYNC_STOP, /* 07 - HSS: hsync stop, depends
223 *on the video standard */
224 0x08, 0xb8, /* 08 - AUFD=1, FSEL=1, EXFIL=0, VTRC=1,
225 * HPLL: free running in playback, locked
226 * in capture, VNOI=0 */
227 0x09, 0x80, /* 09 - BYPS=0, PREF=0, BPSS=0, VBLB=0,
228 * UPTCV=0, APER=1; depends from input */
229 0x0a, 0x80, /* 0a - BRIG=128 */
230 0x0b, 0x44, /* 0b - CONT=1.109 */
231 0x0c, 0x40, /* 0c - SATN=1.0 */
232 0x0d, 0x00, /* 0d - HUE=0 */
233 0x0e, 0x84, /* 0e - CDTO, CSTD2 to 0, DCVF, FCTC,
234 * CCOMB; depends from video standard */
235 0x0f, 0x24, /* 0f - ACGC,CGAIN6 to CGAIN0; depends
236 * from video standard */
237 0x10, 0x03, /* 10 - OFFU1 to 0, OFFV1 to 0, CHBW,
238 * LCBW2 to 0 */
239 0x11, 0x59, /* 11 - COLO, RTP1, HEDL1 to 0, RTP0,
240 * YDEL2 to 0 */
241 0x12, 0xc9, /* 12 - RT signal control RTSE13 to 10
242 * and 03 to 00 */
243 0x13, 0x80, /* 13 - RT/X port output control */
244 0x14, 0x00, /* 14 - analog, ADC, compatibility control */
245 0x15, 0x00, /* 15 - VGATE start FID change */
246 0x16, 0xfe, /* 16 - VGATE stop */
247 0x17, 0x00, /* 17 - Misc., VGATE MSBs */
248 0x18, 0x40, /* RAWG */
249 0x19, 0x80, /* RAWO */
250 0x1a, 0x00,
251 0x1b, 0x00,
252 0x1c, 0x00,
253 0x1d, 0x00,
254 0x1e, 0x00,
255 0x1f, 0x00, /* status byte, read only */
256 0x20, 0x00, /* video decoder reserved part */
257 0x21, 0x00,
258 0x22, 0x00,
259 0x23, 0x00,
260 0x24, 0x00,
261 0x25, 0x00,
262 0x26, 0x00,
263 0x27, 0x00,
264 0x28, 0x00,
265 0x29, 0x00,
266 0x2a, 0x00,
267 0x2b, 0x00,
268 0x2c, 0x00,
269 0x2d, 0x00,
270 0x2e, 0x00,
271 0x2f, 0x00,
272 0x30, 0xbc, /* audio clock generator */
273 0x31, 0xdf,
274 0x32, 0x02,
275 0x33, 0x00,
276 0x34, 0xcd,
277 0x35, 0xcc,
278 0x36, 0x3a,
279 0x37, 0x00,
280 0x38, 0x03,
281 0x39, 0x10,
282 0x3a, 0x00,
283 0x3b, 0x00,
284 0x3c, 0x00,
285 0x3d, 0x00,
286 0x3e, 0x00,
287 0x3f, 0x00,
288 0x40, 0x00, /* VBI data slicer */
289 0x41, 0xff,
290 0x42, 0xff,
291 0x43, 0xff,
292 0x44, 0xff,
293 0x45, 0xff,
294 0x46, 0xff,
295 0x47, 0xff,
296 0x48, 0xff,
297 0x49, 0xff,
298 0x4a, 0xff,
299 0x4b, 0xff,
300 0x4c, 0xff,
301 0x4d, 0xff,
302 0x4e, 0xff,
303 0x4f, 0xff,
304 0x50, 0xff,
305 0x51, 0xff,
306 0x52, 0xff,
307 0x53, 0xff,
308 0x54, 0xff,
309 0x55, 0xff,
310 0x56, 0xff,
311 0x57, 0xff,
312 0x58, 0x40, // framing code
313 0x59, 0x47, // horizontal offset
314 0x5a, 0x06, // vertical offset
315 0x5b, 0x83, // field offset
316 0x5c, 0x00, // reserved
317 0x5d, 0x3e, // header and data
318 0x5e, 0x00, // sliced data
319 0x5f, 0x00, // reserved
320 0x60, 0x00, /* video decoder reserved part */
321 0x61, 0x00,
322 0x62, 0x00,
323 0x63, 0x00,
324 0x64, 0x00,
325 0x65, 0x00,
326 0x66, 0x00,
327 0x67, 0x00,
328 0x68, 0x00,
329 0x69, 0x00,
330 0x6a, 0x00,
331 0x6b, 0x00,
332 0x6c, 0x00,
333 0x6d, 0x00,
334 0x6e, 0x00,
335 0x6f, 0x00,
336 0x70, 0x00, /* video decoder reserved part */
337 0x71, 0x00,
338 0x72, 0x00,
339 0x73, 0x00,
340 0x74, 0x00,
341 0x75, 0x00,
342 0x76, 0x00,
343 0x77, 0x00,
344 0x78, 0x00,
345 0x79, 0x00,
346 0x7a, 0x00,
347 0x7b, 0x00,
348 0x7c, 0x00,
349 0x7d, 0x00,
350 0x7e, 0x00,
351 0x7f, 0x00,
352 0x80, 0x00, /* X-port, I-port and scaler */
353 0x81, 0x00,
354 0x82, 0x00,
355 0x83, 0x00,
356 0x84, 0xc5,
357 0x85, 0x0d, // hsync and vsync ?
358 0x86, 0x40,
359 0x87, 0x01,
360 0x88, 0x00,
361 0x89, 0x00,
362 0x8a, 0x00,
363 0x8b, 0x00,
364 0x8c, 0x00,
365 0x8d, 0x00,
366 0x8e, 0x00,
367 0x8f, 0x00,
368 0x90, 0x03, /* Task A definition */
369 0x91, 0x08,
370 0x92, 0x00,
371 0x93, 0x40,
372 0x94, 0x00, // window settings
373 0x95, 0x00,
374 0x96, 0x00,
375 0x97, 0x00,
376 0x98, 0x00,
377 0x99, 0x00,
378 0x9a, 0x00,
379 0x9b, 0x00,
380 0x9c, 0x00,
381 0x9d, 0x00,
382 0x9e, 0x00,
383 0x9f, 0x00,
384 0xa0, 0x01, /* horizontal integer prescaling ratio */
385 0xa1, 0x00, /* horizontal prescaler accumulation
386 * sequence length */
387 0xa2, 0x00, /* UV FIR filter, Y FIR filter, prescaler
388 * DC gain */
389 0xa3, 0x00,
390 0xa4, 0x80, // luminance brightness
391 0xa5, 0x40, // luminance gain
392 0xa6, 0x40, // chrominance saturation
393 0xa7, 0x00,
394 0xa8, 0x00, // horizontal luminance scaling increment
395 0xa9, 0x04,
396 0xaa, 0x00, // horizontal luminance phase offset
397 0xab, 0x00,
398 0xac, 0x00, // horizontal chrominance scaling increment
399 0xad, 0x02,
400 0xae, 0x00, // horizontal chrominance phase offset
401 0xaf, 0x00,
402 0xb0, 0x00, // vertical luminance scaling increment
403 0xb1, 0x04,
404 0xb2, 0x00, // vertical chrominance scaling increment
405 0xb3, 0x04,
406 0xb4, 0x00,
407 0xb5, 0x00,
408 0xb6, 0x00,
409 0xb7, 0x00,
410 0xb8, 0x00,
411 0xb9, 0x00,
412 0xba, 0x00,
413 0xbb, 0x00,
414 0xbc, 0x00,
415 0xbd, 0x00,
416 0xbe, 0x00,
417 0xbf, 0x00,
418 0xc0, 0x02, // Task B definition
419 0xc1, 0x08,
420 0xc2, 0x00,
421 0xc3, 0x40,
422 0xc4, 0x00, // window settings
423 0xc5, 0x00,
424 0xc6, 0x00,
425 0xc7, 0x00,
426 0xc8, 0x00,
427 0xc9, 0x00,
428 0xca, 0x00,
429 0xcb, 0x00,
430 0xcc, 0x00,
431 0xcd, 0x00,
432 0xce, 0x00,
433 0xcf, 0x00,
434 0xd0, 0x01, // horizontal integer prescaling ratio
435 0xd1, 0x00, // horizontal prescaler accumulation sequence length
436 0xd2, 0x00, // UV FIR filter, Y FIR filter, prescaler DC gain
437 0xd3, 0x00,
438 0xd4, 0x80, // luminance brightness
439 0xd5, 0x40, // luminance gain
440 0xd6, 0x40, // chrominance saturation
441 0xd7, 0x00,
442 0xd8, 0x00, // horizontal luminance scaling increment
443 0xd9, 0x04,
444 0xda, 0x00, // horizontal luminance phase offset
445 0xdb, 0x00,
446 0xdc, 0x00, // horizontal chrominance scaling increment
447 0xdd, 0x02,
448 0xde, 0x00, // horizontal chrominance phase offset
449 0xdf, 0x00,
450 0xe0, 0x00, // vertical luminance scaling increment
451 0xe1, 0x04,
452 0xe2, 0x00, // vertical chrominance scaling increment
453 0xe3, 0x04,
454 0xe4, 0x00,
455 0xe5, 0x00,
456 0xe6, 0x00,
457 0xe7, 0x00,
458 0xe8, 0x00,
459 0xe9, 0x00,
460 0xea, 0x00,
461 0xeb, 0x00,
462 0xec, 0x00,
463 0xed, 0x00,
464 0xee, 0x00,
465 0xef, 0x00
466};
467
468static int
469saa7114_command (struct i2c_client *client,
470 unsigned int cmd,
471 void *arg)
472{
473 struct saa7114 *decoder = i2c_get_clientdata(client);
474
475 switch (cmd) {
476
477 case 0:
478 //dprintk(1, KERN_INFO "%s: writing init\n", I2C_NAME(client));
479 //saa7114_write_block(client, init, sizeof(init));
480 break;
481
482 case DECODER_DUMP:
483 {
484 int i;
485
486 dprintk(1, KERN_INFO "%s: decoder dump\n", I2C_NAME(client));
487
488 for (i = 0; i < 32; i += 16) {
489 int j;
490
491 printk(KERN_DEBUG "%s: %03x", I2C_NAME(client), i);
492 for (j = 0; j < 16; ++j) {
493 printk(" %02x",
494 saa7114_read(client, i + j));
495 }
496 printk("\n");
497 }
498 }
499 break;
500
501 case DECODER_GET_CAPABILITIES:
502 {
503 struct video_decoder_capability *cap = arg;
504
505 dprintk(1, KERN_DEBUG "%s: decoder get capabilities\n",
506 I2C_NAME(client));
507
508 cap->flags = VIDEO_DECODER_PAL |
509 VIDEO_DECODER_NTSC |
510 VIDEO_DECODER_AUTO |
511 VIDEO_DECODER_CCIR;
512 cap->inputs = 8;
513 cap->outputs = 1;
514 }
515 break;
516
517 case DECODER_GET_STATUS:
518 {
519 int *iarg = arg;
520 int status;
521 int res;
522
523 status = saa7114_read(client, 0x1f);
524
525 dprintk(1, KERN_DEBUG "%s status: 0x%02x\n", I2C_NAME(client),
526 status);
527 res = 0;
528 if ((status & (1 << 6)) == 0) {
529 res |= DECODER_STATUS_GOOD;
530 }
531 switch (decoder->norm) {
532 case VIDEO_MODE_NTSC:
533 res |= DECODER_STATUS_NTSC;
534 break;
535 case VIDEO_MODE_PAL:
536 res |= DECODER_STATUS_PAL;
537 break;
538 case VIDEO_MODE_SECAM:
539 res |= DECODER_STATUS_SECAM;
540 break;
541 default:
542 case VIDEO_MODE_AUTO:
543 if ((status & (1 << 5)) != 0) {
544 res |= DECODER_STATUS_NTSC;
545 } else {
546 res |= DECODER_STATUS_PAL;
547 }
548 break;
549 }
550 if ((status & (1 << 0)) != 0) {
551 res |= DECODER_STATUS_COLOR;
552 }
553 *iarg = res;
554 }
555 break;
556
557 case DECODER_SET_NORM:
558 {
559 int *iarg = arg;
560
561 short int hoff = 0, voff = 0, w = 0, h = 0;
562
563 dprintk(1, KERN_DEBUG "%s: decoder set norm ",
564 I2C_NAME(client));
565 switch (*iarg) {
566
567 case VIDEO_MODE_NTSC:
568 dprintk(1, "NTSC\n");
569 decoder->reg[REG_ADDR(0x06)] =
570 SAA_7114_NTSC_HSYNC_START;
571 decoder->reg[REG_ADDR(0x07)] =
572 SAA_7114_NTSC_HSYNC_STOP;
573
574 decoder->reg[REG_ADDR(0x08)] = decoder->playback ? 0x7c : 0xb8; // PLL free when playback, PLL close when capture
575
576 decoder->reg[REG_ADDR(0x0e)] = 0x85;
577 decoder->reg[REG_ADDR(0x0f)] = 0x24;
578
579 hoff = SAA_7114_NTSC_HOFFSET;
580 voff = SAA_7114_NTSC_VOFFSET;
581 w = SAA_7114_NTSC_WIDTH;
582 h = SAA_7114_NTSC_HEIGHT;
583
584 break;
585
586 case VIDEO_MODE_PAL:
587 dprintk(1, "PAL\n");
588 decoder->reg[REG_ADDR(0x06)] =
589 SAA_7114_PAL_HSYNC_START;
590 decoder->reg[REG_ADDR(0x07)] =
591 SAA_7114_PAL_HSYNC_STOP;
592
593 decoder->reg[REG_ADDR(0x08)] = decoder->playback ? 0x7c : 0xb8; // PLL free when playback, PLL close when capture
594
595 decoder->reg[REG_ADDR(0x0e)] = 0x81;
596 decoder->reg[REG_ADDR(0x0f)] = 0x24;
597
598 hoff = SAA_7114_PAL_HOFFSET;
599 voff = SAA_7114_PAL_VOFFSET;
600 w = SAA_7114_PAL_WIDTH;
601 h = SAA_7114_PAL_HEIGHT;
602
603 break;
604
605 default:
606 dprintk(1, " Unknown video mode!!!\n");
607 return -EINVAL;
608
609 }
610
611
612 decoder->reg[REG_ADDR(0x94)] = LOBYTE(hoff); // hoffset low
613 decoder->reg[REG_ADDR(0x95)] = HIBYTE(hoff) & 0x0f; // hoffset high
614 decoder->reg[REG_ADDR(0x96)] = LOBYTE(w); // width low
615 decoder->reg[REG_ADDR(0x97)] = HIBYTE(w) & 0x0f; // width high
616 decoder->reg[REG_ADDR(0x98)] = LOBYTE(voff); // voffset low
617 decoder->reg[REG_ADDR(0x99)] = HIBYTE(voff) & 0x0f; // voffset high
618 decoder->reg[REG_ADDR(0x9a)] = LOBYTE(h + 2); // height low
619 decoder->reg[REG_ADDR(0x9b)] = HIBYTE(h + 2) & 0x0f; // height high
620 decoder->reg[REG_ADDR(0x9c)] = LOBYTE(w); // out width low
621 decoder->reg[REG_ADDR(0x9d)] = HIBYTE(w) & 0x0f; // out width high
622 decoder->reg[REG_ADDR(0x9e)] = LOBYTE(h); // out height low
623 decoder->reg[REG_ADDR(0x9f)] = HIBYTE(h) & 0x0f; // out height high
624
625 decoder->reg[REG_ADDR(0xc4)] = LOBYTE(hoff); // hoffset low
626 decoder->reg[REG_ADDR(0xc5)] = HIBYTE(hoff) & 0x0f; // hoffset high
627 decoder->reg[REG_ADDR(0xc6)] = LOBYTE(w); // width low
628 decoder->reg[REG_ADDR(0xc7)] = HIBYTE(w) & 0x0f; // width high
629 decoder->reg[REG_ADDR(0xc8)] = LOBYTE(voff); // voffset low
630 decoder->reg[REG_ADDR(0xc9)] = HIBYTE(voff) & 0x0f; // voffset high
631 decoder->reg[REG_ADDR(0xca)] = LOBYTE(h + 2); // height low
632 decoder->reg[REG_ADDR(0xcb)] = HIBYTE(h + 2) & 0x0f; // height high
633 decoder->reg[REG_ADDR(0xcc)] = LOBYTE(w); // out width low
634 decoder->reg[REG_ADDR(0xcd)] = HIBYTE(w) & 0x0f; // out width high
635 decoder->reg[REG_ADDR(0xce)] = LOBYTE(h); // out height low
636 decoder->reg[REG_ADDR(0xcf)] = HIBYTE(h) & 0x0f; // out height high
637
638
639 saa7114_write(client, 0x80, 0x06); // i-port and scaler back end clock selection, task A&B off
640 saa7114_write(client, 0x88, 0xd8); // sw reset scaler
641 saa7114_write(client, 0x88, 0xf8); // sw reset scaler release
642
643 saa7114_write_block(client, decoder->reg + (0x06 << 1),
644 3 << 1);
645 saa7114_write_block(client, decoder->reg + (0x0e << 1),
646 2 << 1);
647 saa7114_write_block(client, decoder->reg + (0x5a << 1),
648 2 << 1);
649
650 saa7114_write_block(client, decoder->reg + (0x94 << 1),
651 (0x9f + 1 - 0x94) << 1);
652 saa7114_write_block(client, decoder->reg + (0xc4 << 1),
653 (0xcf + 1 - 0xc4) << 1);
654
655 saa7114_write(client, 0x88, 0xd8); // sw reset scaler
656 saa7114_write(client, 0x88, 0xf8); // sw reset scaler release
657 saa7114_write(client, 0x80, 0x36); // i-port and scaler back end clock selection
658
659 decoder->norm = *iarg;
660 }
661 break;
662
663 case DECODER_SET_INPUT:
664 {
665 int *iarg = arg;
666
667 dprintk(1, KERN_DEBUG "%s: decoder set input (%d)\n",
668 I2C_NAME(client), *iarg);
669 if (*iarg < 0 || *iarg > 7) {
670 return -EINVAL;
671 }
672
673 if (decoder->input != *iarg) {
674 dprintk(1, KERN_DEBUG "%s: now setting %s input\n",
675 I2C_NAME(client),
676 *iarg >= 6 ? "S-Video" : "Composite");
677 decoder->input = *iarg;
678
679 /* select mode */
680 decoder->reg[REG_ADDR(0x02)] =
681 (decoder->
682 reg[REG_ADDR(0x02)] & 0xf0) | (decoder->
683 input <
684 6 ? 0x0 : 0x9);
685 saa7114_write(client, 0x02,
686 decoder->reg[REG_ADDR(0x02)]);
687
688 /* bypass chrominance trap for modes 6..9 */
689 decoder->reg[REG_ADDR(0x09)] =
690 (decoder->
691 reg[REG_ADDR(0x09)] & 0x7f) | (decoder->
692 input <
693 6 ? 0x0 :
694 0x80);
695 saa7114_write(client, 0x09,
696 decoder->reg[REG_ADDR(0x09)]);
697
698 decoder->reg[REG_ADDR(0x0e)] =
699 decoder->input <
700 6 ? decoder->
701 reg[REG_ADDR(0x0e)] | 1 : decoder->
702 reg[REG_ADDR(0x0e)] & ~1;
703 saa7114_write(client, 0x0e,
704 decoder->reg[REG_ADDR(0x0e)]);
705 }
706 }
707 break;
708
709 case DECODER_SET_OUTPUT:
710 {
711 int *iarg = arg;
712
713 dprintk(1, KERN_DEBUG "%s: decoder set output\n",
714 I2C_NAME(client));
715
716 /* not much choice of outputs */
717 if (*iarg != 0) {
718 return -EINVAL;
719 }
720 }
721 break;
722
723 case DECODER_ENABLE_OUTPUT:
724 {
725 int *iarg = arg;
726 int enable = (*iarg != 0);
727
728 dprintk(1, KERN_DEBUG "%s: decoder %s output\n",
729 I2C_NAME(client), enable ? "enable" : "disable");
730
731 decoder->playback = !enable;
732
733 if (decoder->enable != enable) {
734 decoder->enable = enable;
735
736 /* RJ: If output should be disabled (for
737 * playing videos), we also need a open PLL.
738 * The input is set to 0 (where no input
739 * source is connected), although this
740 * is not necessary.
741 *
742 * If output should be enabled, we have to
743 * reverse the above.
744 */
745
746 if (decoder->enable) {
747 decoder->reg[REG_ADDR(0x08)] = 0xb8;
748 decoder->reg[REG_ADDR(0x12)] = 0xc9;
749 decoder->reg[REG_ADDR(0x13)] = 0x80;
750 decoder->reg[REG_ADDR(0x87)] = 0x01;
751 } else {
752 decoder->reg[REG_ADDR(0x08)] = 0x7c;
753 decoder->reg[REG_ADDR(0x12)] = 0x00;
754 decoder->reg[REG_ADDR(0x13)] = 0x00;
755 decoder->reg[REG_ADDR(0x87)] = 0x00;
756 }
757
758 saa7114_write_block(client,
759 decoder->reg + (0x12 << 1),
760 2 << 1);
761 saa7114_write(client, 0x08,
762 decoder->reg[REG_ADDR(0x08)]);
763 saa7114_write(client, 0x87,
764 decoder->reg[REG_ADDR(0x87)]);
765 saa7114_write(client, 0x88, 0xd8); // sw reset scaler
766 saa7114_write(client, 0x88, 0xf8); // sw reset scaler release
767 saa7114_write(client, 0x80, 0x36);
768
769 }
770 }
771 break;
772
773 case DECODER_SET_PICTURE:
774 {
775 struct video_picture *pic = arg;
776
777 dprintk(1,
778 KERN_DEBUG
779 "%s: decoder set picture bright=%d contrast=%d saturation=%d hue=%d\n",
780 I2C_NAME(client), pic->brightness, pic->contrast,
781 pic->colour, pic->hue);
782
783 if (decoder->bright != pic->brightness) {
784 /* We want 0 to 255 we get 0-65535 */
785 decoder->bright = pic->brightness;
786 saa7114_write(client, 0x0a, decoder->bright >> 8);
787 }
788 if (decoder->contrast != pic->contrast) {
789 /* We want 0 to 127 we get 0-65535 */
790 decoder->contrast = pic->contrast;
791 saa7114_write(client, 0x0b,
792 decoder->contrast >> 9);
793 }
794 if (decoder->sat != pic->colour) {
795 /* We want 0 to 127 we get 0-65535 */
796 decoder->sat = pic->colour;
797 saa7114_write(client, 0x0c, decoder->sat >> 9);
798 }
799 if (decoder->hue != pic->hue) {
800 /* We want -128 to 127 we get 0-65535 */
801 decoder->hue = pic->hue;
802 saa7114_write(client, 0x0d,
803 (decoder->hue - 32768) >> 8);
804 }
805 }
806 break;
807
808 default:
809 return -EINVAL;
810 }
811
812 return 0;
813}
814
815/* ----------------------------------------------------------------------- */
816
817/*
818 * Generic i2c probe
819 * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
820 */
821static unsigned short normal_i2c[] =
822 { I2C_SAA7114 >> 1, I2C_SAA7114A >> 1, I2C_CLIENT_END };
823static unsigned short normal_i2c_range[] = { I2C_CLIENT_END };
824
825static unsigned short probe[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
826static unsigned short probe_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
827static unsigned short ignore[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
828static unsigned short ignore_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
829static unsigned short force[2] = { I2C_CLIENT_END , I2C_CLIENT_END };
830
831static struct i2c_client_address_data addr_data = {
832 .normal_i2c = normal_i2c,
833 .normal_i2c_range = normal_i2c_range,
834 .probe = probe,
835 .probe_range = probe_range,
836 .ignore = ignore,
837 .ignore_range = ignore_range,
838 .force = force
839};
840
841static struct i2c_driver i2c_driver_saa7114;
842
843static int
844saa7114_detect_client (struct i2c_adapter *adapter,
845 int address,
846 int kind)
847{
848 int i, err[30];
849 short int hoff = SAA_7114_NTSC_HOFFSET;
850 short int voff = SAA_7114_NTSC_VOFFSET;
851 short int w = SAA_7114_NTSC_WIDTH;
852 short int h = SAA_7114_NTSC_HEIGHT;
853 struct i2c_client *client;
854 struct saa7114 *decoder;
855
856 dprintk(1,
857 KERN_INFO
858 "saa7114.c: detecting saa7114 client on address 0x%x\n",
859 address << 1);
860
861 /* Check if the adapter supports the needed features */
862 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
863 return 0;
864
865 client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
866 if (client == 0)
867 return -ENOMEM;
868 memset(client, 0, sizeof(struct i2c_client));
869 client->addr = address;
870 client->adapter = adapter;
871 client->driver = &i2c_driver_saa7114;
872 client->flags = I2C_CLIENT_ALLOW_USE;
873 strlcpy(I2C_NAME(client), "saa7114", sizeof(I2C_NAME(client)));
874
875 decoder = kmalloc(sizeof(struct saa7114), GFP_KERNEL);
876 if (decoder == NULL) {
877 kfree(client);
878 return -ENOMEM;
879 }
880 memset(decoder, 0, sizeof(struct saa7114));
881 decoder->norm = VIDEO_MODE_NTSC;
882 decoder->input = -1;
883 decoder->enable = 1;
884 decoder->bright = 32768;
885 decoder->contrast = 32768;
886 decoder->hue = 32768;
887 decoder->sat = 32768;
888 decoder->playback = 0; // initially capture mode useda
889 i2c_set_clientdata(client, decoder);
890
891 memcpy(decoder->reg, init, sizeof(init));
892
893 decoder->reg[REG_ADDR(0x94)] = LOBYTE(hoff); // hoffset low
894 decoder->reg[REG_ADDR(0x95)] = HIBYTE(hoff) & 0x0f; // hoffset high
895 decoder->reg[REG_ADDR(0x96)] = LOBYTE(w); // width low
896 decoder->reg[REG_ADDR(0x97)] = HIBYTE(w) & 0x0f; // width high
897 decoder->reg[REG_ADDR(0x98)] = LOBYTE(voff); // voffset low
898 decoder->reg[REG_ADDR(0x99)] = HIBYTE(voff) & 0x0f; // voffset high
899 decoder->reg[REG_ADDR(0x9a)] = LOBYTE(h + 2); // height low
900 decoder->reg[REG_ADDR(0x9b)] = HIBYTE(h + 2) & 0x0f; // height high
901 decoder->reg[REG_ADDR(0x9c)] = LOBYTE(w); // out width low
902 decoder->reg[REG_ADDR(0x9d)] = HIBYTE(w) & 0x0f; // out width high
903 decoder->reg[REG_ADDR(0x9e)] = LOBYTE(h); // out height low
904 decoder->reg[REG_ADDR(0x9f)] = HIBYTE(h) & 0x0f; // out height high
905
906 decoder->reg[REG_ADDR(0xc4)] = LOBYTE(hoff); // hoffset low
907 decoder->reg[REG_ADDR(0xc5)] = HIBYTE(hoff) & 0x0f; // hoffset high
908 decoder->reg[REG_ADDR(0xc6)] = LOBYTE(w); // width low
909 decoder->reg[REG_ADDR(0xc7)] = HIBYTE(w) & 0x0f; // width high
910 decoder->reg[REG_ADDR(0xc8)] = LOBYTE(voff); // voffset low
911 decoder->reg[REG_ADDR(0xc9)] = HIBYTE(voff) & 0x0f; // voffset high
912 decoder->reg[REG_ADDR(0xca)] = LOBYTE(h + 2); // height low
913 decoder->reg[REG_ADDR(0xcb)] = HIBYTE(h + 2) & 0x0f; // height high
914 decoder->reg[REG_ADDR(0xcc)] = LOBYTE(w); // out width low
915 decoder->reg[REG_ADDR(0xcd)] = HIBYTE(w) & 0x0f; // out width high
916 decoder->reg[REG_ADDR(0xce)] = LOBYTE(h); // out height low
917 decoder->reg[REG_ADDR(0xcf)] = HIBYTE(h) & 0x0f; // out height high
918
919 decoder->reg[REG_ADDR(0xb8)] =
920 LOBYTE(LOWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
921 decoder->reg[REG_ADDR(0xb9)] =
922 HIBYTE(LOWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
923 decoder->reg[REG_ADDR(0xba)] =
924 LOBYTE(HIWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
925 decoder->reg[REG_ADDR(0xbb)] =
926 HIBYTE(HIWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
927
928 decoder->reg[REG_ADDR(0xbc)] =
929 LOBYTE(LOWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
930 decoder->reg[REG_ADDR(0xbd)] =
931 HIBYTE(LOWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
932 decoder->reg[REG_ADDR(0xbe)] =
933 LOBYTE(HIWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
934 decoder->reg[REG_ADDR(0xbf)] =
935 HIBYTE(HIWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
936
937 decoder->reg[REG_ADDR(0xe8)] =
938 LOBYTE(LOWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
939 decoder->reg[REG_ADDR(0xe9)] =
940 HIBYTE(LOWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
941 decoder->reg[REG_ADDR(0xea)] =
942 LOBYTE(HIWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
943 decoder->reg[REG_ADDR(0xeb)] =
944 HIBYTE(HIWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
945
946 decoder->reg[REG_ADDR(0xec)] =
947 LOBYTE(LOWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
948 decoder->reg[REG_ADDR(0xed)] =
949 HIBYTE(LOWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
950 decoder->reg[REG_ADDR(0xee)] =
951 LOBYTE(HIWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
952 decoder->reg[REG_ADDR(0xef)] =
953 HIBYTE(HIWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
954
955
956 decoder->reg[REG_ADDR(0x13)] = 0x80; // RTC0 on
957 decoder->reg[REG_ADDR(0x87)] = 0x01; // I-Port
958 decoder->reg[REG_ADDR(0x12)] = 0xc9; // RTS0
959
960 decoder->reg[REG_ADDR(0x02)] = 0xc0; // set composite1 input, aveasy
961 decoder->reg[REG_ADDR(0x09)] = 0x00; // chrominance trap
962 decoder->reg[REG_ADDR(0x0e)] |= 1; // combfilter on
963
964
965 dprintk(1, KERN_DEBUG "%s_attach: starting decoder init\n",
966 I2C_NAME(client));
967
968 err[0] =
969 saa7114_write_block(client, decoder->reg + (0x20 << 1),
970 0x10 << 1);
971 err[1] =
972 saa7114_write_block(client, decoder->reg + (0x30 << 1),
973 0x10 << 1);
974 err[2] =
975 saa7114_write_block(client, decoder->reg + (0x63 << 1),
976 (0x7f + 1 - 0x63) << 1);
977 err[3] =
978 saa7114_write_block(client, decoder->reg + (0x89 << 1),
979 6 << 1);
980 err[4] =
981 saa7114_write_block(client, decoder->reg + (0xb8 << 1),
982 8 << 1);
983 err[5] =
984 saa7114_write_block(client, decoder->reg + (0xe8 << 1),
985 8 << 1);
986
987
988 for (i = 0; i <= 5; i++) {
989 if (err[i] < 0) {
990 dprintk(1,
991 KERN_ERR
992 "%s_attach: init error %d at stage %d, leaving attach.\n",
993 I2C_NAME(client), i, err[i]);
994 kfree(decoder);
995 kfree(client);
996 return 0;
997 }
998 }
999
1000 for (i = 6; i < 8; i++) {
1001 dprintk(1,
1002 KERN_DEBUG
1003 "%s_attach: reg[0x%02x] = 0x%02x (0x%02x)\n",
1004 I2C_NAME(client), i, saa7114_read(client, i),
1005 decoder->reg[REG_ADDR(i)]);
1006 }
1007
1008 dprintk(1,
1009 KERN_DEBUG
1010 "%s_attach: performing decoder reset sequence\n",
1011 I2C_NAME(client));
1012
1013 err[6] = saa7114_write(client, 0x80, 0x06); // i-port and scaler backend clock selection, task A&B off
1014 err[7] = saa7114_write(client, 0x88, 0xd8); // sw reset scaler
1015 err[8] = saa7114_write(client, 0x88, 0xf8); // sw reset scaler release
1016
1017 for (i = 6; i <= 8; i++) {
1018 if (err[i] < 0) {
1019 dprintk(1,
1020 KERN_ERR
1021 "%s_attach: init error %d at stage %d, leaving attach.\n",
1022 I2C_NAME(client), i, err[i]);
1023 kfree(decoder);
1024 kfree(client);
1025 return 0;
1026 }
1027 }
1028
1029 dprintk(1, KERN_INFO "%s_attach: performing the rest of init\n",
1030 I2C_NAME(client));
1031
1032
1033 err[9] = saa7114_write(client, 0x01, decoder->reg[REG_ADDR(0x01)]);
1034 err[10] = saa7114_write_block(client, decoder->reg + (0x03 << 1), (0x1e + 1 - 0x03) << 1); // big seq
1035 err[11] = saa7114_write_block(client, decoder->reg + (0x40 << 1), (0x5f + 1 - 0x40) << 1); // slicer
1036 err[12] = saa7114_write_block(client, decoder->reg + (0x81 << 1), 2 << 1); // ?
1037 err[13] = saa7114_write_block(client, decoder->reg + (0x83 << 1), 5 << 1); // ?
1038 err[14] = saa7114_write_block(client, decoder->reg + (0x90 << 1), 4 << 1); // Task A
1039 err[15] =
1040 saa7114_write_block(client, decoder->reg + (0x94 << 1),
1041 12 << 1);
1042 err[16] =
1043 saa7114_write_block(client, decoder->reg + (0xa0 << 1),
1044 8 << 1);
1045 err[17] =
1046 saa7114_write_block(client, decoder->reg + (0xa8 << 1),
1047 8 << 1);
1048 err[18] =
1049 saa7114_write_block(client, decoder->reg + (0xb0 << 1),
1050 8 << 1);
1051 err[19] = saa7114_write_block(client, decoder->reg + (0xc0 << 1), 4 << 1); // Task B
1052 err[15] =
1053 saa7114_write_block(client, decoder->reg + (0xc4 << 1),
1054 12 << 1);
1055 err[16] =
1056 saa7114_write_block(client, decoder->reg + (0xd0 << 1),
1057 8 << 1);
1058 err[17] =
1059 saa7114_write_block(client, decoder->reg + (0xd8 << 1),
1060 8 << 1);
1061 err[18] =
1062 saa7114_write_block(client, decoder->reg + (0xe0 << 1),
1063 8 << 1);
1064
1065 for (i = 9; i <= 18; i++) {
1066 if (err[i] < 0) {
1067 dprintk(1,
1068 KERN_ERR
1069 "%s_attach: init error %d at stage %d, leaving attach.\n",
1070 I2C_NAME(client), i, err[i]);
1071 kfree(decoder);
1072 kfree(client);
1073 return 0;
1074 }
1075 }
1076
1077
1078 for (i = 6; i < 8; i++) {
1079 dprintk(1,
1080 KERN_DEBUG
1081 "%s_attach: reg[0x%02x] = 0x%02x (0x%02x)\n",
1082 I2C_NAME(client), i, saa7114_read(client, i),
1083 decoder->reg[REG_ADDR(i)]);
1084 }
1085
1086
1087 for (i = 0x11; i <= 0x13; i++) {
1088 dprintk(1,
1089 KERN_DEBUG
1090 "%s_attach: reg[0x%02x] = 0x%02x (0x%02x)\n",
1091 I2C_NAME(client), i, saa7114_read(client, i),
1092 decoder->reg[REG_ADDR(i)]);
1093 }
1094
1095
1096 dprintk(1, KERN_DEBUG "%s_attach: setting video input\n",
1097 I2C_NAME(client));
1098
1099 err[19] =
1100 saa7114_write(client, 0x02, decoder->reg[REG_ADDR(0x02)]);
1101 err[20] =
1102 saa7114_write(client, 0x09, decoder->reg[REG_ADDR(0x09)]);
1103 err[21] =
1104 saa7114_write(client, 0x0e, decoder->reg[REG_ADDR(0x0e)]);
1105
1106 for (i = 19; i <= 21; i++) {
1107 if (err[i] < 0) {
1108 dprintk(1,
1109 KERN_ERR
1110 "%s_attach: init error %d at stage %d, leaving attach.\n",
1111 I2C_NAME(client), i, err[i]);
1112 kfree(decoder);
1113 kfree(client);
1114 return 0;
1115 }
1116 }
1117
1118 dprintk(1,
1119 KERN_DEBUG
1120 "%s_attach: performing decoder reset sequence\n",
1121 I2C_NAME(client));
1122
1123 err[22] = saa7114_write(client, 0x88, 0xd8); // sw reset scaler
1124 err[23] = saa7114_write(client, 0x88, 0xf8); // sw reset scaler release
1125 err[24] = saa7114_write(client, 0x80, 0x36); // i-port and scaler backend clock selection, task A&B off
1126
1127
1128 for (i = 22; i <= 24; i++) {
1129 if (err[i] < 0) {
1130 dprintk(1,
1131 KERN_ERR
1132 "%s_attach: init error %d at stage %d, leaving attach.\n",
1133 I2C_NAME(client), i, err[i]);
1134 kfree(decoder);
1135 kfree(client);
1136 return 0;
1137 }
1138 }
1139
1140 err[25] = saa7114_write(client, 0x06, init[REG_ADDR(0x06)]);
1141 err[26] = saa7114_write(client, 0x07, init[REG_ADDR(0x07)]);
1142 err[27] = saa7114_write(client, 0x10, init[REG_ADDR(0x10)]);
1143
1144 dprintk(1,
1145 KERN_INFO
1146 "%s_attach: chip version %x, decoder status 0x%02x\n",
1147 I2C_NAME(client), saa7114_read(client, 0x00) >> 4,
1148 saa7114_read(client, 0x1f));
1149 dprintk(1,
1150 KERN_DEBUG
1151 "%s_attach: power save control: 0x%02x, scaler status: 0x%02x\n",
1152 I2C_NAME(client), saa7114_read(client, 0x88),
1153 saa7114_read(client, 0x8f));
1154
1155
1156 for (i = 0x94; i < 0x96; i++) {
1157 dprintk(1,
1158 KERN_DEBUG
1159 "%s_attach: reg[0x%02x] = 0x%02x (0x%02x)\n",
1160 I2C_NAME(client), i, saa7114_read(client, i),
1161 decoder->reg[REG_ADDR(i)]);
1162 }
1163
1164 i = i2c_attach_client(client);
1165 if (i) {
1166 kfree(client);
1167 kfree(decoder);
1168 return i;
1169 }
1170
1171 //i = saa7114_write_block(client, init, sizeof(init));
1172 i = 0;
1173 if (i < 0) {
1174 dprintk(1, KERN_ERR "%s_attach error: init status %d\n",
1175 I2C_NAME(client), i);
1176 } else {
1177 dprintk(1,
1178 KERN_INFO
1179 "%s_attach: chip version %x at address 0x%x\n",
1180 I2C_NAME(client), saa7114_read(client, 0x00) >> 4,
1181 client->addr << 1);
1182 }
1183
1184 return 0;
1185}
1186
1187static int
1188saa7114_attach_adapter (struct i2c_adapter *adapter)
1189{
1190 dprintk(1,
1191 KERN_INFO
1192 "saa7114.c: starting probe for adapter %s (0x%x)\n",
1193 I2C_NAME(adapter), adapter->id);
1194 return i2c_probe(adapter, &addr_data, &saa7114_detect_client);
1195}
1196
1197static int
1198saa7114_detach_client (struct i2c_client *client)
1199{
1200 struct saa7114 *decoder = i2c_get_clientdata(client);
1201 int err;
1202
1203 err = i2c_detach_client(client);
1204 if (err) {
1205 return err;
1206 }
1207
1208 kfree(decoder);
1209 kfree(client);
1210
1211 return 0;
1212}
1213
1214/* ----------------------------------------------------------------------- */
1215
1216static struct i2c_driver i2c_driver_saa7114 = {
1217 .owner = THIS_MODULE,
1218 .name = "saa7114",
1219
1220 .id = I2C_DRIVERID_SAA7114,
1221 .flags = I2C_DF_NOTIFY,
1222
1223 .attach_adapter = saa7114_attach_adapter,
1224 .detach_client = saa7114_detach_client,
1225 .command = saa7114_command,
1226};
1227
1228static int __init
1229saa7114_init (void)
1230{
1231 return i2c_add_driver(&i2c_driver_saa7114);
1232}
1233
1234static void __exit
1235saa7114_exit (void)
1236{
1237 i2c_del_driver(&i2c_driver_saa7114);
1238}
1239
1240module_init(saa7114_init);
1241module_exit(saa7114_exit);
diff --git a/drivers/media/video/saa7121.h b/drivers/media/video/saa7121.h
new file mode 100644
index 00000000000..74e37d40520
--- /dev/null
+++ b/drivers/media/video/saa7121.h
@@ -0,0 +1,132 @@
1/* saa7121.h - saa7121 initializations
2 Copyright (C) 1999 Nathan Laredo (laredo@gnu.org)
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 */
19#ifndef __SAA7121_H__
20#define __SAA7121_H__
21
22#define NTSC_BURST_START 0x19 /* 28 */
23#define NTSC_BURST_END 0x1d /* 29 */
24#define NTSC_CHROMA_PHASE 0x67 /* 5a */
25#define NTSC_GAINU 0x76 /* 5b */
26#define NTSC_GAINV 0xa5 /* 5c */
27#define NTSC_BLACK_LEVEL 0x2a /* 5d */
28#define NTSC_BLANKING_LEVEL 0x2e /* 5e */
29#define NTSC_VBI_BLANKING 0x2e /* 5f */
30#define NTSC_DAC_CONTROL 0x11 /* 61 */
31#define NTSC_BURST_AMP 0x3f /* 62 */
32#define NTSC_SUBC3 0x1f /* 63 */
33#define NTSC_SUBC2 0x7c /* 64 */
34#define NTSC_SUBC1 0xf0 /* 65 */
35#define NTSC_SUBC0 0x21 /* 66 */
36#define NTSC_HTRIG 0x72 /* 6c */
37#define NTSC_VTRIG 0x00 /* 6c */
38#define NTSC_MULTI 0x30 /* 6e */
39#define NTSC_CCTTX 0x11 /* 6f */
40#define NTSC_FIRST_ACTIVE 0x12 /* 7a */
41#define NTSC_LAST_ACTIVE 0x02 /* 7b */
42#define NTSC_MSB_VERTICAL 0x40 /* 7c */
43
44#define PAL_BURST_START 0x21 /* 28 */
45#define PAL_BURST_END 0x1d /* 29 */
46#define PAL_CHROMA_PHASE 0x3f /* 5a */
47#define PAL_GAINU 0x7d /* 5b */
48#define PAL_GAINV 0xaf /* 5c */
49#define PAL_BLACK_LEVEL 0x23 /* 5d */
50#define PAL_BLANKING_LEVEL 0x35 /* 5e */
51#define PAL_VBI_BLANKING 0x35 /* 5f */
52#define PAL_DAC_CONTROL 0x02 /* 61 */
53#define PAL_BURST_AMP 0x2f /* 62 */
54#define PAL_SUBC3 0xcb /* 63 */
55#define PAL_SUBC2 0x8a /* 64 */
56#define PAL_SUBC1 0x09 /* 65 */
57#define PAL_SUBC0 0x2a /* 66 */
58#define PAL_HTRIG 0x86 /* 6c */
59#define PAL_VTRIG 0x04 /* 6d */
60#define PAL_MULTI 0x20 /* 6e */
61#define PAL_CCTTX 0x15 /* 6f */
62#define PAL_FIRST_ACTIVE 0x16 /* 7a */
63#define PAL_LAST_ACTIVE 0x36 /* 7b */
64#define PAL_MSB_VERTICAL 0x40 /* 7c */
65
66/* Initialization Sequence */
67
68static __u8 init7121ntsc[] = {
69 0x26, 0x0, 0x27, 0x0,
70 0x28, NTSC_BURST_START, 0x29, NTSC_BURST_END,
71 0x2a, 0x0, 0x2b, 0x0, 0x2c, 0x0, 0x2d, 0x0,
72 0x2e, 0x0, 0x2f, 0x0, 0x30, 0x0, 0x31, 0x0,
73 0x32, 0x0, 0x33, 0x0, 0x34, 0x0, 0x35, 0x0,
74 0x36, 0x0, 0x37, 0x0, 0x38, 0x0, 0x39, 0x0,
75 0x3a, 0x03, 0x3b, 0x0, 0x3c, 0x0, 0x3d, 0x0,
76 0x3e, 0x0, 0x3f, 0x0, 0x40, 0x0, 0x41, 0x0,
77 0x42, 0x0, 0x43, 0x0, 0x44, 0x0, 0x45, 0x0,
78 0x46, 0x0, 0x47, 0x0, 0x48, 0x0, 0x49, 0x0,
79 0x4a, 0x0, 0x4b, 0x0, 0x4c, 0x0, 0x4d, 0x0,
80 0x4e, 0x0, 0x4f, 0x0, 0x50, 0x0, 0x51, 0x0,
81 0x52, 0x0, 0x53, 0x0, 0x54, 0x0, 0x55, 0x0,
82 0x56, 0x0, 0x57, 0x0, 0x58, 0x0, 0x59, 0x0,
83 0x5a, NTSC_CHROMA_PHASE, 0x5b, NTSC_GAINU,
84 0x5c, NTSC_GAINV, 0x5d, NTSC_BLACK_LEVEL,
85 0x5e, NTSC_BLANKING_LEVEL, 0x5f, NTSC_VBI_BLANKING,
86 0x60, 0x0, 0x61, NTSC_DAC_CONTROL,
87 0x62, NTSC_BURST_AMP, 0x63, NTSC_SUBC3,
88 0x64, NTSC_SUBC2, 0x65, NTSC_SUBC1,
89 0x66, NTSC_SUBC0, 0x67, 0x80, 0x68, 0x80,
90 0x69, 0x80, 0x6a, 0x80, 0x6b, 0x29,
91 0x6c, NTSC_HTRIG, 0x6d, NTSC_VTRIG,
92 0x6e, NTSC_MULTI, 0x6f, NTSC_CCTTX,
93 0x70, 0xc9, 0x71, 0x68, 0x72, 0x60, 0x73, 0x0,
94 0x74, 0x0, 0x75, 0x0, 0x76, 0x0, 0x77, 0x0,
95 0x78, 0x0, 0x79, 0x0, 0x7a, NTSC_FIRST_ACTIVE,
96 0x7b, NTSC_LAST_ACTIVE, 0x7c, NTSC_MSB_VERTICAL,
97 0x7d, 0x0, 0x7e, 0x0, 0x7f, 0x0
98};
99#define INIT7121LEN (sizeof(init7121ntsc)/2)
100
101static __u8 init7121pal[] = {
102 0x26, 0x0, 0x27, 0x0,
103 0x28, PAL_BURST_START, 0x29, PAL_BURST_END,
104 0x2a, 0x0, 0x2b, 0x0, 0x2c, 0x0, 0x2d, 0x0,
105 0x2e, 0x0, 0x2f, 0x0, 0x30, 0x0, 0x31, 0x0,
106 0x32, 0x0, 0x33, 0x0, 0x34, 0x0, 0x35, 0x0,
107 0x36, 0x0, 0x37, 0x0, 0x38, 0x0, 0x39, 0x0,
108 0x3a, 0x03, 0x3b, 0x0, 0x3c, 0x0, 0x3d, 0x0,
109 0x3e, 0x0, 0x3f, 0x0, 0x40, 0x0, 0x41, 0x0,
110 0x42, 0x0, 0x43, 0x0, 0x44, 0x0, 0x45, 0x0,
111 0x46, 0x0, 0x47, 0x0, 0x48, 0x0, 0x49, 0x0,
112 0x4a, 0x0, 0x4b, 0x0, 0x4c, 0x0, 0x4d, 0x0,
113 0x4e, 0x0, 0x4f, 0x0, 0x50, 0x0, 0x51, 0x0,
114 0x52, 0x0, 0x53, 0x0, 0x54, 0x0, 0x55, 0x0,
115 0x56, 0x0, 0x57, 0x0, 0x58, 0x0, 0x59, 0x0,
116 0x5a, PAL_CHROMA_PHASE, 0x5b, PAL_GAINU,
117 0x5c, PAL_GAINV, 0x5d, PAL_BLACK_LEVEL,
118 0x5e, PAL_BLANKING_LEVEL, 0x5f, PAL_VBI_BLANKING,
119 0x60, 0x0, 0x61, PAL_DAC_CONTROL,
120 0x62, PAL_BURST_AMP, 0x63, PAL_SUBC3,
121 0x64, PAL_SUBC2, 0x65, PAL_SUBC1,
122 0x66, PAL_SUBC0, 0x67, 0x80, 0x68, 0x80,
123 0x69, 0x80, 0x6a, 0x80, 0x6b, 0x29,
124 0x6c, PAL_HTRIG, 0x6d, PAL_VTRIG,
125 0x6e, PAL_MULTI, 0x6f, PAL_CCTTX,
126 0x70, 0xc9, 0x71, 0x68, 0x72, 0x60, 0x73, 0x0,
127 0x74, 0x0, 0x75, 0x0, 0x76, 0x0, 0x77, 0x0,
128 0x78, 0x0, 0x79, 0x0, 0x7a, PAL_FIRST_ACTIVE,
129 0x7b, PAL_LAST_ACTIVE, 0x7c, PAL_MSB_VERTICAL,
130 0x7d, 0x0, 0x7e, 0x0, 0x7f, 0x0
131};
132#endif
diff --git a/drivers/media/video/saa7134/Makefile b/drivers/media/video/saa7134/Makefile
new file mode 100644
index 00000000000..e577a06b136
--- /dev/null
+++ b/drivers/media/video/saa7134/Makefile
@@ -0,0 +1,11 @@
1
2saa7134-objs := saa7134-cards.o saa7134-core.o saa7134-i2c.o \
3 saa7134-oss.o saa7134-ts.o saa7134-tvaudio.o \
4 saa7134-vbi.o saa7134-video.o saa7134-input.o
5
6obj-$(CONFIG_VIDEO_SAA7134) += saa7134.o saa7134-empress.o saa6752hs.o
7obj-$(CONFIG_VIDEO_SAA7134_DVB) += saa7134-dvb.o
8
9EXTRA_CFLAGS += -I$(src)/..
10EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core
11EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/frontends
diff --git a/drivers/media/video/saa7134/saa6752hs.c b/drivers/media/video/saa7134/saa6752hs.c
new file mode 100644
index 00000000000..cee13584c9c
--- /dev/null
+++ b/drivers/media/video/saa7134/saa6752hs.c
@@ -0,0 +1,543 @@
1#include <linux/module.h>
2#include <linux/kernel.h>
3#include <linux/sched.h>
4#include <linux/string.h>
5#include <linux/timer.h>
6#include <linux/delay.h>
7#include <linux/errno.h>
8#include <linux/slab.h>
9#include <linux/poll.h>
10#include <linux/i2c.h>
11#include <linux/types.h>
12#include <linux/videodev.h>
13#include <linux/init.h>
14#include <linux/crc32.h>
15
16#include <media/id.h>
17
18#define MPEG_VIDEO_TARGET_BITRATE_MAX 27000
19#define MPEG_VIDEO_MAX_BITRATE_MAX 27000
20#define MPEG_TOTAL_TARGET_BITRATE_MAX 27000
21#define MPEG_PID_MAX ((1 << 14) - 1)
22
23/* Addresses to scan */
24static unsigned short normal_i2c[] = {0x20, I2C_CLIENT_END};
25static unsigned short normal_i2c_range[] = {I2C_CLIENT_END};
26I2C_CLIENT_INSMOD;
27
28MODULE_DESCRIPTION("device driver for saa6752hs MPEG2 encoder");
29MODULE_AUTHOR("Andrew de Quincey");
30MODULE_LICENSE("GPL");
31
32static struct i2c_driver driver;
33static struct i2c_client client_template;
34
35struct saa6752hs_state {
36 struct i2c_client client;
37 struct v4l2_mpeg_compression params;
38};
39
40enum saa6752hs_command {
41 SAA6752HS_COMMAND_RESET = 0,
42 SAA6752HS_COMMAND_STOP = 1,
43 SAA6752HS_COMMAND_START = 2,
44 SAA6752HS_COMMAND_PAUSE = 3,
45 SAA6752HS_COMMAND_RECONFIGURE = 4,
46 SAA6752HS_COMMAND_SLEEP = 5,
47 SAA6752HS_COMMAND_RECONFIGURE_FORCE = 6,
48
49 SAA6752HS_COMMAND_MAX
50};
51
52/* ---------------------------------------------------------------------- */
53
54static u8 PAT[] = {
55 0xc2, // i2c register
56 0x00, // table number for encoder
57
58 0x47, // sync
59 0x40, 0x00, // transport_error_indicator(0), payload_unit_start(1), transport_priority(0), pid(0)
60 0x10, // transport_scrambling_control(00), adaptation_field_control(01), continuity_counter(0)
61
62 0x00, // PSI pointer to start of table
63
64 0x00, // tid(0)
65 0xb0, 0x0d, // section_syntax_indicator(1), section_length(13)
66
67 0x00, 0x01, // transport_stream_id(1)
68
69 0xc1, // version_number(0), current_next_indicator(1)
70
71 0x00, 0x00, // section_number(0), last_section_number(0)
72
73 0x00, 0x01, // program_number(1)
74
75 0xe0, 0x00, // PMT PID
76
77 0x00, 0x00, 0x00, 0x00 // CRC32
78};
79
80static u8 PMT[] = {
81 0xc2, // i2c register
82 0x01, // table number for encoder
83
84 0x47, // sync
85 0x40, 0x00, // transport_error_indicator(0), payload_unit_start(1), transport_priority(0), pid
86 0x10, // transport_scrambling_control(00), adaptation_field_control(01), continuity_counter(0)
87
88 0x00, // PSI pointer to start of table
89
90 0x02, // tid(2)
91 0xb0, 0x17, // section_syntax_indicator(1), section_length(23)
92
93 0x00, 0x01, // program_number(1)
94
95 0xc1, // version_number(0), current_next_indicator(1)
96
97 0x00, 0x00, // section_number(0), last_section_number(0)
98
99 0xe0, 0x00, // PCR_PID
100
101 0xf0, 0x00, // program_info_length(0)
102
103 0x02, 0xe0, 0x00, 0xf0, 0x00, // video stream type(2), pid
104 0x04, 0xe0, 0x00, 0xf0, 0x00, // audio stream type(4), pid
105
106 0x00, 0x00, 0x00, 0x00 // CRC32
107};
108
109static struct v4l2_mpeg_compression param_defaults =
110{
111 .st_type = V4L2_MPEG_TS_2,
112 .st_bitrate = {
113 .mode = V4L2_BITRATE_CBR,
114 .target = 7000,
115 },
116
117 .ts_pid_pmt = 16,
118 .ts_pid_video = 260,
119 .ts_pid_audio = 256,
120 .ts_pid_pcr = 259,
121
122 .vi_type = V4L2_MPEG_VI_2,
123 .vi_aspect_ratio = V4L2_MPEG_ASPECT_4_3,
124 .vi_bitrate = {
125 .mode = V4L2_BITRATE_VBR,
126 .target = 4000,
127 .max = 6000,
128 },
129
130 .au_type = V4L2_MPEG_AU_2_II,
131 .au_bitrate = {
132 .mode = V4L2_BITRATE_CBR,
133 .target = 256,
134 },
135
136#if 0
137 /* FIXME: size? via S_FMT? */
138 .video_format = MPEG_VIDEO_FORMAT_D1,
139#endif
140};
141
142/* ---------------------------------------------------------------------- */
143
144static int saa6752hs_chip_command(struct i2c_client* client,
145 enum saa6752hs_command command)
146{
147 unsigned char buf[3];
148 unsigned long timeout;
149 int status = 0;
150
151 // execute the command
152 switch(command) {
153 case SAA6752HS_COMMAND_RESET:
154 buf[0] = 0x00;
155 break;
156
157 case SAA6752HS_COMMAND_STOP:
158 buf[0] = 0x03;
159 break;
160
161 case SAA6752HS_COMMAND_START:
162 buf[0] = 0x02;
163 break;
164
165 case SAA6752HS_COMMAND_PAUSE:
166 buf[0] = 0x04;
167 break;
168
169 case SAA6752HS_COMMAND_RECONFIGURE:
170 buf[0] = 0x05;
171 break;
172
173 case SAA6752HS_COMMAND_SLEEP:
174 buf[0] = 0x06;
175 break;
176
177 case SAA6752HS_COMMAND_RECONFIGURE_FORCE:
178 buf[0] = 0x07;
179 break;
180
181 default:
182 return -EINVAL;
183 }
184
185 // set it and wait for it to be so
186 i2c_master_send(client, buf, 1);
187 timeout = jiffies + HZ * 3;
188 for (;;) {
189 // get the current status
190 buf[0] = 0x10;
191 i2c_master_send(client, buf, 1);
192 i2c_master_recv(client, buf, 1);
193
194 if (!(buf[0] & 0x20))
195 break;
196 if (time_after(jiffies,timeout)) {
197 status = -ETIMEDOUT;
198 break;
199 }
200
201 // wait a bit
202 msleep(10);
203 }
204
205 // delay a bit to let encoder settle
206 msleep(50);
207
208 // done
209 return status;
210}
211
212
213static int saa6752hs_set_bitrate(struct i2c_client* client,
214 struct v4l2_mpeg_compression* params)
215{
216 u8 buf[3];
217
218 // set the bitrate mode
219 buf[0] = 0x71;
220 buf[1] = (params->vi_bitrate.mode == V4L2_BITRATE_VBR) ? 0 : 1;
221 i2c_master_send(client, buf, 2);
222
223 // set the video bitrate
224 if (params->vi_bitrate.mode == V4L2_BITRATE_VBR) {
225 // set the target bitrate
226 buf[0] = 0x80;
227 buf[1] = params->vi_bitrate.target >> 8;
228 buf[2] = params->vi_bitrate.target & 0xff;
229 i2c_master_send(client, buf, 3);
230
231 // set the max bitrate
232 buf[0] = 0x81;
233 buf[1] = params->vi_bitrate.max >> 8;
234 buf[2] = params->vi_bitrate.max & 0xff;
235 i2c_master_send(client, buf, 3);
236 } else {
237 // set the target bitrate (no max bitrate for CBR)
238 buf[0] = 0x81;
239 buf[1] = params->vi_bitrate.target >> 8;
240 buf[2] = params->vi_bitrate.target & 0xff;
241 i2c_master_send(client, buf, 3);
242 }
243
244 // set the audio bitrate
245 buf[0] = 0x94;
246 buf[1] = (256 == params->au_bitrate.target) ? 0 : 1;
247 i2c_master_send(client, buf, 2);
248
249 // set the total bitrate
250 buf[0] = 0xb1;
251 buf[1] = params->st_bitrate.target >> 8;
252 buf[2] = params->st_bitrate.target & 0xff;
253 i2c_master_send(client, buf, 3);
254
255 // return success
256 return 0;
257}
258
259
260static void saa6752hs_set_params(struct i2c_client* client,
261 struct v4l2_mpeg_compression* params)
262{
263 struct saa6752hs_state *h = i2c_get_clientdata(client);
264
265 /* check PIDs */
266 if (params->ts_pid_pmt <= MPEG_PID_MAX)
267 h->params.ts_pid_pmt = params->ts_pid_pmt;
268 if (params->ts_pid_pcr <= MPEG_PID_MAX)
269 h->params.ts_pid_pcr = params->ts_pid_pcr;
270 if (params->ts_pid_video <= MPEG_PID_MAX)
271 h->params.ts_pid_video = params->ts_pid_video;
272 if (params->ts_pid_audio <= MPEG_PID_MAX)
273 h->params.ts_pid_audio = params->ts_pid_audio;
274
275 /* check bitrate parameters */
276 if ((params->vi_bitrate.mode == V4L2_BITRATE_CBR) ||
277 (params->vi_bitrate.mode == V4L2_BITRATE_VBR))
278 h->params.vi_bitrate.mode = params->vi_bitrate.mode;
279 if (params->vi_bitrate.mode != V4L2_BITRATE_NONE)
280 h->params.st_bitrate.target = params->st_bitrate.target;
281 if (params->vi_bitrate.mode != V4L2_BITRATE_NONE)
282 h->params.vi_bitrate.target = params->vi_bitrate.target;
283 if (params->vi_bitrate.mode == V4L2_BITRATE_VBR)
284 h->params.vi_bitrate.max = params->vi_bitrate.max;
285 if (params->au_bitrate.mode != V4L2_BITRATE_NONE)
286 h->params.au_bitrate.target = params->au_bitrate.target;
287
288 /* aspect ratio */
289 if (params->vi_aspect_ratio == V4L2_MPEG_ASPECT_4_3 ||
290 params->vi_aspect_ratio == V4L2_MPEG_ASPECT_16_9)
291 h->params.vi_aspect_ratio = params->vi_aspect_ratio;
292
293 /* range checks */
294 if (h->params.st_bitrate.target > MPEG_TOTAL_TARGET_BITRATE_MAX)
295 h->params.st_bitrate.target = MPEG_TOTAL_TARGET_BITRATE_MAX;
296 if (h->params.vi_bitrate.target > MPEG_VIDEO_TARGET_BITRATE_MAX)
297 h->params.vi_bitrate.target = MPEG_VIDEO_TARGET_BITRATE_MAX;
298 if (h->params.vi_bitrate.max > MPEG_VIDEO_MAX_BITRATE_MAX)
299 h->params.vi_bitrate.max = MPEG_VIDEO_MAX_BITRATE_MAX;
300 if (h->params.au_bitrate.target <= 256)
301 h->params.au_bitrate.target = 256;
302 else
303 h->params.au_bitrate.target = 384;
304}
305
306static int saa6752hs_init(struct i2c_client* client)
307{
308 unsigned char buf[9], buf2[4];
309 struct saa6752hs_state *h;
310 u32 crc;
311 unsigned char localPAT[256];
312 unsigned char localPMT[256];
313
314 h = i2c_get_clientdata(client);
315
316 // Set video format - must be done first as it resets other settings
317 buf[0] = 0x41;
318 buf[1] = 0 /* MPEG_VIDEO_FORMAT_D1 */;
319 i2c_master_send(client, buf, 2);
320
321 // set bitrate
322 saa6752hs_set_bitrate(client, &h->params);
323
324 // Set GOP structure {3, 13}
325 buf[0] = 0x72;
326 buf[1] = 0x03;
327 buf[2] = 0x0D;
328 i2c_master_send(client,buf,3);
329
330 // Set minimum Q-scale {4}
331 buf[0] = 0x82;
332 buf[1] = 0x04;
333 i2c_master_send(client,buf,2);
334
335 // Set maximum Q-scale {12}
336 buf[0] = 0x83;
337 buf[1] = 0x0C;
338 i2c_master_send(client,buf,2);
339
340 // Set Output Protocol
341 buf[0] = 0xD0;
342 buf[1] = 0x81;
343 i2c_master_send(client,buf,2);
344
345 // Set video output stream format {TS}
346 buf[0] = 0xB0;
347 buf[1] = 0x05;
348 i2c_master_send(client,buf,2);
349
350 /* compute PAT */
351 memcpy(localPAT, PAT, sizeof(PAT));
352 localPAT[17] = 0xe0 | ((h->params.ts_pid_pmt >> 8) & 0x0f);
353 localPAT[18] = h->params.ts_pid_pmt & 0xff;
354 crc = crc32_be(~0, &localPAT[7], sizeof(PAT) - 7 - 4);
355 localPAT[sizeof(PAT) - 4] = (crc >> 24) & 0xFF;
356 localPAT[sizeof(PAT) - 3] = (crc >> 16) & 0xFF;
357 localPAT[sizeof(PAT) - 2] = (crc >> 8) & 0xFF;
358 localPAT[sizeof(PAT) - 1] = crc & 0xFF;
359
360 /* compute PMT */
361 memcpy(localPMT, PMT, sizeof(PMT));
362 localPMT[3] = 0x40 | ((h->params.ts_pid_pmt >> 8) & 0x0f);
363 localPMT[4] = h->params.ts_pid_pmt & 0xff;
364 localPMT[15] = 0xE0 | ((h->params.ts_pid_pcr >> 8) & 0x0F);
365 localPMT[16] = h->params.ts_pid_pcr & 0xFF;
366 localPMT[20] = 0xE0 | ((h->params.ts_pid_video >> 8) & 0x0F);
367 localPMT[21] = h->params.ts_pid_video & 0xFF;
368 localPMT[25] = 0xE0 | ((h->params.ts_pid_audio >> 8) & 0x0F);
369 localPMT[26] = h->params.ts_pid_audio & 0xFF;
370 crc = crc32_be(~0, &localPMT[7], sizeof(PMT) - 7 - 4);
371 localPMT[sizeof(PMT) - 4] = (crc >> 24) & 0xFF;
372 localPMT[sizeof(PMT) - 3] = (crc >> 16) & 0xFF;
373 localPMT[sizeof(PMT) - 2] = (crc >> 8) & 0xFF;
374 localPMT[sizeof(PMT) - 1] = crc & 0xFF;
375
376 // Set Audio PID
377 buf[0] = 0xC1;
378 buf[1] = (h->params.ts_pid_audio >> 8) & 0xFF;
379 buf[2] = h->params.ts_pid_audio & 0xFF;
380 i2c_master_send(client,buf,3);
381
382 // Set Video PID
383 buf[0] = 0xC0;
384 buf[1] = (h->params.ts_pid_video >> 8) & 0xFF;
385 buf[2] = h->params.ts_pid_video & 0xFF;
386 i2c_master_send(client,buf,3);
387
388 // Set PCR PID
389 buf[0] = 0xC4;
390 buf[1] = (h->params.ts_pid_pcr >> 8) & 0xFF;
391 buf[2] = h->params.ts_pid_pcr & 0xFF;
392 i2c_master_send(client,buf,3);
393
394 // Send SI tables
395 i2c_master_send(client,localPAT,sizeof(PAT));
396 i2c_master_send(client,localPMT,sizeof(PMT));
397
398 // mute then unmute audio. This removes buzzing artefacts
399 buf[0] = 0xa4;
400 buf[1] = 1;
401 i2c_master_send(client, buf, 2);
402 buf[1] = 0;
403 i2c_master_send(client, buf, 2);
404
405 // start it going
406 saa6752hs_chip_command(client, SAA6752HS_COMMAND_START);
407
408 // readout current state
409 buf[0] = 0xE1;
410 buf[1] = 0xA7;
411 buf[2] = 0xFE;
412 buf[3] = 0x82;
413 buf[4] = 0xB0;
414 i2c_master_send(client, buf, 5);
415 i2c_master_recv(client, buf2, 4);
416
417 // change aspect ratio
418 buf[0] = 0xE0;
419 buf[1] = 0xA7;
420 buf[2] = 0xFE;
421 buf[3] = 0x82;
422 buf[4] = 0xB0;
423 buf[5] = buf2[0];
424 switch(h->params.vi_aspect_ratio) {
425 case V4L2_MPEG_ASPECT_16_9:
426 buf[6] = buf2[1] | 0x40;
427 break;
428 case V4L2_MPEG_ASPECT_4_3:
429 default:
430 buf[6] = buf2[1] & 0xBF;
431 break;
432 break;
433 }
434 buf[7] = buf2[2];
435 buf[8] = buf2[3];
436 i2c_master_send(client, buf, 9);
437
438 // return success
439 return 0;
440}
441
442static int saa6752hs_attach(struct i2c_adapter *adap, int addr, int kind)
443{
444 struct saa6752hs_state *h;
445
446 printk("saa6752hs: chip found @ 0x%x\n", addr<<1);
447
448 if (NULL == (h = kmalloc(sizeof(*h), GFP_KERNEL)))
449 return -ENOMEM;
450 memset(h,0,sizeof(*h));
451 h->client = client_template;
452 h->params = param_defaults;
453 h->client.adapter = adap;
454 h->client.addr = addr;
455
456 i2c_set_clientdata(&h->client, h);
457 i2c_attach_client(&h->client);
458 return 0;
459}
460
461static int saa6752hs_probe(struct i2c_adapter *adap)
462{
463 if (adap->class & I2C_CLASS_TV_ANALOG)
464 return i2c_probe(adap, &addr_data, saa6752hs_attach);
465 return 0;
466}
467
468static int saa6752hs_detach(struct i2c_client *client)
469{
470 struct saa6752hs_state *h;
471
472 h = i2c_get_clientdata(client);
473 i2c_detach_client(client);
474 kfree(h);
475 return 0;
476}
477
478static int
479saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg)
480{
481 struct saa6752hs_state *h = i2c_get_clientdata(client);
482 struct v4l2_mpeg_compression *params = arg;
483 int err = 0;
484
485 switch (cmd) {
486 case VIDIOC_S_MPEGCOMP:
487 if (NULL == params) {
488 /* apply settings and start encoder */
489 saa6752hs_init(client);
490 break;
491 }
492 saa6752hs_set_params(client, params);
493 /* fall through */
494 case VIDIOC_G_MPEGCOMP:
495 *params = h->params;
496 break;
497 default:
498 /* nothing */
499 break;
500 }
501
502 return err;
503}
504
505/* ----------------------------------------------------------------------- */
506
507static struct i2c_driver driver = {
508 .owner = THIS_MODULE,
509 .name = "i2c saa6752hs MPEG encoder",
510 .id = I2C_DRIVERID_SAA6752HS,
511 .flags = I2C_DF_NOTIFY,
512 .attach_adapter = saa6752hs_probe,
513 .detach_client = saa6752hs_detach,
514 .command = saa6752hs_command,
515};
516
517static struct i2c_client client_template =
518{
519 I2C_DEVNAME("saa6752hs"),
520 .flags = I2C_CLIENT_ALLOW_USE,
521 .driver = &driver,
522};
523
524static int __init saa6752hs_init_module(void)
525{
526 return i2c_add_driver(&driver);
527}
528
529static void __exit saa6752hs_cleanup_module(void)
530{
531 i2c_del_driver(&driver);
532}
533
534module_init(saa6752hs_init_module);
535module_exit(saa6752hs_cleanup_module);
536
537/*
538 * Overrides for Emacs so that we follow Linus's tabbing style.
539 * ---------------------------------------------------------------------------
540 * Local variables:
541 * c-basic-offset: 8
542 * End:
543 */
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
new file mode 100644
index 00000000000..180d3175ea5
--- /dev/null
+++ b/drivers/media/video/saa7134/saa7134-cards.c
@@ -0,0 +1,2018 @@
1
2/*
3 * $Id: saa7134-cards.c,v 1.54 2005/03/07 12:01:51 kraxel Exp $
4 *
5 * device driver for philips saa7134 based TV cards
6 * card-specific stuff.
7 *
8 * (c) 2001-04 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
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#include <linux/init.h>
26#include <linux/module.h>
27
28#include "saa7134-reg.h"
29#include "saa7134.h"
30
31/* commly used strings */
32static char name_mute[] = "mute";
33static char name_radio[] = "Radio";
34static char name_tv[] = "Television";
35static char name_tv_mono[] = "TV (mono only)";
36static char name_comp1[] = "Composite1";
37static char name_comp2[] = "Composite2";
38static char name_comp3[] = "Composite3";
39static char name_comp4[] = "Composite4";
40static char name_svideo[] = "S-Video";
41
42/* ------------------------------------------------------------------ */
43/* board config info */
44
45struct saa7134_board saa7134_boards[] = {
46 [SAA7134_BOARD_UNKNOWN] = {
47 .name = "UNKNOWN/GENERIC",
48 .audio_clock = 0x00187de7,
49 .tuner_type = TUNER_ABSENT,
50 .inputs = {{
51 .name = "default",
52 .vmux = 0,
53 .amux = LINE1,
54 }},
55 },
56 [SAA7134_BOARD_PROTEUS_PRO] = {
57 /* /me */
58 .name = "Proteus Pro [philips reference design]",
59 .audio_clock = 0x00187de7,
60 .tuner_type = TUNER_PHILIPS_PAL,
61 .inputs = {{
62 .name = name_comp1,
63 .vmux = 0,
64 .amux = LINE1,
65 },{
66 .name = name_tv,
67 .vmux = 1,
68 .amux = TV,
69 .tv = 1,
70 },{
71 .name = name_tv_mono,
72 .vmux = 1,
73 .amux = LINE2,
74 .tv = 1,
75 }},
76 .radio = {
77 .name = name_radio,
78 .amux = LINE2,
79 },
80 },
81 [SAA7134_BOARD_FLYVIDEO3000] = {
82 /* "Marco d'Itri" <md@Linux.IT> */
83 .name = "LifeView FlyVIDEO3000",
84 .audio_clock = 0x00200000,
85 .tuner_type = TUNER_PHILIPS_PAL,
86 .gpiomask = 0xe000,
87 .inputs = {{
88 .name = name_tv,
89 .vmux = 1,
90 .amux = TV,
91 .gpio = 0x8000,
92 .tv = 1,
93 },{
94 .name = name_tv_mono,
95 .vmux = 1,
96 .amux = LINE2,
97 .gpio = 0x0000,
98 .tv = 1,
99 },{
100 .name = name_comp1,
101 .vmux = 0,
102 .amux = LINE2,
103 .gpio = 0x4000,
104 },{
105 .name = name_comp2,
106 .vmux = 3,
107 .amux = LINE2,
108 .gpio = 0x4000,
109 },{
110 .name = name_svideo,
111 .vmux = 8,
112 .amux = LINE2,
113 .gpio = 0x4000,
114 }},
115 .radio = {
116 .name = name_radio,
117 .amux = LINE2,
118 .gpio = 0x2000,
119 },
120 },
121 [SAA7134_BOARD_FLYVIDEO2000] = {
122 /* "TC Wan" <tcwan@cs.usm.my> */
123 .name = "LifeView FlyVIDEO2000",
124 .audio_clock = 0x00200000,
125 .tuner_type = TUNER_LG_PAL_NEW_TAPC,
126 .gpiomask = 0xe000,
127 .inputs = {{
128 .name = name_tv,
129 .vmux = 1,
130 .amux = LINE2,
131 .gpio = 0x0000,
132 .tv = 1,
133 },{
134 .name = name_comp1,
135 .vmux = 0,
136 .amux = LINE2,
137 .gpio = 0x4000,
138 },{
139 .name = name_comp2,
140 .vmux = 3,
141 .amux = LINE2,
142 .gpio = 0x4000,
143 },{
144 .name = name_svideo,
145 .vmux = 8,
146 .amux = LINE2,
147 .gpio = 0x4000,
148 }},
149 .radio = {
150 .name = name_radio,
151 .amux = LINE2,
152 .gpio = 0x2000,
153 },
154 .mute = {
155 .name = name_mute,
156 .amux = LINE2,
157 .gpio = 0x8000,
158 },
159 },
160 [SAA7134_BOARD_FLYTVPLATINUM_MINI] = {
161 /* "Arnaud Quette" <aquette@free.fr> */
162 .name = "LifeView FlyTV Platinum Mini",
163 .audio_clock = 0x00200000,
164 .tuner_type = TUNER_PHILIPS_TDA8290,
165 .inputs = {{
166 .name = name_tv,
167 .vmux = 1,
168 .amux = LINE2,
169 .tv = 1,
170 },{
171 .name = name_comp1,
172 .vmux = 0,
173 .amux = LINE2,
174 },{
175 .name = name_svideo,
176 .vmux = 8,
177 .amux = LINE2,
178 }},
179 },
180 [SAA7134_BOARD_FLYTVPLATINUM_FM] = {
181 /* LifeView FlyTV Platinum FM (LR214WF) */
182 /* "Peter Missel <peter.missel@onlinehome.de> */
183 .name = "LifeView FlyTV Platinum FM",
184 .audio_clock = 0x00200000,
185 .tuner_type = TUNER_PHILIPS_TDA8290,
186// .gpiomask = 0xe000,
187 .inputs = {{
188 .name = name_tv,
189 .vmux = 1,
190 .amux = TV,
191// .gpio = 0x0000,
192 .tv = 1,
193 },{
194/* .name = name_tv_mono,
195 .vmux = 1,
196 .amux = LINE2,
197 .gpio = 0x0000,
198 .tv = 1,
199 },{
200*/ .name = name_comp1, /* Composite signal on S-Video input */
201 .vmux = 0,
202 .amux = LINE2,
203// .gpio = 0x4000,
204 },{
205 .name = name_comp2, /* Composite input */
206 .vmux = 3,
207 .amux = LINE2,
208// .gpio = 0x4000,
209 },{
210 .name = name_svideo, /* S-Video signal on S-Video input */
211 .vmux = 8,
212 .amux = LINE2,
213// .gpio = 0x4000,
214 }},
215/* .radio = {
216 .name = name_radio,
217 .amux = LINE2,
218 .gpio = 0x2000,
219 },
220*/ },
221 [SAA7134_BOARD_EMPRESS] = {
222 /* "Gert Vervoort" <gert.vervoort@philips.com> */
223 .name = "EMPRESS",
224 .audio_clock = 0x00187de7,
225 .tuner_type = TUNER_PHILIPS_PAL,
226 .inputs = {{
227 .name = name_comp1,
228 .vmux = 0,
229 .amux = LINE1,
230 },{
231 .name = name_svideo,
232 .vmux = 8,
233 .amux = LINE1,
234 },{
235 .name = name_tv,
236 .vmux = 1,
237 .amux = LINE2,
238 .tv = 1,
239 }},
240 .radio = {
241 .name = name_radio,
242 .amux = LINE2,
243 },
244 .mpeg = SAA7134_MPEG_EMPRESS,
245 .video_out = CCIR656,
246 },
247 [SAA7134_BOARD_MONSTERTV] = {
248 /* "K.Ohta" <alpha292@bremen.or.jp> */
249 .name = "SKNet Monster TV",
250 .audio_clock = 0x00187de7,
251 .tuner_type = TUNER_PHILIPS_NTSC_M,
252 .inputs = {{
253 .name = name_tv,
254 .vmux = 1,
255 .amux = TV,
256 .tv = 1,
257 },{
258 .name = name_comp1,
259 .vmux = 0,
260 .amux = LINE1,
261 },{
262 .name = name_svideo,
263 .vmux = 8,
264 .amux = LINE1,
265 }},
266 .radio = {
267 .name = name_radio,
268 .amux = LINE2,
269 },
270 },
271 [SAA7134_BOARD_MD9717] = {
272 .name = "Tevion MD 9717",
273 .audio_clock = 0x00200000,
274 .tuner_type = TUNER_PHILIPS_PAL,
275 .inputs = {{
276 .name = name_tv,
277 .vmux = 1,
278 .amux = TV,
279 .tv = 1,
280 },{
281 /* workaround for problems with normal TV sound */
282 .name = name_tv_mono,
283 .vmux = 1,
284 .amux = LINE2,
285 .tv = 1,
286 },{
287 .name = name_comp1,
288 .vmux = 2,
289 .amux = LINE1,
290 },{
291 .name = name_comp2,
292 .vmux = 3,
293 .amux = LINE1,
294 },{
295 .name = name_svideo,
296 .vmux = 8,
297 .amux = LINE1,
298 }},
299 .radio = {
300 .name = name_radio,
301 .amux = LINE2,
302 },
303 },
304 [SAA7134_BOARD_TVSTATION_RDS] = {
305 /* Typhoon TV Tuner RDS: Art.Nr. 50694 */
306 .name = "KNC One TV-Station RDS / Typhoon TV Tuner RDS",
307 .audio_clock = 0x00200000,
308 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
309 .tda9887_conf = TDA9887_PRESENT,
310 .inputs = {{
311 .name = name_tv,
312 .vmux = 1,
313 .amux = TV,
314 .tv = 1,
315 },{
316 .name = name_tv_mono,
317 .vmux = 1,
318 .amux = LINE2,
319 .tv = 1,
320 },{
321
322 .name = name_svideo,
323 .vmux = 8,
324 .amux = LINE1,
325 },{
326 .name = name_comp1,
327 .vmux = 3,
328 .amux = LINE1,
329 },{
330
331 .name = "CVid over SVid",
332 .vmux = 0,
333 .amux = LINE1,
334 }},
335 .radio = {
336 .name = name_radio,
337 .amux = LINE2,
338 },
339 },
340 [SAA7134_BOARD_TVSTATION_DVR] = {
341 .name = "KNC One TV-Station DVR",
342 .audio_clock = 0x00200000,
343 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
344 .tda9887_conf = TDA9887_PRESENT,
345 .gpiomask = 0x820000,
346 .inputs = {{
347 .name = name_tv,
348 .vmux = 1,
349 .amux = LINE2,
350 .tv = 1,
351 .gpio = 0x20000,
352 },{
353 .name = name_svideo,
354 .vmux = 8,
355 .amux = LINE1,
356 .gpio = 0x20000,
357 },{
358 .name = name_comp1,
359 .vmux = 3,
360 .amux = LINE1,
361 .gpio = 0x20000,
362 }},
363 .radio = {
364 .name = name_radio,
365 .amux = LINE2,
366 .gpio = 0x20000,
367 },
368 .mpeg = SAA7134_MPEG_EMPRESS,
369 .video_out = CCIR656,
370 },
371 [SAA7134_BOARD_CINERGY400] = {
372 .name = "Terratec Cinergy 400 TV",
373 .audio_clock = 0x00200000,
374 .tuner_type = TUNER_PHILIPS_PAL,
375 .inputs = {{
376 .name = name_tv,
377 .vmux = 1,
378 .amux = TV,
379 .tv = 1,
380 },{
381 .name = name_comp1,
382 .vmux = 4,
383 .amux = LINE1,
384 },{
385 .name = name_svideo,
386 .vmux = 8,
387 .amux = LINE1,
388 },{
389 .name = name_comp2, // CVideo over SVideo Connector
390 .vmux = 0,
391 .amux = LINE1,
392 }}
393 },
394 [SAA7134_BOARD_MD5044] = {
395 .name = "Medion 5044",
396 .audio_clock = 0x00187de7, // was: 0x00200000,
397 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
398 .tda9887_conf = TDA9887_PRESENT,
399 .inputs = {{
400 .name = name_tv,
401 .vmux = 1,
402 .amux = TV,
403 .tv = 1,
404 },{
405 /* workaround for problems with normal TV sound */
406 .name = name_tv_mono,
407 .vmux = 1,
408 .amux = LINE2,
409 .tv = 1,
410 },{
411 .name = name_comp1,
412 .vmux = 0,
413 .amux = LINE2,
414 },{
415 .name = name_comp2,
416 .vmux = 3,
417 .amux = LINE2,
418 },{
419 .name = name_svideo,
420 .vmux = 8,
421 .amux = LINE2,
422 }},
423 .radio = {
424 .name = name_radio,
425 .amux = LINE2,
426 },
427 },
428 [SAA7134_BOARD_KWORLD] = {
429 .name = "Kworld/KuroutoShikou SAA7130-TVPCI",
430 .audio_clock = 0x00187de7,
431 .tuner_type = TUNER_PHILIPS_NTSC_M,
432 .inputs = {{
433 .name = name_svideo,
434 .vmux = 8,
435 .amux = LINE1,
436 },{
437 .name = name_comp1,
438 .vmux = 3,
439 .amux = LINE1,
440 },{
441 .name = name_tv,
442 .vmux = 1,
443 .amux = LINE2,
444 .tv = 1,
445 }},
446 },
447 [SAA7134_BOARD_CINERGY600] = {
448 .name = "Terratec Cinergy 600 TV",
449 .audio_clock = 0x00200000,
450 .tuner_type = TUNER_PHILIPS_PAL,
451 .tda9887_conf = TDA9887_PRESENT,
452 .inputs = {{
453 .name = name_tv,
454 .vmux = 1,
455 .amux = TV,
456 .tv = 1,
457 },{
458 .name = name_comp1,
459 .vmux = 4,
460 .amux = LINE1,
461 },{
462 .name = name_svideo,
463 .vmux = 8,
464 .amux = LINE1,
465 },{
466 .name = name_comp2, // CVideo over SVideo Connector
467 .vmux = 0,
468 .amux = LINE1,
469 }},
470 .radio = {
471 .name = name_radio,
472 .amux = LINE2,
473 },
474 },
475 [SAA7134_BOARD_MD7134] = {
476 .name = "Medion 7134",
477 //.audio_clock = 0x00200000,
478 .audio_clock = 0x00187de7,
479 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
480 .tda9887_conf = TDA9887_PRESENT,
481 .mpeg = SAA7134_MPEG_DVB,
482 .inputs = {{
483 .name = name_tv,
484 .vmux = 1,
485 .amux = TV,
486 .tv = 1,
487 },{
488 .name = name_comp1,
489 .vmux = 0,
490 .amux = LINE1,
491 },{
492 .name = name_svideo,
493 .vmux = 8,
494 .amux = LINE1,
495 }},
496 .radio = {
497 .name = name_radio,
498 .amux = LINE2,
499 },
500 },
501 [SAA7134_BOARD_TYPHOON_90031] = {
502 /* aka Typhoon "TV+Radio", Art.Nr 90031 */
503 /* Tom Zoerner <tomzo at users sourceforge net> */
504 .name = "Typhoon TV+Radio 90031",
505 .audio_clock = 0x00200000,
506 .tuner_type = TUNER_PHILIPS_PAL,
507 .tda9887_conf = TDA9887_PRESENT,
508 .inputs = {{
509 .name = name_tv,
510 .vmux = 1,
511 .amux = TV,
512 .tv = 1,
513 },{
514 .name = name_comp1,
515 .vmux = 3,
516 .amux = LINE1,
517 },{
518 .name = name_svideo,
519 .vmux = 8,
520 .amux = LINE1,
521 }},
522 .radio = {
523 .name = name_radio,
524 .amux = LINE2,
525 },
526 },
527 [SAA7134_BOARD_ELSA] = {
528 .name = "ELSA EX-VISION 300TV",
529 .audio_clock = 0x00187de7,
530 .tuner_type = TUNER_HITACHI_NTSC,
531 .inputs = {{
532 .name = name_svideo,
533 .vmux = 8,
534 .amux = LINE1,
535 },{
536 .name = name_comp1,
537 .vmux = 0,
538 .amux = LINE1,
539 },{
540 .name = name_tv,
541 .vmux = 4,
542 .amux = LINE2,
543 .tv = 1,
544 }},
545 },
546 [SAA7134_BOARD_ELSA_500TV] = {
547 .name = "ELSA EX-VISION 500TV",
548 .audio_clock = 0x00187de7,
549 .tuner_type = TUNER_HITACHI_NTSC,
550 .inputs = {{
551 .name = name_svideo,
552 .vmux = 7,
553 .amux = LINE1,
554 },{
555 .name = name_tv,
556 .vmux = 8,
557 .amux = TV,
558 .tv = 1,
559 },{
560 .name = name_tv_mono,
561 .vmux = 8,
562 .amux = LINE2,
563 .tv = 1,
564 }},
565 },
566 [SAA7134_BOARD_ASUSTeK_TVFM7134] = {
567 .name = "ASUS TV-FM 7134",
568 .audio_clock = 0x00187de7,
569 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
570 .tda9887_conf = TDA9887_PRESENT,
571 .inputs = {{
572 .name = name_tv,
573 .vmux = 1,
574 .amux = TV,
575 .tv = 1,
576 },{
577 .name = name_comp1,
578 .vmux = 4,
579 .amux = LINE2,
580 },{
581 .name = name_svideo,
582 .vmux = 6,
583 .amux = LINE2,
584 }},
585 .radio = {
586 .name = name_radio,
587 .amux = LINE1,
588 },
589 },
590 [SAA7135_BOARD_ASUSTeK_TVFM7135] = {
591 .name = "ASUS TV-FM 7135",
592 .audio_clock = 0x00187de7,
593 .tuner_type = TUNER_PHILIPS_TDA8290,
594 .gpiomask = 0x200000,
595 .inputs = {{
596 .name = name_tv,
597 .vmux = 1,
598 .amux = TV,
599 .gpio = 0x0000,
600 .tv = 1,
601 },{
602 .name = name_comp1,
603 .vmux = 4,
604 .amux = LINE2,
605 .gpio = 0x0000,
606 },{
607 .name = name_svideo,
608 .vmux = 6,
609 .amux = LINE2,
610 .gpio = 0x0000,
611 }},
612 .radio = {
613 .name = name_radio,
614 .amux = TV,
615 .gpio = 0x200000,
616 },
617 },
618 [SAA7134_BOARD_VA1000POWER] = {
619 .name = "AOPEN VA1000 POWER",
620 .audio_clock = 0x00187de7,
621 .tuner_type = TUNER_PHILIPS_NTSC,
622 .inputs = {{
623 .name = name_svideo,
624 .vmux = 8,
625 .amux = LINE1,
626 },{
627 .name = name_comp1,
628 .vmux = 3,
629 .amux = LINE1,
630 },{
631 .name = name_tv,
632 .vmux = 1,
633 .amux = LINE2,
634 .tv = 1,
635 }},
636 },
637 [SAA7134_BOARD_10MOONSTVMASTER] = {
638 /* "lilicheng" <llc@linuxfans.org> */
639 .name = "10MOONS PCI TV CAPTURE CARD",
640 .audio_clock = 0x00200000,
641 .tuner_type = TUNER_LG_PAL_NEW_TAPC,
642 .gpiomask = 0xe000,
643 .inputs = {{
644 .name = name_tv,
645 .vmux = 1,
646 .amux = LINE2,
647 .gpio = 0x0000,
648 .tv = 1,
649 },{
650 .name = name_comp1,
651 .vmux = 0,
652 .amux = LINE2,
653 .gpio = 0x4000,
654 },{
655 .name = name_comp2,
656 .vmux = 3,
657 .amux = LINE2,
658 .gpio = 0x4000,
659 },{
660 .name = name_svideo,
661 .vmux = 8,
662 .amux = LINE2,
663 .gpio = 0x4000,
664 }},
665 .radio = {
666 .name = name_radio,
667 .amux = LINE2,
668 .gpio = 0x2000,
669 },
670 .mute = {
671 .name = name_mute,
672 .amux = LINE2,
673 .gpio = 0x8000,
674 },
675 },
676 [SAA7134_BOARD_BMK_MPEX_NOTUNER] = {
677 /* "Andrew de Quincey" <adq@lidskialf.net> */
678 .name = "BMK MPEX No Tuner",
679 .audio_clock = 0x200000,
680 .tuner_type = TUNER_ABSENT,
681 .inputs = {{
682 .name = name_comp1,
683 .vmux = 4,
684 .amux = LINE1,
685 },{
686 .name = name_comp2,
687 .vmux = 3,
688 .amux = LINE1,
689 },{
690 .name = name_comp3,
691 .vmux = 0,
692 .amux = LINE1,
693 },{
694 .name = name_comp4,
695 .vmux = 1,
696 .amux = LINE1,
697 },{
698 .name = name_svideo,
699 .vmux = 8,
700 .amux = LINE1,
701 }},
702 .mpeg = SAA7134_MPEG_EMPRESS,
703 .video_out = CCIR656,
704 },
705 [SAA7134_BOARD_VIDEOMATE_TV] = {
706 .name = "Compro VideoMate TV",
707 .audio_clock = 0x00187de7,
708 .tuner_type = TUNER_PHILIPS_NTSC_M,
709 .inputs = {{
710 .name = name_svideo,
711 .vmux = 8,
712 .amux = LINE1,
713 },{
714 .name = name_comp1,
715 .vmux = 3,
716 .amux = LINE1,
717 },{
718 .name = name_tv,
719 .vmux = 1,
720 .amux = LINE2,
721 .tv = 1,
722 }},
723 },
724 [SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUS] = {
725 .name = "Compro VideoMate TV Gold+",
726 .audio_clock = 0x00187de7,
727 .tuner_type = TUNER_PHILIPS_NTSC_M,
728 .gpiomask = 0x800c0000,
729 .inputs = {{
730 .name = name_svideo,
731 .vmux = 8,
732 .amux = LINE1,
733 .gpio = 0x06c00012,
734 },{
735 .name = name_comp1,
736 .vmux = 3,
737 .amux = LINE1,
738 .gpio = 0x0ac20012,
739 },{
740 .name = name_tv,
741 .vmux = 1,
742 .amux = LINE2,
743 .gpio = 0x08c20012,
744 .tv = 1,
745 }},
746 },
747 [SAA7134_BOARD_CRONOS_PLUS] = {
748 /* gpio pins:
749 0 .. 3 BASE_ID
750 4 .. 7 PROTECT_ID
751 8 .. 11 USER_OUT
752 12 .. 13 USER_IN
753 14 .. 15 VIDIN_SEL */
754 .name = "Matrox CronosPlus",
755 .tuner_type = TUNER_ABSENT,
756 .gpiomask = 0xcf00,
757 .inputs = {{
758 .name = name_comp1,
759 .vmux = 0,
760 .gpio = 2 << 14,
761 },{
762 .name = name_comp2,
763 .vmux = 0,
764 .gpio = 1 << 14,
765 },{
766 .name = name_comp3,
767 .vmux = 0,
768 .gpio = 0 << 14,
769 },{
770 .name = name_comp4,
771 .vmux = 0,
772 .gpio = 3 << 14,
773 },{
774 .name = name_svideo,
775 .vmux = 8,
776 .gpio = 2 << 14,
777 }},
778 },
779 [SAA7134_BOARD_MD2819] = {
780 .name = "AverMedia M156 / Medion 2819",
781 .audio_clock = 0x00187de7,
782 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
783 .tda9887_conf = TDA9887_PRESENT,
784 .inputs = {{
785 .name = name_tv,
786 .vmux = 1,
787 .amux = TV,
788 .tv = 1,
789 },{
790 .name = name_comp1,
791 .vmux = 0,
792 .amux = LINE2,
793 },{
794 .name = name_comp2,
795 .vmux = 3,
796 .amux = LINE2,
797 },{
798 .name = name_svideo,
799 .vmux = 8,
800 .amux = LINE2,
801 }},
802 .radio = {
803 .name = name_radio,
804 .amux = LINE2,
805 },
806 },
807 [SAA7134_BOARD_BMK_MPEX_TUNER] = {
808 /* "Greg Wickham <greg.wickham@grangenet.net> */
809 .name = "BMK MPEX Tuner",
810 .audio_clock = 0x200000,
811 .tuner_type = TUNER_PHILIPS_PAL,
812 .inputs = {{
813 .name = name_comp1,
814 .vmux = 1,
815 .amux = LINE1,
816 },{
817 .name = name_svideo,
818 .vmux = 8,
819 .amux = LINE1,
820 },{
821 .name = name_tv,
822 .vmux = 3,
823 .amux = TV,
824 .tv = 1,
825 }},
826 .mpeg = SAA7134_MPEG_EMPRESS,
827 .video_out = CCIR656,
828 },
829 [SAA7134_BOARD_ASUSTEK_TVFM7133] = {
830 .name = "ASUS TV-FM 7133",
831 .audio_clock = 0x00187de7,
832 // probably wrong, the 7133 one is the NTSC version ...
833 // .tuner_type = TUNER_PHILIPS_FM1236_MK3
834 .tuner_type = TUNER_LG_NTSC_NEW_TAPC,
835 .tda9887_conf = TDA9887_PRESENT,
836 .inputs = {{
837 .name = name_tv,
838 .vmux = 1,
839 .amux = TV,
840 .tv = 1,
841 },{
842 .name = name_comp1,
843 .vmux = 4,
844 .amux = LINE2,
845 },{
846 .name = name_svideo,
847 .vmux = 6,
848 .amux = LINE2,
849 }},
850 .radio = {
851 .name = name_radio,
852 .amux = LINE1,
853 },
854 },
855 [SAA7134_BOARD_PINNACLE_PCTV_STEREO] = {
856 .name = "Pinnacle PCTV Stereo (saa7134)",
857 .audio_clock = 0x00187de7,
858 .tuner_type = TUNER_MT2032,
859 .tda9887_conf = TDA9887_PRESENT | TDA9887_INTERCARRIER,
860 .inputs = {{
861 .name = name_tv,
862 .vmux = 3,
863 .amux = TV,
864 .tv = 1,
865 },{
866 .name = name_comp1,
867 .vmux = 0,
868 .amux = LINE2,
869 },{
870 .name = name_comp2,
871 .vmux = 1,
872 .amux = LINE2,
873 },{
874 .name = name_svideo,
875 .vmux = 8,
876 .amux = LINE2,
877 }},
878 },
879 [SAA7134_BOARD_MANLI_MTV002] = {
880 /* Ognjen Nastic <ognjen@logosoft.ba> */
881 .name = "Manli MuchTV M-TV002",
882 .audio_clock = 0x00200000,
883 .tuner_type = TUNER_PHILIPS_PAL,
884 .inputs = {{
885 .name = name_svideo,
886 .vmux = 8,
887 .amux = LINE1,
888 },{
889 .name = name_comp1,
890 .vmux = 1,
891 .amux = LINE1,
892 },{
893 .name = name_tv,
894 .vmux = 3,
895 .amux = LINE2,
896 .tv = 1,
897 }},
898 .radio = {
899 .name = name_radio,
900 .amux = LINE2,
901 },
902 .mute = {
903 .name = name_mute,
904 .amux = LINE1,
905 },
906 },
907 [SAA7134_BOARD_MANLI_MTV001] = {
908 /* Ognjen Nastic <ognjen@logosoft.ba> UNTESTED */
909 .name = "Manli MuchTV M-TV001",
910 .audio_clock = 0x00200000,
911 .tuner_type = TUNER_PHILIPS_PAL,
912 .inputs = {{
913 .name = name_svideo,
914 .vmux = 8,
915 .amux = LINE1,
916 },{
917 .name = name_comp1,
918 .vmux = 1,
919 .amux = LINE1,
920 },{
921 .name = name_tv,
922 .vmux = 3,
923 .amux = LINE2,
924 .tv = 1,
925 }},
926 },
927 [SAA7134_BOARD_TG3000TV] = {
928 /* TransGear 3000TV */
929 .name = "Nagase Sangyo TransGear 3000TV",
930 .audio_clock = 0x00187de7,
931 .tuner_type = TUNER_PHILIPS_NTSC_M,
932 .inputs = {{
933 .name = name_tv,
934 .vmux = 1,
935 .amux = LINE2,
936 .tv = 1,
937 },{
938 .name = name_comp1,
939 .vmux = 3,
940 .amux = LINE2,
941 },{
942 .name = name_svideo,
943 .vmux = 8,
944 .amux = LINE2,
945 }},
946 },
947 [SAA7134_BOARD_ECS_TVP3XP] = {
948 .name = "Elitegroup ECS TVP3XP FM1216 Tuner Card(PAL-BG,FM) ",
949 .audio_clock = 0x187de7, // xtal 32.1 MHz
950 .tuner_type = TUNER_PHILIPS_PAL,
951 .inputs = {{
952 .name = name_tv,
953 .vmux = 1,
954 .amux = TV,
955 .tv = 1,
956 },{
957 .name = name_tv_mono,
958 .vmux = 1,
959 .amux = LINE2,
960 .tv = 1,
961 },{
962 .name = name_comp1,
963 .vmux = 3,
964 .amux = LINE1,
965 },{
966 .name = name_svideo,
967 .vmux = 8,
968 .amux = LINE1,
969 },{
970 .name = "CVid over SVid",
971 .vmux = 0,
972 .amux = LINE1,
973 }},
974 .radio = {
975 .name = name_radio,
976 .amux = LINE2,
977 },
978 },
979 [SAA7134_BOARD_ECS_TVP3XP_4CB5] = {
980 .name = "Elitegroup ECS TVP3XP FM1236 Tuner Card (NTSC,FM)",
981 .audio_clock = 0x187de7,
982 .tuner_type = TUNER_PHILIPS_NTSC,
983 .inputs = {{
984 .name = name_tv,
985 .vmux = 1,
986 .amux = TV,
987 .tv = 1,
988 },{
989 .name = name_tv_mono,
990 .vmux = 1,
991 .amux = LINE2,
992 .tv = 1,
993 },{
994 .name = name_comp1,
995 .vmux = 3,
996 .amux = LINE1,
997 },{
998 .name = name_svideo,
999 .vmux = 8,
1000 .amux = LINE1,
1001 },{
1002 .name = "CVid over SVid",
1003 .vmux = 0,
1004 .amux = LINE1,
1005 }},
1006 .radio = {
1007 .name = name_radio,
1008 .amux = LINE2,
1009 },
1010 },
1011 [SAA7134_BOARD_AVACSSMARTTV] = {
1012 /* Roman Pszonczenko <romka@kolos.math.uni.lodz.pl> */
1013 .name = "AVACS SmartTV",
1014 .audio_clock = 0x00187de7,
1015 .tuner_type = TUNER_PHILIPS_PAL,
1016 .inputs = {{
1017 .name = name_tv,
1018 .vmux = 1,
1019 .amux = TV,
1020 .tv = 1,
1021 },{
1022 .name = name_tv_mono,
1023 .vmux = 1,
1024 .amux = LINE2,
1025 .tv = 1,
1026 },{
1027 .name = name_comp1,
1028 .vmux = 0,
1029 .amux = LINE2,
1030 },{
1031 .name = name_comp2,
1032 .vmux = 3,
1033 .amux = LINE2,
1034 },{
1035 .name = name_svideo,
1036 .vmux = 8,
1037 .amux = LINE2,
1038 }},
1039 .radio = {
1040 .name = name_radio,
1041 .amux = LINE2,
1042 .gpio = 0x200000,
1043 },
1044 },
1045 [SAA7134_BOARD_AVERMEDIA_DVD_EZMAKER] = {
1046 /* Michael Smith <msmith@cbnco.com> */
1047 .name = "AVerMedia DVD EZMaker",
1048 .audio_clock = 0x00187de7,
1049 .tuner_type = TUNER_ABSENT,
1050 .inputs = {{
1051 .name = name_comp1,
1052 .vmux = 3,
1053 },{
1054 .name = name_svideo,
1055 .vmux = 8,
1056 }},
1057 },
1058 [SAA7134_BOARD_NOVAC_PRIMETV7133] = {
1059 /* toshii@netbsd.org */
1060 .name = "Noval Prime TV 7133",
1061 .audio_clock = 0x00200000,
1062 .tuner_type = TUNER_ALPS_TSBH1_NTSC,
1063 .inputs = {{
1064 .name = name_comp1,
1065 .vmux = 3,
1066 },{
1067 .name = name_tv,
1068 .vmux = 1,
1069 .amux = TV,
1070 .tv = 1,
1071 },{
1072 .name = name_svideo,
1073 .vmux = 8,
1074 }},
1075 },
1076 [SAA7134_BOARD_AVERMEDIA_STUDIO_305] = {
1077 .name = "AverMedia AverTV Studio 305",
1078 .audio_clock = 0x00187de7,
1079 .tuner_type = TUNER_PHILIPS_FM1256_IH3,
1080 .tda9887_conf = TDA9887_PRESENT,
1081 .gpiomask = 0x3,
1082 .inputs = {{
1083 .name = name_tv,
1084 .vmux = 1,
1085 .amux = LINE2,
1086 .tv = 1,
1087 },{
1088 .name = name_comp1,
1089 .vmux = 0,
1090 .amux = LINE2,
1091 },{
1092 .name = name_comp2,
1093 .vmux = 3,
1094 .amux = LINE2,
1095 },{
1096 .name = name_svideo,
1097 .vmux = 8,
1098 .amux = LINE2,
1099 }},
1100 .radio = {
1101 .name = name_radio,
1102 .amux = LINE2,
1103 },
1104 .mute = {
1105 .name = name_mute,
1106 .amux = LINE1,
1107 },
1108 },
1109 [SAA7133_BOARD_UPMOST_PURPLE_TV] = {
1110 .name = "UPMOST PURPLE TV",
1111 .audio_clock = 0x00187de7,
1112 .tuner_type = TUNER_PHILIPS_FM1236_MK3,
1113 .tda9887_conf = TDA9887_PRESENT,
1114 .inputs = {{
1115 .name = name_tv,
1116 .vmux = 7,
1117 .amux = TV,
1118 .tv = 1,
1119 },{
1120 .name = name_svideo,
1121 .vmux = 7,
1122 .amux = LINE1,
1123 }},
1124 },
1125 [SAA7134_BOARD_ITEMS_MTV005] = {
1126 /* Norman Jonas <normanjonas@arcor.de> */
1127 .name = "Items MuchTV Plus / IT-005",
1128 .audio_clock = 0x00187de7,
1129 .tuner_type = TUNER_PHILIPS_PAL,
1130 .inputs = {{
1131 .name = name_tv,
1132 .vmux = 3,
1133 .amux = TV,
1134 .tv = 1,
1135 },{
1136 .name = name_comp1,
1137 .vmux = 1,
1138 .amux = LINE1,
1139 },{
1140 .name = name_svideo,
1141 .vmux = 8,
1142 .amux = LINE1,
1143 }},
1144 .radio = {
1145 .name = name_radio,
1146 .amux = LINE2,
1147 },
1148 },
1149 [SAA7134_BOARD_CINERGY200] = {
1150 .name = "Terratec Cinergy 200 TV",
1151 .audio_clock = 0x00200000,
1152 .tuner_type = TUNER_PHILIPS_PAL,
1153 .inputs = {{
1154 .name = name_tv,
1155 .vmux = 1,
1156 .amux = LINE2,
1157 .tv = 1,
1158 },{
1159 .name = name_comp1,
1160 .vmux = 4,
1161 .amux = LINE1,
1162 },{
1163 .name = name_svideo,
1164 .vmux = 8,
1165 .amux = LINE1,
1166 },{
1167 .name = name_comp2, // CVideo over SVideo Connector
1168 .vmux = 0,
1169 .amux = LINE1,
1170 }},
1171 .mute = {
1172 .name = name_mute,
1173 .amux = LINE2,
1174 },
1175 },
1176 [SAA7134_BOARD_VIDEOMATE_TV_PVR] = {
1177 /* Alain St-Denis <alain@topaze.homeip.net> */
1178 .name = "Compro VideoMate TV PVR/FM",
1179 .audio_clock = 0x00187de7,
1180 .tuner_type = TUNER_PHILIPS_NTSC_M,
1181 .gpiomask = 0x808c0080,
1182 .inputs = {{
1183 .name = name_svideo,
1184 .vmux = 8,
1185 .amux = LINE1,
1186 .gpio = 0x00080,
1187 },{
1188 .name = name_comp1,
1189 .vmux = 3,
1190 .amux = LINE1,
1191 .gpio = 0x00080,
1192 },{
1193 .name = name_tv,
1194 .vmux = 1,
1195 .amux = LINE2_LEFT,
1196 .tv = 1,
1197 .gpio = 0x00080,
1198 }},
1199 .radio = {
1200 .name = name_radio,
1201 .amux = LINE2,
1202 .gpio = 0x80000,
1203 },
1204 .mute = {
1205 .name = name_mute,
1206 .amux = LINE2,
1207 .gpio = 0x40000,
1208 },
1209 },
1210 [SAA7134_BOARD_SABRENT_SBTTVFM] = {
1211 /* Michael Rodriguez-Torrent <mrtorrent@asu.edu> */
1212 .name = "Sabrent SBT-TVFM (saa7130)",
1213 .audio_clock = 0x00187de7,
1214 .tuner_type = TUNER_PHILIPS_NTSC_M,
1215 .inputs = {{
1216 .name = name_comp1,
1217 .vmux = 1,
1218 .amux = LINE2,
1219 },{
1220 .name = name_tv,
1221 .vmux = 3,
1222 .amux = LINE2,
1223 .tv = 1,
1224 },{
1225 .name = name_svideo,
1226 .vmux = 8,
1227 .amux = LINE2,
1228 }},
1229 .radio = {
1230 .name = name_radio,
1231 .amux = LINE2,
1232 },
1233 },
1234 [SAA7134_BOARD_ZOLID_XPERT_TV7134] = {
1235 /* Helge Jensen <helge.jensen@slog.dk> */
1236 .name = ":Zolid Xpert TV7134",
1237 .audio_clock = 0x00187de7,
1238 .tuner_type = TUNER_PHILIPS_NTSC,
1239 .inputs = {{
1240 .name = name_svideo,
1241 .vmux = 8,
1242 .amux = LINE1,
1243 },{
1244 .name = name_comp1,
1245 .vmux = 3,
1246 .amux = LINE1,
1247 },{
1248 .name = name_tv,
1249 .vmux = 1,
1250 .amux = LINE2,
1251 .tv = 1,
1252 }},
1253 },
1254 [SAA7134_BOARD_EMPIRE_PCI_TV_RADIO_LE] = {
1255 /* "Matteo Az" <matte.az@nospam.libero.it> ;-) */
1256 .name = "Empire PCI TV-Radio LE",
1257 .audio_clock = 0x00187de7,
1258 .tuner_type = TUNER_PHILIPS_PAL,
1259 .gpiomask = 0x4000,
1260 .inputs = {{
1261 .name = name_tv_mono,
1262 .vmux = 1,
1263 .amux = LINE2,
1264 .gpio = 0x8000,
1265 .tv = 1,
1266 },{
1267 .name = name_comp1,
1268 .vmux = 3,
1269 .amux = LINE1,
1270 .gpio = 0x8000,
1271 },{
1272 .name = name_svideo,
1273 .vmux = 6,
1274 .amux = LINE1,
1275 .gpio = 0x8000,
1276 }},
1277 .radio = {
1278 .name = name_radio,
1279 .amux = LINE1,
1280 .gpio = 0x8000,
1281 },
1282 .mute = {
1283 .name = name_mute,
1284 .amux = TV,
1285 .gpio =0x8000,
1286 }
1287 },
1288 [SAA7134_BOARD_AVERMEDIA_307] = {
1289 /*
1290 Nickolay V. Shmyrev <nshmyrev@yandex.ru>
1291 Lots of thanks to Andrey Zolotarev <zolotarev_andrey@mail.ru>
1292 */
1293 .name = "Avermedia AVerTV Studio 307",
1294 .audio_clock = 0x00187de7,
1295 .tuner_type = TUNER_PHILIPS_FM1256_IH3,
1296 .tda9887_conf = TDA9887_PRESENT,
1297 .gpiomask = 0x03,
1298 .inputs = {{
1299 .name = name_tv,
1300 .vmux = 1,
1301 .amux = TV,
1302 .tv = 1,
1303 .gpio = 0x00,
1304 },{
1305 .name = name_comp1,
1306 .vmux = 0,
1307 .amux = LINE2,
1308 .gpio = 0x00,
1309 },{
1310 .name = name_comp2,
1311 .vmux = 3,
1312 .amux = LINE2,
1313 .gpio = 0x00,
1314 },{
1315 .name = name_svideo,
1316 .vmux = 8,
1317 .amux = LINE2,
1318 .gpio = 0x00,
1319 }},
1320 .radio = {
1321 .name = name_radio,
1322 .amux = LINE1,
1323 .gpio = 0x01,
1324 },
1325 },
1326 [SAA7134_BOARD_AVERMEDIA_CARDBUS] = {
1327 /* Jon Westgate <oryn@oryn.fsck.tv> */
1328 .name = "AVerMedia Cardbus TV/Radio",
1329 .audio_clock = 0x00200000,
1330 .tuner_type = TUNER_PHILIPS_PAL,
1331 .inputs = {{
1332 .name = name_tv,
1333 .vmux = 1,
1334 .amux = LINE2,
1335 .tv = 1,
1336 },{
1337 .name = name_comp1,
1338 .vmux = 3,
1339 .amux = LINE2,
1340 },{
1341 .name = name_svideo,
1342 .vmux = 8,
1343 .amux = LINE2,
1344 }},
1345 .radio = {
1346 .name = name_radio,
1347 .amux = LINE1,
1348 },
1349 },
1350 [SAA7134_BOARD_CINERGY400_CARDBUS] = {
1351 .name = "Terratec Cinergy 400 mobile",
1352 .audio_clock = 0x187de7,
1353 .tuner_type = TUNER_ALPS_TSBE5_PAL,
1354 .tda9887_conf = TDA9887_PRESENT,
1355 .inputs = {{
1356 .name = name_tv,
1357 .vmux = 1,
1358 .amux = TV,
1359 .tv = 1,
1360 },{
1361 .name = name_tv_mono,
1362 .vmux = 1,
1363 .amux = LINE2,
1364 .tv = 1,
1365 },{
1366 .name = name_comp1,
1367 .vmux = 3,
1368 .amux = LINE1,
1369 },{
1370 .name = name_svideo,
1371 .vmux = 8,
1372 .amux = LINE1,
1373 }},
1374 },
1375 [SAA7134_BOARD_CINERGY600_MK3] = {
1376 .name = "Terratec Cinergy 600 TV MK3",
1377 .audio_clock = 0x00200000,
1378 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
1379 .tda9887_conf = TDA9887_PRESENT,
1380 .inputs = {{
1381 .name = name_tv,
1382 .vmux = 1,
1383 .amux = TV,
1384 .tv = 1,
1385 },{
1386 .name = name_comp1,
1387 .vmux = 4,
1388 .amux = LINE1,
1389 },{
1390 .name = name_svideo,
1391 .vmux = 8,
1392 .amux = LINE1,
1393 },{
1394 .name = name_comp2, // CVideo over SVideo Connector
1395 .vmux = 0,
1396 .amux = LINE1,
1397 }},
1398 .radio = {
1399 .name = name_radio,
1400 .amux = LINE2,
1401 },
1402 },
1403 [SAA7134_BOARD_VIDEOMATE_GOLD_PLUS] = {
1404 /* Dylan Walkden <dylan_walkden@hotmail.com> */
1405 .name = "Compro VideoMate Gold+ Pal",
1406 .audio_clock = 0x00187de7,
1407 .tuner_type = TUNER_PHILIPS_PAL,
1408 .gpiomask = 0x1ce780,
1409 .inputs = {{
1410 .name = name_svideo,
1411 .vmux = 0, // CVideo over SVideo Connector - ok?
1412 .amux = LINE1,
1413 .gpio = 0x008080,
1414 },{
1415 .name = name_comp1,
1416 .vmux = 3,
1417 .amux = LINE1,
1418 .gpio = 0x008080,
1419 },{
1420 .name = name_tv,
1421 .vmux = 1,
1422 .amux = TV,
1423 .tv = 1,
1424 .gpio = 0x008080,
1425 }},
1426 .radio = {
1427 .name = name_radio,
1428 .amux = LINE2,
1429 .gpio = 0x80000,
1430 },
1431 .mute = {
1432 .name = name_mute,
1433 .amux = LINE2,
1434 .gpio = 0x0c8000,
1435 },
1436 },
1437 [SAA7134_BOARD_PINNACLE_300I_DVBT_PAL] = {
1438 .name = "Pinnacle PCTV 300i DVB-T + PAL",
1439 .audio_clock = 0x00187de7,
1440 .tuner_type = TUNER_MT2032,
1441 .tda9887_conf = TDA9887_PRESENT | TDA9887_INTERCARRIER,
1442 .mpeg = SAA7134_MPEG_DVB,
1443 .inputs = {{
1444 .name = name_tv,
1445 .vmux = 3,
1446 .amux = TV,
1447 .tv = 1,
1448 },{
1449 .name = name_comp1,
1450 .vmux = 0,
1451 .amux = LINE2,
1452 },{
1453 .name = name_comp2,
1454 .vmux = 1,
1455 .amux = LINE2,
1456 },{
1457 .name = name_svideo,
1458 .vmux = 8,
1459 .amux = LINE2,
1460 }},
1461 },
1462 [SAA7134_BOARD_PROVIDEO_PV952] = {
1463 /* andreas.kretschmer@web.de */
1464 .name = "ProVideo PV952",
1465 .audio_clock = 0x00187de7,
1466 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
1467 .tda9887_conf = TDA9887_PRESENT,
1468 .inputs = {{
1469 .name = name_comp1,
1470 .vmux = 0,
1471 .amux = LINE1,
1472 },{
1473 .name = name_tv,
1474 .vmux = 1,
1475 .amux = TV,
1476 .tv = 1,
1477 },{
1478 .name = name_tv_mono,
1479 .vmux = 1,
1480 .amux = LINE2,
1481 .tv = 1,
1482 }},
1483 .radio = {
1484 .name = name_radio,
1485 .amux = LINE2,
1486 },
1487 },
1488 [SAA7134_BOARD_AVERMEDIA_305] = {
1489 /* much like the "studio" version but without radio
1490 * and another tuner (sirspiritus@yandex.ru) */
1491 .name = "AverMedia AverTV/305",
1492 .audio_clock = 0x00187de7,
1493 .tuner_type = TUNER_PHILIPS_FQ1216ME,
1494 .tda9887_conf = TDA9887_PRESENT,
1495 .gpiomask = 0x3,
1496 .inputs = {{
1497 .name = name_tv,
1498 .vmux = 1,
1499 .amux = LINE2,
1500 .tv = 1,
1501 },{
1502 .name = name_comp1,
1503 .vmux = 0,
1504 .amux = LINE2,
1505 },{
1506 .name = name_comp2,
1507 .vmux = 3,
1508 .amux = LINE2,
1509 },{
1510 .name = name_svideo,
1511 .vmux = 8,
1512 .amux = LINE2,
1513 }},
1514 .mute = {
1515 .name = name_mute,
1516 .amux = LINE1,
1517 },
1518 },
1519 [SAA7134_BOARD_FLYDVBTDUO] = {
1520 /* LifeView FlyDVB-T DUO */
1521 /* "Nico Sabbi <nsabbi@tiscali.it> */
1522 .name = "LifeView FlyDVB-T DUO",
1523 .audio_clock = 0x00200000,
1524 .tuner_type = TUNER_PHILIPS_TDA8290,
1525// .gpiomask = 0xe000,
1526 .inputs = {{
1527 .name = name_tv,
1528 .vmux = 1,
1529 .amux = TV,
1530// .gpio = 0x0000,
1531 .tv = 1,
1532 },{
1533 .name = name_comp1, /* Composite signal on S-Video input */
1534 .vmux = 0,
1535 .amux = LINE2,
1536// .gpio = 0x4000,
1537 },{
1538 .name = name_comp2, /* Composite input */
1539 .vmux = 3,
1540 .amux = LINE2,
1541// .gpio = 0x4000,
1542 },{
1543 .name = name_svideo, /* S-Video signal on S-Video input */
1544 .vmux = 8,
1545 .amux = LINE2,
1546// .gpio = 0x4000,
1547 }},
1548 },
1549};
1550const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards);
1551
1552/* ------------------------------------------------------------------ */
1553/* PCI ids + subsystem IDs */
1554
1555struct pci_device_id saa7134_pci_tbl[] = {
1556 {
1557 .vendor = PCI_VENDOR_ID_PHILIPS,
1558 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
1559 .subvendor = PCI_VENDOR_ID_PHILIPS,
1560 .subdevice = 0x2001,
1561 .driver_data = SAA7134_BOARD_PROTEUS_PRO,
1562 },{
1563 .vendor = PCI_VENDOR_ID_PHILIPS,
1564 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
1565 .subvendor = PCI_VENDOR_ID_PHILIPS,
1566 .subdevice = 0x2001,
1567 .driver_data = SAA7134_BOARD_PROTEUS_PRO,
1568 },{
1569 .vendor = PCI_VENDOR_ID_PHILIPS,
1570 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
1571 .subvendor = PCI_VENDOR_ID_PHILIPS,
1572 .subdevice = 0x6752,
1573 .driver_data = SAA7134_BOARD_EMPRESS,
1574 },{
1575 .vendor = PCI_VENDOR_ID_PHILIPS,
1576 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
1577 .subvendor = 0x1131,
1578 .subdevice = 0x4e85,
1579 .driver_data = SAA7134_BOARD_MONSTERTV,
1580 },{
1581 .vendor = PCI_VENDOR_ID_PHILIPS,
1582 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
1583 .subvendor = 0x153B,
1584 .subdevice = 0x1142,
1585 .driver_data = SAA7134_BOARD_CINERGY400,
1586 },{
1587 .vendor = PCI_VENDOR_ID_PHILIPS,
1588 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
1589 .subvendor = 0x153B,
1590 .subdevice = 0x1143,
1591 .driver_data = SAA7134_BOARD_CINERGY600,
1592 },{
1593 .vendor = PCI_VENDOR_ID_PHILIPS,
1594 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
1595 .subvendor = 0x153B,
1596 .subdevice = 0x1158,
1597 .driver_data = SAA7134_BOARD_CINERGY600_MK3,
1598 },{
1599 .vendor = PCI_VENDOR_ID_PHILIPS,
1600 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
1601 .subvendor = 0x153b,
1602 .subdevice = 0x1162,
1603 .driver_data = SAA7134_BOARD_CINERGY400_CARDBUS,
1604 },{
1605 .vendor = PCI_VENDOR_ID_PHILIPS,
1606 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
1607 .subvendor = 0x5168,
1608 .subdevice = 0x0138,
1609 .driver_data = SAA7134_BOARD_FLYVIDEO3000,
1610 },{
1611 .vendor = PCI_VENDOR_ID_PHILIPS,
1612 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
1613 .subvendor = 0x4e42, //"Typhoon PCI Capture TV Card" Art.No. 50673
1614 .subdevice = 0x0138,
1615 .driver_data = SAA7134_BOARD_FLYVIDEO3000,
1616 },{
1617 .vendor = PCI_VENDOR_ID_PHILIPS,
1618 .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
1619 .subvendor = 0x5168,
1620 .subdevice = 0x0138,
1621 .driver_data = SAA7134_BOARD_FLYVIDEO2000,
1622 },{
1623 .vendor = PCI_VENDOR_ID_PHILIPS,
1624 .device = PCI_DEVICE_ID_PHILIPS_SAA7135,
1625 .subvendor = 0x5168,
1626 .subdevice = 0x0212, /* minipci, LR212 */
1627 .driver_data = SAA7134_BOARD_FLYTVPLATINUM_MINI,
1628 },{
1629 .vendor = PCI_VENDOR_ID_PHILIPS,
1630 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
1631 .subvendor = 0x5168,
1632 .subdevice = 0x0214, /* Standard PCI, LR214WF */
1633 .driver_data = SAA7134_BOARD_FLYTVPLATINUM_FM,
1634 },{
1635 .vendor = PCI_VENDOR_ID_PHILIPS,
1636 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
1637 .subvendor = 0x16be,
1638 .subdevice = 0x0003,
1639 .driver_data = SAA7134_BOARD_MD7134,
1640 },{
1641 .vendor = PCI_VENDOR_ID_PHILIPS,
1642 .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
1643 .subvendor = 0x1048,
1644 .subdevice = 0x226b,
1645 .driver_data = SAA7134_BOARD_ELSA,
1646 },{
1647 .vendor = PCI_VENDOR_ID_PHILIPS,
1648 .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
1649 .subvendor = 0x1048,
1650 .subdevice = 0x226b,
1651 .driver_data = SAA7134_BOARD_ELSA_500TV,
1652 },{
1653 .vendor = PCI_VENDOR_ID_PHILIPS,
1654 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
1655 .subvendor = PCI_VENDOR_ID_ASUSTEK,
1656 .subdevice = 0x4842,
1657 .driver_data = SAA7134_BOARD_ASUSTeK_TVFM7134,
1658 },{
1659 .vendor = PCI_VENDOR_ID_PHILIPS,
1660 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
1661 .subvendor = PCI_VENDOR_ID_ASUSTEK,
1662 .subdevice = 0x4845,
1663 .driver_data = SAA7135_BOARD_ASUSTeK_TVFM7135,
1664 },{
1665 .vendor = PCI_VENDOR_ID_PHILIPS,
1666 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
1667 .subvendor = PCI_VENDOR_ID_ASUSTEK,
1668 .subdevice = 0x4830,
1669 .driver_data = SAA7134_BOARD_ASUSTeK_TVFM7134,
1670 },{
1671 .vendor = PCI_VENDOR_ID_PHILIPS,
1672 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
1673 .subvendor = PCI_VENDOR_ID_ASUSTEK,
1674 .subdevice = 0x4843,
1675 .driver_data = SAA7134_BOARD_ASUSTEK_TVFM7133,
1676 },{
1677 .vendor = PCI_VENDOR_ID_PHILIPS,
1678 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
1679 .subvendor = PCI_VENDOR_ID_ASUSTEK,
1680 .subdevice = 0x4840,
1681 .driver_data = SAA7134_BOARD_ASUSTeK_TVFM7134,
1682 },{
1683 .vendor = PCI_VENDOR_ID_PHILIPS,
1684 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
1685 .subvendor = PCI_VENDOR_ID_PHILIPS,
1686 .subdevice = 0xfe01,
1687 .driver_data = SAA7134_BOARD_TVSTATION_RDS,
1688 },{
1689 .vendor = PCI_VENDOR_ID_PHILIPS,
1690 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
1691 .subvendor = 0x1894,
1692 .subdevice = 0xfe01,
1693 .driver_data = SAA7134_BOARD_TVSTATION_RDS,
1694 },{
1695 .vendor = PCI_VENDOR_ID_PHILIPS,
1696 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
1697 .subvendor = 0x1894,
1698 .subdevice = 0xa006,
1699 .driver_data = SAA7134_BOARD_TVSTATION_DVR,
1700 },{
1701 .vendor = PCI_VENDOR_ID_PHILIPS,
1702 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
1703 .subvendor = 0x1131,
1704 .subdevice = 0x7133,
1705 .driver_data = SAA7134_BOARD_VA1000POWER,
1706 },{
1707 .vendor = PCI_VENDOR_ID_PHILIPS,
1708 .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
1709 .subvendor = PCI_VENDOR_ID_PHILIPS,
1710 .subdevice = 0x2001,
1711 .driver_data = SAA7134_BOARD_10MOONSTVMASTER,
1712 },{
1713 .vendor = PCI_VENDOR_ID_PHILIPS,
1714 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
1715 .subvendor = 0x185b,
1716 .subdevice = 0xc100,
1717 .driver_data = SAA7134_BOARD_VIDEOMATE_TV,
1718 },{
1719 .vendor = PCI_VENDOR_ID_PHILIPS,
1720 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
1721 .subvendor = 0x185b,
1722 .subdevice = 0xc100,
1723 .driver_data = SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUS,
1724 },{
1725 .vendor = PCI_VENDOR_ID_PHILIPS,
1726 .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
1727 .subvendor = PCI_VENDOR_ID_MATROX,
1728 .subdevice = 0x48d0,
1729 .driver_data = SAA7134_BOARD_CRONOS_PLUS,
1730 },{
1731 .vendor = PCI_VENDOR_ID_PHILIPS,
1732 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
1733 .subvendor = 0x1461, /* Avermedia Technologies Inc */
1734 .subdevice = 0xa70b,
1735 .driver_data = SAA7134_BOARD_MD2819,
1736 },{
1737 .vendor = PCI_VENDOR_ID_PHILIPS,
1738 .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
1739 .subvendor = 0x1461, /* Avermedia Technologies Inc */
1740 .subdevice = 0x2115,
1741 .driver_data = SAA7134_BOARD_AVERMEDIA_STUDIO_305,
1742 },{
1743 .vendor = PCI_VENDOR_ID_PHILIPS,
1744 .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
1745 .subvendor = 0x1461, /* Avermedia Technologies Inc */
1746 .subdevice = 0x2108,
1747 .driver_data = SAA7134_BOARD_AVERMEDIA_305,
1748 },{
1749 .vendor = PCI_VENDOR_ID_PHILIPS,
1750 .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
1751 .subvendor = 0x1461, /* Avermedia Technologies Inc */
1752 .subdevice = 0x10ff,
1753 .driver_data = SAA7134_BOARD_AVERMEDIA_DVD_EZMAKER,
1754 },{
1755 /* AVerMedia CardBus */
1756 .vendor = PCI_VENDOR_ID_PHILIPS,
1757 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
1758 .subvendor = 0x1461, /* Avermedia Technologies Inc */
1759 .subdevice = 0xd6ee,
1760 .driver_data = SAA7134_BOARD_AVERMEDIA_CARDBUS,
1761 },{
1762 /* TransGear 3000TV */
1763 .vendor = PCI_VENDOR_ID_PHILIPS,
1764 .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
1765 .subvendor = 0x1461, /* Avermedia Technologies Inc */
1766 .subdevice = 0x050c,
1767 .driver_data = SAA7134_BOARD_TG3000TV,
1768 },{
1769 .vendor = PCI_VENDOR_ID_PHILIPS,
1770 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
1771 .subvendor = 0x11bd,
1772 .subdevice = 0x002b,
1773 .driver_data = SAA7134_BOARD_PINNACLE_PCTV_STEREO,
1774 },{
1775 .vendor = PCI_VENDOR_ID_PHILIPS,
1776 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
1777 .subvendor = 0x11bd,
1778 .subdevice = 0x002d,
1779 .driver_data = SAA7134_BOARD_PINNACLE_300I_DVBT_PAL,
1780 },{
1781 .vendor = PCI_VENDOR_ID_PHILIPS,
1782 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
1783 .subvendor = 0x1019,
1784 .subdevice = 0x4cb4,
1785 .driver_data = SAA7134_BOARD_ECS_TVP3XP,
1786 },{
1787 .vendor = PCI_VENDOR_ID_PHILIPS,
1788 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
1789 .subvendor = 0x1019,
1790 .subdevice = 0x4cb5,
1791 .driver_data = SAA7134_BOARD_ECS_TVP3XP_4CB5,
1792 },{
1793 .vendor = PCI_VENDOR_ID_PHILIPS,
1794 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
1795 .subvendor = 0x12ab,
1796 .subdevice = 0x0800,
1797 .driver_data = SAA7133_BOARD_UPMOST_PURPLE_TV,
1798 },{
1799 .vendor = PCI_VENDOR_ID_PHILIPS,
1800 .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
1801 .subvendor = 0x153B,
1802 .subdevice = 0x1152,
1803 .driver_data = SAA7134_BOARD_CINERGY200,
1804 },{
1805 .vendor = PCI_VENDOR_ID_PHILIPS,
1806 .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
1807 .subvendor = 0x185b,
1808 .subdevice = 0xc100,
1809 .driver_data = SAA7134_BOARD_VIDEOMATE_TV_PVR,
1810 },{
1811 .vendor = PCI_VENDOR_ID_PHILIPS,
1812 .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
1813 .subvendor = 0x1131,
1814 .subdevice = 0,
1815 .driver_data = SAA7134_BOARD_SABRENT_SBTTVFM,
1816 },{
1817 .vendor = PCI_VENDOR_ID_PHILIPS,
1818 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
1819 .subvendor = 0x1461, /* Avermedia Technologies Inc */
1820 .subdevice = 0x9715,
1821 .driver_data = SAA7134_BOARD_AVERMEDIA_307,
1822 },{
1823 .vendor = PCI_VENDOR_ID_PHILIPS,
1824 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
1825 .subvendor = 0x185b,
1826 .subdevice = 0xc200,
1827 .driver_data = SAA7134_BOARD_VIDEOMATE_GOLD_PLUS,
1828 },{
1829 .vendor = PCI_VENDOR_ID_PHILIPS,
1830 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
1831 .subvendor = 0x1540,
1832 .subdevice = 0x9524,
1833 .driver_data = SAA7134_BOARD_PROVIDEO_PV952,
1834
1835 },{
1836 .vendor = PCI_VENDOR_ID_PHILIPS,
1837 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
1838 .subvendor = 0x5168,
1839 .subdevice = 0x0306,
1840 .driver_data = SAA7134_BOARD_FLYDVBTDUO,
1841
1842 },{
1843 /* --- boards without eeprom + subsystem ID --- */
1844 .vendor = PCI_VENDOR_ID_PHILIPS,
1845 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
1846 .subvendor = PCI_VENDOR_ID_PHILIPS,
1847 .subdevice = 0,
1848 .driver_data = SAA7134_BOARD_NOAUTO,
1849 },{
1850 .vendor = PCI_VENDOR_ID_PHILIPS,
1851 .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
1852 .subvendor = PCI_VENDOR_ID_PHILIPS,
1853 .subdevice = 0,
1854 .driver_data = SAA7134_BOARD_NOAUTO,
1855 },{
1856
1857 /* --- default catch --- */
1858 .vendor = PCI_VENDOR_ID_PHILIPS,
1859 .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
1860 .subvendor = PCI_ANY_ID,
1861 .subdevice = PCI_ANY_ID,
1862 .driver_data = SAA7134_BOARD_UNKNOWN,
1863 },{
1864 .vendor = PCI_VENDOR_ID_PHILIPS,
1865 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
1866 .subvendor = PCI_ANY_ID,
1867 .subdevice = PCI_ANY_ID,
1868 .driver_data = SAA7134_BOARD_UNKNOWN,
1869 },{
1870 .vendor = PCI_VENDOR_ID_PHILIPS,
1871 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
1872 .subvendor = PCI_ANY_ID,
1873 .subdevice = PCI_ANY_ID,
1874 .driver_data = SAA7134_BOARD_UNKNOWN,
1875 },{
1876 .vendor = PCI_VENDOR_ID_PHILIPS,
1877 .device = PCI_DEVICE_ID_PHILIPS_SAA7135,
1878 .subvendor = PCI_ANY_ID,
1879 .subdevice = PCI_ANY_ID,
1880 .driver_data = SAA7134_BOARD_UNKNOWN,
1881 },{
1882 /* --- end of list --- */
1883 }
1884};
1885MODULE_DEVICE_TABLE(pci, saa7134_pci_tbl);
1886
1887/* ----------------------------------------------------------- */
1888/* flyvideo tweaks */
1889
1890#if 0
1891static struct {
1892 char *model;
1893 int tuner_type;
1894} fly_list[0x20] = {
1895 /* default catch ... */
1896 [ 0 ... 0x1f ] = {
1897 .model = "UNKNOWN",
1898 .tuner_type = TUNER_ABSENT,
1899 },
1900 /* ... the ones known so far */
1901 [ 0x05 ] = {
1902 .model = "PAL-BG",
1903 .tuner_type = TUNER_LG_PAL_NEW_TAPC,
1904 },
1905 [ 0x10 ] = {
1906 .model = "PAL-BG / PAL-DK",
1907 .tuner_type = TUNER_PHILIPS_PAL,
1908 },
1909 [ 0x15 ] = {
1910 .model = "NTSC",
1911 .tuner_type = TUNER_ABSENT /* FIXME */,
1912 },
1913};
1914#endif
1915
1916static void board_flyvideo(struct saa7134_dev *dev)
1917{
1918#if 0
1919 /* non-working attempt to detect the correct tuner type ... */
1920 u32 value;
1921 int index;
1922
1923 value = dev->gpio_value;
1924 index = (value & 0x1f00) >> 8;
1925 printk(KERN_INFO "%s: flyvideo: gpio is 0x%x [model=%s,tuner=%d]\n",
1926 dev->name, value, fly_list[index].model,
1927 fly_list[index].tuner_type);
1928 dev->tuner_type = fly_list[index].tuner_type;
1929#endif
1930 printk("%s: there are different flyvideo cards with different tuners\n"
1931 "%s: out there, you might have to use the tuner=<nr> insmod\n"
1932 "%s: option to override the default value.\n",
1933 dev->name, dev->name, dev->name);
1934}
1935
1936/* ----------------------------------------------------------- */
1937
1938int saa7134_board_init1(struct saa7134_dev *dev)
1939{
1940 // Always print gpio, often manufacturers encode tuner type and other info.
1941 saa_writel(SAA7134_GPIO_GPMODE0 >> 2, 0);
1942 dev->gpio_value = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2);
1943 printk(KERN_INFO "%s: board init: gpio is %x\n", dev->name, dev->gpio_value);
1944
1945 switch (dev->board) {
1946 case SAA7134_BOARD_FLYVIDEO2000:
1947 case SAA7134_BOARD_FLYVIDEO3000:
1948 dev->has_remote = 1;
1949 board_flyvideo(dev);
1950 break;
1951 case SAA7134_BOARD_CINERGY400:
1952 case SAA7134_BOARD_CINERGY600:
1953 case SAA7134_BOARD_CINERGY600_MK3:
1954 case SAA7134_BOARD_ECS_TVP3XP:
1955 case SAA7134_BOARD_ECS_TVP3XP_4CB5:
1956 case SAA7134_BOARD_MD2819:
1957 case SAA7134_BOARD_AVERMEDIA_STUDIO_305:
1958 case SAA7134_BOARD_AVERMEDIA_305:
1959 case SAA7134_BOARD_AVERMEDIA_307:
1960// case SAA7134_BOARD_SABRENT_SBTTVFM: /* not finished yet */
1961 case SAA7134_BOARD_VIDEOMATE_TV_PVR:
1962 dev->has_remote = 1;
1963 break;
1964 case SAA7134_BOARD_AVACSSMARTTV:
1965 dev->has_remote = 1;
1966 break;
1967 case SAA7134_BOARD_MD5044:
1968 printk("%s: seems there are two different versions of the MD5044\n"
1969 "%s: (with the same ID) out there. If sound doesn't work for\n"
1970 "%s: you try the audio_clock_override=0x200000 insmod option.\n",
1971 dev->name,dev->name,dev->name);
1972 break;
1973 case SAA7134_BOARD_CINERGY400_CARDBUS:
1974 /* power-up tuner chip */
1975 saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x00040000, 0x00040000);
1976 saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x00040000, 0x00000000);
1977 msleep(1);
1978 break;
1979 }
1980 if (dev->has_remote)
1981 dev->irq2_mask |= (SAA7134_IRQ2_INTE_GPIO18 |
1982 SAA7134_IRQ2_INTE_GPIO18A |
1983 SAA7134_IRQ2_INTE_GPIO16 );
1984 return 0;
1985}
1986
1987/* stuff which needs working i2c */
1988int saa7134_board_init2(struct saa7134_dev *dev)
1989{
1990 unsigned char buf;
1991 int board;
1992
1993 switch (dev->board) {
1994 case SAA7134_BOARD_BMK_MPEX_NOTUNER:
1995 case SAA7134_BOARD_BMK_MPEX_TUNER:
1996 dev->i2c_client.addr = 0x60;
1997 board = (i2c_master_recv(&dev->i2c_client,&buf,0) < 0)
1998 ? SAA7134_BOARD_BMK_MPEX_NOTUNER
1999 : SAA7134_BOARD_BMK_MPEX_TUNER;
2000 if (board == dev->board)
2001 break;
2002 dev->board = board;
2003 printk("%s: board type fixup: %s\n", dev->name,
2004 saa7134_boards[dev->board].name);
2005 dev->tuner_type = saa7134_boards[dev->board].tuner_type;
2006 if (TUNER_ABSENT != dev->tuner_type)
2007 saa7134_i2c_call_clients(dev,TUNER_SET_TYPE,&dev->tuner_type);
2008 break;
2009 }
2010 return 0;
2011}
2012
2013/* ----------------------------------------------------------- */
2014/*
2015 * Local variables:
2016 * c-basic-offset: 8
2017 * End:
2018 */
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c
new file mode 100644
index 00000000000..d506cafba8f
--- /dev/null
+++ b/drivers/media/video/saa7134/saa7134-core.c
@@ -0,0 +1,1237 @@
1/*
2 * $Id: saa7134-core.c,v 1.28 2005/02/22 09:56:29 kraxel Exp $
3 *
4 * device driver for philips saa7134 based TV cards
5 * driver core
6 *
7 * (c) 2001-03 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
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#include <linux/config.h>
25#include <linux/init.h>
26#include <linux/list.h>
27#include <linux/module.h>
28#include <linux/moduleparam.h>
29#include <linux/kernel.h>
30#include <linux/slab.h>
31#include <linux/kmod.h>
32#include <linux/sound.h>
33#include <linux/interrupt.h>
34#include <linux/delay.h>
35
36#include "saa7134-reg.h"
37#include "saa7134.h"
38
39MODULE_DESCRIPTION("v4l2 driver module for saa7130/34 based TV cards");
40MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
41MODULE_LICENSE("GPL");
42
43/* ------------------------------------------------------------------ */
44
45static unsigned int irq_debug = 0;
46module_param(irq_debug, int, 0644);
47MODULE_PARM_DESC(irq_debug,"enable debug messages [IRQ handler]");
48
49static unsigned int core_debug = 0;
50module_param(core_debug, int, 0644);
51MODULE_PARM_DESC(core_debug,"enable debug messages [core]");
52
53static unsigned int gpio_tracking = 0;
54module_param(gpio_tracking, int, 0644);
55MODULE_PARM_DESC(gpio_tracking,"enable debug messages [gpio]");
56
57static unsigned int oss = 0;
58module_param(oss, int, 0444);
59MODULE_PARM_DESC(oss,"register oss devices (default: no)");
60
61static unsigned int latency = UNSET;
62module_param(latency, int, 0444);
63MODULE_PARM_DESC(latency,"pci latency timer");
64
65static unsigned int video_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
66static unsigned int vbi_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
67static unsigned int radio_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
68static unsigned int dsp_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
69static unsigned int mixer_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
70static unsigned int tuner[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
71static unsigned int card[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
72
73module_param_array(video_nr, int, NULL, 0444);
74module_param_array(vbi_nr, int, NULL, 0444);
75module_param_array(radio_nr, int, NULL, 0444);
76module_param_array(dsp_nr, int, NULL, 0444);
77module_param_array(mixer_nr, int, NULL, 0444);
78module_param_array(tuner, int, NULL, 0444);
79module_param_array(card, int, NULL, 0444);
80
81MODULE_PARM_DESC(video_nr, "video device number");
82MODULE_PARM_DESC(vbi_nr, "vbi device number");
83MODULE_PARM_DESC(radio_nr, "radio device number");
84MODULE_PARM_DESC(dsp_nr, "oss dsp device number");
85MODULE_PARM_DESC(mixer_nr, "oss mixer device number");
86MODULE_PARM_DESC(tuner, "tuner type");
87MODULE_PARM_DESC(card, "card type");
88
89static DECLARE_MUTEX(devlist_lock);
90LIST_HEAD(saa7134_devlist);
91static LIST_HEAD(mops_list);
92static unsigned int saa7134_devcount;
93
94#define dprintk(fmt, arg...) if (core_debug) \
95 printk(KERN_DEBUG "%s/core: " fmt, dev->name , ## arg)
96
97/* ------------------------------------------------------------------ */
98/* debug help functions */
99
100static const char *v4l1_ioctls[] = {
101 "0", "GCAP", "GCHAN", "SCHAN", "GTUNER", "STUNER", "GPICT", "SPICT",
102 "CCAPTURE", "GWIN", "SWIN", "GFBUF", "SFBUF", "KEY", "GFREQ",
103 "SFREQ", "GAUDIO", "SAUDIO", "SYNC", "MCAPTURE", "GMBUF", "GUNIT",
104 "GCAPTURE", "SCAPTURE", "SPLAYMODE", "SWRITEMODE", "GPLAYINFO",
105 "SMICROCODE", "GVBIFMT", "SVBIFMT" };
106#define V4L1_IOCTLS ARRAY_SIZE(v4l1_ioctls)
107
108static const char *v4l2_ioctls[] = {
109 "QUERYCAP", "1", "ENUM_PIXFMT", "ENUM_FBUFFMT", "G_FMT", "S_FMT",
110 "G_COMP", "S_COMP", "REQBUFS", "QUERYBUF", "G_FBUF", "S_FBUF",
111 "G_WIN", "S_WIN", "PREVIEW", "QBUF", "16", "DQBUF", "STREAMON",
112 "STREAMOFF", "G_PERF", "G_PARM", "S_PARM", "G_STD", "S_STD",
113 "ENUMSTD", "ENUMINPUT", "G_CTRL", "S_CTRL", "G_TUNER", "S_TUNER",
114 "G_FREQ", "S_FREQ", "G_AUDIO", "S_AUDIO", "35", "QUERYCTRL",
115 "QUERYMENU", "G_INPUT", "S_INPUT", "ENUMCVT", "41", "42", "43",
116 "44", "45", "G_OUTPUT", "S_OUTPUT", "ENUMOUTPUT", "G_AUDOUT",
117 "S_AUDOUT", "ENUMFX", "G_EFFECT", "S_EFFECT", "G_MODULATOR",
118 "S_MODULATOR"
119};
120#define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
121
122static const char *osspcm_ioctls[] = {
123 "RESET", "SYNC", "SPEED", "STEREO", "GETBLKSIZE", "SETFMT",
124 "CHANNELS", "?", "POST", "SUBDIVIDE", "SETFRAGMENT", "GETFMTS",
125 "GETOSPACE", "GETISPACE", "NONBLOCK", "GETCAPS", "GET/SETTRIGGER",
126 "GETIPTR", "GETOPTR", "MAPINBUF", "MAPOUTBUF", "SETSYNCRO",
127 "SETDUPLEX", "GETODELAY"
128};
129#define OSSPCM_IOCTLS ARRAY_SIZE(v4l2_ioctls)
130
131void saa7134_print_ioctl(char *name, unsigned int cmd)
132{
133 char *dir;
134
135 switch (_IOC_DIR(cmd)) {
136 case _IOC_NONE: dir = "--"; break;
137 case _IOC_READ: dir = "r-"; break;
138 case _IOC_WRITE: dir = "-w"; break;
139 case _IOC_READ | _IOC_WRITE: dir = "rw"; break;
140 default: dir = "??"; break;
141 }
142 switch (_IOC_TYPE(cmd)) {
143 case 'v':
144 printk(KERN_DEBUG "%s: ioctl 0x%08x (v4l1, %s, VIDIOC%s)\n",
145 name, cmd, dir, (_IOC_NR(cmd) < V4L1_IOCTLS) ?
146 v4l1_ioctls[_IOC_NR(cmd)] : "???");
147 break;
148 case 'V':
149 printk(KERN_DEBUG "%s: ioctl 0x%08x (v4l2, %s, VIDIOC_%s)\n",
150 name, cmd, dir, (_IOC_NR(cmd) < V4L2_IOCTLS) ?
151 v4l2_ioctls[_IOC_NR(cmd)] : "???");
152 break;
153 case 'P':
154 printk(KERN_DEBUG "%s: ioctl 0x%08x (oss dsp, %s, SNDCTL_DSP_%s)\n",
155 name, cmd, dir, (_IOC_NR(cmd) < OSSPCM_IOCTLS) ?
156 osspcm_ioctls[_IOC_NR(cmd)] : "???");
157 break;
158 case 'M':
159 printk(KERN_DEBUG "%s: ioctl 0x%08x (oss mixer, %s, #%d)\n",
160 name, cmd, dir, _IOC_NR(cmd));
161 break;
162 default:
163 printk(KERN_DEBUG "%s: ioctl 0x%08x (???, %s, #%d)\n",
164 name, cmd, dir, _IOC_NR(cmd));
165 }
166}
167
168void saa7134_track_gpio(struct saa7134_dev *dev, char *msg)
169{
170 unsigned long mode,status;
171
172 if (!gpio_tracking)
173 return;
174 /* rising SAA7134_GPIO_GPRESCAN reads the status */
175 saa_andorb(SAA7134_GPIO_GPMODE3,SAA7134_GPIO_GPRESCAN,0);
176 saa_andorb(SAA7134_GPIO_GPMODE3,SAA7134_GPIO_GPRESCAN,SAA7134_GPIO_GPRESCAN);
177 mode = saa_readl(SAA7134_GPIO_GPMODE0 >> 2) & 0xfffffff;
178 status = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2) & 0xfffffff;
179 printk(KERN_DEBUG
180 "%s: gpio: mode=0x%07lx in=0x%07lx out=0x%07lx [%s]\n",
181 dev->name, mode, (~mode) & status, mode & status, msg);
182}
183
184/* ------------------------------------------------------------------ */
185
186#if 0
187static char *dec1_bits[8] = {
188 "DCSTD0", "DCSCT1", "WIPA", "GLIMB",
189 "GLIMT", "SLTCA", "HLCK"
190};
191static char *dec2_bits[8] = {
192 "RDCAP", "COPRO", "COLSTR", "TYPE3",
193 NULL, "FIDT", "HLVLN", "INTL"
194};
195static char *scale1_bits[8] = {
196 "VID_A", "VBI_A", NULL, NULL, "VID_B", "VBI_B"
197};
198static char *scale2_bits[8] = {
199 "TRERR", "CFERR", "LDERR", "WASRST",
200 "FIDSCI", "FIDSCO", "D6^D5", "TASK"
201};
202
203static void dump_statusreg(struct saa7134_dev *dev, int reg,
204 char *regname, char **bits)
205{
206 int value,i;
207
208 value = saa_readb(reg);
209 printk(KERN_DEBUG "%s: %s:", dev->name, regname);
210 for (i = 7; i >= 0; i--) {
211 if (NULL == bits[i])
212 continue;
213 printk(" %s=%d", bits[i], (value & (1 << i)) ? 1 : 0);
214 }
215 printk("\n");
216}
217
218static void dump_statusregs(struct saa7134_dev *dev)
219{
220 dump_statusreg(dev,SAA7134_STATUS_VIDEO1,"dec1",dec1_bits);
221 dump_statusreg(dev,SAA7134_STATUS_VIDEO2,"dec2",dec2_bits);
222 dump_statusreg(dev,SAA7134_SCALER_STATUS0,"scale0",scale1_bits);
223 dump_statusreg(dev,SAA7134_SCALER_STATUS1,"scale1",scale2_bits);
224}
225#endif
226
227/* ----------------------------------------------------------- */
228/* delayed request_module */
229
230#ifdef CONFIG_MODULES
231
232static int need_empress;
233static int need_dvb;
234
235static int pending_call(struct notifier_block *self, unsigned long state,
236 void *module)
237{
238 if (module != THIS_MODULE || state != MODULE_STATE_LIVE)
239 return NOTIFY_DONE;
240
241 if (need_empress)
242 request_module("saa7134-empress");
243 if (need_dvb)
244 request_module("saa7134-dvb");
245 return NOTIFY_DONE;
246}
247
248static int pending_registered;
249static struct notifier_block pending_notifier = {
250 .notifier_call = pending_call,
251};
252
253static void request_module_depend(char *name, int *flag)
254{
255 switch (THIS_MODULE->state) {
256 case MODULE_STATE_COMING:
257 if (!pending_registered) {
258 register_module_notifier(&pending_notifier);
259 pending_registered = 1;
260 }
261 *flag = 1;
262 break;
263 case MODULE_STATE_LIVE:
264 request_module(name);
265 break;
266 default:
267 /* nothing */;
268 break;
269 }
270}
271
272#else
273
274#define request_module_depend(name,flag)
275
276#endif /* CONFIG_MODULES */
277
278/* ------------------------------------------------------------------ */
279
280/* nr of (saa7134-)pages for the given buffer size */
281static int saa7134_buffer_pages(int size)
282{
283 size = PAGE_ALIGN(size);
284 size += PAGE_SIZE; /* for non-page-aligned buffers */
285 size /= 4096;
286 return size;
287}
288
289/* calc max # of buffers from size (must not exceed the 4MB virtual
290 * address space per DMA channel) */
291int saa7134_buffer_count(unsigned int size, unsigned int count)
292{
293 unsigned int maxcount;
294
295 maxcount = 1024 / saa7134_buffer_pages(size);
296 if (count > maxcount)
297 count = maxcount;
298 return count;
299}
300
301int saa7134_buffer_startpage(struct saa7134_buf *buf)
302{
303 return saa7134_buffer_pages(buf->vb.bsize) * buf->vb.i;
304}
305
306unsigned long saa7134_buffer_base(struct saa7134_buf *buf)
307{
308 unsigned long base;
309
310 base = saa7134_buffer_startpage(buf) * 4096;
311 base += buf->vb.dma.sglist[0].offset;
312 return base;
313}
314
315/* ------------------------------------------------------------------ */
316
317int saa7134_pgtable_alloc(struct pci_dev *pci, struct saa7134_pgtable *pt)
318{
319 u32 *cpu;
320 dma_addr_t dma_addr;
321
322 cpu = pci_alloc_consistent(pci, SAA7134_PGTABLE_SIZE, &dma_addr);
323 if (NULL == cpu)
324 return -ENOMEM;
325 pt->size = SAA7134_PGTABLE_SIZE;
326 pt->cpu = cpu;
327 pt->dma = dma_addr;
328 return 0;
329}
330
331int saa7134_pgtable_build(struct pci_dev *pci, struct saa7134_pgtable *pt,
332 struct scatterlist *list, unsigned int length,
333 unsigned int startpage)
334{
335 u32 *ptr;
336 unsigned int i,p;
337
338 BUG_ON(NULL == pt || NULL == pt->cpu);
339
340 ptr = pt->cpu + startpage;
341 for (i = 0; i < length; i++, list++)
342 for (p = 0; p * 4096 < list->length; p++, ptr++)
343 *ptr = sg_dma_address(list) - list->offset;
344 return 0;
345}
346
347void saa7134_pgtable_free(struct pci_dev *pci, struct saa7134_pgtable *pt)
348{
349 if (NULL == pt->cpu)
350 return;
351 pci_free_consistent(pci, pt->size, pt->cpu, pt->dma);
352 pt->cpu = NULL;
353}
354
355/* ------------------------------------------------------------------ */
356
357void saa7134_dma_free(struct saa7134_dev *dev,struct saa7134_buf *buf)
358{
359 if (in_interrupt())
360 BUG();
361
362 videobuf_waiton(&buf->vb,0,0);
363 videobuf_dma_pci_unmap(dev->pci, &buf->vb.dma);
364 videobuf_dma_free(&buf->vb.dma);
365 buf->vb.state = STATE_NEEDS_INIT;
366}
367
368/* ------------------------------------------------------------------ */
369
370int saa7134_buffer_queue(struct saa7134_dev *dev,
371 struct saa7134_dmaqueue *q,
372 struct saa7134_buf *buf)
373{
374 struct saa7134_buf *next = NULL;
375
376 assert_spin_locked(&dev->slock);
377 dprintk("buffer_queue %p\n",buf);
378 if (NULL == q->curr) {
379 if (!q->need_two) {
380 q->curr = buf;
381 buf->activate(dev,buf,NULL);
382 } else if (list_empty(&q->queue)) {
383 list_add_tail(&buf->vb.queue,&q->queue);
384 buf->vb.state = STATE_QUEUED;
385 } else {
386 next = list_entry(q->queue.next,struct saa7134_buf,
387 vb.queue);
388 q->curr = buf;
389 buf->activate(dev,buf,next);
390 }
391 } else {
392 list_add_tail(&buf->vb.queue,&q->queue);
393 buf->vb.state = STATE_QUEUED;
394 }
395 return 0;
396}
397
398void saa7134_buffer_finish(struct saa7134_dev *dev,
399 struct saa7134_dmaqueue *q,
400 unsigned int state)
401{
402 assert_spin_locked(&dev->slock);
403 dprintk("buffer_finish %p\n",q->curr);
404
405 /* finish current buffer */
406 q->curr->vb.state = state;
407 do_gettimeofday(&q->curr->vb.ts);
408 wake_up(&q->curr->vb.done);
409 q->curr = NULL;
410}
411
412void saa7134_buffer_next(struct saa7134_dev *dev,
413 struct saa7134_dmaqueue *q)
414{
415 struct saa7134_buf *buf,*next = NULL;
416
417 assert_spin_locked(&dev->slock);
418 BUG_ON(NULL != q->curr);
419
420 if (!list_empty(&q->queue)) {
421 /* activate next one from queue */
422 buf = list_entry(q->queue.next,struct saa7134_buf,vb.queue);
423 dprintk("buffer_next %p [prev=%p/next=%p]\n",
424 buf,q->queue.prev,q->queue.next);
425 list_del(&buf->vb.queue);
426 if (!list_empty(&q->queue))
427 next = list_entry(q->queue.next,struct saa7134_buf,
428 vb.queue);
429 q->curr = buf;
430 buf->activate(dev,buf,next);
431 dprintk("buffer_next #2 prev=%p/next=%p\n",
432 q->queue.prev,q->queue.next);
433 } else {
434 /* nothing to do -- just stop DMA */
435 dprintk("buffer_next %p\n",NULL);
436 saa7134_set_dmabits(dev);
437 del_timer(&q->timeout);
438 }
439}
440
441void saa7134_buffer_timeout(unsigned long data)
442{
443 struct saa7134_dmaqueue *q = (struct saa7134_dmaqueue*)data;
444 struct saa7134_dev *dev = q->dev;
445 unsigned long flags;
446
447 spin_lock_irqsave(&dev->slock,flags);
448
449 /* try to reset the hardware (SWRST) */
450 saa_writeb(SAA7134_REGION_ENABLE, 0x00);
451 saa_writeb(SAA7134_REGION_ENABLE, 0x80);
452 saa_writeb(SAA7134_REGION_ENABLE, 0x00);
453
454 /* flag current buffer as failed,
455 try to start over with the next one. */
456 if (q->curr) {
457 dprintk("timeout on %p\n",q->curr);
458 saa7134_buffer_finish(dev,q,STATE_ERROR);
459 }
460 saa7134_buffer_next(dev,q);
461 spin_unlock_irqrestore(&dev->slock,flags);
462}
463
464/* ------------------------------------------------------------------ */
465
466int saa7134_set_dmabits(struct saa7134_dev *dev)
467{
468 u32 split, task=0, ctrl=0, irq=0;
469 enum v4l2_field cap = V4L2_FIELD_ANY;
470 enum v4l2_field ov = V4L2_FIELD_ANY;
471
472 assert_spin_locked(&dev->slock);
473
474 /* video capture -- dma 0 + video task A */
475 if (dev->video_q.curr) {
476 task |= 0x01;
477 ctrl |= SAA7134_MAIN_CTRL_TE0;
478 irq |= SAA7134_IRQ1_INTE_RA0_1 |
479 SAA7134_IRQ1_INTE_RA0_0;
480 cap = dev->video_q.curr->vb.field;
481 }
482
483 /* video capture -- dma 1+2 (planar modes) */
484 if (dev->video_q.curr &&
485 dev->video_q.curr->fmt->planar) {
486 ctrl |= SAA7134_MAIN_CTRL_TE4 |
487 SAA7134_MAIN_CTRL_TE5;
488 }
489
490 /* screen overlay -- dma 0 + video task B */
491 if (dev->ovenable) {
492 task |= 0x10;
493 ctrl |= SAA7134_MAIN_CTRL_TE1;
494 ov = dev->ovfield;
495 }
496
497 /* vbi capture -- dma 0 + vbi task A+B */
498 if (dev->vbi_q.curr) {
499 task |= 0x22;
500 ctrl |= SAA7134_MAIN_CTRL_TE2 |
501 SAA7134_MAIN_CTRL_TE3;
502 irq |= SAA7134_IRQ1_INTE_RA0_7 |
503 SAA7134_IRQ1_INTE_RA0_6 |
504 SAA7134_IRQ1_INTE_RA0_5 |
505 SAA7134_IRQ1_INTE_RA0_4;
506 }
507
508 /* audio capture -- dma 3 */
509 if (dev->oss.dma_running) {
510 ctrl |= SAA7134_MAIN_CTRL_TE6;
511 irq |= SAA7134_IRQ1_INTE_RA3_1 |
512 SAA7134_IRQ1_INTE_RA3_0;
513 }
514
515 /* TS capture -- dma 5 */
516 if (dev->ts_q.curr) {
517 ctrl |= SAA7134_MAIN_CTRL_TE5;
518 irq |= SAA7134_IRQ1_INTE_RA2_3 |
519 SAA7134_IRQ1_INTE_RA2_2 |
520 SAA7134_IRQ1_INTE_RA2_1 |
521 SAA7134_IRQ1_INTE_RA2_0;
522 }
523
524 /* set task conditions + field handling */
525 if (V4L2_FIELD_HAS_BOTH(cap) || V4L2_FIELD_HAS_BOTH(ov) || cap == ov) {
526 /* default config -- use full frames */
527 saa_writeb(SAA7134_TASK_CONDITIONS(TASK_A), 0x0d);
528 saa_writeb(SAA7134_TASK_CONDITIONS(TASK_B), 0x0d);
529 saa_writeb(SAA7134_FIELD_HANDLING(TASK_A), 0x02);
530 saa_writeb(SAA7134_FIELD_HANDLING(TASK_B), 0x02);
531 split = 0;
532 } else {
533 /* split fields between tasks */
534 if (V4L2_FIELD_TOP == cap) {
535 /* odd A, even B, repeat */
536 saa_writeb(SAA7134_TASK_CONDITIONS(TASK_A), 0x0d);
537 saa_writeb(SAA7134_TASK_CONDITIONS(TASK_B), 0x0e);
538 } else {
539 /* odd B, even A, repeat */
540 saa_writeb(SAA7134_TASK_CONDITIONS(TASK_A), 0x0e);
541 saa_writeb(SAA7134_TASK_CONDITIONS(TASK_B), 0x0d);
542 }
543 saa_writeb(SAA7134_FIELD_HANDLING(TASK_A), 0x01);
544 saa_writeb(SAA7134_FIELD_HANDLING(TASK_B), 0x01);
545 split = 1;
546 }
547
548 /* irqs */
549 saa_writeb(SAA7134_REGION_ENABLE, task);
550 saa_writel(SAA7134_IRQ1, irq);
551 saa_andorl(SAA7134_MAIN_CTRL,
552 SAA7134_MAIN_CTRL_TE0 |
553 SAA7134_MAIN_CTRL_TE1 |
554 SAA7134_MAIN_CTRL_TE2 |
555 SAA7134_MAIN_CTRL_TE3 |
556 SAA7134_MAIN_CTRL_TE4 |
557 SAA7134_MAIN_CTRL_TE5 |
558 SAA7134_MAIN_CTRL_TE6,
559 ctrl);
560 dprintk("dmabits: task=0x%02x ctrl=0x%02x irq=0x%x split=%s\n",
561 task, ctrl, irq, split ? "no" : "yes");
562
563 return 0;
564}
565
566/* ------------------------------------------------------------------ */
567/* IRQ handler + helpers */
568
569static char *irqbits[] = {
570 "DONE_RA0", "DONE_RA1", "DONE_RA2", "DONE_RA3",
571 "AR", "PE", "PWR_ON", "RDCAP", "INTL", "FIDT", "MMC",
572 "TRIG_ERR", "CONF_ERR", "LOAD_ERR",
573 "GPIO16?", "GPIO18", "GPIO22", "GPIO23"
574};
575#define IRQBITS ARRAY_SIZE(irqbits)
576
577static void print_irqstatus(struct saa7134_dev *dev, int loop,
578 unsigned long report, unsigned long status)
579{
580 unsigned int i;
581
582 printk(KERN_DEBUG "%s/irq[%d,%ld]: r=0x%lx s=0x%02lx",
583 dev->name,loop,jiffies,report,status);
584 for (i = 0; i < IRQBITS; i++) {
585 if (!(report & (1 << i)))
586 continue;
587 printk(" %s",irqbits[i]);
588 }
589 if (report & SAA7134_IRQ_REPORT_DONE_RA0) {
590 printk(" | RA0=%s,%s,%s,%ld",
591 (status & 0x40) ? "vbi" : "video",
592 (status & 0x20) ? "b" : "a",
593 (status & 0x10) ? "odd" : "even",
594 (status & 0x0f));
595 }
596 printk("\n");
597}
598
599static irqreturn_t saa7134_irq(int irq, void *dev_id, struct pt_regs *regs)
600{
601 struct saa7134_dev *dev = (struct saa7134_dev*) dev_id;
602 unsigned long report,status;
603 int loop, handled = 0;
604
605 for (loop = 0; loop < 10; loop++) {
606 report = saa_readl(SAA7134_IRQ_REPORT);
607 status = saa_readl(SAA7134_IRQ_STATUS);
608 if (0 == report) {
609 if (irq_debug > 1)
610 printk(KERN_DEBUG "%s/irq: no (more) work\n",
611 dev->name);
612 goto out;
613 }
614 handled = 1;
615 saa_writel(SAA7134_IRQ_REPORT,report);
616 if (irq_debug)
617 print_irqstatus(dev,loop,report,status);
618
619#if 0
620 if (report & SAA7134_IRQ_REPORT_CONF_ERR)
621 dump_statusregs(dev);
622#endif
623
624 if (report & SAA7134_IRQ_REPORT_RDCAP /* _INTL */)
625 saa7134_irq_video_intl(dev);
626
627 if ((report & SAA7134_IRQ_REPORT_DONE_RA0) &&
628 (status & 0x60) == 0)
629 saa7134_irq_video_done(dev,status);
630
631 if ((report & SAA7134_IRQ_REPORT_DONE_RA0) &&
632 (status & 0x40) == 0x40)
633 saa7134_irq_vbi_done(dev,status);
634
635 if ((report & SAA7134_IRQ_REPORT_DONE_RA2) &&
636 card_has_mpeg(dev))
637 saa7134_irq_ts_done(dev,status);
638
639 if ((report & SAA7134_IRQ_REPORT_DONE_RA3))
640 saa7134_irq_oss_done(dev,status);
641
642 if ((report & (SAA7134_IRQ_REPORT_GPIO16 |
643 SAA7134_IRQ_REPORT_GPIO18)) &&
644 dev->remote)
645 saa7134_input_irq(dev);
646 }
647
648 if (10 == loop) {
649 print_irqstatus(dev,loop,report,status);
650 if (report & SAA7134_IRQ_REPORT_PE) {
651 /* disable all parity error */
652 printk(KERN_WARNING "%s/irq: looping -- "
653 "clearing PE (parity error!) enable bit\n",dev->name);
654 saa_clearl(SAA7134_IRQ2,SAA7134_IRQ2_INTE_PE);
655 } else if (report & (SAA7134_IRQ_REPORT_GPIO16 |
656 SAA7134_IRQ_REPORT_GPIO18)) {
657 /* disable gpio IRQs */
658 printk(KERN_WARNING "%s/irq: looping -- "
659 "clearing GPIO enable bits\n",dev->name);
660 saa_clearl(SAA7134_IRQ2, (SAA7134_IRQ2_INTE_GPIO16 |
661 SAA7134_IRQ2_INTE_GPIO18));
662 } else {
663 /* disable all irqs */
664 printk(KERN_WARNING "%s/irq: looping -- "
665 "clearing all enable bits\n",dev->name);
666 saa_writel(SAA7134_IRQ1,0);
667 saa_writel(SAA7134_IRQ2,0);
668 }
669 }
670
671 out:
672 return IRQ_RETVAL(handled);
673}
674
675/* ------------------------------------------------------------------ */
676
677/* early init (no i2c, no irq) */
678static int saa7134_hwinit1(struct saa7134_dev *dev)
679{
680 dprintk("hwinit1\n");
681
682 saa_writel(SAA7134_IRQ1, 0);
683 saa_writel(SAA7134_IRQ2, 0);
684 init_MUTEX(&dev->lock);
685 spin_lock_init(&dev->slock);
686
687 saa7134_track_gpio(dev,"pre-init");
688 saa7134_video_init1(dev);
689 saa7134_vbi_init1(dev);
690 if (card_has_mpeg(dev))
691 saa7134_ts_init1(dev);
692 saa7134_input_init1(dev);
693
694 switch (dev->pci->device) {
695 case PCI_DEVICE_ID_PHILIPS_SAA7134:
696 case PCI_DEVICE_ID_PHILIPS_SAA7133:
697 case PCI_DEVICE_ID_PHILIPS_SAA7135:
698 saa7134_oss_init1(dev);
699 break;
700 }
701
702 /* RAM FIFO config */
703 saa_writel(SAA7134_FIFO_SIZE, 0x08070503);
704 saa_writel(SAA7134_THRESHOULD,0x02020202);
705
706 /* enable audio + video processing */
707 saa_writel(SAA7134_MAIN_CTRL,
708 SAA7134_MAIN_CTRL_VPLLE |
709 SAA7134_MAIN_CTRL_APLLE |
710 SAA7134_MAIN_CTRL_EXOSC |
711 SAA7134_MAIN_CTRL_EVFE1 |
712 SAA7134_MAIN_CTRL_EVFE2 |
713 SAA7134_MAIN_CTRL_ESFE |
714 SAA7134_MAIN_CTRL_EBADC |
715 SAA7134_MAIN_CTRL_EBDAC);
716
717 /* enable peripheral devices */
718 saa_writeb(SAA7134_SPECIAL_MODE, 0x01);
719
720 /* set vertical line numbering start (vbi needs this) */
721 saa_writeb(SAA7134_SOURCE_TIMING2, 0x20);
722
723 return 0;
724}
725
726/* late init (with i2c + irq) */
727static int saa7134_hwinit2(struct saa7134_dev *dev)
728{
729 dprintk("hwinit2\n");
730
731 saa7134_video_init2(dev);
732 saa7134_tvaudio_init2(dev);
733
734 /* enable IRQ's */
735 saa_writel(SAA7134_IRQ1, 0);
736 saa_writel(SAA7134_IRQ2, dev->irq2_mask);
737
738 return 0;
739}
740
741/* shutdown */
742static int saa7134_hwfini(struct saa7134_dev *dev)
743{
744 dprintk("hwfini\n");
745
746 switch (dev->pci->device) {
747 case PCI_DEVICE_ID_PHILIPS_SAA7134:
748 case PCI_DEVICE_ID_PHILIPS_SAA7133:
749 case PCI_DEVICE_ID_PHILIPS_SAA7135:
750 saa7134_oss_fini(dev);
751 break;
752 }
753 if (card_has_mpeg(dev))
754 saa7134_ts_fini(dev);
755 saa7134_input_fini(dev);
756 saa7134_vbi_fini(dev);
757 saa7134_video_fini(dev);
758 saa7134_tvaudio_fini(dev);
759 return 0;
760}
761
762static void __devinit must_configure_manually(void)
763{
764 unsigned int i,p;
765
766 printk(KERN_WARNING
767 "saa7134: <rant>\n"
768 "saa7134: Congratulations! Your TV card vendor saved a few\n"
769 "saa7134: cents for a eeprom, thus your pci board has no\n"
770 "saa7134: subsystem ID and I can't identify it automatically\n"
771 "saa7134: </rant>\n"
772 "saa7134: I feel better now. Ok, here are the good news:\n"
773 "saa7134: You can use the card=<nr> insmod option to specify\n"
774 "saa7134: which board do you have. The list:\n");
775 for (i = 0; i < saa7134_bcount; i++) {
776 printk(KERN_WARNING "saa7134: card=%d -> %-40.40s",
777 i,saa7134_boards[i].name);
778 for (p = 0; saa7134_pci_tbl[p].driver_data; p++) {
779 if (saa7134_pci_tbl[p].driver_data != i)
780 continue;
781 printk(" %04x:%04x",
782 saa7134_pci_tbl[p].subvendor,
783 saa7134_pci_tbl[p].subdevice);
784 }
785 printk("\n");
786 }
787}
788
789static struct video_device *vdev_init(struct saa7134_dev *dev,
790 struct video_device *template,
791 char *type)
792{
793 struct video_device *vfd;
794
795 vfd = video_device_alloc();
796 if (NULL == vfd)
797 return NULL;
798 *vfd = *template;
799 vfd->minor = -1;
800 vfd->dev = &dev->pci->dev;
801 vfd->release = video_device_release;
802 snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)",
803 dev->name, type, saa7134_boards[dev->board].name);
804 return vfd;
805}
806
807static void saa7134_unregister_video(struct saa7134_dev *dev)
808{
809 if (dev->video_dev) {
810 if (-1 != dev->video_dev->minor)
811 video_unregister_device(dev->video_dev);
812 else
813 video_device_release(dev->video_dev);
814 dev->video_dev = NULL;
815 }
816 if (dev->vbi_dev) {
817 if (-1 != dev->vbi_dev->minor)
818 video_unregister_device(dev->vbi_dev);
819 else
820 video_device_release(dev->vbi_dev);
821 dev->vbi_dev = NULL;
822 }
823 if (dev->radio_dev) {
824 if (-1 != dev->radio_dev->minor)
825 video_unregister_device(dev->radio_dev);
826 else
827 video_device_release(dev->radio_dev);
828 dev->radio_dev = NULL;
829 }
830}
831
832static void mpeg_ops_attach(struct saa7134_mpeg_ops *ops,
833 struct saa7134_dev *dev)
834{
835 int err;
836
837 if (NULL != dev->mops)
838 return;
839 if (saa7134_boards[dev->board].mpeg != ops->type)
840 return;
841 err = ops->init(dev);
842 if (0 != err)
843 return;
844 dev->mops = ops;
845}
846
847static void mpeg_ops_detach(struct saa7134_mpeg_ops *ops,
848 struct saa7134_dev *dev)
849{
850 if (NULL == dev->mops)
851 return;
852 if (dev->mops != ops)
853 return;
854 dev->mops->fini(dev);
855 dev->mops = NULL;
856}
857
858static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
859 const struct pci_device_id *pci_id)
860{
861 struct saa7134_dev *dev;
862 struct list_head *item;
863 struct saa7134_mpeg_ops *mops;
864 int err;
865
866 dev = kmalloc(sizeof(*dev),GFP_KERNEL);
867 if (NULL == dev)
868 return -ENOMEM;
869 memset(dev,0,sizeof(*dev));
870
871 /* pci init */
872 dev->pci = pci_dev;
873 if (pci_enable_device(pci_dev)) {
874 err = -EIO;
875 goto fail1;
876 }
877
878 dev->nr = saa7134_devcount;
879 sprintf(dev->name,"saa%x[%d]",pci_dev->device,dev->nr);
880
881 /* pci quirks */
882 if (pci_pci_problems) {
883 if (pci_pci_problems & PCIPCI_TRITON)
884 printk(KERN_INFO "%s: quirk: PCIPCI_TRITON\n", dev->name);
885 if (pci_pci_problems & PCIPCI_NATOMA)
886 printk(KERN_INFO "%s: quirk: PCIPCI_NATOMA\n", dev->name);
887 if (pci_pci_problems & PCIPCI_VIAETBF)
888 printk(KERN_INFO "%s: quirk: PCIPCI_VIAETBF\n", dev->name);
889 if (pci_pci_problems & PCIPCI_VSFX)
890 printk(KERN_INFO "%s: quirk: PCIPCI_VSFX\n",dev->name);
891#ifdef PCIPCI_ALIMAGIK
892 if (pci_pci_problems & PCIPCI_ALIMAGIK) {
893 printk(KERN_INFO "%s: quirk: PCIPCI_ALIMAGIK -- latency fixup\n",
894 dev->name);
895 latency = 0x0A;
896 }
897#endif
898 }
899 if (UNSET != latency) {
900 printk(KERN_INFO "%s: setting pci latency timer to %d\n",
901 dev->name,latency);
902 pci_write_config_byte(pci_dev, PCI_LATENCY_TIMER, latency);
903 }
904
905 /* print pci info */
906 pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev);
907 pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat);
908 printk(KERN_INFO "%s: found at %s, rev: %d, irq: %d, "
909 "latency: %d, mmio: 0x%lx\n", dev->name,
910 pci_name(pci_dev), dev->pci_rev, pci_dev->irq,
911 dev->pci_lat,pci_resource_start(pci_dev,0));
912 pci_set_master(pci_dev);
913 if (!pci_dma_supported(pci_dev,0xffffffff)) {
914 printk("%s: Oops: no 32bit PCI DMA ???\n",dev->name);
915 err = -EIO;
916 goto fail1;
917 }
918
919 /* board config */
920 dev->board = pci_id->driver_data;
921 if (card[dev->nr] >= 0 &&
922 card[dev->nr] < saa7134_bcount)
923 dev->board = card[dev->nr];
924 if (SAA7134_BOARD_NOAUTO == dev->board) {
925 must_configure_manually();
926 dev->board = SAA7134_BOARD_UNKNOWN;
927 }
928 dev->tuner_type = saa7134_boards[dev->board].tuner_type;
929 dev->tda9887_conf = saa7134_boards[dev->board].tda9887_conf;
930 if (UNSET != tuner[dev->nr])
931 dev->tuner_type = tuner[dev->nr];
932 printk(KERN_INFO "%s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n",
933 dev->name,pci_dev->subsystem_vendor,
934 pci_dev->subsystem_device,saa7134_boards[dev->board].name,
935 dev->board, card[dev->nr] == dev->board ?
936 "insmod option" : "autodetected");
937
938 /* get mmio */
939 if (!request_mem_region(pci_resource_start(pci_dev,0),
940 pci_resource_len(pci_dev,0),
941 dev->name)) {
942 err = -EBUSY;
943 printk(KERN_ERR "%s: can't get MMIO memory @ 0x%lx\n",
944 dev->name,pci_resource_start(pci_dev,0));
945 goto fail1;
946 }
947 dev->lmmio = ioremap(pci_resource_start(pci_dev,0), 0x1000);
948 dev->bmmio = (__u8 __iomem *)dev->lmmio;
949 if (NULL == dev->lmmio) {
950 err = -EIO;
951 printk(KERN_ERR "%s: can't ioremap() MMIO memory\n",
952 dev->name);
953 goto fail2;
954 }
955
956 /* initialize hardware #1 */
957 dev->irq2_mask =
958 SAA7134_IRQ2_INTE_DEC3 |
959 SAA7134_IRQ2_INTE_DEC2 |
960 SAA7134_IRQ2_INTE_DEC1 |
961 SAA7134_IRQ2_INTE_DEC0 |
962 SAA7134_IRQ2_INTE_PE |
963 SAA7134_IRQ2_INTE_AR;
964 saa7134_board_init1(dev);
965 saa7134_hwinit1(dev);
966
967 /* get irq */
968 err = request_irq(pci_dev->irq, saa7134_irq,
969 SA_SHIRQ | SA_INTERRUPT, dev->name, dev);
970 if (err < 0) {
971 printk(KERN_ERR "%s: can't get IRQ %d\n",
972 dev->name,pci_dev->irq);
973 goto fail3;
974 }
975
976 /* wait a bit, register i2c bus */
977 msleep(100);
978 saa7134_i2c_register(dev);
979
980 /* initialize hardware #2 */
981 saa7134_board_init2(dev);
982 saa7134_hwinit2(dev);
983
984 /* load i2c helpers */
985 if (TUNER_ABSENT != dev->tuner_type)
986 request_module("tuner");
987 if (dev->tda9887_conf)
988 request_module("tda9887");
989 if (card_is_empress(dev)) {
990 request_module("saa6752hs");
991 request_module_depend("saa7134-empress",&need_empress);
992 }
993 if (card_is_dvb(dev))
994 request_module_depend("saa7134-dvb",&need_dvb);
995
996 v4l2_prio_init(&dev->prio);
997
998 /* register v4l devices */
999 dev->video_dev = vdev_init(dev,&saa7134_video_template,"video");
1000 err = video_register_device(dev->video_dev,VFL_TYPE_GRABBER,
1001 video_nr[dev->nr]);
1002 if (err < 0) {
1003 printk(KERN_INFO "%s: can't register video device\n",
1004 dev->name);
1005 goto fail4;
1006 }
1007 printk(KERN_INFO "%s: registered device video%d [v4l2]\n",
1008 dev->name,dev->video_dev->minor & 0x1f);
1009
1010 dev->vbi_dev = vdev_init(dev,&saa7134_vbi_template,"vbi");
1011 err = video_register_device(dev->vbi_dev,VFL_TYPE_VBI,
1012 vbi_nr[dev->nr]);
1013 if (err < 0)
1014 goto fail4;
1015 printk(KERN_INFO "%s: registered device vbi%d\n",
1016 dev->name,dev->vbi_dev->minor & 0x1f);
1017
1018 if (card_has_radio(dev)) {
1019 dev->radio_dev = vdev_init(dev,&saa7134_radio_template,"radio");
1020 err = video_register_device(dev->radio_dev,VFL_TYPE_RADIO,
1021 radio_nr[dev->nr]);
1022 if (err < 0)
1023 goto fail4;
1024 printk(KERN_INFO "%s: registered device radio%d\n",
1025 dev->name,dev->radio_dev->minor & 0x1f);
1026 }
1027
1028 /* register oss devices */
1029 switch (dev->pci->device) {
1030 case PCI_DEVICE_ID_PHILIPS_SAA7134:
1031 case PCI_DEVICE_ID_PHILIPS_SAA7133:
1032 case PCI_DEVICE_ID_PHILIPS_SAA7135:
1033 if (oss) {
1034 err = dev->oss.minor_dsp =
1035 register_sound_dsp(&saa7134_dsp_fops,
1036 dsp_nr[dev->nr]);
1037 if (err < 0) {
1038 goto fail4;
1039 }
1040 printk(KERN_INFO "%s: registered device dsp%d\n",
1041 dev->name,dev->oss.minor_dsp >> 4);
1042
1043 err = dev->oss.minor_mixer =
1044 register_sound_mixer(&saa7134_mixer_fops,
1045 mixer_nr[dev->nr]);
1046 if (err < 0)
1047 goto fail5;
1048 printk(KERN_INFO "%s: registered device mixer%d\n",
1049 dev->name,dev->oss.minor_mixer >> 4);
1050 }
1051 break;
1052 }
1053
1054 /* everything worked */
1055 pci_set_drvdata(pci_dev,dev);
1056 saa7134_devcount++;
1057
1058 down(&devlist_lock);
1059 list_for_each(item,&mops_list) {
1060 mops = list_entry(item, struct saa7134_mpeg_ops, next);
1061 mpeg_ops_attach(mops, dev);
1062 }
1063 list_add_tail(&dev->devlist,&saa7134_devlist);
1064 up(&devlist_lock);
1065
1066 /* check for signal */
1067 saa7134_irq_video_intl(dev);
1068 return 0;
1069
1070 fail5:
1071 switch (dev->pci->device) {
1072 case PCI_DEVICE_ID_PHILIPS_SAA7134:
1073 case PCI_DEVICE_ID_PHILIPS_SAA7133:
1074 case PCI_DEVICE_ID_PHILIPS_SAA7135:
1075 if (oss)
1076 unregister_sound_dsp(dev->oss.minor_dsp);
1077 break;
1078 }
1079 fail4:
1080 saa7134_unregister_video(dev);
1081 saa7134_i2c_unregister(dev);
1082 free_irq(pci_dev->irq, dev);
1083 fail3:
1084 saa7134_hwfini(dev);
1085 iounmap(dev->lmmio);
1086 fail2:
1087 release_mem_region(pci_resource_start(pci_dev,0),
1088 pci_resource_len(pci_dev,0));
1089 fail1:
1090 kfree(dev);
1091 return err;
1092}
1093
1094static void __devexit saa7134_finidev(struct pci_dev *pci_dev)
1095{
1096 struct saa7134_dev *dev = pci_get_drvdata(pci_dev);
1097 struct list_head *item;
1098 struct saa7134_mpeg_ops *mops;
1099
1100 /* debugging ... */
1101 if (irq_debug) {
1102 u32 report = saa_readl(SAA7134_IRQ_REPORT);
1103 u32 status = saa_readl(SAA7134_IRQ_STATUS);
1104 print_irqstatus(dev,42,report,status);
1105 }
1106
1107 /* disable peripheral devices */
1108 saa_writeb(SAA7134_SPECIAL_MODE,0);
1109
1110 /* shutdown hardware */
1111 saa_writel(SAA7134_IRQ1,0);
1112 saa_writel(SAA7134_IRQ2,0);
1113 saa_writel(SAA7134_MAIN_CTRL,0);
1114
1115 /* shutdown subsystems */
1116 saa7134_hwfini(dev);
1117
1118 /* unregister */
1119 down(&devlist_lock);
1120 list_del(&dev->devlist);
1121 list_for_each(item,&mops_list) {
1122 mops = list_entry(item, struct saa7134_mpeg_ops, next);
1123 mpeg_ops_detach(mops, dev);
1124 }
1125 up(&devlist_lock);
1126 saa7134_devcount--;
1127
1128 saa7134_i2c_unregister(dev);
1129 switch (dev->pci->device) {
1130 case PCI_DEVICE_ID_PHILIPS_SAA7134:
1131 case PCI_DEVICE_ID_PHILIPS_SAA7133:
1132 case PCI_DEVICE_ID_PHILIPS_SAA7135:
1133 if (oss) {
1134 unregister_sound_mixer(dev->oss.minor_mixer);
1135 unregister_sound_dsp(dev->oss.minor_dsp);
1136 }
1137 break;
1138 }
1139 saa7134_unregister_video(dev);
1140
1141 /* release ressources */
1142 free_irq(pci_dev->irq, dev);
1143 iounmap(dev->lmmio);
1144 release_mem_region(pci_resource_start(pci_dev,0),
1145 pci_resource_len(pci_dev,0));
1146
1147#if 0 /* causes some trouble when reinserting the driver ... */
1148 pci_disable_device(pci_dev);
1149#endif
1150 pci_set_drvdata(pci_dev, NULL);
1151
1152 /* free memory */
1153 kfree(dev);
1154}
1155
1156/* ----------------------------------------------------------- */
1157
1158int saa7134_ts_register(struct saa7134_mpeg_ops *ops)
1159{
1160 struct list_head *item;
1161 struct saa7134_dev *dev;
1162
1163 down(&devlist_lock);
1164 list_for_each(item,&saa7134_devlist) {
1165 dev = list_entry(item, struct saa7134_dev, devlist);
1166 mpeg_ops_attach(ops, dev);
1167 }
1168 list_add_tail(&ops->next,&mops_list);
1169 up(&devlist_lock);
1170 return 0;
1171}
1172
1173void saa7134_ts_unregister(struct saa7134_mpeg_ops *ops)
1174{
1175 struct list_head *item;
1176 struct saa7134_dev *dev;
1177
1178 down(&devlist_lock);
1179 list_del(&ops->next);
1180 list_for_each(item,&saa7134_devlist) {
1181 dev = list_entry(item, struct saa7134_dev, devlist);
1182 mpeg_ops_detach(ops, dev);
1183 }
1184 up(&devlist_lock);
1185}
1186
1187EXPORT_SYMBOL(saa7134_ts_register);
1188EXPORT_SYMBOL(saa7134_ts_unregister);
1189
1190/* ----------------------------------------------------------- */
1191
1192static struct pci_driver saa7134_pci_driver = {
1193 .name = "saa7134",
1194 .id_table = saa7134_pci_tbl,
1195 .probe = saa7134_initdev,
1196 .remove = __devexit_p(saa7134_finidev),
1197};
1198
1199static int saa7134_init(void)
1200{
1201 INIT_LIST_HEAD(&saa7134_devlist);
1202 printk(KERN_INFO "saa7130/34: v4l2 driver version %d.%d.%d loaded\n",
1203 (SAA7134_VERSION_CODE >> 16) & 0xff,
1204 (SAA7134_VERSION_CODE >> 8) & 0xff,
1205 SAA7134_VERSION_CODE & 0xff);
1206#ifdef SNAPSHOT
1207 printk(KERN_INFO "saa7130/34: snapshot date %04d-%02d-%02d\n",
1208 SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100);
1209#endif
1210 return pci_module_init(&saa7134_pci_driver);
1211}
1212
1213static void saa7134_fini(void)
1214{
1215#ifdef CONFIG_MODULES
1216 if (pending_registered)
1217 unregister_module_notifier(&pending_notifier);
1218#endif
1219 pci_unregister_driver(&saa7134_pci_driver);
1220}
1221
1222module_init(saa7134_init);
1223module_exit(saa7134_fini);
1224
1225/* ----------------------------------------------------------- */
1226
1227EXPORT_SYMBOL(saa7134_print_ioctl);
1228EXPORT_SYMBOL(saa7134_i2c_call_clients);
1229EXPORT_SYMBOL(saa7134_devlist);
1230EXPORT_SYMBOL(saa7134_boards);
1231
1232/* ----------------------------------------------------------- */
1233/*
1234 * Local variables:
1235 * c-basic-offset: 8
1236 * End:
1237 */
diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c
new file mode 100644
index 00000000000..dd4a6c8ee65
--- /dev/null
+++ b/drivers/media/video/saa7134/saa7134-dvb.c
@@ -0,0 +1,266 @@
1/*
2 * $Id: saa7134-dvb.c,v 1.12 2005/02/18 12:28:29 kraxel Exp $
3 *
4 * (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21#include <linux/init.h>
22#include <linux/list.h>
23#include <linux/module.h>
24#include <linux/kernel.h>
25#include <linux/slab.h>
26#include <linux/delay.h>
27#include <linux/kthread.h>
28#include <linux/suspend.h>
29
30#include "saa7134-reg.h"
31#include "saa7134.h"
32
33#include "dvb-pll.h"
34#include "mt352.h"
35#include "mt352_priv.h" /* FIXME */
36#include "tda1004x.h"
37
38MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
39MODULE_LICENSE("GPL");
40
41static unsigned int antenna_pwr = 0;
42module_param(antenna_pwr, int, 0444);
43MODULE_PARM_DESC(antenna_pwr,"enable antenna power (Pinnacle 300i)");
44
45/* ------------------------------------------------------------------ */
46
47static int pinnacle_antenna_pwr(struct saa7134_dev *dev, int on)
48{
49 u32 ok;
50
51 if (!on) {
52 saa_setl(SAA7134_GPIO_GPMODE0 >> 2, (1 << 26));
53 saa_clearl(SAA7134_GPIO_GPSTATUS0 >> 2, (1 << 26));
54 return 0;
55 }
56
57 saa_setl(SAA7134_GPIO_GPMODE0 >> 2, (1 << 26));
58 saa_setl(SAA7134_GPIO_GPSTATUS0 >> 2, (1 << 26));
59 udelay(10);
60
61 saa_setl(SAA7134_GPIO_GPMODE0 >> 2, (1 << 28));
62 saa_clearl(SAA7134_GPIO_GPSTATUS0 >> 2, (1 << 28));
63 udelay(10);
64 saa_setl(SAA7134_GPIO_GPSTATUS0 >> 2, (1 << 28));
65 udelay(10);
66 ok = saa_readl(SAA7134_GPIO_GPSTATUS0) & (1 << 27);
67 printk("%s: %s %s\n", dev->name, __FUNCTION__,
68 ok ? "on" : "off");
69
70 if (!ok)
71 saa_clearl(SAA7134_GPIO_GPSTATUS0 >> 2, (1 << 26));
72 return ok;
73}
74
75static int mt352_pinnacle_init(struct dvb_frontend* fe)
76{
77 static u8 clock_config [] = { CLOCK_CTL, 0x3d, 0x28 };
78 static u8 reset [] = { RESET, 0x80 };
79 static u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 };
80 static u8 agc_cfg [] = { AGC_TARGET, 0x28, 0xa0 };
81 static u8 capt_range_cfg[] = { CAPT_RANGE, 0x31 };
82 static u8 fsm_ctl_cfg[] = { 0x7b, 0x04 };
83 static u8 gpp_ctl_cfg [] = { GPP_CTL, 0x0f };
84 static u8 scan_ctl_cfg [] = { SCAN_CTL, 0x0d };
85 static u8 irq_cfg [] = { INTERRUPT_EN_0, 0x00, 0x00, 0x00, 0x00 };
86 struct saa7134_dev *dev= fe->dvb->priv;
87
88 printk("%s: %s called\n",dev->name,__FUNCTION__);
89
90 mt352_write(fe, clock_config, sizeof(clock_config));
91 udelay(200);
92 mt352_write(fe, reset, sizeof(reset));
93 mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
94 mt352_write(fe, agc_cfg, sizeof(agc_cfg));
95 mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
96 mt352_write(fe, gpp_ctl_cfg, sizeof(gpp_ctl_cfg));
97
98 mt352_write(fe, fsm_ctl_cfg, sizeof(fsm_ctl_cfg));
99 mt352_write(fe, scan_ctl_cfg, sizeof(scan_ctl_cfg));
100 mt352_write(fe, irq_cfg, sizeof(irq_cfg));
101 return 0;
102}
103
104static int mt352_pinnacle_pll_set(struct dvb_frontend* fe,
105 struct dvb_frontend_parameters* params,
106 u8* pllbuf)
107{
108 static int on = TDA9887_PRESENT | TDA9887_PORT2_INACTIVE;
109 static int off = TDA9887_PRESENT | TDA9887_PORT2_ACTIVE;
110 struct saa7134_dev *dev = fe->dvb->priv;
111 struct v4l2_frequency f;
112
113 /* set frequency (mt2050) */
114 f.tuner = 0;
115 f.type = V4L2_TUNER_DIGITAL_TV;
116 f.frequency = params->frequency / 1000 * 16 / 1000;
117 saa7134_i2c_call_clients(dev,TDA9887_SET_CONFIG,&on);
118 saa7134_i2c_call_clients(dev,VIDIOC_S_FREQUENCY,&f);
119 saa7134_i2c_call_clients(dev,TDA9887_SET_CONFIG,&off);
120
121 pinnacle_antenna_pwr(dev, antenna_pwr);
122
123 /* mt352 setup */
124 mt352_pinnacle_init(fe);
125 pllbuf[0] = 0xc2;
126 pllbuf[1] = 0x00;
127 pllbuf[2] = 0x00;
128 pllbuf[3] = 0x80;
129 pllbuf[4] = 0x00;
130 return 0;
131}
132
133static struct mt352_config pinnacle_300i = {
134 .demod_address = 0x3c >> 1,
135 .adc_clock = 20333,
136 .if2 = 36150,
137 .no_tuner = 1,
138 .demod_init = mt352_pinnacle_init,
139 .pll_set = mt352_pinnacle_pll_set,
140};
141
142/* ------------------------------------------------------------------ */
143
144static int medion_cardbus_init(struct dvb_frontend* fe)
145{
146 /* anything to do here ??? */
147 return 0;
148}
149
150static int medion_cardbus_pll_set(struct dvb_frontend* fe,
151 struct dvb_frontend_parameters* params)
152{
153 struct saa7134_dev *dev = fe->dvb->priv;
154 struct v4l2_frequency f;
155
156 /*
157 * this instructs tuner.o to set the frequency, the call will
158 * end up in tuner_command(), VIDIOC_S_FREQUENCY switch.
159 * tda9887.o will see that as well.
160 */
161 f.tuner = 0;
162 f.type = V4L2_TUNER_DIGITAL_TV;
163 f.frequency = params->frequency / 1000 * 16 / 1000;
164 saa7134_i2c_call_clients(dev,VIDIOC_S_FREQUENCY,&f);
165 return 0;
166}
167
168static int fe_request_firmware(struct dvb_frontend* fe,
169 const struct firmware **fw, char* name)
170{
171 struct saa7134_dev *dev = fe->dvb->priv;
172 return request_firmware(fw, name, &dev->pci->dev);
173}
174
175struct tda1004x_config medion_cardbus = {
176 .demod_address = 0x08, /* not sure this is correct */
177 .invert = 0,
178 .invert_oclk = 0,
179 .pll_init = medion_cardbus_init,
180 .pll_set = medion_cardbus_pll_set,
181 .request_firmware = fe_request_firmware,
182};
183
184/* ------------------------------------------------------------------ */
185
186static int dvb_init(struct saa7134_dev *dev)
187{
188 /* init struct videobuf_dvb */
189 dev->ts.nr_bufs = 32;
190 dev->ts.nr_packets = 32*4;
191 dev->dvb.name = dev->name;
192 videobuf_queue_init(&dev->dvb.dvbq, &saa7134_ts_qops,
193 dev->pci, &dev->slock,
194 V4L2_BUF_TYPE_VIDEO_CAPTURE,
195 V4L2_FIELD_ALTERNATE,
196 sizeof(struct saa7134_buf),
197 dev);
198
199 switch (dev->board) {
200 case SAA7134_BOARD_PINNACLE_300I_DVBT_PAL:
201 printk("%s: pinnacle 300i dvb setup\n",dev->name);
202 dev->dvb.frontend = mt352_attach(&pinnacle_300i,
203 &dev->i2c_adap);
204 break;
205 case SAA7134_BOARD_MD7134:
206 dev->dvb.frontend = tda10046_attach(&medion_cardbus,
207 &dev->i2c_adap);
208 if (NULL == dev->dvb.frontend)
209 printk("%s: Hmm, looks like this is the old MD7134 "
210 "version without DVB-T support\n",dev->name);
211 break;
212 default:
213 printk("%s: Huh? unknown DVB card?\n",dev->name);
214 break;
215 }
216
217 if (NULL == dev->dvb.frontend) {
218 printk("%s: frontend initialization failed\n",dev->name);
219 return -1;
220 }
221
222 /* register everything else */
223 return videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev);
224}
225
226static int dvb_fini(struct saa7134_dev *dev)
227{
228 static int on = TDA9887_PRESENT | TDA9887_PORT2_INACTIVE;
229
230 printk("%s: %s\n",dev->name,__FUNCTION__);
231
232 switch (dev->board) {
233 case SAA7134_BOARD_PINNACLE_300I_DVBT_PAL:
234 /* otherwise we don't detect the tuner on next insmod */
235 saa7134_i2c_call_clients(dev,TDA9887_SET_CONFIG,&on);
236 break;
237 };
238 videobuf_dvb_unregister(&dev->dvb);
239 return 0;
240}
241
242static struct saa7134_mpeg_ops dvb_ops = {
243 .type = SAA7134_MPEG_DVB,
244 .init = dvb_init,
245 .fini = dvb_fini,
246};
247
248static int __init dvb_register(void)
249{
250 return saa7134_ts_register(&dvb_ops);
251}
252
253static void __exit dvb_unregister(void)
254{
255 saa7134_ts_unregister(&dvb_ops);
256}
257
258module_init(dvb_register);
259module_exit(dvb_unregister);
260
261/* ------------------------------------------------------------------ */
262/*
263 * Local variables:
264 * c-basic-offset: 8
265 * End:
266 */
diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c
new file mode 100644
index 00000000000..2021e099e35
--- /dev/null
+++ b/drivers/media/video/saa7134/saa7134-empress.c
@@ -0,0 +1,436 @@
1/*
2 * $Id: saa7134-empress.c,v 1.10 2005/02/03 10:24:33 kraxel Exp $
3 *
4 * (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21#include <linux/init.h>
22#include <linux/list.h>
23#include <linux/module.h>
24#include <linux/moduleparam.h>
25#include <linux/kernel.h>
26#include <linux/slab.h>
27#include <linux/delay.h>
28
29#include "saa7134-reg.h"
30#include "saa7134.h"
31
32#include <media/saa6752hs.h>
33
34/* ------------------------------------------------------------------ */
35
36MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
37MODULE_LICENSE("GPL");
38
39static unsigned int empress_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
40module_param_array(empress_nr, int, NULL, 0444);
41MODULE_PARM_DESC(empress_nr,"ts device number");
42
43static unsigned int debug = 0;
44module_param(debug, int, 0644);
45MODULE_PARM_DESC(debug,"enable debug messages");
46
47#define dprintk(fmt, arg...) if (debug) \
48 printk(KERN_DEBUG "%s/empress: " fmt, dev->name , ## arg)
49
50/* ------------------------------------------------------------------ */
51
52static void ts_reset_encoder(struct saa7134_dev* dev)
53{
54 if (!dev->empress_started)
55 return;
56
57 saa_writeb(SAA7134_SPECIAL_MODE, 0x00);
58 msleep(10);
59 saa_writeb(SAA7134_SPECIAL_MODE, 0x01);
60 msleep(100);
61 dev->empress_started = 0;
62}
63
64static int ts_init_encoder(struct saa7134_dev* dev)
65{
66 ts_reset_encoder(dev);
67 saa7134_i2c_call_clients(dev, VIDIOC_S_MPEGCOMP, NULL);
68 dev->empress_started = 1;
69 return 0;
70}
71
72/* ------------------------------------------------------------------ */
73
74static int ts_open(struct inode *inode, struct file *file)
75{
76 int minor = iminor(inode);
77 struct saa7134_dev *h,*dev = NULL;
78 struct list_head *list;
79 int err;
80
81 list_for_each(list,&saa7134_devlist) {
82 h = list_entry(list, struct saa7134_dev, devlist);
83 if (h->empress_dev && h->empress_dev->minor == minor)
84 dev = h;
85 }
86 if (NULL == dev)
87 return -ENODEV;
88
89 dprintk("open minor=%d\n",minor);
90 err = -EBUSY;
91 if (down_trylock(&dev->empress_tsq.lock))
92 goto done;
93 if (dev->empress_users)
94 goto done_up;
95
96 dev->empress_users++;
97 file->private_data = dev;
98 err = 0;
99
100done_up:
101 up(&dev->empress_tsq.lock);
102done:
103 return err;
104}
105
106static int ts_release(struct inode *inode, struct file *file)
107{
108 struct saa7134_dev *dev = file->private_data;
109
110 if (dev->empress_tsq.streaming)
111 videobuf_streamoff(&dev->empress_tsq);
112 down(&dev->empress_tsq.lock);
113 if (dev->empress_tsq.reading)
114 videobuf_read_stop(&dev->empress_tsq);
115 videobuf_mmap_free(&dev->empress_tsq);
116 dev->empress_users--;
117
118 /* stop the encoder */
119 ts_reset_encoder(dev);
120
121 up(&dev->empress_tsq.lock);
122 return 0;
123}
124
125static ssize_t
126ts_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
127{
128 struct saa7134_dev *dev = file->private_data;
129
130 if (!dev->empress_started)
131 ts_init_encoder(dev);
132
133 return videobuf_read_stream(&dev->empress_tsq,
134 data, count, ppos, 0,
135 file->f_flags & O_NONBLOCK);
136}
137
138static unsigned int
139ts_poll(struct file *file, struct poll_table_struct *wait)
140{
141 struct saa7134_dev *dev = file->private_data;
142
143 return videobuf_poll_stream(file, &dev->empress_tsq, wait);
144}
145
146
147static int
148ts_mmap(struct file *file, struct vm_area_struct * vma)
149{
150 struct saa7134_dev *dev = file->private_data;
151
152 return videobuf_mmap_mapper(&dev->empress_tsq, vma);
153}
154
155/*
156 * This function is _not_ called directly, but from
157 * video_generic_ioctl (and maybe others). userspace
158 * copying is done already, arg is a kernel pointer.
159 */
160static int ts_do_ioctl(struct inode *inode, struct file *file,
161 unsigned int cmd, void *arg)
162{
163 struct saa7134_dev *dev = file->private_data;
164
165 if (debug > 1)
166 saa7134_print_ioctl(dev->name,cmd);
167 switch (cmd) {
168 case VIDIOC_QUERYCAP:
169 {
170 struct v4l2_capability *cap = arg;
171
172 memset(cap,0,sizeof(*cap));
173 strcpy(cap->driver, "saa7134");
174 strlcpy(cap->card, saa7134_boards[dev->board].name,
175 sizeof(cap->card));
176 sprintf(cap->bus_info,"PCI:%s",pci_name(dev->pci));
177 cap->version = SAA7134_VERSION_CODE;
178 cap->capabilities =
179 V4L2_CAP_VIDEO_CAPTURE |
180 V4L2_CAP_READWRITE |
181 V4L2_CAP_STREAMING;
182 return 0;
183 }
184
185 /* --- input switching --------------------------------------- */
186 case VIDIOC_ENUMINPUT:
187 {
188 struct v4l2_input *i = arg;
189
190 if (i->index != 0)
191 return -EINVAL;
192 i->type = V4L2_INPUT_TYPE_CAMERA;
193 strcpy(i->name,"CCIR656");
194 return 0;
195 }
196 case VIDIOC_G_INPUT:
197 {
198 int *i = arg;
199 *i = 0;
200 return 0;
201 }
202 case VIDIOC_S_INPUT:
203 {
204 int *i = arg;
205
206 if (*i != 0)
207 return -EINVAL;
208 return 0;
209 }
210 /* --- capture ioctls ---------------------------------------- */
211
212 case VIDIOC_ENUM_FMT:
213 {
214 struct v4l2_fmtdesc *f = arg;
215 int index;
216
217 index = f->index;
218 if (index != 0)
219 return -EINVAL;
220
221 memset(f,0,sizeof(*f));
222 f->index = index;
223 strlcpy(f->description, "MPEG TS", sizeof(f->description));
224 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
225 f->pixelformat = V4L2_PIX_FMT_MPEG;
226 return 0;
227 }
228
229 case VIDIOC_G_FMT:
230 {
231 struct v4l2_format *f = arg;
232
233 memset(f,0,sizeof(*f));
234 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
235
236 /* FIXME: translate subsampling type EMPRESS into
237 * width/height: */
238 f->fmt.pix.width = 720; /* D1 */
239 f->fmt.pix.height = 576;
240 f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
241 f->fmt.pix.sizeimage = TS_PACKET_SIZE * dev->ts.nr_packets;
242 return 0;
243 }
244
245 case VIDIOC_S_FMT:
246 {
247 struct v4l2_format *f = arg;
248
249 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
250 return -EINVAL;
251
252 /*
253 FIXME: translate and round width/height into EMPRESS
254 subsample type:
255
256 type | PAL | NTSC
257 ---------------------------
258 SIF | 352x288 | 352x240
259 1/2 D1 | 352x576 | 352x480
260 2/3 D1 | 480x576 | 480x480
261 D1 | 720x576 | 720x480
262 */
263
264 f->fmt.pix.width = 720; /* D1 */
265 f->fmt.pix.height = 576;
266 f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
267 f->fmt.pix.sizeimage = TS_PACKET_SIZE* dev->ts.nr_packets;
268 return 0;
269 }
270
271 case VIDIOC_REQBUFS:
272 return videobuf_reqbufs(&dev->empress_tsq,arg);
273
274 case VIDIOC_QUERYBUF:
275 return videobuf_querybuf(&dev->empress_tsq,arg);
276
277 case VIDIOC_QBUF:
278 return videobuf_qbuf(&dev->empress_tsq,arg);
279
280 case VIDIOC_DQBUF:
281 return videobuf_dqbuf(&dev->empress_tsq,arg,
282 file->f_flags & O_NONBLOCK);
283
284 case VIDIOC_STREAMON:
285 return videobuf_streamon(&dev->empress_tsq);
286
287 case VIDIOC_STREAMOFF:
288 return videobuf_streamoff(&dev->empress_tsq);
289
290 case VIDIOC_QUERYCTRL:
291 case VIDIOC_G_CTRL:
292 case VIDIOC_S_CTRL:
293 return saa7134_common_ioctl(dev, cmd, arg);
294
295 case VIDIOC_S_MPEGCOMP:
296 saa7134_i2c_call_clients(dev, VIDIOC_S_MPEGCOMP, arg);
297 ts_init_encoder(dev);
298 return 0;
299 case VIDIOC_G_MPEGCOMP:
300 saa7134_i2c_call_clients(dev, VIDIOC_G_MPEGCOMP, arg);
301 return 0;
302
303 default:
304 return -ENOIOCTLCMD;
305 }
306 return 0;
307}
308
309static int ts_ioctl(struct inode *inode, struct file *file,
310 unsigned int cmd, unsigned long arg)
311{
312 return video_usercopy(inode, file, cmd, arg, ts_do_ioctl);
313}
314
315static struct file_operations ts_fops =
316{
317 .owner = THIS_MODULE,
318 .open = ts_open,
319 .release = ts_release,
320 .read = ts_read,
321 .poll = ts_poll,
322 .mmap = ts_mmap,
323 .ioctl = ts_ioctl,
324 .llseek = no_llseek,
325};
326
327/* ----------------------------------------------------------- */
328
329static struct video_device saa7134_empress_template =
330{
331 .name = "saa7134-empress",
332 .type = 0 /* FIXME */,
333 .type2 = 0 /* FIXME */,
334 .hardware = 0,
335 .fops = &ts_fops,
336 .minor = -1,
337};
338
339static void empress_signal_update(void* data)
340{
341 struct saa7134_dev* dev = (struct saa7134_dev*) data;
342
343 if (dev->nosignal) {
344 dprintk("no video signal\n");
345 ts_reset_encoder(dev);
346 } else {
347 dprintk("video signal acquired\n");
348 if (dev->empress_users)
349 ts_init_encoder(dev);
350 }
351}
352
353static void empress_signal_change(struct saa7134_dev *dev)
354{
355 schedule_work(&dev->empress_workqueue);
356}
357
358
359static int empress_init(struct saa7134_dev *dev)
360{
361 int err;
362
363 dprintk("%s: %s\n",dev->name,__FUNCTION__);
364 dev->empress_dev = video_device_alloc();
365 if (NULL == dev->empress_dev)
366 return -ENOMEM;
367 *(dev->empress_dev) = saa7134_empress_template;
368 dev->empress_dev->dev = &dev->pci->dev;
369 dev->empress_dev->release = video_device_release;
370 snprintf(dev->empress_dev->name, sizeof(dev->empress_dev->name),
371 "%s empress (%s)", dev->name,
372 saa7134_boards[dev->board].name);
373
374 INIT_WORK(&dev->empress_workqueue, empress_signal_update, (void*) dev);
375
376 err = video_register_device(dev->empress_dev,VFL_TYPE_GRABBER,
377 empress_nr[dev->nr]);
378 if (err < 0) {
379 printk(KERN_INFO "%s: can't register video device\n",
380 dev->name);
381 video_device_release(dev->empress_dev);
382 dev->empress_dev = NULL;
383 return err;
384 }
385 printk(KERN_INFO "%s: registered device video%d [mpeg]\n",
386 dev->name,dev->empress_dev->minor & 0x1f);
387
388 videobuf_queue_init(&dev->empress_tsq, &saa7134_ts_qops,
389 dev->pci, &dev->slock,
390 V4L2_BUF_TYPE_VIDEO_CAPTURE,
391 V4L2_FIELD_ALTERNATE,
392 sizeof(struct saa7134_buf),
393 dev);
394
395 empress_signal_update(dev);
396 return 0;
397}
398
399static int empress_fini(struct saa7134_dev *dev)
400{
401 dprintk("%s: %s\n",dev->name,__FUNCTION__);
402
403 if (NULL == dev->empress_dev)
404 return 0;
405 flush_scheduled_work();
406 video_unregister_device(dev->empress_dev);
407 dev->empress_dev = NULL;
408 return 0;
409}
410
411static struct saa7134_mpeg_ops empress_ops = {
412 .type = SAA7134_MPEG_EMPRESS,
413 .init = empress_init,
414 .fini = empress_fini,
415 .signal_change = empress_signal_change,
416};
417
418static int __init empress_register(void)
419{
420 return saa7134_ts_register(&empress_ops);
421}
422
423static void __exit empress_unregister(void)
424{
425 saa7134_ts_unregister(&empress_ops);
426}
427
428module_init(empress_register);
429module_exit(empress_unregister);
430
431/* ----------------------------------------------------------- */
432/*
433 * Local variables:
434 * c-basic-offset: 8
435 * End:
436 */
diff --git a/drivers/media/video/saa7134/saa7134-i2c.c b/drivers/media/video/saa7134/saa7134-i2c.c
new file mode 100644
index 00000000000..702bb63d981
--- /dev/null
+++ b/drivers/media/video/saa7134/saa7134-i2c.c
@@ -0,0 +1,453 @@
1/*
2 * $Id: saa7134-i2c.c,v 1.10 2005/01/24 17:37:23 kraxel Exp $
3 *
4 * device driver for philips saa7134 based TV cards
5 * i2c interface support
6 *
7 * (c) 2001,02 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
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#include <linux/init.h>
25#include <linux/list.h>
26#include <linux/module.h>
27#include <linux/moduleparam.h>
28#include <linux/kernel.h>
29#include <linux/slab.h>
30#include <linux/delay.h>
31
32#include "saa7134-reg.h"
33#include "saa7134.h"
34
35/* ----------------------------------------------------------- */
36
37static unsigned int i2c_debug = 0;
38module_param(i2c_debug, int, 0644);
39MODULE_PARM_DESC(i2c_debug,"enable debug messages [i2c]");
40
41static unsigned int i2c_scan = 0;
42module_param(i2c_scan, int, 0444);
43MODULE_PARM_DESC(i2c_scan,"scan i2c bus at insmod time");
44
45#define d1printk if (1 == i2c_debug) printk
46#define d2printk if (2 == i2c_debug) printk
47
48#define I2C_WAIT_DELAY 32
49#define I2C_WAIT_RETRY 16
50
51/* ----------------------------------------------------------- */
52
53static char *str_i2c_status[] = {
54 "IDLE", "DONE_STOP", "BUSY", "TO_SCL", "TO_ARB", "DONE_WRITE",
55 "DONE_READ", "DONE_WRITE_TO", "DONE_READ_TO", "NO_DEVICE",
56 "NO_ACKN", "BUS_ERR", "ARB_LOST", "SEQ_ERR", "ST_ERR", "SW_ERR"
57};
58
59enum i2c_status {
60 IDLE = 0, // no I2C command pending
61 DONE_STOP = 1, // I2C command done and STOP executed
62 BUSY = 2, // executing I2C command
63 TO_SCL = 3, // executing I2C command, time out on clock stretching
64 TO_ARB = 4, // time out on arbitration trial, still trying
65 DONE_WRITE = 5, // I2C command done and awaiting next write command
66 DONE_READ = 6, // I2C command done and awaiting next read command
67 DONE_WRITE_TO = 7, // see 5, and time out on status echo
68 DONE_READ_TO = 8, // see 6, and time out on status echo
69 NO_DEVICE = 9, // no acknowledge on device slave address
70 NO_ACKN = 10, // no acknowledge after data byte transfer
71 BUS_ERR = 11, // bus error
72 ARB_LOST = 12, // arbitration lost during transfer
73 SEQ_ERR = 13, // erroneous programming sequence
74 ST_ERR = 14, // wrong status echoing
75 SW_ERR = 15 // software error
76};
77
78static char *str_i2c_attr[] = {
79 "NOP", "STOP", "CONTINUE", "START"
80};
81
82enum i2c_attr {
83 NOP = 0, // no operation on I2C bus
84 STOP = 1, // stop condition, no associated byte transfer
85 CONTINUE = 2, // continue with byte transfer
86 START = 3 // start condition with byte transfer
87};
88
89static inline enum i2c_status i2c_get_status(struct saa7134_dev *dev)
90{
91 enum i2c_status status;
92
93 status = saa_readb(SAA7134_I2C_ATTR_STATUS) & 0x0f;
94 d2printk(KERN_DEBUG "%s: i2c stat <= %s\n",dev->name,
95 str_i2c_status[status]);
96 return status;
97}
98
99static inline void i2c_set_status(struct saa7134_dev *dev,
100 enum i2c_status status)
101{
102 d2printk(KERN_DEBUG "%s: i2c stat => %s\n",dev->name,
103 str_i2c_status[status]);
104 saa_andorb(SAA7134_I2C_ATTR_STATUS,0x0f,status);
105}
106
107static inline void i2c_set_attr(struct saa7134_dev *dev, enum i2c_attr attr)
108{
109 d2printk(KERN_DEBUG "%s: i2c attr => %s\n",dev->name,
110 str_i2c_attr[attr]);
111 saa_andorb(SAA7134_I2C_ATTR_STATUS,0xc0,attr << 6);
112}
113
114static inline int i2c_is_error(enum i2c_status status)
115{
116 switch (status) {
117 case NO_DEVICE:
118 case NO_ACKN:
119 case BUS_ERR:
120 case ARB_LOST:
121 case SEQ_ERR:
122 case ST_ERR:
123 return TRUE;
124 default:
125 return FALSE;
126 }
127}
128
129static inline int i2c_is_idle(enum i2c_status status)
130{
131 switch (status) {
132 case IDLE:
133 case DONE_STOP:
134 return TRUE;
135 default:
136 return FALSE;
137 }
138}
139
140static inline int i2c_is_busy(enum i2c_status status)
141{
142 switch (status) {
143 case BUSY:
144 return TRUE;
145 default:
146 return FALSE;
147 }
148}
149
150static int i2c_is_busy_wait(struct saa7134_dev *dev)
151{
152 enum i2c_status status;
153 int count;
154
155 for (count = 0; count < I2C_WAIT_RETRY; count++) {
156 status = i2c_get_status(dev);
157 if (!i2c_is_busy(status))
158 break;
159 saa_wait(I2C_WAIT_DELAY);
160 }
161 if (I2C_WAIT_RETRY == count)
162 return FALSE;
163 return TRUE;
164}
165
166static int i2c_reset(struct saa7134_dev *dev)
167{
168 enum i2c_status status;
169 int count;
170
171 d2printk(KERN_DEBUG "%s: i2c reset\n",dev->name);
172 status = i2c_get_status(dev);
173 if (!i2c_is_error(status))
174 return TRUE;
175 i2c_set_status(dev,status);
176
177 for (count = 0; count < I2C_WAIT_RETRY; count++) {
178 status = i2c_get_status(dev);
179 if (!i2c_is_error(status))
180 break;
181 udelay(I2C_WAIT_DELAY);
182 }
183 if (I2C_WAIT_RETRY == count)
184 return FALSE;
185
186 if (!i2c_is_idle(status))
187 return FALSE;
188
189 i2c_set_attr(dev,NOP);
190 return TRUE;
191}
192
193static inline int i2c_send_byte(struct saa7134_dev *dev,
194 enum i2c_attr attr,
195 unsigned char data)
196{
197 enum i2c_status status;
198 __u32 dword;
199
200#if 0
201 i2c_set_attr(dev,attr);
202 saa_writeb(SAA7134_I2C_DATA, data);
203#else
204 /* have to write both attr + data in one 32bit word */
205 dword = saa_readl(SAA7134_I2C_ATTR_STATUS >> 2);
206 dword &= 0x0f;
207 dword |= (attr << 6);
208 dword |= ((__u32)data << 8);
209 dword |= 0x00 << 16; /* 100 kHz */
210// dword |= 0x40 << 16; /* 400 kHz */
211 dword |= 0xf0 << 24;
212 saa_writel(SAA7134_I2C_ATTR_STATUS >> 2, dword);
213#endif
214 d2printk(KERN_DEBUG "%s: i2c data => 0x%x\n",dev->name,data);
215
216 if (!i2c_is_busy_wait(dev))
217 return -EIO;
218 status = i2c_get_status(dev);
219 if (i2c_is_error(status))
220 return -EIO;
221 return 0;
222}
223
224static inline int i2c_recv_byte(struct saa7134_dev *dev)
225{
226 enum i2c_status status;
227 unsigned char data;
228
229 i2c_set_attr(dev,CONTINUE);
230 if (!i2c_is_busy_wait(dev))
231 return -EIO;
232 status = i2c_get_status(dev);
233 if (i2c_is_error(status))
234 return -EIO;
235 data = saa_readb(SAA7134_I2C_DATA);
236 d2printk(KERN_DEBUG "%s: i2c data <= 0x%x\n",dev->name,data);
237 return data;
238}
239
240static int saa7134_i2c_xfer(struct i2c_adapter *i2c_adap,
241 struct i2c_msg *msgs, int num)
242{
243 struct saa7134_dev *dev = i2c_adap->algo_data;
244 enum i2c_status status;
245 unsigned char data;
246 int addr,rc,i,byte;
247
248 status = i2c_get_status(dev);
249 if (!i2c_is_idle(status))
250 if (!i2c_reset(dev))
251 return -EIO;
252
253 d2printk("start xfer\n");
254 d1printk(KERN_DEBUG "%s: i2c xfer:",dev->name);
255 for (i = 0; i < num; i++) {
256 if (!(msgs[i].flags & I2C_M_NOSTART) || 0 == i) {
257 /* send address */
258 d2printk("send address\n");
259 addr = msgs[i].addr << 1;
260 if (msgs[i].flags & I2C_M_RD)
261 addr |= 1;
262 if (i > 0 && msgs[i].flags & I2C_M_RD) {
263 /* workaround for a saa7134 i2c bug
264 * needed to talk to the mt352 demux
265 * thanks to pinnacle for the hint */
266 int quirk = 0xfd;
267 d1printk(" [%02x quirk]",quirk);
268 i2c_send_byte(dev,START,quirk);
269 i2c_recv_byte(dev);
270 }
271 d1printk(" < %02x", addr);
272 rc = i2c_send_byte(dev,START,addr);
273 if (rc < 0)
274 goto err;
275 }
276 if (msgs[i].flags & I2C_M_RD) {
277 /* read bytes */
278 d2printk("read bytes\n");
279 for (byte = 0; byte < msgs[i].len; byte++) {
280 d1printk(" =");
281 rc = i2c_recv_byte(dev);
282 if (rc < 0)
283 goto err;
284 d1printk("%02x", rc);
285 msgs[i].buf[byte] = rc;
286 }
287 } else {
288 /* write bytes */
289 d2printk("write bytes\n");
290 for (byte = 0; byte < msgs[i].len; byte++) {
291 data = msgs[i].buf[byte];
292 d1printk(" %02x", data);
293 rc = i2c_send_byte(dev,CONTINUE,data);
294 if (rc < 0)
295 goto err;
296 }
297 }
298 }
299 d2printk("xfer done\n");
300 d1printk(" >");
301 i2c_set_attr(dev,STOP);
302 rc = -EIO;
303 if (!i2c_is_busy_wait(dev))
304 goto err;
305 status = i2c_get_status(dev);
306 if (i2c_is_error(status))
307 goto err;
308
309 d1printk("\n");
310 return num;
311 err:
312 if (1 == i2c_debug) {
313 status = i2c_get_status(dev);
314 printk(" ERROR: %s\n",str_i2c_status[status]);
315 }
316 return rc;
317}
318
319/* ----------------------------------------------------------- */
320
321static int algo_control(struct i2c_adapter *adapter,
322 unsigned int cmd, unsigned long arg)
323{
324 return 0;
325}
326
327static u32 functionality(struct i2c_adapter *adap)
328{
329 return I2C_FUNC_SMBUS_EMUL;
330}
331
332static int attach_inform(struct i2c_client *client)
333{
334 struct saa7134_dev *dev = client->adapter->algo_data;
335 int tuner = dev->tuner_type;
336 int conf = dev->tda9887_conf;
337
338 saa7134_i2c_call_clients(dev,TUNER_SET_TYPE,&tuner);
339 saa7134_i2c_call_clients(dev,TDA9887_SET_CONFIG,&conf);
340 return 0;
341}
342
343static struct i2c_algorithm saa7134_algo = {
344 .name = "saa7134",
345 .id = I2C_ALGO_SAA7134,
346 .master_xfer = saa7134_i2c_xfer,
347 .algo_control = algo_control,
348 .functionality = functionality,
349};
350
351static struct i2c_adapter saa7134_adap_template = {
352 .owner = THIS_MODULE,
353#ifdef I2C_CLASS_TV_ANALOG
354 .class = I2C_CLASS_TV_ANALOG,
355#endif
356 I2C_DEVNAME("saa7134"),
357 .id = I2C_ALGO_SAA7134,
358 .algo = &saa7134_algo,
359 .client_register = attach_inform,
360};
361
362static struct i2c_client saa7134_client_template = {
363 I2C_DEVNAME("saa7134 internal"),
364};
365
366/* ----------------------------------------------------------- */
367
368static int
369saa7134_i2c_eeprom(struct saa7134_dev *dev, unsigned char *eedata, int len)
370{
371 unsigned char buf;
372 int i,err;
373
374 dev->i2c_client.addr = 0xa0 >> 1;
375 buf = 0;
376 if (1 != (err = i2c_master_send(&dev->i2c_client,&buf,1))) {
377 printk(KERN_INFO "%s: Huh, no eeprom present (err=%d)?\n",
378 dev->name,err);
379 return -1;
380 }
381 if (len != (err = i2c_master_recv(&dev->i2c_client,eedata,len))) {
382 printk(KERN_WARNING "%s: i2c eeprom read error (err=%d)\n",
383 dev->name,err);
384 return -1;
385 }
386 for (i = 0; i < len; i++) {
387 if (0 == (i % 16))
388 printk(KERN_INFO "%s: i2c eeprom %02x:",dev->name,i);
389 printk(" %02x",eedata[i]);
390 if (15 == (i % 16))
391 printk("\n");
392 }
393 return 0;
394}
395
396static char *i2c_devs[128] = {
397 [ 0x20 ] = "mpeg encoder (saa6752hs)",
398 [ 0xa0 >> 1 ] = "eeprom",
399 [ 0xc0 >> 1 ] = "tuner (analog)",
400 [ 0x86 >> 1 ] = "tda9887",
401};
402
403static void do_i2c_scan(char *name, struct i2c_client *c)
404{
405 unsigned char buf;
406 int i,rc;
407
408 for (i = 0; i < 128; i++) {
409 c->addr = i;
410 rc = i2c_master_recv(c,&buf,0);
411 if (rc < 0)
412 continue;
413 printk("%s: i2c scan: found device @ 0x%x [%s]\n",
414 name, i << 1, i2c_devs[i] ? i2c_devs[i] : "???");
415 }
416}
417
418void saa7134_i2c_call_clients(struct saa7134_dev *dev,
419 unsigned int cmd, void *arg)
420{
421 BUG_ON(NULL == dev->i2c_adap.algo_data);
422 i2c_clients_command(&dev->i2c_adap, cmd, arg);
423}
424
425int saa7134_i2c_register(struct saa7134_dev *dev)
426{
427 dev->i2c_adap = saa7134_adap_template;
428 dev->i2c_adap.dev.parent = &dev->pci->dev;
429 strcpy(dev->i2c_adap.name,dev->name);
430 dev->i2c_adap.algo_data = dev;
431 i2c_add_adapter(&dev->i2c_adap);
432
433 dev->i2c_client = saa7134_client_template;
434 dev->i2c_client.adapter = &dev->i2c_adap;
435
436 saa7134_i2c_eeprom(dev,dev->eedata,sizeof(dev->eedata));
437 if (i2c_scan)
438 do_i2c_scan(dev->name,&dev->i2c_client);
439 return 0;
440}
441
442int saa7134_i2c_unregister(struct saa7134_dev *dev)
443{
444 i2c_del_adapter(&dev->i2c_adap);
445 return 0;
446}
447
448/* ----------------------------------------------------------- */
449/*
450 * Local variables:
451 * c-basic-offset: 8
452 * End:
453 */
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c
new file mode 100644
index 00000000000..727d437e07d
--- /dev/null
+++ b/drivers/media/video/saa7134/saa7134-input.c
@@ -0,0 +1,491 @@
1/*
2 * $Id: saa7134-input.c,v 1.16 2004/12/10 12:33:39 kraxel Exp $
3 *
4 * handle saa7134 IR remotes via linux kernel input layer.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 */
21
22#include <linux/module.h>
23#include <linux/moduleparam.h>
24#include <linux/init.h>
25#include <linux/delay.h>
26#include <linux/sched.h>
27#include <linux/interrupt.h>
28#include <linux/input.h>
29
30#include "saa7134-reg.h"
31#include "saa7134.h"
32
33static unsigned int disable_ir = 0;
34module_param(disable_ir, int, 0444);
35MODULE_PARM_DESC(disable_ir,"disable infrared remote support");
36
37static unsigned int ir_debug = 0;
38module_param(ir_debug, int, 0644);
39MODULE_PARM_DESC(ir_debug,"enable debug messages [IR]");
40
41#define dprintk(fmt, arg...) if (ir_debug) \
42 printk(KERN_DEBUG "%s/ir: " fmt, dev->name , ## arg)
43
44/* ---------------------------------------------------------------------- */
45
46static IR_KEYTAB_TYPE flyvideo_codes[IR_KEYTAB_SIZE] = {
47 [ 15 ] = KEY_KP0,
48 [ 3 ] = KEY_KP1,
49 [ 4 ] = KEY_KP2,
50 [ 5 ] = KEY_KP3,
51 [ 7 ] = KEY_KP4,
52 [ 8 ] = KEY_KP5,
53 [ 9 ] = KEY_KP6,
54 [ 11 ] = KEY_KP7,
55 [ 12 ] = KEY_KP8,
56 [ 13 ] = KEY_KP9,
57
58 [ 14 ] = KEY_TUNER, // Air/Cable
59 [ 17 ] = KEY_VIDEO, // Video
60 [ 21 ] = KEY_AUDIO, // Audio
61 [ 0 ] = KEY_POWER, // Pover
62 [ 2 ] = KEY_ZOOM, // Fullscreen
63 [ 27 ] = KEY_MUTE, // Mute
64 [ 20 ] = KEY_VOLUMEUP,
65 [ 23 ] = KEY_VOLUMEDOWN,
66 [ 18 ] = KEY_CHANNELUP, // Channel +
67 [ 19 ] = KEY_CHANNELDOWN, // Channel -
68 [ 6 ] = KEY_AGAIN, // Recal
69 [ 16 ] = KEY_KPENTER, // Enter
70
71#if 1 /* FIXME */
72 [ 26 ] = KEY_F22, // Stereo
73 [ 24 ] = KEY_EDIT, // AV Source
74#endif
75};
76
77static IR_KEYTAB_TYPE cinergy_codes[IR_KEYTAB_SIZE] = {
78 [ 0 ] = KEY_KP0,
79 [ 1 ] = KEY_KP1,
80 [ 2 ] = KEY_KP2,
81 [ 3 ] = KEY_KP3,
82 [ 4 ] = KEY_KP4,
83 [ 5 ] = KEY_KP5,
84 [ 6 ] = KEY_KP6,
85 [ 7 ] = KEY_KP7,
86 [ 8 ] = KEY_KP8,
87 [ 9 ] = KEY_KP9,
88
89 [ 0x0a ] = KEY_POWER,
90 [ 0x0b ] = KEY_PROG1, // app
91 [ 0x0c ] = KEY_ZOOM, // zoom/fullscreen
92 [ 0x0d ] = KEY_CHANNELUP, // channel
93 [ 0x0e ] = KEY_CHANNELDOWN, // channel-
94 [ 0x0f ] = KEY_VOLUMEUP,
95 [ 0x10 ] = KEY_VOLUMEDOWN,
96 [ 0x11 ] = KEY_TUNER, // AV
97 [ 0x12 ] = KEY_NUMLOCK, // -/--
98 [ 0x13 ] = KEY_AUDIO, // audio
99 [ 0x14 ] = KEY_MUTE,
100 [ 0x15 ] = KEY_UP,
101 [ 0x16 ] = KEY_DOWN,
102 [ 0x17 ] = KEY_LEFT,
103 [ 0x18 ] = KEY_RIGHT,
104 [ 0x19 ] = BTN_LEFT,
105 [ 0x1a ] = BTN_RIGHT,
106 [ 0x1b ] = KEY_WWW, // text
107 [ 0x1c ] = KEY_REWIND,
108 [ 0x1d ] = KEY_FORWARD,
109 [ 0x1e ] = KEY_RECORD,
110 [ 0x1f ] = KEY_PLAY,
111 [ 0x20 ] = KEY_PREVIOUSSONG,
112 [ 0x21 ] = KEY_NEXTSONG,
113 [ 0x22 ] = KEY_PAUSE,
114 [ 0x23 ] = KEY_STOP,
115};
116
117/* Alfons Geser <a.geser@cox.net>
118 * updates from Job D. R. Borges <jobdrb@ig.com.br> */
119static IR_KEYTAB_TYPE eztv_codes[IR_KEYTAB_SIZE] = {
120 [ 18 ] = KEY_POWER,
121 [ 1 ] = KEY_TV, // DVR
122 [ 21 ] = KEY_DVD, // DVD
123 [ 23 ] = KEY_AUDIO, // music
124 // DVR mode / DVD mode / music mode
125
126 [ 27 ] = KEY_MUTE, // mute
127 [ 2 ] = KEY_LANGUAGE, // MTS/SAP / audio / autoseek
128 [ 30 ] = KEY_SUBTITLE, // closed captioning / subtitle / seek
129 [ 22 ] = KEY_ZOOM, // full screen
130 [ 28 ] = KEY_VIDEO, // video source / eject / delall
131 [ 29 ] = KEY_RESTART, // playback / angle / del
132 [ 47 ] = KEY_SEARCH, // scan / menu / playlist
133 [ 48 ] = KEY_CHANNEL, // CH surfing / bookmark / memo
134
135 [ 49 ] = KEY_HELP, // help
136 [ 50 ] = KEY_MODE, // num/memo
137 [ 51 ] = KEY_ESC, // cancel
138
139 [ 12 ] = KEY_UP, // up
140 [ 16 ] = KEY_DOWN, // down
141 [ 8 ] = KEY_LEFT, // left
142 [ 4 ] = KEY_RIGHT, // right
143 [ 3 ] = KEY_SELECT, // select
144
145 [ 31 ] = KEY_REWIND, // rewind
146 [ 32 ] = KEY_PLAYPAUSE, // play/pause
147 [ 41 ] = KEY_FORWARD, // forward
148 [ 20 ] = KEY_AGAIN, // repeat
149 [ 43 ] = KEY_RECORD, // recording
150 [ 44 ] = KEY_STOP, // stop
151 [ 45 ] = KEY_PLAY, // play
152 [ 46 ] = KEY_SHUFFLE, // snapshot / shuffle
153
154 [ 0 ] = KEY_KP0,
155 [ 5 ] = KEY_KP1,
156 [ 6 ] = KEY_KP2,
157 [ 7 ] = KEY_KP3,
158 [ 9 ] = KEY_KP4,
159 [ 10 ] = KEY_KP5,
160 [ 11 ] = KEY_KP6,
161 [ 13 ] = KEY_KP7,
162 [ 14 ] = KEY_KP8,
163 [ 15 ] = KEY_KP9,
164
165 [ 42 ] = KEY_VOLUMEUP,
166 [ 17 ] = KEY_VOLUMEDOWN,
167 [ 24 ] = KEY_CHANNELUP, // CH.tracking up
168 [ 25 ] = KEY_CHANNELDOWN, // CH.tracking down
169
170 [ 19 ] = KEY_KPENTER, // enter
171 [ 33 ] = KEY_KPDOT, // . (decimal dot)
172};
173
174static IR_KEYTAB_TYPE avacssmart_codes[IR_KEYTAB_SIZE] = {
175 [ 30 ] = KEY_POWER, // power
176 [ 28 ] = KEY_SEARCH, // scan
177 [ 7 ] = KEY_SELECT, // source
178
179 [ 22 ] = KEY_VOLUMEUP,
180 [ 20 ] = KEY_VOLUMEDOWN,
181 [ 31 ] = KEY_CHANNELUP,
182 [ 23 ] = KEY_CHANNELDOWN,
183 [ 24 ] = KEY_MUTE,
184
185 [ 2 ] = KEY_KP0,
186 [ 1 ] = KEY_KP1,
187 [ 11 ] = KEY_KP2,
188 [ 27 ] = KEY_KP3,
189 [ 5 ] = KEY_KP4,
190 [ 9 ] = KEY_KP5,
191 [ 21 ] = KEY_KP6,
192 [ 6 ] = KEY_KP7,
193 [ 10 ] = KEY_KP8,
194 [ 18 ] = KEY_KP9,
195 [ 16 ] = KEY_KPDOT,
196
197 [ 3 ] = KEY_TUNER, // tv/fm
198 [ 4 ] = KEY_REWIND, // fm tuning left or function left
199 [ 12 ] = KEY_FORWARD, // fm tuning right or function right
200
201 [ 0 ] = KEY_RECORD,
202 [ 8 ] = KEY_STOP,
203 [ 17 ] = KEY_PLAY,
204
205 [ 25 ] = KEY_ZOOM,
206 [ 14 ] = KEY_MENU, // function
207 [ 19 ] = KEY_AGAIN, // recall
208 [ 29 ] = KEY_RESTART, // reset
209
210// FIXME
211 [ 13 ] = KEY_F21, // mts
212 [ 15 ] = KEY_F22, // min
213 [ 26 ] = KEY_F23, // freeze
214};
215
216/* Alex Hermann <gaaf@gmx.net> */
217static IR_KEYTAB_TYPE md2819_codes[IR_KEYTAB_SIZE] = {
218 [ 40 ] = KEY_KP1,
219 [ 24 ] = KEY_KP2,
220 [ 56 ] = KEY_KP3,
221 [ 36 ] = KEY_KP4,
222 [ 20 ] = KEY_KP5,
223 [ 52 ] = KEY_KP6,
224 [ 44 ] = KEY_KP7,
225 [ 28 ] = KEY_KP8,
226 [ 60 ] = KEY_KP9,
227 [ 34 ] = KEY_KP0,
228
229 [ 32 ] = KEY_TV, // TV/FM
230 [ 16 ] = KEY_CD, // CD
231 [ 48 ] = KEY_TEXT, // TELETEXT
232 [ 0 ] = KEY_POWER, // POWER
233
234 [ 8 ] = KEY_VIDEO, // VIDEO
235 [ 4 ] = KEY_AUDIO, // AUDIO
236 [ 12 ] = KEY_ZOOM, // FULL SCREEN
237
238 [ 18 ] = KEY_SUBTITLE, // DISPLAY - ???
239 [ 50 ] = KEY_REWIND, // LOOP - ???
240 [ 2 ] = KEY_PRINT, // PREVIEW - ???
241
242 [ 42 ] = KEY_SEARCH, // AUTOSCAN
243 [ 26 ] = KEY_SLEEP, // FREEZE - ???
244 [ 58 ] = KEY_SHUFFLE, // SNAPSHOT - ???
245 [ 10 ] = KEY_MUTE, // MUTE
246
247 [ 38 ] = KEY_RECORD, // RECORD
248 [ 22 ] = KEY_PAUSE, // PAUSE
249 [ 54 ] = KEY_STOP, // STOP
250 [ 6 ] = KEY_PLAY, // PLAY
251
252 [ 46 ] = KEY_RED, // <RED>
253 [ 33 ] = KEY_GREEN, // <GREEN>
254 [ 14 ] = KEY_YELLOW, // <YELLOW>
255 [ 1 ] = KEY_BLUE, // <BLUE>
256
257 [ 30 ] = KEY_VOLUMEDOWN, // VOLUME-
258 [ 62 ] = KEY_VOLUMEUP, // VOLUME+
259 [ 17 ] = KEY_CHANNELDOWN, // CHANNEL/PAGE-
260 [ 49 ] = KEY_CHANNELUP // CHANNEL/PAGE+
261};
262
263static IR_KEYTAB_TYPE videomate_tv_pvr_codes[IR_KEYTAB_SIZE] = {
264 [ 20 ] = KEY_MUTE,
265 [ 36 ] = KEY_ZOOM,
266
267 [ 1 ] = KEY_DVD,
268 [ 35 ] = KEY_RADIO,
269 [ 0 ] = KEY_TV,
270
271 [ 10 ] = KEY_REWIND,
272 [ 8 ] = KEY_PLAYPAUSE,
273 [ 15 ] = KEY_FORWARD,
274
275 [ 2 ] = KEY_PREVIOUS,
276 [ 7 ] = KEY_STOP,
277 [ 6 ] = KEY_NEXT,
278
279 [ 12 ] = KEY_UP,
280 [ 14 ] = KEY_DOWN,
281 [ 11 ] = KEY_LEFT,
282 [ 13 ] = KEY_RIGHT,
283 [ 17 ] = KEY_OK,
284
285 [ 3 ] = KEY_MENU,
286 [ 9 ] = KEY_SETUP,
287 [ 5 ] = KEY_VIDEO,
288 [ 34 ] = KEY_CHANNEL,
289
290 [ 18 ] = KEY_VOLUMEUP,
291 [ 21 ] = KEY_VOLUMEDOWN,
292 [ 16 ] = KEY_CHANNELUP,
293 [ 19 ] = KEY_CHANNELDOWN,
294
295 [ 4 ] = KEY_RECORD,
296
297 [ 22 ] = KEY_KP1,
298 [ 23 ] = KEY_KP2,
299 [ 24 ] = KEY_KP3,
300 [ 25 ] = KEY_KP4,
301 [ 26 ] = KEY_KP5,
302 [ 27 ] = KEY_KP6,
303 [ 28 ] = KEY_KP7,
304 [ 29 ] = KEY_KP8,
305 [ 30 ] = KEY_KP9,
306 [ 31 ] = KEY_KP0,
307
308 [ 32 ] = KEY_LANGUAGE,
309 [ 33 ] = KEY_SLEEP,
310};
311/* ---------------------------------------------------------------------- */
312
313static int build_key(struct saa7134_dev *dev)
314{
315 struct saa7134_ir *ir = dev->remote;
316 u32 gpio, data;
317
318 /* rising SAA7134_GPIO_GPRESCAN reads the status */
319 saa_clearb(SAA7134_GPIO_GPMODE3,SAA7134_GPIO_GPRESCAN);
320 saa_setb(SAA7134_GPIO_GPMODE3,SAA7134_GPIO_GPRESCAN);
321
322 gpio = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2);
323 if (ir->polling) {
324 if (ir->last_gpio == gpio)
325 return 0;
326 ir->last_gpio = gpio;
327 }
328
329 data = ir_extract_bits(gpio, ir->mask_keycode);
330 dprintk("build_key gpio=0x%x mask=0x%x data=%d\n",
331 gpio, ir->mask_keycode, data);
332
333 if ((ir->mask_keydown && (0 != (gpio & ir->mask_keydown))) ||
334 (ir->mask_keyup && (0 == (gpio & ir->mask_keyup)))) {
335 ir_input_keydown(&ir->dev,&ir->ir,data,data);
336 } else {
337 ir_input_nokey(&ir->dev,&ir->ir);
338 }
339 return 0;
340}
341
342/* ---------------------------------------------------------------------- */
343
344void saa7134_input_irq(struct saa7134_dev *dev)
345{
346 struct saa7134_ir *ir = dev->remote;
347
348 if (!ir->polling)
349 build_key(dev);
350}
351
352static void saa7134_input_timer(unsigned long data)
353{
354 struct saa7134_dev *dev = (struct saa7134_dev*)data;
355 struct saa7134_ir *ir = dev->remote;
356 unsigned long timeout;
357
358 build_key(dev);
359 timeout = jiffies + (ir->polling * HZ / 1000);
360 mod_timer(&ir->timer, timeout);
361}
362
363int saa7134_input_init1(struct saa7134_dev *dev)
364{
365 struct saa7134_ir *ir;
366 IR_KEYTAB_TYPE *ir_codes = NULL;
367 u32 mask_keycode = 0;
368 u32 mask_keydown = 0;
369 u32 mask_keyup = 0;
370 int polling = 0;
371 int ir_type = IR_TYPE_OTHER;
372
373 if (!dev->has_remote)
374 return -ENODEV;
375 if (disable_ir)
376 return -ENODEV;
377
378 /* detect & configure */
379 switch (dev->board) {
380 case SAA7134_BOARD_FLYVIDEO2000:
381 case SAA7134_BOARD_FLYVIDEO3000:
382 ir_codes = flyvideo_codes;
383 mask_keycode = 0xEC00000;
384 mask_keydown = 0x0040000;
385 break;
386 case SAA7134_BOARD_CINERGY400:
387 case SAA7134_BOARD_CINERGY600:
388 case SAA7134_BOARD_CINERGY600_MK3:
389 ir_codes = cinergy_codes;
390 mask_keycode = 0x00003f;
391 mask_keyup = 0x040000;
392 break;
393 case SAA7134_BOARD_ECS_TVP3XP:
394 case SAA7134_BOARD_ECS_TVP3XP_4CB5:
395 ir_codes = eztv_codes;
396 mask_keycode = 0x00017c;
397 mask_keyup = 0x000002;
398 polling = 50; // ms
399 break;
400 case SAA7134_BOARD_AVACSSMARTTV:
401 ir_codes = avacssmart_codes;
402 mask_keycode = 0x00001F;
403 mask_keyup = 0x000020;
404 polling = 50; // ms
405 break;
406 case SAA7134_BOARD_MD2819:
407 case SAA7134_BOARD_AVERMEDIA_305:
408 case SAA7134_BOARD_AVERMEDIA_307:
409 ir_codes = md2819_codes;
410 mask_keycode = 0x0007C8;
411 mask_keydown = 0x000010;
412 polling = 50; // ms
413 /* Set GPIO pin2 to high to enable the IR controller */
414 saa_setb(SAA7134_GPIO_GPMODE0, 0x4);
415 saa_setb(SAA7134_GPIO_GPSTATUS0, 0x4);
416 break;
417 case SAA7134_BOARD_VIDEOMATE_TV_PVR:
418 ir_codes = videomate_tv_pvr_codes;
419 mask_keycode = 0x00003F;
420 mask_keyup = 0x400000;
421 polling = 50; // ms
422 break;
423 }
424 if (NULL == ir_codes) {
425 printk("%s: Oops: IR config error [card=%d]\n",
426 dev->name, dev->board);
427 return -ENODEV;
428 }
429
430 ir = kmalloc(sizeof(*ir),GFP_KERNEL);
431 if (NULL == ir)
432 return -ENOMEM;
433 memset(ir,0,sizeof(*ir));
434
435 /* init hardware-specific stuff */
436 ir->mask_keycode = mask_keycode;
437 ir->mask_keydown = mask_keydown;
438 ir->mask_keyup = mask_keyup;
439 ir->polling = polling;
440
441 /* init input device */
442 snprintf(ir->name, sizeof(ir->name), "saa7134 IR (%s)",
443 saa7134_boards[dev->board].name);
444 snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0",
445 pci_name(dev->pci));
446
447 ir_input_init(&ir->dev, &ir->ir, ir_type, ir_codes);
448 ir->dev.name = ir->name;
449 ir->dev.phys = ir->phys;
450 ir->dev.id.bustype = BUS_PCI;
451 ir->dev.id.version = 1;
452 if (dev->pci->subsystem_vendor) {
453 ir->dev.id.vendor = dev->pci->subsystem_vendor;
454 ir->dev.id.product = dev->pci->subsystem_device;
455 } else {
456 ir->dev.id.vendor = dev->pci->vendor;
457 ir->dev.id.product = dev->pci->device;
458 }
459
460 /* all done */
461 dev->remote = ir;
462 if (ir->polling) {
463 init_timer(&ir->timer);
464 ir->timer.function = saa7134_input_timer;
465 ir->timer.data = (unsigned long)dev;
466 ir->timer.expires = jiffies + HZ;
467 add_timer(&ir->timer);
468 }
469
470 input_register_device(&dev->remote->dev);
471 printk("%s: registered input device for IR\n",dev->name);
472 return 0;
473}
474
475void saa7134_input_fini(struct saa7134_dev *dev)
476{
477 if (NULL == dev->remote)
478 return;
479
480 input_unregister_device(&dev->remote->dev);
481 if (dev->remote->polling)
482 del_timer_sync(&dev->remote->timer);
483 kfree(dev->remote);
484 dev->remote = NULL;
485}
486
487/* ----------------------------------------------------------------------
488 * Local variables:
489 * c-basic-offset: 8
490 * End:
491 */
diff --git a/drivers/media/video/saa7134/saa7134-oss.c b/drivers/media/video/saa7134/saa7134-oss.c
new file mode 100644
index 00000000000..6b6a643bf1c
--- /dev/null
+++ b/drivers/media/video/saa7134/saa7134-oss.c
@@ -0,0 +1,857 @@
1/*
2 * $Id: saa7134-oss.c,v 1.13 2004/12/10 12:33:39 kraxel Exp $
3 *
4 * device driver for philips saa7134 based TV cards
5 * oss dsp interface
6 *
7 * (c) 2001,02 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
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#include <linux/init.h>
25#include <linux/list.h>
26#include <linux/module.h>
27#include <linux/moduleparam.h>
28#include <linux/kernel.h>
29#include <linux/slab.h>
30#include <linux/soundcard.h>
31
32#include "saa7134-reg.h"
33#include "saa7134.h"
34
35/* ------------------------------------------------------------------ */
36
37static unsigned int oss_debug = 0;
38module_param(oss_debug, int, 0644);
39MODULE_PARM_DESC(oss_debug,"enable debug messages [oss]");
40
41static unsigned int oss_rate = 0;
42module_param(oss_rate, int, 0444);
43MODULE_PARM_DESC(oss_rate,"sample rate (valid are: 32000,48000)");
44
45#define dprintk(fmt, arg...) if (oss_debug) \
46 printk(KERN_DEBUG "%s/oss: " fmt, dev->name , ## arg)
47
48/* ------------------------------------------------------------------ */
49
50static int dsp_buffer_conf(struct saa7134_dev *dev, int blksize, int blocks)
51{
52 blksize &= ~0xff;
53 if (blksize < 0x100)
54 blksize = 0x100;
55 if (blksize > 0x10000)
56 blksize = 0x10000;
57
58 if (blocks < 2)
59 blocks = 2;
60 while ((blksize * blocks) & ~PAGE_MASK)
61 blocks++;
62 if ((blksize * blocks) > 1024*1024)
63 blocks = 1024*1024 / blksize;
64
65 dev->oss.blocks = blocks;
66 dev->oss.blksize = blksize;
67 dev->oss.bufsize = blksize * blocks;
68
69 dprintk("buffer config: %d blocks / %d bytes, %d kB total\n",
70 blocks,blksize,blksize * blocks / 1024);
71 return 0;
72}
73
74static int dsp_buffer_init(struct saa7134_dev *dev)
75{
76 int err;
77
78 if (!dev->oss.bufsize)
79 BUG();
80 videobuf_dma_init(&dev->oss.dma);
81 err = videobuf_dma_init_kernel(&dev->oss.dma, PCI_DMA_FROMDEVICE,
82 dev->oss.bufsize >> PAGE_SHIFT);
83 if (0 != err)
84 return err;
85 return 0;
86}
87
88static int dsp_buffer_free(struct saa7134_dev *dev)
89{
90 if (!dev->oss.blksize)
91 BUG();
92 videobuf_dma_free(&dev->oss.dma);
93 dev->oss.blocks = 0;
94 dev->oss.blksize = 0;
95 dev->oss.bufsize = 0;
96 return 0;
97}
98
99static void dsp_dma_start(struct saa7134_dev *dev)
100{
101 dev->oss.dma_blk = 0;
102 dev->oss.dma_running = 1;
103 saa7134_set_dmabits(dev);
104}
105
106static void dsp_dma_stop(struct saa7134_dev *dev)
107{
108 dev->oss.dma_blk = -1;
109 dev->oss.dma_running = 0;
110 saa7134_set_dmabits(dev);
111}
112
113static int dsp_rec_start(struct saa7134_dev *dev)
114{
115 int err, bswap, sign;
116 u32 fmt, control;
117 unsigned long flags;
118
119 /* prepare buffer */
120 if (0 != (err = videobuf_dma_pci_map(dev->pci,&dev->oss.dma)))
121 return err;
122 if (0 != (err = saa7134_pgtable_alloc(dev->pci,&dev->oss.pt)))
123 goto fail1;
124 if (0 != (err = saa7134_pgtable_build(dev->pci,&dev->oss.pt,
125 dev->oss.dma.sglist,
126 dev->oss.dma.sglen,
127 0)))
128 goto fail2;
129
130 /* sample format */
131 switch (dev->oss.afmt) {
132 case AFMT_U8:
133 case AFMT_S8: fmt = 0x00; break;
134 case AFMT_U16_LE:
135 case AFMT_U16_BE:
136 case AFMT_S16_LE:
137 case AFMT_S16_BE: fmt = 0x01; break;
138 default:
139 err = -EINVAL;
140 goto fail2;
141 }
142
143 switch (dev->oss.afmt) {
144 case AFMT_S8:
145 case AFMT_S16_LE:
146 case AFMT_S16_BE: sign = 1; break;
147 default: sign = 0; break;
148 }
149
150 switch (dev->oss.afmt) {
151 case AFMT_U16_BE:
152 case AFMT_S16_BE: bswap = 1; break;
153 default: bswap = 0; break;
154 }
155
156 switch (dev->pci->device) {
157 case PCI_DEVICE_ID_PHILIPS_SAA7134:
158 if (1 == dev->oss.channels)
159 fmt |= (1 << 3);
160 if (2 == dev->oss.channels)
161 fmt |= (3 << 3);
162 if (sign)
163 fmt |= 0x04;
164 fmt |= (TV == dev->oss.input) ? 0xc0 : 0x80;
165
166 saa_writeb(SAA7134_NUM_SAMPLES0, (dev->oss.blksize & 0x0000ff));
167 saa_writeb(SAA7134_NUM_SAMPLES1, (dev->oss.blksize & 0x00ff00) >> 8);
168 saa_writeb(SAA7134_NUM_SAMPLES2, (dev->oss.blksize & 0xff0000) >> 16);
169 saa_writeb(SAA7134_AUDIO_FORMAT_CTRL, fmt);
170 break;
171 case PCI_DEVICE_ID_PHILIPS_SAA7133:
172 case PCI_DEVICE_ID_PHILIPS_SAA7135:
173 if (1 == dev->oss.channels)
174 fmt |= (1 << 4);
175 if (2 == dev->oss.channels)
176 fmt |= (2 << 4);
177 if (!sign)
178 fmt |= 0x04;
179 saa_writel(0x588 >> 2, dev->oss.blksize -4);
180 saa_writel(0x58c >> 2, 0x543210 | (fmt << 24));
181 break;
182 }
183 dprintk("rec_start: afmt=%d ch=%d => fmt=0x%x swap=%c\n",
184 dev->oss.afmt, dev->oss.channels, fmt,
185 bswap ? 'b' : '-');
186
187 /* dma: setup channel 6 (= AUDIO) */
188 control = SAA7134_RS_CONTROL_BURST_16 |
189 SAA7134_RS_CONTROL_ME |
190 (dev->oss.pt.dma >> 12);
191 if (bswap)
192 control |= SAA7134_RS_CONTROL_BSWAP;
193 saa_writel(SAA7134_RS_BA1(6),0);
194 saa_writel(SAA7134_RS_BA2(6),dev->oss.blksize);
195 saa_writel(SAA7134_RS_PITCH(6),0);
196 saa_writel(SAA7134_RS_CONTROL(6),control);
197
198 /* start dma */
199 dev->oss.recording_on = 1;
200 spin_lock_irqsave(&dev->slock,flags);
201 dsp_dma_start(dev);
202 spin_unlock_irqrestore(&dev->slock,flags);
203 return 0;
204
205 fail2:
206 saa7134_pgtable_free(dev->pci,&dev->oss.pt);
207 fail1:
208 videobuf_dma_pci_unmap(dev->pci,&dev->oss.dma);
209 return err;
210}
211
212static int dsp_rec_stop(struct saa7134_dev *dev)
213{
214 unsigned long flags;
215
216 dprintk("rec_stop dma_blk=%d\n",dev->oss.dma_blk);
217
218 /* stop dma */
219 dev->oss.recording_on = 0;
220 spin_lock_irqsave(&dev->slock,flags);
221 dsp_dma_stop(dev);
222 spin_unlock_irqrestore(&dev->slock,flags);
223
224 /* unlock buffer */
225 saa7134_pgtable_free(dev->pci,&dev->oss.pt);
226 videobuf_dma_pci_unmap(dev->pci,&dev->oss.dma);
227 return 0;
228}
229
230/* ------------------------------------------------------------------ */
231
232static int dsp_open(struct inode *inode, struct file *file)
233{
234 int minor = iminor(inode);
235 struct saa7134_dev *h,*dev = NULL;
236 struct list_head *list;
237 int err;
238
239 list_for_each(list,&saa7134_devlist) {
240 h = list_entry(list, struct saa7134_dev, devlist);
241 if (h->oss.minor_dsp == minor)
242 dev = h;
243 }
244 if (NULL == dev)
245 return -ENODEV;
246
247 down(&dev->oss.lock);
248 err = -EBUSY;
249 if (dev->oss.users_dsp)
250 goto fail1;
251 dev->oss.users_dsp++;
252 file->private_data = dev;
253
254 dev->oss.afmt = AFMT_U8;
255 dev->oss.channels = 1;
256 dev->oss.read_count = 0;
257 dev->oss.read_offset = 0;
258 dsp_buffer_conf(dev,PAGE_SIZE,64);
259 err = dsp_buffer_init(dev);
260 if (0 != err)
261 goto fail2;
262
263 up(&dev->oss.lock);
264 return 0;
265
266 fail2:
267 dev->oss.users_dsp--;
268 fail1:
269 up(&dev->oss.lock);
270 return err;
271}
272
273static int dsp_release(struct inode *inode, struct file *file)
274{
275 struct saa7134_dev *dev = file->private_data;
276
277 down(&dev->oss.lock);
278 if (dev->oss.recording_on)
279 dsp_rec_stop(dev);
280 dsp_buffer_free(dev);
281 dev->oss.users_dsp--;
282 file->private_data = NULL;
283 up(&dev->oss.lock);
284 return 0;
285}
286
287static ssize_t dsp_read(struct file *file, char __user *buffer,
288 size_t count, loff_t *ppos)
289{
290 struct saa7134_dev *dev = file->private_data;
291 DECLARE_WAITQUEUE(wait, current);
292 unsigned int bytes;
293 unsigned long flags;
294 int err,ret = 0;
295
296 add_wait_queue(&dev->oss.wq, &wait);
297 down(&dev->oss.lock);
298 while (count > 0) {
299 /* wait for data if needed */
300 if (0 == dev->oss.read_count) {
301 if (!dev->oss.recording_on) {
302 err = dsp_rec_start(dev);
303 if (err < 0) {
304 if (0 == ret)
305 ret = err;
306 break;
307 }
308 }
309 if (dev->oss.recording_on &&
310 !dev->oss.dma_running) {
311 /* recover from overruns */
312 spin_lock_irqsave(&dev->slock,flags);
313 dsp_dma_start(dev);
314 spin_unlock_irqrestore(&dev->slock,flags);
315 }
316 if (file->f_flags & O_NONBLOCK) {
317 if (0 == ret)
318 ret = -EAGAIN;
319 break;
320 }
321 up(&dev->oss.lock);
322 set_current_state(TASK_INTERRUPTIBLE);
323 if (0 == dev->oss.read_count)
324 schedule();
325 set_current_state(TASK_RUNNING);
326 down(&dev->oss.lock);
327 if (signal_pending(current)) {
328 if (0 == ret)
329 ret = -EINTR;
330 break;
331 }
332 }
333
334 /* copy data to userspace */
335 bytes = count;
336 if (bytes > dev->oss.read_count)
337 bytes = dev->oss.read_count;
338 if (bytes > dev->oss.bufsize - dev->oss.read_offset)
339 bytes = dev->oss.bufsize - dev->oss.read_offset;
340 if (copy_to_user(buffer + ret,
341 dev->oss.dma.vmalloc + dev->oss.read_offset,
342 bytes)) {
343 if (0 == ret)
344 ret = -EFAULT;
345 break;
346 }
347
348 ret += bytes;
349 count -= bytes;
350 dev->oss.read_count -= bytes;
351 dev->oss.read_offset += bytes;
352 if (dev->oss.read_offset == dev->oss.bufsize)
353 dev->oss.read_offset = 0;
354 }
355 up(&dev->oss.lock);
356 remove_wait_queue(&dev->oss.wq, &wait);
357 return ret;
358}
359
360static ssize_t dsp_write(struct file *file, const char __user *buffer,
361 size_t count, loff_t *ppos)
362{
363 return -EINVAL;
364}
365
366static int dsp_ioctl(struct inode *inode, struct file *file,
367 unsigned int cmd, unsigned long arg)
368{
369 struct saa7134_dev *dev = file->private_data;
370 void __user *argp = (void __user *) arg;
371 int __user *p = argp;
372 int val = 0;
373
374 if (oss_debug > 1)
375 saa7134_print_ioctl(dev->name,cmd);
376 switch (cmd) {
377 case OSS_GETVERSION:
378 return put_user(SOUND_VERSION, p);
379 case SNDCTL_DSP_GETCAPS:
380 return 0;
381
382 case SNDCTL_DSP_SPEED:
383 if (get_user(val, p))
384 return -EFAULT;
385 /* fall through */
386 case SOUND_PCM_READ_RATE:
387 return put_user(dev->oss.rate, p);
388
389 case SNDCTL_DSP_STEREO:
390 if (get_user(val, p))
391 return -EFAULT;
392 down(&dev->oss.lock);
393 dev->oss.channels = val ? 2 : 1;
394 if (dev->oss.recording_on) {
395 dsp_rec_stop(dev);
396 dsp_rec_start(dev);
397 }
398 up(&dev->oss.lock);
399 return put_user(dev->oss.channels-1, p);
400
401 case SNDCTL_DSP_CHANNELS:
402 if (get_user(val, p))
403 return -EFAULT;
404 if (val != 1 && val != 2)
405 return -EINVAL;
406 down(&dev->oss.lock);
407 dev->oss.channels = val;
408 if (dev->oss.recording_on) {
409 dsp_rec_stop(dev);
410 dsp_rec_start(dev);
411 }
412 up(&dev->oss.lock);
413 /* fall through */
414 case SOUND_PCM_READ_CHANNELS:
415 return put_user(dev->oss.channels, p);
416
417 case SNDCTL_DSP_GETFMTS: /* Returns a mask */
418 return put_user(AFMT_U8 | AFMT_S8 |
419 AFMT_U16_LE | AFMT_U16_BE |
420 AFMT_S16_LE | AFMT_S16_BE, p);
421
422 case SNDCTL_DSP_SETFMT: /* Selects ONE fmt */
423 if (get_user(val, p))
424 return -EFAULT;
425 switch (val) {
426 case AFMT_QUERY:
427 /* nothing to do */
428 break;
429 case AFMT_U8:
430 case AFMT_S8:
431 case AFMT_U16_LE:
432 case AFMT_U16_BE:
433 case AFMT_S16_LE:
434 case AFMT_S16_BE:
435 down(&dev->oss.lock);
436 dev->oss.afmt = val;
437 if (dev->oss.recording_on) {
438 dsp_rec_stop(dev);
439 dsp_rec_start(dev);
440 }
441 up(&dev->oss.lock);
442 return put_user(dev->oss.afmt, p);
443 default:
444 return -EINVAL;
445 }
446
447 case SOUND_PCM_READ_BITS:
448 switch (dev->oss.afmt) {
449 case AFMT_U8:
450 case AFMT_S8:
451 return put_user(8, p);
452 case AFMT_U16_LE:
453 case AFMT_U16_BE:
454 case AFMT_S16_LE:
455 case AFMT_S16_BE:
456 return put_user(16, p);
457 default:
458 return -EINVAL;
459 }
460
461 case SNDCTL_DSP_NONBLOCK:
462 file->f_flags |= O_NONBLOCK;
463 return 0;
464
465 case SNDCTL_DSP_RESET:
466 down(&dev->oss.lock);
467 if (dev->oss.recording_on)
468 dsp_rec_stop(dev);
469 up(&dev->oss.lock);
470 return 0;
471 case SNDCTL_DSP_GETBLKSIZE:
472 return put_user(dev->oss.blksize, p);
473
474 case SNDCTL_DSP_SETFRAGMENT:
475 if (get_user(val, p))
476 return -EFAULT;
477 if (dev->oss.recording_on)
478 return -EBUSY;
479 dsp_buffer_free(dev);
480 /* used to be arg >> 16 instead of val >> 16; fixed */
481 dsp_buffer_conf(dev,1 << (val & 0xffff), (val >> 16) & 0xffff);
482 dsp_buffer_init(dev);
483 return 0;
484
485 case SNDCTL_DSP_SYNC:
486 /* NOP */
487 return 0;
488
489 case SNDCTL_DSP_GETISPACE:
490 {
491 audio_buf_info info;
492 info.fragsize = dev->oss.blksize;
493 info.fragstotal = dev->oss.blocks;
494 info.bytes = dev->oss.read_count;
495 info.fragments = info.bytes / info.fragsize;
496 if (copy_to_user(argp, &info, sizeof(info)))
497 return -EFAULT;
498 return 0;
499 }
500 default:
501 return -EINVAL;
502 }
503}
504
505static unsigned int dsp_poll(struct file *file, struct poll_table_struct *wait)
506{
507 struct saa7134_dev *dev = file->private_data;
508 unsigned int mask = 0;
509
510 poll_wait(file, &dev->oss.wq, wait);
511
512 if (0 == dev->oss.read_count) {
513 down(&dev->oss.lock);
514 if (!dev->oss.recording_on)
515 dsp_rec_start(dev);
516 up(&dev->oss.lock);
517 } else
518 mask |= (POLLIN | POLLRDNORM);
519 return mask;
520}
521
522struct file_operations saa7134_dsp_fops = {
523 .owner = THIS_MODULE,
524 .open = dsp_open,
525 .release = dsp_release,
526 .read = dsp_read,
527 .write = dsp_write,
528 .ioctl = dsp_ioctl,
529 .poll = dsp_poll,
530 .llseek = no_llseek,
531};
532
533/* ------------------------------------------------------------------ */
534
535static int
536mixer_recsrc_7134(struct saa7134_dev *dev)
537{
538 int analog_io,rate;
539
540 switch (dev->oss.input) {
541 case TV:
542 saa_andorb(SAA7134_AUDIO_FORMAT_CTRL, 0xc0, 0xc0);
543 saa_andorb(SAA7134_SIF_SAMPLE_FREQ, 0x03, 0x00);
544 break;
545 case LINE1:
546 case LINE2:
547 case LINE2_LEFT:
548 analog_io = (LINE1 == dev->oss.input) ? 0x00 : 0x08;
549 rate = (32000 == dev->oss.rate) ? 0x01 : 0x03;
550 saa_andorb(SAA7134_ANALOG_IO_SELECT, 0x08, analog_io);
551 saa_andorb(SAA7134_AUDIO_FORMAT_CTRL, 0xc0, 0x80);
552 saa_andorb(SAA7134_SIF_SAMPLE_FREQ, 0x03, rate);
553 break;
554 }
555 return 0;
556}
557
558static int
559mixer_recsrc_7133(struct saa7134_dev *dev)
560{
561 u32 value = 0xbbbbbb;
562
563 switch (dev->oss.input) {
564 case TV:
565 value = 0xbbbb10; /* MAIN */
566 break;
567 case LINE1:
568 value = 0xbbbb32; /* AUX1 */
569 break;
570 case LINE2:
571 case LINE2_LEFT:
572 value = 0xbbbb54; /* AUX2 */
573 break;
574 }
575 saa_dsp_writel(dev, 0x46c >> 2, value);
576 return 0;
577}
578
579static int
580mixer_recsrc(struct saa7134_dev *dev, enum saa7134_audio_in src)
581{
582 static const char *iname[] = { "Oops", "TV", "LINE1", "LINE2" };
583
584 dev->oss.count++;
585 dev->oss.input = src;
586 dprintk("mixer input = %s\n",iname[dev->oss.input]);
587
588 switch (dev->pci->device) {
589 case PCI_DEVICE_ID_PHILIPS_SAA7134:
590 mixer_recsrc_7134(dev);
591 break;
592 case PCI_DEVICE_ID_PHILIPS_SAA7133:
593 case PCI_DEVICE_ID_PHILIPS_SAA7135:
594 mixer_recsrc_7133(dev);
595 break;
596 }
597 return 0;
598}
599
600static int
601mixer_level(struct saa7134_dev *dev, enum saa7134_audio_in src, int level)
602{
603 switch (dev->pci->device) {
604 case PCI_DEVICE_ID_PHILIPS_SAA7134:
605 switch (src) {
606 case TV:
607 /* nothing */
608 break;
609 case LINE1:
610 saa_andorb(SAA7134_ANALOG_IO_SELECT, 0x10,
611 (100 == level) ? 0x00 : 0x10);
612 break;
613 case LINE2:
614 case LINE2_LEFT:
615 saa_andorb(SAA7134_ANALOG_IO_SELECT, 0x20,
616 (100 == level) ? 0x00 : 0x20);
617 break;
618 }
619 break;
620 case PCI_DEVICE_ID_PHILIPS_SAA7133:
621 case PCI_DEVICE_ID_PHILIPS_SAA7135:
622 /* nothing */
623 break;
624 }
625 return 0;
626}
627
628/* ------------------------------------------------------------------ */
629
630static int mixer_open(struct inode *inode, struct file *file)
631{
632 int minor = iminor(inode);
633 struct saa7134_dev *h,*dev = NULL;
634 struct list_head *list;
635
636 list_for_each(list,&saa7134_devlist) {
637 h = list_entry(list, struct saa7134_dev, devlist);
638 if (h->oss.minor_mixer == minor)
639 dev = h;
640 }
641 if (NULL == dev)
642 return -ENODEV;
643
644 file->private_data = dev;
645 return 0;
646}
647
648static int mixer_release(struct inode *inode, struct file *file)
649{
650 file->private_data = NULL;
651 return 0;
652}
653
654static int mixer_ioctl(struct inode *inode, struct file *file,
655 unsigned int cmd, unsigned long arg)
656{
657 struct saa7134_dev *dev = file->private_data;
658 enum saa7134_audio_in input;
659 int val,ret;
660 void __user *argp = (void __user *) arg;
661 int __user *p = argp;
662
663 if (oss_debug > 1)
664 saa7134_print_ioctl(dev->name,cmd);
665 switch (cmd) {
666 case OSS_GETVERSION:
667 return put_user(SOUND_VERSION, p);
668 case SOUND_MIXER_INFO:
669 {
670 mixer_info info;
671 memset(&info,0,sizeof(info));
672 strlcpy(info.id, "TV audio", sizeof(info.id));
673 strlcpy(info.name, dev->name, sizeof(info.name));
674 info.modify_counter = dev->oss.count;
675 if (copy_to_user(argp, &info, sizeof(info)))
676 return -EFAULT;
677 return 0;
678 }
679 case SOUND_OLD_MIXER_INFO:
680 {
681 _old_mixer_info info;
682 memset(&info,0,sizeof(info));
683 strlcpy(info.id, "TV audio", sizeof(info.id));
684 strlcpy(info.name, dev->name, sizeof(info.name));
685 if (copy_to_user(argp, &info, sizeof(info)))
686 return -EFAULT;
687 return 0;
688 }
689 case MIXER_READ(SOUND_MIXER_CAPS):
690 return put_user(SOUND_CAP_EXCL_INPUT, p);
691 case MIXER_READ(SOUND_MIXER_STEREODEVS):
692 return put_user(0, p);
693 case MIXER_READ(SOUND_MIXER_RECMASK):
694 case MIXER_READ(SOUND_MIXER_DEVMASK):
695 val = SOUND_MASK_LINE1 | SOUND_MASK_LINE2;
696 if (32000 == dev->oss.rate)
697 val |= SOUND_MASK_VIDEO;
698 return put_user(val, p);
699
700 case MIXER_WRITE(SOUND_MIXER_RECSRC):
701 if (get_user(val, p))
702 return -EFAULT;
703 input = dev->oss.input;
704 if (32000 == dev->oss.rate &&
705 val & SOUND_MASK_VIDEO && dev->oss.input != TV)
706 input = TV;
707 if (val & SOUND_MASK_LINE1 && dev->oss.input != LINE1)
708 input = LINE1;
709 if (val & SOUND_MASK_LINE2 && dev->oss.input != LINE2)
710 input = LINE2;
711 if (input != dev->oss.input)
712 mixer_recsrc(dev,input);
713 /* fall throuth */
714 case MIXER_READ(SOUND_MIXER_RECSRC):
715 switch (dev->oss.input) {
716 case TV: ret = SOUND_MASK_VIDEO; break;
717 case LINE1: ret = SOUND_MASK_LINE1; break;
718 case LINE2: ret = SOUND_MASK_LINE2; break;
719 default: ret = 0;
720 }
721 return put_user(ret, p);
722
723 case MIXER_WRITE(SOUND_MIXER_VIDEO):
724 case MIXER_READ(SOUND_MIXER_VIDEO):
725 if (32000 != dev->oss.rate)
726 return -EINVAL;
727 return put_user(100 | 100 << 8, p);
728
729 case MIXER_WRITE(SOUND_MIXER_LINE1):
730 if (get_user(val, p))
731 return -EFAULT;
732 val &= 0xff;
733 val = (val <= 50) ? 50 : 100;
734 dev->oss.line1 = val;
735 mixer_level(dev,LINE1,dev->oss.line1);
736 /* fall throuth */
737 case MIXER_READ(SOUND_MIXER_LINE1):
738 return put_user(dev->oss.line1 | dev->oss.line1 << 8, p);
739
740 case MIXER_WRITE(SOUND_MIXER_LINE2):
741 if (get_user(val, p))
742 return -EFAULT;
743 val &= 0xff;
744 val = (val <= 50) ? 50 : 100;
745 dev->oss.line2 = val;
746 mixer_level(dev,LINE2,dev->oss.line2);
747 /* fall throuth */
748 case MIXER_READ(SOUND_MIXER_LINE2):
749 return put_user(dev->oss.line2 | dev->oss.line2 << 8, p);
750
751 default:
752 return -EINVAL;
753 }
754}
755
756struct file_operations saa7134_mixer_fops = {
757 .owner = THIS_MODULE,
758 .open = mixer_open,
759 .release = mixer_release,
760 .ioctl = mixer_ioctl,
761 .llseek = no_llseek,
762};
763
764/* ------------------------------------------------------------------ */
765
766int saa7134_oss_init1(struct saa7134_dev *dev)
767{
768 /* general */
769 init_MUTEX(&dev->oss.lock);
770 init_waitqueue_head(&dev->oss.wq);
771
772 switch (dev->pci->device) {
773 case PCI_DEVICE_ID_PHILIPS_SAA7133:
774 case PCI_DEVICE_ID_PHILIPS_SAA7135:
775 saa_writel(0x588 >> 2, 0x00000fff);
776 saa_writel(0x58c >> 2, 0x00543210);
777 saa_dsp_writel(dev, 0x46c >> 2, 0xbbbbbb);
778 break;
779 }
780
781 /* dsp */
782 dev->oss.rate = 32000;
783 if (oss_rate)
784 dev->oss.rate = oss_rate;
785 dev->oss.rate = (dev->oss.rate > 40000) ? 48000 : 32000;
786
787 /* mixer */
788 dev->oss.line1 = 50;
789 dev->oss.line2 = 50;
790 mixer_level(dev,LINE1,dev->oss.line1);
791 mixer_level(dev,LINE2,dev->oss.line2);
792 mixer_recsrc(dev, (dev->oss.rate == 32000) ? TV : LINE2);
793
794 return 0;
795}
796
797int saa7134_oss_fini(struct saa7134_dev *dev)
798{
799 /* nothing */
800 return 0;
801}
802
803void saa7134_irq_oss_done(struct saa7134_dev *dev, unsigned long status)
804{
805 int next_blk, reg = 0;
806
807 spin_lock(&dev->slock);
808 if (UNSET == dev->oss.dma_blk) {
809 dprintk("irq: recording stopped\n");
810 goto done;
811 }
812 if (0 != (status & 0x0f000000))
813 dprintk("irq: lost %ld\n", (status >> 24) & 0x0f);
814 if (0 == (status & 0x10000000)) {
815 /* odd */
816 if (0 == (dev->oss.dma_blk & 0x01))
817 reg = SAA7134_RS_BA1(6);
818 } else {
819 /* even */
820 if (0 == (dev->oss.dma_blk & 0x00))
821 reg = SAA7134_RS_BA2(6);
822 }
823 if (0 == reg) {
824 dprintk("irq: field oops [%s]\n",
825 (status & 0x10000000) ? "even" : "odd");
826 goto done;
827 }
828 if (dev->oss.read_count >= dev->oss.blksize * (dev->oss.blocks-2)) {
829 dprintk("irq: overrun [full=%d/%d]\n",dev->oss.read_count,
830 dev->oss.bufsize);
831 dsp_dma_stop(dev);
832 goto done;
833 }
834
835 /* next block addr */
836 next_blk = (dev->oss.dma_blk + 2) % dev->oss.blocks;
837 saa_writel(reg,next_blk * dev->oss.blksize);
838 if (oss_debug > 2)
839 dprintk("irq: ok, %s, next_blk=%d, addr=%x\n",
840 (status & 0x10000000) ? "even" : "odd ", next_blk,
841 next_blk * dev->oss.blksize);
842
843 /* update status & wake waiting readers */
844 dev->oss.dma_blk = (dev->oss.dma_blk + 1) % dev->oss.blocks;
845 dev->oss.read_count += dev->oss.blksize;
846 wake_up(&dev->oss.wq);
847
848 done:
849 spin_unlock(&dev->slock);
850}
851
852/* ----------------------------------------------------------- */
853/*
854 * Local variables:
855 * c-basic-offset: 8
856 * End:
857 */
diff --git a/drivers/media/video/saa7134/saa7134-reg.h b/drivers/media/video/saa7134/saa7134-reg.h
new file mode 100644
index 00000000000..87734f22af7
--- /dev/null
+++ b/drivers/media/video/saa7134/saa7134-reg.h
@@ -0,0 +1,366 @@
1/*
2 * $Id: saa7134-reg.h,v 1.2 2004/09/15 16:15:24 kraxel Exp $
3 *
4 * philips saa7134 registers
5 */
6
7/* ------------------------------------------------------------------ */
8/*
9 * PCI ID's
10 */
11#ifndef PCI_DEVICE_ID_PHILIPS_SAA7130
12# define PCI_DEVICE_ID_PHILIPS_SAA7130 0x7130
13#endif
14#ifndef PCI_DEVICE_ID_PHILIPS_SAA7133
15# define PCI_DEVICE_ID_PHILIPS_SAA7133 0x7133
16#endif
17#ifndef PCI_DEVICE_ID_PHILIPS_SAA7134
18# define PCI_DEVICE_ID_PHILIPS_SAA7134 0x7134
19#endif
20#ifndef PCI_DEVICE_ID_PHILIPS_SAA7135
21# define PCI_DEVICE_ID_PHILIPS_SAA7135 0x7135
22#endif
23
24/* ------------------------------------------------------------------ */
25/*
26 * registers -- 32 bit
27 */
28
29/* DMA channels, n = 0 ... 6 */
30#define SAA7134_RS_BA1(n) ((0x200 >> 2) + 4*n)
31#define SAA7134_RS_BA2(n) ((0x204 >> 2) + 4*n)
32#define SAA7134_RS_PITCH(n) ((0x208 >> 2) + 4*n)
33#define SAA7134_RS_CONTROL(n) ((0x20c >> 2) + 4*n)
34#define SAA7134_RS_CONTROL_WSWAP (0x01 << 25)
35#define SAA7134_RS_CONTROL_BSWAP (0x01 << 24)
36#define SAA7134_RS_CONTROL_BURST_2 (0x01 << 21)
37#define SAA7134_RS_CONTROL_BURST_4 (0x02 << 21)
38#define SAA7134_RS_CONTROL_BURST_8 (0x03 << 21)
39#define SAA7134_RS_CONTROL_BURST_16 (0x04 << 21)
40#define SAA7134_RS_CONTROL_BURST_32 (0x05 << 21)
41#define SAA7134_RS_CONTROL_BURST_64 (0x06 << 21)
42#define SAA7134_RS_CONTROL_BURST_MAX (0x07 << 21)
43#define SAA7134_RS_CONTROL_ME (0x01 << 20)
44#define SAA7134_FIFO_SIZE (0x2a0 >> 2)
45#define SAA7134_THRESHOULD (0x2a4 >> 2)
46
47/* main control */
48#define SAA7134_MAIN_CTRL (0x2a8 >> 2)
49#define SAA7134_MAIN_CTRL_VPLLE (1 << 15)
50#define SAA7134_MAIN_CTRL_APLLE (1 << 14)
51#define SAA7134_MAIN_CTRL_EXOSC (1 << 13)
52#define SAA7134_MAIN_CTRL_EVFE1 (1 << 12)
53#define SAA7134_MAIN_CTRL_EVFE2 (1 << 11)
54#define SAA7134_MAIN_CTRL_ESFE (1 << 10)
55#define SAA7134_MAIN_CTRL_EBADC (1 << 9)
56#define SAA7134_MAIN_CTRL_EBDAC (1 << 8)
57#define SAA7134_MAIN_CTRL_TE6 (1 << 6)
58#define SAA7134_MAIN_CTRL_TE5 (1 << 5)
59#define SAA7134_MAIN_CTRL_TE4 (1 << 4)
60#define SAA7134_MAIN_CTRL_TE3 (1 << 3)
61#define SAA7134_MAIN_CTRL_TE2 (1 << 2)
62#define SAA7134_MAIN_CTRL_TE1 (1 << 1)
63#define SAA7134_MAIN_CTRL_TE0 (1 << 0)
64
65/* DMA status */
66#define SAA7134_DMA_STATUS (0x2ac >> 2)
67
68/* audio / video status */
69#define SAA7134_AV_STATUS (0x2c0 >> 2)
70#define SAA7134_AV_STATUS_STEREO (1 << 17)
71#define SAA7134_AV_STATUS_DUAL (1 << 16)
72#define SAA7134_AV_STATUS_PILOT (1 << 15)
73#define SAA7134_AV_STATUS_SMB (1 << 14)
74#define SAA7134_AV_STATUS_DMB (1 << 13)
75#define SAA7134_AV_STATUS_VDSP (1 << 12)
76#define SAA7134_AV_STATUS_IIC_STATUS (3 << 10)
77#define SAA7134_AV_STATUS_MVM (7 << 7)
78#define SAA7134_AV_STATUS_FIDT (1 << 6)
79#define SAA7134_AV_STATUS_INTL (1 << 5)
80#define SAA7134_AV_STATUS_RDCAP (1 << 4)
81#define SAA7134_AV_STATUS_PWR_ON (1 << 3)
82#define SAA7134_AV_STATUS_LOAD_ERR (1 << 2)
83#define SAA7134_AV_STATUS_TRIG_ERR (1 << 1)
84#define SAA7134_AV_STATUS_CONF_ERR (1 << 0)
85
86/* interrupt */
87#define SAA7134_IRQ1 (0x2c4 >> 2)
88#define SAA7134_IRQ1_INTE_RA3_1 (1 << 25)
89#define SAA7134_IRQ1_INTE_RA3_0 (1 << 24)
90#define SAA7134_IRQ1_INTE_RA2_3 (1 << 19)
91#define SAA7134_IRQ1_INTE_RA2_2 (1 << 18)
92#define SAA7134_IRQ1_INTE_RA2_1 (1 << 17)
93#define SAA7134_IRQ1_INTE_RA2_0 (1 << 16)
94#define SAA7134_IRQ1_INTE_RA1_3 (1 << 11)
95#define SAA7134_IRQ1_INTE_RA1_2 (1 << 10)
96#define SAA7134_IRQ1_INTE_RA1_1 (1 << 9)
97#define SAA7134_IRQ1_INTE_RA1_0 (1 << 8)
98#define SAA7134_IRQ1_INTE_RA0_7 (1 << 7)
99#define SAA7134_IRQ1_INTE_RA0_6 (1 << 6)
100#define SAA7134_IRQ1_INTE_RA0_5 (1 << 5)
101#define SAA7134_IRQ1_INTE_RA0_4 (1 << 4)
102#define SAA7134_IRQ1_INTE_RA0_3 (1 << 3)
103#define SAA7134_IRQ1_INTE_RA0_2 (1 << 2)
104#define SAA7134_IRQ1_INTE_RA0_1 (1 << 1)
105#define SAA7134_IRQ1_INTE_RA0_0 (1 << 0)
106
107#define SAA7134_IRQ2 (0x2c8 >> 2)
108#define SAA7134_IRQ2_INTE_GPIO23A (1 << 17)
109#define SAA7134_IRQ2_INTE_GPIO23 (1 << 16)
110#define SAA7134_IRQ2_INTE_GPIO22A (1 << 15)
111#define SAA7134_IRQ2_INTE_GPIO22 (1 << 14)
112#define SAA7134_IRQ2_INTE_GPIO18A (1 << 13)
113#define SAA7134_IRQ2_INTE_GPIO18 (1 << 12)
114#define SAA7134_IRQ2_INTE_GPIO16 (1 << 11) /* not certain */
115#define SAA7134_IRQ2_INTE_SC2 (1 << 10)
116#define SAA7134_IRQ2_INTE_SC1 (1 << 9)
117#define SAA7134_IRQ2_INTE_SC0 (1 << 8)
118#define SAA7134_IRQ2_INTE_DEC5 (1 << 7)
119#define SAA7134_IRQ2_INTE_DEC4 (1 << 6)
120#define SAA7134_IRQ2_INTE_DEC3 (1 << 5)
121#define SAA7134_IRQ2_INTE_DEC2 (1 << 4)
122#define SAA7134_IRQ2_INTE_DEC1 (1 << 3)
123#define SAA7134_IRQ2_INTE_DEC0 (1 << 2)
124#define SAA7134_IRQ2_INTE_PE (1 << 1)
125#define SAA7134_IRQ2_INTE_AR (1 << 0)
126
127#define SAA7134_IRQ_REPORT (0x2cc >> 2)
128#define SAA7134_IRQ_REPORT_GPIO23 (1 << 17)
129#define SAA7134_IRQ_REPORT_GPIO22 (1 << 16)
130#define SAA7134_IRQ_REPORT_GPIO18 (1 << 15)
131#define SAA7134_IRQ_REPORT_GPIO16 (1 << 14) /* not certain */
132#define SAA7134_IRQ_REPORT_LOAD_ERR (1 << 13)
133#define SAA7134_IRQ_REPORT_CONF_ERR (1 << 12)
134#define SAA7134_IRQ_REPORT_TRIG_ERR (1 << 11)
135#define SAA7134_IRQ_REPORT_MMC (1 << 10)
136#define SAA7134_IRQ_REPORT_FIDT (1 << 9)
137#define SAA7134_IRQ_REPORT_INTL (1 << 8)
138#define SAA7134_IRQ_REPORT_RDCAP (1 << 7)
139#define SAA7134_IRQ_REPORT_PWR_ON (1 << 6)
140#define SAA7134_IRQ_REPORT_PE (1 << 5)
141#define SAA7134_IRQ_REPORT_AR (1 << 4)
142#define SAA7134_IRQ_REPORT_DONE_RA3 (1 << 3)
143#define SAA7134_IRQ_REPORT_DONE_RA2 (1 << 2)
144#define SAA7134_IRQ_REPORT_DONE_RA1 (1 << 1)
145#define SAA7134_IRQ_REPORT_DONE_RA0 (1 << 0)
146#define SAA7134_IRQ_STATUS (0x2d0 >> 2)
147
148
149/* ------------------------------------------------------------------ */
150/*
151 * registers -- 8 bit
152 */
153
154/* video decoder */
155#define SAA7134_INCR_DELAY 0x101
156#define SAA7134_ANALOG_IN_CTRL1 0x102
157#define SAA7134_ANALOG_IN_CTRL2 0x103
158#define SAA7134_ANALOG_IN_CTRL3 0x104
159#define SAA7134_ANALOG_IN_CTRL4 0x105
160#define SAA7134_HSYNC_START 0x106
161#define SAA7134_HSYNC_STOP 0x107
162#define SAA7134_SYNC_CTRL 0x108
163#define SAA7134_LUMA_CTRL 0x109
164#define SAA7134_DEC_LUMA_BRIGHT 0x10a
165#define SAA7134_DEC_LUMA_CONTRAST 0x10b
166#define SAA7134_DEC_CHROMA_SATURATION 0x10c
167#define SAA7134_DEC_CHROMA_HUE 0x10d
168#define SAA7134_CHROMA_CTRL1 0x10e
169#define SAA7134_CHROMA_GAIN 0x10f
170#define SAA7134_CHROMA_CTRL2 0x110
171#define SAA7134_MODE_DELAY_CTRL 0x111
172
173#define SAA7134_ANALOG_ADC 0x114
174#define SAA7134_VGATE_START 0x115
175#define SAA7134_VGATE_STOP 0x116
176#define SAA7134_MISC_VGATE_MSB 0x117
177#define SAA7134_RAW_DATA_GAIN 0x118
178#define SAA7134_RAW_DATA_OFFSET 0x119
179#define SAA7134_STATUS_VIDEO1 0x11e
180#define SAA7134_STATUS_VIDEO2 0x11f
181
182/* video scaler */
183#define SAA7134_SOURCE_TIMING1 0x000
184#define SAA7134_SOURCE_TIMING2 0x001
185#define SAA7134_REGION_ENABLE 0x004
186#define SAA7134_SCALER_STATUS0 0x006
187#define SAA7134_SCALER_STATUS1 0x007
188#define SAA7134_START_GREEN 0x00c
189#define SAA7134_START_BLUE 0x00d
190#define SAA7134_START_RED 0x00e
191#define SAA7134_GREEN_PATH(x) (0x010 +x)
192#define SAA7134_BLUE_PATH(x) (0x020 +x)
193#define SAA7134_RED_PATH(x) (0x030 +x)
194
195#define TASK_A 0x040
196#define TASK_B 0x080
197#define SAA7134_TASK_CONDITIONS(t) (0x000 +t)
198#define SAA7134_FIELD_HANDLING(t) (0x001 +t)
199#define SAA7134_DATA_PATH(t) (0x002 +t)
200#define SAA7134_VBI_H_START1(t) (0x004 +t)
201#define SAA7134_VBI_H_START2(t) (0x005 +t)
202#define SAA7134_VBI_H_STOP1(t) (0x006 +t)
203#define SAA7134_VBI_H_STOP2(t) (0x007 +t)
204#define SAA7134_VBI_V_START1(t) (0x008 +t)
205#define SAA7134_VBI_V_START2(t) (0x009 +t)
206#define SAA7134_VBI_V_STOP1(t) (0x00a +t)
207#define SAA7134_VBI_V_STOP2(t) (0x00b +t)
208#define SAA7134_VBI_H_LEN1(t) (0x00c +t)
209#define SAA7134_VBI_H_LEN2(t) (0x00d +t)
210#define SAA7134_VBI_V_LEN1(t) (0x00e +t)
211#define SAA7134_VBI_V_LEN2(t) (0x00f +t)
212
213#define SAA7134_VIDEO_H_START1(t) (0x014 +t)
214#define SAA7134_VIDEO_H_START2(t) (0x015 +t)
215#define SAA7134_VIDEO_H_STOP1(t) (0x016 +t)
216#define SAA7134_VIDEO_H_STOP2(t) (0x017 +t)
217#define SAA7134_VIDEO_V_START1(t) (0x018 +t)
218#define SAA7134_VIDEO_V_START2(t) (0x019 +t)
219#define SAA7134_VIDEO_V_STOP1(t) (0x01a +t)
220#define SAA7134_VIDEO_V_STOP2(t) (0x01b +t)
221#define SAA7134_VIDEO_PIXELS1(t) (0x01c +t)
222#define SAA7134_VIDEO_PIXELS2(t) (0x01d +t)
223#define SAA7134_VIDEO_LINES1(t) (0x01e +t)
224#define SAA7134_VIDEO_LINES2(t) (0x01f +t)
225
226#define SAA7134_H_PRESCALE(t) (0x020 +t)
227#define SAA7134_ACC_LENGTH(t) (0x021 +t)
228#define SAA7134_LEVEL_CTRL(t) (0x022 +t)
229#define SAA7134_FIR_PREFILTER_CTRL(t) (0x023 +t)
230#define SAA7134_LUMA_BRIGHT(t) (0x024 +t)
231#define SAA7134_LUMA_CONTRAST(t) (0x025 +t)
232#define SAA7134_CHROMA_SATURATION(t) (0x026 +t)
233#define SAA7134_VBI_H_SCALE_INC1(t) (0x028 +t)
234#define SAA7134_VBI_H_SCALE_INC2(t) (0x029 +t)
235#define SAA7134_VBI_PHASE_OFFSET_LUMA(t) (0x02a +t)
236#define SAA7134_VBI_PHASE_OFFSET_CHROMA(t) (0x02b +t)
237#define SAA7134_H_SCALE_INC1(t) (0x02c +t)
238#define SAA7134_H_SCALE_INC2(t) (0x02d +t)
239#define SAA7134_H_PHASE_OFF_LUMA(t) (0x02e +t)
240#define SAA7134_H_PHASE_OFF_CHROMA(t) (0x02f +t)
241#define SAA7134_V_SCALE_RATIO1(t) (0x030 +t)
242#define SAA7134_V_SCALE_RATIO2(t) (0x031 +t)
243#define SAA7134_V_FILTER(t) (0x032 +t)
244#define SAA7134_V_PHASE_OFFSET0(t) (0x034 +t)
245#define SAA7134_V_PHASE_OFFSET1(t) (0x035 +t)
246#define SAA7134_V_PHASE_OFFSET2(t) (0x036 +t)
247#define SAA7134_V_PHASE_OFFSET3(t) (0x037 +t)
248
249/* clipping & dma */
250#define SAA7134_OFMT_VIDEO_A 0x300
251#define SAA7134_OFMT_DATA_A 0x301
252#define SAA7134_OFMT_VIDEO_B 0x302
253#define SAA7134_OFMT_DATA_B 0x303
254#define SAA7134_ALPHA_NOCLIP 0x304
255#define SAA7134_ALPHA_CLIP 0x305
256#define SAA7134_UV_PIXEL 0x308
257#define SAA7134_CLIP_RED 0x309
258#define SAA7134_CLIP_GREEN 0x30a
259#define SAA7134_CLIP_BLUE 0x30b
260
261/* i2c bus */
262#define SAA7134_I2C_ATTR_STATUS 0x180
263#define SAA7134_I2C_DATA 0x181
264#define SAA7134_I2C_CLOCK_SELECT 0x182
265#define SAA7134_I2C_TIMER 0x183
266
267/* audio */
268#define SAA7134_NICAM_ADD_DATA1 0x140
269#define SAA7134_NICAM_ADD_DATA2 0x141
270#define SAA7134_NICAM_STATUS 0x142
271#define SAA7134_AUDIO_STATUS 0x143
272#define SAA7134_NICAM_ERROR_COUNT 0x144
273#define SAA7134_IDENT_SIF 0x145
274#define SAA7134_LEVEL_READOUT1 0x146
275#define SAA7134_LEVEL_READOUT2 0x147
276#define SAA7134_NICAM_ERROR_LOW 0x148
277#define SAA7134_NICAM_ERROR_HIGH 0x149
278#define SAA7134_DCXO_IDENT_CTRL 0x14a
279#define SAA7134_DEMODULATOR 0x14b
280#define SAA7134_AGC_GAIN_SELECT 0x14c
281#define SAA7134_CARRIER1_FREQ0 0x150
282#define SAA7134_CARRIER1_FREQ1 0x151
283#define SAA7134_CARRIER1_FREQ2 0x152
284#define SAA7134_CARRIER2_FREQ0 0x154
285#define SAA7134_CARRIER2_FREQ1 0x155
286#define SAA7134_CARRIER2_FREQ2 0x156
287#define SAA7134_NUM_SAMPLES0 0x158
288#define SAA7134_NUM_SAMPLES1 0x159
289#define SAA7134_NUM_SAMPLES2 0x15a
290#define SAA7134_AUDIO_FORMAT_CTRL 0x15b
291#define SAA7134_MONITOR_SELECT 0x160
292#define SAA7134_FM_DEEMPHASIS 0x161
293#define SAA7134_FM_DEMATRIX 0x162
294#define SAA7134_CHANNEL1_LEVEL 0x163
295#define SAA7134_CHANNEL2_LEVEL 0x164
296#define SAA7134_NICAM_CONFIG 0x165
297#define SAA7134_NICAM_LEVEL_ADJUST 0x166
298#define SAA7134_STEREO_DAC_OUTPUT_SELECT 0x167
299#define SAA7134_I2S_OUTPUT_FORMAT 0x168
300#define SAA7134_I2S_OUTPUT_SELECT 0x169
301#define SAA7134_I2S_OUTPUT_LEVEL 0x16a
302#define SAA7134_DSP_OUTPUT_SELECT 0x16b
303#define SAA7134_AUDIO_MUTE_CTRL 0x16c
304#define SAA7134_SIF_SAMPLE_FREQ 0x16d
305#define SAA7134_ANALOG_IO_SELECT 0x16e
306#define SAA7134_AUDIO_CLOCK0 0x170
307#define SAA7134_AUDIO_CLOCK1 0x171
308#define SAA7134_AUDIO_CLOCK2 0x172
309#define SAA7134_AUDIO_PLL_CTRL 0x173
310#define SAA7134_AUDIO_CLOCKS_PER_FIELD0 0x174
311#define SAA7134_AUDIO_CLOCKS_PER_FIELD1 0x175
312#define SAA7134_AUDIO_CLOCKS_PER_FIELD2 0x176
313
314/* video port output */
315#define SAA7134_VIDEO_PORT_CTRL0 0x190
316#define SAA7134_VIDEO_PORT_CTRL1 0x191
317#define SAA7134_VIDEO_PORT_CTRL2 0x192
318#define SAA7134_VIDEO_PORT_CTRL3 0x193
319#define SAA7134_VIDEO_PORT_CTRL4 0x194
320#define SAA7134_VIDEO_PORT_CTRL5 0x195
321#define SAA7134_VIDEO_PORT_CTRL6 0x196
322#define SAA7134_VIDEO_PORT_CTRL7 0x197
323#define SAA7134_VIDEO_PORT_CTRL8 0x198
324
325/* transport stream interface */
326#define SAA7134_TS_PARALLEL 0x1a0
327#define SAA7134_TS_PARALLEL_SERIAL 0x1a1
328#define SAA7134_TS_SERIAL0 0x1a2
329#define SAA7134_TS_SERIAL1 0x1a3
330#define SAA7134_TS_DMA0 0x1a4
331#define SAA7134_TS_DMA1 0x1a5
332#define SAA7134_TS_DMA2 0x1a6
333
334/* GPIO Controls */
335#define SAA7134_GPIO_GPRESCAN 0x80
336#define SAA7134_GPIO_27_25 0x0E
337
338#define SAA7134_GPIO_GPMODE0 0x1B0
339#define SAA7134_GPIO_GPMODE1 0x1B1
340#define SAA7134_GPIO_GPMODE2 0x1B2
341#define SAA7134_GPIO_GPMODE3 0x1B3
342#define SAA7134_GPIO_GPSTATUS0 0x1B4
343#define SAA7134_GPIO_GPSTATUS1 0x1B5
344#define SAA7134_GPIO_GPSTATUS2 0x1B6
345#define SAA7134_GPIO_GPSTATUS3 0x1B7
346
347/* I2S output */
348#define SAA7134_I2S_AUDIO_OUTPUT 0x1c0
349
350/* test modes */
351#define SAA7134_SPECIAL_MODE 0x1d0
352
353/* audio -- saa7133 + saa7135 only */
354#define SAA7135_DSP_RWSTATE 0x580
355#define SAA7135_DSP_RWSTATE_ERR (1 << 3)
356#define SAA7135_DSP_RWSTATE_IDA (1 << 2)
357#define SAA7135_DSP_RWSTATE_RDB (1 << 1)
358#define SAA7135_DSP_RWSTATE_WRR (1 << 0)
359
360/* ------------------------------------------------------------------ */
361/*
362 * Local variables:
363 * c-basic-offset: 8
364 * End:
365 */
366
diff --git a/drivers/media/video/saa7134/saa7134-ts.c b/drivers/media/video/saa7134/saa7134-ts.c
new file mode 100644
index 00000000000..345eb2a8c28
--- /dev/null
+++ b/drivers/media/video/saa7134/saa7134-ts.c
@@ -0,0 +1,243 @@
1/*
2 * $Id: saa7134-ts.c,v 1.14 2005/02/03 10:24:33 kraxel Exp $
3 *
4 * device driver for philips saa7134 based TV cards
5 * video4linux video interface
6 *
7 * (c) 2001,02 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
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#include <linux/init.h>
25#include <linux/list.h>
26#include <linux/module.h>
27#include <linux/moduleparam.h>
28#include <linux/kernel.h>
29#include <linux/slab.h>
30#include <linux/delay.h>
31
32#include "saa7134-reg.h"
33#include "saa7134.h"
34
35/* ------------------------------------------------------------------ */
36
37static unsigned int ts_debug = 0;
38module_param(ts_debug, int, 0644);
39MODULE_PARM_DESC(ts_debug,"enable debug messages [ts]");
40
41#define dprintk(fmt, arg...) if (ts_debug) \
42 printk(KERN_DEBUG "%s/ts: " fmt, dev->name , ## arg)
43
44/* ------------------------------------------------------------------ */
45
46static int buffer_activate(struct saa7134_dev *dev,
47 struct saa7134_buf *buf,
48 struct saa7134_buf *next)
49{
50 u32 control;
51
52 dprintk("buffer_activate [%p]",buf);
53 buf->vb.state = STATE_ACTIVE;
54 buf->top_seen = 0;
55
56 /* dma: setup channel 5 (= TS) */
57 control = SAA7134_RS_CONTROL_BURST_16 |
58 SAA7134_RS_CONTROL_ME |
59 (buf->pt->dma >> 12);
60
61 if (NULL == next)
62 next = buf;
63 if (V4L2_FIELD_TOP == buf->vb.field) {
64 dprintk("- [top] buf=%p next=%p\n",buf,next);
65 saa_writel(SAA7134_RS_BA1(5),saa7134_buffer_base(buf));
66 saa_writel(SAA7134_RS_BA2(5),saa7134_buffer_base(next));
67 } else {
68 dprintk("- [bottom] buf=%p next=%p\n",buf,next);
69 saa_writel(SAA7134_RS_BA1(5),saa7134_buffer_base(next));
70 saa_writel(SAA7134_RS_BA2(5),saa7134_buffer_base(buf));
71 }
72 saa_writel(SAA7134_RS_PITCH(5),TS_PACKET_SIZE);
73 saa_writel(SAA7134_RS_CONTROL(5),control);
74
75 /* start DMA */
76 saa7134_set_dmabits(dev);
77
78 mod_timer(&dev->ts_q.timeout, jiffies+BUFFER_TIMEOUT);
79 return 0;
80}
81
82static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
83 enum v4l2_field field)
84{
85 struct saa7134_dev *dev = q->priv_data;
86 struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb);
87 unsigned int lines, llength, size;
88 int err;
89
90 dprintk("buffer_prepare [%p,%s]\n",buf,v4l2_field_names[field]);
91
92 llength = TS_PACKET_SIZE;
93 lines = dev->ts.nr_packets;
94
95 size = lines * llength;
96 if (0 != buf->vb.baddr && buf->vb.bsize < size)
97 return -EINVAL;
98
99 if (buf->vb.size != size) {
100 saa7134_dma_free(dev,buf);
101 }
102
103 if (STATE_NEEDS_INIT == buf->vb.state) {
104 buf->vb.width = llength;
105 buf->vb.height = lines;
106 buf->vb.size = size;
107 buf->pt = &dev->ts.pt_ts;
108
109 err = videobuf_iolock(dev->pci,&buf->vb,NULL);
110 if (err)
111 goto oops;
112 err = saa7134_pgtable_build(dev->pci,buf->pt,
113 buf->vb.dma.sglist,
114 buf->vb.dma.sglen,
115 saa7134_buffer_startpage(buf));
116 if (err)
117 goto oops;
118 }
119 buf->vb.state = STATE_PREPARED;
120 buf->activate = buffer_activate;
121 buf->vb.field = field;
122 return 0;
123
124 oops:
125 saa7134_dma_free(dev,buf);
126 return err;
127}
128
129static int
130buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
131{
132 struct saa7134_dev *dev = q->priv_data;
133
134 *size = TS_PACKET_SIZE * dev->ts.nr_packets;
135 if (0 == *count)
136 *count = dev->ts.nr_bufs;
137 *count = saa7134_buffer_count(*size,*count);
138 return 0;
139}
140
141static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
142{
143 struct saa7134_dev *dev = q->priv_data;
144 struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb);
145
146 saa7134_buffer_queue(dev,&dev->ts_q,buf);
147}
148
149static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
150{
151 struct saa7134_dev *dev = q->priv_data;
152 struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb);
153
154 saa7134_dma_free(dev,buf);
155}
156
157struct videobuf_queue_ops saa7134_ts_qops = {
158 .buf_setup = buffer_setup,
159 .buf_prepare = buffer_prepare,
160 .buf_queue = buffer_queue,
161 .buf_release = buffer_release,
162};
163EXPORT_SYMBOL_GPL(saa7134_ts_qops);
164
165/* ----------------------------------------------------------- */
166/* exported stuff */
167
168static unsigned int tsbufs = 4;
169module_param(tsbufs, int, 0444);
170MODULE_PARM_DESC(tsbufs,"number of ts buffers, range 2-32");
171
172static unsigned int ts_nr_packets = 30;
173module_param(ts_nr_packets, int, 0444);
174MODULE_PARM_DESC(ts_nr_packets,"size of a ts buffers (in ts packets)");
175
176int saa7134_ts_init1(struct saa7134_dev *dev)
177{
178 /* sanitycheck insmod options */
179 if (tsbufs < 2)
180 tsbufs = 2;
181 if (tsbufs > VIDEO_MAX_FRAME)
182 tsbufs = VIDEO_MAX_FRAME;
183 if (ts_nr_packets < 4)
184 ts_nr_packets = 4;
185 if (ts_nr_packets > 312)
186 ts_nr_packets = 312;
187 dev->ts.nr_bufs = tsbufs;
188 dev->ts.nr_packets = ts_nr_packets;
189
190 INIT_LIST_HEAD(&dev->ts_q.queue);
191 init_timer(&dev->ts_q.timeout);
192 dev->ts_q.timeout.function = saa7134_buffer_timeout;
193 dev->ts_q.timeout.data = (unsigned long)(&dev->ts_q);
194 dev->ts_q.dev = dev;
195 dev->ts_q.need_two = 1;
196 saa7134_pgtable_alloc(dev->pci,&dev->ts.pt_ts);
197
198 /* init TS hw */
199 saa_writeb(SAA7134_TS_SERIAL1, 0x00); /* deactivate TS softreset */
200 saa_writeb(SAA7134_TS_PARALLEL, 0xec); /* TSSOP high active, TSVAL high active, TSLOCK ignored */
201 saa_writeb(SAA7134_TS_PARALLEL_SERIAL, (TS_PACKET_SIZE-1));
202 saa_writeb(SAA7134_TS_DMA0, ((dev->ts.nr_packets-1)&0xff));
203 saa_writeb(SAA7134_TS_DMA1, (((dev->ts.nr_packets-1)>>8)&0xff));
204 saa_writeb(SAA7134_TS_DMA2, ((((dev->ts.nr_packets-1)>>16)&0x3f) | 0x00)); /* TSNOPIT=0, TSCOLAP=0 */
205
206 return 0;
207}
208
209int saa7134_ts_fini(struct saa7134_dev *dev)
210{
211 saa7134_pgtable_free(dev->pci,&dev->ts.pt_ts);
212 return 0;
213}
214
215
216void saa7134_irq_ts_done(struct saa7134_dev *dev, unsigned long status)
217{
218 enum v4l2_field field;
219
220 spin_lock(&dev->slock);
221 if (dev->ts_q.curr) {
222 field = dev->ts_q.curr->vb.field;
223 if (field == V4L2_FIELD_TOP) {
224 if ((status & 0x100000) != 0x000000)
225 goto done;
226 } else {
227 if ((status & 0x100000) != 0x100000)
228 goto done;
229 }
230 saa7134_buffer_finish(dev,&dev->ts_q,STATE_DONE);
231 }
232 saa7134_buffer_next(dev,&dev->ts_q);
233
234 done:
235 spin_unlock(&dev->slock);
236}
237
238/* ----------------------------------------------------------- */
239/*
240 * Local variables:
241 * c-basic-offset: 8
242 * End:
243 */
diff --git a/drivers/media/video/saa7134/saa7134-tvaudio.c b/drivers/media/video/saa7134/saa7134-tvaudio.c
new file mode 100644
index 00000000000..ecac13c006d
--- /dev/null
+++ b/drivers/media/video/saa7134/saa7134-tvaudio.c
@@ -0,0 +1,1031 @@
1/*
2 * $Id: saa7134-tvaudio.c,v 1.22 2005/01/07 13:11:19 kraxel Exp $
3 *
4 * device driver for philips saa7134 based TV cards
5 * tv audio decoder (fm stereo, nicam, ...)
6 *
7 * (c) 2001-03 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
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#include <linux/init.h>
25#include <linux/list.h>
26#include <linux/module.h>
27#include <linux/moduleparam.h>
28#include <linux/kernel.h>
29#include <linux/slab.h>
30#include <linux/delay.h>
31#include <linux/smp_lock.h>
32#include <asm/div64.h>
33
34#include "saa7134-reg.h"
35#include "saa7134.h"
36
37/* ------------------------------------------------------------------ */
38
39static unsigned int audio_debug = 0;
40module_param(audio_debug, int, 0644);
41MODULE_PARM_DESC(audio_debug,"enable debug messages [tv audio]");
42
43static unsigned int audio_ddep = 0;
44module_param(audio_ddep, int, 0644);
45MODULE_PARM_DESC(audio_ddep,"audio ddep overwrite");
46
47static int audio_clock_override = UNSET;
48module_param(audio_clock_override, int, 0644);
49
50static int audio_clock_tweak = 0;
51module_param(audio_clock_tweak, int, 0644);
52MODULE_PARM_DESC(audio_clock_tweak, "Audio clock tick fine tuning for cards with audio crystal that's slightly off (range [-1024 .. 1024])");
53
54#define dprintk(fmt, arg...) if (audio_debug) \
55 printk(KERN_DEBUG "%s/audio: " fmt, dev->name , ## arg)
56#define d2printk(fmt, arg...) if (audio_debug > 1) \
57 printk(KERN_DEBUG "%s/audio: " fmt, dev->name, ## arg)
58
59#define print_regb(reg) printk("%s: reg 0x%03x [%-16s]: 0x%02x\n", \
60 dev->name,(SAA7134_##reg),(#reg),saa_readb((SAA7134_##reg)))
61
62/* msecs */
63#define SCAN_INITIAL_DELAY 1000
64#define SCAN_SAMPLE_DELAY 200
65#define SCAN_SUBCARRIER_DELAY 2000
66
67/* ------------------------------------------------------------------ */
68/* saa7134 code */
69
70static struct mainscan {
71 char *name;
72 v4l2_std_id std;
73 int carr;
74} mainscan[] = {
75 {
76 .name = "M",
77 .std = V4L2_STD_NTSC | V4L2_STD_PAL_M,
78 .carr = 4500,
79 },{
80 .name = "BG",
81 .std = V4L2_STD_PAL_BG,
82 .carr = 5500,
83 },{
84 .name = "I",
85 .std = V4L2_STD_PAL_I,
86 .carr = 6000,
87 },{
88 .name = "DKL",
89 .std = V4L2_STD_PAL_DK | V4L2_STD_SECAM,
90 .carr = 6500,
91 }
92};
93
94static struct saa7134_tvaudio tvaudio[] = {
95 {
96 .name = "PAL-B/G FM-stereo",
97 .std = V4L2_STD_PAL,
98 .mode = TVAUDIO_FM_BG_STEREO,
99 .carr1 = 5500,
100 .carr2 = 5742,
101 },{
102 .name = "PAL-D/K1 FM-stereo",
103 .std = V4L2_STD_PAL,
104 .carr1 = 6500,
105 .carr2 = 6258,
106 .mode = TVAUDIO_FM_BG_STEREO,
107 },{
108 .name = "PAL-D/K2 FM-stereo",
109 .std = V4L2_STD_PAL,
110 .carr1 = 6500,
111 .carr2 = 6742,
112 .mode = TVAUDIO_FM_BG_STEREO,
113 },{
114 .name = "PAL-D/K3 FM-stereo",
115 .std = V4L2_STD_PAL,
116 .carr1 = 6500,
117 .carr2 = 5742,
118 .mode = TVAUDIO_FM_BG_STEREO,
119 },{
120 .name = "PAL-B/G NICAM",
121 .std = V4L2_STD_PAL,
122 .carr1 = 5500,
123 .carr2 = 5850,
124 .mode = TVAUDIO_NICAM_FM,
125 },{
126 .name = "PAL-I NICAM",
127 .std = V4L2_STD_PAL,
128 .carr1 = 6000,
129 .carr2 = 6552,
130 .mode = TVAUDIO_NICAM_FM,
131 },{
132 .name = "PAL-D/K NICAM",
133 .std = V4L2_STD_PAL,
134 .carr1 = 6500,
135 .carr2 = 5850,
136 .mode = TVAUDIO_NICAM_FM,
137 },{
138 .name = "SECAM-L NICAM",
139 .std = V4L2_STD_SECAM,
140 .carr1 = 6500,
141 .carr2 = 5850,
142 .mode = TVAUDIO_NICAM_AM,
143 },{
144 .name = "SECAM-D/K",
145 .std = V4L2_STD_SECAM,
146 .carr1 = 6500,
147 .carr2 = -1,
148 .mode = TVAUDIO_FM_MONO,
149 },{
150 .name = "NTSC-M",
151 .std = V4L2_STD_NTSC,
152 .carr1 = 4500,
153 .carr2 = -1,
154 .mode = TVAUDIO_FM_MONO,
155 },{
156 .name = "NTSC-A2 FM-stereo",
157 .std = V4L2_STD_NTSC,
158 .carr1 = 4500,
159 .carr2 = 4724,
160 .mode = TVAUDIO_FM_K_STEREO,
161 }
162};
163#define TVAUDIO (sizeof(tvaudio)/sizeof(struct saa7134_tvaudio))
164
165/* ------------------------------------------------------------------ */
166
167static void tvaudio_init(struct saa7134_dev *dev)
168{
169 int clock = saa7134_boards[dev->board].audio_clock;
170
171 if (UNSET != audio_clock_override)
172 clock = audio_clock_override;
173
174 /* init all audio registers */
175 saa_writeb(SAA7134_AUDIO_PLL_CTRL, 0x00);
176 if (need_resched())
177 schedule();
178 else
179 udelay(10);
180
181 saa_writeb(SAA7134_AUDIO_CLOCK0, clock & 0xff);
182 saa_writeb(SAA7134_AUDIO_CLOCK1, (clock >> 8) & 0xff);
183 saa_writeb(SAA7134_AUDIO_CLOCK2, (clock >> 16) & 0xff);
184 saa_writeb(SAA7134_AUDIO_PLL_CTRL, 0x01);
185
186 saa_writeb(SAA7134_NICAM_ERROR_LOW, 0x14);
187 saa_writeb(SAA7134_NICAM_ERROR_HIGH, 0x50);
188 saa_writeb(SAA7134_MONITOR_SELECT, 0xa0);
189 saa_writeb(SAA7134_FM_DEMATRIX, 0x80);
190}
191
192static u32 tvaudio_carr2reg(u32 carrier)
193{
194 u64 a = carrier;
195
196 a <<= 24;
197 do_div(a,12288);
198 return a;
199}
200
201static void tvaudio_setcarrier(struct saa7134_dev *dev,
202 int primary, int secondary)
203{
204 if (-1 == secondary)
205 secondary = primary;
206 saa_writel(SAA7134_CARRIER1_FREQ0 >> 2, tvaudio_carr2reg(primary));
207 saa_writel(SAA7134_CARRIER2_FREQ0 >> 2, tvaudio_carr2reg(secondary));
208}
209
210static void mute_input_7134(struct saa7134_dev *dev)
211{
212 unsigned int mute;
213 struct saa7134_input *in;
214 int ausel=0, ics=0, ocs=0;
215 int mask;
216
217 /* look what is to do ... */
218 in = dev->input;
219 mute = (dev->ctl_mute ||
220 (dev->automute && (&card(dev).radio) != in));
221 if (PCI_DEVICE_ID_PHILIPS_SAA7130 == dev->pci->device &&
222 card(dev).mute.name) {
223 /* 7130 - we'll mute using some unconnected audio input */
224 if (mute)
225 in = &card(dev).mute;
226 }
227 if (dev->hw_mute == mute &&
228 dev->hw_input == in) {
229 dprintk("mute/input: nothing to do [mute=%d,input=%s]\n",
230 mute,in->name);
231 return;
232 }
233
234 dprintk("ctl_mute=%d automute=%d input=%s => mute=%d input=%s\n",
235 dev->ctl_mute,dev->automute,dev->input->name,mute,in->name);
236 dev->hw_mute = mute;
237 dev->hw_input = in;
238
239 if (PCI_DEVICE_ID_PHILIPS_SAA7134 == dev->pci->device)
240 /* 7134 mute */
241 saa_writeb(SAA7134_AUDIO_MUTE_CTRL, mute ? 0xbf : 0xbb);
242
243 /* switch internal audio mux */
244 switch (in->amux) {
245 case TV: ausel=0xc0; ics=0x00; ocs=0x02; break;
246 case LINE1: ausel=0x80; ics=0x00; ocs=0x00; break;
247 case LINE2: ausel=0x80; ics=0x08; ocs=0x01; break;
248 case LINE2_LEFT: ausel=0x80; ics=0x08; ocs=0x05; break;
249 }
250 saa_andorb(SAA7134_AUDIO_FORMAT_CTRL, 0xc0, ausel);
251 saa_andorb(SAA7134_ANALOG_IO_SELECT, 0x08, ics);
252 saa_andorb(SAA7134_ANALOG_IO_SELECT, 0x07, ocs);
253
254 /* switch gpio-connected external audio mux */
255 if (0 == card(dev).gpiomask)
256 return;
257 mask = card(dev).gpiomask;
258 saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, mask, mask);
259 saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, mask, in->gpio);
260 saa7134_track_gpio(dev,in->name);
261}
262
263static void tvaudio_setmode(struct saa7134_dev *dev,
264 struct saa7134_tvaudio *audio,
265 char *note)
266{
267 int acpf, tweak = 0;
268
269 if (dev->tvnorm->id == V4L2_STD_NTSC) {
270 acpf = 0x19066;
271 } else {
272 acpf = 0x1e000;
273 }
274 if (audio_clock_tweak > -1024 && audio_clock_tweak < 1024)
275 tweak = audio_clock_tweak;
276
277 if (note)
278 dprintk("tvaudio_setmode: %s %s [%d.%03d/%d.%03d MHz] acpf=%d%+d\n",
279 note,audio->name,
280 audio->carr1 / 1000, audio->carr1 % 1000,
281 audio->carr2 / 1000, audio->carr2 % 1000,
282 acpf, tweak);
283
284 acpf += tweak;
285 saa_writeb(SAA7134_AUDIO_CLOCKS_PER_FIELD0, (acpf & 0x0000ff) >> 0);
286 saa_writeb(SAA7134_AUDIO_CLOCKS_PER_FIELD1, (acpf & 0x00ff00) >> 8);
287 saa_writeb(SAA7134_AUDIO_CLOCKS_PER_FIELD2, (acpf & 0x030000) >> 16);
288 tvaudio_setcarrier(dev,audio->carr1,audio->carr2);
289
290 switch (audio->mode) {
291 case TVAUDIO_FM_MONO:
292 case TVAUDIO_FM_BG_STEREO:
293 saa_writeb(SAA7134_DEMODULATOR, 0x00);
294 saa_writeb(SAA7134_DCXO_IDENT_CTRL, 0x00);
295 saa_writeb(SAA7134_FM_DEEMPHASIS, 0x22);
296 saa_writeb(SAA7134_FM_DEMATRIX, 0x80);
297 saa_writeb(SAA7134_STEREO_DAC_OUTPUT_SELECT, 0xa0);
298 break;
299 case TVAUDIO_FM_K_STEREO:
300 saa_writeb(SAA7134_DEMODULATOR, 0x00);
301 saa_writeb(SAA7134_DCXO_IDENT_CTRL, 0x01);
302 saa_writeb(SAA7134_FM_DEEMPHASIS, 0x22);
303 saa_writeb(SAA7134_FM_DEMATRIX, 0x80);
304 saa_writeb(SAA7134_STEREO_DAC_OUTPUT_SELECT, 0xa0);
305 break;
306 case TVAUDIO_NICAM_FM:
307 saa_writeb(SAA7134_DEMODULATOR, 0x10);
308 saa_writeb(SAA7134_DCXO_IDENT_CTRL, 0x00);
309 saa_writeb(SAA7134_FM_DEEMPHASIS, 0x44);
310 saa_writeb(SAA7134_STEREO_DAC_OUTPUT_SELECT, 0xa1);
311 saa_writeb(SAA7134_NICAM_CONFIG, 0x00);
312 break;
313 case TVAUDIO_NICAM_AM:
314 saa_writeb(SAA7134_DEMODULATOR, 0x12);
315 saa_writeb(SAA7134_DCXO_IDENT_CTRL, 0x00);
316 saa_writeb(SAA7134_FM_DEEMPHASIS, 0x44);
317 saa_writeb(SAA7134_STEREO_DAC_OUTPUT_SELECT, 0xa1);
318 saa_writeb(SAA7134_NICAM_CONFIG, 0x00);
319 break;
320 case TVAUDIO_FM_SAT_STEREO:
321 /* not implemented (yet) */
322 break;
323 }
324}
325
326static int tvaudio_sleep(struct saa7134_dev *dev, int timeout)
327{
328 DECLARE_WAITQUEUE(wait, current);
329
330 add_wait_queue(&dev->thread.wq, &wait);
331 if (dev->thread.scan1 == dev->thread.scan2 && !dev->thread.shutdown) {
332 if (timeout < 0) {
333 set_current_state(TASK_INTERRUPTIBLE);
334 schedule();
335 } else {
336#if 0
337 /* hmm, that one doesn't return on wakeup ... */
338 msleep_interruptible(timeout);
339#else
340 set_current_state(TASK_INTERRUPTIBLE);
341 schedule_timeout(msecs_to_jiffies(timeout));
342#endif
343 }
344 }
345 remove_wait_queue(&dev->thread.wq, &wait);
346 return dev->thread.scan1 != dev->thread.scan2;
347}
348
349static int tvaudio_checkcarrier(struct saa7134_dev *dev, struct mainscan *scan)
350{
351 __s32 left,right,value;
352
353 if (audio_debug > 1) {
354 int i;
355 dprintk("debug %d:",scan->carr);
356 for (i = -150; i <= 150; i += 30) {
357 tvaudio_setcarrier(dev,scan->carr+i,scan->carr+i);
358 saa_readl(SAA7134_LEVEL_READOUT1 >> 2);
359 if (tvaudio_sleep(dev,SCAN_SAMPLE_DELAY))
360 return -1;
361 value = saa_readl(SAA7134_LEVEL_READOUT1 >> 2);
362 if (0 == i)
363 printk(" # %6d # ",value >> 16);
364 else
365 printk(" %6d",value >> 16);
366 }
367 printk("\n");
368 }
369
370 if (dev->tvnorm->id & scan->std) {
371 tvaudio_setcarrier(dev,scan->carr-90,scan->carr-90);
372 saa_readl(SAA7134_LEVEL_READOUT1 >> 2);
373 if (tvaudio_sleep(dev,SCAN_SAMPLE_DELAY))
374 return -1;
375 left = saa_readl(SAA7134_LEVEL_READOUT1 >> 2);
376
377 tvaudio_setcarrier(dev,scan->carr+90,scan->carr+90);
378 saa_readl(SAA7134_LEVEL_READOUT1 >> 2);
379 if (tvaudio_sleep(dev,SCAN_SAMPLE_DELAY))
380 return -1;
381 right = saa_readl(SAA7134_LEVEL_READOUT1 >> 2);
382
383 left >>= 16;
384 right >>= 16;
385 value = left > right ? left - right : right - left;
386 dprintk("scanning %d.%03d MHz [%4s] => dc is %5d [%d/%d]\n",
387 scan->carr / 1000, scan->carr % 1000,
388 scan->name, value, left, right);
389 } else {
390 value = 0;
391 dprintk("skipping %d.%03d MHz [%4s]\n",
392 scan->carr / 1000, scan->carr % 1000, scan->name);
393 }
394 return value;
395}
396
397#if 0
398static void sifdebug_dump_regs(struct saa7134_dev *dev)
399{
400 print_regb(AUDIO_STATUS);
401 print_regb(IDENT_SIF);
402 print_regb(LEVEL_READOUT1);
403 print_regb(LEVEL_READOUT2);
404 print_regb(DCXO_IDENT_CTRL);
405 print_regb(DEMODULATOR);
406 print_regb(AGC_GAIN_SELECT);
407 print_regb(MONITOR_SELECT);
408 print_regb(FM_DEEMPHASIS);
409 print_regb(FM_DEMATRIX);
410 print_regb(SIF_SAMPLE_FREQ);
411 print_regb(ANALOG_IO_SELECT);
412}
413#endif
414
415static int tvaudio_getstereo(struct saa7134_dev *dev, struct saa7134_tvaudio *audio)
416{
417 __u32 idp,nicam;
418 int retval = -1;
419
420 switch (audio->mode) {
421 case TVAUDIO_FM_MONO:
422 return V4L2_TUNER_SUB_MONO;
423 case TVAUDIO_FM_K_STEREO:
424 case TVAUDIO_FM_BG_STEREO:
425 idp = (saa_readb(SAA7134_IDENT_SIF) & 0xe0) >> 5;
426 dprintk("getstereo: fm/stereo: idp=0x%x\n",idp);
427 if (0x03 == (idp & 0x03))
428 retval = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
429 else if (0x05 == (idp & 0x05))
430 retval = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
431 else if (0x01 == (idp & 0x01))
432 retval = V4L2_TUNER_SUB_MONO;
433 break;
434 case TVAUDIO_FM_SAT_STEREO:
435 /* not implemented (yet) */
436 break;
437 case TVAUDIO_NICAM_FM:
438 case TVAUDIO_NICAM_AM:
439 nicam = saa_readb(SAA7134_NICAM_STATUS);
440 dprintk("getstereo: nicam=0x%x\n",nicam);
441 switch (nicam & 0x0b) {
442 case 0x09:
443 retval = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
444 break;
445 case 0x0a:
446 retval = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
447 break;
448 case 0x08:
449 default:
450 retval = V4L2_TUNER_SUB_MONO;
451 break;
452 }
453 break;
454 }
455 if (retval != -1)
456 dprintk("found audio subchannels:%s%s%s%s\n",
457 (retval & V4L2_TUNER_SUB_MONO) ? " mono" : "",
458 (retval & V4L2_TUNER_SUB_STEREO) ? " stereo" : "",
459 (retval & V4L2_TUNER_SUB_LANG1) ? " lang1" : "",
460 (retval & V4L2_TUNER_SUB_LANG2) ? " lang2" : "");
461 return retval;
462}
463
464static int tvaudio_setstereo(struct saa7134_dev *dev, struct saa7134_tvaudio *audio,
465 u32 mode)
466{
467 static char *name[] = {
468 [ V4L2_TUNER_MODE_MONO ] = "mono",
469 [ V4L2_TUNER_MODE_STEREO ] = "stereo",
470 [ V4L2_TUNER_MODE_LANG1 ] = "lang1",
471 [ V4L2_TUNER_MODE_LANG2 ] = "lang2",
472 };
473 static u32 fm[] = {
474 [ V4L2_TUNER_MODE_MONO ] = 0x00, /* ch1 */
475 [ V4L2_TUNER_MODE_STEREO ] = 0x80, /* auto */
476 [ V4L2_TUNER_MODE_LANG1 ] = 0x00, /* ch1 */
477 [ V4L2_TUNER_MODE_LANG2 ] = 0x01, /* ch2 */
478 };
479 u32 reg;
480
481 switch (audio->mode) {
482 case TVAUDIO_FM_MONO:
483 /* nothing to do ... */
484 break;
485 case TVAUDIO_FM_K_STEREO:
486 case TVAUDIO_FM_BG_STEREO:
487 dprintk("setstereo [fm] => %s\n",
488 name[ mode % ARRAY_SIZE(name) ]);
489 reg = fm[ mode % ARRAY_SIZE(fm) ];
490 saa_writeb(SAA7134_FM_DEMATRIX, reg);
491 break;
492 case TVAUDIO_FM_SAT_STEREO:
493 case TVAUDIO_NICAM_AM:
494 case TVAUDIO_NICAM_FM:
495 /* FIXME */
496 break;
497 }
498 return 0;
499}
500
501static int tvaudio_thread(void *data)
502{
503 struct saa7134_dev *dev = data;
504 int carr_vals[ARRAY_SIZE(mainscan)];
505 unsigned int i, audio, nscan;
506 int max1,max2,carrier,rx,mode,lastmode,default_carrier;
507
508 daemonize("%s", dev->name);
509 allow_signal(SIGTERM);
510 for (;;) {
511 tvaudio_sleep(dev,-1);
512 if (dev->thread.shutdown || signal_pending(current))
513 goto done;
514
515 restart:
516 dev->thread.scan1 = dev->thread.scan2;
517 dprintk("tvaudio thread scan start [%d]\n",dev->thread.scan1);
518 dev->tvaudio = NULL;
519 tvaudio_init(dev);
520 if (dev->ctl_automute)
521 dev->automute = 1;
522 mute_input_7134(dev);
523
524 /* give the tuner some time */
525 if (tvaudio_sleep(dev,SCAN_INITIAL_DELAY))
526 goto restart;
527
528 max1 = 0;
529 max2 = 0;
530 nscan = 0;
531 carrier = 0;
532 default_carrier = 0;
533 for (i = 0; i < ARRAY_SIZE(mainscan); i++) {
534 if (!(dev->tvnorm->id & mainscan[i].std))
535 continue;
536 if (!default_carrier)
537 default_carrier = mainscan[i].carr;
538 nscan++;
539 }
540
541 if (1 == nscan) {
542 /* only one candidate -- skip scan ;) */
543 max1 = 12345;
544 carrier = default_carrier;
545 } else {
546 /* scan for the main carrier */
547 saa_writeb(SAA7134_MONITOR_SELECT,0x00);
548 tvaudio_setmode(dev,&tvaudio[0],NULL);
549 for (i = 0; i < ARRAY_SIZE(mainscan); i++) {
550 carr_vals[i] = tvaudio_checkcarrier(dev, mainscan+i);
551 if (dev->thread.scan1 != dev->thread.scan2)
552 goto restart;
553 }
554 for (max1 = 0, max2 = 0, i = 0; i < ARRAY_SIZE(mainscan); i++) {
555 if (max1 < carr_vals[i]) {
556 max2 = max1;
557 max1 = carr_vals[i];
558 carrier = mainscan[i].carr;
559 } else if (max2 < carr_vals[i]) {
560 max2 = carr_vals[i];
561 }
562 }
563 }
564
565 if (0 != carrier && max1 > 2000 && max1 > max2*3) {
566 /* found good carrier */
567 dprintk("found %s main sound carrier @ %d.%03d MHz [%d/%d]\n",
568 dev->tvnorm->name, carrier/1000, carrier%1000,
569 max1, max2);
570 dev->last_carrier = carrier;
571
572 } else if (0 != dev->last_carrier) {
573 /* no carrier -- try last detected one as fallback */
574 carrier = dev->last_carrier;
575 printk(KERN_WARNING "%s/audio: audio carrier scan failed, "
576 "using %d.%03d MHz [last detected]\n",
577 dev->name, carrier/1000, carrier%1000);
578
579 } else {
580 /* no carrier + no fallback -- use default */
581 carrier = default_carrier;
582 printk(KERN_WARNING "%s/audio: audio carrier scan failed, "
583 "using %d.%03d MHz [default]\n",
584 dev->name, carrier/1000, carrier%1000);
585 }
586 tvaudio_setcarrier(dev,carrier,carrier);
587 dev->automute = 0;
588 saa_andorb(SAA7134_STEREO_DAC_OUTPUT_SELECT, 0x30, 0x00);
589 saa7134_tvaudio_setmute(dev);
590
591 /* find the exact tv audio norm */
592 for (audio = UNSET, i = 0; i < TVAUDIO; i++) {
593 if (dev->tvnorm->id != UNSET &&
594 !(dev->tvnorm->id & tvaudio[i].std))
595 continue;
596 if (tvaudio[i].carr1 != carrier)
597 continue;
598
599 if (UNSET == audio)
600 audio = i;
601 tvaudio_setmode(dev,&tvaudio[i],"trying");
602 if (tvaudio_sleep(dev,SCAN_SUBCARRIER_DELAY))
603 goto restart;
604 if (-1 != tvaudio_getstereo(dev,&tvaudio[i])) {
605 audio = i;
606 break;
607 }
608 }
609 saa_andorb(SAA7134_STEREO_DAC_OUTPUT_SELECT, 0x30, 0x30);
610 if (UNSET == audio)
611 continue;
612 tvaudio_setmode(dev,&tvaudio[audio],"using");
613 tvaudio_setstereo(dev,&tvaudio[audio],V4L2_TUNER_MODE_MONO);
614 dev->tvaudio = &tvaudio[audio];
615
616 lastmode = 42;
617 for (;;) {
618 if (tvaudio_sleep(dev,5000))
619 goto restart;
620 if (dev->thread.shutdown || signal_pending(current))
621 break;
622 if (UNSET == dev->thread.mode) {
623 rx = tvaudio_getstereo(dev,&tvaudio[i]);
624 mode = saa7134_tvaudio_rx2mode(rx);
625 } else {
626 mode = dev->thread.mode;
627 }
628 if (lastmode != mode) {
629 tvaudio_setstereo(dev,&tvaudio[audio],mode);
630 lastmode = mode;
631 }
632 }
633 }
634
635 done:
636 complete_and_exit(&dev->thread.exit, 0);
637 return 0;
638}
639
640/* ------------------------------------------------------------------ */
641/* saa7133 / saa7135 code */
642
643static char *stdres[0x20] = {
644 [0x00] = "no standard detected",
645 [0x01] = "B/G (in progress)",
646 [0x02] = "D/K (in progress)",
647 [0x03] = "M (in progress)",
648
649 [0x04] = "B/G A2",
650 [0x05] = "B/G NICAM",
651 [0x06] = "D/K A2 (1)",
652 [0x07] = "D/K A2 (2)",
653 [0x08] = "D/K A2 (3)",
654 [0x09] = "D/K NICAM",
655 [0x0a] = "L NICAM",
656 [0x0b] = "I NICAM",
657
658 [0x0c] = "M Korea",
659 [0x0d] = "M BTSC ",
660 [0x0e] = "M EIAJ",
661
662 [0x0f] = "FM radio / IF 10.7 / 50 deemp",
663 [0x10] = "FM radio / IF 10.7 / 75 deemp",
664 [0x11] = "FM radio / IF sel / 50 deemp",
665 [0x12] = "FM radio / IF sel / 75 deemp",
666
667 [0x13 ... 0x1e ] = "unknown",
668 [0x1f] = "??? [in progress]",
669};
670
671#define DSP_RETRY 32
672#define DSP_DELAY 16
673
674static inline int saa_dsp_wait_bit(struct saa7134_dev *dev, int bit)
675{
676 int state, count = DSP_RETRY;
677
678 state = saa_readb(SAA7135_DSP_RWSTATE);
679 if (unlikely(state & SAA7135_DSP_RWSTATE_ERR)) {
680 printk("%s: dsp access error\n",dev->name);
681 /* FIXME: send ack ... */
682 return -EIO;
683 }
684 while (0 == (state & bit)) {
685 if (unlikely(0 == count)) {
686 printk("%s: dsp access wait timeout [bit=%s]\n",
687 dev->name,
688 (bit & SAA7135_DSP_RWSTATE_WRR) ? "WRR" :
689 (bit & SAA7135_DSP_RWSTATE_RDB) ? "RDB" :
690 (bit & SAA7135_DSP_RWSTATE_IDA) ? "IDA" :
691 "???");
692 return -EIO;
693 }
694 saa_wait(DSP_DELAY);
695 state = saa_readb(SAA7135_DSP_RWSTATE);
696 count--;
697 }
698 return 0;
699}
700
701#if 0
702static int saa_dsp_readl(struct saa7134_dev *dev, int reg, u32 *value)
703{
704 int err;
705
706 d2printk("dsp read reg 0x%x\n", reg<<2);
707 saa_readl(reg);
708 err = saa_dsp_wait_bit(dev,SAA7135_DSP_RWSTATE_RDB);
709 if (err < 0)
710 return err;
711 *value = saa_readl(reg);
712 d2printk("dsp read => 0x%06x\n", *value & 0xffffff);
713 err = saa_dsp_wait_bit(dev,SAA7135_DSP_RWSTATE_IDA);
714 if (err < 0)
715 return err;
716 return 0;
717}
718#endif
719
720int saa_dsp_writel(struct saa7134_dev *dev, int reg, u32 value)
721{
722 int err;
723
724 d2printk("dsp write reg 0x%x = 0x%06x\n",reg<<2,value);
725 err = saa_dsp_wait_bit(dev,SAA7135_DSP_RWSTATE_WRR);
726 if (err < 0)
727 return err;
728 saa_writel(reg,value);
729 err = saa_dsp_wait_bit(dev,SAA7135_DSP_RWSTATE_WRR);
730 if (err < 0)
731 return err;
732 return 0;
733}
734
735static int getstereo_7133(struct saa7134_dev *dev)
736{
737 int retval = V4L2_TUNER_SUB_MONO;
738 u32 value;
739
740 value = saa_readl(0x528 >> 2);
741 if (value & 0x20)
742 retval = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
743 if (value & 0x40)
744 retval = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
745 return retval;
746}
747
748static int mute_input_7133(struct saa7134_dev *dev)
749{
750 u32 reg = 0;
751 int mask;
752
753 switch (dev->input->amux) {
754 case TV:
755 reg = 0x02;
756 break;
757 case LINE1:
758 reg = 0x00;
759 break;
760 case LINE2:
761 case LINE2_LEFT:
762 reg = 0x01;
763 break;
764 }
765 if (dev->ctl_mute)
766 reg = 0x07;
767 saa_writel(0x594 >> 2, reg);
768
769 /* switch gpio-connected external audio mux */
770 if (0 != card(dev).gpiomask) {
771 mask = card(dev).gpiomask;
772 saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, mask, mask);
773 saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, mask, dev->input->gpio);
774 saa7134_track_gpio(dev,dev->input->name);
775 }
776 return 0;
777}
778
779static int tvaudio_thread_ddep(void *data)
780{
781 struct saa7134_dev *dev = data;
782 u32 value, norms, clock;
783
784 daemonize("%s", dev->name);
785 allow_signal(SIGTERM);
786
787 clock = saa7134_boards[dev->board].audio_clock;
788 if (UNSET != audio_clock_override)
789 clock = audio_clock_override;
790 saa_writel(0x598 >> 2, clock);
791
792 /* unmute */
793 saa_dsp_writel(dev, 0x474 >> 2, 0x00);
794 saa_dsp_writel(dev, 0x450 >> 2, 0x00);
795
796 for (;;) {
797 tvaudio_sleep(dev,-1);
798 if (dev->thread.shutdown || signal_pending(current))
799 goto done;
800
801 restart:
802 dev->thread.scan1 = dev->thread.scan2;
803 dprintk("tvaudio thread scan start [%d]\n",dev->thread.scan1);
804
805 if (audio_ddep >= 0x04 && audio_ddep <= 0x0e) {
806 /* insmod option override */
807 norms = (audio_ddep << 2) | 0x01;
808 dprintk("ddep override: %s\n",stdres[audio_ddep]);
809 } else if (&card(dev).radio == dev->input) {
810 dprintk("FM Radio\n");
811 norms = (0x0f << 2) | 0x01;
812 } else {
813 /* (let chip) scan for sound carrier */
814 norms = 0;
815 if (dev->tvnorm->id & V4L2_STD_PAL) {
816 dprintk("PAL scan\n");
817 norms |= 0x2c; /* B/G + D/K + I */
818 }
819 if (dev->tvnorm->id & V4L2_STD_NTSC) {
820 dprintk("NTSC scan\n");
821 norms |= 0x40; /* M */
822 }
823 if (dev->tvnorm->id & V4L2_STD_SECAM) {
824 dprintk("SECAM scan\n");
825 norms |= 0x18; /* L + D/K */
826 }
827 if (0 == norms)
828 norms = 0x7c; /* all */
829 dprintk("scanning:%s%s%s%s%s\n",
830 (norms & 0x04) ? " B/G" : "",
831 (norms & 0x08) ? " D/K" : "",
832 (norms & 0x10) ? " L/L'" : "",
833 (norms & 0x20) ? " I" : "",
834 (norms & 0x40) ? " M" : "");
835 }
836
837 /* kick automatic standard detection */
838 saa_dsp_writel(dev, 0x454 >> 2, 0);
839 saa_dsp_writel(dev, 0x454 >> 2, norms | 0x80);
840
841 /* setup crossbars */
842 saa_dsp_writel(dev, 0x464 >> 2, 0x000000);
843 saa_dsp_writel(dev, 0x470 >> 2, 0x101010);
844
845 if (tvaudio_sleep(dev,3000))
846 goto restart;
847 value = saa_readl(0x528 >> 2) & 0xffffff;
848
849 dprintk("tvaudio thread status: 0x%x [%s%s%s]\n",
850 value, stdres[value & 0x1f],
851 (value & 0x000020) ? ",stereo" : "",
852 (value & 0x000040) ? ",dual" : "");
853 dprintk("detailed status: "
854 "%s#%s#%s#%s#%s#%s#%s#%s#%s#%s#%s#%s#%s#%s\n",
855 (value & 0x000080) ? " A2/EIAJ pilot tone " : "",
856 (value & 0x000100) ? " A2/EIAJ dual " : "",
857 (value & 0x000200) ? " A2/EIAJ stereo " : "",
858 (value & 0x000400) ? " A2/EIAJ noise mute " : "",
859
860 (value & 0x000800) ? " BTSC/FM radio pilot " : "",
861 (value & 0x001000) ? " SAP carrier " : "",
862 (value & 0x002000) ? " BTSC stereo noise mute " : "",
863 (value & 0x004000) ? " SAP noise mute " : "",
864 (value & 0x008000) ? " VDSP " : "",
865
866 (value & 0x010000) ? " NICST " : "",
867 (value & 0x020000) ? " NICDU " : "",
868 (value & 0x040000) ? " NICAM muted " : "",
869 (value & 0x080000) ? " NICAM reserve sound " : "",
870
871 (value & 0x100000) ? " init done " : "");
872 }
873
874 done:
875 complete_and_exit(&dev->thread.exit, 0);
876 return 0;
877}
878
879/* ------------------------------------------------------------------ */
880/* common stuff + external entry points */
881
882static void saa7134_enable_i2s(struct saa7134_dev *dev)
883{
884 int i2s_format;
885
886 if (!card_is_empress(dev))
887 return;
888 i2s_format = (dev->input->amux == TV) ? 0x00 : 0x01;
889
890 /* enable I2S audio output for the mpeg encoder */
891 saa_writeb(SAA7134_I2S_OUTPUT_SELECT, 0x80);
892 saa_writeb(SAA7134_I2S_OUTPUT_FORMAT, i2s_format);
893 saa_writeb(SAA7134_I2S_OUTPUT_LEVEL, 0x0F);
894 saa_writeb(SAA7134_I2S_AUDIO_OUTPUT, 0x01);
895}
896
897int saa7134_tvaudio_rx2mode(u32 rx)
898{
899 u32 mode;
900
901 mode = V4L2_TUNER_MODE_MONO;
902 if (rx & V4L2_TUNER_SUB_STEREO)
903 mode = V4L2_TUNER_MODE_STEREO;
904 else if (rx & V4L2_TUNER_SUB_LANG1)
905 mode = V4L2_TUNER_MODE_LANG1;
906 else if (rx & V4L2_TUNER_SUB_LANG2)
907 mode = V4L2_TUNER_MODE_LANG2;
908 return mode;
909}
910
911void saa7134_tvaudio_setmute(struct saa7134_dev *dev)
912{
913 switch (dev->pci->device) {
914 case PCI_DEVICE_ID_PHILIPS_SAA7130:
915 case PCI_DEVICE_ID_PHILIPS_SAA7134:
916 mute_input_7134(dev);
917 break;
918 case PCI_DEVICE_ID_PHILIPS_SAA7133:
919 case PCI_DEVICE_ID_PHILIPS_SAA7135:
920 mute_input_7133(dev);
921 break;
922 }
923}
924
925void saa7134_tvaudio_setinput(struct saa7134_dev *dev,
926 struct saa7134_input *in)
927{
928 dev->input = in;
929 switch (dev->pci->device) {
930 case PCI_DEVICE_ID_PHILIPS_SAA7130:
931 case PCI_DEVICE_ID_PHILIPS_SAA7134:
932 mute_input_7134(dev);
933 break;
934 case PCI_DEVICE_ID_PHILIPS_SAA7133:
935 case PCI_DEVICE_ID_PHILIPS_SAA7135:
936 mute_input_7133(dev);
937 break;
938 }
939 saa7134_enable_i2s(dev);
940}
941
942void saa7134_tvaudio_setvolume(struct saa7134_dev *dev, int level)
943{
944 switch (dev->pci->device) {
945 case PCI_DEVICE_ID_PHILIPS_SAA7134:
946 saa_writeb(SAA7134_CHANNEL1_LEVEL, level & 0x1f);
947 saa_writeb(SAA7134_CHANNEL2_LEVEL, level & 0x1f);
948 saa_writeb(SAA7134_NICAM_LEVEL_ADJUST, level & 0x1f);
949 break;
950 }
951}
952
953int saa7134_tvaudio_getstereo(struct saa7134_dev *dev)
954{
955 int retval = V4L2_TUNER_SUB_MONO;
956
957 switch (dev->pci->device) {
958 case PCI_DEVICE_ID_PHILIPS_SAA7134:
959 if (dev->tvaudio)
960 retval = tvaudio_getstereo(dev,dev->tvaudio);
961 break;
962 case PCI_DEVICE_ID_PHILIPS_SAA7133:
963 case PCI_DEVICE_ID_PHILIPS_SAA7135:
964 retval = getstereo_7133(dev);
965 break;
966 }
967 return retval;
968}
969
970int saa7134_tvaudio_init2(struct saa7134_dev *dev)
971{
972 DECLARE_MUTEX_LOCKED(sem);
973 int (*my_thread)(void *data) = NULL;
974
975 switch (dev->pci->device) {
976 case PCI_DEVICE_ID_PHILIPS_SAA7134:
977 my_thread = tvaudio_thread;
978 break;
979 case PCI_DEVICE_ID_PHILIPS_SAA7133:
980 case PCI_DEVICE_ID_PHILIPS_SAA7135:
981 my_thread = tvaudio_thread_ddep;
982 break;
983 }
984
985 dev->thread.pid = -1;
986 if (my_thread) {
987 /* start tvaudio thread */
988 init_waitqueue_head(&dev->thread.wq);
989 init_completion(&dev->thread.exit);
990 dev->thread.pid = kernel_thread(my_thread,dev,0);
991 if (dev->thread.pid < 0)
992 printk(KERN_WARNING "%s: kernel_thread() failed\n",
993 dev->name);
994 saa7134_tvaudio_do_scan(dev);
995 }
996
997 saa7134_enable_i2s(dev);
998 return 0;
999}
1000
1001int saa7134_tvaudio_fini(struct saa7134_dev *dev)
1002{
1003 /* shutdown tvaudio thread */
1004 if (dev->thread.pid >= 0) {
1005 dev->thread.shutdown = 1;
1006 wake_up_interruptible(&dev->thread.wq);
1007 wait_for_completion(&dev->thread.exit);
1008 }
1009 saa_andorb(SAA7134_ANALOG_IO_SELECT, 0x07, 0x00); /* LINE1 */
1010 return 0;
1011}
1012
1013int saa7134_tvaudio_do_scan(struct saa7134_dev *dev)
1014{
1015 if (dev->thread.pid >= 0) {
1016 dev->thread.mode = UNSET;
1017 dev->thread.scan2++;
1018 wake_up_interruptible(&dev->thread.wq);
1019 } else {
1020 dev->automute = 0;
1021 saa7134_tvaudio_setmute(dev);
1022 }
1023 return 0;
1024}
1025
1026/* ----------------------------------------------------------- */
1027/*
1028 * Local variables:
1029 * c-basic-offset: 8
1030 * End:
1031 */
diff --git a/drivers/media/video/saa7134/saa7134-vbi.c b/drivers/media/video/saa7134/saa7134-vbi.c
new file mode 100644
index 00000000000..86954cc7c37
--- /dev/null
+++ b/drivers/media/video/saa7134/saa7134-vbi.c
@@ -0,0 +1,270 @@
1/*
2 * $Id: saa7134-vbi.c,v 1.6 2004/12/10 12:33:39 kraxel Exp $
3 *
4 * device driver for philips saa7134 based TV cards
5 * video4linux video interface
6 *
7 * (c) 2001,02 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
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#include <linux/init.h>
25#include <linux/list.h>
26#include <linux/module.h>
27#include <linux/moduleparam.h>
28#include <linux/kernel.h>
29#include <linux/slab.h>
30
31#include "saa7134-reg.h"
32#include "saa7134.h"
33
34/* ------------------------------------------------------------------ */
35
36static unsigned int vbi_debug = 0;
37module_param(vbi_debug, int, 0644);
38MODULE_PARM_DESC(vbi_debug,"enable debug messages [vbi]");
39
40static unsigned int vbibufs = 4;
41module_param(vbibufs, int, 0444);
42MODULE_PARM_DESC(vbibufs,"number of vbi buffers, range 2-32");
43
44#define dprintk(fmt, arg...) if (vbi_debug) \
45 printk(KERN_DEBUG "%s/vbi: " fmt, dev->name , ## arg)
46
47/* ------------------------------------------------------------------ */
48
49#define VBI_LINE_COUNT 16
50#define VBI_LINE_LENGTH 2048
51#define VBI_SCALE 0x200
52
53static void task_init(struct saa7134_dev *dev, struct saa7134_buf *buf,
54 int task)
55{
56 struct saa7134_tvnorm *norm = dev->tvnorm;
57
58 /* setup video scaler */
59 saa_writeb(SAA7134_VBI_H_START1(task), norm->h_start & 0xff);
60 saa_writeb(SAA7134_VBI_H_START2(task), norm->h_start >> 8);
61 saa_writeb(SAA7134_VBI_H_STOP1(task), norm->h_stop & 0xff);
62 saa_writeb(SAA7134_VBI_H_STOP2(task), norm->h_stop >> 8);
63 saa_writeb(SAA7134_VBI_V_START1(task), norm->vbi_v_start & 0xff);
64 saa_writeb(SAA7134_VBI_V_START2(task), norm->vbi_v_start >> 8);
65 saa_writeb(SAA7134_VBI_V_STOP1(task), norm->vbi_v_stop & 0xff);
66 saa_writeb(SAA7134_VBI_V_STOP2(task), norm->vbi_v_stop >> 8);
67
68 saa_writeb(SAA7134_VBI_H_SCALE_INC1(task), VBI_SCALE & 0xff);
69 saa_writeb(SAA7134_VBI_H_SCALE_INC2(task), VBI_SCALE >> 8);
70 saa_writeb(SAA7134_VBI_PHASE_OFFSET_LUMA(task), 0x00);
71 saa_writeb(SAA7134_VBI_PHASE_OFFSET_CHROMA(task), 0x00);
72
73 saa_writeb(SAA7134_VBI_H_LEN1(task), buf->vb.width & 0xff);
74 saa_writeb(SAA7134_VBI_H_LEN2(task), buf->vb.width >> 8);
75 saa_writeb(SAA7134_VBI_V_LEN1(task), buf->vb.height & 0xff);
76 saa_writeb(SAA7134_VBI_V_LEN2(task), buf->vb.height >> 8);
77
78 saa_andorb(SAA7134_DATA_PATH(task), 0xc0, 0x00);
79}
80
81/* ------------------------------------------------------------------ */
82
83static int buffer_activate(struct saa7134_dev *dev,
84 struct saa7134_buf *buf,
85 struct saa7134_buf *next)
86{
87 unsigned long control,base;
88
89 dprintk("buffer_activate [%p]\n",buf);
90 buf->vb.state = STATE_ACTIVE;
91 buf->top_seen = 0;
92
93 task_init(dev,buf,TASK_A);
94 task_init(dev,buf,TASK_B);
95 saa_writeb(SAA7134_OFMT_DATA_A, 0x06);
96 saa_writeb(SAA7134_OFMT_DATA_B, 0x06);
97
98 /* DMA: setup channel 2+3 (= VBI Task A+B) */
99 base = saa7134_buffer_base(buf);
100 control = SAA7134_RS_CONTROL_BURST_16 |
101 SAA7134_RS_CONTROL_ME |
102 (buf->pt->dma >> 12);
103 saa_writel(SAA7134_RS_BA1(2),base);
104 saa_writel(SAA7134_RS_BA2(2),base + buf->vb.size/2);
105 saa_writel(SAA7134_RS_PITCH(2),buf->vb.width);
106 saa_writel(SAA7134_RS_CONTROL(2),control);
107 saa_writel(SAA7134_RS_BA1(3),base);
108 saa_writel(SAA7134_RS_BA2(3),base + buf->vb.size/2);
109 saa_writel(SAA7134_RS_PITCH(3),buf->vb.width);
110 saa_writel(SAA7134_RS_CONTROL(3),control);
111
112 /* start DMA */
113 saa7134_set_dmabits(dev);
114 mod_timer(&dev->vbi_q.timeout, jiffies+BUFFER_TIMEOUT);
115
116 return 0;
117}
118
119static int buffer_prepare(struct videobuf_queue *q,
120 struct videobuf_buffer *vb,
121 enum v4l2_field field)
122{
123 struct saa7134_fh *fh = q->priv_data;
124 struct saa7134_dev *dev = fh->dev;
125 struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb);
126 struct saa7134_tvnorm *norm = dev->tvnorm;
127 unsigned int lines, llength, size;
128 int err;
129
130 lines = norm->vbi_v_stop - norm->vbi_v_start +1;
131 if (lines > VBI_LINE_COUNT)
132 lines = VBI_LINE_COUNT;
133#if 1
134 llength = VBI_LINE_LENGTH;
135#else
136 llength = (norm->h_stop - norm->h_start +1) * 2;
137 if (llength > VBI_LINE_LENGTH)
138 llength = VBI_LINE_LENGTH;
139#endif
140 size = lines * llength * 2;
141 if (0 != buf->vb.baddr && buf->vb.bsize < size)
142 return -EINVAL;
143
144 if (buf->vb.size != size)
145 saa7134_dma_free(dev,buf);
146
147 if (STATE_NEEDS_INIT == buf->vb.state) {
148 buf->vb.width = llength;
149 buf->vb.height = lines;
150 buf->vb.size = size;
151 buf->pt = &fh->pt_vbi;
152
153 err = videobuf_iolock(dev->pci,&buf->vb,NULL);
154 if (err)
155 goto oops;
156 err = saa7134_pgtable_build(dev->pci,buf->pt,
157 buf->vb.dma.sglist,
158 buf->vb.dma.sglen,
159 saa7134_buffer_startpage(buf));
160 if (err)
161 goto oops;
162 }
163 buf->vb.state = STATE_PREPARED;
164 buf->activate = buffer_activate;
165 buf->vb.field = field;
166 return 0;
167
168 oops:
169 saa7134_dma_free(dev,buf);
170 return err;
171}
172
173static int
174buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
175{
176 struct saa7134_fh *fh = q->priv_data;
177 struct saa7134_dev *dev = fh->dev;
178 int llength,lines;
179
180 lines = dev->tvnorm->vbi_v_stop - dev->tvnorm->vbi_v_start +1;
181#if 1
182 llength = VBI_LINE_LENGTH;
183#else
184 llength = (norm->h_stop - norm->h_start +1) * 2;
185 if (llength > VBI_LINE_LENGTH)
186 llength = VBI_LINE_LENGTH;
187#endif
188 *size = lines * llength * 2;
189 if (0 == *count)
190 *count = vbibufs;
191 *count = saa7134_buffer_count(*size,*count);
192 return 0;
193}
194
195static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
196{
197 struct saa7134_fh *fh = q->priv_data;
198 struct saa7134_dev *dev = fh->dev;
199 struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb);
200
201 saa7134_buffer_queue(dev,&dev->vbi_q,buf);
202}
203
204static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
205{
206 struct saa7134_fh *fh = q->priv_data;
207 struct saa7134_dev *dev = fh->dev;
208 struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb);
209
210 saa7134_dma_free(dev,buf);
211}
212
213struct videobuf_queue_ops saa7134_vbi_qops = {
214 .buf_setup = buffer_setup,
215 .buf_prepare = buffer_prepare,
216 .buf_queue = buffer_queue,
217 .buf_release = buffer_release,
218};
219
220/* ------------------------------------------------------------------ */
221
222int saa7134_vbi_init1(struct saa7134_dev *dev)
223{
224 INIT_LIST_HEAD(&dev->vbi_q.queue);
225 init_timer(&dev->vbi_q.timeout);
226 dev->vbi_q.timeout.function = saa7134_buffer_timeout;
227 dev->vbi_q.timeout.data = (unsigned long)(&dev->vbi_q);
228 dev->vbi_q.dev = dev;
229
230 if (vbibufs < 2)
231 vbibufs = 2;
232 if (vbibufs > VIDEO_MAX_FRAME)
233 vbibufs = VIDEO_MAX_FRAME;
234 return 0;
235}
236
237int saa7134_vbi_fini(struct saa7134_dev *dev)
238{
239 /* nothing */
240 return 0;
241}
242
243void saa7134_irq_vbi_done(struct saa7134_dev *dev, unsigned long status)
244{
245 spin_lock(&dev->slock);
246 if (dev->vbi_q.curr) {
247 dev->vbi_fieldcount++;
248 /* make sure we have seen both fields */
249 if ((status & 0x10) == 0x00) {
250 dev->vbi_q.curr->top_seen = 1;
251 goto done;
252 }
253 if (!dev->vbi_q.curr->top_seen)
254 goto done;
255
256 dev->vbi_q.curr->vb.field_count = dev->vbi_fieldcount;
257 saa7134_buffer_finish(dev,&dev->vbi_q,STATE_DONE);
258 }
259 saa7134_buffer_next(dev,&dev->vbi_q);
260
261 done:
262 spin_unlock(&dev->slock);
263}
264
265/* ----------------------------------------------------------- */
266/*
267 * Local variables:
268 * c-basic-offset: 8
269 * End:
270 */
diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c
new file mode 100644
index 00000000000..5d66060026f
--- /dev/null
+++ b/drivers/media/video/saa7134/saa7134-video.c
@@ -0,0 +1,2406 @@
1/*
2 * $Id: saa7134-video.c,v 1.28 2005/02/15 15:59:35 kraxel Exp $
3 *
4 * device driver for philips saa7134 based TV cards
5 * video4linux video interface
6 *
7 * (c) 2001-03 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
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#include <linux/init.h>
25#include <linux/list.h>
26#include <linux/module.h>
27#include <linux/moduleparam.h>
28#include <linux/kernel.h>
29#include <linux/slab.h>
30
31#include "saa7134-reg.h"
32#include "saa7134.h"
33
34#define V4L2_I2C_CLIENTS 1
35
36/* ------------------------------------------------------------------ */
37
38static unsigned int video_debug = 0;
39static unsigned int gbuffers = 8;
40static unsigned int noninterlaced = 0;
41static unsigned int gbufsize = 720*576*4;
42static unsigned int gbufsize_max = 720*576*4;
43module_param(video_debug, int, 0644);
44MODULE_PARM_DESC(video_debug,"enable debug messages [video]");
45module_param(gbuffers, int, 0444);
46MODULE_PARM_DESC(gbuffers,"number of capture buffers, range 2-32");
47module_param(noninterlaced, int, 0644);
48MODULE_PARM_DESC(noninterlaced,"video input is noninterlaced");
49
50#define dprintk(fmt, arg...) if (video_debug) \
51 printk(KERN_DEBUG "%s/video: " fmt, dev->name , ## arg)
52
53/* ------------------------------------------------------------------ */
54/* data structs for video */
55
56static int video_out[][9] = {
57 [CCIR656] = { 0x00, 0xb1, 0x00, 0xa1, 0x00, 0x04, 0x06, 0x00, 0x00 },
58};
59
60static struct saa7134_format formats[] = {
61 {
62 .name = "8 bpp gray",
63 .fourcc = V4L2_PIX_FMT_GREY,
64 .depth = 8,
65 .pm = 0x06,
66 },{
67 .name = "15 bpp RGB, le",
68 .fourcc = V4L2_PIX_FMT_RGB555,
69 .depth = 16,
70 .pm = 0x13 | 0x80,
71 },{
72 .name = "15 bpp RGB, be",
73 .fourcc = V4L2_PIX_FMT_RGB555X,
74 .depth = 16,
75 .pm = 0x13 | 0x80,
76 .bswap = 1,
77 },{
78 .name = "16 bpp RGB, le",
79 .fourcc = V4L2_PIX_FMT_RGB565,
80 .depth = 16,
81 .pm = 0x10 | 0x80,
82 },{
83 .name = "16 bpp RGB, be",
84 .fourcc = V4L2_PIX_FMT_RGB565X,
85 .depth = 16,
86 .pm = 0x10 | 0x80,
87 .bswap = 1,
88 },{
89 .name = "24 bpp RGB, le",
90 .fourcc = V4L2_PIX_FMT_BGR24,
91 .depth = 24,
92 .pm = 0x11,
93 },{
94 .name = "24 bpp RGB, be",
95 .fourcc = V4L2_PIX_FMT_RGB24,
96 .depth = 24,
97 .pm = 0x11,
98 .bswap = 1,
99 },{
100 .name = "32 bpp RGB, le",
101 .fourcc = V4L2_PIX_FMT_BGR32,
102 .depth = 32,
103 .pm = 0x12,
104 },{
105 .name = "32 bpp RGB, be",
106 .fourcc = V4L2_PIX_FMT_RGB32,
107 .depth = 32,
108 .pm = 0x12,
109 .bswap = 1,
110 .wswap = 1,
111 },{
112 .name = "4:2:2 packed, YUYV",
113 .fourcc = V4L2_PIX_FMT_YUYV,
114 .depth = 16,
115 .pm = 0x00,
116 .bswap = 1,
117 .yuv = 1,
118 },{
119 .name = "4:2:2 packed, UYVY",
120 .fourcc = V4L2_PIX_FMT_UYVY,
121 .depth = 16,
122 .pm = 0x00,
123 .yuv = 1,
124 },{
125 .name = "4:2:2 planar, Y-Cb-Cr",
126 .fourcc = V4L2_PIX_FMT_YUV422P,
127 .depth = 16,
128 .pm = 0x09,
129 .yuv = 1,
130 .planar = 1,
131 .hshift = 1,
132 .vshift = 0,
133 },{
134 .name = "4:2:0 planar, Y-Cb-Cr",
135 .fourcc = V4L2_PIX_FMT_YUV420,
136 .depth = 12,
137 .pm = 0x0a,
138 .yuv = 1,
139 .planar = 1,
140 .hshift = 1,
141 .vshift = 1,
142 },{
143 .name = "4:2:0 planar, Y-Cb-Cr",
144 .fourcc = V4L2_PIX_FMT_YVU420,
145 .depth = 12,
146 .pm = 0x0a,
147 .yuv = 1,
148 .planar = 1,
149 .uvswap = 1,
150 .hshift = 1,
151 .vshift = 1,
152 }
153};
154#define FORMATS ARRAY_SIZE(formats)
155
156#define NORM_625_50 \
157 .h_start = 0, \
158 .h_stop = 719, \
159 .video_v_start = 24, \
160 .video_v_stop = 311, \
161 .vbi_v_start = 7, \
162 .vbi_v_stop = 22, \
163 .src_timing = 4
164
165#define NORM_525_60 \
166 .h_start = 0, \
167 .h_stop = 703, \
168 .video_v_start = 22, \
169 .video_v_stop = 22+239, \
170 .vbi_v_start = 10, /* FIXME */ \
171 .vbi_v_stop = 21, /* FIXME */ \
172 .src_timing = 1
173
174static struct saa7134_tvnorm tvnorms[] = {
175 {
176 .name = "PAL", /* autodetect */
177 .id = V4L2_STD_PAL,
178 NORM_625_50,
179
180 .sync_control = 0x18,
181 .luma_control = 0x40,
182 .chroma_ctrl1 = 0x81,
183 .chroma_gain = 0x2a,
184 .chroma_ctrl2 = 0x06,
185 .vgate_misc = 0x1c,
186
187 },{
188 .name = "PAL-BG",
189 .id = V4L2_STD_PAL_BG,
190 NORM_625_50,
191
192 .sync_control = 0x18,
193 .luma_control = 0x40,
194 .chroma_ctrl1 = 0x81,
195 .chroma_gain = 0x2a,
196 .chroma_ctrl2 = 0x06,
197 .vgate_misc = 0x1c,
198
199 },{
200 .name = "PAL-I",
201 .id = V4L2_STD_PAL_I,
202 NORM_625_50,
203
204 .sync_control = 0x18,
205 .luma_control = 0x40,
206 .chroma_ctrl1 = 0x81,
207 .chroma_gain = 0x2a,
208 .chroma_ctrl2 = 0x06,
209 .vgate_misc = 0x1c,
210
211 },{
212 .name = "PAL-DK",
213 .id = V4L2_STD_PAL_DK,
214 NORM_625_50,
215
216 .sync_control = 0x18,
217 .luma_control = 0x40,
218 .chroma_ctrl1 = 0x81,
219 .chroma_gain = 0x2a,
220 .chroma_ctrl2 = 0x06,
221 .vgate_misc = 0x1c,
222
223 },{
224 .name = "NTSC",
225 .id = V4L2_STD_NTSC,
226 NORM_525_60,
227
228 .sync_control = 0x59,
229 .luma_control = 0x40,
230 .chroma_ctrl1 = 0x89,
231 .chroma_gain = 0x2a,
232 .chroma_ctrl2 = 0x0e,
233 .vgate_misc = 0x18,
234
235 },{
236 .name = "SECAM",
237 .id = V4L2_STD_SECAM,
238 NORM_625_50,
239
240 .sync_control = 0x18, /* old: 0x58, */
241 .luma_control = 0x1b,
242 .chroma_ctrl1 = 0xd1,
243 .chroma_gain = 0x80,
244 .chroma_ctrl2 = 0x00,
245 .vgate_misc = 0x1c,
246
247 },{
248 .name = "PAL-M",
249 .id = V4L2_STD_PAL_M,
250 NORM_525_60,
251
252 .sync_control = 0x59,
253 .luma_control = 0x40,
254 .chroma_ctrl1 = 0xb9,
255 .chroma_gain = 0x2a,
256 .chroma_ctrl2 = 0x0e,
257 .vgate_misc = 0x18,
258
259 },{
260 .name = "PAL-Nc",
261 .id = V4L2_STD_PAL_Nc,
262 NORM_625_50,
263
264 .sync_control = 0x18,
265 .luma_control = 0x40,
266 .chroma_ctrl1 = 0xa1,
267 .chroma_gain = 0x2a,
268 .chroma_ctrl2 = 0x06,
269 .vgate_misc = 0x1c,
270
271 },{
272 .name = "PAL-60",
273 .id = V4L2_STD_PAL_60,
274
275 .h_start = 0,
276 .h_stop = 719,
277 .video_v_start = 22,
278 .video_v_stop = 22+239,
279 .vbi_v_start = 10, /* FIXME */
280 .vbi_v_stop = 21, /* FIXME */
281 .src_timing = 1,
282
283 .sync_control = 0x18,
284 .luma_control = 0x40,
285 .chroma_ctrl1 = 0x81,
286 .chroma_gain = 0x2a,
287 .chroma_ctrl2 = 0x06,
288 .vgate_misc = 0x1c,
289 }
290};
291#define TVNORMS ARRAY_SIZE(tvnorms)
292
293#define V4L2_CID_PRIVATE_INVERT (V4L2_CID_PRIVATE_BASE + 0)
294#define V4L2_CID_PRIVATE_Y_ODD (V4L2_CID_PRIVATE_BASE + 1)
295#define V4L2_CID_PRIVATE_Y_EVEN (V4L2_CID_PRIVATE_BASE + 2)
296#define V4L2_CID_PRIVATE_AUTOMUTE (V4L2_CID_PRIVATE_BASE + 3)
297#define V4L2_CID_PRIVATE_LASTP1 (V4L2_CID_PRIVATE_BASE + 4)
298
299static const struct v4l2_queryctrl no_ctrl = {
300 .name = "42",
301 .flags = V4L2_CTRL_FLAG_DISABLED,
302};
303static const struct v4l2_queryctrl video_ctrls[] = {
304 /* --- video --- */
305 {
306 .id = V4L2_CID_BRIGHTNESS,
307 .name = "Brightness",
308 .minimum = 0,
309 .maximum = 255,
310 .step = 1,
311 .default_value = 128,
312 .type = V4L2_CTRL_TYPE_INTEGER,
313 },{
314 .id = V4L2_CID_CONTRAST,
315 .name = "Contrast",
316 .minimum = 0,
317 .maximum = 127,
318 .step = 1,
319 .default_value = 68,
320 .type = V4L2_CTRL_TYPE_INTEGER,
321 },{
322 .id = V4L2_CID_SATURATION,
323 .name = "Saturation",
324 .minimum = 0,
325 .maximum = 127,
326 .step = 1,
327 .default_value = 64,
328 .type = V4L2_CTRL_TYPE_INTEGER,
329 },{
330 .id = V4L2_CID_HUE,
331 .name = "Hue",
332 .minimum = -128,
333 .maximum = 127,
334 .step = 1,
335 .default_value = 0,
336 .type = V4L2_CTRL_TYPE_INTEGER,
337 },{
338 .id = V4L2_CID_VFLIP,
339 .name = "vertical flip",
340 .minimum = 0,
341 .maximum = 1,
342 .type = V4L2_CTRL_TYPE_BOOLEAN,
343 },
344 /* --- audio --- */
345 {
346 .id = V4L2_CID_AUDIO_MUTE,
347 .name = "Mute",
348 .minimum = 0,
349 .maximum = 1,
350 .type = V4L2_CTRL_TYPE_BOOLEAN,
351 },{
352 .id = V4L2_CID_AUDIO_VOLUME,
353 .name = "Volume",
354 .minimum = -15,
355 .maximum = 15,
356 .step = 1,
357 .default_value = 0,
358 .type = V4L2_CTRL_TYPE_INTEGER,
359 },
360 /* --- private --- */
361 {
362 .id = V4L2_CID_PRIVATE_INVERT,
363 .name = "Invert",
364 .minimum = 0,
365 .maximum = 1,
366 .type = V4L2_CTRL_TYPE_BOOLEAN,
367 },{
368 .id = V4L2_CID_PRIVATE_Y_ODD,
369 .name = "y offset odd field",
370 .minimum = 0,
371 .maximum = 128,
372 .default_value = 0,
373 .type = V4L2_CTRL_TYPE_INTEGER,
374 },{
375 .id = V4L2_CID_PRIVATE_Y_EVEN,
376 .name = "y offset even field",
377 .minimum = 0,
378 .maximum = 128,
379 .default_value = 0,
380 .type = V4L2_CTRL_TYPE_INTEGER,
381 },{
382 .id = V4L2_CID_PRIVATE_AUTOMUTE,
383 .name = "automute",
384 .minimum = 0,
385 .maximum = 1,
386 .default_value = 1,
387 .type = V4L2_CTRL_TYPE_BOOLEAN,
388 }
389};
390static const unsigned int CTRLS = ARRAY_SIZE(video_ctrls);
391
392static const struct v4l2_queryctrl* ctrl_by_id(unsigned int id)
393{
394 unsigned int i;
395
396 for (i = 0; i < CTRLS; i++)
397 if (video_ctrls[i].id == id)
398 return video_ctrls+i;
399 return NULL;
400}
401
402static struct saa7134_format* format_by_fourcc(unsigned int fourcc)
403{
404 unsigned int i;
405
406 for (i = 0; i < FORMATS; i++)
407 if (formats[i].fourcc == fourcc)
408 return formats+i;
409 return NULL;
410}
411
412/* ----------------------------------------------------------------------- */
413/* resource management */
414
415static int res_get(struct saa7134_dev *dev, struct saa7134_fh *fh, unsigned int bit)
416{
417 if (fh->resources & bit)
418 /* have it already allocated */
419 return 1;
420
421 /* is it free? */
422 down(&dev->lock);
423 if (dev->resources & bit) {
424 /* no, someone else uses it */
425 up(&dev->lock);
426 return 0;
427 }
428 /* it's free, grab it */
429 fh->resources |= bit;
430 dev->resources |= bit;
431 dprintk("res: get %d\n",bit);
432 up(&dev->lock);
433 return 1;
434}
435
436static
437int res_check(struct saa7134_fh *fh, unsigned int bit)
438{
439 return (fh->resources & bit);
440}
441
442static
443int res_locked(struct saa7134_dev *dev, unsigned int bit)
444{
445 return (dev->resources & bit);
446}
447
448static
449void res_free(struct saa7134_dev *dev, struct saa7134_fh *fh, unsigned int bits)
450{
451 if ((fh->resources & bits) != bits)
452 BUG();
453
454 down(&dev->lock);
455 fh->resources &= ~bits;
456 dev->resources &= ~bits;
457 dprintk("res: put %d\n",bits);
458 up(&dev->lock);
459}
460
461/* ------------------------------------------------------------------ */
462
463static void set_tvnorm(struct saa7134_dev *dev, struct saa7134_tvnorm *norm)
464{
465 int luma_control,sync_control,mux;
466
467 dprintk("set tv norm = %s\n",norm->name);
468 dev->tvnorm = norm;
469
470 mux = card_in(dev,dev->ctl_input).vmux;
471 luma_control = norm->luma_control;
472 sync_control = norm->sync_control;
473
474 if (mux > 5)
475 luma_control |= 0x80; /* svideo */
476 if (noninterlaced || dev->nosignal)
477 sync_control |= 0x20;
478
479 /* setup cropping */
480 dev->crop_bounds.left = norm->h_start;
481 dev->crop_defrect.left = norm->h_start;
482 dev->crop_bounds.width = norm->h_stop - norm->h_start +1;
483 dev->crop_defrect.width = norm->h_stop - norm->h_start +1;
484
485 dev->crop_bounds.top = (norm->vbi_v_stop+1)*2;
486 dev->crop_defrect.top = norm->video_v_start*2;
487 dev->crop_bounds.height = ((norm->id & V4L2_STD_525_60) ? 524 : 624)
488 - dev->crop_bounds.top;
489 dev->crop_defrect.height = (norm->video_v_stop - norm->video_v_start +1)*2;
490
491 dev->crop_current = dev->crop_defrect;
492
493 /* setup video decoder */
494 saa_writeb(SAA7134_INCR_DELAY, 0x08);
495 saa_writeb(SAA7134_ANALOG_IN_CTRL1, 0xc0 | mux);
496 saa_writeb(SAA7134_ANALOG_IN_CTRL2, 0x00);
497
498 saa_writeb(SAA7134_ANALOG_IN_CTRL3, 0x90);
499 saa_writeb(SAA7134_ANALOG_IN_CTRL4, 0x90);
500 saa_writeb(SAA7134_HSYNC_START, 0xeb);
501 saa_writeb(SAA7134_HSYNC_STOP, 0xe0);
502 saa_writeb(SAA7134_SOURCE_TIMING1, norm->src_timing);
503
504 saa_writeb(SAA7134_SYNC_CTRL, sync_control);
505 saa_writeb(SAA7134_LUMA_CTRL, luma_control);
506 saa_writeb(SAA7134_DEC_LUMA_BRIGHT, dev->ctl_bright);
507 saa_writeb(SAA7134_DEC_LUMA_CONTRAST, dev->ctl_contrast);
508
509 saa_writeb(SAA7134_DEC_CHROMA_SATURATION, dev->ctl_saturation);
510 saa_writeb(SAA7134_DEC_CHROMA_HUE, dev->ctl_hue);
511 saa_writeb(SAA7134_CHROMA_CTRL1, norm->chroma_ctrl1);
512 saa_writeb(SAA7134_CHROMA_GAIN, norm->chroma_gain);
513
514 saa_writeb(SAA7134_CHROMA_CTRL2, norm->chroma_ctrl2);
515 saa_writeb(SAA7134_MODE_DELAY_CTRL, 0x00);
516
517 saa_writeb(SAA7134_ANALOG_ADC, 0x01);
518 saa_writeb(SAA7134_VGATE_START, 0x11);
519 saa_writeb(SAA7134_VGATE_STOP, 0xfe);
520 saa_writeb(SAA7134_MISC_VGATE_MSB, norm->vgate_misc);
521 saa_writeb(SAA7134_RAW_DATA_GAIN, 0x40);
522 saa_writeb(SAA7134_RAW_DATA_OFFSET, 0x80);
523
524#ifdef V4L2_I2C_CLIENTS
525 saa7134_i2c_call_clients(dev,VIDIOC_S_STD,&norm->id);
526#else
527 {
528 /* pass down info to the i2c chips (v4l1) */
529 struct video_channel c;
530 memset(&c,0,sizeof(c));
531 c.channel = dev->ctl_input;
532 c.norm = VIDEO_MODE_PAL;
533 if (norm->id & V4L2_STD_NTSC)
534 c.norm = VIDEO_MODE_NTSC;
535 if (norm->id & V4L2_STD_SECAM)
536 c.norm = VIDEO_MODE_SECAM;
537 saa7134_i2c_call_clients(dev,VIDIOCSCHAN,&c);
538 }
539#endif
540}
541
542static void video_mux(struct saa7134_dev *dev, int input)
543{
544 dprintk("video input = %d [%s]\n",input,card_in(dev,input).name);
545 dev->ctl_input = input;
546 set_tvnorm(dev,dev->tvnorm);
547 saa7134_tvaudio_setinput(dev,&card_in(dev,input));
548}
549
550static void set_h_prescale(struct saa7134_dev *dev, int task, int prescale)
551{
552 static const struct {
553 int xpsc;
554 int xacl;
555 int xc2_1;
556 int xdcg;
557 int vpfy;
558 } vals[] = {
559 /* XPSC XACL XC2_1 XDCG VPFY */
560 { 1, 0, 0, 0, 0 },
561 { 2, 2, 1, 2, 2 },
562 { 3, 4, 1, 3, 2 },
563 { 4, 8, 1, 4, 2 },
564 { 5, 8, 1, 4, 2 },
565 { 6, 8, 1, 4, 3 },
566 { 7, 8, 1, 4, 3 },
567 { 8, 15, 0, 4, 3 },
568 { 9, 15, 0, 4, 3 },
569 { 10, 16, 1, 5, 3 },
570 };
571 static const int count = ARRAY_SIZE(vals);
572 int i;
573
574 for (i = 0; i < count; i++)
575 if (vals[i].xpsc == prescale)
576 break;
577 if (i == count)
578 return;
579
580 saa_writeb(SAA7134_H_PRESCALE(task), vals[i].xpsc);
581 saa_writeb(SAA7134_ACC_LENGTH(task), vals[i].xacl);
582 saa_writeb(SAA7134_LEVEL_CTRL(task),
583 (vals[i].xc2_1 << 3) | (vals[i].xdcg));
584 saa_andorb(SAA7134_FIR_PREFILTER_CTRL(task), 0x0f,
585 (vals[i].vpfy << 2) | vals[i].vpfy);
586}
587
588static void set_v_scale(struct saa7134_dev *dev, int task, int yscale)
589{
590 int val,mirror;
591
592 saa_writeb(SAA7134_V_SCALE_RATIO1(task), yscale & 0xff);
593 saa_writeb(SAA7134_V_SCALE_RATIO2(task), yscale >> 8);
594
595 mirror = (dev->ctl_mirror) ? 0x02 : 0x00;
596 if (yscale < 2048) {
597 /* LPI */
598 dprintk("yscale LPI yscale=%d\n",yscale);
599 saa_writeb(SAA7134_V_FILTER(task), 0x00 | mirror);
600 saa_writeb(SAA7134_LUMA_CONTRAST(task), 0x40);
601 saa_writeb(SAA7134_CHROMA_SATURATION(task), 0x40);
602 } else {
603 /* ACM */
604 val = 0x40 * 1024 / yscale;
605 dprintk("yscale ACM yscale=%d val=0x%x\n",yscale,val);
606 saa_writeb(SAA7134_V_FILTER(task), 0x01 | mirror);
607 saa_writeb(SAA7134_LUMA_CONTRAST(task), val);
608 saa_writeb(SAA7134_CHROMA_SATURATION(task), val);
609 }
610 saa_writeb(SAA7134_LUMA_BRIGHT(task), 0x80);
611}
612
613static void set_size(struct saa7134_dev *dev, int task,
614 int width, int height, int interlace)
615{
616 int prescale,xscale,yscale,y_even,y_odd;
617 int h_start, h_stop, v_start, v_stop;
618 int div = interlace ? 2 : 1;
619
620 /* setup video scaler */
621 h_start = dev->crop_current.left;
622 v_start = dev->crop_current.top/2;
623 h_stop = (dev->crop_current.left + dev->crop_current.width -1);
624 v_stop = (dev->crop_current.top + dev->crop_current.height -1)/2;
625
626 saa_writeb(SAA7134_VIDEO_H_START1(task), h_start & 0xff);
627 saa_writeb(SAA7134_VIDEO_H_START2(task), h_start >> 8);
628 saa_writeb(SAA7134_VIDEO_H_STOP1(task), h_stop & 0xff);
629 saa_writeb(SAA7134_VIDEO_H_STOP2(task), h_stop >> 8);
630 saa_writeb(SAA7134_VIDEO_V_START1(task), v_start & 0xff);
631 saa_writeb(SAA7134_VIDEO_V_START2(task), v_start >> 8);
632 saa_writeb(SAA7134_VIDEO_V_STOP1(task), v_stop & 0xff);
633 saa_writeb(SAA7134_VIDEO_V_STOP2(task), v_stop >> 8);
634
635 prescale = dev->crop_current.width / width;
636 if (0 == prescale)
637 prescale = 1;
638 xscale = 1024 * dev->crop_current.width / prescale / width;
639 yscale = 512 * div * dev->crop_current.height / height;
640 dprintk("prescale=%d xscale=%d yscale=%d\n",prescale,xscale,yscale);
641 set_h_prescale(dev,task,prescale);
642 saa_writeb(SAA7134_H_SCALE_INC1(task), xscale & 0xff);
643 saa_writeb(SAA7134_H_SCALE_INC2(task), xscale >> 8);
644 set_v_scale(dev,task,yscale);
645
646 saa_writeb(SAA7134_VIDEO_PIXELS1(task), width & 0xff);
647 saa_writeb(SAA7134_VIDEO_PIXELS2(task), width >> 8);
648 saa_writeb(SAA7134_VIDEO_LINES1(task), height/div & 0xff);
649 saa_writeb(SAA7134_VIDEO_LINES2(task), height/div >> 8);
650
651 /* deinterlace y offsets */
652 y_odd = dev->ctl_y_odd;
653 y_even = dev->ctl_y_even;
654 saa_writeb(SAA7134_V_PHASE_OFFSET0(task), y_odd);
655 saa_writeb(SAA7134_V_PHASE_OFFSET1(task), y_even);
656 saa_writeb(SAA7134_V_PHASE_OFFSET2(task), y_odd);
657 saa_writeb(SAA7134_V_PHASE_OFFSET3(task), y_even);
658}
659
660/* ------------------------------------------------------------------ */
661
662struct cliplist {
663 __u16 position;
664 __u8 enable;
665 __u8 disable;
666};
667
668static void sort_cliplist(struct cliplist *cl, int entries)
669{
670 struct cliplist swap;
671 int i,j,n;
672
673 for (i = entries-2; i >= 0; i--) {
674 for (n = 0, j = 0; j <= i; j++) {
675 if (cl[j].position > cl[j+1].position) {
676 swap = cl[j];
677 cl[j] = cl[j+1];
678 cl[j+1] = swap;
679 n++;
680 }
681 }
682 if (0 == n)
683 break;
684 }
685}
686
687static void set_cliplist(struct saa7134_dev *dev, int reg,
688 struct cliplist *cl, int entries, char *name)
689{
690 __u8 winbits = 0;
691 int i;
692
693 for (i = 0; i < entries; i++) {
694 winbits |= cl[i].enable;
695 winbits &= ~cl[i].disable;
696 if (i < 15 && cl[i].position == cl[i+1].position)
697 continue;
698 saa_writeb(reg + 0, winbits);
699 saa_writeb(reg + 2, cl[i].position & 0xff);
700 saa_writeb(reg + 3, cl[i].position >> 8);
701 dprintk("clip: %s winbits=%02x pos=%d\n",
702 name,winbits,cl[i].position);
703 reg += 8;
704 }
705 for (; reg < 0x400; reg += 8) {
706 saa_writeb(reg+ 0, 0);
707 saa_writeb(reg + 1, 0);
708 saa_writeb(reg + 2, 0);
709 saa_writeb(reg + 3, 0);
710 }
711}
712
713static int clip_range(int val)
714{
715 if (val < 0)
716 val = 0;
717 return val;
718}
719
720static int setup_clipping(struct saa7134_dev *dev, struct v4l2_clip *clips,
721 int nclips, int interlace)
722{
723 struct cliplist col[16], row[16];
724 int cols, rows, i;
725 int div = interlace ? 2 : 1;
726
727 memset(col,0,sizeof(col)); cols = 0;
728 memset(row,0,sizeof(row)); rows = 0;
729 for (i = 0; i < nclips && i < 8; i++) {
730 col[cols].position = clip_range(clips[i].c.left);
731 col[cols].enable = (1 << i);
732 cols++;
733 col[cols].position = clip_range(clips[i].c.left+clips[i].c.width);
734 col[cols].disable = (1 << i);
735 cols++;
736 row[rows].position = clip_range(clips[i].c.top / div);
737 row[rows].enable = (1 << i);
738 rows++;
739 row[rows].position = clip_range((clips[i].c.top + clips[i].c.height)
740 / div);
741 row[rows].disable = (1 << i);
742 rows++;
743 }
744 sort_cliplist(col,cols);
745 sort_cliplist(row,rows);
746 set_cliplist(dev,0x380,col,cols,"cols");
747 set_cliplist(dev,0x384,row,rows,"rows");
748 return 0;
749}
750
751static int verify_preview(struct saa7134_dev *dev, struct v4l2_window *win)
752{
753 enum v4l2_field field;
754 int maxw, maxh;
755
756 if (NULL == dev->ovbuf.base)
757 return -EINVAL;
758 if (NULL == dev->ovfmt)
759 return -EINVAL;
760 if (win->w.width < 48 || win->w.height < 32)
761 return -EINVAL;
762 if (win->clipcount > 2048)
763 return -EINVAL;
764
765 field = win->field;
766 maxw = dev->crop_current.width;
767 maxh = dev->crop_current.height;
768
769 if (V4L2_FIELD_ANY == field) {
770 field = (win->w.height > maxh/2)
771 ? V4L2_FIELD_INTERLACED
772 : V4L2_FIELD_TOP;
773 }
774 switch (field) {
775 case V4L2_FIELD_TOP:
776 case V4L2_FIELD_BOTTOM:
777 maxh = maxh / 2;
778 break;
779 case V4L2_FIELD_INTERLACED:
780 break;
781 default:
782 return -EINVAL;
783 }
784
785 win->field = field;
786 if (win->w.width > maxw)
787 win->w.width = maxw;
788 if (win->w.height > maxh)
789 win->w.height = maxh;
790 return 0;
791}
792
793static int start_preview(struct saa7134_dev *dev, struct saa7134_fh *fh)
794{
795 unsigned long base,control,bpl;
796 int err;
797
798 err = verify_preview(dev,&fh->win);
799 if (0 != err)
800 return err;
801
802 dev->ovfield = fh->win.field;
803 dprintk("start_preview %dx%d+%d+%d %s field=%s\n",
804 fh->win.w.width,fh->win.w.height,
805 fh->win.w.left,fh->win.w.top,
806 dev->ovfmt->name,v4l2_field_names[dev->ovfield]);
807
808 /* setup window + clipping */
809 set_size(dev,TASK_B,fh->win.w.width,fh->win.w.height,
810 V4L2_FIELD_HAS_BOTH(dev->ovfield));
811 setup_clipping(dev,fh->clips,fh->nclips,
812 V4L2_FIELD_HAS_BOTH(dev->ovfield));
813 if (dev->ovfmt->yuv)
814 saa_andorb(SAA7134_DATA_PATH(TASK_B), 0x3f, 0x03);
815 else
816 saa_andorb(SAA7134_DATA_PATH(TASK_B), 0x3f, 0x01);
817 saa_writeb(SAA7134_OFMT_VIDEO_B, dev->ovfmt->pm | 0x20);
818
819 /* dma: setup channel 1 (= Video Task B) */
820 base = (unsigned long)dev->ovbuf.base;
821 base += dev->ovbuf.fmt.bytesperline * fh->win.w.top;
822 base += dev->ovfmt->depth/8 * fh->win.w.left;
823 bpl = dev->ovbuf.fmt.bytesperline;
824 control = SAA7134_RS_CONTROL_BURST_16;
825 if (dev->ovfmt->bswap)
826 control |= SAA7134_RS_CONTROL_BSWAP;
827 if (dev->ovfmt->wswap)
828 control |= SAA7134_RS_CONTROL_WSWAP;
829 if (V4L2_FIELD_HAS_BOTH(dev->ovfield)) {
830 saa_writel(SAA7134_RS_BA1(1),base);
831 saa_writel(SAA7134_RS_BA2(1),base+bpl);
832 saa_writel(SAA7134_RS_PITCH(1),bpl*2);
833 saa_writel(SAA7134_RS_CONTROL(1),control);
834 } else {
835 saa_writel(SAA7134_RS_BA1(1),base);
836 saa_writel(SAA7134_RS_BA2(1),base);
837 saa_writel(SAA7134_RS_PITCH(1),bpl);
838 saa_writel(SAA7134_RS_CONTROL(1),control);
839 }
840
841 /* start dma */
842 dev->ovenable = 1;
843 saa7134_set_dmabits(dev);
844
845 return 0;
846}
847
848static int stop_preview(struct saa7134_dev *dev, struct saa7134_fh *fh)
849{
850 dev->ovenable = 0;
851 saa7134_set_dmabits(dev);
852 return 0;
853}
854
855/* ------------------------------------------------------------------ */
856
857static int buffer_activate(struct saa7134_dev *dev,
858 struct saa7134_buf *buf,
859 struct saa7134_buf *next)
860{
861 unsigned long base,control,bpl;
862 unsigned long bpl_uv,lines_uv,base2,base3,tmp; /* planar */
863
864 dprintk("buffer_activate buf=%p\n",buf);
865 buf->vb.state = STATE_ACTIVE;
866 buf->top_seen = 0;
867
868 set_size(dev,TASK_A,buf->vb.width,buf->vb.height,
869 V4L2_FIELD_HAS_BOTH(buf->vb.field));
870 if (buf->fmt->yuv)
871 saa_andorb(SAA7134_DATA_PATH(TASK_A), 0x3f, 0x03);
872 else
873 saa_andorb(SAA7134_DATA_PATH(TASK_A), 0x3f, 0x01);
874 saa_writeb(SAA7134_OFMT_VIDEO_A, buf->fmt->pm);
875
876 /* DMA: setup channel 0 (= Video Task A0) */
877 base = saa7134_buffer_base(buf);
878 if (buf->fmt->planar)
879 bpl = buf->vb.width;
880 else
881 bpl = (buf->vb.width * buf->fmt->depth) / 8;
882 control = SAA7134_RS_CONTROL_BURST_16 |
883 SAA7134_RS_CONTROL_ME |
884 (buf->pt->dma >> 12);
885 if (buf->fmt->bswap)
886 control |= SAA7134_RS_CONTROL_BSWAP;
887 if (buf->fmt->wswap)
888 control |= SAA7134_RS_CONTROL_WSWAP;
889 if (V4L2_FIELD_HAS_BOTH(buf->vb.field)) {
890 /* interlaced */
891 saa_writel(SAA7134_RS_BA1(0),base);
892 saa_writel(SAA7134_RS_BA2(0),base+bpl);
893 saa_writel(SAA7134_RS_PITCH(0),bpl*2);
894 } else {
895 /* non-interlaced */
896 saa_writel(SAA7134_RS_BA1(0),base);
897 saa_writel(SAA7134_RS_BA2(0),base);
898 saa_writel(SAA7134_RS_PITCH(0),bpl);
899 }
900 saa_writel(SAA7134_RS_CONTROL(0),control);
901
902 if (buf->fmt->planar) {
903 /* DMA: setup channel 4+5 (= planar task A) */
904 bpl_uv = bpl >> buf->fmt->hshift;
905 lines_uv = buf->vb.height >> buf->fmt->vshift;
906 base2 = base + bpl * buf->vb.height;
907 base3 = base2 + bpl_uv * lines_uv;
908 if (buf->fmt->uvswap)
909 tmp = base2, base2 = base3, base3 = tmp;
910 dprintk("uv: bpl=%ld lines=%ld base2/3=%ld/%ld\n",
911 bpl_uv,lines_uv,base2,base3);
912 if (V4L2_FIELD_HAS_BOTH(buf->vb.field)) {
913 /* interlaced */
914 saa_writel(SAA7134_RS_BA1(4),base2);
915 saa_writel(SAA7134_RS_BA2(4),base2+bpl_uv);
916 saa_writel(SAA7134_RS_PITCH(4),bpl_uv*2);
917 saa_writel(SAA7134_RS_BA1(5),base3);
918 saa_writel(SAA7134_RS_BA2(5),base3+bpl_uv);
919 saa_writel(SAA7134_RS_PITCH(5),bpl_uv*2);
920 } else {
921 /* non-interlaced */
922 saa_writel(SAA7134_RS_BA1(4),base2);
923 saa_writel(SAA7134_RS_BA2(4),base2);
924 saa_writel(SAA7134_RS_PITCH(4),bpl_uv);
925 saa_writel(SAA7134_RS_BA1(5),base3);
926 saa_writel(SAA7134_RS_BA2(5),base3);
927 saa_writel(SAA7134_RS_PITCH(5),bpl_uv);
928 }
929 saa_writel(SAA7134_RS_CONTROL(4),control);
930 saa_writel(SAA7134_RS_CONTROL(5),control);
931 }
932
933 /* start DMA */
934 saa7134_set_dmabits(dev);
935 mod_timer(&dev->video_q.timeout, jiffies+BUFFER_TIMEOUT);
936 return 0;
937}
938
939static int buffer_prepare(struct videobuf_queue *q,
940 struct videobuf_buffer *vb,
941 enum v4l2_field field)
942{
943 struct saa7134_fh *fh = q->priv_data;
944 struct saa7134_dev *dev = fh->dev;
945 struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb);
946 unsigned int size;
947 int err;
948
949 /* sanity checks */
950 if (NULL == fh->fmt)
951 return -EINVAL;
952 if (fh->width < 48 ||
953 fh->height < 32 ||
954 fh->width/4 > dev->crop_current.width ||
955 fh->height/4 > dev->crop_current.height ||
956 fh->width > dev->crop_bounds.width ||
957 fh->height > dev->crop_bounds.height)
958 return -EINVAL;
959 size = (fh->width * fh->height * fh->fmt->depth) >> 3;
960 if (0 != buf->vb.baddr && buf->vb.bsize < size)
961 return -EINVAL;
962
963 dprintk("buffer_prepare [%d,size=%dx%d,bytes=%d,fields=%s,%s]\n",
964 vb->i,fh->width,fh->height,size,v4l2_field_names[field],
965 fh->fmt->name);
966 if (buf->vb.width != fh->width ||
967 buf->vb.height != fh->height ||
968 buf->vb.size != size ||
969 buf->vb.field != field ||
970 buf->fmt != fh->fmt) {
971 saa7134_dma_free(dev,buf);
972 }
973
974 if (STATE_NEEDS_INIT == buf->vb.state) {
975 buf->vb.width = fh->width;
976 buf->vb.height = fh->height;
977 buf->vb.size = size;
978 buf->vb.field = field;
979 buf->fmt = fh->fmt;
980 buf->pt = &fh->pt_cap;
981
982 err = videobuf_iolock(dev->pci,&buf->vb,&dev->ovbuf);
983 if (err)
984 goto oops;
985 err = saa7134_pgtable_build(dev->pci,buf->pt,
986 buf->vb.dma.sglist,
987 buf->vb.dma.sglen,
988 saa7134_buffer_startpage(buf));
989 if (err)
990 goto oops;
991 }
992 buf->vb.state = STATE_PREPARED;
993 buf->activate = buffer_activate;
994 return 0;
995
996 oops:
997 saa7134_dma_free(dev,buf);
998 return err;
999}
1000
1001static int
1002buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
1003{
1004 struct saa7134_fh *fh = q->priv_data;
1005
1006 *size = fh->fmt->depth * fh->width * fh->height >> 3;
1007 if (0 == *count)
1008 *count = gbuffers;
1009 *count = saa7134_buffer_count(*size,*count);
1010 return 0;
1011}
1012
1013static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
1014{
1015 struct saa7134_fh *fh = q->priv_data;
1016 struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb);
1017
1018 saa7134_buffer_queue(fh->dev,&fh->dev->video_q,buf);
1019}
1020
1021static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
1022{
1023 struct saa7134_fh *fh = q->priv_data;
1024 struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb);
1025
1026 saa7134_dma_free(fh->dev,buf);
1027}
1028
1029static struct videobuf_queue_ops video_qops = {
1030 .buf_setup = buffer_setup,
1031 .buf_prepare = buffer_prepare,
1032 .buf_queue = buffer_queue,
1033 .buf_release = buffer_release,
1034};
1035
1036/* ------------------------------------------------------------------ */
1037
1038static int get_control(struct saa7134_dev *dev, struct v4l2_control *c)
1039{
1040 const struct v4l2_queryctrl* ctrl;
1041
1042 ctrl = ctrl_by_id(c->id);
1043 if (NULL == ctrl)
1044 return -EINVAL;
1045 switch (c->id) {
1046 case V4L2_CID_BRIGHTNESS:
1047 c->value = dev->ctl_bright;
1048 break;
1049 case V4L2_CID_HUE:
1050 c->value = dev->ctl_hue;
1051 break;
1052 case V4L2_CID_CONTRAST:
1053 c->value = dev->ctl_contrast;
1054 break;
1055 case V4L2_CID_SATURATION:
1056 c->value = dev->ctl_saturation;
1057 break;
1058 case V4L2_CID_AUDIO_MUTE:
1059 c->value = dev->ctl_mute;
1060 break;
1061 case V4L2_CID_AUDIO_VOLUME:
1062 c->value = dev->ctl_volume;
1063 break;
1064 case V4L2_CID_PRIVATE_INVERT:
1065 c->value = dev->ctl_invert;
1066 break;
1067 case V4L2_CID_VFLIP:
1068 c->value = dev->ctl_mirror;
1069 break;
1070 case V4L2_CID_PRIVATE_Y_EVEN:
1071 c->value = dev->ctl_y_even;
1072 break;
1073 case V4L2_CID_PRIVATE_Y_ODD:
1074 c->value = dev->ctl_y_odd;
1075 break;
1076 case V4L2_CID_PRIVATE_AUTOMUTE:
1077 c->value = dev->ctl_automute;
1078 break;
1079 default:
1080 return -EINVAL;
1081 }
1082 return 0;
1083}
1084
1085static int set_control(struct saa7134_dev *dev, struct saa7134_fh *fh,
1086 struct v4l2_control *c)
1087{
1088 const struct v4l2_queryctrl* ctrl;
1089 unsigned long flags;
1090 int restart_overlay = 0;
1091
1092 ctrl = ctrl_by_id(c->id);
1093 if (NULL == ctrl)
1094 return -EINVAL;
1095 dprintk("set_control name=%s val=%d\n",ctrl->name,c->value);
1096 switch (ctrl->type) {
1097 case V4L2_CTRL_TYPE_BOOLEAN:
1098 case V4L2_CTRL_TYPE_MENU:
1099 case V4L2_CTRL_TYPE_INTEGER:
1100 if (c->value < ctrl->minimum)
1101 c->value = ctrl->minimum;
1102 if (c->value > ctrl->maximum)
1103 c->value = ctrl->maximum;
1104 break;
1105 default:
1106 /* nothing */;
1107 };
1108 switch (c->id) {
1109 case V4L2_CID_BRIGHTNESS:
1110 dev->ctl_bright = c->value;
1111 saa_writeb(SAA7134_DEC_LUMA_BRIGHT, dev->ctl_bright);
1112 break;
1113 case V4L2_CID_HUE:
1114 dev->ctl_hue = c->value;
1115 saa_writeb(SAA7134_DEC_CHROMA_HUE, dev->ctl_hue);
1116 break;
1117 case V4L2_CID_CONTRAST:
1118 dev->ctl_contrast = c->value;
1119 saa_writeb(SAA7134_DEC_LUMA_CONTRAST,
1120 dev->ctl_invert ? -dev->ctl_contrast : dev->ctl_contrast);
1121 break;
1122 case V4L2_CID_SATURATION:
1123 dev->ctl_saturation = c->value;
1124 saa_writeb(SAA7134_DEC_CHROMA_SATURATION,
1125 dev->ctl_invert ? -dev->ctl_saturation : dev->ctl_saturation);
1126 break;
1127 case V4L2_CID_AUDIO_MUTE:
1128 dev->ctl_mute = c->value;
1129 saa7134_tvaudio_setmute(dev);
1130 break;
1131 case V4L2_CID_AUDIO_VOLUME:
1132 dev->ctl_volume = c->value;
1133 saa7134_tvaudio_setvolume(dev,dev->ctl_volume);
1134 break;
1135 case V4L2_CID_PRIVATE_INVERT:
1136 dev->ctl_invert = c->value;
1137 saa_writeb(SAA7134_DEC_LUMA_CONTRAST,
1138 dev->ctl_invert ? -dev->ctl_contrast : dev->ctl_contrast);
1139 saa_writeb(SAA7134_DEC_CHROMA_SATURATION,
1140 dev->ctl_invert ? -dev->ctl_saturation : dev->ctl_saturation);
1141 break;
1142 case V4L2_CID_VFLIP:
1143 dev->ctl_mirror = c->value;
1144 restart_overlay = 1;
1145 break;
1146 case V4L2_CID_PRIVATE_Y_EVEN:
1147 dev->ctl_y_even = c->value;
1148 restart_overlay = 1;
1149 break;
1150 case V4L2_CID_PRIVATE_Y_ODD:
1151 dev->ctl_y_odd = c->value;
1152 restart_overlay = 1;
1153 break;
1154 case V4L2_CID_PRIVATE_AUTOMUTE:
1155 dev->ctl_automute = c->value;
1156 if (dev->tda9887_conf) {
1157 if (dev->ctl_automute)
1158 dev->tda9887_conf |= TDA9887_AUTOMUTE;
1159 else
1160 dev->tda9887_conf &= ~TDA9887_AUTOMUTE;
1161 saa7134_i2c_call_clients(dev, TDA9887_SET_CONFIG,
1162 &dev->tda9887_conf);
1163 }
1164 break;
1165 default:
1166 return -EINVAL;
1167 }
1168 if (restart_overlay && fh && res_check(fh, RESOURCE_OVERLAY)) {
1169 spin_lock_irqsave(&dev->slock,flags);
1170 stop_preview(dev,fh);
1171 start_preview(dev,fh);
1172 spin_unlock_irqrestore(&dev->slock,flags);
1173 }
1174 return 0;
1175}
1176
1177/* ------------------------------------------------------------------ */
1178
1179static struct videobuf_queue* saa7134_queue(struct saa7134_fh *fh)
1180{
1181 struct videobuf_queue* q = NULL;
1182
1183 switch (fh->type) {
1184 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1185 q = &fh->cap;
1186 break;
1187 case V4L2_BUF_TYPE_VBI_CAPTURE:
1188 q = &fh->vbi;
1189 break;
1190 default:
1191 BUG();
1192 }
1193 return q;
1194}
1195
1196static int saa7134_resource(struct saa7134_fh *fh)
1197{
1198 int res = 0;
1199
1200 switch (fh->type) {
1201 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1202 res = RESOURCE_VIDEO;
1203 break;
1204 case V4L2_BUF_TYPE_VBI_CAPTURE:
1205 res = RESOURCE_VBI;
1206 break;
1207 default:
1208 BUG();
1209 }
1210 return res;
1211}
1212
1213static int video_open(struct inode *inode, struct file *file)
1214{
1215 int minor = iminor(inode);
1216 struct saa7134_dev *h,*dev = NULL;
1217 struct saa7134_fh *fh;
1218 struct list_head *list;
1219 enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1220 int radio = 0;
1221
1222 list_for_each(list,&saa7134_devlist) {
1223 h = list_entry(list, struct saa7134_dev, devlist);
1224 if (h->video_dev && (h->video_dev->minor == minor))
1225 dev = h;
1226 if (h->radio_dev && (h->radio_dev->minor == minor)) {
1227 radio = 1;
1228 dev = h;
1229 }
1230 if (h->vbi_dev && (h->vbi_dev->minor == minor)) {
1231 type = V4L2_BUF_TYPE_VBI_CAPTURE;
1232 dev = h;
1233 }
1234 }
1235 if (NULL == dev)
1236 return -ENODEV;
1237
1238 dprintk("open minor=%d radio=%d type=%s\n",minor,radio,
1239 v4l2_type_names[type]);
1240
1241 /* allocate + initialize per filehandle data */
1242 fh = kmalloc(sizeof(*fh),GFP_KERNEL);
1243 if (NULL == fh)
1244 return -ENOMEM;
1245 memset(fh,0,sizeof(*fh));
1246 file->private_data = fh;
1247 fh->dev = dev;
1248 fh->radio = radio;
1249 fh->type = type;
1250 fh->fmt = format_by_fourcc(V4L2_PIX_FMT_BGR24);
1251 fh->width = 720;
1252 fh->height = 576;
1253 v4l2_prio_open(&dev->prio,&fh->prio);
1254
1255 videobuf_queue_init(&fh->cap, &video_qops,
1256 dev->pci, &dev->slock,
1257 V4L2_BUF_TYPE_VIDEO_CAPTURE,
1258 V4L2_FIELD_INTERLACED,
1259 sizeof(struct saa7134_buf),
1260 fh);
1261 videobuf_queue_init(&fh->vbi, &saa7134_vbi_qops,
1262 dev->pci, &dev->slock,
1263 V4L2_BUF_TYPE_VBI_CAPTURE,
1264 V4L2_FIELD_SEQ_TB,
1265 sizeof(struct saa7134_buf),
1266 fh);
1267 saa7134_pgtable_alloc(dev->pci,&fh->pt_cap);
1268 saa7134_pgtable_alloc(dev->pci,&fh->pt_vbi);
1269
1270 if (fh->radio) {
1271 /* switch to radio mode */
1272 saa7134_tvaudio_setinput(dev,&card(dev).radio);
1273 saa7134_i2c_call_clients(dev,AUDC_SET_RADIO,NULL);
1274 } else {
1275 /* switch to video/vbi mode */
1276 video_mux(dev,dev->ctl_input);
1277 }
1278 return 0;
1279}
1280
1281static ssize_t
1282video_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
1283{
1284 struct saa7134_fh *fh = file->private_data;
1285
1286 switch (fh->type) {
1287 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1288 if (res_locked(fh->dev,RESOURCE_VIDEO))
1289 return -EBUSY;
1290 return videobuf_read_one(saa7134_queue(fh),
1291 data, count, ppos,
1292 file->f_flags & O_NONBLOCK);
1293 case V4L2_BUF_TYPE_VBI_CAPTURE:
1294 if (!res_get(fh->dev,fh,RESOURCE_VBI))
1295 return -EBUSY;
1296 return videobuf_read_stream(saa7134_queue(fh),
1297 data, count, ppos, 1,
1298 file->f_flags & O_NONBLOCK);
1299 break;
1300 default:
1301 BUG();
1302 return 0;
1303 }
1304}
1305
1306static unsigned int
1307video_poll(struct file *file, struct poll_table_struct *wait)
1308{
1309 struct saa7134_fh *fh = file->private_data;
1310 struct videobuf_buffer *buf = NULL;
1311
1312 if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type)
1313 return videobuf_poll_stream(file, &fh->vbi, wait);
1314
1315 if (res_check(fh,RESOURCE_VIDEO)) {
1316 if (!list_empty(&fh->cap.stream))
1317 buf = list_entry(fh->cap.stream.next, struct videobuf_buffer, stream);
1318 } else {
1319 down(&fh->cap.lock);
1320 if (UNSET == fh->cap.read_off) {
1321 /* need to capture a new frame */
1322 if (res_locked(fh->dev,RESOURCE_VIDEO)) {
1323 up(&fh->cap.lock);
1324 return POLLERR;
1325 }
1326 if (0 != fh->cap.ops->buf_prepare(&fh->cap,fh->cap.read_buf,fh->cap.field)) {
1327 up(&fh->cap.lock);
1328 return POLLERR;
1329 }
1330 fh->cap.ops->buf_queue(&fh->cap,fh->cap.read_buf);
1331 fh->cap.read_off = 0;
1332 }
1333 up(&fh->cap.lock);
1334 buf = fh->cap.read_buf;
1335 }
1336
1337 if (!buf)
1338 return POLLERR;
1339
1340 poll_wait(file, &buf->done, wait);
1341 if (buf->state == STATE_DONE ||
1342 buf->state == STATE_ERROR)
1343 return POLLIN|POLLRDNORM;
1344 return 0;
1345}
1346
1347static int video_release(struct inode *inode, struct file *file)
1348{
1349 struct saa7134_fh *fh = file->private_data;
1350 struct saa7134_dev *dev = fh->dev;
1351 unsigned long flags;
1352
1353 /* turn off overlay */
1354 if (res_check(fh, RESOURCE_OVERLAY)) {
1355 spin_lock_irqsave(&dev->slock,flags);
1356 stop_preview(dev,fh);
1357 spin_unlock_irqrestore(&dev->slock,flags);
1358 res_free(dev,fh,RESOURCE_OVERLAY);
1359 }
1360
1361 /* stop video capture */
1362 if (res_check(fh, RESOURCE_VIDEO)) {
1363 videobuf_streamoff(&fh->cap);
1364 res_free(dev,fh,RESOURCE_VIDEO);
1365 }
1366 if (fh->cap.read_buf) {
1367 buffer_release(&fh->cap,fh->cap.read_buf);
1368 kfree(fh->cap.read_buf);
1369 }
1370
1371 /* stop vbi capture */
1372 if (res_check(fh, RESOURCE_VBI)) {
1373 if (fh->vbi.streaming)
1374 videobuf_streamoff(&fh->vbi);
1375 if (fh->vbi.reading)
1376 videobuf_read_stop(&fh->vbi);
1377 res_free(dev,fh,RESOURCE_VBI);
1378 }
1379
1380 /* free stuff */
1381 videobuf_mmap_free(&fh->cap);
1382 videobuf_mmap_free(&fh->vbi);
1383 saa7134_pgtable_free(dev->pci,&fh->pt_cap);
1384 saa7134_pgtable_free(dev->pci,&fh->pt_vbi);
1385
1386 v4l2_prio_close(&dev->prio,&fh->prio);
1387 file->private_data = NULL;
1388 kfree(fh);
1389 return 0;
1390}
1391
1392static int
1393video_mmap(struct file *file, struct vm_area_struct * vma)
1394{
1395 struct saa7134_fh *fh = file->private_data;
1396
1397 return videobuf_mmap_mapper(saa7134_queue(fh), vma);
1398}
1399
1400/* ------------------------------------------------------------------ */
1401
1402static void saa7134_vbi_fmt(struct saa7134_dev *dev, struct v4l2_format *f)
1403{
1404 struct saa7134_tvnorm *norm = dev->tvnorm;
1405
1406 f->fmt.vbi.sampling_rate = 6750000 * 4;
1407 f->fmt.vbi.samples_per_line = 2048 /* VBI_LINE_LENGTH */;
1408 f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
1409 f->fmt.vbi.offset = 64 * 4;
1410 f->fmt.vbi.start[0] = norm->vbi_v_start;
1411 f->fmt.vbi.count[0] = norm->vbi_v_stop - norm->vbi_v_start +1;
1412 f->fmt.vbi.start[1] = norm->video_v_stop + norm->vbi_v_start +1;
1413 f->fmt.vbi.count[1] = f->fmt.vbi.count[0];
1414 f->fmt.vbi.flags = 0; /* VBI_UNSYNC VBI_INTERLACED */
1415
1416#if 0
1417 if (V4L2_STD_PAL == norm->id) {
1418 /* FIXME */
1419 f->fmt.vbi.start[0] += 3;
1420 f->fmt.vbi.start[1] += 3*2;
1421 }
1422#endif
1423}
1424
1425static int saa7134_g_fmt(struct saa7134_dev *dev, struct saa7134_fh *fh,
1426 struct v4l2_format *f)
1427{
1428 switch (f->type) {
1429 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1430 memset(&f->fmt.pix,0,sizeof(f->fmt.pix));
1431 f->fmt.pix.width = fh->width;
1432 f->fmt.pix.height = fh->height;
1433 f->fmt.pix.field = fh->cap.field;
1434 f->fmt.pix.pixelformat = fh->fmt->fourcc;
1435 f->fmt.pix.bytesperline =
1436 (f->fmt.pix.width * fh->fmt->depth) >> 3;
1437 f->fmt.pix.sizeimage =
1438 f->fmt.pix.height * f->fmt.pix.bytesperline;
1439 return 0;
1440 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
1441 f->fmt.win = fh->win;
1442 return 0;
1443 case V4L2_BUF_TYPE_VBI_CAPTURE:
1444 saa7134_vbi_fmt(dev,f);
1445 return 0;
1446 default:
1447 return -EINVAL;
1448 }
1449}
1450
1451static int saa7134_try_fmt(struct saa7134_dev *dev, struct saa7134_fh *fh,
1452 struct v4l2_format *f)
1453{
1454 int err;
1455
1456 switch (f->type) {
1457 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1458 {
1459 struct saa7134_format *fmt;
1460 enum v4l2_field field;
1461 unsigned int maxw, maxh;
1462
1463 fmt = format_by_fourcc(f->fmt.pix.pixelformat);
1464 if (NULL == fmt)
1465 return -EINVAL;
1466
1467 field = f->fmt.pix.field;
1468 maxw = min(dev->crop_current.width*4, dev->crop_bounds.width);
1469 maxh = min(dev->crop_current.height*4, dev->crop_bounds.height);
1470
1471 if (V4L2_FIELD_ANY == field) {
1472 field = (f->fmt.pix.height > maxh/2)
1473 ? V4L2_FIELD_INTERLACED
1474 : V4L2_FIELD_BOTTOM;
1475 }
1476 switch (field) {
1477 case V4L2_FIELD_TOP:
1478 case V4L2_FIELD_BOTTOM:
1479 maxh = maxh / 2;
1480 break;
1481 case V4L2_FIELD_INTERLACED:
1482 break;
1483 default:
1484 return -EINVAL;
1485 }
1486
1487 f->fmt.pix.field = field;
1488 if (f->fmt.pix.width < 48)
1489 f->fmt.pix.width = 48;
1490 if (f->fmt.pix.height < 32)
1491 f->fmt.pix.height = 32;
1492 if (f->fmt.pix.width > maxw)
1493 f->fmt.pix.width = maxw;
1494 if (f->fmt.pix.height > maxh)
1495 f->fmt.pix.height = maxh;
1496 f->fmt.pix.width &= ~0x03;
1497 f->fmt.pix.bytesperline =
1498 (f->fmt.pix.width * fmt->depth) >> 3;
1499 f->fmt.pix.sizeimage =
1500 f->fmt.pix.height * f->fmt.pix.bytesperline;
1501
1502 return 0;
1503 }
1504 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
1505 err = verify_preview(dev,&f->fmt.win);
1506 if (0 != err)
1507 return err;
1508 return 0;
1509 case V4L2_BUF_TYPE_VBI_CAPTURE:
1510 saa7134_vbi_fmt(dev,f);
1511 return 0;
1512 default:
1513 return -EINVAL;
1514 }
1515}
1516
1517static int saa7134_s_fmt(struct saa7134_dev *dev, struct saa7134_fh *fh,
1518 struct v4l2_format *f)
1519{
1520 unsigned long flags;
1521 int err;
1522
1523 switch (f->type) {
1524 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1525 err = saa7134_try_fmt(dev,fh,f);
1526 if (0 != err)
1527 return err;
1528
1529 fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
1530 fh->width = f->fmt.pix.width;
1531 fh->height = f->fmt.pix.height;
1532 fh->cap.field = f->fmt.pix.field;
1533 return 0;
1534 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
1535 err = verify_preview(dev,&f->fmt.win);
1536 if (0 != err)
1537 return err;
1538
1539 down(&dev->lock);
1540 fh->win = f->fmt.win;
1541 fh->nclips = f->fmt.win.clipcount;
1542 if (fh->nclips > 8)
1543 fh->nclips = 8;
1544 if (copy_from_user(fh->clips,f->fmt.win.clips,
1545 sizeof(struct v4l2_clip)*fh->nclips)) {
1546 up(&dev->lock);
1547 return -EFAULT;
1548 }
1549
1550 if (res_check(fh, RESOURCE_OVERLAY)) {
1551 spin_lock_irqsave(&dev->slock,flags);
1552 stop_preview(dev,fh);
1553 start_preview(dev,fh);
1554 spin_unlock_irqrestore(&dev->slock,flags);
1555 }
1556 up(&dev->lock);
1557 return 0;
1558 case V4L2_BUF_TYPE_VBI_CAPTURE:
1559 saa7134_vbi_fmt(dev,f);
1560 return 0;
1561 default:
1562 return -EINVAL;
1563 }
1564}
1565
1566int saa7134_common_ioctl(struct saa7134_dev *dev,
1567 unsigned int cmd, void *arg)
1568{
1569 int err;
1570
1571 switch (cmd) {
1572 case VIDIOC_QUERYCTRL:
1573 {
1574 const struct v4l2_queryctrl *ctrl;
1575 struct v4l2_queryctrl *c = arg;
1576
1577 if ((c->id < V4L2_CID_BASE ||
1578 c->id >= V4L2_CID_LASTP1) &&
1579 (c->id < V4L2_CID_PRIVATE_BASE ||
1580 c->id >= V4L2_CID_PRIVATE_LASTP1))
1581 return -EINVAL;
1582 ctrl = ctrl_by_id(c->id);
1583 *c = (NULL != ctrl) ? *ctrl : no_ctrl;
1584 return 0;
1585 }
1586 case VIDIOC_G_CTRL:
1587 return get_control(dev,arg);
1588 case VIDIOC_S_CTRL:
1589 {
1590 down(&dev->lock);
1591 err = set_control(dev,NULL,arg);
1592 up(&dev->lock);
1593 return err;
1594 }
1595 /* --- input switching --------------------------------------- */
1596 case VIDIOC_ENUMINPUT:
1597 {
1598 struct v4l2_input *i = arg;
1599 unsigned int n;
1600
1601 n = i->index;
1602 if (n >= SAA7134_INPUT_MAX)
1603 return -EINVAL;
1604 if (NULL == card_in(dev,i->index).name)
1605 return -EINVAL;
1606 memset(i,0,sizeof(*i));
1607 i->index = n;
1608 i->type = V4L2_INPUT_TYPE_CAMERA;
1609 strcpy(i->name,card_in(dev,n).name);
1610 if (card_in(dev,n).tv)
1611 i->type = V4L2_INPUT_TYPE_TUNER;
1612 i->audioset = 1;
1613 if (n == dev->ctl_input) {
1614 int v1 = saa_readb(SAA7134_STATUS_VIDEO1);
1615 int v2 = saa_readb(SAA7134_STATUS_VIDEO2);
1616
1617 if (0 != (v1 & 0x40))
1618 i->status |= V4L2_IN_ST_NO_H_LOCK;
1619 if (0 != (v2 & 0x40))
1620 i->status |= V4L2_IN_ST_NO_SYNC;
1621 if (0 != (v2 & 0x0e))
1622 i->status |= V4L2_IN_ST_MACROVISION;
1623 }
1624 for (n = 0; n < TVNORMS; n++)
1625 i->std |= tvnorms[n].id;
1626 return 0;
1627 }
1628 case VIDIOC_G_INPUT:
1629 {
1630 int *i = arg;
1631 *i = dev->ctl_input;
1632 return 0;
1633 }
1634 case VIDIOC_S_INPUT:
1635 {
1636 int *i = arg;
1637
1638 if (*i < 0 || *i >= SAA7134_INPUT_MAX)
1639 return -EINVAL;
1640 if (NULL == card_in(dev,*i).name)
1641 return -EINVAL;
1642 down(&dev->lock);
1643 video_mux(dev,*i);
1644 up(&dev->lock);
1645 return 0;
1646 }
1647
1648 }
1649 return 0;
1650}
1651EXPORT_SYMBOL(saa7134_common_ioctl);
1652
1653/*
1654 * This function is _not_ called directly, but from
1655 * video_generic_ioctl (and maybe others). userspace
1656 * copying is done already, arg is a kernel pointer.
1657 */
1658static int video_do_ioctl(struct inode *inode, struct file *file,
1659 unsigned int cmd, void *arg)
1660{
1661 struct saa7134_fh *fh = file->private_data;
1662 struct saa7134_dev *dev = fh->dev;
1663 unsigned long flags;
1664 int err;
1665
1666 if (video_debug > 1)
1667 saa7134_print_ioctl(dev->name,cmd);
1668
1669 switch (cmd) {
1670 case VIDIOC_S_CTRL:
1671 case VIDIOC_S_STD:
1672 case VIDIOC_S_INPUT:
1673 case VIDIOC_S_TUNER:
1674 case VIDIOC_S_FREQUENCY:
1675 err = v4l2_prio_check(&dev->prio,&fh->prio);
1676 if (0 != err)
1677 return err;
1678 }
1679
1680 switch (cmd) {
1681 case VIDIOC_QUERYCAP:
1682 {
1683 struct v4l2_capability *cap = arg;
1684
1685 memset(cap,0,sizeof(*cap));
1686 strcpy(cap->driver, "saa7134");
1687 strlcpy(cap->card, saa7134_boards[dev->board].name,
1688 sizeof(cap->card));
1689 sprintf(cap->bus_info,"PCI:%s",pci_name(dev->pci));
1690 cap->version = SAA7134_VERSION_CODE;
1691 cap->capabilities =
1692 V4L2_CAP_VIDEO_CAPTURE |
1693 V4L2_CAP_VIDEO_OVERLAY |
1694 V4L2_CAP_VBI_CAPTURE |
1695 V4L2_CAP_TUNER |
1696 V4L2_CAP_READWRITE |
1697 V4L2_CAP_STREAMING;
1698 return 0;
1699 }
1700
1701 /* --- tv standards ------------------------------------------ */
1702 case VIDIOC_ENUMSTD:
1703 {
1704 struct v4l2_standard *e = arg;
1705 unsigned int i;
1706
1707 i = e->index;
1708 if (i >= TVNORMS)
1709 return -EINVAL;
1710 err = v4l2_video_std_construct(e, tvnorms[e->index].id,
1711 tvnorms[e->index].name);
1712 e->index = i;
1713 if (err < 0)
1714 return err;
1715 return 0;
1716 }
1717 case VIDIOC_G_STD:
1718 {
1719 v4l2_std_id *id = arg;
1720
1721 *id = dev->tvnorm->id;
1722 return 0;
1723 }
1724 case VIDIOC_S_STD:
1725 {
1726 v4l2_std_id *id = arg;
1727 unsigned int i;
1728
1729 for (i = 0; i < TVNORMS; i++)
1730 if (*id == tvnorms[i].id)
1731 break;
1732 if (i == TVNORMS)
1733 for (i = 0; i < TVNORMS; i++)
1734 if (*id & tvnorms[i].id)
1735 break;
1736 if (i == TVNORMS)
1737 return -EINVAL;
1738
1739 down(&dev->lock);
1740 if (res_check(fh, RESOURCE_OVERLAY)) {
1741 spin_lock_irqsave(&dev->slock,flags);
1742 stop_preview(dev,fh);
1743 set_tvnorm(dev,&tvnorms[i]);
1744 start_preview(dev,fh);
1745 spin_unlock_irqrestore(&dev->slock,flags);
1746 } else
1747 set_tvnorm(dev,&tvnorms[i]);
1748 saa7134_tvaudio_do_scan(dev);
1749 up(&dev->lock);
1750 return 0;
1751 }
1752
1753 case VIDIOC_CROPCAP:
1754 {
1755 struct v4l2_cropcap *cap = arg;
1756
1757 if (cap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
1758 cap->type != V4L2_BUF_TYPE_VIDEO_OVERLAY)
1759 return -EINVAL;
1760 cap->bounds = dev->crop_bounds;
1761 cap->defrect = dev->crop_defrect;
1762 cap->pixelaspect.numerator = 1;
1763 cap->pixelaspect.denominator = 1;
1764 if (dev->tvnorm->id & V4L2_STD_525_60) {
1765 cap->pixelaspect.numerator = 11;
1766 cap->pixelaspect.denominator = 10;
1767 }
1768 if (dev->tvnorm->id & V4L2_STD_625_50) {
1769 cap->pixelaspect.numerator = 54;
1770 cap->pixelaspect.denominator = 59;
1771 }
1772 return 0;
1773 }
1774
1775 case VIDIOC_G_CROP:
1776 {
1777 struct v4l2_crop * crop = arg;
1778
1779 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
1780 crop->type != V4L2_BUF_TYPE_VIDEO_OVERLAY)
1781 return -EINVAL;
1782 crop->c = dev->crop_current;
1783 return 0;
1784 }
1785 case VIDIOC_S_CROP:
1786 {
1787 struct v4l2_crop *crop = arg;
1788 struct v4l2_rect *b = &dev->crop_bounds;
1789
1790 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
1791 crop->type != V4L2_BUF_TYPE_VIDEO_OVERLAY)
1792 return -EINVAL;
1793 if (crop->c.height < 0)
1794 return -EINVAL;
1795 if (crop->c.width < 0)
1796 return -EINVAL;
1797
1798 if (res_locked(fh->dev,RESOURCE_OVERLAY))
1799 return -EBUSY;
1800 if (res_locked(fh->dev,RESOURCE_VIDEO))
1801 return -EBUSY;
1802
1803 if (crop->c.top < b->top)
1804 crop->c.top = b->top;
1805 if (crop->c.top > b->top + b->height)
1806 crop->c.top = b->top + b->height;
1807 if (crop->c.height > b->top - crop->c.top + b->height)
1808 crop->c.height = b->top - crop->c.top + b->height;
1809
1810 if (crop->c.left < b->left)
1811 crop->c.top = b->left;
1812 if (crop->c.left > b->left + b->width)
1813 crop->c.top = b->left + b->width;
1814 if (crop->c.width > b->left - crop->c.left + b->width)
1815 crop->c.width = b->left - crop->c.left + b->width;
1816
1817 dev->crop_current = crop->c;
1818 return 0;
1819 }
1820
1821 /* --- tuner ioctls ------------------------------------------ */
1822 case VIDIOC_G_TUNER:
1823 {
1824 struct v4l2_tuner *t = arg;
1825 int n;
1826
1827 if (0 != t->index)
1828 return -EINVAL;
1829 memset(t,0,sizeof(*t));
1830 for (n = 0; n < SAA7134_INPUT_MAX; n++)
1831 if (card_in(dev,n).tv)
1832 break;
1833 if (NULL != card_in(dev,n).name) {
1834 strcpy(t->name, "Television");
1835 t->capability = V4L2_TUNER_CAP_NORM |
1836 V4L2_TUNER_CAP_STEREO |
1837 V4L2_TUNER_CAP_LANG1 |
1838 V4L2_TUNER_CAP_LANG2;
1839 t->rangehigh = 0xffffffffUL;
1840 t->rxsubchans = saa7134_tvaudio_getstereo(dev);
1841 t->audmode = saa7134_tvaudio_rx2mode(t->rxsubchans);
1842 }
1843 if (0 != (saa_readb(SAA7134_STATUS_VIDEO1) & 0x03))
1844 t->signal = 0xffff;
1845 return 0;
1846 }
1847 case VIDIOC_S_TUNER:
1848 {
1849 struct v4l2_tuner *t = arg;
1850 int rx,mode;
1851
1852 mode = dev->thread.mode;
1853 if (UNSET == mode) {
1854 rx = saa7134_tvaudio_getstereo(dev);
1855 mode = saa7134_tvaudio_rx2mode(t->rxsubchans);
1856 }
1857 if (mode != t->audmode) {
1858 dev->thread.mode = t->audmode;
1859 }
1860 return 0;
1861 }
1862 case VIDIOC_G_FREQUENCY:
1863 {
1864 struct v4l2_frequency *f = arg;
1865
1866 memset(f,0,sizeof(*f));
1867 f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
1868 f->frequency = dev->ctl_freq;
1869 return 0;
1870 }
1871 case VIDIOC_S_FREQUENCY:
1872 {
1873 struct v4l2_frequency *f = arg;
1874
1875 if (0 != f->tuner)
1876 return -EINVAL;
1877 if (0 == fh->radio && V4L2_TUNER_ANALOG_TV != f->type)
1878 return -EINVAL;
1879 if (1 == fh->radio && V4L2_TUNER_RADIO != f->type)
1880 return -EINVAL;
1881 down(&dev->lock);
1882 dev->ctl_freq = f->frequency;
1883#ifdef V4L2_I2C_CLIENTS
1884 saa7134_i2c_call_clients(dev,VIDIOC_S_FREQUENCY,f);
1885#else
1886 saa7134_i2c_call_clients(dev,VIDIOCSFREQ,&dev->ctl_freq);
1887#endif
1888 saa7134_tvaudio_do_scan(dev);
1889 up(&dev->lock);
1890 return 0;
1891 }
1892
1893 /* --- control ioctls ---------------------------------------- */
1894 case VIDIOC_ENUMINPUT:
1895 case VIDIOC_G_INPUT:
1896 case VIDIOC_S_INPUT:
1897 case VIDIOC_QUERYCTRL:
1898 case VIDIOC_G_CTRL:
1899 case VIDIOC_S_CTRL:
1900 return saa7134_common_ioctl(dev, cmd, arg);
1901
1902 case VIDIOC_G_AUDIO:
1903 {
1904 struct v4l2_audio *a = arg;
1905
1906 memset(a,0,sizeof(*a));
1907 strcpy(a->name,"audio");
1908 return 0;
1909 }
1910 case VIDIOC_S_AUDIO:
1911 return 0;
1912 case VIDIOC_G_PARM:
1913 {
1914 struct v4l2_captureparm *parm = arg;
1915 memset(parm,0,sizeof(*parm));
1916 return 0;
1917 }
1918
1919 case VIDIOC_G_PRIORITY:
1920 {
1921 enum v4l2_priority *p = arg;
1922
1923 *p = v4l2_prio_max(&dev->prio);
1924 return 0;
1925 }
1926 case VIDIOC_S_PRIORITY:
1927 {
1928 enum v4l2_priority *prio = arg;
1929
1930 return v4l2_prio_change(&dev->prio, &fh->prio, *prio);
1931 }
1932
1933 /* --- preview ioctls ---------------------------------------- */
1934 case VIDIOC_ENUM_FMT:
1935 {
1936 struct v4l2_fmtdesc *f = arg;
1937 enum v4l2_buf_type type;
1938 unsigned int index;
1939
1940 index = f->index;
1941 type = f->type;
1942 switch (type) {
1943 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1944 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
1945 if (index >= FORMATS)
1946 return -EINVAL;
1947 if (f->type == V4L2_BUF_TYPE_VIDEO_OVERLAY &&
1948 formats[index].planar)
1949 return -EINVAL;
1950 memset(f,0,sizeof(*f));
1951 f->index = index;
1952 f->type = type;
1953 strlcpy(f->description,formats[index].name,sizeof(f->description));
1954 f->pixelformat = formats[index].fourcc;
1955 break;
1956 case V4L2_BUF_TYPE_VBI_CAPTURE:
1957 if (0 != index)
1958 return -EINVAL;
1959 memset(f,0,sizeof(*f));
1960 f->index = index;
1961 f->type = type;
1962 f->pixelformat = V4L2_PIX_FMT_GREY;
1963 strcpy(f->description,"vbi data");
1964 break;
1965 default:
1966 return -EINVAL;
1967 }
1968 return 0;
1969 }
1970 case VIDIOC_G_FBUF:
1971 {
1972 struct v4l2_framebuffer *fb = arg;
1973
1974 *fb = dev->ovbuf;
1975 fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING;
1976 return 0;
1977 }
1978 case VIDIOC_S_FBUF:
1979 {
1980 struct v4l2_framebuffer *fb = arg;
1981 struct saa7134_format *fmt;
1982
1983 if(!capable(CAP_SYS_ADMIN) &&
1984 !capable(CAP_SYS_RAWIO))
1985 return -EPERM;
1986
1987 /* check args */
1988 fmt = format_by_fourcc(fb->fmt.pixelformat);
1989 if (NULL == fmt)
1990 return -EINVAL;
1991
1992 /* ok, accept it */
1993 dev->ovbuf = *fb;
1994 dev->ovfmt = fmt;
1995 if (0 == dev->ovbuf.fmt.bytesperline)
1996 dev->ovbuf.fmt.bytesperline =
1997 dev->ovbuf.fmt.width*fmt->depth/8;
1998 return 0;
1999 }
2000 case VIDIOC_OVERLAY:
2001 {
2002 int *on = arg;
2003
2004 if (*on) {
2005 if (!res_get(dev,fh,RESOURCE_OVERLAY))
2006 return -EBUSY;
2007 spin_lock_irqsave(&dev->slock,flags);
2008 start_preview(dev,fh);
2009 spin_unlock_irqrestore(&dev->slock,flags);
2010 }
2011 if (!*on) {
2012 if (!res_check(fh, RESOURCE_OVERLAY))
2013 return -EINVAL;
2014 spin_lock_irqsave(&dev->slock,flags);
2015 stop_preview(dev,fh);
2016 spin_unlock_irqrestore(&dev->slock,flags);
2017 res_free(dev,fh,RESOURCE_OVERLAY);
2018 }
2019 return 0;
2020 }
2021
2022 /* --- capture ioctls ---------------------------------------- */
2023 case VIDIOC_G_FMT:
2024 {
2025 struct v4l2_format *f = arg;
2026 return saa7134_g_fmt(dev,fh,f);
2027 }
2028 case VIDIOC_S_FMT:
2029 {
2030 struct v4l2_format *f = arg;
2031 return saa7134_s_fmt(dev,fh,f);
2032 }
2033 case VIDIOC_TRY_FMT:
2034 {
2035 struct v4l2_format *f = arg;
2036 return saa7134_try_fmt(dev,fh,f);
2037 }
2038
2039 case VIDIOCGMBUF:
2040 {
2041 struct video_mbuf *mbuf = arg;
2042 struct videobuf_queue *q;
2043 struct v4l2_requestbuffers req;
2044 unsigned int i;
2045
2046 q = saa7134_queue(fh);
2047 memset(&req,0,sizeof(req));
2048 req.type = q->type;
2049 req.count = gbuffers;
2050 req.memory = V4L2_MEMORY_MMAP;
2051 err = videobuf_reqbufs(q,&req);
2052 if (err < 0)
2053 return err;
2054 memset(mbuf,0,sizeof(*mbuf));
2055 mbuf->frames = req.count;
2056 mbuf->size = 0;
2057 for (i = 0; i < mbuf->frames; i++) {
2058 mbuf->offsets[i] = q->bufs[i]->boff;
2059 mbuf->size += q->bufs[i]->bsize;
2060 }
2061 return 0;
2062 }
2063 case VIDIOC_REQBUFS:
2064 return videobuf_reqbufs(saa7134_queue(fh),arg);
2065
2066 case VIDIOC_QUERYBUF:
2067 return videobuf_querybuf(saa7134_queue(fh),arg);
2068
2069 case VIDIOC_QBUF:
2070 return videobuf_qbuf(saa7134_queue(fh),arg);
2071
2072 case VIDIOC_DQBUF:
2073 return videobuf_dqbuf(saa7134_queue(fh),arg,
2074 file->f_flags & O_NONBLOCK);
2075
2076 case VIDIOC_STREAMON:
2077 {
2078 int res = saa7134_resource(fh);
2079
2080 if (!res_get(dev,fh,res))
2081 return -EBUSY;
2082 return videobuf_streamon(saa7134_queue(fh));
2083 }
2084 case VIDIOC_STREAMOFF:
2085 {
2086 int res = saa7134_resource(fh);
2087
2088 err = videobuf_streamoff(saa7134_queue(fh));
2089 if (err < 0)
2090 return err;
2091 res_free(dev,fh,res);
2092 return 0;
2093 }
2094
2095 default:
2096 return v4l_compat_translate_ioctl(inode,file,cmd,arg,
2097 video_do_ioctl);
2098 }
2099 return 0;
2100}
2101
2102static int video_ioctl(struct inode *inode, struct file *file,
2103 unsigned int cmd, unsigned long arg)
2104{
2105 return video_usercopy(inode, file, cmd, arg, video_do_ioctl);
2106}
2107
2108static int radio_do_ioctl(struct inode *inode, struct file *file,
2109 unsigned int cmd, void *arg)
2110{
2111 struct saa7134_fh *fh = file->private_data;
2112 struct saa7134_dev *dev = fh->dev;
2113
2114 if (video_debug > 1)
2115 saa7134_print_ioctl(dev->name,cmd);
2116 switch (cmd) {
2117 case VIDIOC_QUERYCAP:
2118 {
2119 struct v4l2_capability *cap = arg;
2120
2121 memset(cap,0,sizeof(*cap));
2122 strcpy(cap->driver, "saa7134");
2123 strlcpy(cap->card, saa7134_boards[dev->board].name,
2124 sizeof(cap->card));
2125 sprintf(cap->bus_info,"PCI:%s",pci_name(dev->pci));
2126 cap->version = SAA7134_VERSION_CODE;
2127 cap->capabilities = V4L2_CAP_TUNER;
2128 return 0;
2129 }
2130 case VIDIOC_G_TUNER:
2131 {
2132 struct v4l2_tuner *t = arg;
2133
2134 if (0 != t->index)
2135 return -EINVAL;
2136
2137 memset(t,0,sizeof(*t));
2138 strcpy(t->name, "Radio");
2139 t->rangelow = (int)(65*16);
2140 t->rangehigh = (int)(108*16);
2141
2142#ifdef V4L2_I2C_CLIENTS
2143 saa7134_i2c_call_clients(dev,VIDIOC_G_TUNER,t);
2144#else
2145 {
2146 struct video_tuner vt;
2147 memset(&vt,0,sizeof(vt));
2148 saa7134_i2c_call_clients(dev,VIDIOCGTUNER,&vt);
2149 t->signal = vt.signal;
2150 }
2151#endif
2152 return 0;
2153 }
2154 case VIDIOC_ENUMINPUT:
2155 {
2156 struct v4l2_input *i = arg;
2157
2158 if (i->index != 0)
2159 return -EINVAL;
2160 strcpy(i->name,"Radio");
2161 i->type = V4L2_INPUT_TYPE_TUNER;
2162 return 0;
2163 }
2164 case VIDIOC_G_INPUT:
2165 {
2166 int *i = arg;
2167 *i = 0;
2168 return 0;
2169 }
2170 case VIDIOC_G_AUDIO:
2171 {
2172 struct v4l2_audio *a = arg;
2173
2174 memset(a,0,sizeof(*a));
2175 strcpy(a->name,"Radio");
2176 return 0;
2177 }
2178 case VIDIOC_G_STD:
2179 {
2180 v4l2_std_id *id = arg;
2181 *id = 0;
2182 return 0;
2183 }
2184 case VIDIOC_S_AUDIO:
2185 case VIDIOC_S_TUNER:
2186 case VIDIOC_S_INPUT:
2187 case VIDIOC_S_STD:
2188 return 0;
2189
2190 case VIDIOC_QUERYCTRL:
2191 {
2192 const struct v4l2_queryctrl *ctrl;
2193 struct v4l2_queryctrl *c = arg;
2194
2195 if (c->id < V4L2_CID_BASE ||
2196 c->id >= V4L2_CID_LASTP1)
2197 return -EINVAL;
2198 if (c->id == V4L2_CID_AUDIO_MUTE) {
2199 ctrl = ctrl_by_id(c->id);
2200 *c = *ctrl;
2201 } else
2202 *c = no_ctrl;
2203 return 0;
2204 }
2205
2206 case VIDIOC_G_CTRL:
2207 case VIDIOC_S_CTRL:
2208 case VIDIOC_G_FREQUENCY:
2209 case VIDIOC_S_FREQUENCY:
2210 return video_do_ioctl(inode,file,cmd,arg);
2211
2212 default:
2213 return v4l_compat_translate_ioctl(inode,file,cmd,arg,
2214 radio_do_ioctl);
2215 }
2216 return 0;
2217}
2218
2219static int radio_ioctl(struct inode *inode, struct file *file,
2220 unsigned int cmd, unsigned long arg)
2221{
2222 return video_usercopy(inode, file, cmd, arg, radio_do_ioctl);
2223}
2224
2225static struct file_operations video_fops =
2226{
2227 .owner = THIS_MODULE,
2228 .open = video_open,
2229 .release = video_release,
2230 .read = video_read,
2231 .poll = video_poll,
2232 .mmap = video_mmap,
2233 .ioctl = video_ioctl,
2234 .llseek = no_llseek,
2235};
2236
2237static struct file_operations radio_fops =
2238{
2239 .owner = THIS_MODULE,
2240 .open = video_open,
2241 .release = video_release,
2242 .ioctl = radio_ioctl,
2243 .llseek = no_llseek,
2244};
2245
2246/* ----------------------------------------------------------- */
2247/* exported stuff */
2248
2249struct video_device saa7134_video_template =
2250{
2251 .name = "saa7134-video",
2252 .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER|VID_TYPE_OVERLAY|
2253 VID_TYPE_CLIPPING|VID_TYPE_SCALES,
2254 .hardware = 0,
2255 .fops = &video_fops,
2256 .minor = -1,
2257};
2258
2259struct video_device saa7134_vbi_template =
2260{
2261 .name = "saa7134-vbi",
2262 .type = VID_TYPE_TUNER|VID_TYPE_TELETEXT,
2263 .hardware = 0,
2264 .fops = &video_fops,
2265 .minor = -1,
2266};
2267
2268struct video_device saa7134_radio_template =
2269{
2270 .name = "saa7134-radio",
2271 .type = VID_TYPE_TUNER,
2272 .hardware = 0,
2273 .fops = &radio_fops,
2274 .minor = -1,
2275};
2276
2277int saa7134_video_init1(struct saa7134_dev *dev)
2278{
2279 /* sanitycheck insmod options */
2280 if (gbuffers < 2 || gbuffers > VIDEO_MAX_FRAME)
2281 gbuffers = 2;
2282 if (gbufsize < 0 || gbufsize > gbufsize_max)
2283 gbufsize = gbufsize_max;
2284 gbufsize = (gbufsize + PAGE_SIZE - 1) & PAGE_MASK;
2285
2286 /* put some sensible defaults into the data structures ... */
2287 dev->ctl_bright = ctrl_by_id(V4L2_CID_BRIGHTNESS)->default_value;
2288 dev->ctl_contrast = ctrl_by_id(V4L2_CID_CONTRAST)->default_value;
2289 dev->ctl_hue = ctrl_by_id(V4L2_CID_HUE)->default_value;
2290 dev->ctl_saturation = ctrl_by_id(V4L2_CID_SATURATION)->default_value;
2291 dev->ctl_volume = ctrl_by_id(V4L2_CID_AUDIO_VOLUME)->default_value;
2292 dev->ctl_mute = 1; // ctrl_by_id(V4L2_CID_AUDIO_MUTE)->default_value;
2293 dev->ctl_invert = ctrl_by_id(V4L2_CID_PRIVATE_INVERT)->default_value;
2294 dev->ctl_automute = ctrl_by_id(V4L2_CID_PRIVATE_AUTOMUTE)->default_value;
2295
2296 if (dev->tda9887_conf && dev->ctl_automute)
2297 dev->tda9887_conf |= TDA9887_AUTOMUTE;
2298 dev->automute = 0;
2299
2300 INIT_LIST_HEAD(&dev->video_q.queue);
2301 init_timer(&dev->video_q.timeout);
2302 dev->video_q.timeout.function = saa7134_buffer_timeout;
2303 dev->video_q.timeout.data = (unsigned long)(&dev->video_q);
2304 dev->video_q.dev = dev;
2305
2306 if (saa7134_boards[dev->board].video_out) {
2307 /* enable video output */
2308 int vo = saa7134_boards[dev->board].video_out;
2309 saa_writeb(SAA7134_VIDEO_PORT_CTRL0, video_out[vo][0]);
2310 saa_writeb(SAA7134_VIDEO_PORT_CTRL1, video_out[vo][1]);
2311 saa_writeb(SAA7134_VIDEO_PORT_CTRL2, video_out[vo][2]);
2312 saa_writeb(SAA7134_VIDEO_PORT_CTRL3, video_out[vo][3]);
2313 saa_writeb(SAA7134_VIDEO_PORT_CTRL4, video_out[vo][4]);
2314 saa_writeb(SAA7134_VIDEO_PORT_CTRL5, video_out[vo][5]);
2315 saa_writeb(SAA7134_VIDEO_PORT_CTRL6, video_out[vo][6]);
2316 saa_writeb(SAA7134_VIDEO_PORT_CTRL7, video_out[vo][7]);
2317 saa_writeb(SAA7134_VIDEO_PORT_CTRL8, video_out[vo][8]);
2318 }
2319
2320 return 0;
2321}
2322
2323int saa7134_video_init2(struct saa7134_dev *dev)
2324{
2325 /* init video hw */
2326 set_tvnorm(dev,&tvnorms[0]);
2327 video_mux(dev,0);
2328 saa7134_tvaudio_setmute(dev);
2329 saa7134_tvaudio_setvolume(dev,dev->ctl_volume);
2330 return 0;
2331}
2332
2333int saa7134_video_fini(struct saa7134_dev *dev)
2334{
2335 /* nothing */
2336 return 0;
2337}
2338
2339void saa7134_irq_video_intl(struct saa7134_dev *dev)
2340{
2341 static const char *st[] = {
2342 "(no signal)", "NTSC", "PAL", "SECAM" };
2343 u32 st1,st2;
2344
2345 st1 = saa_readb(SAA7134_STATUS_VIDEO1);
2346 st2 = saa_readb(SAA7134_STATUS_VIDEO2);
2347 dprintk("DCSDT: pll: %s, sync: %s, norm: %s\n",
2348 (st1 & 0x40) ? "not locked" : "locked",
2349 (st2 & 0x40) ? "no" : "yes",
2350 st[st1 & 0x03]);
2351 dev->nosignal = (st1 & 0x40) || (st2 & 0x40);
2352
2353 if (dev->nosignal) {
2354 /* no video signal -> mute audio */
2355 if (dev->ctl_automute)
2356 dev->automute = 1;
2357 saa7134_tvaudio_setmute(dev);
2358 saa_setb(SAA7134_SYNC_CTRL, 0x20);
2359 } else {
2360 /* wake up tvaudio audio carrier scan thread */
2361 saa7134_tvaudio_do_scan(dev);
2362 if (!noninterlaced)
2363 saa_clearb(SAA7134_SYNC_CTRL, 0x20);
2364 }
2365 if (dev->mops && dev->mops->signal_change)
2366 dev->mops->signal_change(dev);
2367}
2368
2369void saa7134_irq_video_done(struct saa7134_dev *dev, unsigned long status)
2370{
2371 enum v4l2_field field;
2372
2373 spin_lock(&dev->slock);
2374 if (dev->video_q.curr) {
2375 dev->video_fieldcount++;
2376 field = dev->video_q.curr->vb.field;
2377 if (V4L2_FIELD_HAS_BOTH(field)) {
2378 /* make sure we have seen both fields */
2379 if ((status & 0x10) == 0x00) {
2380 dev->video_q.curr->top_seen = 1;
2381 goto done;
2382 }
2383 if (!dev->video_q.curr->top_seen)
2384 goto done;
2385 } else if (field == V4L2_FIELD_TOP) {
2386 if ((status & 0x10) != 0x10)
2387 goto done;
2388 } else if (field == V4L2_FIELD_BOTTOM) {
2389 if ((status & 0x10) != 0x00)
2390 goto done;
2391 }
2392 dev->video_q.curr->vb.field_count = dev->video_fieldcount;
2393 saa7134_buffer_finish(dev,&dev->video_q,STATE_DONE);
2394 }
2395 saa7134_buffer_next(dev,&dev->video_q);
2396
2397 done:
2398 spin_unlock(&dev->slock);
2399}
2400
2401/* ----------------------------------------------------------- */
2402/*
2403 * Local variables:
2404 * c-basic-offset: 8
2405 * End:
2406 */
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
new file mode 100644
index 00000000000..ac90a985323
--- /dev/null
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -0,0 +1,618 @@
1/*
2 * $Id: saa7134.h,v 1.38 2005/03/07 12:01:51 kraxel Exp $
3 *
4 * v4l2 device driver for philips saa7134 based TV cards
5 *
6 * (c) 2001,02 Gerd Knorr <kraxel@bytesex.org>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#include <linux/version.h>
24#define SAA7134_VERSION_CODE KERNEL_VERSION(0,2,12)
25
26#include <linux/pci.h>
27#include <linux/i2c.h>
28#include <linux/videodev.h>
29#include <linux/kdev_t.h>
30#include <linux/input.h>
31
32#include <asm/io.h>
33
34#include <media/tuner.h>
35#include <media/audiochip.h>
36#include <media/id.h>
37#include <media/ir-common.h>
38#include <media/video-buf.h>
39#include <media/video-buf-dvb.h>
40
41#ifndef TRUE
42# define TRUE (1==1)
43#endif
44#ifndef FALSE
45# define FALSE (1==0)
46#endif
47#define UNSET (-1U)
48
49/* 2.4 / 2.5 driver compatibility stuff */
50
51/* ----------------------------------------------------------- */
52/* enums */
53
54enum saa7134_tvaudio_mode {
55 TVAUDIO_FM_MONO = 1,
56 TVAUDIO_FM_BG_STEREO = 2,
57 TVAUDIO_FM_SAT_STEREO = 3,
58 TVAUDIO_FM_K_STEREO = 4,
59 TVAUDIO_NICAM_AM = 5,
60 TVAUDIO_NICAM_FM = 6,
61};
62
63enum saa7134_audio_in {
64 TV = 1,
65 LINE1 = 2,
66 LINE2 = 3,
67 LINE2_LEFT,
68};
69
70enum saa7134_video_out {
71 CCIR656 = 1,
72};
73
74/* ----------------------------------------------------------- */
75/* static data */
76
77struct saa7134_tvnorm {
78 char *name;
79 v4l2_std_id id;
80
81 /* video decoder */
82 unsigned int sync_control;
83 unsigned int luma_control;
84 unsigned int chroma_ctrl1;
85 unsigned int chroma_gain;
86 unsigned int chroma_ctrl2;
87 unsigned int vgate_misc;
88
89 /* video scaler */
90 unsigned int h_start;
91 unsigned int h_stop;
92 unsigned int video_v_start;
93 unsigned int video_v_stop;
94 unsigned int vbi_v_start;
95 unsigned int vbi_v_stop;
96 unsigned int src_timing;
97};
98
99struct saa7134_tvaudio {
100 char *name;
101 v4l2_std_id std;
102 enum saa7134_tvaudio_mode mode;
103 int carr1;
104 int carr2;
105};
106
107struct saa7134_format {
108 char *name;
109 unsigned int fourcc;
110 unsigned int depth;
111 unsigned int pm;
112 unsigned int vshift; /* vertical downsampling (for planar yuv) */
113 unsigned int hshift; /* horizontal downsampling (for planar yuv) */
114 unsigned int bswap:1;
115 unsigned int wswap:1;
116 unsigned int yuv:1;
117 unsigned int planar:1;
118 unsigned int uvswap:1;
119};
120
121/* ----------------------------------------------------------- */
122/* card configuration */
123
124#define SAA7134_BOARD_NOAUTO UNSET
125#define SAA7134_BOARD_UNKNOWN 0
126#define SAA7134_BOARD_PROTEUS_PRO 1
127#define SAA7134_BOARD_FLYVIDEO3000 2
128#define SAA7134_BOARD_FLYVIDEO2000 3
129#define SAA7134_BOARD_EMPRESS 4
130#define SAA7134_BOARD_MONSTERTV 5
131#define SAA7134_BOARD_MD9717 6
132#define SAA7134_BOARD_TVSTATION_RDS 7
133#define SAA7134_BOARD_CINERGY400 8
134#define SAA7134_BOARD_MD5044 9
135#define SAA7134_BOARD_KWORLD 10
136#define SAA7134_BOARD_CINERGY600 11
137#define SAA7134_BOARD_MD7134 12
138#define SAA7134_BOARD_TYPHOON_90031 13
139#define SAA7134_BOARD_ELSA 14
140#define SAA7134_BOARD_ELSA_500TV 15
141#define SAA7134_BOARD_ASUSTeK_TVFM7134 16
142#define SAA7134_BOARD_VA1000POWER 17
143#define SAA7134_BOARD_BMK_MPEX_NOTUNER 18
144#define SAA7134_BOARD_VIDEOMATE_TV 19
145#define SAA7134_BOARD_CRONOS_PLUS 20
146#define SAA7134_BOARD_10MOONSTVMASTER 21
147#define SAA7134_BOARD_MD2819 22
148#define SAA7134_BOARD_BMK_MPEX_TUNER 23
149#define SAA7134_BOARD_TVSTATION_DVR 24
150#define SAA7134_BOARD_ASUSTEK_TVFM7133 25
151#define SAA7134_BOARD_PINNACLE_PCTV_STEREO 26
152#define SAA7134_BOARD_MANLI_MTV002 27
153#define SAA7134_BOARD_MANLI_MTV001 28
154#define SAA7134_BOARD_TG3000TV 29
155#define SAA7134_BOARD_ECS_TVP3XP 30
156#define SAA7134_BOARD_ECS_TVP3XP_4CB5 31
157#define SAA7134_BOARD_AVACSSMARTTV 32
158#define SAA7134_BOARD_AVERMEDIA_DVD_EZMAKER 33
159#define SAA7134_BOARD_NOVAC_PRIMETV7133 34
160#define SAA7134_BOARD_AVERMEDIA_STUDIO_305 35
161#define SAA7133_BOARD_UPMOST_PURPLE_TV 36
162#define SAA7134_BOARD_ITEMS_MTV005 37
163#define SAA7134_BOARD_CINERGY200 38
164#define SAA7134_BOARD_FLYTVPLATINUM_MINI 39
165#define SAA7134_BOARD_VIDEOMATE_TV_PVR 40
166#define SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUS 41
167#define SAA7134_BOARD_SABRENT_SBTTVFM 42
168#define SAA7134_BOARD_ZOLID_XPERT_TV7134 43
169#define SAA7134_BOARD_EMPIRE_PCI_TV_RADIO_LE 44
170#define SAA7134_BOARD_AVERMEDIA_307 45
171#define SAA7134_BOARD_AVERMEDIA_CARDBUS 46
172#define SAA7134_BOARD_CINERGY400_CARDBUS 47
173#define SAA7134_BOARD_CINERGY600_MK3 48
174#define SAA7134_BOARD_VIDEOMATE_GOLD_PLUS 49
175#define SAA7134_BOARD_PINNACLE_300I_DVBT_PAL 50
176#define SAA7134_BOARD_PROVIDEO_PV952 51
177#define SAA7134_BOARD_AVERMEDIA_305 52
178#define SAA7135_BOARD_ASUSTeK_TVFM7135 53
179#define SAA7134_BOARD_FLYTVPLATINUM_FM 54
180#define SAA7134_BOARD_FLYDVBTDUO 55
181
182#define SAA7134_MAXBOARDS 8
183#define SAA7134_INPUT_MAX 8
184
185struct saa7134_input {
186 char *name;
187 unsigned int vmux;
188 enum saa7134_audio_in amux;
189 unsigned int gpio;
190 unsigned int tv:1;
191};
192
193enum saa7134_mpeg_type {
194 SAA7134_MPEG_UNUSED,
195 SAA7134_MPEG_EMPRESS,
196 SAA7134_MPEG_DVB,
197};
198
199struct saa7134_board {
200 char *name;
201 unsigned int audio_clock;
202
203 /* input switching */
204 unsigned int gpiomask;
205 struct saa7134_input inputs[SAA7134_INPUT_MAX];
206 struct saa7134_input radio;
207 struct saa7134_input mute;
208
209 /* i2c chip info */
210 unsigned int tuner_type;
211 unsigned int tda9887_conf;
212
213 /* peripheral I/O */
214 enum saa7134_video_out video_out;
215 enum saa7134_mpeg_type mpeg;
216};
217
218#define card_has_radio(dev) (NULL != saa7134_boards[dev->board].radio.name)
219#define card_is_empress(dev) (SAA7134_MPEG_EMPRESS == saa7134_boards[dev->board].mpeg)
220#define card_is_dvb(dev) (SAA7134_MPEG_DVB == saa7134_boards[dev->board].mpeg)
221#define card_has_mpeg(dev) (SAA7134_MPEG_UNUSED != saa7134_boards[dev->board].mpeg)
222#define card(dev) (saa7134_boards[dev->board])
223#define card_in(dev,n) (saa7134_boards[dev->board].inputs[n])
224
225/* ----------------------------------------------------------- */
226/* device / file handle status */
227
228#define RESOURCE_OVERLAY 1
229#define RESOURCE_VIDEO 2
230#define RESOURCE_VBI 4
231
232#define INTERLACE_AUTO 0
233#define INTERLACE_ON 1
234#define INTERLACE_OFF 2
235
236#define BUFFER_TIMEOUT (HZ/2) /* 0.5 seconds */
237
238struct saa7134_dev;
239struct saa7134_dma;
240
241/* saa7134 page table */
242struct saa7134_pgtable {
243 unsigned int size;
244 u32 *cpu;
245 dma_addr_t dma;
246};
247
248/* tvaudio thread status */
249struct saa7134_thread {
250 pid_t pid;
251 struct completion exit;
252 wait_queue_head_t wq;
253 unsigned int shutdown;
254 unsigned int scan1;
255 unsigned int scan2;
256 unsigned int mode;
257};
258
259/* buffer for one video/vbi/ts frame */
260struct saa7134_buf {
261 /* common v4l buffer stuff -- must be first */
262 struct videobuf_buffer vb;
263
264 /* saa7134 specific */
265 struct saa7134_format *fmt;
266 unsigned int top_seen;
267 int (*activate)(struct saa7134_dev *dev,
268 struct saa7134_buf *buf,
269 struct saa7134_buf *next);
270
271 /* page tables */
272 struct saa7134_pgtable *pt;
273};
274
275struct saa7134_dmaqueue {
276 struct saa7134_dev *dev;
277 struct saa7134_buf *curr;
278 struct list_head queue;
279 struct timer_list timeout;
280 unsigned int need_two;
281};
282
283/* video filehandle status */
284struct saa7134_fh {
285 struct saa7134_dev *dev;
286 unsigned int radio;
287 enum v4l2_buf_type type;
288 unsigned int resources;
289#ifdef VIDIOC_G_PRIORITY
290 enum v4l2_priority prio;
291#endif
292
293 /* video overlay */
294 struct v4l2_window win;
295 struct v4l2_clip clips[8];
296 unsigned int nclips;
297
298 /* video capture */
299 struct saa7134_format *fmt;
300 unsigned int width,height;
301 struct videobuf_queue cap;
302 struct saa7134_pgtable pt_cap;
303
304 /* vbi capture */
305 struct videobuf_queue vbi;
306 struct saa7134_pgtable pt_vbi;
307};
308
309/* oss dsp status */
310struct saa7134_oss {
311 struct semaphore lock;
312 int minor_mixer;
313 int minor_dsp;
314 unsigned int users_dsp;
315
316 /* mixer */
317 enum saa7134_audio_in input;
318 unsigned int count;
319 unsigned int line1;
320 unsigned int line2;
321
322 /* dsp */
323 unsigned int afmt;
324 unsigned int rate;
325 unsigned int channels;
326 unsigned int recording_on;
327 unsigned int dma_running;
328 unsigned int blocks;
329 unsigned int blksize;
330 unsigned int bufsize;
331 struct saa7134_pgtable pt;
332 struct videobuf_dmabuf dma;
333 wait_queue_head_t wq;
334 unsigned int dma_blk;
335 unsigned int read_offset;
336 unsigned int read_count;
337};
338
339/* IR input */
340struct saa7134_ir {
341 struct input_dev dev;
342 struct ir_input_state ir;
343 char name[32];
344 char phys[32];
345 u32 mask_keycode;
346 u32 mask_keydown;
347 u32 mask_keyup;
348 int polling;
349 u32 last_gpio;
350 struct timer_list timer;
351};
352
353/* ts/mpeg status */
354struct saa7134_ts {
355 /* TS capture */
356 struct saa7134_pgtable pt_ts;
357 int nr_packets;
358 int nr_bufs;
359};
360
361/* ts/mpeg ops */
362struct saa7134_mpeg_ops {
363 enum saa7134_mpeg_type type;
364 struct list_head next;
365 int (*init)(struct saa7134_dev *dev);
366 int (*fini)(struct saa7134_dev *dev);
367 void (*signal_change)(struct saa7134_dev *dev);
368};
369
370/* global device status */
371struct saa7134_dev {
372 struct list_head devlist;
373 struct semaphore lock;
374 spinlock_t slock;
375#ifdef VIDIOC_G_PRIORITY
376 struct v4l2_prio_state prio;
377#endif
378
379 /* various device info */
380 unsigned int resources;
381 struct video_device *video_dev;
382 struct video_device *radio_dev;
383 struct video_device *vbi_dev;
384 struct saa7134_oss oss;
385
386 /* infrared remote */
387 int has_remote;
388 struct saa7134_ir *remote;
389
390 /* pci i/o */
391 char name[32];
392 int nr;
393 struct pci_dev *pci;
394 unsigned char pci_rev,pci_lat;
395 __u32 __iomem *lmmio;
396 __u8 __iomem *bmmio;
397
398 /* config info */
399 unsigned int board;
400 unsigned int tuner_type;
401 unsigned int tda9887_conf;
402 unsigned int gpio_value;
403 unsigned int irq2_mask;
404
405 /* i2c i/o */
406 struct i2c_adapter i2c_adap;
407 struct i2c_client i2c_client;
408 unsigned char eedata[64];
409
410 /* video overlay */
411 struct v4l2_framebuffer ovbuf;
412 struct saa7134_format *ovfmt;
413 unsigned int ovenable;
414 enum v4l2_field ovfield;
415
416 /* video+ts+vbi capture */
417 struct saa7134_dmaqueue video_q;
418 struct saa7134_dmaqueue vbi_q;
419 unsigned int video_fieldcount;
420 unsigned int vbi_fieldcount;
421
422 /* various v4l controls */
423 struct saa7134_tvnorm *tvnorm; /* video */
424 struct saa7134_tvaudio *tvaudio;
425 unsigned int ctl_input;
426 int ctl_bright;
427 int ctl_contrast;
428 int ctl_hue;
429 int ctl_saturation;
430 int ctl_freq;
431 int ctl_mute; /* audio */
432 int ctl_volume;
433 int ctl_invert; /* private */
434 int ctl_mirror;
435 int ctl_y_odd;
436 int ctl_y_even;
437 int ctl_automute;
438
439 /* crop */
440 struct v4l2_rect crop_bounds;
441 struct v4l2_rect crop_defrect;
442 struct v4l2_rect crop_current;
443
444 /* other global state info */
445 unsigned int automute;
446 struct saa7134_thread thread;
447 struct saa7134_input *input;
448 struct saa7134_input *hw_input;
449 unsigned int hw_mute;
450 int last_carrier;
451 int nosignal;
452
453 /* SAA7134_MPEG_* */
454 struct saa7134_ts ts;
455 struct saa7134_dmaqueue ts_q;
456 struct saa7134_mpeg_ops *mops;
457
458 /* SAA7134_MPEG_EMPRESS only */
459 struct video_device *empress_dev;
460 struct videobuf_queue empress_tsq;
461 unsigned int empress_users;
462 struct work_struct empress_workqueue;
463 int empress_started;
464
465 /* SAA7134_MPEG_DVB only */
466 struct videobuf_dvb dvb;
467};
468
469/* ----------------------------------------------------------- */
470
471#define saa_readl(reg) readl(dev->lmmio + (reg))
472#define saa_writel(reg,value) writel((value), dev->lmmio + (reg));
473#define saa_andorl(reg,mask,value) \
474 writel((readl(dev->lmmio+(reg)) & ~(mask)) |\
475 ((value) & (mask)), dev->lmmio+(reg))
476#define saa_setl(reg,bit) saa_andorl((reg),(bit),(bit))
477#define saa_clearl(reg,bit) saa_andorl((reg),(bit),0)
478
479#define saa_readb(reg) readb(dev->bmmio + (reg))
480#define saa_writeb(reg,value) writeb((value), dev->bmmio + (reg));
481#define saa_andorb(reg,mask,value) \
482 writeb((readb(dev->bmmio+(reg)) & ~(mask)) |\
483 ((value) & (mask)), dev->bmmio+(reg))
484#define saa_setb(reg,bit) saa_andorb((reg),(bit),(bit))
485#define saa_clearb(reg,bit) saa_andorb((reg),(bit),0)
486
487#define saa_wait(us) { udelay(us); }
488
489/* ----------------------------------------------------------- */
490/* saa7134-core.c */
491
492extern struct list_head saa7134_devlist;
493
494void saa7134_print_ioctl(char *name, unsigned int cmd);
495void saa7134_track_gpio(struct saa7134_dev *dev, char *msg);
496
497#define SAA7134_PGTABLE_SIZE 4096
498
499int saa7134_pgtable_alloc(struct pci_dev *pci, struct saa7134_pgtable *pt);
500int saa7134_pgtable_build(struct pci_dev *pci, struct saa7134_pgtable *pt,
501 struct scatterlist *list, unsigned int length,
502 unsigned int startpage);
503void saa7134_pgtable_free(struct pci_dev *pci, struct saa7134_pgtable *pt);
504
505int saa7134_buffer_count(unsigned int size, unsigned int count);
506int saa7134_buffer_startpage(struct saa7134_buf *buf);
507unsigned long saa7134_buffer_base(struct saa7134_buf *buf);
508
509int saa7134_buffer_queue(struct saa7134_dev *dev, struct saa7134_dmaqueue *q,
510 struct saa7134_buf *buf);
511void saa7134_buffer_finish(struct saa7134_dev *dev, struct saa7134_dmaqueue *q,
512 unsigned int state);
513void saa7134_buffer_next(struct saa7134_dev *dev, struct saa7134_dmaqueue *q);
514void saa7134_buffer_timeout(unsigned long data);
515void saa7134_dma_free(struct saa7134_dev *dev,struct saa7134_buf *buf);
516
517int saa7134_set_dmabits(struct saa7134_dev *dev);
518
519/* ----------------------------------------------------------- */
520/* saa7134-cards.c */
521
522extern struct saa7134_board saa7134_boards[];
523extern const unsigned int saa7134_bcount;
524extern struct pci_device_id __devinitdata saa7134_pci_tbl[];
525
526extern int saa7134_board_init1(struct saa7134_dev *dev);
527extern int saa7134_board_init2(struct saa7134_dev *dev);
528
529
530/* ----------------------------------------------------------- */
531/* saa7134-i2c.c */
532
533int saa7134_i2c_register(struct saa7134_dev *dev);
534int saa7134_i2c_unregister(struct saa7134_dev *dev);
535void saa7134_i2c_call_clients(struct saa7134_dev *dev,
536 unsigned int cmd, void *arg);
537
538
539/* ----------------------------------------------------------- */
540/* saa7134-video.c */
541
542extern struct video_device saa7134_video_template;
543extern struct video_device saa7134_radio_template;
544
545int saa7134_common_ioctl(struct saa7134_dev *dev,
546 unsigned int cmd, void *arg);
547
548int saa7134_video_init1(struct saa7134_dev *dev);
549int saa7134_video_init2(struct saa7134_dev *dev);
550int saa7134_video_fini(struct saa7134_dev *dev);
551void saa7134_irq_video_intl(struct saa7134_dev *dev);
552void saa7134_irq_video_done(struct saa7134_dev *dev, unsigned long status);
553
554
555/* ----------------------------------------------------------- */
556/* saa7134-ts.c */
557
558#define TS_PACKET_SIZE 188 /* TS packets 188 bytes */
559
560extern struct videobuf_queue_ops saa7134_ts_qops;
561
562int saa7134_ts_init1(struct saa7134_dev *dev);
563int saa7134_ts_fini(struct saa7134_dev *dev);
564void saa7134_irq_ts_done(struct saa7134_dev *dev, unsigned long status);
565
566int saa7134_ts_register(struct saa7134_mpeg_ops *ops);
567void saa7134_ts_unregister(struct saa7134_mpeg_ops *ops);
568
569/* ----------------------------------------------------------- */
570/* saa7134-vbi.c */
571
572extern struct videobuf_queue_ops saa7134_vbi_qops;
573extern struct video_device saa7134_vbi_template;
574
575int saa7134_vbi_init1(struct saa7134_dev *dev);
576int saa7134_vbi_fini(struct saa7134_dev *dev);
577void saa7134_irq_vbi_done(struct saa7134_dev *dev, unsigned long status);
578
579
580/* ----------------------------------------------------------- */
581/* saa7134-tvaudio.c */
582
583int saa7134_tvaudio_rx2mode(u32 rx);
584
585void saa7134_tvaudio_setmute(struct saa7134_dev *dev);
586void saa7134_tvaudio_setinput(struct saa7134_dev *dev,
587 struct saa7134_input *in);
588void saa7134_tvaudio_setvolume(struct saa7134_dev *dev, int level);
589int saa7134_tvaudio_getstereo(struct saa7134_dev *dev);
590
591int saa7134_tvaudio_init2(struct saa7134_dev *dev);
592int saa7134_tvaudio_fini(struct saa7134_dev *dev);
593int saa7134_tvaudio_do_scan(struct saa7134_dev *dev);
594
595int saa_dsp_writel(struct saa7134_dev *dev, int reg, u32 value);
596
597/* ----------------------------------------------------------- */
598/* saa7134-oss.c */
599
600extern struct file_operations saa7134_dsp_fops;
601extern struct file_operations saa7134_mixer_fops;
602
603int saa7134_oss_init1(struct saa7134_dev *dev);
604int saa7134_oss_fini(struct saa7134_dev *dev);
605void saa7134_irq_oss_done(struct saa7134_dev *dev, unsigned long status);
606
607/* ----------------------------------------------------------- */
608/* saa7134-input.c */
609
610int saa7134_input_init1(struct saa7134_dev *dev);
611void saa7134_input_fini(struct saa7134_dev *dev);
612void saa7134_input_irq(struct saa7134_dev *dev);
613
614/*
615 * Local variables:
616 * c-basic-offset: 8
617 * End:
618 */
diff --git a/drivers/media/video/saa7146.h b/drivers/media/video/saa7146.h
new file mode 100644
index 00000000000..f305ec802ea
--- /dev/null
+++ b/drivers/media/video/saa7146.h
@@ -0,0 +1,115 @@
1/*
2 saa7146.h - definitions philips saa7146 based cards
3 Copyright (C) 1999 Nathan Laredo (laredo@gnu.org)
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18*/
19
20#ifndef __SAA7146__
21#define __SAA7146__
22
23#define SAA7146_VERSION_CODE 0x000101
24
25#include <linux/types.h>
26#include <linux/wait.h>
27
28#include <linux/videodev.h>
29
30#ifndef O_NONCAP
31#define O_NONCAP O_TRUNC
32#endif
33
34#define MAX_GBUFFERS 2
35#define FBUF_SIZE 0x190000
36
37#ifdef __KERNEL__
38
39struct saa7146_window
40{
41 int x, y;
42 ushort width, height;
43 ushort bpp, bpl;
44 ushort swidth, sheight;
45 short cropx, cropy;
46 ushort cropwidth, cropheight;
47 unsigned long vidadr;
48 int color_fmt;
49 ushort depth;
50};
51
52/* Per-open data for handling multiple opens on one device */
53struct device_open
54{
55 int isopen;
56 int noncapturing;
57 struct saa7146 *dev;
58};
59#define MAX_OPENS 3
60
61struct saa7146
62{
63 struct video_device video_dev;
64 struct video_picture picture;
65 struct video_audio audio_dev;
66 struct video_info vidinfo;
67 int user;
68 int cap;
69 int capuser;
70 int irqstate; /* irq routine is state driven */
71 int writemode;
72 int playmode;
73 unsigned int nr;
74 unsigned long irq; /* IRQ used by SAA7146 card */
75 unsigned short id;
76 struct pci_dev *dev;
77 unsigned char revision;
78 unsigned char boardcfg[64]; /* 64 bytes of config from eeprom */
79 unsigned long saa7146_adr; /* bus address of IO mem from PCI BIOS */
80 struct saa7146_window win;
81 unsigned char __iomem *saa7146_mem; /* pointer to mapped IO memory */
82 struct device_open open_data[MAX_OPENS];
83#define MAX_MARKS 16
84 /* for a/v sync */
85 int endmark[MAX_MARKS], endmarkhead, endmarktail;
86 u32 *dmaRPS1, *pageRPS1, *dmaRPS2, *pageRPS2, *dmavid1, *dmavid2,
87 *dmavid3, *dmaa1in, *dmaa1out, *dmaa2in, *dmaa2out,
88 *pagedebi, *pagevid1, *pagevid2, *pagevid3, *pagea1in,
89 *pagea1out, *pagea2in, *pagea2out;
90 wait_queue_head_t i2cq, debiq, audq, vidq;
91 u8 *vidbuf, *audbuf, *osdbuf, *dmadebi;
92 int audhead, vidhead, osdhead, audtail, vidtail, osdtail;
93 spinlock_t lock; /* the device lock */
94};
95#endif
96
97#ifdef _ALPHA_SAA7146
98#define saawrite(dat,adr) writel((dat), saa->saa7146_adr+(adr))
99#define saaread(adr) readl(saa->saa7146_adr+(adr))
100#else
101#define saawrite(dat,adr) writel((dat), saa->saa7146_mem+(adr))
102#define saaread(adr) readl(saa->saa7146_mem+(adr))
103#endif
104
105#define saaand(dat,adr) saawrite((dat) & saaread(adr), adr)
106#define saaor(dat,adr) saawrite((dat) | saaread(adr), adr)
107#define saaaor(dat,mask,adr) saawrite((dat) | ((mask) & saaread(adr)), adr)
108
109/* bitmask of attached hardware found */
110#define SAA7146_UNKNOWN 0x00000000
111#define SAA7146_SAA7111 0x00000001
112#define SAA7146_SAA7121 0x00000002
113#define SAA7146_IBMMPEG 0x00000004
114
115#endif
diff --git a/drivers/media/video/saa7146reg.h b/drivers/media/video/saa7146reg.h
new file mode 100644
index 00000000000..6cc910f50a4
--- /dev/null
+++ b/drivers/media/video/saa7146reg.h
@@ -0,0 +1,283 @@
1/*
2 saa7146.h - definitions philips saa7146 based cards
3 Copyright (C) 1999 Nathan Laredo (laredo@gnu.org)
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18*/
19
20#ifndef __SAA7146_REG__
21#define __SAA7146_REG__
22#define SAA7146_BASE_ODD1 0x00
23#define SAA7146_BASE_EVEN1 0x04
24#define SAA7146_PROT_ADDR1 0x08
25#define SAA7146_PITCH1 0x0c
26#define SAA7146_PAGE1 0x10
27#define SAA7146_NUM_LINE_BYTE1 0x14
28#define SAA7146_BASE_ODD2 0x18
29#define SAA7146_BASE_EVEN2 0x1c
30#define SAA7146_PROT_ADDR2 0x20
31#define SAA7146_PITCH2 0x24
32#define SAA7146_PAGE2 0x28
33#define SAA7146_NUM_LINE_BYTE2 0x2c
34#define SAA7146_BASE_ODD3 0x30
35#define SAA7146_BASE_EVEN3 0x34
36#define SAA7146_PROT_ADDR3 0x38
37#define SAA7146_PITCH3 0x3c
38#define SAA7146_PAGE3 0x40
39#define SAA7146_NUM_LINE_BYTE3 0x44
40#define SAA7146_PCI_BT_V1 0x48
41#define SAA7146_PCI_BT_V2 0x49
42#define SAA7146_PCI_BT_V3 0x4a
43#define SAA7146_PCI_BT_DEBI 0x4b
44#define SAA7146_PCI_BT_A 0x4c
45#define SAA7146_DD1_INIT 0x50
46#define SAA7146_DD1_STREAM_B 0x54
47#define SAA7146_DD1_STREAM_A 0x56
48#define SAA7146_BRS_CTRL 0x58
49#define SAA7146_HPS_CTRL 0x5c
50#define SAA7146_HPS_V_SCALE 0x60
51#define SAA7146_HPS_V_GAIN 0x64
52#define SAA7146_HPS_H_PRESCALE 0x68
53#define SAA7146_HPS_H_SCALE 0x6c
54#define SAA7146_BCS_CTRL 0x70
55#define SAA7146_CHROMA_KEY_RANGE 0x74
56#define SAA7146_CLIP_FORMAT_CTRL 0x78
57#define SAA7146_DEBI_CONFIG 0x7c
58#define SAA7146_DEBI_COMMAND 0x80
59#define SAA7146_DEBI_PAGE 0x84
60#define SAA7146_DEBI_AD 0x88
61#define SAA7146_I2C_TRANSFER 0x8c
62#define SAA7146_I2C_STATUS 0x90
63#define SAA7146_BASE_A1_IN 0x94
64#define SAA7146_PROT_A1_IN 0x98
65#define SAA7146_PAGE_A1_IN 0x9C
66#define SAA7146_BASE_A1_OUT 0xa0
67#define SAA7146_PROT_A1_OUT 0xa4
68#define SAA7146_PAGE_A1_OUT 0xa8
69#define SAA7146_BASE_A2_IN 0xac
70#define SAA7146_PROT_A2_IN 0xb0
71#define SAA7146_PAGE_A2_IN 0xb4
72#define SAA7146_BASE_A2_OUT 0xb8
73#define SAA7146_PROT_A2_OUT 0xbc
74#define SAA7146_PAGE_A2_OUT 0xc0
75#define SAA7146_RPS_PAGE0 0xc4
76#define SAA7146_RPS_PAGE1 0xc8
77#define SAA7146_RPS_THRESH0 0xcc
78#define SAA7146_RPS_THRESH1 0xd0
79#define SAA7146_RPS_TOV0 0xd4
80#define SAA7146_RPS_TOV1 0xd8
81#define SAA7146_IER 0xdc
82#define SAA7146_GPIO_CTRL 0xe0
83#define SAA7146_EC1SSR 0xe4
84#define SAA7146_EC2SSR 0xe8
85#define SAA7146_ECT1R 0xec
86#define SAA7146_ECT2R 0xf0
87#define SAA7146_ACON1 0xf4
88#define SAA7146_ACON2 0xf8
89#define SAA7146_MC1 0xfc
90#define SAA7146_MC2 0x100
91#define SAA7146_RPS_ADDR0 0x104
92#define SAA7146_RPS_ADDR1 0x108
93#define SAA7146_ISR 0x10c
94#define SAA7146_PSR 0x110
95#define SAA7146_SSR 0x114
96#define SAA7146_EC1R 0x118
97#define SAA7146_EC2R 0x11c
98#define SAA7146_VDP1 0x120
99#define SAA7146_VDP2 0x124
100#define SAA7146_VDP3 0x128
101#define SAA7146_ADP1 0x12c
102#define SAA7146_ADP2 0x130
103#define SAA7146_ADP3 0x134
104#define SAA7146_ADP4 0x138
105#define SAA7146_DDP 0x13c
106#define SAA7146_LEVEL_REP 0x140
107#define SAA7146_FB_BUFFER1 0x144
108#define SAA7146_FB_BUFFER2 0x148
109#define SAA7146_A_TIME_SLOT1 0x180
110#define SAA7146_A_TIME_SLOT2 0x1C0
111
112/* bitfield defines */
113#define MASK_31 0x80000000
114#define MASK_30 0x40000000
115#define MASK_29 0x20000000
116#define MASK_28 0x10000000
117#define MASK_27 0x08000000
118#define MASK_26 0x04000000
119#define MASK_25 0x02000000
120#define MASK_24 0x01000000
121#define MASK_23 0x00800000
122#define MASK_22 0x00400000
123#define MASK_21 0x00200000
124#define MASK_20 0x00100000
125#define MASK_19 0x00080000
126#define MASK_18 0x00040000
127#define MASK_17 0x00020000
128#define MASK_16 0x00010000
129#define MASK_15 0x00008000
130#define MASK_14 0x00004000
131#define MASK_13 0x00002000
132#define MASK_12 0x00001000
133#define MASK_11 0x00000800
134#define MASK_10 0x00000400
135#define MASK_09 0x00000200
136#define MASK_08 0x00000100
137#define MASK_07 0x00000080
138#define MASK_06 0x00000040
139#define MASK_05 0x00000020
140#define MASK_04 0x00000010
141#define MASK_03 0x00000008
142#define MASK_02 0x00000004
143#define MASK_01 0x00000002
144#define MASK_00 0x00000001
145#define MASK_B0 0x000000ff
146#define MASK_B1 0x0000ff00
147#define MASK_B2 0x00ff0000
148#define MASK_B3 0xff000000
149#define MASK_W0 0x0000ffff
150#define MASK_W1 0xffff0000
151#define MASK_PA 0xfffffffc
152#define MASK_PR 0xfffffffe
153#define MASK_ER 0xffffffff
154#define MASK_NONE 0x00000000
155
156#define SAA7146_PAGE_MAP_EN MASK_11
157/* main control register 1 */
158#define SAA7146_MC1_MRST_N MASK_15
159#define SAA7146_MC1_ERPS1 MASK_13
160#define SAA7146_MC1_ERPS0 MASK_12
161#define SAA7146_MC1_EDP MASK_11
162#define SAA7146_MC1_EVP MASK_10
163#define SAA7146_MC1_EAP MASK_09
164#define SAA7146_MC1_EI2C MASK_08
165#define SAA7146_MC1_TR_E_DEBI MASK_07
166#define SAA7146_MC1_TR_E_1 MASK_06
167#define SAA7146_MC1_TR_E_2 MASK_05
168#define SAA7146_MC1_TR_E_3 MASK_04
169#define SAA7146_MC1_TR_E_A2_OUT MASK_03
170#define SAA7146_MC1_TR_E_A2_IN MASK_02
171#define SAA7146_MC1_TR_E_A1_OUT MASK_01
172#define SAA7146_MC1_TR_E_A1_IN MASK_00
173/* main control register 2 */
174#define SAA7146_MC2_RPS_SIG4 MASK_15
175#define SAA7146_MC2_RPS_SIG3 MASK_14
176#define SAA7146_MC2_RPS_SIG2 MASK_13
177#define SAA7146_MC2_RPS_SIG1 MASK_12
178#define SAA7146_MC2_RPS_SIG0 MASK_11
179#define SAA7146_MC2_UPLD_D1_B MASK_10
180#define SAA7146_MC2_UPLD_D1_A MASK_09
181#define SAA7146_MC2_UPLD_BRS MASK_08
182#define SAA7146_MC2_UPLD_HPS_H MASK_06
183#define SAA7146_MC2_UPLD_HPS_V MASK_05
184#define SAA7146_MC2_UPLD_DMA3 MASK_04
185#define SAA7146_MC2_UPLD_DMA2 MASK_03
186#define SAA7146_MC2_UPLD_DMA1 MASK_02
187#define SAA7146_MC2_UPLD_DEBI MASK_01
188#define SAA7146_MC2_UPLD_I2C MASK_00
189/* Primary Status Register and Interrupt Enable/Status Registers */
190#define SAA7146_PSR_PPEF MASK_31
191#define SAA7146_PSR_PABO MASK_30
192#define SAA7146_PSR_PPED MASK_29
193#define SAA7146_PSR_RPS_I1 MASK_28
194#define SAA7146_PSR_RPS_I0 MASK_27
195#define SAA7146_PSR_RPS_LATE1 MASK_26
196#define SAA7146_PSR_RPS_LATE0 MASK_25
197#define SAA7146_PSR_RPS_E1 MASK_24
198#define SAA7146_PSR_RPS_E0 MASK_23
199#define SAA7146_PSR_RPS_TO1 MASK_22
200#define SAA7146_PSR_RPS_TO0 MASK_21
201#define SAA7146_PSR_UPLD MASK_20
202#define SAA7146_PSR_DEBI_S MASK_19
203#define SAA7146_PSR_DEBI_E MASK_18
204#define SAA7146_PSR_I2C_S MASK_17
205#define SAA7146_PSR_I2C_E MASK_16
206#define SAA7146_PSR_A2_IN MASK_15
207#define SAA7146_PSR_A2_OUT MASK_14
208#define SAA7146_PSR_A1_IN MASK_13
209#define SAA7146_PSR_A1_OUT MASK_12
210#define SAA7146_PSR_AFOU MASK_11
211#define SAA7146_PSR_V_PE MASK_10
212#define SAA7146_PSR_VFOU MASK_09
213#define SAA7146_PSR_FIDA MASK_08
214#define SAA7146_PSR_FIDB MASK_07
215#define SAA7146_PSR_PIN3 MASK_06
216#define SAA7146_PSR_PIN2 MASK_05
217#define SAA7146_PSR_PIN1 MASK_04
218#define SAA7146_PSR_PIN0 MASK_03
219#define SAA7146_PSR_ECS MASK_02
220#define SAA7146_PSR_EC3S MASK_01
221#define SAA7146_PSR_EC0S MASK_00
222/* Secondary Status Register */
223#define SAA7146_SSR_PRQ MASK_31
224#define SAA7146_SSR_PMA MASK_30
225#define SAA7146_SSR_RPS_RE1 MASK_29
226#define SAA7146_SSR_RPS_PE1 MASK_28
227#define SAA7146_SSR_RPS_A1 MASK_27
228#define SAA7146_SSR_RPS_RE0 MASK_26
229#define SAA7146_SSR_RPS_PE0 MASK_25
230#define SAA7146_SSR_RPS_A0 MASK_24
231#define SAA7146_SSR_DEBI_TO MASK_23
232#define SAA7146_SSR_DEBI_EF MASK_22
233#define SAA7146_SSR_I2C_EA MASK_21
234#define SAA7146_SSR_I2C_EW MASK_20
235#define SAA7146_SSR_I2C_ER MASK_19
236#define SAA7146_SSR_I2C_EL MASK_18
237#define SAA7146_SSR_I2C_EF MASK_17
238#define SAA7146_SSR_V3P MASK_16
239#define SAA7146_SSR_V2P MASK_15
240#define SAA7146_SSR_V1P MASK_14
241#define SAA7146_SSR_VF3 MASK_13
242#define SAA7146_SSR_VF2 MASK_12
243#define SAA7146_SSR_VF1 MASK_11
244#define SAA7146_SSR_AF2_IN MASK_10
245#define SAA7146_SSR_AF2_OUT MASK_09
246#define SAA7146_SSR_AF1_IN MASK_08
247#define SAA7146_SSR_AF1_OUT MASK_07
248#define SAA7146_SSR_VGT MASK_05
249#define SAA7146_SSR_LNQG MASK_04
250#define SAA7146_SSR_EC5S MASK_03
251#define SAA7146_SSR_EC4S MASK_02
252#define SAA7146_SSR_EC2S MASK_01
253#define SAA7146_SSR_EC1S MASK_00
254/* I2C status register */
255#define SAA7146_I2C_ABORT MASK_07
256#define SAA7146_I2C_SPERR MASK_06
257#define SAA7146_I2C_APERR MASK_05
258#define SAA7146_I2C_DTERR MASK_04
259#define SAA7146_I2C_DRERR MASK_03
260#define SAA7146_I2C_AL MASK_02
261#define SAA7146_I2C_ERR MASK_01
262#define SAA7146_I2C_BUSY MASK_00
263/* output formats */
264#define SAA7146_YUV422 0
265#define SAA7146_RGB16 0
266#define SAA7146_YUV444 1
267#define SAA7146_RGB24 1
268#define SAA7146_ARGB32 2
269#define SAA7146_YUV411 3
270#define SAA7146_ARGB15 3
271#define SAA7146_YUV2 4
272#define SAA7146_RGAB15 4
273#define SAA7146_Y8 6
274#define SAA7146_YUV8 7
275#define SAA7146_RGB8 7
276#define SAA7146_YUV444p 8
277#define SAA7146_YUV422p 9
278#define SAA7146_YUV420p 10
279#define SAA7146_YUV1620 11
280#define SAA7146_Y1 13
281#define SAA7146_Y2 14
282#define SAA7146_YUV1 15
283#endif
diff --git a/drivers/media/video/saa7185.c b/drivers/media/video/saa7185.c
new file mode 100644
index 00000000000..5f0b224c3cb
--- /dev/null
+++ b/drivers/media/video/saa7185.c
@@ -0,0 +1,524 @@
1/*
2 * saa7185 - Philips SAA7185B video encoder driver version 0.0.3
3 *
4 * Copyright (C) 1998 Dave Perks <dperks@ibm.net>
5 *
6 * Slight changes for video timing and attachment output by
7 * Wolfgang Scherr <scherr@net4you.net>
8 *
9 * Changes by Ronald Bultje <rbultje@ronald.bitfreak.net>
10 * - moved over to linux>=2.4.x i2c protocol (1/1/2003)
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 */
26
27#include <linux/module.h>
28#include <linux/init.h>
29#include <linux/delay.h>
30#include <linux/errno.h>
31#include <linux/fs.h>
32#include <linux/kernel.h>
33#include <linux/major.h>
34#include <linux/slab.h>
35#include <linux/mm.h>
36#include <linux/pci.h>
37#include <linux/signal.h>
38#include <asm/io.h>
39#include <asm/pgtable.h>
40#include <asm/page.h>
41#include <linux/sched.h>
42#include <asm/segment.h>
43#include <linux/types.h>
44
45#include <linux/videodev.h>
46#include <asm/uaccess.h>
47
48MODULE_DESCRIPTION("Philips SAA7185 video encoder driver");
49MODULE_AUTHOR("Dave Perks");
50MODULE_LICENSE("GPL");
51
52#include <linux/i2c.h>
53#include <linux/i2c-dev.h>
54
55#define I2C_NAME(s) (s)->name
56
57#include <linux/video_encoder.h>
58
59static int debug = 0;
60module_param(debug, int, 0);
61MODULE_PARM_DESC(debug, "Debug level (0-1)");
62
63#define dprintk(num, format, args...) \
64 do { \
65 if (debug >= num) \
66 printk(format, ##args); \
67 } while (0)
68
69/* ----------------------------------------------------------------------- */
70
71struct saa7185 {
72 unsigned char reg[128];
73
74 int norm;
75 int enable;
76 int bright;
77 int contrast;
78 int hue;
79 int sat;
80};
81
82#define I2C_SAA7185 0x88
83
84/* ----------------------------------------------------------------------- */
85
86static inline int
87saa7185_read (struct i2c_client *client)
88{
89 return i2c_smbus_read_byte(client);
90}
91
92static int
93saa7185_write (struct i2c_client *client,
94 u8 reg,
95 u8 value)
96{
97 struct saa7185 *encoder = i2c_get_clientdata(client);
98
99 dprintk(1, KERN_DEBUG "SAA7185: %02x set to %02x\n", reg, value);
100 encoder->reg[reg] = value;
101 return i2c_smbus_write_byte_data(client, reg, value);
102}
103
104static int
105saa7185_write_block (struct i2c_client *client,
106 const u8 *data,
107 unsigned int len)
108{
109 int ret = -1;
110 u8 reg;
111
112 /* the adv7175 has an autoincrement function, use it if
113 * the adapter understands raw I2C */
114 if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
115 /* do raw I2C, not smbus compatible */
116 struct saa7185 *encoder = i2c_get_clientdata(client);
117 struct i2c_msg msg;
118 u8 block_data[32];
119
120 msg.addr = client->addr;
121 msg.flags = 0;
122 while (len >= 2) {
123 msg.buf = (char *) block_data;
124 msg.len = 0;
125 block_data[msg.len++] = reg = data[0];
126 do {
127 block_data[msg.len++] =
128 encoder->reg[reg++] = data[1];
129 len -= 2;
130 data += 2;
131 } while (len >= 2 && data[0] == reg &&
132 msg.len < 32);
133 if ((ret = i2c_transfer(client->adapter,
134 &msg, 1)) < 0)
135 break;
136 }
137 } else {
138 /* do some slow I2C emulation kind of thing */
139 while (len >= 2) {
140 reg = *data++;
141 if ((ret = saa7185_write(client, reg,
142 *data++)) < 0)
143 break;
144 len -= 2;
145 }
146 }
147
148 return ret;
149}
150
151/* ----------------------------------------------------------------------- */
152
153static const unsigned char init_common[] = {
154 0x3a, 0x0f, /* CBENB=0, V656=0, VY2C=1,
155 * YUV2C=1, MY2C=1, MUV2C=1 */
156
157 0x42, 0x6b, /* OVLY0=107 */
158 0x43, 0x00, /* OVLU0=0 white */
159 0x44, 0x00, /* OVLV0=0 */
160 0x45, 0x22, /* OVLY1=34 */
161 0x46, 0xac, /* OVLU1=172 yellow */
162 0x47, 0x0e, /* OVLV1=14 */
163 0x48, 0x03, /* OVLY2=3 */
164 0x49, 0x1d, /* OVLU2=29 cyan */
165 0x4a, 0xac, /* OVLV2=172 */
166 0x4b, 0xf0, /* OVLY3=240 */
167 0x4c, 0xc8, /* OVLU3=200 green */
168 0x4d, 0xb9, /* OVLV3=185 */
169 0x4e, 0xd4, /* OVLY4=212 */
170 0x4f, 0x38, /* OVLU4=56 magenta */
171 0x50, 0x47, /* OVLV4=71 */
172 0x51, 0xc1, /* OVLY5=193 */
173 0x52, 0xe3, /* OVLU5=227 red */
174 0x53, 0x54, /* OVLV5=84 */
175 0x54, 0xa3, /* OVLY6=163 */
176 0x55, 0x54, /* OVLU6=84 blue */
177 0x56, 0xf2, /* OVLV6=242 */
178 0x57, 0x90, /* OVLY7=144 */
179 0x58, 0x00, /* OVLU7=0 black */
180 0x59, 0x00, /* OVLV7=0 */
181
182 0x5a, 0x00, /* CHPS=0 */
183 0x5b, 0x76, /* GAINU=118 */
184 0x5c, 0xa5, /* GAINV=165 */
185 0x5d, 0x3c, /* BLCKL=60 */
186 0x5e, 0x3a, /* BLNNL=58 */
187 0x5f, 0x3a, /* CCRS=0, BLNVB=58 */
188 0x60, 0x00, /* NULL */
189
190 /* 0x61 - 0x66 set according to norm */
191
192 0x67, 0x00, /* 0 : caption 1st byte odd field */
193 0x68, 0x00, /* 0 : caption 2nd byte odd field */
194 0x69, 0x00, /* 0 : caption 1st byte even field */
195 0x6a, 0x00, /* 0 : caption 2nd byte even field */
196
197 0x6b, 0x91, /* MODIN=2, PCREF=0, SCCLN=17 */
198 0x6c, 0x20, /* SRCV1=0, TRCV2=1, ORCV1=0, PRCV1=0,
199 * CBLF=0, ORCV2=0, PRCV2=0 */
200 0x6d, 0x00, /* SRCM1=0, CCEN=0 */
201
202 0x6e, 0x0e, /* HTRIG=0x005, approx. centered, at
203 * least for PAL */
204 0x6f, 0x00, /* HTRIG upper bits */
205 0x70, 0x20, /* PHRES=0, SBLN=1, VTRIG=0 */
206
207 /* The following should not be needed */
208
209 0x71, 0x15, /* BMRQ=0x115 */
210 0x72, 0x90, /* EMRQ=0x690 */
211 0x73, 0x61, /* EMRQ=0x690, BMRQ=0x115 */
212 0x74, 0x00, /* NULL */
213 0x75, 0x00, /* NULL */
214 0x76, 0x00, /* NULL */
215 0x77, 0x15, /* BRCV=0x115 */
216 0x78, 0x90, /* ERCV=0x690 */
217 0x79, 0x61, /* ERCV=0x690, BRCV=0x115 */
218
219 /* Field length controls */
220
221 0x7a, 0x70, /* FLC=0 */
222
223 /* The following should not be needed if SBLN = 1 */
224
225 0x7b, 0x16, /* FAL=22 */
226 0x7c, 0x35, /* LAL=244 */
227 0x7d, 0x20, /* LAL=244, FAL=22 */
228};
229
230static const unsigned char init_pal[] = {
231 0x61, 0x1e, /* FISE=0, PAL=1, SCBW=1, RTCE=1,
232 * YGS=1, INPI=0, DOWN=0 */
233 0x62, 0xc8, /* DECTYP=1, BSTA=72 */
234 0x63, 0xcb, /* FSC0 */
235 0x64, 0x8a, /* FSC1 */
236 0x65, 0x09, /* FSC2 */
237 0x66, 0x2a, /* FSC3 */
238};
239
240static const unsigned char init_ntsc[] = {
241 0x61, 0x1d, /* FISE=1, PAL=0, SCBW=1, RTCE=1,
242 * YGS=1, INPI=0, DOWN=0 */
243 0x62, 0xe6, /* DECTYP=1, BSTA=102 */
244 0x63, 0x1f, /* FSC0 */
245 0x64, 0x7c, /* FSC1 */
246 0x65, 0xf0, /* FSC2 */
247 0x66, 0x21, /* FSC3 */
248};
249
250static int
251saa7185_command (struct i2c_client *client,
252 unsigned int cmd,
253 void *arg)
254{
255 struct saa7185 *encoder = i2c_get_clientdata(client);
256
257 switch (cmd) {
258
259 case 0:
260 saa7185_write_block(client, init_common,
261 sizeof(init_common));
262 switch (encoder->norm) {
263
264 case VIDEO_MODE_NTSC:
265 saa7185_write_block(client, init_ntsc,
266 sizeof(init_ntsc));
267 break;
268
269 case VIDEO_MODE_PAL:
270 saa7185_write_block(client, init_pal,
271 sizeof(init_pal));
272 break;
273 }
274
275 break;
276
277 case ENCODER_GET_CAPABILITIES:
278 {
279 struct video_encoder_capability *cap = arg;
280
281 cap->flags =
282 VIDEO_ENCODER_PAL | VIDEO_ENCODER_NTSC |
283 VIDEO_ENCODER_SECAM | VIDEO_ENCODER_CCIR;
284 cap->inputs = 1;
285 cap->outputs = 1;
286 }
287 break;
288
289 case ENCODER_SET_NORM:
290 {
291 int *iarg = arg;
292
293 //saa7185_write_block(client, init_common, sizeof(init_common));
294
295 switch (*iarg) {
296
297 case VIDEO_MODE_NTSC:
298 saa7185_write_block(client, init_ntsc,
299 sizeof(init_ntsc));
300 break;
301
302 case VIDEO_MODE_PAL:
303 saa7185_write_block(client, init_pal,
304 sizeof(init_pal));
305 break;
306
307 case VIDEO_MODE_SECAM:
308 default:
309 return -EINVAL;
310
311 }
312 encoder->norm = *iarg;
313 }
314 break;
315
316 case ENCODER_SET_INPUT:
317 {
318 int *iarg = arg;
319
320 /* RJ: *iarg = 0: input is from SA7111
321 *iarg = 1: input is from ZR36060 */
322
323 switch (*iarg) {
324
325 case 0:
326 /* Switch RTCE to 1 */
327 saa7185_write(client, 0x61,
328 (encoder->reg[0x61] & 0xf7) | 0x08);
329 saa7185_write(client, 0x6e, 0x01);
330 break;
331
332 case 1:
333 /* Switch RTCE to 0 */
334 saa7185_write(client, 0x61,
335 (encoder->reg[0x61] & 0xf7) | 0x00);
336 /* SW: a slight sync problem... */
337 saa7185_write(client, 0x6e, 0x00);
338 break;
339
340 default:
341 return -EINVAL;
342
343 }
344 }
345 break;
346
347 case ENCODER_SET_OUTPUT:
348 {
349 int *iarg = arg;
350
351 /* not much choice of outputs */
352 if (*iarg != 0) {
353 return -EINVAL;
354 }
355 }
356 break;
357
358 case ENCODER_ENABLE_OUTPUT:
359 {
360 int *iarg = arg;
361
362 encoder->enable = !!*iarg;
363 saa7185_write(client, 0x61,
364 (encoder->reg[0x61] & 0xbf) |
365 (encoder->enable ? 0x00 : 0x40));
366 }
367 break;
368
369 default:
370 return -EINVAL;
371 }
372
373 return 0;
374}
375
376/* ----------------------------------------------------------------------- */
377
378/*
379 * Generic i2c probe
380 * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
381 */
382static unsigned short normal_i2c[] = { I2C_SAA7185 >> 1, I2C_CLIENT_END };
383static unsigned short normal_i2c_range[] = { I2C_CLIENT_END };
384
385static unsigned short probe[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
386static unsigned short probe_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
387static unsigned short ignore[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
388static unsigned short ignore_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
389static unsigned short force[2] = { I2C_CLIENT_END , I2C_CLIENT_END };
390
391static struct i2c_client_address_data addr_data = {
392 .normal_i2c = normal_i2c,
393 .normal_i2c_range = normal_i2c_range,
394 .probe = probe,
395 .probe_range = probe_range,
396 .ignore = ignore,
397 .ignore_range = ignore_range,
398 .force = force
399};
400
401static struct i2c_driver i2c_driver_saa7185;
402
403static int
404saa7185_detect_client (struct i2c_adapter *adapter,
405 int address,
406 int kind)
407{
408 int i;
409 struct i2c_client *client;
410 struct saa7185 *encoder;
411
412 dprintk(1,
413 KERN_INFO
414 "saa7185.c: detecting saa7185 client on address 0x%x\n",
415 address << 1);
416
417 /* Check if the adapter supports the needed features */
418 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
419 return 0;
420
421 client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
422 if (client == 0)
423 return -ENOMEM;
424 memset(client, 0, sizeof(struct i2c_client));
425 client->addr = address;
426 client->adapter = adapter;
427 client->driver = &i2c_driver_saa7185;
428 client->flags = I2C_CLIENT_ALLOW_USE;
429 strlcpy(I2C_NAME(client), "saa7185", sizeof(I2C_NAME(client)));
430
431 encoder = kmalloc(sizeof(struct saa7185), GFP_KERNEL);
432 if (encoder == NULL) {
433 kfree(client);
434 return -ENOMEM;
435 }
436 memset(encoder, 0, sizeof(struct saa7185));
437 encoder->norm = VIDEO_MODE_NTSC;
438 encoder->enable = 1;
439 i2c_set_clientdata(client, encoder);
440
441 i = i2c_attach_client(client);
442 if (i) {
443 kfree(client);
444 kfree(encoder);
445 return i;
446 }
447
448 i = saa7185_write_block(client, init_common, sizeof(init_common));
449 if (i >= 0) {
450 i = saa7185_write_block(client, init_ntsc,
451 sizeof(init_ntsc));
452 }
453 if (i < 0) {
454 dprintk(1, KERN_ERR "%s_attach: init error %d\n",
455 I2C_NAME(client), i);
456 } else {
457 dprintk(1,
458 KERN_INFO
459 "%s_attach: chip version %d at address 0x%x\n",
460 I2C_NAME(client), saa7185_read(client) >> 5,
461 client->addr << 1);
462 }
463
464 return 0;
465}
466
467static int
468saa7185_attach_adapter (struct i2c_adapter *adapter)
469{
470 dprintk(1,
471 KERN_INFO
472 "saa7185.c: starting probe for adapter %s (0x%x)\n",
473 I2C_NAME(adapter), adapter->id);
474 return i2c_probe(adapter, &addr_data, &saa7185_detect_client);
475}
476
477static int
478saa7185_detach_client (struct i2c_client *client)
479{
480 struct saa7185 *encoder = i2c_get_clientdata(client);
481 int err;
482
483 err = i2c_detach_client(client);
484 if (err) {
485 return err;
486 }
487
488 saa7185_write(client, 0x61, (encoder->reg[0x61]) | 0x40); /* SW: output off is active */
489 //saa7185_write(client, 0x3a, (encoder->reg[0x3a]) | 0x80); /* SW: color bar */
490
491 kfree(encoder);
492 kfree(client);
493
494 return 0;
495}
496
497/* ----------------------------------------------------------------------- */
498
499static struct i2c_driver i2c_driver_saa7185 = {
500 .owner = THIS_MODULE,
501 .name = "saa7185", /* name */
502
503 .id = I2C_DRIVERID_SAA7185B,
504 .flags = I2C_DF_NOTIFY,
505
506 .attach_adapter = saa7185_attach_adapter,
507 .detach_client = saa7185_detach_client,
508 .command = saa7185_command,
509};
510
511static int __init
512saa7185_init (void)
513{
514 return i2c_add_driver(&i2c_driver_saa7185);
515}
516
517static void __exit
518saa7185_exit (void)
519{
520 i2c_del_driver(&i2c_driver_saa7185);
521}
522
523module_init(saa7185_init);
524module_exit(saa7185_exit);
diff --git a/drivers/media/video/saa7196.h b/drivers/media/video/saa7196.h
new file mode 100644
index 00000000000..f92f21cfbca
--- /dev/null
+++ b/drivers/media/video/saa7196.h
@@ -0,0 +1,117 @@
1/*
2 Definitions for the Philips SAA7196 digital video decoder,
3 scaler, and clock generator circuit (DESCpro), as used in
4 the PlanB video input of the Powermac 7x00/8x00 series.
5
6 Copyright (C) 1998 Michel Lanners (mlan@cpu.lu)
7
8 The register defines are shamelessly copied from the meteor
9 driver out of NetBSD (with permission),
10 and are copyrighted (c) 1995 Mark Tinguely and Jim Lowe
11 (Thanks !)
12
13 Additional debugging and coding by Takashi Oe (toe@unlinfo.unl.edu)
14
15 The default values used for PlanB are my mistakes.
16*/
17
18/* $Id: saa7196.h,v 1.5 1999/03/26 23:28:47 mlan Exp $ */
19
20#ifndef _SAA7196_H_
21#define _SAA7196_H_
22
23#define SAA7196_NUMREGS 0x31 /* Number of registers (used)*/
24#define NUM_SUPPORTED_NORM 3 /* Number of supported norms by PlanB */
25
26/* Decoder part: */
27#define SAA7196_IDEL 0x00 /* Increment delay */
28#define SAA7196_HSB5 0x01 /* H-sync begin; 50 hz */
29#define SAA7196_HSS5 0x02 /* H-sync stop; 50 hz */
30#define SAA7196_HCB5 0x03 /* H-clamp begin; 50 hz */
31#define SAA7196_HCS5 0x04 /* H-clamp stop; 50 hz */
32#define SAA7196_HSP5 0x05 /* H-sync after PHI1; 50 hz */
33#define SAA7196_LUMC 0x06 /* Luminance control */
34#define SAA7196_HUEC 0x07 /* Hue control */
35#define SAA7196_CKTQ 0x08 /* Colour Killer Threshold QAM (PAL, NTSC) */
36#define SAA7196_CKTS 0x09 /* Colour Killer Threshold SECAM */
37#define SAA7196_PALS 0x0a /* PAL switch sensitivity */
38#define SAA7196_SECAMS 0x0b /* SECAM switch sensitivity */
39#define SAA7196_CGAINC 0x0c /* Chroma gain control */
40#define SAA7196_STDC 0x0d /* Standard/Mode control */
41#define SAA7196_IOCC 0x0e /* I/O and Clock Control */
42#define SAA7196_CTRL1 0x0f /* Control #1 */
43#define SAA7196_CTRL2 0x10 /* Control #2 */
44#define SAA7196_CGAINR 0x11 /* Chroma Gain Reference */
45#define SAA7196_CSAT 0x12 /* Chroma Saturation */
46#define SAA7196_CONT 0x13 /* Luminance Contrast */
47#define SAA7196_HSB6 0x14 /* H-sync begin; 60 hz */
48#define SAA7196_HSS6 0x15 /* H-sync stop; 60 hz */
49#define SAA7196_HCB6 0x16 /* H-clamp begin; 60 hz */
50#define SAA7196_HCS6 0x17 /* H-clamp stop; 60 hz */
51#define SAA7196_HSP6 0x18 /* H-sync after PHI1; 60 hz */
52#define SAA7196_BRIG 0x19 /* Luminance Brightness */
53
54/* Scaler part: */
55#define SAA7196_FMTS 0x20 /* Formats and sequence */
56#define SAA7196_OUTPIX 0x21 /* Output data pixel/line */
57#define SAA7196_INPIX 0x22 /* Input data pixel/line */
58#define SAA7196_HWS 0x23 /* Horiz. window start */
59#define SAA7196_HFILT 0x24 /* Horiz. filter */
60#define SAA7196_OUTLINE 0x25 /* Output data lines/field */
61#define SAA7196_INLINE 0x26 /* Input data lines/field */
62#define SAA7196_VWS 0x27 /* Vertical window start */
63#define SAA7196_VYP 0x28 /* AFS/vertical Y processing */
64#define SAA7196_VBS 0x29 /* Vertical Bypass start */
65#define SAA7196_VBCNT 0x2a /* Vertical Bypass count */
66#define SAA7196_VBP 0x2b /* veritcal Bypass Polarity */
67#define SAA7196_VLOW 0x2c /* Colour-keying lower V limit */
68#define SAA7196_VHIGH 0x2d /* Colour-keying upper V limit */
69#define SAA7196_ULOW 0x2e /* Colour-keying lower U limit */
70#define SAA7196_UHIGH 0x2f /* Colour-keying upper U limit */
71#define SAA7196_DPATH 0x30 /* Data path setting */
72
73/* Initialization default values: */
74
75unsigned char saa_regs[NUM_SUPPORTED_NORM][SAA7196_NUMREGS] = {
76
77/* PAL, 768x576 (no scaling), composite video-in */
78/* Decoder: */
79 { 0x50, 0x30, 0x00, 0xe8, 0xb6, 0xe5, 0x63, 0xff,
80 0xfe, 0xf0, 0xfe, 0xe0, 0x20, 0x06, 0x3b, 0x98,
81 0x00, 0x59, 0x41, 0x45, 0x34, 0x0a, 0xf4, 0xd2,
82 0xe9, 0xa2,
83/* Padding */
84 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
85/* Scaler: */
86 0x72, 0x80, 0x00, 0x03, 0x8d, 0x20, 0x20, 0x12,
87 0xa5, 0x12, 0x00, 0x00, 0x04, 0x00, 0x04, 0x00,
88 0x87 },
89
90/* NTSC, 640x480? (no scaling), composite video-in */
91/* Decoder: */
92 { 0x50, 0x30, 0x00, 0xe8, 0xb6, 0xe5, 0x50, 0x00,
93 0xf8, 0xf0, 0xfe, 0xe0, 0x00, 0x06, 0x3b, 0x98,
94 0x00, 0x2c, 0x3d, 0x40, 0x34, 0x0a, 0xf4, 0xd2,
95 0xe9, 0x98,
96/* Padding */
97 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
98/* Scaler: */
99 0x72, 0x80, 0x80, 0x03, 0x89, 0xf0, 0xf0, 0x0d,
100 0xa0, 0x0d, 0x00, 0x00, 0x04, 0x00, 0x04, 0x00,
101 0x87 },
102
103/* SECAM, 768x576 (no scaling), composite video-in */
104/* Decoder: */
105 { 0x50, 0x30, 0x00, 0xe8, 0xb6, 0xe5, 0x63, 0xff,
106 0xfe, 0xf0, 0xfe, 0xe0, 0x20, 0x07, 0x3b, 0x98,
107 0x00, 0x59, 0x41, 0x45, 0x34, 0x0a, 0xf4, 0xd2,
108 0xe9, 0xa2,
109/* Padding */
110 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
111/* Scaler: */
112 0x72, 0x80, 0x00, 0x03, 0x8d, 0x20, 0x20, 0x12,
113 0xa5, 0x12, 0x00, 0x00, 0x04, 0x00, 0x04, 0x00,
114 0x87 }
115 };
116
117#endif /* _SAA7196_H_ */
diff --git a/drivers/media/video/stradis.c b/drivers/media/video/stradis.c
new file mode 100644
index 00000000000..b5774357108
--- /dev/null
+++ b/drivers/media/video/stradis.c
@@ -0,0 +1,2258 @@
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/mm.h>
30#include <linux/init.h>
31#include <linux/poll.h>
32#include <linux/pci.h>
33#include <linux/signal.h>
34#include <asm/io.h>
35#include <linux/ioport.h>
36#include <asm/pgtable.h>
37#include <asm/page.h>
38#include <linux/sched.h>
39#include <asm/types.h>
40#include <linux/types.h>
41#include <linux/interrupt.h>
42#include <asm/uaccess.h>
43#include <linux/vmalloc.h>
44#include <linux/videodev.h>
45
46#include "saa7146.h"
47#include "saa7146reg.h"
48#include "ibmmpeg2.h"
49#include "saa7121.h"
50#include "cs8420.h"
51
52#define DEBUG(x) /* debug driver */
53#undef IDEBUG /* debug irq handler */
54#undef MDEBUG /* debug memory management */
55
56#define SAA7146_MAX 6
57
58static struct saa7146 saa7146s[SAA7146_MAX];
59
60static int saa_num = 0; /* number of SAA7146s in use */
61
62static int video_nr = -1;
63module_param(video_nr, int, 0);
64MODULE_LICENSE("GPL");
65
66
67#define nDebNormal 0x00480000
68#define nDebNoInc 0x00480000
69#define nDebVideo 0xd0480000
70#define nDebAudio 0xd0400000
71#define nDebDMA 0x02c80000
72
73#define oDebNormal 0x13c80000
74#define oDebNoInc 0x13c80000
75#define oDebVideo 0xd1080000
76#define oDebAudio 0xd1080000
77#define oDebDMA 0x03080000
78
79#define NewCard (saa->boardcfg[3])
80#define ChipControl (saa->boardcfg[1])
81#define NTSCFirstActive (saa->boardcfg[4])
82#define PALFirstActive (saa->boardcfg[5])
83#define NTSCLastActive (saa->boardcfg[54])
84#define PALLastActive (saa->boardcfg[55])
85#define Have2MB (saa->boardcfg[18] & 0x40)
86#define HaveCS8420 (saa->boardcfg[18] & 0x04)
87#define IBMMPEGCD20 (saa->boardcfg[18] & 0x20)
88#define HaveCS3310 (saa->boardcfg[18] & 0x01)
89#define CS3310MaxLvl ((saa->boardcfg[30] << 8) | saa->boardcfg[31])
90#define HaveCS4341 (saa->boardcfg[40] == 2)
91#define SDIType (saa->boardcfg[27])
92#define CurrentMode (saa->boardcfg[2])
93
94#define debNormal (NewCard ? nDebNormal : oDebNormal)
95#define debNoInc (NewCard ? nDebNoInc : oDebNoInc)
96#define debVideo (NewCard ? nDebVideo : oDebVideo)
97#define debAudio (NewCard ? nDebAudio : oDebAudio)
98#define debDMA (NewCard ? nDebDMA : oDebDMA)
99
100#ifdef USE_RESCUE_EEPROM_SDM275
101static unsigned char rescue_eeprom[64] = {
1020x00,0x01,0x04,0x13,0x26,0x0f,0x10,0x00,0x00,0x00,0x43,0x63,0x22,0x01,0x29,0x15,0x73,0x00,0x1f, 'd', 'e', 'c', 'x', 'l', 'd', 'v', 'a',0x02,0x00,0x01,0x00,0xcc,0xa4,0x63,0x09,0xe2,0x10,0x00,0x0a,0x00,0x02,0x02, 'd', 'e', 'c', 'x', 'l', 'a',0x00,0x00,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
103};
104#endif
105
106/* ----------------------------------------------------------------------- */
107/* Hardware I2C functions */
108static void I2CWipe(struct saa7146 *saa)
109{
110 int i;
111 /* set i2c to ~=100kHz, abort transfer, clear busy */
112 saawrite(0x600 | SAA7146_I2C_ABORT, SAA7146_I2C_STATUS);
113 saawrite((SAA7146_MC2_UPLD_I2C << 16) |
114 SAA7146_MC2_UPLD_I2C, SAA7146_MC2);
115 /* wait for i2c registers to be programmed */
116 for (i = 0; i < 1000 &&
117 !(saaread(SAA7146_MC2) & SAA7146_MC2_UPLD_I2C); i++)
118 schedule();
119 saawrite(0x600, 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}
134
135/* read I2C */
136static int I2CRead(struct saa7146 *saa, unsigned char addr,
137 unsigned char subaddr, int dosub)
138{
139 int i;
140
141 if (saaread(SAA7146_I2C_STATUS) & 0x3c)
142 I2CWipe(saa);
143 for (i = 0; i < 1000 &&
144 (saaread(SAA7146_I2C_STATUS) & SAA7146_I2C_BUSY); i++)
145 schedule();
146 if (i == 1000)
147 I2CWipe(saa);
148 if (dosub)
149 saawrite(((addr & 0xfe) << 24) | (((addr | 1) & 0xff) << 8) |
150 ((subaddr & 0xff) << 16) | 0xed, SAA7146_I2C_TRANSFER);
151 else
152 saawrite(((addr & 0xfe) << 24) | (((addr | 1) & 0xff) << 16) |
153 0xf1, SAA7146_I2C_TRANSFER);
154 saawrite((SAA7146_MC2_UPLD_I2C << 16) |
155 SAA7146_MC2_UPLD_I2C, SAA7146_MC2);
156 /* wait for i2c registers to be programmed */
157 for (i = 0; i < 1000 &&
158 !(saaread(SAA7146_MC2) & SAA7146_MC2_UPLD_I2C); i++)
159 schedule();
160 /* wait for valid data */
161 for (i = 0; i < 1000 &&
162 (saaread(SAA7146_I2C_STATUS) & SAA7146_I2C_BUSY); i++)
163 schedule();
164 if (saaread(SAA7146_I2C_STATUS) & SAA7146_I2C_ERR)
165 return -1;
166 if (i == 1000)
167 printk("i2c setup read timeout\n");
168 saawrite(0x41, SAA7146_I2C_TRANSFER);
169 saawrite((SAA7146_MC2_UPLD_I2C << 16) |
170 SAA7146_MC2_UPLD_I2C, SAA7146_MC2);
171 /* wait for i2c registers to be programmed */
172 for (i = 0; i < 1000 &&
173 !(saaread(SAA7146_MC2) & SAA7146_MC2_UPLD_I2C); i++)
174 schedule();
175 /* wait for valid data */
176 for (i = 0; i < 1000 &&
177 (saaread(SAA7146_I2C_TRANSFER) & SAA7146_I2C_BUSY); i++)
178 schedule();
179 if (saaread(SAA7146_I2C_TRANSFER) & SAA7146_I2C_ERR)
180 return -1;
181 if (i == 1000)
182 printk("i2c read timeout\n");
183 return ((saaread(SAA7146_I2C_TRANSFER) >> 24) & 0xff);
184}
185
186/* set both to write both bytes, reset it to write only b1 */
187
188static int I2CWrite(struct saa7146 *saa, unsigned char addr, unsigned char b1,
189 unsigned char b2, int both)
190{
191 int i;
192 u32 data;
193
194 if (saaread(SAA7146_I2C_STATUS) & 0x3c)
195 I2CWipe(saa);
196 for (i = 0; i < 1000 &&
197 (saaread(SAA7146_I2C_STATUS) & SAA7146_I2C_BUSY); i++)
198 schedule();
199 if (i == 1000)
200 I2CWipe(saa);
201 data = ((addr & 0xfe) << 24) | ((b1 & 0xff) << 16);
202 if (both)
203 data |= ((b2 & 0xff) << 8) | 0xe5;
204 else
205 data |= 0xd1;
206 saawrite(data, SAA7146_I2C_TRANSFER);
207 saawrite((SAA7146_MC2_UPLD_I2C << 16) | SAA7146_MC2_UPLD_I2C,
208 SAA7146_MC2);
209 return 0;
210}
211
212static void attach_inform(struct saa7146 *saa, int id)
213{
214 int i;
215
216 DEBUG(printk(KERN_DEBUG "stradis%d: i2c: device found=%02x\n", saa->nr, id));
217 if (id == 0xa0) { /* we have rev2 or later board, fill in info */
218 for (i = 0; i < 64; i++)
219 saa->boardcfg[i] = I2CRead(saa, 0xa0, i, 1);
220#ifdef USE_RESCUE_EEPROM_SDM275
221 if (saa->boardcfg[0] != 0) {
222 printk("stradis%d: WARNING: EEPROM STORED VALUES HAVE BEEN IGNORED\n", saa->nr);
223 for (i = 0; i < 64; i++)
224 saa->boardcfg[i] = rescue_eeprom[i];
225 }
226#endif
227 printk("stradis%d: config =", saa->nr);
228 for (i = 0; i < 51; i++) {
229 printk(" %02x",saa->boardcfg[i]);
230 }
231 printk("\n");
232 }
233}
234
235static void I2CBusScan(struct saa7146 *saa)
236{
237 int i;
238 for (i = 0; i < 0xff; i += 2)
239 if ((I2CRead(saa, i, 0, 0)) >= 0)
240 attach_inform(saa, i);
241}
242
243static int debiwait_maxwait = 0;
244
245static int wait_for_debi_done(struct saa7146 *saa)
246{
247 int i;
248
249 /* wait for registers to be programmed */
250 for (i = 0; i < 100000 &&
251 !(saaread(SAA7146_MC2) & SAA7146_MC2_UPLD_DEBI); i++)
252 saaread(SAA7146_MC2);
253 /* wait for transfer to complete */
254 for (i = 0; i < 500000 &&
255 (saaread(SAA7146_PSR) & SAA7146_PSR_DEBI_S); i++)
256 saaread(SAA7146_MC2);
257 if (i > debiwait_maxwait)
258 printk("wait-for-debi-done maxwait: %d\n",
259 debiwait_maxwait = i);
260
261 if (i == 500000)
262 return -1;
263 return 0;
264}
265
266static int debiwrite(struct saa7146 *saa, u32 config, int addr,
267 u32 val, int count)
268{
269 u32 cmd;
270 if (count <= 0 || count > 32764)
271 return -1;
272 if (wait_for_debi_done(saa) < 0)
273 return -1;
274 saawrite(config, SAA7146_DEBI_CONFIG);
275 if (count <= 4) /* immediate transfer */
276 saawrite(val, SAA7146_DEBI_AD);
277 else /* block transfer */
278 saawrite(virt_to_bus(saa->dmadebi), SAA7146_DEBI_AD);
279 saawrite((cmd = (count << 17) | (addr & 0xffff)), SAA7146_DEBI_COMMAND);
280 saawrite((SAA7146_MC2_UPLD_DEBI << 16) | SAA7146_MC2_UPLD_DEBI,
281 SAA7146_MC2);
282 return 0;
283}
284
285static u32 debiread(struct saa7146 *saa, u32 config, int addr, int count)
286{
287 u32 result = 0;
288
289 if (count > 32764 || count <= 0)
290 return 0;
291 if (wait_for_debi_done(saa) < 0)
292 return 0;
293 saawrite(virt_to_bus(saa->dmadebi), SAA7146_DEBI_AD);
294 saawrite((count << 17) | 0x10000 | (addr & 0xffff),
295 SAA7146_DEBI_COMMAND);
296 saawrite(config, SAA7146_DEBI_CONFIG);
297 saawrite((SAA7146_MC2_UPLD_DEBI << 16) | SAA7146_MC2_UPLD_DEBI,
298 SAA7146_MC2);
299 if (count > 4) /* not an immediate transfer */
300 return count;
301 wait_for_debi_done(saa);
302 result = saaread(SAA7146_DEBI_AD);
303 if (count == 1)
304 result &= 0xff;
305 if (count == 2)
306 result &= 0xffff;
307 if (count == 3)
308 result &= 0xffffff;
309 return result;
310}
311
312#if 0 /* unused */
313/* MUST be a multiple of 8 bytes and 8-byte aligned and < 32768 bytes */
314/* data copied into saa->dmadebi buffer, caller must re-enable interrupts */
315static void ibm_block_dram_read(struct saa7146 *saa, int address, int bytes)
316{
317 int i, j;
318 u32 *buf;
319 buf = (u32 *) saa->dmadebi;
320 if (bytes > 0x7000)
321 bytes = 0x7000;
322 saawrite(0, SAA7146_IER); /* disable interrupts */
323 for (i=0; i < 10000 &&
324 (debiread(saa, debNormal, IBM_MP2_DRAM_CMD_STAT, 2)
325 & 0x8000); i++)
326 saaread(SAA7146_MC2);
327 if (i == 10000)
328 printk(KERN_ERR "stradis%d: dram_busy never cleared\n",
329 saa->nr);
330 debiwrite(saa, debNormal, IBM_MP2_SRC_ADDR, (address<<16) |
331 (address>>16), 4);
332 debiwrite(saa, debNormal, IBM_MP2_BLOCK_SIZE, bytes, 2);
333 debiwrite(saa, debNormal, IBM_MP2_CMD_STAT, 0x8a10, 2);
334 for (j = 0; j < bytes/4; j++) {
335 for (i = 0; i < 10000 &&
336 (!(debiread(saa, debNormal, IBM_MP2_DRAM_CMD_STAT, 2)
337 & 0x4000)); i++)
338 saaread(SAA7146_MC2);
339 if (i == 10000)
340 printk(KERN_ERR "stradis%d: dram_ready never set\n",
341 saa->nr);
342 buf[j] = debiread(saa, debNormal, IBM_MP2_DRAM_DATA, 4);
343 }
344}
345#endif /* unused */
346
347static void do_irq_send_data(struct saa7146 *saa)
348{
349 int split, audbytes, vidbytes;
350
351 saawrite(SAA7146_PSR_PIN1, SAA7146_IER);
352 /* if special feature mode in effect, disable audio sending */
353 if (saa->playmode != VID_PLAY_NORMAL)
354 saa->audtail = saa->audhead = 0;
355 if (saa->audhead <= saa->audtail)
356 audbytes = saa->audtail - saa->audhead;
357 else
358 audbytes = 65536 - (saa->audhead - saa->audtail);
359 if (saa->vidhead <= saa->vidtail)
360 vidbytes = saa->vidtail - saa->vidhead;
361 else
362 vidbytes = 524288 - (saa->vidhead - saa->vidtail);
363 if (audbytes == 0 && vidbytes == 0 && saa->osdtail == saa->osdhead) {
364 saawrite(0, SAA7146_IER);
365 return;
366 }
367 /* if at least 1 block audio waiting and audio fifo isn't full */
368 if (audbytes >= 2048 && (debiread(saa, debNormal,
369 IBM_MP2_AUD_FIFO, 2) & 0xff) < 60) {
370 if (saa->audhead > saa->audtail)
371 split = 65536 - saa->audhead;
372 else
373 split = 0;
374 audbytes = 2048;
375 if (split > 0 && split < 2048) {
376 memcpy(saa->dmadebi, saa->audbuf + saa->audhead,
377 split);
378 saa->audhead = 0;
379 audbytes -= split;
380 } else
381 split = 0;
382 memcpy(saa->dmadebi + split, saa->audbuf + saa->audhead,
383 audbytes);
384 saa->audhead += audbytes;
385 saa->audhead &= 0xffff;
386 debiwrite(saa, debAudio, (NewCard? IBM_MP2_AUD_FIFO :
387 IBM_MP2_AUD_FIFOW), 0, 2048);
388 wake_up_interruptible(&saa->audq);
389 /* if at least 1 block video waiting and video fifo isn't full */
390 } else if (vidbytes >= 30720 && (debiread(saa, debNormal,
391 IBM_MP2_FIFO, 2)) < 16384) {
392 if (saa->vidhead > saa->vidtail)
393 split = 524288 - saa->vidhead;
394 else
395 split = 0;
396 vidbytes = 30720;
397 if (split > 0 && split < 30720) {
398 memcpy(saa->dmadebi, saa->vidbuf + saa->vidhead,
399 split);
400 saa->vidhead = 0;
401 vidbytes -= split;
402 } else
403 split = 0;
404 memcpy(saa->dmadebi + split, saa->vidbuf + saa->vidhead,
405 vidbytes);
406 saa->vidhead += vidbytes;
407 saa->vidhead &= 0x7ffff;
408 debiwrite(saa, debVideo, (NewCard ? IBM_MP2_FIFO :
409 IBM_MP2_FIFOW), 0, 30720);
410 wake_up_interruptible(&saa->vidq);
411 }
412 saawrite(SAA7146_PSR_DEBI_S | SAA7146_PSR_PIN1, SAA7146_IER);
413}
414
415static void send_osd_data(struct saa7146 *saa)
416{
417 int size = saa->osdtail - saa->osdhead;
418 if (size > 30720)
419 size = 30720;
420 /* ensure some multiple of 8 bytes is transferred */
421 size = 8 * ((size + 8)>>3);
422 if (size) {
423 debiwrite(saa, debNormal, IBM_MP2_OSD_ADDR,
424 (saa->osdhead>>3), 2);
425 memcpy(saa->dmadebi, &saa->osdbuf[saa->osdhead], size);
426 saa->osdhead += size;
427 /* block transfer of next 8 bytes to ~32k bytes */
428 debiwrite(saa, debNormal, IBM_MP2_OSD_DATA, 0, size);
429 }
430 if (saa->osdhead >= saa->osdtail) {
431 saa->osdhead = saa->osdtail = 0;
432 debiwrite(saa, debNormal, IBM_MP2_MASK0, 0xc00c, 2);
433 }
434}
435
436static irqreturn_t saa7146_irq(int irq, void *dev_id, struct pt_regs *regs)
437{
438 struct saa7146 *saa = (struct saa7146 *) dev_id;
439 u32 stat, astat;
440 int count;
441 int handled = 0;
442
443 count = 0;
444 while (1) {
445 /* get/clear interrupt status bits */
446 stat = saaread(SAA7146_ISR);
447 astat = stat & saaread(SAA7146_IER);
448 if (!astat)
449 break;
450 handled = 1;
451 saawrite(astat, SAA7146_ISR);
452 if (astat & SAA7146_PSR_DEBI_S) {
453 do_irq_send_data(saa);
454 }
455 if (astat & SAA7146_PSR_PIN1) {
456 int istat;
457 /* the following read will trigger DEBI_S */
458 istat = debiread(saa, debNormal, IBM_MP2_HOST_INT, 2);
459 if (istat & 1) {
460 saawrite(0, SAA7146_IER);
461 send_osd_data(saa);
462 saawrite(SAA7146_PSR_DEBI_S |
463 SAA7146_PSR_PIN1, SAA7146_IER);
464 }
465 if (istat & 0x20) { /* Video Start */
466 saa->vidinfo.frame_count++;
467 }
468 if (istat & 0x400) { /* Picture Start */
469 /* update temporal reference */
470 }
471 if (istat & 0x200) { /* Picture Resolution Change */
472 /* read new resolution */
473 }
474 if (istat & 0x100) { /* New User Data found */
475 /* read new user data */
476 }
477 if (istat & 0x1000) { /* new GOP/SMPTE */
478 /* read new SMPTE */
479 }
480 if (istat & 0x8000) { /* Sequence Start Code */
481 /* reset frame counter, load sizes */
482 saa->vidinfo.frame_count = 0;
483 saa->vidinfo.h_size = 704;
484 saa->vidinfo.v_size = 480;
485#if 0
486 if (saa->endmarkhead != saa->endmarktail) {
487 saa->audhead =
488 saa->endmark[saa->endmarkhead];
489 saa->endmarkhead++;
490 if (saa->endmarkhead >= MAX_MARKS)
491 saa->endmarkhead = 0;
492 }
493#endif
494 }
495 if (istat & 0x4000) { /* Sequence Error Code */
496 if (saa->endmarkhead != saa->endmarktail) {
497 saa->audhead =
498 saa->endmark[saa->endmarkhead];
499 saa->endmarkhead++;
500 if (saa->endmarkhead >= MAX_MARKS)
501 saa->endmarkhead = 0;
502 }
503 }
504 }
505#ifdef IDEBUG
506 if (astat & SAA7146_PSR_PPEF) {
507 IDEBUG(printk("stradis%d irq: PPEF\n", saa->nr));
508 }
509 if (astat & SAA7146_PSR_PABO) {
510 IDEBUG(printk("stradis%d irq: PABO\n", saa->nr));
511 }
512 if (astat & SAA7146_PSR_PPED) {
513 IDEBUG(printk("stradis%d irq: PPED\n", saa->nr));
514 }
515 if (astat & SAA7146_PSR_RPS_I1) {
516 IDEBUG(printk("stradis%d irq: RPS_I1\n", saa->nr));
517 }
518 if (astat & SAA7146_PSR_RPS_I0) {
519 IDEBUG(printk("stradis%d irq: RPS_I0\n", saa->nr));
520 }
521 if (astat & SAA7146_PSR_RPS_LATE1) {
522 IDEBUG(printk("stradis%d irq: RPS_LATE1\n", saa->nr));
523 }
524 if (astat & SAA7146_PSR_RPS_LATE0) {
525 IDEBUG(printk("stradis%d irq: RPS_LATE0\n", saa->nr));
526 }
527 if (astat & SAA7146_PSR_RPS_E1) {
528 IDEBUG(printk("stradis%d irq: RPS_E1\n", saa->nr));
529 }
530 if (astat & SAA7146_PSR_RPS_E0) {
531 IDEBUG(printk("stradis%d irq: RPS_E0\n", saa->nr));
532 }
533 if (astat & SAA7146_PSR_RPS_TO1) {
534 IDEBUG(printk("stradis%d irq: RPS_TO1\n", saa->nr));
535 }
536 if (astat & SAA7146_PSR_RPS_TO0) {
537 IDEBUG(printk("stradis%d irq: RPS_TO0\n", saa->nr));
538 }
539 if (astat & SAA7146_PSR_UPLD) {
540 IDEBUG(printk("stradis%d irq: UPLD\n", saa->nr));
541 }
542 if (astat & SAA7146_PSR_DEBI_E) {
543 IDEBUG(printk("stradis%d irq: DEBI_E\n", saa->nr));
544 }
545 if (astat & SAA7146_PSR_I2C_S) {
546 IDEBUG(printk("stradis%d irq: I2C_S\n", saa->nr));
547 }
548 if (astat & SAA7146_PSR_I2C_E) {
549 IDEBUG(printk("stradis%d irq: I2C_E\n", saa->nr));
550 }
551 if (astat & SAA7146_PSR_A2_IN) {
552 IDEBUG(printk("stradis%d irq: A2_IN\n", saa->nr));
553 }
554 if (astat & SAA7146_PSR_A2_OUT) {
555 IDEBUG(printk("stradis%d irq: A2_OUT\n", saa->nr));
556 }
557 if (astat & SAA7146_PSR_A1_IN) {
558 IDEBUG(printk("stradis%d irq: A1_IN\n", saa->nr));
559 }
560 if (astat & SAA7146_PSR_A1_OUT) {
561 IDEBUG(printk("stradis%d irq: A1_OUT\n", saa->nr));
562 }
563 if (astat & SAA7146_PSR_AFOU) {
564 IDEBUG(printk("stradis%d irq: AFOU\n", saa->nr));
565 }
566 if (astat & SAA7146_PSR_V_PE) {
567 IDEBUG(printk("stradis%d irq: V_PE\n", saa->nr));
568 }
569 if (astat & SAA7146_PSR_VFOU) {
570 IDEBUG(printk("stradis%d irq: VFOU\n", saa->nr));
571 }
572 if (astat & SAA7146_PSR_FIDA) {
573 IDEBUG(printk("stradis%d irq: FIDA\n", saa->nr));
574 }
575 if (astat & SAA7146_PSR_FIDB) {
576 IDEBUG(printk("stradis%d irq: FIDB\n", saa->nr));
577 }
578 if (astat & SAA7146_PSR_PIN3) {
579 IDEBUG(printk("stradis%d irq: PIN3\n", saa->nr));
580 }
581 if (astat & SAA7146_PSR_PIN2) {
582 IDEBUG(printk("stradis%d irq: PIN2\n", saa->nr));
583 }
584 if (astat & SAA7146_PSR_PIN0) {
585 IDEBUG(printk("stradis%d irq: PIN0\n", saa->nr));
586 }
587 if (astat & SAA7146_PSR_ECS) {
588 IDEBUG(printk("stradis%d irq: ECS\n", saa->nr));
589 }
590 if (astat & SAA7146_PSR_EC3S) {
591 IDEBUG(printk("stradis%d irq: EC3S\n", saa->nr));
592 }
593 if (astat & SAA7146_PSR_EC0S) {
594 IDEBUG(printk("stradis%d irq: EC0S\n", saa->nr));
595 }
596#endif
597 count++;
598 if (count > 15)
599 printk(KERN_WARNING "stradis%d: irq loop %d\n",
600 saa->nr, count);
601 if (count > 20) {
602 saawrite(0, SAA7146_IER);
603 printk(KERN_ERR
604 "stradis%d: IRQ loop cleared\n", saa->nr);
605 }
606 }
607 return IRQ_RETVAL(handled);
608}
609
610static int ibm_send_command(struct saa7146 *saa,
611 int command, int data, int chain)
612{
613 int i;
614
615 if (chain)
616 debiwrite(saa, debNormal, IBM_MP2_COMMAND, (command << 1) | 1, 2);
617 else
618 debiwrite(saa, debNormal, IBM_MP2_COMMAND, command << 1, 2);
619 debiwrite(saa, debNormal, IBM_MP2_CMD_DATA, data, 2);
620 debiwrite(saa, debNormal, IBM_MP2_CMD_STAT, 1, 2);
621 for (i = 0; i < 100 &&
622 (debiread(saa, debNormal, IBM_MP2_CMD_STAT, 2) & 1); i++)
623 schedule();
624 if (i == 100)
625 return -1;
626 return 0;
627}
628
629static void cs4341_setlevel(struct saa7146 *saa, int left, int right)
630{
631 I2CWrite(saa, 0x22, 0x03, left > 94 ? 94 : left, 2);
632 I2CWrite(saa, 0x22, 0x04, right > 94 ? 94 : right, 2);
633}
634
635static void initialize_cs4341(struct saa7146 *saa)
636{
637 int i;
638 for (i = 0; i < 200; i++) {
639 /* auto mute off, power on, no de-emphasis */
640 /* I2S data up to 24-bit 64xFs internal SCLK */
641 I2CWrite(saa, 0x22, 0x01, 0x11, 2);
642 /* ATAPI mixer settings */
643 I2CWrite(saa, 0x22, 0x02, 0x49, 2);
644 /* attenuation left 3db */
645 I2CWrite(saa, 0x22, 0x03, 0x00, 2);
646 /* attenuation right 3db */
647 I2CWrite(saa, 0x22, 0x04, 0x00, 2);
648 I2CWrite(saa, 0x22, 0x01, 0x10, 2);
649 if (I2CRead(saa, 0x22, 0x02, 1) == 0x49)
650 break;
651 schedule();
652 }
653 printk("stradis%d: CS4341 initialized (%d)\n", saa->nr, i);
654 return;
655}
656
657static void initialize_cs8420(struct saa7146 *saa, int pro)
658{
659 int i;
660 u8 *sequence;
661 if (pro)
662 sequence = mode8420pro;
663 else
664 sequence = mode8420con;
665 for (i = 0; i < INIT8420LEN; i++)
666 I2CWrite(saa, 0x20, init8420[i * 2],
667 init8420[i * 2 + 1], 2);
668 for (i = 0; i < MODE8420LEN; i++)
669 I2CWrite(saa, 0x20, sequence[i * 2],
670 sequence[i * 2 + 1], 2);
671 printk("stradis%d: CS8420 initialized\n", saa->nr);
672}
673
674static void initialize_saa7121(struct saa7146 *saa, int dopal)
675{
676 int i, mod;
677 u8 *sequence;
678 if (dopal)
679 sequence = init7121pal;
680 else
681 sequence = init7121ntsc;
682 mod = saaread(SAA7146_PSR) & 0x08;
683 /* initialize PAL/NTSC video encoder */
684 for (i = 0; i < INIT7121LEN; i++) {
685 if (NewCard) { /* handle new card encoder differences */
686 if (sequence[i*2] == 0x3a)
687 I2CWrite(saa, 0x88, 0x3a, 0x13, 2);
688 else if (sequence[i*2] == 0x6b)
689 I2CWrite(saa, 0x88, 0x6b, 0x20, 2);
690 else if (sequence[i*2] == 0x6c)
691 I2CWrite(saa, 0x88, 0x6c,
692 dopal ? 0x09 : 0xf5, 2);
693 else if (sequence[i*2] == 0x6d)
694 I2CWrite(saa, 0x88, 0x6d,
695 dopal ? 0x20 : 0x00, 2);
696 else if (sequence[i*2] == 0x7a)
697 I2CWrite(saa, 0x88, 0x7a,
698 dopal ? (PALFirstActive - 1) :
699 (NTSCFirstActive - 4), 2);
700 else if (sequence[i*2] == 0x7b)
701 I2CWrite(saa, 0x88, 0x7b,
702 dopal ? PALLastActive :
703 NTSCLastActive, 2);
704 else I2CWrite(saa, 0x88, sequence[i * 2],
705 sequence[i * 2 + 1], 2);
706 } else {
707 if (sequence[i*2] == 0x6b && mod)
708 I2CWrite(saa, 0x88, 0x6b,
709 (sequence[i * 2 + 1] ^ 0x09), 2);
710 else if (sequence[i*2] == 0x7a)
711 I2CWrite(saa, 0x88, 0x7a,
712 dopal ? (PALFirstActive - 1) :
713 (NTSCFirstActive - 4), 2);
714 else if (sequence[i*2] == 0x7b)
715 I2CWrite(saa, 0x88, 0x7b,
716 dopal ? PALLastActive :
717 NTSCLastActive, 2);
718 else
719 I2CWrite(saa, 0x88, sequence[i * 2],
720 sequence[i * 2 + 1], 2);
721 }
722 }
723}
724
725static void set_genlock_offset(struct saa7146 *saa, int noffset)
726{
727 int nCode;
728 int PixelsPerLine = 858;
729 if (CurrentMode == VIDEO_MODE_PAL)
730 PixelsPerLine = 864;
731 if (noffset > 500)
732 noffset = 500;
733 else if (noffset < -500)
734 noffset = -500;
735 nCode = noffset + 0x100;
736 if (nCode == 1)
737 nCode = 0x401;
738 else if (nCode < 1) nCode = 0x400 + PixelsPerLine + nCode;
739 debiwrite(saa, debNormal, XILINX_GLDELAY, nCode, 2);
740}
741
742static void set_out_format(struct saa7146 *saa, int mode)
743{
744 initialize_saa7121(saa, (mode == VIDEO_MODE_NTSC ? 0 : 1));
745 saa->boardcfg[2] = mode;
746 /* do not adjust analog video parameters here, use saa7121 init */
747 /* you will affect the SDI output on the new card */
748 if (mode == VIDEO_MODE_PAL) { /* PAL */
749 debiwrite(saa, debNormal, XILINX_CTL0, 0x0808, 2);
750 mdelay(50);
751 saawrite(0x012002c0, SAA7146_NUM_LINE_BYTE1);
752 if (NewCard) {
753 debiwrite(saa, debNormal, IBM_MP2_DISP_MODE,
754 0xe100, 2);
755 mdelay(50);
756 }
757 debiwrite(saa, debNormal, IBM_MP2_DISP_MODE,
758 NewCard ? 0xe500: 0x6500, 2);
759 debiwrite(saa, debNormal, IBM_MP2_DISP_DLY,
760 (1 << 8) |
761 (NewCard ? PALFirstActive : PALFirstActive-6), 2);
762 } else { /* NTSC */
763 debiwrite(saa, debNormal, XILINX_CTL0, 0x0800, 2);
764 mdelay(50);
765 saawrite(0x00f002c0, SAA7146_NUM_LINE_BYTE1);
766 debiwrite(saa, debNormal, IBM_MP2_DISP_MODE,
767 NewCard ? 0xe100: 0x6100, 2);
768 debiwrite(saa, debNormal, IBM_MP2_DISP_DLY,
769 (1 << 8) |
770 (NewCard ? NTSCFirstActive : NTSCFirstActive-6), 2);
771 }
772}
773
774
775/* Intialize bitmangler to map from a byte value to the mangled word that
776 * must be output to program the Xilinx part through the DEBI port.
777 * Xilinx Data Bit->DEBI Bit: 0->15 1->7 2->6 3->12 4->11 5->2 6->1 7->0
778 * transfer FPGA code, init IBM chip, transfer IBM microcode
779 * rev2 card mangles: 0->7 1->6 2->5 3->4 4->3 5->2 6->1 7->0
780 */
781static u16 bitmangler[256];
782
783static int initialize_fpga(struct video_code *bitdata)
784{
785 int i, num, startindex, failure = 0, loadtwo, loadfile = 0;
786 u16 *dmabuf;
787 u8 *newdma;
788 struct saa7146 *saa;
789
790 /* verify fpga code */
791 for (startindex = 0; startindex < bitdata->datasize; startindex++)
792 if (bitdata->data[startindex] == 255)
793 break;
794 if (startindex == bitdata->datasize) {
795 printk(KERN_INFO "stradis: bad fpga code\n");
796 return -1;
797 }
798 /* initialize all detected cards */
799 for (num = 0; num < saa_num; num++) {
800 saa = &saa7146s[num];
801 if (saa->boardcfg[0] > 20)
802 continue; /* card was programmed */
803 loadtwo = (saa->boardcfg[18] & 0x10);
804 if (!NewCard) /* we have an old board */
805 for (i = 0; i < 256; i++)
806 bitmangler[i] = ((i & 0x01) << 15) |
807 ((i & 0x02) << 6) | ((i & 0x04) << 4) |
808 ((i & 0x08) << 9) | ((i & 0x10) << 7) |
809 ((i & 0x20) >> 3) | ((i & 0x40) >> 5) |
810 ((i & 0x80) >> 7);
811 else /* else we have a new board */
812 for (i = 0; i < 256; i++)
813 bitmangler[i] = ((i & 0x01) << 7) |
814 ((i & 0x02) << 5) | ((i & 0x04) << 3) |
815 ((i & 0x08) << 1) | ((i & 0x10) >> 1) |
816 ((i & 0x20) >> 3) | ((i & 0x40) >> 5) |
817 ((i & 0x80) >> 7);
818
819 dmabuf = (u16 *) saa->dmadebi;
820 newdma = (u8 *) saa->dmadebi;
821 if (NewCard) { /* SDM2xxx */
822 if (!strncmp(bitdata->loadwhat, "decoder2", 8))
823 continue; /* fpga not for this card */
824 if (!strncmp(&saa->boardcfg[42],
825 bitdata->loadwhat, 8)) {
826 loadfile = 1;
827 } else if (loadtwo && !strncmp(&saa->boardcfg[19],
828 bitdata->loadwhat, 8)) {
829 loadfile = 2;
830 } else if (!saa->boardcfg[42] && /* special */
831 !strncmp("decxl", bitdata->loadwhat, 8)) {
832 loadfile = 1;
833 } else
834 continue; /* fpga not for this card */
835 if (loadfile != 1 && loadfile != 2) {
836 continue; /* skip to next card */
837 }
838 if (saa->boardcfg[0] && loadfile == 1 )
839 continue; /* skip to next card */
840 if (saa->boardcfg[0] != 1 && loadfile == 2)
841 continue; /* skip to next card */
842 saa->boardcfg[0]++; /* mark fpga handled */
843 printk("stradis%d: loading %s\n", saa->nr,
844 bitdata->loadwhat);
845 if (loadtwo && loadfile == 2)
846 goto send_fpga_stuff;
847 /* turn on the Audio interface to set PROG low */
848 saawrite(0x00400040, SAA7146_GPIO_CTRL);
849 saaread(SAA7146_PSR); /* ensure posted write */
850 /* wait for everyone to reset */
851 mdelay(10);
852 saawrite(0x00400000, SAA7146_GPIO_CTRL);
853 } else { /* original card */
854 if (strncmp(bitdata->loadwhat, "decoder2", 8))
855 continue; /* fpga not for this card */
856 /* Pull the Xilinx PROG signal WS3 low */
857 saawrite(0x02000200, SAA7146_MC1);
858 /* Turn on the Audio interface so can set PROG low */
859 saawrite(0x000000c0, SAA7146_ACON1);
860 /* Pull the Xilinx INIT signal (GPIO2) low */
861 saawrite(0x00400000, SAA7146_GPIO_CTRL);
862 /* Make sure everybody resets */
863 saaread(SAA7146_PSR); /* ensure posted write */
864 mdelay(10);
865 /* Release the Xilinx PROG signal */
866 saawrite(0x00000000, SAA7146_ACON1);
867 /* Turn off the Audio interface */
868 saawrite(0x02000000, SAA7146_MC1);
869 }
870 /* Release Xilinx INIT signal (WS2) */
871 saawrite(0x00000000, SAA7146_GPIO_CTRL);
872 /* Wait for the INIT to go High */
873 for (i = 0; i < 10000 &&
874 !(saaread(SAA7146_PSR) & SAA7146_PSR_PIN2); i++)
875 schedule();
876 if (i == 1000) {
877 printk(KERN_INFO "stradis%d: no fpga INIT\n", saa->nr);
878 return -1;
879 }
880send_fpga_stuff:
881 if (NewCard) {
882 for (i = startindex; i < bitdata->datasize; i++)
883 newdma[i - startindex] =
884 bitmangler[bitdata->data[i]];
885 debiwrite(saa, 0x01420000, 0, 0,
886 ((bitdata->datasize - startindex) + 5));
887 if (loadtwo) {
888 if (loadfile == 1) {
889 printk("stradis%d: "
890 "awaiting 2nd FPGA bitfile\n",
891 saa->nr);
892 continue; /* skip to next card */
893 }
894
895 }
896 } else {
897 for (i = startindex; i < bitdata->datasize; i++)
898 dmabuf[i - startindex] =
899 bitmangler[bitdata->data[i]];
900 debiwrite(saa, 0x014a0000, 0, 0,
901 ((bitdata->datasize - startindex) + 5) * 2);
902 }
903 for (i = 0; i < 1000 &&
904 !(saaread(SAA7146_PSR) & SAA7146_PSR_PIN2); i++)
905 schedule();
906 if (i == 1000) {
907 printk(KERN_INFO "stradis%d: FPGA load failed\n",
908 saa->nr);
909 failure++;
910 continue;
911 }
912 if (!NewCard) {
913 /* Pull the Xilinx INIT signal (GPIO2) low */
914 saawrite(0x00400000, SAA7146_GPIO_CTRL);
915 saaread(SAA7146_PSR); /* ensure posted write */
916 mdelay(2);
917 saawrite(0x00000000, SAA7146_GPIO_CTRL);
918 mdelay(2);
919 }
920 printk(KERN_INFO "stradis%d: FPGA Loaded\n", saa->nr);
921 saa->boardcfg[0] = 26; /* mark fpga programmed */
922 /* set VXCO to its lowest frequency */
923 debiwrite(saa, debNormal, XILINX_PWM, 0, 2);
924 if (NewCard) {
925 /* mute CS3310 */
926 if (HaveCS3310)
927 debiwrite(saa, debNormal, XILINX_CS3310_CMPLT,
928 0, 2);
929 /* set VXCO to PWM mode, release reset, blank on */
930 debiwrite(saa, debNormal, XILINX_CTL0, 0xffc4, 2);
931 mdelay(10);
932 /* unmute CS3310 */
933 if (HaveCS3310)
934 debiwrite(saa, debNormal, XILINX_CTL0,
935 0x2020, 2);
936 }
937 /* set source Black */
938 debiwrite(saa, debNormal, XILINX_CTL0, 0x1707, 2);
939 saa->boardcfg[4] = 22; /* set NTSC First Active Line */
940 saa->boardcfg[5] = 23; /* set PAL First Active Line */
941 saa->boardcfg[54] = 2; /* set NTSC Last Active Line - 256 */
942 saa->boardcfg[55] = 54; /* set PAL Last Active Line - 256 */
943 set_out_format(saa, VIDEO_MODE_NTSC);
944 mdelay(50);
945 /* begin IBM chip init */
946 debiwrite(saa, debNormal, IBM_MP2_CHIP_CONTROL, 4, 2);
947 saaread(SAA7146_PSR); /* wait for reset */
948 mdelay(5);
949 debiwrite(saa, debNormal, IBM_MP2_CHIP_CONTROL, 0, 2);
950 debiread(saa, debNormal, IBM_MP2_CHIP_CONTROL, 2);
951 debiwrite(saa, debNormal, IBM_MP2_CHIP_CONTROL, 0x10, 2);
952 debiwrite(saa, debNormal, IBM_MP2_CMD_ADDR, 0, 2);
953 debiwrite(saa, debNormal, IBM_MP2_CHIP_MODE, 0x2e, 2);
954 if (NewCard) {
955 mdelay(5);
956 /* set i2s rate converter to 48KHz */
957 debiwrite(saa, debNormal, 0x80c0, 6, 2);
958 /* we must init CS8420 first since rev b pulls i2s */
959 /* master clock low and CS4341 needs i2s master to */
960 /* run the i2c port. */
961 if (HaveCS8420) {
962 /* 0=consumer, 1=pro */
963 initialize_cs8420(saa, 0);
964 }
965 mdelay(5);
966 if (HaveCS4341)
967 initialize_cs4341(saa);
968 }
969 debiwrite(saa, debNormal, IBM_MP2_INFC_CTL, 0x48, 2);
970 debiwrite(saa, debNormal, IBM_MP2_BEEP_CTL, 0xa000, 2);
971 debiwrite(saa, debNormal, IBM_MP2_DISP_LBOR, 0, 2);
972 debiwrite(saa, debNormal, IBM_MP2_DISP_TBOR, 0, 2);
973 if (NewCard)
974 set_genlock_offset(saa, 0);
975 debiwrite(saa, debNormal, IBM_MP2_FRNT_ATTEN, 0, 2);
976#if 0
977 /* enable genlock */
978 debiwrite(saa, debNormal, XILINX_CTL0, 0x8000, 2);
979#else
980 /* disable genlock */
981 debiwrite(saa, debNormal, XILINX_CTL0, 0x8080, 2);
982#endif
983 }
984 return failure;
985}
986
987static int do_ibm_reset(struct saa7146 *saa)
988{
989 /* failure if decoder not previously programmed */
990 if (saa->boardcfg[0] < 37)
991 return -EIO;
992 /* mute CS3310 */
993 if (HaveCS3310)
994 debiwrite(saa, debNormal, XILINX_CS3310_CMPLT, 0, 2);
995 /* disable interrupts */
996 saawrite(0, SAA7146_IER);
997 saa->audhead = saa->audtail = 0;
998 saa->vidhead = saa->vidtail = 0;
999 /* tristate debi bus, disable debi transfers */
1000 saawrite(0x00880000, SAA7146_MC1);
1001 /* ensure posted write */
1002 saaread(SAA7146_MC1);
1003 mdelay(50);
1004 /* re-enable debi transfers */
1005 saawrite(0x00880088, SAA7146_MC1);
1006 /* set source Black */
1007 debiwrite(saa, debNormal, XILINX_CTL0, 0x1707, 2);
1008 /* begin IBM chip init */
1009 set_out_format(saa, CurrentMode);
1010 debiwrite(saa, debNormal, IBM_MP2_CHIP_CONTROL, 4, 2);
1011 saaread(SAA7146_PSR); /* wait for reset */
1012 mdelay(5);
1013 debiwrite(saa, debNormal, IBM_MP2_CHIP_CONTROL, 0, 2);
1014 debiread(saa, debNormal, IBM_MP2_CHIP_CONTROL, 2);
1015 debiwrite(saa, debNormal, IBM_MP2_CHIP_CONTROL, ChipControl, 2);
1016 debiwrite(saa, debNormal, IBM_MP2_CHIP_MODE, 0x2e, 2);
1017 if (NewCard) {
1018 mdelay(5);
1019 /* set i2s rate converter to 48KHz */
1020 debiwrite(saa, debNormal, 0x80c0, 6, 2);
1021 /* we must init CS8420 first since rev b pulls i2s */
1022 /* master clock low and CS4341 needs i2s master to */
1023 /* run the i2c port. */
1024 if (HaveCS8420) {
1025 /* 0=consumer, 1=pro */
1026 initialize_cs8420(saa, 1);
1027 }
1028 mdelay(5);
1029 if (HaveCS4341)
1030 initialize_cs4341(saa);
1031 }
1032 debiwrite(saa, debNormal, IBM_MP2_INFC_CTL, 0x48, 2);
1033 debiwrite(saa, debNormal, IBM_MP2_BEEP_CTL, 0xa000, 2);
1034 debiwrite(saa, debNormal, IBM_MP2_DISP_LBOR, 0, 2);
1035 debiwrite(saa, debNormal, IBM_MP2_DISP_TBOR, 0, 2);
1036 if (NewCard)
1037 set_genlock_offset(saa, 0);
1038 debiwrite(saa, debNormal, IBM_MP2_FRNT_ATTEN, 0, 2);
1039 debiwrite(saa, debNormal, IBM_MP2_OSD_SIZE, 0x2000, 2);
1040 debiwrite(saa, debNormal, IBM_MP2_AUD_CTL, 0x4552, 2);
1041 if (ibm_send_command(saa, IBM_MP2_CONFIG_DECODER,
1042 (ChipControl == 0x43 ? 0xe800 : 0xe000), 1)) {
1043 printk(KERN_ERR "stradis%d: IBM config failed\n", saa->nr);
1044 }
1045 if (HaveCS3310) {
1046 int i = CS3310MaxLvl;
1047 debiwrite(saa, debNormal, XILINX_CS3310_CMPLT, ((i<<8)|i), 2);
1048 }
1049 /* start video decoder */
1050 debiwrite(saa, debNormal, IBM_MP2_CHIP_CONTROL, ChipControl, 2);
1051 /* 256k vid, 3520 bytes aud */
1052 debiwrite(saa, debNormal, IBM_MP2_RB_THRESHOLD, 0x4037, 2);
1053 debiwrite(saa, debNormal, IBM_MP2_AUD_CTL, 0x4573, 2);
1054 ibm_send_command(saa, IBM_MP2_PLAY, 0, 0);
1055 /* enable buffer threshold irq */
1056 debiwrite(saa, debNormal, IBM_MP2_MASK0, 0xc00c, 2);
1057 /* clear pending interrupts */
1058 debiread(saa, debNormal, IBM_MP2_HOST_INT, 2);
1059 debiwrite(saa, debNormal, XILINX_CTL0, 0x1711, 2);
1060 return 0;
1061}
1062
1063/* load the decoder microcode */
1064static int initialize_ibmmpeg2(struct video_code *microcode)
1065{
1066 int i, num;
1067 struct saa7146 *saa;
1068
1069 for (num = 0; num < saa_num; num++) {
1070 saa = &saa7146s[num];
1071 /* check that FPGA is loaded */
1072 debiwrite(saa, debNormal, IBM_MP2_OSD_SIZE, 0xa55a, 2);
1073 if ((i = debiread(saa, debNormal, IBM_MP2_OSD_SIZE, 2)) !=
1074 0xa55a) {
1075 printk(KERN_INFO "stradis%d: %04x != 0xa55a\n",
1076 saa->nr, i);
1077#if 0
1078 return -1;
1079#endif
1080 }
1081 if (!strncmp(microcode->loadwhat, "decoder.vid", 11)) {
1082 if (saa->boardcfg[0] > 27)
1083 continue; /* skip to next card */
1084 /* load video control store */
1085 saa->boardcfg[1] = 0x13; /* no-sync default */
1086 debiwrite(saa, debNormal, IBM_MP2_WR_PROT, 1, 2);
1087 debiwrite(saa, debNormal, IBM_MP2_PROC_IADDR, 0, 2);
1088 for (i = 0; i < microcode->datasize / 2; i++)
1089 debiwrite(saa, debNormal, IBM_MP2_PROC_IDATA,
1090 (microcode->data[i * 2] << 8) |
1091 microcode->data[i * 2 + 1], 2);
1092 debiwrite(saa, debNormal, IBM_MP2_PROC_IADDR, 0, 2);
1093 debiwrite(saa, debNormal, IBM_MP2_WR_PROT, 0, 2);
1094 debiwrite(saa, debNormal, IBM_MP2_CHIP_CONTROL,
1095 ChipControl, 2);
1096 saa->boardcfg[0] = 28;
1097 }
1098 if (!strncmp(microcode->loadwhat, "decoder.aud", 11)) {
1099 if (saa->boardcfg[0] > 35)
1100 continue; /* skip to next card */
1101 /* load audio control store */
1102 debiwrite(saa, debNormal, IBM_MP2_WR_PROT, 1, 2);
1103 debiwrite(saa, debNormal, IBM_MP2_AUD_IADDR, 0, 2);
1104 for (i = 0; i < microcode->datasize; i++)
1105 debiwrite(saa, debNormal, IBM_MP2_AUD_IDATA,
1106 microcode->data[i], 1);
1107 debiwrite(saa, debNormal, IBM_MP2_AUD_IADDR, 0, 2);
1108 debiwrite(saa, debNormal, IBM_MP2_WR_PROT, 0, 2);
1109 debiwrite(saa, debNormal, IBM_MP2_OSD_SIZE, 0x2000, 2);
1110 debiwrite(saa, debNormal, IBM_MP2_AUD_CTL, 0x4552, 2);
1111 if (ibm_send_command(saa, IBM_MP2_CONFIG_DECODER,
1112 0xe000, 1)) {
1113 printk(KERN_ERR
1114 "stradis%d: IBM config failed\n",
1115 saa->nr);
1116 return -1;
1117 }
1118 /* set PWM to center value */
1119 if (NewCard) {
1120 debiwrite(saa, debNormal, XILINX_PWM,
1121 saa->boardcfg[14] +
1122 (saa->boardcfg[13]<<8), 2);
1123 } else
1124 debiwrite(saa, debNormal, XILINX_PWM,
1125 0x46, 2);
1126 if (HaveCS3310) {
1127 i = CS3310MaxLvl;
1128 debiwrite(saa, debNormal,
1129 XILINX_CS3310_CMPLT, ((i<<8)|i), 2);
1130 }
1131 printk(KERN_INFO
1132 "stradis%d: IBM MPEGCD%d Initialized\n",
1133 saa->nr, 18 + (debiread(saa, debNormal,
1134 IBM_MP2_CHIP_CONTROL, 2) >> 12));
1135 /* start video decoder */
1136 debiwrite(saa, debNormal, IBM_MP2_CHIP_CONTROL,
1137 ChipControl, 2);
1138 debiwrite(saa, debNormal, IBM_MP2_RB_THRESHOLD,
1139 0x4037, 2); /* 256k vid, 3520 bytes aud */
1140 debiwrite(saa, debNormal, IBM_MP2_AUD_CTL, 0x4573, 2);
1141 ibm_send_command(saa, IBM_MP2_PLAY, 0, 0);
1142 /* enable buffer threshold irq */
1143 debiwrite(saa, debNormal, IBM_MP2_MASK0, 0xc00c, 2);
1144 debiread(saa, debNormal, IBM_MP2_HOST_INT, 2);
1145 /* enable gpio irq */
1146 saawrite(0x00002000, SAA7146_GPIO_CTRL);
1147 /* enable decoder output to HPS */
1148 debiwrite(saa, debNormal, XILINX_CTL0, 0x1711, 2);
1149 saa->boardcfg[0] = 37;
1150 }
1151 }
1152 return 0;
1153}
1154
1155static u32 palette2fmt[] =
1156{ /* some of these YUV translations are wrong */
1157 0xffffffff, 0x86000000, 0x87000000, 0x80000000, 0x8100000, 0x82000000,
1158 0x83000000, 0x00000000, 0x03000000, 0x03000000, 0x0a00000, 0x03000000,
1159 0x06000000, 0x00000000, 0x03000000, 0x0a000000, 0x0300000
1160};
1161static int bpp2fmt[4] =
1162{
1163 VIDEO_PALETTE_HI240, VIDEO_PALETTE_RGB565, VIDEO_PALETTE_RGB24,
1164 VIDEO_PALETTE_RGB32
1165};
1166
1167/* I wish I could find a formula to calculate these... */
1168static u32 h_prescale[64] =
1169{
1170 0x10000000, 0x18040202, 0x18080000, 0x380c0606, 0x38100204, 0x38140808,
1171 0x38180000, 0x381c0000, 0x3820161c, 0x38242a3b, 0x38281230, 0x382c4460,
1172 0x38301040, 0x38340080, 0x38380000, 0x383c0000, 0x3840fefe, 0x3844ee9f,
1173 0x3848ee9f, 0x384cee9f, 0x3850ee9f, 0x38542a3b, 0x38581230, 0x385c0000,
1174 0x38600000, 0x38640000, 0x38680000, 0x386c0000, 0x38700000, 0x38740000,
1175 0x38780000, 0x387c0000, 0x30800000, 0x38840000, 0x38880000, 0x388c0000,
1176 0x38900000, 0x38940000, 0x38980000, 0x389c0000, 0x38a00000, 0x38a40000,
1177 0x38a80000, 0x38ac0000, 0x38b00000, 0x38b40000, 0x38b80000, 0x38bc0000,
1178 0x38c00000, 0x38c40000, 0x38c80000, 0x38cc0000, 0x38d00000, 0x38d40000,
1179 0x38d80000, 0x38dc0000, 0x38e00000, 0x38e40000, 0x38e80000, 0x38ec0000,
1180 0x38f00000, 0x38f40000, 0x38f80000, 0x38fc0000,
1181};
1182static u32 v_gain[64] =
1183{
1184 0x016000ff, 0x016100ff, 0x016100ff, 0x016200ff, 0x016200ff, 0x016200ff,
1185 0x016200ff, 0x016300ff, 0x016300ff, 0x016300ff, 0x016300ff, 0x016300ff,
1186 0x016300ff, 0x016300ff, 0x016300ff, 0x016400ff, 0x016400ff, 0x016400ff,
1187 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff,
1188 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff,
1189 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff,
1190 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff,
1191 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff,
1192 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff,
1193 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff,
1194 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff,
1195};
1196
1197
1198static void saa7146_set_winsize(struct saa7146 *saa)
1199{
1200 u32 format;
1201 int offset, yacl, ysci;
1202 saa->win.color_fmt = format =
1203 (saa->win.depth == 15) ? palette2fmt[VIDEO_PALETTE_RGB555] :
1204 palette2fmt[bpp2fmt[(saa->win.bpp - 1) & 3]];
1205 offset = saa->win.x * saa->win.bpp + saa->win.y * saa->win.bpl;
1206 saawrite(saa->win.vidadr + offset, SAA7146_BASE_EVEN1);
1207 saawrite(saa->win.vidadr + offset + saa->win.bpl, SAA7146_BASE_ODD1);
1208 saawrite(saa->win.bpl * 2, SAA7146_PITCH1);
1209 saawrite(saa->win.vidadr + saa->win.bpl * saa->win.sheight,
1210 SAA7146_PROT_ADDR1);
1211 saawrite(0, SAA7146_PAGE1);
1212 saawrite(format|0x60, SAA7146_CLIP_FORMAT_CTRL);
1213 offset = (704 / (saa->win.width - 1)) & 0x3f;
1214 saawrite(h_prescale[offset], SAA7146_HPS_H_PRESCALE);
1215 offset = (720896 / saa->win.width) / (offset + 1);
1216 saawrite((offset<<12)|0x0c, SAA7146_HPS_H_SCALE);
1217 if (CurrentMode == VIDEO_MODE_NTSC) {
1218 yacl = /*(480 / saa->win.height - 1) & 0x3f*/ 0;
1219 ysci = 1024 - (saa->win.height * 1024 / 480);
1220 } else {
1221 yacl = /*(576 / saa->win.height - 1) & 0x3f*/ 0;
1222 ysci = 1024 - (saa->win.height * 1024 / 576);
1223 }
1224 saawrite((1<<31)|(ysci<<21)|(yacl<<15), SAA7146_HPS_V_SCALE);
1225 saawrite(v_gain[yacl], SAA7146_HPS_V_GAIN);
1226 saawrite(((SAA7146_MC2_UPLD_DMA1 | SAA7146_MC2_UPLD_HPS_V |
1227 SAA7146_MC2_UPLD_HPS_H) << 16) | (SAA7146_MC2_UPLD_DMA1 |
1228 SAA7146_MC2_UPLD_HPS_V | SAA7146_MC2_UPLD_HPS_H),
1229 SAA7146_MC2);
1230}
1231
1232/* clip_draw_rectangle(cm,x,y,w,h) -- handle clipping an area
1233 * bitmap is fixed width, 128 bytes (1024 pixels represented)
1234 * arranged most-sigificant-bit-left in 32-bit words
1235 * based on saa7146 clipping hardware, it swaps bytes if LE
1236 * much of this makes up for egcs brain damage -- so if you
1237 * are wondering "why did he do this?" it is because the C
1238 * was adjusted to generate the optimal asm output without
1239 * writing non-portable __asm__ directives.
1240 */
1241
1242static void clip_draw_rectangle(u32 *clipmap, int x, int y, int w, int h)
1243{
1244 register int startword, endword;
1245 register u32 bitsleft, bitsright;
1246 u32 *temp;
1247 if (x < 0) {
1248 w += x;
1249 x = 0;
1250 }
1251 if (y < 0) {
1252 h += y;
1253 y = 0;
1254 }
1255 if (w <= 0 || h <= 0 || x > 1023 || y > 639)
1256 return; /* throw away bad clips */
1257 if (x + w > 1024)
1258 w = 1024 - x;
1259 if (y + h > 640)
1260 h = 640 - y;
1261 startword = (x >> 5);
1262 endword = ((x + w) >> 5);
1263 bitsleft = (0xffffffff >> (x & 31));
1264 bitsright = (0xffffffff << (~((x + w) - (endword<<5))));
1265 temp = &clipmap[(y<<5) + startword];
1266 w = endword - startword;
1267 if (!w) {
1268 bitsleft |= bitsright;
1269 for (y = 0; y < h; y++) {
1270 *temp |= bitsleft;
1271 temp += 32;
1272 }
1273 } else {
1274 for (y = 0; y < h; y++) {
1275 *temp++ |= bitsleft;
1276 for (x = 1; x < w; x++)
1277 *temp++ = 0xffffffff;
1278 *temp |= bitsright;
1279 temp += (32 - w);
1280 }
1281 }
1282}
1283
1284static void make_clip_tab(struct saa7146 *saa, struct video_clip *cr, int ncr)
1285{
1286 int i, width, height;
1287 u32 *clipmap;
1288
1289 clipmap = saa->dmavid2;
1290 if((width=saa->win.width)>1023)
1291 width = 1023; /* sanity check */
1292 if((height=saa->win.height)>640)
1293 height = 639; /* sanity check */
1294 if (ncr > 0) { /* rectangles pased */
1295 /* convert rectangular clips to a bitmap */
1296 memset(clipmap, 0, VIDEO_CLIPMAP_SIZE); /* clear map */
1297 for (i = 0; i < ncr; i++)
1298 clip_draw_rectangle(clipmap, cr[i].x, cr[i].y,
1299 cr[i].width, cr[i].height);
1300 }
1301 /* clip against viewing window AND screen
1302 so we do not have to rely on the user program
1303 */
1304 clip_draw_rectangle(clipmap,(saa->win.x+width>saa->win.swidth) ?
1305 (saa->win.swidth-saa->win.x) : width, 0, 1024, 768);
1306 clip_draw_rectangle(clipmap,0,(saa->win.y+height>saa->win.sheight) ?
1307 (saa->win.sheight-saa->win.y) : height,1024,768);
1308 if (saa->win.x<0)
1309 clip_draw_rectangle(clipmap, 0, 0, -(saa->win.x), 768);
1310 if (saa->win.y<0)
1311 clip_draw_rectangle(clipmap, 0, 0, 1024, -(saa->win.y));
1312}
1313
1314static int saa_ioctl(struct inode *inode, struct file *file,
1315 unsigned int cmd, unsigned long argl)
1316{
1317 struct saa7146 *saa = file->private_data;
1318 void __user *arg = (void __user *)argl;
1319
1320 switch (cmd) {
1321 case VIDIOCGCAP:
1322 {
1323 struct video_capability b;
1324 strcpy(b.name, saa->video_dev.name);
1325 b.type = VID_TYPE_CAPTURE |
1326 VID_TYPE_OVERLAY |
1327 VID_TYPE_CLIPPING |
1328 VID_TYPE_FRAMERAM |
1329 VID_TYPE_SCALES;
1330 b.channels = 1;
1331 b.audios = 1;
1332 b.maxwidth = 768;
1333 b.maxheight = 576;
1334 b.minwidth = 32;
1335 b.minheight = 32;
1336 if (copy_to_user(arg, &b, sizeof(b)))
1337 return -EFAULT;
1338 return 0;
1339 }
1340 case VIDIOCGPICT:
1341 {
1342 struct video_picture p = saa->picture;
1343 if (saa->win.depth == 8)
1344 p.palette = VIDEO_PALETTE_HI240;
1345 if (saa->win.depth == 15)
1346 p.palette = VIDEO_PALETTE_RGB555;
1347 if (saa->win.depth == 16)
1348 p.palette = VIDEO_PALETTE_RGB565;
1349 if (saa->win.depth == 24)
1350 p.palette = VIDEO_PALETTE_RGB24;
1351 if (saa->win.depth == 32)
1352 p.palette = VIDEO_PALETTE_RGB32;
1353 if (copy_to_user(arg, &p, sizeof(p)))
1354 return -EFAULT;
1355 return 0;
1356 }
1357 case VIDIOCSPICT:
1358 {
1359 struct video_picture p;
1360 u32 format;
1361 if (copy_from_user(&p, arg, sizeof(p)))
1362 return -EFAULT;
1363 if (p.palette < sizeof(palette2fmt) / sizeof(u32)) {
1364 format = palette2fmt[p.palette];
1365 saa->win.color_fmt = format;
1366 saawrite(format|0x60, SAA7146_CLIP_FORMAT_CTRL);
1367 }
1368 saawrite(((p.brightness & 0xff00) << 16) |
1369 ((p.contrast & 0xfe00) << 7) |
1370 ((p.colour & 0xfe00) >> 9), SAA7146_BCS_CTRL);
1371 saa->picture = p;
1372 /* upload changed registers */
1373 saawrite(((SAA7146_MC2_UPLD_HPS_H |
1374 SAA7146_MC2_UPLD_HPS_V) << 16) |
1375 SAA7146_MC2_UPLD_HPS_H | SAA7146_MC2_UPLD_HPS_V,
1376 SAA7146_MC2);
1377 return 0;
1378 }
1379 case VIDIOCSWIN:
1380 {
1381 struct video_window vw;
1382 struct video_clip *vcp = NULL;
1383
1384 if (copy_from_user(&vw, arg, sizeof(vw)))
1385 return -EFAULT;
1386
1387 if (vw.flags || vw.width < 16 || vw.height < 16) { /* stop capture */
1388 saawrite((SAA7146_MC1_TR_E_1 << 16), SAA7146_MC1);
1389 return -EINVAL;
1390 }
1391 if (saa->win.bpp < 4) { /* 32-bit align start and adjust width */
1392 int i = vw.x;
1393 vw.x = (vw.x + 3) & ~3;
1394 i = vw.x - i;
1395 vw.width -= i;
1396 }
1397 saa->win.x = vw.x;
1398 saa->win.y = vw.y;
1399 saa->win.width = vw.width;
1400 if (saa->win.width > 768)
1401 saa->win.width = 768;
1402 saa->win.height = vw.height;
1403 if (CurrentMode == VIDEO_MODE_NTSC) {
1404 if (saa->win.height > 480)
1405 saa->win.height = 480;
1406 } else {
1407 if (saa->win.height > 576)
1408 saa->win.height = 576;
1409 }
1410
1411 /* stop capture */
1412 saawrite((SAA7146_MC1_TR_E_1 << 16), SAA7146_MC1);
1413 saa7146_set_winsize(saa);
1414
1415 /*
1416 * Do any clips.
1417 */
1418 if (vw.clipcount < 0) {
1419 if (copy_from_user(saa->dmavid2, vw.clips,
1420 VIDEO_CLIPMAP_SIZE))
1421 return -EFAULT;
1422 }
1423 else if (vw.clipcount > 16384) {
1424 return -EINVAL;
1425 } else if (vw.clipcount > 0) {
1426 if ((vcp = vmalloc(sizeof(struct video_clip) *
1427 (vw.clipcount))) == NULL)
1428 return -ENOMEM;
1429 if (copy_from_user(vcp, vw.clips,
1430 sizeof(struct video_clip) *
1431 vw.clipcount)) {
1432 vfree(vcp);
1433 return -EFAULT;
1434 }
1435 } else /* nothing clipped */
1436 memset(saa->dmavid2, 0, VIDEO_CLIPMAP_SIZE);
1437 make_clip_tab(saa, vcp, vw.clipcount);
1438 if (vw.clipcount > 0)
1439 vfree(vcp);
1440
1441 /* start capture & clip dma if we have an address */
1442 if ((saa->cap & 3) && saa->win.vidadr != 0)
1443 saawrite(((SAA7146_MC1_TR_E_1 |
1444 SAA7146_MC1_TR_E_2) << 16) | 0xffff,
1445 SAA7146_MC1);
1446 return 0;
1447 }
1448 case VIDIOCGWIN:
1449 {
1450 struct video_window vw;
1451 vw.x = saa->win.x;
1452 vw.y = saa->win.y;
1453 vw.width = saa->win.width;
1454 vw.height = saa->win.height;
1455 vw.chromakey = 0;
1456 vw.flags = 0;
1457 if (copy_to_user(arg, &vw, sizeof(vw)))
1458 return -EFAULT;
1459 return 0;
1460 }
1461 case VIDIOCCAPTURE:
1462 {
1463 int v;
1464 if (copy_from_user(&v, arg, sizeof(v)))
1465 return -EFAULT;
1466 if (v == 0) {
1467 saa->cap &= ~1;
1468 saawrite((SAA7146_MC1_TR_E_1 << 16),
1469 SAA7146_MC1);
1470 } else {
1471 if (saa->win.vidadr == 0 || saa->win.width == 0
1472 || saa->win.height == 0)
1473 return -EINVAL;
1474 saa->cap |= 1;
1475 saawrite((SAA7146_MC1_TR_E_1 << 16) | 0xffff,
1476 SAA7146_MC1);
1477 }
1478 return 0;
1479 }
1480 case VIDIOCGFBUF:
1481 {
1482 struct video_buffer v;
1483 v.base = (void *) saa->win.vidadr;
1484 v.height = saa->win.sheight;
1485 v.width = saa->win.swidth;
1486 v.depth = saa->win.depth;
1487 v.bytesperline = saa->win.bpl;
1488 if (copy_to_user(arg, &v, sizeof(v)))
1489 return -EFAULT;
1490 return 0;
1491
1492 }
1493 case VIDIOCSFBUF:
1494 {
1495 struct video_buffer v;
1496 if (!capable(CAP_SYS_ADMIN))
1497 return -EPERM;
1498 if (copy_from_user(&v, arg, sizeof(v)))
1499 return -EFAULT;
1500 if (v.depth != 8 && v.depth != 15 && v.depth != 16 &&
1501 v.depth != 24 && v.depth != 32 && v.width > 16 &&
1502 v.height > 16 && v.bytesperline > 16)
1503 return -EINVAL;
1504 if (v.base)
1505 saa->win.vidadr = (unsigned long) v.base;
1506 saa->win.sheight = v.height;
1507 saa->win.swidth = v.width;
1508 saa->win.bpp = ((v.depth + 7) & 0x38) / 8;
1509 saa->win.depth = v.depth;
1510 saa->win.bpl = v.bytesperline;
1511
1512 DEBUG(printk("Display at %p is %d by %d, bytedepth %d, bpl %d\n",
1513 v.base, v.width, v.height, saa->win.bpp, saa->win.bpl));
1514 saa7146_set_winsize(saa);
1515 return 0;
1516 }
1517 case VIDIOCKEY:
1518 {
1519 /* Will be handled higher up .. */
1520 return 0;
1521 }
1522
1523 case VIDIOCGAUDIO:
1524 {
1525 struct video_audio v;
1526 v = saa->audio_dev;
1527 v.flags &= ~(VIDEO_AUDIO_MUTE | VIDEO_AUDIO_MUTABLE);
1528 v.flags |= VIDEO_AUDIO_MUTABLE | VIDEO_AUDIO_VOLUME;
1529 strcpy(v.name, "MPEG");
1530 v.mode = VIDEO_SOUND_STEREO;
1531 if (copy_to_user(arg, &v, sizeof(v)))
1532 return -EFAULT;
1533 return 0;
1534 }
1535 case VIDIOCSAUDIO:
1536 {
1537 struct video_audio v;
1538 int i;
1539 if (copy_from_user(&v, arg, sizeof(v)))
1540 return -EFAULT;
1541 i = (~(v.volume>>8))&0xff;
1542 if (!HaveCS4341) {
1543 if (v.flags & VIDEO_AUDIO_MUTE) {
1544 debiwrite(saa, debNormal,
1545 IBM_MP2_FRNT_ATTEN,
1546 0xffff, 2);
1547 }
1548 if (!(v.flags & VIDEO_AUDIO_MUTE))
1549 debiwrite(saa, debNormal,
1550 IBM_MP2_FRNT_ATTEN,
1551 0x0000, 2);
1552 if (v.flags & VIDEO_AUDIO_VOLUME)
1553 debiwrite(saa, debNormal,
1554 IBM_MP2_FRNT_ATTEN,
1555 (i<<8)|i, 2);
1556 } else {
1557 if (v.flags & VIDEO_AUDIO_MUTE)
1558 cs4341_setlevel(saa, 0xff, 0xff);
1559 if (!(v.flags & VIDEO_AUDIO_MUTE))
1560 cs4341_setlevel(saa, 0, 0);
1561 if (v.flags & VIDEO_AUDIO_VOLUME)
1562 cs4341_setlevel(saa, i, i);
1563 }
1564 saa->audio_dev = v;
1565 return 0;
1566 }
1567
1568 case VIDIOCGUNIT:
1569 {
1570 struct video_unit vu;
1571 vu.video = saa->video_dev.minor;
1572 vu.vbi = VIDEO_NO_UNIT;
1573 vu.radio = VIDEO_NO_UNIT;
1574 vu.audio = VIDEO_NO_UNIT;
1575 vu.teletext = VIDEO_NO_UNIT;
1576 if (copy_to_user(arg, &vu, sizeof(vu)))
1577 return -EFAULT;
1578 return 0;
1579 }
1580 case VIDIOCSPLAYMODE:
1581 {
1582 struct video_play_mode pmode;
1583 if (copy_from_user((void *) &pmode, arg,
1584 sizeof(struct video_play_mode)))
1585 return -EFAULT;
1586 switch (pmode.mode) {
1587 case VID_PLAY_VID_OUT_MODE:
1588 if (pmode.p1 != VIDEO_MODE_NTSC &&
1589 pmode.p1 != VIDEO_MODE_PAL)
1590 return -EINVAL;
1591 set_out_format(saa, pmode.p1);
1592 return 0;
1593 case VID_PLAY_GENLOCK:
1594 debiwrite(saa, debNormal,
1595 XILINX_CTL0,
1596 (pmode.p1 ? 0x8000 : 0x8080),
1597 2);
1598 if (NewCard)
1599 set_genlock_offset(saa,
1600 pmode.p2);
1601 return 0;
1602 case VID_PLAY_NORMAL:
1603 debiwrite(saa, debNormal,
1604 IBM_MP2_CHIP_CONTROL,
1605 ChipControl, 2);
1606 ibm_send_command(saa,
1607 IBM_MP2_PLAY, 0, 0);
1608 saa->playmode = pmode.mode;
1609 return 0;
1610 case VID_PLAY_PAUSE:
1611 /* IBM removed the PAUSE command */
1612 /* they say use SINGLE_FRAME now */
1613 case VID_PLAY_SINGLE_FRAME:
1614 ibm_send_command(saa,
1615 IBM_MP2_SINGLE_FRAME,
1616 0, 0);
1617 if (saa->playmode == pmode.mode) {
1618 debiwrite(saa, debNormal,
1619 IBM_MP2_CHIP_CONTROL,
1620 ChipControl, 2);
1621 }
1622 saa->playmode = pmode.mode;
1623 return 0;
1624 case VID_PLAY_FAST_FORWARD:
1625 ibm_send_command(saa,
1626 IBM_MP2_FAST_FORWARD, 0, 0);
1627 saa->playmode = pmode.mode;
1628 return 0;
1629 case VID_PLAY_SLOW_MOTION:
1630 ibm_send_command(saa,
1631 IBM_MP2_SLOW_MOTION,
1632 pmode.p1, 0);
1633 saa->playmode = pmode.mode;
1634 return 0;
1635 case VID_PLAY_IMMEDIATE_NORMAL:
1636 /* ensure transfers resume */
1637 debiwrite(saa, debNormal,
1638 IBM_MP2_CHIP_CONTROL,
1639 ChipControl, 2);
1640 ibm_send_command(saa,
1641 IBM_MP2_IMED_NORM_PLAY, 0, 0);
1642 saa->playmode = VID_PLAY_NORMAL;
1643 return 0;
1644 case VID_PLAY_SWITCH_CHANNELS:
1645 saa->audhead = saa->audtail = 0;
1646 saa->vidhead = saa->vidtail = 0;
1647 ibm_send_command(saa,
1648 IBM_MP2_FREEZE_FRAME, 0, 1);
1649 ibm_send_command(saa,
1650 IBM_MP2_RESET_AUD_RATE, 0, 1);
1651 debiwrite(saa, debNormal,
1652 IBM_MP2_CHIP_CONTROL, 0, 2);
1653 ibm_send_command(saa,
1654 IBM_MP2_CHANNEL_SWITCH, 0, 1);
1655 debiwrite(saa, debNormal,
1656 IBM_MP2_CHIP_CONTROL,
1657 ChipControl, 2);
1658 ibm_send_command(saa,
1659 IBM_MP2_PLAY, 0, 0);
1660 saa->playmode = VID_PLAY_NORMAL;
1661 return 0;
1662 case VID_PLAY_FREEZE_FRAME:
1663 ibm_send_command(saa,
1664 IBM_MP2_FREEZE_FRAME, 0, 0);
1665 saa->playmode = pmode.mode;
1666 return 0;
1667 case VID_PLAY_STILL_MODE:
1668 ibm_send_command(saa,
1669 IBM_MP2_SET_STILL_MODE, 0, 0);
1670 saa->playmode = pmode.mode;
1671 return 0;
1672 case VID_PLAY_MASTER_MODE:
1673 if (pmode.p1 == VID_PLAY_MASTER_NONE)
1674 saa->boardcfg[1] = 0x13;
1675 else if (pmode.p1 ==
1676 VID_PLAY_MASTER_VIDEO)
1677 saa->boardcfg[1] = 0x23;
1678 else if (pmode.p1 ==
1679 VID_PLAY_MASTER_AUDIO)
1680 saa->boardcfg[1] = 0x43;
1681 else
1682 return -EINVAL;
1683 debiwrite(saa, debNormal,
1684 IBM_MP2_CHIP_CONTROL,
1685 ChipControl, 2);
1686 return 0;
1687 case VID_PLAY_ACTIVE_SCANLINES:
1688 if (CurrentMode == VIDEO_MODE_PAL) {
1689 if (pmode.p1 < 1 ||
1690 pmode.p2 > 625)
1691 return -EINVAL;
1692 saa->boardcfg[5] = pmode.p1;
1693 saa->boardcfg[55] = (pmode.p1 +
1694 (pmode.p2/2) - 1) &
1695 0xff;
1696 } else {
1697 if (pmode.p1 < 4 ||
1698 pmode.p2 > 525)
1699 return -EINVAL;
1700 saa->boardcfg[4] = pmode.p1;
1701 saa->boardcfg[54] = (pmode.p1 +
1702 (pmode.p2/2) - 4) &
1703 0xff;
1704 }
1705 set_out_format(saa, CurrentMode);
1706 case VID_PLAY_RESET:
1707 return do_ibm_reset(saa);
1708 case VID_PLAY_END_MARK:
1709 if (saa->endmarktail <
1710 saa->endmarkhead) {
1711 if (saa->endmarkhead -
1712 saa->endmarktail < 2)
1713 return -ENOSPC;
1714 } else if (saa->endmarkhead <=
1715 saa->endmarktail) {
1716 if (saa->endmarktail -
1717 saa->endmarkhead >
1718 (MAX_MARKS - 2))
1719 return -ENOSPC;
1720 } else
1721 return -ENOSPC;
1722 saa->endmark[saa->endmarktail] =
1723 saa->audtail;
1724 saa->endmarktail++;
1725 if (saa->endmarktail >= MAX_MARKS)
1726 saa->endmarktail = 0;
1727 }
1728 return -EINVAL;
1729 }
1730 case VIDIOCSWRITEMODE:
1731 {
1732 int mode;
1733 if (copy_from_user((void *) &mode, arg, sizeof(int)))
1734 return -EFAULT;
1735 if (mode == VID_WRITE_MPEG_AUD ||
1736 mode == VID_WRITE_MPEG_VID ||
1737 mode == VID_WRITE_CC ||
1738 mode == VID_WRITE_TTX ||
1739 mode == VID_WRITE_OSD) {
1740 saa->writemode = mode;
1741 return 0;
1742 }
1743 return -EINVAL;
1744 }
1745 case VIDIOCSMICROCODE:
1746 {
1747 struct video_code ucode;
1748 __u8 *udata;
1749 int i;
1750 if (copy_from_user(&ucode, arg, sizeof(ucode)))
1751 return -EFAULT;
1752 if (ucode.datasize > 65536 || ucode.datasize < 1024 ||
1753 strncmp(ucode.loadwhat, "dec", 3))
1754 return -EINVAL;
1755 if ((udata = vmalloc(ucode.datasize)) == NULL)
1756 return -ENOMEM;
1757 if (copy_from_user(udata, ucode.data, ucode.datasize)) {
1758 vfree(udata);
1759 return -EFAULT;
1760 }
1761 ucode.data = udata;
1762 if (!strncmp(ucode.loadwhat, "decoder.aud", 11)
1763 || !strncmp(ucode.loadwhat, "decoder.vid", 11))
1764 i = initialize_ibmmpeg2(&ucode);
1765 else
1766 i = initialize_fpga(&ucode);
1767 vfree(udata);
1768 if (i)
1769 return -EINVAL;
1770 return 0;
1771
1772 }
1773 case VIDIOCGCHAN: /* this makes xawtv happy */
1774 {
1775 struct video_channel v;
1776 if (copy_from_user(&v, arg, sizeof(v)))
1777 return -EFAULT;
1778 v.flags = VIDEO_VC_AUDIO;
1779 v.tuners = 0;
1780 v.type = VID_TYPE_MPEG_DECODER;
1781 v.norm = CurrentMode;
1782 strcpy(v.name, "MPEG2");
1783 if (copy_to_user(arg, &v, sizeof(v)))
1784 return -EFAULT;
1785 return 0;
1786 }
1787 case VIDIOCSCHAN: /* this makes xawtv happy */
1788 {
1789 struct video_channel v;
1790 if (copy_from_user(&v, arg, sizeof(v)))
1791 return -EFAULT;
1792 /* do nothing */
1793 return 0;
1794 }
1795 default:
1796 return -ENOIOCTLCMD;
1797 }
1798 return 0;
1799}
1800
1801static int saa_mmap(struct file *file, struct vm_area_struct *vma)
1802{
1803 struct saa7146 *saa = file->private_data;
1804 printk(KERN_DEBUG "stradis%d: saa_mmap called\n", saa->nr);
1805 return -EINVAL;
1806}
1807
1808static ssize_t saa_read(struct file *file, char __user *buf,
1809 size_t count, loff_t *ppos)
1810{
1811 return -EINVAL;
1812}
1813
1814static ssize_t saa_write(struct file *file, const char __user *buf,
1815 size_t count, loff_t *ppos)
1816{
1817 struct saa7146 *saa = file->private_data;
1818 unsigned long todo = count;
1819 int blocksize, split;
1820 unsigned long flags;
1821
1822 while (todo > 0) {
1823 if (saa->writemode == VID_WRITE_MPEG_AUD) {
1824 spin_lock_irqsave(&saa->lock, flags);
1825 if (saa->audhead <= saa->audtail)
1826 blocksize = 65536-(saa->audtail - saa->audhead);
1827 else
1828 blocksize = saa->audhead - saa->audtail;
1829 spin_unlock_irqrestore(&saa->lock, flags);
1830 if (blocksize < 16384) {
1831 saawrite(SAA7146_PSR_DEBI_S |
1832 SAA7146_PSR_PIN1, SAA7146_IER);
1833 saawrite(SAA7146_PSR_PIN1, SAA7146_PSR);
1834 /* wait for buffer space to open */
1835 interruptible_sleep_on(&saa->audq);
1836 }
1837 spin_lock_irqsave(&saa->lock, flags);
1838 if (saa->audhead <= saa->audtail) {
1839 blocksize = 65536-(saa->audtail - saa->audhead);
1840 split = 65536 - saa->audtail;
1841 } else {
1842 blocksize = saa->audhead - saa->audtail;
1843 split = 65536;
1844 }
1845 spin_unlock_irqrestore(&saa->lock, flags);
1846 blocksize--;
1847 if (blocksize > todo)
1848 blocksize = todo;
1849 /* double check that we really have space */
1850 if (!blocksize)
1851 return -ENOSPC;
1852 if (split < blocksize) {
1853 if (copy_from_user(saa->audbuf +
1854 saa->audtail, buf, split))
1855 return -EFAULT;
1856 buf += split;
1857 todo -= split;
1858 blocksize -= split;
1859 saa->audtail = 0;
1860 }
1861 if (copy_from_user(saa->audbuf + saa->audtail, buf,
1862 blocksize))
1863 return -EFAULT;
1864 saa->audtail += blocksize;
1865 todo -= blocksize;
1866 buf += blocksize;
1867 saa->audtail &= 0xffff;
1868 } else if (saa->writemode == VID_WRITE_MPEG_VID) {
1869 spin_lock_irqsave(&saa->lock, flags);
1870 if (saa->vidhead <= saa->vidtail)
1871 blocksize=524288-(saa->vidtail - saa->vidhead);
1872 else
1873 blocksize = saa->vidhead - saa->vidtail;
1874 spin_unlock_irqrestore(&saa->lock, flags);
1875 if (blocksize < 65536) {
1876 saawrite(SAA7146_PSR_DEBI_S |
1877 SAA7146_PSR_PIN1, SAA7146_IER);
1878 saawrite(SAA7146_PSR_PIN1, SAA7146_PSR);
1879 /* wait for buffer space to open */
1880 interruptible_sleep_on(&saa->vidq);
1881 }
1882 spin_lock_irqsave(&saa->lock, flags);
1883 if (saa->vidhead <= saa->vidtail) {
1884 blocksize=524288-(saa->vidtail - saa->vidhead);
1885 split = 524288 - saa->vidtail;
1886 } else {
1887 blocksize = saa->vidhead - saa->vidtail;
1888 split = 524288;
1889 }
1890 spin_unlock_irqrestore(&saa->lock, flags);
1891 blocksize--;
1892 if (blocksize > todo)
1893 blocksize = todo;
1894 /* double check that we really have space */
1895 if (!blocksize)
1896 return -ENOSPC;
1897 if (split < blocksize) {
1898 if (copy_from_user(saa->vidbuf +
1899 saa->vidtail, buf, split))
1900 return -EFAULT;
1901 buf += split;
1902 todo -= split;
1903 blocksize -= split;
1904 saa->vidtail = 0;
1905 }
1906 if (copy_from_user(saa->vidbuf + saa->vidtail, buf,
1907 blocksize))
1908 return -EFAULT;
1909 saa->vidtail += blocksize;
1910 todo -= blocksize;
1911 buf += blocksize;
1912 saa->vidtail &= 0x7ffff;
1913 } else if (saa->writemode == VID_WRITE_OSD) {
1914 if (count > 131072)
1915 return -ENOSPC;
1916 if (copy_from_user(saa->osdbuf, buf, count))
1917 return -EFAULT;
1918 buf += count;
1919 saa->osdhead = 0;
1920 saa->osdtail = count;
1921 debiwrite(saa, debNormal, IBM_MP2_OSD_ADDR, 0, 2);
1922 debiwrite(saa, debNormal, IBM_MP2_OSD_LINK_ADDR, 0, 2);
1923 debiwrite(saa, debNormal, IBM_MP2_MASK0, 0xc00d, 2);
1924 debiwrite(saa, debNormal, IBM_MP2_DISP_MODE,
1925 debiread(saa, debNormal,
1926 IBM_MP2_DISP_MODE, 2) | 1, 2);
1927 /* trigger osd data transfer */
1928 saawrite(SAA7146_PSR_DEBI_S |
1929 SAA7146_PSR_PIN1, SAA7146_IER);
1930 saawrite(SAA7146_PSR_PIN1, SAA7146_PSR);
1931 }
1932 }
1933 return count;
1934}
1935
1936static int saa_open(struct inode *inode, struct file *file)
1937{
1938 struct saa7146 *saa = NULL;
1939 unsigned int minor = iminor(inode);
1940 int i;
1941
1942 for (i = 0; i < SAA7146_MAX; i++) {
1943 if (saa7146s[i].video_dev.minor == minor) {
1944 saa = &saa7146s[i];
1945 }
1946 }
1947 if (saa == NULL) {
1948 return -ENODEV;
1949 }
1950 file->private_data = saa;
1951
1952 //saa->video_dev.busy = 0; /* old hack to support multiple open */
1953 saa->user++;
1954 if (saa->user > 1)
1955 return 0; /* device open already, don't reset */
1956 saa->writemode = VID_WRITE_MPEG_VID; /* default to video */
1957 return 0;
1958}
1959
1960static int saa_release(struct inode *inode, struct file *file)
1961{
1962 struct saa7146 *saa = file->private_data;
1963 saa->user--;
1964 //saa->video_dev.busy = 0; /* old hack to support multiple open */
1965 if (saa->user > 0) /* still someone using device */
1966 return 0;
1967 saawrite(0x007f0000, SAA7146_MC1); /* stop all overlay dma */
1968 return 0;
1969}
1970
1971static struct file_operations saa_fops =
1972{
1973 .owner = THIS_MODULE,
1974 .open = saa_open,
1975 .release = saa_release,
1976 .ioctl = saa_ioctl,
1977 .read = saa_read,
1978 .llseek = no_llseek,
1979 .write = saa_write,
1980 .mmap = saa_mmap,
1981};
1982
1983/* template for video_device-structure */
1984static struct video_device saa_template =
1985{
1986 .name = "SAA7146A",
1987 .type = VID_TYPE_CAPTURE | VID_TYPE_OVERLAY,
1988 .hardware = VID_HARDWARE_SAA7146,
1989 .fops = &saa_fops,
1990 .minor = -1,
1991};
1992
1993static int configure_saa7146(struct pci_dev *dev, int num)
1994{
1995 int result;
1996 struct saa7146 *saa;
1997
1998 saa = &saa7146s[num];
1999
2000 saa->endmarkhead = saa->endmarktail = 0;
2001 saa->win.x = saa->win.y = 0;
2002 saa->win.width = saa->win.cropwidth = 720;
2003 saa->win.height = saa->win.cropheight = 480;
2004 saa->win.cropx = saa->win.cropy = 0;
2005 saa->win.bpp = 2;
2006 saa->win.depth = 16;
2007 saa->win.color_fmt = palette2fmt[VIDEO_PALETTE_RGB565];
2008 saa->win.bpl = 1024 * saa->win.bpp;
2009 saa->win.swidth = 1024;
2010 saa->win.sheight = 768;
2011 saa->picture.brightness = 32768;
2012 saa->picture.contrast = 38768;
2013 saa->picture.colour = 32768;
2014 saa->cap = 0;
2015 saa->dev = dev;
2016 saa->nr = num;
2017 saa->playmode = VID_PLAY_NORMAL;
2018 memset(saa->boardcfg, 0, 64); /* clear board config area */
2019 saa->saa7146_mem = NULL;
2020 saa->dmavid1 = saa->dmavid2 = saa->dmavid3 = saa->dmaa1in =
2021 saa->dmaa1out = saa->dmaa2in = saa->dmaa2out =
2022 saa->pagevid1 = saa->pagevid2 = saa->pagevid3 = saa->pagea1in =
2023 saa->pagea1out = saa->pagea2in = saa->pagea2out =
2024 saa->pagedebi = saa->dmaRPS1 = saa->dmaRPS2 = saa->pageRPS1 =
2025 saa->pageRPS2 = NULL;
2026 saa->audbuf = saa->vidbuf = saa->osdbuf = saa->dmadebi = NULL;
2027 saa->audhead = saa->vidtail = 0;
2028
2029 init_waitqueue_head(&saa->i2cq);
2030 init_waitqueue_head(&saa->audq);
2031 init_waitqueue_head(&saa->debiq);
2032 init_waitqueue_head(&saa->vidq);
2033 spin_lock_init(&saa->lock);
2034
2035 if (pci_enable_device(dev))
2036 return -EIO;
2037
2038 saa->id = dev->device;
2039 saa->irq = dev->irq;
2040 saa->video_dev.minor = -1;
2041 saa->saa7146_adr = pci_resource_start(dev, 0);
2042 pci_read_config_byte(dev, PCI_CLASS_REVISION, &saa->revision);
2043
2044 saa->saa7146_mem = ioremap(saa->saa7146_adr, 0x200);
2045 if (!saa->saa7146_mem)
2046 return -EIO;
2047
2048 memcpy(&saa->video_dev, &saa_template, sizeof(saa_template));
2049 saawrite(0, SAA7146_IER); /* turn off all interrupts */
2050 result = request_irq(saa->irq, saa7146_irq,
2051 SA_SHIRQ | SA_INTERRUPT, "stradis", (void *) saa);
2052 if (result == -EINVAL)
2053 printk(KERN_ERR "stradis%d: Bad irq number or handler\n",
2054 num);
2055 if (result == -EBUSY)
2056 printk(KERN_ERR "stradis%d: IRQ %ld busy, change your PnP"
2057 " config in BIOS\n", num, saa->irq);
2058 if (result < 0) {
2059 iounmap(saa->saa7146_mem);
2060 return result;
2061 }
2062 pci_set_master(dev);
2063 if (video_register_device(&saa->video_dev, VFL_TYPE_GRABBER, video_nr) < 0) {
2064 iounmap(saa->saa7146_mem);
2065 return -1;
2066 }
2067 return 0;
2068}
2069
2070static int init_saa7146(int i)
2071{
2072 struct saa7146 *saa = &saa7146s[i];
2073
2074 saa->user = 0;
2075 /* reset the saa7146 */
2076 saawrite(0xffff0000, SAA7146_MC1);
2077 mdelay(5);
2078 /* enable debi and i2c transfers and pins */
2079 saawrite(((SAA7146_MC1_EDP | SAA7146_MC1_EI2C |
2080 SAA7146_MC1_TR_E_DEBI) << 16) | 0xffff, SAA7146_MC1);
2081 /* ensure proper state of chip */
2082 saawrite(0x00000000, SAA7146_PAGE1);
2083 saawrite(0x00f302c0, SAA7146_NUM_LINE_BYTE1);
2084 saawrite(0x00000000, SAA7146_PAGE2);
2085 saawrite(0x01400080, SAA7146_NUM_LINE_BYTE2);
2086 saawrite(0x00000000, SAA7146_DD1_INIT);
2087 saawrite(0x00000000, SAA7146_DD1_STREAM_B);
2088 saawrite(0x00000000, SAA7146_DD1_STREAM_A);
2089 saawrite(0x00000000, SAA7146_BRS_CTRL);
2090 saawrite(0x80400040, SAA7146_BCS_CTRL);
2091 saawrite(0x0000e000 /*| (1<<29)*/, SAA7146_HPS_CTRL);
2092 saawrite(0x00000060, SAA7146_CLIP_FORMAT_CTRL);
2093 saawrite(0x00000000, SAA7146_ACON1);
2094 saawrite(0x00000000, SAA7146_ACON2);
2095 saawrite(0x00000600, SAA7146_I2C_STATUS);
2096 saawrite(((SAA7146_MC2_UPLD_D1_B | SAA7146_MC2_UPLD_D1_A |
2097 SAA7146_MC2_UPLD_BRS | SAA7146_MC2_UPLD_HPS_H |
2098 SAA7146_MC2_UPLD_HPS_V | SAA7146_MC2_UPLD_DMA2 |
2099 SAA7146_MC2_UPLD_DMA1 | SAA7146_MC2_UPLD_I2C) << 16) | 0xffff,
2100 SAA7146_MC2);
2101 /* setup arbitration control registers */
2102 saawrite(0x1412121a, SAA7146_PCI_BT_V1);
2103
2104 /* allocate 32k dma buffer + 4k for page table */
2105 if ((saa->dmadebi = kmalloc(32768 + 4096, GFP_KERNEL)) == NULL) {
2106 printk(KERN_ERR "stradis%d: debi kmalloc failed\n", i);
2107 return -1;
2108 }
2109#if 0
2110 saa->pagedebi = saa->dmadebi + 32768; /* top 4k is for mmu */
2111 saawrite(virt_to_bus(saa->pagedebi) /*|0x800 */ , SAA7146_DEBI_PAGE);
2112 for (i = 0; i < 12; i++) /* setup mmu page table */
2113 saa->pagedebi[i] = virt_to_bus((saa->dmadebi + i * 4096));
2114#endif
2115 saa->audhead = saa->vidhead = saa->osdhead = 0;
2116 saa->audtail = saa->vidtail = saa->osdtail = 0;
2117 if (saa->vidbuf == NULL)
2118 if ((saa->vidbuf = vmalloc(524288)) == NULL) {
2119 printk(KERN_ERR "stradis%d: malloc failed\n", saa->nr);
2120 return -ENOMEM;
2121 }
2122 if (saa->audbuf == NULL)
2123 if ((saa->audbuf = vmalloc(65536)) == NULL) {
2124 printk(KERN_ERR "stradis%d: malloc failed\n", saa->nr);
2125 vfree(saa->vidbuf);
2126 saa->vidbuf = NULL;
2127 return -ENOMEM;
2128 }
2129 if (saa->osdbuf == NULL)
2130 if ((saa->osdbuf = vmalloc(131072)) == NULL) {
2131 printk(KERN_ERR "stradis%d: malloc failed\n", saa->nr);
2132 vfree(saa->vidbuf);
2133 vfree(saa->audbuf);
2134 saa->vidbuf = saa->audbuf = NULL;
2135 return -ENOMEM;
2136 }
2137 /* allocate 81920 byte buffer for clipping */
2138 if ((saa->dmavid2 = kmalloc(VIDEO_CLIPMAP_SIZE, GFP_KERNEL)) == NULL) {
2139 printk(KERN_ERR "stradis%d: clip kmalloc failed\n", saa->nr);
2140 vfree(saa->vidbuf);
2141 vfree(saa->audbuf);
2142 vfree(saa->osdbuf);
2143 saa->vidbuf = saa->audbuf = saa->osdbuf = NULL;
2144 saa->dmavid2 = NULL;
2145 return -1;
2146 }
2147 memset(saa->dmavid2, 0x00, VIDEO_CLIPMAP_SIZE); /* clip everything */
2148 /* setup clipping registers */
2149 saawrite(virt_to_bus(saa->dmavid2), SAA7146_BASE_EVEN2);
2150 saawrite(virt_to_bus(saa->dmavid2) + 128, SAA7146_BASE_ODD2);
2151 saawrite(virt_to_bus(saa->dmavid2) + VIDEO_CLIPMAP_SIZE,
2152 SAA7146_PROT_ADDR2);
2153 saawrite(256, SAA7146_PITCH2);
2154 saawrite(4, SAA7146_PAGE2); /* dma direction: read, no byteswap */
2155 saawrite(((SAA7146_MC2_UPLD_DMA2) << 16) | SAA7146_MC2_UPLD_DMA2,
2156 SAA7146_MC2);
2157 I2CBusScan(saa);
2158 return 0;
2159}
2160
2161static void release_saa(void)
2162{
2163 u8 command;
2164 int i;
2165 struct saa7146 *saa;
2166
2167 for (i = 0; i < saa_num; i++) {
2168 saa = &saa7146s[i];
2169
2170 /* turn off all capturing, DMA and IRQs */
2171 saawrite(0xffff0000, SAA7146_MC1); /* reset chip */
2172 saawrite(0, SAA7146_MC2);
2173 saawrite(0, SAA7146_IER);
2174 saawrite(0xffffffffUL, SAA7146_ISR);
2175
2176 /* disable PCI bus-mastering */
2177 pci_read_config_byte(saa->dev, PCI_COMMAND, &command);
2178 command &= ~PCI_COMMAND_MASTER;
2179 pci_write_config_byte(saa->dev, PCI_COMMAND, command);
2180
2181 /* unmap and free memory */
2182 saa->audhead = saa->audtail = saa->osdhead = 0;
2183 saa->vidhead = saa->vidtail = saa->osdtail = 0;
2184 vfree(saa->vidbuf);
2185 vfree(saa->audbuf);
2186 vfree(saa->osdbuf);
2187 if (saa->dmavid2)
2188 kfree((void *) saa->dmavid2);
2189 saa->audbuf = saa->vidbuf = saa->osdbuf = NULL;
2190 saa->dmavid2 = NULL;
2191 if (saa->dmadebi)
2192 kfree((void *) saa->dmadebi);
2193 if (saa->dmavid1)
2194 kfree((void *) saa->dmavid1);
2195 if (saa->dmavid2)
2196 kfree((void *) saa->dmavid2);
2197 if (saa->dmavid3)
2198 kfree((void *) saa->dmavid3);
2199 if (saa->dmaa1in)
2200 kfree((void *) saa->dmaa1in);
2201 if (saa->dmaa1out)
2202 kfree((void *) saa->dmaa1out);
2203 if (saa->dmaa2in)
2204 kfree((void *) saa->dmaa2in);
2205 if (saa->dmaa2out)
2206 kfree((void *) saa->dmaa2out);
2207 if (saa->dmaRPS1)
2208 kfree((void *) saa->dmaRPS1);
2209 if (saa->dmaRPS2)
2210 kfree((void *) saa->dmaRPS2);
2211 free_irq(saa->irq, saa);
2212 if (saa->saa7146_mem)
2213 iounmap(saa->saa7146_mem);
2214 if (saa->video_dev.minor != -1)
2215 video_unregister_device(&saa->video_dev);
2216 }
2217}
2218
2219
2220static int __init stradis_init (void)
2221{
2222 struct pci_dev *dev = NULL;
2223 int result = 0, i;
2224
2225 saa_num = 0;
2226
2227 while ((dev = pci_find_device(PCI_VENDOR_ID_PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7146, dev))) {
2228 if (!dev->subsystem_vendor)
2229 printk(KERN_INFO "stradis%d: rev1 decoder\n", saa_num);
2230 else
2231 printk(KERN_INFO "stradis%d: SDM2xx found\n", saa_num);
2232 result = configure_saa7146(dev, saa_num++);
2233 if (result)
2234 return result;
2235 }
2236 if (saa_num)
2237 printk(KERN_INFO "stradis: %d card(s) found.\n", saa_num);
2238 else
2239 return -EINVAL;
2240 for (i = 0; i < saa_num; i++)
2241 if (init_saa7146(i) < 0) {
2242 release_saa();
2243 return -EIO;
2244 }
2245 return 0;
2246}
2247
2248
2249static void __exit stradis_exit (void)
2250{
2251 release_saa();
2252 printk(KERN_INFO "stradis: module cleanup complete\n");
2253}
2254
2255
2256module_init(stradis_init);
2257module_exit(stradis_exit);
2258
diff --git a/drivers/media/video/tda7432.c b/drivers/media/video/tda7432.c
new file mode 100644
index 00000000000..376a4a439e9
--- /dev/null
+++ b/drivers/media/video/tda7432.c
@@ -0,0 +1,556 @@
1/*
2 * For the STS-Thompson TDA7432 audio processor chip
3 *
4 * Handles audio functions: volume, balance, tone, loudness
5 * This driver will not complain if used with any
6 * other i2c device with the same address.
7 *
8 * Muting and tone control by Jonathan Isom <jisom@ematic.com>
9 *
10 * Copyright (c) 2000 Eric Sandeen <eric_sandeen@bigfoot.com>
11 * This code is placed under the terms of the GNU General Public License
12 * Based on tda9855.c by Steve VanDeBogart (vandebo@uclink.berkeley.edu)
13 * Which was based on tda8425.c by Greg Alexander (c) 1998
14 *
15 * OPTIONS:
16 * debug - set to 1 if you'd like to see debug messages
17 * set to 2 if you'd like to be inundated with debug messages
18 *
19 * loudness - set between 0 and 15 for varying degrees of loudness effect
20 *
21 * maxvol - set maximium volume to +20db (1), default is 0db(0)
22 *
23 *
24 * Revision: 0.7 - maxvol module parm to set maximium volume 0db or +20db
25 * store if muted so we can return it
26 * change balance only if flaged to
27 * Revision: 0.6 - added tone controls
28 * Revision: 0.5 - Fixed odd balance problem
29 * Revision: 0.4 - added muting
30 * Revision: 0.3 - Fixed silly reversed volume controls. :)
31 * Revision: 0.2 - Cleaned up #defines
32 * fixed volume control
33 * Added I2C_DRIVERID_TDA7432
34 * added loudness insmod control
35 * Revision: 0.1 - initial version
36 */
37
38#include <linux/module.h>
39#include <linux/init.h>
40#include <linux/kernel.h>
41#include <linux/sched.h>
42#include <linux/string.h>
43#include <linux/timer.h>
44#include <linux/delay.h>
45#include <linux/errno.h>
46#include <linux/slab.h>
47#include <linux/videodev.h>
48#include <linux/i2c.h>
49#include <linux/i2c-algo-bit.h>
50
51#include "bttv.h"
52#include <media/audiochip.h>
53#include <media/id.h>
54
55#ifndef VIDEO_AUDIO_BALANCE
56# define VIDEO_AUDIO_BALANCE 32
57#endif
58
59MODULE_AUTHOR("Eric Sandeen <eric_sandeen@bigfoot.com>");
60MODULE_DESCRIPTION("bttv driver for the tda7432 audio processor chip");
61MODULE_LICENSE("GPL");
62
63static int maxvol;
64static int loudness; /* disable loudness by default */
65static int debug; /* insmod parameter */
66module_param(debug, int, S_IRUGO | S_IWUSR);
67module_param(loudness, int, S_IRUGO);
68MODULE_PARM_DESC(maxvol,"Set maximium volume to +20db (0), default is 0db(1)");
69module_param(maxvol, int, S_IRUGO | S_IWUSR);
70
71
72/* Address to scan (I2C address of this chip) */
73static unsigned short normal_i2c[] = {
74 I2C_TDA7432 >> 1,
75 I2C_CLIENT_END,
76};
77static unsigned short normal_i2c_range[] = { I2C_CLIENT_END, I2C_CLIENT_END };
78I2C_CLIENT_INSMOD;
79
80/* Structure of address and subaddresses for the tda7432 */
81
82struct tda7432 {
83 int addr;
84 int input;
85 int volume;
86 int muted;
87 int bass, treble;
88 int lf, lr, rf, rr;
89 int loud;
90 struct i2c_client c;
91};
92static struct i2c_driver driver;
93static struct i2c_client client_template;
94
95#define dprintk if (debug) printk
96#define d2printk if (debug > 1) printk
97
98/* The TDA7432 is made by STS-Thompson
99 * http://www.st.com
100 * http://us.st.com/stonline/books/pdf/docs/4056.pdf
101 *
102 * TDA7432: I2C-bus controlled basic audio processor
103 *
104 * The TDA7432 controls basic audio functions like volume, balance,
105 * and tone control (including loudness). It also has four channel
106 * output (for front and rear). Since most vidcap cards probably
107 * don't have 4 channel output, this driver will set front & rear
108 * together (no independent control).
109 */
110
111 /* Subaddresses for TDA7432 */
112
113#define TDA7432_IN 0x00 /* Input select */
114#define TDA7432_VL 0x01 /* Volume */
115#define TDA7432_TN 0x02 /* Bass, Treble (Tone) */
116#define TDA7432_LF 0x03 /* Attenuation LF (Left Front) */
117#define TDA7432_LR 0x04 /* Attenuation LR (Left Rear) */
118#define TDA7432_RF 0x05 /* Attenuation RF (Right Front) */
119#define TDA7432_RR 0x06 /* Attenuation RR (Right Rear) */
120#define TDA7432_LD 0x07 /* Loudness */
121
122
123 /* Masks for bits in TDA7432 subaddresses */
124
125/* Many of these not used - just for documentation */
126
127/* Subaddress 0x00 - Input selection and bass control */
128
129/* Bits 0,1,2 control input:
130 * 0x00 - Stereo input
131 * 0x02 - Mono input
132 * 0x03 - Mute (Using Attenuators Plays better with modules)
133 * Mono probably isn't used - I'm guessing only the stereo
134 * input is connected on most cards, so we'll set it to stereo.
135 *
136 * Bit 3 controls bass cut: 0/1 is non-symmetric/symmetric bass cut
137 * Bit 4 controls bass range: 0/1 is extended/standard bass range
138 *
139 * Highest 3 bits not used
140 */
141
142#define TDA7432_STEREO_IN 0
143#define TDA7432_MONO_IN 2 /* Probably won't be used */
144#define TDA7432_BASS_SYM 1 << 3
145#define TDA7432_BASS_NORM 1 << 4
146
147/* Subaddress 0x01 - Volume */
148
149/* Lower 7 bits control volume from -79dB to +32dB in 1dB steps
150 * Recommended maximum is +20 dB
151 *
152 * +32dB: 0x00
153 * +20dB: 0x0c
154 * 0dB: 0x20
155 * -79dB: 0x6f
156 *
157 * MSB (bit 7) controls loudness: 1/0 is loudness on/off
158 */
159
160#define TDA7432_VOL_0DB 0x20
161#define TDA7432_LD_ON 1 << 7
162
163
164/* Subaddress 0x02 - Tone control */
165
166/* Bits 0,1,2 control absolute treble gain from 0dB to 14dB
167 * 0x0 is 14dB, 0x7 is 0dB
168 *
169 * Bit 3 controls treble attenuation/gain (sign)
170 * 1 = gain (+)
171 * 0 = attenuation (-)
172 *
173 * Bits 4,5,6 control absolute bass gain from 0dB to 14dB
174 * (This is only true for normal base range, set in 0x00)
175 * 0x0 << 4 is 14dB, 0x7 is 0dB
176 *
177 * Bit 7 controls bass attenuation/gain (sign)
178 * 1 << 7 = gain (+)
179 * 0 << 7 = attenuation (-)
180 *
181 * Example:
182 * 1 1 0 1 0 1 0 1 is +4dB bass, -4dB treble
183 */
184
185#define TDA7432_TREBLE_0DB 0xf
186#define TDA7432_TREBLE 7
187#define TDA7432_TREBLE_GAIN 1 << 3
188#define TDA7432_BASS_0DB 0xf
189#define TDA7432_BASS 7 << 4
190#define TDA7432_BASS_GAIN 1 << 7
191
192
193/* Subaddress 0x03 - Left Front attenuation */
194/* Subaddress 0x04 - Left Rear attenuation */
195/* Subaddress 0x05 - Right Front attenuation */
196/* Subaddress 0x06 - Right Rear attenuation */
197
198/* Bits 0,1,2,3,4 control attenuation from 0dB to -37.5dB
199 * in 1.5dB steps.
200 *
201 * 0x00 is 0dB
202 * 0x1f is -37.5dB
203 *
204 * Bit 5 mutes that channel when set (1 = mute, 0 = unmute)
205 * We'll use the mute on the input, though (above)
206 * Bits 6,7 unused
207 */
208
209#define TDA7432_ATTEN_0DB 0x00
210#define TDA7432_MUTE 0x1 << 5
211
212
213/* Subaddress 0x07 - Loudness Control */
214
215/* Bits 0,1,2,3 control loudness from 0dB to -15dB in 1dB steps
216 * when bit 4 is NOT set
217 *
218 * 0x0 is 0dB
219 * 0xf is -15dB
220 *
221 * If bit 4 is set, then there is a flat attenuation according to
222 * the lower 4 bits, as above.
223 *
224 * Bits 5,6,7 unused
225 */
226
227
228
229/* Begin code */
230
231static int tda7432_write(struct i2c_client *client, int subaddr, int val)
232{
233 unsigned char buffer[2];
234 d2printk("tda7432: In tda7432_write\n");
235 dprintk("tda7432: Writing %d 0x%x\n", subaddr, val);
236 buffer[0] = subaddr;
237 buffer[1] = val;
238 if (2 != i2c_master_send(client,buffer,2)) {
239 printk(KERN_WARNING "tda7432: I/O error, trying (write %d 0x%x)\n",
240 subaddr, val);
241 return -1;
242 }
243 return 0;
244}
245
246/* I don't think we ever actually _read_ the chip... */
247#if 0
248static int tda7432_read(struct i2c_client *client)
249{
250 unsigned char buffer;
251 d2printk("tda7432: In tda7432_read\n");
252 if (1 != i2c_master_recv(client,&buffer,1)) {
253 printk(KERN_WARNING "tda7432: I/O error, trying (read)\n");
254 return -1;
255 }
256 dprintk("tda7432: Read 0x%02x\n", buffer);
257 return buffer;
258}
259#endif
260
261static int tda7432_set(struct i2c_client *client)
262{
263 struct tda7432 *t = i2c_get_clientdata(client);
264 unsigned char buf[16];
265 d2printk("tda7432: In tda7432_set\n");
266
267 dprintk(KERN_INFO
268 "tda7432: 7432_set(0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x)\n",
269 t->input,t->volume,t->bass,t->treble,t->lf,t->lr,t->rf,t->rr,t->loud);
270 buf[0] = TDA7432_IN;
271 buf[1] = t->input;
272 buf[2] = t->volume;
273 buf[3] = t->bass;
274 buf[4] = t->treble;
275 buf[5] = t->lf;
276 buf[6] = t->lr;
277 buf[7] = t->rf;
278 buf[8] = t->rr;
279 buf[9] = t->loud;
280 if (10 != i2c_master_send(client,buf,10)) {
281 printk(KERN_WARNING "tda7432: I/O error, trying tda7432_set\n");
282 return -1;
283 }
284
285 return 0;
286}
287
288static void do_tda7432_init(struct i2c_client *client)
289{
290 struct tda7432 *t = i2c_get_clientdata(client);
291 d2printk("tda7432: In tda7432_init\n");
292
293 t->input = TDA7432_STEREO_IN | /* Main (stereo) input */
294 TDA7432_BASS_SYM | /* Symmetric bass cut */
295 TDA7432_BASS_NORM; /* Normal bass range */
296 t->volume = 0x3b ; /* -27dB Volume */
297 if (loudness) /* Turn loudness on? */
298 t->volume |= TDA7432_LD_ON;
299 t->muted = VIDEO_AUDIO_MUTE;
300 t->treble = TDA7432_TREBLE_0DB; /* 0dB Treble */
301 t->bass = TDA7432_BASS_0DB; /* 0dB Bass */
302 t->lf = TDA7432_ATTEN_0DB; /* 0dB attenuation */
303 t->lr = TDA7432_ATTEN_0DB; /* 0dB attenuation */
304 t->rf = TDA7432_ATTEN_0DB; /* 0dB attenuation */
305 t->rr = TDA7432_ATTEN_0DB; /* 0dB attenuation */
306 t->loud = loudness; /* insmod parameter */
307
308 tda7432_set(client);
309}
310
311/* *********************** *
312 * i2c interface functions *
313 * *********************** */
314
315static int tda7432_attach(struct i2c_adapter *adap, int addr, int kind)
316{
317 struct tda7432 *t;
318 struct i2c_client *client;
319 d2printk("tda7432: In tda7432_attach\n");
320
321 t = kmalloc(sizeof *t,GFP_KERNEL);
322 if (!t)
323 return -ENOMEM;
324 memset(t,0,sizeof *t);
325
326 client = &t->c;
327 memcpy(client,&client_template,sizeof(struct i2c_client));
328 client->adapter = adap;
329 client->addr = addr;
330 i2c_set_clientdata(client, t);
331
332 do_tda7432_init(client);
333 printk(KERN_INFO "tda7432: init\n");
334
335 i2c_attach_client(client);
336 return 0;
337}
338
339static int tda7432_probe(struct i2c_adapter *adap)
340{
341#ifdef I2C_CLASS_TV_ANALOG
342 if (adap->class & I2C_CLASS_TV_ANALOG)
343 return i2c_probe(adap, &addr_data, tda7432_attach);
344#else
345 if (adap->id == (I2C_ALGO_BIT | I2C_HW_B_BT848))
346 return i2c_probe(adap, &addr_data, tda7432_attach);
347#endif
348 return 0;
349}
350
351static int tda7432_detach(struct i2c_client *client)
352{
353 struct tda7432 *t = i2c_get_clientdata(client);
354
355 do_tda7432_init(client);
356 i2c_detach_client(client);
357
358 kfree(t);
359 return 0;
360}
361
362static int tda7432_command(struct i2c_client *client,
363 unsigned int cmd, void *arg)
364{
365 struct tda7432 *t = i2c_get_clientdata(client);
366 d2printk("tda7432: In tda7432_command\n");
367
368 switch (cmd) {
369 /* --- v4l ioctls --- */
370 /* take care: bttv does userspace copying, we'll get a
371 kernel pointer here... */
372
373 /* Query card - scale from TDA7432 settings to V4L settings */
374 case VIDIOCGAUDIO:
375 {
376 struct video_audio *va = arg;
377 dprintk("tda7432: VIDIOCGAUDIO\n");
378
379 va->flags |= VIDEO_AUDIO_VOLUME |
380 VIDEO_AUDIO_BASS |
381 VIDEO_AUDIO_TREBLE |
382 VIDEO_AUDIO_MUTABLE;
383 if (t->muted)
384 va->flags |= VIDEO_AUDIO_MUTE;
385 va->mode |= VIDEO_SOUND_STEREO;
386 /* Master volume control
387 * V4L volume is min 0, max 65535
388 * TDA7432 Volume:
389 * Min (-79dB) is 0x6f
390 * Max (+20dB) is 0x07 (630)
391 * Max (0dB) is 0x20 (829)
392 * (Mask out bit 7 of vol - it's for the loudness setting)
393 */
394 if (!maxvol){ /* max +20db */
395 va->volume = ( 0x6f - (t->volume & 0x7F) ) * 630;
396 } else { /* max 0db */
397 va->volume = ( 0x6f - (t->volume & 0x7F) ) * 829;
398 }
399
400 /* Balance depends on L,R attenuation
401 * V4L balance is 0 to 65535, middle is 32768
402 * TDA7432 attenuation: min (0dB) is 0, max (-37.5dB) is 0x1f
403 * to scale up to V4L numbers, mult by 1057
404 * attenuation exists for lf, lr, rf, rr
405 * we use only lf and rf (front channels)
406 */
407
408 if ( (t->lf) < (t->rf) )
409 /* right is attenuated, balance shifted left */
410 va->balance = (32768 - 1057*(t->rf));
411 else
412 /* left is attenuated, balance shifted right */
413 va->balance = (32768 + 1057*(t->lf));
414
415 /* Bass/treble 4 bits each */
416 va->bass=t->bass;
417 if(va->bass >= 0x8)
418 va->bass = ~(va->bass - 0x8) & 0xf;
419 va->bass = (va->bass << 12)+(va->bass << 8)+(va->bass << 4)+(va->bass);
420 va->treble=t->treble;
421 if(va->treble >= 0x8)
422 va->treble = ~(va->treble - 0x8) & 0xf;
423 va->treble = (va->treble << 12)+(va->treble << 8)+(va->treble << 4)+(va->treble);
424
425 break; /* VIDIOCGAUDIO case */
426 }
427
428 /* Set card - scale from V4L settings to TDA7432 settings */
429 case VIDIOCSAUDIO:
430 {
431 struct video_audio *va = arg;
432 dprintk("tda7432: VIDEOCSAUDIO\n");
433
434 if(va->flags & VIDEO_AUDIO_VOLUME){
435 if(!maxvol){ /* max +20db */
436 t->volume = 0x6f - ((va->volume)/630);
437 } else { /* max 0db */
438 t->volume = 0x6f - ((va->volume)/829);
439 }
440
441 if (loudness) /* Turn on the loudness bit */
442 t->volume |= TDA7432_LD_ON;
443
444 tda7432_write(client,TDA7432_VL, t->volume);
445 }
446
447 if(va->flags & VIDEO_AUDIO_BASS)
448 {
449 t->bass = va->bass >> 12;
450 if(t->bass>= 0x8)
451 t->bass = (~t->bass & 0xf) + 0x8 ;
452 }
453 if(va->flags & VIDEO_AUDIO_TREBLE)
454 {
455 t->treble= va->treble >> 12;
456 if(t->treble>= 0x8)
457 t->treble = (~t->treble & 0xf) + 0x8 ;
458 }
459 if(va->flags & (VIDEO_AUDIO_TREBLE| VIDEO_AUDIO_BASS))
460 tda7432_write(client,TDA7432_TN, 0x10 | (t->bass << 4) | t->treble );
461
462 if(va->flags & VIDEO_AUDIO_BALANCE) {
463 if (va->balance < 32768)
464 {
465 /* shifted to left, attenuate right */
466 t->rr = (32768 - va->balance)/1057;
467 t->rf = t->rr;
468 t->lr = TDA7432_ATTEN_0DB;
469 t->lf = TDA7432_ATTEN_0DB;
470 }
471 else if(va->balance > 32769)
472 {
473 /* shifted to right, attenuate left */
474 t->lf = (va->balance - 32768)/1057;
475 t->lr = t->lf;
476 t->rr = TDA7432_ATTEN_0DB;
477 t->rf = TDA7432_ATTEN_0DB;
478 }
479 else
480 {
481 /* centered */
482 t->rr = TDA7432_ATTEN_0DB;
483 t->rf = TDA7432_ATTEN_0DB;
484 t->lf = TDA7432_ATTEN_0DB;
485 t->lr = TDA7432_ATTEN_0DB;
486 }
487 }
488
489 t->muted=(va->flags & VIDEO_AUDIO_MUTE);
490 if (t->muted)
491 {
492 /* Mute & update balance*/
493 tda7432_write(client,TDA7432_LF, t->lf | TDA7432_MUTE);
494 tda7432_write(client,TDA7432_LR, t->lr | TDA7432_MUTE);
495 tda7432_write(client,TDA7432_RF, t->rf | TDA7432_MUTE);
496 tda7432_write(client,TDA7432_RR, t->rr | TDA7432_MUTE);
497 } else {
498 tda7432_write(client,TDA7432_LF, t->lf);
499 tda7432_write(client,TDA7432_LR, t->lr);
500 tda7432_write(client,TDA7432_RF, t->rf);
501 tda7432_write(client,TDA7432_RR, t->rr);
502 }
503
504 break;
505
506 } /* end of VIDEOCSAUDIO case */
507
508 default: /* Not VIDEOCGAUDIO or VIDEOCSAUDIO */
509
510 /* nothing */
511 d2printk("tda7432: Default\n");
512
513 } /* end of (cmd) switch */
514
515 return 0;
516}
517
518static struct i2c_driver driver = {
519 .owner = THIS_MODULE,
520 .name = "i2c tda7432 driver",
521 .id = I2C_DRIVERID_TDA7432,
522 .flags = I2C_DF_NOTIFY,
523 .attach_adapter = tda7432_probe,
524 .detach_client = tda7432_detach,
525 .command = tda7432_command,
526};
527
528static struct i2c_client client_template =
529{
530 I2C_DEVNAME("tda7432"),
531 .driver = &driver,
532};
533
534static int __init tda7432_init(void)
535{
536 if ( (loudness < 0) || (loudness > 15) ) {
537 printk(KERN_ERR "tda7432: loudness parameter must be between 0 and 15\n");
538 return -EINVAL;
539 }
540
541 return i2c_add_driver(&driver);
542}
543
544static void __exit tda7432_fini(void)
545{
546 i2c_del_driver(&driver);
547}
548
549module_init(tda7432_init);
550module_exit(tda7432_fini);
551
552/*
553 * Local variables:
554 * c-basic-offset: 8
555 * End:
556 */
diff --git a/drivers/media/video/tda8290.c b/drivers/media/video/tda8290.c
new file mode 100644
index 00000000000..b27cc348d95
--- /dev/null
+++ b/drivers/media/video/tda8290.c
@@ -0,0 +1,224 @@
1/*
2 * $Id: tda8290.c,v 1.7 2005/03/07 12:01:51 kraxel Exp $
3 *
4 * i2c tv tuner chip device driver
5 * controls the philips tda8290+75 tuner chip combo.
6 */
7#include <linux/i2c.h>
8#include <linux/videodev.h>
9#include <linux/delay.h>
10#include <media/tuner.h>
11
12/* ---------------------------------------------------------------------- */
13
14struct freq_entry {
15 u16 freq;
16 u8 value;
17};
18
19static struct freq_entry band_table[] = {
20 { 0x2DF4, 0x1C },
21 { 0x2574, 0x14 },
22 { 0x22B4, 0x0C },
23 { 0x20D4, 0x0B },
24 { 0x1E74, 0x3B },
25 { 0x1C34, 0x33 },
26 { 0x16F4, 0x5B },
27 { 0x1454, 0x53 },
28 { 0x12D4, 0x52 },
29 { 0x1034, 0x4A },
30 { 0x0EE4, 0x7A },
31 { 0x0D34, 0x72 },
32 { 0x0B54, 0x9A },
33 { 0x0914, 0x91 },
34 { 0x07F4, 0x89 },
35 { 0x0774, 0xB9 },
36 { 0x067B, 0xB1 },
37 { 0x0634, 0xD9 },
38 { 0x05A4, 0xD8 }, // FM radio
39 { 0x0494, 0xD0 },
40 { 0x03BC, 0xC8 },
41 { 0x0394, 0xF8 }, // 57250000 Hz
42 { 0x0000, 0xF0 }, // 0
43};
44
45static struct freq_entry div_table[] = {
46 { 0x1C34, 3 },
47 { 0x0D34, 2 },
48 { 0x067B, 1 },
49 { 0x0000, 0 },
50};
51
52static struct freq_entry agc_table[] = {
53 { 0x22B4, 0x8F },
54 { 0x0B54, 0x9F },
55 { 0x09A4, 0x8F },
56 { 0x0554, 0x9F },
57 { 0x0000, 0xBF },
58};
59
60static __u8 get_freq_entry( struct freq_entry* table, __u16 freq)
61{
62 while(table->freq && table->freq > freq)
63 table++;
64 return table->value;
65}
66
67/* ---------------------------------------------------------------------- */
68
69static unsigned char i2c_enable_bridge[2] = { 0x21, 0xC0 };
70static unsigned char i2c_disable_bridge[2] = { 0x21, 0x80 };
71static unsigned char i2c_init_tda8275[14] = { 0x00, 0x00, 0x00, 0x00,
72 0x7C, 0x04, 0xA3, 0x3F,
73 0x2A, 0x04, 0xFF, 0x00,
74 0x00, 0x40 };
75static unsigned char i2c_set_VS[2] = { 0x30, 0x6F };
76static unsigned char i2c_set_GP01_CF[2] = { 0x20, 0x0B };
77static unsigned char i2c_tda8290_reset[2] = { 0x00, 0x00 };
78static unsigned char i2c_gainset_off[2] = { 0x28, 0x14 };
79static unsigned char i2c_gainset_on[2] = { 0x28, 0x54 };
80static unsigned char i2c_agc3_00[2] = { 0x80, 0x00 };
81static unsigned char i2c_agc2_BF[2] = { 0x60, 0xBF };
82static unsigned char i2c_cb1_D2[2] = { 0x30, 0xD2 };
83static unsigned char i2c_cb1_56[2] = { 0x30, 0x56 };
84static unsigned char i2c_cb1_52[2] = { 0x30, 0x52 };
85static unsigned char i2c_cb1_50[2] = { 0x30, 0x50 };
86static unsigned char i2c_agc2_7F[2] = { 0x60, 0x7F };
87static unsigned char i2c_agc3_08[2] = { 0x80, 0x08 };
88
89static struct i2c_msg i2c_msg_init[] = {
90 { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_init_tda8275), i2c_init_tda8275 },
91 { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_disable_bridge), i2c_disable_bridge },
92 { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_set_VS), i2c_set_VS },
93 { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_set_GP01_CF), i2c_set_GP01_CF },
94};
95
96static struct i2c_msg i2c_msg_prolog[] = {
97// { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_easy_mode), i2c_easy_mode },
98 { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_gainset_off), i2c_gainset_off },
99 { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_tda8290_reset), i2c_tda8290_reset },
100 { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_enable_bridge), i2c_enable_bridge },
101};
102
103static struct i2c_msg i2c_msg_config[] = {
104// { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_set_freq), i2c_set_freq },
105 { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_agc3_00), i2c_agc3_00 },
106 { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_agc2_BF), i2c_agc2_BF },
107 { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_cb1_D2), i2c_cb1_D2 },
108 { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_cb1_56), i2c_cb1_56 },
109 { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_cb1_52), i2c_cb1_52 },
110};
111
112static struct i2c_msg i2c_msg_epilog[] = {
113 { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_cb1_50), i2c_cb1_50 },
114 { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_agc2_7F), i2c_agc2_7F },
115 { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_agc3_08), i2c_agc3_08 },
116 { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_disable_bridge), i2c_disable_bridge },
117 { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_gainset_on), i2c_gainset_on },
118};
119
120static int tda8290_tune(struct i2c_client *c)
121{
122 struct tuner *t = i2c_get_clientdata(c);
123 struct i2c_msg easy_mode =
124 { I2C_ADDR_TDA8290, 0, 2, t->i2c_easy_mode };
125 struct i2c_msg set_freq =
126 { I2C_ADDR_TDA8275, 0, 8, t->i2c_set_freq };
127
128 i2c_transfer(c->adapter, &easy_mode, 1);
129 i2c_transfer(c->adapter, i2c_msg_prolog, ARRAY_SIZE(i2c_msg_prolog));
130
131 i2c_transfer(c->adapter, &set_freq, 1);
132 i2c_transfer(c->adapter, i2c_msg_config, ARRAY_SIZE(i2c_msg_config));
133
134 msleep(550);
135 i2c_transfer(c->adapter, i2c_msg_epilog, ARRAY_SIZE(i2c_msg_epilog));
136 return 0;
137}
138
139static void set_frequency(struct tuner *t, u16 ifc)
140{
141 u32 N = (((t->freq<<3)+ifc)&0x3fffc);
142
143 N = N >> get_freq_entry(div_table, t->freq);
144 t->i2c_set_freq[0] = 0;
145 t->i2c_set_freq[1] = (unsigned char)(N>>8);
146 t->i2c_set_freq[2] = (unsigned char) N;
147 t->i2c_set_freq[3] = 0x40;
148 t->i2c_set_freq[4] = 0x52;
149 t->i2c_set_freq[5] = get_freq_entry(band_table, t->freq);
150 t->i2c_set_freq[6] = get_freq_entry(agc_table, t->freq);
151 t->i2c_set_freq[7] = 0x8f;
152}
153
154#define V4L2_STD_MN (V4L2_STD_PAL_M|V4L2_STD_PAL_N|V4L2_STD_PAL_Nc|V4L2_STD_NTSC)
155#define V4L2_STD_B (V4L2_STD_PAL_B|V4L2_STD_PAL_B1|V4L2_STD_SECAM_B)
156#define V4L2_STD_GH (V4L2_STD_PAL_G|V4L2_STD_PAL_H|V4L2_STD_SECAM_G|V4L2_STD_SECAM_H)
157#define V4L2_STD_DK (V4L2_STD_PAL_DK|V4L2_STD_SECAM_DK)
158
159static void set_audio(struct tuner *t)
160{
161 t->i2c_easy_mode[0] = 0x01;
162
163 if (t->std & V4L2_STD_MN)
164 t->i2c_easy_mode[1] = 0x01;
165 else if (t->std & V4L2_STD_B)
166 t->i2c_easy_mode[1] = 0x02;
167 else if (t->std & V4L2_STD_GH)
168 t->i2c_easy_mode[1] = 0x04;
169 else if (t->std & V4L2_STD_PAL_I)
170 t->i2c_easy_mode[1] = 0x08;
171 else if (t->std & V4L2_STD_DK)
172 t->i2c_easy_mode[1] = 0x10;
173 else if (t->std & V4L2_STD_SECAM_L)
174 t->i2c_easy_mode[1] = 0x20;
175}
176
177static void set_tv_freq(struct i2c_client *c, unsigned int freq)
178{
179 struct tuner *t = i2c_get_clientdata(c);
180
181 set_audio(t);
182 set_frequency(t, 864);
183 tda8290_tune(c);
184}
185
186static void set_radio_freq(struct i2c_client *c, unsigned int freq)
187{
188 struct tuner *t = i2c_get_clientdata(c);
189 set_frequency(t, 704);
190 tda8290_tune(c);
191}
192
193static int has_signal(struct i2c_client *c)
194{
195 unsigned char i2c_get_afc[1] = { 0x1B };
196 unsigned char afc = 0;
197
198 i2c_master_send(c, i2c_get_afc, ARRAY_SIZE(i2c_get_afc));
199 i2c_master_recv(c, &afc, 1);
200 return (afc & 0x80)? 65535:0;
201}
202
203int tda8290_init(struct i2c_client *c)
204{
205 struct tuner *t = i2c_get_clientdata(c);
206
207 strlcpy(c->name, "tda8290+75", sizeof(c->name));
208 tuner_info("tuner: type set to %s\n", c->name);
209 t->tv_freq = set_tv_freq;
210 t->radio_freq = set_radio_freq;
211 t->has_signal = has_signal;
212
213 i2c_master_send(c, i2c_enable_bridge, ARRAY_SIZE(i2c_enable_bridge));
214 i2c_transfer(c->adapter, i2c_msg_init, ARRAY_SIZE(i2c_msg_init));
215 return 0;
216}
217
218/*
219 * Overrides for Emacs so that we follow Linus's tabbing style.
220 * ---------------------------------------------------------------------------
221 * Local variables:
222 * c-basic-offset: 8
223 * End:
224 */
diff --git a/drivers/media/video/tda9840.c b/drivers/media/video/tda9840.c
new file mode 100644
index 00000000000..b5177c6f54f
--- /dev/null
+++ b/drivers/media/video/tda9840.c
@@ -0,0 +1,254 @@
1 /*
2 tda9840 - i2c-driver for the tda9840 by SGS Thomson
3
4 Copyright (C) 1998-2003 Michael Hunold <michael@mihu.de>
5
6 The tda9840 is a stereo/dual sound processor with digital
7 identification. It can be found at address 0x84 on the i2c-bus.
8
9 For detailed informations download the specifications directly
10 from SGS Thomson at http://www.st.com
11
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
16
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 */
26
27#include <linux/module.h>
28#include <linux/ioctl.h>
29#include <linux/i2c.h>
30
31#include "tda9840.h"
32
33static int debug = 0; /* insmod parameter */
34module_param(debug, int, 0644);
35MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off).");
36#define dprintk(args...) \
37 do { if (debug) { printk("%s: %s()[%d]: ",__stringify(KBUILD_MODNAME), __FUNCTION__, __LINE__); printk(args); } } while (0)
38
39#define SWITCH 0x00
40#define LEVEL_ADJUST 0x02
41#define STEREO_ADJUST 0x03
42#define TEST 0x04
43
44/* addresses to scan, found only at 0x42 (7-Bit) */
45static unsigned short normal_i2c[] = { I2C_TDA9840, I2C_CLIENT_END };
46static unsigned short normal_i2c_range[] = { I2C_CLIENT_END };
47
48/* magic definition of all other variables and things */
49I2C_CLIENT_INSMOD;
50
51static struct i2c_driver driver;
52static struct i2c_client client_template;
53
54static int command(struct i2c_client *client, unsigned int cmd, void *arg)
55{
56 int result;
57 int byte = *(int *)arg;
58
59 switch (cmd) {
60 case TDA9840_SWITCH:
61
62 dprintk("TDA9840_SWITCH: 0x%02x\n", byte);
63
64 if (byte != TDA9840_SET_MONO
65 && byte != TDA9840_SET_MUTE
66 && byte != TDA9840_SET_STEREO
67 && byte != TDA9840_SET_LANG1
68 && byte != TDA9840_SET_LANG2
69 && byte != TDA9840_SET_BOTH
70 && byte != TDA9840_SET_BOTH_R
71 && byte != TDA9840_SET_EXTERNAL) {
72 return -EINVAL;
73 }
74
75 result = i2c_smbus_write_byte_data(client, SWITCH, byte);
76 if (result)
77 dprintk("i2c_smbus_write_byte() failed, ret:%d\n", result);
78 break;
79
80 case TDA9840_LEVEL_ADJUST:
81
82 dprintk("TDA9840_LEVEL_ADJUST: %d\n", byte);
83
84 /* check for correct range */
85 if (byte > 25 || byte < -20)
86 return -EINVAL;
87
88 /* calculate actual value to set, see specs, page 18 */
89 byte /= 5;
90 if (0 < byte)
91 byte += 0x8;
92 else
93 byte = -byte;
94
95 result = i2c_smbus_write_byte_data(client, LEVEL_ADJUST, byte);
96 if (result)
97 dprintk("i2c_smbus_write_byte() failed, ret:%d\n", result);
98 break;
99
100 case TDA9840_STEREO_ADJUST:
101
102 dprintk("TDA9840_STEREO_ADJUST: %d\n", byte);
103
104 /* check for correct range */
105 if (byte > 25 || byte < -24)
106 return -EINVAL;
107
108 /* calculate actual value to set */
109 byte /= 5;
110 if (0 < byte)
111 byte += 0x20;
112 else
113 byte = -byte;
114
115 result = i2c_smbus_write_byte_data(client, STEREO_ADJUST, byte);
116 if (result)
117 dprintk("i2c_smbus_write_byte() failed, ret:%d\n", result);
118 break;
119
120 case TDA9840_DETECT: {
121 int *ret = (int *)arg;
122
123 byte = i2c_smbus_read_byte_data(client, STEREO_ADJUST);
124 if (byte == -1) {
125 dprintk("i2c_smbus_read_byte_data() failed\n");
126 return -EIO;
127 }
128
129 if (0 != (byte & 0x80)) {
130 dprintk("TDA9840_DETECT: register contents invalid\n");
131 return -EINVAL;
132 }
133
134 dprintk("TDA9840_DETECT: byte: 0x%02x\n", byte);
135 *ret = ((byte & 0x60) >> 5);
136 result = 0;
137 break;
138 }
139 case TDA9840_TEST:
140 dprintk("TDA9840_TEST: 0x%02x\n", byte);
141
142 /* mask out irrelevant bits */
143 byte &= 0x3;
144
145 result = i2c_smbus_write_byte_data(client, TEST, byte);
146 if (result)
147 dprintk("i2c_smbus_write_byte() failed, ret:%d\n", result);
148 break;
149 default:
150 return -ENOIOCTLCMD;
151 }
152
153 if (result)
154 return -EIO;
155
156 return 0;
157}
158
159static int detect(struct i2c_adapter *adapter, int address, int kind)
160{
161 struct i2c_client *client;
162 int result = 0;
163
164 int byte = 0x0;
165
166 /* let's see whether this adapter can support what we need */
167 if (0 == i2c_check_functionality(adapter,
168 I2C_FUNC_SMBUS_READ_BYTE_DATA |
169 I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) {
170 return 0;
171 }
172
173 /* allocate memory for client structure */
174 client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
175 if (0 == client) {
176 printk("not enough kernel memory\n");
177 return -ENOMEM;
178 }
179
180 /* fill client structure */
181 memcpy(client, &client_template, sizeof(struct i2c_client));
182 client->addr = address;
183 client->adapter = adapter;
184
185 /* tell the i2c layer a new client has arrived */
186 if (0 != (result = i2c_attach_client(client))) {
187 kfree(client);
188 return result;
189 }
190
191 /* set initial values for level & stereo - adjustment, mode */
192 byte = 0;
193 result = command(client, TDA9840_LEVEL_ADJUST, &byte);
194 result += command(client, TDA9840_STEREO_ADJUST, &byte);
195 byte = TDA9840_SET_MONO;
196 result = command(client, TDA9840_SWITCH, &byte);
197 if (result) {
198 dprintk("could not initialize tda9840\n");
199 return -ENODEV;
200 }
201
202 printk("tda9840: detected @ 0x%02x on adapter %s\n", address, &client->adapter->name[0]);
203 return 0;
204}
205
206static int attach(struct i2c_adapter *adapter)
207{
208 /* let's see whether this is a know adapter we can attach to */
209 if (adapter->id != I2C_ALGO_SAA7146) {
210 dprintk("refusing to probe on unknown adapter [name='%s',id=0x%x]\n", adapter->name, adapter->id);
211 return -ENODEV;
212 }
213
214 return i2c_probe(adapter, &addr_data, &detect);
215}
216
217static int detach(struct i2c_client *client)
218{
219 int ret = i2c_detach_client(client);
220 kfree(client);
221 return ret;
222}
223
224static struct i2c_driver driver = {
225 .owner = THIS_MODULE,
226 .name = "tda9840",
227 .id = I2C_DRIVERID_TDA9840,
228 .flags = I2C_DF_NOTIFY,
229 .attach_adapter = attach,
230 .detach_client = detach,
231 .command = command,
232};
233
234static struct i2c_client client_template = {
235 I2C_DEVNAME("tda9840"),
236 .driver = &driver,
237};
238
239static int __init this_module_init(void)
240{
241 return i2c_add_driver(&driver);
242}
243
244static void __exit this_module_exit(void)
245{
246 i2c_del_driver(&driver);
247}
248
249module_init(this_module_init);
250module_exit(this_module_exit);
251
252MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
253MODULE_DESCRIPTION("tda9840 driver");
254MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/tda9840.h b/drivers/media/video/tda9840.h
new file mode 100644
index 00000000000..28021053bd0
--- /dev/null
+++ b/drivers/media/video/tda9840.h
@@ -0,0 +1,35 @@
1#ifndef __INCLUDED_TDA9840__
2#define __INCLUDED_TDA9840__
3
4#define I2C_TDA9840 0x42
5
6#define TDA9840_DETECT _IOR('v',1,int)
7/* return values for TDA9840_DETCT */
8#define TDA9840_MONO_DETECT 0x0
9#define TDA9840_DUAL_DETECT 0x1
10#define TDA9840_STEREO_DETECT 0x2
11#define TDA9840_INCORRECT_DETECT 0x3
12
13#define TDA9840_SWITCH _IOW('v',2,int)
14/* modes than can be set with TDA9840_SWITCH */
15#define TDA9840_SET_MUTE 0x00
16#define TDA9840_SET_MONO 0x10
17#define TDA9840_SET_STEREO 0x2a
18#define TDA9840_SET_LANG1 0x12
19#define TDA9840_SET_LANG2 0x1e
20#define TDA9840_SET_BOTH 0x1a
21#define TDA9840_SET_BOTH_R 0x16
22#define TDA9840_SET_EXTERNAL 0x7a
23
24/* values may range between +2.5 and -2.0;
25 the value has to be multiplied with 10 */
26#define TDA9840_LEVEL_ADJUST _IOW('v',3,int)
27
28/* values may range between +2.5 and -2.4;
29 the value has to be multiplied with 10 */
30#define TDA9840_STEREO_ADJUST _IOW('v',4,int)
31
32/* currently not implemented */
33#define TDA9840_TEST _IOW('v',5,int)
34
35#endif
diff --git a/drivers/media/video/tda9875.c b/drivers/media/video/tda9875.c
new file mode 100644
index 00000000000..4f1114c033a
--- /dev/null
+++ b/drivers/media/video/tda9875.c
@@ -0,0 +1,423 @@
1/*
2 * For the TDA9875 chip
3 * (The TDA9875 is used on the Diamond DTV2000 french version
4 * Other cards probably use these chips as well.)
5 * This driver will not complain if used with any
6 * other i2c device with the same address.
7 *
8 * Copyright (c) 2000 Guillaume Delvit based on Gerd Knorr source and
9 * Eric Sandeen
10 * This code is placed under the terms of the GNU General Public License
11 * Based on tda9855.c by Steve VanDeBogart (vandebo@uclink.berkeley.edu)
12 * Which was based on tda8425.c by Greg Alexander (c) 1998
13 *
14 * OPTIONS:
15 * debug - set to 1 if you'd like to see debug messages
16 *
17 * Revision: 0.1 - original version
18 */
19
20#include <linux/module.h>
21#include <linux/kernel.h>
22#include <linux/sched.h>
23#include <linux/string.h>
24#include <linux/timer.h>
25#include <linux/delay.h>
26#include <linux/errno.h>
27#include <linux/slab.h>
28#include <linux/videodev.h>
29#include <linux/i2c.h>
30#include <linux/i2c-algo-bit.h>
31#include <linux/init.h>
32
33#include "bttv.h"
34#include <media/audiochip.h>
35#include <media/id.h>
36
37static int debug; /* insmod parameter */
38module_param(debug, int, S_IRUGO | S_IWUSR);
39MODULE_LICENSE("GPL");
40
41
42/* Addresses to scan */
43static unsigned short normal_i2c[] = {
44 I2C_TDA9875 >> 1,
45 I2C_CLIENT_END
46};
47static unsigned short normal_i2c_range[] = {I2C_CLIENT_END};
48I2C_CLIENT_INSMOD;
49
50/* This is a superset of the TDA9875 */
51struct tda9875 {
52 int mode;
53 int rvol, lvol;
54 int bass, treble;
55 struct i2c_client c;
56};
57
58static struct i2c_driver driver;
59static struct i2c_client client_template;
60
61#define dprintk if (debug) printk
62
63/* The TDA9875 is made by Philips Semiconductor
64 * http://www.semiconductors.philips.com
65 * TDA9875: I2C-bus controlled DSP audio processor, FM demodulator
66 *
67 */
68
69 /* subaddresses for TDA9875 */
70#define TDA9875_MUT 0x12 /*General mute (value --> 0b11001100*/
71#define TDA9875_CFG 0x01 /* Config register (value --> 0b00000000 */
72#define TDA9875_DACOS 0x13 /*DAC i/o select (ADC) 0b0000100*/
73#define TDA9875_LOSR 0x16 /*Line output select regirter 0b0100 0001*/
74
75#define TDA9875_CH1V 0x0c /*Channel 1 volume (mute)*/
76#define TDA9875_CH2V 0x0d /*Channel 2 volume (mute)*/
77#define TDA9875_SC1 0x14 /*SCART 1 in (mono)*/
78#define TDA9875_SC2 0x15 /*SCART 2 in (mono)*/
79
80#define TDA9875_ADCIS 0x17 /*ADC input select (mono) 0b0110 000*/
81#define TDA9875_AER 0x19 /*Audio effect (AVL+Pseudo) 0b0000 0110*/
82#define TDA9875_MCS 0x18 /*Main channel select (DAC) 0b0000100*/
83#define TDA9875_MVL 0x1a /* Main volume gauche */
84#define TDA9875_MVR 0x1b /* Main volume droite */
85#define TDA9875_MBA 0x1d /* Main Basse */
86#define TDA9875_MTR 0x1e /* Main treble */
87#define TDA9875_ACS 0x1f /* Auxilary channel select (FM) 0b0000000*/
88#define TDA9875_AVL 0x20 /* Auxilary volume gauche */
89#define TDA9875_AVR 0x21 /* Auxilary volume droite */
90#define TDA9875_ABA 0x22 /* Auxilary Basse */
91#define TDA9875_ATR 0x23 /* Auxilary treble */
92
93#define TDA9875_MSR 0x02 /* Monitor select register */
94#define TDA9875_C1MSB 0x03 /* Carrier 1 (FM) frequency register MSB */
95#define TDA9875_C1MIB 0x04 /* Carrier 1 (FM) frequency register (16-8]b */
96#define TDA9875_C1LSB 0x05 /* Carrier 1 (FM) frequency register LSB */
97#define TDA9875_C2MSB 0x06 /* Carrier 2 (nicam) frequency register MSB */
98#define TDA9875_C2MIB 0x07 /* Carrier 2 (nicam) frequency register (16-8]b */
99#define TDA9875_C2LSB 0x08 /* Carrier 2 (nicam) frequency register LSB */
100#define TDA9875_DCR 0x09 /* Demodulateur configuration regirter*/
101#define TDA9875_DEEM 0x0a /* FM de-emphasis regirter*/
102#define TDA9875_FMAT 0x0b /* FM Matrix regirter*/
103
104/* values */
105#define TDA9875_MUTE_ON 0xff /* general mute */
106#define TDA9875_MUTE_OFF 0xcc /* general no mute */
107
108
109
110/* Begin code */
111
112static int tda9875_write(struct i2c_client *client, int subaddr, unsigned char val)
113{
114 unsigned char buffer[2];
115 dprintk("In tda9875_write\n");
116 dprintk("Writing %d 0x%x\n", subaddr, val);
117 buffer[0] = subaddr;
118 buffer[1] = val;
119 if (2 != i2c_master_send(client,buffer,2)) {
120 printk(KERN_WARNING "tda9875: I/O error, trying (write %d 0x%x)\n",
121 subaddr, val);
122 return -1;
123 }
124 return 0;
125}
126
127#if 0
128static int tda9875_read(struct i2c_client *client)
129{
130 unsigned char buffer;
131 dprintk("In tda9875_read\n");
132 if (1 != i2c_master_recv(client,&buffer,1)) {
133 printk(KERN_WARNING "tda9875: I/O error, trying (read)\n");
134 return -1;
135 }
136 dprintk("Read 0x%02x\n", buffer);
137 return buffer;
138}
139#endif
140
141static int i2c_read_register(struct i2c_adapter *adap, int addr, int reg)
142{
143 unsigned char write[1];
144 unsigned char read[1];
145 struct i2c_msg msgs[2] = {
146 { addr, 0, 1, write },
147 { addr, I2C_M_RD, 1, read }
148 };
149 write[0] = reg;
150
151 if (2 != i2c_transfer(adap,msgs,2)) {
152 printk(KERN_WARNING "tda9875: I/O error (read2)\n");
153 return -1;
154 }
155 dprintk("tda9875: chip_read2: reg%d=0x%x\n",reg,read[0]);
156 return read[0];
157}
158
159static void tda9875_set(struct i2c_client *client)
160{
161 struct tda9875 *tda = i2c_get_clientdata(client);
162 unsigned char a;
163
164 dprintk(KERN_DEBUG "tda9875_set(%04x,%04x,%04x,%04x)\n",
165 tda->lvol,tda->rvol,tda->bass,tda->treble);
166
167
168 a = tda->lvol & 0xff;
169 tda9875_write(client, TDA9875_MVL, a);
170 a =tda->rvol & 0xff;
171 tda9875_write(client, TDA9875_MVR, a);
172 a =tda->bass & 0xff;
173 tda9875_write(client, TDA9875_MBA, a);
174 a =tda->treble & 0xff;
175 tda9875_write(client, TDA9875_MTR, a);
176}
177
178static void do_tda9875_init(struct i2c_client *client)
179{
180 struct tda9875 *t = i2c_get_clientdata(client);
181 dprintk("In tda9875_init\n");
182 tda9875_write(client, TDA9875_CFG, 0xd0 ); /*reg de config 0 (reset)*/
183 tda9875_write(client, TDA9875_MSR, 0x03 ); /* Monitor 0b00000XXX*/
184 tda9875_write(client, TDA9875_C1MSB, 0x00 ); /*Car1(FM) MSB XMHz*/
185 tda9875_write(client, TDA9875_C1MIB, 0x00 ); /*Car1(FM) MIB XMHz*/
186 tda9875_write(client, TDA9875_C1LSB, 0x00 ); /*Car1(FM) LSB XMHz*/
187 tda9875_write(client, TDA9875_C2MSB, 0x00 ); /*Car2(NICAM) MSB XMHz*/
188 tda9875_write(client, TDA9875_C2MIB, 0x00 ); /*Car2(NICAM) MIB XMHz*/
189 tda9875_write(client, TDA9875_C2LSB, 0x00 ); /*Car2(NICAM) LSB XMHz*/
190 tda9875_write(client, TDA9875_DCR, 0x00 ); /*Demod config 0x00*/
191 tda9875_write(client, TDA9875_DEEM, 0x44 ); /*DE-Emph 0b0100 0100*/
192 tda9875_write(client, TDA9875_FMAT, 0x00 ); /*FM Matrix reg 0x00*/
193 tda9875_write(client, TDA9875_SC1, 0x00 ); /* SCART 1 (SC1)*/
194 tda9875_write(client, TDA9875_SC2, 0x01 ); /* SCART 2 (sc2)*/
195
196 tda9875_write(client, TDA9875_CH1V, 0x10 ); /* Channel volume 1 mute*/
197 tda9875_write(client, TDA9875_CH2V, 0x10 ); /* Channel volume 2 mute */
198 tda9875_write(client, TDA9875_DACOS, 0x02 ); /* sig DAC i/o(in:nicam)*/
199 tda9875_write(client, TDA9875_ADCIS, 0x6f ); /* sig ADC input(in:mono)*/
200 tda9875_write(client, TDA9875_LOSR, 0x00 ); /* line out (in:mono)*/
201 tda9875_write(client, TDA9875_AER, 0x00 ); /*06 Effect (AVL+PSEUDO) */
202 tda9875_write(client, TDA9875_MCS, 0x44 ); /* Main ch select (DAC) */
203 tda9875_write(client, TDA9875_MVL, 0x03 ); /* Vol Main left 10dB */
204 tda9875_write(client, TDA9875_MVR, 0x03 ); /* Vol Main right 10dB*/
205 tda9875_write(client, TDA9875_MBA, 0x00 ); /* Main Bass Main 0dB*/
206 tda9875_write(client, TDA9875_MTR, 0x00 ); /* Main Treble Main 0dB*/
207 tda9875_write(client, TDA9875_ACS, 0x44 ); /* Aux chan select (dac)*/
208 tda9875_write(client, TDA9875_AVL, 0x00 ); /* Vol Aux left 0dB*/
209 tda9875_write(client, TDA9875_AVR, 0x00 ); /* Vol Aux right 0dB*/
210 tda9875_write(client, TDA9875_ABA, 0x00 ); /* Aux Bass Main 0dB*/
211 tda9875_write(client, TDA9875_ATR, 0x00 ); /* Aux Aigus Main 0dB*/
212
213 tda9875_write(client, TDA9875_MUT, 0xcc ); /* General mute */
214
215 t->mode=AUDIO_UNMUTE;
216 t->lvol=t->rvol =0; /* 0dB */
217 t->bass=0; /* 0dB */
218 t->treble=0; /* 0dB */
219 tda9875_set(client);
220
221}
222
223
224/* *********************** *
225 * i2c interface functions *
226 * *********************** */
227
228static int tda9875_checkit(struct i2c_adapter *adap, int addr)
229{
230 int dic,rev;
231
232 dic=i2c_read_register(adap,addr,254);
233 rev=i2c_read_register(adap,addr,255);
234
235 if(dic==0 || dic==2) { // tda9875 and tda9875A
236 printk("tda9875: TDA9875%s Rev.%d detected at 0x%x\n",
237 dic==0?"":"A", rev,addr<<1);
238 return 1;
239 }
240 printk("tda9875: no such chip at 0x%x (dic=0x%x rev=0x%x)\n",addr<<1,dic,rev);
241 return(0);
242}
243
244static int tda9875_attach(struct i2c_adapter *adap, int addr, int kind)
245{
246 struct tda9875 *t;
247 struct i2c_client *client;
248 dprintk("In tda9875_attach\n");
249
250 t = kmalloc(sizeof *t,GFP_KERNEL);
251 if (!t)
252 return -ENOMEM;
253 memset(t,0,sizeof *t);
254
255 client = &t->c;
256 memcpy(client,&client_template,sizeof(struct i2c_client));
257 client->adapter = adap;
258 client->addr = addr;
259 i2c_set_clientdata(client, t);
260
261 if(!tda9875_checkit(adap,addr)) {
262 kfree(t);
263 return 1;
264 }
265
266 do_tda9875_init(client);
267 printk(KERN_INFO "tda9875: init\n");
268
269 i2c_attach_client(client);
270 return 0;
271}
272
273static int tda9875_probe(struct i2c_adapter *adap)
274{
275#ifdef I2C_CLASS_TV_ANALOG
276 if (adap->class & I2C_CLASS_TV_ANALOG)
277 return i2c_probe(adap, &addr_data, tda9875_attach);
278#else
279 if (adap->id == (I2C_ALGO_BIT | I2C_HW_B_BT848))
280 return i2c_probe(adap, &addr_data, tda9875_attach);
281#endif
282 return 0;
283}
284
285static int tda9875_detach(struct i2c_client *client)
286{
287 struct tda9875 *t = i2c_get_clientdata(client);
288
289 do_tda9875_init(client);
290 i2c_detach_client(client);
291
292 kfree(t);
293 return 0;
294}
295
296static int tda9875_command(struct i2c_client *client,
297 unsigned int cmd, void *arg)
298{
299 struct tda9875 *t = i2c_get_clientdata(client);
300
301 dprintk("In tda9875_command...\n");
302
303 switch (cmd) {
304 /* --- v4l ioctls --- */
305 /* take care: bttv does userspace copying, we'll get a
306 kernel pointer here... */
307 case VIDIOCGAUDIO:
308 {
309 struct video_audio *va = arg;
310 int left,right;
311
312 dprintk("VIDIOCGAUDIO\n");
313
314 va->flags |= VIDEO_AUDIO_VOLUME |
315 VIDEO_AUDIO_BASS |
316 VIDEO_AUDIO_TREBLE;
317
318 /* min is -84 max is 24 */
319 left = (t->lvol+84)*606;
320 right = (t->rvol+84)*606;
321 va->volume=max(left,right);
322 va->balance=(32768*min(left,right))/
323 (va->volume ? va->volume : 1);
324 va->balance=(left<right)?
325 (65535-va->balance) : va->balance;
326 va->bass = (t->bass+12)*2427; /* min -12 max +15 */
327 va->treble = (t->treble+12)*2730;/* min -12 max +12 */
328 va->mode |= VIDEO_SOUND_MONO;
329
330 break; /* VIDIOCGAUDIO case */
331 }
332
333 case VIDIOCSAUDIO:
334 {
335 struct video_audio *va = arg;
336 int left,right;
337
338 dprintk("VIDEOCSAUDIO...\n");
339 left = (min(65536 - va->balance,32768) *
340 va->volume) / 32768;
341 right = (min(va->balance,(__u16)32768) *
342 va->volume) / 32768;
343 t->lvol = ((left/606)-84) & 0xff;
344 if (t->lvol > 24)
345 t->lvol = 24;
346 if (t->lvol < -84)
347 t->lvol = -84 & 0xff;
348
349 t->rvol = ((right/606)-84) & 0xff;
350 if (t->rvol > 24)
351 t->rvol = 24;
352 if (t->rvol < -84)
353 t->rvol = -84 & 0xff;
354
355 t->bass = ((va->bass/2400)-12) & 0xff;
356 if (t->bass > 15)
357 t->bass = 15;
358 if (t->bass < -12)
359 t->bass = -12 & 0xff;
360
361 t->treble = ((va->treble/2700)-12) & 0xff;
362 if (t->treble > 12)
363 t->treble = 12;
364 if (t->treble < -12)
365 t->treble = -12 & 0xff;
366
367
368
369//printk("tda9875 bal:%04x vol:%04x bass:%04x treble:%04x\n",va->balance,va->volume,va->bass,va->treble);
370
371
372 tda9875_set(client);
373
374 break;
375
376 } /* end of VIDEOCSAUDIO case */
377
378 default: /* Not VIDEOCGAUDIO or VIDEOCSAUDIO */
379
380 /* nothing */
381 dprintk("Default\n");
382
383 } /* end of (cmd) switch */
384
385 return 0;
386}
387
388
389static struct i2c_driver driver = {
390 .owner = THIS_MODULE,
391 .name = "i2c tda9875 driver",
392 .id = I2C_DRIVERID_TDA9875,
393 .flags = I2C_DF_NOTIFY,
394 .attach_adapter = tda9875_probe,
395 .detach_client = tda9875_detach,
396 .command = tda9875_command,
397};
398
399static struct i2c_client client_template =
400{
401 I2C_DEVNAME("tda9875"),
402 .driver = &driver,
403};
404
405static int __init tda9875_init(void)
406{
407 return i2c_add_driver(&driver);
408}
409
410static void __exit tda9875_fini(void)
411{
412 i2c_del_driver(&driver);
413}
414
415module_init(tda9875_init);
416module_exit(tda9875_fini);
417
418/*
419 * Local variables:
420 * c-basic-offset: 8
421 * End:
422 */
423
diff --git a/drivers/media/video/tda9887.c b/drivers/media/video/tda9887.c
new file mode 100644
index 00000000000..7fb063a2796
--- /dev/null
+++ b/drivers/media/video/tda9887.c
@@ -0,0 +1,801 @@
1#include <linux/module.h>
2#include <linux/moduleparam.h>
3#include <linux/kernel.h>
4#include <linux/i2c.h>
5#include <linux/types.h>
6#include <linux/videodev.h>
7#include <linux/init.h>
8#include <linux/errno.h>
9#include <linux/slab.h>
10#include <linux/delay.h>
11
12#include <media/audiochip.h>
13#include <media/tuner.h>
14#include <media/id.h>
15
16/* Chips:
17 TDA9885 (PAL, NTSC)
18 TDA9886 (PAL, SECAM, NTSC)
19 TDA9887 (PAL, SECAM, NTSC, FM Radio)
20
21 found on:
22 - Pinnacle PCTV (Jul.2002 Version with MT2032, bttv)
23 TDA9887 (world), TDA9885 (USA)
24 Note: OP2 of tda988x must be set to 1, else MT2032 is disabled!
25 - KNC One TV-Station RDS (saa7134)
26*/
27
28
29/* Addresses to scan */
30static unsigned short normal_i2c[] = {
31 0x84 >>1,
32 0x86 >>1,
33 0x96 >>1,
34 I2C_CLIENT_END,
35};
36static unsigned short normal_i2c_range[] = {I2C_CLIENT_END,I2C_CLIENT_END};
37I2C_CLIENT_INSMOD;
38
39/* insmod options */
40static unsigned int debug = 0;
41module_param(debug, int, 0644);
42MODULE_LICENSE("GPL");
43
44/* ---------------------------------------------------------------------- */
45
46#define UNSET (-1U)
47#define PREFIX "tda9885/6/7: "
48#define dprintk if (debug) printk
49
50struct tda9887 {
51 struct i2c_client client;
52 v4l2_std_id std;
53 unsigned int radio;
54 unsigned int config;
55 unsigned int pinnacle_id;
56 unsigned int using_v4l2;
57};
58
59struct tvnorm {
60 v4l2_std_id std;
61 char *name;
62 unsigned char b;
63 unsigned char c;
64 unsigned char e;
65};
66
67static struct i2c_driver driver;
68static struct i2c_client client_template;
69
70/* ---------------------------------------------------------------------- */
71
72//
73// TDA defines
74//
75
76//// first reg (b)
77#define cVideoTrapBypassOFF 0x00 // bit b0
78#define cVideoTrapBypassON 0x01 // bit b0
79
80#define cAutoMuteFmInactive 0x00 // bit b1
81#define cAutoMuteFmActive 0x02 // bit b1
82
83#define cIntercarrier 0x00 // bit b2
84#define cQSS 0x04 // bit b2
85
86#define cPositiveAmTV 0x00 // bit b3:4
87#define cFmRadio 0x08 // bit b3:4
88#define cNegativeFmTV 0x10 // bit b3:4
89
90
91#define cForcedMuteAudioON 0x20 // bit b5
92#define cForcedMuteAudioOFF 0x00 // bit b5
93
94#define cOutputPort1Active 0x00 // bit b6
95#define cOutputPort1Inactive 0x40 // bit b6
96
97#define cOutputPort2Active 0x00 // bit b7
98#define cOutputPort2Inactive 0x80 // bit b7
99
100
101//// second reg (c)
102#define cDeemphasisOFF 0x00 // bit c5
103#define cDeemphasisON 0x20 // bit c5
104
105#define cDeemphasis75 0x00 // bit c6
106#define cDeemphasis50 0x40 // bit c6
107
108#define cAudioGain0 0x00 // bit c7
109#define cAudioGain6 0x80 // bit c7
110
111
112//// third reg (e)
113#define cAudioIF_4_5 0x00 // bit e0:1
114#define cAudioIF_5_5 0x01 // bit e0:1
115#define cAudioIF_6_0 0x02 // bit e0:1
116#define cAudioIF_6_5 0x03 // bit e0:1
117
118
119#define cVideoIF_58_75 0x00 // bit e2:4
120#define cVideoIF_45_75 0x04 // bit e2:4
121#define cVideoIF_38_90 0x08 // bit e2:4
122#define cVideoIF_38_00 0x0C // bit e2:4
123#define cVideoIF_33_90 0x10 // bit e2:4
124#define cVideoIF_33_40 0x14 // bit e2:4
125#define cRadioIF_45_75 0x18 // bit e2:4
126#define cRadioIF_38_90 0x1C // bit e2:4
127
128
129#define cTunerGainNormal 0x00 // bit e5
130#define cTunerGainLow 0x20 // bit e5
131
132#define cGating_18 0x00 // bit e6
133#define cGating_36 0x40 // bit e6
134
135#define cAgcOutON 0x80 // bit e7
136#define cAgcOutOFF 0x00 // bit e7
137
138/* ---------------------------------------------------------------------- */
139
140static struct tvnorm tvnorms[] = {
141 {
142 .std = V4L2_STD_PAL_BG,
143 .name = "PAL-BG",
144 .b = ( cNegativeFmTV |
145 cQSS ),
146 .c = ( cDeemphasisON |
147 cDeemphasis50 ),
148 .e = ( cAudioIF_5_5 |
149 cVideoIF_38_90 ),
150 },{
151 .std = V4L2_STD_PAL_I,
152 .name = "PAL-I",
153 .b = ( cNegativeFmTV |
154 cQSS ),
155 .c = ( cDeemphasisON |
156 cDeemphasis50 ),
157 .e = ( cAudioIF_6_0 |
158 cVideoIF_38_90 ),
159 },{
160 .std = V4L2_STD_PAL_DK,
161 .name = "PAL-DK",
162 .b = ( cNegativeFmTV |
163 cQSS ),
164 .c = ( cDeemphasisON |
165 cDeemphasis50 ),
166 .e = ( cAudioIF_6_5 |
167 cVideoIF_38_00 ),
168 },{
169 .std = V4L2_STD_PAL_M | V4L2_STD_PAL_N,
170 .name = "PAL-M/N",
171 .b = ( cNegativeFmTV |
172 cQSS ),
173 .c = ( cDeemphasisON |
174 cDeemphasis75 ),
175 .e = ( cAudioIF_4_5 |
176 cVideoIF_45_75 ),
177 },{
178 .std = V4L2_STD_SECAM_L,
179 .name = "SECAM-L",
180 .b = ( cPositiveAmTV |
181 cQSS ),
182 .e = ( cAudioIF_6_5 |
183 cVideoIF_38_90 ),
184 },{
185 .std = V4L2_STD_SECAM_DK,
186 .name = "SECAM-DK",
187 .b = ( cNegativeFmTV |
188 cQSS ),
189 .c = ( cDeemphasisON |
190 cDeemphasis50 ),
191 .e = ( cAudioIF_6_5 |
192 cVideoIF_38_00 ),
193 },{
194 .std = V4L2_STD_NTSC_M,
195 .name = "NTSC-M",
196 .b = ( cNegativeFmTV |
197 cQSS ),
198 .c = ( cDeemphasisON |
199 cDeemphasis50 ),
200 .e = ( cGating_36 |
201 cAudioIF_4_5 |
202 cVideoIF_45_75 ),
203 },{
204 .std = V4L2_STD_NTSC_M_JP,
205 .name = "NTSC-JP",
206 .b = ( cNegativeFmTV |
207 cQSS ),
208 .c = ( cDeemphasisON |
209 cDeemphasis50 ),
210 .e = ( cGating_36 |
211 cAudioIF_4_5 |
212 cVideoIF_58_75 ),
213 }
214};
215
216static struct tvnorm radio = {
217 .name = "radio",
218 .b = ( cFmRadio |
219 cQSS ),
220 .c = ( cDeemphasisON |
221 cDeemphasis50 ),
222 .e = ( cAudioIF_5_5 |
223 cRadioIF_38_90 ),
224};
225
226/* ---------------------------------------------------------------------- */
227
228static void dump_read_message(unsigned char *buf)
229{
230 static char *afc[16] = {
231 "- 12.5 kHz",
232 "- 37.5 kHz",
233 "- 62.5 kHz",
234 "- 87.5 kHz",
235 "-112.5 kHz",
236 "-137.5 kHz",
237 "-162.5 kHz",
238 "-187.5 kHz [min]",
239 "+187.5 kHz [max]",
240 "+162.5 kHz",
241 "+137.5 kHz",
242 "+112.5 kHz",
243 "+ 87.5 kHz",
244 "+ 62.5 kHz",
245 "+ 37.5 kHz",
246 "+ 12.5 kHz",
247 };
248 printk(PREFIX "read: 0x%2x\n", buf[0]);
249 printk(" after power on : %s\n", (buf[0] & 0x01) ? "yes" : "no");
250 printk(" afc : %s\n", afc[(buf[0] >> 1) & 0x0f]);
251 printk(" fmif level : %s\n", (buf[0] & 0x20) ? "high" : "low");
252 printk(" afc window : %s\n", (buf[0] & 0x40) ? "in" : "out");
253 printk(" vfi level : %s\n", (buf[0] & 0x80) ? "high" : "low");
254}
255
256static void dump_write_message(unsigned char *buf)
257{
258 static char *sound[4] = {
259 "AM/TV",
260 "FM/radio",
261 "FM/TV",
262 "FM/radio"
263 };
264 static char *adjust[32] = {
265 "-16", "-15", "-14", "-13", "-12", "-11", "-10", "-9",
266 "-8", "-7", "-6", "-5", "-4", "-3", "-2", "-1",
267 "0", "+1", "+2", "+3", "+4", "+5", "+6", "+7",
268 "+8", "+9", "+10", "+11", "+12", "+13", "+14", "+15"
269 };
270 static char *deemph[4] = {
271 "no", "no", "75", "50"
272 };
273 static char *carrier[4] = {
274 "4.5 MHz",
275 "5.5 MHz",
276 "6.0 MHz",
277 "6.5 MHz / AM"
278 };
279 static char *vif[8] = {
280 "58.75 MHz",
281 "45.75 MHz",
282 "38.9 MHz",
283 "38.0 MHz",
284 "33.9 MHz",
285 "33.4 MHz",
286 "45.75 MHz + pin13",
287 "38.9 MHz + pin13",
288 };
289 static char *rif[4] = {
290 "44 MHz",
291 "52 MHz",
292 "52 MHz",
293 "44 MHz",
294 };
295
296 printk(PREFIX "write: byte B 0x%02x\n",buf[1]);
297 printk(" B0 video mode : %s\n",
298 (buf[1] & 0x01) ? "video trap" : "sound trap");
299 printk(" B1 auto mute fm : %s\n",
300 (buf[1] & 0x02) ? "yes" : "no");
301 printk(" B2 carrier mode : %s\n",
302 (buf[1] & 0x04) ? "QSS" : "Intercarrier");
303 printk(" B3-4 tv sound/radio : %s\n",
304 sound[(buf[1] & 0x18) >> 3]);
305 printk(" B5 force mute audio: %s\n",
306 (buf[1] & 0x20) ? "yes" : "no");
307 printk(" B6 output port 1 : %s\n",
308 (buf[1] & 0x40) ? "high (inactive)" : "low (active)");
309 printk(" B7 output port 2 : %s\n",
310 (buf[1] & 0x80) ? "high (inactive)" : "low (active)");
311
312 printk(PREFIX "write: byte C 0x%02x\n",buf[2]);
313 printk(" C0-4 top adjustment : %s dB\n", adjust[buf[2] & 0x1f]);
314 printk(" C5-6 de-emphasis : %s\n", deemph[(buf[2] & 0x60) >> 5]);
315 printk(" C7 audio gain : %s\n",
316 (buf[2] & 0x80) ? "-6" : "0");
317
318 printk(PREFIX "write: byte E 0x%02x\n",buf[3]);
319 printk(" E0-1 sound carrier : %s\n",
320 carrier[(buf[3] & 0x03)]);
321 printk(" E6 l pll ganting : %s\n",
322 (buf[3] & 0x40) ? "36" : "13");
323
324 if (buf[1] & 0x08) {
325 /* radio */
326 printk(" E2-4 video if : %s\n",
327 rif[(buf[3] & 0x0c) >> 2]);
328 printk(" E7 vif agc output : %s\n",
329 (buf[3] & 0x80)
330 ? ((buf[3] & 0x10) ? "fm-agc radio" : "sif-agc radio")
331 : "fm radio carrier afc");
332 } else {
333 /* video */
334 printk(" E2-4 video if : %s\n",
335 vif[(buf[3] & 0x1c) >> 2]);
336 printk(" E5 tuner gain : %s\n",
337 (buf[3] & 0x80)
338 ? ((buf[3] & 0x20) ? "external" : "normal")
339 : ((buf[3] & 0x20) ? "minimum" : "normal"));
340 printk(" E7 vif agc output : %s\n",
341 (buf[3] & 0x80)
342 ? ((buf[3] & 0x20)
343 ? "pin3 port, pin22 vif agc out"
344 : "pin22 port, pin3 vif acg ext in")
345 : "pin3+pin22 port");
346 }
347 printk("--\n");
348}
349
350/* ---------------------------------------------------------------------- */
351
352static int tda9887_set_tvnorm(struct tda9887 *t, char *buf)
353{
354 struct tvnorm *norm = NULL;
355 int i;
356
357 if (t->radio) {
358 norm = &radio;
359 } else {
360 for (i = 0; i < ARRAY_SIZE(tvnorms); i++) {
361 if (tvnorms[i].std & t->std) {
362 norm = tvnorms+i;
363 break;
364 }
365 }
366 }
367 if (NULL == norm) {
368 dprintk(PREFIX "Oops: no tvnorm entry found\n");
369 return -1;
370 }
371
372 dprintk(PREFIX "configure for: %s\n",norm->name);
373 buf[1] = norm->b;
374 buf[2] = norm->c;
375 buf[3] = norm->e;
376 return 0;
377}
378
379static unsigned int port1 = UNSET;
380static unsigned int port2 = UNSET;
381static unsigned int qss = UNSET;
382static unsigned int adjust = 0x10;
383module_param(port1, int, 0644);
384module_param(port2, int, 0644);
385module_param(qss, int, 0644);
386module_param(adjust, int, 0644);
387
388static int tda9887_set_insmod(struct tda9887 *t, char *buf)
389{
390 if (UNSET != port1) {
391 if (port1)
392 buf[1] |= cOutputPort1Inactive;
393 else
394 buf[1] &= ~cOutputPort1Inactive;
395 }
396 if (UNSET != port2) {
397 if (port2)
398 buf[1] |= cOutputPort2Inactive;
399 else
400 buf[1] &= ~cOutputPort2Inactive;
401 }
402
403 if (UNSET != qss) {
404 if (qss)
405 buf[1] |= cQSS;
406 else
407 buf[1] &= ~cQSS;
408 }
409
410 if (adjust >= 0x00 && adjust < 0x20)
411 buf[2] |= adjust;
412 return 0;
413}
414
415static int tda9887_set_config(struct tda9887 *t, char *buf)
416{
417 if (t->config & TDA9887_PORT1_ACTIVE)
418 buf[1] &= ~cOutputPort1Inactive;
419 if (t->config & TDA9887_PORT1_INACTIVE)
420 buf[1] |= cOutputPort1Inactive;
421 if (t->config & TDA9887_PORT2_ACTIVE)
422 buf[1] &= ~cOutputPort2Inactive;
423 if (t->config & TDA9887_PORT2_INACTIVE)
424 buf[1] |= cOutputPort2Inactive;
425
426 if (t->config & TDA9887_QSS)
427 buf[1] |= cQSS;
428 if (t->config & TDA9887_INTERCARRIER)
429 buf[1] &= ~cQSS;
430
431 if (t->config & TDA9887_AUTOMUTE)
432 buf[1] |= cAutoMuteFmActive;
433 if (t->config & TDA9887_DEEMPHASIS_MASK) {
434 buf[2] &= ~0x60;
435 switch (t->config & TDA9887_DEEMPHASIS_MASK) {
436 case TDA9887_DEEMPHASIS_NONE:
437 buf[2] |= cDeemphasisOFF;
438 break;
439 case TDA9887_DEEMPHASIS_50:
440 buf[2] |= cDeemphasisON | cDeemphasis50;
441 break;
442 case TDA9887_DEEMPHASIS_75:
443 buf[2] |= cDeemphasisON | cDeemphasis75;
444 break;
445 }
446 }
447 return 0;
448}
449
450/* ---------------------------------------------------------------------- */
451
452static int tda9887_set_pinnacle(struct tda9887 *t, char *buf)
453{
454 unsigned int bCarrierMode = UNSET;
455
456 if (t->std & V4L2_STD_625_50) {
457 if ((1 == t->pinnacle_id) || (7 == t->pinnacle_id)) {
458 bCarrierMode = cIntercarrier;
459 } else {
460 bCarrierMode = cQSS;
461 }
462 }
463 if (t->std & V4L2_STD_525_60) {
464 if ((5 == t->pinnacle_id) || (6 == t->pinnacle_id)) {
465 bCarrierMode = cIntercarrier;
466 } else {
467 bCarrierMode = cQSS;
468 }
469 }
470
471 if (bCarrierMode != UNSET) {
472 buf[1] &= ~0x04;
473 buf[1] |= bCarrierMode;
474 }
475 return 0;
476}
477
478/* ---------------------------------------------------------------------- */
479
480static char pal[] = "-";
481module_param_string(pal, pal, 0644, sizeof(pal));
482static char secam[] = "-";
483module_param_string(secam, secam, 0644, sizeof(secam));
484
485static int tda9887_fixup_std(struct tda9887 *t)
486{
487 /* get more precise norm info from insmod option */
488 if ((t->std & V4L2_STD_PAL) == V4L2_STD_PAL) {
489 switch (pal[0]) {
490 case 'b':
491 case 'B':
492 case 'g':
493 case 'G':
494 dprintk(PREFIX "insmod fixup: PAL => PAL-BG\n");
495 t->std = V4L2_STD_PAL_BG;
496 break;
497 case 'i':
498 case 'I':
499 dprintk(PREFIX "insmod fixup: PAL => PAL-I\n");
500 t->std = V4L2_STD_PAL_I;
501 break;
502 case 'd':
503 case 'D':
504 case 'k':
505 case 'K':
506 dprintk(PREFIX "insmod fixup: PAL => PAL-DK\n");
507 t->std = V4L2_STD_PAL_DK;
508 break;
509 }
510 }
511 if ((t->std & V4L2_STD_SECAM) == V4L2_STD_SECAM) {
512 switch (secam[0]) {
513 case 'd':
514 case 'D':
515 case 'k':
516 case 'K':
517 dprintk(PREFIX "insmod fixup: SECAM => SECAM-DK\n");
518 t->std = V4L2_STD_SECAM_DK;
519 break;
520 case 'l':
521 case 'L':
522 dprintk(PREFIX "insmod fixup: SECAM => SECAM-L\n");
523 t->std = V4L2_STD_SECAM_L;
524 break;
525 }
526 }
527 return 0;
528}
529
530static int tda9887_status(struct tda9887 *t)
531{
532 unsigned char buf[1];
533 int rc;
534
535 memset(buf,0,sizeof(buf));
536 if (1 != (rc = i2c_master_recv(&t->client,buf,1)))
537 printk(PREFIX "i2c i/o error: rc == %d (should be 1)\n",rc);
538 dump_read_message(buf);
539 return 0;
540}
541
542static int tda9887_configure(struct tda9887 *t)
543{
544 unsigned char buf[4];
545 int rc;
546
547 memset(buf,0,sizeof(buf));
548 tda9887_set_tvnorm(t,buf);
549 buf[1] |= cOutputPort1Inactive;
550 buf[1] |= cOutputPort2Inactive;
551 if (UNSET != t->pinnacle_id) {
552 tda9887_set_pinnacle(t,buf);
553 }
554 tda9887_set_config(t,buf);
555 tda9887_set_insmod(t,buf);
556
557#if 0
558 /* This as-is breaks some cards, must be fixed in a
559 * card-specific way, probably using TDA9887_SET_CONFIG to
560 * turn on/off port2 */
561 if (t->std & V4L2_STD_SECAM_L) {
562 /* secam fixup (FIXME: move this to tvnorms array?) */
563 buf[1] &= ~cOutputPort2Inactive;
564 }
565#endif
566
567 dprintk(PREFIX "writing: b=0x%02x c=0x%02x e=0x%02x\n",
568 buf[1],buf[2],buf[3]);
569 if (debug > 1)
570 dump_write_message(buf);
571
572 if (4 != (rc = i2c_master_send(&t->client,buf,4)))
573 printk(PREFIX "i2c i/o error: rc == %d (should be 4)\n",rc);
574
575 if (debug > 2) {
576 msleep_interruptible(1000);
577 tda9887_status(t);
578 }
579 return 0;
580}
581
582/* ---------------------------------------------------------------------- */
583
584static int tda9887_attach(struct i2c_adapter *adap, int addr, int kind)
585{
586 struct tda9887 *t;
587
588 client_template.adapter = adap;
589 client_template.addr = addr;
590
591 printk(PREFIX "chip found @ 0x%x\n", addr<<1);
592
593 if (NULL == (t = kmalloc(sizeof(*t), GFP_KERNEL)))
594 return -ENOMEM;
595 memset(t,0,sizeof(*t));
596 t->client = client_template;
597 t->std = 0;
598 t->pinnacle_id = UNSET;
599 i2c_set_clientdata(&t->client, t);
600 i2c_attach_client(&t->client);
601
602 return 0;
603}
604
605static int tda9887_probe(struct i2c_adapter *adap)
606{
607#ifdef I2C_CLASS_TV_ANALOG
608 if (adap->class & I2C_CLASS_TV_ANALOG)
609 return i2c_probe(adap, &addr_data, tda9887_attach);
610#else
611 switch (adap->id) {
612 case I2C_ALGO_BIT | I2C_HW_B_BT848:
613 case I2C_ALGO_BIT | I2C_HW_B_RIVA:
614 case I2C_ALGO_SAA7134:
615 return i2c_probe(adap, &addr_data, tda9887_attach);
616 break;
617 }
618#endif
619 return 0;
620}
621
622static int tda9887_detach(struct i2c_client *client)
623{
624 struct tda9887 *t = i2c_get_clientdata(client);
625
626 i2c_detach_client(client);
627 kfree(t);
628 return 0;
629}
630
631#define SWITCH_V4L2 if (!t->using_v4l2 && debug) \
632 printk(PREFIX "switching to v4l2\n"); \
633 t->using_v4l2 = 1;
634#define CHECK_V4L2 if (t->using_v4l2) { if (debug) \
635 printk(PREFIX "ignore v4l1 call\n"); \
636 return 0; }
637
638static int
639tda9887_command(struct i2c_client *client, unsigned int cmd, void *arg)
640{
641 struct tda9887 *t = i2c_get_clientdata(client);
642
643 switch (cmd) {
644
645 /* --- configuration --- */
646 case AUDC_SET_RADIO:
647 t->radio = 1;
648 tda9887_configure(t);
649 break;
650
651 case AUDC_CONFIG_PINNACLE:
652 {
653 int *i = arg;
654
655 t->pinnacle_id = *i;
656 tda9887_configure(t);
657 break;
658 }
659 case TDA9887_SET_CONFIG:
660 {
661 int *i = arg;
662
663 t->config = *i;
664 tda9887_configure(t);
665 break;
666 }
667 /* --- v4l ioctls --- */
668 /* take care: bttv does userspace copying, we'll get a
669 kernel pointer here... */
670 case VIDIOCSCHAN:
671 {
672 static const v4l2_std_id map[] = {
673 [ VIDEO_MODE_PAL ] = V4L2_STD_PAL,
674 [ VIDEO_MODE_NTSC ] = V4L2_STD_NTSC_M,
675 [ VIDEO_MODE_SECAM ] = V4L2_STD_SECAM,
676 [ 4 /* bttv */ ] = V4L2_STD_PAL_M,
677 [ 5 /* bttv */ ] = V4L2_STD_PAL_N,
678 [ 6 /* bttv */ ] = V4L2_STD_NTSC_M_JP,
679 };
680 struct video_channel *vc = arg;
681
682 CHECK_V4L2;
683 t->radio = 0;
684 if (vc->norm < ARRAY_SIZE(map))
685 t->std = map[vc->norm];
686 tda9887_fixup_std(t);
687 tda9887_configure(t);
688 break;
689 }
690 case VIDIOC_S_STD:
691 {
692 v4l2_std_id *id = arg;
693
694 SWITCH_V4L2;
695 t->radio = 0;
696 t->std = *id;
697 tda9887_fixup_std(t);
698 tda9887_configure(t);
699 break;
700 }
701 case VIDIOC_S_FREQUENCY:
702 {
703 struct v4l2_frequency *f = arg;
704
705 SWITCH_V4L2;
706 if (V4L2_TUNER_ANALOG_TV == f->type) {
707 if (t->radio == 0)
708 return 0;
709 t->radio = 0;
710 }
711 if (V4L2_TUNER_RADIO == f->type) {
712 if (t->radio == 1)
713 return 0;
714 t->radio = 1;
715 }
716 tda9887_configure(t);
717 break;
718 }
719 case VIDIOC_G_TUNER:
720 {
721 static int AFC_BITS_2_kHz[] = {
722 -12500, -37500, -62500, -97500,
723 -112500, -137500, -162500, -187500,
724 187500, 162500, 137500, 112500,
725 97500 , 62500, 37500 , 12500
726 };
727 struct v4l2_tuner* tuner = arg;
728
729 if (t->radio) {
730 __u8 reg = 0;
731 tuner->afc=0;
732 if (1 == i2c_master_recv(&t->client,&reg,1))
733 tuner->afc = AFC_BITS_2_kHz[(reg>>1)&0x0f];
734 }
735 break;
736 }
737 default:
738 /* nothing */
739 break;
740 }
741 return 0;
742}
743
744static int tda9887_suspend(struct device * dev, u32 state, u32 level)
745{
746 dprintk("tda9887: suspend\n");
747 return 0;
748}
749
750static int tda9887_resume(struct device * dev, u32 level)
751{
752 struct i2c_client *c = container_of(dev, struct i2c_client, dev);
753 struct tda9887 *t = i2c_get_clientdata(c);
754
755 dprintk("tda9887: resume\n");
756 tda9887_configure(t);
757 return 0;
758}
759
760/* ----------------------------------------------------------------------- */
761
762static struct i2c_driver driver = {
763 .owner = THIS_MODULE,
764 .name = "i2c tda9887 driver",
765 .id = -1, /* FIXME */
766 .flags = I2C_DF_NOTIFY,
767 .attach_adapter = tda9887_probe,
768 .detach_client = tda9887_detach,
769 .command = tda9887_command,
770 .driver = {
771 .suspend = tda9887_suspend,
772 .resume = tda9887_resume,
773 },
774};
775static struct i2c_client client_template =
776{
777 I2C_DEVNAME("tda9887"),
778 .flags = I2C_CLIENT_ALLOW_USE,
779 .driver = &driver,
780};
781
782static int __init tda9887_init_module(void)
783{
784 return i2c_add_driver(&driver);
785}
786
787static void __exit tda9887_cleanup_module(void)
788{
789 i2c_del_driver(&driver);
790}
791
792module_init(tda9887_init_module);
793module_exit(tda9887_cleanup_module);
794
795/*
796 * Overrides for Emacs so that we follow Linus's tabbing style.
797 * ---------------------------------------------------------------------------
798 * Local variables:
799 * c-basic-offset: 8
800 * End:
801 */
diff --git a/drivers/media/video/tea6415c.c b/drivers/media/video/tea6415c.c
new file mode 100644
index 00000000000..3ec39550bf4
--- /dev/null
+++ b/drivers/media/video/tea6415c.c
@@ -0,0 +1,223 @@
1 /*
2 tea6415c - i2c-driver for the tea6415c by SGS Thomson
3
4 Copyright (C) 1998-2003 Michael Hunold <michael@mihu.de>
5
6 The tea6415c is a bus controlled video-matrix-switch
7 with 8 inputs and 6 outputs.
8 It is cascadable, i.e. it can be found at the addresses
9 0x86 and 0x06 on the i2c-bus.
10
11 For detailed informations download the specifications directly
12 from SGS Thomson at http://www.st.com
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 vs 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 Mvss Ave, Cambridge, MA 02139, USA.
27 */
28
29#include <linux/module.h>
30#include <linux/ioctl.h>
31#include <linux/i2c.h>
32
33#include "tea6415c.h"
34
35static int debug = 0; /* insmod parameter */
36module_param(debug, int, 0644);
37MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off).");
38#define dprintk(args...) \
39 do { if (debug) { printk("%s: %s()[%d]: ",__stringify(KBUILD_MODNAME), __FUNCTION__, __LINE__); printk(args); } } while (0)
40
41#define TEA6415C_NUM_INPUTS 8
42#define TEA6415C_NUM_OUTPUTS 6
43
44/* addresses to scan, found only at 0x03 and/or 0x43 (7-bit) */
45static unsigned short normal_i2c[] = { I2C_TEA6415C_1, I2C_TEA6415C_2, I2C_CLIENT_END };
46static unsigned short normal_i2c_range[] = { I2C_CLIENT_END };
47
48/* magic definition of all other variables and things */
49I2C_CLIENT_INSMOD;
50
51static struct i2c_driver driver;
52static struct i2c_client client_template;
53
54/* this function is called by i2c_probe */
55static int detect(struct i2c_adapter *adapter, int address, int kind)
56{
57 struct i2c_client *client = NULL;
58 int err = 0;
59
60 /* let's see whether this adapter can support what we need */
61 if (0 == i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE)) {
62 return 0;
63 }
64
65 /* allocate memory for client structure */
66 client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
67 if (0 == client) {
68 return -ENOMEM;
69 }
70
71 /* fill client structure */
72 memcpy(client, &client_template, sizeof(struct i2c_client));
73 client->addr = address;
74 client->adapter = adapter;
75
76 /* tell the i2c layer a new client has arrived */
77 if (0 != (err = i2c_attach_client(client))) {
78 kfree(client);
79 return err;
80 }
81
82 printk("tea6415c: detected @ 0x%02x on adapter %s\n", address, &client->adapter->name[0]);
83
84 return 0;
85}
86
87static int attach(struct i2c_adapter *adapter)
88{
89 /* let's see whether this is a know adapter we can attach to */
90 if (adapter->id != I2C_ALGO_SAA7146) {
91 dprintk("refusing to probe on unknown adapter [name='%s',id=0x%x]\n", adapter->name, adapter->id);
92 return -ENODEV;
93 }
94
95 return i2c_probe(adapter, &addr_data, &detect);
96}
97
98static int detach(struct i2c_client *client)
99{
100 int ret = i2c_detach_client(client);
101 kfree(client);
102 return ret;
103}
104
105/* makes a connection between the input-pin 'i' and the output-pin 'o'
106 for the tea6415c-client 'client' */
107static int switch_matrix(struct i2c_client *client, int i, int o)
108{
109 u8 byte = 0;
110 int ret;
111
112 dprintk("adr:0x%02x, i:%d, o:%d\n", client->addr, i, o);
113
114 /* check if the pins are valid */
115 if (0 == ((1 == i || 3 == i || 5 == i || 6 == i || 8 == i || 10 == i || 20 == i || 11 == i)
116 && (18 == o || 17 == o || 16 == o || 15 == o || 14 == o || 13 == o)))
117 return -1;
118
119 /* to understand this, have a look at the tea6415c-specs (p.5) */
120 switch (o) {
121 case 18:
122 byte = 0x00;
123 break;
124 case 14:
125 byte = 0x20;
126 break;
127 case 16:
128 byte = 0x10;
129 break;
130 case 17:
131 byte = 0x08;
132 break;
133 case 15:
134 byte = 0x18;
135 break;
136 case 13:
137 byte = 0x28;
138 break;
139 };
140
141 switch (i) {
142 case 5:
143 byte |= 0x00;
144 break;
145 case 8:
146 byte |= 0x04;
147 break;
148 case 3:
149 byte |= 0x02;
150 break;
151 case 20:
152 byte |= 0x06;
153 break;
154 case 6:
155 byte |= 0x01;
156 break;
157 case 10:
158 byte |= 0x05;
159 break;
160 case 1:
161 byte |= 0x03;
162 break;
163 case 11:
164 byte |= 0x07;
165 break;
166 };
167
168 ret = i2c_smbus_write_byte(client, byte);
169 if (ret) {
170 dprintk("i2c_smbus_write_byte() failed, ret:%d\n", ret);
171 return -EIO;
172 }
173
174 return ret;
175}
176
177static int command(struct i2c_client *client, unsigned int cmd, void *arg)
178{
179 struct tea6415c_multiplex *v = (struct tea6415c_multiplex *)arg;
180 int result = 0;
181
182 switch (cmd) {
183 case TEA6415C_SWITCH:
184 result = switch_matrix(client, v->in, v->out);
185 break;
186 default:
187 return -ENOIOCTLCMD;
188 }
189
190 return result;
191}
192
193static struct i2c_driver driver = {
194 .owner = THIS_MODULE,
195 .name = "tea6415c",
196 .id = I2C_DRIVERID_TEA6415C,
197 .flags = I2C_DF_NOTIFY,
198 .attach_adapter = attach,
199 .detach_client = detach,
200 .command = command,
201};
202
203static struct i2c_client client_template = {
204 I2C_DEVNAME("tea6415c"),
205 .driver = &driver,
206};
207
208static int __init this_module_init(void)
209{
210 return i2c_add_driver(&driver);
211}
212
213static void __exit this_module_exit(void)
214{
215 i2c_del_driver(&driver);
216}
217
218module_init(this_module_init);
219module_exit(this_module_exit);
220
221MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
222MODULE_DESCRIPTION("tea6415c driver");
223MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/tea6415c.h b/drivers/media/video/tea6415c.h
new file mode 100644
index 00000000000..f84ed80050b
--- /dev/null
+++ b/drivers/media/video/tea6415c.h
@@ -0,0 +1,39 @@
1#ifndef __INCLUDED_TEA6415C__
2#define __INCLUDED_TEA6415C__
3
4/* possible i2c-addresses */
5#define I2C_TEA6415C_1 0x03
6#define I2C_TEA6415C_2 0x43
7
8/* the tea6415c's design is quite brain-dead. although there are
9 8 inputs and 6 outputs, these aren't enumerated in any way. because
10 I don't want to say "connect input pin 20 to output pin 17", I define
11 a "virtual" pin-order. */
12
13/* input pins */
14#define TEA6415C_OUTPUT1 18
15#define TEA6415C_OUTPUT2 14
16#define TEA6415C_OUTPUT3 16
17#define TEA6415C_OUTPUT4 17
18#define TEA6415C_OUTPUT5 13
19#define TEA6415C_OUTPUT6 15
20
21/* output pins */
22#define TEA6415C_INPUT1 5
23#define TEA6415C_INPUT2 8
24#define TEA6415C_INPUT3 3
25#define TEA6415C_INPUT4 20
26#define TEA6415C_INPUT5 6
27#define TEA6415C_INPUT6 10
28#define TEA6415C_INPUT7 1
29#define TEA6415C_INPUT8 11
30
31struct tea6415c_multiplex
32{
33 int in; /* input-pin */
34 int out; /* output-pin */
35};
36
37#define TEA6415C_SWITCH _IOW('v',1,struct tea6415c_multiplex)
38
39#endif
diff --git a/drivers/media/video/tea6420.c b/drivers/media/video/tea6420.c
new file mode 100644
index 00000000000..bd10710fd90
--- /dev/null
+++ b/drivers/media/video/tea6420.c
@@ -0,0 +1,200 @@
1 /*
2 tea6420 - i2c-driver for the tea6420 by SGS Thomson
3
4 Copyright (C) 1998-2003 Michael Hunold <michael@mihu.de>
5
6 The tea6420 is a bus controlled audio-matrix with 5 stereo inputs,
7 4 stereo outputs and gain control for each output.
8 It is cascadable, i.e. it can be found at the adresses 0x98
9 and 0x9a on the i2c-bus.
10
11 For detailed informations download the specifications directly
12 from SGS Thomson at http://www.st.com
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#include <linux/module.h>
30#include <linux/ioctl.h>
31#include <linux/i2c.h>
32
33#include "tea6420.h"
34
35static int debug = 0; /* insmod parameter */
36module_param(debug, int, 0644);
37MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off).");
38#define dprintk(args...) \
39 do { if (debug) { printk("%s: %s()[%d]: ",__stringify(KBUILD_MODNAME), __FUNCTION__, __LINE__); printk(args); } } while (0)
40
41/* addresses to scan, found only at 0x4c and/or 0x4d (7-Bit) */
42static unsigned short normal_i2c[] = { I2C_TEA6420_1, I2C_TEA6420_2, I2C_CLIENT_END };
43static unsigned short normal_i2c_range[] = { I2C_CLIENT_END };
44
45/* magic definition of all other variables and things */
46I2C_CLIENT_INSMOD;
47
48static struct i2c_driver driver;
49static struct i2c_client client_template;
50
51/* make a connection between the input 'i' and the output 'o'
52 with gain 'g' for the tea6420-client 'client' (note: i = 6 means 'mute') */
53static int tea6420_switch(struct i2c_client *client, int i, int o, int g)
54{
55 u8 byte = 0;
56 int ret;
57
58 dprintk("adr:0x%02x, i:%d, o:%d, g:%d\n", client->addr, i, o, g);
59
60 /* check if the paramters are valid */
61 if (i < 1 || i > 6 || o < 1 || o > 4 || g < 0 || g > 6 || g % 2 != 0)
62 return -1;
63
64 byte = ((o - 1) << 5);
65 byte |= (i - 1);
66
67 /* to understand this, have a look at the tea6420-specs (p.5) */
68 switch (g) {
69 case 0:
70 byte |= (3 << 3);
71 break;
72 case 2:
73 byte |= (2 << 3);
74 break;
75 case 4:
76 byte |= (1 << 3);
77 break;
78 case 6:
79 break;
80 }
81
82 ret = i2c_smbus_write_byte(client, byte);
83 if (ret) {
84 dprintk("i2c_smbus_write_byte() failed, ret:%d\n", ret);
85 return -EIO;
86 }
87
88 return 0;
89}
90
91/* this function is called by i2c_probe */
92static int tea6420_detect(struct i2c_adapter *adapter, int address, int kind)
93{
94 struct i2c_client *client;
95 int err = 0, i = 0;
96
97 /* let's see whether this adapter can support what we need */
98 if (0 == i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE)) {
99 return 0;
100 }
101
102 /* allocate memory for client structure */
103 client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
104 if (0 == client) {
105 return -ENOMEM;
106 }
107 memset(client, 0x0, sizeof(struct i2c_client));
108
109 /* fill client structure */
110 memcpy(client, &client_template, sizeof(struct i2c_client));
111 client->addr = address;
112 client->adapter = adapter;
113
114 /* tell the i2c layer a new client has arrived */
115 if (0 != (err = i2c_attach_client(client))) {
116 kfree(client);
117 return err;
118 }
119
120 /* set initial values: set "mute"-input to all outputs at gain 0 */
121 err = 0;
122 for (i = 1; i < 5; i++) {
123 err += tea6420_switch(client, 6, i, 0);
124 }
125 if (err) {
126 dprintk("could not initialize tea6420\n");
127 kfree(client);
128 return -ENODEV;
129 }
130
131 printk("tea6420: detected @ 0x%02x on adapter %s\n", address, &client->adapter->name[0]);
132
133 return 0;
134}
135
136static int attach(struct i2c_adapter *adapter)
137{
138 /* let's see whether this is a know adapter we can attach to */
139 if (adapter->id != I2C_ALGO_SAA7146) {
140 dprintk("refusing to probe on unknown adapter [name='%s',id=0x%x]\n", adapter->name, adapter->id);
141 return -ENODEV;
142 }
143
144 return i2c_probe(adapter, &addr_data, &tea6420_detect);
145}
146
147static int detach(struct i2c_client *client)
148{
149 int ret = i2c_detach_client(client);
150 kfree(client);
151 return ret;
152}
153
154static int command(struct i2c_client *client, unsigned int cmd, void *arg)
155{
156 struct tea6420_multiplex *a = (struct tea6420_multiplex *)arg;
157 int result = 0;
158
159 switch (cmd) {
160 case TEA6420_SWITCH:
161 result = tea6420_switch(client, a->in, a->out, a->gain);
162 break;
163 default:
164 return -ENOIOCTLCMD;
165 }
166
167 return result;
168}
169
170static struct i2c_driver driver = {
171 .owner = THIS_MODULE,
172 .name = "tea6420",
173 .id = I2C_DRIVERID_TEA6420,
174 .flags = I2C_DF_NOTIFY,
175 .attach_adapter = attach,
176 .detach_client = detach,
177 .command = command,
178};
179
180static struct i2c_client client_template = {
181 I2C_DEVNAME("tea6420"),
182 .driver = &driver,
183};
184
185static int __init this_module_init(void)
186{
187 return i2c_add_driver(&driver);
188}
189
190static void __exit this_module_exit(void)
191{
192 i2c_del_driver(&driver);
193}
194
195module_init(this_module_init);
196module_exit(this_module_exit);
197
198MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
199MODULE_DESCRIPTION("tea6420 driver");
200MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/tea6420.h b/drivers/media/video/tea6420.h
new file mode 100644
index 00000000000..ea664df15ad
--- /dev/null
+++ b/drivers/media/video/tea6420.h
@@ -0,0 +1,17 @@
1#ifndef __INCLUDED_TEA6420__
2#define __INCLUDED_TEA6420__
3
4/* possible addresses */
5#define I2C_TEA6420_1 0x4c
6#define I2C_TEA6420_2 0x4d
7
8struct tea6420_multiplex
9{
10 int in; /* input of audio switch */
11 int out; /* output of audio switch */
12 int gain; /* gain of connection */
13};
14
15#define TEA6420_SWITCH _IOW('v',1,struct tea6420_multiplex)
16
17#endif
diff --git a/drivers/media/video/tuner-3036.c b/drivers/media/video/tuner-3036.c
new file mode 100644
index 00000000000..6b20aa902a8
--- /dev/null
+++ b/drivers/media/video/tuner-3036.c
@@ -0,0 +1,220 @@
1/*
2 * Driver for Philips SAB3036 "CITAC" tuner control chip.
3 *
4 * Author: Phil Blundell <philb@gnu.org>
5 *
6 * The SAB3036 is just about different enough from the chips that
7 * tuner.c copes with to make it not worth the effort to crowbar
8 * the support into that file. So instead we have a separate driver.
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version
13 * 2 of the License, or (at your option) any later version.
14 */
15
16#include <linux/module.h>
17#include <linux/kernel.h>
18#include <linux/sched.h>
19#include <linux/string.h>
20#include <linux/timer.h>
21#include <linux/delay.h>
22#include <linux/errno.h>
23#include <linux/slab.h>
24#include <linux/init.h>
25
26#include <linux/i2c.h>
27#include <linux/videodev.h>
28
29#include <media/tuner.h>
30
31static int debug; /* insmod parameter */
32static int this_adap;
33
34static struct i2c_client client_template;
35
36/* Addresses to scan */
37static unsigned short normal_i2c[] = {I2C_CLIENT_END};
38static unsigned short normal_i2c_range[] = {0x60, 0x61, I2C_CLIENT_END};
39static unsigned short probe[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
40static unsigned short probe_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
41static unsigned short ignore[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
42static unsigned short ignore_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
43static unsigned short force[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
44
45static struct i2c_client_address_data addr_data = {
46 normal_i2c, normal_i2c_range,
47 probe, probe_range,
48 ignore, ignore_range,
49 force
50};
51
52/* ---------------------------------------------------------------------- */
53
54static unsigned char
55tuner_getstatus (struct i2c_client *c)
56{
57 unsigned char byte;
58 if (i2c_master_recv(c, &byte, 1) != 1)
59 printk(KERN_ERR "tuner-3036: I/O error.\n");
60 return byte;
61}
62
63#define TUNER_FL 0x80
64
65static int
66tuner_islocked (struct i2c_client *c)
67{
68 return (tuner_getstatus(c) & TUNER_FL);
69}
70
71/* ---------------------------------------------------------------------- */
72
73static void
74set_tv_freq(struct i2c_client *c, int freq)
75{
76 u16 div = ((freq * 20) / 16);
77 unsigned long give_up = jiffies + HZ;
78 unsigned char buffer[2];
79
80 if (debug)
81 printk(KERN_DEBUG "tuner: setting frequency %dMHz, divisor %x\n", freq / 16, div);
82
83 /* Select high tuning current */
84 buffer[0] = 0x29;
85 buffer[1] = 0x3e;
86
87 if (i2c_master_send(c, buffer, 2) != 2)
88 printk("tuner: i2c i/o error 1\n");
89
90 buffer[0] = 0x80 | ((div>>8) & 0x7f);
91 buffer[1] = div & 0xff;
92
93 if (i2c_master_send(c, buffer, 2) != 2)
94 printk("tuner: i2c i/o error 2\n");
95
96 while (!tuner_islocked(c) && time_before(jiffies, give_up))
97 schedule();
98
99 if (!tuner_islocked(c))
100 printk(KERN_WARNING "tuner: failed to achieve PLL lock\n");
101
102 /* Select low tuning current and engage AFC */
103 buffer[0] = 0x29;
104 buffer[1] = 0xb2;
105
106 if (i2c_master_send(c, buffer, 2) != 2)
107 printk("tuner: i2c i/o error 3\n");
108
109 if (debug)
110 printk(KERN_DEBUG "tuner: status %02x\n", tuner_getstatus(c));
111}
112
113/* ---------------------------------------------------------------------- */
114
115static int
116tuner_attach(struct i2c_adapter *adap, int addr, int kind)
117{
118 static unsigned char buffer[] = { 0x29, 0x32, 0x2a, 0, 0x2b, 0 };
119
120 struct i2c_client *client;
121
122 if (this_adap > 0)
123 return -1;
124 this_adap++;
125
126 client_template.adapter = adap;
127 client_template.addr = addr;
128
129 client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
130 if (client == NULL)
131 return -ENOMEM;
132 memcpy(client, &client_template, sizeof(struct i2c_client));
133
134 printk("tuner: SAB3036 found, status %02x\n", tuner_getstatus(client));
135
136 i2c_attach_client(client);
137
138 if (i2c_master_send(client, buffer, 2) != 2)
139 printk("tuner: i2c i/o error 1\n");
140 if (i2c_master_send(client, buffer+2, 2) != 2)
141 printk("tuner: i2c i/o error 2\n");
142 if (i2c_master_send(client, buffer+4, 2) != 2)
143 printk("tuner: i2c i/o error 3\n");
144 return 0;
145}
146
147static int
148tuner_detach(struct i2c_client *c)
149{
150 return 0;
151}
152
153static int
154tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
155{
156 int *iarg = (int*)arg;
157
158 switch (cmd)
159 {
160 case TUNER_SET_TVFREQ:
161 set_tv_freq(client, *iarg);
162 break;
163
164 default:
165 return -EINVAL;
166 }
167 return 0;
168}
169
170static int
171tuner_probe(struct i2c_adapter *adap)
172{
173 this_adap = 0;
174 if (adap->id == (I2C_ALGO_BIT | I2C_HW_B_LP))
175 return i2c_probe(adap, &addr_data, tuner_attach);
176 return 0;
177}
178
179/* ----------------------------------------------------------------------- */
180
181static struct i2c_driver
182i2c_driver_tuner =
183{
184 .owner = THIS_MODULE,
185 .name = "sab3036",
186 .id = I2C_DRIVERID_SAB3036,
187 .flags = I2C_DF_NOTIFY,
188 .attach_adapter = tuner_probe,
189 .detach_client = tuner_detach,
190 .command = tuner_command
191};
192
193static struct i2c_client client_template =
194{
195 .driver = &i2c_driver_tuner,
196 .name = "SAB3036",
197};
198
199static int __init
200tuner3036_init(void)
201{
202 i2c_add_driver(&i2c_driver_tuner);
203 return 0;
204}
205
206static void __exit
207tuner3036_exit(void)
208{
209 i2c_del_driver(&i2c_driver_tuner);
210}
211
212MODULE_DESCRIPTION("SAB3036 tuner driver");
213MODULE_AUTHOR("Philip Blundell <philb@gnu.org>");
214MODULE_LICENSE("GPL");
215
216module_param(debug, int, 0);
217MODULE_PARM_DESC(debug,"Enable debugging output");
218
219module_init(tuner3036_init);
220module_exit(tuner3036_exit);
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
new file mode 100644
index 00000000000..2f4e18d20b7
--- /dev/null
+++ b/drivers/media/video/tuner-core.c
@@ -0,0 +1,443 @@
1/*
2 * $Id: tuner-core.c,v 1.5 2005/02/15 15:59:35 kraxel Exp $
3 *
4 * i2c tv tuner chip device driver
5 * core core, i.e. kernel interfaces, registering and so on
6 */
7
8#include <linux/module.h>
9#include <linux/moduleparam.h>
10#include <linux/kernel.h>
11#include <linux/sched.h>
12#include <linux/string.h>
13#include <linux/timer.h>
14#include <linux/delay.h>
15#include <linux/errno.h>
16#include <linux/slab.h>
17#include <linux/poll.h>
18#include <linux/i2c.h>
19#include <linux/types.h>
20#include <linux/videodev.h>
21#include <linux/init.h>
22
23#include <media/tuner.h>
24#include <media/audiochip.h>
25
26#define UNSET (-1U)
27
28/* standard i2c insmod options */
29static unsigned short normal_i2c[] = {
30 0x4b, /* tda8290 */
31 I2C_CLIENT_END
32};
33static unsigned short normal_i2c_range[] = {
34 0x60, 0x6f,
35 I2C_CLIENT_END
36};
37I2C_CLIENT_INSMOD;
38
39/* insmod options used at init time => read/only */
40static unsigned int addr = 0;
41module_param(addr, int, 0444);
42
43/* insmod options used at runtime => read/write */
44unsigned int tuner_debug = 0;
45module_param(tuner_debug, int, 0644);
46
47static unsigned int tv_range[2] = { 44, 958 };
48static unsigned int radio_range[2] = { 65, 108 };
49
50module_param_array(tv_range, int, NULL, 0644);
51module_param_array(radio_range, int, NULL, 0644);
52
53MODULE_DESCRIPTION("device driver for various TV and TV+FM radio tuners");
54MODULE_AUTHOR("Ralph Metzler, Gerd Knorr, Gunther Mayer");
55MODULE_LICENSE("GPL");
56
57static int this_adap;
58
59static struct i2c_driver driver;
60static struct i2c_client client_template;
61
62/* ---------------------------------------------------------------------- */
63
64// Set tuner frequency, freq in Units of 62.5kHz = 1/16MHz
65static void set_tv_freq(struct i2c_client *c, unsigned int freq)
66{
67 struct tuner *t = i2c_get_clientdata(c);
68
69 if (t->type == UNSET) {
70 tuner_info("tuner type not set\n");
71 return;
72 }
73 if (NULL == t->tv_freq) {
74 tuner_info("Huh? tv_set is NULL?\n");
75 return;
76 }
77 if (freq < tv_range[0]*16 || freq > tv_range[1]*16) {
78 /* FIXME: better do that chip-specific, but
79 right now we don't have that in the config
80 struct and this way is still better than no
81 check at all */
82 tuner_info("TV freq (%d.%02d) out of range (%d-%d)\n",
83 freq/16,freq%16*100/16,tv_range[0],tv_range[1]);
84 return;
85 }
86 t->tv_freq(c,freq);
87}
88
89static void set_radio_freq(struct i2c_client *c, unsigned int freq)
90{
91 struct tuner *t = i2c_get_clientdata(c);
92
93 if (t->type == UNSET) {
94 tuner_info("tuner type not set\n");
95 return;
96 }
97 if (NULL == t->radio_freq) {
98 tuner_info("no radio tuning for this one, sorry.\n");
99 return;
100 }
101 if (freq < radio_range[0]*16 || freq > radio_range[1]*16) {
102 tuner_info("radio freq (%d.%02d) out of range (%d-%d)\n",
103 freq/16,freq%16*100/16,
104 radio_range[0],radio_range[1]);
105 return;
106 }
107 t->radio_freq(c,freq);
108}
109
110static void set_freq(struct i2c_client *c, unsigned long freq)
111{
112 struct tuner *t = i2c_get_clientdata(c);
113
114 switch (t->mode) {
115 case V4L2_TUNER_RADIO:
116 tuner_dbg("radio freq set to %lu.%02lu\n",
117 freq/16,freq%16*100/16);
118 set_radio_freq(c,freq);
119 break;
120 case V4L2_TUNER_ANALOG_TV:
121 case V4L2_TUNER_DIGITAL_TV:
122 tuner_dbg("tv freq set to %lu.%02lu\n",
123 freq/16,freq%16*100/16);
124 set_tv_freq(c, freq);
125 break;
126 }
127 t->freq = freq;
128}
129
130static void set_type(struct i2c_client *c, unsigned int type)
131{
132 struct tuner *t = i2c_get_clientdata(c);
133
134 /* sanity check */
135 if (type == UNSET || type == TUNER_ABSENT)
136 return;
137 if (type >= tuner_count)
138 return;
139
140 if (NULL == t->i2c.dev.driver) {
141 /* not registered yet */
142 t->type = type;
143 return;
144 }
145 if (t->initialized)
146 /* run only once */
147 return;
148
149 t->initialized = 1;
150 t->type = type;
151 switch (t->type) {
152 case TUNER_MT2032:
153 microtune_init(c);
154 break;
155 case TUNER_PHILIPS_TDA8290:
156 tda8290_init(c);
157 break;
158 default:
159 default_tuner_init(c);
160 break;
161 }
162}
163
164static char pal[] = "-";
165module_param_string(pal, pal, 0644, sizeof(pal));
166
167static int tuner_fixup_std(struct tuner *t)
168{
169 if ((t->std & V4L2_STD_PAL) == V4L2_STD_PAL) {
170 /* get more precise norm info from insmod option */
171 switch (pal[0]) {
172 case 'b':
173 case 'B':
174 case 'g':
175 case 'G':
176 tuner_dbg("insmod fixup: PAL => PAL-BG\n");
177 t->std = V4L2_STD_PAL_BG;
178 break;
179 case 'i':
180 case 'I':
181 tuner_dbg("insmod fixup: PAL => PAL-I\n");
182 t->std = V4L2_STD_PAL_I;
183 break;
184 case 'd':
185 case 'D':
186 case 'k':
187 case 'K':
188 tuner_dbg("insmod fixup: PAL => PAL-DK\n");
189 t->std = V4L2_STD_PAL_DK;
190 break;
191 }
192 }
193 return 0;
194}
195
196/* ---------------------------------------------------------------------- */
197
198static int tuner_attach(struct i2c_adapter *adap, int addr, int kind)
199{
200 struct tuner *t;
201
202 if (this_adap > 0)
203 return -1;
204 this_adap++;
205
206 client_template.adapter = adap;
207 client_template.addr = addr;
208
209 t = kmalloc(sizeof(struct tuner),GFP_KERNEL);
210 if (NULL == t)
211 return -ENOMEM;
212 memset(t,0,sizeof(struct tuner));
213 memcpy(&t->i2c,&client_template,sizeof(struct i2c_client));
214 i2c_set_clientdata(&t->i2c, t);
215 t->type = UNSET;
216 t->radio_if2 = 10700*1000; // 10.7MHz - FM radio
217
218 i2c_attach_client(&t->i2c);
219 tuner_info("chip found @ 0x%x (%s)\n",
220 addr << 1, adap->name);
221 set_type(&t->i2c, t->type);
222 return 0;
223}
224
225static int tuner_probe(struct i2c_adapter *adap)
226{
227 if (0 != addr) {
228 normal_i2c[0] = addr;
229 normal_i2c_range[0] = addr;
230 normal_i2c_range[1] = addr;
231 }
232 this_adap = 0;
233
234 if (adap->class & I2C_CLASS_TV_ANALOG)
235 return i2c_probe(adap, &addr_data, tuner_attach);
236 return 0;
237}
238
239static int tuner_detach(struct i2c_client *client)
240{
241 struct tuner *t = i2c_get_clientdata(client);
242
243 i2c_detach_client(&t->i2c);
244 kfree(t);
245 return 0;
246}
247
248#define SWITCH_V4L2 if (!t->using_v4l2 && tuner_debug) \
249 tuner_info("switching to v4l2\n"); \
250 t->using_v4l2 = 1;
251#define CHECK_V4L2 if (t->using_v4l2) { if (tuner_debug) \
252 tuner_info("ignore v4l1 call\n"); \
253 return 0; }
254
255static int
256tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
257{
258 struct tuner *t = i2c_get_clientdata(client);
259 unsigned int *iarg = (int*)arg;
260
261 switch (cmd) {
262
263 /* --- configuration --- */
264 case TUNER_SET_TYPE:
265 set_type(client,*iarg);
266 break;
267 case AUDC_SET_RADIO:
268 if (V4L2_TUNER_RADIO != t->mode) {
269 set_tv_freq(client,400 * 16);
270 t->mode = V4L2_TUNER_RADIO;
271 }
272 break;
273 case AUDC_CONFIG_PINNACLE:
274 switch (*iarg) {
275 case 2:
276 tuner_dbg("pinnacle pal\n");
277 t->radio_if2 = 33300 * 1000;
278 break;
279 case 3:
280 tuner_dbg("pinnacle ntsc\n");
281 t->radio_if2 = 41300 * 1000;
282 break;
283 }
284 break;
285
286 /* --- v4l ioctls --- */
287 /* take care: bttv does userspace copying, we'll get a
288 kernel pointer here... */
289 case VIDIOCSCHAN:
290 {
291 static const v4l2_std_id map[] = {
292 [ VIDEO_MODE_PAL ] = V4L2_STD_PAL,
293 [ VIDEO_MODE_NTSC ] = V4L2_STD_NTSC_M,
294 [ VIDEO_MODE_SECAM ] = V4L2_STD_SECAM,
295 [ 4 /* bttv */ ] = V4L2_STD_PAL_M,
296 [ 5 /* bttv */ ] = V4L2_STD_PAL_N,
297 [ 6 /* bttv */ ] = V4L2_STD_NTSC_M_JP,
298 };
299 struct video_channel *vc = arg;
300
301 CHECK_V4L2;
302 t->mode = V4L2_TUNER_ANALOG_TV;
303 if (vc->norm < ARRAY_SIZE(map))
304 t->std = map[vc->norm];
305 tuner_fixup_std(t);
306 if (t->freq)
307 set_tv_freq(client,t->freq);
308 return 0;
309 }
310 case VIDIOCSFREQ:
311 {
312 unsigned long *v = arg;
313
314 CHECK_V4L2;
315 set_freq(client,*v);
316 return 0;
317 }
318 case VIDIOCGTUNER:
319 {
320 struct video_tuner *vt = arg;
321
322 CHECK_V4L2;
323 if (V4L2_TUNER_RADIO == t->mode && t->has_signal)
324 vt->signal = t->has_signal(client);
325 return 0;
326 }
327 case VIDIOCGAUDIO:
328 {
329 struct video_audio *va = arg;
330
331 CHECK_V4L2;
332 if (V4L2_TUNER_RADIO == t->mode && t->is_stereo)
333 va->mode = t->is_stereo(client)
334 ? VIDEO_SOUND_STEREO
335 : VIDEO_SOUND_MONO;
336 return 0;
337 }
338
339 case VIDIOC_S_STD:
340 {
341 v4l2_std_id *id = arg;
342
343 SWITCH_V4L2;
344 t->mode = V4L2_TUNER_ANALOG_TV;
345 t->std = *id;
346 tuner_fixup_std(t);
347 if (t->freq)
348 set_freq(client,t->freq);
349 break;
350 }
351 case VIDIOC_S_FREQUENCY:
352 {
353 struct v4l2_frequency *f = arg;
354
355 SWITCH_V4L2;
356 if (V4L2_TUNER_RADIO == f->type &&
357 V4L2_TUNER_RADIO != t->mode)
358 set_tv_freq(client,400*16);
359 t->mode = f->type;
360 t->freq = f->frequency;
361 set_freq(client,t->freq);
362 break;
363 }
364 case VIDIOC_G_TUNER:
365 {
366 struct v4l2_tuner *tuner = arg;
367
368 SWITCH_V4L2;
369 if (V4L2_TUNER_RADIO == t->mode && t->has_signal)
370 tuner->signal = t->has_signal(client);
371 break;
372 }
373 default:
374 /* nothing */
375 break;
376 }
377
378 return 0;
379}
380
381static int tuner_suspend(struct device * dev, u32 state, u32 level)
382{
383 struct i2c_client *c = container_of(dev, struct i2c_client, dev);
384 struct tuner *t = i2c_get_clientdata(c);
385
386 tuner_dbg("suspend\n");
387 /* FIXME: power down ??? */
388 return 0;
389}
390
391static int tuner_resume(struct device * dev, u32 level)
392{
393 struct i2c_client *c = container_of(dev, struct i2c_client, dev);
394 struct tuner *t = i2c_get_clientdata(c);
395
396 tuner_dbg("resume\n");
397 if (t->freq)
398 set_freq(c,t->freq);
399 return 0;
400}
401
402/* ----------------------------------------------------------------------- */
403
404static struct i2c_driver driver = {
405 .owner = THIS_MODULE,
406 .name = "tuner",
407 .id = I2C_DRIVERID_TUNER,
408 .flags = I2C_DF_NOTIFY,
409 .attach_adapter = tuner_probe,
410 .detach_client = tuner_detach,
411 .command = tuner_command,
412 .driver = {
413 .suspend = tuner_suspend,
414 .resume = tuner_resume,
415 },
416};
417static struct i2c_client client_template =
418{
419 I2C_DEVNAME("(tuner unset)"),
420 .flags = I2C_CLIENT_ALLOW_USE,
421 .driver = &driver,
422};
423
424static int __init tuner_init_module(void)
425{
426 return i2c_add_driver(&driver);
427}
428
429static void __exit tuner_cleanup_module(void)
430{
431 i2c_del_driver(&driver);
432}
433
434module_init(tuner_init_module);
435module_exit(tuner_cleanup_module);
436
437/*
438 * Overrides for Emacs so that we follow Linus's tabbing style.
439 * ---------------------------------------------------------------------------
440 * Local variables:
441 * c-basic-offset: 8
442 * End:
443 */
diff --git a/drivers/media/video/tuner-simple.c b/drivers/media/video/tuner-simple.c
new file mode 100644
index 00000000000..48c6ceff1dc
--- /dev/null
+++ b/drivers/media/video/tuner-simple.c
@@ -0,0 +1,474 @@
1/*
2 * $Id: tuner-simple.c,v 1.10 2005/03/08 08:38:00 kraxel Exp $
3 *
4 * i2c tv tuner chip device driver
5 * controls all those simple 4-control-bytes style tuners.
6 */
7#include <linux/delay.h>
8#include <linux/i2c.h>
9#include <linux/videodev.h>
10#include <media/tuner.h>
11
12/* ---------------------------------------------------------------------- */
13
14/* tv standard selection for Temic 4046 FM5
15 this value takes the low bits of control byte 2
16 from datasheet Rev.01, Feb.00
17 standard BG I L L2 D
18 picture IF 38.9 38.9 38.9 33.95 38.9
19 sound 1 33.4 32.9 32.4 40.45 32.4
20 sound 2 33.16
21 NICAM 33.05 32.348 33.05 33.05
22 */
23#define TEMIC_SET_PAL_I 0x05
24#define TEMIC_SET_PAL_DK 0x09
25#define TEMIC_SET_PAL_L 0x0a // SECAM ?
26#define TEMIC_SET_PAL_L2 0x0b // change IF !
27#define TEMIC_SET_PAL_BG 0x0c
28
29/* tv tuner system standard selection for Philips FQ1216ME
30 this value takes the low bits of control byte 2
31 from datasheet "1999 Nov 16" (supersedes "1999 Mar 23")
32 standard BG DK I L L`
33 picture carrier 38.90 38.90 38.90 38.90 33.95
34 colour 34.47 34.47 34.47 34.47 38.38
35 sound 1 33.40 32.40 32.90 32.40 40.45
36 sound 2 33.16 - - - -
37 NICAM 33.05 33.05 32.35 33.05 39.80
38 */
39#define PHILIPS_SET_PAL_I 0x01 /* Bit 2 always zero !*/
40#define PHILIPS_SET_PAL_BGDK 0x09
41#define PHILIPS_SET_PAL_L2 0x0a
42#define PHILIPS_SET_PAL_L 0x0b
43
44/* system switching for Philips FI1216MF MK2
45 from datasheet "1996 Jul 09",
46 standard BG L L'
47 picture carrier 38.90 38.90 33.95
48 colour 34.47 34.37 38.38
49 sound 1 33.40 32.40 40.45
50 sound 2 33.16 - -
51 NICAM 33.05 33.05 39.80
52 */
53#define PHILIPS_MF_SET_BG 0x01 /* Bit 2 must be zero, Bit 3 is system output */
54#define PHILIPS_MF_SET_PAL_L 0x03 // France
55#define PHILIPS_MF_SET_PAL_L2 0x02 // L'
56
57
58/* ---------------------------------------------------------------------- */
59
60struct tunertype
61{
62 char *name;
63 unsigned char Vendor;
64 unsigned char Type;
65
66 unsigned short thresh1; /* band switch VHF_LO <=> VHF_HI */
67 unsigned short thresh2; /* band switch VHF_HI <=> UHF */
68 unsigned char VHF_L;
69 unsigned char VHF_H;
70 unsigned char UHF;
71 unsigned char config;
72 unsigned short IFPCoff; /* 622.4=16*38.90 MHz PAL,
73 732 =16*45.75 NTSCi,
74 940 =16*58.75 NTSC-Japan
75 704 =16*44 ATSC */
76};
77
78/*
79 * The floats in the tuner struct are computed at compile time
80 * by gcc and cast back to integers. Thus we don't violate the
81 * "no float in kernel" rule.
82 */
83static struct tunertype tuners[] = {
84 { "Temic PAL (4002 FH5)", TEMIC, PAL,
85 16*140.25,16*463.25,0x02,0x04,0x01,0x8e,623},
86 { "Philips PAL_I (FI1246 and compatibles)", Philips, PAL_I,
87 16*140.25,16*463.25,0xa0,0x90,0x30,0x8e,623},
88 { "Philips NTSC (FI1236,FM1236 and compatibles)", Philips, NTSC,
89 16*157.25,16*451.25,0xA0,0x90,0x30,0x8e,732},
90 { "Philips (SECAM+PAL_BG) (FI1216MF, FM1216MF, FR1216MF)", Philips, SECAM,
91 16*168.25,16*447.25,0xA7,0x97,0x37,0x8e,623},
92
93 { "NoTuner", NoTuner, NOTUNER,
94 0,0,0x00,0x00,0x00,0x00,0x00},
95 { "Philips PAL_BG (FI1216 and compatibles)", Philips, PAL,
96 16*168.25,16*447.25,0xA0,0x90,0x30,0x8e,623},
97 { "Temic NTSC (4032 FY5)", TEMIC, NTSC,
98 16*157.25,16*463.25,0x02,0x04,0x01,0x8e,732},
99 { "Temic PAL_I (4062 FY5)", TEMIC, PAL_I,
100 16*170.00,16*450.00,0x02,0x04,0x01,0x8e,623},
101
102 { "Temic NTSC (4036 FY5)", TEMIC, NTSC,
103 16*157.25,16*463.25,0xa0,0x90,0x30,0x8e,732},
104 { "Alps HSBH1", TEMIC, NTSC,
105 16*137.25,16*385.25,0x01,0x02,0x08,0x8e,732},
106 { "Alps TSBE1",TEMIC,PAL,
107 16*137.25,16*385.25,0x01,0x02,0x08,0x8e,732},
108 { "Alps TSBB5", Alps, PAL_I, /* tested (UK UHF) with Modulartech MM205 */
109 16*133.25,16*351.25,0x01,0x02,0x08,0x8e,632},
110
111 { "Alps TSBE5", Alps, PAL, /* untested - data sheet guess. Only IF differs. */
112 16*133.25,16*351.25,0x01,0x02,0x08,0x8e,622},
113 { "Alps TSBC5", Alps, PAL, /* untested - data sheet guess. Only IF differs. */
114 16*133.25,16*351.25,0x01,0x02,0x08,0x8e,608},
115 { "Temic PAL_BG (4006FH5)", TEMIC, PAL,
116 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623},
117 { "Alps TSCH6",Alps,NTSC,
118 16*137.25,16*385.25,0x14,0x12,0x11,0x8e,732},
119
120 { "Temic PAL_DK (4016 FY5)",TEMIC,PAL,
121 16*168.25,16*456.25,0xa0,0x90,0x30,0x8e,623},
122 { "Philips NTSC_M (MK2)",Philips,NTSC,
123 16*160.00,16*454.00,0xa0,0x90,0x30,0x8e,732},
124 { "Temic PAL_I (4066 FY5)", TEMIC, PAL_I,
125 16*169.00, 16*454.00, 0xa0,0x90,0x30,0x8e,623},
126 { "Temic PAL* auto (4006 FN5)", TEMIC, PAL,
127 16*169.00, 16*454.00, 0xa0,0x90,0x30,0x8e,623},
128
129 { "Temic PAL_BG (4009 FR5) or PAL_I (4069 FR5)", TEMIC, PAL,
130 16*141.00, 16*464.00, 0xa0,0x90,0x30,0x8e,623},
131 { "Temic NTSC (4039 FR5)", TEMIC, NTSC,
132 16*158.00, 16*453.00, 0xa0,0x90,0x30,0x8e,732},
133 { "Temic PAL/SECAM multi (4046 FM5)", TEMIC, PAL,
134 16*169.00, 16*454.00, 0xa0,0x90,0x30,0x8e,623},
135 { "Philips PAL_DK (FI1256 and compatibles)", Philips, PAL,
136 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623},
137
138 { "Philips PAL/SECAM multi (FQ1216ME)", Philips, PAL,
139 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623},
140 { "LG PAL_I+FM (TAPC-I001D)", LGINNOTEK, PAL_I,
141 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623},
142 { "LG PAL_I (TAPC-I701D)", LGINNOTEK, PAL_I,
143 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623},
144 { "LG NTSC+FM (TPI8NSR01F)", LGINNOTEK, NTSC,
145 16*210.00,16*497.00,0xa0,0x90,0x30,0x8e,732},
146
147 { "LG PAL_BG+FM (TPI8PSB01D)", LGINNOTEK, PAL,
148 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623},
149 { "LG PAL_BG (TPI8PSB11D)", LGINNOTEK, PAL,
150 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623},
151 { "Temic PAL* auto + FM (4009 FN5)", TEMIC, PAL,
152 16*141.00, 16*464.00, 0xa0,0x90,0x30,0x8e,623},
153 { "SHARP NTSC_JP (2U5JF5540)", SHARP, NTSC, /* 940=16*58.75 NTSC@Japan */
154 16*137.25,16*317.25,0x01,0x02,0x08,0x8e,940 },
155
156 { "Samsung PAL TCPM9091PD27", Samsung, PAL, /* from sourceforge v3tv */
157 16*169,16*464,0xA0,0x90,0x30,0x8e,623},
158 { "MT20xx universal", Microtune,PAL|NTSC,
159 /* see mt20xx.c for details */ },
160 { "Temic PAL_BG (4106 FH5)", TEMIC, PAL,
161 16*141.00, 16*464.00, 0xa0,0x90,0x30,0x8e,623},
162 { "Temic PAL_DK/SECAM_L (4012 FY5)", TEMIC, PAL,
163 16*140.25, 16*463.25, 0x02,0x04,0x01,0x8e,623},
164
165 { "Temic NTSC (4136 FY5)", TEMIC, NTSC,
166 16*158.00, 16*453.00, 0xa0,0x90,0x30,0x8e,732},
167 { "LG PAL (newer TAPC series)", LGINNOTEK, PAL,
168 16*170.00, 16*450.00, 0x01,0x02,0x08,0x8e,623},
169 { "Philips PAL/SECAM multi (FM1216ME MK3)", Philips, PAL,
170 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,623 },
171 { "LG NTSC (newer TAPC series)", LGINNOTEK, NTSC,
172 16*170.00, 16*450.00, 0x01,0x02,0x08,0x8e,732},
173
174 { "HITACHI V7-J180AT", HITACHI, NTSC,
175 16*170.00, 16*450.00, 0x01,0x02,0x08,0x8e,940 },
176 { "Philips PAL_MK (FI1216 MK)", Philips, PAL,
177 16*140.25,16*463.25,0x01,0xc2,0xcf,0x8e,623},
178 { "Philips 1236D ATSC/NTSC daul in",Philips,ATSC,
179 16*157.25,16*454.00,0xa0,0x90,0x30,0x8e,732},
180 { "Philips NTSC MK3 (FM1236MK3 or FM1236/F)", Philips, NTSC,
181 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732},
182
183 { "Philips 4 in 1 (ATI TV Wonder Pro/Conexant)", Philips, NTSC,
184 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732},
185 { "Microtune 4049 FM5",Microtune,PAL,
186 16*141.00,16*464.00,0xa0,0x90,0x30,0x8e,623},
187 { "Panasonic VP27s/ENGE4324D", Panasonic, NTSC,
188 16*160.00,16*454.00,0x01,0x02,0x08,0xce,940},
189 { "LG NTSC (TAPE series)", LGINNOTEK, NTSC,
190 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732 },
191
192 { "Tenna TNF 8831 BGFF)", Philips, PAL,
193 16*161.25,16*463.25,0xa0,0x90,0x30,0x8e,623},
194 { "Microtune 4042 FI5 ATSC/NTSC dual in", Microtune, NTSC,
195 16*162.00,16*457.00,0xa2,0x94,0x31,0x8e,732},
196 { "TCL 2002N", TCL, NTSC,
197 16*172.00,16*448.00,0x01,0x02,0x08,0x8e,732},
198 { "Philips PAL/SECAM_D (FM 1256 I-H3)", Philips, PAL,
199 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,623 },
200
201 { "Thomson DDT 7610 (ATSC/NTSC)", THOMSON, ATSC,
202 16*157.25,16*454.00,0x39,0x3a,0x3c,0x8e,732},
203 { "Philips FQ1286", Philips, NTSC,
204 16*160.00,16*454.00,0x41,0x42,0x04,0x8e,940}, // UHF band untested
205 { "tda8290+75", Philips,PAL|NTSC,
206 /* see tda8290.c for details */ },
207 { "LG PAL (TAPE series)", LGINNOTEK, PAL,
208 16*170.00, 16*450.00, 0x01,0x02,0x08,0xce,623},
209
210 { "Philips PAL/SECAM multi (FQ1216AME MK4)", Philips, PAL,
211 16*160.00,16*442.00,0x01,0x02,0x04,0xce,623 },
212 { "Philips FQ1236A MK4", Philips, NTSC,
213 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732 },
214
215};
216unsigned const int tuner_count = ARRAY_SIZE(tuners);
217
218/* ---------------------------------------------------------------------- */
219
220static int tuner_getstatus(struct i2c_client *c)
221{
222 unsigned char byte;
223
224 if (1 != i2c_master_recv(c,&byte,1))
225 return 0;
226 return byte;
227}
228
229#define TUNER_POR 0x80
230#define TUNER_FL 0x40
231#define TUNER_MODE 0x38
232#define TUNER_AFC 0x07
233
234#define TUNER_STEREO 0x10 /* radio mode */
235#define TUNER_SIGNAL 0x07 /* radio mode */
236
237static int tuner_signal(struct i2c_client *c)
238{
239 return (tuner_getstatus(c) & TUNER_SIGNAL)<<13;
240}
241
242static int tuner_stereo(struct i2c_client *c)
243{
244 return (tuner_getstatus (c) & TUNER_STEREO);
245}
246
247#if 0 /* unused */
248static int tuner_islocked (struct i2c_client *c)
249{
250 return (tuner_getstatus (c) & TUNER_FL);
251}
252
253static int tuner_afcstatus (struct i2c_client *c)
254{
255 return (tuner_getstatus (c) & TUNER_AFC) - 2;
256}
257
258static int tuner_mode (struct i2c_client *c)
259{
260 return (tuner_getstatus (c) & TUNER_MODE) >> 3;
261}
262#endif
263
264/* ---------------------------------------------------------------------- */
265
266static void default_set_tv_freq(struct i2c_client *c, unsigned int freq)
267{
268 struct tuner *t = i2c_get_clientdata(c);
269 u8 config;
270 u16 div;
271 struct tunertype *tun;
272 unsigned char buffer[4];
273 int rc;
274
275 tun = &tuners[t->type];
276 if (freq < tun->thresh1) {
277 config = tun->VHF_L;
278 tuner_dbg("tv: VHF lowrange\n");
279 } else if (freq < tun->thresh2) {
280 config = tun->VHF_H;
281 tuner_dbg("tv: VHF high range\n");
282 } else {
283 config = tun->UHF;
284 tuner_dbg("tv: UHF range\n");
285 }
286
287
288 /* tv norm specific stuff for multi-norm tuners */
289 switch (t->type) {
290 case TUNER_PHILIPS_SECAM: // FI1216MF
291 /* 0x01 -> ??? no change ??? */
292 /* 0x02 -> PAL BDGHI / SECAM L */
293 /* 0x04 -> ??? PAL others / SECAM others ??? */
294 config &= ~0x02;
295 if (t->std & V4L2_STD_SECAM)
296 config |= 0x02;
297 break;
298
299 case TUNER_TEMIC_4046FM5:
300 config &= ~0x0f;
301
302 if (t->std & V4L2_STD_PAL_BG) {
303 config |= TEMIC_SET_PAL_BG;
304
305 } else if (t->std & V4L2_STD_PAL_I) {
306 config |= TEMIC_SET_PAL_I;
307
308 } else if (t->std & V4L2_STD_PAL_DK) {
309 config |= TEMIC_SET_PAL_DK;
310
311 } else if (t->std & V4L2_STD_SECAM_L) {
312 config |= TEMIC_SET_PAL_L;
313
314 }
315 break;
316
317 case TUNER_PHILIPS_FQ1216ME:
318 config &= ~0x0f;
319
320 if (t->std & (V4L2_STD_PAL_BG|V4L2_STD_PAL_DK)) {
321 config |= PHILIPS_SET_PAL_BGDK;
322
323 } else if (t->std & V4L2_STD_PAL_I) {
324 config |= PHILIPS_SET_PAL_I;
325
326 } else if (t->std & V4L2_STD_SECAM_L) {
327 config |= PHILIPS_SET_PAL_L;
328
329 }
330 break;
331
332 case TUNER_PHILIPS_ATSC:
333 /* 0x00 -> ATSC antenna input 1 */
334 /* 0x01 -> ATSC antenna input 2 */
335 /* 0x02 -> NTSC antenna input 1 */
336 /* 0x03 -> NTSC antenna input 2 */
337 config &= ~0x03;
338 if (!(t->std & V4L2_STD_ATSC))
339 config |= 2;
340 /* FIXME: input */
341 break;
342
343 case TUNER_MICROTUNE_4042FI5:
344 /* Set the charge pump for fast tuning */
345 tun->config |= 0x40;
346 break;
347 }
348
349 /*
350 * Philips FI1216MK2 remark from specification :
351 * for channel selection involving band switching, and to ensure
352 * smooth tuning to the desired channel without causing
353 * unnecessary charge pump action, it is recommended to consider
354 * the difference between wanted channel frequency and the
355 * current channel frequency. Unnecessary charge pump action
356 * will result in very low tuning voltage which may drive the
357 * oscillator to extreme conditions.
358 *
359 * Progfou: specification says to send config data before
360 * frequency in case (wanted frequency < current frequency).
361 */
362
363 div=freq + tun->IFPCoff;
364 if (t->type == TUNER_PHILIPS_SECAM && freq < t->freq) {
365 buffer[0] = tun->config;
366 buffer[1] = config;
367 buffer[2] = (div>>8) & 0x7f;
368 buffer[3] = div & 0xff;
369 } else {
370 buffer[0] = (div>>8) & 0x7f;
371 buffer[1] = div & 0xff;
372 buffer[2] = tun->config;
373 buffer[3] = config;
374 }
375 tuner_dbg("tv 0x%02x 0x%02x 0x%02x 0x%02x\n",
376 buffer[0],buffer[1],buffer[2],buffer[3]);
377
378 if (4 != (rc = i2c_master_send(c,buffer,4)))
379 tuner_warn("i2c i/o error: rc == %d (should be 4)\n",rc);
380
381 if (t->type == TUNER_MICROTUNE_4042FI5) {
382 // FIXME - this may also work for other tuners
383 unsigned long timeout = jiffies + msecs_to_jiffies(1);
384 u8 status_byte = 0;
385
386 /* Wait until the PLL locks */
387 for (;;) {
388 if (time_after(jiffies,timeout))
389 return;
390 if (1 != (rc = i2c_master_recv(c,&status_byte,1))) {
391 tuner_warn("i2c i/o read error: rc == %d (should be 1)\n",rc);
392 break;
393 }
394 /* bit 6 is PLL locked indicator */
395 if (status_byte & 0x40)
396 break;
397 udelay(10);
398 }
399
400 /* Set the charge pump for optimized phase noise figure */
401 tun->config &= ~0x40;
402 buffer[0] = (div>>8) & 0x7f;
403 buffer[1] = div & 0xff;
404 buffer[2] = tun->config;
405 buffer[3] = config;
406 tuner_dbg("tv 0x%02x 0x%02x 0x%02x 0x%02x\n",
407 buffer[0],buffer[1],buffer[2],buffer[3]);
408
409 if (4 != (rc = i2c_master_send(c,buffer,4)))
410 tuner_warn("i2c i/o error: rc == %d (should be 4)\n",rc);
411 }
412}
413
414static void default_set_radio_freq(struct i2c_client *c, unsigned int freq)
415{
416 struct tunertype *tun;
417 struct tuner *t = i2c_get_clientdata(c);
418 unsigned char buffer[4];
419 unsigned div;
420 int rc;
421
422 tun=&tuners[t->type];
423 div = freq + (int)(16*10.7);
424 buffer[2] = tun->config;
425
426 switch (t->type) {
427 case TUNER_PHILIPS_FM1216ME_MK3:
428 case TUNER_PHILIPS_FM1236_MK3:
429 buffer[3] = 0x19;
430 break;
431 case TUNER_PHILIPS_FM1256_IH3:
432 div = (20 * freq)/16 + 333 * 2;
433 buffer[2] = 0x80;
434 buffer[3] = 0x19;
435 break;
436 case TUNER_LG_PAL_FM:
437 buffer[3] = 0xa5;
438 break;
439 default:
440 buffer[3] = 0xa4;
441 break;
442 }
443 buffer[0] = (div>>8) & 0x7f;
444 buffer[1] = div & 0xff;
445
446 tuner_dbg("radio 0x%02x 0x%02x 0x%02x 0x%02x\n",
447 buffer[0],buffer[1],buffer[2],buffer[3]);
448
449 if (4 != (rc = i2c_master_send(c,buffer,4)))
450 tuner_warn("i2c i/o error: rc == %d (should be 4)\n",rc);
451}
452
453int default_tuner_init(struct i2c_client *c)
454{
455 struct tuner *t = i2c_get_clientdata(c);
456
457 tuner_info("type set to %d (%s)\n",
458 t->type, tuners[t->type].name);
459 strlcpy(c->name, tuners[t->type].name, sizeof(c->name));
460
461 t->tv_freq = default_set_tv_freq;
462 t->radio_freq = default_set_radio_freq;
463 t->has_signal = tuner_signal;
464 t->is_stereo = tuner_stereo;
465 return 0;
466}
467
468/*
469 * Overrides for Emacs so that we follow Linus's tabbing style.
470 * ---------------------------------------------------------------------------
471 * Local variables:
472 * c-basic-offset: 8
473 * End:
474 */
diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c
new file mode 100644
index 00000000000..065eb4007b1
--- /dev/null
+++ b/drivers/media/video/tvaudio.c
@@ -0,0 +1,1740 @@
1/*
2 * experimental driver for simple i2c audio chips.
3 *
4 * Copyright (c) 2000 Gerd Knorr
5 * based on code by:
6 * Eric Sandeen (eric_sandeen@bigfoot.com)
7 * Steve VanDeBogart (vandebo@uclink.berkeley.edu)
8 * Greg Alexander (galexand@acm.org)
9 *
10 * This code is placed under the terms of the GNU General Public License
11 *
12 * OPTIONS:
13 * debug - set to 1 if you'd like to see debug messages
14 *
15 */
16
17#include <linux/config.h>
18#include <linux/module.h>
19#include <linux/moduleparam.h>
20#include <linux/kernel.h>
21#include <linux/sched.h>
22#include <linux/string.h>
23#include <linux/timer.h>
24#include <linux/delay.h>
25#include <linux/errno.h>
26#include <linux/slab.h>
27#include <linux/videodev.h>
28#include <linux/i2c.h>
29#include <linux/i2c-algo-bit.h>
30#include <linux/init.h>
31#include <linux/smp_lock.h>
32
33#include <media/audiochip.h>
34#include <media/id.h>
35
36#include "tvaudio.h"
37
38/* ---------------------------------------------------------------------- */
39/* insmod args */
40
41static int debug = 0; /* insmod parameter */
42module_param(debug, int, 0644);
43
44MODULE_DESCRIPTION("device driver for various i2c TV sound decoder / audiomux chips");
45MODULE_AUTHOR("Eric Sandeen, Steve VanDeBogart, Greg Alexander, Gerd Knorr");
46MODULE_LICENSE("GPL");
47
48#define UNSET (-1U)
49#define dprintk if (debug) printk
50
51/* ---------------------------------------------------------------------- */
52/* our structs */
53
54#define MAXREGS 64
55
56struct CHIPSTATE;
57typedef int (*getvalue)(int);
58typedef int (*checkit)(struct CHIPSTATE*);
59typedef int (*initialize)(struct CHIPSTATE*);
60typedef int (*getmode)(struct CHIPSTATE*);
61typedef void (*setmode)(struct CHIPSTATE*, int mode);
62typedef void (*checkmode)(struct CHIPSTATE*);
63
64/* i2c command */
65typedef struct AUDIOCMD {
66 int count; /* # of bytes to send */
67 unsigned char bytes[MAXREGS+1]; /* addr, data, data, ... */
68} audiocmd;
69
70/* chip description */
71struct CHIPDESC {
72 char *name; /* chip name */
73 int id; /* ID */
74 int addr_lo, addr_hi; /* i2c address range */
75 int registers; /* # of registers */
76
77 int *insmodopt;
78 checkit checkit;
79 initialize initialize;
80 int flags;
81#define CHIP_HAS_VOLUME 1
82#define CHIP_HAS_BASSTREBLE 2
83#define CHIP_HAS_INPUTSEL 4
84
85 /* various i2c command sequences */
86 audiocmd init;
87
88 /* which register has which value */
89 int leftreg,rightreg,treblereg,bassreg;
90
91 /* initialize with (defaults to 65535/65535/32768/32768 */
92 int leftinit,rightinit,trebleinit,bassinit;
93
94 /* functions to convert the values (v4l -> chip) */
95 getvalue volfunc,treblefunc,bassfunc;
96
97 /* get/set mode */
98 getmode getmode;
99 setmode setmode;
100
101 /* check / autoswitch audio after channel switches */
102 checkmode checkmode;
103
104 /* input switch register + values for v4l inputs */
105 int inputreg;
106 int inputmap[8];
107 int inputmute;
108 int inputmask;
109};
110static struct CHIPDESC chiplist[];
111
112/* current state of the chip */
113struct CHIPSTATE {
114 struct i2c_client c;
115
116 /* index into CHIPDESC array */
117 int type;
118
119 /* shadow register set */
120 audiocmd shadow;
121
122 /* current settings */
123 __u16 left,right,treble,bass,mode;
124 int prevmode;
125 int norm;
126
127 /* thread */
128 pid_t tpid;
129 struct completion texit;
130 wait_queue_head_t wq;
131 struct timer_list wt;
132 int done;
133 int watch_stereo;
134};
135
136#define VIDEO_MODE_RADIO 16 /* norm magic for radio mode */
137
138/* ---------------------------------------------------------------------- */
139/* i2c addresses */
140
141static unsigned short normal_i2c[] = {
142 I2C_TDA8425 >> 1,
143 I2C_TEA6300 >> 1,
144 I2C_TEA6420 >> 1,
145 I2C_TDA9840 >> 1,
146 I2C_TDA985x_L >> 1,
147 I2C_TDA985x_H >> 1,
148 I2C_TDA9874 >> 1,
149 I2C_PIC16C54 >> 1,
150 I2C_CLIENT_END };
151static unsigned short normal_i2c_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
152I2C_CLIENT_INSMOD;
153
154static struct i2c_driver driver;
155static struct i2c_client client_template;
156
157
158/* ---------------------------------------------------------------------- */
159/* i2c I/O functions */
160
161static int chip_write(struct CHIPSTATE *chip, int subaddr, int val)
162{
163 unsigned char buffer[2];
164
165 if (-1 == subaddr) {
166 dprintk("%s: chip_write: 0x%x\n",
167 i2c_clientname(&chip->c), val);
168 chip->shadow.bytes[1] = val;
169 buffer[0] = val;
170 if (1 != i2c_master_send(&chip->c,buffer,1)) {
171 printk(KERN_WARNING "%s: I/O error (write 0x%x)\n",
172 i2c_clientname(&chip->c), val);
173 return -1;
174 }
175 } else {
176 dprintk("%s: chip_write: reg%d=0x%x\n",
177 i2c_clientname(&chip->c), subaddr, val);
178 chip->shadow.bytes[subaddr+1] = val;
179 buffer[0] = subaddr;
180 buffer[1] = val;
181 if (2 != i2c_master_send(&chip->c,buffer,2)) {
182 printk(KERN_WARNING "%s: I/O error (write reg%d=0x%x)\n",
183 i2c_clientname(&chip->c), subaddr, val);
184 return -1;
185 }
186 }
187 return 0;
188}
189
190static int chip_write_masked(struct CHIPSTATE *chip, int subaddr, int val, int mask)
191{
192 if (mask != 0) {
193 if (-1 == subaddr) {
194 val = (chip->shadow.bytes[1] & ~mask) | (val & mask);
195 } else {
196 val = (chip->shadow.bytes[subaddr+1] & ~mask) | (val & mask);
197 }
198 }
199 return chip_write(chip, subaddr, val);
200}
201
202static int chip_read(struct CHIPSTATE *chip)
203{
204 unsigned char buffer;
205
206 if (1 != i2c_master_recv(&chip->c,&buffer,1)) {
207 printk(KERN_WARNING "%s: I/O error (read)\n",
208 i2c_clientname(&chip->c));
209 return -1;
210 }
211 dprintk("%s: chip_read: 0x%x\n",i2c_clientname(&chip->c),buffer);
212 return buffer;
213}
214
215static int chip_read2(struct CHIPSTATE *chip, int subaddr)
216{
217 unsigned char write[1];
218 unsigned char read[1];
219 struct i2c_msg msgs[2] = {
220 { chip->c.addr, 0, 1, write },
221 { chip->c.addr, I2C_M_RD, 1, read }
222 };
223 write[0] = subaddr;
224
225 if (2 != i2c_transfer(chip->c.adapter,msgs,2)) {
226 printk(KERN_WARNING "%s: I/O error (read2)\n",
227 i2c_clientname(&chip->c));
228 return -1;
229 }
230 dprintk("%s: chip_read2: reg%d=0x%x\n",
231 i2c_clientname(&chip->c),subaddr,read[0]);
232 return read[0];
233}
234
235static int chip_cmd(struct CHIPSTATE *chip, char *name, audiocmd *cmd)
236{
237 int i;
238
239 if (0 == cmd->count)
240 return 0;
241
242 /* update our shadow register set; print bytes if (debug > 0) */
243 dprintk("%s: chip_cmd(%s): reg=%d, data:",
244 i2c_clientname(&chip->c),name,cmd->bytes[0]);
245 for (i = 1; i < cmd->count; i++) {
246 dprintk(" 0x%x",cmd->bytes[i]);
247 chip->shadow.bytes[i+cmd->bytes[0]] = cmd->bytes[i];
248 }
249 dprintk("\n");
250
251 /* send data to the chip */
252 if (cmd->count != i2c_master_send(&chip->c,cmd->bytes,cmd->count)) {
253 printk(KERN_WARNING "%s: I/O error (%s)\n", i2c_clientname(&chip->c), name);
254 return -1;
255 }
256 return 0;
257}
258
259/* ---------------------------------------------------------------------- */
260/* kernel thread for doing i2c stuff asyncronly
261 * right now it is used only to check the audio mode (mono/stereo/whatever)
262 * some time after switching to another TV channel, then turn on stereo
263 * if available, ...
264 */
265
266static void chip_thread_wake(unsigned long data)
267{
268 struct CHIPSTATE *chip = (struct CHIPSTATE*)data;
269 wake_up_interruptible(&chip->wq);
270}
271
272static int chip_thread(void *data)
273{
274 DECLARE_WAITQUEUE(wait, current);
275 struct CHIPSTATE *chip = data;
276 struct CHIPDESC *desc = chiplist + chip->type;
277
278 daemonize("%s",i2c_clientname(&chip->c));
279 allow_signal(SIGTERM);
280 dprintk("%s: thread started\n", i2c_clientname(&chip->c));
281
282 for (;;) {
283 add_wait_queue(&chip->wq, &wait);
284 if (!chip->done) {
285 set_current_state(TASK_INTERRUPTIBLE);
286 schedule();
287 }
288 remove_wait_queue(&chip->wq, &wait);
289 try_to_freeze(PF_FREEZE);
290 if (chip->done || signal_pending(current))
291 break;
292 dprintk("%s: thread wakeup\n", i2c_clientname(&chip->c));
293
294 /* don't do anything for radio or if mode != auto */
295 if (chip->norm == VIDEO_MODE_RADIO || chip->mode != 0)
296 continue;
297
298 /* have a look what's going on */
299 desc->checkmode(chip);
300
301 /* schedule next check */
302 mod_timer(&chip->wt, jiffies+2*HZ);
303 }
304
305 dprintk("%s: thread exiting\n", i2c_clientname(&chip->c));
306 complete_and_exit(&chip->texit, 0);
307 return 0;
308}
309
310static void generic_checkmode(struct CHIPSTATE *chip)
311{
312 struct CHIPDESC *desc = chiplist + chip->type;
313 int mode = desc->getmode(chip);
314
315 if (mode == chip->prevmode)
316 return;
317
318 dprintk("%s: thread checkmode\n", i2c_clientname(&chip->c));
319 chip->prevmode = mode;
320
321 if (mode & VIDEO_SOUND_STEREO)
322 desc->setmode(chip,VIDEO_SOUND_STEREO);
323 else if (mode & VIDEO_SOUND_LANG1)
324 desc->setmode(chip,VIDEO_SOUND_LANG1);
325 else if (mode & VIDEO_SOUND_LANG2)
326 desc->setmode(chip,VIDEO_SOUND_LANG2);
327 else
328 desc->setmode(chip,VIDEO_SOUND_MONO);
329}
330
331/* ---------------------------------------------------------------------- */
332/* audio chip descriptions - defines+functions for tda9840 */
333
334#define TDA9840_SW 0x00
335#define TDA9840_LVADJ 0x02
336#define TDA9840_STADJ 0x03
337#define TDA9840_TEST 0x04
338
339#define TDA9840_MONO 0x10
340#define TDA9840_STEREO 0x2a
341#define TDA9840_DUALA 0x12
342#define TDA9840_DUALB 0x1e
343#define TDA9840_DUALAB 0x1a
344#define TDA9840_DUALBA 0x16
345#define TDA9840_EXTERNAL 0x7a
346
347#define TDA9840_DS_DUAL 0x20 /* Dual sound identified */
348#define TDA9840_ST_STEREO 0x40 /* Stereo sound identified */
349#define TDA9840_PONRES 0x80 /* Power-on reset detected if = 1 */
350
351#define TDA9840_TEST_INT1SN 0x1 /* Integration time 0.5s when set */
352#define TDA9840_TEST_INTFU 0x02 /* Disables integrator function */
353
354static int tda9840_getmode(struct CHIPSTATE *chip)
355{
356 int val, mode;
357
358 val = chip_read(chip);
359 mode = VIDEO_SOUND_MONO;
360 if (val & TDA9840_DS_DUAL)
361 mode |= VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
362 if (val & TDA9840_ST_STEREO)
363 mode |= VIDEO_SOUND_STEREO;
364
365 dprintk ("tda9840_getmode(): raw chip read: %d, return: %d\n",
366 val, mode);
367 return mode;
368}
369
370static void tda9840_setmode(struct CHIPSTATE *chip, int mode)
371{
372 int update = 1;
373 int t = chip->shadow.bytes[TDA9840_SW + 1] & ~0x7e;
374
375 switch (mode) {
376 case VIDEO_SOUND_MONO:
377 t |= TDA9840_MONO;
378 break;
379 case VIDEO_SOUND_STEREO:
380 t |= TDA9840_STEREO;
381 break;
382 case VIDEO_SOUND_LANG1:
383 t |= TDA9840_DUALA;
384 break;
385 case VIDEO_SOUND_LANG2:
386 t |= TDA9840_DUALB;
387 break;
388 default:
389 update = 0;
390 }
391
392 if (update)
393 chip_write(chip, TDA9840_SW, t);
394}
395
396/* ---------------------------------------------------------------------- */
397/* audio chip descriptions - defines+functions for tda985x */
398
399/* subaddresses for TDA9855 */
400#define TDA9855_VR 0x00 /* Volume, right */
401#define TDA9855_VL 0x01 /* Volume, left */
402#define TDA9855_BA 0x02 /* Bass */
403#define TDA9855_TR 0x03 /* Treble */
404#define TDA9855_SW 0x04 /* Subwoofer - not connected on DTV2000 */
405
406/* subaddresses for TDA9850 */
407#define TDA9850_C4 0x04 /* Control 1 for TDA9850 */
408
409/* subaddesses for both chips */
410#define TDA985x_C5 0x05 /* Control 2 for TDA9850, Control 1 for TDA9855 */
411#define TDA985x_C6 0x06 /* Control 3 for TDA9850, Control 2 for TDA9855 */
412#define TDA985x_C7 0x07 /* Control 4 for TDA9850, Control 3 for TDA9855 */
413#define TDA985x_A1 0x08 /* Alignment 1 for both chips */
414#define TDA985x_A2 0x09 /* Alignment 2 for both chips */
415#define TDA985x_A3 0x0a /* Alignment 3 for both chips */
416
417/* Masks for bits in TDA9855 subaddresses */
418/* 0x00 - VR in TDA9855 */
419/* 0x01 - VL in TDA9855 */
420/* lower 7 bits control gain from -71dB (0x28) to 16dB (0x7f)
421 * in 1dB steps - mute is 0x27 */
422
423
424/* 0x02 - BA in TDA9855 */
425/* lower 5 bits control bass gain from -12dB (0x06) to 16.5dB (0x19)
426 * in .5dB steps - 0 is 0x0E */
427
428
429/* 0x03 - TR in TDA9855 */
430/* 4 bits << 1 control treble gain from -12dB (0x3) to 12dB (0xb)
431 * in 3dB steps - 0 is 0x7 */
432
433/* Masks for bits in both chips' subaddresses */
434/* 0x04 - SW in TDA9855, C4/Control 1 in TDA9850 */
435/* Unique to TDA9855: */
436/* 4 bits << 2 control subwoofer/surround gain from -14db (0x1) to 14db (0xf)
437 * in 3dB steps - mute is 0x0 */
438
439/* Unique to TDA9850: */
440/* lower 4 bits control stereo noise threshold, over which stereo turns off
441 * set to values of 0x00 through 0x0f for Ster1 through Ster16 */
442
443
444/* 0x05 - C5 - Control 1 in TDA9855 , Control 2 in TDA9850*/
445/* Unique to TDA9855: */
446#define TDA9855_MUTE 1<<7 /* GMU, Mute at outputs */
447#define TDA9855_AVL 1<<6 /* AVL, Automatic Volume Level */
448#define TDA9855_LOUD 1<<5 /* Loudness, 1==off */
449#define TDA9855_SUR 1<<3 /* Surround / Subwoofer 1==.5(L-R) 0==.5(L+R) */
450 /* Bits 0 to 3 select various combinations
451 * of line in and line out, only the
452 * interesting ones are defined */
453#define TDA9855_EXT 1<<2 /* Selects inputs LIR and LIL. Pins 41 & 12 */
454#define TDA9855_INT 0 /* Selects inputs LOR and LOL. (internal) */
455
456/* Unique to TDA9850: */
457/* lower 4 bits contol SAP noise threshold, over which SAP turns off
458 * set to values of 0x00 through 0x0f for SAP1 through SAP16 */
459
460
461/* 0x06 - C6 - Control 2 in TDA9855, Control 3 in TDA9850 */
462/* Common to TDA9855 and TDA9850: */
463#define TDA985x_SAP 3<<6 /* Selects SAP output, mute if not received */
464#define TDA985x_STEREO 1<<6 /* Selects Stereo ouput, mono if not received */
465#define TDA985x_MONO 0 /* Forces Mono output */
466#define TDA985x_LMU 1<<3 /* Mute (LOR/LOL for 9855, OUTL/OUTR for 9850) */
467
468/* Unique to TDA9855: */
469#define TDA9855_TZCM 1<<5 /* If set, don't mute till zero crossing */
470#define TDA9855_VZCM 1<<4 /* If set, don't change volume till zero crossing*/
471#define TDA9855_LINEAR 0 /* Linear Stereo */
472#define TDA9855_PSEUDO 1 /* Pseudo Stereo */
473#define TDA9855_SPAT_30 2 /* Spatial Stereo, 30% anti-phase crosstalk */
474#define TDA9855_SPAT_50 3 /* Spatial Stereo, 52% anti-phase crosstalk */
475#define TDA9855_E_MONO 7 /* Forced mono - mono select elseware, so useless*/
476
477/* 0x07 - C7 - Control 3 in TDA9855, Control 4 in TDA9850 */
478/* Common to both TDA9855 and TDA9850: */
479/* lower 4 bits control input gain from -3.5dB (0x0) to 4dB (0xF)
480 * in .5dB steps - 0dB is 0x7 */
481
482/* 0x08, 0x09 - A1 and A2 (read/write) */
483/* Common to both TDA9855 and TDA9850: */
484/* lower 5 bites are wideband and spectral expander alignment
485 * from 0x00 to 0x1f - nominal at 0x0f and 0x10 (read/write) */
486#define TDA985x_STP 1<<5 /* Stereo Pilot/detect (read-only) */
487#define TDA985x_SAPP 1<<6 /* SAP Pilot/detect (read-only) */
488#define TDA985x_STS 1<<7 /* Stereo trigger 1= <35mV 0= <30mV (write-only)*/
489
490/* 0x0a - A3 */
491/* Common to both TDA9855 and TDA9850: */
492/* lower 3 bits control timing current for alignment: -30% (0x0), -20% (0x1),
493 * -10% (0x2), nominal (0x3), +10% (0x6), +20% (0x5), +30% (0x4) */
494#define TDA985x_ADJ 1<<7 /* Stereo adjust on/off (wideband and spectral */
495
496static int tda9855_volume(int val) { return val/0x2e8+0x27; }
497static int tda9855_bass(int val) { return val/0xccc+0x06; }
498static int tda9855_treble(int val) { return (val/0x1c71+0x3)<<1; }
499
500static int tda985x_getmode(struct CHIPSTATE *chip)
501{
502 int mode;
503
504 mode = ((TDA985x_STP | TDA985x_SAPP) &
505 chip_read(chip)) >> 4;
506 /* Add mono mode regardless of SAP and stereo */
507 /* Allows forced mono */
508 return mode | VIDEO_SOUND_MONO;
509}
510
511static void tda985x_setmode(struct CHIPSTATE *chip, int mode)
512{
513 int update = 1;
514 int c6 = chip->shadow.bytes[TDA985x_C6+1] & 0x3f;
515
516 switch (mode) {
517 case VIDEO_SOUND_MONO:
518 c6 |= TDA985x_MONO;
519 break;
520 case VIDEO_SOUND_STEREO:
521 c6 |= TDA985x_STEREO;
522 break;
523 case VIDEO_SOUND_LANG1:
524 c6 |= TDA985x_SAP;
525 break;
526 default:
527 update = 0;
528 }
529 if (update)
530 chip_write(chip,TDA985x_C6,c6);
531}
532
533
534/* ---------------------------------------------------------------------- */
535/* audio chip descriptions - defines+functions for tda9873h */
536
537/* Subaddresses for TDA9873H */
538
539#define TDA9873_SW 0x00 /* Switching */
540#define TDA9873_AD 0x01 /* Adjust */
541#define TDA9873_PT 0x02 /* Port */
542
543/* Subaddress 0x00: Switching Data
544 * B7..B0:
545 *
546 * B1, B0: Input source selection
547 * 0, 0 internal
548 * 1, 0 external stereo
549 * 0, 1 external mono
550 */
551#define TDA9873_INP_MASK 3
552#define TDA9873_INTERNAL 0
553#define TDA9873_EXT_STEREO 2
554#define TDA9873_EXT_MONO 1
555
556/* B3, B2: output signal select
557 * B4 : transmission mode
558 * 0, 0, 1 Mono
559 * 1, 0, 0 Stereo
560 * 1, 1, 1 Stereo (reversed channel)
561 * 0, 0, 0 Dual AB
562 * 0, 0, 1 Dual AA
563 * 0, 1, 0 Dual BB
564 * 0, 1, 1 Dual BA
565 */
566
567#define TDA9873_TR_MASK (7 << 2)
568#define TDA9873_TR_MONO 4
569#define TDA9873_TR_STEREO 1 << 4
570#define TDA9873_TR_REVERSE (1 << 3) & (1 << 2)
571#define TDA9873_TR_DUALA 1 << 2
572#define TDA9873_TR_DUALB 1 << 3
573
574/* output level controls
575 * B5: output level switch (0 = reduced gain, 1 = normal gain)
576 * B6: mute (1 = muted)
577 * B7: auto-mute (1 = auto-mute enabled)
578 */
579
580#define TDA9873_GAIN_NORMAL 1 << 5
581#define TDA9873_MUTE 1 << 6
582#define TDA9873_AUTOMUTE 1 << 7
583
584/* Subaddress 0x01: Adjust/standard */
585
586/* Lower 4 bits (C3..C0) control stereo adjustment on R channel (-0.6 - +0.7 dB)
587 * Recommended value is +0 dB
588 */
589
590#define TDA9873_STEREO_ADJ 0x06 /* 0dB gain */
591
592/* Bits C6..C4 control FM stantard
593 * C6, C5, C4
594 * 0, 0, 0 B/G (PAL FM)
595 * 0, 0, 1 M
596 * 0, 1, 0 D/K(1)
597 * 0, 1, 1 D/K(2)
598 * 1, 0, 0 D/K(3)
599 * 1, 0, 1 I
600 */
601#define TDA9873_BG 0
602#define TDA9873_M 1
603#define TDA9873_DK1 2
604#define TDA9873_DK2 3
605#define TDA9873_DK3 4
606#define TDA9873_I 5
607
608/* C7 controls identification response time (1=fast/0=normal)
609 */
610#define TDA9873_IDR_NORM 0
611#define TDA9873_IDR_FAST 1 << 7
612
613
614/* Subaddress 0x02: Port data */
615
616/* E1, E0 free programmable ports P1/P2
617 0, 0 both ports low
618 0, 1 P1 high
619 1, 0 P2 high
620 1, 1 both ports high
621*/
622
623#define TDA9873_PORTS 3
624
625/* E2: test port */
626#define TDA9873_TST_PORT 1 << 2
627
628/* E5..E3 control mono output channel (together with transmission mode bit B4)
629 *
630 * E5 E4 E3 B4 OUTM
631 * 0 0 0 0 mono
632 * 0 0 1 0 DUAL B
633 * 0 1 0 1 mono (from stereo decoder)
634 */
635#define TDA9873_MOUT_MONO 0
636#define TDA9873_MOUT_FMONO 0
637#define TDA9873_MOUT_DUALA 0
638#define TDA9873_MOUT_DUALB 1 << 3
639#define TDA9873_MOUT_ST 1 << 4
640#define TDA9873_MOUT_EXTM (1 << 4 ) & (1 << 3)
641#define TDA9873_MOUT_EXTL 1 << 5
642#define TDA9873_MOUT_EXTR (1 << 5 ) & (1 << 3)
643#define TDA9873_MOUT_EXTLR (1 << 5 ) & (1 << 4)
644#define TDA9873_MOUT_MUTE (1 << 5 ) & (1 << 4) & (1 << 3)
645
646/* Status bits: (chip read) */
647#define TDA9873_PONR 0 /* Power-on reset detected if = 1 */
648#define TDA9873_STEREO 2 /* Stereo sound is identified */
649#define TDA9873_DUAL 4 /* Dual sound is identified */
650
651static int tda9873_getmode(struct CHIPSTATE *chip)
652{
653 int val,mode;
654
655 val = chip_read(chip);
656 mode = VIDEO_SOUND_MONO;
657 if (val & TDA9873_STEREO)
658 mode |= VIDEO_SOUND_STEREO;
659 if (val & TDA9873_DUAL)
660 mode |= VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
661 dprintk ("tda9873_getmode(): raw chip read: %d, return: %d\n",
662 val, mode);
663 return mode;
664}
665
666static void tda9873_setmode(struct CHIPSTATE *chip, int mode)
667{
668 int sw_data = chip->shadow.bytes[TDA9873_SW+1] & ~ TDA9873_TR_MASK;
669 /* int adj_data = chip->shadow.bytes[TDA9873_AD+1] ; */
670
671 if ((sw_data & TDA9873_INP_MASK) != TDA9873_INTERNAL) {
672 dprintk("tda9873_setmode(): external input\n");
673 return;
674 }
675
676 dprintk("tda9873_setmode(): chip->shadow.bytes[%d] = %d\n", TDA9873_SW+1, chip->shadow.bytes[TDA9873_SW+1]);
677 dprintk("tda9873_setmode(): sw_data = %d\n", sw_data);
678
679 switch (mode) {
680 case VIDEO_SOUND_MONO:
681 sw_data |= TDA9873_TR_MONO;
682 break;
683 case VIDEO_SOUND_STEREO:
684 sw_data |= TDA9873_TR_STEREO;
685 break;
686 case VIDEO_SOUND_LANG1:
687 sw_data |= TDA9873_TR_DUALA;
688 break;
689 case VIDEO_SOUND_LANG2:
690 sw_data |= TDA9873_TR_DUALB;
691 break;
692 default:
693 chip->mode = 0;
694 return;
695 }
696
697 chip_write(chip, TDA9873_SW, sw_data);
698 dprintk("tda9873_setmode(): req. mode %d; chip_write: %d\n",
699 mode, sw_data);
700}
701
702static int tda9873_checkit(struct CHIPSTATE *chip)
703{
704 int rc;
705
706 if (-1 == (rc = chip_read2(chip,254)))
707 return 0;
708 return (rc & ~0x1f) == 0x80;
709}
710
711
712/* ---------------------------------------------------------------------- */
713/* audio chip description - defines+functions for tda9874h and tda9874a */
714/* Dariusz Kowalewski <darekk@automex.pl> */
715
716/* Subaddresses for TDA9874H and TDA9874A (slave rx) */
717#define TDA9874A_AGCGR 0x00 /* AGC gain */
718#define TDA9874A_GCONR 0x01 /* general config */
719#define TDA9874A_MSR 0x02 /* monitor select */
720#define TDA9874A_C1FRA 0x03 /* carrier 1 freq. */
721#define TDA9874A_C1FRB 0x04 /* carrier 1 freq. */
722#define TDA9874A_C1FRC 0x05 /* carrier 1 freq. */
723#define TDA9874A_C2FRA 0x06 /* carrier 2 freq. */
724#define TDA9874A_C2FRB 0x07 /* carrier 2 freq. */
725#define TDA9874A_C2FRC 0x08 /* carrier 2 freq. */
726#define TDA9874A_DCR 0x09 /* demodulator config */
727#define TDA9874A_FMER 0x0a /* FM de-emphasis */
728#define TDA9874A_FMMR 0x0b /* FM dematrix */
729#define TDA9874A_C1OLAR 0x0c /* ch.1 output level adj. */
730#define TDA9874A_C2OLAR 0x0d /* ch.2 output level adj. */
731#define TDA9874A_NCONR 0x0e /* NICAM config */
732#define TDA9874A_NOLAR 0x0f /* NICAM output level adj. */
733#define TDA9874A_NLELR 0x10 /* NICAM lower error limit */
734#define TDA9874A_NUELR 0x11 /* NICAM upper error limit */
735#define TDA9874A_AMCONR 0x12 /* audio mute control */
736#define TDA9874A_SDACOSR 0x13 /* stereo DAC output select */
737#define TDA9874A_AOSR 0x14 /* analog output select */
738#define TDA9874A_DAICONR 0x15 /* digital audio interface config */
739#define TDA9874A_I2SOSR 0x16 /* I2S-bus output select */
740#define TDA9874A_I2SOLAR 0x17 /* I2S-bus output level adj. */
741#define TDA9874A_MDACOSR 0x18 /* mono DAC output select (tda9874a) */
742#define TDA9874A_ESP 0xFF /* easy standard progr. (tda9874a) */
743
744/* Subaddresses for TDA9874H and TDA9874A (slave tx) */
745#define TDA9874A_DSR 0x00 /* device status */
746#define TDA9874A_NSR 0x01 /* NICAM status */
747#define TDA9874A_NECR 0x02 /* NICAM error count */
748#define TDA9874A_DR1 0x03 /* add. data LSB */
749#define TDA9874A_DR2 0x04 /* add. data MSB */
750#define TDA9874A_LLRA 0x05 /* monitor level read-out LSB */
751#define TDA9874A_LLRB 0x06 /* monitor level read-out MSB */
752#define TDA9874A_SIFLR 0x07 /* SIF level */
753#define TDA9874A_TR2 252 /* test reg. 2 */
754#define TDA9874A_TR1 253 /* test reg. 1 */
755#define TDA9874A_DIC 254 /* device id. code */
756#define TDA9874A_SIC 255 /* software id. code */
757
758
759static int tda9874a_mode = 1; /* 0: A2, 1: NICAM */
760static int tda9874a_GCONR = 0xc0; /* default config. input pin: SIFSEL=0 */
761static int tda9874a_NCONR = 0x01; /* default NICAM config.: AMSEL=0,AMUTE=1 */
762static int tda9874a_ESP = 0x07; /* default standard: NICAM D/K */
763static int tda9874a_dic = -1; /* device id. code */
764
765/* insmod options for tda9874a */
766static unsigned int tda9874a_SIF = UNSET;
767static unsigned int tda9874a_AMSEL = UNSET;
768static unsigned int tda9874a_STD = UNSET;
769module_param(tda9874a_SIF, int, 0444);
770module_param(tda9874a_AMSEL, int, 0444);
771module_param(tda9874a_STD, int, 0444);
772
773/*
774 * initialization table for tda9874 decoder:
775 * - carrier 1 freq. registers (3 bytes)
776 * - carrier 2 freq. registers (3 bytes)
777 * - demudulator config register
778 * - FM de-emphasis register (slow identification mode)
779 * Note: frequency registers must be written in single i2c transfer.
780 */
781static struct tda9874a_MODES {
782 char *name;
783 audiocmd cmd;
784} tda9874a_modelist[9] = {
785 { "A2, B/G",
786 { 9, { TDA9874A_C1FRA, 0x72,0x95,0x55, 0x77,0xA0,0x00, 0x00,0x00 }} },
787 { "A2, M (Korea)",
788 { 9, { TDA9874A_C1FRA, 0x5D,0xC0,0x00, 0x62,0x6A,0xAA, 0x20,0x22 }} },
789 { "A2, D/K (1)",
790 { 9, { TDA9874A_C1FRA, 0x87,0x6A,0xAA, 0x82,0x60,0x00, 0x00,0x00 }} },
791 { "A2, D/K (2)",
792 { 9, { TDA9874A_C1FRA, 0x87,0x6A,0xAA, 0x8C,0x75,0x55, 0x00,0x00 }} },
793 { "A2, D/K (3)",
794 { 9, { TDA9874A_C1FRA, 0x87,0x6A,0xAA, 0x77,0xA0,0x00, 0x00,0x00 }} },
795 { "NICAM, I",
796 { 9, { TDA9874A_C1FRA, 0x7D,0x00,0x00, 0x88,0x8A,0xAA, 0x08,0x33 }} },
797 { "NICAM, B/G",
798 { 9, { TDA9874A_C1FRA, 0x72,0x95,0x55, 0x79,0xEA,0xAA, 0x08,0x33 }} },
799 { "NICAM, D/K", /* default */
800 { 9, { TDA9874A_C1FRA, 0x87,0x6A,0xAA, 0x79,0xEA,0xAA, 0x08,0x33 }} },
801 { "NICAM, L",
802 { 9, { TDA9874A_C1FRA, 0x87,0x6A,0xAA, 0x79,0xEA,0xAA, 0x09,0x33 }} }
803};
804
805static int tda9874a_setup(struct CHIPSTATE *chip)
806{
807 chip_write(chip, TDA9874A_AGCGR, 0x00); /* 0 dB */
808 chip_write(chip, TDA9874A_GCONR, tda9874a_GCONR);
809 chip_write(chip, TDA9874A_MSR, (tda9874a_mode) ? 0x03:0x02);
810 if(tda9874a_dic == 0x11) {
811 chip_write(chip, TDA9874A_FMMR, 0x80);
812 } else { /* dic == 0x07 */
813 chip_cmd(chip,"tda9874_modelist",&tda9874a_modelist[tda9874a_STD].cmd);
814 chip_write(chip, TDA9874A_FMMR, 0x00);
815 }
816 chip_write(chip, TDA9874A_C1OLAR, 0x00); /* 0 dB */
817 chip_write(chip, TDA9874A_C2OLAR, 0x00); /* 0 dB */
818 chip_write(chip, TDA9874A_NCONR, tda9874a_NCONR);
819 chip_write(chip, TDA9874A_NOLAR, 0x00); /* 0 dB */
820 /* Note: If signal quality is poor you may want to change NICAM */
821 /* error limit registers (NLELR and NUELR) to some greater values. */
822 /* Then the sound would remain stereo, but won't be so clear. */
823 chip_write(chip, TDA9874A_NLELR, 0x14); /* default */
824 chip_write(chip, TDA9874A_NUELR, 0x50); /* default */
825
826 if(tda9874a_dic == 0x11) {
827 chip_write(chip, TDA9874A_AMCONR, 0xf9);
828 chip_write(chip, TDA9874A_SDACOSR, (tda9874a_mode) ? 0x81:0x80);
829 chip_write(chip, TDA9874A_AOSR, 0x80);
830 chip_write(chip, TDA9874A_MDACOSR, (tda9874a_mode) ? 0x82:0x80);
831 chip_write(chip, TDA9874A_ESP, tda9874a_ESP);
832 } else { /* dic == 0x07 */
833 chip_write(chip, TDA9874A_AMCONR, 0xfb);
834 chip_write(chip, TDA9874A_SDACOSR, (tda9874a_mode) ? 0x81:0x80);
835 chip_write(chip, TDA9874A_AOSR, 0x00); // or 0x10
836 }
837 dprintk("tda9874a_setup(): %s [0x%02X].\n",
838 tda9874a_modelist[tda9874a_STD].name,tda9874a_STD);
839 return 1;
840}
841
842static int tda9874a_getmode(struct CHIPSTATE *chip)
843{
844 int dsr,nsr,mode;
845 int necr; /* just for debugging */
846
847 mode = VIDEO_SOUND_MONO;
848
849 if(-1 == (dsr = chip_read2(chip,TDA9874A_DSR)))
850 return mode;
851 if(-1 == (nsr = chip_read2(chip,TDA9874A_NSR)))
852 return mode;
853 if(-1 == (necr = chip_read2(chip,TDA9874A_NECR)))
854 return mode;
855
856 /* need to store dsr/nsr somewhere */
857 chip->shadow.bytes[MAXREGS-2] = dsr;
858 chip->shadow.bytes[MAXREGS-1] = nsr;
859
860 if(tda9874a_mode) {
861 /* Note: DSR.RSSF and DSR.AMSTAT bits are also checked.
862 * If NICAM auto-muting is enabled, DSR.AMSTAT=1 indicates
863 * that sound has (temporarily) switched from NICAM to
864 * mono FM (or AM) on 1st sound carrier due to high NICAM bit
865 * error count. So in fact there is no stereo in this case :-(
866 * But changing the mode to VIDEO_SOUND_MONO would switch
867 * external 4052 multiplexer in audio_hook().
868 */
869#if 0
870 if((nsr & 0x02) && !(dsr & 0x10)) /* NSR.S/MB=1 and DSR.AMSTAT=0 */
871 mode |= VIDEO_SOUND_STEREO;
872#else
873 if(nsr & 0x02) /* NSR.S/MB=1 */
874 mode |= VIDEO_SOUND_STEREO;
875#endif
876 if(nsr & 0x01) /* NSR.D/SB=1 */
877 mode |= VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
878 } else {
879 if(dsr & 0x02) /* DSR.IDSTE=1 */
880 mode |= VIDEO_SOUND_STEREO;
881 if(dsr & 0x04) /* DSR.IDDUA=1 */
882 mode |= VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
883 }
884
885 dprintk("tda9874a_getmode(): DSR=0x%X, NSR=0x%X, NECR=0x%X, return: %d.\n",
886 dsr, nsr, necr, mode);
887 return mode;
888}
889
890static void tda9874a_setmode(struct CHIPSTATE *chip, int mode)
891{
892 /* Disable/enable NICAM auto-muting (based on DSR.RSSF status bit). */
893 /* If auto-muting is disabled, we can hear a signal of degrading quality. */
894 if(tda9874a_mode) {
895 if(chip->shadow.bytes[MAXREGS-2] & 0x20) /* DSR.RSSF=1 */
896 tda9874a_NCONR &= 0xfe; /* enable */
897 else
898 tda9874a_NCONR |= 0x01; /* disable */
899 chip_write(chip, TDA9874A_NCONR, tda9874a_NCONR);
900 }
901
902 /* Note: TDA9874A supports automatic FM dematrixing (FMMR register)
903 * and has auto-select function for audio output (AOSR register).
904 * Old TDA9874H doesn't support these features.
905 * TDA9874A also has additional mono output pin (OUTM), which
906 * on same (all?) tv-cards is not used, anyway (as well as MONOIN).
907 */
908 if(tda9874a_dic == 0x11) {
909 int aosr = 0x80;
910 int mdacosr = (tda9874a_mode) ? 0x82:0x80;
911
912 switch(mode) {
913 case VIDEO_SOUND_MONO:
914 case VIDEO_SOUND_STEREO:
915 break;
916 case VIDEO_SOUND_LANG1:
917 aosr = 0x80; /* auto-select, dual A/A */
918 mdacosr = (tda9874a_mode) ? 0x82:0x80;
919 break;
920 case VIDEO_SOUND_LANG2:
921 aosr = 0xa0; /* auto-select, dual B/B */
922 mdacosr = (tda9874a_mode) ? 0x83:0x81;
923 break;
924 default:
925 chip->mode = 0;
926 return;
927 }
928 chip_write(chip, TDA9874A_AOSR, aosr);
929 chip_write(chip, TDA9874A_MDACOSR, mdacosr);
930
931 dprintk("tda9874a_setmode(): req. mode %d; AOSR=0x%X, MDACOSR=0x%X.\n",
932 mode, aosr, mdacosr);
933
934 } else { /* dic == 0x07 */
935 int fmmr,aosr;
936
937 switch(mode) {
938 case VIDEO_SOUND_MONO:
939 fmmr = 0x00; /* mono */
940 aosr = 0x10; /* A/A */
941 break;
942 case VIDEO_SOUND_STEREO:
943 if(tda9874a_mode) {
944 fmmr = 0x00;
945 aosr = 0x00; /* handled by NICAM auto-mute */
946 } else {
947 fmmr = (tda9874a_ESP == 1) ? 0x05 : 0x04; /* stereo */
948 aosr = 0x00;
949 }
950 break;
951 case VIDEO_SOUND_LANG1:
952 fmmr = 0x02; /* dual */
953 aosr = 0x10; /* dual A/A */
954 break;
955 case VIDEO_SOUND_LANG2:
956 fmmr = 0x02; /* dual */
957 aosr = 0x20; /* dual B/B */
958 break;
959 default:
960 chip->mode = 0;
961 return;
962 }
963 chip_write(chip, TDA9874A_FMMR, fmmr);
964 chip_write(chip, TDA9874A_AOSR, aosr);
965
966 dprintk("tda9874a_setmode(): req. mode %d; FMMR=0x%X, AOSR=0x%X.\n",
967 mode, fmmr, aosr);
968 }
969}
970
971static int tda9874a_checkit(struct CHIPSTATE *chip)
972{
973 int dic,sic; /* device id. and software id. codes */
974
975 if(-1 == (dic = chip_read2(chip,TDA9874A_DIC)))
976 return 0;
977 if(-1 == (sic = chip_read2(chip,TDA9874A_SIC)))
978 return 0;
979
980 dprintk("tda9874a_checkit(): DIC=0x%X, SIC=0x%X.\n", dic, sic);
981
982 if((dic == 0x11)||(dic == 0x07)) {
983 printk("tvaudio: found tda9874%s.\n", (dic == 0x11) ? "a":"h");
984 tda9874a_dic = dic; /* remember device id. */
985 return 1;
986 }
987 return 0; /* not found */
988}
989
990static int tda9874a_initialize(struct CHIPSTATE *chip)
991{
992 if (tda9874a_SIF > 2)
993 tda9874a_SIF = 1;
994 if (tda9874a_STD >= 8)
995 tda9874a_STD = 0;
996 if(tda9874a_AMSEL > 1)
997 tda9874a_AMSEL = 0;
998
999 if(tda9874a_SIF == 1)
1000 tda9874a_GCONR = 0xc0; /* sound IF input 1 */
1001 else
1002 tda9874a_GCONR = 0xc1; /* sound IF input 2 */
1003
1004 tda9874a_ESP = tda9874a_STD;
1005 tda9874a_mode = (tda9874a_STD < 5) ? 0 : 1;
1006
1007 if(tda9874a_AMSEL == 0)
1008 tda9874a_NCONR = 0x01; /* auto-mute: analog mono input */
1009 else
1010 tda9874a_NCONR = 0x05; /* auto-mute: 1st carrier FM or AM */
1011
1012 tda9874a_setup(chip);
1013 return 0;
1014}
1015
1016
1017/* ---------------------------------------------------------------------- */
1018/* audio chip descriptions - defines+functions for tea6420 */
1019
1020#define TEA6300_VL 0x00 /* volume left */
1021#define TEA6300_VR 0x01 /* volume right */
1022#define TEA6300_BA 0x02 /* bass */
1023#define TEA6300_TR 0x03 /* treble */
1024#define TEA6300_FA 0x04 /* fader control */
1025#define TEA6300_S 0x05 /* switch register */
1026 /* values for those registers: */
1027#define TEA6300_S_SA 0x01 /* stereo A input */
1028#define TEA6300_S_SB 0x02 /* stereo B */
1029#define TEA6300_S_SC 0x04 /* stereo C */
1030#define TEA6300_S_GMU 0x80 /* general mute */
1031
1032#define TEA6320_V 0x00 /* volume (0-5)/loudness off (6)/zero crossing mute(7) */
1033#define TEA6320_FFR 0x01 /* fader front right (0-5) */
1034#define TEA6320_FFL 0x02 /* fader front left (0-5) */
1035#define TEA6320_FRR 0x03 /* fader rear right (0-5) */
1036#define TEA6320_FRL 0x04 /* fader rear left (0-5) */
1037#define TEA6320_BA 0x05 /* bass (0-4) */
1038#define TEA6320_TR 0x06 /* treble (0-4) */
1039#define TEA6320_S 0x07 /* switch register */
1040 /* values for those registers: */
1041#define TEA6320_S_SA 0x07 /* stereo A input */
1042#define TEA6320_S_SB 0x06 /* stereo B */
1043#define TEA6320_S_SC 0x05 /* stereo C */
1044#define TEA6320_S_SD 0x04 /* stereo D */
1045#define TEA6320_S_GMU 0x80 /* general mute */
1046
1047#define TEA6420_S_SA 0x00 /* stereo A input */
1048#define TEA6420_S_SB 0x01 /* stereo B */
1049#define TEA6420_S_SC 0x02 /* stereo C */
1050#define TEA6420_S_SD 0x03 /* stereo D */
1051#define TEA6420_S_SE 0x04 /* stereo E */
1052#define TEA6420_S_GMU 0x05 /* general mute */
1053
1054static int tea6300_shift10(int val) { return val >> 10; }
1055static int tea6300_shift12(int val) { return val >> 12; }
1056
1057/* Assumes 16bit input (values 0x3f to 0x0c are unique, values less than */
1058/* 0x0c mirror those immediately higher) */
1059static int tea6320_volume(int val) { return (val / (65535/(63-12)) + 12) & 0x3f; }
1060static int tea6320_shift11(int val) { return val >> 11; }
1061static int tea6320_initialize(struct CHIPSTATE * chip)
1062{
1063 chip_write(chip, TEA6320_FFR, 0x3f);
1064 chip_write(chip, TEA6320_FFL, 0x3f);
1065 chip_write(chip, TEA6320_FRR, 0x3f);
1066 chip_write(chip, TEA6320_FRL, 0x3f);
1067
1068 return 0;
1069}
1070
1071
1072/* ---------------------------------------------------------------------- */
1073/* audio chip descriptions - defines+functions for tda8425 */
1074
1075#define TDA8425_VL 0x00 /* volume left */
1076#define TDA8425_VR 0x01 /* volume right */
1077#define TDA8425_BA 0x02 /* bass */
1078#define TDA8425_TR 0x03 /* treble */
1079#define TDA8425_S1 0x08 /* switch functions */
1080 /* values for those registers: */
1081#define TDA8425_S1_OFF 0xEE /* audio off (mute on) */
1082#define TDA8425_S1_CH1 0xCE /* audio channel 1 (mute off) - "linear stereo" mode */
1083#define TDA8425_S1_CH2 0xCF /* audio channel 2 (mute off) - "linear stereo" mode */
1084#define TDA8425_S1_MU 0x20 /* mute bit */
1085#define TDA8425_S1_STEREO 0x18 /* stereo bits */
1086#define TDA8425_S1_STEREO_SPATIAL 0x18 /* spatial stereo */
1087#define TDA8425_S1_STEREO_LINEAR 0x08 /* linear stereo */
1088#define TDA8425_S1_STEREO_PSEUDO 0x10 /* pseudo stereo */
1089#define TDA8425_S1_STEREO_MONO 0x00 /* forced mono */
1090#define TDA8425_S1_ML 0x06 /* language selector */
1091#define TDA8425_S1_ML_SOUND_A 0x02 /* sound a */
1092#define TDA8425_S1_ML_SOUND_B 0x04 /* sound b */
1093#define TDA8425_S1_ML_STEREO 0x06 /* stereo */
1094#define TDA8425_S1_IS 0x01 /* channel selector */
1095
1096
1097static int tda8425_shift10(int val) { return (val >> 10) | 0xc0; }
1098static int tda8425_shift12(int val) { return (val >> 12) | 0xf0; }
1099
1100static int tda8425_initialize(struct CHIPSTATE *chip)
1101{
1102 struct CHIPDESC *desc = chiplist + chip->type;
1103 int inputmap[8] = { /* tuner */ TDA8425_S1_CH2, /* radio */ TDA8425_S1_CH1,
1104 /* extern */ TDA8425_S1_CH1, /* intern */ TDA8425_S1_OFF,
1105 /* off */ TDA8425_S1_OFF, /* on */ TDA8425_S1_CH2};
1106
1107 if (chip->c.adapter->id == (I2C_ALGO_BIT | I2C_HW_B_RIVA)) {
1108 memcpy (desc->inputmap, inputmap, sizeof (inputmap));
1109 }
1110 return 0;
1111}
1112
1113static void tda8425_setmode(struct CHIPSTATE *chip, int mode)
1114{
1115 int s1 = chip->shadow.bytes[TDA8425_S1+1] & 0xe1;
1116
1117 if (mode & VIDEO_SOUND_LANG1) {
1118 s1 |= TDA8425_S1_ML_SOUND_A;
1119 s1 |= TDA8425_S1_STEREO_PSEUDO;
1120
1121 } else if (mode & VIDEO_SOUND_LANG2) {
1122 s1 |= TDA8425_S1_ML_SOUND_B;
1123 s1 |= TDA8425_S1_STEREO_PSEUDO;
1124
1125 } else {
1126 s1 |= TDA8425_S1_ML_STEREO;
1127
1128 if (mode & VIDEO_SOUND_MONO)
1129 s1 |= TDA8425_S1_STEREO_MONO;
1130 if (mode & VIDEO_SOUND_STEREO)
1131 s1 |= TDA8425_S1_STEREO_SPATIAL;
1132 }
1133 chip_write(chip,TDA8425_S1,s1);
1134}
1135
1136
1137/* ---------------------------------------------------------------------- */
1138/* audio chip descriptions - defines+functions for pic16c54 (PV951) */
1139
1140/* the registers of 16C54, I2C sub address. */
1141#define PIC16C54_REG_KEY_CODE 0x01 /* Not use. */
1142#define PIC16C54_REG_MISC 0x02
1143
1144/* bit definition of the RESET register, I2C data. */
1145#define PIC16C54_MISC_RESET_REMOTE_CTL 0x01 /* bit 0, Reset to receive the key */
1146 /* code of remote controller */
1147#define PIC16C54_MISC_MTS_MAIN 0x02 /* bit 1 */
1148#define PIC16C54_MISC_MTS_SAP 0x04 /* bit 2 */
1149#define PIC16C54_MISC_MTS_BOTH 0x08 /* bit 3 */
1150#define PIC16C54_MISC_SND_MUTE 0x10 /* bit 4, Mute Audio(Line-in and Tuner) */
1151#define PIC16C54_MISC_SND_NOTMUTE 0x20 /* bit 5 */
1152#define PIC16C54_MISC_SWITCH_TUNER 0x40 /* bit 6 , Switch to Line-in */
1153#define PIC16C54_MISC_SWITCH_LINE 0x80 /* bit 7 , Switch to Tuner */
1154
1155/* ---------------------------------------------------------------------- */
1156/* audio chip descriptions - defines+functions for TA8874Z */
1157
1158// write 1st byte
1159#define TA8874Z_LED_STE 0x80
1160#define TA8874Z_LED_BIL 0x40
1161#define TA8874Z_LED_EXT 0x20
1162#define TA8874Z_MONO_SET 0x10
1163#define TA8874Z_MUTE 0x08
1164#define TA8874Z_F_MONO 0x04
1165#define TA8874Z_MODE_SUB 0x02
1166#define TA8874Z_MODE_MAIN 0x01
1167
1168// write 2nd byte
1169//#define TA8874Z_TI 0x80 // test mode
1170#define TA8874Z_SEPARATION 0x3f
1171#define TA8874Z_SEPARATION_DEFAULT 0x10
1172
1173// read
1174#define TA8874Z_B1 0x80
1175#define TA8874Z_B0 0x40
1176#define TA8874Z_CHAG_FLAG 0x20
1177
1178// B1 B0
1179// mono L H
1180// stereo L L
1181// BIL H L
1182
1183static int ta8874z_getmode(struct CHIPSTATE *chip)
1184{
1185 int val, mode;
1186
1187 val = chip_read(chip);
1188 mode = VIDEO_SOUND_MONO;
1189 if (val & TA8874Z_B1){
1190 mode |= VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
1191 }else if (!(val & TA8874Z_B0)){
1192 mode |= VIDEO_SOUND_STEREO;
1193 }
1194 //dprintk ("ta8874z_getmode(): raw chip read: 0x%02x, return: 0x%02x\n", val, mode);
1195 return mode;
1196}
1197
1198static audiocmd ta8874z_stereo = { 2, {0, TA8874Z_SEPARATION_DEFAULT}};
1199static audiocmd ta8874z_mono = {2, { TA8874Z_MONO_SET, TA8874Z_SEPARATION_DEFAULT}};
1200static audiocmd ta8874z_main = {2, { 0, TA8874Z_SEPARATION_DEFAULT}};
1201static audiocmd ta8874z_sub = {2, { TA8874Z_MODE_SUB, TA8874Z_SEPARATION_DEFAULT}};
1202
1203static void ta8874z_setmode(struct CHIPSTATE *chip, int mode)
1204{
1205 int update = 1;
1206 audiocmd *t = NULL;
1207 dprintk("ta8874z_setmode(): mode: 0x%02x\n", mode);
1208
1209 switch(mode){
1210 case VIDEO_SOUND_MONO:
1211 t = &ta8874z_mono;
1212 break;
1213 case VIDEO_SOUND_STEREO:
1214 t = &ta8874z_stereo;
1215 break;
1216 case VIDEO_SOUND_LANG1:
1217 t = &ta8874z_main;
1218 break;
1219 case VIDEO_SOUND_LANG2:
1220 t = &ta8874z_sub;
1221 break;
1222 default:
1223 update = 0;
1224 }
1225
1226 if(update)
1227 chip_cmd(chip, "TA8874Z", t);
1228}
1229
1230static int ta8874z_checkit(struct CHIPSTATE *chip)
1231{
1232 int rc;
1233 rc = chip_read(chip);
1234 return ((rc & 0x1f) == 0x1f) ? 1 : 0;
1235}
1236
1237/* ---------------------------------------------------------------------- */
1238/* audio chip descriptions - struct CHIPDESC */
1239
1240/* insmod options to enable/disable individual audio chips */
1241int tda8425 = 1;
1242int tda9840 = 1;
1243int tda9850 = 1;
1244int tda9855 = 1;
1245int tda9873 = 1;
1246int tda9874a = 1;
1247int tea6300 = 0; // address clash with msp34xx
1248int tea6320 = 0; // address clash with msp34xx
1249int tea6420 = 1;
1250int pic16c54 = 1;
1251int ta8874z = 0; // address clash with tda9840
1252
1253module_param(tda8425, int, 0444);
1254module_param(tda9840, int, 0444);
1255module_param(tda9850, int, 0444);
1256module_param(tda9855, int, 0444);
1257module_param(tda9873, int, 0444);
1258module_param(tda9874a, int, 0444);
1259module_param(tea6300, int, 0444);
1260module_param(tea6320, int, 0444);
1261module_param(tea6420, int, 0444);
1262module_param(pic16c54, int, 0444);
1263module_param(ta8874z, int, 0444);
1264
1265static struct CHIPDESC chiplist[] = {
1266 {
1267 .name = "tda9840",
1268 .id = I2C_DRIVERID_TDA9840,
1269 .insmodopt = &tda9840,
1270 .addr_lo = I2C_TDA9840 >> 1,
1271 .addr_hi = I2C_TDA9840 >> 1,
1272 .registers = 5,
1273
1274 .getmode = tda9840_getmode,
1275 .setmode = tda9840_setmode,
1276 .checkmode = generic_checkmode,
1277
1278 .init = { 2, { TDA9840_TEST, TDA9840_TEST_INT1SN
1279 /* ,TDA9840_SW, TDA9840_MONO */} }
1280 },
1281 {
1282 .name = "tda9873h",
1283 .id = I2C_DRIVERID_TDA9873,
1284 .checkit = tda9873_checkit,
1285 .insmodopt = &tda9873,
1286 .addr_lo = I2C_TDA985x_L >> 1,
1287 .addr_hi = I2C_TDA985x_H >> 1,
1288 .registers = 3,
1289 .flags = CHIP_HAS_INPUTSEL,
1290
1291 .getmode = tda9873_getmode,
1292 .setmode = tda9873_setmode,
1293 .checkmode = generic_checkmode,
1294
1295 .init = { 4, { TDA9873_SW, 0xa4, 0x06, 0x03 } },
1296 .inputreg = TDA9873_SW,
1297 .inputmute = TDA9873_MUTE | TDA9873_AUTOMUTE,
1298 .inputmap = {0xa0, 0xa2, 0xa0, 0xa0, 0xc0},
1299 .inputmask = TDA9873_INP_MASK|TDA9873_MUTE|TDA9873_AUTOMUTE,
1300
1301 },
1302 {
1303 .name = "tda9874h/a",
1304 .id = I2C_DRIVERID_TDA9874,
1305 .checkit = tda9874a_checkit,
1306 .initialize = tda9874a_initialize,
1307 .insmodopt = &tda9874a,
1308 .addr_lo = I2C_TDA9874 >> 1,
1309 .addr_hi = I2C_TDA9874 >> 1,
1310
1311 .getmode = tda9874a_getmode,
1312 .setmode = tda9874a_setmode,
1313 .checkmode = generic_checkmode,
1314 },
1315 {
1316 .name = "tda9850",
1317 .id = I2C_DRIVERID_TDA9850,
1318 .insmodopt = &tda9850,
1319 .addr_lo = I2C_TDA985x_L >> 1,
1320 .addr_hi = I2C_TDA985x_H >> 1,
1321 .registers = 11,
1322
1323 .getmode = tda985x_getmode,
1324 .setmode = tda985x_setmode,
1325
1326 .init = { 8, { TDA9850_C4, 0x08, 0x08, TDA985x_STEREO, 0x07, 0x10, 0x10, 0x03 } }
1327 },
1328 {
1329 .name = "tda9855",
1330 .id = I2C_DRIVERID_TDA9855,
1331 .insmodopt = &tda9855,
1332 .addr_lo = I2C_TDA985x_L >> 1,
1333 .addr_hi = I2C_TDA985x_H >> 1,
1334 .registers = 11,
1335 .flags = CHIP_HAS_VOLUME | CHIP_HAS_BASSTREBLE,
1336
1337 .leftreg = TDA9855_VL,
1338 .rightreg = TDA9855_VR,
1339 .bassreg = TDA9855_BA,
1340 .treblereg = TDA9855_TR,
1341 .volfunc = tda9855_volume,
1342 .bassfunc = tda9855_bass,
1343 .treblefunc = tda9855_treble,
1344
1345 .getmode = tda985x_getmode,
1346 .setmode = tda985x_setmode,
1347
1348 .init = { 12, { 0, 0x6f, 0x6f, 0x0e, 0x07<<1, 0x8<<2,
1349 TDA9855_MUTE | TDA9855_AVL | TDA9855_LOUD | TDA9855_INT,
1350 TDA985x_STEREO | TDA9855_LINEAR | TDA9855_TZCM | TDA9855_VZCM,
1351 0x07, 0x10, 0x10, 0x03 }}
1352 },
1353 {
1354 .name = "tea6300",
1355 .id = I2C_DRIVERID_TEA6300,
1356 .insmodopt = &tea6300,
1357 .addr_lo = I2C_TEA6300 >> 1,
1358 .addr_hi = I2C_TEA6300 >> 1,
1359 .registers = 6,
1360 .flags = CHIP_HAS_VOLUME | CHIP_HAS_BASSTREBLE | CHIP_HAS_INPUTSEL,
1361
1362 .leftreg = TEA6300_VR,
1363 .rightreg = TEA6300_VL,
1364 .bassreg = TEA6300_BA,
1365 .treblereg = TEA6300_TR,
1366 .volfunc = tea6300_shift10,
1367 .bassfunc = tea6300_shift12,
1368 .treblefunc = tea6300_shift12,
1369
1370 .inputreg = TEA6300_S,
1371 .inputmap = { TEA6300_S_SA, TEA6300_S_SB, TEA6300_S_SC },
1372 .inputmute = TEA6300_S_GMU,
1373 },
1374 {
1375 .name = "tea6320",
1376 .id = I2C_DRIVERID_TEA6300,
1377 .initialize = tea6320_initialize,
1378 .insmodopt = &tea6320,
1379 .addr_lo = I2C_TEA6300 >> 1,
1380 .addr_hi = I2C_TEA6300 >> 1,
1381 .registers = 8,
1382 .flags = CHIP_HAS_VOLUME | CHIP_HAS_BASSTREBLE | CHIP_HAS_INPUTSEL,
1383
1384 .leftreg = TEA6320_V,
1385 .rightreg = TEA6320_V,
1386 .bassreg = TEA6320_BA,
1387 .treblereg = TEA6320_TR,
1388 .volfunc = tea6320_volume,
1389 .bassfunc = tea6320_shift11,
1390 .treblefunc = tea6320_shift11,
1391
1392 .inputreg = TEA6320_S,
1393 .inputmap = { TEA6320_S_SA, TEA6420_S_SB, TEA6300_S_SC, TEA6320_S_SD },
1394 .inputmute = TEA6300_S_GMU,
1395 },
1396 {
1397 .name = "tea6420",
1398 .id = I2C_DRIVERID_TEA6420,
1399 .insmodopt = &tea6420,
1400 .addr_lo = I2C_TEA6420 >> 1,
1401 .addr_hi = I2C_TEA6420 >> 1,
1402 .registers = 1,
1403 .flags = CHIP_HAS_INPUTSEL,
1404
1405 .inputreg = -1,
1406 .inputmap = { TEA6420_S_SA, TEA6420_S_SB, TEA6420_S_SC },
1407 .inputmute = TEA6300_S_GMU,
1408 },
1409 {
1410 .name = "tda8425",
1411 .id = I2C_DRIVERID_TDA8425,
1412 .insmodopt = &tda8425,
1413 .addr_lo = I2C_TDA8425 >> 1,
1414 .addr_hi = I2C_TDA8425 >> 1,
1415 .registers = 9,
1416 .flags = CHIP_HAS_VOLUME | CHIP_HAS_BASSTREBLE | CHIP_HAS_INPUTSEL,
1417
1418 .leftreg = TDA8425_VL,
1419 .rightreg = TDA8425_VR,
1420 .bassreg = TDA8425_BA,
1421 .treblereg = TDA8425_TR,
1422 .volfunc = tda8425_shift10,
1423 .bassfunc = tda8425_shift12,
1424 .treblefunc = tda8425_shift12,
1425
1426 .inputreg = TDA8425_S1,
1427 .inputmap = { TDA8425_S1_CH1, TDA8425_S1_CH1, TDA8425_S1_CH1 },
1428 .inputmute = TDA8425_S1_OFF,
1429
1430 .setmode = tda8425_setmode,
1431 .initialize = tda8425_initialize,
1432 },
1433 {
1434 .name = "pic16c54 (PV951)",
1435 .id = I2C_DRIVERID_PIC16C54_PV951,
1436 .insmodopt = &pic16c54,
1437 .addr_lo = I2C_PIC16C54 >> 1,
1438 .addr_hi = I2C_PIC16C54>> 1,
1439 .registers = 2,
1440 .flags = CHIP_HAS_INPUTSEL,
1441
1442 .inputreg = PIC16C54_REG_MISC,
1443 .inputmap = {PIC16C54_MISC_SND_NOTMUTE|PIC16C54_MISC_SWITCH_TUNER,
1444 PIC16C54_MISC_SND_NOTMUTE|PIC16C54_MISC_SWITCH_LINE,
1445 PIC16C54_MISC_SND_NOTMUTE|PIC16C54_MISC_SWITCH_LINE,
1446 PIC16C54_MISC_SND_MUTE,PIC16C54_MISC_SND_MUTE,
1447 PIC16C54_MISC_SND_NOTMUTE},
1448 .inputmute = PIC16C54_MISC_SND_MUTE,
1449 },
1450 {
1451 .name = "ta8874z",
1452 .id = -1,
1453 //.id = I2C_DRIVERID_TA8874Z,
1454 .checkit = ta8874z_checkit,
1455 .insmodopt = &ta8874z,
1456 .addr_lo = I2C_TDA9840 >> 1,
1457 .addr_hi = I2C_TDA9840 >> 1,
1458 .registers = 2,
1459
1460 .getmode = ta8874z_getmode,
1461 .setmode = ta8874z_setmode,
1462 .checkmode = generic_checkmode,
1463
1464 .init = {2, { TA8874Z_MONO_SET, TA8874Z_SEPARATION_DEFAULT}},
1465 },
1466 { .name = NULL } /* EOF */
1467};
1468
1469
1470/* ---------------------------------------------------------------------- */
1471/* i2c registration */
1472
1473static int chip_attach(struct i2c_adapter *adap, int addr, int kind)
1474{
1475 struct CHIPSTATE *chip;
1476 struct CHIPDESC *desc;
1477
1478 chip = kmalloc(sizeof(*chip),GFP_KERNEL);
1479 if (!chip)
1480 return -ENOMEM;
1481 memset(chip,0,sizeof(*chip));
1482 memcpy(&chip->c,&client_template,sizeof(struct i2c_client));
1483 chip->c.adapter = adap;
1484 chip->c.addr = addr;
1485 i2c_set_clientdata(&chip->c, chip);
1486
1487 /* find description for the chip */
1488 dprintk("tvaudio: chip found @ i2c-addr=0x%x\n", addr<<1);
1489 for (desc = chiplist; desc->name != NULL; desc++) {
1490 if (0 == *(desc->insmodopt))
1491 continue;
1492 if (addr < desc->addr_lo ||
1493 addr > desc->addr_hi)
1494 continue;
1495 if (desc->checkit && !desc->checkit(chip))
1496 continue;
1497 break;
1498 }
1499 if (desc->name == NULL) {
1500 dprintk("tvaudio: no matching chip description found\n");
1501 return -EIO;
1502 }
1503 printk("tvaudio: found %s @ 0x%x\n", desc->name, addr<<1);
1504 dprintk("tvaudio: matches:%s%s%s.\n",
1505 (desc->flags & CHIP_HAS_VOLUME) ? " volume" : "",
1506 (desc->flags & CHIP_HAS_BASSTREBLE) ? " bass/treble" : "",
1507 (desc->flags & CHIP_HAS_INPUTSEL) ? " audiomux" : "");
1508
1509 /* fill required data structures */
1510 strcpy(i2c_clientname(&chip->c),desc->name);
1511 chip->type = desc-chiplist;
1512 chip->shadow.count = desc->registers+1;
1513 chip->prevmode = -1;
1514 /* register */
1515 i2c_attach_client(&chip->c);
1516
1517 /* initialization */
1518 if (desc->initialize != NULL)
1519 desc->initialize(chip);
1520 else
1521 chip_cmd(chip,"init",&desc->init);
1522
1523 if (desc->flags & CHIP_HAS_VOLUME) {
1524 chip->left = desc->leftinit ? desc->leftinit : 65535;
1525 chip->right = desc->rightinit ? desc->rightinit : 65535;
1526 chip_write(chip,desc->leftreg,desc->volfunc(chip->left));
1527 chip_write(chip,desc->rightreg,desc->volfunc(chip->right));
1528 }
1529 if (desc->flags & CHIP_HAS_BASSTREBLE) {
1530 chip->treble = desc->trebleinit ? desc->trebleinit : 32768;
1531 chip->bass = desc->bassinit ? desc->bassinit : 32768;
1532 chip_write(chip,desc->bassreg,desc->bassfunc(chip->bass));
1533 chip_write(chip,desc->treblereg,desc->treblefunc(chip->treble));
1534 }
1535
1536 chip->tpid = -1;
1537 if (desc->checkmode) {
1538 /* start async thread */
1539 init_timer(&chip->wt);
1540 chip->wt.function = chip_thread_wake;
1541 chip->wt.data = (unsigned long)chip;
1542 init_waitqueue_head(&chip->wq);
1543 init_completion(&chip->texit);
1544 chip->tpid = kernel_thread(chip_thread,(void *)chip,0);
1545 if (chip->tpid < 0)
1546 printk(KERN_WARNING "%s: kernel_thread() failed\n",
1547 i2c_clientname(&chip->c));
1548 wake_up_interruptible(&chip->wq);
1549 }
1550 return 0;
1551}
1552
1553static int chip_probe(struct i2c_adapter *adap)
1554{
1555 /* don't attach on saa7146 based cards,
1556 because dedicated drivers are used */
1557 if ((adap->id & I2C_ALGO_SAA7146))
1558 return 0;
1559#ifdef I2C_CLASS_TV_ANALOG
1560 if (adap->class & I2C_CLASS_TV_ANALOG)
1561 return i2c_probe(adap, &addr_data, chip_attach);
1562#else
1563 switch (adap->id) {
1564 case I2C_ALGO_BIT | I2C_HW_B_BT848:
1565 case I2C_ALGO_BIT | I2C_HW_B_RIVA:
1566 case I2C_ALGO_SAA7134:
1567 return i2c_probe(adap, &addr_data, chip_attach);
1568 }
1569#endif
1570 return 0;
1571}
1572
1573static int chip_detach(struct i2c_client *client)
1574{
1575 struct CHIPSTATE *chip = i2c_get_clientdata(client);
1576
1577 del_timer_sync(&chip->wt);
1578 if (chip->tpid >= 0) {
1579 /* shutdown async thread */
1580 chip->done = 1;
1581 wake_up_interruptible(&chip->wq);
1582 wait_for_completion(&chip->texit);
1583 }
1584
1585 i2c_detach_client(&chip->c);
1586 kfree(chip);
1587 return 0;
1588}
1589
1590/* ---------------------------------------------------------------------- */
1591/* video4linux interface */
1592
1593static int chip_command(struct i2c_client *client,
1594 unsigned int cmd, void *arg)
1595{
1596 __u16 *sarg = arg;
1597 struct CHIPSTATE *chip = i2c_get_clientdata(client);
1598 struct CHIPDESC *desc = chiplist + chip->type;
1599
1600 dprintk("%s: chip_command 0x%x\n",i2c_clientname(&chip->c),cmd);
1601
1602 switch (cmd) {
1603 case AUDC_SET_INPUT:
1604 if (desc->flags & CHIP_HAS_INPUTSEL) {
1605 if (*sarg & 0x80)
1606 chip_write_masked(chip,desc->inputreg,desc->inputmute,desc->inputmask);
1607 else
1608 chip_write_masked(chip,desc->inputreg,desc->inputmap[*sarg],desc->inputmask);
1609 }
1610 break;
1611
1612 case AUDC_SET_RADIO:
1613 dprintk(KERN_DEBUG "tvaudio: AUDC_SET_RADIO\n");
1614 chip->norm = VIDEO_MODE_RADIO;
1615 chip->watch_stereo = 0;
1616 /* del_timer(&chip->wt); */
1617 break;
1618
1619 /* --- v4l ioctls --- */
1620 /* take care: bttv does userspace copying, we'll get a
1621 kernel pointer here... */
1622 case VIDIOCGAUDIO:
1623 {
1624 struct video_audio *va = arg;
1625
1626 if (desc->flags & CHIP_HAS_VOLUME) {
1627 va->flags |= VIDEO_AUDIO_VOLUME;
1628 va->volume = max(chip->left,chip->right);
1629 if (va->volume)
1630 va->balance = (32768*min(chip->left,chip->right))/
1631 va->volume;
1632 else
1633 va->balance = 32768;
1634 }
1635 if (desc->flags & CHIP_HAS_BASSTREBLE) {
1636 va->flags |= VIDEO_AUDIO_BASS | VIDEO_AUDIO_TREBLE;
1637 va->bass = chip->bass;
1638 va->treble = chip->treble;
1639 }
1640 if (chip->norm != VIDEO_MODE_RADIO) {
1641 if (desc->getmode)
1642 va->mode = desc->getmode(chip);
1643 else
1644 va->mode = VIDEO_SOUND_MONO;
1645 }
1646 break;
1647 }
1648
1649 case VIDIOCSAUDIO:
1650 {
1651 struct video_audio *va = arg;
1652
1653 if (desc->flags & CHIP_HAS_VOLUME) {
1654 chip->left = (min(65536 - va->balance,32768) *
1655 va->volume) / 32768;
1656 chip->right = (min(va->balance,(__u16)32768) *
1657 va->volume) / 32768;
1658 chip_write(chip,desc->leftreg,desc->volfunc(chip->left));
1659 chip_write(chip,desc->rightreg,desc->volfunc(chip->right));
1660 }
1661 if (desc->flags & CHIP_HAS_BASSTREBLE) {
1662 chip->bass = va->bass;
1663 chip->treble = va->treble;
1664 chip_write(chip,desc->bassreg,desc->bassfunc(chip->bass));
1665 chip_write(chip,desc->treblereg,desc->treblefunc(chip->treble));
1666 }
1667 if (desc->setmode && va->mode) {
1668 chip->watch_stereo = 0;
1669 /* del_timer(&chip->wt); */
1670 chip->mode = va->mode;
1671 desc->setmode(chip,va->mode);
1672 }
1673 break;
1674 }
1675 case VIDIOCSCHAN:
1676 {
1677 struct video_channel *vc = arg;
1678
1679 dprintk(KERN_DEBUG "tvaudio: VIDIOCSCHAN\n");
1680 chip->norm = vc->norm;
1681 break;
1682 }
1683 case VIDIOCSFREQ:
1684 {
1685 chip->mode = 0; /* automatic */
1686 if (desc->checkmode) {
1687 desc->setmode(chip,VIDEO_SOUND_MONO);
1688 if (chip->prevmode != VIDEO_SOUND_MONO)
1689 chip->prevmode = -1; /* reset previous mode */
1690 mod_timer(&chip->wt, jiffies+2*HZ);
1691 /* the thread will call checkmode() later */
1692 }
1693 }
1694 }
1695 return 0;
1696}
1697
1698
1699static struct i2c_driver driver = {
1700 .owner = THIS_MODULE,
1701 .name = "generic i2c audio driver",
1702 .id = I2C_DRIVERID_TVAUDIO,
1703 .flags = I2C_DF_NOTIFY,
1704 .attach_adapter = chip_probe,
1705 .detach_client = chip_detach,
1706 .command = chip_command,
1707};
1708
1709static struct i2c_client client_template =
1710{
1711 I2C_DEVNAME("(unset)"),
1712 .flags = I2C_CLIENT_ALLOW_USE,
1713 .driver = &driver,
1714};
1715
1716static int __init audiochip_init_module(void)
1717{
1718 struct CHIPDESC *desc;
1719 printk(KERN_INFO "tvaudio: TV audio decoder + audio/video mux driver\n");
1720 printk(KERN_INFO "tvaudio: known chips: ");
1721 for (desc = chiplist; desc->name != NULL; desc++)
1722 printk("%s%s", (desc == chiplist) ? "" : ",",desc->name);
1723 printk("\n");
1724
1725 return i2c_add_driver(&driver);
1726}
1727
1728static void __exit audiochip_cleanup_module(void)
1729{
1730 i2c_del_driver(&driver);
1731}
1732
1733module_init(audiochip_init_module);
1734module_exit(audiochip_cleanup_module);
1735
1736/*
1737 * Local variables:
1738 * c-basic-offset: 8
1739 * End:
1740 */
diff --git a/drivers/media/video/tvaudio.h b/drivers/media/video/tvaudio.h
new file mode 100644
index 00000000000..af7e116af9a
--- /dev/null
+++ b/drivers/media/video/tvaudio.h
@@ -0,0 +1,14 @@
1/*
2 * i2c bus addresses for the chips supported by tvaudio.c
3 */
4
5#define I2C_TDA8425 0x82
6#define I2C_TDA9840 0x84 /* also used by TA8874Z */
7#define I2C_TDA985x_L 0xb4 /* also used by 9873 */
8#define I2C_TDA985x_H 0xb6
9#define I2C_TDA9874 0xb0 /* also used by 9875 */
10
11#define I2C_TEA6300 0x80 /* also used by 6320 */
12#define I2C_TEA6420 0x98
13
14#define I2C_PIC16C54 0x96 /* PV951 */
diff --git a/drivers/media/video/tveeprom.c b/drivers/media/video/tveeprom.c
new file mode 100644
index 00000000000..e1443a0937e
--- /dev/null
+++ b/drivers/media/video/tveeprom.c
@@ -0,0 +1,587 @@
1/*
2 * tveeprom - eeprom decoder for tvcard configuration eeproms
3 *
4 * Data and decoding routines shamelessly borrowed from bttv-cards.c
5 * eeprom access routine shamelessly borrowed from bttv-if.c
6 * which are:
7
8 Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
9 & Marcus Metzler (mocm@thp.uni-koeln.de)
10 (c) 1999-2001 Gerd Knorr <kraxel@goldbach.in-berlin.de>
11
12 * Adjustments to fit a more general model and all bugs:
13
14 Copyright (C) 2003 John Klar <linpvr at projectplasma.com>
15
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 */
30
31
32#include <linux/module.h>
33#include <linux/moduleparam.h>
34#include <linux/errno.h>
35#include <linux/kernel.h>
36#include <linux/init.h>
37#include <linux/types.h>
38#include <linux/videodev.h>
39#include <linux/i2c.h>
40
41#include <media/tuner.h>
42#include <media/tveeprom.h>
43
44MODULE_DESCRIPTION("i2c Hauppauge eeprom decoder driver");
45MODULE_AUTHOR("John Klar");
46MODULE_LICENSE("GPL");
47
48static int debug = 0;
49module_param(debug, int, 0644);
50MODULE_PARM_DESC(debug, "Debug level (0-2)");
51
52#define STRM(array,i) (i < sizeof(array)/sizeof(char*) ? array[i] : "unknown")
53
54#define dprintk(num, args...) \
55 do { \
56 if (debug >= num) \
57 printk(KERN_INFO "tveeprom: " args); \
58 } while (0)
59
60#define TVEEPROM_KERN_ERR(args...) printk(KERN_ERR "tveeprom: " args);
61#define TVEEPROM_KERN_INFO(args...) printk(KERN_INFO "tveeprom: " args);
62
63/* ----------------------------------------------------------------------- */
64/* some hauppauge specific stuff */
65
66static struct HAUPPAUGE_TUNER_FMT
67{
68 int id;
69 char *name;
70}
71hauppauge_tuner_fmt[] =
72{
73 { 0x00000000, "unknown1" },
74 { 0x00000000, "unknown2" },
75 { 0x00000007, "PAL(B/G)" },
76 { 0x00001000, "NTSC(M)" },
77 { 0x00000010, "PAL(I)" },
78 { 0x00400000, "SECAM(L/L�)" },
79 { 0x00000e00, "PAL(D/K)" },
80 { 0x03000000, "ATSC Digital" },
81};
82
83/* This is the full list of possible tuners. Many thanks to Hauppauge for
84 supplying this information. Note that many tuners where only used for
85 testing and never made it to the outside world. So you will only see
86 a subset in actual produced cards. */
87static struct HAUPPAUGE_TUNER
88{
89 int id;
90 char *name;
91}
92hauppauge_tuner[] =
93{
94 /* 0-9 */
95 { TUNER_ABSENT, "None" },
96 { TUNER_ABSENT, "External" },
97 { TUNER_ABSENT, "Unspecified" },
98 { TUNER_PHILIPS_PAL, "Philips FI1216" },
99 { TUNER_PHILIPS_SECAM, "Philips FI1216MF" },
100 { TUNER_PHILIPS_NTSC, "Philips FI1236" },
101 { TUNER_PHILIPS_PAL_I, "Philips FI1246" },
102 { TUNER_PHILIPS_PAL_DK,"Philips FI1256" },
103 { TUNER_PHILIPS_PAL, "Philips FI1216 MK2" },
104 { TUNER_PHILIPS_SECAM, "Philips FI1216MF MK2" },
105 /* 10-19 */
106 { TUNER_PHILIPS_NTSC, "Philips FI1236 MK2" },
107 { TUNER_PHILIPS_PAL_I, "Philips FI1246 MK2" },
108 { TUNER_PHILIPS_PAL_DK,"Philips FI1256 MK2" },
109 { TUNER_TEMIC_NTSC, "Temic 4032FY5" },
110 { TUNER_TEMIC_PAL, "Temic 4002FH5" },
111 { TUNER_TEMIC_PAL_I, "Temic 4062FY5" },
112 { TUNER_PHILIPS_PAL, "Philips FR1216 MK2" },
113 { TUNER_PHILIPS_SECAM, "Philips FR1216MF MK2" },
114 { TUNER_PHILIPS_NTSC, "Philips FR1236 MK2" },
115 { TUNER_PHILIPS_PAL_I, "Philips FR1246 MK2" },
116 /* 20-29 */
117 { TUNER_PHILIPS_PAL_DK,"Philips FR1256 MK2" },
118 { TUNER_PHILIPS_PAL, "Philips FM1216" },
119 { TUNER_PHILIPS_SECAM, "Philips FM1216MF" },
120 { TUNER_PHILIPS_NTSC, "Philips FM1236" },
121 { TUNER_PHILIPS_PAL_I, "Philips FM1246" },
122 { TUNER_PHILIPS_PAL_DK,"Philips FM1256" },
123 { TUNER_TEMIC_4036FY5_NTSC, "Temic 4036FY5" },
124 { TUNER_ABSENT, "Samsung TCPN9082D" },
125 { TUNER_ABSENT, "Samsung TCPM9092P" },
126 { TUNER_TEMIC_4006FH5_PAL, "Temic 4006FH5" },
127 /* 30-39 */
128 { TUNER_ABSENT, "Samsung TCPN9085D" },
129 { TUNER_ABSENT, "Samsung TCPB9085P" },
130 { TUNER_ABSENT, "Samsung TCPL9091P" },
131 { TUNER_TEMIC_4039FR5_NTSC, "Temic 4039FR5" },
132 { TUNER_PHILIPS_FQ1216ME, "Philips FQ1216 ME" },
133 { TUNER_TEMIC_4066FY5_PAL_I, "Temic 4066FY5" },
134 { TUNER_PHILIPS_NTSC, "Philips TD1536" },
135 { TUNER_PHILIPS_NTSC, "Philips TD1536D" },
136 { TUNER_PHILIPS_NTSC, "Philips FMR1236" }, /* mono radio */
137 { TUNER_ABSENT, "Philips FI1256MP" },
138 /* 40-49 */
139 { TUNER_ABSENT, "Samsung TCPQ9091P" },
140 { TUNER_TEMIC_4006FN5_MULTI_PAL, "Temic 4006FN5" },
141 { TUNER_TEMIC_4009FR5_PAL, "Temic 4009FR5" },
142 { TUNER_TEMIC_4046FM5, "Temic 4046FM5" },
143 { TUNER_TEMIC_4009FN5_MULTI_PAL_FM, "Temic 4009FN5" },
144 { TUNER_ABSENT, "Philips TD1536D FH 44"},
145 { TUNER_LG_NTSC_FM, "LG TP18NSR01F"},
146 { TUNER_LG_PAL_FM, "LG TP18PSB01D"},
147 { TUNER_LG_PAL, "LG TP18PSB11D"},
148 { TUNER_LG_PAL_I_FM, "LG TAPC-I001D"},
149 /* 50-59 */
150 { TUNER_LG_PAL_I, "LG TAPC-I701D"},
151 { TUNER_ABSENT, "Temic 4042FI5"},
152 { TUNER_MICROTUNE_4049FM5, "Microtune 4049 FM5"},
153 { TUNER_ABSENT, "LG TPI8NSR11F"},
154 { TUNER_ABSENT, "Microtune 4049 FM5 Alt I2C"},
155 { TUNER_ABSENT, "Philips FQ1216ME MK3"},
156 { TUNER_ABSENT, "Philips FI1236 MK3"},
157 { TUNER_PHILIPS_FM1216ME_MK3, "Philips FM1216 ME MK3"},
158 { TUNER_ABSENT, "Philips FM1236 MK3"},
159 { TUNER_ABSENT, "Philips FM1216MP MK3"},
160 /* 60-69 */
161 { TUNER_ABSENT, "LG S001D MK3"},
162 { TUNER_ABSENT, "LG M001D MK3"},
163 { TUNER_ABSENT, "LG S701D MK3"},
164 { TUNER_ABSENT, "LG M701D MK3"},
165 { TUNER_ABSENT, "Temic 4146FM5"},
166 { TUNER_ABSENT, "Temic 4136FY5"},
167 { TUNER_ABSENT, "Temic 4106FH5"},
168 { TUNER_ABSENT, "Philips FQ1216LMP MK3"},
169 { TUNER_LG_NTSC_TAPE, "LG TAPE H001F MK3"},
170 { TUNER_ABSENT, "LG TAPE H701F MK3"},
171 /* 70-79 */
172 { TUNER_ABSENT, "LG TALN H200T"},
173 { TUNER_ABSENT, "LG TALN H250T"},
174 { TUNER_ABSENT, "LG TALN M200T"},
175 { TUNER_ABSENT, "LG TALN Z200T"},
176 { TUNER_ABSENT, "LG TALN S200T"},
177 { TUNER_ABSENT, "Thompson DTT7595"},
178 { TUNER_ABSENT, "Thompson DTT7592"},
179 { TUNER_ABSENT, "Silicon TDA8275C1 8290"},
180 { TUNER_ABSENT, "Silicon TDA8275C1 8290 FM"},
181 { TUNER_ABSENT, "Thompson DTT757"},
182 /* 80-89 */
183 { TUNER_ABSENT, "Philips FQ1216LME MK3"},
184 { TUNER_ABSENT, "LG TAPC G701D"},
185 { TUNER_LG_NTSC_NEW_TAPC, "LG TAPC H791F"},
186 { TUNER_ABSENT, "TCL 2002MB 3"},
187 { TUNER_ABSENT, "TCL 2002MI 3"},
188 { TUNER_TCL_2002N, "TCL 2002N 6A"},
189 { TUNER_ABSENT, "Philips FQ1236 MK3"},
190 { TUNER_ABSENT, "Samsung TCPN 2121P30A"},
191 { TUNER_ABSENT, "Samsung TCPE 4121P30A"},
192 { TUNER_ABSENT, "TCL MFPE05 2"},
193 /* 90-99 */
194 { TUNER_ABSENT, "LG TALN H202T"},
195 { TUNER_PHILIPS_FQ1216AME_MK4, "Philips FQ1216AME MK4"},
196 { TUNER_PHILIPS_FQ1236A_MK4, "Philips FQ1236A MK4"},
197 { TUNER_ABSENT, "Philips FQ1286A MK4"},
198 { TUNER_ABSENT, "Philips FQ1216ME MK5"},
199 { TUNER_ABSENT, "Philips FQ1236 MK5"},
200 { TUNER_ABSENT, "Unspecified"},
201 { TUNER_LG_PAL_TAPE, "LG PAL (TAPE Series)"},
202};
203
204static char *sndtype[] = {
205 "None", "TEA6300", "TEA6320", "TDA9850", "MSP3400C", "MSP3410D",
206 "MSP3415", "MSP3430", "MSP3438", "CS5331", "MSP3435", "MSP3440",
207 "MSP3445", "MSP3411", "MSP3416", "MSP3425",
208
209 "Type 0x10","Type 0x11","Type 0x12","Type 0x13",
210 "Type 0x14","Type 0x15","Type 0x16","Type 0x17",
211 "Type 0x18","MSP4418","Type 0x1a","MSP4448",
212 "Type 0x1c","Type 0x1d","Type 0x1e","Type 0x1f",
213};
214
215static int hasRadioTuner(int tunerType)
216{
217 switch (tunerType) {
218 case 18: //PNPEnv_TUNER_FR1236_MK2:
219 case 23: //PNPEnv_TUNER_FM1236:
220 case 38: //PNPEnv_TUNER_FMR1236:
221 case 16: //PNPEnv_TUNER_FR1216_MK2:
222 case 19: //PNPEnv_TUNER_FR1246_MK2:
223 case 21: //PNPEnv_TUNER_FM1216:
224 case 24: //PNPEnv_TUNER_FM1246:
225 case 17: //PNPEnv_TUNER_FR1216MF_MK2:
226 case 22: //PNPEnv_TUNER_FM1216MF:
227 case 20: //PNPEnv_TUNER_FR1256_MK2:
228 case 25: //PNPEnv_TUNER_FM1256:
229 case 33: //PNPEnv_TUNER_4039FR5:
230 case 42: //PNPEnv_TUNER_4009FR5:
231 case 52: //PNPEnv_TUNER_4049FM5:
232 case 54: //PNPEnv_TUNER_4049FM5_AltI2C:
233 case 44: //PNPEnv_TUNER_4009FN5:
234 case 31: //PNPEnv_TUNER_TCPB9085P:
235 case 30: //PNPEnv_TUNER_TCPN9085D:
236 case 46: //PNPEnv_TUNER_TP18NSR01F:
237 case 47: //PNPEnv_TUNER_TP18PSB01D:
238 case 49: //PNPEnv_TUNER_TAPC_I001D:
239 case 60: //PNPEnv_TUNER_TAPE_S001D_MK3:
240 case 57: //PNPEnv_TUNER_FM1216ME_MK3:
241 case 59: //PNPEnv_TUNER_FM1216MP_MK3:
242 case 58: //PNPEnv_TUNER_FM1236_MK3:
243 case 68: //PNPEnv_TUNER_TAPE_H001F_MK3:
244 case 61: //PNPEnv_TUNER_TAPE_M001D_MK3:
245 case 78: //PNPEnv_TUNER_TDA8275C1_8290_FM:
246 case 89: //PNPEnv_TUNER_TCL_MFPE05_2:
247 case 92: //PNPEnv_TUNER_PHILIPS_FQ1236A_MK4:
248 return 1;
249 }
250 return 0;
251}
252
253void tveeprom_hauppauge_analog(struct tveeprom *tvee, unsigned char *eeprom_data)
254{
255 /* ----------------------------------------------
256 ** The hauppauge eeprom format is tagged
257 **
258 ** if packet[0] == 0x84, then packet[0..1] == length
259 ** else length = packet[0] & 3f;
260 ** if packet[0] & f8 == f8, then EOD and packet[1] == checksum
261 **
262 ** In our (ivtv) case we're interested in the following:
263 ** tuner type: tag [00].05 or [0a].01 (index into hauppauge_tuner)
264 ** tuner fmts: tag [00].04 or [0a].00 (bitmask index into hauppauge_tuner_fmt)
265 ** radio: tag [00].{last} or [0e].00 (bitmask. bit2=FM)
266 ** audio proc: tag [02].01 or [05].00 (lower nibble indexes lut?)
267
268 ** Fun info:
269 ** model: tag [00].07-08 or [06].00-01
270 ** revision: tag [00].09-0b or [06].04-06
271 ** serial#: tag [01].05-07 or [04].04-06
272
273 ** # of inputs/outputs ???
274 */
275
276 int i, j, len, done, beenhere, tag, tuner = 0, t_format = 0;
277 char *t_name = NULL, *t_fmt_name = NULL;
278
279 dprintk(1, "%s\n",__FUNCTION__);
280 tvee->revision = done = len = beenhere = 0;
281 for (i = 0; !done && i < 256; i += len) {
282 dprintk(2, "processing pos = %02x (%02x, %02x)\n",
283 i, eeprom_data[i], eeprom_data[i + 1]);
284
285 if (eeprom_data[i] == 0x84) {
286 len = eeprom_data[i + 1] + (eeprom_data[i + 2] << 8);
287 i+=3;
288 } else if ((eeprom_data[i] & 0xf0) == 0x70) {
289 if ((eeprom_data[i] & 0x08)) {
290 /* verify checksum! */
291 done = 1;
292 break;
293 }
294 len = eeprom_data[i] & 0x07;
295 ++i;
296 } else {
297 TVEEPROM_KERN_ERR("Encountered bad packet header [%02x]. "
298 "Corrupt or not a Hauppauge eeprom.\n", eeprom_data[i]);
299 return;
300 }
301
302 dprintk(1, "%3d [%02x] ", len, eeprom_data[i]);
303 for(j = 1; j < len; j++) {
304 dprintk(1, "%02x ", eeprom_data[i + j]);
305 }
306 dprintk(1, "\n");
307
308 /* process by tag */
309 tag = eeprom_data[i];
310 switch (tag) {
311 case 0x00:
312 tuner = eeprom_data[i+6];
313 t_format = eeprom_data[i+5];
314 tvee->has_radio = eeprom_data[i+len-1];
315 tvee->model =
316 eeprom_data[i+8] +
317 (eeprom_data[i+9] << 8);
318 tvee->revision = eeprom_data[i+10] +
319 (eeprom_data[i+11] << 8) +
320 (eeprom_data[i+12] << 16);
321 break;
322 case 0x01:
323 tvee->serial_number =
324 eeprom_data[i+6] +
325 (eeprom_data[i+7] << 8) +
326 (eeprom_data[i+8] << 16);
327 break;
328 case 0x02:
329 tvee->audio_processor = eeprom_data[i+2] & 0x0f;
330 break;
331 case 0x04:
332 tvee->serial_number =
333 eeprom_data[i+5] +
334 (eeprom_data[i+6] << 8) +
335 (eeprom_data[i+7] << 16);
336 break;
337 case 0x05:
338 tvee->audio_processor = eeprom_data[i+1] & 0x0f;
339 break;
340 case 0x06:
341 tvee->model =
342 eeprom_data[i+1] +
343 (eeprom_data[i+2] << 8);
344 tvee->revision = eeprom_data[i+5] +
345 (eeprom_data[i+6] << 8) +
346 (eeprom_data[i+7] << 16);
347 break;
348 case 0x0a:
349 if(beenhere == 0) {
350 tuner = eeprom_data[i+2];
351 t_format = eeprom_data[i+1];
352 beenhere = 1;
353 break;
354 } else {
355 break;
356 }
357 case 0x0e:
358 tvee->has_radio = eeprom_data[i+1];
359 break;
360 default:
361 dprintk(1, "Not sure what to do with tag [%02x]\n", tag);
362 /* dump the rest of the packet? */
363 }
364
365 }
366
367 if (!done) {
368 TVEEPROM_KERN_ERR("Ran out of data!\n");
369 return;
370 }
371
372 if (tvee->revision != 0) {
373 tvee->rev_str[0] = 32 + ((tvee->revision >> 18) & 0x3f);
374 tvee->rev_str[1] = 32 + ((tvee->revision >> 12) & 0x3f);
375 tvee->rev_str[2] = 32 + ((tvee->revision >> 6) & 0x3f);
376 tvee->rev_str[3] = 32 + ( tvee->revision & 0x3f);
377 tvee->rev_str[4] = 0;
378 }
379
380 if (hasRadioTuner(tuner) && !tvee->has_radio) {
381 TVEEPROM_KERN_INFO("The eeprom says no radio is present, but the tuner type\n");
382 TVEEPROM_KERN_INFO("indicates otherwise. I will assume that radio is present.\n");
383 tvee->has_radio = 1;
384 }
385
386 if (tuner < sizeof(hauppauge_tuner)/sizeof(struct HAUPPAUGE_TUNER)) {
387 tvee->tuner_type = hauppauge_tuner[tuner].id;
388 t_name = hauppauge_tuner[tuner].name;
389 } else {
390 t_name = "<unknown>";
391 }
392
393 tvee->tuner_formats = 0;
394 t_fmt_name = "<none>";
395 for (i = 0; i < 8; i++) {
396 if (t_format & (1<<i)) {
397 tvee->tuner_formats |= hauppauge_tuner_fmt[i].id;
398 /* yuck */
399 t_fmt_name = hauppauge_tuner_fmt[i].name;
400 }
401 }
402
403#if 0
404 if (t_format < sizeof(hauppauge_tuner_fmt)/sizeof(struct HAUPPAUGE_TUNER_FMT)) {
405 tvee->tuner_formats = hauppauge_tuner_fmt[t_format].id;
406 t_fmt_name = hauppauge_tuner_fmt[t_format].name;
407 } else {
408 t_fmt_name = "<unknown>";
409 }
410#endif
411
412 TVEEPROM_KERN_INFO("Hauppauge: model = %d, rev = %s, serial# = %d\n",
413 tvee->model,
414 tvee->rev_str,
415 tvee->serial_number);
416 TVEEPROM_KERN_INFO("tuner = %s (idx = %d, type = %d)\n",
417 t_name,
418 tuner,
419 tvee->tuner_type);
420 TVEEPROM_KERN_INFO("tuner fmt = %s (eeprom = 0x%02x, v4l2 = 0x%08x)\n",
421 t_fmt_name,
422 t_format,
423 tvee->tuner_formats);
424
425 TVEEPROM_KERN_INFO("audio_processor = %s (type = %d)\n",
426 STRM(sndtype,tvee->audio_processor),
427 tvee->audio_processor);
428
429}
430EXPORT_SYMBOL(tveeprom_hauppauge_analog);
431
432/* ----------------------------------------------------------------------- */
433/* generic helper functions */
434
435int tveeprom_read(struct i2c_client *c, unsigned char *eedata, int len)
436{
437 unsigned char buf;
438 int err;
439
440 dprintk(1, "%s\n",__FUNCTION__);
441 buf = 0;
442 if (1 != (err = i2c_master_send(c,&buf,1))) {
443 printk(KERN_INFO "tveeprom(%s): Huh, no eeprom present (err=%d)?\n",
444 c->name,err);
445 return -1;
446 }
447 if (len != (err = i2c_master_recv(c,eedata,len))) {
448 printk(KERN_WARNING "tveeprom(%s): i2c eeprom read error (err=%d)\n",
449 c->name,err);
450 return -1;
451 }
452 return 0;
453}
454EXPORT_SYMBOL(tveeprom_read);
455
456int tveeprom_dump(unsigned char *eedata, int len)
457{
458 int i;
459
460 dprintk(1, "%s\n",__FUNCTION__);
461 for (i = 0; i < len; i++) {
462 if (0 == (i % 16))
463 printk(KERN_INFO "tveeprom: %02x:",i);
464 printk(" %02x",eedata[i]);
465 if (15 == (i % 16))
466 printk("\n");
467 }
468 return 0;
469}
470EXPORT_SYMBOL(tveeprom_dump);
471
472/* ----------------------------------------------------------------------- */
473/* needed for ivtv.sf.net at the moment. Should go away in the long */
474/* run, just call the exported tveeprom_* directly, there is no point in */
475/* using the indirect way via i2c_driver->command() */
476
477#ifndef I2C_DRIVERID_TVEEPROM
478# define I2C_DRIVERID_TVEEPROM I2C_DRIVERID_EXP2
479#endif
480
481static unsigned short normal_i2c[] = {
482 0xa0 >> 1,
483 I2C_CLIENT_END,
484};
485static unsigned short normal_i2c_range[] = { I2C_CLIENT_END };
486I2C_CLIENT_INSMOD;
487
488struct i2c_driver i2c_driver_tveeprom;
489
490static int
491tveeprom_command(struct i2c_client *client,
492 unsigned int cmd,
493 void *arg)
494{
495 struct tveeprom eeprom;
496 u32 *eeprom_props = arg;
497 u8 *buf;
498
499 switch (cmd) {
500 case 0:
501 buf = kmalloc(256,GFP_KERNEL);
502 memset(buf,0,256);
503 tveeprom_read(client,buf,256);
504 tveeprom_hauppauge_analog(&eeprom,buf);
505 kfree(buf);
506 eeprom_props[0] = eeprom.tuner_type;
507 eeprom_props[1] = eeprom.tuner_formats;
508 eeprom_props[2] = eeprom.model;
509 eeprom_props[3] = eeprom.revision;
510 break;
511 default:
512 return -EINVAL;
513 }
514 return 0;
515}
516
517static int
518tveeprom_detect_client(struct i2c_adapter *adapter,
519 int address,
520 int kind)
521{
522 struct i2c_client *client;
523
524 dprintk(1,"%s: id 0x%x @ 0x%x\n",__FUNCTION__,
525 adapter->id, address << 1);
526 client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
527 if (NULL == client)
528 return -ENOMEM;
529 memset(client, 0, sizeof(struct i2c_client));
530 client->addr = address;
531 client->adapter = adapter;
532 client->driver = &i2c_driver_tveeprom;
533 client->flags = I2C_CLIENT_ALLOW_USE;
534 snprintf(client->name, sizeof(client->name), "tveeprom");
535 i2c_attach_client(client);
536 return 0;
537}
538
539static int
540tveeprom_attach_adapter (struct i2c_adapter *adapter)
541{
542 dprintk(1,"%s: id 0x%x\n",__FUNCTION__,adapter->id);
543 if (adapter->id != (I2C_ALGO_BIT | I2C_HW_B_BT848))
544 return 0;
545 return i2c_probe(adapter, &addr_data, tveeprom_detect_client);
546}
547
548static int
549tveeprom_detach_client (struct i2c_client *client)
550{
551 int err;
552
553 err = i2c_detach_client(client);
554 if (err < 0)
555 return err;
556 kfree(client);
557 return 0;
558}
559
560struct i2c_driver i2c_driver_tveeprom = {
561 .owner = THIS_MODULE,
562 .name = "tveeprom",
563 .id = I2C_DRIVERID_TVEEPROM,
564 .flags = I2C_DF_NOTIFY,
565 .attach_adapter = tveeprom_attach_adapter,
566 .detach_client = tveeprom_detach_client,
567 .command = tveeprom_command,
568};
569
570static int __init tveeprom_init(void)
571{
572 return i2c_add_driver(&i2c_driver_tveeprom);
573}
574
575static void __exit tveeprom_exit(void)
576{
577 i2c_del_driver(&i2c_driver_tveeprom);
578}
579
580module_init(tveeprom_init);
581module_exit(tveeprom_exit);
582
583/*
584 * Local variables:
585 * c-basic-offset: 8
586 * End:
587 */
diff --git a/drivers/media/video/tvmixer.c b/drivers/media/video/tvmixer.c
new file mode 100644
index 00000000000..eafd7061b31
--- /dev/null
+++ b/drivers/media/video/tvmixer.c
@@ -0,0 +1,367 @@
1#include <linux/module.h>
2#include <linux/moduleparam.h>
3#include <linux/kernel.h>
4#include <linux/sched.h>
5#include <linux/string.h>
6#include <linux/timer.h>
7#include <linux/delay.h>
8#include <linux/errno.h>
9#include <linux/slab.h>
10#include <linux/i2c.h>
11#include <linux/videodev.h>
12#include <linux/init.h>
13#include <linux/kdev_t.h>
14#include <linux/sound.h>
15#include <linux/soundcard.h>
16
17#include <asm/semaphore.h>
18#include <asm/uaccess.h>
19
20
21#define DEV_MAX 4
22
23static int devnr = -1;
24module_param(devnr, int, 0644);
25
26MODULE_AUTHOR("Gerd Knorr");
27MODULE_LICENSE("GPL");
28
29/* ----------------------------------------------------------------------- */
30
31struct TVMIXER {
32 struct i2c_client *dev;
33 int minor;
34 int count;
35};
36
37static struct TVMIXER devices[DEV_MAX];
38
39static int tvmixer_adapters(struct i2c_adapter *adap);
40static int tvmixer_clients(struct i2c_client *client);
41
42/* ----------------------------------------------------------------------- */
43
44static int mix_to_v4l(int i)
45{
46 int r;
47
48 r = ((i & 0xff) * 65536 + 50) / 100;
49 if (r > 65535) r = 65535;
50 if (r < 0) r = 0;
51 return r;
52}
53
54static int v4l_to_mix(int i)
55{
56 int r;
57
58 r = (i * 100 + 32768) / 65536;
59 if (r > 100) r = 100;
60 if (r < 0) r = 0;
61 return r | (r << 8);
62}
63
64static int v4l_to_mix2(int l, int r)
65{
66 r = (r * 100 + 32768) / 65536;
67 if (r > 100) r = 100;
68 if (r < 0) r = 0;
69 l = (l * 100 + 32768) / 65536;
70 if (l > 100) l = 100;
71 if (l < 0) l = 0;
72 return (r << 8) | l;
73}
74
75static int tvmixer_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
76{
77 struct video_audio va;
78 int left,right,ret,val = 0;
79 struct TVMIXER *mix = file->private_data;
80 struct i2c_client *client = mix->dev;
81 void __user *argp = (void __user *)arg;
82 int __user *p = argp;
83
84 if (NULL == client)
85 return -ENODEV;
86
87 if (cmd == SOUND_MIXER_INFO) {
88 mixer_info info;
89 strlcpy(info.id, "tv card", sizeof(info.id));
90 strlcpy(info.name, i2c_clientname(client), sizeof(info.name));
91 info.modify_counter = 42 /* FIXME */;
92 if (copy_to_user(argp, &info, sizeof(info)))
93 return -EFAULT;
94 return 0;
95 }
96 if (cmd == SOUND_OLD_MIXER_INFO) {
97 _old_mixer_info info;
98 strlcpy(info.id, "tv card", sizeof(info.id));
99 strlcpy(info.name, i2c_clientname(client), sizeof(info.name));
100 if (copy_to_user(argp, &info, sizeof(info)))
101 return -EFAULT;
102 return 0;
103 }
104 if (cmd == OSS_GETVERSION)
105 return put_user(SOUND_VERSION, p);
106
107 if (_SIOC_DIR(cmd) & _SIOC_WRITE)
108 if (get_user(val, p))
109 return -EFAULT;
110
111 /* read state */
112 memset(&va,0,sizeof(va));
113 client->driver->command(client,VIDIOCGAUDIO,&va);
114
115 switch (cmd) {
116 case MIXER_READ(SOUND_MIXER_RECMASK):
117 case MIXER_READ(SOUND_MIXER_CAPS):
118 case MIXER_READ(SOUND_MIXER_RECSRC):
119 case MIXER_WRITE(SOUND_MIXER_RECSRC):
120 ret = 0;
121 break;
122
123 case MIXER_READ(SOUND_MIXER_STEREODEVS):
124 ret = SOUND_MASK_VOLUME;
125 break;
126 case MIXER_READ(SOUND_MIXER_DEVMASK):
127 ret = SOUND_MASK_VOLUME;
128 if (va.flags & VIDEO_AUDIO_BASS)
129 ret |= SOUND_MASK_BASS;
130 if (va.flags & VIDEO_AUDIO_TREBLE)
131 ret |= SOUND_MASK_TREBLE;
132 break;
133
134 case MIXER_WRITE(SOUND_MIXER_VOLUME):
135 left = mix_to_v4l(val);
136 right = mix_to_v4l(val >> 8);
137 va.volume = max(left,right);
138 va.balance = (32768*min(left,right)) / (va.volume ? va.volume : 1);
139 va.balance = (left<right) ? (65535-va.balance) : va.balance;
140 if (va.volume)
141 va.flags &= ~VIDEO_AUDIO_MUTE;
142 client->driver->command(client,VIDIOCSAUDIO,&va);
143 client->driver->command(client,VIDIOCGAUDIO,&va);
144 /* fall throuth */
145 case MIXER_READ(SOUND_MIXER_VOLUME):
146 left = (min(65536 - va.balance,32768) *
147 va.volume) / 32768;
148 right = (min(va.balance,(u16)32768) *
149 va.volume) / 32768;
150 ret = v4l_to_mix2(left,right);
151 break;
152
153 case MIXER_WRITE(SOUND_MIXER_BASS):
154 va.bass = mix_to_v4l(val);
155 client->driver->command(client,VIDIOCSAUDIO,&va);
156 client->driver->command(client,VIDIOCGAUDIO,&va);
157 /* fall throuth */
158 case MIXER_READ(SOUND_MIXER_BASS):
159 ret = v4l_to_mix(va.bass);
160 break;
161
162 case MIXER_WRITE(SOUND_MIXER_TREBLE):
163 va.treble = mix_to_v4l(val);
164 client->driver->command(client,VIDIOCSAUDIO,&va);
165 client->driver->command(client,VIDIOCGAUDIO,&va);
166 /* fall throuth */
167 case MIXER_READ(SOUND_MIXER_TREBLE):
168 ret = v4l_to_mix(va.treble);
169 break;
170
171 default:
172 return -EINVAL;
173 }
174 if (put_user(ret, p))
175 return -EFAULT;
176 return 0;
177}
178
179static int tvmixer_open(struct inode *inode, struct file *file)
180{
181 int i, minor = iminor(inode);
182 struct TVMIXER *mix = NULL;
183 struct i2c_client *client = NULL;
184
185 for (i = 0; i < DEV_MAX; i++) {
186 if (devices[i].minor == minor) {
187 mix = devices+i;
188 client = mix->dev;
189 break;
190 }
191 }
192
193 if (NULL == client)
194 return -ENODEV;
195
196 /* lock bttv in memory while the mixer is in use */
197 file->private_data = mix;
198#ifndef I2C_PEC
199 if (client->adapter->inc_use)
200 client->adapter->inc_use(client->adapter);
201#endif
202 if (client->adapter->owner)
203 try_module_get(client->adapter->owner);
204 return 0;
205}
206
207static int tvmixer_release(struct inode *inode, struct file *file)
208{
209 struct TVMIXER *mix = file->private_data;
210 struct i2c_client *client;
211
212 client = mix->dev;
213 if (NULL == client) {
214 return -ENODEV;
215 }
216
217#ifndef I2C_PEC
218 if (client->adapter->dec_use)
219 client->adapter->dec_use(client->adapter);
220#endif
221 if (client->adapter->owner)
222 module_put(client->adapter->owner);
223 return 0;
224}
225
226static struct i2c_driver driver = {
227#ifdef I2C_PEC
228 .owner = THIS_MODULE,
229#endif
230 .name = "tv card mixer driver",
231 .id = I2C_DRIVERID_TVMIXER,
232#ifdef I2C_DF_DUMMY
233 .flags = I2C_DF_DUMMY,
234#else
235 .flags = I2C_DF_NOTIFY,
236 .detach_adapter = tvmixer_adapters,
237#endif
238 .attach_adapter = tvmixer_adapters,
239 .detach_client = tvmixer_clients,
240};
241
242static struct file_operations tvmixer_fops = {
243 .owner = THIS_MODULE,
244 .llseek = no_llseek,
245 .ioctl = tvmixer_ioctl,
246 .open = tvmixer_open,
247 .release = tvmixer_release,
248};
249
250/* ----------------------------------------------------------------------- */
251
252static int tvmixer_adapters(struct i2c_adapter *adap)
253{
254 struct list_head *item;
255 struct i2c_client *client;
256
257 list_for_each(item,&adap->clients) {
258 client = list_entry(item, struct i2c_client, list);
259 tvmixer_clients(client);
260 }
261 return 0;
262}
263
264static int tvmixer_clients(struct i2c_client *client)
265{
266 struct video_audio va;
267 int i,minor;
268
269#ifdef I2C_CLASS_TV_ANALOG
270 if (!(client->adapter->class & I2C_CLASS_TV_ANALOG))
271 return -1;
272#else
273 /* TV card ??? */
274 switch (client->adapter->id) {
275 case I2C_ALGO_BIT | I2C_HW_SMBUS_VOODOO3:
276 case I2C_ALGO_BIT | I2C_HW_B_BT848:
277 case I2C_ALGO_BIT | I2C_HW_B_RIVA:
278 /* ok, have a look ... */
279 break;
280 default:
281 /* ignore that one */
282 return -1;
283 }
284#endif
285
286 /* unregister ?? */
287 for (i = 0; i < DEV_MAX; i++) {
288 if (devices[i].dev == client) {
289 /* unregister */
290 unregister_sound_mixer(devices[i].minor);
291 devices[i].dev = NULL;
292 devices[i].minor = -1;
293 printk("tvmixer: %s unregistered (#1)\n",
294 i2c_clientname(client));
295 return 0;
296 }
297 }
298
299 /* look for a free slot */
300 for (i = 0; i < DEV_MAX; i++)
301 if (NULL == devices[i].dev)
302 break;
303 if (i == DEV_MAX) {
304 printk(KERN_WARNING "tvmixer: DEV_MAX too small\n");
305 return -1;
306 }
307
308 /* audio chip with mixer ??? */
309 if (NULL == client->driver->command)
310 return -1;
311 memset(&va,0,sizeof(va));
312 if (0 != client->driver->command(client,VIDIOCGAUDIO,&va))
313 return -1;
314 if (0 == (va.flags & VIDEO_AUDIO_VOLUME))
315 return -1;
316
317 /* everything is fine, register */
318 if ((minor = register_sound_mixer(&tvmixer_fops,devnr)) < 0) {
319 printk(KERN_ERR "tvmixer: cannot allocate mixer device\n");
320 return -1;
321 }
322
323 devices[i].minor = minor;
324 devices[i].count = 0;
325 devices[i].dev = client;
326 printk("tvmixer: %s (%s) registered with minor %d\n",
327 client->name,client->adapter->name,minor);
328
329 return 0;
330}
331
332/* ----------------------------------------------------------------------- */
333
334static int __init tvmixer_init_module(void)
335{
336 int i;
337
338 for (i = 0; i < DEV_MAX; i++)
339 devices[i].minor = -1;
340
341 return i2c_add_driver(&driver);
342}
343
344static void __exit tvmixer_cleanup_module(void)
345{
346 int i;
347
348 i2c_del_driver(&driver);
349 for (i = 0; i < DEV_MAX; i++) {
350 if (devices[i].minor != -1) {
351 unregister_sound_mixer(devices[i].minor);
352 printk("tvmixer: %s unregistered (#2)\n",
353 i2c_clientname(devices[i].dev));
354 }
355 }
356}
357
358module_init(tvmixer_init_module);
359module_exit(tvmixer_cleanup_module);
360
361/*
362 * Overrides for Emacs so that we follow Linus's tabbing style.
363 * ---------------------------------------------------------------------------
364 * Local variables:
365 * c-basic-offset: 8
366 * End:
367 */
diff --git a/drivers/media/video/v4l1-compat.c b/drivers/media/video/v4l1-compat.c
new file mode 100644
index 00000000000..b0d4bcb027d
--- /dev/null
+++ b/drivers/media/video/v4l1-compat.c
@@ -0,0 +1,1036 @@
1/*
2 * Video for Linux Two
3 * Backward Compatibility Layer
4 *
5 * Support subroutines for providing V4L2 drivers with backward
6 * compatibility with applications using the old API.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version
11 * 2 of the License, or (at your option) any later version.
12 *
13 * Author: Bill Dirks <bdirks@pacbell.net>
14 * et al.
15 *
16 */
17
18#ifndef __KERNEL__
19#define __KERNEL__
20#endif
21
22#include <linux/config.h>
23
24#include <linux/init.h>
25#include <linux/module.h>
26#include <linux/types.h>
27#include <linux/kernel.h>
28#include <linux/sched.h>
29#include <linux/smp_lock.h>
30#include <linux/mm.h>
31#include <linux/fs.h>
32#include <linux/file.h>
33#include <linux/string.h>
34#include <linux/errno.h>
35#include <linux/slab.h>
36#include <linux/videodev.h>
37
38#include <asm/uaccess.h>
39#include <asm/system.h>
40#include <asm/pgtable.h>
41
42#ifdef CONFIG_KMOD
43#include <linux/kmod.h>
44#endif
45
46static unsigned int debug = 0;
47module_param(debug, int, 0644);
48MODULE_PARM_DESC(debug,"enable debug messages");
49MODULE_AUTHOR("Bill Dirks");
50MODULE_DESCRIPTION("v4l(1) compatibility layer for v4l2 drivers.");
51MODULE_LICENSE("GPL");
52
53#define dprintk(fmt, arg...) if (debug) \
54 printk(KERN_DEBUG "v4l1-compat: " fmt , ## arg)
55
56/*
57 * I O C T L T R A N S L A T I O N
58 *
59 * From here on down is the code for translating the numerous
60 * ioctl commands from the old API to the new API.
61 */
62
63static int
64get_v4l_control(struct inode *inode,
65 struct file *file,
66 int cid,
67 v4l2_kioctl drv)
68{
69 struct v4l2_queryctrl qctrl2;
70 struct v4l2_control ctrl2;
71 int err;
72
73 qctrl2.id = cid;
74 err = drv(inode, file, VIDIOC_QUERYCTRL, &qctrl2);
75 if (err < 0)
76 dprintk("VIDIOC_QUERYCTRL: %d\n",err);
77 if (err == 0 &&
78 !(qctrl2.flags & V4L2_CTRL_FLAG_DISABLED))
79 {
80 ctrl2.id = qctrl2.id;
81 err = drv(inode, file, VIDIOC_G_CTRL, &ctrl2);
82 if (err < 0) {
83 dprintk("VIDIOC_G_CTRL: %d\n",err);
84 return 0;
85 }
86 return ((ctrl2.value - qctrl2.minimum) * 65535
87 + (qctrl2.maximum - qctrl2.minimum) / 2)
88 / (qctrl2.maximum - qctrl2.minimum);
89 }
90 return 0;
91}
92
93static int
94set_v4l_control(struct inode *inode,
95 struct file *file,
96 int cid,
97 int value,
98 v4l2_kioctl drv)
99{
100 struct v4l2_queryctrl qctrl2;
101 struct v4l2_control ctrl2;
102 int err;
103
104 qctrl2.id = cid;
105 err = drv(inode, file, VIDIOC_QUERYCTRL, &qctrl2);
106 if (err < 0)
107 dprintk("VIDIOC_QUERYCTRL: %d\n",err);
108 if (err == 0 &&
109 !(qctrl2.flags & V4L2_CTRL_FLAG_DISABLED) &&
110 !(qctrl2.flags & V4L2_CTRL_FLAG_GRABBED))
111 {
112 if (value < 0)
113 value = 0;
114 if (value > 65535)
115 value = 65535;
116 if (value && qctrl2.type == V4L2_CTRL_TYPE_BOOLEAN)
117 value = 65535;
118 ctrl2.id = qctrl2.id;
119 ctrl2.value =
120 (value * (qctrl2.maximum - qctrl2.minimum)
121 + 32767)
122 / 65535;
123 ctrl2.value += qctrl2.minimum;
124 err = drv(inode, file, VIDIOC_S_CTRL, &ctrl2);
125 if (err < 0)
126 dprintk("VIDIOC_S_CTRL: %d\n",err);
127 }
128 return 0;
129}
130
131/* ----------------------------------------------------------------- */
132
133static int palette2pixelformat[] = {
134 [VIDEO_PALETTE_GREY] = V4L2_PIX_FMT_GREY,
135 [VIDEO_PALETTE_RGB555] = V4L2_PIX_FMT_RGB555,
136 [VIDEO_PALETTE_RGB565] = V4L2_PIX_FMT_RGB565,
137 [VIDEO_PALETTE_RGB24] = V4L2_PIX_FMT_BGR24,
138 [VIDEO_PALETTE_RGB32] = V4L2_PIX_FMT_BGR32,
139 /* yuv packed pixel */
140 [VIDEO_PALETTE_YUYV] = V4L2_PIX_FMT_YUYV,
141 [VIDEO_PALETTE_YUV422] = V4L2_PIX_FMT_YUYV,
142 [VIDEO_PALETTE_UYVY] = V4L2_PIX_FMT_UYVY,
143 /* yuv planar */
144 [VIDEO_PALETTE_YUV410P] = V4L2_PIX_FMT_YUV410,
145 [VIDEO_PALETTE_YUV420] = V4L2_PIX_FMT_YUV420,
146 [VIDEO_PALETTE_YUV420P] = V4L2_PIX_FMT_YUV420,
147 [VIDEO_PALETTE_YUV411P] = V4L2_PIX_FMT_YUV411P,
148 [VIDEO_PALETTE_YUV422P] = V4L2_PIX_FMT_YUV422P,
149};
150
151static unsigned int
152palette_to_pixelformat(unsigned int palette)
153{
154 if (palette < ARRAY_SIZE(palette2pixelformat))
155 return palette2pixelformat[palette];
156 else
157 return 0;
158}
159
160static unsigned int
161pixelformat_to_palette(int pixelformat)
162{
163 int palette = 0;
164 switch (pixelformat)
165 {
166 case V4L2_PIX_FMT_GREY:
167 palette = VIDEO_PALETTE_GREY;
168 break;
169 case V4L2_PIX_FMT_RGB555:
170 palette = VIDEO_PALETTE_RGB555;
171 break;
172 case V4L2_PIX_FMT_RGB565:
173 palette = VIDEO_PALETTE_RGB565;
174 break;
175 case V4L2_PIX_FMT_BGR24:
176 palette = VIDEO_PALETTE_RGB24;
177 break;
178 case V4L2_PIX_FMT_BGR32:
179 palette = VIDEO_PALETTE_RGB32;
180 break;
181 /* yuv packed pixel */
182 case V4L2_PIX_FMT_YUYV:
183 palette = VIDEO_PALETTE_YUYV;
184 break;
185 case V4L2_PIX_FMT_UYVY:
186 palette = VIDEO_PALETTE_UYVY;
187 break;
188 /* yuv planar */
189 case V4L2_PIX_FMT_YUV410:
190 palette = VIDEO_PALETTE_YUV420;
191 break;
192 case V4L2_PIX_FMT_YUV420:
193 palette = VIDEO_PALETTE_YUV420;
194 break;
195 case V4L2_PIX_FMT_YUV411P:
196 palette = VIDEO_PALETTE_YUV411P;
197 break;
198 case V4L2_PIX_FMT_YUV422P:
199 palette = VIDEO_PALETTE_YUV422P;
200 break;
201 }
202 return palette;
203}
204
205/* ----------------------------------------------------------------- */
206
207static int poll_one(struct file *file)
208{
209 int retval = 1;
210 poll_table *table;
211 struct poll_wqueues pwq;
212
213 poll_initwait(&pwq);
214 table = &pwq.pt;
215 for (;;) {
216 int mask;
217 set_current_state(TASK_INTERRUPTIBLE);
218 mask = file->f_op->poll(file, table);
219 if (mask & POLLIN)
220 break;
221 table = NULL;
222 if (signal_pending(current)) {
223 retval = -ERESTARTSYS;
224 break;
225 }
226 schedule();
227 }
228 set_current_state(TASK_RUNNING);
229 poll_freewait(&pwq);
230 return retval;
231}
232
233static int count_inputs(struct inode *inode,
234 struct file *file,
235 v4l2_kioctl drv)
236{
237 struct v4l2_input input2;
238 int i;
239
240 for (i = 0;; i++) {
241 memset(&input2,0,sizeof(input2));
242 input2.index = i;
243 if (0 != drv(inode,file,VIDIOC_ENUMINPUT, &input2))
244 break;
245 }
246 return i;
247}
248
249static int check_size(struct inode *inode,
250 struct file *file,
251 v4l2_kioctl drv,
252 int *maxw, int *maxh)
253{
254 struct v4l2_fmtdesc desc2;
255 struct v4l2_format fmt2;
256
257 memset(&desc2,0,sizeof(desc2));
258 memset(&fmt2,0,sizeof(fmt2));
259
260 desc2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
261 if (0 != drv(inode,file,VIDIOC_ENUM_FMT, &desc2))
262 goto done;
263
264 fmt2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
265 fmt2.fmt.pix.width = 10000;
266 fmt2.fmt.pix.height = 10000;
267 fmt2.fmt.pix.pixelformat = desc2.pixelformat;
268 if (0 != drv(inode,file,VIDIOC_TRY_FMT, &fmt2))
269 goto done;
270
271 *maxw = fmt2.fmt.pix.width;
272 *maxh = fmt2.fmt.pix.height;
273
274 done:
275 return 0;
276}
277
278/* ----------------------------------------------------------------- */
279
280/*
281 * This function is exported.
282 */
283int
284v4l_compat_translate_ioctl(struct inode *inode,
285 struct file *file,
286 int cmd,
287 void *arg,
288 v4l2_kioctl drv)
289{
290 struct v4l2_capability *cap2 = NULL;
291 struct v4l2_format *fmt2 = NULL;
292 enum v4l2_buf_type captype = V4L2_BUF_TYPE_VIDEO_CAPTURE;
293
294 struct v4l2_framebuffer fbuf2;
295 struct v4l2_input input2;
296 struct v4l2_tuner tun2;
297 struct v4l2_standard std2;
298 struct v4l2_frequency freq2;
299 struct v4l2_audio aud2;
300 struct v4l2_queryctrl qctrl2;
301 struct v4l2_buffer buf2;
302 v4l2_std_id sid;
303 int i, err = 0;
304
305 switch (cmd) {
306 case VIDIOCGCAP: /* capability */
307 {
308 struct video_capability *cap = arg;
309
310 cap2 = kmalloc(sizeof(*cap2),GFP_KERNEL);
311 memset(cap, 0, sizeof(*cap));
312 memset(cap2, 0, sizeof(*cap2));
313 memset(&fbuf2, 0, sizeof(fbuf2));
314
315 err = drv(inode, file, VIDIOC_QUERYCAP, cap2);
316 if (err < 0) {
317 dprintk("VIDIOCGCAP / VIDIOC_QUERYCAP: %d\n",err);
318 break;
319 }
320 if (cap2->capabilities & V4L2_CAP_VIDEO_OVERLAY) {
321 err = drv(inode, file, VIDIOC_G_FBUF, &fbuf2);
322 if (err < 0) {
323 dprintk("VIDIOCGCAP / VIDIOC_G_FBUF: %d\n",err);
324 memset(&fbuf2, 0, sizeof(fbuf2));
325 }
326 err = 0;
327 }
328
329 memcpy(cap->name, cap2->card,
330 min(sizeof(cap->name), sizeof(cap2->card)));
331 cap->name[sizeof(cap->name) - 1] = 0;
332 if (cap2->capabilities & V4L2_CAP_VIDEO_CAPTURE)
333 cap->type |= VID_TYPE_CAPTURE;
334 if (cap2->capabilities & V4L2_CAP_TUNER)
335 cap->type |= VID_TYPE_TUNER;
336 if (cap2->capabilities & V4L2_CAP_VBI_CAPTURE)
337 cap->type |= VID_TYPE_TELETEXT;
338 if (cap2->capabilities & V4L2_CAP_VIDEO_OVERLAY)
339 cap->type |= VID_TYPE_OVERLAY;
340 if (fbuf2.capability & V4L2_FBUF_CAP_LIST_CLIPPING)
341 cap->type |= VID_TYPE_CLIPPING;
342
343 cap->channels = count_inputs(inode,file,drv);
344 check_size(inode,file,drv,
345 &cap->maxwidth,&cap->maxheight);
346 cap->audios = 0; /* FIXME */
347 cap->minwidth = 48; /* FIXME */
348 cap->minheight = 32; /* FIXME */
349 break;
350 }
351 case VIDIOCGFBUF: /* get frame buffer */
352 {
353 struct video_buffer *buffer = arg;
354
355 err = drv(inode, file, VIDIOC_G_FBUF, &fbuf2);
356 if (err < 0) {
357 dprintk("VIDIOCGFBUF / VIDIOC_G_FBUF: %d\n",err);
358 break;
359 }
360 buffer->base = fbuf2.base;
361 buffer->height = fbuf2.fmt.height;
362 buffer->width = fbuf2.fmt.width;
363
364 switch (fbuf2.fmt.pixelformat) {
365 case V4L2_PIX_FMT_RGB332:
366 buffer->depth = 8;
367 break;
368 case V4L2_PIX_FMT_RGB555:
369 buffer->depth = 15;
370 break;
371 case V4L2_PIX_FMT_RGB565:
372 buffer->depth = 16;
373 break;
374 case V4L2_PIX_FMT_BGR24:
375 buffer->depth = 24;
376 break;
377 case V4L2_PIX_FMT_BGR32:
378 buffer->depth = 32;
379 break;
380 default:
381 buffer->depth = 0;
382 }
383 if (0 != fbuf2.fmt.bytesperline)
384 buffer->bytesperline = fbuf2.fmt.bytesperline;
385 else {
386 buffer->bytesperline =
387 (buffer->width * buffer->depth + 7) & 7;
388 buffer->bytesperline >>= 3;
389 }
390 break;
391 }
392 case VIDIOCSFBUF: /* set frame buffer */
393 {
394 struct video_buffer *buffer = arg;
395
396 memset(&fbuf2, 0, sizeof(fbuf2));
397 fbuf2.base = buffer->base;
398 fbuf2.fmt.height = buffer->height;
399 fbuf2.fmt.width = buffer->width;
400 switch (buffer->depth) {
401 case 8:
402 fbuf2.fmt.pixelformat = V4L2_PIX_FMT_RGB332;
403 break;
404 case 15:
405 fbuf2.fmt.pixelformat = V4L2_PIX_FMT_RGB555;
406 break;
407 case 16:
408 fbuf2.fmt.pixelformat = V4L2_PIX_FMT_RGB565;
409 break;
410 case 24:
411 fbuf2.fmt.pixelformat = V4L2_PIX_FMT_BGR24;
412 break;
413 case 32:
414 fbuf2.fmt.pixelformat = V4L2_PIX_FMT_BGR32;
415 break;
416 }
417 fbuf2.fmt.bytesperline = buffer->bytesperline;
418 err = drv(inode, file, VIDIOC_S_FBUF, &fbuf2);
419 if (err < 0)
420 dprintk("VIDIOCSFBUF / VIDIOC_S_FBUF: %d\n",err);
421 break;
422 }
423 case VIDIOCGWIN: /* get window or capture dimensions */
424 {
425 struct video_window *win = arg;
426
427 fmt2 = kmalloc(sizeof(*fmt2),GFP_KERNEL);
428 memset(win,0,sizeof(*win));
429 memset(fmt2,0,sizeof(*fmt2));
430
431 fmt2->type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
432 err = drv(inode, file, VIDIOC_G_FMT, fmt2);
433 if (err < 0)
434 dprintk("VIDIOCGWIN / VIDIOC_G_WIN: %d\n",err);
435 if (err == 0) {
436 win->x = fmt2->fmt.win.w.left;
437 win->y = fmt2->fmt.win.w.top;
438 win->width = fmt2->fmt.win.w.width;
439 win->height = fmt2->fmt.win.w.height;
440 win->chromakey = fmt2->fmt.win.chromakey;
441 win->clips = NULL;
442 win->clipcount = 0;
443 break;
444 }
445
446 fmt2->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
447 err = drv(inode, file, VIDIOC_G_FMT, fmt2);
448 if (err < 0) {
449 dprintk("VIDIOCGWIN / VIDIOC_G_FMT: %d\n",err);
450 break;
451 }
452 win->x = 0;
453 win->y = 0;
454 win->width = fmt2->fmt.pix.width;
455 win->height = fmt2->fmt.pix.height;
456 win->chromakey = 0;
457 win->clips = NULL;
458 win->clipcount = 0;
459 break;
460 }
461 case VIDIOCSWIN: /* set window and/or capture dimensions */
462 {
463 struct video_window *win = arg;
464 int err1,err2;
465
466 fmt2 = kmalloc(sizeof(*fmt2),GFP_KERNEL);
467 memset(fmt2,0,sizeof(*fmt2));
468 fmt2->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
469 drv(inode, file, VIDIOC_STREAMOFF, &fmt2->type);
470 err1 = drv(inode, file, VIDIOC_G_FMT, fmt2);
471 if (err1 < 0)
472 dprintk("VIDIOCSWIN / VIDIOC_G_FMT: %d\n",err);
473 if (err1 == 0) {
474 fmt2->fmt.pix.width = win->width;
475 fmt2->fmt.pix.height = win->height;
476 fmt2->fmt.pix.field = V4L2_FIELD_ANY;
477 fmt2->fmt.pix.bytesperline = 0;
478 err = drv(inode, file, VIDIOC_S_FMT, fmt2);
479 if (err < 0)
480 dprintk("VIDIOCSWIN / VIDIOC_S_FMT #1: %d\n",
481 err);
482 win->width = fmt2->fmt.pix.width;
483 win->height = fmt2->fmt.pix.height;
484 }
485
486 memset(fmt2,0,sizeof(*fmt2));
487 fmt2->type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
488 fmt2->fmt.win.w.left = win->x;
489 fmt2->fmt.win.w.top = win->y;
490 fmt2->fmt.win.w.width = win->width;
491 fmt2->fmt.win.w.height = win->height;
492 fmt2->fmt.win.chromakey = win->chromakey;
493 fmt2->fmt.win.clips = (void __user *)win->clips;
494 fmt2->fmt.win.clipcount = win->clipcount;
495 err2 = drv(inode, file, VIDIOC_S_FMT, fmt2);
496 if (err2 < 0)
497 dprintk("VIDIOCSWIN / VIDIOC_S_FMT #2: %d\n",err);
498
499 if (err1 != 0 && err2 != 0)
500 err = err1;
501 break;
502 }
503 case VIDIOCCAPTURE: /* turn on/off preview */
504 {
505 int *on = arg;
506
507 if (0 == *on) {
508 /* dirty hack time. But v4l1 has no STREAMOFF
509 * equivalent in the API, and this one at
510 * least comes close ... */
511 drv(inode, file, VIDIOC_STREAMOFF, &captype);
512 }
513 err = drv(inode, file, VIDIOC_OVERLAY, arg);
514 if (err < 0)
515 dprintk("VIDIOCCAPTURE / VIDIOC_PREVIEW: %d\n",err);
516 break;
517 }
518 case VIDIOCGCHAN: /* get input information */
519 {
520 struct video_channel *chan = arg;
521
522 memset(&input2,0,sizeof(input2));
523 input2.index = chan->channel;
524 err = drv(inode, file, VIDIOC_ENUMINPUT, &input2);
525 if (err < 0) {
526 dprintk("VIDIOCGCHAN / VIDIOC_ENUMINPUT: "
527 "channel=%d err=%d\n",chan->channel,err);
528 break;
529 }
530 chan->channel = input2.index;
531 memcpy(chan->name, input2.name,
532 min(sizeof(chan->name), sizeof(input2.name)));
533 chan->name[sizeof(chan->name) - 1] = 0;
534 chan->tuners = (input2.type == V4L2_INPUT_TYPE_TUNER) ? 1 : 0;
535 chan->flags = (chan->tuners) ? VIDEO_VC_TUNER : 0;
536 switch (input2.type) {
537 case V4L2_INPUT_TYPE_TUNER:
538 chan->type = VIDEO_TYPE_TV;
539 break;
540 default:
541 case V4L2_INPUT_TYPE_CAMERA:
542 chan->type = VIDEO_TYPE_CAMERA;
543 break;
544 }
545 chan->norm = 0;
546 err = drv(inode, file, VIDIOC_G_STD, &sid);
547 if (err < 0)
548 dprintk("VIDIOCGCHAN / VIDIOC_G_STD: %d\n",err);
549 if (err == 0) {
550 if (sid & V4L2_STD_PAL)
551 chan->norm = VIDEO_MODE_PAL;
552 if (sid & V4L2_STD_NTSC)
553 chan->norm = VIDEO_MODE_NTSC;
554 if (sid & V4L2_STD_SECAM)
555 chan->norm = VIDEO_MODE_SECAM;
556 }
557 break;
558 }
559 case VIDIOCSCHAN: /* set input */
560 {
561 struct video_channel *chan = arg;
562
563 sid = 0;
564 err = drv(inode, file, VIDIOC_S_INPUT, &chan->channel);
565 if (err < 0)
566 dprintk("VIDIOCSCHAN / VIDIOC_S_INPUT: %d\n",err);
567 switch (chan->norm) {
568 case VIDEO_MODE_PAL:
569 sid = V4L2_STD_PAL;
570 break;
571 case VIDEO_MODE_NTSC:
572 sid = V4L2_STD_NTSC;
573 break;
574 case VIDEO_MODE_SECAM:
575 sid = V4L2_STD_SECAM;
576 break;
577 }
578 if (0 != sid) {
579 err = drv(inode, file, VIDIOC_S_STD, &sid);
580 if (err < 0)
581 dprintk("VIDIOCSCHAN / VIDIOC_S_STD: %d\n",err);
582 }
583 break;
584 }
585 case VIDIOCGPICT: /* get tone controls & partial capture format */
586 {
587 struct video_picture *pict = arg;
588
589 pict->brightness = get_v4l_control(inode, file,
590 V4L2_CID_BRIGHTNESS,drv);
591 pict->hue = get_v4l_control(inode, file,
592 V4L2_CID_HUE, drv);
593 pict->contrast = get_v4l_control(inode, file,
594 V4L2_CID_CONTRAST, drv);
595 pict->colour = get_v4l_control(inode, file,
596 V4L2_CID_SATURATION, drv);
597 pict->whiteness = get_v4l_control(inode, file,
598 V4L2_CID_WHITENESS, drv);
599
600 fmt2 = kmalloc(sizeof(*fmt2),GFP_KERNEL);
601 memset(fmt2,0,sizeof(*fmt2));
602 fmt2->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
603 err = drv(inode, file, VIDIOC_G_FMT, fmt2);
604 if (err < 0) {
605 dprintk("VIDIOCGPICT / VIDIOC_G_FMT: %d\n",err);
606 break;
607 }
608#if 0 /* FIXME */
609 pict->depth = fmt2->fmt.pix.depth;
610#endif
611 pict->palette = pixelformat_to_palette(
612 fmt2->fmt.pix.pixelformat);
613 break;
614 }
615 case VIDIOCSPICT: /* set tone controls & partial capture format */
616 {
617 struct video_picture *pict = arg;
618
619 set_v4l_control(inode, file,
620 V4L2_CID_BRIGHTNESS, pict->brightness, drv);
621 set_v4l_control(inode, file,
622 V4L2_CID_HUE, pict->hue, drv);
623 set_v4l_control(inode, file,
624 V4L2_CID_CONTRAST, pict->contrast, drv);
625 set_v4l_control(inode, file,
626 V4L2_CID_SATURATION, pict->colour, drv);
627 set_v4l_control(inode, file,
628 V4L2_CID_WHITENESS, pict->whiteness, drv);
629
630 fmt2 = kmalloc(sizeof(*fmt2),GFP_KERNEL);
631 memset(fmt2,0,sizeof(*fmt2));
632 fmt2->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
633 err = drv(inode, file, VIDIOC_G_FMT, fmt2);
634 if (err < 0)
635 dprintk("VIDIOCSPICT / VIDIOC_G_FMT: %d\n",err);
636 if (fmt2->fmt.pix.pixelformat !=
637 palette_to_pixelformat(pict->palette)) {
638 fmt2->fmt.pix.pixelformat = palette_to_pixelformat(
639 pict->palette);
640 err = drv(inode, file, VIDIOC_S_FMT, fmt2);
641 if (err < 0)
642 dprintk("VIDIOCSPICT / VIDIOC_S_FMT: %d\n",err);
643 }
644
645 err = drv(inode, file, VIDIOC_G_FBUF, &fbuf2);
646 if (err < 0)
647 dprintk("VIDIOCSPICT / VIDIOC_G_FBUF: %d\n",err);
648 if (fbuf2.fmt.pixelformat !=
649 palette_to_pixelformat(pict->palette)) {
650 fbuf2.fmt.pixelformat = palette_to_pixelformat(
651 pict->palette);
652 err = drv(inode, file, VIDIOC_S_FBUF, &fbuf2);
653 if (err < 0)
654 dprintk("VIDIOCSPICT / VIDIOC_S_FBUF: %d\n",err);
655 err = 0; /* likely fails for non-root */
656 }
657 break;
658 }
659 case VIDIOCGTUNER: /* get tuner information */
660 {
661 struct video_tuner *tun = arg;
662
663 memset(&tun2,0,sizeof(tun2));
664 err = drv(inode, file, VIDIOC_G_TUNER, &tun2);
665 if (err < 0) {
666 dprintk("VIDIOCGTUNER / VIDIOC_G_TUNER: %d\n",err);
667 break;
668 }
669 memcpy(tun->name, tun2.name,
670 min(sizeof(tun->name), sizeof(tun2.name)));
671 tun->name[sizeof(tun->name) - 1] = 0;
672 tun->rangelow = tun2.rangelow;
673 tun->rangehigh = tun2.rangehigh;
674 tun->flags = 0;
675 tun->mode = VIDEO_MODE_AUTO;
676
677 for (i = 0; i < 64; i++) {
678 memset(&std2,0,sizeof(std2));
679 std2.index = i;
680 if (0 != drv(inode, file, VIDIOC_ENUMSTD, &std2))
681 break;
682 if (std2.id & V4L2_STD_PAL)
683 tun->flags |= VIDEO_TUNER_PAL;
684 if (std2.id & V4L2_STD_NTSC)
685 tun->flags |= VIDEO_TUNER_NTSC;
686 if (std2.id & V4L2_STD_SECAM)
687 tun->flags |= VIDEO_TUNER_SECAM;
688 }
689
690 err = drv(inode, file, VIDIOC_G_STD, &sid);
691 if (err < 0)
692 dprintk("VIDIOCGTUNER / VIDIOC_G_STD: %d\n",err);
693 if (err == 0) {
694 if (sid & V4L2_STD_PAL)
695 tun->mode = VIDEO_MODE_PAL;
696 if (sid & V4L2_STD_NTSC)
697 tun->mode = VIDEO_MODE_NTSC;
698 if (sid & V4L2_STD_SECAM)
699 tun->mode = VIDEO_MODE_SECAM;
700 }
701
702 if (tun2.capability & V4L2_TUNER_CAP_LOW)
703 tun->flags |= VIDEO_TUNER_LOW;
704 if (tun2.rxsubchans & V4L2_TUNER_SUB_STEREO)
705 tun->flags |= VIDEO_TUNER_STEREO_ON;
706 tun->signal = tun2.signal;
707 break;
708 }
709 case VIDIOCSTUNER: /* select a tuner input */
710 {
711#if 0 /* FIXME */
712 err = drv(inode, file, VIDIOC_S_INPUT, &i);
713 if (err < 0)
714 dprintk("VIDIOCSTUNER / VIDIOC_S_INPUT: %d\n",err);
715#else
716 err = 0;
717#endif
718 break;
719 }
720 case VIDIOCGFREQ: /* get frequency */
721 {
722 int *freq = arg;
723
724 freq2.tuner = 0;
725 err = drv(inode, file, VIDIOC_G_FREQUENCY, &freq2);
726 if (err < 0)
727 dprintk("VIDIOCGFREQ / VIDIOC_G_FREQUENCY: %d\n",err);
728 if (0 == err)
729 *freq = freq2.frequency;
730 break;
731 }
732 case VIDIOCSFREQ: /* set frequency */
733 {
734 int *freq = arg;
735
736 freq2.tuner = 0;
737 drv(inode, file, VIDIOC_G_FREQUENCY, &freq2);
738 freq2.frequency = *freq;
739 err = drv(inode, file, VIDIOC_S_FREQUENCY, &freq2);
740 if (err < 0)
741 dprintk("VIDIOCSFREQ / VIDIOC_S_FREQUENCY: %d\n",err);
742 break;
743 }
744 case VIDIOCGAUDIO: /* get audio properties/controls */
745 {
746 struct video_audio *aud = arg;
747
748 err = drv(inode, file, VIDIOC_G_AUDIO, &aud2);
749 if (err < 0) {
750 dprintk("VIDIOCGAUDIO / VIDIOC_G_AUDIO: %d\n",err);
751 break;
752 }
753 memcpy(aud->name, aud2.name,
754 min(sizeof(aud->name), sizeof(aud2.name)));
755 aud->name[sizeof(aud->name) - 1] = 0;
756 aud->audio = aud2.index;
757 aud->flags = 0;
758 i = get_v4l_control(inode, file, V4L2_CID_AUDIO_VOLUME, drv);
759 if (i >= 0) {
760 aud->volume = i;
761 aud->flags |= VIDEO_AUDIO_VOLUME;
762 }
763 i = get_v4l_control(inode, file, V4L2_CID_AUDIO_BASS, drv);
764 if (i >= 0) {
765 aud->bass = i;
766 aud->flags |= VIDEO_AUDIO_BASS;
767 }
768 i = get_v4l_control(inode, file, V4L2_CID_AUDIO_TREBLE, drv);
769 if (i >= 0) {
770 aud->treble = i;
771 aud->flags |= VIDEO_AUDIO_TREBLE;
772 }
773 i = get_v4l_control(inode, file, V4L2_CID_AUDIO_BALANCE, drv);
774 if (i >= 0) {
775 aud->balance = i;
776 aud->flags |= VIDEO_AUDIO_BALANCE;
777 }
778 i = get_v4l_control(inode, file, V4L2_CID_AUDIO_MUTE, drv);
779 if (i >= 0) {
780 if (i)
781 aud->flags |= VIDEO_AUDIO_MUTE;
782 aud->flags |= VIDEO_AUDIO_MUTABLE;
783 }
784 aud->step = 1;
785 qctrl2.id = V4L2_CID_AUDIO_VOLUME;
786 if (drv(inode, file, VIDIOC_QUERYCTRL, &qctrl2) == 0 &&
787 !(qctrl2.flags & V4L2_CTRL_FLAG_DISABLED))
788 aud->step = qctrl2.step;
789 aud->mode = 0;
790 err = drv(inode, file, VIDIOC_G_TUNER, &tun2);
791 if (err < 0) {
792 dprintk("VIDIOCGAUDIO / VIDIOC_G_TUNER: %d\n",err);
793 err = 0;
794 break;
795 }
796 if (tun2.rxsubchans & V4L2_TUNER_SUB_LANG2)
797 aud->mode = VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
798 else if (tun2.rxsubchans & V4L2_TUNER_SUB_STEREO)
799 aud->mode = VIDEO_SOUND_STEREO;
800 else if (tun2.rxsubchans & V4L2_TUNER_SUB_MONO)
801 aud->mode = VIDEO_SOUND_MONO;
802 break;
803 }
804 case VIDIOCSAUDIO: /* set audio controls */
805 {
806 struct video_audio *aud = arg;
807
808 memset(&aud2,0,sizeof(aud2));
809 memset(&tun2,0,sizeof(tun2));
810
811 aud2.index = aud->audio;
812 err = drv(inode, file, VIDIOC_S_AUDIO, &aud2);
813 if (err < 0) {
814 dprintk("VIDIOCSAUDIO / VIDIOC_S_AUDIO: %d\n",err);
815 break;
816 }
817
818 set_v4l_control(inode, file, V4L2_CID_AUDIO_VOLUME,
819 aud->volume, drv);
820 set_v4l_control(inode, file, V4L2_CID_AUDIO_BASS,
821 aud->bass, drv);
822 set_v4l_control(inode, file, V4L2_CID_AUDIO_TREBLE,
823 aud->treble, drv);
824 set_v4l_control(inode, file, V4L2_CID_AUDIO_BALANCE,
825 aud->balance, drv);
826 set_v4l_control(inode, file, V4L2_CID_AUDIO_MUTE,
827 !!(aud->flags & VIDEO_AUDIO_MUTE), drv);
828
829 err = drv(inode, file, VIDIOC_G_TUNER, &tun2);
830 if (err < 0)
831 dprintk("VIDIOCSAUDIO / VIDIOC_G_TUNER: %d\n",err);
832 if (err == 0) {
833 switch (aud->mode) {
834 default:
835 case VIDEO_SOUND_MONO:
836 case VIDEO_SOUND_LANG1:
837 tun2.audmode = V4L2_TUNER_MODE_MONO;
838 break;
839 case VIDEO_SOUND_STEREO:
840 tun2.audmode = V4L2_TUNER_MODE_STEREO;
841 break;
842 case VIDEO_SOUND_LANG2:
843 tun2.audmode = V4L2_TUNER_MODE_LANG2;
844 break;
845 }
846 err = drv(inode, file, VIDIOC_S_TUNER, &tun2);
847 if (err < 0)
848 dprintk("VIDIOCSAUDIO / VIDIOC_S_TUNER: %d\n",err);
849 }
850 err = 0;
851 break;
852 }
853#if 0
854 case VIDIOCGMBUF:
855 /* v4l2 drivers must implement that themself. The
856 mmap() differences can't be translated fully
857 transparent, thus there is no point to try that */
858#endif
859 case VIDIOCMCAPTURE: /* capture a frame */
860 {
861 struct video_mmap *mm = arg;
862
863 fmt2 = kmalloc(sizeof(*fmt2),GFP_KERNEL);
864 memset(&buf2,0,sizeof(buf2));
865 memset(fmt2,0,sizeof(*fmt2));
866
867 fmt2->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
868 err = drv(inode, file, VIDIOC_G_FMT, fmt2);
869 if (err < 0) {
870 dprintk("VIDIOCMCAPTURE / VIDIOC_G_FMT: %d\n",err);
871 break;
872 }
873 if (mm->width != fmt2->fmt.pix.width ||
874 mm->height != fmt2->fmt.pix.height ||
875 palette_to_pixelformat(mm->format) !=
876 fmt2->fmt.pix.pixelformat)
877 {/* New capture format... */
878 fmt2->fmt.pix.width = mm->width;
879 fmt2->fmt.pix.height = mm->height;
880 fmt2->fmt.pix.pixelformat =
881 palette_to_pixelformat(mm->format);
882 fmt2->fmt.pix.field = V4L2_FIELD_ANY;
883 fmt2->fmt.pix.bytesperline = 0;
884 err = drv(inode, file, VIDIOC_S_FMT, fmt2);
885 if (err < 0) {
886 dprintk("VIDIOCMCAPTURE / VIDIOC_S_FMT: %d\n",err);
887 break;
888 }
889 }
890 buf2.index = mm->frame;
891 buf2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
892 err = drv(inode, file, VIDIOC_QUERYBUF, &buf2);
893 if (err < 0) {
894 dprintk("VIDIOCMCAPTURE / VIDIOC_QUERYBUF: %d\n",err);
895 break;
896 }
897 err = drv(inode, file, VIDIOC_QBUF, &buf2);
898 if (err < 0) {
899 dprintk("VIDIOCMCAPTURE / VIDIOC_QBUF: %d\n",err);
900 break;
901 }
902 err = drv(inode, file, VIDIOC_STREAMON, &captype);
903 if (err < 0)
904 dprintk("VIDIOCMCAPTURE / VIDIOC_STREAMON: %d\n",err);
905 break;
906 }
907 case VIDIOCSYNC: /* wait for a frame */
908 {
909 int *i = arg;
910
911 buf2.index = *i;
912 buf2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
913 err = drv(inode, file, VIDIOC_QUERYBUF, &buf2);
914 if (err < 0) {
915 /* No such buffer */
916 dprintk("VIDIOCSYNC / VIDIOC_QUERYBUF: %d\n",err);
917 break;
918 }
919 if (!(buf2.flags & V4L2_BUF_FLAG_MAPPED)) {
920 /* Buffer is not mapped */
921 err = -EINVAL;
922 break;
923 }
924
925 /* make sure capture actually runs so we don't block forever */
926 err = drv(inode, file, VIDIOC_STREAMON, &captype);
927 if (err < 0) {
928 dprintk("VIDIOCSYNC / VIDIOC_STREAMON: %d\n",err);
929 break;
930 }
931
932 /* Loop as long as the buffer is queued, but not done */
933 while ((buf2.flags &
934 (V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_DONE))
935 == V4L2_BUF_FLAG_QUEUED)
936 {
937 err = poll_one(file);
938 if (err < 0 || /* error or sleep was interrupted */
939 err == 0) /* timeout? Shouldn't occur. */
940 break;
941 err = drv(inode, file, VIDIOC_QUERYBUF, &buf2);
942 if (err < 0)
943 dprintk("VIDIOCSYNC / VIDIOC_QUERYBUF: %d\n",err);
944 }
945 if (!(buf2.flags & V4L2_BUF_FLAG_DONE)) /* not done */
946 break;
947 do {
948 err = drv(inode, file, VIDIOC_DQBUF, &buf2);
949 if (err < 0)
950 dprintk("VIDIOCSYNC / VIDIOC_DQBUF: %d\n",err);
951 } while (err == 0 && buf2.index != *i);
952 break;
953 }
954
955 case VIDIOCGVBIFMT: /* query VBI data capture format */
956 {
957 struct vbi_format *fmt = arg;
958
959 fmt2 = kmalloc(sizeof(*fmt2),GFP_KERNEL);
960 memset(fmt2, 0, sizeof(*fmt2));
961 fmt2->type = V4L2_BUF_TYPE_VBI_CAPTURE;
962
963 err = drv(inode, file, VIDIOC_G_FMT, fmt2);
964 if (err < 0) {
965 dprintk("VIDIOCGVBIFMT / VIDIOC_G_FMT: %d\n", err);
966 break;
967 }
968 memset(fmt, 0, sizeof(*fmt));
969 fmt->samples_per_line = fmt2->fmt.vbi.samples_per_line;
970 fmt->sampling_rate = fmt2->fmt.vbi.sampling_rate;
971 fmt->sample_format = VIDEO_PALETTE_RAW;
972 fmt->start[0] = fmt2->fmt.vbi.start[0];
973 fmt->count[0] = fmt2->fmt.vbi.count[0];
974 fmt->start[1] = fmt2->fmt.vbi.start[1];
975 fmt->count[1] = fmt2->fmt.vbi.count[1];
976 fmt->flags = fmt2->fmt.vbi.flags & 0x03;
977 break;
978 }
979 case VIDIOCSVBIFMT:
980 {
981 struct vbi_format *fmt = arg;
982
983 fmt2 = kmalloc(sizeof(*fmt2),GFP_KERNEL);
984 memset(fmt2, 0, sizeof(*fmt2));
985
986 fmt2->type = V4L2_BUF_TYPE_VBI_CAPTURE;
987 fmt2->fmt.vbi.samples_per_line = fmt->samples_per_line;
988 fmt2->fmt.vbi.sampling_rate = fmt->sampling_rate;
989 fmt2->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
990 fmt2->fmt.vbi.start[0] = fmt->start[0];
991 fmt2->fmt.vbi.count[0] = fmt->count[0];
992 fmt2->fmt.vbi.start[1] = fmt->start[1];
993 fmt2->fmt.vbi.count[1] = fmt->count[1];
994 fmt2->fmt.vbi.flags = fmt->flags;
995 err = drv(inode, file, VIDIOC_TRY_FMT, fmt2);
996 if (err < 0) {
997 dprintk("VIDIOCSVBIFMT / VIDIOC_TRY_FMT: %d\n", err);
998 break;
999 }
1000
1001 if (fmt2->fmt.vbi.samples_per_line != fmt->samples_per_line ||
1002 fmt2->fmt.vbi.sampling_rate != fmt->sampling_rate ||
1003 VIDEO_PALETTE_RAW != fmt->sample_format ||
1004 fmt2->fmt.vbi.start[0] != fmt->start[0] ||
1005 fmt2->fmt.vbi.count[0] != fmt->count[0] ||
1006 fmt2->fmt.vbi.start[1] != fmt->start[1] ||
1007 fmt2->fmt.vbi.count[1] != fmt->count[1] ||
1008 fmt2->fmt.vbi.flags != fmt->flags) {
1009 err = -EINVAL;
1010 break;
1011 }
1012 err = drv(inode, file, VIDIOC_S_FMT, fmt2);
1013 if (err < 0)
1014 dprintk("VIDIOCSVBIFMT / VIDIOC_S_FMT: %d\n", err);
1015 break;
1016 }
1017
1018 default:
1019 err = -ENOIOCTLCMD;
1020 break;
1021 }
1022
1023 if (cap2)
1024 kfree(cap2);
1025 if (fmt2)
1026 kfree(fmt2);
1027 return err;
1028}
1029
1030EXPORT_SYMBOL(v4l_compat_translate_ioctl);
1031
1032/*
1033 * Local variables:
1034 * c-basic-offset: 8
1035 * End:
1036 */
diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c
new file mode 100644
index 00000000000..b5e0cf3448f
--- /dev/null
+++ b/drivers/media/video/v4l2-common.c
@@ -0,0 +1,282 @@
1/*
2 * Video for Linux Two
3 *
4 * A generic video device interface for the LINUX operating system
5 * using a set of device structures/vectors for low level operations.
6 *
7 * This file replaces the videodev.c file that comes with the
8 * regular kernel distribution.
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version
13 * 2 of the License, or (at your option) any later version.
14 *
15 * Author: Bill Dirks <bdirks@pacbell.net>
16 * based on code by Alan Cox, <alan@cymru.net>
17 *
18 */
19
20/*
21 * Video capture interface for Linux
22 *
23 * A generic video device interface for the LINUX operating system
24 * using a set of device structures/vectors for low level operations.
25 *
26 * This program is free software; you can redistribute it and/or
27 * modify it under the terms of the GNU General Public License
28 * as published by the Free Software Foundation; either version
29 * 2 of the License, or (at your option) any later version.
30 *
31 * Author: Alan Cox, <alan@redhat.com>
32 *
33 * Fixes:
34 */
35
36/*
37 * Video4linux 1/2 integration by Justin Schoeman
38 * <justin@suntiger.ee.up.ac.za>
39 * 2.4 PROCFS support ported from 2.4 kernels by
40 * Iñaki García Etxebarria <garetxe@euskalnet.net>
41 * Makefile fix by "W. Michael Petullo" <mike@flyn.org>
42 * 2.4 devfs support ported from 2.4 kernels by
43 * Dan Merillat <dan@merillat.org>
44 * Added Gerd Knorrs v4l1 enhancements (Justin Schoeman)
45 */
46
47#include <linux/config.h>
48#include <linux/module.h>
49#include <linux/types.h>
50#include <linux/kernel.h>
51#include <linux/sched.h>
52#include <linux/smp_lock.h>
53#include <linux/mm.h>
54#include <linux/string.h>
55#include <linux/errno.h>
56#include <asm/uaccess.h>
57#include <asm/system.h>
58#include <asm/pgtable.h>
59#include <asm/io.h>
60#include <asm/div64.h>
61
62#ifdef CONFIG_KMOD
63#include <linux/kmod.h>
64#endif
65
66#if defined(CONFIG_UST) || defined(CONFIG_UST_MODULE)
67#include <linux/ust.h>
68#endif
69
70
71#include <linux/videodev.h>
72
73MODULE_AUTHOR("Bill Dirks, Justin Schoeman, Gerd Knorr");
74MODULE_DESCRIPTION("misc helper functions for v4l2 device drivers");
75MODULE_LICENSE("GPL");
76
77/*
78 *
79 * V 4 L 2 D R I V E R H E L P E R A P I
80 *
81 */
82
83/*
84 * Video Standard Operations (contributed by Michael Schimek)
85 */
86
87#if 0 /* seems to have no users */
88/* This is the recommended method to deal with the framerate fields. More
89 sophisticated drivers will access the fields directly. */
90unsigned int
91v4l2_video_std_fps(struct v4l2_standard *vs)
92{
93 if (vs->frameperiod.numerator > 0)
94 return (((vs->frameperiod.denominator << 8) /
95 vs->frameperiod.numerator) +
96 (1 << 7)) / (1 << 8);
97 return 0;
98}
99EXPORT_SYMBOL(v4l2_video_std_fps);
100#endif
101
102/* Fill in the fields of a v4l2_standard structure according to the
103 'id' and 'transmission' parameters. Returns negative on error. */
104int v4l2_video_std_construct(struct v4l2_standard *vs,
105 int id, char *name)
106{
107 u32 index = vs->index;
108
109 memset(vs, 0, sizeof(struct v4l2_standard));
110 vs->index = index;
111 vs->id = id;
112 if (id & (V4L2_STD_NTSC | V4L2_STD_PAL_M)) {
113 vs->frameperiod.numerator = 1001;
114 vs->frameperiod.denominator = 30000;
115 vs->framelines = 525;
116 } else {
117 vs->frameperiod.numerator = 1;
118 vs->frameperiod.denominator = 25;
119 vs->framelines = 625;
120 }
121 strlcpy(vs->name,name,sizeof(vs->name));
122 return 0;
123}
124
125
126/* ----------------------------------------------------------------- */
127/* priority handling */
128
129#define V4L2_PRIO_VALID(val) (val == V4L2_PRIORITY_BACKGROUND || \
130 val == V4L2_PRIORITY_INTERACTIVE || \
131 val == V4L2_PRIORITY_RECORD)
132
133int v4l2_prio_init(struct v4l2_prio_state *global)
134{
135 memset(global,0,sizeof(*global));
136 return 0;
137}
138
139int v4l2_prio_change(struct v4l2_prio_state *global, enum v4l2_priority *local,
140 enum v4l2_priority new)
141{
142 if (!V4L2_PRIO_VALID(new))
143 return -EINVAL;
144 if (*local == new)
145 return 0;
146
147 atomic_inc(&global->prios[new]);
148 if (V4L2_PRIO_VALID(*local))
149 atomic_dec(&global->prios[*local]);
150 *local = new;
151 return 0;
152}
153
154int v4l2_prio_open(struct v4l2_prio_state *global, enum v4l2_priority *local)
155{
156 return v4l2_prio_change(global,local,V4L2_PRIORITY_DEFAULT);
157}
158
159int v4l2_prio_close(struct v4l2_prio_state *global, enum v4l2_priority *local)
160{
161 if (V4L2_PRIO_VALID(*local))
162 atomic_dec(&global->prios[*local]);
163 return 0;
164}
165
166enum v4l2_priority v4l2_prio_max(struct v4l2_prio_state *global)
167{
168 if (atomic_read(&global->prios[V4L2_PRIORITY_RECORD]) > 0)
169 return V4L2_PRIORITY_RECORD;
170 if (atomic_read(&global->prios[V4L2_PRIORITY_INTERACTIVE]) > 0)
171 return V4L2_PRIORITY_INTERACTIVE;
172 if (atomic_read(&global->prios[V4L2_PRIORITY_BACKGROUND]) > 0)
173 return V4L2_PRIORITY_BACKGROUND;
174 return V4L2_PRIORITY_UNSET;
175}
176
177int v4l2_prio_check(struct v4l2_prio_state *global, enum v4l2_priority *local)
178{
179 if (*local < v4l2_prio_max(global))
180 return -EBUSY;
181 return 0;
182}
183
184
185/* ----------------------------------------------------------------- */
186/* some arrays for pretty-printing debug messages */
187
188char *v4l2_field_names[] = {
189 [V4L2_FIELD_ANY] = "any",
190 [V4L2_FIELD_NONE] = "none",
191 [V4L2_FIELD_TOP] = "top",
192 [V4L2_FIELD_BOTTOM] = "bottom",
193 [V4L2_FIELD_INTERLACED] = "interlaced",
194 [V4L2_FIELD_SEQ_TB] = "seq-tb",
195 [V4L2_FIELD_SEQ_BT] = "seq-bt",
196 [V4L2_FIELD_ALTERNATE] = "alternate",
197};
198
199char *v4l2_type_names[] = {
200 [V4L2_BUF_TYPE_VIDEO_CAPTURE] = "video-cap",
201 [V4L2_BUF_TYPE_VIDEO_OVERLAY] = "video-over",
202 [V4L2_BUF_TYPE_VIDEO_OUTPUT] = "video-out",
203 [V4L2_BUF_TYPE_VBI_CAPTURE] = "vbi-cap",
204 [V4L2_BUF_TYPE_VBI_OUTPUT] = "vbi-out",
205};
206
207char *v4l2_ioctl_names[256] = {
208#if __GNUC__ >= 3
209 [0 ... 255] = "UNKNOWN",
210#endif
211 [_IOC_NR(VIDIOC_QUERYCAP)] = "VIDIOC_QUERYCAP",
212 [_IOC_NR(VIDIOC_RESERVED)] = "VIDIOC_RESERVED",
213 [_IOC_NR(VIDIOC_ENUM_FMT)] = "VIDIOC_ENUM_FMT",
214 [_IOC_NR(VIDIOC_G_FMT)] = "VIDIOC_G_FMT",
215 [_IOC_NR(VIDIOC_S_FMT)] = "VIDIOC_S_FMT",
216#if 0
217 [_IOC_NR(VIDIOC_G_COMP)] = "VIDIOC_G_COMP",
218 [_IOC_NR(VIDIOC_S_COMP)] = "VIDIOC_S_COMP",
219#endif
220 [_IOC_NR(VIDIOC_REQBUFS)] = "VIDIOC_REQBUFS",
221 [_IOC_NR(VIDIOC_QUERYBUF)] = "VIDIOC_QUERYBUF",
222 [_IOC_NR(VIDIOC_G_FBUF)] = "VIDIOC_G_FBUF",
223 [_IOC_NR(VIDIOC_S_FBUF)] = "VIDIOC_S_FBUF",
224 [_IOC_NR(VIDIOC_OVERLAY)] = "VIDIOC_OVERLAY",
225 [_IOC_NR(VIDIOC_QBUF)] = "VIDIOC_QBUF",
226 [_IOC_NR(VIDIOC_DQBUF)] = "VIDIOC_DQBUF",
227 [_IOC_NR(VIDIOC_STREAMON)] = "VIDIOC_STREAMON",
228 [_IOC_NR(VIDIOC_STREAMOFF)] = "VIDIOC_STREAMOFF",
229 [_IOC_NR(VIDIOC_G_PARM)] = "VIDIOC_G_PARM",
230 [_IOC_NR(VIDIOC_S_PARM)] = "VIDIOC_S_PARM",
231 [_IOC_NR(VIDIOC_G_STD)] = "VIDIOC_G_STD",
232 [_IOC_NR(VIDIOC_S_STD)] = "VIDIOC_S_STD",
233 [_IOC_NR(VIDIOC_ENUMSTD)] = "VIDIOC_ENUMSTD",
234 [_IOC_NR(VIDIOC_ENUMINPUT)] = "VIDIOC_ENUMINPUT",
235 [_IOC_NR(VIDIOC_G_CTRL)] = "VIDIOC_G_CTRL",
236 [_IOC_NR(VIDIOC_S_CTRL)] = "VIDIOC_S_CTRL",
237 [_IOC_NR(VIDIOC_G_TUNER)] = "VIDIOC_G_TUNER",
238 [_IOC_NR(VIDIOC_S_TUNER)] = "VIDIOC_S_TUNER",
239 [_IOC_NR(VIDIOC_G_AUDIO)] = "VIDIOC_G_AUDIO",
240 [_IOC_NR(VIDIOC_S_AUDIO)] = "VIDIOC_S_AUDIO",
241 [_IOC_NR(VIDIOC_QUERYCTRL)] = "VIDIOC_QUERYCTRL",
242 [_IOC_NR(VIDIOC_QUERYMENU)] = "VIDIOC_QUERYMENU",
243 [_IOC_NR(VIDIOC_G_INPUT)] = "VIDIOC_G_INPUT",
244 [_IOC_NR(VIDIOC_S_INPUT)] = "VIDIOC_S_INPUT",
245 [_IOC_NR(VIDIOC_G_OUTPUT)] = "VIDIOC_G_OUTPUT",
246 [_IOC_NR(VIDIOC_S_OUTPUT)] = "VIDIOC_S_OUTPUT",
247 [_IOC_NR(VIDIOC_ENUMOUTPUT)] = "VIDIOC_ENUMOUTPUT",
248 [_IOC_NR(VIDIOC_G_AUDOUT)] = "VIDIOC_G_AUDOUT",
249 [_IOC_NR(VIDIOC_S_AUDOUT)] = "VIDIOC_S_AUDOUT",
250 [_IOC_NR(VIDIOC_G_MODULATOR)] = "VIDIOC_G_MODULATOR",
251 [_IOC_NR(VIDIOC_S_MODULATOR)] = "VIDIOC_S_MODULATOR",
252 [_IOC_NR(VIDIOC_G_FREQUENCY)] = "VIDIOC_G_FREQUENCY",
253 [_IOC_NR(VIDIOC_S_FREQUENCY)] = "VIDIOC_S_FREQUENCY",
254 [_IOC_NR(VIDIOC_CROPCAP)] = "VIDIOC_CROPCAP",
255 [_IOC_NR(VIDIOC_G_CROP)] = "VIDIOC_G_CROP",
256 [_IOC_NR(VIDIOC_S_CROP)] = "VIDIOC_S_CROP",
257 [_IOC_NR(VIDIOC_G_JPEGCOMP)] = "VIDIOC_G_JPEGCOMP",
258 [_IOC_NR(VIDIOC_S_JPEGCOMP)] = "VIDIOC_S_JPEGCOMP",
259 [_IOC_NR(VIDIOC_QUERYSTD)] = "VIDIOC_QUERYSTD",
260 [_IOC_NR(VIDIOC_TRY_FMT)] = "VIDIOC_TRY_FMT",
261};
262
263/* ----------------------------------------------------------------- */
264
265EXPORT_SYMBOL(v4l2_video_std_construct);
266
267EXPORT_SYMBOL(v4l2_prio_init);
268EXPORT_SYMBOL(v4l2_prio_change);
269EXPORT_SYMBOL(v4l2_prio_open);
270EXPORT_SYMBOL(v4l2_prio_close);
271EXPORT_SYMBOL(v4l2_prio_max);
272EXPORT_SYMBOL(v4l2_prio_check);
273
274EXPORT_SYMBOL(v4l2_field_names);
275EXPORT_SYMBOL(v4l2_type_names);
276EXPORT_SYMBOL(v4l2_ioctl_names);
277
278/*
279 * Local variables:
280 * c-basic-offset: 8
281 * End:
282 */
diff --git a/drivers/media/video/video-buf-dvb.c b/drivers/media/video/video-buf-dvb.c
new file mode 100644
index 00000000000..31cc4ed9b74
--- /dev/null
+++ b/drivers/media/video/video-buf-dvb.c
@@ -0,0 +1,251 @@
1/*
2 * $Id: video-buf-dvb.c,v 1.7 2004/12/09 12:51:35 kraxel Exp $
3 *
4 * some helper function for simple DVB cards which simply DMA the
5 * complete transport stream and let the computer sort everything else
6 * (i.e. we are using the software demux, ...). Also uses the
7 * video-buf to manage DMA buffers.
8 *
9 * (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SUSE Labs]
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
17#include <linux/module.h>
18#include <linux/init.h>
19#include <linux/device.h>
20#include <linux/fs.h>
21#include <linux/kthread.h>
22#include <linux/file.h>
23#include <linux/suspend.h>
24
25#include <media/video-buf.h>
26#include <media/video-buf-dvb.h>
27
28/* ------------------------------------------------------------------ */
29
30MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
31MODULE_LICENSE("GPL");
32
33static unsigned int debug = 0;
34module_param(debug, int, 0644);
35MODULE_PARM_DESC(debug,"enable debug messages");
36
37#define dprintk(fmt, arg...) if (debug) \
38 printk(KERN_DEBUG "%s/dvb: " fmt, dvb->name , ## arg)
39
40/* ------------------------------------------------------------------ */
41
42static int videobuf_dvb_thread(void *data)
43{
44 struct videobuf_dvb *dvb = data;
45 struct videobuf_buffer *buf;
46 unsigned long flags;
47 int err;
48
49 dprintk("dvb thread started\n");
50 videobuf_read_start(&dvb->dvbq);
51
52 for (;;) {
53 /* fetch next buffer */
54 buf = list_entry(dvb->dvbq.stream.next,
55 struct videobuf_buffer, stream);
56 list_del(&buf->stream);
57 err = videobuf_waiton(buf,0,1);
58 BUG_ON(0 != err);
59
60 /* no more feeds left or stop_feed() asked us to quit */
61 if (0 == dvb->nfeeds)
62 break;
63 if (kthread_should_stop())
64 break;
65 if (current->flags & PF_FREEZE)
66 refrigerator(PF_FREEZE);
67
68 /* feed buffer data to demux */
69 if (buf->state == STATE_DONE)
70 dvb_dmx_swfilter(&dvb->demux, buf->dma.vmalloc,
71 buf->size);
72
73 /* requeue buffer */
74 list_add_tail(&buf->stream,&dvb->dvbq.stream);
75 spin_lock_irqsave(dvb->dvbq.irqlock,flags);
76 dvb->dvbq.ops->buf_queue(&dvb->dvbq,buf);
77 spin_unlock_irqrestore(dvb->dvbq.irqlock,flags);
78 }
79
80 videobuf_read_stop(&dvb->dvbq);
81 dprintk("dvb thread stopped\n");
82
83 /* Hmm, linux becomes *very* unhappy without this ... */
84 while (!kthread_should_stop()) {
85 set_current_state(TASK_INTERRUPTIBLE);
86 schedule();
87 }
88 return 0;
89}
90
91static int videobuf_dvb_start_feed(struct dvb_demux_feed *feed)
92{
93 struct dvb_demux *demux = feed->demux;
94 struct videobuf_dvb *dvb = demux->priv;
95 int rc;
96
97 if (!demux->dmx.frontend)
98 return -EINVAL;
99
100 down(&dvb->lock);
101 dvb->nfeeds++;
102 rc = dvb->nfeeds;
103
104 if (NULL != dvb->thread)
105 goto out;
106 dvb->thread = kthread_run(videobuf_dvb_thread,
107 dvb, "%s dvb", dvb->name);
108 if (IS_ERR(dvb->thread)) {
109 rc = PTR_ERR(dvb->thread);
110 dvb->thread = NULL;
111 }
112
113out:
114 up(&dvb->lock);
115 return rc;
116}
117
118static int videobuf_dvb_stop_feed(struct dvb_demux_feed *feed)
119{
120 struct dvb_demux *demux = feed->demux;
121 struct videobuf_dvb *dvb = demux->priv;
122 int err = 0;
123
124 down(&dvb->lock);
125 dvb->nfeeds--;
126 if (0 == dvb->nfeeds && NULL != dvb->thread) {
127 // FIXME: cx8802_cancel_buffers(dev);
128 err = kthread_stop(dvb->thread);
129 dvb->thread = NULL;
130 }
131 up(&dvb->lock);
132 return err;
133}
134
135/* ------------------------------------------------------------------ */
136
137int videobuf_dvb_register(struct videobuf_dvb *dvb,
138 struct module *module,
139 void *adapter_priv)
140{
141 int result;
142
143 init_MUTEX(&dvb->lock);
144
145 /* register adapter */
146 result = dvb_register_adapter(&dvb->adapter, dvb->name, module);
147 if (result < 0) {
148 printk(KERN_WARNING "%s: dvb_register_adapter failed (errno = %d)\n",
149 dvb->name, result);
150 goto fail_adapter;
151 }
152 dvb->adapter->priv = adapter_priv;
153
154 /* register frontend */
155 result = dvb_register_frontend(dvb->adapter, dvb->frontend);
156 if (result < 0) {
157 printk(KERN_WARNING "%s: dvb_register_frontend failed (errno = %d)\n",
158 dvb->name, result);
159 goto fail_frontend;
160 }
161
162 /* register demux stuff */
163 dvb->demux.dmx.capabilities =
164 DMX_TS_FILTERING | DMX_SECTION_FILTERING |
165 DMX_MEMORY_BASED_FILTERING;
166 dvb->demux.priv = dvb;
167 dvb->demux.filternum = 256;
168 dvb->demux.feednum = 256;
169 dvb->demux.start_feed = videobuf_dvb_start_feed;
170 dvb->demux.stop_feed = videobuf_dvb_stop_feed;
171 result = dvb_dmx_init(&dvb->demux);
172 if (result < 0) {
173 printk(KERN_WARNING "%s: dvb_dmx_init failed (errno = %d)\n",
174 dvb->name, result);
175 goto fail_dmx;
176 }
177
178 dvb->dmxdev.filternum = 256;
179 dvb->dmxdev.demux = &dvb->demux.dmx;
180 dvb->dmxdev.capabilities = 0;
181 result = dvb_dmxdev_init(&dvb->dmxdev, dvb->adapter);
182 if (result < 0) {
183 printk(KERN_WARNING "%s: dvb_dmxdev_init failed (errno = %d)\n",
184 dvb->name, result);
185 goto fail_dmxdev;
186 }
187
188 dvb->fe_hw.source = DMX_FRONTEND_0;
189 result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_hw);
190 if (result < 0) {
191 printk(KERN_WARNING "%s: add_frontend failed (DMX_FRONTEND_0, errno = %d)\n",
192 dvb->name, result);
193 goto fail_fe_hw;
194 }
195
196 dvb->fe_mem.source = DMX_MEMORY_FE;
197 result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_mem);
198 if (result < 0) {
199 printk(KERN_WARNING "%s: add_frontend failed (DMX_MEMORY_FE, errno = %d)\n",
200 dvb->name, result);
201 goto fail_fe_mem;
202 }
203
204 result = dvb->demux.dmx.connect_frontend(&dvb->demux.dmx, &dvb->fe_hw);
205 if (result < 0) {
206 printk(KERN_WARNING "%s: connect_frontend failed (errno = %d)\n",
207 dvb->name, result);
208 goto fail_fe_conn;
209 }
210
211 /* register network adapter */
212 dvb_net_init(dvb->adapter, &dvb->net, &dvb->demux.dmx);
213 return 0;
214
215fail_fe_conn:
216 dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem);
217fail_fe_mem:
218 dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw);
219fail_fe_hw:
220 dvb_dmxdev_release(&dvb->dmxdev);
221fail_dmxdev:
222 dvb_dmx_release(&dvb->demux);
223fail_dmx:
224 dvb_unregister_frontend(dvb->frontend);
225fail_frontend:
226 dvb_unregister_adapter(dvb->adapter);
227fail_adapter:
228 return result;
229}
230
231void videobuf_dvb_unregister(struct videobuf_dvb *dvb)
232{
233 dvb_net_release(&dvb->net);
234 dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem);
235 dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw);
236 dvb_dmxdev_release(&dvb->dmxdev);
237 dvb_dmx_release(&dvb->demux);
238 dvb_unregister_frontend(dvb->frontend);
239 dvb_unregister_adapter(dvb->adapter);
240}
241
242EXPORT_SYMBOL(videobuf_dvb_register);
243EXPORT_SYMBOL(videobuf_dvb_unregister);
244
245/* ------------------------------------------------------------------ */
246/*
247 * Local variables:
248 * c-basic-offset: 8
249 * compile-command: "make DVB=1"
250 * End:
251 */
diff --git a/drivers/media/video/video-buf.c b/drivers/media/video/video-buf.c
new file mode 100644
index 00000000000..5afdc785261
--- /dev/null
+++ b/drivers/media/video/video-buf.c
@@ -0,0 +1,1290 @@
1/*
2 * $Id: video-buf.c,v 1.18 2005/02/24 13:32:30 kraxel Exp $
3 *
4 * generic helper functions for video4linux capture buffers, to handle
5 * memory management and PCI DMA. Right now bttv + saa7134 use it.
6 *
7 * The functions expect the hardware being able to scatter gatter
8 * (i.e. the buffers are not linear in physical memory, but fragmented
9 * into PAGE_SIZE chunks). They also assume the driver does not need
10 * to touch the video data (thus it is probably not useful for USB 1.1
11 * as data often must be uncompressed by the drivers).
12 *
13 * (c) 2001-2004 Gerd Knorr <kraxel@bytesex.org> [SUSE Labs]
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 */
20
21#include <linux/init.h>
22#include <linux/module.h>
23#include <linux/moduleparam.h>
24#include <linux/vmalloc.h>
25#include <linux/pagemap.h>
26#include <linux/slab.h>
27#include <linux/pci.h>
28#include <linux/interrupt.h>
29#include <asm/page.h>
30#include <asm/pgtable.h>
31
32#include <media/video-buf.h>
33
34#define MAGIC_DMABUF 0x19721112
35#define MAGIC_BUFFER 0x20040302
36#define MAGIC_CHECK(is,should) if (unlikely((is) != (should))) \
37 { printk(KERN_ERR "magic mismatch: %x (expected %x)\n",is,should); BUG(); }
38
39static int debug = 0;
40module_param(debug, int, 0644);
41
42MODULE_DESCRIPTION("helper module to manage video4linux pci dma buffers");
43MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
44MODULE_LICENSE("GPL");
45
46#define dprintk(level, fmt, arg...) if (debug >= level) \
47 printk(KERN_DEBUG "vbuf: " fmt , ## arg)
48
49struct scatterlist*
50videobuf_vmalloc_to_sg(unsigned char *virt, int nr_pages)
51{
52 struct scatterlist *sglist;
53 struct page *pg;
54 int i;
55
56 sglist = kmalloc(sizeof(struct scatterlist)*nr_pages, GFP_KERNEL);
57 if (NULL == sglist)
58 return NULL;
59 memset(sglist,0,sizeof(struct scatterlist)*nr_pages);
60 for (i = 0; i < nr_pages; i++, virt += PAGE_SIZE) {
61 pg = vmalloc_to_page(virt);
62 if (NULL == pg)
63 goto err;
64 if (PageHighMem(pg))
65 BUG();
66 sglist[i].page = pg;
67 sglist[i].length = PAGE_SIZE;
68 }
69 return sglist;
70
71 err:
72 kfree(sglist);
73 return NULL;
74}
75
76struct scatterlist*
77videobuf_pages_to_sg(struct page **pages, int nr_pages, int offset)
78{
79 struct scatterlist *sglist;
80 int i = 0;
81
82 if (NULL == pages[0])
83 return NULL;
84 sglist = kmalloc(sizeof(*sglist) * nr_pages, GFP_KERNEL);
85 if (NULL == sglist)
86 return NULL;
87 memset(sglist, 0, sizeof(*sglist) * nr_pages);
88
89 if (NULL == pages[0])
90 goto nopage;
91 if (PageHighMem(pages[0]))
92 /* DMA to highmem pages might not work */
93 goto highmem;
94 sglist[0].page = pages[0];
95 sglist[0].offset = offset;
96 sglist[0].length = PAGE_SIZE - offset;
97 for (i = 1; i < nr_pages; i++) {
98 if (NULL == pages[i])
99 goto nopage;
100 if (PageHighMem(pages[i]))
101 goto highmem;
102 sglist[i].page = pages[i];
103 sglist[i].length = PAGE_SIZE;
104 }
105 return sglist;
106
107 nopage:
108 dprintk(2,"sgl: oops - no page\n");
109 kfree(sglist);
110 return NULL;
111
112 highmem:
113 dprintk(2,"sgl: oops - highmem page\n");
114 kfree(sglist);
115 return NULL;
116}
117
118/* --------------------------------------------------------------------- */
119
120void videobuf_dma_init(struct videobuf_dmabuf *dma)
121{
122 memset(dma,0,sizeof(*dma));
123 dma->magic = MAGIC_DMABUF;
124}
125
126int videobuf_dma_init_user(struct videobuf_dmabuf *dma, int direction,
127 unsigned long data, unsigned long size)
128{
129 unsigned long first,last;
130 int err, rw = 0;
131
132 dma->direction = direction;
133 switch (dma->direction) {
134 case PCI_DMA_FROMDEVICE: rw = READ; break;
135 case PCI_DMA_TODEVICE: rw = WRITE; break;
136 default: BUG();
137 }
138
139 first = (data & PAGE_MASK) >> PAGE_SHIFT;
140 last = ((data+size-1) & PAGE_MASK) >> PAGE_SHIFT;
141 dma->offset = data & ~PAGE_MASK;
142 dma->nr_pages = last-first+1;
143 dma->pages = kmalloc(dma->nr_pages * sizeof(struct page*),
144 GFP_KERNEL);
145 if (NULL == dma->pages)
146 return -ENOMEM;
147 dprintk(1,"init user [0x%lx+0x%lx => %d pages]\n",
148 data,size,dma->nr_pages);
149
150 down_read(&current->mm->mmap_sem);
151 err = get_user_pages(current,current->mm,
152 data & PAGE_MASK, dma->nr_pages,
153 rw == READ, 1, /* force */
154 dma->pages, NULL);
155 up_read(&current->mm->mmap_sem);
156 if (err != dma->nr_pages) {
157 dma->nr_pages = (err >= 0) ? err : 0;
158 dprintk(1,"get_user_pages: err=%d [%d]\n",err,dma->nr_pages);
159 return err < 0 ? err : -EINVAL;
160 }
161 return 0;
162}
163
164int videobuf_dma_init_kernel(struct videobuf_dmabuf *dma, int direction,
165 int nr_pages)
166{
167 dprintk(1,"init kernel [%d pages]\n",nr_pages);
168 dma->direction = direction;
169 dma->vmalloc = vmalloc_32(nr_pages << PAGE_SHIFT);
170 if (NULL == dma->vmalloc) {
171 dprintk(1,"vmalloc_32(%d pages) failed\n",nr_pages);
172 return -ENOMEM;
173 }
174 memset(dma->vmalloc,0,nr_pages << PAGE_SHIFT);
175 dma->nr_pages = nr_pages;
176 return 0;
177}
178
179int videobuf_dma_init_overlay(struct videobuf_dmabuf *dma, int direction,
180 dma_addr_t addr, int nr_pages)
181{
182 dprintk(1,"init overlay [%d pages @ bus 0x%lx]\n",
183 nr_pages,(unsigned long)addr);
184 dma->direction = direction;
185 if (0 == addr)
186 return -EINVAL;
187
188 dma->bus_addr = addr;
189 dma->nr_pages = nr_pages;
190 return 0;
191}
192
193int videobuf_dma_pci_map(struct pci_dev *dev, struct videobuf_dmabuf *dma)
194{
195 MAGIC_CHECK(dma->magic,MAGIC_DMABUF);
196 BUG_ON(0 == dma->nr_pages);
197
198 if (dma->pages) {
199 dma->sglist = videobuf_pages_to_sg(dma->pages, dma->nr_pages,
200 dma->offset);
201 }
202 if (dma->vmalloc) {
203 dma->sglist = videobuf_vmalloc_to_sg
204 (dma->vmalloc,dma->nr_pages);
205 }
206 if (dma->bus_addr) {
207 dma->sglist = kmalloc(sizeof(struct scatterlist), GFP_KERNEL);
208 if (NULL != dma->sglist) {
209 dma->sglen = 1;
210 sg_dma_address(&dma->sglist[0]) = dma->bus_addr & PAGE_MASK;
211 dma->sglist[0].offset = dma->bus_addr & ~PAGE_MASK;
212 sg_dma_len(&dma->sglist[0]) = dma->nr_pages * PAGE_SIZE;
213 }
214 }
215 if (NULL == dma->sglist) {
216 dprintk(1,"scatterlist is NULL\n");
217 return -ENOMEM;
218 }
219
220 if (!dma->bus_addr) {
221 dma->sglen = pci_map_sg(dev,dma->sglist,dma->nr_pages,
222 dma->direction);
223 if (0 == dma->sglen) {
224 printk(KERN_WARNING
225 "%s: pci_map_sg failed\n",__FUNCTION__);
226 kfree(dma->sglist);
227 dma->sglist = NULL;
228 dma->sglen = 0;
229 return -EIO;
230 }
231 }
232 return 0;
233}
234
235int videobuf_dma_pci_sync(struct pci_dev *dev, struct videobuf_dmabuf *dma)
236{
237 MAGIC_CHECK(dma->magic,MAGIC_DMABUF);
238 BUG_ON(!dma->sglen);
239
240 if (!dma->bus_addr)
241 pci_dma_sync_sg_for_cpu(dev,dma->sglist,dma->nr_pages,dma->direction);
242 return 0;
243}
244
245int videobuf_dma_pci_unmap(struct pci_dev *dev, struct videobuf_dmabuf *dma)
246{
247 MAGIC_CHECK(dma->magic,MAGIC_DMABUF);
248 if (!dma->sglen)
249 return 0;
250
251 if (!dma->bus_addr)
252 pci_unmap_sg(dev,dma->sglist,dma->nr_pages,dma->direction);
253 kfree(dma->sglist);
254 dma->sglist = NULL;
255 dma->sglen = 0;
256 return 0;
257}
258
259int videobuf_dma_free(struct videobuf_dmabuf *dma)
260{
261 MAGIC_CHECK(dma->magic,MAGIC_DMABUF);
262 BUG_ON(dma->sglen);
263
264 if (dma->pages) {
265 int i;
266 for (i=0; i < dma->nr_pages; i++)
267 page_cache_release(dma->pages[i]);
268 kfree(dma->pages);
269 dma->pages = NULL;
270 }
271 if (dma->vmalloc) {
272 vfree(dma->vmalloc);
273 dma->vmalloc = NULL;
274 }
275 if (dma->bus_addr) {
276 dma->bus_addr = 0;
277 }
278 dma->direction = PCI_DMA_NONE;
279 return 0;
280}
281
282/* --------------------------------------------------------------------- */
283
284void* videobuf_alloc(unsigned int size)
285{
286 struct videobuf_buffer *vb;
287
288 vb = kmalloc(size,GFP_KERNEL);
289 if (NULL != vb) {
290 memset(vb,0,size);
291 videobuf_dma_init(&vb->dma);
292 init_waitqueue_head(&vb->done);
293 vb->magic = MAGIC_BUFFER;
294 }
295 return vb;
296}
297
298int videobuf_waiton(struct videobuf_buffer *vb, int non_blocking, int intr)
299{
300 int retval = 0;
301 DECLARE_WAITQUEUE(wait, current);
302
303 MAGIC_CHECK(vb->magic,MAGIC_BUFFER);
304 add_wait_queue(&vb->done, &wait);
305 while (vb->state == STATE_ACTIVE || vb->state == STATE_QUEUED) {
306 if (non_blocking) {
307 retval = -EAGAIN;
308 break;
309 }
310 set_current_state(intr ? TASK_INTERRUPTIBLE
311 : TASK_UNINTERRUPTIBLE);
312 if (vb->state == STATE_ACTIVE || vb->state == STATE_QUEUED)
313 schedule();
314 set_current_state(TASK_RUNNING);
315 if (intr && signal_pending(current)) {
316 dprintk(1,"buffer waiton: -EINTR\n");
317 retval = -EINTR;
318 break;
319 }
320 }
321 remove_wait_queue(&vb->done, &wait);
322 return retval;
323}
324
325int
326videobuf_iolock(struct pci_dev *pci, struct videobuf_buffer *vb,
327 struct v4l2_framebuffer *fbuf)
328{
329 int err,pages;
330 dma_addr_t bus;
331
332 MAGIC_CHECK(vb->magic,MAGIC_BUFFER);
333 switch (vb->memory) {
334 case V4L2_MEMORY_MMAP:
335 case V4L2_MEMORY_USERPTR:
336 if (0 == vb->baddr) {
337 /* no userspace addr -- kernel bounce buffer */
338 pages = PAGE_ALIGN(vb->size) >> PAGE_SHIFT;
339 err = videobuf_dma_init_kernel(&vb->dma,PCI_DMA_FROMDEVICE,
340 pages);
341 if (0 != err)
342 return err;
343 } else {
344 /* dma directly to userspace */
345 err = videobuf_dma_init_user(&vb->dma,PCI_DMA_FROMDEVICE,
346 vb->baddr,vb->bsize);
347 if (0 != err)
348 return err;
349 }
350 break;
351 case V4L2_MEMORY_OVERLAY:
352 if (NULL == fbuf)
353 return -EINVAL;
354 /* FIXME: need sanity checks for vb->boff */
355 bus = (dma_addr_t)fbuf->base + vb->boff;
356 pages = PAGE_ALIGN(vb->size) >> PAGE_SHIFT;
357 err = videobuf_dma_init_overlay(&vb->dma,PCI_DMA_FROMDEVICE,
358 bus, pages);
359 if (0 != err)
360 return err;
361 break;
362 default:
363 BUG();
364 }
365 err = videobuf_dma_pci_map(pci,&vb->dma);
366 if (0 != err)
367 return err;
368
369 return 0;
370}
371
372/* --------------------------------------------------------------------- */
373
374void videobuf_queue_init(struct videobuf_queue* q,
375 struct videobuf_queue_ops *ops,
376 struct pci_dev *pci,
377 spinlock_t *irqlock,
378 enum v4l2_buf_type type,
379 enum v4l2_field field,
380 unsigned int msize,
381 void *priv)
382{
383 memset(q,0,sizeof(*q));
384 q->irqlock = irqlock;
385 q->pci = pci;
386 q->type = type;
387 q->field = field;
388 q->msize = msize;
389 q->ops = ops;
390 q->priv_data = priv;
391
392 init_MUTEX(&q->lock);
393 INIT_LIST_HEAD(&q->stream);
394}
395
396int
397videobuf_queue_is_busy(struct videobuf_queue *q)
398{
399 int i;
400
401 if (q->streaming) {
402 dprintk(1,"busy: streaming active\n");
403 return 1;
404 }
405 if (q->reading) {
406 dprintk(1,"busy: pending read #1\n");
407 return 1;
408 }
409 if (q->read_buf) {
410 dprintk(1,"busy: pending read #2\n");
411 return 1;
412 }
413 for (i = 0; i < VIDEO_MAX_FRAME; i++) {
414 if (NULL == q->bufs[i])
415 continue;
416 if (q->bufs[i]->map) {
417 dprintk(1,"busy: buffer #%d mapped\n",i);
418 return 1;
419 }
420 if (q->bufs[i]->state == STATE_QUEUED) {
421 dprintk(1,"busy: buffer #%d queued\n",i);
422 return 1;
423 }
424 if (q->bufs[i]->state == STATE_ACTIVE) {
425 dprintk(1,"busy: buffer #%d avtive\n",i);
426 return 1;
427 }
428 }
429 return 0;
430}
431
432void
433videobuf_queue_cancel(struct videobuf_queue *q)
434{
435 unsigned long flags;
436 int i;
437
438 /* remove queued buffers from list */
439 spin_lock_irqsave(q->irqlock,flags);
440 for (i = 0; i < VIDEO_MAX_FRAME; i++) {
441 if (NULL == q->bufs[i])
442 continue;
443 if (q->bufs[i]->state == STATE_QUEUED) {
444 list_del(&q->bufs[i]->queue);
445 q->bufs[i]->state = STATE_ERROR;
446 }
447 }
448 spin_unlock_irqrestore(q->irqlock,flags);
449
450 /* free all buffers + clear queue */
451 for (i = 0; i < VIDEO_MAX_FRAME; i++) {
452 if (NULL == q->bufs[i])
453 continue;
454 q->ops->buf_release(q,q->bufs[i]);
455 }
456 INIT_LIST_HEAD(&q->stream);
457}
458
459/* --------------------------------------------------------------------- */
460
461enum v4l2_field
462videobuf_next_field(struct videobuf_queue *q)
463{
464 enum v4l2_field field = q->field;
465
466 BUG_ON(V4L2_FIELD_ANY == field);
467
468 if (V4L2_FIELD_ALTERNATE == field) {
469 if (V4L2_FIELD_TOP == q->last) {
470 field = V4L2_FIELD_BOTTOM;
471 q->last = V4L2_FIELD_BOTTOM;
472 } else {
473 field = V4L2_FIELD_TOP;
474 q->last = V4L2_FIELD_TOP;
475 }
476 }
477 return field;
478}
479
480void
481videobuf_status(struct v4l2_buffer *b, struct videobuf_buffer *vb,
482 enum v4l2_buf_type type)
483{
484 MAGIC_CHECK(vb->magic,MAGIC_BUFFER);
485
486 b->index = vb->i;
487 b->type = type;
488
489 b->memory = vb->memory;
490 switch (b->memory) {
491 case V4L2_MEMORY_MMAP:
492 b->m.offset = vb->boff;
493 b->length = vb->bsize;
494 break;
495 case V4L2_MEMORY_USERPTR:
496 b->m.userptr = vb->baddr;
497 b->length = vb->bsize;
498 break;
499 case V4L2_MEMORY_OVERLAY:
500 b->m.offset = vb->boff;
501 break;
502 }
503
504 b->flags = 0;
505 if (vb->map)
506 b->flags |= V4L2_BUF_FLAG_MAPPED;
507
508 switch (vb->state) {
509 case STATE_PREPARED:
510 case STATE_QUEUED:
511 case STATE_ACTIVE:
512 b->flags |= V4L2_BUF_FLAG_QUEUED;
513 break;
514 case STATE_DONE:
515 case STATE_ERROR:
516 b->flags |= V4L2_BUF_FLAG_DONE;
517 break;
518 case STATE_NEEDS_INIT:
519 case STATE_IDLE:
520 /* nothing */
521 break;
522 }
523
524 if (vb->input != UNSET) {
525 b->flags |= V4L2_BUF_FLAG_INPUT;
526 b->input = vb->input;
527 }
528
529 b->field = vb->field;
530 b->timestamp = vb->ts;
531 b->bytesused = vb->size;
532 b->sequence = vb->field_count >> 1;
533}
534
535int
536videobuf_reqbufs(struct videobuf_queue *q,
537 struct v4l2_requestbuffers *req)
538{
539 unsigned int size,count;
540 int retval;
541
542 if (req->type != q->type)
543 return -EINVAL;
544 if (req->count < 1)
545 return -EINVAL;
546 if (req->memory != V4L2_MEMORY_MMAP &&
547 req->memory != V4L2_MEMORY_USERPTR &&
548 req->memory != V4L2_MEMORY_OVERLAY)
549 return -EINVAL;
550
551 if (q->streaming)
552 return -EBUSY;
553 if (!list_empty(&q->stream))
554 return -EBUSY;
555
556 down(&q->lock);
557 count = req->count;
558 if (count > VIDEO_MAX_FRAME)
559 count = VIDEO_MAX_FRAME;
560 size = 0;
561 q->ops->buf_setup(q,&count,&size);
562 size = PAGE_ALIGN(size);
563 dprintk(1,"reqbufs: bufs=%d, size=0x%x [%d pages total]\n",
564 count, size, (count*size)>>PAGE_SHIFT);
565
566 retval = videobuf_mmap_setup(q,count,size,req->memory);
567 if (retval < 0)
568 goto done;
569
570 req->count = count;
571
572 done:
573 up(&q->lock);
574 return retval;
575}
576
577int
578videobuf_querybuf(struct videobuf_queue *q, struct v4l2_buffer *b)
579{
580 if (unlikely(b->type != q->type))
581 return -EINVAL;
582 if (unlikely(b->index < 0 || b->index >= VIDEO_MAX_FRAME))
583 return -EINVAL;
584 if (unlikely(NULL == q->bufs[b->index]))
585 return -EINVAL;
586 videobuf_status(b,q->bufs[b->index],q->type);
587 return 0;
588}
589
590int
591videobuf_qbuf(struct videobuf_queue *q,
592 struct v4l2_buffer *b)
593{
594 struct videobuf_buffer *buf;
595 enum v4l2_field field;
596 unsigned long flags;
597 int retval;
598
599 down(&q->lock);
600 retval = -EBUSY;
601 if (q->reading)
602 goto done;
603 retval = -EINVAL;
604 if (b->type != q->type)
605 goto done;
606 if (b->index < 0 || b->index >= VIDEO_MAX_FRAME)
607 goto done;
608 buf = q->bufs[b->index];
609 if (NULL == buf)
610 goto done;
611 MAGIC_CHECK(buf->magic,MAGIC_BUFFER);
612 if (buf->memory != b->memory)
613 goto done;
614 if (buf->state == STATE_QUEUED ||
615 buf->state == STATE_ACTIVE)
616 goto done;
617
618 if (b->flags & V4L2_BUF_FLAG_INPUT) {
619 if (b->input >= q->inputs)
620 goto done;
621 buf->input = b->input;
622 } else {
623 buf->input = UNSET;
624 }
625
626 switch (b->memory) {
627 case V4L2_MEMORY_MMAP:
628 if (0 == buf->baddr)
629 goto done;
630 break;
631 case V4L2_MEMORY_USERPTR:
632 if (b->length < buf->bsize)
633 goto done;
634 if (STATE_NEEDS_INIT != buf->state && buf->baddr != b->m.userptr)
635 q->ops->buf_release(q,buf);
636 buf->baddr = b->m.userptr;
637 break;
638 case V4L2_MEMORY_OVERLAY:
639 buf->boff = b->m.offset;
640 break;
641 default:
642 goto done;
643 }
644
645 field = videobuf_next_field(q);
646 retval = q->ops->buf_prepare(q,buf,field);
647 if (0 != retval)
648 goto done;
649
650 list_add_tail(&buf->stream,&q->stream);
651 if (q->streaming) {
652 spin_lock_irqsave(q->irqlock,flags);
653 q->ops->buf_queue(q,buf);
654 spin_unlock_irqrestore(q->irqlock,flags);
655 }
656 retval = 0;
657
658 done:
659 up(&q->lock);
660 return retval;
661}
662
663int
664videobuf_dqbuf(struct videobuf_queue *q,
665 struct v4l2_buffer *b, int nonblocking)
666{
667 struct videobuf_buffer *buf;
668 int retval;
669
670 down(&q->lock);
671 retval = -EBUSY;
672 if (q->reading)
673 goto done;
674 retval = -EINVAL;
675 if (b->type != q->type)
676 goto done;
677 if (list_empty(&q->stream))
678 goto done;
679 buf = list_entry(q->stream.next, struct videobuf_buffer, stream);
680 retval = videobuf_waiton(buf, nonblocking, 1);
681 if (retval < 0)
682 goto done;
683 switch (buf->state) {
684 case STATE_ERROR:
685 retval = -EIO;
686 /* fall through */
687 case STATE_DONE:
688 videobuf_dma_pci_sync(q->pci,&buf->dma);
689 buf->state = STATE_IDLE;
690 break;
691 default:
692 retval = -EINVAL;
693 goto done;
694 }
695 list_del(&buf->stream);
696 memset(b,0,sizeof(*b));
697 videobuf_status(b,buf,q->type);
698
699 done:
700 up(&q->lock);
701 return retval;
702}
703
704int videobuf_streamon(struct videobuf_queue *q)
705{
706 struct videobuf_buffer *buf;
707 struct list_head *list;
708 unsigned long flags;
709 int retval;
710
711 down(&q->lock);
712 retval = -EBUSY;
713 if (q->reading)
714 goto done;
715 retval = 0;
716 if (q->streaming)
717 goto done;
718 q->streaming = 1;
719 spin_lock_irqsave(q->irqlock,flags);
720 list_for_each(list,&q->stream) {
721 buf = list_entry(list, struct videobuf_buffer, stream);
722 if (buf->state == STATE_PREPARED)
723 q->ops->buf_queue(q,buf);
724 }
725 spin_unlock_irqrestore(q->irqlock,flags);
726
727 done:
728 up(&q->lock);
729 return retval;
730}
731
732int videobuf_streamoff(struct videobuf_queue *q)
733{
734 int retval = -EINVAL;
735
736 down(&q->lock);
737 if (!q->streaming)
738 goto done;
739 videobuf_queue_cancel(q);
740 q->streaming = 0;
741 retval = 0;
742
743 done:
744 up(&q->lock);
745 return retval;
746}
747
748static ssize_t
749videobuf_read_zerocopy(struct videobuf_queue *q, char __user *data,
750 size_t count, loff_t *ppos)
751{
752 enum v4l2_field field;
753 unsigned long flags;
754 int retval;
755
756 /* setup stuff */
757 retval = -ENOMEM;
758 q->read_buf = videobuf_alloc(q->msize);
759 if (NULL == q->read_buf)
760 goto done;
761
762 q->read_buf->memory = V4L2_MEMORY_USERPTR;
763 q->read_buf->baddr = (unsigned long)data;
764 q->read_buf->bsize = count;
765 field = videobuf_next_field(q);
766 retval = q->ops->buf_prepare(q,q->read_buf,field);
767 if (0 != retval)
768 goto done;
769
770 /* start capture & wait */
771 spin_lock_irqsave(q->irqlock,flags);
772 q->ops->buf_queue(q,q->read_buf);
773 spin_unlock_irqrestore(q->irqlock,flags);
774 retval = videobuf_waiton(q->read_buf,0,0);
775 if (0 == retval) {
776 videobuf_dma_pci_sync(q->pci,&q->read_buf->dma);
777 if (STATE_ERROR == q->read_buf->state)
778 retval = -EIO;
779 else
780 retval = q->read_buf->size;
781 }
782
783 done:
784 /* cleanup */
785 q->ops->buf_release(q,q->read_buf);
786 kfree(q->read_buf);
787 q->read_buf = NULL;
788 return retval;
789}
790
791ssize_t videobuf_read_one(struct videobuf_queue *q,
792 char __user *data, size_t count, loff_t *ppos,
793 int nonblocking)
794{
795 enum v4l2_field field;
796 unsigned long flags;
797 unsigned size, nbufs, bytes;
798 int retval;
799
800 down(&q->lock);
801
802 nbufs = 1; size = 0;
803 q->ops->buf_setup(q,&nbufs,&size);
804 if (NULL == q->read_buf &&
805 count >= size &&
806 !nonblocking) {
807 retval = videobuf_read_zerocopy(q,data,count,ppos);
808 if (retval >= 0 || retval == -EIO)
809 /* ok, all done */
810 goto done;
811 /* fallback to kernel bounce buffer on failures */
812 }
813
814 if (NULL == q->read_buf) {
815 /* need to capture a new frame */
816 retval = -ENOMEM;
817 q->read_buf = videobuf_alloc(q->msize);
818 if (NULL == q->read_buf)
819 goto done;
820 q->read_buf->memory = V4L2_MEMORY_USERPTR;
821 field = videobuf_next_field(q);
822 retval = q->ops->buf_prepare(q,q->read_buf,field);
823 if (0 != retval)
824 goto done;
825 spin_lock_irqsave(q->irqlock,flags);
826 q->ops->buf_queue(q,q->read_buf);
827 spin_unlock_irqrestore(q->irqlock,flags);
828 q->read_off = 0;
829 }
830
831 /* wait until capture is done */
832 retval = videobuf_waiton(q->read_buf, nonblocking, 1);
833 if (0 != retval)
834 goto done;
835 videobuf_dma_pci_sync(q->pci,&q->read_buf->dma);
836
837 if (STATE_ERROR == q->read_buf->state) {
838 /* catch I/O errors */
839 q->ops->buf_release(q,q->read_buf);
840 kfree(q->read_buf);
841 q->read_buf = NULL;
842 retval = -EIO;
843 goto done;
844 }
845
846 /* copy to userspace */
847 bytes = count;
848 if (bytes > q->read_buf->size - q->read_off)
849 bytes = q->read_buf->size - q->read_off;
850 retval = -EFAULT;
851 if (copy_to_user(data, q->read_buf->dma.vmalloc+q->read_off, bytes))
852 goto done;
853
854 retval = bytes;
855 q->read_off += bytes;
856 if (q->read_off == q->read_buf->size) {
857 /* all data copied, cleanup */
858 q->ops->buf_release(q,q->read_buf);
859 kfree(q->read_buf);
860 q->read_buf = NULL;
861 }
862
863 done:
864 up(&q->lock);
865 return retval;
866}
867
868int videobuf_read_start(struct videobuf_queue *q)
869{
870 enum v4l2_field field;
871 unsigned long flags;
872 int count = 0, size = 0;
873 int err, i;
874
875 q->ops->buf_setup(q,&count,&size);
876 if (count < 2)
877 count = 2;
878 if (count > VIDEO_MAX_FRAME)
879 count = VIDEO_MAX_FRAME;
880 size = PAGE_ALIGN(size);
881
882 err = videobuf_mmap_setup(q, count, size, V4L2_MEMORY_USERPTR);
883 if (err)
884 return err;
885 for (i = 0; i < count; i++) {
886 field = videobuf_next_field(q);
887 err = q->ops->buf_prepare(q,q->bufs[i],field);
888 if (err)
889 return err;
890 list_add_tail(&q->bufs[i]->stream, &q->stream);
891 }
892 spin_lock_irqsave(q->irqlock,flags);
893 for (i = 0; i < count; i++)
894 q->ops->buf_queue(q,q->bufs[i]);
895 spin_unlock_irqrestore(q->irqlock,flags);
896 q->reading = 1;
897 return 0;
898}
899
900void videobuf_read_stop(struct videobuf_queue *q)
901{
902 int i;
903
904 videobuf_queue_cancel(q);
905 videobuf_mmap_free(q);
906 INIT_LIST_HEAD(&q->stream);
907 for (i = 0; i < VIDEO_MAX_FRAME; i++) {
908 if (NULL == q->bufs[i])
909 continue;
910 kfree(q->bufs[i]);
911 q->bufs[i] = NULL;
912 }
913 q->read_buf = NULL;
914 q->reading = 0;
915}
916
917ssize_t videobuf_read_stream(struct videobuf_queue *q,
918 char __user *data, size_t count, loff_t *ppos,
919 int vbihack, int nonblocking)
920{
921 unsigned int *fc, bytes;
922 int err, retval;
923 unsigned long flags;
924
925 dprintk(2,"%s\n",__FUNCTION__);
926 down(&q->lock);
927 retval = -EBUSY;
928 if (q->streaming)
929 goto done;
930 if (!q->reading) {
931 retval = videobuf_read_start(q);
932 if (retval < 0)
933 goto done;
934 }
935
936 retval = 0;
937 while (count > 0) {
938 /* get / wait for data */
939 if (NULL == q->read_buf) {
940 q->read_buf = list_entry(q->stream.next,
941 struct videobuf_buffer,
942 stream);
943 list_del(&q->read_buf->stream);
944 q->read_off = 0;
945 }
946 err = videobuf_waiton(q->read_buf, nonblocking, 1);
947 if (err < 0) {
948 if (0 == retval)
949 retval = err;
950 break;
951 }
952
953 if (q->read_buf->state == STATE_DONE) {
954 if (vbihack) {
955 /* dirty, undocumented hack -- pass the frame counter
956 * within the last four bytes of each vbi data block.
957 * We need that one to maintain backward compatibility
958 * to all vbi decoding software out there ... */
959 fc = (unsigned int*)q->read_buf->dma.vmalloc;
960 fc += (q->read_buf->size>>2) -1;
961 *fc = q->read_buf->field_count >> 1;
962 dprintk(1,"vbihack: %d\n",*fc);
963 }
964
965 /* copy stuff */
966 bytes = count;
967 if (bytes > q->read_buf->size - q->read_off)
968 bytes = q->read_buf->size - q->read_off;
969 if (copy_to_user(data + retval,
970 q->read_buf->dma.vmalloc + q->read_off,
971 bytes)) {
972 if (0 == retval)
973 retval = -EFAULT;
974 break;
975 }
976 count -= bytes;
977 retval += bytes;
978 q->read_off += bytes;
979 } else {
980 /* some error */
981 q->read_off = q->read_buf->size;
982 if (0 == retval)
983 retval = -EIO;
984 }
985
986 /* requeue buffer when done with copying */
987 if (q->read_off == q->read_buf->size) {
988 list_add_tail(&q->read_buf->stream,
989 &q->stream);
990 spin_lock_irqsave(q->irqlock,flags);
991 q->ops->buf_queue(q,q->read_buf);
992 spin_unlock_irqrestore(q->irqlock,flags);
993 q->read_buf = NULL;
994 }
995 if (retval < 0)
996 break;
997 }
998
999 done:
1000 up(&q->lock);
1001 return retval;
1002}
1003
1004unsigned int videobuf_poll_stream(struct file *file,
1005 struct videobuf_queue *q,
1006 poll_table *wait)
1007{
1008 struct videobuf_buffer *buf = NULL;
1009 unsigned int rc = 0;
1010
1011 down(&q->lock);
1012 if (q->streaming) {
1013 if (!list_empty(&q->stream))
1014 buf = list_entry(q->stream.next,
1015 struct videobuf_buffer, stream);
1016 } else {
1017 if (!q->reading)
1018 videobuf_read_start(q);
1019 if (!q->reading) {
1020 rc = POLLERR;
1021 } else if (NULL == q->read_buf) {
1022 q->read_buf = list_entry(q->stream.next,
1023 struct videobuf_buffer,
1024 stream);
1025 list_del(&q->read_buf->stream);
1026 q->read_off = 0;
1027 }
1028 buf = q->read_buf;
1029 }
1030 if (!buf)
1031 rc = POLLERR;
1032
1033 if (0 == rc) {
1034 poll_wait(file, &buf->done, wait);
1035 if (buf->state == STATE_DONE ||
1036 buf->state == STATE_ERROR)
1037 rc = POLLIN|POLLRDNORM;
1038 }
1039 up(&q->lock);
1040 return rc;
1041}
1042
1043/* --------------------------------------------------------------------- */
1044
1045static void
1046videobuf_vm_open(struct vm_area_struct *vma)
1047{
1048 struct videobuf_mapping *map = vma->vm_private_data;
1049
1050 dprintk(2,"vm_open %p [count=%d,vma=%08lx-%08lx]\n",map,
1051 map->count,vma->vm_start,vma->vm_end);
1052 map->count++;
1053}
1054
1055static void
1056videobuf_vm_close(struct vm_area_struct *vma)
1057{
1058 struct videobuf_mapping *map = vma->vm_private_data;
1059 struct videobuf_queue *q = map->q;
1060 int i;
1061
1062 dprintk(2,"vm_close %p [count=%d,vma=%08lx-%08lx]\n",map,
1063 map->count,vma->vm_start,vma->vm_end);
1064
1065 map->count--;
1066 if (0 == map->count) {
1067 dprintk(1,"munmap %p q=%p\n",map,q);
1068 down(&q->lock);
1069 for (i = 0; i < VIDEO_MAX_FRAME; i++) {
1070 if (NULL == q->bufs[i])
1071 continue;
1072 if (q->bufs[i])
1073 ;
1074 if (q->bufs[i]->map != map)
1075 continue;
1076 q->bufs[i]->map = NULL;
1077 q->bufs[i]->baddr = 0;
1078 q->ops->buf_release(q,q->bufs[i]);
1079 }
1080 up(&q->lock);
1081 kfree(map);
1082 }
1083 return;
1084}
1085
1086/*
1087 * Get a anonymous page for the mapping. Make sure we can DMA to that
1088 * memory location with 32bit PCI devices (i.e. don't use highmem for
1089 * now ...). Bounce buffers don't work very well for the data rates
1090 * video capture has.
1091 */
1092static struct page*
1093videobuf_vm_nopage(struct vm_area_struct *vma, unsigned long vaddr,
1094 int *type)
1095{
1096 struct page *page;
1097
1098 dprintk(3,"nopage: fault @ %08lx [vma %08lx-%08lx]\n",
1099 vaddr,vma->vm_start,vma->vm_end);
1100 if (vaddr > vma->vm_end)
1101 return NOPAGE_SIGBUS;
1102 page = alloc_page(GFP_USER);
1103 if (!page)
1104 return NOPAGE_OOM;
1105 clear_user_page(page_address(page), vaddr, page);
1106 if (type)
1107 *type = VM_FAULT_MINOR;
1108 return page;
1109}
1110
1111static struct vm_operations_struct videobuf_vm_ops =
1112{
1113 .open = videobuf_vm_open,
1114 .close = videobuf_vm_close,
1115 .nopage = videobuf_vm_nopage,
1116};
1117
1118int videobuf_mmap_setup(struct videobuf_queue *q,
1119 unsigned int bcount, unsigned int bsize,
1120 enum v4l2_memory memory)
1121{
1122 unsigned int i;
1123 int err;
1124
1125 err = videobuf_mmap_free(q);
1126 if (0 != err)
1127 return err;
1128
1129 for (i = 0; i < bcount; i++) {
1130 q->bufs[i] = videobuf_alloc(q->msize);
1131 q->bufs[i]->i = i;
1132 q->bufs[i]->input = UNSET;
1133 q->bufs[i]->memory = memory;
1134 q->bufs[i]->bsize = bsize;
1135 switch (memory) {
1136 case V4L2_MEMORY_MMAP:
1137 q->bufs[i]->boff = bsize * i;
1138 break;
1139 case V4L2_MEMORY_USERPTR:
1140 case V4L2_MEMORY_OVERLAY:
1141 /* nothing */
1142 break;
1143 }
1144 }
1145 dprintk(1,"mmap setup: %d buffers, %d bytes each\n",
1146 bcount,bsize);
1147 return 0;
1148}
1149
1150int videobuf_mmap_free(struct videobuf_queue *q)
1151{
1152 int i;
1153
1154 for (i = 0; i < VIDEO_MAX_FRAME; i++)
1155 if (q->bufs[i] && q->bufs[i]->map)
1156 return -EBUSY;
1157 for (i = 0; i < VIDEO_MAX_FRAME; i++) {
1158 if (NULL == q->bufs[i])
1159 continue;
1160 q->ops->buf_release(q,q->bufs[i]);
1161 kfree(q->bufs[i]);
1162 q->bufs[i] = NULL;
1163 }
1164 return 0;
1165}
1166
1167int videobuf_mmap_mapper(struct videobuf_queue *q,
1168 struct vm_area_struct *vma)
1169{
1170 struct videobuf_mapping *map;
1171 unsigned int first,last,size,i;
1172 int retval;
1173
1174 down(&q->lock);
1175 retval = -EINVAL;
1176 if (!(vma->vm_flags & VM_WRITE)) {
1177 dprintk(1,"mmap app bug: PROT_WRITE please\n");
1178 goto done;
1179 }
1180 if (!(vma->vm_flags & VM_SHARED)) {
1181 dprintk(1,"mmap app bug: MAP_SHARED please\n");
1182 goto done;
1183 }
1184
1185 /* look for first buffer to map */
1186 for (first = 0; first < VIDEO_MAX_FRAME; first++) {
1187 if (NULL == q->bufs[first])
1188 continue;
1189 if (V4L2_MEMORY_MMAP != q->bufs[first]->memory)
1190 continue;
1191 if (q->bufs[first]->boff == (vma->vm_pgoff << PAGE_SHIFT))
1192 break;
1193 }
1194 if (VIDEO_MAX_FRAME == first) {
1195 dprintk(1,"mmap app bug: offset invalid [offset=0x%lx]\n",
1196 (vma->vm_pgoff << PAGE_SHIFT));
1197 goto done;
1198 }
1199
1200 /* look for last buffer to map */
1201 for (size = 0, last = first; last < VIDEO_MAX_FRAME; last++) {
1202 if (NULL == q->bufs[last])
1203 continue;
1204 if (V4L2_MEMORY_MMAP != q->bufs[last]->memory)
1205 continue;
1206 if (q->bufs[last]->map) {
1207 retval = -EBUSY;
1208 goto done;
1209 }
1210 size += q->bufs[last]->bsize;
1211 if (size == (vma->vm_end - vma->vm_start))
1212 break;
1213 }
1214 if (VIDEO_MAX_FRAME == last) {
1215 dprintk(1,"mmap app bug: size invalid [size=0x%lx]\n",
1216 (vma->vm_end - vma->vm_start));
1217 goto done;
1218 }
1219
1220 /* create mapping + update buffer list */
1221 retval = -ENOMEM;
1222 map = kmalloc(sizeof(struct videobuf_mapping),GFP_KERNEL);
1223 if (NULL == map)
1224 goto done;
1225 for (size = 0, i = first; i <= last; size += q->bufs[i++]->bsize) {
1226 q->bufs[i]->map = map;
1227 q->bufs[i]->baddr = vma->vm_start + size;
1228 }
1229 map->count = 1;
1230 map->start = vma->vm_start;
1231 map->end = vma->vm_end;
1232 map->q = q;
1233 vma->vm_ops = &videobuf_vm_ops;
1234 vma->vm_flags |= VM_DONTEXPAND | VM_RESERVED;
1235 vma->vm_flags &= ~VM_IO; /* using shared anonymous pages */
1236 vma->vm_private_data = map;
1237 dprintk(1,"mmap %p: q=%p %08lx-%08lx pgoff %08lx bufs %d-%d\n",
1238 map,q,vma->vm_start,vma->vm_end,vma->vm_pgoff,first,last);
1239 retval = 0;
1240
1241 done:
1242 up(&q->lock);
1243 return retval;
1244}
1245
1246/* --------------------------------------------------------------------- */
1247
1248EXPORT_SYMBOL_GPL(videobuf_vmalloc_to_sg);
1249
1250EXPORT_SYMBOL_GPL(videobuf_dma_init);
1251EXPORT_SYMBOL_GPL(videobuf_dma_init_user);
1252EXPORT_SYMBOL_GPL(videobuf_dma_init_kernel);
1253EXPORT_SYMBOL_GPL(videobuf_dma_init_overlay);
1254EXPORT_SYMBOL_GPL(videobuf_dma_pci_map);
1255EXPORT_SYMBOL_GPL(videobuf_dma_pci_sync);
1256EXPORT_SYMBOL_GPL(videobuf_dma_pci_unmap);
1257EXPORT_SYMBOL_GPL(videobuf_dma_free);
1258
1259EXPORT_SYMBOL_GPL(videobuf_alloc);
1260EXPORT_SYMBOL_GPL(videobuf_waiton);
1261EXPORT_SYMBOL_GPL(videobuf_iolock);
1262
1263EXPORT_SYMBOL_GPL(videobuf_queue_init);
1264EXPORT_SYMBOL_GPL(videobuf_queue_cancel);
1265EXPORT_SYMBOL_GPL(videobuf_queue_is_busy);
1266
1267EXPORT_SYMBOL_GPL(videobuf_next_field);
1268EXPORT_SYMBOL_GPL(videobuf_status);
1269EXPORT_SYMBOL_GPL(videobuf_reqbufs);
1270EXPORT_SYMBOL_GPL(videobuf_querybuf);
1271EXPORT_SYMBOL_GPL(videobuf_qbuf);
1272EXPORT_SYMBOL_GPL(videobuf_dqbuf);
1273EXPORT_SYMBOL_GPL(videobuf_streamon);
1274EXPORT_SYMBOL_GPL(videobuf_streamoff);
1275
1276EXPORT_SYMBOL_GPL(videobuf_read_start);
1277EXPORT_SYMBOL_GPL(videobuf_read_stop);
1278EXPORT_SYMBOL_GPL(videobuf_read_stream);
1279EXPORT_SYMBOL_GPL(videobuf_read_one);
1280EXPORT_SYMBOL_GPL(videobuf_poll_stream);
1281
1282EXPORT_SYMBOL_GPL(videobuf_mmap_setup);
1283EXPORT_SYMBOL_GPL(videobuf_mmap_free);
1284EXPORT_SYMBOL_GPL(videobuf_mmap_mapper);
1285
1286/*
1287 * Local variables:
1288 * c-basic-offset: 8
1289 * End:
1290 */
diff --git a/drivers/media/video/videocodec.c b/drivers/media/video/videocodec.c
new file mode 100644
index 00000000000..c9d5f1a873c
--- /dev/null
+++ b/drivers/media/video/videocodec.c
@@ -0,0 +1,490 @@
1/*
2 * VIDEO MOTION CODECs internal API for video devices
3 *
4 * Interface for MJPEG (and maybe later MPEG/WAVELETS) codec's
5 * bound to a master device.
6 *
7 * (c) 2002 Wolfgang Scherr <scherr@net4you.at>
8 *
9 * $Id: videocodec.c,v 1.1.2.8 2003/03/29 07:16:04 rbultje Exp $
10 *
11 * ------------------------------------------------------------------------
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 *
27 * ------------------------------------------------------------------------
28 */
29
30#define VIDEOCODEC_VERSION "v0.2"
31
32#include <linux/kernel.h>
33#include <linux/module.h>
34#include <linux/init.h>
35#include <linux/types.h>
36#include <linux/slab.h>
37
38// kernel config is here (procfs flag)
39#include <linux/config.h>
40
41#ifdef CONFIG_PROC_FS
42#include <linux/proc_fs.h>
43#include <asm/uaccess.h>
44#endif
45
46#include "videocodec.h"
47
48static int debug = 0;
49module_param(debug, int, 0);
50MODULE_PARM_DESC(debug, "Debug level (0-4)");
51
52#define dprintk(num, format, args...) \
53 do { \
54 if (debug >= num) \
55 printk(format, ##args); \
56 } while (0)
57
58struct attached_list {
59 struct videocodec *codec;
60 struct attached_list *next;
61};
62
63struct codec_list {
64 const struct videocodec *codec;
65 int attached;
66 struct attached_list *list;
67 struct codec_list *next;
68};
69
70static struct codec_list *codeclist_top = NULL;
71
72/* ================================================= */
73/* function prototypes of the master/slave interface */
74/* ================================================= */
75
76struct videocodec *
77videocodec_attach (struct videocodec_master *master)
78{
79 struct codec_list *h = codeclist_top;
80 struct attached_list *a, *ptr;
81 struct videocodec *codec;
82 int res;
83
84 if (!master) {
85 dprintk(1, KERN_ERR "videocodec_attach: no data\n");
86 return NULL;
87 }
88
89 dprintk(2,
90 "videocodec_attach: '%s', type: %x, flags %lx, magic %lx\n",
91 master->name, master->type, master->flags, master->magic);
92
93 if (!h) {
94 dprintk(1,
95 KERN_ERR
96 "videocodec_attach: no device available\n");
97 return NULL;
98 }
99
100 while (h) {
101 // attach only if the slave has at least the flags
102 // expected by the master
103 if ((master->flags & h->codec->flags) == master->flags) {
104 dprintk(4, "videocodec_attach: try '%s'\n",
105 h->codec->name);
106
107 if (!try_module_get(h->codec->owner))
108 return NULL;
109
110 codec =
111 kmalloc(sizeof(struct videocodec), GFP_KERNEL);
112 if (!codec) {
113 dprintk(1,
114 KERN_ERR
115 "videocodec_attach: no mem\n");
116 goto out_module_put;
117 }
118 memcpy(codec, h->codec, sizeof(struct videocodec));
119
120 snprintf(codec->name, sizeof(codec->name),
121 "%s[%d]", codec->name, h->attached);
122 codec->master_data = master;
123 res = codec->setup(codec);
124 if (res == 0) {
125 dprintk(3, "videocodec_attach '%s'\n",
126 codec->name);
127 ptr = (struct attached_list *)
128 kmalloc(sizeof(struct attached_list),
129 GFP_KERNEL);
130 if (!ptr) {
131 dprintk(1,
132 KERN_ERR
133 "videocodec_attach: no memory\n");
134 goto out_kfree;
135 }
136 memset(ptr, 0,
137 sizeof(struct attached_list));
138 ptr->codec = codec;
139
140 a = h->list;
141 if (!a) {
142 h->list = ptr;
143 dprintk(4,
144 "videocodec: first element\n");
145 } else {
146 while (a->next)
147 a = a->next; // find end
148 a->next = ptr;
149 dprintk(4,
150 "videocodec: in after '%s'\n",
151 h->codec->name);
152 }
153
154 h->attached += 1;
155 return codec;
156 } else {
157 kfree(codec);
158 }
159 }
160 h = h->next;
161 }
162
163 dprintk(1, KERN_ERR "videocodec_attach: no codec found!\n");
164 return NULL;
165
166 out_module_put:
167 module_put(h->codec->owner);
168 out_kfree:
169 kfree(codec);
170 return NULL;
171}
172
173int
174videocodec_detach (struct videocodec *codec)
175{
176 struct codec_list *h = codeclist_top;
177 struct attached_list *a, *prev;
178 int res;
179
180 if (!codec) {
181 dprintk(1, KERN_ERR "videocodec_detach: no data\n");
182 return -EINVAL;
183 }
184
185 dprintk(2,
186 "videocodec_detach: '%s', type: %x, flags %lx, magic %lx\n",
187 codec->name, codec->type, codec->flags, codec->magic);
188
189 if (!h) {
190 dprintk(1,
191 KERN_ERR "videocodec_detach: no device left...\n");
192 return -ENXIO;
193 }
194
195 while (h) {
196 a = h->list;
197 prev = NULL;
198 while (a) {
199 if (codec == a->codec) {
200 res = a->codec->unset(a->codec);
201 if (res >= 0) {
202 dprintk(3,
203 "videocodec_detach: '%s'\n",
204 a->codec->name);
205 a->codec->master_data = NULL;
206 } else {
207 dprintk(1,
208 KERN_ERR
209 "videocodec_detach: '%s'\n",
210 a->codec->name);
211 a->codec->master_data = NULL;
212 }
213 if (prev == NULL) {
214 h->list = a->next;
215 dprintk(4,
216 "videocodec: delete first\n");
217 } else {
218 prev->next = a->next;
219 dprintk(4,
220 "videocodec: delete middle\n");
221 }
222 module_put(a->codec->owner);
223 kfree(a->codec);
224 kfree(a);
225 h->attached -= 1;
226 return 0;
227 }
228 prev = a;
229 a = a->next;
230 }
231 h = h->next;
232 }
233
234 dprintk(1, KERN_ERR "videocodec_detach: given codec not found!\n");
235 return -EINVAL;
236}
237
238int
239videocodec_register (const struct videocodec *codec)
240{
241 struct codec_list *ptr, *h = codeclist_top;
242
243 if (!codec) {
244 dprintk(1, KERN_ERR "videocodec_register: no data!\n");
245 return -EINVAL;
246 }
247
248 dprintk(2,
249 "videocodec: register '%s', type: %x, flags %lx, magic %lx\n",
250 codec->name, codec->type, codec->flags, codec->magic);
251
252 ptr =
253 (struct codec_list *) kmalloc(sizeof(struct codec_list),
254 GFP_KERNEL);
255 if (!ptr) {
256 dprintk(1, KERN_ERR "videocodec_register: no memory\n");
257 return -ENOMEM;
258 }
259 memset(ptr, 0, sizeof(struct codec_list));
260 ptr->codec = codec;
261
262 if (!h) {
263 codeclist_top = ptr;
264 dprintk(4, "videocodec: hooked in as first element\n");
265 } else {
266 while (h->next)
267 h = h->next; // find the end
268 h->next = ptr;
269 dprintk(4, "videocodec: hooked in after '%s'\n",
270 h->codec->name);
271 }
272
273 return 0;
274}
275
276int
277videocodec_unregister (const struct videocodec *codec)
278{
279 struct codec_list *prev = NULL, *h = codeclist_top;
280
281 if (!codec) {
282 dprintk(1, KERN_ERR "videocodec_unregister: no data!\n");
283 return -EINVAL;
284 }
285
286 dprintk(2,
287 "videocodec: unregister '%s', type: %x, flags %lx, magic %lx\n",
288 codec->name, codec->type, codec->flags, codec->magic);
289
290 if (!h) {
291 dprintk(1,
292 KERN_ERR
293 "videocodec_unregister: no device left...\n");
294 return -ENXIO;
295 }
296
297 while (h) {
298 if (codec == h->codec) {
299 if (h->attached) {
300 dprintk(1,
301 KERN_ERR
302 "videocodec: '%s' is used\n",
303 h->codec->name);
304 return -EBUSY;
305 }
306 dprintk(3, "videocodec: unregister '%s' is ok.\n",
307 h->codec->name);
308 if (prev == NULL) {
309 codeclist_top = h->next;
310 dprintk(4,
311 "videocodec: delete first element\n");
312 } else {
313 prev->next = h->next;
314 dprintk(4,
315 "videocodec: delete middle element\n");
316 }
317 kfree(h);
318 return 0;
319 }
320 prev = h;
321 h = h->next;
322 }
323
324 dprintk(1,
325 KERN_ERR
326 "videocodec_unregister: given codec not found!\n");
327 return -EINVAL;
328}
329
330#ifdef CONFIG_PROC_FS
331/* ============ */
332/* procfs stuff */
333/* ============ */
334
335static char *videocodec_buf = NULL;
336static int videocodec_bufsize = 0;
337
338static int
339videocodec_build_table (void)
340{
341 struct codec_list *h = codeclist_top;
342 struct attached_list *a;
343 int i = 0, size;
344
345 // sum up amount of slaves plus their attached masters
346 while (h) {
347 i += h->attached + 1;
348 h = h->next;
349 }
350#define LINESIZE 100
351 size = LINESIZE * (i + 1);
352
353 dprintk(3, "videocodec_build table: %d entries, %d bytes\n", i,
354 size);
355
356 if (videocodec_buf)
357 kfree(videocodec_buf);
358 videocodec_buf = (char *) kmalloc(size, GFP_KERNEL);
359
360 i = 0;
361 i += scnprintf(videocodec_buf + i, size - 1,
362 "<S>lave or attached <M>aster name type flags magic ");
363 i += scnprintf(videocodec_buf + i, size -i - 1, "(connected as)\n");
364
365 h = codeclist_top;
366 while (h) {
367 if (i > (size - LINESIZE))
368 break; // security check
369 i += scnprintf(videocodec_buf + i, size -i -1,
370 "S %32s %04x %08lx %08lx (TEMPLATE)\n",
371 h->codec->name, h->codec->type,
372 h->codec->flags, h->codec->magic);
373 a = h->list;
374 while (a) {
375 if (i > (size - LINESIZE))
376 break; // security check
377 i += scnprintf(videocodec_buf + i, size -i -1,
378 "M %32s %04x %08lx %08lx (%s)\n",
379 a->codec->master_data->name,
380 a->codec->master_data->type,
381 a->codec->master_data->flags,
382 a->codec->master_data->magic,
383 a->codec->name);
384 a = a->next;
385 }
386 h = h->next;
387 }
388
389 return i;
390}
391
392//The definition:
393//typedef int (read_proc_t)(char *page, char **start, off_t off,
394// int count, int *eof, void *data);
395
396static int
397videocodec_info (char *buffer,
398 char **buffer_location,
399 off_t offset,
400 int buffer_length,
401 int *eof,
402 void *data)
403{
404 int size;
405
406 dprintk(3, "videocodec_info: offset: %ld, len %d / size %d\n",
407 offset, buffer_length, videocodec_bufsize);
408
409 if (offset == 0) {
410 videocodec_bufsize = videocodec_build_table();
411 }
412 if ((offset < 0) || (offset >= videocodec_bufsize)) {
413 dprintk(4,
414 "videocodec_info: call delivers no result, return 0\n");
415 *eof = 1;
416 return 0;
417 }
418
419 if (buffer_length < (videocodec_bufsize - offset)) {
420 dprintk(4, "videocodec_info: %ld needed, %d got\n",
421 videocodec_bufsize - offset, buffer_length);
422 size = buffer_length;
423 } else {
424 dprintk(4, "videocodec_info: last reading of %ld bytes\n",
425 videocodec_bufsize - offset);
426 size = videocodec_bufsize - offset;
427 *eof = 1;
428 }
429
430 memcpy(buffer, videocodec_buf + offset, size);
431 /* doesn't work... */
432 /* copy_to_user(buffer, videocodec_buf+offset, size); */
433 /* *buffer_location = videocodec_buf+offset; */
434
435 return size;
436}
437#endif
438
439/* ===================== */
440/* hook in driver module */
441/* ===================== */
442static int __init
443videocodec_init (void)
444{
445#ifdef CONFIG_PROC_FS
446 static struct proc_dir_entry *videocodec_proc_entry;
447#endif
448
449 printk(KERN_INFO "Linux video codec intermediate layer: %s\n",
450 VIDEOCODEC_VERSION);
451
452#ifdef CONFIG_PROC_FS
453 videocodec_buf = NULL;
454 videocodec_bufsize = 0;
455
456 videocodec_proc_entry = create_proc_entry("videocodecs", 0, NULL);
457 if (videocodec_proc_entry) {
458 videocodec_proc_entry->read_proc = videocodec_info;
459 videocodec_proc_entry->write_proc = NULL;
460 videocodec_proc_entry->data = NULL;
461 videocodec_proc_entry->owner = THIS_MODULE;
462 } else {
463 dprintk(1, KERN_ERR "videocodec: can't init procfs.\n");
464 }
465#endif
466 return 0;
467}
468
469static void __exit
470videocodec_exit (void)
471{
472#ifdef CONFIG_PROC_FS
473 remove_proc_entry("videocodecs", NULL);
474 if (videocodec_buf)
475 kfree(videocodec_buf);
476#endif
477}
478
479EXPORT_SYMBOL(videocodec_attach);
480EXPORT_SYMBOL(videocodec_detach);
481EXPORT_SYMBOL(videocodec_register);
482EXPORT_SYMBOL(videocodec_unregister);
483
484module_init(videocodec_init);
485module_exit(videocodec_exit);
486
487MODULE_AUTHOR("Wolfgang Scherr <scherr@net4you.at>");
488MODULE_DESCRIPTION("Intermediate API module for video codecs "
489 VIDEOCODEC_VERSION);
490MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/videocodec.h b/drivers/media/video/videocodec.h
new file mode 100644
index 00000000000..156ae57096f
--- /dev/null
+++ b/drivers/media/video/videocodec.h
@@ -0,0 +1,358 @@
1/*
2 * VIDEO MOTION CODECs internal API for video devices
3 *
4 * Interface for MJPEG (and maybe later MPEG/WAVELETS) codec's
5 * bound to a master device.
6 *
7 * (c) 2002 Wolfgang Scherr <scherr@net4you.at>
8 *
9 * $Id: videocodec.h,v 1.1.2.4 2003/01/14 21:15:03 rbultje Exp $
10 *
11 * ------------------------------------------------------------------------
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 *
27 * ------------------------------------------------------------------------
28 */
29
30/* =================== */
31/* general description */
32/* =================== */
33
34/* Should ease the (re-)usage of drivers supporting cards with (different)
35 video codecs. The codecs register to this module their functionality,
36 and the processors (masters) can attach to them if they fit.
37
38 The codecs are typically have a "strong" binding to their master - so I
39 don't think it makes sense to have a full blown interfacing as with e.g.
40 i2c. If you have an other opinion, let's discuss & implement it :-)))
41
42 Usage:
43
44 The slave has just to setup the videocodec structure and use two functions:
45 videocodec_register(codecdata);
46 videocodec_unregister(codecdata);
47 The best is just calling them at module (de-)initialisation.
48
49 The master sets up the structure videocodec_master and calls:
50 codecdata=videocodec_attach(master_codecdata);
51 videocodec_detach(codecdata);
52
53 The slave is called during attach/detach via functions setup previously
54 during register. At that time, the master_data pointer is set up
55 and the slave can access any io registers of the master device (in the case
56 the slave is bound to it). Otherwise it doesn't need this functions and
57 therfor they may not be initialized.
58
59 The other fuctions are just for convenience, as they are for shure used by
60 most/all of the codecs. The last ones may be ommited, too.
61
62 See the structure declaration below for more information and which data has
63 to be set up for the master and the slave.
64
65 ----------------------------------------------------------------------------
66 The master should have "knowledge" of the slave and vice versa. So the data
67 structures sent to/from slave via set_data/get_data set_image/get_image are
68 device dependent and vary between MJPEG/MPEG/WAVELET/... devices. (!!!!)
69 ----------------------------------------------------------------------------
70*/
71
72
73/* ========================================== */
74/* description of the videocodec_io structure */
75/* ========================================== */
76
77/*
78 ==== master setup ====
79 name -> name of the device structure for reference and debugging
80 master_data -> data ref. for the master (e.g. the zr36055,57,67)
81 readreg -> ref. to read-fn from register (setup by master, used by slave)
82 writereg -> ref. to write-fn to register (setup by master, used by slave)
83 this two functions do the lowlevel I/O job
84
85 ==== slave functionality setup ====
86 slave_data -> data ref. for the slave (e.g. the zr36050,60)
87 check -> fn-ref. checks availability of an device, returns -EIO on failure or
88 the type on success
89 this makes espcecially sense if a driver module supports more than
90 one codec which may be quite similar to access, nevertheless it
91 is good for a first functionality check
92
93 -- main functions you always need for compression/decompression --
94
95 set_mode -> this fn-ref. resets the entire codec, and sets up the mode
96 with the last defined norm/size (or device default if not
97 available) - it returns 0 if the mode is possible
98 set_size -> this fn-ref. sets the norm and image size for
99 compression/decompression (returns 0 on success)
100 the norm param is defined in videodev.h (VIDEO_MODE_*)
101
102 additional setup may be available, too - but the codec should work with
103 some default values even without this
104
105 set_data -> sets device-specific data (tables, quality etc.)
106 get_data -> query device-specific data (tables, quality etc.)
107
108 if the device delivers interrupts, they may be setup/handled here
109 setup_interrupt -> codec irq setup (not needed for 36050/60)
110 handle_interrupt -> codec irq handling (not needed for 36050/60)
111
112 if the device delivers pictures, they may be handled here
113 put_image -> puts image data to the codec (not needed for 36050/60)
114 get_image -> gets image data from the codec (not needed for 36050/60)
115 the calls include frame numbers and flags (even/odd/...)
116 if needed and a flag which allows blocking until its ready
117*/
118
119/* ============== */
120/* user interface */
121/* ============== */
122
123/*
124 Currently there is only a information display planned, as the layer
125 is not visible for the user space at all.
126
127 Information is available via procfs. The current entry is "/proc/videocodecs"
128 but it makes sense to "hide" it in the /proc/video tree of v4l(2) --TODO--.
129
130A example for such an output is:
131
132<S>lave or attached <M>aster name type flags magic (connected as)
133S zr36050 0002 0000d001 00000000 (TEMPLATE)
134M zr36055[0] 0001 0000c001 00000000 (zr36050[0])
135M zr36055[1] 0001 0000c001 00000000 (zr36050[1])
136
137*/
138
139
140/* =============================================== */
141/* special defines for the videocodec_io structure */
142/* =============================================== */
143
144#ifndef __LINUX_VIDEOCODEC_H
145#define __LINUX_VIDEOCODEC_H
146
147#include <linux/videodev.h>
148
149//should be in videodev.h ??? (VID_DO_....)
150#define CODEC_DO_COMPRESSION 0
151#define CODEC_DO_EXPANSION 1
152
153/* this are the current codec flags I think they are needed */
154/* -> type value in structure */
155#define CODEC_FLAG_JPEG 0x00000001L // JPEG codec
156#define CODEC_FLAG_MPEG 0x00000002L // MPEG1/2/4 codec
157#define CODEC_FLAG_DIVX 0x00000004L // DIVX codec
158#define CODEC_FLAG_WAVELET 0x00000008L // WAVELET codec
159 // room for other types
160
161#define CODEC_FLAG_MAGIC 0x00000800L // magic key must match
162#define CODEC_FLAG_HARDWARE 0x00001000L // is a hardware codec
163#define CODEC_FLAG_VFE 0x00002000L // has direct video frontend
164#define CODEC_FLAG_ENCODER 0x00004000L // compression capability
165#define CODEC_FLAG_DECODER 0x00008000L // decompression capability
166#define CODEC_FLAG_NEEDIRQ 0x00010000L // needs irq handling
167#define CODEC_FLAG_RDWRPIC 0x00020000L // handles picture I/O
168
169/* a list of modes, some are just examples (is there any HW?) */
170#define CODEC_MODE_BJPG 0x0001 // Baseline JPEG
171#define CODEC_MODE_LJPG 0x0002 // Lossless JPEG
172#define CODEC_MODE_MPEG1 0x0003 // MPEG 1
173#define CODEC_MODE_MPEG2 0x0004 // MPEG 2
174#define CODEC_MODE_MPEG4 0x0005 // MPEG 4
175#define CODEC_MODE_MSDIVX 0x0006 // MS DivX
176#define CODEC_MODE_ODIVX 0x0007 // Open DivX
177#define CODEC_MODE_WAVELET 0x0008 // Wavelet
178
179/* this are the current codec types I want to implement */
180/* -> type value in structure */
181#define CODEC_TYPE_NONE 0
182#define CODEC_TYPE_L64702 1
183#define CODEC_TYPE_ZR36050 2
184#define CODEC_TYPE_ZR36016 3
185#define CODEC_TYPE_ZR36060 4
186
187/* the type of data may be enhanced by future implementations (data-fn.'s) */
188/* -> used in command */
189#define CODEC_G_STATUS 0x0000 /* codec status (query only) */
190#define CODEC_S_CODEC_MODE 0x0001 /* codec mode (baseline JPEG, MPEG1,... */
191#define CODEC_G_CODEC_MODE 0x8001
192#define CODEC_S_VFE 0x0002 /* additional video frontend setup */
193#define CODEC_G_VFE 0x8002
194#define CODEC_S_MMAP 0x0003 /* MMAP setup (if available) */
195
196#define CODEC_S_JPEG_TDS_BYTE 0x0010 /* target data size in bytes */
197#define CODEC_G_JPEG_TDS_BYTE 0x8010
198#define CODEC_S_JPEG_SCALE 0x0011 /* scaling factor for quant. tables */
199#define CODEC_G_JPEG_SCALE 0x8011
200#define CODEC_S_JPEG_HDT_DATA 0x0018 /* huffman-tables */
201#define CODEC_G_JPEG_HDT_DATA 0x8018
202#define CODEC_S_JPEG_QDT_DATA 0x0019 /* quantizing-tables */
203#define CODEC_G_JPEG_QDT_DATA 0x8019
204#define CODEC_S_JPEG_APP_DATA 0x001A /* APP marker */
205#define CODEC_G_JPEG_APP_DATA 0x801A
206#define CODEC_S_JPEG_COM_DATA 0x001B /* COM marker */
207#define CODEC_G_JPEG_COM_DATA 0x801B
208
209#define CODEC_S_PRIVATE 0x1000 /* "private" commands start here */
210#define CODEC_G_PRIVATE 0x9000
211
212#define CODEC_G_FLAG 0x8000 /* this is how 'get' is detected */
213
214/* types of transfer, directly user space or a kernel buffer (image-fn.'s) */
215/* -> used in get_image, put_image */
216#define CODEC_TRANSFER_KERNEL 0 /* use "memcopy" */
217#define CODEC_TRANSFER_USER 1 /* use "to/from_user" */
218
219
220/* ========================= */
221/* the structures itself ... */
222/* ========================= */
223
224struct vfe_polarity {
225 int vsync_pol:1;
226 int hsync_pol:1;
227 int field_pol:1;
228 int blank_pol:1;
229 int subimg_pol:1;
230 int poe_pol:1;
231 int pvalid_pol:1;
232 int vclk_pol:1;
233};
234
235struct vfe_settings {
236 __u32 x, y; /* Offsets into image */
237 __u32 width, height; /* Area to capture */
238 __u16 decimation; /* Decimation divider */
239 __u16 flags; /* Flags for capture */
240/* flags are the same as in struct video_capture - see videodev.h:
241#define VIDEO_CAPTURE_ODD 0
242#define VIDEO_CAPTURE_EVEN 1
243*/
244 __u16 quality; /* quality of the video */
245};
246
247struct tvnorm {
248 u16 Wt, Wa, HStart, HSyncStart, Ht, Ha, VStart;
249};
250
251struct jpeg_com_marker {
252 int len; /* number of usable bytes in data */
253 char data[60];
254};
255
256struct jpeg_app_marker {
257 int appn; /* number app segment */
258 int len; /* number of usable bytes in data */
259 char data[60];
260};
261
262struct videocodec {
263 struct module *owner;
264 /* -- filled in by slave device during register -- */
265 char name[32];
266 unsigned long magic; /* may be used for client<->master attaching */
267 unsigned long flags; /* functionality flags */
268 unsigned int type; /* codec type */
269
270 /* -- these is filled in later during master device attach -- */
271
272 struct videocodec_master *master_data;
273
274 /* -- these are filled in by the slave device during register -- */
275
276 void *data; /* private slave data */
277
278 /* attach/detach client functions (indirect call) */
279 int (*setup) (struct videocodec * codec);
280 int (*unset) (struct videocodec * codec);
281
282 /* main functions, every client needs them for sure! */
283 // set compression or decompression (or freeze, stop, standby, etc)
284 int (*set_mode) (struct videocodec * codec,
285 int mode);
286 // setup picture size and norm (for the codec's video frontend)
287 int (*set_video) (struct videocodec * codec,
288 struct tvnorm * norm,
289 struct vfe_settings * cap,
290 struct vfe_polarity * pol);
291 // other control commands, also mmap setup etc.
292 int (*control) (struct videocodec * codec,
293 int type,
294 int size,
295 void *data);
296
297 /* additional setup/query/processing (may be NULL pointer) */
298 // interrupt setup / handling (for irq's delivered by master)
299 int (*setup_interrupt) (struct videocodec * codec,
300 long mode);
301 int (*handle_interrupt) (struct videocodec * codec,
302 int source,
303 long flag);
304 // picture interface (if any)
305 long (*put_image) (struct videocodec * codec,
306 int tr_type,
307 int block,
308 long *fr_num,
309 long *flag,
310 long size,
311 void *buf);
312 long (*get_image) (struct videocodec * codec,
313 int tr_type,
314 int block,
315 long *fr_num,
316 long *flag,
317 long size,
318 void *buf);
319};
320
321struct videocodec_master {
322 /* -- filled in by master device for registration -- */
323 char name[32];
324 unsigned long magic; /* may be used for client<->master attaching */
325 unsigned long flags; /* functionality flags */
326 unsigned int type; /* master type */
327
328 void *data; /* private master data */
329
330 __u32(*readreg) (struct videocodec * codec,
331 __u16 reg);
332 void (*writereg) (struct videocodec * codec,
333 __u16 reg,
334 __u32 value);
335};
336
337
338/* ================================================= */
339/* function prototypes of the master/slave interface */
340/* ================================================= */
341
342/* attach and detach commands for the master */
343// * master structure needs to be kmalloc'ed before calling attach
344// and free'd after calling detach
345// * returns pointer on success, NULL on failure
346extern struct videocodec *videocodec_attach(struct videocodec_master *);
347// * 0 on success, <0 (errno) on failure
348extern int videocodec_detach(struct videocodec *);
349
350/* register and unregister commands for the slaves */
351// * 0 on success, <0 (errno) on failure
352extern int videocodec_register(const struct videocodec *);
353// * 0 on success, <0 (errno) on failure
354extern int videocodec_unregister(const struct videocodec *);
355
356/* the other calls are directly done via the videocodec structure! */
357
358#endif /*ifndef __LINUX_VIDEOCODEC_H */
diff --git a/drivers/media/video/videodev.c b/drivers/media/video/videodev.c
new file mode 100644
index 00000000000..06df15f75de
--- /dev/null
+++ b/drivers/media/video/videodev.c
@@ -0,0 +1,436 @@
1/*
2 * Video capture interface for Linux
3 *
4 * A generic video device interface for the LINUX operating system
5 * using a set of device structures/vectors for low level operations.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version
10 * 2 of the License, or (at your option) any later version.
11 *
12 * Author: Alan Cox, <alan@redhat.com>
13 *
14 * Fixes: 20000516 Claudio Matsuoka <claudio@conectiva.com>
15 * - Added procfs support
16 */
17
18#include <linux/module.h>
19#include <linux/types.h>
20#include <linux/kernel.h>
21#include <linux/sched.h>
22#include <linux/smp_lock.h>
23#include <linux/mm.h>
24#include <linux/string.h>
25#include <linux/errno.h>
26#include <linux/init.h>
27#include <linux/kmod.h>
28#include <linux/slab.h>
29#include <linux/devfs_fs_kernel.h>
30#include <asm/uaccess.h>
31#include <asm/system.h>
32#include <asm/semaphore.h>
33
34#include <linux/videodev.h>
35
36#define VIDEO_NUM_DEVICES 256
37#define VIDEO_NAME "video4linux"
38
39/*
40 * sysfs stuff
41 */
42
43static ssize_t show_name(struct class_device *cd, char *buf)
44{
45 struct video_device *vfd = container_of(cd, struct video_device, class_dev);
46 return sprintf(buf,"%.*s\n",(int)sizeof(vfd->name),vfd->name);
47}
48
49static CLASS_DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
50
51struct video_device *video_device_alloc(void)
52{
53 struct video_device *vfd;
54
55 vfd = kmalloc(sizeof(*vfd),GFP_KERNEL);
56 if (NULL == vfd)
57 return NULL;
58 memset(vfd,0,sizeof(*vfd));
59 return vfd;
60}
61
62void video_device_release(struct video_device *vfd)
63{
64 kfree(vfd);
65}
66
67static void video_release(struct class_device *cd)
68{
69 struct video_device *vfd = container_of(cd, struct video_device, class_dev);
70
71#if 1 /* needed until all drivers are fixed */
72 if (!vfd->release)
73 return;
74#endif
75 vfd->release(vfd);
76}
77
78static struct class video_class = {
79 .name = VIDEO_NAME,
80 .release = video_release,
81};
82
83/*
84 * Active devices
85 */
86
87static struct video_device *video_device[VIDEO_NUM_DEVICES];
88static DECLARE_MUTEX(videodev_lock);
89
90struct video_device* video_devdata(struct file *file)
91{
92 return video_device[iminor(file->f_dentry->d_inode)];
93}
94
95/*
96 * Open a video device.
97 */
98static int video_open(struct inode *inode, struct file *file)
99{
100 unsigned int minor = iminor(inode);
101 int err = 0;
102 struct video_device *vfl;
103 struct file_operations *old_fops;
104
105 if(minor>=VIDEO_NUM_DEVICES)
106 return -ENODEV;
107 down(&videodev_lock);
108 vfl=video_device[minor];
109 if(vfl==NULL) {
110 up(&videodev_lock);
111 request_module("char-major-%d-%d", VIDEO_MAJOR, minor);
112 down(&videodev_lock);
113 vfl=video_device[minor];
114 if (vfl==NULL) {
115 up(&videodev_lock);
116 return -ENODEV;
117 }
118 }
119 old_fops = file->f_op;
120 file->f_op = fops_get(vfl->fops);
121 if(file->f_op->open)
122 err = file->f_op->open(inode,file);
123 if (err) {
124 fops_put(file->f_op);
125 file->f_op = fops_get(old_fops);
126 }
127 fops_put(old_fops);
128 up(&videodev_lock);
129 return err;
130}
131
132/*
133 * helper function -- handles userspace copying for ioctl arguments
134 */
135
136static unsigned int
137video_fix_command(unsigned int cmd)
138{
139 switch (cmd) {
140 case VIDIOC_OVERLAY_OLD:
141 cmd = VIDIOC_OVERLAY;
142 break;
143 case VIDIOC_S_PARM_OLD:
144 cmd = VIDIOC_S_PARM;
145 break;
146 case VIDIOC_S_CTRL_OLD:
147 cmd = VIDIOC_S_CTRL;
148 break;
149 case VIDIOC_G_AUDIO_OLD:
150 cmd = VIDIOC_G_AUDIO;
151 break;
152 case VIDIOC_G_AUDOUT_OLD:
153 cmd = VIDIOC_G_AUDOUT;
154 break;
155 case VIDIOC_CROPCAP_OLD:
156 cmd = VIDIOC_CROPCAP;
157 break;
158 }
159 return cmd;
160}
161
162int
163video_usercopy(struct inode *inode, struct file *file,
164 unsigned int cmd, unsigned long arg,
165 int (*func)(struct inode *inode, struct file *file,
166 unsigned int cmd, void *arg))
167{
168 char sbuf[128];
169 void *mbuf = NULL;
170 void *parg = NULL;
171 int err = -EINVAL;
172
173 cmd = video_fix_command(cmd);
174
175 /* Copy arguments into temp kernel buffer */
176 switch (_IOC_DIR(cmd)) {
177 case _IOC_NONE:
178 parg = NULL;
179 break;
180 case _IOC_READ:
181 case _IOC_WRITE:
182 case (_IOC_WRITE | _IOC_READ):
183 if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
184 parg = sbuf;
185 } else {
186 /* too big to allocate from stack */
187 mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL);
188 if (NULL == mbuf)
189 return -ENOMEM;
190 parg = mbuf;
191 }
192
193 err = -EFAULT;
194 if (_IOC_DIR(cmd) & _IOC_WRITE)
195 if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd)))
196 goto out;
197 break;
198 }
199
200 /* call driver */
201 err = func(inode, file, cmd, parg);
202 if (err == -ENOIOCTLCMD)
203 err = -EINVAL;
204 if (err < 0)
205 goto out;
206
207 /* Copy results into user buffer */
208 switch (_IOC_DIR(cmd))
209 {
210 case _IOC_READ:
211 case (_IOC_WRITE | _IOC_READ):
212 if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
213 err = -EFAULT;
214 break;
215 }
216
217out:
218 if (mbuf)
219 kfree(mbuf);
220 return err;
221}
222
223/*
224 * open/release helper functions -- handle exclusive opens
225 */
226int video_exclusive_open(struct inode *inode, struct file *file)
227{
228 struct video_device *vfl = video_devdata(file);
229 int retval = 0;
230
231 down(&vfl->lock);
232 if (vfl->users) {
233 retval = -EBUSY;
234 } else {
235 vfl->users++;
236 }
237 up(&vfl->lock);
238 return retval;
239}
240
241int video_exclusive_release(struct inode *inode, struct file *file)
242{
243 struct video_device *vfl = video_devdata(file);
244
245 vfl->users--;
246 return 0;
247}
248
249static struct file_operations video_fops;
250
251/**
252 * video_register_device - register video4linux devices
253 * @vfd: video device structure we want to register
254 * @type: type of device to register
255 * @nr: which device number (0 == /dev/video0, 1 == /dev/video1, ...
256 * -1 == first free)
257 *
258 * The registration code assigns minor numbers based on the type
259 * requested. -ENFILE is returned in all the device slots for this
260 * category are full. If not then the minor field is set and the
261 * driver initialize function is called (if non %NULL).
262 *
263 * Zero is returned on success.
264 *
265 * Valid types are
266 *
267 * %VFL_TYPE_GRABBER - A frame grabber
268 *
269 * %VFL_TYPE_VTX - A teletext device
270 *
271 * %VFL_TYPE_VBI - Vertical blank data (undecoded)
272 *
273 * %VFL_TYPE_RADIO - A radio card
274 */
275
276int video_register_device(struct video_device *vfd, int type, int nr)
277{
278 int i=0;
279 int base;
280 int end;
281 char *name_base;
282
283 switch(type)
284 {
285 case VFL_TYPE_GRABBER:
286 base=0;
287 end=64;
288 name_base = "video";
289 break;
290 case VFL_TYPE_VTX:
291 base=192;
292 end=224;
293 name_base = "vtx";
294 break;
295 case VFL_TYPE_VBI:
296 base=224;
297 end=240;
298 name_base = "vbi";
299 break;
300 case VFL_TYPE_RADIO:
301 base=64;
302 end=128;
303 name_base = "radio";
304 break;
305 default:
306 return -1;
307 }
308
309 /* pick a minor number */
310 down(&videodev_lock);
311 if (nr >= 0 && nr < end-base) {
312 /* use the one the driver asked for */
313 i = base+nr;
314 if (NULL != video_device[i]) {
315 up(&videodev_lock);
316 return -ENFILE;
317 }
318 } else {
319 /* use first free */
320 for(i=base;i<end;i++)
321 if (NULL == video_device[i])
322 break;
323 if (i == end) {
324 up(&videodev_lock);
325 return -ENFILE;
326 }
327 }
328 video_device[i]=vfd;
329 vfd->minor=i;
330 up(&videodev_lock);
331
332 sprintf(vfd->devfs_name, "v4l/%s%d", name_base, i - base);
333 devfs_mk_cdev(MKDEV(VIDEO_MAJOR, vfd->minor),
334 S_IFCHR | S_IRUSR | S_IWUSR, vfd->devfs_name);
335 init_MUTEX(&vfd->lock);
336
337 /* sysfs class */
338 memset(&vfd->class_dev, 0x00, sizeof(vfd->class_dev));
339 if (vfd->dev)
340 vfd->class_dev.dev = vfd->dev;
341 vfd->class_dev.class = &video_class;
342 vfd->class_dev.devt = MKDEV(VIDEO_MAJOR, vfd->minor);
343 strlcpy(vfd->class_dev.class_id, vfd->devfs_name + 4, BUS_ID_SIZE);
344 class_device_register(&vfd->class_dev);
345 class_device_create_file(&vfd->class_dev,
346 &class_device_attr_name);
347
348#if 1 /* needed until all drivers are fixed */
349 if (!vfd->release)
350 printk(KERN_WARNING "videodev: \"%s\" has no release callback. "
351 "Please fix your driver for proper sysfs support, see "
352 "http://lwn.net/Articles/36850/\n", vfd->name);
353#endif
354 return 0;
355}
356
357/**
358 * video_unregister_device - unregister a video4linux device
359 * @vfd: the device to unregister
360 *
361 * This unregisters the passed device and deassigns the minor
362 * number. Future open calls will be met with errors.
363 */
364
365void video_unregister_device(struct video_device *vfd)
366{
367 down(&videodev_lock);
368 if(video_device[vfd->minor]!=vfd)
369 panic("videodev: bad unregister");
370
371 devfs_remove(vfd->devfs_name);
372 video_device[vfd->minor]=NULL;
373 class_device_unregister(&vfd->class_dev);
374 up(&videodev_lock);
375}
376
377
378static struct file_operations video_fops=
379{
380 .owner = THIS_MODULE,
381 .llseek = no_llseek,
382 .open = video_open,
383};
384
385/*
386 * Initialise video for linux
387 */
388
389static int __init videodev_init(void)
390{
391 int ret;
392
393 printk(KERN_INFO "Linux video capture interface: v1.00\n");
394 if (register_chrdev(VIDEO_MAJOR, VIDEO_NAME, &video_fops)) {
395 printk(KERN_WARNING "video_dev: unable to get major %d\n", VIDEO_MAJOR);
396 return -EIO;
397 }
398
399 ret = class_register(&video_class);
400 if (ret < 0) {
401 unregister_chrdev(VIDEO_MAJOR, VIDEO_NAME);
402 printk(KERN_WARNING "video_dev: class_register failed\n");
403 return -EIO;
404 }
405
406 return 0;
407}
408
409static void __exit videodev_exit(void)
410{
411 class_unregister(&video_class);
412 unregister_chrdev(VIDEO_MAJOR, VIDEO_NAME);
413}
414
415module_init(videodev_init)
416module_exit(videodev_exit)
417
418EXPORT_SYMBOL(video_register_device);
419EXPORT_SYMBOL(video_unregister_device);
420EXPORT_SYMBOL(video_devdata);
421EXPORT_SYMBOL(video_usercopy);
422EXPORT_SYMBOL(video_exclusive_open);
423EXPORT_SYMBOL(video_exclusive_release);
424EXPORT_SYMBOL(video_device_alloc);
425EXPORT_SYMBOL(video_device_release);
426
427MODULE_AUTHOR("Alan Cox");
428MODULE_DESCRIPTION("Device registrar for Video4Linux drivers");
429MODULE_LICENSE("GPL");
430
431
432/*
433 * Local variables:
434 * c-basic-offset: 8
435 * End:
436 */
diff --git a/drivers/media/video/vino.c b/drivers/media/video/vino.c
new file mode 100644
index 00000000000..76e8681d65c
--- /dev/null
+++ b/drivers/media/video/vino.c
@@ -0,0 +1,347 @@
1/*
2 * (incomplete) Driver for the VINO (Video In No Out) system found in SGI Indys.
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License version 2 as published by the Free Software Foundation.
6 *
7 * Copyright (C) 2003 Ladislav Michl <ladis@linux-mips.org>
8 */
9
10#include <linux/module.h>
11#include <linux/init.h>
12#include <linux/types.h>
13#include <linux/mm.h>
14#include <linux/slab.h>
15#include <linux/wrapper.h>
16#include <linux/errno.h>
17#include <linux/irq.h>
18#include <linux/delay.h>
19#include <linux/videodev.h>
20#include <linux/i2c.h>
21#include <linux/i2c-algo-sgi.h>
22
23#include <asm/addrspace.h>
24#include <asm/system.h>
25#include <asm/bootinfo.h>
26#include <asm/pgtable.h>
27#include <asm/paccess.h>
28#include <asm/io.h>
29#include <asm/sgi/ip22.h>
30#include <asm/sgi/hpc3.h>
31#include <asm/sgi/mc.h>
32
33#include "vino.h"
34
35/* debugging? */
36#if 1
37#define DEBUG(x...) printk(x);
38#else
39#define DEBUG(x...)
40#endif
41
42
43/* VINO ASIC registers */
44struct sgi_vino *vino;
45
46static const char *vinostr = "VINO IndyCam/TV";
47static int threshold_a = 512;
48static int threshold_b = 512;
49
50struct vino_device {
51 struct video_device vdev;
52#define VINO_CHAN_A 1
53#define VINO_CHAN_B 2
54 int chan;
55};
56
57struct vino_client {
58 struct i2c_client *driver;
59 int owner;
60};
61
62struct vino_video {
63 struct vino_device chA;
64 struct vino_device chB;
65
66 struct vino_client decoder;
67 struct vino_client camera;
68
69 struct semaphore input_lock;
70
71 /* Loaded into VINO descriptors to clear End Of Descriptors table
72 * interupt condition */
73 unsigned long dummy_page;
74 unsigned int dummy_buf[4] __attribute__((aligned(8)));
75};
76
77static struct vino_video *Vino;
78
79unsigned i2c_vino_getctrl(void *data)
80{
81 return vino->i2c_control;
82}
83
84void i2c_vino_setctrl(void *data, unsigned val)
85{
86 vino->i2c_control = val;
87}
88
89unsigned i2c_vino_rdata(void *data)
90{
91 return vino->i2c_data;
92}
93
94void i2c_vino_wdata(void *data, unsigned val)
95{
96 vino->i2c_data = val;
97}
98
99static struct i2c_algo_sgi_data i2c_sgi_vino_data =
100{
101 .getctrl = &i2c_vino_getctrl,
102 .setctrl = &i2c_vino_setctrl,
103 .rdata = &i2c_vino_rdata,
104 .wdata = &i2c_vino_wdata,
105 .xfer_timeout = 200,
106 .ack_timeout = 1000,
107};
108
109/*
110 * There are two possible clients on VINO I2C bus, so we limit usage only
111 * to them.
112 */
113static int i2c_vino_client_reg(struct i2c_client *client)
114{
115 int res = 0;
116
117 down(&Vino->input_lock);
118 switch (client->driver->id) {
119 case I2C_DRIVERID_SAA7191:
120 if (Vino->decoder.driver)
121 res = -EBUSY;
122 else
123 Vino->decoder.driver = client;
124 break;
125 case I2C_DRIVERID_INDYCAM:
126 if (Vino->camera.driver)
127 res = -EBUSY;
128 else
129 Vino->camera.driver = client;
130 break;
131 default:
132 res = -ENODEV;
133 }
134 up(&Vino->input_lock);
135
136 return res;
137}
138
139static int i2c_vino_client_unreg(struct i2c_client *client)
140{
141 int res = 0;
142
143 down(&Vino->input_lock);
144 if (client == Vino->decoder.driver) {
145 if (Vino->decoder.owner)
146 res = -EBUSY;
147 else
148 Vino->decoder.driver = NULL;
149 } else if (client == Vino->camera.driver) {
150 if (Vino->camera.owner)
151 res = -EBUSY;
152 else
153 Vino->camera.driver = NULL;
154 }
155 up(&Vino->input_lock);
156
157 return res;
158}
159
160static struct i2c_adapter vino_i2c_adapter =
161{
162 .name = "VINO I2C bus",
163 .id = I2C_HW_SGI_VINO,
164 .algo_data = &i2c_sgi_vino_data,
165 .client_register = &i2c_vino_client_reg,
166 .client_unregister = &i2c_vino_client_unreg,
167};
168
169static int vino_i2c_add_bus(void)
170{
171 return i2c_sgi_add_bus(&vino_i2c_adapter);
172}
173
174static int vino_i2c_del_bus(void)
175{
176 return i2c_sgi_del_bus(&vino_i2c_adapter);
177}
178
179
180static void vino_interrupt(int irq, void *dev_id, struct pt_regs *regs)
181{
182}
183
184static int vino_open(struct video_device *dev, int flags)
185{
186 struct vino_device *videv = (struct vino_device *)dev;
187
188 return 0;
189}
190
191static void vino_close(struct video_device *dev)
192{
193 struct vino_device *videv = (struct vino_device *)dev;
194}
195
196static int vino_mmap(struct video_device *dev, const char *adr,
197 unsigned long size)
198{
199 struct vino_device *videv = (struct vino_device *)dev;
200
201 return -EINVAL;
202}
203
204static int vino_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
205{
206 struct vino_device *videv = (struct vino_device *)dev;
207
208 return -EINVAL;
209}
210
211static const struct video_device vino_device = {
212 .owner = THIS_MODULE,
213 .type = VID_TYPE_CAPTURE | VID_TYPE_SUBCAPTURE,
214 .hardware = VID_HARDWARE_VINO,
215 .name = "VINO",
216 .open = vino_open,
217 .close = vino_close,
218 .ioctl = vino_ioctl,
219 .mmap = vino_mmap,
220};
221
222static int __init vino_init(void)
223{
224 unsigned long rev;
225 int i, ret = 0;
226
227 /* VINO is Indy specific beast */
228 if (ip22_is_fullhouse())
229 return -ENODEV;
230
231 /*
232 * VINO is in the EISA address space, so the sysid register will tell
233 * us if the EISA_PRESENT pin on MC has been pulled low.
234 *
235 * If EISA_PRESENT is not set we definitely don't have a VINO equiped
236 * system.
237 */
238 if (!(sgimc->systemid & SGIMC_SYSID_EPRESENT)) {
239 printk(KERN_ERR "VINO not found\n");
240 return -ENODEV;
241 }
242
243 vino = (struct sgi_vino *)ioremap(VINO_BASE, sizeof(struct sgi_vino));
244 if (!vino)
245 return -EIO;
246
247 /* Okay, once we know that VINO is present we'll read its revision
248 * safe way. One never knows... */
249 if (get_dbe(rev, &(vino->rev_id))) {
250 printk(KERN_ERR "VINO: failed to read revision register\n");
251 ret = -ENODEV;
252 goto out_unmap;
253 }
254 if (VINO_ID_VALUE(rev) != VINO_CHIP_ID) {
255 printk(KERN_ERR "VINO is not VINO (Rev/ID: 0x%04lx)\n", rev);
256 ret = -ENODEV;
257 goto out_unmap;
258 }
259 printk(KERN_INFO "VINO Rev: 0x%02lx\n", VINO_REV_NUM(rev));
260
261 Vino = (struct vino_video *)
262 kmalloc(sizeof(struct vino_video), GFP_KERNEL);
263 if (!Vino) {
264 ret = -ENOMEM;
265 goto out_unmap;
266 }
267
268 Vino->dummy_page = get_zeroed_page(GFP_KERNEL | GFP_DMA);
269 if (!Vino->dummy_page) {
270 ret = -ENOMEM;
271 goto out_free_vino;
272 }
273 for (i = 0; i < 4; i++)
274 Vino->dummy_buf[i] = PHYSADDR(Vino->dummy_page);
275
276 vino->control = 0;
277 /* prevent VINO from throwing spurious interrupts */
278 vino->a.next_4_desc = PHYSADDR(Vino->dummy_buf);
279 vino->b.next_4_desc = PHYSADDR(Vino->dummy_buf);
280 udelay(5);
281 vino->intr_status = 0;
282 /* set threshold level */
283 vino->a.fifo_thres = threshold_a;
284 vino->b.fifo_thres = threshold_b;
285
286 init_MUTEX(&Vino->input_lock);
287
288 if (request_irq(SGI_VINO_IRQ, vino_interrupt, 0, vinostr, NULL)) {
289 printk(KERN_ERR "VINO: irq%02d registration failed\n",
290 SGI_VINO_IRQ);
291 ret = -EAGAIN;
292 goto out_free_page;
293 }
294
295 ret = vino_i2c_add_bus();
296 if (ret) {
297 printk(KERN_ERR "VINO: I2C bus registration failed\n");
298 goto out_free_irq;
299 }
300
301 if (video_register_device(&Vino->chA.vdev, VFL_TYPE_GRABBER, -1) < 0) {
302 printk("%s, chnl %d: device registration failed.\n",
303 Vino->chA.vdev.name, Vino->chA.chan);
304 ret = -EINVAL;
305 goto out_i2c_del_bus;
306 }
307 if (video_register_device(&Vino->chB.vdev, VFL_TYPE_GRABBER, -1) < 0) {
308 printk("%s, chnl %d: device registration failed.\n",
309 Vino->chB.vdev.name, Vino->chB.chan);
310 ret = -EINVAL;
311 goto out_unregister_vdev;
312 }
313
314 return 0;
315
316out_unregister_vdev:
317 video_unregister_device(&Vino->chA.vdev);
318out_i2c_del_bus:
319 vino_i2c_del_bus();
320out_free_irq:
321 free_irq(SGI_VINO_IRQ, NULL);
322out_free_page:
323 free_page(Vino->dummy_page);
324out_free_vino:
325 kfree(Vino);
326out_unmap:
327 iounmap(vino);
328
329 return ret;
330}
331
332static void __exit vino_exit(void)
333{
334 video_unregister_device(&Vino->chA.vdev);
335 video_unregister_device(&Vino->chB.vdev);
336 vino_i2c_del_bus();
337 free_irq(SGI_VINO_IRQ, NULL);
338 free_page(Vino->dummy_page);
339 kfree(Vino);
340 iounmap(vino);
341}
342
343module_init(vino_init);
344module_exit(vino_exit);
345
346MODULE_DESCRIPTION("Video4Linux driver for SGI Indy VINO (IndyCam)");
347MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/vino.h b/drivers/media/video/vino.h
new file mode 100644
index 00000000000..d2fce472f35
--- /dev/null
+++ b/drivers/media/video/vino.h
@@ -0,0 +1,131 @@
1/*
2 * Copyright (C) 1999 Ulf Karlsson <ulfc@bun.falkenberg.se>
3 * Copyright (C) 2003 Ladislav Michl <ladis@linux-mips.org>
4 */
5
6#ifndef VINO_H
7#define VINO_H
8
9#define VINO_BASE 0x00080000 /* Vino is in the EISA address space,
10 * but it is not an EISA bus card */
11
12struct sgi_vino_channel {
13 u32 _pad_alpha;
14 volatile u32 alpha;
15
16#define VINO_CLIP_X(x) ((x) & 0x3ff) /* bits 0:9 */
17#define VINO_CLIP_ODD(x) (((x) & 0x1ff) << 10) /* bits 10:18 */
18#define VINO_CLIP_EVEN(x) (((x) & 0x1ff) << 19) /* bits 19:27 */
19 u32 _pad_clip_start;
20 volatile u32 clip_start;
21 u32 _pad_clip_end;
22 volatile u32 clip_end;
23
24#define VINO_FRAMERT_PAL (1<<0) /* 0=NTSC 1=PAL */
25#define VINO_FRAMERT_RT(x) (((x) & 0x1fff) << 1) /* bits 1:12 */
26 u32 _pad_frame_rate;
27 volatile u32 frame_rate;
28
29 u32 _pad_field_counter;
30 volatile u32 field_counter;
31 u32 _pad_line_size;
32 volatile u32 line_size;
33 u32 _pad_line_count;
34 volatile u32 line_count;
35 u32 _pad_page_index;
36 volatile u32 page_index;
37 u32 _pad_next_4_desc;
38 volatile u32 next_4_desc;
39 u32 _pad_start_desc_tbl;
40 volatile u32 start_desc_tbl;
41
42#define VINO_DESC_JUMP (1<<30)
43#define VINO_DESC_STOP (1<<31)
44#define VINO_DESC_VALID (1<<32)
45 u32 _pad_desc_0;
46 volatile u32 desc_0;
47 u32 _pad_desc_1;
48 volatile u32 desc_1;
49 u32 _pad_desc_2;
50 volatile u32 desc_2;
51 u32 _pad_Bdesc_3;
52 volatile u32 desc_3;
53
54 u32 _pad_fifo_thres;
55 volatile u32 fifo_thres;
56 u32 _pad_fifo_read;
57 volatile u32 fifo_read;
58 u32 _pad_fifo_write;
59 volatile u32 fifo_write;
60};
61
62struct sgi_vino {
63#define VINO_CHIP_ID 0xb
64#define VINO_REV_NUM(x) ((x) & 0x0f)
65#define VINO_ID_VALUE(x) (((x) & 0xf0) >> 4)
66 u32 _pad_rev_id;
67 volatile u32 rev_id;
68
69#define VINO_CTRL_LITTLE_ENDIAN (1<<0)
70#define VINO_CTRL_A_FIELD_TRANS_INT (1<<1) /* Field transferred int */
71#define VINO_CTRL_A_FIFO_OF_INT (1<<2) /* FIFO overflow int */
72#define VINO_CTRL_A_END_DESC_TBL_INT (1<<3) /* End of desc table int */
73#define VINO_CTRL_A_INT (VINO_CTRL_A_FIELD_TRANS_INT | \
74 VINO_CTRL_A_FIFO_OF_INT | \
75 VINO_CTRL_A_END_DESC_TBL_INT)
76#define VINO_CTRL_B_FIELD_TRANS_INT (1<<4) /* Field transferred int */
77#define VINO_CTRL_B_FIFO_OF_INT (1<<5) /* FIFO overflow int */
78#define VINO_CTRL_B_END_DESC_TBL_INT (1<<6) /* End of desc table int */
79#define VINO_CTRL_B_INT (VINO_CTRL_B_FIELD_TRANS_INT | \
80 VINO_CTRL_B_FIFO_OF_INT | \
81 VINO_CTRL_B_END_DESC_TBL_INT)
82#define VINO_CTRL_A_DMA_ENBL (1<<7)
83#define VINO_CTRL_A_INTERLEAVE_ENBL (1<<8)
84#define VINO_CTRL_A_SYNC_ENBL (1<<9)
85#define VINO_CTRL_A_SELECT (1<<10) /* 1=D1 0=Philips */
86#define VINO_CTRL_A_RGB (1<<11) /* 1=RGB 0=YUV */
87#define VINO_CTRL_A_LUMA_ONLY (1<<12)
88#define VINO_CTRL_A_DEC_ENBL (1<<13) /* Decimation */
89#define VINO_CTRL_A_DEC_SCALE_MASK 0x1c000 /* bits 14:17 */
90#define VINO_CTRL_A_DEC_SCALE_SHIFT (14)
91#define VINO_CTRL_A_DEC_HOR_ONLY (1<<17) /* Horizontal only */
92#define VINO_CTRL_A_DITHER (1<<18) /* 24 -> 8 bit dither */
93#define VINO_CTRL_B_DMA_ENBL (1<<19)
94#define VINO_CTRL_B_INTERLEAVE_ENBL (1<<20)
95#define VINO_CTRL_B_SYNC_ENBL (1<<21)
96#define VINO_CTRL_B_SELECT (1<<22) /* 1=D1 0=Philips */
97#define VINO_CTRL_B_RGB (1<<23) /* 1=RGB 0=YUV */
98#define VINO_CTRL_B_LUMA_ONLY (1<<24)
99#define VINO_CTRL_B_DEC_ENBL (1<<25) /* Decimation */
100#define VINO_CTRL_B_DEC_SCALE_MASK 0x1c000000 /* bits 26:28 */
101#define VINO_CTRL_B_DEC_SCALE_SHIFT (26)
102#define VINO_CTRL_B_DEC_HOR_ONLY (1<<29) /* Decimation horizontal only */
103#define VINO_CTRL_B_DITHER (1<<30) /* ChanB 24 -> 8 bit dither */
104 u32 _pad_control;
105 volatile u32 control;
106
107#define VINO_INTSTAT_A_FIELD_TRANS (1<<0) /* Field transferred int */
108#define VINO_INTSTAT_A_FIFO_OF (1<<1) /* FIFO overflow int */
109#define VINO_INTSTAT_A_END_DESC_TBL (1<<2) /* End of desc table int */
110#define VINO_INTSTAT_A (VINO_INTSTAT_A_FIELD_TRANS | \
111 VINO_INTSTAT_A_FIFO_OF | \
112 VINO_INTSTAT_A_END_DESC_TBL)
113#define VINO_INTSTAT_B_FIELD_TRANS (1<<3) /* Field transferred int */
114#define VINO_INTSTAT_B_FIFO_OF (1<<4) /* FIFO overflow int */
115#define VINO_INTSTAT_B_END_DESC_TBL (1<<5) /* End of desc table int */
116#define VINO_INTSTAT_B (VINO_INTSTAT_B_FIELD_TRANS | \
117 VINO_INTSTAT_B_FIFO_OF | \
118 VINO_INTSTAT_B_END_DESC_TBL)
119 u32 _pad_intr_status;
120 volatile u32 intr_status;
121
122 u32 _pad_i2c_control;
123 volatile u32 i2c_control;
124 u32 _pad_i2c_data;
125 volatile u32 i2c_data;
126
127 struct sgi_vino_channel a;
128 struct sgi_vino_channel b;
129};
130
131#endif
diff --git a/drivers/media/video/vpx3220.c b/drivers/media/video/vpx3220.c
new file mode 100644
index 00000000000..0fd6c9a7091
--- /dev/null
+++ b/drivers/media/video/vpx3220.c
@@ -0,0 +1,754 @@
1/*
2 * vpx3220a, vpx3216b & vpx3214c video decoder driver version 0.0.1
3 *
4 * Copyright (C) 2001 Laurent Pinchart <lpinchart@freegates.be>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21#include <linux/module.h>
22#include <linux/init.h>
23#include <linux/delay.h>
24#include <linux/types.h>
25#include <linux/slab.h>
26
27#include <linux/byteorder/swab.h>
28
29#include <asm/io.h>
30#include <asm/uaccess.h>
31
32#include <linux/i2c.h>
33#include <linux/i2c-dev.h>
34
35#define I2C_NAME(x) (x)->name
36
37#include <linux/videodev.h>
38#include <linux/video_decoder.h>
39
40#define I2C_VPX3220 0x86
41#define VPX3220_DEBUG KERN_DEBUG "vpx3220: "
42
43static int debug = 0;
44module_param(debug, int, 0);
45MODULE_PARM_DESC(debug, "Debug level (0-1)");
46
47#define dprintk(num, format, args...) \
48 do { \
49 if (debug >= num) \
50 printk(format, ##args); \
51 } while (0)
52
53#define VPX_TIMEOUT_COUNT 10
54
55/* ----------------------------------------------------------------------- */
56
57struct vpx3220 {
58 unsigned char reg[255];
59
60 int norm;
61 int input;
62 int enable;
63 int bright;
64 int contrast;
65 int hue;
66 int sat;
67};
68
69static char *inputs[] = { "internal", "composite", "svideo" };
70
71/* ----------------------------------------------------------------------- */
72static inline int
73vpx3220_write (struct i2c_client *client,
74 u8 reg,
75 u8 value)
76{
77 struct vpx3220 *decoder = i2c_get_clientdata(client);
78
79 decoder->reg[reg] = value;
80 return i2c_smbus_write_byte_data(client, reg, value);
81}
82
83static inline int
84vpx3220_read (struct i2c_client *client,
85 u8 reg)
86{
87 return i2c_smbus_read_byte_data(client, reg);
88}
89
90static int
91vpx3220_fp_status (struct i2c_client *client)
92{
93 unsigned char status;
94 unsigned int i;
95
96 for (i = 0; i < VPX_TIMEOUT_COUNT; i++) {
97 status = vpx3220_read(client, 0x29);
98
99 if (!(status & 4))
100 return 0;
101
102 udelay(10);
103
104 if (need_resched())
105 cond_resched();
106 }
107
108 return -1;
109}
110
111static int
112vpx3220_fp_write (struct i2c_client *client,
113 u8 fpaddr,
114 u16 data)
115{
116 /* Write the 16-bit address to the FPWR register */
117 if (i2c_smbus_write_word_data(client, 0x27, swab16(fpaddr)) == -1) {
118 dprintk(1, VPX3220_DEBUG "%s: failed\n", __func__);
119 return -1;
120 }
121
122 if (vpx3220_fp_status(client) < 0)
123 return -1;
124
125 /* Write the 16-bit data to the FPDAT register */
126 if (i2c_smbus_write_word_data(client, 0x28, swab16(data)) == -1) {
127 dprintk(1, VPX3220_DEBUG "%s: failed\n", __func__);
128 return -1;
129 }
130
131 return 0;
132}
133
134static u16
135vpx3220_fp_read (struct i2c_client *client,
136 u16 fpaddr)
137{
138 s16 data;
139
140 /* Write the 16-bit address to the FPRD register */
141 if (i2c_smbus_write_word_data(client, 0x26, swab16(fpaddr)) == -1) {
142 dprintk(1, VPX3220_DEBUG "%s: failed\n", __func__);
143 return -1;
144 }
145
146 if (vpx3220_fp_status(client) < 0)
147 return -1;
148
149 /* Read the 16-bit data from the FPDAT register */
150 data = i2c_smbus_read_word_data(client, 0x28);
151 if (data == -1) {
152 dprintk(1, VPX3220_DEBUG "%s: failed\n", __func__);
153 return -1;
154 }
155
156 return swab16(data);
157}
158
159static int
160vpx3220_write_block (struct i2c_client *client,
161 const u8 *data,
162 unsigned int len)
163{
164 u8 reg;
165 int ret = -1;
166
167 while (len >= 2) {
168 reg = *data++;
169 if ((ret =
170 vpx3220_write(client, reg, *data++)) < 0)
171 break;
172 len -= 2;
173 }
174
175 return ret;
176}
177
178static int
179vpx3220_write_fp_block (struct i2c_client *client,
180 const u16 *data,
181 unsigned int len)
182{
183 u8 reg;
184 int ret = 0;
185
186 while (len > 1) {
187 reg = *data++;
188 ret |= vpx3220_fp_write(client, reg, *data++);
189 len -= 2;
190 }
191
192 return ret;
193}
194
195/* ---------------------------------------------------------------------- */
196
197static const unsigned short init_ntsc[] = {
198 0x1c, 0x00, /* NTSC tint angle */
199 0x88, 17, /* Window 1 vertical */
200 0x89, 240, /* Vertical lines in */
201 0x8a, 240, /* Vertical lines out */
202 0x8b, 000, /* Horizontal begin */
203 0x8c, 640, /* Horizontal length */
204 0x8d, 640, /* Number of pixels */
205 0x8f, 0xc00, /* Disable window 2 */
206 0xf0, 0x173, /* 13.5 MHz transport, Forced
207 * mode, latch windows */
208 0xf2, 0x13, /* NTSC M, composite input */
209 0xe7, 0x1e1, /* Enable vertical standard
210 * locking @ 240 lines */
211};
212
213static const unsigned short init_pal[] = {
214 0x88, 23, /* Window 1 vertical begin */
215 0x89, 288 + 16, /* Vertical lines in (16 lines
216 * skipped by the VFE) */
217 0x8a, 288 + 16, /* Vertical lines out (16 lines
218 * skipped by the VFE) */
219 0x8b, 16, /* Horizontal begin */
220 0x8c, 768, /* Horizontal length */
221 0x8d, 784, /* Number of pixels
222 * Must be >= Horizontal begin + Horizontal length */
223 0x8f, 0xc00, /* Disable window 2 */
224 0xf0, 0x177, /* 13.5 MHz transport, Forced
225 * mode, latch windows */
226 0xf2, 0x3d1, /* PAL B,G,H,I, composite input */
227 0xe7, 0x261, /* PAL/SECAM set to 288 + 16 lines
228 * change to 0x241 for 288 lines */
229};
230
231static const unsigned short init_secam[] = {
232 0x88, 23 - 16, /* Window 1 vertical begin */
233 0x89, 288 + 16, /* Vertical lines in (16 lines
234 * skipped by the VFE) */
235 0x8a, 288 + 16, /* Vertical lines out (16 lines
236 * skipped by the VFE) */
237 0x8b, 16, /* Horizontal begin */
238 0x8c, 768, /* Horizontal length */
239 0x8d, 784, /* Number of pixels
240 * Must be >= Horizontal begin + Horizontal length */
241 0x8f, 0xc00, /* Disable window 2 */
242 0xf0, 0x177, /* 13.5 MHz transport, Forced
243 * mode, latch windows */
244 0xf2, 0x3d5, /* SECAM, composite input */
245 0xe7, 0x261, /* PAL/SECAM set to 288 + 16 lines
246 * change to 0x241 for 288 lines */
247};
248
249static const unsigned char init_common[] = {
250 0xf2, 0x00, /* Disable all outputs */
251 0x33, 0x0d, /* Luma : VIN2, Chroma : CIN
252 * (clamp off) */
253 0xd8, 0xa8, /* HREF/VREF active high, VREF
254 * pulse = 2, Odd/Even flag */
255 0x20, 0x03, /* IF compensation 0dB/oct */
256 0xe0, 0xff, /* Open up all comparators */
257 0xe1, 0x00,
258 0xe2, 0x7f,
259 0xe3, 0x80,
260 0xe4, 0x7f,
261 0xe5, 0x80,
262 0xe6, 0x00, /* Brightness set to 0 */
263 0xe7, 0xe0, /* Contrast to 1.0, noise shaping
264 * 10 to 8 2-bit error diffusion */
265 0xe8, 0xf8, /* YUV422, CbCr binary offset,
266 * ... (p.32) */
267 0xea, 0x18, /* LLC2 connected, output FIFO
268 * reset with VACTintern */
269 0xf0, 0x8a, /* Half full level to 10, bus
270 * shuffler [7:0, 23:16, 15:8] */
271 0xf1, 0x18, /* Single clock, sync mode, no
272 * FE delay, no HLEN counter */
273 0xf8, 0x12, /* Port A, PIXCLK, HF# & FE#
274 * strength to 2 */
275 0xf9, 0x24, /* Port B, HREF, VREF, PREF &
276 * ALPHA strength to 4 */
277};
278
279static const unsigned short init_fp[] = {
280 0x59, 0,
281 0xa0, 2070, /* ACC reference */
282 0xa3, 0,
283 0xa4, 0,
284 0xa8, 30,
285 0xb2, 768,
286 0xbe, 27,
287 0x58, 0,
288 0x26, 0,
289 0x4b, 0x298, /* PLL gain */
290};
291
292static void
293vpx3220_dump_i2c (struct i2c_client *client)
294{
295 int len = sizeof(init_common);
296 const unsigned char *data = init_common;
297
298 while (len > 1) {
299 dprintk(1,
300 KERN_DEBUG "vpx3216b i2c reg 0x%02x data 0x%02x\n",
301 *data, vpx3220_read(client, *data));
302 data += 2;
303 len -= 2;
304 }
305}
306
307static int
308vpx3220_command (struct i2c_client *client,
309 unsigned int cmd,
310 void *arg)
311{
312 struct vpx3220 *decoder = i2c_get_clientdata(client);
313
314 switch (cmd) {
315 case 0:
316 {
317 vpx3220_write_block(client, init_common,
318 sizeof(init_common));
319 vpx3220_write_fp_block(client, init_fp,
320 sizeof(init_fp) >> 1);
321 switch (decoder->norm) {
322
323 case VIDEO_MODE_NTSC:
324 vpx3220_write_fp_block(client, init_ntsc,
325 sizeof(init_ntsc) >> 1);
326 break;
327
328 case VIDEO_MODE_PAL:
329 vpx3220_write_fp_block(client, init_pal,
330 sizeof(init_pal) >> 1);
331 break;
332 case VIDEO_MODE_SECAM:
333 vpx3220_write_fp_block(client, init_secam,
334 sizeof(init_secam) >> 1);
335 break;
336 default:
337 vpx3220_write_fp_block(client, init_pal,
338 sizeof(init_pal) >> 1);
339 break;
340 }
341 }
342 break;
343
344 case DECODER_DUMP:
345 {
346 vpx3220_dump_i2c(client);
347 }
348 break;
349
350 case DECODER_GET_CAPABILITIES:
351 {
352 struct video_decoder_capability *cap = arg;
353
354 dprintk(1, KERN_DEBUG "%s: DECODER_GET_CAPABILITIES\n",
355 I2C_NAME(client));
356
357 cap->flags = VIDEO_DECODER_PAL |
358 VIDEO_DECODER_NTSC |
359 VIDEO_DECODER_SECAM |
360 VIDEO_DECODER_AUTO |
361 VIDEO_DECODER_CCIR;
362 cap->inputs = 3;
363 cap->outputs = 1;
364 }
365 break;
366
367 case DECODER_GET_STATUS:
368 {
369 int res = 0, status;
370
371 dprintk(1, KERN_INFO "%s: DECODER_GET_STATUS\n",
372 I2C_NAME(client));
373
374 status = vpx3220_fp_read(client, 0x0f3);
375
376 dprintk(1, KERN_INFO "%s: status: 0x%04x\n", I2C_NAME(client),
377 status);
378
379 if (status < 0)
380 return status;
381
382 if ((status & 0x20) == 0) {
383 res |= DECODER_STATUS_GOOD | DECODER_STATUS_COLOR;
384
385 switch (status & 0x18) {
386
387 case 0x00:
388 case 0x10:
389 case 0x14:
390 case 0x18:
391 res |= DECODER_STATUS_PAL;
392 break;
393
394 case 0x08:
395 res |= DECODER_STATUS_SECAM;
396 break;
397
398 case 0x04:
399 case 0x0c:
400 case 0x1c:
401 res |= DECODER_STATUS_NTSC;
402 break;
403 }
404 }
405
406 *(int *) arg = res;
407 }
408 break;
409
410 case DECODER_SET_NORM:
411 {
412 int *iarg = arg, data;
413
414 dprintk(1, KERN_DEBUG "%s: DECODER_SET_NORM %d\n",
415 I2C_NAME(client), *iarg);
416 switch (*iarg) {
417
418 case VIDEO_MODE_NTSC:
419 vpx3220_write_fp_block(client, init_ntsc,
420 sizeof(init_ntsc) >> 1);
421 dprintk(1, KERN_INFO "%s: norm switched to NTSC\n",
422 I2C_NAME(client));
423 break;
424
425 case VIDEO_MODE_PAL:
426 vpx3220_write_fp_block(client, init_pal,
427 sizeof(init_pal) >> 1);
428 dprintk(1, KERN_INFO "%s: norm switched to PAL\n",
429 I2C_NAME(client));
430 break;
431
432 case VIDEO_MODE_SECAM:
433 vpx3220_write_fp_block(client, init_secam,
434 sizeof(init_secam) >> 1);
435 dprintk(1, KERN_INFO "%s: norm switched to SECAM\n",
436 I2C_NAME(client));
437 break;
438
439 case VIDEO_MODE_AUTO:
440 /* FIXME This is only preliminary support */
441 data = vpx3220_fp_read(client, 0xf2) & 0x20;
442 vpx3220_fp_write(client, 0xf2, 0x00c0 | data);
443 dprintk(1, KERN_INFO "%s: norm switched to Auto\n",
444 I2C_NAME(client));
445 break;
446
447 default:
448 return -EINVAL;
449
450 }
451 decoder->norm = *iarg;
452 }
453 break;
454
455 case DECODER_SET_INPUT:
456 {
457 int *iarg = arg, data;
458
459 /* RJ: *iarg = 0: ST8 (PCTV) input
460 *iarg = 1: COMPOSITE input
461 *iarg = 2: SVHS input */
462
463 const int input[3][2] = {
464 {0x0c, 0},
465 {0x0d, 0},
466 {0x0e, 1}
467 };
468
469 if (*iarg < 0 || *iarg > 2)
470 return -EINVAL;
471
472 dprintk(1, KERN_INFO "%s: input switched to %s\n",
473 I2C_NAME(client), inputs[*iarg]);
474
475 vpx3220_write(client, 0x33, input[*iarg][0]);
476
477 data = vpx3220_fp_read(client, 0xf2) & ~(0x0020);
478 if (data < 0)
479 return data;
480 /* 0x0010 is required to latch the setting */
481 vpx3220_fp_write(client, 0xf2,
482 data | (input[*iarg][1] << 5) | 0x0010);
483
484 udelay(10);
485 }
486 break;
487
488 case DECODER_SET_OUTPUT:
489 {
490 int *iarg = arg;
491
492 /* not much choice of outputs */
493 if (*iarg != 0) {
494 return -EINVAL;
495 }
496 }
497 break;
498
499 case DECODER_ENABLE_OUTPUT:
500 {
501 int *iarg = arg;
502
503 dprintk(1, KERN_DEBUG "%s: DECODER_ENABLE_OUTPUT %d\n",
504 I2C_NAME(client), *iarg);
505
506 vpx3220_write(client, 0xf2, (*iarg ? 0x1b : 0x00));
507 }
508 break;
509
510 case DECODER_SET_PICTURE:
511 {
512 struct video_picture *pic = arg;
513
514 if (decoder->bright != pic->brightness) {
515 /* We want -128 to 128 we get 0-65535 */
516 decoder->bright = pic->brightness;
517 vpx3220_write(client, 0xe6,
518 (decoder->bright - 32768) >> 8);
519 }
520 if (decoder->contrast != pic->contrast) {
521 /* We want 0 to 64 we get 0-65535 */
522 /* Bit 7 and 8 is for noise shaping */
523 decoder->contrast = pic->contrast;
524 vpx3220_write(client, 0xe7,
525 (decoder->contrast >> 10) + 192);
526 }
527 if (decoder->sat != pic->colour) {
528 /* We want 0 to 4096 we get 0-65535 */
529 decoder->sat = pic->colour;
530 vpx3220_fp_write(client, 0xa0,
531 decoder->sat >> 4);
532 }
533 if (decoder->hue != pic->hue) {
534 /* We want -512 to 512 we get 0-65535 */
535 decoder->hue = pic->hue;
536 vpx3220_fp_write(client, 0x1c,
537 ((decoder->hue - 32768) >> 6) & 0xFFF);
538 }
539 }
540 break;
541
542 default:
543 return -EINVAL;
544 }
545
546 return 0;
547}
548
549static int
550vpx3220_init_client (struct i2c_client *client)
551{
552 vpx3220_write_block(client, init_common, sizeof(init_common));
553 vpx3220_write_fp_block(client, init_fp, sizeof(init_fp) >> 1);
554 /* Default to PAL */
555 vpx3220_write_fp_block(client, init_pal, sizeof(init_pal) >> 1);
556
557 return 0;
558}
559
560/* -----------------------------------------------------------------------
561 * Client managment code
562 */
563
564/*
565 * Generic i2c probe
566 * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
567 */
568static unsigned short normal_i2c[] =
569 { I2C_VPX3220 >> 1, (I2C_VPX3220 >> 1) + 4,
570 I2C_CLIENT_END
571};
572static unsigned short normal_i2c_range[] = { I2C_CLIENT_END };
573
574static unsigned short probe[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
575static unsigned short probe_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
576static unsigned short ignore[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
577static unsigned short ignore_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
578static unsigned short force[2] = { I2C_CLIENT_END , I2C_CLIENT_END };
579
580static struct i2c_client_address_data addr_data = {
581 .normal_i2c = normal_i2c,
582 .normal_i2c_range = normal_i2c_range,
583 .probe = probe,
584 .probe_range = probe_range,
585 .ignore = ignore,
586 .ignore_range = ignore_range,
587 .force = force
588};
589
590static struct i2c_driver vpx3220_i2c_driver;
591
592static int
593vpx3220_detach_client (struct i2c_client *client)
594{
595 struct vpx3220 *decoder = i2c_get_clientdata(client);
596 int err;
597
598 err = i2c_detach_client(client);
599 if (err) {
600 return err;
601 }
602
603 kfree(decoder);
604 kfree(client);
605
606 return 0;
607}
608
609static int
610vpx3220_detect_client (struct i2c_adapter *adapter,
611 int address,
612 int kind)
613{
614 int err;
615 struct i2c_client *client;
616 struct vpx3220 *decoder;
617
618 dprintk(1, VPX3220_DEBUG "%s\n", __func__);
619
620 /* Check if the adapter supports the needed features */
621 if (!i2c_check_functionality
622 (adapter, I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA))
623 return 0;
624
625 client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
626 if (client == NULL) {
627 return -ENOMEM;
628 }
629
630 memset(client, 0, sizeof(struct i2c_client));
631
632 client->addr = address;
633 client->adapter = adapter;
634 client->driver = &vpx3220_i2c_driver;
635 client->flags = I2C_CLIENT_ALLOW_USE;
636
637 /* Check for manufacture ID and part number */
638 if (kind < 0) {
639 u8 id;
640 u16 pn;
641
642 id = vpx3220_read(client, 0x00);
643 if (id != 0xec) {
644 dprintk(1,
645 KERN_INFO
646 "vpx3220_attach: Wrong manufacturer ID (0x%02x)\n",
647 id);
648 kfree(client);
649 return 0;
650 }
651
652 pn = (vpx3220_read(client, 0x02) << 8) +
653 vpx3220_read(client, 0x01);
654 switch (pn) {
655 case 0x4680:
656 strlcpy(I2C_NAME(client), "vpx3220a",
657 sizeof(I2C_NAME(client)));
658 break;
659 case 0x4260:
660 strlcpy(I2C_NAME(client), "vpx3216b",
661 sizeof(I2C_NAME(client)));
662 break;
663 case 0x4280:
664 strlcpy(I2C_NAME(client), "vpx3214c",
665 sizeof(I2C_NAME(client)));
666 break;
667 default:
668 dprintk(1,
669 KERN_INFO
670 "%s: Wrong part number (0x%04x)\n",
671 __func__, pn);
672 kfree(client);
673 return 0;
674 }
675 } else {
676 strlcpy(I2C_NAME(client), "forced vpx32xx",
677 sizeof(I2C_NAME(client)));
678 }
679
680 decoder = kmalloc(sizeof(struct vpx3220), GFP_KERNEL);
681 if (decoder == NULL) {
682 kfree(client);
683 return -ENOMEM;
684 }
685 memset(decoder, 0, sizeof(struct vpx3220));
686 decoder->norm = VIDEO_MODE_PAL;
687 decoder->input = 0;
688 decoder->enable = 1;
689 decoder->bright = 32768;
690 decoder->contrast = 32768;
691 decoder->hue = 32768;
692 decoder->sat = 32768;
693 i2c_set_clientdata(client, decoder);
694
695 err = i2c_attach_client(client);
696 if (err) {
697 kfree(client);
698 kfree(decoder);
699 return err;
700 }
701
702 dprintk(1, KERN_INFO "%s: vpx32xx client found at address 0x%02x\n",
703 I2C_NAME(client), client->addr << 1);
704
705 vpx3220_init_client(client);
706
707 return 0;
708}
709
710static int
711vpx3220_attach_adapter (struct i2c_adapter *adapter)
712{
713 int ret;
714
715 ret = i2c_probe(adapter, &addr_data, &vpx3220_detect_client);
716 dprintk(1, VPX3220_DEBUG "%s: i2c_probe returned %d\n",
717 __func__, ret);
718 return ret;
719}
720
721/* -----------------------------------------------------------------------
722 * Driver initialization and cleanup code
723 */
724
725static struct i2c_driver vpx3220_i2c_driver = {
726 .owner = THIS_MODULE,
727 .name = "vpx3220",
728
729 .id = I2C_DRIVERID_VPX3220,
730 .flags = I2C_DF_NOTIFY,
731
732 .attach_adapter = vpx3220_attach_adapter,
733 .detach_client = vpx3220_detach_client,
734 .command = vpx3220_command,
735};
736
737static int __init
738vpx3220_init (void)
739{
740 return i2c_add_driver(&vpx3220_i2c_driver);
741}
742
743static void __exit
744vpx3220_cleanup (void)
745{
746 i2c_del_driver(&vpx3220_i2c_driver);
747}
748
749module_init(vpx3220_init);
750module_exit(vpx3220_cleanup);
751
752MODULE_DESCRIPTION("vpx3220a/vpx3216b/vpx3214c video encoder driver");
753MODULE_AUTHOR("Laurent Pinchart");
754MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/w9966.c b/drivers/media/video/w9966.c
new file mode 100644
index 00000000000..c318ba32fba
--- /dev/null
+++ b/drivers/media/video/w9966.c
@@ -0,0 +1,984 @@
1/*
2 Winbond w9966cf Webcam parport driver.
3
4 Version 0.32
5
6 Copyright (C) 2001 Jakob Kemi <jakob.kemi@post.utfors.se>
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21*/
22/*
23 Supported devices:
24 *Lifeview FlyCam Supra (using the Philips saa7111a chip)
25
26 Does any other model using the w9966 interface chip exist ?
27
28 Todo:
29
30 *Add a working EPP mode, since DMA ECP read isn't implemented
31 in the parport drivers. (That's why it's so sloow)
32
33 *Add support for other ccd-control chips than the saa7111
34 please send me feedback on what kind of chips you have.
35
36 *Add proper probing. I don't know what's wrong with the IEEE1284
37 parport drivers but (IEEE1284_MODE_NIBBLE|IEEE1284_DEVICE_ID)
38 and nibble read seems to be broken for some peripherals.
39
40 *Add probing for onboard SRAM, port directions etc. (if possible)
41
42 *Add support for the hardware compressed modes (maybe using v4l2)
43
44 *Fix better support for the capture window (no skewed images, v4l
45 interface to capt. window)
46
47 *Probably some bugs that I don't know of
48
49 Please support me by sending feedback!
50
51 Changes:
52
53 Alan Cox: Removed RGB mode for kernel merge, added THIS_MODULE
54 and owner support for newer module locks
55*/
56
57#include <linux/module.h>
58#include <linux/init.h>
59#include <linux/delay.h>
60#include <linux/videodev.h>
61#include <linux/parport.h>
62
63//#define DEBUG // Undef me for production
64
65#ifdef DEBUG
66#define DPRINTF(x, a...) printk(KERN_DEBUG "W9966: %s(): "x, __FUNCTION__ , ##a)
67#else
68#define DPRINTF(x...)
69#endif
70
71/*
72 * Defines, simple typedefs etc.
73 */
74
75#define W9966_DRIVERNAME "W9966CF Webcam"
76#define W9966_MAXCAMS 4 // Maximum number of cameras
77#define W9966_RBUFFER 2048 // Read buffer (must be an even number)
78#define W9966_SRAMSIZE 131072 // 128kb
79#define W9966_SRAMID 0x02 // check w9966cf.pdf
80
81// Empirically determined window limits
82#define W9966_WND_MIN_X 16
83#define W9966_WND_MIN_Y 14
84#define W9966_WND_MAX_X 705
85#define W9966_WND_MAX_Y 253
86#define W9966_WND_MAX_W (W9966_WND_MAX_X - W9966_WND_MIN_X)
87#define W9966_WND_MAX_H (W9966_WND_MAX_Y - W9966_WND_MIN_Y)
88
89// Keep track of our current state
90#define W9966_STATE_PDEV 0x01
91#define W9966_STATE_CLAIMED 0x02
92#define W9966_STATE_VDEV 0x04
93
94#define W9966_I2C_W_ID 0x48
95#define W9966_I2C_R_ID 0x49
96#define W9966_I2C_R_DATA 0x08
97#define W9966_I2C_R_CLOCK 0x04
98#define W9966_I2C_W_DATA 0x02
99#define W9966_I2C_W_CLOCK 0x01
100
101struct w9966_dev {
102 unsigned char dev_state;
103 unsigned char i2c_state;
104 unsigned short ppmode;
105 struct parport* pport;
106 struct pardevice* pdev;
107 struct video_device vdev;
108 unsigned short width;
109 unsigned short height;
110 unsigned char brightness;
111 signed char contrast;
112 signed char color;
113 signed char hue;
114};
115
116/*
117 * Module specific properties
118 */
119
120MODULE_AUTHOR("Jakob Kemi <jakob.kemi@post.utfors.se>");
121MODULE_DESCRIPTION("Winbond w9966cf WebCam driver (0.32)");
122MODULE_LICENSE("GPL");
123
124
125#ifdef MODULE
126static const char* pardev[] = {[0 ... W9966_MAXCAMS] = ""};
127#else
128static const char* pardev[] = {[0 ... W9966_MAXCAMS] = "aggressive"};
129#endif
130module_param_array(pardev, charp, NULL, 0);
131MODULE_PARM_DESC(pardev, "pardev: where to search for\n\
132\teach camera. 'aggressive' means brute-force search.\n\
133\tEg: >pardev=parport3,aggressive,parport2,parport1< would assign\n\
134\tcam 1 to parport3 and search every parport for cam 2 etc...");
135
136static int parmode = 0;
137module_param(parmode, int, 0);
138MODULE_PARM_DESC(parmode, "parmode: transfer mode (0=auto, 1=ecp, 2=epp");
139
140static int video_nr = -1;
141module_param(video_nr, int, 0);
142
143/*
144 * Private data
145 */
146
147static struct w9966_dev w9966_cams[W9966_MAXCAMS];
148
149/*
150 * Private function declares
151 */
152
153static inline void w9966_setState(struct w9966_dev* cam, int mask, int val);
154static inline int w9966_getState(struct w9966_dev* cam, int mask, int val);
155static inline void w9966_pdev_claim(struct w9966_dev *vdev);
156static inline void w9966_pdev_release(struct w9966_dev *vdev);
157
158static int w9966_rReg(struct w9966_dev* cam, int reg);
159static int w9966_wReg(struct w9966_dev* cam, int reg, int data);
160#if 0
161static int w9966_rReg_i2c(struct w9966_dev* cam, int reg);
162#endif
163static int w9966_wReg_i2c(struct w9966_dev* cam, int reg, int data);
164static int w9966_findlen(int near, int size, int maxlen);
165static int w9966_calcscale(int size, int min, int max, int* beg, int* end, unsigned char* factor);
166static int w9966_setup(struct w9966_dev* cam, int x1, int y1, int x2, int y2, int w, int h);
167
168static int w9966_init(struct w9966_dev* cam, struct parport* port);
169static void w9966_term(struct w9966_dev* cam);
170
171static inline void w9966_i2c_setsda(struct w9966_dev* cam, int state);
172static inline int w9966_i2c_setscl(struct w9966_dev* cam, int state);
173static inline int w9966_i2c_getsda(struct w9966_dev* cam);
174static inline int w9966_i2c_getscl(struct w9966_dev* cam);
175static int w9966_i2c_wbyte(struct w9966_dev* cam, int data);
176#if 0
177static int w9966_i2c_rbyte(struct w9966_dev* cam);
178#endif
179
180static int w9966_v4l_ioctl(struct inode *inode, struct file *file,
181 unsigned int cmd, unsigned long arg);
182static ssize_t w9966_v4l_read(struct file *file, char __user *buf,
183 size_t count, loff_t *ppos);
184
185static struct file_operations w9966_fops = {
186 .owner = THIS_MODULE,
187 .open = video_exclusive_open,
188 .release = video_exclusive_release,
189 .ioctl = w9966_v4l_ioctl,
190 .read = w9966_v4l_read,
191 .llseek = no_llseek,
192};
193static struct video_device w9966_template = {
194 .owner = THIS_MODULE,
195 .name = W9966_DRIVERNAME,
196 .type = VID_TYPE_CAPTURE | VID_TYPE_SCALES,
197 .hardware = VID_HARDWARE_W9966,
198 .fops = &w9966_fops,
199};
200
201/*
202 * Private function defines
203 */
204
205
206// Set camera phase flags, so we know what to uninit when terminating
207static inline void w9966_setState(struct w9966_dev* cam, int mask, int val)
208{
209 cam->dev_state = (cam->dev_state & ~mask) ^ val;
210}
211
212// Get camera phase flags
213static inline int w9966_getState(struct w9966_dev* cam, int mask, int val)
214{
215 return ((cam->dev_state & mask) == val);
216}
217
218// Claim parport for ourself
219static inline void w9966_pdev_claim(struct w9966_dev* cam)
220{
221 if (w9966_getState(cam, W9966_STATE_CLAIMED, W9966_STATE_CLAIMED))
222 return;
223 parport_claim_or_block(cam->pdev);
224 w9966_setState(cam, W9966_STATE_CLAIMED, W9966_STATE_CLAIMED);
225}
226
227// Release parport for others to use
228static inline void w9966_pdev_release(struct w9966_dev* cam)
229{
230 if (w9966_getState(cam, W9966_STATE_CLAIMED, 0))
231 return;
232 parport_release(cam->pdev);
233 w9966_setState(cam, W9966_STATE_CLAIMED, 0);
234}
235
236// Read register from W9966 interface-chip
237// Expects a claimed pdev
238// -1 on error, else register data (byte)
239static int w9966_rReg(struct w9966_dev* cam, int reg)
240{
241 // ECP, read, regtransfer, REG, REG, REG, REG, REG
242 const unsigned char addr = 0x80 | (reg & 0x1f);
243 unsigned char val;
244
245 if (parport_negotiate(cam->pport, cam->ppmode | IEEE1284_ADDR) != 0)
246 return -1;
247 if (parport_write(cam->pport, &addr, 1) != 1)
248 return -1;
249 if (parport_negotiate(cam->pport, cam->ppmode | IEEE1284_DATA) != 0)
250 return -1;
251 if (parport_read(cam->pport, &val, 1) != 1)
252 return -1;
253
254 return val;
255}
256
257// Write register to W9966 interface-chip
258// Expects a claimed pdev
259// -1 on error
260static int w9966_wReg(struct w9966_dev* cam, int reg, int data)
261{
262 // ECP, write, regtransfer, REG, REG, REG, REG, REG
263 const unsigned char addr = 0xc0 | (reg & 0x1f);
264 const unsigned char val = data;
265
266 if (parport_negotiate(cam->pport, cam->ppmode | IEEE1284_ADDR) != 0)
267 return -1;
268 if (parport_write(cam->pport, &addr, 1) != 1)
269 return -1;
270 if (parport_negotiate(cam->pport, cam->ppmode | IEEE1284_DATA) != 0)
271 return -1;
272 if (parport_write(cam->pport, &val, 1) != 1)
273 return -1;
274
275 return 0;
276}
277
278// Initialize camera device. Setup all internal flags, set a
279// default video mode, setup ccd-chip, register v4l device etc..
280// Also used for 'probing' of hardware.
281// -1 on error
282static int w9966_init(struct w9966_dev* cam, struct parport* port)
283{
284 if (cam->dev_state != 0)
285 return -1;
286
287 cam->pport = port;
288 cam->brightness = 128;
289 cam->contrast = 64;
290 cam->color = 64;
291 cam->hue = 0;
292
293// Select requested transfer mode
294 switch(parmode)
295 {
296 default: // Auto-detect (priority: hw-ecp, hw-epp, sw-ecp)
297 case 0:
298 if (port->modes & PARPORT_MODE_ECP)
299 cam->ppmode = IEEE1284_MODE_ECP;
300 else if (port->modes & PARPORT_MODE_EPP)
301 cam->ppmode = IEEE1284_MODE_EPP;
302 else
303 cam->ppmode = IEEE1284_MODE_ECP;
304 break;
305 case 1: // hw- or sw-ecp
306 cam->ppmode = IEEE1284_MODE_ECP;
307 break;
308 case 2: // hw- or sw-epp
309 cam->ppmode = IEEE1284_MODE_EPP;
310 break;
311 }
312
313// Tell the parport driver that we exists
314 cam->pdev = parport_register_device(port, "w9966", NULL, NULL, NULL, 0, NULL);
315 if (cam->pdev == NULL) {
316 DPRINTF("parport_register_device() failed\n");
317 return -1;
318 }
319 w9966_setState(cam, W9966_STATE_PDEV, W9966_STATE_PDEV);
320
321 w9966_pdev_claim(cam);
322
323// Setup a default capture mode
324 if (w9966_setup(cam, 0, 0, 1023, 1023, 200, 160) != 0) {
325 DPRINTF("w9966_setup() failed.\n");
326 return -1;
327 }
328
329 w9966_pdev_release(cam);
330
331// Fill in the video_device struct and register us to v4l
332 memcpy(&cam->vdev, &w9966_template, sizeof(struct video_device));
333 cam->vdev.priv = cam;
334
335 if (video_register_device(&cam->vdev, VFL_TYPE_GRABBER, video_nr) == -1)
336 return -1;
337
338 w9966_setState(cam, W9966_STATE_VDEV, W9966_STATE_VDEV);
339
340 // All ok
341 printk(
342 "w9966cf: Found and initialized a webcam on %s.\n",
343 cam->pport->name
344 );
345 return 0;
346}
347
348
349// Terminate everything gracefully
350static void w9966_term(struct w9966_dev* cam)
351{
352// Unregister from v4l
353 if (w9966_getState(cam, W9966_STATE_VDEV, W9966_STATE_VDEV)) {
354 video_unregister_device(&cam->vdev);
355 w9966_setState(cam, W9966_STATE_VDEV, 0);
356 }
357
358// Terminate from IEEE1284 mode and release pdev block
359 if (w9966_getState(cam, W9966_STATE_PDEV, W9966_STATE_PDEV)) {
360 w9966_pdev_claim(cam);
361 parport_negotiate(cam->pport, IEEE1284_MODE_COMPAT);
362 w9966_pdev_release(cam);
363 }
364
365// Unregister from parport
366 if (w9966_getState(cam, W9966_STATE_PDEV, W9966_STATE_PDEV)) {
367 parport_unregister_device(cam->pdev);
368 w9966_setState(cam, W9966_STATE_PDEV, 0);
369 }
370}
371
372
373// Find a good length for capture window (used both for W and H)
374// A bit ugly but pretty functional. The capture length
375// have to match the downscale
376static int w9966_findlen(int near, int size, int maxlen)
377{
378 int bestlen = size;
379 int besterr = abs(near - bestlen);
380 int len;
381
382 for(len = size+1;len < maxlen;len++)
383 {
384 int err;
385 if ( ((64*size) %len) != 0)
386 continue;
387
388 err = abs(near - len);
389
390 // Only continue as long as we keep getting better values
391 if (err > besterr)
392 break;
393
394 besterr = err;
395 bestlen = len;
396 }
397
398 return bestlen;
399}
400
401// Modify capture window (if necessary)
402// and calculate downscaling
403// Return -1 on error
404static int w9966_calcscale(int size, int min, int max, int* beg, int* end, unsigned char* factor)
405{
406 int maxlen = max - min;
407 int len = *end - *beg + 1;
408 int newlen = w9966_findlen(len, size, maxlen);
409 int err = newlen - len;
410
411 // Check for bad format
412 if (newlen > maxlen || newlen < size)
413 return -1;
414
415 // Set factor (6 bit fixed)
416 *factor = (64*size) / newlen;
417 if (*factor == 64)
418 *factor = 0x00; // downscale is disabled
419 else
420 *factor |= 0x80; // set downscale-enable bit
421
422 // Modify old beginning and end
423 *beg -= err / 2;
424 *end += err - (err / 2);
425
426 // Move window if outside borders
427 if (*beg < min) {
428 *end += min - *beg;
429 *beg += min - *beg;
430 }
431 if (*end > max) {
432 *beg -= *end - max;
433 *end -= *end - max;
434 }
435
436 return 0;
437}
438
439// Setup the cameras capture window etc.
440// Expects a claimed pdev
441// return -1 on error
442static int w9966_setup(struct w9966_dev* cam, int x1, int y1, int x2, int y2, int w, int h)
443{
444 unsigned int i;
445 unsigned int enh_s, enh_e;
446 unsigned char scale_x, scale_y;
447 unsigned char regs[0x1c];
448 unsigned char saa7111_regs[] = {
449 0x21, 0x00, 0xd8, 0x23, 0x00, 0x80, 0x80, 0x00,
450 0x88, 0x10, 0x80, 0x40, 0x40, 0x00, 0x01, 0x00,
451 0x48, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
452 0x00, 0x00, 0x00, 0x71, 0xe7, 0x00, 0x00, 0xc0
453 };
454
455
456 if (w*h*2 > W9966_SRAMSIZE)
457 {
458 DPRINTF("capture window exceeds SRAM size!.\n");
459 w = 200; h = 160; // Pick default values
460 }
461
462 w &= ~0x1;
463 if (w < 2) w = 2;
464 if (h < 1) h = 1;
465 if (w > W9966_WND_MAX_W) w = W9966_WND_MAX_W;
466 if (h > W9966_WND_MAX_H) h = W9966_WND_MAX_H;
467
468 cam->width = w;
469 cam->height = h;
470
471 enh_s = 0;
472 enh_e = w*h*2;
473
474// Modify capture window if necessary and calculate downscaling
475 if (
476 w9966_calcscale(w, W9966_WND_MIN_X, W9966_WND_MAX_X, &x1, &x2, &scale_x) != 0 ||
477 w9966_calcscale(h, W9966_WND_MIN_Y, W9966_WND_MAX_Y, &y1, &y2, &scale_y) != 0
478 ) return -1;
479
480 DPRINTF(
481 "%dx%d, x: %d<->%d, y: %d<->%d, sx: %d/64, sy: %d/64.\n",
482 w, h, x1, x2, y1, y2, scale_x&~0x80, scale_y&~0x80
483 );
484
485// Setup registers
486 regs[0x00] = 0x00; // Set normal operation
487 regs[0x01] = 0x18; // Capture mode
488 regs[0x02] = scale_y; // V-scaling
489 regs[0x03] = scale_x; // H-scaling
490
491 // Capture window
492 regs[0x04] = (x1 & 0x0ff); // X-start (8 low bits)
493 regs[0x05] = (x1 & 0x300)>>8; // X-start (2 high bits)
494 regs[0x06] = (y1 & 0x0ff); // Y-start (8 low bits)
495 regs[0x07] = (y1 & 0x300)>>8; // Y-start (2 high bits)
496 regs[0x08] = (x2 & 0x0ff); // X-end (8 low bits)
497 regs[0x09] = (x2 & 0x300)>>8; // X-end (2 high bits)
498 regs[0x0a] = (y2 & 0x0ff); // Y-end (8 low bits)
499
500 regs[0x0c] = W9966_SRAMID; // SRAM-banks (1x 128kb)
501
502 // Enhancement layer
503 regs[0x0d] = (enh_s& 0x000ff); // Enh. start (0-7)
504 regs[0x0e] = (enh_s& 0x0ff00)>>8; // Enh. start (8-15)
505 regs[0x0f] = (enh_s& 0x70000)>>16; // Enh. start (16-17/18??)
506 regs[0x10] = (enh_e& 0x000ff); // Enh. end (0-7)
507 regs[0x11] = (enh_e& 0x0ff00)>>8; // Enh. end (8-15)
508 regs[0x12] = (enh_e& 0x70000)>>16; // Enh. end (16-17/18??)
509
510 // Misc
511 regs[0x13] = 0x40; // VEE control (raw 4:2:2)
512 regs[0x17] = 0x00; // ???
513 regs[0x18] = cam->i2c_state = 0x00; // Serial bus
514 regs[0x19] = 0xff; // I/O port direction control
515 regs[0x1a] = 0xff; // I/O port data register
516 regs[0x1b] = 0x10; // ???
517
518 // SAA7111 chip settings
519 saa7111_regs[0x0a] = cam->brightness;
520 saa7111_regs[0x0b] = cam->contrast;
521 saa7111_regs[0x0c] = cam->color;
522 saa7111_regs[0x0d] = cam->hue;
523
524// Reset (ECP-fifo & serial-bus)
525 if (w9966_wReg(cam, 0x00, 0x03) == -1)
526 return -1;
527
528// Write regs to w9966cf chip
529 for (i = 0; i < 0x1c; i++)
530 if (w9966_wReg(cam, i, regs[i]) == -1)
531 return -1;
532
533// Write regs to saa7111 chip
534 for (i = 0; i < 0x20; i++)
535 if (w9966_wReg_i2c(cam, i, saa7111_regs[i]) == -1)
536 return -1;
537
538 return 0;
539}
540
541/*
542 * Ugly and primitive i2c protocol functions
543 */
544
545// Sets the data line on the i2c bus.
546// Expects a claimed pdev.
547static inline void w9966_i2c_setsda(struct w9966_dev* cam, int state)
548{
549 if (state)
550 cam->i2c_state |= W9966_I2C_W_DATA;
551 else
552 cam->i2c_state &= ~W9966_I2C_W_DATA;
553
554 w9966_wReg(cam, 0x18, cam->i2c_state);
555 udelay(5);
556}
557
558// Get peripheral clock line
559// Expects a claimed pdev.
560static inline int w9966_i2c_getscl(struct w9966_dev* cam)
561{
562 const unsigned char state = w9966_rReg(cam, 0x18);
563 return ((state & W9966_I2C_R_CLOCK) > 0);
564}
565
566// Sets the clock line on the i2c bus.
567// Expects a claimed pdev. -1 on error
568static inline int w9966_i2c_setscl(struct w9966_dev* cam, int state)
569{
570 unsigned long timeout;
571
572 if (state)
573 cam->i2c_state |= W9966_I2C_W_CLOCK;
574 else
575 cam->i2c_state &= ~W9966_I2C_W_CLOCK;
576
577 w9966_wReg(cam, 0x18, cam->i2c_state);
578 udelay(5);
579
580 // we go to high, we also expect the peripheral to ack.
581 if (state) {
582 timeout = jiffies + 100;
583 while (!w9966_i2c_getscl(cam)) {
584 if (time_after(jiffies, timeout))
585 return -1;
586 }
587 }
588 return 0;
589}
590
591// Get peripheral data line
592// Expects a claimed pdev.
593static inline int w9966_i2c_getsda(struct w9966_dev* cam)
594{
595 const unsigned char state = w9966_rReg(cam, 0x18);
596 return ((state & W9966_I2C_R_DATA) > 0);
597}
598
599// Write a byte with ack to the i2c bus.
600// Expects a claimed pdev. -1 on error
601static int w9966_i2c_wbyte(struct w9966_dev* cam, int data)
602{
603 int i;
604 for (i = 7; i >= 0; i--)
605 {
606 w9966_i2c_setsda(cam, (data >> i) & 0x01);
607
608 if (w9966_i2c_setscl(cam, 1) == -1)
609 return -1;
610 w9966_i2c_setscl(cam, 0);
611 }
612
613 w9966_i2c_setsda(cam, 1);
614
615 if (w9966_i2c_setscl(cam, 1) == -1)
616 return -1;
617 w9966_i2c_setscl(cam, 0);
618
619 return 0;
620}
621
622// Read a data byte with ack from the i2c-bus
623// Expects a claimed pdev. -1 on error
624#if 0
625static int w9966_i2c_rbyte(struct w9966_dev* cam)
626{
627 unsigned char data = 0x00;
628 int i;
629
630 w9966_i2c_setsda(cam, 1);
631
632 for (i = 0; i < 8; i++)
633 {
634 if (w9966_i2c_setscl(cam, 1) == -1)
635 return -1;
636 data = data << 1;
637 if (w9966_i2c_getsda(cam))
638 data |= 0x01;
639
640 w9966_i2c_setscl(cam, 0);
641 }
642 return data;
643}
644#endif
645
646// Read a register from the i2c device.
647// Expects claimed pdev. -1 on error
648#if 0
649static int w9966_rReg_i2c(struct w9966_dev* cam, int reg)
650{
651 int data;
652
653 w9966_i2c_setsda(cam, 0);
654 w9966_i2c_setscl(cam, 0);
655
656 if (
657 w9966_i2c_wbyte(cam, W9966_I2C_W_ID) == -1 ||
658 w9966_i2c_wbyte(cam, reg) == -1
659 )
660 return -1;
661
662 w9966_i2c_setsda(cam, 1);
663 if (w9966_i2c_setscl(cam, 1) == -1)
664 return -1;
665 w9966_i2c_setsda(cam, 0);
666 w9966_i2c_setscl(cam, 0);
667
668 if (
669 w9966_i2c_wbyte(cam, W9966_I2C_R_ID) == -1 ||
670 (data = w9966_i2c_rbyte(cam)) == -1
671 )
672 return -1;
673
674 w9966_i2c_setsda(cam, 0);
675
676 if (w9966_i2c_setscl(cam, 1) == -1)
677 return -1;
678 w9966_i2c_setsda(cam, 1);
679
680 return data;
681}
682#endif
683
684// Write a register to the i2c device.
685// Expects claimed pdev. -1 on error
686static int w9966_wReg_i2c(struct w9966_dev* cam, int reg, int data)
687{
688 w9966_i2c_setsda(cam, 0);
689 w9966_i2c_setscl(cam, 0);
690
691 if (
692 w9966_i2c_wbyte(cam, W9966_I2C_W_ID) == -1 ||
693 w9966_i2c_wbyte(cam, reg) == -1 ||
694 w9966_i2c_wbyte(cam, data) == -1
695 )
696 return -1;
697
698 w9966_i2c_setsda(cam, 0);
699 if (w9966_i2c_setscl(cam, 1) == -1)
700 return -1;
701
702 w9966_i2c_setsda(cam, 1);
703
704 return 0;
705}
706
707/*
708 * Video4linux interfacing
709 */
710
711static int w9966_v4l_do_ioctl(struct inode *inode, struct file *file,
712 unsigned int cmd, void *arg)
713{
714 struct video_device *vdev = video_devdata(file);
715 struct w9966_dev *cam = vdev->priv;
716
717 switch(cmd)
718 {
719 case VIDIOCGCAP:
720 {
721 static struct video_capability vcap = {
722 .name = W9966_DRIVERNAME,
723 .type = VID_TYPE_CAPTURE | VID_TYPE_SCALES,
724 .channels = 1,
725 .maxwidth = W9966_WND_MAX_W,
726 .maxheight = W9966_WND_MAX_H,
727 .minwidth = 2,
728 .minheight = 1,
729 };
730 struct video_capability *cap = arg;
731 *cap = vcap;
732 return 0;
733 }
734 case VIDIOCGCHAN:
735 {
736 struct video_channel *vch = arg;
737 if(vch->channel != 0) // We only support one channel (#0)
738 return -EINVAL;
739 memset(vch,0,sizeof(*vch));
740 strcpy(vch->name, "CCD-input");
741 vch->type = VIDEO_TYPE_CAMERA;
742 return 0;
743 }
744 case VIDIOCSCHAN:
745 {
746 struct video_channel *vch = arg;
747 if(vch->channel != 0)
748 return -EINVAL;
749 return 0;
750 }
751 case VIDIOCGTUNER:
752 {
753 struct video_tuner *vtune = arg;
754 if(vtune->tuner != 0)
755 return -EINVAL;
756 strcpy(vtune->name, "no tuner");
757 vtune->rangelow = 0;
758 vtune->rangehigh = 0;
759 vtune->flags = VIDEO_TUNER_NORM;
760 vtune->mode = VIDEO_MODE_AUTO;
761 vtune->signal = 0xffff;
762 return 0;
763 }
764 case VIDIOCSTUNER:
765 {
766 struct video_tuner *vtune = arg;
767 if (vtune->tuner != 0)
768 return -EINVAL;
769 if (vtune->mode != VIDEO_MODE_AUTO)
770 return -EINVAL;
771 return 0;
772 }
773 case VIDIOCGPICT:
774 {
775 struct video_picture vpic = {
776 cam->brightness << 8, // brightness
777 (cam->hue + 128) << 8, // hue
778 cam->color << 9, // color
779 cam->contrast << 9, // contrast
780 0x8000, // whiteness
781 16, VIDEO_PALETTE_YUV422// bpp, palette format
782 };
783 struct video_picture *pic = arg;
784 *pic = vpic;
785 return 0;
786 }
787 case VIDIOCSPICT:
788 {
789 struct video_picture *vpic = arg;
790 if (vpic->depth != 16 || vpic->palette != VIDEO_PALETTE_YUV422)
791 return -EINVAL;
792
793 cam->brightness = vpic->brightness >> 8;
794 cam->hue = (vpic->hue >> 8) - 128;
795 cam->color = vpic->colour >> 9;
796 cam->contrast = vpic->contrast >> 9;
797
798 w9966_pdev_claim(cam);
799
800 if (
801 w9966_wReg_i2c(cam, 0x0a, cam->brightness) == -1 ||
802 w9966_wReg_i2c(cam, 0x0b, cam->contrast) == -1 ||
803 w9966_wReg_i2c(cam, 0x0c, cam->color) == -1 ||
804 w9966_wReg_i2c(cam, 0x0d, cam->hue) == -1
805 ) {
806 w9966_pdev_release(cam);
807 return -EIO;
808 }
809
810 w9966_pdev_release(cam);
811 return 0;
812 }
813 case VIDIOCSWIN:
814 {
815 int ret;
816 struct video_window *vwin = arg;
817
818 if (vwin->flags != 0)
819 return -EINVAL;
820 if (vwin->clipcount != 0)
821 return -EINVAL;
822 if (vwin->width < 2 || vwin->width > W9966_WND_MAX_W)
823 return -EINVAL;
824 if (vwin->height < 1 || vwin->height > W9966_WND_MAX_H)
825 return -EINVAL;
826
827 // Update camera regs
828 w9966_pdev_claim(cam);
829 ret = w9966_setup(cam, 0, 0, 1023, 1023, vwin->width, vwin->height);
830 w9966_pdev_release(cam);
831
832 if (ret != 0) {
833 DPRINTF("VIDIOCSWIN: w9966_setup() failed.\n");
834 return -EIO;
835 }
836
837 return 0;
838 }
839 case VIDIOCGWIN:
840 {
841 struct video_window *vwin = arg;
842 memset(vwin, 0, sizeof(*vwin));
843 vwin->width = cam->width;
844 vwin->height = cam->height;
845 return 0;
846 }
847 // Unimplemented
848 case VIDIOCCAPTURE:
849 case VIDIOCGFBUF:
850 case VIDIOCSFBUF:
851 case VIDIOCKEY:
852 case VIDIOCGFREQ:
853 case VIDIOCSFREQ:
854 case VIDIOCGAUDIO:
855 case VIDIOCSAUDIO:
856 return -EINVAL;
857 default:
858 return -ENOIOCTLCMD;
859 }
860 return 0;
861}
862
863static int w9966_v4l_ioctl(struct inode *inode, struct file *file,
864 unsigned int cmd, unsigned long arg)
865{
866 return video_usercopy(inode, file, cmd, arg, w9966_v4l_do_ioctl);
867}
868
869// Capture data
870static ssize_t w9966_v4l_read(struct file *file, char __user *buf,
871 size_t count, loff_t *ppos)
872{
873 struct video_device *vdev = video_devdata(file);
874 struct w9966_dev *cam = vdev->priv;
875 unsigned char addr = 0xa0; // ECP, read, CCD-transfer, 00000
876 unsigned char __user *dest = (unsigned char __user *)buf;
877 unsigned long dleft = count;
878 unsigned char *tbuf;
879
880 // Why would anyone want more than this??
881 if (count > cam->width * cam->height * 2)
882 return -EINVAL;
883
884 w9966_pdev_claim(cam);
885 w9966_wReg(cam, 0x00, 0x02); // Reset ECP-FIFO buffer
886 w9966_wReg(cam, 0x00, 0x00); // Return to normal operation
887 w9966_wReg(cam, 0x01, 0x98); // Enable capture
888
889 // write special capture-addr and negotiate into data transfer
890 if (
891 (parport_negotiate(cam->pport, cam->ppmode|IEEE1284_ADDR) != 0 )||
892 (parport_write(cam->pport, &addr, 1) != 1 )||
893 (parport_negotiate(cam->pport, cam->ppmode|IEEE1284_DATA) != 0 )
894 ) {
895 w9966_pdev_release(cam);
896 return -EFAULT;
897 }
898
899 tbuf = kmalloc(W9966_RBUFFER, GFP_KERNEL);
900 if (tbuf == NULL) {
901 count = -ENOMEM;
902 goto out;
903 }
904
905 while(dleft > 0)
906 {
907 unsigned long tsize = (dleft > W9966_RBUFFER) ? W9966_RBUFFER : dleft;
908
909 if (parport_read(cam->pport, tbuf, tsize) < tsize) {
910 count = -EFAULT;
911 goto out;
912 }
913 if (copy_to_user(dest, tbuf, tsize) != 0) {
914 count = -EFAULT;
915 goto out;
916 }
917 dest += tsize;
918 dleft -= tsize;
919 }
920
921 w9966_wReg(cam, 0x01, 0x18); // Disable capture
922
923out:
924 kfree(tbuf);
925 w9966_pdev_release(cam);
926
927 return count;
928}
929
930
931// Called once for every parport on init
932static void w9966_attach(struct parport *port)
933{
934 int i;
935
936 for (i = 0; i < W9966_MAXCAMS; i++)
937 {
938 if (w9966_cams[i].dev_state != 0) // Cam is already assigned
939 continue;
940 if (
941 strcmp(pardev[i], "aggressive") == 0 ||
942 strcmp(pardev[i], port->name) == 0
943 ) {
944 if (w9966_init(&w9966_cams[i], port) != 0)
945 w9966_term(&w9966_cams[i]);
946 break; // return
947 }
948 }
949}
950
951// Called once for every parport on termination
952static void w9966_detach(struct parport *port)
953{
954 int i;
955 for (i = 0; i < W9966_MAXCAMS; i++)
956 if (w9966_cams[i].dev_state != 0 && w9966_cams[i].pport == port)
957 w9966_term(&w9966_cams[i]);
958}
959
960
961static struct parport_driver w9966_ppd = {
962 .name = W9966_DRIVERNAME,
963 .attach = w9966_attach,
964 .detach = w9966_detach,
965};
966
967// Module entry point
968static int __init w9966_mod_init(void)
969{
970 int i;
971 for (i = 0; i < W9966_MAXCAMS; i++)
972 w9966_cams[i].dev_state = 0;
973
974 return parport_register_driver(&w9966_ppd);
975}
976
977// Module cleanup
978static void __exit w9966_mod_term(void)
979{
980 parport_unregister_driver(&w9966_ppd);
981}
982
983module_init(w9966_mod_init);
984module_exit(w9966_mod_term);
diff --git a/drivers/media/video/zoran.h b/drivers/media/video/zoran.h
new file mode 100644
index 00000000000..9fe6ad3b635
--- /dev/null
+++ b/drivers/media/video/zoran.h
@@ -0,0 +1,515 @@
1/*
2 * zoran - Iomega Buz driver
3 *
4 * Copyright (C) 1999 Rainer Johanni <Rainer@Johanni.de>
5 *
6 * based on
7 *
8 * zoran.0.0.3 Copyright (C) 1998 Dave Perks <dperks@ibm.net>
9 *
10 * and
11 *
12 * bttv - Bt848 frame grabber driver
13 * Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
14 * & Marcus Metzler (mocm@thp.uni-koeln.de)
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 */
30
31#ifndef _BUZ_H_
32#define _BUZ_H_
33
34struct zoran_requestbuffers {
35 unsigned long count; /* Number of buffers for MJPEG grabbing */
36 unsigned long size; /* Size PER BUFFER in bytes */
37};
38
39struct zoran_sync {
40 unsigned long frame; /* number of buffer that has been free'd */
41 unsigned long length; /* number of code bytes in buffer (capture only) */
42 unsigned long seq; /* frame sequence number */
43 struct timeval timestamp; /* timestamp */
44};
45
46struct zoran_status {
47 int input; /* Input channel, has to be set prior to BUZIOC_G_STATUS */
48 int signal; /* Returned: 1 if valid video signal detected */
49 int norm; /* Returned: VIDEO_MODE_PAL or VIDEO_MODE_NTSC */
50 int color; /* Returned: 1 if color signal detected */
51};
52
53struct zoran_params {
54
55 /* The following parameters can only be queried */
56
57 int major_version; /* Major version number of driver */
58 int minor_version; /* Minor version number of driver */
59
60 /* Main control parameters */
61
62 int input; /* Input channel: 0 = Composite, 1 = S-VHS */
63 int norm; /* Norm: VIDEO_MODE_PAL or VIDEO_MODE_NTSC */
64 int decimation; /* decimation of captured video,
65 * enlargement of video played back.
66 * Valid values are 1, 2, 4 or 0.
67 * 0 is a special value where the user
68 * has full control over video scaling */
69
70 /* The following parameters only have to be set if decimation==0,
71 * for other values of decimation they provide the data how the image is captured */
72
73 int HorDcm; /* Horizontal decimation: 1, 2 or 4 */
74 int VerDcm; /* Vertical decimation: 1 or 2 */
75 int TmpDcm; /* Temporal decimation: 1 or 2,
76 * if TmpDcm==2 in capture every second frame is dropped,
77 * in playback every frame is played twice */
78 int field_per_buff; /* Number of fields per buffer: 1 or 2 */
79 int img_x; /* start of image in x direction */
80 int img_y; /* start of image in y direction */
81 int img_width; /* image width BEFORE decimation,
82 * must be a multiple of HorDcm*16 */
83 int img_height; /* image height BEFORE decimation,
84 * must be a multiple of VerDcm*8 */
85
86 /* --- End of parameters for decimation==0 only --- */
87
88 /* JPEG control parameters */
89
90 int quality; /* Measure for quality of compressed images.
91 * Scales linearly with the size of the compressed images.
92 * Must be beetween 0 and 100, 100 is a compression
93 * ratio of 1:4 */
94
95 int odd_even; /* Which field should come first ??? */
96
97 int APPn; /* Number of APP segment to be written, must be 0..15 */
98 int APP_len; /* Length of data in JPEG APPn segment */
99 char APP_data[60]; /* Data in the JPEG APPn segment. */
100
101 int COM_len; /* Length of data in JPEG COM segment */
102 char COM_data[60]; /* Data in JPEG COM segment */
103
104 unsigned long jpeg_markers; /* Which markers should go into the JPEG output.
105 * Unless you exactly know what you do, leave them untouched.
106 * Inluding less markers will make the resulting code
107 * smaller, but there will be fewer aplications
108 * which can read it.
109 * The presence of the APP and COM marker is
110 * influenced by APP0_len and COM_len ONLY! */
111#define JPEG_MARKER_DHT (1<<3) /* Define Huffman Tables */
112#define JPEG_MARKER_DQT (1<<4) /* Define Quantization Tables */
113#define JPEG_MARKER_DRI (1<<5) /* Define Restart Interval */
114#define JPEG_MARKER_COM (1<<6) /* Comment segment */
115#define JPEG_MARKER_APP (1<<7) /* App segment, driver will allways use APP0 */
116
117 int VFIFO_FB; /* Flag for enabling Video Fifo Feedback.
118 * If this flag is turned on and JPEG decompressing
119 * is going to the screen, the decompress process
120 * is stopped every time the Video Fifo is full.
121 * This enables a smooth decompress to the screen
122 * but the video output signal will get scrambled */
123
124 /* Misc */
125
126 char reserved[312]; /* Makes 512 bytes for this structure */
127};
128
129/*
130Private IOCTL to set up for displaying MJPEG
131*/
132#define BUZIOC_G_PARAMS _IOR ('v', BASE_VIDIOCPRIVATE+0, struct zoran_params)
133#define BUZIOC_S_PARAMS _IOWR('v', BASE_VIDIOCPRIVATE+1, struct zoran_params)
134#define BUZIOC_REQBUFS _IOWR('v', BASE_VIDIOCPRIVATE+2, struct zoran_requestbuffers)
135#define BUZIOC_QBUF_CAPT _IOW ('v', BASE_VIDIOCPRIVATE+3, int)
136#define BUZIOC_QBUF_PLAY _IOW ('v', BASE_VIDIOCPRIVATE+4, int)
137#define BUZIOC_SYNC _IOR ('v', BASE_VIDIOCPRIVATE+5, struct zoran_sync)
138#define BUZIOC_G_STATUS _IOWR('v', BASE_VIDIOCPRIVATE+6, struct zoran_status)
139
140
141#ifdef __KERNEL__
142
143#define MAJOR_VERSION 0 /* driver major version */
144#define MINOR_VERSION 9 /* driver minor version */
145#define RELEASE_VERSION 5 /* release version */
146
147#define ZORAN_NAME "ZORAN" /* name of the device */
148
149#define ZR_DEVNAME(zr) ((zr)->name)
150
151#define BUZ_MAX_WIDTH (zr->timing->Wa)
152#define BUZ_MAX_HEIGHT (zr->timing->Ha)
153#define BUZ_MIN_WIDTH 32 /* never display less than 32 pixels */
154#define BUZ_MIN_HEIGHT 24 /* never display less than 24 rows */
155
156#define BUZ_NUM_STAT_COM 4
157#define BUZ_MASK_STAT_COM 3
158
159#define BUZ_MAX_FRAME 256 /* Must be a power of 2 */
160#define BUZ_MASK_FRAME 255 /* Must be BUZ_MAX_FRAME-1 */
161
162#define BUZ_MAX_INPUT 8
163
164#if VIDEO_MAX_FRAME <= 32
165# define V4L_MAX_FRAME 32
166#elif VIDEO_MAX_FRAME <= 64
167# define V4L_MAX_FRAME 64
168#else
169# error "Too many video frame buffers to handle"
170#endif
171#define V4L_MASK_FRAME (V4L_MAX_FRAME - 1)
172
173#define MAX_KMALLOC_MEM (128*1024)
174
175#include "zr36057.h"
176
177enum card_type {
178 UNKNOWN = -1,
179
180 /* Pinnacle/Miro */
181 DC10_old, /* DC30 like */
182 DC10_new, /* DC10plus like */
183 DC10plus,
184 DC30,
185 DC30plus,
186
187 /* Linux Media Labs */
188 LML33,
189 LML33R10,
190
191 /* Iomega */
192 BUZ,
193
194 /* total number of cards */
195 NUM_CARDS
196};
197
198enum zoran_codec_mode {
199 BUZ_MODE_IDLE, /* nothing going on */
200 BUZ_MODE_MOTION_COMPRESS, /* grabbing frames */
201 BUZ_MODE_MOTION_DECOMPRESS, /* playing frames */
202 BUZ_MODE_STILL_COMPRESS, /* still frame conversion */
203 BUZ_MODE_STILL_DECOMPRESS /* still frame conversion */
204};
205
206enum zoran_buffer_state {
207 BUZ_STATE_USER, /* buffer is owned by application */
208 BUZ_STATE_PEND, /* buffer is queued in pend[] ready to feed to I/O */
209 BUZ_STATE_DMA, /* buffer is queued in dma[] for I/O */
210 BUZ_STATE_DONE /* buffer is ready to return to application */
211};
212
213enum zoran_map_mode {
214 ZORAN_MAP_MODE_RAW,
215 ZORAN_MAP_MODE_JPG_REC,
216#define ZORAN_MAP_MODE_JPG ZORAN_MAP_MODE_JPG_REC
217 ZORAN_MAP_MODE_JPG_PLAY,
218};
219
220enum gpio_type {
221 GPIO_JPEG_SLEEP = 0,
222 GPIO_JPEG_RESET,
223 GPIO_JPEG_FRAME,
224 GPIO_VID_DIR,
225 GPIO_VID_EN,
226 GPIO_VID_RESET,
227 GPIO_CLK_SEL1,
228 GPIO_CLK_SEL2,
229 GPIO_MAX,
230};
231
232enum gpcs_type {
233 GPCS_JPEG_RESET = 0,
234 GPCS_JPEG_START,
235 GPCS_MAX,
236};
237
238struct zoran_format {
239 char *name;
240 int palette;
241 __u32 fourcc;
242 int colorspace;
243 int depth;
244 __u32 flags;
245};
246/* flags */
247#define ZORAN_FORMAT_COMPRESSED 1<<0
248#define ZORAN_FORMAT_OVERLAY 1<<1
249#define ZORAN_FORMAT_CAPTURE 1<<2
250#define ZORAN_FORMAT_PLAYBACK 1<<3
251
252/* overlay-settings */
253struct zoran_overlay_settings {
254 int is_set;
255 int x, y, width, height; /* position */
256 int clipcount; /* position and number of clips */
257 const struct zoran_format *format; /* overlay format */
258};
259
260/* v4l-capture settings */
261struct zoran_v4l_settings {
262 int width, height, bytesperline; /* capture size */
263 const struct zoran_format *format; /* capture format */
264};
265
266/* whoops, this one is undeclared if !v4l2 */
267#ifndef HAVE_V4L2
268struct v4l2_jpegcompression {
269 int quality;
270 int APPn;
271 int APP_len;
272 char APP_data[60];
273 int COM_len;
274 char COM_data[60];
275 __u32 jpeg_markers;
276 __u8 reserved[116];
277};
278#endif
279
280/* jpg-capture/-playback settings */
281struct zoran_jpg_settings {
282 int decimation; /* this bit is used to set everything to default */
283 int HorDcm, VerDcm, TmpDcm; /* capture decimation settings (TmpDcm=1 means both fields) */
284 int field_per_buff, odd_even; /* field-settings (odd_even=1 (+TmpDcm=1) means top-field-first) */
285 int img_x, img_y, img_width, img_height; /* crop settings (subframe capture) */
286 struct v4l2_jpegcompression jpg_comp; /* JPEG-specific capture settings */
287};
288
289struct zoran_mapping {
290 struct file *file;
291 int count;
292};
293
294struct zoran_jpg_buffer {
295 struct zoran_mapping *map;
296 u32 *frag_tab; /* addresses of frag table */
297 u32 frag_tab_bus; /* same value cached to save time in ISR */
298 enum zoran_buffer_state state; /* non-zero if corresponding buffer is in use in grab queue */
299 struct zoran_sync bs; /* DONE: info to return to application */
300};
301
302struct zoran_v4l_buffer {
303 struct zoran_mapping *map;
304 char *fbuffer; /* virtual address of frame buffer */
305 unsigned long fbuffer_phys; /* physical address of frame buffer */
306 unsigned long fbuffer_bus; /* bus address of frame buffer */
307 enum zoran_buffer_state state; /* state: unused/pending/done */
308 struct zoran_sync bs; /* DONE: info to return to application */
309};
310
311enum zoran_lock_activity {
312 ZORAN_FREE, /* free for use */
313 ZORAN_ACTIVE, /* active but unlocked */
314 ZORAN_LOCKED, /* locked */
315};
316
317/* buffer collections */
318struct zoran_jpg_struct {
319 enum zoran_lock_activity active; /* feature currently in use? */
320 struct zoran_jpg_buffer buffer[BUZ_MAX_FRAME]; /* buffers */
321 int num_buffers, buffer_size;
322 u8 allocated; /* Flag if buffers are allocated */
323 u8 ready_to_be_freed; /* hack - see zoran_driver.c */
324 u8 need_contiguous; /* Flag if contiguous buffers are needed */
325};
326
327struct zoran_v4l_struct {
328 enum zoran_lock_activity active; /* feature currently in use? */
329 struct zoran_v4l_buffer buffer[VIDEO_MAX_FRAME]; /* buffers */
330 int num_buffers, buffer_size;
331 u8 allocated; /* Flag if buffers are allocated */
332 u8 ready_to_be_freed; /* hack - see zoran_driver.c */
333};
334
335struct zoran;
336
337/* zoran_fh contains per-open() settings */
338struct zoran_fh {
339 struct zoran *zr;
340
341 enum zoran_map_mode map_mode; /* Flag which bufferset will map by next mmap() */
342
343 struct zoran_overlay_settings overlay_settings;
344 u32 *overlay_mask; /* overlay mask */
345 enum zoran_lock_activity overlay_active; /* feature currently in use? */
346
347 struct zoran_v4l_settings v4l_settings; /* structure with a lot of things to play with */
348 struct zoran_v4l_struct v4l_buffers; /* V4L buffers' info */
349
350 struct zoran_jpg_settings jpg_settings; /* structure with a lot of things to play with */
351 struct zoran_jpg_struct jpg_buffers; /* MJPEG buffers' info */
352};
353
354struct card_info {
355 enum card_type type;
356 char name[32];
357 u16 i2c_decoder, i2c_encoder; /* I2C types */
358 u16 video_vfe, video_codec; /* videocodec types */
359 u16 audio_chip; /* audio type */
360 u16 vendor_id, device_id; /* subsystem vendor/device ID */
361
362 int inputs; /* number of video inputs */
363 struct input {
364 int muxsel;
365 char name[32];
366 } input[BUZ_MAX_INPUT];
367
368 int norms;
369 struct tvnorm *tvn[3]; /* supported TV norms */
370
371 u32 jpeg_int; /* JPEG interrupt */
372 u32 vsync_int; /* VSYNC interrupt */
373 s8 gpio[GPIO_MAX];
374 u8 gpcs[GPCS_MAX];
375
376 struct vfe_polarity vfe_pol;
377 u8 gpio_pol[GPIO_MAX];
378
379 /* is the /GWS line conected? */
380 u8 gws_not_connected;
381
382 void (*init) (struct zoran * zr);
383};
384
385struct zoran {
386 struct video_device *video_dev;
387
388 struct i2c_adapter i2c_adapter; /* */
389 struct i2c_algo_bit_data i2c_algo; /* */
390 u32 i2cbr;
391
392 struct i2c_client *decoder; /* video decoder i2c client */
393 struct i2c_client *encoder; /* video encoder i2c client */
394
395 struct videocodec *codec; /* video codec */
396 struct videocodec *vfe; /* video front end */
397
398 struct semaphore resource_lock; /* prevent evil stuff */
399
400 u8 initialized; /* flag if zoran has been correctly initalized */
401 int user; /* number of current users */
402 struct card_info card;
403 struct tvnorm *timing;
404
405 unsigned short id; /* number of this device */
406 char name[32]; /* name of this device */
407 struct pci_dev *pci_dev; /* PCI device */
408 unsigned char revision; /* revision of zr36057 */
409 unsigned int zr36057_adr; /* bus address of IO mem returned by PCI BIOS */
410 unsigned char __iomem *zr36057_mem;/* pointer to mapped IO memory */
411
412 spinlock_t spinlock; /* Spinlock */
413
414 /* Video for Linux parameters */
415 int input, norm; /* card's norm and input - norm=VIDEO_MODE_* */
416 int hue, saturation, contrast, brightness; /* Current picture params */
417 struct video_buffer buffer; /* Current buffer params */
418 struct zoran_overlay_settings overlay_settings;
419 u32 *overlay_mask; /* overlay mask */
420 enum zoran_lock_activity overlay_active; /* feature currently in use? */
421
422 wait_queue_head_t v4l_capq;
423
424 int v4l_overlay_active; /* Overlay grab is activated */
425 int v4l_memgrab_active; /* Memory grab is activated */
426
427 int v4l_grab_frame; /* Frame number being currently grabbed */
428#define NO_GRAB_ACTIVE (-1)
429 unsigned long v4l_grab_seq; /* Number of frames grabbed */
430 struct zoran_v4l_settings v4l_settings; /* structure with a lot of things to play with */
431
432 /* V4L grab queue of frames pending */
433 unsigned long v4l_pend_head;
434 unsigned long v4l_pend_tail;
435 unsigned long v4l_sync_tail;
436 int v4l_pend[V4L_MAX_FRAME];
437 struct zoran_v4l_struct v4l_buffers; /* V4L buffers' info */
438
439 /* Buz MJPEG parameters */
440 enum zoran_codec_mode codec_mode; /* status of codec */
441 struct zoran_jpg_settings jpg_settings; /* structure with a lot of things to play with */
442
443 wait_queue_head_t jpg_capq; /* wait here for grab to finish */
444
445 /* grab queue counts/indices, mask with BUZ_MASK_STAT_COM before using as index */
446 /* (dma_head - dma_tail) is number active in DMA, must be <= BUZ_NUM_STAT_COM */
447 /* (value & BUZ_MASK_STAT_COM) corresponds to index in stat_com table */
448 unsigned long jpg_que_head; /* Index where to put next buffer which is queued */
449 unsigned long jpg_dma_head; /* Index of next buffer which goes into stat_com */
450 unsigned long jpg_dma_tail; /* Index of last buffer in stat_com */
451 unsigned long jpg_que_tail; /* Index of last buffer in queue */
452 unsigned long jpg_seq_num; /* count of frames since grab/play started */
453 unsigned long jpg_err_seq; /* last seq_num before error */
454 unsigned long jpg_err_shift;
455 unsigned long jpg_queued_num; /* count of frames queued since grab/play started */
456
457 /* zr36057's code buffer table */
458 u32 *stat_com; /* stat_com[i] is indexed by dma_head/tail & BUZ_MASK_STAT_COM */
459
460 /* (value & BUZ_MASK_FRAME) corresponds to index in pend[] queue */
461 int jpg_pend[BUZ_MAX_FRAME];
462
463 /* array indexed by frame number */
464 struct zoran_jpg_struct jpg_buffers; /* MJPEG buffers' info */
465
466 /* Additional stuff for testing */
467#ifdef CONFIG_PROC_FS
468 struct proc_dir_entry *zoran_proc;
469#else
470 void *zoran_proc;
471#endif
472 int testing;
473 int jpeg_error;
474 int intr_counter_GIRQ1;
475 int intr_counter_GIRQ0;
476 int intr_counter_CodRepIRQ;
477 int intr_counter_JPEGRepIRQ;
478 int field_counter;
479 int IRQ1_in;
480 int IRQ1_out;
481 int JPEG_in;
482 int JPEG_out;
483 int JPEG_0;
484 int JPEG_1;
485 int END_event_missed;
486 int JPEG_missed;
487 int JPEG_error;
488 int num_errors;
489 int JPEG_max_missed;
490 int JPEG_min_missed;
491
492 u32 last_isr;
493 unsigned long frame_num;
494
495 wait_queue_head_t test_q;
496};
497
498/*The following should be done in more portable way. It depends on define
499 of _ALPHA_BUZ in the Makefile.*/
500
501#ifdef _ALPHA_BUZ
502#define btwrite(dat,adr) writel((dat), zr->zr36057_adr+(adr))
503#define btread(adr) readl(zr->zr36057_adr+(adr))
504#else
505#define btwrite(dat,adr) writel((dat), zr->zr36057_mem+(adr))
506#define btread(adr) readl(zr->zr36057_mem+(adr))
507#endif
508
509#define btand(dat,adr) btwrite((dat) & btread(adr), adr)
510#define btor(dat,adr) btwrite((dat) | btread(adr), adr)
511#define btaor(dat,mask,adr) btwrite((dat) | ((mask) & btread(adr)), adr)
512
513#endif /* __kernel__ */
514
515#endif
diff --git a/drivers/media/video/zoran_card.c b/drivers/media/video/zoran_card.c
new file mode 100644
index 00000000000..25743085b2d
--- /dev/null
+++ b/drivers/media/video/zoran_card.c
@@ -0,0 +1,1583 @@
1/*
2 * Zoran zr36057/zr36067 PCI controller driver, for the
3 * Pinnacle/Miro DC10/DC10+/DC30/DC30+, Iomega Buz, Linux
4 * Media Labs LML33/LML33R10.
5 *
6 * This part handles card-specific data and detection
7 *
8 * Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>
9 *
10 * Currently maintained by:
11 * Ronald Bultje <rbultje@ronald.bitfreak.net>
12 * Laurent Pinchart <laurent.pinchart@skynet.be>
13 * Mailinglist <mjpeg-users@lists.sf.net>
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 */
29
30#include <linux/config.h>
31#include <linux/types.h>
32#include <linux/kernel.h>
33#include <linux/module.h>
34#include <linux/init.h>
35#include <linux/vmalloc.h>
36
37#include <linux/proc_fs.h>
38#include <linux/i2c.h>
39#include <linux/i2c-algo-bit.h>
40#include <linux/videodev.h>
41#include <linux/spinlock.h>
42#include <linux/sem.h>
43#include <linux/kmod.h>
44#include <linux/wait.h>
45
46#include <linux/pci.h>
47#include <linux/interrupt.h>
48#include <linux/video_decoder.h>
49#include <linux/video_encoder.h>
50
51#include <asm/io.h>
52
53#include "videocodec.h"
54#include "zoran.h"
55#include "zoran_card.h"
56#include "zoran_device.h"
57#include "zoran_procfs.h"
58
59#define I2C_NAME(x) (x)->name
60
61extern const struct zoran_format zoran_formats[];
62
63static int card[BUZ_MAX] = { -1, -1, -1, -1 };
64module_param_array(card, int, NULL, 0);
65MODULE_PARM_DESC(card, "The type of card");
66
67static int encoder[BUZ_MAX] = { -1, -1, -1, -1 };
68module_param_array(encoder, int, NULL, 0);
69MODULE_PARM_DESC(encoder, "i2c TV encoder");
70
71static int decoder[BUZ_MAX] = { -1, -1, -1, -1 };
72module_param_array(decoder, int, NULL, 0);
73MODULE_PARM_DESC(decoder, "i2c TV decoder");
74
75/*
76 The video mem address of the video card.
77 The driver has a little database for some videocards
78 to determine it from there. If your video card is not in there
79 you have either to give it to the driver as a parameter
80 or set in in a VIDIOCSFBUF ioctl
81 */
82
83static unsigned long vidmem = 0; /* Video memory base address */
84module_param(vidmem, ulong, 0);
85
86/*
87 Default input and video norm at startup of the driver.
88*/
89
90static int default_input = 0; /* 0=Composite, 1=S-Video */
91module_param(default_input, int, 0);
92MODULE_PARM_DESC(default_input,
93 "Default input (0=Composite, 1=S-Video, 2=Internal)");
94
95static int default_norm = 0; /* 0=PAL, 1=NTSC 2=SECAM */
96module_param(default_norm, int, 0);
97MODULE_PARM_DESC(default_norm, "Default norm (0=PAL, 1=NTSC, 2=SECAM)");
98
99static int video_nr = -1; /* /dev/videoN, -1 for autodetect */
100module_param(video_nr, int, 0);
101MODULE_PARM_DESC(video_nr, "video device number");
102
103/*
104 Number and size of grab buffers for Video 4 Linux
105 The vast majority of applications should not need more than 2,
106 the very popular BTTV driver actually does ONLY have 2.
107 Time sensitive applications might need more, the maximum
108 is VIDEO_MAX_FRAME (defined in <linux/videodev.h>).
109
110 The size is set so that the maximum possible request
111 can be satisfied. Decrease it, if bigphys_area alloc'd
112 memory is low. If you don't have the bigphys_area patch,
113 set it to 128 KB. Will you allow only to grab small
114 images with V4L, but that's better than nothing.
115
116 v4l_bufsize has to be given in KB !
117
118*/
119
120int v4l_nbufs = 2;
121int v4l_bufsize = 128; /* Everybody should be able to work with this setting */
122module_param(v4l_nbufs, int, 0);
123MODULE_PARM_DESC(v4l_nbufs, "Maximum number of V4L buffers to use");
124module_param(v4l_bufsize, int, 0);
125MODULE_PARM_DESC(v4l_bufsize, "Maximum size per V4L buffer (in kB)");
126
127int jpg_nbufs = 32;
128int jpg_bufsize = 512; /* max size for 100% quality full-PAL frame */
129module_param(jpg_nbufs, int, 0);
130MODULE_PARM_DESC(jpg_nbufs, "Maximum number of JPG buffers to use");
131module_param(jpg_bufsize, int, 0);
132MODULE_PARM_DESC(jpg_bufsize, "Maximum size per JPG buffer (in kB)");
133
134int pass_through = 0; /* 1=Pass through TV signal when device is not used */
135 /* 0=Show color bar when device is not used (LML33: only if lml33dpath=1) */
136module_param(pass_through, int, 0);
137MODULE_PARM_DESC(pass_through,
138 "Pass TV signal through to TV-out when idling");
139
140static int debug = 1;
141int *zr_debug = &debug;
142module_param(debug, int, 0);
143MODULE_PARM_DESC(debug, "Debug level (0-4)");
144
145MODULE_DESCRIPTION("Zoran-36057/36067 JPEG codec driver");
146MODULE_AUTHOR("Serguei Miridonov");
147MODULE_LICENSE("GPL");
148
149static struct pci_device_id zr36067_pci_tbl[] = {
150 {PCI_VENDOR_ID_ZORAN, PCI_DEVICE_ID_ZORAN_36057,
151 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
152 {0}
153};
154MODULE_DEVICE_TABLE(pci, zr36067_pci_tbl);
155
156#define dprintk(num, format, args...) \
157 do { \
158 if (*zr_debug >= num) \
159 printk(format, ##args); \
160 } while (0)
161
162int zoran_num; /* number of Buzs in use */
163struct zoran zoran[BUZ_MAX];
164
165/* videocodec bus functions ZR36060 */
166static u32
167zr36060_read (struct videocodec *codec,
168 u16 reg)
169{
170 struct zoran *zr = (struct zoran *) codec->master_data->data;
171 __u32 data;
172
173 if (post_office_wait(zr)
174 || post_office_write(zr, 0, 1, reg >> 8)
175 || post_office_write(zr, 0, 2, reg & 0xff)) {
176 return -1;
177 }
178
179 data = post_office_read(zr, 0, 3) & 0xff;
180 return data;
181}
182
183static void
184zr36060_write (struct videocodec *codec,
185 u16 reg,
186 u32 val)
187{
188 struct zoran *zr = (struct zoran *) codec->master_data->data;
189
190 if (post_office_wait(zr)
191 || post_office_write(zr, 0, 1, reg >> 8)
192 || post_office_write(zr, 0, 2, reg & 0xff)) {
193 return;
194 }
195
196 post_office_write(zr, 0, 3, val & 0xff);
197}
198
199/* videocodec bus functions ZR36050 */
200static u32
201zr36050_read (struct videocodec *codec,
202 u16 reg)
203{
204 struct zoran *zr = (struct zoran *) codec->master_data->data;
205 __u32 data;
206
207 if (post_office_wait(zr)
208 || post_office_write(zr, 1, 0, reg >> 2)) { // reg. HIGHBYTES
209 return -1;
210 }
211
212 data = post_office_read(zr, 0, reg & 0x03) & 0xff; // reg. LOWBYTES + read
213 return data;
214}
215
216static void
217zr36050_write (struct videocodec *codec,
218 u16 reg,
219 u32 val)
220{
221 struct zoran *zr = (struct zoran *) codec->master_data->data;
222
223 if (post_office_wait(zr)
224 || post_office_write(zr, 1, 0, reg >> 2)) { // reg. HIGHBYTES
225 return;
226 }
227
228 post_office_write(zr, 0, reg & 0x03, val & 0xff); // reg. LOWBYTES + wr. data
229}
230
231/* videocodec bus functions ZR36016 */
232static u32
233zr36016_read (struct videocodec *codec,
234 u16 reg)
235{
236 struct zoran *zr = (struct zoran *) codec->master_data->data;
237 __u32 data;
238
239 if (post_office_wait(zr)) {
240 return -1;
241 }
242
243 data = post_office_read(zr, 2, reg & 0x03) & 0xff; // read
244 return data;
245}
246
247/* hack for in zoran_device.c */
248void
249zr36016_write (struct videocodec *codec,
250 u16 reg,
251 u32 val)
252{
253 struct zoran *zr = (struct zoran *) codec->master_data->data;
254
255 if (post_office_wait(zr)) {
256 return;
257 }
258
259 post_office_write(zr, 2, reg & 0x03, val & 0x0ff); // wr. data
260}
261
262/*
263 * Board specific information
264 */
265
266static void
267dc10_init (struct zoran *zr)
268{
269 dprintk(3, KERN_DEBUG "%s: dc10_init()\n", ZR_DEVNAME(zr));
270
271 /* Pixel clock selection */
272 GPIO(zr, 4, 0);
273 GPIO(zr, 5, 1);
274 /* Enable the video bus sync signals */
275 GPIO(zr, 7, 0);
276}
277
278static void
279dc10plus_init (struct zoran *zr)
280{
281 dprintk(3, KERN_DEBUG "%s: dc10plus_init()\n", ZR_DEVNAME(zr));
282}
283
284static void
285buz_init (struct zoran *zr)
286{
287 dprintk(3, KERN_DEBUG "%s: buz_init()\n", ZR_DEVNAME(zr));
288
289 /* some stuff from Iomega */
290 pci_write_config_dword(zr->pci_dev, 0xfc, 0x90680f15);
291 pci_write_config_dword(zr->pci_dev, 0x0c, 0x00012020);
292 pci_write_config_dword(zr->pci_dev, 0xe8, 0xc0200000);
293}
294
295static void
296lml33_init (struct zoran *zr)
297{
298 dprintk(3, KERN_DEBUG "%s: lml33_init()\n", ZR_DEVNAME(zr));
299
300 GPIO(zr, 2, 1); // Set Composite input/output
301}
302
303static char *
304i2cid_to_modulename (u16 i2c_id)
305{
306 char *name = NULL;
307
308 switch (i2c_id) {
309 case I2C_DRIVERID_SAA7110:
310 name = "saa7110";
311 break;
312 case I2C_DRIVERID_SAA7111A:
313 name = "saa7111";
314 break;
315 case I2C_DRIVERID_SAA7114:
316 name = "saa7114";
317 break;
318 case I2C_DRIVERID_SAA7185B:
319 name = "saa7185";
320 break;
321 case I2C_DRIVERID_ADV7170:
322 name = "adv7170";
323 break;
324 case I2C_DRIVERID_ADV7175:
325 name = "adv7175";
326 break;
327 case I2C_DRIVERID_BT819:
328 name = "bt819";
329 break;
330 case I2C_DRIVERID_BT856:
331 name = "bt856";
332 break;
333 case I2C_DRIVERID_VPX3220:
334 name = "vpx3220";
335 break;
336/* case I2C_DRIVERID_VPX3224:
337 name = "vpx3224";
338 break;
339 case I2C_DRIVERID_MSE3000:
340 name = "mse3000";
341 break;*/
342 default:
343 break;
344 }
345
346 return name;
347}
348
349static char *
350codecid_to_modulename (u16 codecid)
351{
352 char *name = NULL;
353
354 switch (codecid) {
355 case CODEC_TYPE_ZR36060:
356 name = "zr36060";
357 break;
358 case CODEC_TYPE_ZR36050:
359 name = "zr36050";
360 break;
361 case CODEC_TYPE_ZR36016:
362 name = "zr36016";
363 break;
364 default:
365 break;
366 }
367
368 return name;
369}
370
371// struct tvnorm {
372// u16 Wt, Wa, HStart, HSyncStart, Ht, Ha, VStart;
373// };
374
375static struct tvnorm f50sqpixel = { 944, 768, 83, 880, 625, 576, 16 };
376static struct tvnorm f60sqpixel = { 780, 640, 51, 716, 525, 480, 12 };
377static struct tvnorm f50ccir601 = { 864, 720, 75, 804, 625, 576, 18 };
378static struct tvnorm f60ccir601 = { 858, 720, 57, 788, 525, 480, 16 };
379
380static struct tvnorm f50ccir601_lml33 = { 864, 720, 75+34, 804, 625, 576, 18 };
381static struct tvnorm f60ccir601_lml33 = { 858, 720, 57+34, 788, 525, 480, 16 };
382
383/* The DC10 (57/16/50) uses VActive as HSync, so HStart must be 0 */
384static struct tvnorm f50sqpixel_dc10 = { 944, 768, 0, 880, 625, 576, 0 };
385static struct tvnorm f60sqpixel_dc10 = { 780, 640, 0, 716, 525, 480, 12 };
386
387/* FIXME: I cannot swap U and V in saa7114, so i do one
388 * pixel left shift in zoran (75 -> 74)
389 * (Maxim Yevtyushkin <max@linuxmedialabs.com>) */
390static struct tvnorm f50ccir601_lm33r10 = { 864, 720, 74+54, 804, 625, 576, 18 };
391static struct tvnorm f60ccir601_lm33r10 = { 858, 720, 56+54, 788, 525, 480, 16 };
392
393static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
394 {
395 .type = DC10_old,
396 .name = "DC10(old)",
397 .i2c_decoder = I2C_DRIVERID_VPX3220,
398 /*.i2c_encoder = I2C_DRIVERID_MSE3000,*/
399 .video_codec = CODEC_TYPE_ZR36050,
400 .video_vfe = CODEC_TYPE_ZR36016,
401
402 .inputs = 3,
403 .input = {
404 { 1, "Composite" },
405 { 2, "S-Video" },
406 { 0, "Internal/comp" }
407 },
408 .norms = 3,
409 .tvn = {
410 &f50sqpixel_dc10,
411 &f60sqpixel_dc10,
412 &f50sqpixel_dc10
413 },
414 .jpeg_int = 0,
415 .vsync_int = ZR36057_ISR_GIRQ1,
416 .gpio = { 2, 1, -1, 3, 7, 0, 4, 5 },
417 .gpio_pol = { 0, 0, 0, 1, 0, 0, 0, 0 },
418 .gpcs = { -1, 0 },
419 .vfe_pol = { 0, 0, 0, 0, 0, 0, 0, 0 },
420 .gws_not_connected = 0,
421 .init = &dc10_init,
422 }, {
423 .type = DC10_new,
424 .name = "DC10(new)",
425 .i2c_decoder = I2C_DRIVERID_SAA7110,
426 .i2c_encoder = I2C_DRIVERID_ADV7175,
427 .video_codec = CODEC_TYPE_ZR36060,
428
429 .inputs = 3,
430 .input = {
431 { 0, "Composite" },
432 { 7, "S-Video" },
433 { 5, "Internal/comp" }
434 },
435 .norms = 3,
436 .tvn = {
437 &f50sqpixel,
438 &f60sqpixel,
439 &f50sqpixel},
440 .jpeg_int = ZR36057_ISR_GIRQ0,
441 .vsync_int = ZR36057_ISR_GIRQ1,
442 .gpio = { 3, 0, 6, 1, 2, -1, 4, 5 },
443 .gpio_pol = { 0, 0, 0, 0, 0, 0, 0, 0 },
444 .gpcs = { -1, 1},
445 .vfe_pol = { 1, 1, 1, 1, 0, 0, 0, 0 },
446 .gws_not_connected = 0,
447 .init = &dc10plus_init,
448 }, {
449 .type = DC10plus,
450 .name = "DC10plus",
451 .vendor_id = PCI_VENDOR_ID_MIRO,
452 .device_id = PCI_DEVICE_ID_MIRO_DC10PLUS,
453 .i2c_decoder = I2C_DRIVERID_SAA7110,
454 .i2c_encoder = I2C_DRIVERID_ADV7175,
455 .video_codec = CODEC_TYPE_ZR36060,
456
457 .inputs = 3,
458 .input = {
459 { 0, "Composite" },
460 { 7, "S-Video" },
461 { 5, "Internal/comp" }
462 },
463 .norms = 3,
464 .tvn = {
465 &f50sqpixel,
466 &f60sqpixel,
467 &f50sqpixel
468 },
469 .jpeg_int = ZR36057_ISR_GIRQ0,
470 .vsync_int = ZR36057_ISR_GIRQ1,
471 .gpio = { 3, 0, 6, 1, 2, -1, 4, 5 },
472 .gpio_pol = { 0, 0, 0, 0, 0, 0, 0, 0 },
473 .gpcs = { -1, 1 },
474 .vfe_pol = { 1, 1, 1, 1, 0, 0, 0, 0 },
475 .gws_not_connected = 0,
476 .init = &dc10plus_init,
477 }, {
478 .type = DC30,
479 .name = "DC30",
480 .i2c_decoder = I2C_DRIVERID_VPX3220,
481 .i2c_encoder = I2C_DRIVERID_ADV7175,
482 .video_codec = CODEC_TYPE_ZR36050,
483 .video_vfe = CODEC_TYPE_ZR36016,
484
485 .inputs = 3,
486 .input = {
487 { 1, "Composite" },
488 { 2, "S-Video" },
489 { 0, "Internal/comp" }
490 },
491 .norms = 3,
492 .tvn = {
493 &f50sqpixel_dc10,
494 &f60sqpixel_dc10,
495 &f50sqpixel_dc10
496 },
497 .jpeg_int = 0,
498 .vsync_int = ZR36057_ISR_GIRQ1,
499 .gpio = { 2, 1, -1, 3, 7, 0, 4, 5 },
500 .gpio_pol = { 0, 0, 0, 1, 0, 0, 0, 0 },
501 .gpcs = { -1, 0 },
502 .vfe_pol = { 0, 0, 0, 0, 0, 0, 0, 0 },
503 .gws_not_connected = 0,
504 .init = &dc10_init,
505 }, {
506 .type = DC30plus,
507 .name = "DC30plus",
508 .vendor_id = PCI_VENDOR_ID_MIRO,
509 .device_id = PCI_DEVICE_ID_MIRO_DC30PLUS,
510 .i2c_decoder = I2C_DRIVERID_VPX3220,
511 .i2c_encoder = I2C_DRIVERID_ADV7175,
512 .video_codec = CODEC_TYPE_ZR36050,
513 .video_vfe = CODEC_TYPE_ZR36016,
514
515 .inputs = 3,
516 .input = {
517 { 1, "Composite" },
518 { 2, "S-Video" },
519 { 0, "Internal/comp" }
520 },
521 .norms = 3,
522 .tvn = {
523 &f50sqpixel_dc10,
524 &f60sqpixel_dc10,
525 &f50sqpixel_dc10
526 },
527 .jpeg_int = 0,
528 .vsync_int = ZR36057_ISR_GIRQ1,
529 .gpio = { 2, 1, -1, 3, 7, 0, 4, 5 },
530 .gpio_pol = { 0, 0, 0, 1, 0, 0, 0, 0 },
531 .gpcs = { -1, 0 },
532 .vfe_pol = { 0, 0, 0, 0, 0, 0, 0, 0 },
533 .gws_not_connected = 0,
534 .init = &dc10_init,
535 }, {
536 .type = LML33,
537 .name = "LML33",
538 .i2c_decoder = I2C_DRIVERID_BT819,
539 .i2c_encoder = I2C_DRIVERID_BT856,
540 .video_codec = CODEC_TYPE_ZR36060,
541
542 .inputs = 2,
543 .input = {
544 { 0, "Composite" },
545 { 7, "S-Video" }
546 },
547 .norms = 2,
548 .tvn = {
549 &f50ccir601_lml33,
550 &f60ccir601_lml33,
551 NULL
552 },
553 .jpeg_int = ZR36057_ISR_GIRQ1,
554 .vsync_int = ZR36057_ISR_GIRQ0,
555 .gpio = { 1, -1, 3, 5, 7, -1, -1, -1 },
556 .gpio_pol = { 0, 0, 0, 0, 1, 0, 0, 0 },
557 .gpcs = { 3, 1 },
558 .vfe_pol = { 1, 1, 0, 0, 0, 1, 0, 0 },
559 .gws_not_connected = 1,
560 .init = &lml33_init,
561 }, {
562 .type = LML33R10,
563 .name = "LML33R10",
564 .vendor_id = PCI_VENDOR_ID_ELECTRONICDESIGNGMBH,
565 .device_id = PCI_DEVICE_ID_LML_33R10,
566 .i2c_decoder = I2C_DRIVERID_SAA7114,
567 .i2c_encoder = I2C_DRIVERID_ADV7170,
568 .video_codec = CODEC_TYPE_ZR36060,
569
570 .inputs = 2,
571 .input = {
572 { 0, "Composite" },
573 { 7, "S-Video" }
574 },
575 .norms = 2,
576 .tvn = {
577 &f50ccir601_lm33r10,
578 &f60ccir601_lm33r10,
579 NULL
580 },
581 .jpeg_int = ZR36057_ISR_GIRQ1,
582 .vsync_int = ZR36057_ISR_GIRQ0,
583 .gpio = { 1, -1, 3, 5, 7, -1, -1, -1 },
584 .gpio_pol = { 0, 0, 0, 0, 1, 0, 0, 0 },
585 .gpcs = { 3, 1 },
586 .vfe_pol = { 1, 1, 0, 0, 0, 1, 0, 0 },
587 .gws_not_connected = 1,
588 .init = &lml33_init,
589 }, {
590 .type = BUZ,
591 .name = "Buz",
592 .vendor_id = PCI_VENDOR_ID_IOMEGA,
593 .device_id = PCI_DEVICE_ID_IOMEGA_BUZ,
594 .i2c_decoder = I2C_DRIVERID_SAA7111A,
595 .i2c_encoder = I2C_DRIVERID_SAA7185B,
596 .video_codec = CODEC_TYPE_ZR36060,
597
598 .inputs = 2,
599 .input = {
600 { 3, "Composite" },
601 { 7, "S-Video" }
602 },
603 .norms = 3,
604 .tvn = {
605 &f50ccir601,
606 &f60ccir601,
607 &f50ccir601
608 },
609 .jpeg_int = ZR36057_ISR_GIRQ1,
610 .vsync_int = ZR36057_ISR_GIRQ0,
611 .gpio = { 1, -1, 3, -1, -1, -1, -1, -1 },
612 .gpio_pol = { 0, 0, 0, 0, 0, 0, 0, 0 },
613 .gpcs = { 3, 1 },
614 .vfe_pol = { 1, 1, 0, 0, 0, 1, 0, 0 },
615 .gws_not_connected = 1,
616 .init = &buz_init,
617 }
618};
619
620/*
621 * I2C functions
622 */
623/* software I2C functions */
624static int
625zoran_i2c_getsda (void *data)
626{
627 struct zoran *zr = (struct zoran *) data;
628
629 return (btread(ZR36057_I2CBR) >> 1) & 1;
630}
631
632static int
633zoran_i2c_getscl (void *data)
634{
635 struct zoran *zr = (struct zoran *) data;
636
637 return btread(ZR36057_I2CBR) & 1;
638}
639
640static void
641zoran_i2c_setsda (void *data,
642 int state)
643{
644 struct zoran *zr = (struct zoran *) data;
645
646 if (state)
647 zr->i2cbr |= 2;
648 else
649 zr->i2cbr &= ~2;
650 btwrite(zr->i2cbr, ZR36057_I2CBR);
651}
652
653static void
654zoran_i2c_setscl (void *data,
655 int state)
656{
657 struct zoran *zr = (struct zoran *) data;
658
659 if (state)
660 zr->i2cbr |= 1;
661 else
662 zr->i2cbr &= ~1;
663 btwrite(zr->i2cbr, ZR36057_I2CBR);
664}
665
666static int
667zoran_i2c_client_register (struct i2c_client *client)
668{
669 struct zoran *zr = (struct zoran *) i2c_get_adapdata(client->adapter);
670 int res = 0;
671
672 dprintk(2,
673 KERN_DEBUG "%s: i2c_client_register() - driver id = %d\n",
674 ZR_DEVNAME(zr), client->driver->id);
675
676 down(&zr->resource_lock);
677
678 if (zr->user > 0) {
679 /* we're already busy, so we keep a reference to
680 * them... Could do a lot of stuff here, but this
681 * is easiest. (Did I ever mention I'm a lazy ass?)
682 */
683 res = -EBUSY;
684 goto clientreg_unlock_and_return;
685 }
686
687 if (client->driver->id == zr->card.i2c_decoder)
688 zr->decoder = client;
689 else if (client->driver->id == zr->card.i2c_encoder)
690 zr->encoder = client;
691 else {
692 res = -ENODEV;
693 goto clientreg_unlock_and_return;
694 }
695
696clientreg_unlock_and_return:
697 up(&zr->resource_lock);
698
699 return res;
700}
701
702static int
703zoran_i2c_client_unregister (struct i2c_client *client)
704{
705 struct zoran *zr = (struct zoran *) i2c_get_adapdata(client->adapter);
706 int res = 0;
707
708 dprintk(2, KERN_DEBUG "%s: i2c_client_unregister()\n", ZR_DEVNAME(zr));
709
710 down(&zr->resource_lock);
711
712 if (zr->user > 0) {
713 res = -EBUSY;
714 goto clientunreg_unlock_and_return;
715 }
716
717 /* try to locate it */
718 if (client == zr->encoder) {
719 zr->encoder = NULL;
720 } else if (client == zr->decoder) {
721 zr->decoder = NULL;
722 snprintf(ZR_DEVNAME(zr), sizeof(ZR_DEVNAME(zr)), "MJPEG[%d]", zr->id);
723 }
724clientunreg_unlock_and_return:
725 up(&zr->resource_lock);
726 return res;
727}
728
729static struct i2c_algo_bit_data zoran_i2c_bit_data_template = {
730 .setsda = zoran_i2c_setsda,
731 .setscl = zoran_i2c_setscl,
732 .getsda = zoran_i2c_getsda,
733 .getscl = zoran_i2c_getscl,
734 .udelay = 10,
735 .mdelay = 0,
736 .timeout = 100,
737};
738
739static struct i2c_adapter zoran_i2c_adapter_template = {
740 I2C_DEVNAME("zr36057"),
741 .id = I2C_HW_B_ZR36067,
742 .algo = NULL,
743 .client_register = zoran_i2c_client_register,
744 .client_unregister = zoran_i2c_client_unregister,
745};
746
747static int
748zoran_register_i2c (struct zoran *zr)
749{
750 memcpy(&zr->i2c_algo, &zoran_i2c_bit_data_template,
751 sizeof(struct i2c_algo_bit_data));
752 zr->i2c_algo.data = zr;
753 memcpy(&zr->i2c_adapter, &zoran_i2c_adapter_template,
754 sizeof(struct i2c_adapter));
755 strncpy(I2C_NAME(&zr->i2c_adapter), ZR_DEVNAME(zr),
756 sizeof(I2C_NAME(&zr->i2c_adapter)) - 1);
757 i2c_set_adapdata(&zr->i2c_adapter, zr);
758 zr->i2c_adapter.algo_data = &zr->i2c_algo;
759 return i2c_bit_add_bus(&zr->i2c_adapter);
760}
761
762static void
763zoran_unregister_i2c (struct zoran *zr)
764{
765 i2c_bit_del_bus((&zr->i2c_adapter));
766}
767
768/* Check a zoran_params struct for correctness, insert default params */
769
770int
771zoran_check_jpg_settings (struct zoran *zr,
772 struct zoran_jpg_settings *settings)
773{
774 int err = 0, err0 = 0;
775
776 dprintk(4,
777 KERN_DEBUG
778 "%s: check_jpg_settings() - dec: %d, Hdcm: %d, Vdcm: %d, Tdcm: %d\n",
779 ZR_DEVNAME(zr), settings->decimation, settings->HorDcm,
780 settings->VerDcm, settings->TmpDcm);
781 dprintk(4,
782 KERN_DEBUG
783 "%s: check_jpg_settings() - x: %d, y: %d, w: %d, y: %d\n",
784 ZR_DEVNAME(zr), settings->img_x, settings->img_y,
785 settings->img_width, settings->img_height);
786 /* Check decimation, set default values for decimation = 1, 2, 4 */
787 switch (settings->decimation) {
788 case 1:
789
790 settings->HorDcm = 1;
791 settings->VerDcm = 1;
792 settings->TmpDcm = 1;
793 settings->field_per_buff = 2;
794 settings->img_x = 0;
795 settings->img_y = 0;
796 settings->img_width = BUZ_MAX_WIDTH;
797 settings->img_height = BUZ_MAX_HEIGHT / 2;
798 break;
799 case 2:
800
801 settings->HorDcm = 2;
802 settings->VerDcm = 1;
803 settings->TmpDcm = 2;
804 settings->field_per_buff = 1;
805 settings->img_x = (BUZ_MAX_WIDTH == 720) ? 8 : 0;
806 settings->img_y = 0;
807 settings->img_width =
808 (BUZ_MAX_WIDTH == 720) ? 704 : BUZ_MAX_WIDTH;
809 settings->img_height = BUZ_MAX_HEIGHT / 2;
810 break;
811 case 4:
812
813 if (zr->card.type == DC10_new) {
814 dprintk(1,
815 KERN_DEBUG
816 "%s: check_jpg_settings() - HDec by 4 is not supported on the DC10\n",
817 ZR_DEVNAME(zr));
818 err0++;
819 break;
820 }
821
822 settings->HorDcm = 4;
823 settings->VerDcm = 2;
824 settings->TmpDcm = 2;
825 settings->field_per_buff = 1;
826 settings->img_x = (BUZ_MAX_WIDTH == 720) ? 8 : 0;
827 settings->img_y = 0;
828 settings->img_width =
829 (BUZ_MAX_WIDTH == 720) ? 704 : BUZ_MAX_WIDTH;
830 settings->img_height = BUZ_MAX_HEIGHT / 2;
831 break;
832 case 0:
833
834 /* We have to check the data the user has set */
835
836 if (settings->HorDcm != 1 && settings->HorDcm != 2 &&
837 (zr->card.type == DC10_new || settings->HorDcm != 4))
838 err0++;
839 if (settings->VerDcm != 1 && settings->VerDcm != 2)
840 err0++;
841 if (settings->TmpDcm != 1 && settings->TmpDcm != 2)
842 err0++;
843 if (settings->field_per_buff != 1 &&
844 settings->field_per_buff != 2)
845 err0++;
846 if (settings->img_x < 0)
847 err0++;
848 if (settings->img_y < 0)
849 err0++;
850 if (settings->img_width < 0)
851 err0++;
852 if (settings->img_height < 0)
853 err0++;
854 if (settings->img_x + settings->img_width > BUZ_MAX_WIDTH)
855 err0++;
856 if (settings->img_y + settings->img_height >
857 BUZ_MAX_HEIGHT / 2)
858 err0++;
859 if (settings->HorDcm && settings->VerDcm) {
860 if (settings->img_width %
861 (16 * settings->HorDcm) != 0)
862 err0++;
863 if (settings->img_height %
864 (8 * settings->VerDcm) != 0)
865 err0++;
866 }
867
868 if (err0) {
869 dprintk(1,
870 KERN_ERR
871 "%s: check_jpg_settings() - error in params for decimation = 0\n",
872 ZR_DEVNAME(zr));
873 err++;
874 }
875 break;
876 default:
877 dprintk(1,
878 KERN_ERR
879 "%s: check_jpg_settings() - decimation = %d, must be 0, 1, 2 or 4\n",
880 ZR_DEVNAME(zr), settings->decimation);
881 err++;
882 break;
883 }
884
885 if (settings->jpg_comp.quality > 100)
886 settings->jpg_comp.quality = 100;
887 if (settings->jpg_comp.quality < 5)
888 settings->jpg_comp.quality = 5;
889 if (settings->jpg_comp.APPn < 0)
890 settings->jpg_comp.APPn = 0;
891 if (settings->jpg_comp.APPn > 15)
892 settings->jpg_comp.APPn = 15;
893 if (settings->jpg_comp.APP_len < 0)
894 settings->jpg_comp.APP_len = 0;
895 if (settings->jpg_comp.APP_len > 60)
896 settings->jpg_comp.APP_len = 60;
897 if (settings->jpg_comp.COM_len < 0)
898 settings->jpg_comp.COM_len = 0;
899 if (settings->jpg_comp.COM_len > 60)
900 settings->jpg_comp.COM_len = 60;
901 if (err)
902 return -EINVAL;
903 return 0;
904}
905
906void
907zoran_open_init_params (struct zoran *zr)
908{
909 int i;
910
911 /* User must explicitly set a window */
912 zr->overlay_settings.is_set = 0;
913 zr->overlay_mask = NULL;
914 zr->overlay_active = ZORAN_FREE;
915
916 zr->v4l_memgrab_active = 0;
917 zr->v4l_overlay_active = 0;
918 zr->v4l_grab_frame = NO_GRAB_ACTIVE;
919 zr->v4l_grab_seq = 0;
920 zr->v4l_settings.width = 192;
921 zr->v4l_settings.height = 144;
922 zr->v4l_settings.format = &zoran_formats[4]; /* YUY2 - YUV-4:2:2 packed */
923 zr->v4l_settings.bytesperline =
924 zr->v4l_settings.width *
925 ((zr->v4l_settings.format->depth + 7) / 8);
926
927 /* DMA ring stuff for V4L */
928 zr->v4l_pend_tail = 0;
929 zr->v4l_pend_head = 0;
930 zr->v4l_sync_tail = 0;
931 zr->v4l_buffers.active = ZORAN_FREE;
932 for (i = 0; i < VIDEO_MAX_FRAME; i++) {
933 zr->v4l_buffers.buffer[i].state = BUZ_STATE_USER; /* nothing going on */
934 }
935 zr->v4l_buffers.allocated = 0;
936
937 for (i = 0; i < BUZ_MAX_FRAME; i++) {
938 zr->jpg_buffers.buffer[i].state = BUZ_STATE_USER; /* nothing going on */
939 }
940 zr->jpg_buffers.active = ZORAN_FREE;
941 zr->jpg_buffers.allocated = 0;
942 /* Set necessary params and call zoran_check_jpg_settings to set the defaults */
943 zr->jpg_settings.decimation = 1;
944 zr->jpg_settings.jpg_comp.quality = 50; /* default compression factor 8 */
945 if (zr->card.type != BUZ)
946 zr->jpg_settings.odd_even = 1;
947 else
948 zr->jpg_settings.odd_even = 0;
949 zr->jpg_settings.jpg_comp.APPn = 0;
950 zr->jpg_settings.jpg_comp.APP_len = 0; /* No APPn marker */
951 memset(zr->jpg_settings.jpg_comp.APP_data, 0,
952 sizeof(zr->jpg_settings.jpg_comp.APP_data));
953 zr->jpg_settings.jpg_comp.COM_len = 0; /* No COM marker */
954 memset(zr->jpg_settings.jpg_comp.COM_data, 0,
955 sizeof(zr->jpg_settings.jpg_comp.COM_data));
956 zr->jpg_settings.jpg_comp.jpeg_markers =
957 JPEG_MARKER_DHT | JPEG_MARKER_DQT;
958 i = zoran_check_jpg_settings(zr, &zr->jpg_settings);
959 if (i)
960 dprintk(1,
961 KERN_ERR
962 "%s: zoran_open_init_params() internal error\n",
963 ZR_DEVNAME(zr));
964
965 clear_interrupt_counters(zr);
966 zr->testing = 0;
967}
968
969static void __devinit
970test_interrupts (struct zoran *zr)
971{
972 DEFINE_WAIT(wait);
973 int timeout, icr;
974
975 clear_interrupt_counters(zr);
976
977 zr->testing = 1;
978 icr = btread(ZR36057_ICR);
979 btwrite(0x78000000 | ZR36057_ICR_IntPinEn, ZR36057_ICR);
980 prepare_to_wait(&zr->test_q, &wait, TASK_INTERRUPTIBLE);
981 timeout = schedule_timeout(HZ);
982 finish_wait(&zr->test_q, &wait);
983 btwrite(0, ZR36057_ICR);
984 btwrite(0x78000000, ZR36057_ISR);
985 zr->testing = 0;
986 dprintk(5, KERN_INFO "%s: Testing interrupts...\n", ZR_DEVNAME(zr));
987 if (timeout) {
988 dprintk(1, ": time spent: %d\n", 1 * HZ - timeout);
989 }
990 if (*zr_debug > 1)
991 print_interrupts(zr);
992 btwrite(icr, ZR36057_ICR);
993}
994
995static int __devinit
996zr36057_init (struct zoran *zr)
997{
998 unsigned long mem;
999 void *vdev;
1000 unsigned mem_needed;
1001 int j;
1002 int two = 2;
1003 int zero = 0;
1004
1005 dprintk(1,
1006 KERN_INFO
1007 "%s: zr36057_init() - initializing card[%d], zr=%p\n",
1008 ZR_DEVNAME(zr), zr->id, zr);
1009
1010 /* default setup of all parameters which will persist between opens */
1011 zr->user = 0;
1012
1013 init_waitqueue_head(&zr->v4l_capq);
1014 init_waitqueue_head(&zr->jpg_capq);
1015 init_waitqueue_head(&zr->test_q);
1016 zr->jpg_buffers.allocated = 0;
1017 zr->v4l_buffers.allocated = 0;
1018
1019 zr->buffer.base = (void *) vidmem;
1020 zr->buffer.width = 0;
1021 zr->buffer.height = 0;
1022 zr->buffer.depth = 0;
1023 zr->buffer.bytesperline = 0;
1024
1025 /* Avoid nonsense settings from user for default input/norm */
1026 if (default_norm < VIDEO_MODE_PAL &&
1027 default_norm > VIDEO_MODE_SECAM)
1028 default_norm = VIDEO_MODE_PAL;
1029 zr->norm = default_norm;
1030 if (!(zr->timing = zr->card.tvn[zr->norm])) {
1031 dprintk(1,
1032 KERN_WARNING
1033 "%s: zr36057_init() - default TV standard not supported by hardware. PAL will be used.\n",
1034 ZR_DEVNAME(zr));
1035 zr->norm = VIDEO_MODE_PAL;
1036 zr->timing = zr->card.tvn[zr->norm];
1037 }
1038
1039 zr->input = default_input = (default_input ? 1 : 0);
1040
1041 /* Should the following be reset at every open ? */
1042 zr->hue = 32768;
1043 zr->contrast = 32768;
1044 zr->saturation = 32768;
1045 zr->brightness = 32768;
1046
1047 /* default setup (will be repeated at every open) */
1048 zoran_open_init_params(zr);
1049
1050 /* allocate memory *before* doing anything to the hardware
1051 * in case allocation fails */
1052 mem_needed = BUZ_NUM_STAT_COM * 4;
1053 mem = (unsigned long) kmalloc(mem_needed, GFP_KERNEL);
1054 vdev = (void *) kmalloc(sizeof(struct video_device), GFP_KERNEL);
1055 if (!mem || !vdev) {
1056 dprintk(1,
1057 KERN_ERR
1058 "%s: zr36057_init() - kmalloc (STAT_COM) failed\n",
1059 ZR_DEVNAME(zr));
1060 if (vdev)
1061 kfree(vdev);
1062 if (mem)
1063 kfree((void *)mem);
1064 return -ENOMEM;
1065 }
1066 memset((void *) mem, 0, mem_needed);
1067 zr->stat_com = (u32 *) mem;
1068 for (j = 0; j < BUZ_NUM_STAT_COM; j++) {
1069 zr->stat_com[j] = 1; /* mark as unavailable to zr36057 */
1070 }
1071
1072 /*
1073 * Now add the template and register the device unit.
1074 */
1075 zr->video_dev = vdev;
1076 memcpy(zr->video_dev, &zoran_template, sizeof(zoran_template));
1077 strcpy(zr->video_dev->name, ZR_DEVNAME(zr));
1078 if (video_register_device(zr->video_dev, VFL_TYPE_GRABBER,
1079 video_nr) < 0) {
1080 zoran_unregister_i2c(zr);
1081 kfree((void *) zr->stat_com);
1082 kfree(vdev);
1083 return -1;
1084 }
1085
1086 zoran_init_hardware(zr);
1087 if (*zr_debug > 2)
1088 detect_guest_activity(zr);
1089 test_interrupts(zr);
1090 if (!pass_through) {
1091 decoder_command(zr, DECODER_ENABLE_OUTPUT, &zero);
1092 encoder_command(zr, ENCODER_SET_INPUT, &two);
1093 }
1094
1095 zr->zoran_proc = NULL;
1096 zr->initialized = 1;
1097 return 0;
1098}
1099
1100static void
1101zoran_release (struct zoran *zr)
1102{
1103 if (!zr->initialized)
1104 return;
1105 /* unregister videocodec bus */
1106 if (zr->codec) {
1107 struct videocodec_master *master = zr->codec->master_data;
1108 videocodec_detach(zr->codec);
1109 if (master)
1110 kfree(master);
1111 }
1112 if (zr->vfe) {
1113 struct videocodec_master *master = zr->vfe->master_data;
1114 videocodec_detach(zr->vfe);
1115 if (master)
1116 kfree(master);
1117 }
1118
1119 /* unregister i2c bus */
1120 zoran_unregister_i2c(zr);
1121 /* disable PCI bus-mastering */
1122 zoran_set_pci_master(zr, 0);
1123 /* put chip into reset */
1124 btwrite(0, ZR36057_SPGPPCR);
1125 free_irq(zr->pci_dev->irq, zr);
1126 /* unmap and free memory */
1127 kfree((void *) zr->stat_com);
1128 zoran_proc_cleanup(zr);
1129 iounmap(zr->zr36057_mem);
1130 pci_disable_device(zr->pci_dev);
1131 video_unregister_device(zr->video_dev);
1132}
1133
1134void
1135zoran_vdev_release (struct video_device *vdev)
1136{
1137 kfree(vdev);
1138}
1139
1140static struct videocodec_master * __devinit
1141zoran_setup_videocodec (struct zoran *zr,
1142 int type)
1143{
1144 struct videocodec_master *m = NULL;
1145
1146 m = kmalloc(sizeof(struct videocodec_master), GFP_KERNEL);
1147 if (!m) {
1148 dprintk(1,
1149 KERN_ERR
1150 "%s: zoran_setup_videocodec() - no memory\n",
1151 ZR_DEVNAME(zr));
1152 return m;
1153 }
1154
1155 m->magic = 0L; /* magic not used */
1156 m->type = VID_HARDWARE_ZR36067;
1157 m->flags = CODEC_FLAG_ENCODER | CODEC_FLAG_DECODER;
1158 strncpy(m->name, ZR_DEVNAME(zr), sizeof(m->name));
1159 m->data = zr;
1160
1161 switch (type)
1162 {
1163 case CODEC_TYPE_ZR36060:
1164 m->readreg = zr36060_read;
1165 m->writereg = zr36060_write;
1166 m->flags |= CODEC_FLAG_JPEG | CODEC_FLAG_VFE;
1167 break;
1168 case CODEC_TYPE_ZR36050:
1169 m->readreg = zr36050_read;
1170 m->writereg = zr36050_write;
1171 m->flags |= CODEC_FLAG_JPEG;
1172 break;
1173 case CODEC_TYPE_ZR36016:
1174 m->readreg = zr36016_read;
1175 m->writereg = zr36016_write;
1176 m->flags |= CODEC_FLAG_VFE;
1177 break;
1178 }
1179
1180 return m;
1181}
1182
1183/*
1184 * Scan for a Buz card (actually for the PCI contoler ZR36057),
1185 * request the irq and map the io memory
1186 */
1187static int __devinit
1188find_zr36057 (void)
1189{
1190 unsigned char latency, need_latency;
1191 struct zoran *zr;
1192 struct pci_dev *dev = NULL;
1193 int result;
1194 struct videocodec_master *master_vfe = NULL;
1195 struct videocodec_master *master_codec = NULL;
1196 int card_num;
1197 char *i2c_enc_name, *i2c_dec_name, *codec_name, *vfe_name;
1198
1199 zoran_num = 0;
1200 while (zoran_num < BUZ_MAX &&
1201 (dev =
1202 pci_find_device(PCI_VENDOR_ID_ZORAN,
1203 PCI_DEVICE_ID_ZORAN_36057, dev)) != NULL) {
1204 card_num = card[zoran_num];
1205 zr = &zoran[zoran_num];
1206 memset(zr, 0, sizeof(struct zoran)); // Just in case if previous cycle failed
1207 zr->pci_dev = dev;
1208 //zr->zr36057_mem = NULL;
1209 zr->id = zoran_num;
1210 snprintf(ZR_DEVNAME(zr), sizeof(ZR_DEVNAME(zr)), "MJPEG[%u]", zr->id);
1211 spin_lock_init(&zr->spinlock);
1212 init_MUTEX(&zr->resource_lock);
1213 if (pci_enable_device(dev))
1214 continue;
1215 zr->zr36057_adr = pci_resource_start(zr->pci_dev, 0);
1216 pci_read_config_byte(zr->pci_dev, PCI_CLASS_REVISION,
1217 &zr->revision);
1218 if (zr->revision < 2) {
1219 dprintk(1,
1220 KERN_INFO
1221 "%s: Zoran ZR36057 (rev %d) irq: %d, memory: 0x%08x.\n",
1222 ZR_DEVNAME(zr), zr->revision, zr->pci_dev->irq,
1223 zr->zr36057_adr);
1224
1225 if (card_num == -1) {
1226 dprintk(1,
1227 KERN_ERR
1228 "%s: find_zr36057() - no card specified, please use the card=X insmod option\n",
1229 ZR_DEVNAME(zr));
1230 continue;
1231 }
1232 } else {
1233 int i;
1234 unsigned short ss_vendor, ss_device;
1235
1236 ss_vendor = zr->pci_dev->subsystem_vendor;
1237 ss_device = zr->pci_dev->subsystem_device;
1238 dprintk(1,
1239 KERN_INFO
1240 "%s: Zoran ZR36067 (rev %d) irq: %d, memory: 0x%08x\n",
1241 ZR_DEVNAME(zr), zr->revision, zr->pci_dev->irq,
1242 zr->zr36057_adr);
1243 dprintk(1,
1244 KERN_INFO
1245 "%s: subsystem vendor=0x%04x id=0x%04x\n",
1246 ZR_DEVNAME(zr), ss_vendor, ss_device);
1247 if (card_num == -1) {
1248 dprintk(3,
1249 KERN_DEBUG
1250 "%s: find_zr36057() - trying to autodetect card type\n",
1251 ZR_DEVNAME(zr));
1252 for (i=0;i<NUM_CARDS;i++) {
1253 if (ss_vendor == zoran_cards[i].vendor_id &&
1254 ss_device == zoran_cards[i].device_id) {
1255 dprintk(3,
1256 KERN_DEBUG
1257 "%s: find_zr36057() - card %s detected\n",
1258 ZR_DEVNAME(zr),
1259 zoran_cards[i].name);
1260 card_num = i;
1261 break;
1262 }
1263 }
1264 if (i == NUM_CARDS) {
1265 dprintk(1,
1266 KERN_ERR
1267 "%s: find_zr36057() - unknown card\n",
1268 ZR_DEVNAME(zr));
1269 continue;
1270 }
1271 }
1272 }
1273
1274 if (card_num < 0 || card_num >= NUM_CARDS) {
1275 dprintk(2,
1276 KERN_ERR
1277 "%s: find_zr36057() - invalid cardnum %d\n",
1278 ZR_DEVNAME(zr), card_num);
1279 continue;
1280 }
1281
1282 /* even though we make this a non pointer and thus
1283 * theoretically allow for making changes to this struct
1284 * on a per-individual card basis at runtime, this is
1285 * strongly discouraged. This structure is intended to
1286 * keep general card information, no settings or anything */
1287 zr->card = zoran_cards[card_num];
1288 snprintf(ZR_DEVNAME(zr), sizeof(ZR_DEVNAME(zr)),
1289 "%s[%u]", zr->card.name, zr->id);
1290
1291 zr->zr36057_mem = ioremap_nocache(zr->zr36057_adr, 0x1000);
1292 if (!zr->zr36057_mem) {
1293 dprintk(1,
1294 KERN_ERR
1295 "%s: find_zr36057() - ioremap failed\n",
1296 ZR_DEVNAME(zr));
1297 continue;
1298 }
1299
1300 result = request_irq(zr->pci_dev->irq,
1301 zoran_irq,
1302 SA_SHIRQ | SA_INTERRUPT,
1303 ZR_DEVNAME(zr),
1304 (void *) zr);
1305 if (result < 0) {
1306 if (result == -EINVAL) {
1307 dprintk(1,
1308 KERN_ERR
1309 "%s: find_zr36057() - bad irq number or handler\n",
1310 ZR_DEVNAME(zr));
1311 } else if (result == -EBUSY) {
1312 dprintk(1,
1313 KERN_ERR
1314 "%s: find_zr36057() - IRQ %d busy, change your PnP config in BIOS\n",
1315 ZR_DEVNAME(zr), zr->pci_dev->irq);
1316 } else {
1317 dprintk(1,
1318 KERN_ERR
1319 "%s: find_zr36057() - can't assign irq, error code %d\n",
1320 ZR_DEVNAME(zr), result);
1321 }
1322 goto zr_unmap;
1323 }
1324
1325 /* set PCI latency timer */
1326 pci_read_config_byte(zr->pci_dev, PCI_LATENCY_TIMER,
1327 &latency);
1328 need_latency = zr->revision > 1 ? 32 : 48;
1329 if (latency != need_latency) {
1330 dprintk(2,
1331 KERN_INFO
1332 "%s: Changing PCI latency from %d to %d.\n",
1333 ZR_DEVNAME(zr), latency, need_latency);
1334 pci_write_config_byte(zr->pci_dev,
1335 PCI_LATENCY_TIMER,
1336 need_latency);
1337 }
1338
1339 zr36057_restart(zr);
1340 /* i2c */
1341 dprintk(2, KERN_INFO "%s: Initializing i2c bus...\n",
1342 ZR_DEVNAME(zr));
1343
1344 /* i2c decoder */
1345 if (decoder[zr->id] != -1) {
1346 i2c_dec_name = i2cid_to_modulename(decoder[zr->id]);
1347 zr->card.i2c_decoder = decoder[zr->id];
1348 } else if (zr->card.i2c_decoder != 0) {
1349 i2c_dec_name =
1350 i2cid_to_modulename(zr->card.i2c_decoder);
1351 } else {
1352 i2c_dec_name = NULL;
1353 }
1354
1355 if (i2c_dec_name) {
1356 if ((result = request_module(i2c_dec_name)) < 0) {
1357 dprintk(1,
1358 KERN_ERR
1359 "%s: failed to load module %s: %d\n",
1360 ZR_DEVNAME(zr), i2c_dec_name, result);
1361 }
1362 }
1363
1364 /* i2c encoder */
1365 if (encoder[zr->id] != -1) {
1366 i2c_enc_name = i2cid_to_modulename(encoder[zr->id]);
1367 zr->card.i2c_encoder = encoder[zr->id];
1368 } else if (zr->card.i2c_encoder != 0) {
1369 i2c_enc_name =
1370 i2cid_to_modulename(zr->card.i2c_encoder);
1371 } else {
1372 i2c_enc_name = NULL;
1373 }
1374
1375 if (i2c_enc_name) {
1376 if ((result = request_module(i2c_enc_name)) < 0) {
1377 dprintk(1,
1378 KERN_ERR
1379 "%s: failed to load module %s: %d\n",
1380 ZR_DEVNAME(zr), i2c_enc_name, result);
1381 }
1382 }
1383
1384 if (zoran_register_i2c(zr) < 0) {
1385 dprintk(1,
1386 KERN_ERR
1387 "%s: find_zr36057() - can't initialize i2c bus\n",
1388 ZR_DEVNAME(zr));
1389 goto zr_free_irq;
1390 }
1391
1392 dprintk(2,
1393 KERN_INFO "%s: Initializing videocodec bus...\n",
1394 ZR_DEVNAME(zr));
1395
1396 if (zr->card.video_codec != 0 &&
1397 (codec_name =
1398 codecid_to_modulename(zr->card.video_codec)) != NULL) {
1399 if ((result = request_module(codec_name)) < 0) {
1400 dprintk(1,
1401 KERN_ERR
1402 "%s: failed to load modules %s: %d\n",
1403 ZR_DEVNAME(zr), codec_name, result);
1404 }
1405 }
1406 if (zr->card.video_vfe != 0 &&
1407 (vfe_name =
1408 codecid_to_modulename(zr->card.video_vfe)) != NULL) {
1409 if ((result = request_module(vfe_name)) < 0) {
1410 dprintk(1,
1411 KERN_ERR
1412 "%s: failed to load modules %s: %d\n",
1413 ZR_DEVNAME(zr), vfe_name, result);
1414 }
1415 }
1416
1417 /* reset JPEG codec */
1418 jpeg_codec_sleep(zr, 1);
1419 jpeg_codec_reset(zr);
1420 /* video bus enabled */
1421 /* display codec revision */
1422 if (zr->card.video_codec != 0) {
1423 master_codec = zoran_setup_videocodec(zr,
1424 zr->card.video_codec);
1425 if (!master_codec)
1426 goto zr_unreg_i2c;
1427 zr->codec = videocodec_attach(master_codec);
1428 if (!zr->codec) {
1429 dprintk(1,
1430 KERN_ERR
1431 "%s: find_zr36057() - no codec found\n",
1432 ZR_DEVNAME(zr));
1433 goto zr_free_codec;
1434 }
1435 if (zr->codec->type != zr->card.video_codec) {
1436 dprintk(1,
1437 KERN_ERR
1438 "%s: find_zr36057() - wrong codec\n",
1439 ZR_DEVNAME(zr));
1440 goto zr_detach_codec;
1441 }
1442 }
1443 if (zr->card.video_vfe != 0) {
1444 master_vfe = zoran_setup_videocodec(zr,
1445 zr->card.video_vfe);
1446 if (!master_vfe)
1447 goto zr_detach_codec;
1448 zr->vfe = videocodec_attach(master_vfe);
1449 if (!zr->vfe) {
1450 dprintk(1,
1451 KERN_ERR
1452 "%s: find_zr36057() - no VFE found\n",
1453 ZR_DEVNAME(zr));
1454 goto zr_free_vfe;
1455 }
1456 if (zr->vfe->type != zr->card.video_vfe) {
1457 dprintk(1,
1458 KERN_ERR
1459 "%s: find_zr36057() = wrong VFE\n",
1460 ZR_DEVNAME(zr));
1461 goto zr_detach_vfe;
1462 }
1463 }
1464
1465 zoran_num++;
1466 continue;
1467
1468 // Init errors
1469 zr_detach_vfe:
1470 videocodec_detach(zr->vfe);
1471 zr_free_vfe:
1472 kfree(master_vfe);
1473 zr_detach_codec:
1474 videocodec_detach(zr->codec);
1475 zr_free_codec:
1476 kfree(master_codec);
1477 zr_unreg_i2c:
1478 zoran_unregister_i2c(zr);
1479 zr_free_irq:
1480 btwrite(0, ZR36057_SPGPPCR);
1481 free_irq(zr->pci_dev->irq, zr);
1482 zr_unmap:
1483 iounmap(zr->zr36057_mem);
1484 continue;
1485 }
1486 if (zoran_num == 0) {
1487 dprintk(1, KERN_INFO "No known MJPEG cards found.\n");
1488 }
1489 return zoran_num;
1490}
1491
1492static int __init
1493init_dc10_cards (void)
1494{
1495 int i;
1496
1497 memset(zoran, 0, sizeof(zoran));
1498 printk(KERN_INFO "Zoran MJPEG board driver version %d.%d.%d\n",
1499 MAJOR_VERSION, MINOR_VERSION, RELEASE_VERSION);
1500
1501 /* Look for cards */
1502 if (find_zr36057() < 0) {
1503 return -EIO;
1504 }
1505 if (zoran_num == 0)
1506 return -ENODEV;
1507 dprintk(1, KERN_INFO "%s: %d card(s) found\n", ZORAN_NAME,
1508 zoran_num);
1509 /* check the parameters we have been given, adjust if necessary */
1510 if (v4l_nbufs < 2)
1511 v4l_nbufs = 2;
1512 if (v4l_nbufs > VIDEO_MAX_FRAME)
1513 v4l_nbufs = VIDEO_MAX_FRAME;
1514 /* The user specfies the in KB, we want them in byte
1515 * (and page aligned) */
1516 v4l_bufsize = PAGE_ALIGN(v4l_bufsize * 1024);
1517 if (v4l_bufsize < 32768)
1518 v4l_bufsize = 32768;
1519 /* 2 MB is arbitrary but sufficient for the maximum possible images */
1520 if (v4l_bufsize > 2048 * 1024)
1521 v4l_bufsize = 2048 * 1024;
1522 if (jpg_nbufs < 4)
1523 jpg_nbufs = 4;
1524 if (jpg_nbufs > BUZ_MAX_FRAME)
1525 jpg_nbufs = BUZ_MAX_FRAME;
1526 jpg_bufsize = PAGE_ALIGN(jpg_bufsize * 1024);
1527 if (jpg_bufsize < 8192)
1528 jpg_bufsize = 8192;
1529 if (jpg_bufsize > (512 * 1024))
1530 jpg_bufsize = 512 * 1024;
1531 /* Use parameter for vidmem or try to find a video card */
1532 if (vidmem) {
1533 dprintk(1,
1534 KERN_INFO
1535 "%s: Using supplied video memory base address @ 0x%lx\n",
1536 ZORAN_NAME, vidmem);
1537 }
1538
1539 /* random nonsense */
1540 dprintk(5, KERN_DEBUG "Jotti is een held!\n");
1541
1542 /* some mainboards might not do PCI-PCI data transfer well */
1543 if (pci_pci_problems & PCIPCI_FAIL) {
1544 dprintk(1,
1545 KERN_WARNING
1546 "%s: chipset may not support reliable PCI-PCI DMA\n",
1547 ZORAN_NAME);
1548 }
1549
1550 /* take care of Natoma chipset and a revision 1 zr36057 */
1551 for (i = 0; i < zoran_num; i++) {
1552 struct zoran *zr = &zoran[i];
1553
1554 if (pci_pci_problems & PCIPCI_NATOMA && zr->revision <= 1) {
1555 zr->jpg_buffers.need_contiguous = 1;
1556 dprintk(1,
1557 KERN_INFO
1558 "%s: ZR36057/Natoma bug, max. buffer size is 128K\n",
1559 ZR_DEVNAME(zr));
1560 }
1561
1562 if (zr36057_init(zr) < 0) {
1563 for (i = 0; i < zoran_num; i++)
1564 zoran_release(&zoran[i]);
1565 return -EIO;
1566 }
1567 zoran_proc_init(zr);
1568 }
1569
1570 return 0;
1571}
1572
1573static void __exit
1574unload_dc10_cards (void)
1575{
1576 int i;
1577
1578 for (i = 0; i < zoran_num; i++)
1579 zoran_release(&zoran[i]);
1580}
1581
1582module_init(init_dc10_cards);
1583module_exit(unload_dc10_cards);
diff --git a/drivers/media/video/zoran_card.h b/drivers/media/video/zoran_card.h
new file mode 100644
index 00000000000..e5b6acd3eed
--- /dev/null
+++ b/drivers/media/video/zoran_card.h
@@ -0,0 +1,45 @@
1/*
2 * Zoran zr36057/zr36067 PCI controller driver, for the
3 * Pinnacle/Miro DC10/DC10+/DC30/DC30+, Iomega Buz, Linux
4 * Media Labs LML33/LML33R10.
5 *
6 * This part handles card-specific data and detection
7 *
8 * Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>
9 *
10 * Currently maintained by:
11 * Ronald Bultje <rbultje@ronald.bitfreak.net>
12 * Laurent Pinchart <laurent.pinchart@skynet.be>
13 * Mailinglist <mjpeg-users@lists.sf.net>
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 */
29
30#ifndef __ZORAN_CARD_H__
31#define __ZORAN_CARD_H__
32
33/* Anybody who uses more than four? */
34#define BUZ_MAX 4
35extern int zoran_num;
36extern struct zoran zoran[BUZ_MAX];
37
38extern struct video_device zoran_template;
39
40extern int zoran_check_jpg_settings(struct zoran *zr,
41 struct zoran_jpg_settings *settings);
42extern void zoran_open_init_params(struct zoran *zr);
43extern void zoran_vdev_release(struct video_device *vdev);
44
45#endif /* __ZORAN_CARD_H__ */
diff --git a/drivers/media/video/zoran_device.c b/drivers/media/video/zoran_device.c
new file mode 100644
index 00000000000..4e15afdec4c
--- /dev/null
+++ b/drivers/media/video/zoran_device.c
@@ -0,0 +1,1785 @@
1/*
2 * Zoran zr36057/zr36067 PCI controller driver, for the
3 * Pinnacle/Miro DC10/DC10+/DC30/DC30+, Iomega Buz, Linux
4 * Media Labs LML33/LML33R10.
5 *
6 * This part handles device access (PCI/I2C/codec/...)
7 *
8 * Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>
9 *
10 * Currently maintained by:
11 * Ronald Bultje <rbultje@ronald.bitfreak.net>
12 * Laurent Pinchart <laurent.pinchart@skynet.be>
13 * Mailinglist <mjpeg-users@lists.sf.net>
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 */
29
30#include <linux/config.h>
31#include <linux/types.h>
32#include <linux/kernel.h>
33#include <linux/module.h>
34#include <linux/vmalloc.h>
35#include <linux/byteorder/generic.h>
36
37#include <linux/interrupt.h>
38#include <linux/proc_fs.h>
39#include <linux/i2c.h>
40#include <linux/i2c-algo-bit.h>
41#include <linux/videodev.h>
42#include <linux/spinlock.h>
43#include <linux/sem.h>
44
45#include <linux/pci.h>
46#include <linux/video_decoder.h>
47#include <linux/video_encoder.h>
48#include <linux/delay.h>
49#include <linux/wait.h>
50
51#include <asm/io.h>
52
53#include "videocodec.h"
54#include "zoran.h"
55#include "zoran_device.h"
56
57#define IRQ_MASK ( ZR36057_ISR_GIRQ0 | \
58 ZR36057_ISR_GIRQ1 | \
59 ZR36057_ISR_JPEGRepIRQ )
60
61extern const struct zoran_format zoran_formats[];
62
63extern int *zr_debug;
64
65#define dprintk(num, format, args...) \
66 do { \
67 if (*zr_debug >= num) \
68 printk(format, ##args); \
69 } while (0)
70
71static int lml33dpath = 0; /* 1 will use digital path in capture
72 * mode instead of analog. It can be
73 * used for picture adjustments using
74 * tool like xawtv while watching image
75 * on TV monitor connected to the output.
76 * However, due to absence of 75 Ohm
77 * load on Bt819 input, there will be
78 * some image imperfections */
79
80module_param(lml33dpath, bool, 0);
81MODULE_PARM_DESC(lml33dpath,
82 "Use digital path capture mode (on LML33 cards)");
83
84static void
85zr36057_init_vfe (struct zoran *zr);
86
87/*
88 * General Purpose I/O and Guest bus access
89 */
90
91/*
92 * This is a bit tricky. When a board lacks a GPIO function, the corresponding
93 * GPIO bit number in the card_info structure is set to 0.
94 */
95
96void
97GPIO (struct zoran *zr,
98 int bit,
99 unsigned int value)
100{
101 u32 reg;
102 u32 mask;
103
104 /* Make sure the bit number is legal
105 * A bit number of -1 (lacking) gives a mask of 0,
106 * making it harmless */
107 mask = (1 << (24 + bit)) & 0xff000000;
108 reg = btread(ZR36057_GPPGCR1) & ~mask;
109 if (value) {
110 reg |= mask;
111 }
112 btwrite(reg, ZR36057_GPPGCR1);
113 udelay(1);
114}
115
116/*
117 * Wait til post office is no longer busy
118 */
119
120int
121post_office_wait (struct zoran *zr)
122{
123 u32 por;
124
125// while (((por = btread(ZR36057_POR)) & (ZR36057_POR_POPen | ZR36057_POR_POTime)) == ZR36057_POR_POPen) {
126 while ((por = btread(ZR36057_POR)) & ZR36057_POR_POPen) {
127 /* wait for something to happen */
128 }
129 if ((por & ZR36057_POR_POTime) && !zr->card.gws_not_connected) {
130 /* In LML33/BUZ \GWS line is not connected, so it has always timeout set */
131 dprintk(1, KERN_INFO "%s: pop timeout %08x\n", ZR_DEVNAME(zr),
132 por);
133 return -1;
134 }
135
136 return 0;
137}
138
139int
140post_office_write (struct zoran *zr,
141 unsigned int guest,
142 unsigned int reg,
143 unsigned int value)
144{
145 u32 por;
146
147 por =
148 ZR36057_POR_PODir | ZR36057_POR_POTime | ((guest & 7) << 20) |
149 ((reg & 7) << 16) | (value & 0xFF);
150 btwrite(por, ZR36057_POR);
151
152 return post_office_wait(zr);
153}
154
155int
156post_office_read (struct zoran *zr,
157 unsigned int guest,
158 unsigned int reg)
159{
160 u32 por;
161
162 por = ZR36057_POR_POTime | ((guest & 7) << 20) | ((reg & 7) << 16);
163 btwrite(por, ZR36057_POR);
164 if (post_office_wait(zr) < 0) {
165 return -1;
166 }
167
168 return btread(ZR36057_POR) & 0xFF;
169}
170
171/*
172 * detect guests
173 */
174
175static void
176dump_guests (struct zoran *zr)
177{
178 if (*zr_debug > 2) {
179 int i, guest[8];
180
181 for (i = 1; i < 8; i++) { // Don't read jpeg codec here
182 guest[i] = post_office_read(zr, i, 0);
183 }
184
185 printk(KERN_INFO "%s: Guests:", ZR_DEVNAME(zr));
186
187 for (i = 1; i < 8; i++) {
188 printk(" 0x%02x", guest[i]);
189 }
190 printk("\n");
191 }
192}
193
194static inline unsigned long
195get_time (void)
196{
197 struct timeval tv;
198
199 do_gettimeofday(&tv);
200 return (1000000 * tv.tv_sec + tv.tv_usec);
201}
202
203void
204detect_guest_activity (struct zoran *zr)
205{
206 int timeout, i, j, res, guest[8], guest0[8], change[8][3];
207 unsigned long t0, t1;
208
209 dump_guests(zr);
210 printk(KERN_INFO "%s: Detecting guests activity, please wait...\n",
211 ZR_DEVNAME(zr));
212 for (i = 1; i < 8; i++) { // Don't read jpeg codec here
213 guest0[i] = guest[i] = post_office_read(zr, i, 0);
214 }
215
216 timeout = 0;
217 j = 0;
218 t0 = get_time();
219 while (timeout < 10000) {
220 udelay(10);
221 timeout++;
222 for (i = 1; (i < 8) && (j < 8); i++) {
223 res = post_office_read(zr, i, 0);
224 if (res != guest[i]) {
225 t1 = get_time();
226 change[j][0] = (t1 - t0);
227 t0 = t1;
228 change[j][1] = i;
229 change[j][2] = res;
230 j++;
231 guest[i] = res;
232 }
233 }
234 if (j >= 8)
235 break;
236 }
237 printk(KERN_INFO "%s: Guests:", ZR_DEVNAME(zr));
238
239 for (i = 1; i < 8; i++) {
240 printk(" 0x%02x", guest0[i]);
241 }
242 printk("\n");
243 if (j == 0) {
244 printk(KERN_INFO "%s: No activity detected.\n", ZR_DEVNAME(zr));
245 return;
246 }
247 for (i = 0; i < j; i++) {
248 printk(KERN_INFO "%s: %6d: %d => 0x%02x\n", ZR_DEVNAME(zr),
249 change[i][0], change[i][1], change[i][2]);
250 }
251}
252
253/*
254 * JPEG Codec access
255 */
256
257void
258jpeg_codec_sleep (struct zoran *zr,
259 int sleep)
260{
261 GPIO(zr, zr->card.gpio[GPIO_JPEG_SLEEP], !sleep);
262 if (!sleep) {
263 dprintk(3,
264 KERN_DEBUG
265 "%s: jpeg_codec_sleep() - wake GPIO=0x%08x\n",
266 ZR_DEVNAME(zr), btread(ZR36057_GPPGCR1));
267 udelay(500);
268 } else {
269 dprintk(3,
270 KERN_DEBUG
271 "%s: jpeg_codec_sleep() - sleep GPIO=0x%08x\n",
272 ZR_DEVNAME(zr), btread(ZR36057_GPPGCR1));
273 udelay(2);
274 }
275}
276
277int
278jpeg_codec_reset (struct zoran *zr)
279{
280 /* Take the codec out of sleep */
281 jpeg_codec_sleep(zr, 0);
282
283 if (zr->card.gpcs[GPCS_JPEG_RESET] != 0xff) {
284 post_office_write(zr, zr->card.gpcs[GPCS_JPEG_RESET], 0,
285 0);
286 udelay(2);
287 } else {
288 GPIO(zr, zr->card.gpio[GPIO_JPEG_RESET], 0);
289 udelay(2);
290 GPIO(zr, zr->card.gpio[GPIO_JPEG_RESET], 1);
291 udelay(2);
292 }
293
294 return 0;
295}
296
297/*
298 * Set the registers for the size we have specified. Don't bother
299 * trying to understand this without the ZR36057 manual in front of
300 * you [AC].
301 *
302 * PS: The manual is free for download in .pdf format from
303 * www.zoran.com - nicely done those folks.
304 */
305
306static void
307zr36057_adjust_vfe (struct zoran *zr,
308 enum zoran_codec_mode mode)
309{
310 u32 reg;
311
312 switch (mode) {
313 case BUZ_MODE_MOTION_DECOMPRESS:
314 btand(~ZR36057_VFESPFR_ExtFl, ZR36057_VFESPFR);
315 reg = btread(ZR36057_VFEHCR);
316 if ((reg & (1 << 10)) && zr->card.type != LML33R10) {
317 reg += ((1 << 10) | 1);
318 }
319 btwrite(reg, ZR36057_VFEHCR);
320 break;
321 case BUZ_MODE_MOTION_COMPRESS:
322 case BUZ_MODE_IDLE:
323 default:
324 if (zr->norm == VIDEO_MODE_NTSC ||
325 (zr->card.type == LML33R10 &&
326 zr->norm == VIDEO_MODE_PAL))
327 btand(~ZR36057_VFESPFR_ExtFl, ZR36057_VFESPFR);
328 else
329 btor(ZR36057_VFESPFR_ExtFl, ZR36057_VFESPFR);
330 reg = btread(ZR36057_VFEHCR);
331 if (!(reg & (1 << 10)) && zr->card.type != LML33R10) {
332 reg -= ((1 << 10) | 1);
333 }
334 btwrite(reg, ZR36057_VFEHCR);
335 break;
336 }
337}
338
339/*
340 * set geometry
341 */
342
343static void
344zr36057_set_vfe (struct zoran *zr,
345 int video_width,
346 int video_height,
347 const struct zoran_format *format)
348{
349 struct tvnorm *tvn;
350 unsigned HStart, HEnd, VStart, VEnd;
351 unsigned DispMode;
352 unsigned VidWinWid, VidWinHt;
353 unsigned hcrop1, hcrop2, vcrop1, vcrop2;
354 unsigned Wa, We, Ha, He;
355 unsigned X, Y, HorDcm, VerDcm;
356 u32 reg;
357 unsigned mask_line_size;
358
359 tvn = zr->timing;
360
361 Wa = tvn->Wa;
362 Ha = tvn->Ha;
363
364 dprintk(2, KERN_INFO "%s: set_vfe() - width = %d, height = %d\n",
365 ZR_DEVNAME(zr), video_width, video_height);
366
367 if (zr->norm != VIDEO_MODE_PAL &&
368 zr->norm != VIDEO_MODE_NTSC &&
369 zr->norm != VIDEO_MODE_SECAM) {
370 dprintk(1,
371 KERN_ERR "%s: set_vfe() - norm = %d not valid\n",
372 ZR_DEVNAME(zr), zr->norm);
373 return;
374 }
375 if (video_width < BUZ_MIN_WIDTH ||
376 video_height < BUZ_MIN_HEIGHT ||
377 video_width > Wa || video_height > Ha) {
378 dprintk(1, KERN_ERR "%s: set_vfe: w=%d h=%d not valid\n",
379 ZR_DEVNAME(zr), video_width, video_height);
380 return;
381 }
382
383 /**** zr36057 ****/
384
385 /* horizontal */
386 VidWinWid = video_width;
387 X = (VidWinWid * 64 + tvn->Wa - 1) / tvn->Wa;
388 We = (VidWinWid * 64) / X;
389 HorDcm = 64 - X;
390 hcrop1 = 2 * ((tvn->Wa - We) / 4);
391 hcrop2 = tvn->Wa - We - hcrop1;
392 HStart = tvn->HStart ? tvn->HStart : 1;
393 /* (Ronald) Original comment:
394 * "| 1 Doesn't have any effect, tested on both a DC10 and a DC10+"
395 * this is false. It inverses chroma values on the LML33R10 (so Cr
396 * suddenly is shown as Cb and reverse, really cool effect if you
397 * want to see blue faces, not useful otherwise). So don't use |1.
398 * However, the DC10 has '0' as HStart, but does need |1, so we
399 * use a dirty check...
400 */
401 HEnd = HStart + tvn->Wa - 1;
402 HStart += hcrop1;
403 HEnd -= hcrop2;
404 reg = ((HStart & ZR36057_VFEHCR_Hmask) << ZR36057_VFEHCR_HStart)
405 | ((HEnd & ZR36057_VFEHCR_Hmask) << ZR36057_VFEHCR_HEnd);
406 if (zr->card.vfe_pol.hsync_pol)
407 reg |= ZR36057_VFEHCR_HSPol;
408 btwrite(reg, ZR36057_VFEHCR);
409
410 /* Vertical */
411 DispMode = !(video_height > BUZ_MAX_HEIGHT / 2);
412 VidWinHt = DispMode ? video_height : video_height / 2;
413 Y = (VidWinHt * 64 * 2 + tvn->Ha - 1) / tvn->Ha;
414 He = (VidWinHt * 64) / Y;
415 VerDcm = 64 - Y;
416 vcrop1 = (tvn->Ha / 2 - He) / 2;
417 vcrop2 = tvn->Ha / 2 - He - vcrop1;
418 VStart = tvn->VStart;
419 VEnd = VStart + tvn->Ha / 2; // - 1; FIXME SnapShot times out with -1 in 768*576 on the DC10 - LP
420 VStart += vcrop1;
421 VEnd -= vcrop2;
422 reg = ((VStart & ZR36057_VFEVCR_Vmask) << ZR36057_VFEVCR_VStart)
423 | ((VEnd & ZR36057_VFEVCR_Vmask) << ZR36057_VFEVCR_VEnd);
424 if (zr->card.vfe_pol.vsync_pol)
425 reg |= ZR36057_VFEVCR_VSPol;
426 btwrite(reg, ZR36057_VFEVCR);
427
428 /* scaler and pixel format */
429 reg = 0;
430 reg |= (HorDcm << ZR36057_VFESPFR_HorDcm);
431 reg |= (VerDcm << ZR36057_VFESPFR_VerDcm);
432 reg |= (DispMode << ZR36057_VFESPFR_DispMode);
433 if (format->palette != VIDEO_PALETTE_YUV422)
434 reg |= ZR36057_VFESPFR_LittleEndian;
435 /* RJ: I don't know, why the following has to be the opposite
436 * of the corresponding ZR36060 setting, but only this way
437 * we get the correct colors when uncompressing to the screen */
438 //reg |= ZR36057_VFESPFR_VCLKPol; /**/
439 /* RJ: Don't know if that is needed for NTSC also */
440 if (zr->norm != VIDEO_MODE_NTSC)
441 reg |= ZR36057_VFESPFR_ExtFl; // NEEDED!!!!!!! Wolfgang
442 reg |= ZR36057_VFESPFR_TopField;
443 switch (format->palette) {
444
445 case VIDEO_PALETTE_YUV422:
446 reg |= ZR36057_VFESPFR_YUV422;
447 break;
448
449 case VIDEO_PALETTE_RGB555:
450 reg |= ZR36057_VFESPFR_RGB555 | ZR36057_VFESPFR_ErrDif;
451 break;
452
453 case VIDEO_PALETTE_RGB565:
454 reg |= ZR36057_VFESPFR_RGB565 | ZR36057_VFESPFR_ErrDif;
455 break;
456
457 case VIDEO_PALETTE_RGB24:
458 reg |= ZR36057_VFESPFR_RGB888 | ZR36057_VFESPFR_Pack24;
459 break;
460
461 case VIDEO_PALETTE_RGB32:
462 reg |= ZR36057_VFESPFR_RGB888;
463 break;
464
465 default:
466 dprintk(1,
467 KERN_INFO "%s: set_vfe() - unknown color_fmt=%x\n",
468 ZR_DEVNAME(zr), format->palette);
469 return;
470
471 }
472 if (HorDcm >= 48) {
473 reg |= 3 << ZR36057_VFESPFR_HFilter; /* 5 tap filter */
474 } else if (HorDcm >= 32) {
475 reg |= 2 << ZR36057_VFESPFR_HFilter; /* 4 tap filter */
476 } else if (HorDcm >= 16) {
477 reg |= 1 << ZR36057_VFESPFR_HFilter; /* 3 tap filter */
478 }
479 btwrite(reg, ZR36057_VFESPFR);
480
481 /* display configuration */
482 reg = (16 << ZR36057_VDCR_MinPix)
483 | (VidWinHt << ZR36057_VDCR_VidWinHt)
484 | (VidWinWid << ZR36057_VDCR_VidWinWid);
485 if (pci_pci_problems & PCIPCI_TRITON)
486 // || zr->revision < 1) // Revision 1 has also Triton support
487 reg &= ~ZR36057_VDCR_Triton;
488 else
489 reg |= ZR36057_VDCR_Triton;
490 btwrite(reg, ZR36057_VDCR);
491
492 /* (Ronald) don't write this if overlay_mask = NULL */
493 if (zr->overlay_mask) {
494 /* Write overlay clipping mask data, but don't enable overlay clipping */
495 /* RJ: since this makes only sense on the screen, we use
496 * zr->overlay_settings.width instead of video_width */
497
498 mask_line_size = (BUZ_MAX_WIDTH + 31) / 32;
499 reg = virt_to_bus(zr->overlay_mask);
500 btwrite(reg, ZR36057_MMTR);
501 reg = virt_to_bus(zr->overlay_mask + mask_line_size);
502 btwrite(reg, ZR36057_MMBR);
503 reg =
504 mask_line_size - (zr->overlay_settings.width +
505 31) / 32;
506 if (DispMode == 0)
507 reg += mask_line_size;
508 reg <<= ZR36057_OCR_MaskStride;
509 btwrite(reg, ZR36057_OCR);
510 }
511
512 zr36057_adjust_vfe(zr, zr->codec_mode);
513}
514
515/*
516 * Switch overlay on or off
517 */
518
519void
520zr36057_overlay (struct zoran *zr,
521 int on)
522{
523 u32 reg;
524
525 if (on) {
526 /* do the necessary settings ... */
527 btand(~ZR36057_VDCR_VidEn, ZR36057_VDCR); /* switch it off first */
528
529 zr36057_set_vfe(zr,
530 zr->overlay_settings.width,
531 zr->overlay_settings.height,
532 zr->overlay_settings.format);
533
534 /* Start and length of each line MUST be 4-byte aligned.
535 * This should be allready checked before the call to this routine.
536 * All error messages are internal driver checking only! */
537
538 /* video display top and bottom registers */
539 reg = (u32) zr->buffer.base +
540 zr->overlay_settings.x *
541 ((zr->overlay_settings.format->depth + 7) / 8) +
542 zr->overlay_settings.y *
543 zr->buffer.bytesperline;
544 btwrite(reg, ZR36057_VDTR);
545 if (reg & 3)
546 dprintk(1,
547 KERN_ERR
548 "%s: zr36057_overlay() - video_address not aligned\n",
549 ZR_DEVNAME(zr));
550 if (zr->overlay_settings.height > BUZ_MAX_HEIGHT / 2)
551 reg += zr->buffer.bytesperline;
552 btwrite(reg, ZR36057_VDBR);
553
554 /* video stride, status, and frame grab register */
555 reg = zr->buffer.bytesperline -
556 zr->overlay_settings.width *
557 ((zr->overlay_settings.format->depth + 7) / 8);
558 if (zr->overlay_settings.height > BUZ_MAX_HEIGHT / 2)
559 reg += zr->buffer.bytesperline;
560 if (reg & 3)
561 dprintk(1,
562 KERN_ERR
563 "%s: zr36057_overlay() - video_stride not aligned\n",
564 ZR_DEVNAME(zr));
565 reg = (reg << ZR36057_VSSFGR_DispStride);
566 reg |= ZR36057_VSSFGR_VidOvf; /* clear overflow status */
567 btwrite(reg, ZR36057_VSSFGR);
568
569 /* Set overlay clipping */
570 if (zr->overlay_settings.clipcount > 0)
571 btor(ZR36057_OCR_OvlEnable, ZR36057_OCR);
572
573 /* ... and switch it on */
574 btor(ZR36057_VDCR_VidEn, ZR36057_VDCR);
575 } else {
576 /* Switch it off */
577 btand(~ZR36057_VDCR_VidEn, ZR36057_VDCR);
578 }
579}
580
581/*
582 * The overlay mask has one bit for each pixel on a scan line,
583 * and the maximum window size is BUZ_MAX_WIDTH * BUZ_MAX_HEIGHT pixels.
584 */
585
586void
587write_overlay_mask (struct file *file,
588 struct video_clip *vp,
589 int count)
590{
591 struct zoran_fh *fh = file->private_data;
592 struct zoran *zr = fh->zr;
593 unsigned mask_line_size = (BUZ_MAX_WIDTH + 31) / 32;
594 u32 *mask;
595 int x, y, width, height;
596 unsigned i, j, k;
597 u32 reg;
598
599 /* fill mask with one bits */
600 memset(fh->overlay_mask, ~0, mask_line_size * 4 * BUZ_MAX_HEIGHT);
601 reg = 0;
602
603 for (i = 0; i < count; ++i) {
604 /* pick up local copy of clip */
605 x = vp[i].x;
606 y = vp[i].y;
607 width = vp[i].width;
608 height = vp[i].height;
609
610 /* trim clips that extend beyond the window */
611 if (x < 0) {
612 width += x;
613 x = 0;
614 }
615 if (y < 0) {
616 height += y;
617 y = 0;
618 }
619 if (x + width > fh->overlay_settings.width) {
620 width = fh->overlay_settings.width - x;
621 }
622 if (y + height > fh->overlay_settings.height) {
623 height = fh->overlay_settings.height - y;
624 }
625
626 /* ignore degenerate clips */
627 if (height <= 0) {
628 continue;
629 }
630 if (width <= 0) {
631 continue;
632 }
633
634 /* apply clip for each scan line */
635 for (j = 0; j < height; ++j) {
636 /* reset bit for each pixel */
637 /* this can be optimized later if need be */
638 mask = fh->overlay_mask + (y + j) * mask_line_size;
639 for (k = 0; k < width; ++k) {
640 mask[(x + k) / 32] &=
641 ~((u32) 1 << (x + k) % 32);
642 }
643 }
644 }
645}
646
647/* Enable/Disable uncompressed memory grabbing of the 36057 */
648
649void
650zr36057_set_memgrab (struct zoran *zr,
651 int mode)
652{
653 if (mode) {
654 if (btread(ZR36057_VSSFGR) &
655 (ZR36057_VSSFGR_SnapShot | ZR36057_VSSFGR_FrameGrab))
656 dprintk(1,
657 KERN_WARNING
658 "%s: zr36057_set_memgrab(1) with SnapShot or FrameGrab on!?\n",
659 ZR_DEVNAME(zr));
660
661 /* switch on VSync interrupts */
662 btwrite(IRQ_MASK, ZR36057_ISR); // Clear Interrupts
663 btor(zr->card.vsync_int, ZR36057_ICR); // SW
664
665 /* enable SnapShot */
666 btor(ZR36057_VSSFGR_SnapShot, ZR36057_VSSFGR);
667
668 /* Set zr36057 video front end and enable video */
669 zr36057_set_vfe(zr, zr->v4l_settings.width,
670 zr->v4l_settings.height,
671 zr->v4l_settings.format);
672
673 zr->v4l_memgrab_active = 1;
674 } else {
675 zr->v4l_memgrab_active = 0;
676
677 /* switch off VSync interrupts */
678 btand(~zr->card.vsync_int, ZR36057_ICR); // SW
679
680 /* reenable grabbing to screen if it was running */
681 if (zr->v4l_overlay_active) {
682 zr36057_overlay(zr, 1);
683 } else {
684 btand(~ZR36057_VDCR_VidEn, ZR36057_VDCR);
685 btand(~ZR36057_VSSFGR_SnapShot, ZR36057_VSSFGR);
686 }
687 }
688}
689
690int
691wait_grab_pending (struct zoran *zr)
692{
693 unsigned long flags;
694
695 /* wait until all pending grabs are finished */
696
697 if (!zr->v4l_memgrab_active)
698 return 0;
699
700 wait_event_interruptible(zr->v4l_capq,
701 (zr->v4l_pend_tail == zr->v4l_pend_head));
702 if (signal_pending(current))
703 return -ERESTARTSYS;
704
705 spin_lock_irqsave(&zr->spinlock, flags);
706 zr36057_set_memgrab(zr, 0);
707 spin_unlock_irqrestore(&zr->spinlock, flags);
708
709 return 0;
710}
711
712/*****************************************************************************
713 * *
714 * Set up the Buz-specific MJPEG part *
715 * *
716 *****************************************************************************/
717
718static inline void
719set_frame (struct zoran *zr,
720 int val)
721{
722 GPIO(zr, zr->card.gpio[GPIO_JPEG_FRAME], val);
723}
724
725static void
726set_videobus_dir (struct zoran *zr,
727 int val)
728{
729 switch (zr->card.type) {
730 case LML33:
731 case LML33R10:
732 if (lml33dpath == 0)
733 GPIO(zr, 5, val);
734 else
735 GPIO(zr, 5, 1);
736 break;
737 default:
738 GPIO(zr, zr->card.gpio[GPIO_VID_DIR],
739 zr->card.gpio_pol[GPIO_VID_DIR] ? !val : val);
740 break;
741 }
742}
743
744static void
745init_jpeg_queue (struct zoran *zr)
746{
747 int i;
748
749 /* re-initialize DMA ring stuff */
750 zr->jpg_que_head = 0;
751 zr->jpg_dma_head = 0;
752 zr->jpg_dma_tail = 0;
753 zr->jpg_que_tail = 0;
754 zr->jpg_seq_num = 0;
755 zr->JPEG_error = 0;
756 zr->num_errors = 0;
757 zr->jpg_err_seq = 0;
758 zr->jpg_err_shift = 0;
759 zr->jpg_queued_num = 0;
760 for (i = 0; i < zr->jpg_buffers.num_buffers; i++) {
761 zr->jpg_buffers.buffer[i].state = BUZ_STATE_USER; /* nothing going on */
762 }
763 for (i = 0; i < BUZ_NUM_STAT_COM; i++) {
764 zr->stat_com[i] = cpu_to_le32(1); /* mark as unavailable to zr36057 */
765 }
766}
767
768static void
769zr36057_set_jpg (struct zoran *zr,
770 enum zoran_codec_mode mode)
771{
772 struct tvnorm *tvn;
773 u32 reg;
774
775 tvn = zr->timing;
776
777 /* assert P_Reset, disable code transfer, deassert Active */
778 btwrite(0, ZR36057_JPC);
779
780 /* MJPEG compression mode */
781 switch (mode) {
782
783 case BUZ_MODE_MOTION_COMPRESS:
784 default:
785 reg = ZR36057_JMC_MJPGCmpMode;
786 break;
787
788 case BUZ_MODE_MOTION_DECOMPRESS:
789 reg = ZR36057_JMC_MJPGExpMode;
790 reg |= ZR36057_JMC_SyncMstr;
791 /* RJ: The following is experimental - improves the output to screen */
792 //if(zr->jpg_settings.VFIFO_FB) reg |= ZR36057_JMC_VFIFO_FB; // No, it doesn't. SM
793 break;
794
795 case BUZ_MODE_STILL_COMPRESS:
796 reg = ZR36057_JMC_JPGCmpMode;
797 break;
798
799 case BUZ_MODE_STILL_DECOMPRESS:
800 reg = ZR36057_JMC_JPGExpMode;
801 break;
802
803 }
804 reg |= ZR36057_JMC_JPG;
805 if (zr->jpg_settings.field_per_buff == 1)
806 reg |= ZR36057_JMC_Fld_per_buff;
807 btwrite(reg, ZR36057_JMC);
808
809 /* vertical */
810 btor(ZR36057_VFEVCR_VSPol, ZR36057_VFEVCR);
811 reg = (6 << ZR36057_VSP_VsyncSize) |
812 (tvn->Ht << ZR36057_VSP_FrmTot);
813 btwrite(reg, ZR36057_VSP);
814 reg = ((zr->jpg_settings.img_y + tvn->VStart) << ZR36057_FVAP_NAY) |
815 (zr->jpg_settings.img_height << ZR36057_FVAP_PAY);
816 btwrite(reg, ZR36057_FVAP);
817
818 /* horizontal */
819 if (zr->card.vfe_pol.hsync_pol)
820 btor(ZR36057_VFEHCR_HSPol, ZR36057_VFEHCR);
821 else
822 btand(~ZR36057_VFEHCR_HSPol, ZR36057_VFEHCR);
823 reg = ((tvn->HSyncStart) << ZR36057_HSP_HsyncStart) |
824 (tvn->Wt << ZR36057_HSP_LineTot);
825 btwrite(reg, ZR36057_HSP);
826 reg = ((zr->jpg_settings.img_x +
827 tvn->HStart + 4) << ZR36057_FHAP_NAX) |
828 (zr->jpg_settings.img_width << ZR36057_FHAP_PAX);
829 btwrite(reg, ZR36057_FHAP);
830
831 /* field process parameters */
832 if (zr->jpg_settings.odd_even)
833 reg = ZR36057_FPP_Odd_Even;
834 else
835 reg = 0;
836
837 btwrite(reg, ZR36057_FPP);
838
839 /* Set proper VCLK Polarity, else colors will be wrong during playback */
840 //btor(ZR36057_VFESPFR_VCLKPol, ZR36057_VFESPFR);
841
842 /* code base address */
843 reg = virt_to_bus(zr->stat_com);
844 btwrite(reg, ZR36057_JCBA);
845
846 /* FIFO threshold (FIFO is 160. double words) */
847 /* NOTE: decimal values here */
848 switch (mode) {
849
850 case BUZ_MODE_STILL_COMPRESS:
851 case BUZ_MODE_MOTION_COMPRESS:
852 if (zr->card.type != BUZ)
853 reg = 140;
854 else
855 reg = 60;
856 break;
857
858 case BUZ_MODE_STILL_DECOMPRESS:
859 case BUZ_MODE_MOTION_DECOMPRESS:
860 reg = 20;
861 break;
862
863 default:
864 reg = 80;
865 break;
866
867 }
868 btwrite(reg, ZR36057_JCFT);
869 zr36057_adjust_vfe(zr, mode);
870
871}
872
873void
874print_interrupts (struct zoran *zr)
875{
876 int res, noerr = 0;
877
878 printk(KERN_INFO "%s: interrupts received:", ZR_DEVNAME(zr));
879 if ((res = zr->field_counter) < -1 || res > 1) {
880 printk(" FD:%d", res);
881 }
882 if ((res = zr->intr_counter_GIRQ1) != 0) {
883 printk(" GIRQ1:%d", res);
884 noerr++;
885 }
886 if ((res = zr->intr_counter_GIRQ0) != 0) {
887 printk(" GIRQ0:%d", res);
888 noerr++;
889 }
890 if ((res = zr->intr_counter_CodRepIRQ) != 0) {
891 printk(" CodRepIRQ:%d", res);
892 noerr++;
893 }
894 if ((res = zr->intr_counter_JPEGRepIRQ) != 0) {
895 printk(" JPEGRepIRQ:%d", res);
896 noerr++;
897 }
898 if (zr->JPEG_max_missed) {
899 printk(" JPEG delays: max=%d min=%d", zr->JPEG_max_missed,
900 zr->JPEG_min_missed);
901 }
902 if (zr->END_event_missed) {
903 printk(" ENDs missed: %d", zr->END_event_missed);
904 }
905 //if (zr->jpg_queued_num) {
906 printk(" queue_state=%ld/%ld/%ld/%ld", zr->jpg_que_tail,
907 zr->jpg_dma_tail, zr->jpg_dma_head, zr->jpg_que_head);
908 //}
909 if (!noerr) {
910 printk(": no interrupts detected.");
911 }
912 printk("\n");
913}
914
915void
916clear_interrupt_counters (struct zoran *zr)
917{
918 zr->intr_counter_GIRQ1 = 0;
919 zr->intr_counter_GIRQ0 = 0;
920 zr->intr_counter_CodRepIRQ = 0;
921 zr->intr_counter_JPEGRepIRQ = 0;
922 zr->field_counter = 0;
923 zr->IRQ1_in = 0;
924 zr->IRQ1_out = 0;
925 zr->JPEG_in = 0;
926 zr->JPEG_out = 0;
927 zr->JPEG_0 = 0;
928 zr->JPEG_1 = 0;
929 zr->END_event_missed = 0;
930 zr->JPEG_missed = 0;
931 zr->JPEG_max_missed = 0;
932 zr->JPEG_min_missed = 0x7fffffff;
933}
934
935static u32
936count_reset_interrupt (struct zoran *zr)
937{
938 u32 isr;
939
940 if ((isr = btread(ZR36057_ISR) & 0x78000000)) {
941 if (isr & ZR36057_ISR_GIRQ1) {
942 btwrite(ZR36057_ISR_GIRQ1, ZR36057_ISR);
943 zr->intr_counter_GIRQ1++;
944 }
945 if (isr & ZR36057_ISR_GIRQ0) {
946 btwrite(ZR36057_ISR_GIRQ0, ZR36057_ISR);
947 zr->intr_counter_GIRQ0++;
948 }
949 if (isr & ZR36057_ISR_CodRepIRQ) {
950 btwrite(ZR36057_ISR_CodRepIRQ, ZR36057_ISR);
951 zr->intr_counter_CodRepIRQ++;
952 }
953 if (isr & ZR36057_ISR_JPEGRepIRQ) {
954 btwrite(ZR36057_ISR_JPEGRepIRQ, ZR36057_ISR);
955 zr->intr_counter_JPEGRepIRQ++;
956 }
957 }
958 return isr;
959}
960
961/* hack */
962extern void zr36016_write (struct videocodec *codec,
963 u16 reg,
964 u32 val);
965
966void
967jpeg_start (struct zoran *zr)
968{
969 int reg;
970
971 zr->frame_num = 0;
972
973 /* deassert P_reset, disable code transfer, deassert Active */
974 btwrite(ZR36057_JPC_P_Reset, ZR36057_JPC);
975 /* stop flushing the internal code buffer */
976 btand(~ZR36057_MCTCR_CFlush, ZR36057_MCTCR);
977 /* enable code transfer */
978 btor(ZR36057_JPC_CodTrnsEn, ZR36057_JPC);
979
980 /* clear IRQs */
981 btwrite(IRQ_MASK, ZR36057_ISR);
982 /* enable the JPEG IRQs */
983 btwrite(zr->card.jpeg_int |
984 ZR36057_ICR_JPEGRepIRQ |
985 ZR36057_ICR_IntPinEn,
986 ZR36057_ICR);
987
988 set_frame(zr, 0); // \FRAME
989
990 /* set the JPEG codec guest ID */
991 reg = (zr->card.gpcs[1] << ZR36057_JCGI_JPEGuestID) |
992 (0 << ZR36057_JCGI_JPEGuestReg);
993 btwrite(reg, ZR36057_JCGI);
994
995 if (zr->card.video_vfe == CODEC_TYPE_ZR36016 &&
996 zr->card.video_codec == CODEC_TYPE_ZR36050) {
997 /* Enable processing on the ZR36016 */
998 if (zr->vfe)
999 zr36016_write(zr->vfe, 0, 1);
1000
1001 /* load the address of the GO register in the ZR36050 latch */
1002 post_office_write(zr, 0, 0, 0);
1003 }
1004
1005 /* assert Active */
1006 btor(ZR36057_JPC_Active, ZR36057_JPC);
1007
1008 /* enable the Go generation */
1009 btor(ZR36057_JMC_Go_en, ZR36057_JMC);
1010 udelay(30);
1011
1012 set_frame(zr, 1); // /FRAME
1013
1014 dprintk(3, KERN_DEBUG "%s: jpeg_start\n", ZR_DEVNAME(zr));
1015}
1016
1017void
1018zr36057_enable_jpg (struct zoran *zr,
1019 enum zoran_codec_mode mode)
1020{
1021 static int zero = 0;
1022 static int one = 1;
1023 struct vfe_settings cap;
1024 int field_size =
1025 zr->jpg_buffers.buffer_size / zr->jpg_settings.field_per_buff;
1026
1027 zr->codec_mode = mode;
1028
1029 cap.x = zr->jpg_settings.img_x;
1030 cap.y = zr->jpg_settings.img_y;
1031 cap.width = zr->jpg_settings.img_width;
1032 cap.height = zr->jpg_settings.img_height;
1033 cap.decimation =
1034 zr->jpg_settings.HorDcm | (zr->jpg_settings.VerDcm << 8);
1035 cap.quality = zr->jpg_settings.jpg_comp.quality;
1036
1037 switch (mode) {
1038
1039 case BUZ_MODE_MOTION_COMPRESS: {
1040 struct jpeg_app_marker app;
1041 struct jpeg_com_marker com;
1042
1043 /* In motion compress mode, the decoder output must be enabled, and
1044 * the video bus direction set to input.
1045 */
1046 set_videobus_dir(zr, 0);
1047 decoder_command(zr, DECODER_ENABLE_OUTPUT, &one);
1048 encoder_command(zr, ENCODER_SET_INPUT, &zero);
1049
1050 /* Take the JPEG codec and the VFE out of sleep */
1051 jpeg_codec_sleep(zr, 0);
1052
1053 /* set JPEG app/com marker */
1054 app.appn = zr->jpg_settings.jpg_comp.APPn;
1055 app.len = zr->jpg_settings.jpg_comp.APP_len;
1056 memcpy(app.data, zr->jpg_settings.jpg_comp.APP_data, 60);
1057 zr->codec->control(zr->codec, CODEC_S_JPEG_APP_DATA,
1058 sizeof(struct jpeg_app_marker), &app);
1059
1060 com.len = zr->jpg_settings.jpg_comp.COM_len;
1061 memcpy(com.data, zr->jpg_settings.jpg_comp.COM_data, 60);
1062 zr->codec->control(zr->codec, CODEC_S_JPEG_COM_DATA,
1063 sizeof(struct jpeg_com_marker), &com);
1064
1065 /* Setup the JPEG codec */
1066 zr->codec->control(zr->codec, CODEC_S_JPEG_TDS_BYTE,
1067 sizeof(int), &field_size);
1068 zr->codec->set_video(zr->codec, zr->timing, &cap,
1069 &zr->card.vfe_pol);
1070 zr->codec->set_mode(zr->codec, CODEC_DO_COMPRESSION);
1071
1072 /* Setup the VFE */
1073 if (zr->vfe) {
1074 zr->vfe->control(zr->vfe, CODEC_S_JPEG_TDS_BYTE,
1075 sizeof(int), &field_size);
1076 zr->vfe->set_video(zr->vfe, zr->timing, &cap,
1077 &zr->card.vfe_pol);
1078 zr->vfe->set_mode(zr->vfe, CODEC_DO_COMPRESSION);
1079 }
1080
1081 init_jpeg_queue(zr);
1082 zr36057_set_jpg(zr, mode); // \P_Reset, ... Video param, FIFO
1083
1084 clear_interrupt_counters(zr);
1085 dprintk(2, KERN_INFO "%s: enable_jpg(MOTION_COMPRESS)\n",
1086 ZR_DEVNAME(zr));
1087 break;
1088 }
1089
1090 case BUZ_MODE_MOTION_DECOMPRESS:
1091 /* In motion decompression mode, the decoder output must be disabled, and
1092 * the video bus direction set to output.
1093 */
1094 decoder_command(zr, DECODER_ENABLE_OUTPUT, &zero);
1095 set_videobus_dir(zr, 1);
1096 encoder_command(zr, ENCODER_SET_INPUT, &one);
1097
1098 /* Take the JPEG codec and the VFE out of sleep */
1099 jpeg_codec_sleep(zr, 0);
1100 /* Setup the VFE */
1101 if (zr->vfe) {
1102 zr->vfe->set_video(zr->vfe, zr->timing, &cap,
1103 &zr->card.vfe_pol);
1104 zr->vfe->set_mode(zr->vfe, CODEC_DO_EXPANSION);
1105 }
1106 /* Setup the JPEG codec */
1107 zr->codec->set_video(zr->codec, zr->timing, &cap,
1108 &zr->card.vfe_pol);
1109 zr->codec->set_mode(zr->codec, CODEC_DO_EXPANSION);
1110
1111 init_jpeg_queue(zr);
1112 zr36057_set_jpg(zr, mode); // \P_Reset, ... Video param, FIFO
1113
1114 clear_interrupt_counters(zr);
1115 dprintk(2, KERN_INFO "%s: enable_jpg(MOTION_DECOMPRESS)\n",
1116 ZR_DEVNAME(zr));
1117 break;
1118
1119 case BUZ_MODE_IDLE:
1120 default:
1121 /* shut down processing */
1122 btand(~(zr->card.jpeg_int | ZR36057_ICR_JPEGRepIRQ),
1123 ZR36057_ICR);
1124 btwrite(zr->card.jpeg_int | ZR36057_ICR_JPEGRepIRQ,
1125 ZR36057_ISR);
1126 btand(~ZR36057_JMC_Go_en, ZR36057_JMC); // \Go_en
1127
1128 msleep(50);
1129
1130 set_videobus_dir(zr, 0);
1131 set_frame(zr, 1); // /FRAME
1132 btor(ZR36057_MCTCR_CFlush, ZR36057_MCTCR); // /CFlush
1133 btwrite(0, ZR36057_JPC); // \P_Reset,\CodTrnsEn,\Active
1134 btand(~ZR36057_JMC_VFIFO_FB, ZR36057_JMC);
1135 btand(~ZR36057_JMC_SyncMstr, ZR36057_JMC);
1136 jpeg_codec_reset(zr);
1137 jpeg_codec_sleep(zr, 1);
1138 zr36057_adjust_vfe(zr, mode);
1139
1140 decoder_command(zr, DECODER_ENABLE_OUTPUT, &one);
1141 encoder_command(zr, ENCODER_SET_INPUT, &zero);
1142
1143 dprintk(2, KERN_INFO "%s: enable_jpg(IDLE)\n", ZR_DEVNAME(zr));
1144 break;
1145
1146 }
1147}
1148
1149/* when this is called the spinlock must be held */
1150void
1151zoran_feed_stat_com (struct zoran *zr)
1152{
1153 /* move frames from pending queue to DMA */
1154
1155 int frame, i, max_stat_com;
1156
1157 max_stat_com =
1158 (zr->jpg_settings.TmpDcm ==
1159 1) ? BUZ_NUM_STAT_COM : (BUZ_NUM_STAT_COM >> 1);
1160
1161 while ((zr->jpg_dma_head - zr->jpg_dma_tail) < max_stat_com &&
1162 zr->jpg_dma_head < zr->jpg_que_head) {
1163
1164 frame = zr->jpg_pend[zr->jpg_dma_head & BUZ_MASK_FRAME];
1165 if (zr->jpg_settings.TmpDcm == 1) {
1166 /* fill 1 stat_com entry */
1167 i = (zr->jpg_dma_head -
1168 zr->jpg_err_shift) & BUZ_MASK_STAT_COM;
1169 if (!(zr->stat_com[i] & cpu_to_le32(1)))
1170 break;
1171 zr->stat_com[i] =
1172 cpu_to_le32(zr->jpg_buffers.buffer[frame].frag_tab_bus);
1173 } else {
1174 /* fill 2 stat_com entries */
1175 i = ((zr->jpg_dma_head -
1176 zr->jpg_err_shift) & 1) * 2;
1177 if (!(zr->stat_com[i] & cpu_to_le32(1)))
1178 break;
1179 zr->stat_com[i] =
1180 cpu_to_le32(zr->jpg_buffers.buffer[frame].frag_tab_bus);
1181 zr->stat_com[i + 1] =
1182 cpu_to_le32(zr->jpg_buffers.buffer[frame].frag_tab_bus);
1183 }
1184 zr->jpg_buffers.buffer[frame].state = BUZ_STATE_DMA;
1185 zr->jpg_dma_head++;
1186
1187 }
1188 if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS)
1189 zr->jpg_queued_num++;
1190}
1191
1192/* when this is called the spinlock must be held */
1193static void
1194zoran_reap_stat_com (struct zoran *zr)
1195{
1196 /* move frames from DMA queue to done queue */
1197
1198 int i;
1199 u32 stat_com;
1200 unsigned int seq;
1201 unsigned int dif;
1202 struct zoran_jpg_buffer *buffer;
1203 int frame;
1204
1205 /* In motion decompress we don't have a hardware frame counter,
1206 * we just count the interrupts here */
1207
1208 if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS) {
1209 zr->jpg_seq_num++;
1210 }
1211 while (zr->jpg_dma_tail < zr->jpg_dma_head) {
1212 if (zr->jpg_settings.TmpDcm == 1)
1213 i = (zr->jpg_dma_tail -
1214 zr->jpg_err_shift) & BUZ_MASK_STAT_COM;
1215 else
1216 i = ((zr->jpg_dma_tail -
1217 zr->jpg_err_shift) & 1) * 2 + 1;
1218
1219 stat_com = le32_to_cpu(zr->stat_com[i]);
1220
1221 if ((stat_com & 1) == 0) {
1222 return;
1223 }
1224 frame = zr->jpg_pend[zr->jpg_dma_tail & BUZ_MASK_FRAME];
1225 buffer = &zr->jpg_buffers.buffer[frame];
1226 do_gettimeofday(&buffer->bs.timestamp);
1227
1228 if (zr->codec_mode == BUZ_MODE_MOTION_COMPRESS) {
1229 buffer->bs.length = (stat_com & 0x7fffff) >> 1;
1230
1231 /* update sequence number with the help of the counter in stat_com */
1232
1233 seq = ((stat_com >> 24) + zr->jpg_err_seq) & 0xff;
1234 dif = (seq - zr->jpg_seq_num) & 0xff;
1235 zr->jpg_seq_num += dif;
1236 } else {
1237 buffer->bs.length = 0;
1238 }
1239 buffer->bs.seq =
1240 zr->jpg_settings.TmpDcm ==
1241 2 ? (zr->jpg_seq_num >> 1) : zr->jpg_seq_num;
1242 buffer->state = BUZ_STATE_DONE;
1243
1244 zr->jpg_dma_tail++;
1245 }
1246}
1247
1248static void
1249error_handler (struct zoran *zr,
1250 u32 astat,
1251 u32 stat)
1252{
1253 /* This is JPEG error handling part */
1254 if ((zr->codec_mode != BUZ_MODE_MOTION_COMPRESS) &&
1255 (zr->codec_mode != BUZ_MODE_MOTION_DECOMPRESS)) {
1256 //dprintk(1, KERN_ERR "%s: Internal error: error handling request in mode %d\n", ZR_DEVNAME(zr), zr->codec_mode);
1257 return;
1258 }
1259
1260 if ((stat & 1) == 0 &&
1261 zr->codec_mode == BUZ_MODE_MOTION_COMPRESS &&
1262 zr->jpg_dma_tail - zr->jpg_que_tail >=
1263 zr->jpg_buffers.num_buffers) {
1264 /* No free buffers... */
1265 zoran_reap_stat_com(zr);
1266 zoran_feed_stat_com(zr);
1267 wake_up_interruptible(&zr->jpg_capq);
1268 zr->JPEG_missed = 0;
1269 return;
1270 }
1271
1272 if (zr->JPEG_error != 1) {
1273 /*
1274 * First entry: error just happened during normal operation
1275 *
1276 * In BUZ_MODE_MOTION_COMPRESS:
1277 *
1278 * Possible glitch in TV signal. In this case we should
1279 * stop the codec and wait for good quality signal before
1280 * restarting it to avoid further problems
1281 *
1282 * In BUZ_MODE_MOTION_DECOMPRESS:
1283 *
1284 * Bad JPEG frame: we have to mark it as processed (codec crashed
1285 * and was not able to do it itself), and to remove it from queue.
1286 */
1287 btand(~ZR36057_JMC_Go_en, ZR36057_JMC);
1288 udelay(1);
1289 stat = stat | (post_office_read(zr, 7, 0) & 3) << 8;
1290 btwrite(0, ZR36057_JPC);
1291 btor(ZR36057_MCTCR_CFlush, ZR36057_MCTCR);
1292 jpeg_codec_reset(zr);
1293 jpeg_codec_sleep(zr, 1);
1294 zr->JPEG_error = 1;
1295 zr->num_errors++;
1296
1297 /* Report error */
1298 if (*zr_debug > 1 && zr->num_errors <= 8) {
1299 long frame;
1300 frame =
1301 zr->jpg_pend[zr->jpg_dma_tail & BUZ_MASK_FRAME];
1302 printk(KERN_ERR
1303 "%s: JPEG error stat=0x%08x(0x%08x) queue_state=%ld/%ld/%ld/%ld seq=%ld frame=%ld. Codec stopped. ",
1304 ZR_DEVNAME(zr), stat, zr->last_isr,
1305 zr->jpg_que_tail, zr->jpg_dma_tail,
1306 zr->jpg_dma_head, zr->jpg_que_head,
1307 zr->jpg_seq_num, frame);
1308 printk("stat_com frames:");
1309 {
1310 int i, j;
1311 for (j = 0; j < BUZ_NUM_STAT_COM; j++) {
1312 for (i = 0;
1313 i < zr->jpg_buffers.num_buffers;
1314 i++) {
1315 if (le32_to_cpu(zr->stat_com[j]) ==
1316 zr->jpg_buffers.
1317 buffer[i].
1318 frag_tab_bus) {
1319 printk("% d->%d",
1320 j, i);
1321 }
1322 }
1323 }
1324 printk("\n");
1325 }
1326 }
1327 /* Find an entry in stat_com and rotate contents */
1328 {
1329 int i;
1330
1331 if (zr->jpg_settings.TmpDcm == 1)
1332 i = (zr->jpg_dma_tail -
1333 zr->jpg_err_shift) & BUZ_MASK_STAT_COM;
1334 else
1335 i = ((zr->jpg_dma_tail -
1336 zr->jpg_err_shift) & 1) * 2;
1337 if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS) {
1338 /* Mimic zr36067 operation */
1339 zr->stat_com[i] |= cpu_to_le32(1);
1340 if (zr->jpg_settings.TmpDcm != 1)
1341 zr->stat_com[i + 1] |= cpu_to_le32(1);
1342 /* Refill */
1343 zoran_reap_stat_com(zr);
1344 zoran_feed_stat_com(zr);
1345 wake_up_interruptible(&zr->jpg_capq);
1346 /* Find an entry in stat_com again after refill */
1347 if (zr->jpg_settings.TmpDcm == 1)
1348 i = (zr->jpg_dma_tail -
1349 zr->jpg_err_shift) &
1350 BUZ_MASK_STAT_COM;
1351 else
1352 i = ((zr->jpg_dma_tail -
1353 zr->jpg_err_shift) & 1) * 2;
1354 }
1355 if (i) {
1356 /* Rotate stat_comm entries to make current entry first */
1357 int j;
1358 u32 bus_addr[BUZ_NUM_STAT_COM];
1359
1360 /* Here we are copying the stat_com array, which
1361 * is already in little endian format, so
1362 * no endian conversions here
1363 */
1364 memcpy(bus_addr, zr->stat_com,
1365 sizeof(bus_addr));
1366 for (j = 0; j < BUZ_NUM_STAT_COM; j++) {
1367 zr->stat_com[j] =
1368 bus_addr[(i + j) &
1369 BUZ_MASK_STAT_COM];
1370
1371 }
1372 zr->jpg_err_shift += i;
1373 zr->jpg_err_shift &= BUZ_MASK_STAT_COM;
1374 }
1375 if (zr->codec_mode == BUZ_MODE_MOTION_COMPRESS)
1376 zr->jpg_err_seq = zr->jpg_seq_num; /* + 1; */
1377 }
1378 }
1379
1380 /* Now the stat_comm buffer is ready for restart */
1381 do {
1382 int status, mode;
1383
1384 if (zr->codec_mode == BUZ_MODE_MOTION_COMPRESS) {
1385 decoder_command(zr, DECODER_GET_STATUS, &status);
1386 mode = CODEC_DO_COMPRESSION;
1387 } else {
1388 status = 0;
1389 mode = CODEC_DO_EXPANSION;
1390 }
1391 if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS ||
1392 (status & DECODER_STATUS_GOOD)) {
1393 /********** RESTART code *************/
1394 jpeg_codec_reset(zr);
1395 zr->codec->set_mode(zr->codec, mode);
1396 zr36057_set_jpg(zr, zr->codec_mode);
1397 jpeg_start(zr);
1398
1399 if (zr->num_errors <= 8)
1400 dprintk(2, KERN_INFO "%s: Restart\n",
1401 ZR_DEVNAME(zr));
1402
1403 zr->JPEG_missed = 0;
1404 zr->JPEG_error = 2;
1405 /********** End RESTART code ***********/
1406 }
1407 } while (0);
1408}
1409
1410irqreturn_t
1411zoran_irq (int irq,
1412 void *dev_id,
1413 struct pt_regs *regs)
1414{
1415 u32 stat, astat;
1416 int count;
1417 struct zoran *zr;
1418 unsigned long flags;
1419
1420 zr = (struct zoran *) dev_id;
1421 count = 0;
1422
1423 if (zr->testing) {
1424 /* Testing interrupts */
1425 spin_lock_irqsave(&zr->spinlock, flags);
1426 while ((stat = count_reset_interrupt(zr))) {
1427 if (count++ > 100) {
1428 btand(~ZR36057_ICR_IntPinEn, ZR36057_ICR);
1429 dprintk(1,
1430 KERN_ERR
1431 "%s: IRQ lockup while testing, isr=0x%08x, cleared int mask\n",
1432 ZR_DEVNAME(zr), stat);
1433 wake_up_interruptible(&zr->test_q);
1434 }
1435 }
1436 zr->last_isr = stat;
1437 spin_unlock_irqrestore(&zr->spinlock, flags);
1438 return IRQ_HANDLED;
1439 }
1440
1441 spin_lock_irqsave(&zr->spinlock, flags);
1442 while (1) {
1443 /* get/clear interrupt status bits */
1444 stat = count_reset_interrupt(zr);
1445 astat = stat & IRQ_MASK;
1446 if (!astat) {
1447 break;
1448 }
1449 dprintk(4,
1450 KERN_DEBUG
1451 "zoran_irq: astat: 0x%08x, mask: 0x%08x\n",
1452 astat, btread(ZR36057_ICR));
1453 if (astat & zr->card.vsync_int) { // SW
1454
1455 if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS ||
1456 zr->codec_mode == BUZ_MODE_MOTION_COMPRESS) {
1457 /* count missed interrupts */
1458 zr->JPEG_missed++;
1459 }
1460 //post_office_read(zr,1,0);
1461 /* Interrupts may still happen when
1462 * zr->v4l_memgrab_active is switched off.
1463 * We simply ignore them */
1464
1465 if (zr->v4l_memgrab_active) {
1466
1467 /* A lot more checks should be here ... */
1468 if ((btread(ZR36057_VSSFGR) &
1469 ZR36057_VSSFGR_SnapShot) == 0)
1470 dprintk(1,
1471 KERN_WARNING
1472 "%s: BuzIRQ with SnapShot off ???\n",
1473 ZR_DEVNAME(zr));
1474
1475 if (zr->v4l_grab_frame != NO_GRAB_ACTIVE) {
1476 /* There is a grab on a frame going on, check if it has finished */
1477
1478 if ((btread(ZR36057_VSSFGR) &
1479 ZR36057_VSSFGR_FrameGrab) ==
1480 0) {
1481 /* it is finished, notify the user */
1482
1483 zr->v4l_buffers.buffer[zr->v4l_grab_frame].state = BUZ_STATE_DONE;
1484 zr->v4l_buffers.buffer[zr->v4l_grab_frame].bs.seq = zr->v4l_grab_seq;
1485 do_gettimeofday(&zr->v4l_buffers.buffer[zr->v4l_grab_frame].bs.timestamp);
1486 zr->v4l_grab_frame = NO_GRAB_ACTIVE;
1487 zr->v4l_pend_tail++;
1488 }
1489 }
1490
1491 if (zr->v4l_grab_frame == NO_GRAB_ACTIVE)
1492 wake_up_interruptible(&zr->v4l_capq);
1493
1494 /* Check if there is another grab queued */
1495
1496 if (zr->v4l_grab_frame == NO_GRAB_ACTIVE &&
1497 zr->v4l_pend_tail != zr->v4l_pend_head) {
1498
1499 int frame = zr->v4l_pend[zr->v4l_pend_tail &
1500 V4L_MASK_FRAME];
1501 u32 reg;
1502
1503 zr->v4l_grab_frame = frame;
1504
1505 /* Set zr36057 video front end and enable video */
1506
1507 /* Buffer address */
1508
1509 reg =
1510 zr->v4l_buffers.buffer[frame].
1511 fbuffer_bus;
1512 btwrite(reg, ZR36057_VDTR);
1513 if (zr->v4l_settings.height >
1514 BUZ_MAX_HEIGHT / 2)
1515 reg +=
1516 zr->v4l_settings.
1517 bytesperline;
1518 btwrite(reg, ZR36057_VDBR);
1519
1520 /* video stride, status, and frame grab register */
1521 reg = 0;
1522 if (zr->v4l_settings.height >
1523 BUZ_MAX_HEIGHT / 2)
1524 reg +=
1525 zr->v4l_settings.
1526 bytesperline;
1527 reg =
1528 (reg <<
1529 ZR36057_VSSFGR_DispStride);
1530 reg |= ZR36057_VSSFGR_VidOvf;
1531 reg |= ZR36057_VSSFGR_SnapShot;
1532 reg |= ZR36057_VSSFGR_FrameGrab;
1533 btwrite(reg, ZR36057_VSSFGR);
1534
1535 btor(ZR36057_VDCR_VidEn,
1536 ZR36057_VDCR);
1537 }
1538 }
1539
1540 /* even if we don't grab, we do want to increment
1541 * the sequence counter to see lost frames */
1542 zr->v4l_grab_seq++;
1543 }
1544#if (IRQ_MASK & ZR36057_ISR_CodRepIRQ)
1545 if (astat & ZR36057_ISR_CodRepIRQ) {
1546 zr->intr_counter_CodRepIRQ++;
1547 IDEBUG(printk
1548 (KERN_DEBUG "%s: ZR36057_ISR_CodRepIRQ\n",
1549 ZR_DEVNAME(zr)));
1550 btand(~ZR36057_ICR_CodRepIRQ, ZR36057_ICR);
1551 }
1552#endif /* (IRQ_MASK & ZR36057_ISR_CodRepIRQ) */
1553
1554#if (IRQ_MASK & ZR36057_ISR_JPEGRepIRQ)
1555 if (astat & ZR36057_ISR_JPEGRepIRQ) {
1556
1557 if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS ||
1558 zr->codec_mode == BUZ_MODE_MOTION_COMPRESS) {
1559 if (*zr_debug > 1 &&
1560 (!zr->frame_num || zr->JPEG_error)) {
1561 printk(KERN_INFO
1562 "%s: first frame ready: state=0x%08x odd_even=%d field_per_buff=%d delay=%d\n",
1563 ZR_DEVNAME(zr), stat,
1564 zr->jpg_settings.odd_even,
1565 zr->jpg_settings.
1566 field_per_buff,
1567 zr->JPEG_missed);
1568 {
1569 char sc[] = "0000";
1570 char sv[5];
1571 int i;
1572 strcpy(sv, sc);
1573 for (i = 0; i < 4; i++) {
1574 if (le32_to_cpu(zr->stat_com[i]) & 1)
1575 sv[i] = '1';
1576 }
1577 sv[4] = 0;
1578 printk(KERN_INFO
1579 "%s: stat_com=%s queue_state=%ld/%ld/%ld/%ld\n",
1580 ZR_DEVNAME(zr), sv,
1581 zr->jpg_que_tail,
1582 zr->jpg_dma_tail,
1583 zr->jpg_dma_head,
1584 zr->jpg_que_head);
1585 }
1586 } else {
1587 if (zr->JPEG_missed > zr->JPEG_max_missed) // Get statistics
1588 zr->JPEG_max_missed =
1589 zr->JPEG_missed;
1590 if (zr->JPEG_missed <
1591 zr->JPEG_min_missed)
1592 zr->JPEG_min_missed =
1593 zr->JPEG_missed;
1594 }
1595
1596 if (*zr_debug > 2 && zr->frame_num < 6) {
1597 int i;
1598 printk("%s: seq=%ld stat_com:",
1599 ZR_DEVNAME(zr), zr->jpg_seq_num);
1600 for (i = 0; i < 4; i++) {
1601 printk(" %08x",
1602 le32_to_cpu(zr->stat_com[i]));
1603 }
1604 printk("\n");
1605 }
1606 zr->frame_num++;
1607 zr->JPEG_missed = 0;
1608 zr->JPEG_error = 0;
1609 zoran_reap_stat_com(zr);
1610 zoran_feed_stat_com(zr);
1611 wake_up_interruptible(&zr->jpg_capq);
1612 } /*else {
1613 dprintk(1,
1614 KERN_ERR
1615 "%s: JPEG interrupt while not in motion (de)compress mode!\n",
1616 ZR_DEVNAME(zr));
1617 }*/
1618 }
1619#endif /* (IRQ_MASK & ZR36057_ISR_JPEGRepIRQ) */
1620
1621 /* DATERR, too many fields missed, error processing */
1622 if ((astat & zr->card.jpeg_int) ||
1623 zr->JPEG_missed > 25 ||
1624 zr->JPEG_error == 1 ||
1625 ((zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS) &&
1626 (zr->frame_num & (zr->JPEG_missed >
1627 zr->jpg_settings.field_per_buff)))) {
1628 error_handler(zr, astat, stat);
1629 }
1630
1631 count++;
1632 if (count > 10) {
1633 dprintk(2, KERN_WARNING "%s: irq loop %d\n",
1634 ZR_DEVNAME(zr), count);
1635 if (count > 20) {
1636 btand(~ZR36057_ICR_IntPinEn, ZR36057_ICR);
1637 dprintk(2,
1638 KERN_ERR
1639 "%s: IRQ lockup, cleared int mask\n",
1640 ZR_DEVNAME(zr));
1641 break;
1642 }
1643 }
1644 zr->last_isr = stat;
1645 }
1646 spin_unlock_irqrestore(&zr->spinlock, flags);
1647
1648 return IRQ_HANDLED;
1649}
1650
1651void
1652zoran_set_pci_master (struct zoran *zr,
1653 int set_master)
1654{
1655 if (set_master) {
1656 pci_set_master(zr->pci_dev);
1657 } else {
1658 u16 command;
1659
1660 pci_read_config_word(zr->pci_dev, PCI_COMMAND, &command);
1661 command &= ~PCI_COMMAND_MASTER;
1662 pci_write_config_word(zr->pci_dev, PCI_COMMAND, command);
1663 }
1664}
1665
1666void
1667zoran_init_hardware (struct zoran *zr)
1668{
1669 int j, zero = 0;
1670
1671 /* Enable bus-mastering */
1672 zoran_set_pci_master(zr, 1);
1673
1674 /* Initialize the board */
1675 if (zr->card.init) {
1676 zr->card.init(zr);
1677 }
1678
1679 j = zr->card.input[zr->input].muxsel;
1680
1681 decoder_command(zr, 0, NULL);
1682 decoder_command(zr, DECODER_SET_NORM, &zr->norm);
1683 decoder_command(zr, DECODER_SET_INPUT, &j);
1684
1685 encoder_command(zr, 0, NULL);
1686 encoder_command(zr, ENCODER_SET_NORM, &zr->norm);
1687 encoder_command(zr, ENCODER_SET_INPUT, &zero);
1688
1689 /* toggle JPEG codec sleep to sync PLL */
1690 jpeg_codec_sleep(zr, 1);
1691 jpeg_codec_sleep(zr, 0);
1692
1693 /* set individual interrupt enables (without GIRQ1)
1694 * but don't global enable until zoran_open() */
1695
1696 //btwrite(IRQ_MASK & ~ZR36057_ISR_GIRQ1, ZR36057_ICR); // SW
1697 // It looks like using only JPEGRepIRQEn is not always reliable,
1698 // may be when JPEG codec crashes it won't generate IRQ? So,
1699 /*CP*/ // btwrite(IRQ_MASK, ZR36057_ICR); // Enable Vsync interrupts too. SM WHY ? LP
1700 zr36057_init_vfe(zr);
1701
1702 zr36057_enable_jpg(zr, BUZ_MODE_IDLE);
1703
1704 btwrite(IRQ_MASK, ZR36057_ISR); // Clears interrupts
1705}
1706
1707void
1708zr36057_restart (struct zoran *zr)
1709{
1710 btwrite(0, ZR36057_SPGPPCR);
1711 mdelay(1);
1712 btor(ZR36057_SPGPPCR_SoftReset, ZR36057_SPGPPCR);
1713 mdelay(1);
1714
1715 /* assert P_Reset */
1716 btwrite(0, ZR36057_JPC);
1717 /* set up GPIO direction - all output */
1718 btwrite(ZR36057_SPGPPCR_SoftReset | 0, ZR36057_SPGPPCR);
1719
1720 /* set up GPIO pins and guest bus timing */
1721 btwrite((0x81 << 24) | 0x8888, ZR36057_GPPGCR1);
1722}
1723
1724/*
1725 * initialize video front end
1726 */
1727
1728static void
1729zr36057_init_vfe (struct zoran *zr)
1730{
1731 u32 reg;
1732
1733 reg = btread(ZR36057_VFESPFR);
1734 reg |= ZR36057_VFESPFR_LittleEndian;
1735 reg &= ~ZR36057_VFESPFR_VCLKPol;
1736 reg |= ZR36057_VFESPFR_ExtFl;
1737 reg |= ZR36057_VFESPFR_TopField;
1738 btwrite(reg, ZR36057_VFESPFR);
1739 reg = btread(ZR36057_VDCR);
1740 if (pci_pci_problems & PCIPCI_TRITON)
1741 // || zr->revision < 1) // Revision 1 has also Triton support
1742 reg &= ~ZR36057_VDCR_Triton;
1743 else
1744 reg |= ZR36057_VDCR_Triton;
1745 btwrite(reg, ZR36057_VDCR);
1746}
1747
1748/*
1749 * Interface to decoder and encoder chips using i2c bus
1750 */
1751
1752int
1753decoder_command (struct zoran *zr,
1754 int cmd,
1755 void *data)
1756{
1757 if (zr->decoder == NULL)
1758 return -EIO;
1759
1760 if (zr->card.type == LML33 &&
1761 (cmd == DECODER_SET_NORM || DECODER_SET_INPUT)) {
1762 int res;
1763
1764 // Bt819 needs to reset its FIFO buffer using #FRST pin and
1765 // LML33 card uses GPIO(7) for that.
1766 GPIO(zr, 7, 0);
1767 res = zr->decoder->driver->command(zr->decoder, cmd, data);
1768 // Pull #FRST high.
1769 GPIO(zr, 7, 1);
1770 return res;
1771 } else
1772 return zr->decoder->driver->command(zr->decoder, cmd,
1773 data);
1774}
1775
1776int
1777encoder_command (struct zoran *zr,
1778 int cmd,
1779 void *data)
1780{
1781 if (zr->encoder == NULL)
1782 return -1;
1783
1784 return zr->encoder->driver->command(zr->encoder, cmd, data);
1785}
diff --git a/drivers/media/video/zoran_device.h b/drivers/media/video/zoran_device.h
new file mode 100644
index 00000000000..f315203d710
--- /dev/null
+++ b/drivers/media/video/zoran_device.h
@@ -0,0 +1,91 @@
1/*
2 * Zoran zr36057/zr36067 PCI controller driver, for the
3 * Pinnacle/Miro DC10/DC10+/DC30/DC30+, Iomega Buz, Linux
4 * Media Labs LML33/LML33R10.
5 *
6 * This part handles card-specific data and detection
7 *
8 * Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>
9 *
10 * Currently maintained by:
11 * Ronald Bultje <rbultje@ronald.bitfreak.net>
12 * Laurent Pinchart <laurent.pinchart@skynet.be>
13 * Mailinglist <mjpeg-users@lists.sf.net>
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 */
29
30#ifndef __ZORAN_DEVICE_H__
31#define __ZORAN_DEVICE_H__
32
33/* general purpose I/O */
34extern void GPIO(struct zoran *zr,
35 int bit,
36 unsigned int value);
37
38/* codec (or actually: guest bus) access */
39extern int post_office_wait(struct zoran *zr);
40extern int post_office_write(struct zoran *zr,
41 unsigned guest,
42 unsigned reg,
43 unsigned value);
44extern int post_office_read(struct zoran *zr,
45 unsigned guest,
46 unsigned reg);
47
48extern void detect_guest_activity(struct zoran *zr);
49
50extern void jpeg_codec_sleep(struct zoran *zr,
51 int sleep);
52extern int jpeg_codec_reset(struct zoran *zr);
53
54/* zr360x7 access to raw capture */
55extern void zr36057_overlay(struct zoran *zr,
56 int on);
57extern void write_overlay_mask(struct file *file,
58 struct video_clip *vp,
59 int count);
60extern void zr36057_set_memgrab(struct zoran *zr,
61 int mode);
62extern int wait_grab_pending(struct zoran *zr);
63
64/* interrupts */
65extern void print_interrupts(struct zoran *zr);
66extern void clear_interrupt_counters(struct zoran *zr);
67extern irqreturn_t zoran_irq(int irq,
68 void *dev_id,
69 struct pt_regs *regs);
70
71/* JPEG codec access */
72extern void jpeg_start(struct zoran *zr);
73extern void zr36057_enable_jpg(struct zoran *zr,
74 enum zoran_codec_mode mode);
75extern void zoran_feed_stat_com(struct zoran *zr);
76
77/* general */
78extern void zoran_set_pci_master(struct zoran *zr,
79 int set_master);
80extern void zoran_init_hardware(struct zoran *zr);
81extern void zr36057_restart(struct zoran *zr);
82
83/* i2c */
84extern int decoder_command(struct zoran *zr,
85 int cmd,
86 void *data);
87extern int encoder_command(struct zoran *zr,
88 int cmd,
89 void *data);
90
91#endif /* __ZORAN_DEVICE_H__ */
diff --git a/drivers/media/video/zoran_driver.c b/drivers/media/video/zoran_driver.c
new file mode 100644
index 00000000000..ba838a42ec8
--- /dev/null
+++ b/drivers/media/video/zoran_driver.c
@@ -0,0 +1,4699 @@
1/*
2 * Zoran zr36057/zr36067 PCI controller driver, for the
3 * Pinnacle/Miro DC10/DC10+/DC30/DC30+, Iomega Buz, Linux
4 * Media Labs LML33/LML33R10.
5 *
6 * Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>
7 *
8 * Changes for BUZ by Wolfgang Scherr <scherr@net4you.net>
9 *
10 * Changes for DC10/DC30 by Laurent Pinchart <laurent.pinchart@skynet.be>
11 *
12 * Changes for LML33R10 by Maxim Yevtyushkin <max@linuxmedialabs.com>
13 *
14 * Changes for videodev2/v4l2 by Ronald Bultje <rbultje@ronald.bitfreak.net>
15 *
16 * Based on
17 *
18 * Miro DC10 driver
19 * Copyright (C) 1999 Wolfgang Scherr <scherr@net4you.net>
20 *
21 * Iomega Buz driver version 1.0
22 * Copyright (C) 1999 Rainer Johanni <Rainer@Johanni.de>
23 *
24 * buz.0.0.3
25 * Copyright (C) 1998 Dave Perks <dperks@ibm.net>
26 *
27 * bttv - Bt848 frame grabber driver
28 * Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
29 * & Marcus Metzler (mocm@thp.uni-koeln.de)
30 *
31 *
32 * This program is free software; you can redistribute it and/or modify
33 * it under the terms of the GNU General Public License as published by
34 * the Free Software Foundation; either version 2 of the License, or
35 * (at your option) any later version.
36 *
37 * This program is distributed in the hope that it will be useful,
38 * but WITHOUT ANY WARRANTY; without even the implied warranty of
39 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
40 * GNU General Public License for more details.
41 *
42 * You should have received a copy of the GNU General Public License
43 * along with this program; if not, write to the Free Software
44 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
45 */
46
47#include <linux/config.h>
48#include <linux/version.h>
49#include <linux/init.h>
50#include <linux/module.h>
51#include <linux/delay.h>
52#include <linux/slab.h>
53#include <linux/pci.h>
54#include <linux/vmalloc.h>
55#include <linux/wait.h>
56#include <linux/byteorder/generic.h>
57
58#include <linux/interrupt.h>
59#include <linux/i2c.h>
60#include <linux/i2c-algo-bit.h>
61
62#include <linux/spinlock.h>
63#define MAP_NR(x) virt_to_page(x)
64#define ZORAN_HARDWARE VID_HARDWARE_ZR36067
65#define ZORAN_VID_TYPE ( \
66 VID_TYPE_CAPTURE | \
67 VID_TYPE_OVERLAY | \
68 VID_TYPE_CLIPPING | \
69 VID_TYPE_FRAMERAM | \
70 VID_TYPE_SCALES | \
71 VID_TYPE_MJPEG_DECODER | \
72 VID_TYPE_MJPEG_ENCODER \
73 )
74
75#include <linux/videodev.h>
76#include "videocodec.h"
77
78#include <asm/io.h>
79#include <asm/uaccess.h>
80#include <linux/proc_fs.h>
81
82#include <linux/video_decoder.h>
83#include <linux/video_encoder.h>
84#include "zoran.h"
85#include "zoran_device.h"
86#include "zoran_card.h"
87
88#ifdef HAVE_V4L2
89 /* we declare some card type definitions here, they mean
90 * the same as the v4l1 ZORAN_VID_TYPE above, except it's v4l2 */
91#define ZORAN_V4L2_VID_FLAGS ( \
92 V4L2_CAP_STREAMING |\
93 V4L2_CAP_VIDEO_CAPTURE |\
94 V4L2_CAP_VIDEO_OUTPUT |\
95 V4L2_CAP_VIDEO_OVERLAY \
96 )
97#endif
98
99#include <asm/byteorder.h>
100
101const struct zoran_format zoran_formats[] = {
102 {
103 .name = "15-bit RGB",
104 .palette = VIDEO_PALETTE_RGB555,
105#ifdef HAVE_V4L2
106#ifdef __LITTLE_ENDIAN
107 .fourcc = V4L2_PIX_FMT_RGB555,
108#else
109 .fourcc = V4L2_PIX_FMT_RGB555X,
110#endif
111 .colorspace = V4L2_COLORSPACE_SRGB,
112#endif
113 .depth = 15,
114 .flags = ZORAN_FORMAT_CAPTURE |
115 ZORAN_FORMAT_OVERLAY,
116 }, {
117 .name = "16-bit RGB",
118 .palette = VIDEO_PALETTE_RGB565,
119#ifdef HAVE_V4L2
120#ifdef __LITTLE_ENDIAN
121 .fourcc = V4L2_PIX_FMT_RGB565,
122#else
123 .fourcc = V4L2_PIX_FMT_RGB565X,
124#endif
125 .colorspace = V4L2_COLORSPACE_SRGB,
126#endif
127 .depth = 16,
128 .flags = ZORAN_FORMAT_CAPTURE |
129 ZORAN_FORMAT_OVERLAY,
130 }, {
131 .name = "24-bit RGB",
132 .palette = VIDEO_PALETTE_RGB24,
133#ifdef HAVE_V4L2
134#ifdef __LITTLE_ENDIAN
135 .fourcc = V4L2_PIX_FMT_BGR24,
136#else
137 .fourcc = V4L2_PIX_FMT_RGB24,
138#endif
139 .colorspace = V4L2_COLORSPACE_SRGB,
140#endif
141 .depth = 24,
142 .flags = ZORAN_FORMAT_CAPTURE |
143 ZORAN_FORMAT_OVERLAY,
144 }, {
145 .name = "32-bit RGB",
146 .palette = VIDEO_PALETTE_RGB32,
147#ifdef HAVE_V4L2
148#ifdef __LITTLE_ENDIAN
149 .fourcc = V4L2_PIX_FMT_BGR32,
150#else
151 .fourcc = V4L2_PIX_FMT_RGB32,
152#endif
153 .colorspace = V4L2_COLORSPACE_SRGB,
154#endif
155 .depth = 32,
156 .flags = ZORAN_FORMAT_CAPTURE |
157 ZORAN_FORMAT_OVERLAY,
158 }, {
159 .name = "4:2:2, packed, YUYV",
160 .palette = VIDEO_PALETTE_YUV422,
161#ifdef HAVE_V4L2
162 .fourcc = V4L2_PIX_FMT_YUYV,
163 .colorspace = V4L2_COLORSPACE_SMPTE170M,
164#endif
165 .depth = 16,
166 .flags = ZORAN_FORMAT_CAPTURE |
167 ZORAN_FORMAT_OVERLAY,
168 }, {
169 .name = "Hardware-encoded Motion-JPEG",
170 .palette = -1,
171#ifdef HAVE_V4L2
172 .fourcc = V4L2_PIX_FMT_MJPEG,
173 .colorspace = V4L2_COLORSPACE_SMPTE170M,
174#endif
175 .depth = 0,
176 .flags = ZORAN_FORMAT_CAPTURE |
177 ZORAN_FORMAT_PLAYBACK |
178 ZORAN_FORMAT_COMPRESSED,
179 }
180};
181static const int zoran_num_formats =
182 (sizeof(zoran_formats) / sizeof(struct zoran_format));
183
184// RJ: Test only - want to test BUZ_USE_HIMEM even when CONFIG_BIGPHYS_AREA is defined
185#if !defined(CONFIG_BIGPHYS_AREA)
186//#undef CONFIG_BIGPHYS_AREA
187#define BUZ_USE_HIMEM
188#endif
189
190#if defined(CONFIG_BIGPHYS_AREA)
191# include <linux/bigphysarea.h>
192#endif
193
194extern int *zr_debug;
195
196#define dprintk(num, format, args...) \
197 do { \
198 if (*zr_debug >= num) \
199 printk(format, ##args); \
200 } while (0)
201
202extern int v4l_nbufs;
203extern int v4l_bufsize;
204extern int jpg_nbufs;
205extern int jpg_bufsize;
206extern int pass_through;
207
208static int lock_norm = 0; /* 1=Don't change TV standard (norm) */
209module_param(lock_norm, int, 0);
210MODULE_PARM_DESC(lock_norm, "Users can't change norm");
211
212#ifdef HAVE_V4L2
213 /* small helper function for calculating buffersizes for v4l2
214 * we calculate the nearest higher power-of-two, which
215 * will be the recommended buffersize */
216static __u32
217zoran_v4l2_calc_bufsize (struct zoran_jpg_settings *settings)
218{
219 __u8 div = settings->VerDcm * settings->HorDcm * settings->TmpDcm;
220 __u32 num = (1024 * 512) / (div);
221 __u32 result = 2;
222
223 num--;
224 while (num) {
225 num >>= 1;
226 result <<= 1;
227 }
228
229 if (result > jpg_bufsize)
230 return jpg_bufsize;
231 if (result < 8192)
232 return 8192;
233 return result;
234}
235#endif
236
237/* forward references */
238static void v4l_fbuffer_free(struct file *file);
239static void jpg_fbuffer_free(struct file *file);
240
241/*
242 * Allocate the V4L grab buffers
243 *
244 * These have to be pysically contiguous.
245 * If v4l_bufsize <= MAX_KMALLOC_MEM we use kmalloc
246 * else we try to allocate them with bigphysarea_alloc_pages
247 * if the bigphysarea patch is present in the kernel,
248 * else we try to use high memory (if the user has bootet
249 * Linux with the necessary memory left over).
250 */
251
252#if defined(BUZ_USE_HIMEM) && !defined(CONFIG_BIGPHYS_AREA)
253static unsigned long
254get_high_mem (unsigned long size)
255{
256/*
257 * Check if there is usable memory at the end of Linux memory
258 * of at least size. Return the physical address of this memory,
259 * return 0 on failure.
260 *
261 * The idea is from Alexandro Rubini's book "Linux device drivers".
262 * The driver from him which is downloadable from O'Reilly's
263 * web site misses the "virt_to_phys(high_memory)" part
264 * (and therefore doesn't work at all - at least with 2.2.x kernels).
265 *
266 * It should be unnecessary to mention that THIS IS DANGEROUS,
267 * if more than one driver at a time has the idea to use this memory!!!!
268 */
269
270 volatile unsigned char __iomem *mem;
271 unsigned char c;
272 unsigned long hi_mem_ph;
273 unsigned long i;
274
275 /* Map the high memory to user space */
276
277 hi_mem_ph = virt_to_phys(high_memory);
278
279 mem = ioremap(hi_mem_ph, size);
280 if (!mem) {
281 dprintk(1,
282 KERN_ERR "%s: get_high_mem() - ioremap failed\n",
283 ZORAN_NAME);
284 return 0;
285 }
286
287 for (i = 0; i < size; i++) {
288 /* Check if it is memory */
289 c = i & 0xff;
290 writeb(c, mem + i);
291 if (readb(mem + i) != c)
292 break;
293 c = 255 - c;
294 writeb(c, mem + i);
295 if (readb(mem + i) != c)
296 break;
297 writeb(0, mem + i); /* zero out memory */
298
299 /* give the kernel air to breath */
300 if ((i & 0x3ffff) == 0x3ffff)
301 schedule();
302 }
303
304 iounmap(mem);
305
306 if (i != size) {
307 dprintk(1,
308 KERN_ERR
309 "%s: get_high_mem() - requested %lu, avail %lu\n",
310 ZORAN_NAME, size, i);
311 return 0;
312 }
313
314 return hi_mem_ph;
315}
316#endif
317
318static int
319v4l_fbuffer_alloc (struct file *file)
320{
321 struct zoran_fh *fh = file->private_data;
322 struct zoran *zr = fh->zr;
323 int i, off;
324 unsigned char *mem;
325#if defined(BUZ_USE_HIMEM) && !defined(CONFIG_BIGPHYS_AREA)
326 unsigned long pmem = 0;
327#endif
328
329 /* we might have old buffers lying around... */
330 if (fh->v4l_buffers.ready_to_be_freed) {
331 v4l_fbuffer_free(file);
332 }
333
334 for (i = 0; i < fh->v4l_buffers.num_buffers; i++) {
335 if (fh->v4l_buffers.buffer[i].fbuffer)
336 dprintk(2,
337 KERN_WARNING
338 "%s: v4l_fbuffer_alloc() - buffer %d allready allocated!?\n",
339 ZR_DEVNAME(zr), i);
340
341 //udelay(20);
342 if (fh->v4l_buffers.buffer_size <= MAX_KMALLOC_MEM) {
343 /* Use kmalloc */
344
345 mem =
346 (unsigned char *) kmalloc(fh->v4l_buffers.
347 buffer_size,
348 GFP_KERNEL);
349 if (mem == 0) {
350 dprintk(1,
351 KERN_ERR
352 "%s: v4l_fbuffer_alloc() - kmalloc for V4L buf %d failed\n",
353 ZR_DEVNAME(zr), i);
354 v4l_fbuffer_free(file);
355 return -ENOBUFS;
356 }
357 fh->v4l_buffers.buffer[i].fbuffer = mem;
358 fh->v4l_buffers.buffer[i].fbuffer_phys =
359 virt_to_phys(mem);
360 fh->v4l_buffers.buffer[i].fbuffer_bus =
361 virt_to_bus(mem);
362 for (off = 0; off < fh->v4l_buffers.buffer_size;
363 off += PAGE_SIZE)
364 SetPageReserved(MAP_NR(mem + off));
365 dprintk(4,
366 KERN_INFO
367 "%s: v4l_fbuffer_alloc() - V4L frame %d mem 0x%lx (bus: 0x%lx)\n",
368 ZR_DEVNAME(zr), i, (unsigned long) mem,
369 virt_to_bus(mem));
370 } else {
371#if defined(CONFIG_BIGPHYS_AREA)
372 /* Use bigphysarea_alloc_pages */
373
374 int n =
375 (fh->v4l_buffers.buffer_size + PAGE_SIZE -
376 1) / PAGE_SIZE;
377
378 mem =
379 (unsigned char *) bigphysarea_alloc_pages(n, 0,
380 GFP_KERNEL);
381 if (mem == 0) {
382 dprintk(1,
383 KERN_ERR
384 "%s: v4l_fbuffer_alloc() - bigphysarea_alloc_pages for V4L buf %d failed\n",
385 ZR_DEVNAME(zr), i);
386 v4l_fbuffer_free(file);
387 return -ENOBUFS;
388 }
389 fh->v4l_buffers.buffer[i].fbuffer = mem;
390 fh->v4l_buffers.buffer[i].fbuffer_phys =
391 virt_to_phys(mem);
392 fh->v4l_buffers.buffer[i].fbuffer_bus =
393 virt_to_bus(mem);
394 dprintk(4,
395 KERN_INFO
396 "%s: Bigphysarea frame %d mem 0x%x (bus: 0x%x)\n",
397 ZR_DEVNAME(zr), i, (unsigned) mem,
398 (unsigned) virt_to_bus(mem));
399
400 /* Zero out the allocated memory */
401 memset(fh->v4l_buffers.buffer[i].fbuffer, 0,
402 fh->v4l_buffers.buffer_size);
403#elif defined(BUZ_USE_HIMEM)
404
405 /* Use high memory which has been left at boot time */
406
407 /* Ok., Ok. this is an evil hack - we make
408 * the assumption that physical addresses are
409 * the same as bus addresses (true at least
410 * for Intel processors). The whole method of
411 * obtaining and using this memory is not very
412 * nice - but I hope it saves some poor users
413 * from kernel hacking, which might have even
414 * more evil results */
415
416 if (i == 0) {
417 int size =
418 fh->v4l_buffers.num_buffers *
419 fh->v4l_buffers.buffer_size;
420
421 pmem = get_high_mem(size);
422 if (pmem == 0) {
423 dprintk(1,
424 KERN_ERR
425 "%s: v4l_fbuffer_alloc() - get_high_mem (size = %d KB) for V4L bufs failed\n",
426 ZR_DEVNAME(zr), size >> 10);
427 return -ENOBUFS;
428 }
429 fh->v4l_buffers.buffer[0].fbuffer = NULL;
430 fh->v4l_buffers.buffer[0].fbuffer_phys = pmem;
431 fh->v4l_buffers.buffer[0].fbuffer_bus = pmem;
432 dprintk(4,
433 KERN_INFO
434 "%s: v4l_fbuffer_alloc() - using %d KB high memory\n",
435 ZR_DEVNAME(zr), size >> 10);
436 } else {
437 fh->v4l_buffers.buffer[i].fbuffer = NULL;
438 fh->v4l_buffers.buffer[i].fbuffer_phys =
439 pmem + i * fh->v4l_buffers.buffer_size;
440 fh->v4l_buffers.buffer[i].fbuffer_bus =
441 pmem + i * fh->v4l_buffers.buffer_size;
442 }
443#else
444 /* No bigphysarea present, usage of high memory disabled,
445 * but user wants buffers of more than MAX_KMALLOC_MEM */
446 dprintk(1,
447 KERN_ERR
448 "%s: v4l_fbuffer_alloc() - no bigphysarea_patch present, usage of high memory disabled,\n",
449 ZR_DEVNAME(zr));
450 dprintk(1,
451 KERN_ERR
452 "%s: v4l_fbuffer_alloc() - sorry, could not allocate %d V4L buffers of size %d KB.\n",
453 ZR_DEVNAME(zr), fh->v4l_buffers.num_buffers,
454 fh->v4l_buffers.buffer_size >> 10);
455 return -ENOBUFS;
456#endif
457 }
458 }
459
460 fh->v4l_buffers.allocated = 1;
461
462 return 0;
463}
464
465/* free the V4L grab buffers */
466static void
467v4l_fbuffer_free (struct file *file)
468{
469 struct zoran_fh *fh = file->private_data;
470 struct zoran *zr = fh->zr;
471 int i, off;
472 unsigned char *mem;
473
474 dprintk(4, KERN_INFO "%s: v4l_fbuffer_free()\n", ZR_DEVNAME(zr));
475
476 for (i = 0; i < fh->v4l_buffers.num_buffers; i++) {
477 if (!fh->v4l_buffers.buffer[i].fbuffer)
478 continue;
479
480 if (fh->v4l_buffers.buffer_size <= MAX_KMALLOC_MEM) {
481 mem = fh->v4l_buffers.buffer[i].fbuffer;
482 for (off = 0; off < fh->v4l_buffers.buffer_size;
483 off += PAGE_SIZE)
484 ClearPageReserved(MAP_NR(mem + off));
485 kfree((void *) fh->v4l_buffers.buffer[i].fbuffer);
486 }
487#if defined(CONFIG_BIGPHYS_AREA)
488 else
489 bigphysarea_free_pages((void *) fh->v4l_buffers.
490 buffer[i].fbuffer);
491#endif
492 fh->v4l_buffers.buffer[i].fbuffer = NULL;
493 }
494
495 fh->v4l_buffers.allocated = 0;
496 fh->v4l_buffers.ready_to_be_freed = 0;
497}
498
499/*
500 * Allocate the MJPEG grab buffers.
501 *
502 * If the requested buffer size is smaller than MAX_KMALLOC_MEM,
503 * kmalloc is used to request a physically contiguous area,
504 * else we allocate the memory in framgents with get_zeroed_page.
505 *
506 * If a Natoma chipset is present and this is a revision 1 zr36057,
507 * each MJPEG buffer needs to be physically contiguous.
508 * (RJ: This statement is from Dave Perks' original driver,
509 * I could never check it because I have a zr36067)
510 * The driver cares about this because it reduces the buffer
511 * size to MAX_KMALLOC_MEM in that case (which forces contiguous allocation).
512 *
513 * RJ: The contents grab buffers needs never be accessed in the driver.
514 * Therefore there is no need to allocate them with vmalloc in order
515 * to get a contiguous virtual memory space.
516 * I don't understand why many other drivers first allocate them with
517 * vmalloc (which uses internally also get_zeroed_page, but delivers you
518 * virtual addresses) and then again have to make a lot of efforts
519 * to get the physical address.
520 *
521 * Ben Capper:
522 * On big-endian architectures (such as ppc) some extra steps
523 * are needed. When reading and writing to the stat_com array
524 * and fragment buffers, the device expects to see little-
525 * endian values. The use of cpu_to_le32() and le32_to_cpu()
526 * in this function (and one or two others in zoran_device.c)
527 * ensure that these values are always stored in little-endian
528 * form, regardless of architecture. The zr36057 does Very Bad
529 * Things on big endian architectures if the stat_com array
530 * and fragment buffers are not little-endian.
531 */
532
533static int
534jpg_fbuffer_alloc (struct file *file)
535{
536 struct zoran_fh *fh = file->private_data;
537 struct zoran *zr = fh->zr;
538 int i, j, off;
539 unsigned long mem;
540
541 /* we might have old buffers lying around */
542 if (fh->jpg_buffers.ready_to_be_freed) {
543 jpg_fbuffer_free(file);
544 }
545
546 for (i = 0; i < fh->jpg_buffers.num_buffers; i++) {
547 if (fh->jpg_buffers.buffer[i].frag_tab)
548 dprintk(2,
549 KERN_WARNING
550 "%s: jpg_fbuffer_alloc() - buffer %d allready allocated!?\n",
551 ZR_DEVNAME(zr), i);
552
553 /* Allocate fragment table for this buffer */
554
555 mem = get_zeroed_page(GFP_KERNEL);
556 if (mem == 0) {
557 dprintk(1,
558 KERN_ERR
559 "%s: jpg_fbuffer_alloc() - get_zeroed_page (frag_tab) failed for buffer %d\n",
560 ZR_DEVNAME(zr), i);
561 jpg_fbuffer_free(file);
562 return -ENOBUFS;
563 }
564 memset((void *) mem, 0, PAGE_SIZE);
565 fh->jpg_buffers.buffer[i].frag_tab = (u32 *) mem;
566 fh->jpg_buffers.buffer[i].frag_tab_bus =
567 virt_to_bus((void *) mem);
568
569 //if (alloc_contig) {
570 if (fh->jpg_buffers.need_contiguous) {
571 mem =
572 (unsigned long) kmalloc(fh->jpg_buffers.
573 buffer_size,
574 GFP_KERNEL);
575 if (mem == 0) {
576 dprintk(1,
577 KERN_ERR
578 "%s: jpg_fbuffer_alloc() - kmalloc failed for buffer %d\n",
579 ZR_DEVNAME(zr), i);
580 jpg_fbuffer_free(file);
581 return -ENOBUFS;
582 }
583 fh->jpg_buffers.buffer[i].frag_tab[0] =
584 cpu_to_le32(virt_to_bus((void *) mem));
585 fh->jpg_buffers.buffer[i].frag_tab[1] =
586 cpu_to_le32(((fh->jpg_buffers.buffer_size / 4) << 1) | 1);
587 for (off = 0; off < fh->jpg_buffers.buffer_size;
588 off += PAGE_SIZE)
589 SetPageReserved(MAP_NR(mem + off));
590 } else {
591 /* jpg_bufsize is allreay page aligned */
592 for (j = 0;
593 j < fh->jpg_buffers.buffer_size / PAGE_SIZE;
594 j++) {
595 mem = get_zeroed_page(GFP_KERNEL);
596 if (mem == 0) {
597 dprintk(1,
598 KERN_ERR
599 "%s: jpg_fbuffer_alloc() - get_zeroed_page failed for buffer %d\n",
600 ZR_DEVNAME(zr), i);
601 jpg_fbuffer_free(file);
602 return -ENOBUFS;
603 }
604
605 fh->jpg_buffers.buffer[i].frag_tab[2 * j] =
606 cpu_to_le32(virt_to_bus((void *) mem));
607 fh->jpg_buffers.buffer[i].frag_tab[2 * j +
608 1] =
609 cpu_to_le32((PAGE_SIZE / 4) << 1);
610 SetPageReserved(MAP_NR(mem));
611 }
612
613 fh->jpg_buffers.buffer[i].frag_tab[2 * j - 1] |= cpu_to_le32(1);
614 }
615 }
616
617 dprintk(4,
618 KERN_DEBUG "%s: jpg_fbuffer_alloc() - %d KB allocated\n",
619 ZR_DEVNAME(zr),
620 (fh->jpg_buffers.num_buffers *
621 fh->jpg_buffers.buffer_size) >> 10);
622
623 fh->jpg_buffers.allocated = 1;
624
625 return 0;
626}
627
628/* free the MJPEG grab buffers */
629static void
630jpg_fbuffer_free (struct file *file)
631{
632 struct zoran_fh *fh = file->private_data;
633 struct zoran *zr = fh->zr;
634 int i, j, off;
635 unsigned char *mem;
636
637 dprintk(4, KERN_DEBUG "%s: jpg_fbuffer_free()\n", ZR_DEVNAME(zr));
638
639 for (i = 0; i < fh->jpg_buffers.num_buffers; i++) {
640 if (!fh->jpg_buffers.buffer[i].frag_tab)
641 continue;
642
643 //if (alloc_contig) {
644 if (fh->jpg_buffers.need_contiguous) {
645 if (fh->jpg_buffers.buffer[i].frag_tab[0]) {
646 mem = (unsigned char *) bus_to_virt(le32_to_cpu(
647 fh->jpg_buffers.buffer[i].frag_tab[0]));
648 for (off = 0;
649 off < fh->jpg_buffers.buffer_size;
650 off += PAGE_SIZE)
651 ClearPageReserved(MAP_NR
652 (mem + off));
653 kfree((void *) mem);
654 fh->jpg_buffers.buffer[i].frag_tab[0] = 0;
655 fh->jpg_buffers.buffer[i].frag_tab[1] = 0;
656 }
657 } else {
658 for (j = 0;
659 j < fh->jpg_buffers.buffer_size / PAGE_SIZE;
660 j++) {
661 if (!fh->jpg_buffers.buffer[i].
662 frag_tab[2 * j])
663 break;
664 ClearPageReserved(MAP_NR
665 (bus_to_virt
666 (le32_to_cpu
667 (fh->jpg_buffers.
668 buffer[i].frag_tab[2 *
669 j]))));
670 free_page((unsigned long)
671 bus_to_virt
672 (le32_to_cpu
673 (fh->jpg_buffers.
674 buffer[i].
675 frag_tab[2 * j])));
676 fh->jpg_buffers.buffer[i].frag_tab[2 * j] =
677 0;
678 fh->jpg_buffers.buffer[i].frag_tab[2 * j +
679 1] = 0;
680 }
681 }
682
683 free_page((unsigned long) fh->jpg_buffers.buffer[i].
684 frag_tab);
685 fh->jpg_buffers.buffer[i].frag_tab = NULL;
686 }
687
688 fh->jpg_buffers.allocated = 0;
689 fh->jpg_buffers.ready_to_be_freed = 0;
690}
691
692/*
693 * V4L Buffer grabbing
694 */
695
696static int
697zoran_v4l_set_format (struct file *file,
698 int width,
699 int height,
700 const struct zoran_format *format)
701{
702 struct zoran_fh *fh = file->private_data;
703 struct zoran *zr = fh->zr;
704 int bpp;
705
706 /* Check size and format of the grab wanted */
707
708 if (height < BUZ_MIN_HEIGHT || width < BUZ_MIN_WIDTH ||
709 height > BUZ_MAX_HEIGHT || width > BUZ_MAX_WIDTH) {
710 dprintk(1,
711 KERN_ERR
712 "%s: v4l_set_format() - wrong frame size (%dx%d)\n",
713 ZR_DEVNAME(zr), width, height);
714 return -EINVAL;
715 }
716
717 bpp = (format->depth + 7) / 8;
718
719 /* Check against available buffer size */
720 if (height * width * bpp > fh->v4l_buffers.buffer_size) {
721 dprintk(1,
722 KERN_ERR
723 "%s: v4l_set_format() - video buffer size (%d kB) is too small\n",
724 ZR_DEVNAME(zr), fh->v4l_buffers.buffer_size >> 10);
725 return -EINVAL;
726 }
727
728 /* The video front end needs 4-byte alinged line sizes */
729
730 if ((bpp == 2 && (width & 1)) || (bpp == 3 && (width & 3))) {
731 dprintk(1,
732 KERN_ERR
733 "%s: v4l_set_format() - wrong frame alingment\n",
734 ZR_DEVNAME(zr));
735 return -EINVAL;
736 }
737
738 fh->v4l_settings.width = width;
739 fh->v4l_settings.height = height;
740 fh->v4l_settings.format = format;
741 fh->v4l_settings.bytesperline = bpp * fh->v4l_settings.width;
742
743 return 0;
744}
745
746static int
747zoran_v4l_queue_frame (struct file *file,
748 int num)
749{
750 struct zoran_fh *fh = file->private_data;
751 struct zoran *zr = fh->zr;
752 unsigned long flags;
753 int res = 0;
754
755 if (!fh->v4l_buffers.allocated) {
756 dprintk(1,
757 KERN_ERR
758 "%s: v4l_queue_frame() - buffers not yet allocated\n",
759 ZR_DEVNAME(zr));
760 res = -ENOMEM;
761 }
762
763 /* No grabbing outside the buffer range! */
764 if (num >= fh->v4l_buffers.num_buffers || num < 0) {
765 dprintk(1,
766 KERN_ERR
767 "%s: v4l_queue_frame() - buffer %d is out of range\n",
768 ZR_DEVNAME(zr), num);
769 res = -EINVAL;
770 }
771
772 spin_lock_irqsave(&zr->spinlock, flags);
773
774 if (fh->v4l_buffers.active == ZORAN_FREE) {
775 if (zr->v4l_buffers.active == ZORAN_FREE) {
776 zr->v4l_buffers = fh->v4l_buffers;
777 fh->v4l_buffers.active = ZORAN_ACTIVE;
778 } else {
779 dprintk(1,
780 KERN_ERR
781 "%s: v4l_queue_frame() - another session is already capturing\n",
782 ZR_DEVNAME(zr));
783 res = -EBUSY;
784 }
785 }
786
787 /* make sure a grab isn't going on currently with this buffer */
788 if (!res) {
789 switch (zr->v4l_buffers.buffer[num].state) {
790 default:
791 case BUZ_STATE_PEND:
792 if (zr->v4l_buffers.active == ZORAN_FREE) {
793 fh->v4l_buffers.active = ZORAN_FREE;
794 zr->v4l_buffers.allocated = 0;
795 }
796 res = -EBUSY; /* what are you doing? */
797 break;
798 case BUZ_STATE_DONE:
799 dprintk(2,
800 KERN_WARNING
801 "%s: v4l_queue_frame() - queueing buffer %d in state DONE!?\n",
802 ZR_DEVNAME(zr), num);
803 case BUZ_STATE_USER:
804 /* since there is at least one unused buffer there's room for at least
805 * one more pend[] entry */
806 zr->v4l_pend[zr->v4l_pend_head++ &
807 V4L_MASK_FRAME] = num;
808 zr->v4l_buffers.buffer[num].state = BUZ_STATE_PEND;
809 zr->v4l_buffers.buffer[num].bs.length =
810 fh->v4l_settings.bytesperline *
811 zr->v4l_settings.height;
812 fh->v4l_buffers.buffer[num] =
813 zr->v4l_buffers.buffer[num];
814 break;
815 }
816 }
817
818 spin_unlock_irqrestore(&zr->spinlock, flags);
819
820 if (!res && zr->v4l_buffers.active == ZORAN_FREE)
821 zr->v4l_buffers.active = fh->v4l_buffers.active;
822
823 return res;
824}
825
826static int
827v4l_grab (struct file *file,
828 struct video_mmap *mp)
829{
830 struct zoran_fh *fh = file->private_data;
831 struct zoran *zr = fh->zr;
832 int res = 0, i;
833
834 for (i = 0; i < zoran_num_formats; i++) {
835 if (zoran_formats[i].palette == mp->format &&
836 zoran_formats[i].flags & ZORAN_FORMAT_CAPTURE &&
837 !(zoran_formats[i].flags & ZORAN_FORMAT_COMPRESSED))
838 break;
839 }
840 if (i == zoran_num_formats || zoran_formats[i].depth == 0) {
841 dprintk(1,
842 KERN_ERR
843 "%s: v4l_grab() - wrong bytes-per-pixel format\n",
844 ZR_DEVNAME(zr));
845 return -EINVAL;
846 }
847
848 /*
849 * To minimize the time spent in the IRQ routine, we avoid setting up
850 * the video front end there.
851 * If this grab has different parameters from a running streaming capture
852 * we stop the streaming capture and start it over again.
853 */
854 if (zr->v4l_memgrab_active &&
855 (zr->v4l_settings.width != mp->width ||
856 zr->v4l_settings.height != mp->height ||
857 zr->v4l_settings.format->palette != mp->format)) {
858 res = wait_grab_pending(zr);
859 if (res)
860 return res;
861 }
862 if ((res = zoran_v4l_set_format(file,
863 mp->width,
864 mp->height,
865 &zoran_formats[i])))
866 return res;
867 zr->v4l_settings = fh->v4l_settings;
868
869 /* queue the frame in the pending queue */
870 if ((res = zoran_v4l_queue_frame(file, mp->frame))) {
871 fh->v4l_buffers.active = ZORAN_FREE;
872 return res;
873 }
874
875 /* put the 36057 into frame grabbing mode */
876 if (!res && !zr->v4l_memgrab_active)
877 zr36057_set_memgrab(zr, 1);
878
879 //dprintk(4, KERN_INFO "%s: Frame grab 3...\n", ZR_DEVNAME(zr));
880
881 return res;
882}
883
884/*
885 * Sync on a V4L buffer
886 */
887
888static int
889v4l_sync (struct file *file,
890 int frame)
891{
892 struct zoran_fh *fh = file->private_data;
893 struct zoran *zr = fh->zr;
894 unsigned long flags;
895
896 if (fh->v4l_buffers.active == ZORAN_FREE) {
897 dprintk(1,
898 KERN_ERR
899 "%s: v4l_sync() - no grab active for this session\n",
900 ZR_DEVNAME(zr));
901 return -EINVAL;
902 }
903
904 /* check passed-in frame number */
905 if (frame >= fh->v4l_buffers.num_buffers || frame < 0) {
906 dprintk(1,
907 KERN_ERR "%s: v4l_sync() - frame %d is invalid\n",
908 ZR_DEVNAME(zr), frame);
909 return -EINVAL;
910 }
911
912 /* Check if is buffer was queued at all */
913 if (zr->v4l_buffers.buffer[frame].state == BUZ_STATE_USER) {
914 dprintk(1,
915 KERN_ERR
916 "%s: v4l_sync() - attempt to sync on a buffer which was not queued?\n",
917 ZR_DEVNAME(zr));
918 return -EPROTO;
919 }
920
921 /* wait on this buffer to get ready */
922 if (!wait_event_interruptible_timeout(zr->v4l_capq,
923 (zr->v4l_buffers.buffer[frame].state != BUZ_STATE_PEND),
924 10*HZ))
925 return -ETIME;
926 if (signal_pending(current))
927 return -ERESTARTSYS;
928
929 /* buffer should now be in BUZ_STATE_DONE */
930 if (zr->v4l_buffers.buffer[frame].state != BUZ_STATE_DONE)
931 dprintk(2,
932 KERN_ERR "%s: v4l_sync() - internal state error\n",
933 ZR_DEVNAME(zr));
934
935 zr->v4l_buffers.buffer[frame].state = BUZ_STATE_USER;
936 fh->v4l_buffers.buffer[frame] = zr->v4l_buffers.buffer[frame];
937
938 spin_lock_irqsave(&zr->spinlock, flags);
939
940 /* Check if streaming capture has finished */
941 if (zr->v4l_pend_tail == zr->v4l_pend_head) {
942 zr36057_set_memgrab(zr, 0);
943 if (zr->v4l_buffers.active == ZORAN_ACTIVE) {
944 fh->v4l_buffers.active = zr->v4l_buffers.active =
945 ZORAN_FREE;
946 zr->v4l_buffers.allocated = 0;
947 }
948 }
949
950 spin_unlock_irqrestore(&zr->spinlock, flags);
951
952 return 0;
953}
954
955/*
956 * Queue a MJPEG buffer for capture/playback
957 */
958
959static int
960zoran_jpg_queue_frame (struct file *file,
961 int num,
962 enum zoran_codec_mode mode)
963{
964 struct zoran_fh *fh = file->private_data;
965 struct zoran *zr = fh->zr;
966 unsigned long flags;
967 int res = 0;
968
969 /* Check if buffers are allocated */
970 if (!fh->jpg_buffers.allocated) {
971 dprintk(1,
972 KERN_ERR
973 "%s: jpg_queue_frame() - buffers not yet allocated\n",
974 ZR_DEVNAME(zr));
975 return -ENOMEM;
976 }
977
978 /* No grabbing outside the buffer range! */
979 if (num >= fh->jpg_buffers.num_buffers || num < 0) {
980 dprintk(1,
981 KERN_ERR
982 "%s: jpg_queue_frame() - buffer %d out of range\n",
983 ZR_DEVNAME(zr), num);
984 return -EINVAL;
985 }
986
987 /* what is the codec mode right now? */
988 if (zr->codec_mode == BUZ_MODE_IDLE) {
989 zr->jpg_settings = fh->jpg_settings;
990 } else if (zr->codec_mode != mode) {
991 /* wrong codec mode active - invalid */
992 dprintk(1,
993 KERN_ERR
994 "%s: jpg_queue_frame() - codec in wrong mode\n",
995 ZR_DEVNAME(zr));
996 return -EINVAL;
997 }
998
999 spin_lock_irqsave(&zr->spinlock, flags);
1000
1001 if (fh->jpg_buffers.active == ZORAN_FREE) {
1002 if (zr->jpg_buffers.active == ZORAN_FREE) {
1003 zr->jpg_buffers = fh->jpg_buffers;
1004 fh->jpg_buffers.active = ZORAN_ACTIVE;
1005 } else {
1006 dprintk(1,
1007 KERN_ERR
1008 "%s: jpg_queue_frame() - another session is already capturing\n",
1009 ZR_DEVNAME(zr));
1010 res = -EBUSY;
1011 }
1012 }
1013
1014 if (!res && zr->codec_mode == BUZ_MODE_IDLE) {
1015 /* Ok load up the jpeg codec */
1016 zr36057_enable_jpg(zr, mode);
1017 }
1018
1019 if (!res) {
1020 switch (zr->jpg_buffers.buffer[num].state) {
1021 case BUZ_STATE_DONE:
1022 dprintk(2,
1023 KERN_WARNING
1024 "%s: jpg_queue_frame() - queing frame in BUZ_STATE_DONE state!?\n",
1025 ZR_DEVNAME(zr));
1026 case BUZ_STATE_USER:
1027 /* since there is at least one unused buffer there's room for at
1028 *least one more pend[] entry */
1029 zr->jpg_pend[zr->jpg_que_head++ & BUZ_MASK_FRAME] =
1030 num;
1031 zr->jpg_buffers.buffer[num].state = BUZ_STATE_PEND;
1032 fh->jpg_buffers.buffer[num] =
1033 zr->jpg_buffers.buffer[num];
1034 zoran_feed_stat_com(zr);
1035 break;
1036 default:
1037 case BUZ_STATE_DMA:
1038 case BUZ_STATE_PEND:
1039 if (zr->jpg_buffers.active == ZORAN_FREE) {
1040 fh->jpg_buffers.active = ZORAN_FREE;
1041 zr->jpg_buffers.allocated = 0;
1042 }
1043 res = -EBUSY; /* what are you doing? */
1044 break;
1045 }
1046 }
1047
1048 spin_unlock_irqrestore(&zr->spinlock, flags);
1049
1050 if (!res && zr->jpg_buffers.active == ZORAN_FREE) {
1051 zr->jpg_buffers.active = fh->jpg_buffers.active;
1052 }
1053
1054 return res;
1055}
1056
1057static int
1058jpg_qbuf (struct file *file,
1059 int frame,
1060 enum zoran_codec_mode mode)
1061{
1062 struct zoran_fh *fh = file->private_data;
1063 struct zoran *zr = fh->zr;
1064 int res = 0;
1065
1066 /* Does the user want to stop streaming? */
1067 if (frame < 0) {
1068 if (zr->codec_mode == mode) {
1069 if (fh->jpg_buffers.active == ZORAN_FREE) {
1070 dprintk(1,
1071 KERN_ERR
1072 "%s: jpg_qbuf(-1) - session not active\n",
1073 ZR_DEVNAME(zr));
1074 return -EINVAL;
1075 }
1076 fh->jpg_buffers.active = zr->jpg_buffers.active =
1077 ZORAN_FREE;
1078 zr->jpg_buffers.allocated = 0;
1079 zr36057_enable_jpg(zr, BUZ_MODE_IDLE);
1080 return 0;
1081 } else {
1082 dprintk(1,
1083 KERN_ERR
1084 "%s: jpg_qbuf() - stop streaming but not in streaming mode\n",
1085 ZR_DEVNAME(zr));
1086 return -EINVAL;
1087 }
1088 }
1089
1090 if ((res = zoran_jpg_queue_frame(file, frame, mode)))
1091 return res;
1092
1093 /* Start the jpeg codec when the first frame is queued */
1094 if (!res && zr->jpg_que_head == 1)
1095 jpeg_start(zr);
1096
1097 return res;
1098}
1099
1100/*
1101 * Sync on a MJPEG buffer
1102 */
1103
1104static int
1105jpg_sync (struct file *file,
1106 struct zoran_sync *bs)
1107{
1108 struct zoran_fh *fh = file->private_data;
1109 struct zoran *zr = fh->zr;
1110 unsigned long flags;
1111 int frame;
1112
1113 if (fh->jpg_buffers.active == ZORAN_FREE) {
1114 dprintk(1,
1115 KERN_ERR
1116 "%s: jpg_sync() - capture is not currently active\n",
1117 ZR_DEVNAME(zr));
1118 return -EINVAL;
1119 }
1120 if (zr->codec_mode != BUZ_MODE_MOTION_DECOMPRESS &&
1121 zr->codec_mode != BUZ_MODE_MOTION_COMPRESS) {
1122 dprintk(1,
1123 KERN_ERR
1124 "%s: jpg_sync() - codec not in streaming mode\n",
1125 ZR_DEVNAME(zr));
1126 return -EINVAL;
1127 }
1128 if (!wait_event_interruptible_timeout(zr->jpg_capq,
1129 (zr->jpg_que_tail != zr->jpg_dma_tail ||
1130 zr->jpg_dma_tail == zr->jpg_dma_head),
1131 10*HZ)) {
1132 int isr;
1133
1134 btand(~ZR36057_JMC_Go_en, ZR36057_JMC);
1135 udelay(1);
1136 zr->codec->control(zr->codec, CODEC_G_STATUS,
1137 sizeof(isr), &isr);
1138 dprintk(1,
1139 KERN_ERR
1140 "%s: jpg_sync() - timeout: codec isr=0x%02x\n",
1141 ZR_DEVNAME(zr), isr);
1142
1143 return -ETIME;
1144
1145 }
1146 if (signal_pending(current))
1147 return -ERESTARTSYS;
1148
1149 spin_lock_irqsave(&zr->spinlock, flags);
1150
1151 if (zr->jpg_dma_tail != zr->jpg_dma_head)
1152 frame = zr->jpg_pend[zr->jpg_que_tail++ & BUZ_MASK_FRAME];
1153 else
1154 frame = zr->jpg_pend[zr->jpg_que_tail & BUZ_MASK_FRAME];
1155
1156 /* buffer should now be in BUZ_STATE_DONE */
1157 if (*zr_debug > 0)
1158 if (zr->jpg_buffers.buffer[frame].state != BUZ_STATE_DONE)
1159 dprintk(2,
1160 KERN_ERR
1161 "%s: jpg_sync() - internal state error\n",
1162 ZR_DEVNAME(zr));
1163
1164 *bs = zr->jpg_buffers.buffer[frame].bs;
1165 bs->frame = frame;
1166 zr->jpg_buffers.buffer[frame].state = BUZ_STATE_USER;
1167 fh->jpg_buffers.buffer[frame] = zr->jpg_buffers.buffer[frame];
1168
1169 spin_unlock_irqrestore(&zr->spinlock, flags);
1170
1171 return 0;
1172}
1173
1174static void
1175zoran_open_init_session (struct file *file)
1176{
1177 int i;
1178 struct zoran_fh *fh = file->private_data;
1179 struct zoran *zr = fh->zr;
1180
1181 /* Per default, map the V4L Buffers */
1182 fh->map_mode = ZORAN_MAP_MODE_RAW;
1183
1184 /* take over the card's current settings */
1185 fh->overlay_settings = zr->overlay_settings;
1186 fh->overlay_settings.is_set = 0;
1187 fh->overlay_settings.format = zr->overlay_settings.format;
1188 fh->overlay_active = ZORAN_FREE;
1189
1190 /* v4l settings */
1191 fh->v4l_settings = zr->v4l_settings;
1192
1193 /* v4l_buffers */
1194 memset(&fh->v4l_buffers, 0, sizeof(struct zoran_v4l_struct));
1195 for (i = 0; i < VIDEO_MAX_FRAME; i++) {
1196 fh->v4l_buffers.buffer[i].state = BUZ_STATE_USER; /* nothing going on */
1197 fh->v4l_buffers.buffer[i].bs.frame = i;
1198 }
1199 fh->v4l_buffers.allocated = 0;
1200 fh->v4l_buffers.ready_to_be_freed = 0;
1201 fh->v4l_buffers.active = ZORAN_FREE;
1202 fh->v4l_buffers.buffer_size = v4l_bufsize;
1203 fh->v4l_buffers.num_buffers = v4l_nbufs;
1204
1205 /* jpg settings */
1206 fh->jpg_settings = zr->jpg_settings;
1207
1208 /* jpg_buffers */
1209 memset(&fh->jpg_buffers, 0, sizeof(struct zoran_jpg_struct));
1210 for (i = 0; i < BUZ_MAX_FRAME; i++) {
1211 fh->jpg_buffers.buffer[i].state = BUZ_STATE_USER; /* nothing going on */
1212 fh->jpg_buffers.buffer[i].bs.frame = i;
1213 }
1214 fh->jpg_buffers.need_contiguous = zr->jpg_buffers.need_contiguous;
1215 fh->jpg_buffers.allocated = 0;
1216 fh->jpg_buffers.ready_to_be_freed = 0;
1217 fh->jpg_buffers.active = ZORAN_FREE;
1218 fh->jpg_buffers.buffer_size = jpg_bufsize;
1219 fh->jpg_buffers.num_buffers = jpg_nbufs;
1220}
1221
1222static void
1223zoran_close_end_session (struct file *file)
1224{
1225 struct zoran_fh *fh = file->private_data;
1226 struct zoran *zr = fh->zr;
1227
1228 /* overlay */
1229 if (fh->overlay_active != ZORAN_FREE) {
1230 fh->overlay_active = zr->overlay_active = ZORAN_FREE;
1231 zr->v4l_overlay_active = 0;
1232 if (!zr->v4l_memgrab_active)
1233 zr36057_overlay(zr, 0);
1234 zr->overlay_mask = NULL;
1235 }
1236
1237 /* v4l capture */
1238 if (fh->v4l_buffers.active != ZORAN_FREE) {
1239 zr36057_set_memgrab(zr, 0);
1240 zr->v4l_buffers.allocated = 0;
1241 zr->v4l_buffers.active = fh->v4l_buffers.active =
1242 ZORAN_FREE;
1243 }
1244
1245 /* v4l buffers */
1246 if (fh->v4l_buffers.allocated ||
1247 fh->v4l_buffers.ready_to_be_freed) {
1248 v4l_fbuffer_free(file);
1249 }
1250
1251 /* jpg capture */
1252 if (fh->jpg_buffers.active != ZORAN_FREE) {
1253 zr36057_enable_jpg(zr, BUZ_MODE_IDLE);
1254 zr->jpg_buffers.allocated = 0;
1255 zr->jpg_buffers.active = fh->jpg_buffers.active =
1256 ZORAN_FREE;
1257 }
1258
1259 /* jpg buffers */
1260 if (fh->jpg_buffers.allocated ||
1261 fh->jpg_buffers.ready_to_be_freed) {
1262 jpg_fbuffer_free(file);
1263 }
1264}
1265
1266/*
1267 * Open a zoran card. Right now the flags stuff is just playing
1268 */
1269
1270static int
1271zoran_open (struct inode *inode,
1272 struct file *file)
1273{
1274 unsigned int minor = iminor(inode);
1275 struct zoran *zr = NULL;
1276 struct zoran_fh *fh;
1277 int i, res, first_open = 0, have_module_locks = 0;
1278
1279 /* find the device */
1280 for (i = 0; i < zoran_num; i++) {
1281 if (zoran[i].video_dev->minor == minor) {
1282 zr = &zoran[i];
1283 break;
1284 }
1285 }
1286
1287 if (!zr) {
1288 dprintk(1, KERN_ERR "%s: device not found!\n", ZORAN_NAME);
1289 res = -ENODEV;
1290 goto open_unlock_and_return;
1291 }
1292
1293 /* see fs/device.c - the kernel already locks during open(),
1294 * so locking ourselves only causes deadlocks */
1295 /*down(&zr->resource_lock);*/
1296
1297 if (!zr->decoder) {
1298 dprintk(1,
1299 KERN_ERR "%s: no TV decoder loaded for device!\n",
1300 ZR_DEVNAME(zr));
1301 res = -EIO;
1302 goto open_unlock_and_return;
1303 }
1304
1305 /* try to grab a module lock */
1306 if (!try_module_get(THIS_MODULE)) {
1307 dprintk(1,
1308 KERN_ERR
1309 "%s: failed to acquire my own lock! PANIC!\n",
1310 ZR_DEVNAME(zr));
1311 res = -ENODEV;
1312 goto open_unlock_and_return;
1313 }
1314 if (!try_module_get(zr->decoder->driver->owner)) {
1315 dprintk(1,
1316 KERN_ERR
1317 "%s: failed to grab ownership of i2c decoder\n",
1318 ZR_DEVNAME(zr));
1319 res = -EIO;
1320 module_put(THIS_MODULE);
1321 goto open_unlock_and_return;
1322 }
1323 if (zr->encoder &&
1324 !try_module_get(zr->encoder->driver->owner)) {
1325 dprintk(1,
1326 KERN_ERR
1327 "%s: failed to grab ownership of i2c encoder\n",
1328 ZR_DEVNAME(zr));
1329 res = -EIO;
1330 module_put(zr->decoder->driver->owner);
1331 module_put(THIS_MODULE);
1332 goto open_unlock_and_return;
1333 }
1334
1335 have_module_locks = 1;
1336
1337 if (zr->user >= 2048) {
1338 dprintk(1, KERN_ERR "%s: too many users (%d) on device\n",
1339 ZR_DEVNAME(zr), zr->user);
1340 res = -EBUSY;
1341 goto open_unlock_and_return;
1342 }
1343
1344 dprintk(1, KERN_INFO "%s: zoran_open(%s, pid=[%d]), users(-)=%d\n",
1345 ZR_DEVNAME(zr), current->comm, current->pid, zr->user);
1346
1347 /* now, create the open()-specific file_ops struct */
1348 fh = kmalloc(sizeof(struct zoran_fh), GFP_KERNEL);
1349 if (!fh) {
1350 dprintk(1,
1351 KERN_ERR
1352 "%s: zoran_open() - allocation of zoran_fh failed\n",
1353 ZR_DEVNAME(zr));
1354 res = -ENOMEM;
1355 goto open_unlock_and_return;
1356 }
1357 memset(fh, 0, sizeof(struct zoran_fh));
1358 /* used to be BUZ_MAX_WIDTH/HEIGHT, but that gives overflows
1359 * on norm-change! */
1360 fh->overlay_mask =
1361 kmalloc(((768 + 31) / 32) * 576 * 4, GFP_KERNEL);
1362 if (!fh->overlay_mask) {
1363 dprintk(1,
1364 KERN_ERR
1365 "%s: zoran_open() - allocation of overlay_mask failed\n",
1366 ZR_DEVNAME(zr));
1367 kfree(fh);
1368 res = -ENOMEM;
1369 goto open_unlock_and_return;
1370 }
1371
1372 if (zr->user++ == 0)
1373 first_open = 1;
1374
1375 /*up(&zr->resource_lock);*/
1376
1377 /* default setup - TODO: look at flags */
1378 if (first_open) { /* First device open */
1379 zr36057_restart(zr);
1380 zoran_open_init_params(zr);
1381 zoran_init_hardware(zr);
1382
1383 btor(ZR36057_ICR_IntPinEn, ZR36057_ICR);
1384 }
1385
1386 /* set file_ops stuff */
1387 file->private_data = fh;
1388 fh->zr = zr;
1389 zoran_open_init_session(file);
1390
1391 return 0;
1392
1393open_unlock_and_return:
1394 /* if we grabbed locks, release them accordingly */
1395 if (have_module_locks) {
1396 module_put(zr->decoder->driver->owner);
1397 if (zr->encoder) {
1398 module_put(zr->encoder->driver->owner);
1399 }
1400 module_put(THIS_MODULE);
1401 }
1402
1403 /* if there's no device found, we didn't obtain the lock either */
1404 if (zr) {
1405 /*up(&zr->resource_lock);*/
1406 }
1407
1408 return res;
1409}
1410
1411static int
1412zoran_close (struct inode *inode,
1413 struct file *file)
1414{
1415 struct zoran_fh *fh = file->private_data;
1416 struct zoran *zr = fh->zr;
1417
1418 dprintk(1, KERN_INFO "%s: zoran_close(%s, pid=[%d]), users(+)=%d\n",
1419 ZR_DEVNAME(zr), current->comm, current->pid, zr->user);
1420
1421 /* kernel locks (fs/device.c), so don't do that ourselves
1422 * (prevents deadlocks) */
1423 /*down(&zr->resource_lock);*/
1424
1425 zoran_close_end_session(file);
1426
1427 if (zr->user-- == 1) { /* Last process */
1428 /* Clean up JPEG process */
1429 wake_up_interruptible(&zr->jpg_capq);
1430 zr36057_enable_jpg(zr, BUZ_MODE_IDLE);
1431 zr->jpg_buffers.allocated = 0;
1432 zr->jpg_buffers.active = ZORAN_FREE;
1433
1434 /* disable interrupts */
1435 btand(~ZR36057_ICR_IntPinEn, ZR36057_ICR);
1436
1437 if (*zr_debug > 1)
1438 print_interrupts(zr);
1439
1440 /* Overlay off */
1441 zr->v4l_overlay_active = 0;
1442 zr36057_overlay(zr, 0);
1443 zr->overlay_mask = NULL;
1444
1445 /* capture off */
1446 wake_up_interruptible(&zr->v4l_capq);
1447 zr36057_set_memgrab(zr, 0);
1448 zr->v4l_buffers.allocated = 0;
1449 zr->v4l_buffers.active = ZORAN_FREE;
1450 zoran_set_pci_master(zr, 0);
1451
1452 if (!pass_through) { /* Switch to color bar */
1453 int zero = 0, two = 2;
1454 decoder_command(zr, DECODER_ENABLE_OUTPUT, &zero);
1455 encoder_command(zr, ENCODER_SET_INPUT, &two);
1456 }
1457 }
1458
1459 file->private_data = NULL;
1460 kfree(fh->overlay_mask);
1461 kfree(fh);
1462
1463 /* release locks on the i2c modules */
1464 module_put(zr->decoder->driver->owner);
1465 if (zr->encoder) {
1466 module_put(zr->encoder->driver->owner);
1467 }
1468 module_put(THIS_MODULE);
1469
1470 /*up(&zr->resource_lock);*/
1471
1472 dprintk(4, KERN_INFO "%s: zoran_close() done\n", ZR_DEVNAME(zr));
1473
1474 return 0;
1475}
1476
1477
1478static ssize_t
1479zoran_read (struct file *file,
1480 char __user *data,
1481 size_t count,
1482 loff_t *ppos)
1483{
1484 /* we simply don't support read() (yet)... */
1485
1486 return -EINVAL;
1487}
1488
1489static ssize_t
1490zoran_write (struct file *file,
1491 const char __user *data,
1492 size_t count,
1493 loff_t *ppos)
1494{
1495 /* ...and the same goes for write() */
1496
1497 return -EINVAL;
1498}
1499
1500static int
1501setup_fbuffer (struct file *file,
1502 void *base,
1503 const struct zoran_format *fmt,
1504 int width,
1505 int height,
1506 int bytesperline)
1507{
1508 struct zoran_fh *fh = file->private_data;
1509 struct zoran *zr = fh->zr;
1510
1511 /* (Ronald) v4l/v4l2 guidelines */
1512 if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RAWIO))
1513 return -EPERM;
1514
1515 /* we need a bytesperline value, even if not given */
1516 if (!bytesperline)
1517 bytesperline = width * ((fmt->depth + 7) & ~7) / 8;
1518
1519#if 0
1520 if (zr->overlay_active) {
1521 /* dzjee... stupid users... don't even bother to turn off
1522 * overlay before changing the memory location...
1523 * normally, we would return errors here. However, one of
1524 * the tools that does this is... xawtv! and since xawtv
1525 * is used by +/- 99% of the users, we'd rather be user-
1526 * friendly and silently do as if nothing went wrong */
1527 dprintk(3,
1528 KERN_ERR
1529 "%s: setup_fbuffer() - forced overlay turnoff because framebuffer changed\n",
1530 ZR_DEVNAME(zr));
1531 zr36057_overlay(zr, 0);
1532 }
1533#endif
1534
1535 if (!(fmt->flags & ZORAN_FORMAT_OVERLAY)) {
1536 dprintk(1,
1537 KERN_ERR
1538 "%s: setup_fbuffer() - no valid overlay format given\n",
1539 ZR_DEVNAME(zr));
1540 return -EINVAL;
1541 }
1542 if (height <= 0 || width <= 0 || bytesperline <= 0) {
1543 dprintk(1,
1544 KERN_ERR
1545 "%s: setup_fbuffer() - invalid height/width/bpl value (%d|%d|%d)\n",
1546 ZR_DEVNAME(zr), width, height, bytesperline);
1547 return -EINVAL;
1548 }
1549 if (bytesperline & 3) {
1550 dprintk(1,
1551 KERN_ERR
1552 "%s: setup_fbuffer() - bytesperline (%d) must be 4-byte aligned\n",
1553 ZR_DEVNAME(zr), bytesperline);
1554 return -EINVAL;
1555 }
1556
1557 zr->buffer.base = (void *) ((unsigned long) base & ~3);
1558 zr->buffer.height = height;
1559 zr->buffer.width = width;
1560 zr->buffer.depth = fmt->depth;
1561 zr->overlay_settings.format = fmt;
1562 zr->buffer.bytesperline = bytesperline;
1563
1564 /* The user should set new window parameters */
1565 zr->overlay_settings.is_set = 0;
1566
1567 return 0;
1568}
1569
1570
1571static int
1572setup_window (struct file *file,
1573 int x,
1574 int y,
1575 int width,
1576 int height,
1577 struct video_clip __user *clips,
1578 int clipcount,
1579 void __user *bitmap)
1580{
1581 struct zoran_fh *fh = file->private_data;
1582 struct zoran *zr = fh->zr;
1583 struct video_clip *vcp = NULL;
1584 int on, end;
1585
1586
1587 if (!zr->buffer.base) {
1588 dprintk(1,
1589 KERN_ERR
1590 "%s: setup_window() - frame buffer has to be set first\n",
1591 ZR_DEVNAME(zr));
1592 return -EINVAL;
1593 }
1594
1595 if (!fh->overlay_settings.format) {
1596 dprintk(1,
1597 KERN_ERR
1598 "%s: setup_window() - no overlay format set\n",
1599 ZR_DEVNAME(zr));
1600 return -EINVAL;
1601 }
1602
1603 /*
1604 * The video front end needs 4-byte alinged line sizes, we correct that
1605 * silently here if necessary
1606 */
1607 if (zr->buffer.depth == 15 || zr->buffer.depth == 16) {
1608 end = (x + width) & ~1; /* round down */
1609 x = (x + 1) & ~1; /* round up */
1610 width = end - x;
1611 }
1612
1613 if (zr->buffer.depth == 24) {
1614 end = (x + width) & ~3; /* round down */
1615 x = (x + 3) & ~3; /* round up */
1616 width = end - x;
1617 }
1618
1619 if (width > BUZ_MAX_WIDTH)
1620 width = BUZ_MAX_WIDTH;
1621 if (height > BUZ_MAX_HEIGHT)
1622 height = BUZ_MAX_HEIGHT;
1623
1624 /* Check for vaild parameters */
1625 if (width < BUZ_MIN_WIDTH || height < BUZ_MIN_HEIGHT ||
1626 width > BUZ_MAX_WIDTH || height > BUZ_MAX_HEIGHT) {
1627 dprintk(1,
1628 KERN_ERR
1629 "%s: setup_window() - width = %d or height = %d invalid\n",
1630 ZR_DEVNAME(zr), width, height);
1631 return -EINVAL;
1632 }
1633
1634 fh->overlay_settings.x = x;
1635 fh->overlay_settings.y = y;
1636 fh->overlay_settings.width = width;
1637 fh->overlay_settings.height = height;
1638 fh->overlay_settings.clipcount = clipcount;
1639
1640 /*
1641 * If an overlay is running, we have to switch it off
1642 * and switch it on again in order to get the new settings in effect.
1643 *
1644 * We also want to avoid that the overlay mask is written
1645 * when an overlay is running.
1646 */
1647
1648 on = zr->v4l_overlay_active && !zr->v4l_memgrab_active &&
1649 zr->overlay_active != ZORAN_FREE &&
1650 fh->overlay_active != ZORAN_FREE;
1651 if (on)
1652 zr36057_overlay(zr, 0);
1653
1654 /*
1655 * Write the overlay mask if clips are wanted.
1656 * We prefer a bitmap.
1657 */
1658 if (bitmap) {
1659 /* fake value - it just means we want clips */
1660 fh->overlay_settings.clipcount = 1;
1661
1662 if (copy_from_user(fh->overlay_mask, bitmap,
1663 (width * height + 7) / 8)) {
1664 return -EFAULT;
1665 }
1666 } else if (clipcount > 0) {
1667 /* write our own bitmap from the clips */
1668 vcp = vmalloc(sizeof(struct video_clip) * (clipcount + 4));
1669 if (vcp == NULL) {
1670 dprintk(1,
1671 KERN_ERR
1672 "%s: setup_window() - Alloc of clip mask failed\n",
1673 ZR_DEVNAME(zr));
1674 return -ENOMEM;
1675 }
1676 if (copy_from_user
1677 (vcp, clips, sizeof(struct video_clip) * clipcount)) {
1678 vfree(vcp);
1679 return -EFAULT;
1680 }
1681 write_overlay_mask(file, vcp, clipcount);
1682 vfree(vcp);
1683 }
1684
1685 fh->overlay_settings.is_set = 1;
1686 if (fh->overlay_active != ZORAN_FREE &&
1687 zr->overlay_active != ZORAN_FREE)
1688 zr->overlay_settings = fh->overlay_settings;
1689
1690 if (on)
1691 zr36057_overlay(zr, 1);
1692
1693 /* Make sure the changes come into effect */
1694 return wait_grab_pending(zr);
1695}
1696
1697static int
1698setup_overlay (struct file *file,
1699 int on)
1700{
1701 struct zoran_fh *fh = file->private_data;
1702 struct zoran *zr = fh->zr;
1703
1704 /* If there is nothing to do, return immediatly */
1705 if ((on && fh->overlay_active != ZORAN_FREE) ||
1706 (!on && fh->overlay_active == ZORAN_FREE))
1707 return 0;
1708
1709 /* check whether we're touching someone else's overlay */
1710 if (on && zr->overlay_active != ZORAN_FREE &&
1711 fh->overlay_active == ZORAN_FREE) {
1712 dprintk(1,
1713 KERN_ERR
1714 "%s: setup_overlay() - overlay is already active for another session\n",
1715 ZR_DEVNAME(zr));
1716 return -EBUSY;
1717 }
1718 if (!on && zr->overlay_active != ZORAN_FREE &&
1719 fh->overlay_active == ZORAN_FREE) {
1720 dprintk(1,
1721 KERN_ERR
1722 "%s: setup_overlay() - you cannot cancel someone else's session\n",
1723 ZR_DEVNAME(zr));
1724 return -EPERM;
1725 }
1726
1727 if (on == 0) {
1728 zr->overlay_active = fh->overlay_active = ZORAN_FREE;
1729 zr->v4l_overlay_active = 0;
1730 /* When a grab is running, the video simply
1731 * won't be switched on any more */
1732 if (!zr->v4l_memgrab_active)
1733 zr36057_overlay(zr, 0);
1734 zr->overlay_mask = NULL;
1735 } else {
1736 if (!zr->buffer.base || !fh->overlay_settings.is_set) {
1737 dprintk(1,
1738 KERN_ERR
1739 "%s: setup_overlay() - buffer or window not set\n",
1740 ZR_DEVNAME(zr));
1741 return -EINVAL;
1742 }
1743 if (!fh->overlay_settings.format) {
1744 dprintk(1,
1745 KERN_ERR
1746 "%s: setup_overlay() - no overlay format set\n",
1747 ZR_DEVNAME(zr));
1748 return -EINVAL;
1749 }
1750 zr->overlay_active = fh->overlay_active = ZORAN_LOCKED;
1751 zr->v4l_overlay_active = 1;
1752 zr->overlay_mask = fh->overlay_mask;
1753 zr->overlay_settings = fh->overlay_settings;
1754 if (!zr->v4l_memgrab_active)
1755 zr36057_overlay(zr, 1);
1756 /* When a grab is running, the video will be
1757 * switched on when grab is finished */
1758 }
1759
1760 /* Make sure the changes come into effect */
1761 return wait_grab_pending(zr);
1762}
1763
1764#ifdef HAVE_V4L2
1765 /* get the status of a buffer in the clients buffer queue */
1766static int
1767zoran_v4l2_buffer_status (struct file *file,
1768 struct v4l2_buffer *buf,
1769 int num)
1770{
1771 struct zoran_fh *fh = file->private_data;
1772 struct zoran *zr = fh->zr;
1773
1774 buf->flags = V4L2_BUF_FLAG_MAPPED;
1775
1776 switch (fh->map_mode) {
1777 case ZORAN_MAP_MODE_RAW:
1778
1779 /* check range */
1780 if (num < 0 || num >= fh->v4l_buffers.num_buffers ||
1781 !fh->v4l_buffers.allocated) {
1782 dprintk(1,
1783 KERN_ERR
1784 "%s: v4l2_buffer_status() - wrong number or buffers not allocated\n",
1785 ZR_DEVNAME(zr));
1786 return -EINVAL;
1787 }
1788
1789 buf->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1790 buf->length = fh->v4l_buffers.buffer_size;
1791
1792 /* get buffer */
1793 buf->bytesused = fh->v4l_buffers.buffer[num].bs.length;
1794 if (fh->v4l_buffers.buffer[num].state == BUZ_STATE_DONE ||
1795 fh->v4l_buffers.buffer[num].state == BUZ_STATE_USER) {
1796 buf->sequence = fh->v4l_buffers.buffer[num].bs.seq;
1797 buf->flags |= V4L2_BUF_FLAG_DONE;
1798 buf->timestamp =
1799 fh->v4l_buffers.buffer[num].bs.timestamp;
1800 } else {
1801 buf->flags |= V4L2_BUF_FLAG_QUEUED;
1802 }
1803
1804 if (fh->v4l_settings.height <= BUZ_MAX_HEIGHT / 2)
1805 buf->field = V4L2_FIELD_TOP;
1806 else
1807 buf->field = V4L2_FIELD_INTERLACED;
1808
1809 break;
1810
1811 case ZORAN_MAP_MODE_JPG_REC:
1812 case ZORAN_MAP_MODE_JPG_PLAY:
1813
1814 /* check range */
1815 if (num < 0 || num >= fh->jpg_buffers.num_buffers ||
1816 !fh->jpg_buffers.allocated) {
1817 dprintk(1,
1818 KERN_ERR
1819 "%s: v4l2_buffer_status() - wrong number or buffers not allocated\n",
1820 ZR_DEVNAME(zr));
1821 return -EINVAL;
1822 }
1823
1824 buf->type = (fh->map_mode == ZORAN_MAP_MODE_JPG_REC) ?
1825 V4L2_BUF_TYPE_VIDEO_CAPTURE :
1826 V4L2_BUF_TYPE_VIDEO_OUTPUT;
1827 buf->length = fh->jpg_buffers.buffer_size;
1828
1829 /* these variables are only written after frame has been captured */
1830 if (fh->jpg_buffers.buffer[num].state == BUZ_STATE_DONE ||
1831 fh->jpg_buffers.buffer[num].state == BUZ_STATE_USER) {
1832 buf->sequence = fh->jpg_buffers.buffer[num].bs.seq;
1833 buf->timestamp =
1834 fh->jpg_buffers.buffer[num].bs.timestamp;
1835 buf->bytesused =
1836 fh->jpg_buffers.buffer[num].bs.length;
1837 buf->flags |= V4L2_BUF_FLAG_DONE;
1838 } else {
1839 buf->flags |= V4L2_BUF_FLAG_QUEUED;
1840 }
1841
1842 /* which fields are these? */
1843 if (fh->jpg_settings.TmpDcm != 1)
1844 buf->field =
1845 fh->jpg_settings.
1846 odd_even ? V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM;
1847 else
1848 buf->field =
1849 fh->jpg_settings.
1850 odd_even ? V4L2_FIELD_SEQ_TB :
1851 V4L2_FIELD_SEQ_BT;
1852
1853 break;
1854
1855 default:
1856
1857 dprintk(5,
1858 KERN_ERR
1859 "%s: v4l2_buffer_status() - invalid buffer type|map_mode (%d|%d)\n",
1860 ZR_DEVNAME(zr), buf->type, fh->map_mode);
1861 return -EINVAL;
1862 }
1863
1864 buf->memory = V4L2_MEMORY_MMAP;
1865 buf->index = num;
1866 buf->m.offset = buf->length * num;
1867
1868 return 0;
1869}
1870#endif
1871
1872static int
1873zoran_set_norm (struct zoran *zr,
1874 int norm) /* VIDEO_MODE_* */
1875{
1876 int norm_encoder, on;
1877
1878 if (zr->v4l_buffers.active != ZORAN_FREE ||
1879 zr->jpg_buffers.active != ZORAN_FREE) {
1880 dprintk(1,
1881 KERN_WARNING
1882 "%s: set_norm() called while in playback/capture mode\n",
1883 ZR_DEVNAME(zr));
1884 return -EBUSY;
1885 }
1886
1887 if (lock_norm && norm != zr->norm) {
1888 if (lock_norm > 1) {
1889 dprintk(1,
1890 KERN_WARNING
1891 "%s: set_norm() - TV standard is locked, can not switch norm\n",
1892 ZR_DEVNAME(zr));
1893 return -EPERM;
1894 } else {
1895 dprintk(1,
1896 KERN_WARNING
1897 "%s: set_norm() - TV standard is locked, norm was not changed\n",
1898 ZR_DEVNAME(zr));
1899 norm = zr->norm;
1900 }
1901 }
1902
1903 if (norm != VIDEO_MODE_AUTO &&
1904 (norm < 0 || norm >= zr->card.norms ||
1905 !zr->card.tvn[norm])) {
1906 dprintk(1,
1907 KERN_ERR "%s: set_norm() - unsupported norm %d\n",
1908 ZR_DEVNAME(zr), norm);
1909 return -EINVAL;
1910 }
1911
1912 if (norm == VIDEO_MODE_AUTO) {
1913 int status;
1914
1915 /* if we have autodetect, ... */
1916 struct video_decoder_capability caps;
1917 decoder_command(zr, DECODER_GET_CAPABILITIES, &caps);
1918 if (!(caps.flags & VIDEO_DECODER_AUTO)) {
1919 dprintk(1, KERN_ERR "%s: norm=auto unsupported\n",
1920 ZR_DEVNAME(zr));
1921 return -EINVAL;
1922 }
1923
1924 decoder_command(zr, DECODER_SET_NORM, &norm);
1925
1926 /* let changes come into effect */
1927 ssleep(2);
1928
1929 decoder_command(zr, DECODER_GET_STATUS, &status);
1930 if (!(status & DECODER_STATUS_GOOD)) {
1931 dprintk(1,
1932 KERN_ERR
1933 "%s: set_norm() - no norm detected\n",
1934 ZR_DEVNAME(zr));
1935 /* reset norm */
1936 decoder_command(zr, DECODER_SET_NORM, &zr->norm);
1937 return -EIO;
1938 }
1939
1940 if (status & DECODER_STATUS_NTSC)
1941 norm = VIDEO_MODE_NTSC;
1942 else if (status & DECODER_STATUS_SECAM)
1943 norm = VIDEO_MODE_SECAM;
1944 else
1945 norm = VIDEO_MODE_PAL;
1946 }
1947 zr->timing = zr->card.tvn[norm];
1948 norm_encoder = norm;
1949
1950 /* We switch overlay off and on since a change in the
1951 * norm needs different VFE settings */
1952 on = zr->overlay_active && !zr->v4l_memgrab_active;
1953 if (on)
1954 zr36057_overlay(zr, 0);
1955
1956 decoder_command(zr, DECODER_SET_NORM, &norm);
1957 encoder_command(zr, ENCODER_SET_NORM, &norm_encoder);
1958
1959 if (on)
1960 zr36057_overlay(zr, 1);
1961
1962 /* Make sure the changes come into effect */
1963 zr->norm = norm;
1964
1965 return 0;
1966}
1967
1968static int
1969zoran_set_input (struct zoran *zr,
1970 int input)
1971{
1972 int realinput;
1973
1974 if (input == zr->input) {
1975 return 0;
1976 }
1977
1978 if (zr->v4l_buffers.active != ZORAN_FREE ||
1979 zr->jpg_buffers.active != ZORAN_FREE) {
1980 dprintk(1,
1981 KERN_WARNING
1982 "%s: set_input() called while in playback/capture mode\n",
1983 ZR_DEVNAME(zr));
1984 return -EBUSY;
1985 }
1986
1987 if (input < 0 || input >= zr->card.inputs) {
1988 dprintk(1,
1989 KERN_ERR
1990 "%s: set_input() - unnsupported input %d\n",
1991 ZR_DEVNAME(zr), input);
1992 return -EINVAL;
1993 }
1994
1995 realinput = zr->card.input[input].muxsel;
1996 zr->input = input;
1997
1998 decoder_command(zr, DECODER_SET_INPUT, &realinput);
1999
2000 return 0;
2001}
2002
2003/*
2004 * ioctl routine
2005 */
2006
2007static int
2008zoran_do_ioctl (struct inode *inode,
2009 struct file *file,
2010 unsigned int cmd,
2011 void *arg)
2012{
2013 struct zoran_fh *fh = file->private_data;
2014 struct zoran *zr = fh->zr;
2015 /* CAREFUL: used in multiple places here */
2016 struct zoran_jpg_settings settings;
2017
2018 /* we might have older buffers lying around... We don't want
2019 * to wait, but we do want to try cleaning them up ASAP. So
2020 * we try to obtain the lock and free them. If that fails, we
2021 * don't do anything and wait for the next turn. In the end,
2022 * zoran_close() or a new allocation will still free them...
2023 * This is just a 'the sooner the better' extra 'feature'
2024 *
2025 * We don't free the buffers right on munmap() because that
2026 * causes oopses (kfree() inside munmap() oopses for no
2027 * apparent reason - it's also not reproduceable in any way,
2028 * but moving the free code outside the munmap() handler fixes
2029 * all this... If someone knows why, please explain me (Ronald)
2030 */
2031 if (!down_trylock(&zr->resource_lock)) {
2032 /* we obtained it! Let's try to free some things */
2033 if (fh->jpg_buffers.ready_to_be_freed)
2034 jpg_fbuffer_free(file);
2035 if (fh->v4l_buffers.ready_to_be_freed)
2036 v4l_fbuffer_free(file);
2037
2038 up(&zr->resource_lock);
2039 }
2040
2041 switch (cmd) {
2042
2043 case VIDIOCGCAP:
2044 {
2045 struct video_capability *vcap = arg;
2046
2047 dprintk(3, KERN_DEBUG "%s: VIDIOCGCAP\n", ZR_DEVNAME(zr));
2048
2049 memset(vcap, 0, sizeof(struct video_capability));
2050 strncpy(vcap->name, ZR_DEVNAME(zr), sizeof(vcap->name));
2051 vcap->type = ZORAN_VID_TYPE;
2052
2053 vcap->channels = zr->card.inputs;
2054 vcap->audios = 0;
2055 down(&zr->resource_lock);
2056 vcap->maxwidth = BUZ_MAX_WIDTH;
2057 vcap->maxheight = BUZ_MAX_HEIGHT;
2058 vcap->minwidth = BUZ_MIN_WIDTH;
2059 vcap->minheight = BUZ_MIN_HEIGHT;
2060 up(&zr->resource_lock);
2061
2062 return 0;
2063 }
2064 break;
2065
2066 case VIDIOCGCHAN:
2067 {
2068 struct video_channel *vchan = arg;
2069 int channel = vchan->channel;
2070
2071 dprintk(3, KERN_DEBUG "%s: VIDIOCGCHAN - channel=%d\n",
2072 ZR_DEVNAME(zr), vchan->channel);
2073
2074 memset(vchan, 0, sizeof(struct video_channel));
2075 if (channel > zr->card.inputs || channel < 0) {
2076 dprintk(1,
2077 KERN_ERR
2078 "%s: VIDIOCGCHAN on not existing channel %d\n",
2079 ZR_DEVNAME(zr), channel);
2080 return -EINVAL;
2081 }
2082
2083 strcpy(vchan->name, zr->card.input[channel].name);
2084
2085 vchan->tuners = 0;
2086 vchan->flags = 0;
2087 vchan->type = VIDEO_TYPE_CAMERA;
2088 down(&zr->resource_lock);
2089 vchan->norm = zr->norm;
2090 up(&zr->resource_lock);
2091 vchan->channel = channel;
2092
2093 return 0;
2094 }
2095 break;
2096
2097 /* RJ: the documentation at http://roadrunner.swansea.linux.org.uk/v4lapi.shtml says:
2098 *
2099 * * "The VIDIOCSCHAN ioctl takes an integer argument and switches the capture to this input."
2100 * * ^^^^^^^
2101 * * The famos BTTV driver has it implemented with a struct video_channel argument
2102 * * and we follow it for compatibility reasons
2103 * *
2104 * * BTW: this is the only way the user can set the norm!
2105 */
2106
2107 case VIDIOCSCHAN:
2108 {
2109 struct video_channel *vchan = arg;
2110 int res;
2111
2112 dprintk(3,
2113 KERN_DEBUG
2114 "%s: VIDIOCSCHAN - channel=%d, norm=%d\n",
2115 ZR_DEVNAME(zr), vchan->channel, vchan->norm);
2116
2117 down(&zr->resource_lock);
2118 if ((res = zoran_set_input(zr, vchan->channel)))
2119 goto schan_unlock_and_return;
2120 if ((res = zoran_set_norm(zr, vchan->norm)))
2121 goto schan_unlock_and_return;
2122
2123 /* Make sure the changes come into effect */
2124 res = wait_grab_pending(zr);
2125 schan_unlock_and_return:
2126 up(&zr->resource_lock);
2127 return res;
2128 }
2129 break;
2130
2131 case VIDIOCGPICT:
2132 {
2133 struct video_picture *vpict = arg;
2134
2135 dprintk(3, KERN_DEBUG "%s: VIDIOCGPICT\n", ZR_DEVNAME(zr));
2136
2137 memset(vpict, 0, sizeof(struct video_picture));
2138 down(&zr->resource_lock);
2139 vpict->hue = zr->hue;
2140 vpict->brightness = zr->brightness;
2141 vpict->contrast = zr->contrast;
2142 vpict->colour = zr->saturation;
2143 if (fh->overlay_settings.format) {
2144 vpict->depth = fh->overlay_settings.format->depth;
2145 vpict->palette = fh->overlay_settings.format->palette;
2146 } else {
2147 vpict->depth = 0;
2148 }
2149 up(&zr->resource_lock);
2150
2151 return 0;
2152 }
2153 break;
2154
2155 case VIDIOCSPICT:
2156 {
2157 struct video_picture *vpict = arg;
2158 int i;
2159
2160 dprintk(3,
2161 KERN_DEBUG
2162 "%s: VIDIOCSPICT - bri=%d, hue=%d, col=%d, con=%d, dep=%d, pal=%d\n",
2163 ZR_DEVNAME(zr), vpict->brightness, vpict->hue,
2164 vpict->colour, vpict->contrast, vpict->depth,
2165 vpict->palette);
2166
2167 for (i = 0; i < zoran_num_formats; i++) {
2168 const struct zoran_format *fmt = &zoran_formats[i];
2169
2170 if (fmt->palette != -1 &&
2171 fmt->flags & ZORAN_FORMAT_OVERLAY &&
2172 fmt->palette == vpict->palette &&
2173 fmt->depth == vpict->depth)
2174 break;
2175 }
2176 if (i == zoran_num_formats) {
2177 dprintk(1,
2178 KERN_ERR
2179 "%s: VIDIOCSPICT - Invalid palette %d\n",
2180 ZR_DEVNAME(zr), vpict->palette);
2181 return -EINVAL;
2182 }
2183
2184 down(&zr->resource_lock);
2185
2186 decoder_command(zr, DECODER_SET_PICTURE, vpict);
2187
2188 zr->hue = vpict->hue;
2189 zr->contrast = vpict->contrast;
2190 zr->saturation = vpict->colour;
2191 zr->brightness = vpict->brightness;
2192
2193 fh->overlay_settings.format = &zoran_formats[i];
2194
2195 up(&zr->resource_lock);
2196
2197 return 0;
2198 }
2199 break;
2200
2201 case VIDIOCCAPTURE:
2202 {
2203 int *on = arg, res;
2204
2205 dprintk(3, KERN_DEBUG "%s: VIDIOCCAPTURE - on=%d\n",
2206 ZR_DEVNAME(zr), *on);
2207
2208 down(&zr->resource_lock);
2209 res = setup_overlay(file, *on);
2210 up(&zr->resource_lock);
2211
2212 return res;
2213 }
2214 break;
2215
2216 case VIDIOCGWIN:
2217 {
2218 struct video_window *vwin = arg;
2219
2220 dprintk(3, KERN_DEBUG "%s: VIDIOCGWIN\n", ZR_DEVNAME(zr));
2221
2222 memset(vwin, 0, sizeof(struct video_window));
2223 down(&zr->resource_lock);
2224 vwin->x = fh->overlay_settings.x;
2225 vwin->y = fh->overlay_settings.y;
2226 vwin->width = fh->overlay_settings.width;
2227 vwin->height = fh->overlay_settings.height;
2228 up(&zr->resource_lock);
2229 vwin->clipcount = 0;
2230 return 0;
2231 }
2232 break;
2233
2234 case VIDIOCSWIN:
2235 {
2236 struct video_window *vwin = arg;
2237 int res;
2238
2239 dprintk(3,
2240 KERN_DEBUG
2241 "%s: VIDIOCSWIN - x=%d, y=%d, w=%d, h=%d, clipcount=%d\n",
2242 ZR_DEVNAME(zr), vwin->x, vwin->y, vwin->width,
2243 vwin->height, vwin->clipcount);
2244
2245 down(&zr->resource_lock);
2246 res =
2247 setup_window(file, vwin->x, vwin->y, vwin->width,
2248 vwin->height, vwin->clips,
2249 vwin->clipcount, NULL);
2250 up(&zr->resource_lock);
2251
2252 return res;
2253 }
2254 break;
2255
2256 case VIDIOCGFBUF:
2257 {
2258 struct video_buffer *vbuf = arg;
2259
2260 dprintk(3, KERN_DEBUG "%s: VIDIOCGFBUF\n", ZR_DEVNAME(zr));
2261
2262 down(&zr->resource_lock);
2263 *vbuf = zr->buffer;
2264 up(&zr->resource_lock);
2265 return 0;
2266 }
2267 break;
2268
2269 case VIDIOCSFBUF:
2270 {
2271 struct video_buffer *vbuf = arg;
2272 int i, res = 0;
2273
2274 dprintk(3,
2275 KERN_DEBUG
2276 "%s: VIDIOCSFBUF - base=%p, w=%d, h=%d, depth=%d, bpl=%d\n",
2277 ZR_DEVNAME(zr), vbuf->base, vbuf->width,
2278 vbuf->height, vbuf->depth, vbuf->bytesperline);
2279
2280 for (i = 0; i < zoran_num_formats; i++)
2281 if (zoran_formats[i].depth == vbuf->depth)
2282 break;
2283 if (i == zoran_num_formats) {
2284 dprintk(1,
2285 KERN_ERR
2286 "%s: VIDIOCSFBUF - invalid fbuf depth %d\n",
2287 ZR_DEVNAME(zr), vbuf->depth);
2288 return -EINVAL;
2289 }
2290
2291 down(&zr->resource_lock);
2292 res =
2293 setup_fbuffer(file, vbuf->base, &zoran_formats[i],
2294 vbuf->width, vbuf->height,
2295 vbuf->bytesperline);
2296 up(&zr->resource_lock);
2297
2298 return res;
2299 }
2300 break;
2301
2302 case VIDIOCSYNC:
2303 {
2304 int *frame = arg, res;
2305
2306 dprintk(3, KERN_DEBUG "%s: VIDIOCSYNC - frame=%d\n",
2307 ZR_DEVNAME(zr), *frame);
2308
2309 down(&zr->resource_lock);
2310 res = v4l_sync(file, *frame);
2311 up(&zr->resource_lock);
2312 if (!res)
2313 zr->v4l_sync_tail++;
2314 return res;
2315 }
2316 break;
2317
2318 case VIDIOCMCAPTURE:
2319 {
2320 struct video_mmap *vmap = arg;
2321 int res;
2322
2323 dprintk(3,
2324 KERN_DEBUG
2325 "%s: VIDIOCMCAPTURE - frame=%d, geom=%dx%d, fmt=%d\n",
2326 ZR_DEVNAME(zr), vmap->frame, vmap->width, vmap->height,
2327 vmap->format);
2328
2329 down(&zr->resource_lock);
2330 res = v4l_grab(file, vmap);
2331 up(&zr->resource_lock);
2332 return res;
2333 }
2334 break;
2335
2336 case VIDIOCGMBUF:
2337 {
2338 struct video_mbuf *vmbuf = arg;
2339 int i, res = 0;
2340
2341 dprintk(3, KERN_DEBUG "%s: VIDIOCGMBUF\n", ZR_DEVNAME(zr));
2342
2343 vmbuf->size =
2344 fh->v4l_buffers.num_buffers *
2345 fh->v4l_buffers.buffer_size;
2346 vmbuf->frames = fh->v4l_buffers.num_buffers;
2347 for (i = 0; i < vmbuf->frames; i++) {
2348 vmbuf->offsets[i] =
2349 i * fh->v4l_buffers.buffer_size;
2350 }
2351
2352 down(&zr->resource_lock);
2353
2354 if (fh->jpg_buffers.allocated || fh->v4l_buffers.allocated) {
2355 dprintk(1,
2356 KERN_ERR
2357 "%s: VIDIOCGMBUF - buffers already allocated\n",
2358 ZR_DEVNAME(zr));
2359 res = -EINVAL;
2360 goto v4l1reqbuf_unlock_and_return;
2361 }
2362
2363 if (v4l_fbuffer_alloc(file)) {
2364 res = -ENOMEM;
2365 goto v4l1reqbuf_unlock_and_return;
2366 }
2367
2368 /* The next mmap will map the V4L buffers */
2369 fh->map_mode = ZORAN_MAP_MODE_RAW;
2370 v4l1reqbuf_unlock_and_return:
2371 up(&zr->resource_lock);
2372
2373 return res;
2374 }
2375 break;
2376
2377 case VIDIOCGUNIT:
2378 {
2379 struct video_unit *vunit = arg;
2380
2381 dprintk(3, KERN_DEBUG "%s: VIDIOCGUNIT\n", ZR_DEVNAME(zr));
2382
2383 vunit->video = zr->video_dev->minor;
2384 vunit->vbi = VIDEO_NO_UNIT;
2385 vunit->radio = VIDEO_NO_UNIT;
2386 vunit->audio = VIDEO_NO_UNIT;
2387 vunit->teletext = VIDEO_NO_UNIT;
2388
2389 return 0;
2390 }
2391 break;
2392
2393 /*
2394 * RJ: In principal we could support subcaptures for V4L grabbing.
2395 * Not even the famous BTTV driver has them, however.
2396 * If there should be a strong demand, one could consider
2397 * to implement them.
2398 */
2399 case VIDIOCGCAPTURE:
2400 {
2401 dprintk(3, KERN_ERR "%s: VIDIOCGCAPTURE not supported\n",
2402 ZR_DEVNAME(zr));
2403 return -EINVAL;
2404 }
2405 break;
2406
2407 case VIDIOCSCAPTURE:
2408 {
2409 dprintk(3, KERN_ERR "%s: VIDIOCSCAPTURE not supported\n",
2410 ZR_DEVNAME(zr));
2411 return -EINVAL;
2412 }
2413 break;
2414
2415 case BUZIOC_G_PARAMS:
2416 {
2417 struct zoran_params *bparams = arg;
2418
2419 dprintk(3, KERN_DEBUG "%s: BUZIOC_G_PARAMS\n", ZR_DEVNAME(zr));
2420
2421 memset(bparams, 0, sizeof(struct zoran_params));
2422 bparams->major_version = MAJOR_VERSION;
2423 bparams->minor_version = MINOR_VERSION;
2424
2425 down(&zr->resource_lock);
2426
2427 bparams->norm = zr->norm;
2428 bparams->input = zr->input;
2429
2430 bparams->decimation = fh->jpg_settings.decimation;
2431 bparams->HorDcm = fh->jpg_settings.HorDcm;
2432 bparams->VerDcm = fh->jpg_settings.VerDcm;
2433 bparams->TmpDcm = fh->jpg_settings.TmpDcm;
2434 bparams->field_per_buff = fh->jpg_settings.field_per_buff;
2435 bparams->img_x = fh->jpg_settings.img_x;
2436 bparams->img_y = fh->jpg_settings.img_y;
2437 bparams->img_width = fh->jpg_settings.img_width;
2438 bparams->img_height = fh->jpg_settings.img_height;
2439 bparams->odd_even = fh->jpg_settings.odd_even;
2440
2441 bparams->quality = fh->jpg_settings.jpg_comp.quality;
2442 bparams->APPn = fh->jpg_settings.jpg_comp.APPn;
2443 bparams->APP_len = fh->jpg_settings.jpg_comp.APP_len;
2444 memcpy(bparams->APP_data,
2445 fh->jpg_settings.jpg_comp.APP_data,
2446 sizeof(bparams->APP_data));
2447 bparams->COM_len = zr->jpg_settings.jpg_comp.COM_len;
2448 memcpy(bparams->COM_data,
2449 fh->jpg_settings.jpg_comp.COM_data,
2450 sizeof(bparams->COM_data));
2451 bparams->jpeg_markers =
2452 fh->jpg_settings.jpg_comp.jpeg_markers;
2453
2454 up(&zr->resource_lock);
2455
2456 bparams->VFIFO_FB = 0;
2457
2458 return 0;
2459 }
2460 break;
2461
2462 case BUZIOC_S_PARAMS:
2463 {
2464 struct zoran_params *bparams = arg;
2465 int res = 0;
2466
2467 dprintk(3, KERN_DEBUG "%s: BUZIOC_S_PARAMS\n", ZR_DEVNAME(zr));
2468
2469 settings.decimation = bparams->decimation;
2470 settings.HorDcm = bparams->HorDcm;
2471 settings.VerDcm = bparams->VerDcm;
2472 settings.TmpDcm = bparams->TmpDcm;
2473 settings.field_per_buff = bparams->field_per_buff;
2474 settings.img_x = bparams->img_x;
2475 settings.img_y = bparams->img_y;
2476 settings.img_width = bparams->img_width;
2477 settings.img_height = bparams->img_height;
2478 settings.odd_even = bparams->odd_even;
2479
2480 settings.jpg_comp.quality = bparams->quality;
2481 settings.jpg_comp.APPn = bparams->APPn;
2482 settings.jpg_comp.APP_len = bparams->APP_len;
2483 memcpy(settings.jpg_comp.APP_data, bparams->APP_data,
2484 sizeof(bparams->APP_data));
2485 settings.jpg_comp.COM_len = bparams->COM_len;
2486 memcpy(settings.jpg_comp.COM_data, bparams->COM_data,
2487 sizeof(bparams->COM_data));
2488 settings.jpg_comp.jpeg_markers = bparams->jpeg_markers;
2489
2490 down(&zr->resource_lock);
2491
2492 if (zr->codec_mode != BUZ_MODE_IDLE) {
2493 dprintk(1,
2494 KERN_ERR
2495 "%s: BUZIOC_S_PARAMS called, but Buz in capture/playback mode\n",
2496 ZR_DEVNAME(zr));
2497 res = -EINVAL;
2498 goto sparams_unlock_and_return;
2499 }
2500
2501 /* Check the params first before overwriting our
2502 * nternal values */
2503 if (zoran_check_jpg_settings(zr, &settings)) {
2504 res = -EINVAL;
2505 goto sparams_unlock_and_return;
2506 }
2507
2508 fh->jpg_settings = settings;
2509 sparams_unlock_and_return:
2510 up(&zr->resource_lock);
2511
2512 return res;
2513 }
2514 break;
2515
2516 case BUZIOC_REQBUFS:
2517 {
2518 struct zoran_requestbuffers *breq = arg;
2519 int res = 0;
2520
2521 dprintk(3,
2522 KERN_DEBUG
2523 "%s: BUZIOC_REQBUFS - count=%lu, size=%lu\n",
2524 ZR_DEVNAME(zr), breq->count, breq->size);
2525
2526 /* Enforce reasonable lower and upper limits */
2527 if (breq->count < 4)
2528 breq->count = 4; /* Could be choosen smaller */
2529 if (breq->count > jpg_nbufs)
2530 breq->count = jpg_nbufs;
2531 breq->size = PAGE_ALIGN(breq->size);
2532 if (breq->size < 8192)
2533 breq->size = 8192; /* Arbitrary */
2534 /* breq->size is limited by 1 page for the stat_com
2535 * tables to a Maximum of 2 MB */
2536 if (breq->size > jpg_bufsize)
2537 breq->size = jpg_bufsize;
2538 if (fh->jpg_buffers.need_contiguous &&
2539 breq->size > MAX_KMALLOC_MEM)
2540 breq->size = MAX_KMALLOC_MEM;
2541
2542 down(&zr->resource_lock);
2543
2544 if (fh->jpg_buffers.allocated || fh->v4l_buffers.allocated) {
2545 dprintk(1,
2546 KERN_ERR
2547 "%s: BUZIOC_REQBUFS - buffers allready allocated\n",
2548 ZR_DEVNAME(zr));
2549 res = -EBUSY;
2550 goto jpgreqbuf_unlock_and_return;
2551 }
2552
2553 fh->jpg_buffers.num_buffers = breq->count;
2554 fh->jpg_buffers.buffer_size = breq->size;
2555
2556 if (jpg_fbuffer_alloc(file)) {
2557 res = -ENOMEM;
2558 goto jpgreqbuf_unlock_and_return;
2559 }
2560
2561 /* The next mmap will map the MJPEG buffers - could
2562 * also be *_PLAY, but it doesn't matter here */
2563 fh->map_mode = ZORAN_MAP_MODE_JPG_REC;
2564 jpgreqbuf_unlock_and_return:
2565 up(&zr->resource_lock);
2566
2567 return res;
2568 }
2569 break;
2570
2571 case BUZIOC_QBUF_CAPT:
2572 {
2573 int *frame = arg, res;
2574
2575 dprintk(3, KERN_DEBUG "%s: BUZIOC_QBUF_CAPT - frame=%d\n",
2576 ZR_DEVNAME(zr), *frame);
2577
2578 down(&zr->resource_lock);
2579 res = jpg_qbuf(file, *frame, BUZ_MODE_MOTION_COMPRESS);
2580 up(&zr->resource_lock);
2581
2582 return res;
2583 }
2584 break;
2585
2586 case BUZIOC_QBUF_PLAY:
2587 {
2588 int *frame = arg, res;
2589
2590 dprintk(3, KERN_DEBUG "%s: BUZIOC_QBUF_PLAY - frame=%d\n",
2591 ZR_DEVNAME(zr), *frame);
2592
2593 down(&zr->resource_lock);
2594 res = jpg_qbuf(file, *frame, BUZ_MODE_MOTION_DECOMPRESS);
2595 up(&zr->resource_lock);
2596
2597 return res;
2598 }
2599 break;
2600
2601 case BUZIOC_SYNC:
2602 {
2603 struct zoran_sync *bsync = arg;
2604 int res;
2605
2606 dprintk(3, KERN_DEBUG "%s: BUZIOC_SYNC\n", ZR_DEVNAME(zr));
2607
2608 down(&zr->resource_lock);
2609 res = jpg_sync(file, bsync);
2610 up(&zr->resource_lock);
2611
2612 return res;
2613 }
2614 break;
2615
2616 case BUZIOC_G_STATUS:
2617 {
2618 struct zoran_status *bstat = arg;
2619 int norm, input, status, res = 0;
2620
2621 dprintk(3, KERN_DEBUG "%s: BUZIOC_G_STATUS\n", ZR_DEVNAME(zr));
2622
2623 if (zr->codec_mode != BUZ_MODE_IDLE) {
2624 dprintk(1,
2625 KERN_ERR
2626 "%s: BUZIOC_G_STATUS called but Buz in capture/playback mode\n",
2627 ZR_DEVNAME(zr));
2628 return -EINVAL;
2629 }
2630
2631 input = zr->card.input[bstat->input].muxsel;
2632 norm = VIDEO_MODE_AUTO;
2633
2634 down(&zr->resource_lock);
2635
2636 if (zr->codec_mode != BUZ_MODE_IDLE) {
2637 dprintk(1,
2638 KERN_ERR
2639 "%s: BUZIOC_G_STATUS called, but Buz in capture/playback mode\n",
2640 ZR_DEVNAME(zr));
2641 res = -EINVAL;
2642 goto gstat_unlock_and_return;
2643 }
2644
2645 decoder_command(zr, DECODER_SET_INPUT, &input);
2646 decoder_command(zr, DECODER_SET_NORM, &norm);
2647
2648 /* sleep 1 second */
2649 ssleep(1);
2650
2651 /* Get status of video decoder */
2652 decoder_command(zr, DECODER_GET_STATUS, &status);
2653
2654 /* restore previous input and norm */
2655 input = zr->card.input[zr->input].muxsel;
2656 decoder_command(zr, DECODER_SET_INPUT, &input);
2657 decoder_command(zr, DECODER_SET_NORM, &zr->norm);
2658 gstat_unlock_and_return:
2659 up(&zr->resource_lock);
2660
2661 if (!res) {
2662 bstat->signal =
2663 (status & DECODER_STATUS_GOOD) ? 1 : 0;
2664 if (status & DECODER_STATUS_NTSC)
2665 bstat->norm = VIDEO_MODE_NTSC;
2666 else if (status & DECODER_STATUS_SECAM)
2667 bstat->norm = VIDEO_MODE_SECAM;
2668 else
2669 bstat->norm = VIDEO_MODE_PAL;
2670
2671 bstat->color =
2672 (status & DECODER_STATUS_COLOR) ? 1 : 0;
2673 }
2674
2675 return res;
2676 }
2677 break;
2678
2679#ifdef HAVE_V4L2
2680
2681 /* The new video4linux2 capture interface - much nicer than video4linux1, since
2682 * it allows for integrating the JPEG capturing calls inside standard v4l2
2683 */
2684
2685 case VIDIOC_QUERYCAP:
2686 {
2687 struct v4l2_capability *cap = arg;
2688
2689 dprintk(3, KERN_DEBUG "%s: VIDIOC_QUERYCAP\n", ZR_DEVNAME(zr));
2690
2691 memset(cap, 0, sizeof(*cap));
2692 strncpy(cap->card, ZR_DEVNAME(zr), sizeof(cap->card));
2693 strncpy(cap->driver, "zoran", sizeof(cap->driver));
2694 snprintf(cap->bus_info, sizeof(cap->bus_info), "PCI:%s",
2695 pci_name(zr->pci_dev));
2696 cap->version =
2697 KERNEL_VERSION(MAJOR_VERSION, MINOR_VERSION,
2698 RELEASE_VERSION);
2699 cap->capabilities = ZORAN_V4L2_VID_FLAGS;
2700
2701 return 0;
2702 }
2703 break;
2704
2705 case VIDIOC_ENUM_FMT:
2706 {
2707 struct v4l2_fmtdesc *fmt = arg;
2708 int index = fmt->index, num = -1, i, flag = 0, type =
2709 fmt->type;
2710
2711 dprintk(3, KERN_DEBUG "%s: VIDIOC_ENUM_FMT - index=%d\n",
2712 ZR_DEVNAME(zr), fmt->index);
2713
2714 switch (fmt->type) {
2715 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
2716 flag = ZORAN_FORMAT_CAPTURE;
2717 break;
2718 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
2719 flag = ZORAN_FORMAT_PLAYBACK;
2720 break;
2721 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
2722 flag = ZORAN_FORMAT_OVERLAY;
2723 break;
2724 default:
2725 dprintk(1,
2726 KERN_ERR
2727 "%s: VIDIOC_ENUM_FMT - unknown type %d\n",
2728 ZR_DEVNAME(zr), fmt->type);
2729 return -EINVAL;
2730 }
2731
2732 for (i = 0; i < zoran_num_formats; i++) {
2733 if (zoran_formats[i].flags & flag)
2734 num++;
2735 if (num == fmt->index)
2736 break;
2737 }
2738 if (fmt->index < 0 /* late, but not too late */ ||
2739 i == zoran_num_formats)
2740 return -EINVAL;
2741
2742 memset(fmt, 0, sizeof(*fmt));
2743 fmt->index = index;
2744 fmt->type = type;
2745 strncpy(fmt->description, zoran_formats[i].name, 31);
2746 fmt->pixelformat = zoran_formats[i].fourcc;
2747 if (zoran_formats[i].flags & ZORAN_FORMAT_COMPRESSED)
2748 fmt->flags |= V4L2_FMT_FLAG_COMPRESSED;
2749
2750 return 0;
2751 }
2752 break;
2753
2754 case VIDIOC_G_FMT:
2755 {
2756 struct v4l2_format *fmt = arg;
2757 int type = fmt->type;
2758
2759 dprintk(5, KERN_DEBUG "%s: VIDIOC_G_FMT\n", ZR_DEVNAME(zr));
2760
2761 memset(fmt, 0, sizeof(*fmt));
2762 fmt->type = type;
2763
2764 switch (fmt->type) {
2765 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
2766
2767 down(&zr->resource_lock);
2768
2769 fmt->fmt.win.w.left = fh->overlay_settings.x;
2770 fmt->fmt.win.w.top = fh->overlay_settings.y;
2771 fmt->fmt.win.w.width = fh->overlay_settings.width;
2772 fmt->fmt.win.w.height =
2773 fh->overlay_settings.height;
2774 if (fh->overlay_settings.width * 2 >
2775 BUZ_MAX_HEIGHT)
2776 fmt->fmt.win.field = V4L2_FIELD_INTERLACED;
2777 else
2778 fmt->fmt.win.field = V4L2_FIELD_TOP;
2779
2780 up(&zr->resource_lock);
2781
2782 break;
2783
2784 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
2785 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
2786
2787 down(&zr->resource_lock);
2788
2789 if (fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE &&
2790 fh->map_mode == ZORAN_MAP_MODE_RAW) {
2791
2792 fmt->fmt.pix.width =
2793 fh->v4l_settings.width;
2794 fmt->fmt.pix.height =
2795 fh->v4l_settings.height;
2796 fmt->fmt.pix.sizeimage =
2797 fh->v4l_buffers.buffer_size;
2798 fmt->fmt.pix.pixelformat =
2799 fh->v4l_settings.format->fourcc;
2800 fmt->fmt.pix.colorspace =
2801 fh->v4l_settings.format->colorspace;
2802 fmt->fmt.pix.bytesperline = 0;
2803 if (BUZ_MAX_HEIGHT <
2804 (fh->v4l_settings.height * 2))
2805 fmt->fmt.pix.field =
2806 V4L2_FIELD_INTERLACED;
2807 else
2808 fmt->fmt.pix.field =
2809 V4L2_FIELD_TOP;
2810
2811 } else {
2812
2813 fmt->fmt.pix.width =
2814 fh->jpg_settings.img_width /
2815 fh->jpg_settings.HorDcm;
2816 fmt->fmt.pix.height =
2817 fh->jpg_settings.img_height /
2818 (fh->jpg_settings.VerDcm *
2819 fh->jpg_settings.TmpDcm);
2820 fmt->fmt.pix.sizeimage =
2821 zoran_v4l2_calc_bufsize(&fh->
2822 jpg_settings);
2823 fmt->fmt.pix.pixelformat =
2824 V4L2_PIX_FMT_MJPEG;
2825 if (fh->jpg_settings.TmpDcm == 1)
2826 fmt->fmt.pix.field =
2827 (fh->jpg_settings.
2828 odd_even ? V4L2_FIELD_SEQ_BT :
2829 V4L2_FIELD_SEQ_BT);
2830 else
2831 fmt->fmt.pix.field =
2832 (fh->jpg_settings.
2833 odd_even ? V4L2_FIELD_TOP :
2834 V4L2_FIELD_BOTTOM);
2835
2836 fmt->fmt.pix.bytesperline = 0;
2837 fmt->fmt.pix.colorspace =
2838 V4L2_COLORSPACE_SMPTE170M;
2839 }
2840
2841 up(&zr->resource_lock);
2842
2843 break;
2844
2845 default:
2846 dprintk(1,
2847 KERN_ERR
2848 "%s: VIDIOC_G_FMT - unsupported type %d\n",
2849 ZR_DEVNAME(zr), fmt->type);
2850 return -EINVAL;
2851 }
2852 return 0;
2853 }
2854 break;
2855
2856 case VIDIOC_S_FMT:
2857 {
2858 struct v4l2_format *fmt = arg;
2859 int i, res = 0;
2860 __u32 printformat;
2861
2862 dprintk(3, KERN_DEBUG "%s: VIDIOC_S_FMT - type=%d, ",
2863 ZR_DEVNAME(zr), fmt->type);
2864
2865 switch (fmt->type) {
2866 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
2867
2868 dprintk(3, "x=%d, y=%d, w=%d, h=%d, cnt=%d, map=0x%p\n",
2869 fmt->fmt.win.w.left, fmt->fmt.win.w.top,
2870 fmt->fmt.win.w.width,
2871 fmt->fmt.win.w.height,
2872 fmt->fmt.win.clipcount,
2873 fmt->fmt.win.bitmap);
2874 down(&zr->resource_lock);
2875 res =
2876 setup_window(file, fmt->fmt.win.w.left,
2877 fmt->fmt.win.w.top,
2878 fmt->fmt.win.w.width,
2879 fmt->fmt.win.w.height,
2880 (struct video_clip __user *)
2881 fmt->fmt.win.clips,
2882 fmt->fmt.win.clipcount,
2883 fmt->fmt.win.bitmap);
2884 up(&zr->resource_lock);
2885 return res;
2886 break;
2887
2888 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
2889 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
2890
2891 printformat =
2892 __cpu_to_le32(fmt->fmt.pix.pixelformat);
2893 dprintk(3, "size=%dx%d, fmt=0x%x (%4.4s)\n",
2894 fmt->fmt.pix.width, fmt->fmt.pix.height,
2895 fmt->fmt.pix.pixelformat,
2896 (char *) &printformat);
2897
2898 if (fmt->fmt.pix.bytesperline > 0) {
2899 dprintk(5,
2900 KERN_ERR "%s: bpl not supported\n",
2901 ZR_DEVNAME(zr));
2902 return -EINVAL;
2903 }
2904
2905 /* we can be requested to do JPEG/raw playback/capture */
2906 if (!
2907 (fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE ||
2908 (fmt->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
2909 fmt->fmt.pix.pixelformat ==
2910 V4L2_PIX_FMT_MJPEG))) {
2911 dprintk(1,
2912 KERN_ERR
2913 "%s: VIDIOC_S_FMT - unknown type %d/0x%x(%4.4s) combination\n",
2914 ZR_DEVNAME(zr), fmt->type,
2915 fmt->fmt.pix.pixelformat,
2916 (char *) &printformat);
2917 return -EINVAL;
2918 }
2919
2920 if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG) {
2921 down(&zr->resource_lock);
2922
2923 settings = fh->jpg_settings;
2924
2925 if (fh->v4l_buffers.allocated ||
2926 fh->jpg_buffers.allocated) {
2927 dprintk(1,
2928 KERN_ERR
2929 "%s: VIDIOC_S_FMT - cannot change capture mode\n",
2930 ZR_DEVNAME(zr));
2931 res = -EBUSY;
2932 goto sfmtjpg_unlock_and_return;
2933 }
2934
2935 /* we actually need to set 'real' parameters now */
2936 if ((fmt->fmt.pix.height * 2) >
2937 BUZ_MAX_HEIGHT)
2938 settings.TmpDcm = 1;
2939 else
2940 settings.TmpDcm = 2;
2941 settings.decimation = 0;
2942 if (fmt->fmt.pix.height <=
2943 fh->jpg_settings.img_height / 2)
2944 settings.VerDcm = 2;
2945 else
2946 settings.VerDcm = 1;
2947 if (fmt->fmt.pix.width <=
2948 fh->jpg_settings.img_width / 4)
2949 settings.HorDcm = 4;
2950 else if (fmt->fmt.pix.width <=
2951 fh->jpg_settings.img_width / 2)
2952 settings.HorDcm = 2;
2953 else
2954 settings.HorDcm = 1;
2955 if (settings.TmpDcm == 1)
2956 settings.field_per_buff = 2;
2957 else
2958 settings.field_per_buff = 1;
2959
2960 /* check */
2961 if ((res =
2962 zoran_check_jpg_settings(zr,
2963 &settings)))
2964 goto sfmtjpg_unlock_and_return;
2965
2966 /* it's ok, so set them */
2967 fh->jpg_settings = settings;
2968
2969 /* tell the user what we actually did */
2970 fmt->fmt.pix.width =
2971 settings.img_width / settings.HorDcm;
2972 fmt->fmt.pix.height =
2973 settings.img_height * 2 /
2974 (settings.TmpDcm * settings.VerDcm);
2975 if (settings.TmpDcm == 1)
2976 fmt->fmt.pix.field =
2977 (fh->jpg_settings.
2978 odd_even ? V4L2_FIELD_SEQ_TB :
2979 V4L2_FIELD_SEQ_BT);
2980 else
2981 fmt->fmt.pix.field =
2982 (fh->jpg_settings.
2983 odd_even ? V4L2_FIELD_TOP :
2984 V4L2_FIELD_BOTTOM);
2985 fh->jpg_buffers.buffer_size =
2986 zoran_v4l2_calc_bufsize(&fh->
2987 jpg_settings);
2988 fmt->fmt.pix.sizeimage =
2989 fh->jpg_buffers.buffer_size;
2990
2991 /* we hereby abuse this variable to show that
2992 * we're gonna do mjpeg capture */
2993 fh->map_mode =
2994 (fmt->type ==
2995 V4L2_BUF_TYPE_VIDEO_CAPTURE) ?
2996 ZORAN_MAP_MODE_JPG_REC :
2997 ZORAN_MAP_MODE_JPG_PLAY;
2998 sfmtjpg_unlock_and_return:
2999 up(&zr->resource_lock);
3000 } else {
3001 for (i = 0; i < zoran_num_formats; i++)
3002 if (fmt->fmt.pix.pixelformat ==
3003 zoran_formats[i].fourcc)
3004 break;
3005 if (i == zoran_num_formats) {
3006 dprintk(1,
3007 KERN_ERR
3008 "%s: VIDIOC_S_FMT - unknown/unsupported format 0x%x (%4.4s)\n",
3009 ZR_DEVNAME(zr),
3010 fmt->fmt.pix.pixelformat,
3011 (char *) &printformat);
3012 return -EINVAL;
3013 }
3014 down(&zr->resource_lock);
3015 if (fh->jpg_buffers.allocated ||
3016 (fh->v4l_buffers.allocated &&
3017 fh->v4l_buffers.active !=
3018 ZORAN_FREE)) {
3019 dprintk(1,
3020 KERN_ERR
3021 "%s: VIDIOC_S_FMT - cannot change capture mode\n",
3022 ZR_DEVNAME(zr));
3023 res = -EBUSY;
3024 goto sfmtv4l_unlock_and_return;
3025 }
3026 if (fmt->fmt.pix.height > BUZ_MAX_HEIGHT)
3027 fmt->fmt.pix.height =
3028 BUZ_MAX_HEIGHT;
3029 if (fmt->fmt.pix.width > BUZ_MAX_WIDTH)
3030 fmt->fmt.pix.width = BUZ_MAX_WIDTH;
3031
3032 if ((res =
3033 zoran_v4l_set_format(file,
3034 fmt->fmt.pix.
3035 width,
3036 fmt->fmt.pix.
3037 height,
3038 &zoran_formats
3039 [i])))
3040 goto sfmtv4l_unlock_and_return;
3041
3042 /* tell the user the
3043 * results/missing stuff */
3044 fmt->fmt.pix.sizeimage = fh->v4l_buffers.buffer_size /*zr->gbpl * zr->gheight */
3045 ;
3046 if (BUZ_MAX_HEIGHT <
3047 (fh->v4l_settings.height * 2))
3048 fmt->fmt.pix.field =
3049 V4L2_FIELD_INTERLACED;
3050 else
3051 fmt->fmt.pix.field =
3052 V4L2_FIELD_TOP;
3053
3054 fh->map_mode = ZORAN_MAP_MODE_RAW;
3055 sfmtv4l_unlock_and_return:
3056 up(&zr->resource_lock);
3057 }
3058
3059 break;
3060
3061 default:
3062 dprintk(3, "unsupported\n");
3063 dprintk(1,
3064 KERN_ERR
3065 "%s: VIDIOC_S_FMT - unsupported type %d\n",
3066 ZR_DEVNAME(zr), fmt->type);
3067 return -EINVAL;
3068 }
3069
3070 return res;
3071 }
3072 break;
3073
3074 case VIDIOC_G_FBUF:
3075 {
3076 struct v4l2_framebuffer *fb = arg;
3077
3078 dprintk(3, KERN_DEBUG "%s: VIDIOC_G_FBUF\n", ZR_DEVNAME(zr));
3079
3080 memset(fb, 0, sizeof(*fb));
3081 down(&zr->resource_lock);
3082 fb->base = zr->buffer.base;
3083 fb->fmt.width = zr->buffer.width;
3084 fb->fmt.height = zr->buffer.height;
3085 if (zr->overlay_settings.format) {
3086 fb->fmt.pixelformat =
3087 fh->overlay_settings.format->fourcc;
3088 }
3089 fb->fmt.bytesperline = zr->buffer.bytesperline;
3090 up(&zr->resource_lock);
3091 fb->fmt.colorspace = V4L2_COLORSPACE_SRGB;
3092 fb->fmt.field = V4L2_FIELD_INTERLACED;
3093 fb->flags = V4L2_FBUF_FLAG_OVERLAY;
3094 fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING;
3095
3096 return 0;
3097 }
3098 break;
3099
3100 case VIDIOC_S_FBUF:
3101 {
3102 int i, res = 0;
3103 struct v4l2_framebuffer *fb = arg;
3104 __u32 printformat = __cpu_to_le32(fb->fmt.pixelformat);
3105
3106 dprintk(3,
3107 KERN_DEBUG
3108 "%s: VIDIOC_S_FBUF - base=0x%p, size=%dx%d, bpl=%d, fmt=0x%x (%4.4s)\n",
3109 ZR_DEVNAME(zr), fb->base, fb->fmt.width, fb->fmt.height,
3110 fb->fmt.bytesperline, fb->fmt.pixelformat,
3111 (char *) &printformat);
3112
3113 for (i = 0; i < zoran_num_formats; i++)
3114 if (zoran_formats[i].fourcc == fb->fmt.pixelformat)
3115 break;
3116 if (i == zoran_num_formats) {
3117 dprintk(1,
3118 KERN_ERR
3119 "%s: VIDIOC_S_FBUF - format=0x%x (%4.4s) not allowed\n",
3120 ZR_DEVNAME(zr), fb->fmt.pixelformat,
3121 (char *) &printformat);
3122 return -EINVAL;
3123 }
3124
3125 down(&zr->resource_lock);
3126 res =
3127 setup_fbuffer(file, fb->base, &zoran_formats[i],
3128 fb->fmt.width, fb->fmt.height,
3129 fb->fmt.bytesperline);
3130 up(&zr->resource_lock);
3131
3132 return res;
3133 }
3134 break;
3135
3136 case VIDIOC_OVERLAY:
3137 {
3138 int *on = arg, res;
3139
3140 dprintk(3, KERN_DEBUG "%s: VIDIOC_PREVIEW - on=%d\n",
3141 ZR_DEVNAME(zr), *on);
3142
3143 down(&zr->resource_lock);
3144 res = setup_overlay(file, *on);
3145 up(&zr->resource_lock);
3146
3147 return res;
3148 }
3149 break;
3150
3151 case VIDIOC_REQBUFS:
3152 {
3153 struct v4l2_requestbuffers *req = arg;
3154 int res = 0;
3155
3156 dprintk(3, KERN_DEBUG "%s: VIDIOC_REQBUFS - type=%d\n",
3157 ZR_DEVNAME(zr), req->type);
3158
3159 if (req->memory != V4L2_MEMORY_MMAP) {
3160 dprintk(1,
3161 KERN_ERR
3162 "%s: only MEMORY_MMAP capture is supported, not %d\n",
3163 ZR_DEVNAME(zr), req->memory);
3164 return -EINVAL;
3165 }
3166
3167 down(&zr->resource_lock);
3168
3169 if (fh->v4l_buffers.allocated || fh->jpg_buffers.allocated) {
3170 dprintk(1,
3171 KERN_ERR
3172 "%s: VIDIOC_REQBUFS - buffers allready allocated\n",
3173 ZR_DEVNAME(zr));
3174 res = -EBUSY;
3175 goto v4l2reqbuf_unlock_and_return;
3176 }
3177
3178 if (fh->map_mode == ZORAN_MAP_MODE_RAW &&
3179 req->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
3180
3181 /* control user input */
3182 if (req->count < 2)
3183 req->count = 2;
3184 if (req->count > v4l_nbufs)
3185 req->count = v4l_nbufs;
3186 fh->v4l_buffers.num_buffers = req->count;
3187
3188 if (v4l_fbuffer_alloc(file)) {
3189 res = -ENOMEM;
3190 goto v4l2reqbuf_unlock_and_return;
3191 }
3192
3193 /* The next mmap will map the V4L buffers */
3194 fh->map_mode = ZORAN_MAP_MODE_RAW;
3195
3196 } else if (fh->map_mode == ZORAN_MAP_MODE_JPG_REC ||
3197 fh->map_mode == ZORAN_MAP_MODE_JPG_PLAY) {
3198
3199 /* we need to calculate size ourselves now */
3200 if (req->count < 4)
3201 req->count = 4;
3202 if (req->count > jpg_nbufs)
3203 req->count = jpg_nbufs;
3204 fh->jpg_buffers.num_buffers = req->count;
3205 fh->jpg_buffers.buffer_size =
3206 zoran_v4l2_calc_bufsize(&fh->jpg_settings);
3207
3208 if (jpg_fbuffer_alloc(file)) {
3209 res = -ENOMEM;
3210 goto v4l2reqbuf_unlock_and_return;
3211 }
3212
3213 /* The next mmap will map the MJPEG buffers */
3214 if (req->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
3215 fh->map_mode = ZORAN_MAP_MODE_JPG_REC;
3216 else
3217 fh->map_mode = ZORAN_MAP_MODE_JPG_PLAY;
3218
3219 } else {
3220 dprintk(1,
3221 KERN_ERR
3222 "%s: VIDIOC_REQBUFS - unknown type %d\n",
3223 ZR_DEVNAME(zr), req->type);
3224 res = -EINVAL;
3225 goto v4l2reqbuf_unlock_and_return;
3226 }
3227 v4l2reqbuf_unlock_and_return:
3228 up(&zr->resource_lock);
3229
3230 return 0;
3231 }
3232 break;
3233
3234 case VIDIOC_QUERYBUF:
3235 {
3236 struct v4l2_buffer *buf = arg;
3237 __u32 type = buf->type;
3238 int index = buf->index, res;
3239
3240 dprintk(3,
3241 KERN_DEBUG
3242 "%s: VIDIOC_QUERYBUF - index=%d, type=%d\n",
3243 ZR_DEVNAME(zr), buf->index, buf->type);
3244
3245 memset(buf, 0, sizeof(buf));
3246 buf->type = type;
3247 buf->index = index;
3248
3249 down(&zr->resource_lock);
3250 res = zoran_v4l2_buffer_status(file, buf, buf->index);
3251 up(&zr->resource_lock);
3252
3253 return res;
3254 }
3255 break;
3256
3257 case VIDIOC_QBUF:
3258 {
3259 struct v4l2_buffer *buf = arg;
3260 int res = 0, codec_mode, buf_type;
3261
3262 dprintk(3,
3263 KERN_DEBUG "%s: VIDIOC_QBUF - type=%d, index=%d\n",
3264 ZR_DEVNAME(zr), buf->type, buf->index);
3265
3266 down(&zr->resource_lock);
3267
3268 switch (fh->map_mode) {
3269 case ZORAN_MAP_MODE_RAW:
3270 if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
3271 dprintk(1,
3272 KERN_ERR
3273 "%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n",
3274 ZR_DEVNAME(zr), buf->type, fh->map_mode);
3275 res = -EINVAL;
3276 goto qbuf_unlock_and_return;
3277 }
3278
3279 res = zoran_v4l_queue_frame(file, buf->index);
3280 if (res)
3281 goto qbuf_unlock_and_return;
3282 if (!zr->v4l_memgrab_active &&
3283 fh->v4l_buffers.active == ZORAN_LOCKED)
3284 zr36057_set_memgrab(zr, 1);
3285 break;
3286
3287 case ZORAN_MAP_MODE_JPG_REC:
3288 case ZORAN_MAP_MODE_JPG_PLAY:
3289 if (fh->map_mode == ZORAN_MAP_MODE_JPG_PLAY) {
3290 buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
3291 codec_mode = BUZ_MODE_MOTION_DECOMPRESS;
3292 } else {
3293 buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
3294 codec_mode = BUZ_MODE_MOTION_COMPRESS;
3295 }
3296
3297 if (buf->type != buf_type) {
3298 dprintk(1,
3299 KERN_ERR
3300 "%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n",
3301 ZR_DEVNAME(zr), buf->type, fh->map_mode);
3302 res = -EINVAL;
3303 goto qbuf_unlock_and_return;
3304 }
3305
3306 res =
3307 zoran_jpg_queue_frame(file, buf->index,
3308 codec_mode);
3309 if (res != 0)
3310 goto qbuf_unlock_and_return;
3311 if (zr->codec_mode == BUZ_MODE_IDLE &&
3312 fh->jpg_buffers.active == ZORAN_LOCKED) {
3313 zr36057_enable_jpg(zr, codec_mode);
3314 }
3315 break;
3316
3317 default:
3318 dprintk(1,
3319 KERN_ERR
3320 "%s: VIDIOC_QBUF - unsupported type %d\n",
3321 ZR_DEVNAME(zr), buf->type);
3322 res = -EINVAL;
3323 goto qbuf_unlock_and_return;
3324 }
3325 qbuf_unlock_and_return:
3326 up(&zr->resource_lock);
3327
3328 return res;
3329 }
3330 break;
3331
3332 case VIDIOC_DQBUF:
3333 {
3334 struct v4l2_buffer *buf = arg;
3335 int res = 0, buf_type, num = -1; /* compiler borks here (?) */
3336
3337 dprintk(3, KERN_DEBUG "%s: VIDIOC_DQBUF - type=%d\n",
3338 ZR_DEVNAME(zr), buf->type);
3339
3340 down(&zr->resource_lock);
3341
3342 switch (fh->map_mode) {
3343 case ZORAN_MAP_MODE_RAW:
3344 if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
3345 dprintk(1,
3346 KERN_ERR
3347 "%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n",
3348 ZR_DEVNAME(zr), buf->type, fh->map_mode);
3349 res = -EINVAL;
3350 goto dqbuf_unlock_and_return;
3351 }
3352
3353 num = zr->v4l_pend[zr->v4l_sync_tail & V4L_MASK_FRAME];
3354 if (file->f_flags & O_NONBLOCK &&
3355 zr->v4l_buffers.buffer[num].state !=
3356 BUZ_STATE_DONE) {
3357 res = -EAGAIN;
3358 goto dqbuf_unlock_and_return;
3359 }
3360 res = v4l_sync(file, num);
3361 if (res)
3362 goto dqbuf_unlock_and_return;
3363 else
3364 zr->v4l_sync_tail++;
3365 res = zoran_v4l2_buffer_status(file, buf, num);
3366 break;
3367
3368 case ZORAN_MAP_MODE_JPG_REC:
3369 case ZORAN_MAP_MODE_JPG_PLAY:
3370 {
3371 struct zoran_sync bs;
3372
3373 if (fh->map_mode == ZORAN_MAP_MODE_JPG_PLAY)
3374 buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
3375 else
3376 buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
3377
3378 if (buf->type != buf_type) {
3379 dprintk(1,
3380 KERN_ERR
3381 "%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n",
3382 ZR_DEVNAME(zr), buf->type, fh->map_mode);
3383 res = -EINVAL;
3384 goto dqbuf_unlock_and_return;
3385 }
3386
3387 num =
3388 zr->jpg_pend[zr->
3389 jpg_que_tail & BUZ_MASK_FRAME];
3390
3391 if (file->f_flags & O_NONBLOCK &&
3392 zr->jpg_buffers.buffer[num].state !=
3393 BUZ_STATE_DONE) {
3394 res = -EAGAIN;
3395 goto dqbuf_unlock_and_return;
3396 }
3397 res = jpg_sync(file, &bs);
3398 if (res)
3399 goto dqbuf_unlock_and_return;
3400 res =
3401 zoran_v4l2_buffer_status(file, buf, bs.frame);
3402 break;
3403 }
3404
3405 default:
3406 dprintk(1,
3407 KERN_ERR
3408 "%s: VIDIOC_DQBUF - unsupported type %d\n",
3409 ZR_DEVNAME(zr), buf->type);
3410 res = -EINVAL;
3411 goto dqbuf_unlock_and_return;
3412 }
3413 dqbuf_unlock_and_return:
3414 up(&zr->resource_lock);
3415
3416 return res;
3417 }
3418 break;
3419
3420 case VIDIOC_STREAMON:
3421 {
3422 int res = 0;
3423
3424 dprintk(3, KERN_DEBUG "%s: VIDIOC_STREAMON\n", ZR_DEVNAME(zr));
3425
3426 down(&zr->resource_lock);
3427
3428 switch (fh->map_mode) {
3429 case ZORAN_MAP_MODE_RAW: /* raw capture */
3430 if (zr->v4l_buffers.active != ZORAN_ACTIVE ||
3431 fh->v4l_buffers.active != ZORAN_ACTIVE) {
3432 res = -EBUSY;
3433 goto strmon_unlock_and_return;
3434 }
3435
3436 zr->v4l_buffers.active = fh->v4l_buffers.active =
3437 ZORAN_LOCKED;
3438 zr->v4l_settings = fh->v4l_settings;
3439
3440 zr->v4l_sync_tail = zr->v4l_pend_tail;
3441 if (!zr->v4l_memgrab_active &&
3442 zr->v4l_pend_head != zr->v4l_pend_tail) {
3443 zr36057_set_memgrab(zr, 1);
3444 }
3445 break;
3446
3447 case ZORAN_MAP_MODE_JPG_REC:
3448 case ZORAN_MAP_MODE_JPG_PLAY:
3449 /* what is the codec mode right now? */
3450 if (zr->jpg_buffers.active != ZORAN_ACTIVE ||
3451 fh->jpg_buffers.active != ZORAN_ACTIVE) {
3452 res = -EBUSY;
3453 goto strmon_unlock_and_return;
3454 }
3455
3456 zr->jpg_buffers.active = fh->jpg_buffers.active =
3457 ZORAN_LOCKED;
3458
3459 if (zr->jpg_que_head != zr->jpg_que_tail) {
3460 /* Start the jpeg codec when the first frame is queued */
3461 jpeg_start(zr);
3462 }
3463
3464 break;
3465 default:
3466 dprintk(1,
3467 KERN_ERR
3468 "%s: VIDIOC_STREAMON - invalid map mode %d\n",
3469 ZR_DEVNAME(zr), fh->map_mode);
3470 res = -EINVAL;
3471 goto strmon_unlock_and_return;
3472 }
3473 strmon_unlock_and_return:
3474 up(&zr->resource_lock);
3475
3476 return res;
3477 }
3478 break;
3479
3480 case VIDIOC_STREAMOFF:
3481 {
3482 int i, res = 0;
3483
3484 dprintk(3, KERN_DEBUG "%s: VIDIOC_STREAMOFF\n", ZR_DEVNAME(zr));
3485
3486 down(&zr->resource_lock);
3487
3488 switch (fh->map_mode) {
3489 case ZORAN_MAP_MODE_RAW: /* raw capture */
3490 if (fh->v4l_buffers.active == ZORAN_FREE &&
3491 zr->v4l_buffers.active != ZORAN_FREE) {
3492 res = -EPERM; /* stay off other's settings! */
3493 goto strmoff_unlock_and_return;
3494 }
3495 if (zr->v4l_buffers.active == ZORAN_FREE)
3496 goto strmoff_unlock_and_return;
3497
3498 /* unload capture */
3499 if (zr->v4l_memgrab_active)
3500 zr36057_set_memgrab(zr, 0);
3501
3502 for (i = 0; i < fh->v4l_buffers.num_buffers; i++)
3503 zr->v4l_buffers.buffer[i].state =
3504 BUZ_STATE_USER;
3505 fh->v4l_buffers = zr->v4l_buffers;
3506
3507 zr->v4l_buffers.active = fh->v4l_buffers.active =
3508 ZORAN_FREE;
3509
3510 zr->v4l_grab_seq = 0;
3511 zr->v4l_pend_head = zr->v4l_pend_tail = 0;
3512 zr->v4l_sync_tail = 0;
3513
3514 break;
3515
3516 case ZORAN_MAP_MODE_JPG_REC:
3517 case ZORAN_MAP_MODE_JPG_PLAY:
3518 if (fh->jpg_buffers.active == ZORAN_FREE &&
3519 zr->jpg_buffers.active != ZORAN_FREE) {
3520 res = -EPERM; /* stay off other's settings! */
3521 goto strmoff_unlock_and_return;
3522 }
3523 if (zr->jpg_buffers.active == ZORAN_FREE)
3524 goto strmoff_unlock_and_return;
3525
3526 res =
3527 jpg_qbuf(file, -1,
3528 (fh->map_mode ==
3529 ZORAN_MAP_MODE_JPG_REC) ?
3530 BUZ_MODE_MOTION_COMPRESS :
3531 BUZ_MODE_MOTION_DECOMPRESS);
3532 if (res)
3533 goto strmoff_unlock_and_return;
3534 break;
3535 default:
3536 dprintk(1,
3537 KERN_ERR
3538 "%s: VIDIOC_STREAMOFF - invalid map mode %d\n",
3539 ZR_DEVNAME(zr), fh->map_mode);
3540 res = -EINVAL;
3541 goto strmoff_unlock_and_return;
3542 }
3543 strmoff_unlock_and_return:
3544 up(&zr->resource_lock);
3545
3546 return res;
3547 }
3548 break;
3549
3550 case VIDIOC_QUERYCTRL:
3551 {
3552 struct v4l2_queryctrl *ctrl = arg;
3553
3554 dprintk(3, KERN_DEBUG "%s: VIDIOC_QUERYCTRL - id=%d\n",
3555 ZR_DEVNAME(zr), ctrl->id);
3556
3557 /* we only support hue/saturation/contrast/brightness */
3558 if (ctrl->id < V4L2_CID_BRIGHTNESS ||
3559 ctrl->id > V4L2_CID_HUE)
3560 return -EINVAL;
3561 else {
3562 int id = ctrl->id;
3563 memset(ctrl, 0, sizeof(*ctrl));
3564 ctrl->id = id;
3565 }
3566
3567 switch (ctrl->id) {
3568 case V4L2_CID_BRIGHTNESS:
3569 strncpy(ctrl->name, "Brightness", 31);
3570 break;
3571 case V4L2_CID_CONTRAST:
3572 strncpy(ctrl->name, "Contrast", 31);
3573 break;
3574 case V4L2_CID_SATURATION:
3575 strncpy(ctrl->name, "Saturation", 31);
3576 break;
3577 case V4L2_CID_HUE:
3578 strncpy(ctrl->name, "Hue", 31);
3579 break;
3580 }
3581
3582 ctrl->minimum = 0;
3583 ctrl->maximum = 65535;
3584 ctrl->step = 1;
3585 ctrl->default_value = 32768;
3586 ctrl->type = V4L2_CTRL_TYPE_INTEGER;
3587
3588 return 0;
3589 }
3590 break;
3591
3592 case VIDIOC_G_CTRL:
3593 {
3594 struct v4l2_control *ctrl = arg;
3595
3596 dprintk(3, KERN_DEBUG "%s: VIDIOC_G_CTRL - id=%d\n",
3597 ZR_DEVNAME(zr), ctrl->id);
3598
3599 /* we only support hue/saturation/contrast/brightness */
3600 if (ctrl->id < V4L2_CID_BRIGHTNESS ||
3601 ctrl->id > V4L2_CID_HUE)
3602 return -EINVAL;
3603
3604 down(&zr->resource_lock);
3605 switch (ctrl->id) {
3606 case V4L2_CID_BRIGHTNESS:
3607 ctrl->value = zr->brightness;
3608 break;
3609 case V4L2_CID_CONTRAST:
3610 ctrl->value = zr->contrast;
3611 break;
3612 case V4L2_CID_SATURATION:
3613 ctrl->value = zr->saturation;
3614 break;
3615 case V4L2_CID_HUE:
3616 ctrl->value = zr->hue;
3617 break;
3618 }
3619 up(&zr->resource_lock);
3620
3621 return 0;
3622 }
3623 break;
3624
3625 case VIDIOC_S_CTRL:
3626 {
3627 struct v4l2_control *ctrl = arg;
3628 struct video_picture pict;
3629
3630 dprintk(3, KERN_DEBUG "%s: VIDIOC_S_CTRL - id=%d\n",
3631 ZR_DEVNAME(zr), ctrl->id);
3632
3633 /* we only support hue/saturation/contrast/brightness */
3634 if (ctrl->id < V4L2_CID_BRIGHTNESS ||
3635 ctrl->id > V4L2_CID_HUE)
3636 return -EINVAL;
3637
3638 if (ctrl->value < 0 || ctrl->value > 65535) {
3639 dprintk(1,
3640 KERN_ERR
3641 "%s: VIDIOC_S_CTRL - invalid value %d for id=%d\n",
3642 ZR_DEVNAME(zr), ctrl->value, ctrl->id);
3643 return -EINVAL;
3644 }
3645
3646 down(&zr->resource_lock);
3647 switch (ctrl->id) {
3648 case V4L2_CID_BRIGHTNESS:
3649 zr->brightness = ctrl->value;
3650 break;
3651 case V4L2_CID_CONTRAST:
3652 zr->contrast = ctrl->value;
3653 break;
3654 case V4L2_CID_SATURATION:
3655 zr->saturation = ctrl->value;
3656 break;
3657 case V4L2_CID_HUE:
3658 zr->hue = ctrl->value;
3659 break;
3660 }
3661 pict.brightness = zr->brightness;
3662 pict.contrast = zr->contrast;
3663 pict.colour = zr->saturation;
3664 pict.hue = zr->hue;
3665
3666 decoder_command(zr, DECODER_SET_PICTURE, &pict);
3667
3668 up(&zr->resource_lock);
3669
3670 return 0;
3671 }
3672 break;
3673
3674 case VIDIOC_ENUMSTD:
3675 {
3676 struct v4l2_standard *std = arg;
3677
3678 dprintk(3, KERN_DEBUG "%s: VIDIOC_ENUMSTD - index=%d\n",
3679 ZR_DEVNAME(zr), std->index);
3680
3681 if (std->index < 0 || std->index >= (zr->card.norms + 1))
3682 return -EINVAL;
3683 else {
3684 int id = std->index;
3685 memset(std, 0, sizeof(*std));
3686 std->index = id;
3687 }
3688
3689 if (std->index == zr->card.norms) {
3690 /* if we have autodetect, ... */
3691 struct video_decoder_capability caps;
3692 decoder_command(zr, DECODER_GET_CAPABILITIES,
3693 &caps);
3694 if (caps.flags & VIDEO_DECODER_AUTO) {
3695 std->id = V4L2_STD_ALL;
3696 strncpy(std->name, "Autodetect", 31);
3697 return 0;
3698 } else
3699 return -EINVAL;
3700 }
3701 switch (std->index) {
3702 case 0:
3703 std->id = V4L2_STD_PAL;
3704 strncpy(std->name, "PAL", 31);
3705 std->frameperiod.numerator = 1;
3706 std->frameperiod.denominator = 25;
3707 std->framelines = zr->card.tvn[0]->Ht;
3708 break;
3709 case 1:
3710 std->id = V4L2_STD_NTSC;
3711 strncpy(std->name, "NTSC", 31);
3712 std->frameperiod.numerator = 1001;
3713 std->frameperiod.denominator = 30000;
3714 std->framelines = zr->card.tvn[1]->Ht;
3715 break;
3716 case 2:
3717 std->id = V4L2_STD_SECAM;
3718 strncpy(std->name, "SECAM", 31);
3719 std->frameperiod.numerator = 1;
3720 std->frameperiod.denominator = 25;
3721 std->framelines = zr->card.tvn[2]->Ht;
3722 break;
3723 }
3724
3725 return 0;
3726 }
3727 break;
3728
3729 case VIDIOC_G_STD:
3730 {
3731 v4l2_std_id *std = arg;
3732 int norm;
3733
3734 dprintk(3, KERN_DEBUG "%s: VIDIOC_G_STD\n", ZR_DEVNAME(zr));
3735
3736 down(&zr->resource_lock);
3737 norm = zr->norm;
3738 up(&zr->resource_lock);
3739
3740 switch (norm) {
3741 case VIDEO_MODE_PAL:
3742 *std = V4L2_STD_PAL;
3743 break;
3744 case VIDEO_MODE_NTSC:
3745 *std = V4L2_STD_NTSC;
3746 break;
3747 case VIDEO_MODE_SECAM:
3748 *std = V4L2_STD_SECAM;
3749 break;
3750 }
3751
3752 return 0;
3753 }
3754 break;
3755
3756 case VIDIOC_S_STD:
3757 {
3758 int norm = -1, res = 0;
3759 v4l2_std_id *std = arg;
3760
3761 dprintk(3, KERN_DEBUG "%s: VIDIOC_S_STD - norm=0x%llx\n",
3762 ZR_DEVNAME(zr), (unsigned long long)*std);
3763
3764 if (*std == V4L2_STD_PAL)
3765 norm = VIDEO_MODE_PAL;
3766 else if (*std == V4L2_STD_NTSC)
3767 norm = VIDEO_MODE_NTSC;
3768 else if (*std == V4L2_STD_SECAM)
3769 norm = VIDEO_MODE_SECAM;
3770 else if (*std == V4L2_STD_ALL)
3771 norm = VIDEO_MODE_AUTO;
3772 else {
3773 dprintk(1,
3774 KERN_ERR
3775 "%s: VIDIOC_S_STD - invalid norm 0x%llx\n",
3776 ZR_DEVNAME(zr), (unsigned long long)*std);
3777 return -EINVAL;
3778 }
3779
3780 down(&zr->resource_lock);
3781 if ((res = zoran_set_norm(zr, norm)))
3782 goto sstd_unlock_and_return;
3783
3784 res = wait_grab_pending(zr);
3785 sstd_unlock_and_return:
3786 up(&zr->resource_lock);
3787 return res;
3788 }
3789 break;
3790
3791 case VIDIOC_ENUMINPUT:
3792 {
3793 struct v4l2_input *inp = arg;
3794 int status;
3795
3796 dprintk(3, KERN_DEBUG "%s: VIDIOC_ENUMINPUT - index=%d\n",
3797 ZR_DEVNAME(zr), inp->index);
3798
3799 if (inp->index < 0 || inp->index >= zr->card.inputs)
3800 return -EINVAL;
3801 else {
3802 int id = inp->index;
3803 memset(inp, 0, sizeof(*inp));
3804 inp->index = id;
3805 }
3806
3807 strncpy(inp->name, zr->card.input[inp->index].name,
3808 sizeof(inp->name) - 1);
3809 inp->type = V4L2_INPUT_TYPE_CAMERA;
3810 inp->std = V4L2_STD_ALL;
3811
3812 /* Get status of video decoder */
3813 down(&zr->resource_lock);
3814 decoder_command(zr, DECODER_GET_STATUS, &status);
3815 up(&zr->resource_lock);
3816
3817 if (!(status & DECODER_STATUS_GOOD)) {
3818 inp->status |= V4L2_IN_ST_NO_POWER;
3819 inp->status |= V4L2_IN_ST_NO_SIGNAL;
3820 }
3821 if (!(status & DECODER_STATUS_COLOR))
3822 inp->status |= V4L2_IN_ST_NO_COLOR;
3823
3824 return 0;
3825 }
3826 break;
3827
3828 case VIDIOC_G_INPUT:
3829 {
3830 int *input = arg;
3831
3832 dprintk(3, KERN_DEBUG "%s: VIDIOC_G_INPUT\n", ZR_DEVNAME(zr));
3833
3834 down(&zr->resource_lock);
3835 *input = zr->input;
3836 up(&zr->resource_lock);
3837
3838 return 0;
3839 }
3840 break;
3841
3842 case VIDIOC_S_INPUT:
3843 {
3844 int *input = arg, res = 0;
3845
3846 dprintk(3, KERN_DEBUG "%s: VIDIOC_S_INPUT - input=%d\n",
3847 ZR_DEVNAME(zr), *input);
3848
3849 down(&zr->resource_lock);
3850 if ((res = zoran_set_input(zr, *input)))
3851 goto sinput_unlock_and_return;
3852
3853 /* Make sure the changes come into effect */
3854 res = wait_grab_pending(zr);
3855 sinput_unlock_and_return:
3856 up(&zr->resource_lock);
3857 return res;
3858 }
3859 break;
3860
3861 case VIDIOC_ENUMOUTPUT:
3862 {
3863 struct v4l2_output *outp = arg;
3864
3865 dprintk(3, KERN_DEBUG "%s: VIDIOC_ENUMOUTPUT - index=%d\n",
3866 ZR_DEVNAME(zr), outp->index);
3867
3868 if (outp->index != 0)
3869 return -EINVAL;
3870
3871 memset(outp, 0, sizeof(*outp));
3872 outp->index = 0;
3873 outp->type = V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY;
3874 strncpy(outp->name, "Autodetect", 31);
3875
3876 return 0;
3877 }
3878 break;
3879
3880 case VIDIOC_G_OUTPUT:
3881 {
3882 int *output = arg;
3883
3884 dprintk(3, KERN_DEBUG "%s: VIDIOC_G_OUTPUT\n", ZR_DEVNAME(zr));
3885
3886 *output = 0;
3887
3888 return 0;
3889 }
3890 break;
3891
3892 case VIDIOC_S_OUTPUT:
3893 {
3894 int *output = arg;
3895
3896 dprintk(3, KERN_DEBUG "%s: VIDIOC_S_OUTPUT - output=%d\n",
3897 ZR_DEVNAME(zr), *output);
3898
3899 if (*output != 0)
3900 return -EINVAL;
3901
3902 return 0;
3903 }
3904 break;
3905
3906 /* cropping (sub-frame capture) */
3907 case VIDIOC_CROPCAP:
3908 {
3909 struct v4l2_cropcap *cropcap = arg;
3910 int type = cropcap->type, res = 0;
3911
3912 dprintk(3, KERN_ERR "%s: VIDIOC_CROPCAP - type=%d\n",
3913 ZR_DEVNAME(zr), cropcap->type);
3914
3915 memset(cropcap, 0, sizeof(*cropcap));
3916 cropcap->type = type;
3917
3918 down(&zr->resource_lock);
3919
3920 if (cropcap->type != V4L2_BUF_TYPE_VIDEO_OUTPUT &&
3921 (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
3922 fh->map_mode == ZORAN_MAP_MODE_RAW)) {
3923 dprintk(1,
3924 KERN_ERR
3925 "%s: VIDIOC_CROPCAP - subcapture only supported for compressed capture\n",
3926 ZR_DEVNAME(zr));
3927 res = -EINVAL;
3928 goto cropcap_unlock_and_return;
3929 }
3930
3931 cropcap->bounds.top = cropcap->bounds.left = 0;
3932 cropcap->bounds.width = BUZ_MAX_WIDTH;
3933 cropcap->bounds.height = BUZ_MAX_HEIGHT;
3934 cropcap->defrect.top = cropcap->defrect.left = 0;
3935 cropcap->defrect.width = BUZ_MIN_WIDTH;
3936 cropcap->defrect.height = BUZ_MIN_HEIGHT;
3937 cropcap_unlock_and_return:
3938 up(&zr->resource_lock);
3939 return res;
3940 }
3941 break;
3942
3943 case VIDIOC_G_CROP:
3944 {
3945 struct v4l2_crop *crop = arg;
3946 int type = crop->type, res = 0;
3947
3948 dprintk(3, KERN_ERR "%s: VIDIOC_G_CROP - type=%d\n",
3949 ZR_DEVNAME(zr), crop->type);
3950
3951 memset(crop, 0, sizeof(*crop));
3952 crop->type = type;
3953
3954 down(&zr->resource_lock);
3955
3956 if (crop->type != V4L2_BUF_TYPE_VIDEO_OUTPUT &&
3957 (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
3958 fh->map_mode == ZORAN_MAP_MODE_RAW)) {
3959 dprintk(1,
3960 KERN_ERR
3961 "%s: VIDIOC_G_CROP - subcapture only supported for compressed capture\n",
3962 ZR_DEVNAME(zr));
3963 res = -EINVAL;
3964 goto gcrop_unlock_and_return;
3965 }
3966
3967 crop->c.top = fh->jpg_settings.img_y;
3968 crop->c.left = fh->jpg_settings.img_x;
3969 crop->c.width = fh->jpg_settings.img_width;
3970 crop->c.height = fh->jpg_settings.img_height;
3971
3972 gcrop_unlock_and_return:
3973 up(&zr->resource_lock);
3974
3975 return res;
3976 }
3977 break;
3978
3979 case VIDIOC_S_CROP:
3980 {
3981 struct v4l2_crop *crop = arg;
3982 int res = 0;
3983
3984 settings = fh->jpg_settings;
3985
3986 dprintk(3,
3987 KERN_ERR
3988 "%s: VIDIOC_S_CROP - type=%d, x=%d,y=%d,w=%d,h=%d\n",
3989 ZR_DEVNAME(zr), crop->type, crop->c.left, crop->c.top,
3990 crop->c.width, crop->c.height);
3991
3992 down(&zr->resource_lock);
3993
3994 if (fh->jpg_buffers.allocated || fh->v4l_buffers.allocated) {
3995 dprintk(1,
3996 KERN_ERR
3997 "%s: VIDIOC_S_CROP - cannot change settings while active\n",
3998 ZR_DEVNAME(zr));
3999 res = -EBUSY;
4000 goto scrop_unlock_and_return;
4001 }
4002
4003 if (crop->type != V4L2_BUF_TYPE_VIDEO_OUTPUT &&
4004 (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
4005 fh->map_mode == ZORAN_MAP_MODE_RAW)) {
4006 dprintk(1,
4007 KERN_ERR
4008 "%s: VIDIOC_G_CROP - subcapture only supported for compressed capture\n",
4009 ZR_DEVNAME(zr));
4010 res = -EINVAL;
4011 goto scrop_unlock_and_return;
4012 }
4013
4014 /* move into a form that we understand */
4015 settings.img_x = crop->c.left;
4016 settings.img_y = crop->c.top;
4017 settings.img_width = crop->c.width;
4018 settings.img_height = crop->c.height;
4019
4020 /* check validity */
4021 if ((res = zoran_check_jpg_settings(zr, &settings)))
4022 goto scrop_unlock_and_return;
4023
4024 /* accept */
4025 fh->jpg_settings = settings;
4026
4027 scrop_unlock_and_return:
4028 up(&zr->resource_lock);
4029 return res;
4030 }
4031 break;
4032
4033 case VIDIOC_G_JPEGCOMP:
4034 {
4035 struct v4l2_jpegcompression *params = arg;
4036
4037 dprintk(3, KERN_DEBUG "%s: VIDIOC_G_JPEGCOMP\n",
4038 ZR_DEVNAME(zr));
4039
4040 memset(params, 0, sizeof(*params));
4041
4042 down(&zr->resource_lock);
4043
4044 params->quality = fh->jpg_settings.jpg_comp.quality;
4045 params->APPn = fh->jpg_settings.jpg_comp.APPn;
4046 memcpy(params->APP_data,
4047 fh->jpg_settings.jpg_comp.APP_data,
4048 fh->jpg_settings.jpg_comp.APP_len);
4049 params->APP_len = fh->jpg_settings.jpg_comp.APP_len;
4050 memcpy(params->COM_data,
4051 fh->jpg_settings.jpg_comp.COM_data,
4052 fh->jpg_settings.jpg_comp.COM_len);
4053 params->COM_len = fh->jpg_settings.jpg_comp.COM_len;
4054 params->jpeg_markers =
4055 fh->jpg_settings.jpg_comp.jpeg_markers;
4056
4057 up(&zr->resource_lock);
4058
4059 return 0;
4060 }
4061 break;
4062
4063 case VIDIOC_S_JPEGCOMP:
4064 {
4065 struct v4l2_jpegcompression *params = arg;
4066 int res = 0;
4067
4068 settings = fh->jpg_settings;
4069
4070 dprintk(3,
4071 KERN_DEBUG
4072 "%s: VIDIOC_S_JPEGCOMP - quality=%d, APPN=%d, APP_len=%d, COM_len=%d\n",
4073 ZR_DEVNAME(zr), params->quality, params->APPn,
4074 params->APP_len, params->COM_len);
4075
4076 settings.jpg_comp = *params;
4077
4078 down(&zr->resource_lock);
4079
4080 if (fh->v4l_buffers.active != ZORAN_FREE ||
4081 fh->jpg_buffers.active != ZORAN_FREE) {
4082 dprintk(1,
4083 KERN_WARNING
4084 "%s: VIDIOC_S_JPEGCOMP called while in playback/capture mode\n",
4085 ZR_DEVNAME(zr));
4086 res = -EBUSY;
4087 goto sjpegc_unlock_and_return;
4088 }
4089
4090 if ((res = zoran_check_jpg_settings(zr, &settings)))
4091 goto sjpegc_unlock_and_return;
4092 if (!fh->jpg_buffers.allocated)
4093 fh->jpg_buffers.buffer_size =
4094 zoran_v4l2_calc_bufsize(&fh->jpg_settings);
4095 fh->jpg_settings.jpg_comp = *params = settings.jpg_comp;
4096 sjpegc_unlock_and_return:
4097 up(&zr->resource_lock);
4098
4099 return 0;
4100 }
4101 break;
4102
4103 case VIDIOC_QUERYSTD: /* why is this useful? */
4104 {
4105 v4l2_std_id *std = arg;
4106
4107 dprintk(3,
4108 KERN_DEBUG "%s: VIDIOC_QUERY_STD - std=0x%llx\n",
4109 ZR_DEVNAME(zr), (unsigned long long)*std);
4110
4111 if (*std == V4L2_STD_ALL || *std == V4L2_STD_NTSC ||
4112 *std == V4L2_STD_PAL || (*std == V4L2_STD_SECAM &&
4113 zr->card.norms == 3)) {
4114 return 0;
4115 }
4116
4117 return -EINVAL;
4118 }
4119 break;
4120
4121 case VIDIOC_TRY_FMT:
4122 {
4123 struct v4l2_format *fmt = arg;
4124 int res = 0;
4125
4126 dprintk(3, KERN_DEBUG "%s: VIDIOC_TRY_FMT - type=%d\n",
4127 ZR_DEVNAME(zr), fmt->type);
4128
4129 switch (fmt->type) {
4130 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
4131 down(&zr->resource_lock);
4132
4133 if (fmt->fmt.win.w.width > BUZ_MAX_WIDTH)
4134 fmt->fmt.win.w.width = BUZ_MAX_WIDTH;
4135 if (fmt->fmt.win.w.width < BUZ_MIN_WIDTH)
4136 fmt->fmt.win.w.width = BUZ_MIN_WIDTH;
4137 if (fmt->fmt.win.w.height > BUZ_MAX_HEIGHT)
4138 fmt->fmt.win.w.height = BUZ_MAX_HEIGHT;
4139 if (fmt->fmt.win.w.height < BUZ_MIN_HEIGHT)
4140 fmt->fmt.win.w.height = BUZ_MIN_HEIGHT;
4141
4142 up(&zr->resource_lock);
4143 break;
4144
4145 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
4146 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
4147 if (fmt->fmt.pix.bytesperline > 0)
4148 return -EINVAL;
4149
4150 down(&zr->resource_lock);
4151
4152 if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG) {
4153 settings = fh->jpg_settings;
4154
4155 /* we actually need to set 'real' parameters now */
4156 if ((fmt->fmt.pix.height * 2) >
4157 BUZ_MAX_HEIGHT)
4158 settings.TmpDcm = 1;
4159 else
4160 settings.TmpDcm = 2;
4161 settings.decimation = 0;
4162 if (fmt->fmt.pix.height <=
4163 fh->jpg_settings.img_height / 2)
4164 settings.VerDcm = 2;
4165 else
4166 settings.VerDcm = 1;
4167 if (fmt->fmt.pix.width <=
4168 fh->jpg_settings.img_width / 4)
4169 settings.HorDcm = 4;
4170 else if (fmt->fmt.pix.width <=
4171 fh->jpg_settings.img_width / 2)
4172 settings.HorDcm = 2;
4173 else
4174 settings.HorDcm = 1;
4175 if (settings.TmpDcm == 1)
4176 settings.field_per_buff = 2;
4177 else
4178 settings.field_per_buff = 1;
4179
4180 /* check */
4181 if ((res =
4182 zoran_check_jpg_settings(zr,
4183 &settings)))
4184 goto tryfmt_unlock_and_return;
4185
4186 /* tell the user what we actually did */
4187 fmt->fmt.pix.width =
4188 settings.img_width / settings.HorDcm;
4189 fmt->fmt.pix.height =
4190 settings.img_height * 2 /
4191 (settings.TmpDcm * settings.VerDcm);
4192 if (settings.TmpDcm == 1)
4193 fmt->fmt.pix.field =
4194 (fh->jpg_settings.
4195 odd_even ? V4L2_FIELD_SEQ_TB :
4196 V4L2_FIELD_SEQ_BT);
4197 else
4198 fmt->fmt.pix.field =
4199 (fh->jpg_settings.
4200 odd_even ? V4L2_FIELD_TOP :
4201 V4L2_FIELD_BOTTOM);
4202
4203 fmt->fmt.pix.sizeimage =
4204 zoran_v4l2_calc_bufsize(&settings);
4205 } else if (fmt->type ==
4206 V4L2_BUF_TYPE_VIDEO_CAPTURE) {
4207 int i;
4208
4209 for (i = 0; i < zoran_num_formats; i++)
4210 if (zoran_formats[i].fourcc ==
4211 fmt->fmt.pix.pixelformat)
4212 break;
4213 if (i == zoran_num_formats) {
4214 res = -EINVAL;
4215 goto tryfmt_unlock_and_return;
4216 }
4217
4218 if (fmt->fmt.pix.width > BUZ_MAX_WIDTH)
4219 fmt->fmt.pix.width = BUZ_MAX_WIDTH;
4220 if (fmt->fmt.pix.width < BUZ_MIN_WIDTH)
4221 fmt->fmt.pix.width = BUZ_MIN_WIDTH;
4222 if (fmt->fmt.pix.height > BUZ_MAX_HEIGHT)
4223 fmt->fmt.pix.height =
4224 BUZ_MAX_HEIGHT;
4225 if (fmt->fmt.pix.height < BUZ_MIN_HEIGHT)
4226 fmt->fmt.pix.height =
4227 BUZ_MIN_HEIGHT;
4228 } else {
4229 res = -EINVAL;
4230 goto tryfmt_unlock_and_return;
4231 }
4232 tryfmt_unlock_and_return:
4233 up(&zr->resource_lock);
4234
4235 return res;
4236 break;
4237
4238 default:
4239 return -EINVAL;
4240 }
4241
4242 return 0;
4243 }
4244 break;
4245#endif
4246
4247 default:
4248 dprintk(1, KERN_DEBUG "%s: UNKNOWN ioctl cmd: 0x%x\n",
4249 ZR_DEVNAME(zr), cmd);
4250 return -ENOIOCTLCMD;
4251 break;
4252
4253 }
4254 return 0;
4255}
4256
4257
4258static int
4259zoran_ioctl (struct inode *inode,
4260 struct file *file,
4261 unsigned int cmd,
4262 unsigned long arg)
4263{
4264 return video_usercopy(inode, file, cmd, arg, zoran_do_ioctl);
4265}
4266
4267static unsigned int
4268zoran_poll (struct file *file,
4269 poll_table *wait)
4270{
4271 struct zoran_fh *fh = file->private_data;
4272 struct zoran *zr = fh->zr;
4273 wait_queue_head_t *queue = NULL;
4274 int res = 0, frame;
4275
4276 /* we should check whether buffers are ready to be synced on
4277 * (w/o waits - O_NONBLOCK) here
4278 * if ready for read (sync), return POLLIN|POLLRDNORM,
4279 * if ready for write (sync), return POLLOUT|POLLWRNORM,
4280 * if error, return POLLERR,
4281 * if no buffers queued or so, return POLLNVAL
4282 */
4283
4284 down(&zr->resource_lock);
4285
4286 switch (fh->map_mode) {
4287 case ZORAN_MAP_MODE_RAW:
4288 if (fh->v4l_buffers.active == ZORAN_FREE ||
4289 zr->v4l_pend_head == zr->v4l_pend_tail) {
4290 dprintk(1,
4291 "%s: zoran_poll() - no buffers queued\n",
4292 ZR_DEVNAME(zr));
4293 res = POLLNVAL;
4294 goto poll_unlock_and_return;
4295 }
4296 queue = &zr->v4l_capq;
4297 frame = zr->v4l_pend[zr->v4l_pend_tail & V4L_MASK_FRAME];
4298 poll_wait(file, queue, wait);
4299 if (fh->v4l_buffers.buffer[frame].state == BUZ_STATE_DONE)
4300 res = POLLIN | POLLRDNORM;
4301 break;
4302
4303 case ZORAN_MAP_MODE_JPG_REC:
4304 case ZORAN_MAP_MODE_JPG_PLAY:
4305 if (fh->jpg_buffers.active == ZORAN_FREE ||
4306 zr->jpg_que_head == zr->jpg_que_tail) {
4307 dprintk(1,
4308 "%s: zoran_poll() - no buffers queued\n",
4309 ZR_DEVNAME(zr));
4310 res = POLLNVAL;
4311 goto poll_unlock_and_return;
4312 }
4313 queue = &zr->jpg_capq;
4314 frame = zr->jpg_pend[zr->jpg_que_tail & BUZ_MASK_FRAME];
4315 poll_wait(file, queue, wait);
4316 if (fh->jpg_buffers.buffer[frame].state == BUZ_STATE_DONE) {
4317 if (fh->map_mode == ZORAN_MAP_MODE_JPG_REC)
4318 res = POLLIN | POLLRDNORM;
4319 else
4320 res = POLLOUT | POLLWRNORM;
4321 }
4322 break;
4323
4324 default:
4325 dprintk(1,
4326 "%s: zoran_poll() - internal error, unknown map_mode=%d\n",
4327 ZR_DEVNAME(zr), fh->map_mode);
4328 res = POLLNVAL;
4329 goto poll_unlock_and_return;
4330 }
4331
4332poll_unlock_and_return:
4333 up(&zr->resource_lock);
4334
4335 return res;
4336}
4337
4338
4339/*
4340 * This maps the buffers to user space.
4341 *
4342 * Depending on the state of fh->map_mode
4343 * the V4L or the MJPEG buffers are mapped
4344 * per buffer or all together
4345 *
4346 * Note that we need to connect to some
4347 * unmap signal event to unmap the de-allocate
4348 * the buffer accordingly (zoran_vm_close())
4349 */
4350
4351static void
4352zoran_vm_open (struct vm_area_struct *vma)
4353{
4354 struct zoran_mapping *map = vma->vm_private_data;
4355
4356 map->count++;
4357}
4358
4359static void
4360zoran_vm_close (struct vm_area_struct *vma)
4361{
4362 struct zoran_mapping *map = vma->vm_private_data;
4363 struct file *file = map->file;
4364 struct zoran_fh *fh = file->private_data;
4365 struct zoran *zr = fh->zr;
4366 int i;
4367
4368 map->count--;
4369 if (map->count == 0) {
4370 switch (fh->map_mode) {
4371 case ZORAN_MAP_MODE_JPG_REC:
4372 case ZORAN_MAP_MODE_JPG_PLAY:
4373
4374 dprintk(3, KERN_INFO "%s: munmap(MJPEG)\n",
4375 ZR_DEVNAME(zr));
4376
4377 for (i = 0; i < fh->jpg_buffers.num_buffers; i++) {
4378 if (fh->jpg_buffers.buffer[i].map == map) {
4379 fh->jpg_buffers.buffer[i].map =
4380 NULL;
4381 }
4382 }
4383 kfree(map);
4384
4385 for (i = 0; i < fh->jpg_buffers.num_buffers; i++)
4386 if (fh->jpg_buffers.buffer[i].map)
4387 break;
4388 if (i == fh->jpg_buffers.num_buffers) {
4389 down(&zr->resource_lock);
4390
4391 if (fh->jpg_buffers.active != ZORAN_FREE) {
4392 jpg_qbuf(file, -1, zr->codec_mode);
4393 zr->jpg_buffers.allocated = 0;
4394 zr->jpg_buffers.active =
4395 fh->jpg_buffers.active =
4396 ZORAN_FREE;
4397 }
4398 //jpg_fbuffer_free(file);
4399 fh->jpg_buffers.allocated = 0;
4400 fh->jpg_buffers.ready_to_be_freed = 1;
4401
4402 up(&zr->resource_lock);
4403 }
4404
4405 break;
4406
4407 case ZORAN_MAP_MODE_RAW:
4408
4409 dprintk(3, KERN_INFO "%s: munmap(V4L)\n",
4410 ZR_DEVNAME(zr));
4411
4412 for (i = 0; i < fh->v4l_buffers.num_buffers; i++) {
4413 if (fh->v4l_buffers.buffer[i].map == map) {
4414 /* unqueue/unmap */
4415 fh->v4l_buffers.buffer[i].map =
4416 NULL;
4417 }
4418 }
4419 kfree(map);
4420
4421 for (i = 0; i < fh->v4l_buffers.num_buffers; i++)
4422 if (fh->v4l_buffers.buffer[i].map)
4423 break;
4424 if (i == fh->v4l_buffers.num_buffers) {
4425 down(&zr->resource_lock);
4426
4427 if (fh->v4l_buffers.active != ZORAN_FREE) {
4428 zr36057_set_memgrab(zr, 0);
4429 zr->v4l_buffers.allocated = 0;
4430 zr->v4l_buffers.active =
4431 fh->v4l_buffers.active =
4432 ZORAN_FREE;
4433 }
4434 //v4l_fbuffer_free(file);
4435 fh->v4l_buffers.allocated = 0;
4436 fh->v4l_buffers.ready_to_be_freed = 1;
4437
4438 up(&zr->resource_lock);
4439 }
4440
4441 break;
4442
4443 default:
4444 printk(KERN_ERR
4445 "%s: munmap() - internal error - unknown map mode %d\n",
4446 ZR_DEVNAME(zr), fh->map_mode);
4447 break;
4448
4449 }
4450 }
4451}
4452
4453static struct vm_operations_struct zoran_vm_ops = {
4454 .open = zoran_vm_open,
4455 .close = zoran_vm_close,
4456};
4457
4458static int
4459zoran_mmap (struct file *file,
4460 struct vm_area_struct *vma)
4461{
4462 struct zoran_fh *fh = file->private_data;
4463 struct zoran *zr = fh->zr;
4464 unsigned long size = (vma->vm_end - vma->vm_start);
4465 unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
4466 int i, j;
4467 unsigned long page, start = vma->vm_start, todo, pos, fraglen;
4468 int first, last;
4469 struct zoran_mapping *map;
4470 int res = 0;
4471
4472 dprintk(3,
4473 KERN_INFO "%s: mmap(%s) of 0x%08lx-0x%08lx (size=%lu)\n",
4474 ZR_DEVNAME(zr),
4475 fh->map_mode == ZORAN_MAP_MODE_RAW ? "V4L" : "MJPEG",
4476 vma->vm_start, vma->vm_end, size);
4477
4478 if (!(vma->vm_flags & VM_SHARED) || !(vma->vm_flags & VM_READ) ||
4479 !(vma->vm_flags & VM_WRITE)) {
4480 dprintk(1,
4481 KERN_ERR
4482 "%s: mmap() - no MAP_SHARED/PROT_{READ,WRITE} given\n",
4483 ZR_DEVNAME(zr));
4484 return -EINVAL;
4485 }
4486
4487 switch (fh->map_mode) {
4488
4489 case ZORAN_MAP_MODE_JPG_REC:
4490 case ZORAN_MAP_MODE_JPG_PLAY:
4491
4492 /* lock */
4493 down(&zr->resource_lock);
4494
4495 /* Map the MJPEG buffers */
4496 if (!fh->jpg_buffers.allocated) {
4497 dprintk(1,
4498 KERN_ERR
4499 "%s: zoran_mmap(MJPEG) - buffers not yet allocated\n",
4500 ZR_DEVNAME(zr));
4501 res = -ENOMEM;
4502 goto jpg_mmap_unlock_and_return;
4503 }
4504
4505 first = offset / fh->jpg_buffers.buffer_size;
4506 last = first - 1 + size / fh->jpg_buffers.buffer_size;
4507 if (offset % fh->jpg_buffers.buffer_size != 0 ||
4508 size % fh->jpg_buffers.buffer_size != 0 || first < 0 ||
4509 last < 0 || first >= fh->jpg_buffers.num_buffers ||
4510 last >= fh->jpg_buffers.num_buffers) {
4511 dprintk(1,
4512 KERN_ERR
4513 "%s: mmap(MJPEG) - offset=%lu or size=%lu invalid for bufsize=%d and numbufs=%d\n",
4514 ZR_DEVNAME(zr), offset, size,
4515 fh->jpg_buffers.buffer_size,
4516 fh->jpg_buffers.num_buffers);
4517 res = -EINVAL;
4518 goto jpg_mmap_unlock_and_return;
4519 }
4520 for (i = first; i <= last; i++) {
4521 if (fh->jpg_buffers.buffer[i].map) {
4522 dprintk(1,
4523 KERN_ERR
4524 "%s: mmap(MJPEG) - buffer %d already mapped\n",
4525 ZR_DEVNAME(zr), i);
4526 res = -EBUSY;
4527 goto jpg_mmap_unlock_and_return;
4528 }
4529 }
4530
4531 /* map these buffers (v4l_buffers[i]) */
4532 map = kmalloc(sizeof(struct zoran_mapping), GFP_KERNEL);
4533 if (!map) {
4534 res = -ENOMEM;
4535 goto jpg_mmap_unlock_and_return;
4536 }
4537 map->file = file;
4538 map->count = 1;
4539
4540 vma->vm_ops = &zoran_vm_ops;
4541 vma->vm_flags |= VM_DONTEXPAND;
4542 vma->vm_private_data = map;
4543
4544 for (i = first; i <= last; i++) {
4545 for (j = 0;
4546 j < fh->jpg_buffers.buffer_size / PAGE_SIZE;
4547 j++) {
4548 fraglen =
4549 (le32_to_cpu(fh->jpg_buffers.buffer[i].
4550 frag_tab[2 * j + 1]) & ~1) << 1;
4551 todo = size;
4552 if (todo > fraglen)
4553 todo = fraglen;
4554 pos =
4555 le32_to_cpu((unsigned long) fh->jpg_buffers.
4556 buffer[i].frag_tab[2 * j]);
4557 /* should just be pos on i386 */
4558 page = virt_to_phys(bus_to_virt(pos))
4559 >> PAGE_SHIFT;
4560 if (remap_pfn_range(vma, start, page,
4561 todo, PAGE_SHARED)) {
4562 dprintk(1,
4563 KERN_ERR
4564 "%s: zoran_mmap(V4L) - remap_pfn_range failed\n",
4565 ZR_DEVNAME(zr));
4566 res = -EAGAIN;
4567 goto jpg_mmap_unlock_and_return;
4568 }
4569 size -= todo;
4570 start += todo;
4571 if (size == 0)
4572 break;
4573 if (le32_to_cpu(fh->jpg_buffers.buffer[i].
4574 frag_tab[2 * j + 1]) & 1)
4575 break; /* was last fragment */
4576 }
4577 fh->jpg_buffers.buffer[i].map = map;
4578 if (size == 0)
4579 break;
4580
4581 }
4582 jpg_mmap_unlock_and_return:
4583 up(&zr->resource_lock);
4584
4585 break;
4586
4587 case ZORAN_MAP_MODE_RAW:
4588
4589 down(&zr->resource_lock);
4590
4591 /* Map the V4L buffers */
4592 if (!fh->v4l_buffers.allocated) {
4593 dprintk(1,
4594 KERN_ERR
4595 "%s: zoran_mmap(V4L) - buffers not yet allocated\n",
4596 ZR_DEVNAME(zr));
4597 res = -ENOMEM;
4598 goto v4l_mmap_unlock_and_return;
4599 }
4600
4601 first = offset / fh->v4l_buffers.buffer_size;
4602 last = first - 1 + size / fh->v4l_buffers.buffer_size;
4603 if (offset % fh->v4l_buffers.buffer_size != 0 ||
4604 size % fh->v4l_buffers.buffer_size != 0 || first < 0 ||
4605 last < 0 || first >= fh->v4l_buffers.num_buffers ||
4606 last >= fh->v4l_buffers.buffer_size) {
4607 dprintk(1,
4608 KERN_ERR
4609 "%s: mmap(V4L) - offset=%lu or size=%lu invalid for bufsize=%d and numbufs=%d\n",
4610 ZR_DEVNAME(zr), offset, size,
4611 fh->v4l_buffers.buffer_size,
4612 fh->v4l_buffers.num_buffers);
4613 res = -EINVAL;
4614 goto v4l_mmap_unlock_and_return;
4615 }
4616 for (i = first; i <= last; i++) {
4617 if (fh->v4l_buffers.buffer[i].map) {
4618 dprintk(1,
4619 KERN_ERR
4620 "%s: mmap(V4L) - buffer %d already mapped\n",
4621 ZR_DEVNAME(zr), i);
4622 res = -EBUSY;
4623 goto v4l_mmap_unlock_and_return;
4624 }
4625 }
4626
4627 /* map these buffers (v4l_buffers[i]) */
4628 map = kmalloc(sizeof(struct zoran_mapping), GFP_KERNEL);
4629 if (!map) {
4630 res = -ENOMEM;
4631 goto v4l_mmap_unlock_and_return;
4632 }
4633 map->file = file;
4634 map->count = 1;
4635
4636 vma->vm_ops = &zoran_vm_ops;
4637 vma->vm_flags |= VM_DONTEXPAND;
4638 vma->vm_private_data = map;
4639
4640 for (i = first; i <= last; i++) {
4641 todo = size;
4642 if (todo > fh->v4l_buffers.buffer_size)
4643 todo = fh->v4l_buffers.buffer_size;
4644 page = fh->v4l_buffers.buffer[i].fbuffer_phys;
4645 if (remap_pfn_range(vma, start, page >> PAGE_SHIFT,
4646 todo, PAGE_SHARED)) {
4647 dprintk(1,
4648 KERN_ERR
4649 "%s: zoran_mmap(V4L)i - remap_pfn_range failed\n",
4650 ZR_DEVNAME(zr));
4651 res = -EAGAIN;
4652 goto v4l_mmap_unlock_and_return;
4653 }
4654 size -= todo;
4655 start += todo;
4656 fh->v4l_buffers.buffer[i].map = map;
4657 if (size == 0)
4658 break;
4659 }
4660 v4l_mmap_unlock_and_return:
4661 up(&zr->resource_lock);
4662
4663 break;
4664
4665 default:
4666 dprintk(1,
4667 KERN_ERR
4668 "%s: zoran_mmap() - internal error - unknown map mode %d\n",
4669 ZR_DEVNAME(zr), fh->map_mode);
4670 break;
4671 }
4672
4673 return 0;
4674}
4675
4676static struct file_operations zoran_fops = {
4677 .owner = THIS_MODULE,
4678 .open = zoran_open,
4679 .release = zoran_close,
4680 .ioctl = zoran_ioctl,
4681 .llseek = no_llseek,
4682 .read = zoran_read,
4683 .write = zoran_write,
4684 .mmap = zoran_mmap,
4685 .poll = zoran_poll,
4686};
4687
4688struct video_device zoran_template __devinitdata = {
4689 .name = ZORAN_NAME,
4690 .type = ZORAN_VID_TYPE,
4691#ifdef HAVE_V4L2
4692 .type2 = ZORAN_V4L2_VID_FLAGS,
4693#endif
4694 .hardware = ZORAN_HARDWARE,
4695 .fops = &zoran_fops,
4696 .release = &zoran_vdev_release,
4697 .minor = -1
4698};
4699
diff --git a/drivers/media/video/zoran_procfs.c b/drivers/media/video/zoran_procfs.c
new file mode 100644
index 00000000000..f0d9b13c3c6
--- /dev/null
+++ b/drivers/media/video/zoran_procfs.c
@@ -0,0 +1,233 @@
1/*
2 * Zoran zr36057/zr36067 PCI controller driver, for the
3 * Pinnacle/Miro DC10/DC10+/DC30/DC30+, Iomega Buz, Linux
4 * Media Labs LML33/LML33R10.
5 *
6 * This part handles the procFS entries (/proc/ZORAN[%d])
7 *
8 * Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>
9 *
10 * Currently maintained by:
11 * Ronald Bultje <rbultje@ronald.bitfreak.net>
12 * Laurent Pinchart <laurent.pinchart@skynet.be>
13 * Mailinglist <mjpeg-users@lists.sf.net>
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 */
29
30#include <linux/config.h>
31#include <linux/types.h>
32#include <linux/kernel.h>
33#include <linux/module.h>
34#include <linux/vmalloc.h>
35
36#include <linux/proc_fs.h>
37#include <linux/pci.h>
38#include <linux/i2c.h>
39#include <linux/i2c-algo-bit.h>
40#include <linux/videodev.h>
41#include <linux/spinlock.h>
42#include <linux/sem.h>
43#include <linux/seq_file.h>
44
45#include <linux/ctype.h>
46#include <asm/io.h>
47
48#include "videocodec.h"
49#include "zoran.h"
50#include "zoran_procfs.h"
51
52extern int *zr_debug;
53
54#define dprintk(num, format, args...) \
55 do { \
56 if (*zr_debug >= num) \
57 printk(format, ##args); \
58 } while (0)
59
60#ifdef CONFIG_PROC_FS
61struct procfs_params_zr36067 {
62 char *name;
63 short reg;
64 u32 mask;
65 short bit;
66};
67
68static const struct procfs_params_zr36067 zr67[] = {
69 {"HSPol", 0x000, 1, 30},
70 {"HStart", 0x000, 0x3ff, 10},
71 {"HEnd", 0x000, 0x3ff, 0},
72
73 {"VSPol", 0x004, 1, 30},
74 {"VStart", 0x004, 0x3ff, 10},
75 {"VEnd", 0x004, 0x3ff, 0},
76
77 {"ExtFl", 0x008, 1, 26},
78 {"TopField", 0x008, 1, 25},
79 {"VCLKPol", 0x008, 1, 24},
80 {"DupFld", 0x008, 1, 20},
81 {"LittleEndian", 0x008, 1, 0},
82
83 {"HsyncStart", 0x10c, 0xffff, 16},
84 {"LineTot", 0x10c, 0xffff, 0},
85
86 {"NAX", 0x110, 0xffff, 16},
87 {"PAX", 0x110, 0xffff, 0},
88
89 {"NAY", 0x114, 0xffff, 16},
90 {"PAY", 0x114, 0xffff, 0},
91
92 /* {"",,,}, */
93
94 {NULL, 0, 0, 0},
95};
96
97static void
98setparam (struct zoran *zr,
99 char *name,
100 char *sval)
101{
102 int i = 0, reg0, reg, val;
103
104 while (zr67[i].name != NULL) {
105 if (!strncmp(name, zr67[i].name, strlen(zr67[i].name))) {
106 reg = reg0 = btread(zr67[i].reg);
107 reg &= ~(zr67[i].mask << zr67[i].bit);
108 if (!isdigit(sval[0]))
109 break;
110 val = simple_strtoul(sval, NULL, 0);
111 if ((val & ~zr67[i].mask))
112 break;
113 reg |= (val & zr67[i].mask) << zr67[i].bit;
114 dprintk(4,
115 KERN_INFO
116 "%s: setparam: setting ZR36067 register 0x%03x: 0x%08x=>0x%08x %s=%d\n",
117 ZR_DEVNAME(zr), zr67[i].reg, reg0, reg,
118 zr67[i].name, val);
119 btwrite(reg, zr67[i].reg);
120 break;
121 }
122 i++;
123 }
124}
125
126static int zoran_show(struct seq_file *p, void *v)
127{
128 struct zoran *zr = p->private;
129 int i;
130
131 seq_printf(p, "ZR36067 registers:\n");
132 for (i = 0; i < 0x130; i += 16)
133 seq_printf(p, "%03X %08X %08X %08X %08X \n", i,
134 btread(i), btread(i+4), btread(i+8), btread(i+12));
135 return 0;
136}
137
138static int zoran_open(struct inode *inode, struct file *file)
139{
140 struct zoran *data = PDE(inode)->data;
141 return single_open(file, zoran_show, data);
142}
143
144static ssize_t zoran_write(struct file *file, const char __user *buffer,
145 size_t count, loff_t *ppos)
146{
147 struct zoran *zr = PDE(file->f_dentry->d_inode)->data;
148 char *string, *sp;
149 char *line, *ldelim, *varname, *svar, *tdelim;
150
151 if (count > 32768) /* Stupidity filter */
152 return -EINVAL;
153
154 string = sp = vmalloc(count + 1);
155 if (!string) {
156 dprintk(1,
157 KERN_ERR
158 "%s: write_proc: can not allocate memory\n",
159 ZR_DEVNAME(zr));
160 return -ENOMEM;
161 }
162 if (copy_from_user(string, buffer, count)) {
163 vfree (string);
164 return -EFAULT;
165 }
166 string[count] = 0;
167 dprintk(4, KERN_INFO "%s: write_proc: name=%s count=%zu zr=%p\n",
168 ZR_DEVNAME(zr), file->f_dentry->d_name.name, count, zr);
169 ldelim = " \t\n";
170 tdelim = "=";
171 line = strpbrk(sp, ldelim);
172 while (line) {
173 *line = 0;
174 svar = strpbrk(sp, tdelim);
175 if (svar) {
176 *svar = 0;
177 varname = sp;
178 svar++;
179 setparam(zr, varname, svar);
180 }
181 sp = line + 1;
182 line = strpbrk(sp, ldelim);
183 }
184 vfree(string);
185
186 return count;
187}
188
189static struct file_operations zoran_operations = {
190 .open = zoran_open,
191 .read = seq_read,
192 .write = zoran_write,
193 .llseek = seq_lseek,
194 .release = single_release,
195};
196#endif
197
198int
199zoran_proc_init (struct zoran *zr)
200{
201#ifdef CONFIG_PROC_FS
202 char name[8];
203
204 snprintf(name, 7, "zoran%d", zr->id);
205 if ((zr->zoran_proc = create_proc_entry(name, 0, NULL))) {
206 zr->zoran_proc->data = zr;
207 zr->zoran_proc->owner = THIS_MODULE;
208 zr->zoran_proc->proc_fops = &zoran_operations;
209 dprintk(2,
210 KERN_INFO
211 "%s: procfs entry /proc/%s allocated. data=%p\n",
212 ZR_DEVNAME(zr), name, zr->zoran_proc->data);
213 } else {
214 dprintk(1, KERN_ERR "%s: Unable to initialise /proc/%s\n",
215 ZR_DEVNAME(zr), name);
216 return 1;
217 }
218#endif
219 return 0;
220}
221
222void
223zoran_proc_cleanup (struct zoran *zr)
224{
225#ifdef CONFIG_PROC_FS
226 char name[8];
227
228 snprintf(name, 7, "zoran%d", zr->id);
229 if (zr->zoran_proc)
230 remove_proc_entry(name, NULL);
231 zr->zoran_proc = NULL;
232#endif
233}
diff --git a/drivers/media/video/zoran_procfs.h b/drivers/media/video/zoran_procfs.h
new file mode 100644
index 00000000000..8904fc95955
--- /dev/null
+++ b/drivers/media/video/zoran_procfs.h
@@ -0,0 +1,36 @@
1/*
2 * Zoran zr36057/zr36067 PCI controller driver, for the
3 * Pinnacle/Miro DC10/DC10+/DC30/DC30+, Iomega Buz, Linux
4 * Media Labs LML33/LML33R10.
5 *
6 * This part handles card-specific data and detection
7 *
8 * Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>
9 *
10 * Currently maintained by:
11 * Ronald Bultje <rbultje@ronald.bitfreak.net>
12 * Laurent Pinchart <laurent.pinchart@skynet.be>
13 * Mailinglist <mjpeg-users@lists.sf.net>
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 */
29
30#ifndef __ZORAN_PROCFS_H__
31#define __ZORAN_PROCFS_H__
32
33extern int zoran_proc_init(struct zoran *zr);
34extern void zoran_proc_cleanup(struct zoran *zr);
35
36#endif /* __ZORAN_PROCFS_H__ */
diff --git a/drivers/media/video/zr36016.c b/drivers/media/video/zr36016.c
new file mode 100644
index 00000000000..d4740a89cea
--- /dev/null
+++ b/drivers/media/video/zr36016.c
@@ -0,0 +1,532 @@
1/*
2 * Zoran ZR36016 basic configuration functions
3 *
4 * Copyright (C) 2001 Wolfgang Scherr <scherr@net4you.at>
5 *
6 * $Id: zr36016.c,v 1.1.2.14 2003/08/20 19:46:55 rbultje Exp $
7 *
8 * ------------------------------------------------------------------------
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 */
26
27#define ZR016_VERSION "v0.7"
28
29#include <linux/version.h>
30#include <linux/module.h>
31#include <linux/init.h>
32#include <linux/slab.h>
33#include <linux/delay.h>
34
35#include <linux/types.h>
36#include <linux/wait.h>
37
38/* includes for structures and defines regarding video
39 #include<linux/videodev.h> */
40
41/* I/O commands, error codes */
42#include<asm/io.h>
43//#include<errno.h>
44
45/* v4l API */
46#include<linux/videodev.h>
47
48/* headerfile of this module */
49#include"zr36016.h"
50
51/* codec io API */
52#include"videocodec.h"
53
54/* it doesn't make sense to have more than 20 or so,
55 just to prevent some unwanted loops */
56#define MAX_CODECS 20
57
58/* amount of chips attached via this driver */
59static int zr36016_codecs = 0;
60
61/* debugging is available via module parameter */
62
63static int debug = 0;
64module_param(debug, int, 0);
65MODULE_PARM_DESC(debug, "Debug level (0-4)");
66
67#define dprintk(num, format, args...) \
68 do { \
69 if (debug >= num) \
70 printk(format, ##args); \
71 } while (0)
72
73/* =========================================================================
74 Local hardware I/O functions:
75
76 read/write via codec layer (registers are located in the master device)
77 ========================================================================= */
78
79/* read and write functions */
80static u8
81zr36016_read (struct zr36016 *ptr,
82 u16 reg)
83{
84 u8 value = 0;
85
86 // just in case something is wrong...
87 if (ptr->codec->master_data->readreg)
88 value =
89 (ptr->codec->master_data->
90 readreg(ptr->codec, reg)) & 0xFF;
91 else
92 dprintk(1,
93 KERN_ERR "%s: invalid I/O setup, nothing read!\n",
94 ptr->name);
95
96 dprintk(4, "%s: reading from 0x%04x: %02x\n", ptr->name, reg,
97 value);
98
99 return value;
100}
101
102static void
103zr36016_write (struct zr36016 *ptr,
104 u16 reg,
105 u8 value)
106{
107 dprintk(4, "%s: writing 0x%02x to 0x%04x\n", ptr->name, value,
108 reg);
109
110 // just in case something is wrong...
111 if (ptr->codec->master_data->writereg) {
112 ptr->codec->master_data->writereg(ptr->codec, reg, value);
113 } else
114 dprintk(1,
115 KERN_ERR
116 "%s: invalid I/O setup, nothing written!\n",
117 ptr->name);
118}
119
120/* indirect read and write functions */
121/* the 016 supports auto-addr-increment, but
122 * writing it all time cost not much and is safer... */
123static u8
124zr36016_readi (struct zr36016 *ptr,
125 u16 reg)
126{
127 u8 value = 0;
128
129 // just in case something is wrong...
130 if ((ptr->codec->master_data->writereg) &&
131 (ptr->codec->master_data->readreg)) {
132 ptr->codec->master_data->writereg(ptr->codec, ZR016_IADDR, reg & 0x0F); // ADDR
133 value = (ptr->codec->master_data->readreg(ptr->codec, ZR016_IDATA)) & 0xFF; // DATA
134 } else
135 dprintk(1,
136 KERN_ERR
137 "%s: invalid I/O setup, nothing read (i)!\n",
138 ptr->name);
139
140 dprintk(4, "%s: reading indirect from 0x%04x: %02x\n", ptr->name,
141 reg, value);
142 return value;
143}
144
145static void
146zr36016_writei (struct zr36016 *ptr,
147 u16 reg,
148 u8 value)
149{
150 dprintk(4, "%s: writing indirect 0x%02x to 0x%04x\n", ptr->name,
151 value, reg);
152
153 // just in case something is wrong...
154 if (ptr->codec->master_data->writereg) {
155 ptr->codec->master_data->writereg(ptr->codec, ZR016_IADDR, reg & 0x0F); // ADDR
156 ptr->codec->master_data->writereg(ptr->codec, ZR016_IDATA, value & 0x0FF); // DATA
157 } else
158 dprintk(1,
159 KERN_ERR
160 "%s: invalid I/O setup, nothing written (i)!\n",
161 ptr->name);
162}
163
164/* =========================================================================
165 Local helper function:
166
167 version read
168 ========================================================================= */
169
170/* version kept in datastructure */
171static u8
172zr36016_read_version (struct zr36016 *ptr)
173{
174 ptr->version = zr36016_read(ptr, 0) >> 4;
175 return ptr->version;
176}
177
178/* =========================================================================
179 Local helper function:
180
181 basic test of "connectivity", writes/reads to/from PAX-Lo register
182 ========================================================================= */
183
184static int
185zr36016_basic_test (struct zr36016 *ptr)
186{
187 if (debug) {
188 int i;
189 zr36016_writei(ptr, ZR016I_PAX_LO, 0x55);
190 dprintk(1, KERN_INFO "%s: registers: ", ptr->name);
191 for (i = 0; i <= 0x0b; i++)
192 dprintk(1, "%02x ", zr36016_readi(ptr, i));
193 dprintk(1, "\n");
194 }
195 // for testing just write 0, then the default value to a register and read
196 // it back in both cases
197 zr36016_writei(ptr, ZR016I_PAX_LO, 0x00);
198 if (zr36016_readi(ptr, ZR016I_PAX_LO) != 0x0) {
199 dprintk(1,
200 KERN_ERR
201 "%s: attach failed, can't connect to vfe processor!\n",
202 ptr->name);
203 return -ENXIO;
204 }
205 zr36016_writei(ptr, ZR016I_PAX_LO, 0x0d0);
206 if (zr36016_readi(ptr, ZR016I_PAX_LO) != 0x0d0) {
207 dprintk(1,
208 KERN_ERR
209 "%s: attach failed, can't connect to vfe processor!\n",
210 ptr->name);
211 return -ENXIO;
212 }
213 // we allow version numbers from 0-3, should be enough, though
214 zr36016_read_version(ptr);
215 if (ptr->version & 0x0c) {
216 dprintk(1,
217 KERN_ERR
218 "%s: attach failed, suspicious version %d found...\n",
219 ptr->name, ptr->version);
220 return -ENXIO;
221 }
222
223 return 0; /* looks good! */
224}
225
226/* =========================================================================
227 Local helper function:
228
229 simple loop for pushing the init datasets - NO USE --
230 ========================================================================= */
231
232#if 0
233static int zr36016_pushit (struct zr36016 *ptr,
234 u16 startreg,
235 u16 len,
236 const char *data)
237{
238 int i=0;
239
240 dprintk(4, "%s: write data block to 0x%04x (len=%d)\n",
241 ptr->name, startreg,len);
242 while (i<len) {
243 zr36016_writei(ptr, startreg++, data[i++]);
244 }
245
246 return i;
247}
248#endif
249
250/* =========================================================================
251 Basic datasets & init:
252
253 //TODO//
254 ========================================================================= */
255
256// needed offset values PAL NTSC SECAM
257static const int zr016_xoff[] = { 20, 20, 20 };
258static const int zr016_yoff[] = { 8, 9, 7 };
259
260static void
261zr36016_init (struct zr36016 *ptr)
262{
263 // stop any processing
264 zr36016_write(ptr, ZR016_GOSTOP, 0);
265
266 // mode setup (yuv422 in and out, compression/expansuon due to mode)
267 zr36016_write(ptr, ZR016_MODE,
268 ZR016_YUV422 | ZR016_YUV422_YUV422 |
269 (ptr->mode == CODEC_DO_COMPRESSION ?
270 ZR016_COMPRESSION : ZR016_EXPANSION));
271
272 // misc setup
273 zr36016_writei(ptr, ZR016I_SETUP1,
274 (ptr->xdec ? (ZR016_HRFL | ZR016_HORZ) : 0) |
275 (ptr->ydec ? ZR016_VERT : 0) | ZR016_CNTI);
276 zr36016_writei(ptr, ZR016I_SETUP2, ZR016_CCIR);
277
278 // Window setup
279 // (no extra offset for now, norm defines offset, default width height)
280 zr36016_writei(ptr, ZR016I_PAX_HI, ptr->width >> 8);
281 zr36016_writei(ptr, ZR016I_PAX_LO, ptr->width & 0xFF);
282 zr36016_writei(ptr, ZR016I_PAY_HI, ptr->height >> 8);
283 zr36016_writei(ptr, ZR016I_PAY_LO, ptr->height & 0xFF);
284 zr36016_writei(ptr, ZR016I_NAX_HI, ptr->xoff >> 8);
285 zr36016_writei(ptr, ZR016I_NAX_LO, ptr->xoff & 0xFF);
286 zr36016_writei(ptr, ZR016I_NAY_HI, ptr->yoff >> 8);
287 zr36016_writei(ptr, ZR016I_NAY_LO, ptr->yoff & 0xFF);
288
289 /* shall we continue now, please? */
290 zr36016_write(ptr, ZR016_GOSTOP, 1);
291}
292
293/* =========================================================================
294 CODEC API FUNCTIONS
295
296 this functions are accessed by the master via the API structure
297 ========================================================================= */
298
299/* set compression/expansion mode and launches codec -
300 this should be the last call from the master before starting processing */
301static int
302zr36016_set_mode (struct videocodec *codec,
303 int mode)
304{
305 struct zr36016 *ptr = (struct zr36016 *) codec->data;
306
307 dprintk(2, "%s: set_mode %d call\n", ptr->name, mode);
308
309 if ((mode != CODEC_DO_EXPANSION) && (mode != CODEC_DO_COMPRESSION))
310 return -EINVAL;
311
312 ptr->mode = mode;
313 zr36016_init(ptr);
314
315 return 0;
316}
317
318/* set picture size */
319static int
320zr36016_set_video (struct videocodec *codec,
321 struct tvnorm *norm,
322 struct vfe_settings *cap,
323 struct vfe_polarity *pol)
324{
325 struct zr36016 *ptr = (struct zr36016 *) codec->data;
326
327 dprintk(2, "%s: set_video %d.%d, %d/%d-%dx%d (0x%x) call\n",
328 ptr->name, norm->HStart, norm->VStart,
329 cap->x, cap->y, cap->width, cap->height,
330 cap->decimation);
331
332 /* if () return -EINVAL;
333 * trust the master driver that it knows what it does - so
334 * we allow invalid startx/y for now ... */
335 ptr->width = cap->width;
336 ptr->height = cap->height;
337 /* (Ronald) This is ugly. zoran_device.c, line 387
338 * already mentions what happens if HStart is even
339 * (blue faces, etc., cr/cb inversed). There's probably
340 * some good reason why HStart is 0 instead of 1, so I'm
341 * leaving it to this for now, but really... This can be
342 * done a lot simpler */
343 ptr->xoff = (norm->HStart ? norm->HStart : 1) + cap->x;
344 /* Something to note here (I don't understand it), setting
345 * VStart too high will cause the codec to 'not work'. I
346 * really don't get it. values of 16 (VStart) already break
347 * it here. Just '0' seems to work. More testing needed! */
348 ptr->yoff = norm->VStart + cap->y;
349 /* (Ronald) dzjeeh, can't this thing do hor_decimation = 4? */
350 ptr->xdec = ((cap->decimation & 0xff) == 1) ? 0 : 1;
351 ptr->ydec = (((cap->decimation >> 8) & 0xff) == 1) ? 0 : 1;
352
353 return 0;
354}
355
356/* additional control functions */
357static int
358zr36016_control (struct videocodec *codec,
359 int type,
360 int size,
361 void *data)
362{
363 struct zr36016 *ptr = (struct zr36016 *) codec->data;
364 int *ival = (int *) data;
365
366 dprintk(2, "%s: control %d call with %d byte\n", ptr->name, type,
367 size);
368
369 switch (type) {
370 case CODEC_G_STATUS: /* get last status - we don't know it ... */
371 if (size != sizeof(int))
372 return -EFAULT;
373 *ival = 0;
374 break;
375
376 case CODEC_G_CODEC_MODE:
377 if (size != sizeof(int))
378 return -EFAULT;
379 *ival = 0;
380 break;
381
382 case CODEC_S_CODEC_MODE:
383 if (size != sizeof(int))
384 return -EFAULT;
385 if (*ival != 0)
386 return -EINVAL;
387 /* not needed, do nothing */
388 return 0;
389
390 case CODEC_G_VFE:
391 case CODEC_S_VFE:
392 return 0;
393
394 case CODEC_S_MMAP:
395 /* not available, give an error */
396 return -ENXIO;
397
398 default:
399 return -EINVAL;
400 }
401
402 return size;
403}
404
405/* =========================================================================
406 Exit and unregister function:
407
408 Deinitializes Zoran's JPEG processor
409 ========================================================================= */
410
411static int
412zr36016_unset (struct videocodec *codec)
413{
414 struct zr36016 *ptr = codec->data;
415
416 if (ptr) {
417 /* do wee need some codec deinit here, too ???? */
418
419 dprintk(1, "%s: finished codec #%d\n", ptr->name,
420 ptr->num);
421 kfree(ptr);
422 codec->data = NULL;
423
424 zr36016_codecs--;
425 return 0;
426 }
427
428 return -EFAULT;
429}
430
431/* =========================================================================
432 Setup and registry function:
433
434 Initializes Zoran's JPEG processor
435
436 Also sets pixel size, average code size, mode (compr./decompr.)
437 (the given size is determined by the processor with the video interface)
438 ========================================================================= */
439
440static int
441zr36016_setup (struct videocodec *codec)
442{
443 struct zr36016 *ptr;
444 int res;
445
446 dprintk(2, "zr36016: initializing VFE subsystem #%d.\n",
447 zr36016_codecs);
448
449 if (zr36016_codecs == MAX_CODECS) {
450 dprintk(1,
451 KERN_ERR "zr36016: Can't attach more codecs!\n");
452 return -ENOSPC;
453 }
454 //mem structure init
455 codec->data = ptr = kmalloc(sizeof(struct zr36016), GFP_KERNEL);
456 if (NULL == ptr) {
457 dprintk(1, KERN_ERR "zr36016: Can't get enough memory!\n");
458 return -ENOMEM;
459 }
460 memset(ptr, 0, sizeof(struct zr36016));
461
462 snprintf(ptr->name, sizeof(ptr->name), "zr36016[%d]",
463 zr36016_codecs);
464 ptr->num = zr36016_codecs++;
465 ptr->codec = codec;
466
467 //testing
468 res = zr36016_basic_test(ptr);
469 if (res < 0) {
470 zr36016_unset(codec);
471 return res;
472 }
473 //final setup
474 ptr->mode = CODEC_DO_COMPRESSION;
475 ptr->width = 768;
476 ptr->height = 288;
477 ptr->xdec = 1;
478 ptr->ydec = 0;
479 zr36016_init(ptr);
480
481 dprintk(1, KERN_INFO "%s: codec v%d attached and running\n",
482 ptr->name, ptr->version);
483
484 return 0;
485}
486
487static const struct videocodec zr36016_codec = {
488 .owner = THIS_MODULE,
489 .name = "zr36016",
490 .magic = 0L, // magic not used
491 .flags =
492 CODEC_FLAG_HARDWARE | CODEC_FLAG_VFE | CODEC_FLAG_ENCODER |
493 CODEC_FLAG_DECODER,
494 .type = CODEC_TYPE_ZR36016,
495 .setup = zr36016_setup, // functionality
496 .unset = zr36016_unset,
497 .set_mode = zr36016_set_mode,
498 .set_video = zr36016_set_video,
499 .control = zr36016_control,
500 // others are not used
501};
502
503/* =========================================================================
504 HOOK IN DRIVER AS KERNEL MODULE
505 ========================================================================= */
506
507static int __init
508zr36016_init_module (void)
509{
510 //dprintk(1, "ZR36016 driver %s\n",ZR016_VERSION);
511 zr36016_codecs = 0;
512 return videocodec_register(&zr36016_codec);
513}
514
515static void __exit
516zr36016_cleanup_module (void)
517{
518 if (zr36016_codecs) {
519 dprintk(1,
520 "zr36016: something's wrong - %d codecs left somehow.\n",
521 zr36016_codecs);
522 }
523 videocodec_unregister(&zr36016_codec);
524}
525
526module_init(zr36016_init_module);
527module_exit(zr36016_cleanup_module);
528
529MODULE_AUTHOR("Wolfgang Scherr <scherr@net4you.at>");
530MODULE_DESCRIPTION("Driver module for ZR36016 video frontends "
531 ZR016_VERSION);
532MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/zr36016.h b/drivers/media/video/zr36016.h
new file mode 100644
index 00000000000..8c79229f69d
--- /dev/null
+++ b/drivers/media/video/zr36016.h
@@ -0,0 +1,111 @@
1/*
2 * Zoran ZR36016 basic configuration functions - header file
3 *
4 * Copyright (C) 2001 Wolfgang Scherr <scherr@net4you.at>
5 *
6 * $Id: zr36016.h,v 1.1.2.3 2003/01/14 21:18:07 rbultje Exp $
7 *
8 * ------------------------------------------------------------------------
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 */
26
27#ifndef ZR36016_H
28#define ZR36016_H
29
30/* data stored for each zoran jpeg codec chip */
31struct zr36016 {
32 char name[32];
33 int num;
34 /* io datastructure */
35 struct videocodec *codec;
36 // coder status
37 __u8 version;
38 // actual coder setup
39 int mode;
40
41 __u16 xoff;
42 __u16 yoff;
43 __u16 width;
44 __u16 height;
45 __u16 xdec;
46 __u16 ydec;
47};
48
49/* direct register addresses */
50#define ZR016_GOSTOP 0x00
51#define ZR016_MODE 0x01
52#define ZR016_IADDR 0x02
53#define ZR016_IDATA 0x03
54
55/* indirect register addresses */
56#define ZR016I_SETUP1 0x00
57#define ZR016I_SETUP2 0x01
58#define ZR016I_NAX_LO 0x02
59#define ZR016I_NAX_HI 0x03
60#define ZR016I_PAX_LO 0x04
61#define ZR016I_PAX_HI 0x05
62#define ZR016I_NAY_LO 0x06
63#define ZR016I_NAY_HI 0x07
64#define ZR016I_PAY_LO 0x08
65#define ZR016I_PAY_HI 0x09
66#define ZR016I_NOL_LO 0x0a
67#define ZR016I_NOL_HI 0x0b
68
69/* possible values for mode register */
70#define ZR016_RGB444_YUV444 0x00
71#define ZR016_RGB444_YUV422 0x01
72#define ZR016_RGB444_YUV411 0x02
73#define ZR016_RGB444_Y400 0x03
74#define ZR016_RGB444_RGB444 0x04
75#define ZR016_YUV444_YUV444 0x08
76#define ZR016_YUV444_YUV422 0x09
77#define ZR016_YUV444_YUV411 0x0a
78#define ZR016_YUV444_Y400 0x0b
79#define ZR016_YUV444_RGB444 0x0c
80#define ZR016_YUV422_YUV422 0x11
81#define ZR016_YUV422_YUV411 0x12
82#define ZR016_YUV422_Y400 0x13
83#define ZR016_YUV411_YUV411 0x16
84#define ZR016_YUV411_Y400 0x17
85#define ZR016_4444_4444 0x19
86#define ZR016_100_100 0x1b
87
88#define ZR016_RGB444 0x00
89#define ZR016_YUV444 0x20
90#define ZR016_YUV422 0x40
91
92#define ZR016_COMPRESSION 0x80
93#define ZR016_EXPANSION 0x80
94
95/* possible values for setup 1 register */
96#define ZR016_CKRT 0x80
97#define ZR016_VERT 0x40
98#define ZR016_HORZ 0x20
99#define ZR016_HRFL 0x10
100#define ZR016_DSFL 0x08
101#define ZR016_SBFL 0x04
102#define ZR016_RSTR 0x02
103#define ZR016_CNTI 0x01
104
105/* possible values for setup 2 register */
106#define ZR016_SYEN 0x40
107#define ZR016_CCIR 0x04
108#define ZR016_SIGN 0x02
109#define ZR016_YMCS 0x01
110
111#endif /*fndef ZR36016_H */
diff --git a/drivers/media/video/zr36050.c b/drivers/media/video/zr36050.c
new file mode 100644
index 00000000000..13b1e7b6fd6
--- /dev/null
+++ b/drivers/media/video/zr36050.c
@@ -0,0 +1,907 @@
1/*
2 * Zoran ZR36050 basic configuration functions
3 *
4 * Copyright (C) 2001 Wolfgang Scherr <scherr@net4you.at>
5 *
6 * $Id: zr36050.c,v 1.1.2.11 2003/08/03 14:54:53 rbultje Exp $
7 *
8 * ------------------------------------------------------------------------
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 */
26
27#define ZR050_VERSION "v0.7.1"
28
29#include <linux/version.h>
30#include <linux/module.h>
31#include <linux/init.h>
32#include <linux/slab.h>
33#include <linux/delay.h>
34
35#include <linux/types.h>
36#include <linux/wait.h>
37
38/* includes for structures and defines regarding video
39 #include<linux/videodev.h> */
40
41/* I/O commands, error codes */
42#include<asm/io.h>
43//#include<errno.h>
44
45/* headerfile of this module */
46#include"zr36050.h"
47
48/* codec io API */
49#include"videocodec.h"
50
51/* it doesn't make sense to have more than 20 or so,
52 just to prevent some unwanted loops */
53#define MAX_CODECS 20
54
55/* amount of chips attached via this driver */
56static int zr36050_codecs = 0;
57
58/* debugging is available via module parameter */
59
60static int debug = 0;
61module_param(debug, int, 0);
62MODULE_PARM_DESC(debug, "Debug level (0-4)");
63
64#define dprintk(num, format, args...) \
65 do { \
66 if (debug >= num) \
67 printk(format, ##args); \
68 } while (0)
69
70/* =========================================================================
71 Local hardware I/O functions:
72
73 read/write via codec layer (registers are located in the master device)
74 ========================================================================= */
75
76/* read and write functions */
77static u8
78zr36050_read (struct zr36050 *ptr,
79 u16 reg)
80{
81 u8 value = 0;
82
83 // just in case something is wrong...
84 if (ptr->codec->master_data->readreg)
85 value = (ptr->codec->master_data->readreg(ptr->codec,
86 reg)) & 0xFF;
87 else
88 dprintk(1,
89 KERN_ERR "%s: invalid I/O setup, nothing read!\n",
90 ptr->name);
91
92 dprintk(4, "%s: reading from 0x%04x: %02x\n", ptr->name, reg,
93 value);
94
95 return value;
96}
97
98static void
99zr36050_write (struct zr36050 *ptr,
100 u16 reg,
101 u8 value)
102{
103 dprintk(4, "%s: writing 0x%02x to 0x%04x\n", ptr->name, value,
104 reg);
105
106 // just in case something is wrong...
107 if (ptr->codec->master_data->writereg)
108 ptr->codec->master_data->writereg(ptr->codec, reg, value);
109 else
110 dprintk(1,
111 KERN_ERR
112 "%s: invalid I/O setup, nothing written!\n",
113 ptr->name);
114}
115
116/* =========================================================================
117 Local helper function:
118
119 status read
120 ========================================================================= */
121
122/* status is kept in datastructure */
123static u8
124zr36050_read_status1 (struct zr36050 *ptr)
125{
126 ptr->status1 = zr36050_read(ptr, ZR050_STATUS_1);
127
128 zr36050_read(ptr, 0);
129 return ptr->status1;
130}
131
132/* =========================================================================
133 Local helper function:
134
135 scale factor read
136 ========================================================================= */
137
138/* scale factor is kept in datastructure */
139static u16
140zr36050_read_scalefactor (struct zr36050 *ptr)
141{
142 ptr->scalefact = (zr36050_read(ptr, ZR050_SF_HI) << 8) |
143 (zr36050_read(ptr, ZR050_SF_LO) & 0xFF);
144
145 /* leave 0 selected for an eventually GO from master */
146 zr36050_read(ptr, 0);
147 return ptr->scalefact;
148}
149
150/* =========================================================================
151 Local helper function:
152
153 wait if codec is ready to proceed (end of processing) or time is over
154 ========================================================================= */
155
156static void
157zr36050_wait_end (struct zr36050 *ptr)
158{
159 int i = 0;
160
161 while (!(zr36050_read_status1(ptr) & 0x4)) {
162 udelay(1);
163 if (i++ > 200000) { // 200ms, there is for shure something wrong!!!
164 dprintk(1,
165 "%s: timout at wait_end (last status: 0x%02x)\n",
166 ptr->name, ptr->status1);
167 break;
168 }
169 }
170}
171
172/* =========================================================================
173 Local helper function:
174
175 basic test of "connectivity", writes/reads to/from memory the SOF marker
176 ========================================================================= */
177
178static int
179zr36050_basic_test (struct zr36050 *ptr)
180{
181 zr36050_write(ptr, ZR050_SOF_IDX, 0x00);
182 zr36050_write(ptr, ZR050_SOF_IDX + 1, 0x00);
183 if ((zr36050_read(ptr, ZR050_SOF_IDX) |
184 zr36050_read(ptr, ZR050_SOF_IDX + 1)) != 0x0000) {
185 dprintk(1,
186 KERN_ERR
187 "%s: attach failed, can't connect to jpeg processor!\n",
188 ptr->name);
189 return -ENXIO;
190 }
191 zr36050_write(ptr, ZR050_SOF_IDX, 0xff);
192 zr36050_write(ptr, ZR050_SOF_IDX + 1, 0xc0);
193 if (((zr36050_read(ptr, ZR050_SOF_IDX) << 8) |
194 zr36050_read(ptr, ZR050_SOF_IDX + 1)) != 0xffc0) {
195 dprintk(1,
196 KERN_ERR
197 "%s: attach failed, can't connect to jpeg processor!\n",
198 ptr->name);
199 return -ENXIO;
200 }
201
202 zr36050_wait_end(ptr);
203 if ((ptr->status1 & 0x4) == 0) {
204 dprintk(1,
205 KERN_ERR
206 "%s: attach failed, jpeg processor failed (end flag)!\n",
207 ptr->name);
208 return -EBUSY;
209 }
210
211 return 0; /* looks good! */
212}
213
214/* =========================================================================
215 Local helper function:
216
217 simple loop for pushing the init datasets
218 ========================================================================= */
219
220static int
221zr36050_pushit (struct zr36050 *ptr,
222 u16 startreg,
223 u16 len,
224 const char *data)
225{
226 int i = 0;
227
228 dprintk(4, "%s: write data block to 0x%04x (len=%d)\n", ptr->name,
229 startreg, len);
230 while (i < len) {
231 zr36050_write(ptr, startreg++, data[i++]);
232 }
233
234 return i;
235}
236
237/* =========================================================================
238 Basic datasets:
239
240 jpeg baseline setup data (you find it on lots places in internet, or just
241 extract it from any regular .jpg image...)
242
243 Could be variable, but until it's not needed it they are just fixed to save
244 memory. Otherwise expand zr36050 structure with arrays, push the values to
245 it and initalize from there, as e.g. the linux zr36057/60 driver does it.
246 ========================================================================= */
247
248static const char zr36050_dqt[0x86] = {
249 0xff, 0xdb, //Marker: DQT
250 0x00, 0x84, //Length: 2*65+2
251 0x00, //Pq,Tq first table
252 0x10, 0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e,
253 0x0d, 0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28,
254 0x1a, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25,
255 0x1d, 0x28, 0x3a, 0x33, 0x3d, 0x3c, 0x39, 0x33,
256 0x38, 0x37, 0x40, 0x48, 0x5c, 0x4e, 0x40, 0x44,
257 0x57, 0x45, 0x37, 0x38, 0x50, 0x6d, 0x51, 0x57,
258 0x5f, 0x62, 0x67, 0x68, 0x67, 0x3e, 0x4d, 0x71,
259 0x79, 0x70, 0x64, 0x78, 0x5c, 0x65, 0x67, 0x63,
260 0x01, //Pq,Tq second table
261 0x11, 0x12, 0x12, 0x18, 0x15, 0x18, 0x2f, 0x1a,
262 0x1a, 0x2f, 0x63, 0x42, 0x38, 0x42, 0x63, 0x63,
263 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
264 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
265 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
266 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
267 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
268 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63
269};
270
271static const char zr36050_dht[0x1a4] = {
272 0xff, 0xc4, //Marker: DHT
273 0x01, 0xa2, //Length: 2*AC, 2*DC
274 0x00, //DC first table
275 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01,
276 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
277 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
278 0x01, //DC second table
279 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
280 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
281 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
282 0x10, //AC first table
283 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03,
284 0x05, 0x05, 0x04, 0x04, 0x00, 0x00,
285 0x01, 0x7D, 0x01, 0x02, 0x03, 0x00, 0x04, 0x11,
286 0x05, 0x12, 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61,
287 0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xA1,
288 0x08, 0x23, 0x42, 0xB1, 0xC1, 0x15, 0x52, 0xD1, 0xF0, 0x24,
289 0x33, 0x62, 0x72, 0x82, 0x09, 0x0A, 0x16, 0x17,
290 0x18, 0x19, 0x1A, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x34,
291 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44,
292 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56,
293 0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66,
294 0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
295 0x79, 0x7A, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,
296 0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99,
297 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8,
298 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9,
299 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8,
300 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9,
301 0xDA, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
302 0xE8, 0xE9, 0xEA, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
303 0xF8, 0xF9, 0xFA,
304 0x11, //AC second table
305 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04,
306 0x07, 0x05, 0x04, 0x04, 0x00, 0x01,
307 0x02, 0x77, 0x00, 0x01, 0x02, 0x03, 0x11, 0x04,
308 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
309 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
310 0xA1, 0xB1, 0xC1, 0x09, 0x23, 0x33, 0x52, 0xF0, 0x15, 0x62,
311 0x72, 0xD1, 0x0A, 0x16, 0x24, 0x34, 0xE1, 0x25,
312 0xF1, 0x17, 0x18, 0x19, 0x1A, 0x26, 0x27, 0x28, 0x29, 0x2A,
313 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44,
314 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56,
315 0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66,
316 0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
317 0x79, 0x7A, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
318 0x88, 0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
319 0x99, 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
320 0xA8, 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8,
321 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
322 0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8,
323 0xD9, 0xDA, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
324 0xE8, 0xE9, 0xEA, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8,
325 0xF9, 0xFA
326};
327
328/* jpeg baseline setup, this is just fixed in this driver (YUV pictures) */
329#define NO_OF_COMPONENTS 0x3 //Y,U,V
330#define BASELINE_PRECISION 0x8 //MCU size (?)
331static const char zr36050_tq[8] = { 0, 1, 1, 0, 0, 0, 0, 0 }; //table idx's QT
332static const char zr36050_td[8] = { 0, 1, 1, 0, 0, 0, 0, 0 }; //table idx's DC
333static const char zr36050_ta[8] = { 0, 1, 1, 0, 0, 0, 0, 0 }; //table idx's AC
334
335/* horizontal 422 decimation setup (maybe we support 411 or so later, too) */
336static const char zr36050_decimation_h[8] = { 2, 1, 1, 0, 0, 0, 0, 0 };
337static const char zr36050_decimation_v[8] = { 1, 1, 1, 0, 0, 0, 0, 0 };
338
339/* =========================================================================
340 Local helper functions:
341
342 calculation and setup of parameter-dependent JPEG baseline segments
343 (needed for compression only)
344 ========================================================================= */
345
346/* ------------------------------------------------------------------------- */
347
348/* SOF (start of frame) segment depends on width, height and sampling ratio
349 of each color component */
350
351static int
352zr36050_set_sof (struct zr36050 *ptr)
353{
354 char sof_data[34]; // max. size of register set
355 int i;
356
357 dprintk(3, "%s: write SOF (%dx%d, %d components)\n", ptr->name,
358 ptr->width, ptr->height, NO_OF_COMPONENTS);
359 sof_data[0] = 0xff;
360 sof_data[1] = 0xc0;
361 sof_data[2] = 0x00;
362 sof_data[3] = (3 * NO_OF_COMPONENTS) + 8;
363 sof_data[4] = BASELINE_PRECISION; // only '8' possible with zr36050
364 sof_data[5] = (ptr->height) >> 8;
365 sof_data[6] = (ptr->height) & 0xff;
366 sof_data[7] = (ptr->width) >> 8;
367 sof_data[8] = (ptr->width) & 0xff;
368 sof_data[9] = NO_OF_COMPONENTS;
369 for (i = 0; i < NO_OF_COMPONENTS; i++) {
370 sof_data[10 + (i * 3)] = i; // index identifier
371 sof_data[11 + (i * 3)] = (ptr->h_samp_ratio[i] << 4) | (ptr->v_samp_ratio[i]); // sampling ratios
372 sof_data[12 + (i * 3)] = zr36050_tq[i]; // Q table selection
373 }
374 return zr36050_pushit(ptr, ZR050_SOF_IDX,
375 (3 * NO_OF_COMPONENTS) + 10, sof_data);
376}
377
378/* ------------------------------------------------------------------------- */
379
380/* SOS (start of scan) segment depends on the used scan components
381 of each color component */
382
383static int
384zr36050_set_sos (struct zr36050 *ptr)
385{
386 char sos_data[16]; // max. size of register set
387 int i;
388
389 dprintk(3, "%s: write SOS\n", ptr->name);
390 sos_data[0] = 0xff;
391 sos_data[1] = 0xda;
392 sos_data[2] = 0x00;
393 sos_data[3] = 2 + 1 + (2 * NO_OF_COMPONENTS) + 3;
394 sos_data[4] = NO_OF_COMPONENTS;
395 for (i = 0; i < NO_OF_COMPONENTS; i++) {
396 sos_data[5 + (i * 2)] = i; // index
397 sos_data[6 + (i * 2)] = (zr36050_td[i] << 4) | zr36050_ta[i]; // AC/DC tbl.sel.
398 }
399 sos_data[2 + 1 + (2 * NO_OF_COMPONENTS) + 2] = 00; // scan start
400 sos_data[2 + 1 + (2 * NO_OF_COMPONENTS) + 3] = 0x3F;
401 sos_data[2 + 1 + (2 * NO_OF_COMPONENTS) + 4] = 00;
402 return zr36050_pushit(ptr, ZR050_SOS1_IDX,
403 4 + 1 + (2 * NO_OF_COMPONENTS) + 3,
404 sos_data);
405}
406
407/* ------------------------------------------------------------------------- */
408
409/* DRI (define restart interval) */
410
411static int
412zr36050_set_dri (struct zr36050 *ptr)
413{
414 char dri_data[6]; // max. size of register set
415
416 dprintk(3, "%s: write DRI\n", ptr->name);
417 dri_data[0] = 0xff;
418 dri_data[1] = 0xdd;
419 dri_data[2] = 0x00;
420 dri_data[3] = 0x04;
421 dri_data[4] = ptr->dri >> 8;
422 dri_data[5] = ptr->dri & 0xff;
423 return zr36050_pushit(ptr, ZR050_DRI_IDX, 6, dri_data);
424}
425
426/* =========================================================================
427 Setup function:
428
429 Setup compression/decompression of Zoran's JPEG processor
430 ( see also zoran 36050 manual )
431
432 ... sorry for the spaghetti code ...
433 ========================================================================= */
434static void
435zr36050_init (struct zr36050 *ptr)
436{
437 int sum = 0;
438 long bitcnt, tmp;
439
440 if (ptr->mode == CODEC_DO_COMPRESSION) {
441 dprintk(2, "%s: COMPRESSION SETUP\n", ptr->name);
442
443 /* 050 communicates with 057 in master mode */
444 zr36050_write(ptr, ZR050_HARDWARE, ZR050_HW_MSTR);
445
446 /* encoding table preload for compression */
447 zr36050_write(ptr, ZR050_MODE,
448 ZR050_MO_COMP | ZR050_MO_TLM);
449 zr36050_write(ptr, ZR050_OPTIONS, 0);
450
451 /* disable all IRQs */
452 zr36050_write(ptr, ZR050_INT_REQ_0, 0);
453 zr36050_write(ptr, ZR050_INT_REQ_1, 3); // low 2 bits always 1
454
455 /* volume control settings */
456 /*zr36050_write(ptr, ZR050_MBCV, ptr->max_block_vol);*/
457 zr36050_write(ptr, ZR050_SF_HI, ptr->scalefact >> 8);
458 zr36050_write(ptr, ZR050_SF_LO, ptr->scalefact & 0xff);
459
460 zr36050_write(ptr, ZR050_AF_HI, 0xff);
461 zr36050_write(ptr, ZR050_AF_M, 0xff);
462 zr36050_write(ptr, ZR050_AF_LO, 0xff);
463
464 /* setup the variable jpeg tables */
465 sum += zr36050_set_sof(ptr);
466 sum += zr36050_set_sos(ptr);
467 sum += zr36050_set_dri(ptr);
468
469 /* setup the fixed jpeg tables - maybe variable, though -
470 * (see table init section above) */
471 dprintk(3, "%s: write DQT, DHT, APP\n", ptr->name);
472 sum += zr36050_pushit(ptr, ZR050_DQT_IDX,
473 sizeof(zr36050_dqt), zr36050_dqt);
474 sum += zr36050_pushit(ptr, ZR050_DHT_IDX,
475 sizeof(zr36050_dht), zr36050_dht);
476 zr36050_write(ptr, ZR050_APP_IDX, 0xff);
477 zr36050_write(ptr, ZR050_APP_IDX + 1, 0xe0 + ptr->app.appn);
478 zr36050_write(ptr, ZR050_APP_IDX + 2, 0x00);
479 zr36050_write(ptr, ZR050_APP_IDX + 3, ptr->app.len + 2);
480 sum += zr36050_pushit(ptr, ZR050_APP_IDX + 4, 60,
481 ptr->app.data) + 4;
482 zr36050_write(ptr, ZR050_COM_IDX, 0xff);
483 zr36050_write(ptr, ZR050_COM_IDX + 1, 0xfe);
484 zr36050_write(ptr, ZR050_COM_IDX + 2, 0x00);
485 zr36050_write(ptr, ZR050_COM_IDX + 3, ptr->com.len + 2);
486 sum += zr36050_pushit(ptr, ZR050_COM_IDX + 4, 60,
487 ptr->com.data) + 4;
488
489 /* do the internal huffman table preload */
490 zr36050_write(ptr, ZR050_MARKERS_EN, ZR050_ME_DHTI);
491
492 zr36050_write(ptr, ZR050_GO, 1); // launch codec
493 zr36050_wait_end(ptr);
494 dprintk(2, "%s: Status after table preload: 0x%02x\n",
495 ptr->name, ptr->status1);
496
497 if ((ptr->status1 & 0x4) == 0) {
498 dprintk(1, KERN_ERR "%s: init aborted!\n",
499 ptr->name);
500 return; // something is wrong, its timed out!!!!
501 }
502
503 /* setup misc. data for compression (target code sizes) */
504
505 /* size of compressed code to reach without header data */
506 sum = ptr->real_code_vol - sum;
507 bitcnt = sum << 3; /* need the size in bits */
508
509 tmp = bitcnt >> 16;
510 dprintk(3,
511 "%s: code: csize=%d, tot=%d, bit=%ld, highbits=%ld\n",
512 ptr->name, sum, ptr->real_code_vol, bitcnt, tmp);
513 zr36050_write(ptr, ZR050_TCV_NET_HI, tmp >> 8);
514 zr36050_write(ptr, ZR050_TCV_NET_MH, tmp & 0xff);
515 tmp = bitcnt & 0xffff;
516 zr36050_write(ptr, ZR050_TCV_NET_ML, tmp >> 8);
517 zr36050_write(ptr, ZR050_TCV_NET_LO, tmp & 0xff);
518
519 bitcnt -= bitcnt >> 7; // bits without stuffing
520 bitcnt -= ((bitcnt * 5) >> 6); // bits without eob
521
522 tmp = bitcnt >> 16;
523 dprintk(3, "%s: code: nettobit=%ld, highnettobits=%ld\n",
524 ptr->name, bitcnt, tmp);
525 zr36050_write(ptr, ZR050_TCV_DATA_HI, tmp >> 8);
526 zr36050_write(ptr, ZR050_TCV_DATA_MH, tmp & 0xff);
527 tmp = bitcnt & 0xffff;
528 zr36050_write(ptr, ZR050_TCV_DATA_ML, tmp >> 8);
529 zr36050_write(ptr, ZR050_TCV_DATA_LO, tmp & 0xff);
530
531 /* compression setup with or without bitrate control */
532 zr36050_write(ptr, ZR050_MODE,
533 ZR050_MO_COMP | ZR050_MO_PASS2 |
534 (ptr->bitrate_ctrl ? ZR050_MO_BRC : 0));
535
536 /* this headers seem to deliver "valid AVI" jpeg frames */
537 zr36050_write(ptr, ZR050_MARKERS_EN,
538 ZR050_ME_DQT | ZR050_ME_DHT |
539 ((ptr->app.len > 0) ? ZR050_ME_APP : 0) |
540 ((ptr->com.len > 0) ? ZR050_ME_COM : 0));
541 } else {
542 dprintk(2, "%s: EXPANSION SETUP\n", ptr->name);
543
544 /* 050 communicates with 055 in master mode */
545 zr36050_write(ptr, ZR050_HARDWARE,
546 ZR050_HW_MSTR | ZR050_HW_CFIS_2_CLK);
547
548 /* encoding table preload */
549 zr36050_write(ptr, ZR050_MODE, ZR050_MO_TLM);
550
551 /* disable all IRQs */
552 zr36050_write(ptr, ZR050_INT_REQ_0, 0);
553 zr36050_write(ptr, ZR050_INT_REQ_1, 3); // low 2 bits always 1
554
555 dprintk(3, "%s: write DHT\n", ptr->name);
556 zr36050_pushit(ptr, ZR050_DHT_IDX, sizeof(zr36050_dht),
557 zr36050_dht);
558
559 /* do the internal huffman table preload */
560 zr36050_write(ptr, ZR050_MARKERS_EN, ZR050_ME_DHTI);
561
562 zr36050_write(ptr, ZR050_GO, 1); // launch codec
563 zr36050_wait_end(ptr);
564 dprintk(2, "%s: Status after table preload: 0x%02x\n",
565 ptr->name, ptr->status1);
566
567 if ((ptr->status1 & 0x4) == 0) {
568 dprintk(1, KERN_ERR "%s: init aborted!\n",
569 ptr->name);
570 return; // something is wrong, its timed out!!!!
571 }
572
573 /* setup misc. data for expansion */
574 zr36050_write(ptr, ZR050_MODE, 0);
575 zr36050_write(ptr, ZR050_MARKERS_EN, 0);
576 }
577
578 /* adr on selected, to allow GO from master */
579 zr36050_read(ptr, 0);
580}
581
582/* =========================================================================
583 CODEC API FUNCTIONS
584
585 this functions are accessed by the master via the API structure
586 ========================================================================= */
587
588/* set compression/expansion mode and launches codec -
589 this should be the last call from the master before starting processing */
590static int
591zr36050_set_mode (struct videocodec *codec,
592 int mode)
593{
594 struct zr36050 *ptr = (struct zr36050 *) codec->data;
595
596 dprintk(2, "%s: set_mode %d call\n", ptr->name, mode);
597
598 if ((mode != CODEC_DO_EXPANSION) && (mode != CODEC_DO_COMPRESSION))
599 return -EINVAL;
600
601 ptr->mode = mode;
602 zr36050_init(ptr);
603
604 return 0;
605}
606
607/* set picture size (norm is ignored as the codec doesn't know about it) */
608static int
609zr36050_set_video (struct videocodec *codec,
610 struct tvnorm *norm,
611 struct vfe_settings *cap,
612 struct vfe_polarity *pol)
613{
614 struct zr36050 *ptr = (struct zr36050 *) codec->data;
615 int size;
616
617 dprintk(2, "%s: set_video %d.%d, %d/%d-%dx%d (0x%x) q%d call\n",
618 ptr->name, norm->HStart, norm->VStart,
619 cap->x, cap->y, cap->width, cap->height,
620 cap->decimation, cap->quality);
621 /* if () return -EINVAL;
622 * trust the master driver that it knows what it does - so
623 * we allow invalid startx/y and norm for now ... */
624 ptr->width = cap->width / (cap->decimation & 0xff);
625 ptr->height = cap->height / ((cap->decimation >> 8) & 0xff);
626
627 /* (KM) JPEG quality */
628 size = ptr->width * ptr->height;
629 size *= 16; /* size in bits */
630 /* apply quality setting */
631 size = size * cap->quality / 200;
632
633 /* Minimum: 1kb */
634 if (size < 8192)
635 size = 8192;
636 /* Maximum: 7/8 of code buffer */
637 if (size > ptr->total_code_vol * 7)
638 size = ptr->total_code_vol * 7;
639
640 ptr->real_code_vol = size >> 3; /* in bytes */
641
642 /* Set max_block_vol here (previously in zr36050_init, moved
643 * here for consistency with zr36060 code */
644 zr36050_write(ptr, ZR050_MBCV, ptr->max_block_vol);
645
646 return 0;
647}
648
649/* additional control functions */
650static int
651zr36050_control (struct videocodec *codec,
652 int type,
653 int size,
654 void *data)
655{
656 struct zr36050 *ptr = (struct zr36050 *) codec->data;
657 int *ival = (int *) data;
658
659 dprintk(2, "%s: control %d call with %d byte\n", ptr->name, type,
660 size);
661
662 switch (type) {
663 case CODEC_G_STATUS: /* get last status */
664 if (size != sizeof(int))
665 return -EFAULT;
666 zr36050_read_status1(ptr);
667 *ival = ptr->status1;
668 break;
669
670 case CODEC_G_CODEC_MODE:
671 if (size != sizeof(int))
672 return -EFAULT;
673 *ival = CODEC_MODE_BJPG;
674 break;
675
676 case CODEC_S_CODEC_MODE:
677 if (size != sizeof(int))
678 return -EFAULT;
679 if (*ival != CODEC_MODE_BJPG)
680 return -EINVAL;
681 /* not needed, do nothing */
682 return 0;
683
684 case CODEC_G_VFE:
685 case CODEC_S_VFE:
686 /* not needed, do nothing */
687 return 0;
688
689 case CODEC_S_MMAP:
690 /* not available, give an error */
691 return -ENXIO;
692
693 case CODEC_G_JPEG_TDS_BYTE: /* get target volume in byte */
694 if (size != sizeof(int))
695 return -EFAULT;
696 *ival = ptr->total_code_vol;
697 break;
698
699 case CODEC_S_JPEG_TDS_BYTE: /* get target volume in byte */
700 if (size != sizeof(int))
701 return -EFAULT;
702 ptr->total_code_vol = *ival;
703 /* (Kieran Morrissey)
704 * code copied from zr36060.c to ensure proper bitrate */
705 ptr->real_code_vol = (ptr->total_code_vol * 6) >> 3;
706 break;
707
708 case CODEC_G_JPEG_SCALE: /* get scaling factor */
709 if (size != sizeof(int))
710 return -EFAULT;
711 *ival = zr36050_read_scalefactor(ptr);
712 break;
713
714 case CODEC_S_JPEG_SCALE: /* set scaling factor */
715 if (size != sizeof(int))
716 return -EFAULT;
717 ptr->scalefact = *ival;
718 break;
719
720 case CODEC_G_JPEG_APP_DATA: { /* get appn marker data */
721 struct jpeg_app_marker *app = data;
722
723 if (size != sizeof(struct jpeg_app_marker))
724 return -EFAULT;
725
726 *app = ptr->app;
727 break;
728 }
729
730 case CODEC_S_JPEG_APP_DATA: { /* set appn marker data */
731 struct jpeg_app_marker *app = data;
732
733 if (size != sizeof(struct jpeg_app_marker))
734 return -EFAULT;
735
736 ptr->app = *app;
737 break;
738 }
739
740 case CODEC_G_JPEG_COM_DATA: { /* get comment marker data */
741 struct jpeg_com_marker *com = data;
742
743 if (size != sizeof(struct jpeg_com_marker))
744 return -EFAULT;
745
746 *com = ptr->com;
747 break;
748 }
749
750 case CODEC_S_JPEG_COM_DATA: { /* set comment marker data */
751 struct jpeg_com_marker *com = data;
752
753 if (size != sizeof(struct jpeg_com_marker))
754 return -EFAULT;
755
756 ptr->com = *com;
757 break;
758 }
759
760 default:
761 return -EINVAL;
762 }
763
764 return size;
765}
766
767/* =========================================================================
768 Exit and unregister function:
769
770 Deinitializes Zoran's JPEG processor
771 ========================================================================= */
772
773static int
774zr36050_unset (struct videocodec *codec)
775{
776 struct zr36050 *ptr = codec->data;
777
778 if (ptr) {
779 /* do wee need some codec deinit here, too ???? */
780
781 dprintk(1, "%s: finished codec #%d\n", ptr->name,
782 ptr->num);
783 kfree(ptr);
784 codec->data = NULL;
785
786 zr36050_codecs--;
787 return 0;
788 }
789
790 return -EFAULT;
791}
792
793/* =========================================================================
794 Setup and registry function:
795
796 Initializes Zoran's JPEG processor
797
798 Also sets pixel size, average code size, mode (compr./decompr.)
799 (the given size is determined by the processor with the video interface)
800 ========================================================================= */
801
802static int
803zr36050_setup (struct videocodec *codec)
804{
805 struct zr36050 *ptr;
806 int res;
807
808 dprintk(2, "zr36050: initializing MJPEG subsystem #%d.\n",
809 zr36050_codecs);
810
811 if (zr36050_codecs == MAX_CODECS) {
812 dprintk(1,
813 KERN_ERR "zr36050: Can't attach more codecs!\n");
814 return -ENOSPC;
815 }
816 //mem structure init
817 codec->data = ptr = kmalloc(sizeof(struct zr36050), GFP_KERNEL);
818 if (NULL == ptr) {
819 dprintk(1, KERN_ERR "zr36050: Can't get enough memory!\n");
820 return -ENOMEM;
821 }
822 memset(ptr, 0, sizeof(struct zr36050));
823
824 snprintf(ptr->name, sizeof(ptr->name), "zr36050[%d]",
825 zr36050_codecs);
826 ptr->num = zr36050_codecs++;
827 ptr->codec = codec;
828
829 //testing
830 res = zr36050_basic_test(ptr);
831 if (res < 0) {
832 zr36050_unset(codec);
833 return res;
834 }
835 //final setup
836 memcpy(ptr->h_samp_ratio, zr36050_decimation_h, 8);
837 memcpy(ptr->v_samp_ratio, zr36050_decimation_v, 8);
838
839 ptr->bitrate_ctrl = 0; /* 0 or 1 - fixed file size flag
840 * (what is the difference?) */
841 ptr->mode = CODEC_DO_COMPRESSION;
842 ptr->width = 384;
843 ptr->height = 288;
844 ptr->total_code_vol = 16000;
845 ptr->max_block_vol = 240;
846 ptr->scalefact = 0x100;
847 ptr->dri = 1;
848
849 /* no app/com marker by default */
850 ptr->app.appn = 0;
851 ptr->app.len = 0;
852 ptr->com.len = 0;
853
854 zr36050_init(ptr);
855
856 dprintk(1, KERN_INFO "%s: codec attached and running\n",
857 ptr->name);
858
859 return 0;
860}
861
862static const struct videocodec zr36050_codec = {
863 .owner = THIS_MODULE,
864 .name = "zr36050",
865 .magic = 0L, // magic not used
866 .flags =
867 CODEC_FLAG_JPEG | CODEC_FLAG_HARDWARE | CODEC_FLAG_ENCODER |
868 CODEC_FLAG_DECODER,
869 .type = CODEC_TYPE_ZR36050,
870 .setup = zr36050_setup, // functionality
871 .unset = zr36050_unset,
872 .set_mode = zr36050_set_mode,
873 .set_video = zr36050_set_video,
874 .control = zr36050_control,
875 // others are not used
876};
877
878/* =========================================================================
879 HOOK IN DRIVER AS KERNEL MODULE
880 ========================================================================= */
881
882static int __init
883zr36050_init_module (void)
884{
885 //dprintk(1, "ZR36050 driver %s\n",ZR050_VERSION);
886 zr36050_codecs = 0;
887 return videocodec_register(&zr36050_codec);
888}
889
890static void __exit
891zr36050_cleanup_module (void)
892{
893 if (zr36050_codecs) {
894 dprintk(1,
895 "zr36050: something's wrong - %d codecs left somehow.\n",
896 zr36050_codecs);
897 }
898 videocodec_unregister(&zr36050_codec);
899}
900
901module_init(zr36050_init_module);
902module_exit(zr36050_cleanup_module);
903
904MODULE_AUTHOR("Wolfgang Scherr <scherr@net4you.at>");
905MODULE_DESCRIPTION("Driver module for ZR36050 jpeg processors "
906 ZR050_VERSION);
907MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/zr36050.h b/drivers/media/video/zr36050.h
new file mode 100644
index 00000000000..9f52f0cdde5
--- /dev/null
+++ b/drivers/media/video/zr36050.h
@@ -0,0 +1,184 @@
1/*
2 * Zoran ZR36050 basic configuration functions - header file
3 *
4 * Copyright (C) 2001 Wolfgang Scherr <scherr@net4you.at>
5 *
6 * $Id: zr36050.h,v 1.1.2.2 2003/01/14 21:18:22 rbultje Exp $
7 *
8 * ------------------------------------------------------------------------
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 */
26
27#ifndef ZR36050_H
28#define ZR36050_H
29
30#include "videocodec.h"
31
32/* data stored for each zoran jpeg codec chip */
33struct zr36050 {
34 char name[32];
35 int num;
36 /* io datastructure */
37 struct videocodec *codec;
38 // last coder status
39 __u8 status1;
40 // actual coder setup
41 int mode;
42
43 __u16 width;
44 __u16 height;
45
46 __u16 bitrate_ctrl;
47
48 __u32 total_code_vol;
49 __u32 real_code_vol;
50 __u16 max_block_vol;
51
52 __u8 h_samp_ratio[8];
53 __u8 v_samp_ratio[8];
54 __u16 scalefact;
55 __u16 dri;
56
57 /* com/app marker */
58 struct jpeg_com_marker com;
59 struct jpeg_app_marker app;
60};
61
62/* zr36050 register addresses */
63#define ZR050_GO 0x000
64#define ZR050_HARDWARE 0x002
65#define ZR050_MODE 0x003
66#define ZR050_OPTIONS 0x004
67#define ZR050_MBCV 0x005
68#define ZR050_MARKERS_EN 0x006
69#define ZR050_INT_REQ_0 0x007
70#define ZR050_INT_REQ_1 0x008
71#define ZR050_TCV_NET_HI 0x009
72#define ZR050_TCV_NET_MH 0x00a
73#define ZR050_TCV_NET_ML 0x00b
74#define ZR050_TCV_NET_LO 0x00c
75#define ZR050_TCV_DATA_HI 0x00d
76#define ZR050_TCV_DATA_MH 0x00e
77#define ZR050_TCV_DATA_ML 0x00f
78#define ZR050_TCV_DATA_LO 0x010
79#define ZR050_SF_HI 0x011
80#define ZR050_SF_LO 0x012
81#define ZR050_AF_HI 0x013
82#define ZR050_AF_M 0x014
83#define ZR050_AF_LO 0x015
84#define ZR050_ACV_HI 0x016
85#define ZR050_ACV_MH 0x017
86#define ZR050_ACV_ML 0x018
87#define ZR050_ACV_LO 0x019
88#define ZR050_ACT_HI 0x01a
89#define ZR050_ACT_MH 0x01b
90#define ZR050_ACT_ML 0x01c
91#define ZR050_ACT_LO 0x01d
92#define ZR050_ACV_TRUN_HI 0x01e
93#define ZR050_ACV_TRUN_MH 0x01f
94#define ZR050_ACV_TRUN_ML 0x020
95#define ZR050_ACV_TRUN_LO 0x021
96#define ZR050_STATUS_0 0x02e
97#define ZR050_STATUS_1 0x02f
98
99#define ZR050_SOF_IDX 0x040
100#define ZR050_SOS1_IDX 0x07a
101#define ZR050_SOS2_IDX 0x08a
102#define ZR050_SOS3_IDX 0x09a
103#define ZR050_SOS4_IDX 0x0aa
104#define ZR050_DRI_IDX 0x0c0
105#define ZR050_DNL_IDX 0x0c6
106#define ZR050_DQT_IDX 0x0cc
107#define ZR050_DHT_IDX 0x1d4
108#define ZR050_APP_IDX 0x380
109#define ZR050_COM_IDX 0x3c0
110
111/* zr36050 hardware register bits */
112
113#define ZR050_HW_BSWD 0x80
114#define ZR050_HW_MSTR 0x40
115#define ZR050_HW_DMA 0x20
116#define ZR050_HW_CFIS_1_CLK 0x00
117#define ZR050_HW_CFIS_2_CLK 0x04
118#define ZR050_HW_CFIS_3_CLK 0x08
119#define ZR050_HW_CFIS_4_CLK 0x0C
120#define ZR050_HW_CFIS_5_CLK 0x10
121#define ZR050_HW_CFIS_6_CLK 0x14
122#define ZR050_HW_CFIS_7_CLK 0x18
123#define ZR050_HW_CFIS_8_CLK 0x1C
124#define ZR050_HW_BELE 0x01
125
126/* zr36050 mode register bits */
127
128#define ZR050_MO_COMP 0x80
129#define ZR050_MO_COMP 0x80
130#define ZR050_MO_ATP 0x40
131#define ZR050_MO_PASS2 0x20
132#define ZR050_MO_TLM 0x10
133#define ZR050_MO_DCONLY 0x08
134#define ZR050_MO_BRC 0x04
135
136#define ZR050_MO_ATP 0x40
137#define ZR050_MO_PASS2 0x20
138#define ZR050_MO_TLM 0x10
139#define ZR050_MO_DCONLY 0x08
140
141/* zr36050 option register bits */
142
143#define ZR050_OP_NSCN_1 0x00
144#define ZR050_OP_NSCN_2 0x20
145#define ZR050_OP_NSCN_3 0x40
146#define ZR050_OP_NSCN_4 0x60
147#define ZR050_OP_NSCN_5 0x80
148#define ZR050_OP_NSCN_6 0xA0
149#define ZR050_OP_NSCN_7 0xC0
150#define ZR050_OP_NSCN_8 0xE0
151#define ZR050_OP_OVF 0x10
152
153
154/* zr36050 markers-enable register bits */
155
156#define ZR050_ME_APP 0x80
157#define ZR050_ME_COM 0x40
158#define ZR050_ME_DRI 0x20
159#define ZR050_ME_DQT 0x10
160#define ZR050_ME_DHT 0x08
161#define ZR050_ME_DNL 0x04
162#define ZR050_ME_DQTI 0x02
163#define ZR050_ME_DHTI 0x01
164
165/* zr36050 status0/1 register bit masks */
166
167#define ZR050_ST_RST_MASK 0x20
168#define ZR050_ST_SOF_MASK 0x02
169#define ZR050_ST_SOS_MASK 0x02
170#define ZR050_ST_DATRDY_MASK 0x80
171#define ZR050_ST_MRKDET_MASK 0x40
172#define ZR050_ST_RFM_MASK 0x10
173#define ZR050_ST_RFD_MASK 0x08
174#define ZR050_ST_END_MASK 0x04
175#define ZR050_ST_TCVOVF_MASK 0x02
176#define ZR050_ST_DATOVF_MASK 0x01
177
178/* pixel component idx */
179
180#define ZR050_Y_COMPONENT 0
181#define ZR050_U_COMPONENT 1
182#define ZR050_V_COMPONENT 2
183
184#endif /*fndef ZR36050_H */
diff --git a/drivers/media/video/zr36057.h b/drivers/media/video/zr36057.h
new file mode 100644
index 00000000000..159abfa034d
--- /dev/null
+++ b/drivers/media/video/zr36057.h
@@ -0,0 +1,168 @@
1/*
2 * zr36057.h - zr36057 register offsets
3 *
4 * Copyright (C) 1998 Dave Perks <dperks@ibm.net>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21#ifndef _ZR36057_H_
22#define _ZR36057_H_
23
24
25/* Zoran ZR36057 registers */
26
27#define ZR36057_VFEHCR 0x000 /* Video Front End, Horizontal Configuration Register */
28#define ZR36057_VFEHCR_HSPol (1<<30)
29#define ZR36057_VFEHCR_HStart 10
30#define ZR36057_VFEHCR_HEnd 0
31#define ZR36057_VFEHCR_Hmask 0x3ff
32
33#define ZR36057_VFEVCR 0x004 /* Video Front End, Vertical Configuration Register */
34#define ZR36057_VFEVCR_VSPol (1<<30)
35#define ZR36057_VFEVCR_VStart 10
36#define ZR36057_VFEVCR_VEnd 0
37#define ZR36057_VFEVCR_Vmask 0x3ff
38
39#define ZR36057_VFESPFR 0x008 /* Video Front End, Scaler and Pixel Format Register */
40#define ZR36057_VFESPFR_ExtFl (1<<26)
41#define ZR36057_VFESPFR_TopField (1<<25)
42#define ZR36057_VFESPFR_VCLKPol (1<<24)
43#define ZR36057_VFESPFR_HFilter 21
44#define ZR36057_VFESPFR_HorDcm 14
45#define ZR36057_VFESPFR_VerDcm 8
46#define ZR36057_VFESPFR_DispMode 6
47#define ZR36057_VFESPFR_YUV422 (0<<3)
48#define ZR36057_VFESPFR_RGB888 (1<<3)
49#define ZR36057_VFESPFR_RGB565 (2<<3)
50#define ZR36057_VFESPFR_RGB555 (3<<3)
51#define ZR36057_VFESPFR_ErrDif (1<<2)
52#define ZR36057_VFESPFR_Pack24 (1<<1)
53#define ZR36057_VFESPFR_LittleEndian (1<<0)
54
55#define ZR36057_VDTR 0x00c /* Video Display "Top" Register */
56
57#define ZR36057_VDBR 0x010 /* Video Display "Bottom" Register */
58
59#define ZR36057_VSSFGR 0x014 /* Video Stride, Status, and Frame Grab Register */
60#define ZR36057_VSSFGR_DispStride 16
61#define ZR36057_VSSFGR_VidOvf (1<<8)
62#define ZR36057_VSSFGR_SnapShot (1<<1)
63#define ZR36057_VSSFGR_FrameGrab (1<<0)
64
65#define ZR36057_VDCR 0x018 /* Video Display Configuration Register */
66#define ZR36057_VDCR_VidEn (1<<31)
67#define ZR36057_VDCR_MinPix 24
68#define ZR36057_VDCR_Triton (1<<24)
69#define ZR36057_VDCR_VidWinHt 12
70#define ZR36057_VDCR_VidWinWid 0
71
72#define ZR36057_MMTR 0x01c /* Masking Map "Top" Register */
73
74#define ZR36057_MMBR 0x020 /* Masking Map "Bottom" Register */
75
76#define ZR36057_OCR 0x024 /* Overlay Control Register */
77#define ZR36057_OCR_OvlEnable (1 << 15)
78#define ZR36057_OCR_MaskStride 0
79
80#define ZR36057_SPGPPCR 0x028 /* System, PCI, and General Purpose Pins Control Register */
81#define ZR36057_SPGPPCR_SoftReset (1<<24)
82
83#define ZR36057_GPPGCR1 0x02c /* General Purpose Pins and GuestBus Control Register (1) */
84
85#define ZR36057_MCSAR 0x030 /* MPEG Code Source Address Register */
86
87#define ZR36057_MCTCR 0x034 /* MPEG Code Transfer Control Register */
88#define ZR36057_MCTCR_CodTime (1 << 30)
89#define ZR36057_MCTCR_CEmpty (1 << 29)
90#define ZR36057_MCTCR_CFlush (1 << 28)
91#define ZR36057_MCTCR_CodGuestID 20
92#define ZR36057_MCTCR_CodGuestReg 16
93
94#define ZR36057_MCMPR 0x038 /* MPEG Code Memory Pointer Register */
95
96#define ZR36057_ISR 0x03c /* Interrupt Status Register */
97#define ZR36057_ISR_GIRQ1 (1<<30)
98#define ZR36057_ISR_GIRQ0 (1<<29)
99#define ZR36057_ISR_CodRepIRQ (1<<28)
100#define ZR36057_ISR_JPEGRepIRQ (1<<27)
101
102#define ZR36057_ICR 0x040 /* Interrupt Control Register */
103#define ZR36057_ICR_GIRQ1 (1<<30)
104#define ZR36057_ICR_GIRQ0 (1<<29)
105#define ZR36057_ICR_CodRepIRQ (1<<28)
106#define ZR36057_ICR_JPEGRepIRQ (1<<27)
107#define ZR36057_ICR_IntPinEn (1<<24)
108
109#define ZR36057_I2CBR 0x044 /* I2C Bus Register */
110#define ZR36057_I2CBR_SDA (1<<1)
111#define ZR36057_I2CBR_SCL (1<<0)
112
113#define ZR36057_JMC 0x100 /* JPEG Mode and Control */
114#define ZR36057_JMC_JPG (1 << 31)
115#define ZR36057_JMC_JPGExpMode (0 << 29)
116#define ZR36057_JMC_JPGCmpMode (1 << 29)
117#define ZR36057_JMC_MJPGExpMode (2 << 29)
118#define ZR36057_JMC_MJPGCmpMode (3 << 29)
119#define ZR36057_JMC_RTBUSY_FB (1 << 6)
120#define ZR36057_JMC_Go_en (1 << 5)
121#define ZR36057_JMC_SyncMstr (1 << 4)
122#define ZR36057_JMC_Fld_per_buff (1 << 3)
123#define ZR36057_JMC_VFIFO_FB (1 << 2)
124#define ZR36057_JMC_CFIFO_FB (1 << 1)
125#define ZR36057_JMC_Stll_LitEndian (1 << 0)
126
127#define ZR36057_JPC 0x104 /* JPEG Process Control */
128#define ZR36057_JPC_P_Reset (1 << 7)
129#define ZR36057_JPC_CodTrnsEn (1 << 5)
130#define ZR36057_JPC_Active (1 << 0)
131
132#define ZR36057_VSP 0x108 /* Vertical Sync Parameters */
133#define ZR36057_VSP_VsyncSize 16
134#define ZR36057_VSP_FrmTot 0
135
136#define ZR36057_HSP 0x10c /* Horizontal Sync Parameters */
137#define ZR36057_HSP_HsyncStart 16
138#define ZR36057_HSP_LineTot 0
139
140#define ZR36057_FHAP 0x110 /* Field Horizontal Active Portion */
141#define ZR36057_FHAP_NAX 16
142#define ZR36057_FHAP_PAX 0
143
144#define ZR36057_FVAP 0x114 /* Field Vertical Active Portion */
145#define ZR36057_FVAP_NAY 16
146#define ZR36057_FVAP_PAY 0
147
148#define ZR36057_FPP 0x118 /* Field Process Parameters */
149#define ZR36057_FPP_Odd_Even (1 << 0)
150
151#define ZR36057_JCBA 0x11c /* JPEG Code Base Address */
152
153#define ZR36057_JCFT 0x120 /* JPEG Code FIFO Threshold */
154
155#define ZR36057_JCGI 0x124 /* JPEG Codec Guest ID */
156#define ZR36057_JCGI_JPEGuestID 4
157#define ZR36057_JCGI_JPEGuestReg 0
158
159#define ZR36057_GCR2 0x12c /* GuestBus Control Register (2) */
160
161#define ZR36057_POR 0x200 /* Post Office Register */
162#define ZR36057_POR_POPen (1<<25)
163#define ZR36057_POR_POTime (1<<24)
164#define ZR36057_POR_PODir (1<<23)
165
166#define ZR36057_STR 0x300 /* "Still" Transfer Register */
167
168#endif
diff --git a/drivers/media/video/zr36060.c b/drivers/media/video/zr36060.c
new file mode 100644
index 00000000000..b50dc403e6d
--- /dev/null
+++ b/drivers/media/video/zr36060.c
@@ -0,0 +1,1016 @@
1/*
2 * Zoran ZR36060 basic configuration functions
3 *
4 * Copyright (C) 2002 Laurent Pinchart <laurent.pinchart@skynet.be>
5 *
6 * $Id: zr36060.c,v 1.1.2.22 2003/05/06 09:35:36 rbultje Exp $
7 *
8 * ------------------------------------------------------------------------
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 */
26
27#define ZR060_VERSION "v0.7"
28
29#include <linux/version.h>
30#include <linux/module.h>
31#include <linux/init.h>
32#include <linux/slab.h>
33#include <linux/delay.h>
34
35#include <linux/types.h>
36#include <linux/wait.h>
37
38/* includes for structures and defines regarding video
39 #include<linux/videodev.h> */
40
41/* I/O commands, error codes */
42#include<asm/io.h>
43//#include<errno.h>
44
45/* headerfile of this module */
46#include"zr36060.h"
47
48/* codec io API */
49#include"videocodec.h"
50
51/* it doesn't make sense to have more than 20 or so,
52 just to prevent some unwanted loops */
53#define MAX_CODECS 20
54
55/* amount of chips attached via this driver */
56static int zr36060_codecs = 0;
57
58static int low_bitrate = 0;
59module_param(low_bitrate, bool, 0);
60MODULE_PARM_DESC(low_bitrate, "Buz compatibility option, halves bitrate");
61
62/* debugging is available via module parameter */
63static int debug = 0;
64module_param(debug, int, 0);
65MODULE_PARM_DESC(debug, "Debug level (0-4)");
66
67#define dprintk(num, format, args...) \
68 do { \
69 if (debug >= num) \
70 printk(format, ##args); \
71 } while (0)
72
73/* =========================================================================
74 Local hardware I/O functions:
75
76 read/write via codec layer (registers are located in the master device)
77 ========================================================================= */
78
79/* read and write functions */
80static u8
81zr36060_read (struct zr36060 *ptr,
82 u16 reg)
83{
84 u8 value = 0;
85
86 // just in case something is wrong...
87 if (ptr->codec->master_data->readreg)
88 value = (ptr->codec->master_data->readreg(ptr->codec,
89 reg)) & 0xff;
90 else
91 dprintk(1,
92 KERN_ERR "%s: invalid I/O setup, nothing read!\n",
93 ptr->name);
94
95 //dprintk(4, "%s: reading from 0x%04x: %02x\n",ptr->name,reg,value);
96
97 return value;
98}
99
100static void
101zr36060_write(struct zr36060 *ptr,
102 u16 reg,
103 u8 value)
104{
105 //dprintk(4, "%s: writing 0x%02x to 0x%04x\n",ptr->name,value,reg);
106 dprintk(4, "0x%02x @0x%04x\n", value, reg);
107
108 // just in case something is wrong...
109 if (ptr->codec->master_data->writereg)
110 ptr->codec->master_data->writereg(ptr->codec, reg, value);
111 else
112 dprintk(1,
113 KERN_ERR
114 "%s: invalid I/O setup, nothing written!\n",
115 ptr->name);
116}
117
118/* =========================================================================
119 Local helper function:
120
121 status read
122 ========================================================================= */
123
124/* status is kept in datastructure */
125static u8
126zr36060_read_status (struct zr36060 *ptr)
127{
128 ptr->status = zr36060_read(ptr, ZR060_CFSR);
129
130 zr36060_read(ptr, 0);
131 return ptr->status;
132}
133
134/* =========================================================================
135 Local helper function:
136
137 scale factor read
138 ========================================================================= */
139
140/* scale factor is kept in datastructure */
141static u16
142zr36060_read_scalefactor (struct zr36060 *ptr)
143{
144 ptr->scalefact = (zr36060_read(ptr, ZR060_SF_HI) << 8) |
145 (zr36060_read(ptr, ZR060_SF_LO) & 0xFF);
146
147 /* leave 0 selected for an eventually GO from master */
148 zr36060_read(ptr, 0);
149 return ptr->scalefact;
150}
151
152/* =========================================================================
153 Local helper function:
154
155 wait if codec is ready to proceed (end of processing) or time is over
156 ========================================================================= */
157
158static void
159zr36060_wait_end (struct zr36060 *ptr)
160{
161 int i = 0;
162
163 while (zr36060_read_status(ptr) & ZR060_CFSR_Busy) {
164 udelay(1);
165 if (i++ > 200000) { // 200ms, there is for shure something wrong!!!
166 dprintk(1,
167 "%s: timout at wait_end (last status: 0x%02x)\n",
168 ptr->name, ptr->status);
169 break;
170 }
171 }
172}
173
174/* =========================================================================
175 Local helper function:
176
177 basic test of "connectivity", writes/reads to/from memory the SOF marker
178 ========================================================================= */
179
180static int
181zr36060_basic_test (struct zr36060 *ptr)
182{
183 if ((zr36060_read(ptr, ZR060_IDR_DEV) != 0x33) &&
184 (zr36060_read(ptr, ZR060_IDR_REV) != 0x01)) {
185 dprintk(1,
186 KERN_ERR
187 "%s: attach failed, can't connect to jpeg processor!\n",
188 ptr->name);
189 return -ENXIO;
190 }
191
192 zr36060_wait_end(ptr);
193 if (ptr->status & ZR060_CFSR_Busy) {
194 dprintk(1,
195 KERN_ERR
196 "%s: attach failed, jpeg processor failed (end flag)!\n",
197 ptr->name);
198 return -EBUSY;
199 }
200
201 return 0; /* looks good! */
202}
203
204/* =========================================================================
205 Local helper function:
206
207 simple loop for pushing the init datasets
208 ========================================================================= */
209
210static int
211zr36060_pushit (struct zr36060 *ptr,
212 u16 startreg,
213 u16 len,
214 const char *data)
215{
216 int i = 0;
217
218 dprintk(4, "%s: write data block to 0x%04x (len=%d)\n", ptr->name,
219 startreg, len);
220 while (i < len) {
221 zr36060_write(ptr, startreg++, data[i++]);
222 }
223
224 return i;
225}
226
227/* =========================================================================
228 Basic datasets:
229
230 jpeg baseline setup data (you find it on lots places in internet, or just
231 extract it from any regular .jpg image...)
232
233 Could be variable, but until it's not needed it they are just fixed to save
234 memory. Otherwise expand zr36060 structure with arrays, push the values to
235 it and initalize from there, as e.g. the linux zr36057/60 driver does it.
236 ========================================================================= */
237
238static const char zr36060_dqt[0x86] = {
239 0xff, 0xdb, //Marker: DQT
240 0x00, 0x84, //Length: 2*65+2
241 0x00, //Pq,Tq first table
242 0x10, 0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e,
243 0x0d, 0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28,
244 0x1a, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25,
245 0x1d, 0x28, 0x3a, 0x33, 0x3d, 0x3c, 0x39, 0x33,
246 0x38, 0x37, 0x40, 0x48, 0x5c, 0x4e, 0x40, 0x44,
247 0x57, 0x45, 0x37, 0x38, 0x50, 0x6d, 0x51, 0x57,
248 0x5f, 0x62, 0x67, 0x68, 0x67, 0x3e, 0x4d, 0x71,
249 0x79, 0x70, 0x64, 0x78, 0x5c, 0x65, 0x67, 0x63,
250 0x01, //Pq,Tq second table
251 0x11, 0x12, 0x12, 0x18, 0x15, 0x18, 0x2f, 0x1a,
252 0x1a, 0x2f, 0x63, 0x42, 0x38, 0x42, 0x63, 0x63,
253 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
254 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
255 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
256 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
257 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
258 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63
259};
260
261static const char zr36060_dht[0x1a4] = {
262 0xff, 0xc4, //Marker: DHT
263 0x01, 0xa2, //Length: 2*AC, 2*DC
264 0x00, //DC first table
265 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01,
266 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
267 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
268 0x01, //DC second table
269 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
270 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
271 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
272 0x10, //AC first table
273 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03,
274 0x05, 0x05, 0x04, 0x04, 0x00, 0x00,
275 0x01, 0x7D, 0x01, 0x02, 0x03, 0x00, 0x04, 0x11,
276 0x05, 0x12, 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61,
277 0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xA1,
278 0x08, 0x23, 0x42, 0xB1, 0xC1, 0x15, 0x52, 0xD1, 0xF0, 0x24,
279 0x33, 0x62, 0x72, 0x82, 0x09, 0x0A, 0x16, 0x17,
280 0x18, 0x19, 0x1A, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x34,
281 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44,
282 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56,
283 0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66,
284 0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
285 0x79, 0x7A, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,
286 0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99,
287 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8,
288 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9,
289 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8,
290 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9,
291 0xDA, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
292 0xE8, 0xE9, 0xEA, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
293 0xF8, 0xF9, 0xFA,
294 0x11, //AC second table
295 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04,
296 0x07, 0x05, 0x04, 0x04, 0x00, 0x01,
297 0x02, 0x77, 0x00, 0x01, 0x02, 0x03, 0x11, 0x04,
298 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
299 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
300 0xA1, 0xB1, 0xC1, 0x09, 0x23, 0x33, 0x52, 0xF0, 0x15, 0x62,
301 0x72, 0xD1, 0x0A, 0x16, 0x24, 0x34, 0xE1, 0x25,
302 0xF1, 0x17, 0x18, 0x19, 0x1A, 0x26, 0x27, 0x28, 0x29, 0x2A,
303 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44,
304 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56,
305 0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66,
306 0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
307 0x79, 0x7A, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
308 0x88, 0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
309 0x99, 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
310 0xA8, 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8,
311 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
312 0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8,
313 0xD9, 0xDA, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
314 0xE8, 0xE9, 0xEA, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8,
315 0xF9, 0xFA
316};
317
318/* jpeg baseline setup, this is just fixed in this driver (YUV pictures) */
319#define NO_OF_COMPONENTS 0x3 //Y,U,V
320#define BASELINE_PRECISION 0x8 //MCU size (?)
321static const char zr36060_tq[8] = { 0, 1, 1, 0, 0, 0, 0, 0 }; //table idx's QT
322static const char zr36060_td[8] = { 0, 1, 1, 0, 0, 0, 0, 0 }; //table idx's DC
323static const char zr36060_ta[8] = { 0, 1, 1, 0, 0, 0, 0, 0 }; //table idx's AC
324
325/* horizontal 422 decimation setup (maybe we support 411 or so later, too) */
326static const char zr36060_decimation_h[8] = { 2, 1, 1, 0, 0, 0, 0, 0 };
327static const char zr36060_decimation_v[8] = { 1, 1, 1, 0, 0, 0, 0, 0 };
328
329/* =========================================================================
330 Local helper functions:
331
332 calculation and setup of parameter-dependent JPEG baseline segments
333 (needed for compression only)
334 ========================================================================= */
335
336/* ------------------------------------------------------------------------- */
337
338/* SOF (start of frame) segment depends on width, height and sampling ratio
339 of each color component */
340
341static int
342zr36060_set_sof (struct zr36060 *ptr)
343{
344 char sof_data[34]; // max. size of register set
345 int i;
346
347 dprintk(3, "%s: write SOF (%dx%d, %d components)\n", ptr->name,
348 ptr->width, ptr->height, NO_OF_COMPONENTS);
349 sof_data[0] = 0xff;
350 sof_data[1] = 0xc0;
351 sof_data[2] = 0x00;
352 sof_data[3] = (3 * NO_OF_COMPONENTS) + 8;
353 sof_data[4] = BASELINE_PRECISION; // only '8' possible with zr36060
354 sof_data[5] = (ptr->height) >> 8;
355 sof_data[6] = (ptr->height) & 0xff;
356 sof_data[7] = (ptr->width) >> 8;
357 sof_data[8] = (ptr->width) & 0xff;
358 sof_data[9] = NO_OF_COMPONENTS;
359 for (i = 0; i < NO_OF_COMPONENTS; i++) {
360 sof_data[10 + (i * 3)] = i; // index identifier
361 sof_data[11 + (i * 3)] = (ptr->h_samp_ratio[i] << 4) |
362 (ptr->v_samp_ratio[i]); // sampling ratios
363 sof_data[12 + (i * 3)] = zr36060_tq[i]; // Q table selection
364 }
365 return zr36060_pushit(ptr, ZR060_SOF_IDX,
366 (3 * NO_OF_COMPONENTS) + 10, sof_data);
367}
368
369/* ------------------------------------------------------------------------- */
370
371/* SOS (start of scan) segment depends on the used scan components
372 of each color component */
373
374static int
375zr36060_set_sos (struct zr36060 *ptr)
376{
377 char sos_data[16]; // max. size of register set
378 int i;
379
380 dprintk(3, "%s: write SOS\n", ptr->name);
381 sos_data[0] = 0xff;
382 sos_data[1] = 0xda;
383 sos_data[2] = 0x00;
384 sos_data[3] = 2 + 1 + (2 * NO_OF_COMPONENTS) + 3;
385 sos_data[4] = NO_OF_COMPONENTS;
386 for (i = 0; i < NO_OF_COMPONENTS; i++) {
387 sos_data[5 + (i * 2)] = i; // index
388 sos_data[6 + (i * 2)] = (zr36060_td[i] << 4) |
389 zr36060_ta[i]; // AC/DC tbl.sel.
390 }
391 sos_data[2 + 1 + (2 * NO_OF_COMPONENTS) + 2] = 00; // scan start
392 sos_data[2 + 1 + (2 * NO_OF_COMPONENTS) + 3] = 0x3f;
393 sos_data[2 + 1 + (2 * NO_OF_COMPONENTS) + 4] = 00;
394 return zr36060_pushit(ptr, ZR060_SOS_IDX,
395 4 + 1 + (2 * NO_OF_COMPONENTS) + 3,
396 sos_data);
397}
398
399/* ------------------------------------------------------------------------- */
400
401/* DRI (define restart interval) */
402
403static int
404zr36060_set_dri (struct zr36060 *ptr)
405{
406 char dri_data[6]; // max. size of register set
407
408 dprintk(3, "%s: write DRI\n", ptr->name);
409 dri_data[0] = 0xff;
410 dri_data[1] = 0xdd;
411 dri_data[2] = 0x00;
412 dri_data[3] = 0x04;
413 dri_data[4] = (ptr->dri) >> 8;
414 dri_data[5] = (ptr->dri) & 0xff;
415 return zr36060_pushit(ptr, ZR060_DRI_IDX, 6, dri_data);
416}
417
418/* =========================================================================
419 Setup function:
420
421 Setup compression/decompression of Zoran's JPEG processor
422 ( see also zoran 36060 manual )
423
424 ... sorry for the spaghetti code ...
425 ========================================================================= */
426static void
427zr36060_init (struct zr36060 *ptr)
428{
429 int sum = 0;
430 long bitcnt, tmp;
431
432 if (ptr->mode == CODEC_DO_COMPRESSION) {
433 dprintk(2, "%s: COMPRESSION SETUP\n", ptr->name);
434
435 zr36060_write(ptr, ZR060_LOAD, ZR060_LOAD_SyncRst);
436
437 /* 060 communicates with 067 in master mode */
438 zr36060_write(ptr, ZR060_CIR, ZR060_CIR_CodeMstr);
439
440 /* Compression with or without variable scale factor */
441 /*FIXME: What about ptr->bitrate_ctrl? */
442 zr36060_write(ptr, ZR060_CMR,
443 ZR060_CMR_Comp | ZR060_CMR_Pass2 |
444 ZR060_CMR_BRB);
445
446 /* Must be zero */
447 zr36060_write(ptr, ZR060_MBZ, 0x00);
448 zr36060_write(ptr, ZR060_TCR_HI, 0x00);
449 zr36060_write(ptr, ZR060_TCR_LO, 0x00);
450
451 /* Disable all IRQs - no DataErr means autoreset */
452 zr36060_write(ptr, ZR060_IMR, 0);
453
454 /* volume control settings */
455 zr36060_write(ptr, ZR060_SF_HI, ptr->scalefact >> 8);
456 zr36060_write(ptr, ZR060_SF_LO, ptr->scalefact & 0xff);
457
458 zr36060_write(ptr, ZR060_AF_HI, 0xff);
459 zr36060_write(ptr, ZR060_AF_M, 0xff);
460 zr36060_write(ptr, ZR060_AF_LO, 0xff);
461
462 /* setup the variable jpeg tables */
463 sum += zr36060_set_sof(ptr);
464 sum += zr36060_set_sos(ptr);
465 sum += zr36060_set_dri(ptr);
466
467 /* setup the fixed jpeg tables - maybe variable, though -
468 * (see table init section above) */
469 sum +=
470 zr36060_pushit(ptr, ZR060_DQT_IDX, sizeof(zr36060_dqt),
471 zr36060_dqt);
472 sum +=
473 zr36060_pushit(ptr, ZR060_DHT_IDX, sizeof(zr36060_dht),
474 zr36060_dht);
475 zr36060_write(ptr, ZR060_APP_IDX, 0xff);
476 zr36060_write(ptr, ZR060_APP_IDX + 1, 0xe0 + ptr->app.appn);
477 zr36060_write(ptr, ZR060_APP_IDX + 2, 0x00);
478 zr36060_write(ptr, ZR060_APP_IDX + 3, ptr->app.len + 2);
479 sum += zr36060_pushit(ptr, ZR060_APP_IDX + 4, 60,
480 ptr->app.data) + 4;
481 zr36060_write(ptr, ZR060_COM_IDX, 0xff);
482 zr36060_write(ptr, ZR060_COM_IDX + 1, 0xfe);
483 zr36060_write(ptr, ZR060_COM_IDX + 2, 0x00);
484 zr36060_write(ptr, ZR060_COM_IDX + 3, ptr->com.len + 2);
485 sum += zr36060_pushit(ptr, ZR060_COM_IDX + 4, 60,
486 ptr->com.data) + 4;
487
488 /* setup misc. data for compression (target code sizes) */
489
490 /* size of compressed code to reach without header data */
491 sum = ptr->real_code_vol - sum;
492 bitcnt = sum << 3; /* need the size in bits */
493
494 tmp = bitcnt >> 16;
495 dprintk(3,
496 "%s: code: csize=%d, tot=%d, bit=%ld, highbits=%ld\n",
497 ptr->name, sum, ptr->real_code_vol, bitcnt, tmp);
498 zr36060_write(ptr, ZR060_TCV_NET_HI, tmp >> 8);
499 zr36060_write(ptr, ZR060_TCV_NET_MH, tmp & 0xff);
500 tmp = bitcnt & 0xffff;
501 zr36060_write(ptr, ZR060_TCV_NET_ML, tmp >> 8);
502 zr36060_write(ptr, ZR060_TCV_NET_LO, tmp & 0xff);
503
504 bitcnt -= bitcnt >> 7; // bits without stuffing
505 bitcnt -= ((bitcnt * 5) >> 6); // bits without eob
506
507 tmp = bitcnt >> 16;
508 dprintk(3, "%s: code: nettobit=%ld, highnettobits=%ld\n",
509 ptr->name, bitcnt, tmp);
510 zr36060_write(ptr, ZR060_TCV_DATA_HI, tmp >> 8);
511 zr36060_write(ptr, ZR060_TCV_DATA_MH, tmp & 0xff);
512 tmp = bitcnt & 0xffff;
513 zr36060_write(ptr, ZR060_TCV_DATA_ML, tmp >> 8);
514 zr36060_write(ptr, ZR060_TCV_DATA_LO, tmp & 0xff);
515
516 /* JPEG markers to be included in the compressed stream */
517 zr36060_write(ptr, ZR060_MER,
518 ZR060_MER_DQT | ZR060_MER_DHT |
519 ((ptr->com.len > 0) ? ZR060_MER_Com : 0) |
520 ((ptr->app.len > 0) ? ZR060_MER_App : 0));
521
522 /* Setup the Video Frontend */
523 /* Limit pixel range to 16..235 as per CCIR-601 */
524 zr36060_write(ptr, ZR060_VCR, ZR060_VCR_Range);
525
526 } else {
527 dprintk(2, "%s: EXPANSION SETUP\n", ptr->name);
528
529 zr36060_write(ptr, ZR060_LOAD, ZR060_LOAD_SyncRst);
530
531 /* 060 communicates with 067 in master mode */
532 zr36060_write(ptr, ZR060_CIR, ZR060_CIR_CodeMstr);
533
534 /* Decompression */
535 zr36060_write(ptr, ZR060_CMR, 0);
536
537 /* Must be zero */
538 zr36060_write(ptr, ZR060_MBZ, 0x00);
539 zr36060_write(ptr, ZR060_TCR_HI, 0x00);
540 zr36060_write(ptr, ZR060_TCR_LO, 0x00);
541
542 /* Disable all IRQs - no DataErr means autoreset */
543 zr36060_write(ptr, ZR060_IMR, 0);
544
545 /* setup misc. data for expansion */
546 zr36060_write(ptr, ZR060_MER, 0);
547
548 /* setup the fixed jpeg tables - maybe variable, though -
549 * (see table init section above) */
550 zr36060_pushit(ptr, ZR060_DHT_IDX, sizeof(zr36060_dht),
551 zr36060_dht);
552
553 /* Setup the Video Frontend */
554 //zr36060_write(ptr, ZR060_VCR, ZR060_VCR_FIExt);
555 //this doesn't seem right and doesn't work...
556 zr36060_write(ptr, ZR060_VCR, ZR060_VCR_Range);
557 }
558
559 /* Load the tables */
560 zr36060_write(ptr, ZR060_LOAD,
561 ZR060_LOAD_SyncRst | ZR060_LOAD_Load);
562 zr36060_wait_end(ptr);
563 dprintk(2, "%s: Status after table preload: 0x%02x\n", ptr->name,
564 ptr->status);
565
566 if (ptr->status & ZR060_CFSR_Busy) {
567 dprintk(1, KERN_ERR "%s: init aborted!\n", ptr->name);
568 return; // something is wrong, its timed out!!!!
569 }
570}
571
572/* =========================================================================
573 CODEC API FUNCTIONS
574
575 this functions are accessed by the master via the API structure
576 ========================================================================= */
577
578/* set compression/expansion mode and launches codec -
579 this should be the last call from the master before starting processing */
580static int
581zr36060_set_mode (struct videocodec *codec,
582 int mode)
583{
584 struct zr36060 *ptr = (struct zr36060 *) codec->data;
585
586 dprintk(2, "%s: set_mode %d call\n", ptr->name, mode);
587
588 if ((mode != CODEC_DO_EXPANSION) && (mode != CODEC_DO_COMPRESSION))
589 return -EINVAL;
590
591 ptr->mode = mode;
592 zr36060_init(ptr);
593
594 return 0;
595}
596
597/* set picture size (norm is ignored as the codec doesn't know about it) */
598static int
599zr36060_set_video (struct videocodec *codec,
600 struct tvnorm *norm,
601 struct vfe_settings *cap,
602 struct vfe_polarity *pol)
603{
604 struct zr36060 *ptr = (struct zr36060 *) codec->data;
605 u32 reg;
606 int size;
607
608 dprintk(2, "%s: set_video %d/%d-%dx%d (%%%d) call\n", ptr->name,
609 cap->x, cap->y, cap->width, cap->height, cap->decimation);
610
611 /* if () return -EINVAL;
612 * trust the master driver that it knows what it does - so
613 * we allow invalid startx/y and norm for now ... */
614 ptr->width = cap->width / (cap->decimation & 0xff);
615 ptr->height = cap->height / (cap->decimation >> 8);
616
617 zr36060_write(ptr, ZR060_LOAD, ZR060_LOAD_SyncRst);
618
619 /* Note that VSPol/HSPol bits in zr36060 have the opposite
620 * meaning of their zr360x7 counterparts with the same names
621 * N.b. for VSPol this is only true if FIVEdge = 0 (default,
622 * left unchanged here - in accordance with datasheet).
623 */
624 reg = (!pol->vsync_pol ? ZR060_VPR_VSPol : 0)
625 | (!pol->hsync_pol ? ZR060_VPR_HSPol : 0)
626 | (pol->field_pol ? ZR060_VPR_FIPol : 0)
627 | (pol->blank_pol ? ZR060_VPR_BLPol : 0)
628 | (pol->subimg_pol ? ZR060_VPR_SImgPol : 0)
629 | (pol->poe_pol ? ZR060_VPR_PoePol : 0)
630 | (pol->pvalid_pol ? ZR060_VPR_PValPol : 0)
631 | (pol->vclk_pol ? ZR060_VPR_VCLKPol : 0);
632 zr36060_write(ptr, ZR060_VPR, reg);
633
634 reg = 0;
635 switch (cap->decimation & 0xff) {
636 default:
637 case 1:
638 break;
639
640 case 2:
641 reg |= ZR060_SR_HScale2;
642 break;
643
644 case 4:
645 reg |= ZR060_SR_HScale4;
646 break;
647 }
648
649 switch (cap->decimation >> 8) {
650 default:
651 case 1:
652 break;
653
654 case 2:
655 reg |= ZR060_SR_VScale;
656 break;
657 }
658 zr36060_write(ptr, ZR060_SR, reg);
659
660 zr36060_write(ptr, ZR060_BCR_Y, 0x00);
661 zr36060_write(ptr, ZR060_BCR_U, 0x80);
662 zr36060_write(ptr, ZR060_BCR_V, 0x80);
663
664 /* sync generator */
665
666 reg = norm->Ht - 1; /* Vtotal */
667 zr36060_write(ptr, ZR060_SGR_VTOTAL_HI, (reg >> 8) & 0xff);
668 zr36060_write(ptr, ZR060_SGR_VTOTAL_LO, (reg >> 0) & 0xff);
669
670 reg = norm->Wt - 1; /* Htotal */
671 zr36060_write(ptr, ZR060_SGR_HTOTAL_HI, (reg >> 8) & 0xff);
672 zr36060_write(ptr, ZR060_SGR_HTOTAL_LO, (reg >> 0) & 0xff);
673
674 reg = 6 - 1; /* VsyncSize */
675 zr36060_write(ptr, ZR060_SGR_VSYNC, reg);
676
677 //reg = 30 - 1; /* HsyncSize */
678///*CP*/ reg = (zr->params.norm == 1 ? 57 : 68);
679 reg = 68;
680 zr36060_write(ptr, ZR060_SGR_HSYNC, reg);
681
682 reg = norm->VStart - 1; /* BVstart */
683 zr36060_write(ptr, ZR060_SGR_BVSTART, reg);
684
685 reg += norm->Ha / 2; /* BVend */
686 zr36060_write(ptr, ZR060_SGR_BVEND_HI, (reg >> 8) & 0xff);
687 zr36060_write(ptr, ZR060_SGR_BVEND_LO, (reg >> 0) & 0xff);
688
689 reg = norm->HStart - 1; /* BHstart */
690 zr36060_write(ptr, ZR060_SGR_BHSTART, reg);
691
692 reg += norm->Wa; /* BHend */
693 zr36060_write(ptr, ZR060_SGR_BHEND_HI, (reg >> 8) & 0xff);
694 zr36060_write(ptr, ZR060_SGR_BHEND_LO, (reg >> 0) & 0xff);
695
696 /* active area */
697 reg = cap->y + norm->VStart; /* Vstart */
698 zr36060_write(ptr, ZR060_AAR_VSTART_HI, (reg >> 8) & 0xff);
699 zr36060_write(ptr, ZR060_AAR_VSTART_LO, (reg >> 0) & 0xff);
700
701 reg += cap->height; /* Vend */
702 zr36060_write(ptr, ZR060_AAR_VEND_HI, (reg >> 8) & 0xff);
703 zr36060_write(ptr, ZR060_AAR_VEND_LO, (reg >> 0) & 0xff);
704
705 reg = cap->x + norm->HStart; /* Hstart */
706 zr36060_write(ptr, ZR060_AAR_HSTART_HI, (reg >> 8) & 0xff);
707 zr36060_write(ptr, ZR060_AAR_HSTART_LO, (reg >> 0) & 0xff);
708
709 reg += cap->width; /* Hend */
710 zr36060_write(ptr, ZR060_AAR_HEND_HI, (reg >> 8) & 0xff);
711 zr36060_write(ptr, ZR060_AAR_HEND_LO, (reg >> 0) & 0xff);
712
713 /* subimage area */
714 reg = norm->VStart - 4; /* SVstart */
715 zr36060_write(ptr, ZR060_SWR_VSTART_HI, (reg >> 8) & 0xff);
716 zr36060_write(ptr, ZR060_SWR_VSTART_LO, (reg >> 0) & 0xff);
717
718 reg += norm->Ha / 2 + 8; /* SVend */
719 zr36060_write(ptr, ZR060_SWR_VEND_HI, (reg >> 8) & 0xff);
720 zr36060_write(ptr, ZR060_SWR_VEND_LO, (reg >> 0) & 0xff);
721
722 reg = norm->HStart /*+ 64 */ - 4; /* SHstart */
723 zr36060_write(ptr, ZR060_SWR_HSTART_HI, (reg >> 8) & 0xff);
724 zr36060_write(ptr, ZR060_SWR_HSTART_LO, (reg >> 0) & 0xff);
725
726 reg += norm->Wa + 8; /* SHend */
727 zr36060_write(ptr, ZR060_SWR_HEND_HI, (reg >> 8) & 0xff);
728 zr36060_write(ptr, ZR060_SWR_HEND_LO, (reg >> 0) & 0xff);
729
730 size = ptr->width * ptr->height;
731 /* Target compressed field size in bits: */
732 size = size * 16; /* uncompressed size in bits */
733 /* (Ronald) by default, quality = 100 is a compression
734 * ratio 1:2. Setting low_bitrate (insmod option) sets
735 * it to 1:4 (instead of 1:2, zr36060 max) as limit because the
736 * buz can't handle more at decimation=1... Use low_bitrate if
737 * you have a Buz, unless you know what you're doing */
738 size = size * cap->quality / (low_bitrate ? 400 : 200);
739 /* Lower limit (arbitrary, 1 KB) */
740 if (size < 8192)
741 size = 8192;
742 /* Upper limit: 7/8 of the code buffers */
743 if (size > ptr->total_code_vol * 7)
744 size = ptr->total_code_vol * 7;
745
746 ptr->real_code_vol = size >> 3; /* in bytes */
747
748 /* the MBCVR is the *maximum* block volume, according to the
749 * JPEG ISO specs, this shouldn't be used, since that allows
750 * for the best encoding quality. So set it to it's max value */
751 reg = ptr->max_block_vol;
752 zr36060_write(ptr, ZR060_MBCVR, reg);
753
754 return 0;
755}
756
757/* additional control functions */
758static int
759zr36060_control (struct videocodec *codec,
760 int type,
761 int size,
762 void *data)
763{
764 struct zr36060 *ptr = (struct zr36060 *) codec->data;
765 int *ival = (int *) data;
766
767 dprintk(2, "%s: control %d call with %d byte\n", ptr->name, type,
768 size);
769
770 switch (type) {
771 case CODEC_G_STATUS: /* get last status */
772 if (size != sizeof(int))
773 return -EFAULT;
774 zr36060_read_status(ptr);
775 *ival = ptr->status;
776 break;
777
778 case CODEC_G_CODEC_MODE:
779 if (size != sizeof(int))
780 return -EFAULT;
781 *ival = CODEC_MODE_BJPG;
782 break;
783
784 case CODEC_S_CODEC_MODE:
785 if (size != sizeof(int))
786 return -EFAULT;
787 if (*ival != CODEC_MODE_BJPG)
788 return -EINVAL;
789 /* not needed, do nothing */
790 return 0;
791
792 case CODEC_G_VFE:
793 case CODEC_S_VFE:
794 /* not needed, do nothing */
795 return 0;
796
797 case CODEC_S_MMAP:
798 /* not available, give an error */
799 return -ENXIO;
800
801 case CODEC_G_JPEG_TDS_BYTE: /* get target volume in byte */
802 if (size != sizeof(int))
803 return -EFAULT;
804 *ival = ptr->total_code_vol;
805 break;
806
807 case CODEC_S_JPEG_TDS_BYTE: /* get target volume in byte */
808 if (size != sizeof(int))
809 return -EFAULT;
810 ptr->total_code_vol = *ival;
811 ptr->real_code_vol = (ptr->total_code_vol * 6) >> 3;
812 break;
813
814 case CODEC_G_JPEG_SCALE: /* get scaling factor */
815 if (size != sizeof(int))
816 return -EFAULT;
817 *ival = zr36060_read_scalefactor(ptr);
818 break;
819
820 case CODEC_S_JPEG_SCALE: /* set scaling factor */
821 if (size != sizeof(int))
822 return -EFAULT;
823 ptr->scalefact = *ival;
824 break;
825
826 case CODEC_G_JPEG_APP_DATA: { /* get appn marker data */
827 struct jpeg_app_marker *app = data;
828
829 if (size != sizeof(struct jpeg_app_marker))
830 return -EFAULT;
831
832 *app = ptr->app;
833 break;
834 }
835
836 case CODEC_S_JPEG_APP_DATA: { /* set appn marker data */
837 struct jpeg_app_marker *app = data;
838
839 if (size != sizeof(struct jpeg_app_marker))
840 return -EFAULT;
841
842 ptr->app = *app;
843 break;
844 }
845
846 case CODEC_G_JPEG_COM_DATA: { /* get comment marker data */
847 struct jpeg_com_marker *com = data;
848
849 if (size != sizeof(struct jpeg_com_marker))
850 return -EFAULT;
851
852 *com = ptr->com;
853 break;
854 }
855
856 case CODEC_S_JPEG_COM_DATA: { /* set comment marker data */
857 struct jpeg_com_marker *com = data;
858
859 if (size != sizeof(struct jpeg_com_marker))
860 return -EFAULT;
861
862 ptr->com = *com;
863 break;
864 }
865
866 default:
867 return -EINVAL;
868 }
869
870 return size;
871}
872
873/* =========================================================================
874 Exit and unregister function:
875
876 Deinitializes Zoran's JPEG processor
877 ========================================================================= */
878
879static int
880zr36060_unset (struct videocodec *codec)
881{
882 struct zr36060 *ptr = codec->data;
883
884 if (ptr) {
885 /* do wee need some codec deinit here, too ???? */
886
887 dprintk(1, "%s: finished codec #%d\n", ptr->name,
888 ptr->num);
889 kfree(ptr);
890 codec->data = NULL;
891
892 zr36060_codecs--;
893 return 0;
894 }
895
896 return -EFAULT;
897}
898
899/* =========================================================================
900 Setup and registry function:
901
902 Initializes Zoran's JPEG processor
903
904 Also sets pixel size, average code size, mode (compr./decompr.)
905 (the given size is determined by the processor with the video interface)
906 ========================================================================= */
907
908static int
909zr36060_setup (struct videocodec *codec)
910{
911 struct zr36060 *ptr;
912 int res;
913
914 dprintk(2, "zr36060: initializing MJPEG subsystem #%d.\n",
915 zr36060_codecs);
916
917 if (zr36060_codecs == MAX_CODECS) {
918 dprintk(1,
919 KERN_ERR "zr36060: Can't attach more codecs!\n");
920 return -ENOSPC;
921 }
922 //mem structure init
923 codec->data = ptr = kmalloc(sizeof(struct zr36060), GFP_KERNEL);
924 if (NULL == ptr) {
925 dprintk(1, KERN_ERR "zr36060: Can't get enough memory!\n");
926 return -ENOMEM;
927 }
928 memset(ptr, 0, sizeof(struct zr36060));
929
930 snprintf(ptr->name, sizeof(ptr->name), "zr36060[%d]",
931 zr36060_codecs);
932 ptr->num = zr36060_codecs++;
933 ptr->codec = codec;
934
935 //testing
936 res = zr36060_basic_test(ptr);
937 if (res < 0) {
938 zr36060_unset(codec);
939 return res;
940 }
941 //final setup
942 memcpy(ptr->h_samp_ratio, zr36060_decimation_h, 8);
943 memcpy(ptr->v_samp_ratio, zr36060_decimation_v, 8);
944
945 ptr->bitrate_ctrl = 0; /* 0 or 1 - fixed file size flag
946 * (what is the difference?) */
947 ptr->mode = CODEC_DO_COMPRESSION;
948 ptr->width = 384;
949 ptr->height = 288;
950 ptr->total_code_vol = 16000; /* CHECKME */
951 ptr->real_code_vol = (ptr->total_code_vol * 6) >> 3;
952 ptr->max_block_vol = 240; /* CHECKME, was 120 is 240 */
953 ptr->scalefact = 0x100;
954 ptr->dri = 1; /* CHECKME, was 8 is 1 */
955
956 /* by default, no COM or APP markers - app should set those */
957 ptr->com.len = 0;
958 ptr->app.appn = 0;
959 ptr->app.len = 0;
960
961 zr36060_init(ptr);
962
963 dprintk(1, KERN_INFO "%s: codec attached and running\n",
964 ptr->name);
965
966 return 0;
967}
968
969static const struct videocodec zr36060_codec = {
970 .owner = THIS_MODULE,
971 .name = "zr36060",
972 .magic = 0L, // magic not used
973 .flags =
974 CODEC_FLAG_JPEG | CODEC_FLAG_HARDWARE | CODEC_FLAG_ENCODER |
975 CODEC_FLAG_DECODER | CODEC_FLAG_VFE,
976 .type = CODEC_TYPE_ZR36060,
977 .setup = zr36060_setup, // functionality
978 .unset = zr36060_unset,
979 .set_mode = zr36060_set_mode,
980 .set_video = zr36060_set_video,
981 .control = zr36060_control,
982 // others are not used
983};
984
985/* =========================================================================
986 HOOK IN DRIVER AS KERNEL MODULE
987 ========================================================================= */
988
989static int __init
990zr36060_init_module (void)
991{
992 //dprintk(1, "zr36060 driver %s\n",ZR060_VERSION);
993 zr36060_codecs = 0;
994 return videocodec_register(&zr36060_codec);
995}
996
997static void __exit
998zr36060_cleanup_module (void)
999{
1000 if (zr36060_codecs) {
1001 dprintk(1,
1002 "zr36060: something's wrong - %d codecs left somehow.\n",
1003 zr36060_codecs);
1004 }
1005
1006 /* however, we can't just stay alive */
1007 videocodec_unregister(&zr36060_codec);
1008}
1009
1010module_init(zr36060_init_module);
1011module_exit(zr36060_cleanup_module);
1012
1013MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@skynet.be>");
1014MODULE_DESCRIPTION("Driver module for ZR36060 jpeg processors "
1015 ZR060_VERSION);
1016MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/zr36060.h b/drivers/media/video/zr36060.h
new file mode 100644
index 00000000000..914ffa4ad8d
--- /dev/null
+++ b/drivers/media/video/zr36060.h
@@ -0,0 +1,220 @@
1/*
2 * Zoran ZR36060 basic configuration functions - header file
3 *
4 * Copyright (C) 2002 Laurent Pinchart <laurent.pinchart@skynet.be>
5 *
6 * $Id: zr36060.h,v 1.1.1.1.2.3 2003/01/14 21:18:47 rbultje Exp $
7 *
8 * ------------------------------------------------------------------------
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 */
26
27#ifndef ZR36060_H
28#define ZR36060_H
29
30#include "videocodec.h"
31
32/* data stored for each zoran jpeg codec chip */
33struct zr36060 {
34 char name[32];
35 int num;
36 /* io datastructure */
37 struct videocodec *codec;
38 // last coder status
39 __u8 status;
40 // actual coder setup
41 int mode;
42
43 __u16 width;
44 __u16 height;
45
46 __u16 bitrate_ctrl;
47
48 __u32 total_code_vol;
49 __u32 real_code_vol;
50 __u16 max_block_vol;
51
52 __u8 h_samp_ratio[8];
53 __u8 v_samp_ratio[8];
54 __u16 scalefact;
55 __u16 dri;
56
57 /* app/com marker data */
58 struct jpeg_app_marker app;
59 struct jpeg_com_marker com;
60};
61
62/* ZR36060 register addresses */
63#define ZR060_LOAD 0x000
64#define ZR060_CFSR 0x001
65#define ZR060_CIR 0x002
66#define ZR060_CMR 0x003
67#define ZR060_MBZ 0x004
68#define ZR060_MBCVR 0x005
69#define ZR060_MER 0x006
70#define ZR060_IMR 0x007
71#define ZR060_ISR 0x008
72#define ZR060_TCV_NET_HI 0x009
73#define ZR060_TCV_NET_MH 0x00a
74#define ZR060_TCV_NET_ML 0x00b
75#define ZR060_TCV_NET_LO 0x00c
76#define ZR060_TCV_DATA_HI 0x00d
77#define ZR060_TCV_DATA_MH 0x00e
78#define ZR060_TCV_DATA_ML 0x00f
79#define ZR060_TCV_DATA_LO 0x010
80#define ZR060_SF_HI 0x011
81#define ZR060_SF_LO 0x012
82#define ZR060_AF_HI 0x013
83#define ZR060_AF_M 0x014
84#define ZR060_AF_LO 0x015
85#define ZR060_ACV_HI 0x016
86#define ZR060_ACV_MH 0x017
87#define ZR060_ACV_ML 0x018
88#define ZR060_ACV_LO 0x019
89#define ZR060_ACT_HI 0x01a
90#define ZR060_ACT_MH 0x01b
91#define ZR060_ACT_ML 0x01c
92#define ZR060_ACT_LO 0x01d
93#define ZR060_ACV_TRUN_HI 0x01e
94#define ZR060_ACV_TRUN_MH 0x01f
95#define ZR060_ACV_TRUN_ML 0x020
96#define ZR060_ACV_TRUN_LO 0x021
97#define ZR060_IDR_DEV 0x022
98#define ZR060_IDR_REV 0x023
99#define ZR060_TCR_HI 0x024
100#define ZR060_TCR_LO 0x025
101#define ZR060_VCR 0x030
102#define ZR060_VPR 0x031
103#define ZR060_SR 0x032
104#define ZR060_BCR_Y 0x033
105#define ZR060_BCR_U 0x034
106#define ZR060_BCR_V 0x035
107#define ZR060_SGR_VTOTAL_HI 0x036
108#define ZR060_SGR_VTOTAL_LO 0x037
109#define ZR060_SGR_HTOTAL_HI 0x038
110#define ZR060_SGR_HTOTAL_LO 0x039
111#define ZR060_SGR_VSYNC 0x03a
112#define ZR060_SGR_HSYNC 0x03b
113#define ZR060_SGR_BVSTART 0x03c
114#define ZR060_SGR_BHSTART 0x03d
115#define ZR060_SGR_BVEND_HI 0x03e
116#define ZR060_SGR_BVEND_LO 0x03f
117#define ZR060_SGR_BHEND_HI 0x040
118#define ZR060_SGR_BHEND_LO 0x041
119#define ZR060_AAR_VSTART_HI 0x042
120#define ZR060_AAR_VSTART_LO 0x043
121#define ZR060_AAR_VEND_HI 0x044
122#define ZR060_AAR_VEND_LO 0x045
123#define ZR060_AAR_HSTART_HI 0x046
124#define ZR060_AAR_HSTART_LO 0x047
125#define ZR060_AAR_HEND_HI 0x048
126#define ZR060_AAR_HEND_LO 0x049
127#define ZR060_SWR_VSTART_HI 0x04a
128#define ZR060_SWR_VSTART_LO 0x04b
129#define ZR060_SWR_VEND_HI 0x04c
130#define ZR060_SWR_VEND_LO 0x04d
131#define ZR060_SWR_HSTART_HI 0x04e
132#define ZR060_SWR_HSTART_LO 0x04f
133#define ZR060_SWR_HEND_HI 0x050
134#define ZR060_SWR_HEND_LO 0x051
135
136#define ZR060_SOF_IDX 0x060
137#define ZR060_SOS_IDX 0x07a
138#define ZR060_DRI_IDX 0x0c0
139#define ZR060_DQT_IDX 0x0cc
140#define ZR060_DHT_IDX 0x1d4
141#define ZR060_APP_IDX 0x380
142#define ZR060_COM_IDX 0x3c0
143
144/* ZR36060 LOAD register bits */
145
146#define ZR060_LOAD_Load (1 << 7)
147#define ZR060_LOAD_SyncRst (1 << 0)
148
149/* ZR36060 Code FIFO Status register bits */
150
151#define ZR060_CFSR_Busy (1 << 7)
152#define ZR060_CFSR_CBusy (1 << 2)
153#define ZR060_CFSR_CFIFO (3 << 0)
154
155/* ZR36060 Code Interface register */
156
157#define ZR060_CIR_Code16 (1 << 7)
158#define ZR060_CIR_Endian (1 << 6)
159#define ZR060_CIR_CFIS (1 << 2)
160#define ZR060_CIR_CodeMstr (1 << 0)
161
162/* ZR36060 Codec Mode register */
163
164#define ZR060_CMR_Comp (1 << 7)
165#define ZR060_CMR_ATP (1 << 6)
166#define ZR060_CMR_Pass2 (1 << 5)
167#define ZR060_CMR_TLM (1 << 4)
168#define ZR060_CMR_BRB (1 << 2)
169#define ZR060_CMR_FSF (1 << 1)
170
171/* ZR36060 Markers Enable register */
172
173#define ZR060_MER_App (1 << 7)
174#define ZR060_MER_Com (1 << 6)
175#define ZR060_MER_DRI (1 << 5)
176#define ZR060_MER_DQT (1 << 4)
177#define ZR060_MER_DHT (1 << 3)
178
179/* ZR36060 Interrupt Mask register */
180
181#define ZR060_IMR_EOAV (1 << 3)
182#define ZR060_IMR_EOI (1 << 2)
183#define ZR060_IMR_End (1 << 1)
184#define ZR060_IMR_DataErr (1 << 0)
185
186/* ZR36060 Interrupt Status register */
187
188#define ZR060_ISR_ProCnt (3 << 6)
189#define ZR060_ISR_EOAV (1 << 3)
190#define ZR060_ISR_EOI (1 << 2)
191#define ZR060_ISR_End (1 << 1)
192#define ZR060_ISR_DataErr (1 << 0)
193
194/* ZR36060 Video Control register */
195
196#define ZR060_VCR_Video8 (1 << 7)
197#define ZR060_VCR_Range (1 << 6)
198#define ZR060_VCR_FIDet (1 << 3)
199#define ZR060_VCR_FIVedge (1 << 2)
200#define ZR060_VCR_FIExt (1 << 1)
201#define ZR060_VCR_SyncMstr (1 << 0)
202
203/* ZR36060 Video Polarity register */
204
205#define ZR060_VPR_VCLKPol (1 << 7)
206#define ZR060_VPR_PValPol (1 << 6)
207#define ZR060_VPR_PoePol (1 << 5)
208#define ZR060_VPR_SImgPol (1 << 4)
209#define ZR060_VPR_BLPol (1 << 3)
210#define ZR060_VPR_FIPol (1 << 2)
211#define ZR060_VPR_HSPol (1 << 1)
212#define ZR060_VPR_VSPol (1 << 0)
213
214/* ZR36060 Scaling register */
215
216#define ZR060_SR_VScale (1 << 2)
217#define ZR060_SR_HScale2 (1 << 0)
218#define ZR060_SR_HScale4 (2 << 0)
219
220#endif /*fndef ZR36060_H */
diff --git a/drivers/media/video/zr36120.c b/drivers/media/video/zr36120.c
new file mode 100644
index 00000000000..c33533155cc
--- /dev/null
+++ b/drivers/media/video/zr36120.c
@@ -0,0 +1,2073 @@
1/*
2 zr36120.c - Zoran 36120/36125 based framegrabbers
3
4 Copyright (C) 1998-1999 Pauline Middelink <middelin@polyware.nl>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19*/
20
21#include <linux/module.h>
22#include <linux/delay.h>
23#include <linux/init.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/vmalloc.h>
30#include <linux/mm.h>
31#include <linux/pci.h>
32#include <linux/signal.h>
33#include <linux/wait.h>
34#include <asm/io.h>
35#include <asm/pgtable.h>
36#include <asm/page.h>
37#include <linux/sched.h>
38#include <linux/video_decoder.h>
39
40#include <asm/uaccess.h>
41
42#include "tuner.h"
43#include "zr36120.h"
44#include "zr36120_mem.h"
45
46/* mark an required function argument unused - lintism */
47#define UNUSED(x) (void)(x)
48
49/* sensible default */
50#ifndef CARDTYPE
51#define CARDTYPE 0
52#endif
53
54/* Anybody who uses more than four? */
55#define ZORAN_MAX 4
56
57static unsigned int triton1=0; /* triton1 chipset? */
58static unsigned int cardtype[ZORAN_MAX]={ [ 0 ... ZORAN_MAX-1 ] = CARDTYPE };
59static int video_nr = -1;
60static int vbi_nr = -1;
61
62static struct pci_device_id zr36120_pci_tbl[] = {
63 { PCI_VENDOR_ID_ZORAN,PCI_DEVICE_ID_ZORAN_36120,
64 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
65 { 0 }
66};
67MODULE_DEVICE_TABLE(pci, zr36120_pci_tbl);
68
69MODULE_AUTHOR("Pauline Middelink <middelin@polyware.nl>");
70MODULE_DESCRIPTION("Zoran ZR36120 based framegrabber");
71MODULE_LICENSE("GPL");
72
73MODULE_PARM(triton1,"i");
74MODULE_PARM(cardtype,"1-" __MODULE_STRING(ZORAN_MAX) "i");
75MODULE_PARM(video_nr,"i");
76MODULE_PARM(vbi_nr,"i");
77
78static int zoran_cards;
79static struct zoran zorans[ZORAN_MAX];
80
81/*
82 * the meaning of each element can be found in zr36120.h
83 * Determining the value of gpdir/gpval can be tricky. The
84 * best way is to run the card under the original software
85 * and read the values from the general purpose registers
86 * 0x28 and 0x2C. How you do that is left as an exercise
87 * to the impatient reader :)
88 */
89#define T 1 /* to separate the bools from the ints */
90#define F 0
91static struct tvcard tvcards[] = {
92 /* reported working by <middelin@polyware.nl> */
93/*0*/ { "Trust Victor II",
94 2, 0, T, T, T, T, 0x7F, 0x80, { 1, SVHS(6) }, { 0 } },
95 /* reported working by <Michael.Paxton@aihw.gov.au> */
96/*1*/ { "Aitech WaveWatcher TV-PCI",
97 3, 0, T, F, T, T, 0x7F, 0x80, { 1, TUNER(3), SVHS(6) }, { 0 } },
98 /* reported working by ? */
99/*2*/ { "Genius Video Wonder PCI Video Capture Card",
100 2, 0, T, T, T, T, 0x7F, 0x80, { 1, SVHS(6) }, { 0 } },
101 /* reported working by <Pascal.Gabriel@wanadoo.fr> */
102/*3*/ { "Guillemot Maxi-TV PCI",
103 2, 0, T, T, T, T, 0x7F, 0x80, { 1, SVHS(6) }, { 0 } },
104 /* reported working by "Craig Whitmore <lennon@igrin.co.nz> */
105/*4*/ { "Quadrant Buster",
106 3, 3, T, F, T, T, 0x7F, 0x80, { SVHS(1), TUNER(2), 3 }, { 1, 2, 3 } },
107 /* a debug entry which has all inputs mapped */
108/*5*/ { "ZR36120 based framegrabber (all inputs enabled)",
109 6, 0, T, T, T, T, 0x7F, 0x80, { 1, 2, 3, 4, 5, 6 }, { 0 } }
110};
111#undef T
112#undef F
113#define NRTVCARDS (sizeof(tvcards)/sizeof(tvcards[0]))
114
115#ifdef __sparc__
116#define ENDIANESS 0
117#else
118#define ENDIANESS ZORAN_VFEC_LE
119#endif
120
121static struct { const char name[8]; uint mode; uint bpp; } palette2fmt[] = {
122/* n/a */ { "n/a", 0, 0 },
123/* GREY */ { "GRAY", 0, 0 },
124/* HI240 */ { "HI240", 0, 0 },
125/* RGB565 */ { "RGB565", ZORAN_VFEC_RGB_RGB565|ENDIANESS, 2 },
126/* RGB24 */ { "RGB24", ZORAN_VFEC_RGB_RGB888|ENDIANESS|ZORAN_VFEC_PACK24, 3 },
127/* RGB32 */ { "RGB32", ZORAN_VFEC_RGB_RGB888|ENDIANESS, 4 },
128/* RGB555 */ { "RGB555", ZORAN_VFEC_RGB_RGB555|ENDIANESS, 2 },
129/* YUV422 */ { "YUV422", ZORAN_VFEC_RGB_YUV422|ENDIANESS, 2 },
130/* YUYV */ { "YUYV", 0, 0 },
131/* UYVY */ { "UYVY", 0, 0 },
132/* YUV420 */ { "YUV420", 0, 0 },
133/* YUV411 */ { "YUV411", 0, 0 },
134/* RAW */ { "RAW", 0, 0 },
135/* YUV422P */ { "YUV422P", 0, 0 },
136/* YUV411P */ { "YUV411P", 0, 0 }};
137#define NRPALETTES (sizeof(palette2fmt)/sizeof(palette2fmt[0]))
138#undef ENDIANESS
139
140/* ----------------------------------------------------------------------- */
141/* ZORAN chipset detector */
142/* shamelessly stolen from bttv.c */
143/* Reason for beeing here: we need to detect if we are running on a */
144/* Triton based chipset, and if so, enable a certain bit */
145/* ----------------------------------------------------------------------- */
146static
147void __init handle_chipset(void)
148{
149 /* Just in case some nut set this to something dangerous */
150 if (triton1)
151 triton1 = ZORAN_VDC_TRICOM;
152
153 if (pci_pci_problems & PCIPCI_TRITON) {
154 printk(KERN_INFO "zoran: Host bridge 82437FX Triton PIIX\n");
155 triton1 = ZORAN_VDC_TRICOM;
156 }
157}
158
159/* ----------------------------------------------------------------------- */
160/* ZORAN functions */
161/* ----------------------------------------------------------------------- */
162
163static void zoran_set_geo(struct zoran* ztv, struct vidinfo* i);
164
165#if 0 /* unused */
166static
167void zoran_dump(struct zoran *ztv)
168{
169 char str[256];
170 char *p=str; /* shut up, gcc! */
171 int i;
172
173 for (i=0; i<0x60; i+=4) {
174 if ((i % 16) == 0) {
175 if (i) printk("%s\n",str);
176 p = str;
177 p+= sprintf(str, KERN_DEBUG " %04x: ",i);
178 }
179 p += sprintf(p, "%08x ",zrread(i));
180 }
181}
182#endif /* unused */
183
184static
185void reap_states(struct zoran* ztv)
186{
187 /* count frames */
188 ztv->fieldnr++;
189
190 /*
191 * Are we busy at all?
192 * This depends on if there is a workqueue AND the
193 * videotransfer is enabled on the chip...
194 */
195 if (ztv->workqueue && (zrread(ZORAN_VDC) & ZORAN_VDC_VIDEN))
196 {
197 struct vidinfo* newitem;
198
199 /* did we get a complete frame? */
200 if (zrread(ZORAN_VSTR) & ZORAN_VSTR_GRAB)
201 return;
202
203DEBUG(printk(CARD_DEBUG "completed %s at %p\n",CARD,ztv->workqueue->kindof==FBUFFER_GRAB?"grab":"read",ztv->workqueue));
204
205 /* we are done with this buffer, tell everyone */
206 ztv->workqueue->status = FBUFFER_DONE;
207 ztv->workqueue->fieldnr = ztv->fieldnr;
208 /* not good, here for BTTV_FIELDNR reasons */
209 ztv->lastfieldnr = ztv->fieldnr;
210
211 switch (ztv->workqueue->kindof) {
212 case FBUFFER_GRAB:
213 wake_up_interruptible(&ztv->grabq);
214 break;
215 case FBUFFER_VBI:
216 wake_up_interruptible(&ztv->vbiq);
217 break;
218 default:
219 printk(CARD_INFO "somebody killed the workqueue (kindof=%d)!\n",CARD,ztv->workqueue->kindof);
220 }
221
222 /* item completed, skip to next item in queue */
223 write_lock(&ztv->lock);
224 newitem = ztv->workqueue->next;
225 ztv->workqueue->next = 0; /* mark completed */
226 ztv->workqueue = newitem;
227 write_unlock(&ztv->lock);
228 }
229
230 /*
231 * ok, so it seems we have nothing in progress right now.
232 * Lets see if we can find some work.
233 */
234 if (ztv->workqueue)
235 {
236 struct vidinfo* newitem;
237again:
238
239DEBUG(printk(CARD_DEBUG "starting %s at %p\n",CARD,ztv->workqueue->kindof==FBUFFER_GRAB?"grab":"read",ztv->workqueue));
240
241 /* loadup the frame settings */
242 read_lock(&ztv->lock);
243 zoran_set_geo(ztv,ztv->workqueue);
244 read_unlock(&ztv->lock);
245
246 switch (ztv->workqueue->kindof) {
247 case FBUFFER_GRAB:
248 case FBUFFER_VBI:
249 zrand(~ZORAN_OCR_OVLEN, ZORAN_OCR);
250 zror(ZORAN_VSTR_SNAPSHOT,ZORAN_VSTR);
251 zror(ZORAN_VDC_VIDEN,ZORAN_VDC);
252
253 /* start single-shot grab */
254 zror(ZORAN_VSTR_GRAB, ZORAN_VSTR);
255 break;
256 default:
257 printk(CARD_INFO "what is this doing on the queue? (kindof=%d)\n",CARD,ztv->workqueue->kindof);
258 write_lock(&ztv->lock);
259 newitem = ztv->workqueue->next;
260 ztv->workqueue->next = 0;
261 ztv->workqueue = newitem;
262 write_unlock(&ztv->lock);
263 if (newitem)
264 goto again; /* yeah, sure.. */
265 }
266 /* bye for now */
267 return;
268 }
269DEBUG(printk(CARD_DEBUG "nothing in queue\n",CARD));
270
271 /*
272 * What? Even the workqueue is empty? Am i really here
273 * for nothing? Did i come all that way to... do nothing?
274 */
275
276 /* do we need to overlay? */
277 if (test_bit(STATE_OVERLAY, &ztv->state))
278 {
279 /* are we already overlaying? */
280 if (!(zrread(ZORAN_OCR) & ZORAN_OCR_OVLEN) ||
281 !(zrread(ZORAN_VDC) & ZORAN_VDC_VIDEN))
282 {
283DEBUG(printk(CARD_DEBUG "starting overlay\n",CARD));
284
285 read_lock(&ztv->lock);
286 zoran_set_geo(ztv,&ztv->overinfo);
287 read_unlock(&ztv->lock);
288
289 zror(ZORAN_OCR_OVLEN, ZORAN_OCR);
290 zrand(~ZORAN_VSTR_SNAPSHOT,ZORAN_VSTR);
291 zror(ZORAN_VDC_VIDEN,ZORAN_VDC);
292 }
293
294 /*
295 * leave overlaying on, but turn interrupts off.
296 */
297 zrand(~ZORAN_ICR_EN,ZORAN_ICR);
298 return;
299 }
300
301 /* do we have any VBI idle time processing? */
302 if (test_bit(STATE_VBI, &ztv->state))
303 {
304 struct vidinfo* item;
305 struct vidinfo* lastitem;
306
307 /* protect the workqueue */
308 write_lock(&ztv->lock);
309 lastitem = ztv->workqueue;
310 if (lastitem)
311 while (lastitem->next) lastitem = lastitem->next;
312 for (item=ztv->readinfo; item!=ztv->readinfo+ZORAN_VBI_BUFFERS; item++)
313 if (item->next == 0 && item->status == FBUFFER_FREE)
314 {
315DEBUG(printk(CARD_DEBUG "%p added to queue\n",CARD,item));
316 item->status = FBUFFER_BUSY;
317 if (!lastitem)
318 ztv->workqueue = item;
319 else
320 lastitem->next = item;
321 lastitem = item;
322 }
323 write_unlock(&ztv->lock);
324 if (ztv->workqueue)
325 goto again; /* hey, _i_ graduated :) */
326 }
327
328 /*
329 * Then we must be realy IDLE
330 */
331DEBUG(printk(CARD_DEBUG "turning off\n",CARD));
332 /* nothing further to do, disable DMA and further IRQs */
333 zrand(~ZORAN_VDC_VIDEN,ZORAN_VDC);
334 zrand(~ZORAN_ICR_EN,ZORAN_ICR);
335}
336
337static
338void zoran_irq(int irq, void *dev_id, struct pt_regs * regs)
339{
340 u32 stat,estat;
341 int count = 0;
342 struct zoran *ztv = dev_id;
343
344 UNUSED(irq); UNUSED(regs);
345 for (;;) {
346 /* get/clear interrupt status bits */
347 stat=zrread(ZORAN_ISR);
348 estat=stat & zrread(ZORAN_ICR);
349 if (!estat)
350 return;
351 zrwrite(estat,ZORAN_ISR);
352 IDEBUG(printk(CARD_DEBUG "estat %08x\n",CARD,estat));
353 IDEBUG(printk(CARD_DEBUG " stat %08x\n",CARD,stat));
354
355 if (estat & ZORAN_ISR_CODE)
356 {
357 IDEBUG(printk(CARD_DEBUG "CodReplIRQ\n",CARD));
358 }
359 if (estat & ZORAN_ISR_GIRQ0)
360 {
361 IDEBUG(printk(CARD_DEBUG "GIRQ0\n",CARD));
362 if (!ztv->card->usegirq1)
363 reap_states(ztv);
364 }
365 if (estat & ZORAN_ISR_GIRQ1)
366 {
367 IDEBUG(printk(CARD_DEBUG "GIRQ1\n",CARD));
368 if (ztv->card->usegirq1)
369 reap_states(ztv);
370 }
371
372 count++;
373 if (count > 10)
374 printk(CARD_ERR "irq loop %d (%x)\n",CARD,count,estat);
375 if (count > 20)
376 {
377 zrwrite(0, ZORAN_ICR);
378 printk(CARD_ERR "IRQ lockup, cleared int mask\n",CARD);
379 }
380 }
381}
382
383static
384int zoran_muxsel(struct zoran* ztv, int channel, int norm)
385{
386 int rv;
387
388 /* set the new video norm */
389 rv = i2c_control_device(&(ztv->i2c), I2C_DRIVERID_VIDEODECODER, DECODER_SET_NORM, &norm);
390 if (rv)
391 return rv;
392 ztv->norm = norm;
393
394 /* map the given channel to the cards decoder's channel */
395 channel = ztv->card->video_mux[channel] & CHANNEL_MASK;
396
397 /* set the new channel */
398 rv = i2c_control_device(&(ztv->i2c), I2C_DRIVERID_VIDEODECODER, DECODER_SET_INPUT, &channel);
399 return rv;
400}
401
402/* Tell the interrupt handler what to to. */
403static
404void zoran_cap(struct zoran* ztv, int on)
405{
406DEBUG(printk(CARD_DEBUG "zoran_cap(%d) state=%x\n",CARD,on,ztv->state));
407
408 if (on) {
409 ztv->running = 1;
410
411 /*
412 * turn interrupts (back) on. The DMA will be enabled
413 * inside the irq handler when it detects a restart.
414 */
415 zror(ZORAN_ICR_EN,ZORAN_ICR);
416 }
417 else {
418 /*
419 * turn both interrupts and DMA off
420 */
421 zrand(~ZORAN_VDC_VIDEN,ZORAN_VDC);
422 zrand(~ZORAN_ICR_EN,ZORAN_ICR);
423
424 ztv->running = 0;
425 }
426}
427
428static ulong dmask[] = {
429 0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFC, 0xFFFFFFF8,
430 0xFFFFFFF0, 0xFFFFFFE0, 0xFFFFFFC0, 0xFFFFFF80,
431 0xFFFFFF00, 0xFFFFFE00, 0xFFFFFC00, 0xFFFFF800,
432 0xFFFFF000, 0xFFFFE000, 0xFFFFC000, 0xFFFF8000,
433 0xFFFF0000, 0xFFFE0000, 0xFFFC0000, 0xFFF80000,
434 0xFFF00000, 0xFFE00000, 0xFFC00000, 0xFF800000,
435 0xFF000000, 0xFE000000, 0xFC000000, 0xF8000000,
436 0xF0000000, 0xE0000000, 0xC0000000, 0x80000000
437};
438
439static
440void zoran_built_overlay(struct zoran* ztv, int count, struct video_clip *vcp)
441{
442 ulong* mtop;
443 int ystep = (ztv->vidXshift + ztv->vidWidth+31)/32; /* next DWORD */
444 int i;
445
446DEBUG(printk(KERN_DEBUG " overlay at %p, ystep=%d, clips=%d\n",ztv->overinfo.overlay,ystep,count));
447
448 for (i=0; i<count; i++) {
449 struct video_clip *vp = vcp+i;
450 UNUSED(vp);
451DEBUG(printk(KERN_DEBUG " %d: clip(%d,%d,%d,%d)\n", i,vp->x,vp->y,vp->width,vp->height));
452 }
453
454 /*
455 * activate the visible portion of the screen
456 * Note we take some shortcuts here, because we
457 * know the width can never be < 32. (I.e. a DWORD)
458 * We also assume the overlay starts somewhere in
459 * the FIRST dword.
460 */
461 {
462 int start = ztv->vidXshift;
463 ulong firstd = dmask[start];
464 ulong lastd = ~dmask[(start + ztv->overinfo.w) & 31];
465 mtop = ztv->overinfo.overlay;
466 for (i=0; i<ztv->overinfo.h; i++) {
467 int w = ztv->vidWidth;
468 ulong* line = mtop;
469 if (start & 31) {
470 *line++ = firstd;
471 w -= 32-(start&31);
472 }
473 memset(line, ~0, w/8);
474 if (w & 31)
475 line[w/32] = lastd;
476 mtop += ystep;
477 }
478 }
479
480 /* process clipping regions */
481 for (i=0; i<count; i++) {
482 int h;
483 if (vcp->x < 0 || (uint)vcp->x > ztv->overinfo.w ||
484 vcp->y < 0 || vcp->y > ztv->overinfo.h ||
485 vcp->width < 0 || (uint)(vcp->x+vcp->width) > ztv->overinfo.w ||
486 vcp->height < 0 || (vcp->y+vcp->height) > ztv->overinfo.h)
487 {
488 DEBUG(printk(CARD_DEBUG "invalid clipzone (%d,%d,%d,%d) not in (0,0,%d,%d), adapting\n",CARD,vcp->x,vcp->y,vcp->width,vcp->height,ztv->overinfo.w,ztv->overinfo.h));
489 if (vcp->x < 0) vcp->x = 0;
490 if ((uint)vcp->x > ztv->overinfo.w) vcp->x = ztv->overinfo.w;
491 if (vcp->y < 0) vcp->y = 0;
492 if (vcp->y > ztv->overinfo.h) vcp->y = ztv->overinfo.h;
493 if (vcp->width < 0) vcp->width = 0;
494 if ((uint)(vcp->x+vcp->width) > ztv->overinfo.w) vcp->width = ztv->overinfo.w - vcp->x;
495 if (vcp->height < 0) vcp->height = 0;
496 if (vcp->y+vcp->height > ztv->overinfo.h) vcp->height = ztv->overinfo.h - vcp->y;
497// continue;
498 }
499
500 mtop = &ztv->overinfo.overlay[vcp->y*ystep];
501 for (h=0; h<=vcp->height; h++) {
502 int w;
503 int x = ztv->vidXshift + vcp->x;
504 for (w=0; w<=vcp->width; w++) {
505 clear_bit(x&31, &mtop[x/32]);
506 x++;
507 }
508 mtop += ystep;
509 }
510 ++vcp;
511 }
512
513 mtop = ztv->overinfo.overlay;
514 zrwrite(virt_to_bus(mtop), ZORAN_MTOP);
515 zrwrite(virt_to_bus(mtop+ystep), ZORAN_MBOT);
516 zraor((ztv->vidInterlace*ystep)<<0,~ZORAN_OCR_MASKSTRIDE,ZORAN_OCR);
517}
518
519struct tvnorm
520{
521 u16 Wt, Wa, Ht, Ha, HStart, VStart;
522};
523
524static struct tvnorm tvnorms[] = {
525 /* PAL-BDGHI */
526/* { 864, 720, 625, 576, 131, 21 },*/
527/*00*/ { 864, 768, 625, 576, 81, 17 },
528 /* NTSC */
529/*01*/ { 858, 720, 525, 480, 121, 10 },
530 /* SECAM */
531/*02*/ { 864, 720, 625, 576, 131, 21 },
532 /* BW50 */
533/*03*/ { 864, 720, 625, 576, 131, 21 },
534 /* BW60 */
535/*04*/ { 858, 720, 525, 480, 121, 10 }
536};
537#define TVNORMS (sizeof(tvnorms)/sizeof(tvnorm))
538
539/*
540 * Program the chip for a setup as described in the vidinfo struct.
541 *
542 * Side-effects: calculates vidXshift, vidInterlace,
543 * vidHeight, vidWidth which are used in a later stage
544 * to calculate the overlay mask
545 *
546 * This is an internal function, as such it does not check the
547 * validity of the struct members... Spectaculair crashes will
548 * follow /very/ quick when you're wrong and the chip right :)
549 */
550static
551void zoran_set_geo(struct zoran* ztv, struct vidinfo* i)
552{
553 ulong top, bot;
554 int stride;
555 int winWidth, winHeight;
556 int maxWidth, maxHeight, maxXOffset, maxYOffset;
557 long vfec;
558
559DEBUG(printk(CARD_DEBUG "set_geo(rect=(%d,%d,%d,%d), norm=%d, format=%d, bpp=%d, bpl=%d, busadr=%lx, overlay=%p)\n",CARD,i->x,i->y,i->w,i->h,ztv->norm,i->format,i->bpp,i->bpl,i->busadr,i->overlay));
560
561 /*
562 * make sure the DMA transfers are inhibited during our
563 * reprogramming of the chip
564 */
565 zrand(~ZORAN_VDC_VIDEN,ZORAN_VDC);
566
567 maxWidth = tvnorms[ztv->norm].Wa;
568 maxHeight = tvnorms[ztv->norm].Ha/2;
569 maxXOffset = tvnorms[ztv->norm].HStart;
570 maxYOffset = tvnorms[ztv->norm].VStart;
571
572 /* setup vfec register (keep ExtFl,TopField and VCLKPol settings) */
573 vfec = (zrread(ZORAN_VFEC) & (ZORAN_VFEC_EXTFL|ZORAN_VFEC_TOPFIELD|ZORAN_VFEC_VCLKPOL)) |
574 (palette2fmt[i->format].mode & (ZORAN_VFEC_RGB|ZORAN_VFEC_ERRDIF|ZORAN_VFEC_LE|ZORAN_VFEC_PACK24));
575
576 /*
577 * Set top, bottom ptrs. Since these must be DWORD aligned,
578 * possible adjust the x and the width of the window.
579 * so the endposition stay the same. The vidXshift will make
580 * sure we are not writing pixels before the requested x.
581 */
582 ztv->vidXshift = 0;
583 winWidth = i->w;
584 if (winWidth < 0)
585 winWidth = -winWidth;
586 top = i->busadr + i->x*i->bpp + i->y*i->bpl;
587 if (top & 3) {
588 ztv->vidXshift = (top & 3) / i->bpp;
589 winWidth += ztv->vidXshift;
590 DEBUG(printk(KERN_DEBUG " window-x shifted %d pixels left\n",ztv->vidXshift));
591 top &= ~3;
592 }
593
594 /*
595 * bottom points to next frame but in interleaved mode we want
596 * to 'mix' the 2 frames to one capture, so 'bot' points to one
597 * (physical) line below the top line.
598 */
599 bot = top + i->bpl;
600 zrwrite(top,ZORAN_VTOP);
601 zrwrite(bot,ZORAN_VBOT);
602
603 /*
604 * Make sure the winWidth is DWORD aligned too,
605 * thereby automaticly making sure the stride to the
606 * next line is DWORD aligned too (as required by spec).
607 */
608 if ((winWidth*i->bpp) & 3) {
609DEBUG(printk(KERN_DEBUG " window-width enlarged by %d pixels\n",(winWidth*i->bpp) & 3));
610 winWidth += (winWidth*i->bpp) & 3;
611 }
612
613 /* determine the DispMode and stride */
614 if (i->h >= 0 && i->h <= maxHeight) {
615 /* single frame grab suffices for this height. */
616 vfec |= ZORAN_VFEC_DISPMOD;
617 ztv->vidInterlace = 0;
618 stride = i->bpl - (winWidth*i->bpp);
619 winHeight = i->h;
620 }
621 else {
622 /* interleaving needed for this height */
623 ztv->vidInterlace = 1;
624 stride = i->bpl*2 - (winWidth*i->bpp);
625 winHeight = i->h/2;
626 }
627 if (winHeight < 0) /* can happen for VBI! */
628 winHeight = -winHeight;
629
630 /* safety net, sometimes bpl is too short??? */
631 if (stride<0) {
632DEBUG(printk(CARD_DEBUG "WARNING stride = %d\n",CARD,stride));
633 stride = 0;
634 }
635
636 zraor((winHeight<<12)|(winWidth<<0),~(ZORAN_VDC_VIDWINHT|ZORAN_VDC_VIDWINWID), ZORAN_VDC);
637 zraor(stride<<16,~ZORAN_VSTR_DISPSTRIDE,ZORAN_VSTR);
638
639 /* remember vidWidth, vidHeight for overlay calculations */
640 ztv->vidWidth = winWidth;
641 ztv->vidHeight = winHeight;
642DEBUG(printk(KERN_DEBUG " top=%08lx, bottom=%08lx\n",top,bot));
643DEBUG(printk(KERN_DEBUG " winWidth=%d, winHeight=%d\n",winWidth,winHeight));
644DEBUG(printk(KERN_DEBUG " maxWidth=%d, maxHeight=%d\n",maxWidth,maxHeight));
645DEBUG(printk(KERN_DEBUG " stride=%d\n",stride));
646
647 /*
648 * determine horizontal scales and crops
649 */
650 if (i->w < 0) {
651 int Hstart = 1;
652 int Hend = Hstart + winWidth;
653DEBUG(printk(KERN_DEBUG " Y: scale=0, start=%d, end=%d\n", Hstart, Hend));
654 zraor((Hstart<<10)|(Hend<<0),~(ZORAN_VFEH_HSTART|ZORAN_VFEH_HEND),ZORAN_VFEH);
655 }
656 else {
657 int Wa = maxWidth;
658 int X = (winWidth*64+Wa-1)/Wa;
659 int We = winWidth*64/X;
660 int HorDcm = 64-X;
661 int hcrop1 = 2*(Wa-We)/4;
662 /*
663 * BUGFIX: Juha Nurmela <junki@qn-lpr2-165.quicknet.inet.fi>
664 * found the solution to the color phase shift.
665 * See ChangeLog for the full explanation)
666 */
667 int Hstart = (maxXOffset + hcrop1) | 1;
668 int Hend = Hstart + We - 1;
669
670DEBUG(printk(KERN_DEBUG " X: scale=%d, start=%d, end=%d\n", HorDcm, Hstart, Hend));
671
672 zraor((Hstart<<10)|(Hend<<0),~(ZORAN_VFEH_HSTART|ZORAN_VFEH_HEND),ZORAN_VFEH);
673 vfec |= HorDcm<<14;
674
675 if (HorDcm<16)
676 vfec |= ZORAN_VFEC_HFILTER_1; /* no filter */
677 else if (HorDcm<32)
678 vfec |= ZORAN_VFEC_HFILTER_3; /* 3 tap filter */
679 else if (HorDcm<48)
680 vfec |= ZORAN_VFEC_HFILTER_4; /* 4 tap filter */
681 else vfec |= ZORAN_VFEC_HFILTER_5; /* 5 tap filter */
682 }
683
684 /*
685 * Determine vertical scales and crops
686 *
687 * when height is negative, we want to read starting at line 0
688 * One day someone might need access to these lines...
689 */
690 if (i->h < 0) {
691 int Vstart = 0;
692 int Vend = Vstart + winHeight;
693DEBUG(printk(KERN_DEBUG " Y: scale=0, start=%d, end=%d\n", Vstart, Vend));
694 zraor((Vstart<<10)|(Vend<<0),~(ZORAN_VFEV_VSTART|ZORAN_VFEV_VEND),ZORAN_VFEV);
695 }
696 else {
697 int Ha = maxHeight;
698 int Y = (winHeight*64+Ha-1)/Ha;
699 int He = winHeight*64/Y;
700 int VerDcm = 64-Y;
701 int vcrop1 = 2*(Ha-He)/4;
702 int Vstart = maxYOffset + vcrop1;
703 int Vend = Vstart + He - 1;
704
705DEBUG(printk(KERN_DEBUG " Y: scale=%d, start=%d, end=%d\n", VerDcm, Vstart, Vend));
706 zraor((Vstart<<10)|(Vend<<0),~(ZORAN_VFEV_VSTART|ZORAN_VFEV_VEND),ZORAN_VFEV);
707 vfec |= VerDcm<<8;
708 }
709
710DEBUG(printk(KERN_DEBUG " F: format=%d(=%s)\n",i->format,palette2fmt[i->format].name));
711
712 /* setup the requested format */
713 zrwrite(vfec, ZORAN_VFEC);
714}
715
716static
717void zoran_common_open(struct zoran* ztv, int flags)
718{
719 UNUSED(flags);
720
721 /* already opened? */
722 if (ztv->users++ != 0)
723 return;
724
725 /* unmute audio */
726 /* /what/ audio? */
727
728 ztv->state = 0;
729
730 /* setup the encoder to the initial values */
731 ztv->picture.colour=254<<7;
732 ztv->picture.brightness=128<<8;
733 ztv->picture.hue=128<<8;
734 ztv->picture.contrast=216<<7;
735 i2c_control_device(&ztv->i2c, I2C_DRIVERID_VIDEODECODER, DECODER_SET_PICTURE, &ztv->picture);
736
737 /* default to the composite input since my camera is there */
738 zoran_muxsel(ztv, 0, VIDEO_MODE_PAL);
739}
740
741static
742void zoran_common_close(struct zoran* ztv)
743{
744 if (--ztv->users != 0)
745 return;
746
747 /* mute audio */
748 /* /what/ audio? */
749
750 /* stop the chip */
751 zoran_cap(ztv, 0);
752}
753
754/*
755 * Open a zoran card. Right now the flags are just a hack
756 */
757static int zoran_open(struct video_device *dev, int flags)
758{
759 struct zoran *ztv = (struct zoran*)dev;
760 struct vidinfo* item;
761 char* pos;
762
763 DEBUG(printk(CARD_DEBUG "open(dev,%d)\n",CARD,flags));
764
765 /*********************************************
766 * We really should be doing lazy allocing...
767 *********************************************/
768 /* allocate a frame buffer */
769 if (!ztv->fbuffer)
770 ztv->fbuffer = bmalloc(ZORAN_MAX_FBUFSIZE);
771 if (!ztv->fbuffer) {
772 /* could not get a buffer, bail out */
773 return -ENOBUFS;
774 }
775 /* at this time we _always_ have a framebuffer */
776 memset(ztv->fbuffer,0,ZORAN_MAX_FBUFSIZE);
777
778 if (!ztv->overinfo.overlay)
779 ztv->overinfo.overlay = kmalloc(1024*1024/8, GFP_KERNEL);
780 if (!ztv->overinfo.overlay) {
781 /* could not get an overlay buffer, bail out */
782 bfree(ztv->fbuffer, ZORAN_MAX_FBUFSIZE);
783 return -ENOBUFS;
784 }
785 /* at this time we _always_ have a overlay */
786
787 /* clear buffer status, and give them a DMAable address */
788 pos = ztv->fbuffer;
789 for (item=ztv->grabinfo; item!=ztv->grabinfo+ZORAN_MAX_FBUFFERS; item++)
790 {
791 item->status = FBUFFER_FREE;
792 item->memadr = pos;
793 item->busadr = virt_to_bus(pos);
794 pos += ZORAN_MAX_FBUFFER;
795 }
796
797 /* do the common part of all open's */
798 zoran_common_open(ztv, flags);
799
800 return 0;
801}
802
803static
804void zoran_close(struct video_device* dev)
805{
806 struct zoran *ztv = (struct zoran*)dev;
807
808 DEBUG(printk(CARD_DEBUG "close(dev)\n",CARD));
809
810 /* driver specific closure */
811 clear_bit(STATE_OVERLAY, &ztv->state);
812
813 zoran_common_close(ztv);
814
815 /*
816 * This is sucky but right now I can't find a good way to
817 * be sure its safe to free the buffer. We wait 5-6 fields
818 * which is more than sufficient to be sure.
819 */
820 msleep(100); /* Wait 1/10th of a second */
821
822 /* free the allocated framebuffer */
823 if (ztv->fbuffer)
824 bfree( ztv->fbuffer, ZORAN_MAX_FBUFSIZE );
825 ztv->fbuffer = 0;
826 if (ztv->overinfo.overlay)
827 kfree( ztv->overinfo.overlay );
828 ztv->overinfo.overlay = 0;
829
830}
831
832/*
833 * This read function could be used reentrant in a SMP situation.
834 *
835 * This is made possible by the spinlock which is kept till we
836 * found and marked a buffer for our own use. The lock must
837 * be released as soon as possible to prevent lock contention.
838 */
839static
840long zoran_read(struct video_device* dev, char* buf, unsigned long count, int nonblock)
841{
842 struct zoran *ztv = (struct zoran*)dev;
843 unsigned long max;
844 struct vidinfo* unused = 0;
845 struct vidinfo* done = 0;
846
847 DEBUG(printk(CARD_DEBUG "zoran_read(%p,%ld,%d)\n",CARD,buf,count,nonblock));
848
849 /* find ourself a free or completed buffer */
850 for (;;) {
851 struct vidinfo* item;
852
853 write_lock_irq(&ztv->lock);
854 for (item=ztv->grabinfo; item!=ztv->grabinfo+ZORAN_MAX_FBUFFERS; item++)
855 {
856 if (!unused && item->status == FBUFFER_FREE)
857 unused = item;
858 if (!done && item->status == FBUFFER_DONE)
859 done = item;
860 }
861 if (done || unused)
862 break;
863
864 /* no more free buffers, wait for them. */
865 write_unlock_irq(&ztv->lock);
866 if (nonblock)
867 return -EWOULDBLOCK;
868 interruptible_sleep_on(&ztv->grabq);
869 if (signal_pending(current))
870 return -EINTR;
871 }
872
873 /* Do we have 'ready' data? */
874 if (!done) {
875 /* no? than this will take a while... */
876 if (nonblock) {
877 write_unlock_irq(&ztv->lock);
878 return -EWOULDBLOCK;
879 }
880
881 /* mark the unused buffer as wanted */
882 unused->status = FBUFFER_BUSY;
883 unused->w = 320;
884 unused->h = 240;
885 unused->format = VIDEO_PALETTE_RGB24;
886 unused->bpp = palette2fmt[unused->format].bpp;
887 unused->bpl = unused->w * unused->bpp;
888 unused->next = 0;
889 { /* add to tail of queue */
890 struct vidinfo* oldframe = ztv->workqueue;
891 if (!oldframe) ztv->workqueue = unused;
892 else {
893 while (oldframe->next) oldframe = oldframe->next;
894 oldframe->next = unused;
895 }
896 }
897 write_unlock_irq(&ztv->lock);
898
899 /* tell the state machine we want it filled /NOW/ */
900 zoran_cap(ztv, 1);
901
902 /* wait till this buffer gets grabbed */
903 wait_event_interruptible(ztv->grabq,
904 (unused->status != FBUFFER_BUSY));
905 /* see if a signal did it */
906 if (signal_pending(current))
907 return -EINTR;
908 done = unused;
909 }
910 else
911 write_unlock_irq(&ztv->lock);
912
913 /* Yes! we got data! */
914 max = done->bpl * done->h;
915 if (count > max)
916 count = max;
917 if (copy_to_user((void*)buf, done->memadr, count))
918 count = -EFAULT;
919
920 /* keep the engine running */
921 done->status = FBUFFER_FREE;
922// zoran_cap(ztv,1);
923
924 /* tell listeners this buffer became free */
925 wake_up_interruptible(&ztv->grabq);
926
927 /* goodbye */
928 DEBUG(printk(CARD_DEBUG "zoran_read() returns %lu\n",CARD,count));
929 return count;
930}
931
932static
933long zoran_write(struct video_device* dev, const char* buf, unsigned long count, int nonblock)
934{
935 struct zoran *ztv = (struct zoran *)dev;
936 UNUSED(ztv); UNUSED(dev); UNUSED(buf); UNUSED(count); UNUSED(nonblock);
937 DEBUG(printk(CARD_DEBUG "zoran_write\n",CARD));
938 return -EINVAL;
939}
940
941static
942unsigned int zoran_poll(struct video_device *dev, struct file *file, poll_table *wait)
943{
944 struct zoran *ztv = (struct zoran *)dev;
945 struct vidinfo* item;
946 unsigned int mask = 0;
947
948 poll_wait(file, &ztv->grabq, wait);
949
950 for (item=ztv->grabinfo; item!=ztv->grabinfo+ZORAN_MAX_FBUFFERS; item++)
951 if (item->status == FBUFFER_DONE)
952 {
953 mask |= (POLLIN | POLLRDNORM);
954 break;
955 }
956
957 DEBUG(printk(CARD_DEBUG "zoran_poll()=%x\n",CARD,mask));
958
959 return mask;
960}
961
962/* append a new clipregion to the vector of video_clips */
963static
964void new_clip(struct video_window* vw, struct video_clip* vcp, int x, int y, int w, int h)
965{
966 vcp[vw->clipcount].x = x;
967 vcp[vw->clipcount].y = y;
968 vcp[vw->clipcount].width = w;
969 vcp[vw->clipcount].height = h;
970 vw->clipcount++;
971}
972
973static
974int zoran_ioctl(struct video_device* dev, unsigned int cmd, void *arg)
975{
976 struct zoran* ztv = (struct zoran*)dev;
977
978 switch (cmd) {
979 case VIDIOCGCAP:
980 {
981 struct video_capability c;
982 DEBUG(printk(CARD_DEBUG "VIDIOCGCAP\n",CARD));
983
984 strcpy(c.name,ztv->video_dev.name);
985 c.type = VID_TYPE_CAPTURE|
986 VID_TYPE_OVERLAY|
987 VID_TYPE_CLIPPING|
988 VID_TYPE_FRAMERAM|
989 VID_TYPE_SCALES;
990 if (ztv->have_tuner)
991 c.type |= VID_TYPE_TUNER;
992 if (ztv->have_decoder) {
993 c.channels = ztv->card->video_inputs;
994 c.audios = ztv->card->audio_inputs;
995 } else
996 /* no decoder -> no channels */
997 c.channels = c.audios = 0;
998 c.maxwidth = 768;
999 c.maxheight = 576;
1000 c.minwidth = 32;
1001 c.minheight = 32;
1002 if (copy_to_user(arg,&c,sizeof(c)))
1003 return -EFAULT;
1004 break;
1005 }
1006
1007 case VIDIOCGCHAN:
1008 {
1009 struct video_channel v;
1010 int mux;
1011 if (copy_from_user(&v, arg,sizeof(v)))
1012 return -EFAULT;
1013 DEBUG(printk(CARD_DEBUG "VIDIOCGCHAN(%d)\n",CARD,v.channel));
1014 v.flags=VIDEO_VC_AUDIO
1015#ifdef VIDEO_VC_NORM
1016 |VIDEO_VC_NORM
1017#endif
1018 ;
1019 v.tuners=0;
1020 v.type=VIDEO_TYPE_CAMERA;
1021#ifdef I_EXPECT_POSSIBLE_NORMS_IN_THE_API
1022 v.norm=VIDEO_MODE_PAL|
1023 VIDEO_MODE_NTSC|
1024 VIDEO_MODE_SECAM;
1025#else
1026 v.norm=VIDEO_MODE_PAL;
1027#endif
1028 /* too many inputs? no decoder -> no channels */
1029 if (!ztv->have_decoder || v.channel < 0 || v.channel >= ztv->card->video_inputs)
1030 return -EINVAL;
1031
1032 /* now determine the name of the channel */
1033 mux = ztv->card->video_mux[v.channel];
1034 if (mux & IS_TUNER) {
1035 /* lets assume only one tuner, yes? */
1036 strcpy(v.name,"Television");
1037 v.type = VIDEO_TYPE_TV;
1038 if (ztv->have_tuner) {
1039 v.flags |= VIDEO_VC_TUNER;
1040 v.tuners = 1;
1041 }
1042 }
1043 else if (mux & IS_SVHS)
1044 sprintf(v.name,"S-Video-%d",v.channel);
1045 else
1046 sprintf(v.name,"CVBS-%d",v.channel);
1047
1048 if (copy_to_user(arg,&v,sizeof(v)))
1049 return -EFAULT;
1050 break;
1051 }
1052 case VIDIOCSCHAN:
1053 { /* set video channel */
1054 struct video_channel v;
1055 if (copy_from_user(&v, arg,sizeof(v)))
1056 return -EFAULT;
1057 DEBUG(printk(CARD_DEBUG "VIDIOCSCHAN(%d,%d)\n",CARD,v.channel,v.norm));
1058
1059 /* too many inputs? no decoder -> no channels */
1060 if (!ztv->have_decoder || v.channel >= ztv->card->video_inputs || v.channel < 0)
1061 return -EINVAL;
1062
1063 if (v.norm != VIDEO_MODE_PAL &&
1064 v.norm != VIDEO_MODE_NTSC &&
1065 v.norm != VIDEO_MODE_SECAM &&
1066 v.norm != VIDEO_MODE_AUTO)
1067 return -EOPNOTSUPP;
1068
1069 /* make it happen, nr1! */
1070 return zoran_muxsel(ztv,v.channel,v.norm);
1071 }
1072
1073 case VIDIOCGTUNER:
1074 {
1075 struct video_tuner v;
1076 if (copy_from_user(&v, arg,sizeof(v)))
1077 return -EFAULT;
1078 DEBUG(printk(CARD_DEBUG "VIDIOCGTUNER(%d)\n",CARD,v.tuner));
1079
1080 /* Only no or one tuner for now */
1081 if (!ztv->have_tuner || v.tuner)
1082 return -EINVAL;
1083
1084 strcpy(v.name,"Television");
1085 v.rangelow = 0;
1086 v.rangehigh = ~0;
1087 v.flags = VIDEO_TUNER_PAL|VIDEO_TUNER_NTSC|VIDEO_TUNER_SECAM;
1088 v.mode = ztv->norm;
1089 v.signal = 0xFFFF; /* unknown */
1090
1091 if (copy_to_user(arg,&v,sizeof(v)))
1092 return -EFAULT;
1093 break;
1094 }
1095 case VIDIOCSTUNER:
1096 {
1097 struct video_tuner v;
1098 if (copy_from_user(&v, arg, sizeof(v)))
1099 return -EFAULT;
1100 DEBUG(printk(CARD_DEBUG "VIDIOCSTUNER(%d,%d)\n",CARD,v.tuner,v.mode));
1101
1102 /* Only no or one tuner for now */
1103 if (!ztv->have_tuner || v.tuner)
1104 return -EINVAL;
1105
1106 /* and it only has certain valid modes */
1107 if( v.mode != VIDEO_MODE_PAL &&
1108 v.mode != VIDEO_MODE_NTSC &&
1109 v.mode != VIDEO_MODE_SECAM)
1110 return -EOPNOTSUPP;
1111
1112 /* engage! */
1113 return zoran_muxsel(ztv,v.tuner,v.mode);
1114 }
1115
1116 case VIDIOCGPICT:
1117 {
1118 struct video_picture p = ztv->picture;
1119 DEBUG(printk(CARD_DEBUG "VIDIOCGPICT\n",CARD));
1120 p.depth = ztv->depth;
1121 switch (p.depth) {
1122 case 8: p.palette=VIDEO_PALETTE_YUV422;
1123 break;
1124 case 15: p.palette=VIDEO_PALETTE_RGB555;
1125 break;
1126 case 16: p.palette=VIDEO_PALETTE_RGB565;
1127 break;
1128 case 24: p.palette=VIDEO_PALETTE_RGB24;
1129 break;
1130 case 32: p.palette=VIDEO_PALETTE_RGB32;
1131 break;
1132 }
1133 if (copy_to_user(arg, &p, sizeof(p)))
1134 return -EFAULT;
1135 break;
1136 }
1137 case VIDIOCSPICT:
1138 {
1139 struct video_picture p;
1140 if (copy_from_user(&p, arg,sizeof(p)))
1141 return -EFAULT;
1142 DEBUG(printk(CARD_DEBUG "VIDIOCSPICT(%d,%d,%d,%d,%d,%d,%d)\n",CARD,p.brightness,p.hue,p.colour,p.contrast,p.whiteness,p.depth,p.palette));
1143
1144 /* depth must match with framebuffer */
1145 if (p.depth != ztv->depth)
1146 return -EINVAL;
1147
1148 /* check if palette matches this bpp */
1149 if (p.palette>NRPALETTES ||
1150 palette2fmt[p.palette].bpp != ztv->overinfo.bpp)
1151 return -EINVAL;
1152
1153 write_lock_irq(&ztv->lock);
1154 ztv->overinfo.format = p.palette;
1155 ztv->picture = p;
1156 write_unlock_irq(&ztv->lock);
1157
1158 /* tell the decoder */
1159 i2c_control_device(&ztv->i2c, I2C_DRIVERID_VIDEODECODER, DECODER_SET_PICTURE, &p);
1160 break;
1161 }
1162
1163 case VIDIOCGWIN:
1164 {
1165 struct video_window vw;
1166 DEBUG(printk(CARD_DEBUG "VIDIOCGWIN\n",CARD));
1167 read_lock(&ztv->lock);
1168 vw.x = ztv->overinfo.x;
1169 vw.y = ztv->overinfo.y;
1170 vw.width = ztv->overinfo.w;
1171 vw.height = ztv->overinfo.h;
1172 vw.chromakey= 0;
1173 vw.flags = 0;
1174 if (ztv->vidInterlace)
1175 vw.flags|=VIDEO_WINDOW_INTERLACE;
1176 read_unlock(&ztv->lock);
1177 if (copy_to_user(arg,&vw,sizeof(vw)))
1178 return -EFAULT;
1179 break;
1180 }
1181 case VIDIOCSWIN:
1182 {
1183 struct video_window vw;
1184 struct video_clip *vcp;
1185 int on;
1186 if (copy_from_user(&vw,arg,sizeof(vw)))
1187 return -EFAULT;
1188 DEBUG(printk(CARD_DEBUG "VIDIOCSWIN(%d,%d,%d,%d,%x,%d)\n",CARD,vw.x,vw.y,vw.width,vw.height,vw.flags,vw.clipcount));
1189
1190 if (vw.flags)
1191 return -EINVAL;
1192
1193 if (vw.clipcount <0 || vw.clipcount>256)
1194 return -EDOM; /* Too many! */
1195
1196 /*
1197 * Do any clips.
1198 */
1199 vcp = vmalloc(sizeof(struct video_clip)*(vw.clipcount+4));
1200 if (vcp==NULL)
1201 return -ENOMEM;
1202 if (vw.clipcount && copy_from_user(vcp,vw.clips,sizeof(struct video_clip)*vw.clipcount)) {
1203 vfree(vcp);
1204 return -EFAULT;
1205 }
1206
1207 on = ztv->running;
1208 if (on)
1209 zoran_cap(ztv, 0);
1210
1211 /*
1212 * strange, it seems xawtv sometimes calls us with 0
1213 * width and/or height. Ignore these values
1214 */
1215 if (vw.x == 0)
1216 vw.x = ztv->overinfo.x;
1217 if (vw.y == 0)
1218 vw.y = ztv->overinfo.y;
1219
1220 /* by now we are committed to the new data... */
1221 write_lock_irq(&ztv->lock);
1222 ztv->overinfo.x = vw.x;
1223 ztv->overinfo.y = vw.y;
1224 ztv->overinfo.w = vw.width;
1225 ztv->overinfo.h = vw.height;
1226 write_unlock_irq(&ztv->lock);
1227
1228 /*
1229 * Impose display clips
1230 */
1231 if (vw.x+vw.width > ztv->swidth)
1232 new_clip(&vw, vcp, ztv->swidth-vw.x, 0, vw.width-1, vw.height-1);
1233 if (vw.y+vw.height > ztv->sheight)
1234 new_clip(&vw, vcp, 0, ztv->sheight-vw.y, vw.width-1, vw.height-1);
1235
1236 /* built the requested clipping zones */
1237 zoran_set_geo(ztv, &ztv->overinfo);
1238 zoran_built_overlay(ztv, vw.clipcount, vcp);
1239 vfree(vcp);
1240
1241 /* if we were on, restart the video engine */
1242 if (on)
1243 zoran_cap(ztv, 1);
1244 break;
1245 }
1246
1247 case VIDIOCCAPTURE:
1248 {
1249 int v;
1250 if (get_user(v, (int *)arg))
1251 return -EFAULT;
1252 DEBUG(printk(CARD_DEBUG "VIDIOCCAPTURE(%d)\n",CARD,v));
1253
1254 if (v==0) {
1255 clear_bit(STATE_OVERLAY, &ztv->state);
1256 zoran_cap(ztv, 1);
1257 }
1258 else {
1259 /* is VIDIOCSFBUF, VIDIOCSWIN done? */
1260 if (ztv->overinfo.busadr==0 || ztv->overinfo.w==0 || ztv->overinfo.h==0)
1261 return -EINVAL;
1262
1263 set_bit(STATE_OVERLAY, &ztv->state);
1264 zoran_cap(ztv, 1);
1265 }
1266 break;
1267 }
1268
1269 case VIDIOCGFBUF:
1270 {
1271 struct video_buffer v;
1272 DEBUG(printk(CARD_DEBUG "VIDIOCGFBUF\n",CARD));
1273 read_lock(&ztv->lock);
1274 v.base = (void *)ztv->overinfo.busadr;
1275 v.height = ztv->sheight;
1276 v.width = ztv->swidth;
1277 v.depth = ztv->depth;
1278 v.bytesperline = ztv->overinfo.bpl;
1279 read_unlock(&ztv->lock);
1280 if(copy_to_user(arg, &v,sizeof(v)))
1281 return -EFAULT;
1282 break;
1283 }
1284 case VIDIOCSFBUF:
1285 {
1286 struct video_buffer v;
1287 if(!capable(CAP_SYS_ADMIN))
1288 return -EPERM;
1289 if (copy_from_user(&v, arg,sizeof(v)))
1290 return -EFAULT;
1291 DEBUG(printk(CARD_DEBUG "VIDIOCSFBUF(%p,%d,%d,%d,%d)\n",CARD,v.base, v.width,v.height,v.depth,v.bytesperline));
1292
1293 if (v.depth!=15 && v.depth!=16 && v.depth!=24 && v.depth!=32)
1294 return -EINVAL;
1295 if (v.bytesperline<1)
1296 return -EINVAL;
1297 if (ztv->running)
1298 return -EBUSY;
1299 write_lock_irq(&ztv->lock);
1300 ztv->overinfo.busadr = (ulong)v.base;
1301 ztv->sheight = v.height;
1302 ztv->swidth = v.width;
1303 ztv->depth = v.depth; /* bits per pixel */
1304 ztv->overinfo.bpp = ((v.depth+1)&0x38)/8;/* bytes per pixel */
1305 ztv->overinfo.bpl = v.bytesperline; /* bytes per line */
1306 write_unlock_irq(&ztv->lock);
1307 break;
1308 }
1309
1310 case VIDIOCKEY:
1311 {
1312 /* Will be handled higher up .. */
1313 break;
1314 }
1315
1316 case VIDIOCSYNC:
1317 {
1318 int i;
1319 if (get_user(i, (int *) arg))
1320 return -EFAULT;
1321 DEBUG(printk(CARD_DEBUG "VIDEOCSYNC(%d)\n",CARD,i));
1322 if (i<0 || i>ZORAN_MAX_FBUFFERS)
1323 return -EINVAL;
1324 switch (ztv->grabinfo[i].status) {
1325 case FBUFFER_FREE:
1326 return -EINVAL;
1327 case FBUFFER_BUSY:
1328 /* wait till this buffer gets grabbed */
1329 wait_event_interruptible(ztv->grabq,
1330 (ztv->grabinfo[i].status != FBUFFER_BUSY));
1331 /* see if a signal did it */
1332 if (signal_pending(current))
1333 return -EINTR;
1334 /* don't fall through; a DONE buffer is not UNUSED */
1335 break;
1336 case FBUFFER_DONE:
1337 ztv->grabinfo[i].status = FBUFFER_FREE;
1338 /* tell ppl we have a spare buffer */
1339 wake_up_interruptible(&ztv->grabq);
1340 break;
1341 }
1342 DEBUG(printk(CARD_DEBUG "VIDEOCSYNC(%d) returns\n",CARD,i));
1343 break;
1344 }
1345
1346 case VIDIOCMCAPTURE:
1347 {
1348 struct video_mmap vm;
1349 struct vidinfo* frame;
1350 if (copy_from_user(&vm,arg,sizeof(vm)))
1351 return -EFAULT;
1352 DEBUG(printk(CARD_DEBUG "VIDIOCMCAPTURE(%d,(%d,%d),%d)\n",CARD,vm.frame,vm.width,vm.height,vm.format));
1353 if (vm.frame<0 || vm.frame>ZORAN_MAX_FBUFFERS ||
1354 vm.width<32 || vm.width>768 ||
1355 vm.height<32 || vm.height>576 ||
1356 vm.format>NRPALETTES ||
1357 palette2fmt[vm.format].mode == 0)
1358 return -EINVAL;
1359
1360 /* we are allowed to take over UNUSED and DONE buffers */
1361 frame = &ztv->grabinfo[vm.frame];
1362 if (frame->status == FBUFFER_BUSY)
1363 return -EBUSY;
1364
1365 /* setup the other parameters if they are given */
1366 write_lock_irq(&ztv->lock);
1367 frame->w = vm.width;
1368 frame->h = vm.height;
1369 frame->format = vm.format;
1370 frame->bpp = palette2fmt[frame->format].bpp;
1371 frame->bpl = frame->w*frame->bpp;
1372 frame->status = FBUFFER_BUSY;
1373 frame->next = 0;
1374 { /* add to tail of queue */
1375 struct vidinfo* oldframe = ztv->workqueue;
1376 if (!oldframe) ztv->workqueue = frame;
1377 else {
1378 while (oldframe->next) oldframe = oldframe->next;
1379 oldframe->next = frame;
1380 }
1381 }
1382 write_unlock_irq(&ztv->lock);
1383 zoran_cap(ztv, 1);
1384 break;
1385 }
1386
1387 case VIDIOCGMBUF:
1388 {
1389 struct video_mbuf mb;
1390 int i;
1391 DEBUG(printk(CARD_DEBUG "VIDIOCGMBUF\n",CARD));
1392 mb.size = ZORAN_MAX_FBUFSIZE;
1393 mb.frames = ZORAN_MAX_FBUFFERS;
1394 for (i=0; i<ZORAN_MAX_FBUFFERS; i++)
1395 mb.offsets[i] = i*ZORAN_MAX_FBUFFER;
1396 if(copy_to_user(arg, &mb,sizeof(mb)))
1397 return -EFAULT;
1398 break;
1399 }
1400
1401 case VIDIOCGUNIT:
1402 {
1403 struct video_unit vu;
1404 DEBUG(printk(CARD_DEBUG "VIDIOCGUNIT\n",CARD));
1405 vu.video = ztv->video_dev.minor;
1406 vu.vbi = ztv->vbi_dev.minor;
1407 vu.radio = VIDEO_NO_UNIT;
1408 vu.audio = VIDEO_NO_UNIT;
1409 vu.teletext = VIDEO_NO_UNIT;
1410 if(copy_to_user(arg, &vu,sizeof(vu)))
1411 return -EFAULT;
1412 break;
1413 }
1414
1415 case VIDIOCGFREQ:
1416 {
1417 unsigned long v = ztv->tuner_freq;
1418 if (copy_to_user(arg,&v,sizeof(v)))
1419 return -EFAULT;
1420 DEBUG(printk(CARD_DEBUG "VIDIOCGFREQ\n",CARD));
1421 break;
1422 }
1423 case VIDIOCSFREQ:
1424 {
1425 unsigned long v;
1426 if (copy_from_user(&v, arg, sizeof(v)))
1427 return -EFAULT;
1428 DEBUG(printk(CARD_DEBUG "VIDIOCSFREQ\n",CARD));
1429
1430 if (ztv->have_tuner) {
1431 int fixme = v;
1432 if (i2c_control_device(&(ztv->i2c), I2C_DRIVERID_TUNER, TUNER_SET_TVFREQ, &fixme) < 0)
1433 return -EAGAIN;
1434 }
1435 ztv->tuner_freq = v;
1436 break;
1437 }
1438
1439 /* Why isn't this in the API?
1440 * And why doesn't it take a buffer number?
1441 case BTTV_FIELDNR:
1442 {
1443 unsigned long v = ztv->lastfieldnr;
1444 if (copy_to_user(arg,&v,sizeof(v)))
1445 return -EFAULT;
1446 DEBUG(printk(CARD_DEBUG "BTTV_FIELDNR\n",CARD));
1447 break;
1448 }
1449 */
1450
1451 default:
1452 return -ENOIOCTLCMD;
1453 }
1454 return 0;
1455}
1456
1457static
1458int zoran_mmap(struct vm_area_struct *vma, struct video_device* dev, const char* adr, unsigned long size)
1459{
1460 struct zoran* ztv = (struct zoran*)dev;
1461 unsigned long start = (unsigned long)adr;
1462 unsigned long pos;
1463
1464 DEBUG(printk(CARD_DEBUG "zoran_mmap(0x%p,%ld)\n",CARD,adr,size));
1465
1466 /* sanity checks */
1467 if (size > ZORAN_MAX_FBUFSIZE || !ztv->fbuffer)
1468 return -EINVAL;
1469
1470 /* start mapping the whole shabang to user memory */
1471 pos = (unsigned long)ztv->fbuffer;
1472 while (size>0) {
1473 unsigned long pfn = virt_to_phys((void*)pos) >> PAGE_SHIFT;
1474 if (remap_pfn_range(vma, start, pfn, PAGE_SIZE, PAGE_SHARED))
1475 return -EAGAIN;
1476 start += PAGE_SIZE;
1477 pos += PAGE_SIZE;
1478 size -= PAGE_SIZE;
1479 }
1480 return 0;
1481}
1482
1483static struct video_device zr36120_template=
1484{
1485 .owner = THIS_MODULE,
1486 .name = "UNSET",
1487 .type = VID_TYPE_TUNER|VID_TYPE_CAPTURE|VID_TYPE_OVERLAY,
1488 .hardware = VID_HARDWARE_ZR36120,
1489 .open = zoran_open,
1490 .close = zoran_close,
1491 .read = zoran_read,
1492 .write = zoran_write,
1493 .poll = zoran_poll,
1494 .ioctl = zoran_ioctl,
1495 .mmap = zoran_mmap,
1496 .minor = -1,
1497};
1498
1499static
1500int vbi_open(struct video_device *dev, int flags)
1501{
1502 struct zoran *ztv = dev->priv;
1503 struct vidinfo* item;
1504
1505 DEBUG(printk(CARD_DEBUG "vbi_open(dev,%d)\n",CARD,flags));
1506
1507 /*
1508 * During VBI device open, we continiously grab VBI-like
1509 * data in the vbi buffer when we have nothing to do.
1510 * Only when there is an explicit request for VBI data
1511 * (read call) we /force/ a read.
1512 */
1513
1514 /* allocate buffers */
1515 for (item=ztv->readinfo; item!=ztv->readinfo+ZORAN_VBI_BUFFERS; item++)
1516 {
1517 item->status = FBUFFER_FREE;
1518
1519 /* alloc */
1520 if (!item->memadr) {
1521 item->memadr = bmalloc(ZORAN_VBI_BUFSIZE);
1522 if (!item->memadr) {
1523 /* could not get a buffer, bail out */
1524 while (item != ztv->readinfo) {
1525 item--;
1526 bfree(item->memadr, ZORAN_VBI_BUFSIZE);
1527 item->memadr = 0;
1528 item->busadr = 0;
1529 }
1530 return -ENOBUFS;
1531 }
1532 }
1533
1534 /* determine the DMAable address */
1535 item->busadr = virt_to_bus(item->memadr);
1536 }
1537
1538 /* do the common part of all open's */
1539 zoran_common_open(ztv, flags);
1540
1541 set_bit(STATE_VBI, &ztv->state);
1542 /* start read-ahead */
1543 zoran_cap(ztv, 1);
1544
1545 return 0;
1546}
1547
1548static
1549void vbi_close(struct video_device *dev)
1550{
1551 struct zoran *ztv = dev->priv;
1552 struct vidinfo* item;
1553
1554 DEBUG(printk(CARD_DEBUG "vbi_close(dev)\n",CARD));
1555
1556 /* driver specific closure */
1557 clear_bit(STATE_VBI, &ztv->state);
1558
1559 zoran_common_close(ztv);
1560
1561 /*
1562 * This is sucky but right now I can't find a good way to
1563 * be sure its safe to free the buffer. We wait 5-6 fields
1564 * which is more than sufficient to be sure.
1565 */
1566 msleep(100); /* Wait 1/10th of a second */
1567
1568 for (item=ztv->readinfo; item!=ztv->readinfo+ZORAN_VBI_BUFFERS; item++)
1569 {
1570 if (item->memadr)
1571 bfree(item->memadr, ZORAN_VBI_BUFSIZE);
1572 item->memadr = 0;
1573 }
1574
1575}
1576
1577/*
1578 * This read function could be used reentrant in a SMP situation.
1579 *
1580 * This is made possible by the spinlock which is kept till we
1581 * found and marked a buffer for our own use. The lock must
1582 * be released as soon as possible to prevent lock contention.
1583 */
1584static
1585long vbi_read(struct video_device* dev, char* buf, unsigned long count, int nonblock)
1586{
1587 struct zoran *ztv = dev->priv;
1588 unsigned long max;
1589 struct vidinfo* unused = 0;
1590 struct vidinfo* done = 0;
1591
1592 DEBUG(printk(CARD_DEBUG "vbi_read(0x%p,%ld,%d)\n",CARD,buf,count,nonblock));
1593
1594 /* find ourself a free or completed buffer */
1595 for (;;) {
1596 struct vidinfo* item;
1597
1598 write_lock_irq(&ztv->lock);
1599 for (item=ztv->readinfo; item!=ztv->readinfo+ZORAN_VBI_BUFFERS; item++) {
1600 if (!unused && item->status == FBUFFER_FREE)
1601 unused = item;
1602 if (!done && item->status == FBUFFER_DONE)
1603 done = item;
1604 }
1605 if (done || unused)
1606 break;
1607
1608 /* no more free buffers, wait for them. */
1609 write_unlock_irq(&ztv->lock);
1610 if (nonblock)
1611 return -EWOULDBLOCK;
1612 interruptible_sleep_on(&ztv->vbiq);
1613 if (signal_pending(current))
1614 return -EINTR;
1615 }
1616
1617 /* Do we have 'ready' data? */
1618 if (!done) {
1619 /* no? than this will take a while... */
1620 if (nonblock) {
1621 write_unlock_irq(&ztv->lock);
1622 return -EWOULDBLOCK;
1623 }
1624
1625 /* mark the unused buffer as wanted */
1626 unused->status = FBUFFER_BUSY;
1627 unused->next = 0;
1628 { /* add to tail of queue */
1629 struct vidinfo* oldframe = ztv->workqueue;
1630 if (!oldframe) ztv->workqueue = unused;
1631 else {
1632 while (oldframe->next) oldframe = oldframe->next;
1633 oldframe->next = unused;
1634 }
1635 }
1636 write_unlock_irq(&ztv->lock);
1637
1638 /* tell the state machine we want it filled /NOW/ */
1639 zoran_cap(ztv, 1);
1640
1641 /* wait till this buffer gets grabbed */
1642 wait_event_interruptible(ztv->vbiq,
1643 (unused->status != FBUFFER_BUSY));
1644 /* see if a signal did it */
1645 if (signal_pending(current))
1646 return -EINTR;
1647 done = unused;
1648 }
1649 else
1650 write_unlock_irq(&ztv->lock);
1651
1652 /* Yes! we got data! */
1653 max = done->bpl * -done->h;
1654 if (count > max)
1655 count = max;
1656
1657 /* check if the user gave us enough room to write the data */
1658 if (!access_ok(VERIFY_WRITE, buf, count)) {
1659 count = -EFAULT;
1660 goto out;
1661 }
1662
1663 /*
1664 * Now transform/strip the data from YUV to Y-only
1665 * NB. Assume the Y is in the LSB of the YUV data.
1666 */
1667 {
1668 unsigned char* optr = buf;
1669 unsigned char* eptr = buf+count;
1670
1671 /* are we beeing accessed from an old driver? */
1672 if (count == 2*19*2048) {
1673 /*
1674 * Extreme HACK, old VBI programs expect 2048 points
1675 * of data, and we only got 864 orso. Double each
1676 * datapoint and clear the rest of the line.
1677 * This way we have appear to have a
1678 * sample_frequency of 29.5 Mc.
1679 */
1680 int x,y;
1681 unsigned char* iptr = done->memadr+1;
1682 for (y=done->h; optr<eptr && y<0; y++)
1683 {
1684 /* copy to doubled data to userland */
1685 for (x=0; optr+1<eptr && x<-done->w; x++)
1686 {
1687 unsigned char a = iptr[x*2];
1688 __put_user(a, optr++);
1689 __put_user(a, optr++);
1690 }
1691 /* and clear the rest of the line */
1692 for (x*=2; optr<eptr && x<done->bpl; x++)
1693 __put_user(0, optr++);
1694 /* next line */
1695 iptr += done->bpl;
1696 }
1697 }
1698 else {
1699 /*
1700 * Other (probably newer) programs asked
1701 * us what geometry we are using, and are
1702 * reading the correct size.
1703 */
1704 int x,y;
1705 unsigned char* iptr = done->memadr+1;
1706 for (y=done->h; optr<eptr && y<0; y++)
1707 {
1708 /* copy to doubled data to userland */
1709 for (x=0; optr<eptr && x<-done->w; x++)
1710 __put_user(iptr[x*2], optr++);
1711 /* and clear the rest of the line */
1712 for (;optr<eptr && x<done->bpl; x++)
1713 __put_user(0, optr++);
1714 /* next line */
1715 iptr += done->bpl;
1716 }
1717 }
1718
1719 /* API compliance:
1720 * place the framenumber (half fieldnr) in the last long
1721 */
1722 __put_user(done->fieldnr/2, ((ulong*)eptr)[-1]);
1723 }
1724
1725 /* keep the engine running */
1726 done->status = FBUFFER_FREE;
1727 zoran_cap(ztv, 1);
1728
1729 /* tell listeners this buffer just became free */
1730 wake_up_interruptible(&ztv->vbiq);
1731
1732 /* goodbye */
1733out:
1734 DEBUG(printk(CARD_DEBUG "vbi_read() returns %lu\n",CARD,count));
1735 return count;
1736}
1737
1738static
1739unsigned int vbi_poll(struct video_device *dev, struct file *file, poll_table *wait)
1740{
1741 struct zoran *ztv = dev->priv;
1742 struct vidinfo* item;
1743 unsigned int mask = 0;
1744
1745 poll_wait(file, &ztv->vbiq, wait);
1746
1747 for (item=ztv->readinfo; item!=ztv->readinfo+ZORAN_VBI_BUFFERS; item++)
1748 if (item->status == FBUFFER_DONE)
1749 {
1750 mask |= (POLLIN | POLLRDNORM);
1751 break;
1752 }
1753
1754 DEBUG(printk(CARD_DEBUG "vbi_poll()=%x\n",CARD,mask));
1755
1756 return mask;
1757}
1758
1759static
1760int vbi_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
1761{
1762 struct zoran* ztv = dev->priv;
1763
1764 switch (cmd) {
1765 case VIDIOCGVBIFMT:
1766 {
1767 struct vbi_format f;
1768 DEBUG(printk(CARD_DEBUG "VIDIOCGVBIINFO\n",CARD));
1769 f.sampling_rate = 14750000UL;
1770 f.samples_per_line = -ztv->readinfo[0].w;
1771 f.sample_format = VIDEO_PALETTE_RAW;
1772 f.start[0] = f.start[1] = ztv->readinfo[0].y;
1773 f.start[1] += 312;
1774 f.count[0] = f.count[1] = -ztv->readinfo[0].h;
1775 f.flags = VBI_INTERLACED;
1776 if (copy_to_user(arg,&f,sizeof(f)))
1777 return -EFAULT;
1778 break;
1779 }
1780 case VIDIOCSVBIFMT:
1781 {
1782 struct vbi_format f;
1783 int i;
1784 if (copy_from_user(&f, arg,sizeof(f)))
1785 return -EFAULT;
1786 DEBUG(printk(CARD_DEBUG "VIDIOCSVBIINFO(%d,%d,%d,%d,%d,%d,%d,%x)\n",CARD,f.sampling_rate,f.samples_per_line,f.sample_format,f.start[0],f.start[1],f.count[0],f.count[1],f.flags));
1787
1788 /* lots of parameters are fixed... (PAL) */
1789 if (f.sampling_rate != 14750000UL ||
1790 f.samples_per_line > 864 ||
1791 f.sample_format != VIDEO_PALETTE_RAW ||
1792 f.start[0] < 0 ||
1793 f.start[0] != f.start[1]-312 ||
1794 f.count[0] != f.count[1] ||
1795 f.start[0]+f.count[0] >= 288 ||
1796 f.flags != VBI_INTERLACED)
1797 return -EINVAL;
1798
1799 write_lock_irq(&ztv->lock);
1800 ztv->readinfo[0].y = f.start[0];
1801 ztv->readinfo[0].w = -f.samples_per_line;
1802 ztv->readinfo[0].h = -f.count[0];
1803 ztv->readinfo[0].bpl = f.samples_per_line*ztv->readinfo[0].bpp;
1804 for (i=1; i<ZORAN_VBI_BUFFERS; i++)
1805 ztv->readinfo[i] = ztv->readinfo[i];
1806 write_unlock_irq(&ztv->lock);
1807 break;
1808 }
1809 default:
1810 return -ENOIOCTLCMD;
1811 }
1812 return 0;
1813}
1814
1815static struct video_device vbi_template=
1816{
1817 .owner = THIS_MODULE,
1818 .name = "UNSET",
1819 .type = VID_TYPE_CAPTURE|VID_TYPE_TELETEXT,
1820 .hardware = VID_HARDWARE_ZR36120,
1821 .open = vbi_open,
1822 .close = vbi_close,
1823 .read = vbi_read,
1824 .write = zoran_write,
1825 .poll = vbi_poll,
1826 .ioctl = vbi_ioctl,
1827 .minor = -1,
1828};
1829
1830/*
1831 * Scan for a Zoran chip, request the irq and map the io memory
1832 */
1833static
1834int __init find_zoran(void)
1835{
1836 int result;
1837 struct zoran *ztv;
1838 struct pci_dev *dev = NULL;
1839 unsigned char revision;
1840 int zoran_num=0;
1841
1842 while ((dev = pci_find_device(PCI_VENDOR_ID_ZORAN,PCI_DEVICE_ID_ZORAN_36120, dev)))
1843 {
1844 /* Ok, a ZR36120/ZR36125 found! */
1845 ztv = &zorans[zoran_num];
1846 ztv->dev = dev;
1847
1848 if (pci_enable_device(dev))
1849 return -EIO;
1850
1851 pci_read_config_byte(dev, PCI_CLASS_REVISION, &revision);
1852 printk(KERN_INFO "zoran: Zoran %x (rev %d) ",
1853 dev->device, revision);
1854 printk("bus: %d, devfn: %d, irq: %d, ",
1855 dev->bus->number, dev->devfn, dev->irq);
1856 printk("memory: 0x%08lx.\n", ztv->zoran_adr);
1857
1858 ztv->zoran_mem = ioremap(ztv->zoran_adr, 0x1000);
1859 DEBUG(printk(KERN_DEBUG "zoran: mapped-memory at 0x%p\n",ztv->zoran_mem));
1860
1861 result = request_irq(dev->irq, zoran_irq,
1862 SA_SHIRQ|SA_INTERRUPT,"zoran", ztv);
1863 if (result==-EINVAL)
1864 {
1865 iounmap(ztv->zoran_mem);
1866 printk(KERN_ERR "zoran: Bad irq number or handler\n");
1867 return -EINVAL;
1868 }
1869 if (result==-EBUSY)
1870 printk(KERN_ERR "zoran: IRQ %d busy, change your PnP config in BIOS\n",dev->irq);
1871 if (result < 0) {
1872 iounmap(ztv->zoran_mem);
1873 return result;
1874 }
1875 /* Enable bus-mastering */
1876 pci_set_master(dev);
1877
1878 zoran_num++;
1879 }
1880 if(zoran_num)
1881 printk(KERN_INFO "zoran: %d Zoran card(s) found.\n",zoran_num);
1882 return zoran_num;
1883}
1884
1885static
1886int __init init_zoran(int card)
1887{
1888 struct zoran *ztv = &zorans[card];
1889 int i;
1890
1891 /* if the given cardtype valid? */
1892 if (cardtype[card]>=NRTVCARDS) {
1893 printk(KERN_INFO "invalid cardtype(%d) detected\n",cardtype[card]);
1894 return -1;
1895 }
1896
1897 /* reset the zoran */
1898 zrand(~ZORAN_PCI_SOFTRESET,ZORAN_PCI);
1899 udelay(10);
1900 zror(ZORAN_PCI_SOFTRESET,ZORAN_PCI);
1901 udelay(10);
1902
1903 /* zoran chip specific details */
1904 ztv->card = tvcards+cardtype[card]; /* point to the selected card */
1905 ztv->norm = 0; /* PAL */
1906 ztv->tuner_freq = 0;
1907
1908 /* videocard details */
1909 ztv->swidth = 800;
1910 ztv->sheight = 600;
1911 ztv->depth = 16;
1912
1913 /* State details */
1914 ztv->fbuffer = 0;
1915 ztv->overinfo.kindof = FBUFFER_OVERLAY;
1916 ztv->overinfo.status = FBUFFER_FREE;
1917 ztv->overinfo.x = 0;
1918 ztv->overinfo.y = 0;
1919 ztv->overinfo.w = 768; /* 640 */
1920 ztv->overinfo.h = 576; /* 480 */
1921 ztv->overinfo.format = VIDEO_PALETTE_RGB565;
1922 ztv->overinfo.bpp = palette2fmt[ztv->overinfo.format].bpp;
1923 ztv->overinfo.bpl = ztv->overinfo.bpp*ztv->swidth;
1924 ztv->overinfo.busadr = 0;
1925 ztv->overinfo.memadr = 0;
1926 ztv->overinfo.overlay = 0;
1927 for (i=0; i<ZORAN_MAX_FBUFFERS; i++) {
1928 ztv->grabinfo[i] = ztv->overinfo;
1929 ztv->grabinfo[i].kindof = FBUFFER_GRAB;
1930 }
1931 init_waitqueue_head(&ztv->grabq);
1932
1933 /* VBI details */
1934 ztv->readinfo[0] = ztv->overinfo;
1935 ztv->readinfo[0].kindof = FBUFFER_VBI;
1936 ztv->readinfo[0].w = -864;
1937 ztv->readinfo[0].h = -38;
1938 ztv->readinfo[0].format = VIDEO_PALETTE_YUV422;
1939 ztv->readinfo[0].bpp = palette2fmt[ztv->readinfo[0].format].bpp;
1940 ztv->readinfo[0].bpl = 1024*ztv->readinfo[0].bpp;
1941 for (i=1; i<ZORAN_VBI_BUFFERS; i++)
1942 ztv->readinfo[i] = ztv->readinfo[0];
1943 init_waitqueue_head(&ztv->vbiq);
1944
1945 /* maintenance data */
1946 ztv->have_decoder = 0;
1947 ztv->have_tuner = 0;
1948 ztv->tuner_type = 0;
1949 ztv->running = 0;
1950 ztv->users = 0;
1951 rwlock_init(&ztv->lock);
1952 ztv->workqueue = 0;
1953 ztv->fieldnr = 0;
1954 ztv->lastfieldnr = 0;
1955
1956 if (triton1)
1957 zrand(~ZORAN_VDC_TRICOM, ZORAN_VDC);
1958
1959 /* external FL determines TOP frame */
1960 zror(ZORAN_VFEC_EXTFL, ZORAN_VFEC);
1961
1962 /* set HSpol */
1963 if (ztv->card->hsync_pos)
1964 zrwrite(ZORAN_VFEH_HSPOL, ZORAN_VFEH);
1965 /* set VSpol */
1966 if (ztv->card->vsync_pos)
1967 zrwrite(ZORAN_VFEV_VSPOL, ZORAN_VFEV);
1968
1969 /* Set the proper General Purpuse register bits */
1970 /* implicit: no softreset, 0 waitstates */
1971 zrwrite(ZORAN_PCI_SOFTRESET|(ztv->card->gpdir<<0),ZORAN_PCI);
1972 /* implicit: 3 duration and recovery PCI clocks on guest 0-3 */
1973 zrwrite(ztv->card->gpval<<24,ZORAN_GUEST);
1974
1975 /* clear interrupt status */
1976 zrwrite(~0, ZORAN_ISR);
1977
1978 /*
1979 * i2c template
1980 */
1981 ztv->i2c = zoran_i2c_bus_template;
1982 sprintf(ztv->i2c.name,"zoran-%d",card);
1983 ztv->i2c.data = ztv;
1984
1985 /*
1986 * Now add the template and register the device unit
1987 */
1988 ztv->video_dev = zr36120_template;
1989 strcpy(ztv->video_dev.name, ztv->i2c.name);
1990 ztv->video_dev.priv = ztv;
1991 if (video_register_device(&ztv->video_dev, VFL_TYPE_GRABBER, video_nr) < 0)
1992 return -1;
1993
1994 ztv->vbi_dev = vbi_template;
1995 strcpy(ztv->vbi_dev.name, ztv->i2c.name);
1996 ztv->vbi_dev.priv = ztv;
1997 if (video_register_device(&ztv->vbi_dev, VFL_TYPE_VBI, vbi_nr) < 0) {
1998 video_unregister_device(&ztv->video_dev);
1999 return -1;
2000 }
2001 i2c_register_bus(&ztv->i2c);
2002
2003 /* set interrupt mask - the PIN enable will be set later */
2004 zrwrite(ZORAN_ICR_GIRQ0|ZORAN_ICR_GIRQ1|ZORAN_ICR_CODE, ZORAN_ICR);
2005
2006 printk(KERN_INFO "%s: installed %s\n",ztv->i2c.name,ztv->card->name);
2007 return 0;
2008}
2009
2010static
2011void release_zoran(int max)
2012{
2013 struct zoran *ztv;
2014 int i;
2015
2016 for (i=0;i<max; i++)
2017 {
2018 ztv = &zorans[i];
2019
2020 /* turn off all capturing, DMA and IRQs */
2021 /* reset the zoran */
2022 zrand(~ZORAN_PCI_SOFTRESET,ZORAN_PCI);
2023 udelay(10);
2024 zror(ZORAN_PCI_SOFTRESET,ZORAN_PCI);
2025 udelay(10);
2026
2027 /* first disable interrupts before unmapping the memory! */
2028 zrwrite(0, ZORAN_ICR);
2029 zrwrite(0xffffffffUL,ZORAN_ISR);
2030
2031 /* free it */
2032 free_irq(ztv->dev->irq,ztv);
2033
2034 /* unregister i2c_bus */
2035 i2c_unregister_bus((&ztv->i2c));
2036
2037 /* unmap and free memory */
2038 if (ztv->zoran_mem)
2039 iounmap(ztv->zoran_mem);
2040
2041 video_unregister_device(&ztv->video_dev);
2042 video_unregister_device(&ztv->vbi_dev);
2043 }
2044}
2045
2046void __exit zr36120_exit(void)
2047{
2048 release_zoran(zoran_cards);
2049}
2050
2051int __init zr36120_init(void)
2052{
2053 int card;
2054
2055 handle_chipset();
2056 zoran_cards = find_zoran();
2057 if (zoran_cards<0)
2058 /* no cards found, no need for a driver */
2059 return -EIO;
2060
2061 /* initialize Zorans */
2062 for (card=0; card<zoran_cards; card++) {
2063 if (init_zoran(card)<0) {
2064 /* only release the zorans we have registered */
2065 release_zoran(card);
2066 return -EIO;
2067 }
2068 }
2069 return 0;
2070}
2071
2072module_init(zr36120_init);
2073module_exit(zr36120_exit);
diff --git a/drivers/media/video/zr36120.h b/drivers/media/video/zr36120.h
new file mode 100644
index 00000000000..571f8e84b58
--- /dev/null
+++ b/drivers/media/video/zr36120.h
@@ -0,0 +1,279 @@
1/*
2 zr36120.h - Zoran 36120/36125 based framegrabbers
3
4 Copyright (C) 1998-1999 Pauline Middelink (middelin@polyware.nl)
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19*/
20
21#ifndef _ZR36120_H
22#define _ZR36120_H
23
24#ifdef __KERNEL__
25
26#include <linux/types.h>
27#include <linux/wait.h>
28
29#include <linux/i2c-old.h>
30#include <linux/videodev.h>
31
32#include <asm/io.h>
33
34/*
35 * Debug macro's, place an x behind the ) for actual debug-compilation
36 * E.g. #define DEBUG(x...) x
37 */
38#define DEBUG(x...) /* Debug driver */
39#define IDEBUG(x...) /* Debug interrupt handler */
40#define PDEBUG 0 /* Debug PCI writes */
41
42/* defined in zr36120_i2c */
43extern struct i2c_bus zoran_i2c_bus_template;
44
45#define ZORAN_MAX_FBUFFERS 2
46#define ZORAN_MAX_FBUFFER (768*576*2)
47#define ZORAN_MAX_FBUFSIZE (ZORAN_MAX_FBUFFERS*ZORAN_MAX_FBUFFER)
48
49#define ZORAN_VBI_BUFFERS 2
50#define ZORAN_VBI_BUFSIZE (22*1024*2)
51
52struct tvcard {
53 char* name; /* name of the cardtype */
54 int video_inputs; /* number of channels defined in video_mux */
55 int audio_inputs; /* number of channels defined in audio_mux */
56 __u32 swapi2c:1, /* need to swap i2c wires SDA/SCL? */
57 usegirq1:1, /* VSYNC at GIRQ1 instead of GIRQ0? */
58 vsync_pos:1, /* positive VSYNC signal? */
59 hsync_pos:1, /* positive HSYNC signal? */
60 gpdir:8, /* General Purpose Direction register */
61 gpval:8; /* General Purpose Value register */
62 int video_mux[6]; /* mapping channel number to physical input */
63#define IS_TUNER 0x80
64#define IS_SVHS 0x40
65#define CHANNEL_MASK 0x3F
66 int audio_mux[6]; /* mapping channel number to physical input */
67};
68#define TUNER(x) ((x)|IS_TUNER)
69#define SVHS(x) ((x)|IS_SVHS)
70
71struct vidinfo {
72 struct vidinfo* next; /* next active buffer */
73 uint kindof;
74#define FBUFFER_OVERLAY 0
75#define FBUFFER_GRAB 1
76#define FBUFFER_VBI 2
77 uint status;
78#define FBUFFER_FREE 0
79#define FBUFFER_BUSY 1
80#define FBUFFER_DONE 2
81 ulong fieldnr; /* # of field, not framer! */
82 uint x,y;
83 int w,h; /* w,h can be negative! */
84 uint format; /* index in palette2fmt[] */
85 uint bpp; /* lookup from palette2fmt[] */
86 uint bpl; /* calc: width * bpp */
87 ulong busadr; /* bus addr for DMA engine */
88 char* memadr; /* kernel addr for making copies */
89 ulong* overlay; /* kernel addr of overlay mask */
90};
91
92struct zoran
93{
94 struct video_device video_dev;
95#define CARD_DEBUG KERN_DEBUG "%s(%lu): "
96#define CARD_INFO KERN_INFO "%s(%lu): "
97#define CARD_ERR KERN_ERR "%s(%lu): "
98#define CARD ztv->video_dev.name,ztv->fieldnr
99
100 /* zoran chip specific details */
101 struct i2c_bus i2c; /* i2c registration data */
102 struct pci_dev* dev; /* ptr to PCI device */
103 ulong zoran_adr; /* bus address of IO memory */
104 char* zoran_mem; /* kernel address of IO memory */
105 struct tvcard* card; /* the cardtype */
106 uint norm; /* 0=PAL, 1=NTSC, 2=SECAM */
107 uint tuner_freq; /* Current freq in kHz */
108 struct video_picture picture; /* Current picture params */
109
110 /* videocard details */
111 uint swidth; /* screen width */
112 uint sheight; /* screen height */
113 uint depth; /* depth in bits */
114
115 /* State details */
116 char* fbuffer; /* framebuffers for mmap */
117 struct vidinfo overinfo; /* overlay data */
118 struct vidinfo grabinfo[ZORAN_MAX_FBUFFERS]; /* grabbing data*/
119 wait_queue_head_t grabq; /* grabbers queue */
120
121 /* VBI details */
122 struct video_device vbi_dev;
123 struct vidinfo readinfo[2]; /* VBI data - flip buffers */
124 wait_queue_head_t vbiq; /* vbi queue */
125
126 /* maintenance data */
127 int have_decoder; /* did we detect a mux? */
128 int have_tuner; /* did we detect a tuner? */
129 int users; /* howmany video/vbi open? */
130 int tuner_type; /* tuner type, when found */
131 int running; /* are we rolling? */
132 rwlock_t lock;
133 long state; /* what is requested of us? */
134#define STATE_OVERLAY 0
135#define STATE_VBI 1
136 struct vidinfo* workqueue; /* buffers to grab, head is active */
137 ulong fieldnr; /* #field, ticked every VSYNC */
138 ulong lastfieldnr; /* #field, ticked every GRAB */
139
140 int vidInterlace; /* calculated */
141 int vidXshift; /* calculated */
142 uint vidWidth; /* calculated */
143 uint vidHeight; /* calculated */
144};
145
146#define zrwrite(dat,adr) writel((dat),(char *) (ztv->zoran_mem+(adr)))
147#define zrread(adr) readl(ztv->zoran_mem+(adr))
148
149#if PDEBUG == 0
150#define zrand(dat,adr) zrwrite((dat) & zrread(adr), adr)
151#define zror(dat,adr) zrwrite((dat) | zrread(adr), adr)
152#define zraor(dat,mask,adr) zrwrite( ((dat)&~(mask)) | ((mask)&zrread(adr)), adr)
153#else
154#define zrand(dat, adr) \
155do { \
156 ulong data = (dat) & zrread((adr)); \
157 zrwrite(data, (adr)); \
158 if (0 != (~(dat) & zrread((adr)))) \
159 printk(KERN_DEBUG "zoran: zrand at %d(%d) detected set bits(%x)\n", __LINE__, (adr), (dat)); \
160} while(0)
161
162#define zror(dat, adr) \
163do { \
164 ulong data = (dat) | zrread((adr)); \
165 zrwrite(data, (adr)); \
166 if ((dat) != ((dat) & zrread(adr))) \
167 printk(KERN_DEBUG "zoran: zror at %d(%d) detected unset bits(%x)\n", __LINE__, (adr), (dat)); \
168} while(0)
169
170#define zraor(dat, mask, adr) \
171do { \
172 ulong data; \
173 if ((dat) & (mask)) \
174 printk(KERN_DEBUG "zoran: zraor at %d(%d) detected bits(%x:%x)\n", __LINE__, (adr), (dat), (mask)); \
175 data = ((dat)&~(mask)) | ((mask) & zrread((adr))); \
176 zrwrite(data,(adr)); \
177 if ( (dat) != (~(mask) & zrread((adr))) ) \
178 printk(KERN_DEBUG "zoran: zraor at %d(%d) could not set all bits(%x:%x)\n", __LINE__, (adr), (dat), (mask)); \
179} while(0)
180#endif
181
182#endif
183
184/* zoran PCI address space */
185#define ZORAN_VFEH 0x000 /* Video Front End Horizontal Conf. */
186#define ZORAN_VFEH_HSPOL (1<<30)
187#define ZORAN_VFEH_HSTART (0x3FF<<10)
188#define ZORAN_VFEH_HEND (0x3FF<<0)
189
190#define ZORAN_VFEV 0x004 /* Video Front End Vertical Conf. */
191#define ZORAN_VFEV_VSPOL (1<<30)
192#define ZORAN_VFEV_VSTART (0x3FF<<10)
193#define ZORAN_VFEV_VEND (0x3FF<<0)
194
195#define ZORAN_VFEC 0x008 /* Video Front End Scaler and Pixel */
196#define ZORAN_VFEC_EXTFL (1<<26)
197#define ZORAN_VFEC_TOPFIELD (1<<25)
198#define ZORAN_VFEC_VCLKPOL (1<<24)
199#define ZORAN_VFEC_HFILTER (7<<21)
200#define ZORAN_VFEC_HFILTER_1 (0<<21) /* no lumi, 3-tap chromo */
201#define ZORAN_VFEC_HFILTER_2 (1<<21) /* 3-tap lumi, 3-tap chromo */
202#define ZORAN_VFEC_HFILTER_3 (2<<21) /* 4-tap lumi, 4-tap chromo */
203#define ZORAN_VFEC_HFILTER_4 (3<<21) /* 5-tap lumi, 4-tap chromo */
204#define ZORAN_VFEC_HFILTER_5 (4<<21) /* 4-tap lumi, 4-tap chromo */
205#define ZORAN_VFEC_DUPFLD (1<<20)
206#define ZORAN_VFEC_HORDCM (63<<14)
207#define ZORAN_VFEC_VERDCM (63<<8)
208#define ZORAN_VFEC_DISPMOD (1<<6)
209#define ZORAN_VFEC_RGB (3<<3)
210#define ZORAN_VFEC_RGB_YUV422 (0<<3)
211#define ZORAN_VFEC_RGB_RGB888 (1<<3)
212#define ZORAN_VFEC_RGB_RGB565 (2<<3)
213#define ZORAN_VFEC_RGB_RGB555 (3<<3)
214#define ZORAN_VFEC_ERRDIF (1<<2)
215#define ZORAN_VFEC_PACK24 (1<<1)
216#define ZORAN_VFEC_LE (1<<0)
217
218#define ZORAN_VTOP 0x00C /* Video Display "Top" */
219
220#define ZORAN_VBOT 0x010 /* Video Display "Bottom" */
221
222#define ZORAN_VSTR 0x014 /* Video Display Stride */
223#define ZORAN_VSTR_DISPSTRIDE (0xFFFF<<16)
224#define ZORAN_VSTR_VIDOVF (1<<8)
225#define ZORAN_VSTR_SNAPSHOT (1<<1)
226#define ZORAN_VSTR_GRAB (1<<0)
227
228#define ZORAN_VDC 0x018 /* Video Display Conf. */
229#define ZORAN_VDC_VIDEN (1<<31)
230#define ZORAN_VDC_MINPIX (0x1F<<25)
231#define ZORAN_VDC_TRICOM (1<<24)
232#define ZORAN_VDC_VIDWINHT (0x3FF<<12)
233#define ZORAN_VDC_VIDWINWID (0x3FF<<0)
234
235#define ZORAN_MTOP 0x01C /* Masking Map "Top" */
236
237#define ZORAN_MBOT 0x020 /* Masking Map "Bottom" */
238
239#define ZORAN_OCR 0x024 /* Overlay Control */
240#define ZORAN_OCR_OVLEN (1<<15)
241#define ZORAN_OCR_MASKSTRIDE (0xFF<<0)
242
243#define ZORAN_PCI 0x028 /* System, PCI and GPP Control */
244#define ZORAN_PCI_SOFTRESET (1<<24)
245#define ZORAN_PCI_WAITSTATE (3<<16)
246#define ZORAN_PCI_GENPURDIR (0xFF<<0)
247
248#define ZORAN_GUEST 0x02C /* GuestBus Control */
249
250#define ZORAN_CSOURCE 0x030 /* Code Source Address */
251
252#define ZORAN_CTRANS 0x034 /* Code Transfer Control */
253
254#define ZORAN_CMEM 0x038 /* Code Memory Pointer */
255
256#define ZORAN_ISR 0x03C /* Interrupt Status Register */
257#define ZORAN_ISR_CODE (1<<28)
258#define ZORAN_ISR_GIRQ0 (1<<29)
259#define ZORAN_ISR_GIRQ1 (1<<30)
260
261#define ZORAN_ICR 0x040 /* Interrupt Control Register */
262#define ZORAN_ICR_EN (1<<24)
263#define ZORAN_ICR_CODE (1<<28)
264#define ZORAN_ICR_GIRQ0 (1<<29)
265#define ZORAN_ICR_GIRQ1 (1<<30)
266
267#define ZORAN_I2C 0x044 /* I2C-Bus */
268#define ZORAN_I2C_SCL (1<<1)
269#define ZORAN_I2C_SDA (1<<0)
270
271#define ZORAN_POST 0x48 /* PostOffice */
272#define ZORAN_POST_PEN (1<<25)
273#define ZORAN_POST_TIME (1<<24)
274#define ZORAN_POST_DIR (1<<23)
275#define ZORAN_POST_GUESTID (3<<20)
276#define ZORAN_POST_GUEST (7<<16)
277#define ZORAN_POST_DATA (0xFF<<0)
278
279#endif
diff --git a/drivers/media/video/zr36120_i2c.c b/drivers/media/video/zr36120_i2c.c
new file mode 100644
index 00000000000..6bfe84d657f
--- /dev/null
+++ b/drivers/media/video/zr36120_i2c.c
@@ -0,0 +1,132 @@
1/*
2 zr36120_i2c.c - Zoran 36120/36125 based framegrabbers
3
4 Copyright (C) 1998-1999 Pauline Middelink <middelin@polyware.nl>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19*/
20
21#include <linux/types.h>
22#include <linux/delay.h>
23#include <asm/io.h>
24
25#include <linux/video_decoder.h>
26#include <asm/uaccess.h>
27
28#include "tuner.h"
29#include "zr36120.h"
30
31/* ----------------------------------------------------------------------- */
32/* I2C functions */
33/* ----------------------------------------------------------------------- */
34
35/* software I2C functions */
36
37#define I2C_DELAY 10
38
39static void i2c_setlines(struct i2c_bus *bus,int ctrl,int data)
40{
41 struct zoran *ztv = (struct zoran*)bus->data;
42 unsigned int b = 0;
43 if (data) b |= ztv->card->swapi2c ? ZORAN_I2C_SCL : ZORAN_I2C_SDA;
44 if (ctrl) b |= ztv->card->swapi2c ? ZORAN_I2C_SDA : ZORAN_I2C_SCL;
45 zrwrite(b, ZORAN_I2C);
46 udelay(I2C_DELAY);
47}
48
49static int i2c_getdataline(struct i2c_bus *bus)
50{
51 struct zoran *ztv = (struct zoran*)bus->data;
52 if (ztv->card->swapi2c)
53 return zrread(ZORAN_I2C) & ZORAN_I2C_SCL;
54 return zrread(ZORAN_I2C) & ZORAN_I2C_SDA;
55}
56
57static
58void attach_inform(struct i2c_bus *bus, int id)
59{
60 struct zoran *ztv = (struct zoran*)bus->data;
61 struct video_decoder_capability dc;
62 int rv;
63
64 switch (id) {
65 case I2C_DRIVERID_VIDEODECODER:
66 DEBUG(printk(CARD_INFO "decoder attached\n",CARD));
67
68 /* fetch the capabilites of the decoder */
69 rv = i2c_control_device(&ztv->i2c, I2C_DRIVERID_VIDEODECODER, DECODER_GET_CAPABILITIES, &dc);
70 if (rv) {
71 DEBUG(printk(CARD_DEBUG "decoder is not V4L aware!\n",CARD));
72 break;
73 }
74 DEBUG(printk(CARD_DEBUG "capabilities %d %d %d\n",CARD,dc.flags,dc.inputs,dc.outputs));
75
76 /* Test if the decoder can de VBI transfers */
77 if (dc.flags & 16 /*VIDEO_DECODER_VBI*/)
78 ztv->have_decoder = 2;
79 else
80 ztv->have_decoder = 1;
81 break;
82 case I2C_DRIVERID_TUNER:
83 ztv->have_tuner = 1;
84 DEBUG(printk(CARD_INFO "tuner attached\n",CARD));
85 if (ztv->tuner_type >= 0)
86 {
87 if (i2c_control_device(&ztv->i2c,I2C_DRIVERID_TUNER,TUNER_SET_TYPE,&ztv->tuner_type)<0)
88 DEBUG(printk(CARD_INFO "attach_inform; tuner won't be set to type %d\n",CARD,ztv->tuner_type));
89 }
90 break;
91 default:
92 DEBUG(printk(CARD_INFO "attach_inform; unknown device id=%d\n",CARD,id));
93 break;
94 }
95}
96
97static
98void detach_inform(struct i2c_bus *bus, int id)
99{
100 struct zoran *ztv = (struct zoran*)bus->data;
101
102 switch (id) {
103 case I2C_DRIVERID_VIDEODECODER:
104 ztv->have_decoder = 0;
105 DEBUG(printk(CARD_INFO "decoder detached\n",CARD));
106 break;
107 case I2C_DRIVERID_TUNER:
108 ztv->have_tuner = 0;
109 DEBUG(printk(CARD_INFO "tuner detached\n",CARD));
110 break;
111 default:
112 DEBUG(printk(CARD_INFO "detach_inform; unknown device id=%d\n",CARD,id));
113 break;
114 }
115}
116
117struct i2c_bus zoran_i2c_bus_template =
118{
119 "ZR36120",
120 I2C_BUSID_ZORAN,
121 NULL,
122
123 SPIN_LOCK_UNLOCKED,
124
125 attach_inform,
126 detach_inform,
127
128 i2c_setlines,
129 i2c_getdataline,
130 NULL,
131 NULL
132};
diff --git a/drivers/media/video/zr36120_mem.c b/drivers/media/video/zr36120_mem.c
new file mode 100644
index 00000000000..c87113d6cc6
--- /dev/null
+++ b/drivers/media/video/zr36120_mem.c
@@ -0,0 +1,79 @@
1/*
2 zr36120_mem.c - Zoran 36120/36125 based framegrabbers
3
4 Copyright (C) 1998-1999 Pauline Middelink <middelin@polyware.nl>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19*/
20
21#include <linux/config.h>
22#include <linux/mm.h>
23#include <linux/pci.h>
24#include <linux/slab.h>
25#include <linux/module.h>
26#include <asm/io.h>
27#ifdef CONFIG_BIGPHYS_AREA
28#include <linux/bigphysarea.h>
29#endif
30
31#include "zr36120.h"
32#include "zr36120_mem.h"
33
34/*******************************/
35/* Memory management functions */
36/*******************************/
37
38void* bmalloc(unsigned long size)
39{
40 void* mem;
41#ifdef CONFIG_BIGPHYS_AREA
42 mem = bigphysarea_alloc_pages(size/PAGE_SIZE, 1, GFP_KERNEL);
43#else
44 /*
45 * The following function got a lot of memory at boottime,
46 * so we know its always there...
47 */
48 mem = (void*)__get_free_pages(GFP_USER|GFP_DMA,get_order(size));
49#endif
50 if (mem) {
51 unsigned long adr = (unsigned long)mem;
52 while (size > 0) {
53 SetPageReserved(virt_to_page(phys_to_virt(adr)));
54 adr += PAGE_SIZE;
55 size -= PAGE_SIZE;
56 }
57 }
58 return mem;
59}
60
61void bfree(void* mem, unsigned long size)
62{
63 if (mem) {
64 unsigned long adr = (unsigned long)mem;
65 unsigned long siz = size;
66 while (siz > 0) {
67 ClearPageReserved(virt_to_page(phys_to_virt(adr)));
68 adr += PAGE_SIZE;
69 siz -= PAGE_SIZE;
70 }
71#ifdef CONFIG_BIGPHYS_AREA
72 bigphysarea_free_pages(mem);
73#else
74 free_pages((unsigned long)mem,get_order(size));
75#endif
76 }
77}
78
79MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/zr36120_mem.h b/drivers/media/video/zr36120_mem.h
new file mode 100644
index 00000000000..aad117acc91
--- /dev/null
+++ b/drivers/media/video/zr36120_mem.h
@@ -0,0 +1,3 @@
1/* either kmalloc() or bigphysarea() alloced memory - continuous */
2void* bmalloc(unsigned long size);
3void bfree(void* mem, unsigned long size);