]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/blame - drivers/media/video/bttv-driver.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland...
[mirror_ubuntu-hirsute-kernel.git] / drivers / media / video / bttv-driver.c
CommitLineData
1da177e4 1/*
1da177e4
LT
2
3 bttv - Bt848 frame grabber driver
4
5 Copyright (C) 1996,97,98 Ralph Metzler <rjkm@thp.uni-koeln.de>
4ac97914 6 & Marcus Metzler <mocm@thp.uni-koeln.de>
1da177e4
LT
7 (c) 1999-2002 Gerd Knorr <kraxel@bytesex.org>
8
9 some v4l2 code lines are taken from Justin's bttv2 driver which is
10 (c) 2000 Justin Schoeman <justin@suntiger.ee.up.ac.za>
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/init.h>
28#include <linux/module.h>
29#include <linux/moduleparam.h>
30#include <linux/delay.h>
31#include <linux/errno.h>
32#include <linux/fs.h>
33#include <linux/kernel.h>
34#include <linux/sched.h>
35#include <linux/interrupt.h>
36#include <linux/kdev_t.h>
fa9846a8 37#include <linux/dma-mapping.h>
1da177e4
LT
38
39#include <asm/io.h>
40#include <asm/byteorder.h>
41
42#include "bttvp.h"
43
24a70fdc
MCC
44#include "rds.h"
45
46
1da177e4
LT
47unsigned int bttv_num; /* number of Bt848s in use */
48struct bttv bttvs[BTTV_MAX];
49
50unsigned int bttv_debug = 0;
51unsigned int bttv_verbose = 1;
52unsigned int bttv_gpio = 0;
53
54/* config variables */
55#ifdef __BIG_ENDIAN
56static unsigned int bigendian=1;
57#else
58static unsigned int bigendian=0;
59#endif
60static unsigned int radio[BTTV_MAX];
61static unsigned int irq_debug = 0;
62static unsigned int gbuffers = 8;
63static unsigned int gbufsize = 0x208000;
64
65static int video_nr = -1;
66static int radio_nr = -1;
67static int vbi_nr = -1;
68static int debug_latency = 0;
69
70static unsigned int fdsr = 0;
71
72/* options */
73static unsigned int combfilter = 0;
74static unsigned int lumafilter = 0;
75static unsigned int automute = 1;
76static unsigned int chroma_agc = 0;
77static unsigned int adc_crush = 1;
78static unsigned int whitecrush_upper = 0xCF;
79static unsigned int whitecrush_lower = 0x7F;
80static unsigned int vcr_hack = 0;
81static unsigned int irq_iswitch = 0;
060d3027
MCC
82static unsigned int uv_ratio = 50;
83static unsigned int full_luma_range = 0;
84static unsigned int coring = 0;
4dcef524 85extern int no_overlay;
1da177e4
LT
86
87/* API features (turn on/off stuff for testing) */
88static unsigned int v4l2 = 1;
89
90
91/* insmod args */
92module_param(bttv_verbose, int, 0644);
93module_param(bttv_gpio, int, 0644);
94module_param(bttv_debug, int, 0644);
95module_param(irq_debug, int, 0644);
96module_param(debug_latency, int, 0644);
97
98module_param(fdsr, int, 0444);
99module_param(video_nr, int, 0444);
100module_param(radio_nr, int, 0444);
101module_param(vbi_nr, int, 0444);
102module_param(gbuffers, int, 0444);
103module_param(gbufsize, int, 0444);
104
105module_param(v4l2, int, 0644);
106module_param(bigendian, int, 0644);
107module_param(irq_iswitch, int, 0644);
108module_param(combfilter, int, 0444);
109module_param(lumafilter, int, 0444);
110module_param(automute, int, 0444);
111module_param(chroma_agc, int, 0444);
112module_param(adc_crush, int, 0444);
113module_param(whitecrush_upper, int, 0444);
114module_param(whitecrush_lower, int, 0444);
115module_param(vcr_hack, int, 0444);
060d3027
MCC
116module_param(uv_ratio, int, 0444);
117module_param(full_luma_range, int, 0444);
118module_param(coring, int, 0444);
1da177e4
LT
119
120module_param_array(radio, int, NULL, 0444);
121
122MODULE_PARM_DESC(radio,"The TV card supports radio, default is 0 (no)");
123MODULE_PARM_DESC(bigendian,"byte order of the framebuffer, default is native endian");
124MODULE_PARM_DESC(bttv_verbose,"verbose startup messages, default is 1 (yes)");
125MODULE_PARM_DESC(bttv_gpio,"log gpio changes, default is 0 (no)");
126MODULE_PARM_DESC(bttv_debug,"debug messages, default is 0 (no)");
127MODULE_PARM_DESC(irq_debug,"irq handler debug messages, default is 0 (no)");
128MODULE_PARM_DESC(gbuffers,"number of capture buffers. range 2-32, default 8");
129MODULE_PARM_DESC(gbufsize,"size of the capture buffers, default is 0x208000");
130MODULE_PARM_DESC(automute,"mute audio on bad/missing video signal, default is 1 (yes)");
131MODULE_PARM_DESC(chroma_agc,"enables the AGC of chroma signal, default is 0 (no)");
132MODULE_PARM_DESC(adc_crush,"enables the luminance ADC crush, default is 1 (yes)");
133MODULE_PARM_DESC(whitecrush_upper,"sets the white crush upper value, default is 207");
134MODULE_PARM_DESC(whitecrush_lower,"sets the white crush lower value, default is 127");
135MODULE_PARM_DESC(vcr_hack,"enables the VCR hack (improves synch on poor VCR tapes), default is 0 (no)");
136MODULE_PARM_DESC(irq_iswitch,"switch inputs in irq handler");
060d3027
MCC
137MODULE_PARM_DESC(uv_ratio,"ratio between u and v gains, default is 50");
138MODULE_PARM_DESC(full_luma_range,"use the full luma range, default is 0 (no)");
139MODULE_PARM_DESC(coring,"set the luma coring level, default is 0 (no)");
1da177e4
LT
140
141MODULE_DESCRIPTION("bttv - v4l/v4l2 driver module for bt848/878 based cards");
142MODULE_AUTHOR("Ralph Metzler & Marcus Metzler & Gerd Knorr");
143MODULE_LICENSE("GPL");
144
145/* ----------------------------------------------------------------------- */
146/* sysfs */
147
148static ssize_t show_card(struct class_device *cd, char *buf)
149{
150 struct video_device *vfd = to_video_device(cd);
151 struct bttv *btv = dev_get_drvdata(vfd->dev);
152 return sprintf(buf, "%d\n", btv ? btv->c.type : UNSET);
153}
154static CLASS_DEVICE_ATTR(card, S_IRUGO, show_card, NULL);
155
156/* ----------------------------------------------------------------------- */
157/* static data */
158
159/* special timing tables from conexant... */
160static u8 SRAM_Table[][60] =
161{
162 /* PAL digital input over GPIO[7:0] */
163 {
164 45, // 45 bytes following
165 0x36,0x11,0x01,0x00,0x90,0x02,0x05,0x10,0x04,0x16,
166 0x12,0x05,0x11,0x00,0x04,0x12,0xC0,0x00,0x31,0x00,
167 0x06,0x51,0x08,0x03,0x89,0x08,0x07,0xC0,0x44,0x00,
168 0x81,0x01,0x01,0xA9,0x0D,0x02,0x02,0x50,0x03,0x37,
169 0x37,0x00,0xAF,0x21,0x00
170 },
171 /* NTSC digital input over GPIO[7:0] */
172 {
173 51, // 51 bytes following
174 0x0C,0xC0,0x00,0x00,0x90,0x02,0x03,0x10,0x03,0x06,
175 0x10,0x04,0x12,0x12,0x05,0x02,0x13,0x04,0x19,0x00,
176 0x04,0x39,0x00,0x06,0x59,0x08,0x03,0x83,0x08,0x07,
177 0x03,0x50,0x00,0xC0,0x40,0x00,0x86,0x01,0x01,0xA6,
178 0x0D,0x02,0x03,0x11,0x01,0x05,0x37,0x00,0xAC,0x21,
179 0x00,
180 },
181 // TGB_NTSC392 // quartzsight
182 // This table has been modified to be used for Fusion Rev D
183 {
184 0x2A, // size of table = 42
185 0x06, 0x08, 0x04, 0x0a, 0xc0, 0x00, 0x18, 0x08, 0x03, 0x24,
186 0x08, 0x07, 0x02, 0x90, 0x02, 0x08, 0x10, 0x04, 0x0c, 0x10,
187 0x05, 0x2c, 0x11, 0x04, 0x55, 0x48, 0x00, 0x05, 0x50, 0x00,
188 0xbf, 0x0c, 0x02, 0x2f, 0x3d, 0x00, 0x2f, 0x3f, 0x00, 0xc3,
189 0x20, 0x00
190 }
191};
192
193const struct bttv_tvnorm bttv_tvnorms[] = {
194 /* PAL-BDGHI */
4ac97914
MCC
195 /* max. active video is actually 922, but 924 is divisible by 4 and 3! */
196 /* actually, max active PAL with HSCALE=0 is 948, NTSC is 768 - nil */
1da177e4
LT
197 {
198 .v4l2_id = V4L2_STD_PAL,
199 .name = "PAL",
200 .Fsc = 35468950,
201 .swidth = 924,
202 .sheight = 576,
203 .totalwidth = 1135,
204 .adelay = 0x7f,
205 .bdelay = 0x72,
206 .iform = (BT848_IFORM_PAL_BDGHI|BT848_IFORM_XT1),
207 .scaledtwidth = 1135,
208 .hdelayx1 = 186,
209 .hactivex1 = 924,
210 .vdelay = 0x20,
211 .vbipack = 255,
212 .sram = 0,
213 },{
214 .v4l2_id = V4L2_STD_NTSC_M,
215 .name = "NTSC",
216 .Fsc = 28636363,
217 .swidth = 768,
218 .sheight = 480,
219 .totalwidth = 910,
220 .adelay = 0x68,
221 .bdelay = 0x5d,
222 .iform = (BT848_IFORM_NTSC|BT848_IFORM_XT0),
223 .scaledtwidth = 910,
224 .hdelayx1 = 128,
225 .hactivex1 = 910,
226 .vdelay = 0x1a,
227 .vbipack = 144,
228 .sram = 1,
229 },{
230 .v4l2_id = V4L2_STD_SECAM,
231 .name = "SECAM",
232 .Fsc = 35468950,
233 .swidth = 924,
234 .sheight = 576,
235 .totalwidth = 1135,
236 .adelay = 0x7f,
237 .bdelay = 0xb0,
238 .iform = (BT848_IFORM_SECAM|BT848_IFORM_XT1),
239 .scaledtwidth = 1135,
240 .hdelayx1 = 186,
241 .hactivex1 = 922,
242 .vdelay = 0x20,
243 .vbipack = 255,
244 .sram = 0, /* like PAL, correct? */
245 },{
246 .v4l2_id = V4L2_STD_PAL_Nc,
247 .name = "PAL-Nc",
248 .Fsc = 28636363,
249 .swidth = 640,
250 .sheight = 576,
251 .totalwidth = 910,
252 .adelay = 0x68,
253 .bdelay = 0x5d,
254 .iform = (BT848_IFORM_PAL_NC|BT848_IFORM_XT0),
255 .scaledtwidth = 780,
256 .hdelayx1 = 130,
257 .hactivex1 = 734,
258 .vdelay = 0x1a,
259 .vbipack = 144,
260 .sram = -1,
261 },{
262 .v4l2_id = V4L2_STD_PAL_M,
263 .name = "PAL-M",
264 .Fsc = 28636363,
265 .swidth = 640,
266 .sheight = 480,
267 .totalwidth = 910,
268 .adelay = 0x68,
269 .bdelay = 0x5d,
270 .iform = (BT848_IFORM_PAL_M|BT848_IFORM_XT0),
271 .scaledtwidth = 780,
272 .hdelayx1 = 135,
273 .hactivex1 = 754,
274 .vdelay = 0x1a,
275 .vbipack = 144,
276 .sram = -1,
277 },{
278 .v4l2_id = V4L2_STD_PAL_N,
279 .name = "PAL-N",
280 .Fsc = 35468950,
281 .swidth = 768,
282 .sheight = 576,
283 .totalwidth = 1135,
284 .adelay = 0x7f,
285 .bdelay = 0x72,
286 .iform = (BT848_IFORM_PAL_N|BT848_IFORM_XT1),
287 .scaledtwidth = 944,
288 .hdelayx1 = 186,
289 .hactivex1 = 922,
290 .vdelay = 0x20,
291 .vbipack = 144,
292 .sram = -1,
293 },{
294 .v4l2_id = V4L2_STD_NTSC_M_JP,
295 .name = "NTSC-JP",
296 .Fsc = 28636363,
297 .swidth = 640,
298 .sheight = 480,
299 .totalwidth = 910,
300 .adelay = 0x68,
301 .bdelay = 0x5d,
302 .iform = (BT848_IFORM_NTSC_J|BT848_IFORM_XT0),
303 .scaledtwidth = 780,
304 .hdelayx1 = 135,
305 .hactivex1 = 754,
306 .vdelay = 0x16,
307 .vbipack = 144,
308 .sram = -1,
309 },{
310 /* that one hopefully works with the strange timing
311 * which video recorders produce when playing a NTSC
312 * tape on a PAL TV ... */
313 .v4l2_id = V4L2_STD_PAL_60,
314 .name = "PAL-60",
315 .Fsc = 35468950,
316 .swidth = 924,
317 .sheight = 480,
318 .totalwidth = 1135,
319 .adelay = 0x7f,
320 .bdelay = 0x72,
321 .iform = (BT848_IFORM_PAL_BDGHI|BT848_IFORM_XT1),
322 .scaledtwidth = 1135,
323 .hdelayx1 = 186,
324 .hactivex1 = 924,
325 .vdelay = 0x1a,
326 .vbipack = 255,
327 .vtotal = 524,
328 .sram = -1,
329 }
330};
331static const unsigned int BTTV_TVNORMS = ARRAY_SIZE(bttv_tvnorms);
332
333/* ----------------------------------------------------------------------- */
334/* bttv format list
335 packed pixel formats must come first */
336static const struct bttv_format bttv_formats[] = {
337 {
338 .name = "8 bpp, gray",
339 .palette = VIDEO_PALETTE_GREY,
340 .fourcc = V4L2_PIX_FMT_GREY,
341 .btformat = BT848_COLOR_FMT_Y8,
342 .depth = 8,
343 .flags = FORMAT_FLAGS_PACKED,
344 },{
345 .name = "8 bpp, dithered color",
346 .palette = VIDEO_PALETTE_HI240,
347 .fourcc = V4L2_PIX_FMT_HI240,
348 .btformat = BT848_COLOR_FMT_RGB8,
349 .depth = 8,
350 .flags = FORMAT_FLAGS_PACKED | FORMAT_FLAGS_DITHER,
351 },{
352 .name = "15 bpp RGB, le",
353 .palette = VIDEO_PALETTE_RGB555,
354 .fourcc = V4L2_PIX_FMT_RGB555,
355 .btformat = BT848_COLOR_FMT_RGB15,
356 .depth = 16,
357 .flags = FORMAT_FLAGS_PACKED,
358 },{
359 .name = "15 bpp RGB, be",
360 .palette = -1,
361 .fourcc = V4L2_PIX_FMT_RGB555X,
362 .btformat = BT848_COLOR_FMT_RGB15,
363 .btswap = 0x03, /* byteswap */
364 .depth = 16,
365 .flags = FORMAT_FLAGS_PACKED,
366 },{
367 .name = "16 bpp RGB, le",
368 .palette = VIDEO_PALETTE_RGB565,
369 .fourcc = V4L2_PIX_FMT_RGB565,
370 .btformat = BT848_COLOR_FMT_RGB16,
371 .depth = 16,
372 .flags = FORMAT_FLAGS_PACKED,
373 },{
374 .name = "16 bpp RGB, be",
375 .palette = -1,
376 .fourcc = V4L2_PIX_FMT_RGB565X,
377 .btformat = BT848_COLOR_FMT_RGB16,
378 .btswap = 0x03, /* byteswap */
379 .depth = 16,
380 .flags = FORMAT_FLAGS_PACKED,
381 },{
382 .name = "24 bpp RGB, le",
383 .palette = VIDEO_PALETTE_RGB24,
384 .fourcc = V4L2_PIX_FMT_BGR24,
385 .btformat = BT848_COLOR_FMT_RGB24,
386 .depth = 24,
387 .flags = FORMAT_FLAGS_PACKED,
388 },{
389 .name = "32 bpp RGB, le",
390 .palette = VIDEO_PALETTE_RGB32,
391 .fourcc = V4L2_PIX_FMT_BGR32,
392 .btformat = BT848_COLOR_FMT_RGB32,
393 .depth = 32,
394 .flags = FORMAT_FLAGS_PACKED,
395 },{
396 .name = "32 bpp RGB, be",
397 .palette = -1,
398 .fourcc = V4L2_PIX_FMT_RGB32,
399 .btformat = BT848_COLOR_FMT_RGB32,
400 .btswap = 0x0f, /* byte+word swap */
401 .depth = 32,
402 .flags = FORMAT_FLAGS_PACKED,
403 },{
404 .name = "4:2:2, packed, YUYV",
405 .palette = VIDEO_PALETTE_YUV422,
406 .fourcc = V4L2_PIX_FMT_YUYV,
407 .btformat = BT848_COLOR_FMT_YUY2,
408 .depth = 16,
409 .flags = FORMAT_FLAGS_PACKED,
410 },{
411 .name = "4:2:2, packed, YUYV",
412 .palette = VIDEO_PALETTE_YUYV,
413 .fourcc = V4L2_PIX_FMT_YUYV,
414 .btformat = BT848_COLOR_FMT_YUY2,
415 .depth = 16,
416 .flags = FORMAT_FLAGS_PACKED,
417 },{
418 .name = "4:2:2, packed, UYVY",
419 .palette = VIDEO_PALETTE_UYVY,
420 .fourcc = V4L2_PIX_FMT_UYVY,
421 .btformat = BT848_COLOR_FMT_YUY2,
422 .btswap = 0x03, /* byteswap */
423 .depth = 16,
424 .flags = FORMAT_FLAGS_PACKED,
425 },{
426 .name = "4:2:2, planar, Y-Cb-Cr",
427 .palette = VIDEO_PALETTE_YUV422P,
428 .fourcc = V4L2_PIX_FMT_YUV422P,
429 .btformat = BT848_COLOR_FMT_YCrCb422,
430 .depth = 16,
431 .flags = FORMAT_FLAGS_PLANAR,
432 .hshift = 1,
433 .vshift = 0,
434 },{
435 .name = "4:2:0, planar, Y-Cb-Cr",
436 .palette = VIDEO_PALETTE_YUV420P,
437 .fourcc = V4L2_PIX_FMT_YUV420,
438 .btformat = BT848_COLOR_FMT_YCrCb422,
439 .depth = 12,
440 .flags = FORMAT_FLAGS_PLANAR,
441 .hshift = 1,
442 .vshift = 1,
443 },{
444 .name = "4:2:0, planar, Y-Cr-Cb",
445 .palette = -1,
446 .fourcc = V4L2_PIX_FMT_YVU420,
447 .btformat = BT848_COLOR_FMT_YCrCb422,
448 .depth = 12,
449 .flags = FORMAT_FLAGS_PLANAR | FORMAT_FLAGS_CrCb,
450 .hshift = 1,
451 .vshift = 1,
452 },{
453 .name = "4:1:1, planar, Y-Cb-Cr",
454 .palette = VIDEO_PALETTE_YUV411P,
455 .fourcc = V4L2_PIX_FMT_YUV411P,
456 .btformat = BT848_COLOR_FMT_YCrCb411,
457 .depth = 12,
458 .flags = FORMAT_FLAGS_PLANAR,
459 .hshift = 2,
460 .vshift = 0,
461 },{
462 .name = "4:1:0, planar, Y-Cb-Cr",
463 .palette = VIDEO_PALETTE_YUV410P,
464 .fourcc = V4L2_PIX_FMT_YUV410,
465 .btformat = BT848_COLOR_FMT_YCrCb411,
466 .depth = 9,
467 .flags = FORMAT_FLAGS_PLANAR,
468 .hshift = 2,
469 .vshift = 2,
470 },{
471 .name = "4:1:0, planar, Y-Cr-Cb",
472 .palette = -1,
473 .fourcc = V4L2_PIX_FMT_YVU410,
474 .btformat = BT848_COLOR_FMT_YCrCb411,
475 .depth = 9,
476 .flags = FORMAT_FLAGS_PLANAR | FORMAT_FLAGS_CrCb,
477 .hshift = 2,
478 .vshift = 2,
479 },{
480 .name = "raw scanlines",
481 .palette = VIDEO_PALETTE_RAW,
482 .fourcc = -1,
483 .btformat = BT848_COLOR_FMT_RAW,
484 .depth = 8,
485 .flags = FORMAT_FLAGS_RAW,
486 }
487};
488static const unsigned int BTTV_FORMATS = ARRAY_SIZE(bttv_formats);
489
490/* ----------------------------------------------------------------------- */
491
492#define V4L2_CID_PRIVATE_CHROMA_AGC (V4L2_CID_PRIVATE_BASE + 0)
493#define V4L2_CID_PRIVATE_COMBFILTER (V4L2_CID_PRIVATE_BASE + 1)
494#define V4L2_CID_PRIVATE_AUTOMUTE (V4L2_CID_PRIVATE_BASE + 2)
495#define V4L2_CID_PRIVATE_LUMAFILTER (V4L2_CID_PRIVATE_BASE + 3)
496#define V4L2_CID_PRIVATE_AGC_CRUSH (V4L2_CID_PRIVATE_BASE + 4)
497#define V4L2_CID_PRIVATE_VCR_HACK (V4L2_CID_PRIVATE_BASE + 5)
498#define V4L2_CID_PRIVATE_WHITECRUSH_UPPER (V4L2_CID_PRIVATE_BASE + 6)
499#define V4L2_CID_PRIVATE_WHITECRUSH_LOWER (V4L2_CID_PRIVATE_BASE + 7)
060d3027
MCC
500#define V4L2_CID_PRIVATE_UV_RATIO (V4L2_CID_PRIVATE_BASE + 8)
501#define V4L2_CID_PRIVATE_FULL_LUMA_RANGE (V4L2_CID_PRIVATE_BASE + 9)
502#define V4L2_CID_PRIVATE_CORING (V4L2_CID_PRIVATE_BASE + 10)
503#define V4L2_CID_PRIVATE_LASTP1 (V4L2_CID_PRIVATE_BASE + 11)
1da177e4
LT
504
505static const struct v4l2_queryctrl no_ctl = {
506 .name = "42",
507 .flags = V4L2_CTRL_FLAG_DISABLED,
508};
509static const struct v4l2_queryctrl bttv_ctls[] = {
510 /* --- video --- */
511 {
512 .id = V4L2_CID_BRIGHTNESS,
513 .name = "Brightness",
514 .minimum = 0,
515 .maximum = 65535,
516 .step = 256,
517 .default_value = 32768,
518 .type = V4L2_CTRL_TYPE_INTEGER,
519 },{
520 .id = V4L2_CID_CONTRAST,
521 .name = "Contrast",
522 .minimum = 0,
523 .maximum = 65535,
524 .step = 128,
525 .default_value = 32768,
526 .type = V4L2_CTRL_TYPE_INTEGER,
527 },{
528 .id = V4L2_CID_SATURATION,
529 .name = "Saturation",
530 .minimum = 0,
531 .maximum = 65535,
532 .step = 128,
533 .default_value = 32768,
534 .type = V4L2_CTRL_TYPE_INTEGER,
535 },{
536 .id = V4L2_CID_HUE,
537 .name = "Hue",
538 .minimum = 0,
539 .maximum = 65535,
540 .step = 256,
541 .default_value = 32768,
542 .type = V4L2_CTRL_TYPE_INTEGER,
543 },
544 /* --- audio --- */
545 {
546 .id = V4L2_CID_AUDIO_MUTE,
547 .name = "Mute",
548 .minimum = 0,
549 .maximum = 1,
550 .type = V4L2_CTRL_TYPE_BOOLEAN,
551 },{
552 .id = V4L2_CID_AUDIO_VOLUME,
553 .name = "Volume",
554 .minimum = 0,
555 .maximum = 65535,
556 .step = 65535/100,
557 .default_value = 65535,
558 .type = V4L2_CTRL_TYPE_INTEGER,
559 },{
560 .id = V4L2_CID_AUDIO_BALANCE,
561 .name = "Balance",
562 .minimum = 0,
563 .maximum = 65535,
564 .step = 65535/100,
565 .default_value = 32768,
566 .type = V4L2_CTRL_TYPE_INTEGER,
567 },{
568 .id = V4L2_CID_AUDIO_BASS,
569 .name = "Bass",
570 .minimum = 0,
571 .maximum = 65535,
572 .step = 65535/100,
573 .default_value = 32768,
574 .type = V4L2_CTRL_TYPE_INTEGER,
575 },{
576 .id = V4L2_CID_AUDIO_TREBLE,
577 .name = "Treble",
578 .minimum = 0,
579 .maximum = 65535,
580 .step = 65535/100,
581 .default_value = 32768,
582 .type = V4L2_CTRL_TYPE_INTEGER,
583 },
584 /* --- private --- */
585 {
586 .id = V4L2_CID_PRIVATE_CHROMA_AGC,
587 .name = "chroma agc",
588 .minimum = 0,
589 .maximum = 1,
590 .type = V4L2_CTRL_TYPE_BOOLEAN,
591 },{
592 .id = V4L2_CID_PRIVATE_COMBFILTER,
593 .name = "combfilter",
594 .minimum = 0,
595 .maximum = 1,
596 .type = V4L2_CTRL_TYPE_BOOLEAN,
597 },{
598 .id = V4L2_CID_PRIVATE_AUTOMUTE,
599 .name = "automute",
600 .minimum = 0,
601 .maximum = 1,
602 .type = V4L2_CTRL_TYPE_BOOLEAN,
603 },{
604 .id = V4L2_CID_PRIVATE_LUMAFILTER,
605 .name = "luma decimation filter",
606 .minimum = 0,
607 .maximum = 1,
608 .type = V4L2_CTRL_TYPE_BOOLEAN,
609 },{
610 .id = V4L2_CID_PRIVATE_AGC_CRUSH,
611 .name = "agc crush",
612 .minimum = 0,
613 .maximum = 1,
614 .type = V4L2_CTRL_TYPE_BOOLEAN,
615 },{
616 .id = V4L2_CID_PRIVATE_VCR_HACK,
617 .name = "vcr hack",
618 .minimum = 0,
619 .maximum = 1,
620 .type = V4L2_CTRL_TYPE_BOOLEAN,
621 },{
622 .id = V4L2_CID_PRIVATE_WHITECRUSH_UPPER,
623 .name = "whitecrush upper",
624 .minimum = 0,
625 .maximum = 255,
626 .step = 1,
627 .default_value = 0xCF,
628 .type = V4L2_CTRL_TYPE_INTEGER,
629 },{
630 .id = V4L2_CID_PRIVATE_WHITECRUSH_LOWER,
631 .name = "whitecrush lower",
632 .minimum = 0,
633 .maximum = 255,
634 .step = 1,
635 .default_value = 0x7F,
636 .type = V4L2_CTRL_TYPE_INTEGER,
060d3027
MCC
637 },{
638 .id = V4L2_CID_PRIVATE_UV_RATIO,
639 .name = "uv ratio",
640 .minimum = 0,
641 .maximum = 100,
642 .step = 1,
643 .default_value = 50,
644 .type = V4L2_CTRL_TYPE_INTEGER,
645 },{
646 .id = V4L2_CID_PRIVATE_FULL_LUMA_RANGE,
647 .name = "full luma range",
648 .minimum = 0,
649 .maximum = 1,
650 .type = V4L2_CTRL_TYPE_BOOLEAN,
651 },{
652 .id = V4L2_CID_PRIVATE_CORING,
653 .name = "coring",
654 .minimum = 0,
655 .maximum = 3,
656 .step = 1,
657 .default_value = 0,
658 .type = V4L2_CTRL_TYPE_INTEGER,
1da177e4
LT
659 }
660
060d3027
MCC
661
662
1da177e4
LT
663};
664static const int BTTV_CTLS = ARRAY_SIZE(bttv_ctls);
665
666/* ----------------------------------------------------------------------- */
667/* resource management */
668
669static
670int check_alloc_btres(struct bttv *btv, struct bttv_fh *fh, int bit)
671{
672 if (fh->resources & bit)
673 /* have it already allocated */
674 return 1;
675
676 /* is it free? */
677 down(&btv->reslock);
678 if (btv->resources & bit) {
679 /* no, someone else uses it */
680 up(&btv->reslock);
681 return 0;
682 }
683 /* it's free, grab it */
684 fh->resources |= bit;
685 btv->resources |= bit;
686 up(&btv->reslock);
687 return 1;
688}
689
690static
691int check_btres(struct bttv_fh *fh, int bit)
692{
693 return (fh->resources & bit);
694}
695
696static
697int locked_btres(struct bttv *btv, int bit)
698{
699 return (btv->resources & bit);
700}
701
702static
703void free_btres(struct bttv *btv, struct bttv_fh *fh, int bits)
704{
1da177e4
LT
705 if ((fh->resources & bits) != bits) {
706 /* trying to free ressources not allocated by us ... */
707 printk("bttv: BUG! (btres)\n");
708 }
1da177e4
LT
709 down(&btv->reslock);
710 fh->resources &= ~bits;
711 btv->resources &= ~bits;
712 up(&btv->reslock);
713}
714
715/* ----------------------------------------------------------------------- */
716/* If Bt848a or Bt849, use PLL for PAL/SECAM and crystal for NTSC */
717
718/* Frequency = (F_input / PLL_X) * PLL_I.PLL_F/PLL_C
719 PLL_X = Reference pre-divider (0=1, 1=2)
720 PLL_C = Post divider (0=6, 1=4)
721 PLL_I = Integer input
722 PLL_F = Fractional input
723
724 F_input = 28.636363 MHz:
725 PAL (CLKx2 = 35.46895 MHz): PLL_X = 1, PLL_I = 0x0E, PLL_F = 0xDCF9, PLL_C = 0
726*/
727
728static void set_pll_freq(struct bttv *btv, unsigned int fin, unsigned int fout)
729{
afd1a0c9 730 unsigned char fl, fh, fi;
1da177e4 731
afd1a0c9
MCC
732 /* prevent overflows */
733 fin/=4;
734 fout/=4;
1da177e4 735
afd1a0c9
MCC
736 fout*=12;
737 fi=fout/fin;
1da177e4 738
afd1a0c9
MCC
739 fout=(fout%fin)*256;
740 fh=fout/fin;
1da177e4 741
afd1a0c9
MCC
742 fout=(fout%fin)*256;
743 fl=fout/fin;
1da177e4 744
afd1a0c9
MCC
745 btwrite(fl, BT848_PLL_F_LO);
746 btwrite(fh, BT848_PLL_F_HI);
747 btwrite(fi|BT848_PLL_X, BT848_PLL_XCI);
1da177e4
LT
748}
749
750static void set_pll(struct bttv *btv)
751{
afd1a0c9 752 int i;
1da177e4 753
afd1a0c9
MCC
754 if (!btv->pll.pll_crystal)
755 return;
1da177e4
LT
756
757 if (btv->pll.pll_ofreq == btv->pll.pll_current) {
758 dprintk("bttv%d: PLL: no change required\n",btv->c.nr);
afd1a0c9
MCC
759 return;
760 }
1da177e4 761
afd1a0c9
MCC
762 if (btv->pll.pll_ifreq == btv->pll.pll_ofreq) {
763 /* no PLL needed */
764 if (btv->pll.pll_current == 0)
674434c6 765 return;
e1e70a26 766 bttv_printk(KERN_INFO "bttv%d: PLL can sleep, using XTAL (%d).\n",
674434c6 767 btv->c.nr,btv->pll.pll_ifreq);
afd1a0c9
MCC
768 btwrite(0x00,BT848_TGCTRL);
769 btwrite(0x00,BT848_PLL_XCI);
770 btv->pll.pll_current = 0;
771 return;
772 }
1da177e4 773
e1e70a26 774 bttv_printk(KERN_INFO "bttv%d: PLL: %d => %d ",btv->c.nr,
674434c6 775 btv->pll.pll_ifreq, btv->pll.pll_ofreq);
1da177e4
LT
776 set_pll_freq(btv, btv->pll.pll_ifreq, btv->pll.pll_ofreq);
777
afd1a0c9 778 for (i=0; i<10; i++) {
1da177e4 779 /* Let other people run while the PLL stabilizes */
e1e70a26 780 bttv_printk(".");
1da177e4
LT
781 msleep(10);
782
afd1a0c9 783 if (btread(BT848_DSTATUS) & BT848_DSTATUS_PLOCK) {
1da177e4 784 btwrite(0,BT848_DSTATUS);
afd1a0c9 785 } else {
674434c6
MCC
786 btwrite(0x08,BT848_TGCTRL);
787 btv->pll.pll_current = btv->pll.pll_ofreq;
e1e70a26 788 bttv_printk(" ok\n");
674434c6 789 return;
afd1a0c9
MCC
790 }
791 }
792 btv->pll.pll_current = -1;
e1e70a26 793 bttv_printk("failed\n");
afd1a0c9 794 return;
1da177e4
LT
795}
796
797/* used to switch between the bt848's analog/digital video capture modes */
798static void bt848A_set_timing(struct bttv *btv)
799{
800 int i, len;
801 int table_idx = bttv_tvnorms[btv->tvnorm].sram;
802 int fsc = bttv_tvnorms[btv->tvnorm].Fsc;
803
804 if (UNSET == bttv_tvcards[btv->c.type].muxsel[btv->input]) {
805 dprintk("bttv%d: load digital timing table (table_idx=%d)\n",
806 btv->c.nr,table_idx);
807
808 /* timing change...reset timing generator address */
4ac97914
MCC
809 btwrite(0x00, BT848_TGCTRL);
810 btwrite(0x02, BT848_TGCTRL);
811 btwrite(0x00, BT848_TGCTRL);
1da177e4
LT
812
813 len=SRAM_Table[table_idx][0];
814 for(i = 1; i <= len; i++)
815 btwrite(SRAM_Table[table_idx][i],BT848_TGLB);
816 btv->pll.pll_ofreq = 27000000;
817
818 set_pll(btv);
819 btwrite(0x11, BT848_TGCTRL);
820 btwrite(0x41, BT848_DVSIF);
821 } else {
822 btv->pll.pll_ofreq = fsc;
823 set_pll(btv);
824 btwrite(0x0, BT848_DVSIF);
825 }
826}
827
828/* ----------------------------------------------------------------------- */
829
830static void bt848_bright(struct bttv *btv, int bright)
831{
832 int value;
833
834 // printk("bttv: set bright: %d\n",bright); // DEBUG
835 btv->bright = bright;
836
837 /* We want -128 to 127 we get 0-65535 */
838 value = (bright >> 8) - 128;
839 btwrite(value & 0xff, BT848_BRIGHT);
840}
841
842static void bt848_hue(struct bttv *btv, int hue)
843{
844 int value;
845
846 btv->hue = hue;
847
848 /* -128 to 127 */
849 value = (hue >> 8) - 128;
4ac97914 850 btwrite(value & 0xff, BT848_HUE);
1da177e4
LT
851}
852
853static void bt848_contrast(struct bttv *btv, int cont)
854{
855 int value,hibit;
856
857 btv->contrast = cont;
858
859 /* 0-511 */
860 value = (cont >> 7);
861 hibit = (value >> 6) & 4;
4ac97914
MCC
862 btwrite(value & 0xff, BT848_CONTRAST_LO);
863 btaor(hibit, ~4, BT848_E_CONTROL);
864 btaor(hibit, ~4, BT848_O_CONTROL);
1da177e4
LT
865}
866
867static void bt848_sat(struct bttv *btv, int color)
868{
869 int val_u,val_v,hibits;
870
871 btv->saturation = color;
872
873 /* 0-511 for the color */
060d3027
MCC
874 val_u = ((color * btv->opt_uv_ratio) / 50) >> 7;
875 val_v = (((color * (100 - btv->opt_uv_ratio) / 50) >>7)*180L)/254;
4ac97914 876 hibits = (val_u >> 7) & 2;
1da177e4 877 hibits |= (val_v >> 8) & 1;
4ac97914
MCC
878 btwrite(val_u & 0xff, BT848_SAT_U_LO);
879 btwrite(val_v & 0xff, BT848_SAT_V_LO);
880 btaor(hibits, ~3, BT848_E_CONTROL);
881 btaor(hibits, ~3, BT848_O_CONTROL);
1da177e4
LT
882}
883
884/* ----------------------------------------------------------------------- */
885
886static int
887video_mux(struct bttv *btv, unsigned int input)
888{
889 int mux,mask2;
890
891 if (input >= bttv_tvcards[btv->c.type].video_inputs)
892 return -EINVAL;
893
4ac97914 894 /* needed by RemoteVideo MX */
1da177e4
LT
895 mask2 = bttv_tvcards[btv->c.type].gpiomask2;
896 if (mask2)
897 gpio_inout(mask2,mask2);
898
899 if (input == btv->svhs) {
900 btor(BT848_CONTROL_COMP, BT848_E_CONTROL);
901 btor(BT848_CONTROL_COMP, BT848_O_CONTROL);
902 } else {
903 btand(~BT848_CONTROL_COMP, BT848_E_CONTROL);
904 btand(~BT848_CONTROL_COMP, BT848_O_CONTROL);
905 }
906 mux = bttv_tvcards[btv->c.type].muxsel[input] & 3;
907 btaor(mux<<5, ~(3<<5), BT848_IFORM);
908 dprintk(KERN_DEBUG "bttv%d: video mux: input=%d mux=%d\n",
909 btv->c.nr,input,mux);
910
911 /* card specific hook */
912 if(bttv_tvcards[btv->c.type].muxsel_hook)
913 bttv_tvcards[btv->c.type].muxsel_hook (btv, input);
914 return 0;
915}
916
917static char *audio_modes[] = {
918 "audio: tuner", "audio: radio", "audio: extern",
919 "audio: intern", "audio: off"
920};
921
922static int
923audio_mux(struct bttv *btv, int mode)
924{
925 int val,mux,i2c_mux,signal;
926
927 gpio_inout(bttv_tvcards[btv->c.type].gpiomask,
928 bttv_tvcards[btv->c.type].gpiomask);
929 signal = btread(BT848_DSTATUS) & BT848_DSTATUS_HLOC;
930
931 switch (mode) {
932 case AUDIO_MUTE:
933 btv->audio |= AUDIO_MUTE;
934 break;
935 case AUDIO_UNMUTE:
936 btv->audio &= ~AUDIO_MUTE;
937 break;
938 case AUDIO_TUNER:
939 case AUDIO_RADIO:
940 case AUDIO_EXTERN:
941 case AUDIO_INTERN:
942 btv->audio &= AUDIO_MUTE;
943 btv->audio |= mode;
944 }
945 i2c_mux = mux = (btv->audio & AUDIO_MUTE) ? AUDIO_OFF : btv->audio;
946 if (btv->opt_automute && !signal && !btv->radio_user)
947 mux = AUDIO_OFF;
1da177e4
LT
948
949 val = bttv_tvcards[btv->c.type].audiomux[mux];
950 gpio_bits(bttv_tvcards[btv->c.type].gpiomask,val);
951 if (bttv_gpio)
952 bttv_gpio_tracking(btv,audio_modes[mux]);
953 if (!in_interrupt())
954 bttv_call_i2c_clients(btv,AUDC_SET_INPUT,&(i2c_mux));
955 return 0;
956}
957
958static void
959i2c_vidiocschan(struct bttv *btv)
960{
961 struct video_channel c;
962
963 memset(&c,0,sizeof(c));
964 c.norm = btv->tvnorm;
965 c.channel = btv->input;
966 bttv_call_i2c_clients(btv,VIDIOCSCHAN,&c);
5a25e84b 967 if (btv->c.type == BTTV_BOARD_VOODOOTV_FM)
1da177e4
LT
968 bttv_tda9880_setnorm(btv,c.norm);
969}
970
971static int
972set_tvnorm(struct bttv *btv, unsigned int norm)
973{
974 const struct bttv_tvnorm *tvnorm;
975
976 if (norm < 0 || norm >= BTTV_TVNORMS)
977 return -EINVAL;
978
979 btv->tvnorm = norm;
980 tvnorm = &bttv_tvnorms[norm];
981
982 btwrite(tvnorm->adelay, BT848_ADELAY);
983 btwrite(tvnorm->bdelay, BT848_BDELAY);
984 btaor(tvnorm->iform,~(BT848_IFORM_NORM|BT848_IFORM_XTBOTH),
985 BT848_IFORM);
986 btwrite(tvnorm->vbipack, BT848_VBI_PACK_SIZE);
987 btwrite(1, BT848_VBI_PACK_DEL);
988 bt848A_set_timing(btv);
989
990 switch (btv->c.type) {
5a25e84b 991 case BTTV_BOARD_VOODOOTV_FM:
1da177e4
LT
992 bttv_tda9880_setnorm(btv,norm);
993 break;
1da177e4
LT
994 }
995 return 0;
996}
997
998static void
999set_input(struct bttv *btv, unsigned int input)
1000{
1001 unsigned long flags;
1002
1003 btv->input = input;
1004 if (irq_iswitch) {
1005 spin_lock_irqsave(&btv->s_lock,flags);
1006 if (btv->curr.frame_irq) {
1007 /* active capture -> delayed input switch */
1008 btv->new_input = input;
1009 } else {
1010 video_mux(btv,input);
1011 }
1012 spin_unlock_irqrestore(&btv->s_lock,flags);
1013 } else {
1014 video_mux(btv,input);
1015 }
1016 audio_mux(btv,(input == bttv_tvcards[btv->c.type].tuner ?
1017 AUDIO_TUNER : AUDIO_EXTERN));
1018 set_tvnorm(btv,btv->tvnorm);
1019 i2c_vidiocschan(btv);
1020}
1021
1022static void init_irqreg(struct bttv *btv)
1023{
1024 /* clear status */
1025 btwrite(0xfffffUL, BT848_INT_STAT);
1026
1027 if (bttv_tvcards[btv->c.type].no_video) {
1028 /* i2c only */
1029 btwrite(BT848_INT_I2CDONE,
1030 BT848_INT_MASK);
1031 } else {
1032 /* full video */
1033 btwrite((btv->triton1) |
1034 (btv->gpioirq ? BT848_INT_GPINT : 0) |
1035 BT848_INT_SCERR |
1036 (fdsr ? BT848_INT_FDSR : 0) |
1037 BT848_INT_RISCI|BT848_INT_OCERR|BT848_INT_VPRES|
1038 BT848_INT_FMTCHG|BT848_INT_HLOCK|
1039 BT848_INT_I2CDONE,
1040 BT848_INT_MASK);
1041 }
1042}
1043
1044static void init_bt848(struct bttv *btv)
1045{
1046 int val;
1047
1048 if (bttv_tvcards[btv->c.type].no_video) {
1049 /* very basic init only */
1050 init_irqreg(btv);
1051 return;
1052 }
1053
1054 btwrite(0x00, BT848_CAP_CTL);
1055 btwrite(BT848_COLOR_CTL_GAMMA, BT848_COLOR_CTL);
1056 btwrite(BT848_IFORM_XTAUTO | BT848_IFORM_AUTO, BT848_IFORM);
1057
4ac97914
MCC
1058 /* set planar and packed mode trigger points and */
1059 /* set rising edge of inverted GPINTR pin as irq trigger */
1060 btwrite(BT848_GPIO_DMA_CTL_PKTP_32|
1061 BT848_GPIO_DMA_CTL_PLTP1_16|
1062 BT848_GPIO_DMA_CTL_PLTP23_16|
1063 BT848_GPIO_DMA_CTL_GPINTC|
1064 BT848_GPIO_DMA_CTL_GPINTI,
1065 BT848_GPIO_DMA_CTL);
1da177e4
LT
1066
1067 val = btv->opt_chroma_agc ? BT848_SCLOOP_CAGC : 0;
4ac97914
MCC
1068 btwrite(val, BT848_E_SCLOOP);
1069 btwrite(val, BT848_O_SCLOOP);
1da177e4 1070
4ac97914
MCC
1071 btwrite(0x20, BT848_E_VSCALE_HI);
1072 btwrite(0x20, BT848_O_VSCALE_HI);
1073 btwrite(BT848_ADC_RESERVED | (btv->opt_adc_crush ? BT848_ADC_CRUSH : 0),
1da177e4
LT
1074 BT848_ADC);
1075
1076 btwrite(whitecrush_upper, BT848_WC_UP);
1077 btwrite(whitecrush_lower, BT848_WC_DOWN);
1078
1079 if (btv->opt_lumafilter) {
1080 btwrite(0, BT848_E_CONTROL);
1081 btwrite(0, BT848_O_CONTROL);
1082 } else {
1083 btwrite(BT848_CONTROL_LDEC, BT848_E_CONTROL);
1084 btwrite(BT848_CONTROL_LDEC, BT848_O_CONTROL);
1085 }
1086
1087 bt848_bright(btv, btv->bright);
1088 bt848_hue(btv, btv->hue);
1089 bt848_contrast(btv, btv->contrast);
1090 bt848_sat(btv, btv->saturation);
1091
4ac97914 1092 /* interrupt */
1da177e4
LT
1093 init_irqreg(btv);
1094}
1095
1096static void bttv_reinit_bt848(struct bttv *btv)
1097{
1098 unsigned long flags;
1099
1100 if (bttv_verbose)
1101 printk(KERN_INFO "bttv%d: reset, reinitialize\n",btv->c.nr);
1102 spin_lock_irqsave(&btv->s_lock,flags);
1103 btv->errors=0;
1104 bttv_set_dma(btv,0);
1105 spin_unlock_irqrestore(&btv->s_lock,flags);
1106
1107 init_bt848(btv);
4ac97914 1108 btv->pll.pll_current = -1;
1da177e4
LT
1109 set_input(btv,btv->input);
1110}
1111
1112static int get_control(struct bttv *btv, struct v4l2_control *c)
1113{
1114 struct video_audio va;
1115 int i;
1116
1117 for (i = 0; i < BTTV_CTLS; i++)
1118 if (bttv_ctls[i].id == c->id)
1119 break;
1120 if (i == BTTV_CTLS)
1121 return -EINVAL;
1122 if (i >= 4 && i <= 8) {
1123 memset(&va,0,sizeof(va));
1124 bttv_call_i2c_clients(btv, VIDIOCGAUDIO, &va);
1125 if (btv->audio_hook)
1126 btv->audio_hook(btv,&va,0);
1127 }
1128 switch (c->id) {
1129 case V4L2_CID_BRIGHTNESS:
1130 c->value = btv->bright;
1131 break;
1132 case V4L2_CID_HUE:
1133 c->value = btv->hue;
1134 break;
1135 case V4L2_CID_CONTRAST:
1136 c->value = btv->contrast;
1137 break;
1138 case V4L2_CID_SATURATION:
1139 c->value = btv->saturation;
1140 break;
1141
1142 case V4L2_CID_AUDIO_MUTE:
1143 c->value = (VIDEO_AUDIO_MUTE & va.flags) ? 1 : 0;
1144 break;
1145 case V4L2_CID_AUDIO_VOLUME:
1146 c->value = va.volume;
1147 break;
1148 case V4L2_CID_AUDIO_BALANCE:
1149 c->value = va.balance;
1150 break;
1151 case V4L2_CID_AUDIO_BASS:
1152 c->value = va.bass;
1153 break;
1154 case V4L2_CID_AUDIO_TREBLE:
1155 c->value = va.treble;
1156 break;
1157
1158 case V4L2_CID_PRIVATE_CHROMA_AGC:
1159 c->value = btv->opt_chroma_agc;
1160 break;
1161 case V4L2_CID_PRIVATE_COMBFILTER:
1162 c->value = btv->opt_combfilter;
1163 break;
1164 case V4L2_CID_PRIVATE_LUMAFILTER:
1165 c->value = btv->opt_lumafilter;
1166 break;
1167 case V4L2_CID_PRIVATE_AUTOMUTE:
1168 c->value = btv->opt_automute;
1169 break;
1170 case V4L2_CID_PRIVATE_AGC_CRUSH:
1171 c->value = btv->opt_adc_crush;
1172 break;
1173 case V4L2_CID_PRIVATE_VCR_HACK:
1174 c->value = btv->opt_vcr_hack;
1175 break;
1176 case V4L2_CID_PRIVATE_WHITECRUSH_UPPER:
1177 c->value = btv->opt_whitecrush_upper;
1178 break;
1179 case V4L2_CID_PRIVATE_WHITECRUSH_LOWER:
1180 c->value = btv->opt_whitecrush_lower;
1181 break;
060d3027
MCC
1182 case V4L2_CID_PRIVATE_UV_RATIO:
1183 c->value = btv->opt_uv_ratio;
1184 break;
1185 case V4L2_CID_PRIVATE_FULL_LUMA_RANGE:
1186 c->value = btv->opt_full_luma_range;
1187 break;
1188 case V4L2_CID_PRIVATE_CORING:
1189 c->value = btv->opt_coring;
1190 break;
1da177e4
LT
1191 default:
1192 return -EINVAL;
1193 }
1194 return 0;
1195}
1196
1197static int set_control(struct bttv *btv, struct v4l2_control *c)
1198{
1199 struct video_audio va;
1200 int i,val;
1201
1202 for (i = 0; i < BTTV_CTLS; i++)
1203 if (bttv_ctls[i].id == c->id)
1204 break;
1205 if (i == BTTV_CTLS)
1206 return -EINVAL;
1207 if (i >= 4 && i <= 8) {
1208 memset(&va,0,sizeof(va));
1209 bttv_call_i2c_clients(btv, VIDIOCGAUDIO, &va);
1210 if (btv->audio_hook)
1211 btv->audio_hook(btv,&va,0);
1212 }
1213 switch (c->id) {
1214 case V4L2_CID_BRIGHTNESS:
1215 bt848_bright(btv,c->value);
1216 break;
1217 case V4L2_CID_HUE:
1218 bt848_hue(btv,c->value);
1219 break;
1220 case V4L2_CID_CONTRAST:
1221 bt848_contrast(btv,c->value);
1222 break;
1223 case V4L2_CID_SATURATION:
1224 bt848_sat(btv,c->value);
1225 break;
1226 case V4L2_CID_AUDIO_MUTE:
1227 if (c->value) {
1228 va.flags |= VIDEO_AUDIO_MUTE;
1229 audio_mux(btv, AUDIO_MUTE);
1230 } else {
1231 va.flags &= ~VIDEO_AUDIO_MUTE;
1232 audio_mux(btv, AUDIO_UNMUTE);
1233 }
1234 break;
1235
1236 case V4L2_CID_AUDIO_VOLUME:
1237 va.volume = c->value;
1238 break;
1239 case V4L2_CID_AUDIO_BALANCE:
1240 va.balance = c->value;
1241 break;
1242 case V4L2_CID_AUDIO_BASS:
1243 va.bass = c->value;
1244 break;
1245 case V4L2_CID_AUDIO_TREBLE:
1246 va.treble = c->value;
1247 break;
1248
1249 case V4L2_CID_PRIVATE_CHROMA_AGC:
1250 btv->opt_chroma_agc = c->value;
1251 val = btv->opt_chroma_agc ? BT848_SCLOOP_CAGC : 0;
1252 btwrite(val, BT848_E_SCLOOP);
1253 btwrite(val, BT848_O_SCLOOP);
1254 break;
1255 case V4L2_CID_PRIVATE_COMBFILTER:
1256 btv->opt_combfilter = c->value;
1257 break;
1258 case V4L2_CID_PRIVATE_LUMAFILTER:
1259 btv->opt_lumafilter = c->value;
1260 if (btv->opt_lumafilter) {
1261 btand(~BT848_CONTROL_LDEC, BT848_E_CONTROL);
1262 btand(~BT848_CONTROL_LDEC, BT848_O_CONTROL);
1263 } else {
1264 btor(BT848_CONTROL_LDEC, BT848_E_CONTROL);
1265 btor(BT848_CONTROL_LDEC, BT848_O_CONTROL);
1266 }
1267 break;
1268 case V4L2_CID_PRIVATE_AUTOMUTE:
1269 btv->opt_automute = c->value;
1270 break;
1271 case V4L2_CID_PRIVATE_AGC_CRUSH:
1272 btv->opt_adc_crush = c->value;
1273 btwrite(BT848_ADC_RESERVED | (btv->opt_adc_crush ? BT848_ADC_CRUSH : 0),
1274 BT848_ADC);
1275 break;
1276 case V4L2_CID_PRIVATE_VCR_HACK:
1277 btv->opt_vcr_hack = c->value;
1278 break;
1279 case V4L2_CID_PRIVATE_WHITECRUSH_UPPER:
1280 btv->opt_whitecrush_upper = c->value;
1281 btwrite(c->value, BT848_WC_UP);
1282 break;
1283 case V4L2_CID_PRIVATE_WHITECRUSH_LOWER:
1284 btv->opt_whitecrush_lower = c->value;
1285 btwrite(c->value, BT848_WC_DOWN);
1286 break;
060d3027
MCC
1287 case V4L2_CID_PRIVATE_UV_RATIO:
1288 btv->opt_uv_ratio = c->value;
1289 bt848_sat(btv, btv->saturation);
1290 break;
1291 case V4L2_CID_PRIVATE_FULL_LUMA_RANGE:
1292 btv->opt_full_luma_range = c->value;
1293 btaor((c->value<<7), ~BT848_OFORM_RANGE, BT848_OFORM);
1294 break;
1295 case V4L2_CID_PRIVATE_CORING:
1296 btv->opt_coring = c->value;
1297 btaor((c->value<<5), ~BT848_OFORM_CORE32, BT848_OFORM);
1298 break;
1da177e4
LT
1299 default:
1300 return -EINVAL;
1301 }
1302 if (i >= 4 && i <= 8) {
1303 bttv_call_i2c_clients(btv, VIDIOCSAUDIO, &va);
1304 if (btv->audio_hook)
1305 btv->audio_hook(btv,&va,1);
1306 }
1307 return 0;
1308}
1309
1310/* ----------------------------------------------------------------------- */
1311
1312void bttv_gpio_tracking(struct bttv *btv, char *comment)
1313{
1314 unsigned int outbits, data;
1315 outbits = btread(BT848_GPIO_OUT_EN);
1316 data = btread(BT848_GPIO_DATA);
1317 printk(KERN_DEBUG "bttv%d: gpio: en=%08x, out=%08x in=%08x [%s]\n",
1318 btv->c.nr,outbits,data & outbits, data & ~outbits, comment);
1319}
1320
1321static void bttv_field_count(struct bttv *btv)
1322{
1323 int need_count = 0;
1324
1325 if (btv->users)
1326 need_count++;
1327
1328 if (need_count) {
1329 /* start field counter */
1330 btor(BT848_INT_VSYNC,BT848_INT_MASK);
1331 } else {
1332 /* stop field counter */
1333 btand(~BT848_INT_VSYNC,BT848_INT_MASK);
1334 btv->field_count = 0;
1335 }
1336}
1337
1338static const struct bttv_format*
1339format_by_palette(int palette)
1340{
1341 unsigned int i;
1342
1343 for (i = 0; i < BTTV_FORMATS; i++) {
1344 if (-1 == bttv_formats[i].palette)
1345 continue;
1346 if (bttv_formats[i].palette == palette)
1347 return bttv_formats+i;
1348 }
1349 return NULL;
1350}
1351
1352static const struct bttv_format*
1353format_by_fourcc(int fourcc)
1354{
1355 unsigned int i;
1356
1357 for (i = 0; i < BTTV_FORMATS; i++) {
1358 if (-1 == bttv_formats[i].fourcc)
1359 continue;
1360 if (bttv_formats[i].fourcc == fourcc)
1361 return bttv_formats+i;
1362 }
1363 return NULL;
1364}
1365
1366/* ----------------------------------------------------------------------- */
1367/* misc helpers */
1368
1369static int
1370bttv_switch_overlay(struct bttv *btv, struct bttv_fh *fh,
1371 struct bttv_buffer *new)
1372{
1373 struct bttv_buffer *old;
1374 unsigned long flags;
1375 int retval = 0;
1376
1377 dprintk("switch_overlay: enter [new=%p]\n",new);
1378 if (new)
1379 new->vb.state = STATE_DONE;
1380 spin_lock_irqsave(&btv->s_lock,flags);
1381 old = btv->screen;
1382 btv->screen = new;
1383 btv->loop_irq |= 1;
1384 bttv_set_dma(btv, 0x03);
1385 spin_unlock_irqrestore(&btv->s_lock,flags);
1386 if (NULL == new)
1387 free_btres(btv,fh,RESOURCE_OVERLAY);
1388 if (NULL != old) {
1389 dprintk("switch_overlay: old=%p state is %d\n",old,old->vb.state);
1390 bttv_dma_free(btv, old);
1391 kfree(old);
1392 }
1393 dprintk("switch_overlay: done\n");
1394 return retval;
1395}
1396
1397/* ----------------------------------------------------------------------- */
1398/* video4linux (1) interface */
1399
1400static int bttv_prepare_buffer(struct bttv *btv, struct bttv_buffer *buf,
4ac97914 1401 const struct bttv_format *fmt,
1da177e4
LT
1402 unsigned int width, unsigned int height,
1403 enum v4l2_field field)
1404{
1405 int redo_dma_risc = 0;
1406 int rc;
1407
1408 /* check settings */
1409 if (NULL == fmt)
1410 return -EINVAL;
1411 if (fmt->btformat == BT848_COLOR_FMT_RAW) {
1412 width = RAW_BPL;
1413 height = RAW_LINES*2;
1414 if (width*height > buf->vb.bsize)
1415 return -EINVAL;
1416 buf->vb.size = buf->vb.bsize;
1417 } else {
1418 if (width < 48 ||
1419 height < 32 ||
1420 width > bttv_tvnorms[btv->tvnorm].swidth ||
1421 height > bttv_tvnorms[btv->tvnorm].sheight)
1422 return -EINVAL;
1423 buf->vb.size = (width * height * fmt->depth) >> 3;
1424 if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size)
1425 return -EINVAL;
1426 }
1427
1428 /* alloc + fill struct bttv_buffer (if changed) */
1429 if (buf->vb.width != width || buf->vb.height != height ||
1430 buf->vb.field != field ||
1431 buf->tvnorm != btv->tvnorm || buf->fmt != fmt) {
1432 buf->vb.width = width;
1433 buf->vb.height = height;
1434 buf->vb.field = field;
1435 buf->tvnorm = btv->tvnorm;
1436 buf->fmt = fmt;
1437 redo_dma_risc = 1;
1438 }
1439
1440 /* alloc risc memory */
1441 if (STATE_NEEDS_INIT == buf->vb.state) {
1442 redo_dma_risc = 1;
1443 if (0 != (rc = videobuf_iolock(btv->c.pci,&buf->vb,&btv->fbuf)))
1444 goto fail;
1445 }
1446
1447 if (redo_dma_risc)
1448 if (0 != (rc = bttv_buffer_risc(btv,buf)))
1449 goto fail;
1450
1451 buf->vb.state = STATE_PREPARED;
1452 return 0;
1453
1454 fail:
1455 bttv_dma_free(btv,buf);
1456 return rc;
1457}
1458
1459static int
1460buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
1461{
1462 struct bttv_fh *fh = q->priv_data;
1463
1464 *size = fh->fmt->depth*fh->width*fh->height >> 3;
1465 if (0 == *count)
1466 *count = gbuffers;
1467 while (*size * *count > gbuffers * gbufsize)
1468 (*count)--;
1469 return 0;
1470}
1471
1472static int
1473buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
1474 enum v4l2_field field)
1475{
1476 struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb);
1477 struct bttv_fh *fh = q->priv_data;
1478
1479 return bttv_prepare_buffer(fh->btv, buf, fh->fmt,
1480 fh->width, fh->height, field);
1481}
1482
1483static void
1484buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
1485{
1486 struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb);
1487 struct bttv_fh *fh = q->priv_data;
1488 struct bttv *btv = fh->btv;
1489
1490 buf->vb.state = STATE_QUEUED;
1491 list_add_tail(&buf->vb.queue,&btv->capture);
1492 if (!btv->curr.frame_irq) {
1493 btv->loop_irq |= 1;
1494 bttv_set_dma(btv, 0x03);
1495 }
1496}
1497
1498static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
1499{
1500 struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb);
1501 struct bttv_fh *fh = q->priv_data;
1502
1503 bttv_dma_free(fh->btv,buf);
1504}
1505
1506static struct videobuf_queue_ops bttv_video_qops = {
1507 .buf_setup = buffer_setup,
1508 .buf_prepare = buffer_prepare,
1509 .buf_queue = buffer_queue,
1510 .buf_release = buffer_release,
1511};
1512
1513static const char *v4l1_ioctls[] = {
1514 "?", "CGAP", "GCHAN", "SCHAN", "GTUNER", "STUNER", "GPICT", "SPICT",
1515 "CCAPTURE", "GWIN", "SWIN", "GFBUF", "SFBUF", "KEY", "GFREQ",
1516 "SFREQ", "GAUDIO", "SAUDIO", "SYNC", "MCAPTURE", "GMBUF", "GUNIT",
1517 "GCAPTURE", "SCAPTURE", "SPLAYMODE", "SWRITEMODE", "GPLAYINFO",
1518 "SMICROCODE", "GVBIFMT", "SVBIFMT" };
1519#define V4L1_IOCTLS ARRAY_SIZE(v4l1_ioctls)
1520
1521static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg)
1522{
1523 switch (cmd) {
4ac97914
MCC
1524 case BTTV_VERSION:
1525 return BTTV_VERSION_CODE;
1da177e4
LT
1526
1527 /* *** v4l1 *** ************************************************ */
1528 case VIDIOCGFREQ:
1529 {
1530 unsigned long *freq = arg;
1531 *freq = btv->freq;
1532 return 0;
1533 }
1534 case VIDIOCSFREQ:
1535 {
1536 unsigned long *freq = arg;
1537 down(&btv->lock);
1538 btv->freq=*freq;
1539 bttv_call_i2c_clients(btv,VIDIOCSFREQ,freq);
1540 if (btv->has_matchbox && btv->radio_user)
1541 tea5757_set_freq(btv,*freq);
1542 up(&btv->lock);
1543 return 0;
1544 }
1545
1546 case VIDIOCGTUNER:
1547 {
1548 struct video_tuner *v = arg;
1549
1550 if (UNSET == bttv_tvcards[btv->c.type].tuner)
1551 return -EINVAL;
1552 if (v->tuner) /* Only tuner 0 */
1553 return -EINVAL;
1554 strcpy(v->name, "Television");
1555 v->rangelow = 0;
1556 v->rangehigh = 0x7FFFFFFF;
1557 v->flags = VIDEO_TUNER_PAL|VIDEO_TUNER_NTSC|VIDEO_TUNER_SECAM;
1558 v->mode = btv->tvnorm;
1559 v->signal = (btread(BT848_DSTATUS)&BT848_DSTATUS_HLOC) ? 0xFFFF : 0;
1560 bttv_call_i2c_clients(btv,cmd,v);
1561 return 0;
1562 }
1563 case VIDIOCSTUNER:
1564 {
1565 struct video_tuner *v = arg;
1566
1567 if (v->tuner) /* Only tuner 0 */
1568 return -EINVAL;
1569 if (v->mode >= BTTV_TVNORMS)
1570 return -EINVAL;
1571
1572 down(&btv->lock);
1573 set_tvnorm(btv,v->mode);
1574 bttv_call_i2c_clients(btv,cmd,v);
1575 up(&btv->lock);
1576 return 0;
1577 }
1578
4ac97914
MCC
1579 case VIDIOCGCHAN:
1580 {
1581 struct video_channel *v = arg;
1da177e4
LT
1582 unsigned int channel = v->channel;
1583
4ac97914
MCC
1584 if (channel >= bttv_tvcards[btv->c.type].video_inputs)
1585 return -EINVAL;
1586 v->tuners=0;
1587 v->flags = VIDEO_VC_AUDIO;
1588 v->type = VIDEO_TYPE_CAMERA;
1589 v->norm = btv->tvnorm;
1da177e4 1590 if (channel == bttv_tvcards[btv->c.type].tuner) {
4ac97914
MCC
1591 strcpy(v->name,"Television");
1592 v->flags|=VIDEO_VC_TUNER;
1593 v->type=VIDEO_TYPE_TV;
1594 v->tuners=1;
1595 } else if (channel == btv->svhs) {
1596 strcpy(v->name,"S-Video");
1597 } else {
1598 sprintf(v->name,"Composite%d",channel);
1da177e4
LT
1599 }
1600 return 0;
4ac97914
MCC
1601 }
1602 case VIDIOCSCHAN:
1603 {
1604 struct video_channel *v = arg;
1da177e4
LT
1605 unsigned int channel = v->channel;
1606
1607 if (channel >= bttv_tvcards[btv->c.type].video_inputs)
1608 return -EINVAL;
1609 if (v->norm >= BTTV_TVNORMS)
1610 return -EINVAL;
1611
1612 down(&btv->lock);
1613 if (channel == btv->input &&
1614 v->norm == btv->tvnorm) {
1615 /* nothing to do */
1616 up(&btv->lock);
1617 return 0;
1618 }
1619
1620 btv->tvnorm = v->norm;
1621 set_input(btv,v->channel);
1622 up(&btv->lock);
1623 return 0;
1624 }
1625
4ac97914 1626 case VIDIOCGAUDIO:
1da177e4
LT
1627 {
1628 struct video_audio *v = arg;
1629
1630 memset(v,0,sizeof(*v));
1631 strcpy(v->name,"Television");
1632 v->flags |= VIDEO_AUDIO_MUTABLE;
1633 v->mode = VIDEO_SOUND_MONO;
1634
1635 down(&btv->lock);
1636 bttv_call_i2c_clients(btv,cmd,v);
1637
1638 /* card specific hooks */
1639 if (btv->audio_hook)
1640 btv->audio_hook(btv,v,0);
1641
1642 up(&btv->lock);
1643 return 0;
1644 }
1645 case VIDIOCSAUDIO:
1646 {
1647 struct video_audio *v = arg;
1648 unsigned int audio = v->audio;
1649
1650 if (audio >= bttv_tvcards[btv->c.type].audio_inputs)
1651 return -EINVAL;
1652
1653 down(&btv->lock);
1654 audio_mux(btv, (v->flags&VIDEO_AUDIO_MUTE) ? AUDIO_MUTE : AUDIO_UNMUTE);
1655 bttv_call_i2c_clients(btv,cmd,v);
1656
1657 /* card specific hooks */
1658 if (btv->audio_hook)
1659 btv->audio_hook(btv,v,1);
1660
1661 up(&btv->lock);
1662 return 0;
1663 }
1664
1665 /* *** v4l2 *** ************************************************ */
1666 case VIDIOC_ENUMSTD:
1667 {
1668 struct v4l2_standard *e = arg;
1669 unsigned int index = e->index;
1670
1671 if (index >= BTTV_TVNORMS)
1672 return -EINVAL;
1673 v4l2_video_std_construct(e, bttv_tvnorms[e->index].v4l2_id,
1674 bttv_tvnorms[e->index].name);
1675 e->index = index;
1676 return 0;
1677 }
1678 case VIDIOC_G_STD:
1679 {
1680 v4l2_std_id *id = arg;
1681 *id = bttv_tvnorms[btv->tvnorm].v4l2_id;
1682 return 0;
1683 }
1684 case VIDIOC_S_STD:
1685 {
1686 v4l2_std_id *id = arg;
1687 unsigned int i;
1688
1689 for (i = 0; i < BTTV_TVNORMS; i++)
1690 if (*id & bttv_tvnorms[i].v4l2_id)
1691 break;
1692 if (i == BTTV_TVNORMS)
1693 return -EINVAL;
1694
1695 down(&btv->lock);
1696 set_tvnorm(btv,i);
1697 i2c_vidiocschan(btv);
1698 up(&btv->lock);
1699 return 0;
1700 }
1701 case VIDIOC_QUERYSTD:
1702 {
1703 v4l2_std_id *id = arg;
1704
1705 if (btread(BT848_DSTATUS) & BT848_DSTATUS_NUML)
1706 *id = V4L2_STD_625_50;
1707 else
1708 *id = V4L2_STD_525_60;
1709 return 0;
1710 }
1711
1712 case VIDIOC_ENUMINPUT:
1713 {
1714 struct v4l2_input *i = arg;
1715 unsigned int n;
1716
1717 n = i->index;
1718 if (n >= bttv_tvcards[btv->c.type].video_inputs)
1719 return -EINVAL;
1720 memset(i,0,sizeof(*i));
1721 i->index = n;
1722 i->type = V4L2_INPUT_TYPE_CAMERA;
bbf7871e 1723 i->audioset = 0;
1da177e4
LT
1724 if (i->index == bttv_tvcards[btv->c.type].tuner) {
1725 sprintf(i->name, "Television");
1726 i->type = V4L2_INPUT_TYPE_TUNER;
1727 i->tuner = 0;
1728 } else if (i->index == btv->svhs) {
1729 sprintf(i->name, "S-Video");
1730 } else {
4ac97914 1731 sprintf(i->name,"Composite%d",i->index);
1da177e4
LT
1732 }
1733 if (i->index == btv->input) {
1734 __u32 dstatus = btread(BT848_DSTATUS);
1735 if (0 == (dstatus & BT848_DSTATUS_PRES))
1736 i->status |= V4L2_IN_ST_NO_SIGNAL;
1737 if (0 == (dstatus & BT848_DSTATUS_HLOC))
1738 i->status |= V4L2_IN_ST_NO_H_LOCK;
1739 }
1740 for (n = 0; n < BTTV_TVNORMS; n++)
1741 i->std |= bttv_tvnorms[n].v4l2_id;
1742 return 0;
1743 }
1744 case VIDIOC_G_INPUT:
1745 {
1746 int *i = arg;
1747 *i = btv->input;
1748 return 0;
1749 }
1750 case VIDIOC_S_INPUT:
1751 {
1752 unsigned int *i = arg;
1753
1754 if (*i > bttv_tvcards[btv->c.type].video_inputs)
1755 return -EINVAL;
1756 down(&btv->lock);
1757 set_input(btv,*i);
1758 up(&btv->lock);
1759 return 0;
1760 }
1761
1762 case VIDIOC_G_TUNER:
1763 {
1764 struct v4l2_tuner *t = arg;
1765
1766 if (UNSET == bttv_tvcards[btv->c.type].tuner)
1767 return -EINVAL;
1768 if (0 != t->index)
1769 return -EINVAL;
1770 down(&btv->lock);
1771 memset(t,0,sizeof(*t));
1772 strcpy(t->name, "Television");
1773 t->type = V4L2_TUNER_ANALOG_TV;
1da177e4
LT
1774 t->capability = V4L2_TUNER_CAP_NORM;
1775 t->rxsubchans = V4L2_TUNER_SUB_MONO;
1776 if (btread(BT848_DSTATUS)&BT848_DSTATUS_HLOC)
1777 t->signal = 0xffff;
bbf7871e
MS
1778 {
1779 struct video_tuner tuner;
1780
1781 memset(&tuner, 0, sizeof (tuner));
1782 tuner.rangehigh = 0xffffffffUL;
1783 bttv_call_i2c_clients(btv, VIDIOCGTUNER, &tuner);
1784 t->rangelow = tuner.rangelow;
1785 t->rangehigh = tuner.rangehigh;
1786 }
1da177e4
LT
1787 {
1788 /* Hmmm ... */
1789 struct video_audio va;
1790 memset(&va, 0, sizeof(struct video_audio));
1791 bttv_call_i2c_clients(btv, VIDIOCGAUDIO, &va);
1792 if (btv->audio_hook)
1793 btv->audio_hook(btv,&va,0);
1794 if(va.mode & VIDEO_SOUND_STEREO) {
1795 t->audmode = V4L2_TUNER_MODE_STEREO;
1796 t->rxsubchans |= V4L2_TUNER_SUB_STEREO;
1797 }
1798 if(va.mode & VIDEO_SOUND_LANG1) {
1799 t->audmode = V4L2_TUNER_MODE_LANG1;
1800 t->rxsubchans = V4L2_TUNER_SUB_LANG1
1801 | V4L2_TUNER_SUB_LANG2;
1802 }
1803 }
1804 /* FIXME: fill capability+audmode */
1805 up(&btv->lock);
1806 return 0;
1807 }
1808 case VIDIOC_S_TUNER:
1809 {
1810 struct v4l2_tuner *t = arg;
1811
1812 if (UNSET == bttv_tvcards[btv->c.type].tuner)
1813 return -EINVAL;
1814 if (0 != t->index)
1815 return -EINVAL;
1816 down(&btv->lock);
1817 {
1818 struct video_audio va;
1819 memset(&va, 0, sizeof(struct video_audio));
1820 bttv_call_i2c_clients(btv, VIDIOCGAUDIO, &va);
1821 if (t->audmode == V4L2_TUNER_MODE_MONO)
1822 va.mode = VIDEO_SOUND_MONO;
1823 else if (t->audmode == V4L2_TUNER_MODE_STEREO)
1824 va.mode = VIDEO_SOUND_STEREO;
1825 else if (t->audmode == V4L2_TUNER_MODE_LANG1)
1826 va.mode = VIDEO_SOUND_LANG1;
1827 else if (t->audmode == V4L2_TUNER_MODE_LANG2)
1828 va.mode = VIDEO_SOUND_LANG2;
1829 bttv_call_i2c_clients(btv, VIDIOCSAUDIO, &va);
1830 if (btv->audio_hook)
1831 btv->audio_hook(btv,&va,1);
1832 }
1833 up(&btv->lock);
1834 return 0;
1835 }
1836
1837 case VIDIOC_G_FREQUENCY:
1838 {
1839 struct v4l2_frequency *f = arg;
1840
1841 memset(f,0,sizeof(*f));
1842 f->type = V4L2_TUNER_ANALOG_TV;
1843 f->frequency = btv->freq;
1844 return 0;
1845 }
1846 case VIDIOC_S_FREQUENCY:
1847 {
1848 struct v4l2_frequency *f = arg;
1849
1850 if (unlikely(f->tuner != 0))
1851 return -EINVAL;
fa9846a8 1852 if (unlikely (f->type != V4L2_TUNER_ANALOG_TV))
1da177e4
LT
1853 return -EINVAL;
1854 down(&btv->lock);
1855 btv->freq = f->frequency;
1856 bttv_call_i2c_clients(btv,VIDIOCSFREQ,&btv->freq);
1857 if (btv->has_matchbox && btv->radio_user)
1858 tea5757_set_freq(btv,btv->freq);
1859 up(&btv->lock);
1860 return 0;
1861 }
299392bf
HV
1862 case VIDIOC_LOG_STATUS:
1863 {
97cb445d 1864 bttv_call_i2c_clients(btv, VIDIOC_LOG_STATUS, NULL);
299392bf
HV
1865 return 0;
1866 }
1da177e4
LT
1867
1868 default:
1869 return -ENOIOCTLCMD;
1870
1871 }
1872 return 0;
1873}
1874
1875static int verify_window(const struct bttv_tvnorm *tvn,
1876 struct v4l2_window *win, int fixup)
1877{
1878 enum v4l2_field field;
1879 int maxw, maxh;
1880
1881 if (win->w.width < 48 || win->w.height < 32)
1882 return -EINVAL;
1883 if (win->clipcount > 2048)
1884 return -EINVAL;
1885
1886 field = win->field;
1887 maxw = tvn->swidth;
1888 maxh = tvn->sheight;
1889
1890 if (V4L2_FIELD_ANY == field) {
1891 field = (win->w.height > maxh/2)
1892 ? V4L2_FIELD_INTERLACED
1893 : V4L2_FIELD_TOP;
1894 }
1895 switch (field) {
1896 case V4L2_FIELD_TOP:
1897 case V4L2_FIELD_BOTTOM:
1898 maxh = maxh / 2;
1899 break;
1900 case V4L2_FIELD_INTERLACED:
1901 break;
1902 default:
1903 return -EINVAL;
1904 }
1905
1906 if (!fixup && (win->w.width > maxw || win->w.height > maxh))
1907 return -EINVAL;
1908
1909 if (win->w.width > maxw)
1910 win->w.width = maxw;
1911 if (win->w.height > maxh)
1912 win->w.height = maxh;
1913 win->field = field;
1914 return 0;
1915}
1916
1917static int setup_window(struct bttv_fh *fh, struct bttv *btv,
1918 struct v4l2_window *win, int fixup)
1919{
1920 struct v4l2_clip *clips = NULL;
1921 int n,size,retval = 0;
1922
1923 if (NULL == fh->ovfmt)
1924 return -EINVAL;
1925 if (!(fh->ovfmt->flags & FORMAT_FLAGS_PACKED))
1926 return -EINVAL;
1927 retval = verify_window(&bttv_tvnorms[btv->tvnorm],win,fixup);
1928 if (0 != retval)
1929 return retval;
1930
1931 /* copy clips -- luckily v4l1 + v4l2 are binary
1932 compatible here ...*/
1933 n = win->clipcount;
1934 size = sizeof(*clips)*(n+4);
1935 clips = kmalloc(size,GFP_KERNEL);
1936 if (NULL == clips)
1937 return -ENOMEM;
1938 if (n > 0) {
1939 if (copy_from_user(clips,win->clips,sizeof(struct v4l2_clip)*n)) {
1940 kfree(clips);
1941 return -EFAULT;
1942 }
1943 }
1944 /* clip against screen */
1945 if (NULL != btv->fbuf.base)
1946 n = btcx_screen_clips(btv->fbuf.fmt.width, btv->fbuf.fmt.height,
1947 &win->w, clips, n);
1948 btcx_sort_clips(clips,n);
1949
1950 /* 4-byte alignments */
1951 switch (fh->ovfmt->depth) {
1952 case 8:
1953 case 24:
1954 btcx_align(&win->w, clips, n, 3);
1955 break;
1956 case 16:
1957 btcx_align(&win->w, clips, n, 1);
1958 break;
1959 case 32:
1960 /* no alignment fixups needed */
1961 break;
1962 default:
1963 BUG();
1964 }
1965
1966 down(&fh->cap.lock);
674434c6 1967 kfree(fh->ov.clips);
1da177e4
LT
1968 fh->ov.clips = clips;
1969 fh->ov.nclips = n;
1970
1971 fh->ov.w = win->w;
1972 fh->ov.field = win->field;
1973 fh->ov.setup_ok = 1;
1974 btv->init.ov.w.width = win->w.width;
1975 btv->init.ov.w.height = win->w.height;
1976 btv->init.ov.field = win->field;
1977
1978 /* update overlay if needed */
1979 retval = 0;
1980 if (check_btres(fh, RESOURCE_OVERLAY)) {
1981 struct bttv_buffer *new;
1982
1983 new = videobuf_alloc(sizeof(*new));
1984 bttv_overlay_risc(btv, &fh->ov, fh->ovfmt, new);
1985 retval = bttv_switch_overlay(btv,fh,new);
1986 }
1987 up(&fh->cap.lock);
1988 return retval;
1989}
1990
1991/* ----------------------------------------------------------------------- */
1992
1993static struct videobuf_queue* bttv_queue(struct bttv_fh *fh)
1994{
1995 struct videobuf_queue* q = NULL;
1996
1997 switch (fh->type) {
1998 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1999 q = &fh->cap;
2000 break;
2001 case V4L2_BUF_TYPE_VBI_CAPTURE:
2002 q = &fh->vbi;
2003 break;
2004 default:
2005 BUG();
2006 }
2007 return q;
2008}
2009
2010static int bttv_resource(struct bttv_fh *fh)
2011{
2012 int res = 0;
2013
2014 switch (fh->type) {
2015 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
2016 res = RESOURCE_VIDEO;
2017 break;
2018 case V4L2_BUF_TYPE_VBI_CAPTURE:
2019 res = RESOURCE_VBI;
2020 break;
2021 default:
2022 BUG();
2023 }
2024 return res;
2025}
2026
2027static int bttv_switch_type(struct bttv_fh *fh, enum v4l2_buf_type type)
2028{
2029 struct videobuf_queue *q = bttv_queue(fh);
2030 int res = bttv_resource(fh);
2031
2032 if (check_btres(fh,res))
2033 return -EBUSY;
2034 if (videobuf_queue_is_busy(q))
2035 return -EBUSY;
2036 fh->type = type;
2037 return 0;
2038}
2039
c87c948e
MS
2040static void
2041pix_format_set_size (struct v4l2_pix_format * f,
2042 const struct bttv_format * fmt,
2043 unsigned int width,
2044 unsigned int height)
2045{
2046 f->width = width;
2047 f->height = height;
2048
2049 if (fmt->flags & FORMAT_FLAGS_PLANAR) {
2050 f->bytesperline = width; /* Y plane */
2051 f->sizeimage = (width * height * fmt->depth) >> 3;
2052 } else {
2053 f->bytesperline = (width * fmt->depth) >> 3;
2054 f->sizeimage = height * f->bytesperline;
2055 }
2056}
2057
1da177e4
LT
2058static int bttv_g_fmt(struct bttv_fh *fh, struct v4l2_format *f)
2059{
2060 switch (f->type) {
2061 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
2062 memset(&f->fmt.pix,0,sizeof(struct v4l2_pix_format));
c87c948e
MS
2063 pix_format_set_size (&f->fmt.pix, fh->fmt,
2064 fh->width, fh->height);
1da177e4
LT
2065 f->fmt.pix.field = fh->cap.field;
2066 f->fmt.pix.pixelformat = fh->fmt->fourcc;
1da177e4
LT
2067 return 0;
2068 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
2069 memset(&f->fmt.win,0,sizeof(struct v4l2_window));
2070 f->fmt.win.w = fh->ov.w;
2071 f->fmt.win.field = fh->ov.field;
2072 return 0;
2073 case V4L2_BUF_TYPE_VBI_CAPTURE:
2074 bttv_vbi_get_fmt(fh,f);
2075 return 0;
2076 default:
2077 return -EINVAL;
2078 }
2079}
2080
2081static int bttv_try_fmt(struct bttv_fh *fh, struct bttv *btv,
2082 struct v4l2_format *f)
2083{
2084 switch (f->type) {
2085 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
2086 {
2087 const struct bttv_format *fmt;
2088 enum v4l2_field field;
2089 unsigned int maxw,maxh;
2090
2091 fmt = format_by_fourcc(f->fmt.pix.pixelformat);
2092 if (NULL == fmt)
2093 return -EINVAL;
2094
2095 /* fixup format */
2096 maxw = bttv_tvnorms[btv->tvnorm].swidth;
2097 maxh = bttv_tvnorms[btv->tvnorm].sheight;
2098 field = f->fmt.pix.field;
2099 if (V4L2_FIELD_ANY == field)
2100 field = (f->fmt.pix.height > maxh/2)
2101 ? V4L2_FIELD_INTERLACED
2102 : V4L2_FIELD_BOTTOM;
2103 if (V4L2_FIELD_SEQ_BT == field)
2104 field = V4L2_FIELD_SEQ_TB;
2105 switch (field) {
2106 case V4L2_FIELD_TOP:
2107 case V4L2_FIELD_BOTTOM:
2108 case V4L2_FIELD_ALTERNATE:
2109 maxh = maxh/2;
2110 break;
2111 case V4L2_FIELD_INTERLACED:
2112 break;
2113 case V4L2_FIELD_SEQ_TB:
2114 if (fmt->flags & FORMAT_FLAGS_PLANAR)
2115 return -EINVAL;
2116 break;
2117 default:
2118 return -EINVAL;
2119 }
2120
2121 /* update data for the application */
2122 f->fmt.pix.field = field;
2123 if (f->fmt.pix.width < 48)
2124 f->fmt.pix.width = 48;
2125 if (f->fmt.pix.height < 32)
2126 f->fmt.pix.height = 32;
2127 if (f->fmt.pix.width > maxw)
2128 f->fmt.pix.width = maxw;
2129 if (f->fmt.pix.height > maxh)
2130 f->fmt.pix.height = maxh;
c87c948e
MS
2131 pix_format_set_size (&f->fmt.pix, fmt,
2132 f->fmt.pix.width & ~3,
2133 f->fmt.pix.height);
1da177e4
LT
2134
2135 return 0;
2136 }
2137 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
2138 return verify_window(&bttv_tvnorms[btv->tvnorm],
2139 &f->fmt.win, 1);
2140 case V4L2_BUF_TYPE_VBI_CAPTURE:
2141 bttv_vbi_try_fmt(fh,f);
2142 return 0;
2143 default:
2144 return -EINVAL;
2145 }
2146}
2147
2148static int bttv_s_fmt(struct bttv_fh *fh, struct bttv *btv,
2149 struct v4l2_format *f)
2150{
2151 int retval;
2152
2153 switch (f->type) {
2154 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
2155 {
2156 const struct bttv_format *fmt;
2157
2158 retval = bttv_switch_type(fh,f->type);
2159 if (0 != retval)
2160 return retval;
2161 retval = bttv_try_fmt(fh,btv,f);
2162 if (0 != retval)
2163 return retval;
2164 fmt = format_by_fourcc(f->fmt.pix.pixelformat);
2165
2166 /* update our state informations */
2167 down(&fh->cap.lock);
2168 fh->fmt = fmt;
2169 fh->cap.field = f->fmt.pix.field;
2170 fh->cap.last = V4L2_FIELD_NONE;
2171 fh->width = f->fmt.pix.width;
2172 fh->height = f->fmt.pix.height;
2173 btv->init.fmt = fmt;
2174 btv->init.width = f->fmt.pix.width;
2175 btv->init.height = f->fmt.pix.height;
2176 up(&fh->cap.lock);
2177
2178 return 0;
2179 }
2180 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
4dcef524
MCC
2181 if (no_overlay > 0) {
2182 printk ("V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n");
2183 return -EINVAL;
2184 }
1da177e4
LT
2185 return setup_window(fh, btv, &f->fmt.win, 1);
2186 case V4L2_BUF_TYPE_VBI_CAPTURE:
2187 retval = bttv_switch_type(fh,f->type);
2188 if (0 != retval)
2189 return retval;
2190 if (locked_btres(fh->btv, RESOURCE_VBI))
4ac97914 2191 return -EBUSY;
1da177e4
LT
2192 bttv_vbi_try_fmt(fh,f);
2193 bttv_vbi_setlines(fh,btv,f->fmt.vbi.count[0]);
2194 bttv_vbi_get_fmt(fh,f);
2195 return 0;
2196 default:
2197 return -EINVAL;
2198 }
2199}
2200
2201static int bttv_do_ioctl(struct inode *inode, struct file *file,
2202 unsigned int cmd, void *arg)
2203{
2204 struct bttv_fh *fh = file->private_data;
2205 struct bttv *btv = fh->btv;
2206 unsigned long flags;
2207 int retval = 0;
2208
2209 if (bttv_debug > 1) {
2210 switch (_IOC_TYPE(cmd)) {
2211 case 'v':
2212 printk("bttv%d: ioctl 0x%x (v4l1, VIDIOC%s)\n",
2213 btv->c.nr, cmd, (_IOC_NR(cmd) < V4L1_IOCTLS) ?
2214 v4l1_ioctls[_IOC_NR(cmd)] : "???");
2215 break;
2216 case 'V':
2217 printk("bttv%d: ioctl 0x%x (v4l2, %s)\n",
2218 btv->c.nr, cmd, v4l2_ioctl_names[_IOC_NR(cmd)]);
2219 break;
2220 default:
2221 printk("bttv%d: ioctl 0x%x (???)\n",
2222 btv->c.nr, cmd);
2223 }
2224 }
2225 if (btv->errors)
2226 bttv_reinit_bt848(btv);
2227
2228 switch (cmd) {
4ac97914
MCC
2229 case VIDIOCSFREQ:
2230 case VIDIOCSTUNER:
2231 case VIDIOCSCHAN:
1da177e4
LT
2232 case VIDIOC_S_CTRL:
2233 case VIDIOC_S_STD:
2234 case VIDIOC_S_INPUT:
2235 case VIDIOC_S_TUNER:
2236 case VIDIOC_S_FREQUENCY:
2237 retval = v4l2_prio_check(&btv->prio,&fh->prio);
2238 if (0 != retval)
2239 return retval;
2240 };
2241
2242 switch (cmd) {
2243
2244 /* *** v4l1 *** ************************************************ */
2245 case VIDIOCGCAP:
2246 {
4ac97914 2247 struct video_capability *cap = arg;
1da177e4
LT
2248
2249 memset(cap,0,sizeof(*cap));
4ac97914 2250 strcpy(cap->name,btv->video_dev->name);
1da177e4
LT
2251 if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) {
2252 /* vbi */
2253 cap->type = VID_TYPE_TUNER|VID_TYPE_TELETEXT;
2254 } else {
2255 /* others */
2256 cap->type = VID_TYPE_CAPTURE|
2257 VID_TYPE_TUNER|
1da177e4
LT
2258 VID_TYPE_CLIPPING|
2259 VID_TYPE_SCALES;
4dcef524
MCC
2260 if (no_overlay <= 0)
2261 cap->type |= VID_TYPE_OVERLAY;
2262
1da177e4
LT
2263 cap->maxwidth = bttv_tvnorms[btv->tvnorm].swidth;
2264 cap->maxheight = bttv_tvnorms[btv->tvnorm].sheight;
2265 cap->minwidth = 48;
2266 cap->minheight = 32;
2267 }
2268 cap->channels = bttv_tvcards[btv->c.type].video_inputs;
2269 cap->audios = bttv_tvcards[btv->c.type].audio_inputs;
4ac97914 2270 return 0;
1da177e4
LT
2271 }
2272
2273 case VIDIOCGPICT:
2274 {
2275 struct video_picture *pic = arg;
2276
2277 memset(pic,0,sizeof(*pic));
2278 pic->brightness = btv->bright;
2279 pic->contrast = btv->contrast;
2280 pic->hue = btv->hue;
2281 pic->colour = btv->saturation;
2282 if (fh->fmt) {
2283 pic->depth = fh->fmt->depth;
2284 pic->palette = fh->fmt->palette;
2285 }
2286 return 0;
2287 }
2288 case VIDIOCSPICT:
2289 {
2290 struct video_picture *pic = arg;
2291 const struct bttv_format *fmt;
2292
2293 fmt = format_by_palette(pic->palette);
2294 if (NULL == fmt)
2295 return -EINVAL;
2296 down(&fh->cap.lock);
2297 if (fmt->depth != pic->depth) {
2298 retval = -EINVAL;
2299 goto fh_unlock_and_return;
2300 }
13c72805
MS
2301 if (fmt->flags & FORMAT_FLAGS_RAW) {
2302 /* VIDIOCMCAPTURE uses gbufsize, not RAW_BPL *
2303 RAW_LINES * 2. F1 is stored at offset 0, F2
2304 at buffer size / 2. */
2305 fh->width = RAW_BPL;
2306 fh->height = gbufsize / RAW_BPL;
2307 btv->init.width = RAW_BPL;
2308 btv->init.height = gbufsize / RAW_BPL;
2309 }
1da177e4
LT
2310 fh->ovfmt = fmt;
2311 fh->fmt = fmt;
2312 btv->init.ovfmt = fmt;
2313 btv->init.fmt = fmt;
2314 if (bigendian) {
2315 /* dirty hack time: swap bytes for overlay if the
2316 display adaptor is big endian (insmod option) */
2317 if (fmt->palette == VIDEO_PALETTE_RGB555 ||
2318 fmt->palette == VIDEO_PALETTE_RGB565 ||
2319 fmt->palette == VIDEO_PALETTE_RGB32) {
2320 fh->ovfmt = fmt+1;
2321 }
2322 }
2323 bt848_bright(btv,pic->brightness);
2324 bt848_contrast(btv,pic->contrast);
2325 bt848_hue(btv,pic->hue);
2326 bt848_sat(btv,pic->colour);
2327 up(&fh->cap.lock);
4ac97914 2328 return 0;
1da177e4
LT
2329 }
2330
2331 case VIDIOCGWIN:
2332 {
2333 struct video_window *win = arg;
2334
2335 memset(win,0,sizeof(*win));
2336 win->x = fh->ov.w.left;
2337 win->y = fh->ov.w.top;
2338 win->width = fh->ov.w.width;
2339 win->height = fh->ov.w.height;
2340 return 0;
2341 }
2342 case VIDIOCSWIN:
2343 {
2344 struct video_window *win = arg;
2345 struct v4l2_window w2;
2346
4dcef524
MCC
2347 if (no_overlay > 0) {
2348 printk ("VIDIOCSWIN: no_overlay\n");
2349 return -EINVAL;
2350 }
2351
1da177e4
LT
2352 w2.field = V4L2_FIELD_ANY;
2353 w2.w.left = win->x;
2354 w2.w.top = win->y;
2355 w2.w.width = win->width;
2356 w2.w.height = win->height;
2357 w2.clipcount = win->clipcount;
2358 w2.clips = (struct v4l2_clip __user *)win->clips;
2359 retval = setup_window(fh, btv, &w2, 0);
2360 if (0 == retval) {
2361 /* on v4l1 this ioctl affects the read() size too */
2362 fh->width = fh->ov.w.width;
2363 fh->height = fh->ov.w.height;
2364 btv->init.width = fh->ov.w.width;
2365 btv->init.height = fh->ov.w.height;
2366 }
2367 return retval;
2368 }
2369
2370 case VIDIOCGFBUF:
2371 {
2372 struct video_buffer *fbuf = arg;
2373
2374 fbuf->base = btv->fbuf.base;
2375 fbuf->width = btv->fbuf.fmt.width;
2376 fbuf->height = btv->fbuf.fmt.height;
2377 fbuf->bytesperline = btv->fbuf.fmt.bytesperline;
2378 if (fh->ovfmt)
2379 fbuf->depth = fh->ovfmt->depth;
2380 return 0;
2381 }
2382 case VIDIOCSFBUF:
2383 {
2384 struct video_buffer *fbuf = arg;
2385 const struct bttv_format *fmt;
2386 unsigned long end;
2387
2388 if(!capable(CAP_SYS_ADMIN) &&
4ac97914
MCC
2389 !capable(CAP_SYS_RAWIO))
2390 return -EPERM;
1da177e4
LT
2391 end = (unsigned long)fbuf->base +
2392 fbuf->height * fbuf->bytesperline;
2393 down(&fh->cap.lock);
2394 retval = -EINVAL;
2395
2396 switch (fbuf->depth) {
2397 case 8:
2398 fmt = format_by_palette(VIDEO_PALETTE_HI240);
2399 break;
2400 case 16:
2401 fmt = format_by_palette(VIDEO_PALETTE_RGB565);
2402 break;
2403 case 24:
2404 fmt = format_by_palette(VIDEO_PALETTE_RGB24);
2405 break;
2406 case 32:
2407 fmt = format_by_palette(VIDEO_PALETTE_RGB32);
2408 break;
2409 case 15:
2410 fbuf->depth = 16;
2411 fmt = format_by_palette(VIDEO_PALETTE_RGB555);
2412 break;
2413 default:
2414 fmt = NULL;
2415 break;
2416 }
2417 if (NULL == fmt)
2418 goto fh_unlock_and_return;
2419
2420 fh->ovfmt = fmt;
2421 fh->fmt = fmt;
2422 btv->init.ovfmt = fmt;
2423 btv->init.fmt = fmt;
2424 btv->fbuf.base = fbuf->base;
2425 btv->fbuf.fmt.width = fbuf->width;
2426 btv->fbuf.fmt.height = fbuf->height;
2427 if (fbuf->bytesperline)
2428 btv->fbuf.fmt.bytesperline = fbuf->bytesperline;
2429 else
2430 btv->fbuf.fmt.bytesperline = btv->fbuf.fmt.width*fbuf->depth/8;
2431 up(&fh->cap.lock);
2432 return 0;
2433 }
2434
2435 case VIDIOCCAPTURE:
2436 case VIDIOC_OVERLAY:
2437 {
2438 struct bttv_buffer *new;
2439 int *on = arg;
2440
2441 if (*on) {
2442 /* verify args */
2443 if (NULL == btv->fbuf.base)
2444 return -EINVAL;
2445 if (!fh->ov.setup_ok) {
2446 dprintk("bttv%d: overlay: !setup_ok\n",btv->c.nr);
2447 return -EINVAL;
2448 }
2449 }
2450
2451 if (!check_alloc_btres(btv,fh,RESOURCE_OVERLAY))
2452 return -EBUSY;
2453
2454 down(&fh->cap.lock);
2455 if (*on) {
2456 fh->ov.tvnorm = btv->tvnorm;
2457 new = videobuf_alloc(sizeof(*new));
2458 bttv_overlay_risc(btv, &fh->ov, fh->ovfmt, new);
2459 } else {
2460 new = NULL;
2461 }
2462
2463 /* switch over */
4ac97914 2464 retval = bttv_switch_overlay(btv,fh,new);
1da177e4
LT
2465 up(&fh->cap.lock);
2466 return retval;
2467 }
2468
2469 case VIDIOCGMBUF:
2470 {
2471 struct video_mbuf *mbuf = arg;
2472 unsigned int i;
2473
2474 down(&fh->cap.lock);
2475 retval = videobuf_mmap_setup(&fh->cap,gbuffers,gbufsize,
2476 V4L2_MEMORY_MMAP);
2477 if (retval < 0)
2478 goto fh_unlock_and_return;
2479 memset(mbuf,0,sizeof(*mbuf));
2480 mbuf->frames = gbuffers;
2481 mbuf->size = gbuffers * gbufsize;
2482 for (i = 0; i < gbuffers; i++)
2483 mbuf->offsets[i] = i * gbufsize;
2484 up(&fh->cap.lock);
2485 return 0;
2486 }
2487 case VIDIOCMCAPTURE:
2488 {
2489 struct video_mmap *vm = arg;
2490 struct bttv_buffer *buf;
2491 enum v4l2_field field;
2492
2493 if (vm->frame >= VIDEO_MAX_FRAME)
2494 return -EINVAL;
2495
2496 down(&fh->cap.lock);
2497 retval = -EINVAL;
2498 buf = (struct bttv_buffer *)fh->cap.bufs[vm->frame];
2499 if (NULL == buf)
2500 goto fh_unlock_and_return;
2501 if (0 == buf->vb.baddr)
2502 goto fh_unlock_and_return;
2503 if (buf->vb.state == STATE_QUEUED ||
2504 buf->vb.state == STATE_ACTIVE)
2505 goto fh_unlock_and_return;
2506
2507 field = (vm->height > bttv_tvnorms[btv->tvnorm].sheight/2)
2508 ? V4L2_FIELD_INTERLACED
2509 : V4L2_FIELD_BOTTOM;
2510 retval = bttv_prepare_buffer(btv,buf,
2511 format_by_palette(vm->format),
2512 vm->width,vm->height,field);
2513 if (0 != retval)
2514 goto fh_unlock_and_return;
2515 spin_lock_irqsave(&btv->s_lock,flags);
2516 buffer_queue(&fh->cap,&buf->vb);
2517 spin_unlock_irqrestore(&btv->s_lock,flags);
2518 up(&fh->cap.lock);
2519 return 0;
2520 }
2521 case VIDIOCSYNC:
2522 {
2523 int *frame = arg;
2524 struct bttv_buffer *buf;
2525
2526 if (*frame >= VIDEO_MAX_FRAME)
2527 return -EINVAL;
2528
2529 down(&fh->cap.lock);
2530 retval = -EINVAL;
2531 buf = (struct bttv_buffer *)fh->cap.bufs[*frame];
2532 if (NULL == buf)
2533 goto fh_unlock_and_return;
2534 retval = videobuf_waiton(&buf->vb,0,1);
2535 if (0 != retval)
2536 goto fh_unlock_and_return;
2537 switch (buf->vb.state) {
2538 case STATE_ERROR:
2539 retval = -EIO;
2540 /* fall through */
2541 case STATE_DONE:
2542 videobuf_dma_pci_sync(btv->c.pci,&buf->vb.dma);
2543 bttv_dma_free(btv,buf);
2544 break;
2545 default:
2546 retval = -EINVAL;
2547 break;
2548 }
2549 up(&fh->cap.lock);
2550 return retval;
2551 }
2552
2553 case VIDIOCGVBIFMT:
2554 {
2555 struct vbi_format *fmt = (void *) arg;
2556 struct v4l2_format fmt2;
2557
2558 if (fh->type != V4L2_BUF_TYPE_VBI_CAPTURE) {
2559 retval = bttv_switch_type(fh,V4L2_BUF_TYPE_VBI_CAPTURE);
2560 if (0 != retval)
2561 return retval;
2562 }
2563 bttv_vbi_get_fmt(fh, &fmt2);
2564
2565 memset(fmt,0,sizeof(*fmt));
2566 fmt->sampling_rate = fmt2.fmt.vbi.sampling_rate;
2567 fmt->samples_per_line = fmt2.fmt.vbi.samples_per_line;
2568 fmt->sample_format = VIDEO_PALETTE_RAW;
2569 fmt->start[0] = fmt2.fmt.vbi.start[0];
2570 fmt->count[0] = fmt2.fmt.vbi.count[0];
2571 fmt->start[1] = fmt2.fmt.vbi.start[1];
2572 fmt->count[1] = fmt2.fmt.vbi.count[1];
2573 if (fmt2.fmt.vbi.flags & VBI_UNSYNC)
2574 fmt->flags |= V4L2_VBI_UNSYNC;
2575 if (fmt2.fmt.vbi.flags & VBI_INTERLACED)
2576 fmt->flags |= V4L2_VBI_INTERLACED;
2577 return 0;
2578 }
2579 case VIDIOCSVBIFMT:
2580 {
2581 struct vbi_format *fmt = (void *) arg;
2582 struct v4l2_format fmt2;
2583
2584 retval = bttv_switch_type(fh,V4L2_BUF_TYPE_VBI_CAPTURE);
2585 if (0 != retval)
2586 return retval;
2587 bttv_vbi_get_fmt(fh, &fmt2);
2588
2589 if (fmt->sampling_rate != fmt2.fmt.vbi.sampling_rate ||
2590 fmt->samples_per_line != fmt2.fmt.vbi.samples_per_line ||
2591 fmt->sample_format != VIDEO_PALETTE_RAW ||
2592 fmt->start[0] != fmt2.fmt.vbi.start[0] ||
2593 fmt->start[1] != fmt2.fmt.vbi.start[1] ||
2594 fmt->count[0] != fmt->count[1] ||
2595 fmt->count[0] < 1 ||
2596 fmt->count[0] > 32 /* VBI_MAXLINES */)
2597 return -EINVAL;
2598
2599 bttv_vbi_setlines(fh,btv,fmt->count[0]);
2600 return 0;
2601 }
2602
4ac97914
MCC
2603 case BTTV_VERSION:
2604 case VIDIOCGFREQ:
2605 case VIDIOCSFREQ:
2606 case VIDIOCGTUNER:
2607 case VIDIOCSTUNER:
2608 case VIDIOCGCHAN:
2609 case VIDIOCSCHAN:
1da177e4
LT
2610 case VIDIOCGAUDIO:
2611 case VIDIOCSAUDIO:
2612 return bttv_common_ioctls(btv,cmd,arg);
2613
2614 /* *** v4l2 *** ************************************************ */
2615 case VIDIOC_QUERYCAP:
2616 {
2617 struct v4l2_capability *cap = arg;
2618
2619 if (0 == v4l2)
2620 return -EINVAL;
bbf7871e
MS
2621 memset(cap, 0, sizeof (*cap));
2622 strlcpy(cap->driver, "bttv", sizeof (cap->driver));
2623 strlcpy(cap->card, btv->video_dev->name, sizeof (cap->card));
2624 snprintf(cap->bus_info, sizeof (cap->bus_info),
2625 "PCI:%s", pci_name(btv->c.pci));
1da177e4
LT
2626 cap->version = BTTV_VERSION_CODE;
2627 cap->capabilities =
2628 V4L2_CAP_VIDEO_CAPTURE |
1da177e4
LT
2629 V4L2_CAP_VBI_CAPTURE |
2630 V4L2_CAP_READWRITE |
2631 V4L2_CAP_STREAMING;
4dcef524
MCC
2632 if (no_overlay <= 0)
2633 cap->capabilities |= V4L2_CAP_VIDEO_OVERLAY;
2634
1da177e4
LT
2635 if (bttv_tvcards[btv->c.type].tuner != UNSET &&
2636 bttv_tvcards[btv->c.type].tuner != TUNER_ABSENT)
2637 cap->capabilities |= V4L2_CAP_TUNER;
2638 return 0;
2639 }
2640
2641 case VIDIOC_ENUM_FMT:
2642 {
2643 struct v4l2_fmtdesc *f = arg;
2644 enum v4l2_buf_type type;
2645 unsigned int i;
2646 int index;
2647
2648 type = f->type;
2649 if (V4L2_BUF_TYPE_VBI_CAPTURE == type) {
2650 /* vbi */
2651 index = f->index;
2652 if (0 != index)
2653 return -EINVAL;
2654 memset(f,0,sizeof(*f));
2655 f->index = index;
2656 f->type = type;
2657 f->pixelformat = V4L2_PIX_FMT_GREY;
2658 strcpy(f->description,"vbi data");
2659 return 0;
2660 }
2661
2662 /* video capture + overlay */
2663 index = -1;
2664 for (i = 0; i < BTTV_FORMATS; i++) {
2665 if (bttv_formats[i].fourcc != -1)
2666 index++;
2667 if ((unsigned int)index == f->index)
2668 break;
2669 }
2670 if (BTTV_FORMATS == i)
2671 return -EINVAL;
2672
2673 switch (f->type) {
2674 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
2675 break;
2676 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
2677 if (!(bttv_formats[i].flags & FORMAT_FLAGS_PACKED))
2678 return -EINVAL;
2679 break;
2680 default:
2681 return -EINVAL;
2682 }
2683 memset(f,0,sizeof(*f));
2684 f->index = index;
2685 f->type = type;
2686 f->pixelformat = bttv_formats[i].fourcc;
2687 strlcpy(f->description,bttv_formats[i].name,sizeof(f->description));
2688 return 0;
2689 }
2690
2691 case VIDIOC_TRY_FMT:
2692 {
2693 struct v4l2_format *f = arg;
2694 return bttv_try_fmt(fh,btv,f);
2695 }
2696 case VIDIOC_G_FMT:
2697 {
2698 struct v4l2_format *f = arg;
2699 return bttv_g_fmt(fh,f);
2700 }
2701 case VIDIOC_S_FMT:
2702 {
2703 struct v4l2_format *f = arg;
2704 return bttv_s_fmt(fh,btv,f);
2705 }
2706
2707 case VIDIOC_G_FBUF:
2708 {
2709 struct v4l2_framebuffer *fb = arg;
2710
2711 *fb = btv->fbuf;
2712 fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING;
2713 if (fh->ovfmt)
2714 fb->fmt.pixelformat = fh->ovfmt->fourcc;
2715 return 0;
2716 }
2717 case VIDIOC_S_FBUF:
2718 {
2719 struct v4l2_framebuffer *fb = arg;
2720 const struct bttv_format *fmt;
2721
2722 if(!capable(CAP_SYS_ADMIN) &&
2723 !capable(CAP_SYS_RAWIO))
2724 return -EPERM;
2725
2726 /* check args */
2727 fmt = format_by_fourcc(fb->fmt.pixelformat);
2728 if (NULL == fmt)
2729 return -EINVAL;
2730 if (0 == (fmt->flags & FORMAT_FLAGS_PACKED))
2731 return -EINVAL;
2732
2733 down(&fh->cap.lock);
2734 retval = -EINVAL;
2735 if (fb->flags & V4L2_FBUF_FLAG_OVERLAY) {
2736 if (fb->fmt.width > bttv_tvnorms[btv->tvnorm].swidth)
2737 goto fh_unlock_and_return;
2738 if (fb->fmt.height > bttv_tvnorms[btv->tvnorm].sheight)
2739 goto fh_unlock_and_return;
2740 }
2741
2742 /* ok, accept it */
2743 btv->fbuf.base = fb->base;
2744 btv->fbuf.fmt.width = fb->fmt.width;
2745 btv->fbuf.fmt.height = fb->fmt.height;
2746 if (0 != fb->fmt.bytesperline)
2747 btv->fbuf.fmt.bytesperline = fb->fmt.bytesperline;
2748 else
2749 btv->fbuf.fmt.bytesperline = btv->fbuf.fmt.width*fmt->depth/8;
2750
2751 retval = 0;
2752 fh->ovfmt = fmt;
2753 btv->init.ovfmt = fmt;
2754 if (fb->flags & V4L2_FBUF_FLAG_OVERLAY) {
2755 fh->ov.w.left = 0;
2756 fh->ov.w.top = 0;
2757 fh->ov.w.width = fb->fmt.width;
2758 fh->ov.w.height = fb->fmt.height;
2759 btv->init.ov.w.width = fb->fmt.width;
2760 btv->init.ov.w.height = fb->fmt.height;
674434c6 2761 kfree(fh->ov.clips);
1da177e4
LT
2762 fh->ov.clips = NULL;
2763 fh->ov.nclips = 0;
2764
2765 if (check_btres(fh, RESOURCE_OVERLAY)) {
2766 struct bttv_buffer *new;
2767
2768 new = videobuf_alloc(sizeof(*new));
2769 bttv_overlay_risc(btv,&fh->ov,fh->ovfmt,new);
2770 retval = bttv_switch_overlay(btv,fh,new);
2771 }
2772 }
2773 up(&fh->cap.lock);
2774 return retval;
2775 }
2776
2777 case VIDIOC_REQBUFS:
2778 return videobuf_reqbufs(bttv_queue(fh),arg);
2779
2780 case VIDIOC_QUERYBUF:
2781 return videobuf_querybuf(bttv_queue(fh),arg);
2782
2783 case VIDIOC_QBUF:
2784 return videobuf_qbuf(bttv_queue(fh),arg);
2785
2786 case VIDIOC_DQBUF:
2787 return videobuf_dqbuf(bttv_queue(fh),arg,
2788 file->f_flags & O_NONBLOCK);
2789
2790 case VIDIOC_STREAMON:
2791 {
2792 int res = bttv_resource(fh);
2793
2794 if (!check_alloc_btres(btv,fh,res))
2795 return -EBUSY;
2796 return videobuf_streamon(bttv_queue(fh));
2797 }
2798 case VIDIOC_STREAMOFF:
2799 {
2800 int res = bttv_resource(fh);
2801
2802 retval = videobuf_streamoff(bttv_queue(fh));
2803 if (retval < 0)
2804 return retval;
2805 free_btres(btv,fh,res);
2806 return 0;
2807 }
2808
2809 case VIDIOC_QUERYCTRL:
2810 {
2811 struct v4l2_queryctrl *c = arg;
2812 int i;
2813
2814 if ((c->id < V4L2_CID_BASE ||
2815 c->id >= V4L2_CID_LASTP1) &&
2816 (c->id < V4L2_CID_PRIVATE_BASE ||
2817 c->id >= V4L2_CID_PRIVATE_LASTP1))
2818 return -EINVAL;
2819 for (i = 0; i < BTTV_CTLS; i++)
2820 if (bttv_ctls[i].id == c->id)
2821 break;
2822 if (i == BTTV_CTLS) {
2823 *c = no_ctl;
2824 return 0;
2825 }
2826 *c = bttv_ctls[i];
2827 if (i >= 4 && i <= 8) {
2828 struct video_audio va;
2829 memset(&va,0,sizeof(va));
2830 bttv_call_i2c_clients(btv, VIDIOCGAUDIO, &va);
2831 if (btv->audio_hook)
2832 btv->audio_hook(btv,&va,0);
2833 switch (bttv_ctls[i].id) {
2834 case V4L2_CID_AUDIO_VOLUME:
2835 if (!(va.flags & VIDEO_AUDIO_VOLUME))
2836 *c = no_ctl;
2837 break;
2838 case V4L2_CID_AUDIO_BALANCE:
2839 if (!(va.flags & VIDEO_AUDIO_BALANCE))
2840 *c = no_ctl;
2841 break;
2842 case V4L2_CID_AUDIO_BASS:
2843 if (!(va.flags & VIDEO_AUDIO_BASS))
2844 *c = no_ctl;
2845 break;
2846 case V4L2_CID_AUDIO_TREBLE:
2847 if (!(va.flags & VIDEO_AUDIO_TREBLE))
2848 *c = no_ctl;
2849 break;
2850 }
2851 }
2852 return 0;
2853 }
2854 case VIDIOC_G_CTRL:
2855 return get_control(btv,arg);
2856 case VIDIOC_S_CTRL:
2857 return set_control(btv,arg);
2858 case VIDIOC_G_PARM:
2859 {
2860 struct v4l2_streamparm *parm = arg;
2861 struct v4l2_standard s;
2862 if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
2863 return -EINVAL;
2864 memset(parm,0,sizeof(*parm));
2865 v4l2_video_std_construct(&s, bttv_tvnorms[btv->tvnorm].v4l2_id,
2866 bttv_tvnorms[btv->tvnorm].name);
2867 parm->parm.capture.timeperframe = s.frameperiod;
2868 return 0;
2869 }
2870
2871 case VIDIOC_G_PRIORITY:
2872 {
2873 enum v4l2_priority *p = arg;
2874
2875 *p = v4l2_prio_max(&btv->prio);
2876 return 0;
2877 }
2878 case VIDIOC_S_PRIORITY:
2879 {
2880 enum v4l2_priority *prio = arg;
2881
2882 return v4l2_prio_change(&btv->prio, &fh->prio, *prio);
2883 }
2884
2885 case VIDIOC_ENUMSTD:
2886 case VIDIOC_G_STD:
2887 case VIDIOC_S_STD:
2888 case VIDIOC_ENUMINPUT:
2889 case VIDIOC_G_INPUT:
2890 case VIDIOC_S_INPUT:
2891 case VIDIOC_G_TUNER:
2892 case VIDIOC_S_TUNER:
2893 case VIDIOC_G_FREQUENCY:
2894 case VIDIOC_S_FREQUENCY:
299392bf 2895 case VIDIOC_LOG_STATUS:
1da177e4
LT
2896 return bttv_common_ioctls(btv,cmd,arg);
2897
2898 default:
2899 return -ENOIOCTLCMD;
2900 }
2901 return 0;
2902
2903 fh_unlock_and_return:
2904 up(&fh->cap.lock);
2905 return retval;
2906}
2907
2908static int bttv_ioctl(struct inode *inode, struct file *file,
2909 unsigned int cmd, unsigned long arg)
2910{
2911 struct bttv_fh *fh = file->private_data;
2912
2913 switch (cmd) {
2914 case BTTV_VBISIZE:
2915 bttv_switch_type(fh,V4L2_BUF_TYPE_VBI_CAPTURE);
2916 return fh->lines * 2 * 2048;
2917 default:
2918 return video_usercopy(inode, file, cmd, arg, bttv_do_ioctl);
2919 }
2920}
2921
2922static ssize_t bttv_read(struct file *file, char __user *data,
2923 size_t count, loff_t *ppos)
2924{
2925 struct bttv_fh *fh = file->private_data;
2926 int retval = 0;
2927
2928 if (fh->btv->errors)
2929 bttv_reinit_bt848(fh->btv);
2930 dprintk("bttv%d: read count=%d type=%s\n",
2931 fh->btv->c.nr,(int)count,v4l2_type_names[fh->type]);
2932
2933 switch (fh->type) {
2934 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
2935 if (locked_btres(fh->btv,RESOURCE_VIDEO))
2936 return -EBUSY;
2937 retval = videobuf_read_one(&fh->cap, data, count, ppos,
2938 file->f_flags & O_NONBLOCK);
2939 break;
2940 case V4L2_BUF_TYPE_VBI_CAPTURE:
2941 if (!check_alloc_btres(fh->btv,fh,RESOURCE_VBI))
2942 return -EBUSY;
2943 retval = videobuf_read_stream(&fh->vbi, data, count, ppos, 1,
2944 file->f_flags & O_NONBLOCK);
2945 break;
2946 default:
2947 BUG();
2948 }
2949 return retval;
2950}
2951
2952static unsigned int bttv_poll(struct file *file, poll_table *wait)
2953{
2954 struct bttv_fh *fh = file->private_data;
2955 struct bttv_buffer *buf;
2956 enum v4l2_field field;
2957
2958 if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) {
2959 if (!check_alloc_btres(fh->btv,fh,RESOURCE_VBI))
2960 return POLLERR;
2961 return videobuf_poll_stream(file, &fh->vbi, wait);
2962 }
2963
2964 if (check_btres(fh,RESOURCE_VIDEO)) {
2965 /* streaming capture */
2966 if (list_empty(&fh->cap.stream))
2967 return POLLERR;
2968 buf = list_entry(fh->cap.stream.next,struct bttv_buffer,vb.stream);
2969 } else {
2970 /* read() capture */
2971 down(&fh->cap.lock);
2972 if (NULL == fh->cap.read_buf) {
2973 /* need to capture a new frame */
2974 if (locked_btres(fh->btv,RESOURCE_VIDEO)) {
2975 up(&fh->cap.lock);
2976 return POLLERR;
2977 }
2978 fh->cap.read_buf = videobuf_alloc(fh->cap.msize);
2979 if (NULL == fh->cap.read_buf) {
2980 up(&fh->cap.lock);
2981 return POLLERR;
2982 }
2983 fh->cap.read_buf->memory = V4L2_MEMORY_USERPTR;
2984 field = videobuf_next_field(&fh->cap);
2985 if (0 != fh->cap.ops->buf_prepare(&fh->cap,fh->cap.read_buf,field)) {
50ab5edc
NS
2986 kfree (fh->cap.read_buf);
2987 fh->cap.read_buf = NULL;
1da177e4
LT
2988 up(&fh->cap.lock);
2989 return POLLERR;
2990 }
2991 fh->cap.ops->buf_queue(&fh->cap,fh->cap.read_buf);
2992 fh->cap.read_off = 0;
2993 }
2994 up(&fh->cap.lock);
2995 buf = (struct bttv_buffer*)fh->cap.read_buf;
2996 }
2997
2998 poll_wait(file, &buf->vb.done, wait);
2999 if (buf->vb.state == STATE_DONE ||
3000 buf->vb.state == STATE_ERROR)
3001 return POLLIN|POLLRDNORM;
3002 return 0;
3003}
3004
3005static int bttv_open(struct inode *inode, struct file *file)
3006{
3007 int minor = iminor(inode);
3008 struct bttv *btv = NULL;
3009 struct bttv_fh *fh;
3010 enum v4l2_buf_type type = 0;
3011 unsigned int i;
3012
3013 dprintk(KERN_DEBUG "bttv: open minor=%d\n",minor);
3014
3015 for (i = 0; i < bttv_num; i++) {
3016 if (bttvs[i].video_dev &&
3017 bttvs[i].video_dev->minor == minor) {
3018 btv = &bttvs[i];
3019 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
3020 break;
3021 }
3022 if (bttvs[i].vbi_dev &&
3023 bttvs[i].vbi_dev->minor == minor) {
3024 btv = &bttvs[i];
3025 type = V4L2_BUF_TYPE_VBI_CAPTURE;
3026 break;
3027 }
3028 }
3029 if (NULL == btv)
3030 return -ENODEV;
3031
3032 dprintk(KERN_DEBUG "bttv%d: open called (type=%s)\n",
3033 btv->c.nr,v4l2_type_names[type]);
3034
3035 /* allocate per filehandle data */
3036 fh = kmalloc(sizeof(*fh),GFP_KERNEL);
3037 if (NULL == fh)
3038 return -ENOMEM;
3039 file->private_data = fh;
3040 *fh = btv->init;
3041 fh->type = type;
3042 fh->ov.setup_ok = 0;
3043 v4l2_prio_open(&btv->prio,&fh->prio);
3044
3045 videobuf_queue_init(&fh->cap, &bttv_video_qops,
3046 btv->c.pci, &btv->s_lock,
3047 V4L2_BUF_TYPE_VIDEO_CAPTURE,
3048 V4L2_FIELD_INTERLACED,
3049 sizeof(struct bttv_buffer),
3050 fh);
3051 videobuf_queue_init(&fh->vbi, &bttv_vbi_qops,
3052 btv->c.pci, &btv->s_lock,
3053 V4L2_BUF_TYPE_VBI_CAPTURE,
3054 V4L2_FIELD_SEQ_TB,
3055 sizeof(struct bttv_buffer),
3056 fh);
3057 i2c_vidiocschan(btv);
3058
3059 btv->users++;
3060 if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type)
3061 bttv_vbi_setlines(fh,btv,16);
3062 bttv_field_count(btv);
3063 return 0;
3064}
3065
3066static int bttv_release(struct inode *inode, struct file *file)
3067{
3068 struct bttv_fh *fh = file->private_data;
3069 struct bttv *btv = fh->btv;
3070
3071 /* turn off overlay */
3072 if (check_btres(fh, RESOURCE_OVERLAY))
3073 bttv_switch_overlay(btv,fh,NULL);
3074
3075 /* stop video capture */
3076 if (check_btres(fh, RESOURCE_VIDEO)) {
3077 videobuf_streamoff(&fh->cap);
3078 free_btres(btv,fh,RESOURCE_VIDEO);
3079 }
3080 if (fh->cap.read_buf) {
3081 buffer_release(&fh->cap,fh->cap.read_buf);
3082 kfree(fh->cap.read_buf);
3083 }
3084
3085 /* stop vbi capture */
3086 if (check_btres(fh, RESOURCE_VBI)) {
3087 if (fh->vbi.streaming)
3088 videobuf_streamoff(&fh->vbi);
3089 if (fh->vbi.reading)
3090 videobuf_read_stop(&fh->vbi);
3091 free_btres(btv,fh,RESOURCE_VBI);
3092 }
3093
3094 /* free stuff */
3095 videobuf_mmap_free(&fh->cap);
3096 videobuf_mmap_free(&fh->vbi);
3097 v4l2_prio_close(&btv->prio,&fh->prio);
3098 file->private_data = NULL;
3099 kfree(fh);
3100
3101 btv->users--;
3102 bttv_field_count(btv);
3103 return 0;
3104}
3105
3106static int
3107bttv_mmap(struct file *file, struct vm_area_struct *vma)
3108{
3109 struct bttv_fh *fh = file->private_data;
3110
3111 dprintk("bttv%d: mmap type=%s 0x%lx+%ld\n",
3112 fh->btv->c.nr, v4l2_type_names[fh->type],
3113 vma->vm_start, vma->vm_end - vma->vm_start);
3114 return videobuf_mmap_mapper(bttv_queue(fh),vma);
3115}
3116
3117static struct file_operations bttv_fops =
3118{
3119 .owner = THIS_MODULE,
3120 .open = bttv_open,
3121 .release = bttv_release,
3122 .ioctl = bttv_ioctl,
3123 .llseek = no_llseek,
3124 .read = bttv_read,
3125 .mmap = bttv_mmap,
3126 .poll = bttv_poll,
3127};
3128
3129static struct video_device bttv_video_template =
3130{
3131 .name = "UNSET",
4dcef524 3132 .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER|
4ac97914 3133 VID_TYPE_CLIPPING|VID_TYPE_SCALES,
1da177e4
LT
3134 .hardware = VID_HARDWARE_BT848,
3135 .fops = &bttv_fops,
3136 .minor = -1,
3137};
3138
3139static struct video_device bttv_vbi_template =
3140{
3141 .name = "bt848/878 vbi",
3142 .type = VID_TYPE_TUNER|VID_TYPE_TELETEXT,
3143 .hardware = VID_HARDWARE_BT848,
3144 .fops = &bttv_fops,
3145 .minor = -1,
3146};
3147
3148/* ----------------------------------------------------------------------- */
3149/* radio interface */
3150
3151static int radio_open(struct inode *inode, struct file *file)
3152{
3153 int minor = iminor(inode);
3154 struct bttv *btv = NULL;
3155 unsigned int i;
3156
3157 dprintk("bttv: open minor=%d\n",minor);
3158
3159 for (i = 0; i < bttv_num; i++) {
3160 if (bttvs[i].radio_dev->minor == minor) {
3161 btv = &bttvs[i];
3162 break;
3163 }
3164 }
3165 if (NULL == btv)
3166 return -ENODEV;
3167
3168 dprintk("bttv%d: open called (radio)\n",btv->c.nr);
3169 down(&btv->lock);
24a70fdc 3170
1da177e4 3171 btv->radio_user++;
24a70fdc 3172
1da177e4
LT
3173 file->private_data = btv;
3174
24a70fdc 3175 bttv_call_i2c_clients(btv,AUDC_SET_RADIO,&btv->tuner_type);
1da177e4
LT
3176 audio_mux(btv,AUDIO_RADIO);
3177
3178 up(&btv->lock);
4ac97914 3179 return 0;
1da177e4
LT
3180}
3181
3182static int radio_release(struct inode *inode, struct file *file)
3183{
24a70fdc
MCC
3184 struct bttv *btv = file->private_data;
3185 struct rds_command cmd;
1da177e4
LT
3186
3187 btv->radio_user--;
24a70fdc
MCC
3188
3189 bttv_call_i2c_clients(btv, RDS_CMD_CLOSE, &cmd);
3190
1da177e4
LT
3191 return 0;
3192}
3193
3194static int radio_do_ioctl(struct inode *inode, struct file *file,
3195 unsigned int cmd, void *arg)
3196{
3197 struct bttv *btv = file->private_data;
3198
3199 switch (cmd) {
3200 case VIDIOCGCAP:
3201 {
4ac97914 3202 struct video_capability *cap = arg;
1da177e4
LT
3203
3204 memset(cap,0,sizeof(*cap));
4ac97914
MCC
3205 strcpy(cap->name,btv->radio_dev->name);
3206 cap->type = VID_TYPE_TUNER;
1da177e4
LT
3207 cap->channels = 1;
3208 cap->audios = 1;
4ac97914 3209 return 0;
1da177e4
LT
3210 }
3211
4ac97914
MCC
3212 case VIDIOCGTUNER:
3213 {
3214 struct video_tuner *v = arg;
1da177e4 3215
4ac97914
MCC
3216 if(v->tuner)
3217 return -EINVAL;
1da177e4 3218 memset(v,0,sizeof(*v));
4ac97914
MCC
3219 strcpy(v->name, "Radio");
3220 bttv_call_i2c_clients(btv,cmd,v);
3221 return 0;
3222 }
3223 case VIDIOCSTUNER:
1da177e4
LT
3224 /* nothing to do */
3225 return 0;
3226
3227 case BTTV_VERSION:
4ac97914
MCC
3228 case VIDIOCGFREQ:
3229 case VIDIOCSFREQ:
1da177e4
LT
3230 case VIDIOCGAUDIO:
3231 case VIDIOCSAUDIO:
3232 return bttv_common_ioctls(btv,cmd,arg);
3233
3234 default:
3235 return -ENOIOCTLCMD;
3236 }
3237 return 0;
3238}
3239
3240static int radio_ioctl(struct inode *inode, struct file *file,
3241 unsigned int cmd, unsigned long arg)
3242{
3243 return video_usercopy(inode, file, cmd, arg, radio_do_ioctl);
3244}
3245
24a70fdc
MCC
3246static ssize_t radio_read(struct file *file, char __user *data,
3247 size_t count, loff_t *ppos)
3248{
3249 struct bttv *btv = file->private_data;
3250 struct rds_command cmd;
3251 cmd.block_count = count/3;
3252 cmd.buffer = data;
3253 cmd.instance = file;
3254 cmd.result = -ENODEV;
3255
3256 bttv_call_i2c_clients(btv, RDS_CMD_READ, &cmd);
3257
3258 return cmd.result;
3259}
3260
3261static unsigned int radio_poll(struct file *file, poll_table *wait)
3262{
3263 struct bttv *btv = file->private_data;
3264 struct rds_command cmd;
3265 cmd.instance = file;
3266 cmd.event_list = wait;
3267 cmd.result = -ENODEV;
3268 bttv_call_i2c_clients(btv, RDS_CMD_POLL, &cmd);
3269
3270 return cmd.result;
3271}
3272
1da177e4
LT
3273static struct file_operations radio_fops =
3274{
3275 .owner = THIS_MODULE,
3276 .open = radio_open,
24a70fdc 3277 .read = radio_read,
1da177e4
LT
3278 .release = radio_release,
3279 .ioctl = radio_ioctl,
3280 .llseek = no_llseek,
24a70fdc 3281 .poll = radio_poll,
1da177e4
LT
3282};
3283
3284static struct video_device radio_template =
3285{
3286 .name = "bt848/878 radio",
3287 .type = VID_TYPE_TUNER,
3288 .hardware = VID_HARDWARE_BT848,
3289 .fops = &radio_fops,
3290 .minor = -1,
3291};
3292
3293/* ----------------------------------------------------------------------- */
3294/* some debug code */
3295
408b664a 3296static int bttv_risc_decode(u32 risc)
1da177e4
LT
3297{
3298 static char *instr[16] = {
3299 [ BT848_RISC_WRITE >> 28 ] = "write",
3300 [ BT848_RISC_SKIP >> 28 ] = "skip",
3301 [ BT848_RISC_WRITEC >> 28 ] = "writec",
3302 [ BT848_RISC_JUMP >> 28 ] = "jump",
3303 [ BT848_RISC_SYNC >> 28 ] = "sync",
3304 [ BT848_RISC_WRITE123 >> 28 ] = "write123",
3305 [ BT848_RISC_SKIP123 >> 28 ] = "skip123",
3306 [ BT848_RISC_WRITE1S23 >> 28 ] = "write1s23",
3307 };
3308 static int incr[16] = {
3309 [ BT848_RISC_WRITE >> 28 ] = 2,
3310 [ BT848_RISC_JUMP >> 28 ] = 2,
3311 [ BT848_RISC_SYNC >> 28 ] = 2,
3312 [ BT848_RISC_WRITE123 >> 28 ] = 5,
3313 [ BT848_RISC_SKIP123 >> 28 ] = 2,
3314 [ BT848_RISC_WRITE1S23 >> 28 ] = 3,
3315 };
3316 static char *bits[] = {
3317 "be0", "be1", "be2", "be3/resync",
3318 "set0", "set1", "set2", "set3",
3319 "clr0", "clr1", "clr2", "clr3",
3320 "irq", "res", "eol", "sol",
3321 };
3322 int i;
3323
3324 printk("0x%08x [ %s", risc,
3325 instr[risc >> 28] ? instr[risc >> 28] : "INVALID");
3326 for (i = ARRAY_SIZE(bits)-1; i >= 0; i--)
3327 if (risc & (1 << (i + 12)))
3328 printk(" %s",bits[i]);
3329 printk(" count=%d ]\n", risc & 0xfff);
3330 return incr[risc >> 28] ? incr[risc >> 28] : 1;
3331}
3332
408b664a
AB
3333static void bttv_risc_disasm(struct bttv *btv,
3334 struct btcx_riscmem *risc)
1da177e4
LT
3335{
3336 unsigned int i,j,n;
3337
3338 printk("%s: risc disasm: %p [dma=0x%08lx]\n",
3339 btv->c.name, risc->cpu, (unsigned long)risc->dma);
3340 for (i = 0; i < (risc->size >> 2); i += n) {
3341 printk("%s: 0x%lx: ", btv->c.name,
3342 (unsigned long)(risc->dma + (i<<2)));
3343 n = bttv_risc_decode(risc->cpu[i]);
3344 for (j = 1; j < n; j++)
3345 printk("%s: 0x%lx: 0x%08x [ arg #%d ]\n",
3346 btv->c.name, (unsigned long)(risc->dma + ((i+j)<<2)),
3347 risc->cpu[i+j], j);
3348 if (0 == risc->cpu[i])
3349 break;
3350 }
3351}
3352
3353static void bttv_print_riscaddr(struct bttv *btv)
3354{
3355 printk(" main: %08Lx\n",
3356 (unsigned long long)btv->main.dma);
3357 printk(" vbi : o=%08Lx e=%08Lx\n",
3358 btv->cvbi ? (unsigned long long)btv->cvbi->top.dma : 0,
3359 btv->cvbi ? (unsigned long long)btv->cvbi->bottom.dma : 0);
3360 printk(" cap : o=%08Lx e=%08Lx\n",
3361 btv->curr.top ? (unsigned long long)btv->curr.top->top.dma : 0,
3362 btv->curr.bottom ? (unsigned long long)btv->curr.bottom->bottom.dma : 0);
3363 printk(" scr : o=%08Lx e=%08Lx\n",
3364 btv->screen ? (unsigned long long)btv->screen->top.dma : 0,
3365 btv->screen ? (unsigned long long)btv->screen->bottom.dma : 0);
3366 bttv_risc_disasm(btv, &btv->main);
3367}
3368
3369/* ----------------------------------------------------------------------- */
3370/* irq handler */
3371
3372static char *irq_name[] = {
3373 "FMTCHG", // format change detected (525 vs. 625)
3374 "VSYNC", // vertical sync (new field)
3375 "HSYNC", // horizontal sync
3376 "OFLOW", // chroma/luma AGC overflow
3377 "HLOCK", // horizontal lock changed
3378 "VPRES", // video presence changed
3379 "6", "7",
3380 "I2CDONE", // hw irc operation finished
3381 "GPINT", // gpio port triggered irq
3382 "10",
3383 "RISCI", // risc instruction triggered irq
3384 "FBUS", // pixel data fifo dropped data (high pci bus latencies)
3385 "FTRGT", // pixel data fifo overrun
3386 "FDSR", // fifo data stream resyncronisation
3387 "PPERR", // parity error (data transfer)
3388 "RIPERR", // parity error (read risc instructions)
3389 "PABORT", // pci abort
3390 "OCERR", // risc instruction error
3391 "SCERR", // syncronisation error
3392};
3393
3394static void bttv_print_irqbits(u32 print, u32 mark)
3395{
3396 unsigned int i;
3397
3398 printk("bits:");
3399 for (i = 0; i < ARRAY_SIZE(irq_name); i++) {
3400 if (print & (1 << i))
3401 printk(" %s",irq_name[i]);
3402 if (mark & (1 << i))
3403 printk("*");
3404 }
3405}
3406
3407static void bttv_irq_debug_low_latency(struct bttv *btv, u32 rc)
3408{
3409 printk("bttv%d: irq: skipped frame [main=%lx,o_vbi=%lx,o_field=%lx,rc=%lx]\n",
3410 btv->c.nr,
3411 (unsigned long)btv->main.dma,
3412 (unsigned long)btv->main.cpu[RISC_SLOT_O_VBI+1],
3413 (unsigned long)btv->main.cpu[RISC_SLOT_O_FIELD+1],
3414 (unsigned long)rc);
3415
3416 if (0 == (btread(BT848_DSTATUS) & BT848_DSTATUS_HLOC)) {
3417 printk("bttv%d: Oh, there (temporarely?) is no input signal. "
3418 "Ok, then this is harmless, don't worry ;)\n",
3419 btv->c.nr);
3420 return;
3421 }
3422 printk("bttv%d: Uhm. Looks like we have unusual high IRQ latencies.\n",
3423 btv->c.nr);
3424 printk("bttv%d: Lets try to catch the culpit red-handed ...\n",
3425 btv->c.nr);
3426 dump_stack();
3427}
3428
3429static int
3430bttv_irq_next_video(struct bttv *btv, struct bttv_buffer_set *set)
3431{
3432 struct bttv_buffer *item;
3433
3434 memset(set,0,sizeof(*set));
3435
3436 /* capture request ? */
3437 if (!list_empty(&btv->capture)) {
3438 set->frame_irq = 1;
3439 item = list_entry(btv->capture.next, struct bttv_buffer, vb.queue);
3440 if (V4L2_FIELD_HAS_TOP(item->vb.field))
3441 set->top = item;
3442 if (V4L2_FIELD_HAS_BOTTOM(item->vb.field))
3443 set->bottom = item;
3444
3445 /* capture request for other field ? */
3446 if (!V4L2_FIELD_HAS_BOTH(item->vb.field) &&
3447 (item->vb.queue.next != &btv->capture)) {
3448 item = list_entry(item->vb.queue.next, struct bttv_buffer, vb.queue);
3449 if (!V4L2_FIELD_HAS_BOTH(item->vb.field)) {
3450 if (NULL == set->top &&
3451 V4L2_FIELD_TOP == item->vb.field) {
3452 set->top = item;
3453 }
3454 if (NULL == set->bottom &&
3455 V4L2_FIELD_BOTTOM == item->vb.field) {
3456 set->bottom = item;
3457 }
3458 if (NULL != set->top && NULL != set->bottom)
3459 set->top_irq = 2;
3460 }
3461 }
3462 }
3463
3464 /* screen overlay ? */
3465 if (NULL != btv->screen) {
3466 if (V4L2_FIELD_HAS_BOTH(btv->screen->vb.field)) {
3467 if (NULL == set->top && NULL == set->bottom) {
3468 set->top = btv->screen;
3469 set->bottom = btv->screen;
3470 }
3471 } else {
3472 if (V4L2_FIELD_TOP == btv->screen->vb.field &&
3473 NULL == set->top) {
3474 set->top = btv->screen;
3475 }
3476 if (V4L2_FIELD_BOTTOM == btv->screen->vb.field &&
3477 NULL == set->bottom) {
3478 set->bottom = btv->screen;
3479 }
3480 }
3481 }
3482
3483 dprintk("bttv%d: next set: top=%p bottom=%p [screen=%p,irq=%d,%d]\n",
3484 btv->c.nr,set->top, set->bottom,
3485 btv->screen,set->frame_irq,set->top_irq);
3486 return 0;
3487}
3488
3489static void
3490bttv_irq_wakeup_video(struct bttv *btv, struct bttv_buffer_set *wakeup,
3491 struct bttv_buffer_set *curr, unsigned int state)
3492{
3493 struct timeval ts;
3494
3495 do_gettimeofday(&ts);
3496
3497 if (wakeup->top == wakeup->bottom) {
3498 if (NULL != wakeup->top && curr->top != wakeup->top) {
3499 if (irq_debug > 1)
3500 printk("bttv%d: wakeup: both=%p\n",btv->c.nr,wakeup->top);
3501 wakeup->top->vb.ts = ts;
3502 wakeup->top->vb.field_count = btv->field_count;
3503 wakeup->top->vb.state = state;
3504 wake_up(&wakeup->top->vb.done);
3505 }
3506 } else {
3507 if (NULL != wakeup->top && curr->top != wakeup->top) {
3508 if (irq_debug > 1)
3509 printk("bttv%d: wakeup: top=%p\n",btv->c.nr,wakeup->top);
3510 wakeup->top->vb.ts = ts;
3511 wakeup->top->vb.field_count = btv->field_count;
3512 wakeup->top->vb.state = state;
3513 wake_up(&wakeup->top->vb.done);
3514 }
3515 if (NULL != wakeup->bottom && curr->bottom != wakeup->bottom) {
3516 if (irq_debug > 1)
3517 printk("bttv%d: wakeup: bottom=%p\n",btv->c.nr,wakeup->bottom);
3518 wakeup->bottom->vb.ts = ts;
3519 wakeup->bottom->vb.field_count = btv->field_count;
3520 wakeup->bottom->vb.state = state;
3521 wake_up(&wakeup->bottom->vb.done);
3522 }
3523 }
3524}
3525
3526static void
3527bttv_irq_wakeup_vbi(struct bttv *btv, struct bttv_buffer *wakeup,
3528 unsigned int state)
3529{
3530 struct timeval ts;
3531
3532 if (NULL == wakeup)
3533 return;
3534
3535 do_gettimeofday(&ts);
3536 wakeup->vb.ts = ts;
3537 wakeup->vb.field_count = btv->field_count;
3538 wakeup->vb.state = state;
3539 wake_up(&wakeup->vb.done);
3540}
3541
3542static void bttv_irq_timeout(unsigned long data)
3543{
3544 struct bttv *btv = (struct bttv *)data;
3545 struct bttv_buffer_set old,new;
3546 struct bttv_buffer *ovbi;
3547 struct bttv_buffer *item;
3548 unsigned long flags;
3549
3550 if (bttv_verbose) {
3551 printk(KERN_INFO "bttv%d: timeout: drop=%d irq=%d/%d, risc=%08x, ",
3552 btv->c.nr, btv->framedrop, btv->irq_me, btv->irq_total,
3553 btread(BT848_RISC_COUNT));
3554 bttv_print_irqbits(btread(BT848_INT_STAT),0);
3555 printk("\n");
3556 }
3557
3558 spin_lock_irqsave(&btv->s_lock,flags);
3559
3560 /* deactivate stuff */
3561 memset(&new,0,sizeof(new));
3562 old = btv->curr;
3563 ovbi = btv->cvbi;
3564 btv->curr = new;
3565 btv->cvbi = NULL;
3566 btv->loop_irq = 0;
3567 bttv_buffer_activate_video(btv, &new);
3568 bttv_buffer_activate_vbi(btv, NULL);
3569 bttv_set_dma(btv, 0);
3570
3571 /* wake up */
3572 bttv_irq_wakeup_video(btv, &old, &new, STATE_ERROR);
3573 bttv_irq_wakeup_vbi(btv, ovbi, STATE_ERROR);
3574
3575 /* cancel all outstanding capture / vbi requests */
3576 while (!list_empty(&btv->capture)) {
3577 item = list_entry(btv->capture.next, struct bttv_buffer, vb.queue);
3578 list_del(&item->vb.queue);
3579 item->vb.state = STATE_ERROR;
3580 wake_up(&item->vb.done);
3581 }
3582 while (!list_empty(&btv->vcapture)) {
3583 item = list_entry(btv->vcapture.next, struct bttv_buffer, vb.queue);
3584 list_del(&item->vb.queue);
3585 item->vb.state = STATE_ERROR;
3586 wake_up(&item->vb.done);
3587 }
3588
3589 btv->errors++;
3590 spin_unlock_irqrestore(&btv->s_lock,flags);
3591}
3592
3593static void
3594bttv_irq_wakeup_top(struct bttv *btv)
3595{
3596 struct bttv_buffer *wakeup = btv->curr.top;
3597
3598 if (NULL == wakeup)
3599 return;
3600
3601 spin_lock(&btv->s_lock);
3602 btv->curr.top_irq = 0;
3603 btv->curr.top = NULL;
3604 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL, 0);
3605
3606 do_gettimeofday(&wakeup->vb.ts);
3607 wakeup->vb.field_count = btv->field_count;
3608 wakeup->vb.state = STATE_DONE;
3609 wake_up(&wakeup->vb.done);
3610 spin_unlock(&btv->s_lock);
3611}
3612
3613static inline int is_active(struct btcx_riscmem *risc, u32 rc)
3614{
3615 if (rc < risc->dma)
3616 return 0;
3617 if (rc > risc->dma + risc->size)
3618 return 0;
3619 return 1;
3620}
3621
3622static void
3623bttv_irq_switch_video(struct bttv *btv)
3624{
3625 struct bttv_buffer_set new;
3626 struct bttv_buffer_set old;
3627 dma_addr_t rc;
3628
3629 spin_lock(&btv->s_lock);
3630
3631 /* new buffer set */
3632 bttv_irq_next_video(btv, &new);
3633 rc = btread(BT848_RISC_COUNT);
3634 if ((btv->curr.top && is_active(&btv->curr.top->top, rc)) ||
3635 (btv->curr.bottom && is_active(&btv->curr.bottom->bottom, rc))) {
3636 btv->framedrop++;
3637 if (debug_latency)
3638 bttv_irq_debug_low_latency(btv, rc);
3639 spin_unlock(&btv->s_lock);
3640 return;
3641 }
3642
3643 /* switch over */
3644 old = btv->curr;
3645 btv->curr = new;
3646 btv->loop_irq &= ~1;
3647 bttv_buffer_activate_video(btv, &new);
3648 bttv_set_dma(btv, 0);
3649
3650 /* switch input */
3651 if (UNSET != btv->new_input) {
3652 video_mux(btv,btv->new_input);
3653 btv->new_input = UNSET;
3654 }
3655
3656 /* wake up finished buffers */
3657 bttv_irq_wakeup_video(btv, &old, &new, STATE_DONE);
3658 spin_unlock(&btv->s_lock);
3659}
3660
3661static void
3662bttv_irq_switch_vbi(struct bttv *btv)
3663{
3664 struct bttv_buffer *new = NULL;
3665 struct bttv_buffer *old;
3666 u32 rc;
3667
3668 spin_lock(&btv->s_lock);
3669
3670 if (!list_empty(&btv->vcapture))
3671 new = list_entry(btv->vcapture.next, struct bttv_buffer, vb.queue);
3672 old = btv->cvbi;
3673
3674 rc = btread(BT848_RISC_COUNT);
3675 if (NULL != old && (is_active(&old->top, rc) ||
3676 is_active(&old->bottom, rc))) {
3677 btv->framedrop++;
3678 if (debug_latency)
3679 bttv_irq_debug_low_latency(btv, rc);
3680 spin_unlock(&btv->s_lock);
3681 return;
3682 }
3683
3684 /* switch */
3685 btv->cvbi = new;
3686 btv->loop_irq &= ~4;
3687 bttv_buffer_activate_vbi(btv, new);
3688 bttv_set_dma(btv, 0);
3689
3690 bttv_irq_wakeup_vbi(btv, old, STATE_DONE);
3691 spin_unlock(&btv->s_lock);
3692}
3693
3694static irqreturn_t bttv_irq(int irq, void *dev_id, struct pt_regs * regs)
3695{
3696 u32 stat,astat;
3697 u32 dstat;
3698 int count;
3699 struct bttv *btv;
3700 int handled = 0;
3701
3702 btv=(struct bttv *)dev_id;
6c6c0b2c
MW
3703
3704 if (btv->any_irq)
3705 handled = bttv_any_irq(&btv->c);
3706
1da177e4
LT
3707 count=0;
3708 while (1) {
3709 /* get/clear interrupt status bits */
3710 stat=btread(BT848_INT_STAT);
3711 astat=stat&btread(BT848_INT_MASK);
3712 if (!astat)
3713 break;
3714 handled = 1;
3715 btwrite(stat,BT848_INT_STAT);
3716
3717 /* get device status bits */
3718 dstat=btread(BT848_DSTATUS);
3719
3720 if (irq_debug) {
3721 printk(KERN_DEBUG "bttv%d: irq loop=%d fc=%d "
3722 "riscs=%x, riscc=%08x, ",
3723 btv->c.nr, count, btv->field_count,
3724 stat>>28, btread(BT848_RISC_COUNT));
3725 bttv_print_irqbits(stat,astat);
3726 if (stat & BT848_INT_HLOCK)
3727 printk(" HLOC => %s", (dstat & BT848_DSTATUS_HLOC)
3728 ? "yes" : "no");
3729 if (stat & BT848_INT_VPRES)
3730 printk(" PRES => %s", (dstat & BT848_DSTATUS_PRES)
3731 ? "yes" : "no");
3732 if (stat & BT848_INT_FMTCHG)
3733 printk(" NUML => %s", (dstat & BT848_DSTATUS_NUML)
3734 ? "625" : "525");
3735 printk("\n");
3736 }
3737
3738 if (astat&BT848_INT_VSYNC)
4ac97914 3739 btv->field_count++;
1da177e4
LT
3740
3741 if (astat & BT848_INT_GPINT) {
3742 wake_up(&btv->gpioq);
3743 bttv_gpio_irq(&btv->c);
3744 }
3745
3746 if (astat & BT848_INT_I2CDONE) {
3747 btv->i2c_done = stat;
3748 wake_up(&btv->i2c_queue);
3749 }
3750
4ac97914 3751 if ((astat & BT848_INT_RISCI) && (stat & (4<<28)))
1da177e4
LT
3752 bttv_irq_switch_vbi(btv);
3753
4ac97914 3754 if ((astat & BT848_INT_RISCI) && (stat & (2<<28)))
1da177e4
LT
3755 bttv_irq_wakeup_top(btv);
3756
4ac97914 3757 if ((astat & BT848_INT_RISCI) && (stat & (1<<28)))
1da177e4
LT
3758 bttv_irq_switch_video(btv);
3759
3760 if ((astat & BT848_INT_HLOCK) && btv->opt_automute)
3761 audio_mux(btv, -1);
3762
3763 if (astat & (BT848_INT_SCERR|BT848_INT_OCERR)) {
3764 printk(KERN_INFO "bttv%d: %s%s @ %08x,",btv->c.nr,
3765 (astat & BT848_INT_SCERR) ? "SCERR" : "",
3766 (astat & BT848_INT_OCERR) ? "OCERR" : "",
3767 btread(BT848_RISC_COUNT));
3768 bttv_print_irqbits(stat,astat);
3769 printk("\n");
3770 if (bttv_debug)
3771 bttv_print_riscaddr(btv);
3772 }
3773 if (fdsr && astat & BT848_INT_FDSR) {
3774 printk(KERN_INFO "bttv%d: FDSR @ %08x\n",
3775 btv->c.nr,btread(BT848_RISC_COUNT));
3776 if (bttv_debug)
3777 bttv_print_riscaddr(btv);
3778 }
3779
3780 count++;
3781 if (count > 4) {
c58c21c7 3782
3783 if (count > 8 || !(astat & BT848_INT_GPINT)) {
4ac97914 3784 btwrite(0, BT848_INT_MASK);
c58c21c7 3785
3786 printk(KERN_ERR
3787 "bttv%d: IRQ lockup, cleared int mask [", btv->c.nr);
3788 } else {
3789 printk(KERN_ERR
3790 "bttv%d: IRQ lockup, clearing GPINT from int mask [", btv->c.nr);
3791
3792 btwrite(btread(BT848_INT_MASK) & (-1 ^ BT848_INT_GPINT),
3793 BT848_INT_MASK);
3794 };
3795
1da177e4 3796 bttv_print_irqbits(stat,astat);
c58c21c7 3797
1da177e4
LT
3798 printk("]\n");
3799 }
3800 }
3801 btv->irq_total++;
3802 if (handled)
3803 btv->irq_me++;
3804 return IRQ_RETVAL(handled);
3805}
3806
3807
3808/* ----------------------------------------------------------------------- */
3809/* initialitation */
3810
3811static struct video_device *vdev_init(struct bttv *btv,
3812 struct video_device *template,
3813 char *type)
3814{
3815 struct video_device *vfd;
3816
3817 vfd = video_device_alloc();
3818 if (NULL == vfd)
3819 return NULL;
3820 *vfd = *template;
3821 vfd->minor = -1;
3822 vfd->dev = &btv->c.pci->dev;
3823 vfd->release = video_device_release;
3824 snprintf(vfd->name, sizeof(vfd->name), "BT%d%s %s (%s)",
3825 btv->id, (btv->id==848 && btv->revision==0x12) ? "A" : "",
3826 type, bttv_tvcards[btv->c.type].name);
3827 return vfd;
3828}
3829
3830static void bttv_unregister_video(struct bttv *btv)
3831{
3832 if (btv->video_dev) {
3833 if (-1 != btv->video_dev->minor)
3834 video_unregister_device(btv->video_dev);
3835 else
3836 video_device_release(btv->video_dev);
3837 btv->video_dev = NULL;
3838 }
3839 if (btv->vbi_dev) {
3840 if (-1 != btv->vbi_dev->minor)
3841 video_unregister_device(btv->vbi_dev);
3842 else
3843 video_device_release(btv->vbi_dev);
3844 btv->vbi_dev = NULL;
3845 }
3846 if (btv->radio_dev) {
3847 if (-1 != btv->radio_dev->minor)
3848 video_unregister_device(btv->radio_dev);
3849 else
3850 video_device_release(btv->radio_dev);
3851 btv->radio_dev = NULL;
3852 }
3853}
3854
3855/* register video4linux devices */
3856static int __devinit bttv_register_video(struct bttv *btv)
3857{
4dcef524
MCC
3858 if (no_overlay <= 0) {
3859 bttv_video_template.type |= VID_TYPE_OVERLAY;
3860 } else {
3861 printk("bttv: Overlay support disabled.\n");
3862 }
3863
1da177e4
LT
3864 /* video */
3865 btv->video_dev = vdev_init(btv, &bttv_video_template, "video");
4ac97914 3866 if (NULL == btv->video_dev)
1da177e4
LT
3867 goto err;
3868 if (video_register_device(btv->video_dev,VFL_TYPE_GRABBER,video_nr)<0)
3869 goto err;
3870 printk(KERN_INFO "bttv%d: registered device video%d\n",
3871 btv->c.nr,btv->video_dev->minor & 0x1f);
3872 video_device_create_file(btv->video_dev, &class_device_attr_card);
3873
3874 /* vbi */
3875 btv->vbi_dev = vdev_init(btv, &bttv_vbi_template, "vbi");
4ac97914 3876 if (NULL == btv->vbi_dev)
1da177e4 3877 goto err;
4ac97914 3878 if (video_register_device(btv->vbi_dev,VFL_TYPE_VBI,vbi_nr)<0)
1da177e4
LT
3879 goto err;
3880 printk(KERN_INFO "bttv%d: registered device vbi%d\n",
3881 btv->c.nr,btv->vbi_dev->minor & 0x1f);
3882
4ac97914 3883 if (!btv->has_radio)
1da177e4
LT
3884 return 0;
3885 /* radio */
3886 btv->radio_dev = vdev_init(btv, &radio_template, "radio");
4ac97914 3887 if (NULL == btv->radio_dev)
1da177e4
LT
3888 goto err;
3889 if (video_register_device(btv->radio_dev, VFL_TYPE_RADIO,radio_nr)<0)
3890 goto err;
3891 printk(KERN_INFO "bttv%d: registered device radio%d\n",
3892 btv->c.nr,btv->radio_dev->minor & 0x1f);
3893
3894 /* all done */
3895 return 0;
3896
3897 err:
3898 bttv_unregister_video(btv);
3899 return -1;
3900}
3901
3902
3903/* on OpenFirmware machines (PowerMac at least), PCI memory cycle */
3904/* response on cards with no firmware is not enabled by OF */
3905static void pci_set_command(struct pci_dev *dev)
3906{
3907#if defined(__powerpc__)
4ac97914 3908 unsigned int cmd;
1da177e4 3909
4ac97914
MCC
3910 pci_read_config_dword(dev, PCI_COMMAND, &cmd);
3911 cmd = (cmd | PCI_COMMAND_MEMORY );
3912 pci_write_config_dword(dev, PCI_COMMAND, cmd);
1da177e4
LT
3913#endif
3914}
3915
3916static int __devinit bttv_probe(struct pci_dev *dev,
3917 const struct pci_device_id *pci_id)
3918{
3919 int result;
3920 unsigned char lat;
3921 struct bttv *btv;
3922
3923 if (bttv_num == BTTV_MAX)
3924 return -ENOMEM;
3925 printk(KERN_INFO "bttv: Bt8xx card found (%d).\n", bttv_num);
4ac97914 3926 btv=&bttvs[bttv_num];
1da177e4
LT
3927 memset(btv,0,sizeof(*btv));
3928 btv->c.nr = bttv_num;
3929 sprintf(btv->c.name,"bttv%d",btv->c.nr);
3930
3931 /* initialize structs / fill in defaults */
4ac97914
MCC
3932 init_MUTEX(&btv->lock);
3933 init_MUTEX(&btv->reslock);
3934 spin_lock_init(&btv->s_lock);
3935 spin_lock_init(&btv->gpio_lock);
3936 init_waitqueue_head(&btv->gpioq);
3937 init_waitqueue_head(&btv->i2c_queue);
3938 INIT_LIST_HEAD(&btv->c.subs);
3939 INIT_LIST_HEAD(&btv->capture);
3940 INIT_LIST_HEAD(&btv->vcapture);
1da177e4
LT
3941 v4l2_prio_init(&btv->prio);
3942
3943 init_timer(&btv->timeout);
3944 btv->timeout.function = bttv_irq_timeout;
3945 btv->timeout.data = (unsigned long)btv;
3946
7c08fb02
MK
3947 btv->i2c_rc = -1;
3948 btv->tuner_type = UNSET;
3949 btv->pinnacle_id = UNSET;
1da177e4 3950 btv->new_input = UNSET;
1da177e4
LT
3951 btv->has_radio=radio[btv->c.nr];
3952
3953 /* pci stuff (init, get irq/mmio, ... */
3954 btv->c.pci = dev;
7c08fb02 3955 btv->id = dev->device;
1da177e4 3956 if (pci_enable_device(dev)) {
7c08fb02 3957 printk(KERN_WARNING "bttv%d: Can't enable device.\n",
1da177e4
LT
3958 btv->c.nr);
3959 return -EIO;
3960 }
4ac97914
MCC
3961 if (pci_set_dma_mask(dev, DMA_32BIT_MASK)) {
3962 printk(KERN_WARNING "bttv%d: No suitable DMA available.\n",
1da177e4
LT
3963 btv->c.nr);
3964 return -EIO;
4ac97914 3965 }
1da177e4
LT
3966 if (!request_mem_region(pci_resource_start(dev,0),
3967 pci_resource_len(dev,0),
3968 btv->c.name)) {
4ac97914 3969 printk(KERN_WARNING "bttv%d: can't request iomem (0x%lx).\n",
1da177e4
LT
3970 btv->c.nr, pci_resource_start(dev,0));
3971 return -EBUSY;
3972 }
4ac97914 3973 pci_set_master(dev);
1da177e4
LT
3974 pci_set_command(dev);
3975 pci_set_drvdata(dev,btv);
1da177e4 3976
4ac97914
MCC
3977 pci_read_config_byte(dev, PCI_CLASS_REVISION, &btv->revision);
3978 pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
3979 printk(KERN_INFO "bttv%d: Bt%d (rev %d) at %s, ",
3980 bttv_num,btv->id, btv->revision, pci_name(dev));
3981 printk("irq: %d, latency: %d, mmio: 0x%lx\n",
1da177e4
LT
3982 btv->c.pci->irq, lat, pci_resource_start(dev,0));
3983 schedule();
3984
3985 btv->bt848_mmio=ioremap(pci_resource_start(dev,0), 0x1000);
3986 if (NULL == ioremap(pci_resource_start(dev,0), 0x1000)) {
3987 printk("bttv%d: ioremap() failed\n", btv->c.nr);
3988 result = -EIO;
3989 goto fail1;
3990 }
3991
4ac97914 3992 /* identify card */
1da177e4
LT
3993 bttv_idcard(btv);
3994
4ac97914 3995 /* disable irqs, register irq handler */
1da177e4 3996 btwrite(0, BT848_INT_MASK);
4ac97914
MCC
3997 result = request_irq(btv->c.pci->irq, bttv_irq,
3998 SA_SHIRQ | SA_INTERRUPT,btv->c.name,(void *)btv);
3999 if (result < 0) {
4000 printk(KERN_ERR "bttv%d: can't get IRQ %d\n",
1da177e4
LT
4001 bttv_num,btv->c.pci->irq);
4002 goto fail1;
4ac97914 4003 }
1da177e4
LT
4004
4005 if (0 != bttv_handle_chipset(btv)) {
4006 result = -EIO;
4007 goto fail2;
4ac97914 4008 }
1da177e4
LT
4009
4010 /* init options from insmod args */
4011 btv->opt_combfilter = combfilter;
4012 btv->opt_lumafilter = lumafilter;
4013 btv->opt_automute = automute;
4014 btv->opt_chroma_agc = chroma_agc;
4015 btv->opt_adc_crush = adc_crush;
4016 btv->opt_vcr_hack = vcr_hack;
4017 btv->opt_whitecrush_upper = whitecrush_upper;
4018 btv->opt_whitecrush_lower = whitecrush_lower;
060d3027
MCC
4019 btv->opt_uv_ratio = uv_ratio;
4020 btv->opt_full_luma_range = full_luma_range;
4021 btv->opt_coring = coring;
1da177e4
LT
4022
4023 /* fill struct bttv with some useful defaults */
4024 btv->init.btv = btv;
4025 btv->init.ov.w.width = 320;
4026 btv->init.ov.w.height = 240;
4027 btv->init.fmt = format_by_palette(VIDEO_PALETTE_RGB24);
4028 btv->init.width = 320;
4029 btv->init.height = 240;
4030 btv->init.lines = 16;
4031 btv->input = 0;
4032
4033 /* initialize hardware */
4ac97914
MCC
4034 if (bttv_gpio)
4035 bttv_gpio_tracking(btv,"pre-init");
1da177e4
LT
4036
4037 bttv_risc_init_main(btv);
4038 init_bt848(btv);
4039
4040 /* gpio */
4ac97914
MCC
4041 btwrite(0x00, BT848_GPIO_REG_INP);
4042 btwrite(0x00, BT848_GPIO_OUT_EN);
4043 if (bttv_verbose)
4044 bttv_gpio_tracking(btv,"init");
1da177e4 4045
4ac97914
MCC
4046 /* needs to be done before i2c is registered */
4047 bttv_init_card1(btv);
1da177e4 4048
4ac97914
MCC
4049 /* register i2c + gpio */
4050 init_bttv_i2c(btv);
1da177e4 4051
4ac97914
MCC
4052 /* some card-specific stuff (needs working i2c) */
4053 bttv_init_card2(btv);
1da177e4
LT
4054 init_irqreg(btv);
4055
4ac97914 4056 /* register video4linux + input */
1da177e4
LT
4057 if (!bttv_tvcards[btv->c.type].no_video) {
4058 bttv_register_video(btv);
4059 bt848_bright(btv,32768);
4060 bt848_contrast(btv,32768);
4061 bt848_hue(btv,32768);
4062 bt848_sat(btv,32768);
4063 audio_mux(btv,AUDIO_MUTE);
4064 set_input(btv,0);
4065 }
4066
4067 /* add subdevices */
4068 if (btv->has_remote)
4069 bttv_sub_add_device(&btv->c, "remote");
4070 if (bttv_tvcards[btv->c.type].has_dvb)
4071 bttv_sub_add_device(&btv->c, "dvb");
4072
4073 /* everything is fine */
4074 bttv_num++;
4ac97914 4075 return 0;
1da177e4
LT
4076
4077 fail2:
4ac97914 4078 free_irq(btv->c.pci->irq,btv);
1da177e4
LT
4079
4080 fail1:
4081 if (btv->bt848_mmio)
4082 iounmap(btv->bt848_mmio);
4083 release_mem_region(pci_resource_start(btv->c.pci,0),
4084 pci_resource_len(btv->c.pci,0));
4085 pci_set_drvdata(dev,NULL);
4086 return result;
4087}
4088
4089static void __devexit bttv_remove(struct pci_dev *pci_dev)
4090{
4ac97914 4091 struct bttv *btv = pci_get_drvdata(pci_dev);
1da177e4
LT
4092
4093 if (bttv_verbose)
4094 printk("bttv%d: unloading\n",btv->c.nr);
4095
4ac97914 4096 /* shutdown everything (DMA+IRQs) */
1da177e4
LT
4097 btand(~15, BT848_GPIO_DMA_CTL);
4098 btwrite(0, BT848_INT_MASK);
4099 btwrite(~0x0, BT848_INT_STAT);
4100 btwrite(0x0, BT848_GPIO_OUT_EN);
4101 if (bttv_gpio)
4102 bttv_gpio_tracking(btv,"cleanup");
4103
4104 /* tell gpio modules we are leaving ... */
4105 btv->shutdown=1;
4106 wake_up(&btv->gpioq);
4107 bttv_sub_del_devices(&btv->c);
4108
4ac97914 4109 /* unregister i2c_bus + input */
1da177e4
LT
4110 fini_bttv_i2c(btv);
4111
4112 /* unregister video4linux */
4113 bttv_unregister_video(btv);
4114
4115 /* free allocated memory */
4116 btcx_riscmem_free(btv->c.pci,&btv->main);
4117
4118 /* free ressources */
4ac97914 4119 free_irq(btv->c.pci->irq,btv);
1da177e4 4120 iounmap(btv->bt848_mmio);
4ac97914
MCC
4121 release_mem_region(pci_resource_start(btv->c.pci,0),
4122 pci_resource_len(btv->c.pci,0));
1da177e4
LT
4123
4124 pci_set_drvdata(pci_dev, NULL);
4ac97914 4125 return;
1da177e4
LT
4126}
4127
4128static int bttv_suspend(struct pci_dev *pci_dev, pm_message_t state)
4129{
4ac97914 4130 struct bttv *btv = pci_get_drvdata(pci_dev);
1da177e4
LT
4131 struct bttv_buffer_set idle;
4132 unsigned long flags;
4133
0f97a931 4134 dprintk("bttv%d: suspend %d\n", btv->c.nr, state.event);
1da177e4
LT
4135
4136 /* stop dma + irqs */
4137 spin_lock_irqsave(&btv->s_lock,flags);
4138 memset(&idle, 0, sizeof(idle));
4139 btv->state.video = btv->curr;
4140 btv->state.vbi = btv->cvbi;
4141 btv->state.loop_irq = btv->loop_irq;
4142 btv->curr = idle;
4143 btv->loop_irq = 0;
4144 bttv_buffer_activate_video(btv, &idle);
4145 bttv_buffer_activate_vbi(btv, NULL);
4146 bttv_set_dma(btv, 0);
4147 btwrite(0, BT848_INT_MASK);
4148 spin_unlock_irqrestore(&btv->s_lock,flags);
4149
4150 /* save bt878 state */
4151 btv->state.gpio_enable = btread(BT848_GPIO_OUT_EN);
4152 btv->state.gpio_data = gpio_read();
4153
4154 /* save pci state */
4155 pci_save_state(pci_dev);
4156 if (0 != pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state))) {
4157 pci_disable_device(pci_dev);
4158 btv->state.disabled = 1;
4159 }
4160 return 0;
4161}
4162
4163static int bttv_resume(struct pci_dev *pci_dev)
4164{
4ac97914 4165 struct bttv *btv = pci_get_drvdata(pci_dev);
1da177e4 4166 unsigned long flags;
08adb9e2 4167 int err;
1da177e4
LT
4168
4169 dprintk("bttv%d: resume\n", btv->c.nr);
4170
4171 /* restore pci state */
4172 if (btv->state.disabled) {
08adb9e2
MCC
4173 err=pci_enable_device(pci_dev);
4174 if (err) {
4175 printk(KERN_WARNING "bttv%d: Can't enable device.\n",
4176 btv->c.nr);
4177 return err;
4178 }
1da177e4
LT
4179 btv->state.disabled = 0;
4180 }
08adb9e2
MCC
4181 err=pci_set_power_state(pci_dev, PCI_D0);
4182 if (err) {
4183 pci_disable_device(pci_dev);
4184 printk(KERN_WARNING "bttv%d: Can't enable device.\n",
4185 btv->c.nr);
4186 btv->state.disabled = 1;
4187 return err;
4188 }
4189
1da177e4
LT
4190 pci_restore_state(pci_dev);
4191
4192 /* restore bt878 state */
4193 bttv_reinit_bt848(btv);
4194 gpio_inout(0xffffff, btv->state.gpio_enable);
4195 gpio_write(btv->state.gpio_data);
4196
4197 /* restart dma */
4198 spin_lock_irqsave(&btv->s_lock,flags);
4199 btv->curr = btv->state.video;
4200 btv->cvbi = btv->state.vbi;
4201 btv->loop_irq = btv->state.loop_irq;
4202 bttv_buffer_activate_video(btv, &btv->curr);
4203 bttv_buffer_activate_vbi(btv, btv->cvbi);
4204 bttv_set_dma(btv, 0);
4205 spin_unlock_irqrestore(&btv->s_lock,flags);
4206 return 0;
4207}
4208
4209static struct pci_device_id bttv_pci_tbl[] = {
4ac97914
MCC
4210 {PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT848,
4211 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
1da177e4 4212 {PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT849,
4ac97914 4213 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
1da177e4 4214 {PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT878,
4ac97914 4215 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
1da177e4 4216 {PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT879,
4ac97914
MCC
4217 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
4218 {0,}
1da177e4
LT
4219};
4220
4221MODULE_DEVICE_TABLE(pci, bttv_pci_tbl);
4222
4223static struct pci_driver bttv_pci_driver = {
4ac97914
MCC
4224 .name = "bttv",
4225 .id_table = bttv_pci_tbl,
4226 .probe = bttv_probe,
4227 .remove = __devexit_p(bttv_remove),
1da177e4
LT
4228 .suspend = bttv_suspend,
4229 .resume = bttv_resume,
4230};
4231
4232static int bttv_init_module(void)
4233{
4234 bttv_num = 0;
4235
4236 printk(KERN_INFO "bttv: driver version %d.%d.%d loaded\n",
4237 (BTTV_VERSION_CODE >> 16) & 0xff,
4238 (BTTV_VERSION_CODE >> 8) & 0xff,
4239 BTTV_VERSION_CODE & 0xff);
4240#ifdef SNAPSHOT
4241 printk(KERN_INFO "bttv: snapshot date %04d-%02d-%02d\n",
4242 SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100);
4243#endif
4244 if (gbuffers < 2 || gbuffers > VIDEO_MAX_FRAME)
4245 gbuffers = 2;
4246 if (gbufsize < 0 || gbufsize > BTTV_MAX_FBUF)
4247 gbufsize = BTTV_MAX_FBUF;
4248 gbufsize = (gbufsize + PAGE_SIZE - 1) & PAGE_MASK;
4249 if (bttv_verbose)
4250 printk(KERN_INFO "bttv: using %d buffers with %dk (%d pages) each for capture\n",
4251 gbuffers, gbufsize >> 10, gbufsize >> PAGE_SHIFT);
4252
4253 bttv_check_chipset();
4254
4255 bus_register(&bttv_sub_bus_type);
4256 return pci_module_init(&bttv_pci_driver);
4257}
4258
4259static void bttv_cleanup_module(void)
4260{
4261 pci_unregister_driver(&bttv_pci_driver);
4262 bus_unregister(&bttv_sub_bus_type);
4263 return;
4264}
4265
4266module_init(bttv_init_module);
4267module_exit(bttv_cleanup_module);
4268
4269/*
4270 * Local variables:
4271 * c-basic-offset: 8
4272 * End:
4273 */