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