blob: 914f2e34d8d3c835917dbda43046f020e1ce5899 [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>
Linus Torvalds1da177e2005-04-16 15:20:36 -070057
58#include <linux/dvb/frontend.h>
59
60#include "dvb_frontend.h"
61
62#include "ttpci-eeprom.h"
63#include "av7110.h"
64#include "av7110_hw.h"
65#include "av7110_av.h"
66#include "av7110_ca.h"
67#include "av7110_ipack.h"
68
Oliver Endrissdb5d91e2006-02-28 10:32:25 -030069#include "bsbe1.h"
70#include "lnbp21.h"
71
Linus Torvalds1da177e2005-04-16 15:20:36 -070072#define TS_WIDTH 376
73#define TS_HEIGHT 512
74#define TS_BUFLEN (TS_WIDTH*TS_HEIGHT)
75#define TS_MAX_PACKETS (TS_BUFLEN/TS_SIZE)
76
77
78int av7110_debug;
79
80static int vidmode = CVBS_RGB_OUT;
81static int pids_off;
82static int adac = DVB_ADAC_TI;
83static int hw_sections;
84static int rgb_on;
85static int volume = 255;
Mauro Carvalho Chehaba5ed4252006-01-13 14:10:19 -020086static int budgetpatch;
Linus Torvalds1da177e2005-04-16 15:20:36 -070087
88module_param_named(debug, av7110_debug, int, 0644);
89MODULE_PARM_DESC(debug, "debug level (bitmask, default 0)");
90module_param(vidmode, int, 0444);
91MODULE_PARM_DESC(vidmode,"analog video out: 0 off, 1 CVBS+RGB (default), 2 CVBS+YC, 3 YC");
92module_param(pids_off, int, 0444);
93MODULE_PARM_DESC(pids_off,"clear video/audio/PCR PID filters when demux is closed");
94module_param(adac, int, 0444);
95MODULE_PARM_DESC(adac,"audio DAC type: 0 TI, 1 CRYSTAL, 2 MSP (use if autodetection fails)");
96module_param(hw_sections, int, 0444);
97MODULE_PARM_DESC(hw_sections, "0 use software section filter, 1 use hardware");
98module_param(rgb_on, int, 0444);
99MODULE_PARM_DESC(rgb_on, "For Siemens DVB-C cards only: Enable RGB control"
100 " signal on SCART pin 16 to switch SCART video mode from CVBS to RGB");
101module_param(volume, int, 0444);
102MODULE_PARM_DESC(volume, "initial volume: default 255 (range 0-255)");
103module_param(budgetpatch, int, 0444);
104MODULE_PARM_DESC(budgetpatch, "use budget-patch hardware modification: default 0 (0 no, 1 autodetect, 2 always)");
105
106static void restart_feeds(struct av7110 *av7110);
107
Mauro Carvalho Chehaba5ed4252006-01-13 14:10:19 -0200108static int av7110_num;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700109
110#define FE_FUNC_OVERRIDE(fe_func, av7110_copy, av7110_func) \
111{\
112 if (fe_func != NULL) { \
113 av7110_copy = fe_func; \
114 fe_func = av7110_func; \
115 } \
116}
117
118
119static void init_av7110_av(struct av7110 *av7110)
120{
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700121 int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700122 struct saa7146_dev *dev = av7110->dev;
123
124 /* set internal volume control to maximum */
125 av7110->adac_type = DVB_ADAC_TI;
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700126 ret = av7110_set_volume(av7110, av7110->mixer.volume_left, av7110->mixer.volume_right);
Johannes Stezenbach7a2fa902005-07-07 17:58:01 -0700127 if (ret < 0)
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700128 printk("dvb-ttpci:cannot set internal volume to maximum:%d\n",ret);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700129
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700130 ret = av7710_set_video_mode(av7110, vidmode);
Johannes Stezenbach7a2fa902005-07-07 17:58:01 -0700131 if (ret < 0)
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700132 printk("dvb-ttpci:cannot set video mode:%d\n",ret);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700133
134 /* handle different card types */
135 /* remaining inits according to card and frontend type */
136 av7110->analog_tuner_flags = 0;
137 av7110->current_input = 0;
Marco Schluessler1c13b952006-01-09 15:25:06 -0200138 if (dev->pci->subsystem_vendor == 0x13c2 && dev->pci->subsystem_device == 0x000a) {
139 printk("dvb-ttpci: MSP3415 audio DAC @ card %d\n",
140 av7110->dvb_adapter.num);
141 av7110->adac_type = DVB_ADAC_MSP34x5;
142 av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, ADSwitch, 1, 0); // SPDIF on
143 }
144 else if (i2c_writereg(av7110, 0x20, 0x00, 0x00) == 1) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700145 printk ("dvb-ttpci: Crystal audio DAC @ card %d detected\n",
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -0700146 av7110->dvb_adapter.num);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700147 av7110->adac_type = DVB_ADAC_CRYSTAL;
148 i2c_writereg(av7110, 0x20, 0x01, 0xd2);
149 i2c_writereg(av7110, 0x20, 0x02, 0x49);
150 i2c_writereg(av7110, 0x20, 0x03, 0x00);
151 i2c_writereg(av7110, 0x20, 0x04, 0x00);
152
153 /**
154 * some special handling for the Siemens DVB-C cards...
155 */
156 } else if (0 == av7110_init_analog_module(av7110)) {
157 /* done. */
158 }
159 else if (dev->pci->subsystem_vendor == 0x110a) {
160 printk("dvb-ttpci: DVB-C w/o analog module @ card %d detected\n",
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -0700161 av7110->dvb_adapter.num);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700162 av7110->adac_type = DVB_ADAC_NONE;
163 }
164 else {
165 av7110->adac_type = adac;
166 printk("dvb-ttpci: adac type set to %d @ card %d\n",
Marco Schluessler1c13b952006-01-09 15:25:06 -0200167 av7110->adac_type, av7110->dvb_adapter.num);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700168 }
169
Marco Schluessler1c13b952006-01-09 15:25:06 -0200170 if (av7110->adac_type == DVB_ADAC_NONE || av7110->adac_type == DVB_ADAC_MSP34x0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700171 // switch DVB SCART on
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700172 ret = av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, MainSwitch, 1, 0);
Johannes Stezenbach7a2fa902005-07-07 17:58:01 -0700173 if (ret < 0)
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700174 printk("dvb-ttpci:cannot switch on SCART(Main):%d\n",ret);
175 ret = av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, ADSwitch, 1, 1);
Johannes Stezenbach7a2fa902005-07-07 17:58:01 -0700176 if (ret < 0)
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700177 printk("dvb-ttpci:cannot switch on SCART(AD):%d\n",ret);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700178 if (rgb_on &&
Karl Herz6af4ee12005-09-09 13:03:13 -0700179 ((av7110->dev->pci->subsystem_vendor == 0x110a) ||
180 (av7110->dev->pci->subsystem_vendor == 0x13c2)) &&
181 (av7110->dev->pci->subsystem_device == 0x0000)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700182 saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); // RGB on, SCART pin 16
183 //saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); // SCARTpin 8
184 }
185 }
186
Oliver Endriss60edb132005-12-19 08:54:11 -0200187 if (dev->pci->subsystem_vendor == 0x13c2 && dev->pci->subsystem_device == 0x000e)
188 av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, SpdifSwitch, 1, 0); // SPDIF on
189
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700190 ret = av7110_set_volume(av7110, av7110->mixer.volume_left, av7110->mixer.volume_right);
Johannes Stezenbach7a2fa902005-07-07 17:58:01 -0700191 if (ret < 0)
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700192 printk("dvb-ttpci:cannot set volume :%d\n",ret);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700193}
194
195static void recover_arm(struct av7110 *av7110)
196{
197 dprintk(4, "%p\n",av7110);
198
199 av7110_bootarm(av7110);
200 msleep(100);
Oliver Endriss66190a22006-01-09 15:32:42 -0200201
202 init_av7110_av(av7110);
203
204 /* card-specific recovery */
205 if (av7110->recover)
206 av7110->recover(av7110);
207
Linus Torvalds1da177e2005-04-16 15:20:36 -0700208 restart_feeds(av7110);
209 av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, SetIR, 1, av7110->ir_config);
210}
211
Linus Torvalds1da177e2005-04-16 15:20:36 -0700212static 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
Ingo Molnar3593cab2006-02-07 06:49:14 -0200247 if (mutex_lock_interruptible(&av7110->dcomlock))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700248 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700249 newloops = rdebi(av7110, DEBINOSWAP, STATUS_LOOPS, 0, 2);
Ingo Molnar3593cab2006-02-07 06:49:14 -0200250 mutex_unlock(&av7110->dcomlock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700251
Oliver Endriss66190a22006-01-09 15:32:42 -0200252 if (newloops == av7110->arm_loops || av7110->arm_errors > 3) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700253 printk(KERN_ERR "dvb-ttpci: ARM crashed @ card %d\n",
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -0700254 av7110->dvb_adapter.num);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700255
Oliver Endriss66190a22006-01-09 15:32:42 -0200256 recover_arm(av7110);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700257
Ingo Molnar3593cab2006-02-07 06:49:14 -0200258 if (mutex_lock_interruptible(&av7110->dcomlock))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700259 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700260 newloops = rdebi(av7110, DEBINOSWAP, STATUS_LOOPS, 0, 2) - 1;
Ingo Molnar3593cab2006-02-07 06:49:14 -0200261 mutex_unlock(&av7110->dcomlock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700262 }
263 av7110->arm_loops = newloops;
Oliver Endriss66190a22006-01-09 15:32:42 -0200264 av7110->arm_errors = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700265 }
266
267 av7110->arm_thread = NULL;
268 return 0;
269}
270
271
Linus Torvalds1da177e2005-04-16 15:20:36 -0700272/****************************************************************************
273 * IRQ handling
274 ****************************************************************************/
275
276static int DvbDmxFilterCallback(u8 *buffer1, size_t buffer1_len,
277 u8 *buffer2, size_t buffer2_len,
278 struct dvb_demux_filter *dvbdmxfilter,
279 enum dmx_success success,
280 struct av7110 *av7110)
281{
282 if (!dvbdmxfilter->feed->demux->dmx.frontend)
283 return 0;
284 if (dvbdmxfilter->feed->demux->dmx.frontend->source == DMX_MEMORY_FE)
285 return 0;
286
287 switch (dvbdmxfilter->type) {
288 case DMX_TYPE_SEC:
289 if ((((buffer1[1] << 8) | buffer1[2]) & 0xfff) + 3 != buffer1_len)
290 return 0;
291 if (dvbdmxfilter->doneq) {
292 struct dmx_section_filter *filter = &dvbdmxfilter->filter;
293 int i;
294 u8 xor, neq = 0;
295
296 for (i = 0; i < DVB_DEMUX_MASK_MAX; i++) {
297 xor = filter->filter_value[i] ^ buffer1[i];
298 neq |= dvbdmxfilter->maskandnotmode[i] & xor;
299 }
300 if (!neq)
301 return 0;
302 }
303 return dvbdmxfilter->feed->cb.sec(buffer1, buffer1_len,
304 buffer2, buffer2_len,
305 &dvbdmxfilter->filter,
306 DMX_OK);
307 case DMX_TYPE_TS:
308 if (!(dvbdmxfilter->feed->ts_type & TS_PACKET))
309 return 0;
310 if (dvbdmxfilter->feed->ts_type & TS_PAYLOAD_ONLY)
311 return dvbdmxfilter->feed->cb.ts(buffer1, buffer1_len,
312 buffer2, buffer2_len,
313 &dvbdmxfilter->feed->feed.ts,
314 DMX_OK);
315 else
316 av7110_p2t_write(buffer1, buffer1_len,
317 dvbdmxfilter->feed->pid,
318 &av7110->p2t_filter[dvbdmxfilter->index]);
319 default:
320 return 0;
321 }
322}
323
324
325//#define DEBUG_TIMING
326static inline void print_time(char *s)
327{
328#ifdef DEBUG_TIMING
329 struct timeval tv;
330 do_gettimeofday(&tv);
331 printk("%s: %d.%d\n", s, (int)tv.tv_sec, (int)tv.tv_usec);
332#endif
333}
334
335#define DEBI_READ 0
336#define DEBI_WRITE 1
337static inline void start_debi_dma(struct av7110 *av7110, int dir,
338 unsigned long addr, unsigned int len)
339{
340 dprintk(8, "%c %08lx %u\n", dir == DEBI_READ ? 'R' : 'W', addr, len);
341 if (saa7146_wait_for_debi_done(av7110->dev, 0)) {
342 printk(KERN_ERR "%s: saa7146_wait_for_debi_done timed out\n", __FUNCTION__);
343 return;
344 }
345
346 SAA7146_ISR_CLEAR(av7110->dev, MASK_19); /* for good measure */
347 SAA7146_IER_ENABLE(av7110->dev, MASK_19);
348 if (len < 5)
349 len = 5; /* we want a real DEBI DMA */
350 if (dir == DEBI_WRITE)
351 iwdebi(av7110, DEBISWAB, addr, 0, (len + 3) & ~3);
352 else
353 irdebi(av7110, DEBISWAB, addr, 0, len);
354}
355
356static void debiirq(unsigned long data)
357{
358 struct av7110 *av7110 = (struct av7110 *) data;
359 int type = av7110->debitype;
360 int handle = (type >> 8) & 0x1f;
361 unsigned int xfer = 0;
362
363 print_time("debi");
364 dprintk(4, "type 0x%04x\n", type);
365
366 if (type == -1) {
367 printk("DEBI irq oops @ %ld, psr:0x%08x, ssr:0x%08x\n",
368 jiffies, saa7146_read(av7110->dev, PSR),
369 saa7146_read(av7110->dev, SSR));
370 goto debi_done;
371 }
372 av7110->debitype = -1;
373
374 switch (type & 0xff) {
375
376 case DATA_TS_RECORD:
377 dvb_dmx_swfilter_packets(&av7110->demux,
378 (const u8 *) av7110->debi_virt,
379 av7110->debilen / 188);
380 xfer = RX_BUFF;
381 break;
382
383 case DATA_PES_RECORD:
384 if (av7110->demux.recording)
385 av7110_record_cb(&av7110->p2t[handle],
386 (u8 *) av7110->debi_virt,
387 av7110->debilen);
388 xfer = RX_BUFF;
389 break;
390
391 case DATA_IPMPE:
392 case DATA_FSECTION:
393 case DATA_PIPING:
394 if (av7110->handle2filter[handle])
395 DvbDmxFilterCallback((u8 *)av7110->debi_virt,
396 av7110->debilen, NULL, 0,
397 av7110->handle2filter[handle],
398 DMX_OK, av7110);
399 xfer = RX_BUFF;
400 break;
401
402 case DATA_CI_GET:
403 {
404 u8 *data = av7110->debi_virt;
405
406 if ((data[0] < 2) && data[2] == 0xff) {
407 int flags = 0;
408 if (data[5] > 0)
409 flags |= CA_CI_MODULE_PRESENT;
410 if (data[5] > 5)
411 flags |= CA_CI_MODULE_READY;
412 av7110->ci_slot[data[0]].flags = flags;
413 } else
414 ci_get_data(&av7110->ci_rbuffer,
415 av7110->debi_virt,
416 av7110->debilen);
417 xfer = RX_BUFF;
418 break;
419 }
420
421 case DATA_COMMON_INTERFACE:
422 CI_handle(av7110, (u8 *)av7110->debi_virt, av7110->debilen);
423#if 0
424 {
425 int i;
426
427 printk("av7110%d: ", av7110->num);
428 printk("%02x ", *(u8 *)av7110->debi_virt);
429 printk("%02x ", *(1+(u8 *)av7110->debi_virt));
430 for (i = 2; i < av7110->debilen; i++)
431 printk("%02x ", (*(i+(unsigned char *)av7110->debi_virt)));
432 for (i = 2; i < av7110->debilen; i++)
433 printk("%c", chtrans(*(i+(unsigned char *)av7110->debi_virt)));
434
435 printk("\n");
436 }
437#endif
438 xfer = RX_BUFF;
439 break;
440
441 case DATA_DEBUG_MESSAGE:
442 ((s8*)av7110->debi_virt)[Reserved_SIZE - 1] = 0;
443 printk("%s\n", (s8 *) av7110->debi_virt);
444 xfer = RX_BUFF;
445 break;
446
447 case DATA_CI_PUT:
448 dprintk(4, "debi DATA_CI_PUT\n");
449 case DATA_MPEG_PLAY:
450 dprintk(4, "debi DATA_MPEG_PLAY\n");
451 case DATA_BMP_LOAD:
452 dprintk(4, "debi DATA_BMP_LOAD\n");
453 xfer = TX_BUFF;
454 break;
455 default:
456 break;
457 }
458debi_done:
459 spin_lock(&av7110->debilock);
460 if (xfer)
461 iwdebi(av7110, DEBINOSWAP, xfer, 0, 2);
462 ARM_ClearMailBox(av7110);
463 spin_unlock(&av7110->debilock);
464}
465
466/* irq from av7110 firmware writing the mailbox register in the DPRAM */
467static void gpioirq(unsigned long data)
468{
469 struct av7110 *av7110 = (struct av7110 *) data;
470 u32 rxbuf, txbuf;
471 int len;
472
473 if (av7110->debitype != -1)
474 /* we shouldn't get any irq while a debi xfer is running */
475 printk("dvb-ttpci: GPIO0 irq oops @ %ld, psr:0x%08x, ssr:0x%08x\n",
476 jiffies, saa7146_read(av7110->dev, PSR),
477 saa7146_read(av7110->dev, SSR));
478
479 if (saa7146_wait_for_debi_done(av7110->dev, 0)) {
480 printk(KERN_ERR "%s: saa7146_wait_for_debi_done timed out\n", __FUNCTION__);
481 BUG(); /* maybe we should try resetting the debi? */
482 }
483
484 spin_lock(&av7110->debilock);
485 ARM_ClearIrq(av7110);
486
487 /* see what the av7110 wants */
488 av7110->debitype = irdebi(av7110, DEBINOSWAP, IRQ_STATE, 0, 2);
489 av7110->debilen = irdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);
490 rxbuf = irdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
491 txbuf = irdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);
492 len = (av7110->debilen + 3) & ~3;
493
494 print_time("gpio");
495 dprintk(8, "GPIO0 irq 0x%04x %d\n", av7110->debitype, av7110->debilen);
496
497 switch (av7110->debitype & 0xff) {
498
499 case DATA_TS_PLAY:
500 case DATA_PES_PLAY:
501 break;
502
503 case DATA_MPEG_VIDEO_EVENT:
504 {
505 u32 h_ar;
506 struct video_event event;
507
508 av7110->video_size.w = irdebi(av7110, DEBINOSWAP, STATUS_MPEG_WIDTH, 0, 2);
509 h_ar = irdebi(av7110, DEBINOSWAP, STATUS_MPEG_HEIGHT_AR, 0, 2);
510
511 iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);
512 iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
513
514 av7110->video_size.h = h_ar & 0xfff;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700515
516 event.type = VIDEO_EVENT_SIZE_CHANGED;
517 event.u.size.w = av7110->video_size.w;
518 event.u.size.h = av7110->video_size.h;
519 switch ((h_ar >> 12) & 0xf)
520 {
521 case 3:
522 av7110->video_size.aspect_ratio = VIDEO_FORMAT_16_9;
523 event.u.size.aspect_ratio = VIDEO_FORMAT_16_9;
524 av7110->videostate.video_format = VIDEO_FORMAT_16_9;
525 break;
526 case 4:
527 av7110->video_size.aspect_ratio = VIDEO_FORMAT_221_1;
528 event.u.size.aspect_ratio = VIDEO_FORMAT_221_1;
529 av7110->videostate.video_format = VIDEO_FORMAT_221_1;
530 break;
531 default:
532 av7110->video_size.aspect_ratio = VIDEO_FORMAT_4_3;
533 event.u.size.aspect_ratio = VIDEO_FORMAT_4_3;
534 av7110->videostate.video_format = VIDEO_FORMAT_4_3;
535 }
Oliver Endriss66190a22006-01-09 15:32:42 -0200536
537 dprintk(8, "GPIO0 irq: DATA_MPEG_VIDEO_EVENT: w/h/ar = %u/%u/%u\n",
538 av7110->video_size.w, av7110->video_size.h,
539 av7110->video_size.aspect_ratio);
540
Linus Torvalds1da177e2005-04-16 15:20:36 -0700541 dvb_video_add_event(av7110, &event);
542 break;
543 }
544
545 case DATA_CI_PUT:
546 {
547 int avail;
548 struct dvb_ringbuffer *cibuf = &av7110->ci_wbuffer;
549
550 avail = dvb_ringbuffer_avail(cibuf);
551 if (avail <= 2) {
552 iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);
553 iwdebi(av7110, DEBINOSWAP, TX_LEN, 0, 2);
554 iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);
555 break;
556 }
557 len = DVB_RINGBUFFER_PEEK(cibuf, 0) << 8;
558 len |= DVB_RINGBUFFER_PEEK(cibuf, 1);
559 if (avail < len + 2) {
560 iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);
561 iwdebi(av7110, DEBINOSWAP, TX_LEN, 0, 2);
562 iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);
563 break;
564 }
565 DVB_RINGBUFFER_SKIP(cibuf, 2);
566
567 dvb_ringbuffer_read(cibuf, av7110->debi_virt, len, 0);
568
569 iwdebi(av7110, DEBINOSWAP, TX_LEN, len, 2);
570 iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, len, 2);
571 dprintk(8, "DMA: CI\n");
572 start_debi_dma(av7110, DEBI_WRITE, DPRAM_BASE + txbuf, len);
573 spin_unlock(&av7110->debilock);
574 wake_up(&cibuf->queue);
575 return;
576 }
577
578 case DATA_MPEG_PLAY:
579 if (!av7110->playing) {
580 iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);
581 iwdebi(av7110, DEBINOSWAP, TX_LEN, 0, 2);
582 iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);
583 break;
584 }
585 len = 0;
586 if (av7110->debitype & 0x100) {
587 spin_lock(&av7110->aout.lock);
588 len = av7110_pes_play(av7110->debi_virt, &av7110->aout, 2048);
589 spin_unlock(&av7110->aout.lock);
590 }
591 if (len <= 0 && (av7110->debitype & 0x200)
592 &&av7110->videostate.play_state != VIDEO_FREEZED) {
593 spin_lock(&av7110->avout.lock);
594 len = av7110_pes_play(av7110->debi_virt, &av7110->avout, 2048);
595 spin_unlock(&av7110->avout.lock);
596 }
597 if (len <= 0) {
598 iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);
599 iwdebi(av7110, DEBINOSWAP, TX_LEN, 0, 2);
600 iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);
601 break;
602 }
603 dprintk(8, "GPIO0 PES_PLAY len=%04x\n", len);
604 iwdebi(av7110, DEBINOSWAP, TX_LEN, len, 2);
605 iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, len, 2);
606 dprintk(8, "DMA: MPEG_PLAY\n");
607 start_debi_dma(av7110, DEBI_WRITE, DPRAM_BASE + txbuf, len);
608 spin_unlock(&av7110->debilock);
609 return;
610
611 case DATA_BMP_LOAD:
612 len = av7110->debilen;
613 dprintk(8, "gpio DATA_BMP_LOAD len %d\n", len);
614 if (!len) {
615 av7110->bmp_state = BMP_LOADED;
616 iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);
617 iwdebi(av7110, DEBINOSWAP, TX_LEN, 0, 2);
618 iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);
619 wake_up(&av7110->bmpq);
620 dprintk(8, "gpio DATA_BMP_LOAD done\n");
621 break;
622 }
623 if (len > av7110->bmplen)
624 len = av7110->bmplen;
625 if (len > 2 * 1024)
626 len = 2 * 1024;
627 iwdebi(av7110, DEBINOSWAP, TX_LEN, len, 2);
628 iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, len, 2);
629 memcpy(av7110->debi_virt, av7110->bmpbuf+av7110->bmpp, len);
630 av7110->bmpp += len;
631 av7110->bmplen -= len;
632 dprintk(8, "gpio DATA_BMP_LOAD DMA len %d\n", len);
633 start_debi_dma(av7110, DEBI_WRITE, DPRAM_BASE+txbuf, len);
634 spin_unlock(&av7110->debilock);
635 return;
636
637 case DATA_CI_GET:
638 case DATA_COMMON_INTERFACE:
639 case DATA_FSECTION:
640 case DATA_IPMPE:
641 case DATA_PIPING:
642 if (!len || len > 4 * 1024) {
643 iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
644 break;
645 }
646 /* fall through */
647
648 case DATA_TS_RECORD:
649 case DATA_PES_RECORD:
650 dprintk(8, "DMA: TS_REC etc.\n");
651 start_debi_dma(av7110, DEBI_READ, DPRAM_BASE+rxbuf, len);
652 spin_unlock(&av7110->debilock);
653 return;
654
655 case DATA_DEBUG_MESSAGE:
656 if (!len || len > 0xff) {
657 iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
658 break;
659 }
660 start_debi_dma(av7110, DEBI_READ, Reserved, len);
661 spin_unlock(&av7110->debilock);
662 return;
663
664 case DATA_IRCOMMAND:
Oliver Endriss03388ae2005-09-09 13:03:12 -0700665 if (av7110->ir_handler)
666 av7110->ir_handler(av7110,
667 swahw32(irdebi(av7110, DEBINOSWAP, Reserved, 0, 4)));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700668 iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
669 break;
670
671 default:
672 printk("dvb-ttpci: gpioirq unknown type=%d len=%d\n",
673 av7110->debitype, av7110->debilen);
674 break;
675 }
676 av7110->debitype = -1;
677 ARM_ClearMailBox(av7110);
678 spin_unlock(&av7110->debilock);
679}
680
681
682#ifdef CONFIG_DVB_AV7110_OSD
683static int dvb_osd_ioctl(struct inode *inode, struct file *file,
684 unsigned int cmd, void *parg)
685{
686 struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;
687 struct av7110 *av7110 = (struct av7110 *) dvbdev->priv;
688
689 dprintk(4, "%p\n", av7110);
690
691 if (cmd == OSD_SEND_CMD)
692 return av7110_osd_cmd(av7110, (osd_cmd_t *) parg);
693 if (cmd == OSD_GET_CAPABILITY)
694 return av7110_osd_capability(av7110, (osd_cap_t *) parg);
695
696 return -EINVAL;
697}
698
699
700static struct file_operations dvb_osd_fops = {
701 .owner = THIS_MODULE,
702 .ioctl = dvb_generic_ioctl,
703 .open = dvb_generic_open,
704 .release = dvb_generic_release,
705};
706
707static struct dvb_device dvbdev_osd = {
708 .priv = NULL,
709 .users = 1,
710 .writers = 1,
711 .fops = &dvb_osd_fops,
712 .kernel_ioctl = dvb_osd_ioctl,
713};
714#endif /* CONFIG_DVB_AV7110_OSD */
715
716
717static inline int SetPIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid,
718 u16 subpid, u16 pcrpid)
719{
Dr. Werner Fink47f36922006-01-09 15:25:07 -0200720 u16 aflags = 0;
721
Linus Torvalds1da177e2005-04-16 15:20:36 -0700722 dprintk(4, "%p\n", av7110);
723
724 if (vpid == 0x1fff || apid == 0x1fff ||
725 ttpid == 0x1fff || subpid == 0x1fff || pcrpid == 0x1fff) {
726 vpid = apid = ttpid = subpid = pcrpid = 0;
727 av7110->pids[DMX_PES_VIDEO] = 0;
728 av7110->pids[DMX_PES_AUDIO] = 0;
729 av7110->pids[DMX_PES_TELETEXT] = 0;
730 av7110->pids[DMX_PES_PCR] = 0;
731 }
732
Dr. Werner Fink47f36922006-01-09 15:25:07 -0200733 if (av7110->audiostate.bypass_mode)
734 aflags |= 0x8000;
735
736 return av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, MultiPID, 6,
737 pcrpid, vpid, apid, ttpid, subpid, aflags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700738}
739
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700740int ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700741 u16 subpid, u16 pcrpid)
742{
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700743 int ret = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700744 dprintk(4, "%p\n", av7110);
745
Ingo Molnar3593cab2006-02-07 06:49:14 -0200746 if (mutex_lock_interruptible(&av7110->pid_mutex))
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700747 return -ERESTARTSYS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700748
749 if (!(vpid & 0x8000))
750 av7110->pids[DMX_PES_VIDEO] = vpid;
751 if (!(apid & 0x8000))
752 av7110->pids[DMX_PES_AUDIO] = apid;
753 if (!(ttpid & 0x8000))
754 av7110->pids[DMX_PES_TELETEXT] = ttpid;
755 if (!(pcrpid & 0x8000))
756 av7110->pids[DMX_PES_PCR] = pcrpid;
757
758 av7110->pids[DMX_PES_SUBTITLE] = 0;
759
760 if (av7110->fe_synced) {
761 pcrpid = av7110->pids[DMX_PES_PCR];
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700762 ret = SetPIDs(av7110, vpid, apid, ttpid, subpid, pcrpid);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700763 }
764
Ingo Molnar3593cab2006-02-07 06:49:14 -0200765 mutex_unlock(&av7110->pid_mutex);
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700766 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700767}
768
769
770/******************************************************************************
771 * hardware filter functions
772 ******************************************************************************/
773
774static int StartHWFilter(struct dvb_demux_filter *dvbdmxfilter)
775{
776 struct dvb_demux_feed *dvbdmxfeed = dvbdmxfilter->feed;
777 struct av7110 *av7110 = (struct av7110 *) dvbdmxfeed->demux->priv;
778 u16 buf[20];
779 int ret, i;
780 u16 handle;
781// u16 mode = 0x0320;
782 u16 mode = 0xb96a;
783
784 dprintk(4, "%p\n", av7110);
785
786 if (dvbdmxfilter->type == DMX_TYPE_SEC) {
787 if (hw_sections) {
788 buf[4] = (dvbdmxfilter->filter.filter_value[0] << 8) |
789 dvbdmxfilter->maskandmode[0];
790 for (i = 3; i < 18; i++)
791 buf[i + 4 - 2] =
792 (dvbdmxfilter->filter.filter_value[i] << 8) |
793 dvbdmxfilter->maskandmode[i];
794 mode = 4;
795 }
796 } else if ((dvbdmxfeed->ts_type & TS_PACKET) &&
797 !(dvbdmxfeed->ts_type & TS_PAYLOAD_ONLY)) {
798 av7110_p2t_init(&av7110->p2t_filter[dvbdmxfilter->index], dvbdmxfeed);
799 }
800
801 buf[0] = (COMTYPE_PID_FILTER << 8) + AddPIDFilter;
802 buf[1] = 16;
803 buf[2] = dvbdmxfeed->pid;
804 buf[3] = mode;
805
806 ret = av7110_fw_request(av7110, buf, 20, &handle, 1);
807 if (ret != 0 || handle >= 32) {
808 printk("dvb-ttpci: %s error buf %04x %04x %04x %04x "
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700809 "ret %d handle %04x\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700810 __FUNCTION__, buf[0], buf[1], buf[2], buf[3],
811 ret, handle);
812 dvbdmxfilter->hw_handle = 0xffff;
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700813 if (!ret)
814 ret = -1;
815 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700816 }
817
818 av7110->handle2filter[handle] = dvbdmxfilter;
819 dvbdmxfilter->hw_handle = handle;
820
821 return ret;
822}
823
824static int StopHWFilter(struct dvb_demux_filter *dvbdmxfilter)
825{
826 struct av7110 *av7110 = (struct av7110 *) dvbdmxfilter->feed->demux->priv;
827 u16 buf[3];
828 u16 answ[2];
829 int ret;
830 u16 handle;
831
832 dprintk(4, "%p\n", av7110);
833
834 handle = dvbdmxfilter->hw_handle;
835 if (handle >= 32) {
836 printk("%s tried to stop invalid filter %04x, filter type = %x\n",
837 __FUNCTION__, handle, dvbdmxfilter->type);
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700838 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700839 }
840
841 av7110->handle2filter[handle] = NULL;
842
843 buf[0] = (COMTYPE_PID_FILTER << 8) + DelPIDFilter;
844 buf[1] = 1;
845 buf[2] = handle;
846 ret = av7110_fw_request(av7110, buf, 3, answ, 2);
847 if (ret != 0 || answ[1] != handle) {
848 printk("dvb-ttpci: %s error cmd %04x %04x %04x ret %x "
849 "resp %04x %04x pid %d\n",
850 __FUNCTION__, buf[0], buf[1], buf[2], ret,
851 answ[0], answ[1], dvbdmxfilter->feed->pid);
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700852 if (!ret)
853 ret = -1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700854 }
855 return ret;
856}
857
858
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700859static int dvb_feed_start_pid(struct dvb_demux_feed *dvbdmxfeed)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700860{
861 struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
862 struct av7110 *av7110 = (struct av7110 *) dvbdmx->priv;
863 u16 *pid = dvbdmx->pids, npids[5];
864 int i;
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700865 int ret = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700866
867 dprintk(4, "%p\n", av7110);
868
869 npids[0] = npids[1] = npids[2] = npids[3] = npids[4] = 0xffff;
870 i = dvbdmxfeed->pes_type;
871 npids[i] = (pid[i]&0x8000) ? 0 : pid[i];
872 if ((i == 2) && npids[i] && (dvbdmxfeed->ts_type & TS_PACKET)) {
873 npids[i] = 0;
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700874 ret = ChangePIDs(av7110, npids[1], npids[0], npids[2], npids[3], npids[4]);
875 if (!ret)
876 ret = StartHWFilter(dvbdmxfeed->filter);
877 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700878 }
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700879 if (dvbdmxfeed->pes_type <= 2 || dvbdmxfeed->pes_type == 4) {
880 ret = ChangePIDs(av7110, npids[1], npids[0], npids[2], npids[3], npids[4]);
881 if (ret)
882 return ret;
883 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700884
885 if (dvbdmxfeed->pes_type < 2 && npids[0])
886 if (av7110->fe_synced)
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700887 {
888 ret = av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, Scan, 0);
889 if (ret)
890 return ret;
891 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700892
893 if ((dvbdmxfeed->ts_type & TS_PACKET)) {
894 if (dvbdmxfeed->pes_type == 0 && !(dvbdmx->pids[0] & 0x8000))
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700895 ret = av7110_av_start_record(av7110, RP_AUDIO, dvbdmxfeed);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700896 if (dvbdmxfeed->pes_type == 1 && !(dvbdmx->pids[1] & 0x8000))
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700897 ret = av7110_av_start_record(av7110, RP_VIDEO, dvbdmxfeed);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700898 }
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700899 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700900}
901
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700902static int dvb_feed_stop_pid(struct dvb_demux_feed *dvbdmxfeed)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700903{
904 struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
905 struct av7110 *av7110 = (struct av7110 *) dvbdmx->priv;
906 u16 *pid = dvbdmx->pids, npids[5];
907 int i;
908
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700909 int ret = 0;
910
Linus Torvalds1da177e2005-04-16 15:20:36 -0700911 dprintk(4, "%p\n", av7110);
912
913 if (dvbdmxfeed->pes_type <= 1) {
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700914 ret = av7110_av_stop(av7110, dvbdmxfeed->pes_type ? RP_VIDEO : RP_AUDIO);
915 if (ret)
916 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700917 if (!av7110->rec_mode)
918 dvbdmx->recording = 0;
919 if (!av7110->playing)
920 dvbdmx->playing = 0;
921 }
922 npids[0] = npids[1] = npids[2] = npids[3] = npids[4] = 0xffff;
923 i = dvbdmxfeed->pes_type;
924 switch (i) {
925 case 2: //teletext
926 if (dvbdmxfeed->ts_type & TS_PACKET)
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700927 ret = StopHWFilter(dvbdmxfeed->filter);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700928 npids[2] = 0;
929 break;
930 case 0:
931 case 1:
932 case 4:
933 if (!pids_off)
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700934 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700935 npids[i] = (pid[i]&0x8000) ? 0 : pid[i];
936 break;
937 }
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700938 if (!ret)
939 ret = ChangePIDs(av7110, npids[1], npids[0], npids[2], npids[3], npids[4]);
940 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700941}
942
943static int av7110_start_feed(struct dvb_demux_feed *feed)
944{
945 struct dvb_demux *demux = feed->demux;
946 struct av7110 *av7110 = demux->priv;
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700947 int ret = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700948
949 dprintk(4, "%p\n", av7110);
950
951 if (!demux->dmx.frontend)
952 return -EINVAL;
953
954 if (feed->pid > 0x1fff)
955 return -EINVAL;
956
957 if (feed->type == DMX_TYPE_TS) {
958 if ((feed->ts_type & TS_DECODER) &&
959 (feed->pes_type < DMX_TS_PES_OTHER)) {
960 switch (demux->dmx.frontend->source) {
961 case DMX_MEMORY_FE:
962 if (feed->ts_type & TS_DECODER)
963 if (feed->pes_type < 2 &&
964 !(demux->pids[0] & 0x8000) &&
965 !(demux->pids[1] & 0x8000)) {
966 dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout);
967 dvb_ringbuffer_flush_spinlock_wakeup(&av7110->aout);
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700968 ret = av7110_av_start_play(av7110,RP_AV);
969 if (!ret)
970 demux->playing = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700971 }
972 break;
973 default:
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700974 ret = dvb_feed_start_pid(feed);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700975 break;
976 }
977 } else if ((feed->ts_type & TS_PACKET) &&
978 (demux->dmx.frontend->source != DMX_MEMORY_FE)) {
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700979 ret = StartHWFilter(feed->filter);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700980 }
981 }
982
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700983 else if (feed->type == DMX_TYPE_SEC) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700984 int i;
985
986 for (i = 0; i < demux->filternum; i++) {
987 if (demux->filter[i].state != DMX_STATE_READY)
988 continue;
989 if (demux->filter[i].type != DMX_TYPE_SEC)
990 continue;
991 if (demux->filter[i].filter.parent != &feed->feed.sec)
992 continue;
993 demux->filter[i].state = DMX_STATE_GO;
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700994 if (demux->dmx.frontend->source != DMX_MEMORY_FE) {
995 ret = StartHWFilter(&demux->filter[i]);
996 if (ret)
997 break;
998 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700999 }
1000 }
1001
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001002 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001003}
1004
1005
1006static int av7110_stop_feed(struct dvb_demux_feed *feed)
1007{
1008 struct dvb_demux *demux = feed->demux;
1009 struct av7110 *av7110 = demux->priv;
Johannes Stezenbach12ba0502005-07-07 17:58:00 -07001010 int i, rc, ret = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001011 dprintk(4, "%p\n", av7110);
1012
1013 if (feed->type == DMX_TYPE_TS) {
1014 if (feed->ts_type & TS_DECODER) {
1015 if (feed->pes_type >= DMX_TS_PES_OTHER ||
1016 !demux->pesfilter[feed->pes_type])
1017 return -EINVAL;
1018 demux->pids[feed->pes_type] |= 0x8000;
1019 demux->pesfilter[feed->pes_type] = NULL;
1020 }
1021 if (feed->ts_type & TS_DECODER &&
1022 feed->pes_type < DMX_TS_PES_OTHER) {
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001023 ret = dvb_feed_stop_pid(feed);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001024 } else
1025 if ((feed->ts_type & TS_PACKET) &&
1026 (demux->dmx.frontend->source != DMX_MEMORY_FE))
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001027 ret = StopHWFilter(feed->filter);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001028 }
1029
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001030 if (!ret && feed->type == DMX_TYPE_SEC) {
Johannes Stezenbach12ba0502005-07-07 17:58:00 -07001031 for (i = 0; i<demux->filternum; i++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001032 if (demux->filter[i].state == DMX_STATE_GO &&
1033 demux->filter[i].filter.parent == &feed->feed.sec) {
1034 demux->filter[i].state = DMX_STATE_READY;
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001035 if (demux->dmx.frontend->source != DMX_MEMORY_FE) {
Johannes Stezenbach12ba0502005-07-07 17:58:00 -07001036 rc = StopHWFilter(&demux->filter[i]);
1037 if (!ret)
1038 ret = rc;
1039 /* keep going, stop as many filters as possible */
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001040 }
Johannes Stezenbach12ba0502005-07-07 17:58:00 -07001041 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001042 }
1043 }
1044
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001045 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001046}
1047
1048
1049static void restart_feeds(struct av7110 *av7110)
1050{
1051 struct dvb_demux *dvbdmx = &av7110->demux;
1052 struct dvb_demux_feed *feed;
1053 int mode;
Oliver Endriss66190a22006-01-09 15:32:42 -02001054 int i, j;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001055
1056 dprintk(4, "%p\n", av7110);
1057
1058 mode = av7110->playing;
1059 av7110->playing = 0;
1060 av7110->rec_mode = 0;
1061
Oliver Endriss66190a22006-01-09 15:32:42 -02001062 for (i = 0; i < dvbdmx->feednum; i++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001063 feed = &dvbdmx->feed[i];
Oliver Endriss66190a22006-01-09 15:32:42 -02001064 if (feed->state == DMX_STATE_GO) {
1065 if (feed->type == DMX_TYPE_SEC) {
1066 for (j = 0; j < dvbdmx->filternum; j++) {
1067 if (dvbdmx->filter[j].type != DMX_TYPE_SEC)
1068 continue;
1069 if (dvbdmx->filter[j].filter.parent != &feed->feed.sec)
1070 continue;
1071 if (dvbdmx->filter[j].state == DMX_STATE_GO)
1072 dvbdmx->filter[j].state = DMX_STATE_READY;
1073 }
1074 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001075 av7110_start_feed(feed);
Oliver Endriss66190a22006-01-09 15:32:42 -02001076 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001077 }
1078
1079 if (mode)
1080 av7110_av_start_play(av7110, mode);
1081}
1082
1083static int dvb_get_stc(struct dmx_demux *demux, unsigned int num,
1084 uint64_t *stc, unsigned int *base)
1085{
1086 int ret;
1087 u16 fwstc[4];
1088 u16 tag = ((COMTYPE_REQUEST << 8) + ReqSTC);
1089 struct dvb_demux *dvbdemux;
1090 struct av7110 *av7110;
1091
1092 /* pointer casting paranoia... */
1093 if (!demux)
1094 BUG();
1095 dvbdemux = (struct dvb_demux *) demux->priv;
1096 if (!dvbdemux)
1097 BUG();
1098 av7110 = (struct av7110 *) dvbdemux->priv;
1099
1100 dprintk(4, "%p\n", av7110);
1101
1102 if (num != 0)
1103 return -EINVAL;
1104
1105 ret = av7110_fw_request(av7110, &tag, 0, fwstc, 4);
1106 if (ret) {
1107 printk(KERN_ERR "%s: av7110_fw_request error\n", __FUNCTION__);
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001108 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001109 }
1110 dprintk(2, "fwstc = %04hx %04hx %04hx %04hx\n",
1111 fwstc[0], fwstc[1], fwstc[2], fwstc[3]);
1112
1113 *stc = (((uint64_t) ((fwstc[3] & 0x8000) >> 15)) << 32) |
1114 (((uint64_t) fwstc[1]) << 16) | ((uint64_t) fwstc[0]);
1115 *base = 1;
1116
1117 dprintk(4, "stc = %lu\n", (unsigned long)*stc);
1118
1119 return 0;
1120}
1121
1122
1123/******************************************************************************
1124 * SEC device file operations
1125 ******************************************************************************/
1126
1127
1128static int av7110_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
1129{
1130 struct av7110* av7110 = (struct av7110*) fe->dvb->priv;
1131
1132 switch (tone) {
1133 case SEC_TONE_ON:
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001134 return Set22K(av7110, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001135
1136 case SEC_TONE_OFF:
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001137 return Set22K(av7110, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001138
1139 default:
1140 return -EINVAL;
1141 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001142}
1143
1144static int av7110_diseqc_send_master_cmd(struct dvb_frontend* fe,
1145 struct dvb_diseqc_master_cmd* cmd)
1146{
1147 struct av7110* av7110 = fe->dvb->priv;
1148
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001149 return av7110_diseqc_send(av7110, cmd->msg_len, cmd->msg, -1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001150}
1151
1152static int av7110_diseqc_send_burst(struct dvb_frontend* fe,
1153 fe_sec_mini_cmd_t minicmd)
1154{
1155 struct av7110* av7110 = fe->dvb->priv;
1156
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001157 return av7110_diseqc_send(av7110, 0, NULL, minicmd);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001158}
1159
1160/* simplified code from budget-core.c */
1161static int stop_ts_capture(struct av7110 *budget)
1162{
1163 dprintk(2, "budget: %p\n", budget);
1164
1165 if (--budget->feeding1)
1166 return budget->feeding1;
1167 saa7146_write(budget->dev, MC1, MASK_20); /* DMA3 off */
1168 SAA7146_IER_DISABLE(budget->dev, MASK_10);
1169 SAA7146_ISR_CLEAR(budget->dev, MASK_10);
1170 return 0;
1171}
1172
1173static int start_ts_capture(struct av7110 *budget)
1174{
1175 dprintk(2, "budget: %p\n", budget);
1176
1177 if (budget->feeding1)
1178 return ++budget->feeding1;
1179 memset(budget->grabbing, 0x00, TS_HEIGHT * TS_WIDTH);
1180 budget->tsf = 0xff;
1181 budget->ttbp = 0;
1182 SAA7146_IER_ENABLE(budget->dev, MASK_10); /* VPE */
1183 saa7146_write(budget->dev, MC1, (MASK_04 | MASK_20)); /* DMA3 on */
1184 return ++budget->feeding1;
1185}
1186
1187static int budget_start_feed(struct dvb_demux_feed *feed)
1188{
1189 struct dvb_demux *demux = feed->demux;
1190 struct av7110 *budget = (struct av7110 *) demux->priv;
1191 int status;
1192
1193 dprintk(2, "av7110: %p\n", budget);
1194
1195 spin_lock(&budget->feedlock1);
1196 feed->pusi_seen = 0; /* have a clean section start */
1197 status = start_ts_capture(budget);
1198 spin_unlock(&budget->feedlock1);
1199 return status;
1200}
1201
1202static int budget_stop_feed(struct dvb_demux_feed *feed)
1203{
1204 struct dvb_demux *demux = feed->demux;
1205 struct av7110 *budget = (struct av7110 *) demux->priv;
1206 int status;
1207
1208 dprintk(2, "budget: %p\n", budget);
1209
1210 spin_lock(&budget->feedlock1);
1211 status = stop_ts_capture(budget);
1212 spin_unlock(&budget->feedlock1);
1213 return status;
1214}
1215
1216static void vpeirq(unsigned long data)
1217{
1218 struct av7110 *budget = (struct av7110 *) data;
1219 u8 *mem = (u8 *) (budget->grabbing);
1220 u32 olddma = budget->ttbp;
1221 u32 newdma = saa7146_read(budget->dev, PCI_VDP3);
1222
1223 if (!budgetpatch) {
1224 printk("av7110.c: vpeirq() called while budgetpatch disabled!"
1225 " check saa7146 IER register\n");
1226 BUG();
1227 }
1228 /* nearest lower position divisible by 188 */
1229 newdma -= newdma % 188;
1230
1231 if (newdma >= TS_BUFLEN)
1232 return;
1233
1234 budget->ttbp = newdma;
1235
1236 if (!budget->feeding1 || (newdma == olddma))
1237 return;
1238
1239#if 0
1240 /* track rps1 activity */
1241 printk("vpeirq: %02x Event Counter 1 0x%04x\n",
1242 mem[olddma],
1243 saa7146_read(budget->dev, EC1R) & 0x3fff);
1244#endif
1245
1246 if (newdma > olddma)
1247 /* no wraparound, dump olddma..newdma */
1248 dvb_dmx_swfilter_packets(&budget->demux1, mem + olddma, (newdma - olddma) / 188);
1249 else {
1250 /* wraparound, dump olddma..buflen and 0..newdma */
1251 dvb_dmx_swfilter_packets(&budget->demux1, mem + olddma, (TS_BUFLEN - olddma) / 188);
1252 dvb_dmx_swfilter_packets(&budget->demux1, mem, newdma / 188);
1253 }
1254}
1255
1256static int av7110_register(struct av7110 *av7110)
1257{
1258 int ret, i;
1259 struct dvb_demux *dvbdemux = &av7110->demux;
1260 struct dvb_demux *dvbdemux1 = &av7110->demux1;
1261
1262 dprintk(4, "%p\n", av7110);
1263
1264 if (av7110->registered)
1265 return -1;
1266
1267 av7110->registered = 1;
1268
1269 dvbdemux->priv = (void *) av7110;
1270
1271 for (i = 0; i < 32; i++)
1272 av7110->handle2filter[i] = NULL;
1273
1274 dvbdemux->filternum = 32;
1275 dvbdemux->feednum = 32;
1276 dvbdemux->start_feed = av7110_start_feed;
1277 dvbdemux->stop_feed = av7110_stop_feed;
1278 dvbdemux->write_to_decoder = av7110_write_to_decoder;
1279 dvbdemux->dmx.capabilities = (DMX_TS_FILTERING | DMX_SECTION_FILTERING |
1280 DMX_MEMORY_BASED_FILTERING);
1281
1282 dvb_dmx_init(&av7110->demux);
1283 av7110->demux.dmx.get_stc = dvb_get_stc;
1284
1285 av7110->dmxdev.filternum = 32;
1286 av7110->dmxdev.demux = &dvbdemux->dmx;
1287 av7110->dmxdev.capabilities = 0;
1288
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001289 dvb_dmxdev_init(&av7110->dmxdev, &av7110->dvb_adapter);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001290
1291 av7110->hw_frontend.source = DMX_FRONTEND_0;
1292
1293 ret = dvbdemux->dmx.add_frontend(&dvbdemux->dmx, &av7110->hw_frontend);
1294
1295 if (ret < 0)
1296 return ret;
1297
1298 av7110->mem_frontend.source = DMX_MEMORY_FE;
1299
1300 ret = dvbdemux->dmx.add_frontend(&dvbdemux->dmx, &av7110->mem_frontend);
1301
1302 if (ret < 0)
1303 return ret;
1304
1305 ret = dvbdemux->dmx.connect_frontend(&dvbdemux->dmx,
1306 &av7110->hw_frontend);
1307 if (ret < 0)
1308 return ret;
1309
1310 av7110_av_register(av7110);
1311 av7110_ca_register(av7110);
1312
1313#ifdef CONFIG_DVB_AV7110_OSD
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001314 dvb_register_device(&av7110->dvb_adapter, &av7110->osd_dev,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001315 &dvbdev_osd, av7110, DVB_DEVICE_OSD);
1316#endif
1317
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001318 dvb_net_init(&av7110->dvb_adapter, &av7110->dvb_net, &dvbdemux->dmx);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001319
1320 if (budgetpatch) {
1321 /* initialize software demux1 without its own frontend
1322 * demux1 hardware is connected to frontend0 of demux0
1323 */
1324 dvbdemux1->priv = (void *) av7110;
1325
1326 dvbdemux1->filternum = 256;
1327 dvbdemux1->feednum = 256;
1328 dvbdemux1->start_feed = budget_start_feed;
1329 dvbdemux1->stop_feed = budget_stop_feed;
1330 dvbdemux1->write_to_decoder = NULL;
1331
1332 dvbdemux1->dmx.capabilities = (DMX_TS_FILTERING | DMX_SECTION_FILTERING |
1333 DMX_MEMORY_BASED_FILTERING);
1334
1335 dvb_dmx_init(&av7110->demux1);
1336
1337 av7110->dmxdev1.filternum = 256;
1338 av7110->dmxdev1.demux = &dvbdemux1->dmx;
1339 av7110->dmxdev1.capabilities = 0;
1340
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001341 dvb_dmxdev_init(&av7110->dmxdev1, &av7110->dvb_adapter);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001342
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001343 dvb_net_init(&av7110->dvb_adapter, &av7110->dvb_net1, &dvbdemux1->dmx);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001344 printk("dvb-ttpci: additional demux1 for budget-patch registered\n");
1345 }
1346 return 0;
1347}
1348
1349
1350static void dvb_unregister(struct av7110 *av7110)
1351{
1352 struct dvb_demux *dvbdemux = &av7110->demux;
1353 struct dvb_demux *dvbdemux1 = &av7110->demux1;
1354
1355 dprintk(4, "%p\n", av7110);
1356
1357 if (!av7110->registered)
1358 return;
1359
1360 if (budgetpatch) {
1361 dvb_net_release(&av7110->dvb_net1);
1362 dvbdemux->dmx.close(&dvbdemux1->dmx);
1363 dvb_dmxdev_release(&av7110->dmxdev1);
1364 dvb_dmx_release(&av7110->demux1);
1365 }
1366
1367 dvb_net_release(&av7110->dvb_net);
1368
1369 dvbdemux->dmx.close(&dvbdemux->dmx);
1370 dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, &av7110->hw_frontend);
1371 dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, &av7110->mem_frontend);
1372
1373 dvb_dmxdev_release(&av7110->dmxdev);
1374 dvb_dmx_release(&av7110->demux);
1375
1376 if (av7110->fe != NULL)
1377 dvb_unregister_frontend(av7110->fe);
1378 dvb_unregister_device(av7110->osd_dev);
1379 av7110_av_unregister(av7110);
1380 av7110_ca_unregister(av7110);
1381}
1382
1383
1384/****************************************************************************
1385 * I2C client commands
1386 ****************************************************************************/
1387
1388int i2c_writereg(struct av7110 *av7110, u8 id, u8 reg, u8 val)
1389{
1390 u8 msg[2] = { reg, val };
1391 struct i2c_msg msgs;
1392
1393 msgs.flags = 0;
1394 msgs.addr = id / 2;
1395 msgs.len = 2;
1396 msgs.buf = msg;
1397 return i2c_transfer(&av7110->i2c_adap, &msgs, 1);
1398}
1399
1400#if 0
1401u8 i2c_readreg(struct av7110 *av7110, u8 id, u8 reg)
1402{
1403 u8 mm1[] = {0x00};
1404 u8 mm2[] = {0x00};
1405 struct i2c_msg msgs[2];
1406
1407 msgs[0].flags = 0;
1408 msgs[1].flags = I2C_M_RD;
1409 msgs[0].addr = msgs[1].addr = id / 2;
1410 mm1[0] = reg;
1411 msgs[0].len = 1; msgs[1].len = 1;
1412 msgs[0].buf = mm1; msgs[1].buf = mm2;
1413 i2c_transfer(&av7110->i2c_adap, msgs, 2);
1414
1415 return mm2[0];
1416}
1417#endif
1418
1419/****************************************************************************
1420 * INITIALIZATION
1421 ****************************************************************************/
1422
1423
1424static int check_firmware(struct av7110* av7110)
1425{
1426 u32 crc = 0, len = 0;
1427 unsigned char *ptr;
1428
1429 /* check for firmware magic */
1430 ptr = av7110->bin_fw;
1431 if (ptr[0] != 'A' || ptr[1] != 'V' ||
1432 ptr[2] != 'F' || ptr[3] != 'W') {
1433 printk("dvb-ttpci: this is not an av7110 firmware\n");
1434 return -EINVAL;
1435 }
1436 ptr += 4;
1437
1438 /* check dpram file */
1439 crc = ntohl(*(u32*) ptr);
1440 ptr += 4;
1441 len = ntohl(*(u32*) ptr);
1442 ptr += 4;
1443 if (len >= 512) {
1444 printk("dvb-ttpci: dpram file is way to big.\n");
1445 return -EINVAL;
1446 }
1447 if (crc != crc32_le(0, ptr, len)) {
1448 printk("dvb-ttpci: crc32 of dpram file does not match.\n");
1449 return -EINVAL;
1450 }
1451 av7110->bin_dpram = ptr;
1452 av7110->size_dpram = len;
1453 ptr += len;
1454
1455 /* check root file */
1456 crc = ntohl(*(u32*) ptr);
1457 ptr += 4;
1458 len = ntohl(*(u32*) ptr);
1459 ptr += 4;
1460
1461 if (len <= 200000 || len >= 300000 ||
1462 len > ((av7110->bin_fw + av7110->size_fw) - ptr)) {
1463 printk("dvb-ttpci: root file has strange size (%d). aborting.\n", len);
1464 return -EINVAL;
1465 }
1466 if( crc != crc32_le(0, ptr, len)) {
1467 printk("dvb-ttpci: crc32 of root file does not match.\n");
1468 return -EINVAL;
1469 }
1470 av7110->bin_root = ptr;
1471 av7110->size_root = len;
1472 return 0;
1473}
1474
1475#ifdef CONFIG_DVB_AV7110_FIRMWARE_FILE
1476#include "av7110_firm.h"
1477static void put_firmware(struct av7110* av7110)
1478{
1479 av7110->bin_fw = NULL;
1480}
1481
1482static inline int get_firmware(struct av7110* av7110)
1483{
1484 av7110->bin_fw = dvb_ttpci_fw;
1485 av7110->size_fw = sizeof(dvb_ttpci_fw);
1486 return check_firmware(av7110);
1487}
1488#else
1489static void put_firmware(struct av7110* av7110)
1490{
1491 vfree(av7110->bin_fw);
1492}
1493
1494static int get_firmware(struct av7110* av7110)
1495{
1496 int ret;
1497 const struct firmware *fw;
1498
1499 /* request the av7110 firmware, this will block until someone uploads it */
1500 ret = request_firmware(&fw, "dvb-ttpci-01.fw", &av7110->dev->pci->dev);
1501 if (ret) {
1502 if (ret == -ENOENT) {
1503 printk(KERN_ERR "dvb-ttpci: could not load firmware,"
1504 " file not found: dvb-ttpci-01.fw\n");
Ville Skytt\ä12e66f62006-01-09 15:25:38 -02001505 printk(KERN_ERR "dvb-ttpci: usually this should be in "
1506 "/usr/lib/hotplug/firmware or /lib/firmware\n");
1507 printk(KERN_ERR "dvb-ttpci: and can be downloaded from"
Linus Torvalds1da177e2005-04-16 15:20:36 -07001508 " http://www.linuxtv.org/download/dvb/firmware/\n");
1509 } else
1510 printk(KERN_ERR "dvb-ttpci: cannot request firmware"
1511 " (error %i)\n", ret);
1512 return -EINVAL;
1513 }
1514
1515 if (fw->size <= 200000) {
1516 printk("dvb-ttpci: this firmware is way too small.\n");
1517 release_firmware(fw);
1518 return -EINVAL;
1519 }
1520
1521 /* check if the firmware is available */
1522 av7110->bin_fw = (unsigned char *) vmalloc(fw->size);
1523 if (NULL == av7110->bin_fw) {
1524 dprintk(1, "out of memory\n");
1525 release_firmware(fw);
1526 return -ENOMEM;
1527 }
1528
1529 memcpy(av7110->bin_fw, fw->data, fw->size);
1530 av7110->size_fw = fw->size;
1531 if ((ret = check_firmware(av7110)))
1532 vfree(av7110->bin_fw);
1533
1534 release_firmware(fw);
1535 return ret;
1536}
1537#endif
1538
1539
1540static int alps_bsrv2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
1541{
1542 struct av7110* av7110 = (struct av7110*) fe->dvb->priv;
1543 u8 pwr = 0;
1544 u8 buf[4];
1545 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
1546 u32 div = (params->frequency + 479500) / 125;
1547
1548 if (params->frequency > 2000000) pwr = 3;
1549 else if (params->frequency > 1800000) pwr = 2;
1550 else if (params->frequency > 1600000) pwr = 1;
1551 else if (params->frequency > 1200000) pwr = 0;
1552 else if (params->frequency >= 1100000) pwr = 1;
1553 else pwr = 2;
1554
1555 buf[0] = (div >> 8) & 0x7f;
1556 buf[1] = div & 0xff;
1557 buf[2] = ((div & 0x18000) >> 10) | 0x95;
1558 buf[3] = (pwr << 6) | 0x30;
1559
Mauro Carvalho Chehab9101e622005-12-12 00:37:24 -08001560 // NOTE: since we're using a prescaler of 2, we set the
Linus Torvalds1da177e2005-04-16 15:20:36 -07001561 // divisor frequency to 62.5kHz and divide by 125 above
1562
1563 if (i2c_transfer (&av7110->i2c_adap, &msg, 1) != 1)
1564 return -EIO;
1565 return 0;
1566}
1567
1568static struct ves1x93_config alps_bsrv2_config = {
1569 .demod_address = 0x08,
1570 .xin = 90100000UL,
1571 .invert_pwm = 0,
1572 .pll_set = alps_bsrv2_pll_set,
1573};
1574
1575
1576static u8 alps_bsru6_inittab[] = {
1577 0x01, 0x15,
1578 0x02, 0x30,
1579 0x03, 0x00,
1580 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
1581 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */
1582 0x06, 0x40, /* DAC not used, set to high impendance mode */
1583 0x07, 0x00, /* DAC LSB */
1584 0x08, 0x40, /* DiSEqC off, LNB power on OP2/LOCK pin on */
1585 0x09, 0x00, /* FIFO */
1586 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
1587 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */
1588 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
1589 0x10, 0x3f, // AGC2 0x3d
1590 0x11, 0x84,
Oliver Endrissff29d062005-11-08 21:35:43 -08001591 0x12, 0xb9,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001592 0x15, 0xc9, // lock detector threshold
1593 0x16, 0x00,
1594 0x17, 0x00,
1595 0x18, 0x00,
1596 0x19, 0x00,
1597 0x1a, 0x00,
1598 0x1f, 0x50,
1599 0x20, 0x00,
1600 0x21, 0x00,
1601 0x22, 0x00,
1602 0x23, 0x00,
1603 0x28, 0x00, // out imp: normal out type: parallel FEC mode:0
1604 0x29, 0x1e, // 1/2 threshold
1605 0x2a, 0x14, // 2/3 threshold
1606 0x2b, 0x0f, // 3/4 threshold
1607 0x2c, 0x09, // 5/6 threshold
1608 0x2d, 0x05, // 7/8 threshold
1609 0x2e, 0x01,
1610 0x31, 0x1f, // test all FECs
1611 0x32, 0x19, // viterbi and synchro search
1612 0x33, 0xfc, // rs control
1613 0x34, 0x93, // error control
1614 0x0f, 0x52,
1615 0xff, 0xff
1616};
1617
1618static int alps_bsru6_set_symbol_rate(struct dvb_frontend* fe, u32 srate, u32 ratio)
1619{
1620 u8 aclk = 0;
1621 u8 bclk = 0;
1622
1623 if (srate < 1500000) { aclk = 0xb7; bclk = 0x47; }
1624 else if (srate < 3000000) { aclk = 0xb7; bclk = 0x4b; }
1625 else if (srate < 7000000) { aclk = 0xb7; bclk = 0x4f; }
1626 else if (srate < 14000000) { aclk = 0xb7; bclk = 0x53; }
1627 else if (srate < 30000000) { aclk = 0xb6; bclk = 0x53; }
1628 else if (srate < 45000000) { aclk = 0xb4; bclk = 0x51; }
1629
1630 stv0299_writereg(fe, 0x13, aclk);
1631 stv0299_writereg(fe, 0x14, bclk);
1632 stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
1633 stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
1634 stv0299_writereg(fe, 0x21, (ratio ) & 0xf0);
1635
1636 return 0;
1637}
1638
Andreas Oberrittercfbfce12005-09-09 13:02:30 -07001639static 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 -07001640{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001641 int ret;
1642 u8 data[4];
1643 u32 div;
1644 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
1645
1646 if ((params->frequency < 950000) || (params->frequency > 2150000))
1647 return -EINVAL;
1648
1649 div = (params->frequency + (125 - 1)) / 125; // round correctly
1650 data[0] = (div >> 8) & 0x7f;
1651 data[1] = div & 0xff;
1652 data[2] = 0x80 | ((div & 0x18000) >> 10) | 4;
1653 data[3] = 0xC4;
1654
1655 if (params->frequency > 1530000) data[3] = 0xc0;
1656
Andreas Oberrittercfbfce12005-09-09 13:02:30 -07001657 ret = i2c_transfer(i2c, &msg, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001658 if (ret != 1)
1659 return -EIO;
1660 return 0;
1661}
1662
1663static struct stv0299_config alps_bsru6_config = {
1664
1665 .demod_address = 0x68,
1666 .inittab = alps_bsru6_inittab,
1667 .mclk = 88000000UL,
1668 .invert = 1,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001669 .skip_reinit = 0,
1670 .lock_output = STV0229_LOCKOUTPUT_1,
1671 .volt13_op0_op1 = STV0299_VOLT13_OP1,
1672 .min_delay_ms = 100,
1673 .set_symbol_rate = alps_bsru6_set_symbol_rate,
1674 .pll_set = alps_bsru6_pll_set,
1675};
1676
1677
Linus Torvalds1da177e2005-04-16 15:20:36 -07001678static int alps_tdbe2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
1679{
1680 struct av7110* av7110 = fe->dvb->priv;
1681 u32 div;
1682 u8 data[4];
1683 struct i2c_msg msg = { .addr = 0x62, .flags = 0, .buf = data, .len = sizeof(data) };
1684
1685 div = (params->frequency + 35937500 + 31250) / 62500;
1686
1687 data[0] = (div >> 8) & 0x7f;
1688 data[1] = div & 0xff;
1689 data[2] = 0x85 | ((div >> 10) & 0x60);
1690 data[3] = (params->frequency < 174000000 ? 0x88 : params->frequency < 470000000 ? 0x84 : 0x81);
1691
1692 if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1)
1693 return -EIO;
1694 return 0;
1695}
1696
1697static struct ves1820_config alps_tdbe2_config = {
1698 .demod_address = 0x09,
1699 .xin = 57840000UL,
1700 .invert = 1,
1701 .selagc = VES1820_SELAGC_SIGNAMPERR,
1702 .pll_set = alps_tdbe2_pll_set,
1703};
1704
1705
1706
1707
1708static int grundig_29504_451_pll_set(struct dvb_frontend* fe,
1709 struct dvb_frontend_parameters* params)
1710{
1711 struct av7110* av7110 = fe->dvb->priv;
1712 u32 div;
1713 u8 data[4];
1714 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
1715
1716 div = params->frequency / 125;
1717 data[0] = (div >> 8) & 0x7f;
1718 data[1] = div & 0xff;
1719 data[2] = 0x8e;
1720 data[3] = 0x00;
1721
1722 if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1)
1723 return -EIO;
1724 return 0;
1725}
1726
1727static struct tda8083_config grundig_29504_451_config = {
1728 .demod_address = 0x68,
1729 .pll_set = grundig_29504_451_pll_set,
1730};
1731
1732
1733
1734static int philips_cd1516_pll_set(struct dvb_frontend* fe,
1735 struct dvb_frontend_parameters* params)
1736{
Mauro Carvalho Chehab9101e622005-12-12 00:37:24 -08001737 struct av7110* av7110 = fe->dvb->priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001738 u32 div;
1739 u32 f = params->frequency;
1740 u8 data[4];
1741 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
1742
1743 div = (f + 36125000 + 31250) / 62500;
1744
1745 data[0] = (div >> 8) & 0x7f;
1746 data[1] = div & 0xff;
1747 data[2] = 0x8e;
1748 data[3] = (f < 174000000 ? 0xa1 : f < 470000000 ? 0x92 : 0x34);
1749
1750 if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1)
1751 return -EIO;
1752 return 0;
1753}
1754
1755static struct ves1820_config philips_cd1516_config = {
1756 .demod_address = 0x09,
1757 .xin = 57840000UL,
1758 .invert = 1,
1759 .selagc = VES1820_SELAGC_SIGNAMPERR,
1760 .pll_set = philips_cd1516_pll_set,
1761};
1762
1763
1764
1765static int alps_tdlb7_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
1766{
1767 struct av7110* av7110 = fe->dvb->priv;
1768 u32 div, pwr;
1769 u8 data[4];
1770 struct i2c_msg msg = { .addr = 0x60, .flags = 0, .buf = data, .len = sizeof(data) };
1771
1772 div = (params->frequency + 36200000) / 166666;
1773
1774 if (params->frequency <= 782000000)
1775 pwr = 1;
1776 else
1777 pwr = 2;
1778
1779 data[0] = (div >> 8) & 0x7f;
1780 data[1] = div & 0xff;
1781 data[2] = 0x85;
1782 data[3] = pwr << 6;
1783
1784 if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1)
1785 return -EIO;
1786 return 0;
1787}
1788
1789static int alps_tdlb7_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name)
1790{
1791 struct av7110* av7110 = (struct av7110*) fe->dvb->priv;
1792
1793 return request_firmware(fw, name, &av7110->dev->pci->dev);
1794}
1795
1796static struct sp8870_config alps_tdlb7_config = {
1797
1798 .demod_address = 0x71,
1799 .pll_set = alps_tdlb7_pll_set,
1800 .request_firmware = alps_tdlb7_request_firmware,
1801};
1802
1803
Andrew de Quinceydc27a162005-09-09 13:03:07 -07001804static u8 nexusca_stv0297_inittab[] = {
1805 0x80, 0x01,
1806 0x80, 0x00,
1807 0x81, 0x01,
1808 0x81, 0x00,
1809 0x00, 0x09,
1810 0x01, 0x69,
1811 0x03, 0x00,
1812 0x04, 0x00,
1813 0x07, 0x00,
1814 0x08, 0x00,
1815 0x20, 0x00,
1816 0x21, 0x40,
1817 0x22, 0x00,
1818 0x23, 0x00,
1819 0x24, 0x40,
1820 0x25, 0x88,
1821 0x30, 0xff,
1822 0x31, 0x00,
1823 0x32, 0xff,
1824 0x33, 0x00,
1825 0x34, 0x50,
1826 0x35, 0x7f,
1827 0x36, 0x00,
1828 0x37, 0x20,
1829 0x38, 0x00,
1830 0x40, 0x1c,
1831 0x41, 0xff,
1832 0x42, 0x29,
1833 0x43, 0x00,
1834 0x44, 0xff,
1835 0x45, 0x00,
1836 0x46, 0x00,
1837 0x49, 0x04,
1838 0x4a, 0x00,
1839 0x4b, 0x7b,
1840 0x52, 0x30,
1841 0x55, 0xae,
1842 0x56, 0x47,
1843 0x57, 0xe1,
1844 0x58, 0x3a,
1845 0x5a, 0x1e,
1846 0x5b, 0x34,
1847 0x60, 0x00,
1848 0x63, 0x00,
1849 0x64, 0x00,
1850 0x65, 0x00,
1851 0x66, 0x00,
1852 0x67, 0x00,
1853 0x68, 0x00,
1854 0x69, 0x00,
1855 0x6a, 0x02,
1856 0x6b, 0x00,
1857 0x70, 0xff,
1858 0x71, 0x00,
1859 0x72, 0x00,
1860 0x73, 0x00,
1861 0x74, 0x0c,
1862 0x80, 0x00,
1863 0x81, 0x00,
1864 0x82, 0x00,
1865 0x83, 0x00,
1866 0x84, 0x04,
1867 0x85, 0x80,
1868 0x86, 0x24,
1869 0x87, 0x78,
1870 0x88, 0x10,
1871 0x89, 0x00,
1872 0x90, 0x01,
1873 0x91, 0x01,
1874 0xa0, 0x04,
1875 0xa1, 0x00,
1876 0xa2, 0x00,
1877 0xb0, 0x91,
1878 0xb1, 0x0b,
1879 0xc0, 0x53,
1880 0xc1, 0x70,
1881 0xc2, 0x12,
1882 0xd0, 0x00,
1883 0xd1, 0x00,
1884 0xd2, 0x00,
1885 0xd3, 0x00,
1886 0xd4, 0x00,
1887 0xd5, 0x00,
1888 0xde, 0x00,
1889 0xdf, 0x00,
1890 0x61, 0x49,
1891 0x62, 0x0b,
1892 0x53, 0x08,
1893 0x59, 0x08,
1894 0xff, 0xff,
1895};
Linus Torvalds1da177e2005-04-16 15:20:36 -07001896
1897static int nexusca_stv0297_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
1898{
1899 struct av7110* av7110 = fe->dvb->priv;
1900 u32 div;
1901 u8 data[4];
1902 struct i2c_msg msg = { .addr = 0x63, .flags = 0, .buf = data, .len = sizeof(data) };
1903 struct i2c_msg readmsg = { .addr = 0x63, .flags = I2C_M_RD, .buf = data, .len = 1 };
1904 int i;
1905
1906 div = (params->frequency + 36150000 + 31250) / 62500;
1907
1908 data[0] = (div >> 8) & 0x7f;
1909 data[1] = div & 0xff;
1910 data[2] = 0xce;
1911
1912 if (params->frequency < 45000000)
1913 return -EINVAL;
1914 else if (params->frequency < 137000000)
1915 data[3] = 0x01;
1916 else if (params->frequency < 403000000)
1917 data[3] = 0x02;
1918 else if (params->frequency < 860000000)
1919 data[3] = 0x04;
1920 else
1921 return -EINVAL;
1922
1923 stv0297_enable_plli2c(fe);
1924 if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1) {
1925 printk("nexusca: pll transfer failed!\n");
1926 return -EIO;
1927 }
1928
1929 // wait for PLL lock
1930 for(i = 0; i < 20; i++) {
1931
1932 stv0297_enable_plli2c(fe);
1933 if (i2c_transfer(&av7110->i2c_adap, &readmsg, 1) == 1)
1934 if (data[0] & 0x40) break;
1935 msleep(10);
1936 }
1937
1938 return 0;
1939}
1940
1941static struct stv0297_config nexusca_stv0297_config = {
1942
1943 .demod_address = 0x1C,
Andrew de Quinceydc27a162005-09-09 13:03:07 -07001944 .inittab = nexusca_stv0297_inittab,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001945 .invert = 1,
1946 .pll_set = nexusca_stv0297_pll_set,
1947};
1948
1949
1950
1951static int grundig_29504_401_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
1952{
1953 struct av7110* av7110 = (struct av7110*) fe->dvb->priv;
1954 u32 div;
1955 u8 cfg, cpump, band_select;
1956 u8 data[4];
1957 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
1958
1959 div = (36125000 + params->frequency) / 166666;
1960
1961 cfg = 0x88;
1962
1963 if (params->frequency < 175000000) cpump = 2;
1964 else if (params->frequency < 390000000) cpump = 1;
1965 else if (params->frequency < 470000000) cpump = 2;
1966 else if (params->frequency < 750000000) cpump = 1;
1967 else cpump = 3;
1968
1969 if (params->frequency < 175000000) band_select = 0x0e;
1970 else if (params->frequency < 470000000) band_select = 0x05;
1971 else band_select = 0x03;
1972
1973 data[0] = (div >> 8) & 0x7f;
1974 data[1] = div & 0xff;
1975 data[2] = ((div >> 10) & 0x60) | cfg;
1976 data[3] = (cpump << 6) | band_select;
1977
1978 if (i2c_transfer (&av7110->i2c_adap, &msg, 1) != 1) return -EIO;
1979 return 0;
1980}
1981
1982static struct l64781_config grundig_29504_401_config = {
1983 .demod_address = 0x55,
1984 .pll_set = grundig_29504_401_pll_set,
1985};
1986
1987
1988
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001989static int av7110_fe_lock_fix(struct av7110* av7110, fe_status_t status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001990{
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001991 int ret = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001992 int synced = (status & FE_HAS_LOCK) ? 1 : 0;
1993
1994 av7110->fe_status = status;
1995
1996 if (av7110->fe_synced == synced)
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001997 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001998
Linus Torvalds1da177e2005-04-16 15:20:36 -07001999 if (av7110->playing)
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002000 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002001
Ingo Molnar3593cab2006-02-07 06:49:14 -02002002 if (mutex_lock_interruptible(&av7110->pid_mutex))
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002003 return -ERESTARTSYS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002004
Oliver Endriss34612152005-07-07 17:58:02 -07002005 if (synced) {
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002006 ret = SetPIDs(av7110, av7110->pids[DMX_PES_VIDEO],
Linus Torvalds1da177e2005-04-16 15:20:36 -07002007 av7110->pids[DMX_PES_AUDIO],
2008 av7110->pids[DMX_PES_TELETEXT], 0,
2009 av7110->pids[DMX_PES_PCR]);
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002010 if (!ret)
2011 ret = av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, Scan, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002012 } else {
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002013 ret = SetPIDs(av7110, 0, 0, 0, 0, 0);
2014 if (!ret) {
2015 ret = av7110_fw_cmd(av7110, COMTYPE_PID_FILTER, FlushTSQueue, 0);
2016 if (!ret)
2017 ret = av7110_wait_msgstate(av7110, GPMQBusy);
2018 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002019 }
2020
Oliver Endriss34612152005-07-07 17:58:02 -07002021 if (!ret)
2022 av7110->fe_synced = synced;
2023
Ingo Molnar3593cab2006-02-07 06:49:14 -02002024 mutex_unlock(&av7110->pid_mutex);
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002025 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002026}
2027
2028static int av7110_fe_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
2029{
2030 struct av7110* av7110 = fe->dvb->priv;
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002031
2032 int ret = av7110_fe_lock_fix(av7110, 0);
Oliver Endriss66190a22006-01-09 15:32:42 -02002033 if (!ret) {
2034 av7110->saved_fe_params = *params;
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002035 ret = av7110->fe_set_frontend(fe, params);
Oliver Endriss66190a22006-01-09 15:32:42 -02002036 }
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002037 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002038}
2039
2040static int av7110_fe_init(struct dvb_frontend* fe)
2041{
2042 struct av7110* av7110 = fe->dvb->priv;
2043
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002044 int ret = av7110_fe_lock_fix(av7110, 0);
2045 if (!ret)
2046 ret = av7110->fe_init(fe);
2047 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002048}
2049
2050static int av7110_fe_read_status(struct dvb_frontend* fe, fe_status_t* status)
2051{
2052 struct av7110* av7110 = fe->dvb->priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002053
2054 /* call the real implementation */
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002055 int ret = av7110->fe_read_status(fe, status);
2056 if (!ret)
2057 if (((*status ^ av7110->fe_status) & FE_HAS_LOCK) && (*status & FE_HAS_LOCK))
2058 ret = av7110_fe_lock_fix(av7110, *status);
2059 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002060}
2061
2062static int av7110_fe_diseqc_reset_overload(struct dvb_frontend* fe)
2063{
2064 struct av7110* av7110 = fe->dvb->priv;
2065
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002066 int ret = av7110_fe_lock_fix(av7110, 0);
2067 if (!ret)
2068 ret = av7110->fe_diseqc_reset_overload(fe);
2069 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002070}
2071
2072static int av7110_fe_diseqc_send_master_cmd(struct dvb_frontend* fe,
2073 struct dvb_diseqc_master_cmd* cmd)
2074{
2075 struct av7110* av7110 = fe->dvb->priv;
2076
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002077 int ret = av7110_fe_lock_fix(av7110, 0);
Oliver Endriss66190a22006-01-09 15:32:42 -02002078 if (!ret) {
2079 av7110->saved_master_cmd = *cmd;
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002080 ret = av7110->fe_diseqc_send_master_cmd(fe, cmd);
Oliver Endriss66190a22006-01-09 15:32:42 -02002081 }
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002082 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002083}
2084
2085static int av7110_fe_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd)
2086{
2087 struct av7110* av7110 = fe->dvb->priv;
2088
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002089 int ret = av7110_fe_lock_fix(av7110, 0);
Oliver Endriss66190a22006-01-09 15:32:42 -02002090 if (!ret) {
2091 av7110->saved_minicmd = minicmd;
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002092 ret = av7110->fe_diseqc_send_burst(fe, minicmd);
Oliver Endriss66190a22006-01-09 15:32:42 -02002093 }
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002094 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002095}
2096
2097static int av7110_fe_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
2098{
2099 struct av7110* av7110 = fe->dvb->priv;
2100
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002101 int ret = av7110_fe_lock_fix(av7110, 0);
Oliver Endriss66190a22006-01-09 15:32:42 -02002102 if (!ret) {
2103 av7110->saved_tone = tone;
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002104 ret = av7110->fe_set_tone(fe, tone);
Oliver Endriss66190a22006-01-09 15:32:42 -02002105 }
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002106 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002107}
2108
2109static int av7110_fe_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
2110{
2111 struct av7110* av7110 = fe->dvb->priv;
2112
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002113 int ret = av7110_fe_lock_fix(av7110, 0);
Oliver Endriss66190a22006-01-09 15:32:42 -02002114 if (!ret) {
2115 av7110->saved_voltage = voltage;
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002116 ret = av7110->fe_set_voltage(fe, voltage);
Oliver Endriss66190a22006-01-09 15:32:42 -02002117 }
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002118 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002119}
2120
Peter Beutner400b7082006-01-09 15:32:43 -02002121static int av7110_fe_dishnetwork_send_legacy_command(struct dvb_frontend* fe, unsigned long cmd)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002122{
2123 struct av7110* av7110 = fe->dvb->priv;
2124
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002125 int ret = av7110_fe_lock_fix(av7110, 0);
2126 if (!ret)
2127 ret = av7110->fe_dishnetwork_send_legacy_command(fe, cmd);
2128 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002129}
2130
Oliver Endriss66190a22006-01-09 15:32:42 -02002131static void dvb_s_recover(struct av7110* av7110)
2132{
2133 av7110_fe_init(av7110->fe);
2134
2135 av7110_fe_set_voltage(av7110->fe, av7110->saved_voltage);
2136 if (av7110->saved_master_cmd.msg_len) {
2137 msleep(20);
2138 av7110_fe_diseqc_send_master_cmd(av7110->fe, &av7110->saved_master_cmd);
2139 }
2140 msleep(20);
2141 av7110_fe_diseqc_send_burst(av7110->fe, av7110->saved_minicmd);
2142 msleep(20);
2143 av7110_fe_set_tone(av7110->fe, av7110->saved_tone);
2144
2145 av7110_fe_set_frontend(av7110->fe, &av7110->saved_fe_params);
2146}
2147
Linus Torvalds1da177e2005-04-16 15:20:36 -07002148static u8 read_pwm(struct av7110* av7110)
2149{
2150 u8 b = 0xff;
2151 u8 pwm;
2152 struct i2c_msg msg[] = { { .addr = 0x50,.flags = 0,.buf = &b,.len = 1 },
2153 { .addr = 0x50,.flags = I2C_M_RD,.buf = &pwm,.len = 1} };
2154
Mauro Carvalho Chehab9101e622005-12-12 00:37:24 -08002155 if ((i2c_transfer(&av7110->i2c_adap, msg, 2) != 2) || (pwm == 0xff))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002156 pwm = 0x48;
2157
2158 return pwm;
2159}
2160
2161static int frontend_init(struct av7110 *av7110)
2162{
2163 int ret;
2164
2165 if (av7110->dev->pci->subsystem_vendor == 0x110a) {
2166 switch(av7110->dev->pci->subsystem_device) {
2167 case 0x0000: // Fujitsu/Siemens DVB-Cable (ves1820/Philips CD1516(??))
2168 av7110->fe = ves1820_attach(&philips_cd1516_config,
2169 &av7110->i2c_adap, read_pwm(av7110));
2170 break;
2171 }
2172
2173 } else if (av7110->dev->pci->subsystem_vendor == 0x13c2) {
2174 switch(av7110->dev->pci->subsystem_device) {
2175 case 0x0000: // Hauppauge/TT WinTV DVB-S rev1.X
2176 case 0x0003: // Hauppauge/TT WinTV Nexus-S Rev 2.X
2177 case 0x1002: // Hauppauge/TT WinTV DVB-S rev1.3SE
2178
2179 // try the ALPS BSRV2 first of all
2180 av7110->fe = ves1x93_attach(&alps_bsrv2_config, &av7110->i2c_adap);
2181 if (av7110->fe) {
2182 av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd;
2183 av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst;
2184 av7110->fe->ops->set_tone = av7110_set_tone;
Oliver Endriss66190a22006-01-09 15:32:42 -02002185 av7110->recover = dvb_s_recover;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002186 break;
2187 }
2188
2189 // try the ALPS BSRU6 now
2190 av7110->fe = stv0299_attach(&alps_bsru6_config, &av7110->i2c_adap);
2191 if (av7110->fe) {
2192 av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd;
2193 av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst;
2194 av7110->fe->ops->set_tone = av7110_set_tone;
Oliver Endriss66190a22006-01-09 15:32:42 -02002195 av7110->recover = dvb_s_recover;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002196 break;
2197 }
2198
2199 // Try the grundig 29504-451
Michael Krufky50c25ff2006-01-09 15:25:34 -02002200 av7110->fe = tda8083_attach(&grundig_29504_451_config, &av7110->i2c_adap);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002201 if (av7110->fe) {
2202 av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd;
2203 av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst;
2204 av7110->fe->ops->set_tone = av7110_set_tone;
Oliver Endriss66190a22006-01-09 15:32:42 -02002205 av7110->recover = dvb_s_recover;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002206 break;
2207 }
2208
2209 /* Try DVB-C cards */
2210 switch(av7110->dev->pci->subsystem_device) {
2211 case 0x0000:
2212 /* Siemens DVB-C (full-length card) VES1820/Philips CD1516 */
2213 av7110->fe = ves1820_attach(&philips_cd1516_config, &av7110->i2c_adap,
2214 read_pwm(av7110));
2215 break;
2216 case 0x0003:
2217 /* Haupauge DVB-C 2.1 VES1820/ALPS TDBE2 */
2218 av7110->fe = ves1820_attach(&alps_tdbe2_config, &av7110->i2c_adap,
2219 read_pwm(av7110));
2220 break;
2221 }
2222 break;
2223
2224 case 0x0001: // Hauppauge/TT Nexus-T premium rev1.X
2225
2226 // ALPS TDLB7
Michael Krufky50c25ff2006-01-09 15:25:34 -02002227 av7110->fe = sp8870_attach(&alps_tdlb7_config, &av7110->i2c_adap);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002228 break;
2229
2230 case 0x0002: // Hauppauge/TT DVB-C premium rev2.X
2231
Michael Krufky50c25ff2006-01-09 15:25:34 -02002232 av7110->fe = ves1820_attach(&alps_tdbe2_config, &av7110->i2c_adap, read_pwm(av7110));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002233 break;
2234
Oliver Endriss8bd63012006-02-07 06:49:11 -02002235 case 0x0004: // Galaxis DVB-S rev1.3
2236 /* ALPS BSRV2 */
2237 av7110->fe = ves1x93_attach(&alps_bsrv2_config, &av7110->i2c_adap);
2238 if (av7110->fe) {
2239 av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd;
2240 av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst;
2241 av7110->fe->ops->set_tone = av7110_set_tone;
2242 av7110->recover = dvb_s_recover;
2243 }
2244 break;
2245
Linus Torvalds1da177e2005-04-16 15:20:36 -07002246 case 0x0006: /* Fujitsu-Siemens DVB-S rev 1.6 */
2247 /* Grundig 29504-451 */
2248 av7110->fe = tda8083_attach(&grundig_29504_451_config, &av7110->i2c_adap);
2249 if (av7110->fe) {
2250 av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd;
2251 av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst;
2252 av7110->fe->ops->set_tone = av7110_set_tone;
Oliver Endriss66190a22006-01-09 15:32:42 -02002253 av7110->recover = dvb_s_recover;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002254 }
2255 break;
2256
2257 case 0x0008: // Hauppauge/TT DVB-T
2258
2259 av7110->fe = l64781_attach(&grundig_29504_401_config, &av7110->i2c_adap);
2260 break;
2261
2262 case 0x000A: // Hauppauge/TT Nexus-CA rev1.X
2263
Andrew de Quinceydc27a162005-09-09 13:03:07 -07002264 av7110->fe = stv0297_attach(&nexusca_stv0297_config, &av7110->i2c_adap);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002265 if (av7110->fe) {
2266 /* set TDA9819 into DVB mode */
2267 saa7146_setgpio(av7110->dev, 1, SAA7146_GPIO_OUTLO); // TDA9198 pin9(STD)
2268 saa7146_setgpio(av7110->dev, 3, SAA7146_GPIO_OUTLO); // TDA9198 pin30(VIF)
2269
2270 /* tuner on this needs a slower i2c bus speed */
2271 av7110->dev->i2c_bitrate = SAA7146_I2C_BUS_BIT_RATE_240;
2272 break;
2273 }
Johannes Stezenbach3dfaebd2005-05-16 21:54:19 -07002274 break;
2275
2276 case 0x000E: /* Hauppauge/TT Nexus-S rev 2.3 */
2277 /* ALPS BSBE1 */
2278 av7110->fe = stv0299_attach(&alps_bsbe1_config, &av7110->i2c_adap);
Oliver Endrisseb3daf32006-01-09 15:25:05 -02002279 if (av7110->fe) {
Oliver Endrissdb5d91e2006-02-28 10:32:25 -03002280 if (lnbp21_init(av7110->fe, &av7110->i2c_adap, 0, 0)) {
2281 printk("dvb-ttpci: LNBP21 not found!\n");
2282 if (av7110->fe->ops->release)
2283 av7110->fe->ops->release(av7110->fe);
2284 av7110->fe = NULL;
2285 } else {
2286 av7110->fe->ops->dishnetwork_send_legacy_command = NULL;
2287 av7110->recover = dvb_s_recover;
2288 }
Oliver Endrisseb3daf32006-01-09 15:25:05 -02002289 }
Johannes Stezenbach3dfaebd2005-05-16 21:54:19 -07002290 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002291 }
2292 }
2293
2294 if (!av7110->fe) {
2295 /* FIXME: propagate the failure code from the lower layers */
2296 ret = -ENOMEM;
2297 printk("dvb-ttpci: A frontend driver was not found for device %04x/%04x subsystem %04x/%04x\n",
2298 av7110->dev->pci->vendor,
2299 av7110->dev->pci->device,
2300 av7110->dev->pci->subsystem_vendor,
2301 av7110->dev->pci->subsystem_device);
2302 } else {
2303 FE_FUNC_OVERRIDE(av7110->fe->ops->init, av7110->fe_init, av7110_fe_init);
2304 FE_FUNC_OVERRIDE(av7110->fe->ops->read_status, av7110->fe_read_status, av7110_fe_read_status);
2305 FE_FUNC_OVERRIDE(av7110->fe->ops->diseqc_reset_overload, av7110->fe_diseqc_reset_overload, av7110_fe_diseqc_reset_overload);
2306 FE_FUNC_OVERRIDE(av7110->fe->ops->diseqc_send_master_cmd, av7110->fe_diseqc_send_master_cmd, av7110_fe_diseqc_send_master_cmd);
2307 FE_FUNC_OVERRIDE(av7110->fe->ops->diseqc_send_burst, av7110->fe_diseqc_send_burst, av7110_fe_diseqc_send_burst);
2308 FE_FUNC_OVERRIDE(av7110->fe->ops->set_tone, av7110->fe_set_tone, av7110_fe_set_tone);
2309 FE_FUNC_OVERRIDE(av7110->fe->ops->set_voltage, av7110->fe_set_voltage, av7110_fe_set_voltage;)
2310 FE_FUNC_OVERRIDE(av7110->fe->ops->dishnetwork_send_legacy_command, av7110->fe_dishnetwork_send_legacy_command, av7110_fe_dishnetwork_send_legacy_command);
2311 FE_FUNC_OVERRIDE(av7110->fe->ops->set_frontend, av7110->fe_set_frontend, av7110_fe_set_frontend);
2312
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07002313 ret = dvb_register_frontend(&av7110->dvb_adapter, av7110->fe);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002314 if (ret < 0) {
2315 printk("av7110: Frontend registration failed!\n");
2316 if (av7110->fe->ops->release)
2317 av7110->fe->ops->release(av7110->fe);
2318 av7110->fe = NULL;
2319 }
2320 }
2321 return ret;
2322}
2323
2324/* Budgetpatch note:
2325 * Original hardware design by Roberto Deza:
2326 * There is a DVB_Wiki at
2327 * http://212.227.36.83/linuxtv/wiki/index.php/Main_Page
2328 * where is described this 'DVB TT Budget Patch', on Card Modding:
2329 * http://212.227.36.83/linuxtv/wiki/index.php/DVB_TT_Budget_Patch
2330 * On the short description there is also a link to a external file,
2331 * with more details:
2332 * http://perso.wanadoo.es/jesussolano/Ttf_tsc1.zip
2333 *
2334 * New software triggering design by Emard that works on
2335 * original Roberto Deza's hardware:
2336 *
2337 * rps1 code for budgetpatch will copy internal HS event to GPIO3 pin.
2338 * GPIO3 is in budget-patch hardware connectd to port B VSYNC
2339 * HS is an internal event of 7146, accessible with RPS
2340 * and temporarily raised high every n lines
2341 * (n in defined in the RPS_THRESH1 counter threshold)
2342 * I think HS is raised high on the beginning of the n-th line
2343 * and remains high until this n-th line that triggered
2344 * it is completely received. When the receiption of n-th line
2345 * ends, HS is lowered.
2346 *
2347 * To transmit data over DMA, 7146 needs changing state at
2348 * port B VSYNC pin. Any changing of port B VSYNC will
2349 * cause some DMA data transfer, with more or less packets loss.
2350 * It depends on the phase and frequency of VSYNC and
2351 * the way of 7146 is instructed to trigger on port B (defined
2352 * in DD1_INIT register, 3rd nibble from the right valid
2353 * numbers are 0-7, see datasheet)
2354 *
2355 * The correct triggering can minimize packet loss,
2356 * dvbtraffic should give this stable bandwidths:
2357 * 22k transponder = 33814 kbit/s
2358 * 27.5k transponder = 38045 kbit/s
2359 * by experiment it is found that the best results
2360 * (stable bandwidths and almost no packet loss)
2361 * are obtained using DD1_INIT triggering number 2
2362 * (Va at rising edge of VS Fa = HS x VS-failing forced toggle)
2363 * and a VSYNC phase that occurs in the middle of DMA transfer
2364 * (about byte 188*512=96256 in the DMA window).
2365 *
2366 * Phase of HS is still not clear to me how to control,
2367 * It just happens to be so. It can be seen if one enables
2368 * RPS_IRQ and print Event Counter 1 in vpeirq(). Every
2369 * time RPS_INTERRUPT is called, the Event Counter 1 will
2370 * increment. That's how the 7146 is programmed to do event
2371 * counting in this budget-patch.c
2372 * I *think* HPS setting has something to do with the phase
2373 * of HS but I cant be 100% sure in that.
2374 *
2375 * hardware debug note: a working budget card (including budget patch)
2376 * with vpeirq() interrupt setup in mode "0x90" (every 64K) will
2377 * generate 3 interrupts per 25-Hz DMA frame of 2*188*512 bytes
2378 * and that means 3*25=75 Hz of interrupt freqency, as seen by
2379 * watch cat /proc/interrupts
2380 *
2381 * If this frequency is 3x lower (and data received in the DMA
2382 * buffer don't start with 0x47, but in the middle of packets,
2383 * whose lengths appear to be like 188 292 188 104 etc.
2384 * this means VSYNC line is not connected in the hardware.
2385 * (check soldering pcb and pins)
2386 * The same behaviour of missing VSYNC can be duplicated on budget
2387 * cards, by seting DD1_INIT trigger mode 7 in 3rd nibble.
2388 */
Johannes Stezenbach1be11e32006-02-27 00:09:20 -03002389static int __devinit av7110_attach(struct saa7146_dev* dev,
2390 struct saa7146_pci_extension_data *pci_ext)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002391{
2392 const int length = TS_WIDTH * TS_HEIGHT;
2393 struct pci_dev *pdev = dev->pci;
2394 struct av7110 *av7110;
2395 int ret, count = 0;
2396
2397 dprintk(4, "dev: %p\n", dev);
2398
Mauro Carvalho Chehab9101e622005-12-12 00:37:24 -08002399 /* Set RPS_IRQ to 1 to track rps1 activity.
2400 * Enabling this won't send any interrupt to PC CPU.
2401 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002402#define RPS_IRQ 0
2403
2404 if (budgetpatch == 1) {
2405 budgetpatch = 0;
2406 /* autodetect the presence of budget patch
2407 * this only works if saa7146 has been recently
2408 * reset with with MASK_31 to MC1
2409 *
2410 * will wait for VBI_B event (vertical blank at port B)
2411 * and will reset GPIO3 after VBI_B is detected.
2412 * (GPIO3 should be raised high by CPU to
2413 * test if GPIO3 will generate vertical blank signal
2414 * in budget patch GPIO3 is connected to VSYNC_B
2415 */
2416
2417 /* RESET SAA7146 */
2418 saa7146_write(dev, MC1, MASK_31);
2419 /* autodetection success seems to be time-dependend after reset */
2420
2421 /* Fix VSYNC level */
2422 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
2423 /* set vsync_b triggering */
2424 saa7146_write(dev, DD1_STREAM_B, 0);
2425 /* port B VSYNC at rising edge */
2426 saa7146_write(dev, DD1_INIT, 0x00000200);
2427 saa7146_write(dev, BRS_CTRL, 0x00000000); // VBI
2428 saa7146_write(dev, MC2,
2429 1 * (MASK_08 | MASK_24) | // BRS control
2430 0 * (MASK_09 | MASK_25) | // a
2431 1 * (MASK_10 | MASK_26) | // b
2432 0 * (MASK_06 | MASK_22) | // HPS_CTRL1
2433 0 * (MASK_05 | MASK_21) | // HPS_CTRL2
2434 0 * (MASK_01 | MASK_15) // DEBI
2435 );
2436
2437 /* start writing RPS1 code from beginning */
2438 count = 0;
2439 /* Disable RPS1 */
2440 saa7146_write(dev, MC1, MASK_29);
2441 /* RPS1 timeout disable */
2442 saa7146_write(dev, RPS_TOV1, 0);
2443 WRITE_RPS1(cpu_to_le32(CMD_PAUSE | EVT_VBI_B));
2444 WRITE_RPS1(cpu_to_le32(CMD_WR_REG_MASK | (GPIO_CTRL>>2)));
2445 WRITE_RPS1(cpu_to_le32(GPIO3_MSK));
2446 WRITE_RPS1(cpu_to_le32(SAA7146_GPIO_OUTLO<<24));
2447#if RPS_IRQ
2448 /* issue RPS1 interrupt to increment counter */
2449 WRITE_RPS1(cpu_to_le32(CMD_INTERRUPT));
2450#endif
2451 WRITE_RPS1(cpu_to_le32(CMD_STOP));
2452 /* Jump to begin of RPS program as safety measure (p37) */
2453 WRITE_RPS1(cpu_to_le32(CMD_JUMP));
2454 WRITE_RPS1(cpu_to_le32(dev->d_rps1.dma_handle));
2455
2456#if RPS_IRQ
2457 /* set event counter 1 source as RPS1 interrupt (0x03) (rE4 p53)
2458 * use 0x03 to track RPS1 interrupts - increase by 1 every gpio3 is toggled
2459 * use 0x15 to track VPE interrupts - increase by 1 every vpeirq() is called
2460 */
2461 saa7146_write(dev, EC1SSR, (0x03<<2) | 3 );
2462 /* set event counter 1 treshold to maximum allowed value (rEC p55) */
2463 saa7146_write(dev, ECT1R, 0x3fff );
2464#endif
2465 /* Set RPS1 Address register to point to RPS code (r108 p42) */
2466 saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle);
2467 /* Enable RPS1, (rFC p33) */
2468 saa7146_write(dev, MC1, (MASK_13 | MASK_29 ));
2469
2470 mdelay(10);
2471 /* now send VSYNC_B to rps1 by rising GPIO3 */
2472 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI);
2473 mdelay(10);
2474 /* if rps1 responded by lowering the GPIO3,
2475 * then we have budgetpatch hardware
2476 */
2477 if ((saa7146_read(dev, GPIO_CTRL) & 0x10000000) == 0) {
2478 budgetpatch = 1;
2479 printk("dvb-ttpci: BUDGET-PATCH DETECTED.\n");
2480 }
2481 /* Disable RPS1 */
2482 saa7146_write(dev, MC1, ( MASK_29 ));
2483#if RPS_IRQ
2484 printk("dvb-ttpci: Event Counter 1 0x%04x\n", saa7146_read(dev, EC1R) & 0x3fff );
2485#endif
2486 }
2487
2488 /* prepare the av7110 device struct */
Panagiotis Issaris74081872006-01-11 19:40:56 -02002489 av7110 = kzalloc(sizeof(struct av7110), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002490 if (!av7110) {
2491 dprintk(1, "out of memory\n");
2492 return -ENOMEM;
2493 }
2494
Linus Torvalds1da177e2005-04-16 15:20:36 -07002495 av7110->card_name = (char*) pci_ext->ext_priv;
2496 av7110->dev = dev;
2497 dev->ext_priv = av7110;
2498
2499 ret = get_firmware(av7110);
2500 if (ret < 0)
2501 goto err_kfree_0;
2502
2503 ret = dvb_register_adapter(&av7110->dvb_adapter, av7110->card_name,
2504 THIS_MODULE);
2505 if (ret < 0)
2506 goto err_put_firmware_1;
2507
2508 /* the Siemens DVB needs this if you want to have the i2c chips
2509 get recognized before the main driver is fully loaded */
2510 saa7146_write(dev, GPIO_CTRL, 0x500000);
2511
2512#ifdef I2C_ADAP_CLASS_TV_DIGITAL
2513 av7110->i2c_adap.class = I2C_ADAP_CLASS_TV_DIGITAL;
2514#else
2515 av7110->i2c_adap.class = I2C_CLASS_TV_DIGITAL;
2516#endif
2517 strlcpy(av7110->i2c_adap.name, pci_ext->ext_priv, sizeof(av7110->i2c_adap.name));
2518
2519 saa7146_i2c_adapter_prepare(dev, &av7110->i2c_adap, SAA7146_I2C_BUS_BIT_RATE_120); /* 275 kHz */
2520
2521 ret = i2c_add_adapter(&av7110->i2c_adap);
2522 if (ret < 0)
2523 goto err_dvb_unregister_adapter_2;
2524
2525 ttpci_eeprom_parse_mac(&av7110->i2c_adap,
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07002526 av7110->dvb_adapter.proposed_mac);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002527 ret = -ENOMEM;
2528
2529 if (budgetpatch) {
2530 spin_lock_init(&av7110->feedlock1);
2531 av7110->grabbing = saa7146_vmalloc_build_pgtable(pdev, length,
2532 &av7110->pt);
2533 if (!av7110->grabbing)
2534 goto err_i2c_del_3;
2535
2536 saa7146_write(dev, PCI_BT_V1, 0x1c1f101f);
2537 saa7146_write(dev, BCS_CTRL, 0x80400040);
2538 /* set dd1 stream a & b */
2539 saa7146_write(dev, DD1_STREAM_B, 0x00000000);
2540 saa7146_write(dev, DD1_INIT, 0x03000200);
2541 saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
2542 saa7146_write(dev, BRS_CTRL, 0x60000000);
2543 saa7146_write(dev, BASE_ODD3, 0);
2544 saa7146_write(dev, BASE_EVEN3, 0);
2545 saa7146_write(dev, PROT_ADDR3, TS_WIDTH * TS_HEIGHT);
2546 saa7146_write(dev, BASE_PAGE3, av7110->pt.dma | ME1 | 0x90);
2547
2548 saa7146_write(dev, PITCH3, TS_WIDTH);
2549 saa7146_write(dev, NUM_LINE_BYTE3, (TS_HEIGHT << 16) | TS_WIDTH);
2550
2551 /* upload all */
2552 saa7146_write(dev, MC2, 0x077c077c);
2553 saa7146_write(dev, GPIO_CTRL, 0x000000);
2554#if RPS_IRQ
2555 /* set event counter 1 source as RPS1 interrupt (0x03) (rE4 p53)
2556 * use 0x03 to track RPS1 interrupts - increase by 1 every gpio3 is toggled
2557 * use 0x15 to track VPE interrupts - increase by 1 every vpeirq() is called
2558 */
2559 saa7146_write(dev, EC1SSR, (0x03<<2) | 3 );
2560 /* set event counter 1 treshold to maximum allowed value (rEC p55) */
2561 saa7146_write(dev, ECT1R, 0x3fff );
2562#endif
2563 /* Setup BUDGETPATCH MAIN RPS1 "program" (p35) */
2564 count = 0;
2565
2566 /* Wait Source Line Counter Threshold (p36) */
2567 WRITE_RPS1(cpu_to_le32(CMD_PAUSE | EVT_HS));
2568 /* Set GPIO3=1 (p42) */
2569 WRITE_RPS1(cpu_to_le32(CMD_WR_REG_MASK | (GPIO_CTRL>>2)));
2570 WRITE_RPS1(cpu_to_le32(GPIO3_MSK));
2571 WRITE_RPS1(cpu_to_le32(SAA7146_GPIO_OUTHI<<24));
2572#if RPS_IRQ
2573 /* issue RPS1 interrupt */
2574 WRITE_RPS1(cpu_to_le32(CMD_INTERRUPT));
2575#endif
2576 /* Wait reset Source Line Counter Threshold (p36) */
2577 WRITE_RPS1(cpu_to_le32(CMD_PAUSE | RPS_INV | EVT_HS));
2578 /* Set GPIO3=0 (p42) */
2579 WRITE_RPS1(cpu_to_le32(CMD_WR_REG_MASK | (GPIO_CTRL>>2)));
2580 WRITE_RPS1(cpu_to_le32(GPIO3_MSK));
2581 WRITE_RPS1(cpu_to_le32(SAA7146_GPIO_OUTLO<<24));
2582#if RPS_IRQ
2583 /* issue RPS1 interrupt */
2584 WRITE_RPS1(cpu_to_le32(CMD_INTERRUPT));
2585#endif
2586 /* Jump to begin of RPS program (p37) */
2587 WRITE_RPS1(cpu_to_le32(CMD_JUMP));
2588 WRITE_RPS1(cpu_to_le32(dev->d_rps1.dma_handle));
2589
2590 /* Fix VSYNC level */
2591 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
2592 /* Set RPS1 Address register to point to RPS code (r108 p42) */
2593 saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle);
2594 /* Set Source Line Counter Threshold, using BRS (rCC p43)
2595 * It generates HS event every TS_HEIGHT lines
2596 * this is related to TS_WIDTH set in register
2597 * NUM_LINE_BYTE3. If NUM_LINE_BYTE low 16 bits
2598 * are set to TS_WIDTH bytes (TS_WIDTH=2*188),
2599 * then RPS_THRESH1 should be set to trigger
2600 * every TS_HEIGHT (512) lines.
2601 */
2602 saa7146_write(dev, RPS_THRESH1, (TS_HEIGHT*1) | MASK_12 );
2603
2604 /* Enable RPS1 (rFC p33) */
2605 saa7146_write(dev, MC1, (MASK_13 | MASK_29));
2606
2607 /* end of budgetpatch register initialization */
2608 tasklet_init (&av7110->vpe_tasklet, vpeirq, (unsigned long) av7110);
2609 } else {
2610 saa7146_write(dev, PCI_BT_V1, 0x1c00101f);
2611 saa7146_write(dev, BCS_CTRL, 0x80400040);
2612
2613 /* set dd1 stream a & b */
2614 saa7146_write(dev, DD1_STREAM_B, 0x00000000);
2615 saa7146_write(dev, DD1_INIT, 0x03000000);
2616 saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
2617
2618 /* upload all */
2619 saa7146_write(dev, MC2, 0x077c077c);
2620 saa7146_write(dev, GPIO_CTRL, 0x000000);
2621 }
2622
2623 tasklet_init (&av7110->debi_tasklet, debiirq, (unsigned long) av7110);
2624 tasklet_init (&av7110->gpio_tasklet, gpioirq, (unsigned long) av7110);
2625
Ingo Molnar3593cab2006-02-07 06:49:14 -02002626 mutex_init(&av7110->pid_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002627
2628 /* locks for data transfers from/to AV7110 */
2629 spin_lock_init(&av7110->debilock);
Ingo Molnar3593cab2006-02-07 06:49:14 -02002630 mutex_init(&av7110->dcomlock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002631 av7110->debitype = -1;
2632
2633 /* default OSD window */
2634 av7110->osdwin = 1;
Ingo Molnar3593cab2006-02-07 06:49:14 -02002635 mutex_init(&av7110->osd_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002636
2637 /* ARM "watchdog" */
2638 init_waitqueue_head(&av7110->arm_wait);
2639 av7110->arm_thread = NULL;
2640
2641 /* allocate and init buffers */
2642 av7110->debi_virt = pci_alloc_consistent(pdev, 8192, &av7110->debi_bus);
2643 if (!av7110->debi_virt)
2644 goto err_saa71466_vfree_4;
2645
2646
2647 av7110->iobuf = vmalloc(AVOUTLEN+AOUTLEN+BMPLEN+4*IPACKS);
2648 if (!av7110->iobuf)
2649 goto err_pci_free_5;
2650
2651 ret = av7110_av_init(av7110);
2652 if (ret < 0)
2653 goto err_iobuf_vfree_6;
2654
2655 /* init BMP buffer */
2656 av7110->bmpbuf = av7110->iobuf+AVOUTLEN+AOUTLEN;
2657 init_waitqueue_head(&av7110->bmpq);
2658
2659 ret = av7110_ca_init(av7110);
2660 if (ret < 0)
2661 goto err_av7110_av_exit_7;
2662
2663 /* load firmware into AV7110 cards */
2664 ret = av7110_bootarm(av7110);
2665 if (ret < 0)
2666 goto err_av7110_ca_exit_8;
2667
2668 ret = av7110_firmversion(av7110);
2669 if (ret < 0)
2670 goto err_stop_arm_9;
2671
2672 if (FW_VERSION(av7110->arm_app)<0x2501)
2673 printk ("dvb-ttpci: Warning, firmware version 0x%04x is too old. "
2674 "System might be unstable!\n", FW_VERSION(av7110->arm_app));
2675
2676 ret = kernel_thread(arm_thread, (void *) av7110, 0);
2677 if (ret < 0)
2678 goto err_stop_arm_9;
2679
2680 /* set initial volume in mixer struct */
2681 av7110->mixer.volume_left = volume;
2682 av7110->mixer.volume_right = volume;
2683
2684 init_av7110_av(av7110);
2685
2686 ret = av7110_register(av7110);
2687 if (ret < 0)
2688 goto err_arm_thread_stop_10;
2689
2690 /* special case DVB-C: these cards have an analog tuner
2691 plus need some special handling, so we have separate
2692 saa7146_ext_vv data for these... */
2693 ret = av7110_init_v4l(av7110);
2694 if (ret < 0)
2695 goto err_av7110_unregister_11;
2696
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07002697 av7110->dvb_adapter.priv = av7110;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002698 ret = frontend_init(av7110);
2699 if (ret < 0)
2700 goto err_av7110_exit_v4l_12;
2701
2702#if defined(CONFIG_INPUT_EVDEV) || defined(CONFIG_INPUT_EVDEV_MODULE)
Oliver Endriss03388ae2005-09-09 13:03:12 -07002703 av7110_ir_init(av7110);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002704#endif
2705 printk(KERN_INFO "dvb-ttpci: found av7110-%d.\n", av7110_num);
2706 av7110_num++;
2707out:
2708 return ret;
2709
2710err_av7110_exit_v4l_12:
2711 av7110_exit_v4l(av7110);
2712err_av7110_unregister_11:
2713 dvb_unregister(av7110);
2714err_arm_thread_stop_10:
2715 av7110_arm_sync(av7110);
2716err_stop_arm_9:
2717 /* Nothing to do. Rejoice. */
2718err_av7110_ca_exit_8:
2719 av7110_ca_exit(av7110);
2720err_av7110_av_exit_7:
2721 av7110_av_exit(av7110);
2722err_iobuf_vfree_6:
2723 vfree(av7110->iobuf);
2724err_pci_free_5:
2725 pci_free_consistent(pdev, 8192, av7110->debi_virt, av7110->debi_bus);
2726err_saa71466_vfree_4:
2727 if (!av7110->grabbing)
2728 saa7146_pgtable_free(pdev, &av7110->pt);
2729err_i2c_del_3:
2730 i2c_del_adapter(&av7110->i2c_adap);
2731err_dvb_unregister_adapter_2:
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07002732 dvb_unregister_adapter(&av7110->dvb_adapter);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002733err_put_firmware_1:
2734 put_firmware(av7110);
2735err_kfree_0:
2736 kfree(av7110);
2737 goto out;
2738}
2739
Johannes Stezenbach1be11e32006-02-27 00:09:20 -03002740static int __devexit av7110_detach(struct saa7146_dev* saa)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002741{
2742 struct av7110 *av7110 = saa->ext_priv;
2743 dprintk(4, "%p\n", av7110);
2744
Oliver Endriss03388ae2005-09-09 13:03:12 -07002745#if defined(CONFIG_INPUT_EVDEV) || defined(CONFIG_INPUT_EVDEV_MODULE)
2746 av7110_ir_exit(av7110);
2747#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07002748 if (budgetpatch) {
2749 /* Disable RPS1 */
2750 saa7146_write(saa, MC1, MASK_29);
2751 /* VSYNC LOW (inactive) */
2752 saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO);
2753 saa7146_write(saa, MC1, MASK_20); /* DMA3 off */
2754 SAA7146_IER_DISABLE(saa, MASK_10);
2755 SAA7146_ISR_CLEAR(saa, MASK_10);
2756 msleep(50);
2757 tasklet_kill(&av7110->vpe_tasklet);
2758 saa7146_pgtable_free(saa->pci, &av7110->pt);
2759 }
2760 av7110_exit_v4l(av7110);
2761
2762 av7110_arm_sync(av7110);
2763
2764 tasklet_kill(&av7110->debi_tasklet);
2765 tasklet_kill(&av7110->gpio_tasklet);
2766
2767 dvb_unregister(av7110);
2768
2769 SAA7146_IER_DISABLE(saa, MASK_19 | MASK_03);
2770 SAA7146_ISR_CLEAR(saa, MASK_19 | MASK_03);
2771
2772 av7110_ca_exit(av7110);
2773 av7110_av_exit(av7110);
2774
2775 vfree(av7110->iobuf);
2776 pci_free_consistent(saa->pci, 8192, av7110->debi_virt,
2777 av7110->debi_bus);
2778
2779 i2c_del_adapter(&av7110->i2c_adap);
2780
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07002781 dvb_unregister_adapter (&av7110->dvb_adapter);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002782
2783 av7110_num--;
2784
2785 put_firmware(av7110);
2786
2787 kfree(av7110);
2788
2789 saa->ext_priv = NULL;
2790
2791 return 0;
2792}
2793
2794
2795static void av7110_irq(struct saa7146_dev* dev, u32 *isr)
2796{
2797 struct av7110 *av7110 = dev->ext_priv;
2798
2799 //print_time("av7110_irq");
2800
2801 /* Note: Don't try to handle the DEBI error irq (MASK_18), in
2802 * intel mode the timeout is asserted all the time...
2803 */
2804
2805 if (*isr & MASK_19) {
2806 //printk("av7110_irq: DEBI\n");
2807 /* Note 1: The DEBI irq is level triggered: We must enable it
2808 * only after we started a DMA xfer, and disable it here
2809 * immediately, or it will be signalled all the time while
2810 * DEBI is idle.
2811 * Note 2: You would think that an irq which is masked is
2812 * not signalled by the hardware. Not so for the SAA7146:
2813 * An irq is signalled as long as the corresponding bit
2814 * in the ISR is set, and disabling irqs just prevents the
2815 * hardware from setting the ISR bit. This means a) that we
2816 * must clear the ISR *after* disabling the irq (which is why
2817 * we must do it here even though saa7146_core did it already),
2818 * and b) that if we were to disable an edge triggered irq
2819 * (like the gpio irqs sadly are) temporarily we would likely
2820 * loose some. This sucks :-(
2821 */
2822 SAA7146_IER_DISABLE(av7110->dev, MASK_19);
2823 SAA7146_ISR_CLEAR(av7110->dev, MASK_19);
2824 tasklet_schedule(&av7110->debi_tasklet);
2825 }
2826
2827 if (*isr & MASK_03) {
2828 //printk("av7110_irq: GPIO\n");
2829 tasklet_schedule(&av7110->gpio_tasklet);
2830 }
2831
2832 if ((*isr & MASK_10) && budgetpatch)
2833 tasklet_schedule(&av7110->vpe_tasklet);
2834}
2835
2836
2837static struct saa7146_extension av7110_extension;
2838
2839#define MAKE_AV7110_INFO(x_var,x_name) \
2840static struct saa7146_pci_extension_data x_var = { \
2841 .ext_priv = x_name, \
2842 .ext = &av7110_extension }
2843
Karl Herz6af4ee12005-09-09 13:03:13 -07002844MAKE_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 -07002845MAKE_AV7110_INFO(ttt_1_X, "Technotrend/Hauppauge WinTV DVB-T rev1.X");
2846MAKE_AV7110_INFO(ttc_1_X, "Technotrend/Hauppauge WinTV Nexus-CA rev1.X");
2847MAKE_AV7110_INFO(ttc_2_X, "Technotrend/Hauppauge WinTV DVB-C rev2.X");
2848MAKE_AV7110_INFO(tts_2_X, "Technotrend/Hauppauge WinTV Nexus-S rev2.X");
Johannes Stezenbach3dfaebd2005-05-16 21:54:19 -07002849MAKE_AV7110_INFO(tts_2_3, "Technotrend/Hauppauge WinTV Nexus-S rev2.3");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002850MAKE_AV7110_INFO(tts_1_3se, "Technotrend/Hauppauge WinTV DVB-S rev1.3 SE");
2851MAKE_AV7110_INFO(ttt, "Technotrend/Hauppauge DVB-T");
2852MAKE_AV7110_INFO(fsc, "Fujitsu Siemens DVB-C");
2853MAKE_AV7110_INFO(fss, "Fujitsu Siemens DVB-S rev1.6");
Oliver Endriss8bd63012006-02-07 06:49:11 -02002854MAKE_AV7110_INFO(gxs_1_3, "Galaxis DVB-S rev1.3");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002855
2856static struct pci_device_id pci_tbl[] = {
Karl Herz6af4ee12005-09-09 13:03:13 -07002857 MAKE_EXTENSION_PCI(fsc, 0x110a, 0x0000),
2858 MAKE_EXTENSION_PCI(tts_1_X_fsc, 0x13c2, 0x0000),
2859 MAKE_EXTENSION_PCI(ttt_1_X, 0x13c2, 0x0001),
2860 MAKE_EXTENSION_PCI(ttc_2_X, 0x13c2, 0x0002),
2861 MAKE_EXTENSION_PCI(tts_2_X, 0x13c2, 0x0003),
Oliver Endriss8bd63012006-02-07 06:49:11 -02002862 MAKE_EXTENSION_PCI(gxs_1_3, 0x13c2, 0x0004),
Karl Herz6af4ee12005-09-09 13:03:13 -07002863 MAKE_EXTENSION_PCI(fss, 0x13c2, 0x0006),
2864 MAKE_EXTENSION_PCI(ttt, 0x13c2, 0x0008),
2865 MAKE_EXTENSION_PCI(ttc_1_X, 0x13c2, 0x000a),
2866 MAKE_EXTENSION_PCI(tts_2_3, 0x13c2, 0x000e),
2867 MAKE_EXTENSION_PCI(tts_1_3se, 0x13c2, 0x1002),
Linus Torvalds1da177e2005-04-16 15:20:36 -07002868
Linus Torvalds1da177e2005-04-16 15:20:36 -07002869/* MAKE_EXTENSION_PCI(???, 0x13c2, 0x0005), UNDEFINED CARD */ // Technisat SkyStar1
2870/* MAKE_EXTENSION_PCI(???, 0x13c2, 0x0009), UNDEFINED CARD */ // TT/Hauppauge WinTV Nexus-CA v????
2871
2872 {
2873 .vendor = 0,
2874 }
2875};
2876
2877MODULE_DEVICE_TABLE(pci, pci_tbl);
2878
2879
2880static struct saa7146_extension av7110_extension = {
2881 .name = "dvb\0",
2882 .flags = SAA7146_I2C_SHORT_DELAY,
2883
2884 .module = THIS_MODULE,
2885 .pci_tbl = &pci_tbl[0],
2886 .attach = av7110_attach,
Johannes Stezenbach1be11e32006-02-27 00:09:20 -03002887 .detach = __devexit_p(av7110_detach),
Linus Torvalds1da177e2005-04-16 15:20:36 -07002888
2889 .irq_mask = MASK_19 | MASK_03 | MASK_10,
2890 .irq_func = av7110_irq,
2891};
2892
2893
2894static int __init av7110_init(void)
2895{
2896 int retval;
2897 retval = saa7146_register_extension(&av7110_extension);
2898 return retval;
2899}
2900
2901
2902static void __exit av7110_exit(void)
2903{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002904 saa7146_unregister_extension(&av7110_extension);
2905}
2906
2907module_init(av7110_init);
2908module_exit(av7110_exit);
2909
2910MODULE_DESCRIPTION("driver for the SAA7146 based AV110 PCI DVB cards by "
2911 "Siemens, Technotrend, Hauppauge");
2912MODULE_AUTHOR("Ralph Metzler, Marcus Metzler, others");
2913MODULE_LICENSE("GPL");