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