blob: 7497b1e8d883f4a6649b8b25f45766f6c2f4ab02 [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... */
Eric Sesterhennae246012006-03-13 13:17:11 -03001093 BUG_ON(!demux);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001094 dvbdemux = (struct dvb_demux *) demux->priv;
Eric Sesterhennae246012006-03-13 13:17:11 -03001095 BUG_ON(!dvbdemux);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001096 av7110 = (struct av7110 *) dvbdemux->priv;
1097
1098 dprintk(4, "%p\n", av7110);
1099
1100 if (num != 0)
1101 return -EINVAL;
1102
1103 ret = av7110_fw_request(av7110, &tag, 0, fwstc, 4);
1104 if (ret) {
1105 printk(KERN_ERR "%s: av7110_fw_request error\n", __FUNCTION__);
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001106 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001107 }
1108 dprintk(2, "fwstc = %04hx %04hx %04hx %04hx\n",
1109 fwstc[0], fwstc[1], fwstc[2], fwstc[3]);
1110
1111 *stc = (((uint64_t) ((fwstc[3] & 0x8000) >> 15)) << 32) |
1112 (((uint64_t) fwstc[1]) << 16) | ((uint64_t) fwstc[0]);
1113 *base = 1;
1114
1115 dprintk(4, "stc = %lu\n", (unsigned long)*stc);
1116
1117 return 0;
1118}
1119
1120
1121/******************************************************************************
1122 * SEC device file operations
1123 ******************************************************************************/
1124
1125
1126static int av7110_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
1127{
1128 struct av7110* av7110 = (struct av7110*) fe->dvb->priv;
1129
1130 switch (tone) {
1131 case SEC_TONE_ON:
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001132 return Set22K(av7110, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001133
1134 case SEC_TONE_OFF:
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001135 return Set22K(av7110, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001136
1137 default:
1138 return -EINVAL;
1139 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001140}
1141
1142static int av7110_diseqc_send_master_cmd(struct dvb_frontend* fe,
1143 struct dvb_diseqc_master_cmd* cmd)
1144{
1145 struct av7110* av7110 = fe->dvb->priv;
1146
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001147 return av7110_diseqc_send(av7110, cmd->msg_len, cmd->msg, -1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001148}
1149
1150static int av7110_diseqc_send_burst(struct dvb_frontend* fe,
1151 fe_sec_mini_cmd_t minicmd)
1152{
1153 struct av7110* av7110 = fe->dvb->priv;
1154
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001155 return av7110_diseqc_send(av7110, 0, NULL, minicmd);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001156}
1157
1158/* simplified code from budget-core.c */
1159static int stop_ts_capture(struct av7110 *budget)
1160{
1161 dprintk(2, "budget: %p\n", budget);
1162
1163 if (--budget->feeding1)
1164 return budget->feeding1;
1165 saa7146_write(budget->dev, MC1, MASK_20); /* DMA3 off */
1166 SAA7146_IER_DISABLE(budget->dev, MASK_10);
1167 SAA7146_ISR_CLEAR(budget->dev, MASK_10);
1168 return 0;
1169}
1170
1171static int start_ts_capture(struct av7110 *budget)
1172{
1173 dprintk(2, "budget: %p\n", budget);
1174
1175 if (budget->feeding1)
1176 return ++budget->feeding1;
1177 memset(budget->grabbing, 0x00, TS_HEIGHT * TS_WIDTH);
1178 budget->tsf = 0xff;
1179 budget->ttbp = 0;
1180 SAA7146_IER_ENABLE(budget->dev, MASK_10); /* VPE */
1181 saa7146_write(budget->dev, MC1, (MASK_04 | MASK_20)); /* DMA3 on */
1182 return ++budget->feeding1;
1183}
1184
1185static int budget_start_feed(struct dvb_demux_feed *feed)
1186{
1187 struct dvb_demux *demux = feed->demux;
1188 struct av7110 *budget = (struct av7110 *) demux->priv;
1189 int status;
1190
1191 dprintk(2, "av7110: %p\n", budget);
1192
1193 spin_lock(&budget->feedlock1);
1194 feed->pusi_seen = 0; /* have a clean section start */
1195 status = start_ts_capture(budget);
1196 spin_unlock(&budget->feedlock1);
1197 return status;
1198}
1199
1200static int budget_stop_feed(struct dvb_demux_feed *feed)
1201{
1202 struct dvb_demux *demux = feed->demux;
1203 struct av7110 *budget = (struct av7110 *) demux->priv;
1204 int status;
1205
1206 dprintk(2, "budget: %p\n", budget);
1207
1208 spin_lock(&budget->feedlock1);
1209 status = stop_ts_capture(budget);
1210 spin_unlock(&budget->feedlock1);
1211 return status;
1212}
1213
1214static void vpeirq(unsigned long data)
1215{
1216 struct av7110 *budget = (struct av7110 *) data;
1217 u8 *mem = (u8 *) (budget->grabbing);
1218 u32 olddma = budget->ttbp;
1219 u32 newdma = saa7146_read(budget->dev, PCI_VDP3);
1220
1221 if (!budgetpatch) {
1222 printk("av7110.c: vpeirq() called while budgetpatch disabled!"
1223 " check saa7146 IER register\n");
1224 BUG();
1225 }
1226 /* nearest lower position divisible by 188 */
1227 newdma -= newdma % 188;
1228
1229 if (newdma >= TS_BUFLEN)
1230 return;
1231
1232 budget->ttbp = newdma;
1233
1234 if (!budget->feeding1 || (newdma == olddma))
1235 return;
1236
1237#if 0
1238 /* track rps1 activity */
1239 printk("vpeirq: %02x Event Counter 1 0x%04x\n",
1240 mem[olddma],
1241 saa7146_read(budget->dev, EC1R) & 0x3fff);
1242#endif
1243
1244 if (newdma > olddma)
1245 /* no wraparound, dump olddma..newdma */
1246 dvb_dmx_swfilter_packets(&budget->demux1, mem + olddma, (newdma - olddma) / 188);
1247 else {
1248 /* wraparound, dump olddma..buflen and 0..newdma */
1249 dvb_dmx_swfilter_packets(&budget->demux1, mem + olddma, (TS_BUFLEN - olddma) / 188);
1250 dvb_dmx_swfilter_packets(&budget->demux1, mem, newdma / 188);
1251 }
1252}
1253
1254static int av7110_register(struct av7110 *av7110)
1255{
1256 int ret, i;
1257 struct dvb_demux *dvbdemux = &av7110->demux;
1258 struct dvb_demux *dvbdemux1 = &av7110->demux1;
1259
1260 dprintk(4, "%p\n", av7110);
1261
1262 if (av7110->registered)
1263 return -1;
1264
1265 av7110->registered = 1;
1266
1267 dvbdemux->priv = (void *) av7110;
1268
1269 for (i = 0; i < 32; i++)
1270 av7110->handle2filter[i] = NULL;
1271
1272 dvbdemux->filternum = 32;
1273 dvbdemux->feednum = 32;
1274 dvbdemux->start_feed = av7110_start_feed;
1275 dvbdemux->stop_feed = av7110_stop_feed;
1276 dvbdemux->write_to_decoder = av7110_write_to_decoder;
1277 dvbdemux->dmx.capabilities = (DMX_TS_FILTERING | DMX_SECTION_FILTERING |
1278 DMX_MEMORY_BASED_FILTERING);
1279
1280 dvb_dmx_init(&av7110->demux);
1281 av7110->demux.dmx.get_stc = dvb_get_stc;
1282
1283 av7110->dmxdev.filternum = 32;
1284 av7110->dmxdev.demux = &dvbdemux->dmx;
1285 av7110->dmxdev.capabilities = 0;
1286
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001287 dvb_dmxdev_init(&av7110->dmxdev, &av7110->dvb_adapter);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001288
1289 av7110->hw_frontend.source = DMX_FRONTEND_0;
1290
1291 ret = dvbdemux->dmx.add_frontend(&dvbdemux->dmx, &av7110->hw_frontend);
1292
1293 if (ret < 0)
1294 return ret;
1295
1296 av7110->mem_frontend.source = DMX_MEMORY_FE;
1297
1298 ret = dvbdemux->dmx.add_frontend(&dvbdemux->dmx, &av7110->mem_frontend);
1299
1300 if (ret < 0)
1301 return ret;
1302
1303 ret = dvbdemux->dmx.connect_frontend(&dvbdemux->dmx,
1304 &av7110->hw_frontend);
1305 if (ret < 0)
1306 return ret;
1307
1308 av7110_av_register(av7110);
1309 av7110_ca_register(av7110);
1310
1311#ifdef CONFIG_DVB_AV7110_OSD
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001312 dvb_register_device(&av7110->dvb_adapter, &av7110->osd_dev,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001313 &dvbdev_osd, av7110, DVB_DEVICE_OSD);
1314#endif
1315
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001316 dvb_net_init(&av7110->dvb_adapter, &av7110->dvb_net, &dvbdemux->dmx);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001317
1318 if (budgetpatch) {
1319 /* initialize software demux1 without its own frontend
1320 * demux1 hardware is connected to frontend0 of demux0
1321 */
1322 dvbdemux1->priv = (void *) av7110;
1323
1324 dvbdemux1->filternum = 256;
1325 dvbdemux1->feednum = 256;
1326 dvbdemux1->start_feed = budget_start_feed;
1327 dvbdemux1->stop_feed = budget_stop_feed;
1328 dvbdemux1->write_to_decoder = NULL;
1329
1330 dvbdemux1->dmx.capabilities = (DMX_TS_FILTERING | DMX_SECTION_FILTERING |
1331 DMX_MEMORY_BASED_FILTERING);
1332
1333 dvb_dmx_init(&av7110->demux1);
1334
1335 av7110->dmxdev1.filternum = 256;
1336 av7110->dmxdev1.demux = &dvbdemux1->dmx;
1337 av7110->dmxdev1.capabilities = 0;
1338
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001339 dvb_dmxdev_init(&av7110->dmxdev1, &av7110->dvb_adapter);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001340
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001341 dvb_net_init(&av7110->dvb_adapter, &av7110->dvb_net1, &dvbdemux1->dmx);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001342 printk("dvb-ttpci: additional demux1 for budget-patch registered\n");
1343 }
1344 return 0;
1345}
1346
1347
1348static void dvb_unregister(struct av7110 *av7110)
1349{
1350 struct dvb_demux *dvbdemux = &av7110->demux;
1351 struct dvb_demux *dvbdemux1 = &av7110->demux1;
1352
1353 dprintk(4, "%p\n", av7110);
1354
1355 if (!av7110->registered)
1356 return;
1357
1358 if (budgetpatch) {
1359 dvb_net_release(&av7110->dvb_net1);
1360 dvbdemux->dmx.close(&dvbdemux1->dmx);
1361 dvb_dmxdev_release(&av7110->dmxdev1);
1362 dvb_dmx_release(&av7110->demux1);
1363 }
1364
1365 dvb_net_release(&av7110->dvb_net);
1366
1367 dvbdemux->dmx.close(&dvbdemux->dmx);
1368 dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, &av7110->hw_frontend);
1369 dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, &av7110->mem_frontend);
1370
1371 dvb_dmxdev_release(&av7110->dmxdev);
1372 dvb_dmx_release(&av7110->demux);
1373
1374 if (av7110->fe != NULL)
1375 dvb_unregister_frontend(av7110->fe);
1376 dvb_unregister_device(av7110->osd_dev);
1377 av7110_av_unregister(av7110);
1378 av7110_ca_unregister(av7110);
1379}
1380
1381
1382/****************************************************************************
1383 * I2C client commands
1384 ****************************************************************************/
1385
1386int i2c_writereg(struct av7110 *av7110, u8 id, u8 reg, u8 val)
1387{
1388 u8 msg[2] = { reg, val };
1389 struct i2c_msg msgs;
1390
1391 msgs.flags = 0;
1392 msgs.addr = id / 2;
1393 msgs.len = 2;
1394 msgs.buf = msg;
1395 return i2c_transfer(&av7110->i2c_adap, &msgs, 1);
1396}
1397
1398#if 0
1399u8 i2c_readreg(struct av7110 *av7110, u8 id, u8 reg)
1400{
1401 u8 mm1[] = {0x00};
1402 u8 mm2[] = {0x00};
1403 struct i2c_msg msgs[2];
1404
1405 msgs[0].flags = 0;
1406 msgs[1].flags = I2C_M_RD;
1407 msgs[0].addr = msgs[1].addr = id / 2;
1408 mm1[0] = reg;
1409 msgs[0].len = 1; msgs[1].len = 1;
1410 msgs[0].buf = mm1; msgs[1].buf = mm2;
1411 i2c_transfer(&av7110->i2c_adap, msgs, 2);
1412
1413 return mm2[0];
1414}
1415#endif
1416
1417/****************************************************************************
1418 * INITIALIZATION
1419 ****************************************************************************/
1420
1421
1422static int check_firmware(struct av7110* av7110)
1423{
1424 u32 crc = 0, len = 0;
1425 unsigned char *ptr;
1426
1427 /* check for firmware magic */
1428 ptr = av7110->bin_fw;
1429 if (ptr[0] != 'A' || ptr[1] != 'V' ||
1430 ptr[2] != 'F' || ptr[3] != 'W') {
1431 printk("dvb-ttpci: this is not an av7110 firmware\n");
1432 return -EINVAL;
1433 }
1434 ptr += 4;
1435
1436 /* check dpram file */
1437 crc = ntohl(*(u32*) ptr);
1438 ptr += 4;
1439 len = ntohl(*(u32*) ptr);
1440 ptr += 4;
1441 if (len >= 512) {
Alexey Dobriyanbe787ac2006-03-07 22:20:23 -03001442 printk("dvb-ttpci: dpram file is way too big.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001443 return -EINVAL;
1444 }
1445 if (crc != crc32_le(0, ptr, len)) {
1446 printk("dvb-ttpci: crc32 of dpram file does not match.\n");
1447 return -EINVAL;
1448 }
1449 av7110->bin_dpram = ptr;
1450 av7110->size_dpram = len;
1451 ptr += len;
1452
1453 /* check root file */
1454 crc = ntohl(*(u32*) ptr);
1455 ptr += 4;
1456 len = ntohl(*(u32*) ptr);
1457 ptr += 4;
1458
1459 if (len <= 200000 || len >= 300000 ||
1460 len > ((av7110->bin_fw + av7110->size_fw) - ptr)) {
1461 printk("dvb-ttpci: root file has strange size (%d). aborting.\n", len);
1462 return -EINVAL;
1463 }
1464 if( crc != crc32_le(0, ptr, len)) {
1465 printk("dvb-ttpci: crc32 of root file does not match.\n");
1466 return -EINVAL;
1467 }
1468 av7110->bin_root = ptr;
1469 av7110->size_root = len;
1470 return 0;
1471}
1472
1473#ifdef CONFIG_DVB_AV7110_FIRMWARE_FILE
1474#include "av7110_firm.h"
1475static void put_firmware(struct av7110* av7110)
1476{
1477 av7110->bin_fw = NULL;
1478}
1479
1480static inline int get_firmware(struct av7110* av7110)
1481{
1482 av7110->bin_fw = dvb_ttpci_fw;
1483 av7110->size_fw = sizeof(dvb_ttpci_fw);
1484 return check_firmware(av7110);
1485}
1486#else
1487static void put_firmware(struct av7110* av7110)
1488{
1489 vfree(av7110->bin_fw);
1490}
1491
1492static int get_firmware(struct av7110* av7110)
1493{
1494 int ret;
1495 const struct firmware *fw;
1496
1497 /* request the av7110 firmware, this will block until someone uploads it */
1498 ret = request_firmware(&fw, "dvb-ttpci-01.fw", &av7110->dev->pci->dev);
1499 if (ret) {
1500 if (ret == -ENOENT) {
1501 printk(KERN_ERR "dvb-ttpci: could not load firmware,"
1502 " file not found: dvb-ttpci-01.fw\n");
Ville Skytt\ä12e66f62006-01-09 15:25:38 -02001503 printk(KERN_ERR "dvb-ttpci: usually this should be in "
1504 "/usr/lib/hotplug/firmware or /lib/firmware\n");
1505 printk(KERN_ERR "dvb-ttpci: and can be downloaded from"
Linus Torvalds1da177e2005-04-16 15:20:36 -07001506 " http://www.linuxtv.org/download/dvb/firmware/\n");
1507 } else
1508 printk(KERN_ERR "dvb-ttpci: cannot request firmware"
1509 " (error %i)\n", ret);
1510 return -EINVAL;
1511 }
1512
1513 if (fw->size <= 200000) {
1514 printk("dvb-ttpci: this firmware is way too small.\n");
1515 release_firmware(fw);
1516 return -EINVAL;
1517 }
1518
1519 /* check if the firmware is available */
1520 av7110->bin_fw = (unsigned char *) vmalloc(fw->size);
1521 if (NULL == av7110->bin_fw) {
1522 dprintk(1, "out of memory\n");
1523 release_firmware(fw);
1524 return -ENOMEM;
1525 }
1526
1527 memcpy(av7110->bin_fw, fw->data, fw->size);
1528 av7110->size_fw = fw->size;
1529 if ((ret = check_firmware(av7110)))
1530 vfree(av7110->bin_fw);
1531
1532 release_firmware(fw);
1533 return ret;
1534}
1535#endif
1536
1537
1538static int alps_bsrv2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
1539{
1540 struct av7110* av7110 = (struct av7110*) fe->dvb->priv;
1541 u8 pwr = 0;
1542 u8 buf[4];
1543 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
1544 u32 div = (params->frequency + 479500) / 125;
1545
1546 if (params->frequency > 2000000) pwr = 3;
1547 else if (params->frequency > 1800000) pwr = 2;
1548 else if (params->frequency > 1600000) pwr = 1;
1549 else if (params->frequency > 1200000) pwr = 0;
1550 else if (params->frequency >= 1100000) pwr = 1;
1551 else pwr = 2;
1552
1553 buf[0] = (div >> 8) & 0x7f;
1554 buf[1] = div & 0xff;
1555 buf[2] = ((div & 0x18000) >> 10) | 0x95;
1556 buf[3] = (pwr << 6) | 0x30;
1557
Mauro Carvalho Chehab9101e622005-12-12 00:37:24 -08001558 // NOTE: since we're using a prescaler of 2, we set the
Linus Torvalds1da177e2005-04-16 15:20:36 -07001559 // divisor frequency to 62.5kHz and divide by 125 above
1560
1561 if (i2c_transfer (&av7110->i2c_adap, &msg, 1) != 1)
1562 return -EIO;
1563 return 0;
1564}
1565
1566static struct ves1x93_config alps_bsrv2_config = {
1567 .demod_address = 0x08,
1568 .xin = 90100000UL,
1569 .invert_pwm = 0,
1570 .pll_set = alps_bsrv2_pll_set,
1571};
1572
1573
1574static u8 alps_bsru6_inittab[] = {
1575 0x01, 0x15,
1576 0x02, 0x30,
1577 0x03, 0x00,
1578 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
1579 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */
1580 0x06, 0x40, /* DAC not used, set to high impendance mode */
1581 0x07, 0x00, /* DAC LSB */
1582 0x08, 0x40, /* DiSEqC off, LNB power on OP2/LOCK pin on */
1583 0x09, 0x00, /* FIFO */
1584 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
1585 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */
1586 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
1587 0x10, 0x3f, // AGC2 0x3d
1588 0x11, 0x84,
Oliver Endrissff29d062005-11-08 21:35:43 -08001589 0x12, 0xb9,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001590 0x15, 0xc9, // lock detector threshold
1591 0x16, 0x00,
1592 0x17, 0x00,
1593 0x18, 0x00,
1594 0x19, 0x00,
1595 0x1a, 0x00,
1596 0x1f, 0x50,
1597 0x20, 0x00,
1598 0x21, 0x00,
1599 0x22, 0x00,
1600 0x23, 0x00,
1601 0x28, 0x00, // out imp: normal out type: parallel FEC mode:0
1602 0x29, 0x1e, // 1/2 threshold
1603 0x2a, 0x14, // 2/3 threshold
1604 0x2b, 0x0f, // 3/4 threshold
1605 0x2c, 0x09, // 5/6 threshold
1606 0x2d, 0x05, // 7/8 threshold
1607 0x2e, 0x01,
1608 0x31, 0x1f, // test all FECs
1609 0x32, 0x19, // viterbi and synchro search
1610 0x33, 0xfc, // rs control
1611 0x34, 0x93, // error control
1612 0x0f, 0x52,
1613 0xff, 0xff
1614};
1615
1616static int alps_bsru6_set_symbol_rate(struct dvb_frontend* fe, u32 srate, u32 ratio)
1617{
1618 u8 aclk = 0;
1619 u8 bclk = 0;
1620
1621 if (srate < 1500000) { aclk = 0xb7; bclk = 0x47; }
1622 else if (srate < 3000000) { aclk = 0xb7; bclk = 0x4b; }
1623 else if (srate < 7000000) { aclk = 0xb7; bclk = 0x4f; }
1624 else if (srate < 14000000) { aclk = 0xb7; bclk = 0x53; }
1625 else if (srate < 30000000) { aclk = 0xb6; bclk = 0x53; }
1626 else if (srate < 45000000) { aclk = 0xb4; bclk = 0x51; }
1627
1628 stv0299_writereg(fe, 0x13, aclk);
1629 stv0299_writereg(fe, 0x14, bclk);
1630 stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
1631 stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
1632 stv0299_writereg(fe, 0x21, (ratio ) & 0xf0);
1633
1634 return 0;
1635}
1636
Andreas Oberrittercfbfce12005-09-09 13:02:30 -07001637static 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 -07001638{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001639 int ret;
1640 u8 data[4];
1641 u32 div;
1642 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
1643
1644 if ((params->frequency < 950000) || (params->frequency > 2150000))
1645 return -EINVAL;
1646
1647 div = (params->frequency + (125 - 1)) / 125; // round correctly
1648 data[0] = (div >> 8) & 0x7f;
1649 data[1] = div & 0xff;
1650 data[2] = 0x80 | ((div & 0x18000) >> 10) | 4;
1651 data[3] = 0xC4;
1652
1653 if (params->frequency > 1530000) data[3] = 0xc0;
1654
Andreas Oberrittercfbfce12005-09-09 13:02:30 -07001655 ret = i2c_transfer(i2c, &msg, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001656 if (ret != 1)
1657 return -EIO;
1658 return 0;
1659}
1660
1661static struct stv0299_config alps_bsru6_config = {
1662
1663 .demod_address = 0x68,
1664 .inittab = alps_bsru6_inittab,
1665 .mclk = 88000000UL,
1666 .invert = 1,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001667 .skip_reinit = 0,
1668 .lock_output = STV0229_LOCKOUTPUT_1,
1669 .volt13_op0_op1 = STV0299_VOLT13_OP1,
1670 .min_delay_ms = 100,
1671 .set_symbol_rate = alps_bsru6_set_symbol_rate,
1672 .pll_set = alps_bsru6_pll_set,
1673};
1674
1675
Linus Torvalds1da177e2005-04-16 15:20:36 -07001676static int alps_tdbe2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
1677{
1678 struct av7110* av7110 = fe->dvb->priv;
1679 u32 div;
1680 u8 data[4];
1681 struct i2c_msg msg = { .addr = 0x62, .flags = 0, .buf = data, .len = sizeof(data) };
1682
1683 div = (params->frequency + 35937500 + 31250) / 62500;
1684
1685 data[0] = (div >> 8) & 0x7f;
1686 data[1] = div & 0xff;
1687 data[2] = 0x85 | ((div >> 10) & 0x60);
1688 data[3] = (params->frequency < 174000000 ? 0x88 : params->frequency < 470000000 ? 0x84 : 0x81);
1689
1690 if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1)
1691 return -EIO;
1692 return 0;
1693}
1694
1695static struct ves1820_config alps_tdbe2_config = {
1696 .demod_address = 0x09,
1697 .xin = 57840000UL,
1698 .invert = 1,
1699 .selagc = VES1820_SELAGC_SIGNAMPERR,
1700 .pll_set = alps_tdbe2_pll_set,
1701};
1702
1703
1704
1705
1706static int grundig_29504_451_pll_set(struct dvb_frontend* fe,
1707 struct dvb_frontend_parameters* params)
1708{
1709 struct av7110* av7110 = fe->dvb->priv;
1710 u32 div;
1711 u8 data[4];
1712 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
1713
1714 div = params->frequency / 125;
1715 data[0] = (div >> 8) & 0x7f;
1716 data[1] = div & 0xff;
1717 data[2] = 0x8e;
1718 data[3] = 0x00;
1719
1720 if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1)
1721 return -EIO;
1722 return 0;
1723}
1724
1725static struct tda8083_config grundig_29504_451_config = {
1726 .demod_address = 0x68,
1727 .pll_set = grundig_29504_451_pll_set,
1728};
1729
1730
1731
1732static int philips_cd1516_pll_set(struct dvb_frontend* fe,
1733 struct dvb_frontend_parameters* params)
1734{
Mauro Carvalho Chehab9101e622005-12-12 00:37:24 -08001735 struct av7110* av7110 = fe->dvb->priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001736 u32 div;
1737 u32 f = params->frequency;
1738 u8 data[4];
1739 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
1740
1741 div = (f + 36125000 + 31250) / 62500;
1742
1743 data[0] = (div >> 8) & 0x7f;
1744 data[1] = div & 0xff;
1745 data[2] = 0x8e;
1746 data[3] = (f < 174000000 ? 0xa1 : f < 470000000 ? 0x92 : 0x34);
1747
1748 if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1)
1749 return -EIO;
1750 return 0;
1751}
1752
1753static struct ves1820_config philips_cd1516_config = {
1754 .demod_address = 0x09,
1755 .xin = 57840000UL,
1756 .invert = 1,
1757 .selagc = VES1820_SELAGC_SIGNAMPERR,
1758 .pll_set = philips_cd1516_pll_set,
1759};
1760
1761
1762
1763static int alps_tdlb7_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
1764{
1765 struct av7110* av7110 = fe->dvb->priv;
1766 u32 div, pwr;
1767 u8 data[4];
1768 struct i2c_msg msg = { .addr = 0x60, .flags = 0, .buf = data, .len = sizeof(data) };
1769
1770 div = (params->frequency + 36200000) / 166666;
1771
1772 if (params->frequency <= 782000000)
1773 pwr = 1;
1774 else
1775 pwr = 2;
1776
1777 data[0] = (div >> 8) & 0x7f;
1778 data[1] = div & 0xff;
1779 data[2] = 0x85;
1780 data[3] = pwr << 6;
1781
1782 if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1)
1783 return -EIO;
1784 return 0;
1785}
1786
1787static int alps_tdlb7_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name)
1788{
1789 struct av7110* av7110 = (struct av7110*) fe->dvb->priv;
1790
1791 return request_firmware(fw, name, &av7110->dev->pci->dev);
1792}
1793
1794static struct sp8870_config alps_tdlb7_config = {
1795
1796 .demod_address = 0x71,
1797 .pll_set = alps_tdlb7_pll_set,
1798 .request_firmware = alps_tdlb7_request_firmware,
1799};
1800
1801
Andrew de Quinceydc27a162005-09-09 13:03:07 -07001802static u8 nexusca_stv0297_inittab[] = {
1803 0x80, 0x01,
1804 0x80, 0x00,
1805 0x81, 0x01,
1806 0x81, 0x00,
1807 0x00, 0x09,
1808 0x01, 0x69,
1809 0x03, 0x00,
1810 0x04, 0x00,
1811 0x07, 0x00,
1812 0x08, 0x00,
1813 0x20, 0x00,
1814 0x21, 0x40,
1815 0x22, 0x00,
1816 0x23, 0x00,
1817 0x24, 0x40,
1818 0x25, 0x88,
1819 0x30, 0xff,
1820 0x31, 0x00,
1821 0x32, 0xff,
1822 0x33, 0x00,
1823 0x34, 0x50,
1824 0x35, 0x7f,
1825 0x36, 0x00,
1826 0x37, 0x20,
1827 0x38, 0x00,
1828 0x40, 0x1c,
1829 0x41, 0xff,
1830 0x42, 0x29,
1831 0x43, 0x00,
1832 0x44, 0xff,
1833 0x45, 0x00,
1834 0x46, 0x00,
1835 0x49, 0x04,
1836 0x4a, 0x00,
1837 0x4b, 0x7b,
1838 0x52, 0x30,
1839 0x55, 0xae,
1840 0x56, 0x47,
1841 0x57, 0xe1,
1842 0x58, 0x3a,
1843 0x5a, 0x1e,
1844 0x5b, 0x34,
1845 0x60, 0x00,
1846 0x63, 0x00,
1847 0x64, 0x00,
1848 0x65, 0x00,
1849 0x66, 0x00,
1850 0x67, 0x00,
1851 0x68, 0x00,
1852 0x69, 0x00,
1853 0x6a, 0x02,
1854 0x6b, 0x00,
1855 0x70, 0xff,
1856 0x71, 0x00,
1857 0x72, 0x00,
1858 0x73, 0x00,
1859 0x74, 0x0c,
1860 0x80, 0x00,
1861 0x81, 0x00,
1862 0x82, 0x00,
1863 0x83, 0x00,
1864 0x84, 0x04,
1865 0x85, 0x80,
1866 0x86, 0x24,
1867 0x87, 0x78,
1868 0x88, 0x10,
1869 0x89, 0x00,
1870 0x90, 0x01,
1871 0x91, 0x01,
1872 0xa0, 0x04,
1873 0xa1, 0x00,
1874 0xa2, 0x00,
1875 0xb0, 0x91,
1876 0xb1, 0x0b,
1877 0xc0, 0x53,
1878 0xc1, 0x70,
1879 0xc2, 0x12,
1880 0xd0, 0x00,
1881 0xd1, 0x00,
1882 0xd2, 0x00,
1883 0xd3, 0x00,
1884 0xd4, 0x00,
1885 0xd5, 0x00,
1886 0xde, 0x00,
1887 0xdf, 0x00,
1888 0x61, 0x49,
1889 0x62, 0x0b,
1890 0x53, 0x08,
1891 0x59, 0x08,
1892 0xff, 0xff,
1893};
Linus Torvalds1da177e2005-04-16 15:20:36 -07001894
1895static int nexusca_stv0297_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
1896{
1897 struct av7110* av7110 = fe->dvb->priv;
1898 u32 div;
1899 u8 data[4];
1900 struct i2c_msg msg = { .addr = 0x63, .flags = 0, .buf = data, .len = sizeof(data) };
1901 struct i2c_msg readmsg = { .addr = 0x63, .flags = I2C_M_RD, .buf = data, .len = 1 };
1902 int i;
1903
1904 div = (params->frequency + 36150000 + 31250) / 62500;
1905
1906 data[0] = (div >> 8) & 0x7f;
1907 data[1] = div & 0xff;
1908 data[2] = 0xce;
1909
1910 if (params->frequency < 45000000)
1911 return -EINVAL;
1912 else if (params->frequency < 137000000)
1913 data[3] = 0x01;
1914 else if (params->frequency < 403000000)
1915 data[3] = 0x02;
1916 else if (params->frequency < 860000000)
1917 data[3] = 0x04;
1918 else
1919 return -EINVAL;
1920
1921 stv0297_enable_plli2c(fe);
1922 if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1) {
1923 printk("nexusca: pll transfer failed!\n");
1924 return -EIO;
1925 }
1926
1927 // wait for PLL lock
1928 for(i = 0; i < 20; i++) {
1929
1930 stv0297_enable_plli2c(fe);
1931 if (i2c_transfer(&av7110->i2c_adap, &readmsg, 1) == 1)
1932 if (data[0] & 0x40) break;
1933 msleep(10);
1934 }
1935
1936 return 0;
1937}
1938
1939static struct stv0297_config nexusca_stv0297_config = {
1940
1941 .demod_address = 0x1C,
Andrew de Quinceydc27a162005-09-09 13:03:07 -07001942 .inittab = nexusca_stv0297_inittab,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001943 .invert = 1,
1944 .pll_set = nexusca_stv0297_pll_set,
1945};
1946
1947
1948
1949static int grundig_29504_401_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
1950{
1951 struct av7110* av7110 = (struct av7110*) fe->dvb->priv;
1952 u32 div;
1953 u8 cfg, cpump, band_select;
1954 u8 data[4];
1955 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
1956
1957 div = (36125000 + params->frequency) / 166666;
1958
1959 cfg = 0x88;
1960
1961 if (params->frequency < 175000000) cpump = 2;
1962 else if (params->frequency < 390000000) cpump = 1;
1963 else if (params->frequency < 470000000) cpump = 2;
1964 else if (params->frequency < 750000000) cpump = 1;
1965 else cpump = 3;
1966
1967 if (params->frequency < 175000000) band_select = 0x0e;
1968 else if (params->frequency < 470000000) band_select = 0x05;
1969 else band_select = 0x03;
1970
1971 data[0] = (div >> 8) & 0x7f;
1972 data[1] = div & 0xff;
1973 data[2] = ((div >> 10) & 0x60) | cfg;
1974 data[3] = (cpump << 6) | band_select;
1975
1976 if (i2c_transfer (&av7110->i2c_adap, &msg, 1) != 1) return -EIO;
1977 return 0;
1978}
1979
1980static struct l64781_config grundig_29504_401_config = {
1981 .demod_address = 0x55,
1982 .pll_set = grundig_29504_401_pll_set,
1983};
1984
1985
1986
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001987static int av7110_fe_lock_fix(struct av7110* av7110, fe_status_t status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001988{
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001989 int ret = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001990 int synced = (status & FE_HAS_LOCK) ? 1 : 0;
1991
1992 av7110->fe_status = status;
1993
1994 if (av7110->fe_synced == synced)
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001995 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001996
Linus Torvalds1da177e2005-04-16 15:20:36 -07001997 if (av7110->playing)
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001998 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001999
Ingo Molnar3593cab2006-02-07 06:49:14 -02002000 if (mutex_lock_interruptible(&av7110->pid_mutex))
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002001 return -ERESTARTSYS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002002
Oliver Endriss34612152005-07-07 17:58:02 -07002003 if (synced) {
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002004 ret = SetPIDs(av7110, av7110->pids[DMX_PES_VIDEO],
Linus Torvalds1da177e2005-04-16 15:20:36 -07002005 av7110->pids[DMX_PES_AUDIO],
2006 av7110->pids[DMX_PES_TELETEXT], 0,
2007 av7110->pids[DMX_PES_PCR]);
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002008 if (!ret)
2009 ret = av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, Scan, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002010 } else {
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002011 ret = SetPIDs(av7110, 0, 0, 0, 0, 0);
2012 if (!ret) {
2013 ret = av7110_fw_cmd(av7110, COMTYPE_PID_FILTER, FlushTSQueue, 0);
2014 if (!ret)
2015 ret = av7110_wait_msgstate(av7110, GPMQBusy);
2016 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002017 }
2018
Oliver Endriss34612152005-07-07 17:58:02 -07002019 if (!ret)
2020 av7110->fe_synced = synced;
2021
Ingo Molnar3593cab2006-02-07 06:49:14 -02002022 mutex_unlock(&av7110->pid_mutex);
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002023 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002024}
2025
2026static int av7110_fe_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
2027{
2028 struct av7110* av7110 = fe->dvb->priv;
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002029
2030 int ret = av7110_fe_lock_fix(av7110, 0);
Oliver Endriss66190a22006-01-09 15:32:42 -02002031 if (!ret) {
2032 av7110->saved_fe_params = *params;
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002033 ret = av7110->fe_set_frontend(fe, params);
Oliver Endriss66190a22006-01-09 15:32:42 -02002034 }
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002035 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002036}
2037
2038static int av7110_fe_init(struct dvb_frontend* fe)
2039{
2040 struct av7110* av7110 = fe->dvb->priv;
2041
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002042 int ret = av7110_fe_lock_fix(av7110, 0);
2043 if (!ret)
2044 ret = av7110->fe_init(fe);
2045 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002046}
2047
2048static int av7110_fe_read_status(struct dvb_frontend* fe, fe_status_t* status)
2049{
2050 struct av7110* av7110 = fe->dvb->priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002051
2052 /* call the real implementation */
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002053 int ret = av7110->fe_read_status(fe, status);
2054 if (!ret)
2055 if (((*status ^ av7110->fe_status) & FE_HAS_LOCK) && (*status & FE_HAS_LOCK))
2056 ret = av7110_fe_lock_fix(av7110, *status);
2057 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002058}
2059
2060static int av7110_fe_diseqc_reset_overload(struct dvb_frontend* fe)
2061{
2062 struct av7110* av7110 = fe->dvb->priv;
2063
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002064 int ret = av7110_fe_lock_fix(av7110, 0);
2065 if (!ret)
2066 ret = av7110->fe_diseqc_reset_overload(fe);
2067 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002068}
2069
2070static int av7110_fe_diseqc_send_master_cmd(struct dvb_frontend* fe,
2071 struct dvb_diseqc_master_cmd* cmd)
2072{
2073 struct av7110* av7110 = fe->dvb->priv;
2074
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002075 int ret = av7110_fe_lock_fix(av7110, 0);
Oliver Endriss66190a22006-01-09 15:32:42 -02002076 if (!ret) {
2077 av7110->saved_master_cmd = *cmd;
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002078 ret = av7110->fe_diseqc_send_master_cmd(fe, cmd);
Oliver Endriss66190a22006-01-09 15:32:42 -02002079 }
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002080 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002081}
2082
2083static int av7110_fe_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd)
2084{
2085 struct av7110* av7110 = fe->dvb->priv;
2086
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002087 int ret = av7110_fe_lock_fix(av7110, 0);
Oliver Endriss66190a22006-01-09 15:32:42 -02002088 if (!ret) {
2089 av7110->saved_minicmd = minicmd;
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002090 ret = av7110->fe_diseqc_send_burst(fe, minicmd);
Oliver Endriss66190a22006-01-09 15:32:42 -02002091 }
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002092 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002093}
2094
2095static int av7110_fe_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
2096{
2097 struct av7110* av7110 = fe->dvb->priv;
2098
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002099 int ret = av7110_fe_lock_fix(av7110, 0);
Oliver Endriss66190a22006-01-09 15:32:42 -02002100 if (!ret) {
2101 av7110->saved_tone = tone;
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002102 ret = av7110->fe_set_tone(fe, tone);
Oliver Endriss66190a22006-01-09 15:32:42 -02002103 }
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002104 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002105}
2106
2107static int av7110_fe_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
2108{
2109 struct av7110* av7110 = fe->dvb->priv;
2110
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002111 int ret = av7110_fe_lock_fix(av7110, 0);
Oliver Endriss66190a22006-01-09 15:32:42 -02002112 if (!ret) {
2113 av7110->saved_voltage = voltage;
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002114 ret = av7110->fe_set_voltage(fe, voltage);
Oliver Endriss66190a22006-01-09 15:32:42 -02002115 }
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002116 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002117}
2118
Peter Beutner400b7082006-01-09 15:32:43 -02002119static int av7110_fe_dishnetwork_send_legacy_command(struct dvb_frontend* fe, unsigned long cmd)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002120{
2121 struct av7110* av7110 = fe->dvb->priv;
2122
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002123 int ret = av7110_fe_lock_fix(av7110, 0);
2124 if (!ret)
2125 ret = av7110->fe_dishnetwork_send_legacy_command(fe, cmd);
2126 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002127}
2128
Oliver Endriss66190a22006-01-09 15:32:42 -02002129static void dvb_s_recover(struct av7110* av7110)
2130{
2131 av7110_fe_init(av7110->fe);
2132
2133 av7110_fe_set_voltage(av7110->fe, av7110->saved_voltage);
2134 if (av7110->saved_master_cmd.msg_len) {
2135 msleep(20);
2136 av7110_fe_diseqc_send_master_cmd(av7110->fe, &av7110->saved_master_cmd);
2137 }
2138 msleep(20);
2139 av7110_fe_diseqc_send_burst(av7110->fe, av7110->saved_minicmd);
2140 msleep(20);
2141 av7110_fe_set_tone(av7110->fe, av7110->saved_tone);
2142
2143 av7110_fe_set_frontend(av7110->fe, &av7110->saved_fe_params);
2144}
2145
Linus Torvalds1da177e2005-04-16 15:20:36 -07002146static u8 read_pwm(struct av7110* av7110)
2147{
2148 u8 b = 0xff;
2149 u8 pwm;
2150 struct i2c_msg msg[] = { { .addr = 0x50,.flags = 0,.buf = &b,.len = 1 },
2151 { .addr = 0x50,.flags = I2C_M_RD,.buf = &pwm,.len = 1} };
2152
Mauro Carvalho Chehab9101e622005-12-12 00:37:24 -08002153 if ((i2c_transfer(&av7110->i2c_adap, msg, 2) != 2) || (pwm == 0xff))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002154 pwm = 0x48;
2155
2156 return pwm;
2157}
2158
2159static int frontend_init(struct av7110 *av7110)
2160{
2161 int ret;
2162
2163 if (av7110->dev->pci->subsystem_vendor == 0x110a) {
2164 switch(av7110->dev->pci->subsystem_device) {
2165 case 0x0000: // Fujitsu/Siemens DVB-Cable (ves1820/Philips CD1516(??))
2166 av7110->fe = ves1820_attach(&philips_cd1516_config,
2167 &av7110->i2c_adap, read_pwm(av7110));
2168 break;
2169 }
2170
2171 } else if (av7110->dev->pci->subsystem_vendor == 0x13c2) {
2172 switch(av7110->dev->pci->subsystem_device) {
2173 case 0x0000: // Hauppauge/TT WinTV DVB-S rev1.X
2174 case 0x0003: // Hauppauge/TT WinTV Nexus-S Rev 2.X
2175 case 0x1002: // Hauppauge/TT WinTV DVB-S rev1.3SE
2176
2177 // try the ALPS BSRV2 first of all
2178 av7110->fe = ves1x93_attach(&alps_bsrv2_config, &av7110->i2c_adap);
2179 if (av7110->fe) {
2180 av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd;
2181 av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst;
2182 av7110->fe->ops->set_tone = av7110_set_tone;
Oliver Endriss66190a22006-01-09 15:32:42 -02002183 av7110->recover = dvb_s_recover;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002184 break;
2185 }
2186
2187 // try the ALPS BSRU6 now
2188 av7110->fe = stv0299_attach(&alps_bsru6_config, &av7110->i2c_adap);
2189 if (av7110->fe) {
2190 av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd;
2191 av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst;
2192 av7110->fe->ops->set_tone = av7110_set_tone;
Oliver Endriss66190a22006-01-09 15:32:42 -02002193 av7110->recover = dvb_s_recover;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002194 break;
2195 }
2196
2197 // Try the grundig 29504-451
Michael Krufky50c25ff2006-01-09 15:25:34 -02002198 av7110->fe = tda8083_attach(&grundig_29504_451_config, &av7110->i2c_adap);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002199 if (av7110->fe) {
2200 av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd;
2201 av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst;
2202 av7110->fe->ops->set_tone = av7110_set_tone;
Oliver Endriss66190a22006-01-09 15:32:42 -02002203 av7110->recover = dvb_s_recover;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002204 break;
2205 }
2206
2207 /* Try DVB-C cards */
2208 switch(av7110->dev->pci->subsystem_device) {
2209 case 0x0000:
2210 /* Siemens DVB-C (full-length card) VES1820/Philips CD1516 */
2211 av7110->fe = ves1820_attach(&philips_cd1516_config, &av7110->i2c_adap,
2212 read_pwm(av7110));
2213 break;
2214 case 0x0003:
2215 /* Haupauge DVB-C 2.1 VES1820/ALPS TDBE2 */
2216 av7110->fe = ves1820_attach(&alps_tdbe2_config, &av7110->i2c_adap,
2217 read_pwm(av7110));
2218 break;
2219 }
2220 break;
2221
2222 case 0x0001: // Hauppauge/TT Nexus-T premium rev1.X
2223
2224 // ALPS TDLB7
Michael Krufky50c25ff2006-01-09 15:25:34 -02002225 av7110->fe = sp8870_attach(&alps_tdlb7_config, &av7110->i2c_adap);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002226 break;
2227
2228 case 0x0002: // Hauppauge/TT DVB-C premium rev2.X
2229
Michael Krufky50c25ff2006-01-09 15:25:34 -02002230 av7110->fe = ves1820_attach(&alps_tdbe2_config, &av7110->i2c_adap, read_pwm(av7110));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002231 break;
2232
Oliver Endriss8bd63012006-02-07 06:49:11 -02002233 case 0x0004: // Galaxis DVB-S rev1.3
2234 /* ALPS BSRV2 */
2235 av7110->fe = ves1x93_attach(&alps_bsrv2_config, &av7110->i2c_adap);
2236 if (av7110->fe) {
2237 av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd;
2238 av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst;
2239 av7110->fe->ops->set_tone = av7110_set_tone;
2240 av7110->recover = dvb_s_recover;
2241 }
2242 break;
2243
Linus Torvalds1da177e2005-04-16 15:20:36 -07002244 case 0x0006: /* Fujitsu-Siemens DVB-S rev 1.6 */
2245 /* Grundig 29504-451 */
2246 av7110->fe = tda8083_attach(&grundig_29504_451_config, &av7110->i2c_adap);
2247 if (av7110->fe) {
2248 av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd;
2249 av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst;
2250 av7110->fe->ops->set_tone = av7110_set_tone;
Oliver Endriss66190a22006-01-09 15:32:42 -02002251 av7110->recover = dvb_s_recover;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002252 }
2253 break;
2254
2255 case 0x0008: // Hauppauge/TT DVB-T
2256
2257 av7110->fe = l64781_attach(&grundig_29504_401_config, &av7110->i2c_adap);
2258 break;
2259
2260 case 0x000A: // Hauppauge/TT Nexus-CA rev1.X
2261
Andrew de Quinceydc27a162005-09-09 13:03:07 -07002262 av7110->fe = stv0297_attach(&nexusca_stv0297_config, &av7110->i2c_adap);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002263 if (av7110->fe) {
2264 /* set TDA9819 into DVB mode */
2265 saa7146_setgpio(av7110->dev, 1, SAA7146_GPIO_OUTLO); // TDA9198 pin9(STD)
2266 saa7146_setgpio(av7110->dev, 3, SAA7146_GPIO_OUTLO); // TDA9198 pin30(VIF)
2267
2268 /* tuner on this needs a slower i2c bus speed */
2269 av7110->dev->i2c_bitrate = SAA7146_I2C_BUS_BIT_RATE_240;
2270 break;
2271 }
Johannes Stezenbach3dfaebd2005-05-16 21:54:19 -07002272 break;
2273
2274 case 0x000E: /* Hauppauge/TT Nexus-S rev 2.3 */
2275 /* ALPS BSBE1 */
2276 av7110->fe = stv0299_attach(&alps_bsbe1_config, &av7110->i2c_adap);
Oliver Endrisseb3daf32006-01-09 15:25:05 -02002277 if (av7110->fe) {
Oliver Endrissdb5d91e2006-02-28 10:32:25 -03002278 if (lnbp21_init(av7110->fe, &av7110->i2c_adap, 0, 0)) {
2279 printk("dvb-ttpci: LNBP21 not found!\n");
2280 if (av7110->fe->ops->release)
2281 av7110->fe->ops->release(av7110->fe);
2282 av7110->fe = NULL;
2283 } else {
2284 av7110->fe->ops->dishnetwork_send_legacy_command = NULL;
2285 av7110->recover = dvb_s_recover;
2286 }
Oliver Endrisseb3daf32006-01-09 15:25:05 -02002287 }
Johannes Stezenbach3dfaebd2005-05-16 21:54:19 -07002288 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002289 }
2290 }
2291
2292 if (!av7110->fe) {
2293 /* FIXME: propagate the failure code from the lower layers */
2294 ret = -ENOMEM;
2295 printk("dvb-ttpci: A frontend driver was not found for device %04x/%04x subsystem %04x/%04x\n",
2296 av7110->dev->pci->vendor,
2297 av7110->dev->pci->device,
2298 av7110->dev->pci->subsystem_vendor,
2299 av7110->dev->pci->subsystem_device);
2300 } else {
2301 FE_FUNC_OVERRIDE(av7110->fe->ops->init, av7110->fe_init, av7110_fe_init);
2302 FE_FUNC_OVERRIDE(av7110->fe->ops->read_status, av7110->fe_read_status, av7110_fe_read_status);
2303 FE_FUNC_OVERRIDE(av7110->fe->ops->diseqc_reset_overload, av7110->fe_diseqc_reset_overload, av7110_fe_diseqc_reset_overload);
2304 FE_FUNC_OVERRIDE(av7110->fe->ops->diseqc_send_master_cmd, av7110->fe_diseqc_send_master_cmd, av7110_fe_diseqc_send_master_cmd);
2305 FE_FUNC_OVERRIDE(av7110->fe->ops->diseqc_send_burst, av7110->fe_diseqc_send_burst, av7110_fe_diseqc_send_burst);
2306 FE_FUNC_OVERRIDE(av7110->fe->ops->set_tone, av7110->fe_set_tone, av7110_fe_set_tone);
2307 FE_FUNC_OVERRIDE(av7110->fe->ops->set_voltage, av7110->fe_set_voltage, av7110_fe_set_voltage;)
2308 FE_FUNC_OVERRIDE(av7110->fe->ops->dishnetwork_send_legacy_command, av7110->fe_dishnetwork_send_legacy_command, av7110_fe_dishnetwork_send_legacy_command);
2309 FE_FUNC_OVERRIDE(av7110->fe->ops->set_frontend, av7110->fe_set_frontend, av7110_fe_set_frontend);
2310
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07002311 ret = dvb_register_frontend(&av7110->dvb_adapter, av7110->fe);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002312 if (ret < 0) {
2313 printk("av7110: Frontend registration failed!\n");
2314 if (av7110->fe->ops->release)
2315 av7110->fe->ops->release(av7110->fe);
2316 av7110->fe = NULL;
2317 }
2318 }
2319 return ret;
2320}
2321
2322/* Budgetpatch note:
2323 * Original hardware design by Roberto Deza:
2324 * There is a DVB_Wiki at
2325 * http://212.227.36.83/linuxtv/wiki/index.php/Main_Page
2326 * where is described this 'DVB TT Budget Patch', on Card Modding:
2327 * http://212.227.36.83/linuxtv/wiki/index.php/DVB_TT_Budget_Patch
2328 * On the short description there is also a link to a external file,
2329 * with more details:
2330 * http://perso.wanadoo.es/jesussolano/Ttf_tsc1.zip
2331 *
2332 * New software triggering design by Emard that works on
2333 * original Roberto Deza's hardware:
2334 *
2335 * rps1 code for budgetpatch will copy internal HS event to GPIO3 pin.
2336 * GPIO3 is in budget-patch hardware connectd to port B VSYNC
2337 * HS is an internal event of 7146, accessible with RPS
2338 * and temporarily raised high every n lines
2339 * (n in defined in the RPS_THRESH1 counter threshold)
2340 * I think HS is raised high on the beginning of the n-th line
2341 * and remains high until this n-th line that triggered
2342 * it is completely received. When the receiption of n-th line
2343 * ends, HS is lowered.
2344 *
2345 * To transmit data over DMA, 7146 needs changing state at
2346 * port B VSYNC pin. Any changing of port B VSYNC will
2347 * cause some DMA data transfer, with more or less packets loss.
2348 * It depends on the phase and frequency of VSYNC and
2349 * the way of 7146 is instructed to trigger on port B (defined
2350 * in DD1_INIT register, 3rd nibble from the right valid
2351 * numbers are 0-7, see datasheet)
2352 *
2353 * The correct triggering can minimize packet loss,
2354 * dvbtraffic should give this stable bandwidths:
2355 * 22k transponder = 33814 kbit/s
2356 * 27.5k transponder = 38045 kbit/s
2357 * by experiment it is found that the best results
2358 * (stable bandwidths and almost no packet loss)
2359 * are obtained using DD1_INIT triggering number 2
2360 * (Va at rising edge of VS Fa = HS x VS-failing forced toggle)
2361 * and a VSYNC phase that occurs in the middle of DMA transfer
2362 * (about byte 188*512=96256 in the DMA window).
2363 *
2364 * Phase of HS is still not clear to me how to control,
2365 * It just happens to be so. It can be seen if one enables
2366 * RPS_IRQ and print Event Counter 1 in vpeirq(). Every
2367 * time RPS_INTERRUPT is called, the Event Counter 1 will
2368 * increment. That's how the 7146 is programmed to do event
2369 * counting in this budget-patch.c
2370 * I *think* HPS setting has something to do with the phase
2371 * of HS but I cant be 100% sure in that.
2372 *
2373 * hardware debug note: a working budget card (including budget patch)
2374 * with vpeirq() interrupt setup in mode "0x90" (every 64K) will
2375 * generate 3 interrupts per 25-Hz DMA frame of 2*188*512 bytes
2376 * and that means 3*25=75 Hz of interrupt freqency, as seen by
2377 * watch cat /proc/interrupts
2378 *
2379 * If this frequency is 3x lower (and data received in the DMA
2380 * buffer don't start with 0x47, but in the middle of packets,
2381 * whose lengths appear to be like 188 292 188 104 etc.
2382 * this means VSYNC line is not connected in the hardware.
2383 * (check soldering pcb and pins)
2384 * The same behaviour of missing VSYNC can be duplicated on budget
2385 * cards, by seting DD1_INIT trigger mode 7 in 3rd nibble.
2386 */
Johannes Stezenbach1be11e32006-02-27 00:09:20 -03002387static int __devinit av7110_attach(struct saa7146_dev* dev,
2388 struct saa7146_pci_extension_data *pci_ext)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002389{
2390 const int length = TS_WIDTH * TS_HEIGHT;
2391 struct pci_dev *pdev = dev->pci;
2392 struct av7110 *av7110;
2393 int ret, count = 0;
2394
2395 dprintk(4, "dev: %p\n", dev);
2396
Mauro Carvalho Chehab9101e622005-12-12 00:37:24 -08002397 /* Set RPS_IRQ to 1 to track rps1 activity.
2398 * Enabling this won't send any interrupt to PC CPU.
2399 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002400#define RPS_IRQ 0
2401
2402 if (budgetpatch == 1) {
2403 budgetpatch = 0;
2404 /* autodetect the presence of budget patch
2405 * this only works if saa7146 has been recently
2406 * reset with with MASK_31 to MC1
2407 *
2408 * will wait for VBI_B event (vertical blank at port B)
2409 * and will reset GPIO3 after VBI_B is detected.
2410 * (GPIO3 should be raised high by CPU to
2411 * test if GPIO3 will generate vertical blank signal
2412 * in budget patch GPIO3 is connected to VSYNC_B
2413 */
2414
2415 /* RESET SAA7146 */
2416 saa7146_write(dev, MC1, MASK_31);
2417 /* autodetection success seems to be time-dependend after reset */
2418
2419 /* Fix VSYNC level */
2420 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
2421 /* set vsync_b triggering */
2422 saa7146_write(dev, DD1_STREAM_B, 0);
2423 /* port B VSYNC at rising edge */
2424 saa7146_write(dev, DD1_INIT, 0x00000200);
2425 saa7146_write(dev, BRS_CTRL, 0x00000000); // VBI
2426 saa7146_write(dev, MC2,
2427 1 * (MASK_08 | MASK_24) | // BRS control
2428 0 * (MASK_09 | MASK_25) | // a
2429 1 * (MASK_10 | MASK_26) | // b
2430 0 * (MASK_06 | MASK_22) | // HPS_CTRL1
2431 0 * (MASK_05 | MASK_21) | // HPS_CTRL2
2432 0 * (MASK_01 | MASK_15) // DEBI
2433 );
2434
2435 /* start writing RPS1 code from beginning */
2436 count = 0;
2437 /* Disable RPS1 */
2438 saa7146_write(dev, MC1, MASK_29);
2439 /* RPS1 timeout disable */
2440 saa7146_write(dev, RPS_TOV1, 0);
2441 WRITE_RPS1(cpu_to_le32(CMD_PAUSE | EVT_VBI_B));
2442 WRITE_RPS1(cpu_to_le32(CMD_WR_REG_MASK | (GPIO_CTRL>>2)));
2443 WRITE_RPS1(cpu_to_le32(GPIO3_MSK));
2444 WRITE_RPS1(cpu_to_le32(SAA7146_GPIO_OUTLO<<24));
2445#if RPS_IRQ
2446 /* issue RPS1 interrupt to increment counter */
2447 WRITE_RPS1(cpu_to_le32(CMD_INTERRUPT));
2448#endif
2449 WRITE_RPS1(cpu_to_le32(CMD_STOP));
2450 /* Jump to begin of RPS program as safety measure (p37) */
2451 WRITE_RPS1(cpu_to_le32(CMD_JUMP));
2452 WRITE_RPS1(cpu_to_le32(dev->d_rps1.dma_handle));
2453
2454#if RPS_IRQ
2455 /* set event counter 1 source as RPS1 interrupt (0x03) (rE4 p53)
2456 * use 0x03 to track RPS1 interrupts - increase by 1 every gpio3 is toggled
2457 * use 0x15 to track VPE interrupts - increase by 1 every vpeirq() is called
2458 */
2459 saa7146_write(dev, EC1SSR, (0x03<<2) | 3 );
2460 /* set event counter 1 treshold to maximum allowed value (rEC p55) */
2461 saa7146_write(dev, ECT1R, 0x3fff );
2462#endif
2463 /* Set RPS1 Address register to point to RPS code (r108 p42) */
2464 saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle);
2465 /* Enable RPS1, (rFC p33) */
2466 saa7146_write(dev, MC1, (MASK_13 | MASK_29 ));
2467
2468 mdelay(10);
2469 /* now send VSYNC_B to rps1 by rising GPIO3 */
2470 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI);
2471 mdelay(10);
2472 /* if rps1 responded by lowering the GPIO3,
2473 * then we have budgetpatch hardware
2474 */
2475 if ((saa7146_read(dev, GPIO_CTRL) & 0x10000000) == 0) {
2476 budgetpatch = 1;
2477 printk("dvb-ttpci: BUDGET-PATCH DETECTED.\n");
2478 }
2479 /* Disable RPS1 */
2480 saa7146_write(dev, MC1, ( MASK_29 ));
2481#if RPS_IRQ
2482 printk("dvb-ttpci: Event Counter 1 0x%04x\n", saa7146_read(dev, EC1R) & 0x3fff );
2483#endif
2484 }
2485
2486 /* prepare the av7110 device struct */
Panagiotis Issaris74081872006-01-11 19:40:56 -02002487 av7110 = kzalloc(sizeof(struct av7110), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002488 if (!av7110) {
2489 dprintk(1, "out of memory\n");
2490 return -ENOMEM;
2491 }
2492
Linus Torvalds1da177e2005-04-16 15:20:36 -07002493 av7110->card_name = (char*) pci_ext->ext_priv;
2494 av7110->dev = dev;
2495 dev->ext_priv = av7110;
2496
2497 ret = get_firmware(av7110);
2498 if (ret < 0)
2499 goto err_kfree_0;
2500
2501 ret = dvb_register_adapter(&av7110->dvb_adapter, av7110->card_name,
2502 THIS_MODULE);
2503 if (ret < 0)
2504 goto err_put_firmware_1;
2505
2506 /* the Siemens DVB needs this if you want to have the i2c chips
2507 get recognized before the main driver is fully loaded */
2508 saa7146_write(dev, GPIO_CTRL, 0x500000);
2509
2510#ifdef I2C_ADAP_CLASS_TV_DIGITAL
2511 av7110->i2c_adap.class = I2C_ADAP_CLASS_TV_DIGITAL;
2512#else
2513 av7110->i2c_adap.class = I2C_CLASS_TV_DIGITAL;
2514#endif
2515 strlcpy(av7110->i2c_adap.name, pci_ext->ext_priv, sizeof(av7110->i2c_adap.name));
2516
2517 saa7146_i2c_adapter_prepare(dev, &av7110->i2c_adap, SAA7146_I2C_BUS_BIT_RATE_120); /* 275 kHz */
2518
2519 ret = i2c_add_adapter(&av7110->i2c_adap);
2520 if (ret < 0)
2521 goto err_dvb_unregister_adapter_2;
2522
2523 ttpci_eeprom_parse_mac(&av7110->i2c_adap,
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07002524 av7110->dvb_adapter.proposed_mac);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002525 ret = -ENOMEM;
2526
2527 if (budgetpatch) {
2528 spin_lock_init(&av7110->feedlock1);
2529 av7110->grabbing = saa7146_vmalloc_build_pgtable(pdev, length,
2530 &av7110->pt);
2531 if (!av7110->grabbing)
2532 goto err_i2c_del_3;
2533
2534 saa7146_write(dev, PCI_BT_V1, 0x1c1f101f);
2535 saa7146_write(dev, BCS_CTRL, 0x80400040);
2536 /* set dd1 stream a & b */
2537 saa7146_write(dev, DD1_STREAM_B, 0x00000000);
2538 saa7146_write(dev, DD1_INIT, 0x03000200);
2539 saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
2540 saa7146_write(dev, BRS_CTRL, 0x60000000);
2541 saa7146_write(dev, BASE_ODD3, 0);
2542 saa7146_write(dev, BASE_EVEN3, 0);
2543 saa7146_write(dev, PROT_ADDR3, TS_WIDTH * TS_HEIGHT);
2544 saa7146_write(dev, BASE_PAGE3, av7110->pt.dma | ME1 | 0x90);
2545
2546 saa7146_write(dev, PITCH3, TS_WIDTH);
2547 saa7146_write(dev, NUM_LINE_BYTE3, (TS_HEIGHT << 16) | TS_WIDTH);
2548
2549 /* upload all */
2550 saa7146_write(dev, MC2, 0x077c077c);
2551 saa7146_write(dev, GPIO_CTRL, 0x000000);
2552#if RPS_IRQ
2553 /* set event counter 1 source as RPS1 interrupt (0x03) (rE4 p53)
2554 * use 0x03 to track RPS1 interrupts - increase by 1 every gpio3 is toggled
2555 * use 0x15 to track VPE interrupts - increase by 1 every vpeirq() is called
2556 */
2557 saa7146_write(dev, EC1SSR, (0x03<<2) | 3 );
2558 /* set event counter 1 treshold to maximum allowed value (rEC p55) */
2559 saa7146_write(dev, ECT1R, 0x3fff );
2560#endif
2561 /* Setup BUDGETPATCH MAIN RPS1 "program" (p35) */
2562 count = 0;
2563
2564 /* Wait Source Line Counter Threshold (p36) */
2565 WRITE_RPS1(cpu_to_le32(CMD_PAUSE | EVT_HS));
2566 /* Set GPIO3=1 (p42) */
2567 WRITE_RPS1(cpu_to_le32(CMD_WR_REG_MASK | (GPIO_CTRL>>2)));
2568 WRITE_RPS1(cpu_to_le32(GPIO3_MSK));
2569 WRITE_RPS1(cpu_to_le32(SAA7146_GPIO_OUTHI<<24));
2570#if RPS_IRQ
2571 /* issue RPS1 interrupt */
2572 WRITE_RPS1(cpu_to_le32(CMD_INTERRUPT));
2573#endif
2574 /* Wait reset Source Line Counter Threshold (p36) */
2575 WRITE_RPS1(cpu_to_le32(CMD_PAUSE | RPS_INV | EVT_HS));
2576 /* Set GPIO3=0 (p42) */
2577 WRITE_RPS1(cpu_to_le32(CMD_WR_REG_MASK | (GPIO_CTRL>>2)));
2578 WRITE_RPS1(cpu_to_le32(GPIO3_MSK));
2579 WRITE_RPS1(cpu_to_le32(SAA7146_GPIO_OUTLO<<24));
2580#if RPS_IRQ
2581 /* issue RPS1 interrupt */
2582 WRITE_RPS1(cpu_to_le32(CMD_INTERRUPT));
2583#endif
2584 /* Jump to begin of RPS program (p37) */
2585 WRITE_RPS1(cpu_to_le32(CMD_JUMP));
2586 WRITE_RPS1(cpu_to_le32(dev->d_rps1.dma_handle));
2587
2588 /* Fix VSYNC level */
2589 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
2590 /* Set RPS1 Address register to point to RPS code (r108 p42) */
2591 saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle);
2592 /* Set Source Line Counter Threshold, using BRS (rCC p43)
2593 * It generates HS event every TS_HEIGHT lines
2594 * this is related to TS_WIDTH set in register
2595 * NUM_LINE_BYTE3. If NUM_LINE_BYTE low 16 bits
2596 * are set to TS_WIDTH bytes (TS_WIDTH=2*188),
2597 * then RPS_THRESH1 should be set to trigger
2598 * every TS_HEIGHT (512) lines.
2599 */
2600 saa7146_write(dev, RPS_THRESH1, (TS_HEIGHT*1) | MASK_12 );
2601
2602 /* Enable RPS1 (rFC p33) */
2603 saa7146_write(dev, MC1, (MASK_13 | MASK_29));
2604
2605 /* end of budgetpatch register initialization */
2606 tasklet_init (&av7110->vpe_tasklet, vpeirq, (unsigned long) av7110);
2607 } else {
2608 saa7146_write(dev, PCI_BT_V1, 0x1c00101f);
2609 saa7146_write(dev, BCS_CTRL, 0x80400040);
2610
2611 /* set dd1 stream a & b */
2612 saa7146_write(dev, DD1_STREAM_B, 0x00000000);
2613 saa7146_write(dev, DD1_INIT, 0x03000000);
2614 saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
2615
2616 /* upload all */
2617 saa7146_write(dev, MC2, 0x077c077c);
2618 saa7146_write(dev, GPIO_CTRL, 0x000000);
2619 }
2620
2621 tasklet_init (&av7110->debi_tasklet, debiirq, (unsigned long) av7110);
2622 tasklet_init (&av7110->gpio_tasklet, gpioirq, (unsigned long) av7110);
2623
Ingo Molnar3593cab2006-02-07 06:49:14 -02002624 mutex_init(&av7110->pid_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002625
2626 /* locks for data transfers from/to AV7110 */
2627 spin_lock_init(&av7110->debilock);
Ingo Molnar3593cab2006-02-07 06:49:14 -02002628 mutex_init(&av7110->dcomlock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002629 av7110->debitype = -1;
2630
2631 /* default OSD window */
2632 av7110->osdwin = 1;
Ingo Molnar3593cab2006-02-07 06:49:14 -02002633 mutex_init(&av7110->osd_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002634
2635 /* ARM "watchdog" */
2636 init_waitqueue_head(&av7110->arm_wait);
2637 av7110->arm_thread = NULL;
2638
2639 /* allocate and init buffers */
2640 av7110->debi_virt = pci_alloc_consistent(pdev, 8192, &av7110->debi_bus);
2641 if (!av7110->debi_virt)
2642 goto err_saa71466_vfree_4;
2643
2644
2645 av7110->iobuf = vmalloc(AVOUTLEN+AOUTLEN+BMPLEN+4*IPACKS);
2646 if (!av7110->iobuf)
2647 goto err_pci_free_5;
2648
2649 ret = av7110_av_init(av7110);
2650 if (ret < 0)
2651 goto err_iobuf_vfree_6;
2652
2653 /* init BMP buffer */
2654 av7110->bmpbuf = av7110->iobuf+AVOUTLEN+AOUTLEN;
2655 init_waitqueue_head(&av7110->bmpq);
2656
2657 ret = av7110_ca_init(av7110);
2658 if (ret < 0)
2659 goto err_av7110_av_exit_7;
2660
2661 /* load firmware into AV7110 cards */
2662 ret = av7110_bootarm(av7110);
2663 if (ret < 0)
2664 goto err_av7110_ca_exit_8;
2665
2666 ret = av7110_firmversion(av7110);
2667 if (ret < 0)
2668 goto err_stop_arm_9;
2669
2670 if (FW_VERSION(av7110->arm_app)<0x2501)
2671 printk ("dvb-ttpci: Warning, firmware version 0x%04x is too old. "
2672 "System might be unstable!\n", FW_VERSION(av7110->arm_app));
2673
2674 ret = kernel_thread(arm_thread, (void *) av7110, 0);
2675 if (ret < 0)
2676 goto err_stop_arm_9;
2677
2678 /* set initial volume in mixer struct */
2679 av7110->mixer.volume_left = volume;
2680 av7110->mixer.volume_right = volume;
2681
2682 init_av7110_av(av7110);
2683
2684 ret = av7110_register(av7110);
2685 if (ret < 0)
2686 goto err_arm_thread_stop_10;
2687
2688 /* special case DVB-C: these cards have an analog tuner
2689 plus need some special handling, so we have separate
2690 saa7146_ext_vv data for these... */
2691 ret = av7110_init_v4l(av7110);
2692 if (ret < 0)
2693 goto err_av7110_unregister_11;
2694
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07002695 av7110->dvb_adapter.priv = av7110;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002696 ret = frontend_init(av7110);
2697 if (ret < 0)
2698 goto err_av7110_exit_v4l_12;
2699
2700#if defined(CONFIG_INPUT_EVDEV) || defined(CONFIG_INPUT_EVDEV_MODULE)
Oliver Endriss03388ae2005-09-09 13:03:12 -07002701 av7110_ir_init(av7110);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002702#endif
2703 printk(KERN_INFO "dvb-ttpci: found av7110-%d.\n", av7110_num);
2704 av7110_num++;
2705out:
2706 return ret;
2707
2708err_av7110_exit_v4l_12:
2709 av7110_exit_v4l(av7110);
2710err_av7110_unregister_11:
2711 dvb_unregister(av7110);
2712err_arm_thread_stop_10:
2713 av7110_arm_sync(av7110);
2714err_stop_arm_9:
2715 /* Nothing to do. Rejoice. */
2716err_av7110_ca_exit_8:
2717 av7110_ca_exit(av7110);
2718err_av7110_av_exit_7:
2719 av7110_av_exit(av7110);
2720err_iobuf_vfree_6:
2721 vfree(av7110->iobuf);
2722err_pci_free_5:
2723 pci_free_consistent(pdev, 8192, av7110->debi_virt, av7110->debi_bus);
2724err_saa71466_vfree_4:
2725 if (!av7110->grabbing)
2726 saa7146_pgtable_free(pdev, &av7110->pt);
2727err_i2c_del_3:
2728 i2c_del_adapter(&av7110->i2c_adap);
2729err_dvb_unregister_adapter_2:
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07002730 dvb_unregister_adapter(&av7110->dvb_adapter);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002731err_put_firmware_1:
2732 put_firmware(av7110);
2733err_kfree_0:
2734 kfree(av7110);
2735 goto out;
2736}
2737
Johannes Stezenbach1be11e32006-02-27 00:09:20 -03002738static int __devexit av7110_detach(struct saa7146_dev* saa)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002739{
2740 struct av7110 *av7110 = saa->ext_priv;
2741 dprintk(4, "%p\n", av7110);
2742
Oliver Endriss03388ae2005-09-09 13:03:12 -07002743#if defined(CONFIG_INPUT_EVDEV) || defined(CONFIG_INPUT_EVDEV_MODULE)
2744 av7110_ir_exit(av7110);
2745#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07002746 if (budgetpatch) {
2747 /* Disable RPS1 */
2748 saa7146_write(saa, MC1, MASK_29);
2749 /* VSYNC LOW (inactive) */
2750 saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO);
2751 saa7146_write(saa, MC1, MASK_20); /* DMA3 off */
2752 SAA7146_IER_DISABLE(saa, MASK_10);
2753 SAA7146_ISR_CLEAR(saa, MASK_10);
2754 msleep(50);
2755 tasklet_kill(&av7110->vpe_tasklet);
2756 saa7146_pgtable_free(saa->pci, &av7110->pt);
2757 }
2758 av7110_exit_v4l(av7110);
2759
2760 av7110_arm_sync(av7110);
2761
2762 tasklet_kill(&av7110->debi_tasklet);
2763 tasklet_kill(&av7110->gpio_tasklet);
2764
2765 dvb_unregister(av7110);
2766
2767 SAA7146_IER_DISABLE(saa, MASK_19 | MASK_03);
2768 SAA7146_ISR_CLEAR(saa, MASK_19 | MASK_03);
2769
2770 av7110_ca_exit(av7110);
2771 av7110_av_exit(av7110);
2772
2773 vfree(av7110->iobuf);
2774 pci_free_consistent(saa->pci, 8192, av7110->debi_virt,
2775 av7110->debi_bus);
2776
2777 i2c_del_adapter(&av7110->i2c_adap);
2778
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07002779 dvb_unregister_adapter (&av7110->dvb_adapter);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002780
2781 av7110_num--;
2782
2783 put_firmware(av7110);
2784
2785 kfree(av7110);
2786
2787 saa->ext_priv = NULL;
2788
2789 return 0;
2790}
2791
2792
2793static void av7110_irq(struct saa7146_dev* dev, u32 *isr)
2794{
2795 struct av7110 *av7110 = dev->ext_priv;
2796
2797 //print_time("av7110_irq");
2798
2799 /* Note: Don't try to handle the DEBI error irq (MASK_18), in
2800 * intel mode the timeout is asserted all the time...
2801 */
2802
2803 if (*isr & MASK_19) {
2804 //printk("av7110_irq: DEBI\n");
2805 /* Note 1: The DEBI irq is level triggered: We must enable it
2806 * only after we started a DMA xfer, and disable it here
2807 * immediately, or it will be signalled all the time while
2808 * DEBI is idle.
2809 * Note 2: You would think that an irq which is masked is
2810 * not signalled by the hardware. Not so for the SAA7146:
2811 * An irq is signalled as long as the corresponding bit
2812 * in the ISR is set, and disabling irqs just prevents the
2813 * hardware from setting the ISR bit. This means a) that we
2814 * must clear the ISR *after* disabling the irq (which is why
2815 * we must do it here even though saa7146_core did it already),
2816 * and b) that if we were to disable an edge triggered irq
2817 * (like the gpio irqs sadly are) temporarily we would likely
2818 * loose some. This sucks :-(
2819 */
2820 SAA7146_IER_DISABLE(av7110->dev, MASK_19);
2821 SAA7146_ISR_CLEAR(av7110->dev, MASK_19);
2822 tasklet_schedule(&av7110->debi_tasklet);
2823 }
2824
2825 if (*isr & MASK_03) {
2826 //printk("av7110_irq: GPIO\n");
2827 tasklet_schedule(&av7110->gpio_tasklet);
2828 }
2829
2830 if ((*isr & MASK_10) && budgetpatch)
2831 tasklet_schedule(&av7110->vpe_tasklet);
2832}
2833
2834
2835static struct saa7146_extension av7110_extension;
2836
2837#define MAKE_AV7110_INFO(x_var,x_name) \
2838static struct saa7146_pci_extension_data x_var = { \
2839 .ext_priv = x_name, \
2840 .ext = &av7110_extension }
2841
Karl Herz6af4ee12005-09-09 13:03:13 -07002842MAKE_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 -07002843MAKE_AV7110_INFO(ttt_1_X, "Technotrend/Hauppauge WinTV DVB-T rev1.X");
2844MAKE_AV7110_INFO(ttc_1_X, "Technotrend/Hauppauge WinTV Nexus-CA rev1.X");
2845MAKE_AV7110_INFO(ttc_2_X, "Technotrend/Hauppauge WinTV DVB-C rev2.X");
2846MAKE_AV7110_INFO(tts_2_X, "Technotrend/Hauppauge WinTV Nexus-S rev2.X");
Johannes Stezenbach3dfaebd2005-05-16 21:54:19 -07002847MAKE_AV7110_INFO(tts_2_3, "Technotrend/Hauppauge WinTV Nexus-S rev2.3");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002848MAKE_AV7110_INFO(tts_1_3se, "Technotrend/Hauppauge WinTV DVB-S rev1.3 SE");
2849MAKE_AV7110_INFO(ttt, "Technotrend/Hauppauge DVB-T");
2850MAKE_AV7110_INFO(fsc, "Fujitsu Siemens DVB-C");
2851MAKE_AV7110_INFO(fss, "Fujitsu Siemens DVB-S rev1.6");
Oliver Endriss8bd63012006-02-07 06:49:11 -02002852MAKE_AV7110_INFO(gxs_1_3, "Galaxis DVB-S rev1.3");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002853
2854static struct pci_device_id pci_tbl[] = {
Karl Herz6af4ee12005-09-09 13:03:13 -07002855 MAKE_EXTENSION_PCI(fsc, 0x110a, 0x0000),
2856 MAKE_EXTENSION_PCI(tts_1_X_fsc, 0x13c2, 0x0000),
2857 MAKE_EXTENSION_PCI(ttt_1_X, 0x13c2, 0x0001),
2858 MAKE_EXTENSION_PCI(ttc_2_X, 0x13c2, 0x0002),
2859 MAKE_EXTENSION_PCI(tts_2_X, 0x13c2, 0x0003),
Oliver Endriss8bd63012006-02-07 06:49:11 -02002860 MAKE_EXTENSION_PCI(gxs_1_3, 0x13c2, 0x0004),
Karl Herz6af4ee12005-09-09 13:03:13 -07002861 MAKE_EXTENSION_PCI(fss, 0x13c2, 0x0006),
2862 MAKE_EXTENSION_PCI(ttt, 0x13c2, 0x0008),
2863 MAKE_EXTENSION_PCI(ttc_1_X, 0x13c2, 0x000a),
2864 MAKE_EXTENSION_PCI(tts_2_3, 0x13c2, 0x000e),
2865 MAKE_EXTENSION_PCI(tts_1_3se, 0x13c2, 0x1002),
Linus Torvalds1da177e2005-04-16 15:20:36 -07002866
Linus Torvalds1da177e2005-04-16 15:20:36 -07002867/* MAKE_EXTENSION_PCI(???, 0x13c2, 0x0005), UNDEFINED CARD */ // Technisat SkyStar1
2868/* MAKE_EXTENSION_PCI(???, 0x13c2, 0x0009), UNDEFINED CARD */ // TT/Hauppauge WinTV Nexus-CA v????
2869
2870 {
2871 .vendor = 0,
2872 }
2873};
2874
2875MODULE_DEVICE_TABLE(pci, pci_tbl);
2876
2877
2878static struct saa7146_extension av7110_extension = {
2879 .name = "dvb\0",
2880 .flags = SAA7146_I2C_SHORT_DELAY,
2881
2882 .module = THIS_MODULE,
2883 .pci_tbl = &pci_tbl[0],
2884 .attach = av7110_attach,
Johannes Stezenbach1be11e32006-02-27 00:09:20 -03002885 .detach = __devexit_p(av7110_detach),
Linus Torvalds1da177e2005-04-16 15:20:36 -07002886
2887 .irq_mask = MASK_19 | MASK_03 | MASK_10,
2888 .irq_func = av7110_irq,
2889};
2890
2891
2892static int __init av7110_init(void)
2893{
2894 int retval;
2895 retval = saa7146_register_extension(&av7110_extension);
2896 return retval;
2897}
2898
2899
2900static void __exit av7110_exit(void)
2901{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002902 saa7146_unregister_extension(&av7110_extension);
2903}
2904
2905module_init(av7110_init);
2906module_exit(av7110_exit);
2907
2908MODULE_DESCRIPTION("driver for the SAA7146 based AV110 PCI DVB cards by "
2909 "Siemens, Technotrend, Hauppauge");
2910MODULE_AUTHOR("Ralph Metzler, Marcus Metzler, others");
2911MODULE_LICENSE("GPL");