blob: 5cf5b7d044ff194ac08c16ba6aaad7e6ca7775ac [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"
Perceval Anichini265366e2006-03-16 11:22:47 -030071#include "bsru6.h"
Oliver Endrissdb5d91e2006-02-28 10:32:25 -030072
Linus Torvalds1da177e2005-04-16 15:20:36 -070073#define TS_WIDTH 376
74#define TS_HEIGHT 512
75#define TS_BUFLEN (TS_WIDTH*TS_HEIGHT)
76#define TS_MAX_PACKETS (TS_BUFLEN/TS_SIZE)
77
78
79int av7110_debug;
80
81static int vidmode = CVBS_RGB_OUT;
82static int pids_off;
83static int adac = DVB_ADAC_TI;
84static int hw_sections;
85static int rgb_on;
86static int volume = 255;
Mauro Carvalho Chehaba5ed4252006-01-13 14:10:19 -020087static int budgetpatch;
Linus Torvalds1da177e2005-04-16 15:20:36 -070088
89module_param_named(debug, av7110_debug, int, 0644);
90MODULE_PARM_DESC(debug, "debug level (bitmask, default 0)");
91module_param(vidmode, int, 0444);
92MODULE_PARM_DESC(vidmode,"analog video out: 0 off, 1 CVBS+RGB (default), 2 CVBS+YC, 3 YC");
93module_param(pids_off, int, 0444);
94MODULE_PARM_DESC(pids_off,"clear video/audio/PCR PID filters when demux is closed");
95module_param(adac, int, 0444);
96MODULE_PARM_DESC(adac,"audio DAC type: 0 TI, 1 CRYSTAL, 2 MSP (use if autodetection fails)");
97module_param(hw_sections, int, 0444);
98MODULE_PARM_DESC(hw_sections, "0 use software section filter, 1 use hardware");
99module_param(rgb_on, int, 0444);
100MODULE_PARM_DESC(rgb_on, "For Siemens DVB-C cards only: Enable RGB control"
101 " signal on SCART pin 16 to switch SCART video mode from CVBS to RGB");
102module_param(volume, int, 0444);
103MODULE_PARM_DESC(volume, "initial volume: default 255 (range 0-255)");
104module_param(budgetpatch, int, 0444);
105MODULE_PARM_DESC(budgetpatch, "use budget-patch hardware modification: default 0 (0 no, 1 autodetect, 2 always)");
106
107static void restart_feeds(struct av7110 *av7110);
108
Mauro Carvalho Chehaba5ed4252006-01-13 14:10:19 -0200109static int av7110_num;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700110
111#define FE_FUNC_OVERRIDE(fe_func, av7110_copy, av7110_func) \
112{\
113 if (fe_func != NULL) { \
114 av7110_copy = fe_func; \
115 fe_func = av7110_func; \
116 } \
117}
118
119
120static void init_av7110_av(struct av7110 *av7110)
121{
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700122 int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700123 struct saa7146_dev *dev = av7110->dev;
124
125 /* set internal volume control to maximum */
126 av7110->adac_type = DVB_ADAC_TI;
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700127 ret = av7110_set_volume(av7110, av7110->mixer.volume_left, av7110->mixer.volume_right);
Johannes Stezenbach7a2fa902005-07-07 17:58:01 -0700128 if (ret < 0)
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700129 printk("dvb-ttpci:cannot set internal volume to maximum:%d\n",ret);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700130
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700131 ret = av7710_set_video_mode(av7110, vidmode);
Johannes Stezenbach7a2fa902005-07-07 17:58:01 -0700132 if (ret < 0)
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700133 printk("dvb-ttpci:cannot set video mode:%d\n",ret);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700134
135 /* handle different card types */
136 /* remaining inits according to card and frontend type */
137 av7110->analog_tuner_flags = 0;
138 av7110->current_input = 0;
Marco Schluessler1c13b952006-01-09 15:25:06 -0200139 if (dev->pci->subsystem_vendor == 0x13c2 && dev->pci->subsystem_device == 0x000a) {
140 printk("dvb-ttpci: MSP3415 audio DAC @ card %d\n",
141 av7110->dvb_adapter.num);
142 av7110->adac_type = DVB_ADAC_MSP34x5;
143 av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, ADSwitch, 1, 0); // SPDIF on
144 }
145 else if (i2c_writereg(av7110, 0x20, 0x00, 0x00) == 1) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700146 printk ("dvb-ttpci: Crystal audio DAC @ card %d detected\n",
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -0700147 av7110->dvb_adapter.num);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700148 av7110->adac_type = DVB_ADAC_CRYSTAL;
149 i2c_writereg(av7110, 0x20, 0x01, 0xd2);
150 i2c_writereg(av7110, 0x20, 0x02, 0x49);
151 i2c_writereg(av7110, 0x20, 0x03, 0x00);
152 i2c_writereg(av7110, 0x20, 0x04, 0x00);
153
154 /**
155 * some special handling for the Siemens DVB-C cards...
156 */
157 } else if (0 == av7110_init_analog_module(av7110)) {
158 /* done. */
159 }
160 else if (dev->pci->subsystem_vendor == 0x110a) {
161 printk("dvb-ttpci: DVB-C w/o analog module @ card %d detected\n",
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -0700162 av7110->dvb_adapter.num);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700163 av7110->adac_type = DVB_ADAC_NONE;
164 }
165 else {
166 av7110->adac_type = adac;
167 printk("dvb-ttpci: adac type set to %d @ card %d\n",
Marco Schluessler1c13b952006-01-09 15:25:06 -0200168 av7110->adac_type, av7110->dvb_adapter.num);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700169 }
170
Marco Schluessler1c13b952006-01-09 15:25:06 -0200171 if (av7110->adac_type == DVB_ADAC_NONE || av7110->adac_type == DVB_ADAC_MSP34x0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700172 // switch DVB SCART on
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700173 ret = av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, MainSwitch, 1, 0);
Johannes Stezenbach7a2fa902005-07-07 17:58:01 -0700174 if (ret < 0)
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700175 printk("dvb-ttpci:cannot switch on SCART(Main):%d\n",ret);
176 ret = av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, ADSwitch, 1, 1);
Johannes Stezenbach7a2fa902005-07-07 17:58:01 -0700177 if (ret < 0)
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700178 printk("dvb-ttpci:cannot switch on SCART(AD):%d\n",ret);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700179 if (rgb_on &&
Karl Herz6af4ee12005-09-09 13:03:13 -0700180 ((av7110->dev->pci->subsystem_vendor == 0x110a) ||
181 (av7110->dev->pci->subsystem_vendor == 0x13c2)) &&
182 (av7110->dev->pci->subsystem_device == 0x0000)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700183 saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); // RGB on, SCART pin 16
184 //saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); // SCARTpin 8
185 }
186 }
187
Oliver Endriss60edb132005-12-19 08:54:11 -0200188 if (dev->pci->subsystem_vendor == 0x13c2 && dev->pci->subsystem_device == 0x000e)
189 av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, SpdifSwitch, 1, 0); // SPDIF on
190
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700191 ret = av7110_set_volume(av7110, av7110->mixer.volume_left, av7110->mixer.volume_right);
Johannes Stezenbach7a2fa902005-07-07 17:58:01 -0700192 if (ret < 0)
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700193 printk("dvb-ttpci:cannot set volume :%d\n",ret);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700194}
195
196static void recover_arm(struct av7110 *av7110)
197{
198 dprintk(4, "%p\n",av7110);
199
200 av7110_bootarm(av7110);
201 msleep(100);
Oliver Endriss66190a22006-01-09 15:32:42 -0200202
203 init_av7110_av(av7110);
204
205 /* card-specific recovery */
206 if (av7110->recover)
207 av7110->recover(av7110);
208
Linus Torvalds1da177e2005-04-16 15:20:36 -0700209 restart_feeds(av7110);
210 av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, SetIR, 1, av7110->ir_config);
211}
212
Linus Torvalds1da177e2005-04-16 15:20:36 -0700213static void av7110_arm_sync(struct av7110 *av7110)
214{
215 av7110->arm_rmmod = 1;
216 wake_up_interruptible(&av7110->arm_wait);
217
218 while (av7110->arm_thread)
219 msleep(1);
220}
221
222static int arm_thread(void *data)
223{
224 struct av7110 *av7110 = data;
225 u16 newloops = 0;
226 int timeout;
227
228 dprintk(4, "%p\n",av7110);
229
Mauro Carvalho Chehab9101e622005-12-12 00:37:24 -0800230 lock_kernel();
231 daemonize("arm_mon");
232 sigfillset(&current->blocked);
233 unlock_kernel();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700234
235 av7110->arm_thread = current;
236
237 for (;;) {
238 timeout = wait_event_interruptible_timeout(av7110->arm_wait,
239 av7110->arm_rmmod, 5 * HZ);
240 if (-ERESTARTSYS == timeout || av7110->arm_rmmod) {
241 /* got signal or told to quit*/
242 break;
243 }
244
245 if (!av7110->arm_ready)
246 continue;
247
Ingo Molnar3593cab2006-02-07 06:49:14 -0200248 if (mutex_lock_interruptible(&av7110->dcomlock))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700249 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700250 newloops = rdebi(av7110, DEBINOSWAP, STATUS_LOOPS, 0, 2);
Ingo Molnar3593cab2006-02-07 06:49:14 -0200251 mutex_unlock(&av7110->dcomlock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700252
Oliver Endriss66190a22006-01-09 15:32:42 -0200253 if (newloops == av7110->arm_loops || av7110->arm_errors > 3) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700254 printk(KERN_ERR "dvb-ttpci: ARM crashed @ card %d\n",
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -0700255 av7110->dvb_adapter.num);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700256
Oliver Endriss66190a22006-01-09 15:32:42 -0200257 recover_arm(av7110);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700258
Ingo Molnar3593cab2006-02-07 06:49:14 -0200259 if (mutex_lock_interruptible(&av7110->dcomlock))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700260 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700261 newloops = rdebi(av7110, DEBINOSWAP, STATUS_LOOPS, 0, 2) - 1;
Ingo Molnar3593cab2006-02-07 06:49:14 -0200262 mutex_unlock(&av7110->dcomlock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700263 }
264 av7110->arm_loops = newloops;
Oliver Endriss66190a22006-01-09 15:32:42 -0200265 av7110->arm_errors = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700266 }
267
268 av7110->arm_thread = NULL;
269 return 0;
270}
271
272
Linus Torvalds1da177e2005-04-16 15:20:36 -0700273/****************************************************************************
274 * IRQ handling
275 ****************************************************************************/
276
277static int DvbDmxFilterCallback(u8 *buffer1, size_t buffer1_len,
278 u8 *buffer2, size_t buffer2_len,
279 struct dvb_demux_filter *dvbdmxfilter,
280 enum dmx_success success,
281 struct av7110 *av7110)
282{
283 if (!dvbdmxfilter->feed->demux->dmx.frontend)
284 return 0;
285 if (dvbdmxfilter->feed->demux->dmx.frontend->source == DMX_MEMORY_FE)
286 return 0;
287
288 switch (dvbdmxfilter->type) {
289 case DMX_TYPE_SEC:
290 if ((((buffer1[1] << 8) | buffer1[2]) & 0xfff) + 3 != buffer1_len)
291 return 0;
292 if (dvbdmxfilter->doneq) {
293 struct dmx_section_filter *filter = &dvbdmxfilter->filter;
294 int i;
295 u8 xor, neq = 0;
296
297 for (i = 0; i < DVB_DEMUX_MASK_MAX; i++) {
298 xor = filter->filter_value[i] ^ buffer1[i];
299 neq |= dvbdmxfilter->maskandnotmode[i] & xor;
300 }
301 if (!neq)
302 return 0;
303 }
304 return dvbdmxfilter->feed->cb.sec(buffer1, buffer1_len,
305 buffer2, buffer2_len,
306 &dvbdmxfilter->filter,
307 DMX_OK);
308 case DMX_TYPE_TS:
309 if (!(dvbdmxfilter->feed->ts_type & TS_PACKET))
310 return 0;
311 if (dvbdmxfilter->feed->ts_type & TS_PAYLOAD_ONLY)
312 return dvbdmxfilter->feed->cb.ts(buffer1, buffer1_len,
313 buffer2, buffer2_len,
314 &dvbdmxfilter->feed->feed.ts,
315 DMX_OK);
316 else
317 av7110_p2t_write(buffer1, buffer1_len,
318 dvbdmxfilter->feed->pid,
319 &av7110->p2t_filter[dvbdmxfilter->index]);
320 default:
321 return 0;
322 }
323}
324
325
326//#define DEBUG_TIMING
327static inline void print_time(char *s)
328{
329#ifdef DEBUG_TIMING
330 struct timeval tv;
331 do_gettimeofday(&tv);
332 printk("%s: %d.%d\n", s, (int)tv.tv_sec, (int)tv.tv_usec);
333#endif
334}
335
336#define DEBI_READ 0
337#define DEBI_WRITE 1
338static inline void start_debi_dma(struct av7110 *av7110, int dir,
339 unsigned long addr, unsigned int len)
340{
341 dprintk(8, "%c %08lx %u\n", dir == DEBI_READ ? 'R' : 'W', addr, len);
342 if (saa7146_wait_for_debi_done(av7110->dev, 0)) {
343 printk(KERN_ERR "%s: saa7146_wait_for_debi_done timed out\n", __FUNCTION__);
344 return;
345 }
346
347 SAA7146_ISR_CLEAR(av7110->dev, MASK_19); /* for good measure */
348 SAA7146_IER_ENABLE(av7110->dev, MASK_19);
349 if (len < 5)
350 len = 5; /* we want a real DEBI DMA */
351 if (dir == DEBI_WRITE)
352 iwdebi(av7110, DEBISWAB, addr, 0, (len + 3) & ~3);
353 else
354 irdebi(av7110, DEBISWAB, addr, 0, len);
355}
356
357static void debiirq(unsigned long data)
358{
359 struct av7110 *av7110 = (struct av7110 *) data;
360 int type = av7110->debitype;
361 int handle = (type >> 8) & 0x1f;
362 unsigned int xfer = 0;
363
364 print_time("debi");
365 dprintk(4, "type 0x%04x\n", type);
366
367 if (type == -1) {
368 printk("DEBI irq oops @ %ld, psr:0x%08x, ssr:0x%08x\n",
369 jiffies, saa7146_read(av7110->dev, PSR),
370 saa7146_read(av7110->dev, SSR));
371 goto debi_done;
372 }
373 av7110->debitype = -1;
374
375 switch (type & 0xff) {
376
377 case DATA_TS_RECORD:
378 dvb_dmx_swfilter_packets(&av7110->demux,
379 (const u8 *) av7110->debi_virt,
380 av7110->debilen / 188);
381 xfer = RX_BUFF;
382 break;
383
384 case DATA_PES_RECORD:
385 if (av7110->demux.recording)
386 av7110_record_cb(&av7110->p2t[handle],
387 (u8 *) av7110->debi_virt,
388 av7110->debilen);
389 xfer = RX_BUFF;
390 break;
391
392 case DATA_IPMPE:
393 case DATA_FSECTION:
394 case DATA_PIPING:
395 if (av7110->handle2filter[handle])
396 DvbDmxFilterCallback((u8 *)av7110->debi_virt,
397 av7110->debilen, NULL, 0,
398 av7110->handle2filter[handle],
399 DMX_OK, av7110);
400 xfer = RX_BUFF;
401 break;
402
403 case DATA_CI_GET:
404 {
405 u8 *data = av7110->debi_virt;
406
407 if ((data[0] < 2) && data[2] == 0xff) {
408 int flags = 0;
409 if (data[5] > 0)
410 flags |= CA_CI_MODULE_PRESENT;
411 if (data[5] > 5)
412 flags |= CA_CI_MODULE_READY;
413 av7110->ci_slot[data[0]].flags = flags;
414 } else
415 ci_get_data(&av7110->ci_rbuffer,
416 av7110->debi_virt,
417 av7110->debilen);
418 xfer = RX_BUFF;
419 break;
420 }
421
422 case DATA_COMMON_INTERFACE:
423 CI_handle(av7110, (u8 *)av7110->debi_virt, av7110->debilen);
424#if 0
425 {
426 int i;
427
428 printk("av7110%d: ", av7110->num);
429 printk("%02x ", *(u8 *)av7110->debi_virt);
430 printk("%02x ", *(1+(u8 *)av7110->debi_virt));
431 for (i = 2; i < av7110->debilen; i++)
432 printk("%02x ", (*(i+(unsigned char *)av7110->debi_virt)));
433 for (i = 2; i < av7110->debilen; i++)
434 printk("%c", chtrans(*(i+(unsigned char *)av7110->debi_virt)));
435
436 printk("\n");
437 }
438#endif
439 xfer = RX_BUFF;
440 break;
441
442 case DATA_DEBUG_MESSAGE:
443 ((s8*)av7110->debi_virt)[Reserved_SIZE - 1] = 0;
444 printk("%s\n", (s8 *) av7110->debi_virt);
445 xfer = RX_BUFF;
446 break;
447
448 case DATA_CI_PUT:
449 dprintk(4, "debi DATA_CI_PUT\n");
450 case DATA_MPEG_PLAY:
451 dprintk(4, "debi DATA_MPEG_PLAY\n");
452 case DATA_BMP_LOAD:
453 dprintk(4, "debi DATA_BMP_LOAD\n");
454 xfer = TX_BUFF;
455 break;
456 default:
457 break;
458 }
459debi_done:
460 spin_lock(&av7110->debilock);
461 if (xfer)
462 iwdebi(av7110, DEBINOSWAP, xfer, 0, 2);
463 ARM_ClearMailBox(av7110);
464 spin_unlock(&av7110->debilock);
465}
466
467/* irq from av7110 firmware writing the mailbox register in the DPRAM */
468static void gpioirq(unsigned long data)
469{
470 struct av7110 *av7110 = (struct av7110 *) data;
471 u32 rxbuf, txbuf;
472 int len;
473
474 if (av7110->debitype != -1)
475 /* we shouldn't get any irq while a debi xfer is running */
476 printk("dvb-ttpci: GPIO0 irq oops @ %ld, psr:0x%08x, ssr:0x%08x\n",
477 jiffies, saa7146_read(av7110->dev, PSR),
478 saa7146_read(av7110->dev, SSR));
479
480 if (saa7146_wait_for_debi_done(av7110->dev, 0)) {
481 printk(KERN_ERR "%s: saa7146_wait_for_debi_done timed out\n", __FUNCTION__);
482 BUG(); /* maybe we should try resetting the debi? */
483 }
484
485 spin_lock(&av7110->debilock);
486 ARM_ClearIrq(av7110);
487
488 /* see what the av7110 wants */
489 av7110->debitype = irdebi(av7110, DEBINOSWAP, IRQ_STATE, 0, 2);
490 av7110->debilen = irdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);
491 rxbuf = irdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
492 txbuf = irdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);
493 len = (av7110->debilen + 3) & ~3;
494
495 print_time("gpio");
496 dprintk(8, "GPIO0 irq 0x%04x %d\n", av7110->debitype, av7110->debilen);
497
498 switch (av7110->debitype & 0xff) {
499
500 case DATA_TS_PLAY:
501 case DATA_PES_PLAY:
502 break;
503
504 case DATA_MPEG_VIDEO_EVENT:
505 {
506 u32 h_ar;
507 struct video_event event;
508
509 av7110->video_size.w = irdebi(av7110, DEBINOSWAP, STATUS_MPEG_WIDTH, 0, 2);
510 h_ar = irdebi(av7110, DEBINOSWAP, STATUS_MPEG_HEIGHT_AR, 0, 2);
511
512 iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);
513 iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
514
515 av7110->video_size.h = h_ar & 0xfff;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700516
517 event.type = VIDEO_EVENT_SIZE_CHANGED;
518 event.u.size.w = av7110->video_size.w;
519 event.u.size.h = av7110->video_size.h;
520 switch ((h_ar >> 12) & 0xf)
521 {
522 case 3:
523 av7110->video_size.aspect_ratio = VIDEO_FORMAT_16_9;
524 event.u.size.aspect_ratio = VIDEO_FORMAT_16_9;
525 av7110->videostate.video_format = VIDEO_FORMAT_16_9;
526 break;
527 case 4:
528 av7110->video_size.aspect_ratio = VIDEO_FORMAT_221_1;
529 event.u.size.aspect_ratio = VIDEO_FORMAT_221_1;
530 av7110->videostate.video_format = VIDEO_FORMAT_221_1;
531 break;
532 default:
533 av7110->video_size.aspect_ratio = VIDEO_FORMAT_4_3;
534 event.u.size.aspect_ratio = VIDEO_FORMAT_4_3;
535 av7110->videostate.video_format = VIDEO_FORMAT_4_3;
536 }
Oliver Endriss66190a22006-01-09 15:32:42 -0200537
538 dprintk(8, "GPIO0 irq: DATA_MPEG_VIDEO_EVENT: w/h/ar = %u/%u/%u\n",
539 av7110->video_size.w, av7110->video_size.h,
540 av7110->video_size.aspect_ratio);
541
Linus Torvalds1da177e2005-04-16 15:20:36 -0700542 dvb_video_add_event(av7110, &event);
543 break;
544 }
545
546 case DATA_CI_PUT:
547 {
548 int avail;
549 struct dvb_ringbuffer *cibuf = &av7110->ci_wbuffer;
550
551 avail = dvb_ringbuffer_avail(cibuf);
552 if (avail <= 2) {
553 iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);
554 iwdebi(av7110, DEBINOSWAP, TX_LEN, 0, 2);
555 iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);
556 break;
557 }
558 len = DVB_RINGBUFFER_PEEK(cibuf, 0) << 8;
559 len |= DVB_RINGBUFFER_PEEK(cibuf, 1);
560 if (avail < len + 2) {
561 iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);
562 iwdebi(av7110, DEBINOSWAP, TX_LEN, 0, 2);
563 iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);
564 break;
565 }
566 DVB_RINGBUFFER_SKIP(cibuf, 2);
567
568 dvb_ringbuffer_read(cibuf, av7110->debi_virt, len, 0);
569
570 iwdebi(av7110, DEBINOSWAP, TX_LEN, len, 2);
571 iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, len, 2);
572 dprintk(8, "DMA: CI\n");
573 start_debi_dma(av7110, DEBI_WRITE, DPRAM_BASE + txbuf, len);
574 spin_unlock(&av7110->debilock);
575 wake_up(&cibuf->queue);
576 return;
577 }
578
579 case DATA_MPEG_PLAY:
580 if (!av7110->playing) {
581 iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);
582 iwdebi(av7110, DEBINOSWAP, TX_LEN, 0, 2);
583 iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);
584 break;
585 }
586 len = 0;
587 if (av7110->debitype & 0x100) {
588 spin_lock(&av7110->aout.lock);
589 len = av7110_pes_play(av7110->debi_virt, &av7110->aout, 2048);
590 spin_unlock(&av7110->aout.lock);
591 }
592 if (len <= 0 && (av7110->debitype & 0x200)
593 &&av7110->videostate.play_state != VIDEO_FREEZED) {
594 spin_lock(&av7110->avout.lock);
595 len = av7110_pes_play(av7110->debi_virt, &av7110->avout, 2048);
596 spin_unlock(&av7110->avout.lock);
597 }
598 if (len <= 0) {
599 iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);
600 iwdebi(av7110, DEBINOSWAP, TX_LEN, 0, 2);
601 iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);
602 break;
603 }
604 dprintk(8, "GPIO0 PES_PLAY len=%04x\n", len);
605 iwdebi(av7110, DEBINOSWAP, TX_LEN, len, 2);
606 iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, len, 2);
607 dprintk(8, "DMA: MPEG_PLAY\n");
608 start_debi_dma(av7110, DEBI_WRITE, DPRAM_BASE + txbuf, len);
609 spin_unlock(&av7110->debilock);
610 return;
611
612 case DATA_BMP_LOAD:
613 len = av7110->debilen;
614 dprintk(8, "gpio DATA_BMP_LOAD len %d\n", len);
615 if (!len) {
616 av7110->bmp_state = BMP_LOADED;
617 iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);
618 iwdebi(av7110, DEBINOSWAP, TX_LEN, 0, 2);
619 iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);
620 wake_up(&av7110->bmpq);
621 dprintk(8, "gpio DATA_BMP_LOAD done\n");
622 break;
623 }
624 if (len > av7110->bmplen)
625 len = av7110->bmplen;
626 if (len > 2 * 1024)
627 len = 2 * 1024;
628 iwdebi(av7110, DEBINOSWAP, TX_LEN, len, 2);
629 iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, len, 2);
630 memcpy(av7110->debi_virt, av7110->bmpbuf+av7110->bmpp, len);
631 av7110->bmpp += len;
632 av7110->bmplen -= len;
633 dprintk(8, "gpio DATA_BMP_LOAD DMA len %d\n", len);
634 start_debi_dma(av7110, DEBI_WRITE, DPRAM_BASE+txbuf, len);
635 spin_unlock(&av7110->debilock);
636 return;
637
638 case DATA_CI_GET:
639 case DATA_COMMON_INTERFACE:
640 case DATA_FSECTION:
641 case DATA_IPMPE:
642 case DATA_PIPING:
643 if (!len || len > 4 * 1024) {
644 iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
645 break;
646 }
647 /* fall through */
648
649 case DATA_TS_RECORD:
650 case DATA_PES_RECORD:
651 dprintk(8, "DMA: TS_REC etc.\n");
652 start_debi_dma(av7110, DEBI_READ, DPRAM_BASE+rxbuf, len);
653 spin_unlock(&av7110->debilock);
654 return;
655
656 case DATA_DEBUG_MESSAGE:
657 if (!len || len > 0xff) {
658 iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
659 break;
660 }
661 start_debi_dma(av7110, DEBI_READ, Reserved, len);
662 spin_unlock(&av7110->debilock);
663 return;
664
665 case DATA_IRCOMMAND:
Oliver Endriss03388ae2005-09-09 13:03:12 -0700666 if (av7110->ir_handler)
667 av7110->ir_handler(av7110,
668 swahw32(irdebi(av7110, DEBINOSWAP, Reserved, 0, 4)));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700669 iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
670 break;
671
672 default:
673 printk("dvb-ttpci: gpioirq unknown type=%d len=%d\n",
674 av7110->debitype, av7110->debilen);
675 break;
676 }
677 av7110->debitype = -1;
678 ARM_ClearMailBox(av7110);
679 spin_unlock(&av7110->debilock);
680}
681
682
683#ifdef CONFIG_DVB_AV7110_OSD
684static int dvb_osd_ioctl(struct inode *inode, struct file *file,
685 unsigned int cmd, void *parg)
686{
687 struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;
688 struct av7110 *av7110 = (struct av7110 *) dvbdev->priv;
689
690 dprintk(4, "%p\n", av7110);
691
692 if (cmd == OSD_SEND_CMD)
693 return av7110_osd_cmd(av7110, (osd_cmd_t *) parg);
694 if (cmd == OSD_GET_CAPABILITY)
695 return av7110_osd_capability(av7110, (osd_cap_t *) parg);
696
697 return -EINVAL;
698}
699
700
701static struct file_operations dvb_osd_fops = {
702 .owner = THIS_MODULE,
703 .ioctl = dvb_generic_ioctl,
704 .open = dvb_generic_open,
705 .release = dvb_generic_release,
706};
707
708static struct dvb_device dvbdev_osd = {
709 .priv = NULL,
710 .users = 1,
711 .writers = 1,
712 .fops = &dvb_osd_fops,
713 .kernel_ioctl = dvb_osd_ioctl,
714};
715#endif /* CONFIG_DVB_AV7110_OSD */
716
717
718static inline int SetPIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid,
719 u16 subpid, u16 pcrpid)
720{
Dr. Werner Fink47f36922006-01-09 15:25:07 -0200721 u16 aflags = 0;
722
Linus Torvalds1da177e2005-04-16 15:20:36 -0700723 dprintk(4, "%p\n", av7110);
724
725 if (vpid == 0x1fff || apid == 0x1fff ||
726 ttpid == 0x1fff || subpid == 0x1fff || pcrpid == 0x1fff) {
727 vpid = apid = ttpid = subpid = pcrpid = 0;
728 av7110->pids[DMX_PES_VIDEO] = 0;
729 av7110->pids[DMX_PES_AUDIO] = 0;
730 av7110->pids[DMX_PES_TELETEXT] = 0;
731 av7110->pids[DMX_PES_PCR] = 0;
732 }
733
Dr. Werner Fink47f36922006-01-09 15:25:07 -0200734 if (av7110->audiostate.bypass_mode)
735 aflags |= 0x8000;
736
737 return av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, MultiPID, 6,
738 pcrpid, vpid, apid, ttpid, subpid, aflags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700739}
740
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700741int ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700742 u16 subpid, u16 pcrpid)
743{
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700744 int ret = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700745 dprintk(4, "%p\n", av7110);
746
Ingo Molnar3593cab2006-02-07 06:49:14 -0200747 if (mutex_lock_interruptible(&av7110->pid_mutex))
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700748 return -ERESTARTSYS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700749
750 if (!(vpid & 0x8000))
751 av7110->pids[DMX_PES_VIDEO] = vpid;
752 if (!(apid & 0x8000))
753 av7110->pids[DMX_PES_AUDIO] = apid;
754 if (!(ttpid & 0x8000))
755 av7110->pids[DMX_PES_TELETEXT] = ttpid;
756 if (!(pcrpid & 0x8000))
757 av7110->pids[DMX_PES_PCR] = pcrpid;
758
759 av7110->pids[DMX_PES_SUBTITLE] = 0;
760
761 if (av7110->fe_synced) {
762 pcrpid = av7110->pids[DMX_PES_PCR];
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700763 ret = SetPIDs(av7110, vpid, apid, ttpid, subpid, pcrpid);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700764 }
765
Ingo Molnar3593cab2006-02-07 06:49:14 -0200766 mutex_unlock(&av7110->pid_mutex);
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700767 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700768}
769
770
771/******************************************************************************
772 * hardware filter functions
773 ******************************************************************************/
774
775static int StartHWFilter(struct dvb_demux_filter *dvbdmxfilter)
776{
777 struct dvb_demux_feed *dvbdmxfeed = dvbdmxfilter->feed;
778 struct av7110 *av7110 = (struct av7110 *) dvbdmxfeed->demux->priv;
779 u16 buf[20];
780 int ret, i;
781 u16 handle;
782// u16 mode = 0x0320;
783 u16 mode = 0xb96a;
784
785 dprintk(4, "%p\n", av7110);
786
787 if (dvbdmxfilter->type == DMX_TYPE_SEC) {
788 if (hw_sections) {
789 buf[4] = (dvbdmxfilter->filter.filter_value[0] << 8) |
790 dvbdmxfilter->maskandmode[0];
791 for (i = 3; i < 18; i++)
792 buf[i + 4 - 2] =
793 (dvbdmxfilter->filter.filter_value[i] << 8) |
794 dvbdmxfilter->maskandmode[i];
795 mode = 4;
796 }
797 } else if ((dvbdmxfeed->ts_type & TS_PACKET) &&
798 !(dvbdmxfeed->ts_type & TS_PAYLOAD_ONLY)) {
799 av7110_p2t_init(&av7110->p2t_filter[dvbdmxfilter->index], dvbdmxfeed);
800 }
801
802 buf[0] = (COMTYPE_PID_FILTER << 8) + AddPIDFilter;
803 buf[1] = 16;
804 buf[2] = dvbdmxfeed->pid;
805 buf[3] = mode;
806
807 ret = av7110_fw_request(av7110, buf, 20, &handle, 1);
808 if (ret != 0 || handle >= 32) {
809 printk("dvb-ttpci: %s error buf %04x %04x %04x %04x "
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700810 "ret %d handle %04x\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700811 __FUNCTION__, buf[0], buf[1], buf[2], buf[3],
812 ret, handle);
813 dvbdmxfilter->hw_handle = 0xffff;
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700814 if (!ret)
815 ret = -1;
816 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700817 }
818
819 av7110->handle2filter[handle] = dvbdmxfilter;
820 dvbdmxfilter->hw_handle = handle;
821
822 return ret;
823}
824
825static int StopHWFilter(struct dvb_demux_filter *dvbdmxfilter)
826{
827 struct av7110 *av7110 = (struct av7110 *) dvbdmxfilter->feed->demux->priv;
828 u16 buf[3];
829 u16 answ[2];
830 int ret;
831 u16 handle;
832
833 dprintk(4, "%p\n", av7110);
834
835 handle = dvbdmxfilter->hw_handle;
836 if (handle >= 32) {
837 printk("%s tried to stop invalid filter %04x, filter type = %x\n",
838 __FUNCTION__, handle, dvbdmxfilter->type);
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700839 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700840 }
841
842 av7110->handle2filter[handle] = NULL;
843
844 buf[0] = (COMTYPE_PID_FILTER << 8) + DelPIDFilter;
845 buf[1] = 1;
846 buf[2] = handle;
847 ret = av7110_fw_request(av7110, buf, 3, answ, 2);
848 if (ret != 0 || answ[1] != handle) {
849 printk("dvb-ttpci: %s error cmd %04x %04x %04x ret %x "
850 "resp %04x %04x pid %d\n",
851 __FUNCTION__, buf[0], buf[1], buf[2], ret,
852 answ[0], answ[1], dvbdmxfilter->feed->pid);
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700853 if (!ret)
854 ret = -1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700855 }
856 return ret;
857}
858
859
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700860static int dvb_feed_start_pid(struct dvb_demux_feed *dvbdmxfeed)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700861{
862 struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
863 struct av7110 *av7110 = (struct av7110 *) dvbdmx->priv;
864 u16 *pid = dvbdmx->pids, npids[5];
865 int i;
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700866 int ret = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700867
868 dprintk(4, "%p\n", av7110);
869
870 npids[0] = npids[1] = npids[2] = npids[3] = npids[4] = 0xffff;
871 i = dvbdmxfeed->pes_type;
872 npids[i] = (pid[i]&0x8000) ? 0 : pid[i];
873 if ((i == 2) && npids[i] && (dvbdmxfeed->ts_type & TS_PACKET)) {
874 npids[i] = 0;
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700875 ret = ChangePIDs(av7110, npids[1], npids[0], npids[2], npids[3], npids[4]);
876 if (!ret)
877 ret = StartHWFilter(dvbdmxfeed->filter);
878 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700879 }
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700880 if (dvbdmxfeed->pes_type <= 2 || dvbdmxfeed->pes_type == 4) {
881 ret = ChangePIDs(av7110, npids[1], npids[0], npids[2], npids[3], npids[4]);
882 if (ret)
883 return ret;
884 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700885
886 if (dvbdmxfeed->pes_type < 2 && npids[0])
887 if (av7110->fe_synced)
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700888 {
889 ret = av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, Scan, 0);
890 if (ret)
891 return ret;
892 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700893
894 if ((dvbdmxfeed->ts_type & TS_PACKET)) {
895 if (dvbdmxfeed->pes_type == 0 && !(dvbdmx->pids[0] & 0x8000))
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700896 ret = av7110_av_start_record(av7110, RP_AUDIO, dvbdmxfeed);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700897 if (dvbdmxfeed->pes_type == 1 && !(dvbdmx->pids[1] & 0x8000))
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700898 ret = av7110_av_start_record(av7110, RP_VIDEO, dvbdmxfeed);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700899 }
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700900 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700901}
902
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700903static int dvb_feed_stop_pid(struct dvb_demux_feed *dvbdmxfeed)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700904{
905 struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
906 struct av7110 *av7110 = (struct av7110 *) dvbdmx->priv;
907 u16 *pid = dvbdmx->pids, npids[5];
908 int i;
909
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700910 int ret = 0;
911
Linus Torvalds1da177e2005-04-16 15:20:36 -0700912 dprintk(4, "%p\n", av7110);
913
914 if (dvbdmxfeed->pes_type <= 1) {
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700915 ret = av7110_av_stop(av7110, dvbdmxfeed->pes_type ? RP_VIDEO : RP_AUDIO);
916 if (ret)
917 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700918 if (!av7110->rec_mode)
919 dvbdmx->recording = 0;
920 if (!av7110->playing)
921 dvbdmx->playing = 0;
922 }
923 npids[0] = npids[1] = npids[2] = npids[3] = npids[4] = 0xffff;
924 i = dvbdmxfeed->pes_type;
925 switch (i) {
926 case 2: //teletext
927 if (dvbdmxfeed->ts_type & TS_PACKET)
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700928 ret = StopHWFilter(dvbdmxfeed->filter);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700929 npids[2] = 0;
930 break;
931 case 0:
932 case 1:
933 case 4:
934 if (!pids_off)
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700935 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700936 npids[i] = (pid[i]&0x8000) ? 0 : pid[i];
937 break;
938 }
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700939 if (!ret)
940 ret = ChangePIDs(av7110, npids[1], npids[0], npids[2], npids[3], npids[4]);
941 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700942}
943
944static int av7110_start_feed(struct dvb_demux_feed *feed)
945{
946 struct dvb_demux *demux = feed->demux;
947 struct av7110 *av7110 = demux->priv;
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700948 int ret = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700949
950 dprintk(4, "%p\n", av7110);
951
952 if (!demux->dmx.frontend)
953 return -EINVAL;
954
955 if (feed->pid > 0x1fff)
956 return -EINVAL;
957
958 if (feed->type == DMX_TYPE_TS) {
959 if ((feed->ts_type & TS_DECODER) &&
960 (feed->pes_type < DMX_TS_PES_OTHER)) {
961 switch (demux->dmx.frontend->source) {
962 case DMX_MEMORY_FE:
963 if (feed->ts_type & TS_DECODER)
964 if (feed->pes_type < 2 &&
965 !(demux->pids[0] & 0x8000) &&
966 !(demux->pids[1] & 0x8000)) {
967 dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout);
968 dvb_ringbuffer_flush_spinlock_wakeup(&av7110->aout);
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700969 ret = av7110_av_start_play(av7110,RP_AV);
970 if (!ret)
971 demux->playing = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700972 }
973 break;
974 default:
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700975 ret = dvb_feed_start_pid(feed);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700976 break;
977 }
978 } else if ((feed->ts_type & TS_PACKET) &&
979 (demux->dmx.frontend->source != DMX_MEMORY_FE)) {
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700980 ret = StartHWFilter(feed->filter);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700981 }
982 }
983
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700984 else if (feed->type == DMX_TYPE_SEC) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700985 int i;
986
987 for (i = 0; i < demux->filternum; i++) {
988 if (demux->filter[i].state != DMX_STATE_READY)
989 continue;
990 if (demux->filter[i].type != DMX_TYPE_SEC)
991 continue;
992 if (demux->filter[i].filter.parent != &feed->feed.sec)
993 continue;
994 demux->filter[i].state = DMX_STATE_GO;
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700995 if (demux->dmx.frontend->source != DMX_MEMORY_FE) {
996 ret = StartHWFilter(&demux->filter[i]);
997 if (ret)
998 break;
999 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001000 }
1001 }
1002
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001003 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001004}
1005
1006
1007static int av7110_stop_feed(struct dvb_demux_feed *feed)
1008{
1009 struct dvb_demux *demux = feed->demux;
1010 struct av7110 *av7110 = demux->priv;
Johannes Stezenbach12ba0502005-07-07 17:58:00 -07001011 int i, rc, ret = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001012 dprintk(4, "%p\n", av7110);
1013
1014 if (feed->type == DMX_TYPE_TS) {
1015 if (feed->ts_type & TS_DECODER) {
1016 if (feed->pes_type >= DMX_TS_PES_OTHER ||
1017 !demux->pesfilter[feed->pes_type])
1018 return -EINVAL;
1019 demux->pids[feed->pes_type] |= 0x8000;
1020 demux->pesfilter[feed->pes_type] = NULL;
1021 }
1022 if (feed->ts_type & TS_DECODER &&
1023 feed->pes_type < DMX_TS_PES_OTHER) {
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001024 ret = dvb_feed_stop_pid(feed);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001025 } else
1026 if ((feed->ts_type & TS_PACKET) &&
1027 (demux->dmx.frontend->source != DMX_MEMORY_FE))
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001028 ret = StopHWFilter(feed->filter);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001029 }
1030
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001031 if (!ret && feed->type == DMX_TYPE_SEC) {
Johannes Stezenbach12ba0502005-07-07 17:58:00 -07001032 for (i = 0; i<demux->filternum; i++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001033 if (demux->filter[i].state == DMX_STATE_GO &&
1034 demux->filter[i].filter.parent == &feed->feed.sec) {
1035 demux->filter[i].state = DMX_STATE_READY;
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001036 if (demux->dmx.frontend->source != DMX_MEMORY_FE) {
Johannes Stezenbach12ba0502005-07-07 17:58:00 -07001037 rc = StopHWFilter(&demux->filter[i]);
1038 if (!ret)
1039 ret = rc;
1040 /* keep going, stop as many filters as possible */
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001041 }
Johannes Stezenbach12ba0502005-07-07 17:58:00 -07001042 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001043 }
1044 }
1045
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001046 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001047}
1048
1049
1050static void restart_feeds(struct av7110 *av7110)
1051{
1052 struct dvb_demux *dvbdmx = &av7110->demux;
1053 struct dvb_demux_feed *feed;
1054 int mode;
Oliver Endriss66190a22006-01-09 15:32:42 -02001055 int i, j;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001056
1057 dprintk(4, "%p\n", av7110);
1058
1059 mode = av7110->playing;
1060 av7110->playing = 0;
1061 av7110->rec_mode = 0;
1062
Oliver Endriss66190a22006-01-09 15:32:42 -02001063 for (i = 0; i < dvbdmx->feednum; i++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001064 feed = &dvbdmx->feed[i];
Oliver Endriss66190a22006-01-09 15:32:42 -02001065 if (feed->state == DMX_STATE_GO) {
1066 if (feed->type == DMX_TYPE_SEC) {
1067 for (j = 0; j < dvbdmx->filternum; j++) {
1068 if (dvbdmx->filter[j].type != DMX_TYPE_SEC)
1069 continue;
1070 if (dvbdmx->filter[j].filter.parent != &feed->feed.sec)
1071 continue;
1072 if (dvbdmx->filter[j].state == DMX_STATE_GO)
1073 dvbdmx->filter[j].state = DMX_STATE_READY;
1074 }
1075 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001076 av7110_start_feed(feed);
Oliver Endriss66190a22006-01-09 15:32:42 -02001077 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001078 }
1079
1080 if (mode)
1081 av7110_av_start_play(av7110, mode);
1082}
1083
1084static int dvb_get_stc(struct dmx_demux *demux, unsigned int num,
1085 uint64_t *stc, unsigned int *base)
1086{
1087 int ret;
1088 u16 fwstc[4];
1089 u16 tag = ((COMTYPE_REQUEST << 8) + ReqSTC);
1090 struct dvb_demux *dvbdemux;
1091 struct av7110 *av7110;
1092
1093 /* pointer casting paranoia... */
Eric Sesterhennae246012006-03-13 13:17:11 -03001094 BUG_ON(!demux);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001095 dvbdemux = (struct dvb_demux *) demux->priv;
Eric Sesterhennae246012006-03-13 13:17:11 -03001096 BUG_ON(!dvbdemux);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001097 av7110 = (struct av7110 *) dvbdemux->priv;
1098
1099 dprintk(4, "%p\n", av7110);
1100
1101 if (num != 0)
1102 return -EINVAL;
1103
1104 ret = av7110_fw_request(av7110, &tag, 0, fwstc, 4);
1105 if (ret) {
1106 printk(KERN_ERR "%s: av7110_fw_request error\n", __FUNCTION__);
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001107 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001108 }
1109 dprintk(2, "fwstc = %04hx %04hx %04hx %04hx\n",
1110 fwstc[0], fwstc[1], fwstc[2], fwstc[3]);
1111
1112 *stc = (((uint64_t) ((fwstc[3] & 0x8000) >> 15)) << 32) |
1113 (((uint64_t) fwstc[1]) << 16) | ((uint64_t) fwstc[0]);
1114 *base = 1;
1115
1116 dprintk(4, "stc = %lu\n", (unsigned long)*stc);
1117
1118 return 0;
1119}
1120
1121
1122/******************************************************************************
1123 * SEC device file operations
1124 ******************************************************************************/
1125
1126
1127static int av7110_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
1128{
1129 struct av7110* av7110 = (struct av7110*) fe->dvb->priv;
1130
1131 switch (tone) {
1132 case SEC_TONE_ON:
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001133 return Set22K(av7110, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001134
1135 case SEC_TONE_OFF:
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001136 return Set22K(av7110, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001137
1138 default:
1139 return -EINVAL;
1140 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001141}
1142
1143static int av7110_diseqc_send_master_cmd(struct dvb_frontend* fe,
1144 struct dvb_diseqc_master_cmd* cmd)
1145{
1146 struct av7110* av7110 = fe->dvb->priv;
1147
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001148 return av7110_diseqc_send(av7110, cmd->msg_len, cmd->msg, -1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001149}
1150
1151static int av7110_diseqc_send_burst(struct dvb_frontend* fe,
1152 fe_sec_mini_cmd_t minicmd)
1153{
1154 struct av7110* av7110 = fe->dvb->priv;
1155
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001156 return av7110_diseqc_send(av7110, 0, NULL, minicmd);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001157}
1158
1159/* simplified code from budget-core.c */
1160static int stop_ts_capture(struct av7110 *budget)
1161{
1162 dprintk(2, "budget: %p\n", budget);
1163
1164 if (--budget->feeding1)
1165 return budget->feeding1;
1166 saa7146_write(budget->dev, MC1, MASK_20); /* DMA3 off */
1167 SAA7146_IER_DISABLE(budget->dev, MASK_10);
1168 SAA7146_ISR_CLEAR(budget->dev, MASK_10);
1169 return 0;
1170}
1171
1172static int start_ts_capture(struct av7110 *budget)
1173{
1174 dprintk(2, "budget: %p\n", budget);
1175
1176 if (budget->feeding1)
1177 return ++budget->feeding1;
1178 memset(budget->grabbing, 0x00, TS_HEIGHT * TS_WIDTH);
1179 budget->tsf = 0xff;
1180 budget->ttbp = 0;
1181 SAA7146_IER_ENABLE(budget->dev, MASK_10); /* VPE */
1182 saa7146_write(budget->dev, MC1, (MASK_04 | MASK_20)); /* DMA3 on */
1183 return ++budget->feeding1;
1184}
1185
1186static int budget_start_feed(struct dvb_demux_feed *feed)
1187{
1188 struct dvb_demux *demux = feed->demux;
1189 struct av7110 *budget = (struct av7110 *) demux->priv;
1190 int status;
1191
1192 dprintk(2, "av7110: %p\n", budget);
1193
1194 spin_lock(&budget->feedlock1);
1195 feed->pusi_seen = 0; /* have a clean section start */
1196 status = start_ts_capture(budget);
1197 spin_unlock(&budget->feedlock1);
1198 return status;
1199}
1200
1201static int budget_stop_feed(struct dvb_demux_feed *feed)
1202{
1203 struct dvb_demux *demux = feed->demux;
1204 struct av7110 *budget = (struct av7110 *) demux->priv;
1205 int status;
1206
1207 dprintk(2, "budget: %p\n", budget);
1208
1209 spin_lock(&budget->feedlock1);
1210 status = stop_ts_capture(budget);
1211 spin_unlock(&budget->feedlock1);
1212 return status;
1213}
1214
1215static void vpeirq(unsigned long data)
1216{
1217 struct av7110 *budget = (struct av7110 *) data;
1218 u8 *mem = (u8 *) (budget->grabbing);
1219 u32 olddma = budget->ttbp;
1220 u32 newdma = saa7146_read(budget->dev, PCI_VDP3);
1221
1222 if (!budgetpatch) {
1223 printk("av7110.c: vpeirq() called while budgetpatch disabled!"
1224 " check saa7146 IER register\n");
1225 BUG();
1226 }
1227 /* nearest lower position divisible by 188 */
1228 newdma -= newdma % 188;
1229
1230 if (newdma >= TS_BUFLEN)
1231 return;
1232
1233 budget->ttbp = newdma;
1234
1235 if (!budget->feeding1 || (newdma == olddma))
1236 return;
1237
1238#if 0
1239 /* track rps1 activity */
1240 printk("vpeirq: %02x Event Counter 1 0x%04x\n",
1241 mem[olddma],
1242 saa7146_read(budget->dev, EC1R) & 0x3fff);
1243#endif
1244
1245 if (newdma > olddma)
1246 /* no wraparound, dump olddma..newdma */
1247 dvb_dmx_swfilter_packets(&budget->demux1, mem + olddma, (newdma - olddma) / 188);
1248 else {
1249 /* wraparound, dump olddma..buflen and 0..newdma */
1250 dvb_dmx_swfilter_packets(&budget->demux1, mem + olddma, (TS_BUFLEN - olddma) / 188);
1251 dvb_dmx_swfilter_packets(&budget->demux1, mem, newdma / 188);
1252 }
1253}
1254
1255static int av7110_register(struct av7110 *av7110)
1256{
1257 int ret, i;
1258 struct dvb_demux *dvbdemux = &av7110->demux;
1259 struct dvb_demux *dvbdemux1 = &av7110->demux1;
1260
1261 dprintk(4, "%p\n", av7110);
1262
1263 if (av7110->registered)
1264 return -1;
1265
1266 av7110->registered = 1;
1267
1268 dvbdemux->priv = (void *) av7110;
1269
1270 for (i = 0; i < 32; i++)
1271 av7110->handle2filter[i] = NULL;
1272
1273 dvbdemux->filternum = 32;
1274 dvbdemux->feednum = 32;
1275 dvbdemux->start_feed = av7110_start_feed;
1276 dvbdemux->stop_feed = av7110_stop_feed;
1277 dvbdemux->write_to_decoder = av7110_write_to_decoder;
1278 dvbdemux->dmx.capabilities = (DMX_TS_FILTERING | DMX_SECTION_FILTERING |
1279 DMX_MEMORY_BASED_FILTERING);
1280
1281 dvb_dmx_init(&av7110->demux);
1282 av7110->demux.dmx.get_stc = dvb_get_stc;
1283
1284 av7110->dmxdev.filternum = 32;
1285 av7110->dmxdev.demux = &dvbdemux->dmx;
1286 av7110->dmxdev.capabilities = 0;
1287
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001288 dvb_dmxdev_init(&av7110->dmxdev, &av7110->dvb_adapter);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001289
1290 av7110->hw_frontend.source = DMX_FRONTEND_0;
1291
1292 ret = dvbdemux->dmx.add_frontend(&dvbdemux->dmx, &av7110->hw_frontend);
1293
1294 if (ret < 0)
1295 return ret;
1296
1297 av7110->mem_frontend.source = DMX_MEMORY_FE;
1298
1299 ret = dvbdemux->dmx.add_frontend(&dvbdemux->dmx, &av7110->mem_frontend);
1300
1301 if (ret < 0)
1302 return ret;
1303
1304 ret = dvbdemux->dmx.connect_frontend(&dvbdemux->dmx,
1305 &av7110->hw_frontend);
1306 if (ret < 0)
1307 return ret;
1308
1309 av7110_av_register(av7110);
1310 av7110_ca_register(av7110);
1311
1312#ifdef CONFIG_DVB_AV7110_OSD
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001313 dvb_register_device(&av7110->dvb_adapter, &av7110->osd_dev,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001314 &dvbdev_osd, av7110, DVB_DEVICE_OSD);
1315#endif
1316
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001317 dvb_net_init(&av7110->dvb_adapter, &av7110->dvb_net, &dvbdemux->dmx);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001318
1319 if (budgetpatch) {
1320 /* initialize software demux1 without its own frontend
1321 * demux1 hardware is connected to frontend0 of demux0
1322 */
1323 dvbdemux1->priv = (void *) av7110;
1324
1325 dvbdemux1->filternum = 256;
1326 dvbdemux1->feednum = 256;
1327 dvbdemux1->start_feed = budget_start_feed;
1328 dvbdemux1->stop_feed = budget_stop_feed;
1329 dvbdemux1->write_to_decoder = NULL;
1330
1331 dvbdemux1->dmx.capabilities = (DMX_TS_FILTERING | DMX_SECTION_FILTERING |
1332 DMX_MEMORY_BASED_FILTERING);
1333
1334 dvb_dmx_init(&av7110->demux1);
1335
1336 av7110->dmxdev1.filternum = 256;
1337 av7110->dmxdev1.demux = &dvbdemux1->dmx;
1338 av7110->dmxdev1.capabilities = 0;
1339
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001340 dvb_dmxdev_init(&av7110->dmxdev1, &av7110->dvb_adapter);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001341
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001342 dvb_net_init(&av7110->dvb_adapter, &av7110->dvb_net1, &dvbdemux1->dmx);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001343 printk("dvb-ttpci: additional demux1 for budget-patch registered\n");
1344 }
1345 return 0;
1346}
1347
1348
1349static void dvb_unregister(struct av7110 *av7110)
1350{
1351 struct dvb_demux *dvbdemux = &av7110->demux;
1352 struct dvb_demux *dvbdemux1 = &av7110->demux1;
1353
1354 dprintk(4, "%p\n", av7110);
1355
1356 if (!av7110->registered)
1357 return;
1358
1359 if (budgetpatch) {
1360 dvb_net_release(&av7110->dvb_net1);
1361 dvbdemux->dmx.close(&dvbdemux1->dmx);
1362 dvb_dmxdev_release(&av7110->dmxdev1);
1363 dvb_dmx_release(&av7110->demux1);
1364 }
1365
1366 dvb_net_release(&av7110->dvb_net);
1367
1368 dvbdemux->dmx.close(&dvbdemux->dmx);
1369 dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, &av7110->hw_frontend);
1370 dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, &av7110->mem_frontend);
1371
1372 dvb_dmxdev_release(&av7110->dmxdev);
1373 dvb_dmx_release(&av7110->demux);
1374
1375 if (av7110->fe != NULL)
1376 dvb_unregister_frontend(av7110->fe);
1377 dvb_unregister_device(av7110->osd_dev);
1378 av7110_av_unregister(av7110);
1379 av7110_ca_unregister(av7110);
1380}
1381
1382
1383/****************************************************************************
1384 * I2C client commands
1385 ****************************************************************************/
1386
1387int i2c_writereg(struct av7110 *av7110, u8 id, u8 reg, u8 val)
1388{
1389 u8 msg[2] = { reg, val };
1390 struct i2c_msg msgs;
1391
1392 msgs.flags = 0;
1393 msgs.addr = id / 2;
1394 msgs.len = 2;
1395 msgs.buf = msg;
1396 return i2c_transfer(&av7110->i2c_adap, &msgs, 1);
1397}
1398
1399#if 0
1400u8 i2c_readreg(struct av7110 *av7110, u8 id, u8 reg)
1401{
1402 u8 mm1[] = {0x00};
1403 u8 mm2[] = {0x00};
1404 struct i2c_msg msgs[2];
1405
1406 msgs[0].flags = 0;
1407 msgs[1].flags = I2C_M_RD;
1408 msgs[0].addr = msgs[1].addr = id / 2;
1409 mm1[0] = reg;
1410 msgs[0].len = 1; msgs[1].len = 1;
1411 msgs[0].buf = mm1; msgs[1].buf = mm2;
1412 i2c_transfer(&av7110->i2c_adap, msgs, 2);
1413
1414 return mm2[0];
1415}
1416#endif
1417
1418/****************************************************************************
1419 * INITIALIZATION
1420 ****************************************************************************/
1421
1422
1423static int check_firmware(struct av7110* av7110)
1424{
1425 u32 crc = 0, len = 0;
1426 unsigned char *ptr;
1427
1428 /* check for firmware magic */
1429 ptr = av7110->bin_fw;
1430 if (ptr[0] != 'A' || ptr[1] != 'V' ||
1431 ptr[2] != 'F' || ptr[3] != 'W') {
1432 printk("dvb-ttpci: this is not an av7110 firmware\n");
1433 return -EINVAL;
1434 }
1435 ptr += 4;
1436
1437 /* check dpram file */
1438 crc = ntohl(*(u32*) ptr);
1439 ptr += 4;
1440 len = ntohl(*(u32*) ptr);
1441 ptr += 4;
1442 if (len >= 512) {
Alexey Dobriyanbe787ac2006-03-07 22:20:23 -03001443 printk("dvb-ttpci: dpram file is way too big.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001444 return -EINVAL;
1445 }
1446 if (crc != crc32_le(0, ptr, len)) {
1447 printk("dvb-ttpci: crc32 of dpram file does not match.\n");
1448 return -EINVAL;
1449 }
1450 av7110->bin_dpram = ptr;
1451 av7110->size_dpram = len;
1452 ptr += len;
1453
1454 /* check root file */
1455 crc = ntohl(*(u32*) ptr);
1456 ptr += 4;
1457 len = ntohl(*(u32*) ptr);
1458 ptr += 4;
1459
1460 if (len <= 200000 || len >= 300000 ||
1461 len > ((av7110->bin_fw + av7110->size_fw) - ptr)) {
1462 printk("dvb-ttpci: root file has strange size (%d). aborting.\n", len);
1463 return -EINVAL;
1464 }
1465 if( crc != crc32_le(0, ptr, len)) {
1466 printk("dvb-ttpci: crc32 of root file does not match.\n");
1467 return -EINVAL;
1468 }
1469 av7110->bin_root = ptr;
1470 av7110->size_root = len;
1471 return 0;
1472}
1473
1474#ifdef CONFIG_DVB_AV7110_FIRMWARE_FILE
1475#include "av7110_firm.h"
1476static void put_firmware(struct av7110* av7110)
1477{
1478 av7110->bin_fw = NULL;
1479}
1480
1481static inline int get_firmware(struct av7110* av7110)
1482{
1483 av7110->bin_fw = dvb_ttpci_fw;
1484 av7110->size_fw = sizeof(dvb_ttpci_fw);
1485 return check_firmware(av7110);
1486}
1487#else
1488static void put_firmware(struct av7110* av7110)
1489{
1490 vfree(av7110->bin_fw);
1491}
1492
1493static int get_firmware(struct av7110* av7110)
1494{
1495 int ret;
1496 const struct firmware *fw;
1497
1498 /* request the av7110 firmware, this will block until someone uploads it */
1499 ret = request_firmware(&fw, "dvb-ttpci-01.fw", &av7110->dev->pci->dev);
1500 if (ret) {
1501 if (ret == -ENOENT) {
1502 printk(KERN_ERR "dvb-ttpci: could not load firmware,"
1503 " file not found: dvb-ttpci-01.fw\n");
Ville Skytt\ä12e66f62006-01-09 15:25:38 -02001504 printk(KERN_ERR "dvb-ttpci: usually this should be in "
1505 "/usr/lib/hotplug/firmware or /lib/firmware\n");
1506 printk(KERN_ERR "dvb-ttpci: and can be downloaded from"
Linus Torvalds1da177e2005-04-16 15:20:36 -07001507 " http://www.linuxtv.org/download/dvb/firmware/\n");
1508 } else
1509 printk(KERN_ERR "dvb-ttpci: cannot request firmware"
1510 " (error %i)\n", ret);
1511 return -EINVAL;
1512 }
1513
1514 if (fw->size <= 200000) {
1515 printk("dvb-ttpci: this firmware is way too small.\n");
1516 release_firmware(fw);
1517 return -EINVAL;
1518 }
1519
1520 /* check if the firmware is available */
1521 av7110->bin_fw = (unsigned char *) vmalloc(fw->size);
1522 if (NULL == av7110->bin_fw) {
1523 dprintk(1, "out of memory\n");
1524 release_firmware(fw);
1525 return -ENOMEM;
1526 }
1527
1528 memcpy(av7110->bin_fw, fw->data, fw->size);
1529 av7110->size_fw = fw->size;
1530 if ((ret = check_firmware(av7110)))
1531 vfree(av7110->bin_fw);
1532
1533 release_firmware(fw);
1534 return ret;
1535}
1536#endif
1537
1538
1539static int alps_bsrv2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
1540{
1541 struct av7110* av7110 = (struct av7110*) fe->dvb->priv;
1542 u8 pwr = 0;
1543 u8 buf[4];
1544 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
1545 u32 div = (params->frequency + 479500) / 125;
1546
1547 if (params->frequency > 2000000) pwr = 3;
1548 else if (params->frequency > 1800000) pwr = 2;
1549 else if (params->frequency > 1600000) pwr = 1;
1550 else if (params->frequency > 1200000) pwr = 0;
1551 else if (params->frequency >= 1100000) pwr = 1;
1552 else pwr = 2;
1553
1554 buf[0] = (div >> 8) & 0x7f;
1555 buf[1] = div & 0xff;
1556 buf[2] = ((div & 0x18000) >> 10) | 0x95;
1557 buf[3] = (pwr << 6) | 0x30;
1558
Mauro Carvalho Chehab9101e622005-12-12 00:37:24 -08001559 // NOTE: since we're using a prescaler of 2, we set the
Linus Torvalds1da177e2005-04-16 15:20:36 -07001560 // divisor frequency to 62.5kHz and divide by 125 above
1561
1562 if (i2c_transfer (&av7110->i2c_adap, &msg, 1) != 1)
1563 return -EIO;
1564 return 0;
1565}
1566
1567static struct ves1x93_config alps_bsrv2_config = {
1568 .demod_address = 0x08,
1569 .xin = 90100000UL,
1570 .invert_pwm = 0,
1571 .pll_set = alps_bsrv2_pll_set,
1572};
1573
Linus Torvalds1da177e2005-04-16 15:20:36 -07001574static int alps_tdbe2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
1575{
1576 struct av7110* av7110 = fe->dvb->priv;
1577 u32 div;
1578 u8 data[4];
1579 struct i2c_msg msg = { .addr = 0x62, .flags = 0, .buf = data, .len = sizeof(data) };
1580
1581 div = (params->frequency + 35937500 + 31250) / 62500;
1582
1583 data[0] = (div >> 8) & 0x7f;
1584 data[1] = div & 0xff;
1585 data[2] = 0x85 | ((div >> 10) & 0x60);
1586 data[3] = (params->frequency < 174000000 ? 0x88 : params->frequency < 470000000 ? 0x84 : 0x81);
1587
1588 if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1)
1589 return -EIO;
1590 return 0;
1591}
1592
1593static struct ves1820_config alps_tdbe2_config = {
1594 .demod_address = 0x09,
1595 .xin = 57840000UL,
1596 .invert = 1,
1597 .selagc = VES1820_SELAGC_SIGNAMPERR,
1598 .pll_set = alps_tdbe2_pll_set,
1599};
1600
1601
1602
1603
1604static int grundig_29504_451_pll_set(struct dvb_frontend* fe,
1605 struct dvb_frontend_parameters* params)
1606{
1607 struct av7110* av7110 = fe->dvb->priv;
1608 u32 div;
1609 u8 data[4];
1610 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
1611
1612 div = params->frequency / 125;
1613 data[0] = (div >> 8) & 0x7f;
1614 data[1] = div & 0xff;
1615 data[2] = 0x8e;
1616 data[3] = 0x00;
1617
1618 if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1)
1619 return -EIO;
1620 return 0;
1621}
1622
1623static struct tda8083_config grundig_29504_451_config = {
1624 .demod_address = 0x68,
1625 .pll_set = grundig_29504_451_pll_set,
1626};
1627
1628
1629
1630static int philips_cd1516_pll_set(struct dvb_frontend* fe,
1631 struct dvb_frontend_parameters* params)
1632{
Mauro Carvalho Chehab9101e622005-12-12 00:37:24 -08001633 struct av7110* av7110 = fe->dvb->priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001634 u32 div;
1635 u32 f = params->frequency;
1636 u8 data[4];
1637 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
1638
1639 div = (f + 36125000 + 31250) / 62500;
1640
1641 data[0] = (div >> 8) & 0x7f;
1642 data[1] = div & 0xff;
1643 data[2] = 0x8e;
1644 data[3] = (f < 174000000 ? 0xa1 : f < 470000000 ? 0x92 : 0x34);
1645
1646 if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1)
1647 return -EIO;
1648 return 0;
1649}
1650
1651static struct ves1820_config philips_cd1516_config = {
1652 .demod_address = 0x09,
1653 .xin = 57840000UL,
1654 .invert = 1,
1655 .selagc = VES1820_SELAGC_SIGNAMPERR,
1656 .pll_set = philips_cd1516_pll_set,
1657};
1658
1659
1660
1661static int alps_tdlb7_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
1662{
1663 struct av7110* av7110 = fe->dvb->priv;
1664 u32 div, pwr;
1665 u8 data[4];
1666 struct i2c_msg msg = { .addr = 0x60, .flags = 0, .buf = data, .len = sizeof(data) };
1667
1668 div = (params->frequency + 36200000) / 166666;
1669
1670 if (params->frequency <= 782000000)
1671 pwr = 1;
1672 else
1673 pwr = 2;
1674
1675 data[0] = (div >> 8) & 0x7f;
1676 data[1] = div & 0xff;
1677 data[2] = 0x85;
1678 data[3] = pwr << 6;
1679
1680 if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1)
1681 return -EIO;
1682 return 0;
1683}
1684
1685static int alps_tdlb7_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name)
1686{
1687 struct av7110* av7110 = (struct av7110*) fe->dvb->priv;
1688
1689 return request_firmware(fw, name, &av7110->dev->pci->dev);
1690}
1691
1692static struct sp8870_config alps_tdlb7_config = {
1693
1694 .demod_address = 0x71,
1695 .pll_set = alps_tdlb7_pll_set,
1696 .request_firmware = alps_tdlb7_request_firmware,
1697};
1698
1699
Andrew de Quinceydc27a162005-09-09 13:03:07 -07001700static u8 nexusca_stv0297_inittab[] = {
1701 0x80, 0x01,
1702 0x80, 0x00,
1703 0x81, 0x01,
1704 0x81, 0x00,
1705 0x00, 0x09,
1706 0x01, 0x69,
1707 0x03, 0x00,
1708 0x04, 0x00,
1709 0x07, 0x00,
1710 0x08, 0x00,
1711 0x20, 0x00,
1712 0x21, 0x40,
1713 0x22, 0x00,
1714 0x23, 0x00,
1715 0x24, 0x40,
1716 0x25, 0x88,
1717 0x30, 0xff,
1718 0x31, 0x00,
1719 0x32, 0xff,
1720 0x33, 0x00,
1721 0x34, 0x50,
1722 0x35, 0x7f,
1723 0x36, 0x00,
1724 0x37, 0x20,
1725 0x38, 0x00,
1726 0x40, 0x1c,
1727 0x41, 0xff,
1728 0x42, 0x29,
1729 0x43, 0x00,
1730 0x44, 0xff,
1731 0x45, 0x00,
1732 0x46, 0x00,
1733 0x49, 0x04,
1734 0x4a, 0x00,
1735 0x4b, 0x7b,
1736 0x52, 0x30,
1737 0x55, 0xae,
1738 0x56, 0x47,
1739 0x57, 0xe1,
1740 0x58, 0x3a,
1741 0x5a, 0x1e,
1742 0x5b, 0x34,
1743 0x60, 0x00,
1744 0x63, 0x00,
1745 0x64, 0x00,
1746 0x65, 0x00,
1747 0x66, 0x00,
1748 0x67, 0x00,
1749 0x68, 0x00,
1750 0x69, 0x00,
1751 0x6a, 0x02,
1752 0x6b, 0x00,
1753 0x70, 0xff,
1754 0x71, 0x00,
1755 0x72, 0x00,
1756 0x73, 0x00,
1757 0x74, 0x0c,
1758 0x80, 0x00,
1759 0x81, 0x00,
1760 0x82, 0x00,
1761 0x83, 0x00,
1762 0x84, 0x04,
1763 0x85, 0x80,
1764 0x86, 0x24,
1765 0x87, 0x78,
1766 0x88, 0x10,
1767 0x89, 0x00,
1768 0x90, 0x01,
1769 0x91, 0x01,
1770 0xa0, 0x04,
1771 0xa1, 0x00,
1772 0xa2, 0x00,
1773 0xb0, 0x91,
1774 0xb1, 0x0b,
1775 0xc0, 0x53,
1776 0xc1, 0x70,
1777 0xc2, 0x12,
1778 0xd0, 0x00,
1779 0xd1, 0x00,
1780 0xd2, 0x00,
1781 0xd3, 0x00,
1782 0xd4, 0x00,
1783 0xd5, 0x00,
1784 0xde, 0x00,
1785 0xdf, 0x00,
1786 0x61, 0x49,
1787 0x62, 0x0b,
1788 0x53, 0x08,
1789 0x59, 0x08,
1790 0xff, 0xff,
1791};
Linus Torvalds1da177e2005-04-16 15:20:36 -07001792
1793static int nexusca_stv0297_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
1794{
1795 struct av7110* av7110 = fe->dvb->priv;
1796 u32 div;
1797 u8 data[4];
1798 struct i2c_msg msg = { .addr = 0x63, .flags = 0, .buf = data, .len = sizeof(data) };
1799 struct i2c_msg readmsg = { .addr = 0x63, .flags = I2C_M_RD, .buf = data, .len = 1 };
1800 int i;
1801
1802 div = (params->frequency + 36150000 + 31250) / 62500;
1803
1804 data[0] = (div >> 8) & 0x7f;
1805 data[1] = div & 0xff;
1806 data[2] = 0xce;
1807
1808 if (params->frequency < 45000000)
1809 return -EINVAL;
1810 else if (params->frequency < 137000000)
1811 data[3] = 0x01;
1812 else if (params->frequency < 403000000)
1813 data[3] = 0x02;
1814 else if (params->frequency < 860000000)
1815 data[3] = 0x04;
1816 else
1817 return -EINVAL;
1818
1819 stv0297_enable_plli2c(fe);
1820 if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1) {
1821 printk("nexusca: pll transfer failed!\n");
1822 return -EIO;
1823 }
1824
1825 // wait for PLL lock
1826 for(i = 0; i < 20; i++) {
1827
1828 stv0297_enable_plli2c(fe);
1829 if (i2c_transfer(&av7110->i2c_adap, &readmsg, 1) == 1)
1830 if (data[0] & 0x40) break;
1831 msleep(10);
1832 }
1833
1834 return 0;
1835}
1836
1837static struct stv0297_config nexusca_stv0297_config = {
1838
1839 .demod_address = 0x1C,
Andrew de Quinceydc27a162005-09-09 13:03:07 -07001840 .inittab = nexusca_stv0297_inittab,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001841 .invert = 1,
1842 .pll_set = nexusca_stv0297_pll_set,
1843};
1844
1845
1846
1847static int grundig_29504_401_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
1848{
1849 struct av7110* av7110 = (struct av7110*) fe->dvb->priv;
1850 u32 div;
1851 u8 cfg, cpump, band_select;
1852 u8 data[4];
1853 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
1854
1855 div = (36125000 + params->frequency) / 166666;
1856
1857 cfg = 0x88;
1858
1859 if (params->frequency < 175000000) cpump = 2;
1860 else if (params->frequency < 390000000) cpump = 1;
1861 else if (params->frequency < 470000000) cpump = 2;
1862 else if (params->frequency < 750000000) cpump = 1;
1863 else cpump = 3;
1864
1865 if (params->frequency < 175000000) band_select = 0x0e;
1866 else if (params->frequency < 470000000) band_select = 0x05;
1867 else band_select = 0x03;
1868
1869 data[0] = (div >> 8) & 0x7f;
1870 data[1] = div & 0xff;
1871 data[2] = ((div >> 10) & 0x60) | cfg;
1872 data[3] = (cpump << 6) | band_select;
1873
1874 if (i2c_transfer (&av7110->i2c_adap, &msg, 1) != 1) return -EIO;
1875 return 0;
1876}
1877
1878static struct l64781_config grundig_29504_401_config = {
1879 .demod_address = 0x55,
1880 .pll_set = grundig_29504_401_pll_set,
1881};
1882
1883
1884
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001885static int av7110_fe_lock_fix(struct av7110* av7110, fe_status_t status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001886{
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001887 int ret = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001888 int synced = (status & FE_HAS_LOCK) ? 1 : 0;
1889
1890 av7110->fe_status = status;
1891
1892 if (av7110->fe_synced == synced)
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001893 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001894
Linus Torvalds1da177e2005-04-16 15:20:36 -07001895 if (av7110->playing)
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001896 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001897
Ingo Molnar3593cab2006-02-07 06:49:14 -02001898 if (mutex_lock_interruptible(&av7110->pid_mutex))
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001899 return -ERESTARTSYS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001900
Oliver Endriss34612152005-07-07 17:58:02 -07001901 if (synced) {
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001902 ret = SetPIDs(av7110, av7110->pids[DMX_PES_VIDEO],
Linus Torvalds1da177e2005-04-16 15:20:36 -07001903 av7110->pids[DMX_PES_AUDIO],
1904 av7110->pids[DMX_PES_TELETEXT], 0,
1905 av7110->pids[DMX_PES_PCR]);
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001906 if (!ret)
1907 ret = av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, Scan, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001908 } else {
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001909 ret = SetPIDs(av7110, 0, 0, 0, 0, 0);
1910 if (!ret) {
1911 ret = av7110_fw_cmd(av7110, COMTYPE_PID_FILTER, FlushTSQueue, 0);
1912 if (!ret)
1913 ret = av7110_wait_msgstate(av7110, GPMQBusy);
1914 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001915 }
1916
Oliver Endriss34612152005-07-07 17:58:02 -07001917 if (!ret)
1918 av7110->fe_synced = synced;
1919
Ingo Molnar3593cab2006-02-07 06:49:14 -02001920 mutex_unlock(&av7110->pid_mutex);
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001921 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001922}
1923
1924static int av7110_fe_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
1925{
1926 struct av7110* av7110 = fe->dvb->priv;
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001927
1928 int ret = av7110_fe_lock_fix(av7110, 0);
Oliver Endriss66190a22006-01-09 15:32:42 -02001929 if (!ret) {
1930 av7110->saved_fe_params = *params;
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001931 ret = av7110->fe_set_frontend(fe, params);
Oliver Endriss66190a22006-01-09 15:32:42 -02001932 }
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001933 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001934}
1935
1936static int av7110_fe_init(struct dvb_frontend* fe)
1937{
1938 struct av7110* av7110 = fe->dvb->priv;
1939
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001940 int ret = av7110_fe_lock_fix(av7110, 0);
1941 if (!ret)
1942 ret = av7110->fe_init(fe);
1943 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001944}
1945
1946static int av7110_fe_read_status(struct dvb_frontend* fe, fe_status_t* status)
1947{
1948 struct av7110* av7110 = fe->dvb->priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001949
1950 /* call the real implementation */
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001951 int ret = av7110->fe_read_status(fe, status);
1952 if (!ret)
1953 if (((*status ^ av7110->fe_status) & FE_HAS_LOCK) && (*status & FE_HAS_LOCK))
1954 ret = av7110_fe_lock_fix(av7110, *status);
1955 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001956}
1957
1958static int av7110_fe_diseqc_reset_overload(struct dvb_frontend* fe)
1959{
1960 struct av7110* av7110 = fe->dvb->priv;
1961
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001962 int ret = av7110_fe_lock_fix(av7110, 0);
1963 if (!ret)
1964 ret = av7110->fe_diseqc_reset_overload(fe);
1965 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001966}
1967
1968static int av7110_fe_diseqc_send_master_cmd(struct dvb_frontend* fe,
1969 struct dvb_diseqc_master_cmd* cmd)
1970{
1971 struct av7110* av7110 = fe->dvb->priv;
1972
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001973 int ret = av7110_fe_lock_fix(av7110, 0);
Oliver Endriss66190a22006-01-09 15:32:42 -02001974 if (!ret) {
1975 av7110->saved_master_cmd = *cmd;
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001976 ret = av7110->fe_diseqc_send_master_cmd(fe, cmd);
Oliver Endriss66190a22006-01-09 15:32:42 -02001977 }
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001978 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001979}
1980
1981static int av7110_fe_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd)
1982{
1983 struct av7110* av7110 = fe->dvb->priv;
1984
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001985 int ret = av7110_fe_lock_fix(av7110, 0);
Oliver Endriss66190a22006-01-09 15:32:42 -02001986 if (!ret) {
1987 av7110->saved_minicmd = minicmd;
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001988 ret = av7110->fe_diseqc_send_burst(fe, minicmd);
Oliver Endriss66190a22006-01-09 15:32:42 -02001989 }
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001990 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001991}
1992
1993static int av7110_fe_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
1994{
1995 struct av7110* av7110 = fe->dvb->priv;
1996
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001997 int ret = av7110_fe_lock_fix(av7110, 0);
Oliver Endriss66190a22006-01-09 15:32:42 -02001998 if (!ret) {
1999 av7110->saved_tone = tone;
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002000 ret = av7110->fe_set_tone(fe, tone);
Oliver Endriss66190a22006-01-09 15:32:42 -02002001 }
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002002 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002003}
2004
2005static int av7110_fe_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
2006{
2007 struct av7110* av7110 = fe->dvb->priv;
2008
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002009 int ret = av7110_fe_lock_fix(av7110, 0);
Oliver Endriss66190a22006-01-09 15:32:42 -02002010 if (!ret) {
2011 av7110->saved_voltage = voltage;
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002012 ret = av7110->fe_set_voltage(fe, voltage);
Oliver Endriss66190a22006-01-09 15:32:42 -02002013 }
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002014 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002015}
2016
Peter Beutner400b7082006-01-09 15:32:43 -02002017static int av7110_fe_dishnetwork_send_legacy_command(struct dvb_frontend* fe, unsigned long cmd)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002018{
2019 struct av7110* av7110 = fe->dvb->priv;
2020
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002021 int ret = av7110_fe_lock_fix(av7110, 0);
2022 if (!ret)
2023 ret = av7110->fe_dishnetwork_send_legacy_command(fe, cmd);
2024 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002025}
2026
Oliver Endriss66190a22006-01-09 15:32:42 -02002027static void dvb_s_recover(struct av7110* av7110)
2028{
2029 av7110_fe_init(av7110->fe);
2030
2031 av7110_fe_set_voltage(av7110->fe, av7110->saved_voltage);
2032 if (av7110->saved_master_cmd.msg_len) {
2033 msleep(20);
2034 av7110_fe_diseqc_send_master_cmd(av7110->fe, &av7110->saved_master_cmd);
2035 }
2036 msleep(20);
2037 av7110_fe_diseqc_send_burst(av7110->fe, av7110->saved_minicmd);
2038 msleep(20);
2039 av7110_fe_set_tone(av7110->fe, av7110->saved_tone);
2040
2041 av7110_fe_set_frontend(av7110->fe, &av7110->saved_fe_params);
2042}
2043
Linus Torvalds1da177e2005-04-16 15:20:36 -07002044static u8 read_pwm(struct av7110* av7110)
2045{
2046 u8 b = 0xff;
2047 u8 pwm;
2048 struct i2c_msg msg[] = { { .addr = 0x50,.flags = 0,.buf = &b,.len = 1 },
2049 { .addr = 0x50,.flags = I2C_M_RD,.buf = &pwm,.len = 1} };
2050
Mauro Carvalho Chehab9101e622005-12-12 00:37:24 -08002051 if ((i2c_transfer(&av7110->i2c_adap, msg, 2) != 2) || (pwm == 0xff))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002052 pwm = 0x48;
2053
2054 return pwm;
2055}
2056
2057static int frontend_init(struct av7110 *av7110)
2058{
2059 int ret;
2060
2061 if (av7110->dev->pci->subsystem_vendor == 0x110a) {
2062 switch(av7110->dev->pci->subsystem_device) {
2063 case 0x0000: // Fujitsu/Siemens DVB-Cable (ves1820/Philips CD1516(??))
2064 av7110->fe = ves1820_attach(&philips_cd1516_config,
2065 &av7110->i2c_adap, read_pwm(av7110));
2066 break;
2067 }
2068
2069 } else if (av7110->dev->pci->subsystem_vendor == 0x13c2) {
2070 switch(av7110->dev->pci->subsystem_device) {
2071 case 0x0000: // Hauppauge/TT WinTV DVB-S rev1.X
2072 case 0x0003: // Hauppauge/TT WinTV Nexus-S Rev 2.X
2073 case 0x1002: // Hauppauge/TT WinTV DVB-S rev1.3SE
2074
2075 // try the ALPS BSRV2 first of all
2076 av7110->fe = ves1x93_attach(&alps_bsrv2_config, &av7110->i2c_adap);
2077 if (av7110->fe) {
2078 av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd;
2079 av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst;
2080 av7110->fe->ops->set_tone = av7110_set_tone;
Oliver Endriss66190a22006-01-09 15:32:42 -02002081 av7110->recover = dvb_s_recover;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002082 break;
2083 }
2084
2085 // try the ALPS BSRU6 now
2086 av7110->fe = stv0299_attach(&alps_bsru6_config, &av7110->i2c_adap);
2087 if (av7110->fe) {
2088 av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd;
2089 av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst;
2090 av7110->fe->ops->set_tone = av7110_set_tone;
Oliver Endriss66190a22006-01-09 15:32:42 -02002091 av7110->recover = dvb_s_recover;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002092 break;
2093 }
2094
2095 // Try the grundig 29504-451
Michael Krufky50c25ff2006-01-09 15:25:34 -02002096 av7110->fe = tda8083_attach(&grundig_29504_451_config, &av7110->i2c_adap);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002097 if (av7110->fe) {
2098 av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd;
2099 av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst;
2100 av7110->fe->ops->set_tone = av7110_set_tone;
Oliver Endriss66190a22006-01-09 15:32:42 -02002101 av7110->recover = dvb_s_recover;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002102 break;
2103 }
2104
2105 /* Try DVB-C cards */
2106 switch(av7110->dev->pci->subsystem_device) {
2107 case 0x0000:
2108 /* Siemens DVB-C (full-length card) VES1820/Philips CD1516 */
2109 av7110->fe = ves1820_attach(&philips_cd1516_config, &av7110->i2c_adap,
2110 read_pwm(av7110));
2111 break;
2112 case 0x0003:
2113 /* Haupauge DVB-C 2.1 VES1820/ALPS TDBE2 */
2114 av7110->fe = ves1820_attach(&alps_tdbe2_config, &av7110->i2c_adap,
2115 read_pwm(av7110));
2116 break;
2117 }
2118 break;
2119
2120 case 0x0001: // Hauppauge/TT Nexus-T premium rev1.X
2121
2122 // ALPS TDLB7
Michael Krufky50c25ff2006-01-09 15:25:34 -02002123 av7110->fe = sp8870_attach(&alps_tdlb7_config, &av7110->i2c_adap);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002124 break;
2125
2126 case 0x0002: // Hauppauge/TT DVB-C premium rev2.X
2127
Michael Krufky50c25ff2006-01-09 15:25:34 -02002128 av7110->fe = ves1820_attach(&alps_tdbe2_config, &av7110->i2c_adap, read_pwm(av7110));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002129 break;
2130
Oliver Endriss8bd63012006-02-07 06:49:11 -02002131 case 0x0004: // Galaxis DVB-S rev1.3
2132 /* ALPS BSRV2 */
2133 av7110->fe = ves1x93_attach(&alps_bsrv2_config, &av7110->i2c_adap);
2134 if (av7110->fe) {
2135 av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd;
2136 av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst;
2137 av7110->fe->ops->set_tone = av7110_set_tone;
2138 av7110->recover = dvb_s_recover;
2139 }
2140 break;
2141
Linus Torvalds1da177e2005-04-16 15:20:36 -07002142 case 0x0006: /* Fujitsu-Siemens DVB-S rev 1.6 */
2143 /* Grundig 29504-451 */
2144 av7110->fe = tda8083_attach(&grundig_29504_451_config, &av7110->i2c_adap);
2145 if (av7110->fe) {
2146 av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd;
2147 av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst;
2148 av7110->fe->ops->set_tone = av7110_set_tone;
Oliver Endriss66190a22006-01-09 15:32:42 -02002149 av7110->recover = dvb_s_recover;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002150 }
2151 break;
2152
2153 case 0x0008: // Hauppauge/TT DVB-T
2154
2155 av7110->fe = l64781_attach(&grundig_29504_401_config, &av7110->i2c_adap);
2156 break;
2157
2158 case 0x000A: // Hauppauge/TT Nexus-CA rev1.X
2159
Andrew de Quinceydc27a162005-09-09 13:03:07 -07002160 av7110->fe = stv0297_attach(&nexusca_stv0297_config, &av7110->i2c_adap);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002161 if (av7110->fe) {
2162 /* set TDA9819 into DVB mode */
2163 saa7146_setgpio(av7110->dev, 1, SAA7146_GPIO_OUTLO); // TDA9198 pin9(STD)
2164 saa7146_setgpio(av7110->dev, 3, SAA7146_GPIO_OUTLO); // TDA9198 pin30(VIF)
2165
2166 /* tuner on this needs a slower i2c bus speed */
2167 av7110->dev->i2c_bitrate = SAA7146_I2C_BUS_BIT_RATE_240;
2168 break;
2169 }
Johannes Stezenbach3dfaebd2005-05-16 21:54:19 -07002170 break;
2171
2172 case 0x000E: /* Hauppauge/TT Nexus-S rev 2.3 */
2173 /* ALPS BSBE1 */
2174 av7110->fe = stv0299_attach(&alps_bsbe1_config, &av7110->i2c_adap);
Oliver Endrisseb3daf32006-01-09 15:25:05 -02002175 if (av7110->fe) {
Oliver Endrissdb5d91e2006-02-28 10:32:25 -03002176 if (lnbp21_init(av7110->fe, &av7110->i2c_adap, 0, 0)) {
2177 printk("dvb-ttpci: LNBP21 not found!\n");
2178 if (av7110->fe->ops->release)
2179 av7110->fe->ops->release(av7110->fe);
2180 av7110->fe = NULL;
2181 } else {
2182 av7110->fe->ops->dishnetwork_send_legacy_command = NULL;
2183 av7110->recover = dvb_s_recover;
2184 }
Oliver Endrisseb3daf32006-01-09 15:25:05 -02002185 }
Johannes Stezenbach3dfaebd2005-05-16 21:54:19 -07002186 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002187 }
2188 }
2189
2190 if (!av7110->fe) {
2191 /* FIXME: propagate the failure code from the lower layers */
2192 ret = -ENOMEM;
2193 printk("dvb-ttpci: A frontend driver was not found for device %04x/%04x subsystem %04x/%04x\n",
2194 av7110->dev->pci->vendor,
2195 av7110->dev->pci->device,
2196 av7110->dev->pci->subsystem_vendor,
2197 av7110->dev->pci->subsystem_device);
2198 } else {
2199 FE_FUNC_OVERRIDE(av7110->fe->ops->init, av7110->fe_init, av7110_fe_init);
2200 FE_FUNC_OVERRIDE(av7110->fe->ops->read_status, av7110->fe_read_status, av7110_fe_read_status);
2201 FE_FUNC_OVERRIDE(av7110->fe->ops->diseqc_reset_overload, av7110->fe_diseqc_reset_overload, av7110_fe_diseqc_reset_overload);
2202 FE_FUNC_OVERRIDE(av7110->fe->ops->diseqc_send_master_cmd, av7110->fe_diseqc_send_master_cmd, av7110_fe_diseqc_send_master_cmd);
2203 FE_FUNC_OVERRIDE(av7110->fe->ops->diseqc_send_burst, av7110->fe_diseqc_send_burst, av7110_fe_diseqc_send_burst);
2204 FE_FUNC_OVERRIDE(av7110->fe->ops->set_tone, av7110->fe_set_tone, av7110_fe_set_tone);
2205 FE_FUNC_OVERRIDE(av7110->fe->ops->set_voltage, av7110->fe_set_voltage, av7110_fe_set_voltage;)
2206 FE_FUNC_OVERRIDE(av7110->fe->ops->dishnetwork_send_legacy_command, av7110->fe_dishnetwork_send_legacy_command, av7110_fe_dishnetwork_send_legacy_command);
2207 FE_FUNC_OVERRIDE(av7110->fe->ops->set_frontend, av7110->fe_set_frontend, av7110_fe_set_frontend);
2208
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07002209 ret = dvb_register_frontend(&av7110->dvb_adapter, av7110->fe);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002210 if (ret < 0) {
2211 printk("av7110: Frontend registration failed!\n");
2212 if (av7110->fe->ops->release)
2213 av7110->fe->ops->release(av7110->fe);
2214 av7110->fe = NULL;
2215 }
2216 }
2217 return ret;
2218}
2219
2220/* Budgetpatch note:
2221 * Original hardware design by Roberto Deza:
2222 * There is a DVB_Wiki at
2223 * http://212.227.36.83/linuxtv/wiki/index.php/Main_Page
2224 * where is described this 'DVB TT Budget Patch', on Card Modding:
2225 * http://212.227.36.83/linuxtv/wiki/index.php/DVB_TT_Budget_Patch
2226 * On the short description there is also a link to a external file,
2227 * with more details:
2228 * http://perso.wanadoo.es/jesussolano/Ttf_tsc1.zip
2229 *
2230 * New software triggering design by Emard that works on
2231 * original Roberto Deza's hardware:
2232 *
2233 * rps1 code for budgetpatch will copy internal HS event to GPIO3 pin.
2234 * GPIO3 is in budget-patch hardware connectd to port B VSYNC
2235 * HS is an internal event of 7146, accessible with RPS
2236 * and temporarily raised high every n lines
2237 * (n in defined in the RPS_THRESH1 counter threshold)
2238 * I think HS is raised high on the beginning of the n-th line
2239 * and remains high until this n-th line that triggered
2240 * it is completely received. When the receiption of n-th line
2241 * ends, HS is lowered.
2242 *
2243 * To transmit data over DMA, 7146 needs changing state at
2244 * port B VSYNC pin. Any changing of port B VSYNC will
2245 * cause some DMA data transfer, with more or less packets loss.
2246 * It depends on the phase and frequency of VSYNC and
2247 * the way of 7146 is instructed to trigger on port B (defined
2248 * in DD1_INIT register, 3rd nibble from the right valid
2249 * numbers are 0-7, see datasheet)
2250 *
2251 * The correct triggering can minimize packet loss,
2252 * dvbtraffic should give this stable bandwidths:
2253 * 22k transponder = 33814 kbit/s
2254 * 27.5k transponder = 38045 kbit/s
2255 * by experiment it is found that the best results
2256 * (stable bandwidths and almost no packet loss)
2257 * are obtained using DD1_INIT triggering number 2
2258 * (Va at rising edge of VS Fa = HS x VS-failing forced toggle)
2259 * and a VSYNC phase that occurs in the middle of DMA transfer
2260 * (about byte 188*512=96256 in the DMA window).
2261 *
2262 * Phase of HS is still not clear to me how to control,
2263 * It just happens to be so. It can be seen if one enables
2264 * RPS_IRQ and print Event Counter 1 in vpeirq(). Every
2265 * time RPS_INTERRUPT is called, the Event Counter 1 will
2266 * increment. That's how the 7146 is programmed to do event
2267 * counting in this budget-patch.c
2268 * I *think* HPS setting has something to do with the phase
2269 * of HS but I cant be 100% sure in that.
2270 *
2271 * hardware debug note: a working budget card (including budget patch)
2272 * with vpeirq() interrupt setup in mode "0x90" (every 64K) will
2273 * generate 3 interrupts per 25-Hz DMA frame of 2*188*512 bytes
2274 * and that means 3*25=75 Hz of interrupt freqency, as seen by
2275 * watch cat /proc/interrupts
2276 *
2277 * If this frequency is 3x lower (and data received in the DMA
2278 * buffer don't start with 0x47, but in the middle of packets,
2279 * whose lengths appear to be like 188 292 188 104 etc.
2280 * this means VSYNC line is not connected in the hardware.
2281 * (check soldering pcb and pins)
2282 * The same behaviour of missing VSYNC can be duplicated on budget
2283 * cards, by seting DD1_INIT trigger mode 7 in 3rd nibble.
2284 */
Johannes Stezenbach1be11e32006-02-27 00:09:20 -03002285static int __devinit av7110_attach(struct saa7146_dev* dev,
2286 struct saa7146_pci_extension_data *pci_ext)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002287{
2288 const int length = TS_WIDTH * TS_HEIGHT;
2289 struct pci_dev *pdev = dev->pci;
2290 struct av7110 *av7110;
2291 int ret, count = 0;
2292
2293 dprintk(4, "dev: %p\n", dev);
2294
Mauro Carvalho Chehab9101e622005-12-12 00:37:24 -08002295 /* Set RPS_IRQ to 1 to track rps1 activity.
2296 * Enabling this won't send any interrupt to PC CPU.
2297 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002298#define RPS_IRQ 0
2299
2300 if (budgetpatch == 1) {
2301 budgetpatch = 0;
2302 /* autodetect the presence of budget patch
2303 * this only works if saa7146 has been recently
2304 * reset with with MASK_31 to MC1
2305 *
2306 * will wait for VBI_B event (vertical blank at port B)
2307 * and will reset GPIO3 after VBI_B is detected.
2308 * (GPIO3 should be raised high by CPU to
2309 * test if GPIO3 will generate vertical blank signal
2310 * in budget patch GPIO3 is connected to VSYNC_B
2311 */
2312
2313 /* RESET SAA7146 */
2314 saa7146_write(dev, MC1, MASK_31);
2315 /* autodetection success seems to be time-dependend after reset */
2316
2317 /* Fix VSYNC level */
2318 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
2319 /* set vsync_b triggering */
2320 saa7146_write(dev, DD1_STREAM_B, 0);
2321 /* port B VSYNC at rising edge */
2322 saa7146_write(dev, DD1_INIT, 0x00000200);
2323 saa7146_write(dev, BRS_CTRL, 0x00000000); // VBI
2324 saa7146_write(dev, MC2,
2325 1 * (MASK_08 | MASK_24) | // BRS control
2326 0 * (MASK_09 | MASK_25) | // a
2327 1 * (MASK_10 | MASK_26) | // b
2328 0 * (MASK_06 | MASK_22) | // HPS_CTRL1
2329 0 * (MASK_05 | MASK_21) | // HPS_CTRL2
2330 0 * (MASK_01 | MASK_15) // DEBI
2331 );
2332
2333 /* start writing RPS1 code from beginning */
2334 count = 0;
2335 /* Disable RPS1 */
2336 saa7146_write(dev, MC1, MASK_29);
2337 /* RPS1 timeout disable */
2338 saa7146_write(dev, RPS_TOV1, 0);
2339 WRITE_RPS1(cpu_to_le32(CMD_PAUSE | EVT_VBI_B));
2340 WRITE_RPS1(cpu_to_le32(CMD_WR_REG_MASK | (GPIO_CTRL>>2)));
2341 WRITE_RPS1(cpu_to_le32(GPIO3_MSK));
2342 WRITE_RPS1(cpu_to_le32(SAA7146_GPIO_OUTLO<<24));
2343#if RPS_IRQ
2344 /* issue RPS1 interrupt to increment counter */
2345 WRITE_RPS1(cpu_to_le32(CMD_INTERRUPT));
2346#endif
2347 WRITE_RPS1(cpu_to_le32(CMD_STOP));
2348 /* Jump to begin of RPS program as safety measure (p37) */
2349 WRITE_RPS1(cpu_to_le32(CMD_JUMP));
2350 WRITE_RPS1(cpu_to_le32(dev->d_rps1.dma_handle));
2351
2352#if RPS_IRQ
2353 /* set event counter 1 source as RPS1 interrupt (0x03) (rE4 p53)
2354 * use 0x03 to track RPS1 interrupts - increase by 1 every gpio3 is toggled
2355 * use 0x15 to track VPE interrupts - increase by 1 every vpeirq() is called
2356 */
2357 saa7146_write(dev, EC1SSR, (0x03<<2) | 3 );
2358 /* set event counter 1 treshold to maximum allowed value (rEC p55) */
2359 saa7146_write(dev, ECT1R, 0x3fff );
2360#endif
2361 /* Set RPS1 Address register to point to RPS code (r108 p42) */
2362 saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle);
2363 /* Enable RPS1, (rFC p33) */
2364 saa7146_write(dev, MC1, (MASK_13 | MASK_29 ));
2365
2366 mdelay(10);
2367 /* now send VSYNC_B to rps1 by rising GPIO3 */
2368 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI);
2369 mdelay(10);
2370 /* if rps1 responded by lowering the GPIO3,
2371 * then we have budgetpatch hardware
2372 */
2373 if ((saa7146_read(dev, GPIO_CTRL) & 0x10000000) == 0) {
2374 budgetpatch = 1;
2375 printk("dvb-ttpci: BUDGET-PATCH DETECTED.\n");
2376 }
2377 /* Disable RPS1 */
2378 saa7146_write(dev, MC1, ( MASK_29 ));
2379#if RPS_IRQ
2380 printk("dvb-ttpci: Event Counter 1 0x%04x\n", saa7146_read(dev, EC1R) & 0x3fff );
2381#endif
2382 }
2383
2384 /* prepare the av7110 device struct */
Panagiotis Issaris74081872006-01-11 19:40:56 -02002385 av7110 = kzalloc(sizeof(struct av7110), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002386 if (!av7110) {
2387 dprintk(1, "out of memory\n");
2388 return -ENOMEM;
2389 }
2390
Linus Torvalds1da177e2005-04-16 15:20:36 -07002391 av7110->card_name = (char*) pci_ext->ext_priv;
2392 av7110->dev = dev;
2393 dev->ext_priv = av7110;
2394
2395 ret = get_firmware(av7110);
2396 if (ret < 0)
2397 goto err_kfree_0;
2398
2399 ret = dvb_register_adapter(&av7110->dvb_adapter, av7110->card_name,
2400 THIS_MODULE);
2401 if (ret < 0)
2402 goto err_put_firmware_1;
2403
2404 /* the Siemens DVB needs this if you want to have the i2c chips
2405 get recognized before the main driver is fully loaded */
2406 saa7146_write(dev, GPIO_CTRL, 0x500000);
2407
2408#ifdef I2C_ADAP_CLASS_TV_DIGITAL
2409 av7110->i2c_adap.class = I2C_ADAP_CLASS_TV_DIGITAL;
2410#else
2411 av7110->i2c_adap.class = I2C_CLASS_TV_DIGITAL;
2412#endif
2413 strlcpy(av7110->i2c_adap.name, pci_ext->ext_priv, sizeof(av7110->i2c_adap.name));
2414
2415 saa7146_i2c_adapter_prepare(dev, &av7110->i2c_adap, SAA7146_I2C_BUS_BIT_RATE_120); /* 275 kHz */
2416
2417 ret = i2c_add_adapter(&av7110->i2c_adap);
2418 if (ret < 0)
2419 goto err_dvb_unregister_adapter_2;
2420
2421 ttpci_eeprom_parse_mac(&av7110->i2c_adap,
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07002422 av7110->dvb_adapter.proposed_mac);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002423 ret = -ENOMEM;
2424
2425 if (budgetpatch) {
2426 spin_lock_init(&av7110->feedlock1);
2427 av7110->grabbing = saa7146_vmalloc_build_pgtable(pdev, length,
2428 &av7110->pt);
2429 if (!av7110->grabbing)
2430 goto err_i2c_del_3;
2431
2432 saa7146_write(dev, PCI_BT_V1, 0x1c1f101f);
2433 saa7146_write(dev, BCS_CTRL, 0x80400040);
2434 /* set dd1 stream a & b */
2435 saa7146_write(dev, DD1_STREAM_B, 0x00000000);
2436 saa7146_write(dev, DD1_INIT, 0x03000200);
2437 saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
2438 saa7146_write(dev, BRS_CTRL, 0x60000000);
2439 saa7146_write(dev, BASE_ODD3, 0);
2440 saa7146_write(dev, BASE_EVEN3, 0);
2441 saa7146_write(dev, PROT_ADDR3, TS_WIDTH * TS_HEIGHT);
2442 saa7146_write(dev, BASE_PAGE3, av7110->pt.dma | ME1 | 0x90);
2443
2444 saa7146_write(dev, PITCH3, TS_WIDTH);
2445 saa7146_write(dev, NUM_LINE_BYTE3, (TS_HEIGHT << 16) | TS_WIDTH);
2446
2447 /* upload all */
2448 saa7146_write(dev, MC2, 0x077c077c);
2449 saa7146_write(dev, GPIO_CTRL, 0x000000);
2450#if RPS_IRQ
2451 /* set event counter 1 source as RPS1 interrupt (0x03) (rE4 p53)
2452 * use 0x03 to track RPS1 interrupts - increase by 1 every gpio3 is toggled
2453 * use 0x15 to track VPE interrupts - increase by 1 every vpeirq() is called
2454 */
2455 saa7146_write(dev, EC1SSR, (0x03<<2) | 3 );
2456 /* set event counter 1 treshold to maximum allowed value (rEC p55) */
2457 saa7146_write(dev, ECT1R, 0x3fff );
2458#endif
2459 /* Setup BUDGETPATCH MAIN RPS1 "program" (p35) */
2460 count = 0;
2461
2462 /* Wait Source Line Counter Threshold (p36) */
2463 WRITE_RPS1(cpu_to_le32(CMD_PAUSE | EVT_HS));
2464 /* Set GPIO3=1 (p42) */
2465 WRITE_RPS1(cpu_to_le32(CMD_WR_REG_MASK | (GPIO_CTRL>>2)));
2466 WRITE_RPS1(cpu_to_le32(GPIO3_MSK));
2467 WRITE_RPS1(cpu_to_le32(SAA7146_GPIO_OUTHI<<24));
2468#if RPS_IRQ
2469 /* issue RPS1 interrupt */
2470 WRITE_RPS1(cpu_to_le32(CMD_INTERRUPT));
2471#endif
2472 /* Wait reset Source Line Counter Threshold (p36) */
2473 WRITE_RPS1(cpu_to_le32(CMD_PAUSE | RPS_INV | EVT_HS));
2474 /* Set GPIO3=0 (p42) */
2475 WRITE_RPS1(cpu_to_le32(CMD_WR_REG_MASK | (GPIO_CTRL>>2)));
2476 WRITE_RPS1(cpu_to_le32(GPIO3_MSK));
2477 WRITE_RPS1(cpu_to_le32(SAA7146_GPIO_OUTLO<<24));
2478#if RPS_IRQ
2479 /* issue RPS1 interrupt */
2480 WRITE_RPS1(cpu_to_le32(CMD_INTERRUPT));
2481#endif
2482 /* Jump to begin of RPS program (p37) */
2483 WRITE_RPS1(cpu_to_le32(CMD_JUMP));
2484 WRITE_RPS1(cpu_to_le32(dev->d_rps1.dma_handle));
2485
2486 /* Fix VSYNC level */
2487 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
2488 /* Set RPS1 Address register to point to RPS code (r108 p42) */
2489 saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle);
2490 /* Set Source Line Counter Threshold, using BRS (rCC p43)
2491 * It generates HS event every TS_HEIGHT lines
2492 * this is related to TS_WIDTH set in register
2493 * NUM_LINE_BYTE3. If NUM_LINE_BYTE low 16 bits
2494 * are set to TS_WIDTH bytes (TS_WIDTH=2*188),
2495 * then RPS_THRESH1 should be set to trigger
2496 * every TS_HEIGHT (512) lines.
2497 */
2498 saa7146_write(dev, RPS_THRESH1, (TS_HEIGHT*1) | MASK_12 );
2499
2500 /* Enable RPS1 (rFC p33) */
2501 saa7146_write(dev, MC1, (MASK_13 | MASK_29));
2502
2503 /* end of budgetpatch register initialization */
2504 tasklet_init (&av7110->vpe_tasklet, vpeirq, (unsigned long) av7110);
2505 } else {
2506 saa7146_write(dev, PCI_BT_V1, 0x1c00101f);
2507 saa7146_write(dev, BCS_CTRL, 0x80400040);
2508
2509 /* set dd1 stream a & b */
2510 saa7146_write(dev, DD1_STREAM_B, 0x00000000);
2511 saa7146_write(dev, DD1_INIT, 0x03000000);
2512 saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
2513
2514 /* upload all */
2515 saa7146_write(dev, MC2, 0x077c077c);
2516 saa7146_write(dev, GPIO_CTRL, 0x000000);
2517 }
2518
2519 tasklet_init (&av7110->debi_tasklet, debiirq, (unsigned long) av7110);
2520 tasklet_init (&av7110->gpio_tasklet, gpioirq, (unsigned long) av7110);
2521
Ingo Molnar3593cab2006-02-07 06:49:14 -02002522 mutex_init(&av7110->pid_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002523
2524 /* locks for data transfers from/to AV7110 */
2525 spin_lock_init(&av7110->debilock);
Ingo Molnar3593cab2006-02-07 06:49:14 -02002526 mutex_init(&av7110->dcomlock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002527 av7110->debitype = -1;
2528
2529 /* default OSD window */
2530 av7110->osdwin = 1;
Ingo Molnar3593cab2006-02-07 06:49:14 -02002531 mutex_init(&av7110->osd_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002532
2533 /* ARM "watchdog" */
2534 init_waitqueue_head(&av7110->arm_wait);
2535 av7110->arm_thread = NULL;
2536
2537 /* allocate and init buffers */
2538 av7110->debi_virt = pci_alloc_consistent(pdev, 8192, &av7110->debi_bus);
2539 if (!av7110->debi_virt)
2540 goto err_saa71466_vfree_4;
2541
2542
2543 av7110->iobuf = vmalloc(AVOUTLEN+AOUTLEN+BMPLEN+4*IPACKS);
2544 if (!av7110->iobuf)
2545 goto err_pci_free_5;
2546
2547 ret = av7110_av_init(av7110);
2548 if (ret < 0)
2549 goto err_iobuf_vfree_6;
2550
2551 /* init BMP buffer */
2552 av7110->bmpbuf = av7110->iobuf+AVOUTLEN+AOUTLEN;
2553 init_waitqueue_head(&av7110->bmpq);
2554
2555 ret = av7110_ca_init(av7110);
2556 if (ret < 0)
2557 goto err_av7110_av_exit_7;
2558
2559 /* load firmware into AV7110 cards */
2560 ret = av7110_bootarm(av7110);
2561 if (ret < 0)
2562 goto err_av7110_ca_exit_8;
2563
2564 ret = av7110_firmversion(av7110);
2565 if (ret < 0)
2566 goto err_stop_arm_9;
2567
2568 if (FW_VERSION(av7110->arm_app)<0x2501)
2569 printk ("dvb-ttpci: Warning, firmware version 0x%04x is too old. "
2570 "System might be unstable!\n", FW_VERSION(av7110->arm_app));
2571
2572 ret = kernel_thread(arm_thread, (void *) av7110, 0);
2573 if (ret < 0)
2574 goto err_stop_arm_9;
2575
2576 /* set initial volume in mixer struct */
2577 av7110->mixer.volume_left = volume;
2578 av7110->mixer.volume_right = volume;
2579
2580 init_av7110_av(av7110);
2581
2582 ret = av7110_register(av7110);
2583 if (ret < 0)
2584 goto err_arm_thread_stop_10;
2585
2586 /* special case DVB-C: these cards have an analog tuner
2587 plus need some special handling, so we have separate
2588 saa7146_ext_vv data for these... */
2589 ret = av7110_init_v4l(av7110);
2590 if (ret < 0)
2591 goto err_av7110_unregister_11;
2592
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07002593 av7110->dvb_adapter.priv = av7110;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002594 ret = frontend_init(av7110);
2595 if (ret < 0)
2596 goto err_av7110_exit_v4l_12;
2597
2598#if defined(CONFIG_INPUT_EVDEV) || defined(CONFIG_INPUT_EVDEV_MODULE)
Oliver Endriss03388ae2005-09-09 13:03:12 -07002599 av7110_ir_init(av7110);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002600#endif
2601 printk(KERN_INFO "dvb-ttpci: found av7110-%d.\n", av7110_num);
2602 av7110_num++;
2603out:
2604 return ret;
2605
2606err_av7110_exit_v4l_12:
2607 av7110_exit_v4l(av7110);
2608err_av7110_unregister_11:
2609 dvb_unregister(av7110);
2610err_arm_thread_stop_10:
2611 av7110_arm_sync(av7110);
2612err_stop_arm_9:
2613 /* Nothing to do. Rejoice. */
2614err_av7110_ca_exit_8:
2615 av7110_ca_exit(av7110);
2616err_av7110_av_exit_7:
2617 av7110_av_exit(av7110);
2618err_iobuf_vfree_6:
2619 vfree(av7110->iobuf);
2620err_pci_free_5:
2621 pci_free_consistent(pdev, 8192, av7110->debi_virt, av7110->debi_bus);
2622err_saa71466_vfree_4:
2623 if (!av7110->grabbing)
2624 saa7146_pgtable_free(pdev, &av7110->pt);
2625err_i2c_del_3:
2626 i2c_del_adapter(&av7110->i2c_adap);
2627err_dvb_unregister_adapter_2:
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07002628 dvb_unregister_adapter(&av7110->dvb_adapter);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002629err_put_firmware_1:
2630 put_firmware(av7110);
2631err_kfree_0:
2632 kfree(av7110);
2633 goto out;
2634}
2635
Johannes Stezenbach1be11e32006-02-27 00:09:20 -03002636static int __devexit av7110_detach(struct saa7146_dev* saa)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002637{
2638 struct av7110 *av7110 = saa->ext_priv;
2639 dprintk(4, "%p\n", av7110);
2640
Oliver Endriss03388ae2005-09-09 13:03:12 -07002641#if defined(CONFIG_INPUT_EVDEV) || defined(CONFIG_INPUT_EVDEV_MODULE)
2642 av7110_ir_exit(av7110);
2643#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07002644 if (budgetpatch) {
2645 /* Disable RPS1 */
2646 saa7146_write(saa, MC1, MASK_29);
2647 /* VSYNC LOW (inactive) */
2648 saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO);
2649 saa7146_write(saa, MC1, MASK_20); /* DMA3 off */
2650 SAA7146_IER_DISABLE(saa, MASK_10);
2651 SAA7146_ISR_CLEAR(saa, MASK_10);
2652 msleep(50);
2653 tasklet_kill(&av7110->vpe_tasklet);
2654 saa7146_pgtable_free(saa->pci, &av7110->pt);
2655 }
2656 av7110_exit_v4l(av7110);
2657
2658 av7110_arm_sync(av7110);
2659
2660 tasklet_kill(&av7110->debi_tasklet);
2661 tasklet_kill(&av7110->gpio_tasklet);
2662
2663 dvb_unregister(av7110);
2664
2665 SAA7146_IER_DISABLE(saa, MASK_19 | MASK_03);
2666 SAA7146_ISR_CLEAR(saa, MASK_19 | MASK_03);
2667
2668 av7110_ca_exit(av7110);
2669 av7110_av_exit(av7110);
2670
2671 vfree(av7110->iobuf);
2672 pci_free_consistent(saa->pci, 8192, av7110->debi_virt,
2673 av7110->debi_bus);
2674
2675 i2c_del_adapter(&av7110->i2c_adap);
2676
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07002677 dvb_unregister_adapter (&av7110->dvb_adapter);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002678
2679 av7110_num--;
2680
2681 put_firmware(av7110);
2682
2683 kfree(av7110);
2684
2685 saa->ext_priv = NULL;
2686
2687 return 0;
2688}
2689
2690
2691static void av7110_irq(struct saa7146_dev* dev, u32 *isr)
2692{
2693 struct av7110 *av7110 = dev->ext_priv;
2694
2695 //print_time("av7110_irq");
2696
2697 /* Note: Don't try to handle the DEBI error irq (MASK_18), in
2698 * intel mode the timeout is asserted all the time...
2699 */
2700
2701 if (*isr & MASK_19) {
2702 //printk("av7110_irq: DEBI\n");
2703 /* Note 1: The DEBI irq is level triggered: We must enable it
2704 * only after we started a DMA xfer, and disable it here
2705 * immediately, or it will be signalled all the time while
2706 * DEBI is idle.
2707 * Note 2: You would think that an irq which is masked is
2708 * not signalled by the hardware. Not so for the SAA7146:
2709 * An irq is signalled as long as the corresponding bit
2710 * in the ISR is set, and disabling irqs just prevents the
2711 * hardware from setting the ISR bit. This means a) that we
2712 * must clear the ISR *after* disabling the irq (which is why
2713 * we must do it here even though saa7146_core did it already),
2714 * and b) that if we were to disable an edge triggered irq
2715 * (like the gpio irqs sadly are) temporarily we would likely
2716 * loose some. This sucks :-(
2717 */
2718 SAA7146_IER_DISABLE(av7110->dev, MASK_19);
2719 SAA7146_ISR_CLEAR(av7110->dev, MASK_19);
2720 tasklet_schedule(&av7110->debi_tasklet);
2721 }
2722
2723 if (*isr & MASK_03) {
2724 //printk("av7110_irq: GPIO\n");
2725 tasklet_schedule(&av7110->gpio_tasklet);
2726 }
2727
2728 if ((*isr & MASK_10) && budgetpatch)
2729 tasklet_schedule(&av7110->vpe_tasklet);
2730}
2731
2732
2733static struct saa7146_extension av7110_extension;
2734
2735#define MAKE_AV7110_INFO(x_var,x_name) \
2736static struct saa7146_pci_extension_data x_var = { \
2737 .ext_priv = x_name, \
2738 .ext = &av7110_extension }
2739
Karl Herz6af4ee12005-09-09 13:03:13 -07002740MAKE_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 -07002741MAKE_AV7110_INFO(ttt_1_X, "Technotrend/Hauppauge WinTV DVB-T rev1.X");
2742MAKE_AV7110_INFO(ttc_1_X, "Technotrend/Hauppauge WinTV Nexus-CA rev1.X");
2743MAKE_AV7110_INFO(ttc_2_X, "Technotrend/Hauppauge WinTV DVB-C rev2.X");
2744MAKE_AV7110_INFO(tts_2_X, "Technotrend/Hauppauge WinTV Nexus-S rev2.X");
Johannes Stezenbach3dfaebd2005-05-16 21:54:19 -07002745MAKE_AV7110_INFO(tts_2_3, "Technotrend/Hauppauge WinTV Nexus-S rev2.3");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002746MAKE_AV7110_INFO(tts_1_3se, "Technotrend/Hauppauge WinTV DVB-S rev1.3 SE");
2747MAKE_AV7110_INFO(ttt, "Technotrend/Hauppauge DVB-T");
2748MAKE_AV7110_INFO(fsc, "Fujitsu Siemens DVB-C");
2749MAKE_AV7110_INFO(fss, "Fujitsu Siemens DVB-S rev1.6");
Oliver Endriss8bd63012006-02-07 06:49:11 -02002750MAKE_AV7110_INFO(gxs_1_3, "Galaxis DVB-S rev1.3");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002751
2752static struct pci_device_id pci_tbl[] = {
Karl Herz6af4ee12005-09-09 13:03:13 -07002753 MAKE_EXTENSION_PCI(fsc, 0x110a, 0x0000),
2754 MAKE_EXTENSION_PCI(tts_1_X_fsc, 0x13c2, 0x0000),
2755 MAKE_EXTENSION_PCI(ttt_1_X, 0x13c2, 0x0001),
2756 MAKE_EXTENSION_PCI(ttc_2_X, 0x13c2, 0x0002),
2757 MAKE_EXTENSION_PCI(tts_2_X, 0x13c2, 0x0003),
Oliver Endriss8bd63012006-02-07 06:49:11 -02002758 MAKE_EXTENSION_PCI(gxs_1_3, 0x13c2, 0x0004),
Karl Herz6af4ee12005-09-09 13:03:13 -07002759 MAKE_EXTENSION_PCI(fss, 0x13c2, 0x0006),
2760 MAKE_EXTENSION_PCI(ttt, 0x13c2, 0x0008),
2761 MAKE_EXTENSION_PCI(ttc_1_X, 0x13c2, 0x000a),
2762 MAKE_EXTENSION_PCI(tts_2_3, 0x13c2, 0x000e),
2763 MAKE_EXTENSION_PCI(tts_1_3se, 0x13c2, 0x1002),
Linus Torvalds1da177e2005-04-16 15:20:36 -07002764
Linus Torvalds1da177e2005-04-16 15:20:36 -07002765/* MAKE_EXTENSION_PCI(???, 0x13c2, 0x0005), UNDEFINED CARD */ // Technisat SkyStar1
2766/* MAKE_EXTENSION_PCI(???, 0x13c2, 0x0009), UNDEFINED CARD */ // TT/Hauppauge WinTV Nexus-CA v????
2767
2768 {
2769 .vendor = 0,
2770 }
2771};
2772
2773MODULE_DEVICE_TABLE(pci, pci_tbl);
2774
2775
2776static struct saa7146_extension av7110_extension = {
2777 .name = "dvb\0",
2778 .flags = SAA7146_I2C_SHORT_DELAY,
2779
2780 .module = THIS_MODULE,
2781 .pci_tbl = &pci_tbl[0],
2782 .attach = av7110_attach,
Johannes Stezenbach1be11e32006-02-27 00:09:20 -03002783 .detach = __devexit_p(av7110_detach),
Linus Torvalds1da177e2005-04-16 15:20:36 -07002784
2785 .irq_mask = MASK_19 | MASK_03 | MASK_10,
2786 .irq_func = av7110_irq,
2787};
2788
2789
2790static int __init av7110_init(void)
2791{
2792 int retval;
2793 retval = saa7146_register_extension(&av7110_extension);
2794 return retval;
2795}
2796
2797
2798static void __exit av7110_exit(void)
2799{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002800 saa7146_unregister_extension(&av7110_extension);
2801}
2802
2803module_init(av7110_init);
2804module_exit(av7110_exit);
2805
2806MODULE_DESCRIPTION("driver for the SAA7146 based AV110 PCI DVB cards by "
2807 "Siemens, Technotrend, Hauppauge");
2808MODULE_AUTHOR("Ralph Metzler, Marcus Metzler, others");
2809MODULE_LICENSE("GPL");