blob: d028245c8eede256eee4fdd6de60610ea266816f [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;
Oliver Endriss4caba422006-03-17 05:29:15 -030088static int wss_cfg_4_3 = 0x4008;
89static int wss_cfg_16_9 = 0x0007;
C.Y.M2f03ee82006-03-30 04:31:48 -030090static int tv_standard;
Linus Torvalds1da177e2005-04-16 15:20:36 -070091
92module_param_named(debug, av7110_debug, int, 0644);
93MODULE_PARM_DESC(debug, "debug level (bitmask, default 0)");
94module_param(vidmode, int, 0444);
95MODULE_PARM_DESC(vidmode,"analog video out: 0 off, 1 CVBS+RGB (default), 2 CVBS+YC, 3 YC");
96module_param(pids_off, int, 0444);
97MODULE_PARM_DESC(pids_off,"clear video/audio/PCR PID filters when demux is closed");
98module_param(adac, int, 0444);
99MODULE_PARM_DESC(adac,"audio DAC type: 0 TI, 1 CRYSTAL, 2 MSP (use if autodetection fails)");
100module_param(hw_sections, int, 0444);
101MODULE_PARM_DESC(hw_sections, "0 use software section filter, 1 use hardware");
102module_param(rgb_on, int, 0444);
103MODULE_PARM_DESC(rgb_on, "For Siemens DVB-C cards only: Enable RGB control"
104 " signal on SCART pin 16 to switch SCART video mode from CVBS to RGB");
105module_param(volume, int, 0444);
106MODULE_PARM_DESC(volume, "initial volume: default 255 (range 0-255)");
107module_param(budgetpatch, int, 0444);
108MODULE_PARM_DESC(budgetpatch, "use budget-patch hardware modification: default 0 (0 no, 1 autodetect, 2 always)");
Oliver Endriss4caba422006-03-17 05:29:15 -0300109module_param(wss_cfg_4_3, int, 0444);
110MODULE_PARM_DESC(wss_cfg_4_3, "WSS 4:3 - default 0x4008 - bit 15: disable, 14: burst mode, 13..0: wss data");
111module_param(wss_cfg_16_9, int, 0444);
112MODULE_PARM_DESC(wss_cfg_16_9, "WSS 16:9 - default 0x0007 - bit 15: disable, 14: burst mode, 13..0: wss data");
C.Y.M2f03ee82006-03-30 04:31:48 -0300113module_param(tv_standard, int, 0444);
114MODULE_PARM_DESC(tv_standard, "TV standard: 0 PAL (default), 1 NTSC");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700115
116static void restart_feeds(struct av7110 *av7110);
117
Mauro Carvalho Chehaba5ed4252006-01-13 14:10:19 -0200118static int av7110_num;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700119
120#define FE_FUNC_OVERRIDE(fe_func, av7110_copy, av7110_func) \
121{\
122 if (fe_func != NULL) { \
123 av7110_copy = fe_func; \
124 fe_func = av7110_func; \
125 } \
126}
127
128
129static void init_av7110_av(struct av7110 *av7110)
130{
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700131 int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700132 struct saa7146_dev *dev = av7110->dev;
133
134 /* set internal volume control to maximum */
135 av7110->adac_type = DVB_ADAC_TI;
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700136 ret = av7110_set_volume(av7110, av7110->mixer.volume_left, av7110->mixer.volume_right);
Johannes Stezenbach7a2fa902005-07-07 17:58:01 -0700137 if (ret < 0)
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700138 printk("dvb-ttpci:cannot set internal volume to maximum:%d\n",ret);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700139
Oliver Endriss4caba422006-03-17 05:29:15 -0300140 ret = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetWSSConfig, 2, 2, wss_cfg_4_3);
141 if (ret < 0)
142 printk("dvb-ttpci: unable to configure 4:3 wss\n");
143 ret = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetWSSConfig, 2, 3, wss_cfg_16_9);
144 if (ret < 0)
145 printk("dvb-ttpci: unable to configure 16:9 wss\n");
146
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700147 ret = av7710_set_video_mode(av7110, vidmode);
Johannes Stezenbach7a2fa902005-07-07 17:58:01 -0700148 if (ret < 0)
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700149 printk("dvb-ttpci:cannot set video mode:%d\n",ret);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700150
151 /* handle different card types */
152 /* remaining inits according to card and frontend type */
153 av7110->analog_tuner_flags = 0;
154 av7110->current_input = 0;
Marco Schluessler1c13b952006-01-09 15:25:06 -0200155 if (dev->pci->subsystem_vendor == 0x13c2 && dev->pci->subsystem_device == 0x000a) {
156 printk("dvb-ttpci: MSP3415 audio DAC @ card %d\n",
157 av7110->dvb_adapter.num);
158 av7110->adac_type = DVB_ADAC_MSP34x5;
159 av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, ADSwitch, 1, 0); // SPDIF on
160 }
161 else if (i2c_writereg(av7110, 0x20, 0x00, 0x00) == 1) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700162 printk ("dvb-ttpci: Crystal audio DAC @ card %d detected\n",
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -0700163 av7110->dvb_adapter.num);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700164 av7110->adac_type = DVB_ADAC_CRYSTAL;
165 i2c_writereg(av7110, 0x20, 0x01, 0xd2);
166 i2c_writereg(av7110, 0x20, 0x02, 0x49);
167 i2c_writereg(av7110, 0x20, 0x03, 0x00);
168 i2c_writereg(av7110, 0x20, 0x04, 0x00);
169
170 /**
171 * some special handling for the Siemens DVB-C cards...
172 */
173 } else if (0 == av7110_init_analog_module(av7110)) {
174 /* done. */
175 }
176 else if (dev->pci->subsystem_vendor == 0x110a) {
177 printk("dvb-ttpci: DVB-C w/o analog module @ card %d detected\n",
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -0700178 av7110->dvb_adapter.num);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700179 av7110->adac_type = DVB_ADAC_NONE;
180 }
181 else {
182 av7110->adac_type = adac;
183 printk("dvb-ttpci: adac type set to %d @ card %d\n",
Marco Schluessler1c13b952006-01-09 15:25:06 -0200184 av7110->adac_type, av7110->dvb_adapter.num);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700185 }
186
Marco Schluessler1c13b952006-01-09 15:25:06 -0200187 if (av7110->adac_type == DVB_ADAC_NONE || av7110->adac_type == DVB_ADAC_MSP34x0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700188 // switch DVB SCART on
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700189 ret = av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, MainSwitch, 1, 0);
Johannes Stezenbach7a2fa902005-07-07 17:58:01 -0700190 if (ret < 0)
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700191 printk("dvb-ttpci:cannot switch on SCART(Main):%d\n",ret);
192 ret = av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, ADSwitch, 1, 1);
Johannes Stezenbach7a2fa902005-07-07 17:58:01 -0700193 if (ret < 0)
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700194 printk("dvb-ttpci:cannot switch on SCART(AD):%d\n",ret);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700195 if (rgb_on &&
Karl Herz6af4ee12005-09-09 13:03:13 -0700196 ((av7110->dev->pci->subsystem_vendor == 0x110a) ||
197 (av7110->dev->pci->subsystem_vendor == 0x13c2)) &&
198 (av7110->dev->pci->subsystem_device == 0x0000)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700199 saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); // RGB on, SCART pin 16
200 //saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); // SCARTpin 8
201 }
202 }
203
Oliver Endriss60edb132005-12-19 08:54:11 -0200204 if (dev->pci->subsystem_vendor == 0x13c2 && dev->pci->subsystem_device == 0x000e)
205 av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, SpdifSwitch, 1, 0); // SPDIF on
206
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700207 ret = av7110_set_volume(av7110, av7110->mixer.volume_left, av7110->mixer.volume_right);
Johannes Stezenbach7a2fa902005-07-07 17:58:01 -0700208 if (ret < 0)
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700209 printk("dvb-ttpci:cannot set volume :%d\n",ret);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700210}
211
212static void recover_arm(struct av7110 *av7110)
213{
214 dprintk(4, "%p\n",av7110);
215
216 av7110_bootarm(av7110);
217 msleep(100);
Oliver Endriss66190a22006-01-09 15:32:42 -0200218
219 init_av7110_av(av7110);
220
221 /* card-specific recovery */
222 if (av7110->recover)
223 av7110->recover(av7110);
224
Linus Torvalds1da177e2005-04-16 15:20:36 -0700225 restart_feeds(av7110);
226 av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, SetIR, 1, av7110->ir_config);
227}
228
Linus Torvalds1da177e2005-04-16 15:20:36 -0700229static void av7110_arm_sync(struct av7110 *av7110)
230{
231 av7110->arm_rmmod = 1;
232 wake_up_interruptible(&av7110->arm_wait);
233
234 while (av7110->arm_thread)
235 msleep(1);
236}
237
238static int arm_thread(void *data)
239{
240 struct av7110 *av7110 = data;
241 u16 newloops = 0;
242 int timeout;
243
244 dprintk(4, "%p\n",av7110);
245
Mauro Carvalho Chehab9101e622005-12-12 00:37:24 -0800246 lock_kernel();
247 daemonize("arm_mon");
248 sigfillset(&current->blocked);
249 unlock_kernel();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700250
251 av7110->arm_thread = current;
252
253 for (;;) {
254 timeout = wait_event_interruptible_timeout(av7110->arm_wait,
255 av7110->arm_rmmod, 5 * HZ);
256 if (-ERESTARTSYS == timeout || av7110->arm_rmmod) {
257 /* got signal or told to quit*/
258 break;
259 }
260
261 if (!av7110->arm_ready)
262 continue;
263
Ingo Molnar3593cab2006-02-07 06:49:14 -0200264 if (mutex_lock_interruptible(&av7110->dcomlock))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700265 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700266 newloops = rdebi(av7110, DEBINOSWAP, STATUS_LOOPS, 0, 2);
Ingo Molnar3593cab2006-02-07 06:49:14 -0200267 mutex_unlock(&av7110->dcomlock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700268
Oliver Endriss66190a22006-01-09 15:32:42 -0200269 if (newloops == av7110->arm_loops || av7110->arm_errors > 3) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700270 printk(KERN_ERR "dvb-ttpci: ARM crashed @ card %d\n",
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -0700271 av7110->dvb_adapter.num);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700272
Oliver Endriss66190a22006-01-09 15:32:42 -0200273 recover_arm(av7110);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700274
Ingo Molnar3593cab2006-02-07 06:49:14 -0200275 if (mutex_lock_interruptible(&av7110->dcomlock))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700276 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700277 newloops = rdebi(av7110, DEBINOSWAP, STATUS_LOOPS, 0, 2) - 1;
Ingo Molnar3593cab2006-02-07 06:49:14 -0200278 mutex_unlock(&av7110->dcomlock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700279 }
280 av7110->arm_loops = newloops;
Oliver Endriss66190a22006-01-09 15:32:42 -0200281 av7110->arm_errors = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700282 }
283
284 av7110->arm_thread = NULL;
285 return 0;
286}
287
288
Linus Torvalds1da177e2005-04-16 15:20:36 -0700289/****************************************************************************
290 * IRQ handling
291 ****************************************************************************/
292
293static int DvbDmxFilterCallback(u8 *buffer1, size_t buffer1_len,
294 u8 *buffer2, size_t buffer2_len,
295 struct dvb_demux_filter *dvbdmxfilter,
296 enum dmx_success success,
297 struct av7110 *av7110)
298{
299 if (!dvbdmxfilter->feed->demux->dmx.frontend)
300 return 0;
301 if (dvbdmxfilter->feed->demux->dmx.frontend->source == DMX_MEMORY_FE)
302 return 0;
303
304 switch (dvbdmxfilter->type) {
305 case DMX_TYPE_SEC:
306 if ((((buffer1[1] << 8) | buffer1[2]) & 0xfff) + 3 != buffer1_len)
307 return 0;
308 if (dvbdmxfilter->doneq) {
309 struct dmx_section_filter *filter = &dvbdmxfilter->filter;
310 int i;
311 u8 xor, neq = 0;
312
313 for (i = 0; i < DVB_DEMUX_MASK_MAX; i++) {
314 xor = filter->filter_value[i] ^ buffer1[i];
315 neq |= dvbdmxfilter->maskandnotmode[i] & xor;
316 }
317 if (!neq)
318 return 0;
319 }
320 return dvbdmxfilter->feed->cb.sec(buffer1, buffer1_len,
321 buffer2, buffer2_len,
322 &dvbdmxfilter->filter,
323 DMX_OK);
324 case DMX_TYPE_TS:
325 if (!(dvbdmxfilter->feed->ts_type & TS_PACKET))
326 return 0;
327 if (dvbdmxfilter->feed->ts_type & TS_PAYLOAD_ONLY)
328 return dvbdmxfilter->feed->cb.ts(buffer1, buffer1_len,
329 buffer2, buffer2_len,
330 &dvbdmxfilter->feed->feed.ts,
331 DMX_OK);
332 else
333 av7110_p2t_write(buffer1, buffer1_len,
334 dvbdmxfilter->feed->pid,
335 &av7110->p2t_filter[dvbdmxfilter->index]);
336 default:
337 return 0;
338 }
339}
340
341
342//#define DEBUG_TIMING
343static inline void print_time(char *s)
344{
345#ifdef DEBUG_TIMING
346 struct timeval tv;
347 do_gettimeofday(&tv);
348 printk("%s: %d.%d\n", s, (int)tv.tv_sec, (int)tv.tv_usec);
349#endif
350}
351
352#define DEBI_READ 0
353#define DEBI_WRITE 1
354static inline void start_debi_dma(struct av7110 *av7110, int dir,
355 unsigned long addr, unsigned int len)
356{
357 dprintk(8, "%c %08lx %u\n", dir == DEBI_READ ? 'R' : 'W', addr, len);
358 if (saa7146_wait_for_debi_done(av7110->dev, 0)) {
359 printk(KERN_ERR "%s: saa7146_wait_for_debi_done timed out\n", __FUNCTION__);
360 return;
361 }
362
363 SAA7146_ISR_CLEAR(av7110->dev, MASK_19); /* for good measure */
364 SAA7146_IER_ENABLE(av7110->dev, MASK_19);
365 if (len < 5)
366 len = 5; /* we want a real DEBI DMA */
367 if (dir == DEBI_WRITE)
368 iwdebi(av7110, DEBISWAB, addr, 0, (len + 3) & ~3);
369 else
370 irdebi(av7110, DEBISWAB, addr, 0, len);
371}
372
373static void debiirq(unsigned long data)
374{
375 struct av7110 *av7110 = (struct av7110 *) data;
376 int type = av7110->debitype;
377 int handle = (type >> 8) & 0x1f;
378 unsigned int xfer = 0;
379
380 print_time("debi");
381 dprintk(4, "type 0x%04x\n", type);
382
383 if (type == -1) {
384 printk("DEBI irq oops @ %ld, psr:0x%08x, ssr:0x%08x\n",
385 jiffies, saa7146_read(av7110->dev, PSR),
386 saa7146_read(av7110->dev, SSR));
387 goto debi_done;
388 }
389 av7110->debitype = -1;
390
391 switch (type & 0xff) {
392
393 case DATA_TS_RECORD:
394 dvb_dmx_swfilter_packets(&av7110->demux,
395 (const u8 *) av7110->debi_virt,
396 av7110->debilen / 188);
397 xfer = RX_BUFF;
398 break;
399
400 case DATA_PES_RECORD:
401 if (av7110->demux.recording)
402 av7110_record_cb(&av7110->p2t[handle],
403 (u8 *) av7110->debi_virt,
404 av7110->debilen);
405 xfer = RX_BUFF;
406 break;
407
408 case DATA_IPMPE:
409 case DATA_FSECTION:
410 case DATA_PIPING:
411 if (av7110->handle2filter[handle])
412 DvbDmxFilterCallback((u8 *)av7110->debi_virt,
413 av7110->debilen, NULL, 0,
414 av7110->handle2filter[handle],
415 DMX_OK, av7110);
416 xfer = RX_BUFF;
417 break;
418
419 case DATA_CI_GET:
420 {
421 u8 *data = av7110->debi_virt;
422
423 if ((data[0] < 2) && data[2] == 0xff) {
424 int flags = 0;
425 if (data[5] > 0)
426 flags |= CA_CI_MODULE_PRESENT;
427 if (data[5] > 5)
428 flags |= CA_CI_MODULE_READY;
429 av7110->ci_slot[data[0]].flags = flags;
430 } else
431 ci_get_data(&av7110->ci_rbuffer,
432 av7110->debi_virt,
433 av7110->debilen);
434 xfer = RX_BUFF;
435 break;
436 }
437
438 case DATA_COMMON_INTERFACE:
439 CI_handle(av7110, (u8 *)av7110->debi_virt, av7110->debilen);
440#if 0
441 {
442 int i;
443
444 printk("av7110%d: ", av7110->num);
445 printk("%02x ", *(u8 *)av7110->debi_virt);
446 printk("%02x ", *(1+(u8 *)av7110->debi_virt));
447 for (i = 2; i < av7110->debilen; i++)
448 printk("%02x ", (*(i+(unsigned char *)av7110->debi_virt)));
449 for (i = 2; i < av7110->debilen; i++)
450 printk("%c", chtrans(*(i+(unsigned char *)av7110->debi_virt)));
451
452 printk("\n");
453 }
454#endif
455 xfer = RX_BUFF;
456 break;
457
458 case DATA_DEBUG_MESSAGE:
459 ((s8*)av7110->debi_virt)[Reserved_SIZE - 1] = 0;
460 printk("%s\n", (s8 *) av7110->debi_virt);
461 xfer = RX_BUFF;
462 break;
463
464 case DATA_CI_PUT:
465 dprintk(4, "debi DATA_CI_PUT\n");
466 case DATA_MPEG_PLAY:
467 dprintk(4, "debi DATA_MPEG_PLAY\n");
468 case DATA_BMP_LOAD:
469 dprintk(4, "debi DATA_BMP_LOAD\n");
470 xfer = TX_BUFF;
471 break;
472 default:
473 break;
474 }
475debi_done:
476 spin_lock(&av7110->debilock);
477 if (xfer)
478 iwdebi(av7110, DEBINOSWAP, xfer, 0, 2);
479 ARM_ClearMailBox(av7110);
480 spin_unlock(&av7110->debilock);
481}
482
483/* irq from av7110 firmware writing the mailbox register in the DPRAM */
484static void gpioirq(unsigned long data)
485{
486 struct av7110 *av7110 = (struct av7110 *) data;
487 u32 rxbuf, txbuf;
488 int len;
489
490 if (av7110->debitype != -1)
491 /* we shouldn't get any irq while a debi xfer is running */
492 printk("dvb-ttpci: GPIO0 irq oops @ %ld, psr:0x%08x, ssr:0x%08x\n",
493 jiffies, saa7146_read(av7110->dev, PSR),
494 saa7146_read(av7110->dev, SSR));
495
496 if (saa7146_wait_for_debi_done(av7110->dev, 0)) {
497 printk(KERN_ERR "%s: saa7146_wait_for_debi_done timed out\n", __FUNCTION__);
498 BUG(); /* maybe we should try resetting the debi? */
499 }
500
501 spin_lock(&av7110->debilock);
502 ARM_ClearIrq(av7110);
503
504 /* see what the av7110 wants */
505 av7110->debitype = irdebi(av7110, DEBINOSWAP, IRQ_STATE, 0, 2);
506 av7110->debilen = irdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);
507 rxbuf = irdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
508 txbuf = irdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);
509 len = (av7110->debilen + 3) & ~3;
510
511 print_time("gpio");
512 dprintk(8, "GPIO0 irq 0x%04x %d\n", av7110->debitype, av7110->debilen);
513
514 switch (av7110->debitype & 0xff) {
515
516 case DATA_TS_PLAY:
517 case DATA_PES_PLAY:
518 break;
519
520 case DATA_MPEG_VIDEO_EVENT:
521 {
522 u32 h_ar;
523 struct video_event event;
524
525 av7110->video_size.w = irdebi(av7110, DEBINOSWAP, STATUS_MPEG_WIDTH, 0, 2);
526 h_ar = irdebi(av7110, DEBINOSWAP, STATUS_MPEG_HEIGHT_AR, 0, 2);
527
528 iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);
529 iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
530
531 av7110->video_size.h = h_ar & 0xfff;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700532
533 event.type = VIDEO_EVENT_SIZE_CHANGED;
534 event.u.size.w = av7110->video_size.w;
535 event.u.size.h = av7110->video_size.h;
536 switch ((h_ar >> 12) & 0xf)
537 {
538 case 3:
539 av7110->video_size.aspect_ratio = VIDEO_FORMAT_16_9;
540 event.u.size.aspect_ratio = VIDEO_FORMAT_16_9;
541 av7110->videostate.video_format = VIDEO_FORMAT_16_9;
542 break;
543 case 4:
544 av7110->video_size.aspect_ratio = VIDEO_FORMAT_221_1;
545 event.u.size.aspect_ratio = VIDEO_FORMAT_221_1;
546 av7110->videostate.video_format = VIDEO_FORMAT_221_1;
547 break;
548 default:
549 av7110->video_size.aspect_ratio = VIDEO_FORMAT_4_3;
550 event.u.size.aspect_ratio = VIDEO_FORMAT_4_3;
551 av7110->videostate.video_format = VIDEO_FORMAT_4_3;
552 }
Oliver Endriss66190a22006-01-09 15:32:42 -0200553
554 dprintk(8, "GPIO0 irq: DATA_MPEG_VIDEO_EVENT: w/h/ar = %u/%u/%u\n",
555 av7110->video_size.w, av7110->video_size.h,
556 av7110->video_size.aspect_ratio);
557
Linus Torvalds1da177e2005-04-16 15:20:36 -0700558 dvb_video_add_event(av7110, &event);
559 break;
560 }
561
562 case DATA_CI_PUT:
563 {
564 int avail;
565 struct dvb_ringbuffer *cibuf = &av7110->ci_wbuffer;
566
567 avail = dvb_ringbuffer_avail(cibuf);
568 if (avail <= 2) {
569 iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);
570 iwdebi(av7110, DEBINOSWAP, TX_LEN, 0, 2);
571 iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);
572 break;
573 }
574 len = DVB_RINGBUFFER_PEEK(cibuf, 0) << 8;
575 len |= DVB_RINGBUFFER_PEEK(cibuf, 1);
576 if (avail < len + 2) {
577 iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);
578 iwdebi(av7110, DEBINOSWAP, TX_LEN, 0, 2);
579 iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);
580 break;
581 }
582 DVB_RINGBUFFER_SKIP(cibuf, 2);
583
584 dvb_ringbuffer_read(cibuf, av7110->debi_virt, len, 0);
585
586 iwdebi(av7110, DEBINOSWAP, TX_LEN, len, 2);
587 iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, len, 2);
588 dprintk(8, "DMA: CI\n");
589 start_debi_dma(av7110, DEBI_WRITE, DPRAM_BASE + txbuf, len);
590 spin_unlock(&av7110->debilock);
591 wake_up(&cibuf->queue);
592 return;
593 }
594
595 case DATA_MPEG_PLAY:
596 if (!av7110->playing) {
597 iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);
598 iwdebi(av7110, DEBINOSWAP, TX_LEN, 0, 2);
599 iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);
600 break;
601 }
602 len = 0;
603 if (av7110->debitype & 0x100) {
604 spin_lock(&av7110->aout.lock);
605 len = av7110_pes_play(av7110->debi_virt, &av7110->aout, 2048);
606 spin_unlock(&av7110->aout.lock);
607 }
608 if (len <= 0 && (av7110->debitype & 0x200)
609 &&av7110->videostate.play_state != VIDEO_FREEZED) {
610 spin_lock(&av7110->avout.lock);
611 len = av7110_pes_play(av7110->debi_virt, &av7110->avout, 2048);
612 spin_unlock(&av7110->avout.lock);
613 }
614 if (len <= 0) {
615 iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);
616 iwdebi(av7110, DEBINOSWAP, TX_LEN, 0, 2);
617 iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);
618 break;
619 }
620 dprintk(8, "GPIO0 PES_PLAY len=%04x\n", len);
621 iwdebi(av7110, DEBINOSWAP, TX_LEN, len, 2);
622 iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, len, 2);
623 dprintk(8, "DMA: MPEG_PLAY\n");
624 start_debi_dma(av7110, DEBI_WRITE, DPRAM_BASE + txbuf, len);
625 spin_unlock(&av7110->debilock);
626 return;
627
628 case DATA_BMP_LOAD:
629 len = av7110->debilen;
630 dprintk(8, "gpio DATA_BMP_LOAD len %d\n", len);
631 if (!len) {
632 av7110->bmp_state = BMP_LOADED;
633 iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);
634 iwdebi(av7110, DEBINOSWAP, TX_LEN, 0, 2);
635 iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);
636 wake_up(&av7110->bmpq);
637 dprintk(8, "gpio DATA_BMP_LOAD done\n");
638 break;
639 }
640 if (len > av7110->bmplen)
641 len = av7110->bmplen;
642 if (len > 2 * 1024)
643 len = 2 * 1024;
644 iwdebi(av7110, DEBINOSWAP, TX_LEN, len, 2);
645 iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, len, 2);
646 memcpy(av7110->debi_virt, av7110->bmpbuf+av7110->bmpp, len);
647 av7110->bmpp += len;
648 av7110->bmplen -= len;
649 dprintk(8, "gpio DATA_BMP_LOAD DMA len %d\n", len);
650 start_debi_dma(av7110, DEBI_WRITE, DPRAM_BASE+txbuf, len);
651 spin_unlock(&av7110->debilock);
652 return;
653
654 case DATA_CI_GET:
655 case DATA_COMMON_INTERFACE:
656 case DATA_FSECTION:
657 case DATA_IPMPE:
658 case DATA_PIPING:
659 if (!len || len > 4 * 1024) {
660 iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
661 break;
662 }
663 /* fall through */
664
665 case DATA_TS_RECORD:
666 case DATA_PES_RECORD:
667 dprintk(8, "DMA: TS_REC etc.\n");
668 start_debi_dma(av7110, DEBI_READ, DPRAM_BASE+rxbuf, len);
669 spin_unlock(&av7110->debilock);
670 return;
671
672 case DATA_DEBUG_MESSAGE:
673 if (!len || len > 0xff) {
674 iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
675 break;
676 }
677 start_debi_dma(av7110, DEBI_READ, Reserved, len);
678 spin_unlock(&av7110->debilock);
679 return;
680
681 case DATA_IRCOMMAND:
Oliver Endriss03388ae2005-09-09 13:03:12 -0700682 if (av7110->ir_handler)
683 av7110->ir_handler(av7110,
684 swahw32(irdebi(av7110, DEBINOSWAP, Reserved, 0, 4)));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700685 iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
686 break;
687
688 default:
689 printk("dvb-ttpci: gpioirq unknown type=%d len=%d\n",
690 av7110->debitype, av7110->debilen);
691 break;
692 }
693 av7110->debitype = -1;
694 ARM_ClearMailBox(av7110);
695 spin_unlock(&av7110->debilock);
696}
697
698
699#ifdef CONFIG_DVB_AV7110_OSD
700static int dvb_osd_ioctl(struct inode *inode, struct file *file,
701 unsigned int cmd, void *parg)
702{
703 struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;
704 struct av7110 *av7110 = (struct av7110 *) dvbdev->priv;
705
706 dprintk(4, "%p\n", av7110);
707
708 if (cmd == OSD_SEND_CMD)
709 return av7110_osd_cmd(av7110, (osd_cmd_t *) parg);
710 if (cmd == OSD_GET_CAPABILITY)
711 return av7110_osd_capability(av7110, (osd_cap_t *) parg);
712
713 return -EINVAL;
714}
715
716
717static struct file_operations dvb_osd_fops = {
718 .owner = THIS_MODULE,
719 .ioctl = dvb_generic_ioctl,
720 .open = dvb_generic_open,
721 .release = dvb_generic_release,
722};
723
724static struct dvb_device dvbdev_osd = {
725 .priv = NULL,
726 .users = 1,
727 .writers = 1,
728 .fops = &dvb_osd_fops,
729 .kernel_ioctl = dvb_osd_ioctl,
730};
731#endif /* CONFIG_DVB_AV7110_OSD */
732
733
734static inline int SetPIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid,
735 u16 subpid, u16 pcrpid)
736{
Dr. Werner Fink47f36922006-01-09 15:25:07 -0200737 u16 aflags = 0;
738
Linus Torvalds1da177e2005-04-16 15:20:36 -0700739 dprintk(4, "%p\n", av7110);
740
741 if (vpid == 0x1fff || apid == 0x1fff ||
742 ttpid == 0x1fff || subpid == 0x1fff || pcrpid == 0x1fff) {
743 vpid = apid = ttpid = subpid = pcrpid = 0;
744 av7110->pids[DMX_PES_VIDEO] = 0;
745 av7110->pids[DMX_PES_AUDIO] = 0;
746 av7110->pids[DMX_PES_TELETEXT] = 0;
747 av7110->pids[DMX_PES_PCR] = 0;
748 }
749
Dr. Werner Fink47f36922006-01-09 15:25:07 -0200750 if (av7110->audiostate.bypass_mode)
751 aflags |= 0x8000;
752
753 return av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, MultiPID, 6,
754 pcrpid, vpid, apid, ttpid, subpid, aflags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700755}
756
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700757int ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700758 u16 subpid, u16 pcrpid)
759{
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700760 int ret = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700761 dprintk(4, "%p\n", av7110);
762
Ingo Molnar3593cab2006-02-07 06:49:14 -0200763 if (mutex_lock_interruptible(&av7110->pid_mutex))
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700764 return -ERESTARTSYS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700765
766 if (!(vpid & 0x8000))
767 av7110->pids[DMX_PES_VIDEO] = vpid;
768 if (!(apid & 0x8000))
769 av7110->pids[DMX_PES_AUDIO] = apid;
770 if (!(ttpid & 0x8000))
771 av7110->pids[DMX_PES_TELETEXT] = ttpid;
772 if (!(pcrpid & 0x8000))
773 av7110->pids[DMX_PES_PCR] = pcrpid;
774
775 av7110->pids[DMX_PES_SUBTITLE] = 0;
776
777 if (av7110->fe_synced) {
778 pcrpid = av7110->pids[DMX_PES_PCR];
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700779 ret = SetPIDs(av7110, vpid, apid, ttpid, subpid, pcrpid);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700780 }
781
Ingo Molnar3593cab2006-02-07 06:49:14 -0200782 mutex_unlock(&av7110->pid_mutex);
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700783 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700784}
785
786
787/******************************************************************************
788 * hardware filter functions
789 ******************************************************************************/
790
791static int StartHWFilter(struct dvb_demux_filter *dvbdmxfilter)
792{
793 struct dvb_demux_feed *dvbdmxfeed = dvbdmxfilter->feed;
794 struct av7110 *av7110 = (struct av7110 *) dvbdmxfeed->demux->priv;
795 u16 buf[20];
796 int ret, i;
797 u16 handle;
798// u16 mode = 0x0320;
799 u16 mode = 0xb96a;
800
801 dprintk(4, "%p\n", av7110);
802
803 if (dvbdmxfilter->type == DMX_TYPE_SEC) {
804 if (hw_sections) {
805 buf[4] = (dvbdmxfilter->filter.filter_value[0] << 8) |
806 dvbdmxfilter->maskandmode[0];
807 for (i = 3; i < 18; i++)
808 buf[i + 4 - 2] =
809 (dvbdmxfilter->filter.filter_value[i] << 8) |
810 dvbdmxfilter->maskandmode[i];
811 mode = 4;
812 }
813 } else if ((dvbdmxfeed->ts_type & TS_PACKET) &&
814 !(dvbdmxfeed->ts_type & TS_PAYLOAD_ONLY)) {
815 av7110_p2t_init(&av7110->p2t_filter[dvbdmxfilter->index], dvbdmxfeed);
816 }
817
818 buf[0] = (COMTYPE_PID_FILTER << 8) + AddPIDFilter;
819 buf[1] = 16;
820 buf[2] = dvbdmxfeed->pid;
821 buf[3] = mode;
822
823 ret = av7110_fw_request(av7110, buf, 20, &handle, 1);
824 if (ret != 0 || handle >= 32) {
825 printk("dvb-ttpci: %s error buf %04x %04x %04x %04x "
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700826 "ret %d handle %04x\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700827 __FUNCTION__, buf[0], buf[1], buf[2], buf[3],
828 ret, handle);
829 dvbdmxfilter->hw_handle = 0xffff;
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700830 if (!ret)
831 ret = -1;
832 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700833 }
834
835 av7110->handle2filter[handle] = dvbdmxfilter;
836 dvbdmxfilter->hw_handle = handle;
837
838 return ret;
839}
840
841static int StopHWFilter(struct dvb_demux_filter *dvbdmxfilter)
842{
843 struct av7110 *av7110 = (struct av7110 *) dvbdmxfilter->feed->demux->priv;
844 u16 buf[3];
845 u16 answ[2];
846 int ret;
847 u16 handle;
848
849 dprintk(4, "%p\n", av7110);
850
851 handle = dvbdmxfilter->hw_handle;
852 if (handle >= 32) {
853 printk("%s tried to stop invalid filter %04x, filter type = %x\n",
854 __FUNCTION__, handle, dvbdmxfilter->type);
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700855 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700856 }
857
858 av7110->handle2filter[handle] = NULL;
859
860 buf[0] = (COMTYPE_PID_FILTER << 8) + DelPIDFilter;
861 buf[1] = 1;
862 buf[2] = handle;
863 ret = av7110_fw_request(av7110, buf, 3, answ, 2);
864 if (ret != 0 || answ[1] != handle) {
865 printk("dvb-ttpci: %s error cmd %04x %04x %04x ret %x "
866 "resp %04x %04x pid %d\n",
867 __FUNCTION__, buf[0], buf[1], buf[2], ret,
868 answ[0], answ[1], dvbdmxfilter->feed->pid);
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700869 if (!ret)
870 ret = -1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700871 }
872 return ret;
873}
874
875
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700876static int dvb_feed_start_pid(struct dvb_demux_feed *dvbdmxfeed)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700877{
878 struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
879 struct av7110 *av7110 = (struct av7110 *) dvbdmx->priv;
880 u16 *pid = dvbdmx->pids, npids[5];
881 int i;
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700882 int ret = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700883
884 dprintk(4, "%p\n", av7110);
885
886 npids[0] = npids[1] = npids[2] = npids[3] = npids[4] = 0xffff;
887 i = dvbdmxfeed->pes_type;
888 npids[i] = (pid[i]&0x8000) ? 0 : pid[i];
889 if ((i == 2) && npids[i] && (dvbdmxfeed->ts_type & TS_PACKET)) {
890 npids[i] = 0;
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700891 ret = ChangePIDs(av7110, npids[1], npids[0], npids[2], npids[3], npids[4]);
892 if (!ret)
893 ret = StartHWFilter(dvbdmxfeed->filter);
894 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700895 }
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700896 if (dvbdmxfeed->pes_type <= 2 || dvbdmxfeed->pes_type == 4) {
897 ret = ChangePIDs(av7110, npids[1], npids[0], npids[2], npids[3], npids[4]);
898 if (ret)
899 return ret;
900 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700901
902 if (dvbdmxfeed->pes_type < 2 && npids[0])
903 if (av7110->fe_synced)
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700904 {
905 ret = av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, Scan, 0);
906 if (ret)
907 return ret;
908 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700909
910 if ((dvbdmxfeed->ts_type & TS_PACKET)) {
911 if (dvbdmxfeed->pes_type == 0 && !(dvbdmx->pids[0] & 0x8000))
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700912 ret = av7110_av_start_record(av7110, RP_AUDIO, dvbdmxfeed);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700913 if (dvbdmxfeed->pes_type == 1 && !(dvbdmx->pids[1] & 0x8000))
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700914 ret = av7110_av_start_record(av7110, RP_VIDEO, dvbdmxfeed);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700915 }
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700916 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700917}
918
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700919static int dvb_feed_stop_pid(struct dvb_demux_feed *dvbdmxfeed)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700920{
921 struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
922 struct av7110 *av7110 = (struct av7110 *) dvbdmx->priv;
923 u16 *pid = dvbdmx->pids, npids[5];
924 int i;
925
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700926 int ret = 0;
927
Linus Torvalds1da177e2005-04-16 15:20:36 -0700928 dprintk(4, "%p\n", av7110);
929
930 if (dvbdmxfeed->pes_type <= 1) {
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700931 ret = av7110_av_stop(av7110, dvbdmxfeed->pes_type ? RP_VIDEO : RP_AUDIO);
932 if (ret)
933 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700934 if (!av7110->rec_mode)
935 dvbdmx->recording = 0;
936 if (!av7110->playing)
937 dvbdmx->playing = 0;
938 }
939 npids[0] = npids[1] = npids[2] = npids[3] = npids[4] = 0xffff;
940 i = dvbdmxfeed->pes_type;
941 switch (i) {
942 case 2: //teletext
943 if (dvbdmxfeed->ts_type & TS_PACKET)
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700944 ret = StopHWFilter(dvbdmxfeed->filter);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700945 npids[2] = 0;
946 break;
947 case 0:
948 case 1:
949 case 4:
950 if (!pids_off)
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700951 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700952 npids[i] = (pid[i]&0x8000) ? 0 : pid[i];
953 break;
954 }
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700955 if (!ret)
956 ret = ChangePIDs(av7110, npids[1], npids[0], npids[2], npids[3], npids[4]);
957 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700958}
959
960static int av7110_start_feed(struct dvb_demux_feed *feed)
961{
962 struct dvb_demux *demux = feed->demux;
963 struct av7110 *av7110 = demux->priv;
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700964 int ret = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700965
966 dprintk(4, "%p\n", av7110);
967
968 if (!demux->dmx.frontend)
969 return -EINVAL;
970
971 if (feed->pid > 0x1fff)
972 return -EINVAL;
973
974 if (feed->type == DMX_TYPE_TS) {
975 if ((feed->ts_type & TS_DECODER) &&
976 (feed->pes_type < DMX_TS_PES_OTHER)) {
977 switch (demux->dmx.frontend->source) {
978 case DMX_MEMORY_FE:
979 if (feed->ts_type & TS_DECODER)
980 if (feed->pes_type < 2 &&
981 !(demux->pids[0] & 0x8000) &&
982 !(demux->pids[1] & 0x8000)) {
983 dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout);
984 dvb_ringbuffer_flush_spinlock_wakeup(&av7110->aout);
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700985 ret = av7110_av_start_play(av7110,RP_AV);
986 if (!ret)
987 demux->playing = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700988 }
989 break;
990 default:
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700991 ret = dvb_feed_start_pid(feed);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700992 break;
993 }
994 } else if ((feed->ts_type & TS_PACKET) &&
995 (demux->dmx.frontend->source != DMX_MEMORY_FE)) {
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -0700996 ret = StartHWFilter(feed->filter);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700997 }
998 }
999
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001000 else if (feed->type == DMX_TYPE_SEC) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001001 int i;
1002
1003 for (i = 0; i < demux->filternum; i++) {
1004 if (demux->filter[i].state != DMX_STATE_READY)
1005 continue;
1006 if (demux->filter[i].type != DMX_TYPE_SEC)
1007 continue;
1008 if (demux->filter[i].filter.parent != &feed->feed.sec)
1009 continue;
1010 demux->filter[i].state = DMX_STATE_GO;
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001011 if (demux->dmx.frontend->source != DMX_MEMORY_FE) {
1012 ret = StartHWFilter(&demux->filter[i]);
1013 if (ret)
1014 break;
1015 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001016 }
1017 }
1018
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001019 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001020}
1021
1022
1023static int av7110_stop_feed(struct dvb_demux_feed *feed)
1024{
1025 struct dvb_demux *demux = feed->demux;
1026 struct av7110 *av7110 = demux->priv;
Johannes Stezenbach12ba0502005-07-07 17:58:00 -07001027 int i, rc, ret = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001028 dprintk(4, "%p\n", av7110);
1029
1030 if (feed->type == DMX_TYPE_TS) {
1031 if (feed->ts_type & TS_DECODER) {
1032 if (feed->pes_type >= DMX_TS_PES_OTHER ||
1033 !demux->pesfilter[feed->pes_type])
1034 return -EINVAL;
1035 demux->pids[feed->pes_type] |= 0x8000;
1036 demux->pesfilter[feed->pes_type] = NULL;
1037 }
1038 if (feed->ts_type & TS_DECODER &&
1039 feed->pes_type < DMX_TS_PES_OTHER) {
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001040 ret = dvb_feed_stop_pid(feed);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001041 } else
1042 if ((feed->ts_type & TS_PACKET) &&
1043 (demux->dmx.frontend->source != DMX_MEMORY_FE))
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001044 ret = StopHWFilter(feed->filter);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001045 }
1046
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001047 if (!ret && feed->type == DMX_TYPE_SEC) {
Johannes Stezenbach12ba0502005-07-07 17:58:00 -07001048 for (i = 0; i<demux->filternum; i++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001049 if (demux->filter[i].state == DMX_STATE_GO &&
1050 demux->filter[i].filter.parent == &feed->feed.sec) {
1051 demux->filter[i].state = DMX_STATE_READY;
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001052 if (demux->dmx.frontend->source != DMX_MEMORY_FE) {
Johannes Stezenbach12ba0502005-07-07 17:58:00 -07001053 rc = StopHWFilter(&demux->filter[i]);
1054 if (!ret)
1055 ret = rc;
1056 /* keep going, stop as many filters as possible */
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001057 }
Johannes Stezenbach12ba0502005-07-07 17:58:00 -07001058 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001059 }
1060 }
1061
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001062 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001063}
1064
1065
1066static void restart_feeds(struct av7110 *av7110)
1067{
1068 struct dvb_demux *dvbdmx = &av7110->demux;
1069 struct dvb_demux_feed *feed;
1070 int mode;
Oliver Endriss66190a22006-01-09 15:32:42 -02001071 int i, j;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001072
1073 dprintk(4, "%p\n", av7110);
1074
1075 mode = av7110->playing;
1076 av7110->playing = 0;
1077 av7110->rec_mode = 0;
1078
Oliver Endriss66190a22006-01-09 15:32:42 -02001079 for (i = 0; i < dvbdmx->feednum; i++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001080 feed = &dvbdmx->feed[i];
Oliver Endriss66190a22006-01-09 15:32:42 -02001081 if (feed->state == DMX_STATE_GO) {
1082 if (feed->type == DMX_TYPE_SEC) {
1083 for (j = 0; j < dvbdmx->filternum; j++) {
1084 if (dvbdmx->filter[j].type != DMX_TYPE_SEC)
1085 continue;
1086 if (dvbdmx->filter[j].filter.parent != &feed->feed.sec)
1087 continue;
1088 if (dvbdmx->filter[j].state == DMX_STATE_GO)
1089 dvbdmx->filter[j].state = DMX_STATE_READY;
1090 }
1091 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001092 av7110_start_feed(feed);
Oliver Endriss66190a22006-01-09 15:32:42 -02001093 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001094 }
1095
1096 if (mode)
1097 av7110_av_start_play(av7110, mode);
1098}
1099
1100static int dvb_get_stc(struct dmx_demux *demux, unsigned int num,
1101 uint64_t *stc, unsigned int *base)
1102{
1103 int ret;
1104 u16 fwstc[4];
1105 u16 tag = ((COMTYPE_REQUEST << 8) + ReqSTC);
1106 struct dvb_demux *dvbdemux;
1107 struct av7110 *av7110;
1108
1109 /* pointer casting paranoia... */
Eric Sesterhennae246012006-03-13 13:17:11 -03001110 BUG_ON(!demux);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001111 dvbdemux = (struct dvb_demux *) demux->priv;
Eric Sesterhennae246012006-03-13 13:17:11 -03001112 BUG_ON(!dvbdemux);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001113 av7110 = (struct av7110 *) dvbdemux->priv;
1114
1115 dprintk(4, "%p\n", av7110);
1116
1117 if (num != 0)
1118 return -EINVAL;
1119
1120 ret = av7110_fw_request(av7110, &tag, 0, fwstc, 4);
1121 if (ret) {
1122 printk(KERN_ERR "%s: av7110_fw_request error\n", __FUNCTION__);
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001123 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001124 }
1125 dprintk(2, "fwstc = %04hx %04hx %04hx %04hx\n",
1126 fwstc[0], fwstc[1], fwstc[2], fwstc[3]);
1127
1128 *stc = (((uint64_t) ((fwstc[3] & 0x8000) >> 15)) << 32) |
1129 (((uint64_t) fwstc[1]) << 16) | ((uint64_t) fwstc[0]);
1130 *base = 1;
1131
1132 dprintk(4, "stc = %lu\n", (unsigned long)*stc);
1133
1134 return 0;
1135}
1136
1137
1138/******************************************************************************
1139 * SEC device file operations
1140 ******************************************************************************/
1141
1142
1143static int av7110_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
1144{
1145 struct av7110* av7110 = (struct av7110*) fe->dvb->priv;
1146
1147 switch (tone) {
1148 case SEC_TONE_ON:
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001149 return Set22K(av7110, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001150
1151 case SEC_TONE_OFF:
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001152 return Set22K(av7110, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001153
1154 default:
1155 return -EINVAL;
1156 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001157}
1158
1159static int av7110_diseqc_send_master_cmd(struct dvb_frontend* fe,
1160 struct dvb_diseqc_master_cmd* cmd)
1161{
1162 struct av7110* av7110 = fe->dvb->priv;
1163
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001164 return av7110_diseqc_send(av7110, cmd->msg_len, cmd->msg, -1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001165}
1166
1167static int av7110_diseqc_send_burst(struct dvb_frontend* fe,
1168 fe_sec_mini_cmd_t minicmd)
1169{
1170 struct av7110* av7110 = fe->dvb->priv;
1171
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001172 return av7110_diseqc_send(av7110, 0, NULL, minicmd);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001173}
1174
1175/* simplified code from budget-core.c */
1176static int stop_ts_capture(struct av7110 *budget)
1177{
1178 dprintk(2, "budget: %p\n", budget);
1179
1180 if (--budget->feeding1)
1181 return budget->feeding1;
1182 saa7146_write(budget->dev, MC1, MASK_20); /* DMA3 off */
1183 SAA7146_IER_DISABLE(budget->dev, MASK_10);
1184 SAA7146_ISR_CLEAR(budget->dev, MASK_10);
1185 return 0;
1186}
1187
1188static int start_ts_capture(struct av7110 *budget)
1189{
1190 dprintk(2, "budget: %p\n", budget);
1191
1192 if (budget->feeding1)
1193 return ++budget->feeding1;
1194 memset(budget->grabbing, 0x00, TS_HEIGHT * TS_WIDTH);
1195 budget->tsf = 0xff;
1196 budget->ttbp = 0;
1197 SAA7146_IER_ENABLE(budget->dev, MASK_10); /* VPE */
1198 saa7146_write(budget->dev, MC1, (MASK_04 | MASK_20)); /* DMA3 on */
1199 return ++budget->feeding1;
1200}
1201
1202static int budget_start_feed(struct dvb_demux_feed *feed)
1203{
1204 struct dvb_demux *demux = feed->demux;
1205 struct av7110 *budget = (struct av7110 *) demux->priv;
1206 int status;
1207
1208 dprintk(2, "av7110: %p\n", budget);
1209
1210 spin_lock(&budget->feedlock1);
1211 feed->pusi_seen = 0; /* have a clean section start */
1212 status = start_ts_capture(budget);
1213 spin_unlock(&budget->feedlock1);
1214 return status;
1215}
1216
1217static int budget_stop_feed(struct dvb_demux_feed *feed)
1218{
1219 struct dvb_demux *demux = feed->demux;
1220 struct av7110 *budget = (struct av7110 *) demux->priv;
1221 int status;
1222
1223 dprintk(2, "budget: %p\n", budget);
1224
1225 spin_lock(&budget->feedlock1);
1226 status = stop_ts_capture(budget);
1227 spin_unlock(&budget->feedlock1);
1228 return status;
1229}
1230
1231static void vpeirq(unsigned long data)
1232{
1233 struct av7110 *budget = (struct av7110 *) data;
1234 u8 *mem = (u8 *) (budget->grabbing);
1235 u32 olddma = budget->ttbp;
1236 u32 newdma = saa7146_read(budget->dev, PCI_VDP3);
1237
1238 if (!budgetpatch) {
1239 printk("av7110.c: vpeirq() called while budgetpatch disabled!"
1240 " check saa7146 IER register\n");
1241 BUG();
1242 }
1243 /* nearest lower position divisible by 188 */
1244 newdma -= newdma % 188;
1245
1246 if (newdma >= TS_BUFLEN)
1247 return;
1248
1249 budget->ttbp = newdma;
1250
1251 if (!budget->feeding1 || (newdma == olddma))
1252 return;
1253
1254#if 0
1255 /* track rps1 activity */
1256 printk("vpeirq: %02x Event Counter 1 0x%04x\n",
1257 mem[olddma],
1258 saa7146_read(budget->dev, EC1R) & 0x3fff);
1259#endif
1260
1261 if (newdma > olddma)
1262 /* no wraparound, dump olddma..newdma */
1263 dvb_dmx_swfilter_packets(&budget->demux1, mem + olddma, (newdma - olddma) / 188);
1264 else {
1265 /* wraparound, dump olddma..buflen and 0..newdma */
1266 dvb_dmx_swfilter_packets(&budget->demux1, mem + olddma, (TS_BUFLEN - olddma) / 188);
1267 dvb_dmx_swfilter_packets(&budget->demux1, mem, newdma / 188);
1268 }
1269}
1270
1271static int av7110_register(struct av7110 *av7110)
1272{
1273 int ret, i;
1274 struct dvb_demux *dvbdemux = &av7110->demux;
1275 struct dvb_demux *dvbdemux1 = &av7110->demux1;
1276
1277 dprintk(4, "%p\n", av7110);
1278
1279 if (av7110->registered)
1280 return -1;
1281
1282 av7110->registered = 1;
1283
1284 dvbdemux->priv = (void *) av7110;
1285
1286 for (i = 0; i < 32; i++)
1287 av7110->handle2filter[i] = NULL;
1288
1289 dvbdemux->filternum = 32;
1290 dvbdemux->feednum = 32;
1291 dvbdemux->start_feed = av7110_start_feed;
1292 dvbdemux->stop_feed = av7110_stop_feed;
1293 dvbdemux->write_to_decoder = av7110_write_to_decoder;
1294 dvbdemux->dmx.capabilities = (DMX_TS_FILTERING | DMX_SECTION_FILTERING |
1295 DMX_MEMORY_BASED_FILTERING);
1296
1297 dvb_dmx_init(&av7110->demux);
1298 av7110->demux.dmx.get_stc = dvb_get_stc;
1299
1300 av7110->dmxdev.filternum = 32;
1301 av7110->dmxdev.demux = &dvbdemux->dmx;
1302 av7110->dmxdev.capabilities = 0;
1303
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001304 dvb_dmxdev_init(&av7110->dmxdev, &av7110->dvb_adapter);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001305
1306 av7110->hw_frontend.source = DMX_FRONTEND_0;
1307
1308 ret = dvbdemux->dmx.add_frontend(&dvbdemux->dmx, &av7110->hw_frontend);
1309
1310 if (ret < 0)
1311 return ret;
1312
1313 av7110->mem_frontend.source = DMX_MEMORY_FE;
1314
1315 ret = dvbdemux->dmx.add_frontend(&dvbdemux->dmx, &av7110->mem_frontend);
1316
1317 if (ret < 0)
1318 return ret;
1319
1320 ret = dvbdemux->dmx.connect_frontend(&dvbdemux->dmx,
1321 &av7110->hw_frontend);
1322 if (ret < 0)
1323 return ret;
1324
1325 av7110_av_register(av7110);
1326 av7110_ca_register(av7110);
1327
1328#ifdef CONFIG_DVB_AV7110_OSD
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001329 dvb_register_device(&av7110->dvb_adapter, &av7110->osd_dev,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001330 &dvbdev_osd, av7110, DVB_DEVICE_OSD);
1331#endif
1332
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001333 dvb_net_init(&av7110->dvb_adapter, &av7110->dvb_net, &dvbdemux->dmx);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001334
1335 if (budgetpatch) {
1336 /* initialize software demux1 without its own frontend
1337 * demux1 hardware is connected to frontend0 of demux0
1338 */
1339 dvbdemux1->priv = (void *) av7110;
1340
1341 dvbdemux1->filternum = 256;
1342 dvbdemux1->feednum = 256;
1343 dvbdemux1->start_feed = budget_start_feed;
1344 dvbdemux1->stop_feed = budget_stop_feed;
1345 dvbdemux1->write_to_decoder = NULL;
1346
1347 dvbdemux1->dmx.capabilities = (DMX_TS_FILTERING | DMX_SECTION_FILTERING |
1348 DMX_MEMORY_BASED_FILTERING);
1349
1350 dvb_dmx_init(&av7110->demux1);
1351
1352 av7110->dmxdev1.filternum = 256;
1353 av7110->dmxdev1.demux = &dvbdemux1->dmx;
1354 av7110->dmxdev1.capabilities = 0;
1355
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001356 dvb_dmxdev_init(&av7110->dmxdev1, &av7110->dvb_adapter);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001357
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001358 dvb_net_init(&av7110->dvb_adapter, &av7110->dvb_net1, &dvbdemux1->dmx);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001359 printk("dvb-ttpci: additional demux1 for budget-patch registered\n");
1360 }
1361 return 0;
1362}
1363
1364
1365static void dvb_unregister(struct av7110 *av7110)
1366{
1367 struct dvb_demux *dvbdemux = &av7110->demux;
1368 struct dvb_demux *dvbdemux1 = &av7110->demux1;
1369
1370 dprintk(4, "%p\n", av7110);
1371
1372 if (!av7110->registered)
1373 return;
1374
1375 if (budgetpatch) {
1376 dvb_net_release(&av7110->dvb_net1);
1377 dvbdemux->dmx.close(&dvbdemux1->dmx);
1378 dvb_dmxdev_release(&av7110->dmxdev1);
1379 dvb_dmx_release(&av7110->demux1);
1380 }
1381
1382 dvb_net_release(&av7110->dvb_net);
1383
1384 dvbdemux->dmx.close(&dvbdemux->dmx);
1385 dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, &av7110->hw_frontend);
1386 dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, &av7110->mem_frontend);
1387
1388 dvb_dmxdev_release(&av7110->dmxdev);
1389 dvb_dmx_release(&av7110->demux);
1390
1391 if (av7110->fe != NULL)
1392 dvb_unregister_frontend(av7110->fe);
1393 dvb_unregister_device(av7110->osd_dev);
1394 av7110_av_unregister(av7110);
1395 av7110_ca_unregister(av7110);
1396}
1397
1398
1399/****************************************************************************
1400 * I2C client commands
1401 ****************************************************************************/
1402
1403int i2c_writereg(struct av7110 *av7110, u8 id, u8 reg, u8 val)
1404{
1405 u8 msg[2] = { reg, val };
1406 struct i2c_msg msgs;
1407
1408 msgs.flags = 0;
1409 msgs.addr = id / 2;
1410 msgs.len = 2;
1411 msgs.buf = msg;
1412 return i2c_transfer(&av7110->i2c_adap, &msgs, 1);
1413}
1414
1415#if 0
1416u8 i2c_readreg(struct av7110 *av7110, u8 id, u8 reg)
1417{
1418 u8 mm1[] = {0x00};
1419 u8 mm2[] = {0x00};
1420 struct i2c_msg msgs[2];
1421
1422 msgs[0].flags = 0;
1423 msgs[1].flags = I2C_M_RD;
1424 msgs[0].addr = msgs[1].addr = id / 2;
1425 mm1[0] = reg;
1426 msgs[0].len = 1; msgs[1].len = 1;
1427 msgs[0].buf = mm1; msgs[1].buf = mm2;
1428 i2c_transfer(&av7110->i2c_adap, msgs, 2);
1429
1430 return mm2[0];
1431}
1432#endif
1433
1434/****************************************************************************
1435 * INITIALIZATION
1436 ****************************************************************************/
1437
1438
1439static int check_firmware(struct av7110* av7110)
1440{
1441 u32 crc = 0, len = 0;
1442 unsigned char *ptr;
1443
1444 /* check for firmware magic */
1445 ptr = av7110->bin_fw;
1446 if (ptr[0] != 'A' || ptr[1] != 'V' ||
1447 ptr[2] != 'F' || ptr[3] != 'W') {
1448 printk("dvb-ttpci: this is not an av7110 firmware\n");
1449 return -EINVAL;
1450 }
1451 ptr += 4;
1452
1453 /* check dpram file */
1454 crc = ntohl(*(u32*) ptr);
1455 ptr += 4;
1456 len = ntohl(*(u32*) ptr);
1457 ptr += 4;
1458 if (len >= 512) {
Alexey Dobriyanbe787ac2006-03-07 22:20:23 -03001459 printk("dvb-ttpci: dpram file is way too big.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001460 return -EINVAL;
1461 }
1462 if (crc != crc32_le(0, ptr, len)) {
1463 printk("dvb-ttpci: crc32 of dpram file does not match.\n");
1464 return -EINVAL;
1465 }
1466 av7110->bin_dpram = ptr;
1467 av7110->size_dpram = len;
1468 ptr += len;
1469
1470 /* check root file */
1471 crc = ntohl(*(u32*) ptr);
1472 ptr += 4;
1473 len = ntohl(*(u32*) ptr);
1474 ptr += 4;
1475
1476 if (len <= 200000 || len >= 300000 ||
1477 len > ((av7110->bin_fw + av7110->size_fw) - ptr)) {
1478 printk("dvb-ttpci: root file has strange size (%d). aborting.\n", len);
1479 return -EINVAL;
1480 }
1481 if( crc != crc32_le(0, ptr, len)) {
1482 printk("dvb-ttpci: crc32 of root file does not match.\n");
1483 return -EINVAL;
1484 }
1485 av7110->bin_root = ptr;
1486 av7110->size_root = len;
1487 return 0;
1488}
1489
1490#ifdef CONFIG_DVB_AV7110_FIRMWARE_FILE
1491#include "av7110_firm.h"
1492static void put_firmware(struct av7110* av7110)
1493{
1494 av7110->bin_fw = NULL;
1495}
1496
1497static inline int get_firmware(struct av7110* av7110)
1498{
1499 av7110->bin_fw = dvb_ttpci_fw;
1500 av7110->size_fw = sizeof(dvb_ttpci_fw);
1501 return check_firmware(av7110);
1502}
1503#else
1504static void put_firmware(struct av7110* av7110)
1505{
1506 vfree(av7110->bin_fw);
1507}
1508
1509static int get_firmware(struct av7110* av7110)
1510{
1511 int ret;
1512 const struct firmware *fw;
1513
1514 /* request the av7110 firmware, this will block until someone uploads it */
1515 ret = request_firmware(&fw, "dvb-ttpci-01.fw", &av7110->dev->pci->dev);
1516 if (ret) {
1517 if (ret == -ENOENT) {
1518 printk(KERN_ERR "dvb-ttpci: could not load firmware,"
1519 " file not found: dvb-ttpci-01.fw\n");
Ville Skytt\ä12e66f62006-01-09 15:25:38 -02001520 printk(KERN_ERR "dvb-ttpci: usually this should be in "
1521 "/usr/lib/hotplug/firmware or /lib/firmware\n");
1522 printk(KERN_ERR "dvb-ttpci: and can be downloaded from"
Linus Torvalds1da177e2005-04-16 15:20:36 -07001523 " http://www.linuxtv.org/download/dvb/firmware/\n");
1524 } else
1525 printk(KERN_ERR "dvb-ttpci: cannot request firmware"
1526 " (error %i)\n", ret);
1527 return -EINVAL;
1528 }
1529
1530 if (fw->size <= 200000) {
1531 printk("dvb-ttpci: this firmware is way too small.\n");
1532 release_firmware(fw);
1533 return -EINVAL;
1534 }
1535
1536 /* check if the firmware is available */
1537 av7110->bin_fw = (unsigned char *) vmalloc(fw->size);
1538 if (NULL == av7110->bin_fw) {
1539 dprintk(1, "out of memory\n");
1540 release_firmware(fw);
1541 return -ENOMEM;
1542 }
1543
1544 memcpy(av7110->bin_fw, fw->data, fw->size);
1545 av7110->size_fw = fw->size;
1546 if ((ret = check_firmware(av7110)))
1547 vfree(av7110->bin_fw);
1548
1549 release_firmware(fw);
1550 return ret;
1551}
1552#endif
1553
1554
1555static int alps_bsrv2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
1556{
1557 struct av7110* av7110 = (struct av7110*) fe->dvb->priv;
1558 u8 pwr = 0;
1559 u8 buf[4];
1560 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
1561 u32 div = (params->frequency + 479500) / 125;
1562
1563 if (params->frequency > 2000000) pwr = 3;
1564 else if (params->frequency > 1800000) pwr = 2;
1565 else if (params->frequency > 1600000) pwr = 1;
1566 else if (params->frequency > 1200000) pwr = 0;
1567 else if (params->frequency >= 1100000) pwr = 1;
1568 else pwr = 2;
1569
1570 buf[0] = (div >> 8) & 0x7f;
1571 buf[1] = div & 0xff;
1572 buf[2] = ((div & 0x18000) >> 10) | 0x95;
1573 buf[3] = (pwr << 6) | 0x30;
1574
Mauro Carvalho Chehab9101e622005-12-12 00:37:24 -08001575 // NOTE: since we're using a prescaler of 2, we set the
Linus Torvalds1da177e2005-04-16 15:20:36 -07001576 // divisor frequency to 62.5kHz and divide by 125 above
1577
1578 if (i2c_transfer (&av7110->i2c_adap, &msg, 1) != 1)
1579 return -EIO;
1580 return 0;
1581}
1582
1583static struct ves1x93_config alps_bsrv2_config = {
1584 .demod_address = 0x08,
1585 .xin = 90100000UL,
1586 .invert_pwm = 0,
1587 .pll_set = alps_bsrv2_pll_set,
1588};
1589
Linus Torvalds1da177e2005-04-16 15:20:36 -07001590static int alps_tdbe2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
1591{
1592 struct av7110* av7110 = fe->dvb->priv;
1593 u32 div;
1594 u8 data[4];
1595 struct i2c_msg msg = { .addr = 0x62, .flags = 0, .buf = data, .len = sizeof(data) };
1596
1597 div = (params->frequency + 35937500 + 31250) / 62500;
1598
1599 data[0] = (div >> 8) & 0x7f;
1600 data[1] = div & 0xff;
1601 data[2] = 0x85 | ((div >> 10) & 0x60);
1602 data[3] = (params->frequency < 174000000 ? 0x88 : params->frequency < 470000000 ? 0x84 : 0x81);
1603
1604 if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1)
1605 return -EIO;
1606 return 0;
1607}
1608
1609static struct ves1820_config alps_tdbe2_config = {
1610 .demod_address = 0x09,
1611 .xin = 57840000UL,
1612 .invert = 1,
1613 .selagc = VES1820_SELAGC_SIGNAMPERR,
1614 .pll_set = alps_tdbe2_pll_set,
1615};
1616
1617
1618
1619
1620static int grundig_29504_451_pll_set(struct dvb_frontend* fe,
1621 struct dvb_frontend_parameters* params)
1622{
1623 struct av7110* av7110 = fe->dvb->priv;
1624 u32 div;
1625 u8 data[4];
1626 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
1627
1628 div = params->frequency / 125;
1629 data[0] = (div >> 8) & 0x7f;
1630 data[1] = div & 0xff;
1631 data[2] = 0x8e;
1632 data[3] = 0x00;
1633
1634 if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1)
1635 return -EIO;
1636 return 0;
1637}
1638
1639static struct tda8083_config grundig_29504_451_config = {
1640 .demod_address = 0x68,
1641 .pll_set = grundig_29504_451_pll_set,
1642};
1643
1644
1645
1646static int philips_cd1516_pll_set(struct dvb_frontend* fe,
1647 struct dvb_frontend_parameters* params)
1648{
Mauro Carvalho Chehab9101e622005-12-12 00:37:24 -08001649 struct av7110* av7110 = fe->dvb->priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001650 u32 div;
1651 u32 f = params->frequency;
1652 u8 data[4];
1653 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
1654
1655 div = (f + 36125000 + 31250) / 62500;
1656
1657 data[0] = (div >> 8) & 0x7f;
1658 data[1] = div & 0xff;
1659 data[2] = 0x8e;
1660 data[3] = (f < 174000000 ? 0xa1 : f < 470000000 ? 0x92 : 0x34);
1661
1662 if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1)
1663 return -EIO;
1664 return 0;
1665}
1666
1667static struct ves1820_config philips_cd1516_config = {
1668 .demod_address = 0x09,
1669 .xin = 57840000UL,
1670 .invert = 1,
1671 .selagc = VES1820_SELAGC_SIGNAMPERR,
1672 .pll_set = philips_cd1516_pll_set,
1673};
1674
1675
1676
1677static int alps_tdlb7_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
1678{
1679 struct av7110* av7110 = fe->dvb->priv;
1680 u32 div, pwr;
1681 u8 data[4];
1682 struct i2c_msg msg = { .addr = 0x60, .flags = 0, .buf = data, .len = sizeof(data) };
1683
1684 div = (params->frequency + 36200000) / 166666;
1685
1686 if (params->frequency <= 782000000)
1687 pwr = 1;
1688 else
1689 pwr = 2;
1690
1691 data[0] = (div >> 8) & 0x7f;
1692 data[1] = div & 0xff;
1693 data[2] = 0x85;
1694 data[3] = pwr << 6;
1695
1696 if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1)
1697 return -EIO;
1698 return 0;
1699}
1700
1701static int alps_tdlb7_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name)
1702{
1703 struct av7110* av7110 = (struct av7110*) fe->dvb->priv;
1704
1705 return request_firmware(fw, name, &av7110->dev->pci->dev);
1706}
1707
1708static struct sp8870_config alps_tdlb7_config = {
1709
1710 .demod_address = 0x71,
1711 .pll_set = alps_tdlb7_pll_set,
1712 .request_firmware = alps_tdlb7_request_firmware,
1713};
1714
1715
Andrew de Quinceydc27a162005-09-09 13:03:07 -07001716static u8 nexusca_stv0297_inittab[] = {
1717 0x80, 0x01,
1718 0x80, 0x00,
1719 0x81, 0x01,
1720 0x81, 0x00,
1721 0x00, 0x09,
1722 0x01, 0x69,
1723 0x03, 0x00,
1724 0x04, 0x00,
1725 0x07, 0x00,
1726 0x08, 0x00,
1727 0x20, 0x00,
1728 0x21, 0x40,
1729 0x22, 0x00,
1730 0x23, 0x00,
1731 0x24, 0x40,
1732 0x25, 0x88,
1733 0x30, 0xff,
1734 0x31, 0x00,
1735 0x32, 0xff,
1736 0x33, 0x00,
1737 0x34, 0x50,
1738 0x35, 0x7f,
1739 0x36, 0x00,
1740 0x37, 0x20,
1741 0x38, 0x00,
1742 0x40, 0x1c,
1743 0x41, 0xff,
1744 0x42, 0x29,
1745 0x43, 0x00,
1746 0x44, 0xff,
1747 0x45, 0x00,
1748 0x46, 0x00,
1749 0x49, 0x04,
1750 0x4a, 0x00,
1751 0x4b, 0x7b,
1752 0x52, 0x30,
1753 0x55, 0xae,
1754 0x56, 0x47,
1755 0x57, 0xe1,
1756 0x58, 0x3a,
1757 0x5a, 0x1e,
1758 0x5b, 0x34,
1759 0x60, 0x00,
1760 0x63, 0x00,
1761 0x64, 0x00,
1762 0x65, 0x00,
1763 0x66, 0x00,
1764 0x67, 0x00,
1765 0x68, 0x00,
1766 0x69, 0x00,
1767 0x6a, 0x02,
1768 0x6b, 0x00,
1769 0x70, 0xff,
1770 0x71, 0x00,
1771 0x72, 0x00,
1772 0x73, 0x00,
1773 0x74, 0x0c,
1774 0x80, 0x00,
1775 0x81, 0x00,
1776 0x82, 0x00,
1777 0x83, 0x00,
1778 0x84, 0x04,
1779 0x85, 0x80,
1780 0x86, 0x24,
1781 0x87, 0x78,
1782 0x88, 0x10,
1783 0x89, 0x00,
1784 0x90, 0x01,
1785 0x91, 0x01,
1786 0xa0, 0x04,
1787 0xa1, 0x00,
1788 0xa2, 0x00,
1789 0xb0, 0x91,
1790 0xb1, 0x0b,
1791 0xc0, 0x53,
1792 0xc1, 0x70,
1793 0xc2, 0x12,
1794 0xd0, 0x00,
1795 0xd1, 0x00,
1796 0xd2, 0x00,
1797 0xd3, 0x00,
1798 0xd4, 0x00,
1799 0xd5, 0x00,
1800 0xde, 0x00,
1801 0xdf, 0x00,
1802 0x61, 0x49,
1803 0x62, 0x0b,
1804 0x53, 0x08,
1805 0x59, 0x08,
1806 0xff, 0xff,
1807};
Linus Torvalds1da177e2005-04-16 15:20:36 -07001808
1809static int nexusca_stv0297_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
1810{
1811 struct av7110* av7110 = fe->dvb->priv;
1812 u32 div;
1813 u8 data[4];
1814 struct i2c_msg msg = { .addr = 0x63, .flags = 0, .buf = data, .len = sizeof(data) };
1815 struct i2c_msg readmsg = { .addr = 0x63, .flags = I2C_M_RD, .buf = data, .len = 1 };
1816 int i;
1817
1818 div = (params->frequency + 36150000 + 31250) / 62500;
1819
1820 data[0] = (div >> 8) & 0x7f;
1821 data[1] = div & 0xff;
1822 data[2] = 0xce;
1823
1824 if (params->frequency < 45000000)
1825 return -EINVAL;
1826 else if (params->frequency < 137000000)
1827 data[3] = 0x01;
1828 else if (params->frequency < 403000000)
1829 data[3] = 0x02;
1830 else if (params->frequency < 860000000)
1831 data[3] = 0x04;
1832 else
1833 return -EINVAL;
1834
1835 stv0297_enable_plli2c(fe);
1836 if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1) {
1837 printk("nexusca: pll transfer failed!\n");
1838 return -EIO;
1839 }
1840
1841 // wait for PLL lock
1842 for(i = 0; i < 20; i++) {
1843
1844 stv0297_enable_plli2c(fe);
1845 if (i2c_transfer(&av7110->i2c_adap, &readmsg, 1) == 1)
1846 if (data[0] & 0x40) break;
1847 msleep(10);
1848 }
1849
1850 return 0;
1851}
1852
1853static struct stv0297_config nexusca_stv0297_config = {
1854
1855 .demod_address = 0x1C,
Andrew de Quinceydc27a162005-09-09 13:03:07 -07001856 .inittab = nexusca_stv0297_inittab,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001857 .invert = 1,
1858 .pll_set = nexusca_stv0297_pll_set,
1859};
1860
1861
1862
1863static int grundig_29504_401_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
1864{
1865 struct av7110* av7110 = (struct av7110*) fe->dvb->priv;
1866 u32 div;
1867 u8 cfg, cpump, band_select;
1868 u8 data[4];
1869 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
1870
1871 div = (36125000 + params->frequency) / 166666;
1872
1873 cfg = 0x88;
1874
1875 if (params->frequency < 175000000) cpump = 2;
1876 else if (params->frequency < 390000000) cpump = 1;
1877 else if (params->frequency < 470000000) cpump = 2;
1878 else if (params->frequency < 750000000) cpump = 1;
1879 else cpump = 3;
1880
1881 if (params->frequency < 175000000) band_select = 0x0e;
1882 else if (params->frequency < 470000000) band_select = 0x05;
1883 else band_select = 0x03;
1884
1885 data[0] = (div >> 8) & 0x7f;
1886 data[1] = div & 0xff;
1887 data[2] = ((div >> 10) & 0x60) | cfg;
1888 data[3] = (cpump << 6) | band_select;
1889
1890 if (i2c_transfer (&av7110->i2c_adap, &msg, 1) != 1) return -EIO;
1891 return 0;
1892}
1893
1894static struct l64781_config grundig_29504_401_config = {
1895 .demod_address = 0x55,
1896 .pll_set = grundig_29504_401_pll_set,
1897};
1898
1899
1900
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001901static int av7110_fe_lock_fix(struct av7110* av7110, fe_status_t status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001902{
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001903 int ret = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001904 int synced = (status & FE_HAS_LOCK) ? 1 : 0;
1905
1906 av7110->fe_status = status;
1907
1908 if (av7110->fe_synced == synced)
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001909 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001910
Linus Torvalds1da177e2005-04-16 15:20:36 -07001911 if (av7110->playing)
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001912 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001913
Ingo Molnar3593cab2006-02-07 06:49:14 -02001914 if (mutex_lock_interruptible(&av7110->pid_mutex))
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001915 return -ERESTARTSYS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001916
Oliver Endriss34612152005-07-07 17:58:02 -07001917 if (synced) {
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001918 ret = SetPIDs(av7110, av7110->pids[DMX_PES_VIDEO],
Linus Torvalds1da177e2005-04-16 15:20:36 -07001919 av7110->pids[DMX_PES_AUDIO],
1920 av7110->pids[DMX_PES_TELETEXT], 0,
1921 av7110->pids[DMX_PES_PCR]);
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001922 if (!ret)
1923 ret = av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, Scan, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001924 } else {
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001925 ret = SetPIDs(av7110, 0, 0, 0, 0, 0);
1926 if (!ret) {
1927 ret = av7110_fw_cmd(av7110, COMTYPE_PID_FILTER, FlushTSQueue, 0);
1928 if (!ret)
1929 ret = av7110_wait_msgstate(av7110, GPMQBusy);
1930 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001931 }
1932
Oliver Endriss34612152005-07-07 17:58:02 -07001933 if (!ret)
1934 av7110->fe_synced = synced;
1935
Ingo Molnar3593cab2006-02-07 06:49:14 -02001936 mutex_unlock(&av7110->pid_mutex);
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001937 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001938}
1939
1940static int av7110_fe_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
1941{
1942 struct av7110* av7110 = fe->dvb->priv;
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001943
1944 int ret = av7110_fe_lock_fix(av7110, 0);
Oliver Endriss66190a22006-01-09 15:32:42 -02001945 if (!ret) {
1946 av7110->saved_fe_params = *params;
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001947 ret = av7110->fe_set_frontend(fe, params);
Oliver Endriss66190a22006-01-09 15:32:42 -02001948 }
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001949 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001950}
1951
1952static int av7110_fe_init(struct dvb_frontend* fe)
1953{
1954 struct av7110* av7110 = fe->dvb->priv;
1955
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001956 int ret = av7110_fe_lock_fix(av7110, 0);
1957 if (!ret)
1958 ret = av7110->fe_init(fe);
1959 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001960}
1961
1962static int av7110_fe_read_status(struct dvb_frontend* fe, fe_status_t* status)
1963{
1964 struct av7110* av7110 = fe->dvb->priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001965
1966 /* call the real implementation */
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001967 int ret = av7110->fe_read_status(fe, status);
1968 if (!ret)
1969 if (((*status ^ av7110->fe_status) & FE_HAS_LOCK) && (*status & FE_HAS_LOCK))
1970 ret = av7110_fe_lock_fix(av7110, *status);
1971 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001972}
1973
1974static int av7110_fe_diseqc_reset_overload(struct dvb_frontend* fe)
1975{
1976 struct av7110* av7110 = fe->dvb->priv;
1977
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001978 int ret = av7110_fe_lock_fix(av7110, 0);
1979 if (!ret)
1980 ret = av7110->fe_diseqc_reset_overload(fe);
1981 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001982}
1983
1984static int av7110_fe_diseqc_send_master_cmd(struct dvb_frontend* fe,
1985 struct dvb_diseqc_master_cmd* cmd)
1986{
1987 struct av7110* av7110 = fe->dvb->priv;
1988
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001989 int ret = av7110_fe_lock_fix(av7110, 0);
Oliver Endriss66190a22006-01-09 15:32:42 -02001990 if (!ret) {
1991 av7110->saved_master_cmd = *cmd;
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001992 ret = av7110->fe_diseqc_send_master_cmd(fe, cmd);
Oliver Endriss66190a22006-01-09 15:32:42 -02001993 }
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07001994 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001995}
1996
1997static int av7110_fe_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd)
1998{
1999 struct av7110* av7110 = fe->dvb->priv;
2000
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002001 int ret = av7110_fe_lock_fix(av7110, 0);
Oliver Endriss66190a22006-01-09 15:32:42 -02002002 if (!ret) {
2003 av7110->saved_minicmd = minicmd;
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002004 ret = av7110->fe_diseqc_send_burst(fe, minicmd);
Oliver Endriss66190a22006-01-09 15:32:42 -02002005 }
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002006 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002007}
2008
2009static int av7110_fe_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
2010{
2011 struct av7110* av7110 = fe->dvb->priv;
2012
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002013 int ret = av7110_fe_lock_fix(av7110, 0);
Oliver Endriss66190a22006-01-09 15:32:42 -02002014 if (!ret) {
2015 av7110->saved_tone = tone;
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002016 ret = av7110->fe_set_tone(fe, tone);
Oliver Endriss66190a22006-01-09 15:32:42 -02002017 }
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002018 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002019}
2020
2021static int av7110_fe_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
2022{
2023 struct av7110* av7110 = fe->dvb->priv;
2024
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002025 int ret = av7110_fe_lock_fix(av7110, 0);
Oliver Endriss66190a22006-01-09 15:32:42 -02002026 if (!ret) {
2027 av7110->saved_voltage = voltage;
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002028 ret = av7110->fe_set_voltage(fe, voltage);
Oliver Endriss66190a22006-01-09 15:32:42 -02002029 }
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002030 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002031}
2032
Peter Beutner400b7082006-01-09 15:32:43 -02002033static int av7110_fe_dishnetwork_send_legacy_command(struct dvb_frontend* fe, unsigned long cmd)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002034{
2035 struct av7110* av7110 = fe->dvb->priv;
2036
Wolfgang Rohdewaldce18a222005-07-07 17:57:59 -07002037 int ret = av7110_fe_lock_fix(av7110, 0);
2038 if (!ret)
2039 ret = av7110->fe_dishnetwork_send_legacy_command(fe, cmd);
2040 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002041}
2042
Oliver Endriss66190a22006-01-09 15:32:42 -02002043static void dvb_s_recover(struct av7110* av7110)
2044{
2045 av7110_fe_init(av7110->fe);
2046
2047 av7110_fe_set_voltage(av7110->fe, av7110->saved_voltage);
2048 if (av7110->saved_master_cmd.msg_len) {
2049 msleep(20);
2050 av7110_fe_diseqc_send_master_cmd(av7110->fe, &av7110->saved_master_cmd);
2051 }
2052 msleep(20);
2053 av7110_fe_diseqc_send_burst(av7110->fe, av7110->saved_minicmd);
2054 msleep(20);
2055 av7110_fe_set_tone(av7110->fe, av7110->saved_tone);
2056
2057 av7110_fe_set_frontend(av7110->fe, &av7110->saved_fe_params);
2058}
2059
Linus Torvalds1da177e2005-04-16 15:20:36 -07002060static u8 read_pwm(struct av7110* av7110)
2061{
2062 u8 b = 0xff;
2063 u8 pwm;
2064 struct i2c_msg msg[] = { { .addr = 0x50,.flags = 0,.buf = &b,.len = 1 },
2065 { .addr = 0x50,.flags = I2C_M_RD,.buf = &pwm,.len = 1} };
2066
Mauro Carvalho Chehab9101e622005-12-12 00:37:24 -08002067 if ((i2c_transfer(&av7110->i2c_adap, msg, 2) != 2) || (pwm == 0xff))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002068 pwm = 0x48;
2069
2070 return pwm;
2071}
2072
2073static int frontend_init(struct av7110 *av7110)
2074{
2075 int ret;
2076
2077 if (av7110->dev->pci->subsystem_vendor == 0x110a) {
2078 switch(av7110->dev->pci->subsystem_device) {
2079 case 0x0000: // Fujitsu/Siemens DVB-Cable (ves1820/Philips CD1516(??))
2080 av7110->fe = ves1820_attach(&philips_cd1516_config,
2081 &av7110->i2c_adap, read_pwm(av7110));
2082 break;
2083 }
2084
2085 } else if (av7110->dev->pci->subsystem_vendor == 0x13c2) {
2086 switch(av7110->dev->pci->subsystem_device) {
2087 case 0x0000: // Hauppauge/TT WinTV DVB-S rev1.X
2088 case 0x0003: // Hauppauge/TT WinTV Nexus-S Rev 2.X
2089 case 0x1002: // Hauppauge/TT WinTV DVB-S rev1.3SE
2090
2091 // try the ALPS BSRV2 first of all
2092 av7110->fe = ves1x93_attach(&alps_bsrv2_config, &av7110->i2c_adap);
2093 if (av7110->fe) {
2094 av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd;
2095 av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst;
2096 av7110->fe->ops->set_tone = av7110_set_tone;
Oliver Endriss66190a22006-01-09 15:32:42 -02002097 av7110->recover = dvb_s_recover;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002098 break;
2099 }
2100
2101 // try the ALPS BSRU6 now
2102 av7110->fe = stv0299_attach(&alps_bsru6_config, &av7110->i2c_adap);
2103 if (av7110->fe) {
2104 av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd;
2105 av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst;
2106 av7110->fe->ops->set_tone = av7110_set_tone;
Oliver Endriss66190a22006-01-09 15:32:42 -02002107 av7110->recover = dvb_s_recover;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002108 break;
2109 }
2110
2111 // Try the grundig 29504-451
Michael Krufky50c25ff2006-01-09 15:25:34 -02002112 av7110->fe = tda8083_attach(&grundig_29504_451_config, &av7110->i2c_adap);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002113 if (av7110->fe) {
2114 av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd;
2115 av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst;
2116 av7110->fe->ops->set_tone = av7110_set_tone;
Oliver Endriss66190a22006-01-09 15:32:42 -02002117 av7110->recover = dvb_s_recover;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002118 break;
2119 }
2120
2121 /* Try DVB-C cards */
2122 switch(av7110->dev->pci->subsystem_device) {
2123 case 0x0000:
2124 /* Siemens DVB-C (full-length card) VES1820/Philips CD1516 */
2125 av7110->fe = ves1820_attach(&philips_cd1516_config, &av7110->i2c_adap,
2126 read_pwm(av7110));
2127 break;
2128 case 0x0003:
Adrian Bunkf3688fc2006-03-29 22:46:12 -03002129 /* Hauppauge DVB-C 2.1 VES1820/ALPS TDBE2 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002130 av7110->fe = ves1820_attach(&alps_tdbe2_config, &av7110->i2c_adap,
2131 read_pwm(av7110));
2132 break;
2133 }
2134 break;
2135
2136 case 0x0001: // Hauppauge/TT Nexus-T premium rev1.X
2137
2138 // ALPS TDLB7
Michael Krufky50c25ff2006-01-09 15:25:34 -02002139 av7110->fe = sp8870_attach(&alps_tdlb7_config, &av7110->i2c_adap);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002140 break;
2141
2142 case 0x0002: // Hauppauge/TT DVB-C premium rev2.X
2143
Michael Krufky50c25ff2006-01-09 15:25:34 -02002144 av7110->fe = ves1820_attach(&alps_tdbe2_config, &av7110->i2c_adap, read_pwm(av7110));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002145 break;
2146
Oliver Endriss8bd63012006-02-07 06:49:11 -02002147 case 0x0004: // Galaxis DVB-S rev1.3
2148 /* ALPS BSRV2 */
2149 av7110->fe = ves1x93_attach(&alps_bsrv2_config, &av7110->i2c_adap);
2150 if (av7110->fe) {
2151 av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd;
2152 av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst;
2153 av7110->fe->ops->set_tone = av7110_set_tone;
2154 av7110->recover = dvb_s_recover;
2155 }
2156 break;
2157
Linus Torvalds1da177e2005-04-16 15:20:36 -07002158 case 0x0006: /* Fujitsu-Siemens DVB-S rev 1.6 */
2159 /* Grundig 29504-451 */
2160 av7110->fe = tda8083_attach(&grundig_29504_451_config, &av7110->i2c_adap);
2161 if (av7110->fe) {
2162 av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd;
2163 av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst;
2164 av7110->fe->ops->set_tone = av7110_set_tone;
Oliver Endriss66190a22006-01-09 15:32:42 -02002165 av7110->recover = dvb_s_recover;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002166 }
2167 break;
2168
2169 case 0x0008: // Hauppauge/TT DVB-T
2170
2171 av7110->fe = l64781_attach(&grundig_29504_401_config, &av7110->i2c_adap);
2172 break;
2173
2174 case 0x000A: // Hauppauge/TT Nexus-CA rev1.X
2175
Andrew de Quinceydc27a162005-09-09 13:03:07 -07002176 av7110->fe = stv0297_attach(&nexusca_stv0297_config, &av7110->i2c_adap);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002177 if (av7110->fe) {
2178 /* set TDA9819 into DVB mode */
2179 saa7146_setgpio(av7110->dev, 1, SAA7146_GPIO_OUTLO); // TDA9198 pin9(STD)
2180 saa7146_setgpio(av7110->dev, 3, SAA7146_GPIO_OUTLO); // TDA9198 pin30(VIF)
2181
2182 /* tuner on this needs a slower i2c bus speed */
2183 av7110->dev->i2c_bitrate = SAA7146_I2C_BUS_BIT_RATE_240;
2184 break;
2185 }
Johannes Stezenbach3dfaebd2005-05-16 21:54:19 -07002186 break;
2187
2188 case 0x000E: /* Hauppauge/TT Nexus-S rev 2.3 */
2189 /* ALPS BSBE1 */
2190 av7110->fe = stv0299_attach(&alps_bsbe1_config, &av7110->i2c_adap);
Oliver Endrisseb3daf32006-01-09 15:25:05 -02002191 if (av7110->fe) {
Oliver Endrissdb5d91e2006-02-28 10:32:25 -03002192 if (lnbp21_init(av7110->fe, &av7110->i2c_adap, 0, 0)) {
2193 printk("dvb-ttpci: LNBP21 not found!\n");
2194 if (av7110->fe->ops->release)
2195 av7110->fe->ops->release(av7110->fe);
2196 av7110->fe = NULL;
2197 } else {
2198 av7110->fe->ops->dishnetwork_send_legacy_command = NULL;
2199 av7110->recover = dvb_s_recover;
2200 }
Oliver Endrisseb3daf32006-01-09 15:25:05 -02002201 }
Johannes Stezenbach3dfaebd2005-05-16 21:54:19 -07002202 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002203 }
2204 }
2205
2206 if (!av7110->fe) {
2207 /* FIXME: propagate the failure code from the lower layers */
2208 ret = -ENOMEM;
2209 printk("dvb-ttpci: A frontend driver was not found for device %04x/%04x subsystem %04x/%04x\n",
2210 av7110->dev->pci->vendor,
2211 av7110->dev->pci->device,
2212 av7110->dev->pci->subsystem_vendor,
2213 av7110->dev->pci->subsystem_device);
2214 } else {
2215 FE_FUNC_OVERRIDE(av7110->fe->ops->init, av7110->fe_init, av7110_fe_init);
2216 FE_FUNC_OVERRIDE(av7110->fe->ops->read_status, av7110->fe_read_status, av7110_fe_read_status);
2217 FE_FUNC_OVERRIDE(av7110->fe->ops->diseqc_reset_overload, av7110->fe_diseqc_reset_overload, av7110_fe_diseqc_reset_overload);
2218 FE_FUNC_OVERRIDE(av7110->fe->ops->diseqc_send_master_cmd, av7110->fe_diseqc_send_master_cmd, av7110_fe_diseqc_send_master_cmd);
2219 FE_FUNC_OVERRIDE(av7110->fe->ops->diseqc_send_burst, av7110->fe_diseqc_send_burst, av7110_fe_diseqc_send_burst);
2220 FE_FUNC_OVERRIDE(av7110->fe->ops->set_tone, av7110->fe_set_tone, av7110_fe_set_tone);
2221 FE_FUNC_OVERRIDE(av7110->fe->ops->set_voltage, av7110->fe_set_voltage, av7110_fe_set_voltage;)
2222 FE_FUNC_OVERRIDE(av7110->fe->ops->dishnetwork_send_legacy_command, av7110->fe_dishnetwork_send_legacy_command, av7110_fe_dishnetwork_send_legacy_command);
2223 FE_FUNC_OVERRIDE(av7110->fe->ops->set_frontend, av7110->fe_set_frontend, av7110_fe_set_frontend);
2224
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07002225 ret = dvb_register_frontend(&av7110->dvb_adapter, av7110->fe);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002226 if (ret < 0) {
2227 printk("av7110: Frontend registration failed!\n");
2228 if (av7110->fe->ops->release)
2229 av7110->fe->ops->release(av7110->fe);
2230 av7110->fe = NULL;
2231 }
2232 }
2233 return ret;
2234}
2235
2236/* Budgetpatch note:
2237 * Original hardware design by Roberto Deza:
2238 * There is a DVB_Wiki at
2239 * http://212.227.36.83/linuxtv/wiki/index.php/Main_Page
2240 * where is described this 'DVB TT Budget Patch', on Card Modding:
2241 * http://212.227.36.83/linuxtv/wiki/index.php/DVB_TT_Budget_Patch
2242 * On the short description there is also a link to a external file,
2243 * with more details:
2244 * http://perso.wanadoo.es/jesussolano/Ttf_tsc1.zip
2245 *
2246 * New software triggering design by Emard that works on
2247 * original Roberto Deza's hardware:
2248 *
2249 * rps1 code for budgetpatch will copy internal HS event to GPIO3 pin.
2250 * GPIO3 is in budget-patch hardware connectd to port B VSYNC
2251 * HS is an internal event of 7146, accessible with RPS
2252 * and temporarily raised high every n lines
2253 * (n in defined in the RPS_THRESH1 counter threshold)
2254 * I think HS is raised high on the beginning of the n-th line
2255 * and remains high until this n-th line that triggered
2256 * it is completely received. When the receiption of n-th line
2257 * ends, HS is lowered.
2258 *
2259 * To transmit data over DMA, 7146 needs changing state at
2260 * port B VSYNC pin. Any changing of port B VSYNC will
2261 * cause some DMA data transfer, with more or less packets loss.
2262 * It depends on the phase and frequency of VSYNC and
2263 * the way of 7146 is instructed to trigger on port B (defined
2264 * in DD1_INIT register, 3rd nibble from the right valid
2265 * numbers are 0-7, see datasheet)
2266 *
2267 * The correct triggering can minimize packet loss,
2268 * dvbtraffic should give this stable bandwidths:
2269 * 22k transponder = 33814 kbit/s
2270 * 27.5k transponder = 38045 kbit/s
2271 * by experiment it is found that the best results
2272 * (stable bandwidths and almost no packet loss)
2273 * are obtained using DD1_INIT triggering number 2
2274 * (Va at rising edge of VS Fa = HS x VS-failing forced toggle)
2275 * and a VSYNC phase that occurs in the middle of DMA transfer
2276 * (about byte 188*512=96256 in the DMA window).
2277 *
2278 * Phase of HS is still not clear to me how to control,
2279 * It just happens to be so. It can be seen if one enables
2280 * RPS_IRQ and print Event Counter 1 in vpeirq(). Every
2281 * time RPS_INTERRUPT is called, the Event Counter 1 will
2282 * increment. That's how the 7146 is programmed to do event
2283 * counting in this budget-patch.c
2284 * I *think* HPS setting has something to do with the phase
2285 * of HS but I cant be 100% sure in that.
2286 *
2287 * hardware debug note: a working budget card (including budget patch)
2288 * with vpeirq() interrupt setup in mode "0x90" (every 64K) will
2289 * generate 3 interrupts per 25-Hz DMA frame of 2*188*512 bytes
2290 * and that means 3*25=75 Hz of interrupt freqency, as seen by
2291 * watch cat /proc/interrupts
2292 *
2293 * If this frequency is 3x lower (and data received in the DMA
2294 * buffer don't start with 0x47, but in the middle of packets,
2295 * whose lengths appear to be like 188 292 188 104 etc.
2296 * this means VSYNC line is not connected in the hardware.
2297 * (check soldering pcb and pins)
2298 * The same behaviour of missing VSYNC can be duplicated on budget
2299 * cards, by seting DD1_INIT trigger mode 7 in 3rd nibble.
2300 */
Johannes Stezenbach1be11e32006-02-27 00:09:20 -03002301static int __devinit av7110_attach(struct saa7146_dev* dev,
2302 struct saa7146_pci_extension_data *pci_ext)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002303{
2304 const int length = TS_WIDTH * TS_HEIGHT;
2305 struct pci_dev *pdev = dev->pci;
2306 struct av7110 *av7110;
2307 int ret, count = 0;
2308
2309 dprintk(4, "dev: %p\n", dev);
2310
Mauro Carvalho Chehab9101e622005-12-12 00:37:24 -08002311 /* Set RPS_IRQ to 1 to track rps1 activity.
2312 * Enabling this won't send any interrupt to PC CPU.
2313 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002314#define RPS_IRQ 0
2315
2316 if (budgetpatch == 1) {
2317 budgetpatch = 0;
2318 /* autodetect the presence of budget patch
2319 * this only works if saa7146 has been recently
2320 * reset with with MASK_31 to MC1
2321 *
2322 * will wait for VBI_B event (vertical blank at port B)
2323 * and will reset GPIO3 after VBI_B is detected.
2324 * (GPIO3 should be raised high by CPU to
2325 * test if GPIO3 will generate vertical blank signal
2326 * in budget patch GPIO3 is connected to VSYNC_B
2327 */
2328
2329 /* RESET SAA7146 */
2330 saa7146_write(dev, MC1, MASK_31);
2331 /* autodetection success seems to be time-dependend after reset */
2332
2333 /* Fix VSYNC level */
2334 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
2335 /* set vsync_b triggering */
2336 saa7146_write(dev, DD1_STREAM_B, 0);
2337 /* port B VSYNC at rising edge */
2338 saa7146_write(dev, DD1_INIT, 0x00000200);
2339 saa7146_write(dev, BRS_CTRL, 0x00000000); // VBI
2340 saa7146_write(dev, MC2,
2341 1 * (MASK_08 | MASK_24) | // BRS control
2342 0 * (MASK_09 | MASK_25) | // a
2343 1 * (MASK_10 | MASK_26) | // b
2344 0 * (MASK_06 | MASK_22) | // HPS_CTRL1
2345 0 * (MASK_05 | MASK_21) | // HPS_CTRL2
2346 0 * (MASK_01 | MASK_15) // DEBI
2347 );
2348
2349 /* start writing RPS1 code from beginning */
2350 count = 0;
2351 /* Disable RPS1 */
2352 saa7146_write(dev, MC1, MASK_29);
2353 /* RPS1 timeout disable */
2354 saa7146_write(dev, RPS_TOV1, 0);
2355 WRITE_RPS1(cpu_to_le32(CMD_PAUSE | EVT_VBI_B));
2356 WRITE_RPS1(cpu_to_le32(CMD_WR_REG_MASK | (GPIO_CTRL>>2)));
2357 WRITE_RPS1(cpu_to_le32(GPIO3_MSK));
2358 WRITE_RPS1(cpu_to_le32(SAA7146_GPIO_OUTLO<<24));
2359#if RPS_IRQ
2360 /* issue RPS1 interrupt to increment counter */
2361 WRITE_RPS1(cpu_to_le32(CMD_INTERRUPT));
2362#endif
2363 WRITE_RPS1(cpu_to_le32(CMD_STOP));
2364 /* Jump to begin of RPS program as safety measure (p37) */
2365 WRITE_RPS1(cpu_to_le32(CMD_JUMP));
2366 WRITE_RPS1(cpu_to_le32(dev->d_rps1.dma_handle));
2367
2368#if RPS_IRQ
2369 /* set event counter 1 source as RPS1 interrupt (0x03) (rE4 p53)
2370 * use 0x03 to track RPS1 interrupts - increase by 1 every gpio3 is toggled
2371 * use 0x15 to track VPE interrupts - increase by 1 every vpeirq() is called
2372 */
2373 saa7146_write(dev, EC1SSR, (0x03<<2) | 3 );
2374 /* set event counter 1 treshold to maximum allowed value (rEC p55) */
2375 saa7146_write(dev, ECT1R, 0x3fff );
2376#endif
2377 /* Set RPS1 Address register to point to RPS code (r108 p42) */
2378 saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle);
2379 /* Enable RPS1, (rFC p33) */
2380 saa7146_write(dev, MC1, (MASK_13 | MASK_29 ));
2381
2382 mdelay(10);
2383 /* now send VSYNC_B to rps1 by rising GPIO3 */
2384 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI);
2385 mdelay(10);
2386 /* if rps1 responded by lowering the GPIO3,
2387 * then we have budgetpatch hardware
2388 */
2389 if ((saa7146_read(dev, GPIO_CTRL) & 0x10000000) == 0) {
2390 budgetpatch = 1;
2391 printk("dvb-ttpci: BUDGET-PATCH DETECTED.\n");
2392 }
2393 /* Disable RPS1 */
2394 saa7146_write(dev, MC1, ( MASK_29 ));
2395#if RPS_IRQ
2396 printk("dvb-ttpci: Event Counter 1 0x%04x\n", saa7146_read(dev, EC1R) & 0x3fff );
2397#endif
2398 }
2399
2400 /* prepare the av7110 device struct */
Panagiotis Issaris74081872006-01-11 19:40:56 -02002401 av7110 = kzalloc(sizeof(struct av7110), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002402 if (!av7110) {
2403 dprintk(1, "out of memory\n");
2404 return -ENOMEM;
2405 }
2406
Linus Torvalds1da177e2005-04-16 15:20:36 -07002407 av7110->card_name = (char*) pci_ext->ext_priv;
2408 av7110->dev = dev;
2409 dev->ext_priv = av7110;
2410
2411 ret = get_firmware(av7110);
2412 if (ret < 0)
2413 goto err_kfree_0;
2414
2415 ret = dvb_register_adapter(&av7110->dvb_adapter, av7110->card_name,
2416 THIS_MODULE);
2417 if (ret < 0)
2418 goto err_put_firmware_1;
2419
2420 /* the Siemens DVB needs this if you want to have the i2c chips
2421 get recognized before the main driver is fully loaded */
2422 saa7146_write(dev, GPIO_CTRL, 0x500000);
2423
2424#ifdef I2C_ADAP_CLASS_TV_DIGITAL
2425 av7110->i2c_adap.class = I2C_ADAP_CLASS_TV_DIGITAL;
2426#else
2427 av7110->i2c_adap.class = I2C_CLASS_TV_DIGITAL;
2428#endif
2429 strlcpy(av7110->i2c_adap.name, pci_ext->ext_priv, sizeof(av7110->i2c_adap.name));
2430
2431 saa7146_i2c_adapter_prepare(dev, &av7110->i2c_adap, SAA7146_I2C_BUS_BIT_RATE_120); /* 275 kHz */
2432
2433 ret = i2c_add_adapter(&av7110->i2c_adap);
2434 if (ret < 0)
2435 goto err_dvb_unregister_adapter_2;
2436
2437 ttpci_eeprom_parse_mac(&av7110->i2c_adap,
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07002438 av7110->dvb_adapter.proposed_mac);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002439 ret = -ENOMEM;
2440
2441 if (budgetpatch) {
2442 spin_lock_init(&av7110->feedlock1);
2443 av7110->grabbing = saa7146_vmalloc_build_pgtable(pdev, length,
2444 &av7110->pt);
2445 if (!av7110->grabbing)
2446 goto err_i2c_del_3;
2447
2448 saa7146_write(dev, PCI_BT_V1, 0x1c1f101f);
2449 saa7146_write(dev, BCS_CTRL, 0x80400040);
2450 /* set dd1 stream a & b */
2451 saa7146_write(dev, DD1_STREAM_B, 0x00000000);
2452 saa7146_write(dev, DD1_INIT, 0x03000200);
2453 saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
2454 saa7146_write(dev, BRS_CTRL, 0x60000000);
2455 saa7146_write(dev, BASE_ODD3, 0);
2456 saa7146_write(dev, BASE_EVEN3, 0);
2457 saa7146_write(dev, PROT_ADDR3, TS_WIDTH * TS_HEIGHT);
2458 saa7146_write(dev, BASE_PAGE3, av7110->pt.dma | ME1 | 0x90);
2459
2460 saa7146_write(dev, PITCH3, TS_WIDTH);
2461 saa7146_write(dev, NUM_LINE_BYTE3, (TS_HEIGHT << 16) | TS_WIDTH);
2462
2463 /* upload all */
2464 saa7146_write(dev, MC2, 0x077c077c);
2465 saa7146_write(dev, GPIO_CTRL, 0x000000);
2466#if RPS_IRQ
2467 /* set event counter 1 source as RPS1 interrupt (0x03) (rE4 p53)
2468 * use 0x03 to track RPS1 interrupts - increase by 1 every gpio3 is toggled
2469 * use 0x15 to track VPE interrupts - increase by 1 every vpeirq() is called
2470 */
2471 saa7146_write(dev, EC1SSR, (0x03<<2) | 3 );
2472 /* set event counter 1 treshold to maximum allowed value (rEC p55) */
2473 saa7146_write(dev, ECT1R, 0x3fff );
2474#endif
2475 /* Setup BUDGETPATCH MAIN RPS1 "program" (p35) */
2476 count = 0;
2477
2478 /* Wait Source Line Counter Threshold (p36) */
2479 WRITE_RPS1(cpu_to_le32(CMD_PAUSE | EVT_HS));
2480 /* Set GPIO3=1 (p42) */
2481 WRITE_RPS1(cpu_to_le32(CMD_WR_REG_MASK | (GPIO_CTRL>>2)));
2482 WRITE_RPS1(cpu_to_le32(GPIO3_MSK));
2483 WRITE_RPS1(cpu_to_le32(SAA7146_GPIO_OUTHI<<24));
2484#if RPS_IRQ
2485 /* issue RPS1 interrupt */
2486 WRITE_RPS1(cpu_to_le32(CMD_INTERRUPT));
2487#endif
2488 /* Wait reset Source Line Counter Threshold (p36) */
2489 WRITE_RPS1(cpu_to_le32(CMD_PAUSE | RPS_INV | EVT_HS));
2490 /* Set GPIO3=0 (p42) */
2491 WRITE_RPS1(cpu_to_le32(CMD_WR_REG_MASK | (GPIO_CTRL>>2)));
2492 WRITE_RPS1(cpu_to_le32(GPIO3_MSK));
2493 WRITE_RPS1(cpu_to_le32(SAA7146_GPIO_OUTLO<<24));
2494#if RPS_IRQ
2495 /* issue RPS1 interrupt */
2496 WRITE_RPS1(cpu_to_le32(CMD_INTERRUPT));
2497#endif
2498 /* Jump to begin of RPS program (p37) */
2499 WRITE_RPS1(cpu_to_le32(CMD_JUMP));
2500 WRITE_RPS1(cpu_to_le32(dev->d_rps1.dma_handle));
2501
2502 /* Fix VSYNC level */
2503 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
2504 /* Set RPS1 Address register to point to RPS code (r108 p42) */
2505 saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle);
2506 /* Set Source Line Counter Threshold, using BRS (rCC p43)
2507 * It generates HS event every TS_HEIGHT lines
2508 * this is related to TS_WIDTH set in register
2509 * NUM_LINE_BYTE3. If NUM_LINE_BYTE low 16 bits
2510 * are set to TS_WIDTH bytes (TS_WIDTH=2*188),
2511 * then RPS_THRESH1 should be set to trigger
2512 * every TS_HEIGHT (512) lines.
2513 */
2514 saa7146_write(dev, RPS_THRESH1, (TS_HEIGHT*1) | MASK_12 );
2515
2516 /* Enable RPS1 (rFC p33) */
2517 saa7146_write(dev, MC1, (MASK_13 | MASK_29));
2518
2519 /* end of budgetpatch register initialization */
2520 tasklet_init (&av7110->vpe_tasklet, vpeirq, (unsigned long) av7110);
2521 } else {
2522 saa7146_write(dev, PCI_BT_V1, 0x1c00101f);
2523 saa7146_write(dev, BCS_CTRL, 0x80400040);
2524
2525 /* set dd1 stream a & b */
2526 saa7146_write(dev, DD1_STREAM_B, 0x00000000);
2527 saa7146_write(dev, DD1_INIT, 0x03000000);
2528 saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
2529
2530 /* upload all */
2531 saa7146_write(dev, MC2, 0x077c077c);
2532 saa7146_write(dev, GPIO_CTRL, 0x000000);
2533 }
2534
2535 tasklet_init (&av7110->debi_tasklet, debiirq, (unsigned long) av7110);
2536 tasklet_init (&av7110->gpio_tasklet, gpioirq, (unsigned long) av7110);
2537
Ingo Molnar3593cab2006-02-07 06:49:14 -02002538 mutex_init(&av7110->pid_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002539
2540 /* locks for data transfers from/to AV7110 */
2541 spin_lock_init(&av7110->debilock);
Ingo Molnar3593cab2006-02-07 06:49:14 -02002542 mutex_init(&av7110->dcomlock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002543 av7110->debitype = -1;
2544
2545 /* default OSD window */
2546 av7110->osdwin = 1;
Ingo Molnar3593cab2006-02-07 06:49:14 -02002547 mutex_init(&av7110->osd_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002548
C.Y.M2f03ee82006-03-30 04:31:48 -03002549 /* TV standard */
2550 av7110->vidmode = tv_standard == 1 ? VIDEO_MODE_NTSC : VIDEO_MODE_PAL;
2551
Linus Torvalds1da177e2005-04-16 15:20:36 -07002552 /* ARM "watchdog" */
2553 init_waitqueue_head(&av7110->arm_wait);
2554 av7110->arm_thread = NULL;
2555
2556 /* allocate and init buffers */
2557 av7110->debi_virt = pci_alloc_consistent(pdev, 8192, &av7110->debi_bus);
2558 if (!av7110->debi_virt)
2559 goto err_saa71466_vfree_4;
2560
2561
2562 av7110->iobuf = vmalloc(AVOUTLEN+AOUTLEN+BMPLEN+4*IPACKS);
2563 if (!av7110->iobuf)
2564 goto err_pci_free_5;
2565
2566 ret = av7110_av_init(av7110);
2567 if (ret < 0)
2568 goto err_iobuf_vfree_6;
2569
2570 /* init BMP buffer */
2571 av7110->bmpbuf = av7110->iobuf+AVOUTLEN+AOUTLEN;
2572 init_waitqueue_head(&av7110->bmpq);
2573
2574 ret = av7110_ca_init(av7110);
2575 if (ret < 0)
2576 goto err_av7110_av_exit_7;
2577
2578 /* load firmware into AV7110 cards */
2579 ret = av7110_bootarm(av7110);
2580 if (ret < 0)
2581 goto err_av7110_ca_exit_8;
2582
2583 ret = av7110_firmversion(av7110);
2584 if (ret < 0)
2585 goto err_stop_arm_9;
2586
2587 if (FW_VERSION(av7110->arm_app)<0x2501)
2588 printk ("dvb-ttpci: Warning, firmware version 0x%04x is too old. "
2589 "System might be unstable!\n", FW_VERSION(av7110->arm_app));
2590
2591 ret = kernel_thread(arm_thread, (void *) av7110, 0);
2592 if (ret < 0)
2593 goto err_stop_arm_9;
2594
2595 /* set initial volume in mixer struct */
2596 av7110->mixer.volume_left = volume;
2597 av7110->mixer.volume_right = volume;
2598
2599 init_av7110_av(av7110);
2600
2601 ret = av7110_register(av7110);
2602 if (ret < 0)
2603 goto err_arm_thread_stop_10;
2604
2605 /* special case DVB-C: these cards have an analog tuner
2606 plus need some special handling, so we have separate
2607 saa7146_ext_vv data for these... */
2608 ret = av7110_init_v4l(av7110);
2609 if (ret < 0)
2610 goto err_av7110_unregister_11;
2611
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07002612 av7110->dvb_adapter.priv = av7110;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002613 ret = frontend_init(av7110);
2614 if (ret < 0)
2615 goto err_av7110_exit_v4l_12;
2616
2617#if defined(CONFIG_INPUT_EVDEV) || defined(CONFIG_INPUT_EVDEV_MODULE)
Oliver Endriss03388ae2005-09-09 13:03:12 -07002618 av7110_ir_init(av7110);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002619#endif
2620 printk(KERN_INFO "dvb-ttpci: found av7110-%d.\n", av7110_num);
2621 av7110_num++;
2622out:
2623 return ret;
2624
2625err_av7110_exit_v4l_12:
2626 av7110_exit_v4l(av7110);
2627err_av7110_unregister_11:
2628 dvb_unregister(av7110);
2629err_arm_thread_stop_10:
2630 av7110_arm_sync(av7110);
2631err_stop_arm_9:
2632 /* Nothing to do. Rejoice. */
2633err_av7110_ca_exit_8:
2634 av7110_ca_exit(av7110);
2635err_av7110_av_exit_7:
2636 av7110_av_exit(av7110);
2637err_iobuf_vfree_6:
2638 vfree(av7110->iobuf);
2639err_pci_free_5:
2640 pci_free_consistent(pdev, 8192, av7110->debi_virt, av7110->debi_bus);
2641err_saa71466_vfree_4:
2642 if (!av7110->grabbing)
2643 saa7146_pgtable_free(pdev, &av7110->pt);
2644err_i2c_del_3:
2645 i2c_del_adapter(&av7110->i2c_adap);
2646err_dvb_unregister_adapter_2:
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07002647 dvb_unregister_adapter(&av7110->dvb_adapter);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002648err_put_firmware_1:
2649 put_firmware(av7110);
2650err_kfree_0:
2651 kfree(av7110);
2652 goto out;
2653}
2654
Johannes Stezenbach1be11e32006-02-27 00:09:20 -03002655static int __devexit av7110_detach(struct saa7146_dev* saa)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002656{
2657 struct av7110 *av7110 = saa->ext_priv;
2658 dprintk(4, "%p\n", av7110);
2659
Oliver Endriss03388ae2005-09-09 13:03:12 -07002660#if defined(CONFIG_INPUT_EVDEV) || defined(CONFIG_INPUT_EVDEV_MODULE)
2661 av7110_ir_exit(av7110);
2662#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07002663 if (budgetpatch) {
2664 /* Disable RPS1 */
2665 saa7146_write(saa, MC1, MASK_29);
2666 /* VSYNC LOW (inactive) */
2667 saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO);
2668 saa7146_write(saa, MC1, MASK_20); /* DMA3 off */
2669 SAA7146_IER_DISABLE(saa, MASK_10);
2670 SAA7146_ISR_CLEAR(saa, MASK_10);
2671 msleep(50);
2672 tasklet_kill(&av7110->vpe_tasklet);
2673 saa7146_pgtable_free(saa->pci, &av7110->pt);
2674 }
2675 av7110_exit_v4l(av7110);
2676
2677 av7110_arm_sync(av7110);
2678
2679 tasklet_kill(&av7110->debi_tasklet);
2680 tasklet_kill(&av7110->gpio_tasklet);
2681
2682 dvb_unregister(av7110);
2683
2684 SAA7146_IER_DISABLE(saa, MASK_19 | MASK_03);
2685 SAA7146_ISR_CLEAR(saa, MASK_19 | MASK_03);
2686
2687 av7110_ca_exit(av7110);
2688 av7110_av_exit(av7110);
2689
2690 vfree(av7110->iobuf);
2691 pci_free_consistent(saa->pci, 8192, av7110->debi_virt,
2692 av7110->debi_bus);
2693
2694 i2c_del_adapter(&av7110->i2c_adap);
2695
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07002696 dvb_unregister_adapter (&av7110->dvb_adapter);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002697
2698 av7110_num--;
2699
2700 put_firmware(av7110);
2701
2702 kfree(av7110);
2703
2704 saa->ext_priv = NULL;
2705
2706 return 0;
2707}
2708
2709
2710static void av7110_irq(struct saa7146_dev* dev, u32 *isr)
2711{
2712 struct av7110 *av7110 = dev->ext_priv;
2713
2714 //print_time("av7110_irq");
2715
2716 /* Note: Don't try to handle the DEBI error irq (MASK_18), in
2717 * intel mode the timeout is asserted all the time...
2718 */
2719
2720 if (*isr & MASK_19) {
2721 //printk("av7110_irq: DEBI\n");
2722 /* Note 1: The DEBI irq is level triggered: We must enable it
2723 * only after we started a DMA xfer, and disable it here
2724 * immediately, or it will be signalled all the time while
2725 * DEBI is idle.
2726 * Note 2: You would think that an irq which is masked is
2727 * not signalled by the hardware. Not so for the SAA7146:
2728 * An irq is signalled as long as the corresponding bit
2729 * in the ISR is set, and disabling irqs just prevents the
2730 * hardware from setting the ISR bit. This means a) that we
2731 * must clear the ISR *after* disabling the irq (which is why
2732 * we must do it here even though saa7146_core did it already),
2733 * and b) that if we were to disable an edge triggered irq
2734 * (like the gpio irqs sadly are) temporarily we would likely
2735 * loose some. This sucks :-(
2736 */
2737 SAA7146_IER_DISABLE(av7110->dev, MASK_19);
2738 SAA7146_ISR_CLEAR(av7110->dev, MASK_19);
2739 tasklet_schedule(&av7110->debi_tasklet);
2740 }
2741
2742 if (*isr & MASK_03) {
2743 //printk("av7110_irq: GPIO\n");
2744 tasklet_schedule(&av7110->gpio_tasklet);
2745 }
2746
2747 if ((*isr & MASK_10) && budgetpatch)
2748 tasklet_schedule(&av7110->vpe_tasklet);
2749}
2750
2751
2752static struct saa7146_extension av7110_extension;
2753
2754#define MAKE_AV7110_INFO(x_var,x_name) \
2755static struct saa7146_pci_extension_data x_var = { \
2756 .ext_priv = x_name, \
2757 .ext = &av7110_extension }
2758
Karl Herz6af4ee12005-09-09 13:03:13 -07002759MAKE_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 -07002760MAKE_AV7110_INFO(ttt_1_X, "Technotrend/Hauppauge WinTV DVB-T rev1.X");
2761MAKE_AV7110_INFO(ttc_1_X, "Technotrend/Hauppauge WinTV Nexus-CA rev1.X");
2762MAKE_AV7110_INFO(ttc_2_X, "Technotrend/Hauppauge WinTV DVB-C rev2.X");
2763MAKE_AV7110_INFO(tts_2_X, "Technotrend/Hauppauge WinTV Nexus-S rev2.X");
Johannes Stezenbach3dfaebd2005-05-16 21:54:19 -07002764MAKE_AV7110_INFO(tts_2_3, "Technotrend/Hauppauge WinTV Nexus-S rev2.3");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002765MAKE_AV7110_INFO(tts_1_3se, "Technotrend/Hauppauge WinTV DVB-S rev1.3 SE");
2766MAKE_AV7110_INFO(ttt, "Technotrend/Hauppauge DVB-T");
2767MAKE_AV7110_INFO(fsc, "Fujitsu Siemens DVB-C");
2768MAKE_AV7110_INFO(fss, "Fujitsu Siemens DVB-S rev1.6");
Oliver Endriss8bd63012006-02-07 06:49:11 -02002769MAKE_AV7110_INFO(gxs_1_3, "Galaxis DVB-S rev1.3");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002770
2771static struct pci_device_id pci_tbl[] = {
Karl Herz6af4ee12005-09-09 13:03:13 -07002772 MAKE_EXTENSION_PCI(fsc, 0x110a, 0x0000),
2773 MAKE_EXTENSION_PCI(tts_1_X_fsc, 0x13c2, 0x0000),
2774 MAKE_EXTENSION_PCI(ttt_1_X, 0x13c2, 0x0001),
2775 MAKE_EXTENSION_PCI(ttc_2_X, 0x13c2, 0x0002),
2776 MAKE_EXTENSION_PCI(tts_2_X, 0x13c2, 0x0003),
Oliver Endriss8bd63012006-02-07 06:49:11 -02002777 MAKE_EXTENSION_PCI(gxs_1_3, 0x13c2, 0x0004),
Karl Herz6af4ee12005-09-09 13:03:13 -07002778 MAKE_EXTENSION_PCI(fss, 0x13c2, 0x0006),
2779 MAKE_EXTENSION_PCI(ttt, 0x13c2, 0x0008),
2780 MAKE_EXTENSION_PCI(ttc_1_X, 0x13c2, 0x000a),
2781 MAKE_EXTENSION_PCI(tts_2_3, 0x13c2, 0x000e),
2782 MAKE_EXTENSION_PCI(tts_1_3se, 0x13c2, 0x1002),
Linus Torvalds1da177e2005-04-16 15:20:36 -07002783
Linus Torvalds1da177e2005-04-16 15:20:36 -07002784/* MAKE_EXTENSION_PCI(???, 0x13c2, 0x0005), UNDEFINED CARD */ // Technisat SkyStar1
2785/* MAKE_EXTENSION_PCI(???, 0x13c2, 0x0009), UNDEFINED CARD */ // TT/Hauppauge WinTV Nexus-CA v????
2786
2787 {
2788 .vendor = 0,
2789 }
2790};
2791
2792MODULE_DEVICE_TABLE(pci, pci_tbl);
2793
2794
2795static struct saa7146_extension av7110_extension = {
2796 .name = "dvb\0",
2797 .flags = SAA7146_I2C_SHORT_DELAY,
2798
2799 .module = THIS_MODULE,
2800 .pci_tbl = &pci_tbl[0],
2801 .attach = av7110_attach,
Johannes Stezenbach1be11e32006-02-27 00:09:20 -03002802 .detach = __devexit_p(av7110_detach),
Linus Torvalds1da177e2005-04-16 15:20:36 -07002803
2804 .irq_mask = MASK_19 | MASK_03 | MASK_10,
2805 .irq_func = av7110_irq,
2806};
2807
2808
2809static int __init av7110_init(void)
2810{
2811 int retval;
2812 retval = saa7146_register_extension(&av7110_extension);
2813 return retval;
2814}
2815
2816
2817static void __exit av7110_exit(void)
2818{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002819 saa7146_unregister_extension(&av7110_extension);
2820}
2821
2822module_init(av7110_init);
2823module_exit(av7110_exit);
2824
2825MODULE_DESCRIPTION("driver for the SAA7146 based AV110 PCI DVB cards by "
2826 "Siemens, Technotrend, Hauppauge");
2827MODULE_AUTHOR("Ralph Metzler, Marcus Metzler, others");
2828MODULE_LICENSE("GPL");