aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/ttpci
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/dvb/ttpci')
-rw-r--r--drivers/media/dvb/ttpci/Kconfig134
-rw-r--r--drivers/media/dvb/ttpci/Makefile23
-rw-r--r--drivers/media/dvb/ttpci/av7110.c2739
-rw-r--r--drivers/media/dvb/ttpci/av7110.h284
-rw-r--r--drivers/media/dvb/ttpci/av7110_av.c1459
-rw-r--r--drivers/media/dvb/ttpci/av7110_av.h29
-rw-r--r--drivers/media/dvb/ttpci/av7110_ca.c390
-rw-r--r--drivers/media/dvb/ttpci/av7110_ca.h14
-rw-r--r--drivers/media/dvb/ttpci/av7110_hw.c1170
-rw-r--r--drivers/media/dvb/ttpci/av7110_hw.h500
-rw-r--r--drivers/media/dvb/ttpci/av7110_ipack.c403
-rw-r--r--drivers/media/dvb/ttpci/av7110_ipack.h12
-rw-r--r--drivers/media/dvb/ttpci/av7110_ir.c212
-rw-r--r--drivers/media/dvb/ttpci/av7110_v4l.c771
-rw-r--r--drivers/media/dvb/ttpci/budget-av.c1014
-rw-r--r--drivers/media/dvb/ttpci/budget-ci.c995
-rw-r--r--drivers/media/dvb/ttpci/budget-core.c480
-rw-r--r--drivers/media/dvb/ttpci/budget-patch.c754
-rw-r--r--drivers/media/dvb/ttpci/budget.c573
-rw-r--r--drivers/media/dvb/ttpci/budget.h110
-rw-r--r--drivers/media/dvb/ttpci/fdump.c44
-rw-r--r--drivers/media/dvb/ttpci/ttpci-eeprom.c146
-rw-r--r--drivers/media/dvb/ttpci/ttpci-eeprom.h33
23 files changed, 12289 insertions, 0 deletions
diff --git a/drivers/media/dvb/ttpci/Kconfig b/drivers/media/dvb/ttpci/Kconfig
new file mode 100644
index 000000000000..7ffa2c7315b3
--- /dev/null
+++ b/drivers/media/dvb/ttpci/Kconfig
@@ -0,0 +1,134 @@
1config DVB_AV7110
2 tristate "AV7110 cards"
3 depends on DVB_CORE && PCI
4 select FW_LOADER
5 select VIDEO_DEV
6 select VIDEO_SAA7146_VV
7 select DVB_VES1820
8 select DVB_VES1X93
9 select DVB_STV0299
10 select DVB_TDA8083
11 select DVB_SP8870
12 select DVB_STV0297
13 select DVB_L64781
14 help
15 Support for SAA7146 and AV7110 based DVB cards as produced
16 by Fujitsu-Siemens, Technotrend, Hauppauge and others.
17
18 This driver only supports the fullfeatured cards with
19 onboard MPEG2 decoder.
20
21 This driver needs an external firmware. Please use the script
22 "<kerneldir>/Documentation/dvb/get_dvb_firmware av7110" to
23 download/extract it, and then copy it to /usr/lib/hotplug/firmware.
24
25 Say Y if you own such a card and want to use it.
26
27config DVB_AV7110_FIRMWARE
28 bool "Compile AV7110 firmware into the driver"
29 depends on DVB_AV7110 && !STANDALONE
30 default y if DVB_AV7110=y
31 help
32 The AV7110 firmware is normally loaded by the firmware hotplug manager.
33 If you want to compile the firmware into the driver you need to say
34 Y here and provide the correct path of the firmware. You need this
35 option if you want to compile the whole driver statically into the
36 kernel.
37
38 All other people say N.
39
40config DVB_AV7110_FIRMWARE_FILE
41 string "Full pathname of av7110 firmware file"
42 depends on DVB_AV7110_FIRMWARE
43 default "/usr/lib/hotplug/firmware/dvb-ttpci-01.fw"
44
45config DVB_AV7110_OSD
46 bool "AV7110 OSD support"
47 depends on DVB_AV7110
48 default y if DVB_AV7110=y || DVB_AV7110=m
49 help
50 The AV7110 firmware provides some code to generate an OnScreenDisplay
51 on the video output. This is kind of nonstandard and not guaranteed to
52 be maintained.
53
54 Anyway, some popular DVB software like VDR uses this OSD to render
55 its menus, so say Y if you want to use this software.
56
57 All other people say N.
58
59config DVB_BUDGET
60 tristate "Budget cards"
61 depends on DVB_CORE && PCI
62 select VIDEO_SAA7146
63 select DVB_STV0299
64 select DVB_VES1X93
65 select DVB_VES1820
66 select DVB_L64781
67 select DVB_TDA8083
68 select DVB_TDA10021
69 help
70 Support for simple SAA7146 based DVB cards
71 (so called Budget- or Nova-PCI cards) without onboard
72 MPEG2 decoder.
73
74 Say Y if you own such a card and want to use it.
75
76 To compile this driver as a module, choose M here: the
77 module will be called budget.
78
79config DVB_BUDGET_CI
80 tristate "Budget cards with onboard CI connector"
81 depends on DVB_CORE && PCI
82 select VIDEO_SAA7146
83 select DVB_STV0299
84 select DVB_TDA1004X
85 help
86 Support for simple SAA7146 based DVB cards
87 (so called Budget- or Nova-PCI cards) without onboard
88 MPEG2 decoder, but with onboard Common Interface connector.
89
90 Note: The Common Interface is not yet supported by this driver
91 due to lack of information from the vendor.
92
93 Say Y if you own such a card and want to use it.
94
95 To compile this driver as a module, choose M here: the
96 module will be called budget-ci.
97
98config DVB_BUDGET_AV
99 tristate "Budget cards with analog video inputs"
100 depends on DVB_CORE && PCI
101 select VIDEO_DEV
102 select VIDEO_SAA7146_VV
103 select DVB_STV0299
104 help
105 Support for simple SAA7146 based DVB cards
106 (so called Budget- or Nova-PCI cards) without onboard
107 MPEG2 decoder, but with one or more analog video inputs.
108
109 Say Y if you own such a card and want to use it.
110
111 To compile this driver as a module, choose M here: the
112 module will be called budget-av.
113
114config DVB_BUDGET_PATCH
115 tristate "AV7110 cards with Budget Patch"
116 depends on DVB_CORE && DVB_BUDGET
117 select DVB_AV7110
118 select DVB_STV0299
119 select DVB_VES1X93
120 select DVB_TDA8083
121 help
122 Support for Budget Patch (full TS) modification on
123 SAA7146+AV7110 based cards (DVB-S cards). This
124 driver doesn't use onboard MPEG2 decoder. The
125 card is driven in Budget-only mode. Card is
126 required to have loaded firmware to tune properly.
127 Firmware can be loaded by insertion and removal of
128 standard AV7110 driver prior to loading this
129 driver.
130
131 Say Y if you own such a card and want to use it.
132
133 To compile this driver as a module, choose M here: the
134 module will be called budget-patch.
diff --git a/drivers/media/dvb/ttpci/Makefile b/drivers/media/dvb/ttpci/Makefile
new file mode 100644
index 000000000000..825ab1c38a4f
--- /dev/null
+++ b/drivers/media/dvb/ttpci/Makefile
@@ -0,0 +1,23 @@
1#
2# Makefile for the kernel SAA7146 FULL TS DVB device driver
3# and the AV7110 DVB device driver
4#
5
6dvb-ttpci-objs := av7110_hw.o av7110_v4l.o av7110_av.o av7110_ca.o av7110.o av7110_ipack.o av7110_ir.o
7
8obj-$(CONFIG_DVB_BUDGET) += budget-core.o budget.o ttpci-eeprom.o
9obj-$(CONFIG_DVB_BUDGET_AV) += budget-core.o budget-av.o ttpci-eeprom.o
10obj-$(CONFIG_DVB_BUDGET_CI) += budget-core.o budget-ci.o ttpci-eeprom.o
11obj-$(CONFIG_DVB_BUDGET_PATCH) += budget-core.o budget-patch.o ttpci-eeprom.o
12obj-$(CONFIG_DVB_AV7110) += dvb-ttpci.o ttpci-eeprom.o
13
14EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
15
16hostprogs-y := fdump
17
18ifdef CONFIG_DVB_AV7110_FIRMWARE
19$(obj)/av7110.o: $(obj)/fdump $(obj)/av7110_firm.h
20
21$(obj)/av7110_firm.h:
22 $(obj)/fdump $(CONFIG_DVB_AV7110_FIRMWARE_FILE) dvb_ttpci_fw $@
23endif
diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c
new file mode 100644
index 000000000000..922c205a2652
--- /dev/null
+++ b/drivers/media/dvb/ttpci/av7110.c
@@ -0,0 +1,2739 @@
1/*
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>
57#include <asm/semaphore.h>
58
59#include <linux/dvb/frontend.h>
60
61#include "dvb_frontend.h"
62
63#include "ttpci-eeprom.h"
64#include "av7110.h"
65#include "av7110_hw.h"
66#include "av7110_av.h"
67#include "av7110_ca.h"
68#include "av7110_ipack.h"
69
70#define TS_WIDTH 376
71#define TS_HEIGHT 512
72#define TS_BUFLEN (TS_WIDTH*TS_HEIGHT)
73#define TS_MAX_PACKETS (TS_BUFLEN/TS_SIZE)
74
75
76int av7110_debug;
77
78static int vidmode = CVBS_RGB_OUT;
79static int pids_off;
80static int adac = DVB_ADAC_TI;
81static int hw_sections;
82static int rgb_on;
83static int volume = 255;
84static int budgetpatch = 0;
85
86module_param_named(debug, av7110_debug, int, 0644);
87MODULE_PARM_DESC(debug, "debug level (bitmask, default 0)");
88module_param(vidmode, int, 0444);
89MODULE_PARM_DESC(vidmode,"analog video out: 0 off, 1 CVBS+RGB (default), 2 CVBS+YC, 3 YC");
90module_param(pids_off, int, 0444);
91MODULE_PARM_DESC(pids_off,"clear video/audio/PCR PID filters when demux is closed");
92module_param(adac, int, 0444);
93MODULE_PARM_DESC(adac,"audio DAC type: 0 TI, 1 CRYSTAL, 2 MSP (use if autodetection fails)");
94module_param(hw_sections, int, 0444);
95MODULE_PARM_DESC(hw_sections, "0 use software section filter, 1 use hardware");
96module_param(rgb_on, int, 0444);
97MODULE_PARM_DESC(rgb_on, "For Siemens DVB-C cards only: Enable RGB control"
98 " signal on SCART pin 16 to switch SCART video mode from CVBS to RGB");
99module_param(volume, int, 0444);
100MODULE_PARM_DESC(volume, "initial volume: default 255 (range 0-255)");
101module_param(budgetpatch, int, 0444);
102MODULE_PARM_DESC(budgetpatch, "use budget-patch hardware modification: default 0 (0 no, 1 autodetect, 2 always)");
103
104static void restart_feeds(struct av7110 *av7110);
105
106static int av7110_num = 0;
107
108#define FE_FUNC_OVERRIDE(fe_func, av7110_copy, av7110_func) \
109{\
110 if (fe_func != NULL) { \
111 av7110_copy = fe_func; \
112 fe_func = av7110_func; \
113 } \
114}
115
116
117static void init_av7110_av(struct av7110 *av7110)
118{
119 struct saa7146_dev *dev = av7110->dev;
120
121 /* set internal volume control to maximum */
122 av7110->adac_type = DVB_ADAC_TI;
123 av7110_set_volume(av7110, av7110->mixer.volume_left, av7110->mixer.volume_right);
124
125 av7710_set_video_mode(av7110, vidmode);
126
127 /* handle different card types */
128 /* remaining inits according to card and frontend type */
129 av7110->analog_tuner_flags = 0;
130 av7110->current_input = 0;
131 if (i2c_writereg(av7110, 0x20, 0x00, 0x00) == 1) {
132 printk ("dvb-ttpci: Crystal audio DAC @ card %d detected\n",
133 av7110->dvb_adapter->num);
134 av7110->adac_type = DVB_ADAC_CRYSTAL;
135 i2c_writereg(av7110, 0x20, 0x01, 0xd2);
136 i2c_writereg(av7110, 0x20, 0x02, 0x49);
137 i2c_writereg(av7110, 0x20, 0x03, 0x00);
138 i2c_writereg(av7110, 0x20, 0x04, 0x00);
139
140 /**
141 * some special handling for the Siemens DVB-C cards...
142 */
143 } else if (0 == av7110_init_analog_module(av7110)) {
144 /* done. */
145 }
146 else if (dev->pci->subsystem_vendor == 0x110a) {
147 printk("dvb-ttpci: DVB-C w/o analog module @ card %d detected\n",
148 av7110->dvb_adapter->num);
149 av7110->adac_type = DVB_ADAC_NONE;
150 }
151 else {
152 av7110->adac_type = adac;
153 printk("dvb-ttpci: adac type set to %d @ card %d\n",
154 av7110->dvb_adapter->num, av7110->adac_type);
155 }
156
157 if (av7110->adac_type == DVB_ADAC_NONE || av7110->adac_type == DVB_ADAC_MSP) {
158 // switch DVB SCART on
159 av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, MainSwitch, 1, 0);
160 av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, ADSwitch, 1, 1);
161 if (rgb_on &&
162 (av7110->dev->pci->subsystem_vendor == 0x110a) && (av7110->dev->pci->subsystem_device == 0x0000)) {
163 saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); // RGB on, SCART pin 16
164 //saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); // SCARTpin 8
165 }
166 }
167
168 av7110_set_volume(av7110, av7110->mixer.volume_left, av7110->mixer.volume_right);
169 av7110_setup_irc_config(av7110, 0);
170}
171
172static void recover_arm(struct av7110 *av7110)
173{
174 dprintk(4, "%p\n",av7110);
175
176 av7110_bootarm(av7110);
177 msleep(100);
178 restart_feeds(av7110);
179 av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, SetIR, 1, av7110->ir_config);
180}
181
182static void arm_error(struct av7110 *av7110)
183{
184 dprintk(4, "%p\n",av7110);
185
186 av7110->arm_errors++;
187 av7110->arm_ready = 0;
188 recover_arm(av7110);
189}
190
191static void av7110_arm_sync(struct av7110 *av7110)
192{
193 av7110->arm_rmmod = 1;
194 wake_up_interruptible(&av7110->arm_wait);
195
196 while (av7110->arm_thread)
197 msleep(1);
198}
199
200static int arm_thread(void *data)
201{
202 struct av7110 *av7110 = data;
203 u16 newloops = 0;
204 int timeout;
205
206 dprintk(4, "%p\n",av7110);
207
208 lock_kernel();
209 daemonize("arm_mon");
210 sigfillset(&current->blocked);
211 unlock_kernel();
212
213 av7110->arm_thread = current;
214
215 for (;;) {
216 timeout = wait_event_interruptible_timeout(av7110->arm_wait,
217 av7110->arm_rmmod, 5 * HZ);
218 if (-ERESTARTSYS == timeout || av7110->arm_rmmod) {
219 /* got signal or told to quit*/
220 break;
221 }
222
223 if (!av7110->arm_ready)
224 continue;
225
226 if (down_interruptible(&av7110->dcomlock))
227 break;
228
229 newloops = rdebi(av7110, DEBINOSWAP, STATUS_LOOPS, 0, 2);
230 up(&av7110->dcomlock);
231
232 if (newloops == av7110->arm_loops) {
233 printk(KERN_ERR "dvb-ttpci: ARM crashed @ card %d\n",
234 av7110->dvb_adapter->num);
235
236 arm_error(av7110);
237 av7710_set_video_mode(av7110, vidmode);
238
239 init_av7110_av(av7110);
240
241 if (down_interruptible(&av7110->dcomlock))
242 break;
243
244 newloops = rdebi(av7110, DEBINOSWAP, STATUS_LOOPS, 0, 2) - 1;
245 up(&av7110->dcomlock);
246 }
247 av7110->arm_loops = newloops;
248 }
249
250 av7110->arm_thread = NULL;
251 return 0;
252}
253
254
255/**
256 * Hack! we save the last av7110 ptr. This should be ok, since
257 * you rarely will use more then one IR control.
258 *
259 * If we want to support multiple controls we would have to do much more...
260 */
261void av7110_setup_irc_config(struct av7110 *av7110, u32 ir_config)
262{
263 static struct av7110 *last;
264
265 dprintk(4, "%p\n", av7110);
266
267 if (!av7110)
268 av7110 = last;
269 else
270 last = av7110;
271
272 if (av7110) {
273 av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, SetIR, 1, ir_config);
274 av7110->ir_config = ir_config;
275 }
276}
277
278static void (*irc_handler)(u32);
279
280void av7110_register_irc_handler(void (*func)(u32))
281{
282 dprintk(4, "registering %p\n", func);
283 irc_handler = func;
284}
285
286void av7110_unregister_irc_handler(void (*func)(u32))
287{
288 dprintk(4, "unregistering %p\n", func);
289 irc_handler = NULL;
290}
291
292static void run_handlers(unsigned long ircom)
293{
294 if (irc_handler != NULL)
295 (*irc_handler)((u32) ircom);
296}
297
298static DECLARE_TASKLET(irtask, run_handlers, 0);
299
300static void IR_handle(struct av7110 *av7110, u32 ircom)
301{
302 dprintk(4, "ircommand = %08x\n", ircom);
303 irtask.data = (unsigned long) ircom;
304 tasklet_schedule(&irtask);
305}
306
307/****************************************************************************
308 * IRQ handling
309 ****************************************************************************/
310
311static int DvbDmxFilterCallback(u8 *buffer1, size_t buffer1_len,
312 u8 *buffer2, size_t buffer2_len,
313 struct dvb_demux_filter *dvbdmxfilter,
314 enum dmx_success success,
315 struct av7110 *av7110)
316{
317 if (!dvbdmxfilter->feed->demux->dmx.frontend)
318 return 0;
319 if (dvbdmxfilter->feed->demux->dmx.frontend->source == DMX_MEMORY_FE)
320 return 0;
321
322 switch (dvbdmxfilter->type) {
323 case DMX_TYPE_SEC:
324 if ((((buffer1[1] << 8) | buffer1[2]) & 0xfff) + 3 != buffer1_len)
325 return 0;
326 if (dvbdmxfilter->doneq) {
327 struct dmx_section_filter *filter = &dvbdmxfilter->filter;
328 int i;
329 u8 xor, neq = 0;
330
331 for (i = 0; i < DVB_DEMUX_MASK_MAX; i++) {
332 xor = filter->filter_value[i] ^ buffer1[i];
333 neq |= dvbdmxfilter->maskandnotmode[i] & xor;
334 }
335 if (!neq)
336 return 0;
337 }
338 return dvbdmxfilter->feed->cb.sec(buffer1, buffer1_len,
339 buffer2, buffer2_len,
340 &dvbdmxfilter->filter,
341 DMX_OK);
342 case DMX_TYPE_TS:
343 if (!(dvbdmxfilter->feed->ts_type & TS_PACKET))
344 return 0;
345 if (dvbdmxfilter->feed->ts_type & TS_PAYLOAD_ONLY)
346 return dvbdmxfilter->feed->cb.ts(buffer1, buffer1_len,
347 buffer2, buffer2_len,
348 &dvbdmxfilter->feed->feed.ts,
349 DMX_OK);
350 else
351 av7110_p2t_write(buffer1, buffer1_len,
352 dvbdmxfilter->feed->pid,
353 &av7110->p2t_filter[dvbdmxfilter->index]);
354 default:
355 return 0;
356 }
357}
358
359
360//#define DEBUG_TIMING
361static inline void print_time(char *s)
362{
363#ifdef DEBUG_TIMING
364 struct timeval tv;
365 do_gettimeofday(&tv);
366 printk("%s: %d.%d\n", s, (int)tv.tv_sec, (int)tv.tv_usec);
367#endif
368}
369
370#define DEBI_READ 0
371#define DEBI_WRITE 1
372static inline void start_debi_dma(struct av7110 *av7110, int dir,
373 unsigned long addr, unsigned int len)
374{
375 dprintk(8, "%c %08lx %u\n", dir == DEBI_READ ? 'R' : 'W', addr, len);
376 if (saa7146_wait_for_debi_done(av7110->dev, 0)) {
377 printk(KERN_ERR "%s: saa7146_wait_for_debi_done timed out\n", __FUNCTION__);
378 return;
379 }
380
381 SAA7146_ISR_CLEAR(av7110->dev, MASK_19); /* for good measure */
382 SAA7146_IER_ENABLE(av7110->dev, MASK_19);
383 if (len < 5)
384 len = 5; /* we want a real DEBI DMA */
385 if (dir == DEBI_WRITE)
386 iwdebi(av7110, DEBISWAB, addr, 0, (len + 3) & ~3);
387 else
388 irdebi(av7110, DEBISWAB, addr, 0, len);
389}
390
391static void debiirq(unsigned long data)
392{
393 struct av7110 *av7110 = (struct av7110 *) data;
394 int type = av7110->debitype;
395 int handle = (type >> 8) & 0x1f;
396 unsigned int xfer = 0;
397
398 print_time("debi");
399 dprintk(4, "type 0x%04x\n", type);
400
401 if (type == -1) {
402 printk("DEBI irq oops @ %ld, psr:0x%08x, ssr:0x%08x\n",
403 jiffies, saa7146_read(av7110->dev, PSR),
404 saa7146_read(av7110->dev, SSR));
405 goto debi_done;
406 }
407 av7110->debitype = -1;
408
409 switch (type & 0xff) {
410
411 case DATA_TS_RECORD:
412 dvb_dmx_swfilter_packets(&av7110->demux,
413 (const u8 *) av7110->debi_virt,
414 av7110->debilen / 188);
415 xfer = RX_BUFF;
416 break;
417
418 case DATA_PES_RECORD:
419 if (av7110->demux.recording)
420 av7110_record_cb(&av7110->p2t[handle],
421 (u8 *) av7110->debi_virt,
422 av7110->debilen);
423 xfer = RX_BUFF;
424 break;
425
426 case DATA_IPMPE:
427 case DATA_FSECTION:
428 case DATA_PIPING:
429 if (av7110->handle2filter[handle])
430 DvbDmxFilterCallback((u8 *)av7110->debi_virt,
431 av7110->debilen, NULL, 0,
432 av7110->handle2filter[handle],
433 DMX_OK, av7110);
434 xfer = RX_BUFF;
435 break;
436
437 case DATA_CI_GET:
438 {
439 u8 *data = av7110->debi_virt;
440
441 if ((data[0] < 2) && data[2] == 0xff) {
442 int flags = 0;
443 if (data[5] > 0)
444 flags |= CA_CI_MODULE_PRESENT;
445 if (data[5] > 5)
446 flags |= CA_CI_MODULE_READY;
447 av7110->ci_slot[data[0]].flags = flags;
448 } else
449 ci_get_data(&av7110->ci_rbuffer,
450 av7110->debi_virt,
451 av7110->debilen);
452 xfer = RX_BUFF;
453 break;
454 }
455
456 case DATA_COMMON_INTERFACE:
457 CI_handle(av7110, (u8 *)av7110->debi_virt, av7110->debilen);
458#if 0
459 {
460 int i;
461
462 printk("av7110%d: ", av7110->num);
463 printk("%02x ", *(u8 *)av7110->debi_virt);
464 printk("%02x ", *(1+(u8 *)av7110->debi_virt));
465 for (i = 2; i < av7110->debilen; i++)
466 printk("%02x ", (*(i+(unsigned char *)av7110->debi_virt)));
467 for (i = 2; i < av7110->debilen; i++)
468 printk("%c", chtrans(*(i+(unsigned char *)av7110->debi_virt)));
469
470 printk("\n");
471 }
472#endif
473 xfer = RX_BUFF;
474 break;
475
476 case DATA_DEBUG_MESSAGE:
477 ((s8*)av7110->debi_virt)[Reserved_SIZE - 1] = 0;
478 printk("%s\n", (s8 *) av7110->debi_virt);
479 xfer = RX_BUFF;
480 break;
481
482 case DATA_CI_PUT:
483 dprintk(4, "debi DATA_CI_PUT\n");
484 case DATA_MPEG_PLAY:
485 dprintk(4, "debi DATA_MPEG_PLAY\n");
486 case DATA_BMP_LOAD:
487 dprintk(4, "debi DATA_BMP_LOAD\n");
488 xfer = TX_BUFF;
489 break;
490 default:
491 break;
492 }
493debi_done:
494 spin_lock(&av7110->debilock);
495 if (xfer)
496 iwdebi(av7110, DEBINOSWAP, xfer, 0, 2);
497 ARM_ClearMailBox(av7110);
498 spin_unlock(&av7110->debilock);
499}
500
501/* irq from av7110 firmware writing the mailbox register in the DPRAM */
502static void gpioirq(unsigned long data)
503{
504 struct av7110 *av7110 = (struct av7110 *) data;
505 u32 rxbuf, txbuf;
506 int len;
507
508 if (av7110->debitype != -1)
509 /* we shouldn't get any irq while a debi xfer is running */
510 printk("dvb-ttpci: GPIO0 irq oops @ %ld, psr:0x%08x, ssr:0x%08x\n",
511 jiffies, saa7146_read(av7110->dev, PSR),
512 saa7146_read(av7110->dev, SSR));
513
514 if (saa7146_wait_for_debi_done(av7110->dev, 0)) {
515 printk(KERN_ERR "%s: saa7146_wait_for_debi_done timed out\n", __FUNCTION__);
516 BUG(); /* maybe we should try resetting the debi? */
517 }
518
519 spin_lock(&av7110->debilock);
520 ARM_ClearIrq(av7110);
521
522 /* see what the av7110 wants */
523 av7110->debitype = irdebi(av7110, DEBINOSWAP, IRQ_STATE, 0, 2);
524 av7110->debilen = irdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);
525 rxbuf = irdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
526 txbuf = irdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);
527 len = (av7110->debilen + 3) & ~3;
528
529 print_time("gpio");
530 dprintk(8, "GPIO0 irq 0x%04x %d\n", av7110->debitype, av7110->debilen);
531
532 switch (av7110->debitype & 0xff) {
533
534 case DATA_TS_PLAY:
535 case DATA_PES_PLAY:
536 break;
537
538 case DATA_MPEG_VIDEO_EVENT:
539 {
540 u32 h_ar;
541 struct video_event event;
542
543 av7110->video_size.w = irdebi(av7110, DEBINOSWAP, STATUS_MPEG_WIDTH, 0, 2);
544 h_ar = irdebi(av7110, DEBINOSWAP, STATUS_MPEG_HEIGHT_AR, 0, 2);
545
546 iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);
547 iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
548
549 av7110->video_size.h = h_ar & 0xfff;
550 dprintk(8, "GPIO0 irq: DATA_MPEG_VIDEO_EVENT: w/h/ar = %u/%u/%u\n",
551 av7110->video_size.w,
552 av7110->video_size.h,
553 av7110->video_size.aspect_ratio);
554
555 event.type = VIDEO_EVENT_SIZE_CHANGED;
556 event.u.size.w = av7110->video_size.w;
557 event.u.size.h = av7110->video_size.h;
558 switch ((h_ar >> 12) & 0xf)
559 {
560 case 3:
561 av7110->video_size.aspect_ratio = VIDEO_FORMAT_16_9;
562 event.u.size.aspect_ratio = VIDEO_FORMAT_16_9;
563 av7110->videostate.video_format = VIDEO_FORMAT_16_9;
564 break;
565 case 4:
566 av7110->video_size.aspect_ratio = VIDEO_FORMAT_221_1;
567 event.u.size.aspect_ratio = VIDEO_FORMAT_221_1;
568 av7110->videostate.video_format = VIDEO_FORMAT_221_1;
569 break;
570 default:
571 av7110->video_size.aspect_ratio = VIDEO_FORMAT_4_3;
572 event.u.size.aspect_ratio = VIDEO_FORMAT_4_3;
573 av7110->videostate.video_format = VIDEO_FORMAT_4_3;
574 }
575 dvb_video_add_event(av7110, &event);
576 break;
577 }
578
579 case DATA_CI_PUT:
580 {
581 int avail;
582 struct dvb_ringbuffer *cibuf = &av7110->ci_wbuffer;
583
584 avail = dvb_ringbuffer_avail(cibuf);
585 if (avail <= 2) {
586 iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);
587 iwdebi(av7110, DEBINOSWAP, TX_LEN, 0, 2);
588 iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);
589 break;
590 }
591 len = DVB_RINGBUFFER_PEEK(cibuf, 0) << 8;
592 len |= DVB_RINGBUFFER_PEEK(cibuf, 1);
593 if (avail < len + 2) {
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 DVB_RINGBUFFER_SKIP(cibuf, 2);
600
601 dvb_ringbuffer_read(cibuf, av7110->debi_virt, len, 0);
602
603 iwdebi(av7110, DEBINOSWAP, TX_LEN, len, 2);
604 iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, len, 2);
605 dprintk(8, "DMA: CI\n");
606 start_debi_dma(av7110, DEBI_WRITE, DPRAM_BASE + txbuf, len);
607 spin_unlock(&av7110->debilock);
608 wake_up(&cibuf->queue);
609 return;
610 }
611
612 case DATA_MPEG_PLAY:
613 if (!av7110->playing) {
614 iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);
615 iwdebi(av7110, DEBINOSWAP, TX_LEN, 0, 2);
616 iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);
617 break;
618 }
619 len = 0;
620 if (av7110->debitype & 0x100) {
621 spin_lock(&av7110->aout.lock);
622 len = av7110_pes_play(av7110->debi_virt, &av7110->aout, 2048);
623 spin_unlock(&av7110->aout.lock);
624 }
625 if (len <= 0 && (av7110->debitype & 0x200)
626 &&av7110->videostate.play_state != VIDEO_FREEZED) {
627 spin_lock(&av7110->avout.lock);
628 len = av7110_pes_play(av7110->debi_virt, &av7110->avout, 2048);
629 spin_unlock(&av7110->avout.lock);
630 }
631 if (len <= 0) {
632 iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);
633 iwdebi(av7110, DEBINOSWAP, TX_LEN, 0, 2);
634 iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);
635 break;
636 }
637 dprintk(8, "GPIO0 PES_PLAY len=%04x\n", len);
638 iwdebi(av7110, DEBINOSWAP, TX_LEN, len, 2);
639 iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, len, 2);
640 dprintk(8, "DMA: MPEG_PLAY\n");
641 start_debi_dma(av7110, DEBI_WRITE, DPRAM_BASE + txbuf, len);
642 spin_unlock(&av7110->debilock);
643 return;
644
645 case DATA_BMP_LOAD:
646 len = av7110->debilen;
647 dprintk(8, "gpio DATA_BMP_LOAD len %d\n", len);
648 if (!len) {
649 av7110->bmp_state = BMP_LOADED;
650 iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);
651 iwdebi(av7110, DEBINOSWAP, TX_LEN, 0, 2);
652 iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);
653 wake_up(&av7110->bmpq);
654 dprintk(8, "gpio DATA_BMP_LOAD done\n");
655 break;
656 }
657 if (len > av7110->bmplen)
658 len = av7110->bmplen;
659 if (len > 2 * 1024)
660 len = 2 * 1024;
661 iwdebi(av7110, DEBINOSWAP, TX_LEN, len, 2);
662 iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, len, 2);
663 memcpy(av7110->debi_virt, av7110->bmpbuf+av7110->bmpp, len);
664 av7110->bmpp += len;
665 av7110->bmplen -= len;
666 dprintk(8, "gpio DATA_BMP_LOAD DMA len %d\n", len);
667 start_debi_dma(av7110, DEBI_WRITE, DPRAM_BASE+txbuf, len);
668 spin_unlock(&av7110->debilock);
669 return;
670
671 case DATA_CI_GET:
672 case DATA_COMMON_INTERFACE:
673 case DATA_FSECTION:
674 case DATA_IPMPE:
675 case DATA_PIPING:
676 if (!len || len > 4 * 1024) {
677 iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
678 break;
679 }
680 /* fall through */
681
682 case DATA_TS_RECORD:
683 case DATA_PES_RECORD:
684 dprintk(8, "DMA: TS_REC etc.\n");
685 start_debi_dma(av7110, DEBI_READ, DPRAM_BASE+rxbuf, len);
686 spin_unlock(&av7110->debilock);
687 return;
688
689 case DATA_DEBUG_MESSAGE:
690 if (!len || len > 0xff) {
691 iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
692 break;
693 }
694 start_debi_dma(av7110, DEBI_READ, Reserved, len);
695 spin_unlock(&av7110->debilock);
696 return;
697
698 case DATA_IRCOMMAND:
699 IR_handle(av7110,
700 swahw32(irdebi(av7110, DEBINOSWAP, Reserved, 0, 4)));
701 iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
702 break;
703
704 default:
705 printk("dvb-ttpci: gpioirq unknown type=%d len=%d\n",
706 av7110->debitype, av7110->debilen);
707 break;
708 }
709 av7110->debitype = -1;
710 ARM_ClearMailBox(av7110);
711 spin_unlock(&av7110->debilock);
712}
713
714
715#ifdef CONFIG_DVB_AV7110_OSD
716static int dvb_osd_ioctl(struct inode *inode, struct file *file,
717 unsigned int cmd, void *parg)
718{
719 struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;
720 struct av7110 *av7110 = (struct av7110 *) dvbdev->priv;
721
722 dprintk(4, "%p\n", av7110);
723
724 if (cmd == OSD_SEND_CMD)
725 return av7110_osd_cmd(av7110, (osd_cmd_t *) parg);
726 if (cmd == OSD_GET_CAPABILITY)
727 return av7110_osd_capability(av7110, (osd_cap_t *) parg);
728
729 return -EINVAL;
730}
731
732
733static struct file_operations dvb_osd_fops = {
734 .owner = THIS_MODULE,
735 .ioctl = dvb_generic_ioctl,
736 .open = dvb_generic_open,
737 .release = dvb_generic_release,
738};
739
740static struct dvb_device dvbdev_osd = {
741 .priv = NULL,
742 .users = 1,
743 .writers = 1,
744 .fops = &dvb_osd_fops,
745 .kernel_ioctl = dvb_osd_ioctl,
746};
747#endif /* CONFIG_DVB_AV7110_OSD */
748
749
750static inline int SetPIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid,
751 u16 subpid, u16 pcrpid)
752{
753 dprintk(4, "%p\n", av7110);
754
755 if (vpid == 0x1fff || apid == 0x1fff ||
756 ttpid == 0x1fff || subpid == 0x1fff || pcrpid == 0x1fff) {
757 vpid = apid = ttpid = subpid = pcrpid = 0;
758 av7110->pids[DMX_PES_VIDEO] = 0;
759 av7110->pids[DMX_PES_AUDIO] = 0;
760 av7110->pids[DMX_PES_TELETEXT] = 0;
761 av7110->pids[DMX_PES_PCR] = 0;
762 }
763
764 return av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, MultiPID, 5,
765 pcrpid, vpid, apid, ttpid, subpid);
766}
767
768void ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid,
769 u16 subpid, u16 pcrpid)
770{
771 dprintk(4, "%p\n", av7110);
772
773 if (down_interruptible(&av7110->pid_mutex))
774 return;
775
776 if (!(vpid & 0x8000))
777 av7110->pids[DMX_PES_VIDEO] = vpid;
778 if (!(apid & 0x8000))
779 av7110->pids[DMX_PES_AUDIO] = apid;
780 if (!(ttpid & 0x8000))
781 av7110->pids[DMX_PES_TELETEXT] = ttpid;
782 if (!(pcrpid & 0x8000))
783 av7110->pids[DMX_PES_PCR] = pcrpid;
784
785 av7110->pids[DMX_PES_SUBTITLE] = 0;
786
787 if (av7110->fe_synced) {
788 pcrpid = av7110->pids[DMX_PES_PCR];
789 SetPIDs(av7110, vpid, apid, ttpid, subpid, pcrpid);
790 }
791
792 up(&av7110->pid_mutex);
793}
794
795
796/******************************************************************************
797 * hardware filter functions
798 ******************************************************************************/
799
800static int StartHWFilter(struct dvb_demux_filter *dvbdmxfilter)
801{
802 struct dvb_demux_feed *dvbdmxfeed = dvbdmxfilter->feed;
803 struct av7110 *av7110 = (struct av7110 *) dvbdmxfeed->demux->priv;
804 u16 buf[20];
805 int ret, i;
806 u16 handle;
807// u16 mode = 0x0320;
808 u16 mode = 0xb96a;
809
810 dprintk(4, "%p\n", av7110);
811
812 if (dvbdmxfilter->type == DMX_TYPE_SEC) {
813 if (hw_sections) {
814 buf[4] = (dvbdmxfilter->filter.filter_value[0] << 8) |
815 dvbdmxfilter->maskandmode[0];
816 for (i = 3; i < 18; i++)
817 buf[i + 4 - 2] =
818 (dvbdmxfilter->filter.filter_value[i] << 8) |
819 dvbdmxfilter->maskandmode[i];
820 mode = 4;
821 }
822 } else if ((dvbdmxfeed->ts_type & TS_PACKET) &&
823 !(dvbdmxfeed->ts_type & TS_PAYLOAD_ONLY)) {
824 av7110_p2t_init(&av7110->p2t_filter[dvbdmxfilter->index], dvbdmxfeed);
825 }
826
827 buf[0] = (COMTYPE_PID_FILTER << 8) + AddPIDFilter;
828 buf[1] = 16;
829 buf[2] = dvbdmxfeed->pid;
830 buf[3] = mode;
831
832 ret = av7110_fw_request(av7110, buf, 20, &handle, 1);
833 if (ret != 0 || handle >= 32) {
834 printk("dvb-ttpci: %s error buf %04x %04x %04x %04x "
835 "ret %x handle %04x\n",
836 __FUNCTION__, buf[0], buf[1], buf[2], buf[3],
837 ret, handle);
838 dvbdmxfilter->hw_handle = 0xffff;
839 return -1;
840 }
841
842 av7110->handle2filter[handle] = dvbdmxfilter;
843 dvbdmxfilter->hw_handle = handle;
844
845 return ret;
846}
847
848static int StopHWFilter(struct dvb_demux_filter *dvbdmxfilter)
849{
850 struct av7110 *av7110 = (struct av7110 *) dvbdmxfilter->feed->demux->priv;
851 u16 buf[3];
852 u16 answ[2];
853 int ret;
854 u16 handle;
855
856 dprintk(4, "%p\n", av7110);
857
858 handle = dvbdmxfilter->hw_handle;
859 if (handle >= 32) {
860 printk("%s tried to stop invalid filter %04x, filter type = %x\n",
861 __FUNCTION__, handle, dvbdmxfilter->type);
862 return 0;
863 }
864
865 av7110->handle2filter[handle] = NULL;
866
867 buf[0] = (COMTYPE_PID_FILTER << 8) + DelPIDFilter;
868 buf[1] = 1;
869 buf[2] = handle;
870 ret = av7110_fw_request(av7110, buf, 3, answ, 2);
871 if (ret != 0 || answ[1] != handle) {
872 printk("dvb-ttpci: %s error cmd %04x %04x %04x ret %x "
873 "resp %04x %04x pid %d\n",
874 __FUNCTION__, buf[0], buf[1], buf[2], ret,
875 answ[0], answ[1], dvbdmxfilter->feed->pid);
876 ret = -1;
877 }
878 return ret;
879}
880
881
882static void dvb_feed_start_pid(struct dvb_demux_feed *dvbdmxfeed)
883{
884 struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
885 struct av7110 *av7110 = (struct av7110 *) dvbdmx->priv;
886 u16 *pid = dvbdmx->pids, npids[5];
887 int i;
888
889 dprintk(4, "%p\n", av7110);
890
891 npids[0] = npids[1] = npids[2] = npids[3] = npids[4] = 0xffff;
892 i = dvbdmxfeed->pes_type;
893 npids[i] = (pid[i]&0x8000) ? 0 : pid[i];
894 if ((i == 2) && npids[i] && (dvbdmxfeed->ts_type & TS_PACKET)) {
895 npids[i] = 0;
896 ChangePIDs(av7110, npids[1], npids[0], npids[2], npids[3], npids[4]);
897 StartHWFilter(dvbdmxfeed->filter);
898 return;
899 }
900 if (dvbdmxfeed->pes_type <= 2 || dvbdmxfeed->pes_type == 4)
901 ChangePIDs(av7110, npids[1], npids[0], npids[2], npids[3], npids[4]);
902
903 if (dvbdmxfeed->pes_type < 2 && npids[0])
904 if (av7110->fe_synced)
905 av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, Scan, 0);
906
907 if ((dvbdmxfeed->ts_type & TS_PACKET)) {
908 if (dvbdmxfeed->pes_type == 0 && !(dvbdmx->pids[0] & 0x8000))
909 av7110_av_start_record(av7110, RP_AUDIO, dvbdmxfeed);
910 if (dvbdmxfeed->pes_type == 1 && !(dvbdmx->pids[1] & 0x8000))
911 av7110_av_start_record(av7110, RP_VIDEO, dvbdmxfeed);
912 }
913}
914
915static void dvb_feed_stop_pid(struct dvb_demux_feed *dvbdmxfeed)
916{
917 struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
918 struct av7110 *av7110 = (struct av7110 *) dvbdmx->priv;
919 u16 *pid = dvbdmx->pids, npids[5];
920 int i;
921
922 dprintk(4, "%p\n", av7110);
923
924 if (dvbdmxfeed->pes_type <= 1) {
925 av7110_av_stop(av7110, dvbdmxfeed->pes_type ? RP_VIDEO : RP_AUDIO);
926 if (!av7110->rec_mode)
927 dvbdmx->recording = 0;
928 if (!av7110->playing)
929 dvbdmx->playing = 0;
930 }
931 npids[0] = npids[1] = npids[2] = npids[3] = npids[4] = 0xffff;
932 i = dvbdmxfeed->pes_type;
933 switch (i) {
934 case 2: //teletext
935 if (dvbdmxfeed->ts_type & TS_PACKET)
936 StopHWFilter(dvbdmxfeed->filter);
937 npids[2] = 0;
938 break;
939 case 0:
940 case 1:
941 case 4:
942 if (!pids_off)
943 return;
944 npids[i] = (pid[i]&0x8000) ? 0 : pid[i];
945 break;
946 }
947 ChangePIDs(av7110, npids[1], npids[0], npids[2], npids[3], npids[4]);
948}
949
950static int av7110_start_feed(struct dvb_demux_feed *feed)
951{
952 struct dvb_demux *demux = feed->demux;
953 struct av7110 *av7110 = demux->priv;
954
955 dprintk(4, "%p\n", av7110);
956
957 if (!demux->dmx.frontend)
958 return -EINVAL;
959
960 if (feed->pid > 0x1fff)
961 return -EINVAL;
962
963 if (feed->type == DMX_TYPE_TS) {
964 if ((feed->ts_type & TS_DECODER) &&
965 (feed->pes_type < DMX_TS_PES_OTHER)) {
966 switch (demux->dmx.frontend->source) {
967 case DMX_MEMORY_FE:
968 if (feed->ts_type & TS_DECODER)
969 if (feed->pes_type < 2 &&
970 !(demux->pids[0] & 0x8000) &&
971 !(demux->pids[1] & 0x8000)) {
972 dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout);
973 dvb_ringbuffer_flush_spinlock_wakeup(&av7110->aout);
974 av7110_av_start_play(av7110,RP_AV);
975 demux->playing = 1;
976 }
977 break;
978 default:
979 dvb_feed_start_pid(feed);
980 break;
981 }
982 } else if ((feed->ts_type & TS_PACKET) &&
983 (demux->dmx.frontend->source != DMX_MEMORY_FE)) {
984 StartHWFilter(feed->filter);
985 }
986 }
987
988 if (feed->type == DMX_TYPE_SEC) {
989 int i;
990
991 for (i = 0; i < demux->filternum; i++) {
992 if (demux->filter[i].state != DMX_STATE_READY)
993 continue;
994 if (demux->filter[i].type != DMX_TYPE_SEC)
995 continue;
996 if (demux->filter[i].filter.parent != &feed->feed.sec)
997 continue;
998 demux->filter[i].state = DMX_STATE_GO;
999 if (demux->dmx.frontend->source != DMX_MEMORY_FE)
1000 StartHWFilter(&demux->filter[i]);
1001 }
1002 }
1003
1004 return 0;
1005}
1006
1007
1008static int av7110_stop_feed(struct dvb_demux_feed *feed)
1009{
1010 struct dvb_demux *demux = feed->demux;
1011 struct av7110 *av7110 = demux->priv;
1012
1013 dprintk(4, "%p\n", av7110);
1014
1015 if (feed->type == DMX_TYPE_TS) {
1016 if (feed->ts_type & TS_DECODER) {
1017 if (feed->pes_type >= DMX_TS_PES_OTHER ||
1018 !demux->pesfilter[feed->pes_type])
1019 return -EINVAL;
1020 demux->pids[feed->pes_type] |= 0x8000;
1021 demux->pesfilter[feed->pes_type] = NULL;
1022 }
1023 if (feed->ts_type & TS_DECODER &&
1024 feed->pes_type < DMX_TS_PES_OTHER) {
1025 dvb_feed_stop_pid(feed);
1026 } else
1027 if ((feed->ts_type & TS_PACKET) &&
1028 (demux->dmx.frontend->source != DMX_MEMORY_FE))
1029 StopHWFilter(feed->filter);
1030 }
1031
1032 if (feed->type == DMX_TYPE_SEC) {
1033 int i;
1034
1035 for (i = 0; i<demux->filternum; i++)
1036 if (demux->filter[i].state == DMX_STATE_GO &&
1037 demux->filter[i].filter.parent == &feed->feed.sec) {
1038 demux->filter[i].state = DMX_STATE_READY;
1039 if (demux->dmx.frontend->source != DMX_MEMORY_FE)
1040 StopHWFilter(&demux->filter[i]);
1041 }
1042 }
1043
1044 return 0;
1045}
1046
1047
1048static void restart_feeds(struct av7110 *av7110)
1049{
1050 struct dvb_demux *dvbdmx = &av7110->demux;
1051 struct dvb_demux_feed *feed;
1052 int mode;
1053 int i;
1054
1055 dprintk(4, "%p\n", av7110);
1056
1057 mode = av7110->playing;
1058 av7110->playing = 0;
1059 av7110->rec_mode = 0;
1060
1061 for (i = 0; i < dvbdmx->filternum; i++) {
1062 feed = &dvbdmx->feed[i];
1063 if (feed->state == DMX_STATE_GO)
1064 av7110_start_feed(feed);
1065 }
1066
1067 if (mode)
1068 av7110_av_start_play(av7110, mode);
1069}
1070
1071static int dvb_get_stc(struct dmx_demux *demux, unsigned int num,
1072 uint64_t *stc, unsigned int *base)
1073{
1074 int ret;
1075 u16 fwstc[4];
1076 u16 tag = ((COMTYPE_REQUEST << 8) + ReqSTC);
1077 struct dvb_demux *dvbdemux;
1078 struct av7110 *av7110;
1079
1080 /* pointer casting paranoia... */
1081 if (!demux)
1082 BUG();
1083 dvbdemux = (struct dvb_demux *) demux->priv;
1084 if (!dvbdemux)
1085 BUG();
1086 av7110 = (struct av7110 *) dvbdemux->priv;
1087
1088 dprintk(4, "%p\n", av7110);
1089
1090 if (num != 0)
1091 return -EINVAL;
1092
1093 ret = av7110_fw_request(av7110, &tag, 0, fwstc, 4);
1094 if (ret) {
1095 printk(KERN_ERR "%s: av7110_fw_request error\n", __FUNCTION__);
1096 return -EIO;
1097 }
1098 dprintk(2, "fwstc = %04hx %04hx %04hx %04hx\n",
1099 fwstc[0], fwstc[1], fwstc[2], fwstc[3]);
1100
1101 *stc = (((uint64_t) ((fwstc[3] & 0x8000) >> 15)) << 32) |
1102 (((uint64_t) fwstc[1]) << 16) | ((uint64_t) fwstc[0]);
1103 *base = 1;
1104
1105 dprintk(4, "stc = %lu\n", (unsigned long)*stc);
1106
1107 return 0;
1108}
1109
1110
1111/******************************************************************************
1112 * SEC device file operations
1113 ******************************************************************************/
1114
1115
1116static int av7110_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
1117{
1118 struct av7110* av7110 = (struct av7110*) fe->dvb->priv;
1119
1120 switch (tone) {
1121 case SEC_TONE_ON:
1122 Set22K(av7110, 1);
1123 break;
1124
1125 case SEC_TONE_OFF:
1126 Set22K(av7110, 0);
1127 break;
1128
1129 default:
1130 return -EINVAL;
1131 }
1132
1133 return 0;
1134}
1135
1136static int av7110_diseqc_send_master_cmd(struct dvb_frontend* fe,
1137 struct dvb_diseqc_master_cmd* cmd)
1138{
1139 struct av7110* av7110 = fe->dvb->priv;
1140
1141 av7110_diseqc_send(av7110, cmd->msg_len, cmd->msg, -1);
1142
1143 return 0;
1144}
1145
1146static int av7110_diseqc_send_burst(struct dvb_frontend* fe,
1147 fe_sec_mini_cmd_t minicmd)
1148{
1149 struct av7110* av7110 = fe->dvb->priv;
1150
1151 av7110_diseqc_send(av7110, 0, NULL, minicmd);
1152
1153 return 0;
1154}
1155
1156/* simplified code from budget-core.c */
1157static int stop_ts_capture(struct av7110 *budget)
1158{
1159 dprintk(2, "budget: %p\n", budget);
1160
1161 if (--budget->feeding1)
1162 return budget->feeding1;
1163 saa7146_write(budget->dev, MC1, MASK_20); /* DMA3 off */
1164 SAA7146_IER_DISABLE(budget->dev, MASK_10);
1165 SAA7146_ISR_CLEAR(budget->dev, MASK_10);
1166 return 0;
1167}
1168
1169static int start_ts_capture(struct av7110 *budget)
1170{
1171 dprintk(2, "budget: %p\n", budget);
1172
1173 if (budget->feeding1)
1174 return ++budget->feeding1;
1175 memset(budget->grabbing, 0x00, TS_HEIGHT * TS_WIDTH);
1176 budget->tsf = 0xff;
1177 budget->ttbp = 0;
1178 SAA7146_IER_ENABLE(budget->dev, MASK_10); /* VPE */
1179 saa7146_write(budget->dev, MC1, (MASK_04 | MASK_20)); /* DMA3 on */
1180 return ++budget->feeding1;
1181}
1182
1183static int budget_start_feed(struct dvb_demux_feed *feed)
1184{
1185 struct dvb_demux *demux = feed->demux;
1186 struct av7110 *budget = (struct av7110 *) demux->priv;
1187 int status;
1188
1189 dprintk(2, "av7110: %p\n", budget);
1190
1191 spin_lock(&budget->feedlock1);
1192 feed->pusi_seen = 0; /* have a clean section start */
1193 status = start_ts_capture(budget);
1194 spin_unlock(&budget->feedlock1);
1195 return status;
1196}
1197
1198static int budget_stop_feed(struct dvb_demux_feed *feed)
1199{
1200 struct dvb_demux *demux = feed->demux;
1201 struct av7110 *budget = (struct av7110 *) demux->priv;
1202 int status;
1203
1204 dprintk(2, "budget: %p\n", budget);
1205
1206 spin_lock(&budget->feedlock1);
1207 status = stop_ts_capture(budget);
1208 spin_unlock(&budget->feedlock1);
1209 return status;
1210}
1211
1212static void vpeirq(unsigned long data)
1213{
1214 struct av7110 *budget = (struct av7110 *) data;
1215 u8 *mem = (u8 *) (budget->grabbing);
1216 u32 olddma = budget->ttbp;
1217 u32 newdma = saa7146_read(budget->dev, PCI_VDP3);
1218
1219 if (!budgetpatch) {
1220 printk("av7110.c: vpeirq() called while budgetpatch disabled!"
1221 " check saa7146 IER register\n");
1222 BUG();
1223 }
1224 /* nearest lower position divisible by 188 */
1225 newdma -= newdma % 188;
1226
1227 if (newdma >= TS_BUFLEN)
1228 return;
1229
1230 budget->ttbp = newdma;
1231
1232 if (!budget->feeding1 || (newdma == olddma))
1233 return;
1234
1235#if 0
1236 /* track rps1 activity */
1237 printk("vpeirq: %02x Event Counter 1 0x%04x\n",
1238 mem[olddma],
1239 saa7146_read(budget->dev, EC1R) & 0x3fff);
1240#endif
1241
1242 if (newdma > olddma)
1243 /* no wraparound, dump olddma..newdma */
1244 dvb_dmx_swfilter_packets(&budget->demux1, mem + olddma, (newdma - olddma) / 188);
1245 else {
1246 /* wraparound, dump olddma..buflen and 0..newdma */
1247 dvb_dmx_swfilter_packets(&budget->demux1, mem + olddma, (TS_BUFLEN - olddma) / 188);
1248 dvb_dmx_swfilter_packets(&budget->demux1, mem, newdma / 188);
1249 }
1250}
1251
1252static int av7110_register(struct av7110 *av7110)
1253{
1254 int ret, i;
1255 struct dvb_demux *dvbdemux = &av7110->demux;
1256 struct dvb_demux *dvbdemux1 = &av7110->demux1;
1257
1258 dprintk(4, "%p\n", av7110);
1259
1260 if (av7110->registered)
1261 return -1;
1262
1263 av7110->registered = 1;
1264
1265 dvbdemux->priv = (void *) av7110;
1266
1267 for (i = 0; i < 32; i++)
1268 av7110->handle2filter[i] = NULL;
1269
1270 dvbdemux->filternum = 32;
1271 dvbdemux->feednum = 32;
1272 dvbdemux->start_feed = av7110_start_feed;
1273 dvbdemux->stop_feed = av7110_stop_feed;
1274 dvbdemux->write_to_decoder = av7110_write_to_decoder;
1275 dvbdemux->dmx.capabilities = (DMX_TS_FILTERING | DMX_SECTION_FILTERING |
1276 DMX_MEMORY_BASED_FILTERING);
1277
1278 dvb_dmx_init(&av7110->demux);
1279 av7110->demux.dmx.get_stc = dvb_get_stc;
1280
1281 av7110->dmxdev.filternum = 32;
1282 av7110->dmxdev.demux = &dvbdemux->dmx;
1283 av7110->dmxdev.capabilities = 0;
1284
1285 dvb_dmxdev_init(&av7110->dmxdev, av7110->dvb_adapter);
1286
1287 av7110->hw_frontend.source = DMX_FRONTEND_0;
1288
1289 ret = dvbdemux->dmx.add_frontend(&dvbdemux->dmx, &av7110->hw_frontend);
1290
1291 if (ret < 0)
1292 return ret;
1293
1294 av7110->mem_frontend.source = DMX_MEMORY_FE;
1295
1296 ret = dvbdemux->dmx.add_frontend(&dvbdemux->dmx, &av7110->mem_frontend);
1297
1298 if (ret < 0)
1299 return ret;
1300
1301 ret = dvbdemux->dmx.connect_frontend(&dvbdemux->dmx,
1302 &av7110->hw_frontend);
1303 if (ret < 0)
1304 return ret;
1305
1306 av7110_av_register(av7110);
1307 av7110_ca_register(av7110);
1308
1309#ifdef CONFIG_DVB_AV7110_OSD
1310 dvb_register_device(av7110->dvb_adapter, &av7110->osd_dev,
1311 &dvbdev_osd, av7110, DVB_DEVICE_OSD);
1312#endif
1313
1314 dvb_net_init(av7110->dvb_adapter, &av7110->dvb_net, &dvbdemux->dmx);
1315
1316 if (budgetpatch) {
1317 /* initialize software demux1 without its own frontend
1318 * demux1 hardware is connected to frontend0 of demux0
1319 */
1320 dvbdemux1->priv = (void *) av7110;
1321
1322 dvbdemux1->filternum = 256;
1323 dvbdemux1->feednum = 256;
1324 dvbdemux1->start_feed = budget_start_feed;
1325 dvbdemux1->stop_feed = budget_stop_feed;
1326 dvbdemux1->write_to_decoder = NULL;
1327
1328 dvbdemux1->dmx.capabilities = (DMX_TS_FILTERING | DMX_SECTION_FILTERING |
1329 DMX_MEMORY_BASED_FILTERING);
1330
1331 dvb_dmx_init(&av7110->demux1);
1332
1333 av7110->dmxdev1.filternum = 256;
1334 av7110->dmxdev1.demux = &dvbdemux1->dmx;
1335 av7110->dmxdev1.capabilities = 0;
1336
1337 dvb_dmxdev_init(&av7110->dmxdev1, av7110->dvb_adapter);
1338
1339 dvb_net_init(av7110->dvb_adapter, &av7110->dvb_net1, &dvbdemux1->dmx);
1340 printk("dvb-ttpci: additional demux1 for budget-patch registered\n");
1341 }
1342 return 0;
1343}
1344
1345
1346static void dvb_unregister(struct av7110 *av7110)
1347{
1348 struct dvb_demux *dvbdemux = &av7110->demux;
1349 struct dvb_demux *dvbdemux1 = &av7110->demux1;
1350
1351 dprintk(4, "%p\n", av7110);
1352
1353 if (!av7110->registered)
1354 return;
1355
1356 if (budgetpatch) {
1357 dvb_net_release(&av7110->dvb_net1);
1358 dvbdemux->dmx.close(&dvbdemux1->dmx);
1359 dvb_dmxdev_release(&av7110->dmxdev1);
1360 dvb_dmx_release(&av7110->demux1);
1361 }
1362
1363 dvb_net_release(&av7110->dvb_net);
1364
1365 dvbdemux->dmx.close(&dvbdemux->dmx);
1366 dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, &av7110->hw_frontend);
1367 dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, &av7110->mem_frontend);
1368
1369 dvb_dmxdev_release(&av7110->dmxdev);
1370 dvb_dmx_release(&av7110->demux);
1371
1372 if (av7110->fe != NULL)
1373 dvb_unregister_frontend(av7110->fe);
1374 dvb_unregister_device(av7110->osd_dev);
1375 av7110_av_unregister(av7110);
1376 av7110_ca_unregister(av7110);
1377}
1378
1379
1380/****************************************************************************
1381 * I2C client commands
1382 ****************************************************************************/
1383
1384int i2c_writereg(struct av7110 *av7110, u8 id, u8 reg, u8 val)
1385{
1386 u8 msg[2] = { reg, val };
1387 struct i2c_msg msgs;
1388
1389 msgs.flags = 0;
1390 msgs.addr = id / 2;
1391 msgs.len = 2;
1392 msgs.buf = msg;
1393 return i2c_transfer(&av7110->i2c_adap, &msgs, 1);
1394}
1395
1396#if 0
1397u8 i2c_readreg(struct av7110 *av7110, u8 id, u8 reg)
1398{
1399 u8 mm1[] = {0x00};
1400 u8 mm2[] = {0x00};
1401 struct i2c_msg msgs[2];
1402
1403 msgs[0].flags = 0;
1404 msgs[1].flags = I2C_M_RD;
1405 msgs[0].addr = msgs[1].addr = id / 2;
1406 mm1[0] = reg;
1407 msgs[0].len = 1; msgs[1].len = 1;
1408 msgs[0].buf = mm1; msgs[1].buf = mm2;
1409 i2c_transfer(&av7110->i2c_adap, msgs, 2);
1410
1411 return mm2[0];
1412}
1413#endif
1414
1415/****************************************************************************
1416 * INITIALIZATION
1417 ****************************************************************************/
1418
1419
1420static int check_firmware(struct av7110* av7110)
1421{
1422 u32 crc = 0, len = 0;
1423 unsigned char *ptr;
1424
1425 /* check for firmware magic */
1426 ptr = av7110->bin_fw;
1427 if (ptr[0] != 'A' || ptr[1] != 'V' ||
1428 ptr[2] != 'F' || ptr[3] != 'W') {
1429 printk("dvb-ttpci: this is not an av7110 firmware\n");
1430 return -EINVAL;
1431 }
1432 ptr += 4;
1433
1434 /* check dpram file */
1435 crc = ntohl(*(u32*) ptr);
1436 ptr += 4;
1437 len = ntohl(*(u32*) ptr);
1438 ptr += 4;
1439 if (len >= 512) {
1440 printk("dvb-ttpci: dpram file is way to big.\n");
1441 return -EINVAL;
1442 }
1443 if (crc != crc32_le(0, ptr, len)) {
1444 printk("dvb-ttpci: crc32 of dpram file does not match.\n");
1445 return -EINVAL;
1446 }
1447 av7110->bin_dpram = ptr;
1448 av7110->size_dpram = len;
1449 ptr += len;
1450
1451 /* check root file */
1452 crc = ntohl(*(u32*) ptr);
1453 ptr += 4;
1454 len = ntohl(*(u32*) ptr);
1455 ptr += 4;
1456
1457 if (len <= 200000 || len >= 300000 ||
1458 len > ((av7110->bin_fw + av7110->size_fw) - ptr)) {
1459 printk("dvb-ttpci: root file has strange size (%d). aborting.\n", len);
1460 return -EINVAL;
1461 }
1462 if( crc != crc32_le(0, ptr, len)) {
1463 printk("dvb-ttpci: crc32 of root file does not match.\n");
1464 return -EINVAL;
1465 }
1466 av7110->bin_root = ptr;
1467 av7110->size_root = len;
1468 return 0;
1469}
1470
1471#ifdef CONFIG_DVB_AV7110_FIRMWARE_FILE
1472#include "av7110_firm.h"
1473static void put_firmware(struct av7110* av7110)
1474{
1475 av7110->bin_fw = NULL;
1476}
1477
1478static inline int get_firmware(struct av7110* av7110)
1479{
1480 av7110->bin_fw = dvb_ttpci_fw;
1481 av7110->size_fw = sizeof(dvb_ttpci_fw);
1482 return check_firmware(av7110);
1483}
1484#else
1485static void put_firmware(struct av7110* av7110)
1486{
1487 vfree(av7110->bin_fw);
1488}
1489
1490static int get_firmware(struct av7110* av7110)
1491{
1492 int ret;
1493 const struct firmware *fw;
1494
1495 /* request the av7110 firmware, this will block until someone uploads it */
1496 ret = request_firmware(&fw, "dvb-ttpci-01.fw", &av7110->dev->pci->dev);
1497 if (ret) {
1498 if (ret == -ENOENT) {
1499 printk(KERN_ERR "dvb-ttpci: could not load firmware,"
1500 " file not found: dvb-ttpci-01.fw\n");
1501 printk(KERN_ERR "dvb-ttpci: usually this should be in"
1502 " /usr/lib/hotplug/firmware\n");
1503 printk(KERN_ERR "dvb-ttpci: and can be downloaded here"
1504 " http://www.linuxtv.org/download/dvb/firmware/\n");
1505 } else
1506 printk(KERN_ERR "dvb-ttpci: cannot request firmware"
1507 " (error %i)\n", ret);
1508 return -EINVAL;
1509 }
1510
1511 if (fw->size <= 200000) {
1512 printk("dvb-ttpci: this firmware is way too small.\n");
1513 release_firmware(fw);
1514 return -EINVAL;
1515 }
1516
1517 /* check if the firmware is available */
1518 av7110->bin_fw = (unsigned char *) vmalloc(fw->size);
1519 if (NULL == av7110->bin_fw) {
1520 dprintk(1, "out of memory\n");
1521 release_firmware(fw);
1522 return -ENOMEM;
1523 }
1524
1525 memcpy(av7110->bin_fw, fw->data, fw->size);
1526 av7110->size_fw = fw->size;
1527 if ((ret = check_firmware(av7110)))
1528 vfree(av7110->bin_fw);
1529
1530 release_firmware(fw);
1531 return ret;
1532}
1533#endif
1534
1535
1536static int alps_bsrv2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
1537{
1538 struct av7110* av7110 = (struct av7110*) fe->dvb->priv;
1539 u8 pwr = 0;
1540 u8 buf[4];
1541 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
1542 u32 div = (params->frequency + 479500) / 125;
1543
1544 if (params->frequency > 2000000) pwr = 3;
1545 else if (params->frequency > 1800000) pwr = 2;
1546 else if (params->frequency > 1600000) pwr = 1;
1547 else if (params->frequency > 1200000) pwr = 0;
1548 else if (params->frequency >= 1100000) pwr = 1;
1549 else pwr = 2;
1550
1551 buf[0] = (div >> 8) & 0x7f;
1552 buf[1] = div & 0xff;
1553 buf[2] = ((div & 0x18000) >> 10) | 0x95;
1554 buf[3] = (pwr << 6) | 0x30;
1555
1556 // NOTE: since we're using a prescaler of 2, we set the
1557 // divisor frequency to 62.5kHz and divide by 125 above
1558
1559 if (i2c_transfer (&av7110->i2c_adap, &msg, 1) != 1)
1560 return -EIO;
1561 return 0;
1562}
1563
1564static struct ves1x93_config alps_bsrv2_config = {
1565 .demod_address = 0x08,
1566 .xin = 90100000UL,
1567 .invert_pwm = 0,
1568 .pll_set = alps_bsrv2_pll_set,
1569};
1570
1571
1572static u8 alps_bsru6_inittab[] = {
1573 0x01, 0x15,
1574 0x02, 0x30,
1575 0x03, 0x00,
1576 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
1577 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */
1578 0x06, 0x40, /* DAC not used, set to high impendance mode */
1579 0x07, 0x00, /* DAC LSB */
1580 0x08, 0x40, /* DiSEqC off, LNB power on OP2/LOCK pin on */
1581 0x09, 0x00, /* FIFO */
1582 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
1583 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */
1584 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
1585 0x10, 0x3f, // AGC2 0x3d
1586 0x11, 0x84,
1587 0x12, 0xb5, // Lock detect: -64 Carrier freq detect:on
1588 0x15, 0xc9, // lock detector threshold
1589 0x16, 0x00,
1590 0x17, 0x00,
1591 0x18, 0x00,
1592 0x19, 0x00,
1593 0x1a, 0x00,
1594 0x1f, 0x50,
1595 0x20, 0x00,
1596 0x21, 0x00,
1597 0x22, 0x00,
1598 0x23, 0x00,
1599 0x28, 0x00, // out imp: normal out type: parallel FEC mode:0
1600 0x29, 0x1e, // 1/2 threshold
1601 0x2a, 0x14, // 2/3 threshold
1602 0x2b, 0x0f, // 3/4 threshold
1603 0x2c, 0x09, // 5/6 threshold
1604 0x2d, 0x05, // 7/8 threshold
1605 0x2e, 0x01,
1606 0x31, 0x1f, // test all FECs
1607 0x32, 0x19, // viterbi and synchro search
1608 0x33, 0xfc, // rs control
1609 0x34, 0x93, // error control
1610 0x0f, 0x52,
1611 0xff, 0xff
1612};
1613
1614static int alps_bsru6_set_symbol_rate(struct dvb_frontend* fe, u32 srate, u32 ratio)
1615{
1616 u8 aclk = 0;
1617 u8 bclk = 0;
1618
1619 if (srate < 1500000) { aclk = 0xb7; bclk = 0x47; }
1620 else if (srate < 3000000) { aclk = 0xb7; bclk = 0x4b; }
1621 else if (srate < 7000000) { aclk = 0xb7; bclk = 0x4f; }
1622 else if (srate < 14000000) { aclk = 0xb7; bclk = 0x53; }
1623 else if (srate < 30000000) { aclk = 0xb6; bclk = 0x53; }
1624 else if (srate < 45000000) { aclk = 0xb4; bclk = 0x51; }
1625
1626 stv0299_writereg(fe, 0x13, aclk);
1627 stv0299_writereg(fe, 0x14, bclk);
1628 stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
1629 stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
1630 stv0299_writereg(fe, 0x21, (ratio ) & 0xf0);
1631
1632 return 0;
1633}
1634
1635static int alps_bsru6_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
1636{
1637 struct av7110* av7110 = (struct av7110*) fe->dvb->priv;
1638 int ret;
1639 u8 data[4];
1640 u32 div;
1641 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
1642
1643 if ((params->frequency < 950000) || (params->frequency > 2150000))
1644 return -EINVAL;
1645
1646 div = (params->frequency + (125 - 1)) / 125; // round correctly
1647 data[0] = (div >> 8) & 0x7f;
1648 data[1] = div & 0xff;
1649 data[2] = 0x80 | ((div & 0x18000) >> 10) | 4;
1650 data[3] = 0xC4;
1651
1652 if (params->frequency > 1530000) data[3] = 0xc0;
1653
1654 ret = i2c_transfer(&av7110->i2c_adap, &msg, 1);
1655 if (ret != 1)
1656 return -EIO;
1657 return 0;
1658}
1659
1660static struct stv0299_config alps_bsru6_config = {
1661
1662 .demod_address = 0x68,
1663 .inittab = alps_bsru6_inittab,
1664 .mclk = 88000000UL,
1665 .invert = 1,
1666 .enhanced_tuning = 0,
1667 .skip_reinit = 0,
1668 .lock_output = STV0229_LOCKOUTPUT_1,
1669 .volt13_op0_op1 = STV0299_VOLT13_OP1,
1670 .min_delay_ms = 100,
1671 .set_symbol_rate = alps_bsru6_set_symbol_rate,
1672 .pll_set = alps_bsru6_pll_set,
1673};
1674
1675
1676
1677static int alps_tdbe2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
1678{
1679 struct av7110* av7110 = fe->dvb->priv;
1680 u32 div;
1681 u8 data[4];
1682 struct i2c_msg msg = { .addr = 0x62, .flags = 0, .buf = data, .len = sizeof(data) };
1683
1684 div = (params->frequency + 35937500 + 31250) / 62500;
1685
1686 data[0] = (div >> 8) & 0x7f;
1687 data[1] = div & 0xff;
1688 data[2] = 0x85 | ((div >> 10) & 0x60);
1689 data[3] = (params->frequency < 174000000 ? 0x88 : params->frequency < 470000000 ? 0x84 : 0x81);
1690
1691 if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1)
1692 return -EIO;
1693 return 0;
1694}
1695
1696static struct ves1820_config alps_tdbe2_config = {
1697 .demod_address = 0x09,
1698 .xin = 57840000UL,
1699 .invert = 1,
1700 .selagc = VES1820_SELAGC_SIGNAMPERR,
1701 .pll_set = alps_tdbe2_pll_set,
1702};
1703
1704
1705
1706
1707static int grundig_29504_451_pll_set(struct dvb_frontend* fe,
1708 struct dvb_frontend_parameters* params)
1709{
1710 struct av7110* av7110 = fe->dvb->priv;
1711 u32 div;
1712 u8 data[4];
1713 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
1714
1715 div = params->frequency / 125;
1716 data[0] = (div >> 8) & 0x7f;
1717 data[1] = div & 0xff;
1718 data[2] = 0x8e;
1719 data[3] = 0x00;
1720
1721 if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1)
1722 return -EIO;
1723 return 0;
1724}
1725
1726static struct tda8083_config grundig_29504_451_config = {
1727 .demod_address = 0x68,
1728 .pll_set = grundig_29504_451_pll_set,
1729};
1730
1731
1732
1733static int philips_cd1516_pll_set(struct dvb_frontend* fe,
1734 struct dvb_frontend_parameters* params)
1735{
1736 struct av7110* av7110 = fe->dvb->priv;
1737 u32 div;
1738 u32 f = params->frequency;
1739 u8 data[4];
1740 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
1741
1742 div = (f + 36125000 + 31250) / 62500;
1743
1744 data[0] = (div >> 8) & 0x7f;
1745 data[1] = div & 0xff;
1746 data[2] = 0x8e;
1747 data[3] = (f < 174000000 ? 0xa1 : f < 470000000 ? 0x92 : 0x34);
1748
1749 if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1)
1750 return -EIO;
1751 return 0;
1752}
1753
1754static struct ves1820_config philips_cd1516_config = {
1755 .demod_address = 0x09,
1756 .xin = 57840000UL,
1757 .invert = 1,
1758 .selagc = VES1820_SELAGC_SIGNAMPERR,
1759 .pll_set = philips_cd1516_pll_set,
1760};
1761
1762
1763
1764static int alps_tdlb7_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
1765{
1766 struct av7110* av7110 = fe->dvb->priv;
1767 u32 div, pwr;
1768 u8 data[4];
1769 struct i2c_msg msg = { .addr = 0x60, .flags = 0, .buf = data, .len = sizeof(data) };
1770
1771 div = (params->frequency + 36200000) / 166666;
1772
1773 if (params->frequency <= 782000000)
1774 pwr = 1;
1775 else
1776 pwr = 2;
1777
1778 data[0] = (div >> 8) & 0x7f;
1779 data[1] = div & 0xff;
1780 data[2] = 0x85;
1781 data[3] = pwr << 6;
1782
1783 if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1)
1784 return -EIO;
1785 return 0;
1786}
1787
1788static int alps_tdlb7_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name)
1789{
1790 struct av7110* av7110 = (struct av7110*) fe->dvb->priv;
1791
1792 return request_firmware(fw, name, &av7110->dev->pci->dev);
1793}
1794
1795static struct sp8870_config alps_tdlb7_config = {
1796
1797 .demod_address = 0x71,
1798 .pll_set = alps_tdlb7_pll_set,
1799 .request_firmware = alps_tdlb7_request_firmware,
1800};
1801
1802
1803
1804static int nexusca_stv0297_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
1805{
1806 struct av7110* av7110 = fe->dvb->priv;
1807 u32 div;
1808 u8 data[4];
1809 struct i2c_msg msg = { .addr = 0x63, .flags = 0, .buf = data, .len = sizeof(data) };
1810 struct i2c_msg readmsg = { .addr = 0x63, .flags = I2C_M_RD, .buf = data, .len = 1 };
1811 int i;
1812
1813 div = (params->frequency + 36150000 + 31250) / 62500;
1814
1815 data[0] = (div >> 8) & 0x7f;
1816 data[1] = div & 0xff;
1817 data[2] = 0xce;
1818
1819 if (params->frequency < 45000000)
1820 return -EINVAL;
1821 else if (params->frequency < 137000000)
1822 data[3] = 0x01;
1823 else if (params->frequency < 403000000)
1824 data[3] = 0x02;
1825 else if (params->frequency < 860000000)
1826 data[3] = 0x04;
1827 else
1828 return -EINVAL;
1829
1830 stv0297_enable_plli2c(fe);
1831 if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1) {
1832 printk("nexusca: pll transfer failed!\n");
1833 return -EIO;
1834 }
1835
1836 // wait for PLL lock
1837 for(i = 0; i < 20; i++) {
1838
1839 stv0297_enable_plli2c(fe);
1840 if (i2c_transfer(&av7110->i2c_adap, &readmsg, 1) == 1)
1841 if (data[0] & 0x40) break;
1842 msleep(10);
1843 }
1844
1845 return 0;
1846}
1847
1848static struct stv0297_config nexusca_stv0297_config = {
1849
1850 .demod_address = 0x1C,
1851 .invert = 1,
1852 .pll_set = nexusca_stv0297_pll_set,
1853};
1854
1855
1856
1857static int grundig_29504_401_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
1858{
1859 struct av7110* av7110 = (struct av7110*) fe->dvb->priv;
1860 u32 div;
1861 u8 cfg, cpump, band_select;
1862 u8 data[4];
1863 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
1864
1865 div = (36125000 + params->frequency) / 166666;
1866
1867 cfg = 0x88;
1868
1869 if (params->frequency < 175000000) cpump = 2;
1870 else if (params->frequency < 390000000) cpump = 1;
1871 else if (params->frequency < 470000000) cpump = 2;
1872 else if (params->frequency < 750000000) cpump = 1;
1873 else cpump = 3;
1874
1875 if (params->frequency < 175000000) band_select = 0x0e;
1876 else if (params->frequency < 470000000) band_select = 0x05;
1877 else band_select = 0x03;
1878
1879 data[0] = (div >> 8) & 0x7f;
1880 data[1] = div & 0xff;
1881 data[2] = ((div >> 10) & 0x60) | cfg;
1882 data[3] = (cpump << 6) | band_select;
1883
1884 if (i2c_transfer (&av7110->i2c_adap, &msg, 1) != 1) return -EIO;
1885 return 0;
1886}
1887
1888static struct l64781_config grundig_29504_401_config = {
1889 .demod_address = 0x55,
1890 .pll_set = grundig_29504_401_pll_set,
1891};
1892
1893
1894
1895static void av7110_fe_lock_fix(struct av7110* av7110, fe_status_t status)
1896{
1897 int synced = (status & FE_HAS_LOCK) ? 1 : 0;
1898
1899 av7110->fe_status = status;
1900
1901 if (av7110->fe_synced == synced)
1902 return;
1903
1904 av7110->fe_synced = synced;
1905
1906 if (av7110->playing)
1907 return;
1908
1909 if (down_interruptible(&av7110->pid_mutex))
1910 return;
1911
1912 if (av7110->fe_synced) {
1913 SetPIDs(av7110, av7110->pids[DMX_PES_VIDEO],
1914 av7110->pids[DMX_PES_AUDIO],
1915 av7110->pids[DMX_PES_TELETEXT], 0,
1916 av7110->pids[DMX_PES_PCR]);
1917 av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, Scan, 0);
1918 } else {
1919 SetPIDs(av7110, 0, 0, 0, 0, 0);
1920 av7110_fw_cmd(av7110, COMTYPE_PID_FILTER, FlushTSQueue, 0);
1921 av7110_wait_msgstate(av7110, GPMQBusy);
1922 }
1923
1924 up(&av7110->pid_mutex);
1925}
1926
1927static int av7110_fe_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
1928{
1929 struct av7110* av7110 = fe->dvb->priv;
1930 av7110_fe_lock_fix(av7110, 0);
1931 return av7110->fe_set_frontend(fe, params);
1932}
1933
1934static int av7110_fe_init(struct dvb_frontend* fe)
1935{
1936 struct av7110* av7110 = fe->dvb->priv;
1937
1938 av7110_fe_lock_fix(av7110, 0);
1939 return av7110->fe_init(fe);
1940}
1941
1942static int av7110_fe_read_status(struct dvb_frontend* fe, fe_status_t* status)
1943{
1944 struct av7110* av7110 = fe->dvb->priv;
1945 int ret;
1946
1947 /* call the real implementation */
1948 ret = av7110->fe_read_status(fe, status);
1949 if (ret)
1950 return ret;
1951
1952 if (((*status ^ av7110->fe_status) & FE_HAS_LOCK) && (*status & FE_HAS_LOCK)) {
1953 av7110_fe_lock_fix(av7110, *status);
1954 }
1955
1956 return 0;
1957}
1958
1959static int av7110_fe_diseqc_reset_overload(struct dvb_frontend* fe)
1960{
1961 struct av7110* av7110 = fe->dvb->priv;
1962
1963 av7110_fe_lock_fix(av7110, 0);
1964 return av7110->fe_diseqc_reset_overload(fe);
1965}
1966
1967static int av7110_fe_diseqc_send_master_cmd(struct dvb_frontend* fe,
1968 struct dvb_diseqc_master_cmd* cmd)
1969{
1970 struct av7110* av7110 = fe->dvb->priv;
1971
1972 av7110_fe_lock_fix(av7110, 0);
1973 return av7110->fe_diseqc_send_master_cmd(fe, cmd);
1974}
1975
1976static int av7110_fe_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd)
1977{
1978 struct av7110* av7110 = fe->dvb->priv;
1979
1980 av7110_fe_lock_fix(av7110, 0);
1981 return av7110->fe_diseqc_send_burst(fe, minicmd);
1982}
1983
1984static int av7110_fe_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
1985{
1986 struct av7110* av7110 = fe->dvb->priv;
1987
1988 av7110_fe_lock_fix(av7110, 0);
1989 return av7110->fe_set_tone(fe, tone);
1990}
1991
1992static int av7110_fe_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
1993{
1994 struct av7110* av7110 = fe->dvb->priv;
1995
1996 av7110_fe_lock_fix(av7110, 0);
1997 return av7110->fe_set_voltage(fe, voltage);
1998}
1999
2000static int av7110_fe_dishnetwork_send_legacy_command(struct dvb_frontend* fe, unsigned int cmd)
2001{
2002 struct av7110* av7110 = fe->dvb->priv;
2003
2004 av7110_fe_lock_fix(av7110, 0);
2005 return av7110->fe_dishnetwork_send_legacy_command(fe, cmd);
2006}
2007
2008static u8 read_pwm(struct av7110* av7110)
2009{
2010 u8 b = 0xff;
2011 u8 pwm;
2012 struct i2c_msg msg[] = { { .addr = 0x50,.flags = 0,.buf = &b,.len = 1 },
2013 { .addr = 0x50,.flags = I2C_M_RD,.buf = &pwm,.len = 1} };
2014
2015 if ((i2c_transfer(&av7110->i2c_adap, msg, 2) != 2) || (pwm == 0xff))
2016 pwm = 0x48;
2017
2018 return pwm;
2019}
2020
2021static int frontend_init(struct av7110 *av7110)
2022{
2023 int ret;
2024
2025 if (av7110->dev->pci->subsystem_vendor == 0x110a) {
2026 switch(av7110->dev->pci->subsystem_device) {
2027 case 0x0000: // Fujitsu/Siemens DVB-Cable (ves1820/Philips CD1516(??))
2028 av7110->fe = ves1820_attach(&philips_cd1516_config,
2029 &av7110->i2c_adap, read_pwm(av7110));
2030 break;
2031 }
2032
2033 } else if (av7110->dev->pci->subsystem_vendor == 0x13c2) {
2034 switch(av7110->dev->pci->subsystem_device) {
2035 case 0x0000: // Hauppauge/TT WinTV DVB-S rev1.X
2036 case 0x0003: // Hauppauge/TT WinTV Nexus-S Rev 2.X
2037 case 0x1002: // Hauppauge/TT WinTV DVB-S rev1.3SE
2038
2039 // try the ALPS BSRV2 first of all
2040 av7110->fe = ves1x93_attach(&alps_bsrv2_config, &av7110->i2c_adap);
2041 if (av7110->fe) {
2042 av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd;
2043 av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst;
2044 av7110->fe->ops->set_tone = av7110_set_tone;
2045 break;
2046 }
2047
2048 // try the ALPS BSRU6 now
2049 av7110->fe = stv0299_attach(&alps_bsru6_config, &av7110->i2c_adap);
2050 if (av7110->fe) {
2051 av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd;
2052 av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst;
2053 av7110->fe->ops->set_tone = av7110_set_tone;
2054 break;
2055 }
2056
2057 // Try the grundig 29504-451
2058 av7110->fe = tda8083_attach(&grundig_29504_451_config, &av7110->i2c_adap);
2059 if (av7110->fe) {
2060 av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd;
2061 av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst;
2062 av7110->fe->ops->set_tone = av7110_set_tone;
2063 break;
2064 }
2065
2066 /* Try DVB-C cards */
2067 switch(av7110->dev->pci->subsystem_device) {
2068 case 0x0000:
2069 /* Siemens DVB-C (full-length card) VES1820/Philips CD1516 */
2070 av7110->fe = ves1820_attach(&philips_cd1516_config, &av7110->i2c_adap,
2071 read_pwm(av7110));
2072 break;
2073 case 0x0003:
2074 /* Haupauge DVB-C 2.1 VES1820/ALPS TDBE2 */
2075 av7110->fe = ves1820_attach(&alps_tdbe2_config, &av7110->i2c_adap,
2076 read_pwm(av7110));
2077 break;
2078 }
2079 break;
2080
2081 case 0x0001: // Hauppauge/TT Nexus-T premium rev1.X
2082
2083 // ALPS TDLB7
2084 av7110->fe = sp8870_attach(&alps_tdlb7_config, &av7110->i2c_adap);
2085 break;
2086
2087 case 0x0002: // Hauppauge/TT DVB-C premium rev2.X
2088
2089 av7110->fe = ves1820_attach(&alps_tdbe2_config, &av7110->i2c_adap, read_pwm(av7110));
2090 break;
2091
2092 case 0x0006: /* Fujitsu-Siemens DVB-S rev 1.6 */
2093 /* Grundig 29504-451 */
2094 av7110->fe = tda8083_attach(&grundig_29504_451_config, &av7110->i2c_adap);
2095 if (av7110->fe) {
2096 av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd;
2097 av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst;
2098 av7110->fe->ops->set_tone = av7110_set_tone;
2099 }
2100 break;
2101
2102 case 0x0008: // Hauppauge/TT DVB-T
2103
2104 av7110->fe = l64781_attach(&grundig_29504_401_config, &av7110->i2c_adap);
2105 break;
2106
2107 case 0x000A: // Hauppauge/TT Nexus-CA rev1.X
2108
2109 av7110->fe = stv0297_attach(&nexusca_stv0297_config, &av7110->i2c_adap, 0x7b);
2110 if (av7110->fe) {
2111 /* set TDA9819 into DVB mode */
2112 saa7146_setgpio(av7110->dev, 1, SAA7146_GPIO_OUTLO); // TDA9198 pin9(STD)
2113 saa7146_setgpio(av7110->dev, 3, SAA7146_GPIO_OUTLO); // TDA9198 pin30(VIF)
2114
2115 /* tuner on this needs a slower i2c bus speed */
2116 av7110->dev->i2c_bitrate = SAA7146_I2C_BUS_BIT_RATE_240;
2117 break;
2118 }
2119 }
2120 }
2121
2122 if (!av7110->fe) {
2123 /* FIXME: propagate the failure code from the lower layers */
2124 ret = -ENOMEM;
2125 printk("dvb-ttpci: A frontend driver was not found for device %04x/%04x subsystem %04x/%04x\n",
2126 av7110->dev->pci->vendor,
2127 av7110->dev->pci->device,
2128 av7110->dev->pci->subsystem_vendor,
2129 av7110->dev->pci->subsystem_device);
2130 } else {
2131 FE_FUNC_OVERRIDE(av7110->fe->ops->init, av7110->fe_init, av7110_fe_init);
2132 FE_FUNC_OVERRIDE(av7110->fe->ops->read_status, av7110->fe_read_status, av7110_fe_read_status);
2133 FE_FUNC_OVERRIDE(av7110->fe->ops->diseqc_reset_overload, av7110->fe_diseqc_reset_overload, av7110_fe_diseqc_reset_overload);
2134 FE_FUNC_OVERRIDE(av7110->fe->ops->diseqc_send_master_cmd, av7110->fe_diseqc_send_master_cmd, av7110_fe_diseqc_send_master_cmd);
2135 FE_FUNC_OVERRIDE(av7110->fe->ops->diseqc_send_burst, av7110->fe_diseqc_send_burst, av7110_fe_diseqc_send_burst);
2136 FE_FUNC_OVERRIDE(av7110->fe->ops->set_tone, av7110->fe_set_tone, av7110_fe_set_tone);
2137 FE_FUNC_OVERRIDE(av7110->fe->ops->set_voltage, av7110->fe_set_voltage, av7110_fe_set_voltage;)
2138 FE_FUNC_OVERRIDE(av7110->fe->ops->dishnetwork_send_legacy_command, av7110->fe_dishnetwork_send_legacy_command, av7110_fe_dishnetwork_send_legacy_command);
2139 FE_FUNC_OVERRIDE(av7110->fe->ops->set_frontend, av7110->fe_set_frontend, av7110_fe_set_frontend);
2140
2141 ret = dvb_register_frontend(av7110->dvb_adapter, av7110->fe);
2142 if (ret < 0) {
2143 printk("av7110: Frontend registration failed!\n");
2144 if (av7110->fe->ops->release)
2145 av7110->fe->ops->release(av7110->fe);
2146 av7110->fe = NULL;
2147 }
2148 }
2149 return ret;
2150}
2151
2152/* Budgetpatch note:
2153 * Original hardware design by Roberto Deza:
2154 * There is a DVB_Wiki at
2155 * http://212.227.36.83/linuxtv/wiki/index.php/Main_Page
2156 * where is described this 'DVB TT Budget Patch', on Card Modding:
2157 * http://212.227.36.83/linuxtv/wiki/index.php/DVB_TT_Budget_Patch
2158 * On the short description there is also a link to a external file,
2159 * with more details:
2160 * http://perso.wanadoo.es/jesussolano/Ttf_tsc1.zip
2161 *
2162 * New software triggering design by Emard that works on
2163 * original Roberto Deza's hardware:
2164 *
2165 * rps1 code for budgetpatch will copy internal HS event to GPIO3 pin.
2166 * GPIO3 is in budget-patch hardware connectd to port B VSYNC
2167 * HS is an internal event of 7146, accessible with RPS
2168 * and temporarily raised high every n lines
2169 * (n in defined in the RPS_THRESH1 counter threshold)
2170 * I think HS is raised high on the beginning of the n-th line
2171 * and remains high until this n-th line that triggered
2172 * it is completely received. When the receiption of n-th line
2173 * ends, HS is lowered.
2174 *
2175 * To transmit data over DMA, 7146 needs changing state at
2176 * port B VSYNC pin. Any changing of port B VSYNC will
2177 * cause some DMA data transfer, with more or less packets loss.
2178 * It depends on the phase and frequency of VSYNC and
2179 * the way of 7146 is instructed to trigger on port B (defined
2180 * in DD1_INIT register, 3rd nibble from the right valid
2181 * numbers are 0-7, see datasheet)
2182 *
2183 * The correct triggering can minimize packet loss,
2184 * dvbtraffic should give this stable bandwidths:
2185 * 22k transponder = 33814 kbit/s
2186 * 27.5k transponder = 38045 kbit/s
2187 * by experiment it is found that the best results
2188 * (stable bandwidths and almost no packet loss)
2189 * are obtained using DD1_INIT triggering number 2
2190 * (Va at rising edge of VS Fa = HS x VS-failing forced toggle)
2191 * and a VSYNC phase that occurs in the middle of DMA transfer
2192 * (about byte 188*512=96256 in the DMA window).
2193 *
2194 * Phase of HS is still not clear to me how to control,
2195 * It just happens to be so. It can be seen if one enables
2196 * RPS_IRQ and print Event Counter 1 in vpeirq(). Every
2197 * time RPS_INTERRUPT is called, the Event Counter 1 will
2198 * increment. That's how the 7146 is programmed to do event
2199 * counting in this budget-patch.c
2200 * I *think* HPS setting has something to do with the phase
2201 * of HS but I cant be 100% sure in that.
2202 *
2203 * hardware debug note: a working budget card (including budget patch)
2204 * with vpeirq() interrupt setup in mode "0x90" (every 64K) will
2205 * generate 3 interrupts per 25-Hz DMA frame of 2*188*512 bytes
2206 * and that means 3*25=75 Hz of interrupt freqency, as seen by
2207 * watch cat /proc/interrupts
2208 *
2209 * If this frequency is 3x lower (and data received in the DMA
2210 * buffer don't start with 0x47, but in the middle of packets,
2211 * whose lengths appear to be like 188 292 188 104 etc.
2212 * this means VSYNC line is not connected in the hardware.
2213 * (check soldering pcb and pins)
2214 * The same behaviour of missing VSYNC can be duplicated on budget
2215 * cards, by seting DD1_INIT trigger mode 7 in 3rd nibble.
2216 */
2217static int av7110_attach(struct saa7146_dev* dev, struct saa7146_pci_extension_data *pci_ext)
2218{
2219 const int length = TS_WIDTH * TS_HEIGHT;
2220 struct pci_dev *pdev = dev->pci;
2221 struct av7110 *av7110;
2222 int ret, count = 0;
2223
2224 dprintk(4, "dev: %p\n", dev);
2225
2226 /* Set RPS_IRQ to 1 to track rps1 activity.
2227 * Enabling this won't send any interrupt to PC CPU.
2228 */
2229#define RPS_IRQ 0
2230
2231 if (budgetpatch == 1) {
2232 budgetpatch = 0;
2233 /* autodetect the presence of budget patch
2234 * this only works if saa7146 has been recently
2235 * reset with with MASK_31 to MC1
2236 *
2237 * will wait for VBI_B event (vertical blank at port B)
2238 * and will reset GPIO3 after VBI_B is detected.
2239 * (GPIO3 should be raised high by CPU to
2240 * test if GPIO3 will generate vertical blank signal
2241 * in budget patch GPIO3 is connected to VSYNC_B
2242 */
2243
2244 /* RESET SAA7146 */
2245 saa7146_write(dev, MC1, MASK_31);
2246 /* autodetection success seems to be time-dependend after reset */
2247
2248 /* Fix VSYNC level */
2249 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
2250 /* set vsync_b triggering */
2251 saa7146_write(dev, DD1_STREAM_B, 0);
2252 /* port B VSYNC at rising edge */
2253 saa7146_write(dev, DD1_INIT, 0x00000200);
2254 saa7146_write(dev, BRS_CTRL, 0x00000000); // VBI
2255 saa7146_write(dev, MC2,
2256 1 * (MASK_08 | MASK_24) | // BRS control
2257 0 * (MASK_09 | MASK_25) | // a
2258 1 * (MASK_10 | MASK_26) | // b
2259 0 * (MASK_06 | MASK_22) | // HPS_CTRL1
2260 0 * (MASK_05 | MASK_21) | // HPS_CTRL2
2261 0 * (MASK_01 | MASK_15) // DEBI
2262 );
2263
2264 /* start writing RPS1 code from beginning */
2265 count = 0;
2266 /* Disable RPS1 */
2267 saa7146_write(dev, MC1, MASK_29);
2268 /* RPS1 timeout disable */
2269 saa7146_write(dev, RPS_TOV1, 0);
2270 WRITE_RPS1(cpu_to_le32(CMD_PAUSE | EVT_VBI_B));
2271 WRITE_RPS1(cpu_to_le32(CMD_WR_REG_MASK | (GPIO_CTRL>>2)));
2272 WRITE_RPS1(cpu_to_le32(GPIO3_MSK));
2273 WRITE_RPS1(cpu_to_le32(SAA7146_GPIO_OUTLO<<24));
2274#if RPS_IRQ
2275 /* issue RPS1 interrupt to increment counter */
2276 WRITE_RPS1(cpu_to_le32(CMD_INTERRUPT));
2277#endif
2278 WRITE_RPS1(cpu_to_le32(CMD_STOP));
2279 /* Jump to begin of RPS program as safety measure (p37) */
2280 WRITE_RPS1(cpu_to_le32(CMD_JUMP));
2281 WRITE_RPS1(cpu_to_le32(dev->d_rps1.dma_handle));
2282
2283#if RPS_IRQ
2284 /* set event counter 1 source as RPS1 interrupt (0x03) (rE4 p53)
2285 * use 0x03 to track RPS1 interrupts - increase by 1 every gpio3 is toggled
2286 * use 0x15 to track VPE interrupts - increase by 1 every vpeirq() is called
2287 */
2288 saa7146_write(dev, EC1SSR, (0x03<<2) | 3 );
2289 /* set event counter 1 treshold to maximum allowed value (rEC p55) */
2290 saa7146_write(dev, ECT1R, 0x3fff );
2291#endif
2292 /* Set RPS1 Address register to point to RPS code (r108 p42) */
2293 saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle);
2294 /* Enable RPS1, (rFC p33) */
2295 saa7146_write(dev, MC1, (MASK_13 | MASK_29 ));
2296
2297 mdelay(10);
2298 /* now send VSYNC_B to rps1 by rising GPIO3 */
2299 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI);
2300 mdelay(10);
2301 /* if rps1 responded by lowering the GPIO3,
2302 * then we have budgetpatch hardware
2303 */
2304 if ((saa7146_read(dev, GPIO_CTRL) & 0x10000000) == 0) {
2305 budgetpatch = 1;
2306 printk("dvb-ttpci: BUDGET-PATCH DETECTED.\n");
2307 }
2308 /* Disable RPS1 */
2309 saa7146_write(dev, MC1, ( MASK_29 ));
2310#if RPS_IRQ
2311 printk("dvb-ttpci: Event Counter 1 0x%04x\n", saa7146_read(dev, EC1R) & 0x3fff );
2312#endif
2313 }
2314
2315 /* prepare the av7110 device struct */
2316 av7110 = kmalloc(sizeof(struct av7110), GFP_KERNEL);
2317 if (!av7110) {
2318 dprintk(1, "out of memory\n");
2319 return -ENOMEM;
2320 }
2321
2322 memset(av7110, 0, sizeof(struct av7110));
2323
2324 av7110->card_name = (char*) pci_ext->ext_priv;
2325 av7110->dev = dev;
2326 dev->ext_priv = av7110;
2327
2328 ret = get_firmware(av7110);
2329 if (ret < 0)
2330 goto err_kfree_0;
2331
2332 ret = dvb_register_adapter(&av7110->dvb_adapter, av7110->card_name,
2333 THIS_MODULE);
2334 if (ret < 0)
2335 goto err_put_firmware_1;
2336
2337 /* the Siemens DVB needs this if you want to have the i2c chips
2338 get recognized before the main driver is fully loaded */
2339 saa7146_write(dev, GPIO_CTRL, 0x500000);
2340
2341#ifdef I2C_ADAP_CLASS_TV_DIGITAL
2342 av7110->i2c_adap.class = I2C_ADAP_CLASS_TV_DIGITAL;
2343#else
2344 av7110->i2c_adap.class = I2C_CLASS_TV_DIGITAL;
2345#endif
2346 strlcpy(av7110->i2c_adap.name, pci_ext->ext_priv, sizeof(av7110->i2c_adap.name));
2347
2348 saa7146_i2c_adapter_prepare(dev, &av7110->i2c_adap, SAA7146_I2C_BUS_BIT_RATE_120); /* 275 kHz */
2349
2350 ret = i2c_add_adapter(&av7110->i2c_adap);
2351 if (ret < 0)
2352 goto err_dvb_unregister_adapter_2;
2353
2354 ttpci_eeprom_parse_mac(&av7110->i2c_adap,
2355 av7110->dvb_adapter->proposed_mac);
2356 ret = -ENOMEM;
2357
2358 if (budgetpatch) {
2359 spin_lock_init(&av7110->feedlock1);
2360 av7110->grabbing = saa7146_vmalloc_build_pgtable(pdev, length,
2361 &av7110->pt);
2362 if (!av7110->grabbing)
2363 goto err_i2c_del_3;
2364
2365 saa7146_write(dev, PCI_BT_V1, 0x1c1f101f);
2366 saa7146_write(dev, BCS_CTRL, 0x80400040);
2367 /* set dd1 stream a & b */
2368 saa7146_write(dev, DD1_STREAM_B, 0x00000000);
2369 saa7146_write(dev, DD1_INIT, 0x03000200);
2370 saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
2371 saa7146_write(dev, BRS_CTRL, 0x60000000);
2372 saa7146_write(dev, BASE_ODD3, 0);
2373 saa7146_write(dev, BASE_EVEN3, 0);
2374 saa7146_write(dev, PROT_ADDR3, TS_WIDTH * TS_HEIGHT);
2375 saa7146_write(dev, BASE_PAGE3, av7110->pt.dma | ME1 | 0x90);
2376
2377 saa7146_write(dev, PITCH3, TS_WIDTH);
2378 saa7146_write(dev, NUM_LINE_BYTE3, (TS_HEIGHT << 16) | TS_WIDTH);
2379
2380 /* upload all */
2381 saa7146_write(dev, MC2, 0x077c077c);
2382 saa7146_write(dev, GPIO_CTRL, 0x000000);
2383#if RPS_IRQ
2384 /* set event counter 1 source as RPS1 interrupt (0x03) (rE4 p53)
2385 * use 0x03 to track RPS1 interrupts - increase by 1 every gpio3 is toggled
2386 * use 0x15 to track VPE interrupts - increase by 1 every vpeirq() is called
2387 */
2388 saa7146_write(dev, EC1SSR, (0x03<<2) | 3 );
2389 /* set event counter 1 treshold to maximum allowed value (rEC p55) */
2390 saa7146_write(dev, ECT1R, 0x3fff );
2391#endif
2392 /* Setup BUDGETPATCH MAIN RPS1 "program" (p35) */
2393 count = 0;
2394
2395 /* Wait Source Line Counter Threshold (p36) */
2396 WRITE_RPS1(cpu_to_le32(CMD_PAUSE | EVT_HS));
2397 /* Set GPIO3=1 (p42) */
2398 WRITE_RPS1(cpu_to_le32(CMD_WR_REG_MASK | (GPIO_CTRL>>2)));
2399 WRITE_RPS1(cpu_to_le32(GPIO3_MSK));
2400 WRITE_RPS1(cpu_to_le32(SAA7146_GPIO_OUTHI<<24));
2401#if RPS_IRQ
2402 /* issue RPS1 interrupt */
2403 WRITE_RPS1(cpu_to_le32(CMD_INTERRUPT));
2404#endif
2405 /* Wait reset Source Line Counter Threshold (p36) */
2406 WRITE_RPS1(cpu_to_le32(CMD_PAUSE | RPS_INV | EVT_HS));
2407 /* Set GPIO3=0 (p42) */
2408 WRITE_RPS1(cpu_to_le32(CMD_WR_REG_MASK | (GPIO_CTRL>>2)));
2409 WRITE_RPS1(cpu_to_le32(GPIO3_MSK));
2410 WRITE_RPS1(cpu_to_le32(SAA7146_GPIO_OUTLO<<24));
2411#if RPS_IRQ
2412 /* issue RPS1 interrupt */
2413 WRITE_RPS1(cpu_to_le32(CMD_INTERRUPT));
2414#endif
2415 /* Jump to begin of RPS program (p37) */
2416 WRITE_RPS1(cpu_to_le32(CMD_JUMP));
2417 WRITE_RPS1(cpu_to_le32(dev->d_rps1.dma_handle));
2418
2419 /* Fix VSYNC level */
2420 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
2421 /* Set RPS1 Address register to point to RPS code (r108 p42) */
2422 saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle);
2423 /* Set Source Line Counter Threshold, using BRS (rCC p43)
2424 * It generates HS event every TS_HEIGHT lines
2425 * this is related to TS_WIDTH set in register
2426 * NUM_LINE_BYTE3. If NUM_LINE_BYTE low 16 bits
2427 * are set to TS_WIDTH bytes (TS_WIDTH=2*188),
2428 * then RPS_THRESH1 should be set to trigger
2429 * every TS_HEIGHT (512) lines.
2430 */
2431 saa7146_write(dev, RPS_THRESH1, (TS_HEIGHT*1) | MASK_12 );
2432
2433 /* Enable RPS1 (rFC p33) */
2434 saa7146_write(dev, MC1, (MASK_13 | MASK_29));
2435
2436 /* end of budgetpatch register initialization */
2437 tasklet_init (&av7110->vpe_tasklet, vpeirq, (unsigned long) av7110);
2438 } else {
2439 saa7146_write(dev, PCI_BT_V1, 0x1c00101f);
2440 saa7146_write(dev, BCS_CTRL, 0x80400040);
2441
2442 /* set dd1 stream a & b */
2443 saa7146_write(dev, DD1_STREAM_B, 0x00000000);
2444 saa7146_write(dev, DD1_INIT, 0x03000000);
2445 saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
2446
2447 /* upload all */
2448 saa7146_write(dev, MC2, 0x077c077c);
2449 saa7146_write(dev, GPIO_CTRL, 0x000000);
2450 }
2451
2452 tasklet_init (&av7110->debi_tasklet, debiirq, (unsigned long) av7110);
2453 tasklet_init (&av7110->gpio_tasklet, gpioirq, (unsigned long) av7110);
2454
2455 sema_init(&av7110->pid_mutex, 1);
2456
2457 /* locks for data transfers from/to AV7110 */
2458 spin_lock_init(&av7110->debilock);
2459 sema_init(&av7110->dcomlock, 1);
2460 av7110->debitype = -1;
2461
2462 /* default OSD window */
2463 av7110->osdwin = 1;
2464 sema_init(&av7110->osd_sema, 1);
2465
2466 /* ARM "watchdog" */
2467 init_waitqueue_head(&av7110->arm_wait);
2468 av7110->arm_thread = NULL;
2469
2470 /* allocate and init buffers */
2471 av7110->debi_virt = pci_alloc_consistent(pdev, 8192, &av7110->debi_bus);
2472 if (!av7110->debi_virt)
2473 goto err_saa71466_vfree_4;
2474
2475
2476 av7110->iobuf = vmalloc(AVOUTLEN+AOUTLEN+BMPLEN+4*IPACKS);
2477 if (!av7110->iobuf)
2478 goto err_pci_free_5;
2479
2480 ret = av7110_av_init(av7110);
2481 if (ret < 0)
2482 goto err_iobuf_vfree_6;
2483
2484 /* init BMP buffer */
2485 av7110->bmpbuf = av7110->iobuf+AVOUTLEN+AOUTLEN;
2486 init_waitqueue_head(&av7110->bmpq);
2487
2488 ret = av7110_ca_init(av7110);
2489 if (ret < 0)
2490 goto err_av7110_av_exit_7;
2491
2492 /* load firmware into AV7110 cards */
2493 ret = av7110_bootarm(av7110);
2494 if (ret < 0)
2495 goto err_av7110_ca_exit_8;
2496
2497 ret = av7110_firmversion(av7110);
2498 if (ret < 0)
2499 goto err_stop_arm_9;
2500
2501 if (FW_VERSION(av7110->arm_app)<0x2501)
2502 printk ("dvb-ttpci: Warning, firmware version 0x%04x is too old. "
2503 "System might be unstable!\n", FW_VERSION(av7110->arm_app));
2504
2505 ret = kernel_thread(arm_thread, (void *) av7110, 0);
2506 if (ret < 0)
2507 goto err_stop_arm_9;
2508
2509 /* set initial volume in mixer struct */
2510 av7110->mixer.volume_left = volume;
2511 av7110->mixer.volume_right = volume;
2512
2513 init_av7110_av(av7110);
2514
2515 ret = av7110_register(av7110);
2516 if (ret < 0)
2517 goto err_arm_thread_stop_10;
2518
2519 /* special case DVB-C: these cards have an analog tuner
2520 plus need some special handling, so we have separate
2521 saa7146_ext_vv data for these... */
2522 ret = av7110_init_v4l(av7110);
2523 if (ret < 0)
2524 goto err_av7110_unregister_11;
2525
2526 av7110->dvb_adapter->priv = av7110;
2527 ret = frontend_init(av7110);
2528 if (ret < 0)
2529 goto err_av7110_exit_v4l_12;
2530
2531#if defined(CONFIG_INPUT_EVDEV) || defined(CONFIG_INPUT_EVDEV_MODULE)
2532 av7110_ir_init();
2533#endif
2534 printk(KERN_INFO "dvb-ttpci: found av7110-%d.\n", av7110_num);
2535 av7110_num++;
2536out:
2537 return ret;
2538
2539err_av7110_exit_v4l_12:
2540 av7110_exit_v4l(av7110);
2541err_av7110_unregister_11:
2542 dvb_unregister(av7110);
2543err_arm_thread_stop_10:
2544 av7110_arm_sync(av7110);
2545err_stop_arm_9:
2546 /* Nothing to do. Rejoice. */
2547err_av7110_ca_exit_8:
2548 av7110_ca_exit(av7110);
2549err_av7110_av_exit_7:
2550 av7110_av_exit(av7110);
2551err_iobuf_vfree_6:
2552 vfree(av7110->iobuf);
2553err_pci_free_5:
2554 pci_free_consistent(pdev, 8192, av7110->debi_virt, av7110->debi_bus);
2555err_saa71466_vfree_4:
2556 if (!av7110->grabbing)
2557 saa7146_pgtable_free(pdev, &av7110->pt);
2558err_i2c_del_3:
2559 i2c_del_adapter(&av7110->i2c_adap);
2560err_dvb_unregister_adapter_2:
2561 dvb_unregister_adapter(av7110->dvb_adapter);
2562err_put_firmware_1:
2563 put_firmware(av7110);
2564err_kfree_0:
2565 kfree(av7110);
2566 goto out;
2567}
2568
2569static int av7110_detach(struct saa7146_dev* saa)
2570{
2571 struct av7110 *av7110 = saa->ext_priv;
2572 dprintk(4, "%p\n", av7110);
2573
2574 if (budgetpatch) {
2575 /* Disable RPS1 */
2576 saa7146_write(saa, MC1, MASK_29);
2577 /* VSYNC LOW (inactive) */
2578 saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO);
2579 saa7146_write(saa, MC1, MASK_20); /* DMA3 off */
2580 SAA7146_IER_DISABLE(saa, MASK_10);
2581 SAA7146_ISR_CLEAR(saa, MASK_10);
2582 msleep(50);
2583 tasklet_kill(&av7110->vpe_tasklet);
2584 saa7146_pgtable_free(saa->pci, &av7110->pt);
2585 }
2586 av7110_exit_v4l(av7110);
2587
2588 av7110_arm_sync(av7110);
2589
2590 tasklet_kill(&av7110->debi_tasklet);
2591 tasklet_kill(&av7110->gpio_tasklet);
2592
2593 dvb_unregister(av7110);
2594
2595 SAA7146_IER_DISABLE(saa, MASK_19 | MASK_03);
2596 SAA7146_ISR_CLEAR(saa, MASK_19 | MASK_03);
2597
2598 av7110_ca_exit(av7110);
2599 av7110_av_exit(av7110);
2600
2601 vfree(av7110->iobuf);
2602 pci_free_consistent(saa->pci, 8192, av7110->debi_virt,
2603 av7110->debi_bus);
2604
2605 i2c_del_adapter(&av7110->i2c_adap);
2606
2607 dvb_unregister_adapter (av7110->dvb_adapter);
2608
2609 av7110_num--;
2610
2611 put_firmware(av7110);
2612
2613 kfree(av7110);
2614
2615 saa->ext_priv = NULL;
2616
2617 return 0;
2618}
2619
2620
2621static void av7110_irq(struct saa7146_dev* dev, u32 *isr)
2622{
2623 struct av7110 *av7110 = dev->ext_priv;
2624
2625 //print_time("av7110_irq");
2626
2627 /* Note: Don't try to handle the DEBI error irq (MASK_18), in
2628 * intel mode the timeout is asserted all the time...
2629 */
2630
2631 if (*isr & MASK_19) {
2632 //printk("av7110_irq: DEBI\n");
2633 /* Note 1: The DEBI irq is level triggered: We must enable it
2634 * only after we started a DMA xfer, and disable it here
2635 * immediately, or it will be signalled all the time while
2636 * DEBI is idle.
2637 * Note 2: You would think that an irq which is masked is
2638 * not signalled by the hardware. Not so for the SAA7146:
2639 * An irq is signalled as long as the corresponding bit
2640 * in the ISR is set, and disabling irqs just prevents the
2641 * hardware from setting the ISR bit. This means a) that we
2642 * must clear the ISR *after* disabling the irq (which is why
2643 * we must do it here even though saa7146_core did it already),
2644 * and b) that if we were to disable an edge triggered irq
2645 * (like the gpio irqs sadly are) temporarily we would likely
2646 * loose some. This sucks :-(
2647 */
2648 SAA7146_IER_DISABLE(av7110->dev, MASK_19);
2649 SAA7146_ISR_CLEAR(av7110->dev, MASK_19);
2650 tasklet_schedule(&av7110->debi_tasklet);
2651 }
2652
2653 if (*isr & MASK_03) {
2654 //printk("av7110_irq: GPIO\n");
2655 tasklet_schedule(&av7110->gpio_tasklet);
2656 }
2657
2658 if ((*isr & MASK_10) && budgetpatch)
2659 tasklet_schedule(&av7110->vpe_tasklet);
2660}
2661
2662
2663static struct saa7146_extension av7110_extension;
2664
2665#define MAKE_AV7110_INFO(x_var,x_name) \
2666static struct saa7146_pci_extension_data x_var = { \
2667 .ext_priv = x_name, \
2668 .ext = &av7110_extension }
2669
2670MAKE_AV7110_INFO(tts_1_X, "Technotrend/Hauppauge WinTV DVB-S rev1.X");
2671MAKE_AV7110_INFO(ttt_1_X, "Technotrend/Hauppauge WinTV DVB-T rev1.X");
2672MAKE_AV7110_INFO(ttc_1_X, "Technotrend/Hauppauge WinTV Nexus-CA rev1.X");
2673MAKE_AV7110_INFO(ttc_2_X, "Technotrend/Hauppauge WinTV DVB-C rev2.X");
2674MAKE_AV7110_INFO(tts_2_X, "Technotrend/Hauppauge WinTV Nexus-S rev2.X");
2675MAKE_AV7110_INFO(tts_1_3se, "Technotrend/Hauppauge WinTV DVB-S rev1.3 SE");
2676MAKE_AV7110_INFO(ttt, "Technotrend/Hauppauge DVB-T");
2677MAKE_AV7110_INFO(fsc, "Fujitsu Siemens DVB-C");
2678MAKE_AV7110_INFO(fss, "Fujitsu Siemens DVB-S rev1.6");
2679
2680static struct pci_device_id pci_tbl[] = {
2681 MAKE_EXTENSION_PCI(tts_1_X, 0x13c2, 0x0000),
2682 MAKE_EXTENSION_PCI(ttt_1_X, 0x13c2, 0x0001),
2683 MAKE_EXTENSION_PCI(ttc_2_X, 0x13c2, 0x0002),
2684 MAKE_EXTENSION_PCI(tts_2_X, 0x13c2, 0x0003),
2685 MAKE_EXTENSION_PCI(tts_1_3se, 0x13c2, 0x1002),
2686 MAKE_EXTENSION_PCI(fsc, 0x110a, 0x0000),
2687 MAKE_EXTENSION_PCI(ttc_1_X, 0x13c2, 0x000a),
2688 MAKE_EXTENSION_PCI(fss, 0x13c2, 0x0006),
2689 MAKE_EXTENSION_PCI(ttt, 0x13c2, 0x0008),
2690
2691/* MAKE_EXTENSION_PCI(???, 0x13c2, 0x0004), UNDEFINED CARD */ // Galaxis DVB PC-Sat-Carte
2692/* MAKE_EXTENSION_PCI(???, 0x13c2, 0x0005), UNDEFINED CARD */ // Technisat SkyStar1
2693/* MAKE_EXTENSION_PCI(???, 0x13c2, 0x0009), UNDEFINED CARD */ // TT/Hauppauge WinTV Nexus-CA v????
2694
2695 {
2696 .vendor = 0,
2697 }
2698};
2699
2700MODULE_DEVICE_TABLE(pci, pci_tbl);
2701
2702
2703static struct saa7146_extension av7110_extension = {
2704 .name = "dvb\0",
2705 .flags = SAA7146_I2C_SHORT_DELAY,
2706
2707 .module = THIS_MODULE,
2708 .pci_tbl = &pci_tbl[0],
2709 .attach = av7110_attach,
2710 .detach = av7110_detach,
2711
2712 .irq_mask = MASK_19 | MASK_03 | MASK_10,
2713 .irq_func = av7110_irq,
2714};
2715
2716
2717static int __init av7110_init(void)
2718{
2719 int retval;
2720 retval = saa7146_register_extension(&av7110_extension);
2721 return retval;
2722}
2723
2724
2725static void __exit av7110_exit(void)
2726{
2727#if defined(CONFIG_INPUT_EVDEV) || defined(CONFIG_INPUT_EVDEV_MODULE)
2728 av7110_ir_exit();
2729#endif
2730 saa7146_unregister_extension(&av7110_extension);
2731}
2732
2733module_init(av7110_init);
2734module_exit(av7110_exit);
2735
2736MODULE_DESCRIPTION("driver for the SAA7146 based AV110 PCI DVB cards by "
2737 "Siemens, Technotrend, Hauppauge");
2738MODULE_AUTHOR("Ralph Metzler, Marcus Metzler, others");
2739MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/ttpci/av7110.h b/drivers/media/dvb/ttpci/av7110.h
new file mode 100644
index 000000000000..5070e0523da7
--- /dev/null
+++ b/drivers/media/dvb/ttpci/av7110.h
@@ -0,0 +1,284 @@
1#ifndef _AV7110_H_
2#define _AV7110_H_
3
4#include <linux/interrupt.h>
5#include <linux/socket.h>
6#include <linux/netdevice.h>
7#include <linux/i2c.h>
8
9#ifdef CONFIG_DEVFS_FS
10#include <linux/devfs_fs_kernel.h>
11#endif
12
13#include <linux/dvb/video.h>
14#include <linux/dvb/audio.h>
15#include <linux/dvb/dmx.h>
16#include <linux/dvb/ca.h>
17#include <linux/dvb/osd.h>
18#include <linux/dvb/net.h>
19
20#include "dvbdev.h"
21#include "demux.h"
22#include "dvb_demux.h"
23#include "dmxdev.h"
24#include "dvb_filter.h"
25#include "dvb_net.h"
26#include "dvb_ringbuffer.h"
27#include "dvb_frontend.h"
28#include "ves1820.h"
29#include "ves1x93.h"
30#include "stv0299.h"
31#include "tda8083.h"
32#include "sp8870.h"
33#include "stv0297.h"
34#include "l64781.h"
35
36#include <media/saa7146_vv.h>
37
38
39#define ANALOG_TUNER_VES1820 1
40#define ANALOG_TUNER_STV0297 2
41#define ANALOG_TUNER_VBI 0x100
42
43extern int av7110_debug;
44
45#define dprintk(level,args...) \
46 do { if ((av7110_debug & level)) { printk("dvb-ttpci: %s(): ", __FUNCTION__); printk(args); } } while (0)
47
48#define MAXFILT 32
49
50enum {AV_PES_STREAM, PS_STREAM, TS_STREAM, PES_STREAM};
51
52struct av7110_p2t {
53 u8 pes[TS_SIZE];
54 u8 counter;
55 long int pos;
56 int frags;
57 struct dvb_demux_feed *feed;
58};
59
60/* video MPEG decoder events: */
61/* (code copied from dvb_frontend.c, should maybe be factored out...) */
62#define MAX_VIDEO_EVENT 8
63struct dvb_video_events {
64 struct video_event events[MAX_VIDEO_EVENT];
65 int eventw;
66 int eventr;
67 int overflow;
68 wait_queue_head_t wait_queue;
69 spinlock_t lock;
70};
71
72
73/* place to store all the necessary device information */
74struct av7110 {
75
76 /* devices */
77
78 struct dvb_device dvb_dev;
79 struct dvb_net dvb_net;
80
81 struct video_device *v4l_dev;
82 struct video_device *vbi_dev;
83
84 struct saa7146_dev *dev;
85
86 struct i2c_adapter i2c_adap;
87
88 char *card_name;
89
90 /* support for analog module of dvb-c */
91 int analog_tuner_flags;
92 int current_input;
93 u32 current_freq;
94
95 struct tasklet_struct debi_tasklet;
96 struct tasklet_struct gpio_tasklet;
97
98 int adac_type; /* audio DAC type */
99#define DVB_ADAC_TI 0
100#define DVB_ADAC_CRYSTAL 1
101#define DVB_ADAC_MSP 2
102#define DVB_ADAC_NONE -1
103
104
105 /* buffers */
106
107 void *iobuf; /* memory for all buffers */
108 struct dvb_ringbuffer avout; /* buffer for video or A/V mux */
109#define AVOUTLEN (128*1024)
110 struct dvb_ringbuffer aout; /* buffer for audio */
111#define AOUTLEN (64*1024)
112 void *bmpbuf;
113#define BMPLEN (8*32768+1024)
114
115 /* bitmap buffers and states */
116
117 int bmpp;
118 int bmplen;
119 volatile int bmp_state;
120#define BMP_NONE 0
121#define BMP_LOADING 1
122#define BMP_LOADINGS 2
123#define BMP_LOADED 3
124 wait_queue_head_t bmpq;
125
126
127 /* DEBI and polled command interface */
128
129 spinlock_t debilock;
130 struct semaphore dcomlock;
131 volatile int debitype;
132 volatile int debilen;
133
134
135 /* Recording and playback flags */
136
137 int rec_mode;
138 int playing;
139#define RP_NONE 0
140#define RP_VIDEO 1
141#define RP_AUDIO 2
142#define RP_AV 3
143
144
145 /* OSD */
146
147 int osdwin; /* currently active window */
148 u16 osdbpp[8];
149 struct semaphore osd_sema;
150
151 /* CA */
152
153 ca_slot_info_t ci_slot[2];
154
155 int vidmode;
156 struct dmxdev dmxdev;
157 struct dvb_demux demux;
158
159 struct dmx_frontend hw_frontend;
160 struct dmx_frontend mem_frontend;
161
162 /* for budget mode demux1 */
163 struct dmxdev dmxdev1;
164 struct dvb_demux demux1;
165 struct dvb_net dvb_net1;
166 spinlock_t feedlock1;
167 int feeding1;
168 u8 tsf;
169 u32 ttbp;
170 unsigned char *grabbing;
171 struct saa7146_pgtable pt;
172 struct tasklet_struct vpe_tasklet;
173
174 int fe_synced;
175 struct semaphore pid_mutex;
176
177 int video_blank;
178 struct video_status videostate;
179 int display_ar;
180 int trickmode;
181#define TRICK_NONE 0
182#define TRICK_FAST 1
183#define TRICK_SLOW 2
184#define TRICK_FREEZE 3
185 struct audio_status audiostate;
186
187 struct dvb_demux_filter *handle2filter[32];
188 struct av7110_p2t p2t_filter[MAXFILT];
189 struct dvb_filter_pes2ts p2t[2];
190 struct ipack ipack[2];
191 u8 *kbuf[2];
192
193 int sinfo;
194 int feeding;
195
196 int arm_errors;
197 int registered;
198
199
200 /* AV711X */
201
202 u32 arm_fw;
203 u32 arm_rtsl;
204 u32 arm_vid;
205 u32 arm_app;
206 u32 avtype;
207 int arm_ready;
208 struct task_struct *arm_thread;
209 wait_queue_head_t arm_wait;
210 u16 arm_loops;
211 int arm_rmmod;
212
213 void *debi_virt;
214 dma_addr_t debi_bus;
215
216 u16 pids[DMX_PES_OTHER];
217
218 struct dvb_ringbuffer ci_rbuffer;
219 struct dvb_ringbuffer ci_wbuffer;
220
221 struct audio_mixer mixer;
222
223 struct dvb_adapter *dvb_adapter;
224 struct dvb_device *video_dev;
225 struct dvb_device *audio_dev;
226 struct dvb_device *ca_dev;
227 struct dvb_device *osd_dev;
228
229 struct dvb_video_events video_events;
230 video_size_t video_size;
231
232 u32 ir_config;
233
234 /* firmware stuff */
235 unsigned char *bin_fw;
236 unsigned long size_fw;
237
238 unsigned char *bin_dpram;
239 unsigned long size_dpram;
240
241 unsigned char *bin_root;
242 unsigned long size_root;
243
244 struct dvb_frontend* fe;
245 fe_status_t fe_status;
246 int (*fe_init)(struct dvb_frontend* fe);
247 int (*fe_read_status)(struct dvb_frontend* fe, fe_status_t* status);
248 int (*fe_diseqc_reset_overload)(struct dvb_frontend* fe);
249 int (*fe_diseqc_send_master_cmd)(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd);
250 int (*fe_diseqc_send_burst)(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd);
251 int (*fe_set_tone)(struct dvb_frontend* fe, fe_sec_tone_mode_t tone);
252 int (*fe_set_voltage)(struct dvb_frontend* fe, fe_sec_voltage_t voltage);
253 int (*fe_dishnetwork_send_legacy_command)(struct dvb_frontend* fe, unsigned int cmd);
254 int (*fe_set_frontend)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
255};
256
257
258extern void ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid,
259 u16 subpid, u16 pcrpid);
260
261extern void av7110_register_irc_handler(void (*func)(u32));
262extern void av7110_unregister_irc_handler(void (*func)(u32));
263extern void av7110_setup_irc_config (struct av7110 *av7110, u32 ir_config);
264
265extern int av7110_ir_init (void);
266extern void av7110_ir_exit (void);
267
268/* msp3400 i2c subaddresses */
269#define MSP_WR_DEM 0x10
270#define MSP_RD_DEM 0x11
271#define MSP_WR_DSP 0x12
272#define MSP_RD_DSP 0x13
273
274extern int i2c_writereg(struct av7110 *av7110, u8 id, u8 reg, u8 val);
275extern u8 i2c_readreg(struct av7110 *av7110, u8 id, u8 reg);
276extern int msp_writereg(struct av7110 *av7110, u8 dev, u16 reg, u16 val);
277extern int msp_readreg(struct av7110 *av7110, u8 dev, u16 reg, u16 *val);
278
279
280extern int av7110_init_analog_module(struct av7110 *av7110);
281extern int av7110_init_v4l(struct av7110 *av7110);
282extern int av7110_exit_v4l(struct av7110 *av7110);
283
284#endif /* _AV7110_H_ */
diff --git a/drivers/media/dvb/ttpci/av7110_av.c b/drivers/media/dvb/ttpci/av7110_av.c
new file mode 100644
index 000000000000..d77e8a00688f
--- /dev/null
+++ b/drivers/media/dvb/ttpci/av7110_av.c
@@ -0,0 +1,1459 @@
1/*
2 * av7110_av.c: audio and video MPEG decoder stuff
3 *
4 * Copyright (C) 1999-2002 Ralph Metzler
5 * & Marcus Metzler for convergence integrated media GmbH
6 *
7 * originally based on code by:
8 * Copyright (C) 1998,1999 Christian Theiss <mistert@rz.fh-augsburg.de>
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
14 *
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
26 *
27 *
28 * the project's page is at http://www.linuxtv.org/dvb/
29 */
30
31#include <linux/types.h>
32#include <linux/kernel.h>
33#include <linux/string.h>
34#include <linux/sched.h>
35#include <linux/delay.h>
36#include <linux/byteorder/swabb.h>
37#include <linux/smp_lock.h>
38#include <linux/fs.h>
39
40#include "av7110.h"
41#include "av7110_hw.h"
42#include "av7110_av.h"
43#include "av7110_ipack.h"
44
45/* MPEG-2 (ISO 13818 / H.222.0) stream types */
46#define PROG_STREAM_MAP 0xBC
47#define PRIVATE_STREAM1 0xBD
48#define PADDING_STREAM 0xBE
49#define PRIVATE_STREAM2 0xBF
50#define AUDIO_STREAM_S 0xC0
51#define AUDIO_STREAM_E 0xDF
52#define VIDEO_STREAM_S 0xE0
53#define VIDEO_STREAM_E 0xEF
54#define ECM_STREAM 0xF0
55#define EMM_STREAM 0xF1
56#define DSM_CC_STREAM 0xF2
57#define ISO13522_STREAM 0xF3
58#define PROG_STREAM_DIR 0xFF
59
60#define PTS_DTS_FLAGS 0xC0
61
62//pts_dts flags
63#define PTS_ONLY 0x80
64#define PTS_DTS 0xC0
65#define TS_SIZE 188
66#define TRANS_ERROR 0x80
67#define PAY_START 0x40
68#define TRANS_PRIO 0x20
69#define PID_MASK_HI 0x1F
70//flags
71#define TRANS_SCRMBL1 0x80
72#define TRANS_SCRMBL2 0x40
73#define ADAPT_FIELD 0x20
74#define PAYLOAD 0x10
75#define COUNT_MASK 0x0F
76
77// adaptation flags
78#define DISCON_IND 0x80
79#define RAND_ACC_IND 0x40
80#define ES_PRI_IND 0x20
81#define PCR_FLAG 0x10
82#define OPCR_FLAG 0x08
83#define SPLICE_FLAG 0x04
84#define TRANS_PRIV 0x02
85#define ADAP_EXT_FLAG 0x01
86
87// adaptation extension flags
88#define LTW_FLAG 0x80
89#define PIECE_RATE 0x40
90#define SEAM_SPLICE 0x20
91
92
93static void p_to_t(u8 const *buf, long int length, u16 pid,
94 u8 *counter, struct dvb_demux_feed *feed);
95
96
97int av7110_record_cb(struct dvb_filter_pes2ts *p2t, u8 *buf, size_t len)
98{
99 struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *) p2t->priv;
100
101 if (!(dvbdmxfeed->ts_type & TS_PACKET))
102 return 0;
103 if (buf[3] == 0xe0) // video PES do not have a length in TS
104 buf[4] = buf[5] = 0;
105 if (dvbdmxfeed->ts_type & TS_PAYLOAD_ONLY)
106 return dvbdmxfeed->cb.ts(buf, len, NULL, 0,
107 &dvbdmxfeed->feed.ts, DMX_OK);
108 else
109 return dvb_filter_pes2ts(p2t, buf, len, 1);
110}
111
112static int dvb_filter_pes2ts_cb(void *priv, unsigned char *data)
113{
114 struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *) priv;
115
116 dvbdmxfeed->cb.ts(data, 188, NULL, 0,
117 &dvbdmxfeed->feed.ts, DMX_OK);
118 return 0;
119}
120
121int av7110_av_start_record(struct av7110 *av7110, int av,
122 struct dvb_demux_feed *dvbdmxfeed)
123{
124 struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
125
126 dprintk(2, "av7110:%p, , dvb_demux_feed:%p\n", av7110, dvbdmxfeed);
127
128 if (av7110->playing || (av7110->rec_mode & av))
129 return -EBUSY;
130 av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Stop, 0);
131 dvbdmx->recording = 1;
132 av7110->rec_mode |= av;
133
134 switch (av7110->rec_mode) {
135 case RP_AUDIO:
136 dvb_filter_pes2ts_init(&av7110->p2t[0],
137 dvbdmx->pesfilter[0]->pid,
138 dvb_filter_pes2ts_cb,
139 (void *) dvbdmx->pesfilter[0]);
140 av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, AudioPES, 0);
141 break;
142
143 case RP_VIDEO:
144 dvb_filter_pes2ts_init(&av7110->p2t[1],
145 dvbdmx->pesfilter[1]->pid,
146 dvb_filter_pes2ts_cb,
147 (void *) dvbdmx->pesfilter[1]);
148 av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, VideoPES, 0);
149 break;
150
151 case RP_AV:
152 dvb_filter_pes2ts_init(&av7110->p2t[0],
153 dvbdmx->pesfilter[0]->pid,
154 dvb_filter_pes2ts_cb,
155 (void *) dvbdmx->pesfilter[0]);
156 dvb_filter_pes2ts_init(&av7110->p2t[1],
157 dvbdmx->pesfilter[1]->pid,
158 dvb_filter_pes2ts_cb,
159 (void *) dvbdmx->pesfilter[1]);
160 av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, AV_PES, 0);
161 break;
162 }
163 return 0;
164}
165
166int av7110_av_start_play(struct av7110 *av7110, int av)
167{
168 dprintk(2, "av7110:%p, \n", av7110);
169
170 if (av7110->rec_mode)
171 return -EBUSY;
172 if (av7110->playing & av)
173 return -EBUSY;
174
175 av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Stop, 0);
176
177 if (av7110->playing == RP_NONE) {
178 av7110_ipack_reset(&av7110->ipack[0]);
179 av7110_ipack_reset(&av7110->ipack[1]);
180 }
181
182 av7110->playing |= av;
183 switch (av7110->playing) {
184 case RP_AUDIO:
185 av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, AudioPES, 0);
186 break;
187 case RP_VIDEO:
188 av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, VideoPES, 0);
189 av7110->sinfo = 0;
190 break;
191 case RP_AV:
192 av7110->sinfo = 0;
193 av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, AV_PES, 0);
194 break;
195 }
196 return av7110->playing;
197}
198
199void av7110_av_stop(struct av7110 *av7110, int av)
200{
201 dprintk(2, "av7110:%p, \n", av7110);
202
203 if (!(av7110->playing & av) && !(av7110->rec_mode & av))
204 return;
205
206 av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Stop, 0);
207 if (av7110->playing) {
208 av7110->playing &= ~av;
209 switch (av7110->playing) {
210 case RP_AUDIO:
211 av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, AudioPES, 0);
212 break;
213 case RP_VIDEO:
214 av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, VideoPES, 0);
215 break;
216 case RP_NONE:
217 av7110_set_vidmode(av7110, av7110->vidmode);
218 break;
219 }
220 } else {
221 av7110->rec_mode &= ~av;
222 switch (av7110->rec_mode) {
223 case RP_AUDIO:
224 av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, AudioPES, 0);
225 break;
226 case RP_VIDEO:
227 av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, VideoPES, 0);
228 break;
229 case RP_NONE:
230 break;
231 }
232 }
233}
234
235
236int av7110_pes_play(void *dest, struct dvb_ringbuffer *buf, int dlen)
237{
238 int len;
239 u32 sync;
240 u16 blen;
241
242 if (!dlen) {
243 wake_up(&buf->queue);
244 return -1;
245 }
246 while (1) {
247 if ((len = dvb_ringbuffer_avail(buf)) < 6)
248 return -1;
249 sync = DVB_RINGBUFFER_PEEK(buf, 0) << 24;
250 sync |= DVB_RINGBUFFER_PEEK(buf, 1) << 16;
251 sync |= DVB_RINGBUFFER_PEEK(buf, 2) << 8;
252 sync |= DVB_RINGBUFFER_PEEK(buf, 3);
253
254 if (((sync &~ 0x0f) == 0x000001e0) ||
255 ((sync &~ 0x1f) == 0x000001c0) ||
256 (sync == 0x000001bd))
257 break;
258 printk("resync\n");
259 DVB_RINGBUFFER_SKIP(buf, 1);
260 }
261 blen = DVB_RINGBUFFER_PEEK(buf, 4) << 8;
262 blen |= DVB_RINGBUFFER_PEEK(buf, 5);
263 blen += 6;
264 if (len < blen || blen > dlen) {
265 //printk("buffer empty - avail %d blen %u dlen %d\n", len, blen, dlen);
266 wake_up(&buf->queue);
267 return -1;
268 }
269
270 dvb_ringbuffer_read(buf, dest, (size_t) blen, 0);
271
272 dprintk(2, "pread=0x%08lx, pwrite=0x%08lx\n",
273 (unsigned long) buf->pread, (unsigned long) buf->pwrite);
274 wake_up(&buf->queue);
275 return blen;
276}
277
278
279int av7110_set_volume(struct av7110 *av7110, int volleft, int volright)
280{
281 int err, vol, val, balance = 0;
282
283 dprintk(2, "av7110:%p, \n", av7110);
284
285 av7110->mixer.volume_left = volleft;
286 av7110->mixer.volume_right = volright;
287
288 switch (av7110->adac_type) {
289 case DVB_ADAC_TI:
290 volleft = (volleft * 256) / 1036;
291 volright = (volright * 256) / 1036;
292 if (volleft > 0x3f)
293 volleft = 0x3f;
294 if (volright > 0x3f)
295 volright = 0x3f;
296 if ((err = SendDAC(av7110, 3, 0x80 + volleft)))
297 return err;
298 return SendDAC(av7110, 4, volright);
299
300 case DVB_ADAC_CRYSTAL:
301 volleft = 127 - volleft / 2;
302 volright = 127 - volright / 2;
303 i2c_writereg(av7110, 0x20, 0x03, volleft);
304 i2c_writereg(av7110, 0x20, 0x04, volright);
305 return 0;
306
307 case DVB_ADAC_MSP:
308 vol = (volleft > volright) ? volleft : volright;
309 val = (vol * 0x73 / 255) << 8;
310 if (vol > 0)
311 balance = ((volright - volleft) * 127) / vol;
312 msp_writereg(av7110, MSP_WR_DSP, 0x0001, balance << 8);
313 msp_writereg(av7110, MSP_WR_DSP, 0x0000, val); /* loudspeaker */
314 msp_writereg(av7110, MSP_WR_DSP, 0x0006, val); /* headphonesr */
315 return 0;
316 }
317 return 0;
318}
319
320void av7110_set_vidmode(struct av7110 *av7110, int mode)
321{
322 dprintk(2, "av7110:%p, \n", av7110);
323
324 av7110_fw_cmd(av7110, COMTYPE_ENCODER, LoadVidCode, 1, mode);
325
326 if (!av7110->playing) {
327 ChangePIDs(av7110, av7110->pids[DMX_PES_VIDEO],
328 av7110->pids[DMX_PES_AUDIO],
329 av7110->pids[DMX_PES_TELETEXT],
330 0, av7110->pids[DMX_PES_PCR]);
331 av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, Scan, 0);
332 }
333}
334
335
336static int sw2mode[16] = {
337 VIDEO_MODE_PAL, VIDEO_MODE_NTSC, VIDEO_MODE_NTSC, VIDEO_MODE_PAL,
338 VIDEO_MODE_NTSC, VIDEO_MODE_NTSC, VIDEO_MODE_PAL, VIDEO_MODE_NTSC,
339 VIDEO_MODE_PAL, VIDEO_MODE_PAL, VIDEO_MODE_PAL, VIDEO_MODE_PAL,
340 VIDEO_MODE_PAL, VIDEO_MODE_PAL, VIDEO_MODE_PAL, VIDEO_MODE_PAL,
341};
342
343static void get_video_format(struct av7110 *av7110, u8 *buf, int count)
344{
345 int i;
346 int hsize, vsize;
347 int sw;
348 u8 *p;
349
350 dprintk(2, "av7110:%p, \n", av7110);
351
352 if (av7110->sinfo)
353 return;
354 for (i = 7; i < count - 10; i++) {
355 p = buf + i;
356 if (p[0] || p[1] || p[2] != 0x01 || p[3] != 0xb3)
357 continue;
358 p += 4;
359 hsize = ((p[1] &0xF0) >> 4) | (p[0] << 4);
360 vsize = ((p[1] &0x0F) << 8) | (p[2]);
361 sw = (p[3] & 0x0F);
362 av7110_set_vidmode(av7110, sw2mode[sw]);
363 dprintk(2, "playback %dx%d fr=%d\n", hsize, vsize, sw);
364 av7110->sinfo = 1;
365 break;
366 }
367}
368
369
370/****************************************************************************
371 * I/O buffer management and control
372 ****************************************************************************/
373
374static inline long aux_ring_buffer_write(struct dvb_ringbuffer *rbuf,
375 const char *buf, unsigned long count)
376{
377 unsigned long todo = count;
378 int free;
379
380 while (todo > 0) {
381 if (dvb_ringbuffer_free(rbuf) < 2048) {
382 if (wait_event_interruptible(rbuf->queue,
383 (dvb_ringbuffer_free(rbuf) >= 2048)))
384 return count - todo;
385 }
386 free = dvb_ringbuffer_free(rbuf);
387 if (free > todo)
388 free = todo;
389 dvb_ringbuffer_write(rbuf, buf, free);
390 todo -= free;
391 buf += free;
392 }
393
394 return count - todo;
395}
396
397static void play_video_cb(u8 *buf, int count, void *priv)
398{
399 struct av7110 *av7110 = (struct av7110 *) priv;
400 dprintk(2, "av7110:%p, \n", av7110);
401
402 if ((buf[3] & 0xe0) == 0xe0) {
403 get_video_format(av7110, buf, count);
404 aux_ring_buffer_write(&av7110->avout, buf, count);
405 } else
406 aux_ring_buffer_write(&av7110->aout, buf, count);
407}
408
409static void play_audio_cb(u8 *buf, int count, void *priv)
410{
411 struct av7110 *av7110 = (struct av7110 *) priv;
412 dprintk(2, "av7110:%p, \n", av7110);
413
414 aux_ring_buffer_write(&av7110->aout, buf, count);
415}
416
417#define FREE_COND (dvb_ringbuffer_free(&av7110->avout) >= 20 * 1024 && \
418 dvb_ringbuffer_free(&av7110->aout) >= 20 * 1024)
419
420static ssize_t dvb_play(struct av7110 *av7110, const u8 __user *buf,
421 unsigned long count, int nonblock, int type)
422{
423 unsigned long todo = count, n;
424 dprintk(2, "av7110:%p, \n", av7110);
425
426 if (!av7110->kbuf[type])
427 return -ENOBUFS;
428
429 if (nonblock && !FREE_COND)
430 return -EWOULDBLOCK;
431
432 while (todo > 0) {
433 if (!FREE_COND) {
434 if (nonblock)
435 return count - todo;
436 if (wait_event_interruptible(av7110->avout.queue,
437 FREE_COND))
438 return count - todo;
439 }
440 n = todo;
441 if (n > IPACKS * 2)
442 n = IPACKS * 2;
443 if (copy_from_user(av7110->kbuf[type], buf, n))
444 return -EFAULT;
445 av7110_ipack_instant_repack(av7110->kbuf[type], n,
446 &av7110->ipack[type]);
447 todo -= n;
448 buf += n;
449 }
450 return count - todo;
451}
452
453static ssize_t dvb_play_kernel(struct av7110 *av7110, const u8 *buf,
454 unsigned long count, int nonblock, int type)
455{
456 unsigned long todo = count, n;
457 dprintk(2, "av7110:%p, \n", av7110);
458
459 if (!av7110->kbuf[type])
460 return -ENOBUFS;
461
462 if (nonblock && !FREE_COND)
463 return -EWOULDBLOCK;
464
465 while (todo > 0) {
466 if (!FREE_COND) {
467 if (nonblock)
468 return count - todo;
469 if (wait_event_interruptible(av7110->avout.queue,
470 FREE_COND))
471 return count - todo;
472 }
473 n = todo;
474 if (n > IPACKS * 2)
475 n = IPACKS * 2;
476 av7110_ipack_instant_repack(buf, n, &av7110->ipack[type]);
477 todo -= n;
478 buf += n;
479 }
480 return count - todo;
481}
482
483static ssize_t dvb_aplay(struct av7110 *av7110, const u8 __user *buf,
484 unsigned long count, int nonblock, int type)
485{
486 unsigned long todo = count, n;
487 dprintk(2, "av7110:%p, \n", av7110);
488
489 if (!av7110->kbuf[type])
490 return -ENOBUFS;
491 if (nonblock && dvb_ringbuffer_free(&av7110->aout) < 20 * 1024)
492 return -EWOULDBLOCK;
493
494 while (todo > 0) {
495 if (dvb_ringbuffer_free(&av7110->aout) < 20 * 1024) {
496 if (nonblock)
497 return count - todo;
498 if (wait_event_interruptible(av7110->aout.queue,
499 (dvb_ringbuffer_free(&av7110->aout) >= 20 * 1024)))
500 return count-todo;
501 }
502 n = todo;
503 if (n > IPACKS * 2)
504 n = IPACKS * 2;
505 if (copy_from_user(av7110->kbuf[type], buf, n))
506 return -EFAULT;
507 av7110_ipack_instant_repack(av7110->kbuf[type], n,
508 &av7110->ipack[type]);
509 todo -= n;
510 buf += n;
511 }
512 return count - todo;
513}
514
515void av7110_p2t_init(struct av7110_p2t *p, struct dvb_demux_feed *feed)
516{
517 memset(p->pes, 0, TS_SIZE);
518 p->counter = 0;
519 p->pos = 0;
520 p->frags = 0;
521 if (feed)
522 p->feed = feed;
523}
524
525static void clear_p2t(struct av7110_p2t *p)
526{
527 memset(p->pes, 0, TS_SIZE);
528// p->counter = 0;
529 p->pos = 0;
530 p->frags = 0;
531}
532
533
534static int find_pes_header(u8 const *buf, long int length, int *frags)
535{
536 int c = 0;
537 int found = 0;
538
539 *frags = 0;
540
541 while (c < length - 3 && !found) {
542 if (buf[c] == 0x00 && buf[c + 1] == 0x00 &&
543 buf[c + 2] == 0x01) {
544 switch ( buf[c + 3] ) {
545 case PROG_STREAM_MAP:
546 case PRIVATE_STREAM2:
547 case PROG_STREAM_DIR:
548 case ECM_STREAM :
549 case EMM_STREAM :
550 case PADDING_STREAM :
551 case DSM_CC_STREAM :
552 case ISO13522_STREAM:
553 case PRIVATE_STREAM1:
554 case AUDIO_STREAM_S ... AUDIO_STREAM_E:
555 case VIDEO_STREAM_S ... VIDEO_STREAM_E:
556 found = 1;
557 break;
558
559 default:
560 c++;
561 break;
562 }
563 } else
564 c++;
565 }
566 if (c == length - 3 && !found) {
567 if (buf[length - 1] == 0x00)
568 *frags = 1;
569 if (buf[length - 2] == 0x00 &&
570 buf[length - 1] == 0x00)
571 *frags = 2;
572 if (buf[length - 3] == 0x00 &&
573 buf[length - 2] == 0x00 &&
574 buf[length - 1] == 0x01)
575 *frags = 3;
576 return -1;
577 }
578
579 return c;
580}
581
582void av7110_p2t_write(u8 const *buf, long int length, u16 pid, struct av7110_p2t *p)
583{
584 int c, c2, l, add;
585 int check, rest;
586
587 c = 0;
588 c2 = 0;
589 if (p->frags){
590 check = 0;
591 switch(p->frags) {
592 case 1:
593 if (buf[c] == 0x00 && buf[c + 1] == 0x01) {
594 check = 1;
595 c += 2;
596 }
597 break;
598 case 2:
599 if (buf[c] == 0x01) {
600 check = 1;
601 c++;
602 }
603 break;
604 case 3:
605 check = 1;
606 }
607 if (check) {
608 switch (buf[c]) {
609 case PROG_STREAM_MAP:
610 case PRIVATE_STREAM2:
611 case PROG_STREAM_DIR:
612 case ECM_STREAM :
613 case EMM_STREAM :
614 case PADDING_STREAM :
615 case DSM_CC_STREAM :
616 case ISO13522_STREAM:
617 case PRIVATE_STREAM1:
618 case AUDIO_STREAM_S ... AUDIO_STREAM_E:
619 case VIDEO_STREAM_S ... VIDEO_STREAM_E:
620 p->pes[0] = 0x00;
621 p->pes[1] = 0x00;
622 p->pes[2] = 0x01;
623 p->pes[3] = buf[c];
624 p->pos = 4;
625 memcpy(p->pes + p->pos, buf + c, (TS_SIZE - 4) - p->pos);
626 c += (TS_SIZE - 4) - p->pos;
627 p_to_t(p->pes, (TS_SIZE - 4), pid, &p->counter, p->feed);
628 clear_p2t(p);
629 break;
630
631 default:
632 c = 0;
633 break;
634 }
635 }
636 p->frags = 0;
637 }
638
639 if (p->pos) {
640 c2 = find_pes_header(buf + c, length - c, &p->frags);
641 if (c2 >= 0 && c2 < (TS_SIZE - 4) - p->pos)
642 l = c2+c;
643 else
644 l = (TS_SIZE - 4) - p->pos;
645 memcpy(p->pes + p->pos, buf, l);
646 c += l;
647 p->pos += l;
648 p_to_t(p->pes, p->pos, pid, &p->counter, p->feed);
649 clear_p2t(p);
650 }
651
652 add = 0;
653 while (c < length) {
654 c2 = find_pes_header(buf + c + add, length - c - add, &p->frags);
655 if (c2 >= 0) {
656 c2 += c + add;
657 if (c2 > c){
658 p_to_t(buf + c, c2 - c, pid, &p->counter, p->feed);
659 c = c2;
660 clear_p2t(p);
661 add = 0;
662 } else
663 add = 1;
664 } else {
665 l = length - c;
666 rest = l % (TS_SIZE - 4);
667 l -= rest;
668 p_to_t(buf + c, l, pid, &p->counter, p->feed);
669 memcpy(p->pes, buf + c + l, rest);
670 p->pos = rest;
671 c = length;
672 }
673 }
674}
675
676
677static int write_ts_header2(u16 pid, u8 *counter, int pes_start, u8 *buf, u8 length)
678{
679 int i;
680 int c = 0;
681 int fill;
682 u8 tshead[4] = { 0x47, 0x00, 0x00, 0x10 };
683
684 fill = (TS_SIZE - 4) - length;
685 if (pes_start)
686 tshead[1] = 0x40;
687 if (fill)
688 tshead[3] = 0x30;
689 tshead[1] |= (u8)((pid & 0x1F00) >> 8);
690 tshead[2] |= (u8)(pid & 0x00FF);
691 tshead[3] |= ((*counter)++ & 0x0F);
692 memcpy(buf, tshead, 4);
693 c += 4;
694
695 if (fill) {
696 buf[4] = fill - 1;
697 c++;
698 if (fill > 1) {
699 buf[5] = 0x00;
700 c++;
701 }
702 for (i = 6; i < fill + 4; i++) {
703 buf[i] = 0xFF;
704 c++;
705 }
706 }
707
708 return c;
709}
710
711
712static void p_to_t(u8 const *buf, long int length, u16 pid, u8 *counter,
713 struct dvb_demux_feed *feed)
714{
715 int l, pes_start;
716 u8 obuf[TS_SIZE];
717 long c = 0;
718
719 pes_start = 0;
720 if (length > 3 &&
721 buf[0] == 0x00 && buf[1] == 0x00 && buf[2] == 0x01)
722 switch (buf[3]) {
723 case PROG_STREAM_MAP:
724 case PRIVATE_STREAM2:
725 case PROG_STREAM_DIR:
726 case ECM_STREAM :
727 case EMM_STREAM :
728 case PADDING_STREAM :
729 case DSM_CC_STREAM :
730 case ISO13522_STREAM:
731 case PRIVATE_STREAM1:
732 case AUDIO_STREAM_S ... AUDIO_STREAM_E:
733 case VIDEO_STREAM_S ... VIDEO_STREAM_E:
734 pes_start = 1;
735 break;
736
737 default:
738 break;
739 }
740
741 while (c < length) {
742 memset(obuf, 0, TS_SIZE);
743 if (length - c >= (TS_SIZE - 4)){
744 l = write_ts_header2(pid, counter, pes_start,
745 obuf, (TS_SIZE - 4));
746 memcpy(obuf + l, buf + c, TS_SIZE - l);
747 c += TS_SIZE - l;
748 } else {
749 l = write_ts_header2(pid, counter, pes_start,
750 obuf, length - c);
751 memcpy(obuf + l, buf + c, TS_SIZE - l);
752 c = length;
753 }
754 feed->cb.ts(obuf, 188, NULL, 0, &feed->feed.ts, DMX_OK);
755 pes_start = 0;
756 }
757}
758
759
760int av7110_write_to_decoder(struct dvb_demux_feed *feed, const u8 *buf, size_t len)
761{
762 struct dvb_demux *demux = feed->demux;
763 struct av7110 *av7110 = (struct av7110 *) demux->priv;
764 struct ipack *ipack = &av7110->ipack[feed->pes_type];
765
766 dprintk(2, "av7110:%p, \n", av7110);
767
768 switch (feed->pes_type) {
769 case 0:
770 if (av7110->audiostate.stream_source == AUDIO_SOURCE_MEMORY)
771 return -EINVAL;
772 break;
773 case 1:
774 if (av7110->videostate.stream_source == VIDEO_SOURCE_MEMORY)
775 return -EINVAL;
776 break;
777 default:
778 return -1;
779 }
780
781 if (!(buf[3] & 0x10)) /* no payload? */
782 return -1;
783 if (buf[1] & 0x40)
784 av7110_ipack_flush(ipack);
785
786 if (buf[3] & 0x20) { /* adaptation field? */
787 len -= buf[4] + 1;
788 buf += buf[4] + 1;
789 if (!len)
790 return 0;
791 }
792
793 av7110_ipack_instant_repack(buf + 4, len - 4, &av7110->ipack[feed->pes_type]);
794 return 0;
795}
796
797
798
799/******************************************************************************
800 * Video MPEG decoder events
801 ******************************************************************************/
802void dvb_video_add_event(struct av7110 *av7110, struct video_event *event)
803{
804 struct dvb_video_events *events = &av7110->video_events;
805 int wp;
806
807 spin_lock_bh(&events->lock);
808
809 wp = (events->eventw + 1) % MAX_VIDEO_EVENT;
810 if (wp == events->eventr) {
811 events->overflow = 1;
812 events->eventr = (events->eventr + 1) % MAX_VIDEO_EVENT;
813 }
814
815 //FIXME: timestamp?
816 memcpy(&events->events[events->eventw], event, sizeof(struct video_event));
817 events->eventw = wp;
818
819 spin_unlock_bh(&events->lock);
820
821 wake_up_interruptible(&events->wait_queue);
822}
823
824
825static int dvb_video_get_event (struct av7110 *av7110, struct video_event *event, int flags)
826{
827 struct dvb_video_events *events = &av7110->video_events;
828
829 if (events->overflow) {
830 events->overflow = 0;
831 return -EOVERFLOW;
832 }
833 if (events->eventw == events->eventr) {
834 int ret;
835
836 if (flags & O_NONBLOCK)
837 return -EWOULDBLOCK;
838
839 ret = wait_event_interruptible(events->wait_queue,
840 events->eventw != events->eventr);
841 if (ret < 0)
842 return ret;
843 }
844
845 spin_lock_bh(&events->lock);
846
847 memcpy(event, &events->events[events->eventr],
848 sizeof(struct video_event));
849 events->eventr = (events->eventr + 1) % MAX_VIDEO_EVENT;
850
851 spin_unlock_bh(&events->lock);
852
853 return 0;
854}
855
856
857/******************************************************************************
858 * DVB device file operations
859 ******************************************************************************/
860
861static unsigned int dvb_video_poll(struct file *file, poll_table *wait)
862{
863 struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;
864 struct av7110 *av7110 = (struct av7110 *) dvbdev->priv;
865 unsigned int mask = 0;
866
867 dprintk(2, "av7110:%p, \n", av7110);
868
869 if ((file->f_flags & O_ACCMODE) != O_RDONLY)
870 poll_wait(file, &av7110->avout.queue, wait);
871
872 poll_wait(file, &av7110->video_events.wait_queue, wait);
873
874 if (av7110->video_events.eventw != av7110->video_events.eventr)
875 mask = POLLPRI;
876
877 if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
878 if (av7110->playing) {
879 if (FREE_COND)
880 mask |= (POLLOUT | POLLWRNORM);
881 } else /* if not playing: may play if asked for */
882 mask |= (POLLOUT | POLLWRNORM);
883 }
884
885 return mask;
886}
887
888static ssize_t dvb_video_write(struct file *file, const char __user *buf,
889 size_t count, loff_t *ppos)
890{
891 struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;
892 struct av7110 *av7110 = (struct av7110 *) dvbdev->priv;
893
894 dprintk(2, "av7110:%p, \n", av7110);
895
896 if ((file->f_flags & O_ACCMODE) == O_RDONLY)
897 return -EPERM;
898
899 if (av7110->videostate.stream_source != VIDEO_SOURCE_MEMORY)
900 return -EPERM;
901
902 return dvb_play(av7110, buf, count, file->f_flags & O_NONBLOCK, 1);
903}
904
905static unsigned int dvb_audio_poll(struct file *file, poll_table *wait)
906{
907 struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;
908 struct av7110 *av7110 = (struct av7110 *) dvbdev->priv;
909 unsigned int mask = 0;
910
911 dprintk(2, "av7110:%p, \n", av7110);
912
913 poll_wait(file, &av7110->aout.queue, wait);
914
915 if (av7110->playing) {
916 if (dvb_ringbuffer_free(&av7110->aout) >= 20 * 1024)
917 mask |= (POLLOUT | POLLWRNORM);
918 } else /* if not playing: may play if asked for */
919 mask = (POLLOUT | POLLWRNORM);
920
921 return mask;
922}
923
924static ssize_t dvb_audio_write(struct file *file, const char __user *buf,
925 size_t count, loff_t *ppos)
926{
927 struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;
928 struct av7110 *av7110 = (struct av7110 *) dvbdev->priv;
929
930 dprintk(2, "av7110:%p, \n", av7110);
931
932 if (av7110->audiostate.stream_source != AUDIO_SOURCE_MEMORY) {
933 printk(KERN_ERR "not audio source memory\n");
934 return -EPERM;
935 }
936 return dvb_aplay(av7110, buf, count, file->f_flags & O_NONBLOCK, 0);
937}
938
939static u8 iframe_header[] = { 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x80, 0x00, 0x00 };
940
941#define MIN_IFRAME 400000
942
943static int play_iframe(struct av7110 *av7110, u8 __user *buf, unsigned int len, int nonblock)
944{
945 int i, n;
946
947 dprintk(2, "av7110:%p, \n", av7110);
948
949 if (!(av7110->playing & RP_VIDEO)) {
950 if (av7110_av_start_play(av7110, RP_VIDEO) < 0)
951 return -EBUSY;
952 }
953
954 /* setting n always > 1, fixes problems when playing stillframes
955 consisting of I- and P-Frames */
956 n = MIN_IFRAME / len + 1;
957
958 /* FIXME: nonblock? */
959 dvb_play_kernel(av7110, iframe_header, sizeof(iframe_header), 0, 1);
960
961 for (i = 0; i < n; i++)
962 dvb_play(av7110, buf, len, 0, 1);
963
964 av7110_ipack_flush(&av7110->ipack[1]);
965 return 0;
966}
967
968
969static int dvb_video_ioctl(struct inode *inode, struct file *file,
970 unsigned int cmd, void *parg)
971{
972 struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;
973 struct av7110 *av7110 = (struct av7110 *) dvbdev->priv;
974 unsigned long arg = (unsigned long) parg;
975 int ret = 0;
976
977 dprintk(2, "av7110:%p, \n", av7110);
978
979 if ((file->f_flags & O_ACCMODE) == O_RDONLY) {
980 if ( cmd != VIDEO_GET_STATUS && cmd != VIDEO_GET_EVENT &&
981 cmd != VIDEO_GET_SIZE ) {
982 return -EPERM;
983 }
984 }
985
986 switch (cmd) {
987 case VIDEO_STOP:
988 av7110->videostate.play_state = VIDEO_STOPPED;
989 if (av7110->videostate.stream_source == VIDEO_SOURCE_MEMORY)
990 av7110_av_stop(av7110, RP_VIDEO);
991 else
992 vidcom(av7110, VIDEO_CMD_STOP,
993 av7110->videostate.video_blank ? 0 : 1);
994 av7110->trickmode = TRICK_NONE;
995 break;
996
997 case VIDEO_PLAY:
998 av7110->trickmode = TRICK_NONE;
999 if (av7110->videostate.play_state == VIDEO_FREEZED) {
1000 av7110->videostate.play_state = VIDEO_PLAYING;
1001 vidcom(av7110, VIDEO_CMD_PLAY, 0);
1002 }
1003
1004 if (av7110->videostate.stream_source == VIDEO_SOURCE_MEMORY) {
1005 if (av7110->playing == RP_AV) {
1006 av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Stop, 0);
1007 av7110->playing &= ~RP_VIDEO;
1008 }
1009 av7110_av_start_play(av7110, RP_VIDEO);
1010 vidcom(av7110, VIDEO_CMD_PLAY, 0);
1011 } else {
1012 //av7110_av_stop(av7110, RP_VIDEO);
1013 vidcom(av7110, VIDEO_CMD_PLAY, 0);
1014 }
1015 av7110->videostate.play_state = VIDEO_PLAYING;
1016 break;
1017
1018 case VIDEO_FREEZE:
1019 av7110->videostate.play_state = VIDEO_FREEZED;
1020 if (av7110->playing & RP_VIDEO)
1021 av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Pause, 0);
1022 else
1023 vidcom(av7110, VIDEO_CMD_FREEZE, 1);
1024 av7110->trickmode = TRICK_FREEZE;
1025 break;
1026
1027 case VIDEO_CONTINUE:
1028 if (av7110->playing & RP_VIDEO)
1029 av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Continue, 0);
1030 vidcom(av7110, VIDEO_CMD_PLAY, 0);
1031 av7110->videostate.play_state = VIDEO_PLAYING;
1032 av7110->trickmode = TRICK_NONE;
1033 break;
1034
1035 case VIDEO_SELECT_SOURCE:
1036 av7110->videostate.stream_source = (video_stream_source_t) arg;
1037 break;
1038
1039 case VIDEO_SET_BLANK:
1040 av7110->videostate.video_blank = (int) arg;
1041 break;
1042
1043 case VIDEO_GET_STATUS:
1044 memcpy(parg, &av7110->videostate, sizeof(struct video_status));
1045 break;
1046
1047 case VIDEO_GET_EVENT:
1048 ret=dvb_video_get_event(av7110, parg, file->f_flags);
1049 break;
1050
1051 case VIDEO_GET_SIZE:
1052 memcpy(parg, &av7110->video_size, sizeof(video_size_t));
1053 break;
1054
1055 case VIDEO_SET_DISPLAY_FORMAT:
1056 {
1057 video_displayformat_t format = (video_displayformat_t) arg;
1058 u16 val = 0;
1059
1060 switch (format) {
1061 case VIDEO_PAN_SCAN:
1062 val = VID_PAN_SCAN_PREF;
1063 break;
1064
1065 case VIDEO_LETTER_BOX:
1066 val = VID_VC_AND_PS_PREF;
1067 break;
1068
1069 case VIDEO_CENTER_CUT_OUT:
1070 val = VID_CENTRE_CUT_PREF;
1071 break;
1072
1073 default:
1074 ret = -EINVAL;
1075 }
1076 if (ret < 0)
1077 break;
1078 av7110->videostate.video_format = format;
1079 ret = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetPanScanType,
1080 1, (u16) val);
1081 break;
1082 }
1083
1084 case VIDEO_SET_FORMAT:
1085 if (arg > 1) {
1086 ret = -EINVAL;
1087 break;
1088 }
1089 av7110->display_ar = arg;
1090 ret = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetMonitorType,
1091 1, (u16) arg);
1092 break;
1093
1094 case VIDEO_STILLPICTURE:
1095 {
1096 struct video_still_picture *pic =
1097 (struct video_still_picture *) parg;
1098 av7110->videostate.stream_source = VIDEO_SOURCE_MEMORY;
1099 dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout);
1100 ret = play_iframe(av7110, pic->iFrame, pic->size,
1101 file->f_flags & O_NONBLOCK);
1102 break;
1103 }
1104
1105 case VIDEO_FAST_FORWARD:
1106 //note: arg is ignored by firmware
1107 if (av7110->playing & RP_VIDEO)
1108 av7110_fw_cmd(av7110, COMTYPE_REC_PLAY,
1109 __Scan_I, 2, AV_PES, 0);
1110 else
1111 vidcom(av7110, VIDEO_CMD_FFWD, arg);
1112 av7110->trickmode = TRICK_FAST;
1113 av7110->videostate.play_state = VIDEO_PLAYING;
1114 break;
1115
1116 case VIDEO_SLOWMOTION:
1117 if (av7110->playing&RP_VIDEO) {
1118 av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Slow, 2, 0, 0);
1119 vidcom(av7110, VIDEO_CMD_SLOW, arg);
1120 } else {
1121 vidcom(av7110, VIDEO_CMD_PLAY, 0);
1122 vidcom(av7110, VIDEO_CMD_STOP, 0);
1123 vidcom(av7110, VIDEO_CMD_SLOW, arg);
1124 }
1125 av7110->trickmode = TRICK_SLOW;
1126 av7110->videostate.play_state = VIDEO_PLAYING;
1127 break;
1128
1129 case VIDEO_GET_CAPABILITIES:
1130 *(int *)parg = VIDEO_CAP_MPEG1 | VIDEO_CAP_MPEG2 |
1131 VIDEO_CAP_SYS | VIDEO_CAP_PROG;
1132 break;
1133
1134 case VIDEO_CLEAR_BUFFER:
1135 dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout);
1136 av7110_ipack_reset(&av7110->ipack[1]);
1137
1138 if (av7110->playing == RP_AV) {
1139 av7110_fw_cmd(av7110, COMTYPE_REC_PLAY,
1140 __Play, 2, AV_PES, 0);
1141 if (av7110->trickmode == TRICK_FAST)
1142 av7110_fw_cmd(av7110, COMTYPE_REC_PLAY,
1143 __Scan_I, 2, AV_PES, 0);
1144 if (av7110->trickmode == TRICK_SLOW) {
1145 av7110_fw_cmd(av7110, COMTYPE_REC_PLAY,
1146 __Slow, 2, 0, 0);
1147 vidcom(av7110, VIDEO_CMD_SLOW, arg);
1148 }
1149 if (av7110->trickmode == TRICK_FREEZE)
1150 vidcom(av7110, VIDEO_CMD_STOP, 1);
1151 }
1152 break;
1153
1154 case VIDEO_SET_STREAMTYPE:
1155
1156 break;
1157
1158 default:
1159 ret = -ENOIOCTLCMD;
1160 break;
1161 }
1162 return ret;
1163}
1164
1165static int dvb_audio_ioctl(struct inode *inode, struct file *file,
1166 unsigned int cmd, void *parg)
1167{
1168 struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;
1169 struct av7110 *av7110 = (struct av7110 *) dvbdev->priv;
1170 unsigned long arg = (unsigned long) parg;
1171 int ret = 0;
1172
1173 dprintk(2, "av7110:%p, \n", av7110);
1174
1175 if (((file->f_flags & O_ACCMODE) == O_RDONLY) &&
1176 (cmd != AUDIO_GET_STATUS))
1177 return -EPERM;
1178
1179 switch (cmd) {
1180 case AUDIO_STOP:
1181 if (av7110->audiostate.stream_source == AUDIO_SOURCE_MEMORY)
1182 av7110_av_stop(av7110, RP_AUDIO);
1183 else
1184 audcom(av7110, AUDIO_CMD_MUTE);
1185 av7110->audiostate.play_state = AUDIO_STOPPED;
1186 break;
1187
1188 case AUDIO_PLAY:
1189 if (av7110->audiostate.stream_source == AUDIO_SOURCE_MEMORY)
1190 av7110_av_start_play(av7110, RP_AUDIO);
1191 audcom(av7110, AUDIO_CMD_UNMUTE);
1192 av7110->audiostate.play_state = AUDIO_PLAYING;
1193 break;
1194
1195 case AUDIO_PAUSE:
1196 audcom(av7110, AUDIO_CMD_MUTE);
1197 av7110->audiostate.play_state = AUDIO_PAUSED;
1198 break;
1199
1200 case AUDIO_CONTINUE:
1201 if (av7110->audiostate.play_state == AUDIO_PAUSED) {
1202 av7110->audiostate.play_state = AUDIO_PLAYING;
1203 audcom(av7110, AUDIO_CMD_MUTE | AUDIO_CMD_PCM16);
1204 }
1205 break;
1206
1207 case AUDIO_SELECT_SOURCE:
1208 av7110->audiostate.stream_source = (audio_stream_source_t) arg;
1209 break;
1210
1211 case AUDIO_SET_MUTE:
1212 {
1213 audcom(av7110, arg ? AUDIO_CMD_MUTE : AUDIO_CMD_UNMUTE);
1214 av7110->audiostate.mute_state = (int) arg;
1215 break;
1216 }
1217
1218 case AUDIO_SET_AV_SYNC:
1219 av7110->audiostate.AV_sync_state = (int) arg;
1220 audcom(av7110, arg ? AUDIO_CMD_SYNC_ON : AUDIO_CMD_SYNC_OFF);
1221 break;
1222
1223 case AUDIO_SET_BYPASS_MODE:
1224 ret = -EINVAL;
1225 break;
1226
1227 case AUDIO_CHANNEL_SELECT:
1228 av7110->audiostate.channel_select = (audio_channel_select_t) arg;
1229
1230 switch(av7110->audiostate.channel_select) {
1231 case AUDIO_STEREO:
1232 audcom(av7110, AUDIO_CMD_STEREO);
1233 break;
1234
1235 case AUDIO_MONO_LEFT:
1236 audcom(av7110, AUDIO_CMD_MONO_L);
1237 break;
1238
1239 case AUDIO_MONO_RIGHT:
1240 audcom(av7110, AUDIO_CMD_MONO_R);
1241 break;
1242
1243 default:
1244 ret = -EINVAL;
1245 break;
1246 }
1247 break;
1248
1249 case AUDIO_GET_STATUS:
1250 memcpy(parg, &av7110->audiostate, sizeof(struct audio_status));
1251 break;
1252
1253 case AUDIO_GET_CAPABILITIES:
1254 *(int *)parg = AUDIO_CAP_LPCM | AUDIO_CAP_MP1 | AUDIO_CAP_MP2;
1255 break;
1256
1257 case AUDIO_CLEAR_BUFFER:
1258 dvb_ringbuffer_flush_spinlock_wakeup(&av7110->aout);
1259 av7110_ipack_reset(&av7110->ipack[0]);
1260 if (av7110->playing == RP_AV)
1261 av7110_fw_cmd(av7110, COMTYPE_REC_PLAY,
1262 __Play, 2, AV_PES, 0);
1263 break;
1264 case AUDIO_SET_ID:
1265
1266 break;
1267 case AUDIO_SET_MIXER:
1268 {
1269 struct audio_mixer *amix = (struct audio_mixer *)parg;
1270
1271 av7110_set_volume(av7110, amix->volume_left, amix->volume_right);
1272 break;
1273 }
1274 case AUDIO_SET_STREAMTYPE:
1275 break;
1276 default:
1277 ret = -ENOIOCTLCMD;
1278 }
1279 return ret;
1280}
1281
1282
1283static int dvb_video_open(struct inode *inode, struct file *file)
1284{
1285 struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;
1286 struct av7110 *av7110 = (struct av7110 *) dvbdev->priv;
1287 int err;
1288
1289 dprintk(2, "av7110:%p, \n", av7110);
1290
1291 if ((err = dvb_generic_open(inode, file)) < 0)
1292 return err;
1293
1294 if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
1295 dvb_ringbuffer_flush_spinlock_wakeup(&av7110->aout);
1296 dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout);
1297 av7110->video_blank = 1;
1298 av7110->audiostate.AV_sync_state = 1;
1299 av7110->videostate.stream_source = VIDEO_SOURCE_DEMUX;
1300
1301 /* empty event queue */
1302 av7110->video_events.eventr = av7110->video_events.eventw = 0;
1303 }
1304
1305 return 0;
1306}
1307
1308static int dvb_video_release(struct inode *inode, struct file *file)
1309{
1310 struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;
1311 struct av7110 *av7110 = (struct av7110 *) dvbdev->priv;
1312
1313 dprintk(2, "av7110:%p, \n", av7110);
1314
1315 if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
1316 av7110_av_stop(av7110, RP_VIDEO);
1317 }
1318
1319 return dvb_generic_release(inode, file);
1320}
1321
1322static int dvb_audio_open(struct inode *inode, struct file *file)
1323{
1324 struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;
1325 struct av7110 *av7110 = (struct av7110 *) dvbdev->priv;
1326 int err=dvb_generic_open(inode, file);
1327
1328 dprintk(2, "av7110:%p, \n", av7110);
1329
1330 if (err < 0)
1331 return err;
1332 dvb_ringbuffer_flush_spinlock_wakeup(&av7110->aout);
1333 av7110->audiostate.stream_source = AUDIO_SOURCE_DEMUX;
1334 return 0;
1335}
1336
1337static int dvb_audio_release(struct inode *inode, struct file *file)
1338{
1339 struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;
1340 struct av7110 *av7110 = (struct av7110 *) dvbdev->priv;
1341
1342 dprintk(2, "av7110:%p, \n", av7110);
1343
1344 av7110_av_stop(av7110, RP_AUDIO);
1345 return dvb_generic_release(inode, file);
1346}
1347
1348
1349
1350/******************************************************************************
1351 * driver registration
1352 ******************************************************************************/
1353
1354static struct file_operations dvb_video_fops = {
1355 .owner = THIS_MODULE,
1356 .write = dvb_video_write,
1357 .ioctl = dvb_generic_ioctl,
1358 .open = dvb_video_open,
1359 .release = dvb_video_release,
1360 .poll = dvb_video_poll,
1361};
1362
1363static struct dvb_device dvbdev_video = {
1364 .priv = NULL,
1365 .users = 6,
1366 .readers = 5, /* arbitrary */
1367 .writers = 1,
1368 .fops = &dvb_video_fops,
1369 .kernel_ioctl = dvb_video_ioctl,
1370};
1371
1372static struct file_operations dvb_audio_fops = {
1373 .owner = THIS_MODULE,
1374 .write = dvb_audio_write,
1375 .ioctl = dvb_generic_ioctl,
1376 .open = dvb_audio_open,
1377 .release = dvb_audio_release,
1378 .poll = dvb_audio_poll,
1379};
1380
1381static struct dvb_device dvbdev_audio = {
1382 .priv = NULL,
1383 .users = 1,
1384 .writers = 1,
1385 .fops = &dvb_audio_fops,
1386 .kernel_ioctl = dvb_audio_ioctl,
1387};
1388
1389
1390int av7110_av_register(struct av7110 *av7110)
1391{
1392 av7110->audiostate.AV_sync_state = 0;
1393 av7110->audiostate.mute_state = 0;
1394 av7110->audiostate.play_state = AUDIO_STOPPED;
1395 av7110->audiostate.stream_source = AUDIO_SOURCE_DEMUX;
1396 av7110->audiostate.channel_select = AUDIO_STEREO;
1397 av7110->audiostate.bypass_mode = 0;
1398
1399 av7110->videostate.video_blank = 0;
1400 av7110->videostate.play_state = VIDEO_STOPPED;
1401 av7110->videostate.stream_source = VIDEO_SOURCE_DEMUX;
1402 av7110->videostate.video_format = VIDEO_FORMAT_4_3;
1403 av7110->videostate.display_format = VIDEO_CENTER_CUT_OUT;
1404 av7110->display_ar = VIDEO_FORMAT_4_3;
1405
1406 init_waitqueue_head(&av7110->video_events.wait_queue);
1407 spin_lock_init(&av7110->video_events.lock);
1408 av7110->video_events.eventw = av7110->video_events.eventr = 0;
1409 av7110->video_events.overflow = 0;
1410 memset(&av7110->video_size, 0, sizeof (video_size_t));
1411
1412 dvb_register_device(av7110->dvb_adapter, &av7110->video_dev,
1413 &dvbdev_video, av7110, DVB_DEVICE_VIDEO);
1414
1415 dvb_register_device(av7110->dvb_adapter, &av7110->audio_dev,
1416 &dvbdev_audio, av7110, DVB_DEVICE_AUDIO);
1417
1418 return 0;
1419}
1420
1421void av7110_av_unregister(struct av7110 *av7110)
1422{
1423 dvb_unregister_device(av7110->audio_dev);
1424 dvb_unregister_device(av7110->video_dev);
1425}
1426
1427int av7110_av_init(struct av7110 *av7110)
1428{
1429 void (*play[])(u8 *, int, void *) = { play_audio_cb, play_video_cb };
1430 int i, ret;
1431
1432 av7110->vidmode = VIDEO_MODE_PAL;
1433
1434 for (i = 0; i < 2; i++) {
1435 struct ipack *ipack = av7110->ipack + i;
1436
1437 ret = av7110_ipack_init(ipack, IPACKS, play[i]);
1438 if (ret < 0) {
1439 if (i)
1440 av7110_ipack_free(--ipack);
1441 goto out;
1442 }
1443 ipack->data = av7110;
1444 }
1445
1446 dvb_ringbuffer_init(&av7110->avout, av7110->iobuf, AVOUTLEN);
1447 dvb_ringbuffer_init(&av7110->aout, av7110->iobuf + AVOUTLEN, AOUTLEN);
1448
1449 av7110->kbuf[0] = (u8 *)(av7110->iobuf + AVOUTLEN + AOUTLEN + BMPLEN);
1450 av7110->kbuf[1] = av7110->kbuf[0] + 2 * IPACKS;
1451out:
1452 return ret;
1453}
1454
1455void av7110_av_exit(struct av7110 *av7110)
1456{
1457 av7110_ipack_free(&av7110->ipack[0]);
1458 av7110_ipack_free(&av7110->ipack[1]);
1459}
diff --git a/drivers/media/dvb/ttpci/av7110_av.h b/drivers/media/dvb/ttpci/av7110_av.h
new file mode 100644
index 000000000000..cc5e7a7e87c3
--- /dev/null
+++ b/drivers/media/dvb/ttpci/av7110_av.h
@@ -0,0 +1,29 @@
1#ifndef _AV7110_AV_H_
2#define _AV7110_AV_H_
3
4struct av7110;
5
6extern void av7110_set_vidmode(struct av7110 *av7110, int mode);
7
8extern int av7110_record_cb(struct dvb_filter_pes2ts *p2t, u8 *buf, size_t len);
9extern int av7110_pes_play(void *dest, struct dvb_ringbuffer *buf, int dlen);
10extern int av7110_write_to_decoder(struct dvb_demux_feed *feed, const u8 *buf, size_t len);
11
12extern int av7110_set_volume(struct av7110 *av7110, int volleft, int volright);
13extern void av7110_av_stop(struct av7110 *av7110, int av);
14extern int av7110_av_start_record(struct av7110 *av7110, int av,
15 struct dvb_demux_feed *dvbdmxfeed);
16extern int av7110_av_start_play(struct av7110 *av7110, int av);
17
18extern void dvb_video_add_event(struct av7110 *av7110, struct video_event *event);
19
20extern void av7110_p2t_init(struct av7110_p2t *p, struct dvb_demux_feed *feed);
21extern void av7110_p2t_write(u8 const *buf, long int length, u16 pid, struct av7110_p2t *p);
22
23extern int av7110_av_register(struct av7110 *av7110);
24extern void av7110_av_unregister(struct av7110 *av7110);
25extern int av7110_av_init(struct av7110 *av7110);
26extern void av7110_av_exit(struct av7110 *av7110);
27
28
29#endif /* _AV7110_AV_H_ */
diff --git a/drivers/media/dvb/ttpci/av7110_ca.c b/drivers/media/dvb/ttpci/av7110_ca.c
new file mode 100644
index 000000000000..21f7aacf7726
--- /dev/null
+++ b/drivers/media/dvb/ttpci/av7110_ca.c
@@ -0,0 +1,390 @@
1/*
2 * av7110_ca.c: CA and CI stuff
3 *
4 * Copyright (C) 1999-2002 Ralph Metzler
5 * & Marcus Metzler for convergence integrated media GmbH
6 *
7 * originally based on code by:
8 * Copyright (C) 1998,1999 Christian Theiss <mistert@rz.fh-augsburg.de>
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
14 *
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
26 *
27 *
28 * the project's page is at http://www.linuxtv.org/dvb/
29 */
30
31#include <linux/kernel.h>
32#include <linux/sched.h>
33#include <linux/types.h>
34#include <linux/delay.h>
35#include <linux/fs.h>
36#include <linux/timer.h>
37#include <linux/poll.h>
38#include <linux/byteorder/swabb.h>
39#include <linux/smp_lock.h>
40
41#include "av7110.h"
42#include "av7110_hw.h"
43
44
45void CI_handle(struct av7110 *av7110, u8 *data, u16 len)
46{
47 dprintk(8, "av7110:%p\n",av7110);
48
49 if (len < 3)
50 return;
51 switch (data[0]) {
52 case CI_MSG_CI_INFO:
53 if (data[2] != 1 && data[2] != 2)
54 break;
55 switch (data[1]) {
56 case 0:
57 av7110->ci_slot[data[2] - 1].flags = 0;
58 break;
59 case 1:
60 av7110->ci_slot[data[2] - 1].flags |= CA_CI_MODULE_PRESENT;
61 break;
62 case 2:
63 av7110->ci_slot[data[2] - 1].flags |= CA_CI_MODULE_READY;
64 break;
65 }
66 break;
67 case CI_SWITCH_PRG_REPLY:
68 //av7110->ci_stat=data[1];
69 break;
70 default:
71 break;
72 }
73}
74
75
76void ci_get_data(struct dvb_ringbuffer *cibuf, u8 *data, int len)
77{
78 if (dvb_ringbuffer_free(cibuf) < len + 2)
79 return;
80
81 DVB_RINGBUFFER_WRITE_BYTE(cibuf, len >> 8);
82 DVB_RINGBUFFER_WRITE_BYTE(cibuf, len & 0xff);
83 dvb_ringbuffer_write(cibuf, data, len);
84 wake_up_interruptible(&cibuf->queue);
85}
86
87
88/******************************************************************************
89 * CI link layer file ops
90 ******************************************************************************/
91
92static int ci_ll_init(struct dvb_ringbuffer *cirbuf, struct dvb_ringbuffer *ciwbuf, int size)
93{
94 struct dvb_ringbuffer *tab[] = { cirbuf, ciwbuf, NULL }, **p;
95 void *data;
96
97 for (p = tab; *p; p++) {
98 data = vmalloc(size);
99 if (!data) {
100 while (p-- != tab) {
101 vfree(p[0]->data);
102 p[0]->data = NULL;
103 }
104 return -ENOMEM;
105 }
106 dvb_ringbuffer_init(*p, data, size);
107 }
108 return 0;
109}
110
111static void ci_ll_flush(struct dvb_ringbuffer *cirbuf, struct dvb_ringbuffer *ciwbuf)
112{
113 dvb_ringbuffer_flush_spinlock_wakeup(cirbuf);
114 dvb_ringbuffer_flush_spinlock_wakeup(ciwbuf);
115}
116
117static void ci_ll_release(struct dvb_ringbuffer *cirbuf, struct dvb_ringbuffer *ciwbuf)
118{
119 vfree(cirbuf->data);
120 cirbuf->data = NULL;
121 vfree(ciwbuf->data);
122 ciwbuf->data = NULL;
123}
124
125static int ci_ll_reset(struct dvb_ringbuffer *cibuf, struct file *file,
126 int slots, ca_slot_info_t *slot)
127{
128 int i;
129 int len = 0;
130 u8 msg[8] = { 0x00, 0x06, 0x00, 0x00, 0xff, 0x02, 0x00, 0x00 };
131
132 for (i = 0; i < 2; i++) {
133 if (slots & (1 << i))
134 len += 8;
135 }
136
137 if (dvb_ringbuffer_free(cibuf) < len)
138 return -EBUSY;
139
140 for (i = 0; i < 2; i++) {
141 if (slots & (1 << i)) {
142 msg[2] = i;
143 dvb_ringbuffer_write(cibuf, msg, 8);
144 slot[i].flags = 0;
145 }
146 }
147
148 return 0;
149}
150
151static ssize_t ci_ll_write(struct dvb_ringbuffer *cibuf, struct file *file,
152 const char __user *buf, size_t count, loff_t *ppos)
153{
154 int free;
155 int non_blocking = file->f_flags & O_NONBLOCK;
156 char *page = (char *)__get_free_page(GFP_USER);
157 int res;
158
159 if (!page)
160 return -ENOMEM;
161
162 res = -EINVAL;
163 if (count > 2048)
164 goto out;
165
166 res = -EFAULT;
167 if (copy_from_user(page, buf, count))
168 goto out;
169
170 free = dvb_ringbuffer_free(cibuf);
171 if (count + 2 > free) {
172 res = -EWOULDBLOCK;
173 if (non_blocking)
174 goto out;
175 res = -ERESTARTSYS;
176 if (wait_event_interruptible(cibuf->queue,
177 (dvb_ringbuffer_free(cibuf) >= count + 2)))
178 goto out;
179 }
180
181 DVB_RINGBUFFER_WRITE_BYTE(cibuf, count >> 8);
182 DVB_RINGBUFFER_WRITE_BYTE(cibuf, count & 0xff);
183
184 res = dvb_ringbuffer_write(cibuf, page, count);
185out:
186 free_page((unsigned long)page);
187 return res;
188}
189
190static ssize_t ci_ll_read(struct dvb_ringbuffer *cibuf, struct file *file,
191 char __user *buf, size_t count, loff_t *ppos)
192{
193 int avail;
194 int non_blocking = file->f_flags & O_NONBLOCK;
195 ssize_t len;
196
197 if (!cibuf->data || !count)
198 return 0;
199 if (non_blocking && (dvb_ringbuffer_empty(cibuf)))
200 return -EWOULDBLOCK;
201 if (wait_event_interruptible(cibuf->queue,
202 !dvb_ringbuffer_empty(cibuf)))
203 return -ERESTARTSYS;
204 avail = dvb_ringbuffer_avail(cibuf);
205 if (avail < 4)
206 return 0;
207 len = DVB_RINGBUFFER_PEEK(cibuf, 0) << 8;
208 len |= DVB_RINGBUFFER_PEEK(cibuf, 1);
209 if (avail < len + 2 || count < len)
210 return -EINVAL;
211 DVB_RINGBUFFER_SKIP(cibuf, 2);
212
213 return dvb_ringbuffer_read(cibuf, buf, len, 1);
214}
215
216static int dvb_ca_open(struct inode *inode, struct file *file)
217{
218 struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;
219 struct av7110 *av7110 = (struct av7110 *) dvbdev->priv;
220 int err = dvb_generic_open(inode, file);
221
222 dprintk(8, "av7110:%p\n",av7110);
223
224 if (err < 0)
225 return err;
226 ci_ll_flush(&av7110->ci_rbuffer, &av7110->ci_wbuffer);
227 return 0;
228}
229
230static unsigned int dvb_ca_poll (struct file *file, poll_table *wait)
231{
232 struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;
233 struct av7110 *av7110 = (struct av7110 *) dvbdev->priv;
234 struct dvb_ringbuffer *rbuf = &av7110->ci_rbuffer;
235 struct dvb_ringbuffer *wbuf = &av7110->ci_wbuffer;
236 unsigned int mask = 0;
237
238 dprintk(8, "av7110:%p\n",av7110);
239
240 poll_wait(file, &rbuf->queue, wait);
241 poll_wait(file, &wbuf->queue, wait);
242
243 if (!dvb_ringbuffer_empty(rbuf))
244 mask |= (POLLIN | POLLRDNORM);
245
246 if (dvb_ringbuffer_free(wbuf) > 1024)
247 mask |= (POLLOUT | POLLWRNORM);
248
249 return mask;
250}
251
252static int dvb_ca_ioctl(struct inode *inode, struct file *file,
253 unsigned int cmd, void *parg)
254{
255 struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;
256 struct av7110 *av7110 = (struct av7110 *) dvbdev->priv;
257 unsigned long arg = (unsigned long) parg;
258
259 dprintk(8, "av7110:%p\n",av7110);
260
261 switch (cmd) {
262 case CA_RESET:
263 return ci_ll_reset(&av7110->ci_wbuffer, file, arg, &av7110->ci_slot[0]);
264 break;
265 case CA_GET_CAP:
266 {
267 ca_caps_t cap;
268
269 cap.slot_num = 2;
270 cap.slot_type = (FW_CI_LL_SUPPORT(av7110->arm_app) ?
271 CA_CI_LINK : CA_CI) | CA_DESCR;
272 cap.descr_num = 16;
273 cap.descr_type = CA_ECD;
274 memcpy(parg, &cap, sizeof(cap));
275 break;
276 }
277
278 case CA_GET_SLOT_INFO:
279 {
280 ca_slot_info_t *info=(ca_slot_info_t *)parg;
281
282 if (info->num > 1)
283 return -EINVAL;
284 av7110->ci_slot[info->num].num = info->num;
285 av7110->ci_slot[info->num].type = FW_CI_LL_SUPPORT(av7110->arm_app) ?
286 CA_CI_LINK : CA_CI;
287 memcpy(info, &av7110->ci_slot[info->num], sizeof(ca_slot_info_t));
288 break;
289 }
290
291 case CA_GET_MSG:
292 break;
293
294 case CA_SEND_MSG:
295 break;
296
297 case CA_GET_DESCR_INFO:
298 {
299 ca_descr_info_t info;
300
301 info.num = 16;
302 info.type = CA_ECD;
303 memcpy(parg, &info, sizeof (info));
304 break;
305 }
306
307 case CA_SET_DESCR:
308 {
309 ca_descr_t *descr = (ca_descr_t*) parg;
310
311 if (descr->index >= 16)
312 return -EINVAL;
313 if (descr->parity > 1)
314 return -EINVAL;
315 av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, SetDescr, 5,
316 (descr->index<<8)|descr->parity,
317 (descr->cw[0]<<8)|descr->cw[1],
318 (descr->cw[2]<<8)|descr->cw[3],
319 (descr->cw[4]<<8)|descr->cw[5],
320 (descr->cw[6]<<8)|descr->cw[7]);
321 break;
322 }
323
324 default:
325 return -EINVAL;
326 }
327 return 0;
328}
329
330static ssize_t dvb_ca_write(struct file *file, const char __user *buf,
331 size_t count, loff_t *ppos)
332{
333 struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;
334 struct av7110 *av7110 = (struct av7110 *) dvbdev->priv;
335
336 dprintk(8, "av7110:%p\n",av7110);
337 return ci_ll_write(&av7110->ci_wbuffer, file, buf, count, ppos);
338}
339
340static ssize_t dvb_ca_read(struct file *file, char __user *buf,
341 size_t count, loff_t *ppos)
342{
343 struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;
344 struct av7110 *av7110 = (struct av7110 *) dvbdev->priv;
345
346 dprintk(8, "av7110:%p\n",av7110);
347 return ci_ll_read(&av7110->ci_rbuffer, file, buf, count, ppos);
348}
349
350
351
352static struct file_operations dvb_ca_fops = {
353 .owner = THIS_MODULE,
354 .read = dvb_ca_read,
355 .write = dvb_ca_write,
356 .ioctl = dvb_generic_ioctl,
357 .open = dvb_ca_open,
358 .release = dvb_generic_release,
359 .poll = dvb_ca_poll,
360};
361
362static struct dvb_device dvbdev_ca = {
363 .priv = NULL,
364 .users = 1,
365 .writers = 1,
366 .fops = &dvb_ca_fops,
367 .kernel_ioctl = dvb_ca_ioctl,
368};
369
370
371int av7110_ca_register(struct av7110 *av7110)
372{
373 return dvb_register_device(av7110->dvb_adapter, &av7110->ca_dev,
374 &dvbdev_ca, av7110, DVB_DEVICE_CA);
375}
376
377void av7110_ca_unregister(struct av7110 *av7110)
378{
379 dvb_unregister_device(av7110->ca_dev);
380}
381
382int av7110_ca_init(struct av7110* av7110)
383{
384 return ci_ll_init(&av7110->ci_rbuffer, &av7110->ci_wbuffer, 8192);
385}
386
387void av7110_ca_exit(struct av7110* av7110)
388{
389 ci_ll_release(&av7110->ci_rbuffer, &av7110->ci_wbuffer);
390}
diff --git a/drivers/media/dvb/ttpci/av7110_ca.h b/drivers/media/dvb/ttpci/av7110_ca.h
new file mode 100644
index 000000000000..70ee855ece1b
--- /dev/null
+++ b/drivers/media/dvb/ttpci/av7110_ca.h
@@ -0,0 +1,14 @@
1#ifndef _AV7110_CA_H_
2#define _AV7110_CA_H_
3
4struct av7110;
5
6extern void CI_handle(struct av7110 *av7110, u8 *data, u16 len);
7extern void ci_get_data(struct dvb_ringbuffer *cibuf, u8 *data, int len);
8
9extern int av7110_ca_register(struct av7110 *av7110);
10extern void av7110_ca_unregister(struct av7110 *av7110);
11extern int av7110_ca_init(struct av7110* av7110);
12extern void av7110_ca_exit(struct av7110* av7110);
13
14#endif /* _AV7110_CA_H_ */
diff --git a/drivers/media/dvb/ttpci/av7110_hw.c b/drivers/media/dvb/ttpci/av7110_hw.c
new file mode 100644
index 000000000000..bd6e5ea4aefe
--- /dev/null
+++ b/drivers/media/dvb/ttpci/av7110_hw.c
@@ -0,0 +1,1170 @@
1/*
2 * av7110_hw.c: av7110 low level hardware access and firmware interface
3 *
4 * Copyright (C) 1999-2002 Ralph Metzler
5 * & Marcus Metzler for convergence integrated media GmbH
6 *
7 * originally based on code by:
8 * Copyright (C) 1998,1999 Christian Theiss <mistert@rz.fh-augsburg.de>
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
24 *
25 * the project's page is at http://www.linuxtv.org/dvb/
26 */
27
28/* for debugging ARM communication: */
29//#define COM_DEBUG
30
31#include <stdarg.h>
32#include <linux/types.h>
33#include <linux/kernel.h>
34#include <linux/string.h>
35#include <linux/sched.h>
36#include <linux/delay.h>
37#include <linux/byteorder/swabb.h>
38#include <linux/smp_lock.h>
39#include <linux/fs.h>
40
41#include "av7110.h"
42#include "av7110_hw.h"
43
44/****************************************************************************
45 * DEBI functions
46 ****************************************************************************/
47
48/* This DEBI code is based on the Stradis driver
49 by Nathan Laredo <laredo@gnu.org> */
50
51int av7110_debiwrite(struct av7110 *av7110, u32 config,
52 int addr, u32 val, int count)
53{
54 struct saa7146_dev *dev = av7110->dev;
55
56 if (count <= 0 || count > 32764) {
57 printk("%s: invalid count %d\n", __FUNCTION__, count);
58 return -1;
59 }
60 if (saa7146_wait_for_debi_done(av7110->dev, 0) < 0) {
61 printk("%s: wait_for_debi_done failed\n", __FUNCTION__);
62 return -1;
63 }
64 saa7146_write(dev, DEBI_CONFIG, config);
65 if (count <= 4) /* immediate transfer */
66 saa7146_write(dev, DEBI_AD, val);
67 else /* block transfer */
68 saa7146_write(dev, DEBI_AD, av7110->debi_bus);
69 saa7146_write(dev, DEBI_COMMAND, (count << 17) | (addr & 0xffff));
70 saa7146_write(dev, MC2, (2 << 16) | 2);
71 return 0;
72}
73
74u32 av7110_debiread(struct av7110 *av7110, u32 config, int addr, int count)
75{
76 struct saa7146_dev *dev = av7110->dev;
77 u32 result = 0;
78
79 if (count > 32764 || count <= 0) {
80 printk("%s: invalid count %d\n", __FUNCTION__, count);
81 return 0;
82 }
83 if (saa7146_wait_for_debi_done(av7110->dev, 0) < 0) {
84 printk("%s: wait_for_debi_done #1 failed\n", __FUNCTION__);
85 return 0;
86 }
87 saa7146_write(dev, DEBI_AD, av7110->debi_bus);
88 saa7146_write(dev, DEBI_COMMAND, (count << 17) | 0x10000 | (addr & 0xffff));
89
90 saa7146_write(dev, DEBI_CONFIG, config);
91 saa7146_write(dev, MC2, (2 << 16) | 2);
92 if (count > 4)
93 return count;
94 if (saa7146_wait_for_debi_done(av7110->dev, 0) < 0) {
95 printk("%s: wait_for_debi_done #2 failed\n", __FUNCTION__);
96 return 0;
97 }
98
99 result = saa7146_read(dev, DEBI_AD);
100 result &= (0xffffffffUL >> ((4 - count) * 8));
101 return result;
102}
103
104
105
106/* av7110 ARM core boot stuff */
107
108void av7110_reset_arm(struct av7110 *av7110)
109{
110 saa7146_setgpio(av7110->dev, RESET_LINE, SAA7146_GPIO_OUTLO);
111
112 /* Disable DEBI and GPIO irq */
113 SAA7146_IER_DISABLE(av7110->dev, MASK_19 | MASK_03);
114 SAA7146_ISR_CLEAR(av7110->dev, MASK_19 | MASK_03);
115
116 saa7146_setgpio(av7110->dev, RESET_LINE, SAA7146_GPIO_OUTHI);
117 msleep(30); /* the firmware needs some time to initialize */
118
119 ARM_ResetMailBox(av7110);
120
121 SAA7146_ISR_CLEAR(av7110->dev, MASK_19 | MASK_03);
122 SAA7146_IER_ENABLE(av7110->dev, MASK_03);
123
124 av7110->arm_ready = 1;
125 dprintk(1, "reset ARM\n");
126}
127
128
129static int waitdebi(struct av7110 *av7110, int adr, int state)
130{
131 int k;
132
133 dprintk(4, "%p\n", av7110);
134
135 for (k = 0; k < 100; k++) {
136 if (irdebi(av7110, DEBINOSWAP, adr, 0, 2) == state)
137 return 0;
138 udelay(5);
139 }
140 return -1;
141}
142
143static int load_dram(struct av7110 *av7110, u32 *data, int len)
144{
145 int i;
146 int blocks, rest;
147 u32 base, bootblock = BOOT_BLOCK;
148
149 dprintk(4, "%p\n", av7110);
150
151 blocks = len / BOOT_MAX_SIZE;
152 rest = len % BOOT_MAX_SIZE;
153 base = DRAM_START_CODE;
154
155 for (i = 0; i < blocks; i++) {
156 if (waitdebi(av7110, BOOT_STATE, BOOTSTATE_BUFFER_EMPTY) < 0) {
157 printk(KERN_ERR "dvb-ttpci: load_dram(): timeout at block %d\n", i);
158 return -1;
159 }
160 dprintk(4, "writing DRAM block %d\n", i);
161 mwdebi(av7110, DEBISWAB, bootblock,
162 ((char*)data) + i * BOOT_MAX_SIZE, BOOT_MAX_SIZE);
163 bootblock ^= 0x1400;
164 iwdebi(av7110, DEBISWAB, BOOT_BASE, swab32(base), 4);
165 iwdebi(av7110, DEBINOSWAP, BOOT_SIZE, BOOT_MAX_SIZE, 2);
166 iwdebi(av7110, DEBINOSWAP, BOOT_STATE, BOOTSTATE_BUFFER_FULL, 2);
167 base += BOOT_MAX_SIZE;
168 }
169
170 if (rest > 0) {
171 if (waitdebi(av7110, BOOT_STATE, BOOTSTATE_BUFFER_EMPTY) < 0) {
172 printk(KERN_ERR "dvb-ttpci: load_dram(): timeout at last block\n");
173 return -1;
174 }
175 if (rest > 4)
176 mwdebi(av7110, DEBISWAB, bootblock,
177 ((char*)data) + i * BOOT_MAX_SIZE, rest);
178 else
179 mwdebi(av7110, DEBISWAB, bootblock,
180 ((char*)data) + i * BOOT_MAX_SIZE - 4, rest + 4);
181
182 iwdebi(av7110, DEBISWAB, BOOT_BASE, swab32(base), 4);
183 iwdebi(av7110, DEBINOSWAP, BOOT_SIZE, rest, 2);
184 iwdebi(av7110, DEBINOSWAP, BOOT_STATE, BOOTSTATE_BUFFER_FULL, 2);
185 }
186 if (waitdebi(av7110, BOOT_STATE, BOOTSTATE_BUFFER_EMPTY) < 0) {
187 printk(KERN_ERR "dvb-ttpci: load_dram(): timeout after last block\n");
188 return -1;
189 }
190 iwdebi(av7110, DEBINOSWAP, BOOT_SIZE, 0, 2);
191 iwdebi(av7110, DEBINOSWAP, BOOT_STATE, BOOTSTATE_BUFFER_FULL, 2);
192 if (waitdebi(av7110, BOOT_STATE, BOOTSTATE_BOOT_COMPLETE) < 0) {
193 printk(KERN_ERR "dvb-ttpci: load_dram(): final handshake timeout\n");
194 return -1;
195 }
196 return 0;
197}
198
199
200/* we cannot write av7110 DRAM directly, so load a bootloader into
201 * the DPRAM which implements a simple boot protocol */
202static u8 bootcode[] = {
203 0xea, 0x00, 0x00, 0x0e, 0xe1, 0xb0, 0xf0, 0x0e, 0xe2, 0x5e, 0xf0, 0x04,
204 0xe2, 0x5e, 0xf0, 0x04, 0xe2, 0x5e, 0xf0, 0x08, 0xe2, 0x5e, 0xf0, 0x04,
205 0xe2, 0x5e, 0xf0, 0x04, 0xe2, 0x5e, 0xf0, 0x04, 0x2c, 0x00, 0x00, 0x24,
206 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x34,
207 0x00, 0x00, 0x00, 0x00, 0xa5, 0xa5, 0x5a, 0x5a, 0x00, 0x1f, 0x15, 0x55,
208 0x00, 0x00, 0x00, 0x09, 0xe5, 0x9f, 0xd0, 0x7c, 0xe5, 0x9f, 0x40, 0x74,
209 0xe3, 0xa0, 0x00, 0x00, 0xe5, 0x84, 0x00, 0x00, 0xe5, 0x84, 0x00, 0x04,
210 0xe5, 0x9f, 0x10, 0x70, 0xe5, 0x9f, 0x20, 0x70, 0xe5, 0x9f, 0x30, 0x64,
211 0xe8, 0xb1, 0x1f, 0xe0, 0xe8, 0xa3, 0x1f, 0xe0, 0xe1, 0x51, 0x00, 0x02,
212 0xda, 0xff, 0xff, 0xfb, 0xe5, 0x9f, 0xf0, 0x50, 0xe1, 0xd4, 0x10, 0xb0,
213 0xe3, 0x51, 0x00, 0x00, 0x0a, 0xff, 0xff, 0xfc, 0xe1, 0xa0, 0x10, 0x0d,
214 0xe5, 0x94, 0x30, 0x04, 0xe1, 0xd4, 0x20, 0xb2, 0xe2, 0x82, 0x20, 0x3f,
215 0xe1, 0xb0, 0x23, 0x22, 0x03, 0xa0, 0x00, 0x02, 0xe1, 0xc4, 0x00, 0xb0,
216 0x0a, 0xff, 0xff, 0xf4, 0xe8, 0xb1, 0x1f, 0xe0, 0xe8, 0xa3, 0x1f, 0xe0,
217 0xe8, 0xb1, 0x1f, 0xe0, 0xe8, 0xa3, 0x1f, 0xe0, 0xe2, 0x52, 0x20, 0x01,
218 0x1a, 0xff, 0xff, 0xf9, 0xe2, 0x2d, 0xdb, 0x05, 0xea, 0xff, 0xff, 0xec,
219 0x2c, 0x00, 0x03, 0xf8, 0x2c, 0x00, 0x04, 0x00, 0x9e, 0x00, 0x08, 0x00,
220 0x2c, 0x00, 0x00, 0x74, 0x2c, 0x00, 0x00, 0xc0
221};
222
223int av7110_bootarm(struct av7110 *av7110)
224{
225 struct saa7146_dev *dev = av7110->dev;
226 u32 ret;
227 int i;
228
229 dprintk(4, "%p\n", av7110);
230
231 saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTLO);
232
233 /* Disable DEBI and GPIO irq */
234 SAA7146_IER_DISABLE(av7110->dev, MASK_03 | MASK_19);
235 SAA7146_ISR_CLEAR(av7110->dev, MASK_19 | MASK_03);
236
237 /* enable DEBI */
238 saa7146_write(av7110->dev, MC1, 0x08800880);
239 saa7146_write(av7110->dev, DD1_STREAM_B, 0x00000000);
240 saa7146_write(av7110->dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
241
242 /* test DEBI */
243 iwdebi(av7110, DEBISWAP, DPRAM_BASE, 0x76543210, 4);
244 if ((ret=irdebi(av7110, DEBINOSWAP, DPRAM_BASE, 0, 4)) != 0x10325476) {
245 printk(KERN_ERR "dvb-ttpci: debi test in av7110_bootarm() failed: "
246 "%08x != %08x (check your BIOS 'Plug&Play OS' settings)\n",
247 ret, 0x10325476);
248 return -1;
249 }
250 for (i = 0; i < 8192; i += 4)
251 iwdebi(av7110, DEBISWAP, DPRAM_BASE + i, 0x00, 4);
252 dprintk(2, "debi test OK\n");
253
254 /* boot */
255 dprintk(1, "load boot code\n");
256 saa7146_setgpio(dev, ARM_IRQ_LINE, SAA7146_GPIO_IRQLO);
257 //saa7146_setgpio(dev, DEBI_DONE_LINE, SAA7146_GPIO_INPUT);
258 //saa7146_setgpio(dev, 3, SAA7146_GPIO_INPUT);
259
260 mwdebi(av7110, DEBISWAB, DPRAM_BASE, bootcode, sizeof(bootcode));
261 iwdebi(av7110, DEBINOSWAP, BOOT_STATE, BOOTSTATE_BUFFER_FULL, 2);
262
263 if (saa7146_wait_for_debi_done(av7110->dev, 1)) {
264 printk(KERN_ERR "dvb-ttpci: av7110_bootarm(): "
265 "saa7146_wait_for_debi_done() timed out\n");
266 return -1;
267 }
268 saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTHI);
269 mdelay(1);
270
271 dprintk(1, "load dram code\n");
272 if (load_dram(av7110, (u32 *)av7110->bin_root, av7110->size_root) < 0) {
273 printk(KERN_ERR "dvb-ttpci: av7110_bootarm(): "
274 "load_dram() failed\n");
275 return -1;
276 }
277
278 saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTLO);
279 mdelay(1);
280
281 dprintk(1, "load dpram code\n");
282 mwdebi(av7110, DEBISWAB, DPRAM_BASE, av7110->bin_dpram, av7110->size_dpram);
283
284 if (saa7146_wait_for_debi_done(av7110->dev, 1)) {
285 printk(KERN_ERR "dvb-ttpci: av7110_bootarm(): "
286 "saa7146_wait_for_debi_done() timed out after loading DRAM\n");
287 return -1;
288 }
289 saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTHI);
290 msleep(30); /* the firmware needs some time to initialize */
291
292 //ARM_ClearIrq(av7110);
293 ARM_ResetMailBox(av7110);
294 SAA7146_ISR_CLEAR(av7110->dev, MASK_19 | MASK_03);
295 SAA7146_IER_ENABLE(av7110->dev, MASK_03);
296
297 av7110->arm_errors = 0;
298 av7110->arm_ready = 1;
299 return 0;
300}
301
302
303/****************************************************************************
304 * DEBI command polling
305 ****************************************************************************/
306
307int av7110_wait_msgstate(struct av7110 *av7110, u16 flags)
308{
309 unsigned long start;
310 u32 stat;
311
312 if (FW_VERSION(av7110->arm_app) <= 0x261c) {
313 /* not supported by old firmware */
314 msleep(50);
315 return 0;
316 }
317
318 /* new firmware */
319 start = jiffies;
320 for (;;) {
321 if (down_interruptible(&av7110->dcomlock))
322 return -ERESTARTSYS;
323 stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2);
324 up(&av7110->dcomlock);
325 if ((stat & flags) == 0) {
326 break;
327 }
328 if (time_after(jiffies, start + ARM_WAIT_FREE)) {
329 printk(KERN_ERR "%s: timeout waiting for MSGSTATE %04x\n",
330 __FUNCTION__, stat & flags);
331 return -1;
332 }
333 msleep(1);
334 }
335 return 0;
336}
337
338int __av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length)
339{
340 int i;
341 unsigned long start;
342 char *type = NULL;
343 u16 flags[2] = {0, 0};
344 u32 stat;
345
346// dprintk(4, "%p\n", av7110);
347
348 if (!av7110->arm_ready) {
349 dprintk(1, "arm not ready.\n");
350 return -ENXIO;
351 }
352
353 start = jiffies;
354 while (rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2 )) {
355 msleep(1);
356 if (time_after(jiffies, start + ARM_WAIT_FREE)) {
357 printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for COMMAND idle\n", __FUNCTION__);
358 return -ETIMEDOUT;
359 }
360 }
361
362 wdebi(av7110, DEBINOSWAP, COM_IF_LOCK, 0xffff, 2);
363
364#ifndef _NOHANDSHAKE
365 start = jiffies;
366 while (rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2 )) {
367 msleep(1);
368 if (time_after(jiffies, start + ARM_WAIT_SHAKE)) {
369 printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for HANDSHAKE_REG\n", __FUNCTION__);
370 return -ETIMEDOUT;
371 }
372 }
373#endif
374
375 switch ((buf[0] >> 8) & 0xff) {
376 case COMTYPE_PIDFILTER:
377 case COMTYPE_ENCODER:
378 case COMTYPE_REC_PLAY:
379 case COMTYPE_MPEGDECODER:
380 type = "MSG";
381 flags[0] = GPMQOver;
382 flags[1] = GPMQFull;
383 break;
384 case COMTYPE_OSD:
385 type = "OSD";
386 flags[0] = OSDQOver;
387 flags[1] = OSDQFull;
388 break;
389 case COMTYPE_MISC:
390 if (FW_VERSION(av7110->arm_app) >= 0x261d) {
391 type = "MSG";
392 flags[0] = GPMQOver;
393 flags[1] = GPMQBusy;
394 }
395 break;
396 default:
397 break;
398 }
399
400 if (type != NULL) {
401 /* non-immediate COMMAND type */
402 start = jiffies;
403 for (;;) {
404 stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2);
405 if (stat & flags[0]) {
406 printk(KERN_ERR "%s: %s QUEUE overflow\n",
407 __FUNCTION__, type);
408 return -1;
409 }
410 if ((stat & flags[1]) == 0)
411 break;
412 if (time_after(jiffies, start + ARM_WAIT_FREE)) {
413 printk(KERN_ERR "%s: timeout waiting on busy %s QUEUE\n",
414 __FUNCTION__, type);
415 return -1;
416 }
417 msleep(1);
418 }
419 }
420
421 for (i = 2; i < length; i++)
422 wdebi(av7110, DEBINOSWAP, COMMAND + 2 * i, (u32) buf[i], 2);
423
424 if (length)
425 wdebi(av7110, DEBINOSWAP, COMMAND + 2, (u32) buf[1], 2);
426 else
427 wdebi(av7110, DEBINOSWAP, COMMAND + 2, 0, 2);
428
429 wdebi(av7110, DEBINOSWAP, COMMAND, (u32) buf[0], 2);
430
431 wdebi(av7110, DEBINOSWAP, COM_IF_LOCK, 0x0000, 2);
432
433#ifdef COM_DEBUG
434 start = jiffies;
435 while (rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2 )) {
436 msleep(1);
437 if (time_after(jiffies, start + ARM_WAIT_FREE)) {
438 printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for COMMAND to complete\n",
439 __FUNCTION__);
440 return -ETIMEDOUT;
441 }
442 }
443
444 stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2);
445 if (stat & GPMQOver) {
446 printk(KERN_ERR "dvb-ttpci: %s(): GPMQOver\n", __FUNCTION__);
447 return -ENOSPC;
448 }
449 else if (stat & OSDQOver) {
450 printk(KERN_ERR "dvb-ttpci: %s(): OSDQOver\n", __FUNCTION__);
451 return -ENOSPC;
452 }
453#endif
454
455 return 0;
456}
457
458int av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length)
459{
460 int ret;
461
462// dprintk(4, "%p\n", av7110);
463
464 if (!av7110->arm_ready) {
465 dprintk(1, "arm not ready.\n");
466 return -1;
467 }
468 if (down_interruptible(&av7110->dcomlock))
469 return -ERESTARTSYS;
470
471 ret = __av7110_send_fw_cmd(av7110, buf, length);
472 up(&av7110->dcomlock);
473 if (ret)
474 printk(KERN_ERR "dvb-ttpci: %s(): av7110_send_fw_cmd error %d\n",
475 __FUNCTION__, ret);
476 return ret;
477}
478
479int av7110_fw_cmd(struct av7110 *av7110, int type, int com, int num, ...)
480{
481 va_list args;
482 u16 buf[num + 2];
483 int i, ret;
484
485// dprintk(4, "%p\n", av7110);
486
487 buf[0] = ((type << 8) | com);
488 buf[1] = num;
489
490 if (num) {
491 va_start(args, num);
492 for (i = 0; i < num; i++)
493 buf[i + 2] = va_arg(args, u32);
494 va_end(args);
495 }
496
497 ret = av7110_send_fw_cmd(av7110, buf, num + 2);
498 if (ret)
499 printk(KERN_ERR "dvb-ttpci: av7110_fw_cmd error %d\n", ret);
500 return ret;
501}
502
503int av7110_send_ci_cmd(struct av7110 *av7110, u8 subcom, u8 *buf, u8 len)
504{
505 int i, ret;
506 u16 cmd[18] = { ((COMTYPE_COMMON_IF << 8) + subcom),
507 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
508
509 dprintk(4, "%p\n", av7110);
510
511 for(i = 0; i < len && i < 32; i++)
512 {
513 if(i % 2 == 0)
514 cmd[(i / 2) + 2] = (u16)(buf[i]) << 8;
515 else
516 cmd[(i / 2) + 2] |= buf[i];
517 }
518
519 ret = av7110_send_fw_cmd(av7110, cmd, 18);
520 if (ret)
521 printk(KERN_ERR "dvb-ttpci: av7110_send_ci_cmd error %d\n", ret);
522 return ret;
523}
524
525int av7110_fw_request(struct av7110 *av7110, u16 *request_buf,
526 int request_buf_len, u16 *reply_buf, int reply_buf_len)
527{
528 int err;
529 s16 i;
530 unsigned long start;
531#ifdef COM_DEBUG
532 u32 stat;
533#endif
534
535 dprintk(4, "%p\n", av7110);
536
537 if (!av7110->arm_ready) {
538 dprintk(1, "arm not ready.\n");
539 return -1;
540 }
541
542 if (down_interruptible(&av7110->dcomlock))
543 return -ERESTARTSYS;
544
545 if ((err = __av7110_send_fw_cmd(av7110, request_buf, request_buf_len)) < 0) {
546 up(&av7110->dcomlock);
547 printk(KERN_ERR "dvb-ttpci: av7110_fw_request error %d\n", err);
548 return err;
549 }
550
551 start = jiffies;
552 while (rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2)) {
553#ifdef _NOHANDSHAKE
554 msleep(1);
555#endif
556 if (time_after(jiffies, start + ARM_WAIT_FREE)) {
557 printk(KERN_ERR "%s: timeout waiting for COMMAND to complete\n", __FUNCTION__);
558 up(&av7110->dcomlock);
559 return -1;
560 }
561 }
562
563#ifndef _NOHANDSHAKE
564 start = jiffies;
565 while (rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2 )) {
566 msleep(1);
567 if (time_after(jiffies, start + ARM_WAIT_SHAKE)) {
568 printk(KERN_ERR "%s: timeout waiting for HANDSHAKE_REG\n", __FUNCTION__);
569 up(&av7110->dcomlock);
570 return -1;
571 }
572 }
573#endif
574
575#ifdef COM_DEBUG
576 stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2);
577 if (stat & GPMQOver) {
578 printk(KERN_ERR "%s: GPMQOver\n", __FUNCTION__);
579 up(&av7110->dcomlock);
580 return -1;
581 }
582 else if (stat & OSDQOver) {
583 printk(KERN_ERR "%s: OSDQOver\n", __FUNCTION__);
584 up(&av7110->dcomlock);
585 return -1;
586 }
587#endif
588
589 for (i = 0; i < reply_buf_len; i++)
590 reply_buf[i] = rdebi(av7110, DEBINOSWAP, COM_BUFF + 2 * i, 0, 2);
591
592 up(&av7110->dcomlock);
593 return 0;
594}
595
596int av7110_fw_query(struct av7110 *av7110, u16 tag, u16* buf, s16 length)
597{
598 int ret;
599 ret = av7110_fw_request(av7110, &tag, 0, buf, length);
600 if (ret)
601 printk(KERN_ERR "dvb-ttpci: av7110_fw_query error %d\n", ret);
602 return ret;
603}
604
605
606/****************************************************************************
607 * Firmware commands
608 ****************************************************************************/
609
610/* get version of the firmware ROM, RTSL, video ucode and ARM application */
611int av7110_firmversion(struct av7110 *av7110)
612{
613 u16 buf[20];
614 u16 tag = ((COMTYPE_REQUEST << 8) + ReqVersion);
615
616 dprintk(4, "%p\n", av7110);
617
618 if (av7110_fw_query(av7110, tag, buf, 16)) {
619 printk("dvb-ttpci: failed to boot firmware @ card %d\n",
620 av7110->dvb_adapter->num);
621 return -EIO;
622 }
623
624 av7110->arm_fw = (buf[0] << 16) + buf[1];
625 av7110->arm_rtsl = (buf[2] << 16) + buf[3];
626 av7110->arm_vid = (buf[4] << 16) + buf[5];
627 av7110->arm_app = (buf[6] << 16) + buf[7];
628 av7110->avtype = (buf[8] << 16) + buf[9];
629
630 printk("dvb-ttpci: info @ card %d: firm %08x, rtsl %08x, vid %08x, app %08x\n",
631 av7110->dvb_adapter->num, av7110->arm_fw,
632 av7110->arm_rtsl, av7110->arm_vid, av7110->arm_app);
633
634 /* print firmware capabilities */
635 if (FW_CI_LL_SUPPORT(av7110->arm_app))
636 printk("dvb-ttpci: firmware @ card %d supports CI link layer interface\n",
637 av7110->dvb_adapter->num);
638 else
639 printk("dvb-ttpci: no firmware support for CI link layer interface @ card %d\n",
640 av7110->dvb_adapter->num);
641
642 return 0;
643}
644
645
646int av7110_diseqc_send(struct av7110 *av7110, int len, u8 *msg, unsigned long burst)
647{
648 int i, ret;
649 u16 buf[18] = { ((COMTYPE_AUDIODAC << 8) + SendDiSEqC),
650 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
651
652 dprintk(4, "%p\n", av7110);
653
654 if (len > 10)
655 len = 10;
656
657 buf[1] = len + 2;
658 buf[2] = len;
659
660 if (burst != -1)
661 buf[3] = burst ? 0x01 : 0x00;
662 else
663 buf[3] = 0xffff;
664
665 for (i = 0; i < len; i++)
666 buf[i + 4] = msg[i];
667
668 if ((ret = av7110_send_fw_cmd(av7110, buf, 18)))
669 printk(KERN_ERR "dvb-ttpci: av7110_diseqc_send error %d\n", ret);
670
671 return 0;
672}
673
674
675#ifdef CONFIG_DVB_AV7110_OSD
676
677static inline int SetColorBlend(struct av7110 *av7110, u8 windownr)
678{
679 return av7110_fw_cmd(av7110, COMTYPE_OSD, SetCBlend, 1, windownr);
680}
681
682static inline int SetBlend_(struct av7110 *av7110, u8 windownr,
683 enum av7110_osd_palette_type colordepth, u16 index, u8 blending)
684{
685 return av7110_fw_cmd(av7110, COMTYPE_OSD, SetBlend, 4,
686 windownr, colordepth, index, blending);
687}
688
689static inline int SetColor_(struct av7110 *av7110, u8 windownr,
690 enum av7110_osd_palette_type colordepth, u16 index, u16 colorhi, u16 colorlo)
691{
692 return av7110_fw_cmd(av7110, COMTYPE_OSD, SetColor, 5,
693 windownr, colordepth, index, colorhi, colorlo);
694}
695
696static inline int SetFont(struct av7110 *av7110, u8 windownr, u8 fontsize,
697 u16 colorfg, u16 colorbg)
698{
699 return av7110_fw_cmd(av7110, COMTYPE_OSD, Set_Font, 4,
700 windownr, fontsize, colorfg, colorbg);
701}
702
703static int FlushText(struct av7110 *av7110)
704{
705 unsigned long start;
706
707 if (down_interruptible(&av7110->dcomlock))
708 return -ERESTARTSYS;
709 start = jiffies;
710 while (rdebi(av7110, DEBINOSWAP, BUFF1_BASE, 0, 2)) {
711 msleep(1);
712 if (time_after(jiffies, start + ARM_WAIT_OSD)) {
713 printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for BUFF1_BASE == 0\n",
714 __FUNCTION__);
715 up(&av7110->dcomlock);
716 return -1;
717 }
718 }
719 up(&av7110->dcomlock);
720 return 0;
721}
722
723static int WriteText(struct av7110 *av7110, u8 win, u16 x, u16 y, u8* buf)
724{
725 int i, ret;
726 unsigned long start;
727 int length = strlen(buf) + 1;
728 u16 cbuf[5] = { (COMTYPE_OSD << 8) + DText, 3, win, x, y };
729
730 if (down_interruptible(&av7110->dcomlock))
731 return -ERESTARTSYS;
732
733 start = jiffies;
734 while (rdebi(av7110, DEBINOSWAP, BUFF1_BASE, 0, 2)) {
735 msleep(1);
736 if (time_after(jiffies, start + ARM_WAIT_OSD)) {
737 printk(KERN_ERR "dvb-ttpci: %s: timeout waiting for BUFF1_BASE == 0\n",
738 __FUNCTION__);
739 up(&av7110->dcomlock);
740 return -1;
741 }
742 }
743#ifndef _NOHANDSHAKE
744 start = jiffies;
745 while (rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2)) {
746 msleep(1);
747 if (time_after(jiffies, start + ARM_WAIT_SHAKE)) {
748 printk(KERN_ERR "dvb-ttpci: %s: timeout waiting for HANDSHAKE_REG\n",
749 __FUNCTION__);
750 up(&av7110->dcomlock);
751 return -1;
752 }
753 }
754#endif
755 for (i = 0; i < length / 2; i++)
756 wdebi(av7110, DEBINOSWAP, BUFF1_BASE + i * 2,
757 swab16(*(u16 *)(buf + 2 * i)), 2);
758 if (length & 1)
759 wdebi(av7110, DEBINOSWAP, BUFF1_BASE + i * 2, 0, 2);
760 ret = __av7110_send_fw_cmd(av7110, cbuf, 5);
761 up(&av7110->dcomlock);
762 if (ret)
763 printk(KERN_ERR "dvb-ttpci: WriteText error %d\n", ret);
764 return ret;
765}
766
767static inline int DrawLine(struct av7110 *av7110, u8 windownr,
768 u16 x, u16 y, u16 dx, u16 dy, u16 color)
769{
770 return av7110_fw_cmd(av7110, COMTYPE_OSD, DLine, 6,
771 windownr, x, y, dx, dy, color);
772}
773
774static inline int DrawBlock(struct av7110 *av7110, u8 windownr,
775 u16 x, u16 y, u16 dx, u16 dy, u16 color)
776{
777 return av7110_fw_cmd(av7110, COMTYPE_OSD, DBox, 6,
778 windownr, x, y, dx, dy, color);
779}
780
781static inline int HideWindow(struct av7110 *av7110, u8 windownr)
782{
783 return av7110_fw_cmd(av7110, COMTYPE_OSD, WHide, 1, windownr);
784}
785
786static inline int MoveWindowRel(struct av7110 *av7110, u8 windownr, u16 x, u16 y)
787{
788 return av7110_fw_cmd(av7110, COMTYPE_OSD, WMoveD, 3, windownr, x, y);
789}
790
791static inline int MoveWindowAbs(struct av7110 *av7110, u8 windownr, u16 x, u16 y)
792{
793 return av7110_fw_cmd(av7110, COMTYPE_OSD, WMoveA, 3, windownr, x, y);
794}
795
796static inline int DestroyOSDWindow(struct av7110 *av7110, u8 windownr)
797{
798 return av7110_fw_cmd(av7110, COMTYPE_OSD, WDestroy, 1, windownr);
799}
800
801static inline int CreateOSDWindow(struct av7110 *av7110, u8 windownr,
802 osd_raw_window_t disptype,
803 u16 width, u16 height)
804{
805 return av7110_fw_cmd(av7110, COMTYPE_OSD, WCreate, 4,
806 windownr, disptype, width, height);
807}
808
809
810static enum av7110_osd_palette_type bpp2pal[8] = {
811 Pal1Bit, Pal2Bit, 0, Pal4Bit, 0, 0, 0, Pal8Bit
812};
813static osd_raw_window_t bpp2bit[8] = {
814 OSD_BITMAP1, OSD_BITMAP2, 0, OSD_BITMAP4, 0, 0, 0, OSD_BITMAP8
815};
816
817static inline int LoadBitmap(struct av7110 *av7110, u16 format,
818 u16 dx, u16 dy, int inc, u8 __user * data)
819{
820 int bpp;
821 int i;
822 int d, delta;
823 u8 c;
824 int ret;
825
826 dprintk(4, "%p\n", av7110);
827
828 ret = wait_event_interruptible_timeout(av7110->bmpq, av7110->bmp_state != BMP_LOADING, HZ);
829 if (ret == -ERESTARTSYS || ret == 0) {
830 printk("dvb-ttpci: warning: timeout waiting in LoadBitmap: %d, %d\n",
831 ret, av7110->bmp_state);
832 av7110->bmp_state = BMP_NONE;
833 return -1;
834 }
835 BUG_ON (av7110->bmp_state == BMP_LOADING);
836
837 av7110->bmp_state = BMP_LOADING;
838 if (format == OSD_BITMAP8) {
839 bpp=8; delta = 1;
840 } else if (format == OSD_BITMAP4) {
841 bpp=4; delta = 2;
842 } else if (format == OSD_BITMAP2) {
843 bpp=2; delta = 4;
844 } else if (format == OSD_BITMAP1) {
845 bpp=1; delta = 8;
846 } else {
847 av7110->bmp_state = BMP_NONE;
848 return -1;
849 }
850 av7110->bmplen = ((dx * dy * bpp + 7) & ~7) / 8;
851 av7110->bmpp = 0;
852 if (av7110->bmplen > 32768) {
853 av7110->bmp_state = BMP_NONE;
854 return -1;
855 }
856 for (i = 0; i < dy; i++) {
857 if (copy_from_user(av7110->bmpbuf + 1024 + i * dx, data + i * inc, dx)) {
858 av7110->bmp_state = BMP_NONE;
859 return -1;
860 }
861 }
862 if (format != OSD_BITMAP8) {
863 for (i = 0; i < dx * dy / delta; i++) {
864 c = ((u8 *)av7110->bmpbuf)[1024 + i * delta + delta - 1];
865 for (d = delta - 2; d >= 0; d--) {
866 c |= (((u8 *)av7110->bmpbuf)[1024 + i * delta + d]
867 << ((delta - d - 1) * bpp));
868 ((u8 *)av7110->bmpbuf)[1024 + i] = c;
869 }
870 }
871 }
872 av7110->bmplen += 1024;
873 dprintk(4, "av7110_fw_cmd: LoadBmp size %d\n", av7110->bmplen);
874 return av7110_fw_cmd(av7110, COMTYPE_OSD, LoadBmp, 3, format, dx, dy);
875}
876
877static int BlitBitmap(struct av7110 *av7110, u16 win, u16 x, u16 y, u16 trans)
878{
879 int ret;
880
881 dprintk(4, "%p\n", av7110);
882
883 BUG_ON (av7110->bmp_state == BMP_NONE);
884
885 ret = wait_event_interruptible_timeout(av7110->bmpq,
886 av7110->bmp_state != BMP_LOADING, 10*HZ);
887 if (ret == -ERESTARTSYS || ret == 0) {
888 printk("dvb-ttpci: warning: timeout waiting in BlitBitmap: %d, %d\n",
889 ret, av7110->bmp_state);
890 av7110->bmp_state = BMP_NONE;
891 return (ret == 0) ? -ETIMEDOUT : ret;
892 }
893
894 BUG_ON (av7110->bmp_state != BMP_LOADED);
895
896 return av7110_fw_cmd(av7110, COMTYPE_OSD, BlitBmp, 4, win, x, y, trans);
897}
898
899static inline int ReleaseBitmap(struct av7110 *av7110)
900{
901 dprintk(4, "%p\n", av7110);
902
903 if (av7110->bmp_state != BMP_LOADED)
904 return -1;
905 av7110->bmp_state = BMP_NONE;
906 return av7110_fw_cmd(av7110, COMTYPE_OSD, ReleaseBmp, 0);
907}
908
909static u32 RGB2YUV(u16 R, u16 G, u16 B)
910{
911 u16 y, u, v;
912 u16 Y, Cr, Cb;
913
914 y = R * 77 + G * 150 + B * 29; /* Luma=0.299R+0.587G+0.114B 0..65535 */
915 u = 2048 + B * 8 -(y >> 5); /* Cr 0..4095 */
916 v = 2048 + R * 8 -(y >> 5); /* Cb 0..4095 */
917
918 Y = y / 256;
919 Cb = u / 16;
920 Cr = v / 16;
921
922 return Cr | (Cb << 16) | (Y << 8);
923}
924
925static void OSDSetColor(struct av7110 *av7110, u8 color, u8 r, u8 g, u8 b, u8 blend)
926{
927 u16 ch, cl;
928 u32 yuv;
929
930 yuv = blend ? RGB2YUV(r,g,b) : 0;
931 cl = (yuv & 0xffff);
932 ch = ((yuv >> 16) & 0xffff);
933 SetColor_(av7110, av7110->osdwin, bpp2pal[av7110->osdbpp[av7110->osdwin]],
934 color, ch, cl);
935 SetBlend_(av7110, av7110->osdwin, bpp2pal[av7110->osdbpp[av7110->osdwin]],
936 color, ((blend >> 4) & 0x0f));
937}
938
939static int OSDSetPalette(struct av7110 *av7110, u32 __user * colors, u8 first, u8 last)
940{
941 int i;
942 int length = last - first + 1;
943
944 if (length * 4 > DATA_BUFF3_SIZE)
945 return -EINVAL;
946
947 for (i = 0; i < length; i++) {
948 u32 color, blend, yuv;
949
950 if (get_user(color, colors + i))
951 return -EFAULT;
952 blend = (color & 0xF0000000) >> 4;
953 yuv = blend ? RGB2YUV(color & 0xFF, (color >> 8) & 0xFF,
954 (color >> 16) & 0xFF) | blend : 0;
955 yuv = ((yuv & 0xFFFF0000) >> 16) | ((yuv & 0x0000FFFF) << 16);
956 wdebi(av7110, DEBINOSWAP, DATA_BUFF3_BASE + i * 4, yuv, 4);
957 }
958 return av7110_fw_cmd(av7110, COMTYPE_OSD, Set_Palette, 4,
959 av7110->osdwin,
960 bpp2pal[av7110->osdbpp[av7110->osdwin]],
961 first, last);
962}
963
964static int OSDSetBlock(struct av7110 *av7110, int x0, int y0,
965 int x1, int y1, int inc, u8 __user * data)
966{
967 uint w, h, bpp, bpl, size, lpb, bnum, brest;
968 int i;
969 int rc;
970
971 w = x1 - x0 + 1;
972 h = y1 - y0 + 1;
973 if (inc <= 0)
974 inc = w;
975 if (w <= 0 || w > 720 || h <= 0 || h > 576)
976 return -1;
977 bpp = av7110->osdbpp[av7110->osdwin] + 1;
978 bpl = ((w * bpp + 7) & ~7) / 8;
979 size = h * bpl;
980 lpb = (32 * 1024) / bpl;
981 bnum = size / (lpb * bpl);
982 brest = size - bnum * lpb * bpl;
983
984 for (i = 0; i < bnum; i++) {
985 rc = LoadBitmap(av7110, bpp2bit[av7110->osdbpp[av7110->osdwin]],
986 w, lpb, inc, data);
987 if (rc)
988 return rc;
989 rc = BlitBitmap(av7110, av7110->osdwin, x0, y0 + i * lpb, 0);
990 if (rc)
991 return rc;
992 data += lpb * inc;
993 }
994 if (brest) {
995 rc = LoadBitmap(av7110, bpp2bit[av7110->osdbpp[av7110->osdwin]],
996 w, brest / bpl, inc, data);
997 if (rc)
998 return rc;
999 rc = BlitBitmap(av7110, av7110->osdwin, x0, y0 + bnum * lpb, 0);
1000 if (rc)
1001 return rc;
1002 }
1003 ReleaseBitmap(av7110);
1004 return 0;
1005}
1006
1007int av7110_osd_cmd(struct av7110 *av7110, osd_cmd_t *dc)
1008{
1009 int ret;
1010
1011 ret = down_interruptible(&av7110->osd_sema);
1012 if (ret)
1013 return -ERESTARTSYS;
1014
1015 /* stupid, but OSD functions don't provide a return code anyway */
1016 ret = 0;
1017
1018 switch (dc->cmd) {
1019 case OSD_Close:
1020 DestroyOSDWindow(av7110, av7110->osdwin);
1021 goto out;
1022 case OSD_Open:
1023 av7110->osdbpp[av7110->osdwin] = (dc->color - 1) & 7;
1024 CreateOSDWindow(av7110, av7110->osdwin,
1025 bpp2bit[av7110->osdbpp[av7110->osdwin]],
1026 dc->x1 - dc->x0 + 1, dc->y1 - dc->y0 + 1);
1027 if (!dc->data) {
1028 MoveWindowAbs(av7110, av7110->osdwin, dc->x0, dc->y0);
1029 SetColorBlend(av7110, av7110->osdwin);
1030 }
1031 goto out;
1032 case OSD_Show:
1033 MoveWindowRel(av7110, av7110->osdwin, 0, 0);
1034 goto out;
1035 case OSD_Hide:
1036 HideWindow(av7110, av7110->osdwin);
1037 goto out;
1038 case OSD_Clear:
1039 DrawBlock(av7110, av7110->osdwin, 0, 0, 720, 576, 0);
1040 goto out;
1041 case OSD_Fill:
1042 DrawBlock(av7110, av7110->osdwin, 0, 0, 720, 576, dc->color);
1043 goto out;
1044 case OSD_SetColor:
1045 OSDSetColor(av7110, dc->color, dc->x0, dc->y0, dc->x1, dc->y1);
1046 goto out;
1047 case OSD_SetPalette:
1048 {
1049 if (FW_VERSION(av7110->arm_app) >= 0x2618) {
1050 ret = OSDSetPalette(av7110, dc->data, dc->color, dc->x0);
1051 goto out;
1052 } else {
1053 int i, len = dc->x0-dc->color+1;
1054 u8 __user *colors = (u8 __user *)dc->data;
1055 u8 r, g, b, blend;
1056
1057 for (i = 0; i<len; i++) {
1058 if (get_user(r, colors + i * 4) ||
1059 get_user(g, colors + i * 4 + 1) ||
1060 get_user(b, colors + i * 4 + 2) ||
1061 get_user(blend, colors + i * 4 + 3)) {
1062 ret = -EFAULT;
1063 goto out;
1064 }
1065 OSDSetColor(av7110, dc->color + i, r, g, b, blend);
1066 }
1067 }
1068 ret = 0;
1069 goto out;
1070 }
1071 case OSD_SetTrans:
1072 goto out;
1073 case OSD_SetPixel:
1074 DrawLine(av7110, av7110->osdwin,
1075 dc->x0, dc->y0, 0, 0, dc->color);
1076 goto out;
1077 case OSD_GetPixel:
1078 goto out;
1079 case OSD_SetRow:
1080 dc->y1 = dc->y0;
1081 /* fall through */
1082 case OSD_SetBlock:
1083 ret = OSDSetBlock(av7110, dc->x0, dc->y0, dc->x1, dc->y1, dc->color, dc->data);
1084 goto out;
1085 case OSD_FillRow:
1086 DrawBlock(av7110, av7110->osdwin, dc->x0, dc->y0,
1087 dc->x1-dc->x0+1, dc->y1, dc->color);
1088 goto out;
1089 case OSD_FillBlock:
1090 DrawBlock(av7110, av7110->osdwin, dc->x0, dc->y0,
1091 dc->x1 - dc->x0 + 1, dc->y1 - dc->y0 + 1, dc->color);
1092 goto out;
1093 case OSD_Line:
1094 DrawLine(av7110, av7110->osdwin,
1095 dc->x0, dc->y0, dc->x1 - dc->x0, dc->y1 - dc->y0, dc->color);
1096 goto out;
1097 case OSD_Query:
1098 goto out;
1099 case OSD_Test:
1100 goto out;
1101 case OSD_Text:
1102 {
1103 char textbuf[240];
1104
1105 if (strncpy_from_user(textbuf, dc->data, 240) < 0) {
1106 ret = -EFAULT;
1107 goto out;
1108 }
1109 textbuf[239] = 0;
1110 if (dc->x1 > 3)
1111 dc->x1 = 3;
1112 SetFont(av7110, av7110->osdwin, dc->x1,
1113 (u16) (dc->color & 0xffff), (u16) (dc->color >> 16));
1114 FlushText(av7110);
1115 WriteText(av7110, av7110->osdwin, dc->x0, dc->y0, textbuf);
1116 goto out;
1117 }
1118 case OSD_SetWindow:
1119 if (dc->x0 < 1 || dc->x0 > 7) {
1120 ret = -EINVAL;
1121 goto out;
1122 }
1123 av7110->osdwin = dc->x0;
1124 goto out;
1125 case OSD_MoveWindow:
1126 MoveWindowAbs(av7110, av7110->osdwin, dc->x0, dc->y0);
1127 SetColorBlend(av7110, av7110->osdwin);
1128 goto out;
1129 case OSD_OpenRaw:
1130 if (dc->color < OSD_BITMAP1 || dc->color > OSD_CURSOR) {
1131 ret = -EINVAL;
1132 goto out;
1133 }
1134 if (dc->color >= OSD_BITMAP1 && dc->color <= OSD_BITMAP8HR) {
1135 av7110->osdbpp[av7110->osdwin] = (1 << (dc->color & 3)) - 1;
1136 }
1137 else {
1138 av7110->osdbpp[av7110->osdwin] = 0;
1139 }
1140 CreateOSDWindow(av7110, av7110->osdwin, (osd_raw_window_t)dc->color,
1141 dc->x1 - dc->x0 + 1, dc->y1 - dc->y0 + 1);
1142 if (!dc->data) {
1143 MoveWindowAbs(av7110, av7110->osdwin, dc->x0, dc->y0);
1144 SetColorBlend(av7110, av7110->osdwin);
1145 }
1146 goto out;
1147 default:
1148 ret = -EINVAL;
1149 goto out;
1150 }
1151
1152out:
1153 up(&av7110->osd_sema);
1154 return ret;
1155}
1156
1157int av7110_osd_capability(struct av7110 *av7110, osd_cap_t *cap)
1158{
1159 switch (cap->cmd) {
1160 case OSD_CAP_MEMSIZE:
1161 if (FW_4M_SDRAM(av7110->arm_app))
1162 cap->val = 1000000;
1163 else
1164 cap->val = 92000;
1165 return 0;
1166 default:
1167 return -EINVAL;
1168 }
1169}
1170#endif /* CONFIG_DVB_AV7110_OSD */
diff --git a/drivers/media/dvb/ttpci/av7110_hw.h b/drivers/media/dvb/ttpci/av7110_hw.h
new file mode 100644
index 000000000000..bf901c624682
--- /dev/null
+++ b/drivers/media/dvb/ttpci/av7110_hw.h
@@ -0,0 +1,500 @@
1#ifndef _AV7110_HW_H_
2#define _AV7110_HW_H_
3
4#include "av7110.h"
5
6/* DEBI transfer mode defs */
7
8#define DEBINOSWAP 0x000e0000
9#define DEBISWAB 0x001e0000
10#define DEBISWAP 0x002e0000
11
12#define ARM_WAIT_FREE (HZ)
13#define ARM_WAIT_SHAKE (HZ/5)
14#define ARM_WAIT_OSD (HZ)
15
16
17enum av7110_bootstate
18{
19 BOOTSTATE_BUFFER_EMPTY = 0,
20 BOOTSTATE_BUFFER_FULL = 1,
21 BOOTSTATE_BOOT_COMPLETE = 2
22};
23
24enum av7110_type_rec_play_format
25{ RP_None,
26 AudioPES,
27 AudioMp2,
28 AudioPCM,
29 VideoPES,
30 AV_PES
31};
32
33enum av7110_osd_palette_type
34{
35 NoPalet = 0, /* No palette */
36 Pal1Bit = 2, /* 2 colors for 1 Bit Palette */
37 Pal2Bit = 4, /* 4 colors for 2 bit palette */
38 Pal4Bit = 16, /* 16 colors for 4 bit palette */
39 Pal8Bit = 256 /* 256 colors for 16 bit palette */
40};
41
42/* switch defines */
43#define SB_GPIO 3
44#define SB_OFF SAA7146_GPIO_OUTLO /* SlowBlank off (TV-Mode) */
45#define SB_ON SAA7146_GPIO_INPUT /* SlowBlank on (AV-Mode) */
46#define SB_WIDE SAA7146_GPIO_OUTHI /* SlowBlank 6V (16/9-Mode) (not implemented) */
47
48#define FB_GPIO 1
49#define FB_OFF SAA7146_GPIO_LO /* FastBlank off (CVBS-Mode) */
50#define FB_ON SAA7146_GPIO_OUTHI /* FastBlank on (RGB-Mode) */
51#define FB_LOOP SAA7146_GPIO_INPUT /* FastBlank loop-through (PC graphics ???) */
52
53enum av7110_video_output_mode
54{
55 NO_OUT = 0, /* disable analog output */
56 CVBS_RGB_OUT = 1,
57 CVBS_YC_OUT = 2,
58 YC_OUT = 3
59};
60
61/* firmware internal msg q status: */
62#define GPMQFull 0x0001 /* Main Message Queue Full */
63#define GPMQOver 0x0002 /* Main Message Queue Overflow */
64#define HPQFull 0x0004 /* High Priority Msg Queue Full */
65#define HPQOver 0x0008
66#define OSDQFull 0x0010 /* OSD Queue Full */
67#define OSDQOver 0x0020
68#define GPMQBusy 0x0040 /* Queue not empty, FW >= 261d */
69#define HPQBusy 0x0080
70#define OSDQBusy 0x0100
71
72/* hw section filter flags */
73#define SECTION_EIT 0x01
74#define SECTION_SINGLE 0x00
75#define SECTION_CYCLE 0x02
76#define SECTION_CONTINUOS 0x04
77#define SECTION_MODE 0x06
78#define SECTION_IPMPE 0x0C /* size up to 4k */
79#define SECTION_HIGH_SPEED 0x1C /* larger buffer */
80#define DATA_PIPING_FLAG 0x20 /* for Data Piping Filter */
81
82#define PBUFSIZE_NONE 0x0000
83#define PBUFSIZE_1P 0x0100
84#define PBUFSIZE_2P 0x0200
85#define PBUFSIZE_1K 0x0300
86#define PBUFSIZE_2K 0x0400
87#define PBUFSIZE_4K 0x0500
88#define PBUFSIZE_8K 0x0600
89#define PBUFSIZE_16K 0x0700
90#define PBUFSIZE_32K 0x0800
91
92
93/* firmware command codes */
94enum av7110_osd_command {
95 WCreate,
96 WDestroy,
97 WMoveD,
98 WMoveA,
99 WHide,
100 WTop,
101 DBox,
102 DLine,
103 DText,
104 Set_Font,
105 SetColor,
106 SetBlend,
107 SetWBlend,
108 SetCBlend,
109 SetNonBlend,
110 LoadBmp,
111 BlitBmp,
112 ReleaseBmp,
113 SetWTrans,
114 SetWNoTrans,
115 Set_Palette
116};
117
118enum av7110_pid_command {
119 MultiPID,
120 VideoPID,
121 AudioPID,
122 InitFilt,
123 FiltError,
124 NewVersion,
125 CacheError,
126 AddPIDFilter,
127 DelPIDFilter,
128 Scan,
129 SetDescr,
130 SetIR,
131 FlushTSQueue
132};
133
134enum av7110_mpeg_command {
135 SelAudChannels
136};
137
138enum av7110_audio_command {
139 AudioDAC,
140 CabADAC,
141 ON22K,
142 OFF22K,
143 MainSwitch,
144 ADSwitch,
145 SendDiSEqC,
146 SetRegister
147};
148
149enum av7110_request_command {
150 AudioState,
151 AudioBuffState,
152 VideoState1,
153 VideoState2,
154 VideoState3,
155 CrashCounter,
156 ReqVersion,
157 ReqVCXO,
158 ReqRegister,
159 ReqSecFilterError,
160 ReqSTC
161};
162
163enum av7110_encoder_command {
164 SetVidMode,
165 SetTestMode,
166 LoadVidCode,
167 SetMonitorType,
168 SetPanScanType,
169 SetFreezeMode
170};
171
172enum av7110_rec_play_state {
173 __Record,
174 __Stop,
175 __Play,
176 __Pause,
177 __Slow,
178 __FF_IP,
179 __Scan_I,
180 __Continue
181};
182
183enum av7110_fw_cmd_misc {
184 AV7110_FW_VIDEO_ZOOM = 1,
185 AV7110_FW_VIDEO_COMMAND,
186 AV7110_FW_AUDIO_COMMAND
187};
188
189enum av7110_command_type {
190 COMTYPE_NOCOM,
191 COMTYPE_PIDFILTER,
192 COMTYPE_MPEGDECODER,
193 COMTYPE_OSD,
194 COMTYPE_BMP,
195 COMTYPE_ENCODER,
196 COMTYPE_AUDIODAC,
197 COMTYPE_REQUEST,
198 COMTYPE_SYSTEM,
199 COMTYPE_REC_PLAY,
200 COMTYPE_COMMON_IF,
201 COMTYPE_PID_FILTER,
202 COMTYPE_PES,
203 COMTYPE_TS,
204 COMTYPE_VIDEO,
205 COMTYPE_AUDIO,
206 COMTYPE_CI_LL,
207 COMTYPE_MISC = 0x80
208};
209
210#define VID_NONE_PREF 0x00 /* No aspect ration processing preferred */
211#define VID_PAN_SCAN_PREF 0x01 /* Pan and Scan Display preferred */
212#define VID_VERT_COMP_PREF 0x02 /* Vertical compression display preferred */
213#define VID_VC_AND_PS_PREF 0x03 /* PanScan and vertical Compression if allowed */
214#define VID_CENTRE_CUT_PREF 0x05 /* PanScan with zero vector */
215
216/* MPEG video decoder commands */
217#define VIDEO_CMD_STOP 0x000e
218#define VIDEO_CMD_PLAY 0x000d
219#define VIDEO_CMD_FREEZE 0x0102
220#define VIDEO_CMD_FFWD 0x0016
221#define VIDEO_CMD_SLOW 0x0022
222
223/* MPEG audio decoder commands */
224#define AUDIO_CMD_MUTE 0x0001
225#define AUDIO_CMD_UNMUTE 0x0002
226#define AUDIO_CMD_PCM16 0x0010
227#define AUDIO_CMD_STEREO 0x0080
228#define AUDIO_CMD_MONO_L 0x0100
229#define AUDIO_CMD_MONO_R 0x0200
230#define AUDIO_CMD_SYNC_OFF 0x000e
231#define AUDIO_CMD_SYNC_ON 0x000f
232
233/* firmware data interface codes */
234#define DATA_NONE 0x00
235#define DATA_FSECTION 0x01
236#define DATA_IPMPE 0x02
237#define DATA_MPEG_RECORD 0x03
238#define DATA_DEBUG_MESSAGE 0x04
239#define DATA_COMMON_INTERFACE 0x05
240#define DATA_MPEG_PLAY 0x06
241#define DATA_BMP_LOAD 0x07
242#define DATA_IRCOMMAND 0x08
243#define DATA_PIPING 0x09
244#define DATA_STREAMING 0x0a
245#define DATA_CI_GET 0x0b
246#define DATA_CI_PUT 0x0c
247#define DATA_MPEG_VIDEO_EVENT 0x0d
248
249#define DATA_PES_RECORD 0x10
250#define DATA_PES_PLAY 0x11
251#define DATA_TS_RECORD 0x12
252#define DATA_TS_PLAY 0x13
253
254/* ancient CI command codes, only two are actually still used
255 * by the link level CI firmware */
256#define CI_CMD_ERROR 0x00
257#define CI_CMD_ACK 0x01
258#define CI_CMD_SYSTEM_READY 0x02
259#define CI_CMD_KEYPRESS 0x03
260#define CI_CMD_ON_TUNED 0x04
261#define CI_CMD_ON_SWITCH_PROGRAM 0x05
262#define CI_CMD_SECTION_ARRIVED 0x06
263#define CI_CMD_SECTION_TIMEOUT 0x07
264#define CI_CMD_TIME 0x08
265#define CI_CMD_ENTER_MENU 0x09
266#define CI_CMD_FAST_PSI 0x0a
267#define CI_CMD_GET_SLOT_INFO 0x0b
268
269#define CI_MSG_NONE 0x00
270#define CI_MSG_CI_INFO 0x01
271#define CI_MSG_MENU 0x02
272#define CI_MSG_LIST 0x03
273#define CI_MSG_TEXT 0x04
274#define CI_MSG_REQUEST_INPUT 0x05
275#define CI_MSG_INPUT_COMPLETE 0x06
276#define CI_MSG_LIST_MORE 0x07
277#define CI_MSG_MENU_MORE 0x08
278#define CI_MSG_CLOSE_MMI_IMM 0x09
279#define CI_MSG_SECTION_REQUEST 0x0a
280#define CI_MSG_CLOSE_FILTER 0x0b
281#define CI_PSI_COMPLETE 0x0c
282#define CI_MODULE_READY 0x0d
283#define CI_SWITCH_PRG_REPLY 0x0e
284#define CI_MSG_TEXT_MORE 0x0f
285
286#define CI_MSG_CA_PMT 0xe0
287#define CI_MSG_ERROR 0xf0
288
289
290/* base address of the dual ported RAM which serves as communication
291 * area between PCI bus and av7110,
292 * as seen by the DEBI bus of the saa7146 */
293#define DPRAM_BASE 0x4000
294
295/* boot protocol area */
296#define BOOT_STATE (DPRAM_BASE + 0x3F8)
297#define BOOT_SIZE (DPRAM_BASE + 0x3FA)
298#define BOOT_BASE (DPRAM_BASE + 0x3FC)
299#define BOOT_BLOCK (DPRAM_BASE + 0x400)
300#define BOOT_MAX_SIZE 0xc00
301
302/* firmware command protocol area */
303#define IRQ_STATE (DPRAM_BASE + 0x0F4)
304#define IRQ_STATE_EXT (DPRAM_BASE + 0x0F6)
305#define MSGSTATE (DPRAM_BASE + 0x0F8)
306#define FILT_STATE (DPRAM_BASE + 0x0FA)
307#define COMMAND (DPRAM_BASE + 0x0FC)
308#define COM_BUFF (DPRAM_BASE + 0x100)
309#define COM_BUFF_SIZE 0x20
310
311/* various data buffers */
312#define BUFF1_BASE (DPRAM_BASE + 0x120)
313#define BUFF1_SIZE 0xE0
314
315#define DATA_BUFF0_BASE (DPRAM_BASE + 0x200)
316#define DATA_BUFF0_SIZE 0x0800
317
318#define DATA_BUFF1_BASE (DATA_BUFF0_BASE+DATA_BUFF0_SIZE)
319#define DATA_BUFF1_SIZE 0x0800
320
321#define DATA_BUFF2_BASE (DATA_BUFF1_BASE+DATA_BUFF1_SIZE)
322#define DATA_BUFF2_SIZE 0x0800
323
324#define DATA_BUFF3_BASE (DATA_BUFF2_BASE+DATA_BUFF2_SIZE)
325#define DATA_BUFF3_SIZE 0x0400
326
327#define Reserved (DPRAM_BASE + 0x1E00)
328#define Reserved_SIZE 0x1C0
329
330
331/* firmware status area */
332#define STATUS_BASE (DPRAM_BASE + 0x1FC0)
333#define STATUS_SCR (STATUS_BASE + 0x00)
334#define STATUS_MODES (STATUS_BASE + 0x04)
335#define STATUS_LOOPS (STATUS_BASE + 0x08)
336
337#define STATUS_MPEG_WIDTH (STATUS_BASE + 0x0C)
338/* ((aspect_ratio & 0xf) << 12) | (height & 0xfff) */
339#define STATUS_MPEG_HEIGHT_AR (STATUS_BASE + 0x0E)
340
341/* firmware data protocol area */
342#define RX_TYPE (DPRAM_BASE + 0x1FE8)
343#define RX_LEN (DPRAM_BASE + 0x1FEA)
344#define TX_TYPE (DPRAM_BASE + 0x1FEC)
345#define TX_LEN (DPRAM_BASE + 0x1FEE)
346
347#define RX_BUFF (DPRAM_BASE + 0x1FF4)
348#define TX_BUFF (DPRAM_BASE + 0x1FF6)
349
350#define HANDSHAKE_REG (DPRAM_BASE + 0x1FF8)
351#define COM_IF_LOCK (DPRAM_BASE + 0x1FFA)
352
353#define IRQ_RX (DPRAM_BASE + 0x1FFC)
354#define IRQ_TX (DPRAM_BASE + 0x1FFE)
355
356/* used by boot protocol to load firmware into av7110 DRAM */
357#define DRAM_START_CODE 0x2e000404
358#define DRAM_MAX_CODE_SIZE 0x00100000
359
360/* saa7146 gpio lines */
361#define RESET_LINE 2
362#define DEBI_DONE_LINE 1
363#define ARM_IRQ_LINE 0
364
365
366
367extern void av7110_reset_arm(struct av7110 *av7110);
368extern int av7110_bootarm(struct av7110 *av7110);
369extern int av7110_firmversion(struct av7110 *av7110);
370#define FW_CI_LL_SUPPORT(arm_app) ((arm_app) & 0x80000000)
371#define FW_4M_SDRAM(arm_app) ((arm_app) & 0x40000000)
372#define FW_VERSION(arm_app) ((arm_app) & 0x0000FFFF)
373
374extern int av7110_wait_msgstate(struct av7110 *av7110, u16 flags);
375extern int av7110_fw_cmd(struct av7110 *av7110, int type, int com, int num, ...);
376extern int __av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length);
377extern int av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length);
378extern int av7110_send_ci_cmd(struct av7110 *av7110, u8 subcom, u8 *buf, u8 len);
379extern int av7110_fw_request(struct av7110 *av7110, u16 *request_buf,
380 int request_buf_len, u16 *reply_buf, int reply_buf_len);
381extern int av7110_fw_query(struct av7110 *av7110, u16 tag, u16* Buff, s16 length);
382
383
384/* DEBI (saa7146 data extension bus interface) access */
385extern int av7110_debiwrite(struct av7110 *av7110, u32 config,
386 int addr, u32 val, int count);
387extern u32 av7110_debiread(struct av7110 *av7110, u32 config,
388 int addr, int count);
389
390
391/* DEBI during interrupt */
392/* single word writes */
393static inline void iwdebi(struct av7110 *av7110, u32 config, int addr, u32 val, int count)
394{
395 av7110_debiwrite(av7110, config, addr, val, count);
396}
397
398/* buffer writes */
399static inline void mwdebi(struct av7110 *av7110, u32 config, int addr, char *val, int count)
400{
401 memcpy(av7110->debi_virt, val, count);
402 av7110_debiwrite(av7110, config, addr, 0, count);
403}
404
405static inline u32 irdebi(struct av7110 *av7110, u32 config, int addr, u32 val, int count)
406{
407 u32 res;
408
409 res=av7110_debiread(av7110, config, addr, count);
410 if (count<=4)
411 memcpy(av7110->debi_virt, (char *) &res, count);
412 return res;
413}
414
415/* DEBI outside interrupts, only for count <= 4! */
416static inline void wdebi(struct av7110 *av7110, u32 config, int addr, u32 val, int count)
417{
418 unsigned long flags;
419
420 spin_lock_irqsave(&av7110->debilock, flags);
421 av7110_debiwrite(av7110, config, addr, val, count);
422 spin_unlock_irqrestore(&av7110->debilock, flags);
423}
424
425static inline u32 rdebi(struct av7110 *av7110, u32 config, int addr, u32 val, int count)
426{
427 unsigned long flags;
428 u32 res;
429
430 spin_lock_irqsave(&av7110->debilock, flags);
431 res=av7110_debiread(av7110, config, addr, count);
432 spin_unlock_irqrestore(&av7110->debilock, flags);
433 return res;
434}
435
436/* handle mailbox registers of the dual ported RAM */
437static inline void ARM_ResetMailBox(struct av7110 *av7110)
438{
439 unsigned long flags;
440
441 spin_lock_irqsave(&av7110->debilock, flags);
442 av7110_debiread(av7110, DEBINOSWAP, IRQ_RX, 2);
443 av7110_debiwrite(av7110, DEBINOSWAP, IRQ_RX, 0, 2);
444 spin_unlock_irqrestore(&av7110->debilock, flags);
445}
446
447static inline void ARM_ClearMailBox(struct av7110 *av7110)
448{
449 iwdebi(av7110, DEBINOSWAP, IRQ_RX, 0, 2);
450}
451
452static inline void ARM_ClearIrq(struct av7110 *av7110)
453{
454 irdebi(av7110, DEBINOSWAP, IRQ_RX, 0, 2);
455}
456
457/****************************************************************************
458 * Firmware commands
459 ****************************************************************************/
460
461static inline int SendDAC(struct av7110 *av7110, u8 addr, u8 data)
462{
463 return av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, AudioDAC, 2, addr, data);
464}
465
466static inline void av7710_set_video_mode(struct av7110 *av7110, int mode)
467{
468 av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetVidMode, 1, mode);
469}
470
471static int inline vidcom(struct av7110 *av7110, u32 com, u32 arg)
472{
473 return av7110_fw_cmd(av7110, COMTYPE_MISC, AV7110_FW_VIDEO_COMMAND, 4,
474 (com>>16), (com&0xffff),
475 (arg>>16), (arg&0xffff));
476}
477
478static int inline audcom(struct av7110 *av7110, u32 com)
479{
480 return av7110_fw_cmd(av7110, COMTYPE_MISC, AV7110_FW_AUDIO_COMMAND, 2,
481 (com>>16), (com&0xffff));
482}
483
484static inline void Set22K(struct av7110 *av7110, int state)
485{
486 av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, (state ? ON22K : OFF22K), 0);
487}
488
489
490extern int av7110_diseqc_send(struct av7110 *av7110, int len, u8 *msg, unsigned long burst);
491
492
493#ifdef CONFIG_DVB_AV7110_OSD
494extern int av7110_osd_cmd(struct av7110 *av7110, osd_cmd_t *dc);
495extern int av7110_osd_capability(struct av7110 *av7110, osd_cap_t *cap);
496#endif /* CONFIG_DVB_AV7110_OSD */
497
498
499
500#endif /* _AV7110_HW_H_ */
diff --git a/drivers/media/dvb/ttpci/av7110_ipack.c b/drivers/media/dvb/ttpci/av7110_ipack.c
new file mode 100644
index 000000000000..246640741888
--- /dev/null
+++ b/drivers/media/dvb/ttpci/av7110_ipack.c
@@ -0,0 +1,403 @@
1#include "dvb_filter.h"
2#include "av7110_ipack.h"
3#include <linux/string.h> /* for memcpy() */
4#include <linux/vmalloc.h>
5
6
7void av7110_ipack_reset(struct ipack *p)
8{
9 p->found = 0;
10 p->cid = 0;
11 p->plength = 0;
12 p->flag1 = 0;
13 p->flag2 = 0;
14 p->hlength = 0;
15 p->mpeg = 0;
16 p->check = 0;
17 p->which = 0;
18 p->done = 0;
19 p->count = 0;
20}
21
22
23int av7110_ipack_init(struct ipack *p, int size,
24 void (*func)(u8 *buf, int size, void *priv))
25{
26 if (!(p->buf = vmalloc(size*sizeof(u8)))) {
27 printk ("Couldn't allocate memory for ipack\n");
28 return -ENOMEM;
29 }
30 p->size = size;
31 p->func = func;
32 p->repack_subids = 0;
33 av7110_ipack_reset(p);
34 return 0;
35}
36
37
38void av7110_ipack_free(struct ipack *p)
39{
40 vfree(p->buf);
41}
42
43
44static void send_ipack(struct ipack *p)
45{
46 int off;
47 struct dvb_audio_info ai;
48 int ac3_off = 0;
49 int streamid = 0;
50 int nframes = 0;
51 int f = 0;
52
53 switch (p->mpeg) {
54 case 2:
55 if (p->count < 10)
56 return;
57 p->buf[3] = p->cid;
58 p->buf[4] = (u8)(((p->count - 6) & 0xff00) >> 8);
59 p->buf[5] = (u8)((p->count - 6) & 0x00ff);
60 if (p->repack_subids && p->cid == PRIVATE_STREAM1) {
61 off = 9 + p->buf[8];
62 streamid = p->buf[off];
63 if ((streamid & 0xf8) == 0x80) {
64 ai.off = 0;
65 ac3_off = ((p->buf[off + 2] << 8)|
66 p->buf[off + 3]);
67 if (ac3_off < p->count)
68 f = dvb_filter_get_ac3info(p->buf + off + 3 + ac3_off,
69 p->count - ac3_off, &ai, 0);
70 if (!f) {
71 nframes = (p->count - off - 3 - ac3_off) /
72 ai.framesize + 1;
73 p->buf[off + 2] = (ac3_off >> 8) & 0xff;
74 p->buf[off + 3] = (ac3_off) & 0xff;
75 p->buf[off + 1] = nframes;
76 ac3_off += nframes * ai.framesize - p->count;
77 }
78 }
79 }
80 p->func(p->buf, p->count, p->data);
81
82 p->buf[6] = 0x80;
83 p->buf[7] = 0x00;
84 p->buf[8] = 0x00;
85 p->count = 9;
86 if (p->repack_subids && p->cid == PRIVATE_STREAM1
87 && (streamid & 0xf8) == 0x80) {
88 p->count += 4;
89 p->buf[9] = streamid;
90 p->buf[10] = (ac3_off >> 8) & 0xff;
91 p->buf[11] = (ac3_off) & 0xff;
92 p->buf[12] = 0;
93 }
94 break;
95
96 case 1:
97 if (p->count < 8)
98 return;
99 p->buf[3] = p->cid;
100 p->buf[4] = (u8)(((p->count - 6) & 0xff00) >> 8);
101 p->buf[5] = (u8)((p->count - 6) & 0x00ff);
102 p->func(p->buf, p->count, p->data);
103
104 p->buf[6] = 0x0f;
105 p->count = 7;
106 break;
107 }
108}
109
110
111void av7110_ipack_flush(struct ipack *p)
112{
113 if (p->plength != MMAX_PLENGTH - 6 || p->found <= 6)
114 return;
115 p->plength = p->found - 6;
116 p->found = 0;
117 send_ipack(p);
118 av7110_ipack_reset(p);
119}
120
121
122static void write_ipack(struct ipack *p, const u8 *data, int count)
123{
124 u8 headr[3] = { 0x00, 0x00, 0x01 };
125
126 if (p->count < 6) {
127 memcpy(p->buf, headr, 3);
128 p->count = 6;
129 }
130
131 if (p->count + count < p->size){
132 memcpy(p->buf+p->count, data, count);
133 p->count += count;
134 } else {
135 int rest = p->size - p->count;
136 memcpy(p->buf+p->count, data, rest);
137 p->count += rest;
138 send_ipack(p);
139 if (count - rest > 0)
140 write_ipack(p, data + rest, count - rest);
141 }
142}
143
144
145int av7110_ipack_instant_repack (const u8 *buf, int count, struct ipack *p)
146{
147 int l;
148 int c = 0;
149
150 while (c < count && (p->mpeg == 0 ||
151 (p->mpeg == 1 && p->found < 7) ||
152 (p->mpeg == 2 && p->found < 9))
153 && (p->found < 5 || !p->done)) {
154 switch (p->found) {
155 case 0:
156 case 1:
157 if (buf[c] == 0x00)
158 p->found++;
159 else
160 p->found = 0;
161 c++;
162 break;
163 case 2:
164 if (buf[c] == 0x01)
165 p->found++;
166 else if (buf[c] == 0)
167 p->found = 2;
168 else
169 p->found = 0;
170 c++;
171 break;
172 case 3:
173 p->cid = 0;
174 switch (buf[c]) {
175 case PROG_STREAM_MAP:
176 case PRIVATE_STREAM2:
177 case PROG_STREAM_DIR:
178 case ECM_STREAM :
179 case EMM_STREAM :
180 case PADDING_STREAM :
181 case DSM_CC_STREAM :
182 case ISO13522_STREAM:
183 p->done = 1;
184 /* fall through */
185 case PRIVATE_STREAM1:
186 case VIDEO_STREAM_S ... VIDEO_STREAM_E:
187 case AUDIO_STREAM_S ... AUDIO_STREAM_E:
188 p->found++;
189 p->cid = buf[c];
190 c++;
191 break;
192 default:
193 p->found = 0;
194 break;
195 }
196 break;
197
198 case 4:
199 if (count-c > 1) {
200 p->plen[0] = buf[c];
201 c++;
202 p->plen[1] = buf[c];
203 c++;
204 p->found += 2;
205 p->plength = (p->plen[0] << 8) | p->plen[1];
206 } else {
207 p->plen[0] = buf[c];
208 p->found++;
209 return count;
210 }
211 break;
212 case 5:
213 p->plen[1] = buf[c];
214 c++;
215 p->found++;
216 p->plength = (p->plen[0] << 8) | p->plen[1];
217 break;
218 case 6:
219 if (!p->done) {
220 p->flag1 = buf[c];
221 c++;
222 p->found++;
223 if ((p->flag1 & 0xc0) == 0x80)
224 p->mpeg = 2;
225 else {
226 p->hlength = 0;
227 p->which = 0;
228 p->mpeg = 1;
229 p->flag2 = 0;
230 }
231 }
232 break;
233
234 case 7:
235 if (!p->done && p->mpeg == 2) {
236 p->flag2 = buf[c];
237 c++;
238 p->found++;
239 }
240 break;
241
242 case 8:
243 if (!p->done && p->mpeg == 2) {
244 p->hlength = buf[c];
245 c++;
246 p->found++;
247 }
248 break;
249 }
250 }
251
252 if (c == count)
253 return count;
254
255 if (!p->plength)
256 p->plength = MMAX_PLENGTH - 6;
257
258 if (p->done || ((p->mpeg == 2 && p->found >= 9) ||
259 (p->mpeg == 1 && p->found >= 7))) {
260 switch (p->cid) {
261 case AUDIO_STREAM_S ... AUDIO_STREAM_E:
262 case VIDEO_STREAM_S ... VIDEO_STREAM_E:
263 case PRIVATE_STREAM1:
264 if (p->mpeg == 2 && p->found == 9) {
265 write_ipack(p, &p->flag1, 1);
266 write_ipack(p, &p->flag2, 1);
267 write_ipack(p, &p->hlength, 1);
268 }
269
270 if (p->mpeg == 1 && p->found == 7)
271 write_ipack(p, &p->flag1, 1);
272
273 if (p->mpeg == 2 && (p->flag2 & PTS_ONLY) &&
274 p->found < 14) {
275 while (c < count && p->found < 14) {
276 p->pts[p->found - 9] = buf[c];
277 write_ipack(p, buf + c, 1);
278 c++;
279 p->found++;
280 }
281 if (c == count)
282 return count;
283 }
284
285 if (p->mpeg == 1 && p->which < 2000) {
286
287 if (p->found == 7) {
288 p->check = p->flag1;
289 p->hlength = 1;
290 }
291
292 while (!p->which && c < count &&
293 p->check == 0xff){
294 p->check = buf[c];
295 write_ipack(p, buf + c, 1);
296 c++;
297 p->found++;
298 p->hlength++;
299 }
300
301 if (c == count)
302 return count;
303
304 if ((p->check & 0xc0) == 0x40 && !p->which) {
305 p->check = buf[c];
306 write_ipack(p, buf + c, 1);
307 c++;
308 p->found++;
309 p->hlength++;
310
311 p->which = 1;
312 if (c == count)
313 return count;
314 p->check = buf[c];
315 write_ipack(p, buf + c, 1);
316 c++;
317 p->found++;
318 p->hlength++;
319 p->which = 2;
320 if (c == count)
321 return count;
322 }
323
324 if (p->which == 1) {
325 p->check = buf[c];
326 write_ipack(p, buf + c, 1);
327 c++;
328 p->found++;
329 p->hlength++;
330 p->which = 2;
331 if (c == count)
332 return count;
333 }
334
335 if ((p->check & 0x30) && p->check != 0xff) {
336 p->flag2 = (p->check & 0xf0) << 2;
337 p->pts[0] = p->check;
338 p->which = 3;
339 }
340
341 if (c == count)
342 return count;
343 if (p->which > 2){
344 if ((p->flag2 & PTS_DTS_FLAGS) == PTS_ONLY) {
345 while (c < count && p->which < 7) {
346 p->pts[p->which - 2] = buf[c];
347 write_ipack(p, buf + c, 1);
348 c++;
349 p->found++;
350 p->which++;
351 p->hlength++;
352 }
353 if (c == count)
354 return count;
355 } else if ((p->flag2 & PTS_DTS_FLAGS) == PTS_DTS) {
356 while (c < count && p->which < 12) {
357 if (p->which < 7)
358 p->pts[p->which - 2] = buf[c];
359 write_ipack(p, buf + c, 1);
360 c++;
361 p->found++;
362 p->which++;
363 p->hlength++;
364 }
365 if (c == count)
366 return count;
367 }
368 p->which = 2000;
369 }
370
371 }
372
373 while (c < count && p->found < p->plength + 6) {
374 l = count - c;
375 if (l + p->found > p->plength + 6)
376 l = p->plength + 6 - p->found;
377 write_ipack(p, buf + c, l);
378 p->found += l;
379 c += l;
380 }
381 break;
382 }
383
384
385 if (p->done) {
386 if (p->found + count - c < p->plength + 6) {
387 p->found += count - c;
388 c = count;
389 } else {
390 c += p->plength + 6 - p->found;
391 p->found = p->plength + 6;
392 }
393 }
394
395 if (p->plength && p->found == p->plength + 6) {
396 send_ipack(p);
397 av7110_ipack_reset(p);
398 if (c < count)
399 av7110_ipack_instant_repack(buf + c, count - c, p);
400 }
401 }
402 return count;
403}
diff --git a/drivers/media/dvb/ttpci/av7110_ipack.h b/drivers/media/dvb/ttpci/av7110_ipack.h
new file mode 100644
index 000000000000..becf94d3fdfa
--- /dev/null
+++ b/drivers/media/dvb/ttpci/av7110_ipack.h
@@ -0,0 +1,12 @@
1#ifndef _AV7110_IPACK_H_
2#define _AV7110_IPACK_H_
3
4extern int av7110_ipack_init(struct ipack *p, int size,
5 void (*func)(u8 *buf, int size, void *priv));
6
7extern void av7110_ipack_reset(struct ipack *p);
8extern int av7110_ipack_instant_repack(const u8 *buf, int count, struct ipack *p);
9extern void av7110_ipack_free(struct ipack * p);
10extern void av7110_ipack_flush(struct ipack *p);
11
12#endif
diff --git a/drivers/media/dvb/ttpci/av7110_ir.c b/drivers/media/dvb/ttpci/av7110_ir.c
new file mode 100644
index 000000000000..6d2256f1e354
--- /dev/null
+++ b/drivers/media/dvb/ttpci/av7110_ir.c
@@ -0,0 +1,212 @@
1#include <linux/types.h>
2#include <linux/init.h>
3#include <linux/module.h>
4#include <linux/moduleparam.h>
5#include <linux/input.h>
6#include <linux/proc_fs.h>
7#include <asm/bitops.h>
8
9#include "av7110.h"
10
11#define UP_TIMEOUT (HZ/4)
12
13/* enable ir debugging by or'ing av7110_debug with 16 */
14
15static int ir_initialized;
16static struct input_dev input_dev;
17
18static u32 ir_config;
19
20static u16 key_map [256] = {
21 KEY_0, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7,
22 KEY_8, KEY_9, KEY_BACK, 0, KEY_POWER, KEY_MUTE, 0, KEY_INFO,
23 KEY_VOLUMEUP, KEY_VOLUMEDOWN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
24 KEY_CHANNELUP, KEY_CHANNELDOWN, 0, 0, 0, 0, 0, 0,
25 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
26 0, 0, 0, 0, KEY_TEXT, 0, 0, KEY_TV, 0, 0, 0, 0, 0, KEY_SETUP, 0, 0,
27 0, 0, 0, KEY_SUBTITLE, 0, 0, KEY_LANGUAGE, 0,
28 KEY_RADIO, 0, 0, 0, 0, KEY_EXIT, 0, 0,
29 KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT, KEY_OK, 0, 0, 0,
30 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, KEY_RED, KEY_GREEN, KEY_YELLOW,
31 KEY_BLUE, 0, 0, 0, 0, 0, 0, 0, KEY_MENU, KEY_LIST, 0, 0, 0, 0, 0, 0,
32 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
33 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
34 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
35 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
36 0, 0, 0, 0, KEY_UP, KEY_UP, KEY_DOWN, KEY_DOWN,
37 0, 0, 0, 0, KEY_EPG, 0, 0, 0,
38 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
39 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
40 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, KEY_VCR
41};
42
43
44static void av7110_emit_keyup(unsigned long data)
45{
46 if (!data || !test_bit(data, input_dev.key))
47 return;
48
49 input_event(&input_dev, EV_KEY, data, !!0);
50}
51
52
53static struct timer_list keyup_timer = { .function = av7110_emit_keyup };
54
55
56static void av7110_emit_key(u32 ircom)
57{
58 u8 data;
59 u8 addr;
60 static u16 old_toggle = 0;
61 u16 new_toggle;
62 u16 keycode;
63
64 /* extract device address and data */
65 if (ir_config & 0x0001) {
66 /* TODO RCMM: ? bits device address, 8 bits data */
67 data = ircom & 0xff;
68 addr = (ircom >> 8) & 0xff;
69 } else {
70 /* RC5: 5 bits device address, 6 bits data */
71 data = ircom & 0x3f;
72 addr = (ircom >> 6) & 0x1f;
73 }
74
75 keycode = key_map[data];
76
77 dprintk(16, "#########%08x######### addr %i data 0x%02x (keycode %i)\n",
78 ircom, addr, data, keycode);
79
80 /* check device address (if selected) */
81 if (ir_config & 0x4000)
82 if (addr != ((ir_config >> 16) & 0xff))
83 return;
84
85 if (!keycode) {
86 printk ("%s: unknown key 0x%02x!!\n", __FUNCTION__, data);
87 return;
88 }
89
90 if (ir_config & 0x0001)
91 new_toggle = 0; /* RCMM */
92 else
93 new_toggle = (ircom & 0x800); /* RC5 */
94
95 if (timer_pending(&keyup_timer)) {
96 del_timer(&keyup_timer);
97 if (keyup_timer.data != keycode || new_toggle != old_toggle) {
98 input_event(&input_dev, EV_KEY, keyup_timer.data, !!0);
99 input_event(&input_dev, EV_KEY, keycode, !0);
100 } else
101 input_event(&input_dev, EV_KEY, keycode, 2);
102
103 } else
104 input_event(&input_dev, EV_KEY, keycode, !0);
105
106 keyup_timer.expires = jiffies + UP_TIMEOUT;
107 keyup_timer.data = keycode;
108
109 add_timer(&keyup_timer);
110
111 old_toggle = new_toggle;
112}
113
114static void input_register_keys(void)
115{
116 int i;
117
118 memset(input_dev.keybit, 0, sizeof(input_dev.keybit));
119
120 for (i = 0; i < sizeof(key_map) / sizeof(key_map[0]); i++) {
121 if (key_map[i] > KEY_MAX)
122 key_map[i] = 0;
123 else if (key_map[i] > KEY_RESERVED)
124 set_bit(key_map[i], input_dev.keybit);
125 }
126}
127
128
129static void input_repeat_key(unsigned long data)
130{
131 /* dummy routine to disable autorepeat in the input driver */
132}
133
134
135static int av7110_ir_write_proc(struct file *file, const char __user *buffer,
136 unsigned long count, void *data)
137{
138 char *page;
139 int size = 4 + 256 * sizeof(u16);
140
141 if (count < size)
142 return -EINVAL;
143
144 page = (char *) vmalloc(size);
145 if (!page)
146 return -ENOMEM;
147
148 if (copy_from_user(page, buffer, size)) {
149 vfree(page);
150 return -EFAULT;
151 }
152
153 memcpy(&ir_config, page, 4);
154 memcpy(&key_map, page + 4, 256 * sizeof(u16));
155 vfree(page);
156 av7110_setup_irc_config(NULL, ir_config);
157 input_register_keys();
158 return count;
159}
160
161
162int __init av7110_ir_init(void)
163{
164 static struct proc_dir_entry *e;
165
166 if (ir_initialized)
167 return 0;
168
169 init_timer(&keyup_timer);
170 keyup_timer.data = 0;
171
172 input_dev.name = "DVB on-card IR receiver";
173
174 /**
175 * enable keys
176 */
177 set_bit(EV_KEY, input_dev.evbit);
178 set_bit(EV_REP, input_dev.evbit);
179
180 input_register_keys();
181
182 input_register_device(&input_dev);
183 input_dev.timer.function = input_repeat_key;
184
185 av7110_setup_irc_config(NULL, 0x0001);
186 av7110_register_irc_handler(av7110_emit_key);
187
188 e = create_proc_entry("av7110_ir", S_IFREG | S_IRUGO | S_IWUSR, NULL);
189 if (e) {
190 e->write_proc = av7110_ir_write_proc;
191 e->size = 4 + 256 * sizeof(u16);
192 }
193
194 ir_initialized = 1;
195 return 0;
196}
197
198
199void __exit av7110_ir_exit(void)
200{
201 if (ir_initialized == 0)
202 return;
203 del_timer_sync(&keyup_timer);
204 remove_proc_entry("av7110_ir", NULL);
205 av7110_unregister_irc_handler(av7110_emit_key);
206 input_unregister_device(&input_dev);
207 ir_initialized = 0;
208}
209
210//MODULE_AUTHOR("Holger Waechtler <holger@convergence.de>");
211//MODULE_LICENSE("GPL");
212
diff --git a/drivers/media/dvb/ttpci/av7110_v4l.c b/drivers/media/dvb/ttpci/av7110_v4l.c
new file mode 100644
index 000000000000..eb84fb08d95c
--- /dev/null
+++ b/drivers/media/dvb/ttpci/av7110_v4l.c
@@ -0,0 +1,771 @@
1/*
2 * av7110_v4l.c: av7110 video4linux interface for DVB and Siemens DVB-C analog module
3 *
4 * Copyright (C) 1999-2002 Ralph Metzler
5 * & Marcus Metzler for convergence integrated media GmbH
6 *
7 * originally based on code by:
8 * Copyright (C) 1998,1999 Christian Theiss <mistert@rz.fh-augsburg.de>
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
24 *
25 * the project's page is at http://www.linuxtv.org/dvb/
26 */
27
28#include <linux/kernel.h>
29#include <linux/sched.h>
30#include <linux/types.h>
31#include <linux/delay.h>
32#include <linux/fs.h>
33#include <linux/timer.h>
34#include <linux/poll.h>
35#include <linux/byteorder/swabb.h>
36#include <linux/smp_lock.h>
37
38#include "av7110.h"
39#include "av7110_hw.h"
40#include "av7110_av.h"
41
42int msp_writereg(struct av7110 *av7110, u8 dev, u16 reg, u16 val)
43{
44 u8 msg[5] = { dev, reg >> 8, reg & 0xff, val >> 8 , val & 0xff };
45 struct i2c_msg msgs = { .flags = 0, .addr = 0x40, .len = 5, .buf = msg };
46
47 if (i2c_transfer(&av7110->i2c_adap, &msgs, 1) != 1) {
48 dprintk(1, "dvb-ttpci: failed @ card %d, %u = %u\n",
49 av7110->dvb_adapter->num, reg, val);
50 return -EIO;
51 }
52 return 0;
53}
54
55int msp_readreg(struct av7110 *av7110, u8 dev, u16 reg, u16 *val)
56{
57 u8 msg1[3] = { dev, reg >> 8, reg & 0xff };
58 u8 msg2[2];
59 struct i2c_msg msgs[2] = {
60 { .flags = 0, .addr = 0x40, .len = 3, .buf = msg1 },
61 { .flags = I2C_M_RD, .addr = 0x40, .len = 2, .buf = msg2 }
62 };
63
64 if (i2c_transfer(&av7110->i2c_adap, &msgs[0], 2) != 2) {
65 dprintk(1, "dvb-ttpci: failed @ card %d, %u\n",
66 av7110->dvb_adapter->num, reg);
67 return -EIO;
68 }
69 *val = (msg2[0] << 8) | msg2[1];
70 return 0;
71}
72
73static struct v4l2_input inputs[2] = {
74 {
75 .index = 0,
76 .name = "DVB",
77 .type = V4L2_INPUT_TYPE_CAMERA,
78 .audioset = 1,
79 .tuner = 0, /* ignored */
80 .std = V4L2_STD_PAL_BG|V4L2_STD_NTSC_M,
81 .status = 0,
82 }, {
83 .index = 1,
84 .name = "Television",
85 .type = V4L2_INPUT_TYPE_TUNER,
86 .audioset = 2,
87 .tuner = 0,
88 .std = V4L2_STD_PAL_BG|V4L2_STD_NTSC_M,
89 .status = 0,
90 }
91};
92
93static int ves1820_writereg(struct saa7146_dev *dev, u8 addr, u8 reg, u8 data)
94{
95 u8 buf[] = { 0x00, reg, data };
96 struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = buf, .len = 3 };
97
98 dprintk(4, "dev: %p\n", dev);
99
100 if (1 != saa7146_i2c_transfer(dev, &msg, 1, 1))
101 return -1;
102 return 0;
103}
104
105static int stv0297_writereg(struct saa7146_dev *dev, u8 addr, u8 reg, u8 data)
106{
107 u8 buf [] = { reg, data };
108 struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = buf, .len = 2 };
109
110 if (1 != saa7146_i2c_transfer(dev, &msg, 1, 1))
111 return -1;
112 return 0;
113}
114
115
116static int tuner_write(struct saa7146_dev *dev, u8 addr, u8 data [4])
117{
118 struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = data, .len = 4 };
119
120 dprintk(4, "dev: %p\n", dev);
121
122 if (1 != saa7146_i2c_transfer(dev, &msg, 1, 1))
123 return -1;
124 return 0;
125}
126
127static int ves1820_set_tv_freq(struct saa7146_dev *dev, u32 freq)
128{
129 u32 div;
130 u8 config;
131 u8 buf[4];
132
133 dprintk(4, "freq: 0x%08x\n", freq);
134
135 /* magic number: 614. tuning with the frequency given by v4l2
136 is always off by 614*62.5 = 38375 kHz...*/
137 div = freq + 614;
138
139 buf[0] = (div >> 8) & 0x7f;
140 buf[1] = div & 0xff;
141 buf[2] = 0x8e;
142
143 if (freq < (u32) (16 * 168.25))
144 config = 0xa0;
145 else if (freq < (u32) (16 * 447.25))
146 config = 0x90;
147 else
148 config = 0x30;
149 config &= ~0x02;
150
151 buf[3] = config;
152
153 return tuner_write(dev, 0x61, buf);
154}
155
156static int stv0297_set_tv_freq(struct saa7146_dev *dev, u32 freq)
157{
158 u32 div;
159 u8 data[4];
160
161 div = (freq + 38900000 + 31250) / 62500;
162
163 data[0] = (div >> 8) & 0x7f;
164 data[1] = div & 0xff;
165 data[2] = 0xce;
166
167 if (freq < 45000000)
168 return -EINVAL;
169 else if (freq < 137000000)
170 data[3] = 0x01;
171 else if (freq < 403000000)
172 data[3] = 0x02;
173 else if (freq < 860000000)
174 data[3] = 0x04;
175 else
176 return -EINVAL;
177
178 stv0297_writereg(dev, 0x1C, 0x87, 0x78);
179 stv0297_writereg(dev, 0x1C, 0x86, 0xc8);
180 return tuner_write(dev, 0x63, data);
181}
182
183
184
185static struct saa7146_standard analog_standard[];
186static struct saa7146_standard dvb_standard[];
187static struct saa7146_standard standard[];
188
189static struct v4l2_audio msp3400_v4l2_audio = {
190 .index = 0,
191 .name = "Television",
192 .capability = V4L2_AUDCAP_STEREO
193};
194
195static int av7110_dvb_c_switch(struct saa7146_fh *fh)
196{
197 struct saa7146_dev *dev = fh->dev;
198 struct saa7146_vv *vv = dev->vv_data;
199 struct av7110 *av7110 = (struct av7110*)dev->ext_priv;
200 u16 adswitch;
201 int source, sync, err;
202
203 dprintk(4, "%p\n", av7110);
204
205 if ((vv->video_status & STATUS_OVERLAY) != 0) {
206 vv->ov_suspend = vv->video_fh;
207 err = saa7146_stop_preview(vv->video_fh); /* side effect: video_status is now 0, video_fh is NULL */
208 if (err != 0) {
209 dprintk(2, "suspending video failed\n");
210 vv->ov_suspend = NULL;
211 }
212 }
213
214 if (0 != av7110->current_input) {
215 adswitch = 1;
216 source = SAA7146_HPS_SOURCE_PORT_B;
217 sync = SAA7146_HPS_SYNC_PORT_B;
218 memcpy(standard, analog_standard, sizeof(struct saa7146_standard) * 2);
219 dprintk(1, "switching to analog TV\n");
220 msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0000); // loudspeaker source
221 msp_writereg(av7110, MSP_WR_DSP, 0x0009, 0x0000); // headphone source
222 msp_writereg(av7110, MSP_WR_DSP, 0x000a, 0x0000); // SCART 1 source
223 msp_writereg(av7110, MSP_WR_DSP, 0x000e, 0x3000); // FM matrix, mono
224 msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x4f00); // loudspeaker + headphone
225 msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x4f00); // SCART 1 volume
226
227 if (av7110->analog_tuner_flags & ANALOG_TUNER_VES1820) {
228 if (ves1820_writereg(dev, 0x09, 0x0f, 0x60))
229 dprintk(1, "setting band in demodulator failed.\n");
230 } else if (av7110->analog_tuner_flags & ANALOG_TUNER_STV0297) {
231 saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); // TDA9198 pin9(STD)
232 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI); // TDA9198 pin30(VIF)
233 }
234 } else {
235 adswitch = 0;
236 source = SAA7146_HPS_SOURCE_PORT_A;
237 sync = SAA7146_HPS_SYNC_PORT_A;
238 memcpy(standard, dvb_standard, sizeof(struct saa7146_standard) * 2);
239 dprintk(1, "switching DVB mode\n");
240 msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0220); // loudspeaker source
241 msp_writereg(av7110, MSP_WR_DSP, 0x0009, 0x0220); // headphone source
242 msp_writereg(av7110, MSP_WR_DSP, 0x000a, 0x0220); // SCART 1 source
243 msp_writereg(av7110, MSP_WR_DSP, 0x000e, 0x3000); // FM matrix, mono
244 msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x7f00); // loudspeaker + headphone
245 msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x7f00); // SCART 1 volume
246
247 if (av7110->analog_tuner_flags & ANALOG_TUNER_VES1820) {
248 if (ves1820_writereg(dev, 0x09, 0x0f, 0x20))
249 dprintk(1, "setting band in demodulator failed.\n");
250 } else if (av7110->analog_tuner_flags & ANALOG_TUNER_STV0297) {
251 saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTLO); // TDA9198 pin9(STD)
252 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); // TDA9198 pin30(VIF)
253 }
254 }
255
256 /* hmm, this does not do anything!? */
257 if (av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, ADSwitch, 1, adswitch))
258 dprintk(1, "ADSwitch error\n");
259
260 saa7146_set_hps_source_and_sync(dev, source, sync);
261
262 if (vv->ov_suspend != NULL) {
263 saa7146_start_preview(vv->ov_suspend);
264 vv->ov_suspend = NULL;
265 }
266
267 return 0;
268}
269
270static int av7110_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
271{
272 struct saa7146_dev *dev = fh->dev;
273 struct av7110 *av7110 = (struct av7110*) dev->ext_priv;
274 dprintk(4, "saa7146_dev: %p\n", dev);
275
276 switch (cmd) {
277 case VIDIOC_G_TUNER:
278 {
279 struct v4l2_tuner *t = arg;
280 u16 stereo_det;
281 s8 stereo;
282
283 dprintk(2, "VIDIOC_G_TUNER: %d\n", t->index);
284
285 if (!av7110->analog_tuner_flags || t->index != 0)
286 return -EINVAL;
287
288 memset(t, 0, sizeof(*t));
289 strcpy(t->name, "Television");
290
291 t->type = V4L2_TUNER_ANALOG_TV;
292 t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO |
293 V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
294 t->rangelow = 772; /* 48.25 MHZ / 62.5 kHz = 772, see fi1216mk2-specs, page 2 */
295 t->rangehigh = 13684; /* 855.25 MHz / 62.5 kHz = 13684 */
296 /* FIXME: add the real signal strength here */
297 t->signal = 0xffff;
298 t->afc = 0;
299
300 // FIXME: standard / stereo detection is still broken
301 msp_readreg(av7110, MSP_RD_DEM, 0x007e, &stereo_det);
302 dprintk(1, "VIDIOC_G_TUNER: msp3400 TV standard detection: 0x%04x\n", stereo_det);
303
304 msp_readreg(av7110, MSP_RD_DSP, 0x0018, &stereo_det);
305 dprintk(1, "VIDIOC_G_TUNER: msp3400 stereo detection: 0x%04x\n", stereo_det);
306 stereo = (s8)(stereo_det >> 8);
307 if (stereo > 0x10) {
308 /* stereo */
309 t->rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO;
310 t->audmode = V4L2_TUNER_MODE_STEREO;
311 }
312 else if (stereo < -0x10) {
313 /* bilingual*/
314 t->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
315 t->audmode = V4L2_TUNER_MODE_LANG1;
316 }
317 else /* mono */
318 t->rxsubchans = V4L2_TUNER_SUB_MONO;
319
320 return 0;
321 }
322 case VIDIOC_S_TUNER:
323 {
324 struct v4l2_tuner *t = arg;
325 u16 fm_matrix, src;
326 dprintk(2, "VIDIOC_S_TUNER: %d\n", t->index);
327
328 if (!av7110->analog_tuner_flags || av7110->current_input != 1)
329 return -EINVAL;
330
331 switch (t->audmode) {
332 case V4L2_TUNER_MODE_STEREO:
333 dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_STEREO\n");
334 fm_matrix = 0x3001; // stereo
335 src = 0x0020;
336 break;
337 case V4L2_TUNER_MODE_LANG1:
338 dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG1\n");
339 fm_matrix = 0x3000; // mono
340 src = 0x0000;
341 break;
342 case V4L2_TUNER_MODE_LANG2:
343 dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG2\n");
344 fm_matrix = 0x3000; // mono
345 src = 0x0010;
346 break;
347 default: /* case V4L2_TUNER_MODE_MONO: {*/
348 dprintk(2, "VIDIOC_S_TUNER: TDA9840_SET_MONO\n");
349 fm_matrix = 0x3000; // mono
350 src = 0x0030;
351 break;
352 }
353 msp_writereg(av7110, MSP_WR_DSP, 0x000e, fm_matrix);
354 msp_writereg(av7110, MSP_WR_DSP, 0x0008, src);
355 msp_writereg(av7110, MSP_WR_DSP, 0x0009, src);
356 msp_writereg(av7110, MSP_WR_DSP, 0x000a, src);
357 return 0;
358 }
359 case VIDIOC_G_FREQUENCY:
360 {
361 struct v4l2_frequency *f = arg;
362
363 dprintk(2, "VIDIOC_G_FREQ: freq:0x%08x.\n", f->frequency);
364
365 if (!av7110->analog_tuner_flags || av7110->current_input != 1)
366 return -EINVAL;
367
368 memset(f, 0, sizeof(*f));
369 f->type = V4L2_TUNER_ANALOG_TV;
370 f->frequency = av7110->current_freq;
371 return 0;
372 }
373 case VIDIOC_S_FREQUENCY:
374 {
375 struct v4l2_frequency *f = arg;
376
377 dprintk(2, "VIDIOC_S_FREQUENCY: freq:0x%08x.\n", f->frequency);
378
379 if (!av7110->analog_tuner_flags || av7110->current_input != 1)
380 return -EINVAL;
381
382 if (V4L2_TUNER_ANALOG_TV != f->type)
383 return -EINVAL;
384
385 msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0xffe0); // fast mute
386 msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0xffe0);
387
388 /* tune in desired frequency */
389 if (av7110->analog_tuner_flags & ANALOG_TUNER_VES1820) {
390 ves1820_set_tv_freq(dev, f->frequency);
391 } else if (av7110->analog_tuner_flags & ANALOG_TUNER_STV0297) {
392 stv0297_set_tv_freq(dev, f->frequency);
393 }
394 av7110->current_freq = f->frequency;
395
396 msp_writereg(av7110, MSP_WR_DSP, 0x0015, 0x003f); // start stereo detection
397 msp_writereg(av7110, MSP_WR_DSP, 0x0015, 0x0000);
398 msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x4f00); // loudspeaker + headphone
399 msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x4f00); // SCART 1 volume
400 return 0;
401 }
402 case VIDIOC_ENUMINPUT:
403 {
404 struct v4l2_input *i = arg;
405
406 dprintk(2, "VIDIOC_ENUMINPUT: %d\n", i->index);
407
408 if (av7110->analog_tuner_flags) {
409 if (i->index < 0 || i->index >= 2)
410 return -EINVAL;
411 } else {
412 if (i->index != 0)
413 return -EINVAL;
414 }
415
416 memcpy(i, &inputs[i->index], sizeof(struct v4l2_input));
417
418 return 0;
419 }
420 case VIDIOC_G_INPUT:
421 {
422 int *input = (int *)arg;
423 *input = av7110->current_input;
424 dprintk(2, "VIDIOC_G_INPUT: %d\n", *input);
425 return 0;
426 }
427 case VIDIOC_S_INPUT:
428 {
429 int input = *(int *)arg;
430
431 dprintk(2, "VIDIOC_S_INPUT: %d\n", input);
432
433 if (!av7110->analog_tuner_flags)
434 return 0;
435
436 if (input < 0 || input >= 2)
437 return -EINVAL;
438
439 /* FIXME: switch inputs here */
440 av7110->current_input = input;
441 return av7110_dvb_c_switch(fh);
442 }
443 case VIDIOC_G_AUDIO:
444 {
445 struct v4l2_audio *a = arg;
446
447 dprintk(2, "VIDIOC_G_AUDIO: %d\n", a->index);
448 if (a->index != 0)
449 return -EINVAL;
450 memcpy(a, &msp3400_v4l2_audio, sizeof(struct v4l2_audio));
451 break;
452 }
453 case VIDIOC_S_AUDIO:
454 {
455 struct v4l2_audio *a = arg;
456 dprintk(2, "VIDIOC_S_AUDIO: %d\n", a->index);
457 break;
458 }
459 default:
460 printk("no such ioctl\n");
461 return -ENOIOCTLCMD;
462 }
463 return 0;
464}
465
466
467/****************************************************************************
468 * INITIALIZATION
469 ****************************************************************************/
470
471static struct saa7146_extension_ioctls ioctls[] = {
472 { VIDIOC_ENUMINPUT, SAA7146_EXCLUSIVE },
473 { VIDIOC_G_INPUT, SAA7146_EXCLUSIVE },
474 { VIDIOC_S_INPUT, SAA7146_EXCLUSIVE },
475 { VIDIOC_G_FREQUENCY, SAA7146_EXCLUSIVE },
476 { VIDIOC_S_FREQUENCY, SAA7146_EXCLUSIVE },
477 { VIDIOC_G_TUNER, SAA7146_EXCLUSIVE },
478 { VIDIOC_S_TUNER, SAA7146_EXCLUSIVE },
479 { VIDIOC_G_AUDIO, SAA7146_EXCLUSIVE },
480 { VIDIOC_S_AUDIO, SAA7146_EXCLUSIVE },
481 { 0, 0 }
482};
483
484static u8 saa7113_init_regs[] = {
485 0x02, 0xd0,
486 0x03, 0x23,
487 0x04, 0x00,
488 0x05, 0x00,
489 0x06, 0xe9,
490 0x07, 0x0d,
491 0x08, 0x98,
492 0x09, 0x02,
493 0x0a, 0x80,
494 0x0b, 0x40,
495 0x0c, 0x40,
496 0x0d, 0x00,
497 0x0e, 0x01,
498 0x0f, 0x7c,
499 0x10, 0x48,
500 0x11, 0x0c,
501 0x12, 0x8b,
502 0x13, 0x1a,
503 0x14, 0x00,
504 0x15, 0x00,
505 0x16, 0x00,
506 0x17, 0x00,
507 0x18, 0x00,
508 0x19, 0x00,
509 0x1a, 0x00,
510 0x1b, 0x00,
511 0x1c, 0x00,
512 0x1d, 0x00,
513 0x1e, 0x00,
514
515 0x41, 0x77,
516 0x42, 0x77,
517 0x43, 0x77,
518 0x44, 0x77,
519 0x45, 0x77,
520 0x46, 0x77,
521 0x47, 0x77,
522 0x48, 0x77,
523 0x49, 0x77,
524 0x4a, 0x77,
525 0x4b, 0x77,
526 0x4c, 0x77,
527 0x4d, 0x77,
528 0x4e, 0x77,
529 0x4f, 0x77,
530 0x50, 0x77,
531 0x51, 0x77,
532 0x52, 0x77,
533 0x53, 0x77,
534 0x54, 0x77,
535 0x55, 0x77,
536 0x56, 0x77,
537 0x57, 0xff,
538
539 0xff
540};
541
542
543static struct saa7146_ext_vv av7110_vv_data_st;
544static struct saa7146_ext_vv av7110_vv_data_c;
545
546int av7110_init_analog_module(struct av7110 *av7110)
547{
548 u16 version1, version2;
549
550 if (i2c_writereg(av7110, 0x80, 0x0, 0x80) != 1
551 || i2c_writereg(av7110, 0x80, 0x0, 0) != 1)
552 return -ENODEV;
553
554 printk("dvb-ttpci: DVB-C analog module @ card %d detected, initializing MSP3400\n",
555 av7110->dvb_adapter->num);
556 av7110->adac_type = DVB_ADAC_MSP;
557 msleep(100); // the probing above resets the msp...
558 msp_readreg(av7110, MSP_RD_DSP, 0x001e, &version1);
559 msp_readreg(av7110, MSP_RD_DSP, 0x001f, &version2);
560 dprintk(1, "dvb-ttpci: @ card %d MSP3400 version 0x%04x 0x%04x\n",
561 av7110->dvb_adapter->num, version1, version2);
562 msp_writereg(av7110, MSP_WR_DSP, 0x0013, 0x0c00);
563 msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x7f00); // loudspeaker + headphone
564 msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0220); // loudspeaker source
565 msp_writereg(av7110, MSP_WR_DSP, 0x0009, 0x0220); // headphone source
566 msp_writereg(av7110, MSP_WR_DSP, 0x0004, 0x7f00); // loudspeaker volume
567 msp_writereg(av7110, MSP_WR_DSP, 0x000a, 0x0220); // SCART 1 source
568 msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x7f00); // SCART 1 volume
569 msp_writereg(av7110, MSP_WR_DSP, 0x000d, 0x4800); // prescale SCART
570
571 if (i2c_writereg(av7110, 0x48, 0x01, 0x00)!=1) {
572 INFO(("saa7113 not accessible.\n"));
573 } else {
574 u8 *i = saa7113_init_regs;
575
576 if ((av7110->dev->pci->subsystem_vendor == 0x110a) && (av7110->dev->pci->subsystem_device == 0x0000)) {
577 /* Fujitsu/Siemens DVB-Cable */
578 av7110->analog_tuner_flags |= ANALOG_TUNER_VES1820;
579 } else if ((av7110->dev->pci->subsystem_vendor == 0x13c2) && (av7110->dev->pci->subsystem_device == 0x0002)) {
580 /* Hauppauge/TT DVB-C premium */
581 av7110->analog_tuner_flags |= ANALOG_TUNER_VES1820;
582 } else if ((av7110->dev->pci->subsystem_vendor == 0x13c2) && (av7110->dev->pci->subsystem_device == 0x000A)) {
583 /* Hauppauge/TT DVB-C premium */
584 av7110->analog_tuner_flags |= ANALOG_TUNER_STV0297;
585 }
586
587 /* setup for DVB by default */
588 if (av7110->analog_tuner_flags & ANALOG_TUNER_VES1820) {
589 if (ves1820_writereg(av7110->dev, 0x09, 0x0f, 0x20))
590 dprintk(1, "setting band in demodulator failed.\n");
591 } else if (av7110->analog_tuner_flags & ANALOG_TUNER_STV0297) {
592 saa7146_setgpio(av7110->dev, 1, SAA7146_GPIO_OUTLO); // TDA9198 pin9(STD)
593 saa7146_setgpio(av7110->dev, 3, SAA7146_GPIO_OUTLO); // TDA9198 pin30(VIF)
594 }
595
596 /* init the saa7113 */
597 while (*i != 0xff) {
598 if (i2c_writereg(av7110, 0x48, i[0], i[1]) != 1) {
599 dprintk(1, "saa7113 initialization failed @ card %d", av7110->dvb_adapter->num);
600 break;
601 }
602 i += 2;
603 }
604 /* setup msp for analog sound: B/G Dual-FM */
605 msp_writereg(av7110, MSP_WR_DEM, 0x00bb, 0x02d0); // AD_CV
606 msp_writereg(av7110, MSP_WR_DEM, 0x0001, 3); // FIR1
607 msp_writereg(av7110, MSP_WR_DEM, 0x0001, 18); // FIR1
608 msp_writereg(av7110, MSP_WR_DEM, 0x0001, 27); // FIR1
609 msp_writereg(av7110, MSP_WR_DEM, 0x0001, 48); // FIR1
610 msp_writereg(av7110, MSP_WR_DEM, 0x0001, 66); // FIR1
611 msp_writereg(av7110, MSP_WR_DEM, 0x0001, 72); // FIR1
612 msp_writereg(av7110, MSP_WR_DEM, 0x0005, 4); // FIR2
613 msp_writereg(av7110, MSP_WR_DEM, 0x0005, 64); // FIR2
614 msp_writereg(av7110, MSP_WR_DEM, 0x0005, 0); // FIR2
615 msp_writereg(av7110, MSP_WR_DEM, 0x0005, 3); // FIR2
616 msp_writereg(av7110, MSP_WR_DEM, 0x0005, 18); // FIR2
617 msp_writereg(av7110, MSP_WR_DEM, 0x0005, 27); // FIR2
618 msp_writereg(av7110, MSP_WR_DEM, 0x0005, 48); // FIR2
619 msp_writereg(av7110, MSP_WR_DEM, 0x0005, 66); // FIR2
620 msp_writereg(av7110, MSP_WR_DEM, 0x0005, 72); // FIR2
621 msp_writereg(av7110, MSP_WR_DEM, 0x0083, 0xa000); // MODE_REG
622 msp_writereg(av7110, MSP_WR_DEM, 0x0093, 0x00aa); // DCO1_LO 5.74MHz
623 msp_writereg(av7110, MSP_WR_DEM, 0x009b, 0x04fc); // DCO1_HI
624 msp_writereg(av7110, MSP_WR_DEM, 0x00a3, 0x038e); // DCO2_LO 5.5MHz
625 msp_writereg(av7110, MSP_WR_DEM, 0x00ab, 0x04c6); // DCO2_HI
626 msp_writereg(av7110, MSP_WR_DEM, 0x0056, 0); // LOAD_REG 1/2
627 }
628
629 memcpy(standard, dvb_standard, sizeof(struct saa7146_standard) * 2);
630 /* set dd1 stream a & b */
631 saa7146_write(av7110->dev, DD1_STREAM_B, 0x00000000);
632 saa7146_write(av7110->dev, DD1_INIT, 0x03000700);
633 saa7146_write(av7110->dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
634
635 return 0;
636}
637
638int av7110_init_v4l(struct av7110 *av7110)
639{
640 struct saa7146_dev* dev = av7110->dev;
641 int ret;
642
643 /* special case DVB-C: these cards have an analog tuner
644 plus need some special handling, so we have separate
645 saa7146_ext_vv data for these... */
646 if (av7110->analog_tuner_flags)
647 ret = saa7146_vv_init(dev, &av7110_vv_data_c);
648 else
649 ret = saa7146_vv_init(dev, &av7110_vv_data_st);
650
651 if (ret) {
652 ERR(("cannot init capture device. skipping.\n"));
653 return -ENODEV;
654 }
655
656 if (saa7146_register_device(&av7110->v4l_dev, dev, "av7110", VFL_TYPE_GRABBER)) {
657 ERR(("cannot register capture device. skipping.\n"));
658 saa7146_vv_release(dev);
659 return -ENODEV;
660 }
661 if (av7110->analog_tuner_flags) {
662 if (saa7146_register_device(&av7110->vbi_dev, dev, "av7110", VFL_TYPE_VBI)) {
663 ERR(("cannot register vbi v4l2 device. skipping.\n"));
664 } else {
665 av7110->analog_tuner_flags |= ANALOG_TUNER_VBI;
666 }
667 }
668 return 0;
669}
670
671int av7110_exit_v4l(struct av7110 *av7110)
672{
673 saa7146_unregister_device(&av7110->v4l_dev, av7110->dev);
674 if (av7110->analog_tuner_flags & ANALOG_TUNER_VBI)
675 saa7146_unregister_device(&av7110->vbi_dev, av7110->dev);
676 return 0;
677}
678
679
680
681/* FIXME: these values are experimental values that look better than the
682 values from the latest "official" driver -- at least for me... (MiHu) */
683static struct saa7146_standard standard[] = {
684 {
685 .name = "PAL", .id = V4L2_STD_PAL_BG,
686 .v_offset = 0x15, .v_field = 288,
687 .h_offset = 0x48, .h_pixels = 708,
688 .v_max_out = 576, .h_max_out = 768,
689 }, {
690 .name = "NTSC", .id = V4L2_STD_NTSC,
691 .v_offset = 0x10, .v_field = 244,
692 .h_offset = 0x40, .h_pixels = 708,
693 .v_max_out = 480, .h_max_out = 640,
694 }
695};
696
697static struct saa7146_standard analog_standard[] = {
698 {
699 .name = "PAL", .id = V4L2_STD_PAL_BG,
700 .v_offset = 0x1b, .v_field = 288,
701 .h_offset = 0x08, .h_pixels = 708,
702 .v_max_out = 576, .h_max_out = 768,
703 }, {
704 .name = "NTSC", .id = V4L2_STD_NTSC,
705 .v_offset = 0x10, .v_field = 244,
706 .h_offset = 0x40, .h_pixels = 708,
707 .v_max_out = 480, .h_max_out = 640,
708 }
709};
710
711static struct saa7146_standard dvb_standard[] = {
712 {
713 .name = "PAL", .id = V4L2_STD_PAL_BG,
714 .v_offset = 0x14, .v_field = 288,
715 .h_offset = 0x48, .h_pixels = 708,
716 .v_max_out = 576, .h_max_out = 768,
717 }, {
718 .name = "NTSC", .id = V4L2_STD_NTSC,
719 .v_offset = 0x10, .v_field = 244,
720 .h_offset = 0x40, .h_pixels = 708,
721 .v_max_out = 480, .h_max_out = 640,
722 }
723};
724
725static int std_callback(struct saa7146_dev* dev, struct saa7146_standard *std)
726{
727 struct av7110 *av7110 = (struct av7110*) dev->ext_priv;
728
729 if (std->id == V4L2_STD_PAL) {
730 av7110->vidmode = VIDEO_MODE_PAL;
731 av7110_set_vidmode(av7110, av7110->vidmode);
732 }
733 else if (std->id == V4L2_STD_NTSC) {
734 av7110->vidmode = VIDEO_MODE_NTSC;
735 av7110_set_vidmode(av7110, av7110->vidmode);
736 }
737 else
738 return -1;
739
740 return 0;
741}
742
743
744static struct saa7146_ext_vv av7110_vv_data_st = {
745 .inputs = 1,
746 .audios = 1,
747 .capabilities = 0,
748 .flags = 0,
749
750 .stds = &standard[0],
751 .num_stds = ARRAY_SIZE(standard),
752 .std_callback = &std_callback,
753
754 .ioctls = &ioctls[0],
755 .ioctl = av7110_ioctl,
756};
757
758static struct saa7146_ext_vv av7110_vv_data_c = {
759 .inputs = 1,
760 .audios = 1,
761 .capabilities = V4L2_CAP_TUNER | V4L2_CAP_VBI_CAPTURE,
762 .flags = SAA7146_USE_PORT_B_FOR_VBI,
763
764 .stds = &standard[0],
765 .num_stds = ARRAY_SIZE(standard),
766 .std_callback = &std_callback,
767
768 .ioctls = &ioctls[0],
769 .ioctl = av7110_ioctl,
770};
771
diff --git a/drivers/media/dvb/ttpci/budget-av.c b/drivers/media/dvb/ttpci/budget-av.c
new file mode 100644
index 000000000000..14e963206b89
--- /dev/null
+++ b/drivers/media/dvb/ttpci/budget-av.c
@@ -0,0 +1,1014 @@
1/*
2 * budget-av.c: driver for the SAA7146 based Budget DVB cards
3 * with analog video in
4 *
5 * Compiled from various sources by Michael Hunold <michael@mihu.de>
6 *
7 * CI interface support (c) 2004 Olivier Gournet <ogournet@anevia.com> &
8 * Andrew de Quincey <adq_dvb@lidskialf.net>
9 *
10 * Copyright (C) 2002 Ralph Metzler <rjkm@metzlerbros.de>
11 *
12 * Copyright (C) 1999-2002 Ralph Metzler
13 * & Marcus Metzler for convergence integrated media GmbH
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
19 *
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 *
27 * You should have received a copy of the GNU General Public License
28 * along with this program; if not, write to the Free Software
29 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
30 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
31 *
32 *
33 * the project's page is at http://www.linuxtv.org/dvb/
34 */
35
36#include "budget.h"
37#include "stv0299.h"
38#include "tda10021.h"
39#include "tda1004x.h"
40#include <media/saa7146_vv.h>
41#include <linux/module.h>
42#include <linux/errno.h>
43#include <linux/slab.h>
44#include <linux/interrupt.h>
45#include <linux/input.h>
46#include <linux/spinlock.h>
47
48#include "dvb_ca_en50221.h"
49
50#define DEBICICAM 0x02420000
51
52struct budget_av {
53 struct budget budget;
54 struct video_device *vd;
55 int cur_input;
56 int has_saa7113;
57 struct tasklet_struct ciintf_irq_tasklet;
58 int slot_status;
59 struct dvb_ca_en50221 ca;
60};
61
62static int enable_ci = 0;
63
64
65/****************************************************************************
66 * INITIALIZATION
67 ****************************************************************************/
68
69static u8 i2c_readreg(struct i2c_adapter *i2c, u8 id, u8 reg)
70{
71 u8 mm1[] = { 0x00 };
72 u8 mm2[] = { 0x00 };
73 struct i2c_msg msgs[2];
74
75 msgs[0].flags = 0;
76 msgs[1].flags = I2C_M_RD;
77 msgs[0].addr = msgs[1].addr = id / 2;
78 mm1[0] = reg;
79 msgs[0].len = 1;
80 msgs[1].len = 1;
81 msgs[0].buf = mm1;
82 msgs[1].buf = mm2;
83
84 i2c_transfer(i2c, msgs, 2);
85
86 return mm2[0];
87}
88
89static int i2c_readregs(struct i2c_adapter *i2c, u8 id, u8 reg, u8 * buf, u8 len)
90{
91 u8 mm1[] = { reg };
92 struct i2c_msg msgs[2] = {
93 {.addr = id / 2,.flags = 0,.buf = mm1,.len = 1},
94 {.addr = id / 2,.flags = I2C_M_RD,.buf = buf,.len = len}
95 };
96
97 if (i2c_transfer(i2c, msgs, 2) != 2)
98 return -EIO;
99
100 return 0;
101}
102
103static int i2c_writereg(struct i2c_adapter *i2c, u8 id, u8 reg, u8 val)
104{
105 u8 msg[2] = { reg, val };
106 struct i2c_msg msgs;
107
108 msgs.flags = 0;
109 msgs.addr = id / 2;
110 msgs.len = 2;
111 msgs.buf = msg;
112 return i2c_transfer(i2c, &msgs, 1);
113}
114
115static int ciintf_read_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address)
116{
117 struct budget_av *budget_av = (struct budget_av *) ca->data;
118 int result;
119
120 if (slot != 0)
121 return -EINVAL;
122
123 saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTHI);
124 udelay(1);
125
126 result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, address & 0xfff, 1, 0, 0);
127
128 if (result == -ETIMEDOUT)
129 budget_av->slot_status = 0;
130 return result;
131}
132
133static int ciintf_write_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address, u8 value)
134{
135 struct budget_av *budget_av = (struct budget_av *) ca->data;
136 int result;
137
138 if (slot != 0)
139 return -EINVAL;
140
141 saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTHI);
142 udelay(1);
143
144 result = ttpci_budget_debiwrite(&budget_av->budget, DEBICICAM, address & 0xfff, 1, value, 0, 0);
145
146 if (result == -ETIMEDOUT)
147 budget_av->slot_status = 0;
148 return result;
149}
150
151static int ciintf_read_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address)
152{
153 struct budget_av *budget_av = (struct budget_av *) ca->data;
154 int result;
155
156 if (slot != 0)
157 return -EINVAL;
158
159 saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO);
160 udelay(1);
161
162 result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, address & 3, 1, 0, 0);
163
164 if (result == -ETIMEDOUT)
165 budget_av->slot_status = 0;
166 return result;
167}
168
169static int ciintf_write_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address, u8 value)
170{
171 struct budget_av *budget_av = (struct budget_av *) ca->data;
172 int result;
173
174 if (slot != 0)
175 return -EINVAL;
176
177 saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO);
178 udelay(1);
179
180 result = ttpci_budget_debiwrite(&budget_av->budget, DEBICICAM, address & 3, 1, value, 0, 0);
181
182 if (result == -ETIMEDOUT)
183 budget_av->slot_status = 0;
184 return result;
185}
186
187static int ciintf_slot_reset(struct dvb_ca_en50221 *ca, int slot)
188{
189 struct budget_av *budget_av = (struct budget_av *) ca->data;
190 struct saa7146_dev *saa = budget_av->budget.dev;
191 int max = 20;
192
193 if (slot != 0)
194 return -EINVAL;
195
196 dprintk(1, "ciintf_slot_reset\n");
197
198 /* reset the card */
199 saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTHI);
200 msleep(100);
201 saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO);
202
203 while (--max > 0 && ciintf_read_attribute_mem(ca, slot, 0) != 0x1d)
204 msleep(100);
205
206 ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB);
207 return 0;
208}
209
210static int ciintf_slot_shutdown(struct dvb_ca_en50221 *ca, int slot)
211{
212 struct budget_av *budget_av = (struct budget_av *) ca->data;
213 struct saa7146_dev *saa = budget_av->budget.dev;
214
215 if (slot != 0)
216 return -EINVAL;
217
218 dprintk(1, "ciintf_slot_shutdown\n");
219
220 ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB);
221 budget_av->slot_status = 0;
222 return 0;
223}
224
225static int ciintf_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot)
226{
227 struct budget_av *budget_av = (struct budget_av *) ca->data;
228 struct saa7146_dev *saa = budget_av->budget.dev;
229
230 if (slot != 0)
231 return -EINVAL;
232
233 dprintk(1, "ciintf_slot_ts_enable: %d\n", budget_av->slot_status);
234
235 ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTA);
236 return 0;
237}
238
239static int ciintf_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open)
240{
241 struct budget_av *budget_av = (struct budget_av *) ca->data;
242 struct saa7146_dev *saa = budget_av->budget.dev;
243 int cam = 0;
244
245 if (slot != 0)
246 return -EINVAL;
247
248 if (!budget_av->slot_status) {
249 saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT);
250 udelay(1);
251 cam = saa7146_read(saa, PSR) & MASK_06;
252 saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO);
253
254 if (cam)
255 budget_av->slot_status = 1;
256 } else if (!open) {
257 saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO);
258 if (ttpci_budget_debiread(&budget_av->budget, DEBICICAM, 0, 1, 0, 1) == -ETIMEDOUT)
259 budget_av->slot_status = 0;
260 }
261
262 if (budget_av->slot_status == 1)
263 return DVB_CA_EN50221_POLL_CAM_PRESENT | DVB_CA_EN50221_POLL_CAM_READY;
264
265 return 0;
266}
267
268static int ciintf_init(struct budget_av *budget_av)
269{
270 struct saa7146_dev *saa = budget_av->budget.dev;
271 int result;
272
273 memset(&budget_av->ca, 0, sizeof(struct dvb_ca_en50221));
274
275 /* setup GPIOs */
276 saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTHI);
277 saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTLO);
278 saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO);
279
280 /* Reset the card */
281 saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTHI);
282 msleep(50);
283 saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO);
284 msleep(100);
285
286 /* Enable DEBI pins */
287 saa7146_write(saa, MC1, saa7146_read(saa, MC1) | (0x800 << 16) | 0x800);
288
289 /* register CI interface */
290 budget_av->ca.owner = THIS_MODULE;
291 budget_av->ca.read_attribute_mem = ciintf_read_attribute_mem;
292 budget_av->ca.write_attribute_mem = ciintf_write_attribute_mem;
293 budget_av->ca.read_cam_control = ciintf_read_cam_control;
294 budget_av->ca.write_cam_control = ciintf_write_cam_control;
295 budget_av->ca.slot_reset = ciintf_slot_reset;
296 budget_av->ca.slot_shutdown = ciintf_slot_shutdown;
297 budget_av->ca.slot_ts_enable = ciintf_slot_ts_enable;
298 budget_av->ca.poll_slot_status = ciintf_poll_slot_status;
299 budget_av->ca.data = budget_av;
300 if ((result = dvb_ca_en50221_init(budget_av->budget.dvb_adapter,
301 &budget_av->ca, 0, 1)) != 0) {
302 printk("budget_av: CI interface detected, but initialisation failed.\n");
303 goto error;
304 }
305 // success!
306 printk("ciintf_init: CI interface initialised\n");
307 budget_av->budget.ci_present = 1;
308 return 0;
309
310error:
311 saa7146_write(saa, MC1, saa7146_read(saa, MC1) | (0x800 << 16));
312 return result;
313}
314
315static void ciintf_deinit(struct budget_av *budget_av)
316{
317 struct saa7146_dev *saa = budget_av->budget.dev;
318
319 saa7146_setgpio(saa, 0, SAA7146_GPIO_INPUT);
320 saa7146_setgpio(saa, 1, SAA7146_GPIO_INPUT);
321 saa7146_setgpio(saa, 2, SAA7146_GPIO_INPUT);
322 saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT);
323
324 /* release the CA device */
325 dvb_ca_en50221_release(&budget_av->ca);
326
327 /* disable DEBI pins */
328 saa7146_write(saa, MC1, saa7146_read(saa, MC1) | (0x800 << 16));
329}
330
331
332static const u8 saa7113_tab[] = {
333 0x01, 0x08,
334 0x02, 0xc0,
335 0x03, 0x33,
336 0x04, 0x00,
337 0x05, 0x00,
338 0x06, 0xeb,
339 0x07, 0xe0,
340 0x08, 0x28,
341 0x09, 0x00,
342 0x0a, 0x80,
343 0x0b, 0x47,
344 0x0c, 0x40,
345 0x0d, 0x00,
346 0x0e, 0x01,
347 0x0f, 0x44,
348
349 0x10, 0x08,
350 0x11, 0x0c,
351 0x12, 0x7b,
352 0x13, 0x00,
353 0x15, 0x00, 0x16, 0x00, 0x17, 0x00,
354
355 0x57, 0xff,
356 0x40, 0x82, 0x58, 0x00, 0x59, 0x54, 0x5a, 0x07,
357 0x5b, 0x83, 0x5e, 0x00,
358 0xff
359};
360
361static int saa7113_init(struct budget_av *budget_av)
362{
363 struct budget *budget = &budget_av->budget;
364 const u8 *data = saa7113_tab;
365
366 if (i2c_writereg(&budget->i2c_adap, 0x4a, 0x01, 0x08) != 1) {
367 dprintk(1, "saa7113 not found on KNC card\n");
368 return -ENODEV;
369 }
370
371 dprintk(1, "saa7113 detected and initializing\n");
372
373 while (*data != 0xff) {
374 i2c_writereg(&budget->i2c_adap, 0x4a, *data, *(data + 1));
375 data += 2;
376 }
377
378 dprintk(1, "saa7113 status=%02x\n", i2c_readreg(&budget->i2c_adap, 0x4a, 0x1f));
379
380 return 0;
381}
382
383static int saa7113_setinput(struct budget_av *budget_av, int input)
384{
385 struct budget *budget = &budget_av->budget;
386
387 if (1 != budget_av->has_saa7113)
388 return -ENODEV;
389
390 if (input == 1) {
391 i2c_writereg(&budget->i2c_adap, 0x4a, 0x02, 0xc7);
392 i2c_writereg(&budget->i2c_adap, 0x4a, 0x09, 0x80);
393 } else if (input == 0) {
394 i2c_writereg(&budget->i2c_adap, 0x4a, 0x02, 0xc0);
395 i2c_writereg(&budget->i2c_adap, 0x4a, 0x09, 0x00);
396 } else
397 return -EINVAL;
398
399 budget_av->cur_input = input;
400 return 0;
401}
402
403
404static int philips_su1278_ty_ci_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32 ratio)
405{
406 u8 aclk = 0;
407 u8 bclk = 0;
408 u8 m1;
409
410 aclk = 0xb5;
411 if (srate < 2000000)
412 bclk = 0x86;
413 else if (srate < 5000000)
414 bclk = 0x89;
415 else if (srate < 15000000)
416 bclk = 0x8f;
417 else if (srate < 45000000)
418 bclk = 0x95;
419
420 m1 = 0x14;
421 if (srate < 4000000)
422 m1 = 0x10;
423
424 stv0299_writereg(fe, 0x13, aclk);
425 stv0299_writereg(fe, 0x14, bclk);
426 stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
427 stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
428 stv0299_writereg(fe, 0x21, (ratio) & 0xf0);
429 stv0299_writereg(fe, 0x0f, 0x80 | m1);
430
431 return 0;
432}
433
434static int philips_su1278_ty_ci_pll_set(struct dvb_frontend *fe,
435 struct dvb_frontend_parameters *params)
436{
437 struct budget_av *budget_av = (struct budget_av *) fe->dvb->priv;
438 u32 div;
439 u8 buf[4];
440 struct i2c_msg msg = {.addr = 0x61,.flags = 0,.buf = buf,.len = sizeof(buf) };
441
442 if ((params->frequency < 950000) || (params->frequency > 2150000))
443 return -EINVAL;
444
445 div = (params->frequency + (125 - 1)) / 125; // round correctly
446 buf[0] = (div >> 8) & 0x7f;
447 buf[1] = div & 0xff;
448 buf[2] = 0x80 | ((div & 0x18000) >> 10) | 4;
449 buf[3] = 0x20;
450
451 if (params->u.qpsk.symbol_rate < 4000000)
452 buf[3] |= 1;
453
454 if (params->frequency < 1250000)
455 buf[3] |= 0;
456 else if (params->frequency < 1550000)
457 buf[3] |= 0x40;
458 else if (params->frequency < 2050000)
459 buf[3] |= 0x80;
460 else if (params->frequency < 2150000)
461 buf[3] |= 0xC0;
462
463 if (i2c_transfer(&budget_av->budget.i2c_adap, &msg, 1) != 1)
464 return -EIO;
465 return 0;
466}
467
468static u8 typhoon_cinergy1200s_inittab[] = {
469 0x01, 0x15,
470 0x02, 0x30,
471 0x03, 0x00,
472 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
473 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */
474 0x06, 0x40, /* DAC not used, set to high impendance mode */
475 0x07, 0x00, /* DAC LSB */
476 0x08, 0x40, /* DiSEqC off */
477 0x09, 0x00, /* FIFO */
478 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
479 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */
480 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
481 0x10, 0x3f, // AGC2 0x3d
482 0x11, 0x84,
483 0x12, 0xb5, // Lock detect: -64 Carrier freq detect:on
484 0x15, 0xc9, // lock detector threshold
485 0x16, 0x00,
486 0x17, 0x00,
487 0x18, 0x00,
488 0x19, 0x00,
489 0x1a, 0x00,
490 0x1f, 0x50,
491 0x20, 0x00,
492 0x21, 0x00,
493 0x22, 0x00,
494 0x23, 0x00,
495 0x28, 0x00, // out imp: normal out type: parallel FEC mode:0
496 0x29, 0x1e, // 1/2 threshold
497 0x2a, 0x14, // 2/3 threshold
498 0x2b, 0x0f, // 3/4 threshold
499 0x2c, 0x09, // 5/6 threshold
500 0x2d, 0x05, // 7/8 threshold
501 0x2e, 0x01,
502 0x31, 0x1f, // test all FECs
503 0x32, 0x19, // viterbi and synchro search
504 0x33, 0xfc, // rs control
505 0x34, 0x93, // error control
506 0x0f, 0x92,
507 0xff, 0xff
508};
509
510static struct stv0299_config typhoon_config = {
511 .demod_address = 0x68,
512 .inittab = typhoon_cinergy1200s_inittab,
513 .mclk = 88000000UL,
514 .invert = 0,
515 .enhanced_tuning = 0,
516 .skip_reinit = 0,
517 .lock_output = STV0229_LOCKOUTPUT_1,
518 .volt13_op0_op1 = STV0299_VOLT13_OP0,
519 .min_delay_ms = 100,
520 .set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate,
521 .pll_set = philips_su1278_ty_ci_pll_set,
522};
523
524
525static struct stv0299_config cinergy_1200s_config = {
526 .demod_address = 0x68,
527 .inittab = typhoon_cinergy1200s_inittab,
528 .mclk = 88000000UL,
529 .invert = 0,
530 .enhanced_tuning = 0,
531 .skip_reinit = 0,
532 .lock_output = STV0229_LOCKOUTPUT_0,
533 .volt13_op0_op1 = STV0299_VOLT13_OP0,
534 .min_delay_ms = 100,
535 .set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate,
536 .pll_set = philips_su1278_ty_ci_pll_set,
537};
538
539
540static int philips_cu1216_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
541{
542 struct budget *budget = (struct budget *) fe->dvb->priv;
543 u8 buf[4];
544 struct i2c_msg msg = {.addr = 0x60,.flags = 0,.buf = buf,.len = sizeof(buf) };
545
546#define TUNER_MUL 62500
547
548 u32 div = (params->frequency + 36125000 + TUNER_MUL / 2) / TUNER_MUL;
549
550 buf[0] = (div >> 8) & 0x7f;
551 buf[1] = div & 0xff;
552 buf[2] = 0x8e;
553 buf[3] = (params->frequency < 174500000 ? 0xa1 :
554 params->frequency < 454000000 ? 0x92 : 0x34);
555
556 if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1)
557 return -EIO;
558 return 0;
559}
560
561static struct tda10021_config philips_cu1216_config = {
562 .demod_address = 0x0c,
563 .pll_set = philips_cu1216_pll_set,
564};
565
566
567
568
569static int philips_tu1216_pll_init(struct dvb_frontend *fe)
570{
571 struct budget *budget = (struct budget *) fe->dvb->priv;
572 static u8 tu1216_init[] = { 0x0b, 0xf5, 0x85, 0xab };
573 struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tu1216_init,.len = sizeof(tu1216_init) };
574
575 // setup PLL configuration
576 if (i2c_transfer(&budget->i2c_adap, &tuner_msg, 1) != 1)
577 return -EIO;
578 msleep(1);
579
580 return 0;
581}
582
583static int philips_tu1216_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
584{
585 struct budget *budget = (struct budget *) fe->dvb->priv;
586 u8 tuner_buf[4];
587 struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tuner_buf,.len =
588 sizeof(tuner_buf) };
589 int tuner_frequency = 0;
590 u8 band, cp, filter;
591
592 // determine charge pump
593 tuner_frequency = params->frequency + 36166000;
594 if (tuner_frequency < 87000000)
595 return -EINVAL;
596 else if (tuner_frequency < 130000000)
597 cp = 3;
598 else if (tuner_frequency < 160000000)
599 cp = 5;
600 else if (tuner_frequency < 200000000)
601 cp = 6;
602 else if (tuner_frequency < 290000000)
603 cp = 3;
604 else if (tuner_frequency < 420000000)
605 cp = 5;
606 else if (tuner_frequency < 480000000)
607 cp = 6;
608 else if (tuner_frequency < 620000000)
609 cp = 3;
610 else if (tuner_frequency < 830000000)
611 cp = 5;
612 else if (tuner_frequency < 895000000)
613 cp = 7;
614 else
615 return -EINVAL;
616
617 // determine band
618 if (params->frequency < 49000000)
619 return -EINVAL;
620 else if (params->frequency < 161000000)
621 band = 1;
622 else if (params->frequency < 444000000)
623 band = 2;
624 else if (params->frequency < 861000000)
625 band = 4;
626 else
627 return -EINVAL;
628
629 // setup PLL filter
630 switch (params->u.ofdm.bandwidth) {
631 case BANDWIDTH_6_MHZ:
632 filter = 0;
633 break;
634
635 case BANDWIDTH_7_MHZ:
636 filter = 0;
637 break;
638
639 case BANDWIDTH_8_MHZ:
640 filter = 1;
641 break;
642
643 default:
644 return -EINVAL;
645 }
646
647 // calculate divisor
648 // ((36166000+((1000000/6)/2)) + Finput)/(1000000/6)
649 tuner_frequency = (((params->frequency / 1000) * 6) + 217496) / 1000;
650
651 // setup tuner buffer
652 tuner_buf[0] = (tuner_frequency >> 8) & 0x7f;
653 tuner_buf[1] = tuner_frequency & 0xff;
654 tuner_buf[2] = 0xca;
655 tuner_buf[3] = (cp << 5) | (filter << 3) | band;
656
657 if (i2c_transfer(&budget->i2c_adap, &tuner_msg, 1) != 1)
658 return -EIO;
659
660 msleep(1);
661 return 0;
662}
663
664static int philips_tu1216_request_firmware(struct dvb_frontend *fe,
665 const struct firmware **fw, char *name)
666{
667 struct budget *budget = (struct budget *) fe->dvb->priv;
668
669 return request_firmware(fw, name, &budget->dev->pci->dev);
670}
671
672static struct tda1004x_config philips_tu1216_config = {
673
674 .demod_address = 0x8,
675 .invert = 1,
676 .invert_oclk = 1,
677 .pll_init = philips_tu1216_pll_init,
678 .pll_set = philips_tu1216_pll_set,
679 .request_firmware = philips_tu1216_request_firmware,
680};
681
682
683
684
685static u8 read_pwm(struct budget_av *budget_av)
686{
687 u8 b = 0xff;
688 u8 pwm;
689 struct i2c_msg msg[] = { {.addr = 0x50,.flags = 0,.buf = &b,.len = 1},
690 {.addr = 0x50,.flags = I2C_M_RD,.buf = &pwm,.len = 1}
691 };
692
693 if ((i2c_transfer(&budget_av->budget.i2c_adap, msg, 2) != 2)
694 || (pwm == 0xff))
695 pwm = 0x48;
696
697 return pwm;
698}
699
700
701static void frontend_init(struct budget_av *budget_av)
702{
703 switch (budget_av->budget.dev->pci->subsystem_device) {
704 case 0x4f56: // Typhoon/KNC1 DVB-S budget (stv0299/Philips SU1278(tsa5059))
705 budget_av->budget.dvb_frontend =
706 stv0299_attach(&typhoon_config, &budget_av->budget.i2c_adap);
707 if (budget_av->budget.dvb_frontend != NULL) {
708 break;
709 }
710 break;
711
712 case 0x0020: // KNC1 DVB-C budget (tda10021/Philips CU1216(tua6034))
713 budget_av->budget.dvb_frontend =
714 tda10021_attach(&philips_cu1216_config,
715 &budget_av->budget.i2c_adap, read_pwm(budget_av));
716 if (budget_av->budget.dvb_frontend != NULL) {
717 break;
718 }
719 break;
720
721 case 0x0030: // KNC1 DVB-T budget (tda10046/Philips TU1216(tda6651tt))
722 budget_av->budget.dvb_frontend =
723 tda10046_attach(&philips_tu1216_config, &budget_av->budget.i2c_adap);
724 if (budget_av->budget.dvb_frontend != NULL) {
725 break;
726 }
727 break;
728
729 case 0x1154: // TerraTec Cinergy 1200 DVB-S (stv0299/Philips SU1278(tsa5059))
730 budget_av->budget.dvb_frontend =
731 stv0299_attach(&cinergy_1200s_config, &budget_av->budget.i2c_adap);
732 if (budget_av->budget.dvb_frontend != NULL) {
733 break;
734 }
735 break;
736
737 case 0x1156: // Terratec Cinergy 1200 DVB-C (tda10021/Philips CU1216(tua6034))
738 budget_av->budget.dvb_frontend =
739 tda10021_attach(&philips_cu1216_config,
740 &budget_av->budget.i2c_adap, read_pwm(budget_av));
741 if (budget_av->budget.dvb_frontend) {
742 break;
743 }
744 break;
745
746 case 0x1157: // Terratec Cinergy 1200 DVB-T (tda10046/Philips TU1216(tda6651tt))
747 budget_av->budget.dvb_frontend =
748 tda10046_attach(&philips_tu1216_config, &budget_av->budget.i2c_adap);
749 if (budget_av->budget.dvb_frontend) {
750 break;
751 }
752 break;
753 }
754
755 if (budget_av->budget.dvb_frontend == NULL) {
756 printk("budget_av: A frontend driver was not found for device %04x/%04x subsystem %04x/%04x\n",
757 budget_av->budget.dev->pci->vendor,
758 budget_av->budget.dev->pci->device,
759 budget_av->budget.dev->pci->subsystem_vendor,
760 budget_av->budget.dev->pci->subsystem_device);
761 } else {
762 if (dvb_register_frontend
763 (budget_av->budget.dvb_adapter, budget_av->budget.dvb_frontend)) {
764 printk("budget-av: Frontend registration failed!\n");
765 if (budget_av->budget.dvb_frontend->ops->release)
766 budget_av->budget.dvb_frontend->ops->release(budget_av->budget.dvb_frontend);
767 budget_av->budget.dvb_frontend = NULL;
768 }
769 }
770}
771
772
773static void budget_av_irq(struct saa7146_dev *dev, u32 * isr)
774{
775 struct budget_av *budget_av = (struct budget_av *) dev->ext_priv;
776
777 dprintk(8, "dev: %p, budget_av: %p\n", dev, budget_av);
778
779 if (*isr & MASK_10)
780 ttpci_budget_irq10_handler(dev, isr);
781}
782
783static int budget_av_detach(struct saa7146_dev *dev)
784{
785 struct budget_av *budget_av = (struct budget_av *) dev->ext_priv;
786 int err;
787
788 dprintk(2, "dev: %p\n", dev);
789
790 if (1 == budget_av->has_saa7113) {
791 saa7146_setgpio(dev, 0, SAA7146_GPIO_OUTLO);
792
793 msleep(200);
794
795 saa7146_unregister_device(&budget_av->vd, dev);
796 }
797
798 if (budget_av->budget.ci_present)
799 ciintf_deinit(budget_av);
800
801 if (budget_av->budget.dvb_frontend != NULL)
802 dvb_unregister_frontend(budget_av->budget.dvb_frontend);
803 err = ttpci_budget_deinit(&budget_av->budget);
804
805 kfree(budget_av);
806
807 return err;
808}
809
810static struct saa7146_ext_vv vv_data;
811
812static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
813{
814 struct budget_av *budget_av;
815 u8 *mac;
816 int err;
817
818 dprintk(2, "dev: %p\n", dev);
819
820 if (!(budget_av = kmalloc(sizeof(struct budget_av), GFP_KERNEL)))
821 return -ENOMEM;
822
823 memset(budget_av, 0, sizeof(struct budget_av));
824
825 budget_av->budget.ci_present = 0;
826
827 dev->ext_priv = budget_av;
828
829 if ((err = ttpci_budget_init(&budget_av->budget, dev, info, THIS_MODULE))) {
830 kfree(budget_av);
831 return err;
832 }
833
834 /* knc1 initialization */
835 saa7146_write(dev, DD1_STREAM_B, 0x04000000);
836 saa7146_write(dev, DD1_INIT, 0x07000600);
837 saa7146_write(dev, MC2, MASK_09 | MASK_25 | MASK_10 | MASK_26);
838
839 saa7146_setgpio(dev, 0, SAA7146_GPIO_OUTHI);
840 msleep(500);
841
842 if (0 == saa7113_init(budget_av)) {
843 budget_av->has_saa7113 = 1;
844
845 if (0 != saa7146_vv_init(dev, &vv_data)) {
846 /* fixme: proper cleanup here */
847 ERR(("cannot init vv subsystem.\n"));
848 return err;
849 }
850
851 if ((err = saa7146_register_device(&budget_av->vd, dev, "knc1", VFL_TYPE_GRABBER))) {
852 /* fixme: proper cleanup here */
853 ERR(("cannot register capture v4l2 device.\n"));
854 return err;
855 }
856
857 /* beware: this modifies dev->vv ... */
858 saa7146_set_hps_source_and_sync(dev, SAA7146_HPS_SOURCE_PORT_A,
859 SAA7146_HPS_SYNC_PORT_A);
860
861 saa7113_setinput(budget_av, 0);
862 } else {
863 budget_av->has_saa7113 = 0;
864
865 saa7146_setgpio(dev, 0, SAA7146_GPIO_OUTLO);
866 }
867
868 /* fixme: find some sane values here... */
869 saa7146_write(dev, PCI_BT_V1, 0x1c00101f);
870
871 mac = budget_av->budget.dvb_adapter->proposed_mac;
872 if (i2c_readregs(&budget_av->budget.i2c_adap, 0xa0, 0x30, mac, 6)) {
873 printk("KNC1-%d: Could not read MAC from KNC1 card\n",
874 budget_av->budget.dvb_adapter->num);
875 memset(mac, 0, 6);
876 } else {
877 printk("KNC1-%d: MAC addr = %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",
878 budget_av->budget.dvb_adapter->num,
879 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
880 }
881
882 budget_av->budget.dvb_adapter->priv = budget_av;
883 frontend_init(budget_av);
884
885 if (enable_ci)
886 ciintf_init(budget_av);
887
888 return 0;
889}
890
891#define KNC1_INPUTS 2
892static struct v4l2_input knc1_inputs[KNC1_INPUTS] = {
893 {0, "Composite", V4L2_INPUT_TYPE_TUNER, 1, 0, V4L2_STD_PAL_BG | V4L2_STD_NTSC_M, 0},
894 {1, "S-Video", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG | V4L2_STD_NTSC_M, 0},
895};
896
897static struct saa7146_extension_ioctls ioctls[] = {
898 {VIDIOC_ENUMINPUT, SAA7146_EXCLUSIVE},
899 {VIDIOC_G_INPUT, SAA7146_EXCLUSIVE},
900 {VIDIOC_S_INPUT, SAA7146_EXCLUSIVE},
901 {0, 0}
902};
903
904static int av_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
905{
906 struct saa7146_dev *dev = fh->dev;
907 struct budget_av *budget_av = (struct budget_av *) dev->ext_priv;
908
909 switch (cmd) {
910 case VIDIOC_ENUMINPUT:{
911 struct v4l2_input *i = arg;
912
913 dprintk(1, "VIDIOC_ENUMINPUT %d.\n", i->index);
914 if (i->index < 0 || i->index >= KNC1_INPUTS) {
915 return -EINVAL;
916 }
917 memcpy(i, &knc1_inputs[i->index], sizeof(struct v4l2_input));
918 return 0;
919 }
920 case VIDIOC_G_INPUT:{
921 int *input = (int *) arg;
922
923 *input = budget_av->cur_input;
924
925 dprintk(1, "VIDIOC_G_INPUT %d.\n", *input);
926 return 0;
927 }
928 case VIDIOC_S_INPUT:{
929 int input = *(int *) arg;
930 dprintk(1, "VIDIOC_S_INPUT %d.\n", input);
931 return saa7113_setinput(budget_av, input);
932 }
933 default:
934 return -ENOIOCTLCMD;
935 }
936 return 0;
937}
938
939static struct saa7146_standard standard[] = {
940 {.name = "PAL",.id = V4L2_STD_PAL,
941 .v_offset = 0x17,.v_field = 288,
942 .h_offset = 0x14,.h_pixels = 680,
943 .v_max_out = 576,.h_max_out = 768 },
944
945 {.name = "NTSC",.id = V4L2_STD_NTSC,
946 .v_offset = 0x16,.v_field = 240,
947 .h_offset = 0x06,.h_pixels = 708,
948 .v_max_out = 480,.h_max_out = 640, },
949};
950
951static struct saa7146_ext_vv vv_data = {
952 .inputs = 2,
953 .capabilities = 0, // perhaps later: V4L2_CAP_VBI_CAPTURE, but that need tweaking with the saa7113
954 .flags = 0,
955 .stds = &standard[0],
956 .num_stds = sizeof(standard) / sizeof(struct saa7146_standard),
957 .ioctls = &ioctls[0],
958 .ioctl = av_ioctl,
959};
960
961static struct saa7146_extension budget_extension;
962
963MAKE_BUDGET_INFO(knc1s, "KNC1 DVB-S", BUDGET_KNC1S);
964MAKE_BUDGET_INFO(knc1c, "KNC1 DVB-C", BUDGET_KNC1C);
965MAKE_BUDGET_INFO(knc1t, "KNC1 DVB-T", BUDGET_KNC1T);
966MAKE_BUDGET_INFO(cin1200s, "TerraTec Cinergy 1200 DVB-S", BUDGET_CIN1200S);
967MAKE_BUDGET_INFO(cin1200c, "Terratec Cinergy 1200 DVB-C", BUDGET_CIN1200C);
968MAKE_BUDGET_INFO(cin1200t, "Terratec Cinergy 1200 DVB-T", BUDGET_CIN1200T);
969
970static struct pci_device_id pci_tbl[] = {
971 MAKE_EXTENSION_PCI(knc1s, 0x1131, 0x4f56),
972 MAKE_EXTENSION_PCI(knc1c, 0x1894, 0x0020),
973 MAKE_EXTENSION_PCI(knc1t, 0x1894, 0x0030),
974 MAKE_EXTENSION_PCI(cin1200s, 0x153b, 0x1154),
975 MAKE_EXTENSION_PCI(cin1200c, 0x153b, 0x1156),
976 MAKE_EXTENSION_PCI(cin1200t, 0x153b, 0x1157),
977 {
978 .vendor = 0,
979 }
980};
981
982MODULE_DEVICE_TABLE(pci, pci_tbl);
983
984static struct saa7146_extension budget_extension = {
985 .name = "budget dvb /w video in\0",
986 .pci_tbl = pci_tbl,
987
988 .module = THIS_MODULE,
989 .attach = budget_av_attach,
990 .detach = budget_av_detach,
991
992 .irq_mask = MASK_10,
993 .irq_func = budget_av_irq,
994};
995
996static int __init budget_av_init(void)
997{
998 return saa7146_register_extension(&budget_extension);
999}
1000
1001static void __exit budget_av_exit(void)
1002{
1003 saa7146_unregister_extension(&budget_extension);
1004}
1005
1006module_init(budget_av_init);
1007module_exit(budget_av_exit);
1008
1009MODULE_LICENSE("GPL");
1010MODULE_AUTHOR("Ralph Metzler, Marcus Metzler, Michael Hunold, others");
1011MODULE_DESCRIPTION("driver for the SAA7146 based so-called "
1012 "budget PCI DVB w/ analog input and CI-module (e.g. the KNC cards)");
1013module_param_named(enable_ci, enable_ci, int, 0644);
1014MODULE_PARM_DESC(enable_ci, "Turn on/off CI module (default:off).");
diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c
new file mode 100644
index 000000000000..521111be3558
--- /dev/null
+++ b/drivers/media/dvb/ttpci/budget-ci.c
@@ -0,0 +1,995 @@
1/*
2 * budget-ci.c: driver for the SAA7146 based Budget DVB cards
3 *
4 * Compiled from various sources by Michael Hunold <michael@mihu.de>
5 *
6 * msp430 IR support contributed by Jack Thomasson <jkt@Helius.COM>
7 * partially based on the Siemens DVB driver by Ralph+Marcus Metzler
8 *
9 * CI interface support (c) 2004 Andrew de Quincey <adq_dvb@lidskialf.net>
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#include "budget.h"
33
34#include <linux/module.h>
35#include <linux/errno.h>
36#include <linux/slab.h>
37#include <linux/interrupt.h>
38#include <linux/input.h>
39#include <linux/spinlock.h>
40
41#include "dvb_ca_en50221.h"
42#include "stv0299.h"
43#include "tda1004x.h"
44
45#define DEBIADDR_IR 0x1234
46#define DEBIADDR_CICONTROL 0x0000
47#define DEBIADDR_CIVERSION 0x4000
48#define DEBIADDR_IO 0x1000
49#define DEBIADDR_ATTR 0x3000
50
51#define CICONTROL_RESET 0x01
52#define CICONTROL_ENABLETS 0x02
53#define CICONTROL_CAMDETECT 0x08
54
55#define DEBICICTL 0x00420000
56#define DEBICICAM 0x02420000
57
58#define SLOTSTATUS_NONE 1
59#define SLOTSTATUS_PRESENT 2
60#define SLOTSTATUS_RESET 4
61#define SLOTSTATUS_READY 8
62#define SLOTSTATUS_OCCUPIED (SLOTSTATUS_PRESENT|SLOTSTATUS_RESET|SLOTSTATUS_READY)
63
64struct budget_ci {
65 struct budget budget;
66 struct input_dev input_dev;
67 struct tasklet_struct msp430_irq_tasklet;
68 struct tasklet_struct ciintf_irq_tasklet;
69 int slot_status;
70 struct dvb_ca_en50221 ca;
71 char ir_dev_name[50];
72};
73
74/* from reading the following remotes:
75 Zenith Universal 7 / TV Mode 807 / VCR Mode 837
76 Hauppauge (from NOVA-CI-s box product)
77 i've taken a "middle of the road" approach and note the differences
78*/
79static u16 key_map[64] = {
80 /* 0x0X */
81 KEY_0, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7, KEY_8,
82 KEY_9,
83 KEY_ENTER,
84 KEY_RED,
85 KEY_POWER, /* RADIO on Hauppauge */
86 KEY_MUTE,
87 0,
88 KEY_A, /* TV on Hauppauge */
89 /* 0x1X */
90 KEY_VOLUMEUP, KEY_VOLUMEDOWN,
91 0, 0,
92 KEY_B,
93 0, 0, 0, 0, 0, 0, 0,
94 KEY_UP, KEY_DOWN,
95 KEY_OPTION, /* RESERVED on Hauppauge */
96 KEY_BREAK,
97 /* 0x2X */
98 KEY_CHANNELUP, KEY_CHANNELDOWN,
99 KEY_PREVIOUS, /* Prev. Ch on Zenith, SOURCE on Hauppauge */
100 0, KEY_RESTART, KEY_OK,
101 KEY_CYCLEWINDOWS, /* MINIMIZE on Hauppauge */
102 0,
103 KEY_ENTER, /* VCR mode on Zenith */
104 KEY_PAUSE,
105 0,
106 KEY_RIGHT, KEY_LEFT,
107 0,
108 KEY_MENU, /* FULL SCREEN on Hauppauge */
109 0,
110 /* 0x3X */
111 KEY_SLOW,
112 KEY_PREVIOUS, /* VCR mode on Zenith */
113 KEY_REWIND,
114 0,
115 KEY_FASTFORWARD,
116 KEY_PLAY, KEY_STOP,
117 KEY_RECORD,
118 KEY_TUNER, /* TV/VCR on Zenith */
119 0,
120 KEY_C,
121 0,
122 KEY_EXIT,
123 KEY_POWER2,
124 KEY_TUNER, /* VCR mode on Zenith */
125 0,
126};
127
128static void msp430_ir_debounce(unsigned long data)
129{
130 struct input_dev *dev = (struct input_dev *) data;
131
132 if (dev->rep[0] == 0 || dev->rep[0] == ~0) {
133 input_event(dev, EV_KEY, key_map[dev->repeat_key], !!0);
134 return;
135 }
136
137 dev->rep[0] = 0;
138 dev->timer.expires = jiffies + HZ * 350 / 1000;
139 add_timer(&dev->timer);
140 input_event(dev, EV_KEY, key_map[dev->repeat_key], 2); /* REPEAT */
141}
142
143static void msp430_ir_interrupt(unsigned long data)
144{
145 struct budget_ci *budget_ci = (struct budget_ci *) data;
146 struct input_dev *dev = &budget_ci->input_dev;
147 unsigned int code =
148 ttpci_budget_debiread(&budget_ci->budget, DEBINOSWAP, DEBIADDR_IR, 2, 1, 0) >> 8;
149
150 if (code & 0x40) {
151 code &= 0x3f;
152
153 if (timer_pending(&dev->timer)) {
154 if (code == dev->repeat_key) {
155 ++dev->rep[0];
156 return;
157 }
158 del_timer(&dev->timer);
159 input_event(dev, EV_KEY, key_map[dev->repeat_key], !!0);
160 }
161
162 if (!key_map[code]) {
163 printk("DVB (%s): no key for %02x!\n", __FUNCTION__, code);
164 return;
165 }
166
167 /* initialize debounce and repeat */
168 dev->repeat_key = code;
169 /* Zenith remote _always_ sends 2 sequences */
170 dev->rep[0] = ~0;
171 /* 350 milliseconds */
172 dev->timer.expires = jiffies + HZ * 350 / 1000;
173 /* MAKE */
174 input_event(dev, EV_KEY, key_map[code], !0);
175 add_timer(&dev->timer);
176 }
177}
178
179static int msp430_ir_init(struct budget_ci *budget_ci)
180{
181 struct saa7146_dev *saa = budget_ci->budget.dev;
182 int i;
183
184 memset(&budget_ci->input_dev, 0, sizeof(struct input_dev));
185
186 sprintf(budget_ci->ir_dev_name, "Budget-CI dvb ir receiver %s", saa->name);
187 budget_ci->input_dev.name = budget_ci->ir_dev_name;
188
189 set_bit(EV_KEY, budget_ci->input_dev.evbit);
190
191 for (i = 0; i < sizeof(key_map) / sizeof(*key_map); i++)
192 if (key_map[i])
193 set_bit(key_map[i], budget_ci->input_dev.keybit);
194
195 input_register_device(&budget_ci->input_dev);
196
197 budget_ci->input_dev.timer.function = msp430_ir_debounce;
198
199 saa7146_write(saa, IER, saa7146_read(saa, IER) | MASK_06);
200
201 saa7146_setgpio(saa, 3, SAA7146_GPIO_IRQHI);
202
203 return 0;
204}
205
206static void msp430_ir_deinit(struct budget_ci *budget_ci)
207{
208 struct saa7146_dev *saa = budget_ci->budget.dev;
209 struct input_dev *dev = &budget_ci->input_dev;
210
211 saa7146_write(saa, IER, saa7146_read(saa, IER) & ~MASK_06);
212 saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT);
213
214 if (del_timer(&dev->timer))
215 input_event(dev, EV_KEY, key_map[dev->repeat_key], !!0);
216
217 input_unregister_device(dev);
218}
219
220static int ciintf_read_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address)
221{
222 struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
223
224 if (slot != 0)
225 return -EINVAL;
226
227 return ttpci_budget_debiread(&budget_ci->budget, DEBICICAM,
228 DEBIADDR_ATTR | (address & 0xfff), 1, 1, 0);
229}
230
231static int ciintf_write_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address, u8 value)
232{
233 struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
234
235 if (slot != 0)
236 return -EINVAL;
237
238 return ttpci_budget_debiwrite(&budget_ci->budget, DEBICICAM,
239 DEBIADDR_ATTR | (address & 0xfff), 1, value, 1, 0);
240}
241
242static int ciintf_read_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address)
243{
244 struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
245
246 if (slot != 0)
247 return -EINVAL;
248
249 return ttpci_budget_debiread(&budget_ci->budget, DEBICICAM,
250 DEBIADDR_IO | (address & 3), 1, 1, 0);
251}
252
253static int ciintf_write_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address, u8 value)
254{
255 struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
256
257 if (slot != 0)
258 return -EINVAL;
259
260 return ttpci_budget_debiwrite(&budget_ci->budget, DEBICICAM,
261 DEBIADDR_IO | (address & 3), 1, value, 1, 0);
262}
263
264static int ciintf_slot_reset(struct dvb_ca_en50221 *ca, int slot)
265{
266 struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
267 struct saa7146_dev *saa = budget_ci->budget.dev;
268
269 if (slot != 0)
270 return -EINVAL;
271
272 // trigger on RISING edge during reset so we know when READY is re-asserted
273 saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI);
274 budget_ci->slot_status = SLOTSTATUS_RESET;
275 ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 0, 1, 0);
276 msleep(1);
277 ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1,
278 CICONTROL_RESET, 1, 0);
279
280 saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTHI);
281 ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB);
282 return 0;
283}
284
285static int ciintf_slot_shutdown(struct dvb_ca_en50221 *ca, int slot)
286{
287 struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
288 struct saa7146_dev *saa = budget_ci->budget.dev;
289
290 if (slot != 0)
291 return -EINVAL;
292
293 saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTHI);
294 ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB);
295 return 0;
296}
297
298static int ciintf_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot)
299{
300 struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
301 struct saa7146_dev *saa = budget_ci->budget.dev;
302 int tmp;
303
304 if (slot != 0)
305 return -EINVAL;
306
307 saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTLO);
308
309 tmp = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 1, 0);
310 ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1,
311 tmp | CICONTROL_ENABLETS, 1, 0);
312
313 ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTA);
314 return 0;
315}
316
317static void ciintf_interrupt(unsigned long data)
318{
319 struct budget_ci *budget_ci = (struct budget_ci *) data;
320 struct saa7146_dev *saa = budget_ci->budget.dev;
321 unsigned int flags;
322
323 // ensure we don't get spurious IRQs during initialisation
324 if (!budget_ci->budget.ci_present)
325 return;
326
327 // read the CAM status
328 flags = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 1, 0);
329 if (flags & CICONTROL_CAMDETECT) {
330
331 // GPIO should be set to trigger on falling edge if a CAM is present
332 saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQLO);
333
334 if (budget_ci->slot_status & SLOTSTATUS_NONE) {
335 // CAM insertion IRQ
336 budget_ci->slot_status = SLOTSTATUS_PRESENT;
337 dvb_ca_en50221_camchange_irq(&budget_ci->ca, 0,
338 DVB_CA_EN50221_CAMCHANGE_INSERTED);
339
340 } else if (budget_ci->slot_status & SLOTSTATUS_RESET) {
341 // CAM ready (reset completed)
342 budget_ci->slot_status = SLOTSTATUS_READY;
343 dvb_ca_en50221_camready_irq(&budget_ci->ca, 0);
344
345 } else if (budget_ci->slot_status & SLOTSTATUS_READY) {
346 // FR/DA IRQ
347 dvb_ca_en50221_frda_irq(&budget_ci->ca, 0);
348 }
349 } else {
350
351 // trigger on rising edge if a CAM is not present - when a CAM is inserted, we
352 // only want to get the IRQ when it sets READY. If we trigger on the falling edge,
353 // the CAM might not actually be ready yet.
354 saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI);
355
356 // generate a CAM removal IRQ if we haven't already
357 if (budget_ci->slot_status & SLOTSTATUS_OCCUPIED) {
358 // CAM removal IRQ
359 budget_ci->slot_status = SLOTSTATUS_NONE;
360 dvb_ca_en50221_camchange_irq(&budget_ci->ca, 0,
361 DVB_CA_EN50221_CAMCHANGE_REMOVED);
362 }
363 }
364}
365
366static int ciintf_init(struct budget_ci *budget_ci)
367{
368 struct saa7146_dev *saa = budget_ci->budget.dev;
369 int flags;
370 int result;
371
372 memset(&budget_ci->ca, 0, sizeof(struct dvb_ca_en50221));
373
374 // enable DEBI pins
375 saa7146_write(saa, MC1, saa7146_read(saa, MC1) | (0x800 << 16) | 0x800);
376
377 // test if it is there
378 if ((ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CIVERSION, 1, 1, 0) & 0xa0) != 0xa0) {
379 result = -ENODEV;
380 goto error;
381 }
382 // determine whether a CAM is present or not
383 flags = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 1, 0);
384 budget_ci->slot_status = SLOTSTATUS_NONE;
385 if (flags & CICONTROL_CAMDETECT)
386 budget_ci->slot_status = SLOTSTATUS_PRESENT;
387
388 // register CI interface
389 budget_ci->ca.owner = THIS_MODULE;
390 budget_ci->ca.read_attribute_mem = ciintf_read_attribute_mem;
391 budget_ci->ca.write_attribute_mem = ciintf_write_attribute_mem;
392 budget_ci->ca.read_cam_control = ciintf_read_cam_control;
393 budget_ci->ca.write_cam_control = ciintf_write_cam_control;
394 budget_ci->ca.slot_reset = ciintf_slot_reset;
395 budget_ci->ca.slot_shutdown = ciintf_slot_shutdown;
396 budget_ci->ca.slot_ts_enable = ciintf_slot_ts_enable;
397 budget_ci->ca.data = budget_ci;
398 if ((result = dvb_ca_en50221_init(budget_ci->budget.dvb_adapter,
399 &budget_ci->ca,
400 DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE |
401 DVB_CA_EN50221_FLAG_IRQ_FR |
402 DVB_CA_EN50221_FLAG_IRQ_DA, 1)) != 0) {
403 printk("budget_ci: CI interface detected, but initialisation failed.\n");
404 goto error;
405 }
406 // Setup CI slot IRQ
407 tasklet_init(&budget_ci->ciintf_irq_tasklet, ciintf_interrupt, (unsigned long) budget_ci);
408 if (budget_ci->slot_status != SLOTSTATUS_NONE) {
409 saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQLO);
410 } else {
411 saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI);
412 }
413 saa7146_write(saa, IER, saa7146_read(saa, IER) | MASK_03);
414 ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1,
415 CICONTROL_RESET, 1, 0);
416
417 // success!
418 printk("budget_ci: CI interface initialised\n");
419 budget_ci->budget.ci_present = 1;
420
421 // forge a fake CI IRQ so the CAM state is setup correctly
422 flags = DVB_CA_EN50221_CAMCHANGE_REMOVED;
423 if (budget_ci->slot_status != SLOTSTATUS_NONE)
424 flags = DVB_CA_EN50221_CAMCHANGE_INSERTED;
425 dvb_ca_en50221_camchange_irq(&budget_ci->ca, 0, flags);
426
427 return 0;
428
429error:
430 saa7146_write(saa, MC1, saa7146_read(saa, MC1) | (0x800 << 16));
431 return result;
432}
433
434static void ciintf_deinit(struct budget_ci *budget_ci)
435{
436 struct saa7146_dev *saa = budget_ci->budget.dev;
437
438 // disable CI interrupts
439 saa7146_write(saa, IER, saa7146_read(saa, IER) & ~MASK_03);
440 saa7146_setgpio(saa, 0, SAA7146_GPIO_INPUT);
441 tasklet_kill(&budget_ci->ciintf_irq_tasklet);
442 ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 0, 1, 0);
443 msleep(1);
444 ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1,
445 CICONTROL_RESET, 1, 0);
446
447 // disable TS data stream to CI interface
448 saa7146_setgpio(saa, 1, SAA7146_GPIO_INPUT);
449
450 // release the CA device
451 dvb_ca_en50221_release(&budget_ci->ca);
452
453 // disable DEBI pins
454 saa7146_write(saa, MC1, saa7146_read(saa, MC1) | (0x800 << 16));
455}
456
457static void budget_ci_irq(struct saa7146_dev *dev, u32 * isr)
458{
459 struct budget_ci *budget_ci = (struct budget_ci *) dev->ext_priv;
460
461 dprintk(8, "dev: %p, budget_ci: %p\n", dev, budget_ci);
462
463 if (*isr & MASK_06)
464 tasklet_schedule(&budget_ci->msp430_irq_tasklet);
465
466 if (*isr & MASK_10)
467 ttpci_budget_irq10_handler(dev, isr);
468
469 if ((*isr & MASK_03) && (budget_ci->budget.ci_present))
470 tasklet_schedule(&budget_ci->ciintf_irq_tasklet);
471}
472
473
474static u8 alps_bsru6_inittab[] = {
475 0x01, 0x15,
476 0x02, 0x00,
477 0x03, 0x00,
478 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
479 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */
480 0x06, 0x40, /* DAC not used, set to high impendance mode */
481 0x07, 0x00, /* DAC LSB */
482 0x08, 0x40, /* DiSEqC off, LNB power on OP2/LOCK pin on */
483 0x09, 0x00, /* FIFO */
484 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
485 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */
486 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
487 0x10, 0x3f, // AGC2 0x3d
488 0x11, 0x84,
489 0x12, 0xb5, // Lock detect: -64 Carrier freq detect:on
490 0x15, 0xc9, // lock detector threshold
491 0x16, 0x00,
492 0x17, 0x00,
493 0x18, 0x00,
494 0x19, 0x00,
495 0x1a, 0x00,
496 0x1f, 0x50,
497 0x20, 0x00,
498 0x21, 0x00,
499 0x22, 0x00,
500 0x23, 0x00,
501 0x28, 0x00, // out imp: normal out type: parallel FEC mode:0
502 0x29, 0x1e, // 1/2 threshold
503 0x2a, 0x14, // 2/3 threshold
504 0x2b, 0x0f, // 3/4 threshold
505 0x2c, 0x09, // 5/6 threshold
506 0x2d, 0x05, // 7/8 threshold
507 0x2e, 0x01,
508 0x31, 0x1f, // test all FECs
509 0x32, 0x19, // viterbi and synchro search
510 0x33, 0xfc, // rs control
511 0x34, 0x93, // error control
512 0x0f, 0x52,
513 0xff, 0xff
514};
515
516static int alps_bsru6_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32 ratio)
517{
518 u8 aclk = 0;
519 u8 bclk = 0;
520
521 if (srate < 1500000) {
522 aclk = 0xb7;
523 bclk = 0x47;
524 } else if (srate < 3000000) {
525 aclk = 0xb7;
526 bclk = 0x4b;
527 } else if (srate < 7000000) {
528 aclk = 0xb7;
529 bclk = 0x4f;
530 } else if (srate < 14000000) {
531 aclk = 0xb7;
532 bclk = 0x53;
533 } else if (srate < 30000000) {
534 aclk = 0xb6;
535 bclk = 0x53;
536 } else if (srate < 45000000) {
537 aclk = 0xb4;
538 bclk = 0x51;
539 }
540
541 stv0299_writereg(fe, 0x13, aclk);
542 stv0299_writereg(fe, 0x14, bclk);
543 stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
544 stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
545 stv0299_writereg(fe, 0x21, (ratio) & 0xf0);
546
547 return 0;
548}
549
550static int alps_bsru6_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
551{
552 struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
553 u8 buf[4];
554 u32 div;
555 struct i2c_msg msg = {.addr = 0x61,.flags = 0,.buf = buf,.len = sizeof(buf) };
556
557 if ((params->frequency < 950000) || (params->frequency > 2150000))
558 return -EINVAL;
559
560 div = (params->frequency + (125 - 1)) / 125; // round correctly
561 buf[0] = (div >> 8) & 0x7f;
562 buf[1] = div & 0xff;
563 buf[2] = 0x80 | ((div & 0x18000) >> 10) | 4;
564 buf[3] = 0xC4;
565
566 if (params->frequency > 1530000)
567 buf[3] = 0xc0;
568
569 if (i2c_transfer(&budget_ci->budget.i2c_adap, &msg, 1) != 1)
570 return -EIO;
571 return 0;
572}
573
574static struct stv0299_config alps_bsru6_config = {
575
576 .demod_address = 0x68,
577 .inittab = alps_bsru6_inittab,
578 .mclk = 88000000UL,
579 .invert = 1,
580 .enhanced_tuning = 0,
581 .skip_reinit = 0,
582 .lock_output = STV0229_LOCKOUTPUT_1,
583 .volt13_op0_op1 = STV0299_VOLT13_OP1,
584 .min_delay_ms = 100,
585 .set_symbol_rate = alps_bsru6_set_symbol_rate,
586 .pll_set = alps_bsru6_pll_set,
587};
588
589
590
591
592static u8 philips_su1278_tt_inittab[] = {
593 0x01, 0x0f,
594 0x02, 0x30,
595 0x03, 0x00,
596 0x04, 0x5b,
597 0x05, 0x85,
598 0x06, 0x02,
599 0x07, 0x00,
600 0x08, 0x02,
601 0x09, 0x00,
602 0x0C, 0x01,
603 0x0D, 0x81,
604 0x0E, 0x44,
605 0x0f, 0x14,
606 0x10, 0x3c,
607 0x11, 0x84,
608 0x12, 0xda,
609 0x13, 0x97,
610 0x14, 0x95,
611 0x15, 0xc9,
612 0x16, 0x19,
613 0x17, 0x8c,
614 0x18, 0x59,
615 0x19, 0xf8,
616 0x1a, 0xfe,
617 0x1c, 0x7f,
618 0x1d, 0x00,
619 0x1e, 0x00,
620 0x1f, 0x50,
621 0x20, 0x00,
622 0x21, 0x00,
623 0x22, 0x00,
624 0x23, 0x00,
625 0x28, 0x00,
626 0x29, 0x28,
627 0x2a, 0x14,
628 0x2b, 0x0f,
629 0x2c, 0x09,
630 0x2d, 0x09,
631 0x31, 0x1f,
632 0x32, 0x19,
633 0x33, 0xfc,
634 0x34, 0x93,
635 0xff, 0xff
636};
637
638static int philips_su1278_tt_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32 ratio)
639{
640 stv0299_writereg(fe, 0x0e, 0x44);
641 if (srate >= 10000000) {
642 stv0299_writereg(fe, 0x13, 0x97);
643 stv0299_writereg(fe, 0x14, 0x95);
644 stv0299_writereg(fe, 0x15, 0xc9);
645 stv0299_writereg(fe, 0x17, 0x8c);
646 stv0299_writereg(fe, 0x1a, 0xfe);
647 stv0299_writereg(fe, 0x1c, 0x7f);
648 stv0299_writereg(fe, 0x2d, 0x09);
649 } else {
650 stv0299_writereg(fe, 0x13, 0x99);
651 stv0299_writereg(fe, 0x14, 0x8d);
652 stv0299_writereg(fe, 0x15, 0xce);
653 stv0299_writereg(fe, 0x17, 0x43);
654 stv0299_writereg(fe, 0x1a, 0x1d);
655 stv0299_writereg(fe, 0x1c, 0x12);
656 stv0299_writereg(fe, 0x2d, 0x05);
657 }
658 stv0299_writereg(fe, 0x0e, 0x23);
659 stv0299_writereg(fe, 0x0f, 0x94);
660 stv0299_writereg(fe, 0x10, 0x39);
661 stv0299_writereg(fe, 0x15, 0xc9);
662
663 stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
664 stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
665 stv0299_writereg(fe, 0x21, (ratio) & 0xf0);
666
667 return 0;
668}
669
670static int philips_su1278_tt_pll_set(struct dvb_frontend *fe,
671 struct dvb_frontend_parameters *params)
672{
673 struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
674 u32 div;
675 u8 buf[4];
676 struct i2c_msg msg = {.addr = 0x60,.flags = 0,.buf = buf,.len = sizeof(buf) };
677
678 if ((params->frequency < 950000) || (params->frequency > 2150000))
679 return -EINVAL;
680
681 div = (params->frequency + (500 - 1)) / 500; // round correctly
682 buf[0] = (div >> 8) & 0x7f;
683 buf[1] = div & 0xff;
684 buf[2] = 0x80 | ((div & 0x18000) >> 10) | 2;
685 buf[3] = 0x20;
686
687 if (params->u.qpsk.symbol_rate < 4000000)
688 buf[3] |= 1;
689
690 if (params->frequency < 1250000)
691 buf[3] |= 0;
692 else if (params->frequency < 1550000)
693 buf[3] |= 0x40;
694 else if (params->frequency < 2050000)
695 buf[3] |= 0x80;
696 else if (params->frequency < 2150000)
697 buf[3] |= 0xC0;
698
699 if (i2c_transfer(&budget_ci->budget.i2c_adap, &msg, 1) != 1)
700 return -EIO;
701 return 0;
702}
703
704static struct stv0299_config philips_su1278_tt_config = {
705
706 .demod_address = 0x68,
707 .inittab = philips_su1278_tt_inittab,
708 .mclk = 64000000UL,
709 .invert = 0,
710 .enhanced_tuning = 1,
711 .skip_reinit = 1,
712 .lock_output = STV0229_LOCKOUTPUT_1,
713 .volt13_op0_op1 = STV0299_VOLT13_OP1,
714 .min_delay_ms = 50,
715 .set_symbol_rate = philips_su1278_tt_set_symbol_rate,
716 .pll_set = philips_su1278_tt_pll_set,
717};
718
719
720
721static int philips_tdm1316l_pll_init(struct dvb_frontend *fe)
722{
723 struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
724 static u8 td1316_init[] = { 0x0b, 0xf5, 0x85, 0xab };
725 static u8 disable_mc44BC374c[] = { 0x1d, 0x74, 0xa0, 0x68 };
726 struct i2c_msg tuner_msg = {.addr = 0x63,.flags = 0,.buf = td1316_init,.len =
727 sizeof(td1316_init) };
728
729 // setup PLL configuration
730 if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1)
731 return -EIO;
732 msleep(1);
733
734 // disable the mc44BC374c (do not check for errors)
735 tuner_msg.addr = 0x65;
736 tuner_msg.buf = disable_mc44BC374c;
737 tuner_msg.len = sizeof(disable_mc44BC374c);
738 if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1) {
739 i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1);
740 }
741
742 return 0;
743}
744
745static int philips_tdm1316l_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
746{
747 struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
748 u8 tuner_buf[4];
749 struct i2c_msg tuner_msg = {.addr = 0x63,.flags = 0,.buf = tuner_buf,.len = sizeof(tuner_buf) };
750 int tuner_frequency = 0;
751 u8 band, cp, filter;
752
753 // determine charge pump
754 tuner_frequency = params->frequency + 36130000;
755 if (tuner_frequency < 87000000)
756 return -EINVAL;
757 else if (tuner_frequency < 130000000)
758 cp = 3;
759 else if (tuner_frequency < 160000000)
760 cp = 5;
761 else if (tuner_frequency < 200000000)
762 cp = 6;
763 else if (tuner_frequency < 290000000)
764 cp = 3;
765 else if (tuner_frequency < 420000000)
766 cp = 5;
767 else if (tuner_frequency < 480000000)
768 cp = 6;
769 else if (tuner_frequency < 620000000)
770 cp = 3;
771 else if (tuner_frequency < 830000000)
772 cp = 5;
773 else if (tuner_frequency < 895000000)
774 cp = 7;
775 else
776 return -EINVAL;
777
778 // determine band
779 if (params->frequency < 49000000)
780 return -EINVAL;
781 else if (params->frequency < 159000000)
782 band = 1;
783 else if (params->frequency < 444000000)
784 band = 2;
785 else if (params->frequency < 861000000)
786 band = 4;
787 else
788 return -EINVAL;
789
790 // setup PLL filter and TDA9889
791 switch (params->u.ofdm.bandwidth) {
792 case BANDWIDTH_6_MHZ:
793 tda1004x_write_byte(fe, 0x0C, 0x14);
794 filter = 0;
795 break;
796
797 case BANDWIDTH_7_MHZ:
798 tda1004x_write_byte(fe, 0x0C, 0x80);
799 filter = 0;
800 break;
801
802 case BANDWIDTH_8_MHZ:
803 tda1004x_write_byte(fe, 0x0C, 0x14);
804 filter = 1;
805 break;
806
807 default:
808 return -EINVAL;
809 }
810
811 // calculate divisor
812 // ((36130000+((1000000/6)/2)) + Finput)/(1000000/6)
813 tuner_frequency = (((params->frequency / 1000) * 6) + 217280) / 1000;
814
815 // setup tuner buffer
816 tuner_buf[0] = tuner_frequency >> 8;
817 tuner_buf[1] = tuner_frequency & 0xff;
818 tuner_buf[2] = 0xca;
819 tuner_buf[3] = (cp << 5) | (filter << 3) | band;
820
821 if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1)
822 return -EIO;
823
824 msleep(1);
825 return 0;
826}
827
828static int philips_tdm1316l_request_firmware(struct dvb_frontend *fe,
829 const struct firmware **fw, char *name)
830{
831 struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
832
833 return request_firmware(fw, name, &budget_ci->budget.dev->pci->dev);
834}
835
836static struct tda1004x_config philips_tdm1316l_config = {
837
838 .demod_address = 0x8,
839 .invert = 0,
840 .invert_oclk = 0,
841 .pll_init = philips_tdm1316l_pll_init,
842 .pll_set = philips_tdm1316l_pll_set,
843 .request_firmware = philips_tdm1316l_request_firmware,
844};
845
846
847
848static void frontend_init(struct budget_ci *budget_ci)
849{
850 switch (budget_ci->budget.dev->pci->subsystem_device) {
851 case 0x100c: // Hauppauge/TT Nova-CI budget (stv0299/ALPS BSRU6(tsa5059))
852 budget_ci->budget.dvb_frontend =
853 stv0299_attach(&alps_bsru6_config, &budget_ci->budget.i2c_adap);
854 if (budget_ci->budget.dvb_frontend) {
855 break;
856 }
857 break;
858
859 case 0x100f: // Hauppauge/TT Nova-CI budget (stv0299b/Philips su1278(tsa5059))
860 budget_ci->budget.dvb_frontend =
861 stv0299_attach(&philips_su1278_tt_config, &budget_ci->budget.i2c_adap);
862 if (budget_ci->budget.dvb_frontend) {
863 break;
864 }
865 break;
866
867 case 0x1011: // Hauppauge/TT Nova-T budget (tda10045/Philips tdm1316l(tda6651tt) + TDA9889)
868 budget_ci->budget.dvb_frontend =
869 tda10045_attach(&philips_tdm1316l_config, &budget_ci->budget.i2c_adap);
870 if (budget_ci->budget.dvb_frontend) {
871 break;
872 }
873 break;
874 }
875
876 if (budget_ci->budget.dvb_frontend == NULL) {
877 printk("budget-ci: A frontend driver was not found for device %04x/%04x subsystem %04x/%04x\n",
878 budget_ci->budget.dev->pci->vendor,
879 budget_ci->budget.dev->pci->device,
880 budget_ci->budget.dev->pci->subsystem_vendor,
881 budget_ci->budget.dev->pci->subsystem_device);
882 } else {
883 if (dvb_register_frontend
884 (budget_ci->budget.dvb_adapter, budget_ci->budget.dvb_frontend)) {
885 printk("budget-ci: Frontend registration failed!\n");
886 if (budget_ci->budget.dvb_frontend->ops->release)
887 budget_ci->budget.dvb_frontend->ops->release(budget_ci->budget.dvb_frontend);
888 budget_ci->budget.dvb_frontend = NULL;
889 }
890 }
891}
892
893static int budget_ci_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
894{
895 struct budget_ci *budget_ci;
896 int err;
897
898 if (!(budget_ci = kmalloc(sizeof(struct budget_ci), GFP_KERNEL)))
899 return -ENOMEM;
900
901 dprintk(2, "budget_ci: %p\n", budget_ci);
902
903 budget_ci->budget.ci_present = 0;
904
905 dev->ext_priv = budget_ci;
906
907 if ((err = ttpci_budget_init(&budget_ci->budget, dev, info, THIS_MODULE))) {
908 kfree(budget_ci);
909 return err;
910 }
911
912 tasklet_init(&budget_ci->msp430_irq_tasklet, msp430_ir_interrupt,
913 (unsigned long) budget_ci);
914
915 msp430_ir_init(budget_ci);
916
917 ciintf_init(budget_ci);
918
919 budget_ci->budget.dvb_adapter->priv = budget_ci;
920 frontend_init(budget_ci);
921
922 return 0;
923}
924
925static int budget_ci_detach(struct saa7146_dev *dev)
926{
927 struct budget_ci *budget_ci = (struct budget_ci *) dev->ext_priv;
928 struct saa7146_dev *saa = budget_ci->budget.dev;
929 int err;
930
931 if (budget_ci->budget.ci_present)
932 ciintf_deinit(budget_ci);
933 if (budget_ci->budget.dvb_frontend)
934 dvb_unregister_frontend(budget_ci->budget.dvb_frontend);
935 err = ttpci_budget_deinit(&budget_ci->budget);
936
937 tasklet_kill(&budget_ci->msp430_irq_tasklet);
938
939 msp430_ir_deinit(budget_ci);
940
941 // disable frontend and CI interface
942 saa7146_setgpio(saa, 2, SAA7146_GPIO_INPUT);
943
944 kfree(budget_ci);
945
946 return err;
947}
948
949static struct saa7146_extension budget_extension;
950
951MAKE_BUDGET_INFO(ttbci, "TT-Budget/WinTV-NOVA-CI PCI", BUDGET_TT_HW_DISEQC);
952MAKE_BUDGET_INFO(ttbt2, "TT-Budget/WinTV-NOVA-T PCI", BUDGET_TT);
953
954static struct pci_device_id pci_tbl[] = {
955 MAKE_EXTENSION_PCI(ttbci, 0x13c2, 0x100c),
956 MAKE_EXTENSION_PCI(ttbci, 0x13c2, 0x100f),
957 MAKE_EXTENSION_PCI(ttbt2, 0x13c2, 0x1011),
958 {
959 .vendor = 0,
960 }
961};
962
963MODULE_DEVICE_TABLE(pci, pci_tbl);
964
965static struct saa7146_extension budget_extension = {
966 .name = "budget_ci dvb\0",
967 .flags = 0,
968
969 .module = THIS_MODULE,
970 .pci_tbl = &pci_tbl[0],
971 .attach = budget_ci_attach,
972 .detach = budget_ci_detach,
973
974 .irq_mask = MASK_03 | MASK_06 | MASK_10,
975 .irq_func = budget_ci_irq,
976};
977
978static int __init budget_ci_init(void)
979{
980 return saa7146_register_extension(&budget_extension);
981}
982
983static void __exit budget_ci_exit(void)
984{
985 saa7146_unregister_extension(&budget_extension);
986}
987
988module_init(budget_ci_init);
989module_exit(budget_ci_exit);
990
991MODULE_LICENSE("GPL");
992MODULE_AUTHOR("Michael Hunold, Jack Thomasson, Andrew de Quincey, others");
993MODULE_DESCRIPTION("driver for the SAA7146 based so-called "
994 "budget PCI DVB cards w/ CI-module produced by "
995 "Siemens, Technotrend, Hauppauge");
diff --git a/drivers/media/dvb/ttpci/budget-core.c b/drivers/media/dvb/ttpci/budget-core.c
new file mode 100644
index 000000000000..93a9b40917e4
--- /dev/null
+++ b/drivers/media/dvb/ttpci/budget-core.c
@@ -0,0 +1,480 @@
1/*
2 * budget-core.c: driver for the SAA7146 based Budget DVB cards
3 *
4 * Compiled from various sources by Michael Hunold <michael@mihu.de>
5 *
6 * Copyright (C) 2002 Ralph Metzler <rjkm@metzlerbros.de>
7 *
8 * Copyright (C) 1999-2002 Ralph Metzler
9 * & Marcus Metzler for convergence integrated media GmbH
10 *
11 * 26feb2004 Support for FS Activy Card (Grundig tuner) by
12 * Michael Dreher <michael@5dot1.de>,
13 * Oliver Endriss <o.endriss@gmx.de>,
14 * Andreas 'randy' Weinberger
15 *
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License
18 * as published by the Free Software Foundation; either version 2
19 * of the License, or (at your option) any later version.
20 *
21 *
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 *
27 *
28 * You should have received a copy of the GNU General Public License
29 * along with this program; if not, write to the Free Software
30 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
31 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
32 *
33 *
34 * the project's page is at http://www.linuxtv.org/dvb/
35 */
36
37#include <linux/moduleparam.h>
38
39#include "budget.h"
40#include "ttpci-eeprom.h"
41
42int budget_debug;
43module_param_named(debug, budget_debug, int, 0644);
44MODULE_PARM_DESC(debug, "Turn on/off budget debugging (default:off).");
45
46/****************************************************************************
47 * TT budget / WinTV Nova
48 ****************************************************************************/
49
50static int stop_ts_capture(struct budget *budget)
51{
52 dprintk(2, "budget: %p\n", budget);
53
54 if (--budget->feeding)
55 return budget->feeding;
56
57 saa7146_write(budget->dev, MC1, MASK_20); // DMA3 off
58 SAA7146_IER_DISABLE(budget->dev, MASK_10);
59 return 0;
60}
61
62static int start_ts_capture(struct budget *budget)
63{
64 struct saa7146_dev *dev = budget->dev;
65
66 dprintk(2, "budget: %p\n", budget);
67
68 if (budget->feeding)
69 return ++budget->feeding;
70
71 saa7146_write(dev, MC1, MASK_20); // DMA3 off
72
73 memset(budget->grabbing, 0x00, TS_HEIGHT * TS_WIDTH);
74
75 saa7146_write(dev, PCI_BT_V1, 0x001c0000 | (saa7146_read(dev, PCI_BT_V1) & ~0x001f0000));
76
77 budget->tsf = 0xff;
78 budget->ttbp = 0;
79
80 /*
81 * Signal path on the Activy:
82 *
83 * tuner -> SAA7146 port A -> SAA7146 BRS -> SAA7146 DMA3 -> memory
84 *
85 * Since the tuner feeds 204 bytes packets into the SAA7146,
86 * DMA3 is configured to strip the trailing 16 FEC bytes:
87 * Pitch: 188, NumBytes3: 188, NumLines3: 1024
88 */
89
90 switch(budget->card->type) {
91 case BUDGET_FS_ACTIVY:
92 saa7146_write(dev, DD1_INIT, 0x04000000);
93 saa7146_write(dev, MC2, (MASK_09 | MASK_25));
94 saa7146_write(dev, BRS_CTRL, 0x00000000);
95 break;
96 case BUDGET_PATCH:
97 saa7146_write(dev, DD1_INIT, 0x00000200);
98 saa7146_write(dev, MC2, (MASK_10 | MASK_26));
99 saa7146_write(dev, BRS_CTRL, 0x60000000);
100 break;
101 default:
102 if (budget->video_port == BUDGET_VIDEO_PORTA) {
103 saa7146_write(dev, DD1_INIT, 0x06000200);
104 saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
105 saa7146_write(dev, BRS_CTRL, 0x00000000);
106 } else {
107 saa7146_write(dev, DD1_INIT, 0x02000600);
108 saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
109 saa7146_write(dev, BRS_CTRL, 0x60000000);
110 }
111 }
112
113 saa7146_write(dev, MC2, (MASK_08 | MASK_24));
114 mdelay(10);
115
116 saa7146_write(dev, BASE_ODD3, 0);
117 saa7146_write(dev, BASE_EVEN3, 0);
118 saa7146_write(dev, PROT_ADDR3, TS_WIDTH * TS_HEIGHT);
119 saa7146_write(dev, BASE_PAGE3, budget->pt.dma | ME1 | 0x90);
120
121 if (budget->card->type == BUDGET_FS_ACTIVY) {
122 saa7146_write(dev, PITCH3, TS_WIDTH / 2);
123 saa7146_write(dev, NUM_LINE_BYTE3, ((TS_HEIGHT * 2) << 16) | (TS_WIDTH / 2));
124 } else {
125 saa7146_write(dev, PITCH3, TS_WIDTH);
126 saa7146_write(dev, NUM_LINE_BYTE3, (TS_HEIGHT << 16) | TS_WIDTH);
127 }
128
129 saa7146_write(dev, MC2, (MASK_04 | MASK_20));
130
131 SAA7146_ISR_CLEAR(budget->dev, MASK_10); /* VPE */
132 SAA7146_IER_ENABLE(budget->dev, MASK_10); /* VPE */
133 saa7146_write(dev, MC1, (MASK_04 | MASK_20)); /* DMA3 on */
134
135 return ++budget->feeding;
136}
137
138static void vpeirq(unsigned long data)
139{
140 struct budget *budget = (struct budget *) data;
141 u8 *mem = (u8 *) (budget->grabbing);
142 u32 olddma = budget->ttbp;
143 u32 newdma = saa7146_read(budget->dev, PCI_VDP3);
144
145 /* nearest lower position divisible by 188 */
146 newdma -= newdma % 188;
147
148 if (newdma >= TS_BUFLEN)
149 return;
150
151 budget->ttbp = newdma;
152
153 if (budget->feeding == 0 || newdma == olddma)
154 return;
155
156 if (newdma > olddma) { /* no wraparound, dump olddma..newdma */
157 dvb_dmx_swfilter_packets(&budget->demux, mem + olddma, (newdma - olddma) / 188);
158 } else { /* wraparound, dump olddma..buflen and 0..newdma */
159 dvb_dmx_swfilter_packets(&budget->demux, mem + olddma, (TS_BUFLEN - olddma) / 188);
160 dvb_dmx_swfilter_packets(&budget->demux, mem, newdma / 188);
161 }
162}
163
164
165int ttpci_budget_debiread(struct budget *budget, u32 config, int addr, int count,
166 int uselocks, int nobusyloop)
167{
168 struct saa7146_dev *saa = budget->dev;
169 int result = 0;
170 unsigned long flags = 0;
171
172 if (count > 4 || count <= 0)
173 return 0;
174
175 if (uselocks)
176 spin_lock_irqsave(&budget->debilock, flags);
177
178 if ((result = saa7146_wait_for_debi_done(saa, nobusyloop)) < 0) {
179 if (uselocks)
180 spin_unlock_irqrestore(&budget->debilock, flags);
181 return result;
182 }
183
184 saa7146_write(saa, DEBI_COMMAND, (count << 17) | 0x10000 | (addr & 0xffff));
185 saa7146_write(saa, DEBI_CONFIG, config);
186 saa7146_write(saa, DEBI_PAGE, 0);
187 saa7146_write(saa, MC2, (2 << 16) | 2);
188
189 if ((result = saa7146_wait_for_debi_done(saa, nobusyloop)) < 0) {
190 if (uselocks)
191 spin_unlock_irqrestore(&budget->debilock, flags);
192 return result;
193 }
194
195 result = saa7146_read(saa, DEBI_AD);
196 result &= (0xffffffffUL >> ((4 - count) * 8));
197
198 if (uselocks)
199 spin_unlock_irqrestore(&budget->debilock, flags);
200
201 return result;
202}
203
204int ttpci_budget_debiwrite(struct budget *budget, u32 config, int addr,
205 int count, u32 value, int uselocks, int nobusyloop)
206{
207 struct saa7146_dev *saa = budget->dev;
208 unsigned long flags = 0;
209 int result;
210
211 if (count > 4 || count <= 0)
212 return 0;
213
214 if (uselocks)
215 spin_lock_irqsave(&budget->debilock, flags);
216
217 if ((result = saa7146_wait_for_debi_done(saa, nobusyloop)) < 0) {
218 if (uselocks)
219 spin_unlock_irqrestore(&budget->debilock, flags);
220 return result;
221 }
222
223 saa7146_write(saa, DEBI_COMMAND, (count << 17) | 0x00000 | (addr & 0xffff));
224 saa7146_write(saa, DEBI_CONFIG, config);
225 saa7146_write(saa, DEBI_PAGE, 0);
226 saa7146_write(saa, DEBI_AD, value);
227 saa7146_write(saa, MC2, (2 << 16) | 2);
228
229 if ((result = saa7146_wait_for_debi_done(saa, nobusyloop)) < 0) {
230 if (uselocks)
231 spin_unlock_irqrestore(&budget->debilock, flags);
232 return result;
233 }
234
235 if (uselocks)
236 spin_unlock_irqrestore(&budget->debilock, flags);
237 return 0;
238}
239
240
241/****************************************************************************
242 * DVB API SECTION
243 ****************************************************************************/
244
245static int budget_start_feed(struct dvb_demux_feed *feed)
246{
247 struct dvb_demux *demux = feed->demux;
248 struct budget *budget = (struct budget *) demux->priv;
249 int status;
250
251 dprintk(2, "budget: %p\n", budget);
252
253 if (!demux->dmx.frontend)
254 return -EINVAL;
255
256 spin_lock(&budget->feedlock);
257 feed->pusi_seen = 0; /* have a clean section start */
258 status = start_ts_capture(budget);
259 spin_unlock(&budget->feedlock);
260 return status;
261}
262
263static int budget_stop_feed(struct dvb_demux_feed *feed)
264{
265 struct dvb_demux *demux = feed->demux;
266 struct budget *budget = (struct budget *) demux->priv;
267 int status;
268
269 dprintk(2, "budget: %p\n", budget);
270
271 spin_lock(&budget->feedlock);
272 status = stop_ts_capture(budget);
273 spin_unlock(&budget->feedlock);
274 return status;
275}
276
277static int budget_register(struct budget *budget)
278{
279 struct dvb_demux *dvbdemux = &budget->demux;
280 int ret;
281
282 dprintk(2, "budget: %p\n", budget);
283
284 dvbdemux->priv = (void *) budget;
285
286 dvbdemux->filternum = 256;
287 dvbdemux->feednum = 256;
288 dvbdemux->start_feed = budget_start_feed;
289 dvbdemux->stop_feed = budget_stop_feed;
290 dvbdemux->write_to_decoder = NULL;
291
292 dvbdemux->dmx.capabilities = (DMX_TS_FILTERING | DMX_SECTION_FILTERING |
293 DMX_MEMORY_BASED_FILTERING);
294
295 dvb_dmx_init(&budget->demux);
296
297 budget->dmxdev.filternum = 256;
298 budget->dmxdev.demux = &dvbdemux->dmx;
299 budget->dmxdev.capabilities = 0;
300
301 dvb_dmxdev_init(&budget->dmxdev, budget->dvb_adapter);
302
303 budget->hw_frontend.source = DMX_FRONTEND_0;
304
305 ret = dvbdemux->dmx.add_frontend(&dvbdemux->dmx, &budget->hw_frontend);
306
307 if (ret < 0)
308 return ret;
309
310 budget->mem_frontend.source = DMX_MEMORY_FE;
311 ret = dvbdemux->dmx.add_frontend(&dvbdemux->dmx, &budget->mem_frontend);
312 if (ret < 0)
313 return ret;
314
315 ret = dvbdemux->dmx.connect_frontend(&dvbdemux->dmx, &budget->hw_frontend);
316 if (ret < 0)
317 return ret;
318
319 dvb_net_init(budget->dvb_adapter, &budget->dvb_net, &dvbdemux->dmx);
320
321 return 0;
322}
323
324static void budget_unregister(struct budget *budget)
325{
326 struct dvb_demux *dvbdemux = &budget->demux;
327
328 dprintk(2, "budget: %p\n", budget);
329
330 dvb_net_release(&budget->dvb_net);
331
332 dvbdemux->dmx.close(&dvbdemux->dmx);
333 dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, &budget->hw_frontend);
334 dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, &budget->mem_frontend);
335
336 dvb_dmxdev_release(&budget->dmxdev);
337 dvb_dmx_release(&budget->demux);
338}
339
340int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev,
341 struct saa7146_pci_extension_data *info,
342 struct module *owner)
343{
344 int length = TS_WIDTH * TS_HEIGHT;
345 int ret = 0;
346 struct budget_info *bi = info->ext_priv;
347
348 memset(budget, 0, sizeof(struct budget));
349
350 dprintk(2, "dev: %p, budget: %p\n", dev, budget);
351
352 budget->card = bi;
353 budget->dev = (struct saa7146_dev *) dev;
354
355 dvb_register_adapter(&budget->dvb_adapter, budget->card->name, owner);
356
357 /* set dd1 stream a & b */
358 saa7146_write(dev, DD1_STREAM_B, 0x00000000);
359 saa7146_write(dev, MC2, (MASK_09 | MASK_25));
360 saa7146_write(dev, MC2, (MASK_10 | MASK_26));
361 saa7146_write(dev, DD1_INIT, 0x02000000);
362 saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
363
364 if (bi->type != BUDGET_FS_ACTIVY)
365 budget->video_port = BUDGET_VIDEO_PORTB;
366 else
367 budget->video_port = BUDGET_VIDEO_PORTA;
368 spin_lock_init(&budget->feedlock);
369 spin_lock_init(&budget->debilock);
370
371 /* the Siemens DVB needs this if you want to have the i2c chips
372 get recognized before the main driver is loaded */
373 if (bi->type != BUDGET_FS_ACTIVY)
374 saa7146_write(dev, GPIO_CTRL, 0x500000); /* GPIO 3 = 1 */
375
376#ifdef I2C_ADAP_CLASS_TV_DIGITAL
377 budget->i2c_adap.class = I2C_ADAP_CLASS_TV_DIGITAL;
378#else
379 budget->i2c_adap.class = I2C_CLASS_TV_DIGITAL;
380#endif
381
382 strlcpy(budget->i2c_adap.name, budget->card->name, sizeof(budget->i2c_adap.name));
383
384 saa7146_i2c_adapter_prepare(dev, &budget->i2c_adap, SAA7146_I2C_BUS_BIT_RATE_120);
385 strcpy(budget->i2c_adap.name, budget->card->name);
386
387 if (i2c_add_adapter(&budget->i2c_adap) < 0) {
388 dvb_unregister_adapter(budget->dvb_adapter);
389 return -ENOMEM;
390 }
391
392 ttpci_eeprom_parse_mac(&budget->i2c_adap, budget->dvb_adapter->proposed_mac);
393
394 if (NULL ==
395 (budget->grabbing = saa7146_vmalloc_build_pgtable(dev->pci, length, &budget->pt))) {
396 ret = -ENOMEM;
397 goto err;
398 }
399
400 saa7146_write(dev, PCI_BT_V1, 0x001c0000);
401 /* upload all */
402 saa7146_write(dev, GPIO_CTRL, 0x000000);
403
404 tasklet_init(&budget->vpe_tasklet, vpeirq, (unsigned long) budget);
405
406 /* frontend power on */
407 if (bi->type == BUDGET_FS_ACTIVY)
408 saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI);
409 else
410 saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTHI);
411
412 if (budget_register(budget) == 0) {
413 return 0;
414 }
415err:
416 i2c_del_adapter(&budget->i2c_adap);
417
418 vfree(budget->grabbing);
419
420 dvb_unregister_adapter(budget->dvb_adapter);
421
422 return ret;
423}
424
425int ttpci_budget_deinit(struct budget *budget)
426{
427 struct saa7146_dev *dev = budget->dev;
428
429 dprintk(2, "budget: %p\n", budget);
430
431 budget_unregister(budget);
432
433 i2c_del_adapter(&budget->i2c_adap);
434
435 dvb_unregister_adapter(budget->dvb_adapter);
436
437 tasklet_kill(&budget->vpe_tasklet);
438
439 saa7146_pgtable_free(dev->pci, &budget->pt);
440
441 vfree(budget->grabbing);
442
443 return 0;
444}
445
446void ttpci_budget_irq10_handler(struct saa7146_dev *dev, u32 * isr)
447{
448 struct budget *budget = (struct budget *) dev->ext_priv;
449
450 dprintk(8, "dev: %p, budget: %p\n", dev, budget);
451
452 if (*isr & MASK_10)
453 tasklet_schedule(&budget->vpe_tasklet);
454}
455
456void ttpci_budget_set_video_port(struct saa7146_dev *dev, int video_port)
457{
458 struct budget *budget = (struct budget *) dev->ext_priv;
459
460 spin_lock(&budget->feedlock);
461 budget->video_port = video_port;
462 if (budget->feeding) {
463 int oldfeeding = budget->feeding;
464 budget->feeding = 1;
465 stop_ts_capture(budget);
466 start_ts_capture(budget);
467 budget->feeding = oldfeeding;
468 }
469 spin_unlock(&budget->feedlock);
470}
471
472EXPORT_SYMBOL_GPL(ttpci_budget_debiread);
473EXPORT_SYMBOL_GPL(ttpci_budget_debiwrite);
474EXPORT_SYMBOL_GPL(ttpci_budget_init);
475EXPORT_SYMBOL_GPL(ttpci_budget_deinit);
476EXPORT_SYMBOL_GPL(ttpci_budget_irq10_handler);
477EXPORT_SYMBOL_GPL(ttpci_budget_set_video_port);
478EXPORT_SYMBOL_GPL(budget_debug);
479
480MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/ttpci/budget-patch.c b/drivers/media/dvb/ttpci/budget-patch.c
new file mode 100644
index 000000000000..5d524a4f213f
--- /dev/null
+++ b/drivers/media/dvb/ttpci/budget-patch.c
@@ -0,0 +1,754 @@
1/*
2 * budget-patch.c: driver for Budget Patch,
3 * hardware modification of DVB-S cards enabling full TS
4 *
5 * Written by Emard <emard@softhome.net>
6 *
7 * Original idea by Roberto Deza <rdeza@unav.es>
8 *
9 * Special thanks to Holger Waechtler, Michael Hunold, Marian Durkovic
10 * and Metzlerbros
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
28 *
29 *
30 * the project's page is at http://www.linuxtv.org/dvb/
31 */
32
33#include "av7110.h"
34#include "av7110_hw.h"
35#include "budget.h"
36#include "stv0299.h"
37#include "ves1x93.h"
38#include "tda8083.h"
39
40#define budget_patch budget
41
42static struct saa7146_extension budget_extension;
43
44MAKE_BUDGET_INFO(ttbp, "TT-Budget/Patch DVB-S 1.x PCI", BUDGET_PATCH);
45//MAKE_BUDGET_INFO(satel,"TT-Budget/Patch SATELCO PCI", BUDGET_TT_HW_DISEQC);
46
47static struct pci_device_id pci_tbl[] = {
48 MAKE_EXTENSION_PCI(ttbp,0x13c2, 0x0000),
49// MAKE_EXTENSION_PCI(satel, 0x13c2, 0x1013),
50 {
51 .vendor = 0,
52 }
53};
54
55/* those lines are for budget-patch to be tried
56** on a true budget card and observe the
57** behaviour of VSYNC generated by rps1.
58** this code was shamelessly copy/pasted from budget.c
59*/
60static void gpio_Set22K (struct budget *budget, int state)
61{
62 struct saa7146_dev *dev=budget->dev;
63 dprintk(2, "budget: %p\n", budget);
64 saa7146_setgpio(dev, 3, (state ? SAA7146_GPIO_OUTHI : SAA7146_GPIO_OUTLO));
65}
66
67/* Diseqc functions only for TT Budget card */
68/* taken from the Skyvision DVB driver by
69 Ralph Metzler <rjkm@metzlerbros.de> */
70
71static void DiseqcSendBit (struct budget *budget, int data)
72{
73 struct saa7146_dev *dev=budget->dev;
74 dprintk(2, "budget: %p\n", budget);
75
76 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI);
77 udelay(data ? 500 : 1000);
78 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
79 udelay(data ? 1000 : 500);
80}
81
82static void DiseqcSendByte (struct budget *budget, int data)
83{
84 int i, par=1, d;
85
86 dprintk(2, "budget: %p\n", budget);
87
88 for (i=7; i>=0; i--) {
89 d = (data>>i)&1;
90 par ^= d;
91 DiseqcSendBit(budget, d);
92 }
93
94 DiseqcSendBit(budget, par);
95}
96
97static int SendDiSEqCMsg (struct budget *budget, int len, u8 *msg, unsigned long burst)
98{
99 struct saa7146_dev *dev=budget->dev;
100 int i;
101
102 dprintk(2, "budget: %p\n", budget);
103
104 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
105 mdelay(16);
106
107 for (i=0; i<len; i++)
108 DiseqcSendByte(budget, msg[i]);
109
110 mdelay(16);
111
112 if (burst!=-1) {
113 if (burst)
114 DiseqcSendByte(budget, 0xff);
115 else {
116 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI);
117 udelay(12500);
118 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
119 }
120 msleep(20);
121 }
122
123 return 0;
124}
125
126/* shamelessly copy/pasted from budget.c
127*/
128static int budget_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
129{
130 struct budget* budget = (struct budget*) fe->dvb->priv;
131
132 switch (tone) {
133 case SEC_TONE_ON:
134 gpio_Set22K (budget, 1);
135 break;
136
137 case SEC_TONE_OFF:
138 gpio_Set22K (budget, 0);
139 break;
140
141 default:
142 return -EINVAL;
143 }
144
145 return 0;
146}
147
148static int budget_diseqc_send_master_cmd(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd)
149{
150 struct budget* budget = (struct budget*) fe->dvb->priv;
151
152 SendDiSEqCMsg (budget, cmd->msg_len, cmd->msg, 0);
153
154 return 0;
155}
156
157static int budget_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd)
158{
159 struct budget* budget = (struct budget*) fe->dvb->priv;
160
161 SendDiSEqCMsg (budget, 0, NULL, minicmd);
162
163 return 0;
164}
165
166static int budget_av7110_send_fw_cmd(struct budget_patch *budget, u16* buf, int length)
167{
168 int i;
169
170 dprintk(2, "budget: %p\n", budget);
171
172 for (i = 2; i < length; i++)
173 {
174 ttpci_budget_debiwrite(budget, DEBINOSWAP, COMMAND + 2*i, 2, (u32) buf[i], 0,0);
175 msleep(5);
176 }
177 if (length)
178 ttpci_budget_debiwrite(budget, DEBINOSWAP, COMMAND + 2, 2, (u32) buf[1], 0,0);
179 else
180 ttpci_budget_debiwrite(budget, DEBINOSWAP, COMMAND + 2, 2, 0, 0,0);
181 msleep(5);
182 ttpci_budget_debiwrite(budget, DEBINOSWAP, COMMAND, 2, (u32) buf[0], 0,0);
183 msleep(5);
184 return 0;
185}
186
187static void av7110_set22k(struct budget_patch *budget, int state)
188{
189 u16 buf[2] = {( COMTYPE_AUDIODAC << 8) | (state ? ON22K : OFF22K), 0};
190
191 dprintk(2, "budget: %p\n", budget);
192 budget_av7110_send_fw_cmd(budget, buf, 2);
193}
194
195static int av7110_send_diseqc_msg(struct budget_patch *budget, int len, u8 *msg, int burst)
196{
197 int i;
198 u16 buf[18] = { ((COMTYPE_AUDIODAC << 8) | SendDiSEqC),
199 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
200
201 dprintk(2, "budget: %p\n", budget);
202
203 if (len>10)
204 len=10;
205
206 buf[1] = len+2;
207 buf[2] = len;
208
209 if (burst != -1)
210 buf[3]=burst ? 0x01 : 0x00;
211 else
212 buf[3]=0xffff;
213
214 for (i=0; i<len; i++)
215 buf[i+4]=msg[i];
216
217 budget_av7110_send_fw_cmd(budget, buf, 18);
218 return 0;
219}
220
221static int budget_patch_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
222{
223 struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv;
224
225 switch (tone) {
226 case SEC_TONE_ON:
227 av7110_set22k (budget, 1);
228 break;
229
230 case SEC_TONE_OFF:
231 av7110_set22k (budget, 0);
232 break;
233
234 default:
235 return -EINVAL;
236 }
237
238 return 0;
239}
240
241static int budget_patch_diseqc_send_master_cmd(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd)
242{
243 struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv;
244
245 av7110_send_diseqc_msg (budget, cmd->msg_len, cmd->msg, 0);
246
247 return 0;
248}
249
250static int budget_patch_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd)
251{
252 struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv;
253
254 av7110_send_diseqc_msg (budget, 0, NULL, minicmd);
255
256 return 0;
257}
258
259static int alps_bsrv2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
260{
261 struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv;
262 u8 pwr = 0;
263 u8 buf[4];
264 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
265 u32 div = (params->frequency + 479500) / 125;
266
267 if (params->frequency > 2000000) pwr = 3;
268 else if (params->frequency > 1800000) pwr = 2;
269 else if (params->frequency > 1600000) pwr = 1;
270 else if (params->frequency > 1200000) pwr = 0;
271 else if (params->frequency >= 1100000) pwr = 1;
272 else pwr = 2;
273
274 buf[0] = (div >> 8) & 0x7f;
275 buf[1] = div & 0xff;
276 buf[2] = ((div & 0x18000) >> 10) | 0x95;
277 buf[3] = (pwr << 6) | 0x30;
278
279 // NOTE: since we're using a prescaler of 2, we set the
280 // divisor frequency to 62.5kHz and divide by 125 above
281
282 if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO;
283 return 0;
284}
285
286static struct ves1x93_config alps_bsrv2_config = {
287 .demod_address = 0x08,
288 .xin = 90100000UL,
289 .invert_pwm = 0,
290 .pll_set = alps_bsrv2_pll_set,
291};
292
293static u8 alps_bsru6_inittab[] = {
294 0x01, 0x15,
295 0x02, 0x00,
296 0x03, 0x00,
297 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
298 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */
299 0x06, 0x40, /* DAC not used, set to high impendance mode */
300 0x07, 0x00, /* DAC LSB */
301 0x08, 0x40, /* DiSEqC off, LNB power on OP2/LOCK pin on */
302 0x09, 0x00, /* FIFO */
303 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
304 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */
305 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
306 0x10, 0x3f, // AGC2 0x3d
307 0x11, 0x84,
308 0x12, 0xb5, // Lock detect: -64 Carrier freq detect:on
309 0x15, 0xc9, // lock detector threshold
310 0x16, 0x00,
311 0x17, 0x00,
312 0x18, 0x00,
313 0x19, 0x00,
314 0x1a, 0x00,
315 0x1f, 0x50,
316 0x20, 0x00,
317 0x21, 0x00,
318 0x22, 0x00,
319 0x23, 0x00,
320 0x28, 0x00, // out imp: normal out type: parallel FEC mode:0
321 0x29, 0x1e, // 1/2 threshold
322 0x2a, 0x14, // 2/3 threshold
323 0x2b, 0x0f, // 3/4 threshold
324 0x2c, 0x09, // 5/6 threshold
325 0x2d, 0x05, // 7/8 threshold
326 0x2e, 0x01,
327 0x31, 0x1f, // test all FECs
328 0x32, 0x19, // viterbi and synchro search
329 0x33, 0xfc, // rs control
330 0x34, 0x93, // error control
331 0x0f, 0x52,
332 0xff, 0xff
333};
334
335static int alps_bsru6_set_symbol_rate(struct dvb_frontend* fe, u32 srate, u32 ratio)
336{
337 u8 aclk = 0;
338 u8 bclk = 0;
339
340 if (srate < 1500000) { aclk = 0xb7; bclk = 0x47; }
341 else if (srate < 3000000) { aclk = 0xb7; bclk = 0x4b; }
342 else if (srate < 7000000) { aclk = 0xb7; bclk = 0x4f; }
343 else if (srate < 14000000) { aclk = 0xb7; bclk = 0x53; }
344 else if (srate < 30000000) { aclk = 0xb6; bclk = 0x53; }
345 else if (srate < 45000000) { aclk = 0xb4; bclk = 0x51; }
346
347 stv0299_writereg (fe, 0x13, aclk);
348 stv0299_writereg (fe, 0x14, bclk);
349 stv0299_writereg (fe, 0x1f, (ratio >> 16) & 0xff);
350 stv0299_writereg (fe, 0x20, (ratio >> 8) & 0xff);
351 stv0299_writereg (fe, 0x21, (ratio ) & 0xf0);
352
353 return 0;
354}
355
356static int alps_bsru6_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
357{
358 struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv;
359 u8 data[4];
360 u32 div;
361 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
362
363 if ((params->frequency < 950000) || (params->frequency > 2150000)) return -EINVAL;
364
365 div = (params->frequency + (125 - 1)) / 125; // round correctly
366 data[0] = (div >> 8) & 0x7f;
367 data[1] = div & 0xff;
368 data[2] = 0x80 | ((div & 0x18000) >> 10) | 4;
369 data[3] = 0xC4;
370
371 if (params->frequency > 1530000) data[3] = 0xc0;
372
373 if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO;
374 return 0;
375}
376
377static struct stv0299_config alps_bsru6_config = {
378
379 .demod_address = 0x68,
380 .inittab = alps_bsru6_inittab,
381 .mclk = 88000000UL,
382 .invert = 1,
383 .enhanced_tuning = 0,
384 .skip_reinit = 0,
385 .lock_output = STV0229_LOCKOUTPUT_1,
386 .volt13_op0_op1 = STV0299_VOLT13_OP1,
387 .min_delay_ms = 100,
388 .set_symbol_rate = alps_bsru6_set_symbol_rate,
389 .pll_set = alps_bsru6_pll_set,
390};
391
392static int grundig_29504_451_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
393{
394 struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv;
395 u32 div;
396 u8 data[4];
397 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
398
399 div = params->frequency / 125;
400 data[0] = (div >> 8) & 0x7f;
401 data[1] = div & 0xff;
402 data[2] = 0x8e;
403 data[3] = 0x00;
404
405 if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO;
406 return 0;
407}
408
409static struct tda8083_config grundig_29504_451_config = {
410 .demod_address = 0x68,
411 .pll_set = grundig_29504_451_pll_set,
412};
413
414static void frontend_init(struct budget_patch* budget)
415{
416 switch(budget->dev->pci->subsystem_device) {
417 case 0x0000: // Hauppauge/TT WinTV DVB-S rev1.X
418 case 0x1013: // SATELCO Multimedia PCI
419
420 // try the ALPS BSRV2 first of all
421 budget->dvb_frontend = ves1x93_attach(&alps_bsrv2_config, &budget->i2c_adap);
422 if (budget->dvb_frontend) {
423 budget->dvb_frontend->ops->diseqc_send_master_cmd = budget_patch_diseqc_send_master_cmd;
424 budget->dvb_frontend->ops->diseqc_send_burst = budget_patch_diseqc_send_burst;
425 budget->dvb_frontend->ops->set_tone = budget_patch_set_tone;
426 break;
427 }
428
429 // try the ALPS BSRU6 now
430 budget->dvb_frontend = stv0299_attach(&alps_bsru6_config, &budget->i2c_adap);
431 if (budget->dvb_frontend) {
432 budget->dvb_frontend->ops->diseqc_send_master_cmd = budget_diseqc_send_master_cmd;
433 budget->dvb_frontend->ops->diseqc_send_burst = budget_diseqc_send_burst;
434 budget->dvb_frontend->ops->set_tone = budget_set_tone;
435 break;
436 }
437
438 // Try the grundig 29504-451
439 budget->dvb_frontend = tda8083_attach(&grundig_29504_451_config, &budget->i2c_adap);
440 if (budget->dvb_frontend) {
441 budget->dvb_frontend->ops->diseqc_send_master_cmd = budget_diseqc_send_master_cmd;
442 budget->dvb_frontend->ops->diseqc_send_burst = budget_diseqc_send_burst;
443 budget->dvb_frontend->ops->set_tone = budget_set_tone;
444 break;
445 }
446 break;
447 }
448
449 if (budget->dvb_frontend == NULL) {
450 printk("dvb-ttpci: A frontend driver was not found for device %04x/%04x subsystem %04x/%04x\n",
451 budget->dev->pci->vendor,
452 budget->dev->pci->device,
453 budget->dev->pci->subsystem_vendor,
454 budget->dev->pci->subsystem_device);
455 } else {
456 if (dvb_register_frontend(budget->dvb_adapter, budget->dvb_frontend)) {
457 printk("budget-av: Frontend registration failed!\n");
458 if (budget->dvb_frontend->ops->release)
459 budget->dvb_frontend->ops->release(budget->dvb_frontend);
460 budget->dvb_frontend = NULL;
461 }
462 }
463}
464
465/* written by Emard */
466static int budget_patch_attach (struct saa7146_dev* dev, struct saa7146_pci_extension_data *info)
467{
468 struct budget_patch *budget;
469 int err;
470 int count = 0;
471 int detected = 0;
472
473#define PATCH_RESET 0
474#define RPS_IRQ 0
475#define HPS_SETUP 0
476#if PATCH_RESET
477 saa7146_write(dev, MC1, MASK_31);
478 msleep(40);
479#endif
480#if HPS_SETUP
481 // initialize registers. Better to have it like this
482 // than leaving something unconfigured
483 saa7146_write(dev, DD1_STREAM_B, 0);
484 // port B VSYNC at rising edge
485 saa7146_write(dev, DD1_INIT, 0x00000200); // have this in budget-core too!
486 saa7146_write(dev, BRS_CTRL, 0x00000000); // VBI
487
488 // debi config
489 // saa7146_write(dev, DEBI_CONFIG, MASK_30|MASK_28|MASK_18);
490
491 // zero all HPS registers
492 saa7146_write(dev, HPS_H_PRESCALE, 0); // r68
493 saa7146_write(dev, HPS_H_SCALE, 0); // r6c
494 saa7146_write(dev, BCS_CTRL, 0); // r70
495 saa7146_write(dev, HPS_V_SCALE, 0); // r60
496 saa7146_write(dev, HPS_V_GAIN, 0); // r64
497 saa7146_write(dev, CHROMA_KEY_RANGE, 0); // r74
498 saa7146_write(dev, CLIP_FORMAT_CTRL, 0); // r78
499 // Set HPS prescaler for port B input
500 saa7146_write(dev, HPS_CTRL, (1<<30) | (0<<29) | (1<<28) | (0<<12) );
501 saa7146_write(dev, MC2,
502 0 * (MASK_08 | MASK_24) | // BRS control
503 0 * (MASK_09 | MASK_25) | // a
504 0 * (MASK_10 | MASK_26) | // b
505 1 * (MASK_06 | MASK_22) | // HPS_CTRL1
506 1 * (MASK_05 | MASK_21) | // HPS_CTRL2
507 0 * (MASK_01 | MASK_15) // DEBI
508 );
509#endif
510 // Disable RPS1 and RPS0
511 saa7146_write(dev, MC1, ( MASK_29 | MASK_28));
512 // RPS1 timeout disable
513 saa7146_write(dev, RPS_TOV1, 0);
514
515 // code for autodetection
516 // will wait for VBI_B event (vertical blank at port B)
517 // and will reset GPIO3 after VBI_B is detected.
518 // (GPIO3 should be raised high by CPU to
519 // test if GPIO3 will generate vertical blank signal
520 // in budget patch GPIO3 is connected to VSYNC_B
521 count = 0;
522#if 0
523 WRITE_RPS1(cpu_to_le32(CMD_UPLOAD |
524 MASK_10 | MASK_09 | MASK_08 | MASK_06 | MASK_05 | MASK_04 | MASK_03 | MASK_02 ));
525#endif
526 WRITE_RPS1(cpu_to_le32(CMD_PAUSE | EVT_VBI_B));
527 WRITE_RPS1(cpu_to_le32(CMD_WR_REG_MASK | (GPIO_CTRL>>2)));
528 WRITE_RPS1(cpu_to_le32(GPIO3_MSK));
529 WRITE_RPS1(cpu_to_le32(SAA7146_GPIO_OUTLO<<24));
530#if RPS_IRQ
531 // issue RPS1 interrupt to increment counter
532 WRITE_RPS1(cpu_to_le32(CMD_INTERRUPT));
533 // at least a NOP is neede between two interrupts
534 WRITE_RPS1(cpu_to_le32(CMD_NOP));
535 // interrupt again
536 WRITE_RPS1(cpu_to_le32(CMD_INTERRUPT));
537#endif
538 WRITE_RPS1(cpu_to_le32(CMD_STOP));
539
540#if RPS_IRQ
541 // set event counter 1 source as RPS1 interrupt (0x03) (rE4 p53)
542 // use 0x03 to track RPS1 interrupts - increase by 1 every gpio3 is toggled
543 // use 0x15 to track VPE interrupts - increase by 1 every vpeirq() is called
544 saa7146_write(dev, EC1SSR, (0x03<<2) | 3 );
545 // set event counter 1 treshold to maximum allowed value (rEC p55)
546 saa7146_write(dev, ECT1R, 0x3fff );
547#endif
548 // Fix VSYNC level
549 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
550 // Set RPS1 Address register to point to RPS code (r108 p42)
551 saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle);
552 // Enable RPS1, (rFC p33)
553 saa7146_write(dev, MC1, (MASK_13 | MASK_29 ));
554
555
556 mdelay(50);
557 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI);
558 mdelay(150);
559
560
561 if( (saa7146_read(dev, GPIO_CTRL) & 0x10000000) == 0)
562 detected = 1;
563
564#if RPS_IRQ
565 printk("Event Counter 1 0x%04x\n", saa7146_read(dev, EC1R) & 0x3fff );
566#endif
567 // Disable RPS1
568 saa7146_write(dev, MC1, ( MASK_29 ));
569
570 if(detected == 0)
571 printk("budget-patch not detected or saa7146 in non-default state.\n"
572 "try enabling ressetting of 7146 with MASK_31 in MC1 register\n");
573
574 else
575 printk("BUDGET-PATCH DETECTED.\n");
576
577
578/* OLD (Original design by Roberto Deza):
579** This code will setup the SAA7146_RPS1 to generate a square
580** wave on GPIO3, changing when a field (TS_HEIGHT/2 "lines" of
581** TS_WIDTH packets) has been acquired on SAA7146_D1B video port;
582** then, this GPIO3 output which is connected to the D1B_VSYNC
583** input, will trigger the acquisition of the alternate field
584** and so on.
585** Currently, the TT_budget / WinTV_Nova cards have two ICs
586** (74HCT4040, LVC74) for the generation of this VSYNC signal,
587** which seems that can be done perfectly without this :-)).
588*/
589
590/* New design (By Emard)
591** this rps1 code will copy internal HS event to GPIO3 pin.
592** GPIO3 is in budget-patch hardware connectd to port B VSYNC
593
594** HS is an internal event of 7146, accessible with RPS
595** and temporarily raised high every n lines
596** (n in defined in the RPS_THRESH1 counter threshold)
597** I think HS is raised high on the beginning of the n-th line
598** and remains high until this n-th line that triggered
599** it is completely received. When the receiption of n-th line
600** ends, HS is lowered.
601
602** To transmit data over DMA, 7146 needs changing state at
603** port B VSYNC pin. Any changing of port B VSYNC will
604** cause some DMA data transfer, with more or less packets loss.
605** It depends on the phase and frequency of VSYNC and
606** the way of 7146 is instructed to trigger on port B (defined
607** in DD1_INIT register, 3rd nibble from the right valid
608** numbers are 0-7, see datasheet)
609**
610** The correct triggering can minimize packet loss,
611** dvbtraffic should give this stable bandwidths:
612** 22k transponder = 33814 kbit/s
613** 27.5k transponder = 38045 kbit/s
614** by experiment it is found that the best results
615** (stable bandwidths and almost no packet loss)
616** are obtained using DD1_INIT triggering number 2
617** (Va at rising edge of VS Fa = HS x VS-failing forced toggle)
618** and a VSYNC phase that occurs in the middle of DMA transfer
619** (about byte 188*512=96256 in the DMA window).
620**
621** Phase of HS is still not clear to me how to control,
622** It just happens to be so. It can be seen if one enables
623** RPS_IRQ and print Event Counter 1 in vpeirq(). Every
624** time RPS_INTERRUPT is called, the Event Counter 1 will
625** increment. That's how the 7146 is programmed to do event
626** counting in this budget-patch.c
627** I *think* HPS setting has something to do with the phase
628** of HS but I cant be 100% sure in that.
629
630** hardware debug note: a working budget card (including budget patch)
631** with vpeirq() interrupt setup in mode "0x90" (every 64K) will
632** generate 3 interrupts per 25-Hz DMA frame of 2*188*512 bytes
633** and that means 3*25=75 Hz of interrupt freqency, as seen by
634** watch cat /proc/interrupts
635**
636** If this frequency is 3x lower (and data received in the DMA
637** buffer don't start with 0x47, but in the middle of packets,
638** whose lengths appear to be like 188 292 188 104 etc.
639** this means VSYNC line is not connected in the hardware.
640** (check soldering pcb and pins)
641** The same behaviour of missing VSYNC can be duplicated on budget
642** cards, by seting DD1_INIT trigger mode 7 in 3rd nibble.
643*/
644
645 // Setup RPS1 "program" (p35)
646 count = 0;
647
648
649 // Wait Source Line Counter Threshold (p36)
650 WRITE_RPS1(cpu_to_le32(CMD_PAUSE | EVT_HS));
651 // Set GPIO3=1 (p42)
652 WRITE_RPS1(cpu_to_le32(CMD_WR_REG_MASK | (GPIO_CTRL>>2)));
653 WRITE_RPS1(cpu_to_le32(GPIO3_MSK));
654 WRITE_RPS1(cpu_to_le32(SAA7146_GPIO_OUTHI<<24));
655#if RPS_IRQ
656 // issue RPS1 interrupt
657 WRITE_RPS1(cpu_to_le32(CMD_INTERRUPT));
658#endif
659 // Wait reset Source Line Counter Threshold (p36)
660 WRITE_RPS1(cpu_to_le32(CMD_PAUSE | RPS_INV | EVT_HS));
661 // Set GPIO3=0 (p42)
662 WRITE_RPS1(cpu_to_le32(CMD_WR_REG_MASK | (GPIO_CTRL>>2)));
663 WRITE_RPS1(cpu_to_le32(GPIO3_MSK));
664 WRITE_RPS1(cpu_to_le32(SAA7146_GPIO_OUTLO<<24));
665#if RPS_IRQ
666 // issue RPS1 interrupt
667 WRITE_RPS1(cpu_to_le32(CMD_INTERRUPT));
668#endif
669 // Jump to begin of RPS program (p37)
670 WRITE_RPS1(cpu_to_le32(CMD_JUMP));
671 WRITE_RPS1(cpu_to_le32(dev->d_rps1.dma_handle));
672
673 // Fix VSYNC level
674 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
675 // Set RPS1 Address register to point to RPS code (r108 p42)
676 saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle);
677 // Set Source Line Counter Threshold, using BRS (rCC p43)
678 // It generates HS event every TS_HEIGHT lines
679 // this is related to TS_WIDTH set in register
680 // NUM_LINE_BYTE3 in budget-core.c. If NUM_LINE_BYTE
681 // low 16 bits are set to TS_WIDTH bytes (TS_WIDTH=2*188
682 //,then RPS_THRESH1
683 // should be set to trigger every TS_HEIGHT (512) lines.
684 //
685 saa7146_write(dev, RPS_THRESH1, (TS_HEIGHT*1) | MASK_12 );
686
687 // saa7146_write(dev, RPS_THRESH0, ((TS_HEIGHT/2)<<16) |MASK_28| (TS_HEIGHT/2) |MASK_12 );
688 // Enable RPS1 (rFC p33)
689 saa7146_write(dev, MC1, (MASK_13 | MASK_29));
690
691
692 if (!(budget = kmalloc (sizeof(struct budget_patch), GFP_KERNEL)))
693 return -ENOMEM;
694
695 dprintk(2, "budget: %p\n", budget);
696
697 if ((err = ttpci_budget_init (budget, dev, info, THIS_MODULE))) {
698 kfree (budget);
699 return err;
700 }
701
702
703 dev->ext_priv = budget;
704
705 budget->dvb_adapter->priv = budget;
706 frontend_init(budget);
707
708 return 0;
709}
710
711static int budget_patch_detach (struct saa7146_dev* dev)
712{
713 struct budget_patch *budget = (struct budget_patch*) dev->ext_priv;
714 int err;
715
716 if (budget->dvb_frontend) dvb_unregister_frontend(budget->dvb_frontend);
717
718 err = ttpci_budget_deinit (budget);
719
720 kfree (budget);
721
722 return err;
723}
724
725static int __init budget_patch_init(void)
726{
727 return saa7146_register_extension(&budget_extension);
728}
729
730static void __exit budget_patch_exit(void)
731{
732 saa7146_unregister_extension(&budget_extension);
733}
734
735static struct saa7146_extension budget_extension = {
736 .name = "budget_patch dvb\0",
737 .flags = 0,
738
739 .module = THIS_MODULE,
740 .pci_tbl = pci_tbl,
741 .attach = budget_patch_attach,
742 .detach = budget_patch_detach,
743
744 .irq_mask = MASK_10,
745 .irq_func = ttpci_budget_irq10_handler,
746};
747
748module_init(budget_patch_init);
749module_exit(budget_patch_exit);
750
751MODULE_LICENSE("GPL");
752MODULE_AUTHOR("Emard, Roberto Deza, Holger Waechtler, Michael Hunold, others");
753MODULE_DESCRIPTION("Driver for full TS modified DVB-S SAA7146+AV7110 "
754 "based so-called Budget Patch cards");
diff --git a/drivers/media/dvb/ttpci/budget.c b/drivers/media/dvb/ttpci/budget.c
new file mode 100644
index 000000000000..5e6a10f4ad95
--- /dev/null
+++ b/drivers/media/dvb/ttpci/budget.c
@@ -0,0 +1,573 @@
1/*
2 * budget.c: driver for the SAA7146 based Budget DVB cards
3 *
4 * Compiled from various sources by Michael Hunold <michael@mihu.de>
5 *
6 * Copyright (C) 2002 Ralph Metzler <rjkm@metzlerbros.de>
7 *
8 * Copyright (C) 1999-2002 Ralph Metzler
9 * & Marcus Metzler for convergence integrated media GmbH
10 *
11 * 26feb2004 Support for FS Activy Card (Grundig tuner) by
12 * Michael Dreher <michael@5dot1.de>,
13 * Oliver Endriss <o.endriss@gmx.de> and
14 * Andreas 'randy' Weinberger
15 *
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License
18 * as published by the Free Software Foundation; either version 2
19 * of the License, or (at your option) any later version.
20 *
21 *
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 *
27 *
28 * You should have received a copy of the GNU General Public License
29 * along with this program; if not, write to the Free Software
30 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
31 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
32 *
33 *
34 * the project's page is at http://www.linuxtv.org/dvb/
35 */
36
37#include "budget.h"
38#include "stv0299.h"
39#include "ves1x93.h"
40#include "ves1820.h"
41#include "l64781.h"
42#include "tda8083.h"
43
44static void Set22K (struct budget *budget, int state)
45{
46 struct saa7146_dev *dev=budget->dev;
47 dprintk(2, "budget: %p\n", budget);
48 saa7146_setgpio(dev, 3, (state ? SAA7146_GPIO_OUTHI : SAA7146_GPIO_OUTLO));
49}
50
51/* Diseqc functions only for TT Budget card */
52/* taken from the Skyvision DVB driver by
53 Ralph Metzler <rjkm@metzlerbros.de> */
54
55static void DiseqcSendBit (struct budget *budget, int data)
56{
57 struct saa7146_dev *dev=budget->dev;
58 dprintk(2, "budget: %p\n", budget);
59
60 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI);
61 udelay(data ? 500 : 1000);
62 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
63 udelay(data ? 1000 : 500);
64}
65
66static void DiseqcSendByte (struct budget *budget, int data)
67{
68 int i, par=1, d;
69
70 dprintk(2, "budget: %p\n", budget);
71
72 for (i=7; i>=0; i--) {
73 d = (data>>i)&1;
74 par ^= d;
75 DiseqcSendBit(budget, d);
76 }
77
78 DiseqcSendBit(budget, par);
79}
80
81static int SendDiSEqCMsg (struct budget *budget, int len, u8 *msg, unsigned long burst)
82{
83 struct saa7146_dev *dev=budget->dev;
84 int i;
85
86 dprintk(2, "budget: %p\n", budget);
87
88 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
89 mdelay(16);
90
91 for (i=0; i<len; i++)
92 DiseqcSendByte(budget, msg[i]);
93
94 mdelay(16);
95
96 if (burst!=-1) {
97 if (burst)
98 DiseqcSendByte(budget, 0xff);
99 else {
100 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI);
101 udelay(12500);
102 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
103 }
104 msleep(20);
105 }
106
107 return 0;
108}
109
110/*
111 * Routines for the Fujitsu Siemens Activy budget card
112 * 22 kHz tone and DiSEqC are handled by the frontend.
113 * Voltage must be set here.
114 */
115static int SetVoltage_Activy (struct budget *budget, fe_sec_voltage_t voltage)
116{
117 struct saa7146_dev *dev=budget->dev;
118
119 dprintk(2, "budget: %p\n", budget);
120
121 switch (voltage) {
122 case SEC_VOLTAGE_13:
123 saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTLO);
124 break;
125 case SEC_VOLTAGE_18:
126 saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTHI);
127 break;
128 default:
129 return -EINVAL;
130 }
131
132 return 0;
133}
134
135static int siemens_budget_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
136{
137 struct budget* budget = (struct budget*) fe->dvb->priv;
138
139 return SetVoltage_Activy (budget, voltage);
140}
141
142static int budget_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
143{
144 struct budget* budget = (struct budget*) fe->dvb->priv;
145
146 switch (tone) {
147 case SEC_TONE_ON:
148 Set22K (budget, 1);
149 break;
150
151 case SEC_TONE_OFF:
152 Set22K (budget, 0);
153 break;
154
155 default:
156 return -EINVAL;
157 }
158
159 return 0;
160}
161
162static int budget_diseqc_send_master_cmd(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd)
163{
164 struct budget* budget = (struct budget*) fe->dvb->priv;
165
166 SendDiSEqCMsg (budget, cmd->msg_len, cmd->msg, 0);
167
168 return 0;
169}
170
171static int budget_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd)
172{
173 struct budget* budget = (struct budget*) fe->dvb->priv;
174
175 SendDiSEqCMsg (budget, 0, NULL, minicmd);
176
177 return 0;
178}
179
180static int alps_bsrv2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
181{
182 struct budget* budget = (struct budget*) fe->dvb->priv;
183 u8 pwr = 0;
184 u8 buf[4];
185 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
186 u32 div = (params->frequency + 479500) / 125;
187
188 if (params->frequency > 2000000) pwr = 3;
189 else if (params->frequency > 1800000) pwr = 2;
190 else if (params->frequency > 1600000) pwr = 1;
191 else if (params->frequency > 1200000) pwr = 0;
192 else if (params->frequency >= 1100000) pwr = 1;
193 else pwr = 2;
194
195 buf[0] = (div >> 8) & 0x7f;
196 buf[1] = div & 0xff;
197 buf[2] = ((div & 0x18000) >> 10) | 0x95;
198 buf[3] = (pwr << 6) | 0x30;
199
200 // NOTE: since we're using a prescaler of 2, we set the
201 // divisor frequency to 62.5kHz and divide by 125 above
202
203 if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO;
204 return 0;
205}
206
207static struct ves1x93_config alps_bsrv2_config =
208{
209 .demod_address = 0x08,
210 .xin = 90100000UL,
211 .invert_pwm = 0,
212 .pll_set = alps_bsrv2_pll_set,
213};
214
215static u8 alps_bsru6_inittab[] = {
216 0x01, 0x15,
217 0x02, 0x00,
218 0x03, 0x00,
219 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
220 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */
221 0x06, 0x40, /* DAC not used, set to high impendance mode */
222 0x07, 0x00, /* DAC LSB */
223 0x08, 0x40, /* DiSEqC off, LNB power on OP2/LOCK pin on */
224 0x09, 0x00, /* FIFO */
225 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
226 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */
227 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
228 0x10, 0x3f, // AGC2 0x3d
229 0x11, 0x84,
230 0x12, 0xb5, // Lock detect: -64 Carrier freq detect:on
231 0x15, 0xc9, // lock detector threshold
232 0x16, 0x00,
233 0x17, 0x00,
234 0x18, 0x00,
235 0x19, 0x00,
236 0x1a, 0x00,
237 0x1f, 0x50,
238 0x20, 0x00,
239 0x21, 0x00,
240 0x22, 0x00,
241 0x23, 0x00,
242 0x28, 0x00, // out imp: normal out type: parallel FEC mode:0
243 0x29, 0x1e, // 1/2 threshold
244 0x2a, 0x14, // 2/3 threshold
245 0x2b, 0x0f, // 3/4 threshold
246 0x2c, 0x09, // 5/6 threshold
247 0x2d, 0x05, // 7/8 threshold
248 0x2e, 0x01,
249 0x31, 0x1f, // test all FECs
250 0x32, 0x19, // viterbi and synchro search
251 0x33, 0xfc, // rs control
252 0x34, 0x93, // error control
253 0x0f, 0x52,
254 0xff, 0xff
255};
256
257static int alps_bsru6_set_symbol_rate(struct dvb_frontend* fe, u32 srate, u32 ratio)
258{
259 u8 aclk = 0;
260 u8 bclk = 0;
261
262 if (srate < 1500000) { aclk = 0xb7; bclk = 0x47; }
263 else if (srate < 3000000) { aclk = 0xb7; bclk = 0x4b; }
264 else if (srate < 7000000) { aclk = 0xb7; bclk = 0x4f; }
265 else if (srate < 14000000) { aclk = 0xb7; bclk = 0x53; }
266 else if (srate < 30000000) { aclk = 0xb6; bclk = 0x53; }
267 else if (srate < 45000000) { aclk = 0xb4; bclk = 0x51; }
268
269 stv0299_writereg (fe, 0x13, aclk);
270 stv0299_writereg (fe, 0x14, bclk);
271 stv0299_writereg (fe, 0x1f, (ratio >> 16) & 0xff);
272 stv0299_writereg (fe, 0x20, (ratio >> 8) & 0xff);
273 stv0299_writereg (fe, 0x21, (ratio ) & 0xf0);
274
275 return 0;
276}
277
278static int alps_bsru6_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
279{
280 struct budget* budget = (struct budget*) fe->dvb->priv;
281 u8 data[4];
282 u32 div;
283 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
284
285 if ((params->frequency < 950000) || (params->frequency > 2150000)) return -EINVAL;
286
287 div = (params->frequency + (125 - 1)) / 125; // round correctly
288 data[0] = (div >> 8) & 0x7f;
289 data[1] = div & 0xff;
290 data[2] = 0x80 | ((div & 0x18000) >> 10) | 4;
291 data[3] = 0xC4;
292
293 if (params->frequency > 1530000) data[3] = 0xc0;
294
295 if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO;
296 return 0;
297}
298
299static struct stv0299_config alps_bsru6_config = {
300
301 .demod_address = 0x68,
302 .inittab = alps_bsru6_inittab,
303 .mclk = 88000000UL,
304 .invert = 1,
305 .enhanced_tuning = 0,
306 .skip_reinit = 0,
307 .lock_output = STV0229_LOCKOUTPUT_1,
308 .volt13_op0_op1 = STV0299_VOLT13_OP1,
309 .min_delay_ms = 100,
310 .set_symbol_rate = alps_bsru6_set_symbol_rate,
311 .pll_set = alps_bsru6_pll_set,
312};
313
314static int alps_tdbe2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
315{
316 struct budget* budget = (struct budget*) fe->dvb->priv;
317 u32 div;
318 u8 data[4];
319 struct i2c_msg msg = { .addr = 0x62, .flags = 0, .buf = data, .len = sizeof(data) };
320
321 div = (params->frequency + 35937500 + 31250) / 62500;
322
323 data[0] = (div >> 8) & 0x7f;
324 data[1] = div & 0xff;
325 data[2] = 0x85 | ((div >> 10) & 0x60);
326 data[3] = (params->frequency < 174000000 ? 0x88 : params->frequency < 470000000 ? 0x84 : 0x81);
327
328 if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO;
329 return 0;
330}
331
332static struct ves1820_config alps_tdbe2_config = {
333 .demod_address = 0x09,
334 .xin = 57840000UL,
335 .invert = 1,
336 .selagc = VES1820_SELAGC_SIGNAMPERR,
337 .pll_set = alps_tdbe2_pll_set,
338};
339
340static int grundig_29504_401_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
341{
342 struct budget* budget = (struct budget*) fe->dvb->priv;
343 u32 div;
344 u8 cfg, cpump, band_select;
345 u8 data[4];
346 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
347
348 div = (36125000 + params->frequency) / 166666;
349
350 cfg = 0x88;
351
352 if (params->frequency < 175000000) cpump = 2;
353 else if (params->frequency < 390000000) cpump = 1;
354 else if (params->frequency < 470000000) cpump = 2;
355 else if (params->frequency < 750000000) cpump = 1;
356 else cpump = 3;
357
358 if (params->frequency < 175000000) band_select = 0x0e;
359 else if (params->frequency < 470000000) band_select = 0x05;
360 else band_select = 0x03;
361
362 data[0] = (div >> 8) & 0x7f;
363 data[1] = div & 0xff;
364 data[2] = ((div >> 10) & 0x60) | cfg;
365 data[3] = (cpump << 6) | band_select;
366
367 if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO;
368 return 0;
369}
370
371static struct l64781_config grundig_29504_401_config = {
372 .demod_address = 0x55,
373 .pll_set = grundig_29504_401_pll_set,
374};
375
376static int grundig_29504_451_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
377{
378 struct budget* budget = (struct budget*) fe->dvb->priv;
379 u32 div;
380 u8 data[4];
381 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
382
383 div = params->frequency / 125;
384 data[0] = (div >> 8) & 0x7f;
385 data[1] = div & 0xff;
386 data[2] = 0x8e;
387 data[3] = 0x00;
388
389 if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO;
390 return 0;
391}
392
393static struct tda8083_config grundig_29504_451_config = {
394 .demod_address = 0x68,
395 .pll_set = grundig_29504_451_pll_set,
396};
397
398static u8 read_pwm(struct budget* budget)
399{
400 u8 b = 0xff;
401 u8 pwm;
402 struct i2c_msg msg[] = { { .addr = 0x50,.flags = 0,.buf = &b,.len = 1 },
403 { .addr = 0x50,.flags = I2C_M_RD,.buf = &pwm,.len = 1} };
404
405 if ((i2c_transfer(&budget->i2c_adap, msg, 2) != 2) || (pwm == 0xff))
406 pwm = 0x48;
407
408 return pwm;
409}
410
411static void frontend_init(struct budget *budget)
412{
413 switch(budget->dev->pci->subsystem_device) {
414 case 0x1003: // Hauppauge/TT Nova budget (stv0299/ALPS BSRU6(tsa5059) OR ves1893/ALPS BSRV2(sp5659))
415 case 0x1013:
416 // try the ALPS BSRV2 first of all
417 budget->dvb_frontend = ves1x93_attach(&alps_bsrv2_config, &budget->i2c_adap);
418 if (budget->dvb_frontend) {
419 budget->dvb_frontend->ops->diseqc_send_master_cmd = budget_diseqc_send_master_cmd;
420 budget->dvb_frontend->ops->diseqc_send_burst = budget_diseqc_send_burst;
421 budget->dvb_frontend->ops->set_tone = budget_set_tone;
422 break;
423 }
424
425 // try the ALPS BSRU6 now
426 budget->dvb_frontend = stv0299_attach(&alps_bsru6_config, &budget->i2c_adap);
427 if (budget->dvb_frontend) {
428 budget->dvb_frontend->ops->diseqc_send_master_cmd = budget_diseqc_send_master_cmd;
429 budget->dvb_frontend->ops->diseqc_send_burst = budget_diseqc_send_burst;
430 budget->dvb_frontend->ops->set_tone = budget_set_tone;
431 break;
432 }
433 break;
434
435 case 0x1004: // Hauppauge/TT DVB-C budget (ves1820/ALPS TDBE2(sp5659))
436
437 budget->dvb_frontend = ves1820_attach(&alps_tdbe2_config, &budget->i2c_adap, read_pwm(budget));
438 if (budget->dvb_frontend) break;
439 break;
440
441 case 0x1005: // Hauppauge/TT Nova-T budget (L64781/Grundig 29504-401(tsa5060))
442
443 budget->dvb_frontend = l64781_attach(&grundig_29504_401_config, &budget->i2c_adap);
444 if (budget->dvb_frontend) break;
445 break;
446
447 case 0x4f60: // Fujitsu Siemens Activy Budget-S PCI rev AL (stv0299/ALPS BSRU6(tsa5059))
448 budget->dvb_frontend = stv0299_attach(&alps_bsru6_config, &budget->i2c_adap);
449 if (budget->dvb_frontend) {
450 budget->dvb_frontend->ops->set_voltage = siemens_budget_set_voltage;
451 break;
452 }
453 break;
454
455 case 0x4f61: // Fujitsu Siemens Activy Budget-S PCI rev GR (tda8083/Grundig 29504-451(tsa5522))
456 budget->dvb_frontend = tda8083_attach(&grundig_29504_451_config, &budget->i2c_adap);
457 if (budget->dvb_frontend) {
458 budget->dvb_frontend->ops->set_voltage = siemens_budget_set_voltage;
459 break;
460 }
461 break;
462 }
463
464 if (budget->dvb_frontend == NULL) {
465 printk("budget: A frontend driver was not found for device %04x/%04x subsystem %04x/%04x\n",
466 budget->dev->pci->vendor,
467 budget->dev->pci->device,
468 budget->dev->pci->subsystem_vendor,
469 budget->dev->pci->subsystem_device);
470 } else {
471 if (dvb_register_frontend(budget->dvb_adapter, budget->dvb_frontend)) {
472 printk("budget: Frontend registration failed!\n");
473 if (budget->dvb_frontend->ops->release)
474 budget->dvb_frontend->ops->release(budget->dvb_frontend);
475 budget->dvb_frontend = NULL;
476 }
477 }
478}
479
480static int budget_attach (struct saa7146_dev* dev, struct saa7146_pci_extension_data *info)
481{
482 struct budget *budget = NULL;
483 int err;
484
485 budget = kmalloc(sizeof(struct budget), GFP_KERNEL);
486 if( NULL == budget ) {
487 return -ENOMEM;
488 }
489
490 dprintk(2, "dev:%p, info:%p, budget:%p\n", dev, info, budget);
491
492 dev->ext_priv = budget;
493
494 if ((err = ttpci_budget_init (budget, dev, info, THIS_MODULE))) {
495 printk("==> failed\n");
496 kfree (budget);
497 return err;
498 }
499
500 budget->dvb_adapter->priv = budget;
501 frontend_init(budget);
502
503 return 0;
504}
505
506static int budget_detach (struct saa7146_dev* dev)
507{
508 struct budget *budget = (struct budget*) dev->ext_priv;
509 int err;
510
511 if (budget->dvb_frontend) dvb_unregister_frontend(budget->dvb_frontend);
512
513 err = ttpci_budget_deinit (budget);
514
515 kfree (budget);
516 dev->ext_priv = NULL;
517
518 return err;
519}
520
521static struct saa7146_extension budget_extension;
522
523MAKE_BUDGET_INFO(ttbs, "TT-Budget/WinTV-NOVA-S PCI", BUDGET_TT);
524MAKE_BUDGET_INFO(ttbc, "TT-Budget/WinTV-NOVA-C PCI", BUDGET_TT);
525MAKE_BUDGET_INFO(ttbt, "TT-Budget/WinTV-NOVA-T PCI", BUDGET_TT);
526MAKE_BUDGET_INFO(satel, "SATELCO Multimedia PCI", BUDGET_TT_HW_DISEQC);
527MAKE_BUDGET_INFO(fsacs0, "Fujitsu Siemens Activy Budget-S PCI (rev GR/grundig frontend)", BUDGET_FS_ACTIVY);
528MAKE_BUDGET_INFO(fsacs1, "Fujitsu Siemens Activy Budget-S PCI (rev AL/alps frontend)", BUDGET_FS_ACTIVY);
529
530static struct pci_device_id pci_tbl[] = {
531 MAKE_EXTENSION_PCI(ttbs, 0x13c2, 0x1003),
532 MAKE_EXTENSION_PCI(ttbc, 0x13c2, 0x1004),
533 MAKE_EXTENSION_PCI(ttbt, 0x13c2, 0x1005),
534 MAKE_EXTENSION_PCI(satel, 0x13c2, 0x1013),
535 MAKE_EXTENSION_PCI(fsacs1,0x1131, 0x4f60),
536 MAKE_EXTENSION_PCI(fsacs0,0x1131, 0x4f61),
537 {
538 .vendor = 0,
539 }
540};
541
542MODULE_DEVICE_TABLE(pci, pci_tbl);
543
544static struct saa7146_extension budget_extension = {
545 .name = "budget dvb\0",
546 .flags = 0,
547
548 .module = THIS_MODULE,
549 .pci_tbl = pci_tbl,
550 .attach = budget_attach,
551 .detach = budget_detach,
552
553 .irq_mask = MASK_10,
554 .irq_func = ttpci_budget_irq10_handler,
555};
556
557static int __init budget_init(void)
558{
559 return saa7146_register_extension(&budget_extension);
560}
561
562static void __exit budget_exit(void)
563{
564 saa7146_unregister_extension(&budget_extension);
565}
566
567module_init(budget_init);
568module_exit(budget_exit);
569
570MODULE_LICENSE("GPL");
571MODULE_AUTHOR("Ralph Metzler, Marcus Metzler, Michael Hunold, others");
572MODULE_DESCRIPTION("driver for the SAA7146 based so-called "
573 "budget PCI DVB cards by Siemens, Technotrend, Hauppauge");
diff --git a/drivers/media/dvb/ttpci/budget.h b/drivers/media/dvb/ttpci/budget.h
new file mode 100644
index 000000000000..10bd41f0363b
--- /dev/null
+++ b/drivers/media/dvb/ttpci/budget.h
@@ -0,0 +1,110 @@
1#ifndef __BUDGET_DVB__
2#define __BUDGET_DVB__
3
4#include "dvb_frontend.h"
5#include "dvbdev.h"
6#include "demux.h"
7#include "dvb_demux.h"
8#include "dmxdev.h"
9#include "dvb_filter.h"
10#include "dvb_net.h"
11
12#include <linux/module.h>
13#include <media/saa7146.h>
14
15extern int budget_debug;
16
17#ifdef dprintk
18#undef dprintk
19#endif
20
21#define dprintk(level,args...) \
22 do { if ((budget_debug & level)) { printk("%s: %s(): ",__stringify(KBUILD_MODNAME), __FUNCTION__); printk(args); } } while (0)
23
24struct budget_info {
25 char *name;
26 int type;
27};
28
29/* place to store all the necessary device information */
30struct budget {
31
32 /* devices */
33 struct dvb_device dvb_dev;
34 struct dvb_net dvb_net;
35
36 struct saa7146_dev *dev;
37
38 struct i2c_adapter i2c_adap;
39 struct budget_info *card;
40
41 unsigned char *grabbing;
42 struct saa7146_pgtable pt;
43
44 struct tasklet_struct fidb_tasklet;
45 struct tasklet_struct vpe_tasklet;
46
47 struct dmxdev dmxdev;
48 struct dvb_demux demux;
49
50 struct dmx_frontend hw_frontend;
51 struct dmx_frontend mem_frontend;
52
53 int fe_synced;
54 struct semaphore pid_mutex;
55
56 int ci_present;
57 int video_port;
58
59 u8 tsf;
60 u32 ttbp;
61 int feeding;
62
63 spinlock_t feedlock;
64
65 spinlock_t debilock;
66
67 struct dvb_adapter *dvb_adapter;
68 struct dvb_frontend *dvb_frontend;
69 void *priv;
70};
71
72#define MAKE_BUDGET_INFO(x_var,x_name,x_type) \
73static struct budget_info x_var ## _info = { \
74 .name=x_name, \
75 .type=x_type }; \
76static struct saa7146_pci_extension_data x_var = { \
77 .ext_priv = &x_var ## _info, \
78 .ext = &budget_extension };
79
80#define TS_WIDTH (376)
81#define TS_HEIGHT (512)
82#define TS_BUFLEN (TS_WIDTH*TS_HEIGHT)
83#define TS_MAX_PACKETS (TS_BUFLEN/TS_SIZE)
84
85#define BUDGET_TT 0
86#define BUDGET_TT_HW_DISEQC 1
87#define BUDGET_PATCH 3
88#define BUDGET_FS_ACTIVY 4
89#define BUDGET_CIN1200S 5
90#define BUDGET_CIN1200C 6
91#define BUDGET_CIN1200T 7
92#define BUDGET_KNC1S 8
93#define BUDGET_KNC1C 9
94#define BUDGET_KNC1T 10
95
96#define BUDGET_VIDEO_PORTA 0
97#define BUDGET_VIDEO_PORTB 1
98
99extern int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev,
100 struct saa7146_pci_extension_data *info,
101 struct module *owner);
102extern int ttpci_budget_deinit(struct budget *budget);
103extern void ttpci_budget_irq10_handler(struct saa7146_dev *dev, u32 * isr);
104extern void ttpci_budget_set_video_port(struct saa7146_dev *dev, int video_port);
105extern int ttpci_budget_debiread(struct budget *budget, u32 config, int addr, int count,
106 int uselocks, int nobusyloop);
107extern int ttpci_budget_debiwrite(struct budget *budget, u32 config, int addr, int count, u32 value,
108 int uselocks, int nobusyloop);
109
110#endif
diff --git a/drivers/media/dvb/ttpci/fdump.c b/drivers/media/dvb/ttpci/fdump.c
new file mode 100644
index 000000000000..0b478db3e744
--- /dev/null
+++ b/drivers/media/dvb/ttpci/fdump.c
@@ -0,0 +1,44 @@
1#include <stdio.h>
2#include <sys/types.h>
3#include <sys/stat.h>
4#include <fcntl.h>
5#include <unistd.h>
6
7int main(int argc, char **argv)
8{
9 unsigned char buf[8];
10 unsigned int i, count, bytes = 0;
11 FILE *fd_in, *fd_out;
12
13 if (argc != 4) {
14 fprintf(stderr, "\n\tusage: %s <ucode.bin> <array_name> <output_name>\n\n", argv[0]);
15 return -1;
16 }
17
18 fd_in = fopen(argv[1], "rb");
19 if (fd_in == NULL) {
20 fprintf(stderr, "firmware file '%s' not found\n", argv[1]);
21 return -1;
22 }
23
24 fd_out = fopen(argv[3], "w+");
25 if (fd_out == NULL) {
26 fprintf(stderr, "cannot create output file '%s'\n", argv[3]);
27 return -1;
28 }
29
30 fprintf(fd_out, "\n#include <asm/types.h>\n\nu8 %s [] = {", argv[2]);
31
32 while ((count = fread(buf, 1, 8, fd_in)) > 0) {
33 fprintf(fd_out, "\n\t");
34 for (i = 0; i < count; i++, bytes++)
35 fprintf(fd_out, "0x%02x, ", buf[i]);
36 }
37
38 fprintf(fd_out, "\n};\n\n");
39
40 fclose(fd_in);
41 fclose(fd_out);
42
43 return 0;
44}
diff --git a/drivers/media/dvb/ttpci/ttpci-eeprom.c b/drivers/media/dvb/ttpci/ttpci-eeprom.c
new file mode 100644
index 000000000000..e9a8457b0727
--- /dev/null
+++ b/drivers/media/dvb/ttpci/ttpci-eeprom.c
@@ -0,0 +1,146 @@
1/*
2 Retrieve encoded MAC address from 24C16 serial 2-wire EEPROM,
3 decode it and store it in the associated adapter struct for
4 use by dvb_net.c
5
6 This card appear to have the 24C16 write protect held to ground,
7 thus permitting normal read/write operation. Theoretically it
8 would be possible to write routines to burn a different (encoded)
9 MAC address into the EEPROM.
10
11 Robert Schlabbach GMX
12 Michael Glaum KVH Industries
13 Holger Waechtler Convergence
14
15 Copyright (C) 2002-2003 Ralph Metzler <rjkm@metzlerbros.de>
16 Metzler Brothers Systementwicklung GbR
17
18 This program is free software; you can redistribute it and/or modify
19 it under the terms of the GNU General Public License as published by
20 the Free Software Foundation; either version 2 of the License, or
21 (at your option) any later version.
22
23 This program is distributed in the hope that it will be useful,
24 but WITHOUT ANY WARRANTY; without even the implied warranty of
25 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 GNU General Public License for more details.
27
28 You should have received a copy of the GNU General Public License
29 along with this program; if not, write to the Free Software
30 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
31
32*/
33
34#include <asm/errno.h>
35#include <linux/init.h>
36#include <linux/module.h>
37#include <linux/string.h>
38#include <linux/i2c.h>
39
40
41#if 1
42#define dprintk(x...) do { printk(x); } while (0)
43#else
44#define dprintk(x...) do { } while (0)
45#endif
46
47
48static int check_mac_tt(u8 *buf)
49{
50 int i;
51 u16 tmp = 0xffff;
52
53 for (i = 0; i < 8; i++) {
54 tmp = (tmp << 8) | ((tmp >> 8) ^ buf[i]);
55 tmp ^= (tmp >> 4) & 0x0f;
56 tmp ^= (tmp << 12) ^ ((tmp & 0xff) << 5);
57 }
58 tmp ^= 0xffff;
59 return (((tmp >> 8) ^ buf[8]) | ((tmp & 0xff) ^ buf[9]));
60}
61
62static int getmac_tt(u8 * decodedMAC, u8 * encodedMAC)
63{
64 u8 xor[20] = { 0x72, 0x23, 0x68, 0x19, 0x5c, 0xa8, 0x71, 0x2c,
65 0x54, 0xd3, 0x7b, 0xf1, 0x9E, 0x23, 0x16, 0xf6,
66 0x1d, 0x36, 0x64, 0x78};
67 u8 data[20];
68 int i;
69
70 /* In case there is a sig check failure have the orig contents available */
71 memcpy(data, encodedMAC, 20);
72
73 for (i = 0; i < 20; i++)
74 data[i] ^= xor[i];
75 for (i = 0; i < 10; i++)
76 data[i] = ((data[2 * i + 1] << 8) | data[2 * i])
77 >> ((data[2 * i + 1] >> 6) & 3);
78
79 if (check_mac_tt(data))
80 return -ENODEV;
81
82 decodedMAC[0] = data[2]; decodedMAC[1] = data[1]; decodedMAC[2] = data[0];
83 decodedMAC[3] = data[6]; decodedMAC[4] = data[5]; decodedMAC[5] = data[4];
84 return 0;
85}
86
87static int ttpci_eeprom_read_encodedMAC(struct i2c_adapter *adapter, u8 * encodedMAC)
88{
89 int ret;
90 u8 b0[] = { 0xcc };
91
92 struct i2c_msg msg[] = {
93 { .addr = 0x50, .flags = 0, .buf = b0, .len = 1 },
94 { .addr = 0x50, .flags = I2C_M_RD, .buf = encodedMAC, .len = 20 }
95 };
96
97 /* dprintk("%s\n", __FUNCTION__); */
98
99 ret = i2c_transfer(adapter, msg, 2);
100
101 if (ret != 2) /* Assume EEPROM isn't there */
102 return (-ENODEV);
103
104 return 0;
105}
106
107
108int ttpci_eeprom_parse_mac(struct i2c_adapter *adapter, u8 *proposed_mac)
109{
110 int ret, i;
111 u8 encodedMAC[20];
112 u8 decodedMAC[6];
113
114 ret = ttpci_eeprom_read_encodedMAC(adapter, encodedMAC);
115
116 if (ret != 0) { /* Will only be -ENODEV */
117 dprintk("Couldn't read from EEPROM: not there?\n");
118 memset(proposed_mac, 0, 6);
119 return ret;
120 }
121
122 ret = getmac_tt(decodedMAC, encodedMAC);
123 if( ret != 0 ) {
124 dprintk("adapter failed MAC signature check\n");
125 dprintk("encoded MAC from EEPROM was " );
126 for(i=0; i<19; i++) {
127 dprintk( "%.2x:", encodedMAC[i]);
128 }
129 dprintk("%.2x\n", encodedMAC[19]);
130 memset(proposed_mac, 0, 6);
131 return ret;
132 }
133
134 memcpy(proposed_mac, decodedMAC, 6);
135 dprintk("adapter has MAC addr = %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",
136 decodedMAC[0], decodedMAC[1], decodedMAC[2],
137 decodedMAC[3], decodedMAC[4], decodedMAC[5]);
138 return 0;
139}
140
141EXPORT_SYMBOL(ttpci_eeprom_parse_mac);
142
143MODULE_LICENSE("GPL");
144MODULE_AUTHOR("Ralph Metzler, Marcus Metzler, others");
145MODULE_DESCRIPTION("Decode dvb_net MAC address from EEPROM of PCI DVB cards "
146 "made by Siemens, Technotrend, Hauppauge");
diff --git a/drivers/media/dvb/ttpci/ttpci-eeprom.h b/drivers/media/dvb/ttpci/ttpci-eeprom.h
new file mode 100644
index 000000000000..e2dc6cfe205c
--- /dev/null
+++ b/drivers/media/dvb/ttpci/ttpci-eeprom.h
@@ -0,0 +1,33 @@
1/*
2 Retrieve encoded MAC address from ATMEL ttpci_eeprom serial 2-wire EEPROM,
3 decode it and store it in associated adapter net device
4
5 Robert Schlabbach GMX
6 Michael Glaum KVH Industries
7 Holger Waechtler Convergence
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22
23*/
24
25#ifndef __TTPCI_EEPROM_H__
26#define __TTPCI_EEPROM_H__
27
28#include <linux/types.h>
29#include <linux/i2c.h>
30
31extern int ttpci_eeprom_parse_mac(struct i2c_adapter *adapter, u8 *propsed_mac);
32
33#endif