blob: 22b203f8ff27a42b0693ef8061e8dda1c0c8c007 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * driver for the SAA7146 based AV110 cards (like the Fujitsu-Siemens DVB)
3 * av7110.c: initialization and demux stuff
4 *
5 * Copyright (C) 1999-2002 Ralph Metzler
6 * & Marcus Metzler for convergence integrated media GmbH
7 *
8 * originally based on code by:
9 * Copyright (C) 1998,1999 Christian Theiss <mistert@rz.fh-augsburg.de>
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
15 *
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
27 *
28 *
29 * the project's page is at http://www.linuxtv.org/dvb/
30 */
31
32
33#include <linux/config.h>
34#include <linux/module.h>
35#include <linux/kmod.h>
36#include <linux/delay.h>
37#include <linux/fs.h>
38#include <linux/timer.h>
39#include <linux/poll.h>
40#include <linux/byteorder/swabb.h>
41#include <linux/smp_lock.h>
42
43#include <linux/kernel.h>
44#include <linux/moduleparam.h>
45#include <linux/sched.h>
46#include <linux/types.h>
47#include <linux/fcntl.h>
48#include <linux/interrupt.h>
49#include <linux/string.h>
50#include <linux/pci.h>
51#include <linux/vmalloc.h>
52#include <linux/firmware.h>
53#include <linux/crc32.h>
54#include <linux/i2c.h>
55
56#include <asm/system.h>
57#include <asm/semaphore.h>
58
59#include <linux/dvb/frontend.h>
60
61#include "dvb_frontend.h"
62
63#include "ttpci-eeprom.h"
64#include "av7110.h"
65#include "av7110_hw.h"
66#include "av7110_av.h"
67#include "av7110_ca.h"
68#include "av7110_ipack.h"
69
70#define TS_WIDTH 376
71#define TS_HEIGHT 512
72#define TS_BUFLEN (TS_WIDTH*TS_HEIGHT)
73#define TS_MAX_PACKETS (TS_BUFLEN/TS_SIZE)
74
75
76int av7110_debug;
77
78static int vidmode = CVBS_RGB_OUT;
79static int pids_off;
80static int adac = DVB_ADAC_TI;
81static int hw_sections;
82static int rgb_on;
83static int volume = 255;
84static int budgetpatch = 0;
85
86module_param_named(debug, av7110_debug, int, 0644);
87MODULE_PARM_DESC(debug, "debug level (bitmask, default 0)");
88module_param(vidmode, int, 0444);
89MODULE_PARM_DESC(vidmode,"analog video out: 0 off, 1 CVBS+RGB (default), 2 CVBS+YC, 3 YC");
90module_param(pids_off, int, 0444);
91MODULE_PARM_DESC(pids_off,"clear video/audio/PCR PID filters when demux is closed");
92module_param(adac, int, 0444);
93MODULE_PARM_DESC(adac,"audio DAC type: 0 TI, 1 CRYSTAL, 2 MSP (use if autodetection fails)");
94module_param(hw_sections, int, 0444);
95MODULE_PARM_DESC(hw_sections, "0 use software section filter, 1 use hardware");
96module_param(rgb_on, int, 0444);
97MODULE_PARM_DESC(rgb_on, "For Siemens DVB-C cards only: Enable RGB control"
98 " signal on SCART pin 16 to switch SCART video mode from CVBS to RGB");
99module_param(volume, int, 0444);
100MODULE_PARM_DESC(volume, "initial volume: default 255 (range 0-255)");
101module_param(budgetpatch, int, 0444);
102MODULE_PARM_DESC(budgetpatch, "use budget-patch hardware modification: default 0 (0 no, 1 autodetect, 2 always)");
103
104static void restart_feeds(struct av7110 *av7110);
105
106static int av7110_num = 0;
107
108#define FE_FUNC_OVERRIDE(fe_func, av7110_copy, av7110_func) \
109{\
110 if (fe_func != NULL) { \
111 av7110_copy = fe_func; \
112 fe_func = av7110_func; \
113 } \
114}
115
116
117static void init_av7110_av(struct av7110 *av7110)
118{
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700119 int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700120 struct saa7146_dev *dev = av7110->dev;
121
122 /* set internal volume control to maximum */
123 av7110->adac_type = DVB_ADAC_TI;
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700124 ret = av7110_set_volume(av7110, av7110->mixer.volume_left, av7110->mixer.volume_right);
Johannes Stezenbach7a2fa902005-07-07 17:58:01 -0700125 if (ret < 0)
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700126 printk("dvb-ttpci:cannot set internal volume to maximum:%d\n",ret);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700127
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700128 ret = av7710_set_video_mode(av7110, vidmode);
Johannes Stezenbach7a2fa902005-07-07 17:58:01 -0700129 if (ret < 0)
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700130 printk("dvb-ttpci:cannot set video mode:%d\n",ret);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700131
132 /* handle different card types */
133 /* remaining inits according to card and frontend type */
134 av7110->analog_tuner_flags = 0;
135 av7110->current_input = 0;
136 if (i2c_writereg(av7110, 0x20, 0x00, 0x00) == 1) {
137 printk ("dvb-ttpci: Crystal audio DAC @ card %d detected\n",
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -0700138 av7110->dvb_adapter.num);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700139 av7110->adac_type = DVB_ADAC_CRYSTAL;
140 i2c_writereg(av7110, 0x20, 0x01, 0xd2);
141 i2c_writereg(av7110, 0x20, 0x02, 0x49);
142 i2c_writereg(av7110, 0x20, 0x03, 0x00);
143 i2c_writereg(av7110, 0x20, 0x04, 0x00);
144
145 /**
146 * some special handling for the Siemens DVB-C cards...
147 */
148 } else if (0 == av7110_init_analog_module(av7110)) {
149 /* done. */
150 }
151 else if (dev->pci->subsystem_vendor == 0x110a) {
152 printk("dvb-ttpci: DVB-C w/o analog module @ card %d detected\n",
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -0700153 av7110->dvb_adapter.num);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700154 av7110->adac_type = DVB_ADAC_NONE;
155 }
156 else {
157 av7110->adac_type = adac;
158 printk("dvb-ttpci: adac type set to %d @ card %d\n",
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -0700159 av7110->dvb_adapter.num, av7110->adac_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700160 }
161
162 if (av7110->adac_type == DVB_ADAC_NONE || av7110->adac_type == DVB_ADAC_MSP) {
163 // switch DVB SCART on
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700164 ret = av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, MainSwitch, 1, 0);
Johannes Stezenbach7a2fa902005-07-07 17:58:01 -0700165 if (ret < 0)
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700166 printk("dvb-ttpci:cannot switch on SCART(Main):%d\n",ret);
167 ret = av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, ADSwitch, 1, 1);
Johannes Stezenbach7a2fa902005-07-07 17:58:01 -0700168 if (ret < 0)
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700169 printk("dvb-ttpci:cannot switch on SCART(AD):%d\n",ret);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700170 if (rgb_on &&
Karl Herz6af4ee12005-09-09 13:03:13 -0700171 ((av7110->dev->pci->subsystem_vendor == 0x110a) ||
172 (av7110->dev->pci->subsystem_vendor == 0x13c2)) &&
173 (av7110->dev->pci->subsystem_device == 0x0000)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700174 saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); // RGB on, SCART pin 16
175 //saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); // SCARTpin 8
176 }
177 }
178
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700179 ret = av7110_set_volume(av7110, av7110->mixer.volume_left, av7110->mixer.volume_right);
Johannes Stezenbach7a2fa902005-07-07 17:58:01 -0700180 if (ret < 0)
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700181 printk("dvb-ttpci:cannot set volume :%d\n",ret);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700182}
183
184static void recover_arm(struct av7110 *av7110)
185{
186 dprintk(4, "%p\n",av7110);
187
188 av7110_bootarm(av7110);
189 msleep(100);
190 restart_feeds(av7110);
191 av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, SetIR, 1, av7110->ir_config);
192}
193
194static void arm_error(struct av7110 *av7110)
195{
196 dprintk(4, "%p\n",av7110);
197
198 av7110->arm_errors++;
199 av7110->arm_ready = 0;
200 recover_arm(av7110);
201}
202
203static void av7110_arm_sync(struct av7110 *av7110)
204{
205 av7110->arm_rmmod = 1;
206 wake_up_interruptible(&av7110->arm_wait);
207
208 while (av7110->arm_thread)
209 msleep(1);
210}
211
212static int arm_thread(void *data)
213{
214 struct av7110 *av7110 = data;
215 u16 newloops = 0;
216 int timeout;
217
218 dprintk(4, "%p\n",av7110);
219
220 lock_kernel();
221 daemonize("arm_mon");
222 sigfillset(&current->blocked);
223 unlock_kernel();
224
225 av7110->arm_thread = current;
226
227 for (;;) {
228 timeout = wait_event_interruptible_timeout(av7110->arm_wait,
229 av7110->arm_rmmod, 5 * HZ);
230 if (-ERESTARTSYS == timeout || av7110->arm_rmmod) {
231 /* got signal or told to quit*/
232 break;
233 }
234
235 if (!av7110->arm_ready)
236 continue;
237
238 if (down_interruptible(&av7110->dcomlock))
239 break;
240
241 newloops = rdebi(av7110, DEBINOSWAP, STATUS_LOOPS, 0, 2);
242 up(&av7110->dcomlock);
243
244 if (newloops == av7110->arm_loops) {
245 printk(KERN_ERR "dvb-ttpci: ARM crashed @ card %d\n",
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -0700246 av7110->dvb_adapter.num);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700247
248 arm_error(av7110);
249 av7710_set_video_mode(av7110, vidmode);
250
251 init_av7110_av(av7110);
252
253 if (down_interruptible(&av7110->dcomlock))
254 break;
255
256 newloops = rdebi(av7110, DEBINOSWAP, STATUS_LOOPS, 0, 2) - 1;
257 up(&av7110->dcomlock);
258 }
259 av7110->arm_loops = newloops;
260 }
261
262 av7110->arm_thread = NULL;
263 return 0;
264}
265
266
Linus Torvalds1da177e2005-04-16 15:20:36 -0700267/****************************************************************************
268 * IRQ handling
269 ****************************************************************************/
270
271static int DvbDmxFilterCallback(u8 *buffer1, size_t buffer1_len,
272 u8 *buffer2, size_t buffer2_len,
273 struct dvb_demux_filter *dvbdmxfilter,
274 enum dmx_success success,
275 struct av7110 *av7110)
276{
277 if (!dvbdmxfilter->feed->demux->dmx.frontend)
278 return 0;
279 if (dvbdmxfilter->feed->demux->dmx.frontend->source == DMX_MEMORY_FE)
280 return 0;
281
282 switch (dvbdmxfilter->type) {
283 case DMX_TYPE_SEC:
284 if ((((buffer1[1] << 8) | buffer1[2]) & 0xfff) + 3 != buffer1_len)
285 return 0;
286 if (dvbdmxfilter->doneq) {
287 struct dmx_section_filter *filter = &dvbdmxfilter->filter;
288 int i;
289 u8 xor, neq = 0;
290
291 for (i = 0; i < DVB_DEMUX_MASK_MAX; i++) {
292 xor = filter->filter_value[i] ^ buffer1[i];
293 neq |= dvbdmxfilter->maskandnotmode[i] & xor;
294 }
295 if (!neq)
296 return 0;
297 }
298 return dvbdmxfilter->feed->cb.sec(buffer1, buffer1_len,
299 buffer2, buffer2_len,
300 &dvbdmxfilter->filter,
301 DMX_OK);
302 case DMX_TYPE_TS:
303 if (!(dvbdmxfilter->feed->ts_type & TS_PACKET))
304 return 0;
305 if (dvbdmxfilter->feed->ts_type & TS_PAYLOAD_ONLY)
306 return dvbdmxfilter->feed->cb.ts(buffer1, buffer1_len,
307 buffer2, buffer2_len,
308 &dvbdmxfilter->feed->feed.ts,
309 DMX_OK);
310 else
311 av7110_p2t_write(buffer1, buffer1_len,
312 dvbdmxfilter->feed->pid,
313 &av7110->p2t_filter[dvbdmxfilter->index]);
314 default:
315 return 0;
316 }
317}
318
319
320//#define DEBUG_TIMING
321static inline void print_time(char *s)
322{
323#ifdef DEBUG_TIMING
324 struct timeval tv;
325 do_gettimeofday(&tv);
326 printk("%s: %d.%d\n", s, (int)tv.tv_sec, (int)tv.tv_usec);
327#endif
328}
329
330#define DEBI_READ 0
331#define DEBI_WRITE 1
332static inline void start_debi_dma(struct av7110 *av7110, int dir,
333 unsigned long addr, unsigned int len)
334{
335 dprintk(8, "%c %08lx %u\n", dir == DEBI_READ ? 'R' : 'W', addr, len);
336 if (saa7146_wait_for_debi_done(av7110->dev, 0)) {
337 printk(KERN_ERR "%s: saa7146_wait_for_debi_done timed out\n", __FUNCTION__);
338 return;
339 }
340
341 SAA7146_ISR_CLEAR(av7110->dev, MASK_19); /* for good measure */
342 SAA7146_IER_ENABLE(av7110->dev, MASK_19);
343 if (len < 5)
344 len = 5; /* we want a real DEBI DMA */
345 if (dir == DEBI_WRITE)
346 iwdebi(av7110, DEBISWAB, addr, 0, (len + 3) & ~3);
347 else
348 irdebi(av7110, DEBISWAB, addr, 0, len);
349}
350
351static void debiirq(unsigned long data)
352{
353 struct av7110 *av7110 = (struct av7110 *) data;
354 int type = av7110->debitype;
355 int handle = (type >> 8) & 0x1f;
356 unsigned int xfer = 0;
357
358 print_time("debi");
359 dprintk(4, "type 0x%04x\n", type);
360
361 if (type == -1) {
362 printk("DEBI irq oops @ %ld, psr:0x%08x, ssr:0x%08x\n",
363 jiffies, saa7146_read(av7110->dev, PSR),
364 saa7146_read(av7110->dev, SSR));
365 goto debi_done;
366 }
367 av7110->debitype = -1;
368
369 switch (type & 0xff) {
370
371 case DATA_TS_RECORD:
372 dvb_dmx_swfilter_packets(&av7110->demux,
373 (const u8 *) av7110->debi_virt,
374 av7110->debilen / 188);
375 xfer = RX_BUFF;
376 break;
377
378 case DATA_PES_RECORD:
379 if (av7110->demux.recording)
380 av7110_record_cb(&av7110->p2t[handle],
381 (u8 *) av7110->debi_virt,
382 av7110->debilen);
383 xfer = RX_BUFF;
384 break;
385
386 case DATA_IPMPE:
387 case DATA_FSECTION:
388 case DATA_PIPING:
389 if (av7110->handle2filter[handle])
390 DvbDmxFilterCallback((u8 *)av7110->debi_virt,
391 av7110->debilen, NULL, 0,
392 av7110->handle2filter[handle],
393 DMX_OK, av7110);
394 xfer = RX_BUFF;
395 break;
396
397 case DATA_CI_GET:
398 {
399 u8 *data = av7110->debi_virt;
400
401 if ((data[0] < 2) && data[2] == 0xff) {
402 int flags = 0;
403 if (data[5] > 0)
404 flags |= CA_CI_MODULE_PRESENT;
405 if (data[5] > 5)
406 flags |= CA_CI_MODULE_READY;
407 av7110->ci_slot[data[0]].flags = flags;
408 } else
409 ci_get_data(&av7110->ci_rbuffer,
410 av7110->debi_virt,
411 av7110->debilen);
412 xfer = RX_BUFF;
413 break;
414 }
415
416 case DATA_COMMON_INTERFACE:
417 CI_handle(av7110, (u8 *)av7110->debi_virt, av7110->debilen);
418#if 0
419 {
420 int i;
421
422 printk("av7110%d: ", av7110->num);
423 printk("%02x ", *(u8 *)av7110->debi_virt);
424 printk("%02x ", *(1+(u8 *)av7110->debi_virt));
425 for (i = 2; i < av7110->debilen; i++)
426 printk("%02x ", (*(i+(unsigned char *)av7110->debi_virt)));
427 for (i = 2; i < av7110->debilen; i++)
428 printk("%c", chtrans(*(i+(unsigned char *)av7110->debi_virt)));
429
430 printk("\n");
431 }
432#endif
433 xfer = RX_BUFF;
434 break;
435
436 case DATA_DEBUG_MESSAGE:
437 ((s8*)av7110->debi_virt)[Reserved_SIZE - 1] = 0;
438 printk("%s\n", (s8 *) av7110->debi_virt);
439 xfer = RX_BUFF;
440 break;
441
442 case DATA_CI_PUT:
443 dprintk(4, "debi DATA_CI_PUT\n");
444 case DATA_MPEG_PLAY:
445 dprintk(4, "debi DATA_MPEG_PLAY\n");
446 case DATA_BMP_LOAD:
447 dprintk(4, "debi DATA_BMP_LOAD\n");
448 xfer = TX_BUFF;
449 break;
450 default:
451 break;
452 }
453debi_done:
454 spin_lock(&av7110->debilock);
455 if (xfer)
456 iwdebi(av7110, DEBINOSWAP, xfer, 0, 2);
457 ARM_ClearMailBox(av7110);
458 spin_unlock(&av7110->debilock);
459}
460
461/* irq from av7110 firmware writing the mailbox register in the DPRAM */
462static void gpioirq(unsigned long data)
463{
464 struct av7110 *av7110 = (struct av7110 *) data;
465 u32 rxbuf, txbuf;
466 int len;
467
468 if (av7110->debitype != -1)
469 /* we shouldn't get any irq while a debi xfer is running */
470 printk("dvb-ttpci: GPIO0 irq oops @ %ld, psr:0x%08x, ssr:0x%08x\n",
471 jiffies, saa7146_read(av7110->dev, PSR),
472 saa7146_read(av7110->dev, SSR));
473
474 if (saa7146_wait_for_debi_done(av7110->dev, 0)) {
475 printk(KERN_ERR "%s: saa7146_wait_for_debi_done timed out\n", __FUNCTION__);
476 BUG(); /* maybe we should try resetting the debi? */
477 }
478
479 spin_lock(&av7110->debilock);
480 ARM_ClearIrq(av7110);
481
482 /* see what the av7110 wants */
483 av7110->debitype = irdebi(av7110, DEBINOSWAP, IRQ_STATE, 0, 2);
484 av7110->debilen = irdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);
485 rxbuf = irdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
486 txbuf = irdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);
487 len = (av7110->debilen + 3) & ~3;
488
489 print_time("gpio");
490 dprintk(8, "GPIO0 irq 0x%04x %d\n", av7110->debitype, av7110->debilen);
491
492 switch (av7110->debitype & 0xff) {
493
494 case DATA_TS_PLAY:
495 case DATA_PES_PLAY:
496 break;
497
498 case DATA_MPEG_VIDEO_EVENT:
499 {
500 u32 h_ar;
501 struct video_event event;
502
503 av7110->video_size.w = irdebi(av7110, DEBINOSWAP, STATUS_MPEG_WIDTH, 0, 2);
504 h_ar = irdebi(av7110, DEBINOSWAP, STATUS_MPEG_HEIGHT_AR, 0, 2);
505
506 iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);
507 iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
508
509 av7110->video_size.h = h_ar & 0xfff;
510 dprintk(8, "GPIO0 irq: DATA_MPEG_VIDEO_EVENT: w/h/ar = %u/%u/%u\n",
511 av7110->video_size.w,
512 av7110->video_size.h,
513 av7110->video_size.aspect_ratio);
514
515 event.type = VIDEO_EVENT_SIZE_CHANGED;
516 event.u.size.w = av7110->video_size.w;
517 event.u.size.h = av7110->video_size.h;
518 switch ((h_ar >> 12) & 0xf)
519 {
520 case 3:
521 av7110->video_size.aspect_ratio = VIDEO_FORMAT_16_9;
522 event.u.size.aspect_ratio = VIDEO_FORMAT_16_9;
523 av7110->videostate.video_format = VIDEO_FORMAT_16_9;
524 break;
525 case 4:
526 av7110->video_size.aspect_ratio = VIDEO_FORMAT_221_1;
527 event.u.size.aspect_ratio = VIDEO_FORMAT_221_1;
528 av7110->videostate.video_format = VIDEO_FORMAT_221_1;
529 break;
530 default:
531 av7110->video_size.aspect_ratio = VIDEO_FORMAT_4_3;
532 event.u.size.aspect_ratio = VIDEO_FORMAT_4_3;
533 av7110->videostate.video_format = VIDEO_FORMAT_4_3;
534 }
535 dvb_video_add_event(av7110, &event);
536 break;
537 }
538
539 case DATA_CI_PUT:
540 {
541 int avail;
542 struct dvb_ringbuffer *cibuf = &av7110->ci_wbuffer;
543
544 avail = dvb_ringbuffer_avail(cibuf);
545 if (avail <= 2) {
546 iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);
547 iwdebi(av7110, DEBINOSWAP, TX_LEN, 0, 2);
548 iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);
549 break;
550 }
551 len = DVB_RINGBUFFER_PEEK(cibuf, 0) << 8;
552 len |= DVB_RINGBUFFER_PEEK(cibuf, 1);
553 if (avail < len + 2) {
554 iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);
555 iwdebi(av7110, DEBINOSWAP, TX_LEN, 0, 2);
556 iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);
557 break;
558 }
559 DVB_RINGBUFFER_SKIP(cibuf, 2);
560
561 dvb_ringbuffer_read(cibuf, av7110->debi_virt, len, 0);
562
563 iwdebi(av7110, DEBINOSWAP, TX_LEN, len, 2);
564 iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, len, 2);
565 dprintk(8, "DMA: CI\n");
566 start_debi_dma(av7110, DEBI_WRITE, DPRAM_BASE + txbuf, len);
567 spin_unlock(&av7110->debilock);
568 wake_up(&cibuf->queue);
569 return;
570 }
571
572 case DATA_MPEG_PLAY:
573 if (!av7110->playing) {
574 iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);
575 iwdebi(av7110, DEBINOSWAP, TX_LEN, 0, 2);
576 iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);
577 break;
578 }
579 len = 0;
580 if (av7110->debitype & 0x100) {
581 spin_lock(&av7110->aout.lock);
582 len = av7110_pes_play(av7110->debi_virt, &av7110->aout, 2048);
583 spin_unlock(&av7110->aout.lock);
584 }
585 if (len <= 0 && (av7110->debitype & 0x200)
586 &&av7110->videostate.play_state != VIDEO_FREEZED) {
587 spin_lock(&av7110->avout.lock);
588 len = av7110_pes_play(av7110->debi_virt, &av7110->avout, 2048);
589 spin_unlock(&av7110->avout.lock);
590 }
591 if (len <= 0) {
592 iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);
593 iwdebi(av7110, DEBINOSWAP, TX_LEN, 0, 2);
594 iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);
595 break;
596 }
597 dprintk(8, "GPIO0 PES_PLAY len=%04x\n", len);
598 iwdebi(av7110, DEBINOSWAP, TX_LEN, len, 2);
599 iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, len, 2);
600 dprintk(8, "DMA: MPEG_PLAY\n");
601 start_debi_dma(av7110, DEBI_WRITE, DPRAM_BASE + txbuf, len);
602 spin_unlock(&av7110->debilock);
603 return;
604
605 case DATA_BMP_LOAD:
606 len = av7110->debilen;
607 dprintk(8, "gpio DATA_BMP_LOAD len %d\n", len);
608 if (!len) {
609 av7110->bmp_state = BMP_LOADED;
610 iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);
611 iwdebi(av7110, DEBINOSWAP, TX_LEN, 0, 2);
612 iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);
613 wake_up(&av7110->bmpq);
614 dprintk(8, "gpio DATA_BMP_LOAD done\n");
615 break;
616 }
617 if (len > av7110->bmplen)
618 len = av7110->bmplen;
619 if (len > 2 * 1024)
620 len = 2 * 1024;
621 iwdebi(av7110, DEBINOSWAP, TX_LEN, len, 2);
622 iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, len, 2);
623 memcpy(av7110->debi_virt, av7110->bmpbuf+av7110->bmpp, len);
624 av7110->bmpp += len;
625 av7110->bmplen -= len;
626 dprintk(8, "gpio DATA_BMP_LOAD DMA len %d\n", len);
627 start_debi_dma(av7110, DEBI_WRITE, DPRAM_BASE+txbuf, len);
628 spin_unlock(&av7110->debilock);
629 return;
630
631 case DATA_CI_GET:
632 case DATA_COMMON_INTERFACE:
633 case DATA_FSECTION:
634 case DATA_IPMPE:
635 case DATA_PIPING:
636 if (!len || len > 4 * 1024) {
637 iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
638 break;
639 }
640 /* fall through */
641
642 case DATA_TS_RECORD:
643 case DATA_PES_RECORD:
644 dprintk(8, "DMA: TS_REC etc.\n");
645 start_debi_dma(av7110, DEBI_READ, DPRAM_BASE+rxbuf, len);
646 spin_unlock(&av7110->debilock);
647 return;
648
649 case DATA_DEBUG_MESSAGE:
650 if (!len || len > 0xff) {
651 iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
652 break;
653 }
654 start_debi_dma(av7110, DEBI_READ, Reserved, len);
655 spin_unlock(&av7110->debilock);
656 return;
657
658 case DATA_IRCOMMAND:
Oliver Endriss03388ae2005-09-09 13:03:12 -0700659 if (av7110->ir_handler)
660 av7110->ir_handler(av7110,
661 swahw32(irdebi(av7110, DEBINOSWAP, Reserved, 0, 4)));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700662 iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
663 break;
664
665 default:
666 printk("dvb-ttpci: gpioirq unknown type=%d len=%d\n",
667 av7110->debitype, av7110->debilen);
668 break;
669 }
670 av7110->debitype = -1;
671 ARM_ClearMailBox(av7110);
672 spin_unlock(&av7110->debilock);
673}
674
675
676#ifdef CONFIG_DVB_AV7110_OSD
677static int dvb_osd_ioctl(struct inode *inode, struct file *file,
678 unsigned int cmd, void *parg)
679{
680 struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;
681 struct av7110 *av7110 = (struct av7110 *) dvbdev->priv;
682
683 dprintk(4, "%p\n", av7110);
684
685 if (cmd == OSD_SEND_CMD)
686 return av7110_osd_cmd(av7110, (osd_cmd_t *) parg);
687 if (cmd == OSD_GET_CAPABILITY)
688 return av7110_osd_capability(av7110, (osd_cap_t *) parg);
689
690 return -EINVAL;
691}
692
693
694static struct file_operations dvb_osd_fops = {
695 .owner = THIS_MODULE,
696 .ioctl = dvb_generic_ioctl,
697 .open = dvb_generic_open,
698 .release = dvb_generic_release,
699};
700
701static struct dvb_device dvbdev_osd = {
702 .priv = NULL,
703 .users = 1,
704 .writers = 1,
705 .fops = &dvb_osd_fops,
706 .kernel_ioctl = dvb_osd_ioctl,
707};
708#endif /* CONFIG_DVB_AV7110_OSD */
709
710
711static inline int SetPIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid,
712 u16 subpid, u16 pcrpid)
713{
714 dprintk(4, "%p\n", av7110);
715
716 if (vpid == 0x1fff || apid == 0x1fff ||
717 ttpid == 0x1fff || subpid == 0x1fff || pcrpid == 0x1fff) {
718 vpid = apid = ttpid = subpid = pcrpid = 0;
719 av7110->pids[DMX_PES_VIDEO] = 0;
720 av7110->pids[DMX_PES_AUDIO] = 0;
721 av7110->pids[DMX_PES_TELETEXT] = 0;
722 av7110->pids[DMX_PES_PCR] = 0;
723 }
724
725 return av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, MultiPID, 5,
726 pcrpid, vpid, apid, ttpid, subpid);
727}
728
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700729int ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700730 u16 subpid, u16 pcrpid)
731{
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700732 int ret = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700733 dprintk(4, "%p\n", av7110);
734
735 if (down_interruptible(&av7110->pid_mutex))
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700736 return -ERESTARTSYS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700737
738 if (!(vpid & 0x8000))
739 av7110->pids[DMX_PES_VIDEO] = vpid;
740 if (!(apid & 0x8000))
741 av7110->pids[DMX_PES_AUDIO] = apid;
742 if (!(ttpid & 0x8000))
743 av7110->pids[DMX_PES_TELETEXT] = ttpid;
744 if (!(pcrpid & 0x8000))
745 av7110->pids[DMX_PES_PCR] = pcrpid;
746
747 av7110->pids[DMX_PES_SUBTITLE] = 0;
748
749 if (av7110->fe_synced) {
750 pcrpid = av7110->pids[DMX_PES_PCR];
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700751 ret = SetPIDs(av7110, vpid, apid, ttpid, subpid, pcrpid);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700752 }
753
754 up(&av7110->pid_mutex);
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700755 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700756}
757
758
759/******************************************************************************
760 * hardware filter functions
761 ******************************************************************************/
762
763static int StartHWFilter(struct dvb_demux_filter *dvbdmxfilter)
764{
765 struct dvb_demux_feed *dvbdmxfeed = dvbdmxfilter->feed;
766 struct av7110 *av7110 = (struct av7110 *) dvbdmxfeed->demux->priv;
767 u16 buf[20];
768 int ret, i;
769 u16 handle;
770// u16 mode = 0x0320;
771 u16 mode = 0xb96a;
772
773 dprintk(4, "%p\n", av7110);
774
775 if (dvbdmxfilter->type == DMX_TYPE_SEC) {
776 if (hw_sections) {
777 buf[4] = (dvbdmxfilter->filter.filter_value[0] << 8) |
778 dvbdmxfilter->maskandmode[0];
779 for (i = 3; i < 18; i++)
780 buf[i + 4 - 2] =
781 (dvbdmxfilter->filter.filter_value[i] << 8) |
782 dvbdmxfilter->maskandmode[i];
783 mode = 4;
784 }
785 } else if ((dvbdmxfeed->ts_type & TS_PACKET) &&
786 !(dvbdmxfeed->ts_type & TS_PAYLOAD_ONLY)) {
787 av7110_p2t_init(&av7110->p2t_filter[dvbdmxfilter->index], dvbdmxfeed);
788 }
789
790 buf[0] = (COMTYPE_PID_FILTER << 8) + AddPIDFilter;
791 buf[1] = 16;
792 buf[2] = dvbdmxfeed->pid;
793 buf[3] = mode;
794
795 ret = av7110_fw_request(av7110, buf, 20, &handle, 1);
796 if (ret != 0 || handle >= 32) {
797 printk("dvb-ttpci: %s error buf %04x %04x %04x %04x "
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700798 "ret %d handle %04x\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700799 __FUNCTION__, buf[0], buf[1], buf[2], buf[3],
800 ret, handle);
801 dvbdmxfilter->hw_handle = 0xffff;
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700802 if (!ret)
803 ret = -1;
804 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700805 }
806
807 av7110->handle2filter[handle] = dvbdmxfilter;
808 dvbdmxfilter->hw_handle = handle;
809
810 return ret;
811}
812
813static int StopHWFilter(struct dvb_demux_filter *dvbdmxfilter)
814{
815 struct av7110 *av7110 = (struct av7110 *) dvbdmxfilter->feed->demux->priv;
816 u16 buf[3];
817 u16 answ[2];
818 int ret;
819 u16 handle;
820
821 dprintk(4, "%p\n", av7110);
822
823 handle = dvbdmxfilter->hw_handle;
824 if (handle >= 32) {
825 printk("%s tried to stop invalid filter %04x, filter type = %x\n",
826 __FUNCTION__, handle, dvbdmxfilter->type);
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700827 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700828 }
829
830 av7110->handle2filter[handle] = NULL;
831
832 buf[0] = (COMTYPE_PID_FILTER << 8) + DelPIDFilter;
833 buf[1] = 1;
834 buf[2] = handle;
835 ret = av7110_fw_request(av7110, buf, 3, answ, 2);
836 if (ret != 0 || answ[1] != handle) {
837 printk("dvb-ttpci: %s error cmd %04x %04x %04x ret %x "
838 "resp %04x %04x pid %d\n",
839 __FUNCTION__, buf[0], buf[1], buf[2], ret,
840 answ[0], answ[1], dvbdmxfilter->feed->pid);
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700841 if (!ret)
842 ret = -1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700843 }
844 return ret;
845}
846
847
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700848static int dvb_feed_start_pid(struct dvb_demux_feed *dvbdmxfeed)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700849{
850 struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
851 struct av7110 *av7110 = (struct av7110 *) dvbdmx->priv;
852 u16 *pid = dvbdmx->pids, npids[5];
853 int i;
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700854 int ret = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700855
856 dprintk(4, "%p\n", av7110);
857
858 npids[0] = npids[1] = npids[2] = npids[3] = npids[4] = 0xffff;
859 i = dvbdmxfeed->pes_type;
860 npids[i] = (pid[i]&0x8000) ? 0 : pid[i];
861 if ((i == 2) && npids[i] && (dvbdmxfeed->ts_type & TS_PACKET)) {
862 npids[i] = 0;
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700863 ret = ChangePIDs(av7110, npids[1], npids[0], npids[2], npids[3], npids[4]);
864 if (!ret)
865 ret = StartHWFilter(dvbdmxfeed->filter);
866 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700867 }
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700868 if (dvbdmxfeed->pes_type <= 2 || dvbdmxfeed->pes_type == 4) {
869 ret = ChangePIDs(av7110, npids[1], npids[0], npids[2], npids[3], npids[4]);
870 if (ret)
871 return ret;
872 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700873
874 if (dvbdmxfeed->pes_type < 2 && npids[0])
875 if (av7110->fe_synced)
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700876 {
877 ret = av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, Scan, 0);
878 if (ret)
879 return ret;
880 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700881
882 if ((dvbdmxfeed->ts_type & TS_PACKET)) {
883 if (dvbdmxfeed->pes_type == 0 && !(dvbdmx->pids[0] & 0x8000))
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700884 ret = av7110_av_start_record(av7110, RP_AUDIO, dvbdmxfeed);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700885 if (dvbdmxfeed->pes_type == 1 && !(dvbdmx->pids[1] & 0x8000))
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700886 ret = av7110_av_start_record(av7110, RP_VIDEO, dvbdmxfeed);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700887 }
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700888 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700889}
890
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700891static int dvb_feed_stop_pid(struct dvb_demux_feed *dvbdmxfeed)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700892{
893 struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
894 struct av7110 *av7110 = (struct av7110 *) dvbdmx->priv;
895 u16 *pid = dvbdmx->pids, npids[5];
896 int i;
897
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700898 int ret = 0;
899
Linus Torvalds1da177e2005-04-16 15:20:36 -0700900 dprintk(4, "%p\n", av7110);
901
902 if (dvbdmxfeed->pes_type <= 1) {
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700903 ret = av7110_av_stop(av7110, dvbdmxfeed->pes_type ? RP_VIDEO : RP_AUDIO);
904 if (ret)
905 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700906 if (!av7110->rec_mode)
907 dvbdmx->recording = 0;
908 if (!av7110->playing)
909 dvbdmx->playing = 0;
910 }
911 npids[0] = npids[1] = npids[2] = npids[3] = npids[4] = 0xffff;
912 i = dvbdmxfeed->pes_type;
913 switch (i) {
914 case 2: //teletext
915 if (dvbdmxfeed->ts_type & TS_PACKET)
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700916 ret = StopHWFilter(dvbdmxfeed->filter);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700917 npids[2] = 0;
918 break;
919 case 0:
920 case 1:
921 case 4:
922 if (!pids_off)
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700923 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700924 npids[i] = (pid[i]&0x8000) ? 0 : pid[i];
925 break;
926 }
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700927 if (!ret)
928 ret = ChangePIDs(av7110, npids[1], npids[0], npids[2], npids[3], npids[4]);
929 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700930}
931
932static int av7110_start_feed(struct dvb_demux_feed *feed)
933{
934 struct dvb_demux *demux = feed->demux;
935 struct av7110 *av7110 = demux->priv;
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700936 int ret = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700937
938 dprintk(4, "%p\n", av7110);
939
940 if (!demux->dmx.frontend)
941 return -EINVAL;
942
943 if (feed->pid > 0x1fff)
944 return -EINVAL;
945
946 if (feed->type == DMX_TYPE_TS) {
947 if ((feed->ts_type & TS_DECODER) &&
948 (feed->pes_type < DMX_TS_PES_OTHER)) {
949 switch (demux->dmx.frontend->source) {
950 case DMX_MEMORY_FE:
951 if (feed->ts_type & TS_DECODER)
952 if (feed->pes_type < 2 &&
953 !(demux->pids[0] & 0x8000) &&
954 !(demux->pids[1] & 0x8000)) {
955 dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout);
956 dvb_ringbuffer_flush_spinlock_wakeup(&av7110->aout);
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700957 ret = av7110_av_start_play(av7110,RP_AV);
958 if (!ret)
959 demux->playing = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700960 }
961 break;
962 default:
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700963 ret = dvb_feed_start_pid(feed);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700964 break;
965 }
966 } else if ((feed->ts_type & TS_PACKET) &&
967 (demux->dmx.frontend->source != DMX_MEMORY_FE)) {
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700968 ret = StartHWFilter(feed->filter);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700969 }
970 }
971
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700972 else if (feed->type == DMX_TYPE_SEC) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700973 int i;
974
975 for (i = 0; i < demux->filternum; i++) {
976 if (demux->filter[i].state != DMX_STATE_READY)
977 continue;
978 if (demux->filter[i].type != DMX_TYPE_SEC)
979 continue;
980 if (demux->filter[i].filter.parent != &feed->feed.sec)
981 continue;
982 demux->filter[i].state = DMX_STATE_GO;
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700983 if (demux->dmx.frontend->source != DMX_MEMORY_FE) {
984 ret = StartHWFilter(&demux->filter[i]);
985 if (ret)
986 break;
987 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700988 }
989 }
990
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700991 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700992}
993
994
995static int av7110_stop_feed(struct dvb_demux_feed *feed)
996{
997 struct dvb_demux *demux = feed->demux;
998 struct av7110 *av7110 = demux->priv;
Johannes Stezenbach12ba0502005-07-07 17:58:00 -0700999 int i, rc, ret = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001000 dprintk(4, "%p\n", av7110);
1001
1002 if (feed->type == DMX_TYPE_TS) {
1003 if (feed->ts_type & TS_DECODER) {
1004 if (feed->pes_type >= DMX_TS_PES_OTHER ||
1005 !demux->pesfilter[feed->pes_type])
1006 return -EINVAL;
1007 demux->pids[feed->pes_type] |= 0x8000;
1008 demux->pesfilter[feed->pes_type] = NULL;
1009 }
1010 if (feed->ts_type & TS_DECODER &&
1011 feed->pes_type < DMX_TS_PES_OTHER) {
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001012 ret = dvb_feed_stop_pid(feed);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001013 } else
1014 if ((feed->ts_type & TS_PACKET) &&
1015 (demux->dmx.frontend->source != DMX_MEMORY_FE))
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001016 ret = StopHWFilter(feed->filter);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001017 }
1018
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001019 if (!ret && feed->type == DMX_TYPE_SEC) {
Johannes Stezenbach12ba0502005-07-07 17:58:00 -07001020 for (i = 0; i<demux->filternum; i++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001021 if (demux->filter[i].state == DMX_STATE_GO &&
1022 demux->filter[i].filter.parent == &feed->feed.sec) {
1023 demux->filter[i].state = DMX_STATE_READY;
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001024 if (demux->dmx.frontend->source != DMX_MEMORY_FE) {
Johannes Stezenbach12ba0502005-07-07 17:58:00 -07001025 rc = StopHWFilter(&demux->filter[i]);
1026 if (!ret)
1027 ret = rc;
1028 /* keep going, stop as many filters as possible */
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001029 }
Johannes Stezenbach12ba0502005-07-07 17:58:00 -07001030 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001031 }
1032 }
1033
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001034 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001035}
1036
1037
1038static void restart_feeds(struct av7110 *av7110)
1039{
1040 struct dvb_demux *dvbdmx = &av7110->demux;
1041 struct dvb_demux_feed *feed;
1042 int mode;
1043 int i;
1044
1045 dprintk(4, "%p\n", av7110);
1046
1047 mode = av7110->playing;
1048 av7110->playing = 0;
1049 av7110->rec_mode = 0;
1050
1051 for (i = 0; i < dvbdmx->filternum; i++) {
1052 feed = &dvbdmx->feed[i];
1053 if (feed->state == DMX_STATE_GO)
1054 av7110_start_feed(feed);
1055 }
1056
1057 if (mode)
1058 av7110_av_start_play(av7110, mode);
1059}
1060
1061static int dvb_get_stc(struct dmx_demux *demux, unsigned int num,
1062 uint64_t *stc, unsigned int *base)
1063{
1064 int ret;
1065 u16 fwstc[4];
1066 u16 tag = ((COMTYPE_REQUEST << 8) + ReqSTC);
1067 struct dvb_demux *dvbdemux;
1068 struct av7110 *av7110;
1069
1070 /* pointer casting paranoia... */
1071 if (!demux)
1072 BUG();
1073 dvbdemux = (struct dvb_demux *) demux->priv;
1074 if (!dvbdemux)
1075 BUG();
1076 av7110 = (struct av7110 *) dvbdemux->priv;
1077
1078 dprintk(4, "%p\n", av7110);
1079
1080 if (num != 0)
1081 return -EINVAL;
1082
1083 ret = av7110_fw_request(av7110, &tag, 0, fwstc, 4);
1084 if (ret) {
1085 printk(KERN_ERR "%s: av7110_fw_request error\n", __FUNCTION__);
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001086 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001087 }
1088 dprintk(2, "fwstc = %04hx %04hx %04hx %04hx\n",
1089 fwstc[0], fwstc[1], fwstc[2], fwstc[3]);
1090
1091 *stc = (((uint64_t) ((fwstc[3] & 0x8000) >> 15)) << 32) |
1092 (((uint64_t) fwstc[1]) << 16) | ((uint64_t) fwstc[0]);
1093 *base = 1;
1094
1095 dprintk(4, "stc = %lu\n", (unsigned long)*stc);
1096
1097 return 0;
1098}
1099
1100
1101/******************************************************************************
1102 * SEC device file operations
1103 ******************************************************************************/
1104
1105
1106static int av7110_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
1107{
1108 struct av7110* av7110 = (struct av7110*) fe->dvb->priv;
1109
1110 switch (tone) {
1111 case SEC_TONE_ON:
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001112 return Set22K(av7110, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001113
1114 case SEC_TONE_OFF:
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001115 return Set22K(av7110, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001116
1117 default:
1118 return -EINVAL;
1119 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001120}
1121
1122static int av7110_diseqc_send_master_cmd(struct dvb_frontend* fe,
1123 struct dvb_diseqc_master_cmd* cmd)
1124{
1125 struct av7110* av7110 = fe->dvb->priv;
1126
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001127 return av7110_diseqc_send(av7110, cmd->msg_len, cmd->msg, -1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001128}
1129
1130static int av7110_diseqc_send_burst(struct dvb_frontend* fe,
1131 fe_sec_mini_cmd_t minicmd)
1132{
1133 struct av7110* av7110 = fe->dvb->priv;
1134
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001135 return av7110_diseqc_send(av7110, 0, NULL, minicmd);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001136}
1137
1138/* simplified code from budget-core.c */
1139static int stop_ts_capture(struct av7110 *budget)
1140{
1141 dprintk(2, "budget: %p\n", budget);
1142
1143 if (--budget->feeding1)
1144 return budget->feeding1;
1145 saa7146_write(budget->dev, MC1, MASK_20); /* DMA3 off */
1146 SAA7146_IER_DISABLE(budget->dev, MASK_10);
1147 SAA7146_ISR_CLEAR(budget->dev, MASK_10);
1148 return 0;
1149}
1150
1151static int start_ts_capture(struct av7110 *budget)
1152{
1153 dprintk(2, "budget: %p\n", budget);
1154
1155 if (budget->feeding1)
1156 return ++budget->feeding1;
1157 memset(budget->grabbing, 0x00, TS_HEIGHT * TS_WIDTH);
1158 budget->tsf = 0xff;
1159 budget->ttbp = 0;
1160 SAA7146_IER_ENABLE(budget->dev, MASK_10); /* VPE */
1161 saa7146_write(budget->dev, MC1, (MASK_04 | MASK_20)); /* DMA3 on */
1162 return ++budget->feeding1;
1163}
1164
1165static int budget_start_feed(struct dvb_demux_feed *feed)
1166{
1167 struct dvb_demux *demux = feed->demux;
1168 struct av7110 *budget = (struct av7110 *) demux->priv;
1169 int status;
1170
1171 dprintk(2, "av7110: %p\n", budget);
1172
1173 spin_lock(&budget->feedlock1);
1174 feed->pusi_seen = 0; /* have a clean section start */
1175 status = start_ts_capture(budget);
1176 spin_unlock(&budget->feedlock1);
1177 return status;
1178}
1179
1180static int budget_stop_feed(struct dvb_demux_feed *feed)
1181{
1182 struct dvb_demux *demux = feed->demux;
1183 struct av7110 *budget = (struct av7110 *) demux->priv;
1184 int status;
1185
1186 dprintk(2, "budget: %p\n", budget);
1187
1188 spin_lock(&budget->feedlock1);
1189 status = stop_ts_capture(budget);
1190 spin_unlock(&budget->feedlock1);
1191 return status;
1192}
1193
1194static void vpeirq(unsigned long data)
1195{
1196 struct av7110 *budget = (struct av7110 *) data;
1197 u8 *mem = (u8 *) (budget->grabbing);
1198 u32 olddma = budget->ttbp;
1199 u32 newdma = saa7146_read(budget->dev, PCI_VDP3);
1200
1201 if (!budgetpatch) {
1202 printk("av7110.c: vpeirq() called while budgetpatch disabled!"
1203 " check saa7146 IER register\n");
1204 BUG();
1205 }
1206 /* nearest lower position divisible by 188 */
1207 newdma -= newdma % 188;
1208
1209 if (newdma >= TS_BUFLEN)
1210 return;
1211
1212 budget->ttbp = newdma;
1213
1214 if (!budget->feeding1 || (newdma == olddma))
1215 return;
1216
1217#if 0
1218 /* track rps1 activity */
1219 printk("vpeirq: %02x Event Counter 1 0x%04x\n",
1220 mem[olddma],
1221 saa7146_read(budget->dev, EC1R) & 0x3fff);
1222#endif
1223
1224 if (newdma > olddma)
1225 /* no wraparound, dump olddma..newdma */
1226 dvb_dmx_swfilter_packets(&budget->demux1, mem + olddma, (newdma - olddma) / 188);
1227 else {
1228 /* wraparound, dump olddma..buflen and 0..newdma */
1229 dvb_dmx_swfilter_packets(&budget->demux1, mem + olddma, (TS_BUFLEN - olddma) / 188);
1230 dvb_dmx_swfilter_packets(&budget->demux1, mem, newdma / 188);
1231 }
1232}
1233
1234static int av7110_register(struct av7110 *av7110)
1235{
1236 int ret, i;
1237 struct dvb_demux *dvbdemux = &av7110->demux;
1238 struct dvb_demux *dvbdemux1 = &av7110->demux1;
1239
1240 dprintk(4, "%p\n", av7110);
1241
1242 if (av7110->registered)
1243 return -1;
1244
1245 av7110->registered = 1;
1246
1247 dvbdemux->priv = (void *) av7110;
1248
1249 for (i = 0; i < 32; i++)
1250 av7110->handle2filter[i] = NULL;
1251
1252 dvbdemux->filternum = 32;
1253 dvbdemux->feednum = 32;
1254 dvbdemux->start_feed = av7110_start_feed;
1255 dvbdemux->stop_feed = av7110_stop_feed;
1256 dvbdemux->write_to_decoder = av7110_write_to_decoder;
1257 dvbdemux->dmx.capabilities = (DMX_TS_FILTERING | DMX_SECTION_FILTERING |
1258 DMX_MEMORY_BASED_FILTERING);
1259
1260 dvb_dmx_init(&av7110->demux);
1261 av7110->demux.dmx.get_stc = dvb_get_stc;
1262
1263 av7110->dmxdev.filternum = 32;
1264 av7110->dmxdev.demux = &dvbdemux->dmx;
1265 av7110->dmxdev.capabilities = 0;
1266
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001267 dvb_dmxdev_init(&av7110->dmxdev, &av7110->dvb_adapter);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001268
1269 av7110->hw_frontend.source = DMX_FRONTEND_0;
1270
1271 ret = dvbdemux->dmx.add_frontend(&dvbdemux->dmx, &av7110->hw_frontend);
1272
1273 if (ret < 0)
1274 return ret;
1275
1276 av7110->mem_frontend.source = DMX_MEMORY_FE;
1277
1278 ret = dvbdemux->dmx.add_frontend(&dvbdemux->dmx, &av7110->mem_frontend);
1279
1280 if (ret < 0)
1281 return ret;
1282
1283 ret = dvbdemux->dmx.connect_frontend(&dvbdemux->dmx,
1284 &av7110->hw_frontend);
1285 if (ret < 0)
1286 return ret;
1287
1288 av7110_av_register(av7110);
1289 av7110_ca_register(av7110);
1290
1291#ifdef CONFIG_DVB_AV7110_OSD
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001292 dvb_register_device(&av7110->dvb_adapter, &av7110->osd_dev,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001293 &dvbdev_osd, av7110, DVB_DEVICE_OSD);
1294#endif
1295
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001296 dvb_net_init(&av7110->dvb_adapter, &av7110->dvb_net, &dvbdemux->dmx);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001297
1298 if (budgetpatch) {
1299 /* initialize software demux1 without its own frontend
1300 * demux1 hardware is connected to frontend0 of demux0
1301 */
1302 dvbdemux1->priv = (void *) av7110;
1303
1304 dvbdemux1->filternum = 256;
1305 dvbdemux1->feednum = 256;
1306 dvbdemux1->start_feed = budget_start_feed;
1307 dvbdemux1->stop_feed = budget_stop_feed;
1308 dvbdemux1->write_to_decoder = NULL;
1309
1310 dvbdemux1->dmx.capabilities = (DMX_TS_FILTERING | DMX_SECTION_FILTERING |
1311 DMX_MEMORY_BASED_FILTERING);
1312
1313 dvb_dmx_init(&av7110->demux1);
1314
1315 av7110->dmxdev1.filternum = 256;
1316 av7110->dmxdev1.demux = &dvbdemux1->dmx;
1317 av7110->dmxdev1.capabilities = 0;
1318
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001319 dvb_dmxdev_init(&av7110->dmxdev1, &av7110->dvb_adapter);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001320
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001321 dvb_net_init(&av7110->dvb_adapter, &av7110->dvb_net1, &dvbdemux1->dmx);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001322 printk("dvb-ttpci: additional demux1 for budget-patch registered\n");
1323 }
1324 return 0;
1325}
1326
1327
1328static void dvb_unregister(struct av7110 *av7110)
1329{
1330 struct dvb_demux *dvbdemux = &av7110->demux;
1331 struct dvb_demux *dvbdemux1 = &av7110->demux1;
1332
1333 dprintk(4, "%p\n", av7110);
1334
1335 if (!av7110->registered)
1336 return;
1337
1338 if (budgetpatch) {
1339 dvb_net_release(&av7110->dvb_net1);
1340 dvbdemux->dmx.close(&dvbdemux1->dmx);
1341 dvb_dmxdev_release(&av7110->dmxdev1);
1342 dvb_dmx_release(&av7110->demux1);
1343 }
1344
1345 dvb_net_release(&av7110->dvb_net);
1346
1347 dvbdemux->dmx.close(&dvbdemux->dmx);
1348 dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, &av7110->hw_frontend);
1349 dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, &av7110->mem_frontend);
1350
1351 dvb_dmxdev_release(&av7110->dmxdev);
1352 dvb_dmx_release(&av7110->demux);
1353
1354 if (av7110->fe != NULL)
1355 dvb_unregister_frontend(av7110->fe);
1356 dvb_unregister_device(av7110->osd_dev);
1357 av7110_av_unregister(av7110);
1358 av7110_ca_unregister(av7110);
1359}
1360
1361
1362/****************************************************************************
1363 * I2C client commands
1364 ****************************************************************************/
1365
1366int i2c_writereg(struct av7110 *av7110, u8 id, u8 reg, u8 val)
1367{
1368 u8 msg[2] = { reg, val };
1369 struct i2c_msg msgs;
1370
1371 msgs.flags = 0;
1372 msgs.addr = id / 2;
1373 msgs.len = 2;
1374 msgs.buf = msg;
1375 return i2c_transfer(&av7110->i2c_adap, &msgs, 1);
1376}
1377
1378#if 0
1379u8 i2c_readreg(struct av7110 *av7110, u8 id, u8 reg)
1380{
1381 u8 mm1[] = {0x00};
1382 u8 mm2[] = {0x00};
1383 struct i2c_msg msgs[2];
1384
1385 msgs[0].flags = 0;
1386 msgs[1].flags = I2C_M_RD;
1387 msgs[0].addr = msgs[1].addr = id / 2;
1388 mm1[0] = reg;
1389 msgs[0].len = 1; msgs[1].len = 1;
1390 msgs[0].buf = mm1; msgs[1].buf = mm2;
1391 i2c_transfer(&av7110->i2c_adap, msgs, 2);
1392
1393 return mm2[0];
1394}
1395#endif
1396
1397/****************************************************************************
1398 * INITIALIZATION
1399 ****************************************************************************/
1400
1401
1402static int check_firmware(struct av7110* av7110)
1403{
1404 u32 crc = 0, len = 0;
1405 unsigned char *ptr;
1406
1407 /* check for firmware magic */
1408 ptr = av7110->bin_fw;
1409 if (ptr[0] != 'A' || ptr[1] != 'V' ||
1410 ptr[2] != 'F' || ptr[3] != 'W') {
1411 printk("dvb-ttpci: this is not an av7110 firmware\n");
1412 return -EINVAL;
1413 }
1414 ptr += 4;
1415
1416 /* check dpram file */
1417 crc = ntohl(*(u32*) ptr);
1418 ptr += 4;
1419 len = ntohl(*(u32*) ptr);
1420 ptr += 4;
1421 if (len >= 512) {
1422 printk("dvb-ttpci: dpram file is way to big.\n");
1423 return -EINVAL;
1424 }
1425 if (crc != crc32_le(0, ptr, len)) {
1426 printk("dvb-ttpci: crc32 of dpram file does not match.\n");
1427 return -EINVAL;
1428 }
1429 av7110->bin_dpram = ptr;
1430 av7110->size_dpram = len;
1431 ptr += len;
1432
1433 /* check root file */
1434 crc = ntohl(*(u32*) ptr);
1435 ptr += 4;
1436 len = ntohl(*(u32*) ptr);
1437 ptr += 4;
1438
1439 if (len <= 200000 || len >= 300000 ||
1440 len > ((av7110->bin_fw + av7110->size_fw) - ptr)) {
1441 printk("dvb-ttpci: root file has strange size (%d). aborting.\n", len);
1442 return -EINVAL;
1443 }
1444 if( crc != crc32_le(0, ptr, len)) {
1445 printk("dvb-ttpci: crc32 of root file does not match.\n");
1446 return -EINVAL;
1447 }
1448 av7110->bin_root = ptr;
1449 av7110->size_root = len;
1450 return 0;
1451}
1452
1453#ifdef CONFIG_DVB_AV7110_FIRMWARE_FILE
1454#include "av7110_firm.h"
1455static void put_firmware(struct av7110* av7110)
1456{
1457 av7110->bin_fw = NULL;
1458}
1459
1460static inline int get_firmware(struct av7110* av7110)
1461{
1462 av7110->bin_fw = dvb_ttpci_fw;
1463 av7110->size_fw = sizeof(dvb_ttpci_fw);
1464 return check_firmware(av7110);
1465}
1466#else
1467static void put_firmware(struct av7110* av7110)
1468{
1469 vfree(av7110->bin_fw);
1470}
1471
1472static int get_firmware(struct av7110* av7110)
1473{
1474 int ret;
1475 const struct firmware *fw;
1476
1477 /* request the av7110 firmware, this will block until someone uploads it */
1478 ret = request_firmware(&fw, "dvb-ttpci-01.fw", &av7110->dev->pci->dev);
1479 if (ret) {
1480 if (ret == -ENOENT) {
1481 printk(KERN_ERR "dvb-ttpci: could not load firmware,"
1482 " file not found: dvb-ttpci-01.fw\n");
1483 printk(KERN_ERR "dvb-ttpci: usually this should be in"
1484 " /usr/lib/hotplug/firmware\n");
1485 printk(KERN_ERR "dvb-ttpci: and can be downloaded here"
1486 " http://www.linuxtv.org/download/dvb/firmware/\n");
1487 } else
1488 printk(KERN_ERR "dvb-ttpci: cannot request firmware"
1489 " (error %i)\n", ret);
1490 return -EINVAL;
1491 }
1492
1493 if (fw->size <= 200000) {
1494 printk("dvb-ttpci: this firmware is way too small.\n");
1495 release_firmware(fw);
1496 return -EINVAL;
1497 }
1498
1499 /* check if the firmware is available */
1500 av7110->bin_fw = (unsigned char *) vmalloc(fw->size);
1501 if (NULL == av7110->bin_fw) {
1502 dprintk(1, "out of memory\n");
1503 release_firmware(fw);
1504 return -ENOMEM;
1505 }
1506
1507 memcpy(av7110->bin_fw, fw->data, fw->size);
1508 av7110->size_fw = fw->size;
1509 if ((ret = check_firmware(av7110)))
1510 vfree(av7110->bin_fw);
1511
1512 release_firmware(fw);
1513 return ret;
1514}
1515#endif
1516
1517
1518static int alps_bsrv2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
1519{
1520 struct av7110* av7110 = (struct av7110*) fe->dvb->priv;
1521 u8 pwr = 0;
1522 u8 buf[4];
1523 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
1524 u32 div = (params->frequency + 479500) / 125;
1525
1526 if (params->frequency > 2000000) pwr = 3;
1527 else if (params->frequency > 1800000) pwr = 2;
1528 else if (params->frequency > 1600000) pwr = 1;
1529 else if (params->frequency > 1200000) pwr = 0;
1530 else if (params->frequency >= 1100000) pwr = 1;
1531 else pwr = 2;
1532
1533 buf[0] = (div >> 8) & 0x7f;
1534 buf[1] = div & 0xff;
1535 buf[2] = ((div & 0x18000) >> 10) | 0x95;
1536 buf[3] = (pwr << 6) | 0x30;
1537
1538 // NOTE: since we're using a prescaler of 2, we set the
1539 // divisor frequency to 62.5kHz and divide by 125 above
1540
1541 if (i2c_transfer (&av7110->i2c_adap, &msg, 1) != 1)
1542 return -EIO;
1543 return 0;
1544}
1545
1546static struct ves1x93_config alps_bsrv2_config = {
1547 .demod_address = 0x08,
1548 .xin = 90100000UL,
1549 .invert_pwm = 0,
1550 .pll_set = alps_bsrv2_pll_set,
1551};
1552
1553
1554static u8 alps_bsru6_inittab[] = {
1555 0x01, 0x15,
1556 0x02, 0x30,
1557 0x03, 0x00,
1558 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
1559 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */
1560 0x06, 0x40, /* DAC not used, set to high impendance mode */
1561 0x07, 0x00, /* DAC LSB */
1562 0x08, 0x40, /* DiSEqC off, LNB power on OP2/LOCK pin on */
1563 0x09, 0x00, /* FIFO */
1564 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
1565 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */
1566 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
1567 0x10, 0x3f, // AGC2 0x3d
1568 0x11, 0x84,
1569 0x12, 0xb5, // Lock detect: -64 Carrier freq detect:on
1570 0x15, 0xc9, // lock detector threshold
1571 0x16, 0x00,
1572 0x17, 0x00,
1573 0x18, 0x00,
1574 0x19, 0x00,
1575 0x1a, 0x00,
1576 0x1f, 0x50,
1577 0x20, 0x00,
1578 0x21, 0x00,
1579 0x22, 0x00,
1580 0x23, 0x00,
1581 0x28, 0x00, // out imp: normal out type: parallel FEC mode:0
1582 0x29, 0x1e, // 1/2 threshold
1583 0x2a, 0x14, // 2/3 threshold
1584 0x2b, 0x0f, // 3/4 threshold
1585 0x2c, 0x09, // 5/6 threshold
1586 0x2d, 0x05, // 7/8 threshold
1587 0x2e, 0x01,
1588 0x31, 0x1f, // test all FECs
1589 0x32, 0x19, // viterbi and synchro search
1590 0x33, 0xfc, // rs control
1591 0x34, 0x93, // error control
1592 0x0f, 0x52,
1593 0xff, 0xff
1594};
1595
1596static int alps_bsru6_set_symbol_rate(struct dvb_frontend* fe, u32 srate, u32 ratio)
1597{
1598 u8 aclk = 0;
1599 u8 bclk = 0;
1600
1601 if (srate < 1500000) { aclk = 0xb7; bclk = 0x47; }
1602 else if (srate < 3000000) { aclk = 0xb7; bclk = 0x4b; }
1603 else if (srate < 7000000) { aclk = 0xb7; bclk = 0x4f; }
1604 else if (srate < 14000000) { aclk = 0xb7; bclk = 0x53; }
1605 else if (srate < 30000000) { aclk = 0xb6; bclk = 0x53; }
1606 else if (srate < 45000000) { aclk = 0xb4; bclk = 0x51; }
1607
1608 stv0299_writereg(fe, 0x13, aclk);
1609 stv0299_writereg(fe, 0x14, bclk);
1610 stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
1611 stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
1612 stv0299_writereg(fe, 0x21, (ratio ) & 0xf0);
1613
1614 return 0;
1615}
1616
Andreas Oberrittercfbfce12005-09-09 13:02:30 -07001617static int alps_bsru6_pll_set(struct dvb_frontend* fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters* params)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001618{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001619 int ret;
1620 u8 data[4];
1621 u32 div;
1622 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
1623
1624 if ((params->frequency < 950000) || (params->frequency > 2150000))
1625 return -EINVAL;
1626
1627 div = (params->frequency + (125 - 1)) / 125; // round correctly
1628 data[0] = (div >> 8) & 0x7f;
1629 data[1] = div & 0xff;
1630 data[2] = 0x80 | ((div & 0x18000) >> 10) | 4;
1631 data[3] = 0xC4;
1632
1633 if (params->frequency > 1530000) data[3] = 0xc0;
1634
Andreas Oberrittercfbfce12005-09-09 13:02:30 -07001635 ret = i2c_transfer(i2c, &msg, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001636 if (ret != 1)
1637 return -EIO;
1638 return 0;
1639}
1640
1641static struct stv0299_config alps_bsru6_config = {
1642
1643 .demod_address = 0x68,
1644 .inittab = alps_bsru6_inittab,
1645 .mclk = 88000000UL,
1646 .invert = 1,
1647 .enhanced_tuning = 0,
1648 .skip_reinit = 0,
1649 .lock_output = STV0229_LOCKOUTPUT_1,
1650 .volt13_op0_op1 = STV0299_VOLT13_OP1,
1651 .min_delay_ms = 100,
1652 .set_symbol_rate = alps_bsru6_set_symbol_rate,
1653 .pll_set = alps_bsru6_pll_set,
1654};
1655
1656
Johannes Stezenbach3dfaebd2005-05-16 21:54:19 -07001657static u8 alps_bsbe1_inittab[] = {
1658 0x01, 0x15,
1659 0x02, 0x30,
1660 0x03, 0x00,
1661 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
1662 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */
1663 0x06, 0x40, /* DAC not used, set to high impendance mode */
1664 0x07, 0x00, /* DAC LSB */
1665 0x08, 0x40, /* DiSEqC off, LNB power on OP2/LOCK pin on */
1666 0x09, 0x00, /* FIFO */
1667 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
1668 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */
1669 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
1670 0x10, 0x3f, // AGC2 0x3d
1671 0x11, 0x84,
1672 0x12, 0xb5, // Lock detect: -64 Carrier freq detect:on
1673 0x15, 0xc9, // lock detector threshold
1674 0x16, 0x00,
1675 0x17, 0x00,
1676 0x18, 0x00,
1677 0x19, 0x00,
1678 0x1a, 0x00,
1679 0x1f, 0x50,
1680 0x20, 0x00,
1681 0x21, 0x00,
1682 0x22, 0x00,
1683 0x23, 0x00,
1684 0x28, 0x00, // out imp: normal out type: parallel FEC mode:0
1685 0x29, 0x1e, // 1/2 threshold
1686 0x2a, 0x14, // 2/3 threshold
1687 0x2b, 0x0f, // 3/4 threshold
1688 0x2c, 0x09, // 5/6 threshold
1689 0x2d, 0x05, // 7/8 threshold
1690 0x2e, 0x01,
1691 0x31, 0x1f, // test all FECs
1692 0x32, 0x19, // viterbi and synchro search
1693 0x33, 0xfc, // rs control
1694 0x34, 0x93, // error control
1695 0x0f, 0x92,
1696 0xff, 0xff
1697};
1698
Andreas Oberrittercfbfce12005-09-09 13:02:30 -07001699static int alps_bsbe1_pll_set(struct dvb_frontend* fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters* params)
Johannes Stezenbach3dfaebd2005-05-16 21:54:19 -07001700{
Johannes Stezenbach3dfaebd2005-05-16 21:54:19 -07001701 int ret;
1702 u8 data[4];
1703 u32 div;
1704 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
1705
1706 if ((params->frequency < 950000) || (params->frequency > 2150000))
1707 return -EINVAL;
1708
1709 div = (params->frequency + (125 - 1)) / 125; // round correctly
1710 data[0] = (div >> 8) & 0x7f;
1711 data[1] = div & 0xff;
1712 data[2] = 0x80 | ((div & 0x18000) >> 10) | 4;
1713 data[3] = (params->frequency > 1530000) ? 0xE0 : 0xE4;
1714
Andreas Oberrittercfbfce12005-09-09 13:02:30 -07001715 ret = i2c_transfer(i2c, &msg, 1);
Johannes Stezenbach3dfaebd2005-05-16 21:54:19 -07001716 return (ret != 1) ? -EIO : 0;
1717}
1718
1719static struct stv0299_config alps_bsbe1_config = {
1720 .demod_address = 0x68,
1721 .inittab = alps_bsbe1_inittab,
1722 .mclk = 88000000UL,
1723 .invert = 1,
1724 .enhanced_tuning = 0,
1725 .skip_reinit = 0,
1726 .min_delay_ms = 100,
1727 .set_symbol_rate = alps_bsru6_set_symbol_rate,
1728 .pll_set = alps_bsbe1_pll_set,
1729};
1730
1731static int lnbp21_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
1732{
1733 struct av7110* av7110 = (struct av7110*) fe->dvb->priv;
1734 int ret;
1735 u8 data[1];
1736 struct i2c_msg msg = { .addr = 0x08, .flags = 0, .buf = data, .len = sizeof(data) };
1737
1738 switch(voltage) {
1739 case SEC_VOLTAGE_OFF:
1740 data[0] = 0x00;
1741 break;
1742 case SEC_VOLTAGE_13:
1743 data[0] = 0x44;
1744 break;
1745 case SEC_VOLTAGE_18:
1746 data[0] = 0x4c;
1747 break;
1748 default:
1749 return -EINVAL;
1750 };
1751
1752 ret = i2c_transfer(&av7110->i2c_adap, &msg, 1);
1753 return (ret != 1) ? -EIO : 0;
1754}
1755
Linus Torvalds1da177e2005-04-16 15:20:36 -07001756
1757static int alps_tdbe2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
1758{
1759 struct av7110* av7110 = fe->dvb->priv;
1760 u32 div;
1761 u8 data[4];
1762 struct i2c_msg msg = { .addr = 0x62, .flags = 0, .buf = data, .len = sizeof(data) };
1763
1764 div = (params->frequency + 35937500 + 31250) / 62500;
1765
1766 data[0] = (div >> 8) & 0x7f;
1767 data[1] = div & 0xff;
1768 data[2] = 0x85 | ((div >> 10) & 0x60);
1769 data[3] = (params->frequency < 174000000 ? 0x88 : params->frequency < 470000000 ? 0x84 : 0x81);
1770
1771 if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1)
1772 return -EIO;
1773 return 0;
1774}
1775
1776static struct ves1820_config alps_tdbe2_config = {
1777 .demod_address = 0x09,
1778 .xin = 57840000UL,
1779 .invert = 1,
1780 .selagc = VES1820_SELAGC_SIGNAMPERR,
1781 .pll_set = alps_tdbe2_pll_set,
1782};
1783
1784
1785
1786
1787static int grundig_29504_451_pll_set(struct dvb_frontend* fe,
1788 struct dvb_frontend_parameters* params)
1789{
1790 struct av7110* av7110 = fe->dvb->priv;
1791 u32 div;
1792 u8 data[4];
1793 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
1794
1795 div = params->frequency / 125;
1796 data[0] = (div >> 8) & 0x7f;
1797 data[1] = div & 0xff;
1798 data[2] = 0x8e;
1799 data[3] = 0x00;
1800
1801 if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1)
1802 return -EIO;
1803 return 0;
1804}
1805
1806static struct tda8083_config grundig_29504_451_config = {
1807 .demod_address = 0x68,
1808 .pll_set = grundig_29504_451_pll_set,
1809};
1810
1811
1812
1813static int philips_cd1516_pll_set(struct dvb_frontend* fe,
1814 struct dvb_frontend_parameters* params)
1815{
1816 struct av7110* av7110 = fe->dvb->priv;
1817 u32 div;
1818 u32 f = params->frequency;
1819 u8 data[4];
1820 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
1821
1822 div = (f + 36125000 + 31250) / 62500;
1823
1824 data[0] = (div >> 8) & 0x7f;
1825 data[1] = div & 0xff;
1826 data[2] = 0x8e;
1827 data[3] = (f < 174000000 ? 0xa1 : f < 470000000 ? 0x92 : 0x34);
1828
1829 if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1)
1830 return -EIO;
1831 return 0;
1832}
1833
1834static struct ves1820_config philips_cd1516_config = {
1835 .demod_address = 0x09,
1836 .xin = 57840000UL,
1837 .invert = 1,
1838 .selagc = VES1820_SELAGC_SIGNAMPERR,
1839 .pll_set = philips_cd1516_pll_set,
1840};
1841
1842
1843
1844static int alps_tdlb7_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
1845{
1846 struct av7110* av7110 = fe->dvb->priv;
1847 u32 div, pwr;
1848 u8 data[4];
1849 struct i2c_msg msg = { .addr = 0x60, .flags = 0, .buf = data, .len = sizeof(data) };
1850
1851 div = (params->frequency + 36200000) / 166666;
1852
1853 if (params->frequency <= 782000000)
1854 pwr = 1;
1855 else
1856 pwr = 2;
1857
1858 data[0] = (div >> 8) & 0x7f;
1859 data[1] = div & 0xff;
1860 data[2] = 0x85;
1861 data[3] = pwr << 6;
1862
1863 if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1)
1864 return -EIO;
1865 return 0;
1866}
1867
1868static int alps_tdlb7_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name)
1869{
1870 struct av7110* av7110 = (struct av7110*) fe->dvb->priv;
1871
1872 return request_firmware(fw, name, &av7110->dev->pci->dev);
1873}
1874
1875static struct sp8870_config alps_tdlb7_config = {
1876
1877 .demod_address = 0x71,
1878 .pll_set = alps_tdlb7_pll_set,
1879 .request_firmware = alps_tdlb7_request_firmware,
1880};
1881
1882
Andrew de Quinceydc27a162005-09-09 13:03:07 -07001883static u8 nexusca_stv0297_inittab[] = {
1884 0x80, 0x01,
1885 0x80, 0x00,
1886 0x81, 0x01,
1887 0x81, 0x00,
1888 0x00, 0x09,
1889 0x01, 0x69,
1890 0x03, 0x00,
1891 0x04, 0x00,
1892 0x07, 0x00,
1893 0x08, 0x00,
1894 0x20, 0x00,
1895 0x21, 0x40,
1896 0x22, 0x00,
1897 0x23, 0x00,
1898 0x24, 0x40,
1899 0x25, 0x88,
1900 0x30, 0xff,
1901 0x31, 0x00,
1902 0x32, 0xff,
1903 0x33, 0x00,
1904 0x34, 0x50,
1905 0x35, 0x7f,
1906 0x36, 0x00,
1907 0x37, 0x20,
1908 0x38, 0x00,
1909 0x40, 0x1c,
1910 0x41, 0xff,
1911 0x42, 0x29,
1912 0x43, 0x00,
1913 0x44, 0xff,
1914 0x45, 0x00,
1915 0x46, 0x00,
1916 0x49, 0x04,
1917 0x4a, 0x00,
1918 0x4b, 0x7b,
1919 0x52, 0x30,
1920 0x55, 0xae,
1921 0x56, 0x47,
1922 0x57, 0xe1,
1923 0x58, 0x3a,
1924 0x5a, 0x1e,
1925 0x5b, 0x34,
1926 0x60, 0x00,
1927 0x63, 0x00,
1928 0x64, 0x00,
1929 0x65, 0x00,
1930 0x66, 0x00,
1931 0x67, 0x00,
1932 0x68, 0x00,
1933 0x69, 0x00,
1934 0x6a, 0x02,
1935 0x6b, 0x00,
1936 0x70, 0xff,
1937 0x71, 0x00,
1938 0x72, 0x00,
1939 0x73, 0x00,
1940 0x74, 0x0c,
1941 0x80, 0x00,
1942 0x81, 0x00,
1943 0x82, 0x00,
1944 0x83, 0x00,
1945 0x84, 0x04,
1946 0x85, 0x80,
1947 0x86, 0x24,
1948 0x87, 0x78,
1949 0x88, 0x10,
1950 0x89, 0x00,
1951 0x90, 0x01,
1952 0x91, 0x01,
1953 0xa0, 0x04,
1954 0xa1, 0x00,
1955 0xa2, 0x00,
1956 0xb0, 0x91,
1957 0xb1, 0x0b,
1958 0xc0, 0x53,
1959 0xc1, 0x70,
1960 0xc2, 0x12,
1961 0xd0, 0x00,
1962 0xd1, 0x00,
1963 0xd2, 0x00,
1964 0xd3, 0x00,
1965 0xd4, 0x00,
1966 0xd5, 0x00,
1967 0xde, 0x00,
1968 0xdf, 0x00,
1969 0x61, 0x49,
1970 0x62, 0x0b,
1971 0x53, 0x08,
1972 0x59, 0x08,
1973 0xff, 0xff,
1974};
Linus Torvalds1da177e2005-04-16 15:20:36 -07001975
1976static int nexusca_stv0297_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
1977{
1978 struct av7110* av7110 = fe->dvb->priv;
1979 u32 div;
1980 u8 data[4];
1981 struct i2c_msg msg = { .addr = 0x63, .flags = 0, .buf = data, .len = sizeof(data) };
1982 struct i2c_msg readmsg = { .addr = 0x63, .flags = I2C_M_RD, .buf = data, .len = 1 };
1983 int i;
1984
1985 div = (params->frequency + 36150000 + 31250) / 62500;
1986
1987 data[0] = (div >> 8) & 0x7f;
1988 data[1] = div & 0xff;
1989 data[2] = 0xce;
1990
1991 if (params->frequency < 45000000)
1992 return -EINVAL;
1993 else if (params->frequency < 137000000)
1994 data[3] = 0x01;
1995 else if (params->frequency < 403000000)
1996 data[3] = 0x02;
1997 else if (params->frequency < 860000000)
1998 data[3] = 0x04;
1999 else
2000 return -EINVAL;
2001
2002 stv0297_enable_plli2c(fe);
2003 if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1) {
2004 printk("nexusca: pll transfer failed!\n");
2005 return -EIO;
2006 }
2007
2008 // wait for PLL lock
2009 for(i = 0; i < 20; i++) {
2010
2011 stv0297_enable_plli2c(fe);
2012 if (i2c_transfer(&av7110->i2c_adap, &readmsg, 1) == 1)
2013 if (data[0] & 0x40) break;
2014 msleep(10);
2015 }
2016
2017 return 0;
2018}
2019
2020static struct stv0297_config nexusca_stv0297_config = {
2021
2022 .demod_address = 0x1C,
Andrew de Quinceydc27a162005-09-09 13:03:07 -07002023 .inittab = nexusca_stv0297_inittab,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002024 .invert = 1,
2025 .pll_set = nexusca_stv0297_pll_set,
2026};
2027
2028
2029
2030static int grundig_29504_401_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
2031{
2032 struct av7110* av7110 = (struct av7110*) fe->dvb->priv;
2033 u32 div;
2034 u8 cfg, cpump, band_select;
2035 u8 data[4];
2036 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
2037
2038 div = (36125000 + params->frequency) / 166666;
2039
2040 cfg = 0x88;
2041
2042 if (params->frequency < 175000000) cpump = 2;
2043 else if (params->frequency < 390000000) cpump = 1;
2044 else if (params->frequency < 470000000) cpump = 2;
2045 else if (params->frequency < 750000000) cpump = 1;
2046 else cpump = 3;
2047
2048 if (params->frequency < 175000000) band_select = 0x0e;
2049 else if (params->frequency < 470000000) band_select = 0x05;
2050 else band_select = 0x03;
2051
2052 data[0] = (div >> 8) & 0x7f;
2053 data[1] = div & 0xff;
2054 data[2] = ((div >> 10) & 0x60) | cfg;
2055 data[3] = (cpump << 6) | band_select;
2056
2057 if (i2c_transfer (&av7110->i2c_adap, &msg, 1) != 1) return -EIO;
2058 return 0;
2059}
2060
2061static struct l64781_config grundig_29504_401_config = {
2062 .demod_address = 0x55,
2063 .pll_set = grundig_29504_401_pll_set,
2064};
2065
2066
2067
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002068static int av7110_fe_lock_fix(struct av7110* av7110, fe_status_t status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002069{
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002070 int ret = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002071 int synced = (status & FE_HAS_LOCK) ? 1 : 0;
2072
2073 av7110->fe_status = status;
2074
2075 if (av7110->fe_synced == synced)
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002076 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002077
Linus Torvalds1da177e2005-04-16 15:20:36 -07002078 if (av7110->playing)
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002079 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002080
2081 if (down_interruptible(&av7110->pid_mutex))
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002082 return -ERESTARTSYS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002083
Oliver Endriss34612152005-07-07 17:58:02 -07002084 if (synced) {
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002085 ret = SetPIDs(av7110, av7110->pids[DMX_PES_VIDEO],
Linus Torvalds1da177e2005-04-16 15:20:36 -07002086 av7110->pids[DMX_PES_AUDIO],
2087 av7110->pids[DMX_PES_TELETEXT], 0,
2088 av7110->pids[DMX_PES_PCR]);
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002089 if (!ret)
2090 ret = av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, Scan, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002091 } else {
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002092 ret = SetPIDs(av7110, 0, 0, 0, 0, 0);
2093 if (!ret) {
2094 ret = av7110_fw_cmd(av7110, COMTYPE_PID_FILTER, FlushTSQueue, 0);
2095 if (!ret)
2096 ret = av7110_wait_msgstate(av7110, GPMQBusy);
2097 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002098 }
2099
Oliver Endriss34612152005-07-07 17:58:02 -07002100 if (!ret)
2101 av7110->fe_synced = synced;
2102
Linus Torvalds1da177e2005-04-16 15:20:36 -07002103 up(&av7110->pid_mutex);
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002104 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002105}
2106
2107static int av7110_fe_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
2108{
2109 struct av7110* av7110 = fe->dvb->priv;
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002110
2111 int ret = av7110_fe_lock_fix(av7110, 0);
2112 if (!ret)
2113 ret = av7110->fe_set_frontend(fe, params);
2114 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002115}
2116
2117static int av7110_fe_init(struct dvb_frontend* fe)
2118{
2119 struct av7110* av7110 = fe->dvb->priv;
2120
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002121 int ret = av7110_fe_lock_fix(av7110, 0);
2122 if (!ret)
2123 ret = av7110->fe_init(fe);
2124 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002125}
2126
2127static int av7110_fe_read_status(struct dvb_frontend* fe, fe_status_t* status)
2128{
2129 struct av7110* av7110 = fe->dvb->priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002130
2131 /* call the real implementation */
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002132 int ret = av7110->fe_read_status(fe, status);
2133 if (!ret)
2134 if (((*status ^ av7110->fe_status) & FE_HAS_LOCK) && (*status & FE_HAS_LOCK))
2135 ret = av7110_fe_lock_fix(av7110, *status);
2136 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002137}
2138
2139static int av7110_fe_diseqc_reset_overload(struct dvb_frontend* fe)
2140{
2141 struct av7110* av7110 = fe->dvb->priv;
2142
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002143 int ret = av7110_fe_lock_fix(av7110, 0);
2144 if (!ret)
2145 ret = av7110->fe_diseqc_reset_overload(fe);
2146 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002147}
2148
2149static int av7110_fe_diseqc_send_master_cmd(struct dvb_frontend* fe,
2150 struct dvb_diseqc_master_cmd* cmd)
2151{
2152 struct av7110* av7110 = fe->dvb->priv;
2153
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002154 int ret = av7110_fe_lock_fix(av7110, 0);
2155 if (!ret)
2156 ret = av7110->fe_diseqc_send_master_cmd(fe, cmd);
2157 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002158}
2159
2160static int av7110_fe_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd)
2161{
2162 struct av7110* av7110 = fe->dvb->priv;
2163
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002164 int ret = av7110_fe_lock_fix(av7110, 0);
2165 if (!ret)
2166 ret = av7110->fe_diseqc_send_burst(fe, minicmd);
2167 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002168}
2169
2170static int av7110_fe_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
2171{
2172 struct av7110* av7110 = fe->dvb->priv;
2173
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002174 int ret = av7110_fe_lock_fix(av7110, 0);
2175 if (!ret)
2176 ret = av7110->fe_set_tone(fe, tone);
2177 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002178}
2179
2180static int av7110_fe_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
2181{
2182 struct av7110* av7110 = fe->dvb->priv;
2183
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002184 int ret = av7110_fe_lock_fix(av7110, 0);
2185 if (!ret)
2186 ret = av7110->fe_set_voltage(fe, voltage);
2187 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002188}
2189
2190static int av7110_fe_dishnetwork_send_legacy_command(struct dvb_frontend* fe, unsigned int cmd)
2191{
2192 struct av7110* av7110 = fe->dvb->priv;
2193
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002194 int ret = av7110_fe_lock_fix(av7110, 0);
2195 if (!ret)
2196 ret = av7110->fe_dishnetwork_send_legacy_command(fe, cmd);
2197 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002198}
2199
2200static u8 read_pwm(struct av7110* av7110)
2201{
2202 u8 b = 0xff;
2203 u8 pwm;
2204 struct i2c_msg msg[] = { { .addr = 0x50,.flags = 0,.buf = &b,.len = 1 },
2205 { .addr = 0x50,.flags = I2C_M_RD,.buf = &pwm,.len = 1} };
2206
2207 if ((i2c_transfer(&av7110->i2c_adap, msg, 2) != 2) || (pwm == 0xff))
2208 pwm = 0x48;
2209
2210 return pwm;
2211}
2212
2213static int frontend_init(struct av7110 *av7110)
2214{
2215 int ret;
2216
2217 if (av7110->dev->pci->subsystem_vendor == 0x110a) {
2218 switch(av7110->dev->pci->subsystem_device) {
2219 case 0x0000: // Fujitsu/Siemens DVB-Cable (ves1820/Philips CD1516(??))
2220 av7110->fe = ves1820_attach(&philips_cd1516_config,
2221 &av7110->i2c_adap, read_pwm(av7110));
2222 break;
2223 }
2224
2225 } else if (av7110->dev->pci->subsystem_vendor == 0x13c2) {
2226 switch(av7110->dev->pci->subsystem_device) {
2227 case 0x0000: // Hauppauge/TT WinTV DVB-S rev1.X
2228 case 0x0003: // Hauppauge/TT WinTV Nexus-S Rev 2.X
2229 case 0x1002: // Hauppauge/TT WinTV DVB-S rev1.3SE
2230
2231 // try the ALPS BSRV2 first of all
2232 av7110->fe = ves1x93_attach(&alps_bsrv2_config, &av7110->i2c_adap);
2233 if (av7110->fe) {
2234 av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd;
2235 av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst;
2236 av7110->fe->ops->set_tone = av7110_set_tone;
2237 break;
2238 }
2239
2240 // try the ALPS BSRU6 now
2241 av7110->fe = stv0299_attach(&alps_bsru6_config, &av7110->i2c_adap);
2242 if (av7110->fe) {
2243 av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd;
2244 av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst;
2245 av7110->fe->ops->set_tone = av7110_set_tone;
2246 break;
2247 }
2248
2249 // Try the grundig 29504-451
2250 av7110->fe = tda8083_attach(&grundig_29504_451_config, &av7110->i2c_adap);
2251 if (av7110->fe) {
2252 av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd;
2253 av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst;
2254 av7110->fe->ops->set_tone = av7110_set_tone;
2255 break;
2256 }
2257
2258 /* Try DVB-C cards */
2259 switch(av7110->dev->pci->subsystem_device) {
2260 case 0x0000:
2261 /* Siemens DVB-C (full-length card) VES1820/Philips CD1516 */
2262 av7110->fe = ves1820_attach(&philips_cd1516_config, &av7110->i2c_adap,
2263 read_pwm(av7110));
2264 break;
2265 case 0x0003:
2266 /* Haupauge DVB-C 2.1 VES1820/ALPS TDBE2 */
2267 av7110->fe = ves1820_attach(&alps_tdbe2_config, &av7110->i2c_adap,
2268 read_pwm(av7110));
2269 break;
2270 }
2271 break;
2272
2273 case 0x0001: // Hauppauge/TT Nexus-T premium rev1.X
2274
2275 // ALPS TDLB7
2276 av7110->fe = sp8870_attach(&alps_tdlb7_config, &av7110->i2c_adap);
2277 break;
2278
2279 case 0x0002: // Hauppauge/TT DVB-C premium rev2.X
2280
2281 av7110->fe = ves1820_attach(&alps_tdbe2_config, &av7110->i2c_adap, read_pwm(av7110));
2282 break;
2283
2284 case 0x0006: /* Fujitsu-Siemens DVB-S rev 1.6 */
2285 /* Grundig 29504-451 */
2286 av7110->fe = tda8083_attach(&grundig_29504_451_config, &av7110->i2c_adap);
2287 if (av7110->fe) {
2288 av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd;
2289 av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst;
2290 av7110->fe->ops->set_tone = av7110_set_tone;
2291 }
2292 break;
2293
2294 case 0x0008: // Hauppauge/TT DVB-T
2295
2296 av7110->fe = l64781_attach(&grundig_29504_401_config, &av7110->i2c_adap);
2297 break;
2298
2299 case 0x000A: // Hauppauge/TT Nexus-CA rev1.X
2300
Andrew de Quinceydc27a162005-09-09 13:03:07 -07002301 av7110->fe = stv0297_attach(&nexusca_stv0297_config, &av7110->i2c_adap);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002302 if (av7110->fe) {
2303 /* set TDA9819 into DVB mode */
2304 saa7146_setgpio(av7110->dev, 1, SAA7146_GPIO_OUTLO); // TDA9198 pin9(STD)
2305 saa7146_setgpio(av7110->dev, 3, SAA7146_GPIO_OUTLO); // TDA9198 pin30(VIF)
2306
2307 /* tuner on this needs a slower i2c bus speed */
2308 av7110->dev->i2c_bitrate = SAA7146_I2C_BUS_BIT_RATE_240;
2309 break;
2310 }
Johannes Stezenbach3dfaebd2005-05-16 21:54:19 -07002311 break;
2312
2313 case 0x000E: /* Hauppauge/TT Nexus-S rev 2.3 */
2314 /* ALPS BSBE1 */
2315 av7110->fe = stv0299_attach(&alps_bsbe1_config, &av7110->i2c_adap);
2316 if (av7110->fe)
2317 av7110->fe->ops->set_voltage = lnbp21_set_voltage;
2318 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002319 }
2320 }
2321
2322 if (!av7110->fe) {
2323 /* FIXME: propagate the failure code from the lower layers */
2324 ret = -ENOMEM;
2325 printk("dvb-ttpci: A frontend driver was not found for device %04x/%04x subsystem %04x/%04x\n",
2326 av7110->dev->pci->vendor,
2327 av7110->dev->pci->device,
2328 av7110->dev->pci->subsystem_vendor,
2329 av7110->dev->pci->subsystem_device);
2330 } else {
2331 FE_FUNC_OVERRIDE(av7110->fe->ops->init, av7110->fe_init, av7110_fe_init);
2332 FE_FUNC_OVERRIDE(av7110->fe->ops->read_status, av7110->fe_read_status, av7110_fe_read_status);
2333 FE_FUNC_OVERRIDE(av7110->fe->ops->diseqc_reset_overload, av7110->fe_diseqc_reset_overload, av7110_fe_diseqc_reset_overload);
2334 FE_FUNC_OVERRIDE(av7110->fe->ops->diseqc_send_master_cmd, av7110->fe_diseqc_send_master_cmd, av7110_fe_diseqc_send_master_cmd);
2335 FE_FUNC_OVERRIDE(av7110->fe->ops->diseqc_send_burst, av7110->fe_diseqc_send_burst, av7110_fe_diseqc_send_burst);
2336 FE_FUNC_OVERRIDE(av7110->fe->ops->set_tone, av7110->fe_set_tone, av7110_fe_set_tone);
2337 FE_FUNC_OVERRIDE(av7110->fe->ops->set_voltage, av7110->fe_set_voltage, av7110_fe_set_voltage;)
2338 FE_FUNC_OVERRIDE(av7110->fe->ops->dishnetwork_send_legacy_command, av7110->fe_dishnetwork_send_legacy_command, av7110_fe_dishnetwork_send_legacy_command);
2339 FE_FUNC_OVERRIDE(av7110->fe->ops->set_frontend, av7110->fe_set_frontend, av7110_fe_set_frontend);
2340
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07002341 ret = dvb_register_frontend(&av7110->dvb_adapter, av7110->fe);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002342 if (ret < 0) {
2343 printk("av7110: Frontend registration failed!\n");
2344 if (av7110->fe->ops->release)
2345 av7110->fe->ops->release(av7110->fe);
2346 av7110->fe = NULL;
2347 }
2348 }
2349 return ret;
2350}
2351
2352/* Budgetpatch note:
2353 * Original hardware design by Roberto Deza:
2354 * There is a DVB_Wiki at
2355 * http://212.227.36.83/linuxtv/wiki/index.php/Main_Page
2356 * where is described this 'DVB TT Budget Patch', on Card Modding:
2357 * http://212.227.36.83/linuxtv/wiki/index.php/DVB_TT_Budget_Patch
2358 * On the short description there is also a link to a external file,
2359 * with more details:
2360 * http://perso.wanadoo.es/jesussolano/Ttf_tsc1.zip
2361 *
2362 * New software triggering design by Emard that works on
2363 * original Roberto Deza's hardware:
2364 *
2365 * rps1 code for budgetpatch will copy internal HS event to GPIO3 pin.
2366 * GPIO3 is in budget-patch hardware connectd to port B VSYNC
2367 * HS is an internal event of 7146, accessible with RPS
2368 * and temporarily raised high every n lines
2369 * (n in defined in the RPS_THRESH1 counter threshold)
2370 * I think HS is raised high on the beginning of the n-th line
2371 * and remains high until this n-th line that triggered
2372 * it is completely received. When the receiption of n-th line
2373 * ends, HS is lowered.
2374 *
2375 * To transmit data over DMA, 7146 needs changing state at
2376 * port B VSYNC pin. Any changing of port B VSYNC will
2377 * cause some DMA data transfer, with more or less packets loss.
2378 * It depends on the phase and frequency of VSYNC and
2379 * the way of 7146 is instructed to trigger on port B (defined
2380 * in DD1_INIT register, 3rd nibble from the right valid
2381 * numbers are 0-7, see datasheet)
2382 *
2383 * The correct triggering can minimize packet loss,
2384 * dvbtraffic should give this stable bandwidths:
2385 * 22k transponder = 33814 kbit/s
2386 * 27.5k transponder = 38045 kbit/s
2387 * by experiment it is found that the best results
2388 * (stable bandwidths and almost no packet loss)
2389 * are obtained using DD1_INIT triggering number 2
2390 * (Va at rising edge of VS Fa = HS x VS-failing forced toggle)
2391 * and a VSYNC phase that occurs in the middle of DMA transfer
2392 * (about byte 188*512=96256 in the DMA window).
2393 *
2394 * Phase of HS is still not clear to me how to control,
2395 * It just happens to be so. It can be seen if one enables
2396 * RPS_IRQ and print Event Counter 1 in vpeirq(). Every
2397 * time RPS_INTERRUPT is called, the Event Counter 1 will
2398 * increment. That's how the 7146 is programmed to do event
2399 * counting in this budget-patch.c
2400 * I *think* HPS setting has something to do with the phase
2401 * of HS but I cant be 100% sure in that.
2402 *
2403 * hardware debug note: a working budget card (including budget patch)
2404 * with vpeirq() interrupt setup in mode "0x90" (every 64K) will
2405 * generate 3 interrupts per 25-Hz DMA frame of 2*188*512 bytes
2406 * and that means 3*25=75 Hz of interrupt freqency, as seen by
2407 * watch cat /proc/interrupts
2408 *
2409 * If this frequency is 3x lower (and data received in the DMA
2410 * buffer don't start with 0x47, but in the middle of packets,
2411 * whose lengths appear to be like 188 292 188 104 etc.
2412 * this means VSYNC line is not connected in the hardware.
2413 * (check soldering pcb and pins)
2414 * The same behaviour of missing VSYNC can be duplicated on budget
2415 * cards, by seting DD1_INIT trigger mode 7 in 3rd nibble.
2416 */
2417static int av7110_attach(struct saa7146_dev* dev, struct saa7146_pci_extension_data *pci_ext)
2418{
2419 const int length = TS_WIDTH * TS_HEIGHT;
2420 struct pci_dev *pdev = dev->pci;
2421 struct av7110 *av7110;
2422 int ret, count = 0;
2423
2424 dprintk(4, "dev: %p\n", dev);
2425
2426 /* Set RPS_IRQ to 1 to track rps1 activity.
2427 * Enabling this won't send any interrupt to PC CPU.
2428 */
2429#define RPS_IRQ 0
2430
2431 if (budgetpatch == 1) {
2432 budgetpatch = 0;
2433 /* autodetect the presence of budget patch
2434 * this only works if saa7146 has been recently
2435 * reset with with MASK_31 to MC1
2436 *
2437 * will wait for VBI_B event (vertical blank at port B)
2438 * and will reset GPIO3 after VBI_B is detected.
2439 * (GPIO3 should be raised high by CPU to
2440 * test if GPIO3 will generate vertical blank signal
2441 * in budget patch GPIO3 is connected to VSYNC_B
2442 */
2443
2444 /* RESET SAA7146 */
2445 saa7146_write(dev, MC1, MASK_31);
2446 /* autodetection success seems to be time-dependend after reset */
2447
2448 /* Fix VSYNC level */
2449 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
2450 /* set vsync_b triggering */
2451 saa7146_write(dev, DD1_STREAM_B, 0);
2452 /* port B VSYNC at rising edge */
2453 saa7146_write(dev, DD1_INIT, 0x00000200);
2454 saa7146_write(dev, BRS_CTRL, 0x00000000); // VBI
2455 saa7146_write(dev, MC2,
2456 1 * (MASK_08 | MASK_24) | // BRS control
2457 0 * (MASK_09 | MASK_25) | // a
2458 1 * (MASK_10 | MASK_26) | // b
2459 0 * (MASK_06 | MASK_22) | // HPS_CTRL1
2460 0 * (MASK_05 | MASK_21) | // HPS_CTRL2
2461 0 * (MASK_01 | MASK_15) // DEBI
2462 );
2463
2464 /* start writing RPS1 code from beginning */
2465 count = 0;
2466 /* Disable RPS1 */
2467 saa7146_write(dev, MC1, MASK_29);
2468 /* RPS1 timeout disable */
2469 saa7146_write(dev, RPS_TOV1, 0);
2470 WRITE_RPS1(cpu_to_le32(CMD_PAUSE | EVT_VBI_B));
2471 WRITE_RPS1(cpu_to_le32(CMD_WR_REG_MASK | (GPIO_CTRL>>2)));
2472 WRITE_RPS1(cpu_to_le32(GPIO3_MSK));
2473 WRITE_RPS1(cpu_to_le32(SAA7146_GPIO_OUTLO<<24));
2474#if RPS_IRQ
2475 /* issue RPS1 interrupt to increment counter */
2476 WRITE_RPS1(cpu_to_le32(CMD_INTERRUPT));
2477#endif
2478 WRITE_RPS1(cpu_to_le32(CMD_STOP));
2479 /* Jump to begin of RPS program as safety measure (p37) */
2480 WRITE_RPS1(cpu_to_le32(CMD_JUMP));
2481 WRITE_RPS1(cpu_to_le32(dev->d_rps1.dma_handle));
2482
2483#if RPS_IRQ
2484 /* set event counter 1 source as RPS1 interrupt (0x03) (rE4 p53)
2485 * use 0x03 to track RPS1 interrupts - increase by 1 every gpio3 is toggled
2486 * use 0x15 to track VPE interrupts - increase by 1 every vpeirq() is called
2487 */
2488 saa7146_write(dev, EC1SSR, (0x03<<2) | 3 );
2489 /* set event counter 1 treshold to maximum allowed value (rEC p55) */
2490 saa7146_write(dev, ECT1R, 0x3fff );
2491#endif
2492 /* Set RPS1 Address register to point to RPS code (r108 p42) */
2493 saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle);
2494 /* Enable RPS1, (rFC p33) */
2495 saa7146_write(dev, MC1, (MASK_13 | MASK_29 ));
2496
2497 mdelay(10);
2498 /* now send VSYNC_B to rps1 by rising GPIO3 */
2499 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI);
2500 mdelay(10);
2501 /* if rps1 responded by lowering the GPIO3,
2502 * then we have budgetpatch hardware
2503 */
2504 if ((saa7146_read(dev, GPIO_CTRL) & 0x10000000) == 0) {
2505 budgetpatch = 1;
2506 printk("dvb-ttpci: BUDGET-PATCH DETECTED.\n");
2507 }
2508 /* Disable RPS1 */
2509 saa7146_write(dev, MC1, ( MASK_29 ));
2510#if RPS_IRQ
2511 printk("dvb-ttpci: Event Counter 1 0x%04x\n", saa7146_read(dev, EC1R) & 0x3fff );
2512#endif
2513 }
2514
2515 /* prepare the av7110 device struct */
2516 av7110 = kmalloc(sizeof(struct av7110), GFP_KERNEL);
2517 if (!av7110) {
2518 dprintk(1, "out of memory\n");
2519 return -ENOMEM;
2520 }
2521
2522 memset(av7110, 0, sizeof(struct av7110));
2523
2524 av7110->card_name = (char*) pci_ext->ext_priv;
2525 av7110->dev = dev;
2526 dev->ext_priv = av7110;
2527
2528 ret = get_firmware(av7110);
2529 if (ret < 0)
2530 goto err_kfree_0;
2531
2532 ret = dvb_register_adapter(&av7110->dvb_adapter, av7110->card_name,
2533 THIS_MODULE);
2534 if (ret < 0)
2535 goto err_put_firmware_1;
2536
2537 /* the Siemens DVB needs this if you want to have the i2c chips
2538 get recognized before the main driver is fully loaded */
2539 saa7146_write(dev, GPIO_CTRL, 0x500000);
2540
2541#ifdef I2C_ADAP_CLASS_TV_DIGITAL
2542 av7110->i2c_adap.class = I2C_ADAP_CLASS_TV_DIGITAL;
2543#else
2544 av7110->i2c_adap.class = I2C_CLASS_TV_DIGITAL;
2545#endif
2546 strlcpy(av7110->i2c_adap.name, pci_ext->ext_priv, sizeof(av7110->i2c_adap.name));
2547
2548 saa7146_i2c_adapter_prepare(dev, &av7110->i2c_adap, SAA7146_I2C_BUS_BIT_RATE_120); /* 275 kHz */
2549
2550 ret = i2c_add_adapter(&av7110->i2c_adap);
2551 if (ret < 0)
2552 goto err_dvb_unregister_adapter_2;
2553
2554 ttpci_eeprom_parse_mac(&av7110->i2c_adap,
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07002555 av7110->dvb_adapter.proposed_mac);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002556 ret = -ENOMEM;
2557
2558 if (budgetpatch) {
2559 spin_lock_init(&av7110->feedlock1);
2560 av7110->grabbing = saa7146_vmalloc_build_pgtable(pdev, length,
2561 &av7110->pt);
2562 if (!av7110->grabbing)
2563 goto err_i2c_del_3;
2564
2565 saa7146_write(dev, PCI_BT_V1, 0x1c1f101f);
2566 saa7146_write(dev, BCS_CTRL, 0x80400040);
2567 /* set dd1 stream a & b */
2568 saa7146_write(dev, DD1_STREAM_B, 0x00000000);
2569 saa7146_write(dev, DD1_INIT, 0x03000200);
2570 saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
2571 saa7146_write(dev, BRS_CTRL, 0x60000000);
2572 saa7146_write(dev, BASE_ODD3, 0);
2573 saa7146_write(dev, BASE_EVEN3, 0);
2574 saa7146_write(dev, PROT_ADDR3, TS_WIDTH * TS_HEIGHT);
2575 saa7146_write(dev, BASE_PAGE3, av7110->pt.dma | ME1 | 0x90);
2576
2577 saa7146_write(dev, PITCH3, TS_WIDTH);
2578 saa7146_write(dev, NUM_LINE_BYTE3, (TS_HEIGHT << 16) | TS_WIDTH);
2579
2580 /* upload all */
2581 saa7146_write(dev, MC2, 0x077c077c);
2582 saa7146_write(dev, GPIO_CTRL, 0x000000);
2583#if RPS_IRQ
2584 /* set event counter 1 source as RPS1 interrupt (0x03) (rE4 p53)
2585 * use 0x03 to track RPS1 interrupts - increase by 1 every gpio3 is toggled
2586 * use 0x15 to track VPE interrupts - increase by 1 every vpeirq() is called
2587 */
2588 saa7146_write(dev, EC1SSR, (0x03<<2) | 3 );
2589 /* set event counter 1 treshold to maximum allowed value (rEC p55) */
2590 saa7146_write(dev, ECT1R, 0x3fff );
2591#endif
2592 /* Setup BUDGETPATCH MAIN RPS1 "program" (p35) */
2593 count = 0;
2594
2595 /* Wait Source Line Counter Threshold (p36) */
2596 WRITE_RPS1(cpu_to_le32(CMD_PAUSE | EVT_HS));
2597 /* Set GPIO3=1 (p42) */
2598 WRITE_RPS1(cpu_to_le32(CMD_WR_REG_MASK | (GPIO_CTRL>>2)));
2599 WRITE_RPS1(cpu_to_le32(GPIO3_MSK));
2600 WRITE_RPS1(cpu_to_le32(SAA7146_GPIO_OUTHI<<24));
2601#if RPS_IRQ
2602 /* issue RPS1 interrupt */
2603 WRITE_RPS1(cpu_to_le32(CMD_INTERRUPT));
2604#endif
2605 /* Wait reset Source Line Counter Threshold (p36) */
2606 WRITE_RPS1(cpu_to_le32(CMD_PAUSE | RPS_INV | EVT_HS));
2607 /* Set GPIO3=0 (p42) */
2608 WRITE_RPS1(cpu_to_le32(CMD_WR_REG_MASK | (GPIO_CTRL>>2)));
2609 WRITE_RPS1(cpu_to_le32(GPIO3_MSK));
2610 WRITE_RPS1(cpu_to_le32(SAA7146_GPIO_OUTLO<<24));
2611#if RPS_IRQ
2612 /* issue RPS1 interrupt */
2613 WRITE_RPS1(cpu_to_le32(CMD_INTERRUPT));
2614#endif
2615 /* Jump to begin of RPS program (p37) */
2616 WRITE_RPS1(cpu_to_le32(CMD_JUMP));
2617 WRITE_RPS1(cpu_to_le32(dev->d_rps1.dma_handle));
2618
2619 /* Fix VSYNC level */
2620 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
2621 /* Set RPS1 Address register to point to RPS code (r108 p42) */
2622 saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle);
2623 /* Set Source Line Counter Threshold, using BRS (rCC p43)
2624 * It generates HS event every TS_HEIGHT lines
2625 * this is related to TS_WIDTH set in register
2626 * NUM_LINE_BYTE3. If NUM_LINE_BYTE low 16 bits
2627 * are set to TS_WIDTH bytes (TS_WIDTH=2*188),
2628 * then RPS_THRESH1 should be set to trigger
2629 * every TS_HEIGHT (512) lines.
2630 */
2631 saa7146_write(dev, RPS_THRESH1, (TS_HEIGHT*1) | MASK_12 );
2632
2633 /* Enable RPS1 (rFC p33) */
2634 saa7146_write(dev, MC1, (MASK_13 | MASK_29));
2635
2636 /* end of budgetpatch register initialization */
2637 tasklet_init (&av7110->vpe_tasklet, vpeirq, (unsigned long) av7110);
2638 } else {
2639 saa7146_write(dev, PCI_BT_V1, 0x1c00101f);
2640 saa7146_write(dev, BCS_CTRL, 0x80400040);
2641
2642 /* set dd1 stream a & b */
2643 saa7146_write(dev, DD1_STREAM_B, 0x00000000);
2644 saa7146_write(dev, DD1_INIT, 0x03000000);
2645 saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
2646
2647 /* upload all */
2648 saa7146_write(dev, MC2, 0x077c077c);
2649 saa7146_write(dev, GPIO_CTRL, 0x000000);
2650 }
2651
2652 tasklet_init (&av7110->debi_tasklet, debiirq, (unsigned long) av7110);
2653 tasklet_init (&av7110->gpio_tasklet, gpioirq, (unsigned long) av7110);
2654
2655 sema_init(&av7110->pid_mutex, 1);
2656
2657 /* locks for data transfers from/to AV7110 */
2658 spin_lock_init(&av7110->debilock);
2659 sema_init(&av7110->dcomlock, 1);
2660 av7110->debitype = -1;
2661
2662 /* default OSD window */
2663 av7110->osdwin = 1;
2664 sema_init(&av7110->osd_sema, 1);
2665
2666 /* ARM "watchdog" */
2667 init_waitqueue_head(&av7110->arm_wait);
2668 av7110->arm_thread = NULL;
2669
2670 /* allocate and init buffers */
2671 av7110->debi_virt = pci_alloc_consistent(pdev, 8192, &av7110->debi_bus);
2672 if (!av7110->debi_virt)
2673 goto err_saa71466_vfree_4;
2674
2675
2676 av7110->iobuf = vmalloc(AVOUTLEN+AOUTLEN+BMPLEN+4*IPACKS);
2677 if (!av7110->iobuf)
2678 goto err_pci_free_5;
2679
2680 ret = av7110_av_init(av7110);
2681 if (ret < 0)
2682 goto err_iobuf_vfree_6;
2683
2684 /* init BMP buffer */
2685 av7110->bmpbuf = av7110->iobuf+AVOUTLEN+AOUTLEN;
2686 init_waitqueue_head(&av7110->bmpq);
2687
2688 ret = av7110_ca_init(av7110);
2689 if (ret < 0)
2690 goto err_av7110_av_exit_7;
2691
2692 /* load firmware into AV7110 cards */
2693 ret = av7110_bootarm(av7110);
2694 if (ret < 0)
2695 goto err_av7110_ca_exit_8;
2696
2697 ret = av7110_firmversion(av7110);
2698 if (ret < 0)
2699 goto err_stop_arm_9;
2700
2701 if (FW_VERSION(av7110->arm_app)<0x2501)
2702 printk ("dvb-ttpci: Warning, firmware version 0x%04x is too old. "
2703 "System might be unstable!\n", FW_VERSION(av7110->arm_app));
2704
2705 ret = kernel_thread(arm_thread, (void *) av7110, 0);
2706 if (ret < 0)
2707 goto err_stop_arm_9;
2708
2709 /* set initial volume in mixer struct */
2710 av7110->mixer.volume_left = volume;
2711 av7110->mixer.volume_right = volume;
2712
2713 init_av7110_av(av7110);
2714
2715 ret = av7110_register(av7110);
2716 if (ret < 0)
2717 goto err_arm_thread_stop_10;
2718
2719 /* special case DVB-C: these cards have an analog tuner
2720 plus need some special handling, so we have separate
2721 saa7146_ext_vv data for these... */
2722 ret = av7110_init_v4l(av7110);
2723 if (ret < 0)
2724 goto err_av7110_unregister_11;
2725
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07002726 av7110->dvb_adapter.priv = av7110;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002727 ret = frontend_init(av7110);
2728 if (ret < 0)
2729 goto err_av7110_exit_v4l_12;
2730
2731#if defined(CONFIG_INPUT_EVDEV) || defined(CONFIG_INPUT_EVDEV_MODULE)
Oliver Endriss03388ae2005-09-09 13:03:12 -07002732 av7110_ir_init(av7110);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002733#endif
2734 printk(KERN_INFO "dvb-ttpci: found av7110-%d.\n", av7110_num);
2735 av7110_num++;
2736out:
2737 return ret;
2738
2739err_av7110_exit_v4l_12:
2740 av7110_exit_v4l(av7110);
2741err_av7110_unregister_11:
2742 dvb_unregister(av7110);
2743err_arm_thread_stop_10:
2744 av7110_arm_sync(av7110);
2745err_stop_arm_9:
2746 /* Nothing to do. Rejoice. */
2747err_av7110_ca_exit_8:
2748 av7110_ca_exit(av7110);
2749err_av7110_av_exit_7:
2750 av7110_av_exit(av7110);
2751err_iobuf_vfree_6:
2752 vfree(av7110->iobuf);
2753err_pci_free_5:
2754 pci_free_consistent(pdev, 8192, av7110->debi_virt, av7110->debi_bus);
2755err_saa71466_vfree_4:
2756 if (!av7110->grabbing)
2757 saa7146_pgtable_free(pdev, &av7110->pt);
2758err_i2c_del_3:
2759 i2c_del_adapter(&av7110->i2c_adap);
2760err_dvb_unregister_adapter_2:
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07002761 dvb_unregister_adapter(&av7110->dvb_adapter);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002762err_put_firmware_1:
2763 put_firmware(av7110);
2764err_kfree_0:
2765 kfree(av7110);
2766 goto out;
2767}
2768
2769static int av7110_detach(struct saa7146_dev* saa)
2770{
2771 struct av7110 *av7110 = saa->ext_priv;
2772 dprintk(4, "%p\n", av7110);
2773
Oliver Endriss03388ae2005-09-09 13:03:12 -07002774#if defined(CONFIG_INPUT_EVDEV) || defined(CONFIG_INPUT_EVDEV_MODULE)
2775 av7110_ir_exit(av7110);
2776#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07002777 if (budgetpatch) {
2778 /* Disable RPS1 */
2779 saa7146_write(saa, MC1, MASK_29);
2780 /* VSYNC LOW (inactive) */
2781 saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO);
2782 saa7146_write(saa, MC1, MASK_20); /* DMA3 off */
2783 SAA7146_IER_DISABLE(saa, MASK_10);
2784 SAA7146_ISR_CLEAR(saa, MASK_10);
2785 msleep(50);
2786 tasklet_kill(&av7110->vpe_tasklet);
2787 saa7146_pgtable_free(saa->pci, &av7110->pt);
2788 }
2789 av7110_exit_v4l(av7110);
2790
2791 av7110_arm_sync(av7110);
2792
2793 tasklet_kill(&av7110->debi_tasklet);
2794 tasklet_kill(&av7110->gpio_tasklet);
2795
2796 dvb_unregister(av7110);
2797
2798 SAA7146_IER_DISABLE(saa, MASK_19 | MASK_03);
2799 SAA7146_ISR_CLEAR(saa, MASK_19 | MASK_03);
2800
2801 av7110_ca_exit(av7110);
2802 av7110_av_exit(av7110);
2803
2804 vfree(av7110->iobuf);
2805 pci_free_consistent(saa->pci, 8192, av7110->debi_virt,
2806 av7110->debi_bus);
2807
2808 i2c_del_adapter(&av7110->i2c_adap);
2809
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07002810 dvb_unregister_adapter (&av7110->dvb_adapter);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002811
2812 av7110_num--;
2813
2814 put_firmware(av7110);
2815
2816 kfree(av7110);
2817
2818 saa->ext_priv = NULL;
2819
2820 return 0;
2821}
2822
2823
2824static void av7110_irq(struct saa7146_dev* dev, u32 *isr)
2825{
2826 struct av7110 *av7110 = dev->ext_priv;
2827
2828 //print_time("av7110_irq");
2829
2830 /* Note: Don't try to handle the DEBI error irq (MASK_18), in
2831 * intel mode the timeout is asserted all the time...
2832 */
2833
2834 if (*isr & MASK_19) {
2835 //printk("av7110_irq: DEBI\n");
2836 /* Note 1: The DEBI irq is level triggered: We must enable it
2837 * only after we started a DMA xfer, and disable it here
2838 * immediately, or it will be signalled all the time while
2839 * DEBI is idle.
2840 * Note 2: You would think that an irq which is masked is
2841 * not signalled by the hardware. Not so for the SAA7146:
2842 * An irq is signalled as long as the corresponding bit
2843 * in the ISR is set, and disabling irqs just prevents the
2844 * hardware from setting the ISR bit. This means a) that we
2845 * must clear the ISR *after* disabling the irq (which is why
2846 * we must do it here even though saa7146_core did it already),
2847 * and b) that if we were to disable an edge triggered irq
2848 * (like the gpio irqs sadly are) temporarily we would likely
2849 * loose some. This sucks :-(
2850 */
2851 SAA7146_IER_DISABLE(av7110->dev, MASK_19);
2852 SAA7146_ISR_CLEAR(av7110->dev, MASK_19);
2853 tasklet_schedule(&av7110->debi_tasklet);
2854 }
2855
2856 if (*isr & MASK_03) {
2857 //printk("av7110_irq: GPIO\n");
2858 tasklet_schedule(&av7110->gpio_tasklet);
2859 }
2860
2861 if ((*isr & MASK_10) && budgetpatch)
2862 tasklet_schedule(&av7110->vpe_tasklet);
2863}
2864
2865
2866static struct saa7146_extension av7110_extension;
2867
2868#define MAKE_AV7110_INFO(x_var,x_name) \
2869static struct saa7146_pci_extension_data x_var = { \
2870 .ext_priv = x_name, \
2871 .ext = &av7110_extension }
2872
Karl Herz6af4ee12005-09-09 13:03:13 -07002873MAKE_AV7110_INFO(tts_1_X_fsc,"Technotrend/Hauppauge WinTV DVB-S rev1.X or Fujitsu Siemens DVB-C");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002874MAKE_AV7110_INFO(ttt_1_X, "Technotrend/Hauppauge WinTV DVB-T rev1.X");
2875MAKE_AV7110_INFO(ttc_1_X, "Technotrend/Hauppauge WinTV Nexus-CA rev1.X");
2876MAKE_AV7110_INFO(ttc_2_X, "Technotrend/Hauppauge WinTV DVB-C rev2.X");
2877MAKE_AV7110_INFO(tts_2_X, "Technotrend/Hauppauge WinTV Nexus-S rev2.X");
Johannes Stezenbach3dfaebd2005-05-16 21:54:19 -07002878MAKE_AV7110_INFO(tts_2_3, "Technotrend/Hauppauge WinTV Nexus-S rev2.3");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002879MAKE_AV7110_INFO(tts_1_3se, "Technotrend/Hauppauge WinTV DVB-S rev1.3 SE");
2880MAKE_AV7110_INFO(ttt, "Technotrend/Hauppauge DVB-T");
2881MAKE_AV7110_INFO(fsc, "Fujitsu Siemens DVB-C");
2882MAKE_AV7110_INFO(fss, "Fujitsu Siemens DVB-S rev1.6");
2883
2884static struct pci_device_id pci_tbl[] = {
Karl Herz6af4ee12005-09-09 13:03:13 -07002885 MAKE_EXTENSION_PCI(fsc, 0x110a, 0x0000),
2886 MAKE_EXTENSION_PCI(tts_1_X_fsc, 0x13c2, 0x0000),
2887 MAKE_EXTENSION_PCI(ttt_1_X, 0x13c2, 0x0001),
2888 MAKE_EXTENSION_PCI(ttc_2_X, 0x13c2, 0x0002),
2889 MAKE_EXTENSION_PCI(tts_2_X, 0x13c2, 0x0003),
2890 MAKE_EXTENSION_PCI(fss, 0x13c2, 0x0006),
2891 MAKE_EXTENSION_PCI(ttt, 0x13c2, 0x0008),
2892 MAKE_EXTENSION_PCI(ttc_1_X, 0x13c2, 0x000a),
2893 MAKE_EXTENSION_PCI(tts_2_3, 0x13c2, 0x000e),
2894 MAKE_EXTENSION_PCI(tts_1_3se, 0x13c2, 0x1002),
Linus Torvalds1da177e2005-04-16 15:20:36 -07002895
2896/* MAKE_EXTENSION_PCI(???, 0x13c2, 0x0004), UNDEFINED CARD */ // Galaxis DVB PC-Sat-Carte
2897/* MAKE_EXTENSION_PCI(???, 0x13c2, 0x0005), UNDEFINED CARD */ // Technisat SkyStar1
2898/* MAKE_EXTENSION_PCI(???, 0x13c2, 0x0009), UNDEFINED CARD */ // TT/Hauppauge WinTV Nexus-CA v????
2899
2900 {
2901 .vendor = 0,
2902 }
2903};
2904
2905MODULE_DEVICE_TABLE(pci, pci_tbl);
2906
2907
2908static struct saa7146_extension av7110_extension = {
2909 .name = "dvb\0",
2910 .flags = SAA7146_I2C_SHORT_DELAY,
2911
2912 .module = THIS_MODULE,
2913 .pci_tbl = &pci_tbl[0],
2914 .attach = av7110_attach,
2915 .detach = av7110_detach,
2916
2917 .irq_mask = MASK_19 | MASK_03 | MASK_10,
2918 .irq_func = av7110_irq,
2919};
2920
2921
2922static int __init av7110_init(void)
2923{
2924 int retval;
2925 retval = saa7146_register_extension(&av7110_extension);
2926 return retval;
2927}
2928
2929
2930static void __exit av7110_exit(void)
2931{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002932 saa7146_unregister_extension(&av7110_extension);
2933}
2934
2935module_init(av7110_init);
2936module_exit(av7110_exit);
2937
2938MODULE_DESCRIPTION("driver for the SAA7146 based AV110 PCI DVB cards by "
2939 "Siemens, Technotrend, Hauppauge");
2940MODULE_AUTHOR("Ralph Metzler, Marcus Metzler, others");
2941MODULE_LICENSE("GPL");