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