aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/saa7134
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /drivers/media/video/saa7134
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
Diffstat (limited to 'drivers/media/video/saa7134')
-rw-r--r--drivers/media/video/saa7134/Makefile11
-rw-r--r--drivers/media/video/saa7134/saa6752hs.c543
-rw-r--r--drivers/media/video/saa7134/saa7134-cards.c2018
-rw-r--r--drivers/media/video/saa7134/saa7134-core.c1237
-rw-r--r--drivers/media/video/saa7134/saa7134-dvb.c266
-rw-r--r--drivers/media/video/saa7134/saa7134-empress.c436
-rw-r--r--drivers/media/video/saa7134/saa7134-i2c.c453
-rw-r--r--drivers/media/video/saa7134/saa7134-input.c491
-rw-r--r--drivers/media/video/saa7134/saa7134-oss.c857
-rw-r--r--drivers/media/video/saa7134/saa7134-reg.h366
-rw-r--r--drivers/media/video/saa7134/saa7134-ts.c243
-rw-r--r--drivers/media/video/saa7134/saa7134-tvaudio.c1031
-rw-r--r--drivers/media/video/saa7134/saa7134-vbi.c270
-rw-r--r--drivers/media/video/saa7134/saa7134-video.c2406
-rw-r--r--drivers/media/video/saa7134/saa7134.h618
15 files changed, 11246 insertions, 0 deletions
diff --git a/drivers/media/video/saa7134/Makefile b/drivers/media/video/saa7134/Makefile
new file mode 100644
index 000000000000..e577a06b136b
--- /dev/null
+++ b/drivers/media/video/saa7134/Makefile
@@ -0,0 +1,11 @@
1
2saa7134-objs := saa7134-cards.o saa7134-core.o saa7134-i2c.o \
3 saa7134-oss.o saa7134-ts.o saa7134-tvaudio.o \
4 saa7134-vbi.o saa7134-video.o saa7134-input.o
5
6obj-$(CONFIG_VIDEO_SAA7134) += saa7134.o saa7134-empress.o saa6752hs.o
7obj-$(CONFIG_VIDEO_SAA7134_DVB) += saa7134-dvb.o
8
9EXTRA_CFLAGS += -I$(src)/..
10EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core
11EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/frontends
diff --git a/drivers/media/video/saa7134/saa6752hs.c b/drivers/media/video/saa7134/saa6752hs.c
new file mode 100644
index 000000000000..cee13584c9cf
--- /dev/null
+++ b/drivers/media/video/saa7134/saa6752hs.c
@@ -0,0 +1,543 @@
1#include <linux/module.h>
2#include <linux/kernel.h>
3#include <linux/sched.h>
4#include <linux/string.h>
5#include <linux/timer.h>
6#include <linux/delay.h>
7#include <linux/errno.h>
8#include <linux/slab.h>
9#include <linux/poll.h>
10#include <linux/i2c.h>
11#include <linux/types.h>
12#include <linux/videodev.h>
13#include <linux/init.h>
14#include <linux/crc32.h>
15
16#include <media/id.h>
17
18#define MPEG_VIDEO_TARGET_BITRATE_MAX 27000
19#define MPEG_VIDEO_MAX_BITRATE_MAX 27000
20#define MPEG_TOTAL_TARGET_BITRATE_MAX 27000
21#define MPEG_PID_MAX ((1 << 14) - 1)
22
23/* Addresses to scan */
24static unsigned short normal_i2c[] = {0x20, I2C_CLIENT_END};
25static unsigned short normal_i2c_range[] = {I2C_CLIENT_END};
26I2C_CLIENT_INSMOD;
27
28MODULE_DESCRIPTION("device driver for saa6752hs MPEG2 encoder");
29MODULE_AUTHOR("Andrew de Quincey");
30MODULE_LICENSE("GPL");
31
32static struct i2c_driver driver;
33static struct i2c_client client_template;
34
35struct saa6752hs_state {
36 struct i2c_client client;
37 struct v4l2_mpeg_compression params;
38};
39
40enum saa6752hs_command {
41 SAA6752HS_COMMAND_RESET = 0,
42 SAA6752HS_COMMAND_STOP = 1,
43 SAA6752HS_COMMAND_START = 2,
44 SAA6752HS_COMMAND_PAUSE = 3,
45 SAA6752HS_COMMAND_RECONFIGURE = 4,
46 SAA6752HS_COMMAND_SLEEP = 5,
47 SAA6752HS_COMMAND_RECONFIGURE_FORCE = 6,
48
49 SAA6752HS_COMMAND_MAX
50};
51
52/* ---------------------------------------------------------------------- */
53
54static u8 PAT[] = {
55 0xc2, // i2c register
56 0x00, // table number for encoder
57
58 0x47, // sync
59 0x40, 0x00, // transport_error_indicator(0), payload_unit_start(1), transport_priority(0), pid(0)
60 0x10, // transport_scrambling_control(00), adaptation_field_control(01), continuity_counter(0)
61
62 0x00, // PSI pointer to start of table
63
64 0x00, // tid(0)
65 0xb0, 0x0d, // section_syntax_indicator(1), section_length(13)
66
67 0x00, 0x01, // transport_stream_id(1)
68
69 0xc1, // version_number(0), current_next_indicator(1)
70
71 0x00, 0x00, // section_number(0), last_section_number(0)
72
73 0x00, 0x01, // program_number(1)
74
75 0xe0, 0x00, // PMT PID
76
77 0x00, 0x00, 0x00, 0x00 // CRC32
78};
79
80static u8 PMT[] = {
81 0xc2, // i2c register
82 0x01, // table number for encoder
83
84 0x47, // sync
85 0x40, 0x00, // transport_error_indicator(0), payload_unit_start(1), transport_priority(0), pid
86 0x10, // transport_scrambling_control(00), adaptation_field_control(01), continuity_counter(0)
87
88 0x00, // PSI pointer to start of table
89
90 0x02, // tid(2)
91 0xb0, 0x17, // section_syntax_indicator(1), section_length(23)
92
93 0x00, 0x01, // program_number(1)
94
95 0xc1, // version_number(0), current_next_indicator(1)
96
97 0x00, 0x00, // section_number(0), last_section_number(0)
98
99 0xe0, 0x00, // PCR_PID
100
101 0xf0, 0x00, // program_info_length(0)
102
103 0x02, 0xe0, 0x00, 0xf0, 0x00, // video stream type(2), pid
104 0x04, 0xe0, 0x00, 0xf0, 0x00, // audio stream type(4), pid
105
106 0x00, 0x00, 0x00, 0x00 // CRC32
107};
108
109static struct v4l2_mpeg_compression param_defaults =
110{
111 .st_type = V4L2_MPEG_TS_2,
112 .st_bitrate = {
113 .mode = V4L2_BITRATE_CBR,
114 .target = 7000,
115 },
116
117 .ts_pid_pmt = 16,
118 .ts_pid_video = 260,
119 .ts_pid_audio = 256,
120 .ts_pid_pcr = 259,
121
122 .vi_type = V4L2_MPEG_VI_2,
123 .vi_aspect_ratio = V4L2_MPEG_ASPECT_4_3,
124 .vi_bitrate = {
125 .mode = V4L2_BITRATE_VBR,
126 .target = 4000,
127 .max = 6000,
128 },
129
130 .au_type = V4L2_MPEG_AU_2_II,
131 .au_bitrate = {
132 .mode = V4L2_BITRATE_CBR,
133 .target = 256,
134 },
135
136#if 0
137 /* FIXME: size? via S_FMT? */
138 .video_format = MPEG_VIDEO_FORMAT_D1,
139#endif
140};
141
142/* ---------------------------------------------------------------------- */
143
144static int saa6752hs_chip_command(struct i2c_client* client,
145 enum saa6752hs_command command)
146{
147 unsigned char buf[3];
148 unsigned long timeout;
149 int status = 0;
150
151 // execute the command
152 switch(command) {
153 case SAA6752HS_COMMAND_RESET:
154 buf[0] = 0x00;
155 break;
156
157 case SAA6752HS_COMMAND_STOP:
158 buf[0] = 0x03;
159 break;
160
161 case SAA6752HS_COMMAND_START:
162 buf[0] = 0x02;
163 break;
164
165 case SAA6752HS_COMMAND_PAUSE:
166 buf[0] = 0x04;
167 break;
168
169 case SAA6752HS_COMMAND_RECONFIGURE:
170 buf[0] = 0x05;
171 break;
172
173 case SAA6752HS_COMMAND_SLEEP:
174 buf[0] = 0x06;
175 break;
176
177 case SAA6752HS_COMMAND_RECONFIGURE_FORCE:
178 buf[0] = 0x07;
179 break;
180
181 default:
182 return -EINVAL;
183 }
184
185 // set it and wait for it to be so
186 i2c_master_send(client, buf, 1);
187 timeout = jiffies + HZ * 3;
188 for (;;) {
189 // get the current status
190 buf[0] = 0x10;
191 i2c_master_send(client, buf, 1);
192 i2c_master_recv(client, buf, 1);
193
194 if (!(buf[0] & 0x20))
195 break;
196 if (time_after(jiffies,timeout)) {
197 status = -ETIMEDOUT;
198 break;
199 }
200
201 // wait a bit
202 msleep(10);
203 }
204
205 // delay a bit to let encoder settle
206 msleep(50);
207
208 // done
209 return status;
210}
211
212
213static int saa6752hs_set_bitrate(struct i2c_client* client,
214 struct v4l2_mpeg_compression* params)
215{
216 u8 buf[3];
217
218 // set the bitrate mode
219 buf[0] = 0x71;
220 buf[1] = (params->vi_bitrate.mode == V4L2_BITRATE_VBR) ? 0 : 1;
221 i2c_master_send(client, buf, 2);
222
223 // set the video bitrate
224 if (params->vi_bitrate.mode == V4L2_BITRATE_VBR) {
225 // set the target bitrate
226 buf[0] = 0x80;
227 buf[1] = params->vi_bitrate.target >> 8;
228 buf[2] = params->vi_bitrate.target & 0xff;
229 i2c_master_send(client, buf, 3);
230
231 // set the max bitrate
232 buf[0] = 0x81;
233 buf[1] = params->vi_bitrate.max >> 8;
234 buf[2] = params->vi_bitrate.max & 0xff;
235 i2c_master_send(client, buf, 3);
236 } else {
237 // set the target bitrate (no max bitrate for CBR)
238 buf[0] = 0x81;
239 buf[1] = params->vi_bitrate.target >> 8;
240 buf[2] = params->vi_bitrate.target & 0xff;
241 i2c_master_send(client, buf, 3);
242 }
243
244 // set the audio bitrate
245 buf[0] = 0x94;
246 buf[1] = (256 == params->au_bitrate.target) ? 0 : 1;
247 i2c_master_send(client, buf, 2);
248
249 // set the total bitrate
250 buf[0] = 0xb1;
251 buf[1] = params->st_bitrate.target >> 8;
252 buf[2] = params->st_bitrate.target & 0xff;
253 i2c_master_send(client, buf, 3);
254
255 // return success
256 return 0;
257}
258
259
260static void saa6752hs_set_params(struct i2c_client* client,
261 struct v4l2_mpeg_compression* params)
262{
263 struct saa6752hs_state *h = i2c_get_clientdata(client);
264
265 /* check PIDs */
266 if (params->ts_pid_pmt <= MPEG_PID_MAX)
267 h->params.ts_pid_pmt = params->ts_pid_pmt;
268 if (params->ts_pid_pcr <= MPEG_PID_MAX)
269 h->params.ts_pid_pcr = params->ts_pid_pcr;
270 if (params->ts_pid_video <= MPEG_PID_MAX)
271 h->params.ts_pid_video = params->ts_pid_video;
272 if (params->ts_pid_audio <= MPEG_PID_MAX)
273 h->params.ts_pid_audio = params->ts_pid_audio;
274
275 /* check bitrate parameters */
276 if ((params->vi_bitrate.mode == V4L2_BITRATE_CBR) ||
277 (params->vi_bitrate.mode == V4L2_BITRATE_VBR))
278 h->params.vi_bitrate.mode = params->vi_bitrate.mode;
279 if (params->vi_bitrate.mode != V4L2_BITRATE_NONE)
280 h->params.st_bitrate.target = params->st_bitrate.target;
281 if (params->vi_bitrate.mode != V4L2_BITRATE_NONE)
282 h->params.vi_bitrate.target = params->vi_bitrate.target;
283 if (params->vi_bitrate.mode == V4L2_BITRATE_VBR)
284 h->params.vi_bitrate.max = params->vi_bitrate.max;
285 if (params->au_bitrate.mode != V4L2_BITRATE_NONE)
286 h->params.au_bitrate.target = params->au_bitrate.target;
287
288 /* aspect ratio */
289 if (params->vi_aspect_ratio == V4L2_MPEG_ASPECT_4_3 ||
290 params->vi_aspect_ratio == V4L2_MPEG_ASPECT_16_9)
291 h->params.vi_aspect_ratio = params->vi_aspect_ratio;
292
293 /* range checks */
294 if (h->params.st_bitrate.target > MPEG_TOTAL_TARGET_BITRATE_MAX)
295 h->params.st_bitrate.target = MPEG_TOTAL_TARGET_BITRATE_MAX;
296 if (h->params.vi_bitrate.target > MPEG_VIDEO_TARGET_BITRATE_MAX)
297 h->params.vi_bitrate.target = MPEG_VIDEO_TARGET_BITRATE_MAX;
298 if (h->params.vi_bitrate.max > MPEG_VIDEO_MAX_BITRATE_MAX)
299 h->params.vi_bitrate.max = MPEG_VIDEO_MAX_BITRATE_MAX;
300 if (h->params.au_bitrate.target <= 256)
301 h->params.au_bitrate.target = 256;
302 else
303 h->params.au_bitrate.target = 384;
304}
305
306static int saa6752hs_init(struct i2c_client* client)
307{
308 unsigned char buf[9], buf2[4];
309 struct saa6752hs_state *h;
310 u32 crc;
311 unsigned char localPAT[256];
312 unsigned char localPMT[256];
313
314 h = i2c_get_clientdata(client);
315
316 // Set video format - must be done first as it resets other settings
317 buf[0] = 0x41;
318 buf[1] = 0 /* MPEG_VIDEO_FORMAT_D1 */;
319 i2c_master_send(client, buf, 2);
320
321 // set bitrate
322 saa6752hs_set_bitrate(client, &h->params);
323
324 // Set GOP structure {3, 13}
325 buf[0] = 0x72;
326 buf[1] = 0x03;
327 buf[2] = 0x0D;
328 i2c_master_send(client,buf,3);
329
330 // Set minimum Q-scale {4}
331 buf[0] = 0x82;
332 buf[1] = 0x04;
333 i2c_master_send(client,buf,2);
334
335 // Set maximum Q-scale {12}
336 buf[0] = 0x83;
337 buf[1] = 0x0C;
338 i2c_master_send(client,buf,2);
339
340 // Set Output Protocol
341 buf[0] = 0xD0;
342 buf[1] = 0x81;
343 i2c_master_send(client,buf,2);
344
345 // Set video output stream format {TS}
346 buf[0] = 0xB0;
347 buf[1] = 0x05;
348 i2c_master_send(client,buf,2);
349
350 /* compute PAT */
351 memcpy(localPAT, PAT, sizeof(PAT));
352 localPAT[17] = 0xe0 | ((h->params.ts_pid_pmt >> 8) & 0x0f);
353 localPAT[18] = h->params.ts_pid_pmt & 0xff;
354 crc = crc32_be(~0, &localPAT[7], sizeof(PAT) - 7 - 4);
355 localPAT[sizeof(PAT) - 4] = (crc >> 24) & 0xFF;
356 localPAT[sizeof(PAT) - 3] = (crc >> 16) & 0xFF;
357 localPAT[sizeof(PAT) - 2] = (crc >> 8) & 0xFF;
358 localPAT[sizeof(PAT) - 1] = crc & 0xFF;
359
360 /* compute PMT */
361 memcpy(localPMT, PMT, sizeof(PMT));
362 localPMT[3] = 0x40 | ((h->params.ts_pid_pmt >> 8) & 0x0f);
363 localPMT[4] = h->params.ts_pid_pmt & 0xff;
364 localPMT[15] = 0xE0 | ((h->params.ts_pid_pcr >> 8) & 0x0F);
365 localPMT[16] = h->params.ts_pid_pcr & 0xFF;
366 localPMT[20] = 0xE0 | ((h->params.ts_pid_video >> 8) & 0x0F);
367 localPMT[21] = h->params.ts_pid_video & 0xFF;
368 localPMT[25] = 0xE0 | ((h->params.ts_pid_audio >> 8) & 0x0F);
369 localPMT[26] = h->params.ts_pid_audio & 0xFF;
370 crc = crc32_be(~0, &localPMT[7], sizeof(PMT) - 7 - 4);
371 localPMT[sizeof(PMT) - 4] = (crc >> 24) & 0xFF;
372 localPMT[sizeof(PMT) - 3] = (crc >> 16) & 0xFF;
373 localPMT[sizeof(PMT) - 2] = (crc >> 8) & 0xFF;
374 localPMT[sizeof(PMT) - 1] = crc & 0xFF;
375
376 // Set Audio PID
377 buf[0] = 0xC1;
378 buf[1] = (h->params.ts_pid_audio >> 8) & 0xFF;
379 buf[2] = h->params.ts_pid_audio & 0xFF;
380 i2c_master_send(client,buf,3);
381
382 // Set Video PID
383 buf[0] = 0xC0;
384 buf[1] = (h->params.ts_pid_video >> 8) & 0xFF;
385 buf[2] = h->params.ts_pid_video & 0xFF;
386 i2c_master_send(client,buf,3);
387
388 // Set PCR PID
389 buf[0] = 0xC4;
390 buf[1] = (h->params.ts_pid_pcr >> 8) & 0xFF;
391 buf[2] = h->params.ts_pid_pcr & 0xFF;
392 i2c_master_send(client,buf,3);
393
394 // Send SI tables
395 i2c_master_send(client,localPAT,sizeof(PAT));
396 i2c_master_send(client,localPMT,sizeof(PMT));
397
398 // mute then unmute audio. This removes buzzing artefacts
399 buf[0] = 0xa4;
400 buf[1] = 1;
401 i2c_master_send(client, buf, 2);
402 buf[1] = 0;
403 i2c_master_send(client, buf, 2);
404
405 // start it going
406 saa6752hs_chip_command(client, SAA6752HS_COMMAND_START);
407
408 // readout current state
409 buf[0] = 0xE1;
410 buf[1] = 0xA7;
411 buf[2] = 0xFE;
412 buf[3] = 0x82;
413 buf[4] = 0xB0;
414 i2c_master_send(client, buf, 5);
415 i2c_master_recv(client, buf2, 4);
416
417 // change aspect ratio
418 buf[0] = 0xE0;
419 buf[1] = 0xA7;
420 buf[2] = 0xFE;
421 buf[3] = 0x82;
422 buf[4] = 0xB0;
423 buf[5] = buf2[0];
424 switch(h->params.vi_aspect_ratio) {
425 case V4L2_MPEG_ASPECT_16_9:
426 buf[6] = buf2[1] | 0x40;
427 break;
428 case V4L2_MPEG_ASPECT_4_3:
429 default:
430 buf[6] = buf2[1] & 0xBF;
431 break;
432 break;
433 }
434 buf[7] = buf2[2];
435 buf[8] = buf2[3];
436 i2c_master_send(client, buf, 9);
437
438 // return success
439 return 0;
440}
441
442static int saa6752hs_attach(struct i2c_adapter *adap, int addr, int kind)
443{
444 struct saa6752hs_state *h;
445
446 printk("saa6752hs: chip found @ 0x%x\n", addr<<1);
447
448 if (NULL == (h = kmalloc(sizeof(*h), GFP_KERNEL)))
449 return -ENOMEM;
450 memset(h,0,sizeof(*h));
451 h->client = client_template;
452 h->params = param_defaults;
453 h->client.adapter = adap;
454 h->client.addr = addr;
455
456 i2c_set_clientdata(&h->client, h);
457 i2c_attach_client(&h->client);
458 return 0;
459}
460
461static int saa6752hs_probe(struct i2c_adapter *adap)
462{
463 if (adap->class & I2C_CLASS_TV_ANALOG)
464 return i2c_probe(adap, &addr_data, saa6752hs_attach);
465 return 0;
466}
467
468static int saa6752hs_detach(struct i2c_client *client)
469{
470 struct saa6752hs_state *h;
471
472 h = i2c_get_clientdata(client);
473 i2c_detach_client(client);
474 kfree(h);
475 return 0;
476}
477
478static int
479saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg)
480{
481 struct saa6752hs_state *h = i2c_get_clientdata(client);
482 struct v4l2_mpeg_compression *params = arg;
483 int err = 0;
484
485 switch (cmd) {
486 case VIDIOC_S_MPEGCOMP:
487 if (NULL == params) {
488 /* apply settings and start encoder */
489 saa6752hs_init(client);
490 break;
491 }
492 saa6752hs_set_params(client, params);
493 /* fall through */
494 case VIDIOC_G_MPEGCOMP:
495 *params = h->params;
496 break;
497 default:
498 /* nothing */
499 break;
500 }
501
502 return err;
503}
504
505/* ----------------------------------------------------------------------- */
506
507static struct i2c_driver driver = {
508 .owner = THIS_MODULE,
509 .name = "i2c saa6752hs MPEG encoder",
510 .id = I2C_DRIVERID_SAA6752HS,
511 .flags = I2C_DF_NOTIFY,
512 .attach_adapter = saa6752hs_probe,
513 .detach_client = saa6752hs_detach,
514 .command = saa6752hs_command,
515};
516
517static struct i2c_client client_template =
518{
519 I2C_DEVNAME("saa6752hs"),
520 .flags = I2C_CLIENT_ALLOW_USE,
521 .driver = &driver,
522};
523
524static int __init saa6752hs_init_module(void)
525{
526 return i2c_add_driver(&driver);
527}
528
529static void __exit saa6752hs_cleanup_module(void)
530{
531 i2c_del_driver(&driver);
532}
533
534module_init(saa6752hs_init_module);
535module_exit(saa6752hs_cleanup_module);
536
537/*
538 * Overrides for Emacs so that we follow Linus's tabbing style.
539 * ---------------------------------------------------------------------------
540 * Local variables:
541 * c-basic-offset: 8
542 * End:
543 */
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
new file mode 100644
index 000000000000..180d3175ea5b
--- /dev/null
+++ b/drivers/media/video/saa7134/saa7134-cards.c
@@ -0,0 +1,2018 @@
1
2/*
3 * $Id: saa7134-cards.c,v 1.54 2005/03/07 12:01:51 kraxel Exp $
4 *
5 * device driver for philips saa7134 based TV cards
6 * card-specific stuff.
7 *
8 * (c) 2001-04 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 */
24
25#include <linux/init.h>
26#include <linux/module.h>
27
28#include "saa7134-reg.h"
29#include "saa7134.h"
30
31/* commly used strings */
32static char name_mute[] = "mute";
33static char name_radio[] = "Radio";
34static char name_tv[] = "Television";
35static char name_tv_mono[] = "TV (mono only)";
36static char name_comp1[] = "Composite1";
37static char name_comp2[] = "Composite2";
38static char name_comp3[] = "Composite3";
39static char name_comp4[] = "Composite4";
40static char name_svideo[] = "S-Video";
41
42/* ------------------------------------------------------------------ */
43/* board config info */
44
45struct saa7134_board saa7134_boards[] = {
46 [SAA7134_BOARD_UNKNOWN] = {
47 .name = "UNKNOWN/GENERIC",
48 .audio_clock = 0x00187de7,
49 .tuner_type = TUNER_ABSENT,
50 .inputs = {{
51 .name = "default",
52 .vmux = 0,
53 .amux = LINE1,
54 }},
55 },
56 [SAA7134_BOARD_PROTEUS_PRO] = {
57 /* /me */
58 .name = "Proteus Pro [philips reference design]",
59 .audio_clock = 0x00187de7,
60 .tuner_type = TUNER_PHILIPS_PAL,
61 .inputs = {{
62 .name = name_comp1,
63 .vmux = 0,
64 .amux = LINE1,
65 },{
66 .name = name_tv,
67 .vmux = 1,
68 .amux = TV,
69 .tv = 1,
70 },{
71 .name = name_tv_mono,
72 .vmux = 1,
73 .amux = LINE2,
74 .tv = 1,
75 }},
76 .radio = {
77 .name = name_radio,
78 .amux = LINE2,
79 },
80 },
81 [SAA7134_BOARD_FLYVIDEO3000] = {
82 /* "Marco d'Itri" <md@Linux.IT> */
83 .name = "LifeView FlyVIDEO3000",
84 .audio_clock = 0x00200000,
85 .tuner_type = TUNER_PHILIPS_PAL,
86 .gpiomask = 0xe000,
87 .inputs = {{
88 .name = name_tv,
89 .vmux = 1,
90 .amux = TV,
91 .gpio = 0x8000,
92 .tv = 1,
93 },{
94 .name = name_tv_mono,
95 .vmux = 1,
96 .amux = LINE2,
97 .gpio = 0x0000,
98 .tv = 1,
99 },{
100 .name = name_comp1,
101 .vmux = 0,
102 .amux = LINE2,
103 .gpio = 0x4000,
104 },{
105 .name = name_comp2,
106 .vmux = 3,
107 .amux = LINE2,
108 .gpio = 0x4000,
109 },{
110 .name = name_svideo,
111 .vmux = 8,
112 .amux = LINE2,
113 .gpio = 0x4000,
114 }},
115 .radio = {
116 .name = name_radio,
117 .amux = LINE2,
118 .gpio = 0x2000,
119 },
120 },
121 [SAA7134_BOARD_FLYVIDEO2000] = {
122 /* "TC Wan" <tcwan@cs.usm.my> */
123 .name = "LifeView FlyVIDEO2000",
124 .audio_clock = 0x00200000,
125 .tuner_type = TUNER_LG_PAL_NEW_TAPC,
126 .gpiomask = 0xe000,
127 .inputs = {{
128 .name = name_tv,
129 .vmux = 1,
130 .amux = LINE2,
131 .gpio = 0x0000,
132 .tv = 1,
133 },{
134 .name = name_comp1,
135 .vmux = 0,
136 .amux = LINE2,
137 .gpio = 0x4000,
138 },{
139 .name = name_comp2,
140 .vmux = 3,
141 .amux = LINE2,
142 .gpio = 0x4000,
143 },{
144 .name = name_svideo,
145 .vmux = 8,
146 .amux = LINE2,
147 .gpio = 0x4000,
148 }},
149 .radio = {
150 .name = name_radio,
151 .amux = LINE2,
152 .gpio = 0x2000,
153 },
154 .mute = {
155 .name = name_mute,
156 .amux = LINE2,
157 .gpio = 0x8000,
158 },
159 },
160 [SAA7134_BOARD_FLYTVPLATINUM_MINI] = {
161 /* "Arnaud Quette" <aquette@free.fr> */
162 .name = "LifeView FlyTV Platinum Mini",
163 .audio_clock = 0x00200000,
164 .tuner_type = TUNER_PHILIPS_TDA8290,
165 .inputs = {{
166 .name = name_tv,
167 .vmux = 1,
168 .amux = LINE2,
169 .tv = 1,
170 },{
171 .name = name_comp1,
172 .vmux = 0,
173 .amux = LINE2,
174 },{
175 .name = name_svideo,
176 .vmux = 8,
177 .amux = LINE2,
178 }},
179 },
180 [SAA7134_BOARD_FLYTVPLATINUM_FM] = {
181 /* LifeView FlyTV Platinum FM (LR214WF) */
182 /* "Peter Missel <peter.missel@onlinehome.de> */
183 .name = "LifeView FlyTV Platinum FM",
184 .audio_clock = 0x00200000,
185 .tuner_type = TUNER_PHILIPS_TDA8290,
186// .gpiomask = 0xe000,
187 .inputs = {{
188 .name = name_tv,
189 .vmux = 1,
190 .amux = TV,
191// .gpio = 0x0000,
192 .tv = 1,
193 },{
194/* .name = name_tv_mono,
195 .vmux = 1,
196 .amux = LINE2,
197 .gpio = 0x0000,
198 .tv = 1,
199 },{
200*/ .name = name_comp1, /* Composite signal on S-Video input */
201 .vmux = 0,
202 .amux = LINE2,
203// .gpio = 0x4000,
204 },{
205 .name = name_comp2, /* Composite input */
206 .vmux = 3,
207 .amux = LINE2,
208// .gpio = 0x4000,
209 },{
210 .name = name_svideo, /* S-Video signal on S-Video input */
211 .vmux = 8,
212 .amux = LINE2,
213// .gpio = 0x4000,
214 }},
215/* .radio = {
216 .name = name_radio,
217 .amux = LINE2,
218 .gpio = 0x2000,
219 },
220*/ },
221 [SAA7134_BOARD_EMPRESS] = {
222 /* "Gert Vervoort" <gert.vervoort@philips.com> */
223 .name = "EMPRESS",
224 .audio_clock = 0x00187de7,
225 .tuner_type = TUNER_PHILIPS_PAL,
226 .inputs = {{
227 .name = name_comp1,
228 .vmux = 0,
229 .amux = LINE1,
230 },{
231 .name = name_svideo,
232 .vmux = 8,
233 .amux = LINE1,
234 },{
235 .name = name_tv,
236 .vmux = 1,
237 .amux = LINE2,
238 .tv = 1,
239 }},
240 .radio = {
241 .name = name_radio,
242 .amux = LINE2,
243 },
244 .mpeg = SAA7134_MPEG_EMPRESS,
245 .video_out = CCIR656,
246 },
247 [SAA7134_BOARD_MONSTERTV] = {
248 /* "K.Ohta" <alpha292@bremen.or.jp> */
249 .name = "SKNet Monster TV",
250 .audio_clock = 0x00187de7,
251 .tuner_type = TUNER_PHILIPS_NTSC_M,
252 .inputs = {{
253 .name = name_tv,
254 .vmux = 1,
255 .amux = TV,
256 .tv = 1,
257 },{
258 .name = name_comp1,
259 .vmux = 0,
260 .amux = LINE1,
261 },{
262 .name = name_svideo,
263 .vmux = 8,
264 .amux = LINE1,
265 }},
266 .radio = {
267 .name = name_radio,
268 .amux = LINE2,
269 },
270 },
271 [SAA7134_BOARD_MD9717] = {
272 .name = "Tevion MD 9717",
273 .audio_clock = 0x00200000,
274 .tuner_type = TUNER_PHILIPS_PAL,
275 .inputs = {{
276 .name = name_tv,
277 .vmux = 1,
278 .amux = TV,
279 .tv = 1,
280 },{
281 /* workaround for problems with normal TV sound */
282 .name = name_tv_mono,
283 .vmux = 1,
284 .amux = LINE2,
285 .tv = 1,
286 },{
287 .name = name_comp1,
288 .vmux = 2,
289 .amux = LINE1,
290 },{
291 .name = name_comp2,
292 .vmux = 3,
293 .amux = LINE1,
294 },{
295 .name = name_svideo,
296 .vmux = 8,
297 .amux = LINE1,
298 }},
299 .radio = {
300 .name = name_radio,
301 .amux = LINE2,
302 },
303 },
304 [SAA7134_BOARD_TVSTATION_RDS] = {
305 /* Typhoon TV Tuner RDS: Art.Nr. 50694 */
306 .name = "KNC One TV-Station RDS / Typhoon TV Tuner RDS",
307 .audio_clock = 0x00200000,
308 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
309 .tda9887_conf = TDA9887_PRESENT,
310 .inputs = {{
311 .name = name_tv,
312 .vmux = 1,
313 .amux = TV,
314 .tv = 1,
315 },{
316 .name = name_tv_mono,
317 .vmux = 1,
318 .amux = LINE2,
319 .tv = 1,
320 },{
321
322 .name = name_svideo,
323 .vmux = 8,
324 .amux = LINE1,
325 },{
326 .name = name_comp1,
327 .vmux = 3,
328 .amux = LINE1,
329 },{
330
331 .name = "CVid over SVid",
332 .vmux = 0,
333 .amux = LINE1,
334 }},
335 .radio = {
336 .name = name_radio,
337 .amux = LINE2,
338 },
339 },
340 [SAA7134_BOARD_TVSTATION_DVR] = {
341 .name = "KNC One TV-Station DVR",
342 .audio_clock = 0x00200000,
343 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
344 .tda9887_conf = TDA9887_PRESENT,
345 .gpiomask = 0x820000,
346 .inputs = {{
347 .name = name_tv,
348 .vmux = 1,
349 .amux = LINE2,
350 .tv = 1,
351 .gpio = 0x20000,
352 },{
353 .name = name_svideo,
354 .vmux = 8,
355 .amux = LINE1,
356 .gpio = 0x20000,
357 },{
358 .name = name_comp1,
359 .vmux = 3,
360 .amux = LINE1,
361 .gpio = 0x20000,
362 }},
363 .radio = {
364 .name = name_radio,
365 .amux = LINE2,
366 .gpio = 0x20000,
367 },
368 .mpeg = SAA7134_MPEG_EMPRESS,
369 .video_out = CCIR656,
370 },
371 [SAA7134_BOARD_CINERGY400] = {
372 .name = "Terratec Cinergy 400 TV",
373 .audio_clock = 0x00200000,
374 .tuner_type = TUNER_PHILIPS_PAL,
375 .inputs = {{
376 .name = name_tv,
377 .vmux = 1,
378 .amux = TV,
379 .tv = 1,
380 },{
381 .name = name_comp1,
382 .vmux = 4,
383 .amux = LINE1,
384 },{
385 .name = name_svideo,
386 .vmux = 8,
387 .amux = LINE1,
388 },{
389 .name = name_comp2, // CVideo over SVideo Connector
390 .vmux = 0,
391 .amux = LINE1,
392 }}
393 },
394 [SAA7134_BOARD_MD5044] = {
395 .name = "Medion 5044",
396 .audio_clock = 0x00187de7, // was: 0x00200000,
397 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
398 .tda9887_conf = TDA9887_PRESENT,
399 .inputs = {{
400 .name = name_tv,
401 .vmux = 1,
402 .amux = TV,
403 .tv = 1,
404 },{
405 /* workaround for problems with normal TV sound */
406 .name = name_tv_mono,
407 .vmux = 1,
408 .amux = LINE2,
409 .tv = 1,
410 },{
411 .name = name_comp1,
412 .vmux = 0,
413 .amux = LINE2,
414 },{
415 .name = name_comp2,
416 .vmux = 3,
417 .amux = LINE2,
418 },{
419 .name = name_svideo,
420 .vmux = 8,
421 .amux = LINE2,
422 }},
423 .radio = {
424 .name = name_radio,
425 .amux = LINE2,
426 },
427 },
428 [SAA7134_BOARD_KWORLD] = {
429 .name = "Kworld/KuroutoShikou SAA7130-TVPCI",
430 .audio_clock = 0x00187de7,
431 .tuner_type = TUNER_PHILIPS_NTSC_M,
432 .inputs = {{
433 .name = name_svideo,
434 .vmux = 8,
435 .amux = LINE1,
436 },{
437 .name = name_comp1,
438 .vmux = 3,
439 .amux = LINE1,
440 },{
441 .name = name_tv,
442 .vmux = 1,
443 .amux = LINE2,
444 .tv = 1,
445 }},
446 },
447 [SAA7134_BOARD_CINERGY600] = {
448 .name = "Terratec Cinergy 600 TV",
449 .audio_clock = 0x00200000,
450 .tuner_type = TUNER_PHILIPS_PAL,
451 .tda9887_conf = TDA9887_PRESENT,
452 .inputs = {{
453 .name = name_tv,
454 .vmux = 1,
455 .amux = TV,
456 .tv = 1,
457 },{
458 .name = name_comp1,
459 .vmux = 4,
460 .amux = LINE1,
461 },{
462 .name = name_svideo,
463 .vmux = 8,
464 .amux = LINE1,
465 },{
466 .name = name_comp2, // CVideo over SVideo Connector
467 .vmux = 0,
468 .amux = LINE1,
469 }},
470 .radio = {
471 .name = name_radio,
472 .amux = LINE2,
473 },
474 },
475 [SAA7134_BOARD_MD7134] = {
476 .name = "Medion 7134",
477 //.audio_clock = 0x00200000,
478 .audio_clock = 0x00187de7,
479 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
480 .tda9887_conf = TDA9887_PRESENT,
481 .mpeg = SAA7134_MPEG_DVB,
482 .inputs = {{
483 .name = name_tv,
484 .vmux = 1,
485 .amux = TV,
486 .tv = 1,
487 },{
488 .name = name_comp1,
489 .vmux = 0,
490 .amux = LINE1,
491 },{
492 .name = name_svideo,
493 .vmux = 8,
494 .amux = LINE1,
495 }},
496 .radio = {
497 .name = name_radio,
498 .amux = LINE2,
499 },
500 },
501 [SAA7134_BOARD_TYPHOON_90031] = {
502 /* aka Typhoon "TV+Radio", Art.Nr 90031 */
503 /* Tom Zoerner <tomzo at users sourceforge net> */
504 .name = "Typhoon TV+Radio 90031",
505 .audio_clock = 0x00200000,
506 .tuner_type = TUNER_PHILIPS_PAL,
507 .tda9887_conf = TDA9887_PRESENT,
508 .inputs = {{
509 .name = name_tv,
510 .vmux = 1,
511 .amux = TV,
512 .tv = 1,
513 },{
514 .name = name_comp1,
515 .vmux = 3,
516 .amux = LINE1,
517 },{
518 .name = name_svideo,
519 .vmux = 8,
520 .amux = LINE1,
521 }},
522 .radio = {
523 .name = name_radio,
524 .amux = LINE2,
525 },
526 },
527 [SAA7134_BOARD_ELSA] = {
528 .name = "ELSA EX-VISION 300TV",
529 .audio_clock = 0x00187de7,
530 .tuner_type = TUNER_HITACHI_NTSC,
531 .inputs = {{
532 .name = name_svideo,
533 .vmux = 8,
534 .amux = LINE1,
535 },{
536 .name = name_comp1,
537 .vmux = 0,
538 .amux = LINE1,
539 },{
540 .name = name_tv,
541 .vmux = 4,
542 .amux = LINE2,
543 .tv = 1,
544 }},
545 },
546 [SAA7134_BOARD_ELSA_500TV] = {
547 .name = "ELSA EX-VISION 500TV",
548 .audio_clock = 0x00187de7,
549 .tuner_type = TUNER_HITACHI_NTSC,
550 .inputs = {{
551 .name = name_svideo,
552 .vmux = 7,
553 .amux = LINE1,
554 },{
555 .name = name_tv,
556 .vmux = 8,
557 .amux = TV,
558 .tv = 1,
559 },{
560 .name = name_tv_mono,
561 .vmux = 8,
562 .amux = LINE2,
563 .tv = 1,
564 }},
565 },
566 [SAA7134_BOARD_ASUSTeK_TVFM7134] = {
567 .name = "ASUS TV-FM 7134",
568 .audio_clock = 0x00187de7,
569 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
570 .tda9887_conf = TDA9887_PRESENT,
571 .inputs = {{
572 .name = name_tv,
573 .vmux = 1,
574 .amux = TV,
575 .tv = 1,
576 },{
577 .name = name_comp1,
578 .vmux = 4,
579 .amux = LINE2,
580 },{
581 .name = name_svideo,
582 .vmux = 6,
583 .amux = LINE2,
584 }},
585 .radio = {
586 .name = name_radio,
587 .amux = LINE1,
588 },
589 },
590 [SAA7135_BOARD_ASUSTeK_TVFM7135] = {
591 .name = "ASUS TV-FM 7135",
592 .audio_clock = 0x00187de7,
593 .tuner_type = TUNER_PHILIPS_TDA8290,
594 .gpiomask = 0x200000,
595 .inputs = {{
596 .name = name_tv,
597 .vmux = 1,
598 .amux = TV,
599 .gpio = 0x0000,
600 .tv = 1,
601 },{
602 .name = name_comp1,
603 .vmux = 4,
604 .amux = LINE2,
605 .gpio = 0x0000,
606 },{
607 .name = name_svideo,
608 .vmux = 6,
609 .amux = LINE2,
610 .gpio = 0x0000,
611 }},
612 .radio = {
613 .name = name_radio,
614 .amux = TV,
615 .gpio = 0x200000,
616 },
617 },
618 [SAA7134_BOARD_VA1000POWER] = {
619 .name = "AOPEN VA1000 POWER",
620 .audio_clock = 0x00187de7,
621 .tuner_type = TUNER_PHILIPS_NTSC,
622 .inputs = {{
623 .name = name_svideo,
624 .vmux = 8,
625 .amux = LINE1,
626 },{
627 .name = name_comp1,
628 .vmux = 3,
629 .amux = LINE1,
630 },{
631 .name = name_tv,
632 .vmux = 1,
633 .amux = LINE2,
634 .tv = 1,
635 }},
636 },
637 [SAA7134_BOARD_10MOONSTVMASTER] = {
638 /* "lilicheng" <llc@linuxfans.org> */
639 .name = "10MOONS PCI TV CAPTURE CARD",
640 .audio_clock = 0x00200000,
641 .tuner_type = TUNER_LG_PAL_NEW_TAPC,
642 .gpiomask = 0xe000,
643 .inputs = {{
644 .name = name_tv,
645 .vmux = 1,
646 .amux = LINE2,
647 .gpio = 0x0000,
648 .tv = 1,
649 },{
650 .name = name_comp1,
651 .vmux = 0,
652 .amux = LINE2,
653 .gpio = 0x4000,
654 },{
655 .name = name_comp2,
656 .vmux = 3,
657 .amux = LINE2,
658 .gpio = 0x4000,
659 },{
660 .name = name_svideo,
661 .vmux = 8,
662 .amux = LINE2,
663 .gpio = 0x4000,
664 }},
665 .radio = {
666 .name = name_radio,
667 .amux = LINE2,
668 .gpio = 0x2000,
669 },
670 .mute = {
671 .name = name_mute,
672 .amux = LINE2,
673 .gpio = 0x8000,
674 },
675 },
676 [SAA7134_BOARD_BMK_MPEX_NOTUNER] = {
677 /* "Andrew de Quincey" <adq@lidskialf.net> */
678 .name = "BMK MPEX No Tuner",
679 .audio_clock = 0x200000,
680 .tuner_type = TUNER_ABSENT,
681 .inputs = {{
682 .name = name_comp1,
683 .vmux = 4,
684 .amux = LINE1,
685 },{
686 .name = name_comp2,
687 .vmux = 3,
688 .amux = LINE1,
689 },{
690 .name = name_comp3,
691 .vmux = 0,
692 .amux = LINE1,
693 },{
694 .name = name_comp4,
695 .vmux = 1,
696 .amux = LINE1,
697 },{
698 .name = name_svideo,
699 .vmux = 8,
700 .amux = LINE1,
701 }},
702 .mpeg = SAA7134_MPEG_EMPRESS,
703 .video_out = CCIR656,
704 },
705 [SAA7134_BOARD_VIDEOMATE_TV] = {
706 .name = "Compro VideoMate TV",
707 .audio_clock = 0x00187de7,
708 .tuner_type = TUNER_PHILIPS_NTSC_M,
709 .inputs = {{
710 .name = name_svideo,
711 .vmux = 8,
712 .amux = LINE1,
713 },{
714 .name = name_comp1,
715 .vmux = 3,
716 .amux = LINE1,
717 },{
718 .name = name_tv,
719 .vmux = 1,
720 .amux = LINE2,
721 .tv = 1,
722 }},
723 },
724 [SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUS] = {
725 .name = "Compro VideoMate TV Gold+",
726 .audio_clock = 0x00187de7,
727 .tuner_type = TUNER_PHILIPS_NTSC_M,
728 .gpiomask = 0x800c0000,
729 .inputs = {{
730 .name = name_svideo,
731 .vmux = 8,
732 .amux = LINE1,
733 .gpio = 0x06c00012,
734 },{
735 .name = name_comp1,
736 .vmux = 3,
737 .amux = LINE1,
738 .gpio = 0x0ac20012,
739 },{
740 .name = name_tv,
741 .vmux = 1,
742 .amux = LINE2,
743 .gpio = 0x08c20012,
744 .tv = 1,
745 }},
746 },
747 [SAA7134_BOARD_CRONOS_PLUS] = {
748 /* gpio pins:
749 0 .. 3 BASE_ID
750 4 .. 7 PROTECT_ID
751 8 .. 11 USER_OUT
752 12 .. 13 USER_IN
753 14 .. 15 VIDIN_SEL */
754 .name = "Matrox CronosPlus",
755 .tuner_type = TUNER_ABSENT,
756 .gpiomask = 0xcf00,
757 .inputs = {{
758 .name = name_comp1,
759 .vmux = 0,
760 .gpio = 2 << 14,
761 },{
762 .name = name_comp2,
763 .vmux = 0,
764 .gpio = 1 << 14,
765 },{
766 .name = name_comp3,
767 .vmux = 0,
768 .gpio = 0 << 14,
769 },{
770 .name = name_comp4,
771 .vmux = 0,
772 .gpio = 3 << 14,
773 },{
774 .name = name_svideo,
775 .vmux = 8,
776 .gpio = 2 << 14,
777 }},
778 },
779 [SAA7134_BOARD_MD2819] = {
780 .name = "AverMedia M156 / Medion 2819",
781 .audio_clock = 0x00187de7,
782 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
783 .tda9887_conf = TDA9887_PRESENT,
784 .inputs = {{
785 .name = name_tv,
786 .vmux = 1,
787 .amux = TV,
788 .tv = 1,
789 },{
790 .name = name_comp1,
791 .vmux = 0,
792 .amux = LINE2,
793 },{
794 .name = name_comp2,
795 .vmux = 3,
796 .amux = LINE2,
797 },{
798 .name = name_svideo,
799 .vmux = 8,
800 .amux = LINE2,
801 }},
802 .radio = {
803 .name = name_radio,
804 .amux = LINE2,
805 },
806 },
807 [SAA7134_BOARD_BMK_MPEX_TUNER] = {
808 /* "Greg Wickham <greg.wickham@grangenet.net> */
809 .name = "BMK MPEX Tuner",
810 .audio_clock = 0x200000,
811 .tuner_type = TUNER_PHILIPS_PAL,
812 .inputs = {{
813 .name = name_comp1,
814 .vmux = 1,
815 .amux = LINE1,
816 },{
817 .name = name_svideo,
818 .vmux = 8,
819 .amux = LINE1,
820 },{
821 .name = name_tv,
822 .vmux = 3,
823 .amux = TV,
824 .tv = 1,
825 }},
826 .mpeg = SAA7134_MPEG_EMPRESS,
827 .video_out = CCIR656,
828 },
829 [SAA7134_BOARD_ASUSTEK_TVFM7133] = {
830 .name = "ASUS TV-FM 7133",
831 .audio_clock = 0x00187de7,
832 // probably wrong, the 7133 one is the NTSC version ...
833 // .tuner_type = TUNER_PHILIPS_FM1236_MK3
834 .tuner_type = TUNER_LG_NTSC_NEW_TAPC,
835 .tda9887_conf = TDA9887_PRESENT,
836 .inputs = {{
837 .name = name_tv,
838 .vmux = 1,
839 .amux = TV,
840 .tv = 1,
841 },{
842 .name = name_comp1,
843 .vmux = 4,
844 .amux = LINE2,
845 },{
846 .name = name_svideo,
847 .vmux = 6,
848 .amux = LINE2,
849 }},
850 .radio = {
851 .name = name_radio,
852 .amux = LINE1,
853 },
854 },
855 [SAA7134_BOARD_PINNACLE_PCTV_STEREO] = {
856 .name = "Pinnacle PCTV Stereo (saa7134)",
857 .audio_clock = 0x00187de7,
858 .tuner_type = TUNER_MT2032,
859 .tda9887_conf = TDA9887_PRESENT | TDA9887_INTERCARRIER,
860 .inputs = {{
861 .name = name_tv,
862 .vmux = 3,
863 .amux = TV,
864 .tv = 1,
865 },{
866 .name = name_comp1,
867 .vmux = 0,
868 .amux = LINE2,
869 },{
870 .name = name_comp2,
871 .vmux = 1,
872 .amux = LINE2,
873 },{
874 .name = name_svideo,
875 .vmux = 8,
876 .amux = LINE2,
877 }},
878 },
879 [SAA7134_BOARD_MANLI_MTV002] = {
880 /* Ognjen Nastic <ognjen@logosoft.ba> */
881 .name = "Manli MuchTV M-TV002",
882 .audio_clock = 0x00200000,
883 .tuner_type = TUNER_PHILIPS_PAL,
884 .inputs = {{
885 .name = name_svideo,
886 .vmux = 8,
887 .amux = LINE1,
888 },{
889 .name = name_comp1,
890 .vmux = 1,
891 .amux = LINE1,
892 },{
893 .name = name_tv,
894 .vmux = 3,
895 .amux = LINE2,
896 .tv = 1,
897 }},
898 .radio = {
899 .name = name_radio,
900 .amux = LINE2,
901 },
902 .mute = {
903 .name = name_mute,
904 .amux = LINE1,
905 },
906 },
907 [SAA7134_BOARD_MANLI_MTV001] = {
908 /* Ognjen Nastic <ognjen@logosoft.ba> UNTESTED */
909 .name = "Manli MuchTV M-TV001",
910 .audio_clock = 0x00200000,
911 .tuner_type = TUNER_PHILIPS_PAL,
912 .inputs = {{
913 .name = name_svideo,
914 .vmux = 8,
915 .amux = LINE1,
916 },{
917 .name = name_comp1,
918 .vmux = 1,
919 .amux = LINE1,
920 },{
921 .name = name_tv,
922 .vmux = 3,
923 .amux = LINE2,
924 .tv = 1,
925 }},
926 },
927 [SAA7134_BOARD_TG3000TV] = {
928 /* TransGear 3000TV */
929 .name = "Nagase Sangyo TransGear 3000TV",
930 .audio_clock = 0x00187de7,
931 .tuner_type = TUNER_PHILIPS_NTSC_M,
932 .inputs = {{
933 .name = name_tv,
934 .vmux = 1,
935 .amux = LINE2,
936 .tv = 1,
937 },{
938 .name = name_comp1,
939 .vmux = 3,
940 .amux = LINE2,
941 },{
942 .name = name_svideo,
943 .vmux = 8,
944 .amux = LINE2,
945 }},
946 },
947 [SAA7134_BOARD_ECS_TVP3XP] = {
948 .name = "Elitegroup ECS TVP3XP FM1216 Tuner Card(PAL-BG,FM) ",
949 .audio_clock = 0x187de7, // xtal 32.1 MHz
950 .tuner_type = TUNER_PHILIPS_PAL,
951 .inputs = {{
952 .name = name_tv,
953 .vmux = 1,
954 .amux = TV,
955 .tv = 1,
956 },{
957 .name = name_tv_mono,
958 .vmux = 1,
959 .amux = LINE2,
960 .tv = 1,
961 },{
962 .name = name_comp1,
963 .vmux = 3,
964 .amux = LINE1,
965 },{
966 .name = name_svideo,
967 .vmux = 8,
968 .amux = LINE1,
969 },{
970 .name = "CVid over SVid",
971 .vmux = 0,
972 .amux = LINE1,
973 }},
974 .radio = {
975 .name = name_radio,
976 .amux = LINE2,
977 },
978 },
979 [SAA7134_BOARD_ECS_TVP3XP_4CB5] = {
980 .name = "Elitegroup ECS TVP3XP FM1236 Tuner Card (NTSC,FM)",
981 .audio_clock = 0x187de7,
982 .tuner_type = TUNER_PHILIPS_NTSC,
983 .inputs = {{
984 .name = name_tv,
985 .vmux = 1,
986 .amux = TV,
987 .tv = 1,
988 },{
989 .name = name_tv_mono,
990 .vmux = 1,
991 .amux = LINE2,
992 .tv = 1,
993 },{
994 .name = name_comp1,
995 .vmux = 3,
996 .amux = LINE1,
997 },{
998 .name = name_svideo,
999 .vmux = 8,
1000 .amux = LINE1,
1001 },{
1002 .name = "CVid over SVid",
1003 .vmux = 0,
1004 .amux = LINE1,
1005 }},
1006 .radio = {
1007 .name = name_radio,
1008 .amux = LINE2,
1009 },
1010 },
1011 [SAA7134_BOARD_AVACSSMARTTV] = {
1012 /* Roman Pszonczenko <romka@kolos.math.uni.lodz.pl> */
1013 .name = "AVACS SmartTV",
1014 .audio_clock = 0x00187de7,
1015 .tuner_type = TUNER_PHILIPS_PAL,
1016 .inputs = {{
1017 .name = name_tv,
1018 .vmux = 1,
1019 .amux = TV,
1020 .tv = 1,
1021 },{
1022 .name = name_tv_mono,
1023 .vmux = 1,
1024 .amux = LINE2,
1025 .tv = 1,
1026 },{
1027 .name = name_comp1,
1028 .vmux = 0,
1029 .amux = LINE2,
1030 },{
1031 .name = name_comp2,
1032 .vmux = 3,
1033 .amux = LINE2,
1034 },{
1035 .name = name_svideo,
1036 .vmux = 8,
1037 .amux = LINE2,
1038 }},
1039 .radio = {
1040 .name = name_radio,
1041 .amux = LINE2,
1042 .gpio = 0x200000,
1043 },
1044 },
1045 [SAA7134_BOARD_AVERMEDIA_DVD_EZMAKER] = {
1046 /* Michael Smith <msmith@cbnco.com> */
1047 .name = "AVerMedia DVD EZMaker",
1048 .audio_clock = 0x00187de7,
1049 .tuner_type = TUNER_ABSENT,
1050 .inputs = {{
1051 .name = name_comp1,
1052 .vmux = 3,
1053 },{
1054 .name = name_svideo,
1055 .vmux = 8,
1056 }},
1057 },
1058 [SAA7134_BOARD_NOVAC_PRIMETV7133] = {
1059 /* toshii@netbsd.org */
1060 .name = "Noval Prime TV 7133",
1061 .audio_clock = 0x00200000,
1062 .tuner_type = TUNER_ALPS_TSBH1_NTSC,
1063 .inputs = {{
1064 .name = name_comp1,
1065 .vmux = 3,
1066 },{
1067 .name = name_tv,
1068 .vmux = 1,
1069 .amux = TV,
1070 .tv = 1,
1071 },{
1072 .name = name_svideo,
1073 .vmux = 8,
1074 }},
1075 },
1076 [SAA7134_BOARD_AVERMEDIA_STUDIO_305] = {
1077 .name = "AverMedia AverTV Studio 305",
1078 .audio_clock = 0x00187de7,
1079 .tuner_type = TUNER_PHILIPS_FM1256_IH3,
1080 .tda9887_conf = TDA9887_PRESENT,
1081 .gpiomask = 0x3,
1082 .inputs = {{
1083 .name = name_tv,
1084 .vmux = 1,
1085 .amux = LINE2,
1086 .tv = 1,
1087 },{
1088 .name = name_comp1,
1089 .vmux = 0,
1090 .amux = LINE2,
1091 },{
1092 .name = name_comp2,
1093 .vmux = 3,
1094 .amux = LINE2,
1095 },{
1096 .name = name_svideo,
1097 .vmux = 8,
1098 .amux = LINE2,
1099 }},
1100 .radio = {
1101 .name = name_radio,
1102 .amux = LINE2,
1103 },
1104 .mute = {
1105 .name = name_mute,
1106 .amux = LINE1,
1107 },
1108 },
1109 [SAA7133_BOARD_UPMOST_PURPLE_TV] = {
1110 .name = "UPMOST PURPLE TV",
1111 .audio_clock = 0x00187de7,
1112 .tuner_type = TUNER_PHILIPS_FM1236_MK3,
1113 .tda9887_conf = TDA9887_PRESENT,
1114 .inputs = {{
1115 .name = name_tv,
1116 .vmux = 7,
1117 .amux = TV,
1118 .tv = 1,
1119 },{
1120 .name = name_svideo,
1121 .vmux = 7,
1122 .amux = LINE1,
1123 }},
1124 },
1125 [SAA7134_BOARD_ITEMS_MTV005] = {
1126 /* Norman Jonas <normanjonas@arcor.de> */
1127 .name = "Items MuchTV Plus / IT-005",
1128 .audio_clock = 0x00187de7,
1129 .tuner_type = TUNER_PHILIPS_PAL,
1130 .inputs = {{
1131 .name = name_tv,
1132 .vmux = 3,
1133 .amux = TV,
1134 .tv = 1,
1135 },{
1136 .name = name_comp1,
1137 .vmux = 1,
1138 .amux = LINE1,
1139 },{
1140 .name = name_svideo,
1141 .vmux = 8,
1142 .amux = LINE1,
1143 }},
1144 .radio = {
1145 .name = name_radio,
1146 .amux = LINE2,
1147 },
1148 },
1149 [SAA7134_BOARD_CINERGY200] = {
1150 .name = "Terratec Cinergy 200 TV",
1151 .audio_clock = 0x00200000,
1152 .tuner_type = TUNER_PHILIPS_PAL,
1153 .inputs = {{
1154 .name = name_tv,
1155 .vmux = 1,
1156 .amux = LINE2,
1157 .tv = 1,
1158 },{
1159 .name = name_comp1,
1160 .vmux = 4,
1161 .amux = LINE1,
1162 },{
1163 .name = name_svideo,
1164 .vmux = 8,
1165 .amux = LINE1,
1166 },{
1167 .name = name_comp2, // CVideo over SVideo Connector
1168 .vmux = 0,
1169 .amux = LINE1,
1170 }},
1171 .mute = {
1172 .name = name_mute,
1173 .amux = LINE2,
1174 },
1175 },
1176 [SAA7134_BOARD_VIDEOMATE_TV_PVR] = {
1177 /* Alain St-Denis <alain@topaze.homeip.net> */
1178 .name = "Compro VideoMate TV PVR/FM",
1179 .audio_clock = 0x00187de7,
1180 .tuner_type = TUNER_PHILIPS_NTSC_M,
1181 .gpiomask = 0x808c0080,
1182 .inputs = {{
1183 .name = name_svideo,
1184 .vmux = 8,
1185 .amux = LINE1,
1186 .gpio = 0x00080,
1187 },{
1188 .name = name_comp1,
1189 .vmux = 3,
1190 .amux = LINE1,
1191 .gpio = 0x00080,
1192 },{
1193 .name = name_tv,
1194 .vmux = 1,
1195 .amux = LINE2_LEFT,
1196 .tv = 1,
1197 .gpio = 0x00080,
1198 }},
1199 .radio = {
1200 .name = name_radio,
1201 .amux = LINE2,
1202 .gpio = 0x80000,
1203 },
1204 .mute = {
1205 .name = name_mute,
1206 .amux = LINE2,
1207 .gpio = 0x40000,
1208 },
1209 },
1210 [SAA7134_BOARD_SABRENT_SBTTVFM] = {
1211 /* Michael Rodriguez-Torrent <mrtorrent@asu.edu> */
1212 .name = "Sabrent SBT-TVFM (saa7130)",
1213 .audio_clock = 0x00187de7,
1214 .tuner_type = TUNER_PHILIPS_NTSC_M,
1215 .inputs = {{
1216 .name = name_comp1,
1217 .vmux = 1,
1218 .amux = LINE2,
1219 },{
1220 .name = name_tv,
1221 .vmux = 3,
1222 .amux = LINE2,
1223 .tv = 1,
1224 },{
1225 .name = name_svideo,
1226 .vmux = 8,
1227 .amux = LINE2,
1228 }},
1229 .radio = {
1230 .name = name_radio,
1231 .amux = LINE2,
1232 },
1233 },
1234 [SAA7134_BOARD_ZOLID_XPERT_TV7134] = {
1235 /* Helge Jensen <helge.jensen@slog.dk> */
1236 .name = ":Zolid Xpert TV7134",
1237 .audio_clock = 0x00187de7,
1238 .tuner_type = TUNER_PHILIPS_NTSC,
1239 .inputs = {{
1240 .name = name_svideo,
1241 .vmux = 8,
1242 .amux = LINE1,
1243 },{
1244 .name = name_comp1,
1245 .vmux = 3,
1246 .amux = LINE1,
1247 },{
1248 .name = name_tv,
1249 .vmux = 1,
1250 .amux = LINE2,
1251 .tv = 1,
1252 }},
1253 },
1254 [SAA7134_BOARD_EMPIRE_PCI_TV_RADIO_LE] = {
1255 /* "Matteo Az" <matte.az@nospam.libero.it> ;-) */
1256 .name = "Empire PCI TV-Radio LE",
1257 .audio_clock = 0x00187de7,
1258 .tuner_type = TUNER_PHILIPS_PAL,
1259 .gpiomask = 0x4000,
1260 .inputs = {{
1261 .name = name_tv_mono,
1262 .vmux = 1,
1263 .amux = LINE2,
1264 .gpio = 0x8000,
1265 .tv = 1,
1266 },{
1267 .name = name_comp1,
1268 .vmux = 3,
1269 .amux = LINE1,
1270 .gpio = 0x8000,
1271 },{
1272 .name = name_svideo,
1273 .vmux = 6,
1274 .amux = LINE1,
1275 .gpio = 0x8000,
1276 }},
1277 .radio = {
1278 .name = name_radio,
1279 .amux = LINE1,
1280 .gpio = 0x8000,
1281 },
1282 .mute = {
1283 .name = name_mute,
1284 .amux = TV,
1285 .gpio =0x8000,
1286 }
1287 },
1288 [SAA7134_BOARD_AVERMEDIA_307] = {
1289 /*
1290 Nickolay V. Shmyrev <nshmyrev@yandex.ru>
1291 Lots of thanks to Andrey Zolotarev <zolotarev_andrey@mail.ru>
1292 */
1293 .name = "Avermedia AVerTV Studio 307",
1294 .audio_clock = 0x00187de7,
1295 .tuner_type = TUNER_PHILIPS_FM1256_IH3,
1296 .tda9887_conf = TDA9887_PRESENT,
1297 .gpiomask = 0x03,
1298 .inputs = {{
1299 .name = name_tv,
1300 .vmux = 1,
1301 .amux = TV,
1302 .tv = 1,
1303 .gpio = 0x00,
1304 },{
1305 .name = name_comp1,
1306 .vmux = 0,
1307 .amux = LINE2,
1308 .gpio = 0x00,
1309 },{
1310 .name = name_comp2,
1311 .vmux = 3,
1312 .amux = LINE2,
1313 .gpio = 0x00,
1314 },{
1315 .name = name_svideo,
1316 .vmux = 8,
1317 .amux = LINE2,
1318 .gpio = 0x00,
1319 }},
1320 .radio = {
1321 .name = name_radio,
1322 .amux = LINE1,
1323 .gpio = 0x01,
1324 },
1325 },
1326 [SAA7134_BOARD_AVERMEDIA_CARDBUS] = {
1327 /* Jon Westgate <oryn@oryn.fsck.tv> */
1328 .name = "AVerMedia Cardbus TV/Radio",
1329 .audio_clock = 0x00200000,
1330 .tuner_type = TUNER_PHILIPS_PAL,
1331 .inputs = {{
1332 .name = name_tv,
1333 .vmux = 1,
1334 .amux = LINE2,
1335 .tv = 1,
1336 },{
1337 .name = name_comp1,
1338 .vmux = 3,
1339 .amux = LINE2,
1340 },{
1341 .name = name_svideo,
1342 .vmux = 8,
1343 .amux = LINE2,
1344 }},
1345 .radio = {
1346 .name = name_radio,
1347 .amux = LINE1,
1348 },
1349 },
1350 [SAA7134_BOARD_CINERGY400_CARDBUS] = {
1351 .name = "Terratec Cinergy 400 mobile",
1352 .audio_clock = 0x187de7,
1353 .tuner_type = TUNER_ALPS_TSBE5_PAL,
1354 .tda9887_conf = TDA9887_PRESENT,
1355 .inputs = {{
1356 .name = name_tv,
1357 .vmux = 1,
1358 .amux = TV,
1359 .tv = 1,
1360 },{
1361 .name = name_tv_mono,
1362 .vmux = 1,
1363 .amux = LINE2,
1364 .tv = 1,
1365 },{
1366 .name = name_comp1,
1367 .vmux = 3,
1368 .amux = LINE1,
1369 },{
1370 .name = name_svideo,
1371 .vmux = 8,
1372 .amux = LINE1,
1373 }},
1374 },
1375 [SAA7134_BOARD_CINERGY600_MK3] = {
1376 .name = "Terratec Cinergy 600 TV MK3",
1377 .audio_clock = 0x00200000,
1378 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
1379 .tda9887_conf = TDA9887_PRESENT,
1380 .inputs = {{
1381 .name = name_tv,
1382 .vmux = 1,
1383 .amux = TV,
1384 .tv = 1,
1385 },{
1386 .name = name_comp1,
1387 .vmux = 4,
1388 .amux = LINE1,
1389 },{
1390 .name = name_svideo,
1391 .vmux = 8,
1392 .amux = LINE1,
1393 },{
1394 .name = name_comp2, // CVideo over SVideo Connector
1395 .vmux = 0,
1396 .amux = LINE1,
1397 }},
1398 .radio = {
1399 .name = name_radio,
1400 .amux = LINE2,
1401 },
1402 },
1403 [SAA7134_BOARD_VIDEOMATE_GOLD_PLUS] = {
1404 /* Dylan Walkden <dylan_walkden@hotmail.com> */
1405 .name = "Compro VideoMate Gold+ Pal",
1406 .audio_clock = 0x00187de7,
1407 .tuner_type = TUNER_PHILIPS_PAL,
1408 .gpiomask = 0x1ce780,
1409 .inputs = {{
1410 .name = name_svideo,
1411 .vmux = 0, // CVideo over SVideo Connector - ok?
1412 .amux = LINE1,
1413 .gpio = 0x008080,
1414 },{
1415 .name = name_comp1,
1416 .vmux = 3,
1417 .amux = LINE1,
1418 .gpio = 0x008080,
1419 },{
1420 .name = name_tv,
1421 .vmux = 1,
1422 .amux = TV,
1423 .tv = 1,
1424 .gpio = 0x008080,
1425 }},
1426 .radio = {
1427 .name = name_radio,
1428 .amux = LINE2,
1429 .gpio = 0x80000,
1430 },
1431 .mute = {
1432 .name = name_mute,
1433 .amux = LINE2,
1434 .gpio = 0x0c8000,
1435 },
1436 },
1437 [SAA7134_BOARD_PINNACLE_300I_DVBT_PAL] = {
1438 .name = "Pinnacle PCTV 300i DVB-T + PAL",
1439 .audio_clock = 0x00187de7,
1440 .tuner_type = TUNER_MT2032,
1441 .tda9887_conf = TDA9887_PRESENT | TDA9887_INTERCARRIER,
1442 .mpeg = SAA7134_MPEG_DVB,
1443 .inputs = {{
1444 .name = name_tv,
1445 .vmux = 3,
1446 .amux = TV,
1447 .tv = 1,
1448 },{
1449 .name = name_comp1,
1450 .vmux = 0,
1451 .amux = LINE2,
1452 },{
1453 .name = name_comp2,
1454 .vmux = 1,
1455 .amux = LINE2,
1456 },{
1457 .name = name_svideo,
1458 .vmux = 8,
1459 .amux = LINE2,
1460 }},
1461 },
1462 [SAA7134_BOARD_PROVIDEO_PV952] = {
1463 /* andreas.kretschmer@web.de */
1464 .name = "ProVideo PV952",
1465 .audio_clock = 0x00187de7,
1466 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
1467 .tda9887_conf = TDA9887_PRESENT,
1468 .inputs = {{
1469 .name = name_comp1,
1470 .vmux = 0,
1471 .amux = LINE1,
1472 },{
1473 .name = name_tv,
1474 .vmux = 1,
1475 .amux = TV,
1476 .tv = 1,
1477 },{
1478 .name = name_tv_mono,
1479 .vmux = 1,
1480 .amux = LINE2,
1481 .tv = 1,
1482 }},
1483 .radio = {
1484 .name = name_radio,
1485 .amux = LINE2,
1486 },
1487 },
1488 [SAA7134_BOARD_AVERMEDIA_305] = {
1489 /* much like the "studio" version but without radio
1490 * and another tuner (sirspiritus@yandex.ru) */
1491 .name = "AverMedia AverTV/305",
1492 .audio_clock = 0x00187de7,
1493 .tuner_type = TUNER_PHILIPS_FQ1216ME,
1494 .tda9887_conf = TDA9887_PRESENT,
1495 .gpiomask = 0x3,
1496 .inputs = {{
1497 .name = name_tv,
1498 .vmux = 1,
1499 .amux = LINE2,
1500 .tv = 1,
1501 },{
1502 .name = name_comp1,
1503 .vmux = 0,
1504 .amux = LINE2,
1505 },{
1506 .name = name_comp2,
1507 .vmux = 3,
1508 .amux = LINE2,
1509 },{
1510 .name = name_svideo,
1511 .vmux = 8,
1512 .amux = LINE2,
1513 }},
1514 .mute = {
1515 .name = name_mute,
1516 .amux = LINE1,
1517 },
1518 },
1519 [SAA7134_BOARD_FLYDVBTDUO] = {
1520 /* LifeView FlyDVB-T DUO */
1521 /* "Nico Sabbi <nsabbi@tiscali.it> */
1522 .name = "LifeView FlyDVB-T DUO",
1523 .audio_clock = 0x00200000,
1524 .tuner_type = TUNER_PHILIPS_TDA8290,
1525// .gpiomask = 0xe000,
1526 .inputs = {{
1527 .name = name_tv,
1528 .vmux = 1,
1529 .amux = TV,
1530// .gpio = 0x0000,
1531 .tv = 1,
1532 },{
1533 .name = name_comp1, /* Composite signal on S-Video input */
1534 .vmux = 0,
1535 .amux = LINE2,
1536// .gpio = 0x4000,
1537 },{
1538 .name = name_comp2, /* Composite input */
1539 .vmux = 3,
1540 .amux = LINE2,
1541// .gpio = 0x4000,
1542 },{
1543 .name = name_svideo, /* S-Video signal on S-Video input */
1544 .vmux = 8,
1545 .amux = LINE2,
1546// .gpio = 0x4000,
1547 }},
1548 },
1549};
1550const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards);
1551
1552/* ------------------------------------------------------------------ */
1553/* PCI ids + subsystem IDs */
1554
1555struct pci_device_id saa7134_pci_tbl[] = {
1556 {
1557 .vendor = PCI_VENDOR_ID_PHILIPS,
1558 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
1559 .subvendor = PCI_VENDOR_ID_PHILIPS,
1560 .subdevice = 0x2001,
1561 .driver_data = SAA7134_BOARD_PROTEUS_PRO,
1562 },{
1563 .vendor = PCI_VENDOR_ID_PHILIPS,
1564 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
1565 .subvendor = PCI_VENDOR_ID_PHILIPS,
1566 .subdevice = 0x2001,
1567 .driver_data = SAA7134_BOARD_PROTEUS_PRO,
1568 },{
1569 .vendor = PCI_VENDOR_ID_PHILIPS,
1570 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
1571 .subvendor = PCI_VENDOR_ID_PHILIPS,
1572 .subdevice = 0x6752,
1573 .driver_data = SAA7134_BOARD_EMPRESS,
1574 },{
1575 .vendor = PCI_VENDOR_ID_PHILIPS,
1576 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
1577 .subvendor = 0x1131,
1578 .subdevice = 0x4e85,
1579 .driver_data = SAA7134_BOARD_MONSTERTV,
1580 },{
1581 .vendor = PCI_VENDOR_ID_PHILIPS,
1582 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
1583 .subvendor = 0x153B,
1584 .subdevice = 0x1142,
1585 .driver_data = SAA7134_BOARD_CINERGY400,
1586 },{
1587 .vendor = PCI_VENDOR_ID_PHILIPS,
1588 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
1589 .subvendor = 0x153B,
1590 .subdevice = 0x1143,
1591 .driver_data = SAA7134_BOARD_CINERGY600,
1592 },{
1593 .vendor = PCI_VENDOR_ID_PHILIPS,
1594 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
1595 .subvendor = 0x153B,
1596 .subdevice = 0x1158,
1597 .driver_data = SAA7134_BOARD_CINERGY600_MK3,
1598 },{
1599 .vendor = PCI_VENDOR_ID_PHILIPS,
1600 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
1601 .subvendor = 0x153b,
1602 .subdevice = 0x1162,
1603 .driver_data = SAA7134_BOARD_CINERGY400_CARDBUS,
1604 },{
1605 .vendor = PCI_VENDOR_ID_PHILIPS,
1606 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
1607 .subvendor = 0x5168,
1608 .subdevice = 0x0138,
1609 .driver_data = SAA7134_BOARD_FLYVIDEO3000,
1610 },{
1611 .vendor = PCI_VENDOR_ID_PHILIPS,
1612 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
1613 .subvendor = 0x4e42, //"Typhoon PCI Capture TV Card" Art.No. 50673
1614 .subdevice = 0x0138,
1615 .driver_data = SAA7134_BOARD_FLYVIDEO3000,
1616 },{
1617 .vendor = PCI_VENDOR_ID_PHILIPS,
1618 .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
1619 .subvendor = 0x5168,
1620 .subdevice = 0x0138,
1621 .driver_data = SAA7134_BOARD_FLYVIDEO2000,
1622 },{
1623 .vendor = PCI_VENDOR_ID_PHILIPS,
1624 .device = PCI_DEVICE_ID_PHILIPS_SAA7135,
1625 .subvendor = 0x5168,
1626 .subdevice = 0x0212, /* minipci, LR212 */
1627 .driver_data = SAA7134_BOARD_FLYTVPLATINUM_MINI,
1628 },{
1629 .vendor = PCI_VENDOR_ID_PHILIPS,
1630 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
1631 .subvendor = 0x5168,
1632 .subdevice = 0x0214, /* Standard PCI, LR214WF */
1633 .driver_data = SAA7134_BOARD_FLYTVPLATINUM_FM,
1634 },{
1635 .vendor = PCI_VENDOR_ID_PHILIPS,
1636 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
1637 .subvendor = 0x16be,
1638 .subdevice = 0x0003,
1639 .driver_data = SAA7134_BOARD_MD7134,
1640 },{
1641 .vendor = PCI_VENDOR_ID_PHILIPS,
1642 .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
1643 .subvendor = 0x1048,
1644 .subdevice = 0x226b,
1645 .driver_data = SAA7134_BOARD_ELSA,
1646 },{
1647 .vendor = PCI_VENDOR_ID_PHILIPS,
1648 .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
1649 .subvendor = 0x1048,
1650 .subdevice = 0x226b,
1651 .driver_data = SAA7134_BOARD_ELSA_500TV,
1652 },{
1653 .vendor = PCI_VENDOR_ID_PHILIPS,
1654 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
1655 .subvendor = PCI_VENDOR_ID_ASUSTEK,
1656 .subdevice = 0x4842,
1657 .driver_data = SAA7134_BOARD_ASUSTeK_TVFM7134,
1658 },{
1659 .vendor = PCI_VENDOR_ID_PHILIPS,
1660 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
1661 .subvendor = PCI_VENDOR_ID_ASUSTEK,
1662 .subdevice = 0x4845,
1663 .driver_data = SAA7135_BOARD_ASUSTeK_TVFM7135,
1664 },{
1665 .vendor = PCI_VENDOR_ID_PHILIPS,
1666 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
1667 .subvendor = PCI_VENDOR_ID_ASUSTEK,
1668 .subdevice = 0x4830,
1669 .driver_data = SAA7134_BOARD_ASUSTeK_TVFM7134,
1670 },{
1671 .vendor = PCI_VENDOR_ID_PHILIPS,
1672 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
1673 .subvendor = PCI_VENDOR_ID_ASUSTEK,
1674 .subdevice = 0x4843,
1675 .driver_data = SAA7134_BOARD_ASUSTEK_TVFM7133,
1676 },{
1677 .vendor = PCI_VENDOR_ID_PHILIPS,
1678 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
1679 .subvendor = PCI_VENDOR_ID_ASUSTEK,
1680 .subdevice = 0x4840,
1681 .driver_data = SAA7134_BOARD_ASUSTeK_TVFM7134,
1682 },{
1683 .vendor = PCI_VENDOR_ID_PHILIPS,
1684 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
1685 .subvendor = PCI_VENDOR_ID_PHILIPS,
1686 .subdevice = 0xfe01,
1687 .driver_data = SAA7134_BOARD_TVSTATION_RDS,
1688 },{
1689 .vendor = PCI_VENDOR_ID_PHILIPS,
1690 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
1691 .subvendor = 0x1894,
1692 .subdevice = 0xfe01,
1693 .driver_data = SAA7134_BOARD_TVSTATION_RDS,
1694 },{
1695 .vendor = PCI_VENDOR_ID_PHILIPS,
1696 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
1697 .subvendor = 0x1894,
1698 .subdevice = 0xa006,
1699 .driver_data = SAA7134_BOARD_TVSTATION_DVR,
1700 },{
1701 .vendor = PCI_VENDOR_ID_PHILIPS,
1702 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
1703 .subvendor = 0x1131,
1704 .subdevice = 0x7133,
1705 .driver_data = SAA7134_BOARD_VA1000POWER,
1706 },{
1707 .vendor = PCI_VENDOR_ID_PHILIPS,
1708 .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
1709 .subvendor = PCI_VENDOR_ID_PHILIPS,
1710 .subdevice = 0x2001,
1711 .driver_data = SAA7134_BOARD_10MOONSTVMASTER,
1712 },{
1713 .vendor = PCI_VENDOR_ID_PHILIPS,
1714 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
1715 .subvendor = 0x185b,
1716 .subdevice = 0xc100,
1717 .driver_data = SAA7134_BOARD_VIDEOMATE_TV,
1718 },{
1719 .vendor = PCI_VENDOR_ID_PHILIPS,
1720 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
1721 .subvendor = 0x185b,
1722 .subdevice = 0xc100,
1723 .driver_data = SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUS,
1724 },{
1725 .vendor = PCI_VENDOR_ID_PHILIPS,
1726 .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
1727 .subvendor = PCI_VENDOR_ID_MATROX,
1728 .subdevice = 0x48d0,
1729 .driver_data = SAA7134_BOARD_CRONOS_PLUS,
1730 },{
1731 .vendor = PCI_VENDOR_ID_PHILIPS,
1732 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
1733 .subvendor = 0x1461, /* Avermedia Technologies Inc */
1734 .subdevice = 0xa70b,
1735 .driver_data = SAA7134_BOARD_MD2819,
1736 },{
1737 .vendor = PCI_VENDOR_ID_PHILIPS,
1738 .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
1739 .subvendor = 0x1461, /* Avermedia Technologies Inc */
1740 .subdevice = 0x2115,
1741 .driver_data = SAA7134_BOARD_AVERMEDIA_STUDIO_305,
1742 },{
1743 .vendor = PCI_VENDOR_ID_PHILIPS,
1744 .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
1745 .subvendor = 0x1461, /* Avermedia Technologies Inc */
1746 .subdevice = 0x2108,
1747 .driver_data = SAA7134_BOARD_AVERMEDIA_305,
1748 },{
1749 .vendor = PCI_VENDOR_ID_PHILIPS,
1750 .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
1751 .subvendor = 0x1461, /* Avermedia Technologies Inc */
1752 .subdevice = 0x10ff,
1753 .driver_data = SAA7134_BOARD_AVERMEDIA_DVD_EZMAKER,
1754 },{
1755 /* AVerMedia CardBus */
1756 .vendor = PCI_VENDOR_ID_PHILIPS,
1757 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
1758 .subvendor = 0x1461, /* Avermedia Technologies Inc */
1759 .subdevice = 0xd6ee,
1760 .driver_data = SAA7134_BOARD_AVERMEDIA_CARDBUS,
1761 },{
1762 /* TransGear 3000TV */
1763 .vendor = PCI_VENDOR_ID_PHILIPS,
1764 .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
1765 .subvendor = 0x1461, /* Avermedia Technologies Inc */
1766 .subdevice = 0x050c,
1767 .driver_data = SAA7134_BOARD_TG3000TV,
1768 },{
1769 .vendor = PCI_VENDOR_ID_PHILIPS,
1770 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
1771 .subvendor = 0x11bd,
1772 .subdevice = 0x002b,
1773 .driver_data = SAA7134_BOARD_PINNACLE_PCTV_STEREO,
1774 },{
1775 .vendor = PCI_VENDOR_ID_PHILIPS,
1776 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
1777 .subvendor = 0x11bd,
1778 .subdevice = 0x002d,
1779 .driver_data = SAA7134_BOARD_PINNACLE_300I_DVBT_PAL,
1780 },{
1781 .vendor = PCI_VENDOR_ID_PHILIPS,
1782 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
1783 .subvendor = 0x1019,
1784 .subdevice = 0x4cb4,
1785 .driver_data = SAA7134_BOARD_ECS_TVP3XP,
1786 },{
1787 .vendor = PCI_VENDOR_ID_PHILIPS,
1788 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
1789 .subvendor = 0x1019,
1790 .subdevice = 0x4cb5,
1791 .driver_data = SAA7134_BOARD_ECS_TVP3XP_4CB5,
1792 },{
1793 .vendor = PCI_VENDOR_ID_PHILIPS,
1794 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
1795 .subvendor = 0x12ab,
1796 .subdevice = 0x0800,
1797 .driver_data = SAA7133_BOARD_UPMOST_PURPLE_TV,
1798 },{
1799 .vendor = PCI_VENDOR_ID_PHILIPS,
1800 .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
1801 .subvendor = 0x153B,
1802 .subdevice = 0x1152,
1803 .driver_data = SAA7134_BOARD_CINERGY200,
1804 },{
1805 .vendor = PCI_VENDOR_ID_PHILIPS,
1806 .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
1807 .subvendor = 0x185b,
1808 .subdevice = 0xc100,
1809 .driver_data = SAA7134_BOARD_VIDEOMATE_TV_PVR,
1810 },{
1811 .vendor = PCI_VENDOR_ID_PHILIPS,
1812 .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
1813 .subvendor = 0x1131,
1814 .subdevice = 0,
1815 .driver_data = SAA7134_BOARD_SABRENT_SBTTVFM,
1816 },{
1817 .vendor = PCI_VENDOR_ID_PHILIPS,
1818 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
1819 .subvendor = 0x1461, /* Avermedia Technologies Inc */
1820 .subdevice = 0x9715,
1821 .driver_data = SAA7134_BOARD_AVERMEDIA_307,
1822 },{
1823 .vendor = PCI_VENDOR_ID_PHILIPS,
1824 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
1825 .subvendor = 0x185b,
1826 .subdevice = 0xc200,
1827 .driver_data = SAA7134_BOARD_VIDEOMATE_GOLD_PLUS,
1828 },{
1829 .vendor = PCI_VENDOR_ID_PHILIPS,
1830 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
1831 .subvendor = 0x1540,
1832 .subdevice = 0x9524,
1833 .driver_data = SAA7134_BOARD_PROVIDEO_PV952,
1834
1835 },{
1836 .vendor = PCI_VENDOR_ID_PHILIPS,
1837 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
1838 .subvendor = 0x5168,
1839 .subdevice = 0x0306,
1840 .driver_data = SAA7134_BOARD_FLYDVBTDUO,
1841
1842 },{
1843 /* --- boards without eeprom + subsystem ID --- */
1844 .vendor = PCI_VENDOR_ID_PHILIPS,
1845 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
1846 .subvendor = PCI_VENDOR_ID_PHILIPS,
1847 .subdevice = 0,
1848 .driver_data = SAA7134_BOARD_NOAUTO,
1849 },{
1850 .vendor = PCI_VENDOR_ID_PHILIPS,
1851 .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
1852 .subvendor = PCI_VENDOR_ID_PHILIPS,
1853 .subdevice = 0,
1854 .driver_data = SAA7134_BOARD_NOAUTO,
1855 },{
1856
1857 /* --- default catch --- */
1858 .vendor = PCI_VENDOR_ID_PHILIPS,
1859 .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
1860 .subvendor = PCI_ANY_ID,
1861 .subdevice = PCI_ANY_ID,
1862 .driver_data = SAA7134_BOARD_UNKNOWN,
1863 },{
1864 .vendor = PCI_VENDOR_ID_PHILIPS,
1865 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
1866 .subvendor = PCI_ANY_ID,
1867 .subdevice = PCI_ANY_ID,
1868 .driver_data = SAA7134_BOARD_UNKNOWN,
1869 },{
1870 .vendor = PCI_VENDOR_ID_PHILIPS,
1871 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
1872 .subvendor = PCI_ANY_ID,
1873 .subdevice = PCI_ANY_ID,
1874 .driver_data = SAA7134_BOARD_UNKNOWN,
1875 },{
1876 .vendor = PCI_VENDOR_ID_PHILIPS,
1877 .device = PCI_DEVICE_ID_PHILIPS_SAA7135,
1878 .subvendor = PCI_ANY_ID,
1879 .subdevice = PCI_ANY_ID,
1880 .driver_data = SAA7134_BOARD_UNKNOWN,
1881 },{
1882 /* --- end of list --- */
1883 }
1884};
1885MODULE_DEVICE_TABLE(pci, saa7134_pci_tbl);
1886
1887/* ----------------------------------------------------------- */
1888/* flyvideo tweaks */
1889
1890#if 0
1891static struct {
1892 char *model;
1893 int tuner_type;
1894} fly_list[0x20] = {
1895 /* default catch ... */
1896 [ 0 ... 0x1f ] = {
1897 .model = "UNKNOWN",
1898 .tuner_type = TUNER_ABSENT,
1899 },
1900 /* ... the ones known so far */
1901 [ 0x05 ] = {
1902 .model = "PAL-BG",
1903 .tuner_type = TUNER_LG_PAL_NEW_TAPC,
1904 },
1905 [ 0x10 ] = {
1906 .model = "PAL-BG / PAL-DK",
1907 .tuner_type = TUNER_PHILIPS_PAL,
1908 },
1909 [ 0x15 ] = {
1910 .model = "NTSC",
1911 .tuner_type = TUNER_ABSENT /* FIXME */,
1912 },
1913};
1914#endif
1915
1916static void board_flyvideo(struct saa7134_dev *dev)
1917{
1918#if 0
1919 /* non-working attempt to detect the correct tuner type ... */
1920 u32 value;
1921 int index;
1922
1923 value = dev->gpio_value;
1924 index = (value & 0x1f00) >> 8;
1925 printk(KERN_INFO "%s: flyvideo: gpio is 0x%x [model=%s,tuner=%d]\n",
1926 dev->name, value, fly_list[index].model,
1927 fly_list[index].tuner_type);
1928 dev->tuner_type = fly_list[index].tuner_type;
1929#endif
1930 printk("%s: there are different flyvideo cards with different tuners\n"
1931 "%s: out there, you might have to use the tuner=<nr> insmod\n"
1932 "%s: option to override the default value.\n",
1933 dev->name, dev->name, dev->name);
1934}
1935
1936/* ----------------------------------------------------------- */
1937
1938int saa7134_board_init1(struct saa7134_dev *dev)
1939{
1940 // Always print gpio, often manufacturers encode tuner type and other info.
1941 saa_writel(SAA7134_GPIO_GPMODE0 >> 2, 0);
1942 dev->gpio_value = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2);
1943 printk(KERN_INFO "%s: board init: gpio is %x\n", dev->name, dev->gpio_value);
1944
1945 switch (dev->board) {
1946 case SAA7134_BOARD_FLYVIDEO2000:
1947 case SAA7134_BOARD_FLYVIDEO3000:
1948 dev->has_remote = 1;
1949 board_flyvideo(dev);
1950 break;
1951 case SAA7134_BOARD_CINERGY400:
1952 case SAA7134_BOARD_CINERGY600:
1953 case SAA7134_BOARD_CINERGY600_MK3:
1954 case SAA7134_BOARD_ECS_TVP3XP:
1955 case SAA7134_BOARD_ECS_TVP3XP_4CB5:
1956 case SAA7134_BOARD_MD2819:
1957 case SAA7134_BOARD_AVERMEDIA_STUDIO_305:
1958 case SAA7134_BOARD_AVERMEDIA_305:
1959 case SAA7134_BOARD_AVERMEDIA_307:
1960// case SAA7134_BOARD_SABRENT_SBTTVFM: /* not finished yet */
1961 case SAA7134_BOARD_VIDEOMATE_TV_PVR:
1962 dev->has_remote = 1;
1963 break;
1964 case SAA7134_BOARD_AVACSSMARTTV:
1965 dev->has_remote = 1;
1966 break;
1967 case SAA7134_BOARD_MD5044:
1968 printk("%s: seems there are two different versions of the MD5044\n"
1969 "%s: (with the same ID) out there. If sound doesn't work for\n"
1970 "%s: you try the audio_clock_override=0x200000 insmod option.\n",
1971 dev->name,dev->name,dev->name);
1972 break;
1973 case SAA7134_BOARD_CINERGY400_CARDBUS:
1974 /* power-up tuner chip */
1975 saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x00040000, 0x00040000);
1976 saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x00040000, 0x00000000);
1977 msleep(1);
1978 break;
1979 }
1980 if (dev->has_remote)
1981 dev->irq2_mask |= (SAA7134_IRQ2_INTE_GPIO18 |
1982 SAA7134_IRQ2_INTE_GPIO18A |
1983 SAA7134_IRQ2_INTE_GPIO16 );
1984 return 0;
1985}
1986
1987/* stuff which needs working i2c */
1988int saa7134_board_init2(struct saa7134_dev *dev)
1989{
1990 unsigned char buf;
1991 int board;
1992
1993 switch (dev->board) {
1994 case SAA7134_BOARD_BMK_MPEX_NOTUNER:
1995 case SAA7134_BOARD_BMK_MPEX_TUNER:
1996 dev->i2c_client.addr = 0x60;
1997 board = (i2c_master_recv(&dev->i2c_client,&buf,0) < 0)
1998 ? SAA7134_BOARD_BMK_MPEX_NOTUNER
1999 : SAA7134_BOARD_BMK_MPEX_TUNER;
2000 if (board == dev->board)
2001 break;
2002 dev->board = board;
2003 printk("%s: board type fixup: %s\n", dev->name,
2004 saa7134_boards[dev->board].name);
2005 dev->tuner_type = saa7134_boards[dev->board].tuner_type;
2006 if (TUNER_ABSENT != dev->tuner_type)
2007 saa7134_i2c_call_clients(dev,TUNER_SET_TYPE,&dev->tuner_type);
2008 break;
2009 }
2010 return 0;
2011}
2012
2013/* ----------------------------------------------------------- */
2014/*
2015 * Local variables:
2016 * c-basic-offset: 8
2017 * End:
2018 */
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c
new file mode 100644
index 000000000000..d506cafba8ff
--- /dev/null
+++ b/drivers/media/video/saa7134/saa7134-core.c
@@ -0,0 +1,1237 @@
1/*
2 * $Id: saa7134-core.c,v 1.28 2005/02/22 09:56:29 kraxel Exp $
3 *
4 * device driver for philips saa7134 based TV cards
5 * driver core
6 *
7 * (c) 2001-03 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include <linux/config.h>
25#include <linux/init.h>
26#include <linux/list.h>
27#include <linux/module.h>
28#include <linux/moduleparam.h>
29#include <linux/kernel.h>
30#include <linux/slab.h>
31#include <linux/kmod.h>
32#include <linux/sound.h>
33#include <linux/interrupt.h>
34#include <linux/delay.h>
35
36#include "saa7134-reg.h"
37#include "saa7134.h"
38
39MODULE_DESCRIPTION("v4l2 driver module for saa7130/34 based TV cards");
40MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
41MODULE_LICENSE("GPL");
42
43/* ------------------------------------------------------------------ */
44
45static unsigned int irq_debug = 0;
46module_param(irq_debug, int, 0644);
47MODULE_PARM_DESC(irq_debug,"enable debug messages [IRQ handler]");
48
49static unsigned int core_debug = 0;
50module_param(core_debug, int, 0644);
51MODULE_PARM_DESC(core_debug,"enable debug messages [core]");
52
53static unsigned int gpio_tracking = 0;
54module_param(gpio_tracking, int, 0644);
55MODULE_PARM_DESC(gpio_tracking,"enable debug messages [gpio]");
56
57static unsigned int oss = 0;
58module_param(oss, int, 0444);
59MODULE_PARM_DESC(oss,"register oss devices (default: no)");
60
61static unsigned int latency = UNSET;
62module_param(latency, int, 0444);
63MODULE_PARM_DESC(latency,"pci latency timer");
64
65static unsigned int video_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
66static unsigned int vbi_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
67static unsigned int radio_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
68static unsigned int dsp_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
69static unsigned int mixer_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
70static unsigned int tuner[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
71static unsigned int card[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
72
73module_param_array(video_nr, int, NULL, 0444);
74module_param_array(vbi_nr, int, NULL, 0444);
75module_param_array(radio_nr, int, NULL, 0444);
76module_param_array(dsp_nr, int, NULL, 0444);
77module_param_array(mixer_nr, int, NULL, 0444);
78module_param_array(tuner, int, NULL, 0444);
79module_param_array(card, int, NULL, 0444);
80
81MODULE_PARM_DESC(video_nr, "video device number");
82MODULE_PARM_DESC(vbi_nr, "vbi device number");
83MODULE_PARM_DESC(radio_nr, "radio device number");
84MODULE_PARM_DESC(dsp_nr, "oss dsp device number");
85MODULE_PARM_DESC(mixer_nr, "oss mixer device number");
86MODULE_PARM_DESC(tuner, "tuner type");
87MODULE_PARM_DESC(card, "card type");
88
89static DECLARE_MUTEX(devlist_lock);
90LIST_HEAD(saa7134_devlist);
91static LIST_HEAD(mops_list);
92static unsigned int saa7134_devcount;
93
94#define dprintk(fmt, arg...) if (core_debug) \
95 printk(KERN_DEBUG "%s/core: " fmt, dev->name , ## arg)
96
97/* ------------------------------------------------------------------ */
98/* debug help functions */
99
100static const char *v4l1_ioctls[] = {
101 "0", "GCAP", "GCHAN", "SCHAN", "GTUNER", "STUNER", "GPICT", "SPICT",
102 "CCAPTURE", "GWIN", "SWIN", "GFBUF", "SFBUF", "KEY", "GFREQ",
103 "SFREQ", "GAUDIO", "SAUDIO", "SYNC", "MCAPTURE", "GMBUF", "GUNIT",
104 "GCAPTURE", "SCAPTURE", "SPLAYMODE", "SWRITEMODE", "GPLAYINFO",
105 "SMICROCODE", "GVBIFMT", "SVBIFMT" };
106#define V4L1_IOCTLS ARRAY_SIZE(v4l1_ioctls)
107
108static const char *v4l2_ioctls[] = {
109 "QUERYCAP", "1", "ENUM_PIXFMT", "ENUM_FBUFFMT", "G_FMT", "S_FMT",
110 "G_COMP", "S_COMP", "REQBUFS", "QUERYBUF", "G_FBUF", "S_FBUF",
111 "G_WIN", "S_WIN", "PREVIEW", "QBUF", "16", "DQBUF", "STREAMON",
112 "STREAMOFF", "G_PERF", "G_PARM", "S_PARM", "G_STD", "S_STD",
113 "ENUMSTD", "ENUMINPUT", "G_CTRL", "S_CTRL", "G_TUNER", "S_TUNER",
114 "G_FREQ", "S_FREQ", "G_AUDIO", "S_AUDIO", "35", "QUERYCTRL",
115 "QUERYMENU", "G_INPUT", "S_INPUT", "ENUMCVT", "41", "42", "43",
116 "44", "45", "G_OUTPUT", "S_OUTPUT", "ENUMOUTPUT", "G_AUDOUT",
117 "S_AUDOUT", "ENUMFX", "G_EFFECT", "S_EFFECT", "G_MODULATOR",
118 "S_MODULATOR"
119};
120#define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
121
122static const char *osspcm_ioctls[] = {
123 "RESET", "SYNC", "SPEED", "STEREO", "GETBLKSIZE", "SETFMT",
124 "CHANNELS", "?", "POST", "SUBDIVIDE", "SETFRAGMENT", "GETFMTS",
125 "GETOSPACE", "GETISPACE", "NONBLOCK", "GETCAPS", "GET/SETTRIGGER",
126 "GETIPTR", "GETOPTR", "MAPINBUF", "MAPOUTBUF", "SETSYNCRO",
127 "SETDUPLEX", "GETODELAY"
128};
129#define OSSPCM_IOCTLS ARRAY_SIZE(v4l2_ioctls)
130
131void saa7134_print_ioctl(char *name, unsigned int cmd)
132{
133 char *dir;
134
135 switch (_IOC_DIR(cmd)) {
136 case _IOC_NONE: dir = "--"; break;
137 case _IOC_READ: dir = "r-"; break;
138 case _IOC_WRITE: dir = "-w"; break;
139 case _IOC_READ | _IOC_WRITE: dir = "rw"; break;
140 default: dir = "??"; break;
141 }
142 switch (_IOC_TYPE(cmd)) {
143 case 'v':
144 printk(KERN_DEBUG "%s: ioctl 0x%08x (v4l1, %s, VIDIOC%s)\n",
145 name, cmd, dir, (_IOC_NR(cmd) < V4L1_IOCTLS) ?
146 v4l1_ioctls[_IOC_NR(cmd)] : "???");
147 break;
148 case 'V':
149 printk(KERN_DEBUG "%s: ioctl 0x%08x (v4l2, %s, VIDIOC_%s)\n",
150 name, cmd, dir, (_IOC_NR(cmd) < V4L2_IOCTLS) ?
151 v4l2_ioctls[_IOC_NR(cmd)] : "???");
152 break;
153 case 'P':
154 printk(KERN_DEBUG "%s: ioctl 0x%08x (oss dsp, %s, SNDCTL_DSP_%s)\n",
155 name, cmd, dir, (_IOC_NR(cmd) < OSSPCM_IOCTLS) ?
156 osspcm_ioctls[_IOC_NR(cmd)] : "???");
157 break;
158 case 'M':
159 printk(KERN_DEBUG "%s: ioctl 0x%08x (oss mixer, %s, #%d)\n",
160 name, cmd, dir, _IOC_NR(cmd));
161 break;
162 default:
163 printk(KERN_DEBUG "%s: ioctl 0x%08x (???, %s, #%d)\n",
164 name, cmd, dir, _IOC_NR(cmd));
165 }
166}
167
168void saa7134_track_gpio(struct saa7134_dev *dev, char *msg)
169{
170 unsigned long mode,status;
171
172 if (!gpio_tracking)
173 return;
174 /* rising SAA7134_GPIO_GPRESCAN reads the status */
175 saa_andorb(SAA7134_GPIO_GPMODE3,SAA7134_GPIO_GPRESCAN,0);
176 saa_andorb(SAA7134_GPIO_GPMODE3,SAA7134_GPIO_GPRESCAN,SAA7134_GPIO_GPRESCAN);
177 mode = saa_readl(SAA7134_GPIO_GPMODE0 >> 2) & 0xfffffff;
178 status = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2) & 0xfffffff;
179 printk(KERN_DEBUG
180 "%s: gpio: mode=0x%07lx in=0x%07lx out=0x%07lx [%s]\n",
181 dev->name, mode, (~mode) & status, mode & status, msg);
182}
183
184/* ------------------------------------------------------------------ */
185
186#if 0
187static char *dec1_bits[8] = {
188 "DCSTD0", "DCSCT1", "WIPA", "GLIMB",
189 "GLIMT", "SLTCA", "HLCK"
190};
191static char *dec2_bits[8] = {
192 "RDCAP", "COPRO", "COLSTR", "TYPE3",
193 NULL, "FIDT", "HLVLN", "INTL"
194};
195static char *scale1_bits[8] = {
196 "VID_A", "VBI_A", NULL, NULL, "VID_B", "VBI_B"
197};
198static char *scale2_bits[8] = {
199 "TRERR", "CFERR", "LDERR", "WASRST",
200 "FIDSCI", "FIDSCO", "D6^D5", "TASK"
201};
202
203static void dump_statusreg(struct saa7134_dev *dev, int reg,
204 char *regname, char **bits)
205{
206 int value,i;
207
208 value = saa_readb(reg);
209 printk(KERN_DEBUG "%s: %s:", dev->name, regname);
210 for (i = 7; i >= 0; i--) {
211 if (NULL == bits[i])
212 continue;
213 printk(" %s=%d", bits[i], (value & (1 << i)) ? 1 : 0);
214 }
215 printk("\n");
216}
217
218static void dump_statusregs(struct saa7134_dev *dev)
219{
220 dump_statusreg(dev,SAA7134_STATUS_VIDEO1,"dec1",dec1_bits);
221 dump_statusreg(dev,SAA7134_STATUS_VIDEO2,"dec2",dec2_bits);
222 dump_statusreg(dev,SAA7134_SCALER_STATUS0,"scale0",scale1_bits);
223 dump_statusreg(dev,SAA7134_SCALER_STATUS1,"scale1",scale2_bits);
224}
225#endif
226
227/* ----------------------------------------------------------- */
228/* delayed request_module */
229
230#ifdef CONFIG_MODULES
231
232static int need_empress;
233static int need_dvb;
234
235static int pending_call(struct notifier_block *self, unsigned long state,
236 void *module)
237{
238 if (module != THIS_MODULE || state != MODULE_STATE_LIVE)
239 return NOTIFY_DONE;
240
241 if (need_empress)
242 request_module("saa7134-empress");
243 if (need_dvb)
244 request_module("saa7134-dvb");
245 return NOTIFY_DONE;
246}
247
248static int pending_registered;
249static struct notifier_block pending_notifier = {
250 .notifier_call = pending_call,
251};
252
253static void request_module_depend(char *name, int *flag)
254{
255 switch (THIS_MODULE->state) {
256 case MODULE_STATE_COMING:
257 if (!pending_registered) {
258 register_module_notifier(&pending_notifier);
259 pending_registered = 1;
260 }
261 *flag = 1;
262 break;
263 case MODULE_STATE_LIVE:
264 request_module(name);
265 break;
266 default:
267 /* nothing */;
268 break;
269 }
270}
271
272#else
273
274#define request_module_depend(name,flag)
275
276#endif /* CONFIG_MODULES */
277
278/* ------------------------------------------------------------------ */
279
280/* nr of (saa7134-)pages for the given buffer size */
281static int saa7134_buffer_pages(int size)
282{
283 size = PAGE_ALIGN(size);
284 size += PAGE_SIZE; /* for non-page-aligned buffers */
285 size /= 4096;
286 return size;
287}
288
289/* calc max # of buffers from size (must not exceed the 4MB virtual
290 * address space per DMA channel) */
291int saa7134_buffer_count(unsigned int size, unsigned int count)
292{
293 unsigned int maxcount;
294
295 maxcount = 1024 / saa7134_buffer_pages(size);
296 if (count > maxcount)
297 count = maxcount;
298 return count;
299}
300
301int saa7134_buffer_startpage(struct saa7134_buf *buf)
302{
303 return saa7134_buffer_pages(buf->vb.bsize) * buf->vb.i;
304}
305
306unsigned long saa7134_buffer_base(struct saa7134_buf *buf)
307{
308 unsigned long base;
309
310 base = saa7134_buffer_startpage(buf) * 4096;
311 base += buf->vb.dma.sglist[0].offset;
312 return base;
313}
314
315/* ------------------------------------------------------------------ */
316
317int saa7134_pgtable_alloc(struct pci_dev *pci, struct saa7134_pgtable *pt)
318{
319 u32 *cpu;
320 dma_addr_t dma_addr;
321
322 cpu = pci_alloc_consistent(pci, SAA7134_PGTABLE_SIZE, &dma_addr);
323 if (NULL == cpu)
324 return -ENOMEM;
325 pt->size = SAA7134_PGTABLE_SIZE;
326 pt->cpu = cpu;
327 pt->dma = dma_addr;
328 return 0;
329}
330
331int saa7134_pgtable_build(struct pci_dev *pci, struct saa7134_pgtable *pt,
332 struct scatterlist *list, unsigned int length,
333 unsigned int startpage)
334{
335 u32 *ptr;
336 unsigned int i,p;
337
338 BUG_ON(NULL == pt || NULL == pt->cpu);
339
340 ptr = pt->cpu + startpage;
341 for (i = 0; i < length; i++, list++)
342 for (p = 0; p * 4096 < list->length; p++, ptr++)
343 *ptr = sg_dma_address(list) - list->offset;
344 return 0;
345}
346
347void saa7134_pgtable_free(struct pci_dev *pci, struct saa7134_pgtable *pt)
348{
349 if (NULL == pt->cpu)
350 return;
351 pci_free_consistent(pci, pt->size, pt->cpu, pt->dma);
352 pt->cpu = NULL;
353}
354
355/* ------------------------------------------------------------------ */
356
357void saa7134_dma_free(struct saa7134_dev *dev,struct saa7134_buf *buf)
358{
359 if (in_interrupt())
360 BUG();
361
362 videobuf_waiton(&buf->vb,0,0);
363 videobuf_dma_pci_unmap(dev->pci, &buf->vb.dma);
364 videobuf_dma_free(&buf->vb.dma);
365 buf->vb.state = STATE_NEEDS_INIT;
366}
367
368/* ------------------------------------------------------------------ */
369
370int saa7134_buffer_queue(struct saa7134_dev *dev,
371 struct saa7134_dmaqueue *q,
372 struct saa7134_buf *buf)
373{
374 struct saa7134_buf *next = NULL;
375
376 assert_spin_locked(&dev->slock);
377 dprintk("buffer_queue %p\n",buf);
378 if (NULL == q->curr) {
379 if (!q->need_two) {
380 q->curr = buf;
381 buf->activate(dev,buf,NULL);
382 } else if (list_empty(&q->queue)) {
383 list_add_tail(&buf->vb.queue,&q->queue);
384 buf->vb.state = STATE_QUEUED;
385 } else {
386 next = list_entry(q->queue.next,struct saa7134_buf,
387 vb.queue);
388 q->curr = buf;
389 buf->activate(dev,buf,next);
390 }
391 } else {
392 list_add_tail(&buf->vb.queue,&q->queue);
393 buf->vb.state = STATE_QUEUED;
394 }
395 return 0;
396}
397
398void saa7134_buffer_finish(struct saa7134_dev *dev,
399 struct saa7134_dmaqueue *q,
400 unsigned int state)
401{
402 assert_spin_locked(&dev->slock);
403 dprintk("buffer_finish %p\n",q->curr);
404
405 /* finish current buffer */
406 q->curr->vb.state = state;
407 do_gettimeofday(&q->curr->vb.ts);
408 wake_up(&q->curr->vb.done);
409 q->curr = NULL;
410}
411
412void saa7134_buffer_next(struct saa7134_dev *dev,
413 struct saa7134_dmaqueue *q)
414{
415 struct saa7134_buf *buf,*next = NULL;
416
417 assert_spin_locked(&dev->slock);
418 BUG_ON(NULL != q->curr);
419
420 if (!list_empty(&q->queue)) {
421 /* activate next one from queue */
422 buf = list_entry(q->queue.next,struct saa7134_buf,vb.queue);
423 dprintk("buffer_next %p [prev=%p/next=%p]\n",
424 buf,q->queue.prev,q->queue.next);
425 list_del(&buf->vb.queue);
426 if (!list_empty(&q->queue))
427 next = list_entry(q->queue.next,struct saa7134_buf,
428 vb.queue);
429 q->curr = buf;
430 buf->activate(dev,buf,next);
431 dprintk("buffer_next #2 prev=%p/next=%p\n",
432 q->queue.prev,q->queue.next);
433 } else {
434 /* nothing to do -- just stop DMA */
435 dprintk("buffer_next %p\n",NULL);
436 saa7134_set_dmabits(dev);
437 del_timer(&q->timeout);
438 }
439}
440
441void saa7134_buffer_timeout(unsigned long data)
442{
443 struct saa7134_dmaqueue *q = (struct saa7134_dmaqueue*)data;
444 struct saa7134_dev *dev = q->dev;
445 unsigned long flags;
446
447 spin_lock_irqsave(&dev->slock,flags);
448
449 /* try to reset the hardware (SWRST) */
450 saa_writeb(SAA7134_REGION_ENABLE, 0x00);
451 saa_writeb(SAA7134_REGION_ENABLE, 0x80);
452 saa_writeb(SAA7134_REGION_ENABLE, 0x00);
453
454 /* flag current buffer as failed,
455 try to start over with the next one. */
456 if (q->curr) {
457 dprintk("timeout on %p\n",q->curr);
458 saa7134_buffer_finish(dev,q,STATE_ERROR);
459 }
460 saa7134_buffer_next(dev,q);
461 spin_unlock_irqrestore(&dev->slock,flags);
462}
463
464/* ------------------------------------------------------------------ */
465
466int saa7134_set_dmabits(struct saa7134_dev *dev)
467{
468 u32 split, task=0, ctrl=0, irq=0;
469 enum v4l2_field cap = V4L2_FIELD_ANY;
470 enum v4l2_field ov = V4L2_FIELD_ANY;
471
472 assert_spin_locked(&dev->slock);
473
474 /* video capture -- dma 0 + video task A */
475 if (dev->video_q.curr) {
476 task |= 0x01;
477 ctrl |= SAA7134_MAIN_CTRL_TE0;
478 irq |= SAA7134_IRQ1_INTE_RA0_1 |
479 SAA7134_IRQ1_INTE_RA0_0;
480 cap = dev->video_q.curr->vb.field;
481 }
482
483 /* video capture -- dma 1+2 (planar modes) */
484 if (dev->video_q.curr &&
485 dev->video_q.curr->fmt->planar) {
486 ctrl |= SAA7134_MAIN_CTRL_TE4 |
487 SAA7134_MAIN_CTRL_TE5;
488 }
489
490 /* screen overlay -- dma 0 + video task B */
491 if (dev->ovenable) {
492 task |= 0x10;
493 ctrl |= SAA7134_MAIN_CTRL_TE1;
494 ov = dev->ovfield;
495 }
496
497 /* vbi capture -- dma 0 + vbi task A+B */
498 if (dev->vbi_q.curr) {
499 task |= 0x22;
500 ctrl |= SAA7134_MAIN_CTRL_TE2 |
501 SAA7134_MAIN_CTRL_TE3;
502 irq |= SAA7134_IRQ1_INTE_RA0_7 |
503 SAA7134_IRQ1_INTE_RA0_6 |
504 SAA7134_IRQ1_INTE_RA0_5 |
505 SAA7134_IRQ1_INTE_RA0_4;
506 }
507
508 /* audio capture -- dma 3 */
509 if (dev->oss.dma_running) {
510 ctrl |= SAA7134_MAIN_CTRL_TE6;
511 irq |= SAA7134_IRQ1_INTE_RA3_1 |
512 SAA7134_IRQ1_INTE_RA3_0;
513 }
514
515 /* TS capture -- dma 5 */
516 if (dev->ts_q.curr) {
517 ctrl |= SAA7134_MAIN_CTRL_TE5;
518 irq |= SAA7134_IRQ1_INTE_RA2_3 |
519 SAA7134_IRQ1_INTE_RA2_2 |
520 SAA7134_IRQ1_INTE_RA2_1 |
521 SAA7134_IRQ1_INTE_RA2_0;
522 }
523
524 /* set task conditions + field handling */
525 if (V4L2_FIELD_HAS_BOTH(cap) || V4L2_FIELD_HAS_BOTH(ov) || cap == ov) {
526 /* default config -- use full frames */
527 saa_writeb(SAA7134_TASK_CONDITIONS(TASK_A), 0x0d);
528 saa_writeb(SAA7134_TASK_CONDITIONS(TASK_B), 0x0d);
529 saa_writeb(SAA7134_FIELD_HANDLING(TASK_A), 0x02);
530 saa_writeb(SAA7134_FIELD_HANDLING(TASK_B), 0x02);
531 split = 0;
532 } else {
533 /* split fields between tasks */
534 if (V4L2_FIELD_TOP == cap) {
535 /* odd A, even B, repeat */
536 saa_writeb(SAA7134_TASK_CONDITIONS(TASK_A), 0x0d);
537 saa_writeb(SAA7134_TASK_CONDITIONS(TASK_B), 0x0e);
538 } else {
539 /* odd B, even A, repeat */
540 saa_writeb(SAA7134_TASK_CONDITIONS(TASK_A), 0x0e);
541 saa_writeb(SAA7134_TASK_CONDITIONS(TASK_B), 0x0d);
542 }
543 saa_writeb(SAA7134_FIELD_HANDLING(TASK_A), 0x01);
544 saa_writeb(SAA7134_FIELD_HANDLING(TASK_B), 0x01);
545 split = 1;
546 }
547
548 /* irqs */
549 saa_writeb(SAA7134_REGION_ENABLE, task);
550 saa_writel(SAA7134_IRQ1, irq);
551 saa_andorl(SAA7134_MAIN_CTRL,
552 SAA7134_MAIN_CTRL_TE0 |
553 SAA7134_MAIN_CTRL_TE1 |
554 SAA7134_MAIN_CTRL_TE2 |
555 SAA7134_MAIN_CTRL_TE3 |
556 SAA7134_MAIN_CTRL_TE4 |
557 SAA7134_MAIN_CTRL_TE5 |
558 SAA7134_MAIN_CTRL_TE6,
559 ctrl);
560 dprintk("dmabits: task=0x%02x ctrl=0x%02x irq=0x%x split=%s\n",
561 task, ctrl, irq, split ? "no" : "yes");
562
563 return 0;
564}
565
566/* ------------------------------------------------------------------ */
567/* IRQ handler + helpers */
568
569static char *irqbits[] = {
570 "DONE_RA0", "DONE_RA1", "DONE_RA2", "DONE_RA3",
571 "AR", "PE", "PWR_ON", "RDCAP", "INTL", "FIDT", "MMC",
572 "TRIG_ERR", "CONF_ERR", "LOAD_ERR",
573 "GPIO16?", "GPIO18", "GPIO22", "GPIO23"
574};
575#define IRQBITS ARRAY_SIZE(irqbits)
576
577static void print_irqstatus(struct saa7134_dev *dev, int loop,
578 unsigned long report, unsigned long status)
579{
580 unsigned int i;
581
582 printk(KERN_DEBUG "%s/irq[%d,%ld]: r=0x%lx s=0x%02lx",
583 dev->name,loop,jiffies,report,status);
584 for (i = 0; i < IRQBITS; i++) {
585 if (!(report & (1 << i)))
586 continue;
587 printk(" %s",irqbits[i]);
588 }
589 if (report & SAA7134_IRQ_REPORT_DONE_RA0) {
590 printk(" | RA0=%s,%s,%s,%ld",
591 (status & 0x40) ? "vbi" : "video",
592 (status & 0x20) ? "b" : "a",
593 (status & 0x10) ? "odd" : "even",
594 (status & 0x0f));
595 }
596 printk("\n");
597}
598
599static irqreturn_t saa7134_irq(int irq, void *dev_id, struct pt_regs *regs)
600{
601 struct saa7134_dev *dev = (struct saa7134_dev*) dev_id;
602 unsigned long report,status;
603 int loop, handled = 0;
604
605 for (loop = 0; loop < 10; loop++) {
606 report = saa_readl(SAA7134_IRQ_REPORT);
607 status = saa_readl(SAA7134_IRQ_STATUS);
608 if (0 == report) {
609 if (irq_debug > 1)
610 printk(KERN_DEBUG "%s/irq: no (more) work\n",
611 dev->name);
612 goto out;
613 }
614 handled = 1;
615 saa_writel(SAA7134_IRQ_REPORT,report);
616 if (irq_debug)
617 print_irqstatus(dev,loop,report,status);
618
619#if 0
620 if (report & SAA7134_IRQ_REPORT_CONF_ERR)
621 dump_statusregs(dev);
622#endif
623
624 if (report & SAA7134_IRQ_REPORT_RDCAP /* _INTL */)
625 saa7134_irq_video_intl(dev);
626
627 if ((report & SAA7134_IRQ_REPORT_DONE_RA0) &&
628 (status & 0x60) == 0)
629 saa7134_irq_video_done(dev,status);
630
631 if ((report & SAA7134_IRQ_REPORT_DONE_RA0) &&
632 (status & 0x40) == 0x40)
633 saa7134_irq_vbi_done(dev,status);
634
635 if ((report & SAA7134_IRQ_REPORT_DONE_RA2) &&
636 card_has_mpeg(dev))
637 saa7134_irq_ts_done(dev,status);
638
639 if ((report & SAA7134_IRQ_REPORT_DONE_RA3))
640 saa7134_irq_oss_done(dev,status);
641
642 if ((report & (SAA7134_IRQ_REPORT_GPIO16 |
643 SAA7134_IRQ_REPORT_GPIO18)) &&
644 dev->remote)
645 saa7134_input_irq(dev);
646 }
647
648 if (10 == loop) {
649 print_irqstatus(dev,loop,report,status);
650 if (report & SAA7134_IRQ_REPORT_PE) {
651 /* disable all parity error */
652 printk(KERN_WARNING "%s/irq: looping -- "
653 "clearing PE (parity error!) enable bit\n",dev->name);
654 saa_clearl(SAA7134_IRQ2,SAA7134_IRQ2_INTE_PE);
655 } else if (report & (SAA7134_IRQ_REPORT_GPIO16 |
656 SAA7134_IRQ_REPORT_GPIO18)) {
657 /* disable gpio IRQs */
658 printk(KERN_WARNING "%s/irq: looping -- "
659 "clearing GPIO enable bits\n",dev->name);
660 saa_clearl(SAA7134_IRQ2, (SAA7134_IRQ2_INTE_GPIO16 |
661 SAA7134_IRQ2_INTE_GPIO18));
662 } else {
663 /* disable all irqs */
664 printk(KERN_WARNING "%s/irq: looping -- "
665 "clearing all enable bits\n",dev->name);
666 saa_writel(SAA7134_IRQ1,0);
667 saa_writel(SAA7134_IRQ2,0);
668 }
669 }
670
671 out:
672 return IRQ_RETVAL(handled);
673}
674
675/* ------------------------------------------------------------------ */
676
677/* early init (no i2c, no irq) */
678static int saa7134_hwinit1(struct saa7134_dev *dev)
679{
680 dprintk("hwinit1\n");
681
682 saa_writel(SAA7134_IRQ1, 0);
683 saa_writel(SAA7134_IRQ2, 0);
684 init_MUTEX(&dev->lock);
685 spin_lock_init(&dev->slock);
686
687 saa7134_track_gpio(dev,"pre-init");
688 saa7134_video_init1(dev);
689 saa7134_vbi_init1(dev);
690 if (card_has_mpeg(dev))
691 saa7134_ts_init1(dev);
692 saa7134_input_init1(dev);
693
694 switch (dev->pci->device) {
695 case PCI_DEVICE_ID_PHILIPS_SAA7134:
696 case PCI_DEVICE_ID_PHILIPS_SAA7133:
697 case PCI_DEVICE_ID_PHILIPS_SAA7135:
698 saa7134_oss_init1(dev);
699 break;
700 }
701
702 /* RAM FIFO config */
703 saa_writel(SAA7134_FIFO_SIZE, 0x08070503);
704 saa_writel(SAA7134_THRESHOULD,0x02020202);
705
706 /* enable audio + video processing */
707 saa_writel(SAA7134_MAIN_CTRL,
708 SAA7134_MAIN_CTRL_VPLLE |
709 SAA7134_MAIN_CTRL_APLLE |
710 SAA7134_MAIN_CTRL_EXOSC |
711 SAA7134_MAIN_CTRL_EVFE1 |
712 SAA7134_MAIN_CTRL_EVFE2 |
713 SAA7134_MAIN_CTRL_ESFE |
714 SAA7134_MAIN_CTRL_EBADC |
715 SAA7134_MAIN_CTRL_EBDAC);
716
717 /* enable peripheral devices */
718 saa_writeb(SAA7134_SPECIAL_MODE, 0x01);
719
720 /* set vertical line numbering start (vbi needs this) */
721 saa_writeb(SAA7134_SOURCE_TIMING2, 0x20);
722
723 return 0;
724}
725
726/* late init (with i2c + irq) */
727static int saa7134_hwinit2(struct saa7134_dev *dev)
728{
729 dprintk("hwinit2\n");
730
731 saa7134_video_init2(dev);
732 saa7134_tvaudio_init2(dev);
733
734 /* enable IRQ's */
735 saa_writel(SAA7134_IRQ1, 0);
736 saa_writel(SAA7134_IRQ2, dev->irq2_mask);
737
738 return 0;
739}
740
741/* shutdown */
742static int saa7134_hwfini(struct saa7134_dev *dev)
743{
744 dprintk("hwfini\n");
745
746 switch (dev->pci->device) {
747 case PCI_DEVICE_ID_PHILIPS_SAA7134:
748 case PCI_DEVICE_ID_PHILIPS_SAA7133:
749 case PCI_DEVICE_ID_PHILIPS_SAA7135:
750 saa7134_oss_fini(dev);
751 break;
752 }
753 if (card_has_mpeg(dev))
754 saa7134_ts_fini(dev);
755 saa7134_input_fini(dev);
756 saa7134_vbi_fini(dev);
757 saa7134_video_fini(dev);
758 saa7134_tvaudio_fini(dev);
759 return 0;
760}
761
762static void __devinit must_configure_manually(void)
763{
764 unsigned int i,p;
765
766 printk(KERN_WARNING
767 "saa7134: <rant>\n"
768 "saa7134: Congratulations! Your TV card vendor saved a few\n"
769 "saa7134: cents for a eeprom, thus your pci board has no\n"
770 "saa7134: subsystem ID and I can't identify it automatically\n"
771 "saa7134: </rant>\n"
772 "saa7134: I feel better now. Ok, here are the good news:\n"
773 "saa7134: You can use the card=<nr> insmod option to specify\n"
774 "saa7134: which board do you have. The list:\n");
775 for (i = 0; i < saa7134_bcount; i++) {
776 printk(KERN_WARNING "saa7134: card=%d -> %-40.40s",
777 i,saa7134_boards[i].name);
778 for (p = 0; saa7134_pci_tbl[p].driver_data; p++) {
779 if (saa7134_pci_tbl[p].driver_data != i)
780 continue;
781 printk(" %04x:%04x",
782 saa7134_pci_tbl[p].subvendor,
783 saa7134_pci_tbl[p].subdevice);
784 }
785 printk("\n");
786 }
787}
788
789static struct video_device *vdev_init(struct saa7134_dev *dev,
790 struct video_device *template,
791 char *type)
792{
793 struct video_device *vfd;
794
795 vfd = video_device_alloc();
796 if (NULL == vfd)
797 return NULL;
798 *vfd = *template;
799 vfd->minor = -1;
800 vfd->dev = &dev->pci->dev;
801 vfd->release = video_device_release;
802 snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)",
803 dev->name, type, saa7134_boards[dev->board].name);
804 return vfd;
805}
806
807static void saa7134_unregister_video(struct saa7134_dev *dev)
808{
809 if (dev->video_dev) {
810 if (-1 != dev->video_dev->minor)
811 video_unregister_device(dev->video_dev);
812 else
813 video_device_release(dev->video_dev);
814 dev->video_dev = NULL;
815 }
816 if (dev->vbi_dev) {
817 if (-1 != dev->vbi_dev->minor)
818 video_unregister_device(dev->vbi_dev);
819 else
820 video_device_release(dev->vbi_dev);
821 dev->vbi_dev = NULL;
822 }
823 if (dev->radio_dev) {
824 if (-1 != dev->radio_dev->minor)
825 video_unregister_device(dev->radio_dev);
826 else
827 video_device_release(dev->radio_dev);
828 dev->radio_dev = NULL;
829 }
830}
831
832static void mpeg_ops_attach(struct saa7134_mpeg_ops *ops,
833 struct saa7134_dev *dev)
834{
835 int err;
836
837 if (NULL != dev->mops)
838 return;
839 if (saa7134_boards[dev->board].mpeg != ops->type)
840 return;
841 err = ops->init(dev);
842 if (0 != err)
843 return;
844 dev->mops = ops;
845}
846
847static void mpeg_ops_detach(struct saa7134_mpeg_ops *ops,
848 struct saa7134_dev *dev)
849{
850 if (NULL == dev->mops)
851 return;
852 if (dev->mops != ops)
853 return;
854 dev->mops->fini(dev);
855 dev->mops = NULL;
856}
857
858static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
859 const struct pci_device_id *pci_id)
860{
861 struct saa7134_dev *dev;
862 struct list_head *item;
863 struct saa7134_mpeg_ops *mops;
864 int err;
865
866 dev = kmalloc(sizeof(*dev),GFP_KERNEL);
867 if (NULL == dev)
868 return -ENOMEM;
869 memset(dev,0,sizeof(*dev));
870
871 /* pci init */
872 dev->pci = pci_dev;
873 if (pci_enable_device(pci_dev)) {
874 err = -EIO;
875 goto fail1;
876 }
877
878 dev->nr = saa7134_devcount;
879 sprintf(dev->name,"saa%x[%d]",pci_dev->device,dev->nr);
880
881 /* pci quirks */
882 if (pci_pci_problems) {
883 if (pci_pci_problems & PCIPCI_TRITON)
884 printk(KERN_INFO "%s: quirk: PCIPCI_TRITON\n", dev->name);
885 if (pci_pci_problems & PCIPCI_NATOMA)
886 printk(KERN_INFO "%s: quirk: PCIPCI_NATOMA\n", dev->name);
887 if (pci_pci_problems & PCIPCI_VIAETBF)
888 printk(KERN_INFO "%s: quirk: PCIPCI_VIAETBF\n", dev->name);
889 if (pci_pci_problems & PCIPCI_VSFX)
890 printk(KERN_INFO "%s: quirk: PCIPCI_VSFX\n",dev->name);
891#ifdef PCIPCI_ALIMAGIK
892 if (pci_pci_problems & PCIPCI_ALIMAGIK) {
893 printk(KERN_INFO "%s: quirk: PCIPCI_ALIMAGIK -- latency fixup\n",
894 dev->name);
895 latency = 0x0A;
896 }
897#endif
898 }
899 if (UNSET != latency) {
900 printk(KERN_INFO "%s: setting pci latency timer to %d\n",
901 dev->name,latency);
902 pci_write_config_byte(pci_dev, PCI_LATENCY_TIMER, latency);
903 }
904
905 /* print pci info */
906 pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev);
907 pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat);
908 printk(KERN_INFO "%s: found at %s, rev: %d, irq: %d, "
909 "latency: %d, mmio: 0x%lx\n", dev->name,
910 pci_name(pci_dev), dev->pci_rev, pci_dev->irq,
911 dev->pci_lat,pci_resource_start(pci_dev,0));
912 pci_set_master(pci_dev);
913 if (!pci_dma_supported(pci_dev,0xffffffff)) {
914 printk("%s: Oops: no 32bit PCI DMA ???\n",dev->name);
915 err = -EIO;
916 goto fail1;
917 }
918
919 /* board config */
920 dev->board = pci_id->driver_data;
921 if (card[dev->nr] >= 0 &&
922 card[dev->nr] < saa7134_bcount)
923 dev->board = card[dev->nr];
924 if (SAA7134_BOARD_NOAUTO == dev->board) {
925 must_configure_manually();
926 dev->board = SAA7134_BOARD_UNKNOWN;
927 }
928 dev->tuner_type = saa7134_boards[dev->board].tuner_type;
929 dev->tda9887_conf = saa7134_boards[dev->board].tda9887_conf;
930 if (UNSET != tuner[dev->nr])
931 dev->tuner_type = tuner[dev->nr];
932 printk(KERN_INFO "%s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n",
933 dev->name,pci_dev->subsystem_vendor,
934 pci_dev->subsystem_device,saa7134_boards[dev->board].name,
935 dev->board, card[dev->nr] == dev->board ?
936 "insmod option" : "autodetected");
937
938 /* get mmio */
939 if (!request_mem_region(pci_resource_start(pci_dev,0),
940 pci_resource_len(pci_dev,0),
941 dev->name)) {
942 err = -EBUSY;
943 printk(KERN_ERR "%s: can't get MMIO memory @ 0x%lx\n",
944 dev->name,pci_resource_start(pci_dev,0));
945 goto fail1;
946 }
947 dev->lmmio = ioremap(pci_resource_start(pci_dev,0), 0x1000);
948 dev->bmmio = (__u8 __iomem *)dev->lmmio;
949 if (NULL == dev->lmmio) {
950 err = -EIO;
951 printk(KERN_ERR "%s: can't ioremap() MMIO memory\n",
952 dev->name);
953 goto fail2;
954 }
955
956 /* initialize hardware #1 */
957 dev->irq2_mask =
958 SAA7134_IRQ2_INTE_DEC3 |
959 SAA7134_IRQ2_INTE_DEC2 |
960 SAA7134_IRQ2_INTE_DEC1 |
961 SAA7134_IRQ2_INTE_DEC0 |
962 SAA7134_IRQ2_INTE_PE |
963 SAA7134_IRQ2_INTE_AR;
964 saa7134_board_init1(dev);
965 saa7134_hwinit1(dev);
966
967 /* get irq */
968 err = request_irq(pci_dev->irq, saa7134_irq,
969 SA_SHIRQ | SA_INTERRUPT, dev->name, dev);
970 if (err < 0) {
971 printk(KERN_ERR "%s: can't get IRQ %d\n",
972 dev->name,pci_dev->irq);
973 goto fail3;
974 }
975
976 /* wait a bit, register i2c bus */
977 msleep(100);
978 saa7134_i2c_register(dev);
979
980 /* initialize hardware #2 */
981 saa7134_board_init2(dev);
982 saa7134_hwinit2(dev);
983
984 /* load i2c helpers */
985 if (TUNER_ABSENT != dev->tuner_type)
986 request_module("tuner");
987 if (dev->tda9887_conf)
988 request_module("tda9887");
989 if (card_is_empress(dev)) {
990 request_module("saa6752hs");
991 request_module_depend("saa7134-empress",&need_empress);
992 }
993 if (card_is_dvb(dev))
994 request_module_depend("saa7134-dvb",&need_dvb);
995
996 v4l2_prio_init(&dev->prio);
997
998 /* register v4l devices */
999 dev->video_dev = vdev_init(dev,&saa7134_video_template,"video");
1000 err = video_register_device(dev->video_dev,VFL_TYPE_GRABBER,
1001 video_nr[dev->nr]);
1002 if (err < 0) {
1003 printk(KERN_INFO "%s: can't register video device\n",
1004 dev->name);
1005 goto fail4;
1006 }
1007 printk(KERN_INFO "%s: registered device video%d [v4l2]\n",
1008 dev->name,dev->video_dev->minor & 0x1f);
1009
1010 dev->vbi_dev = vdev_init(dev,&saa7134_vbi_template,"vbi");
1011 err = video_register_device(dev->vbi_dev,VFL_TYPE_VBI,
1012 vbi_nr[dev->nr]);
1013 if (err < 0)
1014 goto fail4;
1015 printk(KERN_INFO "%s: registered device vbi%d\n",
1016 dev->name,dev->vbi_dev->minor & 0x1f);
1017
1018 if (card_has_radio(dev)) {
1019 dev->radio_dev = vdev_init(dev,&saa7134_radio_template,"radio");
1020 err = video_register_device(dev->radio_dev,VFL_TYPE_RADIO,
1021 radio_nr[dev->nr]);
1022 if (err < 0)
1023 goto fail4;
1024 printk(KERN_INFO "%s: registered device radio%d\n",
1025 dev->name,dev->radio_dev->minor & 0x1f);
1026 }
1027
1028 /* register oss devices */
1029 switch (dev->pci->device) {
1030 case PCI_DEVICE_ID_PHILIPS_SAA7134:
1031 case PCI_DEVICE_ID_PHILIPS_SAA7133:
1032 case PCI_DEVICE_ID_PHILIPS_SAA7135:
1033 if (oss) {
1034 err = dev->oss.minor_dsp =
1035 register_sound_dsp(&saa7134_dsp_fops,
1036 dsp_nr[dev->nr]);
1037 if (err < 0) {
1038 goto fail4;
1039 }
1040 printk(KERN_INFO "%s: registered device dsp%d\n",
1041 dev->name,dev->oss.minor_dsp >> 4);
1042
1043 err = dev->oss.minor_mixer =
1044 register_sound_mixer(&saa7134_mixer_fops,
1045 mixer_nr[dev->nr]);
1046 if (err < 0)
1047 goto fail5;
1048 printk(KERN_INFO "%s: registered device mixer%d\n",
1049 dev->name,dev->oss.minor_mixer >> 4);
1050 }
1051 break;
1052 }
1053
1054 /* everything worked */
1055 pci_set_drvdata(pci_dev,dev);
1056 saa7134_devcount++;
1057
1058 down(&devlist_lock);
1059 list_for_each(item,&mops_list) {
1060 mops = list_entry(item, struct saa7134_mpeg_ops, next);
1061 mpeg_ops_attach(mops, dev);
1062 }
1063 list_add_tail(&dev->devlist,&saa7134_devlist);
1064 up(&devlist_lock);
1065
1066 /* check for signal */
1067 saa7134_irq_video_intl(dev);
1068 return 0;
1069
1070 fail5:
1071 switch (dev->pci->device) {
1072 case PCI_DEVICE_ID_PHILIPS_SAA7134:
1073 case PCI_DEVICE_ID_PHILIPS_SAA7133:
1074 case PCI_DEVICE_ID_PHILIPS_SAA7135:
1075 if (oss)
1076 unregister_sound_dsp(dev->oss.minor_dsp);
1077 break;
1078 }
1079 fail4:
1080 saa7134_unregister_video(dev);
1081 saa7134_i2c_unregister(dev);
1082 free_irq(pci_dev->irq, dev);
1083 fail3:
1084 saa7134_hwfini(dev);
1085 iounmap(dev->lmmio);
1086 fail2:
1087 release_mem_region(pci_resource_start(pci_dev,0),
1088 pci_resource_len(pci_dev,0));
1089 fail1:
1090 kfree(dev);
1091 return err;
1092}
1093
1094static void __devexit saa7134_finidev(struct pci_dev *pci_dev)
1095{
1096 struct saa7134_dev *dev = pci_get_drvdata(pci_dev);
1097 struct list_head *item;
1098 struct saa7134_mpeg_ops *mops;
1099
1100 /* debugging ... */
1101 if (irq_debug) {
1102 u32 report = saa_readl(SAA7134_IRQ_REPORT);
1103 u32 status = saa_readl(SAA7134_IRQ_STATUS);
1104 print_irqstatus(dev,42,report,status);
1105 }
1106
1107 /* disable peripheral devices */
1108 saa_writeb(SAA7134_SPECIAL_MODE,0);
1109
1110 /* shutdown hardware */
1111 saa_writel(SAA7134_IRQ1,0);
1112 saa_writel(SAA7134_IRQ2,0);
1113 saa_writel(SAA7134_MAIN_CTRL,0);
1114
1115 /* shutdown subsystems */
1116 saa7134_hwfini(dev);
1117
1118 /* unregister */
1119 down(&devlist_lock);
1120 list_del(&dev->devlist);
1121 list_for_each(item,&mops_list) {
1122 mops = list_entry(item, struct saa7134_mpeg_ops, next);
1123 mpeg_ops_detach(mops, dev);
1124 }
1125 up(&devlist_lock);
1126 saa7134_devcount--;
1127
1128 saa7134_i2c_unregister(dev);
1129 switch (dev->pci->device) {
1130 case PCI_DEVICE_ID_PHILIPS_SAA7134:
1131 case PCI_DEVICE_ID_PHILIPS_SAA7133:
1132 case PCI_DEVICE_ID_PHILIPS_SAA7135:
1133 if (oss) {
1134 unregister_sound_mixer(dev->oss.minor_mixer);
1135 unregister_sound_dsp(dev->oss.minor_dsp);
1136 }
1137 break;
1138 }
1139 saa7134_unregister_video(dev);
1140
1141 /* release ressources */
1142 free_irq(pci_dev->irq, dev);
1143 iounmap(dev->lmmio);
1144 release_mem_region(pci_resource_start(pci_dev,0),
1145 pci_resource_len(pci_dev,0));
1146
1147#if 0 /* causes some trouble when reinserting the driver ... */
1148 pci_disable_device(pci_dev);
1149#endif
1150 pci_set_drvdata(pci_dev, NULL);
1151
1152 /* free memory */
1153 kfree(dev);
1154}
1155
1156/* ----------------------------------------------------------- */
1157
1158int saa7134_ts_register(struct saa7134_mpeg_ops *ops)
1159{
1160 struct list_head *item;
1161 struct saa7134_dev *dev;
1162
1163 down(&devlist_lock);
1164 list_for_each(item,&saa7134_devlist) {
1165 dev = list_entry(item, struct saa7134_dev, devlist);
1166 mpeg_ops_attach(ops, dev);
1167 }
1168 list_add_tail(&ops->next,&mops_list);
1169 up(&devlist_lock);
1170 return 0;
1171}
1172
1173void saa7134_ts_unregister(struct saa7134_mpeg_ops *ops)
1174{
1175 struct list_head *item;
1176 struct saa7134_dev *dev;
1177
1178 down(&devlist_lock);
1179 list_del(&ops->next);
1180 list_for_each(item,&saa7134_devlist) {
1181 dev = list_entry(item, struct saa7134_dev, devlist);
1182 mpeg_ops_detach(ops, dev);
1183 }
1184 up(&devlist_lock);
1185}
1186
1187EXPORT_SYMBOL(saa7134_ts_register);
1188EXPORT_SYMBOL(saa7134_ts_unregister);
1189
1190/* ----------------------------------------------------------- */
1191
1192static struct pci_driver saa7134_pci_driver = {
1193 .name = "saa7134",
1194 .id_table = saa7134_pci_tbl,
1195 .probe = saa7134_initdev,
1196 .remove = __devexit_p(saa7134_finidev),
1197};
1198
1199static int saa7134_init(void)
1200{
1201 INIT_LIST_HEAD(&saa7134_devlist);
1202 printk(KERN_INFO "saa7130/34: v4l2 driver version %d.%d.%d loaded\n",
1203 (SAA7134_VERSION_CODE >> 16) & 0xff,
1204 (SAA7134_VERSION_CODE >> 8) & 0xff,
1205 SAA7134_VERSION_CODE & 0xff);
1206#ifdef SNAPSHOT
1207 printk(KERN_INFO "saa7130/34: snapshot date %04d-%02d-%02d\n",
1208 SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100);
1209#endif
1210 return pci_module_init(&saa7134_pci_driver);
1211}
1212
1213static void saa7134_fini(void)
1214{
1215#ifdef CONFIG_MODULES
1216 if (pending_registered)
1217 unregister_module_notifier(&pending_notifier);
1218#endif
1219 pci_unregister_driver(&saa7134_pci_driver);
1220}
1221
1222module_init(saa7134_init);
1223module_exit(saa7134_fini);
1224
1225/* ----------------------------------------------------------- */
1226
1227EXPORT_SYMBOL(saa7134_print_ioctl);
1228EXPORT_SYMBOL(saa7134_i2c_call_clients);
1229EXPORT_SYMBOL(saa7134_devlist);
1230EXPORT_SYMBOL(saa7134_boards);
1231
1232/* ----------------------------------------------------------- */
1233/*
1234 * Local variables:
1235 * c-basic-offset: 8
1236 * End:
1237 */
diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c
new file mode 100644
index 000000000000..dd4a6c8ee65f
--- /dev/null
+++ b/drivers/media/video/saa7134/saa7134-dvb.c
@@ -0,0 +1,266 @@
1/*
2 * $Id: saa7134-dvb.c,v 1.12 2005/02/18 12:28:29 kraxel Exp $
3 *
4 * (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21#include <linux/init.h>
22#include <linux/list.h>
23#include <linux/module.h>
24#include <linux/kernel.h>
25#include <linux/slab.h>
26#include <linux/delay.h>
27#include <linux/kthread.h>
28#include <linux/suspend.h>
29
30#include "saa7134-reg.h"
31#include "saa7134.h"
32
33#include "dvb-pll.h"
34#include "mt352.h"
35#include "mt352_priv.h" /* FIXME */
36#include "tda1004x.h"
37
38MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
39MODULE_LICENSE("GPL");
40
41static unsigned int antenna_pwr = 0;
42module_param(antenna_pwr, int, 0444);
43MODULE_PARM_DESC(antenna_pwr,"enable antenna power (Pinnacle 300i)");
44
45/* ------------------------------------------------------------------ */
46
47static int pinnacle_antenna_pwr(struct saa7134_dev *dev, int on)
48{
49 u32 ok;
50
51 if (!on) {
52 saa_setl(SAA7134_GPIO_GPMODE0 >> 2, (1 << 26));
53 saa_clearl(SAA7134_GPIO_GPSTATUS0 >> 2, (1 << 26));
54 return 0;
55 }
56
57 saa_setl(SAA7134_GPIO_GPMODE0 >> 2, (1 << 26));
58 saa_setl(SAA7134_GPIO_GPSTATUS0 >> 2, (1 << 26));
59 udelay(10);
60
61 saa_setl(SAA7134_GPIO_GPMODE0 >> 2, (1 << 28));
62 saa_clearl(SAA7134_GPIO_GPSTATUS0 >> 2, (1 << 28));
63 udelay(10);
64 saa_setl(SAA7134_GPIO_GPSTATUS0 >> 2, (1 << 28));
65 udelay(10);
66 ok = saa_readl(SAA7134_GPIO_GPSTATUS0) & (1 << 27);
67 printk("%s: %s %s\n", dev->name, __FUNCTION__,
68 ok ? "on" : "off");
69
70 if (!ok)
71 saa_clearl(SAA7134_GPIO_GPSTATUS0 >> 2, (1 << 26));
72 return ok;
73}
74
75static int mt352_pinnacle_init(struct dvb_frontend* fe)
76{
77 static u8 clock_config [] = { CLOCK_CTL, 0x3d, 0x28 };
78 static u8 reset [] = { RESET, 0x80 };
79 static u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 };
80 static u8 agc_cfg [] = { AGC_TARGET, 0x28, 0xa0 };
81 static u8 capt_range_cfg[] = { CAPT_RANGE, 0x31 };
82 static u8 fsm_ctl_cfg[] = { 0x7b, 0x04 };
83 static u8 gpp_ctl_cfg [] = { GPP_CTL, 0x0f };
84 static u8 scan_ctl_cfg [] = { SCAN_CTL, 0x0d };
85 static u8 irq_cfg [] = { INTERRUPT_EN_0, 0x00, 0x00, 0x00, 0x00 };
86 struct saa7134_dev *dev= fe->dvb->priv;
87
88 printk("%s: %s called\n",dev->name,__FUNCTION__);
89
90 mt352_write(fe, clock_config, sizeof(clock_config));
91 udelay(200);
92 mt352_write(fe, reset, sizeof(reset));
93 mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
94 mt352_write(fe, agc_cfg, sizeof(agc_cfg));
95 mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
96 mt352_write(fe, gpp_ctl_cfg, sizeof(gpp_ctl_cfg));
97
98 mt352_write(fe, fsm_ctl_cfg, sizeof(fsm_ctl_cfg));
99 mt352_write(fe, scan_ctl_cfg, sizeof(scan_ctl_cfg));
100 mt352_write(fe, irq_cfg, sizeof(irq_cfg));
101 return 0;
102}
103
104static int mt352_pinnacle_pll_set(struct dvb_frontend* fe,
105 struct dvb_frontend_parameters* params,
106 u8* pllbuf)
107{
108 static int on = TDA9887_PRESENT | TDA9887_PORT2_INACTIVE;
109 static int off = TDA9887_PRESENT | TDA9887_PORT2_ACTIVE;
110 struct saa7134_dev *dev = fe->dvb->priv;
111 struct v4l2_frequency f;
112
113 /* set frequency (mt2050) */
114 f.tuner = 0;
115 f.type = V4L2_TUNER_DIGITAL_TV;
116 f.frequency = params->frequency / 1000 * 16 / 1000;
117 saa7134_i2c_call_clients(dev,TDA9887_SET_CONFIG,&on);
118 saa7134_i2c_call_clients(dev,VIDIOC_S_FREQUENCY,&f);
119 saa7134_i2c_call_clients(dev,TDA9887_SET_CONFIG,&off);
120
121 pinnacle_antenna_pwr(dev, antenna_pwr);
122
123 /* mt352 setup */
124 mt352_pinnacle_init(fe);
125 pllbuf[0] = 0xc2;
126 pllbuf[1] = 0x00;
127 pllbuf[2] = 0x00;
128 pllbuf[3] = 0x80;
129 pllbuf[4] = 0x00;
130 return 0;
131}
132
133static struct mt352_config pinnacle_300i = {
134 .demod_address = 0x3c >> 1,
135 .adc_clock = 20333,
136 .if2 = 36150,
137 .no_tuner = 1,
138 .demod_init = mt352_pinnacle_init,
139 .pll_set = mt352_pinnacle_pll_set,
140};
141
142/* ------------------------------------------------------------------ */
143
144static int medion_cardbus_init(struct dvb_frontend* fe)
145{
146 /* anything to do here ??? */
147 return 0;
148}
149
150static int medion_cardbus_pll_set(struct dvb_frontend* fe,
151 struct dvb_frontend_parameters* params)
152{
153 struct saa7134_dev *dev = fe->dvb->priv;
154 struct v4l2_frequency f;
155
156 /*
157 * this instructs tuner.o to set the frequency, the call will
158 * end up in tuner_command(), VIDIOC_S_FREQUENCY switch.
159 * tda9887.o will see that as well.
160 */
161 f.tuner = 0;
162 f.type = V4L2_TUNER_DIGITAL_TV;
163 f.frequency = params->frequency / 1000 * 16 / 1000;
164 saa7134_i2c_call_clients(dev,VIDIOC_S_FREQUENCY,&f);
165 return 0;
166}
167
168static int fe_request_firmware(struct dvb_frontend* fe,
169 const struct firmware **fw, char* name)
170{
171 struct saa7134_dev *dev = fe->dvb->priv;
172 return request_firmware(fw, name, &dev->pci->dev);
173}
174
175struct tda1004x_config medion_cardbus = {
176 .demod_address = 0x08, /* not sure this is correct */
177 .invert = 0,
178 .invert_oclk = 0,
179 .pll_init = medion_cardbus_init,
180 .pll_set = medion_cardbus_pll_set,
181 .request_firmware = fe_request_firmware,
182};
183
184/* ------------------------------------------------------------------ */
185
186static int dvb_init(struct saa7134_dev *dev)
187{
188 /* init struct videobuf_dvb */
189 dev->ts.nr_bufs = 32;
190 dev->ts.nr_packets = 32*4;
191 dev->dvb.name = dev->name;
192 videobuf_queue_init(&dev->dvb.dvbq, &saa7134_ts_qops,
193 dev->pci, &dev->slock,
194 V4L2_BUF_TYPE_VIDEO_CAPTURE,
195 V4L2_FIELD_ALTERNATE,
196 sizeof(struct saa7134_buf),
197 dev);
198
199 switch (dev->board) {
200 case SAA7134_BOARD_PINNACLE_300I_DVBT_PAL:
201 printk("%s: pinnacle 300i dvb setup\n",dev->name);
202 dev->dvb.frontend = mt352_attach(&pinnacle_300i,
203 &dev->i2c_adap);
204 break;
205 case SAA7134_BOARD_MD7134:
206 dev->dvb.frontend = tda10046_attach(&medion_cardbus,
207 &dev->i2c_adap);
208 if (NULL == dev->dvb.frontend)
209 printk("%s: Hmm, looks like this is the old MD7134 "
210 "version without DVB-T support\n",dev->name);
211 break;
212 default:
213 printk("%s: Huh? unknown DVB card?\n",dev->name);
214 break;
215 }
216
217 if (NULL == dev->dvb.frontend) {
218 printk("%s: frontend initialization failed\n",dev->name);
219 return -1;
220 }
221
222 /* register everything else */
223 return videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev);
224}
225
226static int dvb_fini(struct saa7134_dev *dev)
227{
228 static int on = TDA9887_PRESENT | TDA9887_PORT2_INACTIVE;
229
230 printk("%s: %s\n",dev->name,__FUNCTION__);
231
232 switch (dev->board) {
233 case SAA7134_BOARD_PINNACLE_300I_DVBT_PAL:
234 /* otherwise we don't detect the tuner on next insmod */
235 saa7134_i2c_call_clients(dev,TDA9887_SET_CONFIG,&on);
236 break;
237 };
238 videobuf_dvb_unregister(&dev->dvb);
239 return 0;
240}
241
242static struct saa7134_mpeg_ops dvb_ops = {
243 .type = SAA7134_MPEG_DVB,
244 .init = dvb_init,
245 .fini = dvb_fini,
246};
247
248static int __init dvb_register(void)
249{
250 return saa7134_ts_register(&dvb_ops);
251}
252
253static void __exit dvb_unregister(void)
254{
255 saa7134_ts_unregister(&dvb_ops);
256}
257
258module_init(dvb_register);
259module_exit(dvb_unregister);
260
261/* ------------------------------------------------------------------ */
262/*
263 * Local variables:
264 * c-basic-offset: 8
265 * End:
266 */
diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c
new file mode 100644
index 000000000000..2021e099e35a
--- /dev/null
+++ b/drivers/media/video/saa7134/saa7134-empress.c
@@ -0,0 +1,436 @@
1/*
2 * $Id: saa7134-empress.c,v 1.10 2005/02/03 10:24:33 kraxel Exp $
3 *
4 * (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21#include <linux/init.h>
22#include <linux/list.h>
23#include <linux/module.h>
24#include <linux/moduleparam.h>
25#include <linux/kernel.h>
26#include <linux/slab.h>
27#include <linux/delay.h>
28
29#include "saa7134-reg.h"
30#include "saa7134.h"
31
32#include <media/saa6752hs.h>
33
34/* ------------------------------------------------------------------ */
35
36MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
37MODULE_LICENSE("GPL");
38
39static unsigned int empress_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
40module_param_array(empress_nr, int, NULL, 0444);
41MODULE_PARM_DESC(empress_nr,"ts device number");
42
43static unsigned int debug = 0;
44module_param(debug, int, 0644);
45MODULE_PARM_DESC(debug,"enable debug messages");
46
47#define dprintk(fmt, arg...) if (debug) \
48 printk(KERN_DEBUG "%s/empress: " fmt, dev->name , ## arg)
49
50/* ------------------------------------------------------------------ */
51
52static void ts_reset_encoder(struct saa7134_dev* dev)
53{
54 if (!dev->empress_started)
55 return;
56
57 saa_writeb(SAA7134_SPECIAL_MODE, 0x00);
58 msleep(10);
59 saa_writeb(SAA7134_SPECIAL_MODE, 0x01);
60 msleep(100);
61 dev->empress_started = 0;
62}
63
64static int ts_init_encoder(struct saa7134_dev* dev)
65{
66 ts_reset_encoder(dev);
67 saa7134_i2c_call_clients(dev, VIDIOC_S_MPEGCOMP, NULL);
68 dev->empress_started = 1;
69 return 0;
70}
71
72/* ------------------------------------------------------------------ */
73
74static int ts_open(struct inode *inode, struct file *file)
75{
76 int minor = iminor(inode);
77 struct saa7134_dev *h,*dev = NULL;
78 struct list_head *list;
79 int err;
80
81 list_for_each(list,&saa7134_devlist) {
82 h = list_entry(list, struct saa7134_dev, devlist);
83 if (h->empress_dev && h->empress_dev->minor == minor)
84 dev = h;
85 }
86 if (NULL == dev)
87 return -ENODEV;
88
89 dprintk("open minor=%d\n",minor);
90 err = -EBUSY;
91 if (down_trylock(&dev->empress_tsq.lock))
92 goto done;
93 if (dev->empress_users)
94 goto done_up;
95
96 dev->empress_users++;
97 file->private_data = dev;
98 err = 0;
99
100done_up:
101 up(&dev->empress_tsq.lock);
102done:
103 return err;
104}
105
106static int ts_release(struct inode *inode, struct file *file)
107{
108 struct saa7134_dev *dev = file->private_data;
109
110 if (dev->empress_tsq.streaming)
111 videobuf_streamoff(&dev->empress_tsq);
112 down(&dev->empress_tsq.lock);
113 if (dev->empress_tsq.reading)
114 videobuf_read_stop(&dev->empress_tsq);
115 videobuf_mmap_free(&dev->empress_tsq);
116 dev->empress_users--;
117
118 /* stop the encoder */
119 ts_reset_encoder(dev);
120
121 up(&dev->empress_tsq.lock);
122 return 0;
123}
124
125static ssize_t
126ts_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
127{
128 struct saa7134_dev *dev = file->private_data;
129
130 if (!dev->empress_started)
131 ts_init_encoder(dev);
132
133 return videobuf_read_stream(&dev->empress_tsq,
134 data, count, ppos, 0,
135 file->f_flags & O_NONBLOCK);
136}
137
138static unsigned int
139ts_poll(struct file *file, struct poll_table_struct *wait)
140{
141 struct saa7134_dev *dev = file->private_data;
142
143 return videobuf_poll_stream(file, &dev->empress_tsq, wait);
144}
145
146
147static int
148ts_mmap(struct file *file, struct vm_area_struct * vma)
149{
150 struct saa7134_dev *dev = file->private_data;
151
152 return videobuf_mmap_mapper(&dev->empress_tsq, vma);
153}
154
155/*
156 * This function is _not_ called directly, but from
157 * video_generic_ioctl (and maybe others). userspace
158 * copying is done already, arg is a kernel pointer.
159 */
160static int ts_do_ioctl(struct inode *inode, struct file *file,
161 unsigned int cmd, void *arg)
162{
163 struct saa7134_dev *dev = file->private_data;
164
165 if (debug > 1)
166 saa7134_print_ioctl(dev->name,cmd);
167 switch (cmd) {
168 case VIDIOC_QUERYCAP:
169 {
170 struct v4l2_capability *cap = arg;
171
172 memset(cap,0,sizeof(*cap));
173 strcpy(cap->driver, "saa7134");
174 strlcpy(cap->card, saa7134_boards[dev->board].name,
175 sizeof(cap->card));
176 sprintf(cap->bus_info,"PCI:%s",pci_name(dev->pci));
177 cap->version = SAA7134_VERSION_CODE;
178 cap->capabilities =
179 V4L2_CAP_VIDEO_CAPTURE |
180 V4L2_CAP_READWRITE |
181 V4L2_CAP_STREAMING;
182 return 0;
183 }
184
185 /* --- input switching --------------------------------------- */
186 case VIDIOC_ENUMINPUT:
187 {
188 struct v4l2_input *i = arg;
189
190 if (i->index != 0)
191 return -EINVAL;
192 i->type = V4L2_INPUT_TYPE_CAMERA;
193 strcpy(i->name,"CCIR656");
194 return 0;
195 }
196 case VIDIOC_G_INPUT:
197 {
198 int *i = arg;
199 *i = 0;
200 return 0;
201 }
202 case VIDIOC_S_INPUT:
203 {
204 int *i = arg;
205
206 if (*i != 0)
207 return -EINVAL;
208 return 0;
209 }
210 /* --- capture ioctls ---------------------------------------- */
211
212 case VIDIOC_ENUM_FMT:
213 {
214 struct v4l2_fmtdesc *f = arg;
215 int index;
216
217 index = f->index;
218 if (index != 0)
219 return -EINVAL;
220
221 memset(f,0,sizeof(*f));
222 f->index = index;
223 strlcpy(f->description, "MPEG TS", sizeof(f->description));
224 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
225 f->pixelformat = V4L2_PIX_FMT_MPEG;
226 return 0;
227 }
228
229 case VIDIOC_G_FMT:
230 {
231 struct v4l2_format *f = arg;
232
233 memset(f,0,sizeof(*f));
234 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
235
236 /* FIXME: translate subsampling type EMPRESS into
237 * width/height: */
238 f->fmt.pix.width = 720; /* D1 */
239 f->fmt.pix.height = 576;
240 f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
241 f->fmt.pix.sizeimage = TS_PACKET_SIZE * dev->ts.nr_packets;
242 return 0;
243 }
244
245 case VIDIOC_S_FMT:
246 {
247 struct v4l2_format *f = arg;
248
249 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
250 return -EINVAL;
251
252 /*
253 FIXME: translate and round width/height into EMPRESS
254 subsample type:
255
256 type | PAL | NTSC
257 ---------------------------
258 SIF | 352x288 | 352x240
259 1/2 D1 | 352x576 | 352x480
260 2/3 D1 | 480x576 | 480x480
261 D1 | 720x576 | 720x480
262 */
263
264 f->fmt.pix.width = 720; /* D1 */
265 f->fmt.pix.height = 576;
266 f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
267 f->fmt.pix.sizeimage = TS_PACKET_SIZE* dev->ts.nr_packets;
268 return 0;
269 }
270
271 case VIDIOC_REQBUFS:
272 return videobuf_reqbufs(&dev->empress_tsq,arg);
273
274 case VIDIOC_QUERYBUF:
275 return videobuf_querybuf(&dev->empress_tsq,arg);
276
277 case VIDIOC_QBUF:
278 return videobuf_qbuf(&dev->empress_tsq,arg);
279
280 case VIDIOC_DQBUF:
281 return videobuf_dqbuf(&dev->empress_tsq,arg,
282 file->f_flags & O_NONBLOCK);
283
284 case VIDIOC_STREAMON:
285 return videobuf_streamon(&dev->empress_tsq);
286
287 case VIDIOC_STREAMOFF:
288 return videobuf_streamoff(&dev->empress_tsq);
289
290 case VIDIOC_QUERYCTRL:
291 case VIDIOC_G_CTRL:
292 case VIDIOC_S_CTRL:
293 return saa7134_common_ioctl(dev, cmd, arg);
294
295 case VIDIOC_S_MPEGCOMP:
296 saa7134_i2c_call_clients(dev, VIDIOC_S_MPEGCOMP, arg);
297 ts_init_encoder(dev);
298 return 0;
299 case VIDIOC_G_MPEGCOMP:
300 saa7134_i2c_call_clients(dev, VIDIOC_G_MPEGCOMP, arg);
301 return 0;
302
303 default:
304 return -ENOIOCTLCMD;
305 }
306 return 0;
307}
308
309static int ts_ioctl(struct inode *inode, struct file *file,
310 unsigned int cmd, unsigned long arg)
311{
312 return video_usercopy(inode, file, cmd, arg, ts_do_ioctl);
313}
314
315static struct file_operations ts_fops =
316{
317 .owner = THIS_MODULE,
318 .open = ts_open,
319 .release = ts_release,
320 .read = ts_read,
321 .poll = ts_poll,
322 .mmap = ts_mmap,
323 .ioctl = ts_ioctl,
324 .llseek = no_llseek,
325};
326
327/* ----------------------------------------------------------- */
328
329static struct video_device saa7134_empress_template =
330{
331 .name = "saa7134-empress",
332 .type = 0 /* FIXME */,
333 .type2 = 0 /* FIXME */,
334 .hardware = 0,
335 .fops = &ts_fops,
336 .minor = -1,
337};
338
339static void empress_signal_update(void* data)
340{
341 struct saa7134_dev* dev = (struct saa7134_dev*) data;
342
343 if (dev->nosignal) {
344 dprintk("no video signal\n");
345 ts_reset_encoder(dev);
346 } else {
347 dprintk("video signal acquired\n");
348 if (dev->empress_users)
349 ts_init_encoder(dev);
350 }
351}
352
353static void empress_signal_change(struct saa7134_dev *dev)
354{
355 schedule_work(&dev->empress_workqueue);
356}
357
358
359static int empress_init(struct saa7134_dev *dev)
360{
361 int err;
362
363 dprintk("%s: %s\n",dev->name,__FUNCTION__);
364 dev->empress_dev = video_device_alloc();
365 if (NULL == dev->empress_dev)
366 return -ENOMEM;
367 *(dev->empress_dev) = saa7134_empress_template;
368 dev->empress_dev->dev = &dev->pci->dev;
369 dev->empress_dev->release = video_device_release;
370 snprintf(dev->empress_dev->name, sizeof(dev->empress_dev->name),
371 "%s empress (%s)", dev->name,
372 saa7134_boards[dev->board].name);
373
374 INIT_WORK(&dev->empress_workqueue, empress_signal_update, (void*) dev);
375
376 err = video_register_device(dev->empress_dev,VFL_TYPE_GRABBER,
377 empress_nr[dev->nr]);
378 if (err < 0) {
379 printk(KERN_INFO "%s: can't register video device\n",
380 dev->name);
381 video_device_release(dev->empress_dev);
382 dev->empress_dev = NULL;
383 return err;
384 }
385 printk(KERN_INFO "%s: registered device video%d [mpeg]\n",
386 dev->name,dev->empress_dev->minor & 0x1f);
387
388 videobuf_queue_init(&dev->empress_tsq, &saa7134_ts_qops,
389 dev->pci, &dev->slock,
390 V4L2_BUF_TYPE_VIDEO_CAPTURE,
391 V4L2_FIELD_ALTERNATE,
392 sizeof(struct saa7134_buf),
393 dev);
394
395 empress_signal_update(dev);
396 return 0;
397}
398
399static int empress_fini(struct saa7134_dev *dev)
400{
401 dprintk("%s: %s\n",dev->name,__FUNCTION__);
402
403 if (NULL == dev->empress_dev)
404 return 0;
405 flush_scheduled_work();
406 video_unregister_device(dev->empress_dev);
407 dev->empress_dev = NULL;
408 return 0;
409}
410
411static struct saa7134_mpeg_ops empress_ops = {
412 .type = SAA7134_MPEG_EMPRESS,
413 .init = empress_init,
414 .fini = empress_fini,
415 .signal_change = empress_signal_change,
416};
417
418static int __init empress_register(void)
419{
420 return saa7134_ts_register(&empress_ops);
421}
422
423static void __exit empress_unregister(void)
424{
425 saa7134_ts_unregister(&empress_ops);
426}
427
428module_init(empress_register);
429module_exit(empress_unregister);
430
431/* ----------------------------------------------------------- */
432/*
433 * Local variables:
434 * c-basic-offset: 8
435 * End:
436 */
diff --git a/drivers/media/video/saa7134/saa7134-i2c.c b/drivers/media/video/saa7134/saa7134-i2c.c
new file mode 100644
index 000000000000..702bb63d9813
--- /dev/null
+++ b/drivers/media/video/saa7134/saa7134-i2c.c
@@ -0,0 +1,453 @@
1/*
2 * $Id: saa7134-i2c.c,v 1.10 2005/01/24 17:37:23 kraxel Exp $
3 *
4 * device driver for philips saa7134 based TV cards
5 * i2c interface support
6 *
7 * (c) 2001,02 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include <linux/init.h>
25#include <linux/list.h>
26#include <linux/module.h>
27#include <linux/moduleparam.h>
28#include <linux/kernel.h>
29#include <linux/slab.h>
30#include <linux/delay.h>
31
32#include "saa7134-reg.h"
33#include "saa7134.h"
34
35/* ----------------------------------------------------------- */
36
37static unsigned int i2c_debug = 0;
38module_param(i2c_debug, int, 0644);
39MODULE_PARM_DESC(i2c_debug,"enable debug messages [i2c]");
40
41static unsigned int i2c_scan = 0;
42module_param(i2c_scan, int, 0444);
43MODULE_PARM_DESC(i2c_scan,"scan i2c bus at insmod time");
44
45#define d1printk if (1 == i2c_debug) printk
46#define d2printk if (2 == i2c_debug) printk
47
48#define I2C_WAIT_DELAY 32
49#define I2C_WAIT_RETRY 16
50
51/* ----------------------------------------------------------- */
52
53static char *str_i2c_status[] = {
54 "IDLE", "DONE_STOP", "BUSY", "TO_SCL", "TO_ARB", "DONE_WRITE",
55 "DONE_READ", "DONE_WRITE_TO", "DONE_READ_TO", "NO_DEVICE",
56 "NO_ACKN", "BUS_ERR", "ARB_LOST", "SEQ_ERR", "ST_ERR", "SW_ERR"
57};
58
59enum i2c_status {
60 IDLE = 0, // no I2C command pending
61 DONE_STOP = 1, // I2C command done and STOP executed
62 BUSY = 2, // executing I2C command
63 TO_SCL = 3, // executing I2C command, time out on clock stretching
64 TO_ARB = 4, // time out on arbitration trial, still trying
65 DONE_WRITE = 5, // I2C command done and awaiting next write command
66 DONE_READ = 6, // I2C command done and awaiting next read command
67 DONE_WRITE_TO = 7, // see 5, and time out on status echo
68 DONE_READ_TO = 8, // see 6, and time out on status echo
69 NO_DEVICE = 9, // no acknowledge on device slave address
70 NO_ACKN = 10, // no acknowledge after data byte transfer
71 BUS_ERR = 11, // bus error
72 ARB_LOST = 12, // arbitration lost during transfer
73 SEQ_ERR = 13, // erroneous programming sequence
74 ST_ERR = 14, // wrong status echoing
75 SW_ERR = 15 // software error
76};
77
78static char *str_i2c_attr[] = {
79 "NOP", "STOP", "CONTINUE", "START"
80};
81
82enum i2c_attr {
83 NOP = 0, // no operation on I2C bus
84 STOP = 1, // stop condition, no associated byte transfer
85 CONTINUE = 2, // continue with byte transfer
86 START = 3 // start condition with byte transfer
87};
88
89static inline enum i2c_status i2c_get_status(struct saa7134_dev *dev)
90{
91 enum i2c_status status;
92
93 status = saa_readb(SAA7134_I2C_ATTR_STATUS) & 0x0f;
94 d2printk(KERN_DEBUG "%s: i2c stat <= %s\n",dev->name,
95 str_i2c_status[status]);
96 return status;
97}
98
99static inline void i2c_set_status(struct saa7134_dev *dev,
100 enum i2c_status status)
101{
102 d2printk(KERN_DEBUG "%s: i2c stat => %s\n",dev->name,
103 str_i2c_status[status]);
104 saa_andorb(SAA7134_I2C_ATTR_STATUS,0x0f,status);
105}
106
107static inline void i2c_set_attr(struct saa7134_dev *dev, enum i2c_attr attr)
108{
109 d2printk(KERN_DEBUG "%s: i2c attr => %s\n",dev->name,
110 str_i2c_attr[attr]);
111 saa_andorb(SAA7134_I2C_ATTR_STATUS,0xc0,attr << 6);
112}
113
114static inline int i2c_is_error(enum i2c_status status)
115{
116 switch (status) {
117 case NO_DEVICE:
118 case NO_ACKN:
119 case BUS_ERR:
120 case ARB_LOST:
121 case SEQ_ERR:
122 case ST_ERR:
123 return TRUE;
124 default:
125 return FALSE;
126 }
127}
128
129static inline int i2c_is_idle(enum i2c_status status)
130{
131 switch (status) {
132 case IDLE:
133 case DONE_STOP:
134 return TRUE;
135 default:
136 return FALSE;
137 }
138}
139
140static inline int i2c_is_busy(enum i2c_status status)
141{
142 switch (status) {
143 case BUSY:
144 return TRUE;
145 default:
146 return FALSE;
147 }
148}
149
150static int i2c_is_busy_wait(struct saa7134_dev *dev)
151{
152 enum i2c_status status;
153 int count;
154
155 for (count = 0; count < I2C_WAIT_RETRY; count++) {
156 status = i2c_get_status(dev);
157 if (!i2c_is_busy(status))
158 break;
159 saa_wait(I2C_WAIT_DELAY);
160 }
161 if (I2C_WAIT_RETRY == count)
162 return FALSE;
163 return TRUE;
164}
165
166static int i2c_reset(struct saa7134_dev *dev)
167{
168 enum i2c_status status;
169 int count;
170
171 d2printk(KERN_DEBUG "%s: i2c reset\n",dev->name);
172 status = i2c_get_status(dev);
173 if (!i2c_is_error(status))
174 return TRUE;
175 i2c_set_status(dev,status);
176
177 for (count = 0; count < I2C_WAIT_RETRY; count++) {
178 status = i2c_get_status(dev);
179 if (!i2c_is_error(status))
180 break;
181 udelay(I2C_WAIT_DELAY);
182 }
183 if (I2C_WAIT_RETRY == count)
184 return FALSE;
185
186 if (!i2c_is_idle(status))
187 return FALSE;
188
189 i2c_set_attr(dev,NOP);
190 return TRUE;
191}
192
193static inline int i2c_send_byte(struct saa7134_dev *dev,
194 enum i2c_attr attr,
195 unsigned char data)
196{
197 enum i2c_status status;
198 __u32 dword;
199
200#if 0
201 i2c_set_attr(dev,attr);
202 saa_writeb(SAA7134_I2C_DATA, data);
203#else
204 /* have to write both attr + data in one 32bit word */
205 dword = saa_readl(SAA7134_I2C_ATTR_STATUS >> 2);
206 dword &= 0x0f;
207 dword |= (attr << 6);
208 dword |= ((__u32)data << 8);
209 dword |= 0x00 << 16; /* 100 kHz */
210// dword |= 0x40 << 16; /* 400 kHz */
211 dword |= 0xf0 << 24;
212 saa_writel(SAA7134_I2C_ATTR_STATUS >> 2, dword);
213#endif
214 d2printk(KERN_DEBUG "%s: i2c data => 0x%x\n",dev->name,data);
215
216 if (!i2c_is_busy_wait(dev))
217 return -EIO;
218 status = i2c_get_status(dev);
219 if (i2c_is_error(status))
220 return -EIO;
221 return 0;
222}
223
224static inline int i2c_recv_byte(struct saa7134_dev *dev)
225{
226 enum i2c_status status;
227 unsigned char data;
228
229 i2c_set_attr(dev,CONTINUE);
230 if (!i2c_is_busy_wait(dev))
231 return -EIO;
232 status = i2c_get_status(dev);
233 if (i2c_is_error(status))
234 return -EIO;
235 data = saa_readb(SAA7134_I2C_DATA);
236 d2printk(KERN_DEBUG "%s: i2c data <= 0x%x\n",dev->name,data);
237 return data;
238}
239
240static int saa7134_i2c_xfer(struct i2c_adapter *i2c_adap,
241 struct i2c_msg *msgs, int num)
242{
243 struct saa7134_dev *dev = i2c_adap->algo_data;
244 enum i2c_status status;
245 unsigned char data;
246 int addr,rc,i,byte;
247
248 status = i2c_get_status(dev);
249 if (!i2c_is_idle(status))
250 if (!i2c_reset(dev))
251 return -EIO;
252
253 d2printk("start xfer\n");
254 d1printk(KERN_DEBUG "%s: i2c xfer:",dev->name);
255 for (i = 0; i < num; i++) {
256 if (!(msgs[i].flags & I2C_M_NOSTART) || 0 == i) {
257 /* send address */
258 d2printk("send address\n");
259 addr = msgs[i].addr << 1;
260 if (msgs[i].flags & I2C_M_RD)
261 addr |= 1;
262 if (i > 0 && msgs[i].flags & I2C_M_RD) {
263 /* workaround for a saa7134 i2c bug
264 * needed to talk to the mt352 demux
265 * thanks to pinnacle for the hint */
266 int quirk = 0xfd;
267 d1printk(" [%02x quirk]",quirk);
268 i2c_send_byte(dev,START,quirk);
269 i2c_recv_byte(dev);
270 }
271 d1printk(" < %02x", addr);
272 rc = i2c_send_byte(dev,START,addr);
273 if (rc < 0)
274 goto err;
275 }
276 if (msgs[i].flags & I2C_M_RD) {
277 /* read bytes */
278 d2printk("read bytes\n");
279 for (byte = 0; byte < msgs[i].len; byte++) {
280 d1printk(" =");
281 rc = i2c_recv_byte(dev);
282 if (rc < 0)
283 goto err;
284 d1printk("%02x", rc);
285 msgs[i].buf[byte] = rc;
286 }
287 } else {
288 /* write bytes */
289 d2printk("write bytes\n");
290 for (byte = 0; byte < msgs[i].len; byte++) {
291 data = msgs[i].buf[byte];
292 d1printk(" %02x", data);
293 rc = i2c_send_byte(dev,CONTINUE,data);
294 if (rc < 0)
295 goto err;
296 }
297 }
298 }
299 d2printk("xfer done\n");
300 d1printk(" >");
301 i2c_set_attr(dev,STOP);
302 rc = -EIO;
303 if (!i2c_is_busy_wait(dev))
304 goto err;
305 status = i2c_get_status(dev);
306 if (i2c_is_error(status))
307 goto err;
308
309 d1printk("\n");
310 return num;
311 err:
312 if (1 == i2c_debug) {
313 status = i2c_get_status(dev);
314 printk(" ERROR: %s\n",str_i2c_status[status]);
315 }
316 return rc;
317}
318
319/* ----------------------------------------------------------- */
320
321static int algo_control(struct i2c_adapter *adapter,
322 unsigned int cmd, unsigned long arg)
323{
324 return 0;
325}
326
327static u32 functionality(struct i2c_adapter *adap)
328{
329 return I2C_FUNC_SMBUS_EMUL;
330}
331
332static int attach_inform(struct i2c_client *client)
333{
334 struct saa7134_dev *dev = client->adapter->algo_data;
335 int tuner = dev->tuner_type;
336 int conf = dev->tda9887_conf;
337
338 saa7134_i2c_call_clients(dev,TUNER_SET_TYPE,&tuner);
339 saa7134_i2c_call_clients(dev,TDA9887_SET_CONFIG,&conf);
340 return 0;
341}
342
343static struct i2c_algorithm saa7134_algo = {
344 .name = "saa7134",
345 .id = I2C_ALGO_SAA7134,
346 .master_xfer = saa7134_i2c_xfer,
347 .algo_control = algo_control,
348 .functionality = functionality,
349};
350
351static struct i2c_adapter saa7134_adap_template = {
352 .owner = THIS_MODULE,
353#ifdef I2C_CLASS_TV_ANALOG
354 .class = I2C_CLASS_TV_ANALOG,
355#endif
356 I2C_DEVNAME("saa7134"),
357 .id = I2C_ALGO_SAA7134,
358 .algo = &saa7134_algo,
359 .client_register = attach_inform,
360};
361
362static struct i2c_client saa7134_client_template = {
363 I2C_DEVNAME("saa7134 internal"),
364};
365
366/* ----------------------------------------------------------- */
367
368static int
369saa7134_i2c_eeprom(struct saa7134_dev *dev, unsigned char *eedata, int len)
370{
371 unsigned char buf;
372 int i,err;
373
374 dev->i2c_client.addr = 0xa0 >> 1;
375 buf = 0;
376 if (1 != (err = i2c_master_send(&dev->i2c_client,&buf,1))) {
377 printk(KERN_INFO "%s: Huh, no eeprom present (err=%d)?\n",
378 dev->name,err);
379 return -1;
380 }
381 if (len != (err = i2c_master_recv(&dev->i2c_client,eedata,len))) {
382 printk(KERN_WARNING "%s: i2c eeprom read error (err=%d)\n",
383 dev->name,err);
384 return -1;
385 }
386 for (i = 0; i < len; i++) {
387 if (0 == (i % 16))
388 printk(KERN_INFO "%s: i2c eeprom %02x:",dev->name,i);
389 printk(" %02x",eedata[i]);
390 if (15 == (i % 16))
391 printk("\n");
392 }
393 return 0;
394}
395
396static char *i2c_devs[128] = {
397 [ 0x20 ] = "mpeg encoder (saa6752hs)",
398 [ 0xa0 >> 1 ] = "eeprom",
399 [ 0xc0 >> 1 ] = "tuner (analog)",
400 [ 0x86 >> 1 ] = "tda9887",
401};
402
403static void do_i2c_scan(char *name, struct i2c_client *c)
404{
405 unsigned char buf;
406 int i,rc;
407
408 for (i = 0; i < 128; i++) {
409 c->addr = i;
410 rc = i2c_master_recv(c,&buf,0);
411 if (rc < 0)
412 continue;
413 printk("%s: i2c scan: found device @ 0x%x [%s]\n",
414 name, i << 1, i2c_devs[i] ? i2c_devs[i] : "???");
415 }
416}
417
418void saa7134_i2c_call_clients(struct saa7134_dev *dev,
419 unsigned int cmd, void *arg)
420{
421 BUG_ON(NULL == dev->i2c_adap.algo_data);
422 i2c_clients_command(&dev->i2c_adap, cmd, arg);
423}
424
425int saa7134_i2c_register(struct saa7134_dev *dev)
426{
427 dev->i2c_adap = saa7134_adap_template;
428 dev->i2c_adap.dev.parent = &dev->pci->dev;
429 strcpy(dev->i2c_adap.name,dev->name);
430 dev->i2c_adap.algo_data = dev;
431 i2c_add_adapter(&dev->i2c_adap);
432
433 dev->i2c_client = saa7134_client_template;
434 dev->i2c_client.adapter = &dev->i2c_adap;
435
436 saa7134_i2c_eeprom(dev,dev->eedata,sizeof(dev->eedata));
437 if (i2c_scan)
438 do_i2c_scan(dev->name,&dev->i2c_client);
439 return 0;
440}
441
442int saa7134_i2c_unregister(struct saa7134_dev *dev)
443{
444 i2c_del_adapter(&dev->i2c_adap);
445 return 0;
446}
447
448/* ----------------------------------------------------------- */
449/*
450 * Local variables:
451 * c-basic-offset: 8
452 * End:
453 */
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c
new file mode 100644
index 000000000000..727d437e07df
--- /dev/null
+++ b/drivers/media/video/saa7134/saa7134-input.c
@@ -0,0 +1,491 @@
1/*
2 * $Id: saa7134-input.c,v 1.16 2004/12/10 12:33:39 kraxel Exp $
3 *
4 * handle saa7134 IR remotes via linux kernel input layer.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 */
21
22#include <linux/module.h>
23#include <linux/moduleparam.h>
24#include <linux/init.h>
25#include <linux/delay.h>
26#include <linux/sched.h>
27#include <linux/interrupt.h>
28#include <linux/input.h>
29
30#include "saa7134-reg.h"
31#include "saa7134.h"
32
33static unsigned int disable_ir = 0;
34module_param(disable_ir, int, 0444);
35MODULE_PARM_DESC(disable_ir,"disable infrared remote support");
36
37static unsigned int ir_debug = 0;
38module_param(ir_debug, int, 0644);
39MODULE_PARM_DESC(ir_debug,"enable debug messages [IR]");
40
41#define dprintk(fmt, arg...) if (ir_debug) \
42 printk(KERN_DEBUG "%s/ir: " fmt, dev->name , ## arg)
43
44/* ---------------------------------------------------------------------- */
45
46static IR_KEYTAB_TYPE flyvideo_codes[IR_KEYTAB_SIZE] = {
47 [ 15 ] = KEY_KP0,
48 [ 3 ] = KEY_KP1,
49 [ 4 ] = KEY_KP2,
50 [ 5 ] = KEY_KP3,
51 [ 7 ] = KEY_KP4,
52 [ 8 ] = KEY_KP5,
53 [ 9 ] = KEY_KP6,
54 [ 11 ] = KEY_KP7,
55 [ 12 ] = KEY_KP8,
56 [ 13 ] = KEY_KP9,
57
58 [ 14 ] = KEY_TUNER, // Air/Cable
59 [ 17 ] = KEY_VIDEO, // Video
60 [ 21 ] = KEY_AUDIO, // Audio
61 [ 0 ] = KEY_POWER, // Pover
62 [ 2 ] = KEY_ZOOM, // Fullscreen
63 [ 27 ] = KEY_MUTE, // Mute
64 [ 20 ] = KEY_VOLUMEUP,
65 [ 23 ] = KEY_VOLUMEDOWN,
66 [ 18 ] = KEY_CHANNELUP, // Channel +
67 [ 19 ] = KEY_CHANNELDOWN, // Channel -
68 [ 6 ] = KEY_AGAIN, // Recal
69 [ 16 ] = KEY_KPENTER, // Enter
70
71#if 1 /* FIXME */
72 [ 26 ] = KEY_F22, // Stereo
73 [ 24 ] = KEY_EDIT, // AV Source
74#endif
75};
76
77static IR_KEYTAB_TYPE cinergy_codes[IR_KEYTAB_SIZE] = {
78 [ 0 ] = KEY_KP0,
79 [ 1 ] = KEY_KP1,
80 [ 2 ] = KEY_KP2,
81 [ 3 ] = KEY_KP3,
82 [ 4 ] = KEY_KP4,
83 [ 5 ] = KEY_KP5,
84 [ 6 ] = KEY_KP6,
85 [ 7 ] = KEY_KP7,
86 [ 8 ] = KEY_KP8,
87 [ 9 ] = KEY_KP9,
88
89 [ 0x0a ] = KEY_POWER,
90 [ 0x0b ] = KEY_PROG1, // app
91 [ 0x0c ] = KEY_ZOOM, // zoom/fullscreen
92 [ 0x0d ] = KEY_CHANNELUP, // channel
93 [ 0x0e ] = KEY_CHANNELDOWN, // channel-
94 [ 0x0f ] = KEY_VOLUMEUP,
95 [ 0x10 ] = KEY_VOLUMEDOWN,
96 [ 0x11 ] = KEY_TUNER, // AV
97 [ 0x12 ] = KEY_NUMLOCK, // -/--
98 [ 0x13 ] = KEY_AUDIO, // audio
99 [ 0x14 ] = KEY_MUTE,
100 [ 0x15 ] = KEY_UP,
101 [ 0x16 ] = KEY_DOWN,
102 [ 0x17 ] = KEY_LEFT,
103 [ 0x18 ] = KEY_RIGHT,
104 [ 0x19 ] = BTN_LEFT,
105 [ 0x1a ] = BTN_RIGHT,
106 [ 0x1b ] = KEY_WWW, // text
107 [ 0x1c ] = KEY_REWIND,
108 [ 0x1d ] = KEY_FORWARD,
109 [ 0x1e ] = KEY_RECORD,
110 [ 0x1f ] = KEY_PLAY,
111 [ 0x20 ] = KEY_PREVIOUSSONG,
112 [ 0x21 ] = KEY_NEXTSONG,
113 [ 0x22 ] = KEY_PAUSE,
114 [ 0x23 ] = KEY_STOP,
115};
116
117/* Alfons Geser <a.geser@cox.net>
118 * updates from Job D. R. Borges <jobdrb@ig.com.br> */
119static IR_KEYTAB_TYPE eztv_codes[IR_KEYTAB_SIZE] = {
120 [ 18 ] = KEY_POWER,
121 [ 1 ] = KEY_TV, // DVR
122 [ 21 ] = KEY_DVD, // DVD
123 [ 23 ] = KEY_AUDIO, // music
124 // DVR mode / DVD mode / music mode
125
126 [ 27 ] = KEY_MUTE, // mute
127 [ 2 ] = KEY_LANGUAGE, // MTS/SAP / audio / autoseek
128 [ 30 ] = KEY_SUBTITLE, // closed captioning / subtitle / seek
129 [ 22 ] = KEY_ZOOM, // full screen
130 [ 28 ] = KEY_VIDEO, // video source / eject / delall
131 [ 29 ] = KEY_RESTART, // playback / angle / del
132 [ 47 ] = KEY_SEARCH, // scan / menu / playlist
133 [ 48 ] = KEY_CHANNEL, // CH surfing / bookmark / memo
134
135 [ 49 ] = KEY_HELP, // help
136 [ 50 ] = KEY_MODE, // num/memo
137 [ 51 ] = KEY_ESC, // cancel
138
139 [ 12 ] = KEY_UP, // up
140 [ 16 ] = KEY_DOWN, // down
141 [ 8 ] = KEY_LEFT, // left
142 [ 4 ] = KEY_RIGHT, // right
143 [ 3 ] = KEY_SELECT, // select
144
145 [ 31 ] = KEY_REWIND, // rewind
146 [ 32 ] = KEY_PLAYPAUSE, // play/pause
147 [ 41 ] = KEY_FORWARD, // forward
148 [ 20 ] = KEY_AGAIN, // repeat
149 [ 43 ] = KEY_RECORD, // recording
150 [ 44 ] = KEY_STOP, // stop
151 [ 45 ] = KEY_PLAY, // play
152 [ 46 ] = KEY_SHUFFLE, // snapshot / shuffle
153
154 [ 0 ] = KEY_KP0,
155 [ 5 ] = KEY_KP1,
156 [ 6 ] = KEY_KP2,
157 [ 7 ] = KEY_KP3,
158 [ 9 ] = KEY_KP4,
159 [ 10 ] = KEY_KP5,
160 [ 11 ] = KEY_KP6,
161 [ 13 ] = KEY_KP7,
162 [ 14 ] = KEY_KP8,
163 [ 15 ] = KEY_KP9,
164
165 [ 42 ] = KEY_VOLUMEUP,
166 [ 17 ] = KEY_VOLUMEDOWN,
167 [ 24 ] = KEY_CHANNELUP, // CH.tracking up
168 [ 25 ] = KEY_CHANNELDOWN, // CH.tracking down
169
170 [ 19 ] = KEY_KPENTER, // enter
171 [ 33 ] = KEY_KPDOT, // . (decimal dot)
172};
173
174static IR_KEYTAB_TYPE avacssmart_codes[IR_KEYTAB_SIZE] = {
175 [ 30 ] = KEY_POWER, // power
176 [ 28 ] = KEY_SEARCH, // scan
177 [ 7 ] = KEY_SELECT, // source
178
179 [ 22 ] = KEY_VOLUMEUP,
180 [ 20 ] = KEY_VOLUMEDOWN,
181 [ 31 ] = KEY_CHANNELUP,
182 [ 23 ] = KEY_CHANNELDOWN,
183 [ 24 ] = KEY_MUTE,
184
185 [ 2 ] = KEY_KP0,
186 [ 1 ] = KEY_KP1,
187 [ 11 ] = KEY_KP2,
188 [ 27 ] = KEY_KP3,
189 [ 5 ] = KEY_KP4,
190 [ 9 ] = KEY_KP5,
191 [ 21 ] = KEY_KP6,
192 [ 6 ] = KEY_KP7,
193 [ 10 ] = KEY_KP8,
194 [ 18 ] = KEY_KP9,
195 [ 16 ] = KEY_KPDOT,
196
197 [ 3 ] = KEY_TUNER, // tv/fm
198 [ 4 ] = KEY_REWIND, // fm tuning left or function left
199 [ 12 ] = KEY_FORWARD, // fm tuning right or function right
200
201 [ 0 ] = KEY_RECORD,
202 [ 8 ] = KEY_STOP,
203 [ 17 ] = KEY_PLAY,
204
205 [ 25 ] = KEY_ZOOM,
206 [ 14 ] = KEY_MENU, // function
207 [ 19 ] = KEY_AGAIN, // recall
208 [ 29 ] = KEY_RESTART, // reset
209
210// FIXME
211 [ 13 ] = KEY_F21, // mts
212 [ 15 ] = KEY_F22, // min
213 [ 26 ] = KEY_F23, // freeze
214};
215
216/* Alex Hermann <gaaf@gmx.net> */
217static IR_KEYTAB_TYPE md2819_codes[IR_KEYTAB_SIZE] = {
218 [ 40 ] = KEY_KP1,
219 [ 24 ] = KEY_KP2,
220 [ 56 ] = KEY_KP3,
221 [ 36 ] = KEY_KP4,
222 [ 20 ] = KEY_KP5,
223 [ 52 ] = KEY_KP6,
224 [ 44 ] = KEY_KP7,
225 [ 28 ] = KEY_KP8,
226 [ 60 ] = KEY_KP9,
227 [ 34 ] = KEY_KP0,
228
229 [ 32 ] = KEY_TV, // TV/FM
230 [ 16 ] = KEY_CD, // CD
231 [ 48 ] = KEY_TEXT, // TELETEXT
232 [ 0 ] = KEY_POWER, // POWER
233
234 [ 8 ] = KEY_VIDEO, // VIDEO
235 [ 4 ] = KEY_AUDIO, // AUDIO
236 [ 12 ] = KEY_ZOOM, // FULL SCREEN
237
238 [ 18 ] = KEY_SUBTITLE, // DISPLAY - ???
239 [ 50 ] = KEY_REWIND, // LOOP - ???
240 [ 2 ] = KEY_PRINT, // PREVIEW - ???
241
242 [ 42 ] = KEY_SEARCH, // AUTOSCAN
243 [ 26 ] = KEY_SLEEP, // FREEZE - ???
244 [ 58 ] = KEY_SHUFFLE, // SNAPSHOT - ???
245 [ 10 ] = KEY_MUTE, // MUTE
246
247 [ 38 ] = KEY_RECORD, // RECORD
248 [ 22 ] = KEY_PAUSE, // PAUSE
249 [ 54 ] = KEY_STOP, // STOP
250 [ 6 ] = KEY_PLAY, // PLAY
251
252 [ 46 ] = KEY_RED, // <RED>
253 [ 33 ] = KEY_GREEN, // <GREEN>
254 [ 14 ] = KEY_YELLOW, // <YELLOW>
255 [ 1 ] = KEY_BLUE, // <BLUE>
256
257 [ 30 ] = KEY_VOLUMEDOWN, // VOLUME-
258 [ 62 ] = KEY_VOLUMEUP, // VOLUME+
259 [ 17 ] = KEY_CHANNELDOWN, // CHANNEL/PAGE-
260 [ 49 ] = KEY_CHANNELUP // CHANNEL/PAGE+
261};
262
263static IR_KEYTAB_TYPE videomate_tv_pvr_codes[IR_KEYTAB_SIZE] = {
264 [ 20 ] = KEY_MUTE,
265 [ 36 ] = KEY_ZOOM,
266
267 [ 1 ] = KEY_DVD,
268 [ 35 ] = KEY_RADIO,
269 [ 0 ] = KEY_TV,
270
271 [ 10 ] = KEY_REWIND,
272 [ 8 ] = KEY_PLAYPAUSE,
273 [ 15 ] = KEY_FORWARD,
274
275 [ 2 ] = KEY_PREVIOUS,
276 [ 7 ] = KEY_STOP,
277 [ 6 ] = KEY_NEXT,
278
279 [ 12 ] = KEY_UP,
280 [ 14 ] = KEY_DOWN,
281 [ 11 ] = KEY_LEFT,
282 [ 13 ] = KEY_RIGHT,
283 [ 17 ] = KEY_OK,
284
285 [ 3 ] = KEY_MENU,
286 [ 9 ] = KEY_SETUP,
287 [ 5 ] = KEY_VIDEO,
288 [ 34 ] = KEY_CHANNEL,
289
290 [ 18 ] = KEY_VOLUMEUP,
291 [ 21 ] = KEY_VOLUMEDOWN,
292 [ 16 ] = KEY_CHANNELUP,
293 [ 19 ] = KEY_CHANNELDOWN,
294
295 [ 4 ] = KEY_RECORD,
296
297 [ 22 ] = KEY_KP1,
298 [ 23 ] = KEY_KP2,
299 [ 24 ] = KEY_KP3,
300 [ 25 ] = KEY_KP4,
301 [ 26 ] = KEY_KP5,
302 [ 27 ] = KEY_KP6,
303 [ 28 ] = KEY_KP7,
304 [ 29 ] = KEY_KP8,
305 [ 30 ] = KEY_KP9,
306 [ 31 ] = KEY_KP0,
307
308 [ 32 ] = KEY_LANGUAGE,
309 [ 33 ] = KEY_SLEEP,
310};
311/* ---------------------------------------------------------------------- */
312
313static int build_key(struct saa7134_dev *dev)
314{
315 struct saa7134_ir *ir = dev->remote;
316 u32 gpio, data;
317
318 /* rising SAA7134_GPIO_GPRESCAN reads the status */
319 saa_clearb(SAA7134_GPIO_GPMODE3,SAA7134_GPIO_GPRESCAN);
320 saa_setb(SAA7134_GPIO_GPMODE3,SAA7134_GPIO_GPRESCAN);
321
322 gpio = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2);
323 if (ir->polling) {
324 if (ir->last_gpio == gpio)
325 return 0;
326 ir->last_gpio = gpio;
327 }
328
329 data = ir_extract_bits(gpio, ir->mask_keycode);
330 dprintk("build_key gpio=0x%x mask=0x%x data=%d\n",
331 gpio, ir->mask_keycode, data);
332
333 if ((ir->mask_keydown && (0 != (gpio & ir->mask_keydown))) ||
334 (ir->mask_keyup && (0 == (gpio & ir->mask_keyup)))) {
335 ir_input_keydown(&ir->dev,&ir->ir,data,data);
336 } else {
337 ir_input_nokey(&ir->dev,&ir->ir);
338 }
339 return 0;
340}
341
342/* ---------------------------------------------------------------------- */
343
344void saa7134_input_irq(struct saa7134_dev *dev)
345{
346 struct saa7134_ir *ir = dev->remote;
347
348 if (!ir->polling)
349 build_key(dev);
350}
351
352static void saa7134_input_timer(unsigned long data)
353{
354 struct saa7134_dev *dev = (struct saa7134_dev*)data;
355 struct saa7134_ir *ir = dev->remote;
356 unsigned long timeout;
357
358 build_key(dev);
359 timeout = jiffies + (ir->polling * HZ / 1000);
360 mod_timer(&ir->timer, timeout);
361}
362
363int saa7134_input_init1(struct saa7134_dev *dev)
364{
365 struct saa7134_ir *ir;
366 IR_KEYTAB_TYPE *ir_codes = NULL;
367 u32 mask_keycode = 0;
368 u32 mask_keydown = 0;
369 u32 mask_keyup = 0;
370 int polling = 0;
371 int ir_type = IR_TYPE_OTHER;
372
373 if (!dev->has_remote)
374 return -ENODEV;
375 if (disable_ir)
376 return -ENODEV;
377
378 /* detect & configure */
379 switch (dev->board) {
380 case SAA7134_BOARD_FLYVIDEO2000:
381 case SAA7134_BOARD_FLYVIDEO3000:
382 ir_codes = flyvideo_codes;
383 mask_keycode = 0xEC00000;
384 mask_keydown = 0x0040000;
385 break;
386 case SAA7134_BOARD_CINERGY400:
387 case SAA7134_BOARD_CINERGY600:
388 case SAA7134_BOARD_CINERGY600_MK3:
389 ir_codes = cinergy_codes;
390 mask_keycode = 0x00003f;
391 mask_keyup = 0x040000;
392 break;
393 case SAA7134_BOARD_ECS_TVP3XP:
394 case SAA7134_BOARD_ECS_TVP3XP_4CB5:
395 ir_codes = eztv_codes;
396 mask_keycode = 0x00017c;
397 mask_keyup = 0x000002;
398 polling = 50; // ms
399 break;
400 case SAA7134_BOARD_AVACSSMARTTV:
401 ir_codes = avacssmart_codes;
402 mask_keycode = 0x00001F;
403 mask_keyup = 0x000020;
404 polling = 50; // ms
405 break;
406 case SAA7134_BOARD_MD2819:
407 case SAA7134_BOARD_AVERMEDIA_305:
408 case SAA7134_BOARD_AVERMEDIA_307:
409 ir_codes = md2819_codes;
410 mask_keycode = 0x0007C8;
411 mask_keydown = 0x000010;
412 polling = 50; // ms
413 /* Set GPIO pin2 to high to enable the IR controller */
414 saa_setb(SAA7134_GPIO_GPMODE0, 0x4);
415 saa_setb(SAA7134_GPIO_GPSTATUS0, 0x4);
416 break;
417 case SAA7134_BOARD_VIDEOMATE_TV_PVR:
418 ir_codes = videomate_tv_pvr_codes;
419 mask_keycode = 0x00003F;
420 mask_keyup = 0x400000;
421 polling = 50; // ms
422 break;
423 }
424 if (NULL == ir_codes) {
425 printk("%s: Oops: IR config error [card=%d]\n",
426 dev->name, dev->board);
427 return -ENODEV;
428 }
429
430 ir = kmalloc(sizeof(*ir),GFP_KERNEL);
431 if (NULL == ir)
432 return -ENOMEM;
433 memset(ir,0,sizeof(*ir));
434
435 /* init hardware-specific stuff */
436 ir->mask_keycode = mask_keycode;
437 ir->mask_keydown = mask_keydown;
438 ir->mask_keyup = mask_keyup;
439 ir->polling = polling;
440
441 /* init input device */
442 snprintf(ir->name, sizeof(ir->name), "saa7134 IR (%s)",
443 saa7134_boards[dev->board].name);
444 snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0",
445 pci_name(dev->pci));
446
447 ir_input_init(&ir->dev, &ir->ir, ir_type, ir_codes);
448 ir->dev.name = ir->name;
449 ir->dev.phys = ir->phys;
450 ir->dev.id.bustype = BUS_PCI;
451 ir->dev.id.version = 1;
452 if (dev->pci->subsystem_vendor) {
453 ir->dev.id.vendor = dev->pci->subsystem_vendor;
454 ir->dev.id.product = dev->pci->subsystem_device;
455 } else {
456 ir->dev.id.vendor = dev->pci->vendor;
457 ir->dev.id.product = dev->pci->device;
458 }
459
460 /* all done */
461 dev->remote = ir;
462 if (ir->polling) {
463 init_timer(&ir->timer);
464 ir->timer.function = saa7134_input_timer;
465 ir->timer.data = (unsigned long)dev;
466 ir->timer.expires = jiffies + HZ;
467 add_timer(&ir->timer);
468 }
469
470 input_register_device(&dev->remote->dev);
471 printk("%s: registered input device for IR\n",dev->name);
472 return 0;
473}
474
475void saa7134_input_fini(struct saa7134_dev *dev)
476{
477 if (NULL == dev->remote)
478 return;
479
480 input_unregister_device(&dev->remote->dev);
481 if (dev->remote->polling)
482 del_timer_sync(&dev->remote->timer);
483 kfree(dev->remote);
484 dev->remote = NULL;
485}
486
487/* ----------------------------------------------------------------------
488 * Local variables:
489 * c-basic-offset: 8
490 * End:
491 */
diff --git a/drivers/media/video/saa7134/saa7134-oss.c b/drivers/media/video/saa7134/saa7134-oss.c
new file mode 100644
index 000000000000..6b6a643bf1cd
--- /dev/null
+++ b/drivers/media/video/saa7134/saa7134-oss.c
@@ -0,0 +1,857 @@
1/*
2 * $Id: saa7134-oss.c,v 1.13 2004/12/10 12:33:39 kraxel Exp $
3 *
4 * device driver for philips saa7134 based TV cards
5 * oss dsp interface
6 *
7 * (c) 2001,02 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include <linux/init.h>
25#include <linux/list.h>
26#include <linux/module.h>
27#include <linux/moduleparam.h>
28#include <linux/kernel.h>
29#include <linux/slab.h>
30#include <linux/soundcard.h>
31
32#include "saa7134-reg.h"
33#include "saa7134.h"
34
35/* ------------------------------------------------------------------ */
36
37static unsigned int oss_debug = 0;
38module_param(oss_debug, int, 0644);
39MODULE_PARM_DESC(oss_debug,"enable debug messages [oss]");
40
41static unsigned int oss_rate = 0;
42module_param(oss_rate, int, 0444);
43MODULE_PARM_DESC(oss_rate,"sample rate (valid are: 32000,48000)");
44
45#define dprintk(fmt, arg...) if (oss_debug) \
46 printk(KERN_DEBUG "%s/oss: " fmt, dev->name , ## arg)
47
48/* ------------------------------------------------------------------ */
49
50static int dsp_buffer_conf(struct saa7134_dev *dev, int blksize, int blocks)
51{
52 blksize &= ~0xff;
53 if (blksize < 0x100)
54 blksize = 0x100;
55 if (blksize > 0x10000)
56 blksize = 0x10000;
57
58 if (blocks < 2)
59 blocks = 2;
60 while ((blksize * blocks) & ~PAGE_MASK)
61 blocks++;
62 if ((blksize * blocks) > 1024*1024)
63 blocks = 1024*1024 / blksize;
64
65 dev->oss.blocks = blocks;
66 dev->oss.blksize = blksize;
67 dev->oss.bufsize = blksize * blocks;
68
69 dprintk("buffer config: %d blocks / %d bytes, %d kB total\n",
70 blocks,blksize,blksize * blocks / 1024);
71 return 0;
72}
73
74static int dsp_buffer_init(struct saa7134_dev *dev)
75{
76 int err;
77
78 if (!dev->oss.bufsize)
79 BUG();
80 videobuf_dma_init(&dev->oss.dma);
81 err = videobuf_dma_init_kernel(&dev->oss.dma, PCI_DMA_FROMDEVICE,
82 dev->oss.bufsize >> PAGE_SHIFT);
83 if (0 != err)
84 return err;
85 return 0;
86}
87
88static int dsp_buffer_free(struct saa7134_dev *dev)
89{
90 if (!dev->oss.blksize)
91 BUG();
92 videobuf_dma_free(&dev->oss.dma);
93 dev->oss.blocks = 0;
94 dev->oss.blksize = 0;
95 dev->oss.bufsize = 0;
96 return 0;
97}
98
99static void dsp_dma_start(struct saa7134_dev *dev)
100{
101 dev->oss.dma_blk = 0;
102 dev->oss.dma_running = 1;
103 saa7134_set_dmabits(dev);
104}
105
106static void dsp_dma_stop(struct saa7134_dev *dev)
107{
108 dev->oss.dma_blk = -1;
109 dev->oss.dma_running = 0;
110 saa7134_set_dmabits(dev);
111}
112
113static int dsp_rec_start(struct saa7134_dev *dev)
114{
115 int err, bswap, sign;
116 u32 fmt, control;
117 unsigned long flags;
118
119 /* prepare buffer */
120 if (0 != (err = videobuf_dma_pci_map(dev->pci,&dev->oss.dma)))
121 return err;
122 if (0 != (err = saa7134_pgtable_alloc(dev->pci,&dev->oss.pt)))
123 goto fail1;
124 if (0 != (err = saa7134_pgtable_build(dev->pci,&dev->oss.pt,
125 dev->oss.dma.sglist,
126 dev->oss.dma.sglen,
127 0)))
128 goto fail2;
129
130 /* sample format */
131 switch (dev->oss.afmt) {
132 case AFMT_U8:
133 case AFMT_S8: fmt = 0x00; break;
134 case AFMT_U16_LE:
135 case AFMT_U16_BE:
136 case AFMT_S16_LE:
137 case AFMT_S16_BE: fmt = 0x01; break;
138 default:
139 err = -EINVAL;
140 goto fail2;
141 }
142
143 switch (dev->oss.afmt) {
144 case AFMT_S8:
145 case AFMT_S16_LE:
146 case AFMT_S16_BE: sign = 1; break;
147 default: sign = 0; break;
148 }
149
150 switch (dev->oss.afmt) {
151 case AFMT_U16_BE:
152 case AFMT_S16_BE: bswap = 1; break;
153 default: bswap = 0; break;
154 }
155
156 switch (dev->pci->device) {
157 case PCI_DEVICE_ID_PHILIPS_SAA7134:
158 if (1 == dev->oss.channels)
159 fmt |= (1 << 3);
160 if (2 == dev->oss.channels)
161 fmt |= (3 << 3);
162 if (sign)
163 fmt |= 0x04;
164 fmt |= (TV == dev->oss.input) ? 0xc0 : 0x80;
165
166 saa_writeb(SAA7134_NUM_SAMPLES0, (dev->oss.blksize & 0x0000ff));
167 saa_writeb(SAA7134_NUM_SAMPLES1, (dev->oss.blksize & 0x00ff00) >> 8);
168 saa_writeb(SAA7134_NUM_SAMPLES2, (dev->oss.blksize & 0xff0000) >> 16);
169 saa_writeb(SAA7134_AUDIO_FORMAT_CTRL, fmt);
170 break;
171 case PCI_DEVICE_ID_PHILIPS_SAA7133:
172 case PCI_DEVICE_ID_PHILIPS_SAA7135:
173 if (1 == dev->oss.channels)
174 fmt |= (1 << 4);
175 if (2 == dev->oss.channels)
176 fmt |= (2 << 4);
177 if (!sign)
178 fmt |= 0x04;
179 saa_writel(0x588 >> 2, dev->oss.blksize -4);
180 saa_writel(0x58c >> 2, 0x543210 | (fmt << 24));
181 break;
182 }
183 dprintk("rec_start: afmt=%d ch=%d => fmt=0x%x swap=%c\n",
184 dev->oss.afmt, dev->oss.channels, fmt,
185 bswap ? 'b' : '-');
186
187 /* dma: setup channel 6 (= AUDIO) */
188 control = SAA7134_RS_CONTROL_BURST_16 |
189 SAA7134_RS_CONTROL_ME |
190 (dev->oss.pt.dma >> 12);
191 if (bswap)
192 control |= SAA7134_RS_CONTROL_BSWAP;
193 saa_writel(SAA7134_RS_BA1(6),0);
194 saa_writel(SAA7134_RS_BA2(6),dev->oss.blksize);
195 saa_writel(SAA7134_RS_PITCH(6),0);
196 saa_writel(SAA7134_RS_CONTROL(6),control);
197
198 /* start dma */
199 dev->oss.recording_on = 1;
200 spin_lock_irqsave(&dev->slock,flags);
201 dsp_dma_start(dev);
202 spin_unlock_irqrestore(&dev->slock,flags);
203 return 0;
204
205 fail2:
206 saa7134_pgtable_free(dev->pci,&dev->oss.pt);
207 fail1:
208 videobuf_dma_pci_unmap(dev->pci,&dev->oss.dma);
209 return err;
210}
211
212static int dsp_rec_stop(struct saa7134_dev *dev)
213{
214 unsigned long flags;
215
216 dprintk("rec_stop dma_blk=%d\n",dev->oss.dma_blk);
217
218 /* stop dma */
219 dev->oss.recording_on = 0;
220 spin_lock_irqsave(&dev->slock,flags);
221 dsp_dma_stop(dev);
222 spin_unlock_irqrestore(&dev->slock,flags);
223
224 /* unlock buffer */
225 saa7134_pgtable_free(dev->pci,&dev->oss.pt);
226 videobuf_dma_pci_unmap(dev->pci,&dev->oss.dma);
227 return 0;
228}
229
230/* ------------------------------------------------------------------ */
231
232static int dsp_open(struct inode *inode, struct file *file)
233{
234 int minor = iminor(inode);
235 struct saa7134_dev *h,*dev = NULL;
236 struct list_head *list;
237 int err;
238
239 list_for_each(list,&saa7134_devlist) {
240 h = list_entry(list, struct saa7134_dev, devlist);
241 if (h->oss.minor_dsp == minor)
242 dev = h;
243 }
244 if (NULL == dev)
245 return -ENODEV;
246
247 down(&dev->oss.lock);
248 err = -EBUSY;
249 if (dev->oss.users_dsp)
250 goto fail1;
251 dev->oss.users_dsp++;
252 file->private_data = dev;
253
254 dev->oss.afmt = AFMT_U8;
255 dev->oss.channels = 1;
256 dev->oss.read_count = 0;
257 dev->oss.read_offset = 0;
258 dsp_buffer_conf(dev,PAGE_SIZE,64);
259 err = dsp_buffer_init(dev);
260 if (0 != err)
261 goto fail2;
262
263 up(&dev->oss.lock);
264 return 0;
265
266 fail2:
267 dev->oss.users_dsp--;
268 fail1:
269 up(&dev->oss.lock);
270 return err;
271}
272
273static int dsp_release(struct inode *inode, struct file *file)
274{
275 struct saa7134_dev *dev = file->private_data;
276
277 down(&dev->oss.lock);
278 if (dev->oss.recording_on)
279 dsp_rec_stop(dev);
280 dsp_buffer_free(dev);
281 dev->oss.users_dsp--;
282 file->private_data = NULL;
283 up(&dev->oss.lock);
284 return 0;
285}
286
287static ssize_t dsp_read(struct file *file, char __user *buffer,
288 size_t count, loff_t *ppos)
289{
290 struct saa7134_dev *dev = file->private_data;
291 DECLARE_WAITQUEUE(wait, current);
292 unsigned int bytes;
293 unsigned long flags;
294 int err,ret = 0;
295
296 add_wait_queue(&dev->oss.wq, &wait);
297 down(&dev->oss.lock);
298 while (count > 0) {
299 /* wait for data if needed */
300 if (0 == dev->oss.read_count) {
301 if (!dev->oss.recording_on) {
302 err = dsp_rec_start(dev);
303 if (err < 0) {
304 if (0 == ret)
305 ret = err;
306 break;
307 }
308 }
309 if (dev->oss.recording_on &&
310 !dev->oss.dma_running) {
311 /* recover from overruns */
312 spin_lock_irqsave(&dev->slock,flags);
313 dsp_dma_start(dev);
314 spin_unlock_irqrestore(&dev->slock,flags);
315 }
316 if (file->f_flags & O_NONBLOCK) {
317 if (0 == ret)
318 ret = -EAGAIN;
319 break;
320 }
321 up(&dev->oss.lock);
322 set_current_state(TASK_INTERRUPTIBLE);
323 if (0 == dev->oss.read_count)
324 schedule();
325 set_current_state(TASK_RUNNING);
326 down(&dev->oss.lock);
327 if (signal_pending(current)) {
328 if (0 == ret)
329 ret = -EINTR;
330 break;
331 }
332 }
333
334 /* copy data to userspace */
335 bytes = count;
336 if (bytes > dev->oss.read_count)
337 bytes = dev->oss.read_count;
338 if (bytes > dev->oss.bufsize - dev->oss.read_offset)
339 bytes = dev->oss.bufsize - dev->oss.read_offset;
340 if (copy_to_user(buffer + ret,
341 dev->oss.dma.vmalloc + dev->oss.read_offset,
342 bytes)) {
343 if (0 == ret)
344 ret = -EFAULT;
345 break;
346 }
347
348 ret += bytes;
349 count -= bytes;
350 dev->oss.read_count -= bytes;
351 dev->oss.read_offset += bytes;
352 if (dev->oss.read_offset == dev->oss.bufsize)
353 dev->oss.read_offset = 0;
354 }
355 up(&dev->oss.lock);
356 remove_wait_queue(&dev->oss.wq, &wait);
357 return ret;
358}
359
360static ssize_t dsp_write(struct file *file, const char __user *buffer,
361 size_t count, loff_t *ppos)
362{
363 return -EINVAL;
364}
365
366static int dsp_ioctl(struct inode *inode, struct file *file,
367 unsigned int cmd, unsigned long arg)
368{
369 struct saa7134_dev *dev = file->private_data;
370 void __user *argp = (void __user *) arg;
371 int __user *p = argp;
372 int val = 0;
373
374 if (oss_debug > 1)
375 saa7134_print_ioctl(dev->name,cmd);
376 switch (cmd) {
377 case OSS_GETVERSION:
378 return put_user(SOUND_VERSION, p);
379 case SNDCTL_DSP_GETCAPS:
380 return 0;
381
382 case SNDCTL_DSP_SPEED:
383 if (get_user(val, p))
384 return -EFAULT;
385 /* fall through */
386 case SOUND_PCM_READ_RATE:
387 return put_user(dev->oss.rate, p);
388
389 case SNDCTL_DSP_STEREO:
390 if (get_user(val, p))
391 return -EFAULT;
392 down(&dev->oss.lock);
393 dev->oss.channels = val ? 2 : 1;
394 if (dev->oss.recording_on) {
395 dsp_rec_stop(dev);
396 dsp_rec_start(dev);
397 }
398 up(&dev->oss.lock);
399 return put_user(dev->oss.channels-1, p);
400
401 case SNDCTL_DSP_CHANNELS:
402 if (get_user(val, p))
403 return -EFAULT;
404 if (val != 1 && val != 2)
405 return -EINVAL;
406 down(&dev->oss.lock);
407 dev->oss.channels = val;
408 if (dev->oss.recording_on) {
409 dsp_rec_stop(dev);
410 dsp_rec_start(dev);
411 }
412 up(&dev->oss.lock);
413 /* fall through */
414 case SOUND_PCM_READ_CHANNELS:
415 return put_user(dev->oss.channels, p);
416
417 case SNDCTL_DSP_GETFMTS: /* Returns a mask */
418 return put_user(AFMT_U8 | AFMT_S8 |
419 AFMT_U16_LE | AFMT_U16_BE |
420 AFMT_S16_LE | AFMT_S16_BE, p);
421
422 case SNDCTL_DSP_SETFMT: /* Selects ONE fmt */
423 if (get_user(val, p))
424 return -EFAULT;
425 switch (val) {
426 case AFMT_QUERY:
427 /* nothing to do */
428 break;
429 case AFMT_U8:
430 case AFMT_S8:
431 case AFMT_U16_LE:
432 case AFMT_U16_BE:
433 case AFMT_S16_LE:
434 case AFMT_S16_BE:
435 down(&dev->oss.lock);
436 dev->oss.afmt = val;
437 if (dev->oss.recording_on) {
438 dsp_rec_stop(dev);
439 dsp_rec_start(dev);
440 }
441 up(&dev->oss.lock);
442 return put_user(dev->oss.afmt, p);
443 default:
444 return -EINVAL;
445 }
446
447 case SOUND_PCM_READ_BITS:
448 switch (dev->oss.afmt) {
449 case AFMT_U8:
450 case AFMT_S8:
451 return put_user(8, p);
452 case AFMT_U16_LE:
453 case AFMT_U16_BE:
454 case AFMT_S16_LE:
455 case AFMT_S16_BE:
456 return put_user(16, p);
457 default:
458 return -EINVAL;
459 }
460
461 case SNDCTL_DSP_NONBLOCK:
462 file->f_flags |= O_NONBLOCK;
463 return 0;
464
465 case SNDCTL_DSP_RESET:
466 down(&dev->oss.lock);
467 if (dev->oss.recording_on)
468 dsp_rec_stop(dev);
469 up(&dev->oss.lock);
470 return 0;
471 case SNDCTL_DSP_GETBLKSIZE:
472 return put_user(dev->oss.blksize, p);
473
474 case SNDCTL_DSP_SETFRAGMENT:
475 if (get_user(val, p))
476 return -EFAULT;
477 if (dev->oss.recording_on)
478 return -EBUSY;
479 dsp_buffer_free(dev);
480 /* used to be arg >> 16 instead of val >> 16; fixed */
481 dsp_buffer_conf(dev,1 << (val & 0xffff), (val >> 16) & 0xffff);
482 dsp_buffer_init(dev);
483 return 0;
484
485 case SNDCTL_DSP_SYNC:
486 /* NOP */
487 return 0;
488
489 case SNDCTL_DSP_GETISPACE:
490 {
491 audio_buf_info info;
492 info.fragsize = dev->oss.blksize;
493 info.fragstotal = dev->oss.blocks;
494 info.bytes = dev->oss.read_count;
495 info.fragments = info.bytes / info.fragsize;
496 if (copy_to_user(argp, &info, sizeof(info)))
497 return -EFAULT;
498 return 0;
499 }
500 default:
501 return -EINVAL;
502 }
503}
504
505static unsigned int dsp_poll(struct file *file, struct poll_table_struct *wait)
506{
507 struct saa7134_dev *dev = file->private_data;
508 unsigned int mask = 0;
509
510 poll_wait(file, &dev->oss.wq, wait);
511
512 if (0 == dev->oss.read_count) {
513 down(&dev->oss.lock);
514 if (!dev->oss.recording_on)
515 dsp_rec_start(dev);
516 up(&dev->oss.lock);
517 } else
518 mask |= (POLLIN | POLLRDNORM);
519 return mask;
520}
521
522struct file_operations saa7134_dsp_fops = {
523 .owner = THIS_MODULE,
524 .open = dsp_open,
525 .release = dsp_release,
526 .read = dsp_read,
527 .write = dsp_write,
528 .ioctl = dsp_ioctl,
529 .poll = dsp_poll,
530 .llseek = no_llseek,
531};
532
533/* ------------------------------------------------------------------ */
534
535static int
536mixer_recsrc_7134(struct saa7134_dev *dev)
537{
538 int analog_io,rate;
539
540 switch (dev->oss.input) {
541 case TV:
542 saa_andorb(SAA7134_AUDIO_FORMAT_CTRL, 0xc0, 0xc0);
543 saa_andorb(SAA7134_SIF_SAMPLE_FREQ, 0x03, 0x00);
544 break;
545 case LINE1:
546 case LINE2:
547 case LINE2_LEFT:
548 analog_io = (LINE1 == dev->oss.input) ? 0x00 : 0x08;
549 rate = (32000 == dev->oss.rate) ? 0x01 : 0x03;
550 saa_andorb(SAA7134_ANALOG_IO_SELECT, 0x08, analog_io);
551 saa_andorb(SAA7134_AUDIO_FORMAT_CTRL, 0xc0, 0x80);
552 saa_andorb(SAA7134_SIF_SAMPLE_FREQ, 0x03, rate);
553 break;
554 }
555 return 0;
556}
557
558static int
559mixer_recsrc_7133(struct saa7134_dev *dev)
560{
561 u32 value = 0xbbbbbb;
562
563 switch (dev->oss.input) {
564 case TV:
565 value = 0xbbbb10; /* MAIN */
566 break;
567 case LINE1:
568 value = 0xbbbb32; /* AUX1 */
569 break;
570 case LINE2:
571 case LINE2_LEFT:
572 value = 0xbbbb54; /* AUX2 */
573 break;
574 }
575 saa_dsp_writel(dev, 0x46c >> 2, value);
576 return 0;
577}
578
579static int
580mixer_recsrc(struct saa7134_dev *dev, enum saa7134_audio_in src)
581{
582 static const char *iname[] = { "Oops", "TV", "LINE1", "LINE2" };
583
584 dev->oss.count++;
585 dev->oss.input = src;
586 dprintk("mixer input = %s\n",iname[dev->oss.input]);
587
588 switch (dev->pci->device) {
589 case PCI_DEVICE_ID_PHILIPS_SAA7134:
590 mixer_recsrc_7134(dev);
591 break;
592 case PCI_DEVICE_ID_PHILIPS_SAA7133:
593 case PCI_DEVICE_ID_PHILIPS_SAA7135:
594 mixer_recsrc_7133(dev);
595 break;
596 }
597 return 0;
598}
599
600static int
601mixer_level(struct saa7134_dev *dev, enum saa7134_audio_in src, int level)
602{
603 switch (dev->pci->device) {
604 case PCI_DEVICE_ID_PHILIPS_SAA7134:
605 switch (src) {
606 case TV:
607 /* nothing */
608 break;
609 case LINE1:
610 saa_andorb(SAA7134_ANALOG_IO_SELECT, 0x10,
611 (100 == level) ? 0x00 : 0x10);
612 break;
613 case LINE2:
614 case LINE2_LEFT:
615 saa_andorb(SAA7134_ANALOG_IO_SELECT, 0x20,
616 (100 == level) ? 0x00 : 0x20);
617 break;
618 }
619 break;
620 case PCI_DEVICE_ID_PHILIPS_SAA7133:
621 case PCI_DEVICE_ID_PHILIPS_SAA7135:
622 /* nothing */
623 break;
624 }
625 return 0;
626}
627
628/* ------------------------------------------------------------------ */
629
630static int mixer_open(struct inode *inode, struct file *file)
631{
632 int minor = iminor(inode);
633 struct saa7134_dev *h,*dev = NULL;
634 struct list_head *list;
635
636 list_for_each(list,&saa7134_devlist) {
637 h = list_entry(list, struct saa7134_dev, devlist);
638 if (h->oss.minor_mixer == minor)
639 dev = h;
640 }
641 if (NULL == dev)
642 return -ENODEV;
643
644 file->private_data = dev;
645 return 0;
646}
647
648static int mixer_release(struct inode *inode, struct file *file)
649{
650 file->private_data = NULL;
651 return 0;
652}
653
654static int mixer_ioctl(struct inode *inode, struct file *file,
655 unsigned int cmd, unsigned long arg)
656{
657 struct saa7134_dev *dev = file->private_data;
658 enum saa7134_audio_in input;
659 int val,ret;
660 void __user *argp = (void __user *) arg;
661 int __user *p = argp;
662
663 if (oss_debug > 1)
664 saa7134_print_ioctl(dev->name,cmd);
665 switch (cmd) {
666 case OSS_GETVERSION:
667 return put_user(SOUND_VERSION, p);
668 case SOUND_MIXER_INFO:
669 {
670 mixer_info info;
671 memset(&info,0,sizeof(info));
672 strlcpy(info.id, "TV audio", sizeof(info.id));
673 strlcpy(info.name, dev->name, sizeof(info.name));
674 info.modify_counter = dev->oss.count;
675 if (copy_to_user(argp, &info, sizeof(info)))
676 return -EFAULT;
677 return 0;
678 }
679 case SOUND_OLD_MIXER_INFO:
680 {
681 _old_mixer_info info;
682 memset(&info,0,sizeof(info));
683 strlcpy(info.id, "TV audio", sizeof(info.id));
684 strlcpy(info.name, dev->name, sizeof(info.name));
685 if (copy_to_user(argp, &info, sizeof(info)))
686 return -EFAULT;
687 return 0;
688 }
689 case MIXER_READ(SOUND_MIXER_CAPS):
690 return put_user(SOUND_CAP_EXCL_INPUT, p);
691 case MIXER_READ(SOUND_MIXER_STEREODEVS):
692 return put_user(0, p);
693 case MIXER_READ(SOUND_MIXER_RECMASK):
694 case MIXER_READ(SOUND_MIXER_DEVMASK):
695 val = SOUND_MASK_LINE1 | SOUND_MASK_LINE2;
696 if (32000 == dev->oss.rate)
697 val |= SOUND_MASK_VIDEO;
698 return put_user(val, p);
699
700 case MIXER_WRITE(SOUND_MIXER_RECSRC):
701 if (get_user(val, p))
702 return -EFAULT;
703 input = dev->oss.input;
704 if (32000 == dev->oss.rate &&
705 val & SOUND_MASK_VIDEO && dev->oss.input != TV)
706 input = TV;
707 if (val & SOUND_MASK_LINE1 && dev->oss.input != LINE1)
708 input = LINE1;
709 if (val & SOUND_MASK_LINE2 && dev->oss.input != LINE2)
710 input = LINE2;
711 if (input != dev->oss.input)
712 mixer_recsrc(dev,input);
713 /* fall throuth */
714 case MIXER_READ(SOUND_MIXER_RECSRC):
715 switch (dev->oss.input) {
716 case TV: ret = SOUND_MASK_VIDEO; break;
717 case LINE1: ret = SOUND_MASK_LINE1; break;
718 case LINE2: ret = SOUND_MASK_LINE2; break;
719 default: ret = 0;
720 }
721 return put_user(ret, p);
722
723 case MIXER_WRITE(SOUND_MIXER_VIDEO):
724 case MIXER_READ(SOUND_MIXER_VIDEO):
725 if (32000 != dev->oss.rate)
726 return -EINVAL;
727 return put_user(100 | 100 << 8, p);
728
729 case MIXER_WRITE(SOUND_MIXER_LINE1):
730 if (get_user(val, p))
731 return -EFAULT;
732 val &= 0xff;
733 val = (val <= 50) ? 50 : 100;
734 dev->oss.line1 = val;
735 mixer_level(dev,LINE1,dev->oss.line1);
736 /* fall throuth */
737 case MIXER_READ(SOUND_MIXER_LINE1):
738 return put_user(dev->oss.line1 | dev->oss.line1 << 8, p);
739
740 case MIXER_WRITE(SOUND_MIXER_LINE2):
741 if (get_user(val, p))
742 return -EFAULT;
743 val &= 0xff;
744 val = (val <= 50) ? 50 : 100;
745 dev->oss.line2 = val;
746 mixer_level(dev,LINE2,dev->oss.line2);
747 /* fall throuth */
748 case MIXER_READ(SOUND_MIXER_LINE2):
749 return put_user(dev->oss.line2 | dev->oss.line2 << 8, p);
750
751 default:
752 return -EINVAL;
753 }
754}
755
756struct file_operations saa7134_mixer_fops = {
757 .owner = THIS_MODULE,
758 .open = mixer_open,
759 .release = mixer_release,
760 .ioctl = mixer_ioctl,
761 .llseek = no_llseek,
762};
763
764/* ------------------------------------------------------------------ */
765
766int saa7134_oss_init1(struct saa7134_dev *dev)
767{
768 /* general */
769 init_MUTEX(&dev->oss.lock);
770 init_waitqueue_head(&dev->oss.wq);
771
772 switch (dev->pci->device) {
773 case PCI_DEVICE_ID_PHILIPS_SAA7133:
774 case PCI_DEVICE_ID_PHILIPS_SAA7135:
775 saa_writel(0x588 >> 2, 0x00000fff);
776 saa_writel(0x58c >> 2, 0x00543210);
777 saa_dsp_writel(dev, 0x46c >> 2, 0xbbbbbb);
778 break;
779 }
780
781 /* dsp */
782 dev->oss.rate = 32000;
783 if (oss_rate)
784 dev->oss.rate = oss_rate;
785 dev->oss.rate = (dev->oss.rate > 40000) ? 48000 : 32000;
786
787 /* mixer */
788 dev->oss.line1 = 50;
789 dev->oss.line2 = 50;
790 mixer_level(dev,LINE1,dev->oss.line1);
791 mixer_level(dev,LINE2,dev->oss.line2);
792 mixer_recsrc(dev, (dev->oss.rate == 32000) ? TV : LINE2);
793
794 return 0;
795}
796
797int saa7134_oss_fini(struct saa7134_dev *dev)
798{
799 /* nothing */
800 return 0;
801}
802
803void saa7134_irq_oss_done(struct saa7134_dev *dev, unsigned long status)
804{
805 int next_blk, reg = 0;
806
807 spin_lock(&dev->slock);
808 if (UNSET == dev->oss.dma_blk) {
809 dprintk("irq: recording stopped\n");
810 goto done;
811 }
812 if (0 != (status & 0x0f000000))
813 dprintk("irq: lost %ld\n", (status >> 24) & 0x0f);
814 if (0 == (status & 0x10000000)) {
815 /* odd */
816 if (0 == (dev->oss.dma_blk & 0x01))
817 reg = SAA7134_RS_BA1(6);
818 } else {
819 /* even */
820 if (0 == (dev->oss.dma_blk & 0x00))
821 reg = SAA7134_RS_BA2(6);
822 }
823 if (0 == reg) {
824 dprintk("irq: field oops [%s]\n",
825 (status & 0x10000000) ? "even" : "odd");
826 goto done;
827 }
828 if (dev->oss.read_count >= dev->oss.blksize * (dev->oss.blocks-2)) {
829 dprintk("irq: overrun [full=%d/%d]\n",dev->oss.read_count,
830 dev->oss.bufsize);
831 dsp_dma_stop(dev);
832 goto done;
833 }
834
835 /* next block addr */
836 next_blk = (dev->oss.dma_blk + 2) % dev->oss.blocks;
837 saa_writel(reg,next_blk * dev->oss.blksize);
838 if (oss_debug > 2)
839 dprintk("irq: ok, %s, next_blk=%d, addr=%x\n",
840 (status & 0x10000000) ? "even" : "odd ", next_blk,
841 next_blk * dev->oss.blksize);
842
843 /* update status & wake waiting readers */
844 dev->oss.dma_blk = (dev->oss.dma_blk + 1) % dev->oss.blocks;
845 dev->oss.read_count += dev->oss.blksize;
846 wake_up(&dev->oss.wq);
847
848 done:
849 spin_unlock(&dev->slock);
850}
851
852/* ----------------------------------------------------------- */
853/*
854 * Local variables:
855 * c-basic-offset: 8
856 * End:
857 */
diff --git a/drivers/media/video/saa7134/saa7134-reg.h b/drivers/media/video/saa7134/saa7134-reg.h
new file mode 100644
index 000000000000..87734f22af7d
--- /dev/null
+++ b/drivers/media/video/saa7134/saa7134-reg.h
@@ -0,0 +1,366 @@
1/*
2 * $Id: saa7134-reg.h,v 1.2 2004/09/15 16:15:24 kraxel Exp $
3 *
4 * philips saa7134 registers
5 */
6
7/* ------------------------------------------------------------------ */
8/*
9 * PCI ID's
10 */
11#ifndef PCI_DEVICE_ID_PHILIPS_SAA7130
12# define PCI_DEVICE_ID_PHILIPS_SAA7130 0x7130
13#endif
14#ifndef PCI_DEVICE_ID_PHILIPS_SAA7133
15# define PCI_DEVICE_ID_PHILIPS_SAA7133 0x7133
16#endif
17#ifndef PCI_DEVICE_ID_PHILIPS_SAA7134
18# define PCI_DEVICE_ID_PHILIPS_SAA7134 0x7134
19#endif
20#ifndef PCI_DEVICE_ID_PHILIPS_SAA7135
21# define PCI_DEVICE_ID_PHILIPS_SAA7135 0x7135
22#endif
23
24/* ------------------------------------------------------------------ */
25/*
26 * registers -- 32 bit
27 */
28
29/* DMA channels, n = 0 ... 6 */
30#define SAA7134_RS_BA1(n) ((0x200 >> 2) + 4*n)
31#define SAA7134_RS_BA2(n) ((0x204 >> 2) + 4*n)
32#define SAA7134_RS_PITCH(n) ((0x208 >> 2) + 4*n)
33#define SAA7134_RS_CONTROL(n) ((0x20c >> 2) + 4*n)
34#define SAA7134_RS_CONTROL_WSWAP (0x01 << 25)
35#define SAA7134_RS_CONTROL_BSWAP (0x01 << 24)
36#define SAA7134_RS_CONTROL_BURST_2 (0x01 << 21)
37#define SAA7134_RS_CONTROL_BURST_4 (0x02 << 21)
38#define SAA7134_RS_CONTROL_BURST_8 (0x03 << 21)
39#define SAA7134_RS_CONTROL_BURST_16 (0x04 << 21)
40#define SAA7134_RS_CONTROL_BURST_32 (0x05 << 21)
41#define SAA7134_RS_CONTROL_BURST_64 (0x06 << 21)
42#define SAA7134_RS_CONTROL_BURST_MAX (0x07 << 21)
43#define SAA7134_RS_CONTROL_ME (0x01 << 20)
44#define SAA7134_FIFO_SIZE (0x2a0 >> 2)
45#define SAA7134_THRESHOULD (0x2a4 >> 2)
46
47/* main control */
48#define SAA7134_MAIN_CTRL (0x2a8 >> 2)
49#define SAA7134_MAIN_CTRL_VPLLE (1 << 15)
50#define SAA7134_MAIN_CTRL_APLLE (1 << 14)
51#define SAA7134_MAIN_CTRL_EXOSC (1 << 13)
52#define SAA7134_MAIN_CTRL_EVFE1 (1 << 12)
53#define SAA7134_MAIN_CTRL_EVFE2 (1 << 11)
54#define SAA7134_MAIN_CTRL_ESFE (1 << 10)
55#define SAA7134_MAIN_CTRL_EBADC (1 << 9)
56#define SAA7134_MAIN_CTRL_EBDAC (1 << 8)
57#define SAA7134_MAIN_CTRL_TE6 (1 << 6)
58#define SAA7134_MAIN_CTRL_TE5 (1 << 5)
59#define SAA7134_MAIN_CTRL_TE4 (1 << 4)
60#define SAA7134_MAIN_CTRL_TE3 (1 << 3)
61#define SAA7134_MAIN_CTRL_TE2 (1 << 2)
62#define SAA7134_MAIN_CTRL_TE1 (1 << 1)
63#define SAA7134_MAIN_CTRL_TE0 (1 << 0)
64
65/* DMA status */
66#define SAA7134_DMA_STATUS (0x2ac >> 2)
67
68/* audio / video status */
69#define SAA7134_AV_STATUS (0x2c0 >> 2)
70#define SAA7134_AV_STATUS_STEREO (1 << 17)
71#define SAA7134_AV_STATUS_DUAL (1 << 16)
72#define SAA7134_AV_STATUS_PILOT (1 << 15)
73#define SAA7134_AV_STATUS_SMB (1 << 14)
74#define SAA7134_AV_STATUS_DMB (1 << 13)
75#define SAA7134_AV_STATUS_VDSP (1 << 12)
76#define SAA7134_AV_STATUS_IIC_STATUS (3 << 10)
77#define SAA7134_AV_STATUS_MVM (7 << 7)
78#define SAA7134_AV_STATUS_FIDT (1 << 6)
79#define SAA7134_AV_STATUS_INTL (1 << 5)
80#define SAA7134_AV_STATUS_RDCAP (1 << 4)
81#define SAA7134_AV_STATUS_PWR_ON (1 << 3)
82#define SAA7134_AV_STATUS_LOAD_ERR (1 << 2)
83#define SAA7134_AV_STATUS_TRIG_ERR (1 << 1)
84#define SAA7134_AV_STATUS_CONF_ERR (1 << 0)
85
86/* interrupt */
87#define SAA7134_IRQ1 (0x2c4 >> 2)
88#define SAA7134_IRQ1_INTE_RA3_1 (1 << 25)
89#define SAA7134_IRQ1_INTE_RA3_0 (1 << 24)
90#define SAA7134_IRQ1_INTE_RA2_3 (1 << 19)
91#define SAA7134_IRQ1_INTE_RA2_2 (1 << 18)
92#define SAA7134_IRQ1_INTE_RA2_1 (1 << 17)
93#define SAA7134_IRQ1_INTE_RA2_0 (1 << 16)
94#define SAA7134_IRQ1_INTE_RA1_3 (1 << 11)
95#define SAA7134_IRQ1_INTE_RA1_2 (1 << 10)
96#define SAA7134_IRQ1_INTE_RA1_1 (1 << 9)
97#define SAA7134_IRQ1_INTE_RA1_0 (1 << 8)
98#define SAA7134_IRQ1_INTE_RA0_7 (1 << 7)
99#define SAA7134_IRQ1_INTE_RA0_6 (1 << 6)
100#define SAA7134_IRQ1_INTE_RA0_5 (1 << 5)
101#define SAA7134_IRQ1_INTE_RA0_4 (1 << 4)
102#define SAA7134_IRQ1_INTE_RA0_3 (1 << 3)
103#define SAA7134_IRQ1_INTE_RA0_2 (1 << 2)
104#define SAA7134_IRQ1_INTE_RA0_1 (1 << 1)
105#define SAA7134_IRQ1_INTE_RA0_0 (1 << 0)
106
107#define SAA7134_IRQ2 (0x2c8 >> 2)
108#define SAA7134_IRQ2_INTE_GPIO23A (1 << 17)
109#define SAA7134_IRQ2_INTE_GPIO23 (1 << 16)
110#define SAA7134_IRQ2_INTE_GPIO22A (1 << 15)
111#define SAA7134_IRQ2_INTE_GPIO22 (1 << 14)
112#define SAA7134_IRQ2_INTE_GPIO18A (1 << 13)
113#define SAA7134_IRQ2_INTE_GPIO18 (1 << 12)
114#define SAA7134_IRQ2_INTE_GPIO16 (1 << 11) /* not certain */
115#define SAA7134_IRQ2_INTE_SC2 (1 << 10)
116#define SAA7134_IRQ2_INTE_SC1 (1 << 9)
117#define SAA7134_IRQ2_INTE_SC0 (1 << 8)
118#define SAA7134_IRQ2_INTE_DEC5 (1 << 7)
119#define SAA7134_IRQ2_INTE_DEC4 (1 << 6)
120#define SAA7134_IRQ2_INTE_DEC3 (1 << 5)
121#define SAA7134_IRQ2_INTE_DEC2 (1 << 4)
122#define SAA7134_IRQ2_INTE_DEC1 (1 << 3)
123#define SAA7134_IRQ2_INTE_DEC0 (1 << 2)
124#define SAA7134_IRQ2_INTE_PE (1 << 1)
125#define SAA7134_IRQ2_INTE_AR (1 << 0)
126
127#define SAA7134_IRQ_REPORT (0x2cc >> 2)
128#define SAA7134_IRQ_REPORT_GPIO23 (1 << 17)
129#define SAA7134_IRQ_REPORT_GPIO22 (1 << 16)
130#define SAA7134_IRQ_REPORT_GPIO18 (1 << 15)
131#define SAA7134_IRQ_REPORT_GPIO16 (1 << 14) /* not certain */
132#define SAA7134_IRQ_REPORT_LOAD_ERR (1 << 13)
133#define SAA7134_IRQ_REPORT_CONF_ERR (1 << 12)
134#define SAA7134_IRQ_REPORT_TRIG_ERR (1 << 11)
135#define SAA7134_IRQ_REPORT_MMC (1 << 10)
136#define SAA7134_IRQ_REPORT_FIDT (1 << 9)
137#define SAA7134_IRQ_REPORT_INTL (1 << 8)
138#define SAA7134_IRQ_REPORT_RDCAP (1 << 7)
139#define SAA7134_IRQ_REPORT_PWR_ON (1 << 6)
140#define SAA7134_IRQ_REPORT_PE (1 << 5)
141#define SAA7134_IRQ_REPORT_AR (1 << 4)
142#define SAA7134_IRQ_REPORT_DONE_RA3 (1 << 3)
143#define SAA7134_IRQ_REPORT_DONE_RA2 (1 << 2)
144#define SAA7134_IRQ_REPORT_DONE_RA1 (1 << 1)
145#define SAA7134_IRQ_REPORT_DONE_RA0 (1 << 0)
146#define SAA7134_IRQ_STATUS (0x2d0 >> 2)
147
148
149/* ------------------------------------------------------------------ */
150/*
151 * registers -- 8 bit
152 */
153
154/* video decoder */
155#define SAA7134_INCR_DELAY 0x101
156#define SAA7134_ANALOG_IN_CTRL1 0x102
157#define SAA7134_ANALOG_IN_CTRL2 0x103
158#define SAA7134_ANALOG_IN_CTRL3 0x104
159#define SAA7134_ANALOG_IN_CTRL4 0x105
160#define SAA7134_HSYNC_START 0x106
161#define SAA7134_HSYNC_STOP 0x107
162#define SAA7134_SYNC_CTRL 0x108
163#define SAA7134_LUMA_CTRL 0x109
164#define SAA7134_DEC_LUMA_BRIGHT 0x10a
165#define SAA7134_DEC_LUMA_CONTRAST 0x10b
166#define SAA7134_DEC_CHROMA_SATURATION 0x10c
167#define SAA7134_DEC_CHROMA_HUE 0x10d
168#define SAA7134_CHROMA_CTRL1 0x10e
169#define SAA7134_CHROMA_GAIN 0x10f
170#define SAA7134_CHROMA_CTRL2 0x110
171#define SAA7134_MODE_DELAY_CTRL 0x111
172
173#define SAA7134_ANALOG_ADC 0x114
174#define SAA7134_VGATE_START 0x115
175#define SAA7134_VGATE_STOP 0x116
176#define SAA7134_MISC_VGATE_MSB 0x117
177#define SAA7134_RAW_DATA_GAIN 0x118
178#define SAA7134_RAW_DATA_OFFSET 0x119
179#define SAA7134_STATUS_VIDEO1 0x11e
180#define SAA7134_STATUS_VIDEO2 0x11f
181
182/* video scaler */
183#define SAA7134_SOURCE_TIMING1 0x000
184#define SAA7134_SOURCE_TIMING2 0x001
185#define SAA7134_REGION_ENABLE 0x004
186#define SAA7134_SCALER_STATUS0 0x006
187#define SAA7134_SCALER_STATUS1 0x007
188#define SAA7134_START_GREEN 0x00c
189#define SAA7134_START_BLUE 0x00d
190#define SAA7134_START_RED 0x00e
191#define SAA7134_GREEN_PATH(x) (0x010 +x)
192#define SAA7134_BLUE_PATH(x) (0x020 +x)
193#define SAA7134_RED_PATH(x) (0x030 +x)
194
195#define TASK_A 0x040
196#define TASK_B 0x080
197#define SAA7134_TASK_CONDITIONS(t) (0x000 +t)
198#define SAA7134_FIELD_HANDLING(t) (0x001 +t)
199#define SAA7134_DATA_PATH(t) (0x002 +t)
200#define SAA7134_VBI_H_START1(t) (0x004 +t)
201#define SAA7134_VBI_H_START2(t) (0x005 +t)
202#define SAA7134_VBI_H_STOP1(t) (0x006 +t)
203#define SAA7134_VBI_H_STOP2(t) (0x007 +t)
204#define SAA7134_VBI_V_START1(t) (0x008 +t)
205#define SAA7134_VBI_V_START2(t) (0x009 +t)
206#define SAA7134_VBI_V_STOP1(t) (0x00a +t)
207#define SAA7134_VBI_V_STOP2(t) (0x00b +t)
208#define SAA7134_VBI_H_LEN1(t) (0x00c +t)
209#define SAA7134_VBI_H_LEN2(t) (0x00d +t)
210#define SAA7134_VBI_V_LEN1(t) (0x00e +t)
211#define SAA7134_VBI_V_LEN2(t) (0x00f +t)
212
213#define SAA7134_VIDEO_H_START1(t) (0x014 +t)
214#define SAA7134_VIDEO_H_START2(t) (0x015 +t)
215#define SAA7134_VIDEO_H_STOP1(t) (0x016 +t)
216#define SAA7134_VIDEO_H_STOP2(t) (0x017 +t)
217#define SAA7134_VIDEO_V_START1(t) (0x018 +t)
218#define SAA7134_VIDEO_V_START2(t) (0x019 +t)
219#define SAA7134_VIDEO_V_STOP1(t) (0x01a +t)
220#define SAA7134_VIDEO_V_STOP2(t) (0x01b +t)
221#define SAA7134_VIDEO_PIXELS1(t) (0x01c +t)
222#define SAA7134_VIDEO_PIXELS2(t) (0x01d +t)
223#define SAA7134_VIDEO_LINES1(t) (0x01e +t)
224#define SAA7134_VIDEO_LINES2(t) (0x01f +t)
225
226#define SAA7134_H_PRESCALE(t) (0x020 +t)
227#define SAA7134_ACC_LENGTH(t) (0x021 +t)
228#define SAA7134_LEVEL_CTRL(t) (0x022 +t)
229#define SAA7134_FIR_PREFILTER_CTRL(t) (0x023 +t)
230#define SAA7134_LUMA_BRIGHT(t) (0x024 +t)
231#define SAA7134_LUMA_CONTRAST(t) (0x025 +t)
232#define SAA7134_CHROMA_SATURATION(t) (0x026 +t)
233#define SAA7134_VBI_H_SCALE_INC1(t) (0x028 +t)
234#define SAA7134_VBI_H_SCALE_INC2(t) (0x029 +t)
235#define SAA7134_VBI_PHASE_OFFSET_LUMA(t) (0x02a +t)
236#define SAA7134_VBI_PHASE_OFFSET_CHROMA(t) (0x02b +t)
237#define SAA7134_H_SCALE_INC1(t) (0x02c +t)
238#define SAA7134_H_SCALE_INC2(t) (0x02d +t)
239#define SAA7134_H_PHASE_OFF_LUMA(t) (0x02e +t)
240#define SAA7134_H_PHASE_OFF_CHROMA(t) (0x02f +t)
241#define SAA7134_V_SCALE_RATIO1(t) (0x030 +t)
242#define SAA7134_V_SCALE_RATIO2(t) (0x031 +t)
243#define SAA7134_V_FILTER(t) (0x032 +t)
244#define SAA7134_V_PHASE_OFFSET0(t) (0x034 +t)
245#define SAA7134_V_PHASE_OFFSET1(t) (0x035 +t)
246#define SAA7134_V_PHASE_OFFSET2(t) (0x036 +t)
247#define SAA7134_V_PHASE_OFFSET3(t) (0x037 +t)
248
249/* clipping & dma */
250#define SAA7134_OFMT_VIDEO_A 0x300
251#define SAA7134_OFMT_DATA_A 0x301
252#define SAA7134_OFMT_VIDEO_B 0x302
253#define SAA7134_OFMT_DATA_B 0x303
254#define SAA7134_ALPHA_NOCLIP 0x304
255#define SAA7134_ALPHA_CLIP 0x305
256#define SAA7134_UV_PIXEL 0x308
257#define SAA7134_CLIP_RED 0x309
258#define SAA7134_CLIP_GREEN 0x30a
259#define SAA7134_CLIP_BLUE 0x30b
260
261/* i2c bus */
262#define SAA7134_I2C_ATTR_STATUS 0x180
263#define SAA7134_I2C_DATA 0x181
264#define SAA7134_I2C_CLOCK_SELECT 0x182
265#define SAA7134_I2C_TIMER 0x183
266
267/* audio */
268#define SAA7134_NICAM_ADD_DATA1 0x140
269#define SAA7134_NICAM_ADD_DATA2 0x141
270#define SAA7134_NICAM_STATUS 0x142
271#define SAA7134_AUDIO_STATUS 0x143
272#define SAA7134_NICAM_ERROR_COUNT 0x144
273#define SAA7134_IDENT_SIF 0x145
274#define SAA7134_LEVEL_READOUT1 0x146
275#define SAA7134_LEVEL_READOUT2 0x147
276#define SAA7134_NICAM_ERROR_LOW 0x148
277#define SAA7134_NICAM_ERROR_HIGH 0x149
278#define SAA7134_DCXO_IDENT_CTRL 0x14a
279#define SAA7134_DEMODULATOR 0x14b
280#define SAA7134_AGC_GAIN_SELECT 0x14c
281#define SAA7134_CARRIER1_FREQ0 0x150
282#define SAA7134_CARRIER1_FREQ1 0x151
283#define SAA7134_CARRIER1_FREQ2 0x152
284#define SAA7134_CARRIER2_FREQ0 0x154
285#define SAA7134_CARRIER2_FREQ1 0x155
286#define SAA7134_CARRIER2_FREQ2 0x156
287#define SAA7134_NUM_SAMPLES0 0x158
288#define SAA7134_NUM_SAMPLES1 0x159
289#define SAA7134_NUM_SAMPLES2 0x15a
290#define SAA7134_AUDIO_FORMAT_CTRL 0x15b
291#define SAA7134_MONITOR_SELECT 0x160
292#define SAA7134_FM_DEEMPHASIS 0x161
293#define SAA7134_FM_DEMATRIX 0x162
294#define SAA7134_CHANNEL1_LEVEL 0x163
295#define SAA7134_CHANNEL2_LEVEL 0x164
296#define SAA7134_NICAM_CONFIG 0x165
297#define SAA7134_NICAM_LEVEL_ADJUST 0x166
298#define SAA7134_STEREO_DAC_OUTPUT_SELECT 0x167
299#define SAA7134_I2S_OUTPUT_FORMAT 0x168
300#define SAA7134_I2S_OUTPUT_SELECT 0x169
301#define SAA7134_I2S_OUTPUT_LEVEL 0x16a
302#define SAA7134_DSP_OUTPUT_SELECT 0x16b
303#define SAA7134_AUDIO_MUTE_CTRL 0x16c
304#define SAA7134_SIF_SAMPLE_FREQ 0x16d
305#define SAA7134_ANALOG_IO_SELECT 0x16e
306#define SAA7134_AUDIO_CLOCK0 0x170
307#define SAA7134_AUDIO_CLOCK1 0x171
308#define SAA7134_AUDIO_CLOCK2 0x172
309#define SAA7134_AUDIO_PLL_CTRL 0x173
310#define SAA7134_AUDIO_CLOCKS_PER_FIELD0 0x174
311#define SAA7134_AUDIO_CLOCKS_PER_FIELD1 0x175
312#define SAA7134_AUDIO_CLOCKS_PER_FIELD2 0x176
313
314/* video port output */
315#define SAA7134_VIDEO_PORT_CTRL0 0x190
316#define SAA7134_VIDEO_PORT_CTRL1 0x191
317#define SAA7134_VIDEO_PORT_CTRL2 0x192
318#define SAA7134_VIDEO_PORT_CTRL3 0x193
319#define SAA7134_VIDEO_PORT_CTRL4 0x194
320#define SAA7134_VIDEO_PORT_CTRL5 0x195
321#define SAA7134_VIDEO_PORT_CTRL6 0x196
322#define SAA7134_VIDEO_PORT_CTRL7 0x197
323#define SAA7134_VIDEO_PORT_CTRL8 0x198
324
325/* transport stream interface */
326#define SAA7134_TS_PARALLEL 0x1a0
327#define SAA7134_TS_PARALLEL_SERIAL 0x1a1
328#define SAA7134_TS_SERIAL0 0x1a2
329#define SAA7134_TS_SERIAL1 0x1a3
330#define SAA7134_TS_DMA0 0x1a4
331#define SAA7134_TS_DMA1 0x1a5
332#define SAA7134_TS_DMA2 0x1a6
333
334/* GPIO Controls */
335#define SAA7134_GPIO_GPRESCAN 0x80
336#define SAA7134_GPIO_27_25 0x0E
337
338#define SAA7134_GPIO_GPMODE0 0x1B0
339#define SAA7134_GPIO_GPMODE1 0x1B1
340#define SAA7134_GPIO_GPMODE2 0x1B2
341#define SAA7134_GPIO_GPMODE3 0x1B3
342#define SAA7134_GPIO_GPSTATUS0 0x1B4
343#define SAA7134_GPIO_GPSTATUS1 0x1B5
344#define SAA7134_GPIO_GPSTATUS2 0x1B6
345#define SAA7134_GPIO_GPSTATUS3 0x1B7
346
347/* I2S output */
348#define SAA7134_I2S_AUDIO_OUTPUT 0x1c0
349
350/* test modes */
351#define SAA7134_SPECIAL_MODE 0x1d0
352
353/* audio -- saa7133 + saa7135 only */
354#define SAA7135_DSP_RWSTATE 0x580
355#define SAA7135_DSP_RWSTATE_ERR (1 << 3)
356#define SAA7135_DSP_RWSTATE_IDA (1 << 2)
357#define SAA7135_DSP_RWSTATE_RDB (1 << 1)
358#define SAA7135_DSP_RWSTATE_WRR (1 << 0)
359
360/* ------------------------------------------------------------------ */
361/*
362 * Local variables:
363 * c-basic-offset: 8
364 * End:
365 */
366
diff --git a/drivers/media/video/saa7134/saa7134-ts.c b/drivers/media/video/saa7134/saa7134-ts.c
new file mode 100644
index 000000000000..345eb2a8c28d
--- /dev/null
+++ b/drivers/media/video/saa7134/saa7134-ts.c
@@ -0,0 +1,243 @@
1/*
2 * $Id: saa7134-ts.c,v 1.14 2005/02/03 10:24:33 kraxel Exp $
3 *
4 * device driver for philips saa7134 based TV cards
5 * video4linux video interface
6 *
7 * (c) 2001,02 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include <linux/init.h>
25#include <linux/list.h>
26#include <linux/module.h>
27#include <linux/moduleparam.h>
28#include <linux/kernel.h>
29#include <linux/slab.h>
30#include <linux/delay.h>
31
32#include "saa7134-reg.h"
33#include "saa7134.h"
34
35/* ------------------------------------------------------------------ */
36
37static unsigned int ts_debug = 0;
38module_param(ts_debug, int, 0644);
39MODULE_PARM_DESC(ts_debug,"enable debug messages [ts]");
40
41#define dprintk(fmt, arg...) if (ts_debug) \
42 printk(KERN_DEBUG "%s/ts: " fmt, dev->name , ## arg)
43
44/* ------------------------------------------------------------------ */
45
46static int buffer_activate(struct saa7134_dev *dev,
47 struct saa7134_buf *buf,
48 struct saa7134_buf *next)
49{
50 u32 control;
51
52 dprintk("buffer_activate [%p]",buf);
53 buf->vb.state = STATE_ACTIVE;
54 buf->top_seen = 0;
55
56 /* dma: setup channel 5 (= TS) */
57 control = SAA7134_RS_CONTROL_BURST_16 |
58 SAA7134_RS_CONTROL_ME |
59 (buf->pt->dma >> 12);
60
61 if (NULL == next)
62 next = buf;
63 if (V4L2_FIELD_TOP == buf->vb.field) {
64 dprintk("- [top] buf=%p next=%p\n",buf,next);
65 saa_writel(SAA7134_RS_BA1(5),saa7134_buffer_base(buf));
66 saa_writel(SAA7134_RS_BA2(5),saa7134_buffer_base(next));
67 } else {
68 dprintk("- [bottom] buf=%p next=%p\n",buf,next);
69 saa_writel(SAA7134_RS_BA1(5),saa7134_buffer_base(next));
70 saa_writel(SAA7134_RS_BA2(5),saa7134_buffer_base(buf));
71 }
72 saa_writel(SAA7134_RS_PITCH(5),TS_PACKET_SIZE);
73 saa_writel(SAA7134_RS_CONTROL(5),control);
74
75 /* start DMA */
76 saa7134_set_dmabits(dev);
77
78 mod_timer(&dev->ts_q.timeout, jiffies+BUFFER_TIMEOUT);
79 return 0;
80}
81
82static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
83 enum v4l2_field field)
84{
85 struct saa7134_dev *dev = q->priv_data;
86 struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb);
87 unsigned int lines, llength, size;
88 int err;
89
90 dprintk("buffer_prepare [%p,%s]\n",buf,v4l2_field_names[field]);
91
92 llength = TS_PACKET_SIZE;
93 lines = dev->ts.nr_packets;
94
95 size = lines * llength;
96 if (0 != buf->vb.baddr && buf->vb.bsize < size)
97 return -EINVAL;
98
99 if (buf->vb.size != size) {
100 saa7134_dma_free(dev,buf);
101 }
102
103 if (STATE_NEEDS_INIT == buf->vb.state) {
104 buf->vb.width = llength;
105 buf->vb.height = lines;
106 buf->vb.size = size;
107 buf->pt = &dev->ts.pt_ts;
108
109 err = videobuf_iolock(dev->pci,&buf->vb,NULL);
110 if (err)
111 goto oops;
112 err = saa7134_pgtable_build(dev->pci,buf->pt,
113 buf->vb.dma.sglist,
114 buf->vb.dma.sglen,
115 saa7134_buffer_startpage(buf));
116 if (err)
117 goto oops;
118 }
119 buf->vb.state = STATE_PREPARED;
120 buf->activate = buffer_activate;
121 buf->vb.field = field;
122 return 0;
123
124 oops:
125 saa7134_dma_free(dev,buf);
126 return err;
127}
128
129static int
130buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
131{
132 struct saa7134_dev *dev = q->priv_data;
133
134 *size = TS_PACKET_SIZE * dev->ts.nr_packets;
135 if (0 == *count)
136 *count = dev->ts.nr_bufs;
137 *count = saa7134_buffer_count(*size,*count);
138 return 0;
139}
140
141static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
142{
143 struct saa7134_dev *dev = q->priv_data;
144 struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb);
145
146 saa7134_buffer_queue(dev,&dev->ts_q,buf);
147}
148
149static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
150{
151 struct saa7134_dev *dev = q->priv_data;
152 struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb);
153
154 saa7134_dma_free(dev,buf);
155}
156
157struct videobuf_queue_ops saa7134_ts_qops = {
158 .buf_setup = buffer_setup,
159 .buf_prepare = buffer_prepare,
160 .buf_queue = buffer_queue,
161 .buf_release = buffer_release,
162};
163EXPORT_SYMBOL_GPL(saa7134_ts_qops);
164
165/* ----------------------------------------------------------- */
166/* exported stuff */
167
168static unsigned int tsbufs = 4;
169module_param(tsbufs, int, 0444);
170MODULE_PARM_DESC(tsbufs,"number of ts buffers, range 2-32");
171
172static unsigned int ts_nr_packets = 30;
173module_param(ts_nr_packets, int, 0444);
174MODULE_PARM_DESC(ts_nr_packets,"size of a ts buffers (in ts packets)");
175
176int saa7134_ts_init1(struct saa7134_dev *dev)
177{
178 /* sanitycheck insmod options */
179 if (tsbufs < 2)
180 tsbufs = 2;
181 if (tsbufs > VIDEO_MAX_FRAME)
182 tsbufs = VIDEO_MAX_FRAME;
183 if (ts_nr_packets < 4)
184 ts_nr_packets = 4;
185 if (ts_nr_packets > 312)
186 ts_nr_packets = 312;
187 dev->ts.nr_bufs = tsbufs;
188 dev->ts.nr_packets = ts_nr_packets;
189
190 INIT_LIST_HEAD(&dev->ts_q.queue);
191 init_timer(&dev->ts_q.timeout);
192 dev->ts_q.timeout.function = saa7134_buffer_timeout;
193 dev->ts_q.timeout.data = (unsigned long)(&dev->ts_q);
194 dev->ts_q.dev = dev;
195 dev->ts_q.need_two = 1;
196 saa7134_pgtable_alloc(dev->pci,&dev->ts.pt_ts);
197
198 /* init TS hw */
199 saa_writeb(SAA7134_TS_SERIAL1, 0x00); /* deactivate TS softreset */
200 saa_writeb(SAA7134_TS_PARALLEL, 0xec); /* TSSOP high active, TSVAL high active, TSLOCK ignored */
201 saa_writeb(SAA7134_TS_PARALLEL_SERIAL, (TS_PACKET_SIZE-1));
202 saa_writeb(SAA7134_TS_DMA0, ((dev->ts.nr_packets-1)&0xff));
203 saa_writeb(SAA7134_TS_DMA1, (((dev->ts.nr_packets-1)>>8)&0xff));
204 saa_writeb(SAA7134_TS_DMA2, ((((dev->ts.nr_packets-1)>>16)&0x3f) | 0x00)); /* TSNOPIT=0, TSCOLAP=0 */
205
206 return 0;
207}
208
209int saa7134_ts_fini(struct saa7134_dev *dev)
210{
211 saa7134_pgtable_free(dev->pci,&dev->ts.pt_ts);
212 return 0;
213}
214
215
216void saa7134_irq_ts_done(struct saa7134_dev *dev, unsigned long status)
217{
218 enum v4l2_field field;
219
220 spin_lock(&dev->slock);
221 if (dev->ts_q.curr) {
222 field = dev->ts_q.curr->vb.field;
223 if (field == V4L2_FIELD_TOP) {
224 if ((status & 0x100000) != 0x000000)
225 goto done;
226 } else {
227 if ((status & 0x100000) != 0x100000)
228 goto done;
229 }
230 saa7134_buffer_finish(dev,&dev->ts_q,STATE_DONE);
231 }
232 saa7134_buffer_next(dev,&dev->ts_q);
233
234 done:
235 spin_unlock(&dev->slock);
236}
237
238/* ----------------------------------------------------------- */
239/*
240 * Local variables:
241 * c-basic-offset: 8
242 * End:
243 */
diff --git a/drivers/media/video/saa7134/saa7134-tvaudio.c b/drivers/media/video/saa7134/saa7134-tvaudio.c
new file mode 100644
index 000000000000..ecac13c006d5
--- /dev/null
+++ b/drivers/media/video/saa7134/saa7134-tvaudio.c
@@ -0,0 +1,1031 @@
1/*
2 * $Id: saa7134-tvaudio.c,v 1.22 2005/01/07 13:11:19 kraxel Exp $
3 *
4 * device driver for philips saa7134 based TV cards
5 * tv audio decoder (fm stereo, nicam, ...)
6 *
7 * (c) 2001-03 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include <linux/init.h>
25#include <linux/list.h>
26#include <linux/module.h>
27#include <linux/moduleparam.h>
28#include <linux/kernel.h>
29#include <linux/slab.h>
30#include <linux/delay.h>
31#include <linux/smp_lock.h>
32#include <asm/div64.h>
33
34#include "saa7134-reg.h"
35#include "saa7134.h"
36
37/* ------------------------------------------------------------------ */
38
39static unsigned int audio_debug = 0;
40module_param(audio_debug, int, 0644);
41MODULE_PARM_DESC(audio_debug,"enable debug messages [tv audio]");
42
43static unsigned int audio_ddep = 0;
44module_param(audio_ddep, int, 0644);
45MODULE_PARM_DESC(audio_ddep,"audio ddep overwrite");
46
47static int audio_clock_override = UNSET;
48module_param(audio_clock_override, int, 0644);
49
50static int audio_clock_tweak = 0;
51module_param(audio_clock_tweak, int, 0644);
52MODULE_PARM_DESC(audio_clock_tweak, "Audio clock tick fine tuning for cards with audio crystal that's slightly off (range [-1024 .. 1024])");
53
54#define dprintk(fmt, arg...) if (audio_debug) \
55 printk(KERN_DEBUG "%s/audio: " fmt, dev->name , ## arg)
56#define d2printk(fmt, arg...) if (audio_debug > 1) \
57 printk(KERN_DEBUG "%s/audio: " fmt, dev->name, ## arg)
58
59#define print_regb(reg) printk("%s: reg 0x%03x [%-16s]: 0x%02x\n", \
60 dev->name,(SAA7134_##reg),(#reg),saa_readb((SAA7134_##reg)))
61
62/* msecs */
63#define SCAN_INITIAL_DELAY 1000
64#define SCAN_SAMPLE_DELAY 200
65#define SCAN_SUBCARRIER_DELAY 2000
66
67/* ------------------------------------------------------------------ */
68/* saa7134 code */
69
70static struct mainscan {
71 char *name;
72 v4l2_std_id std;
73 int carr;
74} mainscan[] = {
75 {
76 .name = "M",
77 .std = V4L2_STD_NTSC | V4L2_STD_PAL_M,
78 .carr = 4500,
79 },{
80 .name = "BG",
81 .std = V4L2_STD_PAL_BG,
82 .carr = 5500,
83 },{
84 .name = "I",
85 .std = V4L2_STD_PAL_I,
86 .carr = 6000,
87 },{
88 .name = "DKL",
89 .std = V4L2_STD_PAL_DK | V4L2_STD_SECAM,
90 .carr = 6500,
91 }
92};
93
94static struct saa7134_tvaudio tvaudio[] = {
95 {
96 .name = "PAL-B/G FM-stereo",
97 .std = V4L2_STD_PAL,
98 .mode = TVAUDIO_FM_BG_STEREO,
99 .carr1 = 5500,
100 .carr2 = 5742,
101 },{
102 .name = "PAL-D/K1 FM-stereo",
103 .std = V4L2_STD_PAL,
104 .carr1 = 6500,
105 .carr2 = 6258,
106 .mode = TVAUDIO_FM_BG_STEREO,
107 },{
108 .name = "PAL-D/K2 FM-stereo",
109 .std = V4L2_STD_PAL,
110 .carr1 = 6500,
111 .carr2 = 6742,
112 .mode = TVAUDIO_FM_BG_STEREO,
113 },{
114 .name = "PAL-D/K3 FM-stereo",
115 .std = V4L2_STD_PAL,
116 .carr1 = 6500,
117 .carr2 = 5742,
118 .mode = TVAUDIO_FM_BG_STEREO,
119 },{
120 .name = "PAL-B/G NICAM",
121 .std = V4L2_STD_PAL,
122 .carr1 = 5500,
123 .carr2 = 5850,
124 .mode = TVAUDIO_NICAM_FM,
125 },{
126 .name = "PAL-I NICAM",
127 .std = V4L2_STD_PAL,
128 .carr1 = 6000,
129 .carr2 = 6552,
130 .mode = TVAUDIO_NICAM_FM,
131 },{
132 .name = "PAL-D/K NICAM",
133 .std = V4L2_STD_PAL,
134 .carr1 = 6500,
135 .carr2 = 5850,
136 .mode = TVAUDIO_NICAM_FM,
137 },{
138 .name = "SECAM-L NICAM",
139 .std = V4L2_STD_SECAM,
140 .carr1 = 6500,
141 .carr2 = 5850,
142 .mode = TVAUDIO_NICAM_AM,
143 },{
144 .name = "SECAM-D/K",
145 .std = V4L2_STD_SECAM,
146 .carr1 = 6500,
147 .carr2 = -1,
148 .mode = TVAUDIO_FM_MONO,
149 },{
150 .name = "NTSC-M",
151 .std = V4L2_STD_NTSC,
152 .carr1 = 4500,
153 .carr2 = -1,
154 .mode = TVAUDIO_FM_MONO,
155 },{
156 .name = "NTSC-A2 FM-stereo",
157 .std = V4L2_STD_NTSC,
158 .carr1 = 4500,
159 .carr2 = 4724,
160 .mode = TVAUDIO_FM_K_STEREO,
161 }
162};
163#define TVAUDIO (sizeof(tvaudio)/sizeof(struct saa7134_tvaudio))
164
165/* ------------------------------------------------------------------ */
166
167static void tvaudio_init(struct saa7134_dev *dev)
168{
169 int clock = saa7134_boards[dev->board].audio_clock;
170
171 if (UNSET != audio_clock_override)
172 clock = audio_clock_override;
173
174 /* init all audio registers */
175 saa_writeb(SAA7134_AUDIO_PLL_CTRL, 0x00);
176 if (need_resched())
177 schedule();
178 else
179 udelay(10);
180
181 saa_writeb(SAA7134_AUDIO_CLOCK0, clock & 0xff);
182 saa_writeb(SAA7134_AUDIO_CLOCK1, (clock >> 8) & 0xff);
183 saa_writeb(SAA7134_AUDIO_CLOCK2, (clock >> 16) & 0xff);
184 saa_writeb(SAA7134_AUDIO_PLL_CTRL, 0x01);
185
186 saa_writeb(SAA7134_NICAM_ERROR_LOW, 0x14);
187 saa_writeb(SAA7134_NICAM_ERROR_HIGH, 0x50);
188 saa_writeb(SAA7134_MONITOR_SELECT, 0xa0);
189 saa_writeb(SAA7134_FM_DEMATRIX, 0x80);
190}
191
192static u32 tvaudio_carr2reg(u32 carrier)
193{
194 u64 a = carrier;
195
196 a <<= 24;
197 do_div(a,12288);
198 return a;
199}
200
201static void tvaudio_setcarrier(struct saa7134_dev *dev,
202 int primary, int secondary)
203{
204 if (-1 == secondary)
205 secondary = primary;
206 saa_writel(SAA7134_CARRIER1_FREQ0 >> 2, tvaudio_carr2reg(primary));
207 saa_writel(SAA7134_CARRIER2_FREQ0 >> 2, tvaudio_carr2reg(secondary));
208}
209
210static void mute_input_7134(struct saa7134_dev *dev)
211{
212 unsigned int mute;
213 struct saa7134_input *in;
214 int ausel=0, ics=0, ocs=0;
215 int mask;
216
217 /* look what is to do ... */
218 in = dev->input;
219 mute = (dev->ctl_mute ||
220 (dev->automute && (&card(dev).radio) != in));
221 if (PCI_DEVICE_ID_PHILIPS_SAA7130 == dev->pci->device &&
222 card(dev).mute.name) {
223 /* 7130 - we'll mute using some unconnected audio input */
224 if (mute)
225 in = &card(dev).mute;
226 }
227 if (dev->hw_mute == mute &&
228 dev->hw_input == in) {
229 dprintk("mute/input: nothing to do [mute=%d,input=%s]\n",
230 mute,in->name);
231 return;
232 }
233
234 dprintk("ctl_mute=%d automute=%d input=%s => mute=%d input=%s\n",
235 dev->ctl_mute,dev->automute,dev->input->name,mute,in->name);
236 dev->hw_mute = mute;
237 dev->hw_input = in;
238
239 if (PCI_DEVICE_ID_PHILIPS_SAA7134 == dev->pci->device)
240 /* 7134 mute */
241 saa_writeb(SAA7134_AUDIO_MUTE_CTRL, mute ? 0xbf : 0xbb);
242
243 /* switch internal audio mux */
244 switch (in->amux) {
245 case TV: ausel=0xc0; ics=0x00; ocs=0x02; break;
246 case LINE1: ausel=0x80; ics=0x00; ocs=0x00; break;
247 case LINE2: ausel=0x80; ics=0x08; ocs=0x01; break;
248 case LINE2_LEFT: ausel=0x80; ics=0x08; ocs=0x05; break;
249 }
250 saa_andorb(SAA7134_AUDIO_FORMAT_CTRL, 0xc0, ausel);
251 saa_andorb(SAA7134_ANALOG_IO_SELECT, 0x08, ics);
252 saa_andorb(SAA7134_ANALOG_IO_SELECT, 0x07, ocs);
253
254 /* switch gpio-connected external audio mux */
255 if (0 == card(dev).gpiomask)
256 return;
257 mask = card(dev).gpiomask;
258 saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, mask, mask);
259 saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, mask, in->gpio);
260 saa7134_track_gpio(dev,in->name);
261}
262
263static void tvaudio_setmode(struct saa7134_dev *dev,
264 struct saa7134_tvaudio *audio,
265 char *note)
266{
267 int acpf, tweak = 0;
268
269 if (dev->tvnorm->id == V4L2_STD_NTSC) {
270 acpf = 0x19066;
271 } else {
272 acpf = 0x1e000;
273 }
274 if (audio_clock_tweak > -1024 && audio_clock_tweak < 1024)
275 tweak = audio_clock_tweak;
276
277 if (note)
278 dprintk("tvaudio_setmode: %s %s [%d.%03d/%d.%03d MHz] acpf=%d%+d\n",
279 note,audio->name,
280 audio->carr1 / 1000, audio->carr1 % 1000,
281 audio->carr2 / 1000, audio->carr2 % 1000,
282 acpf, tweak);
283
284 acpf += tweak;
285 saa_writeb(SAA7134_AUDIO_CLOCKS_PER_FIELD0, (acpf & 0x0000ff) >> 0);
286 saa_writeb(SAA7134_AUDIO_CLOCKS_PER_FIELD1, (acpf & 0x00ff00) >> 8);
287 saa_writeb(SAA7134_AUDIO_CLOCKS_PER_FIELD2, (acpf & 0x030000) >> 16);
288 tvaudio_setcarrier(dev,audio->carr1,audio->carr2);
289
290 switch (audio->mode) {
291 case TVAUDIO_FM_MONO:
292 case TVAUDIO_FM_BG_STEREO:
293 saa_writeb(SAA7134_DEMODULATOR, 0x00);
294 saa_writeb(SAA7134_DCXO_IDENT_CTRL, 0x00);
295 saa_writeb(SAA7134_FM_DEEMPHASIS, 0x22);
296 saa_writeb(SAA7134_FM_DEMATRIX, 0x80);
297 saa_writeb(SAA7134_STEREO_DAC_OUTPUT_SELECT, 0xa0);
298 break;
299 case TVAUDIO_FM_K_STEREO:
300 saa_writeb(SAA7134_DEMODULATOR, 0x00);
301 saa_writeb(SAA7134_DCXO_IDENT_CTRL, 0x01);
302 saa_writeb(SAA7134_FM_DEEMPHASIS, 0x22);
303 saa_writeb(SAA7134_FM_DEMATRIX, 0x80);
304 saa_writeb(SAA7134_STEREO_DAC_OUTPUT_SELECT, 0xa0);
305 break;
306 case TVAUDIO_NICAM_FM:
307 saa_writeb(SAA7134_DEMODULATOR, 0x10);
308 saa_writeb(SAA7134_DCXO_IDENT_CTRL, 0x00);
309 saa_writeb(SAA7134_FM_DEEMPHASIS, 0x44);
310 saa_writeb(SAA7134_STEREO_DAC_OUTPUT_SELECT, 0xa1);
311 saa_writeb(SAA7134_NICAM_CONFIG, 0x00);
312 break;
313 case TVAUDIO_NICAM_AM:
314 saa_writeb(SAA7134_DEMODULATOR, 0x12);
315 saa_writeb(SAA7134_DCXO_IDENT_CTRL, 0x00);
316 saa_writeb(SAA7134_FM_DEEMPHASIS, 0x44);
317 saa_writeb(SAA7134_STEREO_DAC_OUTPUT_SELECT, 0xa1);
318 saa_writeb(SAA7134_NICAM_CONFIG, 0x00);
319 break;
320 case TVAUDIO_FM_SAT_STEREO:
321 /* not implemented (yet) */
322 break;
323 }
324}
325
326static int tvaudio_sleep(struct saa7134_dev *dev, int timeout)
327{
328 DECLARE_WAITQUEUE(wait, current);
329
330 add_wait_queue(&dev->thread.wq, &wait);
331 if (dev->thread.scan1 == dev->thread.scan2 && !dev->thread.shutdown) {
332 if (timeout < 0) {
333 set_current_state(TASK_INTERRUPTIBLE);
334 schedule();
335 } else {
336#if 0
337 /* hmm, that one doesn't return on wakeup ... */
338 msleep_interruptible(timeout);
339#else
340 set_current_state(TASK_INTERRUPTIBLE);
341 schedule_timeout(msecs_to_jiffies(timeout));
342#endif
343 }
344 }
345 remove_wait_queue(&dev->thread.wq, &wait);
346 return dev->thread.scan1 != dev->thread.scan2;
347}
348
349static int tvaudio_checkcarrier(struct saa7134_dev *dev, struct mainscan *scan)
350{
351 __s32 left,right,value;
352
353 if (audio_debug > 1) {
354 int i;
355 dprintk("debug %d:",scan->carr);
356 for (i = -150; i <= 150; i += 30) {
357 tvaudio_setcarrier(dev,scan->carr+i,scan->carr+i);
358 saa_readl(SAA7134_LEVEL_READOUT1 >> 2);
359 if (tvaudio_sleep(dev,SCAN_SAMPLE_DELAY))
360 return -1;
361 value = saa_readl(SAA7134_LEVEL_READOUT1 >> 2);
362 if (0 == i)
363 printk(" # %6d # ",value >> 16);
364 else
365 printk(" %6d",value >> 16);
366 }
367 printk("\n");
368 }
369
370 if (dev->tvnorm->id & scan->std) {
371 tvaudio_setcarrier(dev,scan->carr-90,scan->carr-90);
372 saa_readl(SAA7134_LEVEL_READOUT1 >> 2);
373 if (tvaudio_sleep(dev,SCAN_SAMPLE_DELAY))
374 return -1;
375 left = saa_readl(SAA7134_LEVEL_READOUT1 >> 2);
376
377 tvaudio_setcarrier(dev,scan->carr+90,scan->carr+90);
378 saa_readl(SAA7134_LEVEL_READOUT1 >> 2);
379 if (tvaudio_sleep(dev,SCAN_SAMPLE_DELAY))
380 return -1;
381 right = saa_readl(SAA7134_LEVEL_READOUT1 >> 2);
382
383 left >>= 16;
384 right >>= 16;
385 value = left > right ? left - right : right - left;
386 dprintk("scanning %d.%03d MHz [%4s] => dc is %5d [%d/%d]\n",
387 scan->carr / 1000, scan->carr % 1000,
388 scan->name, value, left, right);
389 } else {
390 value = 0;
391 dprintk("skipping %d.%03d MHz [%4s]\n",
392 scan->carr / 1000, scan->carr % 1000, scan->name);
393 }
394 return value;
395}
396
397#if 0
398static void sifdebug_dump_regs(struct saa7134_dev *dev)
399{
400 print_regb(AUDIO_STATUS);
401 print_regb(IDENT_SIF);
402 print_regb(LEVEL_READOUT1);
403 print_regb(LEVEL_READOUT2);
404 print_regb(DCXO_IDENT_CTRL);
405 print_regb(DEMODULATOR);
406 print_regb(AGC_GAIN_SELECT);
407 print_regb(MONITOR_SELECT);
408 print_regb(FM_DEEMPHASIS);
409 print_regb(FM_DEMATRIX);
410 print_regb(SIF_SAMPLE_FREQ);
411 print_regb(ANALOG_IO_SELECT);
412}
413#endif
414
415static int tvaudio_getstereo(struct saa7134_dev *dev, struct saa7134_tvaudio *audio)
416{
417 __u32 idp,nicam;
418 int retval = -1;
419
420 switch (audio->mode) {
421 case TVAUDIO_FM_MONO:
422 return V4L2_TUNER_SUB_MONO;
423 case TVAUDIO_FM_K_STEREO:
424 case TVAUDIO_FM_BG_STEREO:
425 idp = (saa_readb(SAA7134_IDENT_SIF) & 0xe0) >> 5;
426 dprintk("getstereo: fm/stereo: idp=0x%x\n",idp);
427 if (0x03 == (idp & 0x03))
428 retval = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
429 else if (0x05 == (idp & 0x05))
430 retval = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
431 else if (0x01 == (idp & 0x01))
432 retval = V4L2_TUNER_SUB_MONO;
433 break;
434 case TVAUDIO_FM_SAT_STEREO:
435 /* not implemented (yet) */
436 break;
437 case TVAUDIO_NICAM_FM:
438 case TVAUDIO_NICAM_AM:
439 nicam = saa_readb(SAA7134_NICAM_STATUS);
440 dprintk("getstereo: nicam=0x%x\n",nicam);
441 switch (nicam & 0x0b) {
442 case 0x09:
443 retval = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
444 break;
445 case 0x0a:
446 retval = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
447 break;
448 case 0x08:
449 default:
450 retval = V4L2_TUNER_SUB_MONO;
451 break;
452 }
453 break;
454 }
455 if (retval != -1)
456 dprintk("found audio subchannels:%s%s%s%s\n",
457 (retval & V4L2_TUNER_SUB_MONO) ? " mono" : "",
458 (retval & V4L2_TUNER_SUB_STEREO) ? " stereo" : "",
459 (retval & V4L2_TUNER_SUB_LANG1) ? " lang1" : "",
460 (retval & V4L2_TUNER_SUB_LANG2) ? " lang2" : "");
461 return retval;
462}
463
464static int tvaudio_setstereo(struct saa7134_dev *dev, struct saa7134_tvaudio *audio,
465 u32 mode)
466{
467 static char *name[] = {
468 [ V4L2_TUNER_MODE_MONO ] = "mono",
469 [ V4L2_TUNER_MODE_STEREO ] = "stereo",
470 [ V4L2_TUNER_MODE_LANG1 ] = "lang1",
471 [ V4L2_TUNER_MODE_LANG2 ] = "lang2",
472 };
473 static u32 fm[] = {
474 [ V4L2_TUNER_MODE_MONO ] = 0x00, /* ch1 */
475 [ V4L2_TUNER_MODE_STEREO ] = 0x80, /* auto */
476 [ V4L2_TUNER_MODE_LANG1 ] = 0x00, /* ch1 */
477 [ V4L2_TUNER_MODE_LANG2 ] = 0x01, /* ch2 */
478 };
479 u32 reg;
480
481 switch (audio->mode) {
482 case TVAUDIO_FM_MONO:
483 /* nothing to do ... */
484 break;
485 case TVAUDIO_FM_K_STEREO:
486 case TVAUDIO_FM_BG_STEREO:
487 dprintk("setstereo [fm] => %s\n",
488 name[ mode % ARRAY_SIZE(name) ]);
489 reg = fm[ mode % ARRAY_SIZE(fm) ];
490 saa_writeb(SAA7134_FM_DEMATRIX, reg);
491 break;
492 case TVAUDIO_FM_SAT_STEREO:
493 case TVAUDIO_NICAM_AM:
494 case TVAUDIO_NICAM_FM:
495 /* FIXME */
496 break;
497 }
498 return 0;
499}
500
501static int tvaudio_thread(void *data)
502{
503 struct saa7134_dev *dev = data;
504 int carr_vals[ARRAY_SIZE(mainscan)];
505 unsigned int i, audio, nscan;
506 int max1,max2,carrier,rx,mode,lastmode,default_carrier;
507
508 daemonize("%s", dev->name);
509 allow_signal(SIGTERM);
510 for (;;) {
511 tvaudio_sleep(dev,-1);
512 if (dev->thread.shutdown || signal_pending(current))
513 goto done;
514
515 restart:
516 dev->thread.scan1 = dev->thread.scan2;
517 dprintk("tvaudio thread scan start [%d]\n",dev->thread.scan1);
518 dev->tvaudio = NULL;
519 tvaudio_init(dev);
520 if (dev->ctl_automute)
521 dev->automute = 1;
522 mute_input_7134(dev);
523
524 /* give the tuner some time */
525 if (tvaudio_sleep(dev,SCAN_INITIAL_DELAY))
526 goto restart;
527
528 max1 = 0;
529 max2 = 0;
530 nscan = 0;
531 carrier = 0;
532 default_carrier = 0;
533 for (i = 0; i < ARRAY_SIZE(mainscan); i++) {
534 if (!(dev->tvnorm->id & mainscan[i].std))
535 continue;
536 if (!default_carrier)
537 default_carrier = mainscan[i].carr;
538 nscan++;
539 }
540
541 if (1 == nscan) {
542 /* only one candidate -- skip scan ;) */
543 max1 = 12345;
544 carrier = default_carrier;
545 } else {
546 /* scan for the main carrier */
547 saa_writeb(SAA7134_MONITOR_SELECT,0x00);
548 tvaudio_setmode(dev,&tvaudio[0],NULL);
549 for (i = 0; i < ARRAY_SIZE(mainscan); i++) {
550 carr_vals[i] = tvaudio_checkcarrier(dev, mainscan+i);
551 if (dev->thread.scan1 != dev->thread.scan2)
552 goto restart;
553 }
554 for (max1 = 0, max2 = 0, i = 0; i < ARRAY_SIZE(mainscan); i++) {
555 if (max1 < carr_vals[i]) {
556 max2 = max1;
557 max1 = carr_vals[i];
558 carrier = mainscan[i].carr;
559 } else if (max2 < carr_vals[i]) {
560 max2 = carr_vals[i];
561 }
562 }
563 }
564
565 if (0 != carrier && max1 > 2000 && max1 > max2*3) {
566 /* found good carrier */
567 dprintk("found %s main sound carrier @ %d.%03d MHz [%d/%d]\n",
568 dev->tvnorm->name, carrier/1000, carrier%1000,
569 max1, max2);
570 dev->last_carrier = carrier;
571
572 } else if (0 != dev->last_carrier) {
573 /* no carrier -- try last detected one as fallback */
574 carrier = dev->last_carrier;
575 printk(KERN_WARNING "%s/audio: audio carrier scan failed, "
576 "using %d.%03d MHz [last detected]\n",
577 dev->name, carrier/1000, carrier%1000);
578
579 } else {
580 /* no carrier + no fallback -- use default */
581 carrier = default_carrier;
582 printk(KERN_WARNING "%s/audio: audio carrier scan failed, "
583 "using %d.%03d MHz [default]\n",
584 dev->name, carrier/1000, carrier%1000);
585 }
586 tvaudio_setcarrier(dev,carrier,carrier);
587 dev->automute = 0;
588 saa_andorb(SAA7134_STEREO_DAC_OUTPUT_SELECT, 0x30, 0x00);
589 saa7134_tvaudio_setmute(dev);
590
591 /* find the exact tv audio norm */
592 for (audio = UNSET, i = 0; i < TVAUDIO; i++) {
593 if (dev->tvnorm->id != UNSET &&
594 !(dev->tvnorm->id & tvaudio[i].std))
595 continue;
596 if (tvaudio[i].carr1 != carrier)
597 continue;
598
599 if (UNSET == audio)
600 audio = i;
601 tvaudio_setmode(dev,&tvaudio[i],"trying");
602 if (tvaudio_sleep(dev,SCAN_SUBCARRIER_DELAY))
603 goto restart;
604 if (-1 != tvaudio_getstereo(dev,&tvaudio[i])) {
605 audio = i;
606 break;
607 }
608 }
609 saa_andorb(SAA7134_STEREO_DAC_OUTPUT_SELECT, 0x30, 0x30);
610 if (UNSET == audio)
611 continue;
612 tvaudio_setmode(dev,&tvaudio[audio],"using");
613 tvaudio_setstereo(dev,&tvaudio[audio],V4L2_TUNER_MODE_MONO);
614 dev->tvaudio = &tvaudio[audio];
615
616 lastmode = 42;
617 for (;;) {
618 if (tvaudio_sleep(dev,5000))
619 goto restart;
620 if (dev->thread.shutdown || signal_pending(current))
621 break;
622 if (UNSET == dev->thread.mode) {
623 rx = tvaudio_getstereo(dev,&tvaudio[i]);
624 mode = saa7134_tvaudio_rx2mode(rx);
625 } else {
626 mode = dev->thread.mode;
627 }
628 if (lastmode != mode) {
629 tvaudio_setstereo(dev,&tvaudio[audio],mode);
630 lastmode = mode;
631 }
632 }
633 }
634
635 done:
636 complete_and_exit(&dev->thread.exit, 0);
637 return 0;
638}
639
640/* ------------------------------------------------------------------ */
641/* saa7133 / saa7135 code */
642
643static char *stdres[0x20] = {
644 [0x00] = "no standard detected",
645 [0x01] = "B/G (in progress)",
646 [0x02] = "D/K (in progress)",
647 [0x03] = "M (in progress)",
648
649 [0x04] = "B/G A2",
650 [0x05] = "B/G NICAM",
651 [0x06] = "D/K A2 (1)",
652 [0x07] = "D/K A2 (2)",
653 [0x08] = "D/K A2 (3)",
654 [0x09] = "D/K NICAM",
655 [0x0a] = "L NICAM",
656 [0x0b] = "I NICAM",
657
658 [0x0c] = "M Korea",
659 [0x0d] = "M BTSC ",
660 [0x0e] = "M EIAJ",
661
662 [0x0f] = "FM radio / IF 10.7 / 50 deemp",
663 [0x10] = "FM radio / IF 10.7 / 75 deemp",
664 [0x11] = "FM radio / IF sel / 50 deemp",
665 [0x12] = "FM radio / IF sel / 75 deemp",
666
667 [0x13 ... 0x1e ] = "unknown",
668 [0x1f] = "??? [in progress]",
669};
670
671#define DSP_RETRY 32
672#define DSP_DELAY 16
673
674static inline int saa_dsp_wait_bit(struct saa7134_dev *dev, int bit)
675{
676 int state, count = DSP_RETRY;
677
678 state = saa_readb(SAA7135_DSP_RWSTATE);
679 if (unlikely(state & SAA7135_DSP_RWSTATE_ERR)) {
680 printk("%s: dsp access error\n",dev->name);
681 /* FIXME: send ack ... */
682 return -EIO;
683 }
684 while (0 == (state & bit)) {
685 if (unlikely(0 == count)) {
686 printk("%s: dsp access wait timeout [bit=%s]\n",
687 dev->name,
688 (bit & SAA7135_DSP_RWSTATE_WRR) ? "WRR" :
689 (bit & SAA7135_DSP_RWSTATE_RDB) ? "RDB" :
690 (bit & SAA7135_DSP_RWSTATE_IDA) ? "IDA" :
691 "???");
692 return -EIO;
693 }
694 saa_wait(DSP_DELAY);
695 state = saa_readb(SAA7135_DSP_RWSTATE);
696 count--;
697 }
698 return 0;
699}
700
701#if 0
702static int saa_dsp_readl(struct saa7134_dev *dev, int reg, u32 *value)
703{
704 int err;
705
706 d2printk("dsp read reg 0x%x\n", reg<<2);
707 saa_readl(reg);
708 err = saa_dsp_wait_bit(dev,SAA7135_DSP_RWSTATE_RDB);
709 if (err < 0)
710 return err;
711 *value = saa_readl(reg);
712 d2printk("dsp read => 0x%06x\n", *value & 0xffffff);
713 err = saa_dsp_wait_bit(dev,SAA7135_DSP_RWSTATE_IDA);
714 if (err < 0)
715 return err;
716 return 0;
717}
718#endif
719
720int saa_dsp_writel(struct saa7134_dev *dev, int reg, u32 value)
721{
722 int err;
723
724 d2printk("dsp write reg 0x%x = 0x%06x\n",reg<<2,value);
725 err = saa_dsp_wait_bit(dev,SAA7135_DSP_RWSTATE_WRR);
726 if (err < 0)
727 return err;
728 saa_writel(reg,value);
729 err = saa_dsp_wait_bit(dev,SAA7135_DSP_RWSTATE_WRR);
730 if (err < 0)
731 return err;
732 return 0;
733}
734
735static int getstereo_7133(struct saa7134_dev *dev)
736{
737 int retval = V4L2_TUNER_SUB_MONO;
738 u32 value;
739
740 value = saa_readl(0x528 >> 2);
741 if (value & 0x20)
742 retval = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
743 if (value & 0x40)
744 retval = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
745 return retval;
746}
747
748static int mute_input_7133(struct saa7134_dev *dev)
749{
750 u32 reg = 0;
751 int mask;
752
753 switch (dev->input->amux) {
754 case TV:
755 reg = 0x02;
756 break;
757 case LINE1:
758 reg = 0x00;
759 break;
760 case LINE2:
761 case LINE2_LEFT:
762 reg = 0x01;
763 break;
764 }
765 if (dev->ctl_mute)
766 reg = 0x07;
767 saa_writel(0x594 >> 2, reg);
768
769 /* switch gpio-connected external audio mux */
770 if (0 != card(dev).gpiomask) {
771 mask = card(dev).gpiomask;
772 saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, mask, mask);
773 saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, mask, dev->input->gpio);
774 saa7134_track_gpio(dev,dev->input->name);
775 }
776 return 0;
777}
778
779static int tvaudio_thread_ddep(void *data)
780{
781 struct saa7134_dev *dev = data;
782 u32 value, norms, clock;
783
784 daemonize("%s", dev->name);
785 allow_signal(SIGTERM);
786
787 clock = saa7134_boards[dev->board].audio_clock;
788 if (UNSET != audio_clock_override)
789 clock = audio_clock_override;
790 saa_writel(0x598 >> 2, clock);
791
792 /* unmute */
793 saa_dsp_writel(dev, 0x474 >> 2, 0x00);
794 saa_dsp_writel(dev, 0x450 >> 2, 0x00);
795
796 for (;;) {
797 tvaudio_sleep(dev,-1);
798 if (dev->thread.shutdown || signal_pending(current))
799 goto done;
800
801 restart:
802 dev->thread.scan1 = dev->thread.scan2;
803 dprintk("tvaudio thread scan start [%d]\n",dev->thread.scan1);
804
805 if (audio_ddep >= 0x04 && audio_ddep <= 0x0e) {
806 /* insmod option override */
807 norms = (audio_ddep << 2) | 0x01;
808 dprintk("ddep override: %s\n",stdres[audio_ddep]);
809 } else if (&card(dev).radio == dev->input) {
810 dprintk("FM Radio\n");
811 norms = (0x0f << 2) | 0x01;
812 } else {
813 /* (let chip) scan for sound carrier */
814 norms = 0;
815 if (dev->tvnorm->id & V4L2_STD_PAL) {
816 dprintk("PAL scan\n");
817 norms |= 0x2c; /* B/G + D/K + I */
818 }
819 if (dev->tvnorm->id & V4L2_STD_NTSC) {
820 dprintk("NTSC scan\n");
821 norms |= 0x40; /* M */
822 }
823 if (dev->tvnorm->id & V4L2_STD_SECAM) {
824 dprintk("SECAM scan\n");
825 norms |= 0x18; /* L + D/K */
826 }
827 if (0 == norms)
828 norms = 0x7c; /* all */
829 dprintk("scanning:%s%s%s%s%s\n",
830 (norms & 0x04) ? " B/G" : "",
831 (norms & 0x08) ? " D/K" : "",
832 (norms & 0x10) ? " L/L'" : "",
833 (norms & 0x20) ? " I" : "",
834 (norms & 0x40) ? " M" : "");
835 }
836
837 /* kick automatic standard detection */
838 saa_dsp_writel(dev, 0x454 >> 2, 0);
839 saa_dsp_writel(dev, 0x454 >> 2, norms | 0x80);
840
841 /* setup crossbars */
842 saa_dsp_writel(dev, 0x464 >> 2, 0x000000);
843 saa_dsp_writel(dev, 0x470 >> 2, 0x101010);
844
845 if (tvaudio_sleep(dev,3000))
846 goto restart;
847 value = saa_readl(0x528 >> 2) & 0xffffff;
848
849 dprintk("tvaudio thread status: 0x%x [%s%s%s]\n",
850 value, stdres[value & 0x1f],
851 (value & 0x000020) ? ",stereo" : "",
852 (value & 0x000040) ? ",dual" : "");
853 dprintk("detailed status: "
854 "%s#%s#%s#%s#%s#%s#%s#%s#%s#%s#%s#%s#%s#%s\n",
855 (value & 0x000080) ? " A2/EIAJ pilot tone " : "",
856 (value & 0x000100) ? " A2/EIAJ dual " : "",
857 (value & 0x000200) ? " A2/EIAJ stereo " : "",
858 (value & 0x000400) ? " A2/EIAJ noise mute " : "",
859
860 (value & 0x000800) ? " BTSC/FM radio pilot " : "",
861 (value & 0x001000) ? " SAP carrier " : "",
862 (value & 0x002000) ? " BTSC stereo noise mute " : "",
863 (value & 0x004000) ? " SAP noise mute " : "",
864 (value & 0x008000) ? " VDSP " : "",
865
866 (value & 0x010000) ? " NICST " : "",
867 (value & 0x020000) ? " NICDU " : "",
868 (value & 0x040000) ? " NICAM muted " : "",
869 (value & 0x080000) ? " NICAM reserve sound " : "",
870
871 (value & 0x100000) ? " init done " : "");
872 }
873
874 done:
875 complete_and_exit(&dev->thread.exit, 0);
876 return 0;
877}
878
879/* ------------------------------------------------------------------ */
880/* common stuff + external entry points */
881
882static void saa7134_enable_i2s(struct saa7134_dev *dev)
883{
884 int i2s_format;
885
886 if (!card_is_empress(dev))
887 return;
888 i2s_format = (dev->input->amux == TV) ? 0x00 : 0x01;
889
890 /* enable I2S audio output for the mpeg encoder */
891 saa_writeb(SAA7134_I2S_OUTPUT_SELECT, 0x80);
892 saa_writeb(SAA7134_I2S_OUTPUT_FORMAT, i2s_format);
893 saa_writeb(SAA7134_I2S_OUTPUT_LEVEL, 0x0F);
894 saa_writeb(SAA7134_I2S_AUDIO_OUTPUT, 0x01);
895}
896
897int saa7134_tvaudio_rx2mode(u32 rx)
898{
899 u32 mode;
900
901 mode = V4L2_TUNER_MODE_MONO;
902 if (rx & V4L2_TUNER_SUB_STEREO)
903 mode = V4L2_TUNER_MODE_STEREO;
904 else if (rx & V4L2_TUNER_SUB_LANG1)
905 mode = V4L2_TUNER_MODE_LANG1;
906 else if (rx & V4L2_TUNER_SUB_LANG2)
907 mode = V4L2_TUNER_MODE_LANG2;
908 return mode;
909}
910
911void saa7134_tvaudio_setmute(struct saa7134_dev *dev)
912{
913 switch (dev->pci->device) {
914 case PCI_DEVICE_ID_PHILIPS_SAA7130:
915 case PCI_DEVICE_ID_PHILIPS_SAA7134:
916 mute_input_7134(dev);
917 break;
918 case PCI_DEVICE_ID_PHILIPS_SAA7133:
919 case PCI_DEVICE_ID_PHILIPS_SAA7135:
920 mute_input_7133(dev);
921 break;
922 }
923}
924
925void saa7134_tvaudio_setinput(struct saa7134_dev *dev,
926 struct saa7134_input *in)
927{
928 dev->input = in;
929 switch (dev->pci->device) {
930 case PCI_DEVICE_ID_PHILIPS_SAA7130:
931 case PCI_DEVICE_ID_PHILIPS_SAA7134:
932 mute_input_7134(dev);
933 break;
934 case PCI_DEVICE_ID_PHILIPS_SAA7133:
935 case PCI_DEVICE_ID_PHILIPS_SAA7135:
936 mute_input_7133(dev);
937 break;
938 }
939 saa7134_enable_i2s(dev);
940}
941
942void saa7134_tvaudio_setvolume(struct saa7134_dev *dev, int level)
943{
944 switch (dev->pci->device) {
945 case PCI_DEVICE_ID_PHILIPS_SAA7134:
946 saa_writeb(SAA7134_CHANNEL1_LEVEL, level & 0x1f);
947 saa_writeb(SAA7134_CHANNEL2_LEVEL, level & 0x1f);
948 saa_writeb(SAA7134_NICAM_LEVEL_ADJUST, level & 0x1f);
949 break;
950 }
951}
952
953int saa7134_tvaudio_getstereo(struct saa7134_dev *dev)
954{
955 int retval = V4L2_TUNER_SUB_MONO;
956
957 switch (dev->pci->device) {
958 case PCI_DEVICE_ID_PHILIPS_SAA7134:
959 if (dev->tvaudio)
960 retval = tvaudio_getstereo(dev,dev->tvaudio);
961 break;
962 case PCI_DEVICE_ID_PHILIPS_SAA7133:
963 case PCI_DEVICE_ID_PHILIPS_SAA7135:
964 retval = getstereo_7133(dev);
965 break;
966 }
967 return retval;
968}
969
970int saa7134_tvaudio_init2(struct saa7134_dev *dev)
971{
972 DECLARE_MUTEX_LOCKED(sem);
973 int (*my_thread)(void *data) = NULL;
974
975 switch (dev->pci->device) {
976 case PCI_DEVICE_ID_PHILIPS_SAA7134:
977 my_thread = tvaudio_thread;
978 break;
979 case PCI_DEVICE_ID_PHILIPS_SAA7133:
980 case PCI_DEVICE_ID_PHILIPS_SAA7135:
981 my_thread = tvaudio_thread_ddep;
982 break;
983 }
984
985 dev->thread.pid = -1;
986 if (my_thread) {
987 /* start tvaudio thread */
988 init_waitqueue_head(&dev->thread.wq);
989 init_completion(&dev->thread.exit);
990 dev->thread.pid = kernel_thread(my_thread,dev,0);
991 if (dev->thread.pid < 0)
992 printk(KERN_WARNING "%s: kernel_thread() failed\n",
993 dev->name);
994 saa7134_tvaudio_do_scan(dev);
995 }
996
997 saa7134_enable_i2s(dev);
998 return 0;
999}
1000
1001int saa7134_tvaudio_fini(struct saa7134_dev *dev)
1002{
1003 /* shutdown tvaudio thread */
1004 if (dev->thread.pid >= 0) {
1005 dev->thread.shutdown = 1;
1006 wake_up_interruptible(&dev->thread.wq);
1007 wait_for_completion(&dev->thread.exit);
1008 }
1009 saa_andorb(SAA7134_ANALOG_IO_SELECT, 0x07, 0x00); /* LINE1 */
1010 return 0;
1011}
1012
1013int saa7134_tvaudio_do_scan(struct saa7134_dev *dev)
1014{
1015 if (dev->thread.pid >= 0) {
1016 dev->thread.mode = UNSET;
1017 dev->thread.scan2++;
1018 wake_up_interruptible(&dev->thread.wq);
1019 } else {
1020 dev->automute = 0;
1021 saa7134_tvaudio_setmute(dev);
1022 }
1023 return 0;
1024}
1025
1026/* ----------------------------------------------------------- */
1027/*
1028 * Local variables:
1029 * c-basic-offset: 8
1030 * End:
1031 */
diff --git a/drivers/media/video/saa7134/saa7134-vbi.c b/drivers/media/video/saa7134/saa7134-vbi.c
new file mode 100644
index 000000000000..86954cc7c377
--- /dev/null
+++ b/drivers/media/video/saa7134/saa7134-vbi.c
@@ -0,0 +1,270 @@
1/*
2 * $Id: saa7134-vbi.c,v 1.6 2004/12/10 12:33:39 kraxel Exp $
3 *
4 * device driver for philips saa7134 based TV cards
5 * video4linux video interface
6 *
7 * (c) 2001,02 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include <linux/init.h>
25#include <linux/list.h>
26#include <linux/module.h>
27#include <linux/moduleparam.h>
28#include <linux/kernel.h>
29#include <linux/slab.h>
30
31#include "saa7134-reg.h"
32#include "saa7134.h"
33
34/* ------------------------------------------------------------------ */
35
36static unsigned int vbi_debug = 0;
37module_param(vbi_debug, int, 0644);
38MODULE_PARM_DESC(vbi_debug,"enable debug messages [vbi]");
39
40static unsigned int vbibufs = 4;
41module_param(vbibufs, int, 0444);
42MODULE_PARM_DESC(vbibufs,"number of vbi buffers, range 2-32");
43
44#define dprintk(fmt, arg...) if (vbi_debug) \
45 printk(KERN_DEBUG "%s/vbi: " fmt, dev->name , ## arg)
46
47/* ------------------------------------------------------------------ */
48
49#define VBI_LINE_COUNT 16
50#define VBI_LINE_LENGTH 2048
51#define VBI_SCALE 0x200
52
53static void task_init(struct saa7134_dev *dev, struct saa7134_buf *buf,
54 int task)
55{
56 struct saa7134_tvnorm *norm = dev->tvnorm;
57
58 /* setup video scaler */
59 saa_writeb(SAA7134_VBI_H_START1(task), norm->h_start & 0xff);
60 saa_writeb(SAA7134_VBI_H_START2(task), norm->h_start >> 8);
61 saa_writeb(SAA7134_VBI_H_STOP1(task), norm->h_stop & 0xff);
62 saa_writeb(SAA7134_VBI_H_STOP2(task), norm->h_stop >> 8);
63 saa_writeb(SAA7134_VBI_V_START1(task), norm->vbi_v_start & 0xff);
64 saa_writeb(SAA7134_VBI_V_START2(task), norm->vbi_v_start >> 8);
65 saa_writeb(SAA7134_VBI_V_STOP1(task), norm->vbi_v_stop & 0xff);
66 saa_writeb(SAA7134_VBI_V_STOP2(task), norm->vbi_v_stop >> 8);
67
68 saa_writeb(SAA7134_VBI_H_SCALE_INC1(task), VBI_SCALE & 0xff);
69 saa_writeb(SAA7134_VBI_H_SCALE_INC2(task), VBI_SCALE >> 8);
70 saa_writeb(SAA7134_VBI_PHASE_OFFSET_LUMA(task), 0x00);
71 saa_writeb(SAA7134_VBI_PHASE_OFFSET_CHROMA(task), 0x00);
72
73 saa_writeb(SAA7134_VBI_H_LEN1(task), buf->vb.width & 0xff);
74 saa_writeb(SAA7134_VBI_H_LEN2(task), buf->vb.width >> 8);
75 saa_writeb(SAA7134_VBI_V_LEN1(task), buf->vb.height & 0xff);
76 saa_writeb(SAA7134_VBI_V_LEN2(task), buf->vb.height >> 8);
77
78 saa_andorb(SAA7134_DATA_PATH(task), 0xc0, 0x00);
79}
80
81/* ------------------------------------------------------------------ */
82
83static int buffer_activate(struct saa7134_dev *dev,
84 struct saa7134_buf *buf,
85 struct saa7134_buf *next)
86{
87 unsigned long control,base;
88
89 dprintk("buffer_activate [%p]\n",buf);
90 buf->vb.state = STATE_ACTIVE;
91 buf->top_seen = 0;
92
93 task_init(dev,buf,TASK_A);
94 task_init(dev,buf,TASK_B);
95 saa_writeb(SAA7134_OFMT_DATA_A, 0x06);
96 saa_writeb(SAA7134_OFMT_DATA_B, 0x06);
97
98 /* DMA: setup channel 2+3 (= VBI Task A+B) */
99 base = saa7134_buffer_base(buf);
100 control = SAA7134_RS_CONTROL_BURST_16 |
101 SAA7134_RS_CONTROL_ME |
102 (buf->pt->dma >> 12);
103 saa_writel(SAA7134_RS_BA1(2),base);
104 saa_writel(SAA7134_RS_BA2(2),base + buf->vb.size/2);
105 saa_writel(SAA7134_RS_PITCH(2),buf->vb.width);
106 saa_writel(SAA7134_RS_CONTROL(2),control);
107 saa_writel(SAA7134_RS_BA1(3),base);
108 saa_writel(SAA7134_RS_BA2(3),base + buf->vb.size/2);
109 saa_writel(SAA7134_RS_PITCH(3),buf->vb.width);
110 saa_writel(SAA7134_RS_CONTROL(3),control);
111
112 /* start DMA */
113 saa7134_set_dmabits(dev);
114 mod_timer(&dev->vbi_q.timeout, jiffies+BUFFER_TIMEOUT);
115
116 return 0;
117}
118
119static int buffer_prepare(struct videobuf_queue *q,
120 struct videobuf_buffer *vb,
121 enum v4l2_field field)
122{
123 struct saa7134_fh *fh = q->priv_data;
124 struct saa7134_dev *dev = fh->dev;
125 struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb);
126 struct saa7134_tvnorm *norm = dev->tvnorm;
127 unsigned int lines, llength, size;
128 int err;
129
130 lines = norm->vbi_v_stop - norm->vbi_v_start +1;
131 if (lines > VBI_LINE_COUNT)
132 lines = VBI_LINE_COUNT;
133#if 1
134 llength = VBI_LINE_LENGTH;
135#else
136 llength = (norm->h_stop - norm->h_start +1) * 2;
137 if (llength > VBI_LINE_LENGTH)
138 llength = VBI_LINE_LENGTH;
139#endif
140 size = lines * llength * 2;
141 if (0 != buf->vb.baddr && buf->vb.bsize < size)
142 return -EINVAL;
143
144 if (buf->vb.size != size)
145 saa7134_dma_free(dev,buf);
146
147 if (STATE_NEEDS_INIT == buf->vb.state) {
148 buf->vb.width = llength;
149 buf->vb.height = lines;
150 buf->vb.size = size;
151 buf->pt = &fh->pt_vbi;
152
153 err = videobuf_iolock(dev->pci,&buf->vb,NULL);
154 if (err)
155 goto oops;
156 err = saa7134_pgtable_build(dev->pci,buf->pt,
157 buf->vb.dma.sglist,
158 buf->vb.dma.sglen,
159 saa7134_buffer_startpage(buf));
160 if (err)
161 goto oops;
162 }
163 buf->vb.state = STATE_PREPARED;
164 buf->activate = buffer_activate;
165 buf->vb.field = field;
166 return 0;
167
168 oops:
169 saa7134_dma_free(dev,buf);
170 return err;
171}
172
173static int
174buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
175{
176 struct saa7134_fh *fh = q->priv_data;
177 struct saa7134_dev *dev = fh->dev;
178 int llength,lines;
179
180 lines = dev->tvnorm->vbi_v_stop - dev->tvnorm->vbi_v_start +1;
181#if 1
182 llength = VBI_LINE_LENGTH;
183#else
184 llength = (norm->h_stop - norm->h_start +1) * 2;
185 if (llength > VBI_LINE_LENGTH)
186 llength = VBI_LINE_LENGTH;
187#endif
188 *size = lines * llength * 2;
189 if (0 == *count)
190 *count = vbibufs;
191 *count = saa7134_buffer_count(*size,*count);
192 return 0;
193}
194
195static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
196{
197 struct saa7134_fh *fh = q->priv_data;
198 struct saa7134_dev *dev = fh->dev;
199 struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb);
200
201 saa7134_buffer_queue(dev,&dev->vbi_q,buf);
202}
203
204static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
205{
206 struct saa7134_fh *fh = q->priv_data;
207 struct saa7134_dev *dev = fh->dev;
208 struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb);
209
210 saa7134_dma_free(dev,buf);
211}
212
213struct videobuf_queue_ops saa7134_vbi_qops = {
214 .buf_setup = buffer_setup,
215 .buf_prepare = buffer_prepare,
216 .buf_queue = buffer_queue,
217 .buf_release = buffer_release,
218};
219
220/* ------------------------------------------------------------------ */
221
222int saa7134_vbi_init1(struct saa7134_dev *dev)
223{
224 INIT_LIST_HEAD(&dev->vbi_q.queue);
225 init_timer(&dev->vbi_q.timeout);
226 dev->vbi_q.timeout.function = saa7134_buffer_timeout;
227 dev->vbi_q.timeout.data = (unsigned long)(&dev->vbi_q);
228 dev->vbi_q.dev = dev;
229
230 if (vbibufs < 2)
231 vbibufs = 2;
232 if (vbibufs > VIDEO_MAX_FRAME)
233 vbibufs = VIDEO_MAX_FRAME;
234 return 0;
235}
236
237int saa7134_vbi_fini(struct saa7134_dev *dev)
238{
239 /* nothing */
240 return 0;
241}
242
243void saa7134_irq_vbi_done(struct saa7134_dev *dev, unsigned long status)
244{
245 spin_lock(&dev->slock);
246 if (dev->vbi_q.curr) {
247 dev->vbi_fieldcount++;
248 /* make sure we have seen both fields */
249 if ((status & 0x10) == 0x00) {
250 dev->vbi_q.curr->top_seen = 1;
251 goto done;
252 }
253 if (!dev->vbi_q.curr->top_seen)
254 goto done;
255
256 dev->vbi_q.curr->vb.field_count = dev->vbi_fieldcount;
257 saa7134_buffer_finish(dev,&dev->vbi_q,STATE_DONE);
258 }
259 saa7134_buffer_next(dev,&dev->vbi_q);
260
261 done:
262 spin_unlock(&dev->slock);
263}
264
265/* ----------------------------------------------------------- */
266/*
267 * Local variables:
268 * c-basic-offset: 8
269 * End:
270 */
diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c
new file mode 100644
index 000000000000..5d66060026ff
--- /dev/null
+++ b/drivers/media/video/saa7134/saa7134-video.c
@@ -0,0 +1,2406 @@
1/*
2 * $Id: saa7134-video.c,v 1.28 2005/02/15 15:59:35 kraxel Exp $
3 *
4 * device driver for philips saa7134 based TV cards
5 * video4linux video interface
6 *
7 * (c) 2001-03 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include <linux/init.h>
25#include <linux/list.h>
26#include <linux/module.h>
27#include <linux/moduleparam.h>
28#include <linux/kernel.h>
29#include <linux/slab.h>
30
31#include "saa7134-reg.h"
32#include "saa7134.h"
33
34#define V4L2_I2C_CLIENTS 1
35
36/* ------------------------------------------------------------------ */
37
38static unsigned int video_debug = 0;
39static unsigned int gbuffers = 8;
40static unsigned int noninterlaced = 0;
41static unsigned int gbufsize = 720*576*4;
42static unsigned int gbufsize_max = 720*576*4;
43module_param(video_debug, int, 0644);
44MODULE_PARM_DESC(video_debug,"enable debug messages [video]");
45module_param(gbuffers, int, 0444);
46MODULE_PARM_DESC(gbuffers,"number of capture buffers, range 2-32");
47module_param(noninterlaced, int, 0644);
48MODULE_PARM_DESC(noninterlaced,"video input is noninterlaced");
49
50#define dprintk(fmt, arg...) if (video_debug) \
51 printk(KERN_DEBUG "%s/video: " fmt, dev->name , ## arg)
52
53/* ------------------------------------------------------------------ */
54/* data structs for video */
55
56static int video_out[][9] = {
57 [CCIR656] = { 0x00, 0xb1, 0x00, 0xa1, 0x00, 0x04, 0x06, 0x00, 0x00 },
58};
59
60static struct saa7134_format formats[] = {
61 {
62 .name = "8 bpp gray",
63 .fourcc = V4L2_PIX_FMT_GREY,
64 .depth = 8,
65 .pm = 0x06,
66 },{
67 .name = "15 bpp RGB, le",
68 .fourcc = V4L2_PIX_FMT_RGB555,
69 .depth = 16,
70 .pm = 0x13 | 0x80,
71 },{
72 .name = "15 bpp RGB, be",
73 .fourcc = V4L2_PIX_FMT_RGB555X,
74 .depth = 16,
75 .pm = 0x13 | 0x80,
76 .bswap = 1,
77 },{
78 .name = "16 bpp RGB, le",
79 .fourcc = V4L2_PIX_FMT_RGB565,
80 .depth = 16,
81 .pm = 0x10 | 0x80,
82 },{
83 .name = "16 bpp RGB, be",
84 .fourcc = V4L2_PIX_FMT_RGB565X,
85 .depth = 16,
86 .pm = 0x10 | 0x80,
87 .bswap = 1,
88 },{
89 .name = "24 bpp RGB, le",
90 .fourcc = V4L2_PIX_FMT_BGR24,
91 .depth = 24,
92 .pm = 0x11,
93 },{
94 .name = "24 bpp RGB, be",
95 .fourcc = V4L2_PIX_FMT_RGB24,
96 .depth = 24,
97 .pm = 0x11,
98 .bswap = 1,
99 },{
100 .name = "32 bpp RGB, le",
101 .fourcc = V4L2_PIX_FMT_BGR32,
102 .depth = 32,
103 .pm = 0x12,
104 },{
105 .name = "32 bpp RGB, be",
106 .fourcc = V4L2_PIX_FMT_RGB32,
107 .depth = 32,
108 .pm = 0x12,
109 .bswap = 1,
110 .wswap = 1,
111 },{
112 .name = "4:2:2 packed, YUYV",
113 .fourcc = V4L2_PIX_FMT_YUYV,
114 .depth = 16,
115 .pm = 0x00,
116 .bswap = 1,
117 .yuv = 1,
118 },{
119 .name = "4:2:2 packed, UYVY",
120 .fourcc = V4L2_PIX_FMT_UYVY,
121 .depth = 16,
122 .pm = 0x00,
123 .yuv = 1,
124 },{
125 .name = "4:2:2 planar, Y-Cb-Cr",
126 .fourcc = V4L2_PIX_FMT_YUV422P,
127 .depth = 16,
128 .pm = 0x09,
129 .yuv = 1,
130 .planar = 1,
131 .hshift = 1,
132 .vshift = 0,
133 },{
134 .name = "4:2:0 planar, Y-Cb-Cr",
135 .fourcc = V4L2_PIX_FMT_YUV420,
136 .depth = 12,
137 .pm = 0x0a,
138 .yuv = 1,
139 .planar = 1,
140 .hshift = 1,
141 .vshift = 1,
142 },{
143 .name = "4:2:0 planar, Y-Cb-Cr",
144 .fourcc = V4L2_PIX_FMT_YVU420,
145 .depth = 12,
146 .pm = 0x0a,
147 .yuv = 1,
148 .planar = 1,
149 .uvswap = 1,
150 .hshift = 1,
151 .vshift = 1,
152 }
153};
154#define FORMATS ARRAY_SIZE(formats)
155
156#define NORM_625_50 \
157 .h_start = 0, \
158 .h_stop = 719, \
159 .video_v_start = 24, \
160 .video_v_stop = 311, \
161 .vbi_v_start = 7, \
162 .vbi_v_stop = 22, \
163 .src_timing = 4
164
165#define NORM_525_60 \
166 .h_start = 0, \
167 .h_stop = 703, \
168 .video_v_start = 22, \
169 .video_v_stop = 22+239, \
170 .vbi_v_start = 10, /* FIXME */ \
171 .vbi_v_stop = 21, /* FIXME */ \
172 .src_timing = 1
173
174static struct saa7134_tvnorm tvnorms[] = {
175 {
176 .name = "PAL", /* autodetect */
177 .id = V4L2_STD_PAL,
178 NORM_625_50,
179
180 .sync_control = 0x18,
181 .luma_control = 0x40,
182 .chroma_ctrl1 = 0x81,
183 .chroma_gain = 0x2a,
184 .chroma_ctrl2 = 0x06,
185 .vgate_misc = 0x1c,
186
187 },{
188 .name = "PAL-BG",
189 .id = V4L2_STD_PAL_BG,
190 NORM_625_50,
191
192 .sync_control = 0x18,
193 .luma_control = 0x40,
194 .chroma_ctrl1 = 0x81,
195 .chroma_gain = 0x2a,
196 .chroma_ctrl2 = 0x06,
197 .vgate_misc = 0x1c,
198
199 },{
200 .name = "PAL-I",
201 .id = V4L2_STD_PAL_I,
202 NORM_625_50,
203
204 .sync_control = 0x18,
205 .luma_control = 0x40,
206 .chroma_ctrl1 = 0x81,
207 .chroma_gain = 0x2a,
208 .chroma_ctrl2 = 0x06,
209 .vgate_misc = 0x1c,
210
211 },{
212 .name = "PAL-DK",
213 .id = V4L2_STD_PAL_DK,
214 NORM_625_50,
215
216 .sync_control = 0x18,
217 .luma_control = 0x40,
218 .chroma_ctrl1 = 0x81,
219 .chroma_gain = 0x2a,
220 .chroma_ctrl2 = 0x06,
221 .vgate_misc = 0x1c,
222
223 },{
224 .name = "NTSC",
225 .id = V4L2_STD_NTSC,
226 NORM_525_60,
227
228 .sync_control = 0x59,
229 .luma_control = 0x40,
230 .chroma_ctrl1 = 0x89,
231 .chroma_gain = 0x2a,
232 .chroma_ctrl2 = 0x0e,
233 .vgate_misc = 0x18,
234
235 },{
236 .name = "SECAM",
237 .id = V4L2_STD_SECAM,
238 NORM_625_50,
239
240 .sync_control = 0x18, /* old: 0x58, */
241 .luma_control = 0x1b,
242 .chroma_ctrl1 = 0xd1,
243 .chroma_gain = 0x80,
244 .chroma_ctrl2 = 0x00,
245 .vgate_misc = 0x1c,
246
247 },{
248 .name = "PAL-M",
249 .id = V4L2_STD_PAL_M,
250 NORM_525_60,
251
252 .sync_control = 0x59,
253 .luma_control = 0x40,
254 .chroma_ctrl1 = 0xb9,
255 .chroma_gain = 0x2a,
256 .chroma_ctrl2 = 0x0e,
257 .vgate_misc = 0x18,
258
259 },{
260 .name = "PAL-Nc",
261 .id = V4L2_STD_PAL_Nc,
262 NORM_625_50,
263
264 .sync_control = 0x18,
265 .luma_control = 0x40,
266 .chroma_ctrl1 = 0xa1,
267 .chroma_gain = 0x2a,
268 .chroma_ctrl2 = 0x06,
269 .vgate_misc = 0x1c,
270
271 },{
272 .name = "PAL-60",
273 .id = V4L2_STD_PAL_60,
274
275 .h_start = 0,
276 .h_stop = 719,
277 .video_v_start = 22,
278 .video_v_stop = 22+239,
279 .vbi_v_start = 10, /* FIXME */
280 .vbi_v_stop = 21, /* FIXME */
281 .src_timing = 1,
282
283 .sync_control = 0x18,
284 .luma_control = 0x40,
285 .chroma_ctrl1 = 0x81,
286 .chroma_gain = 0x2a,
287 .chroma_ctrl2 = 0x06,
288 .vgate_misc = 0x1c,
289 }
290};
291#define TVNORMS ARRAY_SIZE(tvnorms)
292
293#define V4L2_CID_PRIVATE_INVERT (V4L2_CID_PRIVATE_BASE + 0)
294#define V4L2_CID_PRIVATE_Y_ODD (V4L2_CID_PRIVATE_BASE + 1)
295#define V4L2_CID_PRIVATE_Y_EVEN (V4L2_CID_PRIVATE_BASE + 2)
296#define V4L2_CID_PRIVATE_AUTOMUTE (V4L2_CID_PRIVATE_BASE + 3)
297#define V4L2_CID_PRIVATE_LASTP1 (V4L2_CID_PRIVATE_BASE + 4)
298
299static const struct v4l2_queryctrl no_ctrl = {
300 .name = "42",
301 .flags = V4L2_CTRL_FLAG_DISABLED,
302};
303static const struct v4l2_queryctrl video_ctrls[] = {
304 /* --- video --- */
305 {
306 .id = V4L2_CID_BRIGHTNESS,
307 .name = "Brightness",
308 .minimum = 0,
309 .maximum = 255,
310 .step = 1,
311 .default_value = 128,
312 .type = V4L2_CTRL_TYPE_INTEGER,
313 },{
314 .id = V4L2_CID_CONTRAST,
315 .name = "Contrast",
316 .minimum = 0,
317 .maximum = 127,
318 .step = 1,
319 .default_value = 68,
320 .type = V4L2_CTRL_TYPE_INTEGER,
321 },{
322 .id = V4L2_CID_SATURATION,
323 .name = "Saturation",
324 .minimum = 0,
325 .maximum = 127,
326 .step = 1,
327 .default_value = 64,
328 .type = V4L2_CTRL_TYPE_INTEGER,
329 },{
330 .id = V4L2_CID_HUE,
331 .name = "Hue",
332 .minimum = -128,
333 .maximum = 127,
334 .step = 1,
335 .default_value = 0,
336 .type = V4L2_CTRL_TYPE_INTEGER,
337 },{
338 .id = V4L2_CID_VFLIP,
339 .name = "vertical flip",
340 .minimum = 0,
341 .maximum = 1,
342 .type = V4L2_CTRL_TYPE_BOOLEAN,
343 },
344 /* --- audio --- */
345 {
346 .id = V4L2_CID_AUDIO_MUTE,
347 .name = "Mute",
348 .minimum = 0,
349 .maximum = 1,
350 .type = V4L2_CTRL_TYPE_BOOLEAN,
351 },{
352 .id = V4L2_CID_AUDIO_VOLUME,
353 .name = "Volume",
354 .minimum = -15,
355 .maximum = 15,
356 .step = 1,
357 .default_value = 0,
358 .type = V4L2_CTRL_TYPE_INTEGER,
359 },
360 /* --- private --- */
361 {
362 .id = V4L2_CID_PRIVATE_INVERT,
363 .name = "Invert",
364 .minimum = 0,
365 .maximum = 1,
366 .type = V4L2_CTRL_TYPE_BOOLEAN,
367 },{
368 .id = V4L2_CID_PRIVATE_Y_ODD,
369 .name = "y offset odd field",
370 .minimum = 0,
371 .maximum = 128,
372 .default_value = 0,
373 .type = V4L2_CTRL_TYPE_INTEGER,
374 },{
375 .id = V4L2_CID_PRIVATE_Y_EVEN,
376 .name = "y offset even field",
377 .minimum = 0,
378 .maximum = 128,
379 .default_value = 0,
380 .type = V4L2_CTRL_TYPE_INTEGER,
381 },{
382 .id = V4L2_CID_PRIVATE_AUTOMUTE,
383 .name = "automute",
384 .minimum = 0,
385 .maximum = 1,
386 .default_value = 1,
387 .type = V4L2_CTRL_TYPE_BOOLEAN,
388 }
389};
390static const unsigned int CTRLS = ARRAY_SIZE(video_ctrls);
391
392static const struct v4l2_queryctrl* ctrl_by_id(unsigned int id)
393{
394 unsigned int i;
395
396 for (i = 0; i < CTRLS; i++)
397 if (video_ctrls[i].id == id)
398 return video_ctrls+i;
399 return NULL;
400}
401
402static struct saa7134_format* format_by_fourcc(unsigned int fourcc)
403{
404 unsigned int i;
405
406 for (i = 0; i < FORMATS; i++)
407 if (formats[i].fourcc == fourcc)
408 return formats+i;
409 return NULL;
410}
411
412/* ----------------------------------------------------------------------- */
413/* resource management */
414
415static int res_get(struct saa7134_dev *dev, struct saa7134_fh *fh, unsigned int bit)
416{
417 if (fh->resources & bit)
418 /* have it already allocated */
419 return 1;
420
421 /* is it free? */
422 down(&dev->lock);
423 if (dev->resources & bit) {
424 /* no, someone else uses it */
425 up(&dev->lock);
426 return 0;
427 }
428 /* it's free, grab it */
429 fh->resources |= bit;
430 dev->resources |= bit;
431 dprintk("res: get %d\n",bit);
432 up(&dev->lock);
433 return 1;
434}
435
436static
437int res_check(struct saa7134_fh *fh, unsigned int bit)
438{
439 return (fh->resources & bit);
440}
441
442static
443int res_locked(struct saa7134_dev *dev, unsigned int bit)
444{
445 return (dev->resources & bit);
446}
447
448static
449void res_free(struct saa7134_dev *dev, struct saa7134_fh *fh, unsigned int bits)
450{
451 if ((fh->resources & bits) != bits)
452 BUG();
453
454 down(&dev->lock);
455 fh->resources &= ~bits;
456 dev->resources &= ~bits;
457 dprintk("res: put %d\n",bits);
458 up(&dev->lock);
459}
460
461/* ------------------------------------------------------------------ */
462
463static void set_tvnorm(struct saa7134_dev *dev, struct saa7134_tvnorm *norm)
464{
465 int luma_control,sync_control,mux;
466
467 dprintk("set tv norm = %s\n",norm->name);
468 dev->tvnorm = norm;
469
470 mux = card_in(dev,dev->ctl_input).vmux;
471 luma_control = norm->luma_control;
472 sync_control = norm->sync_control;
473
474 if (mux > 5)
475 luma_control |= 0x80; /* svideo */
476 if (noninterlaced || dev->nosignal)
477 sync_control |= 0x20;
478
479 /* setup cropping */
480 dev->crop_bounds.left = norm->h_start;
481 dev->crop_defrect.left = norm->h_start;
482 dev->crop_bounds.width = norm->h_stop - norm->h_start +1;
483 dev->crop_defrect.width = norm->h_stop - norm->h_start +1;
484
485 dev->crop_bounds.top = (norm->vbi_v_stop+1)*2;
486 dev->crop_defrect.top = norm->video_v_start*2;
487 dev->crop_bounds.height = ((norm->id & V4L2_STD_525_60) ? 524 : 624)
488 - dev->crop_bounds.top;
489 dev->crop_defrect.height = (norm->video_v_stop - norm->video_v_start +1)*2;
490
491 dev->crop_current = dev->crop_defrect;
492
493 /* setup video decoder */
494 saa_writeb(SAA7134_INCR_DELAY, 0x08);
495 saa_writeb(SAA7134_ANALOG_IN_CTRL1, 0xc0 | mux);
496 saa_writeb(SAA7134_ANALOG_IN_CTRL2, 0x00);
497
498 saa_writeb(SAA7134_ANALOG_IN_CTRL3, 0x90);
499 saa_writeb(SAA7134_ANALOG_IN_CTRL4, 0x90);
500 saa_writeb(SAA7134_HSYNC_START, 0xeb);
501 saa_writeb(SAA7134_HSYNC_STOP, 0xe0);
502 saa_writeb(SAA7134_SOURCE_TIMING1, norm->src_timing);
503
504 saa_writeb(SAA7134_SYNC_CTRL, sync_control);
505 saa_writeb(SAA7134_LUMA_CTRL, luma_control);
506 saa_writeb(SAA7134_DEC_LUMA_BRIGHT, dev->ctl_bright);
507 saa_writeb(SAA7134_DEC_LUMA_CONTRAST, dev->ctl_contrast);
508
509 saa_writeb(SAA7134_DEC_CHROMA_SATURATION, dev->ctl_saturation);
510 saa_writeb(SAA7134_DEC_CHROMA_HUE, dev->ctl_hue);
511 saa_writeb(SAA7134_CHROMA_CTRL1, norm->chroma_ctrl1);
512 saa_writeb(SAA7134_CHROMA_GAIN, norm->chroma_gain);
513
514 saa_writeb(SAA7134_CHROMA_CTRL2, norm->chroma_ctrl2);
515 saa_writeb(SAA7134_MODE_DELAY_CTRL, 0x00);
516
517 saa_writeb(SAA7134_ANALOG_ADC, 0x01);
518 saa_writeb(SAA7134_VGATE_START, 0x11);
519 saa_writeb(SAA7134_VGATE_STOP, 0xfe);
520 saa_writeb(SAA7134_MISC_VGATE_MSB, norm->vgate_misc);
521 saa_writeb(SAA7134_RAW_DATA_GAIN, 0x40);
522 saa_writeb(SAA7134_RAW_DATA_OFFSET, 0x80);
523
524#ifdef V4L2_I2C_CLIENTS
525 saa7134_i2c_call_clients(dev,VIDIOC_S_STD,&norm->id);
526#else
527 {
528 /* pass down info to the i2c chips (v4l1) */
529 struct video_channel c;
530 memset(&c,0,sizeof(c));
531 c.channel = dev->ctl_input;
532 c.norm = VIDEO_MODE_PAL;
533 if (norm->id & V4L2_STD_NTSC)
534 c.norm = VIDEO_MODE_NTSC;
535 if (norm->id & V4L2_STD_SECAM)
536 c.norm = VIDEO_MODE_SECAM;
537 saa7134_i2c_call_clients(dev,VIDIOCSCHAN,&c);
538 }
539#endif
540}
541
542static void video_mux(struct saa7134_dev *dev, int input)
543{
544 dprintk("video input = %d [%s]\n",input,card_in(dev,input).name);
545 dev->ctl_input = input;
546 set_tvnorm(dev,dev->tvnorm);
547 saa7134_tvaudio_setinput(dev,&card_in(dev,input));
548}
549
550static void set_h_prescale(struct saa7134_dev *dev, int task, int prescale)
551{
552 static const struct {
553 int xpsc;
554 int xacl;
555 int xc2_1;
556 int xdcg;
557 int vpfy;
558 } vals[] = {
559 /* XPSC XACL XC2_1 XDCG VPFY */
560 { 1, 0, 0, 0, 0 },
561 { 2, 2, 1, 2, 2 },
562 { 3, 4, 1, 3, 2 },
563 { 4, 8, 1, 4, 2 },
564 { 5, 8, 1, 4, 2 },
565 { 6, 8, 1, 4, 3 },
566 { 7, 8, 1, 4, 3 },
567 { 8, 15, 0, 4, 3 },
568 { 9, 15, 0, 4, 3 },
569 { 10, 16, 1, 5, 3 },
570 };
571 static const int count = ARRAY_SIZE(vals);
572 int i;
573
574 for (i = 0; i < count; i++)
575 if (vals[i].xpsc == prescale)
576 break;
577 if (i == count)
578 return;
579
580 saa_writeb(SAA7134_H_PRESCALE(task), vals[i].xpsc);
581 saa_writeb(SAA7134_ACC_LENGTH(task), vals[i].xacl);
582 saa_writeb(SAA7134_LEVEL_CTRL(task),
583 (vals[i].xc2_1 << 3) | (vals[i].xdcg));
584 saa_andorb(SAA7134_FIR_PREFILTER_CTRL(task), 0x0f,
585 (vals[i].vpfy << 2) | vals[i].vpfy);
586}
587
588static void set_v_scale(struct saa7134_dev *dev, int task, int yscale)
589{
590 int val,mirror;
591
592 saa_writeb(SAA7134_V_SCALE_RATIO1(task), yscale & 0xff);
593 saa_writeb(SAA7134_V_SCALE_RATIO2(task), yscale >> 8);
594
595 mirror = (dev->ctl_mirror) ? 0x02 : 0x00;
596 if (yscale < 2048) {
597 /* LPI */
598 dprintk("yscale LPI yscale=%d\n",yscale);
599 saa_writeb(SAA7134_V_FILTER(task), 0x00 | mirror);
600 saa_writeb(SAA7134_LUMA_CONTRAST(task), 0x40);
601 saa_writeb(SAA7134_CHROMA_SATURATION(task), 0x40);
602 } else {
603 /* ACM */
604 val = 0x40 * 1024 / yscale;
605 dprintk("yscale ACM yscale=%d val=0x%x\n",yscale,val);
606 saa_writeb(SAA7134_V_FILTER(task), 0x01 | mirror);
607 saa_writeb(SAA7134_LUMA_CONTRAST(task), val);
608 saa_writeb(SAA7134_CHROMA_SATURATION(task), val);
609 }
610 saa_writeb(SAA7134_LUMA_BRIGHT(task), 0x80);
611}
612
613static void set_size(struct saa7134_dev *dev, int task,
614 int width, int height, int interlace)
615{
616 int prescale,xscale,yscale,y_even,y_odd;
617 int h_start, h_stop, v_start, v_stop;
618 int div = interlace ? 2 : 1;
619
620 /* setup video scaler */
621 h_start = dev->crop_current.left;
622 v_start = dev->crop_current.top/2;
623 h_stop = (dev->crop_current.left + dev->crop_current.width -1);
624 v_stop = (dev->crop_current.top + dev->crop_current.height -1)/2;
625
626 saa_writeb(SAA7134_VIDEO_H_START1(task), h_start & 0xff);
627 saa_writeb(SAA7134_VIDEO_H_START2(task), h_start >> 8);
628 saa_writeb(SAA7134_VIDEO_H_STOP1(task), h_stop & 0xff);
629 saa_writeb(SAA7134_VIDEO_H_STOP2(task), h_stop >> 8);
630 saa_writeb(SAA7134_VIDEO_V_START1(task), v_start & 0xff);
631 saa_writeb(SAA7134_VIDEO_V_START2(task), v_start >> 8);
632 saa_writeb(SAA7134_VIDEO_V_STOP1(task), v_stop & 0xff);
633 saa_writeb(SAA7134_VIDEO_V_STOP2(task), v_stop >> 8);
634
635 prescale = dev->crop_current.width / width;
636 if (0 == prescale)
637 prescale = 1;
638 xscale = 1024 * dev->crop_current.width / prescale / width;
639 yscale = 512 * div * dev->crop_current.height / height;
640 dprintk("prescale=%d xscale=%d yscale=%d\n",prescale,xscale,yscale);
641 set_h_prescale(dev,task,prescale);
642 saa_writeb(SAA7134_H_SCALE_INC1(task), xscale & 0xff);
643 saa_writeb(SAA7134_H_SCALE_INC2(task), xscale >> 8);
644 set_v_scale(dev,task,yscale);
645
646 saa_writeb(SAA7134_VIDEO_PIXELS1(task), width & 0xff);
647 saa_writeb(SAA7134_VIDEO_PIXELS2(task), width >> 8);
648 saa_writeb(SAA7134_VIDEO_LINES1(task), height/div & 0xff);
649 saa_writeb(SAA7134_VIDEO_LINES2(task), height/div >> 8);
650
651 /* deinterlace y offsets */
652 y_odd = dev->ctl_y_odd;
653 y_even = dev->ctl_y_even;
654 saa_writeb(SAA7134_V_PHASE_OFFSET0(task), y_odd);
655 saa_writeb(SAA7134_V_PHASE_OFFSET1(task), y_even);
656 saa_writeb(SAA7134_V_PHASE_OFFSET2(task), y_odd);
657 saa_writeb(SAA7134_V_PHASE_OFFSET3(task), y_even);
658}
659
660/* ------------------------------------------------------------------ */
661
662struct cliplist {
663 __u16 position;
664 __u8 enable;
665 __u8 disable;
666};
667
668static void sort_cliplist(struct cliplist *cl, int entries)
669{
670 struct cliplist swap;
671 int i,j,n;
672
673 for (i = entries-2; i >= 0; i--) {
674 for (n = 0, j = 0; j <= i; j++) {
675 if (cl[j].position > cl[j+1].position) {
676 swap = cl[j];
677 cl[j] = cl[j+1];
678 cl[j+1] = swap;
679 n++;
680 }
681 }
682 if (0 == n)
683 break;
684 }
685}
686
687static void set_cliplist(struct saa7134_dev *dev, int reg,
688 struct cliplist *cl, int entries, char *name)
689{
690 __u8 winbits = 0;
691 int i;
692
693 for (i = 0; i < entries; i++) {
694 winbits |= cl[i].enable;
695 winbits &= ~cl[i].disable;
696 if (i < 15 && cl[i].position == cl[i+1].position)
697 continue;
698 saa_writeb(reg + 0, winbits);
699 saa_writeb(reg + 2, cl[i].position & 0xff);
700 saa_writeb(reg + 3, cl[i].position >> 8);
701 dprintk("clip: %s winbits=%02x pos=%d\n",
702 name,winbits,cl[i].position);
703 reg += 8;
704 }
705 for (; reg < 0x400; reg += 8) {
706 saa_writeb(reg+ 0, 0);
707 saa_writeb(reg + 1, 0);
708 saa_writeb(reg + 2, 0);
709 saa_writeb(reg + 3, 0);
710 }
711}
712
713static int clip_range(int val)
714{
715 if (val < 0)
716 val = 0;
717 return val;
718}
719
720static int setup_clipping(struct saa7134_dev *dev, struct v4l2_clip *clips,
721 int nclips, int interlace)
722{
723 struct cliplist col[16], row[16];
724 int cols, rows, i;
725 int div = interlace ? 2 : 1;
726
727 memset(col,0,sizeof(col)); cols = 0;
728 memset(row,0,sizeof(row)); rows = 0;
729 for (i = 0; i < nclips && i < 8; i++) {
730 col[cols].position = clip_range(clips[i].c.left);
731 col[cols].enable = (1 << i);
732 cols++;
733 col[cols].position = clip_range(clips[i].c.left+clips[i].c.width);
734 col[cols].disable = (1 << i);
735 cols++;
736 row[rows].position = clip_range(clips[i].c.top / div);
737 row[rows].enable = (1 << i);
738 rows++;
739 row[rows].position = clip_range((clips[i].c.top + clips[i].c.height)
740 / div);
741 row[rows].disable = (1 << i);
742 rows++;
743 }
744 sort_cliplist(col,cols);
745 sort_cliplist(row,rows);
746 set_cliplist(dev,0x380,col,cols,"cols");
747 set_cliplist(dev,0x384,row,rows,"rows");
748 return 0;
749}
750
751static int verify_preview(struct saa7134_dev *dev, struct v4l2_window *win)
752{
753 enum v4l2_field field;
754 int maxw, maxh;
755
756 if (NULL == dev->ovbuf.base)
757 return -EINVAL;
758 if (NULL == dev->ovfmt)
759 return -EINVAL;
760 if (win->w.width < 48 || win->w.height < 32)
761 return -EINVAL;
762 if (win->clipcount > 2048)
763 return -EINVAL;
764
765 field = win->field;
766 maxw = dev->crop_current.width;
767 maxh = dev->crop_current.height;
768
769 if (V4L2_FIELD_ANY == field) {
770 field = (win->w.height > maxh/2)
771 ? V4L2_FIELD_INTERLACED
772 : V4L2_FIELD_TOP;
773 }
774 switch (field) {
775 case V4L2_FIELD_TOP:
776 case V4L2_FIELD_BOTTOM:
777 maxh = maxh / 2;
778 break;
779 case V4L2_FIELD_INTERLACED:
780 break;
781 default:
782 return -EINVAL;
783 }
784
785 win->field = field;
786 if (win->w.width > maxw)
787 win->w.width = maxw;
788 if (win->w.height > maxh)
789 win->w.height = maxh;
790 return 0;
791}
792
793static int start_preview(struct saa7134_dev *dev, struct saa7134_fh *fh)
794{
795 unsigned long base,control,bpl;
796 int err;
797
798 err = verify_preview(dev,&fh->win);
799 if (0 != err)
800 return err;
801
802 dev->ovfield = fh->win.field;
803 dprintk("start_preview %dx%d+%d+%d %s field=%s\n",
804 fh->win.w.width,fh->win.w.height,
805 fh->win.w.left,fh->win.w.top,
806 dev->ovfmt->name,v4l2_field_names[dev->ovfield]);
807
808 /* setup window + clipping */
809 set_size(dev,TASK_B,fh->win.w.width,fh->win.w.height,
810 V4L2_FIELD_HAS_BOTH(dev->ovfield));
811 setup_clipping(dev,fh->clips,fh->nclips,
812 V4L2_FIELD_HAS_BOTH(dev->ovfield));
813 if (dev->ovfmt->yuv)
814 saa_andorb(SAA7134_DATA_PATH(TASK_B), 0x3f, 0x03);
815 else
816 saa_andorb(SAA7134_DATA_PATH(TASK_B), 0x3f, 0x01);
817 saa_writeb(SAA7134_OFMT_VIDEO_B, dev->ovfmt->pm | 0x20);
818
819 /* dma: setup channel 1 (= Video Task B) */
820 base = (unsigned long)dev->ovbuf.base;
821 base += dev->ovbuf.fmt.bytesperline * fh->win.w.top;
822 base += dev->ovfmt->depth/8 * fh->win.w.left;
823 bpl = dev->ovbuf.fmt.bytesperline;
824 control = SAA7134_RS_CONTROL_BURST_16;
825 if (dev->ovfmt->bswap)
826 control |= SAA7134_RS_CONTROL_BSWAP;
827 if (dev->ovfmt->wswap)
828 control |= SAA7134_RS_CONTROL_WSWAP;
829 if (V4L2_FIELD_HAS_BOTH(dev->ovfield)) {
830 saa_writel(SAA7134_RS_BA1(1),base);
831 saa_writel(SAA7134_RS_BA2(1),base+bpl);
832 saa_writel(SAA7134_RS_PITCH(1),bpl*2);
833 saa_writel(SAA7134_RS_CONTROL(1),control);
834 } else {
835 saa_writel(SAA7134_RS_BA1(1),base);
836 saa_writel(SAA7134_RS_BA2(1),base);
837 saa_writel(SAA7134_RS_PITCH(1),bpl);
838 saa_writel(SAA7134_RS_CONTROL(1),control);
839 }
840
841 /* start dma */
842 dev->ovenable = 1;
843 saa7134_set_dmabits(dev);
844
845 return 0;
846}
847
848static int stop_preview(struct saa7134_dev *dev, struct saa7134_fh *fh)
849{
850 dev->ovenable = 0;
851 saa7134_set_dmabits(dev);
852 return 0;
853}
854
855/* ------------------------------------------------------------------ */
856
857static int buffer_activate(struct saa7134_dev *dev,
858 struct saa7134_buf *buf,
859 struct saa7134_buf *next)
860{
861 unsigned long base,control,bpl;
862 unsigned long bpl_uv,lines_uv,base2,base3,tmp; /* planar */
863
864 dprintk("buffer_activate buf=%p\n",buf);
865 buf->vb.state = STATE_ACTIVE;
866 buf->top_seen = 0;
867
868 set_size(dev,TASK_A,buf->vb.width,buf->vb.height,
869 V4L2_FIELD_HAS_BOTH(buf->vb.field));
870 if (buf->fmt->yuv)
871 saa_andorb(SAA7134_DATA_PATH(TASK_A), 0x3f, 0x03);
872 else
873 saa_andorb(SAA7134_DATA_PATH(TASK_A), 0x3f, 0x01);
874 saa_writeb(SAA7134_OFMT_VIDEO_A, buf->fmt->pm);
875
876 /* DMA: setup channel 0 (= Video Task A0) */
877 base = saa7134_buffer_base(buf);
878 if (buf->fmt->planar)
879 bpl = buf->vb.width;
880 else
881 bpl = (buf->vb.width * buf->fmt->depth) / 8;
882 control = SAA7134_RS_CONTROL_BURST_16 |
883 SAA7134_RS_CONTROL_ME |
884 (buf->pt->dma >> 12);
885 if (buf->fmt->bswap)
886 control |= SAA7134_RS_CONTROL_BSWAP;
887 if (buf->fmt->wswap)
888 control |= SAA7134_RS_CONTROL_WSWAP;
889 if (V4L2_FIELD_HAS_BOTH(buf->vb.field)) {
890 /* interlaced */
891 saa_writel(SAA7134_RS_BA1(0),base);
892 saa_writel(SAA7134_RS_BA2(0),base+bpl);
893 saa_writel(SAA7134_RS_PITCH(0),bpl*2);
894 } else {
895 /* non-interlaced */
896 saa_writel(SAA7134_RS_BA1(0),base);
897 saa_writel(SAA7134_RS_BA2(0),base);
898 saa_writel(SAA7134_RS_PITCH(0),bpl);
899 }
900 saa_writel(SAA7134_RS_CONTROL(0),control);
901
902 if (buf->fmt->planar) {
903 /* DMA: setup channel 4+5 (= planar task A) */
904 bpl_uv = bpl >> buf->fmt->hshift;
905 lines_uv = buf->vb.height >> buf->fmt->vshift;
906 base2 = base + bpl * buf->vb.height;
907 base3 = base2 + bpl_uv * lines_uv;
908 if (buf->fmt->uvswap)
909 tmp = base2, base2 = base3, base3 = tmp;
910 dprintk("uv: bpl=%ld lines=%ld base2/3=%ld/%ld\n",
911 bpl_uv,lines_uv,base2,base3);
912 if (V4L2_FIELD_HAS_BOTH(buf->vb.field)) {
913 /* interlaced */
914 saa_writel(SAA7134_RS_BA1(4),base2);
915 saa_writel(SAA7134_RS_BA2(4),base2+bpl_uv);
916 saa_writel(SAA7134_RS_PITCH(4),bpl_uv*2);
917 saa_writel(SAA7134_RS_BA1(5),base3);
918 saa_writel(SAA7134_RS_BA2(5),base3+bpl_uv);
919 saa_writel(SAA7134_RS_PITCH(5),bpl_uv*2);
920 } else {
921 /* non-interlaced */
922 saa_writel(SAA7134_RS_BA1(4),base2);
923 saa_writel(SAA7134_RS_BA2(4),base2);
924 saa_writel(SAA7134_RS_PITCH(4),bpl_uv);
925 saa_writel(SAA7134_RS_BA1(5),base3);
926 saa_writel(SAA7134_RS_BA2(5),base3);
927 saa_writel(SAA7134_RS_PITCH(5),bpl_uv);
928 }
929 saa_writel(SAA7134_RS_CONTROL(4),control);
930 saa_writel(SAA7134_RS_CONTROL(5),control);
931 }
932
933 /* start DMA */
934 saa7134_set_dmabits(dev);
935 mod_timer(&dev->video_q.timeout, jiffies+BUFFER_TIMEOUT);
936 return 0;
937}
938
939static int buffer_prepare(struct videobuf_queue *q,
940 struct videobuf_buffer *vb,
941 enum v4l2_field field)
942{
943 struct saa7134_fh *fh = q->priv_data;
944 struct saa7134_dev *dev = fh->dev;
945 struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb);
946 unsigned int size;
947 int err;
948
949 /* sanity checks */
950 if (NULL == fh->fmt)
951 return -EINVAL;
952 if (fh->width < 48 ||
953 fh->height < 32 ||
954 fh->width/4 > dev->crop_current.width ||
955 fh->height/4 > dev->crop_current.height ||
956 fh->width > dev->crop_bounds.width ||
957 fh->height > dev->crop_bounds.height)
958 return -EINVAL;
959 size = (fh->width * fh->height * fh->fmt->depth) >> 3;
960 if (0 != buf->vb.baddr && buf->vb.bsize < size)
961 return -EINVAL;
962
963 dprintk("buffer_prepare [%d,size=%dx%d,bytes=%d,fields=%s,%s]\n",
964 vb->i,fh->width,fh->height,size,v4l2_field_names[field],
965 fh->fmt->name);
966 if (buf->vb.width != fh->width ||
967 buf->vb.height != fh->height ||
968 buf->vb.size != size ||
969 buf->vb.field != field ||
970 buf->fmt != fh->fmt) {
971 saa7134_dma_free(dev,buf);
972 }
973
974 if (STATE_NEEDS_INIT == buf->vb.state) {
975 buf->vb.width = fh->width;
976 buf->vb.height = fh->height;
977 buf->vb.size = size;
978 buf->vb.field = field;
979 buf->fmt = fh->fmt;
980 buf->pt = &fh->pt_cap;
981
982 err = videobuf_iolock(dev->pci,&buf->vb,&dev->ovbuf);
983 if (err)
984 goto oops;
985 err = saa7134_pgtable_build(dev->pci,buf->pt,
986 buf->vb.dma.sglist,
987 buf->vb.dma.sglen,
988 saa7134_buffer_startpage(buf));
989 if (err)
990 goto oops;
991 }
992 buf->vb.state = STATE_PREPARED;
993 buf->activate = buffer_activate;
994 return 0;
995
996 oops:
997 saa7134_dma_free(dev,buf);
998 return err;
999}
1000
1001static int
1002buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
1003{
1004 struct saa7134_fh *fh = q->priv_data;
1005
1006 *size = fh->fmt->depth * fh->width * fh->height >> 3;
1007 if (0 == *count)
1008 *count = gbuffers;
1009 *count = saa7134_buffer_count(*size,*count);
1010 return 0;
1011}
1012
1013static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
1014{
1015 struct saa7134_fh *fh = q->priv_data;
1016 struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb);
1017
1018 saa7134_buffer_queue(fh->dev,&fh->dev->video_q,buf);
1019}
1020
1021static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
1022{
1023 struct saa7134_fh *fh = q->priv_data;
1024 struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb);
1025
1026 saa7134_dma_free(fh->dev,buf);
1027}
1028
1029static struct videobuf_queue_ops video_qops = {
1030 .buf_setup = buffer_setup,
1031 .buf_prepare = buffer_prepare,
1032 .buf_queue = buffer_queue,
1033 .buf_release = buffer_release,
1034};
1035
1036/* ------------------------------------------------------------------ */
1037
1038static int get_control(struct saa7134_dev *dev, struct v4l2_control *c)
1039{
1040 const struct v4l2_queryctrl* ctrl;
1041
1042 ctrl = ctrl_by_id(c->id);
1043 if (NULL == ctrl)
1044 return -EINVAL;
1045 switch (c->id) {
1046 case V4L2_CID_BRIGHTNESS:
1047 c->value = dev->ctl_bright;
1048 break;
1049 case V4L2_CID_HUE:
1050 c->value = dev->ctl_hue;
1051 break;
1052 case V4L2_CID_CONTRAST:
1053 c->value = dev->ctl_contrast;
1054 break;
1055 case V4L2_CID_SATURATION:
1056 c->value = dev->ctl_saturation;
1057 break;
1058 case V4L2_CID_AUDIO_MUTE:
1059 c->value = dev->ctl_mute;
1060 break;
1061 case V4L2_CID_AUDIO_VOLUME:
1062 c->value = dev->ctl_volume;
1063 break;
1064 case V4L2_CID_PRIVATE_INVERT:
1065 c->value = dev->ctl_invert;
1066 break;
1067 case V4L2_CID_VFLIP:
1068 c->value = dev->ctl_mirror;
1069 break;
1070 case V4L2_CID_PRIVATE_Y_EVEN:
1071 c->value = dev->ctl_y_even;
1072 break;
1073 case V4L2_CID_PRIVATE_Y_ODD:
1074 c->value = dev->ctl_y_odd;
1075 break;
1076 case V4L2_CID_PRIVATE_AUTOMUTE:
1077 c->value = dev->ctl_automute;
1078 break;
1079 default:
1080 return -EINVAL;
1081 }
1082 return 0;
1083}
1084
1085static int set_control(struct saa7134_dev *dev, struct saa7134_fh *fh,
1086 struct v4l2_control *c)
1087{
1088 const struct v4l2_queryctrl* ctrl;
1089 unsigned long flags;
1090 int restart_overlay = 0;
1091
1092 ctrl = ctrl_by_id(c->id);
1093 if (NULL == ctrl)
1094 return -EINVAL;
1095 dprintk("set_control name=%s val=%d\n",ctrl->name,c->value);
1096 switch (ctrl->type) {
1097 case V4L2_CTRL_TYPE_BOOLEAN:
1098 case V4L2_CTRL_TYPE_MENU:
1099 case V4L2_CTRL_TYPE_INTEGER:
1100 if (c->value < ctrl->minimum)
1101 c->value = ctrl->minimum;
1102 if (c->value > ctrl->maximum)
1103 c->value = ctrl->maximum;
1104 break;
1105 default:
1106 /* nothing */;
1107 };
1108 switch (c->id) {
1109 case V4L2_CID_BRIGHTNESS:
1110 dev->ctl_bright = c->value;
1111 saa_writeb(SAA7134_DEC_LUMA_BRIGHT, dev->ctl_bright);
1112 break;
1113 case V4L2_CID_HUE:
1114 dev->ctl_hue = c->value;
1115 saa_writeb(SAA7134_DEC_CHROMA_HUE, dev->ctl_hue);
1116 break;
1117 case V4L2_CID_CONTRAST:
1118 dev->ctl_contrast = c->value;
1119 saa_writeb(SAA7134_DEC_LUMA_CONTRAST,
1120 dev->ctl_invert ? -dev->ctl_contrast : dev->ctl_contrast);
1121 break;
1122 case V4L2_CID_SATURATION:
1123 dev->ctl_saturation = c->value;
1124 saa_writeb(SAA7134_DEC_CHROMA_SATURATION,
1125 dev->ctl_invert ? -dev->ctl_saturation : dev->ctl_saturation);
1126 break;
1127 case V4L2_CID_AUDIO_MUTE:
1128 dev->ctl_mute = c->value;
1129 saa7134_tvaudio_setmute(dev);
1130 break;
1131 case V4L2_CID_AUDIO_VOLUME:
1132 dev->ctl_volume = c->value;
1133 saa7134_tvaudio_setvolume(dev,dev->ctl_volume);
1134 break;
1135 case V4L2_CID_PRIVATE_INVERT:
1136 dev->ctl_invert = c->value;
1137 saa_writeb(SAA7134_DEC_LUMA_CONTRAST,
1138 dev->ctl_invert ? -dev->ctl_contrast : dev->ctl_contrast);
1139 saa_writeb(SAA7134_DEC_CHROMA_SATURATION,
1140 dev->ctl_invert ? -dev->ctl_saturation : dev->ctl_saturation);
1141 break;
1142 case V4L2_CID_VFLIP:
1143 dev->ctl_mirror = c->value;
1144 restart_overlay = 1;
1145 break;
1146 case V4L2_CID_PRIVATE_Y_EVEN:
1147 dev->ctl_y_even = c->value;
1148 restart_overlay = 1;
1149 break;
1150 case V4L2_CID_PRIVATE_Y_ODD:
1151 dev->ctl_y_odd = c->value;
1152 restart_overlay = 1;
1153 break;
1154 case V4L2_CID_PRIVATE_AUTOMUTE:
1155 dev->ctl_automute = c->value;
1156 if (dev->tda9887_conf) {
1157 if (dev->ctl_automute)
1158 dev->tda9887_conf |= TDA9887_AUTOMUTE;
1159 else
1160 dev->tda9887_conf &= ~TDA9887_AUTOMUTE;
1161 saa7134_i2c_call_clients(dev, TDA9887_SET_CONFIG,
1162 &dev->tda9887_conf);
1163 }
1164 break;
1165 default:
1166 return -EINVAL;
1167 }
1168 if (restart_overlay && fh && res_check(fh, RESOURCE_OVERLAY)) {
1169 spin_lock_irqsave(&dev->slock,flags);
1170 stop_preview(dev,fh);
1171 start_preview(dev,fh);
1172 spin_unlock_irqrestore(&dev->slock,flags);
1173 }
1174 return 0;
1175}
1176
1177/* ------------------------------------------------------------------ */
1178
1179static struct videobuf_queue* saa7134_queue(struct saa7134_fh *fh)
1180{
1181 struct videobuf_queue* q = NULL;
1182
1183 switch (fh->type) {
1184 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1185 q = &fh->cap;
1186 break;
1187 case V4L2_BUF_TYPE_VBI_CAPTURE:
1188 q = &fh->vbi;
1189 break;
1190 default:
1191 BUG();
1192 }
1193 return q;
1194}
1195
1196static int saa7134_resource(struct saa7134_fh *fh)
1197{
1198 int res = 0;
1199
1200 switch (fh->type) {
1201 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1202 res = RESOURCE_VIDEO;
1203 break;
1204 case V4L2_BUF_TYPE_VBI_CAPTURE:
1205 res = RESOURCE_VBI;
1206 break;
1207 default:
1208 BUG();
1209 }
1210 return res;
1211}
1212
1213static int video_open(struct inode *inode, struct file *file)
1214{
1215 int minor = iminor(inode);
1216 struct saa7134_dev *h,*dev = NULL;
1217 struct saa7134_fh *fh;
1218 struct list_head *list;
1219 enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1220 int radio = 0;
1221
1222 list_for_each(list,&saa7134_devlist) {
1223 h = list_entry(list, struct saa7134_dev, devlist);
1224 if (h->video_dev && (h->video_dev->minor == minor))
1225 dev = h;
1226 if (h->radio_dev && (h->radio_dev->minor == minor)) {
1227 radio = 1;
1228 dev = h;
1229 }
1230 if (h->vbi_dev && (h->vbi_dev->minor == minor)) {
1231 type = V4L2_BUF_TYPE_VBI_CAPTURE;
1232 dev = h;
1233 }
1234 }
1235 if (NULL == dev)
1236 return -ENODEV;
1237
1238 dprintk("open minor=%d radio=%d type=%s\n",minor,radio,
1239 v4l2_type_names[type]);
1240
1241 /* allocate + initialize per filehandle data */
1242 fh = kmalloc(sizeof(*fh),GFP_KERNEL);
1243 if (NULL == fh)
1244 return -ENOMEM;
1245 memset(fh,0,sizeof(*fh));
1246 file->private_data = fh;
1247 fh->dev = dev;
1248 fh->radio = radio;
1249 fh->type = type;
1250 fh->fmt = format_by_fourcc(V4L2_PIX_FMT_BGR24);
1251 fh->width = 720;
1252 fh->height = 576;
1253 v4l2_prio_open(&dev->prio,&fh->prio);
1254
1255 videobuf_queue_init(&fh->cap, &video_qops,
1256 dev->pci, &dev->slock,
1257 V4L2_BUF_TYPE_VIDEO_CAPTURE,
1258 V4L2_FIELD_INTERLACED,
1259 sizeof(struct saa7134_buf),
1260 fh);
1261 videobuf_queue_init(&fh->vbi, &saa7134_vbi_qops,
1262 dev->pci, &dev->slock,
1263 V4L2_BUF_TYPE_VBI_CAPTURE,
1264 V4L2_FIELD_SEQ_TB,
1265 sizeof(struct saa7134_buf),
1266 fh);
1267 saa7134_pgtable_alloc(dev->pci,&fh->pt_cap);
1268 saa7134_pgtable_alloc(dev->pci,&fh->pt_vbi);
1269
1270 if (fh->radio) {
1271 /* switch to radio mode */
1272 saa7134_tvaudio_setinput(dev,&card(dev).radio);
1273 saa7134_i2c_call_clients(dev,AUDC_SET_RADIO,NULL);
1274 } else {
1275 /* switch to video/vbi mode */
1276 video_mux(dev,dev->ctl_input);
1277 }
1278 return 0;
1279}
1280
1281static ssize_t
1282video_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
1283{
1284 struct saa7134_fh *fh = file->private_data;
1285
1286 switch (fh->type) {
1287 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1288 if (res_locked(fh->dev,RESOURCE_VIDEO))
1289 return -EBUSY;
1290 return videobuf_read_one(saa7134_queue(fh),
1291 data, count, ppos,
1292 file->f_flags & O_NONBLOCK);
1293 case V4L2_BUF_TYPE_VBI_CAPTURE:
1294 if (!res_get(fh->dev,fh,RESOURCE_VBI))
1295 return -EBUSY;
1296 return videobuf_read_stream(saa7134_queue(fh),
1297 data, count, ppos, 1,
1298 file->f_flags & O_NONBLOCK);
1299 break;
1300 default:
1301 BUG();
1302 return 0;
1303 }
1304}
1305
1306static unsigned int
1307video_poll(struct file *file, struct poll_table_struct *wait)
1308{
1309 struct saa7134_fh *fh = file->private_data;
1310 struct videobuf_buffer *buf = NULL;
1311
1312 if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type)
1313 return videobuf_poll_stream(file, &fh->vbi, wait);
1314
1315 if (res_check(fh,RESOURCE_VIDEO)) {
1316 if (!list_empty(&fh->cap.stream))
1317 buf = list_entry(fh->cap.stream.next, struct videobuf_buffer, stream);
1318 } else {
1319 down(&fh->cap.lock);
1320 if (UNSET == fh->cap.read_off) {
1321 /* need to capture a new frame */
1322 if (res_locked(fh->dev,RESOURCE_VIDEO)) {
1323 up(&fh->cap.lock);
1324 return POLLERR;
1325 }
1326 if (0 != fh->cap.ops->buf_prepare(&fh->cap,fh->cap.read_buf,fh->cap.field)) {
1327 up(&fh->cap.lock);
1328 return POLLERR;
1329 }
1330 fh->cap.ops->buf_queue(&fh->cap,fh->cap.read_buf);
1331 fh->cap.read_off = 0;
1332 }
1333 up(&fh->cap.lock);
1334 buf = fh->cap.read_buf;
1335 }
1336
1337 if (!buf)
1338 return POLLERR;
1339
1340 poll_wait(file, &buf->done, wait);
1341 if (buf->state == STATE_DONE ||
1342 buf->state == STATE_ERROR)
1343 return POLLIN|POLLRDNORM;
1344 return 0;
1345}
1346
1347static int video_release(struct inode *inode, struct file *file)
1348{
1349 struct saa7134_fh *fh = file->private_data;
1350 struct saa7134_dev *dev = fh->dev;
1351 unsigned long flags;
1352
1353 /* turn off overlay */
1354 if (res_check(fh, RESOURCE_OVERLAY)) {
1355 spin_lock_irqsave(&dev->slock,flags);
1356 stop_preview(dev,fh);
1357 spin_unlock_irqrestore(&dev->slock,flags);
1358 res_free(dev,fh,RESOURCE_OVERLAY);
1359 }
1360
1361 /* stop video capture */
1362 if (res_check(fh, RESOURCE_VIDEO)) {
1363 videobuf_streamoff(&fh->cap);
1364 res_free(dev,fh,RESOURCE_VIDEO);
1365 }
1366 if (fh->cap.read_buf) {
1367 buffer_release(&fh->cap,fh->cap.read_buf);
1368 kfree(fh->cap.read_buf);
1369 }
1370
1371 /* stop vbi capture */
1372 if (res_check(fh, RESOURCE_VBI)) {
1373 if (fh->vbi.streaming)
1374 videobuf_streamoff(&fh->vbi);
1375 if (fh->vbi.reading)
1376 videobuf_read_stop(&fh->vbi);
1377 res_free(dev,fh,RESOURCE_VBI);
1378 }
1379
1380 /* free stuff */
1381 videobuf_mmap_free(&fh->cap);
1382 videobuf_mmap_free(&fh->vbi);
1383 saa7134_pgtable_free(dev->pci,&fh->pt_cap);
1384 saa7134_pgtable_free(dev->pci,&fh->pt_vbi);
1385
1386 v4l2_prio_close(&dev->prio,&fh->prio);
1387 file->private_data = NULL;
1388 kfree(fh);
1389 return 0;
1390}
1391
1392static int
1393video_mmap(struct file *file, struct vm_area_struct * vma)
1394{
1395 struct saa7134_fh *fh = file->private_data;
1396
1397 return videobuf_mmap_mapper(saa7134_queue(fh), vma);
1398}
1399
1400/* ------------------------------------------------------------------ */
1401
1402static void saa7134_vbi_fmt(struct saa7134_dev *dev, struct v4l2_format *f)
1403{
1404 struct saa7134_tvnorm *norm = dev->tvnorm;
1405
1406 f->fmt.vbi.sampling_rate = 6750000 * 4;
1407 f->fmt.vbi.samples_per_line = 2048 /* VBI_LINE_LENGTH */;
1408 f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
1409 f->fmt.vbi.offset = 64 * 4;
1410 f->fmt.vbi.start[0] = norm->vbi_v_start;
1411 f->fmt.vbi.count[0] = norm->vbi_v_stop - norm->vbi_v_start +1;
1412 f->fmt.vbi.start[1] = norm->video_v_stop + norm->vbi_v_start +1;
1413 f->fmt.vbi.count[1] = f->fmt.vbi.count[0];
1414 f->fmt.vbi.flags = 0; /* VBI_UNSYNC VBI_INTERLACED */
1415
1416#if 0
1417 if (V4L2_STD_PAL == norm->id) {
1418 /* FIXME */
1419 f->fmt.vbi.start[0] += 3;
1420 f->fmt.vbi.start[1] += 3*2;
1421 }
1422#endif
1423}
1424
1425static int saa7134_g_fmt(struct saa7134_dev *dev, struct saa7134_fh *fh,
1426 struct v4l2_format *f)
1427{
1428 switch (f->type) {
1429 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1430 memset(&f->fmt.pix,0,sizeof(f->fmt.pix));
1431 f->fmt.pix.width = fh->width;
1432 f->fmt.pix.height = fh->height;
1433 f->fmt.pix.field = fh->cap.field;
1434 f->fmt.pix.pixelformat = fh->fmt->fourcc;
1435 f->fmt.pix.bytesperline =
1436 (f->fmt.pix.width * fh->fmt->depth) >> 3;
1437 f->fmt.pix.sizeimage =
1438 f->fmt.pix.height * f->fmt.pix.bytesperline;
1439 return 0;
1440 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
1441 f->fmt.win = fh->win;
1442 return 0;
1443 case V4L2_BUF_TYPE_VBI_CAPTURE:
1444 saa7134_vbi_fmt(dev,f);
1445 return 0;
1446 default:
1447 return -EINVAL;
1448 }
1449}
1450
1451static int saa7134_try_fmt(struct saa7134_dev *dev, struct saa7134_fh *fh,
1452 struct v4l2_format *f)
1453{
1454 int err;
1455
1456 switch (f->type) {
1457 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1458 {
1459 struct saa7134_format *fmt;
1460 enum v4l2_field field;
1461 unsigned int maxw, maxh;
1462
1463 fmt = format_by_fourcc(f->fmt.pix.pixelformat);
1464 if (NULL == fmt)
1465 return -EINVAL;
1466
1467 field = f->fmt.pix.field;
1468 maxw = min(dev->crop_current.width*4, dev->crop_bounds.width);
1469 maxh = min(dev->crop_current.height*4, dev->crop_bounds.height);
1470
1471 if (V4L2_FIELD_ANY == field) {
1472 field = (f->fmt.pix.height > maxh/2)
1473 ? V4L2_FIELD_INTERLACED
1474 : V4L2_FIELD_BOTTOM;
1475 }
1476 switch (field) {
1477 case V4L2_FIELD_TOP:
1478 case V4L2_FIELD_BOTTOM:
1479 maxh = maxh / 2;
1480 break;
1481 case V4L2_FIELD_INTERLACED:
1482 break;
1483 default:
1484 return -EINVAL;
1485 }
1486
1487 f->fmt.pix.field = field;
1488 if (f->fmt.pix.width < 48)
1489 f->fmt.pix.width = 48;
1490 if (f->fmt.pix.height < 32)
1491 f->fmt.pix.height = 32;
1492 if (f->fmt.pix.width > maxw)
1493 f->fmt.pix.width = maxw;
1494 if (f->fmt.pix.height > maxh)
1495 f->fmt.pix.height = maxh;
1496 f->fmt.pix.width &= ~0x03;
1497 f->fmt.pix.bytesperline =
1498 (f->fmt.pix.width * fmt->depth) >> 3;
1499 f->fmt.pix.sizeimage =
1500 f->fmt.pix.height * f->fmt.pix.bytesperline;
1501
1502 return 0;
1503 }
1504 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
1505 err = verify_preview(dev,&f->fmt.win);
1506 if (0 != err)
1507 return err;
1508 return 0;
1509 case V4L2_BUF_TYPE_VBI_CAPTURE:
1510 saa7134_vbi_fmt(dev,f);
1511 return 0;
1512 default:
1513 return -EINVAL;
1514 }
1515}
1516
1517static int saa7134_s_fmt(struct saa7134_dev *dev, struct saa7134_fh *fh,
1518 struct v4l2_format *f)
1519{
1520 unsigned long flags;
1521 int err;
1522
1523 switch (f->type) {
1524 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1525 err = saa7134_try_fmt(dev,fh,f);
1526 if (0 != err)
1527 return err;
1528
1529 fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
1530 fh->width = f->fmt.pix.width;
1531 fh->height = f->fmt.pix.height;
1532 fh->cap.field = f->fmt.pix.field;
1533 return 0;
1534 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
1535 err = verify_preview(dev,&f->fmt.win);
1536 if (0 != err)
1537 return err;
1538
1539 down(&dev->lock);
1540 fh->win = f->fmt.win;
1541 fh->nclips = f->fmt.win.clipcount;
1542 if (fh->nclips > 8)
1543 fh->nclips = 8;
1544 if (copy_from_user(fh->clips,f->fmt.win.clips,
1545 sizeof(struct v4l2_clip)*fh->nclips)) {
1546 up(&dev->lock);
1547 return -EFAULT;
1548 }
1549
1550 if (res_check(fh, RESOURCE_OVERLAY)) {
1551 spin_lock_irqsave(&dev->slock,flags);
1552 stop_preview(dev,fh);
1553 start_preview(dev,fh);
1554 spin_unlock_irqrestore(&dev->slock,flags);
1555 }
1556 up(&dev->lock);
1557 return 0;
1558 case V4L2_BUF_TYPE_VBI_CAPTURE:
1559 saa7134_vbi_fmt(dev,f);
1560 return 0;
1561 default:
1562 return -EINVAL;
1563 }
1564}
1565
1566int saa7134_common_ioctl(struct saa7134_dev *dev,
1567 unsigned int cmd, void *arg)
1568{
1569 int err;
1570
1571 switch (cmd) {
1572 case VIDIOC_QUERYCTRL:
1573 {
1574 const struct v4l2_queryctrl *ctrl;
1575 struct v4l2_queryctrl *c = arg;
1576
1577 if ((c->id < V4L2_CID_BASE ||
1578 c->id >= V4L2_CID_LASTP1) &&
1579 (c->id < V4L2_CID_PRIVATE_BASE ||
1580 c->id >= V4L2_CID_PRIVATE_LASTP1))
1581 return -EINVAL;
1582 ctrl = ctrl_by_id(c->id);
1583 *c = (NULL != ctrl) ? *ctrl : no_ctrl;
1584 return 0;
1585 }
1586 case VIDIOC_G_CTRL:
1587 return get_control(dev,arg);
1588 case VIDIOC_S_CTRL:
1589 {
1590 down(&dev->lock);
1591 err = set_control(dev,NULL,arg);
1592 up(&dev->lock);
1593 return err;
1594 }
1595 /* --- input switching --------------------------------------- */
1596 case VIDIOC_ENUMINPUT:
1597 {
1598 struct v4l2_input *i = arg;
1599 unsigned int n;
1600
1601 n = i->index;
1602 if (n >= SAA7134_INPUT_MAX)
1603 return -EINVAL;
1604 if (NULL == card_in(dev,i->index).name)
1605 return -EINVAL;
1606 memset(i,0,sizeof(*i));
1607 i->index = n;
1608 i->type = V4L2_INPUT_TYPE_CAMERA;
1609 strcpy(i->name,card_in(dev,n).name);
1610 if (card_in(dev,n).tv)
1611 i->type = V4L2_INPUT_TYPE_TUNER;
1612 i->audioset = 1;
1613 if (n == dev->ctl_input) {
1614 int v1 = saa_readb(SAA7134_STATUS_VIDEO1);
1615 int v2 = saa_readb(SAA7134_STATUS_VIDEO2);
1616
1617 if (0 != (v1 & 0x40))
1618 i->status |= V4L2_IN_ST_NO_H_LOCK;
1619 if (0 != (v2 & 0x40))
1620 i->status |= V4L2_IN_ST_NO_SYNC;
1621 if (0 != (v2 & 0x0e))
1622 i->status |= V4L2_IN_ST_MACROVISION;
1623 }
1624 for (n = 0; n < TVNORMS; n++)
1625 i->std |= tvnorms[n].id;
1626 return 0;
1627 }
1628 case VIDIOC_G_INPUT:
1629 {
1630 int *i = arg;
1631 *i = dev->ctl_input;
1632 return 0;
1633 }
1634 case VIDIOC_S_INPUT:
1635 {
1636 int *i = arg;
1637
1638 if (*i < 0 || *i >= SAA7134_INPUT_MAX)
1639 return -EINVAL;
1640 if (NULL == card_in(dev,*i).name)
1641 return -EINVAL;
1642 down(&dev->lock);
1643 video_mux(dev,*i);
1644 up(&dev->lock);
1645 return 0;
1646 }
1647
1648 }
1649 return 0;
1650}
1651EXPORT_SYMBOL(saa7134_common_ioctl);
1652
1653/*
1654 * This function is _not_ called directly, but from
1655 * video_generic_ioctl (and maybe others). userspace
1656 * copying is done already, arg is a kernel pointer.
1657 */
1658static int video_do_ioctl(struct inode *inode, struct file *file,
1659 unsigned int cmd, void *arg)
1660{
1661 struct saa7134_fh *fh = file->private_data;
1662 struct saa7134_dev *dev = fh->dev;
1663 unsigned long flags;
1664 int err;
1665
1666 if (video_debug > 1)
1667 saa7134_print_ioctl(dev->name,cmd);
1668
1669 switch (cmd) {
1670 case VIDIOC_S_CTRL:
1671 case VIDIOC_S_STD:
1672 case VIDIOC_S_INPUT:
1673 case VIDIOC_S_TUNER:
1674 case VIDIOC_S_FREQUENCY:
1675 err = v4l2_prio_check(&dev->prio,&fh->prio);
1676 if (0 != err)
1677 return err;
1678 }
1679
1680 switch (cmd) {
1681 case VIDIOC_QUERYCAP:
1682 {
1683 struct v4l2_capability *cap = arg;
1684
1685 memset(cap,0,sizeof(*cap));
1686 strcpy(cap->driver, "saa7134");
1687 strlcpy(cap->card, saa7134_boards[dev->board].name,
1688 sizeof(cap->card));
1689 sprintf(cap->bus_info,"PCI:%s",pci_name(dev->pci));
1690 cap->version = SAA7134_VERSION_CODE;
1691 cap->capabilities =
1692 V4L2_CAP_VIDEO_CAPTURE |
1693 V4L2_CAP_VIDEO_OVERLAY |
1694 V4L2_CAP_VBI_CAPTURE |
1695 V4L2_CAP_TUNER |
1696 V4L2_CAP_READWRITE |
1697 V4L2_CAP_STREAMING;
1698 return 0;
1699 }
1700
1701 /* --- tv standards ------------------------------------------ */
1702 case VIDIOC_ENUMSTD:
1703 {
1704 struct v4l2_standard *e = arg;
1705 unsigned int i;
1706
1707 i = e->index;
1708 if (i >= TVNORMS)
1709 return -EINVAL;
1710 err = v4l2_video_std_construct(e, tvnorms[e->index].id,
1711 tvnorms[e->index].name);
1712 e->index = i;
1713 if (err < 0)
1714 return err;
1715 return 0;
1716 }
1717 case VIDIOC_G_STD:
1718 {
1719 v4l2_std_id *id = arg;
1720
1721 *id = dev->tvnorm->id;
1722 return 0;
1723 }
1724 case VIDIOC_S_STD:
1725 {
1726 v4l2_std_id *id = arg;
1727 unsigned int i;
1728
1729 for (i = 0; i < TVNORMS; i++)
1730 if (*id == tvnorms[i].id)
1731 break;
1732 if (i == TVNORMS)
1733 for (i = 0; i < TVNORMS; i++)
1734 if (*id & tvnorms[i].id)
1735 break;
1736 if (i == TVNORMS)
1737 return -EINVAL;
1738
1739 down(&dev->lock);
1740 if (res_check(fh, RESOURCE_OVERLAY)) {
1741 spin_lock_irqsave(&dev->slock,flags);
1742 stop_preview(dev,fh);
1743 set_tvnorm(dev,&tvnorms[i]);
1744 start_preview(dev,fh);
1745 spin_unlock_irqrestore(&dev->slock,flags);
1746 } else
1747 set_tvnorm(dev,&tvnorms[i]);
1748 saa7134_tvaudio_do_scan(dev);
1749 up(&dev->lock);
1750 return 0;
1751 }
1752
1753 case VIDIOC_CROPCAP:
1754 {
1755 struct v4l2_cropcap *cap = arg;
1756
1757 if (cap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
1758 cap->type != V4L2_BUF_TYPE_VIDEO_OVERLAY)
1759 return -EINVAL;
1760 cap->bounds = dev->crop_bounds;
1761 cap->defrect = dev->crop_defrect;
1762 cap->pixelaspect.numerator = 1;
1763 cap->pixelaspect.denominator = 1;
1764 if (dev->tvnorm->id & V4L2_STD_525_60) {
1765 cap->pixelaspect.numerator = 11;
1766 cap->pixelaspect.denominator = 10;
1767 }
1768 if (dev->tvnorm->id & V4L2_STD_625_50) {
1769 cap->pixelaspect.numerator = 54;
1770 cap->pixelaspect.denominator = 59;
1771 }
1772 return 0;
1773 }
1774
1775 case VIDIOC_G_CROP:
1776 {
1777 struct v4l2_crop * crop = arg;
1778
1779 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
1780 crop->type != V4L2_BUF_TYPE_VIDEO_OVERLAY)
1781 return -EINVAL;
1782 crop->c = dev->crop_current;
1783 return 0;
1784 }
1785 case VIDIOC_S_CROP:
1786 {
1787 struct v4l2_crop *crop = arg;
1788 struct v4l2_rect *b = &dev->crop_bounds;
1789
1790 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
1791 crop->type != V4L2_BUF_TYPE_VIDEO_OVERLAY)
1792 return -EINVAL;
1793 if (crop->c.height < 0)
1794 return -EINVAL;
1795 if (crop->c.width < 0)
1796 return -EINVAL;
1797
1798 if (res_locked(fh->dev,RESOURCE_OVERLAY))
1799 return -EBUSY;
1800 if (res_locked(fh->dev,RESOURCE_VIDEO))
1801 return -EBUSY;
1802
1803 if (crop->c.top < b->top)
1804 crop->c.top = b->top;
1805 if (crop->c.top > b->top + b->height)
1806 crop->c.top = b->top + b->height;
1807 if (crop->c.height > b->top - crop->c.top + b->height)
1808 crop->c.height = b->top - crop->c.top + b->height;
1809
1810 if (crop->c.left < b->left)
1811 crop->c.top = b->left;
1812 if (crop->c.left > b->left + b->width)
1813 crop->c.top = b->left + b->width;
1814 if (crop->c.width > b->left - crop->c.left + b->width)
1815 crop->c.width = b->left - crop->c.left + b->width;
1816
1817 dev->crop_current = crop->c;
1818 return 0;
1819 }
1820
1821 /* --- tuner ioctls ------------------------------------------ */
1822 case VIDIOC_G_TUNER:
1823 {
1824 struct v4l2_tuner *t = arg;
1825 int n;
1826
1827 if (0 != t->index)
1828 return -EINVAL;
1829 memset(t,0,sizeof(*t));
1830 for (n = 0; n < SAA7134_INPUT_MAX; n++)
1831 if (card_in(dev,n).tv)
1832 break;
1833 if (NULL != card_in(dev,n).name) {
1834 strcpy(t->name, "Television");
1835 t->capability = V4L2_TUNER_CAP_NORM |
1836 V4L2_TUNER_CAP_STEREO |
1837 V4L2_TUNER_CAP_LANG1 |
1838 V4L2_TUNER_CAP_LANG2;
1839 t->rangehigh = 0xffffffffUL;
1840 t->rxsubchans = saa7134_tvaudio_getstereo(dev);
1841 t->audmode = saa7134_tvaudio_rx2mode(t->rxsubchans);
1842 }
1843 if (0 != (saa_readb(SAA7134_STATUS_VIDEO1) & 0x03))
1844 t->signal = 0xffff;
1845 return 0;
1846 }
1847 case VIDIOC_S_TUNER:
1848 {
1849 struct v4l2_tuner *t = arg;
1850 int rx,mode;
1851
1852 mode = dev->thread.mode;
1853 if (UNSET == mode) {
1854 rx = saa7134_tvaudio_getstereo(dev);
1855 mode = saa7134_tvaudio_rx2mode(t->rxsubchans);
1856 }
1857 if (mode != t->audmode) {
1858 dev->thread.mode = t->audmode;
1859 }
1860 return 0;
1861 }
1862 case VIDIOC_G_FREQUENCY:
1863 {
1864 struct v4l2_frequency *f = arg;
1865
1866 memset(f,0,sizeof(*f));
1867 f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
1868 f->frequency = dev->ctl_freq;
1869 return 0;
1870 }
1871 case VIDIOC_S_FREQUENCY:
1872 {
1873 struct v4l2_frequency *f = arg;
1874
1875 if (0 != f->tuner)
1876 return -EINVAL;
1877 if (0 == fh->radio && V4L2_TUNER_ANALOG_TV != f->type)
1878 return -EINVAL;
1879 if (1 == fh->radio && V4L2_TUNER_RADIO != f->type)
1880 return -EINVAL;
1881 down(&dev->lock);
1882 dev->ctl_freq = f->frequency;
1883#ifdef V4L2_I2C_CLIENTS
1884 saa7134_i2c_call_clients(dev,VIDIOC_S_FREQUENCY,f);
1885#else
1886 saa7134_i2c_call_clients(dev,VIDIOCSFREQ,&dev->ctl_freq);
1887#endif
1888 saa7134_tvaudio_do_scan(dev);
1889 up(&dev->lock);
1890 return 0;
1891 }
1892
1893 /* --- control ioctls ---------------------------------------- */
1894 case VIDIOC_ENUMINPUT:
1895 case VIDIOC_G_INPUT:
1896 case VIDIOC_S_INPUT:
1897 case VIDIOC_QUERYCTRL:
1898 case VIDIOC_G_CTRL:
1899 case VIDIOC_S_CTRL:
1900 return saa7134_common_ioctl(dev, cmd, arg);
1901
1902 case VIDIOC_G_AUDIO:
1903 {
1904 struct v4l2_audio *a = arg;
1905
1906 memset(a,0,sizeof(*a));
1907 strcpy(a->name,"audio");
1908 return 0;
1909 }
1910 case VIDIOC_S_AUDIO:
1911 return 0;
1912 case VIDIOC_G_PARM:
1913 {
1914 struct v4l2_captureparm *parm = arg;
1915 memset(parm,0,sizeof(*parm));
1916 return 0;
1917 }
1918
1919 case VIDIOC_G_PRIORITY:
1920 {
1921 enum v4l2_priority *p = arg;
1922
1923 *p = v4l2_prio_max(&dev->prio);
1924 return 0;
1925 }
1926 case VIDIOC_S_PRIORITY:
1927 {
1928 enum v4l2_priority *prio = arg;
1929
1930 return v4l2_prio_change(&dev->prio, &fh->prio, *prio);
1931 }
1932
1933 /* --- preview ioctls ---------------------------------------- */
1934 case VIDIOC_ENUM_FMT:
1935 {
1936 struct v4l2_fmtdesc *f = arg;
1937 enum v4l2_buf_type type;
1938 unsigned int index;
1939
1940 index = f->index;
1941 type = f->type;
1942 switch (type) {
1943 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1944 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
1945 if (index >= FORMATS)
1946 return -EINVAL;
1947 if (f->type == V4L2_BUF_TYPE_VIDEO_OVERLAY &&
1948 formats[index].planar)
1949 return -EINVAL;
1950 memset(f,0,sizeof(*f));
1951 f->index = index;
1952 f->type = type;
1953 strlcpy(f->description,formats[index].name,sizeof(f->description));
1954 f->pixelformat = formats[index].fourcc;
1955 break;
1956 case V4L2_BUF_TYPE_VBI_CAPTURE:
1957 if (0 != index)
1958 return -EINVAL;
1959 memset(f,0,sizeof(*f));
1960 f->index = index;
1961 f->type = type;
1962 f->pixelformat = V4L2_PIX_FMT_GREY;
1963 strcpy(f->description,"vbi data");
1964 break;
1965 default:
1966 return -EINVAL;
1967 }
1968 return 0;
1969 }
1970 case VIDIOC_G_FBUF:
1971 {
1972 struct v4l2_framebuffer *fb = arg;
1973
1974 *fb = dev->ovbuf;
1975 fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING;
1976 return 0;
1977 }
1978 case VIDIOC_S_FBUF:
1979 {
1980 struct v4l2_framebuffer *fb = arg;
1981 struct saa7134_format *fmt;
1982
1983 if(!capable(CAP_SYS_ADMIN) &&
1984 !capable(CAP_SYS_RAWIO))
1985 return -EPERM;
1986
1987 /* check args */
1988 fmt = format_by_fourcc(fb->fmt.pixelformat);
1989 if (NULL == fmt)
1990 return -EINVAL;
1991
1992 /* ok, accept it */
1993 dev->ovbuf = *fb;
1994 dev->ovfmt = fmt;
1995 if (0 == dev->ovbuf.fmt.bytesperline)
1996 dev->ovbuf.fmt.bytesperline =
1997 dev->ovbuf.fmt.width*fmt->depth/8;
1998 return 0;
1999 }
2000 case VIDIOC_OVERLAY:
2001 {
2002 int *on = arg;
2003
2004 if (*on) {
2005 if (!res_get(dev,fh,RESOURCE_OVERLAY))
2006 return -EBUSY;
2007 spin_lock_irqsave(&dev->slock,flags);
2008 start_preview(dev,fh);
2009 spin_unlock_irqrestore(&dev->slock,flags);
2010 }
2011 if (!*on) {
2012 if (!res_check(fh, RESOURCE_OVERLAY))
2013 return -EINVAL;
2014 spin_lock_irqsave(&dev->slock,flags);
2015 stop_preview(dev,fh);
2016 spin_unlock_irqrestore(&dev->slock,flags);
2017 res_free(dev,fh,RESOURCE_OVERLAY);
2018 }
2019 return 0;
2020 }
2021
2022 /* --- capture ioctls ---------------------------------------- */
2023 case VIDIOC_G_FMT:
2024 {
2025 struct v4l2_format *f = arg;
2026 return saa7134_g_fmt(dev,fh,f);
2027 }
2028 case VIDIOC_S_FMT:
2029 {
2030 struct v4l2_format *f = arg;
2031 return saa7134_s_fmt(dev,fh,f);
2032 }
2033 case VIDIOC_TRY_FMT:
2034 {
2035 struct v4l2_format *f = arg;
2036 return saa7134_try_fmt(dev,fh,f);
2037 }
2038
2039 case VIDIOCGMBUF:
2040 {
2041 struct video_mbuf *mbuf = arg;
2042 struct videobuf_queue *q;
2043 struct v4l2_requestbuffers req;
2044 unsigned int i;
2045
2046 q = saa7134_queue(fh);
2047 memset(&req,0,sizeof(req));
2048 req.type = q->type;
2049 req.count = gbuffers;
2050 req.memory = V4L2_MEMORY_MMAP;
2051 err = videobuf_reqbufs(q,&req);
2052 if (err < 0)
2053 return err;
2054 memset(mbuf,0,sizeof(*mbuf));
2055 mbuf->frames = req.count;
2056 mbuf->size = 0;
2057 for (i = 0; i < mbuf->frames; i++) {
2058 mbuf->offsets[i] = q->bufs[i]->boff;
2059 mbuf->size += q->bufs[i]->bsize;
2060 }
2061 return 0;
2062 }
2063 case VIDIOC_REQBUFS:
2064 return videobuf_reqbufs(saa7134_queue(fh),arg);
2065
2066 case VIDIOC_QUERYBUF:
2067 return videobuf_querybuf(saa7134_queue(fh),arg);
2068
2069 case VIDIOC_QBUF:
2070 return videobuf_qbuf(saa7134_queue(fh),arg);
2071
2072 case VIDIOC_DQBUF:
2073 return videobuf_dqbuf(saa7134_queue(fh),arg,
2074 file->f_flags & O_NONBLOCK);
2075
2076 case VIDIOC_STREAMON:
2077 {
2078 int res = saa7134_resource(fh);
2079
2080 if (!res_get(dev,fh,res))
2081 return -EBUSY;
2082 return videobuf_streamon(saa7134_queue(fh));
2083 }
2084 case VIDIOC_STREAMOFF:
2085 {
2086 int res = saa7134_resource(fh);
2087
2088 err = videobuf_streamoff(saa7134_queue(fh));
2089 if (err < 0)
2090 return err;
2091 res_free(dev,fh,res);
2092 return 0;
2093 }
2094
2095 default:
2096 return v4l_compat_translate_ioctl(inode,file,cmd,arg,
2097 video_do_ioctl);
2098 }
2099 return 0;
2100}
2101
2102static int video_ioctl(struct inode *inode, struct file *file,
2103 unsigned int cmd, unsigned long arg)
2104{
2105 return video_usercopy(inode, file, cmd, arg, video_do_ioctl);
2106}
2107
2108static int radio_do_ioctl(struct inode *inode, struct file *file,
2109 unsigned int cmd, void *arg)
2110{
2111 struct saa7134_fh *fh = file->private_data;
2112 struct saa7134_dev *dev = fh->dev;
2113
2114 if (video_debug > 1)
2115 saa7134_print_ioctl(dev->name,cmd);
2116 switch (cmd) {
2117 case VIDIOC_QUERYCAP:
2118 {
2119 struct v4l2_capability *cap = arg;
2120
2121 memset(cap,0,sizeof(*cap));
2122 strcpy(cap->driver, "saa7134");
2123 strlcpy(cap->card, saa7134_boards[dev->board].name,
2124 sizeof(cap->card));
2125 sprintf(cap->bus_info,"PCI:%s",pci_name(dev->pci));
2126 cap->version = SAA7134_VERSION_CODE;
2127 cap->capabilities = V4L2_CAP_TUNER;
2128 return 0;
2129 }
2130 case VIDIOC_G_TUNER:
2131 {
2132 struct v4l2_tuner *t = arg;
2133
2134 if (0 != t->index)
2135 return -EINVAL;
2136
2137 memset(t,0,sizeof(*t));
2138 strcpy(t->name, "Radio");
2139 t->rangelow = (int)(65*16);
2140 t->rangehigh = (int)(108*16);
2141
2142#ifdef V4L2_I2C_CLIENTS
2143 saa7134_i2c_call_clients(dev,VIDIOC_G_TUNER,t);
2144#else
2145 {
2146 struct video_tuner vt;
2147 memset(&vt,0,sizeof(vt));
2148 saa7134_i2c_call_clients(dev,VIDIOCGTUNER,&vt);
2149 t->signal = vt.signal;
2150 }
2151#endif
2152 return 0;
2153 }
2154 case VIDIOC_ENUMINPUT:
2155 {
2156 struct v4l2_input *i = arg;
2157
2158 if (i->index != 0)
2159 return -EINVAL;
2160 strcpy(i->name,"Radio");
2161 i->type = V4L2_INPUT_TYPE_TUNER;
2162 return 0;
2163 }
2164 case VIDIOC_G_INPUT:
2165 {
2166 int *i = arg;
2167 *i = 0;
2168 return 0;
2169 }
2170 case VIDIOC_G_AUDIO:
2171 {
2172 struct v4l2_audio *a = arg;
2173
2174 memset(a,0,sizeof(*a));
2175 strcpy(a->name,"Radio");
2176 return 0;
2177 }
2178 case VIDIOC_G_STD:
2179 {
2180 v4l2_std_id *id = arg;
2181 *id = 0;
2182 return 0;
2183 }
2184 case VIDIOC_S_AUDIO:
2185 case VIDIOC_S_TUNER:
2186 case VIDIOC_S_INPUT:
2187 case VIDIOC_S_STD:
2188 return 0;
2189
2190 case VIDIOC_QUERYCTRL:
2191 {
2192 const struct v4l2_queryctrl *ctrl;
2193 struct v4l2_queryctrl *c = arg;
2194
2195 if (c->id < V4L2_CID_BASE ||
2196 c->id >= V4L2_CID_LASTP1)
2197 return -EINVAL;
2198 if (c->id == V4L2_CID_AUDIO_MUTE) {
2199 ctrl = ctrl_by_id(c->id);
2200 *c = *ctrl;
2201 } else
2202 *c = no_ctrl;
2203 return 0;
2204 }
2205
2206 case VIDIOC_G_CTRL:
2207 case VIDIOC_S_CTRL:
2208 case VIDIOC_G_FREQUENCY:
2209 case VIDIOC_S_FREQUENCY:
2210 return video_do_ioctl(inode,file,cmd,arg);
2211
2212 default:
2213 return v4l_compat_translate_ioctl(inode,file,cmd,arg,
2214 radio_do_ioctl);
2215 }
2216 return 0;
2217}
2218
2219static int radio_ioctl(struct inode *inode, struct file *file,
2220 unsigned int cmd, unsigned long arg)
2221{
2222 return video_usercopy(inode, file, cmd, arg, radio_do_ioctl);
2223}
2224
2225static struct file_operations video_fops =
2226{
2227 .owner = THIS_MODULE,
2228 .open = video_open,
2229 .release = video_release,
2230 .read = video_read,
2231 .poll = video_poll,
2232 .mmap = video_mmap,
2233 .ioctl = video_ioctl,
2234 .llseek = no_llseek,
2235};
2236
2237static struct file_operations radio_fops =
2238{
2239 .owner = THIS_MODULE,
2240 .open = video_open,
2241 .release = video_release,
2242 .ioctl = radio_ioctl,
2243 .llseek = no_llseek,
2244};
2245
2246/* ----------------------------------------------------------- */
2247/* exported stuff */
2248
2249struct video_device saa7134_video_template =
2250{
2251 .name = "saa7134-video",
2252 .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER|VID_TYPE_OVERLAY|
2253 VID_TYPE_CLIPPING|VID_TYPE_SCALES,
2254 .hardware = 0,
2255 .fops = &video_fops,
2256 .minor = -1,
2257};
2258
2259struct video_device saa7134_vbi_template =
2260{
2261 .name = "saa7134-vbi",
2262 .type = VID_TYPE_TUNER|VID_TYPE_TELETEXT,
2263 .hardware = 0,
2264 .fops = &video_fops,
2265 .minor = -1,
2266};
2267
2268struct video_device saa7134_radio_template =
2269{
2270 .name = "saa7134-radio",
2271 .type = VID_TYPE_TUNER,
2272 .hardware = 0,
2273 .fops = &radio_fops,
2274 .minor = -1,
2275};
2276
2277int saa7134_video_init1(struct saa7134_dev *dev)
2278{
2279 /* sanitycheck insmod options */
2280 if (gbuffers < 2 || gbuffers > VIDEO_MAX_FRAME)
2281 gbuffers = 2;
2282 if (gbufsize < 0 || gbufsize > gbufsize_max)
2283 gbufsize = gbufsize_max;
2284 gbufsize = (gbufsize + PAGE_SIZE - 1) & PAGE_MASK;
2285
2286 /* put some sensible defaults into the data structures ... */
2287 dev->ctl_bright = ctrl_by_id(V4L2_CID_BRIGHTNESS)->default_value;
2288 dev->ctl_contrast = ctrl_by_id(V4L2_CID_CONTRAST)->default_value;
2289 dev->ctl_hue = ctrl_by_id(V4L2_CID_HUE)->default_value;
2290 dev->ctl_saturation = ctrl_by_id(V4L2_CID_SATURATION)->default_value;
2291 dev->ctl_volume = ctrl_by_id(V4L2_CID_AUDIO_VOLUME)->default_value;
2292 dev->ctl_mute = 1; // ctrl_by_id(V4L2_CID_AUDIO_MUTE)->default_value;
2293 dev->ctl_invert = ctrl_by_id(V4L2_CID_PRIVATE_INVERT)->default_value;
2294 dev->ctl_automute = ctrl_by_id(V4L2_CID_PRIVATE_AUTOMUTE)->default_value;
2295
2296 if (dev->tda9887_conf && dev->ctl_automute)
2297 dev->tda9887_conf |= TDA9887_AUTOMUTE;
2298 dev->automute = 0;
2299
2300 INIT_LIST_HEAD(&dev->video_q.queue);
2301 init_timer(&dev->video_q.timeout);
2302 dev->video_q.timeout.function = saa7134_buffer_timeout;
2303 dev->video_q.timeout.data = (unsigned long)(&dev->video_q);
2304 dev->video_q.dev = dev;
2305
2306 if (saa7134_boards[dev->board].video_out) {
2307 /* enable video output */
2308 int vo = saa7134_boards[dev->board].video_out;
2309 saa_writeb(SAA7134_VIDEO_PORT_CTRL0, video_out[vo][0]);
2310 saa_writeb(SAA7134_VIDEO_PORT_CTRL1, video_out[vo][1]);
2311 saa_writeb(SAA7134_VIDEO_PORT_CTRL2, video_out[vo][2]);
2312 saa_writeb(SAA7134_VIDEO_PORT_CTRL3, video_out[vo][3]);
2313 saa_writeb(SAA7134_VIDEO_PORT_CTRL4, video_out[vo][4]);
2314 saa_writeb(SAA7134_VIDEO_PORT_CTRL5, video_out[vo][5]);
2315 saa_writeb(SAA7134_VIDEO_PORT_CTRL6, video_out[vo][6]);
2316 saa_writeb(SAA7134_VIDEO_PORT_CTRL7, video_out[vo][7]);
2317 saa_writeb(SAA7134_VIDEO_PORT_CTRL8, video_out[vo][8]);
2318 }
2319
2320 return 0;
2321}
2322
2323int saa7134_video_init2(struct saa7134_dev *dev)
2324{
2325 /* init video hw */
2326 set_tvnorm(dev,&tvnorms[0]);
2327 video_mux(dev,0);
2328 saa7134_tvaudio_setmute(dev);
2329 saa7134_tvaudio_setvolume(dev,dev->ctl_volume);
2330 return 0;
2331}
2332
2333int saa7134_video_fini(struct saa7134_dev *dev)
2334{
2335 /* nothing */
2336 return 0;
2337}
2338
2339void saa7134_irq_video_intl(struct saa7134_dev *dev)
2340{
2341 static const char *st[] = {
2342 "(no signal)", "NTSC", "PAL", "SECAM" };
2343 u32 st1,st2;
2344
2345 st1 = saa_readb(SAA7134_STATUS_VIDEO1);
2346 st2 = saa_readb(SAA7134_STATUS_VIDEO2);
2347 dprintk("DCSDT: pll: %s, sync: %s, norm: %s\n",
2348 (st1 & 0x40) ? "not locked" : "locked",
2349 (st2 & 0x40) ? "no" : "yes",
2350 st[st1 & 0x03]);
2351 dev->nosignal = (st1 & 0x40) || (st2 & 0x40);
2352
2353 if (dev->nosignal) {
2354 /* no video signal -> mute audio */
2355 if (dev->ctl_automute)
2356 dev->automute = 1;
2357 saa7134_tvaudio_setmute(dev);
2358 saa_setb(SAA7134_SYNC_CTRL, 0x20);
2359 } else {
2360 /* wake up tvaudio audio carrier scan thread */
2361 saa7134_tvaudio_do_scan(dev);
2362 if (!noninterlaced)
2363 saa_clearb(SAA7134_SYNC_CTRL, 0x20);
2364 }
2365 if (dev->mops && dev->mops->signal_change)
2366 dev->mops->signal_change(dev);
2367}
2368
2369void saa7134_irq_video_done(struct saa7134_dev *dev, unsigned long status)
2370{
2371 enum v4l2_field field;
2372
2373 spin_lock(&dev->slock);
2374 if (dev->video_q.curr) {
2375 dev->video_fieldcount++;
2376 field = dev->video_q.curr->vb.field;
2377 if (V4L2_FIELD_HAS_BOTH(field)) {
2378 /* make sure we have seen both fields */
2379 if ((status & 0x10) == 0x00) {
2380 dev->video_q.curr->top_seen = 1;
2381 goto done;
2382 }
2383 if (!dev->video_q.curr->top_seen)
2384 goto done;
2385 } else if (field == V4L2_FIELD_TOP) {
2386 if ((status & 0x10) != 0x10)
2387 goto done;
2388 } else if (field == V4L2_FIELD_BOTTOM) {
2389 if ((status & 0x10) != 0x00)
2390 goto done;
2391 }
2392 dev->video_q.curr->vb.field_count = dev->video_fieldcount;
2393 saa7134_buffer_finish(dev,&dev->video_q,STATE_DONE);
2394 }
2395 saa7134_buffer_next(dev,&dev->video_q);
2396
2397 done:
2398 spin_unlock(&dev->slock);
2399}
2400
2401/* ----------------------------------------------------------- */
2402/*
2403 * Local variables:
2404 * c-basic-offset: 8
2405 * End:
2406 */
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
new file mode 100644
index 000000000000..ac90a9853236
--- /dev/null
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -0,0 +1,618 @@
1/*
2 * $Id: saa7134.h,v 1.38 2005/03/07 12:01:51 kraxel Exp $
3 *
4 * v4l2 device driver for philips saa7134 based TV cards
5 *
6 * (c) 2001,02 Gerd Knorr <kraxel@bytesex.org>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#include <linux/version.h>
24#define SAA7134_VERSION_CODE KERNEL_VERSION(0,2,12)
25
26#include <linux/pci.h>
27#include <linux/i2c.h>
28#include <linux/videodev.h>
29#include <linux/kdev_t.h>
30#include <linux/input.h>
31
32#include <asm/io.h>
33
34#include <media/tuner.h>
35#include <media/audiochip.h>
36#include <media/id.h>
37#include <media/ir-common.h>
38#include <media/video-buf.h>
39#include <media/video-buf-dvb.h>
40
41#ifndef TRUE
42# define TRUE (1==1)
43#endif
44#ifndef FALSE
45# define FALSE (1==0)
46#endif
47#define UNSET (-1U)
48
49/* 2.4 / 2.5 driver compatibility stuff */
50
51/* ----------------------------------------------------------- */
52/* enums */
53
54enum saa7134_tvaudio_mode {
55 TVAUDIO_FM_MONO = 1,
56 TVAUDIO_FM_BG_STEREO = 2,
57 TVAUDIO_FM_SAT_STEREO = 3,
58 TVAUDIO_FM_K_STEREO = 4,
59 TVAUDIO_NICAM_AM = 5,
60 TVAUDIO_NICAM_FM = 6,
61};
62
63enum saa7134_audio_in {
64 TV = 1,
65 LINE1 = 2,
66 LINE2 = 3,
67 LINE2_LEFT,
68};
69
70enum saa7134_video_out {
71 CCIR656 = 1,
72};
73
74/* ----------------------------------------------------------- */
75/* static data */
76
77struct saa7134_tvnorm {
78 char *name;
79 v4l2_std_id id;
80
81 /* video decoder */
82 unsigned int sync_control;
83 unsigned int luma_control;
84 unsigned int chroma_ctrl1;
85 unsigned int chroma_gain;
86 unsigned int chroma_ctrl2;
87 unsigned int vgate_misc;
88
89 /* video scaler */
90 unsigned int h_start;
91 unsigned int h_stop;
92 unsigned int video_v_start;
93 unsigned int video_v_stop;
94 unsigned int vbi_v_start;
95 unsigned int vbi_v_stop;
96 unsigned int src_timing;
97};
98
99struct saa7134_tvaudio {
100 char *name;
101 v4l2_std_id std;
102 enum saa7134_tvaudio_mode mode;
103 int carr1;
104 int carr2;
105};
106
107struct saa7134_format {
108 char *name;
109 unsigned int fourcc;
110 unsigned int depth;
111 unsigned int pm;
112 unsigned int vshift; /* vertical downsampling (for planar yuv) */
113 unsigned int hshift; /* horizontal downsampling (for planar yuv) */
114 unsigned int bswap:1;
115 unsigned int wswap:1;
116 unsigned int yuv:1;
117 unsigned int planar:1;
118 unsigned int uvswap:1;
119};
120
121/* ----------------------------------------------------------- */
122/* card configuration */
123
124#define SAA7134_BOARD_NOAUTO UNSET
125#define SAA7134_BOARD_UNKNOWN 0
126#define SAA7134_BOARD_PROTEUS_PRO 1
127#define SAA7134_BOARD_FLYVIDEO3000 2
128#define SAA7134_BOARD_FLYVIDEO2000 3
129#define SAA7134_BOARD_EMPRESS 4
130#define SAA7134_BOARD_MONSTERTV 5
131#define SAA7134_BOARD_MD9717 6
132#define SAA7134_BOARD_TVSTATION_RDS 7
133#define SAA7134_BOARD_CINERGY400 8
134#define SAA7134_BOARD_MD5044 9
135#define SAA7134_BOARD_KWORLD 10
136#define SAA7134_BOARD_CINERGY600 11
137#define SAA7134_BOARD_MD7134 12
138#define SAA7134_BOARD_TYPHOON_90031 13
139#define SAA7134_BOARD_ELSA 14
140#define SAA7134_BOARD_ELSA_500TV 15
141#define SAA7134_BOARD_ASUSTeK_TVFM7134 16
142#define SAA7134_BOARD_VA1000POWER 17
143#define SAA7134_BOARD_BMK_MPEX_NOTUNER 18
144#define SAA7134_BOARD_VIDEOMATE_TV 19
145#define SAA7134_BOARD_CRONOS_PLUS 20
146#define SAA7134_BOARD_10MOONSTVMASTER 21
147#define SAA7134_BOARD_MD2819 22
148#define SAA7134_BOARD_BMK_MPEX_TUNER 23
149#define SAA7134_BOARD_TVSTATION_DVR 24
150#define SAA7134_BOARD_ASUSTEK_TVFM7133 25
151#define SAA7134_BOARD_PINNACLE_PCTV_STEREO 26
152#define SAA7134_BOARD_MANLI_MTV002 27
153#define SAA7134_BOARD_MANLI_MTV001 28
154#define SAA7134_BOARD_TG3000TV 29
155#define SAA7134_BOARD_ECS_TVP3XP 30
156#define SAA7134_BOARD_ECS_TVP3XP_4CB5 31
157#define SAA7134_BOARD_AVACSSMARTTV 32
158#define SAA7134_BOARD_AVERMEDIA_DVD_EZMAKER 33
159#define SAA7134_BOARD_NOVAC_PRIMETV7133 34
160#define SAA7134_BOARD_AVERMEDIA_STUDIO_305 35
161#define SAA7133_BOARD_UPMOST_PURPLE_TV 36
162#define SAA7134_BOARD_ITEMS_MTV005 37
163#define SAA7134_BOARD_CINERGY200 38
164#define SAA7134_BOARD_FLYTVPLATINUM_MINI 39
165#define SAA7134_BOARD_VIDEOMATE_TV_PVR 40
166#define SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUS 41
167#define SAA7134_BOARD_SABRENT_SBTTVFM 42
168#define SAA7134_BOARD_ZOLID_XPERT_TV7134 43
169#define SAA7134_BOARD_EMPIRE_PCI_TV_RADIO_LE 44
170#define SAA7134_BOARD_AVERMEDIA_307 45
171#define SAA7134_BOARD_AVERMEDIA_CARDBUS 46
172#define SAA7134_BOARD_CINERGY400_CARDBUS 47
173#define SAA7134_BOARD_CINERGY600_MK3 48
174#define SAA7134_BOARD_VIDEOMATE_GOLD_PLUS 49
175#define SAA7134_BOARD_PINNACLE_300I_DVBT_PAL 50
176#define SAA7134_BOARD_PROVIDEO_PV952 51
177#define SAA7134_BOARD_AVERMEDIA_305 52
178#define SAA7135_BOARD_ASUSTeK_TVFM7135 53
179#define SAA7134_BOARD_FLYTVPLATINUM_FM 54
180#define SAA7134_BOARD_FLYDVBTDUO 55
181
182#define SAA7134_MAXBOARDS 8
183#define SAA7134_INPUT_MAX 8
184
185struct saa7134_input {
186 char *name;
187 unsigned int vmux;
188 enum saa7134_audio_in amux;
189 unsigned int gpio;
190 unsigned int tv:1;
191};
192
193enum saa7134_mpeg_type {
194 SAA7134_MPEG_UNUSED,
195 SAA7134_MPEG_EMPRESS,
196 SAA7134_MPEG_DVB,
197};
198
199struct saa7134_board {
200 char *name;
201 unsigned int audio_clock;
202
203 /* input switching */
204 unsigned int gpiomask;
205 struct saa7134_input inputs[SAA7134_INPUT_MAX];
206 struct saa7134_input radio;
207 struct saa7134_input mute;
208
209 /* i2c chip info */
210 unsigned int tuner_type;
211 unsigned int tda9887_conf;
212
213 /* peripheral I/O */
214 enum saa7134_video_out video_out;
215 enum saa7134_mpeg_type mpeg;
216};
217
218#define card_has_radio(dev) (NULL != saa7134_boards[dev->board].radio.name)
219#define card_is_empress(dev) (SAA7134_MPEG_EMPRESS == saa7134_boards[dev->board].mpeg)
220#define card_is_dvb(dev) (SAA7134_MPEG_DVB == saa7134_boards[dev->board].mpeg)
221#define card_has_mpeg(dev) (SAA7134_MPEG_UNUSED != saa7134_boards[dev->board].mpeg)
222#define card(dev) (saa7134_boards[dev->board])
223#define card_in(dev,n) (saa7134_boards[dev->board].inputs[n])
224
225/* ----------------------------------------------------------- */
226/* device / file handle status */
227
228#define RESOURCE_OVERLAY 1
229#define RESOURCE_VIDEO 2
230#define RESOURCE_VBI 4
231
232#define INTERLACE_AUTO 0
233#define INTERLACE_ON 1
234#define INTERLACE_OFF 2
235
236#define BUFFER_TIMEOUT (HZ/2) /* 0.5 seconds */
237
238struct saa7134_dev;
239struct saa7134_dma;
240
241/* saa7134 page table */
242struct saa7134_pgtable {
243 unsigned int size;
244 u32 *cpu;
245 dma_addr_t dma;
246};
247
248/* tvaudio thread status */
249struct saa7134_thread {
250 pid_t pid;
251 struct completion exit;
252 wait_queue_head_t wq;
253 unsigned int shutdown;
254 unsigned int scan1;
255 unsigned int scan2;
256 unsigned int mode;
257};
258
259/* buffer for one video/vbi/ts frame */
260struct saa7134_buf {
261 /* common v4l buffer stuff -- must be first */
262 struct videobuf_buffer vb;
263
264 /* saa7134 specific */
265 struct saa7134_format *fmt;
266 unsigned int top_seen;
267 int (*activate)(struct saa7134_dev *dev,
268 struct saa7134_buf *buf,
269 struct saa7134_buf *next);
270
271 /* page tables */
272 struct saa7134_pgtable *pt;
273};
274
275struct saa7134_dmaqueue {
276 struct saa7134_dev *dev;
277 struct saa7134_buf *curr;
278 struct list_head queue;
279 struct timer_list timeout;
280 unsigned int need_two;
281};
282
283/* video filehandle status */
284struct saa7134_fh {
285 struct saa7134_dev *dev;
286 unsigned int radio;
287 enum v4l2_buf_type type;
288 unsigned int resources;
289#ifdef VIDIOC_G_PRIORITY
290 enum v4l2_priority prio;
291#endif
292
293 /* video overlay */
294 struct v4l2_window win;
295 struct v4l2_clip clips[8];
296 unsigned int nclips;
297
298 /* video capture */
299 struct saa7134_format *fmt;
300 unsigned int width,height;
301 struct videobuf_queue cap;
302 struct saa7134_pgtable pt_cap;
303
304 /* vbi capture */
305 struct videobuf_queue vbi;
306 struct saa7134_pgtable pt_vbi;
307};
308
309/* oss dsp status */
310struct saa7134_oss {
311 struct semaphore lock;
312 int minor_mixer;
313 int minor_dsp;
314 unsigned int users_dsp;
315
316 /* mixer */
317 enum saa7134_audio_in input;
318 unsigned int count;
319 unsigned int line1;
320 unsigned int line2;
321
322 /* dsp */
323 unsigned int afmt;
324 unsigned int rate;
325 unsigned int channels;
326 unsigned int recording_on;
327 unsigned int dma_running;
328 unsigned int blocks;
329 unsigned int blksize;
330 unsigned int bufsize;
331 struct saa7134_pgtable pt;
332 struct videobuf_dmabuf dma;
333 wait_queue_head_t wq;
334 unsigned int dma_blk;
335 unsigned int read_offset;
336 unsigned int read_count;
337};
338
339/* IR input */
340struct saa7134_ir {
341 struct input_dev dev;
342 struct ir_input_state ir;
343 char name[32];
344 char phys[32];
345 u32 mask_keycode;
346 u32 mask_keydown;
347 u32 mask_keyup;
348 int polling;
349 u32 last_gpio;
350 struct timer_list timer;
351};
352
353/* ts/mpeg status */
354struct saa7134_ts {
355 /* TS capture */
356 struct saa7134_pgtable pt_ts;
357 int nr_packets;
358 int nr_bufs;
359};
360
361/* ts/mpeg ops */
362struct saa7134_mpeg_ops {
363 enum saa7134_mpeg_type type;
364 struct list_head next;
365 int (*init)(struct saa7134_dev *dev);
366 int (*fini)(struct saa7134_dev *dev);
367 void (*signal_change)(struct saa7134_dev *dev);
368};
369
370/* global device status */
371struct saa7134_dev {
372 struct list_head devlist;
373 struct semaphore lock;
374 spinlock_t slock;
375#ifdef VIDIOC_G_PRIORITY
376 struct v4l2_prio_state prio;
377#endif
378
379 /* various device info */
380 unsigned int resources;
381 struct video_device *video_dev;
382 struct video_device *radio_dev;
383 struct video_device *vbi_dev;
384 struct saa7134_oss oss;
385
386 /* infrared remote */
387 int has_remote;
388 struct saa7134_ir *remote;
389
390 /* pci i/o */
391 char name[32];
392 int nr;
393 struct pci_dev *pci;
394 unsigned char pci_rev,pci_lat;
395 __u32 __iomem *lmmio;
396 __u8 __iomem *bmmio;
397
398 /* config info */
399 unsigned int board;
400 unsigned int tuner_type;
401 unsigned int tda9887_conf;
402 unsigned int gpio_value;
403 unsigned int irq2_mask;
404
405 /* i2c i/o */
406 struct i2c_adapter i2c_adap;
407 struct i2c_client i2c_client;
408 unsigned char eedata[64];
409
410 /* video overlay */
411 struct v4l2_framebuffer ovbuf;
412 struct saa7134_format *ovfmt;
413 unsigned int ovenable;
414 enum v4l2_field ovfield;
415
416 /* video+ts+vbi capture */
417 struct saa7134_dmaqueue video_q;
418 struct saa7134_dmaqueue vbi_q;
419 unsigned int video_fieldcount;
420 unsigned int vbi_fieldcount;
421
422 /* various v4l controls */
423 struct saa7134_tvnorm *tvnorm; /* video */
424 struct saa7134_tvaudio *tvaudio;
425 unsigned int ctl_input;
426 int ctl_bright;
427 int ctl_contrast;
428 int ctl_hue;
429 int ctl_saturation;
430 int ctl_freq;
431 int ctl_mute; /* audio */
432 int ctl_volume;
433 int ctl_invert; /* private */
434 int ctl_mirror;
435 int ctl_y_odd;
436 int ctl_y_even;
437 int ctl_automute;
438
439 /* crop */
440 struct v4l2_rect crop_bounds;
441 struct v4l2_rect crop_defrect;
442 struct v4l2_rect crop_current;
443
444 /* other global state info */
445 unsigned int automute;
446 struct saa7134_thread thread;
447 struct saa7134_input *input;
448 struct saa7134_input *hw_input;
449 unsigned int hw_mute;
450 int last_carrier;
451 int nosignal;
452
453 /* SAA7134_MPEG_* */
454 struct saa7134_ts ts;
455 struct saa7134_dmaqueue ts_q;
456 struct saa7134_mpeg_ops *mops;
457
458 /* SAA7134_MPEG_EMPRESS only */
459 struct video_device *empress_dev;
460 struct videobuf_queue empress_tsq;
461 unsigned int empress_users;
462 struct work_struct empress_workqueue;
463 int empress_started;
464
465 /* SAA7134_MPEG_DVB only */
466 struct videobuf_dvb dvb;
467};
468
469/* ----------------------------------------------------------- */
470
471#define saa_readl(reg) readl(dev->lmmio + (reg))
472#define saa_writel(reg,value) writel((value), dev->lmmio + (reg));
473#define saa_andorl(reg,mask,value) \
474 writel((readl(dev->lmmio+(reg)) & ~(mask)) |\
475 ((value) & (mask)), dev->lmmio+(reg))
476#define saa_setl(reg,bit) saa_andorl((reg),(bit),(bit))
477#define saa_clearl(reg,bit) saa_andorl((reg),(bit),0)
478
479#define saa_readb(reg) readb(dev->bmmio + (reg))
480#define saa_writeb(reg,value) writeb((value), dev->bmmio + (reg));
481#define saa_andorb(reg,mask,value) \
482 writeb((readb(dev->bmmio+(reg)) & ~(mask)) |\
483 ((value) & (mask)), dev->bmmio+(reg))
484#define saa_setb(reg,bit) saa_andorb((reg),(bit),(bit))
485#define saa_clearb(reg,bit) saa_andorb((reg),(bit),0)
486
487#define saa_wait(us) { udelay(us); }
488
489/* ----------------------------------------------------------- */
490/* saa7134-core.c */
491
492extern struct list_head saa7134_devlist;
493
494void saa7134_print_ioctl(char *name, unsigned int cmd);
495void saa7134_track_gpio(struct saa7134_dev *dev, char *msg);
496
497#define SAA7134_PGTABLE_SIZE 4096
498
499int saa7134_pgtable_alloc(struct pci_dev *pci, struct saa7134_pgtable *pt);
500int saa7134_pgtable_build(struct pci_dev *pci, struct saa7134_pgtable *pt,
501 struct scatterlist *list, unsigned int length,
502 unsigned int startpage);
503void saa7134_pgtable_free(struct pci_dev *pci, struct saa7134_pgtable *pt);
504
505int saa7134_buffer_count(unsigned int size, unsigned int count);
506int saa7134_buffer_startpage(struct saa7134_buf *buf);
507unsigned long saa7134_buffer_base(struct saa7134_buf *buf);
508
509int saa7134_buffer_queue(struct saa7134_dev *dev, struct saa7134_dmaqueue *q,
510 struct saa7134_buf *buf);
511void saa7134_buffer_finish(struct saa7134_dev *dev, struct saa7134_dmaqueue *q,
512 unsigned int state);
513void saa7134_buffer_next(struct saa7134_dev *dev, struct saa7134_dmaqueue *q);
514void saa7134_buffer_timeout(unsigned long data);
515void saa7134_dma_free(struct saa7134_dev *dev,struct saa7134_buf *buf);
516
517int saa7134_set_dmabits(struct saa7134_dev *dev);
518
519/* ----------------------------------------------------------- */
520/* saa7134-cards.c */
521
522extern struct saa7134_board saa7134_boards[];
523extern const unsigned int saa7134_bcount;
524extern struct pci_device_id __devinitdata saa7134_pci_tbl[];
525
526extern int saa7134_board_init1(struct saa7134_dev *dev);
527extern int saa7134_board_init2(struct saa7134_dev *dev);
528
529
530/* ----------------------------------------------------------- */
531/* saa7134-i2c.c */
532
533int saa7134_i2c_register(struct saa7134_dev *dev);
534int saa7134_i2c_unregister(struct saa7134_dev *dev);
535void saa7134_i2c_call_clients(struct saa7134_dev *dev,
536 unsigned int cmd, void *arg);
537
538
539/* ----------------------------------------------------------- */
540/* saa7134-video.c */
541
542extern struct video_device saa7134_video_template;
543extern struct video_device saa7134_radio_template;
544
545int saa7134_common_ioctl(struct saa7134_dev *dev,
546 unsigned int cmd, void *arg);
547
548int saa7134_video_init1(struct saa7134_dev *dev);
549int saa7134_video_init2(struct saa7134_dev *dev);
550int saa7134_video_fini(struct saa7134_dev *dev);
551void saa7134_irq_video_intl(struct saa7134_dev *dev);
552void saa7134_irq_video_done(struct saa7134_dev *dev, unsigned long status);
553
554
555/* ----------------------------------------------------------- */
556/* saa7134-ts.c */
557
558#define TS_PACKET_SIZE 188 /* TS packets 188 bytes */
559
560extern struct videobuf_queue_ops saa7134_ts_qops;
561
562int saa7134_ts_init1(struct saa7134_dev *dev);
563int saa7134_ts_fini(struct saa7134_dev *dev);
564void saa7134_irq_ts_done(struct saa7134_dev *dev, unsigned long status);
565
566int saa7134_ts_register(struct saa7134_mpeg_ops *ops);
567void saa7134_ts_unregister(struct saa7134_mpeg_ops *ops);
568
569/* ----------------------------------------------------------- */
570/* saa7134-vbi.c */
571
572extern struct videobuf_queue_ops saa7134_vbi_qops;
573extern struct video_device saa7134_vbi_template;
574
575int saa7134_vbi_init1(struct saa7134_dev *dev);
576int saa7134_vbi_fini(struct saa7134_dev *dev);
577void saa7134_irq_vbi_done(struct saa7134_dev *dev, unsigned long status);
578
579
580/* ----------------------------------------------------------- */
581/* saa7134-tvaudio.c */
582
583int saa7134_tvaudio_rx2mode(u32 rx);
584
585void saa7134_tvaudio_setmute(struct saa7134_dev *dev);
586void saa7134_tvaudio_setinput(struct saa7134_dev *dev,
587 struct saa7134_input *in);
588void saa7134_tvaudio_setvolume(struct saa7134_dev *dev, int level);
589int saa7134_tvaudio_getstereo(struct saa7134_dev *dev);
590
591int saa7134_tvaudio_init2(struct saa7134_dev *dev);
592int saa7134_tvaudio_fini(struct saa7134_dev *dev);
593int saa7134_tvaudio_do_scan(struct saa7134_dev *dev);
594
595int saa_dsp_writel(struct saa7134_dev *dev, int reg, u32 value);
596
597/* ----------------------------------------------------------- */
598/* saa7134-oss.c */
599
600extern struct file_operations saa7134_dsp_fops;
601extern struct file_operations saa7134_mixer_fops;
602
603int saa7134_oss_init1(struct saa7134_dev *dev);
604int saa7134_oss_fini(struct saa7134_dev *dev);
605void saa7134_irq_oss_done(struct saa7134_dev *dev, unsigned long status);
606
607/* ----------------------------------------------------------- */
608/* saa7134-input.c */
609
610int saa7134_input_init1(struct saa7134_dev *dev);
611void saa7134_input_fini(struct saa7134_dev *dev);
612void saa7134_input_irq(struct saa7134_dev *dev);
613
614/*
615 * Local variables:
616 * c-basic-offset: 8
617 * End:
618 */