aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /drivers/media/dvb
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
Diffstat (limited to 'drivers/media/dvb')
-rw-r--r--drivers/media/dvb/Kconfig47
-rw-r--r--drivers/media/dvb/Makefile5
-rw-r--r--drivers/media/dvb/b2c2/Kconfig26
-rw-r--r--drivers/media/dvb/b2c2/Makefile6
-rw-r--r--drivers/media/dvb/b2c2/b2c2-common.c214
-rw-r--r--drivers/media/dvb/b2c2/b2c2-usb-core.c549
-rw-r--r--drivers/media/dvb/b2c2/skystar2.c2644
-rw-r--r--drivers/media/dvb/bt8xx/Kconfig19
-rw-r--r--drivers/media/dvb/bt8xx/Makefile5
-rw-r--r--drivers/media/dvb/bt8xx/bt878.c588
-rw-r--r--drivers/media/dvb/bt8xx/bt878.h147
-rw-r--r--drivers/media/dvb/bt8xx/dst.c1089
-rw-r--r--drivers/media/dvb/bt8xx/dst.h40
-rw-r--r--drivers/media/dvb/bt8xx/dst_priv.h36
-rw-r--r--drivers/media/dvb/bt8xx/dvb-bt8xx.c797
-rw-r--r--drivers/media/dvb/bt8xx/dvb-bt8xx.h59
-rw-r--r--drivers/media/dvb/cinergyT2/Kconfig85
-rw-r--r--drivers/media/dvb/cinergyT2/Makefile3
-rw-r--r--drivers/media/dvb/cinergyT2/cinergyT2.c965
-rw-r--r--drivers/media/dvb/dibusb/Kconfig62
-rw-r--r--drivers/media/dvb/dibusb/Makefile11
-rw-r--r--drivers/media/dvb/dibusb/dvb-dibusb-core.c558
-rw-r--r--drivers/media/dvb/dibusb/dvb-dibusb-dvb.c185
-rw-r--r--drivers/media/dvb/dibusb/dvb-dibusb-fe-i2c.c582
-rw-r--r--drivers/media/dvb/dibusb/dvb-dibusb-firmware.c87
-rw-r--r--drivers/media/dvb/dibusb/dvb-dibusb-remote.c316
-rw-r--r--drivers/media/dvb/dibusb/dvb-dibusb-usb.c303
-rw-r--r--drivers/media/dvb/dibusb/dvb-dibusb.h327
-rw-r--r--drivers/media/dvb/dibusb/dvb-fe-dtt200u.c263
-rw-r--r--drivers/media/dvb/dvb-core/Kconfig11
-rw-r--r--drivers/media/dvb/dvb-core/Makefile9
-rw-r--r--drivers/media/dvb/dvb-core/demux.h301
-rw-r--r--drivers/media/dvb/dvb-core/dmxdev.c1137
-rw-r--r--drivers/media/dvb/dvb-core/dmxdev.h128
-rw-r--r--drivers/media/dvb/dvb-core/dvb_ca_en50221.c1778
-rw-r--r--drivers/media/dvb/dvb-core/dvb_ca_en50221.h134
-rw-r--r--drivers/media/dvb/dvb-core/dvb_demux.c1294
-rw-r--r--drivers/media/dvb/dvb-core/dvb_demux.h146
-rw-r--r--drivers/media/dvb/dvb-core/dvb_filter.c603
-rw-r--r--drivers/media/dvb/dvb-core/dvb_filter.h246
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.c915
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.h126
-rw-r--r--drivers/media/dvb/dvb-core/dvb_net.c1381
-rw-r--r--drivers/media/dvb/dvb-core/dvb_net.h46
-rw-r--r--drivers/media/dvb/dvb-core/dvb_ringbuffer.c270
-rw-r--r--drivers/media/dvb/dvb-core/dvb_ringbuffer.h173
-rw-r--r--drivers/media/dvb/dvb-core/dvbdev.c449
-rw-r--r--drivers/media/dvb/dvb-core/dvbdev.h104
-rw-r--r--drivers/media/dvb/frontends/Kconfig172
-rw-r--r--drivers/media/dvb/frontends/Makefile30
-rw-r--r--drivers/media/dvb/frontends/at76c651.c450
-rw-r--r--drivers/media/dvb/frontends/at76c651.h47
-rw-r--r--drivers/media/dvb/frontends/cx22700.c435
-rw-r--r--drivers/media/dvb/frontends/cx22700.h41
-rw-r--r--drivers/media/dvb/frontends/cx22702.c519
-rw-r--r--drivers/media/dvb/frontends/cx22702.h46
-rw-r--r--drivers/media/dvb/frontends/cx24110.c657
-rw-r--r--drivers/media/dvb/frontends/cx24110.h45
-rw-r--r--drivers/media/dvb/frontends/dib3000-common.c83
-rw-r--r--drivers/media/dvb/frontends/dib3000-common.h137
-rw-r--r--drivers/media/dvb/frontends/dib3000.h54
-rw-r--r--drivers/media/dvb/frontends/dib3000mb.c784
-rw-r--r--drivers/media/dvb/frontends/dib3000mb_priv.h467
-rw-r--r--drivers/media/dvb/frontends/dib3000mc.c931
-rw-r--r--drivers/media/dvb/frontends/dib3000mc_priv.h428
-rw-r--r--drivers/media/dvb/frontends/dvb-pll.c168
-rw-r--r--drivers/media/dvb/frontends/dvb-pll.h34
-rw-r--r--drivers/media/dvb/frontends/dvb_dummy_fe.c279
-rw-r--r--drivers/media/dvb/frontends/dvb_dummy_fe.h32
-rw-r--r--drivers/media/dvb/frontends/l64781.c602
-rw-r--r--drivers/media/dvb/frontends/l64781.h42
-rw-r--r--drivers/media/dvb/frontends/mt312.c729
-rw-r--r--drivers/media/dvb/frontends/mt312.h47
-rw-r--r--drivers/media/dvb/frontends/mt312_priv.h162
-rw-r--r--drivers/media/dvb/frontends/mt352.c610
-rw-r--r--drivers/media/dvb/frontends/mt352.h72
-rw-r--r--drivers/media/dvb/frontends/mt352_priv.h127
-rw-r--r--drivers/media/dvb/frontends/nxt2002.c705
-rw-r--r--drivers/media/dvb/frontends/nxt2002.h23
-rw-r--r--drivers/media/dvb/frontends/nxt6000.c554
-rw-r--r--drivers/media/dvb/frontends/nxt6000.h43
-rw-r--r--drivers/media/dvb/frontends/nxt6000_priv.h265
-rw-r--r--drivers/media/dvb/frontends/or51132.c628
-rw-r--r--drivers/media/dvb/frontends/or51132.h48
-rw-r--r--drivers/media/dvb/frontends/or51211.c631
-rw-r--r--drivers/media/dvb/frontends/or51211.h44
-rw-r--r--drivers/media/dvb/frontends/sp8870.c614
-rw-r--r--drivers/media/dvb/frontends/sp8870.h45
-rw-r--r--drivers/media/dvb/frontends/sp887x.c606
-rw-r--r--drivers/media/dvb/frontends/sp887x.h29
-rw-r--r--drivers/media/dvb/frontends/stv0297.c798
-rw-r--r--drivers/media/dvb/frontends/stv0297.h44
-rw-r--r--drivers/media/dvb/frontends/stv0299.c731
-rw-r--r--drivers/media/dvb/frontends/stv0299.h104
-rw-r--r--drivers/media/dvb/frontends/tda10021.c469
-rw-r--r--drivers/media/dvb/frontends/tda10021.h42
-rw-r--r--drivers/media/dvb/frontends/tda1004x.c1206
-rw-r--r--drivers/media/dvb/frontends/tda1004x.h56
-rw-r--r--drivers/media/dvb/frontends/tda8083.c456
-rw-r--r--drivers/media/dvb/frontends/tda8083.h45
-rw-r--r--drivers/media/dvb/frontends/tda80xx.c734
-rw-r--r--drivers/media/dvb/frontends/tda80xx.h51
-rw-r--r--drivers/media/dvb/frontends/ves1820.c450
-rw-r--r--drivers/media/dvb/frontends/ves1820.h51
-rw-r--r--drivers/media/dvb/frontends/ves1x93.c545
-rw-r--r--drivers/media/dvb/frontends/ves1x93.h50
-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
-rw-r--r--drivers/media/dvb/ttusb-budget/Kconfig15
-rw-r--r--drivers/media/dvb/ttusb-budget/Makefile3
-rw-r--r--drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c1610
-rw-r--r--drivers/media/dvb/ttusb-budget/dvb-ttusb-dspbootcode.h1644
-rw-r--r--drivers/media/dvb/ttusb-dec/Kconfig21
-rw-r--r--drivers/media/dvb/ttusb-dec/Makefile3
-rw-r--r--drivers/media/dvb/ttusb-dec/ttusb_dec.c1744
-rw-r--r--drivers/media/dvb/ttusb-dec/ttusbdecfe.c255
-rw-r--r--drivers/media/dvb/ttusb-dec/ttusbdecfe.h38
138 files changed, 55188 insertions, 0 deletions
diff --git a/drivers/media/dvb/Kconfig b/drivers/media/dvb/Kconfig
new file mode 100644
index 000000000000..883ec08490f4
--- /dev/null
+++ b/drivers/media/dvb/Kconfig
@@ -0,0 +1,47 @@
1#
2# Multimedia device configuration
3#
4
5menu "Digital Video Broadcasting Devices"
6
7config DVB
8 bool "DVB For Linux"
9 depends on NET && INET
10 ---help---
11 Support Digital Video Broadcasting hardware. Enable this if you
12 own a DVB adapter and want to use it or if you compile Linux for
13 a digital SetTopBox.
14
15 API specs and user tools are available from <http://www.linuxtv.org/>.
16
17 Please report problems regarding this driver to the LinuxDVB
18 mailing list.
19
20 If unsure say N.
21
22source "drivers/media/dvb/dvb-core/Kconfig"
23
24comment "Supported SAA7146 based PCI Adapters"
25 depends on DVB_CORE && PCI
26source "drivers/media/dvb/ttpci/Kconfig"
27
28comment "Supported USB Adapters"
29 depends on DVB_CORE && USB
30source "drivers/media/dvb/ttusb-budget/Kconfig"
31source "drivers/media/dvb/ttusb-dec/Kconfig"
32source "drivers/media/dvb/dibusb/Kconfig"
33source "drivers/media/dvb/cinergyT2/Kconfig"
34
35comment "Supported FlexCopII (B2C2) Adapters"
36 depends on DVB_CORE && PCI
37source "drivers/media/dvb/b2c2/Kconfig"
38
39comment "Supported BT878 Adapters"
40 depends on DVB_CORE && PCI
41source "drivers/media/dvb/bt8xx/Kconfig"
42
43comment "Supported DVB Frontends"
44 depends on DVB_CORE
45source "drivers/media/dvb/frontends/Kconfig"
46
47endmenu
diff --git a/drivers/media/dvb/Makefile b/drivers/media/dvb/Makefile
new file mode 100644
index 000000000000..520fc3902819
--- /dev/null
+++ b/drivers/media/dvb/Makefile
@@ -0,0 +1,5 @@
1#
2# Makefile for the kernel multimedia device drivers.
3#
4
5obj-y := dvb-core/ frontends/ ttpci/ ttusb-dec/ ttusb-budget/ b2c2/ bt8xx/ dibusb/ cinergyT2/
diff --git a/drivers/media/dvb/b2c2/Kconfig b/drivers/media/dvb/b2c2/Kconfig
new file mode 100644
index 000000000000..52596907a0be
--- /dev/null
+++ b/drivers/media/dvb/b2c2/Kconfig
@@ -0,0 +1,26 @@
1config DVB_B2C2_SKYSTAR
2 tristate "B2C2/Technisat Air/Sky/CableStar 2 PCI"
3 depends on DVB_CORE && PCI
4 select DVB_STV0299
5 select DVB_MT352
6 select DVB_MT312
7 select DVB_NXT2002
8 help
9 Support for the Skystar2 PCI DVB card by Technisat, which
10 is equipped with the FlexCopII chipset by B2C2, and
11 for the B2C2/BBTI Air2PC-ATSC card.
12
13 Say Y if you own such a device and want to use it.
14
15config DVB_B2C2_USB
16 tristate "B2C2/Technisat Air/Sky/Cable2PC USB"
17 depends on DVB_CORE && USB && EXPERIMENTAL
18 select DVB_STV0299
19 select DVB_MT352
20 help
21 Support for the Air/Sky/Cable2PC USB DVB device by B2C2. Currently
22 the does nothing, but providing basic function for the used usb
23 protocol.
24
25 Say Y if you own such a device and want to use it.
26
diff --git a/drivers/media/dvb/b2c2/Makefile b/drivers/media/dvb/b2c2/Makefile
new file mode 100644
index 000000000000..9fb1247bfab8
--- /dev/null
+++ b/drivers/media/dvb/b2c2/Makefile
@@ -0,0 +1,6 @@
1obj-b2c2-usb = b2c2-usb-core.o b2c2-common.o
2
3obj-$(CONFIG_DVB_B2C2_SKYSTAR) += skystar2.o
4obj-$(CONFIG_DVB_B2C2_USB) + = b2c2-usb.o
5
6EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
diff --git a/drivers/media/dvb/b2c2/b2c2-common.c b/drivers/media/dvb/b2c2/b2c2-common.c
new file mode 100644
index 000000000000..000d60c405e3
--- /dev/null
+++ b/drivers/media/dvb/b2c2/b2c2-common.c
@@ -0,0 +1,214 @@
1/*
2 * b2c2-common.c - common methods for the B2C2/Technisat SkyStar2 PCI DVB card and
3 * for the B2C2/Technisat Sky/Cable/AirStar USB devices
4 * based on the FlexCopII/FlexCopIII by B2C2, Inc.
5 *
6 * Copyright (C) 2003 Vadim Catana, skystar@moldova.cc
7 *
8 * FIX: DISEQC Tone Burst in flexcop_diseqc_ioctl()
9 * FIX: FULL soft DiSEqC for skystar2 (FlexCopII rev 130) VP310 equipped
10 * Vincenzo Di Massa, hawk.it at tiscalinet.it
11 *
12 * Converted to Linux coding style
13 * Misc reorganization, polishing, restyling
14 * Roberto Ragusa, r.ragusa at libero.it
15 *
16 * Added hardware filtering support,
17 * Niklas Peinecke, peinecke at gdv.uni-hannover.de
18 *
19 * This program is free software; you can redistribute it and/or
20 * modify it under the terms of the GNU Lesser General Public License
21 * as published by the Free Software Foundation; either version 2.1
22 * of the License, or (at your option) any later version.
23 *
24 * This program is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
28 *
29 * You should have received a copy of the GNU Lesser General Public License
30 * along with this program; if not, write to the Free Software
31 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
32 *
33 */
34#include "stv0299.h"
35#include "mt352.h"
36#include "mt312.h"
37
38static int samsung_tbmu24112_set_symbol_rate(struct dvb_frontend* fe, u32 srate, u32 ratio)
39{
40 u8 aclk = 0;
41 u8 bclk = 0;
42
43 if (srate < 1500000) { aclk = 0xb7; bclk = 0x47; }
44 else if (srate < 3000000) { aclk = 0xb7; bclk = 0x4b; }
45 else if (srate < 7000000) { aclk = 0xb7; bclk = 0x4f; }
46 else if (srate < 14000000) { aclk = 0xb7; bclk = 0x53; }
47 else if (srate < 30000000) { aclk = 0xb6; bclk = 0x53; }
48 else if (srate < 45000000) { aclk = 0xb4; bclk = 0x51; }
49
50 stv0299_writereg (fe, 0x13, aclk);
51 stv0299_writereg (fe, 0x14, bclk);
52 stv0299_writereg (fe, 0x1f, (ratio >> 16) & 0xff);
53 stv0299_writereg (fe, 0x20, (ratio >> 8) & 0xff);
54 stv0299_writereg (fe, 0x21, (ratio ) & 0xf0);
55
56 return 0;
57}
58
59static int samsung_tbmu24112_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
60{
61 u8 buf[4];
62 u32 div;
63 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
64// struct adapter* adapter = (struct adapter*) fe->dvb->priv;
65
66 div = params->frequency / 125;
67
68 buf[0] = (div >> 8) & 0x7f;
69 buf[1] = div & 0xff;
70 buf[2] = 0x84; // 0xC4
71 buf[3] = 0x08;
72
73 if (params->frequency < 1500000) buf[3] |= 0x10;
74
75// if (i2c_transfer (&adapter->i2c_adap, &msg, 1) != 1) return -EIO;
76 return 0;
77}
78
79static u8 samsung_tbmu24112_inittab[] = {
80 0x01, 0x15,
81 0x02, 0x30,
82 0x03, 0x00,
83 0x04, 0x7D,
84 0x05, 0x35,
85 0x06, 0x02,
86 0x07, 0x00,
87 0x08, 0xC3,
88 0x0C, 0x00,
89 0x0D, 0x81,
90 0x0E, 0x23,
91 0x0F, 0x12,
92 0x10, 0x7E,
93 0x11, 0x84,
94 0x12, 0xB9,
95 0x13, 0x88,
96 0x14, 0x89,
97 0x15, 0xC9,
98 0x16, 0x00,
99 0x17, 0x5C,
100 0x18, 0x00,
101 0x19, 0x00,
102 0x1A, 0x00,
103 0x1C, 0x00,
104 0x1D, 0x00,
105 0x1E, 0x00,
106 0x1F, 0x3A,
107 0x20, 0x2E,
108 0x21, 0x80,
109 0x22, 0xFF,
110 0x23, 0xC1,
111 0x28, 0x00,
112 0x29, 0x1E,
113 0x2A, 0x14,
114 0x2B, 0x0F,
115 0x2C, 0x09,
116 0x2D, 0x05,
117 0x31, 0x1F,
118 0x32, 0x19,
119 0x33, 0xFE,
120 0x34, 0x93,
121 0xff, 0xff,
122};
123
124static struct stv0299_config samsung_tbmu24112_config = {
125 .demod_address = 0x68,
126 .inittab = samsung_tbmu24112_inittab,
127 .mclk = 88000000UL,
128 .invert = 0,
129 .enhanced_tuning = 0,
130 .skip_reinit = 0,
131 .lock_output = STV0229_LOCKOUTPUT_LK,
132 .volt13_op0_op1 = STV0299_VOLT13_OP1,
133 .min_delay_ms = 100,
134 .set_symbol_rate = samsung_tbmu24112_set_symbol_rate,
135 .pll_set = samsung_tbmu24112_pll_set,
136};
137
138
139
140
141
142static int samsung_tdtc9251dh0_demod_init(struct dvb_frontend* fe)
143{
144 static u8 mt352_clock_config [] = { 0x89, 0x10, 0x2d };
145 static u8 mt352_reset [] = { 0x50, 0x80 };
146 static u8 mt352_adc_ctl_1_cfg [] = { 0x8E, 0x40 };
147 static u8 mt352_agc_cfg [] = { 0x67, 0x28, 0xa1 };
148 static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 };
149
150 mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config));
151 udelay(2000);
152 mt352_write(fe, mt352_reset, sizeof(mt352_reset));
153 mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg));
154
155 mt352_write(fe, mt352_agc_cfg, sizeof(mt352_agc_cfg));
156 mt352_write(fe, mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg));
157
158 return 0;
159}
160
161static int samsung_tdtc9251dh0_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u8* pllbuf)
162{
163 u32 div;
164 unsigned char bs = 0;
165
166 #define IF_FREQUENCYx6 217 /* 6 * 36.16666666667MHz */
167 div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6;
168
169 if (params->frequency >= 48000000 && params->frequency <= 154000000) bs = 0x09;
170 if (params->frequency >= 161000000 && params->frequency <= 439000000) bs = 0x0a;
171 if (params->frequency >= 447000000 && params->frequency <= 863000000) bs = 0x08;
172
173 pllbuf[0] = 0xc2; // Note: non-linux standard PLL i2c address
174 pllbuf[1] = div >> 8;
175 pllbuf[2] = div & 0xff;
176 pllbuf[3] = 0xcc;
177 pllbuf[4] = bs;
178
179 return 0;
180}
181
182static struct mt352_config samsung_tdtc9251dh0_config = {
183
184 .demod_address = 0x0f,
185 .demod_init = samsung_tdtc9251dh0_demod_init,
186 .pll_set = samsung_tdtc9251dh0_pll_set,
187};
188
189static int skystar23_samsung_tbdu18132_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
190{
191 u8 buf[4];
192 u32 div;
193 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
194// struct adapter* adapter = (struct adapter*) fe->dvb->priv;
195
196 div = (params->frequency + (125/2)) / 125;
197
198 buf[0] = (div >> 8) & 0x7f;
199 buf[1] = (div >> 0) & 0xff;
200 buf[2] = 0x84 | ((div >> 10) & 0x60);
201 buf[3] = 0x80;
202
203 if (params->frequency < 1550000)
204 buf[3] |= 0x02;
205
206 //if (i2c_transfer (&adapter->i2c_adap, &msg, 1) != 1) return -EIO;
207 return 0;
208}
209
210static struct mt312_config skystar23_samsung_tbdu18132_config = {
211
212 .demod_address = 0x0e,
213 .pll_set = skystar23_samsung_tbdu18132_pll_set,
214};
diff --git a/drivers/media/dvb/b2c2/b2c2-usb-core.c b/drivers/media/dvb/b2c2/b2c2-usb-core.c
new file mode 100644
index 000000000000..9306da046c91
--- /dev/null
+++ b/drivers/media/dvb/b2c2/b2c2-usb-core.c
@@ -0,0 +1,549 @@
1/*
2 * Copyright (C) 2004 Patrick Boettcher <patrick.boettcher@desy.de>,
3 * Luca Bertagnolio <>,
4 *
5 * based on information provided by John Jurrius from BBTI, Inc.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation, version 2.
10 *
11 */
12
13#include <linux/config.h>
14#include <linux/kernel.h>
15#include <linux/usb.h>
16#include <linux/moduleparam.h>
17#include <linux/pci.h>
18#include <linux/version.h>
19
20#include "dmxdev.h"
21#include "dvb_demux.h"
22#include "dvb_filter.h"
23#include "dvb_net.h"
24#include "dvb_frontend.h"
25
26/* debug */
27#define dprintk(level,args...) \
28 do { if ((debug & level)) { printk(args); } } while (0)
29#define debug_dump(b,l) if (debug) {\
30 int i; deb_xfer("%s: %d > ",__FUNCTION__,l); \
31 for (i = 0; i < l; i++) deb_xfer("%02x ", b[i]); \
32 deb_xfer("\n");\
33}
34
35static int debug;
36module_param(debug, int, 0644);
37MODULE_PARM_DESC(debug, "set debugging level (1=info,ts=2,ctrl=4 (or-able)).");
38
39#define deb_info(args...) dprintk(0x01,args)
40#define deb_ts(args...) dprintk(0x02,args)
41#define deb_ctrl(args...) dprintk(0x04,args)
42
43/* Version information */
44#define DRIVER_VERSION "0.0"
45#define DRIVER_DESC "Driver for B2C2/Technisat Air/Cable/Sky-2-PC USB devices"
46#define DRIVER_AUTHOR "Patrick Boettcher, patrick.boettcher@desy.de"
47
48/* transfer parameters */
49#define B2C2_USB_FRAMES_PER_ISO 4
50#define B2C2_USB_NUM_ISO_URB 4 /* TODO check out a good value */
51
52#define B2C2_USB_CTRL_PIPE_IN usb_rcvctrlpipe(b2c2->udev,0)
53#define B2C2_USB_CTRL_PIPE_OUT usb_sndctrlpipe(b2c2->udev,0)
54#define B2C2_USB_DATA_PIPE usb_rcvisocpipe(b2c2->udev,0x81)
55
56struct usb_b2c2_usb {
57 struct usb_device *udev;
58 struct usb_interface *uintf;
59
60 u8 *iso_buffer;
61 int buffer_size;
62 dma_addr_t iso_dma_handle;
63 struct urb *iso_urb[B2C2_USB_NUM_ISO_URB];
64};
65
66
67/*
68 * USB
69 * 10 90 34 12 78 56 04 00
70 * usb_control_msg(udev, usb_sndctrlpipe(udev,0),
71 * 0x90,
72 * 0x10,
73 * 0x1234,
74 * 0x5678,
75 * buf,
76 * 4,
77 * 5*HZ);
78 *
79 * extern int usb_control_msg(struct usb_device *dev, unsigned int pipe,
80 * __u8 request,
81 * __u8 requesttype,
82 * __u16 value,
83 * __u16 index,
84 * void *data,
85 * __u16 size,
86 * int timeout);
87 *
88 */
89
90/* request types */
91typedef enum {
92
93/* something is wrong with this part
94 RTYPE_READ_DW = (1 << 6),
95 RTYPE_WRITE_DW_1 = (3 << 6),
96 RTYPE_READ_V8_MEMORY = (6 << 6),
97 RTYPE_WRITE_V8_MEMORY = (7 << 6),
98 RTYPE_WRITE_V8_FLASH = (8 << 6),
99 RTYPE_GENERIC = (9 << 6),
100*/
101 RTYPE_READ_DW = (3 << 6),
102 RTYPE_WRITE_DW_1 = (1 << 6),
103
104 RTYPE_READ_V8_MEMORY = (6 << 6),
105 RTYPE_WRITE_V8_MEMORY = (7 << 6),
106 RTYPE_WRITE_V8_FLASH = (8 << 6),
107 RTYPE_GENERIC = (9 << 6),
108} b2c2_usb_request_type_t;
109
110/* request */
111typedef enum {
112 B2C2_USB_WRITE_V8_MEM = 0x04,
113 B2C2_USB_READ_V8_MEM = 0x05,
114 B2C2_USB_READ_REG = 0x08,
115 B2C2_USB_WRITE_REG = 0x0A,
116/* B2C2_USB_WRITEREGLO = 0x0A, */
117 B2C2_USB_WRITEREGHI = 0x0B,
118 B2C2_USB_FLASH_BLOCK = 0x10,
119 B2C2_USB_I2C_REQUEST = 0x11,
120 B2C2_USB_UTILITY = 0x12,
121} b2c2_usb_request_t;
122
123/* function definition for I2C_REQUEST */
124typedef enum {
125 USB_FUNC_I2C_WRITE = 0x01,
126 USB_FUNC_I2C_MULTIWRITE = 0x02,
127 USB_FUNC_I2C_READ = 0x03,
128 USB_FUNC_I2C_REPEATWRITE = 0x04,
129 USB_FUNC_GET_DESCRIPTOR = 0x05,
130 USB_FUNC_I2C_REPEATREAD = 0x06,
131/* DKT 020208 - add this to support special case of DiSEqC */
132 USB_FUNC_I2C_CHECKWRITE = 0x07,
133 USB_FUNC_I2C_CHECKRESULT = 0x08,
134} b2c2_usb_i2c_function_t;
135
136/*
137 * function definition for UTILITY request 0x12
138 * DKT 020304 - new utility function
139 */
140typedef enum {
141 UTILITY_SET_FILTER = 0x01,
142 UTILITY_DATA_ENABLE = 0x02,
143 UTILITY_FLEX_MULTIWRITE = 0x03,
144 UTILITY_SET_BUFFER_SIZE = 0x04,
145 UTILITY_FLEX_OPERATOR = 0x05,
146 UTILITY_FLEX_RESET300_START = 0x06,
147 UTILITY_FLEX_RESET300_STOP = 0x07,
148 UTILITY_FLEX_RESET300 = 0x08,
149 UTILITY_SET_ISO_SIZE = 0x09,
150 UTILITY_DATA_RESET = 0x0A,
151 UTILITY_GET_DATA_STATUS = 0x10,
152 UTILITY_GET_V8_REG = 0x11,
153/* DKT 020326 - add function for v1.14 */
154 UTILITY_SRAM_WRITE = 0x12,
155 UTILITY_SRAM_READ = 0x13,
156 UTILITY_SRAM_TESTFILL = 0x14,
157 UTILITY_SRAM_TESTSET = 0x15,
158 UTILITY_SRAM_TESTVERIFY = 0x16,
159} b2c2_usb_utility_function_t;
160
161#define B2C2_WAIT_FOR_OPERATION_RW 1 // 1 s
162#define B2C2_WAIT_FOR_OPERATION_RDW 3 // 3 s
163#define B2C2_WAIT_FOR_OPERATION_WDW 1 // 1 s
164
165#define B2C2_WAIT_FOR_OPERATION_V8READ 3 // 3 s
166#define B2C2_WAIT_FOR_OPERATION_V8WRITE 3 // 3 s
167#define B2C2_WAIT_FOR_OPERATION_V8FLASH 3 // 3 s
168
169/* JLP 111700: we will include the 1 bit gap between the upper and lower 3 bits
170 * in the IBI address, to make the V8 code simpler.
171 * PCI ADDRESS FORMAT: 0x71C -> 0000 0111 0001 1100 (these are the six bits used)
172 * in general: 0000 0HHH 000L LL00
173 * IBI ADDRESS FORMAT: RHHH BLLL
174 *
175 * where R is the read(1)/write(0) bit, B is the busy bit
176 * and HHH and LLL are the two sets of three bits from the PCI address.
177 */
178#define B2C2_FLEX_PCIOFFSET_TO_INTERNALADDR(usPCI) (u8) (((usPCI >> 2) & 0x07) + ((usPCI >> 4) & 0x70))
179#define B2C2_FLEX_INTERNALADDR_TO_PCIOFFSET(ucAddr) (u16) (((ucAddr & 0x07) << 2) + ((ucAddr & 0x70) << 4))
180
181/*
182 * DKT 020228 - forget about this VENDOR_BUFFER_SIZE, read and write register
183 * deal with DWORD or 4 bytes, that should be should from now on
184 */
185static u32 b2c2_usb_read_dw(struct usb_b2c2_usb *b2c2, u16 wRegOffsPCI)
186{
187 u32 val;
188 u16 wAddress = B2C2_FLEX_PCIOFFSET_TO_INTERNALADDR(wRegOffsPCI) | 0x0080;
189 int len = usb_control_msg(b2c2->udev,
190 B2C2_USB_CTRL_PIPE_IN,
191 B2C2_USB_READ_REG,
192 RTYPE_READ_DW,
193 wAddress,
194 0,
195 &val,
196 sizeof(u32),
197 B2C2_WAIT_FOR_OPERATION_RDW * 1000);
198
199 if (len != sizeof(u32)) {
200 err("error while reading dword from %d (%d).",wAddress,wRegOffsPCI);
201 return -EIO;
202 } else
203 return val;
204}
205
206/*
207 * DKT 020228 - from now on, we don't support anything older than firm 1.00
208 * I eliminated the write register as a 2 trip of writing hi word and lo word
209 * and force this to write only 4 bytes at a time.
210 * NOTE: this should work with all the firmware from 1.00 and newer
211 */
212static int b2c2_usb_write_dw(struct usb_b2c2_usb *b2c2, u16 wRegOffsPCI, u32 val)
213{
214 u16 wAddress = B2C2_FLEX_PCIOFFSET_TO_INTERNALADDR(wRegOffsPCI);
215 int len = usb_control_msg(b2c2->udev,
216 B2C2_USB_CTRL_PIPE_OUT,
217 B2C2_USB_WRITE_REG,
218 RTYPE_WRITE_DW_1,
219 wAddress,
220 0,
221 &val,
222 sizeof(u32),
223 B2C2_WAIT_FOR_OPERATION_RDW * 1000);
224
225 if (len != sizeof(u32)) {
226 err("error while reading dword from %d (%d).",wAddress,wRegOffsPCI);
227 return -EIO;
228 } else
229 return 0;
230}
231
232/*
233 * DKT 010817 - add support for V8 memory read/write and flash update
234 */
235static int b2c2_usb_v8_memory_req(struct usb_b2c2_usb *b2c2,
236 b2c2_usb_request_t req, u8 page, u16 wAddress,
237 u16 buflen, u8 *pbBuffer)
238{
239 u8 dwRequestType;
240 u16 wIndex;
241 int nWaitTime,pipe,len;
242
243 wIndex = page << 8;
244
245 switch (req) {
246 case B2C2_USB_READ_V8_MEM:
247 nWaitTime = B2C2_WAIT_FOR_OPERATION_V8READ;
248 dwRequestType = (u8) RTYPE_READ_V8_MEMORY;
249 pipe = B2C2_USB_CTRL_PIPE_IN;
250 break;
251 case B2C2_USB_WRITE_V8_MEM:
252 wIndex |= pbBuffer[0];
253 nWaitTime = B2C2_WAIT_FOR_OPERATION_V8WRITE;
254 dwRequestType = (u8) RTYPE_WRITE_V8_MEMORY;
255 pipe = B2C2_USB_CTRL_PIPE_OUT;
256 break;
257 case B2C2_USB_FLASH_BLOCK:
258 nWaitTime = B2C2_WAIT_FOR_OPERATION_V8FLASH;
259 dwRequestType = (u8) RTYPE_WRITE_V8_FLASH;
260 pipe = B2C2_USB_CTRL_PIPE_OUT;
261 break;
262 default:
263 deb_info("unsupported request for v8_mem_req %x.\n",req);
264 return -EINVAL;
265 }
266 len = usb_control_msg(b2c2->udev,pipe,
267 req,
268 dwRequestType,
269 wAddress,
270 wIndex,
271 pbBuffer,
272 buflen,
273 nWaitTime * 1000);
274 return len == buflen ? 0 : -EIO;
275}
276
277static int b2c2_usb_i2c_req(struct usb_b2c2_usb *b2c2,
278 b2c2_usb_request_t req, b2c2_usb_i2c_function_t func,
279 u8 port, u8 chipaddr, u8 addr, u8 buflen, u8 *buf)
280{
281 u16 wValue, wIndex;
282 int nWaitTime,pipe,len;
283 u8 dwRequestType;
284
285 switch (func) {
286 case USB_FUNC_I2C_WRITE:
287 case USB_FUNC_I2C_MULTIWRITE:
288 case USB_FUNC_I2C_REPEATWRITE:
289 /* DKT 020208 - add this to support special case of DiSEqC */
290 case USB_FUNC_I2C_CHECKWRITE:
291 pipe = B2C2_USB_CTRL_PIPE_OUT;
292 nWaitTime = 2;
293 dwRequestType = (u8) RTYPE_GENERIC;
294 break;
295 case USB_FUNC_I2C_READ:
296 case USB_FUNC_I2C_REPEATREAD:
297 pipe = B2C2_USB_CTRL_PIPE_IN;
298 nWaitTime = 2;
299 dwRequestType = (u8) RTYPE_GENERIC;
300 break;
301 default:
302 deb_info("unsupported function for i2c_req %x\n",func);
303 return -EINVAL;
304 }
305 wValue = (func << 8 ) | port;
306 wIndex = (chipaddr << 8 ) | addr;
307
308 len = usb_control_msg(b2c2->udev,pipe,
309 req,
310 dwRequestType,
311 addr,
312 wIndex,
313 buf,
314 buflen,
315 nWaitTime * 1000);
316 return len == buflen ? 0 : -EIO;
317}
318
319int static b2c2_usb_utility_req(struct usb_b2c2_usb *b2c2, int set,
320 b2c2_usb_utility_function_t func, u8 extra, u16 wIndex,
321 u16 buflen, u8 *pvBuffer)
322{
323 u16 wValue;
324 int nWaitTime = 2,
325 pipe = set ? B2C2_USB_CTRL_PIPE_OUT : B2C2_USB_CTRL_PIPE_IN,
326 len;
327
328 wValue = (func << 8) | extra;
329
330 len = usb_control_msg(b2c2->udev,pipe,
331 B2C2_USB_UTILITY,
332 (u8) RTYPE_GENERIC,
333 wValue,
334 wIndex,
335 pvBuffer,
336 buflen,
337 nWaitTime * 1000);
338 return len == buflen ? 0 : -EIO;
339}
340
341
342
343static void b2c2_dumpfourreg(struct usb_b2c2_usb *b2c2, u16 offs)
344{
345 u32 r0,r1,r2,r3;
346 r0 = r1 = r2 = r3 = 0;
347 r0 = b2c2_usb_read_dw(b2c2,offs);
348 r1 = b2c2_usb_read_dw(b2c2,offs + 0x04);
349 r2 = b2c2_usb_read_dw(b2c2,offs + 0x08);
350 r3 = b2c2_usb_read_dw(b2c2,offs + 0x0c);
351 deb_ctrl("dump: offset: %03x, %08x, %08x, %08x, %08x\n",offs,r0,r1,r2,r3);
352}
353
354static void b2c2_urb_complete(struct urb *urb, struct pt_regs *ptregs)
355{
356 struct usb_b2c2_usb *b2c2 = urb->context;
357 deb_ts("urb completed, bufsize: %d\n",urb->transfer_buffer_length);
358
359// urb_submit_urb(urb,GFP_ATOMIC); enable for real action
360}
361
362static void b2c2_exit_usb(struct usb_b2c2_usb *b2c2)
363{
364 int i;
365 for (i = 0; i < B2C2_USB_NUM_ISO_URB; i++)
366 if (b2c2->iso_urb[i] != NULL) { /* not sure about unlink_urb and iso-urbs TODO */
367 deb_info("unlinking/killing urb no. %d\n",i);
368#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,7)
369 usb_unlink_urb(b2c2->iso_urb[i]);
370#else
371 usb_kill_urb(b2c2->iso_urb[i]);
372#endif
373 usb_free_urb(b2c2->iso_urb[i]);
374 }
375
376 if (b2c2->iso_buffer != NULL)
377 pci_free_consistent(NULL,b2c2->buffer_size, b2c2->iso_buffer, b2c2->iso_dma_handle);
378
379}
380
381static int b2c2_init_usb(struct usb_b2c2_usb *b2c2)
382{
383 u16 frame_size = le16_to_cpu(b2c2->uintf->cur_altsetting->endpoint[0].desc.wMaxPacketSize);
384 int bufsize = B2C2_USB_NUM_ISO_URB * B2C2_USB_FRAMES_PER_ISO * frame_size,i,j,ret;
385 int buffer_offset = 0;
386
387 deb_info("creating %d iso-urbs with %d frames each of %d bytes size = %d.\n",
388 B2C2_USB_NUM_ISO_URB, B2C2_USB_FRAMES_PER_ISO, frame_size,bufsize);
389
390 b2c2->iso_buffer = pci_alloc_consistent(NULL,bufsize,&b2c2->iso_dma_handle);
391 if (b2c2->iso_buffer == NULL)
392 return -ENOMEM;
393 memset(b2c2->iso_buffer, 0, bufsize);
394 b2c2->buffer_size = bufsize;
395
396 /* creating iso urbs */
397 for (i = 0; i < B2C2_USB_NUM_ISO_URB; i++)
398 if (!(b2c2->iso_urb[i] = usb_alloc_urb(B2C2_USB_FRAMES_PER_ISO,GFP_ATOMIC))) {
399 ret = -ENOMEM;
400 goto urb_error;
401 }
402 /* initialising and submitting iso urbs */
403 for (i = 0; i < B2C2_USB_NUM_ISO_URB; i++) {
404 int frame_offset = 0;
405 struct urb *urb = b2c2->iso_urb[i];
406 deb_info("initializing and submitting urb no. %d (buf_offset: %d).\n",i,buffer_offset);
407
408 urb->dev = b2c2->udev;
409 urb->context = b2c2;
410 urb->complete = b2c2_urb_complete;
411 urb->pipe = B2C2_USB_DATA_PIPE;
412 urb->transfer_flags = URB_ISO_ASAP;
413 urb->interval = 1;
414 urb->number_of_packets = B2C2_USB_FRAMES_PER_ISO;
415 urb->transfer_buffer_length = frame_size * B2C2_USB_FRAMES_PER_ISO;
416 urb->transfer_buffer = b2c2->iso_buffer + buffer_offset;
417
418 buffer_offset += frame_size * B2C2_USB_FRAMES_PER_ISO;
419 for (j = 0; j < B2C2_USB_FRAMES_PER_ISO; j++) {
420 deb_info("urb no: %d, frame: %d, frame_offset: %d\n",i,j,frame_offset);
421 urb->iso_frame_desc[j].offset = frame_offset;
422 urb->iso_frame_desc[j].length = frame_size;
423 frame_offset += frame_size;
424 }
425
426 if ((ret = usb_submit_urb(b2c2->iso_urb[i],GFP_ATOMIC))) {
427 err("submitting urb %d failed with %d.",i,ret);
428 goto urb_error;
429 }
430 deb_info("submitted urb no. %d.\n",i);
431 }
432
433 ret = 0;
434 goto success;
435urb_error:
436 b2c2_exit_usb(b2c2);
437success:
438 return ret;
439}
440
441static int b2c2_usb_probe(struct usb_interface *intf,
442 const struct usb_device_id *id)
443{
444 struct usb_device *udev = interface_to_usbdev(intf);
445 struct usb_b2c2_usb *b2c2 = NULL;
446 int ret;
447
448 b2c2 = kmalloc(sizeof(struct usb_b2c2_usb),GFP_KERNEL);
449 if (b2c2 == NULL) {
450 err("no memory");
451 return -ENOMEM;
452 }
453 b2c2->udev = udev;
454 b2c2->uintf = intf;
455
456 /* use the alternate setting with the larges buffer */
457 usb_set_interface(udev,0,1);
458
459 if ((ret = b2c2_init_usb(b2c2)))
460 goto usb_init_error;
461
462 usb_set_intfdata(intf,b2c2);
463
464 switch (udev->speed) {
465 case USB_SPEED_LOW:
466 err("cannot handle USB speed because it is to sLOW.");
467 break;
468 case USB_SPEED_FULL:
469 info("running at FULL speed.");
470 break;
471 case USB_SPEED_HIGH:
472 info("running at HIGH speed.");
473 break;
474 case USB_SPEED_UNKNOWN: /* fall through */
475 default:
476 err("cannot handle USB speed because it is unkown.");
477 break;
478 }
479
480 b2c2_dumpfourreg(b2c2,0x200);
481 b2c2_dumpfourreg(b2c2,0x300);
482 b2c2_dumpfourreg(b2c2,0x400);
483 b2c2_dumpfourreg(b2c2,0x700);
484
485
486 if (ret == 0)
487 info("%s successfully initialized and connected.",DRIVER_DESC);
488 else
489 info("%s error while loading driver (%d)",DRIVER_DESC,ret);
490
491 ret = 0;
492 goto success;
493
494usb_init_error:
495 kfree(b2c2);
496success:
497 return ret;
498}
499
500static void b2c2_usb_disconnect(struct usb_interface *intf)
501{
502 struct usb_b2c2_usb *b2c2 = usb_get_intfdata(intf);
503 usb_set_intfdata(intf,NULL);
504 if (b2c2 != NULL) {
505 b2c2_exit_usb(b2c2);
506 kfree(b2c2);
507 }
508 info("%s successfully deinitialized and disconnected.",DRIVER_DESC);
509
510}
511
512static struct usb_device_id b2c2_usb_table [] = {
513 { USB_DEVICE(0x0af7, 0x0101) }
514};
515
516/* usb specific object needed to register this driver with the usb subsystem */
517static struct usb_driver b2c2_usb_driver = {
518 .owner = THIS_MODULE,
519 .name = "dvb_b2c2_usb",
520 .probe = b2c2_usb_probe,
521 .disconnect = b2c2_usb_disconnect,
522 .id_table = b2c2_usb_table,
523};
524
525/* module stuff */
526static int __init b2c2_usb_init(void)
527{
528 int result;
529 if ((result = usb_register(&b2c2_usb_driver))) {
530 err("usb_register failed. Error number %d",result);
531 return result;
532 }
533
534 return 0;
535}
536
537static void __exit b2c2_usb_exit(void)
538{
539 /* deregister this driver from the USB subsystem */
540 usb_deregister(&b2c2_usb_driver);
541}
542
543module_init (b2c2_usb_init);
544module_exit (b2c2_usb_exit);
545
546MODULE_AUTHOR(DRIVER_AUTHOR);
547MODULE_DESCRIPTION(DRIVER_DESC);
548MODULE_LICENSE("GPL");
549MODULE_DEVICE_TABLE(usb, b2c2_usb_table);
diff --git a/drivers/media/dvb/b2c2/skystar2.c b/drivers/media/dvb/b2c2/skystar2.c
new file mode 100644
index 000000000000..336c178fcd5f
--- /dev/null
+++ b/drivers/media/dvb/b2c2/skystar2.c
@@ -0,0 +1,2644 @@
1/*
2 * skystar2.c - driver for the Technisat SkyStar2 PCI DVB card
3 * based on the FlexCopII by B2C2,Inc.
4 *
5 * Copyright (C) 2003 Vadim Catana, skystar@moldova.cc
6 *
7 * FIX: DISEQC Tone Burst in flexcop_diseqc_ioctl()
8 * FIX: FULL soft DiSEqC for skystar2 (FlexCopII rev 130) VP310 equipped
9 * Vincenzo Di Massa, hawk.it at tiscalinet.it
10 *
11 * Converted to Linux coding style
12 * Misc reorganization, polishing, restyling
13 * Roberto Ragusa, skystar2-c5b8 at robertoragusa dot it
14 *
15 * Added hardware filtering support,
16 * Niklas Peinecke, peinecke at gdv.uni-hannover.de
17 *
18 *
19 * This program is free software; you can redistribute it and/or
20 * modify it under the terms of the GNU Lesser General Public License
21 * as published by the Free Software Foundation; either version 2.1
22 * of the License, or (at your option) any later version.
23 *
24 * This program is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
28 *
29 * You should have received a copy of the GNU Lesser General Public License
30 * along with this program; if not, write to the Free Software
31 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
32 */
33
34#include <linux/module.h>
35#include <linux/moduleparam.h>
36#include <linux/delay.h>
37#include <linux/pci.h>
38#include <linux/init.h>
39#include <linux/version.h>
40
41#include <asm/io.h>
42
43#include "dvb_frontend.h"
44
45#include <linux/dvb/frontend.h>
46#include <linux/dvb/dmx.h>
47#include "dvb_demux.h"
48#include "dmxdev.h"
49#include "dvb_filter.h"
50#include "dvbdev.h"
51#include "demux.h"
52#include "dvb_net.h"
53#include "stv0299.h"
54#include "mt352.h"
55#include "mt312.h"
56#include "nxt2002.h"
57
58static int debug;
59static int enable_hw_filters = 2;
60
61module_param(debug, int, 0644);
62MODULE_PARM_DESC(debug, "Set debugging level (0 = default, 1 = most messages, 2 = all messages).");
63module_param(enable_hw_filters, int, 0444);
64MODULE_PARM_DESC(enable_hw_filters, "enable hardware filters: supported values: 0 (none), 1, 2");
65
66#define dprintk(x...) do { if (debug>=1) printk(x); } while (0)
67#define ddprintk(x...) do { if (debug>=2) printk(x); } while (0)
68
69#define SIZE_OF_BUF_DMA1 0x3ac00
70#define SIZE_OF_BUF_DMA2 0x758
71
72#define MAX_N_HW_FILTERS (6+32)
73#define N_PID_SLOTS 256
74
75struct dmaq {
76 u32 bus_addr;
77 u32 head;
78 u32 tail;
79 u32 buffer_size;
80 u8 *buffer;
81};
82
83#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9)
84#define __iomem
85#endif
86
87struct adapter {
88 struct pci_dev *pdev;
89
90 u8 card_revision;
91 u32 b2c2_revision;
92 u32 pid_filter_max;
93 u32 mac_filter_max;
94 u32 irq;
95 void __iomem *io_mem;
96 unsigned long io_port;
97 u8 mac_addr[8];
98 u32 dw_sram_type;
99
100 struct dvb_adapter *dvb_adapter;
101 struct dvb_demux demux;
102 struct dmxdev dmxdev;
103 struct dmx_frontend hw_frontend;
104 struct dmx_frontend mem_frontend;
105 struct i2c_adapter i2c_adap;
106 struct dvb_net dvbnet;
107
108 struct semaphore i2c_sem;
109
110 struct dmaq dmaq1;
111 struct dmaq dmaq2;
112
113 u32 dma_ctrl;
114 u32 dma_status;
115
116 int capturing;
117
118 spinlock_t lock;
119
120 int useable_hw_filters;
121 u16 hw_pids[MAX_N_HW_FILTERS];
122 u16 pid_list[N_PID_SLOTS];
123 int pid_rc[N_PID_SLOTS]; // ref counters for the pids
124 int pid_count;
125 int whole_bandwidth_count;
126 u32 mac_filter;
127
128 struct dvb_frontend* fe;
129 int (*fe_sleep)(struct dvb_frontend* fe);
130};
131
132#define write_reg_dw(adapter,reg,value) writel(value, adapter->io_mem + reg)
133#define read_reg_dw(adapter,reg) readl(adapter->io_mem + reg)
134
135static void write_reg_bitfield(struct adapter *adapter, u32 reg, u32 zeromask, u32 orvalue)
136{
137 u32 tmp;
138
139 tmp = read_reg_dw(adapter, reg);
140 tmp = (tmp & ~zeromask) | orvalue;
141 write_reg_dw(adapter, reg, tmp);
142}
143
144/* i2c functions */
145static int i2c_main_write_for_flex2(struct adapter *adapter, u32 command, u8 *buf, int retries)
146{
147 int i;
148 u32 value;
149
150 write_reg_dw(adapter, 0x100, 0);
151 write_reg_dw(adapter, 0x100, command);
152
153 for (i = 0; i < retries; i++) {
154 value = read_reg_dw(adapter, 0x100);
155
156 if ((value & 0x40000000) == 0) {
157 if ((value & 0x81000000) == 0x80000000) {
158 if (buf != 0)
159 *buf = (value >> 0x10) & 0xff;
160
161 return 1;
162 }
163 } else {
164 write_reg_dw(adapter, 0x100, 0);
165 write_reg_dw(adapter, 0x100, command);
166 }
167 }
168
169 return 0;
170}
171
172/* device = 0x10000000 for tuner, 0x20000000 for eeprom */
173static void i2c_main_setup(u32 device, u32 chip_addr, u8 op, u8 addr, u32 value, u32 len, u32 *command)
174{
175 *command = device | ((len - 1) << 26) | (value << 16) | (addr << 8) | chip_addr;
176
177 if (op != 0)
178 *command = *command | 0x03000000;
179 else
180 *command = *command | 0x01000000;
181}
182
183static int flex_i2c_read4(struct adapter *adapter, u32 device, u32 chip_addr, u16 addr, u8 *buf, u8 len)
184{
185 u32 command;
186 u32 value;
187
188 int result, i;
189
190 i2c_main_setup(device, chip_addr, 1, addr, 0, len, &command);
191
192 result = i2c_main_write_for_flex2(adapter, command, buf, 100000);
193
194 if ((result & 0xff) != 0) {
195 if (len > 1) {
196 value = read_reg_dw(adapter, 0x104);
197
198 for (i = 1; i < len; i++) {
199 buf[i] = value & 0xff;
200 value = value >> 8;
201 }
202 }
203 }
204
205 return result;
206}
207
208static int flex_i2c_write4(struct adapter *adapter, u32 device, u32 chip_addr, u32 addr, u8 *buf, u8 len)
209{
210 u32 command;
211 u32 value;
212 int i;
213
214 if (len > 1) {
215 value = 0;
216
217 for (i = len; i > 1; i--) {
218 value = value << 8;
219 value = value | buf[i - 1];
220 }
221
222 write_reg_dw(adapter, 0x104, value);
223 }
224
225 i2c_main_setup(device, chip_addr, 0, addr, buf[0], len, &command);
226
227 return i2c_main_write_for_flex2(adapter, command, NULL, 100000);
228}
229
230static void fixchipaddr(u32 device, u32 bus, u32 addr, u32 *ret)
231{
232 if (device == 0x20000000)
233 *ret = bus | ((addr >> 8) & 3);
234 else
235 *ret = bus;
236}
237
238static u32 flex_i2c_read(struct adapter *adapter, u32 device, u32 bus, u32 addr, u8 *buf, u32 len)
239{
240 u32 chipaddr;
241 u32 bytes_to_transfer;
242 u8 *start;
243
244 ddprintk("%s:\n", __FUNCTION__);
245
246 start = buf;
247
248 while (len != 0) {
249 bytes_to_transfer = len;
250
251 if (bytes_to_transfer > 4)
252 bytes_to_transfer = 4;
253
254 fixchipaddr(device, bus, addr, &chipaddr);
255
256 if (flex_i2c_read4(adapter, device, chipaddr, addr, buf, bytes_to_transfer) == 0)
257 return buf - start;
258
259 buf = buf + bytes_to_transfer;
260 addr = addr + bytes_to_transfer;
261 len = len - bytes_to_transfer;
262 };
263
264 return buf - start;
265}
266
267static u32 flex_i2c_write(struct adapter *adapter, u32 device, u32 bus, u32 addr, u8 *buf, u32 len)
268{
269 u32 chipaddr;
270 u32 bytes_to_transfer;
271 u8 *start;
272
273 ddprintk("%s:\n", __FUNCTION__);
274
275 start = buf;
276
277 while (len != 0) {
278 bytes_to_transfer = len;
279
280 if (bytes_to_transfer > 4)
281 bytes_to_transfer = 4;
282
283 fixchipaddr(device, bus, addr, &chipaddr);
284
285 if (flex_i2c_write4(adapter, device, chipaddr, addr, buf, bytes_to_transfer) == 0)
286 return buf - start;
287
288 buf = buf + bytes_to_transfer;
289 addr = addr + bytes_to_transfer;
290 len = len - bytes_to_transfer;
291 }
292
293 return buf - start;
294}
295
296static int master_xfer(struct i2c_adapter* adapter, struct i2c_msg *msgs, int num)
297{
298 struct adapter *tmp = i2c_get_adapdata(adapter);
299 int i, ret = 0;
300
301 if (down_interruptible(&tmp->i2c_sem))
302 return -ERESTARTSYS;
303
304 ddprintk("%s: %d messages to transfer\n", __FUNCTION__, num);
305
306 for (i = 0; i < num; i++) {
307 ddprintk("message %d: flags=0x%x, addr=0x%x, buf=0x%x, len=%d \n", i,
308 msgs[i].flags, msgs[i].addr, msgs[i].buf[0], msgs[i].len);
309 }
310
311 // read command
312 if ((num == 2) && (msgs[0].flags == 0) && (msgs[1].flags == I2C_M_RD) && (msgs[0].buf != NULL) && (msgs[1].buf != NULL)) {
313
314 ret = flex_i2c_read(tmp, 0x10000000, msgs[0].addr, msgs[0].buf[0], msgs[1].buf, msgs[1].len);
315
316 up(&tmp->i2c_sem);
317
318 if (ret != msgs[1].len) {
319 dprintk("%s: read error !\n", __FUNCTION__);
320
321 for (i = 0; i < 2; i++) {
322 dprintk("message %d: flags=0x%x, addr=0x%x, buf=0x%x, len=%d \n", i,
323 msgs[i].flags, msgs[i].addr, msgs[i].buf[0], msgs[i].len);
324 }
325
326 return -EREMOTEIO;
327 }
328
329 return num;
330 }
331 // write command
332 for (i = 0; i < num; i++) {
333
334 if ((msgs[i].flags != 0) || (msgs[i].buf == NULL) || (msgs[i].len < 2))
335 return -EINVAL;
336
337 ret = flex_i2c_write(tmp, 0x10000000, msgs[i].addr, msgs[i].buf[0], &msgs[i].buf[1], msgs[i].len - 1);
338
339 up(&tmp->i2c_sem);
340
341 if (ret != msgs[0].len - 1) {
342 dprintk("%s: write error %i !\n", __FUNCTION__, ret);
343
344 dprintk("message %d: flags=0x%x, addr=0x%x, buf[0]=0x%x, len=%d \n", i,
345 msgs[i].flags, msgs[i].addr, msgs[i].buf[0], msgs[i].len);
346
347 return -EREMOTEIO;
348 }
349
350 return num;
351 }
352
353 printk("%s: unknown command format !\n", __FUNCTION__);
354
355 return -EINVAL;
356}
357
358/* SRAM (Skystar2 rev2.3 has one "ISSI IS61LV256" chip on board,
359 but it seems that FlexCopII can work with more than one chip) */
360static void sram_set_net_dest(struct adapter *adapter, u8 dest)
361{
362 u32 tmp;
363
364 udelay(1000);
365
366 tmp = (read_reg_dw(adapter, 0x714) & 0xfffffffc) | (dest & 3);
367
368 udelay(1000);
369
370 write_reg_dw(adapter, 0x714, tmp);
371 write_reg_dw(adapter, 0x714, tmp);
372
373 udelay(1000);
374
375 /* return value is never used? */
376/* return tmp; */
377}
378
379static void sram_set_cai_dest(struct adapter *adapter, u8 dest)
380{
381 u32 tmp;
382
383 udelay(1000);
384
385 tmp = (read_reg_dw(adapter, 0x714) & 0xfffffff3) | ((dest & 3) << 2);
386
387 udelay(1000);
388 udelay(1000);
389
390 write_reg_dw(adapter, 0x714, tmp);
391 write_reg_dw(adapter, 0x714, tmp);
392
393 udelay(1000);
394
395 /* return value is never used? */
396/* return tmp; */
397}
398
399static void sram_set_cao_dest(struct adapter *adapter, u8 dest)
400{
401 u32 tmp;
402
403 udelay(1000);
404
405 tmp = (read_reg_dw(adapter, 0x714) & 0xffffffcf) | ((dest & 3) << 4);
406
407 udelay(1000);
408 udelay(1000);
409
410 write_reg_dw(adapter, 0x714, tmp);
411 write_reg_dw(adapter, 0x714, tmp);
412
413 udelay(1000);
414
415 /* return value is never used? */
416/* return tmp; */
417}
418
419static void sram_set_media_dest(struct adapter *adapter, u8 dest)
420{
421 u32 tmp;
422
423 udelay(1000);
424
425 tmp = (read_reg_dw(adapter, 0x714) & 0xffffff3f) | ((dest & 3) << 6);
426
427 udelay(1000);
428 udelay(1000);
429
430 write_reg_dw(adapter, 0x714, tmp);
431 write_reg_dw(adapter, 0x714, tmp);
432
433 udelay(1000);
434
435 /* return value is never used? */
436/* return tmp; */
437}
438
439/* SRAM memory is accessed through a buffer register in the FlexCop
440 chip (0x700). This register has the following structure:
441 bits 0-14 : address
442 bit 15 : read/write flag
443 bits 16-23 : 8-bit word to write
444 bits 24-27 : = 4
445 bits 28-29 : memory bank selector
446 bit 31 : busy flag
447*/
448static void flex_sram_write(struct adapter *adapter, u32 bank, u32 addr, u8 *buf, u32 len)
449{
450 int i, retries;
451 u32 command;
452
453 for (i = 0; i < len; i++) {
454 command = bank | addr | 0x04000000 | (*buf << 0x10);
455
456 retries = 2;
457
458 while (((read_reg_dw(adapter, 0x700) & 0x80000000) != 0) && (retries > 0)) {
459 mdelay(1);
460 retries--;
461 };
462
463 if (retries == 0)
464 printk("%s: SRAM timeout\n", __FUNCTION__);
465
466 write_reg_dw(adapter, 0x700, command);
467
468 buf++;
469 addr++;
470 }
471}
472
473static void flex_sram_read(struct adapter *adapter, u32 bank, u32 addr, u8 *buf, u32 len)
474{
475 int i, retries;
476 u32 command, value;
477
478 for (i = 0; i < len; i++) {
479 command = bank | addr | 0x04008000;
480
481 retries = 10000;
482
483 while (((read_reg_dw(adapter, 0x700) & 0x80000000) != 0) && (retries > 0)) {
484 mdelay(1);
485 retries--;
486 };
487
488 if (retries == 0)
489 printk("%s: SRAM timeout\n", __FUNCTION__);
490
491 write_reg_dw(adapter, 0x700, command);
492
493 retries = 10000;
494
495 while (((read_reg_dw(adapter, 0x700) & 0x80000000) != 0) && (retries > 0)) {
496 mdelay(1);
497 retries--;
498 };
499
500 if (retries == 0)
501 printk("%s: SRAM timeout\n", __FUNCTION__);
502
503 value = read_reg_dw(adapter, 0x700) >> 0x10;
504
505 *buf = (value & 0xff);
506
507 addr++;
508 buf++;
509 }
510}
511
512static void sram_write_chunk(struct adapter *adapter, u32 addr, u8 *buf, u16 len)
513{
514 u32 bank;
515
516 bank = 0;
517
518 if (adapter->dw_sram_type == 0x20000) {
519 bank = (addr & 0x18000) << 0x0d;
520 }
521
522 if (adapter->dw_sram_type == 0x00000) {
523 if ((addr >> 0x0f) == 0)
524 bank = 0x20000000;
525 else
526 bank = 0x10000000;
527 }
528
529 flex_sram_write(adapter, bank, addr & 0x7fff, buf, len);
530}
531
532static void sram_read_chunk(struct adapter *adapter, u32 addr, u8 *buf, u16 len)
533{
534 u32 bank;
535
536 bank = 0;
537
538 if (adapter->dw_sram_type == 0x20000) {
539 bank = (addr & 0x18000) << 0x0d;
540 }
541
542 if (adapter->dw_sram_type == 0x00000) {
543 if ((addr >> 0x0f) == 0)
544 bank = 0x20000000;
545 else
546 bank = 0x10000000;
547 }
548
549 flex_sram_read(adapter, bank, addr & 0x7fff, buf, len);
550}
551
552static void sram_read(struct adapter *adapter, u32 addr, u8 *buf, u32 len)
553{
554 u32 length;
555
556 while (len != 0) {
557 length = len;
558
559 // check if the address range belongs to the same
560 // 32K memory chip. If not, the data is read from
561 // one chip at a time.
562 if ((addr >> 0x0f) != ((addr + len - 1) >> 0x0f)) {
563 length = (((addr >> 0x0f) + 1) << 0x0f) - addr;
564 }
565
566 sram_read_chunk(adapter, addr, buf, length);
567
568 addr = addr + length;
569 buf = buf + length;
570 len = len - length;
571 }
572}
573
574static void sram_write(struct adapter *adapter, u32 addr, u8 *buf, u32 len)
575{
576 u32 length;
577
578 while (len != 0) {
579 length = len;
580
581 // check if the address range belongs to the same
582 // 32K memory chip. If not, the data is written to
583 // one chip at a time.
584 if ((addr >> 0x0f) != ((addr + len - 1) >> 0x0f)) {
585 length = (((addr >> 0x0f) + 1) << 0x0f) - addr;
586 }
587
588 sram_write_chunk(adapter, addr, buf, length);
589
590 addr = addr + length;
591 buf = buf + length;
592 len = len - length;
593 }
594}
595
596static void sram_set_size(struct adapter *adapter, u32 mask)
597{
598 write_reg_dw(adapter, 0x71c, (mask | (~0x30000 & read_reg_dw(adapter, 0x71c))));
599}
600
601static void sram_init(struct adapter *adapter)
602{
603 u32 tmp;
604
605 tmp = read_reg_dw(adapter, 0x71c);
606
607 write_reg_dw(adapter, 0x71c, 1);
608
609 if (read_reg_dw(adapter, 0x71c) != 0) {
610 write_reg_dw(adapter, 0x71c, tmp);
611
612 adapter->dw_sram_type = tmp & 0x30000;
613
614 ddprintk("%s: dw_sram_type = %x\n", __FUNCTION__, adapter->dw_sram_type);
615
616 } else {
617
618 adapter->dw_sram_type = 0x10000;
619
620 ddprintk("%s: dw_sram_type = %x\n", __FUNCTION__, adapter->dw_sram_type);
621 }
622
623 /* return value is never used? */
624/* return adapter->dw_sram_type; */
625}
626
627static int sram_test_location(struct adapter *adapter, u32 mask, u32 addr)
628{
629 u8 tmp1, tmp2;
630
631 dprintk("%s: mask = %x, addr = %x\n", __FUNCTION__, mask, addr);
632
633 sram_set_size(adapter, mask);
634 sram_init(adapter);
635
636 tmp2 = 0xa5;
637 tmp1 = 0x4f;
638
639 sram_write(adapter, addr, &tmp2, 1);
640 sram_write(adapter, addr + 4, &tmp1, 1);
641
642 tmp2 = 0;
643
644 mdelay(20);
645
646 sram_read(adapter, addr, &tmp2, 1);
647 sram_read(adapter, addr, &tmp2, 1);
648
649 dprintk("%s: wrote 0xa5, read 0x%2x\n", __FUNCTION__, tmp2);
650
651 if (tmp2 != 0xa5)
652 return 0;
653
654 tmp2 = 0x5a;
655 tmp1 = 0xf4;
656
657 sram_write(adapter, addr, &tmp2, 1);
658 sram_write(adapter, addr + 4, &tmp1, 1);
659
660 tmp2 = 0;
661
662 mdelay(20);
663
664 sram_read(adapter, addr, &tmp2, 1);
665 sram_read(adapter, addr, &tmp2, 1);
666
667 dprintk("%s: wrote 0x5a, read 0x%2x\n", __FUNCTION__, tmp2);
668
669 if (tmp2 != 0x5a)
670 return 0;
671
672 return 1;
673}
674
675static u32 sram_length(struct adapter *adapter)
676{
677 if (adapter->dw_sram_type == 0x10000)
678 return 32768; // 32K
679 if (adapter->dw_sram_type == 0x00000)
680 return 65536; // 64K
681 if (adapter->dw_sram_type == 0x20000)
682 return 131072; // 128K
683
684 return 32768; // 32K
685}
686
687/* FlexcopII can work with 32K, 64K or 128K of external SRAM memory.
688 - for 128K there are 4x32K chips at bank 0,1,2,3.
689 - for 64K there are 2x32K chips at bank 1,2.
690 - for 32K there is one 32K chip at bank 0.
691
692 FlexCop works only with one bank at a time. The bank is selected
693 by bits 28-29 of the 0x700 register.
694
695 bank 0 covers addresses 0x00000-0x07fff
696 bank 1 covers addresses 0x08000-0x0ffff
697 bank 2 covers addresses 0x10000-0x17fff
698 bank 3 covers addresses 0x18000-0x1ffff
699*/
700static int sram_detect_for_flex2(struct adapter *adapter)
701{
702 u32 tmp, tmp2, tmp3;
703
704 dprintk("%s:\n", __FUNCTION__);
705
706 tmp = read_reg_dw(adapter, 0x208);
707 write_reg_dw(adapter, 0x208, 0);
708
709 tmp2 = read_reg_dw(adapter, 0x71c);
710
711 dprintk("%s: tmp2 = %x\n", __FUNCTION__, tmp2);
712
713 write_reg_dw(adapter, 0x71c, 1);
714
715 tmp3 = read_reg_dw(adapter, 0x71c);
716
717 dprintk("%s: tmp3 = %x\n", __FUNCTION__, tmp3);
718
719 write_reg_dw(adapter, 0x71c, tmp2);
720
721 // check for internal SRAM ???
722 tmp3--;
723 if (tmp3 != 0) {
724 sram_set_size(adapter, 0x10000);
725 sram_init(adapter);
726 write_reg_dw(adapter, 0x208, tmp);
727
728 dprintk("%s: sram size = 32K\n", __FUNCTION__);
729
730 return 32;
731 }
732
733 if (sram_test_location(adapter, 0x20000, 0x18000) != 0) {
734 sram_set_size(adapter, 0x20000);
735 sram_init(adapter);
736 write_reg_dw(adapter, 0x208, tmp);
737
738 dprintk("%s: sram size = 128K\n", __FUNCTION__);
739
740 return 128;
741 }
742
743 if (sram_test_location(adapter, 0x00000, 0x10000) != 0) {
744 sram_set_size(adapter, 0x00000);
745 sram_init(adapter);
746 write_reg_dw(adapter, 0x208, tmp);
747
748 dprintk("%s: sram size = 64K\n", __FUNCTION__);
749
750 return 64;
751 }
752
753 if (sram_test_location(adapter, 0x10000, 0x00000) != 0) {
754 sram_set_size(adapter, 0x10000);
755 sram_init(adapter);
756 write_reg_dw(adapter, 0x208, tmp);
757
758 dprintk("%s: sram size = 32K\n", __FUNCTION__);
759
760 return 32;
761 }
762
763 sram_set_size(adapter, 0x10000);
764 sram_init(adapter);
765 write_reg_dw(adapter, 0x208, tmp);
766
767 dprintk("%s: SRAM detection failed. Set to 32K \n", __FUNCTION__);
768
769 return 0;
770}
771
772static void sll_detect_sram_size(struct adapter *adapter)
773{
774 sram_detect_for_flex2(adapter);
775}
776
777/* EEPROM (Skystar2 has one "24LC08B" chip on board) */
778/*
779static int eeprom_write(struct adapter *adapter, u16 addr, u8 *buf, u16 len)
780{
781 return flex_i2c_write(adapter, 0x20000000, 0x50, addr, buf, len);
782}
783*/
784
785static int eeprom_read(struct adapter *adapter, u16 addr, u8 *buf, u16 len)
786{
787 return flex_i2c_read(adapter, 0x20000000, 0x50, addr, buf, len);
788}
789
790static u8 calc_lrc(u8 *buf, int len)
791{
792 int i;
793 u8 sum;
794
795 sum = 0;
796
797 for (i = 0; i < len; i++)
798 sum = sum ^ buf[i];
799
800 return sum;
801}
802
803static int eeprom_lrc_read(struct adapter *adapter, u32 addr, u32 len, u8 *buf, int retries)
804{
805 int i;
806
807 for (i = 0; i < retries; i++) {
808 if (eeprom_read(adapter, addr, buf, len) == len) {
809 if (calc_lrc(buf, len - 1) == buf[len - 1])
810 return 1;
811 }
812 }
813
814 return 0;
815}
816
817/*
818static int eeprom_lrc_write(struct adapter *adapter, u32 addr, u32 len, u8 *wbuf, u8 *rbuf, int retries)
819{
820 int i;
821
822 for (i = 0; i < retries; i++) {
823 if (eeprom_write(adapter, addr, wbuf, len) == len) {
824 if (eeprom_lrc_read(adapter, addr, len, rbuf, retries) == 1)
825 return 1;
826 }
827 }
828
829 return 0;
830}
831*/
832
833
834/* These functions could be used to unlock SkyStar2 cards. */
835
836/*
837static int eeprom_writeKey(struct adapter *adapter, u8 *key, u32 len)
838{
839 u8 rbuf[20];
840 u8 wbuf[20];
841
842 if (len != 16)
843 return 0;
844
845 memcpy(wbuf, key, len);
846
847 wbuf[16] = 0;
848 wbuf[17] = 0;
849 wbuf[18] = 0;
850 wbuf[19] = calc_lrc(wbuf, 19);
851
852 return eeprom_lrc_write(adapter, 0x3e4, 20, wbuf, rbuf, 4);
853}
854
855static int eeprom_readKey(struct adapter *adapter, u8 *key, u32 len)
856{
857 u8 buf[20];
858
859 if (len != 16)
860 return 0;
861
862 if (eeprom_lrc_read(adapter, 0x3e4, 20, buf, 4) == 0)
863 return 0;
864
865 memcpy(key, buf, len);
866
867 return 1;
868}
869*/
870
871static int eeprom_get_mac_addr(struct adapter *adapter, char type, u8 *mac)
872{
873 u8 tmp[8];
874
875 if (eeprom_lrc_read(adapter, 0x3f8, 8, tmp, 4) != 0) {
876 if (type != 0) {
877 mac[0] = tmp[0];
878 mac[1] = tmp[1];
879 mac[2] = tmp[2];
880 mac[3] = 0xfe;
881 mac[4] = 0xff;
882 mac[5] = tmp[3];
883 mac[6] = tmp[4];
884 mac[7] = tmp[5];
885
886 } else {
887
888 mac[0] = tmp[0];
889 mac[1] = tmp[1];
890 mac[2] = tmp[2];
891 mac[3] = tmp[3];
892 mac[4] = tmp[4];
893 mac[5] = tmp[5];
894 }
895
896 return 1;
897
898 } else {
899
900 if (type == 0) {
901 memset(mac, 0, 6);
902
903 } else {
904
905 memset(mac, 0, 8);
906 }
907
908 return 0;
909 }
910}
911
912/*
913static char eeprom_set_mac_addr(struct adapter *adapter, char type, u8 *mac)
914{
915 u8 tmp[8];
916
917 if (type != 0) {
918 tmp[0] = mac[0];
919 tmp[1] = mac[1];
920 tmp[2] = mac[2];
921 tmp[3] = mac[5];
922 tmp[4] = mac[6];
923 tmp[5] = mac[7];
924
925 } else {
926
927 tmp[0] = mac[0];
928 tmp[1] = mac[1];
929 tmp[2] = mac[2];
930 tmp[3] = mac[3];
931 tmp[4] = mac[4];
932 tmp[5] = mac[5];
933 }
934
935 tmp[6] = 0;
936 tmp[7] = calc_lrc(tmp, 7);
937
938 if (eeprom_write(adapter, 0x3f8, tmp, 8) == 8)
939 return 1;
940
941 return 0;
942}
943*/
944
945/* PID filter */
946
947/* every flexcop has 6 "lower" hw PID filters */
948/* these are enabled by setting bits 0-5 of 0x208 */
949/* for the 32 additional filters we have to select one */
950/* of them through 0x310 and modify through 0x314 */
951/* op: 0=disable, 1=enable */
952static void filter_enable_hw_filter(struct adapter *adapter, int id, u8 op)
953{
954 dprintk("%s: id=%d op=%d\n", __FUNCTION__, id, op);
955 if (id <= 5) {
956 u32 mask = (0x00000001 << id);
957 write_reg_bitfield(adapter, 0x208, mask, op ? mask : 0);
958 } else {
959 /* select */
960 write_reg_bitfield(adapter, 0x310, 0x1f, (id - 6) & 0x1f);
961 /* modify */
962 write_reg_bitfield(adapter, 0x314, 0x00006000, op ? 0x00004000 : 0);
963 }
964}
965
966/* this sets the PID that should pass the specified filter */
967static void pid_set_hw_pid(struct adapter *adapter, int id, u16 pid)
968{
969 dprintk("%s: id=%d pid=%d\n", __FUNCTION__, id, pid);
970 if (id <= 5) {
971 u32 adr = 0x300 + ((id & 6) << 1);
972 int shift = (id & 1) ? 16 : 0;
973 dprintk("%s: id=%d addr=%x %c pid=%d\n", __FUNCTION__, id, adr, (id & 1) ? 'h' : 'l', pid);
974 write_reg_bitfield(adapter, adr, (0x7fff) << shift, (pid & 0x1fff) << shift);
975 } else {
976 /* select */
977 write_reg_bitfield(adapter, 0x310, 0x1f, (id - 6) & 0x1f);
978 /* modify */
979 write_reg_bitfield(adapter, 0x314, 0x1fff, pid & 0x1fff);
980 }
981}
982
983
984/*
985static void filter_enable_null_filter(struct adapter *adapter, u32 op)
986{
987 dprintk("%s: op=%x\n", __FUNCTION__, op);
988
989 write_reg_bitfield(adapter, 0x208, 0x00000040, op?0x00000040:0);
990}
991*/
992
993static void filter_enable_mask_filter(struct adapter *adapter, u32 op)
994{
995 dprintk("%s: op=%x\n", __FUNCTION__, op);
996
997 write_reg_bitfield(adapter, 0x208, 0x00000080, op ? 0x00000080 : 0);
998}
999
1000
1001static void ctrl_enable_mac(struct adapter *adapter, u32 op)
1002{
1003 write_reg_bitfield(adapter, 0x208, 0x00004000, op ? 0x00004000 : 0);
1004}
1005
1006static int ca_set_mac_dst_addr_filter(struct adapter *adapter, u8 *mac)
1007{
1008 u32 tmp1, tmp2;
1009
1010 tmp1 = (mac[3] << 0x18) | (mac[2] << 0x10) | (mac[1] << 0x08) | mac[0];
1011 tmp2 = (mac[5] << 0x08) | mac[4];
1012
1013 write_reg_dw(adapter, 0x418, tmp1);
1014 write_reg_dw(adapter, 0x41c, tmp2);
1015
1016 return 0;
1017}
1018
1019/*
1020static void set_ignore_mac_filter(struct adapter *adapter, u8 op)
1021{
1022 if (op != 0) {
1023 write_reg_bitfield(adapter, 0x208, 0x00004000, 0);
1024 adapter->mac_filter = 1;
1025 } else {
1026 if (adapter->mac_filter != 0) {
1027 adapter->mac_filter = 0;
1028 write_reg_bitfield(adapter, 0x208, 0x00004000, 0x00004000);
1029 }
1030 }
1031}
1032*/
1033
1034/*
1035static void check_null_filter_enable(struct adapter *adapter)
1036{
1037 filter_enable_null_filter(adapter, 1);
1038 filter_enable_mask_filter(adapter, 1);
1039}
1040*/
1041
1042static void pid_set_group_pid(struct adapter *adapter, u16 pid)
1043{
1044 u32 value;
1045
1046 dprintk("%s: pid=%x\n", __FUNCTION__, pid);
1047 value = (pid & 0x3fff) | (read_reg_dw(adapter, 0x30c) & 0xffff0000);
1048 write_reg_dw(adapter, 0x30c, value);
1049}
1050
1051static void pid_set_group_mask(struct adapter *adapter, u16 pid)
1052{
1053 u32 value;
1054
1055 dprintk("%s: pid=%x\n", __FUNCTION__, pid);
1056 value = ((pid & 0x3fff) << 0x10) | (read_reg_dw(adapter, 0x30c) & 0xffff);
1057 write_reg_dw(adapter, 0x30c, value);
1058}
1059
1060/*
1061static int pid_get_group_pid(struct adapter *adapter)
1062{
1063 return read_reg_dw(adapter, 0x30c) & 0x00001fff;
1064}
1065
1066static int pid_get_group_mask(struct adapter *adapter)
1067{
1068 return (read_reg_dw(adapter, 0x30c) >> 0x10)& 0x00001fff;
1069}
1070*/
1071
1072/*
1073static void reset_hardware_pid_filter(struct adapter *adapter)
1074{
1075 pid_set_stream1_pid(adapter, 0x1fff);
1076
1077 pid_set_stream2_pid(adapter, 0x1fff);
1078 filter_enable_stream2_filter(adapter, 0);
1079
1080 pid_set_pcr_pid(adapter, 0x1fff);
1081 filter_enable_pcr_filter(adapter, 0);
1082
1083 pid_set_pmt_pid(adapter, 0x1fff);
1084 filter_enable_pmt_filter(adapter, 0);
1085
1086 pid_set_ecm_pid(adapter, 0x1fff);
1087 filter_enable_ecm_filter(adapter, 0);
1088
1089 pid_set_emm_pid(adapter, 0x1fff);
1090 filter_enable_emm_filter(adapter, 0);
1091}
1092*/
1093
1094static void init_pids(struct adapter *adapter)
1095{
1096 int i;
1097
1098 adapter->pid_count = 0;
1099 adapter->whole_bandwidth_count = 0;
1100 for (i = 0; i < adapter->useable_hw_filters; i++) {
1101 dprintk("%s: setting filter %d to 0x1fff\n", __FUNCTION__, i);
1102 adapter->hw_pids[i] = 0x1fff;
1103 pid_set_hw_pid(adapter, i, 0x1fff);
1104}
1105
1106 pid_set_group_pid(adapter, 0);
1107 pid_set_group_mask(adapter, 0x1fe0);
1108}
1109
1110static void open_whole_bandwidth(struct adapter *adapter)
1111{
1112 dprintk("%s:\n", __FUNCTION__);
1113 pid_set_group_pid(adapter, 0);
1114 pid_set_group_mask(adapter, 0);
1115/*
1116 filter_enable_mask_filter(adapter, 1);
1117*/
1118}
1119
1120static void close_whole_bandwidth(struct adapter *adapter)
1121{
1122 dprintk("%s:\n", __FUNCTION__);
1123 pid_set_group_pid(adapter, 0);
1124 pid_set_group_mask(adapter, 0x1fe0);
1125/*
1126 filter_enable_mask_filter(adapter, 1);
1127*/
1128}
1129
1130static void whole_bandwidth_inc(struct adapter *adapter)
1131{
1132 if (adapter->whole_bandwidth_count++ == 0)
1133 open_whole_bandwidth(adapter);
1134}
1135
1136static void whole_bandwidth_dec(struct adapter *adapter)
1137{
1138 if (--adapter->whole_bandwidth_count <= 0)
1139 close_whole_bandwidth(adapter);
1140}
1141
1142/* The specified PID has to be let through the
1143 hw filters.
1144 We try to allocate an hardware filter and open whole
1145 bandwidth when allocation is impossible.
1146 All pids<=0x1f pass through the group filter.
1147 Returns 1 on success, -1 on error */
1148static int add_hw_pid(struct adapter *adapter, u16 pid)
1149{
1150 int i;
1151
1152 dprintk("%s: pid=%d\n", __FUNCTION__, pid);
1153
1154 if (pid <= 0x1f)
1155 return 1;
1156
1157 /* we can't use a filter for 0x2000, so no search */
1158 if (pid != 0x2000) {
1159 /* find an unused hardware filter */
1160 for (i = 0; i < adapter->useable_hw_filters; i++) {
1161 dprintk("%s: pid=%d searching slot=%d\n", __FUNCTION__, pid, i);
1162 if (adapter->hw_pids[i] == 0x1fff) {
1163 dprintk("%s: pid=%d slot=%d\n", __FUNCTION__, pid, i);
1164 adapter->hw_pids[i] = pid;
1165 pid_set_hw_pid(adapter, i, pid);
1166 filter_enable_hw_filter(adapter, i, 1);
1167 return 1;
1168 }
1169 }
1170 }
1171 /* if we have not used a filter, this pid depends on whole bandwidth */
1172 dprintk("%s: pid=%d whole_bandwidth\n", __FUNCTION__, pid);
1173 whole_bandwidth_inc(adapter);
1174 return 1;
1175 }
1176
1177/* returns -1 if the pid was not present in the filters */
1178static int remove_hw_pid(struct adapter *adapter, u16 pid)
1179{
1180 int i;
1181
1182 dprintk("%s: pid=%d\n", __FUNCTION__, pid);
1183
1184 if (pid <= 0x1f)
1185 return 1;
1186
1187 /* we can't use a filter for 0x2000, so no search */
1188 if (pid != 0x2000) {
1189 for (i = 0; i < adapter->useable_hw_filters; i++) {
1190 dprintk("%s: pid=%d searching slot=%d\n", __FUNCTION__, pid, i);
1191 if (adapter->hw_pids[i] == pid) { // find the pid slot
1192 dprintk("%s: pid=%d slot=%d\n", __FUNCTION__, pid, i);
1193 adapter->hw_pids[i] = 0x1fff;
1194 pid_set_hw_pid(adapter, i, 0x1fff);
1195 filter_enable_hw_filter(adapter, i, 0);
1196 return 1;
1197 }
1198 }
1199 }
1200 /* if we have not used a filter, this pid depended on whole bandwith */
1201 dprintk("%s: pid=%d whole_bandwidth\n", __FUNCTION__, pid);
1202 whole_bandwidth_dec(adapter);
1203 return 1;
1204 }
1205
1206/* Adds a PID to the filters.
1207 Adding a pid more than once is possible, we keep reference counts.
1208 Whole stream available through pid==0x2000.
1209 Returns 1 on success, -1 on error */
1210static int add_pid(struct adapter *adapter, u16 pid)
1211{
1212 int i;
1213
1214 dprintk("%s: pid=%d\n", __FUNCTION__, pid);
1215
1216 if (pid > 0x1ffe && pid != 0x2000)
1217 return -1;
1218
1219 // check if the pid is already present
1220 for (i = 0; i < adapter->pid_count; i++)
1221 if (adapter->pid_list[i] == pid) {
1222 adapter->pid_rc[i]++; // increment ref counter
1223 return 1;
1224 }
1225
1226 if (adapter->pid_count == N_PID_SLOTS)
1227 return -1; // no more pids can be added
1228 adapter->pid_list[adapter->pid_count] = pid; // register pid
1229 adapter->pid_rc[adapter->pid_count] = 1;
1230 adapter->pid_count++;
1231 // hardware setting
1232 add_hw_pid(adapter, pid);
1233
1234 return 1;
1235 }
1236
1237/* Removes a PID from the filters. */
1238static int remove_pid(struct adapter *adapter, u16 pid)
1239{
1240 int i;
1241
1242 dprintk("%s: pid=%d\n", __FUNCTION__, pid);
1243
1244 if (pid > 0x1ffe && pid != 0x2000)
1245 return -1;
1246
1247 // check if the pid is present (it must be!)
1248 for (i = 0; i < adapter->pid_count; i++) {
1249 if (adapter->pid_list[i] == pid) {
1250 adapter->pid_rc[i]--;
1251 if (adapter->pid_rc[i] <= 0) {
1252 // remove from the list
1253 adapter->pid_count--;
1254 adapter->pid_list[i]=adapter->pid_list[adapter->pid_count];
1255 adapter->pid_rc[i] = adapter->pid_rc[adapter->pid_count];
1256 // hardware setting
1257 remove_hw_pid(adapter, pid);
1258 }
1259 return 1;
1260 }
1261 }
1262
1263 return -1;
1264}
1265
1266
1267/* dma & irq */
1268static void ctrl_enable_smc(struct adapter *adapter, u32 op)
1269{
1270 write_reg_bitfield(adapter, 0x208, 0x00000800, op ? 0x00000800 : 0);
1271}
1272
1273static void dma_enable_disable_irq(struct adapter *adapter, u32 flag1, u32 flag2, u32 flag3)
1274{
1275 adapter->dma_ctrl = adapter->dma_ctrl & 0x000f0000;
1276
1277 if (flag1 == 0) {
1278 if (flag2 == 0)
1279 adapter->dma_ctrl = adapter->dma_ctrl & ~0x00010000;
1280 else
1281 adapter->dma_ctrl = adapter->dma_ctrl | 0x00010000;
1282
1283 if (flag3 == 0)
1284 adapter->dma_ctrl = adapter->dma_ctrl & ~0x00020000;
1285 else
1286 adapter->dma_ctrl = adapter->dma_ctrl | 0x00020000;
1287
1288 } else {
1289
1290 if (flag2 == 0)
1291 adapter->dma_ctrl = adapter->dma_ctrl & ~0x00040000;
1292 else
1293 adapter->dma_ctrl = adapter->dma_ctrl | 0x00040000;
1294
1295 if (flag3 == 0)
1296 adapter->dma_ctrl = adapter->dma_ctrl & ~0x00080000;
1297 else
1298 adapter->dma_ctrl = adapter->dma_ctrl | 0x00080000;
1299 }
1300}
1301
1302static void irq_dma_enable_disable_irq(struct adapter *adapter, u32 op)
1303{
1304 u32 value;
1305
1306 value = read_reg_dw(adapter, 0x208) & 0xfff0ffff;
1307
1308 if (op != 0)
1309 value = value | (adapter->dma_ctrl & 0x000f0000);
1310
1311 write_reg_dw(adapter, 0x208, value);
1312}
1313
1314/* FlexCopII has 2 dma channels. DMA1 is used to transfer TS data to
1315 system memory.
1316
1317 The DMA1 buffer is divided in 2 subbuffers of equal size.
1318 FlexCopII will transfer TS data to one subbuffer, signal an interrupt
1319 when the subbuffer is full and continue fillig the second subbuffer.
1320
1321 For DMA1:
1322 subbuffer size in 32-bit words is stored in the first 24 bits of
1323 register 0x004. The last 8 bits of register 0x004 contain the number
1324 of subbuffers.
1325
1326 the first 30 bits of register 0x000 contain the address of the first
1327 subbuffer. The last 2 bits contain 0, when dma1 is disabled and 1,
1328 when dma1 is enabled.
1329
1330 the first 30 bits of register 0x00c contain the address of the second
1331 subbuffer. the last 2 bits contain 1.
1332
1333 register 0x008 will contain the address of the subbuffer that was filled
1334 with TS data, when FlexCopII will generate an interrupt.
1335
1336 For DMA2:
1337 subbuffer size in 32-bit words is stored in the first 24 bits of
1338 register 0x014. The last 8 bits of register 0x014 contain the number
1339 of subbuffers.
1340
1341 the first 30 bits of register 0x010 contain the address of the first
1342 subbuffer. The last 2 bits contain 0, when dma1 is disabled and 1,
1343 when dma1 is enabled.
1344
1345 the first 30 bits of register 0x01c contain the address of the second
1346 subbuffer. the last 2 bits contain 1.
1347
1348 register 0x018 contains the address of the subbuffer that was filled
1349 with TS data, when FlexCopII generates an interrupt.
1350*/
1351static int dma_init_dma(struct adapter *adapter, u32 dma_channel)
1352{
1353 u32 subbuffers, subbufsize, subbuf0, subbuf1;
1354
1355 if (dma_channel == 0) {
1356 dprintk("%s: Initializing DMA1 channel\n", __FUNCTION__);
1357
1358 subbuffers = 2;
1359
1360 subbufsize = (((adapter->dmaq1.buffer_size / 2) / 4) << 8) | subbuffers;
1361
1362 subbuf0 = adapter->dmaq1.bus_addr & 0xfffffffc;
1363
1364 subbuf1 = ((adapter->dmaq1.bus_addr + adapter->dmaq1.buffer_size / 2) & 0xfffffffc) | 1;
1365
1366 dprintk("%s: first subbuffer address = 0x%x\n", __FUNCTION__, subbuf0);
1367 udelay(1000);
1368 write_reg_dw(adapter, 0x000, subbuf0);
1369
1370 dprintk("%s: subbuffer size = 0x%x\n", __FUNCTION__, (subbufsize >> 8) * 4);
1371 udelay(1000);
1372 write_reg_dw(adapter, 0x004, subbufsize);
1373
1374 dprintk("%s: second subbuffer address = 0x%x\n", __FUNCTION__, subbuf1);
1375 udelay(1000);
1376 write_reg_dw(adapter, 0x00c, subbuf1);
1377
1378 dprintk("%s: counter = 0x%x\n", __FUNCTION__, adapter->dmaq1.bus_addr & 0xfffffffc);
1379 write_reg_dw(adapter, 0x008, adapter->dmaq1.bus_addr & 0xfffffffc);
1380 udelay(1000);
1381
1382 dma_enable_disable_irq(adapter, 0, 1, subbuffers ? 1 : 0);
1383
1384 irq_dma_enable_disable_irq(adapter, 1);
1385
1386 sram_set_media_dest(adapter, 1);
1387 sram_set_net_dest(adapter, 1);
1388 sram_set_cai_dest(adapter, 2);
1389 sram_set_cao_dest(adapter, 2);
1390 }
1391
1392 if (dma_channel == 1) {
1393 dprintk("%s: Initializing DMA2 channel\n", __FUNCTION__);
1394
1395 subbuffers = 2;
1396
1397 subbufsize = (((adapter->dmaq2.buffer_size / 2) / 4) << 8) | subbuffers;
1398
1399 subbuf0 = adapter->dmaq2.bus_addr & 0xfffffffc;
1400
1401 subbuf1 = ((adapter->dmaq2.bus_addr + adapter->dmaq2.buffer_size / 2) & 0xfffffffc) | 1;
1402
1403 dprintk("%s: first subbuffer address = 0x%x\n", __FUNCTION__, subbuf0);
1404 udelay(1000);
1405 write_reg_dw(adapter, 0x010, subbuf0);
1406
1407 dprintk("%s: subbuffer size = 0x%x\n", __FUNCTION__, (subbufsize >> 8) * 4);
1408 udelay(1000);
1409 write_reg_dw(adapter, 0x014, subbufsize);
1410
1411 dprintk("%s: second buffer address = 0x%x\n", __FUNCTION__, subbuf1);
1412 udelay(1000);
1413 write_reg_dw(adapter, 0x01c, subbuf1);
1414
1415 sram_set_cai_dest(adapter, 2);
1416 }
1417
1418 return 0;
1419}
1420
1421static void ctrl_enable_receive_data(struct adapter *adapter, u32 op)
1422{
1423 if (op == 0) {
1424 write_reg_bitfield(adapter, 0x208, 0x00008000, 0);
1425 adapter->dma_status = adapter->dma_status & ~0x00000004;
1426 } else {
1427 write_reg_bitfield(adapter, 0x208, 0x00008000, 0x00008000);
1428 adapter->dma_status = adapter->dma_status | 0x00000004;
1429 }
1430}
1431
1432/* bit 0 of dma_mask is set to 1 if dma1 channel has to be enabled/disabled
1433 bit 1 of dma_mask is set to 1 if dma2 channel has to be enabled/disabled
1434*/
1435static void dma_start_stop(struct adapter *adapter, u32 dma_mask, int start_stop)
1436{
1437 u32 dma_enable, dma1_enable, dma2_enable;
1438
1439 dprintk("%s: dma_mask=%x\n", __FUNCTION__, dma_mask);
1440
1441 if (start_stop == 1) {
1442 dprintk("%s: starting dma\n", __FUNCTION__);
1443
1444 dma1_enable = 0;
1445 dma2_enable = 0;
1446
1447 if (((dma_mask & 1) != 0) && ((adapter->dma_status & 1) == 0) && (adapter->dmaq1.bus_addr != 0)) {
1448 adapter->dma_status = adapter->dma_status | 1;
1449 dma1_enable = 1;
1450 }
1451
1452 if (((dma_mask & 2) != 0) && ((adapter->dma_status & 2) == 0) && (adapter->dmaq2.bus_addr != 0)) {
1453 adapter->dma_status = adapter->dma_status | 2;
1454 dma2_enable = 1;
1455 }
1456 // enable dma1 and dma2
1457 if ((dma1_enable == 1) && (dma2_enable == 1)) {
1458 write_reg_dw(adapter, 0x000, adapter->dmaq1.bus_addr | 1);
1459 write_reg_dw(adapter, 0x00c, (adapter->dmaq1.bus_addr + adapter->dmaq1.buffer_size / 2) | 1);
1460 write_reg_dw(adapter, 0x010, adapter->dmaq2.bus_addr | 1);
1461
1462 ctrl_enable_receive_data(adapter, 1);
1463
1464 return;
1465 }
1466 // enable dma1
1467 if ((dma1_enable == 1) && (dma2_enable == 0)) {
1468 write_reg_dw(adapter, 0x000, adapter->dmaq1.bus_addr | 1);
1469 write_reg_dw(adapter, 0x00c, (adapter->dmaq1.bus_addr + adapter->dmaq1.buffer_size / 2) | 1);
1470
1471 ctrl_enable_receive_data(adapter, 1);
1472
1473 return;
1474 }
1475 // enable dma2
1476 if ((dma1_enable == 0) && (dma2_enable == 1)) {
1477 write_reg_dw(adapter, 0x010, adapter->dmaq2.bus_addr | 1);
1478
1479 ctrl_enable_receive_data(adapter, 1);
1480
1481 return;
1482 }
1483 // start dma
1484 if ((dma1_enable == 0) && (dma2_enable == 0)) {
1485 ctrl_enable_receive_data(adapter, 1);
1486
1487 return;
1488 }
1489
1490 } else {
1491
1492 dprintk("%s: stopping dma\n", __FUNCTION__);
1493
1494 dma_enable = adapter->dma_status & 0x00000003;
1495
1496 if (((dma_mask & 1) != 0) && ((adapter->dma_status & 1) != 0)) {
1497 dma_enable = dma_enable & 0xfffffffe;
1498 }
1499
1500 if (((dma_mask & 2) != 0) && ((adapter->dma_status & 2) != 0)) {
1501 dma_enable = dma_enable & 0xfffffffd;
1502 }
1503 //stop dma
1504 if ((dma_enable == 0) && ((adapter->dma_status & 4) != 0)) {
1505 ctrl_enable_receive_data(adapter, 0);
1506
1507 udelay(3000);
1508 }
1509 //disable dma1
1510 if (((dma_mask & 1) != 0) && ((adapter->dma_status & 1) != 0) && (adapter->dmaq1.bus_addr != 0)) {
1511 write_reg_dw(adapter, 0x000, adapter->dmaq1.bus_addr);
1512 write_reg_dw(adapter, 0x00c, (adapter->dmaq1.bus_addr + adapter->dmaq1.buffer_size / 2) | 1);
1513
1514 adapter->dma_status = adapter->dma_status & ~0x00000001;
1515 }
1516 //disable dma2
1517 if (((dma_mask & 2) != 0) && ((adapter->dma_status & 2) != 0) && (adapter->dmaq2.bus_addr != 0)) {
1518 write_reg_dw(adapter, 0x010, adapter->dmaq2.bus_addr);
1519
1520 adapter->dma_status = adapter->dma_status & ~0x00000002;
1521 }
1522 }
1523}
1524
1525static void open_stream(struct adapter *adapter, u16 pid)
1526{
1527 u32 dma_mask;
1528
1529 ++adapter->capturing;
1530
1531 filter_enable_mask_filter(adapter, 1);
1532
1533 add_pid(adapter, pid);
1534
1535 dprintk("%s: adapter->dma_status=%x\n", __FUNCTION__, adapter->dma_status);
1536
1537 if ((adapter->dma_status & 7) != 7) {
1538 dma_mask = 0;
1539
1540 if (((adapter->dma_status & 0x10000000) != 0) && ((adapter->dma_status & 1) == 0)) {
1541 dma_mask = dma_mask | 1;
1542
1543 adapter->dmaq1.head = 0;
1544 adapter->dmaq1.tail = 0;
1545
1546 memset(adapter->dmaq1.buffer, 0, adapter->dmaq1.buffer_size);
1547 }
1548
1549 if (((adapter->dma_status & 0x20000000) != 0) && ((adapter->dma_status & 2) == 0)) {
1550 dma_mask = dma_mask | 2;
1551
1552 adapter->dmaq2.head = 0;
1553 adapter->dmaq2.tail = 0;
1554 }
1555
1556 if (dma_mask != 0) {
1557 irq_dma_enable_disable_irq(adapter, 1);
1558
1559 dma_start_stop(adapter, dma_mask, 1);
1560 }
1561 }
1562}
1563
1564static void close_stream(struct adapter *adapter, u16 pid)
1565{
1566 if (adapter->capturing > 0)
1567 --adapter->capturing;
1568
1569 dprintk("%s: dma_status=%x\n", __FUNCTION__, adapter->dma_status);
1570
1571 if (adapter->capturing == 0) {
1572 u32 dma_mask = 0;
1573
1574 if ((adapter->dma_status & 1) != 0)
1575 dma_mask = dma_mask | 0x00000001;
1576 if ((adapter->dma_status & 2) != 0)
1577 dma_mask = dma_mask | 0x00000002;
1578
1579 if (dma_mask != 0) {
1580 dma_start_stop(adapter, dma_mask, 0);
1581 }
1582 }
1583 remove_pid(adapter, pid);
1584}
1585
1586static void interrupt_service_dma1(struct adapter *adapter)
1587{
1588 struct dvb_demux *dvbdmx = &adapter->demux;
1589
1590 int n_cur_dma_counter;
1591 u32 n_num_bytes_parsed;
1592 u32 n_num_new_bytes_transferred;
1593 u32 dw_default_packet_size = 188;
1594 u8 gb_tmp_buffer[188];
1595 u8 *pb_dma_buf_cur_pos;
1596
1597 n_cur_dma_counter = readl(adapter->io_mem + 0x008) - adapter->dmaq1.bus_addr;
1598 n_cur_dma_counter = (n_cur_dma_counter / dw_default_packet_size) * dw_default_packet_size;
1599
1600 if ((n_cur_dma_counter < 0) || (n_cur_dma_counter > adapter->dmaq1.buffer_size)) {
1601 dprintk("%s: dma counter outside dma buffer\n", __FUNCTION__);
1602 return;
1603 }
1604
1605 adapter->dmaq1.head = n_cur_dma_counter;
1606
1607 if (adapter->dmaq1.tail <= n_cur_dma_counter) {
1608 n_num_new_bytes_transferred = n_cur_dma_counter - adapter->dmaq1.tail;
1609
1610 } else {
1611
1612 n_num_new_bytes_transferred = (adapter->dmaq1.buffer_size - adapter->dmaq1.tail) + n_cur_dma_counter;
1613 }
1614
1615 ddprintk("%s: n_cur_dma_counter = %d\n", __FUNCTION__, n_cur_dma_counter);
1616 ddprintk("%s: dmaq1.tail = %d\n", __FUNCTION__, adapter->dmaq1.tail);
1617 ddprintk("%s: bytes_transferred = %d\n", __FUNCTION__, n_num_new_bytes_transferred);
1618
1619 if (n_num_new_bytes_transferred < dw_default_packet_size)
1620 return;
1621
1622 n_num_bytes_parsed = 0;
1623
1624 while (n_num_bytes_parsed < n_num_new_bytes_transferred) {
1625 pb_dma_buf_cur_pos = adapter->dmaq1.buffer + adapter->dmaq1.tail;
1626
1627 if (adapter->dmaq1.buffer + adapter->dmaq1.buffer_size < adapter->dmaq1.buffer + adapter->dmaq1.tail + 188) {
1628 memcpy(gb_tmp_buffer, adapter->dmaq1.buffer + adapter->dmaq1.tail,
1629 adapter->dmaq1.buffer_size - adapter->dmaq1.tail);
1630 memcpy(gb_tmp_buffer + (adapter->dmaq1.buffer_size - adapter->dmaq1.tail), adapter->dmaq1.buffer,
1631 (188 - (adapter->dmaq1.buffer_size - adapter->dmaq1.tail)));
1632
1633 pb_dma_buf_cur_pos = gb_tmp_buffer;
1634 }
1635
1636 if (adapter->capturing != 0) {
1637 dvb_dmx_swfilter_packets(dvbdmx, pb_dma_buf_cur_pos, dw_default_packet_size / 188);
1638 }
1639
1640 n_num_bytes_parsed = n_num_bytes_parsed + dw_default_packet_size;
1641
1642 adapter->dmaq1.tail = adapter->dmaq1.tail + dw_default_packet_size;
1643
1644 if (adapter->dmaq1.tail >= adapter->dmaq1.buffer_size)
1645 adapter->dmaq1.tail = adapter->dmaq1.tail - adapter->dmaq1.buffer_size;
1646 };
1647}
1648
1649static void interrupt_service_dma2(struct adapter *adapter)
1650{
1651 printk("%s:\n", __FUNCTION__);
1652}
1653
1654static irqreturn_t isr(int irq, void *dev_id, struct pt_regs *regs)
1655{
1656 struct adapter *tmp = dev_id;
1657
1658 u32 value;
1659
1660 ddprintk("%s:\n", __FUNCTION__);
1661
1662 spin_lock_irq(&tmp->lock);
1663
1664 if (0 == ((value = read_reg_dw(tmp, 0x20c)) & 0x0f)) {
1665 spin_unlock_irq(&tmp->lock);
1666 return IRQ_NONE;
1667 }
1668
1669 while (value != 0) {
1670 if ((value & 0x03) != 0)
1671 interrupt_service_dma1(tmp);
1672 if ((value & 0x0c) != 0)
1673 interrupt_service_dma2(tmp);
1674 value = read_reg_dw(tmp, 0x20c) & 0x0f;
1675 }
1676
1677 spin_unlock_irq(&tmp->lock);
1678 return IRQ_HANDLED;
1679}
1680
1681static int init_dma_queue_one(struct adapter *adapter, struct dmaq *dmaq,
1682 int size, int dmaq_offset)
1683{
1684 struct pci_dev *pdev = adapter->pdev;
1685 dma_addr_t dma_addr;
1686
1687 dmaq->head = 0;
1688 dmaq->tail = 0;
1689
1690 dmaq->buffer = pci_alloc_consistent(pdev, size + 0x80, &dma_addr);
1691 if (!dmaq->buffer)
1692 return -ENOMEM;
1693
1694 dmaq->bus_addr = dma_addr;
1695 dmaq->buffer_size = size;
1696
1697 dma_init_dma(adapter, dmaq_offset);
1698
1699 ddprintk("%s: allocated dma buffer at 0x%p, length=%d\n",
1700 __FUNCTION__, dmaq->buffer, size);
1701
1702 return 0;
1703 }
1704
1705static int init_dma_queue(struct adapter *adapter)
1706{
1707 struct {
1708 struct dmaq *dmaq;
1709 u32 dma_status;
1710 int size;
1711 } dmaq_desc[] = {
1712 { &adapter->dmaq1, 0x10000000, SIZE_OF_BUF_DMA1 },
1713 { &adapter->dmaq2, 0x20000000, SIZE_OF_BUF_DMA2 }
1714 }, *p = dmaq_desc;
1715 int i;
1716
1717 for (i = 0; i < 2; i++, p++) {
1718 if (init_dma_queue_one(adapter, p->dmaq, p->size, i) < 0)
1719 adapter->dma_status &= ~p->dma_status;
1720 else
1721 adapter->dma_status |= p->dma_status;
1722 }
1723 return (adapter->dma_status & 0x30000000) ? 0 : -ENOMEM;
1724}
1725
1726static void free_dma_queue_one(struct adapter *adapter, struct dmaq *dmaq)
1727{
1728 if (dmaq->buffer) {
1729 pci_free_consistent(adapter->pdev, dmaq->buffer_size + 0x80,
1730 dmaq->buffer, dmaq->bus_addr);
1731 memset(dmaq, 0, sizeof(*dmaq));
1732 }
1733}
1734
1735static void free_dma_queue(struct adapter *adapter)
1736{
1737 struct dmaq *dmaq[] = {
1738 &adapter->dmaq1,
1739 &adapter->dmaq2,
1740 NULL
1741 }, **p;
1742
1743 for (p = dmaq; *p; p++)
1744 free_dma_queue_one(adapter, *p);
1745 }
1746
1747static void release_adapter(struct adapter *adapter)
1748{
1749 struct pci_dev *pdev = adapter->pdev;
1750
1751 iounmap(adapter->io_mem);
1752 pci_disable_device(pdev);
1753 pci_release_region(pdev, 0);
1754 pci_release_region(pdev, 1);
1755}
1756
1757static void free_adapter_object(struct adapter *adapter)
1758{
1759 dprintk("%s:\n", __FUNCTION__);
1760
1761 close_stream(adapter, 0);
1762 free_irq(adapter->irq, adapter);
1763 free_dma_queue(adapter);
1764 release_adapter(adapter);
1765 kfree(adapter);
1766}
1767
1768static struct pci_driver skystar2_pci_driver;
1769
1770static int claim_adapter(struct adapter *adapter)
1771{
1772 struct pci_dev *pdev = adapter->pdev;
1773 u16 var;
1774 int ret;
1775
1776 ret = pci_request_region(pdev, 1, skystar2_pci_driver.name);
1777 if (ret < 0)
1778 goto out;
1779
1780 ret = pci_request_region(pdev, 0, skystar2_pci_driver.name);
1781 if (ret < 0)
1782 goto err_pci_release_1;
1783
1784 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &adapter->card_revision);
1785
1786 dprintk("%s: card revision %x \n", __FUNCTION__, adapter->card_revision);
1787
1788 ret = pci_enable_device(pdev);
1789 if (ret < 0)
1790 goto err_pci_release_0;
1791
1792 pci_read_config_word(pdev, 4, &var);
1793
1794 if ((var & 4) == 0)
1795 pci_set_master(pdev);
1796
1797 adapter->io_port = pdev->resource[1].start;
1798
1799 adapter->io_mem = ioremap(pdev->resource[0].start, 0x800);
1800
1801 if (!adapter->io_mem) {
1802 dprintk("%s: can not map io memory\n", __FUNCTION__);
1803 ret = -EIO;
1804 goto err_pci_disable;
1805 }
1806
1807 dprintk("%s: io memory maped at %p\n", __FUNCTION__, adapter->io_mem);
1808
1809 ret = 1;
1810out:
1811 return ret;
1812
1813err_pci_disable:
1814 pci_disable_device(pdev);
1815err_pci_release_0:
1816 pci_release_region(pdev, 0);
1817err_pci_release_1:
1818 pci_release_region(pdev, 1);
1819 goto out;
1820}
1821
1822/*
1823static int sll_reset_flexcop(struct adapter *adapter)
1824{
1825 write_reg_dw(adapter, 0x208, 0);
1826 write_reg_dw(adapter, 0x210, 0xb2ff);
1827
1828 return 0;
1829}
1830*/
1831
1832static void decide_how_many_hw_filters(struct adapter *adapter)
1833{
1834 int hw_filters;
1835 int mod_option_hw_filters;
1836
1837 // FlexCop IIb & III have 6+32 hw filters
1838 // FlexCop II has 6 hw filters, every other should have at least 6
1839 switch (adapter->b2c2_revision) {
1840 case 0x82: /* II */
1841 hw_filters = 6;
1842 break;
1843 case 0xc3: /* IIB */
1844 hw_filters = 6 + 32;
1845 break;
1846 case 0xc0: /* III */
1847 hw_filters = 6 + 32;
1848 break;
1849 default:
1850 hw_filters = 6;
1851 break;
1852 }
1853 printk("%s: the chip has %i hardware filters", __FILE__, hw_filters);
1854
1855 mod_option_hw_filters = 0;
1856 if (enable_hw_filters >= 1)
1857 mod_option_hw_filters += 6;
1858 if (enable_hw_filters >= 2)
1859 mod_option_hw_filters += 32;
1860
1861 if (mod_option_hw_filters >= hw_filters) {
1862 adapter->useable_hw_filters = hw_filters;
1863 } else {
1864 adapter->useable_hw_filters = mod_option_hw_filters;
1865 printk(", but only %d will be used because of module option", mod_option_hw_filters);
1866 }
1867 printk("\n");
1868 dprintk("%s: useable_hardware_filters set to %i\n", __FILE__, adapter->useable_hw_filters);
1869}
1870
1871static int driver_initialize(struct pci_dev *pdev)
1872{
1873 struct adapter *adapter;
1874 u32 tmp;
1875 int ret = -ENOMEM;
1876
1877 adapter = kmalloc(sizeof(struct adapter), GFP_KERNEL);
1878 if (!adapter) {
1879 dprintk("%s: out of memory!\n", __FUNCTION__);
1880 goto out;
1881 }
1882
1883 memset(adapter, 0, sizeof(struct adapter));
1884
1885 pci_set_drvdata(pdev,adapter);
1886
1887 adapter->pdev = pdev;
1888 adapter->irq = pdev->irq;
1889
1890 ret = claim_adapter(adapter);
1891 if (ret < 0)
1892 goto err_kfree;
1893
1894 irq_dma_enable_disable_irq(adapter, 0);
1895
1896 ret = request_irq(pdev->irq, isr, 0x4000000, "Skystar2", adapter);
1897 if (ret < 0) {
1898 dprintk("%s: unable to allocate irq=%d !\n", __FUNCTION__, pdev->irq);
1899 goto err_release_adapter;
1900 }
1901
1902 read_reg_dw(adapter, 0x208);
1903 write_reg_dw(adapter, 0x208, 0);
1904 write_reg_dw(adapter, 0x210, 0xb2ff);
1905 write_reg_dw(adapter, 0x208, 0x40);
1906
1907 ret = init_dma_queue(adapter);
1908 if (ret < 0)
1909 goto err_free_irq;
1910
1911 adapter->b2c2_revision = (read_reg_dw(adapter, 0x204) >> 0x18);
1912
1913 switch (adapter->b2c2_revision) {
1914 case 0x82:
1915 printk("%s: FlexCopII(rev.130) chip found\n", __FILE__);
1916 break;
1917 case 0xc3:
1918 printk("%s: FlexCopIIB(rev.195) chip found\n", __FILE__);
1919 break;
1920 case 0xc0:
1921 printk("%s: FlexCopIII(rev.192) chip found\n", __FILE__);
1922 break;
1923 default:
1924 printk("%s: The revision of the FlexCop chip on your card is %d\n", __FILE__, adapter->b2c2_revision);
1925 printk("%s: This driver works only with FlexCopII(rev.130), FlexCopIIB(rev.195) and FlexCopIII(rev.192).\n", __FILE__);
1926 ret = -ENODEV;
1927 goto err_free_dma_queue;
1928 }
1929
1930 decide_how_many_hw_filters(adapter);
1931
1932 init_pids(adapter);
1933
1934 tmp = read_reg_dw(adapter, 0x204);
1935
1936 write_reg_dw(adapter, 0x204, 0);
1937 mdelay(20);
1938
1939 write_reg_dw(adapter, 0x204, tmp);
1940 mdelay(10);
1941
1942 tmp = read_reg_dw(adapter, 0x308);
1943 write_reg_dw(adapter, 0x308, 0x4000 | tmp);
1944
1945 adapter->dw_sram_type = 0x10000;
1946
1947 sll_detect_sram_size(adapter);
1948
1949 dprintk("%s sram length = %d, sram type= %x\n", __FUNCTION__, sram_length(adapter), adapter->dw_sram_type);
1950
1951 sram_set_media_dest(adapter, 1);
1952 sram_set_net_dest(adapter, 1);
1953
1954 ctrl_enable_smc(adapter, 0);
1955
1956 sram_set_cai_dest(adapter, 2);
1957 sram_set_cao_dest(adapter, 2);
1958
1959 dma_enable_disable_irq(adapter, 1, 0, 0);
1960
1961 if (eeprom_get_mac_addr(adapter, 0, adapter->mac_addr) != 0) {
1962 printk("%s MAC address = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x \n", __FUNCTION__, adapter->mac_addr[0],
1963 adapter->mac_addr[1], adapter->mac_addr[2], adapter->mac_addr[3], adapter->mac_addr[4], adapter->mac_addr[5],
1964 adapter->mac_addr[6], adapter->mac_addr[7]
1965 );
1966
1967 ca_set_mac_dst_addr_filter(adapter, adapter->mac_addr);
1968 ctrl_enable_mac(adapter, 1);
1969 }
1970
1971 spin_lock_init(&adapter->lock);
1972
1973out:
1974 return ret;
1975
1976err_free_dma_queue:
1977 free_dma_queue(adapter);
1978err_free_irq:
1979 free_irq(pdev->irq, adapter);
1980err_release_adapter:
1981 release_adapter(adapter);
1982err_kfree:
1983 pci_set_drvdata(pdev, NULL);
1984 kfree(adapter);
1985 goto out;
1986}
1987
1988static void driver_halt(struct pci_dev *pdev)
1989{
1990 struct adapter *adapter = pci_get_drvdata(pdev);
1991
1992 irq_dma_enable_disable_irq(adapter, 0);
1993
1994 ctrl_enable_receive_data(adapter, 0);
1995
1996 free_adapter_object(adapter);
1997
1998 pci_set_drvdata(pdev, NULL);
1999}
2000
2001static int dvb_start_feed(struct dvb_demux_feed *dvbdmxfeed)
2002{
2003 struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
2004 struct adapter *adapter = (struct adapter *) dvbdmx->priv;
2005
2006 dprintk("%s: PID=%d, type=%d\n", __FUNCTION__, dvbdmxfeed->pid, dvbdmxfeed->type);
2007
2008 open_stream(adapter, dvbdmxfeed->pid);
2009
2010 return 0;
2011}
2012
2013static int dvb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
2014{
2015 struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
2016 struct adapter *adapter = (struct adapter *) dvbdmx->priv;
2017
2018 dprintk("%s: PID=%d, type=%d\n", __FUNCTION__, dvbdmxfeed->pid, dvbdmxfeed->type);
2019
2020 close_stream(adapter, dvbdmxfeed->pid);
2021
2022 return 0;
2023}
2024
2025/* lnb control */
2026static void set_tuner_tone(struct adapter *adapter, u8 tone)
2027{
2028 u16 wz_half_period_for_45_mhz[] = { 0x01ff, 0x0154, 0x00ff, 0x00cc };
2029 u16 ax;
2030
2031 dprintk("%s: %u\n", __FUNCTION__, tone);
2032
2033 switch (tone) {
2034 case 1:
2035 ax = wz_half_period_for_45_mhz[0];
2036 break;
2037 case 2:
2038 ax = wz_half_period_for_45_mhz[1];
2039 break;
2040 case 3:
2041 ax = wz_half_period_for_45_mhz[2];
2042 break;
2043 case 4:
2044 ax = wz_half_period_for_45_mhz[3];
2045 break;
2046
2047 default:
2048 ax = 0;
2049 }
2050
2051 if (ax != 0) {
2052 write_reg_dw(adapter, 0x200, ((ax << 0x0f) + (ax & 0x7fff)) | 0x40000000);
2053
2054 } else {
2055
2056 write_reg_dw(adapter, 0x200, 0x40ff8000);
2057 }
2058}
2059
2060static void set_tuner_polarity(struct adapter *adapter, u8 polarity)
2061{
2062 u32 var;
2063
2064 dprintk("%s : polarity = %u \n", __FUNCTION__, polarity);
2065
2066 var = read_reg_dw(adapter, 0x204);
2067
2068 if (polarity == 0) {
2069 dprintk("%s: LNB power off\n", __FUNCTION__);
2070 var = var | 1;
2071 };
2072
2073 if (polarity == 1) {
2074 var = var & ~1;
2075 var = var & ~4;
2076 };
2077
2078 if (polarity == 2) {
2079 var = var & ~1;
2080 var = var | 4;
2081 }
2082
2083 write_reg_dw(adapter, 0x204, var);
2084}
2085
2086static void diseqc_send_bit(struct adapter *adapter, int data)
2087{
2088 set_tuner_tone(adapter, 1);
2089 udelay(data ? 500 : 1000);
2090 set_tuner_tone(adapter, 0);
2091 udelay(data ? 1000 : 500);
2092}
2093
2094
2095static void diseqc_send_byte(struct adapter *adapter, int data)
2096 {
2097 int i, par = 1, d;
2098
2099 for (i = 7; i >= 0; i--) {
2100 d = (data >> i) & 1;
2101 par ^= d;
2102 diseqc_send_bit(adapter, d);
2103 }
2104
2105 diseqc_send_bit(adapter, par);
2106 }
2107
2108
2109static int send_diseqc_msg(struct adapter *adapter, int len, u8 *msg, unsigned long burst)
2110{
2111 int i;
2112
2113 set_tuner_tone(adapter, 0);
2114 mdelay(16);
2115
2116 for (i = 0; i < len; i++)
2117 diseqc_send_byte(adapter, msg[i]);
2118
2119 mdelay(16);
2120
2121 if (burst != -1) {
2122 if (burst)
2123 diseqc_send_byte(adapter, 0xff);
2124 else {
2125 set_tuner_tone(adapter, 1);
2126 udelay(12500);
2127 set_tuner_tone(adapter, 0);
2128 }
2129 msleep(20);
2130 }
2131
2132 return 0;
2133}
2134
2135static int flexcop_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
2136{
2137 struct adapter* adapter = (struct adapter*) fe->dvb->priv;
2138
2139 switch(tone) {
2140 case SEC_TONE_ON:
2141 set_tuner_tone(adapter, 1);
2142 break;
2143 case SEC_TONE_OFF:
2144 set_tuner_tone(adapter, 0);
2145 break;
2146 default:
2147 return -EINVAL;
2148 };
2149
2150 return 0;
2151}
2152
2153static int flexcop_diseqc_send_master_cmd(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd)
2154 {
2155 struct adapter* adapter = (struct adapter*) fe->dvb->priv;
2156
2157 send_diseqc_msg(adapter, cmd->msg_len, cmd->msg, 0);
2158
2159 return 0;
2160 }
2161
2162static int flexcop_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd)
2163{
2164 struct adapter* adapter = (struct adapter*) fe->dvb->priv;
2165
2166 send_diseqc_msg(adapter, 0, NULL, minicmd);
2167
2168 return 0;
2169}
2170
2171static int flexcop_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
2172 {
2173 struct adapter* adapter = (struct adapter*) fe->dvb->priv;
2174
2175 dprintk("%s: FE_SET_VOLTAGE\n", __FUNCTION__);
2176
2177 switch (voltage) {
2178 case SEC_VOLTAGE_13:
2179 dprintk("%s: SEC_VOLTAGE_13, %x\n", __FUNCTION__, SEC_VOLTAGE_13);
2180 set_tuner_polarity(adapter, 1);
2181 return 0;
2182
2183 case SEC_VOLTAGE_18:
2184 dprintk("%s: SEC_VOLTAGE_18, %x\n", __FUNCTION__, SEC_VOLTAGE_18);
2185 set_tuner_polarity(adapter, 2);
2186 return 0;
2187
2188 default:
2189 return -EINVAL;
2190 }
2191 }
2192
2193static int flexcop_sleep(struct dvb_frontend* fe)
2194 {
2195 struct adapter* adapter = (struct adapter*) fe->dvb->priv;
2196
2197 dprintk("%s: FE_SLEEP\n", __FUNCTION__);
2198 set_tuner_polarity(adapter, 0);
2199
2200 if (adapter->fe_sleep) return adapter->fe_sleep(fe);
2201 return 0;
2202 }
2203
2204static u32 flexcop_i2c_func(struct i2c_adapter *adapter)
2205 {
2206 printk("flexcop_i2c_func\n");
2207
2208 return I2C_FUNC_I2C;
2209}
2210
2211static struct i2c_algorithm flexcop_algo = {
2212 .name = "flexcop i2c algorithm",
2213 .id = I2C_ALGO_BIT,
2214 .master_xfer = master_xfer,
2215 .functionality = flexcop_i2c_func,
2216};
2217
2218
2219
2220
2221static int samsung_tbmu24112_set_symbol_rate(struct dvb_frontend* fe, u32 srate, u32 ratio)
2222{
2223 u8 aclk = 0;
2224 u8 bclk = 0;
2225
2226 if (srate < 1500000) { aclk = 0xb7; bclk = 0x47; }
2227 else if (srate < 3000000) { aclk = 0xb7; bclk = 0x4b; }
2228 else if (srate < 7000000) { aclk = 0xb7; bclk = 0x4f; }
2229 else if (srate < 14000000) { aclk = 0xb7; bclk = 0x53; }
2230 else if (srate < 30000000) { aclk = 0xb6; bclk = 0x53; }
2231 else if (srate < 45000000) { aclk = 0xb4; bclk = 0x51; }
2232
2233 stv0299_writereg (fe, 0x13, aclk);
2234 stv0299_writereg (fe, 0x14, bclk);
2235 stv0299_writereg (fe, 0x1f, (ratio >> 16) & 0xff);
2236 stv0299_writereg (fe, 0x20, (ratio >> 8) & 0xff);
2237 stv0299_writereg (fe, 0x21, (ratio ) & 0xf0);
2238
2239 return 0;
2240}
2241
2242static int samsung_tbmu24112_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
2243{
2244 u8 buf[4];
2245 u32 div;
2246 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
2247 struct adapter* adapter = (struct adapter*) fe->dvb->priv;
2248
2249 div = params->frequency / 125;
2250
2251 buf[0] = (div >> 8) & 0x7f;
2252 buf[1] = div & 0xff;
2253 buf[2] = 0x84; // 0xC4
2254 buf[3] = 0x08;
2255
2256 if (params->frequency < 1500000) buf[3] |= 0x10;
2257
2258 if (i2c_transfer (&adapter->i2c_adap, &msg, 1) != 1) return -EIO;
2259 return 0;
2260}
2261
2262static u8 samsung_tbmu24112_inittab[] = {
2263 0x01, 0x15,
2264 0x02, 0x30,
2265 0x03, 0x00,
2266 0x04, 0x7D,
2267 0x05, 0x35,
2268 0x06, 0x02,
2269 0x07, 0x00,
2270 0x08, 0xC3,
2271 0x0C, 0x00,
2272 0x0D, 0x81,
2273 0x0E, 0x23,
2274 0x0F, 0x12,
2275 0x10, 0x7E,
2276 0x11, 0x84,
2277 0x12, 0xB9,
2278 0x13, 0x88,
2279 0x14, 0x89,
2280 0x15, 0xC9,
2281 0x16, 0x00,
2282 0x17, 0x5C,
2283 0x18, 0x00,
2284 0x19, 0x00,
2285 0x1A, 0x00,
2286 0x1C, 0x00,
2287 0x1D, 0x00,
2288 0x1E, 0x00,
2289 0x1F, 0x3A,
2290 0x20, 0x2E,
2291 0x21, 0x80,
2292 0x22, 0xFF,
2293 0x23, 0xC1,
2294 0x28, 0x00,
2295 0x29, 0x1E,
2296 0x2A, 0x14,
2297 0x2B, 0x0F,
2298 0x2C, 0x09,
2299 0x2D, 0x05,
2300 0x31, 0x1F,
2301 0x32, 0x19,
2302 0x33, 0xFE,
2303 0x34, 0x93,
2304 0xff, 0xff,
2305 };
2306
2307static struct stv0299_config samsung_tbmu24112_config = {
2308 .demod_address = 0x68,
2309 .inittab = samsung_tbmu24112_inittab,
2310 .mclk = 88000000UL,
2311 .invert = 0,
2312 .enhanced_tuning = 0,
2313 .skip_reinit = 0,
2314 .lock_output = STV0229_LOCKOUTPUT_LK,
2315 .volt13_op0_op1 = STV0299_VOLT13_OP1,
2316 .min_delay_ms = 100,
2317 .set_symbol_rate = samsung_tbmu24112_set_symbol_rate,
2318 .pll_set = samsung_tbmu24112_pll_set,
2319};
2320
2321
2322
2323static int nxt2002_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name)
2324{
2325 struct adapter* adapter = (struct adapter*) fe->dvb->priv;
2326
2327 return request_firmware(fw, name, &adapter->pdev->dev);
2328}
2329
2330
2331static struct nxt2002_config samsung_tbmv_config = {
2332 .demod_address = 0x0A,
2333 .request_firmware = nxt2002_request_firmware,
2334};
2335
2336static int samsung_tdtc9251dh0_demod_init(struct dvb_frontend* fe)
2337{
2338 static u8 mt352_clock_config [] = { 0x89, 0x18, 0x2d };
2339 static u8 mt352_reset [] = { 0x50, 0x80 };
2340 static u8 mt352_adc_ctl_1_cfg [] = { 0x8E, 0x40 };
2341 static u8 mt352_agc_cfg [] = { 0x67, 0x28, 0xa1 };
2342 static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 };
2343
2344 mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config));
2345 udelay(2000);
2346 mt352_write(fe, mt352_reset, sizeof(mt352_reset));
2347 mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg));
2348
2349 mt352_write(fe, mt352_agc_cfg, sizeof(mt352_agc_cfg));
2350 mt352_write(fe, mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg));
2351
2352 return 0;
2353}
2354
2355static int samsung_tdtc9251dh0_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u8* pllbuf)
2356{
2357 u32 div;
2358 unsigned char bs = 0;
2359
2360 #define IF_FREQUENCYx6 217 /* 6 * 36.16666666667MHz */
2361 div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6;
2362
2363 if (params->frequency >= 48000000 && params->frequency <= 154000000) bs = 0x09;
2364 if (params->frequency >= 161000000 && params->frequency <= 439000000) bs = 0x0a;
2365 if (params->frequency >= 447000000 && params->frequency <= 863000000) bs = 0x08;
2366
2367 pllbuf[0] = 0xc2; // Note: non-linux standard PLL i2c address
2368 pllbuf[1] = div >> 8;
2369 pllbuf[2] = div & 0xff;
2370 pllbuf[3] = 0xcc;
2371 pllbuf[4] = bs;
2372
2373 return 0;
2374}
2375
2376static struct mt352_config samsung_tdtc9251dh0_config = {
2377
2378 .demod_address = 0x0f,
2379 .demod_init = samsung_tdtc9251dh0_demod_init,
2380 .pll_set = samsung_tdtc9251dh0_pll_set,
2381};
2382
2383static int skystar23_samsung_tbdu18132_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
2384{
2385 u8 buf[4];
2386 u32 div;
2387 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
2388 struct adapter* adapter = (struct adapter*) fe->dvb->priv;
2389
2390 div = (params->frequency + (125/2)) / 125;
2391
2392 buf[0] = (div >> 8) & 0x7f;
2393 buf[1] = (div >> 0) & 0xff;
2394 buf[2] = 0x84 | ((div >> 10) & 0x60);
2395 buf[3] = 0x80;
2396
2397 if (params->frequency < 1550000)
2398 buf[3] |= 0x02;
2399
2400 if (i2c_transfer (&adapter->i2c_adap, &msg, 1) != 1) return -EIO;
2401 return 0;
2402}
2403
2404static struct mt312_config skystar23_samsung_tbdu18132_config = {
2405
2406 .demod_address = 0x0e,
2407 .pll_set = skystar23_samsung_tbdu18132_pll_set,
2408};
2409
2410
2411
2412
2413static void frontend_init(struct adapter *skystar2)
2414{
2415 switch(skystar2->pdev->device) {
2416 case 0x2103: // Technisat Skystar2 OR Technisat Airstar2 (DVB-T or ATSC)
2417
2418 // Attempt to load the Nextwave nxt2002 for ATSC support
2419 skystar2->fe = nxt2002_attach(&samsung_tbmv_config, &skystar2->i2c_adap);
2420 if (skystar2->fe != NULL) {
2421 skystar2->fe_sleep = skystar2->fe->ops->sleep;
2422 skystar2->fe->ops->sleep = flexcop_sleep;
2423 break;
2424 }
2425
2426 // try the skystar2 v2.6 first (stv0299/Samsung tbmu24112(sl1935))
2427 skystar2->fe = stv0299_attach(&samsung_tbmu24112_config, &skystar2->i2c_adap);
2428 if (skystar2->fe != NULL) {
2429 skystar2->fe->ops->set_voltage = flexcop_set_voltage;
2430 skystar2->fe_sleep = skystar2->fe->ops->sleep;
2431 skystar2->fe->ops->sleep = flexcop_sleep;
2432 break;
2433}
2434
2435 // try the airstar2 (mt352/Samsung tdtc9251dh0(??))
2436 skystar2->fe = mt352_attach(&samsung_tdtc9251dh0_config, &skystar2->i2c_adap);
2437 if (skystar2->fe != NULL) {
2438 skystar2->fe->ops->info.frequency_min = 474000000;
2439 skystar2->fe->ops->info.frequency_max = 858000000;
2440 break;
2441 }
2442
2443 // try the skystar2 v2.3 (vp310/Samsung tbdu18132(tsa5059))
2444 skystar2->fe = vp310_attach(&skystar23_samsung_tbdu18132_config, &skystar2->i2c_adap);
2445 if (skystar2->fe != NULL) {
2446 skystar2->fe->ops->diseqc_send_master_cmd = flexcop_diseqc_send_master_cmd;
2447 skystar2->fe->ops->diseqc_send_burst = flexcop_diseqc_send_burst;
2448 skystar2->fe->ops->set_tone = flexcop_set_tone;
2449 skystar2->fe->ops->set_voltage = flexcop_set_voltage;
2450 skystar2->fe_sleep = skystar2->fe->ops->sleep;
2451 skystar2->fe->ops->sleep = flexcop_sleep;
2452 break;
2453 }
2454 break;
2455 }
2456
2457 if (skystar2->fe == NULL) {
2458 printk("skystar2: A frontend driver was not found for device %04x/%04x subsystem %04x/%04x\n",
2459 skystar2->pdev->vendor,
2460 skystar2->pdev->device,
2461 skystar2->pdev->subsystem_vendor,
2462 skystar2->pdev->subsystem_device);
2463 } else {
2464 if (dvb_register_frontend(skystar2->dvb_adapter, skystar2->fe)) {
2465 printk("skystar2: Frontend registration failed!\n");
2466 if (skystar2->fe->ops->release)
2467 skystar2->fe->ops->release(skystar2->fe);
2468 skystar2->fe = NULL;
2469 }
2470 }
2471}
2472
2473
2474static int skystar2_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
2475{
2476 struct adapter *adapter;
2477 struct dvb_adapter *dvb_adapter;
2478 struct dvb_demux *dvbdemux;
2479 struct dmx_demux *dmx;
2480 int ret = -ENODEV;
2481
2482 if (!pdev)
2483 goto out;
2484
2485 ret = driver_initialize(pdev);
2486 if (ret < 0)
2487 goto out;
2488
2489 ret = dvb_register_adapter(&dvb_adapter, skystar2_pci_driver.name,
2490 THIS_MODULE);
2491 if (ret < 0) {
2492 printk("%s: Error registering DVB adapter\n", __FUNCTION__);
2493 goto err_halt;
2494 }
2495
2496 adapter = pci_get_drvdata(pdev);
2497
2498 dvb_adapter->priv = adapter;
2499 adapter->dvb_adapter = dvb_adapter;
2500
2501
2502 init_MUTEX(&adapter->i2c_sem);
2503
2504
2505 memset(&adapter->i2c_adap, 0, sizeof(struct i2c_adapter));
2506 strcpy(adapter->i2c_adap.name, "SkyStar2");
2507
2508 i2c_set_adapdata(&adapter->i2c_adap, adapter);
2509
2510#ifdef I2C_ADAP_CLASS_TV_DIGITAL
2511 adapter->i2c_adap.class = I2C_ADAP_CLASS_TV_DIGITAL;
2512#else
2513 adapter->i2c_adap.class = I2C_CLASS_TV_DIGITAL;
2514#endif
2515 adapter->i2c_adap.algo = &flexcop_algo;
2516 adapter->i2c_adap.algo_data = NULL;
2517 adapter->i2c_adap.id = I2C_ALGO_BIT;
2518
2519 ret = i2c_add_adapter(&adapter->i2c_adap);
2520 if (ret < 0)
2521 goto err_dvb_unregister;
2522
2523 dvbdemux = &adapter->demux;
2524
2525 dvbdemux->priv = adapter;
2526 dvbdemux->filternum = N_PID_SLOTS;
2527 dvbdemux->feednum = N_PID_SLOTS;
2528 dvbdemux->start_feed = dvb_start_feed;
2529 dvbdemux->stop_feed = dvb_stop_feed;
2530 dvbdemux->write_to_decoder = NULL;
2531 dvbdemux->dmx.capabilities = (DMX_TS_FILTERING | DMX_SECTION_FILTERING | DMX_MEMORY_BASED_FILTERING);
2532
2533 ret = dvb_dmx_init(&adapter->demux);
2534 if (ret < 0)
2535 goto err_i2c_del;
2536
2537 dmx = &dvbdemux->dmx;
2538
2539 adapter->hw_frontend.source = DMX_FRONTEND_0;
2540 adapter->dmxdev.filternum = N_PID_SLOTS;
2541 adapter->dmxdev.demux = dmx;
2542 adapter->dmxdev.capabilities = 0;
2543
2544 ret = dvb_dmxdev_init(&adapter->dmxdev, adapter->dvb_adapter);
2545 if (ret < 0)
2546 goto err_dmx_release;
2547
2548 ret = dmx->add_frontend(dmx, &adapter->hw_frontend);
2549 if (ret < 0)
2550 goto err_dmxdev_release;
2551
2552 adapter->mem_frontend.source = DMX_MEMORY_FE;
2553
2554 ret = dmx->add_frontend(dmx, &adapter->mem_frontend);
2555 if (ret < 0)
2556 goto err_remove_hw_frontend;
2557
2558 ret = dmx->connect_frontend(dmx, &adapter->hw_frontend);
2559 if (ret < 0)
2560 goto err_remove_mem_frontend;
2561
2562 dvb_net_init(adapter->dvb_adapter, &adapter->dvbnet, &dvbdemux->dmx);
2563
2564 frontend_init(adapter);
2565out:
2566 return ret;
2567
2568err_remove_mem_frontend:
2569 dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, &adapter->mem_frontend);
2570err_remove_hw_frontend:
2571 dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, &adapter->hw_frontend);
2572err_dmxdev_release:
2573 dvb_dmxdev_release(&adapter->dmxdev);
2574err_dmx_release:
2575 dvb_dmx_release(&adapter->demux);
2576err_i2c_del:
2577 i2c_del_adapter(&adapter->i2c_adap);
2578err_dvb_unregister:
2579 dvb_unregister_adapter(adapter->dvb_adapter);
2580err_halt:
2581 driver_halt(pdev);
2582 goto out;
2583}
2584
2585static void skystar2_remove(struct pci_dev *pdev)
2586{
2587 struct adapter *adapter = pci_get_drvdata(pdev);
2588 struct dvb_demux *dvbdemux;
2589 struct dmx_demux *dmx;
2590
2591 if (!adapter)
2592 return;
2593
2594 dvb_net_release(&adapter->dvbnet);
2595 dvbdemux = &adapter->demux;
2596 dmx = &dvbdemux->dmx;
2597
2598 dmx->close(dmx);
2599 dmx->remove_frontend(dmx, &adapter->hw_frontend);
2600 dmx->remove_frontend(dmx, &adapter->mem_frontend);
2601
2602 dvb_dmxdev_release(&adapter->dmxdev);
2603 dvb_dmx_release(dvbdemux);
2604
2605 if (adapter->fe != NULL)
2606 dvb_unregister_frontend(adapter->fe);
2607
2608 dvb_unregister_adapter(adapter->dvb_adapter);
2609
2610 i2c_del_adapter(&adapter->i2c_adap);
2611
2612 driver_halt(pdev);
2613 }
2614
2615static struct pci_device_id skystar2_pci_tbl[] = {
2616 {0x000013d0, 0x00002103, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000},
2617/* {0x000013d0, 0x00002200, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000}, UNDEFINED HARDWARE - mail linuxtv.org list */ //FCIII
2618 {0,},
2619};
2620
2621MODULE_DEVICE_TABLE(pci, skystar2_pci_tbl);
2622
2623static struct pci_driver skystar2_pci_driver = {
2624 .name = "SkyStar2",
2625 .id_table = skystar2_pci_tbl,
2626 .probe = skystar2_probe,
2627 .remove = skystar2_remove,
2628};
2629
2630static int skystar2_init(void)
2631{
2632 return pci_register_driver(&skystar2_pci_driver);
2633}
2634
2635static void skystar2_cleanup(void)
2636{
2637 pci_unregister_driver(&skystar2_pci_driver);
2638}
2639
2640module_init(skystar2_init);
2641module_exit(skystar2_cleanup);
2642
2643MODULE_DESCRIPTION("Technisat SkyStar2 DVB PCI Driver");
2644MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/bt8xx/Kconfig b/drivers/media/dvb/bt8xx/Kconfig
new file mode 100644
index 000000000000..e7d11e0667a8
--- /dev/null
+++ b/drivers/media/dvb/bt8xx/Kconfig
@@ -0,0 +1,19 @@
1config DVB_BT8XX
2 tristate "Nebula/Pinnacle PCTV/Twinhan PCI cards"
3 depends on DVB_CORE && PCI && VIDEO_BT848
4 select DVB_MT352
5 select DVB_SP887X
6 select DVB_NXT6000
7 select DVB_CX24110
8 select DVB_OR51211
9 help
10 Support for PCI cards based on the Bt8xx PCI bridge. Examples are
11 the Nebula cards, the Pinnacle PCTV cards, the Twinhan DST cards and
12 pcHDTV HD2000 cards.
13
14 Since these cards have no MPEG decoder onboard, they transmit
15 only compressed MPEG data over the PCI bus, so you need
16 an external software decoder to watch TV on your computer.
17
18 Say Y if you own such a device and want to use it.
19
diff --git a/drivers/media/dvb/bt8xx/Makefile b/drivers/media/dvb/bt8xx/Makefile
new file mode 100644
index 000000000000..9da8604b9e18
--- /dev/null
+++ b/drivers/media/dvb/bt8xx/Makefile
@@ -0,0 +1,5 @@
1
2obj-$(CONFIG_DVB_BT8XX) += bt878.o dvb-bt8xx.o dst.o
3
4EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/video -Idrivers/media/dvb/frontends
5
diff --git a/drivers/media/dvb/bt8xx/bt878.c b/drivers/media/dvb/bt8xx/bt878.c
new file mode 100644
index 000000000000..213ff7902024
--- /dev/null
+++ b/drivers/media/dvb/bt8xx/bt878.c
@@ -0,0 +1,588 @@
1/*
2 * bt878.c: part of the driver for the Pinnacle PCTV Sat DVB PCI card
3 *
4 * Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@t-online.de>
5 *
6 * large parts based on the bttv driver
7 * Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
8 * & Marcus Metzler (mocm@thp.uni-koeln.de)
9 * (c) 1999,2000 Gerd Knorr <kraxel@goldbach.in-berlin.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
30#include <linux/module.h>
31#include <linux/moduleparam.h>
32#include <linux/kernel.h>
33#include <linux/pci.h>
34#include <asm/io.h>
35#include <linux/ioport.h>
36#include <asm/pgtable.h>
37#include <asm/page.h>
38#include <linux/types.h>
39#include <linux/interrupt.h>
40#include <linux/kmod.h>
41#include <linux/vmalloc.h>
42#include <linux/init.h>
43
44#include "dmxdev.h"
45#include "dvbdev.h"
46#include "bt878.h"
47#include "dst_priv.h"
48
49
50/**************************************/
51/* Miscellaneous utility definitions */
52/**************************************/
53
54static unsigned int bt878_verbose = 1;
55static unsigned int bt878_debug;
56
57module_param_named(verbose, bt878_verbose, int, 0444);
58MODULE_PARM_DESC(verbose,
59 "verbose startup messages, default is 1 (yes)");
60module_param_named(debug, bt878_debug, int, 0644);
61MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
62
63int bt878_num;
64struct bt878 bt878[BT878_MAX];
65
66EXPORT_SYMBOL(bt878_debug);
67EXPORT_SYMBOL(bt878_verbose);
68EXPORT_SYMBOL(bt878_num);
69EXPORT_SYMBOL(bt878);
70
71#define btwrite(dat,adr) bmtwrite((dat), (bt->bt878_mem+(adr)))
72#define btread(adr) bmtread(bt->bt878_mem+(adr))
73
74#define btand(dat,adr) btwrite((dat) & btread(adr), adr)
75#define btor(dat,adr) btwrite((dat) | btread(adr), adr)
76#define btaor(dat,mask,adr) btwrite((dat) | ((mask) & btread(adr)), adr)
77
78#if defined(dprintk)
79#undef dprintk
80#endif
81#define dprintk if(bt878_debug) printk
82
83static void bt878_mem_free(struct bt878 *bt)
84{
85 if (bt->buf_cpu) {
86 pci_free_consistent(bt->dev, bt->buf_size, bt->buf_cpu,
87 bt->buf_dma);
88 bt->buf_cpu = NULL;
89 }
90
91 if (bt->risc_cpu) {
92 pci_free_consistent(bt->dev, bt->risc_size, bt->risc_cpu,
93 bt->risc_dma);
94 bt->risc_cpu = NULL;
95 }
96}
97
98static int bt878_mem_alloc(struct bt878 *bt)
99{
100 if (!bt->buf_cpu) {
101 bt->buf_size = 128 * 1024;
102
103 bt->buf_cpu =
104 pci_alloc_consistent(bt->dev, bt->buf_size,
105 &bt->buf_dma);
106
107 if (!bt->buf_cpu)
108 return -ENOMEM;
109
110 memset(bt->buf_cpu, 0, bt->buf_size);
111 }
112
113 if (!bt->risc_cpu) {
114 bt->risc_size = PAGE_SIZE;
115 bt->risc_cpu =
116 pci_alloc_consistent(bt->dev, bt->risc_size,
117 &bt->risc_dma);
118
119 if (!bt->risc_cpu) {
120 bt878_mem_free(bt);
121 return -ENOMEM;
122 }
123
124 memset(bt->risc_cpu, 0, bt->risc_size);
125 }
126
127 return 0;
128}
129
130/* RISC instructions */
131#define RISC_WRITE (0x01 << 28)
132#define RISC_JUMP (0x07 << 28)
133#define RISC_SYNC (0x08 << 28)
134
135/* RISC bits */
136#define RISC_WR_SOL (1 << 27)
137#define RISC_WR_EOL (1 << 26)
138#define RISC_IRQ (1 << 24)
139#define RISC_STATUS(status) ((((~status) & 0x0F) << 20) | ((status & 0x0F) << 16))
140#define RISC_SYNC_RESYNC (1 << 15)
141#define RISC_SYNC_FM1 0x06
142#define RISC_SYNC_VRO 0x0C
143
144#define RISC_FLUSH() bt->risc_pos = 0
145#define RISC_INSTR(instr) bt->risc_cpu[bt->risc_pos++] = cpu_to_le32(instr)
146
147static int bt878_make_risc(struct bt878 *bt)
148{
149 bt->block_bytes = bt->buf_size >> 4;
150 bt->block_count = 1 << 4;
151 bt->line_bytes = bt->block_bytes;
152 bt->line_count = bt->block_count;
153
154 while (bt->line_bytes > 4095) {
155 bt->line_bytes >>= 1;
156 bt->line_count <<= 1;
157 }
158
159 if (bt->line_count > 255) {
160 printk("bt878: buffer size error!\n");
161 return -EINVAL;
162 }
163 return 0;
164}
165
166
167static void bt878_risc_program(struct bt878 *bt, u32 op_sync_orin)
168{
169 u32 buf_pos = 0;
170 u32 line;
171
172 RISC_FLUSH();
173 RISC_INSTR(RISC_SYNC | RISC_SYNC_FM1 | op_sync_orin);
174 RISC_INSTR(0);
175
176 dprintk("bt878: risc len lines %u, bytes per line %u\n",
177 bt->line_count, bt->line_bytes);
178 for (line = 0; line < bt->line_count; line++) {
179 // At the beginning of every block we issue an IRQ with previous (finished) block number set
180 if (!(buf_pos % bt->block_bytes))
181 RISC_INSTR(RISC_WRITE | RISC_WR_SOL | RISC_WR_EOL |
182 RISC_IRQ |
183 RISC_STATUS(((buf_pos /
184 bt->block_bytes) +
185 (bt->block_count -
186 1)) %
187 bt->block_count) | bt->
188 line_bytes);
189 else
190 RISC_INSTR(RISC_WRITE | RISC_WR_SOL | RISC_WR_EOL |
191 bt->line_bytes);
192 RISC_INSTR(bt->buf_dma + buf_pos);
193 buf_pos += bt->line_bytes;
194 }
195
196 RISC_INSTR(RISC_SYNC | op_sync_orin | RISC_SYNC_VRO);
197 RISC_INSTR(0);
198
199 RISC_INSTR(RISC_JUMP);
200 RISC_INSTR(bt->risc_dma);
201
202 btwrite((bt->line_count << 16) | bt->line_bytes, BT878_APACK_LEN);
203}
204
205/*****************************/
206/* Start/Stop grabbing funcs */
207/*****************************/
208
209void bt878_start(struct bt878 *bt, u32 controlreg, u32 op_sync_orin,
210 u32 irq_err_ignore)
211{
212 u32 int_mask;
213
214 dprintk("bt878 debug: bt878_start (ctl=%8.8x)\n", controlreg);
215 /* complete the writing of the risc dma program now we have
216 * the card specifics
217 */
218 bt878_risc_program(bt, op_sync_orin);
219 controlreg &= ~0x1f;
220 controlreg |= 0x1b;
221
222 btwrite(cpu_to_le32(bt->risc_dma), BT878_ARISC_START);
223
224 /* original int mask had :
225 * 6 2 8 4 0
226 * 1111 1111 1000 0000 0000
227 * SCERR|OCERR|PABORT|RIPERR|FDSR|FTRGT|FBUS|RISCI
228 * Hacked for DST to:
229 * SCERR | OCERR | FDSR | FTRGT | FBUS | RISCI
230 */
231 int_mask = BT878_ASCERR | BT878_AOCERR | BT878_APABORT |
232 BT878_ARIPERR | BT878_APPERR | BT878_AFDSR | BT878_AFTRGT |
233 BT878_AFBUS | BT878_ARISCI;
234
235
236 /* ignore pesky bits */
237 int_mask &= ~irq_err_ignore;
238
239 btwrite(int_mask, BT878_AINT_MASK);
240 btwrite(controlreg, BT878_AGPIO_DMA_CTL);
241}
242
243void bt878_stop(struct bt878 *bt)
244{
245 u32 stat;
246 int i = 0;
247
248 dprintk("bt878 debug: bt878_stop\n");
249
250 btwrite(0, BT878_AINT_MASK);
251 btand(~0x13, BT878_AGPIO_DMA_CTL);
252
253 do {
254 stat = btread(BT878_AINT_STAT);
255 if (!(stat & BT878_ARISC_EN))
256 break;
257 i++;
258 } while (i < 500);
259
260 dprintk("bt878(%d) debug: bt878_stop, i=%d, stat=0x%8.8x\n",
261 bt->nr, i, stat);
262}
263
264EXPORT_SYMBOL(bt878_start);
265EXPORT_SYMBOL(bt878_stop);
266
267/*****************************/
268/* Interrupt service routine */
269/*****************************/
270
271static irqreturn_t bt878_irq(int irq, void *dev_id, struct pt_regs *regs)
272{
273 u32 stat, astat, mask;
274 int count;
275 struct bt878 *bt;
276
277 bt = (struct bt878 *) dev_id;
278
279 count = 0;
280 while (1) {
281 stat = btread(BT878_AINT_STAT);
282 mask = btread(BT878_AINT_MASK);
283 if (!(astat = (stat & mask)))
284 return IRQ_NONE; /* this interrupt is not for me */
285/* dprintk("bt878(%d) debug: irq count %d, stat 0x%8.8x, mask 0x%8.8x\n",bt->nr,count,stat,mask); */
286 btwrite(astat, BT878_AINT_STAT); /* try to clear interupt condition */
287
288
289 if (astat & (BT878_ASCERR | BT878_AOCERR)) {
290 if (bt878_verbose) {
291 printk("bt878(%d): irq%s%s risc_pc=%08x\n",
292 bt->nr,
293 (astat & BT878_ASCERR) ? " SCERR" :
294 "",
295 (astat & BT878_AOCERR) ? " OCERR" :
296 "", btread(BT878_ARISC_PC));
297 }
298 }
299 if (astat & (BT878_APABORT | BT878_ARIPERR | BT878_APPERR)) {
300 if (bt878_verbose) {
301 printk
302 ("bt878(%d): irq%s%s%s risc_pc=%08x\n",
303 bt->nr,
304 (astat & BT878_APABORT) ? " PABORT" :
305 "",
306 (astat & BT878_ARIPERR) ? " RIPERR" :
307 "",
308 (astat & BT878_APPERR) ? " PPERR" :
309 "", btread(BT878_ARISC_PC));
310 }
311 }
312 if (astat & (BT878_AFDSR | BT878_AFTRGT | BT878_AFBUS)) {
313 if (bt878_verbose) {
314 printk
315 ("bt878(%d): irq%s%s%s risc_pc=%08x\n",
316 bt->nr,
317 (astat & BT878_AFDSR) ? " FDSR" : "",
318 (astat & BT878_AFTRGT) ? " FTRGT" :
319 "",
320 (astat & BT878_AFBUS) ? " FBUS" : "",
321 btread(BT878_ARISC_PC));
322 }
323 }
324 if (astat & BT878_ARISCI) {
325 bt->finished_block = (stat & BT878_ARISCS) >> 28;
326 tasklet_schedule(&bt->tasklet);
327 break;
328 }
329 count++;
330 if (count > 20) {
331 btwrite(0, BT878_AINT_MASK);
332 printk(KERN_ERR
333 "bt878(%d): IRQ lockup, cleared int mask\n",
334 bt->nr);
335 break;
336 }
337 }
338 return IRQ_HANDLED;
339}
340
341int
342bt878_device_control(struct bt878 *bt, unsigned int cmd, union dst_gpio_packet *mp)
343{
344 int retval;
345
346 retval = 0;
347 if (down_interruptible (&bt->gpio_lock))
348 return -ERESTARTSYS;
349 /* special gpio signal */
350 switch (cmd) {
351 case DST_IG_ENABLE:
352 // dprintk("dvb_bt8xx: dst enable mask 0x%02x enb 0x%02x \n", mp->dstg.enb.mask, mp->dstg.enb.enable);
353 retval = bttv_gpio_enable(bt->bttv_nr,
354 mp->enb.mask,
355 mp->enb.enable);
356 break;
357 case DST_IG_WRITE:
358 // dprintk("dvb_bt8xx: dst write gpio mask 0x%02x out 0x%02x\n", mp->dstg.outp.mask, mp->dstg.outp.highvals);
359 retval = bttv_write_gpio(bt->bttv_nr,
360 mp->outp.mask,
361 mp->outp.highvals);
362
363 break;
364 case DST_IG_READ:
365 /* read */
366 retval = bttv_read_gpio(bt->bttv_nr, &mp->rd.value);
367 // dprintk("dvb_bt8xx: dst read gpio 0x%02x\n", (unsigned)mp->dstg.rd.value);
368 break;
369 case DST_IG_TS:
370 /* Set packet size */
371 bt->TS_Size = mp->psize;
372 break;
373
374 default:
375 retval = -EINVAL;
376 break;
377 }
378 up(&bt->gpio_lock);
379 return retval;
380}
381
382EXPORT_SYMBOL(bt878_device_control);
383
384/***********************/
385/* PCI device handling */
386/***********************/
387
388static int __devinit bt878_probe(struct pci_dev *dev,
389 const struct pci_device_id *pci_id)
390{
391 int result;
392 unsigned char lat;
393 struct bt878 *bt;
394#if defined(__powerpc__)
395 unsigned int cmd;
396#endif
397
398 printk(KERN_INFO "bt878: Bt878 AUDIO function found (%d).\n",
399 bt878_num);
400 if (pci_enable_device(dev))
401 return -EIO;
402
403 bt = &bt878[bt878_num];
404 bt->dev = dev;
405 bt->nr = bt878_num;
406 bt->shutdown = 0;
407
408 bt->id = dev->device;
409 bt->irq = dev->irq;
410 bt->bt878_adr = pci_resource_start(dev, 0);
411 if (!request_mem_region(pci_resource_start(dev, 0),
412 pci_resource_len(dev, 0), "bt878")) {
413 result = -EBUSY;
414 goto fail0;
415 }
416
417 pci_read_config_byte(dev, PCI_CLASS_REVISION, &bt->revision);
418 pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
419 printk(KERN_INFO "bt878(%d): Bt%x (rev %d) at %02x:%02x.%x, ",
420 bt878_num, bt->id, bt->revision, dev->bus->number,
421 PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
422 printk("irq: %d, latency: %d, memory: 0x%lx\n",
423 bt->irq, lat, bt->bt878_adr);
424
425
426#if defined(__powerpc__)
427 /* on OpenFirmware machines (PowerMac at least), PCI memory cycle */
428 /* response on cards with no firmware is not enabled by OF */
429 pci_read_config_dword(dev, PCI_COMMAND, &cmd);
430 cmd = (cmd | PCI_COMMAND_MEMORY);
431 pci_write_config_dword(dev, PCI_COMMAND, cmd);
432#endif
433
434#ifdef __sparc__
435 bt->bt878_mem = (unsigned char *) bt->bt878_adr;
436#else
437 bt->bt878_mem = ioremap(bt->bt878_adr, 0x1000);
438#endif
439
440 /* clear interrupt mask */
441 btwrite(0, BT848_INT_MASK);
442
443 result = request_irq(bt->irq, bt878_irq,
444 SA_SHIRQ | SA_INTERRUPT, "bt878",
445 (void *) bt);
446 if (result == -EINVAL) {
447 printk(KERN_ERR "bt878(%d): Bad irq number or handler\n",
448 bt878_num);
449 goto fail1;
450 }
451 if (result == -EBUSY) {
452 printk(KERN_ERR
453 "bt878(%d): IRQ %d busy, change your PnP config in BIOS\n",
454 bt878_num, bt->irq);
455 goto fail1;
456 }
457 if (result < 0)
458 goto fail1;
459
460 pci_set_master(dev);
461 pci_set_drvdata(dev, bt);
462
463/* if(init_bt878(btv) < 0) {
464 bt878_remove(dev);
465 return -EIO;
466 }
467*/
468
469 if ((result = bt878_mem_alloc(bt))) {
470 printk("bt878: failed to allocate memory!\n");
471 goto fail2;
472 }
473
474 bt878_make_risc(bt);
475 btwrite(0, BT878_AINT_MASK);
476 bt878_num++;
477
478 return 0;
479
480 fail2:
481 free_irq(bt->irq, bt);
482 fail1:
483 release_mem_region(pci_resource_start(bt->dev, 0),
484 pci_resource_len(bt->dev, 0));
485 fail0:
486 pci_disable_device(dev);
487 return result;
488}
489
490static void __devexit bt878_remove(struct pci_dev *pci_dev)
491{
492 u8 command;
493 struct bt878 *bt = pci_get_drvdata(pci_dev);
494
495 if (bt878_verbose)
496 printk("bt878(%d): unloading\n", bt->nr);
497
498 /* turn off all capturing, DMA and IRQs */
499 btand(~0x13, BT878_AGPIO_DMA_CTL);
500
501 /* first disable interrupts before unmapping the memory! */
502 btwrite(0, BT878_AINT_MASK);
503 btwrite(~0U, BT878_AINT_STAT);
504
505 /* disable PCI bus-mastering */
506 pci_read_config_byte(bt->dev, PCI_COMMAND, &command);
507 /* Should this be &=~ ?? */
508 command &= ~PCI_COMMAND_MASTER;
509 pci_write_config_byte(bt->dev, PCI_COMMAND, command);
510
511 free_irq(bt->irq, bt);
512 printk(KERN_DEBUG "bt878_mem: 0x%p.\n", bt->bt878_mem);
513 if (bt->bt878_mem)
514 iounmap(bt->bt878_mem);
515
516 release_mem_region(pci_resource_start(bt->dev, 0),
517 pci_resource_len(bt->dev, 0));
518 /* wake up any waiting processes
519 because shutdown flag is set, no new processes (in this queue)
520 are expected
521 */
522 bt->shutdown = 1;
523 bt878_mem_free(bt);
524
525 pci_set_drvdata(pci_dev, NULL);
526 pci_disable_device(pci_dev);
527 return;
528}
529
530static struct pci_device_id bt878_pci_tbl[] __devinitdata = {
531 {PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BROOKTREE_878,
532 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
533 {0,}
534};
535
536MODULE_DEVICE_TABLE(pci, bt878_pci_tbl);
537
538static struct pci_driver bt878_pci_driver = {
539 .name = "bt878",
540 .id_table = bt878_pci_tbl,
541 .probe = bt878_probe,
542 .remove = bt878_remove,
543};
544
545static int bt878_pci_driver_registered = 0;
546
547/*******************************/
548/* Module management functions */
549/*******************************/
550
551static int bt878_init_module(void)
552{
553 bt878_num = 0;
554 bt878_pci_driver_registered = 0;
555
556 printk(KERN_INFO "bt878: AUDIO driver version %d.%d.%d loaded\n",
557 (BT878_VERSION_CODE >> 16) & 0xff,
558 (BT878_VERSION_CODE >> 8) & 0xff,
559 BT878_VERSION_CODE & 0xff);
560/*
561 bt878_check_chipset();
562*/
563 /* later we register inside of bt878_find_audio_dma()
564 * because we may want to ignore certain cards */
565 bt878_pci_driver_registered = 1;
566 return pci_register_driver(&bt878_pci_driver);
567}
568
569static void bt878_cleanup_module(void)
570{
571 if (bt878_pci_driver_registered) {
572 bt878_pci_driver_registered = 0;
573 pci_unregister_driver(&bt878_pci_driver);
574 }
575 return;
576}
577
578module_init(bt878_init_module);
579module_exit(bt878_cleanup_module);
580
581//MODULE_AUTHOR("XXX");
582MODULE_LICENSE("GPL");
583
584/*
585 * Local variables:
586 * c-basic-offset: 8
587 * End:
588 */
diff --git a/drivers/media/dvb/bt8xx/bt878.h b/drivers/media/dvb/bt8xx/bt878.h
new file mode 100644
index 000000000000..e1b9809d1b08
--- /dev/null
+++ b/drivers/media/dvb/bt8xx/bt878.h
@@ -0,0 +1,147 @@
1/*
2 bt878.h - Bt878 audio module (register offsets)
3
4 Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@t-online.de>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19*/
20
21#ifndef _BT878_H_
22#define _BT878_H_
23
24#include <linux/interrupt.h>
25#include <linux/pci.h>
26#include <linux/sched.h>
27#include <linux/spinlock.h>
28#include "bt848.h"
29#include "bttv.h"
30
31#define BT878_VERSION_CODE 0x000000
32
33#define BT878_AINT_STAT 0x100
34#define BT878_ARISCS (0xf<<28)
35#define BT878_ARISC_EN (1<<27)
36#define BT878_ASCERR (1<<19)
37#define BT878_AOCERR (1<<18)
38#define BT878_APABORT (1<<17)
39#define BT878_ARIPERR (1<<16)
40#define BT878_APPERR (1<<15)
41#define BT878_AFDSR (1<<14)
42#define BT878_AFTRGT (1<<13)
43#define BT878_AFBUS (1<<12)
44#define BT878_ARISCI (1<<11)
45#define BT878_AOFLOW (1<<3)
46
47#define BT878_AINT_MASK 0x104
48
49#define BT878_AGPIO_DMA_CTL 0x10c
50#define BT878_A_GAIN (0xf<<28)
51#define BT878_A_G2X (1<<27)
52#define BT878_A_PWRDN (1<<26)
53#define BT878_A_SEL (3<<24)
54#define BT878_DA_SCE (1<<23)
55#define BT878_DA_LRI (1<<22)
56#define BT878_DA_MLB (1<<21)
57#define BT878_DA_LRD (0x1f<<16)
58#define BT878_DA_DPM (1<<15)
59#define BT878_DA_SBR (1<<14)
60#define BT878_DA_ES2 (1<<13)
61#define BT878_DA_LMT (1<<12)
62#define BT878_DA_SDR (0xf<<8)
63#define BT878_DA_IOM (3<<6)
64#define BT878_DA_APP (1<<5)
65#define BT878_ACAP_EN (1<<4)
66#define BT878_PKTP (3<<2)
67#define BT878_RISC_EN (1<<1)
68#define BT878_FIFO_EN 1
69
70#define BT878_APACK_LEN 0x110
71#define BT878_AFP_LEN (0xff<<16)
72#define BT878_ALP_LEN 0xfff
73
74#define BT878_ARISC_START 0x114
75
76#define BT878_ARISC_PC 0x120
77
78/* BT878 FUNCTION 0 REGISTERS */
79#define BT878_GPIO_DMA_CTL 0x10c
80
81/* Interrupt register */
82#define BT878_INT_STAT 0x100
83#define BT878_INT_MASK 0x104
84#define BT878_I2CRACK (1<<25)
85#define BT878_I2CDONE (1<<8)
86
87#define BT878_MAX 4
88
89#define BT878_RISC_SYNC_MASK (1 << 15)
90
91extern int bt878_num;
92
93struct bt878 {
94 struct semaphore gpio_lock;
95 unsigned int nr;
96 unsigned int bttv_nr;
97 struct i2c_adapter *adapter;
98 struct pci_dev *dev;
99 unsigned int id;
100 unsigned int TS_Size;
101 unsigned char revision;
102 unsigned int irq;
103 unsigned long bt878_adr;
104 volatile void __iomem *bt878_mem; /* function 1 */
105
106 volatile u32 finished_block;
107 volatile u32 last_block;
108 u32 block_count;
109 u32 block_bytes;
110 u32 line_bytes;
111 u32 line_count;
112
113 u32 buf_size;
114 u8 *buf_cpu;
115 dma_addr_t buf_dma;
116
117 u32 risc_size;
118 u32 *risc_cpu;
119 dma_addr_t risc_dma;
120 u32 risc_pos;
121
122 struct tasklet_struct tasklet;
123 int shutdown;
124};
125
126extern struct bt878 bt878[BT878_MAX];
127
128void bt878_start(struct bt878 *bt, u32 controlreg, u32 op_sync_orin,
129 u32 irq_err_ignore);
130void bt878_stop(struct bt878 *bt);
131
132#if defined(__powerpc__) /* big-endian */
133extern __inline__ void io_st_le32(volatile unsigned __iomem *addr, unsigned val)
134{
135 __asm__ __volatile__("stwbrx %1,0,%2":"=m"(*addr):"r"(val),
136 "r"(addr));
137 __asm__ __volatile__("eieio":::"memory");
138}
139
140#define bmtwrite(dat,adr) io_st_le32((adr),(dat))
141#define bmtread(adr) ld_le32((adr))
142#else
143#define bmtwrite(dat,adr) writel((dat), (adr))
144#define bmtread(adr) readl(adr)
145#endif
146
147#endif
diff --git a/drivers/media/dvb/bt8xx/dst.c b/drivers/media/dvb/bt8xx/dst.c
new file mode 100644
index 000000000000..eac83768dfd0
--- /dev/null
+++ b/drivers/media/dvb/bt8xx/dst.c
@@ -0,0 +1,1089 @@
1/*
2 Frontend-driver for TwinHan DST Frontend
3
4 Copyright (C) 2003 Jamie Honan
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21*/
22
23#include <linux/kernel.h>
24#include <linux/module.h>
25#include <linux/init.h>
26#include <linux/string.h>
27#include <linux/slab.h>
28#include <linux/vmalloc.h>
29#include <linux/delay.h>
30#include <asm/div64.h>
31
32#include "dvb_frontend.h"
33#include "dst_priv.h"
34#include "dst.h"
35
36struct dst_state {
37
38 struct i2c_adapter* i2c;
39
40 struct bt878* bt;
41
42 struct dvb_frontend_ops ops;
43
44 /* configuration settings */
45 const struct dst_config* config;
46
47 struct dvb_frontend frontend;
48
49 /* private demodulator data */
50 u8 tx_tuna[10];
51 u8 rx_tuna[10];
52 u8 rxbuffer[10];
53 u8 diseq_flags;
54 u8 dst_type;
55 u32 type_flags;
56 u32 frequency; /* intermediate frequency in kHz for QPSK */
57 fe_spectral_inversion_t inversion;
58 u32 symbol_rate; /* symbol rate in Symbols per second */
59 fe_code_rate_t fec;
60 fe_sec_voltage_t voltage;
61 fe_sec_tone_mode_t tone;
62 u32 decode_freq;
63 u8 decode_lock;
64 u16 decode_strength;
65 u16 decode_snr;
66 unsigned long cur_jiff;
67 u8 k22;
68 fe_bandwidth_t bandwidth;
69};
70
71static unsigned int dst_verbose = 0;
72module_param(dst_verbose, int, 0644);
73MODULE_PARM_DESC(dst_verbose, "verbose startup messages, default is 1 (yes)");
74static unsigned int dst_debug = 0;
75module_param(dst_debug, int, 0644);
76MODULE_PARM_DESC(dst_debug, "debug messages, default is 0 (no)");
77
78#define dprintk if (dst_debug) printk
79
80#define DST_TYPE_IS_SAT 0
81#define DST_TYPE_IS_TERR 1
82#define DST_TYPE_IS_CABLE 2
83
84#define DST_TYPE_HAS_NEWTUNE 1
85#define DST_TYPE_HAS_TS204 2
86#define DST_TYPE_HAS_SYMDIV 4
87
88#define HAS_LOCK 1
89#define ATTEMPT_TUNE 2
90#define HAS_POWER 4
91
92static void dst_packsize(struct dst_state* state, int psize)
93{
94 union dst_gpio_packet bits;
95
96 bits.psize = psize;
97 bt878_device_control(state->bt, DST_IG_TS, &bits);
98}
99
100static int dst_gpio_outb(struct dst_state* state, u32 mask, u32 enbb, u32 outhigh)
101{
102 union dst_gpio_packet enb;
103 union dst_gpio_packet bits;
104 int err;
105
106 enb.enb.mask = mask;
107 enb.enb.enable = enbb;
108 if ((err = bt878_device_control(state->bt, DST_IG_ENABLE, &enb)) < 0) {
109 dprintk("%s: dst_gpio_enb error (err == %i, mask == 0x%02x, enb == 0x%02x)\n", __FUNCTION__, err, mask, enbb);
110 return -EREMOTEIO;
111 }
112
113 /* because complete disabling means no output, no need to do output packet */
114 if (enbb == 0)
115 return 0;
116
117 bits.outp.mask = enbb;
118 bits.outp.highvals = outhigh;
119
120 if ((err = bt878_device_control(state->bt, DST_IG_WRITE, &bits)) < 0) {
121 dprintk("%s: dst_gpio_outb error (err == %i, enbb == 0x%02x, outhigh == 0x%02x)\n", __FUNCTION__, err, enbb, outhigh);
122 return -EREMOTEIO;
123 }
124 return 0;
125}
126
127static int dst_gpio_inb(struct dst_state *state, u8 * result)
128{
129 union dst_gpio_packet rd_packet;
130 int err;
131
132 *result = 0;
133
134 if ((err = bt878_device_control(state->bt, DST_IG_READ, &rd_packet)) < 0) {
135 dprintk("%s: dst_gpio_inb error (err == %i)\n", __FUNCTION__, err);
136 return -EREMOTEIO;
137 }
138
139 *result = (u8) rd_packet.rd.value;
140 return 0;
141}
142
143#define DST_I2C_ENABLE 1
144#define DST_8820 2
145
146static int dst_reset8820(struct dst_state *state)
147{
148 int retval;
149 /* pull 8820 gpio pin low, wait, high, wait, then low */
150 // dprintk ("%s: reset 8820\n", __FUNCTION__);
151 retval = dst_gpio_outb(state, DST_8820, DST_8820, 0);
152 if (retval < 0)
153 return retval;
154 msleep(10);
155 retval = dst_gpio_outb(state, DST_8820, DST_8820, DST_8820);
156 if (retval < 0)
157 return retval;
158 /* wait for more feedback on what works here *
159 msleep(10);
160 retval = dst_gpio_outb(dst, DST_8820, DST_8820, 0);
161 if (retval < 0)
162 return retval;
163 */
164 return 0;
165}
166
167static int dst_i2c_enable(struct dst_state *state)
168{
169 int retval;
170 /* pull I2C enable gpio pin low, wait */
171 // dprintk ("%s: i2c enable\n", __FUNCTION__);
172 retval = dst_gpio_outb(state, ~0, DST_I2C_ENABLE, 0);
173 if (retval < 0)
174 return retval;
175 // dprintk ("%s: i2c enable delay\n", __FUNCTION__);
176 msleep(33);
177 return 0;
178}
179
180static int dst_i2c_disable(struct dst_state *state)
181{
182 int retval;
183 /* release I2C enable gpio pin, wait */
184 // dprintk ("%s: i2c disable\n", __FUNCTION__);
185 retval = dst_gpio_outb(state, ~0, 0, 0);
186 if (retval < 0)
187 return retval;
188 // dprintk ("%s: i2c disable delay\n", __FUNCTION__);
189 msleep(33);
190 return 0;
191}
192
193static int dst_wait_dst_ready(struct dst_state *state)
194{
195 u8 reply;
196 int retval;
197 int i;
198 for (i = 0; i < 200; i++) {
199 retval = dst_gpio_inb(state, &reply);
200 if (retval < 0)
201 return retval;
202 if ((reply & DST_I2C_ENABLE) == 0) {
203 dprintk("%s: dst wait ready after %d\n", __FUNCTION__, i);
204 return 1;
205 }
206 msleep(10);
207 }
208 dprintk("%s: dst wait NOT ready after %d\n", __FUNCTION__, i);
209 return 0;
210}
211
212static int write_dst(struct dst_state *state, u8 * data, u8 len)
213{
214 struct i2c_msg msg = {
215 .addr = state->config->demod_address,.flags = 0,.buf = data,.len = len
216 };
217 int err;
218 int cnt;
219
220 if (dst_debug && dst_verbose) {
221 u8 i;
222 dprintk("%s writing", __FUNCTION__);
223 for (i = 0; i < len; i++) {
224 dprintk(" 0x%02x", data[i]);
225 }
226 dprintk("\n");
227 }
228 msleep(30);
229 for (cnt = 0; cnt < 4; cnt++) {
230 if ((err = i2c_transfer(state->i2c, &msg, 1)) < 0) {
231 dprintk("%s: write_dst error (err == %i, len == 0x%02x, b0 == 0x%02x)\n", __FUNCTION__, err, len, data[0]);
232 dst_i2c_disable(state);
233 msleep(500);
234 dst_i2c_enable(state);
235 msleep(500);
236 continue;
237 } else
238 break;
239 }
240 if (cnt >= 4)
241 return -EREMOTEIO;
242 return 0;
243}
244
245static int read_dst(struct dst_state *state, u8 * ret, u8 len)
246{
247 struct i2c_msg msg = {.addr = state->config->demod_address,.flags = I2C_M_RD,.buf = ret,.len = len };
248 int err;
249 int cnt;
250
251 for (cnt = 0; cnt < 4; cnt++) {
252 if ((err = i2c_transfer(state->i2c, &msg, 1)) < 0) {
253 dprintk("%s: read_dst error (err == %i, len == 0x%02x, b0 == 0x%02x)\n", __FUNCTION__, err, len, ret[0]);
254 dst_i2c_disable(state);
255 dst_i2c_enable(state);
256 continue;
257 } else
258 break;
259 }
260 if (cnt >= 4)
261 return -EREMOTEIO;
262 dprintk("%s reply is 0x%x\n", __FUNCTION__, ret[0]);
263 if (dst_debug && dst_verbose) {
264 for (err = 1; err < len; err++)
265 dprintk(" 0x%x", ret[err]);
266 if (err > 1)
267 dprintk("\n");
268 }
269 return 0;
270}
271
272static int dst_set_freq(struct dst_state *state, u32 freq)
273{
274 u8 *val;
275
276 state->frequency = freq;
277
278 // dprintk("%s: set frequency %u\n", __FUNCTION__, freq);
279 if (state->dst_type == DST_TYPE_IS_SAT) {
280 freq = freq / 1000;
281 if (freq < 950 || freq > 2150)
282 return -EINVAL;
283 val = &state->tx_tuna[0];
284 val[2] = (freq >> 8) & 0x7f;
285 val[3] = (u8) freq;
286 val[4] = 1;
287 val[8] &= ~4;
288 if (freq < 1531)
289 val[8] |= 4;
290 } else if (state->dst_type == DST_TYPE_IS_TERR) {
291 freq = freq / 1000;
292 if (freq < 137000 || freq > 858000)
293 return -EINVAL;
294 val = &state->tx_tuna[0];
295 val[2] = (freq >> 16) & 0xff;
296 val[3] = (freq >> 8) & 0xff;
297 val[4] = (u8) freq;
298 val[5] = 0;
299 switch (state->bandwidth) {
300 case BANDWIDTH_6_MHZ:
301 val[6] = 6;
302 break;
303
304 case BANDWIDTH_7_MHZ:
305 case BANDWIDTH_AUTO:
306 val[6] = 7;
307 break;
308
309 case BANDWIDTH_8_MHZ:
310 val[6] = 8;
311 break;
312 }
313
314 val[7] = 0;
315 val[8] = 0;
316 } else if (state->dst_type == DST_TYPE_IS_CABLE) {
317 /* guess till will get one */
318 freq = freq / 1000;
319 val = &state->tx_tuna[0];
320 val[2] = (freq >> 16) & 0xff;
321 val[3] = (freq >> 8) & 0xff;
322 val[4] = (u8) freq;
323 } else
324 return -EINVAL;
325 return 0;
326}
327
328static int dst_set_bandwidth(struct dst_state* state, fe_bandwidth_t bandwidth)
329{
330 u8 *val;
331
332 state->bandwidth = bandwidth;
333
334 if (state->dst_type != DST_TYPE_IS_TERR)
335 return 0;
336
337 val = &state->tx_tuna[0];
338 switch (bandwidth) {
339 case BANDWIDTH_6_MHZ:
340 val[6] = 6;
341 break;
342
343 case BANDWIDTH_7_MHZ:
344 val[6] = 7;
345 break;
346
347 case BANDWIDTH_8_MHZ:
348 val[6] = 8;
349 break;
350
351 default:
352 return -EINVAL;
353 }
354 return 0;
355}
356
357static int dst_set_inversion(struct dst_state* state, fe_spectral_inversion_t inversion)
358{
359 u8 *val;
360
361 state->inversion = inversion;
362
363 val = &state->tx_tuna[0];
364
365 val[8] &= ~0x80;
366
367 switch (inversion) {
368 case INVERSION_OFF:
369 break;
370 case INVERSION_ON:
371 val[8] |= 0x80;
372 break;
373 default:
374 return -EINVAL;
375 }
376 return 0;
377}
378
379static int dst_set_fec(struct dst_state* state, fe_code_rate_t fec)
380{
381 state->fec = fec;
382 return 0;
383}
384
385static fe_code_rate_t dst_get_fec(struct dst_state* state)
386{
387 return state->fec;
388}
389
390static int dst_set_symbolrate(struct dst_state* state, u32 srate)
391{
392 u8 *val;
393 u32 symcalc;
394 u64 sval;
395
396 state->symbol_rate = srate;
397
398 if (state->dst_type == DST_TYPE_IS_TERR) {
399 return 0;
400 }
401 // dprintk("%s: set srate %u\n", __FUNCTION__, srate);
402 srate /= 1000;
403 val = &state->tx_tuna[0];
404
405 if (state->type_flags & DST_TYPE_HAS_SYMDIV) {
406 sval = srate;
407 sval <<= 20;
408 do_div(sval, 88000);
409 symcalc = (u32) sval;
410 // dprintk("%s: set symcalc %u\n", __FUNCTION__, symcalc);
411 val[5] = (u8) (symcalc >> 12);
412 val[6] = (u8) (symcalc >> 4);
413 val[7] = (u8) (symcalc << 4);
414 } else {
415 val[5] = (u8) (srate >> 16) & 0x7f;
416 val[6] = (u8) (srate >> 8);
417 val[7] = (u8) srate;
418 }
419 val[8] &= ~0x20;
420 if (srate > 8000)
421 val[8] |= 0x20;
422 return 0;
423}
424
425static u8 dst_check_sum(u8 * buf, u32 len)
426{
427 u32 i;
428 u8 val = 0;
429 if (!len)
430 return 0;
431 for (i = 0; i < len; i++) {
432 val += buf[i];
433 }
434 return ((~val) + 1);
435}
436
437struct dst_types {
438 char *mstr;
439 int offs;
440 u8 dst_type;
441 u32 type_flags;
442};
443
444static struct dst_types dst_tlist[] = {
445 {"DST-020", 0, DST_TYPE_IS_SAT, DST_TYPE_HAS_SYMDIV},
446 {"DST-030", 0, DST_TYPE_IS_SAT, DST_TYPE_HAS_TS204 | DST_TYPE_HAS_NEWTUNE},
447 {"DST-03T", 0, DST_TYPE_IS_SAT, DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_TS204},
448 {"DST-MOT", 0, DST_TYPE_IS_SAT, DST_TYPE_HAS_SYMDIV},
449 {"DST-CI", 1, DST_TYPE_IS_SAT, DST_TYPE_HAS_TS204 | DST_TYPE_HAS_NEWTUNE},
450 {"DSTMCI", 1, DST_TYPE_IS_SAT, DST_TYPE_HAS_NEWTUNE},
451 {"DSTFCI", 1, DST_TYPE_IS_SAT, DST_TYPE_HAS_NEWTUNE},
452 {"DCTNEW", 1, DST_TYPE_IS_CABLE, DST_TYPE_HAS_NEWTUNE},
453 {"DCT-CI", 1, DST_TYPE_IS_CABLE, DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_TS204},
454 {"DTTDIG", 1, DST_TYPE_IS_TERR, 0}
455};
456
457/* DCTNEW and DCT-CI are guesses */
458
459static void dst_type_flags_print(u32 type_flags)
460{
461 printk("DST type flags :");
462 if (type_flags & DST_TYPE_HAS_NEWTUNE)
463 printk(" 0x%x newtuner", DST_TYPE_HAS_NEWTUNE);
464 if (type_flags & DST_TYPE_HAS_TS204)
465 printk(" 0x%x ts204", DST_TYPE_HAS_TS204);
466 if (type_flags & DST_TYPE_HAS_SYMDIV)
467 printk(" 0x%x symdiv", DST_TYPE_HAS_SYMDIV);
468 printk("\n");
469}
470
471static int dst_type_print(u8 type)
472{
473 char *otype;
474 switch (type) {
475 case DST_TYPE_IS_SAT:
476 otype = "satellite";
477 break;
478 case DST_TYPE_IS_TERR:
479 otype = "terrestrial";
480 break;
481 case DST_TYPE_IS_CABLE:
482 otype = "cable";
483 break;
484 default:
485 printk("%s: invalid dst type %d\n", __FUNCTION__, type);
486 return -EINVAL;
487 }
488 printk("DST type : %s\n", otype);
489 return 0;
490}
491
492static int dst_check_ci(struct dst_state *state)
493{
494 u8 txbuf[8];
495 u8 rxbuf[8];
496 int retval;
497 int i;
498 struct dst_types *dsp;
499 u8 use_dst_type;
500 u32 use_type_flags;
501
502 memset(txbuf, 0, sizeof(txbuf));
503 txbuf[1] = 6;
504 txbuf[7] = dst_check_sum(txbuf, 7);
505
506 dst_i2c_enable(state);
507 dst_reset8820(state);
508 retval = write_dst(state, txbuf, 8);
509 if (retval < 0) {
510 dst_i2c_disable(state);
511 dprintk("%s: write not successful, maybe no card?\n", __FUNCTION__);
512 return retval;
513 }
514 msleep(3);
515 retval = read_dst(state, rxbuf, 1);
516 dst_i2c_disable(state);
517 if (retval < 0) {
518 dprintk("%s: read not successful, maybe no card?\n", __FUNCTION__);
519 return retval;
520 }
521 if (rxbuf[0] != 0xff) {
522 dprintk("%s: write reply not 0xff, not ci (%02x)\n", __FUNCTION__, rxbuf[0]);
523 return retval;
524 }
525 if (!dst_wait_dst_ready(state))
526 return 0;
527 // dst_i2c_enable(i2c); Dimitri
528 retval = read_dst(state, rxbuf, 8);
529 dst_i2c_disable(state);
530 if (retval < 0) {
531 dprintk("%s: read not successful\n", __FUNCTION__);
532 return retval;
533 }
534 if (rxbuf[7] != dst_check_sum(rxbuf, 7)) {
535 dprintk("%s: checksum failure\n", __FUNCTION__);
536 return retval;
537 }
538 rxbuf[7] = '\0';
539 for (i = 0, dsp = &dst_tlist[0]; i < sizeof(dst_tlist) / sizeof(dst_tlist[0]); i++, dsp++) {
540 if (!strncmp(&rxbuf[dsp->offs], dsp->mstr, strlen(dsp->mstr))) {
541 use_type_flags = dsp->type_flags;
542 use_dst_type = dsp->dst_type;
543 printk("%s: recognize %s\n", __FUNCTION__, dsp->mstr);
544 break;
545 }
546 }
547 if (i >= sizeof(dst_tlist) / sizeof(dst_tlist[0])) {
548 printk("%s: unable to recognize %s or %s\n", __FUNCTION__, &rxbuf[0], &rxbuf[1]);
549 printk("%s please email linux-dvb@linuxtv.org with this type in\n", __FUNCTION__);
550 use_dst_type = DST_TYPE_IS_SAT;
551 use_type_flags = DST_TYPE_HAS_SYMDIV;
552 }
553 dst_type_print(use_dst_type);
554
555 state->type_flags = use_type_flags;
556 state->dst_type = use_dst_type;
557 dst_type_flags_print(state->type_flags);
558
559 if (state->type_flags & DST_TYPE_HAS_TS204) {
560 dst_packsize(state, 204);
561 }
562 return 0;
563}
564
565static int dst_command(struct dst_state* state, u8 * data, u8 len)
566{
567 int retval;
568 u8 reply;
569
570 dst_i2c_enable(state);
571 dst_reset8820(state);
572 retval = write_dst(state, data, len);
573 if (retval < 0) {
574 dst_i2c_disable(state);
575 dprintk("%s: write not successful\n", __FUNCTION__);
576 return retval;
577 }
578 msleep(33);
579 retval = read_dst(state, &reply, 1);
580 dst_i2c_disable(state);
581 if (retval < 0) {
582 dprintk("%s: read verify not successful\n", __FUNCTION__);
583 return retval;
584 }
585 if (reply != 0xff) {
586 dprintk("%s: write reply not 0xff 0x%02x \n", __FUNCTION__, reply);
587 return 0;
588 }
589 if (len >= 2 && data[0] == 0 && (data[1] == 1 || data[1] == 3))
590 return 0;
591 if (!dst_wait_dst_ready(state))
592 return 0;
593 // dst_i2c_enable(i2c); Per dimitri
594 retval = read_dst(state, state->rxbuffer, 8);
595 dst_i2c_disable(state);
596 if (retval < 0) {
597 dprintk("%s: read not successful\n", __FUNCTION__);
598 return 0;
599 }
600 if (state->rxbuffer[7] != dst_check_sum(state->rxbuffer, 7)) {
601 dprintk("%s: checksum failure\n", __FUNCTION__);
602 return 0;
603 }
604 return 0;
605}
606
607static int dst_get_signal(struct dst_state* state)
608{
609 int retval;
610 u8 get_signal[] = { 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb };
611
612 if ((state->diseq_flags & ATTEMPT_TUNE) == 0) {
613 state->decode_lock = state->decode_strength = state->decode_snr = 0;
614 return 0;
615 }
616 if (0 == (state->diseq_flags & HAS_LOCK)) {
617 state->decode_lock = state->decode_strength = state->decode_snr = 0;
618 return 0;
619 }
620 if (time_after_eq(jiffies, state->cur_jiff + (HZ / 5))) {
621 retval = dst_command(state, get_signal, 8);
622 if (retval < 0)
623 return retval;
624 if (state->dst_type == DST_TYPE_IS_SAT) {
625 state->decode_lock = ((state->rxbuffer[6] & 0x10) == 0) ? 1 : 0;
626 state->decode_strength = state->rxbuffer[5] << 8;
627 state->decode_snr = state->rxbuffer[2] << 8 | state->rxbuffer[3];
628 } else if ((state->dst_type == DST_TYPE_IS_TERR) || (state->dst_type == DST_TYPE_IS_CABLE)) {
629 state->decode_lock = (state->rxbuffer[1]) ? 1 : 0;
630 state->decode_strength = state->rxbuffer[4] << 8;
631 state->decode_snr = state->rxbuffer[3] << 8;
632 }
633 state->cur_jiff = jiffies;
634 }
635 return 0;
636}
637
638static int dst_tone_power_cmd(struct dst_state* state)
639{
640 u8 paket[8] = { 0x00, 0x09, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00 };
641
642 if (state->dst_type == DST_TYPE_IS_TERR)
643 return 0;
644
645 if (state->voltage == SEC_VOLTAGE_OFF)
646 paket[4] = 0;
647 else
648 paket[4] = 1;
649 if (state->tone == SEC_TONE_ON)
650 paket[2] = state->k22;
651 else
652 paket[2] = 0;
653 paket[7] = dst_check_sum(&paket[0], 7);
654 dst_command(state, paket, 8);
655 return 0;
656}
657
658static int dst_get_tuna(struct dst_state* state)
659{
660 int retval;
661 if ((state->diseq_flags & ATTEMPT_TUNE) == 0)
662 return 0;
663 state->diseq_flags &= ~(HAS_LOCK);
664 if (!dst_wait_dst_ready(state))
665 return 0;
666 if (state->type_flags & DST_TYPE_HAS_NEWTUNE) {
667 /* how to get variable length reply ???? */
668 retval = read_dst(state, state->rx_tuna, 10);
669 } else {
670 retval = read_dst(state, &state->rx_tuna[2], 8);
671 }
672 if (retval < 0) {
673 dprintk("%s: read not successful\n", __FUNCTION__);
674 return 0;
675 }
676 if (state->type_flags & DST_TYPE_HAS_NEWTUNE) {
677 if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[0], 9)) {
678 dprintk("%s: checksum failure?\n", __FUNCTION__);
679 return 0;
680 }
681 } else {
682 if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[2], 7)) {
683 dprintk("%s: checksum failure?\n", __FUNCTION__);
684 return 0;
685 }
686 }
687 if (state->rx_tuna[2] == 0 && state->rx_tuna[3] == 0)
688 return 0;
689 state->decode_freq = ((state->rx_tuna[2] & 0x7f) << 8) + state->rx_tuna[3];
690
691 state->decode_lock = 1;
692 /*
693 dst->decode_n1 = (dst->rx_tuna[4] << 8) +
694 (dst->rx_tuna[5]);
695
696 dst->decode_n2 = (dst->rx_tuna[8] << 8) +
697 (dst->rx_tuna[7]);
698 */
699 state->diseq_flags |= HAS_LOCK;
700 /* dst->cur_jiff = jiffies; */
701 return 1;
702}
703
704static int dst_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage);
705
706static int dst_write_tuna(struct dvb_frontend* fe)
707{
708 struct dst_state* state = (struct dst_state*) fe->demodulator_priv;
709 int retval;
710 u8 reply;
711
712 dprintk("%s: type_flags 0x%x \n", __FUNCTION__, state->type_flags);
713 state->decode_freq = 0;
714 state->decode_lock = state->decode_strength = state->decode_snr = 0;
715 if (state->dst_type == DST_TYPE_IS_SAT) {
716 if (!(state->diseq_flags & HAS_POWER))
717 dst_set_voltage(fe, SEC_VOLTAGE_13);
718 }
719 state->diseq_flags &= ~(HAS_LOCK | ATTEMPT_TUNE);
720 dst_i2c_enable(state);
721 if (state->type_flags & DST_TYPE_HAS_NEWTUNE) {
722 dst_reset8820(state);
723 state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[0], 9);
724 retval = write_dst(state, &state->tx_tuna[0], 10);
725 } else {
726 state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[2], 7);
727 retval = write_dst(state, &state->tx_tuna[2], 8);
728 }
729 if (retval < 0) {
730 dst_i2c_disable(state);
731 dprintk("%s: write not successful\n", __FUNCTION__);
732 return retval;
733 }
734 msleep(3);
735 retval = read_dst(state, &reply, 1);
736 dst_i2c_disable(state);
737 if (retval < 0) {
738 dprintk("%s: read verify not successful\n", __FUNCTION__);
739 return retval;
740 }
741 if (reply != 0xff) {
742 dprintk("%s: write reply not 0xff 0x%02x \n", __FUNCTION__, reply);
743 return 0;
744 }
745 state->diseq_flags |= ATTEMPT_TUNE;
746 return dst_get_tuna(state);
747}
748
749/*
750 * line22k0 0x00, 0x09, 0x00, 0xff, 0x01, 0x00, 0x00, 0x00
751 * line22k1 0x00, 0x09, 0x01, 0xff, 0x01, 0x00, 0x00, 0x00
752 * line22k2 0x00, 0x09, 0x02, 0xff, 0x01, 0x00, 0x00, 0x00
753 * tone 0x00, 0x09, 0xff, 0x00, 0x01, 0x00, 0x00, 0x00
754 * data 0x00, 0x09, 0xff, 0x01, 0x01, 0x00, 0x00, 0x00
755 * power_off 0x00, 0x09, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00
756 * power_on 0x00, 0x09, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00
757 * Diseqc 1 0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf0, 0xec
758 * Diseqc 2 0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf4, 0xe8
759 * Diseqc 3 0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf8, 0xe4
760 * Diseqc 4 0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xfc, 0xe0
761 */
762
763static int dst_set_diseqc(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd)
764{
765 struct dst_state* state = (struct dst_state*) fe->demodulator_priv;
766 u8 paket[8] = { 0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf0, 0xec };
767
768 if (state->dst_type == DST_TYPE_IS_TERR)
769 return 0;
770
771 if (cmd->msg_len == 0 || cmd->msg_len > 4)
772 return -EINVAL;
773 memcpy(&paket[3], cmd->msg, cmd->msg_len);
774 paket[7] = dst_check_sum(&paket[0], 7);
775 dst_command(state, paket, 8);
776 return 0;
777}
778
779static int dst_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
780{
781 u8 *val;
782 int need_cmd;
783 struct dst_state* state = (struct dst_state*) fe->demodulator_priv;
784
785 state->voltage = voltage;
786
787 if (state->dst_type == DST_TYPE_IS_TERR)
788 return 0;
789
790 need_cmd = 0;
791 val = &state->tx_tuna[0];
792 val[8] &= ~0x40;
793 switch (voltage) {
794 case SEC_VOLTAGE_13:
795 if ((state->diseq_flags & HAS_POWER) == 0)
796 need_cmd = 1;
797 state->diseq_flags |= HAS_POWER;
798 break;
799 case SEC_VOLTAGE_18:
800 if ((state->diseq_flags & HAS_POWER) == 0)
801 need_cmd = 1;
802 state->diseq_flags |= HAS_POWER;
803 val[8] |= 0x40;
804 break;
805 case SEC_VOLTAGE_OFF:
806 need_cmd = 1;
807 state->diseq_flags &= ~(HAS_POWER | HAS_LOCK | ATTEMPT_TUNE);
808 break;
809 default:
810 return -EINVAL;
811 }
812 if (need_cmd) {
813 dst_tone_power_cmd(state);
814 }
815 return 0;
816}
817
818static int dst_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
819{
820 u8 *val;
821 struct dst_state* state = (struct dst_state*) fe->demodulator_priv;
822
823 state->tone = tone;
824
825 if (state->dst_type == DST_TYPE_IS_TERR)
826 return 0;
827
828 val = &state->tx_tuna[0];
829
830 val[8] &= ~0x1;
831
832 switch (tone) {
833 case SEC_TONE_OFF:
834 break;
835 case SEC_TONE_ON:
836 val[8] |= 1;
837 break;
838 default:
839 return -EINVAL;
840 }
841 dst_tone_power_cmd(state);
842 return 0;
843}
844
845static int dst_init(struct dvb_frontend* fe)
846{
847 struct dst_state* state = (struct dst_state*) fe->demodulator_priv;
848 static u8 ini_satci_tuna[] = { 9, 0, 3, 0xb6, 1, 0, 0x73, 0x21, 0, 0 };
849 static u8 ini_satfta_tuna[] = { 0, 0, 3, 0xb6, 1, 0x55, 0xbd, 0x50, 0, 0 };
850 static u8 ini_tvfta_tuna[] = { 0, 0, 3, 0xb6, 1, 7, 0x0, 0x0, 0, 0 };
851 static u8 ini_tvci_tuna[] = { 9, 0, 3, 0xb6, 1, 7, 0x0, 0x0, 0, 0 };
852 static u8 ini_cabfta_tuna[] = { 0, 0, 3, 0xb6, 1, 7, 0x0, 0x0, 0, 0 };
853 static u8 ini_cabci_tuna[] = { 9, 0, 3, 0xb6, 1, 7, 0x0, 0x0, 0, 0 };
854 state->inversion = INVERSION_ON;
855 state->voltage = SEC_VOLTAGE_13;
856 state->tone = SEC_TONE_OFF;
857 state->symbol_rate = 29473000;
858 state->fec = FEC_AUTO;
859 state->diseq_flags = 0;
860 state->k22 = 0x02;
861 state->bandwidth = BANDWIDTH_7_MHZ;
862 state->cur_jiff = jiffies;
863 if (state->dst_type == DST_TYPE_IS_SAT) {
864 state->frequency = 950000;
865 memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_NEWTUNE) ? ini_satci_tuna : ini_satfta_tuna), sizeof(ini_satfta_tuna));
866 } else if (state->dst_type == DST_TYPE_IS_TERR) {
867 state->frequency = 137000000;
868 memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_NEWTUNE) ? ini_tvci_tuna : ini_tvfta_tuna), sizeof(ini_tvfta_tuna));
869 } else if (state->dst_type == DST_TYPE_IS_CABLE) {
870 state->frequency = 51000000;
871 memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_NEWTUNE) ? ini_cabci_tuna : ini_cabfta_tuna), sizeof(ini_cabfta_tuna));
872 }
873
874 return 0;
875}
876
877static int dst_read_status(struct dvb_frontend* fe, fe_status_t* status)
878{
879 struct dst_state* state = (struct dst_state*) fe->demodulator_priv;
880
881 *status = 0;
882 if (state->diseq_flags & HAS_LOCK) {
883 dst_get_signal(state);
884 if (state->decode_lock)
885 *status |= FE_HAS_LOCK | FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_SYNC | FE_HAS_VITERBI;
886 }
887
888 return 0;
889}
890
891static int dst_read_signal_strength(struct dvb_frontend* fe, u16* strength)
892{
893 struct dst_state* state = (struct dst_state*) fe->demodulator_priv;
894
895 dst_get_signal(state);
896 *strength = state->decode_strength;
897
898 return 0;
899}
900
901static int dst_read_snr(struct dvb_frontend* fe, u16* snr)
902{
903 struct dst_state* state = (struct dst_state*) fe->demodulator_priv;
904
905 dst_get_signal(state);
906 *snr = state->decode_snr;
907
908 return 0;
909}
910
911static int dst_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
912{
913 struct dst_state* state = (struct dst_state*) fe->demodulator_priv;
914
915 dst_set_freq(state, p->frequency);
916 dst_set_inversion(state, p->inversion);
917 if (state->dst_type == DST_TYPE_IS_SAT) {
918 dst_set_fec(state, p->u.qpsk.fec_inner);
919 dst_set_symbolrate(state, p->u.qpsk.symbol_rate);
920 } else if (state->dst_type == DST_TYPE_IS_TERR) {
921 dst_set_bandwidth(state, p->u.ofdm.bandwidth);
922 } else if (state->dst_type == DST_TYPE_IS_CABLE) {
923 dst_set_fec(state, p->u.qam.fec_inner);
924 dst_set_symbolrate(state, p->u.qam.symbol_rate);
925 }
926 dst_write_tuna(fe);
927
928 return 0;
929}
930
931static int dst_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
932{
933 struct dst_state* state = (struct dst_state*) fe->demodulator_priv;
934
935 p->frequency = state->decode_freq;
936 p->inversion = state->inversion;
937 if (state->dst_type == DST_TYPE_IS_SAT) {
938 p->u.qpsk.symbol_rate = state->symbol_rate;
939 p->u.qpsk.fec_inner = dst_get_fec(state);
940 } else if (state->dst_type == DST_TYPE_IS_TERR) {
941 p->u.ofdm.bandwidth = state->bandwidth;
942 } else if (state->dst_type == DST_TYPE_IS_CABLE) {
943 p->u.qam.symbol_rate = state->symbol_rate;
944 p->u.qam.fec_inner = dst_get_fec(state);
945 p->u.qam.modulation = QAM_AUTO;
946 }
947
948 return 0;
949}
950
951static void dst_release(struct dvb_frontend* fe)
952{
953 struct dst_state* state = (struct dst_state*) fe->demodulator_priv;
954 kfree(state);
955}
956
957static struct dvb_frontend_ops dst_dvbt_ops;
958static struct dvb_frontend_ops dst_dvbs_ops;
959static struct dvb_frontend_ops dst_dvbc_ops;
960
961struct dvb_frontend* dst_attach(const struct dst_config* config,
962 struct i2c_adapter* i2c,
963 struct bt878 *bt)
964{
965 struct dst_state* state = NULL;
966
967 /* allocate memory for the internal state */
968 state = (struct dst_state*) kmalloc(sizeof(struct dst_state), GFP_KERNEL);
969 if (state == NULL) goto error;
970
971 /* setup the state */
972 state->config = config;
973 state->i2c = i2c;
974 state->bt = bt;
975
976 /* check if the demod is there */
977 if (dst_check_ci(state) < 0) goto error;
978
979 /* determine settings based on type */
980 switch (state->dst_type) {
981 case DST_TYPE_IS_TERR:
982 memcpy(&state->ops, &dst_dvbt_ops, sizeof(struct dvb_frontend_ops));
983 break;
984 case DST_TYPE_IS_CABLE:
985 memcpy(&state->ops, &dst_dvbc_ops, sizeof(struct dvb_frontend_ops));
986 break;
987 case DST_TYPE_IS_SAT:
988 memcpy(&state->ops, &dst_dvbs_ops, sizeof(struct dvb_frontend_ops));
989 break;
990 default:
991 printk("dst: unknown frontend type. please report to the LinuxTV.org DVB mailinglist.\n");
992 goto error;
993 }
994
995 /* create dvb_frontend */
996 state->frontend.ops = &state->ops;
997 state->frontend.demodulator_priv = state;
998 return &state->frontend;
999
1000error:
1001 kfree(state);
1002 return NULL;
1003}
1004
1005static struct dvb_frontend_ops dst_dvbt_ops = {
1006
1007 .info = {
1008 .name = "DST DVB-T",
1009 .type = FE_OFDM,
1010 .frequency_min = 137000000,
1011 .frequency_max = 858000000,
1012 .frequency_stepsize = 166667,
1013 .caps = FE_CAN_FEC_AUTO | FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO
1014 },
1015
1016 .release = dst_release,
1017
1018 .init = dst_init,
1019
1020 .set_frontend = dst_set_frontend,
1021 .get_frontend = dst_get_frontend,
1022
1023 .read_status = dst_read_status,
1024 .read_signal_strength = dst_read_signal_strength,
1025 .read_snr = dst_read_snr,
1026};
1027
1028static struct dvb_frontend_ops dst_dvbs_ops = {
1029
1030 .info = {
1031 .name = "DST DVB-S",
1032 .type = FE_QPSK,
1033 .frequency_min = 950000,
1034 .frequency_max = 2150000,
1035 .frequency_stepsize = 1000, /* kHz for QPSK frontends */
1036 .frequency_tolerance = 29500,
1037 .symbol_rate_min = 1000000,
1038 .symbol_rate_max = 45000000,
1039 /* . symbol_rate_tolerance = ???,*/
1040 .caps = FE_CAN_FEC_AUTO | FE_CAN_QPSK
1041 },
1042
1043 .release = dst_release,
1044
1045 .init = dst_init,
1046
1047 .set_frontend = dst_set_frontend,
1048 .get_frontend = dst_get_frontend,
1049
1050 .read_status = dst_read_status,
1051 .read_signal_strength = dst_read_signal_strength,
1052 .read_snr = dst_read_snr,
1053
1054 .diseqc_send_master_cmd = dst_set_diseqc,
1055 .set_voltage = dst_set_voltage,
1056 .set_tone = dst_set_tone,
1057};
1058
1059static struct dvb_frontend_ops dst_dvbc_ops = {
1060
1061 .info = {
1062 .name = "DST DVB-C",
1063 .type = FE_QAM,
1064 .frequency_stepsize = 62500,
1065 .frequency_min = 51000000,
1066 .frequency_max = 858000000,
1067 .symbol_rate_min = 1000000,
1068 .symbol_rate_max = 45000000,
1069 /* . symbol_rate_tolerance = ???,*/
1070 .caps = FE_CAN_FEC_AUTO | FE_CAN_QAM_AUTO
1071 },
1072
1073 .release = dst_release,
1074
1075 .init = dst_init,
1076
1077 .set_frontend = dst_set_frontend,
1078 .get_frontend = dst_get_frontend,
1079
1080 .read_status = dst_read_status,
1081 .read_signal_strength = dst_read_signal_strength,
1082 .read_snr = dst_read_snr,
1083};
1084
1085MODULE_DESCRIPTION("DST DVB-S/T/C Combo Frontend driver");
1086MODULE_AUTHOR("Jamie Honan");
1087MODULE_LICENSE("GPL");
1088
1089EXPORT_SYMBOL(dst_attach);
diff --git a/drivers/media/dvb/bt8xx/dst.h b/drivers/media/dvb/bt8xx/dst.h
new file mode 100644
index 000000000000..bcb418c5c121
--- /dev/null
+++ b/drivers/media/dvb/bt8xx/dst.h
@@ -0,0 +1,40 @@
1/*
2 Frontend-driver for TwinHan DST Frontend
3
4 Copyright (C) 2003 Jamie Honan
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21*/
22
23#ifndef DST_H
24#define DST_H
25
26#include <linux/dvb/frontend.h>
27#include <linux/device.h>
28#include "bt878.h"
29
30struct dst_config
31{
32 /* the demodulator's i2c address */
33 u8 demod_address;
34};
35
36extern struct dvb_frontend* dst_attach(const struct dst_config* config,
37 struct i2c_adapter* i2c,
38 struct bt878 *bt);
39
40#endif // DST_H
diff --git a/drivers/media/dvb/bt8xx/dst_priv.h b/drivers/media/dvb/bt8xx/dst_priv.h
new file mode 100644
index 000000000000..80488aa628b4
--- /dev/null
+++ b/drivers/media/dvb/bt8xx/dst_priv.h
@@ -0,0 +1,36 @@
1/*
2 * dst-bt878.h: part of the DST driver for the TwinHan DST Frontend
3 *
4 * Copyright (C) 2003 Jamie Honan
5 */
6
7struct dst_gpio_enable {
8 u32 mask;
9 u32 enable;
10};
11
12struct dst_gpio_output {
13 u32 mask;
14 u32 highvals;
15};
16
17struct dst_gpio_read {
18 unsigned long value;
19};
20
21union dst_gpio_packet {
22 struct dst_gpio_enable enb;
23 struct dst_gpio_output outp;
24 struct dst_gpio_read rd;
25 int psize;
26};
27
28#define DST_IG_ENABLE 0
29#define DST_IG_WRITE 1
30#define DST_IG_READ 2
31#define DST_IG_TS 3
32
33struct bt878;
34
35int bt878_device_control(struct bt878 *bt, unsigned int cmd, union dst_gpio_packet *mp);
36
diff --git a/drivers/media/dvb/bt8xx/dvb-bt8xx.c b/drivers/media/dvb/bt8xx/dvb-bt8xx.c
new file mode 100644
index 000000000000..b735397f59aa
--- /dev/null
+++ b/drivers/media/dvb/bt8xx/dvb-bt8xx.c
@@ -0,0 +1,797 @@
1/*
2 * Bt8xx based DVB adapter driver
3 *
4 * Copyright (C) 2002,2003 Florian Schirmer <jolt@tuxbox.org>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 *
20 */
21
22#include <linux/bitops.h>
23#include <linux/module.h>
24#include <linux/moduleparam.h>
25#include <linux/init.h>
26#include <linux/device.h>
27#include <linux/delay.h>
28#include <linux/slab.h>
29#include <linux/i2c.h>
30
31#include "dmxdev.h"
32#include "dvbdev.h"
33#include "dvb_demux.h"
34#include "dvb_frontend.h"
35
36#include "dvb-bt8xx.h"
37
38#include "bt878.h"
39
40static int debug;
41
42module_param(debug, int, 0644);
43MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
44
45#define dprintk( args... ) \
46 do { \
47 if (debug) printk(KERN_DEBUG args); \
48 } while (0)
49
50static void dvb_bt8xx_task(unsigned long data)
51{
52 struct dvb_bt8xx_card *card = (struct dvb_bt8xx_card *)data;
53
54 //printk("%d ", card->bt->finished_block);
55
56 while (card->bt->last_block != card->bt->finished_block) {
57 (card->bt->TS_Size ? dvb_dmx_swfilter_204 : dvb_dmx_swfilter)
58 (&card->demux,
59 &card->bt->buf_cpu[card->bt->last_block *
60 card->bt->block_bytes],
61 card->bt->block_bytes);
62 card->bt->last_block = (card->bt->last_block + 1) %
63 card->bt->block_count;
64 }
65}
66
67static int dvb_bt8xx_start_feed(struct dvb_demux_feed *dvbdmxfeed)
68{
69 struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
70 struct dvb_bt8xx_card *card = dvbdmx->priv;
71 int rc;
72
73 dprintk("dvb_bt8xx: start_feed\n");
74
75 if (!dvbdmx->dmx.frontend)
76 return -EINVAL;
77
78 down(&card->lock);
79 card->nfeeds++;
80 rc = card->nfeeds;
81 if (card->nfeeds == 1)
82 bt878_start(card->bt, card->gpio_mode,
83 card->op_sync_orin, card->irq_err_ignore);
84 up(&card->lock);
85 return rc;
86}
87
88static int dvb_bt8xx_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
89{
90 struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
91 struct dvb_bt8xx_card *card = dvbdmx->priv;
92
93 dprintk("dvb_bt8xx: stop_feed\n");
94
95 if (!dvbdmx->dmx.frontend)
96 return -EINVAL;
97
98 down(&card->lock);
99 card->nfeeds--;
100 if (card->nfeeds == 0)
101 bt878_stop(card->bt);
102 up(&card->lock);
103
104 return 0;
105}
106
107static int is_pci_slot_eq(struct pci_dev* adev, struct pci_dev* bdev)
108{
109 if ((adev->subsystem_vendor == bdev->subsystem_vendor) &&
110 (adev->subsystem_device == bdev->subsystem_device) &&
111 (adev->bus->number == bdev->bus->number) &&
112 (PCI_SLOT(adev->devfn) == PCI_SLOT(bdev->devfn)))
113 return 1;
114 return 0;
115}
116
117static struct bt878 __init *dvb_bt8xx_878_match(unsigned int bttv_nr, struct pci_dev* bttv_pci_dev)
118{
119 unsigned int card_nr;
120
121 /* Hmm, n squared. Hope n is small */
122 for (card_nr = 0; card_nr < bt878_num; card_nr++) {
123 if (is_pci_slot_eq(bt878[card_nr].dev, bttv_pci_dev))
124 return &bt878[card_nr];
125 }
126 return NULL;
127}
128
129
130static int thomson_dtt7579_demod_init(struct dvb_frontend* fe)
131{
132 static u8 mt352_clock_config [] = { 0x89, 0x38, 0x38 };
133 static u8 mt352_reset [] = { 0x50, 0x80 };
134 static u8 mt352_adc_ctl_1_cfg [] = { 0x8E, 0x40 };
135 static u8 mt352_agc_cfg [] = { 0x67, 0x28, 0x20 };
136 static u8 mt352_gpp_ctl_cfg [] = { 0x8C, 0x33 };
137 static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 };
138
139 mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config));
140 udelay(2000);
141 mt352_write(fe, mt352_reset, sizeof(mt352_reset));
142 mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg));
143
144 mt352_write(fe, mt352_agc_cfg, sizeof(mt352_agc_cfg));
145 mt352_write(fe, mt352_gpp_ctl_cfg, sizeof(mt352_gpp_ctl_cfg));
146 mt352_write(fe, mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg));
147
148 return 0;
149}
150
151static int thomson_dtt7579_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u8* pllbuf)
152{
153 u32 div;
154 unsigned char bs = 0;
155 unsigned char cp = 0;
156
157 #define IF_FREQUENCYx6 217 /* 6 * 36.16666666667MHz */
158 div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6;
159
160 if (params->frequency < 542000000) cp = 0xb4;
161 else if (params->frequency < 771000000) cp = 0xbc;
162 else cp = 0xf4;
163
164 if (params->frequency == 0) bs = 0x03;
165 else if (params->frequency < 443250000) bs = 0x02;
166 else bs = 0x08;
167
168 pllbuf[0] = 0xc0; // Note: non-linux standard PLL i2c address
169 pllbuf[1] = div >> 8;
170 pllbuf[2] = div & 0xff;
171 pllbuf[3] = cp;
172 pllbuf[4] = bs;
173
174 return 0;
175}
176
177static struct mt352_config thomson_dtt7579_config = {
178
179 .demod_address = 0x0f,
180 .demod_init = thomson_dtt7579_demod_init,
181 .pll_set = thomson_dtt7579_pll_set,
182};
183
184static int cx24108_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
185{
186 u32 freq = params->frequency;
187
188 int i, a, n, pump;
189 u32 band, pll;
190
191
192 u32 osci[]={950000,1019000,1075000,1178000,1296000,1432000,
193 1576000,1718000,1856000,2036000,2150000};
194 u32 bandsel[]={0,0x00020000,0x00040000,0x00100800,0x00101000,
195 0x00102000,0x00104000,0x00108000,0x00110000,
196 0x00120000,0x00140000};
197
198#define XTAL 1011100 /* Hz, really 1.0111 MHz and a /10 prescaler */
199 printk("cx24108 debug: entering SetTunerFreq, freq=%d\n",freq);
200
201 /* This is really the bit driving the tuner chip cx24108 */
202
203 if(freq<950000) freq=950000; /* kHz */
204 if(freq>2150000) freq=2150000; /* satellite IF is 950..2150MHz */
205
206 /* decide which VCO to use for the input frequency */
207 for(i=1;(i<sizeof(osci)/sizeof(osci[0]))&&(osci[i]<freq);i++);
208 printk("cx24108 debug: select vco #%d (f=%d)\n",i,freq);
209 band=bandsel[i];
210 /* the gain values must be set by SetSymbolrate */
211 /* compute the pll divider needed, from Conexant data sheet,
212 resolved for (n*32+a), remember f(vco) is f(receive) *2 or *4,
213 depending on the divider bit. It is set to /4 on the 2 lowest
214 bands */
215 n=((i<=2?2:1)*freq*10L)/(XTAL/100);
216 a=n%32; n/=32; if(a==0) n--;
217 pump=(freq<(osci[i-1]+osci[i])/2);
218 pll=0xf8000000|
219 ((pump?1:2)<<(14+11))|
220 ((n&0x1ff)<<(5+11))|
221 ((a&0x1f)<<11);
222 /* everything is shifted left 11 bits to left-align the bits in the
223 32bit word. Output to the tuner goes MSB-aligned, after all */
224 printk("cx24108 debug: pump=%d, n=%d, a=%d\n",pump,n,a);
225 cx24110_pll_write(fe,band);
226 /* set vga and vca to their widest-band settings, as a precaution.
227 SetSymbolrate might not be called to set this up */
228 cx24110_pll_write(fe,0x500c0000);
229 cx24110_pll_write(fe,0x83f1f800);
230 cx24110_pll_write(fe,pll);
231/* writereg(client,0x56,0x7f);*/
232
233 return 0;
234}
235
236static int pinnsat_pll_init(struct dvb_frontend* fe)
237{
238 return 0;
239}
240
241
242static struct cx24110_config pctvsat_config = {
243
244 .demod_address = 0x55,
245 .pll_init = pinnsat_pll_init,
246 .pll_set = cx24108_pll_set,
247};
248
249
250static int microtune_mt7202dtf_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
251{
252 struct dvb_bt8xx_card *card = (struct dvb_bt8xx_card *) fe->dvb->priv;
253 u8 cfg, cpump, band_select;
254 u8 data[4];
255 u32 div;
256 struct i2c_msg msg = { .addr = 0x60, .flags = 0, .buf = data, .len = sizeof(data) };
257
258 div = (36000000 + params->frequency + 83333) / 166666;
259 cfg = 0x88;
260
261 if (params->frequency < 175000000) cpump = 2;
262 else if (params->frequency < 390000000) cpump = 1;
263 else if (params->frequency < 470000000) cpump = 2;
264 else if (params->frequency < 750000000) cpump = 2;
265 else cpump = 3;
266
267 if (params->frequency < 175000000) band_select = 0x0e;
268 else if (params->frequency < 470000000) band_select = 0x05;
269 else band_select = 0x03;
270
271 data[0] = (div >> 8) & 0x7f;
272 data[1] = div & 0xff;
273 data[2] = ((div >> 10) & 0x60) | cfg;
274 data[3] = cpump | band_select;
275
276 i2c_transfer(card->i2c_adapter, &msg, 1);
277 return (div * 166666 - 36000000);
278}
279
280static int microtune_mt7202dtf_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name)
281{
282 struct dvb_bt8xx_card* bt = (struct dvb_bt8xx_card*) fe->dvb->priv;
283
284 return request_firmware(fw, name, &bt->bt->dev->dev);
285}
286
287static struct sp887x_config microtune_mt7202dtf_config = {
288
289 .demod_address = 0x70,
290 .pll_set = microtune_mt7202dtf_pll_set,
291 .request_firmware = microtune_mt7202dtf_request_firmware,
292};
293
294
295
296static int advbt771_samsung_tdtc9251dh0_demod_init(struct dvb_frontend* fe)
297{
298 static u8 mt352_clock_config [] = { 0x89, 0x38, 0x2d };
299 static u8 mt352_reset [] = { 0x50, 0x80 };
300 static u8 mt352_adc_ctl_1_cfg [] = { 0x8E, 0x40 };
301 static u8 mt352_agc_cfg [] = { 0x67, 0x10, 0x23, 0x00, 0xFF, 0xFF,
302 0x00, 0xFF, 0x00, 0x40, 0x40 };
303 static u8 mt352_av771_extra[] = { 0xB5, 0x7A };
304 static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 };
305
306
307 mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config));
308 udelay(2000);
309 mt352_write(fe, mt352_reset, sizeof(mt352_reset));
310 mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg));
311
312 mt352_write(fe, mt352_agc_cfg,sizeof(mt352_agc_cfg));
313 udelay(2000);
314 mt352_write(fe, mt352_av771_extra,sizeof(mt352_av771_extra));
315 mt352_write(fe, mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg));
316
317 return 0;
318}
319
320static int advbt771_samsung_tdtc9251dh0_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u8* pllbuf)
321{
322 u32 div;
323 unsigned char bs = 0;
324 unsigned char cp = 0;
325
326 #define IF_FREQUENCYx6 217 /* 6 * 36.16666666667MHz */
327 div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6;
328
329 if (params->frequency < 150000000) cp = 0xB4;
330 else if (params->frequency < 173000000) cp = 0xBC;
331 else if (params->frequency < 250000000) cp = 0xB4;
332 else if (params->frequency < 400000000) cp = 0xBC;
333 else if (params->frequency < 420000000) cp = 0xF4;
334 else if (params->frequency < 470000000) cp = 0xFC;
335 else if (params->frequency < 600000000) cp = 0xBC;
336 else if (params->frequency < 730000000) cp = 0xF4;
337 else cp = 0xFC;
338
339 if (params->frequency < 150000000) bs = 0x01;
340 else if (params->frequency < 173000000) bs = 0x01;
341 else if (params->frequency < 250000000) bs = 0x02;
342 else if (params->frequency < 400000000) bs = 0x02;
343 else if (params->frequency < 420000000) bs = 0x02;
344 else if (params->frequency < 470000000) bs = 0x02;
345 else if (params->frequency < 600000000) bs = 0x08;
346 else if (params->frequency < 730000000) bs = 0x08;
347 else bs = 0x08;
348
349 pllbuf[0] = 0xc2; // Note: non-linux standard PLL i2c address
350 pllbuf[1] = div >> 8;
351 pllbuf[2] = div & 0xff;
352 pllbuf[3] = cp;
353 pllbuf[4] = bs;
354
355 return 0;
356}
357
358static struct mt352_config advbt771_samsung_tdtc9251dh0_config = {
359
360 .demod_address = 0x0f,
361 .demod_init = advbt771_samsung_tdtc9251dh0_demod_init,
362 .pll_set = advbt771_samsung_tdtc9251dh0_pll_set,
363};
364
365
366static struct dst_config dst_config = {
367
368 .demod_address = 0x55,
369};
370
371
372static int or51211_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name)
373{
374 struct dvb_bt8xx_card* bt = (struct dvb_bt8xx_card*) fe->dvb->priv;
375
376 return request_firmware(fw, name, &bt->bt->dev->dev);
377}
378
379static void or51211_setmode(struct dvb_frontend * fe, int mode)
380{
381 struct dvb_bt8xx_card *bt = fe->dvb->priv;
382 bttv_write_gpio(bt->bttv_nr, 0x0002, mode); /* Reset */
383 msleep(20);
384}
385
386static void or51211_reset(struct dvb_frontend * fe)
387{
388 struct dvb_bt8xx_card *bt = fe->dvb->priv;
389
390 /* RESET DEVICE
391 * reset is controled by GPIO-0
392 * when set to 0 causes reset and when to 1 for normal op
393 * must remain reset for 128 clock cycles on a 50Mhz clock
394 * also PRM1 PRM2 & PRM4 are controled by GPIO-1,GPIO-2 & GPIO-4
395 * We assume that the reset has be held low long enough or we
396 * have been reset by a power on. When the driver is unloaded
397 * reset set to 0 so if reloaded we have been reset.
398 */
399 /* reset & PRM1,2&4 are outputs */
400 int ret = bttv_gpio_enable(bt->bttv_nr, 0x001F, 0x001F);
401 if (ret != 0) {
402 printk(KERN_WARNING "or51211: Init Error - Can't Reset DVR "
403 "(%i)\n", ret);
404 }
405 bttv_write_gpio(bt->bttv_nr, 0x001F, 0x0000); /* Reset */
406 msleep(20);
407 /* Now set for normal operation */
408 bttv_write_gpio(bt->bttv_nr, 0x0001F, 0x0001);
409 /* wait for operation to begin */
410 msleep(500);
411}
412
413static void or51211_sleep(struct dvb_frontend * fe)
414{
415 struct dvb_bt8xx_card *bt = fe->dvb->priv;
416 bttv_write_gpio(bt->bttv_nr, 0x0001, 0x0000);
417}
418
419static struct or51211_config or51211_config = {
420
421 .demod_address = 0x15,
422 .request_firmware = or51211_request_firmware,
423 .setmode = or51211_setmode,
424 .reset = or51211_reset,
425 .sleep = or51211_sleep,
426};
427
428
429static int vp3021_alps_tded4_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
430{
431 struct dvb_bt8xx_card *card = (struct dvb_bt8xx_card *) fe->dvb->priv;
432 u8 buf[4];
433 u32 div;
434 struct i2c_msg msg = { .addr = 0x60, .flags = 0, .buf = buf, .len = sizeof(buf) };
435
436 div = (params->frequency + 36166667) / 166667;
437
438 buf[0] = (div >> 8) & 0x7F;
439 buf[1] = div & 0xFF;
440 buf[2] = 0x85;
441 if ((params->frequency >= 47000000) && (params->frequency < 153000000))
442 buf[3] = 0x01;
443 else if ((params->frequency >= 153000000) && (params->frequency < 430000000))
444 buf[3] = 0x02;
445 else if ((params->frequency >= 430000000) && (params->frequency < 824000000))
446 buf[3] = 0x0C;
447 else if ((params->frequency >= 824000000) && (params->frequency < 863000000))
448 buf[3] = 0x8C;
449 else
450 return -EINVAL;
451
452 i2c_transfer(card->i2c_adapter, &msg, 1);
453 return 0;
454}
455
456static struct nxt6000_config vp3021_alps_tded4_config = {
457
458 .demod_address = 0x0a,
459 .clock_inversion = 1,
460 .pll_set = vp3021_alps_tded4_pll_set,
461};
462
463
464static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
465{
466 switch(type) {
467#ifdef BTTV_DVICO_DVBT_LITE
468 case BTTV_DVICO_DVBT_LITE:
469 card->fe = mt352_attach(&thomson_dtt7579_config, card->i2c_adapter);
470 if (card->fe != NULL) {
471 card->fe->ops->info.frequency_min = 174000000;
472 card->fe->ops->info.frequency_max = 862000000;
473 break;
474 }
475 break;
476#endif
477
478#ifdef BTTV_TWINHAN_VP3021
479 case BTTV_TWINHAN_VP3021:
480#else
481 case BTTV_NEBULA_DIGITV:
482#endif
483 card->fe = nxt6000_attach(&vp3021_alps_tded4_config, card->i2c_adapter);
484 if (card->fe != NULL) {
485 break;
486 }
487 break;
488
489 case BTTV_AVDVBT_761:
490 card->fe = sp887x_attach(&microtune_mt7202dtf_config, card->i2c_adapter);
491 if (card->fe != NULL) {
492 break;
493 }
494 break;
495
496 case BTTV_AVDVBT_771:
497 card->fe = mt352_attach(&advbt771_samsung_tdtc9251dh0_config, card->i2c_adapter);
498 if (card->fe != NULL) {
499 card->fe->ops->info.frequency_min = 174000000;
500 card->fe->ops->info.frequency_max = 862000000;
501 break;
502 }
503 break;
504
505 case BTTV_TWINHAN_DST:
506 card->fe = dst_attach(&dst_config, card->i2c_adapter, card->bt);
507 if (card->fe != NULL) {
508 break;
509 }
510 break;
511
512 case BTTV_PINNACLESAT:
513 card->fe = cx24110_attach(&pctvsat_config, card->i2c_adapter);
514 if (card->fe != NULL) {
515 break;
516 }
517 break;
518
519 case BTTV_PC_HDTV:
520 card->fe = or51211_attach(&or51211_config, card->i2c_adapter);
521 if (card->fe != NULL) {
522 break;
523 }
524 break;
525 }
526
527 if (card->fe == NULL) {
528 printk("dvb-bt8xx: A frontend driver was not found for device %04x/%04x subsystem %04x/%04x\n",
529 card->bt->dev->vendor,
530 card->bt->dev->device,
531 card->bt->dev->subsystem_vendor,
532 card->bt->dev->subsystem_device);
533 } else {
534 if (dvb_register_frontend(card->dvb_adapter, card->fe)) {
535 printk("dvb-bt8xx: Frontend registration failed!\n");
536 if (card->fe->ops->release)
537 card->fe->ops->release(card->fe);
538 card->fe = NULL;
539 }
540 }
541}
542
543static int __init dvb_bt8xx_load_card(struct dvb_bt8xx_card *card, u32 type)
544{
545 int result;
546
547 if ((result = dvb_register_adapter(&card->dvb_adapter, card->card_name,
548 THIS_MODULE)) < 0) {
549 printk("dvb_bt8xx: dvb_register_adapter failed (errno = %d)\n", result);
550 return result;
551
552 }
553 card->dvb_adapter->priv = card;
554
555 card->bt->adapter = card->i2c_adapter;
556
557 memset(&card->demux, 0, sizeof(struct dvb_demux));
558
559 card->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING | DMX_MEMORY_BASED_FILTERING;
560
561 card->demux.priv = card;
562 card->demux.filternum = 256;
563 card->demux.feednum = 256;
564 card->demux.start_feed = dvb_bt8xx_start_feed;
565 card->demux.stop_feed = dvb_bt8xx_stop_feed;
566 card->demux.write_to_decoder = NULL;
567
568 if ((result = dvb_dmx_init(&card->demux)) < 0) {
569 printk("dvb_bt8xx: dvb_dmx_init failed (errno = %d)\n", result);
570
571 dvb_unregister_adapter(card->dvb_adapter);
572 return result;
573 }
574
575 card->dmxdev.filternum = 256;
576 card->dmxdev.demux = &card->demux.dmx;
577 card->dmxdev.capabilities = 0;
578
579 if ((result = dvb_dmxdev_init(&card->dmxdev, card->dvb_adapter)) < 0) {
580 printk("dvb_bt8xx: dvb_dmxdev_init failed (errno = %d)\n", result);
581
582 dvb_dmx_release(&card->demux);
583 dvb_unregister_adapter(card->dvb_adapter);
584 return result;
585 }
586
587 card->fe_hw.source = DMX_FRONTEND_0;
588
589 if ((result = card->demux.dmx.add_frontend(&card->demux.dmx, &card->fe_hw)) < 0) {
590 printk("dvb_bt8xx: dvb_dmx_init failed (errno = %d)\n", result);
591
592 dvb_dmxdev_release(&card->dmxdev);
593 dvb_dmx_release(&card->demux);
594 dvb_unregister_adapter(card->dvb_adapter);
595 return result;
596 }
597
598 card->fe_mem.source = DMX_MEMORY_FE;
599
600 if ((result = card->demux.dmx.add_frontend(&card->demux.dmx, &card->fe_mem)) < 0) {
601 printk("dvb_bt8xx: dvb_dmx_init failed (errno = %d)\n", result);
602
603 card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_hw);
604 dvb_dmxdev_release(&card->dmxdev);
605 dvb_dmx_release(&card->demux);
606 dvb_unregister_adapter(card->dvb_adapter);
607 return result;
608 }
609
610 if ((result = card->demux.dmx.connect_frontend(&card->demux.dmx, &card->fe_hw)) < 0) {
611 printk("dvb_bt8xx: dvb_dmx_init failed (errno = %d)\n", result);
612
613 card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_mem);
614 card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_hw);
615 dvb_dmxdev_release(&card->dmxdev);
616 dvb_dmx_release(&card->demux);
617 dvb_unregister_adapter(card->dvb_adapter);
618 return result;
619 }
620
621 dvb_net_init(card->dvb_adapter, &card->dvbnet, &card->demux.dmx);
622
623 tasklet_init(&card->bt->tasklet, dvb_bt8xx_task, (unsigned long) card);
624
625 frontend_init(card, type);
626
627 return 0;
628}
629
630static int dvb_bt8xx_probe(struct device *dev)
631{
632 struct bttv_sub_device *sub = to_bttv_sub_dev(dev);
633 struct dvb_bt8xx_card *card;
634 struct pci_dev* bttv_pci_dev;
635 int ret;
636
637 if (!(card = kmalloc(sizeof(struct dvb_bt8xx_card), GFP_KERNEL)))
638 return -ENOMEM;
639
640 memset(card, 0, sizeof(*card));
641 init_MUTEX(&card->lock);
642 card->bttv_nr = sub->core->nr;
643 strncpy(card->card_name, sub->core->name, sizeof(sub->core->name));
644 card->i2c_adapter = &sub->core->i2c_adap;
645
646 switch(sub->core->type)
647 {
648 case BTTV_PINNACLESAT:
649 card->gpio_mode = 0x0400c060;
650 /* should be: BT878_A_GAIN=0,BT878_A_PWRDN,BT878_DA_DPM,BT878_DA_SBR,
651 BT878_DA_IOM=1,BT878_DA_APP to enable serial highspeed mode. */
652 card->op_sync_orin = 0;
653 card->irq_err_ignore = 0;
654 break;
655
656#ifdef BTTV_DVICO_DVBT_LITE
657 case BTTV_DVICO_DVBT_LITE:
658#endif
659 card->gpio_mode = 0x0400C060;
660 card->op_sync_orin = 0;
661 card->irq_err_ignore = 0;
662 /* 26, 15, 14, 6, 5
663 * A_PWRDN DA_DPM DA_SBR DA_IOM_DA
664 * DA_APP(parallel) */
665 break;
666
667#ifdef BTTV_TWINHAN_VP3021
668 case BTTV_TWINHAN_VP3021:
669#else
670 case BTTV_NEBULA_DIGITV:
671#endif
672 case BTTV_AVDVBT_761:
673 card->gpio_mode = (1 << 26) | (1 << 14) | (1 << 5);
674 card->op_sync_orin = 0;
675 card->irq_err_ignore = 0;
676 /* A_PWRDN DA_SBR DA_APP (high speed serial) */
677 break;
678
679 case BTTV_AVDVBT_771: //case 0x07711461:
680 card->gpio_mode = 0x0400402B;
681 card->op_sync_orin = BT878_RISC_SYNC_MASK;
682 card->irq_err_ignore = 0;
683 /* A_PWRDN DA_SBR DA_APP[0] PKTP=10 RISC_ENABLE FIFO_ENABLE*/
684 break;
685
686 case BTTV_TWINHAN_DST:
687 card->gpio_mode = 0x2204f2c;
688 card->op_sync_orin = BT878_RISC_SYNC_MASK;
689 card->irq_err_ignore = BT878_APABORT | BT878_ARIPERR |
690 BT878_APPERR | BT878_AFBUS;
691 /* 25,21,14,11,10,9,8,3,2 then
692 * 0x33 = 5,4,1,0
693 * A_SEL=SML, DA_MLB, DA_SBR,
694 * DA_SDR=f, fifo trigger = 32 DWORDS
695 * IOM = 0 == audio A/D
696 * DPM = 0 == digital audio mode
697 * == async data parallel port
698 * then 0x33 (13 is set by start_capture)
699 * DA_APP = async data parallel port,
700 * ACAP_EN = 1,
701 * RISC+FIFO ENABLE */
702 break;
703
704 case BTTV_PC_HDTV:
705 card->gpio_mode = 0x0100EC7B;
706 card->op_sync_orin = 0;
707 card->irq_err_ignore = 0;
708 break;
709
710 default:
711 printk(KERN_WARNING "dvb_bt8xx: Unknown bttv card type: %d.\n",
712 sub->core->type);
713 kfree(card);
714 return -ENODEV;
715 }
716
717 dprintk("dvb_bt8xx: identified card%d as %s\n", card->bttv_nr, card->card_name);
718
719 if (!(bttv_pci_dev = bttv_get_pcidev(card->bttv_nr))) {
720 printk("dvb_bt8xx: no pci device for card %d\n", card->bttv_nr);
721 kfree(card);
722 return -EFAULT;
723 }
724
725 if (!(card->bt = dvb_bt8xx_878_match(card->bttv_nr, bttv_pci_dev))) {
726 printk("dvb_bt8xx: unable to determine DMA core of card %d,\n",
727 card->bttv_nr);
728 printk("dvb_bt8xx: if you have the ALSA bt87x audio driver "
729 "installed, try removing it.\n");
730
731 kfree(card);
732 return -EFAULT;
733
734 }
735
736 init_MUTEX(&card->bt->gpio_lock);
737 card->bt->bttv_nr = sub->core->nr;
738
739 if ( (ret = dvb_bt8xx_load_card(card, sub->core->type)) ) {
740 kfree(card);
741 return ret;
742 }
743
744 dev_set_drvdata(dev, card);
745 return 0;
746}
747
748static int dvb_bt8xx_remove(struct device *dev)
749{
750 struct dvb_bt8xx_card *card = dev_get_drvdata(dev);
751
752 dprintk("dvb_bt8xx: unloading card%d\n", card->bttv_nr);
753
754 bt878_stop(card->bt);
755 tasklet_kill(&card->bt->tasklet);
756 dvb_net_release(&card->dvbnet);
757 card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_mem);
758 card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_hw);
759 dvb_dmxdev_release(&card->dmxdev);
760 dvb_dmx_release(&card->demux);
761 if (card->fe) dvb_unregister_frontend(card->fe);
762 dvb_unregister_adapter(card->dvb_adapter);
763
764 kfree(card);
765
766 return 0;
767}
768
769static struct bttv_sub_driver driver = {
770 .drv = {
771 .name = "dvb-bt8xx",
772 .probe = dvb_bt8xx_probe,
773 .remove = dvb_bt8xx_remove,
774 /* FIXME:
775 * .shutdown = dvb_bt8xx_shutdown,
776 * .suspend = dvb_bt8xx_suspend,
777 * .resume = dvb_bt8xx_resume,
778 */
779 },
780};
781
782static int __init dvb_bt8xx_init(void)
783{
784 return bttv_sub_register(&driver, "dvb");
785}
786
787static void __exit dvb_bt8xx_exit(void)
788{
789 bttv_sub_unregister(&driver);
790}
791
792module_init(dvb_bt8xx_init);
793module_exit(dvb_bt8xx_exit);
794
795MODULE_DESCRIPTION("Bt8xx based DVB adapter driver");
796MODULE_AUTHOR("Florian Schirmer <jolt@tuxbox.org>");
797MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/bt8xx/dvb-bt8xx.h b/drivers/media/dvb/bt8xx/dvb-bt8xx.h
new file mode 100644
index 000000000000..80ef189f930f
--- /dev/null
+++ b/drivers/media/dvb/bt8xx/dvb-bt8xx.h
@@ -0,0 +1,59 @@
1/*
2 * Bt8xx based DVB adapter driver
3 *
4 * Copyright (C) 2002,2003 Florian Schirmer <jolt@tuxbox.org>
5 * Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@t-online.de>
6 * Copyright (C) 1999-2001 Ralph Metzler & Marcus Metzler for convergence integrated media GmbH
7 * Copyright (C) 1998,1999 Christian Theiss <mistert@rz.fh-augsburg.de>
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 DVB_BT8XX_H
26#define DVB_BT8XX_H
27
28#include <linux/i2c.h>
29#include "dvbdev.h"
30#include "dvb_net.h"
31#include "bttv.h"
32#include "mt352.h"
33#include "sp887x.h"
34#include "dst.h"
35#include "nxt6000.h"
36#include "cx24110.h"
37#include "or51211.h"
38
39struct dvb_bt8xx_card {
40 struct semaphore lock;
41 int nfeeds;
42 char card_name[32];
43 struct dvb_adapter *dvb_adapter;
44 struct bt878 *bt;
45 unsigned int bttv_nr;
46 struct dvb_demux demux;
47 struct dmxdev dmxdev;
48 struct dmx_frontend fe_hw;
49 struct dmx_frontend fe_mem;
50 u32 gpio_mode;
51 u32 op_sync_orin;
52 u32 irq_err_ignore;
53 struct i2c_adapter *i2c_adapter;
54 struct dvb_net dvbnet;
55
56 struct dvb_frontend* fe;
57};
58
59#endif /* DVB_BT8XX_H */
diff --git a/drivers/media/dvb/cinergyT2/Kconfig b/drivers/media/dvb/cinergyT2/Kconfig
new file mode 100644
index 000000000000..226714085f58
--- /dev/null
+++ b/drivers/media/dvb/cinergyT2/Kconfig
@@ -0,0 +1,85 @@
1config DVB_CINERGYT2
2 tristate "Terratec CinergyT2/qanu USB2 DVB-T receiver"
3 depends on DVB_CORE && USB
4 help
5 Support for "TerraTec CinergyT2" USB2.0 Highspeed DVB Receivers
6
7 Say Y if you own such a device and want to use it.
8
9
10config DVB_CINERGYT2_TUNING
11 bool "sophisticated fine-tuning for CinergyT2 cards"
12 depends on DVB_CINERGYT2
13 help
14 Here you can fine-tune some parameters of the CinergyT2 driver.
15
16 Normally you don't need to touch this, but in exotic setups you
17 may fine-tune your setup and adjust e.g. DMA buffer sizes for
18 a particular application.
19
20
21config DVB_CINERGYT2_STREAM_URB_COUNT
22 int "Number of queued USB Request Blocks for Highspeed Stream Transfers"
23 depends on DVB_CINERGYT2_TUNING
24 default "32"
25 help
26 USB Request Blocks for Highspeed Stream transfers are scheduled in
27 a queue for the Host Controller.
28
29 Usually the default value is a safe choice.
30
31 You may increase this number if you are using this device in a
32 Server Environment with many high-traffic USB Highspeed devices
33 sharing the same USB bus.
34
35
36config DVB_CINERGYT2_STREAM_BUF_SIZE
37 int "Size of URB Stream Buffers for Highspeed Transfers"
38 depends on DVB_CINERGYT2_TUNING
39 default "512"
40 help
41 Should be a multiple of native buffer size of 512 bytes.
42 Default value is a safe choice.
43
44 You may increase this number if you are using this device in a
45 Server Environment with many high-traffic USB Highspeed devices
46 sharing the same USB bus.
47
48
49config DVB_CINERGYT2_QUERY_INTERVAL
50 int "Status update interval [milliseconds]"
51 depends on DVB_CINERGYT2_TUNING
52 default "250"
53 help
54 This is the interval for status readouts from the demodulator.
55 You may try lower values if you need more responsive signal quality
56 measurements.
57
58 Please keep in mind that these updates cause traffic on the tuner
59 control bus and thus may or may not affect receiption sensitivity.
60
61 The default value should be a safe choice for common applications.
62
63
64config DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE
65 bool "Register the onboard IR Remote Control Receiver as Input Device"
66 depends on DVB_CINERGYT2_TUNING
67 default "yes"
68 help
69 Enable this option if you want to use the onboard Infrared Remote
70 Control Receiver as Linux-Input device.
71
72 Right now only the keycode table for the default Remote Control
73 delivered with the device is supported, please see the driver
74 source code to find out how to add support for other controls.
75
76
77config DVB_CINERGYT2_RC_QUERY_INTERVAL
78 int "Infrared Remote Controller update interval [milliseconds]"
79 depends on DVB_CINERGYT2_TUNING && DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE
80 default "100"
81 help
82 If you have a very fast-repeating remote control you can try lower
83 values, for normal consumer receivers the default value should be
84 a safe choice.
85
diff --git a/drivers/media/dvb/cinergyT2/Makefile b/drivers/media/dvb/cinergyT2/Makefile
new file mode 100644
index 000000000000..c51aece20f9f
--- /dev/null
+++ b/drivers/media/dvb/cinergyT2/Makefile
@@ -0,0 +1,3 @@
1obj-$(CONFIG_DVB_CINERGYT2) += cinergyT2.o
2
3EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/
diff --git a/drivers/media/dvb/cinergyT2/cinergyT2.c b/drivers/media/dvb/cinergyT2/cinergyT2.c
new file mode 100644
index 000000000000..f1f539761371
--- /dev/null
+++ b/drivers/media/dvb/cinergyT2/cinergyT2.c
@@ -0,0 +1,965 @@
1/*
2 * TerraTec Cinergy T²/qanu USB2 DVB-T adapter.
3 *
4 * Copyright (C) 2004 Daniel Mack <daniel@qanu.de> and
5 * Holger Waechtler <holger@qanu.de>
6 *
7 * Protocol Spec published on http://qanu.de/specs/terratec_cinergyT2.pdf
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#include <linux/config.h>
26#include <linux/init.h>
27#include <linux/module.h>
28#include <linux/version.h>
29#include <linux/slab.h>
30#include <linux/usb.h>
31#include <linux/pci.h>
32#include <linux/input.h>
33#include <linux/dvb/frontend.h>
34
35#include "dmxdev.h"
36#include "dvb_demux.h"
37#include "dvb_net.h"
38
39
40#ifdef CONFIG_DVB_CINERGYT2_TUNING
41 #define STREAM_URB_COUNT (CONFIG_DVB_CINERGYT2_STREAM_URB_COUNT)
42 #define STREAM_BUF_SIZE (CONFIG_DVB_CINERGYT2_STREAM_BUF_SIZE)
43 #define QUERY_INTERVAL (CONFIG_DVB_CINERGYT2_QUERY_INTERVAL)
44 #ifdef CONFIG_DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE
45 #define RC_QUERY_INTERVAL (CONFIG_DVB_CINERGYT2_RC_QUERY_INTERVAL)
46 #define ENABLE_RC (1)
47 #endif
48#else
49 #define STREAM_URB_COUNT (32)
50 #define STREAM_BUF_SIZE (512) /* bytes */
51 #define ENABLE_RC (1)
52 #define RC_QUERY_INTERVAL (100) /* milliseconds */
53 #define QUERY_INTERVAL (333) /* milliseconds */
54#endif
55
56#define DRIVER_NAME "TerraTec/qanu USB2.0 Highspeed DVB-T Receiver"
57
58static int debug;
59module_param_named(debug, debug, int, 0644);
60MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
61
62#define dprintk(level, args...) \
63do { \
64 if ((debug & level)) { \
65 printk("%s: %s(): ", __stringify(KBUILD_MODNAME), \
66 __FUNCTION__); \
67 printk(args); } \
68} while (0)
69
70enum cinergyt2_ep1_cmd {
71 CINERGYT2_EP1_PID_TABLE_RESET = 0x01,
72 CINERGYT2_EP1_PID_SETUP = 0x02,
73 CINERGYT2_EP1_CONTROL_STREAM_TRANSFER = 0x03,
74 CINERGYT2_EP1_SET_TUNER_PARAMETERS = 0x04,
75 CINERGYT2_EP1_GET_TUNER_STATUS = 0x05,
76 CINERGYT2_EP1_START_SCAN = 0x06,
77 CINERGYT2_EP1_CONTINUE_SCAN = 0x07,
78 CINERGYT2_EP1_GET_RC_EVENTS = 0x08,
79 CINERGYT2_EP1_SLEEP_MODE = 0x09
80};
81
82struct dvbt_set_parameters_msg {
83 uint8_t cmd;
84 uint32_t freq;
85 uint8_t bandwidth;
86 uint16_t tps;
87 uint8_t flags;
88} __attribute__((packed));
89
90struct dvbt_get_status_msg {
91 uint32_t freq;
92 uint8_t bandwidth;
93 uint16_t tps;
94 uint8_t flags;
95 uint16_t gain;
96 uint8_t snr;
97 uint32_t viterbi_error_rate;
98 uint32_t rs_error_rate;
99 uint32_t uncorrected_block_count;
100 uint8_t lock_bits;
101 uint8_t prev_lock_bits;
102} __attribute__((packed));
103
104static struct dvb_frontend_info cinergyt2_fe_info = {
105 .name = DRIVER_NAME,
106 .type = FE_OFDM,
107 .frequency_min = 174000000,
108 .frequency_max = 862000000,
109 .frequency_stepsize = 166667,
110 .caps = FE_CAN_INVERSION_AUTO | FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
111 FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
112 FE_CAN_FEC_AUTO |
113 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
114 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
115 FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER | FE_CAN_MUTE_TS
116};
117
118struct cinergyt2 {
119 struct dvb_demux demux;
120 struct usb_device *udev;
121 struct semaphore sem;
122 struct dvb_adapter *adapter;
123 struct dvb_device *fedev;
124 struct dmxdev dmxdev;
125 struct dvb_net dvbnet;
126
127 int streaming;
128 int sleeping;
129
130 struct dvbt_set_parameters_msg param;
131 struct dvbt_get_status_msg status;
132 struct work_struct query_work;
133
134 wait_queue_head_t poll_wq;
135 int pending_fe_events;
136
137 void *streambuf;
138 dma_addr_t streambuf_dmahandle;
139 struct urb *stream_urb [STREAM_URB_COUNT];
140
141#ifdef ENABLE_RC
142 struct input_dev rc_input_dev;
143 struct work_struct rc_query_work;
144 int rc_input_event;
145#endif
146};
147
148enum {
149 CINERGYT2_RC_EVENT_TYPE_NONE = 0x00,
150 CINERGYT2_RC_EVENT_TYPE_NEC = 0x01,
151 CINERGYT2_RC_EVENT_TYPE_RC5 = 0x02
152};
153
154struct cinergyt2_rc_event {
155 char type;
156 uint32_t value;
157} __attribute__((packed));
158
159static const uint32_t rc_keys [] = {
160 CINERGYT2_RC_EVENT_TYPE_NEC, 0xfe01eb04, KEY_POWER,
161 CINERGYT2_RC_EVENT_TYPE_NEC, 0xfd02eb04, KEY_1,
162 CINERGYT2_RC_EVENT_TYPE_NEC, 0xfc03eb04, KEY_2,
163 CINERGYT2_RC_EVENT_TYPE_NEC, 0xfb04eb04, KEY_3,
164 CINERGYT2_RC_EVENT_TYPE_NEC, 0xfa05eb04, KEY_4,
165 CINERGYT2_RC_EVENT_TYPE_NEC, 0xf906eb04, KEY_5,
166 CINERGYT2_RC_EVENT_TYPE_NEC, 0xf807eb04, KEY_6,
167 CINERGYT2_RC_EVENT_TYPE_NEC, 0xf708eb04, KEY_7,
168 CINERGYT2_RC_EVENT_TYPE_NEC, 0xf609eb04, KEY_8,
169 CINERGYT2_RC_EVENT_TYPE_NEC, 0xf50aeb04, KEY_9,
170 CINERGYT2_RC_EVENT_TYPE_NEC, 0xf30ceb04, KEY_0,
171 CINERGYT2_RC_EVENT_TYPE_NEC, 0xf40beb04, KEY_VIDEO,
172 CINERGYT2_RC_EVENT_TYPE_NEC, 0xf20deb04, KEY_REFRESH,
173 CINERGYT2_RC_EVENT_TYPE_NEC, 0xf10eeb04, KEY_SELECT,
174 CINERGYT2_RC_EVENT_TYPE_NEC, 0xf00feb04, KEY_EPG,
175 CINERGYT2_RC_EVENT_TYPE_NEC, 0xef10eb04, KEY_UP,
176 CINERGYT2_RC_EVENT_TYPE_NEC, 0xeb14eb04, KEY_DOWN,
177 CINERGYT2_RC_EVENT_TYPE_NEC, 0xee11eb04, KEY_LEFT,
178 CINERGYT2_RC_EVENT_TYPE_NEC, 0xec13eb04, KEY_RIGHT,
179 CINERGYT2_RC_EVENT_TYPE_NEC, 0xed12eb04, KEY_OK,
180 CINERGYT2_RC_EVENT_TYPE_NEC, 0xea15eb04, KEY_TEXT,
181 CINERGYT2_RC_EVENT_TYPE_NEC, 0xe916eb04, KEY_INFO,
182 CINERGYT2_RC_EVENT_TYPE_NEC, 0xe817eb04, KEY_RED,
183 CINERGYT2_RC_EVENT_TYPE_NEC, 0xe718eb04, KEY_GREEN,
184 CINERGYT2_RC_EVENT_TYPE_NEC, 0xe619eb04, KEY_YELLOW,
185 CINERGYT2_RC_EVENT_TYPE_NEC, 0xe51aeb04, KEY_BLUE,
186 CINERGYT2_RC_EVENT_TYPE_NEC, 0xe31ceb04, KEY_VOLUMEUP,
187 CINERGYT2_RC_EVENT_TYPE_NEC, 0xe11eeb04, KEY_VOLUMEDOWN,
188 CINERGYT2_RC_EVENT_TYPE_NEC, 0xe21deb04, KEY_MUTE,
189 CINERGYT2_RC_EVENT_TYPE_NEC, 0xe41beb04, KEY_CHANNELUP,
190 CINERGYT2_RC_EVENT_TYPE_NEC, 0xe01feb04, KEY_CHANNELDOWN,
191 CINERGYT2_RC_EVENT_TYPE_NEC, 0xbf40eb04, KEY_PAUSE,
192 CINERGYT2_RC_EVENT_TYPE_NEC, 0xb34ceb04, KEY_PLAY,
193 CINERGYT2_RC_EVENT_TYPE_NEC, 0xa758eb04, KEY_RECORD,
194 CINERGYT2_RC_EVENT_TYPE_NEC, 0xab54eb04, KEY_PREVIOUS,
195 CINERGYT2_RC_EVENT_TYPE_NEC, 0xb748eb04, KEY_STOP,
196 CINERGYT2_RC_EVENT_TYPE_NEC, 0xa35ceb04, KEY_NEXT
197};
198
199static int cinergyt2_command (struct cinergyt2 *cinergyt2,
200 char *send_buf, int send_buf_len,
201 char *recv_buf, int recv_buf_len)
202{
203 int actual_len;
204 char dummy;
205 int ret;
206
207 ret = usb_bulk_msg(cinergyt2->udev, usb_sndbulkpipe(cinergyt2->udev, 1),
208 send_buf, send_buf_len, &actual_len, 1000);
209
210 if (ret)
211 dprintk(1, "usb_bulk_msg (send) failed, err %i\n", ret);
212
213 if (!recv_buf)
214 recv_buf = &dummy;
215
216 ret = usb_bulk_msg(cinergyt2->udev, usb_rcvbulkpipe(cinergyt2->udev, 1),
217 recv_buf, recv_buf_len, &actual_len, 1000);
218
219 if (ret)
220 dprintk(1, "usb_bulk_msg (read) failed, err %i\n", ret);
221
222 return ret ? ret : actual_len;
223}
224
225static void cinergyt2_control_stream_transfer (struct cinergyt2 *cinergyt2, int enable)
226{
227 char buf [] = { CINERGYT2_EP1_CONTROL_STREAM_TRANSFER, enable ? 1 : 0 };
228 cinergyt2_command(cinergyt2, buf, sizeof(buf), NULL, 0);
229}
230
231static void cinergyt2_sleep (struct cinergyt2 *cinergyt2, int sleep)
232{
233 char buf [] = { CINERGYT2_EP1_SLEEP_MODE, sleep ? 1 : 0 };
234 cinergyt2_command(cinergyt2, buf, sizeof(buf), NULL, 0);
235 cinergyt2->sleeping = sleep;
236}
237
238static void cinergyt2_stream_irq (struct urb *urb, struct pt_regs *regs);
239
240static int cinergyt2_submit_stream_urb (struct cinergyt2 *cinergyt2, struct urb *urb)
241{
242 int err;
243
244 usb_fill_bulk_urb(urb,
245 cinergyt2->udev,
246 usb_rcvbulkpipe(cinergyt2->udev, 0x2),
247 urb->transfer_buffer,
248 STREAM_BUF_SIZE,
249 cinergyt2_stream_irq,
250 cinergyt2);
251
252 if ((err = usb_submit_urb(urb, GFP_ATOMIC)))
253 dprintk(1, "urb submission failed (err = %i)!\n", err);
254
255 return err;
256}
257
258static void cinergyt2_stream_irq (struct urb *urb, struct pt_regs *regs)
259{
260 struct cinergyt2 *cinergyt2 = urb->context;
261
262 if (urb->actual_length > 0)
263 dvb_dmx_swfilter(&cinergyt2->demux,
264 urb->transfer_buffer, urb->actual_length);
265
266 if (cinergyt2->streaming)
267 cinergyt2_submit_stream_urb(cinergyt2, urb);
268}
269
270static void cinergyt2_free_stream_urbs (struct cinergyt2 *cinergyt2)
271{
272 int i;
273
274 for (i=0; i<STREAM_URB_COUNT; i++)
275 if (cinergyt2->stream_urb[i])
276 usb_free_urb(cinergyt2->stream_urb[i]);
277
278 pci_free_consistent(NULL, STREAM_URB_COUNT*STREAM_BUF_SIZE,
279 cinergyt2->streambuf, cinergyt2->streambuf_dmahandle);
280}
281
282static int cinergyt2_alloc_stream_urbs (struct cinergyt2 *cinergyt2)
283{
284 int i;
285
286 cinergyt2->streambuf = pci_alloc_consistent(NULL,
287 STREAM_URB_COUNT*STREAM_BUF_SIZE,
288 &cinergyt2->streambuf_dmahandle);
289 if (!cinergyt2->streambuf) {
290 dprintk(1, "failed to alloc consistent stream memory area, bailing out!\n");
291 return -ENOMEM;
292 }
293
294 memset(cinergyt2->streambuf, 0, STREAM_URB_COUNT*STREAM_BUF_SIZE);
295
296 for (i=0; i<STREAM_URB_COUNT; i++) {
297 struct urb *urb;
298
299 if (!(urb = usb_alloc_urb(0, GFP_ATOMIC))) {
300 dprintk(1, "failed to alloc consistent stream urbs, bailing out!\n");
301 cinergyt2_free_stream_urbs(cinergyt2);
302 return -ENOMEM;
303 }
304
305 urb->transfer_buffer = cinergyt2->streambuf + i * STREAM_BUF_SIZE;
306 urb->transfer_buffer_length = STREAM_BUF_SIZE;
307
308 cinergyt2->stream_urb[i] = urb;
309 }
310
311 return 0;
312}
313
314static void cinergyt2_stop_stream_xfer (struct cinergyt2 *cinergyt2)
315{
316 int i;
317
318 cinergyt2_control_stream_transfer(cinergyt2, 0);
319
320 for (i=0; i<STREAM_URB_COUNT; i++)
321 if (cinergyt2->stream_urb[i])
322 usb_kill_urb(cinergyt2->stream_urb[i]);
323}
324
325static int cinergyt2_start_stream_xfer (struct cinergyt2 *cinergyt2)
326{
327 int i, err;
328
329 for (i=0; i<STREAM_URB_COUNT; i++) {
330 if ((err = cinergyt2_submit_stream_urb(cinergyt2, cinergyt2->stream_urb[i]))) {
331 cinergyt2_stop_stream_xfer(cinergyt2);
332 dprintk(1, "failed urb submission (%i: err = %i)!\n", i, err);
333 return err;
334 }
335 }
336
337 cinergyt2_control_stream_transfer(cinergyt2, 1);
338 return 0;
339}
340
341static int cinergyt2_start_feed(struct dvb_demux_feed *dvbdmxfeed)
342{
343 struct dvb_demux *demux = dvbdmxfeed->demux;
344 struct cinergyt2 *cinergyt2 = demux->priv;
345
346 if (down_interruptible(&cinergyt2->sem))
347 return -ERESTARTSYS;
348
349 if (cinergyt2->streaming == 0)
350 cinergyt2_start_stream_xfer(cinergyt2);
351
352 cinergyt2->streaming++;
353 up(&cinergyt2->sem);
354 return 0;
355}
356
357static int cinergyt2_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
358{
359 struct dvb_demux *demux = dvbdmxfeed->demux;
360 struct cinergyt2 *cinergyt2 = demux->priv;
361
362 if (down_interruptible(&cinergyt2->sem))
363 return -ERESTARTSYS;
364
365 if (--cinergyt2->streaming == 0)
366 cinergyt2_stop_stream_xfer(cinergyt2);
367
368 up(&cinergyt2->sem);
369 return 0;
370}
371
372/**
373 * convert linux-dvb frontend parameter set into TPS.
374 * See ETSI ETS-300744, section 4.6.2, table 9 for details.
375 *
376 * This function is probably reusable and may better get placed in a support
377 * library.
378 *
379 * We replace errornous fields by default TPS fields (the ones with value 0).
380 */
381static uint16_t compute_tps (struct dvb_frontend_parameters *p)
382{
383 struct dvb_ofdm_parameters *op = &p->u.ofdm;
384 uint16_t tps = 0;
385
386 switch (op->code_rate_HP) {
387 case FEC_2_3:
388 tps |= (1 << 7);
389 break;
390 case FEC_3_4:
391 tps |= (2 << 7);
392 break;
393 case FEC_5_6:
394 tps |= (3 << 7);
395 break;
396 case FEC_7_8:
397 tps |= (4 << 7);
398 break;
399 case FEC_1_2:
400 case FEC_AUTO:
401 default:
402 /* tps |= (0 << 7) */;
403 }
404
405 switch (op->code_rate_LP) {
406 case FEC_2_3:
407 tps |= (1 << 4);
408 break;
409 case FEC_3_4:
410 tps |= (2 << 4);
411 break;
412 case FEC_5_6:
413 tps |= (3 << 4);
414 break;
415 case FEC_7_8:
416 tps |= (4 << 4);
417 break;
418 case FEC_1_2:
419 case FEC_AUTO:
420 default:
421 /* tps |= (0 << 4) */;
422 }
423
424 switch (op->constellation) {
425 case QAM_16:
426 tps |= (1 << 13);
427 break;
428 case QAM_64:
429 tps |= (2 << 13);
430 break;
431 case QPSK:
432 default:
433 /* tps |= (0 << 13) */;
434 }
435
436 switch (op->transmission_mode) {
437 case TRANSMISSION_MODE_8K:
438 tps |= (1 << 0);
439 break;
440 case TRANSMISSION_MODE_2K:
441 default:
442 /* tps |= (0 << 0) */;
443 }
444
445 switch (op->guard_interval) {
446 case GUARD_INTERVAL_1_16:
447 tps |= (1 << 2);
448 break;
449 case GUARD_INTERVAL_1_8:
450 tps |= (2 << 2);
451 break;
452 case GUARD_INTERVAL_1_4:
453 tps |= (3 << 2);
454 break;
455 case GUARD_INTERVAL_1_32:
456 default:
457 /* tps |= (0 << 2) */;
458 }
459
460 switch (op->hierarchy_information) {
461 case HIERARCHY_1:
462 tps |= (1 << 10);
463 break;
464 case HIERARCHY_2:
465 tps |= (2 << 10);
466 break;
467 case HIERARCHY_4:
468 tps |= (3 << 10);
469 break;
470 case HIERARCHY_NONE:
471 default:
472 /* tps |= (0 << 10) */;
473 }
474
475 return tps;
476}
477
478static int cinergyt2_open (struct inode *inode, struct file *file)
479{
480 struct dvb_device *dvbdev = file->private_data;
481 struct cinergyt2 *cinergyt2 = dvbdev->priv;
482 int err;
483
484 if ((err = dvb_generic_open(inode, file)))
485 return err;
486
487 if (down_interruptible(&cinergyt2->sem))
488 return -ERESTARTSYS;
489
490 if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
491 cinergyt2_sleep(cinergyt2, 0);
492 schedule_delayed_work(&cinergyt2->query_work, HZ/2);
493 }
494
495 up(&cinergyt2->sem);
496 return 0;
497}
498
499static int cinergyt2_release (struct inode *inode, struct file *file)
500{
501 struct dvb_device *dvbdev = file->private_data;
502 struct cinergyt2 *cinergyt2 = dvbdev->priv;
503
504 if (down_interruptible(&cinergyt2->sem))
505 return -ERESTARTSYS;
506
507 if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
508 cancel_delayed_work(&cinergyt2->query_work);
509 flush_scheduled_work();
510 cinergyt2_sleep(cinergyt2, 1);
511 }
512
513 up(&cinergyt2->sem);
514
515 return dvb_generic_release(inode, file);
516}
517
518static unsigned int cinergyt2_poll (struct file *file, struct poll_table_struct *wait)
519{
520 struct dvb_device *dvbdev = file->private_data;
521 struct cinergyt2 *cinergyt2 = dvbdev->priv;
522 poll_wait(file, &cinergyt2->poll_wq, wait);
523 return (POLLIN | POLLRDNORM | POLLPRI);
524}
525
526
527static int cinergyt2_ioctl (struct inode *inode, struct file *file,
528 unsigned cmd, unsigned long arg)
529{
530 struct dvb_device *dvbdev = file->private_data;
531 struct cinergyt2 *cinergyt2 = dvbdev->priv;
532 struct dvbt_get_status_msg *stat = &cinergyt2->status;
533 fe_status_t status = 0;
534
535 switch (cmd) {
536 case FE_GET_INFO:
537 return copy_to_user((void __user*) arg, &cinergyt2_fe_info,
538 sizeof(struct dvb_frontend_info));
539
540 case FE_READ_STATUS:
541 if (0xffff - le16_to_cpu(stat->gain) > 30)
542 status |= FE_HAS_SIGNAL;
543 if (stat->lock_bits & (1 << 6))
544 status |= FE_HAS_LOCK;
545 if (stat->lock_bits & (1 << 5))
546 status |= FE_HAS_SYNC;
547 if (stat->lock_bits & (1 << 4))
548 status |= FE_HAS_CARRIER;
549 if (stat->lock_bits & (1 << 1))
550 status |= FE_HAS_VITERBI;
551
552 return copy_to_user((void __user*) arg, &status, sizeof(status));
553
554 case FE_READ_BER:
555 return put_user(le32_to_cpu(stat->viterbi_error_rate),
556 (__u32 __user *) arg);
557
558 case FE_READ_SIGNAL_STRENGTH:
559 return put_user(0xffff - le16_to_cpu(stat->gain),
560 (__u16 __user *) arg);
561
562 case FE_READ_SNR:
563 return put_user((stat->snr << 8) | stat->snr,
564 (__u16 __user *) arg);
565
566 case FE_READ_UNCORRECTED_BLOCKS:
567 /* UNC are already converted to host byte order... */
568 return put_user(stat->uncorrected_block_count,
569 (__u32 __user *) arg);
570
571 case FE_SET_FRONTEND:
572 {
573 struct dvbt_set_parameters_msg *param = &cinergyt2->param;
574 struct dvb_frontend_parameters p;
575 int err;
576
577 if ((file->f_flags & O_ACCMODE) == O_RDONLY)
578 return -EPERM;
579
580 if (copy_from_user(&p, (void __user*) arg, sizeof(p)))
581 return -EFAULT;
582
583 if (down_interruptible(&cinergyt2->sem))
584 return -ERESTARTSYS;
585
586 param->cmd = CINERGYT2_EP1_SET_TUNER_PARAMETERS;
587 param->tps = cpu_to_le16(compute_tps(&p));
588 param->freq = cpu_to_le32(p.frequency / 1000);
589 param->bandwidth = 8 - p.u.ofdm.bandwidth - BANDWIDTH_8_MHZ;
590
591 stat->lock_bits = 0;
592 cinergyt2->pending_fe_events++;
593 wake_up_interruptible(&cinergyt2->poll_wq);
594
595 err = cinergyt2_command(cinergyt2,
596 (char *) param, sizeof(*param),
597 NULL, 0);
598
599 up(&cinergyt2->sem);
600
601 return (err < 0) ? err : 0;
602 }
603
604 case FE_GET_FRONTEND:
605 /**
606 * trivial to implement (see struct dvbt_get_status_msg).
607 * equivalent to FE_READ ioctls, but needs
608 * TPS -> linux-dvb parameter set conversion. Feel free
609 * to implement this and send us a patch if you need this
610 * functionality.
611 */
612 break;
613
614 case FE_GET_EVENT:
615 {
616 /**
617 * for now we only fill the status field. the parameters
618 * are trivial to fill as soon FE_GET_FRONTEND is done.
619 */
620 struct dvb_frontend_event __user *e = (void __user *) arg;
621 if (cinergyt2->pending_fe_events == 0) {
622 if (file->f_flags & O_NONBLOCK)
623 return -EWOULDBLOCK;
624 wait_event_interruptible(cinergyt2->poll_wq,
625 cinergyt2->pending_fe_events > 0);
626 }
627 cinergyt2->pending_fe_events = 0;
628 return cinergyt2_ioctl(inode, file, FE_READ_STATUS,
629 (unsigned long) &e->status);
630 }
631
632 default:
633 ;
634 }
635
636 return -EINVAL;
637}
638
639static int cinergyt2_mmap(struct file *file, struct vm_area_struct *vma)
640{
641 struct dvb_device *dvbdev = file->private_data;
642 struct cinergyt2 *cinergyt2 = dvbdev->priv;
643 int ret = 0;
644
645 lock_kernel();
646
647 if (vma->vm_flags & (VM_WRITE | VM_EXEC)) {
648 ret = -EPERM;
649 goto bailout;
650 }
651
652 if (vma->vm_end > vma->vm_start + STREAM_URB_COUNT * STREAM_BUF_SIZE) {
653 ret = -EINVAL;
654 goto bailout;
655 }
656
657 vma->vm_flags |= (VM_IO | VM_DONTCOPY);
658 vma->vm_file = file;
659
660 ret = remap_pfn_range(vma, vma->vm_start,
661 virt_to_phys(cinergyt2->streambuf) >> PAGE_SHIFT,
662 vma->vm_end - vma->vm_start,
663 vma->vm_page_prot) ? -EAGAIN : 0;
664bailout:
665 unlock_kernel();
666 return ret;
667}
668
669static struct file_operations cinergyt2_fops = {
670 .owner = THIS_MODULE,
671 .ioctl = cinergyt2_ioctl,
672 .poll = cinergyt2_poll,
673 .open = cinergyt2_open,
674 .release = cinergyt2_release,
675 .mmap = cinergyt2_mmap
676};
677
678static struct dvb_device cinergyt2_fe_template = {
679 .users = ~0,
680 .writers = 1,
681 .readers = (~0)-1,
682 .fops = &cinergyt2_fops
683};
684
685#ifdef ENABLE_RC
686static void cinergyt2_query_rc (void *data)
687{
688 struct cinergyt2 *cinergyt2 = (struct cinergyt2 *) data;
689 char buf [1] = { CINERGYT2_EP1_GET_RC_EVENTS };
690 struct cinergyt2_rc_event rc_events[12];
691 int n, len;
692
693 if (down_interruptible(&cinergyt2->sem))
694 return;
695
696 len = cinergyt2_command(cinergyt2, buf, sizeof(buf),
697 (char *) rc_events, sizeof(rc_events));
698
699 for (n=0; len>0 && n<(len/sizeof(rc_events[0])); n++) {
700 int i;
701
702 if (rc_events[n].type == CINERGYT2_RC_EVENT_TYPE_NEC &&
703 rc_events[n].value == ~0)
704 {
705 /**
706 * keyrepeat bit. If we would handle this properly
707 * we would need to emit down events as long the
708 * keyrepeat goes, a up event if no further
709 * repeat bits occur. Would need a timer to implement
710 * and no other driver does this, so we simply
711 * emit the last key up/down sequence again.
712 */
713 } else {
714 cinergyt2->rc_input_event = KEY_MAX;
715 for (i=0; i<sizeof(rc_keys)/sizeof(rc_keys[0]); i+=3) {
716 if (rc_keys[i+0] == rc_events[n].type &&
717 rc_keys[i+1] == rc_events[n].value)
718 {
719 cinergyt2->rc_input_event = rc_keys[i+2];
720 break;
721 }
722 }
723 }
724
725 if (cinergyt2->rc_input_event != KEY_MAX) {
726 input_report_key(&cinergyt2->rc_input_dev, cinergyt2->rc_input_event, 1);
727 input_report_key(&cinergyt2->rc_input_dev, cinergyt2->rc_input_event, 0);
728 input_sync(&cinergyt2->rc_input_dev);
729 }
730 }
731
732 schedule_delayed_work(&cinergyt2->rc_query_work,
733 msecs_to_jiffies(RC_QUERY_INTERVAL));
734
735 up(&cinergyt2->sem);
736}
737#endif
738
739static void cinergyt2_query (void *data)
740{
741 struct cinergyt2 *cinergyt2 = (struct cinergyt2 *) data;
742 char cmd [] = { CINERGYT2_EP1_GET_TUNER_STATUS };
743 struct dvbt_get_status_msg *s = &cinergyt2->status;
744 uint8_t lock_bits;
745 uint32_t unc;
746
747 if (down_interruptible(&cinergyt2->sem))
748 return;
749
750 unc = s->uncorrected_block_count;
751 lock_bits = s->lock_bits;
752
753 cinergyt2_command(cinergyt2, cmd, sizeof(cmd), (char *) s, sizeof(*s));
754
755 unc += le32_to_cpu(s->uncorrected_block_count);
756 s->uncorrected_block_count = unc;
757
758 if (lock_bits != s->lock_bits) {
759 wake_up_interruptible(&cinergyt2->poll_wq);
760 cinergyt2->pending_fe_events++;
761 }
762
763 schedule_delayed_work(&cinergyt2->query_work,
764 msecs_to_jiffies(QUERY_INTERVAL));
765
766 up(&cinergyt2->sem);
767}
768
769static int cinergyt2_probe (struct usb_interface *intf,
770 const struct usb_device_id *id)
771{
772 struct cinergyt2 *cinergyt2;
773 int i, err;
774
775 if (!(cinergyt2 = kmalloc (sizeof(struct cinergyt2), GFP_KERNEL))) {
776 dprintk(1, "out of memory?!?\n");
777 return -ENOMEM;
778 }
779
780 memset (cinergyt2, 0, sizeof (struct cinergyt2));
781 usb_set_intfdata (intf, (void *) cinergyt2);
782
783 init_MUTEX(&cinergyt2->sem);
784 init_waitqueue_head (&cinergyt2->poll_wq);
785 INIT_WORK(&cinergyt2->query_work, cinergyt2_query, cinergyt2);
786
787 cinergyt2->udev = interface_to_usbdev(intf);
788 cinergyt2->param.cmd = CINERGYT2_EP1_SET_TUNER_PARAMETERS;
789
790 if (cinergyt2_alloc_stream_urbs (cinergyt2) < 0) {
791 dprintk(1, "unable to allocate stream urbs\n");
792 kfree(cinergyt2);
793 return -ENOMEM;
794 }
795
796 dvb_register_adapter(&cinergyt2->adapter, DRIVER_NAME, THIS_MODULE);
797
798 cinergyt2->demux.priv = cinergyt2;
799 cinergyt2->demux.filternum = 256;
800 cinergyt2->demux.feednum = 256;
801 cinergyt2->demux.start_feed = cinergyt2_start_feed;
802 cinergyt2->demux.stop_feed = cinergyt2_stop_feed;
803 cinergyt2->demux.dmx.capabilities = DMX_TS_FILTERING |
804 DMX_SECTION_FILTERING |
805 DMX_MEMORY_BASED_FILTERING;
806
807 if ((err = dvb_dmx_init(&cinergyt2->demux)) < 0) {
808 dprintk(1, "dvb_dmx_init() failed (err = %d)\n", err);
809 goto bailout;
810 }
811
812 cinergyt2->dmxdev.filternum = cinergyt2->demux.filternum;
813 cinergyt2->dmxdev.demux = &cinergyt2->demux.dmx;
814 cinergyt2->dmxdev.capabilities = 0;
815
816 if ((err = dvb_dmxdev_init(&cinergyt2->dmxdev, cinergyt2->adapter)) < 0) {
817 dprintk(1, "dvb_dmxdev_init() failed (err = %d)\n", err);
818 goto bailout;
819 }
820
821 if (dvb_net_init(cinergyt2->adapter, &cinergyt2->dvbnet, &cinergyt2->demux.dmx))
822 dprintk(1, "dvb_net_init() failed!\n");
823
824 dvb_register_device(cinergyt2->adapter, &cinergyt2->fedev,
825 &cinergyt2_fe_template, cinergyt2,
826 DVB_DEVICE_FRONTEND);
827
828#ifdef ENABLE_RC
829 init_input_dev(&cinergyt2->rc_input_dev);
830
831 cinergyt2->rc_input_dev.evbit[0] = BIT(EV_KEY);
832 cinergyt2->rc_input_dev.keycodesize = sizeof(unsigned char);
833 cinergyt2->rc_input_dev.keycodemax = KEY_MAX;
834 cinergyt2->rc_input_dev.name = DRIVER_NAME " remote control";
835
836 for (i=0; i<sizeof(rc_keys)/sizeof(rc_keys[0]); i+=3)
837 set_bit(rc_keys[i+2], cinergyt2->rc_input_dev.keybit);
838
839 input_register_device(&cinergyt2->rc_input_dev);
840
841 cinergyt2->rc_input_event = KEY_MAX;
842
843 INIT_WORK(&cinergyt2->rc_query_work, cinergyt2_query_rc, cinergyt2);
844 schedule_delayed_work(&cinergyt2->rc_query_work, HZ/2);
845#endif
846 return 0;
847
848bailout:
849 dvb_dmxdev_release(&cinergyt2->dmxdev);
850 dvb_dmx_release(&cinergyt2->demux);
851 dvb_unregister_adapter (cinergyt2->adapter);
852 cinergyt2_free_stream_urbs (cinergyt2);
853 kfree(cinergyt2);
854 return -ENOMEM;
855}
856
857static void cinergyt2_disconnect (struct usb_interface *intf)
858{
859 struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf);
860
861 if (down_interruptible(&cinergyt2->sem))
862 return;
863
864#ifdef ENABLE_RC
865 cancel_delayed_work(&cinergyt2->rc_query_work);
866 flush_scheduled_work();
867 input_unregister_device(&cinergyt2->rc_input_dev);
868#endif
869
870 cinergyt2->demux.dmx.close(&cinergyt2->demux.dmx);
871 dvb_net_release(&cinergyt2->dvbnet);
872 dvb_dmxdev_release(&cinergyt2->dmxdev);
873 dvb_dmx_release(&cinergyt2->demux);
874 dvb_unregister_device(cinergyt2->fedev);
875 dvb_unregister_adapter(cinergyt2->adapter);
876
877 cinergyt2_free_stream_urbs(cinergyt2);
878 up(&cinergyt2->sem);
879 kfree(cinergyt2);
880}
881
882static int cinergyt2_suspend (struct usb_interface *intf, u32 state)
883{
884 struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf);
885
886 if (down_interruptible(&cinergyt2->sem))
887 return -ERESTARTSYS;
888
889 if (state > 0) { /* state 0 seems to mean DEVICE_PM_ON */
890 struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf);
891#ifdef ENABLE_RC
892 cancel_delayed_work(&cinergyt2->rc_query_work);
893#endif
894 cancel_delayed_work(&cinergyt2->query_work);
895 if (cinergyt2->streaming)
896 cinergyt2_stop_stream_xfer(cinergyt2);
897 flush_scheduled_work();
898 cinergyt2_sleep(cinergyt2, 1);
899 }
900
901 up(&cinergyt2->sem);
902 return 0;
903}
904
905static int cinergyt2_resume (struct usb_interface *intf)
906{
907 struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf);
908 struct dvbt_set_parameters_msg *param = &cinergyt2->param;
909
910 if (down_interruptible(&cinergyt2->sem))
911 return -ERESTARTSYS;
912
913 if (!cinergyt2->sleeping) {
914 cinergyt2_sleep(cinergyt2, 0);
915 cinergyt2_command(cinergyt2, (char *) param, sizeof(*param), NULL, 0);
916 if (cinergyt2->streaming)
917 cinergyt2_start_stream_xfer(cinergyt2);
918 schedule_delayed_work(&cinergyt2->query_work, HZ/2);
919 }
920
921#ifdef ENABLE_RC
922 schedule_delayed_work(&cinergyt2->rc_query_work, HZ/2);
923#endif
924 up(&cinergyt2->sem);
925 return 0;
926}
927
928static const struct usb_device_id cinergyt2_table [] __devinitdata = {
929 { USB_DEVICE(0x0ccd, 0x0038) },
930 { 0 }
931};
932
933MODULE_DEVICE_TABLE(usb, cinergyt2_table);
934
935static struct usb_driver cinergyt2_driver = {
936 .owner = THIS_MODULE,
937 .name = "cinergyT2",
938 .probe = cinergyt2_probe,
939 .disconnect = cinergyt2_disconnect,
940 .suspend = cinergyt2_suspend,
941 .resume = cinergyt2_resume,
942 .id_table = cinergyt2_table
943};
944
945static int __init cinergyt2_init (void)
946{
947 int err;
948
949 if ((err = usb_register(&cinergyt2_driver)) < 0)
950 dprintk(1, "usb_register() failed! (err %i)\n", err);
951
952 return err;
953}
954
955static void __exit cinergyt2_exit (void)
956{
957 usb_deregister(&cinergyt2_driver);
958}
959
960module_init (cinergyt2_init);
961module_exit (cinergyt2_exit);
962
963MODULE_LICENSE("GPL");
964MODULE_AUTHOR("Holger Waechtler, Daniel Mack");
965
diff --git a/drivers/media/dvb/dibusb/Kconfig b/drivers/media/dvb/dibusb/Kconfig
new file mode 100644
index 000000000000..74dfc73ae5b0
--- /dev/null
+++ b/drivers/media/dvb/dibusb/Kconfig
@@ -0,0 +1,62 @@
1config DVB_DIBUSB
2 tristate "DiBcom USB DVB-T devices (see help for a complete device list)"
3 depends on DVB_CORE && USB
4 select FW_LOADER
5 select DVB_DIB3000MB
6 select DVB_DIB3000MC
7 select DVB_MT352
8 help
9 Support for USB 1.1 and 2.0 DVB-T devices based on reference designs made by
10 DiBcom (http://www.dibcom.fr) and C&E.
11
12 Devices supported by this driver:
13
14 TwinhanDTV USB-Ter (VP7041)
15 TwinhanDTV Magic Box (VP7041e)
16 KWorld/JetWay/ADSTech V-Stream XPERT DTV - DVB-T USB1.1 and USB2.0
17 Hama DVB-T USB-Box
18 DiBcom reference devices (non-public)
19 Ultima Electronic/Artec T1 USB TVBOX
20 Compro Videomate DVB-U2000 - DVB-T USB
21 Grandtec DVB-T USB
22 Avermedia AverTV DVBT USB
23 Artec T1 USB1.1 and USB2.0 boxes
24 Yakumo/Typhoon DVB-T USB2.0
25 Hanftek UMT-010 USB2.0
26 Hauppauge WinTV NOVA-T USB2
27
28 The VP7041 seems to be identical to "CTS Portable" (Chinese
29 Television System).
30
31 These devices can be understood as budget ones, they "only" deliver
32 (a part of) the MPEG2 transport stream.
33
34 A firmware is needed to get the device working. See Documentation/dvb/README.dibusb
35 details.
36
37 Say Y if you own such a device and want to use it. You should build it as
38 a module.
39
40config DVB_DIBUSB_MISDESIGNED_DEVICES
41 bool "Enable support for some misdesigned (see help) devices, which identify with wrong IDs"
42 depends on DVB_DIBUSB
43 help
44 Somehow Artec/Ultima Electronic forgot to program the eeprom of some of their
45 USB1.1/USB2.0 devices.
46 So comes that they identify with the default Vendor and Product ID of the Cypress
47 CY7C64613 (AN2235) or Cypress FX2.
48
49 Affected device IDs:
50 0x0574:0x2235 (Artec T1 USB1.1, cold)
51 0x04b4:0x8613 (Artec T1 USB2.0, cold)
52 0x0574:0x1002 (Artec T1 USB2.0, warm)
53 0x0574:0x2131 (aged DiBcom USB1.1 test device)
54
55 Say Y if your device has one of the mentioned IDs.
56
57config DVB_DIBCOM_DEBUG
58 bool "Enable extended debug support for DiBcom USB device"
59 depends on DVB_DIBUSB
60 help
61 Say Y if you want to enable debuging. See modinfo dvb-dibusb for
62 debug levels.
diff --git a/drivers/media/dvb/dibusb/Makefile b/drivers/media/dvb/dibusb/Makefile
new file mode 100644
index 000000000000..e941c508624e
--- /dev/null
+++ b/drivers/media/dvb/dibusb/Makefile
@@ -0,0 +1,11 @@
1dvb-dibusb-objs = dvb-dibusb-core.o \
2 dvb-dibusb-dvb.o \
3 dvb-dibusb-fe-i2c.o \
4 dvb-dibusb-firmware.o \
5 dvb-dibusb-remote.o \
6 dvb-dibusb-usb.o \
7 dvb-fe-dtt200u.o
8
9obj-$(CONFIG_DVB_DIBUSB) += dvb-dibusb.o
10
11EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
diff --git a/drivers/media/dvb/dibusb/dvb-dibusb-core.c b/drivers/media/dvb/dibusb/dvb-dibusb-core.c
new file mode 100644
index 000000000000..26235f9247e4
--- /dev/null
+++ b/drivers/media/dvb/dibusb/dvb-dibusb-core.c
@@ -0,0 +1,558 @@
1/*
2 * Driver for mobile USB Budget DVB-T devices based on reference
3 * design made by DiBcom (http://www.dibcom.fr/)
4 *
5 * dvb-dibusb-core.c
6 *
7 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
8 *
9 * based on GPL code from DiBcom, which has
10 * Copyright (C) 2004 Amaury Demol for DiBcom (ademol@dibcom.fr)
11 *
12 * Remote control code added by David Matthews (dm@prolingua.co.uk)
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License as
16 * published by the Free Software Foundation, version 2.
17 *
18 * Acknowledgements
19 *
20 * Amaury Demol (ademol@dibcom.fr) from DiBcom for providing specs and driver
21 * sources, on which this driver (and the dib3000mb/mc/p frontends) are based.
22 *
23 * see Documentation/dvb/README.dibusb for more information
24 */
25#include "dvb-dibusb.h"
26
27#include <linux/moduleparam.h>
28
29/* debug */
30int dvb_dibusb_debug;
31module_param_named(debug, dvb_dibusb_debug, int, 0644);
32
33#ifdef CONFIG_DVB_DIBCOM_DEBUG
34#define DBSTATUS ""
35#else
36#define DBSTATUS " (debugging is not enabled)"
37#endif
38MODULE_PARM_DESC(debug, "set debugging level (1=info,2=xfer,4=alotmore,8=ts,16=err,32=rc (|-able))." DBSTATUS);
39#undef DBSTATUS
40
41static int pid_parse;
42module_param(pid_parse, int, 0644);
43MODULE_PARM_DESC(pid_parse, "enable pid parsing (filtering) when running at USB2.0");
44
45static int rc_query_interval = 100;
46module_param(rc_query_interval, int, 0644);
47MODULE_PARM_DESC(rc_query_interval, "interval in msecs for remote control query (default: 100; min: 40)");
48
49static int rc_key_repeat_count = 2;
50module_param(rc_key_repeat_count, int, 0644);
51MODULE_PARM_DESC(rc_key_repeat_count, "how many key repeats will be dropped before passing the key event again (default: 2)");
52
53/* Vendor IDs */
54#define USB_VID_ADSTECH 0x06e1
55#define USB_VID_ANCHOR 0x0547
56#define USB_VID_AVERMEDIA 0x14aa
57#define USB_VID_COMPRO 0x185b
58#define USB_VID_COMPRO_UNK 0x145f
59#define USB_VID_CYPRESS 0x04b4
60#define USB_VID_DIBCOM 0x10b8
61#define USB_VID_EMPIA 0xeb1a
62#define USB_VID_GRANDTEC 0x5032
63#define USB_VID_HANFTEK 0x15f4
64#define USB_VID_HAUPPAUGE 0x2040
65#define USB_VID_HYPER_PALTEK 0x1025
66#define USB_VID_IMC_NETWORKS 0x13d3
67#define USB_VID_TWINHAN 0x1822
68#define USB_VID_ULTIMA_ELECTRONIC 0x05d8
69
70/* Product IDs */
71#define USB_PID_ADSTECH_USB2_COLD 0xa333
72#define USB_PID_ADSTECH_USB2_WARM 0xa334
73#define USB_PID_AVERMEDIA_DVBT_USB_COLD 0x0001
74#define USB_PID_AVERMEDIA_DVBT_USB_WARM 0x0002
75#define USB_PID_COMPRO_DVBU2000_COLD 0xd000
76#define USB_PID_COMPRO_DVBU2000_WARM 0xd001
77#define USB_PID_COMPRO_DVBU2000_UNK_COLD 0x010c
78#define USB_PID_COMPRO_DVBU2000_UNK_WARM 0x010d
79#define USB_PID_DIBCOM_MOD3000_COLD 0x0bb8
80#define USB_PID_DIBCOM_MOD3000_WARM 0x0bb9
81#define USB_PID_DIBCOM_MOD3001_COLD 0x0bc6
82#define USB_PID_DIBCOM_MOD3001_WARM 0x0bc7
83#define USB_PID_DIBCOM_ANCHOR_2135_COLD 0x2131
84#define USB_PID_GRANDTEC_DVBT_USB_COLD 0x0fa0
85#define USB_PID_GRANDTEC_DVBT_USB_WARM 0x0fa1
86#define USB_PID_KWORLD_VSTREAM_COLD 0x17de
87#define USB_PID_KWORLD_VSTREAM_WARM 0x17df
88#define USB_PID_TWINHAN_VP7041_COLD 0x3201
89#define USB_PID_TWINHAN_VP7041_WARM 0x3202
90#define USB_PID_ULTIMA_TVBOX_COLD 0x8105
91#define USB_PID_ULTIMA_TVBOX_WARM 0x8106
92#define USB_PID_ULTIMA_TVBOX_AN2235_COLD 0x8107
93#define USB_PID_ULTIMA_TVBOX_AN2235_WARM 0x8108
94#define USB_PID_ULTIMA_TVBOX_ANCHOR_COLD 0x2235
95#define USB_PID_ULTIMA_TVBOX_USB2_COLD 0x8109
96#define USB_PID_ULTIMA_TVBOX_USB2_FX_COLD 0x8613
97#define USB_PID_ULTIMA_TVBOX_USB2_FX_WARM 0x1002
98#define USB_PID_UNK_HYPER_PALTEK_COLD 0x005e
99#define USB_PID_UNK_HYPER_PALTEK_WARM 0x005f
100#define USB_PID_HANFTEK_UMT_010_COLD 0x0001
101#define USB_PID_HANFTEK_UMT_010_WARM 0x0015
102#define USB_PID_YAKUMO_DTT200U_COLD 0x0201
103#define USB_PID_YAKUMO_DTT200U_WARM 0x0301
104#define USB_PID_WINTV_NOVA_T_USB2_COLD 0x9300
105#define USB_PID_WINTV_NOVA_T_USB2_WARM 0x9301
106
107/* USB Driver stuff
108 * table of devices that this driver is working with
109 *
110 * ATTENTION: Never ever change the order of this table, the particular
111 * devices depend on this order
112 *
113 * Each entry is used as a reference in the device_struct. Currently this is
114 * the only non-redundant way of assigning USB ids to actual devices I'm aware
115 * of, because there is only one place in the code where the assignment of
116 * vendor and product id is done, here.
117 */
118static struct usb_device_id dib_table [] = {
119/* 00 */ { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_DVBT_USB_COLD)},
120/* 01 */ { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_DVBT_USB_WARM)},
121/* 02 */ { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_YAKUMO_DTT200U_COLD) },
122/* 03 */ { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_YAKUMO_DTT200U_WARM) },
123
124/* 04 */ { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_DVBU2000_COLD) },
125/* 05 */ { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_DVBU2000_WARM) },
126/* 06 */ { USB_DEVICE(USB_VID_COMPRO_UNK, USB_PID_COMPRO_DVBU2000_UNK_COLD) },
127/* 07 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3000_COLD) },
128/* 08 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3000_WARM) },
129/* 09 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3001_COLD) },
130/* 10 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3001_WARM) },
131/* 11 */ { USB_DEVICE(USB_VID_EMPIA, USB_PID_KWORLD_VSTREAM_COLD) },
132/* 12 */ { USB_DEVICE(USB_VID_EMPIA, USB_PID_KWORLD_VSTREAM_WARM) },
133/* 13 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_GRANDTEC_DVBT_USB_COLD) },
134/* 14 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_GRANDTEC_DVBT_USB_WARM) },
135/* 15 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_DIBCOM_MOD3000_COLD) },
136/* 16 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_DIBCOM_MOD3000_WARM) },
137/* 17 */ { USB_DEVICE(USB_VID_HYPER_PALTEK, USB_PID_UNK_HYPER_PALTEK_COLD) },
138/* 18 */ { USB_DEVICE(USB_VID_HYPER_PALTEK, USB_PID_UNK_HYPER_PALTEK_WARM) },
139/* 19 */ { USB_DEVICE(USB_VID_IMC_NETWORKS, USB_PID_TWINHAN_VP7041_COLD) },
140/* 20 */ { USB_DEVICE(USB_VID_IMC_NETWORKS, USB_PID_TWINHAN_VP7041_WARM) },
141/* 21 */ { USB_DEVICE(USB_VID_TWINHAN, USB_PID_TWINHAN_VP7041_COLD) },
142/* 22 */ { USB_DEVICE(USB_VID_TWINHAN, USB_PID_TWINHAN_VP7041_WARM) },
143/* 23 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_COLD) },
144/* 24 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_WARM) },
145/* 25 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_AN2235_COLD) },
146/* 26 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_AN2235_WARM) },
147/* 27 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_USB2_COLD) },
148
149/* 28 */ { USB_DEVICE(USB_VID_HANFTEK, USB_PID_HANFTEK_UMT_010_COLD) },
150/* 29 */ { USB_DEVICE(USB_VID_HANFTEK, USB_PID_HANFTEK_UMT_010_WARM) },
151
152/* 30 */ { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_WINTV_NOVA_T_USB2_COLD) },
153/* 31 */ { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_WINTV_NOVA_T_USB2_WARM) },
154/* 32 */ { USB_DEVICE(USB_VID_ADSTECH, USB_PID_ADSTECH_USB2_COLD) },
155/* 33 */ { USB_DEVICE(USB_VID_ADSTECH, USB_PID_ADSTECH_USB2_WARM) },
156/*
157 * activate the following define when you have one of the devices and want to
158 * build it from build-2.6 in dvb-kernel
159 */
160// #define CONFIG_DVB_DIBUSB_MISDESIGNED_DEVICES
161#ifdef CONFIG_DVB_DIBUSB_MISDESIGNED_DEVICES
162/* 34 */ { USB_DEVICE(USB_VID_ANCHOR, USB_PID_ULTIMA_TVBOX_ANCHOR_COLD) },
163/* 35 */ { USB_DEVICE(USB_VID_CYPRESS, USB_PID_ULTIMA_TVBOX_USB2_FX_COLD) },
164/* 36 */ { USB_DEVICE(USB_VID_ANCHOR, USB_PID_ULTIMA_TVBOX_USB2_FX_WARM) },
165/* 37 */ { USB_DEVICE(USB_VID_ANCHOR, USB_PID_DIBCOM_ANCHOR_2135_COLD) },
166#endif
167 { } /* Terminating entry */
168};
169
170MODULE_DEVICE_TABLE (usb, dib_table);
171
172static struct dibusb_usb_controller dibusb_usb_ctrl[] = {
173 { .name = "Cypress AN2135", .cpu_cs_register = 0x7f92 },
174 { .name = "Cypress AN2235", .cpu_cs_register = 0x7f92 },
175 { .name = "Cypress FX2", .cpu_cs_register = 0xe600 },
176};
177
178struct dibusb_tuner dibusb_tuner[] = {
179 { DIBUSB_TUNER_CABLE_THOMSON,
180 0x61
181 },
182 { DIBUSB_TUNER_COFDM_PANASONIC_ENV57H1XD5,
183 0x60
184 },
185 { DIBUSB_TUNER_CABLE_LG_TDTP_E102P,
186 0x61
187 },
188 { DIBUSB_TUNER_COFDM_PANASONIC_ENV77H11D5,
189 0x60
190 },
191};
192
193static struct dibusb_demod dibusb_demod[] = {
194 { DIBUSB_DIB3000MB,
195 16,
196 { 0x8, 0 },
197 },
198 { DIBUSB_DIB3000MC,
199 32,
200 { 0x9, 0xa, 0xb, 0xc },
201 },
202 { DIBUSB_MT352,
203 254,
204 { 0xf, 0 },
205 },
206 { DTT200U_FE,
207 8,
208 { 0xff,0 }, /* there is no i2c bus in this device */
209 }
210};
211
212static struct dibusb_device_class dibusb_device_classes[] = {
213 { .id = DIBUSB1_1, .usb_ctrl = &dibusb_usb_ctrl[0],
214 .firmware = "dvb-dibusb-5.0.0.11.fw",
215 .pipe_cmd = 0x01, .pipe_data = 0x02,
216 .urb_count = 7, .urb_buffer_size = 4096,
217 DIBUSB_RC_NEC_PROTOCOL,
218 &dibusb_demod[DIBUSB_DIB3000MB],
219 &dibusb_tuner[DIBUSB_TUNER_CABLE_THOMSON],
220 },
221 { DIBUSB1_1_AN2235, &dibusb_usb_ctrl[1],
222 "dvb-dibusb-an2235-1.fw",
223 0x01, 0x02,
224 7, 4096,
225 DIBUSB_RC_NEC_PROTOCOL,
226 &dibusb_demod[DIBUSB_DIB3000MB],
227 &dibusb_tuner[DIBUSB_TUNER_CABLE_THOMSON],
228 },
229 { DIBUSB2_0,&dibusb_usb_ctrl[2],
230 "dvb-dibusb-6.0.0.5.fw",
231 0x01, 0x06,
232 7, 4096,
233 DIBUSB_RC_NEC_PROTOCOL,
234 &dibusb_demod[DIBUSB_DIB3000MC],
235 &dibusb_tuner[DIBUSB_TUNER_COFDM_PANASONIC_ENV57H1XD5],
236 },
237 { UMT2_0, &dibusb_usb_ctrl[2],
238 "dvb-dibusb-umt-2.fw",
239 0x01, 0x06,
240 20, 512,
241 DIBUSB_RC_NO,
242 &dibusb_demod[DIBUSB_MT352],
243 &dibusb_tuner[DIBUSB_TUNER_CABLE_LG_TDTP_E102P],
244 },
245 { DIBUSB2_0B,&dibusb_usb_ctrl[2],
246 "dvb-dibusb-adstech-usb2-1.fw",
247 0x01, 0x06,
248 7, 4096,
249 DIBUSB_RC_NEC_PROTOCOL,
250 &dibusb_demod[DIBUSB_DIB3000MB],
251 &dibusb_tuner[DIBUSB_TUNER_CABLE_THOMSON],
252 },
253 { NOVAT_USB2,&dibusb_usb_ctrl[2],
254 "dvb-dibusb-nova-t-1.fw",
255 0x01, 0x06,
256 7, 4096,
257 DIBUSB_RC_HAUPPAUGE_PROTO,
258 &dibusb_demod[DIBUSB_DIB3000MC],
259 &dibusb_tuner[DIBUSB_TUNER_COFDM_PANASONIC_ENV57H1XD5],
260 },
261 { DTT200U,&dibusb_usb_ctrl[2],
262 "dvb-dtt200u-1.fw",
263 0x01, 0x02,
264 7, 4096,
265 DIBUSB_RC_NO,
266 &dibusb_demod[DTT200U_FE],
267 NULL, /* no explicit tuner/pll-programming necessary (it has the ENV57H1XD5) */
268 },
269};
270
271static struct dibusb_usb_device dibusb_devices[] = {
272 { "TwinhanDTV USB1.1 / Magic Box / HAMA USB1.1 DVB-T device",
273 &dibusb_device_classes[DIBUSB1_1],
274 { &dib_table[19], &dib_table[21], NULL},
275 { &dib_table[20], &dib_table[22], NULL},
276 },
277 { "KWorld V-Stream XPERT DTV - DVB-T USB1.1",
278 &dibusb_device_classes[DIBUSB1_1],
279 { &dib_table[11], NULL },
280 { &dib_table[12], NULL },
281 },
282 { "Grandtec USB1.1 DVB-T",
283 &dibusb_device_classes[DIBUSB1_1],
284 { &dib_table[13], &dib_table[15], NULL },
285 { &dib_table[14], &dib_table[16], NULL },
286 },
287 { "DiBcom USB1.1 DVB-T reference design (MOD3000)",
288 &dibusb_device_classes[DIBUSB1_1],
289 { &dib_table[7], NULL },
290 { &dib_table[8], NULL },
291 },
292 { "Artec T1 USB1.1 TVBOX with AN2135",
293 &dibusb_device_classes[DIBUSB1_1],
294 { &dib_table[23], NULL },
295 { &dib_table[24], NULL },
296 },
297 { "Artec T1 USB1.1 TVBOX with AN2235",
298 &dibusb_device_classes[DIBUSB1_1_AN2235],
299 { &dib_table[25], NULL },
300 { &dib_table[26], NULL },
301 },
302 { "Avermedia AverTV DVBT USB1.1",
303 &dibusb_device_classes[DIBUSB1_1],
304 { &dib_table[0], NULL },
305 { &dib_table[1], NULL },
306 },
307 { "Compro Videomate DVB-U2000 - DVB-T USB1.1 (please confirm to linux-dvb)",
308 &dibusb_device_classes[DIBUSB1_1],
309 { &dib_table[4], &dib_table[6], NULL},
310 { &dib_table[5], NULL },
311 },
312 { "Unkown USB1.1 DVB-T device ???? please report the name to the author",
313 &dibusb_device_classes[DIBUSB1_1],
314 { &dib_table[17], NULL },
315 { &dib_table[18], NULL },
316 },
317 { "DiBcom USB2.0 DVB-T reference design (MOD3000P)",
318 &dibusb_device_classes[DIBUSB2_0],
319 { &dib_table[9], NULL },
320 { &dib_table[10], NULL },
321 },
322 { "Artec T1 USB2.0 TVBOX (please report the warm ID)",
323 &dibusb_device_classes[DIBUSB2_0],
324 { &dib_table[27], NULL },
325 { NULL },
326 },
327 { "Hauppauge WinTV NOVA-T USB2",
328 &dibusb_device_classes[NOVAT_USB2],
329 { &dib_table[30], NULL },
330 { &dib_table[31], NULL },
331 },
332 { "DTT200U (Yakumo/Hama/Typhoon) DVB-T USB2.0",
333 &dibusb_device_classes[DTT200U],
334 { &dib_table[2], NULL },
335 { &dib_table[3], NULL },
336 },
337 { "Hanftek UMT-010 DVB-T USB2.0",
338 &dibusb_device_classes[UMT2_0],
339 { &dib_table[28], NULL },
340 { &dib_table[29], NULL },
341 },
342 { "KWorld/ADSTech Instant DVB-T USB 2.0",
343 &dibusb_device_classes[DIBUSB2_0B],
344 { &dib_table[32], NULL },
345 { &dib_table[33], NULL }, /* device ID with default DIBUSB2_0-firmware */
346 },
347#ifdef CONFIG_DVB_DIBUSB_MISDESIGNED_DEVICES
348 { "Artec T1 USB1.1 TVBOX with AN2235 (misdesigned)",
349 &dibusb_device_classes[DIBUSB1_1_AN2235],
350 { &dib_table[34], NULL },
351 { NULL },
352 },
353 { "Artec T1 USB2.0 TVBOX with FX2 IDs (misdesigned, please report the warm ID)",
354 &dibusb_device_classes[DTT200U],
355 { &dib_table[35], NULL },
356 { &dib_table[36], NULL }, /* undefined, it could be that the device will get another USB ID in warm state */
357 },
358 { "DiBcom USB1.1 DVB-T reference design (MOD3000) with AN2135 default IDs",
359 &dibusb_device_classes[DIBUSB1_1],
360 { &dib_table[37], NULL },
361 { NULL },
362 },
363#endif
364};
365
366static int dibusb_exit(struct usb_dibusb *dib)
367{
368 deb_info("init_state before exiting everything: %x\n",dib->init_state);
369 dibusb_remote_exit(dib);
370 dibusb_fe_exit(dib);
371 dibusb_i2c_exit(dib);
372 dibusb_dvb_exit(dib);
373 dibusb_urb_exit(dib);
374 deb_info("init_state should be zero now: %x\n",dib->init_state);
375 dib->init_state = DIBUSB_STATE_INIT;
376 kfree(dib);
377 return 0;
378}
379
380static int dibusb_init(struct usb_dibusb *dib)
381{
382 int ret = 0;
383 sema_init(&dib->usb_sem, 1);
384 sema_init(&dib->i2c_sem, 1);
385
386 dib->init_state = DIBUSB_STATE_INIT;
387
388 if ((ret = dibusb_urb_init(dib)) ||
389 (ret = dibusb_dvb_init(dib)) ||
390 (ret = dibusb_i2c_init(dib))) {
391 dibusb_exit(dib);
392 return ret;
393 }
394
395 if ((ret = dibusb_fe_init(dib)))
396 err("could not initialize a frontend.");
397
398 if ((ret = dibusb_remote_init(dib)))
399 err("could not initialize remote control.");
400
401 return 0;
402}
403
404static struct dibusb_usb_device * dibusb_device_class_quirk(struct usb_device *udev, struct dibusb_usb_device *dev)
405{
406 int i;
407
408 /* Quirk for the Kworld/ADSTech Instant USB2.0 device. It has the same USB
409 * IDs like the USB1.1 KWorld after loading the firmware. Which is a bad
410 * idea and make this quirk necessary.
411 */
412 if (dev->dev_cl->id == DIBUSB1_1 && udev->speed == USB_SPEED_HIGH) {
413 info("this seems to be the Kworld/ADSTech Instant USB2.0 device or equal.");
414 for (i = 0; i < sizeof(dibusb_devices)/sizeof(struct dibusb_usb_device); i++) {
415 if (dibusb_devices[i].dev_cl->id == DIBUSB2_0B) {
416 dev = &dibusb_devices[i];
417 break;
418 }
419 }
420 }
421
422 return dev;
423}
424
425static struct dibusb_usb_device * dibusb_find_device (struct usb_device *udev,int *cold)
426{
427 int i,j;
428 struct dibusb_usb_device *dev = NULL;
429 *cold = -1;
430
431 for (i = 0; i < sizeof(dibusb_devices)/sizeof(struct dibusb_usb_device); i++) {
432 for (j = 0; j < DIBUSB_ID_MAX_NUM && dibusb_devices[i].cold_ids[j] != NULL; j++) {
433 deb_info("check for cold %x %x\n",dibusb_devices[i].cold_ids[j]->idVendor, dibusb_devices[i].cold_ids[j]->idProduct);
434 if (dibusb_devices[i].cold_ids[j]->idVendor == le16_to_cpu(udev->descriptor.idVendor) &&
435 dibusb_devices[i].cold_ids[j]->idProduct == le16_to_cpu(udev->descriptor.idProduct)) {
436 *cold = 1;
437 dev = &dibusb_devices[i];
438 break;
439 }
440 }
441
442 if (dev != NULL)
443 break;
444
445 for (j = 0; j < DIBUSB_ID_MAX_NUM && dibusb_devices[i].warm_ids[j] != NULL; j++) {
446 deb_info("check for warm %x %x\n",dibusb_devices[i].warm_ids[j]->idVendor, dibusb_devices[i].warm_ids[j]->idProduct);
447 if (dibusb_devices[i].warm_ids[j]->idVendor == le16_to_cpu(udev->descriptor.idVendor) &&
448 dibusb_devices[i].warm_ids[j]->idProduct == le16_to_cpu(udev->descriptor.idProduct)) {
449 *cold = 0;
450 dev = &dibusb_devices[i];
451 break;
452 }
453 }
454 }
455
456 if (dev != NULL)
457 dev = dibusb_device_class_quirk(udev,dev);
458
459 return dev;
460}
461
462/*
463 * USB
464 */
465static int dibusb_probe(struct usb_interface *intf,
466 const struct usb_device_id *id)
467{
468 struct usb_device *udev = interface_to_usbdev(intf);
469 struct usb_dibusb *dib = NULL;
470 struct dibusb_usb_device *dibdev = NULL;
471
472 int ret = -ENOMEM,cold=0;
473
474 if ((dibdev = dibusb_find_device(udev,&cold)) == NULL) {
475 err("something went very wrong, "
476 "unknown product ID: %.4x",le16_to_cpu(udev->descriptor.idProduct));
477 return -ENODEV;
478 }
479
480 if (cold == 1) {
481 info("found a '%s' in cold state, will try to load a firmware",dibdev->name);
482 ret = dibusb_loadfirmware(udev,dibdev);
483 } else {
484 info("found a '%s' in warm state.",dibdev->name);
485 dib = kmalloc(sizeof(struct usb_dibusb),GFP_KERNEL);
486 if (dib == NULL) {
487 err("no memory");
488 return ret;
489 }
490 memset(dib,0,sizeof(struct usb_dibusb));
491
492 dib->udev = udev;
493 dib->dibdev = dibdev;
494
495 /* store parameters to structures */
496 dib->rc_query_interval = rc_query_interval;
497 dib->pid_parse = pid_parse;
498 dib->rc_key_repeat_count = rc_key_repeat_count;
499
500 usb_set_intfdata(intf, dib);
501
502 ret = dibusb_init(dib);
503 }
504
505 if (ret == 0)
506 info("%s successfully initialized and connected.",dibdev->name);
507 else
508 info("%s error while loading driver (%d)",dibdev->name,ret);
509 return ret;
510}
511
512static void dibusb_disconnect(struct usb_interface *intf)
513{
514 struct usb_dibusb *dib = usb_get_intfdata(intf);
515 const char *name = DRIVER_DESC;
516
517 usb_set_intfdata(intf,NULL);
518 if (dib != NULL && dib->dibdev != NULL) {
519 name = dib->dibdev->name;
520 dibusb_exit(dib);
521 }
522 info("%s successfully deinitialized and disconnected.",name);
523
524}
525
526/* usb specific object needed to register this driver with the usb subsystem */
527static struct usb_driver dibusb_driver = {
528 .owner = THIS_MODULE,
529 .name = DRIVER_DESC,
530 .probe = dibusb_probe,
531 .disconnect = dibusb_disconnect,
532 .id_table = dib_table,
533};
534
535/* module stuff */
536static int __init usb_dibusb_init(void)
537{
538 int result;
539 if ((result = usb_register(&dibusb_driver))) {
540 err("usb_register failed. Error number %d",result);
541 return result;
542 }
543
544 return 0;
545}
546
547static void __exit usb_dibusb_exit(void)
548{
549 /* deregister this driver from the USB subsystem */
550 usb_deregister(&dibusb_driver);
551}
552
553module_init (usb_dibusb_init);
554module_exit (usb_dibusb_exit);
555
556MODULE_AUTHOR(DRIVER_AUTHOR);
557MODULE_DESCRIPTION(DRIVER_DESC);
558MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dibusb/dvb-dibusb-dvb.c b/drivers/media/dvb/dibusb/dvb-dibusb-dvb.c
new file mode 100644
index 000000000000..04e54ec093f0
--- /dev/null
+++ b/drivers/media/dvb/dibusb/dvb-dibusb-dvb.c
@@ -0,0 +1,185 @@
1/*
2 * dvb-dibusb-dvb.c is part of the driver for mobile USB Budget DVB-T devices
3 * based on reference design made by DiBcom (http://www.dibcom.fr/)
4 *
5 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
6 *
7 * see dvb-dibusb-core.c for more copyright details.
8 *
9 * This file contains functions for initializing and handling the
10 * linux-dvb API.
11 */
12#include "dvb-dibusb.h"
13
14#include <linux/usb.h>
15#include <linux/version.h>
16
17static u32 urb_compl_count;
18
19/*
20 * MPEG2 TS DVB stuff
21 */
22void dibusb_urb_complete(struct urb *urb, struct pt_regs *ptregs)
23{
24 struct usb_dibusb *dib = urb->context;
25
26 deb_ts("urb complete feedcount: %d, status: %d, length: %d\n",dib->feedcount,urb->status,
27 urb->actual_length);
28
29 urb_compl_count++;
30 if (urb_compl_count % 1000 == 0)
31 deb_info("%d urbs completed so far.\n",urb_compl_count);
32
33 switch (urb->status) {
34 case 0: /* success */
35 case -ETIMEDOUT: /* NAK */
36 break;
37 case -ECONNRESET: /* kill */
38 case -ENOENT:
39 case -ESHUTDOWN:
40 return;
41 default: /* error */
42 deb_ts("urb completition error %d.", urb->status);
43 break;
44 }
45
46 if (dib->feedcount > 0 && urb->actual_length > 0) {
47 if (dib->init_state & DIBUSB_STATE_DVB)
48 dvb_dmx_swfilter(&dib->demux, (u8*) urb->transfer_buffer,urb->actual_length);
49 } else
50 deb_ts("URB dropped because of feedcount.\n");
51
52 usb_submit_urb(urb,GFP_ATOMIC);
53}
54
55static int dibusb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed, int onoff)
56{
57 struct usb_dibusb *dib = dvbdmxfeed->demux->priv;
58 int newfeedcount;
59
60 if (dib == NULL)
61 return -ENODEV;
62
63 newfeedcount = dib->feedcount + (onoff ? 1 : -1);
64
65 /*
66 * stop feed before setting a new pid if there will be no pid anymore
67 */
68 if (newfeedcount == 0) {
69 deb_ts("stop feeding\n");
70 if (dib->xfer_ops.fifo_ctrl != NULL) {
71 if (dib->xfer_ops.fifo_ctrl(dib->fe,0)) {
72 err("error while inhibiting fifo.");
73 return -ENODEV;
74 }
75 }
76 dibusb_streaming(dib,0);
77 }
78
79 dib->feedcount = newfeedcount;
80
81 /* activate the pid on the device specific pid_filter */
82 deb_ts("setting pid: %5d %04x at index %d '%s'\n",dvbdmxfeed->pid,dvbdmxfeed->pid,dvbdmxfeed->index,onoff ? "on" : "off");
83 if (dib->pid_parse && dib->xfer_ops.pid_ctrl != NULL)
84 dib->xfer_ops.pid_ctrl(dib->fe,dvbdmxfeed->index,dvbdmxfeed->pid,onoff);
85
86 /*
87 * start the feed if this was the first pid to set and there is still a pid
88 * for reception.
89 */
90 if (dib->feedcount == onoff && dib->feedcount > 0) {
91
92 deb_ts("controlling pid parser\n");
93 if (dib->xfer_ops.pid_parse != NULL) {
94 if (dib->xfer_ops.pid_parse(dib->fe,dib->pid_parse) < 0) {
95 err("could not handle pid_parser");
96 }
97 }
98
99 deb_ts("start feeding\n");
100 if (dib->xfer_ops.fifo_ctrl != NULL) {
101 if (dib->xfer_ops.fifo_ctrl(dib->fe,1)) {
102 err("error while enabling fifo.");
103 return -ENODEV;
104 }
105 }
106 dibusb_streaming(dib,1);
107 }
108 return 0;
109}
110
111static int dibusb_start_feed(struct dvb_demux_feed *dvbdmxfeed)
112{
113 deb_ts("start pid: 0x%04x, feedtype: %d\n", dvbdmxfeed->pid,dvbdmxfeed->type);
114 return dibusb_ctrl_feed(dvbdmxfeed,1);
115}
116
117static int dibusb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
118{
119 deb_ts("stop pid: 0x%04x, feedtype: %d\n", dvbdmxfeed->pid, dvbdmxfeed->type);
120 return dibusb_ctrl_feed(dvbdmxfeed,0);
121}
122
123int dibusb_dvb_init(struct usb_dibusb *dib)
124{
125 int ret;
126
127 urb_compl_count = 0;
128
129 if ((ret = dvb_register_adapter(&dib->adapter, DRIVER_DESC,
130 THIS_MODULE)) < 0) {
131 deb_info("dvb_register_adapter failed: error %d", ret);
132 goto err;
133 }
134 dib->adapter->priv = dib;
135
136/* i2c is done in dibusb_i2c_init */
137
138 dib->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING;
139
140 dib->demux.priv = (void *)dib;
141 /* get pidcount from demod */
142 dib->demux.feednum = dib->demux.filternum = 255;
143 dib->demux.start_feed = dibusb_start_feed;
144 dib->demux.stop_feed = dibusb_stop_feed;
145 dib->demux.write_to_decoder = NULL;
146 if ((ret = dvb_dmx_init(&dib->demux)) < 0) {
147 err("dvb_dmx_init failed: error %d",ret);
148 goto err_dmx;
149 }
150
151 dib->dmxdev.filternum = dib->demux.filternum;
152 dib->dmxdev.demux = &dib->demux.dmx;
153 dib->dmxdev.capabilities = 0;
154 if ((ret = dvb_dmxdev_init(&dib->dmxdev, dib->adapter)) < 0) {
155 err("dvb_dmxdev_init failed: error %d",ret);
156 goto err_dmx_dev;
157 }
158
159 dvb_net_init(dib->adapter, &dib->dvb_net, &dib->demux.dmx);
160
161 goto success;
162err_dmx_dev:
163 dvb_dmx_release(&dib->demux);
164err_dmx:
165 dvb_unregister_adapter(dib->adapter);
166err:
167 return ret;
168success:
169 dib->init_state |= DIBUSB_STATE_DVB;
170 return 0;
171}
172
173int dibusb_dvb_exit(struct usb_dibusb *dib)
174{
175 if (dib->init_state & DIBUSB_STATE_DVB) {
176 dib->init_state &= ~DIBUSB_STATE_DVB;
177 deb_info("unregistering DVB part\n");
178 dvb_net_release(&dib->dvb_net);
179 dib->demux.dmx.close(&dib->demux.dmx);
180 dvb_dmxdev_release(&dib->dmxdev);
181 dvb_dmx_release(&dib->demux);
182 dvb_unregister_adapter(dib->adapter);
183 }
184 return 0;
185}
diff --git a/drivers/media/dvb/dibusb/dvb-dibusb-fe-i2c.c b/drivers/media/dvb/dibusb/dvb-dibusb-fe-i2c.c
new file mode 100644
index 000000000000..2ed89488c7c4
--- /dev/null
+++ b/drivers/media/dvb/dibusb/dvb-dibusb-fe-i2c.c
@@ -0,0 +1,582 @@
1/*
2 * dvb-dibusb-fe-i2c.c is part of the driver for mobile USB Budget DVB-T devices
3 * based on reference design made by DiBcom (http://www.dibcom.fr/)
4 *
5 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
6 *
7 * see dvb-dibusb-core.c for more copyright details.
8 *
9 * This file contains functions for attaching, initializing of an appropriate
10 * demodulator/frontend. I2C-stuff is also located here.
11 *
12 */
13#include "dvb-dibusb.h"
14
15#include <linux/usb.h>
16
17static int dibusb_i2c_msg(struct usb_dibusb *dib, u8 addr,
18 u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen)
19{
20 u8 sndbuf[wlen+4]; /* lead(1) devaddr,direction(1) addr(2) data(wlen) (len(2) (when reading)) */
21 /* write only ? */
22 int wo = (rbuf == NULL || rlen == 0),
23 len = 2 + wlen + (wo ? 0 : 2);
24
25 sndbuf[0] = wo ? DIBUSB_REQ_I2C_WRITE : DIBUSB_REQ_I2C_READ;
26 sndbuf[1] = (addr << 1) | (wo ? 0 : 1);
27
28 memcpy(&sndbuf[2],wbuf,wlen);
29
30 if (!wo) {
31 sndbuf[wlen+2] = (rlen >> 8) & 0xff;
32 sndbuf[wlen+3] = rlen & 0xff;
33 }
34
35 return dibusb_readwrite_usb(dib,sndbuf,len,rbuf,rlen);
36}
37
38/*
39 * I2C master xfer function
40 */
41static int dibusb_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg *msg,int num)
42{
43 struct usb_dibusb *dib = i2c_get_adapdata(adap);
44 int i;
45
46 if (down_interruptible(&dib->i2c_sem) < 0)
47 return -EAGAIN;
48
49 if (num > 2)
50 warn("more than 2 i2c messages at a time is not handled yet. TODO.");
51
52 for (i = 0; i < num; i++) {
53 /* write/read request */
54 if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) {
55 if (dibusb_i2c_msg(dib, msg[i].addr, msg[i].buf,msg[i].len,
56 msg[i+1].buf,msg[i+1].len) < 0)
57 break;
58 i++;
59 } else
60 if (dibusb_i2c_msg(dib, msg[i].addr, msg[i].buf,msg[i].len,NULL,0) < 0)
61 break;
62 }
63
64 up(&dib->i2c_sem);
65 return i;
66}
67
68static u32 dibusb_i2c_func(struct i2c_adapter *adapter)
69{
70 return I2C_FUNC_I2C;
71}
72
73static struct i2c_algorithm dibusb_algo = {
74 .name = "DiBcom USB i2c algorithm",
75 .id = I2C_ALGO_BIT,
76 .master_xfer = dibusb_i2c_xfer,
77 .functionality = dibusb_i2c_func,
78};
79
80static int dibusb_general_demod_init(struct dvb_frontend *fe);
81static u8 dibusb_general_pll_addr(struct dvb_frontend *fe);
82static int dibusb_general_pll_init(struct dvb_frontend *fe, u8 pll_buf[5]);
83static int dibusb_general_pll_set(struct dvb_frontend *fe,
84 struct dvb_frontend_parameters* params, u8 pll_buf[5]);
85
86static struct mt352_config mt352_hanftek_umt_010_config = {
87 .demod_address = 0x1e,
88 .demod_init = dibusb_general_demod_init,
89 .pll_set = dibusb_general_pll_set,
90};
91
92static int dibusb_tuner_quirk(struct usb_dibusb *dib)
93{
94 switch (dib->dibdev->dev_cl->id) {
95 case DIBUSB1_1: /* some these device have the ENV77H11D5 and some the THOMSON CABLE */
96 case DIBUSB1_1_AN2235: { /* actually its this device, but in warm state they are indistinguishable */
97 struct dibusb_tuner *t;
98 u8 b[2] = { 0,0 } ,b2[1];
99 struct i2c_msg msg[2] = {
100 { .flags = 0, .buf = b, .len = 2 },
101 { .flags = I2C_M_RD, .buf = b2, .len = 1},
102 };
103
104 t = &dibusb_tuner[DIBUSB_TUNER_COFDM_PANASONIC_ENV77H11D5];
105
106 msg[0].addr = msg[1].addr = t->pll_addr;
107
108 if (dib->xfer_ops.tuner_pass_ctrl != NULL)
109 dib->xfer_ops.tuner_pass_ctrl(dib->fe,1,t->pll_addr);
110 dibusb_i2c_xfer(&dib->i2c_adap,msg,2);
111 if (dib->xfer_ops.tuner_pass_ctrl != NULL)
112 dib->xfer_ops.tuner_pass_ctrl(dib->fe,0,t->pll_addr);
113
114 if (b2[0] == 0xfe)
115 info("this device has the Thomson Cable onboard. Which is default.");
116 else {
117 dib->tuner = t;
118 info("this device has the Panasonic ENV77H11D5 onboard.");
119 }
120 break;
121 }
122 default:
123 break;
124 }
125 return 0;
126}
127
128int dibusb_fe_init(struct usb_dibusb* dib)
129{
130 struct dib3000_config demod_cfg;
131 int i;
132
133 if (dib->init_state & DIBUSB_STATE_I2C) {
134 for (i = 0; i < sizeof(dib->dibdev->dev_cl->demod->i2c_addrs) / sizeof(unsigned char) &&
135 dib->dibdev->dev_cl->demod->i2c_addrs[i] != 0; i++) {
136
137 demod_cfg.demod_address = dib->dibdev->dev_cl->demod->i2c_addrs[i];
138 demod_cfg.pll_addr = dibusb_general_pll_addr;
139 demod_cfg.pll_set = dibusb_general_pll_set;
140 demod_cfg.pll_init = dibusb_general_pll_init;
141
142 deb_info("demod id: %d %d\n",dib->dibdev->dev_cl->demod->id,DTT200U_FE);
143
144 switch (dib->dibdev->dev_cl->demod->id) {
145 case DIBUSB_DIB3000MB:
146 dib->fe = dib3000mb_attach(&demod_cfg,&dib->i2c_adap,&dib->xfer_ops);
147 break;
148 case DIBUSB_DIB3000MC:
149 dib->fe = dib3000mc_attach(&demod_cfg,&dib->i2c_adap,&dib->xfer_ops);
150 break;
151 case DIBUSB_MT352:
152 mt352_hanftek_umt_010_config.demod_address = dib->dibdev->dev_cl->demod->i2c_addrs[i];
153 dib->fe = mt352_attach(&mt352_hanftek_umt_010_config, &dib->i2c_adap);
154 break;
155 case DTT200U_FE:
156 dib->fe = dtt200u_fe_attach(dib,&dib->xfer_ops);
157 break;
158 }
159 if (dib->fe != NULL) {
160 info("found demodulator at i2c address 0x%x",dib->dibdev->dev_cl->demod->i2c_addrs[i]);
161 break;
162 }
163 }
164 /* if a frontend was found */
165 if (dib->fe != NULL) {
166 if (dib->fe->ops->sleep != NULL)
167 dib->fe_sleep = dib->fe->ops->sleep;
168 dib->fe->ops->sleep = dibusb_hw_sleep;
169
170 if (dib->fe->ops->init != NULL )
171 dib->fe_init = dib->fe->ops->init;
172 dib->fe->ops->init = dibusb_hw_wakeup;
173
174 /* setting the default tuner */
175 dib->tuner = dib->dibdev->dev_cl->tuner;
176
177 /* check which tuner is mounted on this device, in case this is unsure */
178 dibusb_tuner_quirk(dib);
179 }
180 }
181 if (dib->fe == NULL) {
182 err("A frontend driver was not found for device '%s'.",
183 dib->dibdev->name);
184 return -ENODEV;
185 } else {
186 if (dvb_register_frontend(dib->adapter, dib->fe)) {
187 err("Frontend registration failed.");
188 if (dib->fe->ops->release)
189 dib->fe->ops->release(dib->fe);
190 dib->fe = NULL;
191 return -ENODEV;
192 }
193 }
194
195 return 0;
196}
197
198int dibusb_fe_exit(struct usb_dibusb *dib)
199{
200 if (dib->fe != NULL)
201 dvb_unregister_frontend(dib->fe);
202 return 0;
203}
204
205int dibusb_i2c_init(struct usb_dibusb *dib)
206{
207 int ret = 0;
208
209 dib->adapter->priv = dib;
210
211 strncpy(dib->i2c_adap.name,dib->dibdev->name,I2C_NAME_SIZE);
212#ifdef I2C_ADAP_CLASS_TV_DIGITAL
213 dib->i2c_adap.class = I2C_ADAP_CLASS_TV_DIGITAL,
214#else
215 dib->i2c_adap.class = I2C_CLASS_TV_DIGITAL,
216#endif
217 dib->i2c_adap.algo = &dibusb_algo;
218 dib->i2c_adap.algo_data = NULL;
219 dib->i2c_adap.id = I2C_ALGO_BIT;
220
221 i2c_set_adapdata(&dib->i2c_adap, dib);
222
223 if ((ret = i2c_add_adapter(&dib->i2c_adap)) < 0)
224 err("could not add i2c adapter");
225
226 dib->init_state |= DIBUSB_STATE_I2C;
227
228 return ret;
229}
230
231int dibusb_i2c_exit(struct usb_dibusb *dib)
232{
233 if (dib->init_state & DIBUSB_STATE_I2C)
234 i2c_del_adapter(&dib->i2c_adap);
235 dib->init_state &= ~DIBUSB_STATE_I2C;
236 return 0;
237}
238
239
240/* pll stuff, maybe removed soon (thx to Gerd/Andrew in advance) */
241static int thomson_cable_eu_pll_set(struct dvb_frontend_parameters *fep, u8 pllbuf[4])
242{
243 u32 tfreq = (fep->frequency + 36125000) / 62500;
244 int vu,p0,p1,p2;
245
246 if (fep->frequency > 403250000)
247 vu = 1, p2 = 1, p1 = 0, p0 = 1;
248 else if (fep->frequency > 115750000)
249 vu = 0, p2 = 1, p1 = 1, p0 = 0;
250 else if (fep->frequency > 44250000)
251 vu = 0, p2 = 0, p1 = 1, p0 = 1;
252 else
253 return -EINVAL;
254
255 pllbuf[0] = (tfreq >> 8) & 0x7f;
256 pllbuf[1] = tfreq & 0xff;
257 pllbuf[2] = 0x8e;
258 pllbuf[3] = (vu << 7) | (p2 << 2) | (p1 << 1) | p0;
259 return 0;
260}
261
262static int panasonic_cofdm_env57h1xd5_pll_set(struct dvb_frontend_parameters *fep, u8 pllbuf[4])
263{
264 u32 freq_khz = fep->frequency / 1000;
265 u32 tfreq = ((freq_khz + 36125)*6 + 500) / 1000;
266 u8 TA, T210, R210, ctrl1, cp210, p4321;
267 if (freq_khz > 858000) {
268 err("frequency cannot be larger than 858 MHz.");
269 return -EINVAL;
270 }
271
272 // contol data 1 : 1 | T/A=1 | T2,T1,T0 = 0,0,0 | R2,R1,R0 = 0,1,0
273 TA = 1;
274 T210 = 0;
275 R210 = 0x2;
276 ctrl1 = (1 << 7) | (TA << 6) | (T210 << 3) | R210;
277
278// ******** CHARGE PUMP CONFIG vs RF FREQUENCIES *****************
279 if (freq_khz < 470000)
280 cp210 = 2; // VHF Low and High band ch E12 to E4 to E12
281 else if (freq_khz < 526000)
282 cp210 = 4; // UHF band Ch E21 to E27
283 else // if (freq < 862000000)
284 cp210 = 5; // UHF band ch E28 to E69
285
286//********************* BW select *******************************
287 if (freq_khz < 153000)
288 p4321 = 1; // BW selected for VHF low
289 else if (freq_khz < 470000)
290 p4321 = 2; // BW selected for VHF high E5 to E12
291 else // if (freq < 862000000)
292 p4321 = 4; // BW selection for UHF E21 to E69
293
294 pllbuf[0] = (tfreq >> 8) & 0xff;
295 pllbuf[1] = (tfreq >> 0) & 0xff;
296 pllbuf[2] = 0xff & ctrl1;
297 pllbuf[3] = (cp210 << 5) | (p4321);
298
299 return 0;
300}
301
302/*
303 * 7 6 5 4 3 2 1 0
304 * Address Byte 1 1 0 0 0 MA1 MA0 R/~W=0
305 *
306 * Program divider byte 1 0 n14 n13 n12 n11 n10 n9 n8
307 * Program divider byte 2 n7 n6 n5 n4 n3 n2 n1 n0
308 *
309 * Control byte 1 1 T/A=1 T2 T1 T0 R2 R1 R0
310 * 1 T/A=0 0 0 ATC AL2 AL1 AL0
311 *
312 * Control byte 2 CP2 CP1 CP0 BS5 BS4 BS3 BS2 BS1
313 *
314 * MA0/1 = programmable address bits
315 * R/~W = read/write bit (0 for writing)
316 * N14-0 = programmable LO frequency
317 *
318 * T/A = test AGC bit (0 = next 6 bits AGC setting,
319 * 1 = next 6 bits test and reference divider ratio settings)
320 * T2-0 = test bits
321 * R2-0 = reference divider ratio and programmable frequency step
322 * ATC = AGC current setting and time constant
323 * ATC = 0: AGC current = 220nA, AGC time constant = 2s
324 * ATC = 1: AGC current = 9uA, AGC time constant = 50ms
325 * AL2-0 = AGC take-over point bits
326 * CP2-0 = charge pump current
327 * BS5-1 = PMOS ports control bits;
328 * BSn = 0 corresponding port is off, high-impedance state (at power-on)
329 * BSn = 1 corresponding port is on
330 */
331static int panasonic_cofdm_env77h11d5_tda6650_init(struct dvb_frontend *fe, u8 pllbuf[4])
332{
333 pllbuf[0] = 0x0b;
334 pllbuf[1] = 0xf5;
335 pllbuf[2] = 0x85;
336 pllbuf[3] = 0xab;
337 return 0;
338}
339
340static int panasonic_cofdm_env77h11d5_tda6650_set (struct dvb_frontend_parameters *fep,u8 pllbuf[4])
341{
342 int tuner_frequency = 0;
343 u8 band, cp, filter;
344
345 // determine charge pump
346 tuner_frequency = fep->frequency + 36166000;
347 if (tuner_frequency < 87000000)
348 return -EINVAL;
349 else if (tuner_frequency < 130000000)
350 cp = 3;
351 else if (tuner_frequency < 160000000)
352 cp = 5;
353 else if (tuner_frequency < 200000000)
354 cp = 6;
355 else if (tuner_frequency < 290000000)
356 cp = 3;
357 else if (tuner_frequency < 420000000)
358 cp = 5;
359 else if (tuner_frequency < 480000000)
360 cp = 6;
361 else if (tuner_frequency < 620000000)
362 cp = 3;
363 else if (tuner_frequency < 830000000)
364 cp = 5;
365 else if (tuner_frequency < 895000000)
366 cp = 7;
367 else
368 return -EINVAL;
369
370 // determine band
371 if (fep->frequency < 49000000)
372 return -EINVAL;
373 else if (fep->frequency < 161000000)
374 band = 1;
375 else if (fep->frequency < 444000000)
376 band = 2;
377 else if (fep->frequency < 861000000)
378 band = 4;
379 else
380 return -EINVAL;
381
382 // setup PLL filter
383 switch (fep->u.ofdm.bandwidth) {
384 case BANDWIDTH_6_MHZ:
385 case BANDWIDTH_7_MHZ:
386 filter = 0;
387 break;
388 case BANDWIDTH_8_MHZ:
389 filter = 1;
390 break;
391 default:
392 return -EINVAL;
393 }
394
395 // calculate divisor
396 // ((36166000+((1000000/6)/2)) + Finput)/(1000000/6)
397 tuner_frequency = (((fep->frequency / 1000) * 6) + 217496) / 1000;
398
399 // setup tuner buffer
400 pllbuf[0] = (tuner_frequency >> 8) & 0x7f;
401 pllbuf[1] = tuner_frequency & 0xff;
402 pllbuf[2] = 0xca;
403 pllbuf[3] = (cp << 5) | (filter << 3) | band;
404 return 0;
405}
406
407/*
408 * 7 6 5 4 3 2 1 0
409 * Address Byte 1 1 0 0 0 MA1 MA0 R/~W=0
410 *
411 * Program divider byte 1 0 n14 n13 n12 n11 n10 n9 n8
412 * Program divider byte 2 n7 n6 n5 n4 n3 n2 n1 n0
413 *
414 * Control byte 1 CP T2 T1 T0 RSA RSB OS
415 *
416 * Band Switch byte X X X P4 P3 P2 P1 P0
417 *
418 * Auxiliary byte ATC AL2 AL1 AL0 0 0 0 0
419 *
420 * Address: MA1 MA0 Address
421 * 0 0 c0
422 * 0 1 c2 (always valid)
423 * 1 0 c4
424 * 1 1 c6
425 */
426static int lg_tdtp_e102p_tua6034(struct dvb_frontend_parameters* fep, u8 pllbuf[4])
427{
428 u32 div;
429 u8 p210, p3;
430
431#define TUNER_MUL 62500
432
433 div = (fep->frequency + 36125000 + TUNER_MUL / 2) / TUNER_MUL;
434// div = ((fep->frequency/1000 + 36166) * 6) / 1000;
435
436 if (fep->frequency < 174500000)
437 p210 = 1; // not supported by the tdtp_e102p
438 else if (fep->frequency < 230000000) // VHF
439 p210 = 2;
440 else
441 p210 = 4;
442
443 if (fep->u.ofdm.bandwidth == BANDWIDTH_7_MHZ)
444 p3 = 0;
445 else
446 p3 = 1;
447
448 pllbuf[0] = (div >> 8) & 0x7f;
449 pllbuf[1] = div & 0xff;
450 pllbuf[2] = 0xce;
451// pllbuf[2] = 0xcc;
452 pllbuf[3] = (p3 << 3) | p210;
453
454 return 0;
455}
456
457static int lg_tdtp_e102p_mt352_demod_init(struct dvb_frontend *fe)
458{
459 static u8 mt352_clock_config[] = { 0x89, 0xb8, 0x2d };
460 static u8 mt352_reset[] = { 0x50, 0x80 };
461 static u8 mt352_mclk_ratio[] = { 0x8b, 0x00 };
462 static u8 mt352_adc_ctl_1_cfg[] = { 0x8E, 0x40 };
463 static u8 mt352_agc_cfg[] = { 0x67, 0x10, 0xa0 };
464
465 static u8 mt352_sec_agc_cfg1[] = { 0x6a, 0xff };
466 static u8 mt352_sec_agc_cfg2[] = { 0x6d, 0xff };
467 static u8 mt352_sec_agc_cfg3[] = { 0x70, 0x40 };
468 static u8 mt352_sec_agc_cfg4[] = { 0x7b, 0x03 };
469 static u8 mt352_sec_agc_cfg5[] = { 0x7d, 0x0f };
470
471 static u8 mt352_acq_ctl[] = { 0x53, 0x50 };
472 static u8 mt352_input_freq_1[] = { 0x56, 0x31, 0x06 };
473
474 mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config));
475 udelay(2000);
476 mt352_write(fe, mt352_reset, sizeof(mt352_reset));
477 mt352_write(fe, mt352_mclk_ratio, sizeof(mt352_mclk_ratio));
478
479 mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg));
480 mt352_write(fe, mt352_agc_cfg, sizeof(mt352_agc_cfg));
481
482 mt352_write(fe, mt352_sec_agc_cfg1, sizeof(mt352_sec_agc_cfg1));
483 mt352_write(fe, mt352_sec_agc_cfg2, sizeof(mt352_sec_agc_cfg2));
484 mt352_write(fe, mt352_sec_agc_cfg3, sizeof(mt352_sec_agc_cfg3));
485 mt352_write(fe, mt352_sec_agc_cfg4, sizeof(mt352_sec_agc_cfg4));
486 mt352_write(fe, mt352_sec_agc_cfg5, sizeof(mt352_sec_agc_cfg5));
487
488 mt352_write(fe, mt352_acq_ctl, sizeof(mt352_acq_ctl));
489 mt352_write(fe, mt352_input_freq_1, sizeof(mt352_input_freq_1));
490
491 return 0;
492}
493
494static int dibusb_general_demod_init(struct dvb_frontend *fe)
495{
496 struct usb_dibusb* dib = (struct usb_dibusb*) fe->dvb->priv;
497 switch (dib->dibdev->dev_cl->id) {
498 case UMT2_0:
499 return lg_tdtp_e102p_mt352_demod_init(fe);
500 default: /* other device classes do not have device specific demod inits */
501 break;
502 }
503 return 0;
504}
505
506static u8 dibusb_general_pll_addr(struct dvb_frontend *fe)
507{
508 struct usb_dibusb* dib = (struct usb_dibusb*) fe->dvb->priv;
509 return dib->tuner->pll_addr;
510}
511
512static int dibusb_pll_i2c_helper(struct usb_dibusb *dib, u8 pll_buf[5], u8 buf[4])
513{
514 if (pll_buf == NULL) {
515 struct i2c_msg msg = {
516 .addr = dib->tuner->pll_addr,
517 .flags = 0,
518 .buf = buf,
519 .len = sizeof(buf)
520 };
521 if (i2c_transfer (&dib->i2c_adap, &msg, 1) != 1)
522 return -EIO;
523 msleep(1);
524 } else {
525 pll_buf[0] = dib->tuner->pll_addr << 1;
526 memcpy(&pll_buf[1],buf,4);
527 }
528
529 return 0;
530}
531
532static int dibusb_general_pll_init(struct dvb_frontend *fe,
533 u8 pll_buf[5])
534{
535 struct usb_dibusb* dib = (struct usb_dibusb*) fe->dvb->priv;
536 u8 buf[4];
537 int ret=0;
538 switch (dib->tuner->id) {
539 case DIBUSB_TUNER_COFDM_PANASONIC_ENV77H11D5:
540 ret = panasonic_cofdm_env77h11d5_tda6650_init(fe,buf);
541 break;
542 default:
543 break;
544 }
545
546 if (ret)
547 return ret;
548
549 return dibusb_pll_i2c_helper(dib,pll_buf,buf);
550}
551
552static int dibusb_general_pll_set(struct dvb_frontend *fe,
553 struct dvb_frontend_parameters *fep, u8 pll_buf[5])
554{
555 struct usb_dibusb* dib = (struct usb_dibusb*) fe->dvb->priv;
556 u8 buf[4];
557 int ret=0;
558
559 switch (dib->tuner->id) {
560 case DIBUSB_TUNER_CABLE_THOMSON:
561 ret = thomson_cable_eu_pll_set(fep, buf);
562 break;
563 case DIBUSB_TUNER_COFDM_PANASONIC_ENV57H1XD5:
564 ret = panasonic_cofdm_env57h1xd5_pll_set(fep, buf);
565 break;
566 case DIBUSB_TUNER_CABLE_LG_TDTP_E102P:
567 ret = lg_tdtp_e102p_tua6034(fep, buf);
568 break;
569 case DIBUSB_TUNER_COFDM_PANASONIC_ENV77H11D5:
570 ret = panasonic_cofdm_env77h11d5_tda6650_set(fep,buf);
571 break;
572 default:
573 warn("no pll programming routine found for tuner %d.\n",dib->tuner->id);
574 ret = -ENODEV;
575 break;
576 }
577
578 if (ret)
579 return ret;
580
581 return dibusb_pll_i2c_helper(dib,pll_buf,buf);
582}
diff --git a/drivers/media/dvb/dibusb/dvb-dibusb-firmware.c b/drivers/media/dvb/dibusb/dvb-dibusb-firmware.c
new file mode 100644
index 000000000000..504ba47afdf3
--- /dev/null
+++ b/drivers/media/dvb/dibusb/dvb-dibusb-firmware.c
@@ -0,0 +1,87 @@
1/*
2 * dvb-dibusb-firmware.c is part of the driver for mobile USB Budget DVB-T devices
3 * based on reference design made by DiBcom (http://www.dibcom.fr/)
4 *
5 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
6 *
7 * see dvb-dibusb-core.c for more copyright details.
8 *
9 * This file contains functions for downloading the firmware to the device.
10 */
11#include "dvb-dibusb.h"
12
13#include <linux/firmware.h>
14#include <linux/usb.h>
15
16/*
17 * load a firmware packet to the device
18 */
19static int dibusb_writemem(struct usb_device *udev,u16 addr,u8 *data, u8 len)
20{
21 return usb_control_msg(udev, usb_sndctrlpipe(udev,0),
22 0xa0, USB_TYPE_VENDOR, addr, 0x00, data, len, 5000);
23}
24
25int dibusb_loadfirmware(struct usb_device *udev, struct dibusb_usb_device *dibdev)
26{
27 const struct firmware *fw = NULL;
28 u16 addr;
29 u8 *b,*p;
30 int ret = 0,i;
31
32 if ((ret = request_firmware(&fw, dibdev->dev_cl->firmware, &udev->dev)) != 0) {
33 err("did not find the firmware file. (%s) "
34 "Please see linux/Documentation/dvb/ for more details on firmware-problems.",
35 dibdev->dev_cl->firmware);
36 return ret;
37 }
38
39 info("downloading firmware from file '%s'.",dibdev->dev_cl->firmware);
40
41 p = kmalloc(fw->size,GFP_KERNEL);
42 if (p != NULL) {
43 u8 reset;
44 /*
45 * you cannot use the fw->data as buffer for
46 * usb_control_msg, a new buffer has to be
47 * created
48 */
49 memcpy(p,fw->data,fw->size);
50
51 /* stop the CPU */
52 reset = 1;
53 if ((ret = dibusb_writemem(udev,dibdev->dev_cl->usb_ctrl->cpu_cs_register,&reset,1)) != 1)
54 err("could not stop the USB controller CPU.");
55 for(i = 0; p[i+3] == 0 && i < fw->size; ) {
56 b = (u8 *) &p[i];
57 addr = *((u16 *) &b[1]);
58
59 ret = dibusb_writemem(udev,addr,&b[4],b[0]);
60
61 if (ret != b[0]) {
62 err("error while transferring firmware "
63 "(transferred size: %d, block size: %d)",
64 ret,b[0]);
65 ret = -EINVAL;
66 break;
67 }
68 i += 5 + b[0];
69 }
70 /* length in ret */
71 if (ret > 0)
72 ret = 0;
73 /* restart the CPU */
74 reset = 0;
75 if (ret || dibusb_writemem(udev,dibdev->dev_cl->usb_ctrl->cpu_cs_register,&reset,1) != 1) {
76 err("could not restart the USB controller CPU.");
77 ret = -EINVAL;
78 }
79
80 kfree(p);
81 } else {
82 ret = -ENOMEM;
83 }
84 release_firmware(fw);
85
86 return ret;
87}
diff --git a/drivers/media/dvb/dibusb/dvb-dibusb-remote.c b/drivers/media/dvb/dibusb/dvb-dibusb-remote.c
new file mode 100644
index 000000000000..9dc8b15517b7
--- /dev/null
+++ b/drivers/media/dvb/dibusb/dvb-dibusb-remote.c
@@ -0,0 +1,316 @@
1/*
2 * dvb-dibusb-remote.c is part of the driver for mobile USB Budget DVB-T devices
3 * based on reference design made by DiBcom (http://www.dibcom.fr/)
4 *
5 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
6 *
7 * see dvb-dibusb-core.c for more copyright details.
8 *
9 * This file contains functions for handling the event device on the software
10 * side and the remote control on the hardware side.
11 */
12#include "dvb-dibusb.h"
13
14/* Table to map raw key codes to key events. This should not be hard-wired
15 into the kernel. */
16static const struct { u8 c0, c1, c2; uint32_t key; } nec_rc_keys [] =
17{
18 /* Key codes for the little Artec T1/Twinhan/HAMA/ remote. */
19 { 0x00, 0xff, 0x16, KEY_POWER },
20 { 0x00, 0xff, 0x10, KEY_MUTE },
21 { 0x00, 0xff, 0x03, KEY_1 },
22 { 0x00, 0xff, 0x01, KEY_2 },
23 { 0x00, 0xff, 0x06, KEY_3 },
24 { 0x00, 0xff, 0x09, KEY_4 },
25 { 0x00, 0xff, 0x1d, KEY_5 },
26 { 0x00, 0xff, 0x1f, KEY_6 },
27 { 0x00, 0xff, 0x0d, KEY_7 },
28 { 0x00, 0xff, 0x19, KEY_8 },
29 { 0x00, 0xff, 0x1b, KEY_9 },
30 { 0x00, 0xff, 0x15, KEY_0 },
31 { 0x00, 0xff, 0x05, KEY_CHANNELUP },
32 { 0x00, 0xff, 0x02, KEY_CHANNELDOWN },
33 { 0x00, 0xff, 0x1e, KEY_VOLUMEUP },
34 { 0x00, 0xff, 0x0a, KEY_VOLUMEDOWN },
35 { 0x00, 0xff, 0x11, KEY_RECORD },
36 { 0x00, 0xff, 0x17, KEY_FAVORITES }, /* Heart symbol - Channel list. */
37 { 0x00, 0xff, 0x14, KEY_PLAY },
38 { 0x00, 0xff, 0x1a, KEY_STOP },
39 { 0x00, 0xff, 0x40, KEY_REWIND },
40 { 0x00, 0xff, 0x12, KEY_FASTFORWARD },
41 { 0x00, 0xff, 0x0e, KEY_PREVIOUS }, /* Recall - Previous channel. */
42 { 0x00, 0xff, 0x4c, KEY_PAUSE },
43 { 0x00, 0xff, 0x4d, KEY_SCREEN }, /* Full screen mode. */
44 { 0x00, 0xff, 0x54, KEY_AUDIO }, /* MTS - Switch to secondary audio. */
45 /* additional keys TwinHan VisionPlus, the Artec seemingly not have */
46 { 0x00, 0xff, 0x0c, KEY_CANCEL }, /* Cancel */
47 { 0x00, 0xff, 0x1c, KEY_EPG }, /* EPG */
48 { 0x00, 0xff, 0x00, KEY_TAB }, /* Tab */
49 { 0x00, 0xff, 0x48, KEY_INFO }, /* Preview */
50 { 0x00, 0xff, 0x04, KEY_LIST }, /* RecordList */
51 { 0x00, 0xff, 0x0f, KEY_TEXT }, /* Teletext */
52 /* Key codes for the KWorld/ADSTech/JetWay remote. */
53 { 0x86, 0x6b, 0x12, KEY_POWER },
54 { 0x86, 0x6b, 0x0f, KEY_SELECT }, /* source */
55 { 0x86, 0x6b, 0x0c, KEY_UNKNOWN }, /* scan */
56 { 0x86, 0x6b, 0x0b, KEY_EPG },
57 { 0x86, 0x6b, 0x10, KEY_MUTE },
58 { 0x86, 0x6b, 0x01, KEY_1 },
59 { 0x86, 0x6b, 0x02, KEY_2 },
60 { 0x86, 0x6b, 0x03, KEY_3 },
61 { 0x86, 0x6b, 0x04, KEY_4 },
62 { 0x86, 0x6b, 0x05, KEY_5 },
63 { 0x86, 0x6b, 0x06, KEY_6 },
64 { 0x86, 0x6b, 0x07, KEY_7 },
65 { 0x86, 0x6b, 0x08, KEY_8 },
66 { 0x86, 0x6b, 0x09, KEY_9 },
67 { 0x86, 0x6b, 0x0a, KEY_0 },
68 { 0x86, 0x6b, 0x18, KEY_ZOOM },
69 { 0x86, 0x6b, 0x1c, KEY_UNKNOWN }, /* preview */
70 { 0x86, 0x6b, 0x13, KEY_UNKNOWN }, /* snap */
71 { 0x86, 0x6b, 0x00, KEY_UNDO },
72 { 0x86, 0x6b, 0x1d, KEY_RECORD },
73 { 0x86, 0x6b, 0x0d, KEY_STOP },
74 { 0x86, 0x6b, 0x0e, KEY_PAUSE },
75 { 0x86, 0x6b, 0x16, KEY_PLAY },
76 { 0x86, 0x6b, 0x11, KEY_BACK },
77 { 0x86, 0x6b, 0x19, KEY_FORWARD },
78 { 0x86, 0x6b, 0x14, KEY_UNKNOWN }, /* pip */
79 { 0x86, 0x6b, 0x15, KEY_ESC },
80 { 0x86, 0x6b, 0x1a, KEY_UP },
81 { 0x86, 0x6b, 0x1e, KEY_DOWN },
82 { 0x86, 0x6b, 0x1f, KEY_LEFT },
83 { 0x86, 0x6b, 0x1b, KEY_RIGHT },
84};
85
86/* Hauppauge NOVA-T USB2 keys */
87static const struct { u16 raw; uint32_t key; } haupp_rc_keys [] = {
88 { 0xddf, KEY_GOTO },
89 { 0xdef, KEY_POWER },
90 { 0xce7, KEY_TV },
91 { 0xcc7, KEY_VIDEO },
92 { 0xccf, KEY_AUDIO },
93 { 0xcd7, KEY_MEDIA },
94 { 0xcdf, KEY_EPG },
95 { 0xca7, KEY_UP },
96 { 0xc67, KEY_RADIO },
97 { 0xcb7, KEY_LEFT },
98 { 0xd2f, KEY_OK },
99 { 0xcbf, KEY_RIGHT },
100 { 0xcff, KEY_BACK },
101 { 0xcaf, KEY_DOWN },
102 { 0xc6f, KEY_MENU },
103 { 0xc87, KEY_VOLUMEUP },
104 { 0xc8f, KEY_VOLUMEDOWN },
105 { 0xc97, KEY_CHANNEL },
106 { 0xc7f, KEY_MUTE },
107 { 0xd07, KEY_CHANNELUP },
108 { 0xd0f, KEY_CHANNELDOWN },
109 { 0xdbf, KEY_RECORD },
110 { 0xdb7, KEY_STOP },
111 { 0xd97, KEY_REWIND },
112 { 0xdaf, KEY_PLAY },
113 { 0xda7, KEY_FASTFORWARD },
114 { 0xd27, KEY_LAST }, /* Skip backwards */
115 { 0xd87, KEY_PAUSE },
116 { 0xcf7, KEY_NEXT },
117 { 0xc07, KEY_0 },
118 { 0xc0f, KEY_1 },
119 { 0xc17, KEY_2 },
120 { 0xc1f, KEY_3 },
121 { 0xc27, KEY_4 },
122 { 0xc2f, KEY_5 },
123 { 0xc37, KEY_6 },
124 { 0xc3f, KEY_7 },
125 { 0xc47, KEY_8 },
126 { 0xc4f, KEY_9 },
127 { 0xc57, KEY_KPASTERISK },
128 { 0xc77, KEY_GRAVE }, /* # */
129 { 0xc5f, KEY_RED },
130 { 0xd77, KEY_GREEN },
131 { 0xdc7, KEY_YELLOW },
132 { 0xd4f, KEY_BLUE},
133};
134
135static int dibusb_key2event_nec(struct usb_dibusb *dib,u8 rb[5])
136{
137 int i;
138 switch (rb[0]) {
139 case DIBUSB_RC_NEC_KEY_PRESSED:
140 /* rb[1-3] is the actual key, rb[4] is a checksum */
141 deb_rc("raw key code 0x%02x, 0x%02x, 0x%02x, 0x%02x\n",
142 rb[1], rb[2], rb[3], rb[4]);
143
144 if ((0xff - rb[3]) != rb[4]) {
145 deb_rc("remote control checksum failed.\n");
146 break;
147 }
148
149 /* See if we can match the raw key code. */
150 for (i = 0; i < sizeof(nec_rc_keys)/sizeof(nec_rc_keys[0]); i++) {
151 if (nec_rc_keys[i].c0 == rb[1] &&
152 nec_rc_keys[i].c1 == rb[2] &&
153 nec_rc_keys[i].c2 == rb[3]) {
154
155 dib->last_event = nec_rc_keys[i].key;
156 return 1;
157 }
158 }
159 break;
160 case DIBUSB_RC_NEC_KEY_REPEATED:
161 /* rb[1]..rb[4] are always zero.*/
162 /* Repeats often seem to occur so for the moment just ignore this. */
163 return 0;
164 case DIBUSB_RC_NEC_EMPTY: /* No (more) remote control keys. */
165 default:
166 break;
167 }
168 return -1;
169}
170
171static int dibusb_key2event_hauppauge(struct usb_dibusb *dib,u8 rb[4])
172{
173 u16 raw;
174 int i,state;
175 switch (rb[0]) {
176 case DIBUSB_RC_HAUPPAUGE_KEY_PRESSED:
177 raw = ((rb[1] & 0x0f) << 8) | rb[2];
178
179 state = !!(rb[1] & 0x40);
180
181 deb_rc("raw key code 0x%02x, 0x%02x, 0x%02x to %04x state: %d\n",rb[1],rb[2],rb[3],raw,state);
182 for (i = 0; i < sizeof(haupp_rc_keys)/sizeof(haupp_rc_keys[0]); i++) {
183 if (haupp_rc_keys[i].raw == raw) {
184 if (dib->last_event == haupp_rc_keys[i].key &&
185 dib->last_state == state) {
186 deb_rc("key repeat\n");
187 return 0;
188 } else {
189 dib->last_event = haupp_rc_keys[i].key;
190 dib->last_state = state;
191 return 1;
192 }
193 }
194 }
195
196 break;
197 case DIBUSB_RC_HAUPPAUGE_KEY_EMPTY:
198 default:
199 break;
200 }
201 return -1;
202}
203
204/*
205 * Read the remote control and feed the appropriate event.
206 * NEC protocol is used for remote controls
207 */
208static int dibusb_read_remote_control(struct usb_dibusb *dib)
209{
210 u8 b[1] = { DIBUSB_REQ_POLL_REMOTE }, rb[5];
211 int ret,event = 0;
212
213 if ((ret = dibusb_readwrite_usb(dib,b,1,rb,5)))
214 return ret;
215
216 switch (dib->dibdev->dev_cl->remote_type) {
217 case DIBUSB_RC_NEC_PROTOCOL:
218 event = dibusb_key2event_nec(dib,rb);
219 break;
220 case DIBUSB_RC_HAUPPAUGE_PROTO:
221 event = dibusb_key2event_hauppauge(dib,rb);
222 default:
223 break;
224 }
225
226 /* key repeat */
227 if (event == 0)
228 if (++dib->repeat_key_count < dib->rc_key_repeat_count) {
229 deb_rc("key repeat dropped. (%d)\n",dib->repeat_key_count);
230 event = -1; /* skip this key repeat */
231 }
232
233 if (event == 1 || event == 0) {
234 deb_rc("Translated key 0x%04x\n",event);
235
236 /* Signal down and up events for this key. */
237 input_report_key(&dib->rc_input_dev, dib->last_event, 1);
238 input_report_key(&dib->rc_input_dev, dib->last_event, 0);
239 input_sync(&dib->rc_input_dev);
240
241 if (event == 1)
242 dib->repeat_key_count = 0;
243 }
244 return 0;
245}
246
247/* Remote-control poll function - called every dib->rc_query_interval ms to see
248 whether the remote control has received anything. */
249static void dibusb_remote_query(void *data)
250{
251 struct usb_dibusb *dib = (struct usb_dibusb *) data;
252 /* TODO: need a lock here. We can simply skip checking for the remote control
253 if we're busy. */
254 dibusb_read_remote_control(dib);
255 schedule_delayed_work(&dib->rc_query_work,
256 msecs_to_jiffies(dib->rc_query_interval));
257}
258
259int dibusb_remote_init(struct usb_dibusb *dib)
260{
261 int i;
262
263 if (dib->dibdev->dev_cl->remote_type == DIBUSB_RC_NO)
264 return 0;
265
266 /* Initialise the remote-control structures.*/
267 init_input_dev(&dib->rc_input_dev);
268
269 dib->rc_input_dev.evbit[0] = BIT(EV_KEY);
270 dib->rc_input_dev.keycodesize = sizeof(unsigned char);
271 dib->rc_input_dev.keycodemax = KEY_MAX;
272 dib->rc_input_dev.name = DRIVER_DESC " remote control";
273
274 switch (dib->dibdev->dev_cl->remote_type) {
275 case DIBUSB_RC_NEC_PROTOCOL:
276 for (i=0; i<sizeof(nec_rc_keys)/sizeof(nec_rc_keys[0]); i++)
277 set_bit(nec_rc_keys[i].key, dib->rc_input_dev.keybit);
278 break;
279 case DIBUSB_RC_HAUPPAUGE_PROTO:
280 for (i=0; i<sizeof(haupp_rc_keys)/sizeof(haupp_rc_keys[0]); i++)
281 set_bit(haupp_rc_keys[i].key, dib->rc_input_dev.keybit);
282 break;
283 default:
284 break;
285 }
286
287
288 input_register_device(&dib->rc_input_dev);
289
290 INIT_WORK(&dib->rc_query_work, dibusb_remote_query, dib);
291
292 /* Start the remote-control polling. */
293 if (dib->rc_query_interval < 40)
294 dib->rc_query_interval = 100; /* default */
295
296 info("schedule remote query interval to %d msecs.",dib->rc_query_interval);
297 schedule_delayed_work(&dib->rc_query_work,msecs_to_jiffies(dib->rc_query_interval));
298
299 dib->init_state |= DIBUSB_STATE_REMOTE;
300
301 return 0;
302}
303
304int dibusb_remote_exit(struct usb_dibusb *dib)
305{
306 if (dib->dibdev->dev_cl->remote_type == DIBUSB_RC_NO)
307 return 0;
308
309 if (dib->init_state & DIBUSB_STATE_REMOTE) {
310 cancel_delayed_work(&dib->rc_query_work);
311 flush_scheduled_work();
312 input_unregister_device(&dib->rc_input_dev);
313 }
314 dib->init_state &= ~DIBUSB_STATE_REMOTE;
315 return 0;
316}
diff --git a/drivers/media/dvb/dibusb/dvb-dibusb-usb.c b/drivers/media/dvb/dibusb/dvb-dibusb-usb.c
new file mode 100644
index 000000000000..642f0596a5ba
--- /dev/null
+++ b/drivers/media/dvb/dibusb/dvb-dibusb-usb.c
@@ -0,0 +1,303 @@
1/*
2 * dvb-dibusb-usb.c is part of the driver for mobile USB Budget DVB-T devices
3 * based on reference design made by DiBcom (http://www.dibcom.fr/)
4 *
5 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
6 *
7 * see dvb-dibusb-core.c for more copyright details.
8 *
9 * This file contains functions for initializing and handling the
10 * usb specific stuff.
11 */
12#include "dvb-dibusb.h"
13
14#include <linux/version.h>
15#include <linux/pci.h>
16
17int dibusb_readwrite_usb(struct usb_dibusb *dib, u8 *wbuf, u16 wlen, u8 *rbuf,
18 u16 rlen)
19{
20 int actlen,ret = -ENOMEM;
21
22 if (wbuf == NULL || wlen == 0)
23 return -EINVAL;
24
25 if ((ret = down_interruptible(&dib->usb_sem)))
26 return ret;
27
28 debug_dump(wbuf,wlen);
29
30 ret = usb_bulk_msg(dib->udev,usb_sndbulkpipe(dib->udev,
31 dib->dibdev->dev_cl->pipe_cmd), wbuf,wlen,&actlen,
32 DIBUSB_I2C_TIMEOUT);
33
34 if (ret)
35 err("bulk message failed: %d (%d/%d)",ret,wlen,actlen);
36 else
37 ret = actlen != wlen ? -1 : 0;
38
39 /* an answer is expected, and no error before */
40 if (!ret && rbuf && rlen) {
41 ret = usb_bulk_msg(dib->udev,usb_rcvbulkpipe(dib->udev,
42 dib->dibdev->dev_cl->pipe_cmd),rbuf,rlen,&actlen,
43 DIBUSB_I2C_TIMEOUT);
44
45 if (ret)
46 err("recv bulk message failed: %d",ret);
47 else {
48 deb_alot("rlen: %d\n",rlen);
49 debug_dump(rbuf,actlen);
50 }
51 }
52
53 up(&dib->usb_sem);
54 return ret;
55}
56
57/*
58 * Cypress controls
59 */
60int dibusb_write_usb(struct usb_dibusb *dib, u8 *buf, u16 len)
61{
62 return dibusb_readwrite_usb(dib,buf,len,NULL,0);
63}
64
65#if 0
66/*
67 * #if 0'ing the following functions as they are not in use _now_,
68 * but probably will be sometime.
69 */
70/*
71 * do not use this, just a workaround for a bug,
72 * which will hopefully never occur :).
73 */
74int dibusb_interrupt_read_loop(struct usb_dibusb *dib)
75{
76 u8 b[1] = { DIBUSB_REQ_INTR_READ };
77 return dibusb_write_usb(dib,b,1);
78}
79#endif
80
81/*
82 * ioctl for the firmware
83 */
84static int dibusb_ioctl_cmd(struct usb_dibusb *dib, u8 cmd, u8 *param, int plen)
85{
86 u8 b[34];
87 int size = plen > 32 ? 32 : plen;
88 memset(b,0,34);
89 b[0] = DIBUSB_REQ_SET_IOCTL;
90 b[1] = cmd;
91
92 if (size > 0)
93 memcpy(&b[2],param,size);
94
95 return dibusb_write_usb(dib,b,34); //2+size);
96}
97
98/*
99 * ioctl for power control
100 */
101int dibusb_hw_wakeup(struct dvb_frontend *fe)
102{
103 struct usb_dibusb *dib = (struct usb_dibusb *) fe->dvb->priv;
104 u8 b[1] = { DIBUSB_IOCTL_POWER_WAKEUP };
105 deb_info("dibusb-device is getting up.\n");
106
107 switch (dib->dibdev->dev_cl->id) {
108 case DTT200U:
109 break;
110 default:
111 dibusb_ioctl_cmd(dib,DIBUSB_IOCTL_CMD_POWER_MODE, b,1);
112 break;
113 }
114
115 if (dib->fe_init)
116 return dib->fe_init(fe);
117
118 return 0;
119}
120
121int dibusb_hw_sleep(struct dvb_frontend *fe)
122{
123 struct usb_dibusb *dib = (struct usb_dibusb *) fe->dvb->priv;
124 u8 b[1] = { DIBUSB_IOCTL_POWER_SLEEP };
125 deb_info("dibusb-device is going to bed.\n");
126 /* workaround, something is wrong, when dibusb 1.1 device are going to bed too late */
127 switch (dib->dibdev->dev_cl->id) {
128 case DIBUSB1_1:
129 case NOVAT_USB2:
130 case DTT200U:
131 break;
132 default:
133 dibusb_ioctl_cmd(dib,DIBUSB_IOCTL_CMD_POWER_MODE, b,1);
134 break;
135 }
136 if (dib->fe_sleep)
137 return dib->fe_sleep(fe);
138
139 return 0;
140}
141
142int dibusb_set_streaming_mode(struct usb_dibusb *dib,u8 mode)
143{
144 u8 b[2] = { DIBUSB_REQ_SET_STREAMING_MODE, mode };
145 return dibusb_readwrite_usb(dib,b,2,NULL,0);
146}
147
148static int dibusb_urb_kill(struct usb_dibusb *dib)
149{
150 int i;
151deb_info("trying to kill urbs\n");
152 if (dib->init_state & DIBUSB_STATE_URB_SUBMIT) {
153 for (i = 0; i < dib->dibdev->dev_cl->urb_count; i++) {
154 deb_info("killing URB no. %d.\n",i);
155
156 /* stop the URB */
157 usb_kill_urb(dib->urb_list[i]);
158 }
159 } else
160 deb_info(" URBs not killed.\n");
161 dib->init_state &= ~DIBUSB_STATE_URB_SUBMIT;
162 return 0;
163}
164
165static int dibusb_urb_submit(struct usb_dibusb *dib)
166{
167 int i,ret;
168 if (dib->init_state & DIBUSB_STATE_URB_INIT) {
169 for (i = 0; i < dib->dibdev->dev_cl->urb_count; i++) {
170 deb_info("submitting URB no. %d\n",i);
171 if ((ret = usb_submit_urb(dib->urb_list[i],GFP_ATOMIC))) {
172 err("could not submit buffer urb no. %d - get them all back\n",i);
173 dibusb_urb_kill(dib);
174 return ret;
175 }
176 dib->init_state |= DIBUSB_STATE_URB_SUBMIT;
177 }
178 }
179 return 0;
180}
181
182int dibusb_streaming(struct usb_dibusb *dib,int onoff)
183{
184 if (onoff)
185 dibusb_urb_submit(dib);
186 else
187 dibusb_urb_kill(dib);
188
189 switch (dib->dibdev->dev_cl->id) {
190 case DIBUSB2_0:
191 case DIBUSB2_0B:
192 case NOVAT_USB2:
193 case UMT2_0:
194 if (onoff)
195 return dibusb_ioctl_cmd(dib,DIBUSB_IOCTL_CMD_ENABLE_STREAM,NULL,0);
196 else
197 return dibusb_ioctl_cmd(dib,DIBUSB_IOCTL_CMD_DISABLE_STREAM,NULL,0);
198 break;
199 default:
200 break;
201 }
202 return 0;
203}
204
205int dibusb_urb_init(struct usb_dibusb *dib)
206{
207 int i,bufsize,def_pid_parse = 1;
208
209 /*
210 * when reloading the driver w/o replugging the device
211 * a timeout occures, this helps
212 */
213 usb_clear_halt(dib->udev,usb_sndbulkpipe(dib->udev,dib->dibdev->dev_cl->pipe_cmd));
214 usb_clear_halt(dib->udev,usb_rcvbulkpipe(dib->udev,dib->dibdev->dev_cl->pipe_cmd));
215 usb_clear_halt(dib->udev,usb_rcvbulkpipe(dib->udev,dib->dibdev->dev_cl->pipe_data));
216
217 /* allocate the array for the data transfer URBs */
218 dib->urb_list = kmalloc(dib->dibdev->dev_cl->urb_count*sizeof(struct urb *),GFP_KERNEL);
219 if (dib->urb_list == NULL)
220 return -ENOMEM;
221 memset(dib->urb_list,0,dib->dibdev->dev_cl->urb_count*sizeof(struct urb *));
222
223 dib->init_state |= DIBUSB_STATE_URB_LIST;
224
225 bufsize = dib->dibdev->dev_cl->urb_count*dib->dibdev->dev_cl->urb_buffer_size;
226 deb_info("allocate %d bytes as buffersize for all URBs\n",bufsize);
227 /* allocate the actual buffer for the URBs */
228 if ((dib->buffer = pci_alloc_consistent(NULL,bufsize,&dib->dma_handle)) == NULL) {
229 deb_info("not enough memory.\n");
230 return -ENOMEM;
231 }
232 deb_info("allocation complete\n");
233 memset(dib->buffer,0,bufsize);
234
235 dib->init_state |= DIBUSB_STATE_URB_BUF;
236
237 /* allocate and submit the URBs */
238 for (i = 0; i < dib->dibdev->dev_cl->urb_count; i++) {
239 if (!(dib->urb_list[i] = usb_alloc_urb(0,GFP_ATOMIC))) {
240 return -ENOMEM;
241 }
242
243 usb_fill_bulk_urb( dib->urb_list[i], dib->udev,
244 usb_rcvbulkpipe(dib->udev,dib->dibdev->dev_cl->pipe_data),
245 &dib->buffer[i*dib->dibdev->dev_cl->urb_buffer_size],
246 dib->dibdev->dev_cl->urb_buffer_size,
247 dibusb_urb_complete, dib);
248
249 dib->urb_list[i]->transfer_flags = 0;
250
251 dib->init_state |= DIBUSB_STATE_URB_INIT;
252 }
253
254 /* dib->pid_parse here contains the value of the module parameter */
255 /* decide if pid parsing can be deactivated:
256 * is possible (by device type) and wanted (by user)
257 */
258 switch (dib->dibdev->dev_cl->id) {
259 case DIBUSB2_0:
260 case DIBUSB2_0B:
261 if (dib->udev->speed == USB_SPEED_HIGH && !dib->pid_parse) {
262 def_pid_parse = 0;
263 info("running at HIGH speed, will deliver the complete TS.");
264 } else
265 info("will use pid_parsing.");
266 break;
267 default:
268 break;
269 }
270 /* from here on it contains the device and user decision */
271 dib->pid_parse = def_pid_parse;
272
273 return 0;
274}
275
276int dibusb_urb_exit(struct usb_dibusb *dib)
277{
278 int i;
279
280 dibusb_urb_kill(dib);
281
282 if (dib->init_state & DIBUSB_STATE_URB_LIST) {
283 for (i = 0; i < dib->dibdev->dev_cl->urb_count; i++) {
284 if (dib->urb_list[i] != NULL) {
285 deb_info("freeing URB no. %d.\n",i);
286 /* free the URBs */
287 usb_free_urb(dib->urb_list[i]);
288 }
289 }
290 /* free the urb array */
291 kfree(dib->urb_list);
292 dib->init_state &= ~DIBUSB_STATE_URB_LIST;
293 }
294
295 if (dib->init_state & DIBUSB_STATE_URB_BUF)
296 pci_free_consistent(NULL,
297 dib->dibdev->dev_cl->urb_buffer_size*dib->dibdev->dev_cl->urb_count,
298 dib->buffer,dib->dma_handle);
299
300 dib->init_state &= ~DIBUSB_STATE_URB_BUF;
301 dib->init_state &= ~DIBUSB_STATE_URB_INIT;
302 return 0;
303}
diff --git a/drivers/media/dvb/dibusb/dvb-dibusb.h b/drivers/media/dvb/dibusb/dvb-dibusb.h
new file mode 100644
index 000000000000..52cd35dd9d83
--- /dev/null
+++ b/drivers/media/dvb/dibusb/dvb-dibusb.h
@@ -0,0 +1,327 @@
1/*
2 * dvb-dibusb.h
3 *
4 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation, version 2.
9 *
10 * for more information see dvb-dibusb-core.c .
11 */
12#ifndef __DVB_DIBUSB_H__
13#define __DVB_DIBUSB_H__
14
15#include <linux/input.h>
16#include <linux/config.h>
17#include <linux/usb.h>
18
19#include "dvb_frontend.h"
20#include "dvb_demux.h"
21#include "dvb_net.h"
22#include "dmxdev.h"
23
24#include "dib3000.h"
25#include "mt352.h"
26
27/* debug */
28#ifdef CONFIG_DVB_DIBCOM_DEBUG
29#define dprintk(level,args...) \
30 do { if ((dvb_dibusb_debug & level)) { printk(args); } } while (0)
31
32#define debug_dump(b,l) {\
33 int i; \
34 for (i = 0; i < l; i++) deb_xfer("%02x ", b[i]); \
35 deb_xfer("\n");\
36}
37
38#else
39#define dprintk(args...)
40#define debug_dump(b,l)
41#endif
42
43extern int dvb_dibusb_debug;
44
45/* Version information */
46#define DRIVER_VERSION "0.3"
47#define DRIVER_DESC "DiBcom based USB Budget DVB-T device"
48#define DRIVER_AUTHOR "Patrick Boettcher, patrick.boettcher@desy.de"
49
50#define deb_info(args...) dprintk(0x01,args)
51#define deb_xfer(args...) dprintk(0x02,args)
52#define deb_alot(args...) dprintk(0x04,args)
53#define deb_ts(args...) dprintk(0x08,args)
54#define deb_err(args...) dprintk(0x10,args)
55#define deb_rc(args...) dprintk(0x20,args)
56
57/* generic log methods - taken from usb.h */
58#undef err
59#define err(format, arg...) printk(KERN_ERR "dvb-dibusb: " format "\n" , ## arg)
60#undef info
61#define info(format, arg...) printk(KERN_INFO "dvb-dibusb: " format "\n" , ## arg)
62#undef warn
63#define warn(format, arg...) printk(KERN_WARNING "dvb-dibusb: " format "\n" , ## arg)
64
65struct dibusb_usb_controller {
66 const char *name; /* name of the usb controller */
67 u16 cpu_cs_register; /* needs to be restarted, when the firmware has been downloaded. */
68};
69
70typedef enum {
71 DIBUSB1_1 = 0,
72 DIBUSB1_1_AN2235,
73 DIBUSB2_0,
74 UMT2_0,
75 DIBUSB2_0B,
76 NOVAT_USB2,
77 DTT200U,
78} dibusb_class_t;
79
80typedef enum {
81 DIBUSB_TUNER_CABLE_THOMSON = 0,
82 DIBUSB_TUNER_COFDM_PANASONIC_ENV57H1XD5,
83 DIBUSB_TUNER_CABLE_LG_TDTP_E102P,
84 DIBUSB_TUNER_COFDM_PANASONIC_ENV77H11D5,
85} dibusb_tuner_t;
86
87typedef enum {
88 DIBUSB_DIB3000MB = 0,
89 DIBUSB_DIB3000MC,
90 DIBUSB_MT352,
91 DTT200U_FE,
92} dibusb_demodulator_t;
93
94typedef enum {
95 DIBUSB_RC_NO = 0,
96 DIBUSB_RC_NEC_PROTOCOL,
97 DIBUSB_RC_HAUPPAUGE_PROTO,
98} dibusb_remote_t;
99
100struct dibusb_tuner {
101 dibusb_tuner_t id;
102
103 u8 pll_addr; /* tuner i2c address */
104};
105extern struct dibusb_tuner dibusb_tuner[];
106
107#define DIBUSB_POSSIBLE_I2C_ADDR_NUM 4
108struct dibusb_demod {
109 dibusb_demodulator_t id;
110
111 int pid_filter_count; /* counter of the internal pid_filter */
112 u8 i2c_addrs[DIBUSB_POSSIBLE_I2C_ADDR_NUM]; /* list of possible i2c addresses of the demod */
113};
114
115#define DIBUSB_MAX_TUNER_NUM 2
116struct dibusb_device_class {
117 dibusb_class_t id;
118
119 const struct dibusb_usb_controller *usb_ctrl; /* usb controller */
120 const char *firmware; /* valid firmware filenames */
121
122 int pipe_cmd; /* command pipe (read/write) */
123 int pipe_data; /* data pipe */
124
125 int urb_count; /* number of data URBs to be submitted */
126 int urb_buffer_size; /* the size of the buffer for each URB */
127
128 dibusb_remote_t remote_type; /* does this device have a ir-receiver */
129
130 struct dibusb_demod *demod; /* which demodulator is mount */
131 struct dibusb_tuner *tuner; /* which tuner can be found here */
132};
133
134#define DIBUSB_ID_MAX_NUM 15
135struct dibusb_usb_device {
136 const char *name; /* real name of the box */
137 struct dibusb_device_class *dev_cl; /* which dibusb_device_class is this device part of */
138
139 struct usb_device_id *cold_ids[DIBUSB_ID_MAX_NUM]; /* list of USB ids when this device is at pre firmware state */
140 struct usb_device_id *warm_ids[DIBUSB_ID_MAX_NUM]; /* list of USB ids when this device is at post firmware state */
141};
142
143/* a PID for the pid_filter list, when in use */
144struct dibusb_pid
145{
146 int index;
147 u16 pid;
148 int active;
149};
150
151struct usb_dibusb {
152 /* usb */
153 struct usb_device * udev;
154
155 struct dibusb_usb_device * dibdev;
156
157#define DIBUSB_STATE_INIT 0x000
158#define DIBUSB_STATE_URB_LIST 0x001
159#define DIBUSB_STATE_URB_BUF 0x002
160#define DIBUSB_STATE_URB_INIT 0x004
161#define DIBUSB_STATE_DVB 0x008
162#define DIBUSB_STATE_I2C 0x010
163#define DIBUSB_STATE_REMOTE 0x020
164#define DIBUSB_STATE_URB_SUBMIT 0x040
165 int init_state;
166
167 int feedcount;
168 struct dib_fe_xfer_ops xfer_ops;
169
170 struct dibusb_tuner *tuner;
171
172 struct urb **urb_list;
173 u8 *buffer;
174 dma_addr_t dma_handle;
175
176 /* I2C */
177 struct i2c_adapter i2c_adap;
178
179 /* locking */
180 struct semaphore usb_sem;
181 struct semaphore i2c_sem;
182
183 /* dvb */
184 struct dvb_adapter *adapter;
185 struct dmxdev dmxdev;
186 struct dvb_demux demux;
187 struct dvb_net dvb_net;
188 struct dvb_frontend* fe;
189
190 int (*fe_sleep) (struct dvb_frontend *);
191 int (*fe_init) (struct dvb_frontend *);
192
193 /* remote control */
194 struct input_dev rc_input_dev;
195 struct work_struct rc_query_work;
196 int last_event;
197 int last_state; /* for Hauppauge RC protocol */
198 int repeat_key_count;
199 int rc_key_repeat_count; /* module parameter */
200
201 /* module parameters */
202 int pid_parse;
203 int rc_query_interval;
204};
205
206/* commonly used functions in the separated files */
207
208/* dvb-dibusb-firmware.c */
209int dibusb_loadfirmware(struct usb_device *udev, struct dibusb_usb_device *dibdev);
210
211/* dvb-dibusb-remote.c */
212int dibusb_remote_exit(struct usb_dibusb *dib);
213int dibusb_remote_init(struct usb_dibusb *dib);
214
215/* dvb-dibusb-fe-i2c.c */
216int dibusb_fe_init(struct usb_dibusb* dib);
217int dibusb_fe_exit(struct usb_dibusb *dib);
218int dibusb_i2c_init(struct usb_dibusb *dib);
219int dibusb_i2c_exit(struct usb_dibusb *dib);
220
221/* dvb-dibusb-dvb.c */
222void dibusb_urb_complete(struct urb *urb, struct pt_regs *ptregs);
223int dibusb_dvb_init(struct usb_dibusb *dib);
224int dibusb_dvb_exit(struct usb_dibusb *dib);
225
226/* dvb-dibusb-usb.c */
227int dibusb_readwrite_usb(struct usb_dibusb *dib, u8 *wbuf, u16 wlen, u8 *rbuf,
228 u16 rlen);
229int dibusb_write_usb(struct usb_dibusb *dib, u8 *buf, u16 len);
230
231int dibusb_hw_wakeup(struct dvb_frontend *);
232int dibusb_hw_sleep(struct dvb_frontend *);
233int dibusb_set_streaming_mode(struct usb_dibusb *,u8);
234int dibusb_streaming(struct usb_dibusb *,int);
235
236int dibusb_urb_init(struct usb_dibusb *);
237int dibusb_urb_exit(struct usb_dibusb *);
238
239/* dvb-fe-dtt200u.c */
240struct dvb_frontend* dtt200u_fe_attach(struct usb_dibusb *,struct dib_fe_xfer_ops *);
241
242/* i2c and transfer stuff */
243#define DIBUSB_I2C_TIMEOUT 5000
244
245/*
246 * protocol of all dibusb related devices
247 */
248
249/*
250 * bulk msg to/from endpoint 0x01
251 *
252 * general structure:
253 * request_byte parameter_bytes
254 */
255
256#define DIBUSB_REQ_START_READ 0x00
257#define DIBUSB_REQ_START_DEMOD 0x01
258
259/*
260 * i2c read
261 * bulk write: 0x02 ((7bit i2c_addr << 1) & 0x01) register_bytes length_word
262 * bulk read: byte_buffer (length_word bytes)
263 */
264#define DIBUSB_REQ_I2C_READ 0x02
265
266/*
267 * i2c write
268 * bulk write: 0x03 (7bit i2c_addr << 1) register_bytes value_bytes
269 */
270#define DIBUSB_REQ_I2C_WRITE 0x03
271
272/*
273 * polling the value of the remote control
274 * bulk write: 0x04
275 * bulk read: byte_buffer (5 bytes)
276 *
277 * first byte of byte_buffer shows the status (0x00, 0x01, 0x02)
278 */
279#define DIBUSB_REQ_POLL_REMOTE 0x04
280
281#define DIBUSB_RC_NEC_EMPTY 0x00
282#define DIBUSB_RC_NEC_KEY_PRESSED 0x01
283#define DIBUSB_RC_NEC_KEY_REPEATED 0x02
284
285/* additional status values for Hauppauge Remote Control Protocol */
286#define DIBUSB_RC_HAUPPAUGE_KEY_PRESSED 0x01
287#define DIBUSB_RC_HAUPPAUGE_KEY_EMPTY 0x03
288
289/* streaming mode:
290 * bulk write: 0x05 mode_byte
291 *
292 * mode_byte is mostly 0x00
293 */
294#define DIBUSB_REQ_SET_STREAMING_MODE 0x05
295
296/* interrupt the internal read loop, when blocking */
297#define DIBUSB_REQ_INTR_READ 0x06
298
299/* io control
300 * 0x07 cmd_byte param_bytes
301 *
302 * param_bytes can be up to 32 bytes
303 *
304 * cmd_byte function parameter name
305 * 0x00 power mode
306 * 0x00 sleep
307 * 0x01 wakeup
308 *
309 * 0x01 enable streaming
310 * 0x02 disable streaming
311 *
312 *
313 */
314#define DIBUSB_REQ_SET_IOCTL 0x07
315
316/* IOCTL commands */
317
318/* change the power mode in firmware */
319#define DIBUSB_IOCTL_CMD_POWER_MODE 0x00
320#define DIBUSB_IOCTL_POWER_SLEEP 0x00
321#define DIBUSB_IOCTL_POWER_WAKEUP 0x01
322
323/* modify streaming of the FX2 */
324#define DIBUSB_IOCTL_CMD_ENABLE_STREAM 0x01
325#define DIBUSB_IOCTL_CMD_DISABLE_STREAM 0x02
326
327#endif
diff --git a/drivers/media/dvb/dibusb/dvb-fe-dtt200u.c b/drivers/media/dvb/dibusb/dvb-fe-dtt200u.c
new file mode 100644
index 000000000000..1872aa6d200a
--- /dev/null
+++ b/drivers/media/dvb/dibusb/dvb-fe-dtt200u.c
@@ -0,0 +1,263 @@
1/*
2 * dvb-dtt200u-fe.c is a driver which implements the frontend-part of the
3 * Yakumo/Typhoon/Hama USB2.0 boxes. It is hard-wired to the dibusb-driver as
4 * it uses the usb-transfer functions directly (maybe creating a
5 * generic-dvb-usb-lib for all usb-drivers will be reduce some more code.)
6 *
7 * Copyright (C) 2005 Patrick Boettcher <patrick.boettcher@desy.de>
8 *
9 * see dvb-dibusb-core.c for copyright details.
10 */
11
12/* guessed protocol description (reverse engineered):
13 * read
14 * 00 - USB type 0x02 for usb2.0, 0x01 for usb1.1
15 * 81 - <TS_LOCK> <current frequency divided by 250000>
16 * 82 - crash - do not touch
17 * 83 - crash - do not touch
18 * 84 - remote control
19 * 85 - crash - do not touch (OK, stop testing here)
20 * 88 - locking 2 bytes (0x80 0x40 == no signal, 0x89 0x20 == nice signal)
21 * 89 - noise-to-signal
22 * 8a - unkown 1 byte - signal_strength
23 * 8c - ber ???
24 * 8d - ber
25 * 8e - unc
26 *
27 * write
28 * 02 - bandwidth
29 * 03 - frequency (divided by 250000)
30 * 04 - pid table (index pid(7:0) pid(12:8))
31 * 05 - reset the pid table
32 * 08 - demod transfer enabled or not (FX2 transfer is enabled by default)
33 */
34
35#include "dvb-dibusb.h"
36#include "dvb_frontend.h"
37
38struct dtt200u_fe_state {
39 struct usb_dibusb *dib;
40
41 struct dvb_frontend_parameters fep;
42 struct dvb_frontend frontend;
43};
44
45#define moan(which,what) info("unexpected value in '%s' for cmd '%02x' - please report to linux-dvb@linuxtv.org",which,what)
46
47static int dtt200u_fe_read_status(struct dvb_frontend* fe, fe_status_t *stat)
48{
49 struct dtt200u_fe_state *state = fe->demodulator_priv;
50 u8 bw[1] = { 0x81 };
51 u8 br[3] = { 0 };
52// u8 bdeb[5] = { 0 };
53
54 dibusb_readwrite_usb(state->dib,bw,1,br,3);
55 switch (br[0]) {
56 case 0x01:
57 *stat = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
58 break;
59 case 0x00:
60 *stat = 0;
61 break;
62 default:
63 moan("br[0]",0x81);
64 break;
65 }
66
67// bw[0] = 0x88;
68// dibusb_readwrite_usb(state->dib,bw,1,bdeb,5);
69
70// deb_info("%02x: %02x %02x %02x %02x %02x\n",bw[0],bdeb[0],bdeb[1],bdeb[2],bdeb[3],bdeb[4]);
71
72 return 0;
73}
74static int dtt200u_fe_read_ber(struct dvb_frontend* fe, u32 *ber)
75{
76 struct dtt200u_fe_state *state = fe->demodulator_priv;
77 u8 bw[1] = { 0x8d };
78 *ber = 0;
79 dibusb_readwrite_usb(state->dib,bw,1,(u8*) ber, 3);
80 return 0;
81}
82
83static int dtt200u_fe_read_unc_blocks(struct dvb_frontend* fe, u32 *unc)
84{
85 struct dtt200u_fe_state *state = fe->demodulator_priv;
86 u8 bw[1] = { 0x8c };
87 *unc = 0;
88 dibusb_readwrite_usb(state->dib,bw,1,(u8*) unc, 3);
89 return 0;
90}
91
92static int dtt200u_fe_read_signal_strength(struct dvb_frontend* fe, u16 *strength)
93{
94 struct dtt200u_fe_state *state = fe->demodulator_priv;
95 u8 bw[1] = { 0x8a };
96 u8 b;
97 dibusb_readwrite_usb(state->dib,bw,1,&b, 1);
98 *strength = (b << 8) | b;
99 return 0;
100}
101
102static int dtt200u_fe_read_snr(struct dvb_frontend* fe, u16 *snr)
103{
104 struct dtt200u_fe_state *state = fe->demodulator_priv;
105 u8 bw[1] = { 0x89 };
106 u8 br[1] = { 0 };
107 dibusb_readwrite_usb(state->dib,bw,1,br,1);
108 *snr = ((0xff - br[0]) << 8) | (0xff - br[0]);
109 return 0;
110}
111
112static int dtt200u_fe_init(struct dvb_frontend* fe)
113{
114 struct dtt200u_fe_state *state = fe->demodulator_priv;
115 u8 b[] = { 0x01 };
116 return dibusb_write_usb(state->dib,b,1);
117}
118
119static int dtt200u_fe_sleep(struct dvb_frontend* fe)
120{
121 return dtt200u_fe_init(fe);
122}
123
124static int dtt200u_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
125{
126 tune->min_delay_ms = 1500;
127 tune->step_size = 166667;
128 tune->max_drift = 166667 * 2;
129 return 0;
130}
131
132static int dtt200u_fe_set_frontend(struct dvb_frontend* fe,
133 struct dvb_frontend_parameters *fep)
134{
135 struct dtt200u_fe_state *state = fe->demodulator_priv;
136 u16 freq = fep->frequency / 250000;
137 u8 bw,bwbuf[2] = { 0x03, 0 }, freqbuf[3] = { 0x02, 0, 0 };
138
139 switch (fep->u.ofdm.bandwidth) {
140 case BANDWIDTH_8_MHZ: bw = 8; break;
141 case BANDWIDTH_7_MHZ: bw = 7; break;
142 case BANDWIDTH_6_MHZ: bw = 6; break;
143 case BANDWIDTH_AUTO: return -EOPNOTSUPP;
144 default:
145 return -EINVAL;
146 }
147 deb_info("set_frontend\n");
148
149 bwbuf[1] = bw;
150 dibusb_write_usb(state->dib,bwbuf,2);
151
152 freqbuf[1] = freq & 0xff;
153 freqbuf[2] = (freq >> 8) & 0xff;
154 dibusb_write_usb(state->dib,freqbuf,3);
155
156 memcpy(&state->fep,fep,sizeof(struct dvb_frontend_parameters));
157
158 return 0;
159}
160
161static int dtt200u_fe_get_frontend(struct dvb_frontend* fe,
162 struct dvb_frontend_parameters *fep)
163{
164 struct dtt200u_fe_state *state = fe->demodulator_priv;
165 memcpy(fep,&state->fep,sizeof(struct dvb_frontend_parameters));
166 return 0;
167}
168
169static void dtt200u_fe_release(struct dvb_frontend* fe)
170{
171 struct dtt200u_fe_state *state = (struct dtt200u_fe_state*) fe->demodulator_priv;
172 kfree(state);
173}
174
175static int dtt200u_pid_control(struct dvb_frontend *fe,int index, int pid,int onoff)
176{
177 struct dtt200u_fe_state *state = (struct dtt200u_fe_state*) fe->demodulator_priv;
178 u8 b_pid[4];
179 pid = onoff ? pid : 0;
180
181 b_pid[0] = 0x04;
182 b_pid[1] = index;
183 b_pid[2] = pid & 0xff;
184 b_pid[3] = (pid >> 8) & 0xff;
185
186 dibusb_write_usb(state->dib,b_pid,4);
187 return 0;
188}
189
190static int dtt200u_fifo_control(struct dvb_frontend *fe, int onoff)
191{
192 struct dtt200u_fe_state *state = (struct dtt200u_fe_state*) fe->demodulator_priv;
193 u8 b_streaming[2] = { 0x08, onoff };
194 u8 b_rst_pid[1] = { 0x05 };
195
196 dibusb_write_usb(state->dib,b_streaming,2);
197
198 if (!onoff)
199 dibusb_write_usb(state->dib,b_rst_pid,1);
200 return 0;
201}
202
203static struct dvb_frontend_ops dtt200u_fe_ops;
204
205struct dvb_frontend* dtt200u_fe_attach(struct usb_dibusb *dib, struct dib_fe_xfer_ops *xfer_ops)
206{
207 struct dtt200u_fe_state* state = NULL;
208
209 /* allocate memory for the internal state */
210 state = (struct dtt200u_fe_state*) kmalloc(sizeof(struct dtt200u_fe_state), GFP_KERNEL);
211 if (state == NULL)
212 goto error;
213 memset(state,0,sizeof(struct dtt200u_fe_state));
214
215 deb_info("attaching frontend dtt200u\n");
216
217 state->dib = dib;
218
219 state->frontend.ops = &dtt200u_fe_ops;
220 state->frontend.demodulator_priv = state;
221
222 xfer_ops->fifo_ctrl = dtt200u_fifo_control;
223 xfer_ops->pid_ctrl = dtt200u_pid_control;
224
225 goto success;
226error:
227 return NULL;
228success:
229 return &state->frontend;
230}
231
232static struct dvb_frontend_ops dtt200u_fe_ops = {
233 .info = {
234 .name = "DTT200U (Yakumo/Typhoon/Hama) DVB-T",
235 .type = FE_OFDM,
236 .frequency_min = 44250000,
237 .frequency_max = 867250000,
238 .frequency_stepsize = 250000,
239 .caps = FE_CAN_INVERSION_AUTO |
240 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
241 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
242 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
243 FE_CAN_TRANSMISSION_MODE_AUTO |
244 FE_CAN_GUARD_INTERVAL_AUTO |
245 FE_CAN_RECOVER |
246 FE_CAN_HIERARCHY_AUTO,
247 },
248
249 .release = dtt200u_fe_release,
250
251 .init = dtt200u_fe_init,
252 .sleep = dtt200u_fe_sleep,
253
254 .set_frontend = dtt200u_fe_set_frontend,
255 .get_frontend = dtt200u_fe_get_frontend,
256 .get_tune_settings = dtt200u_fe_get_tune_settings,
257
258 .read_status = dtt200u_fe_read_status,
259 .read_ber = dtt200u_fe_read_ber,
260 .read_signal_strength = dtt200u_fe_read_signal_strength,
261 .read_snr = dtt200u_fe_read_snr,
262 .read_ucblocks = dtt200u_fe_read_unc_blocks,
263};
diff --git a/drivers/media/dvb/dvb-core/Kconfig b/drivers/media/dvb/dvb-core/Kconfig
new file mode 100644
index 000000000000..a9a7b3421048
--- /dev/null
+++ b/drivers/media/dvb/dvb-core/Kconfig
@@ -0,0 +1,11 @@
1config DVB_CORE
2 tristate "DVB Core Support"
3 depends on DVB
4 select CRC32
5 help
6 DVB core utility functions for device handling, software fallbacks etc.
7 Say Y when you have a DVB card and want to use it. Say Y if your want
8 to build your drivers outside the kernel, but need the DVB core. All
9 in-kernel drivers will select this automatically if needed.
10 If unsure say N.
11
diff --git a/drivers/media/dvb/dvb-core/Makefile b/drivers/media/dvb/dvb-core/Makefile
new file mode 100644
index 000000000000..c6baac20f529
--- /dev/null
+++ b/drivers/media/dvb/dvb-core/Makefile
@@ -0,0 +1,9 @@
1#
2# Makefile for the kernel DVB device drivers.
3#
4
5dvb-core-objs = dvbdev.o dmxdev.o dvb_demux.o dvb_filter.o \
6 dvb_ca_en50221.o dvb_frontend.o \
7 dvb_net.o dvb_ringbuffer.o
8
9obj-$(CONFIG_DVB_CORE) += dvb-core.o
diff --git a/drivers/media/dvb/dvb-core/demux.h b/drivers/media/dvb/dvb-core/demux.h
new file mode 100644
index 000000000000..fb55eaa5c8e7
--- /dev/null
+++ b/drivers/media/dvb/dvb-core/demux.h
@@ -0,0 +1,301 @@
1/*
2 * demux.h
3 *
4 * Copyright (c) 2002 Convergence GmbH
5 *
6 * based on code:
7 * Copyright (c) 2000 Nokia Research Center
8 * Tampere, FINLAND
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public License
12 * as published by the Free Software Foundation; either version 2.1
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 Lesser 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 *
24 */
25
26#ifndef __DEMUX_H
27#define __DEMUX_H
28
29#include <linux/types.h>
30#include <linux/errno.h>
31#include <linux/list.h>
32#include <linux/time.h>
33
34/*--------------------------------------------------------------------------*/
35/* Common definitions */
36/*--------------------------------------------------------------------------*/
37
38/*
39 * DMX_MAX_FILTER_SIZE: Maximum length (in bytes) of a section/PES filter.
40 */
41
42#ifndef DMX_MAX_FILTER_SIZE
43#define DMX_MAX_FILTER_SIZE 18
44#endif
45
46/*
47 * DMX_MAX_SECFEED_SIZE: Maximum length (in bytes) of a private section feed filter.
48 */
49
50#ifndef DMX_MAX_SECFEED_SIZE
51#define DMX_MAX_SECFEED_SIZE 4096
52#endif
53
54
55/*
56 * enum dmx_success: Success codes for the Demux Callback API.
57 */
58
59enum dmx_success {
60 DMX_OK = 0, /* Received Ok */
61 DMX_LENGTH_ERROR, /* Incorrect length */
62 DMX_OVERRUN_ERROR, /* Receiver ring buffer overrun */
63 DMX_CRC_ERROR, /* Incorrect CRC */
64 DMX_FRAME_ERROR, /* Frame alignment error */
65 DMX_FIFO_ERROR, /* Receiver FIFO overrun */
66 DMX_MISSED_ERROR /* Receiver missed packet */
67} ;
68
69/*--------------------------------------------------------------------------*/
70/* TS packet reception */
71/*--------------------------------------------------------------------------*/
72
73/* TS filter type for set() */
74
75#define TS_PACKET 1 /* send TS packets (188 bytes) to callback (default) */
76#define TS_PAYLOAD_ONLY 2 /* in case TS_PACKET is set, only send the TS
77 payload (<=184 bytes per packet) to callback */
78#define TS_DECODER 4 /* send stream to built-in decoder (if present) */
79
80/* PES type for filters which write to built-in decoder */
81/* these should be kept identical to the types in dmx.h */
82
83enum dmx_ts_pes
84{ /* also send packets to decoder (if it exists) */
85 DMX_TS_PES_AUDIO0,
86 DMX_TS_PES_VIDEO0,
87 DMX_TS_PES_TELETEXT0,
88 DMX_TS_PES_SUBTITLE0,
89 DMX_TS_PES_PCR0,
90
91 DMX_TS_PES_AUDIO1,
92 DMX_TS_PES_VIDEO1,
93 DMX_TS_PES_TELETEXT1,
94 DMX_TS_PES_SUBTITLE1,
95 DMX_TS_PES_PCR1,
96
97 DMX_TS_PES_AUDIO2,
98 DMX_TS_PES_VIDEO2,
99 DMX_TS_PES_TELETEXT2,
100 DMX_TS_PES_SUBTITLE2,
101 DMX_TS_PES_PCR2,
102
103 DMX_TS_PES_AUDIO3,
104 DMX_TS_PES_VIDEO3,
105 DMX_TS_PES_TELETEXT3,
106 DMX_TS_PES_SUBTITLE3,
107 DMX_TS_PES_PCR3,
108
109 DMX_TS_PES_OTHER
110};
111
112#define DMX_TS_PES_AUDIO DMX_TS_PES_AUDIO0
113#define DMX_TS_PES_VIDEO DMX_TS_PES_VIDEO0
114#define DMX_TS_PES_TELETEXT DMX_TS_PES_TELETEXT0
115#define DMX_TS_PES_SUBTITLE DMX_TS_PES_SUBTITLE0
116#define DMX_TS_PES_PCR DMX_TS_PES_PCR0
117
118
119struct dmx_ts_feed {
120 int is_filtering; /* Set to non-zero when filtering in progress */
121 struct dmx_demux *parent; /* Back-pointer */
122 void *priv; /* Pointer to private data of the API client */
123 int (*set) (struct dmx_ts_feed *feed,
124 u16 pid,
125 int type,
126 enum dmx_ts_pes pes_type,
127 size_t callback_length,
128 size_t circular_buffer_size,
129 int descramble,
130 struct timespec timeout);
131 int (*start_filtering) (struct dmx_ts_feed* feed);
132 int (*stop_filtering) (struct dmx_ts_feed* feed);
133};
134
135/*--------------------------------------------------------------------------*/
136/* Section reception */
137/*--------------------------------------------------------------------------*/
138
139struct dmx_section_filter {
140 u8 filter_value [DMX_MAX_FILTER_SIZE];
141 u8 filter_mask [DMX_MAX_FILTER_SIZE];
142 u8 filter_mode [DMX_MAX_FILTER_SIZE];
143 struct dmx_section_feed* parent; /* Back-pointer */
144 void* priv; /* Pointer to private data of the API client */
145};
146
147struct dmx_section_feed {
148 int is_filtering; /* Set to non-zero when filtering in progress */
149 struct dmx_demux* parent; /* Back-pointer */
150 void* priv; /* Pointer to private data of the API client */
151
152 int check_crc;
153 u32 crc_val;
154
155 u8 *secbuf;
156 u8 secbuf_base[DMX_MAX_SECFEED_SIZE];
157 u16 secbufp, seclen, tsfeedp;
158
159 int (*set) (struct dmx_section_feed* feed,
160 u16 pid,
161 size_t circular_buffer_size,
162 int descramble,
163 int check_crc);
164 int (*allocate_filter) (struct dmx_section_feed* feed,
165 struct dmx_section_filter** filter);
166 int (*release_filter) (struct dmx_section_feed* feed,
167 struct dmx_section_filter* filter);
168 int (*start_filtering) (struct dmx_section_feed* feed);
169 int (*stop_filtering) (struct dmx_section_feed* feed);
170};
171
172/*--------------------------------------------------------------------------*/
173/* Callback functions */
174/*--------------------------------------------------------------------------*/
175
176typedef int (*dmx_ts_cb) ( const u8 * buffer1,
177 size_t buffer1_length,
178 const u8 * buffer2,
179 size_t buffer2_length,
180 struct dmx_ts_feed* source,
181 enum dmx_success success);
182
183typedef int (*dmx_section_cb) ( const u8 * buffer1,
184 size_t buffer1_len,
185 const u8 * buffer2,
186 size_t buffer2_len,
187 struct dmx_section_filter * source,
188 enum dmx_success success);
189
190/*--------------------------------------------------------------------------*/
191/* DVB Front-End */
192/*--------------------------------------------------------------------------*/
193
194enum dmx_frontend_source {
195 DMX_MEMORY_FE,
196 DMX_FRONTEND_0,
197 DMX_FRONTEND_1,
198 DMX_FRONTEND_2,
199 DMX_FRONTEND_3,
200 DMX_STREAM_0, /* external stream input, e.g. LVDS */
201 DMX_STREAM_1,
202 DMX_STREAM_2,
203 DMX_STREAM_3
204};
205
206struct dmx_frontend {
207 struct list_head connectivity_list; /* List of front-ends that can
208 be connected to a particular
209 demux */
210 void* priv; /* Pointer to private data of the API client */
211 enum dmx_frontend_source source;
212};
213
214/*--------------------------------------------------------------------------*/
215/* MPEG-2 TS Demux */
216/*--------------------------------------------------------------------------*/
217
218/*
219 * Flags OR'ed in the capabilites field of struct dmx_demux.
220 */
221
222#define DMX_TS_FILTERING 1
223#define DMX_PES_FILTERING 2
224#define DMX_SECTION_FILTERING 4
225#define DMX_MEMORY_BASED_FILTERING 8 /* write() available */
226#define DMX_CRC_CHECKING 16
227#define DMX_TS_DESCRAMBLING 32
228#define DMX_SECTION_PAYLOAD_DESCRAMBLING 64
229#define DMX_MAC_ADDRESS_DESCRAMBLING 128
230
231/*
232 * Demux resource type identifier.
233*/
234
235/*
236 * DMX_FE_ENTRY(): Casts elements in the list of registered
237 * front-ends from the generic type struct list_head
238 * to the type * struct dmx_frontend
239 *.
240*/
241
242#define DMX_FE_ENTRY(list) list_entry(list, struct dmx_frontend, connectivity_list)
243
244struct dmx_demux {
245 u32 capabilities; /* Bitfield of capability flags */
246 struct dmx_frontend* frontend; /* Front-end connected to the demux */
247 struct list_head reg_list; /* List of registered demuxes */
248 void* priv; /* Pointer to private data of the API client */
249 int users; /* Number of users */
250 int (*open) (struct dmx_demux* demux);
251 int (*close) (struct dmx_demux* demux);
252 int (*write) (struct dmx_demux* demux, const char* buf, size_t count);
253 int (*allocate_ts_feed) (struct dmx_demux* demux,
254 struct dmx_ts_feed** feed,
255 dmx_ts_cb callback);
256 int (*release_ts_feed) (struct dmx_demux* demux,
257 struct dmx_ts_feed* feed);
258 int (*allocate_section_feed) (struct dmx_demux* demux,
259 struct dmx_section_feed** feed,
260 dmx_section_cb callback);
261 int (*release_section_feed) (struct dmx_demux* demux,
262 struct dmx_section_feed* feed);
263 int (*descramble_mac_address) (struct dmx_demux* demux,
264 u8* buffer1,
265 size_t buffer1_length,
266 u8* buffer2,
267 size_t buffer2_length,
268 u16 pid);
269 int (*descramble_section_payload) (struct dmx_demux* demux,
270 u8* buffer1,
271 size_t buffer1_length,
272 u8* buffer2, size_t buffer2_length,
273 u16 pid);
274 int (*add_frontend) (struct dmx_demux* demux,
275 struct dmx_frontend* frontend);
276 int (*remove_frontend) (struct dmx_demux* demux,
277 struct dmx_frontend* frontend);
278 struct list_head* (*get_frontends) (struct dmx_demux* demux);
279 int (*connect_frontend) (struct dmx_demux* demux,
280 struct dmx_frontend* frontend);
281 int (*disconnect_frontend) (struct dmx_demux* demux);
282
283 int (*get_pes_pids) (struct dmx_demux* demux, u16 *pids);
284
285 int (*get_stc) (struct dmx_demux* demux, unsigned int num,
286 u64 *stc, unsigned int *base);
287};
288
289/*--------------------------------------------------------------------------*/
290/* Demux directory */
291/*--------------------------------------------------------------------------*/
292
293/*
294 * DMX_DIR_ENTRY(): Casts elements in the list of registered
295 * demuxes from the generic type struct list_head* to the type struct dmx_demux
296 *.
297 */
298
299#define DMX_DIR_ENTRY(list) list_entry(list, struct dmx_demux, reg_list)
300
301#endif /* #ifndef __DEMUX_H */
diff --git a/drivers/media/dvb/dvb-core/dmxdev.c b/drivers/media/dvb/dvb-core/dmxdev.c
new file mode 100644
index 000000000000..1863f1dfb00c
--- /dev/null
+++ b/drivers/media/dvb/dvb-core/dmxdev.c
@@ -0,0 +1,1137 @@
1/*
2 * dmxdev.c - DVB demultiplexer device
3 *
4 * Copyright (C) 2000 Ralph Metzler <ralph@convergence.de>
5 * & Marcus Metzler <marcus@convergence.de>
6 for convergence integrated media GmbH
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 *
22 */
23
24#include <linux/spinlock.h>
25#include <linux/slab.h>
26#include <linux/vmalloc.h>
27#include <linux/module.h>
28#include <linux/moduleparam.h>
29#include <linux/sched.h>
30#include <linux/poll.h>
31#include <linux/ioctl.h>
32#include <linux/wait.h>
33#include <asm/uaccess.h>
34#include <asm/system.h>
35
36#include "dmxdev.h"
37
38static int debug;
39
40module_param(debug, int, 0644);
41MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
42
43#define dprintk if (debug) printk
44
45static inline struct dmxdev_filter *
46dvb_dmxdev_file_to_filter(struct file *file)
47{
48 return (struct dmxdev_filter *) file->private_data;
49}
50
51static inline void dvb_dmxdev_buffer_init(struct dmxdev_buffer *buffer)
52{
53 buffer->data=NULL;
54 buffer->size=8192;
55 buffer->pread=0;
56 buffer->pwrite=0;
57 buffer->error=0;
58 init_waitqueue_head(&buffer->queue);
59}
60
61static inline int dvb_dmxdev_buffer_write(struct dmxdev_buffer *buf, const u8 *src, int len)
62{
63 int split;
64 int free;
65 int todo;
66
67 if (!len)
68 return 0;
69 if (!buf->data)
70 return 0;
71
72 free=buf->pread-buf->pwrite;
73 split=0;
74 if (free<=0) {
75 free+=buf->size;
76 split=buf->size-buf->pwrite;
77 }
78 if (len>=free) {
79 dprintk("dmxdev: buffer overflow\n");
80 return -1;
81 }
82 if (split>=len)
83 split=0;
84 todo=len;
85 if (split) {
86 memcpy(buf->data + buf->pwrite, src, split);
87 todo-=split;
88 buf->pwrite=0;
89 }
90 memcpy(buf->data + buf->pwrite, src+split, todo);
91 buf->pwrite=(buf->pwrite+todo)%buf->size;
92 return len;
93}
94
95static ssize_t dvb_dmxdev_buffer_read(struct dmxdev_buffer *src,
96 int non_blocking, char __user *buf, size_t count, loff_t *ppos)
97{
98 unsigned long todo=count;
99 int split, avail, error;
100
101 if (!src->data)
102 return 0;
103
104 if ((error=src->error)) {
105 src->pwrite=src->pread;
106 src->error=0;
107 return error;
108 }
109
110 if (non_blocking && (src->pwrite==src->pread))
111 return -EWOULDBLOCK;
112
113 while (todo>0) {
114 if (non_blocking && (src->pwrite==src->pread))
115 return (count-todo) ? (count-todo) : -EWOULDBLOCK;
116
117 if (wait_event_interruptible(src->queue,
118 (src->pread!=src->pwrite) ||
119 (src->error))<0)
120 return count-todo;
121
122 if ((error=src->error)) {
123 src->pwrite=src->pread;
124 src->error=0;
125 return error;
126 }
127
128 split=src->size;
129 avail=src->pwrite - src->pread;
130 if (avail<0) {
131 avail+=src->size;
132 split=src->size - src->pread;
133 }
134 if (avail>todo)
135 avail=todo;
136 if (split<avail) {
137 if (copy_to_user(buf, src->data+src->pread, split))
138 return -EFAULT;
139 buf+=split;
140 src->pread=0;
141 todo-=split;
142 avail-=split;
143 }
144 if (avail) {
145 if (copy_to_user(buf, src->data+src->pread, avail))
146 return -EFAULT;
147 src->pread = (src->pread + avail) % src->size;
148 todo-=avail;
149 buf+=avail;
150 }
151 }
152 return count;
153}
154
155static struct dmx_frontend * get_fe(struct dmx_demux *demux, int type)
156{
157 struct list_head *head, *pos;
158
159 head=demux->get_frontends(demux);
160 if (!head)
161 return NULL;
162 list_for_each(pos, head)
163 if (DMX_FE_ENTRY(pos)->source==type)
164 return DMX_FE_ENTRY(pos);
165
166 return NULL;
167}
168
169static inline void dvb_dmxdev_dvr_state_set(struct dmxdev_dvr *dmxdevdvr, int state)
170{
171 spin_lock_irq(&dmxdevdvr->dev->lock);
172 dmxdevdvr->state=state;
173 spin_unlock_irq(&dmxdevdvr->dev->lock);
174}
175
176static int dvb_dvr_open(struct inode *inode, struct file *file)
177{
178 struct dvb_device *dvbdev=(struct dvb_device *) file->private_data;
179 struct dmxdev *dmxdev=(struct dmxdev *) dvbdev->priv;
180 struct dmx_frontend *front;
181
182 dprintk ("function : %s\n", __FUNCTION__);
183
184 if (down_interruptible (&dmxdev->mutex))
185 return -ERESTARTSYS;
186
187 if ((file->f_flags&O_ACCMODE)==O_RDWR) {
188 if (!(dmxdev->capabilities&DMXDEV_CAP_DUPLEX)) {
189 up(&dmxdev->mutex);
190 return -EOPNOTSUPP;
191 }
192 }
193
194 if ((file->f_flags&O_ACCMODE)==O_RDONLY) {
195 dvb_dmxdev_buffer_init(&dmxdev->dvr_buffer);
196 dmxdev->dvr_buffer.size=DVR_BUFFER_SIZE;
197 dmxdev->dvr_buffer.data=vmalloc(DVR_BUFFER_SIZE);
198 if (!dmxdev->dvr_buffer.data) {
199 up(&dmxdev->mutex);
200 return -ENOMEM;
201 }
202 }
203
204 if ((file->f_flags&O_ACCMODE)==O_WRONLY) {
205 dmxdev->dvr_orig_fe=dmxdev->demux->frontend;
206
207 if (!dmxdev->demux->write) {
208 up(&dmxdev->mutex);
209 return -EOPNOTSUPP;
210 }
211
212 front=get_fe(dmxdev->demux, DMX_MEMORY_FE);
213
214 if (!front) {
215 up(&dmxdev->mutex);
216 return -EINVAL;
217 }
218 dmxdev->demux->disconnect_frontend(dmxdev->demux);
219 dmxdev->demux->connect_frontend(dmxdev->demux, front);
220 }
221 up(&dmxdev->mutex);
222 return 0;
223}
224
225static int dvb_dvr_release(struct inode *inode, struct file *file)
226{
227 struct dvb_device *dvbdev=(struct dvb_device *) file->private_data;
228 struct dmxdev *dmxdev=(struct dmxdev *) dvbdev->priv;
229
230 if (down_interruptible (&dmxdev->mutex))
231 return -ERESTARTSYS;
232
233 if ((file->f_flags&O_ACCMODE)==O_WRONLY) {
234 dmxdev->demux->disconnect_frontend(dmxdev->demux);
235 dmxdev->demux->connect_frontend(dmxdev->demux,
236 dmxdev->dvr_orig_fe);
237 }
238 if ((file->f_flags&O_ACCMODE)==O_RDONLY) {
239 if (dmxdev->dvr_buffer.data) {
240 void *mem=dmxdev->dvr_buffer.data;
241 mb();
242 spin_lock_irq(&dmxdev->lock);
243 dmxdev->dvr_buffer.data=NULL;
244 spin_unlock_irq(&dmxdev->lock);
245 vfree(mem);
246 }
247 }
248 up(&dmxdev->mutex);
249 return 0;
250}
251
252static ssize_t dvb_dvr_write(struct file *file, const char __user *buf,
253 size_t count, loff_t *ppos)
254{
255 struct dvb_device *dvbdev=(struct dvb_device *) file->private_data;
256 struct dmxdev *dmxdev=(struct dmxdev *) dvbdev->priv;
257 int ret;
258
259 if (!dmxdev->demux->write)
260 return -EOPNOTSUPP;
261 if ((file->f_flags&O_ACCMODE)!=O_WRONLY)
262 return -EINVAL;
263 if (down_interruptible (&dmxdev->mutex))
264 return -ERESTARTSYS;
265 ret=dmxdev->demux->write(dmxdev->demux, buf, count);
266 up(&dmxdev->mutex);
267 return ret;
268}
269
270static ssize_t dvb_dvr_read(struct file *file, char __user *buf, size_t count,
271 loff_t *ppos)
272{
273 struct dvb_device *dvbdev=(struct dvb_device *) file->private_data;
274 struct dmxdev *dmxdev=(struct dmxdev *) dvbdev->priv;
275 int ret;
276
277 //down(&dmxdev->mutex);
278 ret= dvb_dmxdev_buffer_read(&dmxdev->dvr_buffer,
279 file->f_flags&O_NONBLOCK,
280 buf, count, ppos);
281 //up(&dmxdev->mutex);
282 return ret;
283}
284
285static inline void dvb_dmxdev_filter_state_set(struct dmxdev_filter *dmxdevfilter, int state)
286{
287 spin_lock_irq(&dmxdevfilter->dev->lock);
288 dmxdevfilter->state=state;
289 spin_unlock_irq(&dmxdevfilter->dev->lock);
290}
291
292static int dvb_dmxdev_set_buffer_size(struct dmxdev_filter *dmxdevfilter, unsigned long size)
293{
294 struct dmxdev_buffer *buf=&dmxdevfilter->buffer;
295 void *mem;
296
297 if (buf->size==size)
298 return 0;
299 if (dmxdevfilter->state>=DMXDEV_STATE_GO)
300 return -EBUSY;
301 spin_lock_irq(&dmxdevfilter->dev->lock);
302 mem=buf->data;
303 buf->data=NULL;
304 buf->size=size;
305 buf->pwrite=buf->pread=0;
306 spin_unlock_irq(&dmxdevfilter->dev->lock);
307 vfree(mem);
308
309 if (buf->size) {
310 mem=vmalloc(dmxdevfilter->buffer.size);
311 if (!mem)
312 return -ENOMEM;
313 spin_lock_irq(&dmxdevfilter->dev->lock);
314 buf->data=mem;
315 spin_unlock_irq(&dmxdevfilter->dev->lock);
316 }
317 return 0;
318}
319
320static void dvb_dmxdev_filter_timeout(unsigned long data)
321{
322 struct dmxdev_filter *dmxdevfilter=(struct dmxdev_filter *)data;
323
324 dmxdevfilter->buffer.error=-ETIMEDOUT;
325 spin_lock_irq(&dmxdevfilter->dev->lock);
326 dmxdevfilter->state=DMXDEV_STATE_TIMEDOUT;
327 spin_unlock_irq(&dmxdevfilter->dev->lock);
328 wake_up(&dmxdevfilter->buffer.queue);
329}
330
331static void dvb_dmxdev_filter_timer(struct dmxdev_filter *dmxdevfilter)
332{
333 struct dmx_sct_filter_params *para=&dmxdevfilter->params.sec;
334
335 del_timer(&dmxdevfilter->timer);
336 if (para->timeout) {
337 dmxdevfilter->timer.function=dvb_dmxdev_filter_timeout;
338 dmxdevfilter->timer.data=(unsigned long) dmxdevfilter;
339 dmxdevfilter->timer.expires=jiffies+1+(HZ/2+HZ*para->timeout)/1000;
340 add_timer(&dmxdevfilter->timer);
341 }
342}
343
344static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len,
345 const u8 *buffer2, size_t buffer2_len,
346 struct dmx_section_filter *filter, enum dmx_success success)
347{
348 struct dmxdev_filter *dmxdevfilter=(struct dmxdev_filter *) filter->priv;
349 int ret;
350
351 if (dmxdevfilter->buffer.error) {
352 wake_up(&dmxdevfilter->buffer.queue);
353 return 0;
354 }
355 spin_lock(&dmxdevfilter->dev->lock);
356 if (dmxdevfilter->state!=DMXDEV_STATE_GO) {
357 spin_unlock(&dmxdevfilter->dev->lock);
358 return 0;
359 }
360 del_timer(&dmxdevfilter->timer);
361 dprintk("dmxdev: section callback %02x %02x %02x %02x %02x %02x\n",
362 buffer1[0], buffer1[1],
363 buffer1[2], buffer1[3],
364 buffer1[4], buffer1[5]);
365 ret=dvb_dmxdev_buffer_write(&dmxdevfilter->buffer, buffer1, buffer1_len);
366 if (ret==buffer1_len) {
367 ret=dvb_dmxdev_buffer_write(&dmxdevfilter->buffer, buffer2, buffer2_len);
368 }
369 if (ret<0) {
370 dmxdevfilter->buffer.pwrite=dmxdevfilter->buffer.pread;
371 dmxdevfilter->buffer.error=-EOVERFLOW;
372 }
373 if (dmxdevfilter->params.sec.flags&DMX_ONESHOT)
374 dmxdevfilter->state=DMXDEV_STATE_DONE;
375 spin_unlock(&dmxdevfilter->dev->lock);
376 wake_up(&dmxdevfilter->buffer.queue);
377 return 0;
378}
379
380static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len,
381 const u8 *buffer2, size_t buffer2_len,
382 struct dmx_ts_feed *feed, enum dmx_success success)
383{
384 struct dmxdev_filter *dmxdevfilter=(struct dmxdev_filter *) feed->priv;
385 struct dmxdev_buffer *buffer;
386 int ret;
387
388 spin_lock(&dmxdevfilter->dev->lock);
389 if (dmxdevfilter->params.pes.output==DMX_OUT_DECODER) {
390 spin_unlock(&dmxdevfilter->dev->lock);
391 return 0;
392 }
393
394 if (dmxdevfilter->params.pes.output==DMX_OUT_TAP)
395 buffer=&dmxdevfilter->buffer;
396 else
397 buffer=&dmxdevfilter->dev->dvr_buffer;
398 if (buffer->error) {
399 spin_unlock(&dmxdevfilter->dev->lock);
400 wake_up(&buffer->queue);
401 return 0;
402 }
403 ret=dvb_dmxdev_buffer_write(buffer, buffer1, buffer1_len);
404 if (ret==buffer1_len)
405 ret=dvb_dmxdev_buffer_write(buffer, buffer2, buffer2_len);
406 if (ret<0) {
407 buffer->pwrite=buffer->pread;
408 buffer->error=-EOVERFLOW;
409 }
410 spin_unlock(&dmxdevfilter->dev->lock);
411 wake_up(&buffer->queue);
412 return 0;
413}
414
415
416/* stop feed but only mark the specified filter as stopped (state set) */
417
418static int dvb_dmxdev_feed_stop(struct dmxdev_filter *dmxdevfilter)
419{
420 dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_SET);
421
422 switch (dmxdevfilter->type) {
423 case DMXDEV_TYPE_SEC:
424 del_timer(&dmxdevfilter->timer);
425 dmxdevfilter->feed.sec->stop_filtering(dmxdevfilter->feed.sec);
426 break;
427 case DMXDEV_TYPE_PES:
428 dmxdevfilter->feed.ts->stop_filtering(dmxdevfilter->feed.ts);
429 break;
430 default:
431 return -EINVAL;
432 }
433 return 0;
434}
435
436
437/* start feed associated with the specified filter */
438
439static int dvb_dmxdev_feed_start(struct dmxdev_filter *filter)
440{
441 dvb_dmxdev_filter_state_set (filter, DMXDEV_STATE_GO);
442
443 switch (filter->type) {
444 case DMXDEV_TYPE_SEC:
445 return filter->feed.sec->start_filtering(filter->feed.sec);
446 break;
447 case DMXDEV_TYPE_PES:
448 return filter->feed.ts->start_filtering(filter->feed.ts);
449 break;
450 default:
451 return -EINVAL;
452 }
453
454 return 0;
455}
456
457
458/* restart section feed if it has filters left associated with it,
459 otherwise release the feed */
460
461static int dvb_dmxdev_feed_restart(struct dmxdev_filter *filter)
462{
463 int i;
464 struct dmxdev *dmxdev = filter->dev;
465 u16 pid = filter->params.sec.pid;
466
467 for (i=0; i<dmxdev->filternum; i++)
468 if (dmxdev->filter[i].state>=DMXDEV_STATE_GO &&
469 dmxdev->filter[i].type==DMXDEV_TYPE_SEC &&
470 dmxdev->filter[i].pid==pid) {
471 dvb_dmxdev_feed_start(&dmxdev->filter[i]);
472 return 0;
473 }
474
475 filter->dev->demux->release_section_feed(dmxdev->demux, filter->feed.sec);
476
477 return 0;
478}
479
480static int dvb_dmxdev_filter_stop(struct dmxdev_filter *dmxdevfilter)
481{
482 if (dmxdevfilter->state<DMXDEV_STATE_GO)
483 return 0;
484
485 switch (dmxdevfilter->type) {
486 case DMXDEV_TYPE_SEC:
487 if (!dmxdevfilter->feed.sec)
488 break;
489 dvb_dmxdev_feed_stop(dmxdevfilter);
490 if (dmxdevfilter->filter.sec)
491 dmxdevfilter->feed.sec->
492 release_filter(dmxdevfilter->feed.sec,
493 dmxdevfilter->filter.sec);
494 dvb_dmxdev_feed_restart(dmxdevfilter);
495 dmxdevfilter->feed.sec=NULL;
496 break;
497 case DMXDEV_TYPE_PES:
498 if (!dmxdevfilter->feed.ts)
499 break;
500 dvb_dmxdev_feed_stop(dmxdevfilter);
501 dmxdevfilter->dev->demux->
502 release_ts_feed(dmxdevfilter->dev->demux,
503 dmxdevfilter->feed.ts);
504 dmxdevfilter->feed.ts=NULL;
505 break;
506 default:
507 if (dmxdevfilter->state==DMXDEV_STATE_ALLOCATED)
508 return 0;
509 return -EINVAL;
510 }
511 dmxdevfilter->buffer.pwrite=dmxdevfilter->buffer.pread=0;
512 return 0;
513}
514
515static inline int dvb_dmxdev_filter_reset(struct dmxdev_filter *dmxdevfilter)
516{
517 if (dmxdevfilter->state<DMXDEV_STATE_SET)
518 return 0;
519
520 dmxdevfilter->type=DMXDEV_TYPE_NONE;
521 dmxdevfilter->pid=0xffff;
522 dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_ALLOCATED);
523 return 0;
524}
525
526static int dvb_dmxdev_filter_start(struct dmxdev_filter *filter)
527{
528 struct dmxdev *dmxdev = filter->dev;
529 void *mem;
530 int ret, i;
531
532 if (filter->state < DMXDEV_STATE_SET)
533 return -EINVAL;
534
535 if (filter->state >= DMXDEV_STATE_GO)
536 dvb_dmxdev_filter_stop(filter);
537
538 if (!(mem = filter->buffer.data)) {
539 mem = vmalloc(filter->buffer.size);
540 spin_lock_irq(&filter->dev->lock);
541 filter->buffer.data=mem;
542 spin_unlock_irq(&filter->dev->lock);
543 if (!filter->buffer.data)
544 return -ENOMEM;
545 }
546
547 filter->buffer.pwrite = filter->buffer.pread = 0;
548
549 switch (filter->type) {
550 case DMXDEV_TYPE_SEC:
551 {
552 struct dmx_sct_filter_params *para=&filter->params.sec;
553 struct dmx_section_filter **secfilter=&filter->filter.sec;
554 struct dmx_section_feed **secfeed=&filter->feed.sec;
555
556 *secfilter=NULL;
557 *secfeed=NULL;
558
559 /* find active filter/feed with same PID */
560 for (i=0; i<dmxdev->filternum; i++) {
561 if (dmxdev->filter[i].state >= DMXDEV_STATE_GO &&
562 dmxdev->filter[i].pid == para->pid &&
563 dmxdev->filter[i].type == DMXDEV_TYPE_SEC) {
564 *secfeed = dmxdev->filter[i].feed.sec;
565 break;
566 }
567 }
568
569 /* if no feed found, try to allocate new one */
570 if (!*secfeed) {
571 ret=dmxdev->demux->allocate_section_feed(dmxdev->demux,
572 secfeed,
573 dvb_dmxdev_section_callback);
574 if (ret<0) {
575 printk ("DVB (%s): could not alloc feed\n",
576 __FUNCTION__);
577 return ret;
578 }
579
580 ret=(*secfeed)->set(*secfeed, para->pid, 32768, 0,
581 (para->flags & DMX_CHECK_CRC) ? 1 : 0);
582
583 if (ret<0) {
584 printk ("DVB (%s): could not set feed\n",
585 __FUNCTION__);
586 dvb_dmxdev_feed_restart(filter);
587 return ret;
588 }
589 } else {
590 dvb_dmxdev_feed_stop(filter);
591 }
592
593 ret=(*secfeed)->allocate_filter(*secfeed, secfilter);
594
595 if (ret < 0) {
596 dvb_dmxdev_feed_restart(filter);
597 filter->feed.sec->start_filtering(*secfeed);
598 dprintk ("could not get filter\n");
599 return ret;
600 }
601
602 (*secfilter)->priv = filter;
603
604 memcpy(&((*secfilter)->filter_value[3]),
605 &(para->filter.filter[1]), DMX_FILTER_SIZE-1);
606 memcpy(&(*secfilter)->filter_mask[3],
607 &para->filter.mask[1], DMX_FILTER_SIZE-1);
608 memcpy(&(*secfilter)->filter_mode[3],
609 &para->filter.mode[1], DMX_FILTER_SIZE-1);
610
611 (*secfilter)->filter_value[0]=para->filter.filter[0];
612 (*secfilter)->filter_mask[0]=para->filter.mask[0];
613 (*secfilter)->filter_mode[0]=para->filter.mode[0];
614 (*secfilter)->filter_mask[1]=0;
615 (*secfilter)->filter_mask[2]=0;
616
617 filter->todo = 0;
618
619 ret = filter->feed.sec->start_filtering (filter->feed.sec);
620
621 if (ret < 0)
622 return ret;
623
624 dvb_dmxdev_filter_timer(filter);
625 break;
626 }
627
628 case DMXDEV_TYPE_PES:
629 {
630 struct timespec timeout = { 0 };
631 struct dmx_pes_filter_params *para = &filter->params.pes;
632 dmx_output_t otype;
633 int ret;
634 int ts_type;
635 enum dmx_ts_pes ts_pes;
636 struct dmx_ts_feed **tsfeed = &filter->feed.ts;
637
638 filter->feed.ts = NULL;
639 otype=para->output;
640
641 ts_pes=(enum dmx_ts_pes) para->pes_type;
642
643 if (ts_pes<DMX_PES_OTHER)
644 ts_type=TS_DECODER;
645 else
646 ts_type=0;
647
648 if (otype == DMX_OUT_TS_TAP)
649 ts_type |= TS_PACKET;
650
651 if (otype == DMX_OUT_TAP)
652 ts_type |= TS_PAYLOAD_ONLY|TS_PACKET;
653
654 ret=dmxdev->demux->allocate_ts_feed(dmxdev->demux,
655 tsfeed,
656 dvb_dmxdev_ts_callback);
657 if (ret<0)
658 return ret;
659
660 (*tsfeed)->priv = (void *) filter;
661
662 ret = (*tsfeed)->set(*tsfeed, para->pid, ts_type, ts_pes,
663 188, 32768, 0, timeout);
664
665 if (ret < 0) {
666 dmxdev->demux->release_ts_feed(dmxdev->demux, *tsfeed);
667 return ret;
668 }
669
670 ret = filter->feed.ts->start_filtering(filter->feed.ts);
671
672 if (ret < 0)
673 return ret;
674
675 break;
676 }
677 default:
678 return -EINVAL;
679 }
680
681 dvb_dmxdev_filter_state_set(filter, DMXDEV_STATE_GO);
682 return 0;
683}
684
685static int dvb_demux_open(struct inode *inode, struct file *file)
686{
687 struct dvb_device *dvbdev=(struct dvb_device *) file->private_data;
688 struct dmxdev *dmxdev=(struct dmxdev *) dvbdev->priv;
689 int i;
690 struct dmxdev_filter *dmxdevfilter;
691
692 if (!dmxdev->filter)
693 return -EINVAL;
694
695 if (down_interruptible(&dmxdev->mutex))
696 return -ERESTARTSYS;
697
698 for (i=0; i<dmxdev->filternum; i++)
699 if (dmxdev->filter[i].state==DMXDEV_STATE_FREE)
700 break;
701
702 if (i==dmxdev->filternum) {
703 up(&dmxdev->mutex);
704 return -EMFILE;
705 }
706
707 dmxdevfilter=&dmxdev->filter[i];
708 sema_init(&dmxdevfilter->mutex, 1);
709 dmxdevfilter->dvbdev=dmxdev->dvbdev;
710 file->private_data=dmxdevfilter;
711
712 dvb_dmxdev_buffer_init(&dmxdevfilter->buffer);
713 dmxdevfilter->type=DMXDEV_TYPE_NONE;
714 dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_ALLOCATED);
715 dmxdevfilter->feed.ts=NULL;
716 init_timer(&dmxdevfilter->timer);
717
718 up(&dmxdev->mutex);
719 return 0;
720}
721
722
723static int dvb_dmxdev_filter_free(struct dmxdev *dmxdev, struct dmxdev_filter *dmxdevfilter)
724{
725 if (down_interruptible(&dmxdev->mutex))
726 return -ERESTARTSYS;
727
728 if (down_interruptible(&dmxdevfilter->mutex)) {
729 up(&dmxdev->mutex);
730 return -ERESTARTSYS;
731 }
732
733 dvb_dmxdev_filter_stop(dmxdevfilter);
734 dvb_dmxdev_filter_reset(dmxdevfilter);
735
736 if (dmxdevfilter->buffer.data) {
737 void *mem=dmxdevfilter->buffer.data;
738
739 spin_lock_irq(&dmxdev->lock);
740 dmxdevfilter->buffer.data=NULL;
741 spin_unlock_irq(&dmxdev->lock);
742 vfree(mem);
743 }
744
745 dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_FREE);
746 wake_up(&dmxdevfilter->buffer.queue);
747 up(&dmxdevfilter->mutex);
748 up(&dmxdev->mutex);
749 return 0;
750}
751
752static inline void invert_mode(dmx_filter_t *filter)
753{
754 int i;
755
756 for (i=0; i<DMX_FILTER_SIZE; i++)
757 filter->mode[i]^=0xff;
758}
759
760
761static int dvb_dmxdev_filter_set(struct dmxdev *dmxdev,
762 struct dmxdev_filter *dmxdevfilter,
763 struct dmx_sct_filter_params *params)
764{
765 dprintk ("function : %s\n", __FUNCTION__);
766
767 dvb_dmxdev_filter_stop(dmxdevfilter);
768
769 dmxdevfilter->type=DMXDEV_TYPE_SEC;
770 dmxdevfilter->pid=params->pid;
771 memcpy(&dmxdevfilter->params.sec,
772 params, sizeof(struct dmx_sct_filter_params));
773 invert_mode(&dmxdevfilter->params.sec.filter);
774 dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_SET);
775
776 if (params->flags&DMX_IMMEDIATE_START)
777 return dvb_dmxdev_filter_start(dmxdevfilter);
778
779 return 0;
780}
781
782static int dvb_dmxdev_pes_filter_set(struct dmxdev *dmxdev,
783 struct dmxdev_filter *dmxdevfilter,
784 struct dmx_pes_filter_params *params)
785{
786 dvb_dmxdev_filter_stop(dmxdevfilter);
787
788 if (params->pes_type>DMX_PES_OTHER || params->pes_type<0)
789 return -EINVAL;
790
791 dmxdevfilter->type=DMXDEV_TYPE_PES;
792 dmxdevfilter->pid=params->pid;
793 memcpy(&dmxdevfilter->params, params, sizeof(struct dmx_pes_filter_params));
794
795 dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_SET);
796
797 if (params->flags&DMX_IMMEDIATE_START)
798 return dvb_dmxdev_filter_start(dmxdevfilter);
799
800 return 0;
801}
802
803static ssize_t dvb_dmxdev_read_sec(struct dmxdev_filter *dfil,
804 struct file *file, char __user *buf, size_t count, loff_t *ppos)
805{
806 int result, hcount;
807 int done=0;
808
809 if (dfil->todo<=0) {
810 hcount=3+dfil->todo;
811 if (hcount>count)
812 hcount=count;
813 result=dvb_dmxdev_buffer_read(&dfil->buffer, file->f_flags&O_NONBLOCK,
814 buf, hcount, ppos);
815 if (result<0) {
816 dfil->todo=0;
817 return result;
818 }
819 if (copy_from_user(dfil->secheader-dfil->todo, buf, result))
820 return -EFAULT;
821 buf+=result;
822 done=result;
823 count-=result;
824 dfil->todo-=result;
825 if (dfil->todo>-3)
826 return done;
827 dfil->todo=((dfil->secheader[1]<<8)|dfil->secheader[2])&0xfff;
828 if (!count)
829 return done;
830 }
831 if (count>dfil->todo)
832 count=dfil->todo;
833 result=dvb_dmxdev_buffer_read(&dfil->buffer, file->f_flags&O_NONBLOCK,
834 buf, count, ppos);
835 if (result<0)
836 return result;
837 dfil->todo-=result;
838 return (result+done);
839}
840
841
842static ssize_t
843dvb_demux_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
844{
845 struct dmxdev_filter *dmxdevfilter=dvb_dmxdev_file_to_filter(file);
846 int ret=0;
847
848 if (down_interruptible(&dmxdevfilter->mutex))
849 return -ERESTARTSYS;
850
851 if (dmxdevfilter->type==DMXDEV_TYPE_SEC)
852 ret=dvb_dmxdev_read_sec(dmxdevfilter, file, buf, count, ppos);
853 else
854 ret=dvb_dmxdev_buffer_read(&dmxdevfilter->buffer,
855 file->f_flags&O_NONBLOCK,
856 buf, count, ppos);
857
858 up(&dmxdevfilter->mutex);
859 return ret;
860}
861
862
863static int dvb_demux_do_ioctl(struct inode *inode, struct file *file,
864 unsigned int cmd, void *parg)
865{
866 struct dmxdev_filter *dmxdevfilter=dvb_dmxdev_file_to_filter(file);
867 struct dmxdev *dmxdev=dmxdevfilter->dev;
868 unsigned long arg=(unsigned long) parg;
869 int ret=0;
870
871 if (down_interruptible (&dmxdev->mutex))
872 return -ERESTARTSYS;
873
874 switch (cmd) {
875 case DMX_START:
876 if (down_interruptible(&dmxdevfilter->mutex)) {
877 up(&dmxdev->mutex);
878 return -ERESTARTSYS;
879 }
880 if (dmxdevfilter->state<DMXDEV_STATE_SET)
881 ret = -EINVAL;
882 else
883 ret = dvb_dmxdev_filter_start(dmxdevfilter);
884 up(&dmxdevfilter->mutex);
885 break;
886
887 case DMX_STOP:
888 if (down_interruptible(&dmxdevfilter->mutex)) {
889 up(&dmxdev->mutex);
890 return -ERESTARTSYS;
891 }
892 ret=dvb_dmxdev_filter_stop(dmxdevfilter);
893 up(&dmxdevfilter->mutex);
894 break;
895
896 case DMX_SET_FILTER:
897 if (down_interruptible(&dmxdevfilter->mutex)) {
898 up(&dmxdev->mutex);
899 return -ERESTARTSYS;
900 }
901 ret = dvb_dmxdev_filter_set(dmxdev, dmxdevfilter,
902 (struct dmx_sct_filter_params *)parg);
903 up(&dmxdevfilter->mutex);
904 break;
905
906 case DMX_SET_PES_FILTER:
907 if (down_interruptible(&dmxdevfilter->mutex)) {
908 up(&dmxdev->mutex);
909 return -ERESTARTSYS;
910 }
911 ret=dvb_dmxdev_pes_filter_set(dmxdev, dmxdevfilter,
912 (struct dmx_pes_filter_params *)parg);
913 up(&dmxdevfilter->mutex);
914 break;
915
916 case DMX_SET_BUFFER_SIZE:
917 if (down_interruptible(&dmxdevfilter->mutex)) {
918 up(&dmxdev->mutex);
919 return -ERESTARTSYS;
920 }
921 ret=dvb_dmxdev_set_buffer_size(dmxdevfilter, arg);
922 up(&dmxdevfilter->mutex);
923 break;
924
925 case DMX_GET_EVENT:
926 break;
927
928 case DMX_GET_PES_PIDS:
929 if (!dmxdev->demux->get_pes_pids) {
930 ret=-EINVAL;
931 break;
932 }
933 dmxdev->demux->get_pes_pids(dmxdev->demux, (u16 *)parg);
934 break;
935
936 case DMX_GET_STC:
937 if (!dmxdev->demux->get_stc) {
938 ret=-EINVAL;
939 break;
940 }
941 ret = dmxdev->demux->get_stc(dmxdev->demux,
942 ((struct dmx_stc *)parg)->num,
943 &((struct dmx_stc *)parg)->stc,
944 &((struct dmx_stc *)parg)->base);
945 break;
946
947 default:
948 ret=-EINVAL;
949 }
950 up(&dmxdev->mutex);
951 return ret;
952}
953
954static int dvb_demux_ioctl(struct inode *inode, struct file *file,
955 unsigned int cmd, unsigned long arg)
956{
957 return dvb_usercopy(inode, file, cmd, arg, dvb_demux_do_ioctl);
958}
959
960
961static unsigned int dvb_demux_poll (struct file *file, poll_table *wait)
962{
963 struct dmxdev_filter *dmxdevfilter = dvb_dmxdev_file_to_filter(file);
964 unsigned int mask = 0;
965
966 if (!dmxdevfilter)
967 return -EINVAL;
968
969 poll_wait(file, &dmxdevfilter->buffer.queue, wait);
970
971 if (dmxdevfilter->state != DMXDEV_STATE_GO &&
972 dmxdevfilter->state != DMXDEV_STATE_DONE &&
973 dmxdevfilter->state != DMXDEV_STATE_TIMEDOUT)
974 return 0;
975
976 if (dmxdevfilter->buffer.error)
977 mask |= (POLLIN | POLLRDNORM | POLLPRI | POLLERR);
978
979 if (dmxdevfilter->buffer.pread != dmxdevfilter->buffer.pwrite)
980 mask |= (POLLIN | POLLRDNORM | POLLPRI);
981
982 return mask;
983}
984
985
986static int dvb_demux_release(struct inode *inode, struct file *file)
987{
988 struct dmxdev_filter *dmxdevfilter = dvb_dmxdev_file_to_filter(file);
989 struct dmxdev *dmxdev = dmxdevfilter->dev;
990
991 return dvb_dmxdev_filter_free(dmxdev, dmxdevfilter);
992}
993
994
995static struct file_operations dvb_demux_fops = {
996 .owner = THIS_MODULE,
997 .read = dvb_demux_read,
998 .ioctl = dvb_demux_ioctl,
999 .open = dvb_demux_open,
1000 .release = dvb_demux_release,
1001 .poll = dvb_demux_poll,
1002};
1003
1004
1005static struct dvb_device dvbdev_demux = {
1006 .priv = NULL,
1007 .users = 1,
1008 .writers = 1,
1009 .fops = &dvb_demux_fops
1010};
1011
1012
1013static int dvb_dvr_do_ioctl(struct inode *inode, struct file *file,
1014 unsigned int cmd, void *parg)
1015{
1016 struct dvb_device *dvbdev=(struct dvb_device *) file->private_data;
1017 struct dmxdev *dmxdev=(struct dmxdev *) dvbdev->priv;
1018
1019 int ret=0;
1020
1021 if (down_interruptible (&dmxdev->mutex))
1022 return -ERESTARTSYS;
1023
1024 switch (cmd) {
1025 case DMX_SET_BUFFER_SIZE:
1026 // FIXME: implement
1027 ret=0;
1028 break;
1029
1030 default:
1031 ret=-EINVAL;
1032 }
1033 up(&dmxdev->mutex);
1034 return ret;
1035}
1036
1037
1038static int dvb_dvr_ioctl(struct inode *inode, struct file *file,
1039 unsigned int cmd, unsigned long arg)
1040{
1041 return dvb_usercopy(inode, file, cmd, arg, dvb_dvr_do_ioctl);
1042}
1043
1044
1045static unsigned int dvb_dvr_poll (struct file *file, poll_table *wait)
1046{
1047 struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;
1048 struct dmxdev *dmxdev = (struct dmxdev *) dvbdev->priv;
1049 unsigned int mask = 0;
1050
1051 dprintk ("function : %s\n", __FUNCTION__);
1052
1053 poll_wait(file, &dmxdev->dvr_buffer.queue, wait);
1054
1055 if ((file->f_flags&O_ACCMODE) == O_RDONLY) {
1056 if (dmxdev->dvr_buffer.error)
1057 mask |= (POLLIN | POLLRDNORM | POLLPRI | POLLERR);
1058
1059 if (dmxdev->dvr_buffer.pread!=dmxdev->dvr_buffer.pwrite)
1060 mask |= (POLLIN | POLLRDNORM | POLLPRI);
1061 } else
1062 mask |= (POLLOUT | POLLWRNORM | POLLPRI);
1063
1064 return mask;
1065}
1066
1067
1068static struct file_operations dvb_dvr_fops = {
1069 .owner = THIS_MODULE,
1070 .read = dvb_dvr_read,
1071 .write = dvb_dvr_write,
1072 .ioctl = dvb_dvr_ioctl,
1073 .open = dvb_dvr_open,
1074 .release = dvb_dvr_release,
1075 .poll = dvb_dvr_poll,
1076};
1077
1078static struct dvb_device dvbdev_dvr = {
1079 .priv = NULL,
1080 .users = 1,
1081 .writers = 1,
1082 .fops = &dvb_dvr_fops
1083};
1084
1085int
1086dvb_dmxdev_init(struct dmxdev *dmxdev, struct dvb_adapter *dvb_adapter)
1087{
1088 int i;
1089
1090 if (dmxdev->demux->open(dmxdev->demux) < 0)
1091 return -EUSERS;
1092
1093 dmxdev->filter = vmalloc(dmxdev->filternum*sizeof(struct dmxdev_filter));
1094 if (!dmxdev->filter)
1095 return -ENOMEM;
1096
1097 dmxdev->dvr = vmalloc(dmxdev->filternum*sizeof(struct dmxdev_dvr));
1098 if (!dmxdev->dvr) {
1099 vfree(dmxdev->filter);
1100 dmxdev->filter = NULL;
1101 return -ENOMEM;
1102 }
1103
1104 sema_init(&dmxdev->mutex, 1);
1105 spin_lock_init(&dmxdev->lock);
1106 for (i=0; i<dmxdev->filternum; i++) {
1107 dmxdev->filter[i].dev=dmxdev;
1108 dmxdev->filter[i].buffer.data=NULL;
1109 dvb_dmxdev_filter_state_set(&dmxdev->filter[i], DMXDEV_STATE_FREE);
1110 dmxdev->dvr[i].dev=dmxdev;
1111 dmxdev->dvr[i].buffer.data=NULL;
1112 dvb_dmxdev_filter_state_set(&dmxdev->filter[i], DMXDEV_STATE_FREE);
1113 dvb_dmxdev_dvr_state_set(&dmxdev->dvr[i], DMXDEV_STATE_FREE);
1114 }
1115
1116 dvb_register_device(dvb_adapter, &dmxdev->dvbdev, &dvbdev_demux, dmxdev, DVB_DEVICE_DEMUX);
1117 dvb_register_device(dvb_adapter, &dmxdev->dvr_dvbdev, &dvbdev_dvr, dmxdev, DVB_DEVICE_DVR);
1118
1119 dvb_dmxdev_buffer_init(&dmxdev->dvr_buffer);
1120
1121 return 0;
1122}
1123EXPORT_SYMBOL(dvb_dmxdev_init);
1124
1125void
1126dvb_dmxdev_release(struct dmxdev *dmxdev)
1127{
1128 dvb_unregister_device(dmxdev->dvbdev);
1129 dvb_unregister_device(dmxdev->dvr_dvbdev);
1130
1131 vfree(dmxdev->filter);
1132 dmxdev->filter=NULL;
1133 vfree(dmxdev->dvr);
1134 dmxdev->dvr=NULL;
1135 dmxdev->demux->close(dmxdev->demux);
1136}
1137EXPORT_SYMBOL(dvb_dmxdev_release);
diff --git a/drivers/media/dvb/dvb-core/dmxdev.h b/drivers/media/dvb/dvb-core/dmxdev.h
new file mode 100644
index 000000000000..395a9cd75012
--- /dev/null
+++ b/drivers/media/dvb/dvb-core/dmxdev.h
@@ -0,0 +1,128 @@
1/*
2 * dmxdev.h
3 *
4 * Copyright (C) 2000 Ralph Metzler & Marcus Metzler
5 * for convergence integrated media GmbH
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public License
9 * as published by the Free Software Foundation; either version 2.1
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 *
21 */
22
23#ifndef _DMXDEV_H_
24#define _DMXDEV_H_
25
26#include <linux/types.h>
27#include <linux/spinlock.h>
28#include <linux/kernel.h>
29#include <linux/timer.h>
30#include <linux/wait.h>
31#include <linux/fs.h>
32#include <linux/string.h>
33#include <asm/semaphore.h>
34
35#include <linux/dvb/dmx.h>
36
37#include "dvbdev.h"
38#include "demux.h"
39
40enum dmxdevype {
41 DMXDEV_TYPE_NONE,
42 DMXDEV_TYPE_SEC,
43 DMXDEV_TYPE_PES,
44};
45
46enum dmxdev_state {
47 DMXDEV_STATE_FREE,
48 DMXDEV_STATE_ALLOCATED,
49 DMXDEV_STATE_SET,
50 DMXDEV_STATE_GO,
51 DMXDEV_STATE_DONE,
52 DMXDEV_STATE_TIMEDOUT
53};
54
55struct dmxdev_buffer {
56 u8 *data;
57 int size;
58 int pread;
59 int pwrite;
60 wait_queue_head_t queue;
61 int error;
62};
63
64struct dmxdev_filter {
65 struct dvb_device *dvbdev;
66
67 union {
68 struct dmx_section_filter *sec;
69 } filter;
70
71 union {
72 struct dmx_ts_feed *ts;
73 struct dmx_section_feed *sec;
74 } feed;
75
76 union {
77 struct dmx_sct_filter_params sec;
78 struct dmx_pes_filter_params pes;
79 } params;
80
81 int type;
82 enum dmxdev_state state;
83 struct dmxdev *dev;
84 struct dmxdev_buffer buffer;
85
86 struct semaphore mutex;
87
88 /* only for sections */
89 struct timer_list timer;
90 int todo;
91 u8 secheader[3];
92
93 u16 pid;
94};
95
96
97struct dmxdev_dvr {
98 int state;
99 struct dmxdev *dev;
100 struct dmxdev_buffer buffer;
101};
102
103
104struct dmxdev {
105 struct dvb_device *dvbdev;
106 struct dvb_device *dvr_dvbdev;
107
108 struct dmxdev_filter *filter;
109 struct dmxdev_dvr *dvr;
110 struct dmx_demux *demux;
111
112 int filternum;
113 int capabilities;
114#define DMXDEV_CAP_DUPLEX 1
115 struct dmx_frontend *dvr_orig_fe;
116
117 struct dmxdev_buffer dvr_buffer;
118#define DVR_BUFFER_SIZE (10*188*1024)
119
120 struct semaphore mutex;
121 spinlock_t lock;
122};
123
124
125int dvb_dmxdev_init(struct dmxdev *dmxdev, struct dvb_adapter *);
126void dvb_dmxdev_release(struct dmxdev *dmxdev);
127
128#endif /* _DMXDEV_H_ */
diff --git a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
new file mode 100644
index 000000000000..c1ea89f2880c
--- /dev/null
+++ b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
@@ -0,0 +1,1778 @@
1/*
2 * dvb_ca.c: generic DVB functions for EN50221 CAM interfaces
3 *
4 * Copyright (C) 2004 Andrew de Quincey
5 *
6 * Parts of this file were based on sources as follows:
7 *
8 * Copyright (C) 2003 Ralph Metzler <rjkm@metzlerbros.de>
9 *
10 * based on code:
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 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
28 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
29 */
30
31#include <linux/errno.h>
32#include <linux/slab.h>
33#include <linux/list.h>
34#include <linux/module.h>
35#include <linux/moduleparam.h>
36#include <linux/vmalloc.h>
37#include <linux/delay.h>
38#include <linux/rwsem.h>
39
40#include "dvb_ca_en50221.h"
41#include "dvb_ringbuffer.h"
42
43static int dvb_ca_en50221_debug;
44
45module_param_named(cam_debug, dvb_ca_en50221_debug, int, 0644);
46MODULE_PARM_DESC(cam_debug, "enable verbose debug messages");
47
48#define dprintk if (dvb_ca_en50221_debug) printk
49
50#define INIT_TIMEOUT_SECS 5
51
52#define HOST_LINK_BUF_SIZE 0x200
53
54#define RX_BUFFER_SIZE 65535
55
56#define MAX_RX_PACKETS_PER_ITERATION 10
57
58#define CTRLIF_DATA 0
59#define CTRLIF_COMMAND 1
60#define CTRLIF_STATUS 1
61#define CTRLIF_SIZE_LOW 2
62#define CTRLIF_SIZE_HIGH 3
63
64#define CMDREG_HC 1 /* Host control */
65#define CMDREG_SW 2 /* Size write */
66#define CMDREG_SR 4 /* Size read */
67#define CMDREG_RS 8 /* Reset interface */
68#define CMDREG_FRIE 0x40 /* Enable FR interrupt */
69#define CMDREG_DAIE 0x80 /* Enable DA interrupt */
70#define IRQEN (CMDREG_DAIE)
71
72#define STATUSREG_RE 1 /* read error */
73#define STATUSREG_WE 2 /* write error */
74#define STATUSREG_FR 0x40 /* module free */
75#define STATUSREG_DA 0x80 /* data available */
76#define STATUSREG_TXERR (STATUSREG_RE|STATUSREG_WE) /* general transfer error */
77
78
79#define DVB_CA_SLOTSTATE_NONE 0
80#define DVB_CA_SLOTSTATE_UNINITIALISED 1
81#define DVB_CA_SLOTSTATE_RUNNING 2
82#define DVB_CA_SLOTSTATE_INVALID 3
83#define DVB_CA_SLOTSTATE_WAITREADY 4
84#define DVB_CA_SLOTSTATE_VALIDATE 5
85#define DVB_CA_SLOTSTATE_WAITFR 6
86#define DVB_CA_SLOTSTATE_LINKINIT 7
87
88
89/* Information on a CA slot */
90struct dvb_ca_slot {
91
92 /* current state of the CAM */
93 int slot_state;
94
95 /* Number of CAMCHANGES that have occurred since last processing */
96 atomic_t camchange_count;
97
98 /* Type of last CAMCHANGE */
99 int camchange_type;
100
101 /* base address of CAM config */
102 u32 config_base;
103
104 /* value to write into Config Control register */
105 u8 config_option;
106
107 /* if 1, the CAM supports DA IRQs */
108 u8 da_irq_supported:1;
109
110 /* size of the buffer to use when talking to the CAM */
111 int link_buf_size;
112
113 /* semaphore for syncing access to slot structure */
114 struct rw_semaphore sem;
115
116 /* buffer for incoming packets */
117 struct dvb_ringbuffer rx_buffer;
118
119 /* timer used during various states of the slot */
120 unsigned long timeout;
121};
122
123/* Private CA-interface information */
124struct dvb_ca_private {
125
126 /* pointer back to the public data structure */
127 struct dvb_ca_en50221 *pub;
128
129 /* the DVB device */
130 struct dvb_device *dvbdev;
131
132 /* Flags describing the interface (DVB_CA_FLAG_*) */
133 u32 flags;
134
135 /* number of slots supported by this CA interface */
136 unsigned int slot_count;
137
138 /* information on each slot */
139 struct dvb_ca_slot *slot_info;
140
141 /* wait queues for read() and write() operations */
142 wait_queue_head_t wait_queue;
143
144 /* PID of the monitoring thread */
145 pid_t thread_pid;
146
147 /* Wait queue used when shutting thread down */
148 wait_queue_head_t thread_queue;
149
150 /* Flag indicating when thread should exit */
151 unsigned int exit:1;
152
153 /* Flag indicating if the CA device is open */
154 unsigned int open:1;
155
156 /* Flag indicating the thread should wake up now */
157 unsigned int wakeup:1;
158
159 /* Delay the main thread should use */
160 unsigned long delay;
161
162 /* Slot to start looking for data to read from in the next user-space read operation */
163 int next_read_slot;
164};
165
166static void dvb_ca_en50221_thread_wakeup(struct dvb_ca_private *ca);
167static int dvb_ca_en50221_read_data(struct dvb_ca_private *ca, int slot, u8 * ebuf, int ecount);
168static int dvb_ca_en50221_write_data(struct dvb_ca_private *ca, int slot, u8 * ebuf, int ecount);
169
170
171/**
172 * Safely find needle in haystack.
173 *
174 * @param haystack Buffer to look in.
175 * @param hlen Number of bytes in haystack.
176 * @param needle Buffer to find.
177 * @param nlen Number of bytes in needle.
178 * @return Pointer into haystack needle was found at, or NULL if not found.
179 */
180static u8 *findstr(u8 * haystack, int hlen, u8 * needle, int nlen)
181{
182 int i;
183
184 if (hlen < nlen)
185 return NULL;
186
187 for (i = 0; i <= hlen - nlen; i++) {
188 if (!strncmp(haystack + i, needle, nlen))
189 return haystack + i;
190 }
191
192 return NULL;
193}
194
195
196
197/* ******************************************************************************** */
198/* EN50221 physical interface functions */
199
200
201/**
202 * Check CAM status.
203 */
204static int dvb_ca_en50221_check_camstatus(struct dvb_ca_private *ca, int slot)
205{
206 int slot_status;
207 int cam_present_now;
208 int cam_changed;
209
210 /* IRQ mode */
211 if (ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE) {
212 return (atomic_read(&ca->slot_info[slot].camchange_count) != 0);
213 }
214
215 /* poll mode */
216 slot_status = ca->pub->poll_slot_status(ca->pub, slot, ca->open);
217
218 cam_present_now = (slot_status & DVB_CA_EN50221_POLL_CAM_PRESENT) ? 1 : 0;
219 cam_changed = (slot_status & DVB_CA_EN50221_POLL_CAM_CHANGED) ? 1 : 0;
220 if (!cam_changed) {
221 int cam_present_old = (ca->slot_info[slot].slot_state != DVB_CA_SLOTSTATE_NONE);
222 cam_changed = (cam_present_now != cam_present_old);
223 }
224
225 if (cam_changed) {
226 if (!cam_present_now) {
227 ca->slot_info[slot].camchange_type = DVB_CA_EN50221_CAMCHANGE_REMOVED;
228 } else {
229 ca->slot_info[slot].camchange_type = DVB_CA_EN50221_CAMCHANGE_INSERTED;
230 }
231 atomic_set(&ca->slot_info[slot].camchange_count, 1);
232 } else {
233 if ((ca->slot_info[slot].slot_state == DVB_CA_SLOTSTATE_WAITREADY) &&
234 (slot_status & DVB_CA_EN50221_POLL_CAM_READY)) {
235 // move to validate state if reset is completed
236 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_VALIDATE;
237 }
238 }
239
240 return cam_changed;
241}
242
243
244/**
245 * Wait for flags to become set on the STATUS register on a CAM interface,
246 * checking for errors and timeout.
247 *
248 * @param ca CA instance.
249 * @param slot Slot on interface.
250 * @param waitfor Flags to wait for.
251 * @param timeout_ms Timeout in milliseconds.
252 *
253 * @return 0 on success, nonzero on error.
254 */
255static int dvb_ca_en50221_wait_if_status(struct dvb_ca_private *ca, int slot,
256 u8 waitfor, int timeout_hz)
257{
258 unsigned long timeout;
259 unsigned long start;
260
261 dprintk("%s\n", __FUNCTION__);
262
263 /* loop until timeout elapsed */
264 start = jiffies;
265 timeout = jiffies + timeout_hz;
266 while (1) {
267 /* read the status and check for error */
268 int res = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_STATUS);
269 if (res < 0)
270 return -EIO;
271
272 /* if we got the flags, it was successful! */
273 if (res & waitfor) {
274 dprintk("%s succeeded timeout:%lu\n", __FUNCTION__, jiffies - start);
275 return 0;
276 }
277
278 /* check for timeout */
279 if (time_after(jiffies, timeout)) {
280 break;
281 }
282
283 /* wait for a bit */
284 msleep(1);
285 }
286
287 dprintk("%s failed timeout:%lu\n", __FUNCTION__, jiffies - start);
288
289 /* if we get here, we've timed out */
290 return -ETIMEDOUT;
291}
292
293
294/**
295 * Initialise the link layer connection to a CAM.
296 *
297 * @param ca CA instance.
298 * @param slot Slot id.
299 *
300 * @return 0 on success, nonzero on failure.
301 */
302static int dvb_ca_en50221_link_init(struct dvb_ca_private *ca, int slot)
303{
304 int ret;
305 int buf_size;
306 u8 buf[2];
307
308 dprintk("%s\n", __FUNCTION__);
309
310 /* we'll be determining these during this function */
311 ca->slot_info[slot].da_irq_supported = 0;
312
313 /* set the host link buffer size temporarily. it will be overwritten with the
314 * real negotiated size later. */
315 ca->slot_info[slot].link_buf_size = 2;
316
317 /* read the buffer size from the CAM */
318 if ((ret = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_COMMAND, IRQEN | CMDREG_SR)) != 0)
319 return ret;
320 if ((ret = dvb_ca_en50221_wait_if_status(ca, slot, STATUSREG_DA, HZ / 10)) != 0)
321 return ret;
322 if ((ret = dvb_ca_en50221_read_data(ca, slot, buf, 2)) != 2)
323 return -EIO;
324 if ((ret = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_COMMAND, IRQEN)) != 0)
325 return ret;
326
327 /* store it, and choose the minimum of our buffer and the CAM's buffer size */
328 buf_size = (buf[0] << 8) | buf[1];
329 if (buf_size > HOST_LINK_BUF_SIZE)
330 buf_size = HOST_LINK_BUF_SIZE;
331 ca->slot_info[slot].link_buf_size = buf_size;
332 buf[0] = buf_size >> 8;
333 buf[1] = buf_size & 0xff;
334 dprintk("Chosen link buffer size of %i\n", buf_size);
335
336 /* write the buffer size to the CAM */
337 if ((ret = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_COMMAND, IRQEN | CMDREG_SW)) != 0)
338 return ret;
339 if ((ret = dvb_ca_en50221_wait_if_status(ca, slot, STATUSREG_FR, HZ / 10)) != 0)
340 return ret;
341 if ((ret = dvb_ca_en50221_write_data(ca, slot, buf, 2)) != 2)
342 return -EIO;
343 if ((ret = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_COMMAND, IRQEN)) != 0)
344 return ret;
345
346 /* success */
347 return 0;
348}
349
350/**
351 * Read a tuple from attribute memory.
352 *
353 * @param ca CA instance.
354 * @param slot Slot id.
355 * @param address Address to read from. Updated.
356 * @param tupleType Tuple id byte. Updated.
357 * @param tupleLength Tuple length. Updated.
358 * @param tuple Dest buffer for tuple (must be 256 bytes). Updated.
359 *
360 * @return 0 on success, nonzero on error.
361 */
362static int dvb_ca_en50221_read_tuple(struct dvb_ca_private *ca, int slot,
363 int *address, int *tupleType, int *tupleLength, u8 * tuple)
364{
365 int i;
366 int _tupleType;
367 int _tupleLength;
368 int _address = *address;
369
370 /* grab the next tuple length and type */
371 if ((_tupleType = ca->pub->read_attribute_mem(ca->pub, slot, _address)) < 0)
372 return _tupleType;
373 if (_tupleType == 0xff) {
374 dprintk("END OF CHAIN TUPLE type:0x%x\n", _tupleType);
375 *address += 2;
376 *tupleType = _tupleType;
377 *tupleLength = 0;
378 return 0;
379 }
380 if ((_tupleLength = ca->pub->read_attribute_mem(ca->pub, slot, _address + 2)) < 0)
381 return _tupleLength;
382 _address += 4;
383
384 dprintk("TUPLE type:0x%x length:%i\n", _tupleType, _tupleLength);
385
386 /* read in the whole tuple */
387 for (i = 0; i < _tupleLength; i++) {
388 tuple[i] = ca->pub->read_attribute_mem(ca->pub, slot, _address + (i * 2));
389 dprintk(" 0x%02x: 0x%02x %c\n",
390 i, tuple[i] & 0xff,
391 ((tuple[i] > 31) && (tuple[i] < 127)) ? tuple[i] : '.');
392 }
393 _address += (_tupleLength * 2);
394
395 // success
396 *tupleType = _tupleType;
397 *tupleLength = _tupleLength;
398 *address = _address;
399 return 0;
400}
401
402
403/**
404 * Parse attribute memory of a CAM module, extracting Config register, and checking
405 * it is a DVB CAM module.
406 *
407 * @param ca CA instance.
408 * @param slot Slot id.
409 *
410 * @return 0 on success, <0 on failure.
411 */
412static int dvb_ca_en50221_parse_attributes(struct dvb_ca_private *ca, int slot)
413{
414 int address = 0;
415 int tupleLength;
416 int tupleType;
417 u8 tuple[257];
418 char *dvb_str;
419 int rasz;
420 int status;
421 int got_cftableentry = 0;
422 int end_chain = 0;
423 int i;
424 u16 manfid = 0;
425 u16 devid = 0;
426
427
428 // CISTPL_DEVICE_0A
429 if ((status =
430 dvb_ca_en50221_read_tuple(ca, slot, &address, &tupleType, &tupleLength, tuple)) < 0)
431 return status;
432 if (tupleType != 0x1D)
433 return -EINVAL;
434
435
436
437 // CISTPL_DEVICE_0C
438 if ((status =
439 dvb_ca_en50221_read_tuple(ca, slot, &address, &tupleType, &tupleLength, tuple)) < 0)
440 return status;
441 if (tupleType != 0x1C)
442 return -EINVAL;
443
444
445
446 // CISTPL_VERS_1
447 if ((status =
448 dvb_ca_en50221_read_tuple(ca, slot, &address, &tupleType, &tupleLength, tuple)) < 0)
449 return status;
450 if (tupleType != 0x15)
451 return -EINVAL;
452
453
454
455 // CISTPL_MANFID
456 if ((status = dvb_ca_en50221_read_tuple(ca, slot, &address, &tupleType,
457 &tupleLength, tuple)) < 0)
458 return status;
459 if (tupleType != 0x20)
460 return -EINVAL;
461 if (tupleLength != 4)
462 return -EINVAL;
463 manfid = (tuple[1] << 8) | tuple[0];
464 devid = (tuple[3] << 8) | tuple[2];
465
466
467
468 // CISTPL_CONFIG
469 if ((status = dvb_ca_en50221_read_tuple(ca, slot, &address, &tupleType,
470 &tupleLength, tuple)) < 0)
471 return status;
472 if (tupleType != 0x1A)
473 return -EINVAL;
474 if (tupleLength < 3)
475 return -EINVAL;
476
477 /* extract the configbase */
478 rasz = tuple[0] & 3;
479 if (tupleLength < (3 + rasz + 14))
480 return -EINVAL;
481 ca->slot_info[slot].config_base = 0;
482 for (i = 0; i < rasz + 1; i++) {
483 ca->slot_info[slot].config_base |= (tuple[2 + i] << (8 * i));
484 }
485
486 /* check it contains the correct DVB string */
487 dvb_str = findstr(tuple, tupleLength, "DVB_CI_V", 8);
488 if (dvb_str == NULL)
489 return -EINVAL;
490 if (tupleLength < ((dvb_str - (char *) tuple) + 12))
491 return -EINVAL;
492
493 /* is it a version we support? */
494 if (strncmp(dvb_str + 8, "1.00", 4)) {
495 printk("dvb_ca adapter %d: Unsupported DVB CAM module version %c%c%c%c\n",
496 ca->dvbdev->adapter->num, dvb_str[8], dvb_str[9], dvb_str[10], dvb_str[11]);
497 return -EINVAL;
498 }
499
500 /* process the CFTABLE_ENTRY tuples, and any after those */
501 while ((!end_chain) && (address < 0x1000)) {
502 if ((status = dvb_ca_en50221_read_tuple(ca, slot, &address, &tupleType,
503 &tupleLength, tuple)) < 0)
504 return status;
505 switch (tupleType) {
506 case 0x1B: // CISTPL_CFTABLE_ENTRY
507 if (tupleLength < (2 + 11 + 17))
508 break;
509
510 /* if we've already parsed one, just use it */
511 if (got_cftableentry)
512 break;
513
514 /* get the config option */
515 ca->slot_info[slot].config_option = tuple[0] & 0x3f;
516
517 /* OK, check it contains the correct strings */
518 if ((findstr(tuple, tupleLength, "DVB_HOST", 8) == NULL) ||
519 (findstr(tuple, tupleLength, "DVB_CI_MODULE", 13) == NULL))
520 break;
521
522 got_cftableentry = 1;
523 break;
524
525 case 0x14: // CISTPL_NO_LINK
526 break;
527
528 case 0xFF: // CISTPL_END
529 end_chain = 1;
530 break;
531
532 default: /* Unknown tuple type - just skip this tuple and move to the next one */
533 dprintk("dvb_ca: Skipping unknown tuple type:0x%x length:0x%x\n", tupleType,
534 tupleLength);
535 break;
536 }
537 }
538
539 if ((address > 0x1000) || (!got_cftableentry))
540 return -EINVAL;
541
542 dprintk("Valid DVB CAM detected MANID:%x DEVID:%x CONFIGBASE:0x%x CONFIGOPTION:0x%x\n",
543 manfid, devid, ca->slot_info[slot].config_base, ca->slot_info[slot].config_option);
544
545 // success!
546 return 0;
547}
548
549
550/**
551 * Set CAM's configoption correctly.
552 *
553 * @param ca CA instance.
554 * @param slot Slot containing the CAM.
555 */
556static int dvb_ca_en50221_set_configoption(struct dvb_ca_private *ca, int slot)
557{
558 int configoption;
559
560 dprintk("%s\n", __FUNCTION__);
561
562 /* set the config option */
563 ca->pub->write_attribute_mem(ca->pub, slot,
564 ca->slot_info[slot].config_base,
565 ca->slot_info[slot].config_option);
566
567 /* check it */
568 configoption = ca->pub->read_attribute_mem(ca->pub, slot, ca->slot_info[slot].config_base);
569 dprintk("Set configoption 0x%x, read configoption 0x%x\n",
570 ca->slot_info[slot].config_option, configoption & 0x3f);
571
572 /* fine! */
573 return 0;
574
575}
576
577
578/**
579 * This function talks to an EN50221 CAM control interface. It reads a buffer of
580 * data from the CAM. The data can either be stored in a supplied buffer, or
581 * automatically be added to the slot's rx_buffer.
582 *
583 * @param ca CA instance.
584 * @param slot Slot to read from.
585 * @param ebuf If non-NULL, the data will be written to this buffer. If NULL,
586 * the data will be added into the buffering system as a normal fragment.
587 * @param ecount Size of ebuf. Ignored if ebuf is NULL.
588 *
589 * @return Number of bytes read, or < 0 on error
590 */
591static int dvb_ca_en50221_read_data(struct dvb_ca_private *ca, int slot, u8 * ebuf, int ecount)
592{
593 int bytes_read;
594 int status;
595 u8 buf[HOST_LINK_BUF_SIZE];
596 int i;
597
598 dprintk("%s\n", __FUNCTION__);
599
600 /* check if we have space for a link buf in the rx_buffer */
601 if (ebuf == NULL) {
602 int buf_free;
603
604 down_read(&ca->slot_info[slot].sem);
605 if (ca->slot_info[slot].rx_buffer.data == NULL) {
606 up_read(&ca->slot_info[slot].sem);
607 status = -EIO;
608 goto exit;
609 }
610 buf_free = dvb_ringbuffer_free(&ca->slot_info[slot].rx_buffer);
611 up_read(&ca->slot_info[slot].sem);
612
613 if (buf_free < (ca->slot_info[slot].link_buf_size + DVB_RINGBUFFER_PKTHDRSIZE)) {
614 status = -EAGAIN;
615 goto exit;
616 }
617 }
618
619 /* check if there is data available */
620 if ((status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_STATUS)) < 0)
621 goto exit;
622 if (!(status & STATUSREG_DA)) {
623 /* no data */
624 status = 0;
625 goto exit;
626 }
627
628 /* read the amount of data */
629 if ((status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_SIZE_HIGH)) < 0)
630 goto exit;
631 bytes_read = status << 8;
632 if ((status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_SIZE_LOW)) < 0)
633 goto exit;
634 bytes_read |= status;
635
636 /* check it will fit */
637 if (ebuf == NULL) {
638 if (bytes_read > ca->slot_info[slot].link_buf_size) {
639 printk("dvb_ca adapter %d: CAM tried to send a buffer larger than the link buffer size (%i > %i)!\n",
640 ca->dvbdev->adapter->num, bytes_read, ca->slot_info[slot].link_buf_size);
641 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_LINKINIT;
642 status = -EIO;
643 goto exit;
644 }
645 if (bytes_read < 2) {
646 printk("dvb_ca adapter %d: CAM sent a buffer that was less than 2 bytes!\n",
647 ca->dvbdev->adapter->num);
648 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_LINKINIT;
649 status = -EIO;
650 goto exit;
651 }
652 } else {
653 if (bytes_read > ecount) {
654 printk("dvb_ca adapter %d: CAM tried to send a buffer larger than the ecount size!\n",
655 ca->dvbdev->adapter->num);
656 status = -EIO;
657 goto exit;
658 }
659 }
660
661 /* fill the buffer */
662 for (i = 0; i < bytes_read; i++) {
663 /* read byte and check */
664 if ((status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_DATA)) < 0)
665 goto exit;
666
667 /* OK, store it in the buffer */
668 buf[i] = status;
669 }
670
671 /* check for read error (RE should now be 0) */
672 if ((status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_STATUS)) < 0)
673 goto exit;
674 if (status & STATUSREG_RE) {
675 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_LINKINIT;
676 status = -EIO;
677 goto exit;
678 }
679
680 /* OK, add it to the receive buffer, or copy into external buffer if supplied */
681 if (ebuf == NULL) {
682 down_read(&ca->slot_info[slot].sem);
683 if (ca->slot_info[slot].rx_buffer.data == NULL) {
684 up_read(&ca->slot_info[slot].sem);
685 status = -EIO;
686 goto exit;
687 }
688 dvb_ringbuffer_pkt_write(&ca->slot_info[slot].rx_buffer, buf, bytes_read);
689 up_read(&ca->slot_info[slot].sem);
690 } else {
691 memcpy(ebuf, buf, bytes_read);
692 }
693
694 dprintk("Received CA packet for slot %i connection id 0x%x last_frag:%i size:0x%x\n", slot,
695 buf[0], (buf[1] & 0x80) == 0, bytes_read);
696
697 /* wake up readers when a last_fragment is received */
698 if ((buf[1] & 0x80) == 0x00) {
699 wake_up_interruptible(&ca->wait_queue);
700 }
701 status = bytes_read;
702
703exit:
704 return status;
705}
706
707
708/**
709 * This function talks to an EN50221 CAM control interface. It writes a buffer of data
710 * to a CAM.
711 *
712 * @param ca CA instance.
713 * @param slot Slot to write to.
714 * @param ebuf The data in this buffer is treated as a complete link-level packet to
715 * be written.
716 * @param count Size of ebuf.
717 *
718 * @return Number of bytes written, or < 0 on error.
719 */
720static int dvb_ca_en50221_write_data(struct dvb_ca_private *ca, int slot, u8 * buf, int bytes_write)
721{
722 int status;
723 int i;
724
725 dprintk("%s\n", __FUNCTION__);
726
727
728 // sanity check
729 if (bytes_write > ca->slot_info[slot].link_buf_size)
730 return -EINVAL;
731
732 /* check if interface is actually waiting for us to read from it, or if a read is in progress */
733 if ((status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_STATUS)) < 0)
734 goto exitnowrite;
735 if (status & (STATUSREG_DA | STATUSREG_RE)) {
736 status = -EAGAIN;
737 goto exitnowrite;
738 }
739
740 /* OK, set HC bit */
741 if ((status = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_COMMAND,
742 IRQEN | CMDREG_HC)) != 0)
743 goto exit;
744
745 /* check if interface is still free */
746 if ((status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_STATUS)) < 0)
747 goto exit;
748 if (!(status & STATUSREG_FR)) {
749 /* it wasn't free => try again later */
750 status = -EAGAIN;
751 goto exit;
752 }
753
754 /* send the amount of data */
755 if ((status = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_SIZE_HIGH, bytes_write >> 8)) != 0)
756 goto exit;
757 if ((status = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_SIZE_LOW,
758 bytes_write & 0xff)) != 0)
759 goto exit;
760
761 /* send the buffer */
762 for (i = 0; i < bytes_write; i++) {
763 if ((status = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_DATA, buf[i])) != 0)
764 goto exit;
765 }
766
767 /* check for write error (WE should now be 0) */
768 if ((status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_STATUS)) < 0)
769 goto exit;
770 if (status & STATUSREG_WE) {
771 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_LINKINIT;
772 status = -EIO;
773 goto exit;
774 }
775 status = bytes_write;
776
777 dprintk("Wrote CA packet for slot %i, connection id 0x%x last_frag:%i size:0x%x\n", slot,
778 buf[0], (buf[1] & 0x80) == 0, bytes_write);
779
780exit:
781 ca->pub->write_cam_control(ca->pub, slot, CTRLIF_COMMAND, IRQEN);
782
783exitnowrite:
784 return status;
785}
786EXPORT_SYMBOL(dvb_ca_en50221_camchange_irq);
787
788
789
790/* ******************************************************************************** */
791/* EN50221 higher level functions */
792
793
794/**
795 * A CAM has been removed => shut it down.
796 *
797 * @param ca CA instance.
798 * @param slot Slot to shut down.
799 */
800static int dvb_ca_en50221_slot_shutdown(struct dvb_ca_private *ca, int slot)
801{
802 dprintk("%s\n", __FUNCTION__);
803
804 down_write(&ca->slot_info[slot].sem);
805 ca->pub->slot_shutdown(ca->pub, slot);
806 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_NONE;
807 vfree(ca->slot_info[slot].rx_buffer.data);
808 ca->slot_info[slot].rx_buffer.data = NULL;
809 up_write(&ca->slot_info[slot].sem);
810
811 /* need to wake up all processes to check if they're now
812 trying to write to a defunct CAM */
813 wake_up_interruptible(&ca->wait_queue);
814
815 dprintk("Slot %i shutdown\n", slot);
816
817 /* success */
818 return 0;
819}
820EXPORT_SYMBOL(dvb_ca_en50221_camready_irq);
821
822
823/**
824 * A CAMCHANGE IRQ has occurred.
825 *
826 * @param ca CA instance.
827 * @param slot Slot concerned.
828 * @param change_type One of the DVB_CA_CAMCHANGE_* values.
829 */
830void dvb_ca_en50221_camchange_irq(struct dvb_ca_en50221 *pubca, int slot, int change_type)
831{
832 struct dvb_ca_private *ca = (struct dvb_ca_private *) pubca->private;
833
834 dprintk("CAMCHANGE IRQ slot:%i change_type:%i\n", slot, change_type);
835
836 switch (change_type) {
837 case DVB_CA_EN50221_CAMCHANGE_REMOVED:
838 case DVB_CA_EN50221_CAMCHANGE_INSERTED:
839 break;
840
841 default:
842 return;
843 }
844
845 ca->slot_info[slot].camchange_type = change_type;
846 atomic_inc(&ca->slot_info[slot].camchange_count);
847 dvb_ca_en50221_thread_wakeup(ca);
848}
849EXPORT_SYMBOL(dvb_ca_en50221_frda_irq);
850
851
852/**
853 * A CAMREADY IRQ has occurred.
854 *
855 * @param ca CA instance.
856 * @param slot Slot concerned.
857 */
858void dvb_ca_en50221_camready_irq(struct dvb_ca_en50221 *pubca, int slot)
859{
860 struct dvb_ca_private *ca = (struct dvb_ca_private *) pubca->private;
861
862 dprintk("CAMREADY IRQ slot:%i\n", slot);
863
864 if (ca->slot_info[slot].slot_state == DVB_CA_SLOTSTATE_WAITREADY) {
865 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_VALIDATE;
866 dvb_ca_en50221_thread_wakeup(ca);
867 }
868}
869
870
871/**
872 * An FR or DA IRQ has occurred.
873 *
874 * @param ca CA instance.
875 * @param slot Slot concerned.
876 */
877void dvb_ca_en50221_frda_irq(struct dvb_ca_en50221 *pubca, int slot)
878{
879 struct dvb_ca_private *ca = (struct dvb_ca_private *) pubca->private;
880 int flags;
881
882 dprintk("FR/DA IRQ slot:%i\n", slot);
883
884 switch (ca->slot_info[slot].slot_state) {
885 case DVB_CA_SLOTSTATE_LINKINIT:
886 flags = ca->pub->read_cam_control(pubca, slot, CTRLIF_STATUS);
887 if (flags & STATUSREG_DA) {
888 dprintk("CAM supports DA IRQ\n");
889 ca->slot_info[slot].da_irq_supported = 1;
890 }
891 break;
892
893 case DVB_CA_SLOTSTATE_RUNNING:
894 if (ca->open)
895 dvb_ca_en50221_read_data(ca, slot, NULL, 0);
896 break;
897 }
898}
899
900
901
902/* ******************************************************************************** */
903/* EN50221 thread functions */
904
905/**
906 * Wake up the DVB CA thread
907 *
908 * @param ca CA instance.
909 */
910static void dvb_ca_en50221_thread_wakeup(struct dvb_ca_private *ca)
911{
912
913 dprintk("%s\n", __FUNCTION__);
914
915 ca->wakeup = 1;
916 mb();
917 wake_up_interruptible(&ca->thread_queue);
918}
919
920/**
921 * Used by the CA thread to determine if an early wakeup is necessary
922 *
923 * @param ca CA instance.
924 */
925static int dvb_ca_en50221_thread_should_wakeup(struct dvb_ca_private *ca)
926{
927 if (ca->wakeup) {
928 ca->wakeup = 0;
929 return 1;
930 }
931 if (ca->exit)
932 return 1;
933
934 return 0;
935}
936
937
938/**
939 * Update the delay used by the thread.
940 *
941 * @param ca CA instance.
942 */
943static void dvb_ca_en50221_thread_update_delay(struct dvb_ca_private *ca)
944{
945 int delay;
946 int curdelay = 100000000;
947 int slot;
948
949 for (slot = 0; slot < ca->slot_count; slot++) {
950 switch (ca->slot_info[slot].slot_state) {
951 default:
952 case DVB_CA_SLOTSTATE_NONE:
953 case DVB_CA_SLOTSTATE_INVALID:
954 delay = HZ * 60;
955 if (!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE)) {
956 delay = HZ / 10;
957 }
958 break;
959
960 case DVB_CA_SLOTSTATE_UNINITIALISED:
961 case DVB_CA_SLOTSTATE_WAITREADY:
962 case DVB_CA_SLOTSTATE_VALIDATE:
963 case DVB_CA_SLOTSTATE_WAITFR:
964 case DVB_CA_SLOTSTATE_LINKINIT:
965 delay = HZ / 10;
966 break;
967
968 case DVB_CA_SLOTSTATE_RUNNING:
969 delay = HZ * 60;
970 if (!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE)) {
971 delay = HZ / 10;
972 }
973 if (ca->open) {
974 if ((!ca->slot_info[slot].da_irq_supported) ||
975 (!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_DA))) {
976 delay = HZ / 10;
977 }
978 }
979 break;
980 }
981
982 if (delay < curdelay)
983 curdelay = delay;
984 }
985
986 ca->delay = curdelay;
987}
988
989
990
991/**
992 * Kernel thread which monitors CA slots for CAM changes, and performs data transfers.
993 */
994static int dvb_ca_en50221_thread(void *data)
995{
996 struct dvb_ca_private *ca = (struct dvb_ca_private *) data;
997 char name[15];
998 int slot;
999 int flags;
1000 int status;
1001 int pktcount;
1002 void *rxbuf;
1003
1004 dprintk("%s\n", __FUNCTION__);
1005
1006 /* setup kernel thread */
1007 snprintf(name, sizeof(name), "kdvb-ca-%i:%i", ca->dvbdev->adapter->num, ca->dvbdev->id);
1008
1009 lock_kernel();
1010 daemonize(name);
1011 sigfillset(&current->blocked);
1012 unlock_kernel();
1013
1014 /* choose the correct initial delay */
1015 dvb_ca_en50221_thread_update_delay(ca);
1016
1017 /* main loop */
1018 while (!ca->exit) {
1019 /* sleep for a bit */
1020 if (!ca->wakeup) {
1021 flags = wait_event_interruptible_timeout(ca->thread_queue,
1022 dvb_ca_en50221_thread_should_wakeup(ca),
1023 ca->delay);
1024 if ((flags == -ERESTARTSYS) || ca->exit) {
1025 /* got signal or quitting */
1026 break;
1027 }
1028 }
1029 ca->wakeup = 0;
1030
1031 /* go through all the slots processing them */
1032 for (slot = 0; slot < ca->slot_count; slot++) {
1033
1034 // check the cam status + deal with CAMCHANGEs
1035 while (dvb_ca_en50221_check_camstatus(ca, slot)) {
1036 /* clear down an old CI slot if necessary */
1037 if (ca->slot_info[slot].slot_state != DVB_CA_SLOTSTATE_NONE)
1038 dvb_ca_en50221_slot_shutdown(ca, slot);
1039
1040 /* if a CAM is NOW present, initialise it */
1041 if (ca->slot_info[slot].camchange_type == DVB_CA_EN50221_CAMCHANGE_INSERTED) {
1042 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_UNINITIALISED;
1043 }
1044
1045 /* we've handled one CAMCHANGE */
1046 dvb_ca_en50221_thread_update_delay(ca);
1047 atomic_dec(&ca->slot_info[slot].camchange_count);
1048 }
1049
1050 // CAM state machine
1051 switch (ca->slot_info[slot].slot_state) {
1052 case DVB_CA_SLOTSTATE_NONE:
1053 case DVB_CA_SLOTSTATE_INVALID:
1054 // no action needed
1055 break;
1056
1057 case DVB_CA_SLOTSTATE_UNINITIALISED:
1058 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_WAITREADY;
1059 ca->pub->slot_reset(ca->pub, slot);
1060 ca->slot_info[slot].timeout = jiffies + (INIT_TIMEOUT_SECS * HZ);
1061 break;
1062
1063 case DVB_CA_SLOTSTATE_WAITREADY:
1064 if (time_after(jiffies, ca->slot_info[slot].timeout)) {
1065 printk("dvb_ca adaptor %d: PC card did not respond :(\n",
1066 ca->dvbdev->adapter->num);
1067 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_INVALID;
1068 dvb_ca_en50221_thread_update_delay(ca);
1069 break;
1070 }
1071 // no other action needed; will automatically change state when ready
1072 break;
1073
1074 case DVB_CA_SLOTSTATE_VALIDATE:
1075 if (dvb_ca_en50221_parse_attributes(ca, slot)
1076 != 0) {
1077 printk("dvb_ca adapter %d: Invalid PC card inserted :(\n",
1078 ca->dvbdev->adapter->num);
1079 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_INVALID;
1080 dvb_ca_en50221_thread_update_delay(ca);
1081 break;
1082 }
1083 if (dvb_ca_en50221_set_configoption(ca, slot) != 0) {
1084 printk("dvb_ca adapter %d: Unable to initialise CAM :(\n",
1085 ca->dvbdev->adapter->num);
1086 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_INVALID;
1087 dvb_ca_en50221_thread_update_delay(ca);
1088 break;
1089 }
1090 if (ca->pub->write_cam_control(ca->pub, slot,
1091 CTRLIF_COMMAND, CMDREG_RS) != 0) {
1092 printk("dvb_ca adapter %d: Unable to reset CAM IF\n",
1093 ca->dvbdev->adapter->num);
1094 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_INVALID;
1095 dvb_ca_en50221_thread_update_delay(ca);
1096 break;
1097 }
1098 dprintk("DVB CAM validated successfully\n");
1099
1100 ca->slot_info[slot].timeout = jiffies + (INIT_TIMEOUT_SECS * HZ);
1101 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_WAITFR;
1102 ca->wakeup = 1;
1103 break;
1104
1105 case DVB_CA_SLOTSTATE_WAITFR:
1106 if (time_after(jiffies, ca->slot_info[slot].timeout)) {
1107 printk("dvb_ca adapter %d: DVB CAM did not respond :(\n",
1108 ca->dvbdev->adapter->num);
1109 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_INVALID;
1110 dvb_ca_en50221_thread_update_delay(ca);
1111 break;
1112 }
1113
1114 flags = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_STATUS);
1115 if (flags & STATUSREG_FR) {
1116 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_LINKINIT;
1117 ca->wakeup = 1;
1118 }
1119 break;
1120
1121 case DVB_CA_SLOTSTATE_LINKINIT:
1122 if (dvb_ca_en50221_link_init(ca, slot) != 0) {
1123 printk("dvb_ca adapter %d: DVB CAM link initialisation failed :(\n", ca->dvbdev->adapter->num);
1124 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_INVALID;
1125 dvb_ca_en50221_thread_update_delay(ca);
1126 break;
1127 }
1128
1129 rxbuf = vmalloc(RX_BUFFER_SIZE);
1130 if (rxbuf == NULL) {
1131 printk("dvb_ca adapter %d: Unable to allocate CAM rx buffer :(\n", ca->dvbdev->adapter->num);
1132 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_INVALID;
1133 dvb_ca_en50221_thread_update_delay(ca);
1134 break;
1135 }
1136 down_write(&ca->slot_info[slot].sem);
1137 dvb_ringbuffer_init(&ca->slot_info[slot].rx_buffer, rxbuf, RX_BUFFER_SIZE);
1138 up_write(&ca->slot_info[slot].sem);
1139
1140 ca->pub->slot_ts_enable(ca->pub, slot);
1141 ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_RUNNING;
1142 dvb_ca_en50221_thread_update_delay(ca);
1143 printk("dvb_ca adapter %d: DVB CAM detected and initialised successfully\n", ca->dvbdev->adapter->num);
1144 break;
1145
1146 case DVB_CA_SLOTSTATE_RUNNING:
1147 if (!ca->open)
1148 continue;
1149
1150 // no need to poll if the CAM supports IRQs
1151 if (ca->slot_info[slot].da_irq_supported)
1152 break;
1153
1154 // poll mode
1155 pktcount = 0;
1156 while ((status = dvb_ca_en50221_read_data(ca, slot, NULL, 0)) > 0) {
1157 if (!ca->open)
1158 break;
1159
1160 /* if a CAMCHANGE occurred at some point, do not do any more processing of this slot */
1161 if (dvb_ca_en50221_check_camstatus(ca, slot)) {
1162 // we dont want to sleep on the next iteration so we can handle the cam change
1163 ca->wakeup = 1;
1164 break;
1165 }
1166
1167 /* check if we've hit our limit this time */
1168 if (++pktcount >= MAX_RX_PACKETS_PER_ITERATION) {
1169 // dont sleep; there is likely to be more data to read
1170 ca->wakeup = 1;
1171 break;
1172 }
1173 }
1174 break;
1175 }
1176 }
1177 }
1178
1179 /* completed */
1180 ca->thread_pid = 0;
1181 mb();
1182 wake_up_interruptible(&ca->thread_queue);
1183 return 0;
1184}
1185
1186
1187
1188/* ******************************************************************************** */
1189/* EN50221 IO interface functions */
1190
1191/**
1192 * Real ioctl implementation.
1193 * NOTE: CA_SEND_MSG/CA_GET_MSG ioctls have userspace buffers passed to them.
1194 *
1195 * @param inode Inode concerned.
1196 * @param file File concerned.
1197 * @param cmd IOCTL command.
1198 * @param arg Associated argument.
1199 *
1200 * @return 0 on success, <0 on error.
1201 */
1202static int dvb_ca_en50221_io_do_ioctl(struct inode *inode, struct file *file,
1203 unsigned int cmd, void *parg)
1204{
1205 struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;
1206 struct dvb_ca_private *ca = (struct dvb_ca_private *) dvbdev->priv;
1207 int err = 0;
1208 int slot;
1209
1210 dprintk("%s\n", __FUNCTION__);
1211
1212 switch (cmd) {
1213 case CA_RESET:
1214 for (slot = 0; slot < ca->slot_count; slot++) {
1215 if (ca->slot_info[slot].slot_state != DVB_CA_SLOTSTATE_NONE) {
1216 dvb_ca_en50221_slot_shutdown(ca, slot);
1217 if (ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE)
1218 dvb_ca_en50221_camchange_irq(ca->pub,
1219 slot,
1220 DVB_CA_EN50221_CAMCHANGE_INSERTED);
1221 }
1222 }
1223 ca->next_read_slot = 0;
1224 dvb_ca_en50221_thread_wakeup(ca);
1225 break;
1226
1227 case CA_GET_CAP: {
1228 struct ca_caps *caps = (struct ca_caps *) parg;
1229
1230 caps->slot_num = ca->slot_count;
1231 caps->slot_type = CA_CI_LINK;
1232 caps->descr_num = 0;
1233 caps->descr_type = 0;
1234 break;
1235 }
1236
1237 case CA_GET_SLOT_INFO: {
1238 struct ca_slot_info *info = (struct ca_slot_info *) parg;
1239
1240 if ((info->num > ca->slot_count) || (info->num < 0))
1241 return -EINVAL;
1242
1243 info->type = CA_CI_LINK;
1244 info->flags = 0;
1245 if ((ca->slot_info[info->num].slot_state != DVB_CA_SLOTSTATE_NONE)
1246 && (ca->slot_info[info->num].slot_state != DVB_CA_SLOTSTATE_INVALID)) {
1247 info->flags = CA_CI_MODULE_PRESENT;
1248 }
1249 if (ca->slot_info[info->num].slot_state == DVB_CA_SLOTSTATE_RUNNING) {
1250 info->flags |= CA_CI_MODULE_READY;
1251 }
1252 break;
1253 }
1254
1255 default:
1256 err = -EINVAL;
1257 break;
1258 }
1259
1260 return err;
1261}
1262
1263
1264/**
1265 * Wrapper for ioctl implementation.
1266 *
1267 * @param inode Inode concerned.
1268 * @param file File concerned.
1269 * @param cmd IOCTL command.
1270 * @param arg Associated argument.
1271 *
1272 * @return 0 on success, <0 on error.
1273 */
1274static int dvb_ca_en50221_io_ioctl(struct inode *inode, struct file *file,
1275 unsigned int cmd, unsigned long arg)
1276{
1277 return dvb_usercopy(inode, file, cmd, arg, dvb_ca_en50221_io_do_ioctl);
1278}
1279
1280
1281/**
1282 * Implementation of write() syscall.
1283 *
1284 * @param file File structure.
1285 * @param buf Source buffer.
1286 * @param count Size of source buffer.
1287 * @param ppos Position in file (ignored).
1288 *
1289 * @return Number of bytes read, or <0 on error.
1290 */
1291static ssize_t dvb_ca_en50221_io_write(struct file *file,
1292 const char __user * buf, size_t count, loff_t * ppos)
1293{
1294 struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;
1295 struct dvb_ca_private *ca = (struct dvb_ca_private *) dvbdev->priv;
1296 u8 slot, connection_id;
1297 int status;
1298 char fragbuf[HOST_LINK_BUF_SIZE];
1299 int fragpos = 0;
1300 int fraglen;
1301 unsigned long timeout;
1302 int written;
1303
1304 dprintk("%s\n", __FUNCTION__);
1305
1306 /* Incoming packet has a 2 byte header. hdr[0] = slot_id, hdr[1] = connection_id */
1307 if (count < 2)
1308 return -EINVAL;
1309
1310 /* extract slot & connection id */
1311 if (copy_from_user(&slot, buf, 1))
1312 return -EFAULT;
1313 if (copy_from_user(&connection_id, buf + 1, 1))
1314 return -EFAULT;
1315 buf += 2;
1316 count -= 2;
1317
1318 /* check if the slot is actually running */
1319 if (ca->slot_info[slot].slot_state != DVB_CA_SLOTSTATE_RUNNING)
1320 return -EINVAL;
1321
1322 /* fragment the packets & store in the buffer */
1323 while (fragpos < count) {
1324 fraglen = ca->slot_info[slot].link_buf_size - 2;
1325 if ((count - fragpos) < fraglen)
1326 fraglen = count - fragpos;
1327
1328 fragbuf[0] = connection_id;
1329 fragbuf[1] = ((fragpos + fraglen) < count) ? 0x80 : 0x00;
1330 if ((status = copy_from_user(fragbuf + 2, buf + fragpos, fraglen)) != 0)
1331 goto exit;
1332
1333 timeout = jiffies + HZ / 2;
1334 written = 0;
1335 while (!time_after(jiffies, timeout)) {
1336 /* check the CAM hasn't been removed/reset in the meantime */
1337 if (ca->slot_info[slot].slot_state != DVB_CA_SLOTSTATE_RUNNING) {
1338 status = -EIO;
1339 goto exit;
1340 }
1341
1342 status = dvb_ca_en50221_write_data(ca, slot, fragbuf, fraglen + 2);
1343 if (status == (fraglen + 2)) {
1344 written = 1;
1345 break;
1346 }
1347 if (status != -EAGAIN)
1348 goto exit;
1349
1350 msleep(1);
1351 }
1352 if (!written) {
1353 status = -EIO;
1354 goto exit;
1355 }
1356
1357 fragpos += fraglen;
1358 }
1359 status = count + 2;
1360
1361exit:
1362 return status;
1363}
1364
1365
1366/**
1367 * Condition for waking up in dvb_ca_en50221_io_read_condition
1368 */
1369static int dvb_ca_en50221_io_read_condition(struct dvb_ca_private *ca, int *result, int *_slot)
1370{
1371 int slot;
1372 int slot_count = 0;
1373 int idx;
1374 int fraglen;
1375 int connection_id = -1;
1376 int found = 0;
1377 u8 hdr[2];
1378
1379 slot = ca->next_read_slot;
1380 while ((slot_count < ca->slot_count) && (!found)) {
1381 if (ca->slot_info[slot].slot_state != DVB_CA_SLOTSTATE_RUNNING)
1382 goto nextslot;
1383
1384 down_read(&ca->slot_info[slot].sem);
1385
1386 if (ca->slot_info[slot].rx_buffer.data == NULL) {
1387 up_read(&ca->slot_info[slot].sem);
1388 return 0;
1389 }
1390
1391 idx = dvb_ringbuffer_pkt_next(&ca->slot_info[slot].rx_buffer, -1, &fraglen);
1392 while (idx != -1) {
1393 dvb_ringbuffer_pkt_read(&ca->slot_info[slot].rx_buffer, idx, 0, hdr, 2, 0);
1394 if (connection_id == -1)
1395 connection_id = hdr[0];
1396 if ((hdr[0] == connection_id) && ((hdr[1] & 0x80) == 0)) {
1397 *_slot = slot;
1398 found = 1;
1399 break;
1400 }
1401
1402 idx = dvb_ringbuffer_pkt_next(&ca->slot_info[slot].rx_buffer, idx, &fraglen);
1403 }
1404
1405 if (!found)
1406 up_read(&ca->slot_info[slot].sem);
1407
1408 nextslot:
1409 slot = (slot + 1) % ca->slot_count;
1410 slot_count++;
1411 }
1412
1413 ca->next_read_slot = slot;
1414 return found;
1415}
1416
1417
1418/**
1419 * Implementation of read() syscall.
1420 *
1421 * @param file File structure.
1422 * @param buf Destination buffer.
1423 * @param count Size of destination buffer.
1424 * @param ppos Position in file (ignored).
1425 *
1426 * @return Number of bytes read, or <0 on error.
1427 */
1428static ssize_t dvb_ca_en50221_io_read(struct file *file, char __user * buf,
1429 size_t count, loff_t * ppos)
1430{
1431 struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;
1432 struct dvb_ca_private *ca = (struct dvb_ca_private *) dvbdev->priv;
1433 int status;
1434 int result = 0;
1435 u8 hdr[2];
1436 int slot;
1437 int connection_id = -1;
1438 size_t idx, idx2;
1439 int last_fragment = 0;
1440 size_t fraglen;
1441 int pktlen;
1442 int dispose = 0;
1443
1444 dprintk("%s\n", __FUNCTION__);
1445
1446 /* Outgoing packet has a 2 byte header. hdr[0] = slot_id, hdr[1] = connection_id */
1447 if (count < 2)
1448 return -EINVAL;
1449
1450 /* wait for some data */
1451 if ((status = dvb_ca_en50221_io_read_condition(ca, &result, &slot)) == 0) {
1452
1453 /* if we're in nonblocking mode, exit immediately */
1454 if (file->f_flags & O_NONBLOCK)
1455 return -EWOULDBLOCK;
1456
1457 /* wait for some data */
1458 status = wait_event_interruptible(ca->wait_queue,
1459 dvb_ca_en50221_io_read_condition
1460 (ca, &result, &slot));
1461 }
1462 if ((status < 0) || (result < 0)) {
1463 if (result)
1464 return result;
1465 return status;
1466 }
1467
1468 idx = dvb_ringbuffer_pkt_next(&ca->slot_info[slot].rx_buffer, -1, &fraglen);
1469 pktlen = 2;
1470 do {
1471 if (idx == -1) {
1472 printk("dvb_ca adapter %d: BUG: read packet ended before last_fragment encountered\n", ca->dvbdev->adapter->num);
1473 status = -EIO;
1474 goto exit;
1475 }
1476
1477 dvb_ringbuffer_pkt_read(&ca->slot_info[slot].rx_buffer, idx, 0, hdr, 2, 0);
1478 if (connection_id == -1)
1479 connection_id = hdr[0];
1480 if (hdr[0] == connection_id) {
1481 if (pktlen < count) {
1482 if ((pktlen + fraglen - 2) > count) {
1483 fraglen = count - pktlen;
1484 } else {
1485 fraglen -= 2;
1486 }
1487
1488 if ((status = dvb_ringbuffer_pkt_read(&ca->slot_info[slot].rx_buffer, idx, 2,
1489 buf + pktlen, fraglen, 1)) < 0) {
1490 goto exit;
1491 }
1492 pktlen += fraglen;
1493 }
1494
1495 if ((hdr[1] & 0x80) == 0)
1496 last_fragment = 1;
1497 dispose = 1;
1498 }
1499
1500 idx2 = dvb_ringbuffer_pkt_next(&ca->slot_info[slot].rx_buffer, idx, &fraglen);
1501 if (dispose)
1502 dvb_ringbuffer_pkt_dispose(&ca->slot_info[slot].rx_buffer, idx);
1503 idx = idx2;
1504 dispose = 0;
1505 } while (!last_fragment);
1506
1507 hdr[0] = slot;
1508 hdr[1] = connection_id;
1509 if ((status = copy_to_user(buf, hdr, 2)) != 0)
1510 goto exit;
1511 status = pktlen;
1512
1513 exit:
1514 up_read(&ca->slot_info[slot].sem);
1515 return status;
1516}
1517
1518
1519/**
1520 * Implementation of file open syscall.
1521 *
1522 * @param inode Inode concerned.
1523 * @param file File concerned.
1524 *
1525 * @return 0 on success, <0 on failure.
1526 */
1527static int dvb_ca_en50221_io_open(struct inode *inode, struct file *file)
1528{
1529 struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;
1530 struct dvb_ca_private *ca = (struct dvb_ca_private *) dvbdev->priv;
1531 int err;
1532 int i;
1533
1534 dprintk("%s\n", __FUNCTION__);
1535
1536 if (!try_module_get(ca->pub->owner))
1537 return -EIO;
1538
1539 err = dvb_generic_open(inode, file);
1540 if (err < 0)
1541 return err;
1542
1543 for (i = 0; i < ca->slot_count; i++) {
1544
1545 if (ca->slot_info[i].slot_state == DVB_CA_SLOTSTATE_RUNNING) {
1546 down_write(&ca->slot_info[i].sem);
1547 if (ca->slot_info[i].rx_buffer.data != NULL) {
1548 dvb_ringbuffer_flush(&ca->slot_info[i].rx_buffer);
1549 }
1550 up_write(&ca->slot_info[i].sem);
1551 }
1552 }
1553
1554 ca->open = 1;
1555 dvb_ca_en50221_thread_update_delay(ca);
1556 dvb_ca_en50221_thread_wakeup(ca);
1557
1558 return 0;
1559}
1560
1561
1562/**
1563 * Implementation of file close syscall.
1564 *
1565 * @param inode Inode concerned.
1566 * @param file File concerned.
1567 *
1568 * @return 0 on success, <0 on failure.
1569 */
1570static int dvb_ca_en50221_io_release(struct inode *inode, struct file *file)
1571{
1572 struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;
1573 struct dvb_ca_private *ca = (struct dvb_ca_private *) dvbdev->priv;
1574 int err = 0;
1575
1576 dprintk("%s\n", __FUNCTION__);
1577
1578 /* mark the CA device as closed */
1579 ca->open = 0;
1580 dvb_ca_en50221_thread_update_delay(ca);
1581
1582 err = dvb_generic_release(inode, file);
1583
1584 module_put(ca->pub->owner);
1585
1586 return 0;
1587}
1588
1589
1590/**
1591 * Implementation of poll() syscall.
1592 *
1593 * @param file File concerned.
1594 * @param wait poll wait table.
1595 *
1596 * @return Standard poll mask.
1597 */
1598static unsigned int dvb_ca_en50221_io_poll(struct file *file, poll_table * wait)
1599{
1600 struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;
1601 struct dvb_ca_private *ca = (struct dvb_ca_private *) dvbdev->priv;
1602 unsigned int mask = 0;
1603 int slot;
1604 int result = 0;
1605
1606 dprintk("%s\n", __FUNCTION__);
1607
1608 if (dvb_ca_en50221_io_read_condition(ca, &result, &slot) == 1) {
1609 up_read(&ca->slot_info[slot].sem);
1610 mask |= POLLIN;
1611 }
1612
1613 /* if there is something, return now */
1614 if (mask)
1615 return mask;
1616
1617 /* wait for something to happen */
1618 poll_wait(file, &ca->wait_queue, wait);
1619
1620 if (dvb_ca_en50221_io_read_condition(ca, &result, &slot) == 1) {
1621 up_read(&ca->slot_info[slot].sem);
1622 mask |= POLLIN;
1623 }
1624
1625 return mask;
1626}
1627EXPORT_SYMBOL(dvb_ca_en50221_init);
1628
1629
1630static struct file_operations dvb_ca_fops = {
1631 .owner = THIS_MODULE,
1632 .read = dvb_ca_en50221_io_read,
1633 .write = dvb_ca_en50221_io_write,
1634 .ioctl = dvb_ca_en50221_io_ioctl,
1635 .open = dvb_ca_en50221_io_open,
1636 .release = dvb_ca_en50221_io_release,
1637 .poll = dvb_ca_en50221_io_poll,
1638};
1639
1640static struct dvb_device dvbdev_ca = {
1641 .priv = NULL,
1642 .users = 1,
1643 .readers = 1,
1644 .writers = 1,
1645 .fops = &dvb_ca_fops,
1646};
1647
1648
1649/* ******************************************************************************** */
1650/* Initialisation/shutdown functions */
1651
1652
1653/**
1654 * Initialise a new DVB CA EN50221 interface device.
1655 *
1656 * @param dvb_adapter DVB adapter to attach the new CA device to.
1657 * @param ca The dvb_ca instance.
1658 * @param flags Flags describing the CA device (DVB_CA_FLAG_*).
1659 * @param slot_count Number of slots supported.
1660 *
1661 * @return 0 on success, nonzero on failure
1662 */
1663int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter,
1664 struct dvb_ca_en50221 *pubca, int flags, int slot_count)
1665{
1666 int ret;
1667 struct dvb_ca_private *ca = NULL;
1668 int i;
1669
1670 dprintk("%s\n", __FUNCTION__);
1671
1672 if (slot_count < 1)
1673 return -EINVAL;
1674
1675 /* initialise the system data */
1676 if ((ca =
1677 (struct dvb_ca_private *) kmalloc(sizeof(struct dvb_ca_private),
1678 GFP_KERNEL)) == NULL) {
1679 ret = -ENOMEM;
1680 goto error;
1681 }
1682 memset(ca, 0, sizeof(struct dvb_ca_private));
1683 ca->pub = pubca;
1684 ca->flags = flags;
1685 ca->slot_count = slot_count;
1686 if ((ca->slot_info = kmalloc(sizeof(struct dvb_ca_slot) * slot_count, GFP_KERNEL)) == NULL) {
1687 ret = -ENOMEM;
1688 goto error;
1689 }
1690 memset(ca->slot_info, 0, sizeof(struct dvb_ca_slot) * slot_count);
1691 init_waitqueue_head(&ca->wait_queue);
1692 ca->thread_pid = 0;
1693 init_waitqueue_head(&ca->thread_queue);
1694 ca->exit = 0;
1695 ca->open = 0;
1696 ca->wakeup = 0;
1697 ca->next_read_slot = 0;
1698 pubca->private = ca;
1699
1700 /* register the DVB device */
1701 ret = dvb_register_device(dvb_adapter, &ca->dvbdev, &dvbdev_ca, ca, DVB_DEVICE_CA);
1702 if (ret)
1703 goto error;
1704
1705 /* now initialise each slot */
1706 for (i = 0; i < slot_count; i++) {
1707 memset(&ca->slot_info[i], 0, sizeof(struct dvb_ca_slot));
1708 ca->slot_info[i].slot_state = DVB_CA_SLOTSTATE_NONE;
1709 atomic_set(&ca->slot_info[i].camchange_count, 0);
1710 ca->slot_info[i].camchange_type = DVB_CA_EN50221_CAMCHANGE_REMOVED;
1711 init_rwsem(&ca->slot_info[i].sem);
1712 }
1713
1714 if (signal_pending(current)) {
1715 ret = -EINTR;
1716 goto error;
1717 }
1718 mb();
1719
1720 /* create a kthread for monitoring this CA device */
1721
1722 ret = kernel_thread(dvb_ca_en50221_thread, ca, 0);
1723
1724 if (ret < 0) {
1725 printk("dvb_ca_init: failed to start kernel_thread (%d)\n", ret);
1726 goto error;
1727 }
1728 ca->thread_pid = ret;
1729 return 0;
1730
1731 error:
1732 if (ca != NULL) {
1733 if (ca->dvbdev != NULL)
1734 dvb_unregister_device(ca->dvbdev);
1735 kfree(ca->slot_info);
1736 kfree(ca);
1737 }
1738 pubca->private = NULL;
1739 return ret;
1740}
1741EXPORT_SYMBOL(dvb_ca_en50221_release);
1742
1743
1744
1745/**
1746 * Release a DVB CA EN50221 interface device.
1747 *
1748 * @param ca_dev The dvb_device_t instance for the CA device.
1749 * @param ca The associated dvb_ca instance.
1750 */
1751void dvb_ca_en50221_release(struct dvb_ca_en50221 *pubca)
1752{
1753 struct dvb_ca_private *ca = (struct dvb_ca_private *) pubca->private;
1754 int i;
1755
1756 dprintk("%s\n", __FUNCTION__);
1757
1758 /* shutdown the thread if there was one */
1759 if (ca->thread_pid) {
1760 if (kill_proc(ca->thread_pid, 0, 1) == -ESRCH) {
1761 printk("dvb_ca_release adapter %d: thread PID %d already died\n",
1762 ca->dvbdev->adapter->num, ca->thread_pid);
1763 } else {
1764 ca->exit = 1;
1765 mb();
1766 dvb_ca_en50221_thread_wakeup(ca);
1767 wait_event_interruptible(ca->thread_queue, ca->thread_pid == 0);
1768 }
1769 }
1770
1771 for (i = 0; i < ca->slot_count; i++) {
1772 dvb_ca_en50221_slot_shutdown(ca, i);
1773 }
1774 kfree(ca->slot_info);
1775 dvb_unregister_device(ca->dvbdev);
1776 kfree(ca);
1777 pubca->private = NULL;
1778}
diff --git a/drivers/media/dvb/dvb-core/dvb_ca_en50221.h b/drivers/media/dvb/dvb-core/dvb_ca_en50221.h
new file mode 100644
index 000000000000..8467e63ddc0d
--- /dev/null
+++ b/drivers/media/dvb/dvb-core/dvb_ca_en50221.h
@@ -0,0 +1,134 @@
1/*
2 * dvb_ca.h: generic DVB functions for EN50221 CA interfaces
3 *
4 * Copyright (C) 2004 Andrew de Quincey
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public License
8 * as published by the Free Software Foundation; either version 2.1
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20
21#ifndef _DVB_CA_EN50221_H_
22#define _DVB_CA_EN50221_H_
23
24#include <linux/list.h>
25#include <linux/dvb/ca.h>
26
27#include "dvbdev.h"
28
29#define DVB_CA_EN50221_POLL_CAM_PRESENT 1
30#define DVB_CA_EN50221_POLL_CAM_CHANGED 2
31#define DVB_CA_EN50221_POLL_CAM_READY 4
32
33#define DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE 1
34#define DVB_CA_EN50221_FLAG_IRQ_FR 2
35#define DVB_CA_EN50221_FLAG_IRQ_DA 4
36
37#define DVB_CA_EN50221_CAMCHANGE_REMOVED 0
38#define DVB_CA_EN50221_CAMCHANGE_INSERTED 1
39
40
41
42/* Structure describing a CA interface */
43struct dvb_ca_en50221 {
44
45 /* the module owning this structure */
46 struct module* owner;
47
48 /* NOTE: the read_*, write_* and poll_slot_status functions must use locks as
49 * they may be called from several threads at once */
50
51 /* functions for accessing attribute memory on the CAM */
52 int (*read_attribute_mem)(struct dvb_ca_en50221* ca, int slot, int address);
53 int (*write_attribute_mem)(struct dvb_ca_en50221* ca, int slot, int address, u8 value);
54
55 /* functions for accessing the control interface on the CAM */
56 int (*read_cam_control)(struct dvb_ca_en50221* ca, int slot, u8 address);
57 int (*write_cam_control)(struct dvb_ca_en50221* ca, int slot, u8 address, u8 value);
58
59 /* Functions for controlling slots */
60 int (*slot_reset)(struct dvb_ca_en50221* ca, int slot);
61 int (*slot_shutdown)(struct dvb_ca_en50221* ca, int slot);
62 int (*slot_ts_enable)(struct dvb_ca_en50221* ca, int slot);
63
64 /*
65 * Poll slot status.
66 * Only necessary if DVB_CA_FLAG_EN50221_IRQ_CAMCHANGE is not set
67 */
68 int (*poll_slot_status)(struct dvb_ca_en50221* ca, int slot, int open);
69
70 /* private data, used by caller */
71 void* data;
72
73 /* Opaque data used by the dvb_ca core. Do not modify! */
74 void* private;
75};
76
77
78
79
80/* ******************************************************************************** */
81/* Functions for reporting IRQ events */
82
83/**
84 * A CAMCHANGE IRQ has occurred.
85 *
86 * @param ca CA instance.
87 * @param slot Slot concerned.
88 * @param change_type One of the DVB_CA_CAMCHANGE_* values
89 */
90void dvb_ca_en50221_camchange_irq(struct dvb_ca_en50221* pubca, int slot, int change_type);
91
92/**
93 * A CAMREADY IRQ has occurred.
94 *
95 * @param ca CA instance.
96 * @param slot Slot concerned.
97 */
98void dvb_ca_en50221_camready_irq(struct dvb_ca_en50221* pubca, int slot);
99
100/**
101 * An FR or a DA IRQ has occurred.
102 *
103 * @param ca CA instance.
104 * @param slot Slot concerned.
105 */
106void dvb_ca_en50221_frda_irq(struct dvb_ca_en50221* ca, int slot);
107
108
109
110/* ******************************************************************************** */
111/* Initialisation/shutdown functions */
112
113/**
114 * Initialise a new DVB CA device.
115 *
116 * @param dvb_adapter DVB adapter to attach the new CA device to.
117 * @param ca The dvb_ca instance.
118 * @param flags Flags describing the CA device (DVB_CA_EN50221_FLAG_*).
119 * @param slot_count Number of slots supported.
120 *
121 * @return 0 on success, nonzero on failure
122 */
123extern int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter, struct dvb_ca_en50221* ca, int flags, int slot_count);
124
125/**
126 * Release a DVB CA device.
127 *
128 * @param ca The associated dvb_ca instance.
129 */
130extern void dvb_ca_en50221_release(struct dvb_ca_en50221* ca);
131
132
133
134#endif
diff --git a/drivers/media/dvb/dvb-core/dvb_demux.c b/drivers/media/dvb/dvb-core/dvb_demux.c
new file mode 100644
index 000000000000..ac9889d22288
--- /dev/null
+++ b/drivers/media/dvb/dvb-core/dvb_demux.c
@@ -0,0 +1,1294 @@
1/*
2 * dvb_demux.c - DVB kernel demux API
3 *
4 * Copyright (C) 2000-2001 Ralph Metzler <ralph@convergence.de>
5 * & Marcus Metzler <marcus@convergence.de>
6 * for convergence integrated media GmbH
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 *
22 */
23
24#include <linux/spinlock.h>
25#include <linux/slab.h>
26#include <linux/vmalloc.h>
27#include <linux/module.h>
28#include <linux/poll.h>
29#include <linux/string.h>
30#include <linux/crc32.h>
31#include <asm/uaccess.h>
32
33#include "dvb_demux.h"
34
35#define NOBUFS
36/*
37** #define DVB_DEMUX_SECTION_LOSS_LOG to monitor payload loss in the syslog
38*/
39// #define DVB_DEMUX_SECTION_LOSS_LOG
40
41
42static LIST_HEAD(dmx_muxs);
43
44
45static int dmx_register_demux(struct dmx_demux *demux)
46{
47 demux->users = 0;
48 list_add(&demux->reg_list, &dmx_muxs);
49 return 0;
50}
51
52static int dmx_unregister_demux(struct dmx_demux* demux)
53{
54 struct list_head *pos, *n, *head=&dmx_muxs;
55
56 list_for_each_safe (pos, n, head) {
57 if (DMX_DIR_ENTRY(pos) == demux) {
58 if (demux->users>0)
59 return -EINVAL;
60 list_del(pos);
61 return 0;
62 }
63 }
64
65 return -ENODEV;
66}
67
68
69/******************************************************************************
70 * static inlined helper functions
71 ******************************************************************************/
72
73
74static inline u16 section_length(const u8 *buf)
75{
76 return 3+((buf[1]&0x0f)<<8)+buf[2];
77}
78
79
80static inline u16 ts_pid(const u8 *buf)
81{
82 return ((buf[1]&0x1f)<<8)+buf[2];
83}
84
85
86static inline u8 payload(const u8 *tsp)
87{
88 if (!(tsp[3] & 0x10)) // no payload?
89 return 0;
90 if (tsp[3] & 0x20) { // adaptation field?
91 if (tsp[4] > 183) // corrupted data?
92 return 0;
93 else
94 return 184-1-tsp[4];
95 }
96 return 184;
97}
98
99
100static u32 dvb_dmx_crc32 (struct dvb_demux_feed *f, const u8 *src, size_t len)
101{
102 return (f->feed.sec.crc_val = crc32_be (f->feed.sec.crc_val, src, len));
103}
104
105
106static void dvb_dmx_memcopy (struct dvb_demux_feed *f, u8 *d, const u8 *s, size_t len)
107{
108 memcpy (d, s, len);
109}
110
111
112/******************************************************************************
113 * Software filter functions
114 ******************************************************************************/
115
116static inline int dvb_dmx_swfilter_payload (struct dvb_demux_feed *feed, const u8 *buf)
117{
118 int count = payload(buf);
119 int p;
120 //int ccok;
121 //u8 cc;
122
123 if (count == 0)
124 return -1;
125
126 p = 188-count;
127
128 /*
129 cc=buf[3]&0x0f;
130 ccok=((dvbdmxfeed->cc+1)&0x0f)==cc ? 1 : 0;
131 dvbdmxfeed->cc=cc;
132 if (!ccok)
133 printk("missed packet!\n");
134 */
135
136 if (buf[1] & 0x40) // PUSI ?
137 feed->peslen = 0xfffa;
138
139 feed->peslen += count;
140
141 return feed->cb.ts (&buf[p], count, NULL, 0, &feed->feed.ts, DMX_OK);
142}
143
144
145static int dvb_dmx_swfilter_sectionfilter (struct dvb_demux_feed *feed,
146 struct dvb_demux_filter *f)
147{
148 u8 neq = 0;
149 int i;
150
151 for (i=0; i<DVB_DEMUX_MASK_MAX; i++) {
152 u8 xor = f->filter.filter_value[i] ^ feed->feed.sec.secbuf[i];
153
154 if (f->maskandmode[i] & xor)
155 return 0;
156
157 neq |= f->maskandnotmode[i] & xor;
158 }
159
160 if (f->doneq && !neq)
161 return 0;
162
163 return feed->cb.sec (feed->feed.sec.secbuf, feed->feed.sec.seclen,
164 NULL, 0, &f->filter, DMX_OK);
165}
166
167
168static inline int dvb_dmx_swfilter_section_feed (struct dvb_demux_feed *feed)
169{
170 struct dvb_demux *demux = feed->demux;
171 struct dvb_demux_filter *f = feed->filter;
172 struct dmx_section_feed *sec = &feed->feed.sec;
173 int section_syntax_indicator;
174
175 if (!sec->is_filtering)
176 return 0;
177
178 if (!f)
179 return 0;
180
181 if (sec->check_crc) {
182 section_syntax_indicator = ((sec->secbuf[1] & 0x80) != 0);
183 if (section_syntax_indicator &&
184 demux->check_crc32(feed, sec->secbuf, sec->seclen))
185 return -1;
186 }
187
188 do {
189 if (dvb_dmx_swfilter_sectionfilter(feed, f) < 0)
190 return -1;
191 } while ((f = f->next) && sec->is_filtering);
192
193 sec->seclen = 0;
194
195 return 0;
196}
197
198
199static void dvb_dmx_swfilter_section_new(struct dvb_demux_feed *feed)
200{
201 struct dmx_section_feed *sec = &feed->feed.sec;
202
203#ifdef DVB_DEMUX_SECTION_LOSS_LOG
204 if(sec->secbufp < sec->tsfeedp)
205 {
206 int i, n = sec->tsfeedp - sec->secbufp;
207
208 /* section padding is done with 0xff bytes entirely.
209 ** due to speed reasons, we won't check all of them
210 ** but just first and last
211 */
212 if(sec->secbuf[0] != 0xff || sec->secbuf[n-1] != 0xff)
213 {
214 printk("dvb_demux.c section ts padding loss: %d/%d\n",
215 n, sec->tsfeedp);
216 printk("dvb_demux.c pad data:");
217 for(i = 0; i < n; i++)
218 printk(" %02x", sec->secbuf[i]);
219 printk("\n");
220 }
221 }
222#endif
223
224 sec->tsfeedp = sec->secbufp = sec->seclen = 0;
225 sec->secbuf = sec->secbuf_base;
226}
227
228/*
229** Losless Section Demux 1.4.1 by Emard
230** Valsecchi Patrick:
231** - middle of section A (no PUSI)
232** - end of section A and start of section B
233** (with PUSI pointing to the start of the second section)
234**
235** In this case, without feed->pusi_seen you'll receive a garbage section
236** consisting of the end of section A. Basically because tsfeedp
237** is incemented and the use=0 condition is not raised
238** when the second packet arrives.
239**
240** Fix:
241** when demux is started, let feed->pusi_seen = 0 to
242** prevent initial feeding of garbage from the end of
243** previous section. When you for the first time see PUSI=1
244** then set feed->pusi_seen = 1
245*/
246static int dvb_dmx_swfilter_section_copy_dump(struct dvb_demux_feed *feed, const u8 *buf, u8 len)
247{
248 struct dvb_demux *demux = feed->demux;
249 struct dmx_section_feed *sec = &feed->feed.sec;
250 u16 limit, seclen, n;
251
252 if(sec->tsfeedp >= DMX_MAX_SECFEED_SIZE)
253 return 0;
254
255 if(sec->tsfeedp + len > DMX_MAX_SECFEED_SIZE)
256 {
257#ifdef DVB_DEMUX_SECTION_LOSS_LOG
258 printk("dvb_demux.c section buffer full loss: %d/%d\n",
259 sec->tsfeedp + len - DMX_MAX_SECFEED_SIZE, DMX_MAX_SECFEED_SIZE);
260#endif
261 len = DMX_MAX_SECFEED_SIZE - sec->tsfeedp;
262 }
263
264 if(len <= 0)
265 return 0;
266
267 demux->memcopy(feed, sec->secbuf_base + sec->tsfeedp, buf, len);
268 sec->tsfeedp += len;
269
270 /* -----------------------------------------------------
271 ** Dump all the sections we can find in the data (Emard)
272 */
273
274 limit = sec->tsfeedp;
275 if(limit > DMX_MAX_SECFEED_SIZE)
276 return -1; /* internal error should never happen */
277
278 /* to be sure always set secbuf */
279 sec->secbuf = sec->secbuf_base + sec->secbufp;
280
281 for(n = 0; sec->secbufp + 2 < limit; n++)
282 {
283 seclen = section_length(sec->secbuf);
284 if(seclen <= 0 || seclen > DMX_MAX_SECFEED_SIZE
285 || seclen + sec->secbufp > limit)
286 return 0;
287 sec->seclen = seclen;
288 sec->crc_val = ~0;
289 /* dump [secbuf .. secbuf+seclen) */
290 if(feed->pusi_seen)
291 dvb_dmx_swfilter_section_feed(feed);
292#ifdef DVB_DEMUX_SECTION_LOSS_LOG
293 else
294 printk("dvb_demux.c pusi not seen, discarding section data\n");
295#endif
296 sec->secbufp += seclen; /* secbufp and secbuf moving together is */
297 sec->secbuf += seclen; /* redundand but saves pointer arithmetic */
298 }
299
300 return 0;
301}
302
303
304static int dvb_dmx_swfilter_section_packet(struct dvb_demux_feed *feed, const u8 *buf)
305{
306 u8 p, count;
307 int ccok, dc_i = 0;
308 u8 cc;
309
310 count = payload(buf);
311
312 if (count == 0) /* count == 0 if no payload or out of range */
313 return -1;
314
315 p = 188 - count; /* payload start */
316
317 cc = buf[3] & 0x0f;
318 ccok = ((feed->cc + 1) & 0x0f) == cc;
319 feed->cc = cc;
320
321 if (buf[3] & 0x20) {
322 /* adaption field present, check for discontinuity_indicator */
323 if ((buf[4] > 0) && (buf[5] & 0x80))
324 dc_i = 1;
325 }
326
327 if (!ccok || dc_i) {
328#ifdef DVB_DEMUX_SECTION_LOSS_LOG
329 printk("dvb_demux.c discontinuity detected %d bytes lost\n", count);
330 /* those bytes under sume circumstances will again be reported
331 ** in the following dvb_dmx_swfilter_section_new
332 */
333#endif
334 /* Discontinuity detected. Reset pusi_seen = 0 to
335 ** stop feeding of suspicious data until next PUSI=1 arrives
336 */
337 feed->pusi_seen = 0;
338 dvb_dmx_swfilter_section_new(feed);
339 return 0;
340 }
341
342 if (buf[1] & 0x40) {
343 // PUSI=1 (is set), section boundary is here
344 if (count > 1 && buf[p] < count) {
345 const u8 *before = buf+p+1;
346 u8 before_len = buf[p];
347 const u8 *after = before+before_len;
348 u8 after_len = count-1-before_len;
349
350 dvb_dmx_swfilter_section_copy_dump(feed, before, before_len);
351 /* before start of new section, set pusi_seen = 1 */
352 feed->pusi_seen = 1;
353 dvb_dmx_swfilter_section_new(feed);
354 dvb_dmx_swfilter_section_copy_dump(feed, after, after_len);
355 }
356#ifdef DVB_DEMUX_SECTION_LOSS_LOG
357 else
358 if (count > 0)
359 printk("dvb_demux.c PUSI=1 but %d bytes lost\n", count);
360#endif
361 } else {
362 // PUSI=0 (is not set), no section boundary
363 const u8 *entire = buf+p;
364 u8 entire_len = count;
365
366 dvb_dmx_swfilter_section_copy_dump(feed, entire, entire_len);
367 }
368 return 0;
369}
370
371
372static inline void dvb_dmx_swfilter_packet_type(struct dvb_demux_feed *feed, const u8 *buf)
373{
374 switch(feed->type) {
375 case DMX_TYPE_TS:
376 if (!feed->feed.ts.is_filtering)
377 break;
378 if (feed->ts_type & TS_PACKET) {
379 if (feed->ts_type & TS_PAYLOAD_ONLY)
380 dvb_dmx_swfilter_payload(feed, buf);
381 else
382 feed->cb.ts(buf, 188, NULL, 0, &feed->feed.ts, DMX_OK);
383 }
384 if (feed->ts_type & TS_DECODER)
385 if (feed->demux->write_to_decoder)
386 feed->demux->write_to_decoder(feed, buf, 188);
387 break;
388
389 case DMX_TYPE_SEC:
390 if (!feed->feed.sec.is_filtering)
391 break;
392 if (dvb_dmx_swfilter_section_packet(feed, buf) < 0)
393 feed->feed.sec.seclen = feed->feed.sec.secbufp=0;
394 break;
395
396 default:
397 break;
398 }
399}
400
401#define DVR_FEED(f) \
402 (((f)->type == DMX_TYPE_TS) && \
403 ((f)->feed.ts.is_filtering) && \
404 (((f)->ts_type & (TS_PACKET|TS_PAYLOAD_ONLY)) == TS_PACKET))
405
406static void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf)
407{
408 struct dvb_demux_feed *feed;
409 struct list_head *pos, *head=&demux->feed_list;
410 u16 pid = ts_pid(buf);
411 int dvr_done = 0;
412
413 list_for_each(pos, head) {
414 feed = list_entry(pos, struct dvb_demux_feed, list_head);
415
416 if ((feed->pid != pid) && (feed->pid != 0x2000))
417 continue;
418
419 /* copy each packet only once to the dvr device, even
420 * if a PID is in multiple filters (e.g. video + PCR) */
421 if ((DVR_FEED(feed)) && (dvr_done++))
422 continue;
423
424 if (feed->pid == pid) {
425 dvb_dmx_swfilter_packet_type(feed, buf);
426 if (DVR_FEED(feed))
427 continue;
428 }
429
430 if (feed->pid == 0x2000)
431 feed->cb.ts(buf, 188, NULL, 0, &feed->feed.ts, DMX_OK);
432 }
433}
434
435void dvb_dmx_swfilter_packets(struct dvb_demux *demux, const u8 *buf, size_t count)
436{
437 spin_lock(&demux->lock);
438
439 while (count--) {
440 if(buf[0] == 0x47) {
441 dvb_dmx_swfilter_packet(demux, buf);
442 }
443 buf += 188;
444 }
445
446 spin_unlock(&demux->lock);
447}
448EXPORT_SYMBOL(dvb_dmx_swfilter_packets);
449
450
451void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count)
452{
453 int p = 0, i, j;
454
455 spin_lock(&demux->lock);
456
457 if ((i = demux->tsbufp)) {
458 if (count < (j=188-i)) {
459 memcpy(&demux->tsbuf[i], buf, count);
460 demux->tsbufp += count;
461 goto bailout;
462 }
463 memcpy(&demux->tsbuf[i], buf, j);
464 if (demux->tsbuf[0] == 0x47)
465 dvb_dmx_swfilter_packet(demux, demux->tsbuf);
466 demux->tsbufp = 0;
467 p += j;
468 }
469
470 while (p < count) {
471 if (buf[p] == 0x47) {
472 if (count-p >= 188) {
473 dvb_dmx_swfilter_packet(demux, buf+p);
474 p += 188;
475 } else {
476 i = count-p;
477 memcpy(demux->tsbuf, buf+p, i);
478 demux->tsbufp=i;
479 goto bailout;
480 }
481 } else
482 p++;
483 }
484
485bailout:
486 spin_unlock(&demux->lock);
487}
488EXPORT_SYMBOL(dvb_dmx_swfilter);
489
490void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf, size_t count)
491{
492 int p = 0,i, j;
493 u8 tmppack[188];
494 spin_lock(&demux->lock);
495
496 if ((i = demux->tsbufp)) {
497 if (count < (j=204-i)) {
498 memcpy(&demux->tsbuf[i], buf, count);
499 demux->tsbufp += count;
500 goto bailout;
501 }
502 memcpy(&demux->tsbuf[i], buf, j);
503 if ((demux->tsbuf[0] == 0x47)|(demux->tsbuf[0]==0xB8)) {
504 memcpy(tmppack, demux->tsbuf, 188);
505 if (tmppack[0] == 0xB8) tmppack[0] = 0x47;
506 dvb_dmx_swfilter_packet(demux, tmppack);
507 }
508 demux->tsbufp = 0;
509 p += j;
510 }
511
512 while (p < count) {
513 if ((buf[p] == 0x47)|(buf[p] == 0xB8)) {
514 if (count-p >= 204) {
515 memcpy(tmppack, buf+p, 188);
516 if (tmppack[0] == 0xB8) tmppack[0] = 0x47;
517 dvb_dmx_swfilter_packet(demux, tmppack);
518 p += 204;
519 } else {
520 i = count-p;
521 memcpy(demux->tsbuf, buf+p, i);
522 demux->tsbufp=i;
523 goto bailout;
524 }
525 } else {
526 p++;
527 }
528 }
529
530bailout:
531 spin_unlock(&demux->lock);
532}
533EXPORT_SYMBOL(dvb_dmx_swfilter_204);
534
535
536static struct dvb_demux_filter * dvb_dmx_filter_alloc(struct dvb_demux *demux)
537{
538 int i;
539
540 for (i=0; i<demux->filternum; i++)
541 if (demux->filter[i].state == DMX_STATE_FREE)
542 break;
543
544 if (i == demux->filternum)
545 return NULL;
546
547 demux->filter[i].state = DMX_STATE_ALLOCATED;
548
549 return &demux->filter[i];
550}
551
552static struct dvb_demux_feed * dvb_dmx_feed_alloc(struct dvb_demux *demux)
553{
554 int i;
555
556 for (i=0; i<demux->feednum; i++)
557 if (demux->feed[i].state == DMX_STATE_FREE)
558 break;
559
560 if (i == demux->feednum)
561 return NULL;
562
563 demux->feed[i].state = DMX_STATE_ALLOCATED;
564
565 return &demux->feed[i];
566}
567
568static int dvb_demux_feed_find(struct dvb_demux_feed *feed)
569{
570 struct dvb_demux_feed *entry;
571
572 list_for_each_entry(entry, &feed->demux->feed_list, list_head)
573 if (entry == feed)
574 return 1;
575
576 return 0;
577}
578
579static void dvb_demux_feed_add(struct dvb_demux_feed *feed)
580{
581 spin_lock_irq(&feed->demux->lock);
582 if (dvb_demux_feed_find(feed)) {
583 printk(KERN_ERR "%s: feed already in list (type=%x state=%x pid=%x)\n",
584 __FUNCTION__, feed->type, feed->state, feed->pid);
585 goto out;
586 }
587
588 list_add(&feed->list_head, &feed->demux->feed_list);
589out:
590 spin_unlock_irq(&feed->demux->lock);
591}
592
593static void dvb_demux_feed_del(struct dvb_demux_feed *feed)
594{
595 spin_lock_irq(&feed->demux->lock);
596 if (!(dvb_demux_feed_find(feed))) {
597 printk(KERN_ERR "%s: feed not in list (type=%x state=%x pid=%x)\n",
598 __FUNCTION__, feed->type, feed->state, feed->pid);
599 goto out;
600 }
601
602 list_del(&feed->list_head);
603out:
604 spin_unlock_irq(&feed->demux->lock);
605}
606
607static int dmx_ts_feed_set (struct dmx_ts_feed* ts_feed, u16 pid, int ts_type,
608 enum dmx_ts_pes pes_type, size_t callback_length,
609 size_t circular_buffer_size, int descramble,
610 struct timespec timeout)
611{
612 struct dvb_demux_feed *feed = (struct dvb_demux_feed *) ts_feed;
613 struct dvb_demux *demux = feed->demux;
614
615 if (pid > DMX_MAX_PID)
616 return -EINVAL;
617
618 if (down_interruptible (&demux->mutex))
619 return -ERESTARTSYS;
620
621 if (ts_type & TS_DECODER) {
622 if (pes_type >= DMX_TS_PES_OTHER) {
623 up(&demux->mutex);
624 return -EINVAL;
625 }
626
627 if (demux->pesfilter[pes_type] &&
628 demux->pesfilter[pes_type] != feed) {
629 up(&demux->mutex);
630 return -EINVAL;
631 }
632
633 demux->pesfilter[pes_type] = feed;
634 demux->pids[pes_type] = pid;
635 }
636
637 dvb_demux_feed_add(feed);
638
639 feed->pid = pid;
640 feed->buffer_size = circular_buffer_size;
641 feed->descramble = descramble;
642 feed->timeout = timeout;
643 feed->cb_length = callback_length;
644 feed->ts_type = ts_type;
645 feed->pes_type = pes_type;
646
647 if (feed->descramble) {
648 up(&demux->mutex);
649 return -ENOSYS;
650 }
651
652 if (feed->buffer_size) {
653#ifdef NOBUFS
654 feed->buffer=NULL;
655#else
656 feed->buffer = vmalloc(feed->buffer_size);
657 if (!feed->buffer) {
658 up(&demux->mutex);
659 return -ENOMEM;
660 }
661#endif
662 }
663
664 feed->state = DMX_STATE_READY;
665 up(&demux->mutex);
666
667 return 0;
668}
669
670
671static int dmx_ts_feed_start_filtering(struct dmx_ts_feed* ts_feed)
672{
673 struct dvb_demux_feed *feed = (struct dvb_demux_feed *) ts_feed;
674 struct dvb_demux *demux = feed->demux;
675 int ret;
676
677 if (down_interruptible (&demux->mutex))
678 return -ERESTARTSYS;
679
680 if (feed->state != DMX_STATE_READY || feed->type != DMX_TYPE_TS) {
681 up(&demux->mutex);
682 return -EINVAL;
683 }
684
685 if (!demux->start_feed) {
686 up(&demux->mutex);
687 return -ENODEV;
688 }
689
690 if ((ret = demux->start_feed(feed)) < 0) {
691 up(&demux->mutex);
692 return ret;
693 }
694
695 spin_lock_irq(&demux->lock);
696 ts_feed->is_filtering = 1;
697 feed->state = DMX_STATE_GO;
698 spin_unlock_irq(&demux->lock);
699 up(&demux->mutex);
700
701 return 0;
702}
703
704static int dmx_ts_feed_stop_filtering(struct dmx_ts_feed* ts_feed)
705{
706 struct dvb_demux_feed *feed = (struct dvb_demux_feed *) ts_feed;
707 struct dvb_demux *demux = feed->demux;
708 int ret;
709
710 if (down_interruptible (&demux->mutex))
711 return -ERESTARTSYS;
712
713 if (feed->state < DMX_STATE_GO) {
714 up(&demux->mutex);
715 return -EINVAL;
716 }
717
718 if (!demux->stop_feed) {
719 up(&demux->mutex);
720 return -ENODEV;
721 }
722
723 ret = demux->stop_feed(feed);
724
725 spin_lock_irq(&demux->lock);
726 ts_feed->is_filtering = 0;
727 feed->state = DMX_STATE_ALLOCATED;
728 spin_unlock_irq(&demux->lock);
729 up(&demux->mutex);
730
731 return ret;
732}
733
734static int dvbdmx_allocate_ts_feed (struct dmx_demux *dmx, struct dmx_ts_feed **ts_feed,
735 dmx_ts_cb callback)
736{
737 struct dvb_demux *demux = (struct dvb_demux *) dmx;
738 struct dvb_demux_feed *feed;
739
740 if (down_interruptible (&demux->mutex))
741 return -ERESTARTSYS;
742
743 if (!(feed = dvb_dmx_feed_alloc(demux))) {
744 up(&demux->mutex);
745 return -EBUSY;
746 }
747
748 feed->type = DMX_TYPE_TS;
749 feed->cb.ts = callback;
750 feed->demux = demux;
751 feed->pid = 0xffff;
752 feed->peslen = 0xfffa;
753 feed->buffer = NULL;
754
755 (*ts_feed) = &feed->feed.ts;
756 (*ts_feed)->parent = dmx;
757 (*ts_feed)->priv = NULL;
758 (*ts_feed)->is_filtering = 0;
759 (*ts_feed)->start_filtering = dmx_ts_feed_start_filtering;
760 (*ts_feed)->stop_filtering = dmx_ts_feed_stop_filtering;
761 (*ts_feed)->set = dmx_ts_feed_set;
762
763
764 if (!(feed->filter = dvb_dmx_filter_alloc(demux))) {
765 feed->state = DMX_STATE_FREE;
766 up(&demux->mutex);
767 return -EBUSY;
768 }
769
770 feed->filter->type = DMX_TYPE_TS;
771 feed->filter->feed = feed;
772 feed->filter->state = DMX_STATE_READY;
773
774 up(&demux->mutex);
775
776 return 0;
777}
778
779static int dvbdmx_release_ts_feed(struct dmx_demux *dmx, struct dmx_ts_feed *ts_feed)
780{
781 struct dvb_demux *demux = (struct dvb_demux *) dmx;
782 struct dvb_demux_feed *feed = (struct dvb_demux_feed *) ts_feed;
783
784 if (down_interruptible (&demux->mutex))
785 return -ERESTARTSYS;
786
787 if (feed->state == DMX_STATE_FREE) {
788 up(&demux->mutex);
789 return -EINVAL;
790 }
791
792#ifndef NOBUFS
793 vfree(feed->buffer);
794 feed->buffer=0;
795#endif
796
797 feed->state = DMX_STATE_FREE;
798 feed->filter->state = DMX_STATE_FREE;
799
800 dvb_demux_feed_del(feed);
801
802 feed->pid = 0xffff;
803
804 if (feed->ts_type & TS_DECODER && feed->pes_type < DMX_TS_PES_OTHER)
805 demux->pesfilter[feed->pes_type] = NULL;
806
807 up(&demux->mutex);
808 return 0;
809}
810
811
812/******************************************************************************
813 * dmx_section_feed API calls
814 ******************************************************************************/
815
816static int dmx_section_feed_allocate_filter(struct dmx_section_feed* feed,
817 struct dmx_section_filter** filter)
818{
819 struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *) feed;
820 struct dvb_demux *dvbdemux = dvbdmxfeed->demux;
821 struct dvb_demux_filter *dvbdmxfilter;
822
823 if (down_interruptible (&dvbdemux->mutex))
824 return -ERESTARTSYS;
825
826 dvbdmxfilter = dvb_dmx_filter_alloc(dvbdemux);
827 if (!dvbdmxfilter) {
828 up(&dvbdemux->mutex);
829 return -EBUSY;
830 }
831
832 spin_lock_irq(&dvbdemux->lock);
833 *filter = &dvbdmxfilter->filter;
834 (*filter)->parent = feed;
835 (*filter)->priv = NULL;
836 dvbdmxfilter->feed = dvbdmxfeed;
837 dvbdmxfilter->type = DMX_TYPE_SEC;
838 dvbdmxfilter->state = DMX_STATE_READY;
839 dvbdmxfilter->next = dvbdmxfeed->filter;
840 dvbdmxfeed->filter = dvbdmxfilter;
841 spin_unlock_irq(&dvbdemux->lock);
842
843 up(&dvbdemux->mutex);
844 return 0;
845}
846
847
848static int dmx_section_feed_set(struct dmx_section_feed* feed,
849 u16 pid, size_t circular_buffer_size,
850 int descramble, int check_crc)
851{
852 struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *) feed;
853 struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
854
855 if (pid > 0x1fff)
856 return -EINVAL;
857
858 if (down_interruptible (&dvbdmx->mutex))
859 return -ERESTARTSYS;
860
861 dvb_demux_feed_add(dvbdmxfeed);
862
863 dvbdmxfeed->pid = pid;
864 dvbdmxfeed->buffer_size = circular_buffer_size;
865 dvbdmxfeed->descramble = descramble;
866 if (dvbdmxfeed->descramble) {
867 up(&dvbdmx->mutex);
868 return -ENOSYS;
869 }
870
871 dvbdmxfeed->feed.sec.check_crc = check_crc;
872
873#ifdef NOBUFS
874 dvbdmxfeed->buffer = NULL;
875#else
876 dvbdmxfeed->buffer=vmalloc(dvbdmxfeed->buffer_size);
877 if (!dvbdmxfeed->buffer) {
878 up(&dvbdmx->mutex);
879 return -ENOMEM;
880 }
881#endif
882
883 dvbdmxfeed->state = DMX_STATE_READY;
884 up(&dvbdmx->mutex);
885 return 0;
886}
887
888
889static void prepare_secfilters(struct dvb_demux_feed *dvbdmxfeed)
890{
891 int i;
892 struct dvb_demux_filter *f;
893 struct dmx_section_filter *sf;
894 u8 mask, mode, doneq;
895
896 if (!(f=dvbdmxfeed->filter))
897 return;
898 do {
899 sf = &f->filter;
900 doneq = 0;
901 for (i=0; i<DVB_DEMUX_MASK_MAX; i++) {
902 mode = sf->filter_mode[i];
903 mask = sf->filter_mask[i];
904 f->maskandmode[i] = mask & mode;
905 doneq |= f->maskandnotmode[i] = mask & ~mode;
906 }
907 f->doneq = doneq ? 1 : 0;
908 } while ((f = f->next));
909}
910
911
912static int dmx_section_feed_start_filtering(struct dmx_section_feed *feed)
913{
914 struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *) feed;
915 struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
916 int ret;
917
918 if (down_interruptible (&dvbdmx->mutex))
919 return -ERESTARTSYS;
920
921 if (feed->is_filtering) {
922 up(&dvbdmx->mutex);
923 return -EBUSY;
924 }
925
926 if (!dvbdmxfeed->filter) {
927 up(&dvbdmx->mutex);
928 return -EINVAL;
929 }
930
931 dvbdmxfeed->feed.sec.tsfeedp = 0;
932 dvbdmxfeed->feed.sec.secbuf = dvbdmxfeed->feed.sec.secbuf_base;
933 dvbdmxfeed->feed.sec.secbufp = 0;
934 dvbdmxfeed->feed.sec.seclen = 0;
935
936 if (!dvbdmx->start_feed) {
937 up(&dvbdmx->mutex);
938 return -ENODEV;
939 }
940
941 prepare_secfilters(dvbdmxfeed);
942
943 if ((ret = dvbdmx->start_feed(dvbdmxfeed)) < 0) {
944 up(&dvbdmx->mutex);
945 return ret;
946 }
947
948 spin_lock_irq(&dvbdmx->lock);
949 feed->is_filtering = 1;
950 dvbdmxfeed->state = DMX_STATE_GO;
951 spin_unlock_irq(&dvbdmx->lock);
952
953 up(&dvbdmx->mutex);
954 return 0;
955}
956
957
958static int dmx_section_feed_stop_filtering(struct dmx_section_feed* feed)
959{
960 struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *) feed;
961 struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
962 int ret;
963
964 if (down_interruptible (&dvbdmx->mutex))
965 return -ERESTARTSYS;
966
967 if (!dvbdmx->stop_feed) {
968 up(&dvbdmx->mutex);
969 return -ENODEV;
970 }
971
972 ret = dvbdmx->stop_feed(dvbdmxfeed);
973
974 spin_lock_irq(&dvbdmx->lock);
975 dvbdmxfeed->state = DMX_STATE_READY;
976 feed->is_filtering = 0;
977 spin_unlock_irq(&dvbdmx->lock);
978
979 up(&dvbdmx->mutex);
980 return ret;
981}
982
983
984static int dmx_section_feed_release_filter(struct dmx_section_feed *feed,
985 struct dmx_section_filter* filter)
986{
987 struct dvb_demux_filter *dvbdmxfilter = (struct dvb_demux_filter *) filter, *f;
988 struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *) feed;
989 struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
990
991 if (down_interruptible (&dvbdmx->mutex))
992 return -ERESTARTSYS;
993
994 if (dvbdmxfilter->feed != dvbdmxfeed) {
995 up(&dvbdmx->mutex);
996 return -EINVAL;
997 }
998
999 if (feed->is_filtering)
1000 feed->stop_filtering(feed);
1001
1002 spin_lock_irq(&dvbdmx->lock);
1003 f = dvbdmxfeed->filter;
1004
1005 if (f == dvbdmxfilter) {
1006 dvbdmxfeed->filter = dvbdmxfilter->next;
1007 } else {
1008 while(f->next != dvbdmxfilter)
1009 f = f->next;
1010 f->next = f->next->next;
1011 }
1012
1013 dvbdmxfilter->state = DMX_STATE_FREE;
1014 spin_unlock_irq(&dvbdmx->lock);
1015 up(&dvbdmx->mutex);
1016 return 0;
1017}
1018
1019static int dvbdmx_allocate_section_feed(struct dmx_demux *demux,
1020 struct dmx_section_feed **feed,
1021 dmx_section_cb callback)
1022{
1023 struct dvb_demux *dvbdmx = (struct dvb_demux *) demux;
1024 struct dvb_demux_feed *dvbdmxfeed;
1025
1026 if (down_interruptible (&dvbdmx->mutex))
1027 return -ERESTARTSYS;
1028
1029 if (!(dvbdmxfeed = dvb_dmx_feed_alloc(dvbdmx))) {
1030 up(&dvbdmx->mutex);
1031 return -EBUSY;
1032 }
1033
1034 dvbdmxfeed->type = DMX_TYPE_SEC;
1035 dvbdmxfeed->cb.sec = callback;
1036 dvbdmxfeed->demux = dvbdmx;
1037 dvbdmxfeed->pid = 0xffff;
1038 dvbdmxfeed->feed.sec.secbuf = dvbdmxfeed->feed.sec.secbuf_base;
1039 dvbdmxfeed->feed.sec.secbufp = dvbdmxfeed->feed.sec.seclen = 0;
1040 dvbdmxfeed->feed.sec.tsfeedp = 0;
1041 dvbdmxfeed->filter = NULL;
1042 dvbdmxfeed->buffer = NULL;
1043
1044 (*feed)=&dvbdmxfeed->feed.sec;
1045 (*feed)->is_filtering = 0;
1046 (*feed)->parent = demux;
1047 (*feed)->priv = NULL;
1048
1049 (*feed)->set = dmx_section_feed_set;
1050 (*feed)->allocate_filter = dmx_section_feed_allocate_filter;
1051 (*feed)->start_filtering = dmx_section_feed_start_filtering;
1052 (*feed)->stop_filtering = dmx_section_feed_stop_filtering;
1053 (*feed)->release_filter = dmx_section_feed_release_filter;
1054
1055 up(&dvbdmx->mutex);
1056 return 0;
1057}
1058
1059static int dvbdmx_release_section_feed(struct dmx_demux *demux,
1060 struct dmx_section_feed *feed)
1061{
1062 struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *) feed;
1063 struct dvb_demux *dvbdmx = (struct dvb_demux *) demux;
1064
1065 if (down_interruptible (&dvbdmx->mutex))
1066 return -ERESTARTSYS;
1067
1068 if (dvbdmxfeed->state==DMX_STATE_FREE) {
1069 up(&dvbdmx->mutex);
1070 return -EINVAL;
1071 }
1072#ifndef NOBUFS
1073 vfree(dvbdmxfeed->buffer);
1074 dvbdmxfeed->buffer=0;
1075#endif
1076 dvbdmxfeed->state=DMX_STATE_FREE;
1077
1078 dvb_demux_feed_del(dvbdmxfeed);
1079
1080 dvbdmxfeed->pid = 0xffff;
1081
1082 up(&dvbdmx->mutex);
1083 return 0;
1084}
1085
1086
1087/******************************************************************************
1088 * dvb_demux kernel data API calls
1089 ******************************************************************************/
1090
1091static int dvbdmx_open(struct dmx_demux *demux)
1092{
1093 struct dvb_demux *dvbdemux = (struct dvb_demux *) demux;
1094
1095 if (dvbdemux->users >= MAX_DVB_DEMUX_USERS)
1096 return -EUSERS;
1097
1098 dvbdemux->users++;
1099 return 0;
1100}
1101
1102
1103static int dvbdmx_close(struct dmx_demux *demux)
1104{
1105 struct dvb_demux *dvbdemux = (struct dvb_demux *) demux;
1106
1107 if (dvbdemux->users == 0)
1108 return -ENODEV;
1109
1110 dvbdemux->users--;
1111 //FIXME: release any unneeded resources if users==0
1112 return 0;
1113}
1114
1115
1116static int dvbdmx_write(struct dmx_demux *demux, const char *buf, size_t count)
1117{
1118 struct dvb_demux *dvbdemux=(struct dvb_demux *) demux;
1119
1120 if ((!demux->frontend) || (demux->frontend->source != DMX_MEMORY_FE))
1121 return -EINVAL;
1122
1123 if (down_interruptible (&dvbdemux->mutex))
1124 return -ERESTARTSYS;
1125 dvb_dmx_swfilter(dvbdemux, buf, count);
1126 up(&dvbdemux->mutex);
1127
1128 if (signal_pending(current))
1129 return -EINTR;
1130 return count;
1131}
1132
1133
1134static int dvbdmx_add_frontend(struct dmx_demux *demux, struct dmx_frontend *frontend)
1135{
1136 struct dvb_demux *dvbdemux = (struct dvb_demux *) demux;
1137 struct list_head *head = &dvbdemux->frontend_list;
1138
1139 list_add(&(frontend->connectivity_list), head);
1140
1141 return 0;
1142}
1143
1144
1145static int dvbdmx_remove_frontend(struct dmx_demux *demux, struct dmx_frontend *frontend)
1146{
1147 struct dvb_demux *dvbdemux = (struct dvb_demux *) demux;
1148 struct list_head *pos, *n, *head = &dvbdemux->frontend_list;
1149
1150 list_for_each_safe (pos, n, head) {
1151 if (DMX_FE_ENTRY(pos) == frontend) {
1152 list_del(pos);
1153 return 0;
1154 }
1155 }
1156
1157 return -ENODEV;
1158}
1159
1160
1161static struct list_head * dvbdmx_get_frontends(struct dmx_demux *demux)
1162{
1163 struct dvb_demux *dvbdemux = (struct dvb_demux *) demux;
1164
1165 if (list_empty(&dvbdemux->frontend_list))
1166 return NULL;
1167 return &dvbdemux->frontend_list;
1168}
1169
1170
1171static int dvbdmx_connect_frontend(struct dmx_demux *demux, struct dmx_frontend *frontend)
1172{
1173 struct dvb_demux *dvbdemux = (struct dvb_demux *) demux;
1174
1175 if (demux->frontend)
1176 return -EINVAL;
1177
1178 if (down_interruptible (&dvbdemux->mutex))
1179 return -ERESTARTSYS;
1180
1181 demux->frontend = frontend;
1182 up(&dvbdemux->mutex);
1183 return 0;
1184}
1185
1186
1187static int dvbdmx_disconnect_frontend(struct dmx_demux *demux)
1188{
1189 struct dvb_demux *dvbdemux = (struct dvb_demux *) demux;
1190
1191 if (down_interruptible (&dvbdemux->mutex))
1192 return -ERESTARTSYS;
1193
1194 demux->frontend = NULL;
1195 up(&dvbdemux->mutex);
1196 return 0;
1197}
1198
1199
1200static int dvbdmx_get_pes_pids(struct dmx_demux *demux, u16 *pids)
1201{
1202 struct dvb_demux *dvbdemux = (struct dvb_demux *) demux;
1203
1204 memcpy(pids, dvbdemux->pids, 5*sizeof(u16));
1205 return 0;
1206}
1207
1208
1209int dvb_dmx_init(struct dvb_demux *dvbdemux)
1210{
1211 int i, err;
1212 struct dmx_demux *dmx = &dvbdemux->dmx;
1213
1214 dvbdemux->users = 0;
1215 dvbdemux->filter = vmalloc(dvbdemux->filternum*sizeof(struct dvb_demux_filter));
1216
1217 if (!dvbdemux->filter)
1218 return -ENOMEM;
1219
1220 dvbdemux->feed = vmalloc(dvbdemux->feednum*sizeof(struct dvb_demux_feed));
1221 if (!dvbdemux->feed) {
1222 vfree(dvbdemux->filter);
1223 return -ENOMEM;
1224 }
1225 for (i=0; i<dvbdemux->filternum; i++) {
1226 dvbdemux->filter[i].state = DMX_STATE_FREE;
1227 dvbdemux->filter[i].index = i;
1228 }
1229 for (i=0; i<dvbdemux->feednum; i++) {
1230 dvbdemux->feed[i].state = DMX_STATE_FREE;
1231 dvbdemux->feed[i].index = i;
1232 }
1233 dvbdemux->frontend_list.next=
1234 dvbdemux->frontend_list.prev=
1235 &dvbdemux->frontend_list;
1236 for (i=0; i<DMX_TS_PES_OTHER; i++) {
1237 dvbdemux->pesfilter[i] = NULL;
1238 dvbdemux->pids[i] = 0xffff;
1239 }
1240
1241 INIT_LIST_HEAD(&dvbdemux->feed_list);
1242
1243 dvbdemux->playing = 0;
1244 dvbdemux->recording = 0;
1245 dvbdemux->tsbufp = 0;
1246
1247 if (!dvbdemux->check_crc32)
1248 dvbdemux->check_crc32 = dvb_dmx_crc32;
1249
1250 if (!dvbdemux->memcopy)
1251 dvbdemux->memcopy = dvb_dmx_memcopy;
1252
1253 dmx->frontend = NULL;
1254 dmx->reg_list.prev = dmx->reg_list.next = &dmx->reg_list;
1255 dmx->priv = (void *) dvbdemux;
1256 dmx->open = dvbdmx_open;
1257 dmx->close = dvbdmx_close;
1258 dmx->write = dvbdmx_write;
1259 dmx->allocate_ts_feed = dvbdmx_allocate_ts_feed;
1260 dmx->release_ts_feed = dvbdmx_release_ts_feed;
1261 dmx->allocate_section_feed = dvbdmx_allocate_section_feed;
1262 dmx->release_section_feed = dvbdmx_release_section_feed;
1263
1264 dmx->descramble_mac_address = NULL;
1265 dmx->descramble_section_payload = NULL;
1266
1267 dmx->add_frontend = dvbdmx_add_frontend;
1268 dmx->remove_frontend = dvbdmx_remove_frontend;
1269 dmx->get_frontends = dvbdmx_get_frontends;
1270 dmx->connect_frontend = dvbdmx_connect_frontend;
1271 dmx->disconnect_frontend = dvbdmx_disconnect_frontend;
1272 dmx->get_pes_pids = dvbdmx_get_pes_pids;
1273
1274 sema_init(&dvbdemux->mutex, 1);
1275 spin_lock_init(&dvbdemux->lock);
1276
1277 if ((err = dmx_register_demux(dmx)) < 0)
1278 return err;
1279
1280 return 0;
1281}
1282EXPORT_SYMBOL(dvb_dmx_init);
1283
1284
1285int dvb_dmx_release(struct dvb_demux *dvbdemux)
1286{
1287 struct dmx_demux *dmx = &dvbdemux->dmx;
1288
1289 dmx_unregister_demux(dmx);
1290 vfree(dvbdemux->filter);
1291 vfree(dvbdemux->feed);
1292 return 0;
1293}
1294EXPORT_SYMBOL(dvb_dmx_release);
diff --git a/drivers/media/dvb/dvb-core/dvb_demux.h b/drivers/media/dvb/dvb-core/dvb_demux.h
new file mode 100644
index 000000000000..c09beb391622
--- /dev/null
+++ b/drivers/media/dvb/dvb-core/dvb_demux.h
@@ -0,0 +1,146 @@
1/*
2 * dvb_demux.h: DVB kernel demux API
3 *
4 * Copyright (C) 2000-2001 Marcus Metzler & Ralph Metzler
5 * for convergence integrated media GmbH
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public License
9 * as published by the Free Software Foundation; either version 2.1
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 *
21 */
22
23
24#ifndef _DVB_DEMUX_H_
25#define _DVB_DEMUX_H_
26
27#include <linux/time.h>
28#include <linux/timer.h>
29#include <linux/spinlock.h>
30#include <asm/semaphore.h>
31
32#include "demux.h"
33
34#define DMX_TYPE_TS 0
35#define DMX_TYPE_SEC 1
36#define DMX_TYPE_PES 2
37
38#define DMX_STATE_FREE 0
39#define DMX_STATE_ALLOCATED 1
40#define DMX_STATE_SET 2
41#define DMX_STATE_READY 3
42#define DMX_STATE_GO 4
43
44#define DVB_DEMUX_MASK_MAX 18
45
46struct dvb_demux_filter {
47 struct dmx_section_filter filter;
48 u8 maskandmode [DMX_MAX_FILTER_SIZE];
49 u8 maskandnotmode [DMX_MAX_FILTER_SIZE];
50 int doneq;
51
52 struct dvb_demux_filter *next;
53 struct dvb_demux_feed *feed;
54 int index;
55 int state;
56 int type;
57 int pesto;
58
59 u16 handle;
60 u16 hw_handle;
61 struct timer_list timer;
62 int ts_state;
63};
64
65
66#define DMX_FEED_ENTRY(pos) list_entry(pos, struct dvb_demux_feed, list_head)
67
68struct dvb_demux_feed {
69 union {
70 struct dmx_ts_feed ts;
71 struct dmx_section_feed sec;
72 } feed;
73
74 union {
75 dmx_ts_cb ts;
76 dmx_section_cb sec;
77 } cb;
78
79 struct dvb_demux *demux;
80 void *priv;
81 int type;
82 int state;
83 u16 pid;
84 u8 *buffer;
85 int buffer_size;
86 int descramble;
87
88 struct timespec timeout;
89 struct dvb_demux_filter *filter;
90 int cb_length;
91
92 int ts_type;
93 enum dmx_ts_pes pes_type;
94
95 int cc;
96 int pusi_seen; /* prevents feeding of garbage from previous section */
97
98 u16 peslen;
99
100 struct list_head list_head;
101 int index; /* a unique index for each feed (can be used as hardware pid filter index) */
102};
103
104struct dvb_demux {
105 struct dmx_demux dmx;
106 void *priv;
107 int filternum;
108 int feednum;
109 int (*start_feed) (struct dvb_demux_feed *feed);
110 int (*stop_feed) (struct dvb_demux_feed *feed);
111 int (*write_to_decoder) (struct dvb_demux_feed *feed,
112 const u8 *buf, size_t len);
113 u32 (*check_crc32) (struct dvb_demux_feed *feed,
114 const u8 *buf, size_t len);
115 void (*memcopy) (struct dvb_demux_feed *feed, u8 *dst,
116 const u8 *src, size_t len);
117
118 int users;
119#define MAX_DVB_DEMUX_USERS 10
120 struct dvb_demux_filter *filter;
121 struct dvb_demux_feed *feed;
122
123 struct list_head frontend_list;
124
125 struct dvb_demux_feed *pesfilter[DMX_TS_PES_OTHER];
126 u16 pids[DMX_TS_PES_OTHER];
127 int playing;
128 int recording;
129
130#define DMX_MAX_PID 0x2000
131 struct list_head feed_list;
132 u8 tsbuf[204];
133 int tsbufp;
134
135 struct semaphore mutex;
136 spinlock_t lock;
137};
138
139
140int dvb_dmx_init(struct dvb_demux *dvbdemux);
141int dvb_dmx_release(struct dvb_demux *dvbdemux);
142void dvb_dmx_swfilter_packets(struct dvb_demux *dvbdmx, const u8 *buf, size_t count);
143void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count);
144void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf, size_t count);
145
146#endif /* _DVB_DEMUX_H_ */
diff --git a/drivers/media/dvb/dvb-core/dvb_filter.c b/drivers/media/dvb/dvb-core/dvb_filter.c
new file mode 100644
index 000000000000..bd5143906084
--- /dev/null
+++ b/drivers/media/dvb/dvb-core/dvb_filter.c
@@ -0,0 +1,603 @@
1#include <linux/kernel.h>
2#include <linux/module.h>
3#include <linux/string.h>
4#include "dvb_filter.h"
5
6#if 0
7static unsigned int bitrates[3][16] =
8{{0,32,64,96,128,160,192,224,256,288,320,352,384,416,448,0},
9 {0,32,48,56,64,80,96,112,128,160,192,224,256,320,384,0},
10 {0,32,40,48,56,64,80,96,112,128,160,192,224,256,320,0}};
11#endif
12
13static u32 freq[4] = {480, 441, 320, 0};
14
15static unsigned int ac3_bitrates[32] =
16 {32,40,48,56,64,80,96,112,128,160,192,224,256,320,384,448,512,576,640,
17 0,0,0,0,0,0,0,0,0,0,0,0,0};
18
19static u32 ac3_frames[3][32] =
20 {{64,80,96,112,128,160,192,224,256,320,384,448,512,640,768,896,1024,
21 1152,1280,0,0,0,0,0,0,0,0,0,0,0,0,0},
22 {69,87,104,121,139,174,208,243,278,348,417,487,557,696,835,975,1114,
23 1253,1393,0,0,0,0,0,0,0,0,0,0,0,0,0},
24 {96,120,144,168,192,240,288,336,384,480,576,672,768,960,1152,1344,
25 1536,1728,1920,0,0,0,0,0,0,0,0,0,0,0,0,0}};
26
27
28
29#if 0
30static void setup_ts2pes(ipack *pa, ipack *pv, u16 *pida, u16 *pidv,
31 void (*pes_write)(u8 *buf, int count, void *data),
32 void *priv)
33{
34 dvb_filter_ipack_init(pa, IPACKS, pes_write);
35 dvb_filter_ipack_init(pv, IPACKS, pes_write);
36 pa->pid = pida;
37 pv->pid = pidv;
38 pa->data = priv;
39 pv->data = priv;
40}
41#endif
42
43#if 0
44static void ts_to_pes(ipack *p, u8 *buf) // don't need count (=188)
45{
46 u8 off = 0;
47
48 if (!buf || !p ){
49 printk("NULL POINTER IDIOT\n");
50 return;
51 }
52 if (buf[1]&PAY_START) {
53 if (p->plength == MMAX_PLENGTH-6 && p->found>6){
54 p->plength = p->found-6;
55 p->found = 0;
56 send_ipack(p);
57 dvb_filter_ipack_reset(p);
58 }
59 }
60 if (buf[3] & ADAPT_FIELD) { // adaptation field?
61 off = buf[4] + 1;
62 if (off+4 > 187) return;
63 }
64 dvb_filter_instant_repack(buf+4+off, TS_SIZE-4-off, p);
65}
66#endif
67
68#if 0
69/* needs 5 byte input, returns picture coding type*/
70static int read_picture_header(u8 *headr, struct mpg_picture *pic, int field, int pr)
71{
72 u8 pct;
73
74 if (pr) printk( "Pic header: ");
75 pic->temporal_reference[field] = (( headr[0] << 2 ) |
76 (headr[1] & 0x03) )& 0x03ff;
77 if (pr) printk( " temp ref: 0x%04x", pic->temporal_reference[field]);
78
79 pct = ( headr[1] >> 2 ) & 0x07;
80 pic->picture_coding_type[field] = pct;
81 if (pr) {
82 switch(pct){
83 case I_FRAME:
84 printk( " I-FRAME");
85 break;
86 case B_FRAME:
87 printk( " B-FRAME");
88 break;
89 case P_FRAME:
90 printk( " P-FRAME");
91 break;
92 }
93 }
94
95
96 pic->vinfo.vbv_delay = (( headr[1] >> 5 ) | ( headr[2] << 3) |
97 ( (headr[3] & 0x1F) << 11) ) & 0xffff;
98
99 if (pr) printk( " vbv delay: 0x%04x", pic->vinfo.vbv_delay);
100
101 pic->picture_header_parameter = ( headr[3] & 0xe0 ) |
102 ((headr[4] & 0x80) >> 3);
103
104 if ( pct == B_FRAME ){
105 pic->picture_header_parameter |= ( headr[4] >> 3 ) & 0x0f;
106 }
107 if (pr) printk( " pic head param: 0x%x",
108 pic->picture_header_parameter);
109
110 return pct;
111}
112#endif
113
114#if 0
115/* needs 4 byte input */
116static int read_gop_header(u8 *headr, struct mpg_picture *pic, int pr)
117{
118 if (pr) printk("GOP header: ");
119
120 pic->time_code = (( headr[0] << 17 ) | ( headr[1] << 9) |
121 ( headr[2] << 1 ) | (headr[3] &0x01)) & 0x1ffffff;
122
123 if (pr) printk(" time: %d:%d.%d ", (headr[0]>>2)& 0x1F,
124 ((headr[0]<<4)& 0x30)| ((headr[1]>>4)& 0x0F),
125 ((headr[1]<<3)& 0x38)| ((headr[2]>>5)& 0x0F));
126
127 if ( ( headr[3] & 0x40 ) != 0 ){
128 pic->closed_gop = 1;
129 } else {
130 pic->closed_gop = 0;
131 }
132 if (pr) printk("closed: %d", pic->closed_gop);
133
134 if ( ( headr[3] & 0x20 ) != 0 ){
135 pic->broken_link = 1;
136 } else {
137 pic->broken_link = 0;
138 }
139 if (pr) printk(" broken: %d\n", pic->broken_link);
140
141 return 0;
142}
143#endif
144
145#if 0
146/* needs 8 byte input */
147static int read_sequence_header(u8 *headr, struct dvb_video_info *vi, int pr)
148{
149 int sw;
150 int form = -1;
151
152 if (pr) printk("Reading sequence header\n");
153
154 vi->horizontal_size = ((headr[1] &0xF0) >> 4) | (headr[0] << 4);
155 vi->vertical_size = ((headr[1] &0x0F) << 8) | (headr[2]);
156
157 sw = (int)((headr[3]&0xF0) >> 4) ;
158
159 switch( sw ){
160 case 1:
161 if (pr)
162 printk("Videostream: ASPECT: 1:1");
163 vi->aspect_ratio = 100;
164 break;
165 case 2:
166 if (pr)
167 printk("Videostream: ASPECT: 4:3");
168 vi->aspect_ratio = 133;
169 break;
170 case 3:
171 if (pr)
172 printk("Videostream: ASPECT: 16:9");
173 vi->aspect_ratio = 177;
174 break;
175 case 4:
176 if (pr)
177 printk("Videostream: ASPECT: 2.21:1");
178 vi->aspect_ratio = 221;
179 break;
180
181 case 5 ... 15:
182 if (pr)
183 printk("Videostream: ASPECT: reserved");
184 vi->aspect_ratio = 0;
185 break;
186
187 default:
188 vi->aspect_ratio = 0;
189 return -1;
190 }
191
192 if (pr)
193 printk(" Size = %dx%d",vi->horizontal_size,vi->vertical_size);
194
195 sw = (int)(headr[3]&0x0F);
196
197 switch ( sw ) {
198 case 1:
199 if (pr)
200 printk(" FRate: 23.976 fps");
201 vi->framerate = 23976;
202 form = -1;
203 break;
204 case 2:
205 if (pr)
206 printk(" FRate: 24 fps");
207 vi->framerate = 24000;
208 form = -1;
209 break;
210 case 3:
211 if (pr)
212 printk(" FRate: 25 fps");
213 vi->framerate = 25000;
214 form = VIDEO_MODE_PAL;
215 break;
216 case 4:
217 if (pr)
218 printk(" FRate: 29.97 fps");
219 vi->framerate = 29970;
220 form = VIDEO_MODE_NTSC;
221 break;
222 case 5:
223 if (pr)
224 printk(" FRate: 30 fps");
225 vi->framerate = 30000;
226 form = VIDEO_MODE_NTSC;
227 break;
228 case 6:
229 if (pr)
230 printk(" FRate: 50 fps");
231 vi->framerate = 50000;
232 form = VIDEO_MODE_PAL;
233 break;
234 case 7:
235 if (pr)
236 printk(" FRate: 60 fps");
237 vi->framerate = 60000;
238 form = VIDEO_MODE_NTSC;
239 break;
240 }
241
242 vi->bit_rate = (headr[4] << 10) | (headr[5] << 2) | (headr[6] & 0x03);
243
244 vi->vbv_buffer_size
245 = (( headr[6] & 0xF8) >> 3 ) | (( headr[7] & 0x1F )<< 5);
246
247 if (pr){
248 printk(" BRate: %d Mbit/s",4*(vi->bit_rate)/10000);
249 printk(" vbvbuffer %d",16*1024*(vi->vbv_buffer_size));
250 printk("\n");
251 }
252
253 vi->video_format = form;
254
255 return 0;
256}
257#endif
258
259
260#if 0
261static int get_vinfo(u8 *mbuf, int count, struct dvb_video_info *vi, int pr)
262{
263 u8 *headr;
264 int found = 0;
265 int c = 0;
266
267 while (found < 4 && c+4 < count){
268 u8 *b;
269
270 b = mbuf+c;
271 if ( b[0] == 0x00 && b[1] == 0x00 && b[2] == 0x01
272 && b[3] == 0xb3) found = 4;
273 else {
274 c++;
275 }
276 }
277
278 if (! found) return -1;
279 c += 4;
280 if (c+12 >= count) return -1;
281 headr = mbuf+c;
282 if (read_sequence_header(headr, vi, pr) < 0) return -1;
283 vi->off = c-4;
284 return 0;
285}
286#endif
287
288
289#if 0
290static int get_ainfo(u8 *mbuf, int count, struct dvb_audio_info *ai, int pr)
291{
292 u8 *headr;
293 int found = 0;
294 int c = 0;
295 int fr = 0;
296
297 while (found < 2 && c < count){
298 u8 b[2];
299 memcpy( b, mbuf+c, 2);
300
301 if ( b[0] == 0xff && (b[1] & 0xf8) == 0xf8)
302 found = 2;
303 else {
304 c++;
305 }
306 }
307
308 if (!found) return -1;
309
310 if (c+3 >= count) return -1;
311 headr = mbuf+c;
312
313 ai->layer = (headr[1] & 0x06) >> 1;
314
315 if (pr)
316 printk("Audiostream: Layer: %d", 4-ai->layer);
317
318
319 ai->bit_rate = bitrates[(3-ai->layer)][(headr[2] >> 4 )]*1000;
320
321 if (pr){
322 if (ai->bit_rate == 0)
323 printk(" Bit rate: free");
324 else if (ai->bit_rate == 0xf)
325 printk(" BRate: reserved");
326 else
327 printk(" BRate: %d kb/s", ai->bit_rate/1000);
328 }
329
330 fr = (headr[2] & 0x0c ) >> 2;
331 ai->frequency = freq[fr]*100;
332 if (pr){
333 if (ai->frequency == 3)
334 printk(" Freq: reserved\n");
335 else
336 printk(" Freq: %d kHz\n",ai->frequency);
337
338 }
339 ai->off = c;
340 return 0;
341}
342#endif
343
344
345int dvb_filter_get_ac3info(u8 *mbuf, int count, struct dvb_audio_info *ai, int pr)
346{
347 u8 *headr;
348 int found = 0;
349 int c = 0;
350 u8 frame = 0;
351 int fr = 0;
352
353 while ( !found && c < count){
354 u8 *b = mbuf+c;
355
356 if ( b[0] == 0x0b && b[1] == 0x77 )
357 found = 1;
358 else {
359 c++;
360 }
361 }
362
363 if (!found) return -1;
364 if (pr)
365 printk("Audiostream: AC3");
366
367 ai->off = c;
368 if (c+5 >= count) return -1;
369
370 ai->layer = 0; // 0 for AC3
371 headr = mbuf+c+2;
372
373 frame = (headr[2]&0x3f);
374 ai->bit_rate = ac3_bitrates[frame >> 1]*1000;
375
376 if (pr)
377 printk(" BRate: %d kb/s", (int) ai->bit_rate/1000);
378
379 ai->frequency = (headr[2] & 0xc0 ) >> 6;
380 fr = (headr[2] & 0xc0 ) >> 6;
381 ai->frequency = freq[fr]*100;
382 if (pr) printk (" Freq: %d Hz\n", (int) ai->frequency);
383
384
385 ai->framesize = ac3_frames[fr][frame >> 1];
386 if ((frame & 1) && (fr == 1)) ai->framesize++;
387 ai->framesize = ai->framesize << 1;
388 if (pr) printk (" Framesize %d\n",(int) ai->framesize);
389
390
391 return 0;
392}
393EXPORT_SYMBOL(dvb_filter_get_ac3info);
394
395
396#if 0
397static u8 *skip_pes_header(u8 **bufp)
398{
399 u8 *inbuf = *bufp;
400 u8 *buf = inbuf;
401 u8 *pts = NULL;
402 int skip = 0;
403
404 static const int mpeg1_skip_table[16] = {
405 1, 0xffff, 5, 10, 0xffff, 0xffff, 0xffff, 0xffff,
406 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff
407 };
408
409
410 if ((inbuf[6] & 0xc0) == 0x80){ /* mpeg2 */
411 if (buf[7] & PTS_ONLY)
412 pts = buf+9;
413 else pts = NULL;
414 buf = inbuf + 9 + inbuf[8];
415 } else { /* mpeg1 */
416 for (buf = inbuf + 6; *buf == 0xff; buf++)
417 if (buf == inbuf + 6 + 16) {
418 break;
419 }
420 if ((*buf & 0xc0) == 0x40)
421 buf += 2;
422 skip = mpeg1_skip_table [*buf >> 4];
423 if (skip == 5 || skip == 10) pts = buf;
424 else pts = NULL;
425
426 buf += mpeg1_skip_table [*buf >> 4];
427 }
428
429 *bufp = buf;
430 return pts;
431}
432#endif
433
434#if 0
435static void initialize_quant_matrix( u32 *matrix )
436{
437 int i;
438
439 matrix[0] = 0x08101013;
440 matrix[1] = 0x10131616;
441 matrix[2] = 0x16161616;
442 matrix[3] = 0x1a181a1b;
443 matrix[4] = 0x1b1b1a1a;
444 matrix[5] = 0x1a1a1b1b;
445 matrix[6] = 0x1b1d1d1d;
446 matrix[7] = 0x2222221d;
447 matrix[8] = 0x1d1d1b1b;
448 matrix[9] = 0x1d1d2020;
449 matrix[10] = 0x22222526;
450 matrix[11] = 0x25232322;
451 matrix[12] = 0x23262628;
452 matrix[13] = 0x28283030;
453 matrix[14] = 0x2e2e3838;
454 matrix[15] = 0x3a454553;
455
456 for ( i = 16 ; i < 32 ; i++ )
457 matrix[i] = 0x10101010;
458}
459#endif
460
461#if 0
462static void initialize_mpg_picture(struct mpg_picture *pic)
463{
464 int i;
465
466 /* set MPEG1 */
467 pic->mpeg1_flag = 1;
468 pic->profile_and_level = 0x4A ; /* MP@LL */
469 pic->progressive_sequence = 1;
470 pic->low_delay = 0;
471
472 pic->sequence_display_extension_flag = 0;
473 for ( i = 0 ; i < 4 ; i++ ){
474 pic->frame_centre_horizontal_offset[i] = 0;
475 pic->frame_centre_vertical_offset[i] = 0;
476 }
477 pic->last_frame_centre_horizontal_offset = 0;
478 pic->last_frame_centre_vertical_offset = 0;
479
480 pic->picture_display_extension_flag[0] = 0;
481 pic->picture_display_extension_flag[1] = 0;
482 pic->sequence_header_flag = 0;
483 pic->gop_flag = 0;
484 pic->sequence_end_flag = 0;
485}
486#endif
487
488#if 0
489static void mpg_set_picture_parameter( int32_t field_type, struct mpg_picture *pic )
490{
491 int16_t last_h_offset;
492 int16_t last_v_offset;
493
494 int16_t *p_h_offset;
495 int16_t *p_v_offset;
496
497 if ( pic->mpeg1_flag ){
498 pic->picture_structure[field_type] = VIDEO_FRAME_PICTURE;
499 pic->top_field_first = 0;
500 pic->repeat_first_field = 0;
501 pic->progressive_frame = 1;
502 pic->picture_coding_parameter = 0x000010;
503 }
504
505 /* Reset flag */
506 pic->picture_display_extension_flag[field_type] = 0;
507
508 last_h_offset = pic->last_frame_centre_horizontal_offset;
509 last_v_offset = pic->last_frame_centre_vertical_offset;
510 if ( field_type == FIRST_FIELD ){
511 p_h_offset = pic->frame_centre_horizontal_offset;
512 p_v_offset = pic->frame_centre_vertical_offset;
513 *p_h_offset = last_h_offset;
514 *(p_h_offset + 1) = last_h_offset;
515 *(p_h_offset + 2) = last_h_offset;
516 *p_v_offset = last_v_offset;
517 *(p_v_offset + 1) = last_v_offset;
518 *(p_v_offset + 2) = last_v_offset;
519 } else {
520 pic->frame_centre_horizontal_offset[3] = last_h_offset;
521 pic->frame_centre_vertical_offset[3] = last_v_offset;
522 }
523}
524#endif
525
526#if 0
527static void init_mpg_picture( struct mpg_picture *pic, int chan, int32_t field_type)
528{
529 pic->picture_header = 0;
530 pic->sequence_header_data
531 = ( INIT_HORIZONTAL_SIZE << 20 )
532 | ( INIT_VERTICAL_SIZE << 8 )
533 | ( INIT_ASPECT_RATIO << 4 )
534 | ( INIT_FRAME_RATE );
535 pic->mpeg1_flag = 0;
536 pic->vinfo.horizontal_size
537 = INIT_DISP_HORIZONTAL_SIZE;
538 pic->vinfo.vertical_size
539 = INIT_DISP_VERTICAL_SIZE;
540 pic->picture_display_extension_flag[field_type]
541 = 0;
542 pic->pts_flag[field_type] = 0;
543
544 pic->sequence_gop_header = 0;
545 pic->picture_header = 0;
546 pic->sequence_header_flag = 0;
547 pic->gop_flag = 0;
548 pic->sequence_end_flag = 0;
549 pic->sequence_display_extension_flag = 0;
550 pic->last_frame_centre_horizontal_offset = 0;
551 pic->last_frame_centre_vertical_offset = 0;
552 pic->channel = chan;
553}
554#endif
555
556void dvb_filter_pes2ts_init(struct dvb_filter_pes2ts *p2ts, unsigned short pid,
557 dvb_filter_pes2ts_cb_t *cb, void *priv)
558{
559 unsigned char *buf=p2ts->buf;
560
561 buf[0]=0x47;
562 buf[1]=(pid>>8);
563 buf[2]=pid&0xff;
564 p2ts->cc=0;
565 p2ts->cb=cb;
566 p2ts->priv=priv;
567}
568EXPORT_SYMBOL(dvb_filter_pes2ts_init);
569
570int dvb_filter_pes2ts(struct dvb_filter_pes2ts *p2ts, unsigned char *pes,
571 int len, int payload_start)
572{
573 unsigned char *buf=p2ts->buf;
574 int ret=0, rest;
575
576 //len=6+((pes[4]<<8)|pes[5]);
577
578 if (payload_start)
579 buf[1]|=0x40;
580 else
581 buf[1]&=~0x40;
582 while (len>=184) {
583 buf[3]=0x10|((p2ts->cc++)&0x0f);
584 memcpy(buf+4, pes, 184);
585 if ((ret=p2ts->cb(p2ts->priv, buf)))
586 return ret;
587 len-=184; pes+=184;
588 buf[1]&=~0x40;
589 }
590 if (!len)
591 return 0;
592 buf[3]=0x30|((p2ts->cc++)&0x0f);
593 rest=183-len;
594 if (rest) {
595 buf[5]=0x00;
596 if (rest-1)
597 memset(buf+6, 0xff, rest-1);
598 }
599 buf[4]=rest;
600 memcpy(buf+5+rest, pes, len);
601 return p2ts->cb(p2ts->priv, buf);
602}
603EXPORT_SYMBOL(dvb_filter_pes2ts);
diff --git a/drivers/media/dvb/dvb-core/dvb_filter.h b/drivers/media/dvb/dvb-core/dvb_filter.h
new file mode 100644
index 000000000000..b0848f7836b7
--- /dev/null
+++ b/drivers/media/dvb/dvb-core/dvb_filter.h
@@ -0,0 +1,246 @@
1/*
2 * dvb_filter.h
3 *
4 * Copyright (C) 2003 Convergence GmbH
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public License
8 * as published by the Free Software Foundation; either version 2.1
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20
21#ifndef _DVB_FILTER_H_
22#define _DVB_FILTER_H_
23
24#include <linux/slab.h>
25
26#include "demux.h"
27
28typedef int (dvb_filter_pes2ts_cb_t) (void *, unsigned char *);
29
30struct dvb_filter_pes2ts {
31 unsigned char buf[188];
32 unsigned char cc;
33 dvb_filter_pes2ts_cb_t *cb;
34 void *priv;
35};
36
37void dvb_filter_pes2ts_init(struct dvb_filter_pes2ts *p2ts, unsigned short pid,
38 dvb_filter_pes2ts_cb_t *cb, void *priv);
39
40int dvb_filter_pes2ts(struct dvb_filter_pes2ts *p2ts, unsigned char *pes,
41 int len, int payload_start);
42
43
44#define PROG_STREAM_MAP 0xBC
45#define PRIVATE_STREAM1 0xBD
46#define PADDING_STREAM 0xBE
47#define PRIVATE_STREAM2 0xBF
48#define AUDIO_STREAM_S 0xC0
49#define AUDIO_STREAM_E 0xDF
50#define VIDEO_STREAM_S 0xE0
51#define VIDEO_STREAM_E 0xEF
52#define ECM_STREAM 0xF0
53#define EMM_STREAM 0xF1
54#define DSM_CC_STREAM 0xF2
55#define ISO13522_STREAM 0xF3
56#define PROG_STREAM_DIR 0xFF
57
58#define DVB_PICTURE_START 0x00
59#define DVB_USER_START 0xb2
60#define DVB_SEQUENCE_HEADER 0xb3
61#define DVB_SEQUENCE_ERROR 0xb4
62#define DVB_EXTENSION_START 0xb5
63#define DVB_SEQUENCE_END 0xb7
64#define DVB_GOP_START 0xb8
65#define DVB_EXCEPT_SLICE 0xb0
66
67#define SEQUENCE_EXTENSION 0x01
68#define SEQUENCE_DISPLAY_EXTENSION 0x02
69#define PICTURE_CODING_EXTENSION 0x08
70#define QUANT_MATRIX_EXTENSION 0x03
71#define PICTURE_DISPLAY_EXTENSION 0x07
72
73#define I_FRAME 0x01
74#define B_FRAME 0x02
75#define P_FRAME 0x03
76
77/* Initialize sequence_data */
78#define INIT_HORIZONTAL_SIZE 720
79#define INIT_VERTICAL_SIZE 576
80#define INIT_ASPECT_RATIO 0x02
81#define INIT_FRAME_RATE 0x03
82#define INIT_DISP_HORIZONTAL_SIZE 540
83#define INIT_DISP_VERTICAL_SIZE 576
84
85
86//flags2
87#define PTS_DTS_FLAGS 0xC0
88#define ESCR_FLAG 0x20
89#define ES_RATE_FLAG 0x10
90#define DSM_TRICK_FLAG 0x08
91#define ADD_CPY_FLAG 0x04
92#define PES_CRC_FLAG 0x02
93#define PES_EXT_FLAG 0x01
94
95//pts_dts flags
96#define PTS_ONLY 0x80
97#define PTS_DTS 0xC0
98
99#define TS_SIZE 188
100#define TRANS_ERROR 0x80
101#define PAY_START 0x40
102#define TRANS_PRIO 0x20
103#define PID_MASK_HI 0x1F
104//flags
105#define TRANS_SCRMBL1 0x80
106#define TRANS_SCRMBL2 0x40
107#define ADAPT_FIELD 0x20
108#define PAYLOAD 0x10
109#define COUNT_MASK 0x0F
110
111// adaptation flags
112#define DISCON_IND 0x80
113#define RAND_ACC_IND 0x40
114#define ES_PRI_IND 0x20
115#define PCR_FLAG 0x10
116#define OPCR_FLAG 0x08
117#define SPLICE_FLAG 0x04
118#define TRANS_PRIV 0x02
119#define ADAP_EXT_FLAG 0x01
120
121// adaptation extension flags
122#define LTW_FLAG 0x80
123#define PIECE_RATE 0x40
124#define SEAM_SPLICE 0x20
125
126
127#define MAX_PLENGTH 0xFFFF
128#define MMAX_PLENGTH (256*MAX_PLENGTH)
129
130#ifndef IPACKS
131#define IPACKS 2048
132#endif
133
134struct ipack {
135 int size;
136 int found;
137 u8 *buf;
138 u8 cid;
139 u32 plength;
140 u8 plen[2];
141 u8 flag1;
142 u8 flag2;
143 u8 hlength;
144 u8 pts[5];
145 u16 *pid;
146 int mpeg;
147 u8 check;
148 int which;
149 int done;
150 void *data;
151 void (*func)(u8 *buf, int size, void *priv);
152 int count;
153 int repack_subids;
154};
155
156struct dvb_video_info {
157 u32 horizontal_size;
158 u32 vertical_size;
159 u32 aspect_ratio;
160 u32 framerate;
161 u32 video_format;
162 u32 bit_rate;
163 u32 comp_bit_rate;
164 u32 vbv_buffer_size;
165 s16 vbv_delay;
166 u32 CSPF;
167 u32 off;
168};
169
170#define OFF_SIZE 4
171#define FIRST_FIELD 0
172#define SECOND_FIELD 1
173#define VIDEO_FRAME_PICTURE 0x03
174
175struct mpg_picture {
176 int channel;
177 struct dvb_video_info vinfo;
178 u32 *sequence_gop_header;
179 u32 *picture_header;
180 s32 time_code;
181 int low_delay;
182 int closed_gop;
183 int broken_link;
184 int sequence_header_flag;
185 int gop_flag;
186 int sequence_end_flag;
187
188 u8 profile_and_level;
189 s32 picture_coding_parameter;
190 u32 matrix[32];
191 s8 matrix_change_flag;
192
193 u8 picture_header_parameter;
194 /* bit 0 - 2: bwd f code
195 bit 3 : fpb vector
196 bit 4 - 6: fwd f code
197 bit 7 : fpf vector */
198
199 int mpeg1_flag;
200 int progressive_sequence;
201 int sequence_display_extension_flag;
202 u32 sequence_header_data;
203 s16 last_frame_centre_horizontal_offset;
204 s16 last_frame_centre_vertical_offset;
205
206 u32 pts[2]; /* [0] 1st field, [1] 2nd field */
207 int top_field_first;
208 int repeat_first_field;
209 int progressive_frame;
210 int bank;
211 int forward_bank;
212 int backward_bank;
213 int compress;
214 s16 frame_centre_horizontal_offset[OFF_SIZE];
215 /* [0-2] 1st field, [3] 2nd field */
216 s16 frame_centre_vertical_offset[OFF_SIZE];
217 /* [0-2] 1st field, [3] 2nd field */
218 s16 temporal_reference[2];
219 /* [0] 1st field, [1] 2nd field */
220
221 s8 picture_coding_type[2];
222 /* [0] 1st field, [1] 2nd field */
223 s8 picture_structure[2];
224 /* [0] 1st field, [1] 2nd field */
225 s8 picture_display_extension_flag[2];
226 /* [0] 1st field, [1] 2nd field */
227 /* picture_display_extenion() 0:no 1:exit*/
228 s8 pts_flag[2];
229 /* [0] 1st field, [1] 2nd field */
230};
231
232struct dvb_audio_info {
233 int layer;
234 u32 bit_rate;
235 u32 frequency;
236 u32 mode;
237 u32 mode_extension ;
238 u32 emphasis;
239 u32 framesize;
240 u32 off;
241};
242
243int dvb_filter_get_ac3info(u8 *mbuf, int count, struct dvb_audio_info *ai, int pr);
244
245
246#endif
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c
new file mode 100644
index 000000000000..59a9adfae1eb
--- /dev/null
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -0,0 +1,915 @@
1/*
2 * dvb_frontend.c: DVB frontend tuning interface/thread
3 *
4 *
5 * Copyright (C) 1999-2001 Ralph Metzler
6 * Marcus Metzler
7 * Holger Waechtler
8 * for convergence integrated media GmbH
9 *
10 * Copyright (C) 2004 Andrew de Quincey (tuning thread cleanup)
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 * 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 * 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#include <linux/string.h>
29#include <linux/kernel.h>
30#include <linux/sched.h>
31#include <linux/wait.h>
32#include <linux/slab.h>
33#include <linux/poll.h>
34#include <linux/module.h>
35#include <linux/moduleparam.h>
36#include <linux/list.h>
37#include <linux/suspend.h>
38#include <asm/processor.h>
39#include <asm/semaphore.h>
40
41#include "dvb_frontend.h"
42#include "dvbdev.h"
43
44static int dvb_frontend_debug;
45static int dvb_shutdown_timeout = 5;
46static int dvb_force_auto_inversion;
47static int dvb_override_tune_delay;
48static int dvb_powerdown_on_sleep = 1;
49
50module_param_named(frontend_debug, dvb_frontend_debug, int, 0644);
51MODULE_PARM_DESC(dvb_frontend_debug, "Turn on/off frontend core debugging (default:off).");
52module_param(dvb_shutdown_timeout, int, 0444);
53MODULE_PARM_DESC(dvb_shutdown_timeout, "wait <shutdown_timeout> seconds after close() before suspending hardware");
54module_param(dvb_force_auto_inversion, int, 0444);
55MODULE_PARM_DESC(dvb_force_auto_inversion, "0: normal (default), 1: INVERSION_AUTO forced always");
56module_param(dvb_override_tune_delay, int, 0444);
57MODULE_PARM_DESC(dvb_override_tune_delay, "0: normal (default), >0 => delay in milliseconds to wait for lock after a tune attempt");
58module_param(dvb_powerdown_on_sleep, int, 0444);
59MODULE_PARM_DESC(dvb_powerdown_on_sleep, "0: do not power down, 1: turn LNB volatage off on sleep (default)");
60
61#define dprintk if (dvb_frontend_debug) printk
62
63#define FESTATE_IDLE 1
64#define FESTATE_RETUNE 2
65#define FESTATE_TUNING_FAST 4
66#define FESTATE_TUNING_SLOW 8
67#define FESTATE_TUNED 16
68#define FESTATE_ZIGZAG_FAST 32
69#define FESTATE_ZIGZAG_SLOW 64
70#define FESTATE_DISEQC 128
71#define FESTATE_WAITFORLOCK (FESTATE_TUNING_FAST | FESTATE_TUNING_SLOW | FESTATE_ZIGZAG_FAST | FESTATE_ZIGZAG_SLOW | FESTATE_DISEQC)
72#define FESTATE_SEARCHING_FAST (FESTATE_TUNING_FAST | FESTATE_ZIGZAG_FAST)
73#define FESTATE_SEARCHING_SLOW (FESTATE_TUNING_SLOW | FESTATE_ZIGZAG_SLOW)
74#define FESTATE_LOSTLOCK (FESTATE_ZIGZAG_FAST | FESTATE_ZIGZAG_SLOW)
75/*
76 * FESTATE_IDLE. No tuning parameters have been supplied and the loop is idling.
77 * FESTATE_RETUNE. Parameters have been supplied, but we have not yet performed the first tune.
78 * FESTATE_TUNING_FAST. Tuning parameters have been supplied and fast zigzag scan is in progress.
79 * FESTATE_TUNING_SLOW. Tuning parameters have been supplied. Fast zigzag failed, so we're trying again, but slower.
80 * FESTATE_TUNED. The frontend has successfully locked on.
81 * FESTATE_ZIGZAG_FAST. The lock has been lost, and a fast zigzag has been initiated to try and regain it.
82 * FESTATE_ZIGZAG_SLOW. The lock has been lost. Fast zigzag has been failed, so we're trying again, but slower.
83 * FESTATE_DISEQC. A DISEQC command has just been issued.
84 * FESTATE_WAITFORLOCK. When we're waiting for a lock.
85 * FESTATE_SEARCHING_FAST. When we're searching for a signal using a fast zigzag scan.
86 * FESTATE_SEARCHING_SLOW. When we're searching for a signal using a slow zigzag scan.
87 * FESTATE_LOSTLOCK. When the lock has been lost, and we're searching it again.
88 */
89
90static DECLARE_MUTEX(frontend_mutex);
91
92struct dvb_frontend_private {
93
94 struct dvb_device *dvbdev;
95 struct dvb_frontend_parameters parameters;
96 struct dvb_fe_events events;
97 struct semaphore sem;
98 struct list_head list_head;
99 wait_queue_head_t wait_queue;
100 pid_t thread_pid;
101 unsigned long release_jiffies;
102 int state;
103 int bending;
104 int lnb_drift;
105 int inversion;
106 int auto_step;
107 int auto_sub_step;
108 int started_auto_step;
109 int min_delay;
110 int max_drift;
111 int step_size;
112 int exit;
113 int wakeup;
114 fe_status_t status;
115};
116
117
118static void dvb_frontend_add_event(struct dvb_frontend *fe, fe_status_t status)
119{
120 struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv;
121 struct dvb_fe_events *events = &fepriv->events;
122 struct dvb_frontend_event *e;
123 int wp;
124
125 dprintk ("%s\n", __FUNCTION__);
126
127 if (down_interruptible (&events->sem))
128 return;
129
130 wp = (events->eventw + 1) % MAX_EVENT;
131
132 if (wp == events->eventr) {
133 events->overflow = 1;
134 events->eventr = (events->eventr + 1) % MAX_EVENT;
135 }
136
137 e = &events->events[events->eventw];
138
139 memcpy (&e->parameters, &fepriv->parameters,
140 sizeof (struct dvb_frontend_parameters));
141
142 if (status & FE_HAS_LOCK)
143 if (fe->ops->get_frontend)
144 fe->ops->get_frontend(fe, &e->parameters);
145
146 events->eventw = wp;
147
148 up (&events->sem);
149
150 e->status = status;
151
152 wake_up_interruptible (&events->wait_queue);
153}
154
155static int dvb_frontend_get_event(struct dvb_frontend *fe,
156 struct dvb_frontend_event *event, int flags)
157{
158 struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv;
159 struct dvb_fe_events *events = &fepriv->events;
160
161 dprintk ("%s\n", __FUNCTION__);
162
163 if (events->overflow) {
164 events->overflow = 0;
165 return -EOVERFLOW;
166 }
167
168 if (events->eventw == events->eventr) {
169 int ret;
170
171 if (flags & O_NONBLOCK)
172 return -EWOULDBLOCK;
173
174 up(&fepriv->sem);
175
176 ret = wait_event_interruptible (events->wait_queue,
177 events->eventw != events->eventr);
178
179 if (down_interruptible (&fepriv->sem))
180 return -ERESTARTSYS;
181
182 if (ret < 0)
183 return ret;
184 }
185
186 if (down_interruptible (&events->sem))
187 return -ERESTARTSYS;
188
189 memcpy (event, &events->events[events->eventr],
190 sizeof(struct dvb_frontend_event));
191
192 events->eventr = (events->eventr + 1) % MAX_EVENT;
193
194 up (&events->sem);
195
196 return 0;
197}
198
199static void dvb_frontend_init(struct dvb_frontend *fe)
200{
201 dprintk ("DVB: initialising frontend %i (%s)...\n",
202 fe->dvb->num,
203 fe->ops->info.name);
204
205 if (fe->ops->init)
206 fe->ops->init(fe);
207}
208
209static void update_delay(int *quality, int *delay, int min_delay, int locked)
210{
211 int q2;
212
213 dprintk ("%s\n", __FUNCTION__);
214
215 if (locked)
216 (*quality) = (*quality * 220 + 36*256) / 256;
217 else
218 (*quality) = (*quality * 220 + 0) / 256;
219
220 q2 = *quality - 128;
221 q2 *= q2;
222
223 *delay = min_delay + q2 * HZ / (128*128);
224}
225
226/**
227 * Performs automatic twiddling of frontend parameters.
228 *
229 * @param fe The frontend concerned.
230 * @param check_wrapped Checks if an iteration has completed. DO NOT SET ON THE FIRST ATTEMPT
231 * @returns Number of complete iterations that have been performed.
232 */
233static int dvb_frontend_autotune(struct dvb_frontend *fe, int check_wrapped)
234{
235 int autoinversion;
236 int ready = 0;
237 struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv;
238 int original_inversion = fepriv->parameters.inversion;
239 u32 original_frequency = fepriv->parameters.frequency;
240
241 /* are we using autoinversion? */
242 autoinversion = ((!(fe->ops->info.caps & FE_CAN_INVERSION_AUTO)) &&
243 (fepriv->parameters.inversion == INVERSION_AUTO));
244
245 /* setup parameters correctly */
246 while(!ready) {
247 /* calculate the lnb_drift */
248 fepriv->lnb_drift = fepriv->auto_step * fepriv->step_size;
249
250 /* wrap the auto_step if we've exceeded the maximum drift */
251 if (fepriv->lnb_drift > fepriv->max_drift) {
252 fepriv->auto_step = 0;
253 fepriv->auto_sub_step = 0;
254 fepriv->lnb_drift = 0;
255 }
256
257 /* perform inversion and +/- zigzag */
258 switch(fepriv->auto_sub_step) {
259 case 0:
260 /* try with the current inversion and current drift setting */
261 ready = 1;
262 break;
263
264 case 1:
265 if (!autoinversion) break;
266
267 fepriv->inversion = (fepriv->inversion == INVERSION_OFF) ? INVERSION_ON : INVERSION_OFF;
268 ready = 1;
269 break;
270
271 case 2:
272 if (fepriv->lnb_drift == 0) break;
273
274 fepriv->lnb_drift = -fepriv->lnb_drift;
275 ready = 1;
276 break;
277
278 case 3:
279 if (fepriv->lnb_drift == 0) break;
280 if (!autoinversion) break;
281
282 fepriv->inversion = (fepriv->inversion == INVERSION_OFF) ? INVERSION_ON : INVERSION_OFF;
283 fepriv->lnb_drift = -fepriv->lnb_drift;
284 ready = 1;
285 break;
286
287 default:
288 fepriv->auto_step++;
289 fepriv->auto_sub_step = -1; /* it'll be incremented to 0 in a moment */
290 break;
291 }
292
293 if (!ready) fepriv->auto_sub_step++;
294 }
295
296 /* if this attempt would hit where we started, indicate a complete
297 * iteration has occurred */
298 if ((fepriv->auto_step == fepriv->started_auto_step) &&
299 (fepriv->auto_sub_step == 0) && check_wrapped) {
300 return 1;
301 }
302
303 dprintk("%s: drift:%i inversion:%i auto_step:%i "
304 "auto_sub_step:%i started_auto_step:%i\n",
305 __FUNCTION__, fepriv->lnb_drift, fepriv->inversion,
306 fepriv->auto_step, fepriv->auto_sub_step, fepriv->started_auto_step);
307
308 /* set the frontend itself */
309 fepriv->parameters.frequency += fepriv->lnb_drift;
310 if (autoinversion)
311 fepriv->parameters.inversion = fepriv->inversion;
312 if (fe->ops->set_frontend)
313 fe->ops->set_frontend(fe, &fepriv->parameters);
314
315 fepriv->parameters.frequency = original_frequency;
316 fepriv->parameters.inversion = original_inversion;
317
318 fepriv->auto_sub_step++;
319 return 0;
320}
321
322static int dvb_frontend_is_exiting(struct dvb_frontend *fe)
323{
324 struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv;
325
326 if (fepriv->exit)
327 return 1;
328
329 if (fepriv->dvbdev->writers == 1)
330 if (jiffies - fepriv->release_jiffies > dvb_shutdown_timeout * HZ)
331 return 1;
332
333 return 0;
334}
335
336static int dvb_frontend_should_wakeup(struct dvb_frontend *fe)
337{
338 struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv;
339
340 if (fepriv->wakeup) {
341 fepriv->wakeup = 0;
342 return 1;
343 }
344 return dvb_frontend_is_exiting(fe);
345}
346
347static void dvb_frontend_wakeup(struct dvb_frontend *fe)
348{
349 struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv;
350
351 fepriv->wakeup = 1;
352 wake_up_interruptible(&fepriv->wait_queue);
353}
354
355/*
356 * FIXME: use linux/kthread.h
357 */
358static int dvb_frontend_thread(void *data)
359{
360 struct dvb_frontend *fe = (struct dvb_frontend *) data;
361 struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv;
362 unsigned long timeout;
363 char name [15];
364 int quality = 0, delay = 3*HZ;
365 fe_status_t s;
366 int check_wrapped = 0;
367
368 dprintk("%s\n", __FUNCTION__);
369
370 snprintf (name, sizeof(name), "kdvb-fe-%i", fe->dvb->num);
371
372 lock_kernel();
373 daemonize(name);
374 sigfillset(&current->blocked);
375 unlock_kernel();
376
377 fepriv->status = 0;
378 dvb_frontend_init(fe);
379 fepriv->wakeup = 0;
380
381 while (1) {
382 up(&fepriv->sem); /* is locked when we enter the thread... */
383
384 timeout = wait_event_interruptible_timeout(fepriv->wait_queue,
385 dvb_frontend_should_wakeup(fe),
386 delay);
387 if (0 != dvb_frontend_is_exiting(fe)) {
388 /* got signal or quitting */
389 break;
390 }
391
392 if (current->flags & PF_FREEZE)
393 refrigerator(PF_FREEZE);
394
395 if (down_interruptible(&fepriv->sem))
396 break;
397
398 /* if we've got no parameters, just keep idling */
399 if (fepriv->state & FESTATE_IDLE) {
400 delay = 3*HZ;
401 quality = 0;
402 continue;
403 }
404
405 /* get the frontend status */
406 if (fepriv->state & FESTATE_RETUNE) {
407 s = 0;
408 } else {
409 if (fe->ops->read_status)
410 fe->ops->read_status(fe, &s);
411 if (s != fepriv->status) {
412 dvb_frontend_add_event(fe, s);
413 fepriv->status = s;
414 }
415 }
416 /* if we're not tuned, and we have a lock, move to the TUNED state */
417 if ((fepriv->state & FESTATE_WAITFORLOCK) && (s & FE_HAS_LOCK)) {
418 update_delay(&quality, &delay, fepriv->min_delay, s & FE_HAS_LOCK);
419 fepriv->state = FESTATE_TUNED;
420
421 /* if we're tuned, then we have determined the correct inversion */
422 if ((!(fe->ops->info.caps & FE_CAN_INVERSION_AUTO)) &&
423 (fepriv->parameters.inversion == INVERSION_AUTO)) {
424 fepriv->parameters.inversion = fepriv->inversion;
425 }
426 continue;
427 }
428
429 /* if we are tuned already, check we're still locked */
430 if (fepriv->state & FESTATE_TUNED) {
431 update_delay(&quality, &delay, fepriv->min_delay, s & FE_HAS_LOCK);
432
433 /* we're tuned, and the lock is still good... */
434 if (s & FE_HAS_LOCK)
435 continue;
436 else {
437 /* if we _WERE_ tuned, but now don't have a lock,
438 * need to zigzag */
439 fepriv->state = FESTATE_ZIGZAG_FAST;
440 fepriv->started_auto_step = fepriv->auto_step;
441 check_wrapped = 0;
442 }
443 }
444
445 /* don't actually do anything if we're in the LOSTLOCK state,
446 * the frontend is set to FE_CAN_RECOVER, and the max_drift is 0 */
447 if ((fepriv->state & FESTATE_LOSTLOCK) &&
448 (fe->ops->info.caps & FE_CAN_RECOVER) && (fepriv->max_drift == 0)) {
449 update_delay(&quality, &delay, fepriv->min_delay, s & FE_HAS_LOCK);
450 continue;
451 }
452
453 /* don't do anything if we're in the DISEQC state, since this
454 * might be someone with a motorized dish controlled by DISEQC.
455 * If its actually a re-tune, there will be a SET_FRONTEND soon enough. */
456 if (fepriv->state & FESTATE_DISEQC) {
457 update_delay(&quality, &delay, fepriv->min_delay, s & FE_HAS_LOCK);
458 continue;
459 }
460
461 /* if we're in the RETUNE state, set everything up for a brand
462 * new scan, keeping the current inversion setting, as the next
463 * tune is _very_ likely to require the same */
464 if (fepriv->state & FESTATE_RETUNE) {
465 fepriv->lnb_drift = 0;
466 fepriv->auto_step = 0;
467 fepriv->auto_sub_step = 0;
468 fepriv->started_auto_step = 0;
469 check_wrapped = 0;
470 }
471
472 /* fast zigzag. */
473 if ((fepriv->state & FESTATE_SEARCHING_FAST) || (fepriv->state & FESTATE_RETUNE)) {
474 delay = fepriv->min_delay;
475
476 /* peform a tune */
477 if (dvb_frontend_autotune(fe, check_wrapped)) {
478 /* OK, if we've run out of trials at the fast speed.
479 * Drop back to slow for the _next_ attempt */
480 fepriv->state = FESTATE_SEARCHING_SLOW;
481 fepriv->started_auto_step = fepriv->auto_step;
482 continue;
483 }
484 check_wrapped = 1;
485
486 /* if we've just retuned, enter the ZIGZAG_FAST state.
487 * This ensures we cannot return from an
488 * FE_SET_FRONTEND ioctl before the first frontend tune
489 * occurs */
490 if (fepriv->state & FESTATE_RETUNE) {
491 fepriv->state = FESTATE_TUNING_FAST;
492 }
493 }
494
495 /* slow zigzag */
496 if (fepriv->state & FESTATE_SEARCHING_SLOW) {
497 update_delay(&quality, &delay, fepriv->min_delay, s & FE_HAS_LOCK);
498
499 /* Note: don't bother checking for wrapping; we stay in this
500 * state until we get a lock */
501 dvb_frontend_autotune(fe, 0);
502 }
503 }
504
505 if (dvb_shutdown_timeout) {
506 if (dvb_powerdown_on_sleep)
507 if (fe->ops->set_voltage)
508 fe->ops->set_voltage(fe, SEC_VOLTAGE_OFF);
509 if (fe->ops->sleep)
510 fe->ops->sleep(fe);
511 }
512
513 fepriv->thread_pid = 0;
514 mb();
515
516 dvb_frontend_wakeup(fe);
517 return 0;
518}
519
520static void dvb_frontend_stop(struct dvb_frontend *fe)
521{
522 unsigned long ret;
523 struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv;
524
525 dprintk ("%s\n", __FUNCTION__);
526
527 fepriv->exit = 1;
528 mb();
529
530 if (!fepriv->thread_pid)
531 return;
532
533 /* check if the thread is really alive */
534 if (kill_proc(fepriv->thread_pid, 0, 1) == -ESRCH) {
535 printk("dvb_frontend_stop: thread PID %d already died\n",
536 fepriv->thread_pid);
537 /* make sure the mutex was not held by the thread */
538 init_MUTEX (&fepriv->sem);
539 return;
540 }
541
542 /* wake up the frontend thread, so it notices that fe->exit == 1 */
543 dvb_frontend_wakeup(fe);
544
545 /* wait until the frontend thread has exited */
546 ret = wait_event_interruptible(fepriv->wait_queue,0 == fepriv->thread_pid);
547 if (-ERESTARTSYS != ret) {
548 fepriv->state = FESTATE_IDLE;
549 return;
550 }
551 fepriv->state = FESTATE_IDLE;
552
553 /* paranoia check in case a signal arrived */
554 if (fepriv->thread_pid)
555 printk("dvb_frontend_stop: warning: thread PID %d won't exit\n",
556 fepriv->thread_pid);
557}
558
559static int dvb_frontend_start(struct dvb_frontend *fe)
560{
561 int ret;
562 struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv;
563
564 dprintk ("%s\n", __FUNCTION__);
565
566 if (fepriv->thread_pid) {
567 if (!fepriv->exit)
568 return 0;
569 else
570 dvb_frontend_stop (fe);
571 }
572
573 if (signal_pending(current))
574 return -EINTR;
575 if (down_interruptible (&fepriv->sem))
576 return -EINTR;
577
578 fepriv->state = FESTATE_IDLE;
579 fepriv->exit = 0;
580 fepriv->thread_pid = 0;
581 mb();
582
583 ret = kernel_thread (dvb_frontend_thread, fe, 0);
584
585 if (ret < 0) {
586 printk("dvb_frontend_start: failed to start kernel_thread (%d)\n", ret);
587 up(&fepriv->sem);
588 return ret;
589 }
590 fepriv->thread_pid = ret;
591
592 return 0;
593}
594
595static int dvb_frontend_ioctl(struct inode *inode, struct file *file,
596 unsigned int cmd, void *parg)
597{
598 struct dvb_device *dvbdev = file->private_data;
599 struct dvb_frontend *fe = dvbdev->priv;
600 struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv;
601 int err = -EOPNOTSUPP;
602
603 dprintk ("%s\n", __FUNCTION__);
604
605 if (!fe || fepriv->exit)
606 return -ENODEV;
607
608 if ((file->f_flags & O_ACCMODE) == O_RDONLY &&
609 (_IOC_DIR(cmd) != _IOC_READ || cmd == FE_GET_EVENT ||
610 cmd == FE_DISEQC_RECV_SLAVE_REPLY))
611 return -EPERM;
612
613 if (down_interruptible (&fepriv->sem))
614 return -ERESTARTSYS;
615
616 switch (cmd) {
617 case FE_GET_INFO: {
618 struct dvb_frontend_info* info = (struct dvb_frontend_info*) parg;
619 memcpy(info, &fe->ops->info, sizeof(struct dvb_frontend_info));
620
621 /* Force the CAN_INVERSION_AUTO bit on. If the frontend doesn't
622 * do it, it is done for it. */
623 info->caps |= FE_CAN_INVERSION_AUTO;
624 err = 0;
625 break;
626 }
627
628 case FE_READ_STATUS:
629 if (fe->ops->read_status)
630 err = fe->ops->read_status(fe, (fe_status_t*) parg);
631 break;
632
633 case FE_READ_BER:
634 if (fe->ops->read_ber)
635 err = fe->ops->read_ber(fe, (__u32*) parg);
636 break;
637
638 case FE_READ_SIGNAL_STRENGTH:
639 if (fe->ops->read_signal_strength)
640 err = fe->ops->read_signal_strength(fe, (__u16*) parg);
641 break;
642
643 case FE_READ_SNR:
644 if (fe->ops->read_snr)
645 err = fe->ops->read_snr(fe, (__u16*) parg);
646 break;
647
648 case FE_READ_UNCORRECTED_BLOCKS:
649 if (fe->ops->read_ucblocks)
650 err = fe->ops->read_ucblocks(fe, (__u32*) parg);
651 break;
652
653
654 case FE_DISEQC_RESET_OVERLOAD:
655 if (fe->ops->diseqc_reset_overload) {
656 err = fe->ops->diseqc_reset_overload(fe);
657 fepriv->state = FESTATE_DISEQC;
658 fepriv->status = 0;
659 }
660 break;
661
662 case FE_DISEQC_SEND_MASTER_CMD:
663 if (fe->ops->diseqc_send_master_cmd) {
664 err = fe->ops->diseqc_send_master_cmd(fe, (struct dvb_diseqc_master_cmd*) parg);
665 fepriv->state = FESTATE_DISEQC;
666 fepriv->status = 0;
667 }
668 break;
669
670 case FE_DISEQC_SEND_BURST:
671 if (fe->ops->diseqc_send_burst) {
672 err = fe->ops->diseqc_send_burst(fe, (fe_sec_mini_cmd_t) parg);
673 fepriv->state = FESTATE_DISEQC;
674 fepriv->status = 0;
675 }
676 break;
677
678 case FE_SET_TONE:
679 if (fe->ops->set_tone) {
680 err = fe->ops->set_tone(fe, (fe_sec_tone_mode_t) parg);
681 fepriv->state = FESTATE_DISEQC;
682 fepriv->status = 0;
683 }
684 break;
685
686 case FE_SET_VOLTAGE:
687 if (fe->ops->set_voltage) {
688 err = fe->ops->set_voltage(fe, (fe_sec_voltage_t) parg);
689 fepriv->state = FESTATE_DISEQC;
690 fepriv->status = 0;
691 }
692 break;
693
694 case FE_DISHNETWORK_SEND_LEGACY_CMD:
695 if (fe->ops->dishnetwork_send_legacy_command) {
696 err = fe->ops->dishnetwork_send_legacy_command(fe, (unsigned int) parg);
697 fepriv->state = FESTATE_DISEQC;
698 fepriv->status = 0;
699 }
700 break;
701
702 case FE_DISEQC_RECV_SLAVE_REPLY:
703 if (fe->ops->diseqc_recv_slave_reply)
704 err = fe->ops->diseqc_recv_slave_reply(fe, (struct dvb_diseqc_slave_reply*) parg);
705 break;
706
707 case FE_ENABLE_HIGH_LNB_VOLTAGE:
708 if (fe->ops->enable_high_lnb_voltage)
709 err = fe->ops->enable_high_lnb_voltage(fe, (int) parg);
710 break;
711
712 case FE_SET_FRONTEND: {
713 struct dvb_frontend_tune_settings fetunesettings;
714
715 memcpy (&fepriv->parameters, parg,
716 sizeof (struct dvb_frontend_parameters));
717
718 memset(&fetunesettings, 0, sizeof(struct dvb_frontend_tune_settings));
719 memcpy(&fetunesettings.parameters, parg,
720 sizeof (struct dvb_frontend_parameters));
721
722 /* force auto frequency inversion if requested */
723 if (dvb_force_auto_inversion) {
724 fepriv->parameters.inversion = INVERSION_AUTO;
725 fetunesettings.parameters.inversion = INVERSION_AUTO;
726 }
727 if (fe->ops->info.type == FE_OFDM) {
728 /* without hierachical coding code_rate_LP is irrelevant,
729 * so we tolerate the otherwise invalid FEC_NONE setting */
730 if (fepriv->parameters.u.ofdm.hierarchy_information == HIERARCHY_NONE &&
731 fepriv->parameters.u.ofdm.code_rate_LP == FEC_NONE)
732 fepriv->parameters.u.ofdm.code_rate_LP = FEC_AUTO;
733 }
734
735 /* get frontend-specific tuning settings */
736 if (fe->ops->get_tune_settings && (fe->ops->get_tune_settings(fe, &fetunesettings) == 0)) {
737 fepriv->min_delay = (fetunesettings.min_delay_ms * HZ) / 1000;
738 fepriv->max_drift = fetunesettings.max_drift;
739 fepriv->step_size = fetunesettings.step_size;
740 } else {
741 /* default values */
742 switch(fe->ops->info.type) {
743 case FE_QPSK:
744 fepriv->min_delay = HZ/20;
745 fepriv->step_size = fepriv->parameters.u.qpsk.symbol_rate / 16000;
746 fepriv->max_drift = fepriv->parameters.u.qpsk.symbol_rate / 2000;
747 break;
748
749 case FE_QAM:
750 fepriv->min_delay = HZ/20;
751 fepriv->step_size = 0; /* no zigzag */
752 fepriv->max_drift = 0;
753 break;
754
755 case FE_OFDM:
756 fepriv->min_delay = HZ/20;
757 fepriv->step_size = fe->ops->info.frequency_stepsize * 2;
758 fepriv->max_drift = (fe->ops->info.frequency_stepsize * 2) + 1;
759 break;
760 case FE_ATSC:
761 printk("dvb-core: FE_ATSC not handled yet.\n");
762 break;
763 }
764 }
765 if (dvb_override_tune_delay > 0)
766 fepriv->min_delay = (dvb_override_tune_delay * HZ) / 1000;
767
768 fepriv->state = FESTATE_RETUNE;
769 dvb_frontend_wakeup(fe);
770 dvb_frontend_add_event(fe, 0);
771 fepriv->status = 0;
772 err = 0;
773 break;
774 }
775
776 case FE_GET_EVENT:
777 err = dvb_frontend_get_event (fe, parg, file->f_flags);
778 break;
779
780 case FE_GET_FRONTEND:
781 if (fe->ops->get_frontend) {
782 memcpy (parg, &fepriv->parameters, sizeof (struct dvb_frontend_parameters));
783 err = fe->ops->get_frontend(fe, (struct dvb_frontend_parameters*) parg);
784 }
785 break;
786 };
787
788 up (&fepriv->sem);
789 return err;
790}
791
792static unsigned int dvb_frontend_poll(struct file *file, struct poll_table_struct *wait)
793{
794 struct dvb_device *dvbdev = file->private_data;
795 struct dvb_frontend *fe = dvbdev->priv;
796 struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv;
797
798 dprintk ("%s\n", __FUNCTION__);
799
800 poll_wait (file, &fepriv->events.wait_queue, wait);
801
802 if (fepriv->events.eventw != fepriv->events.eventr)
803 return (POLLIN | POLLRDNORM | POLLPRI);
804
805 return 0;
806}
807
808static int dvb_frontend_open(struct inode *inode, struct file *file)
809{
810 struct dvb_device *dvbdev = file->private_data;
811 struct dvb_frontend *fe = dvbdev->priv;
812 struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv;
813 int ret;
814
815 dprintk ("%s\n", __FUNCTION__);
816
817 if ((ret = dvb_generic_open (inode, file)) < 0)
818 return ret;
819
820 if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
821 ret = dvb_frontend_start (fe);
822 if (ret)
823 dvb_generic_release (inode, file);
824
825 /* empty event queue */
826 fepriv->events.eventr = fepriv->events.eventw = 0;
827 }
828
829 return ret;
830}
831
832static int dvb_frontend_release(struct inode *inode, struct file *file)
833{
834 struct dvb_device *dvbdev = file->private_data;
835 struct dvb_frontend *fe = dvbdev->priv;
836 struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv;
837
838 dprintk ("%s\n", __FUNCTION__);
839
840 if ((file->f_flags & O_ACCMODE) != O_RDONLY)
841 fepriv->release_jiffies = jiffies;
842
843 return dvb_generic_release (inode, file);
844}
845
846static struct file_operations dvb_frontend_fops = {
847 .owner = THIS_MODULE,
848 .ioctl = dvb_generic_ioctl,
849 .poll = dvb_frontend_poll,
850 .open = dvb_frontend_open,
851 .release = dvb_frontend_release
852};
853
854int dvb_register_frontend(struct dvb_adapter* dvb,
855 struct dvb_frontend* fe)
856{
857 struct dvb_frontend_private *fepriv;
858 static const struct dvb_device dvbdev_template = {
859 .users = ~0,
860 .writers = 1,
861 .readers = (~0)-1,
862 .fops = &dvb_frontend_fops,
863 .kernel_ioctl = dvb_frontend_ioctl
864 };
865
866 dprintk ("%s\n", __FUNCTION__);
867
868 if (down_interruptible (&frontend_mutex))
869 return -ERESTARTSYS;
870
871 fe->frontend_priv = kmalloc(sizeof(struct dvb_frontend_private), GFP_KERNEL);
872 if (fe->frontend_priv == NULL) {
873 up(&frontend_mutex);
874 return -ENOMEM;
875 }
876 fepriv = (struct dvb_frontend_private*) fe->frontend_priv;
877 memset(fe->frontend_priv, 0, sizeof(struct dvb_frontend_private));
878
879 init_MUTEX (&fepriv->sem);
880 init_waitqueue_head (&fepriv->wait_queue);
881 init_waitqueue_head (&fepriv->events.wait_queue);
882 init_MUTEX (&fepriv->events.sem);
883 fe->dvb = dvb;
884 fepriv->inversion = INVERSION_OFF;
885
886 printk ("DVB: registering frontend %i (%s)...\n",
887 fe->dvb->num,
888 fe->ops->info.name);
889
890 dvb_register_device (fe->dvb, &fepriv->dvbdev, &dvbdev_template,
891 fe, DVB_DEVICE_FRONTEND);
892
893 up (&frontend_mutex);
894 return 0;
895}
896EXPORT_SYMBOL(dvb_register_frontend);
897
898int dvb_unregister_frontend(struct dvb_frontend* fe)
899{
900 struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv;
901 dprintk ("%s\n", __FUNCTION__);
902
903 down (&frontend_mutex);
904 dvb_unregister_device (fepriv->dvbdev);
905 dvb_frontend_stop (fe);
906 if (fe->ops->release)
907 fe->ops->release(fe);
908 else
909 printk("dvb_frontend: Demodulator (%s) does not have a release callback!\n", fe->ops->info.name);
910 /* fe is invalid now */
911 kfree(fepriv);
912 up (&frontend_mutex);
913 return 0;
914}
915EXPORT_SYMBOL(dvb_unregister_frontend);
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.h b/drivers/media/dvb/dvb-core/dvb_frontend.h
new file mode 100644
index 000000000000..d2b021792791
--- /dev/null
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.h
@@ -0,0 +1,126 @@
1/*
2 * dvb_frontend.h
3 *
4 * Copyright (C) 2001 convergence integrated media GmbH
5 * Copyright (C) 2004 convergence GmbH
6 *
7 * Written by Ralph Metzler
8 * Overhauled by Holger Waechtler
9 * Kernel I2C stuff by Michael Hunold <hunold@convergence.de>
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public License
13 * as published by the Free Software Foundation; either version 2.1
14 * of the License, or (at your option) any later version.
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 Lesser 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 *
26 */
27
28#ifndef _DVB_FRONTEND_H_
29#define _DVB_FRONTEND_H_
30
31#include <linux/types.h>
32#include <linux/sched.h>
33#include <linux/ioctl.h>
34#include <linux/i2c.h>
35#include <linux/module.h>
36#include <linux/errno.h>
37#include <linux/delay.h>
38
39#include <linux/dvb/frontend.h>
40
41#include "dvbdev.h"
42
43/* FIXME: Move to i2c-id.h */
44#define I2C_DRIVERID_DVBFE_SP8870 I2C_DRIVERID_EXP2
45#define I2C_DRIVERID_DVBFE_CX22700 I2C_DRIVERID_EXP2
46#define I2C_DRIVERID_DVBFE_AT76C651 I2C_DRIVERID_EXP2
47#define I2C_DRIVERID_DVBFE_CX24110 I2C_DRIVERID_EXP2
48#define I2C_DRIVERID_DVBFE_CX22702 I2C_DRIVERID_EXP2
49#define I2C_DRIVERID_DVBFE_DIB3000MB I2C_DRIVERID_EXP2
50#define I2C_DRIVERID_DVBFE_DST I2C_DRIVERID_EXP2
51#define I2C_DRIVERID_DVBFE_DUMMY I2C_DRIVERID_EXP2
52#define I2C_DRIVERID_DVBFE_L64781 I2C_DRIVERID_EXP2
53#define I2C_DRIVERID_DVBFE_MT312 I2C_DRIVERID_EXP2
54#define I2C_DRIVERID_DVBFE_MT352 I2C_DRIVERID_EXP2
55#define I2C_DRIVERID_DVBFE_NXT6000 I2C_DRIVERID_EXP2
56#define I2C_DRIVERID_DVBFE_SP887X I2C_DRIVERID_EXP2
57#define I2C_DRIVERID_DVBFE_STV0299 I2C_DRIVERID_EXP2
58#define I2C_DRIVERID_DVBFE_TDA1004X I2C_DRIVERID_EXP2
59#define I2C_DRIVERID_DVBFE_TDA8083 I2C_DRIVERID_EXP2
60#define I2C_DRIVERID_DVBFE_VES1820 I2C_DRIVERID_EXP2
61#define I2C_DRIVERID_DVBFE_VES1X93 I2C_DRIVERID_EXP2
62#define I2C_DRIVERID_DVBFE_TDA80XX I2C_DRIVERID_EXP2
63
64
65struct dvb_frontend_tune_settings {
66 int min_delay_ms;
67 int step_size;
68 int max_drift;
69 struct dvb_frontend_parameters parameters;
70};
71
72struct dvb_frontend;
73
74struct dvb_frontend_ops {
75
76 struct dvb_frontend_info info;
77
78 void (*release)(struct dvb_frontend* fe);
79
80 int (*init)(struct dvb_frontend* fe);
81 int (*sleep)(struct dvb_frontend* fe);
82
83 int (*set_frontend)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
84 int (*get_frontend)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
85 int (*get_tune_settings)(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* settings);
86
87 int (*read_status)(struct dvb_frontend* fe, fe_status_t* status);
88 int (*read_ber)(struct dvb_frontend* fe, u32* ber);
89 int (*read_signal_strength)(struct dvb_frontend* fe, u16* strength);
90 int (*read_snr)(struct dvb_frontend* fe, u16* snr);
91 int (*read_ucblocks)(struct dvb_frontend* fe, u32* ucblocks);
92
93 int (*diseqc_reset_overload)(struct dvb_frontend* fe);
94 int (*diseqc_send_master_cmd)(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd);
95 int (*diseqc_recv_slave_reply)(struct dvb_frontend* fe, struct dvb_diseqc_slave_reply* reply);
96 int (*diseqc_send_burst)(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd);
97 int (*set_tone)(struct dvb_frontend* fe, fe_sec_tone_mode_t tone);
98 int (*set_voltage)(struct dvb_frontend* fe, fe_sec_voltage_t voltage);
99 int (*enable_high_lnb_voltage)(struct dvb_frontend* fe, int arg);
100 int (*dishnetwork_send_legacy_command)(struct dvb_frontend* fe, unsigned int cmd);
101};
102
103#define MAX_EVENT 8
104
105struct dvb_fe_events {
106 struct dvb_frontend_event events[MAX_EVENT];
107 int eventw;
108 int eventr;
109 int overflow;
110 wait_queue_head_t wait_queue;
111 struct semaphore sem;
112};
113
114struct dvb_frontend {
115 struct dvb_frontend_ops* ops;
116 struct dvb_adapter *dvb;
117 void* demodulator_priv;
118 void* frontend_priv;
119};
120
121extern int dvb_register_frontend(struct dvb_adapter* dvb,
122 struct dvb_frontend* fe);
123
124extern int dvb_unregister_frontend(struct dvb_frontend* fe);
125
126#endif
diff --git a/drivers/media/dvb/dvb-core/dvb_net.c b/drivers/media/dvb/dvb-core/dvb_net.c
new file mode 100644
index 000000000000..44892e7abd3d
--- /dev/null
+++ b/drivers/media/dvb/dvb-core/dvb_net.c
@@ -0,0 +1,1381 @@
1/*
2 * dvb_net.c
3 *
4 * Copyright (C) 2001 Convergence integrated media GmbH
5 * Ralph Metzler <ralph@convergence.de>
6 * Copyright (C) 2002 Ralph Metzler <rjkm@metzlerbros.de>
7 *
8 * ULE Decapsulation code:
9 * Copyright (C) 2003, 2004 gcs - Global Communication & Services GmbH.
10 * and Department of Scientific Computing
11 * Paris Lodron University of Salzburg.
12 * Hilmar Linder <hlinder@cosy.sbg.ac.at>
13 * and Wolfram Stering <wstering@cosy.sbg.ac.at>
14 *
15 * ULE Decaps according to draft-ietf-ipdvb-ule-03.txt.
16 *
17 * This program is free software; you can redistribute it and/or
18 * modify it under the terms of the GNU General Public License
19 * as published by the Free Software Foundation; either version 2
20 * of the License, or (at your option) any later version.
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 * 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/*
34 * ULE ChangeLog:
35 * Feb 2004: hl/ws v1: Implementing draft-fair-ipdvb-ule-01.txt
36 *
37 * Dec 2004: hl/ws v2: Implementing draft-ietf-ipdvb-ule-03.txt:
38 * ULE Extension header handling.
39 * Bugreports by Moritz Vieth and Hanno Tersteegen,
40 * Fraunhofer Institute for Open Communication Systems
41 * Competence Center for Advanced Satellite Communications.
42 * Bugfixes and robustness improvements.
43 * Filtering on dest MAC addresses, if present (D-Bit = 0)
44 * ULE_DEBUG compile-time option.
45 */
46
47/*
48 * FIXME / TODO (dvb_net.c):
49 *
50 * Unloading does not work for 2.6.9 kernels: a refcount doesn't go to zero.
51 *
52 * TS_FEED callback is called once for every single TS cell although it is
53 * registered (in dvb_net_feed_start()) for 100 TS cells (used for dvb_net_ule()).
54 *
55 */
56
57#include <linux/module.h>
58#include <linux/kernel.h>
59#include <linux/netdevice.h>
60#include <linux/etherdevice.h>
61#include <linux/dvb/net.h>
62#include <linux/uio.h>
63#include <asm/uaccess.h>
64#include <linux/crc32.h>
65#include <linux/version.h>
66
67#include "dvb_demux.h"
68#include "dvb_net.h"
69
70static int dvb_net_debug;
71module_param(dvb_net_debug, int, 0444);
72MODULE_PARM_DESC(dvb_net_debug, "enable debug messages");
73
74#define dprintk(x...) do { if (dvb_net_debug) printk(x); } while (0)
75
76
77static inline __u32 iov_crc32( __u32 c, struct kvec *iov, unsigned int cnt )
78{
79 unsigned int j;
80 for (j = 0; j < cnt; j++)
81 c = crc32_be( c, iov[j].iov_base, iov[j].iov_len );
82 return c;
83}
84
85
86#define DVB_NET_MULTICAST_MAX 10
87
88#undef ULE_DEBUG
89
90#ifdef ULE_DEBUG
91
92#define isprint(c) ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9'))
93
94static void hexdump( const unsigned char *buf, unsigned short len )
95{
96 char str[80], octet[10];
97 int ofs, i, l;
98
99 for (ofs = 0; ofs < len; ofs += 16) {
100 sprintf( str, "%03d: ", ofs );
101
102 for (i = 0; i < 16; i++) {
103 if ((i + ofs) < len)
104 sprintf( octet, "%02x ", buf[ofs + i] );
105 else
106 strcpy( octet, " " );
107
108 strcat( str, octet );
109 }
110 strcat( str, " " );
111 l = strlen( str );
112
113 for (i = 0; (i < 16) && ((i + ofs) < len); i++)
114 str[l++] = isprint( buf[ofs + i] ) ? buf[ofs + i] : '.';
115
116 str[l] = '\0';
117 printk( KERN_WARNING "%s\n", str );
118 }
119}
120
121#endif
122
123struct dvb_net_priv {
124 int in_use;
125 struct net_device_stats stats;
126 u16 pid;
127 struct dvb_net *host;
128 struct dmx_demux *demux;
129 struct dmx_section_feed *secfeed;
130 struct dmx_section_filter *secfilter;
131 struct dmx_ts_feed *tsfeed;
132 int multi_num;
133 struct dmx_section_filter *multi_secfilter[DVB_NET_MULTICAST_MAX];
134 unsigned char multi_macs[DVB_NET_MULTICAST_MAX][6];
135 int rx_mode;
136#define RX_MODE_UNI 0
137#define RX_MODE_MULTI 1
138#define RX_MODE_ALL_MULTI 2
139#define RX_MODE_PROMISC 3
140 struct work_struct set_multicast_list_wq;
141 struct work_struct restart_net_feed_wq;
142 unsigned char feedtype; /* Either FEED_TYPE_ or FEED_TYPE_ULE */
143 int need_pusi; /* Set to 1, if synchronization on PUSI required. */
144 unsigned char tscc; /* TS continuity counter after sync on PUSI. */
145 struct sk_buff *ule_skb; /* ULE SNDU decodes into this buffer. */
146 unsigned char *ule_next_hdr; /* Pointer into skb to next ULE extension header. */
147 unsigned short ule_sndu_len; /* ULE SNDU length in bytes, w/o D-Bit. */
148 unsigned short ule_sndu_type; /* ULE SNDU type field, complete. */
149 unsigned char ule_sndu_type_1; /* ULE SNDU type field, if split across 2 TS cells. */
150 unsigned char ule_dbit; /* Whether the DestMAC address present
151 * or not (bit is set). */
152 unsigned char ule_bridged; /* Whether the ULE_BRIDGED extension header was found. */
153 int ule_sndu_remain; /* Nr. of bytes still required for current ULE SNDU. */
154 unsigned long ts_count; /* Current ts cell counter. */
155};
156
157
158/**
159 * Determine the packet's protocol ID. The rule here is that we
160 * assume 802.3 if the type field is short enough to be a length.
161 * This is normal practice and works for any 'now in use' protocol.
162 *
163 * stolen from eth.c out of the linux kernel, hacked for dvb-device
164 * by Michael Holzt <kju@debian.org>
165 */
166static unsigned short dvb_net_eth_type_trans(struct sk_buff *skb,
167 struct net_device *dev)
168{
169 struct ethhdr *eth;
170 unsigned char *rawp;
171
172 skb->mac.raw=skb->data;
173 skb_pull(skb,dev->hard_header_len);
174#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,8)
175 eth = skb->mac.ethernet;
176#else
177 eth = eth_hdr(skb);
178#endif
179
180 if (*eth->h_dest & 1) {
181 if(memcmp(eth->h_dest,dev->broadcast, ETH_ALEN)==0)
182 skb->pkt_type=PACKET_BROADCAST;
183 else
184 skb->pkt_type=PACKET_MULTICAST;
185 }
186
187 if (ntohs(eth->h_proto) >= 1536)
188 return eth->h_proto;
189
190 rawp = skb->data;
191
192 /**
193 * This is a magic hack to spot IPX packets. Older Novell breaks
194 * the protocol design and runs IPX over 802.3 without an 802.2 LLC
195 * layer. We look for FFFF which isn't a used 802.2 SSAP/DSAP. This
196 * won't work for fault tolerant netware but does for the rest.
197 */
198 if (*(unsigned short *)rawp == 0xFFFF)
199 return htons(ETH_P_802_3);
200
201 /**
202 * Real 802.2 LLC
203 */
204 return htons(ETH_P_802_2);
205}
206
207#define TS_SZ 188
208#define TS_SYNC 0x47
209#define TS_TEI 0x80
210#define TS_SC 0xC0
211#define TS_PUSI 0x40
212#define TS_AF_A 0x20
213#define TS_AF_D 0x10
214
215/* ULE Extension Header handlers. */
216
217#define ULE_TEST 0
218#define ULE_BRIDGED 1
219
220static int ule_test_sndu( struct dvb_net_priv *p )
221{
222 return -1;
223}
224
225static int ule_bridged_sndu( struct dvb_net_priv *p )
226{
227 /* BRIDGE SNDU handling sucks in draft-ietf-ipdvb-ule-03.txt.
228 * This has to be the last extension header, otherwise it won't work.
229 * Blame the authors!
230 */
231 p->ule_bridged = 1;
232 return 0;
233}
234
235
236/** Handle ULE extension headers.
237 * Function is called after a successful CRC32 verification of an ULE SNDU to complete its decoding.
238 * Returns: >= 0: nr. of bytes consumed by next extension header
239 * -1: Mandatory extension header that is not recognized or TEST SNDU; discard.
240 */
241static int handle_one_ule_extension( struct dvb_net_priv *p )
242{
243 /* Table of mandatory extension header handlers. The header type is the index. */
244 static int (*ule_mandatory_ext_handlers[255])( struct dvb_net_priv *p ) =
245 { [0] = ule_test_sndu, [1] = ule_bridged_sndu, [2] = NULL, };
246
247 /* Table of optional extension header handlers. The header type is the index. */
248 static int (*ule_optional_ext_handlers[255])( struct dvb_net_priv *p ) = { NULL, };
249
250 int ext_len = 0;
251 unsigned char hlen = (p->ule_sndu_type & 0x0700) >> 8;
252 unsigned char htype = p->ule_sndu_type & 0x00FF;
253
254 /* Discriminate mandatory and optional extension headers. */
255 if (hlen == 0) {
256 /* Mandatory extension header */
257 if (ule_mandatory_ext_handlers[htype]) {
258 ext_len = ule_mandatory_ext_handlers[htype]( p );
259 p->ule_next_hdr += ext_len;
260 if (! p->ule_bridged) {
261 p->ule_sndu_type = ntohs( *(unsigned short *)p->ule_next_hdr );
262 p->ule_next_hdr += 2;
263 } else {
264 p->ule_sndu_type = ntohs( *(unsigned short *)(p->ule_next_hdr + ((p->ule_dbit ? 2 : 3) * ETH_ALEN)) );
265 /* This assures the extension handling loop will terminate. */
266 }
267 } else
268 ext_len = -1; /* SNDU has to be discarded. */
269 } else {
270 /* Optional extension header. Calculate the length. */
271 ext_len = hlen << 2;
272 /* Process the optional extension header according to its type. */
273 if (ule_optional_ext_handlers[htype])
274 (void)ule_optional_ext_handlers[htype]( p );
275 p->ule_next_hdr += ext_len;
276 p->ule_sndu_type = ntohs( *(unsigned short *)p->ule_next_hdr );
277 p->ule_next_hdr += 2;
278 }
279
280 return ext_len;
281}
282
283static int handle_ule_extensions( struct dvb_net_priv *p )
284{
285 int total_ext_len = 0, l;
286
287 p->ule_next_hdr = p->ule_skb->data;
288 do {
289 l = handle_one_ule_extension( p );
290 if (l == -1) return -1; /* Stop extension header processing and discard SNDU. */
291 total_ext_len += l;
292
293 } while (p->ule_sndu_type < 1536);
294
295 return total_ext_len;
296}
297
298
299/** Prepare for a new ULE SNDU: reset the decoder state. */
300static inline void reset_ule( struct dvb_net_priv *p )
301{
302 p->ule_skb = NULL;
303 p->ule_next_hdr = NULL;
304 p->ule_sndu_len = 0;
305 p->ule_sndu_type = 0;
306 p->ule_sndu_type_1 = 0;
307 p->ule_sndu_remain = 0;
308 p->ule_dbit = 0xFF;
309 p->ule_bridged = 0;
310}
311
312/**
313 * Decode ULE SNDUs according to draft-ietf-ipdvb-ule-03.txt from a sequence of
314 * TS cells of a single PID.
315 */
316static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len )
317{
318 struct dvb_net_priv *priv = (struct dvb_net_priv *)dev->priv;
319 unsigned long skipped = 0L;
320 u8 *ts, *ts_end, *from_where = NULL, ts_remain = 0, how_much = 0, new_ts = 1;
321 struct ethhdr *ethh = NULL;
322
323#ifdef ULE_DEBUG
324 /* The code inside ULE_DEBUG keeps a history of the last 100 TS cells processed. */
325 static unsigned char ule_hist[100*TS_SZ];
326 static unsigned char *ule_where = ule_hist, ule_dump = 0;
327#endif
328
329 if (dev == NULL) {
330 printk( KERN_ERR "NO netdev struct!\n" );
331 return;
332 }
333
334 /* For all TS cells in current buffer.
335 * Appearently, we are called for every single TS cell.
336 */
337 for (ts = (char *)buf, ts_end = (char *)buf + buf_len; ts < ts_end; /* no default incr. */ ) {
338
339 if (new_ts) {
340 /* We are about to process a new TS cell. */
341
342#ifdef ULE_DEBUG
343 if (ule_where >= &ule_hist[100*TS_SZ]) ule_where = ule_hist;
344 memcpy( ule_where, ts, TS_SZ );
345 if (ule_dump) {
346 hexdump( ule_where, TS_SZ );
347 ule_dump = 0;
348 }
349 ule_where += TS_SZ;
350#endif
351
352 /* Check TS error conditions: sync_byte, transport_error_indicator, scrambling_control . */
353 if ((ts[0] != TS_SYNC) || (ts[1] & TS_TEI) || ((ts[3] & TS_SC) != 0)) {
354 printk(KERN_WARNING "%lu: Invalid TS cell: SYNC %#x, TEI %u, SC %#x.\n",
355 priv->ts_count, ts[0], ts[1] & TS_TEI >> 7, ts[3] & 0xC0 >> 6);
356
357 /* Drop partly decoded SNDU, reset state, resync on PUSI. */
358 if (priv->ule_skb) {
359 dev_kfree_skb( priv->ule_skb );
360 /* Prepare for next SNDU. */
361 ((struct dvb_net_priv *) dev->priv)->stats.rx_errors++;
362 ((struct dvb_net_priv *) dev->priv)->stats.rx_frame_errors++;
363 }
364 reset_ule(priv);
365 priv->need_pusi = 1;
366
367 /* Continue with next TS cell. */
368 ts += TS_SZ;
369 priv->ts_count++;
370 continue;
371 }
372
373 ts_remain = 184;
374 from_where = ts + 4;
375 }
376 /* Synchronize on PUSI, if required. */
377 if (priv->need_pusi) {
378 if (ts[1] & TS_PUSI) {
379 /* Find beginning of first ULE SNDU in current TS cell. */
380 /* Synchronize continuity counter. */
381 priv->tscc = ts[3] & 0x0F;
382 /* There is a pointer field here. */
383 if (ts[4] > ts_remain) {
384 printk(KERN_ERR "%lu: Invalid ULE packet "
385 "(pointer field %d)\n", priv->ts_count, ts[4]);
386 ts += TS_SZ;
387 priv->ts_count++;
388 continue;
389 }
390 /* Skip to destination of pointer field. */
391 from_where = &ts[5] + ts[4];
392 ts_remain -= 1 + ts[4];
393 skipped = 0;
394 } else {
395 skipped++;
396 ts += TS_SZ;
397 priv->ts_count++;
398 continue;
399 }
400 }
401
402 /* Check continuity counter. */
403 if (new_ts) {
404 if ((ts[3] & 0x0F) == priv->tscc)
405 priv->tscc = (priv->tscc + 1) & 0x0F;
406 else {
407 /* TS discontinuity handling: */
408 printk(KERN_WARNING "%lu: TS discontinuity: got %#x, "
409 "exptected %#x.\n", priv->ts_count, ts[3] & 0x0F, priv->tscc);
410 /* Drop partly decoded SNDU, reset state, resync on PUSI. */
411 if (priv->ule_skb) {
412 dev_kfree_skb( priv->ule_skb );
413 /* Prepare for next SNDU. */
414 // reset_ule(priv); moved to below.
415 ((struct dvb_net_priv *) dev->priv)->stats.rx_errors++;
416 ((struct dvb_net_priv *) dev->priv)->stats.rx_frame_errors++;
417 }
418 reset_ule(priv);
419 /* skip to next PUSI. */
420 priv->need_pusi = 1;
421 ts += TS_SZ;
422 priv->ts_count++;
423 continue;
424 }
425 /* If we still have an incomplete payload, but PUSI is
426 * set; some TS cells are missing.
427 * This is only possible here, if we missed exactly 16 TS
428 * cells (continuity counter wrap). */
429 if (ts[1] & TS_PUSI) {
430 if (! priv->need_pusi) {
431 if (*from_where > 181) {
432 /* Pointer field is invalid. Drop this TS cell and any started ULE SNDU. */
433 printk(KERN_WARNING "%lu: Invalid pointer "
434 "field: %u.\n", priv->ts_count, *from_where);
435
436 /* Drop partly decoded SNDU, reset state, resync on PUSI. */
437 if (priv->ule_skb) {
438 dev_kfree_skb( priv->ule_skb );
439 ((struct dvb_net_priv *) dev->priv)->stats.rx_errors++;
440 ((struct dvb_net_priv *) dev->priv)->stats.rx_frame_errors++;
441 }
442 reset_ule(priv);
443 priv->need_pusi = 1;
444 ts += TS_SZ;
445 priv->ts_count++;
446 continue;
447 }
448 /* Skip pointer field (we're processing a
449 * packed payload). */
450 from_where += 1;
451 ts_remain -= 1;
452 } else
453 priv->need_pusi = 0;
454
455 if (priv->ule_sndu_remain > 183) {
456 /* Current SNDU lacks more data than there could be available in the
457 * current TS cell. */
458 ((struct dvb_net_priv *) dev->priv)->stats.rx_errors++;
459 ((struct dvb_net_priv *) dev->priv)->stats.rx_length_errors++;
460 printk(KERN_WARNING "%lu: Expected %d more SNDU bytes, but "
461 "got PUSI (pf %d, ts_remain %d). Flushing incomplete payload.\n",
462 priv->ts_count, priv->ule_sndu_remain, ts[4], ts_remain);
463 dev_kfree_skb(priv->ule_skb);
464 /* Prepare for next SNDU. */
465 reset_ule(priv);
466 /* Resync: go to where pointer field points to: start of next ULE SNDU. */
467 from_where += ts[4];
468 ts_remain -= ts[4];
469 }
470 }
471 }
472
473 /* Check if new payload needs to be started. */
474 if (priv->ule_skb == NULL) {
475 /* Start a new payload with skb.
476 * Find ULE header. It is only guaranteed that the
477 * length field (2 bytes) is contained in the current
478 * TS.
479 * Check ts_remain has to be >= 2 here. */
480 if (ts_remain < 2) {
481 printk(KERN_WARNING "Invalid payload packing: only %d "
482 "bytes left in TS. Resyncing.\n", ts_remain);
483 priv->ule_sndu_len = 0;
484 priv->need_pusi = 1;
485 continue;
486 }
487
488 if (! priv->ule_sndu_len) {
489 /* Got at least two bytes, thus extrace the SNDU length. */
490 priv->ule_sndu_len = from_where[0] << 8 | from_where[1];
491 if (priv->ule_sndu_len & 0x8000) {
492 /* D-Bit is set: no dest mac present. */
493 priv->ule_sndu_len &= 0x7FFF;
494 priv->ule_dbit = 1;
495 } else
496 priv->ule_dbit = 0;
497
498 if (priv->ule_sndu_len > 32763) {
499 printk(KERN_WARNING "%lu: Invalid ULE SNDU length %u. "
500 "Resyncing.\n", priv->ts_count, priv->ule_sndu_len);
501 priv->ule_sndu_len = 0;
502 priv->need_pusi = 1;
503 new_ts = 1;
504 ts += TS_SZ;
505 priv->ts_count++;
506 continue;
507 }
508 ts_remain -= 2; /* consume the 2 bytes SNDU length. */
509 from_where += 2;
510 }
511
512 /*
513 * State of current TS:
514 * ts_remain (remaining bytes in the current TS cell)
515 * 0 ule_type is not available now, we need the next TS cell
516 * 1 the first byte of the ule_type is present
517 * >=2 full ULE header present, maybe some payload data as well.
518 */
519 switch (ts_remain) {
520 case 1:
521 priv->ule_sndu_type = from_where[0] << 8;
522 priv->ule_sndu_type_1 = 1; /* first byte of ule_type is set. */
523 ts_remain -= 1; from_where += 1;
524 /* Continue w/ next TS. */
525 case 0:
526 new_ts = 1;
527 ts += TS_SZ;
528 priv->ts_count++;
529 continue;
530
531 default: /* complete ULE header is present in current TS. */
532 /* Extract ULE type field. */
533 if (priv->ule_sndu_type_1) {
534 priv->ule_sndu_type |= from_where[0];
535 from_where += 1; /* points to payload start. */
536 ts_remain -= 1;
537 } else {
538 /* Complete type is present in new TS. */
539 priv->ule_sndu_type = from_where[0] << 8 | from_where[1];
540 from_where += 2; /* points to payload start. */
541 ts_remain -= 2;
542 }
543 break;
544 }
545
546 /* Allocate the skb (decoder target buffer) with the correct size, as follows:
547 * prepare for the largest case: bridged SNDU with MAC address (dbit = 0). */
548 priv->ule_skb = dev_alloc_skb( priv->ule_sndu_len + ETH_HLEN + ETH_ALEN );
549 if (priv->ule_skb == NULL) {
550 printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n",
551 dev->name);
552 ((struct dvb_net_priv *)dev->priv)->stats.rx_dropped++;
553 return;
554 }
555
556 /* This includes the CRC32 _and_ dest mac, if !dbit. */
557 priv->ule_sndu_remain = priv->ule_sndu_len;
558 priv->ule_skb->dev = dev;
559 /* Leave space for Ethernet or bridged SNDU header (eth hdr plus one MAC addr). */
560 skb_reserve( priv->ule_skb, ETH_HLEN + ETH_ALEN );
561 }
562
563 /* Copy data into our current skb. */
564 how_much = min(priv->ule_sndu_remain, (int)ts_remain);
565 memcpy(skb_put(priv->ule_skb, how_much), from_where, how_much);
566 priv->ule_sndu_remain -= how_much;
567 ts_remain -= how_much;
568 from_where += how_much;
569
570 /* Check for complete payload. */
571 if (priv->ule_sndu_remain <= 0) {
572 /* Check CRC32, we've got it in our skb already. */
573 unsigned short ulen = htons(priv->ule_sndu_len);
574 unsigned short utype = htons(priv->ule_sndu_type);
575 struct kvec iov[3] = {
576 { &ulen, sizeof ulen },
577 { &utype, sizeof utype },
578 { priv->ule_skb->data, priv->ule_skb->len - 4 }
579 };
580 unsigned long ule_crc = ~0L, expected_crc;
581 if (priv->ule_dbit) {
582 /* Set D-bit for CRC32 verification,
583 * if it was set originally. */
584 ulen |= 0x0080;
585 }
586
587 ule_crc = iov_crc32(ule_crc, iov, 3);
588 expected_crc = *((u8 *)priv->ule_skb->tail - 4) << 24 |
589 *((u8 *)priv->ule_skb->tail - 3) << 16 |
590 *((u8 *)priv->ule_skb->tail - 2) << 8 |
591 *((u8 *)priv->ule_skb->tail - 1);
592 if (ule_crc != expected_crc) {
593 printk(KERN_WARNING "%lu: CRC32 check FAILED: %#lx / %#lx, SNDU len %d type %#x, ts_remain %d, next 2: %x.\n",
594 priv->ts_count, ule_crc, expected_crc, priv->ule_sndu_len, priv->ule_sndu_type, ts_remain, ts_remain > 2 ? *(unsigned short *)from_where : 0);
595
596#ifdef ULE_DEBUG
597 hexdump( iov[0].iov_base, iov[0].iov_len );
598 hexdump( iov[1].iov_base, iov[1].iov_len );
599 hexdump( iov[2].iov_base, iov[2].iov_len );
600
601 if (ule_where == ule_hist) {
602 hexdump( &ule_hist[98*TS_SZ], TS_SZ );
603 hexdump( &ule_hist[99*TS_SZ], TS_SZ );
604 } else if (ule_where == &ule_hist[TS_SZ]) {
605 hexdump( &ule_hist[99*TS_SZ], TS_SZ );
606 hexdump( ule_hist, TS_SZ );
607 } else {
608 hexdump( ule_where - TS_SZ - TS_SZ, TS_SZ );
609 hexdump( ule_where - TS_SZ, TS_SZ );
610 }
611 ule_dump = 1;
612#endif
613
614 ((struct dvb_net_priv *) dev->priv)->stats.rx_errors++;
615 ((struct dvb_net_priv *) dev->priv)->stats.rx_crc_errors++;
616 dev_kfree_skb(priv->ule_skb);
617 } else {
618 /* CRC32 verified OK. */
619 /* Handle ULE Extension Headers. */
620 if (priv->ule_sndu_type < 1536) {
621 /* There is an extension header. Handle it accordingly. */
622 int l = handle_ule_extensions( priv );
623 if (l < 0) {
624 /* Mandatory extension header unknown or TEST SNDU. Drop it. */
625 // printk( KERN_WARNING "Dropping SNDU, extension headers.\n" );
626 dev_kfree_skb( priv->ule_skb );
627 goto sndu_done;
628 }
629 skb_pull( priv->ule_skb, l );
630 }
631
632 /* CRC32 was OK. Remove it from skb. */
633 priv->ule_skb->tail -= 4;
634 priv->ule_skb->len -= 4;
635
636 /* Filter on receiver's destination MAC address, if present. */
637 if (!priv->ule_dbit) {
638 /* The destination MAC address is the next data in the skb. */
639 if (memcmp( priv->ule_skb->data, dev->dev_addr, ETH_ALEN )) {
640 /* MAC addresses don't match. Drop SNDU. */
641 // printk( KERN_WARNING "Dropping SNDU, MAC address.\n" );
642 dev_kfree_skb( priv->ule_skb );
643 goto sndu_done;
644 }
645 if (! priv->ule_bridged) {
646 skb_push( priv->ule_skb, ETH_ALEN + 2 );
647 ethh = (struct ethhdr *)priv->ule_skb->data;
648 memcpy( ethh->h_dest, ethh->h_source, ETH_ALEN );
649 memset( ethh->h_source, 0, ETH_ALEN );
650 ethh->h_proto = htons( priv->ule_sndu_type );
651 } else {
652 /* Skip the Receiver destination MAC address. */
653 skb_pull( priv->ule_skb, ETH_ALEN );
654 }
655 } else {
656 if (! priv->ule_bridged) {
657 skb_push( priv->ule_skb, ETH_HLEN );
658 ethh = (struct ethhdr *)priv->ule_skb->data;
659 memcpy( ethh->h_dest, dev->dev_addr, ETH_ALEN );
660 memset( ethh->h_source, 0, ETH_ALEN );
661 ethh->h_proto = htons( priv->ule_sndu_type );
662 } else {
663 /* skb is in correct state; nothing to do. */
664 }
665 }
666 priv->ule_bridged = 0;
667
668 /* Stuff into kernel's protocol stack. */
669 priv->ule_skb->protocol = dvb_net_eth_type_trans(priv->ule_skb, dev);
670 /* If D-bit is set (i.e. destination MAC address not present),
671 * receive the packet anyhow. */
672 /* if (priv->ule_dbit && skb->pkt_type == PACKET_OTHERHOST)
673 priv->ule_skb->pkt_type = PACKET_HOST; */
674 ((struct dvb_net_priv *) dev->priv)->stats.rx_packets++;
675 ((struct dvb_net_priv *) dev->priv)->stats.rx_bytes += priv->ule_skb->len;
676 netif_rx(priv->ule_skb);
677 }
678 sndu_done:
679 /* Prepare for next SNDU. */
680 reset_ule(priv);
681 }
682
683 /* More data in current TS (look at the bytes following the CRC32)? */
684 if (ts_remain >= 2 && *((unsigned short *)from_where) != 0xFFFF) {
685 /* Next ULE SNDU starts right there. */
686 new_ts = 0;
687 priv->ule_skb = NULL;
688 priv->ule_sndu_type_1 = 0;
689 priv->ule_sndu_len = 0;
690 // printk(KERN_WARNING "More data in current TS: [%#x %#x %#x %#x]\n",
691 // *(from_where + 0), *(from_where + 1),
692 // *(from_where + 2), *(from_where + 3));
693 // printk(KERN_WARNING "ts @ %p, stopped @ %p:\n", ts, from_where + 0);
694 // hexdump(ts, 188);
695 } else {
696 new_ts = 1;
697 ts += TS_SZ;
698 priv->ts_count++;
699 if (priv->ule_skb == NULL) {
700 priv->need_pusi = 1;
701 priv->ule_sndu_type_1 = 0;
702 priv->ule_sndu_len = 0;
703 }
704 }
705 } /* for all available TS cells */
706}
707
708static int dvb_net_ts_callback(const u8 *buffer1, size_t buffer1_len,
709 const u8 *buffer2, size_t buffer2_len,
710 struct dmx_ts_feed *feed, enum dmx_success success)
711{
712 struct net_device *dev = (struct net_device *)feed->priv;
713
714 if (buffer2 != 0)
715 printk(KERN_WARNING "buffer2 not 0: %p.\n", buffer2);
716 if (buffer1_len > 32768)
717 printk(KERN_WARNING "length > 32k: %zu.\n", buffer1_len);
718 /* printk("TS callback: %u bytes, %u TS cells @ %p.\n",
719 buffer1_len, buffer1_len / TS_SZ, buffer1); */
720 dvb_net_ule(dev, buffer1, buffer1_len);
721 return 0;
722}
723
724
725static void dvb_net_sec(struct net_device *dev, u8 *pkt, int pkt_len)
726{
727 u8 *eth;
728 struct sk_buff *skb;
729 struct net_device_stats *stats = &(((struct dvb_net_priv *) dev->priv)->stats);
730
731 /* note: pkt_len includes a 32bit checksum */
732 if (pkt_len < 16) {
733 printk("%s: IP/MPE packet length = %d too small.\n",
734 dev->name, pkt_len);
735 stats->rx_errors++;
736 stats->rx_length_errors++;
737 return;
738 }
739/* it seems some ISPs manage to screw up here, so we have to
740 * relax the error checks... */
741#if 0
742 if ((pkt[5] & 0xfd) != 0xc1) {
743 /* drop scrambled or broken packets */
744#else
745 if ((pkt[5] & 0x3c) != 0x00) {
746 /* drop scrambled */
747#endif
748 stats->rx_errors++;
749 stats->rx_crc_errors++;
750 return;
751 }
752 if (pkt[5] & 0x02) {
753 //FIXME: handle LLC/SNAP
754 stats->rx_dropped++;
755 return;
756 }
757 if (pkt[7]) {
758 /* FIXME: assemble datagram from multiple sections */
759 stats->rx_errors++;
760 stats->rx_frame_errors++;
761 return;
762 }
763
764 /* we have 14 byte ethernet header (ip header follows);
765 * 12 byte MPE header; 4 byte checksum; + 2 byte alignment
766 */
767 if (!(skb = dev_alloc_skb(pkt_len - 4 - 12 + 14 + 2))) {
768 //printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n", dev->name);
769 stats->rx_dropped++;
770 return;
771 }
772 skb_reserve(skb, 2); /* longword align L3 header */
773 skb->dev = dev;
774
775 /* copy L3 payload */
776 eth = (u8 *) skb_put(skb, pkt_len - 12 - 4 + 14);
777 memcpy(eth + 14, pkt + 12, pkt_len - 12 - 4);
778
779 /* create ethernet header: */
780 eth[0]=pkt[0x0b];
781 eth[1]=pkt[0x0a];
782 eth[2]=pkt[0x09];
783 eth[3]=pkt[0x08];
784 eth[4]=pkt[0x04];
785 eth[5]=pkt[0x03];
786
787 eth[6]=eth[7]=eth[8]=eth[9]=eth[10]=eth[11]=0;
788
789 eth[12] = 0x08; /* ETH_P_IP */
790 eth[13] = 0x00;
791
792 skb->protocol = dvb_net_eth_type_trans(skb, dev);
793
794 stats->rx_packets++;
795 stats->rx_bytes+=skb->len;
796 netif_rx(skb);
797}
798
799static int dvb_net_sec_callback(const u8 *buffer1, size_t buffer1_len,
800 const u8 *buffer2, size_t buffer2_len,
801 struct dmx_section_filter *filter,
802 enum dmx_success success)
803{
804 struct net_device *dev=(struct net_device *) filter->priv;
805
806 /**
807 * we rely on the DVB API definition where exactly one complete
808 * section is delivered in buffer1
809 */
810 dvb_net_sec (dev, (u8*) buffer1, buffer1_len);
811 return 0;
812}
813
814static int dvb_net_tx(struct sk_buff *skb, struct net_device *dev)
815{
816 dev_kfree_skb(skb);
817 return 0;
818}
819
820static u8 mask_normal[6]={0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
821static u8 mask_allmulti[6]={0xff, 0xff, 0xff, 0x00, 0x00, 0x00};
822static u8 mac_allmulti[6]={0x01, 0x00, 0x5e, 0x00, 0x00, 0x00};
823static u8 mask_promisc[6]={0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
824
825static int dvb_net_filter_sec_set(struct net_device *dev,
826 struct dmx_section_filter **secfilter,
827 u8 *mac, u8 *mac_mask)
828{
829 struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv;
830 int ret;
831
832 *secfilter=NULL;
833 ret = priv->secfeed->allocate_filter(priv->secfeed, secfilter);
834 if (ret<0) {
835 printk("%s: could not get filter\n", dev->name);
836 return ret;
837 }
838
839 (*secfilter)->priv=(void *) dev;
840
841 memset((*secfilter)->filter_value, 0x00, DMX_MAX_FILTER_SIZE);
842 memset((*secfilter)->filter_mask, 0x00, DMX_MAX_FILTER_SIZE);
843 memset((*secfilter)->filter_mode, 0xff, DMX_MAX_FILTER_SIZE);
844
845 (*secfilter)->filter_value[0]=0x3e;
846 (*secfilter)->filter_value[3]=mac[5];
847 (*secfilter)->filter_value[4]=mac[4];
848 (*secfilter)->filter_value[8]=mac[3];
849 (*secfilter)->filter_value[9]=mac[2];
850 (*secfilter)->filter_value[10]=mac[1];
851 (*secfilter)->filter_value[11]=mac[0];
852
853 (*secfilter)->filter_mask[0] = 0xff;
854 (*secfilter)->filter_mask[3] = mac_mask[5];
855 (*secfilter)->filter_mask[4] = mac_mask[4];
856 (*secfilter)->filter_mask[8] = mac_mask[3];
857 (*secfilter)->filter_mask[9] = mac_mask[2];
858 (*secfilter)->filter_mask[10] = mac_mask[1];
859 (*secfilter)->filter_mask[11]=mac_mask[0];
860
861 dprintk("%s: filter mac=%02x %02x %02x %02x %02x %02x\n",
862 dev->name, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
863 dprintk("%s: filter mask=%02x %02x %02x %02x %02x %02x\n",
864 dev->name, mac_mask[0], mac_mask[1], mac_mask[2],
865 mac_mask[3], mac_mask[4], mac_mask[5]);
866
867 return 0;
868}
869
870static int dvb_net_feed_start(struct net_device *dev)
871{
872 int ret, i;
873 struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv;
874 struct dmx_demux *demux = priv->demux;
875 unsigned char *mac = (unsigned char *) dev->dev_addr;
876
877 dprintk("%s: rx_mode %i\n", __FUNCTION__, priv->rx_mode);
878 if (priv->tsfeed || priv->secfeed || priv->secfilter || priv->multi_secfilter[0])
879 printk("%s: BUG %d\n", __FUNCTION__, __LINE__);
880
881 priv->secfeed=NULL;
882 priv->secfilter=NULL;
883 priv->tsfeed = NULL;
884
885 if (priv->feedtype == DVB_NET_FEEDTYPE_MPE) {
886 dprintk("%s: alloc secfeed\n", __FUNCTION__);
887 ret=demux->allocate_section_feed(demux, &priv->secfeed,
888 dvb_net_sec_callback);
889 if (ret<0) {
890 printk("%s: could not allocate section feed\n", dev->name);
891 return ret;
892 }
893
894 ret = priv->secfeed->set(priv->secfeed, priv->pid, 32768, 0, 1);
895
896 if (ret<0) {
897 printk("%s: could not set section feed\n", dev->name);
898 priv->demux->release_section_feed(priv->demux, priv->secfeed);
899 priv->secfeed=NULL;
900 return ret;
901 }
902
903 if (priv->rx_mode != RX_MODE_PROMISC) {
904 dprintk("%s: set secfilter\n", __FUNCTION__);
905 dvb_net_filter_sec_set(dev, &priv->secfilter, mac, mask_normal);
906 }
907
908 switch (priv->rx_mode) {
909 case RX_MODE_MULTI:
910 for (i = 0; i < priv->multi_num; i++) {
911 dprintk("%s: set multi_secfilter[%d]\n", __FUNCTION__, i);
912 dvb_net_filter_sec_set(dev, &priv->multi_secfilter[i],
913 priv->multi_macs[i], mask_normal);
914 }
915 break;
916 case RX_MODE_ALL_MULTI:
917 priv->multi_num=1;
918 dprintk("%s: set multi_secfilter[0]\n", __FUNCTION__);
919 dvb_net_filter_sec_set(dev, &priv->multi_secfilter[0],
920 mac_allmulti, mask_allmulti);
921 break;
922 case RX_MODE_PROMISC:
923 priv->multi_num=0;
924 dprintk("%s: set secfilter\n", __FUNCTION__);
925 dvb_net_filter_sec_set(dev, &priv->secfilter, mac, mask_promisc);
926 break;
927 }
928
929 dprintk("%s: start filtering\n", __FUNCTION__);
930 priv->secfeed->start_filtering(priv->secfeed);
931 } else if (priv->feedtype == DVB_NET_FEEDTYPE_ULE) {
932 struct timespec timeout = { 0, 30000000 }; // 30 msec
933
934 /* we have payloads encapsulated in TS */
935 dprintk("%s: alloc tsfeed\n", __FUNCTION__);
936 ret = demux->allocate_ts_feed(demux, &priv->tsfeed, dvb_net_ts_callback);
937 if (ret < 0) {
938 printk("%s: could not allocate ts feed\n", dev->name);
939 return ret;
940 }
941
942 /* Set netdevice pointer for ts decaps callback. */
943 priv->tsfeed->priv = (void *)dev;
944 ret = priv->tsfeed->set(priv->tsfeed, priv->pid,
945 TS_PACKET, DMX_TS_PES_OTHER,
946 188 * 100, /* nr. of bytes delivered per callback */
947 32768, /* circular buffer size */
948 0, /* descramble */
949 timeout);
950
951 if (ret < 0) {
952 printk("%s: could not set ts feed\n", dev->name);
953 priv->demux->release_ts_feed(priv->demux, priv->tsfeed);
954 priv->tsfeed = NULL;
955 return ret;
956 }
957
958 dprintk("%s: start filtering\n", __FUNCTION__);
959 priv->tsfeed->start_filtering(priv->tsfeed);
960 } else
961 return -EINVAL;
962
963 return 0;
964}
965
966static int dvb_net_feed_stop(struct net_device *dev)
967{
968 struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv;
969 int i;
970
971 dprintk("%s\n", __FUNCTION__);
972 if (priv->feedtype == DVB_NET_FEEDTYPE_MPE) {
973 if (priv->secfeed) {
974 if (priv->secfeed->is_filtering) {
975 dprintk("%s: stop secfeed\n", __FUNCTION__);
976 priv->secfeed->stop_filtering(priv->secfeed);
977 }
978
979 if (priv->secfilter) {
980 dprintk("%s: release secfilter\n", __FUNCTION__);
981 priv->secfeed->release_filter(priv->secfeed,
982 priv->secfilter);
983 priv->secfilter=NULL;
984 }
985
986 for (i=0; i<priv->multi_num; i++) {
987 if (priv->multi_secfilter[i]) {
988 dprintk("%s: release multi_filter[%d]\n",
989 __FUNCTION__, i);
990 priv->secfeed->release_filter(priv->secfeed,
991 priv->multi_secfilter[i]);
992 priv->multi_secfilter[i] = NULL;
993 }
994 }
995
996 priv->demux->release_section_feed(priv->demux, priv->secfeed);
997 priv->secfeed = NULL;
998 } else
999 printk("%s: no feed to stop\n", dev->name);
1000 } else if (priv->feedtype == DVB_NET_FEEDTYPE_ULE) {
1001 if (priv->tsfeed) {
1002 if (priv->tsfeed->is_filtering) {
1003 dprintk("%s: stop tsfeed\n", __FUNCTION__);
1004 priv->tsfeed->stop_filtering(priv->tsfeed);
1005 }
1006 priv->demux->release_ts_feed(priv->demux, priv->tsfeed);
1007 priv->tsfeed = NULL;
1008 }
1009 else
1010 printk("%s: no ts feed to stop\n", dev->name);
1011 } else
1012 return -EINVAL;
1013 return 0;
1014}
1015
1016
1017static int dvb_set_mc_filter (struct net_device *dev, struct dev_mc_list *mc)
1018{
1019 struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv;
1020
1021 if (priv->multi_num == DVB_NET_MULTICAST_MAX)
1022 return -ENOMEM;
1023
1024 memcpy(priv->multi_macs[priv->multi_num], mc->dmi_addr, 6);
1025
1026 priv->multi_num++;
1027 return 0;
1028}
1029
1030
1031static void wq_set_multicast_list (void *data)
1032{
1033 struct net_device *dev = data;
1034 struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv;
1035
1036 dvb_net_feed_stop(dev);
1037
1038 priv->rx_mode = RX_MODE_UNI;
1039
1040 if (dev->flags & IFF_PROMISC) {
1041 dprintk("%s: promiscuous mode\n", dev->name);
1042 priv->rx_mode = RX_MODE_PROMISC;
1043 } else if ((dev->flags & IFF_ALLMULTI)) {
1044 dprintk("%s: allmulti mode\n", dev->name);
1045 priv->rx_mode = RX_MODE_ALL_MULTI;
1046 } else if (dev->mc_count) {
1047 int mci;
1048 struct dev_mc_list *mc;
1049
1050 dprintk("%s: set_mc_list, %d entries\n",
1051 dev->name, dev->mc_count);
1052
1053 priv->rx_mode = RX_MODE_MULTI;
1054 priv->multi_num = 0;
1055
1056 for (mci = 0, mc=dev->mc_list;
1057 mci < dev->mc_count;
1058 mc = mc->next, mci++) {
1059 dvb_set_mc_filter(dev, mc);
1060 }
1061 }
1062
1063 dvb_net_feed_start(dev);
1064}
1065
1066
1067static void dvb_net_set_multicast_list (struct net_device *dev)
1068{
1069 struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv;
1070 schedule_work(&priv->set_multicast_list_wq);
1071}
1072
1073
1074static void wq_restart_net_feed (void *data)
1075{
1076 struct net_device *dev = data;
1077
1078 if (netif_running(dev)) {
1079 dvb_net_feed_stop(dev);
1080 dvb_net_feed_start(dev);
1081 }
1082}
1083
1084
1085static int dvb_net_set_mac (struct net_device *dev, void *p)
1086{
1087 struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv;
1088 struct sockaddr *addr=p;
1089
1090 memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
1091
1092 if (netif_running(dev))
1093 schedule_work(&priv->restart_net_feed_wq);
1094
1095 return 0;
1096}
1097
1098
1099static int dvb_net_open(struct net_device *dev)
1100{
1101 struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv;
1102
1103 priv->in_use++;
1104 dvb_net_feed_start(dev);
1105 return 0;
1106}
1107
1108
1109static int dvb_net_stop(struct net_device *dev)
1110{
1111 struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv;
1112
1113 priv->in_use--;
1114 return dvb_net_feed_stop(dev);
1115}
1116
1117static struct net_device_stats * dvb_net_get_stats(struct net_device *dev)
1118{
1119 return &((struct dvb_net_priv*) dev->priv)->stats;
1120}
1121
1122static void dvb_net_setup(struct net_device *dev)
1123{
1124 ether_setup(dev);
1125
1126 dev->open = dvb_net_open;
1127 dev->stop = dvb_net_stop;
1128 dev->hard_start_xmit = dvb_net_tx;
1129 dev->get_stats = dvb_net_get_stats;
1130 dev->set_multicast_list = dvb_net_set_multicast_list;
1131 dev->set_mac_address = dvb_net_set_mac;
1132 dev->mtu = 4096;
1133 dev->mc_count = 0;
1134 dev->hard_header_cache = NULL;
1135 dev->flags |= IFF_NOARP;
1136}
1137
1138static int get_if(struct dvb_net *dvbnet)
1139{
1140 int i;
1141
1142 for (i=0; i<DVB_NET_DEVICES_MAX; i++)
1143 if (!dvbnet->state[i])
1144 break;
1145
1146 if (i == DVB_NET_DEVICES_MAX)
1147 return -1;
1148
1149 dvbnet->state[i]=1;
1150 return i;
1151}
1152
1153static int dvb_net_add_if(struct dvb_net *dvbnet, u16 pid, u8 feedtype)
1154{
1155 struct net_device *net;
1156 struct dvb_net_priv *priv;
1157 int result;
1158 int if_num;
1159
1160 if (feedtype != DVB_NET_FEEDTYPE_MPE && feedtype != DVB_NET_FEEDTYPE_ULE)
1161 return -EINVAL;
1162 if ((if_num = get_if(dvbnet)) < 0)
1163 return -EINVAL;
1164
1165 net = alloc_netdev(sizeof(struct dvb_net_priv), "dvb", dvb_net_setup);
1166 if (!net)
1167 return -ENOMEM;
1168
1169 if (dvbnet->dvbdev->id)
1170 snprintf(net->name, IFNAMSIZ, "dvb%d%u%d",
1171 dvbnet->dvbdev->adapter->num, dvbnet->dvbdev->id, if_num);
1172 else
1173 /* compatibility fix to keep dvb0_0 format */
1174 snprintf(net->name, IFNAMSIZ, "dvb%d_%d",
1175 dvbnet->dvbdev->adapter->num, if_num);
1176
1177 net->addr_len = 6;
1178 memcpy(net->dev_addr, dvbnet->dvbdev->adapter->proposed_mac, 6);
1179
1180 dvbnet->device[if_num] = net;
1181
1182 priv = net->priv;
1183 priv->demux = dvbnet->demux;
1184 priv->pid = pid;
1185 priv->rx_mode = RX_MODE_UNI;
1186 priv->need_pusi = 1;
1187 priv->tscc = 0;
1188 priv->feedtype = feedtype;
1189 reset_ule(priv);
1190
1191 INIT_WORK(&priv->set_multicast_list_wq, wq_set_multicast_list, net);
1192 INIT_WORK(&priv->restart_net_feed_wq, wq_restart_net_feed, net);
1193
1194 net->base_addr = pid;
1195
1196 if ((result = register_netdev(net)) < 0) {
1197 dvbnet->device[if_num] = NULL;
1198 free_netdev(net);
1199 return result;
1200 }
1201 printk("dvb_net: created network interface %s\n", net->name);
1202
1203 return if_num;
1204}
1205
1206static int dvb_net_remove_if(struct dvb_net *dvbnet, unsigned int num)
1207{
1208 struct net_device *net = dvbnet->device[num];
1209 struct dvb_net_priv *priv;
1210
1211 if (!dvbnet->state[num])
1212 return -EINVAL;
1213 priv = net->priv;
1214 if (priv->in_use)
1215 return -EBUSY;
1216
1217 dvb_net_stop(net);
1218 flush_scheduled_work();
1219 printk("dvb_net: removed network interface %s\n", net->name);
1220 unregister_netdev(net);
1221 dvbnet->state[num]=0;
1222 dvbnet->device[num] = NULL;
1223 free_netdev(net);
1224
1225 return 0;
1226}
1227
1228static int dvb_net_do_ioctl(struct inode *inode, struct file *file,
1229 unsigned int cmd, void *parg)
1230{
1231 struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;
1232 struct dvb_net *dvbnet = (struct dvb_net *) dvbdev->priv;
1233
1234 if (((file->f_flags&O_ACCMODE)==O_RDONLY))
1235 return -EPERM;
1236
1237 switch (cmd) {
1238 case NET_ADD_IF:
1239 {
1240 struct dvb_net_if *dvbnetif=(struct dvb_net_if *)parg;
1241 int result;
1242
1243 if (!capable(CAP_SYS_ADMIN))
1244 return -EPERM;
1245
1246 if (!try_module_get(dvbdev->adapter->module))
1247 return -EPERM;
1248
1249 result=dvb_net_add_if(dvbnet, dvbnetif->pid, dvbnetif->feedtype);
1250 if (result<0) {
1251 module_put(dvbdev->adapter->module);
1252 return result;
1253 }
1254 dvbnetif->if_num=result;
1255 break;
1256 }
1257 case NET_GET_IF:
1258 {
1259 struct net_device *netdev;
1260 struct dvb_net_priv *priv_data;
1261 struct dvb_net_if *dvbnetif=(struct dvb_net_if *)parg;
1262
1263 if (dvbnetif->if_num >= DVB_NET_DEVICES_MAX ||
1264 !dvbnet->state[dvbnetif->if_num])
1265 return -EINVAL;
1266
1267 netdev = dvbnet->device[dvbnetif->if_num];
1268
1269 priv_data=(struct dvb_net_priv*)netdev->priv;
1270 dvbnetif->pid=priv_data->pid;
1271 dvbnetif->feedtype=priv_data->feedtype;
1272 break;
1273 }
1274 case NET_REMOVE_IF:
1275 {
1276 int ret;
1277
1278 if (!capable(CAP_SYS_ADMIN))
1279 return -EPERM;
1280 if ((unsigned int) parg >= DVB_NET_DEVICES_MAX)
1281 return -EINVAL;
1282 ret = dvb_net_remove_if(dvbnet, (unsigned int) parg);
1283 if (!ret)
1284 module_put(dvbdev->adapter->module);
1285 return ret;
1286 }
1287
1288 /* binary compatiblity cruft */
1289 case __NET_ADD_IF_OLD:
1290 {
1291 struct __dvb_net_if_old *dvbnetif=(struct __dvb_net_if_old *)parg;
1292 int result;
1293
1294 if (!capable(CAP_SYS_ADMIN))
1295 return -EPERM;
1296
1297 if (!try_module_get(dvbdev->adapter->module))
1298 return -EPERM;
1299
1300 result=dvb_net_add_if(dvbnet, dvbnetif->pid, DVB_NET_FEEDTYPE_MPE);
1301 if (result<0) {
1302 module_put(dvbdev->adapter->module);
1303 return result;
1304 }
1305 dvbnetif->if_num=result;
1306 break;
1307 }
1308 case __NET_GET_IF_OLD:
1309 {
1310 struct net_device *netdev;
1311 struct dvb_net_priv *priv_data;
1312 struct __dvb_net_if_old *dvbnetif=(struct __dvb_net_if_old *)parg;
1313
1314 if (dvbnetif->if_num >= DVB_NET_DEVICES_MAX ||
1315 !dvbnet->state[dvbnetif->if_num])
1316 return -EINVAL;
1317
1318 netdev = dvbnet->device[dvbnetif->if_num];
1319
1320 priv_data=(struct dvb_net_priv*)netdev->priv;
1321 dvbnetif->pid=priv_data->pid;
1322 break;
1323 }
1324 default:
1325 return -ENOTTY;
1326 }
1327 return 0;
1328}
1329
1330static int dvb_net_ioctl(struct inode *inode, struct file *file,
1331 unsigned int cmd, unsigned long arg)
1332{
1333 return dvb_usercopy(inode, file, cmd, arg, dvb_net_do_ioctl);
1334}
1335
1336static struct file_operations dvb_net_fops = {
1337 .owner = THIS_MODULE,
1338 .ioctl = dvb_net_ioctl,
1339 .open = dvb_generic_open,
1340 .release = dvb_generic_release,
1341};
1342
1343static struct dvb_device dvbdev_net = {
1344 .priv = NULL,
1345 .users = 1,
1346 .writers = 1,
1347 .fops = &dvb_net_fops,
1348};
1349
1350
1351void dvb_net_release (struct dvb_net *dvbnet)
1352{
1353 int i;
1354
1355 dvb_unregister_device(dvbnet->dvbdev);
1356
1357 for (i=0; i<DVB_NET_DEVICES_MAX; i++) {
1358 if (!dvbnet->state[i])
1359 continue;
1360 dvb_net_remove_if(dvbnet, i);
1361 }
1362}
1363EXPORT_SYMBOL(dvb_net_release);
1364
1365
1366int dvb_net_init (struct dvb_adapter *adap, struct dvb_net *dvbnet,
1367 struct dmx_demux *dmx)
1368{
1369 int i;
1370
1371 dvbnet->demux = dmx;
1372
1373 for (i=0; i<DVB_NET_DEVICES_MAX; i++)
1374 dvbnet->state[i] = 0;
1375
1376 dvb_register_device (adap, &dvbnet->dvbdev, &dvbdev_net,
1377 dvbnet, DVB_DEVICE_NET);
1378
1379 return 0;
1380}
1381EXPORT_SYMBOL(dvb_net_init);
diff --git a/drivers/media/dvb/dvb-core/dvb_net.h b/drivers/media/dvb/dvb-core/dvb_net.h
new file mode 100644
index 000000000000..f14e4ca38570
--- /dev/null
+++ b/drivers/media/dvb/dvb-core/dvb_net.h
@@ -0,0 +1,46 @@
1/*
2 * dvb_net.h
3 *
4 * Copyright (C) 2001 Ralph Metzler for convergence integrated media GmbH
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public License
8 * as published by the Free Software Foundation; either version 2.1
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 *
20 */
21
22#ifndef _DVB_NET_H_
23#define _DVB_NET_H_
24
25#include <linux/module.h>
26#include <linux/netdevice.h>
27#include <linux/inetdevice.h>
28#include <linux/etherdevice.h>
29#include <linux/skbuff.h>
30
31#include "dvbdev.h"
32
33#define DVB_NET_DEVICES_MAX 10
34
35struct dvb_net {
36 struct dvb_device *dvbdev;
37 struct net_device *device[DVB_NET_DEVICES_MAX];
38 int state[DVB_NET_DEVICES_MAX];
39 struct dmx_demux *demux;
40};
41
42
43void dvb_net_release(struct dvb_net *);
44int dvb_net_init(struct dvb_adapter *, struct dvb_net *, struct dmx_demux *);
45
46#endif
diff --git a/drivers/media/dvb/dvb-core/dvb_ringbuffer.c b/drivers/media/dvb/dvb-core/dvb_ringbuffer.c
new file mode 100644
index 000000000000..fb6d94a69d71
--- /dev/null
+++ b/drivers/media/dvb/dvb-core/dvb_ringbuffer.c
@@ -0,0 +1,270 @@
1/*
2 *
3 * dvb_ringbuffer.c: ring buffer implementation for the dvb driver
4 *
5 * Copyright (C) 2003 Oliver Endriss
6 * Copyright (C) 2004 Andrew de Quincey
7 *
8 * based on code originally found in av7110.c & dvb_ci.c:
9 * Copyright (C) 1999-2003 Ralph Metzler
10 * & Marcus Metzler for convergence integrated media GmbH
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public License
14 * as published by the Free Software Foundation; either version 2.1
15 * of the License, or (at your option) any later version.
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 Lesser General Public License for more details.
21 *
22 * You should have received a copy of the GNU Lesser 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 */
26
27
28
29#define __KERNEL_SYSCALLS__
30#include <linux/errno.h>
31#include <linux/kernel.h>
32#include <linux/module.h>
33#include <linux/sched.h>
34#include <linux/string.h>
35#include <asm/uaccess.h>
36
37#include "dvb_ringbuffer.h"
38
39#define PKT_READY 0
40#define PKT_DISPOSED 1
41
42
43void dvb_ringbuffer_init(struct dvb_ringbuffer *rbuf, void *data, size_t len)
44{
45 rbuf->pread=rbuf->pwrite=0;
46 rbuf->data=data;
47 rbuf->size=len;
48
49 init_waitqueue_head(&rbuf->queue);
50
51 spin_lock_init(&(rbuf->lock));
52}
53
54
55
56int dvb_ringbuffer_empty(struct dvb_ringbuffer *rbuf)
57{
58 return (rbuf->pread==rbuf->pwrite);
59}
60
61
62
63ssize_t dvb_ringbuffer_free(struct dvb_ringbuffer *rbuf)
64{
65 ssize_t free;
66
67 free = rbuf->pread - rbuf->pwrite;
68 if (free <= 0)
69 free += rbuf->size;
70 return free-1;
71}
72
73
74
75ssize_t dvb_ringbuffer_avail(struct dvb_ringbuffer *rbuf)
76{
77 ssize_t avail;
78
79 avail = rbuf->pwrite - rbuf->pread;
80 if (avail < 0)
81 avail += rbuf->size;
82 return avail;
83}
84
85
86
87void dvb_ringbuffer_flush(struct dvb_ringbuffer *rbuf)
88{
89 rbuf->pread = rbuf->pwrite;
90}
91
92
93
94void dvb_ringbuffer_flush_spinlock_wakeup(struct dvb_ringbuffer *rbuf)
95{
96 unsigned long flags;
97
98 spin_lock_irqsave(&rbuf->lock, flags);
99 dvb_ringbuffer_flush(rbuf);
100 spin_unlock_irqrestore(&rbuf->lock, flags);
101
102 wake_up(&rbuf->queue);
103}
104
105
106
107ssize_t dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf, u8 *buf, size_t len, int usermem)
108{
109 size_t todo = len;
110 size_t split;
111
112 split = (rbuf->pread + len > rbuf->size) ? rbuf->size - rbuf->pread : 0;
113 if (split > 0) {
114 if (!usermem)
115 memcpy(buf, rbuf->data+rbuf->pread, split);
116 else
117 if (copy_to_user(buf, rbuf->data+rbuf->pread, split))
118 return -EFAULT;
119 buf += split;
120 todo -= split;
121 rbuf->pread = 0;
122 }
123 if (!usermem)
124 memcpy(buf, rbuf->data+rbuf->pread, todo);
125 else
126 if (copy_to_user(buf, rbuf->data+rbuf->pread, todo))
127 return -EFAULT;
128
129 rbuf->pread = (rbuf->pread + todo) % rbuf->size;
130
131 return len;
132}
133
134
135
136ssize_t dvb_ringbuffer_write(struct dvb_ringbuffer *rbuf, const u8 *buf, size_t len)
137{
138 size_t todo = len;
139 size_t split;
140
141 split = (rbuf->pwrite + len > rbuf->size) ? rbuf->size - rbuf->pwrite : 0;
142
143 if (split > 0) {
144 memcpy(rbuf->data+rbuf->pwrite, buf, split);
145 buf += split;
146 todo -= split;
147 rbuf->pwrite = 0;
148 }
149 memcpy(rbuf->data+rbuf->pwrite, buf, todo);
150 rbuf->pwrite = (rbuf->pwrite + todo) % rbuf->size;
151
152 return len;
153}
154
155ssize_t dvb_ringbuffer_pkt_write(struct dvb_ringbuffer *rbuf, u8* buf, size_t len)
156{
157 int status;
158 ssize_t oldpwrite = rbuf->pwrite;
159
160 DVB_RINGBUFFER_WRITE_BYTE(rbuf, len >> 8);
161 DVB_RINGBUFFER_WRITE_BYTE(rbuf, len & 0xff);
162 DVB_RINGBUFFER_WRITE_BYTE(rbuf, PKT_READY);
163 status = dvb_ringbuffer_write(rbuf, buf, len);
164
165 if (status < 0) rbuf->pwrite = oldpwrite;
166 return status;
167}
168
169ssize_t dvb_ringbuffer_pkt_read(struct dvb_ringbuffer *rbuf, size_t idx,
170 int offset, u8* buf, size_t len, int usermem)
171{
172 size_t todo;
173 size_t split;
174 size_t pktlen;
175
176 pktlen = rbuf->data[idx] << 8;
177 pktlen |= rbuf->data[(idx + 1) % rbuf->size];
178 if (offset > pktlen) return -EINVAL;
179 if ((offset + len) > pktlen) len = pktlen - offset;
180
181 idx = (idx + DVB_RINGBUFFER_PKTHDRSIZE + offset) % rbuf->size;
182 todo = len;
183 split = ((idx + len) > rbuf->size) ? rbuf->size - idx : 0;
184 if (split > 0) {
185 if (!usermem)
186 memcpy(buf, rbuf->data+idx, split);
187 else
188 if (copy_to_user(buf, rbuf->data+idx, split))
189 return -EFAULT;
190 buf += split;
191 todo -= split;
192 idx = 0;
193 }
194 if (!usermem)
195 memcpy(buf, rbuf->data+idx, todo);
196 else
197 if (copy_to_user(buf, rbuf->data+idx, todo))
198 return -EFAULT;
199
200 return len;
201}
202
203void dvb_ringbuffer_pkt_dispose(struct dvb_ringbuffer *rbuf, size_t idx)
204{
205 size_t pktlen;
206
207 rbuf->data[(idx + 2) % rbuf->size] = PKT_DISPOSED;
208
209 // clean up disposed packets
210 while(dvb_ringbuffer_avail(rbuf) > DVB_RINGBUFFER_PKTHDRSIZE) {
211 if (DVB_RINGBUFFER_PEEK(rbuf, 2) == PKT_DISPOSED) {
212 pktlen = DVB_RINGBUFFER_PEEK(rbuf, 0) << 8;
213 pktlen |= DVB_RINGBUFFER_PEEK(rbuf, 1);
214 DVB_RINGBUFFER_SKIP(rbuf, pktlen + DVB_RINGBUFFER_PKTHDRSIZE);
215 } else {
216 // first packet is not disposed, so we stop cleaning now
217 break;
218 }
219 }
220}
221
222ssize_t dvb_ringbuffer_pkt_next(struct dvb_ringbuffer *rbuf, size_t idx, size_t* pktlen)
223{
224 int consumed;
225 int curpktlen;
226 int curpktstatus;
227
228 if (idx == -1) {
229 idx = rbuf->pread;
230 } else {
231 curpktlen = rbuf->data[idx] << 8;
232 curpktlen |= rbuf->data[(idx + 1) % rbuf->size];
233 idx = (idx + curpktlen + DVB_RINGBUFFER_PKTHDRSIZE) % rbuf->size;
234 }
235
236 consumed = (idx - rbuf->pread) % rbuf->size;
237
238 while((dvb_ringbuffer_avail(rbuf) - consumed) > DVB_RINGBUFFER_PKTHDRSIZE) {
239
240 curpktlen = rbuf->data[idx] << 8;
241 curpktlen |= rbuf->data[(idx + 1) % rbuf->size];
242 curpktstatus = rbuf->data[(idx + 2) % rbuf->size];
243
244 if (curpktstatus == PKT_READY) {
245 *pktlen = curpktlen;
246 return idx;
247 }
248
249 consumed += curpktlen + DVB_RINGBUFFER_PKTHDRSIZE;
250 idx = (idx + curpktlen + DVB_RINGBUFFER_PKTHDRSIZE) % rbuf->size;
251 }
252
253 // no packets available
254 return -1;
255}
256
257
258
259EXPORT_SYMBOL(dvb_ringbuffer_init);
260EXPORT_SYMBOL(dvb_ringbuffer_empty);
261EXPORT_SYMBOL(dvb_ringbuffer_free);
262EXPORT_SYMBOL(dvb_ringbuffer_avail);
263EXPORT_SYMBOL(dvb_ringbuffer_flush);
264EXPORT_SYMBOL(dvb_ringbuffer_flush_spinlock_wakeup);
265EXPORT_SYMBOL(dvb_ringbuffer_read);
266EXPORT_SYMBOL(dvb_ringbuffer_write);
267EXPORT_SYMBOL(dvb_ringbuffer_pkt_write);
268EXPORT_SYMBOL(dvb_ringbuffer_pkt_read);
269EXPORT_SYMBOL(dvb_ringbuffer_pkt_dispose);
270EXPORT_SYMBOL(dvb_ringbuffer_pkt_next);
diff --git a/drivers/media/dvb/dvb-core/dvb_ringbuffer.h b/drivers/media/dvb/dvb-core/dvb_ringbuffer.h
new file mode 100644
index 000000000000..d18e9c4ba9ea
--- /dev/null
+++ b/drivers/media/dvb/dvb-core/dvb_ringbuffer.h
@@ -0,0 +1,173 @@
1/*
2 *
3 * dvb_ringbuffer.h: ring buffer implementation for the dvb driver
4 *
5 * Copyright (C) 2003 Oliver Endriss
6 * Copyright (C) 2004 Andrew de Quincey
7 *
8 * based on code originally found in av7110.c & dvb_ci.c:
9 * Copyright (C) 1999-2003 Ralph Metzler & Marcus Metzler
10 * for convergence integrated media GmbH
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public License
14 * as published by the Free Software Foundation; either version 2.1
15 * of the License, or (at your option) any later version.
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 Lesser General Public License for more details.
21 *
22 * You should have received a copy of the GNU Lesser 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 */
26
27#ifndef _DVB_RINGBUFFER_H_
28#define _DVB_RINGBUFFER_H_
29
30#include <linux/spinlock.h>
31#include <linux/wait.h>
32
33struct dvb_ringbuffer {
34 u8 *data;
35 ssize_t size;
36 ssize_t pread;
37 ssize_t pwrite;
38
39 wait_queue_head_t queue;
40 spinlock_t lock;
41};
42
43#define DVB_RINGBUFFER_PKTHDRSIZE 3
44
45
46/*
47** Notes:
48** ------
49** (1) For performance reasons read and write routines don't check buffer sizes
50** and/or number of bytes free/available. This has to be done before these
51** routines are called. For example:
52**
53** *** write <buflen> bytes ***
54** free = dvb_ringbuffer_free(rbuf);
55** if (free >= buflen)
56** count = dvb_ringbuffer_write(rbuf, buffer, buflen);
57** else
58** ...
59**
60** *** read min. 1000, max. <bufsize> bytes ***
61** avail = dvb_ringbuffer_avail(rbuf);
62** if (avail >= 1000)
63** count = dvb_ringbuffer_read(rbuf, buffer, min(avail, bufsize), 0);
64** else
65** ...
66**
67** (2) If there is exactly one reader and one writer, there is no need
68** to lock read or write operations.
69** Two or more readers must be locked against each other.
70** Flushing the buffer counts as a read operation.
71** Two or more writers must be locked against each other.
72*/
73
74/* initialize ring buffer, lock and queue */
75extern void dvb_ringbuffer_init(struct dvb_ringbuffer *rbuf, void *data, size_t len);
76
77/* test whether buffer is empty */
78extern int dvb_ringbuffer_empty(struct dvb_ringbuffer *rbuf);
79
80/* return the number of free bytes in the buffer */
81extern ssize_t dvb_ringbuffer_free(struct dvb_ringbuffer *rbuf);
82
83/* return the number of bytes waiting in the buffer */
84extern ssize_t dvb_ringbuffer_avail(struct dvb_ringbuffer *rbuf);
85
86
87/* read routines & macros */
88/* ---------------------- */
89/* flush buffer */
90extern void dvb_ringbuffer_flush(struct dvb_ringbuffer *rbuf);
91
92/* flush buffer protected by spinlock and wake-up waiting task(s) */
93extern void dvb_ringbuffer_flush_spinlock_wakeup(struct dvb_ringbuffer *rbuf);
94
95/* peek at byte <offs> in the buffer */
96#define DVB_RINGBUFFER_PEEK(rbuf,offs) \
97 (rbuf)->data[((rbuf)->pread+(offs))%(rbuf)->size]
98
99/* advance read ptr by <num> bytes */
100#define DVB_RINGBUFFER_SKIP(rbuf,num) \
101 (rbuf)->pread=((rbuf)->pread+(num))%(rbuf)->size
102
103/*
104** read <len> bytes from ring buffer into <buf>
105** <usermem> specifies whether <buf> resides in user space
106** returns number of bytes transferred or -EFAULT
107*/
108extern ssize_t dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf, u8 *buf,
109 size_t len, int usermem);
110
111
112/* write routines & macros */
113/* ----------------------- */
114/* write single byte to ring buffer */
115#define DVB_RINGBUFFER_WRITE_BYTE(rbuf,byte) \
116 { (rbuf)->data[(rbuf)->pwrite]=(byte); \
117 (rbuf)->pwrite=((rbuf)->pwrite+1)%(rbuf)->size; }
118/*
119** write <len> bytes to ring buffer
120** <usermem> specifies whether <buf> resides in user space
121** returns number of bytes transferred or -EFAULT
122*/
123extern ssize_t dvb_ringbuffer_write(struct dvb_ringbuffer *rbuf, const u8 *buf,
124 size_t len);
125
126
127/**
128 * Write a packet into the ringbuffer.
129 *
130 * <rbuf> Ringbuffer to write to.
131 * <buf> Buffer to write.
132 * <len> Length of buffer (currently limited to 65535 bytes max).
133 * returns Number of bytes written, or -EFAULT, -ENOMEM, -EVINAL.
134 */
135extern ssize_t dvb_ringbuffer_pkt_write(struct dvb_ringbuffer *rbuf, u8* buf,
136 size_t len);
137
138/**
139 * Read from a packet in the ringbuffer. Note: unlike dvb_ringbuffer_read(), this
140 * does NOT update the read pointer in the ringbuffer. You must use
141 * dvb_ringbuffer_pkt_dispose() to mark a packet as no longer required.
142 *
143 * <rbuf> Ringbuffer concerned.
144 * <idx> Packet index as returned by dvb_ringbuffer_pkt_next().
145 * <offset> Offset into packet to read from.
146 * <buf> Destination buffer for data.
147 * <len> Size of destination buffer.
148 * <usermem> Set to 1 if <buf> is in userspace.
149 * returns Number of bytes read, or -EFAULT.
150 */
151extern ssize_t dvb_ringbuffer_pkt_read(struct dvb_ringbuffer *rbuf, size_t idx,
152 int offset, u8* buf, size_t len, int usermem);
153
154/**
155 * Dispose of a packet in the ring buffer.
156 *
157 * <rbuf> Ring buffer concerned.
158 * <idx> Packet index as returned by dvb_ringbuffer_pkt_next().
159 */
160extern void dvb_ringbuffer_pkt_dispose(struct dvb_ringbuffer *rbuf, size_t idx);
161
162/**
163 * Get the index of the next packet in a ringbuffer.
164 *
165 * <rbuf> Ringbuffer concerned.
166 * <idx> Previous packet index, or -1 to return the first packet index.
167 * <pktlen> On success, will be updated to contain the length of the packet in bytes.
168 * returns Packet index (if >=0), or -1 if no packets available.
169 */
170extern ssize_t dvb_ringbuffer_pkt_next(struct dvb_ringbuffer *rbuf, size_t idx, size_t* pktlen);
171
172
173#endif /* _DVB_RINGBUFFER_H_ */
diff --git a/drivers/media/dvb/dvb-core/dvbdev.c b/drivers/media/dvb/dvb-core/dvbdev.c
new file mode 100644
index 000000000000..cf4ffe38fda3
--- /dev/null
+++ b/drivers/media/dvb/dvb-core/dvbdev.c
@@ -0,0 +1,449 @@
1/*
2 * dvbdev.c
3 *
4 * Copyright (C) 2000 Ralph Metzler <ralph@convergence.de>
5 * & Marcus Metzler <marcus@convergence.de>
6 * for convergence integrated media GmbH
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 *
22 */
23
24#include <linux/types.h>
25#include <linux/errno.h>
26#include <linux/string.h>
27#include <linux/module.h>
28#include <linux/moduleparam.h>
29#include <linux/kernel.h>
30#include <linux/sched.h>
31#include <linux/init.h>
32#include <linux/slab.h>
33#include <linux/device.h>
34#include <linux/fs.h>
35#include <linux/cdev.h>
36
37#include "dvbdev.h"
38
39static int dvbdev_debug;
40
41module_param(dvbdev_debug, int, 0644);
42MODULE_PARM_DESC(dvbdev_debug, "Turn on/off device debugging (default:off).");
43
44#define dprintk if (dvbdev_debug) printk
45
46static LIST_HEAD(dvb_adapter_list);
47static DECLARE_MUTEX(dvbdev_register_lock);
48
49static const char * const dnames[] = {
50 "video", "audio", "sec", "frontend", "demux", "dvr", "ca",
51 "net", "osd"
52};
53
54#define DVB_MAX_ADAPTERS 8
55#define DVB_MAX_IDS 4
56#define nums2minor(num,type,id) ((num << 6) | (id << 4) | type)
57#define MAX_DVB_MINORS (DVB_MAX_ADAPTERS*64)
58
59struct class_simple *dvb_class;
60EXPORT_SYMBOL(dvb_class);
61
62static struct dvb_device* dvbdev_find_device (int minor)
63{
64 struct list_head *entry;
65
66 list_for_each (entry, &dvb_adapter_list) {
67 struct list_head *entry0;
68 struct dvb_adapter *adap;
69 adap = list_entry (entry, struct dvb_adapter, list_head);
70 list_for_each (entry0, &adap->device_list) {
71 struct dvb_device *dev;
72 dev = list_entry (entry0, struct dvb_device, list_head);
73 if (nums2minor(adap->num, dev->type, dev->id) == minor)
74 return dev;
75 }
76 }
77
78 return NULL;
79}
80
81
82static int dvb_device_open(struct inode *inode, struct file *file)
83{
84 struct dvb_device *dvbdev;
85
86 dvbdev = dvbdev_find_device (iminor(inode));
87
88 if (dvbdev && dvbdev->fops) {
89 int err = 0;
90 struct file_operations *old_fops;
91
92 file->private_data = dvbdev;
93 old_fops = file->f_op;
94 file->f_op = fops_get(dvbdev->fops);
95 if(file->f_op->open)
96 err = file->f_op->open(inode,file);
97 if (err) {
98 fops_put(file->f_op);
99 file->f_op = fops_get(old_fops);
100 }
101 fops_put(old_fops);
102 return err;
103 }
104 return -ENODEV;
105}
106
107
108static struct file_operations dvb_device_fops =
109{
110 .owner = THIS_MODULE,
111 .open = dvb_device_open,
112};
113
114static struct cdev dvb_device_cdev = {
115 .kobj = {.name = "dvb", },
116 .owner = THIS_MODULE,
117};
118
119int dvb_generic_open(struct inode *inode, struct file *file)
120{
121 struct dvb_device *dvbdev = file->private_data;
122
123 if (!dvbdev)
124 return -ENODEV;
125
126 if (!dvbdev->users)
127 return -EBUSY;
128
129 if ((file->f_flags & O_ACCMODE) == O_RDONLY) {
130 if (!dvbdev->readers)
131 return -EBUSY;
132 dvbdev->readers--;
133 } else {
134 if (!dvbdev->writers)
135 return -EBUSY;
136 dvbdev->writers--;
137 }
138
139 dvbdev->users--;
140 return 0;
141}
142EXPORT_SYMBOL(dvb_generic_open);
143
144
145int dvb_generic_release(struct inode *inode, struct file *file)
146{
147 struct dvb_device *dvbdev = file->private_data;
148
149 if (!dvbdev)
150 return -ENODEV;
151
152 if ((file->f_flags & O_ACCMODE) == O_RDONLY) {
153 dvbdev->readers++;
154 } else {
155 dvbdev->writers++;
156 }
157
158 dvbdev->users++;
159 return 0;
160}
161EXPORT_SYMBOL(dvb_generic_release);
162
163
164int dvb_generic_ioctl(struct inode *inode, struct file *file,
165 unsigned int cmd, unsigned long arg)
166{
167 struct dvb_device *dvbdev = file->private_data;
168
169 if (!dvbdev)
170 return -ENODEV;
171
172 if (!dvbdev->kernel_ioctl)
173 return -EINVAL;
174
175 return dvb_usercopy (inode, file, cmd, arg, dvbdev->kernel_ioctl);
176}
177EXPORT_SYMBOL(dvb_generic_ioctl);
178
179
180static int dvbdev_get_free_id (struct dvb_adapter *adap, int type)
181{
182 u32 id = 0;
183
184 while (id < DVB_MAX_IDS) {
185 struct list_head *entry;
186 list_for_each (entry, &adap->device_list) {
187 struct dvb_device *dev;
188 dev = list_entry (entry, struct dvb_device, list_head);
189 if (dev->type == type && dev->id == id)
190 goto skip;
191 }
192 return id;
193skip:
194 id++;
195 }
196 return -ENFILE;
197}
198
199
200int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
201 const struct dvb_device *template, void *priv, int type)
202{
203 struct dvb_device *dvbdev;
204 int id;
205
206 if (down_interruptible (&dvbdev_register_lock))
207 return -ERESTARTSYS;
208
209 if ((id = dvbdev_get_free_id (adap, type)) < 0) {
210 up (&dvbdev_register_lock);
211 *pdvbdev = NULL;
212 printk ("%s: could get find free device id...\n", __FUNCTION__);
213 return -ENFILE;
214 }
215
216 *pdvbdev = dvbdev = kmalloc(sizeof(struct dvb_device), GFP_KERNEL);
217
218 if (!dvbdev) {
219 up(&dvbdev_register_lock);
220 return -ENOMEM;
221 }
222
223 up (&dvbdev_register_lock);
224
225 memcpy(dvbdev, template, sizeof(struct dvb_device));
226 dvbdev->type = type;
227 dvbdev->id = id;
228 dvbdev->adapter = adap;
229 dvbdev->priv = priv;
230
231 dvbdev->fops->owner = adap->module;
232
233 list_add_tail (&dvbdev->list_head, &adap->device_list);
234
235 devfs_mk_cdev(MKDEV(DVB_MAJOR, nums2minor(adap->num, type, id)),
236 S_IFCHR | S_IRUSR | S_IWUSR,
237 "dvb/adapter%d/%s%d", adap->num, dnames[type], id);
238
239 class_simple_device_add(dvb_class, MKDEV(DVB_MAJOR, nums2minor(adap->num, type, id)),
240 NULL, "dvb%d.%s%d", adap->num, dnames[type], id);
241
242 dprintk("DVB: register adapter%d/%s%d @ minor: %i (0x%02x)\n",
243 adap->num, dnames[type], id, nums2minor(adap->num, type, id),
244 nums2minor(adap->num, type, id));
245
246 return 0;
247}
248EXPORT_SYMBOL(dvb_register_device);
249
250
251void dvb_unregister_device(struct dvb_device *dvbdev)
252{
253 if (!dvbdev)
254 return;
255
256 devfs_remove("dvb/adapter%d/%s%d", dvbdev->adapter->num,
257 dnames[dvbdev->type], dvbdev->id);
258
259 class_simple_device_remove(MKDEV(DVB_MAJOR, nums2minor(dvbdev->adapter->num,
260 dvbdev->type, dvbdev->id)));
261
262 list_del (&dvbdev->list_head);
263 kfree (dvbdev);
264}
265EXPORT_SYMBOL(dvb_unregister_device);
266
267
268static int dvbdev_get_free_adapter_num (void)
269{
270 int num = 0;
271
272 while (num < DVB_MAX_ADAPTERS) {
273 struct list_head *entry;
274 list_for_each (entry, &dvb_adapter_list) {
275 struct dvb_adapter *adap;
276 adap = list_entry (entry, struct dvb_adapter, list_head);
277 if (adap->num == num)
278 goto skip;
279 }
280 return num;
281skip:
282 num++;
283 }
284
285 return -ENFILE;
286}
287
288
289int dvb_register_adapter(struct dvb_adapter **padap, const char *name, struct module *module)
290{
291 struct dvb_adapter *adap;
292 int num;
293
294 if (down_interruptible (&dvbdev_register_lock))
295 return -ERESTARTSYS;
296
297 if ((num = dvbdev_get_free_adapter_num ()) < 0) {
298 up (&dvbdev_register_lock);
299 return -ENFILE;
300 }
301
302 if (!(*padap = adap = kmalloc(sizeof(struct dvb_adapter), GFP_KERNEL))) {
303 up(&dvbdev_register_lock);
304 return -ENOMEM;
305 }
306
307 memset (adap, 0, sizeof(struct dvb_adapter));
308 INIT_LIST_HEAD (&adap->device_list);
309
310 printk ("DVB: registering new adapter (%s).\n", name);
311
312 devfs_mk_dir("dvb/adapter%d", num);
313 adap->num = num;
314 adap->name = name;
315 adap->module = module;
316
317 list_add_tail (&adap->list_head, &dvb_adapter_list);
318
319 up (&dvbdev_register_lock);
320
321 return num;
322}
323EXPORT_SYMBOL(dvb_register_adapter);
324
325
326int dvb_unregister_adapter(struct dvb_adapter *adap)
327{
328 devfs_remove("dvb/adapter%d", adap->num);
329
330 if (down_interruptible (&dvbdev_register_lock))
331 return -ERESTARTSYS;
332 list_del (&adap->list_head);
333 up (&dvbdev_register_lock);
334 kfree (adap);
335 return 0;
336}
337EXPORT_SYMBOL(dvb_unregister_adapter);
338
339/* if the miracle happens and "generic_usercopy()" is included into
340 the kernel, then this can vanish. please don't make the mistake and
341 define this as video_usercopy(). this will introduce a dependecy
342 to the v4l "videodev.o" module, which is unnecessary for some
343 cards (ie. the budget dvb-cards don't need the v4l module...) */
344int dvb_usercopy(struct inode *inode, struct file *file,
345 unsigned int cmd, unsigned long arg,
346 int (*func)(struct inode *inode, struct file *file,
347 unsigned int cmd, void *arg))
348{
349 char sbuf[128];
350 void *mbuf = NULL;
351 void *parg = NULL;
352 int err = -EINVAL;
353
354 /* Copy arguments into temp kernel buffer */
355 switch (_IOC_DIR(cmd)) {
356 case _IOC_NONE:
357 /*
358 * For this command, the pointer is actually an integer
359 * argument.
360 */
361 parg = (void *) arg;
362 break;
363 case _IOC_READ: /* some v4l ioctls are marked wrong ... */
364 case _IOC_WRITE:
365 case (_IOC_WRITE | _IOC_READ):
366 if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
367 parg = sbuf;
368 } else {
369 /* too big to allocate from stack */
370 mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL);
371 if (NULL == mbuf)
372 return -ENOMEM;
373 parg = mbuf;
374 }
375
376 err = -EFAULT;
377 if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd)))
378 goto out;
379 break;
380 }
381
382 /* call driver */
383 if ((err = func(inode, file, cmd, parg)) == -ENOIOCTLCMD)
384 err = -EINVAL;
385
386 if (err < 0)
387 goto out;
388
389 /* Copy results into user buffer */
390 switch (_IOC_DIR(cmd))
391 {
392 case _IOC_READ:
393 case (_IOC_WRITE | _IOC_READ):
394 if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
395 err = -EFAULT;
396 break;
397 }
398
399out:
400 kfree(mbuf);
401 return err;
402}
403
404static int __init init_dvbdev(void)
405{
406 int retval;
407 dev_t dev = MKDEV(DVB_MAJOR, 0);
408
409 if ((retval = register_chrdev_region(dev, MAX_DVB_MINORS, "DVB")) != 0) {
410 printk("dvb-core: unable to get major %d\n", DVB_MAJOR);
411 return retval;
412 }
413
414 cdev_init(&dvb_device_cdev, &dvb_device_fops);
415 if ((retval = cdev_add(&dvb_device_cdev, dev, MAX_DVB_MINORS)) != 0) {
416 printk("dvb-core: unable to get major %d\n", DVB_MAJOR);
417 goto error;
418 }
419
420 devfs_mk_dir("dvb");
421
422 dvb_class = class_simple_create(THIS_MODULE, "dvb");
423 if (IS_ERR(dvb_class)) {
424 retval = PTR_ERR(dvb_class);
425 goto error;
426 }
427 return 0;
428
429error:
430 cdev_del(&dvb_device_cdev);
431 unregister_chrdev_region(dev, MAX_DVB_MINORS);
432 return retval;
433}
434
435
436static void __exit exit_dvbdev(void)
437{
438 devfs_remove("dvb");
439 class_simple_destroy(dvb_class);
440 cdev_del(&dvb_device_cdev);
441 unregister_chrdev_region(MKDEV(DVB_MAJOR, 0), MAX_DVB_MINORS);
442}
443
444module_init(init_dvbdev);
445module_exit(exit_dvbdev);
446
447MODULE_DESCRIPTION("DVB Core Driver");
448MODULE_AUTHOR("Marcus Metzler, Ralph Metzler, Holger Waechtler");
449MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-core/dvbdev.h b/drivers/media/dvb/dvb-core/dvbdev.h
new file mode 100644
index 000000000000..184edba3caa7
--- /dev/null
+++ b/drivers/media/dvb/dvb-core/dvbdev.h
@@ -0,0 +1,104 @@
1/*
2 * dvbdev.h
3 *
4 * Copyright (C) 2000 Ralph Metzler & Marcus Metzler
5 * for convergence integrated media GmbH
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Lesser Public License
9 * as published by the Free Software Foundation; either version 2.1
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 *
21 */
22
23#ifndef _DVBDEV_H_
24#define _DVBDEV_H_
25
26#include <linux/types.h>
27#include <linux/poll.h>
28#include <linux/fs.h>
29#include <linux/list.h>
30#include <linux/devfs_fs_kernel.h>
31#include <linux/smp_lock.h>
32
33#define DVB_MAJOR 212
34
35#define DVB_DEVICE_VIDEO 0
36#define DVB_DEVICE_AUDIO 1
37#define DVB_DEVICE_SEC 2
38#define DVB_DEVICE_FRONTEND 3
39#define DVB_DEVICE_DEMUX 4
40#define DVB_DEVICE_DVR 5
41#define DVB_DEVICE_CA 6
42#define DVB_DEVICE_NET 7
43#define DVB_DEVICE_OSD 8
44
45
46struct dvb_adapter {
47 int num;
48 struct list_head list_head;
49 struct list_head device_list;
50 const char *name;
51 u8 proposed_mac [6];
52 void* priv;
53
54 struct module *module;
55};
56
57
58struct dvb_device {
59 struct list_head list_head;
60 struct file_operations *fops;
61 struct dvb_adapter *adapter;
62 int type;
63 u32 id;
64
65 /* in theory, 'users' can vanish now,
66 but I don't want to change too much now... */
67 int readers;
68 int writers;
69 int users;
70
71 /* don't really need those !? -- FIXME: use video_usercopy */
72 int (*kernel_ioctl)(struct inode *inode, struct file *file,
73 unsigned int cmd, void *arg);
74
75 void *priv;
76};
77
78
79extern int dvb_register_adapter (struct dvb_adapter **padap, const char *name, struct module *module);
80extern int dvb_unregister_adapter (struct dvb_adapter *adap);
81
82extern int dvb_register_device (struct dvb_adapter *adap,
83 struct dvb_device **pdvbdev,
84 const struct dvb_device *template,
85 void *priv,
86 int type);
87
88extern void dvb_unregister_device (struct dvb_device *dvbdev);
89
90extern int dvb_generic_open (struct inode *inode, struct file *file);
91extern int dvb_generic_release (struct inode *inode, struct file *file);
92extern int dvb_generic_ioctl (struct inode *inode, struct file *file,
93 unsigned int cmd, unsigned long arg);
94
95/* we don't mess with video_usercopy() any more,
96we simply define out own dvb_usercopy(), which will hopefully become
97generic_usercopy() someday... */
98
99extern int dvb_usercopy(struct inode *inode, struct file *file,
100 unsigned int cmd, unsigned long arg,
101 int (*func)(struct inode *inode, struct file *file,
102 unsigned int cmd, void *arg));
103
104#endif /* #ifndef _DVBDEV_H_ */
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig
new file mode 100644
index 000000000000..0bfd4df17d08
--- /dev/null
+++ b/drivers/media/dvb/frontends/Kconfig
@@ -0,0 +1,172 @@
1menu "Customise DVB Frontends"
2 depends on DVB_CORE
3
4comment "DVB-S (satellite) frontends"
5 depends on DVB_CORE
6
7config DVB_STV0299
8 tristate "ST STV0299 based"
9 depends on DVB_CORE
10 help
11 A DVB-S tuner module. Say Y when you want to support this frontend.
12
13config DVB_CX24110
14 tristate "Conexant CX24110 based"
15 depends on DVB_CORE
16 help
17 A DVB-S tuner module. Say Y when you want to support this frontend.
18
19config DVB_TDA8083
20 tristate "Philips TDA8083 based"
21 depends on DVB_CORE
22 help
23 A DVB-S tuner module. Say Y when you want to support this frontend.
24
25config DVB_TDA80XX
26 tristate "Philips TDA8044 or TDA8083 based"
27 depends on DVB_CORE
28 help
29 A DVB-S tuner module. Say Y when you want to support this frontend.
30
31config DVB_MT312
32 tristate "Zarlink MT312 based"
33 depends on DVB_CORE
34 help
35 A DVB-S tuner module. Say Y when you want to support this frontend.
36
37config DVB_VES1X93
38 tristate "VLSI VES1893 or VES1993 based"
39 depends on DVB_CORE
40 help
41 A DVB-S tuner module. Say Y when you want to support this frontend.
42
43comment "DVB-T (terrestrial) frontends"
44 depends on DVB_CORE
45
46config DVB_SP8870
47 tristate "Spase sp8870 based"
48 depends on DVB_CORE
49 select FW_LOADER
50 help
51 A DVB-T tuner module. Say Y when you want to support this frontend.
52
53 This driver needs external firmware. Please use the command
54 "<kerneldir>/Documentation/dvb/get_dvb_firmware sp8870" to
55 download/extract it, and then copy it to /usr/lib/hotplug/firmware.
56
57config DVB_SP887X
58 tristate "Spase sp887x based"
59 depends on DVB_CORE
60 select FW_LOADER
61 help
62 A DVB-T tuner module. Say Y when you want to support this frontend.
63
64 This driver needs external firmware. Please use the command
65 "<kerneldir>/Documentation/dvb/get_dvb_firmware sp887x" to
66 download/extract it, and then copy it to /usr/lib/hotplug/firmware.
67
68config DVB_CX22700
69 tristate "Conexant CX22700 based"
70 depends on DVB_CORE
71 help
72 A DVB-T tuner module. Say Y when you want to support this frontend.
73
74config DVB_CX22702
75 tristate "Conexant cx22702 demodulator (OFDM)"
76 depends on DVB_CORE
77 help
78 A DVB-T tuner module. Say Y when you want to support this frontend.
79
80config DVB_L64781
81 tristate "LSI L64781"
82 depends on DVB_CORE
83 help
84 A DVB-T tuner module. Say Y when you want to support this frontend.
85
86config DVB_TDA1004X
87 tristate "Philips TDA10045H/TDA10046H based"
88 depends on DVB_CORE
89 select FW_LOADER
90 help
91 A DVB-T tuner module. Say Y when you want to support this frontend.
92
93 This driver needs external firmware. Please use the commands
94 "<kerneldir>/Documentation/dvb/get_dvb_firmware tda10045",
95 "<kerneldir>/Documentation/dvb/get_dvb_firmware tda10046" to
96 download/extract them, and then copy them to /usr/lib/hotplug/firmware.
97
98config DVB_NXT6000
99 tristate "NxtWave Communications NXT6000 based"
100 depends on DVB_CORE
101 help
102 A DVB-T tuner module. Say Y when you want to support this frontend.
103
104config DVB_MT352
105 tristate "Zarlink MT352 based"
106 depends on DVB_CORE
107 help
108 A DVB-T tuner module. Say Y when you want to support this frontend.
109
110config DVB_DIB3000MB
111 tristate "DiBcom 3000M-B"
112 depends on DVB_CORE
113 help
114 A DVB-T tuner module. Designed for mobile usage. Say Y when you want
115 to support this frontend.
116
117config DVB_DIB3000MC
118 tristate "DiBcom 3000P/M-C"
119 depends on DVB_CORE
120 help
121 A DVB-T tuner module. Designed for mobile usage. Say Y when you want
122 to support this frontend.
123
124comment "DVB-C (cable) frontends"
125 depends on DVB_CORE
126
127config DVB_ATMEL_AT76C651
128 tristate "Atmel AT76C651 based"
129 depends on DVB_CORE
130 help
131 A DVB-C tuner module. Say Y when you want to support this frontend.
132
133config DVB_VES1820
134 tristate "VLSI VES1820 based"
135 depends on DVB_CORE
136 help
137 A DVB-C tuner module. Say Y when you want to support this frontend.
138
139config DVB_TDA10021
140 tristate "Philips TDA10021 based"
141 depends on DVB_CORE
142 help
143 A DVB-C tuner module. Say Y when you want to support this frontend.
144
145config DVB_STV0297
146 tristate "ST STV0297 based"
147 depends on DVB_CORE
148 help
149 A DVB-C tuner module. Say Y when you want to support this frontend.
150
151comment "ATSC (North American/Korean Terresterial DTV) frontends"
152 depends on DVB_CORE
153
154config DVB_NXT2002
155 tristate "Nxt2002 based"
156 depends on DVB_CORE
157 select FW_LOADER
158 help
159 An ATSC 8VSB tuner module. Say Y when you want to support this frontend.
160
161config DVB_OR51132
162 tristate "OR51132 based (pcHDTV)"
163 depends on DVB_CORE
164
165config DVB_OR51211
166 tristate "or51211 based (pcHDTV HD2000 card)"
167 depends on DVB_CORE
168 select FW_LOADER
169 help
170 An ATSC 8VSB tuner module. Say Y when you want to support this frontend.
171
172endmenu
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile
new file mode 100644
index 000000000000..7f8784870eab
--- /dev/null
+++ b/drivers/media/dvb/frontends/Makefile
@@ -0,0 +1,30 @@
1#
2# Makefile for the kernel DVB frontend device drivers.
3#
4
5EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/
6
7obj-$(CONFIG_DVB_CORE) += dvb-pll.o
8obj-$(CONFIG_DVB_STV0299) += stv0299.o
9obj-$(CONFIG_DVB_SP8870) += sp8870.o
10obj-$(CONFIG_DVB_CX22700) += cx22700.o
11obj-$(CONFIG_DVB_ATMEL_AT76C651) += at76c651.o
12obj-$(CONFIG_DVB_CX24110) += cx24110.o
13obj-$(CONFIG_DVB_TDA8083) += tda8083.o
14obj-$(CONFIG_DVB_L64781) += l64781.o
15obj-$(CONFIG_DVB_DIB3000MB) += dib3000mb.o dib3000-common.o
16obj-$(CONFIG_DVB_DIB3000MC) += dib3000mc.o dib3000-common.o
17obj-$(CONFIG_DVB_MT312) += mt312.o
18obj-$(CONFIG_DVB_VES1820) += ves1820.o
19obj-$(CONFIG_DVB_VES1X93) += ves1x93.o
20obj-$(CONFIG_DVB_TDA1004X) += tda1004x.o
21obj-$(CONFIG_DVB_SP887X) += sp887x.o
22obj-$(CONFIG_DVB_NXT6000) += nxt6000.o
23obj-$(CONFIG_DVB_MT352) += mt352.o
24obj-$(CONFIG_DVB_CX22702) += cx22702.o
25obj-$(CONFIG_DVB_TDA80XX) += tda80xx.o
26obj-$(CONFIG_DVB_TDA10021) += tda10021.o
27obj-$(CONFIG_DVB_STV0297) += stv0297.o
28obj-$(CONFIG_DVB_NXT2002) += nxt2002.o
29obj-$(CONFIG_DVB_OR51211) += or51211.o
30obj-$(CONFIG_DVB_OR51132) += or51132.o
diff --git a/drivers/media/dvb/frontends/at76c651.c b/drivers/media/dvb/frontends/at76c651.c
new file mode 100644
index 000000000000..ce2eaa1640e8
--- /dev/null
+++ b/drivers/media/dvb/frontends/at76c651.c
@@ -0,0 +1,450 @@
1/*
2 * at76c651.c
3 *
4 * Atmel DVB-C Frontend Driver (at76c651/tua6010xs)
5 *
6 * Copyright (C) 2001 fnbrd <fnbrd@gmx.de>
7 * & 2002-2004 Andreas Oberritter <obi@linuxtv.org>
8 * & 2003 Wolfram Joost <dbox2@frokaschwei.de>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (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., 675 Mass Ave, Cambridge, MA 02139, USA.
23 *
24 * AT76C651
25 * http://www.nalanda.nitc.ac.in/industry/datasheets/atmel/acrobat/doc1293.pdf
26 * http://www.atmel.com/atmel/acrobat/doc1320.pdf
27 */
28
29#include <linux/init.h>
30#include <linux/module.h>
31#include <linux/moduleparam.h>
32#include <linux/kernel.h>
33#include <linux/string.h>
34#include <linux/slab.h>
35#include <linux/bitops.h>
36#include "dvb_frontend.h"
37#include "at76c651.h"
38
39
40struct at76c651_state {
41
42 struct i2c_adapter* i2c;
43
44 struct dvb_frontend_ops ops;
45
46 const struct at76c651_config* config;
47
48 struct dvb_frontend frontend;
49
50 /* revision of the chip */
51 u8 revision;
52
53 /* last QAM value set */
54 u8 qam;
55};
56
57static int debug;
58#define dprintk(args...) \
59 do { \
60 if (debug) printk(KERN_DEBUG "at76c651: " args); \
61 } while (0)
62
63
64#if ! defined(__powerpc__)
65static __inline__ int __ilog2(unsigned long x)
66{
67 int i;
68
69 if (x == 0)
70 return -1;
71
72 for (i = 0; x != 0; i++)
73 x >>= 1;
74
75 return i - 1;
76}
77#endif
78
79static int at76c651_writereg(struct at76c651_state* state, u8 reg, u8 data)
80{
81 int ret;
82 u8 buf[] = { reg, data };
83 struct i2c_msg msg =
84 { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 };
85
86 ret = i2c_transfer(state->i2c, &msg, 1);
87
88 if (ret != 1)
89 dprintk("%s: writereg error "
90 "(reg == 0x%02x, val == 0x%02x, ret == %i)\n",
91 __FUNCTION__, reg, data, ret);
92
93 msleep(10);
94
95 return (ret != 1) ? -EREMOTEIO : 0;
96}
97
98static u8 at76c651_readreg(struct at76c651_state* state, u8 reg)
99{
100 int ret;
101 u8 val;
102 struct i2c_msg msg[] = {
103 { .addr = state->config->demod_address, .flags = 0, .buf = &reg, .len = 1 },
104 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = &val, .len = 1 }
105 };
106
107 ret = i2c_transfer(state->i2c, msg, 2);
108
109 if (ret != 2)
110 dprintk("%s: readreg error (ret == %i)\n", __FUNCTION__, ret);
111
112 return val;
113}
114
115static int at76c651_reset(struct at76c651_state* state)
116{
117 return at76c651_writereg(state, 0x07, 0x01);
118}
119
120static void at76c651_disable_interrupts(struct at76c651_state* state)
121{
122 at76c651_writereg(state, 0x0b, 0x00);
123}
124
125static int at76c651_set_auto_config(struct at76c651_state *state)
126{
127 /*
128 * Autoconfig
129 */
130
131 at76c651_writereg(state, 0x06, 0x01);
132
133 /*
134 * Performance optimizations, should be done after autoconfig
135 */
136
137 at76c651_writereg(state, 0x10, 0x06);
138 at76c651_writereg(state, 0x11, ((state->qam == 5) || (state->qam == 7)) ? 0x12 : 0x10);
139 at76c651_writereg(state, 0x15, 0x28);
140 at76c651_writereg(state, 0x20, 0x09);
141 at76c651_writereg(state, 0x24, ((state->qam == 5) || (state->qam == 7)) ? 0xC0 : 0x90);
142 at76c651_writereg(state, 0x30, 0x90);
143 if (state->qam == 5)
144 at76c651_writereg(state, 0x35, 0x2A);
145
146 /*
147 * Initialize A/D-converter
148 */
149
150 if (state->revision == 0x11) {
151 at76c651_writereg(state, 0x2E, 0x38);
152 at76c651_writereg(state, 0x2F, 0x13);
153 }
154
155 at76c651_disable_interrupts(state);
156
157 /*
158 * Restart operation
159 */
160
161 at76c651_reset(state);
162
163 return 0;
164}
165
166static void at76c651_set_bbfreq(struct at76c651_state* state)
167{
168 at76c651_writereg(state, 0x04, 0x3f);
169 at76c651_writereg(state, 0x05, 0xee);
170}
171
172static int at76c651_set_symbol_rate(struct at76c651_state* state, u32 symbol_rate)
173{
174 u8 exponent;
175 u32 mantissa;
176
177 if (symbol_rate > 9360000)
178 return -EINVAL;
179
180 /*
181 * FREF = 57800 kHz
182 * exponent = 10 + floor (log2(symbol_rate / FREF))
183 * mantissa = (symbol_rate / FREF) * (1 << (30 - exponent))
184 */
185
186 exponent = __ilog2((symbol_rate << 4) / 903125);
187 mantissa = ((symbol_rate / 3125) * (1 << (24 - exponent))) / 289;
188
189 at76c651_writereg(state, 0x00, mantissa >> 13);
190 at76c651_writereg(state, 0x01, mantissa >> 5);
191 at76c651_writereg(state, 0x02, (mantissa << 3) | exponent);
192
193 return 0;
194}
195
196static int at76c651_set_qam(struct at76c651_state *state, fe_modulation_t qam)
197{
198 switch (qam) {
199 case QPSK:
200 state->qam = 0x02;
201 break;
202 case QAM_16:
203 state->qam = 0x04;
204 break;
205 case QAM_32:
206 state->qam = 0x05;
207 break;
208 case QAM_64:
209 state->qam = 0x06;
210 break;
211 case QAM_128:
212 state->qam = 0x07;
213 break;
214 case QAM_256:
215 state->qam = 0x08;
216 break;
217#if 0
218 case QAM_512:
219 state->qam = 0x09;
220 break;
221 case QAM_1024:
222 state->qam = 0x0A;
223 break;
224#endif
225 default:
226 return -EINVAL;
227
228 }
229
230 return at76c651_writereg(state, 0x03, state->qam);
231}
232
233static int at76c651_set_inversion(struct at76c651_state* state, fe_spectral_inversion_t inversion)
234{
235 u8 feciqinv = at76c651_readreg(state, 0x60);
236
237 switch (inversion) {
238 case INVERSION_OFF:
239 feciqinv |= 0x02;
240 feciqinv &= 0xFE;
241 break;
242
243 case INVERSION_ON:
244 feciqinv |= 0x03;
245 break;
246
247 case INVERSION_AUTO:
248 feciqinv &= 0xFC;
249 break;
250
251 default:
252 return -EINVAL;
253 }
254
255 return at76c651_writereg(state, 0x60, feciqinv);
256}
257
258static int at76c651_set_parameters(struct dvb_frontend* fe,
259 struct dvb_frontend_parameters *p)
260{
261 int ret;
262 struct at76c651_state* state = (struct at76c651_state*) fe->demodulator_priv;
263
264 at76c651_writereg(state, 0x0c, 0xc3);
265 state->config->pll_set(fe, p);
266 at76c651_writereg(state, 0x0c, 0xc2);
267
268 if ((ret = at76c651_set_symbol_rate(state, p->u.qam.symbol_rate)))
269 return ret;
270
271 if ((ret = at76c651_set_inversion(state, p->inversion)))
272 return ret;
273
274 return at76c651_set_auto_config(state);
275}
276
277static int at76c651_set_defaults(struct dvb_frontend* fe)
278{
279 struct at76c651_state* state = (struct at76c651_state*) fe->demodulator_priv;
280
281 at76c651_set_symbol_rate(state, 6900000);
282 at76c651_set_qam(state, QAM_64);
283 at76c651_set_bbfreq(state);
284 at76c651_set_auto_config(state);
285
286 if (state->config->pll_init) {
287 at76c651_writereg(state, 0x0c, 0xc3);
288 state->config->pll_init(fe);
289 at76c651_writereg(state, 0x0c, 0xc2);
290 }
291
292 return 0;
293}
294
295static int at76c651_read_status(struct dvb_frontend* fe, fe_status_t* status)
296{
297 struct at76c651_state* state = (struct at76c651_state*) fe->demodulator_priv;
298 u8 sync;
299
300 /*
301 * Bits: FEC, CAR, EQU, TIM, AGC2, AGC1, ADC, PLL (PLL=0)
302 */
303 sync = at76c651_readreg(state, 0x80);
304 *status = 0;
305
306 if (sync & (0x04 | 0x10)) /* AGC1 || TIM */
307 *status |= FE_HAS_SIGNAL;
308 if (sync & 0x10) /* TIM */
309 *status |= FE_HAS_CARRIER;
310 if (sync & 0x80) /* FEC */
311 *status |= FE_HAS_VITERBI;
312 if (sync & 0x40) /* CAR */
313 *status |= FE_HAS_SYNC;
314 if ((sync & 0xF0) == 0xF0) /* TIM && EQU && CAR && FEC */
315 *status |= FE_HAS_LOCK;
316
317 return 0;
318}
319
320static int at76c651_read_ber(struct dvb_frontend* fe, u32* ber)
321{
322 struct at76c651_state* state = (struct at76c651_state*) fe->demodulator_priv;
323
324 *ber = (at76c651_readreg(state, 0x81) & 0x0F) << 16;
325 *ber |= at76c651_readreg(state, 0x82) << 8;
326 *ber |= at76c651_readreg(state, 0x83);
327 *ber *= 10;
328
329 return 0;
330}
331
332static int at76c651_read_signal_strength(struct dvb_frontend* fe, u16* strength)
333{
334 struct at76c651_state* state = (struct at76c651_state*) fe->demodulator_priv;
335
336 u8 gain = ~at76c651_readreg(state, 0x91);
337 *strength = (gain << 8) | gain;
338
339 return 0;
340}
341
342static int at76c651_read_snr(struct dvb_frontend* fe, u16* snr)
343{
344 struct at76c651_state* state = (struct at76c651_state*) fe->demodulator_priv;
345
346 *snr = 0xFFFF -
347 ((at76c651_readreg(state, 0x8F) << 8) |
348 at76c651_readreg(state, 0x90));
349
350 return 0;
351}
352
353static int at76c651_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
354{
355 struct at76c651_state* state = (struct at76c651_state*) fe->demodulator_priv;
356
357 *ucblocks = at76c651_readreg(state, 0x82);
358
359 return 0;
360}
361
362static int at76c651_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *fesettings)
363{
364 fesettings->min_delay_ms = 50;
365 fesettings->step_size = 0;
366 fesettings->max_drift = 0;
367 return 0;
368}
369
370static void at76c651_release(struct dvb_frontend* fe)
371{
372 struct at76c651_state* state = (struct at76c651_state*) fe->demodulator_priv;
373 kfree(state);
374}
375
376static struct dvb_frontend_ops at76c651_ops;
377
378struct dvb_frontend* at76c651_attach(const struct at76c651_config* config,
379 struct i2c_adapter* i2c)
380{
381 struct at76c651_state* state = NULL;
382
383 /* allocate memory for the internal state */
384 state = (struct at76c651_state*) kmalloc(sizeof(struct at76c651_state), GFP_KERNEL);
385 if (state == NULL) goto error;
386
387 /* setup the state */
388 state->config = config;
389 state->qam = 0;
390
391 /* check if the demod is there */
392 if (at76c651_readreg(state, 0x0e) != 0x65) goto error;
393
394 /* finalise state setup */
395 state->i2c = i2c;
396 state->revision = at76c651_readreg(state, 0x0f) & 0xfe;
397 memcpy(&state->ops, &at76c651_ops, sizeof(struct dvb_frontend_ops));
398
399 /* create dvb_frontend */
400 state->frontend.ops = &state->ops;
401 state->frontend.demodulator_priv = state;
402 return &state->frontend;
403
404error:
405 kfree(state);
406 return NULL;
407}
408
409static struct dvb_frontend_ops at76c651_ops = {
410
411 .info = {
412 .name = "Atmel AT76C651B DVB-C",
413 .type = FE_QAM,
414 .frequency_min = 48250000,
415 .frequency_max = 863250000,
416 .frequency_stepsize = 62500,
417 /*.frequency_tolerance = */ /* FIXME: 12% of SR */
418 .symbol_rate_min = 0, /* FIXME */
419 .symbol_rate_max = 9360000, /* FIXME */
420 .symbol_rate_tolerance = 4000,
421 .caps = FE_CAN_INVERSION_AUTO |
422 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
423 FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 |
424 FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO |
425 FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 | FE_CAN_QAM_128 |
426 FE_CAN_MUTE_TS | FE_CAN_QAM_256 | FE_CAN_RECOVER
427 },
428
429 .release = at76c651_release,
430
431 .init = at76c651_set_defaults,
432
433 .set_frontend = at76c651_set_parameters,
434 .get_tune_settings = at76c651_get_tune_settings,
435
436 .read_status = at76c651_read_status,
437 .read_ber = at76c651_read_ber,
438 .read_signal_strength = at76c651_read_signal_strength,
439 .read_snr = at76c651_read_snr,
440 .read_ucblocks = at76c651_read_ucblocks,
441};
442
443module_param(debug, int, 0644);
444MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
445
446MODULE_DESCRIPTION("Atmel AT76C651 DVB-C Demodulator Driver");
447MODULE_AUTHOR("Andreas Oberritter <obi@linuxtv.org>");
448MODULE_LICENSE("GPL");
449
450EXPORT_SYMBOL(at76c651_attach);
diff --git a/drivers/media/dvb/frontends/at76c651.h b/drivers/media/dvb/frontends/at76c651.h
new file mode 100644
index 000000000000..34054df93608
--- /dev/null
+++ b/drivers/media/dvb/frontends/at76c651.h
@@ -0,0 +1,47 @@
1/*
2 * at76c651.c
3 *
4 * Atmel DVB-C Frontend Driver (at76c651)
5 *
6 * Copyright (C) 2001 fnbrd <fnbrd@gmx.de>
7 * & 2002-2004 Andreas Oberritter <obi@linuxtv.org>
8 * & 2003 Wolfram Joost <dbox2@frokaschwei.de>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (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., 675 Mass Ave, Cambridge, MA 02139, USA.
23 *
24 * AT76C651
25 * http://www.nalanda.nitc.ac.in/industry/datasheets/atmel/acrobat/doc1293.pdf
26 * http://www.atmel.com/atmel/acrobat/doc1320.pdf
27 */
28
29#ifndef AT76C651_H
30#define AT76C651_H
31
32#include <linux/dvb/frontend.h>
33
34struct at76c651_config
35{
36 /* the demodulator's i2c address */
37 u8 demod_address;
38
39 /* PLL maintenance */
40 int (*pll_init)(struct dvb_frontend* fe);
41 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
42};
43
44extern struct dvb_frontend* at76c651_attach(const struct at76c651_config* config,
45 struct i2c_adapter* i2c);
46
47#endif // AT76C651_H
diff --git a/drivers/media/dvb/frontends/cx22700.c b/drivers/media/dvb/frontends/cx22700.c
new file mode 100644
index 000000000000..a212279042b8
--- /dev/null
+++ b/drivers/media/dvb/frontends/cx22700.c
@@ -0,0 +1,435 @@
1/*
2 Conexant cx22700 DVB OFDM demodulator driver
3
4 Copyright (C) 2001-2002 Convergence Integrated Media GmbH
5 Holger Waechtler <holger@convergence.de>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21*/
22
23#include <linux/kernel.h>
24#include <linux/init.h>
25#include <linux/module.h>
26#include <linux/moduleparam.h>
27#include <linux/string.h>
28#include <linux/slab.h>
29#include "dvb_frontend.h"
30#include "cx22700.h"
31
32
33struct cx22700_state {
34
35 struct i2c_adapter* i2c;
36
37 struct dvb_frontend_ops ops;
38
39 const struct cx22700_config* config;
40
41 struct dvb_frontend frontend;
42};
43
44
45static int debug;
46#define dprintk(args...) \
47 do { \
48 if (debug) printk(KERN_DEBUG "cx22700: " args); \
49 } while (0)
50
51static u8 init_tab [] = {
52 0x04, 0x10,
53 0x05, 0x09,
54 0x06, 0x00,
55 0x08, 0x04,
56 0x09, 0x00,
57 0x0a, 0x01,
58 0x15, 0x40,
59 0x16, 0x10,
60 0x17, 0x87,
61 0x18, 0x17,
62 0x1a, 0x10,
63 0x25, 0x04,
64 0x2e, 0x00,
65 0x39, 0x00,
66 0x3a, 0x04,
67 0x45, 0x08,
68 0x46, 0x02,
69 0x47, 0x05,
70};
71
72
73static int cx22700_writereg (struct cx22700_state* state, u8 reg, u8 data)
74{
75 int ret;
76 u8 buf [] = { reg, data };
77 struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 };
78
79 dprintk ("%s\n", __FUNCTION__);
80
81 ret = i2c_transfer (state->i2c, &msg, 1);
82
83 if (ret != 1)
84 printk("%s: writereg error (reg == 0x%02x, val == 0x%02x, ret == %i)\n",
85 __FUNCTION__, reg, data, ret);
86
87 return (ret != 1) ? -1 : 0;
88}
89
90static int cx22700_readreg (struct cx22700_state* state, u8 reg)
91{
92 int ret;
93 u8 b0 [] = { reg };
94 u8 b1 [] = { 0 };
95 struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 },
96 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
97
98 dprintk ("%s\n", __FUNCTION__);
99
100 ret = i2c_transfer (state->i2c, msg, 2);
101
102 if (ret != 2) return -EIO;
103
104 return b1[0];
105}
106
107static int cx22700_set_inversion (struct cx22700_state* state, int inversion)
108{
109 u8 val;
110
111 dprintk ("%s\n", __FUNCTION__);
112
113 switch (inversion) {
114 case INVERSION_AUTO:
115 return -EOPNOTSUPP;
116 case INVERSION_ON:
117 val = cx22700_readreg (state, 0x09);
118 return cx22700_writereg (state, 0x09, val | 0x01);
119 case INVERSION_OFF:
120 val = cx22700_readreg (state, 0x09);
121 return cx22700_writereg (state, 0x09, val & 0xfe);
122 default:
123 return -EINVAL;
124 }
125}
126
127static int cx22700_set_tps (struct cx22700_state *state, struct dvb_ofdm_parameters *p)
128{
129 static const u8 qam_tab [4] = { 0, 1, 0, 2 };
130 static const u8 fec_tab [6] = { 0, 1, 2, 0, 3, 4 };
131 u8 val;
132
133 dprintk ("%s\n", __FUNCTION__);
134
135 if (p->code_rate_HP < FEC_1_2 || p->code_rate_HP > FEC_7_8)
136 return -EINVAL;
137
138 if (p->code_rate_LP < FEC_1_2 || p->code_rate_LP > FEC_7_8)
139
140 if (p->code_rate_HP == FEC_4_5 || p->code_rate_LP == FEC_4_5)
141 return -EINVAL;
142
143 if (p->guard_interval < GUARD_INTERVAL_1_32 ||
144 p->guard_interval > GUARD_INTERVAL_1_4)
145 return -EINVAL;
146
147 if (p->transmission_mode != TRANSMISSION_MODE_2K &&
148 p->transmission_mode != TRANSMISSION_MODE_8K)
149 return -EINVAL;
150
151 if (p->constellation != QPSK &&
152 p->constellation != QAM_16 &&
153 p->constellation != QAM_64)
154 return -EINVAL;
155
156 if (p->hierarchy_information < HIERARCHY_NONE ||
157 p->hierarchy_information > HIERARCHY_4)
158 return -EINVAL;
159
160 if (p->bandwidth < BANDWIDTH_8_MHZ && p->bandwidth > BANDWIDTH_6_MHZ)
161 return -EINVAL;
162
163 if (p->bandwidth == BANDWIDTH_7_MHZ)
164 cx22700_writereg (state, 0x09, cx22700_readreg (state, 0x09 | 0x10));
165 else
166 cx22700_writereg (state, 0x09, cx22700_readreg (state, 0x09 & ~0x10));
167
168 val = qam_tab[p->constellation - QPSK];
169 val |= p->hierarchy_information - HIERARCHY_NONE;
170
171 cx22700_writereg (state, 0x04, val);
172
173 val = fec_tab[p->code_rate_HP - FEC_1_2] << 3;
174 val |= fec_tab[p->code_rate_LP - FEC_1_2];
175
176 cx22700_writereg (state, 0x05, val);
177
178 val = (p->guard_interval - GUARD_INTERVAL_1_32) << 2;
179 val |= p->transmission_mode - TRANSMISSION_MODE_2K;
180
181 cx22700_writereg (state, 0x06, val);
182
183 cx22700_writereg (state, 0x08, 0x04 | 0x02); /* use user tps parameters */
184 cx22700_writereg (state, 0x08, 0x04); /* restart aquisition */
185
186 return 0;
187}
188
189static int cx22700_get_tps (struct cx22700_state* state, struct dvb_ofdm_parameters *p)
190{
191 static const fe_modulation_t qam_tab [3] = { QPSK, QAM_16, QAM_64 };
192 static const fe_code_rate_t fec_tab [5] = { FEC_1_2, FEC_2_3, FEC_3_4,
193 FEC_5_6, FEC_7_8 };
194 u8 val;
195
196 dprintk ("%s\n", __FUNCTION__);
197
198 if (!(cx22700_readreg(state, 0x07) & 0x20)) /* tps valid? */
199 return -EAGAIN;
200
201 val = cx22700_readreg (state, 0x01);
202
203 if ((val & 0x7) > 4)
204 p->hierarchy_information = HIERARCHY_AUTO;
205 else
206 p->hierarchy_information = HIERARCHY_NONE + (val & 0x7);
207
208 if (((val >> 3) & 0x3) > 2)
209 p->constellation = QAM_AUTO;
210 else
211 p->constellation = qam_tab[(val >> 3) & 0x3];
212
213 val = cx22700_readreg (state, 0x02);
214
215 if (((val >> 3) & 0x07) > 4)
216 p->code_rate_HP = FEC_AUTO;
217 else
218 p->code_rate_HP = fec_tab[(val >> 3) & 0x07];
219
220 if ((val & 0x07) > 4)
221 p->code_rate_LP = FEC_AUTO;
222 else
223 p->code_rate_LP = fec_tab[val & 0x07];
224
225 val = cx22700_readreg (state, 0x03);
226
227 p->guard_interval = GUARD_INTERVAL_1_32 + ((val >> 6) & 0x3);
228 p->transmission_mode = TRANSMISSION_MODE_2K + ((val >> 5) & 0x1);
229
230 return 0;
231}
232
233static int cx22700_init (struct dvb_frontend* fe)
234
235{ struct cx22700_state* state = (struct cx22700_state*) fe->demodulator_priv;
236 int i;
237
238 dprintk("cx22700_init: init chip\n");
239
240 cx22700_writereg (state, 0x00, 0x02); /* soft reset */
241 cx22700_writereg (state, 0x00, 0x00);
242
243 msleep(10);
244
245 for (i=0; i<sizeof(init_tab); i+=2)
246 cx22700_writereg (state, init_tab[i], init_tab[i+1]);
247
248 cx22700_writereg (state, 0x00, 0x01);
249
250 if (state->config->pll_init) {
251 cx22700_writereg (state, 0x0a, 0x00); /* open i2c bus switch */
252 state->config->pll_init(fe);
253 cx22700_writereg (state, 0x0a, 0x01); /* close i2c bus switch */
254 }
255
256 return 0;
257}
258
259static int cx22700_read_status(struct dvb_frontend* fe, fe_status_t* status)
260{
261 struct cx22700_state* state = (struct cx22700_state*) fe->demodulator_priv;
262
263 u16 rs_ber = (cx22700_readreg (state, 0x0d) << 9)
264 | (cx22700_readreg (state, 0x0e) << 1);
265 u8 sync = cx22700_readreg (state, 0x07);
266
267 *status = 0;
268
269 if (rs_ber < 0xff00)
270 *status |= FE_HAS_SIGNAL;
271
272 if (sync & 0x20)
273 *status |= FE_HAS_CARRIER;
274
275 if (sync & 0x10)
276 *status |= FE_HAS_VITERBI;
277
278 if (sync & 0x10)
279 *status |= FE_HAS_SYNC;
280
281 if (*status == 0x0f)
282 *status |= FE_HAS_LOCK;
283
284 return 0;
285}
286
287static int cx22700_read_ber(struct dvb_frontend* fe, u32* ber)
288{
289 struct cx22700_state* state = (struct cx22700_state*) fe->demodulator_priv;
290
291 *ber = cx22700_readreg (state, 0x0c) & 0x7f;
292 cx22700_writereg (state, 0x0c, 0x00);
293
294 return 0;
295}
296
297static int cx22700_read_signal_strength(struct dvb_frontend* fe, u16* signal_strength)
298{
299 struct cx22700_state* state = (struct cx22700_state*) fe->demodulator_priv;
300
301 u16 rs_ber = (cx22700_readreg (state, 0x0d) << 9)
302 | (cx22700_readreg (state, 0x0e) << 1);
303 *signal_strength = ~rs_ber;
304
305 return 0;
306}
307
308static int cx22700_read_snr(struct dvb_frontend* fe, u16* snr)
309{
310 struct cx22700_state* state = (struct cx22700_state*) fe->demodulator_priv;
311
312 u16 rs_ber = (cx22700_readreg (state, 0x0d) << 9)
313 | (cx22700_readreg (state, 0x0e) << 1);
314 *snr = ~rs_ber;
315
316 return 0;
317}
318
319static int cx22700_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
320{
321 struct cx22700_state* state = (struct cx22700_state*) fe->demodulator_priv;
322
323 *ucblocks = cx22700_readreg (state, 0x0f);
324 cx22700_writereg (state, 0x0f, 0x00);
325
326 return 0;
327}
328
329static int cx22700_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
330{
331 struct cx22700_state* state = (struct cx22700_state*) fe->demodulator_priv;
332
333 cx22700_writereg (state, 0x00, 0x02); /* XXX CHECKME: soft reset*/
334 cx22700_writereg (state, 0x00, 0x00);
335
336 cx22700_writereg (state, 0x0a, 0x00); /* open i2c bus switch */
337 state->config->pll_set(fe, p);
338 cx22700_writereg (state, 0x0a, 0x01); /* close i2c bus switch */
339 cx22700_set_inversion (state, p->inversion);
340 cx22700_set_tps (state, &p->u.ofdm);
341 cx22700_writereg (state, 0x37, 0x01); /* PAL loop filter off */
342 cx22700_writereg (state, 0x00, 0x01); /* restart acquire */
343
344 return 0;
345}
346
347static int cx22700_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
348{
349 struct cx22700_state* state = (struct cx22700_state*) fe->demodulator_priv;
350 u8 reg09 = cx22700_readreg (state, 0x09);
351
352 p->inversion = reg09 & 0x1 ? INVERSION_ON : INVERSION_OFF;
353 return cx22700_get_tps (state, &p->u.ofdm);
354}
355
356static int cx22700_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
357{
358 fesettings->min_delay_ms = 150;
359 fesettings->step_size = 166667;
360 fesettings->max_drift = 166667*2;
361 return 0;
362}
363
364static void cx22700_release(struct dvb_frontend* fe)
365{
366 struct cx22700_state* state = (struct cx22700_state*) fe->demodulator_priv;
367 kfree(state);
368}
369
370static struct dvb_frontend_ops cx22700_ops;
371
372struct dvb_frontend* cx22700_attach(const struct cx22700_config* config,
373 struct i2c_adapter* i2c)
374{
375 struct cx22700_state* state = NULL;
376
377 /* allocate memory for the internal state */
378 state = (struct cx22700_state*) kmalloc(sizeof(struct cx22700_state), GFP_KERNEL);
379 if (state == NULL) goto error;
380
381 /* setup the state */
382 state->config = config;
383 state->i2c = i2c;
384 memcpy(&state->ops, &cx22700_ops, sizeof(struct dvb_frontend_ops));
385
386 /* check if the demod is there */
387 if (cx22700_readreg(state, 0x07) < 0) goto error;
388
389 /* create dvb_frontend */
390 state->frontend.ops = &state->ops;
391 state->frontend.demodulator_priv = state;
392 return &state->frontend;
393
394error:
395 kfree(state);
396 return NULL;
397}
398
399static struct dvb_frontend_ops cx22700_ops = {
400
401 .info = {
402 .name = "Conexant CX22700 DVB-T",
403 .type = FE_OFDM,
404 .frequency_min = 470000000,
405 .frequency_max = 860000000,
406 .frequency_stepsize = 166667,
407 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
408 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
409 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 |
410 FE_CAN_RECOVER
411 },
412
413 .release = cx22700_release,
414
415 .init = cx22700_init,
416
417 .set_frontend = cx22700_set_frontend,
418 .get_frontend = cx22700_get_frontend,
419 .get_tune_settings = cx22700_get_tune_settings,
420
421 .read_status = cx22700_read_status,
422 .read_ber = cx22700_read_ber,
423 .read_signal_strength = cx22700_read_signal_strength,
424 .read_snr = cx22700_read_snr,
425 .read_ucblocks = cx22700_read_ucblocks,
426};
427
428module_param(debug, int, 0644);
429MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
430
431MODULE_DESCRIPTION("Conexant CX22700 DVB-T Demodulator driver");
432MODULE_AUTHOR("Holger Waechtler");
433MODULE_LICENSE("GPL");
434
435EXPORT_SYMBOL(cx22700_attach);
diff --git a/drivers/media/dvb/frontends/cx22700.h b/drivers/media/dvb/frontends/cx22700.h
new file mode 100644
index 000000000000..c9145b45874b
--- /dev/null
+++ b/drivers/media/dvb/frontends/cx22700.h
@@ -0,0 +1,41 @@
1/*
2 Conexant CX22700 DVB OFDM demodulator driver
3
4 Copyright (C) 2001-2002 Convergence Integrated Media GmbH
5 Holger Waechtler <holger@convergence.de>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21*/
22
23#ifndef CX22700_H
24#define CX22700_H
25
26#include <linux/dvb/frontend.h>
27
28struct cx22700_config
29{
30 /* the demodulator's i2c address */
31 u8 demod_address;
32
33 /* PLL maintenance */
34 int (*pll_init)(struct dvb_frontend* fe);
35 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
36};
37
38extern struct dvb_frontend* cx22700_attach(const struct cx22700_config* config,
39 struct i2c_adapter* i2c);
40
41#endif // CX22700_H
diff --git a/drivers/media/dvb/frontends/cx22702.c b/drivers/media/dvb/frontends/cx22702.c
new file mode 100644
index 000000000000..1930b513eefa
--- /dev/null
+++ b/drivers/media/dvb/frontends/cx22702.c
@@ -0,0 +1,519 @@
1/*
2 Conexant 22702 DVB OFDM demodulator driver
3
4 based on:
5 Alps TDMB7 DVB OFDM demodulator driver
6
7 Copyright (C) 2001-2002 Convergence Integrated Media GmbH
8 Holger Waechtler <holger@convergence.de>
9
10 Copyright (C) 2004 Steven Toth <steve@toth.demon.co.uk>
11
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
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 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., 675 Mass Ave, Cambridge, MA 02139, USA.
25
26*/
27
28#include <linux/kernel.h>
29#include <linux/init.h>
30#include <linux/module.h>
31#include <linux/string.h>
32#include <linux/slab.h>
33#include <linux/delay.h>
34#include "dvb_frontend.h"
35#include "cx22702.h"
36
37
38struct cx22702_state {
39
40 struct i2c_adapter* i2c;
41
42 struct dvb_frontend_ops ops;
43
44 /* configuration settings */
45 const struct cx22702_config* config;
46
47 struct dvb_frontend frontend;
48
49 /* previous uncorrected block counter */
50 u8 prevUCBlocks;
51};
52
53static int debug = 0;
54#define dprintk if (debug) printk
55
56/* Register values to initialise the demod */
57static u8 init_tab [] = {
58 0x00, 0x00, /* Stop aquisition */
59 0x0B, 0x06,
60 0x09, 0x01,
61 0x0D, 0x41,
62 0x16, 0x32,
63 0x20, 0x0A,
64 0x21, 0x17,
65 0x24, 0x3e,
66 0x26, 0xff,
67 0x27, 0x10,
68 0x28, 0x00,
69 0x29, 0x00,
70 0x2a, 0x10,
71 0x2b, 0x00,
72 0x2c, 0x10,
73 0x2d, 0x00,
74 0x48, 0xd4,
75 0x49, 0x56,
76 0x6b, 0x1e,
77 0xc8, 0x02,
78 0xf8, 0x02,
79 0xf9, 0x00,
80 0xfa, 0x00,
81 0xfb, 0x00,
82 0xfc, 0x00,
83 0xfd, 0x00,
84};
85
86static int cx22702_writereg (struct cx22702_state* state, u8 reg, u8 data)
87{
88 int ret;
89 u8 buf [] = { reg, data };
90 struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 };
91
92 ret = i2c_transfer(state->i2c, &msg, 1);
93
94 if (ret != 1)
95 printk("%s: writereg error (reg == 0x%02x, val == 0x%02x, ret == %i)\n",
96 __FUNCTION__, reg, data, ret);
97
98 return (ret != 1) ? -1 : 0;
99}
100
101static u8 cx22702_readreg (struct cx22702_state* state, u8 reg)
102{
103 int ret;
104 u8 b0 [] = { reg };
105 u8 b1 [] = { 0 };
106
107 struct i2c_msg msg [] = {
108 { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 },
109 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
110
111 ret = i2c_transfer(state->i2c, msg, 2);
112
113 if (ret != 2)
114 printk("%s: readreg error (ret == %i)\n", __FUNCTION__, ret);
115
116 return b1[0];
117}
118
119static int cx22702_set_inversion (struct cx22702_state *state, int inversion)
120{
121 u8 val;
122
123 switch (inversion) {
124
125 case INVERSION_AUTO:
126 return -EOPNOTSUPP;
127
128 case INVERSION_ON:
129 val = cx22702_readreg (state, 0x0C);
130 return cx22702_writereg (state, 0x0C, val | 0x01);
131
132 case INVERSION_OFF:
133 val = cx22702_readreg (state, 0x0C);
134 return cx22702_writereg (state, 0x0C, val & 0xfe);
135
136 default:
137 return -EINVAL;
138
139 }
140
141}
142
143/* Retrieve the demod settings */
144static int cx22702_get_tps (struct cx22702_state *state, struct dvb_ofdm_parameters *p)
145{
146 u8 val;
147
148 /* Make sure the TPS regs are valid */
149 if (!(cx22702_readreg(state, 0x0A) & 0x20))
150 return -EAGAIN;
151
152 val = cx22702_readreg (state, 0x01);
153 switch( (val&0x18)>>3) {
154 case 0: p->constellation = QPSK; break;
155 case 1: p->constellation = QAM_16; break;
156 case 2: p->constellation = QAM_64; break;
157 }
158 switch( val&0x07 ) {
159 case 0: p->hierarchy_information = HIERARCHY_NONE; break;
160 case 1: p->hierarchy_information = HIERARCHY_1; break;
161 case 2: p->hierarchy_information = HIERARCHY_2; break;
162 case 3: p->hierarchy_information = HIERARCHY_4; break;
163 }
164
165
166 val = cx22702_readreg (state, 0x02);
167 switch( (val&0x38)>>3 ) {
168 case 0: p->code_rate_HP = FEC_1_2; break;
169 case 1: p->code_rate_HP = FEC_2_3; break;
170 case 2: p->code_rate_HP = FEC_3_4; break;
171 case 3: p->code_rate_HP = FEC_5_6; break;
172 case 4: p->code_rate_HP = FEC_7_8; break;
173 }
174 switch( val&0x07 ) {
175 case 0: p->code_rate_LP = FEC_1_2; break;
176 case 1: p->code_rate_LP = FEC_2_3; break;
177 case 2: p->code_rate_LP = FEC_3_4; break;
178 case 3: p->code_rate_LP = FEC_5_6; break;
179 case 4: p->code_rate_LP = FEC_7_8; break;
180 }
181
182
183 val = cx22702_readreg (state, 0x03);
184 switch( (val&0x0c)>>2 ) {
185 case 0: p->guard_interval = GUARD_INTERVAL_1_32; break;
186 case 1: p->guard_interval = GUARD_INTERVAL_1_16; break;
187 case 2: p->guard_interval = GUARD_INTERVAL_1_8; break;
188 case 3: p->guard_interval = GUARD_INTERVAL_1_4; break;
189 }
190 switch( val&0x03 ) {
191 case 0: p->transmission_mode = TRANSMISSION_MODE_2K; break;
192 case 1: p->transmission_mode = TRANSMISSION_MODE_8K; break;
193 }
194
195 return 0;
196}
197
198/* Talk to the demod, set the FEC, GUARD, QAM settings etc */
199static int cx22702_set_tps (struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
200{
201 u8 val;
202 struct cx22702_state* state = (struct cx22702_state*) fe->demodulator_priv;
203
204 /* set PLL */
205 cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) &0xfe);
206 state->config->pll_set(fe, p);
207 cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) | 1);
208
209 /* set inversion */
210 cx22702_set_inversion (state, p->inversion);
211
212 /* set bandwidth */
213 switch(p->u.ofdm.bandwidth) {
214 case BANDWIDTH_6_MHZ:
215 cx22702_writereg(state, 0x0C, (cx22702_readreg(state, 0x0C) & 0xcf) | 0x20 );
216 break;
217 case BANDWIDTH_7_MHZ:
218 cx22702_writereg(state, 0x0C, (cx22702_readreg(state, 0x0C) & 0xcf) | 0x10 );
219 break;
220 case BANDWIDTH_8_MHZ:
221 cx22702_writereg(state, 0x0C, cx22702_readreg(state, 0x0C) &0xcf );
222 break;
223 default:
224 dprintk ("%s: invalid bandwidth\n",__FUNCTION__);
225 return -EINVAL;
226 }
227
228
229 p->u.ofdm.code_rate_LP = FEC_AUTO; //temp hack as manual not working
230
231 /* use auto configuration? */
232 if((p->u.ofdm.hierarchy_information==HIERARCHY_AUTO) ||
233 (p->u.ofdm.constellation==QAM_AUTO) ||
234 (p->u.ofdm.code_rate_HP==FEC_AUTO) ||
235 (p->u.ofdm.code_rate_LP==FEC_AUTO) ||
236 (p->u.ofdm.guard_interval==GUARD_INTERVAL_AUTO) ||
237 (p->u.ofdm.transmission_mode==TRANSMISSION_MODE_AUTO) ) {
238
239 /* TPS Source - use hardware driven values */
240 cx22702_writereg(state, 0x06, 0x10);
241 cx22702_writereg(state, 0x07, 0x9);
242 cx22702_writereg(state, 0x08, 0xC1);
243 cx22702_writereg(state, 0x0B, cx22702_readreg(state, 0x0B) & 0xfc );
244 cx22702_writereg(state, 0x0C, (cx22702_readreg(state, 0x0C) & 0xBF) | 0x40 );
245 cx22702_writereg(state, 0x00, 0x01); /* Begin aquisition */
246 printk("%s: Autodetecting\n",__FUNCTION__);
247 return 0;
248 }
249
250 /* manually programmed values */
251 val=0;
252 switch(p->u.ofdm.constellation) {
253 case QPSK: val = (val&0xe7); break;
254 case QAM_16: val = (val&0xe7)|0x08; break;
255 case QAM_64: val = (val&0xe7)|0x10; break;
256 default:
257 dprintk ("%s: invalid constellation\n",__FUNCTION__);
258 return -EINVAL;
259 }
260 switch(p->u.ofdm.hierarchy_information) {
261 case HIERARCHY_NONE: val = (val&0xf8); break;
262 case HIERARCHY_1: val = (val&0xf8)|1; break;
263 case HIERARCHY_2: val = (val&0xf8)|2; break;
264 case HIERARCHY_4: val = (val&0xf8)|3; break;
265 default:
266 dprintk ("%s: invalid hierarchy\n",__FUNCTION__);
267 return -EINVAL;
268 }
269 cx22702_writereg (state, 0x06, val);
270
271 val=0;
272 switch(p->u.ofdm.code_rate_HP) {
273 case FEC_NONE:
274 case FEC_1_2: val = (val&0xc7); break;
275 case FEC_2_3: val = (val&0xc7)|0x08; break;
276 case FEC_3_4: val = (val&0xc7)|0x10; break;
277 case FEC_5_6: val = (val&0xc7)|0x18; break;
278 case FEC_7_8: val = (val&0xc7)|0x20; break;
279 default:
280 dprintk ("%s: invalid code_rate_HP\n",__FUNCTION__);
281 return -EINVAL;
282 }
283 switch(p->u.ofdm.code_rate_LP) {
284 case FEC_NONE:
285 case FEC_1_2: val = (val&0xf8); break;
286 case FEC_2_3: val = (val&0xf8)|1; break;
287 case FEC_3_4: val = (val&0xf8)|2; break;
288 case FEC_5_6: val = (val&0xf8)|3; break;
289 case FEC_7_8: val = (val&0xf8)|4; break;
290 default:
291 dprintk ("%s: invalid code_rate_LP\n",__FUNCTION__);
292 return -EINVAL;
293 }
294 cx22702_writereg (state, 0x07, val);
295
296 val=0;
297 switch(p->u.ofdm.guard_interval) {
298 case GUARD_INTERVAL_1_32: val = (val&0xf3); break;
299 case GUARD_INTERVAL_1_16: val = (val&0xf3)|0x04; break;
300 case GUARD_INTERVAL_1_8: val = (val&0xf3)|0x08; break;
301 case GUARD_INTERVAL_1_4: val = (val&0xf3)|0x0c; break;
302 default:
303 dprintk ("%s: invalid guard_interval\n",__FUNCTION__);
304 return -EINVAL;
305 }
306 switch(p->u.ofdm.transmission_mode) {
307 case TRANSMISSION_MODE_2K: val = (val&0xfc); break;
308 case TRANSMISSION_MODE_8K: val = (val&0xfc)|1; break;
309 default:
310 dprintk ("%s: invalid transmission_mode\n",__FUNCTION__);
311 return -EINVAL;
312 }
313 cx22702_writereg(state, 0x08, val);
314 cx22702_writereg(state, 0x0B, (cx22702_readreg(state, 0x0B) & 0xfc) | 0x02 );
315 cx22702_writereg(state, 0x0C, (cx22702_readreg(state, 0x0C) & 0xBF) | 0x40 );
316
317 /* Begin channel aquisition */
318 cx22702_writereg(state, 0x00, 0x01);
319
320 return 0;
321}
322
323/* Reset the demod hardware and reset all of the configuration registers
324 to a default state. */
325static int cx22702_init (struct dvb_frontend* fe)
326{
327 int i;
328 struct cx22702_state* state = (struct cx22702_state*) fe->demodulator_priv;
329
330 cx22702_writereg (state, 0x00, 0x02);
331
332 msleep(10);
333
334 for (i=0; i<sizeof(init_tab); i+=2)
335 cx22702_writereg (state, init_tab[i], init_tab[i+1]);
336
337
338 /* init PLL */
339 if (state->config->pll_init) {
340 cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) &0xfe);
341 state->config->pll_init(fe);
342 cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) | 1);
343 }
344
345 return 0;
346}
347
348static int cx22702_read_status(struct dvb_frontend* fe, fe_status_t* status)
349{
350 struct cx22702_state* state = (struct cx22702_state*) fe->demodulator_priv;
351 u8 reg0A;
352 u8 reg23;
353
354 *status = 0;
355
356 reg0A = cx22702_readreg (state, 0x0A);
357 reg23 = cx22702_readreg (state, 0x23);
358
359 dprintk ("%s: status demod=0x%02x agc=0x%02x\n"
360 ,__FUNCTION__,reg0A,reg23);
361
362 if(reg0A & 0x10) {
363 *status |= FE_HAS_LOCK;
364 *status |= FE_HAS_VITERBI;
365 *status |= FE_HAS_SYNC;
366 }
367
368 if(reg0A & 0x20)
369 *status |= FE_HAS_CARRIER;
370
371 if(reg23 < 0xf0)
372 *status |= FE_HAS_SIGNAL;
373
374 return 0;
375}
376
377static int cx22702_read_ber(struct dvb_frontend* fe, u32* ber)
378{
379 struct cx22702_state* state = (struct cx22702_state*) fe->demodulator_priv;
380
381 if(cx22702_readreg (state, 0xE4) & 0x02) {
382 /* Realtime statistics */
383 *ber = (cx22702_readreg (state, 0xDE) & 0x7F) << 7
384 | (cx22702_readreg (state, 0xDF)&0x7F);
385 } else {
386 /* Averagtine statistics */
387 *ber = (cx22702_readreg (state, 0xDE) & 0x7F) << 7
388 | cx22702_readreg (state, 0xDF);
389 }
390
391 return 0;
392}
393
394static int cx22702_read_signal_strength(struct dvb_frontend* fe, u16* signal_strength)
395{
396 struct cx22702_state* state = (struct cx22702_state*) fe->demodulator_priv;
397
398 *signal_strength = cx22702_readreg (state, 0x23);
399
400 return 0;
401}
402
403static int cx22702_read_snr(struct dvb_frontend* fe, u16* snr)
404{
405 struct cx22702_state* state = (struct cx22702_state*) fe->demodulator_priv;
406
407 u16 rs_ber=0;
408 if(cx22702_readreg (state, 0xE4) & 0x02) {
409 /* Realtime statistics */
410 rs_ber = (cx22702_readreg (state, 0xDE) & 0x7F) << 7
411 | (cx22702_readreg (state, 0xDF)& 0x7F);
412 } else {
413 /* Averagine statistics */
414 rs_ber = (cx22702_readreg (state, 0xDE) & 0x7F) << 8
415 | cx22702_readreg (state, 0xDF);
416 }
417 *snr = ~rs_ber;
418
419 return 0;
420}
421
422static int cx22702_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
423{
424 struct cx22702_state* state = (struct cx22702_state*) fe->demodulator_priv;
425
426 u8 _ucblocks;
427
428 /* RS Uncorrectable Packet Count then reset */
429 _ucblocks = cx22702_readreg (state, 0xE3);
430 if (state->prevUCBlocks < _ucblocks) *ucblocks = (_ucblocks - state->prevUCBlocks);
431 else *ucblocks = state->prevUCBlocks - _ucblocks;
432 state->prevUCBlocks = _ucblocks;
433
434 return 0;
435}
436
437static int cx22702_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
438{
439 struct cx22702_state* state = (struct cx22702_state*) fe->demodulator_priv;
440
441 u8 reg0C = cx22702_readreg (state, 0x0C);
442
443 p->inversion = reg0C & 0x1 ? INVERSION_ON : INVERSION_OFF;
444 return cx22702_get_tps (state, &p->u.ofdm);
445}
446
447static void cx22702_release(struct dvb_frontend* fe)
448{
449 struct cx22702_state* state = (struct cx22702_state*) fe->demodulator_priv;
450 kfree(state);
451}
452
453static struct dvb_frontend_ops cx22702_ops;
454
455struct dvb_frontend* cx22702_attach(const struct cx22702_config* config,
456 struct i2c_adapter* i2c)
457{
458 struct cx22702_state* state = NULL;
459
460 /* allocate memory for the internal state */
461 state = (struct cx22702_state*) kmalloc(sizeof(struct cx22702_state), GFP_KERNEL);
462 if (state == NULL) goto error;
463
464 /* setup the state */
465 state->config = config;
466 state->i2c = i2c;
467 memcpy(&state->ops, &cx22702_ops, sizeof(struct dvb_frontend_ops));
468 state->prevUCBlocks = 0;
469
470 /* check if the demod is there */
471 if (cx22702_readreg(state, 0x1f) != 0x3) goto error;
472
473 /* create dvb_frontend */
474 state->frontend.ops = &state->ops;
475 state->frontend.demodulator_priv = state;
476 return &state->frontend;
477
478error:
479 kfree(state);
480 return NULL;
481}
482
483static struct dvb_frontend_ops cx22702_ops = {
484
485 .info = {
486 .name = "Conexant CX22702 DVB-T",
487 .type = FE_OFDM,
488 .frequency_min = 177000000,
489 .frequency_max = 858000000,
490 .frequency_stepsize = 166666,
491 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
492 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
493 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
494 FE_CAN_HIERARCHY_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
495 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_RECOVER
496 },
497
498 .release = cx22702_release,
499
500 .init = cx22702_init,
501
502 .set_frontend = cx22702_set_tps,
503 .get_frontend = cx22702_get_frontend,
504
505 .read_status = cx22702_read_status,
506 .read_ber = cx22702_read_ber,
507 .read_signal_strength = cx22702_read_signal_strength,
508 .read_snr = cx22702_read_snr,
509 .read_ucblocks = cx22702_read_ucblocks,
510};
511
512module_param(debug, int, 0644);
513MODULE_PARM_DESC(debug, "Enable verbose debug messages");
514
515MODULE_DESCRIPTION("Conexant CX22702 DVB-T Demodulator driver");
516MODULE_AUTHOR("Steven Toth");
517MODULE_LICENSE("GPL");
518
519EXPORT_SYMBOL(cx22702_attach);
diff --git a/drivers/media/dvb/frontends/cx22702.h b/drivers/media/dvb/frontends/cx22702.h
new file mode 100644
index 000000000000..6e34f997aba2
--- /dev/null
+++ b/drivers/media/dvb/frontends/cx22702.h
@@ -0,0 +1,46 @@
1/*
2 Conexant 22702 DVB OFDM demodulator driver
3
4 based on:
5 Alps TDMB7 DVB OFDM demodulator driver
6
7 Copyright (C) 2001-2002 Convergence Integrated Media GmbH
8 Holger Waechtler <holger@convergence.de>
9
10 Copyright (C) 2004 Steven Toth <steve@toth.demon.co.uk>
11
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
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 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., 675 Mass Ave, Cambridge, MA 02139, USA.
25
26*/
27
28#ifndef CX22702_H
29#define CX22702_H
30
31#include <linux/dvb/frontend.h>
32
33struct cx22702_config
34{
35 /* the demodulator's i2c address */
36 u8 demod_address;
37
38 /* PLL maintenance */
39 int (*pll_init)(struct dvb_frontend* fe);
40 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
41};
42
43extern struct dvb_frontend* cx22702_attach(const struct cx22702_config* config,
44 struct i2c_adapter* i2c);
45
46#endif // CX22702_H
diff --git a/drivers/media/dvb/frontends/cx24110.c b/drivers/media/dvb/frontends/cx24110.c
new file mode 100644
index 000000000000..ae16112a0653
--- /dev/null
+++ b/drivers/media/dvb/frontends/cx24110.c
@@ -0,0 +1,657 @@
1/*
2 cx24110 - Single Chip Satellite Channel Receiver driver module
3
4 Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@t-online.de> based on
5 work
6 Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de>
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
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#include <linux/slab.h>
26#include <linux/kernel.h>
27#include <linux/module.h>
28#include <linux/moduleparam.h>
29#include <linux/init.h>
30
31#include "dvb_frontend.h"
32#include "cx24110.h"
33
34
35struct cx24110_state {
36
37 struct i2c_adapter* i2c;
38
39 struct dvb_frontend_ops ops;
40
41 const struct cx24110_config* config;
42
43 struct dvb_frontend frontend;
44
45 u32 lastber;
46 u32 lastbler;
47 u32 lastesn0;
48};
49
50static int debug;
51#define dprintk(args...) \
52 do { \
53 if (debug) printk(KERN_DEBUG "cx24110: " args); \
54 } while (0)
55
56static struct {u8 reg; u8 data;} cx24110_regdata[]=
57 /* Comments beginning with @ denote this value should
58 be the default */
59 {{0x09,0x01}, /* SoftResetAll */
60 {0x09,0x00}, /* release reset */
61 {0x01,0xe8}, /* MSB of code rate 27.5MS/s */
62 {0x02,0x17}, /* middle byte " */
63 {0x03,0x29}, /* LSB " */
64 {0x05,0x03}, /* @ DVB mode, standard code rate 3/4 */
65 {0x06,0xa5}, /* @ PLL 60MHz */
66 {0x07,0x01}, /* @ Fclk, i.e. sampling clock, 60MHz */
67 {0x0a,0x00}, /* @ partial chip disables, do not set */
68 {0x0b,0x01}, /* set output clock in gapped mode, start signal low
69 active for first byte */
70 {0x0c,0x11}, /* no parity bytes, large hold time, serial data out */
71 {0x0d,0x6f}, /* @ RS Sync/Unsync thresholds */
72 {0x10,0x40}, /* chip doc is misleading here: write bit 6 as 1
73 to avoid starting the BER counter. Reset the
74 CRC test bit. Finite counting selected */
75 {0x15,0xff}, /* @ size of the limited time window for RS BER
76 estimation. It is <value>*256 RS blocks, this
77 gives approx. 2.6 sec at 27.5MS/s, rate 3/4 */
78 {0x16,0x00}, /* @ enable all RS output ports */
79 {0x17,0x04}, /* @ time window allowed for the RS to sync */
80 {0x18,0xae}, /* @ allow all standard DVB code rates to be scanned
81 for automatically */
82 /* leave the current code rate and normalization
83 registers as they are after reset... */
84 {0x21,0x10}, /* @ during AutoAcq, search each viterbi setting
85 only once */
86 {0x23,0x18}, /* @ size of the limited time window for Viterbi BER
87 estimation. It is <value>*65536 channel bits, i.e.
88 approx. 38ms at 27.5MS/s, rate 3/4 */
89 {0x24,0x24}, /* do not trigger Viterbi CRC test. Finite count window */
90 /* leave front-end AGC parameters at default values */
91 /* leave decimation AGC parameters at default values */
92 {0x35,0x40}, /* disable all interrupts. They are not connected anyway */
93 {0x36,0xff}, /* clear all interrupt pending flags */
94 {0x37,0x00}, /* @ fully enable AutoAcqq state machine */
95 {0x38,0x07}, /* @ enable fade recovery, but not autostart AutoAcq */
96 /* leave the equalizer parameters on their default values */
97 /* leave the final AGC parameters on their default values */
98 {0x41,0x00}, /* @ MSB of front-end derotator frequency */
99 {0x42,0x00}, /* @ middle bytes " */
100 {0x43,0x00}, /* @ LSB " */
101 /* leave the carrier tracking loop parameters on default */
102 /* leave the bit timing loop parameters at gefault */
103 {0x56,0x4d}, /* set the filtune voltage to 2.7V, as recommended by */
104 /* the cx24108 data sheet for symbol rates above 15MS/s */
105 {0x57,0x00}, /* @ Filter sigma delta enabled, positive */
106 {0x61,0x95}, /* GPIO pins 1-4 have special function */
107 {0x62,0x05}, /* GPIO pin 5 has special function, pin 6 is GPIO */
108 {0x63,0x00}, /* All GPIO pins use CMOS output characteristics */
109 {0x64,0x20}, /* GPIO 6 is input, all others are outputs */
110 {0x6d,0x30}, /* tuner auto mode clock freq 62kHz */
111 {0x70,0x15}, /* use auto mode, tuner word is 21 bits long */
112 {0x73,0x00}, /* @ disable several demod bypasses */
113 {0x74,0x00}, /* @ " */
114 {0x75,0x00} /* @ " */
115 /* the remaining registers are for SEC */
116 };
117
118
119static int cx24110_writereg (struct cx24110_state* state, int reg, int data)
120{
121 u8 buf [] = { reg, data };
122 struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 };
123 int err;
124
125 if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {
126 dprintk ("%s: writereg error (err == %i, reg == 0x%02x,"
127 " data == 0x%02x)\n", __FUNCTION__, err, reg, data);
128 return -EREMOTEIO;
129 }
130
131 return 0;
132}
133
134static int cx24110_readreg (struct cx24110_state* state, u8 reg)
135{
136 int ret;
137 u8 b0 [] = { reg };
138 u8 b1 [] = { 0 };
139 struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 },
140 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
141
142 ret = i2c_transfer(state->i2c, msg, 2);
143
144 if (ret != 2) return ret;
145
146 return b1[0];
147}
148
149static int cx24110_set_inversion (struct cx24110_state* state, fe_spectral_inversion_t inversion)
150{
151/* fixme (low): error handling */
152
153 switch (inversion) {
154 case INVERSION_OFF:
155 cx24110_writereg(state,0x37,cx24110_readreg(state,0x37)|0x1);
156 /* AcqSpectrInvDis on. No idea why someone should want this */
157 cx24110_writereg(state,0x5,cx24110_readreg(state,0x5)&0xf7);
158 /* Initial value 0 at start of acq */
159 cx24110_writereg(state,0x22,cx24110_readreg(state,0x22)&0xef);
160 /* current value 0 */
161 /* The cx24110 manual tells us this reg is read-only.
162 But what the heck... set it ayways */
163 break;
164 case INVERSION_ON:
165 cx24110_writereg(state,0x37,cx24110_readreg(state,0x37)|0x1);
166 /* AcqSpectrInvDis on. No idea why someone should want this */
167 cx24110_writereg(state,0x5,cx24110_readreg(state,0x5)|0x08);
168 /* Initial value 1 at start of acq */
169 cx24110_writereg(state,0x22,cx24110_readreg(state,0x22)|0x10);
170 /* current value 1 */
171 break;
172 case INVERSION_AUTO:
173 cx24110_writereg(state,0x37,cx24110_readreg(state,0x37)&0xfe);
174 /* AcqSpectrInvDis off. Leave initial & current states as is */
175 break;
176 default:
177 return -EINVAL;
178 }
179
180 return 0;
181}
182
183static int cx24110_set_fec (struct cx24110_state* state, fe_code_rate_t fec)
184{
185/* fixme (low): error handling */
186
187 static const int rate[]={-1,1,2,3,5,7,-1};
188 static const int g1[]={-1,0x01,0x02,0x05,0x15,0x45,-1};
189 static const int g2[]={-1,0x01,0x03,0x06,0x1a,0x7a,-1};
190
191 /* Well, the AutoAcq engine of the cx24106 and 24110 automatically
192 searches all enabled viterbi rates, and can handle non-standard
193 rates as well. */
194
195 if (fec>FEC_AUTO)
196 fec=FEC_AUTO;
197
198 if (fec==FEC_AUTO) { /* (re-)establish AutoAcq behaviour */
199 cx24110_writereg(state,0x37,cx24110_readreg(state,0x37)&0xdf);
200 /* clear AcqVitDis bit */
201 cx24110_writereg(state,0x18,0xae);
202 /* allow all DVB standard code rates */
203 cx24110_writereg(state,0x05,(cx24110_readreg(state,0x05)&0xf0)|0x3);
204 /* set nominal Viterbi rate 3/4 */
205 cx24110_writereg(state,0x22,(cx24110_readreg(state,0x22)&0xf0)|0x3);
206 /* set current Viterbi rate 3/4 */
207 cx24110_writereg(state,0x1a,0x05); cx24110_writereg(state,0x1b,0x06);
208 /* set the puncture registers for code rate 3/4 */
209 return 0;
210 } else {
211 cx24110_writereg(state,0x37,cx24110_readreg(state,0x37)|0x20);
212 /* set AcqVitDis bit */
213 if(rate[fec]>0) {
214 cx24110_writereg(state,0x05,(cx24110_readreg(state,0x05)&0xf0)|rate[fec]);
215 /* set nominal Viterbi rate */
216 cx24110_writereg(state,0x22,(cx24110_readreg(state,0x22)&0xf0)|rate[fec]);
217 /* set current Viterbi rate */
218 cx24110_writereg(state,0x1a,g1[fec]);
219 cx24110_writereg(state,0x1b,g2[fec]);
220 /* not sure if this is the right way: I always used AutoAcq mode */
221 } else
222 return -EOPNOTSUPP;
223/* fixme (low): which is the correct return code? */
224 };
225 return 0;
226}
227
228static fe_code_rate_t cx24110_get_fec (struct cx24110_state* state)
229{
230 int i;
231
232 i=cx24110_readreg(state,0x22)&0x0f;
233 if(!(i&0x08)) {
234 return FEC_1_2 + i - 1;
235 } else {
236/* fixme (low): a special code rate has been selected. In theory, we need to
237 return a denominator value, a numerator value, and a pair of puncture
238 maps to correctly describe this mode. But this should never happen in
239 practice, because it cannot be set by cx24110_get_fec. */
240 return FEC_NONE;
241 }
242}
243
244static int cx24110_set_symbolrate (struct cx24110_state* state, u32 srate)
245{
246/* fixme (low): add error handling */
247 u32 ratio;
248 u32 tmp, fclk, BDRI;
249
250 static const u32 bands[]={5000000UL,15000000UL,90999000UL/2};
251 int i;
252
253dprintk("cx24110 debug: entering %s(%d)\n",__FUNCTION__,srate);
254 if (srate>90999000UL/2)
255 srate=90999000UL/2;
256 if (srate<500000)
257 srate=500000;
258
259 for(i=0;(i<sizeof(bands)/sizeof(bands[0]))&&(srate>bands[i]);i++)
260 ;
261 /* first, check which sample rate is appropriate: 45, 60 80 or 90 MHz,
262 and set the PLL accordingly (R07[1:0] Fclk, R06[7:4] PLLmult,
263 R06[3:0] PLLphaseDetGain */
264 tmp=cx24110_readreg(state,0x07)&0xfc;
265 if(srate<90999000UL/4) { /* sample rate 45MHz*/
266 cx24110_writereg(state,0x07,tmp);
267 cx24110_writereg(state,0x06,0x78);
268 fclk=90999000UL/2;
269 } else if(srate<60666000UL/2) { /* sample rate 60MHz */
270 cx24110_writereg(state,0x07,tmp|0x1);
271 cx24110_writereg(state,0x06,0xa5);
272 fclk=60666000UL;
273 } else if(srate<80888000UL/2) { /* sample rate 80MHz */
274 cx24110_writereg(state,0x07,tmp|0x2);
275 cx24110_writereg(state,0x06,0x87);
276 fclk=80888000UL;
277 } else { /* sample rate 90MHz */
278 cx24110_writereg(state,0x07,tmp|0x3);
279 cx24110_writereg(state,0x06,0x78);
280 fclk=90999000UL;
281 };
282 dprintk("cx24110 debug: fclk %d Hz\n",fclk);
283 /* we need to divide two integers with approx. 27 bits in 32 bit
284 arithmetic giving a 25 bit result */
285 /* the maximum dividend is 90999000/2, 0x02b6446c, this number is
286 also the most complex divisor. Hence, the dividend has,
287 assuming 32bit unsigned arithmetic, 6 clear bits on top, the
288 divisor 2 unused bits at the bottom. Also, the quotient is
289 always less than 1/2. Borrowed from VES1893.c, of course */
290
291 tmp=srate<<6;
292 BDRI=fclk>>2;
293 ratio=(tmp/BDRI);
294
295 tmp=(tmp%BDRI)<<8;
296 ratio=(ratio<<8)+(tmp/BDRI);
297
298 tmp=(tmp%BDRI)<<8;
299 ratio=(ratio<<8)+(tmp/BDRI);
300
301 tmp=(tmp%BDRI)<<1;
302 ratio=(ratio<<1)+(tmp/BDRI);
303
304 dprintk("srate= %d (range %d, up to %d)\n", srate,i,bands[i]);
305 dprintk("fclk = %d\n", fclk);
306 dprintk("ratio= %08x\n", ratio);
307
308 cx24110_writereg(state, 0x1, (ratio>>16)&0xff);
309 cx24110_writereg(state, 0x2, (ratio>>8)&0xff);
310 cx24110_writereg(state, 0x3, (ratio)&0xff);
311
312 return 0;
313
314}
315
316int cx24110_pll_write (struct dvb_frontend* fe, u32 data)
317{
318 struct cx24110_state *state = (struct cx24110_state*) fe->demodulator_priv;
319
320/* tuner data is 21 bits long, must be left-aligned in data */
321/* tuner cx24108 is written through a dedicated 3wire interface on the demod chip */
322/* FIXME (low): add error handling, avoid infinite loops if HW fails... */
323
324 dprintk("cx24110 debug: cx24108_write(%8.8x)\n",data);
325
326 cx24110_writereg(state,0x6d,0x30); /* auto mode at 62kHz */
327 cx24110_writereg(state,0x70,0x15); /* auto mode 21 bits */
328
329 /* if the auto tuner writer is still busy, clear it out */
330 while (cx24110_readreg(state,0x6d)&0x80)
331 cx24110_writereg(state,0x72,0);
332
333 /* write the topmost 8 bits */
334 cx24110_writereg(state,0x72,(data>>24)&0xff);
335
336 /* wait for the send to be completed */
337 while ((cx24110_readreg(state,0x6d)&0xc0)==0x80)
338 ;
339
340 /* send another 8 bytes */
341 cx24110_writereg(state,0x72,(data>>16)&0xff);
342 while ((cx24110_readreg(state,0x6d)&0xc0)==0x80)
343 ;
344
345 /* and the topmost 5 bits of this byte */
346 cx24110_writereg(state,0x72,(data>>8)&0xff);
347 while ((cx24110_readreg(state,0x6d)&0xc0)==0x80)
348 ;
349
350 /* now strobe the enable line once */
351 cx24110_writereg(state,0x6d,0x32);
352 cx24110_writereg(state,0x6d,0x30);
353
354 return 0;
355}
356
357static int cx24110_initfe(struct dvb_frontend* fe)
358{
359 struct cx24110_state *state = (struct cx24110_state*) fe->demodulator_priv;
360/* fixme (low): error handling */
361 int i;
362
363 dprintk("%s: init chip\n", __FUNCTION__);
364
365 for(i=0;i<sizeof(cx24110_regdata)/sizeof(cx24110_regdata[0]);i++) {
366 cx24110_writereg(state, cx24110_regdata[i].reg, cx24110_regdata[i].data);
367 };
368
369 if (state->config->pll_init) state->config->pll_init(fe);
370
371 return 0;
372}
373
374static int cx24110_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltage)
375{
376 struct cx24110_state *state = (struct cx24110_state*) fe->demodulator_priv;
377
378 switch (voltage) {
379 case SEC_VOLTAGE_13:
380 return cx24110_writereg(state,0x76,(cx24110_readreg(state,0x76)&0x3b)|0xc0);
381 case SEC_VOLTAGE_18:
382 return cx24110_writereg(state,0x76,(cx24110_readreg(state,0x76)&0x3b)|0x40);
383 default:
384 return -EINVAL;
385 };
386}
387
388static int cx24110_diseqc_send_burst(struct dvb_frontend* fe,
389 fe_sec_mini_cmd_t burst)
390{
391 int rv, bit, i;
392 struct cx24110_state *state = fe->demodulator_priv;
393
394 if (burst == SEC_MINI_A)
395 bit = 0x00;
396 else if (burst == SEC_MINI_B)
397 bit = 0x08;
398 else
399 return -EINVAL;
400
401 rv = cx24110_readreg(state, 0x77);
402 cx24110_writereg(state, 0x77, rv|0x04);
403
404 rv = cx24110_readreg(state, 0x76);
405 cx24110_writereg(state, 0x76, ((rv & 0x90) | 0x40 | bit));
406 for (i = 500; i-- > 0 && !(cx24110_readreg(state,0x76)&0x40) ; )
407 ; /* wait for LNB ready */
408
409 return 0;
410}
411
412static int cx24110_send_diseqc_msg(struct dvb_frontend* fe,
413 struct dvb_diseqc_master_cmd *cmd)
414{
415 int i, rv;
416 struct cx24110_state *state = (struct cx24110_state*) fe->demodulator_priv;
417
418 for (i = 0; i < cmd->msg_len; i++)
419 cx24110_writereg(state, 0x79 + i, cmd->msg[i]);
420
421 rv = cx24110_readreg(state, 0x77);
422 cx24110_writereg(state, 0x77, rv|0x04);
423
424 rv = cx24110_readreg(state, 0x76);
425
426 cx24110_writereg(state, 0x76, ((rv & 0x90) | 0x40) | ((cmd->msg_len-3) & 3));
427 for (i=500; i-- > 0 && !(cx24110_readreg(state,0x76)&0x40);)
428 ; /* wait for LNB ready */
429
430 return 0;
431}
432
433static int cx24110_read_status(struct dvb_frontend* fe, fe_status_t* status)
434{
435 struct cx24110_state *state = (struct cx24110_state*) fe->demodulator_priv;
436
437 int sync = cx24110_readreg (state, 0x55);
438
439 *status = 0;
440
441 if (sync & 0x10)
442 *status |= FE_HAS_SIGNAL;
443
444 if (sync & 0x08)
445 *status |= FE_HAS_CARRIER;
446
447 sync = cx24110_readreg (state, 0x08);
448
449 if (sync & 0x40)
450 *status |= FE_HAS_VITERBI;
451
452 if (sync & 0x20)
453 *status |= FE_HAS_SYNC;
454
455 if ((sync & 0x60) == 0x60)
456 *status |= FE_HAS_LOCK;
457
458 return 0;
459}
460
461static int cx24110_read_ber(struct dvb_frontend* fe, u32* ber)
462{
463 struct cx24110_state *state = (struct cx24110_state*) fe->demodulator_priv;
464
465 /* fixme (maybe): value range is 16 bit. Scale? */
466 if(cx24110_readreg(state,0x24)&0x10) {
467 /* the Viterbi error counter has finished one counting window */
468 cx24110_writereg(state,0x24,0x04); /* select the ber reg */
469 state->lastber=cx24110_readreg(state,0x25)|
470 (cx24110_readreg(state,0x26)<<8);
471 cx24110_writereg(state,0x24,0x04); /* start new count window */
472 cx24110_writereg(state,0x24,0x14);
473 }
474 *ber = state->lastber;
475
476 return 0;
477}
478
479static int cx24110_read_signal_strength(struct dvb_frontend* fe, u16* signal_strength)
480{
481 struct cx24110_state *state = (struct cx24110_state*) fe->demodulator_priv;
482
483/* no provision in hardware. Read the frontend AGC accumulator. No idea how to scale this, but I know it is 2s complement */
484 u8 signal = cx24110_readreg (state, 0x27)+128;
485 *signal_strength = (signal << 8) | signal;
486
487 return 0;
488}
489
490static int cx24110_read_snr(struct dvb_frontend* fe, u16* snr)
491{
492 struct cx24110_state *state = (struct cx24110_state*) fe->demodulator_priv;
493
494 /* no provision in hardware. Can be computed from the Es/N0 estimator, but I don't know how. */
495 if(cx24110_readreg(state,0x6a)&0x80) {
496 /* the Es/N0 error counter has finished one counting window */
497 state->lastesn0=cx24110_readreg(state,0x69)|
498 (cx24110_readreg(state,0x68)<<8);
499 cx24110_writereg(state,0x6a,0x84); /* start new count window */
500 }
501 *snr = state->lastesn0;
502
503 return 0;
504}
505
506static int cx24110_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
507{
508 struct cx24110_state *state = (struct cx24110_state*) fe->demodulator_priv;
509 u32 lastbyer;
510
511 if(cx24110_readreg(state,0x10)&0x40) {
512 /* the RS error counter has finished one counting window */
513 cx24110_writereg(state,0x10,0x60); /* select the byer reg */
514 lastbyer=cx24110_readreg(state,0x12)|
515 (cx24110_readreg(state,0x13)<<8)|
516 (cx24110_readreg(state,0x14)<<16);
517 cx24110_writereg(state,0x10,0x70); /* select the bler reg */
518 state->lastbler=cx24110_readreg(state,0x12)|
519 (cx24110_readreg(state,0x13)<<8)|
520 (cx24110_readreg(state,0x14)<<16);
521 cx24110_writereg(state,0x10,0x20); /* start new count window */
522 }
523 *ucblocks = state->lastbler;
524
525 return 0;
526}
527
528static int cx24110_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
529{
530 struct cx24110_state *state = (struct cx24110_state*) fe->demodulator_priv;
531
532 state->config->pll_set(fe, p);
533 cx24110_set_inversion (state, p->inversion);
534 cx24110_set_fec (state, p->u.qpsk.fec_inner);
535 cx24110_set_symbolrate (state, p->u.qpsk.symbol_rate);
536 cx24110_writereg(state,0x04,0x05); /* start aquisition */
537
538 return 0;
539}
540
541static int cx24110_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
542{
543 struct cx24110_state *state = (struct cx24110_state*) fe->demodulator_priv;
544 s32 afc; unsigned sclk;
545
546/* cannot read back tuner settings (freq). Need to have some private storage */
547
548 sclk = cx24110_readreg (state, 0x07) & 0x03;
549/* ok, real AFC (FEDR) freq. is afc/2^24*fsamp, fsamp=45/60/80/90MHz.
550 * Need 64 bit arithmetic. Is thiss possible in the kernel? */
551 if (sclk==0) sclk=90999000L/2L;
552 else if (sclk==1) sclk=60666000L;
553 else if (sclk==2) sclk=80888000L;
554 else sclk=90999000L;
555 sclk>>=8;
556 afc = sclk*(cx24110_readreg (state, 0x44)&0x1f)+
557 ((sclk*cx24110_readreg (state, 0x45))>>8)+
558 ((sclk*cx24110_readreg (state, 0x46))>>16);
559
560 p->frequency += afc;
561 p->inversion = (cx24110_readreg (state, 0x22) & 0x10) ?
562 INVERSION_ON : INVERSION_OFF;
563 p->u.qpsk.fec_inner = cx24110_get_fec (state);
564
565 return 0;
566}
567
568static int cx24110_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
569{
570 struct cx24110_state *state = (struct cx24110_state*) fe->demodulator_priv;
571
572 return cx24110_writereg(state,0x76,(cx24110_readreg(state,0x76)&~0x10)|(((tone==SEC_TONE_ON))?0x10:0));
573}
574
575static void cx24110_release(struct dvb_frontend* fe)
576{
577 struct cx24110_state* state = (struct cx24110_state*) fe->demodulator_priv;
578 kfree(state);
579}
580
581static struct dvb_frontend_ops cx24110_ops;
582
583struct dvb_frontend* cx24110_attach(const struct cx24110_config* config,
584 struct i2c_adapter* i2c)
585{
586 struct cx24110_state* state = NULL;
587 int ret;
588
589 /* allocate memory for the internal state */
590 state = (struct cx24110_state*) kmalloc(sizeof(struct cx24110_state), GFP_KERNEL);
591 if (state == NULL) goto error;
592
593 /* setup the state */
594 state->config = config;
595 state->i2c = i2c;
596 memcpy(&state->ops, &cx24110_ops, sizeof(struct dvb_frontend_ops));
597 state->lastber = 0;
598 state->lastbler = 0;
599 state->lastesn0 = 0;
600
601 /* check if the demod is there */
602 ret = cx24110_readreg(state, 0x00);
603 if ((ret != 0x5a) && (ret != 0x69)) goto error;
604
605 /* create dvb_frontend */
606 state->frontend.ops = &state->ops;
607 state->frontend.demodulator_priv = state;
608 return &state->frontend;
609
610error:
611 kfree(state);
612 return NULL;
613}
614
615static struct dvb_frontend_ops cx24110_ops = {
616
617 .info = {
618 .name = "Conexant CX24110 DVB-S",
619 .type = FE_QPSK,
620 .frequency_min = 950000,
621 .frequency_max = 2150000,
622 .frequency_stepsize = 1011, /* kHz for QPSK frontends */
623 .frequency_tolerance = 29500,
624 .symbol_rate_min = 1000000,
625 .symbol_rate_max = 45000000,
626 .caps = FE_CAN_INVERSION_AUTO |
627 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
628 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
629 FE_CAN_QPSK | FE_CAN_RECOVER
630 },
631
632 .release = cx24110_release,
633
634 .init = cx24110_initfe,
635 .set_frontend = cx24110_set_frontend,
636 .get_frontend = cx24110_get_frontend,
637 .read_status = cx24110_read_status,
638 .read_ber = cx24110_read_ber,
639 .read_signal_strength = cx24110_read_signal_strength,
640 .read_snr = cx24110_read_snr,
641 .read_ucblocks = cx24110_read_ucblocks,
642
643 .diseqc_send_master_cmd = cx24110_send_diseqc_msg,
644 .set_tone = cx24110_set_tone,
645 .set_voltage = cx24110_set_voltage,
646 .diseqc_send_burst = cx24110_diseqc_send_burst,
647};
648
649module_param(debug, int, 0644);
650MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
651
652MODULE_DESCRIPTION("Conexant CX24110 DVB-S Demodulator driver");
653MODULE_AUTHOR("Peter Hettkamp");
654MODULE_LICENSE("GPL");
655
656EXPORT_SYMBOL(cx24110_attach);
657EXPORT_SYMBOL(cx24110_pll_write);
diff --git a/drivers/media/dvb/frontends/cx24110.h b/drivers/media/dvb/frontends/cx24110.h
new file mode 100644
index 000000000000..6b663f4744e0
--- /dev/null
+++ b/drivers/media/dvb/frontends/cx24110.h
@@ -0,0 +1,45 @@
1/*
2 cx24110 - Single Chip Satellite Channel Receiver driver module
3
4 Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@t-online.de> based on
5 work
6 Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de>
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
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 CX24110_H
26#define CX24110_H
27
28#include <linux/dvb/frontend.h>
29
30struct cx24110_config
31{
32 /* the demodulator's i2c address */
33 u8 demod_address;
34
35 /* PLL maintenance */
36 int (*pll_init)(struct dvb_frontend* fe);
37 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
38};
39
40extern struct dvb_frontend* cx24110_attach(const struct cx24110_config* config,
41 struct i2c_adapter* i2c);
42
43extern int cx24110_pll_write(struct dvb_frontend* fe, u32 data);
44
45#endif // CX24110_H
diff --git a/drivers/media/dvb/frontends/dib3000-common.c b/drivers/media/dvb/frontends/dib3000-common.c
new file mode 100644
index 000000000000..47ab02e133d1
--- /dev/null
+++ b/drivers/media/dvb/frontends/dib3000-common.c
@@ -0,0 +1,83 @@
1#include "dib3000-common.h"
2
3#ifdef CONFIG_DVB_DIBCOM_DEBUG
4static int debug;
5module_param(debug, int, 0644);
6MODULE_PARM_DESC(debug, "set debugging level (1=info,2=i2c,4=srch (|-able)).");
7#endif
8#define deb_info(args...) dprintk(0x01,args)
9#define deb_i2c(args...) dprintk(0x02,args)
10#define deb_srch(args...) dprintk(0x04,args)
11
12
13int dib3000_read_reg(struct dib3000_state *state, u16 reg)
14{
15 u8 wb[] = { ((reg >> 8) | 0x80) & 0xff, reg & 0xff };
16 u8 rb[2];
17 struct i2c_msg msg[] = {
18 { .addr = state->config.demod_address, .flags = 0, .buf = wb, .len = 2 },
19 { .addr = state->config.demod_address, .flags = I2C_M_RD, .buf = rb, .len = 2 },
20 };
21
22 if (i2c_transfer(state->i2c, msg, 2) != 2)
23 deb_i2c("i2c read error\n");
24
25 deb_i2c("reading i2c bus (reg: %5d 0x%04x, val: %5d 0x%04x)\n",reg,reg,
26 (rb[0] << 8) | rb[1],(rb[0] << 8) | rb[1]);
27
28 return (rb[0] << 8) | rb[1];
29}
30
31int dib3000_write_reg(struct dib3000_state *state, u16 reg, u16 val)
32{
33 u8 b[] = {
34 (reg >> 8) & 0xff, reg & 0xff,
35 (val >> 8) & 0xff, val & 0xff,
36 };
37 struct i2c_msg msg[] = {
38 { .addr = state->config.demod_address, .flags = 0, .buf = b, .len = 4 }
39 };
40 deb_i2c("writing i2c bus (reg: %5d 0x%04x, val: %5d 0x%04x)\n",reg,reg,val,val);
41
42 return i2c_transfer(state->i2c,msg, 1) != 1 ? -EREMOTEIO : 0;
43}
44
45int dib3000_search_status(u16 irq,u16 lock)
46{
47 if (irq & 0x02) {
48 if (lock & 0x01) {
49 deb_srch("auto search succeeded\n");
50 return 1; // auto search succeeded
51 } else {
52 deb_srch("auto search not successful\n");
53 return 0; // auto search failed
54 }
55 } else if (irq & 0x01) {
56 deb_srch("auto search failed\n");
57 return 0; // auto search failed
58 }
59 return -1; // try again
60}
61
62/* for auto search */
63u16 dib3000_seq[2][2][2] = /* fft,gua, inv */
64 { /* fft */
65 { /* gua */
66 { 0, 1 }, /* 0 0 { 0,1 } */
67 { 3, 9 }, /* 0 1 { 0,1 } */
68 },
69 {
70 { 2, 5 }, /* 1 0 { 0,1 } */
71 { 6, 11 }, /* 1 1 { 0,1 } */
72 }
73 };
74
75MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de");
76MODULE_DESCRIPTION("Common functions for the dib3000mb/dib3000mc dvb-frontend drivers");
77MODULE_LICENSE("GPL");
78
79EXPORT_SYMBOL(dib3000_seq);
80
81EXPORT_SYMBOL(dib3000_read_reg);
82EXPORT_SYMBOL(dib3000_write_reg);
83EXPORT_SYMBOL(dib3000_search_status);
diff --git a/drivers/media/dvb/frontends/dib3000-common.h b/drivers/media/dvb/frontends/dib3000-common.h
new file mode 100644
index 000000000000..c31d6df15472
--- /dev/null
+++ b/drivers/media/dvb/frontends/dib3000-common.h
@@ -0,0 +1,137 @@
1/*
2 * .h-files for the common use of the frontend drivers made by DiBcom
3 * DiBcom 3000M-B/C, 3000P
4 *
5 * DiBcom (http://www.dibcom.fr/)
6 *
7 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
8 *
9 * based on GPL code from DibCom, which has
10 *
11 * Copyright (C) 2004 Amaury Demol for DiBcom (ademol@dibcom.fr)
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License as
15 * published by the Free Software Foundation, version 2.
16 *
17 * Acknowledgements
18 *
19 * Amaury Demol (ademol@dibcom.fr) from DiBcom for providing specs and driver
20 * sources, on which this driver (and the dvb-dibusb) are based.
21 *
22 * see Documentation/dvb/README.dibusb for more information
23 *
24 */
25
26#ifndef DIB3000_COMMON_H
27#define DIB3000_COMMON_H
28
29#include "dvb_frontend.h"
30#include "dib3000.h"
31
32/* info and err, taken from usb.h, if there is anything available like by default. */
33#define err(format, arg...) printk(KERN_ERR "dib3000: " format "\n" , ## arg)
34#define info(format, arg...) printk(KERN_INFO "dib3000: " format "\n" , ## arg)
35#define warn(format, arg...) printk(KERN_WARNING "dib3000: " format "\n" , ## arg)
36
37/* frontend state */
38struct dib3000_state {
39 struct i2c_adapter* i2c;
40
41 struct dvb_frontend_ops ops;
42
43/* configuration settings */
44 struct dib3000_config config;
45
46 struct dvb_frontend frontend;
47 int timing_offset;
48 int timing_offset_comp_done;
49
50 fe_bandwidth_t last_tuned_bw;
51 u32 last_tuned_freq;
52};
53
54/* commonly used methods by the dib3000mb/mc/p frontend */
55extern int dib3000_read_reg(struct dib3000_state *state, u16 reg);
56extern int dib3000_write_reg(struct dib3000_state *state, u16 reg, u16 val);
57
58extern int dib3000_search_status(u16 irq,u16 lock);
59
60/* handy shortcuts */
61#define rd(reg) dib3000_read_reg(state,reg)
62
63#define wr(reg,val) if (dib3000_write_reg(state,reg,val)) \
64 { err("while sending 0x%04x to 0x%04x.",val,reg); return -EREMOTEIO; }
65
66#define wr_foreach(a,v) { int i; \
67 if (sizeof(a) != sizeof(v)) \
68 err("sizeof: %zu %zu is different",sizeof(a),sizeof(v));\
69 for (i=0; i < sizeof(a)/sizeof(u16); i++) \
70 wr(a[i],v[i]); \
71 }
72
73#define set_or(reg,val) wr(reg,rd(reg) | val)
74
75#define set_and(reg,val) wr(reg,rd(reg) & val)
76
77
78/* debug */
79
80#ifdef CONFIG_DVB_DIBCOM_DEBUG
81#define dprintk(level,args...) \
82 do { if ((debug & level)) { printk(args); } } while (0)
83#else
84#define dprintk(args...) do { } while (0)
85#endif
86
87/* mask for enabling a specific pid for the pid_filter */
88#define DIB3000_ACTIVATE_PID_FILTERING (0x2000)
89
90/* common values for tuning */
91#define DIB3000_ALPHA_0 ( 0)
92#define DIB3000_ALPHA_1 ( 1)
93#define DIB3000_ALPHA_2 ( 2)
94#define DIB3000_ALPHA_4 ( 4)
95
96#define DIB3000_CONSTELLATION_QPSK ( 0)
97#define DIB3000_CONSTELLATION_16QAM ( 1)
98#define DIB3000_CONSTELLATION_64QAM ( 2)
99
100#define DIB3000_GUARD_TIME_1_32 ( 0)
101#define DIB3000_GUARD_TIME_1_16 ( 1)
102#define DIB3000_GUARD_TIME_1_8 ( 2)
103#define DIB3000_GUARD_TIME_1_4 ( 3)
104
105#define DIB3000_TRANSMISSION_MODE_2K ( 0)
106#define DIB3000_TRANSMISSION_MODE_8K ( 1)
107
108#define DIB3000_SELECT_LP ( 0)
109#define DIB3000_SELECT_HP ( 1)
110
111#define DIB3000_FEC_1_2 ( 1)
112#define DIB3000_FEC_2_3 ( 2)
113#define DIB3000_FEC_3_4 ( 3)
114#define DIB3000_FEC_5_6 ( 5)
115#define DIB3000_FEC_7_8 ( 7)
116
117#define DIB3000_HRCH_OFF ( 0)
118#define DIB3000_HRCH_ON ( 1)
119
120#define DIB3000_DDS_INVERSION_OFF ( 0)
121#define DIB3000_DDS_INVERSION_ON ( 1)
122
123#define DIB3000_TUNER_WRITE_ENABLE(a) (0xffff & (a << 8))
124#define DIB3000_TUNER_WRITE_DISABLE(a) (0xffff & ((a << 8) | (1 << 7)))
125
126/* for auto search */
127extern u16 dib3000_seq[2][2][2];
128
129#define DIB3000_REG_MANUFACTOR_ID ( 1025)
130#define DIB3000_I2C_ID_DIBCOM (0x01b3)
131
132#define DIB3000_REG_DEVICE_ID ( 1026)
133#define DIB3000MB_DEVICE_ID (0x3000)
134#define DIB3000MC_DEVICE_ID (0x3001)
135#define DIB3000P_DEVICE_ID (0x3002)
136
137#endif // DIB3000_COMMON_H
diff --git a/drivers/media/dvb/frontends/dib3000.h b/drivers/media/dvb/frontends/dib3000.h
new file mode 100644
index 000000000000..80687c130836
--- /dev/null
+++ b/drivers/media/dvb/frontends/dib3000.h
@@ -0,0 +1,54 @@
1/*
2 * public header file of the frontend drivers for mobile DVB-T demodulators
3 * DiBcom 3000M-B and DiBcom 3000P/M-C (http://www.dibcom.fr/)
4 *
5 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
6 *
7 * based on GPL code from DibCom, which has
8 *
9 * Copyright (C) 2004 Amaury Demol for DiBcom (ademol@dibcom.fr)
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 as
13 * published by the Free Software Foundation, version 2.
14 *
15 * Acknowledgements
16 *
17 * Amaury Demol (ademol@dibcom.fr) from DiBcom for providing specs and driver
18 * sources, on which this driver (and the dvb-dibusb) are based.
19 *
20 * see Documentation/dvb/README.dibusb for more information
21 *
22 */
23
24#ifndef DIB3000_H
25#define DIB3000_H
26
27#include <linux/dvb/frontend.h>
28
29struct dib3000_config
30{
31 /* the demodulator's i2c address */
32 u8 demod_address;
33
34 /* PLL maintenance and the i2c address of the PLL */
35 u8 (*pll_addr)(struct dvb_frontend *fe);
36 int (*pll_init)(struct dvb_frontend *fe, u8 pll_buf[5]);
37 int (*pll_set)(struct dvb_frontend *fe, struct dvb_frontend_parameters* params, u8 pll_buf[5]);
38};
39
40struct dib_fe_xfer_ops
41{
42 /* pid and transfer handling is done in the demodulator */
43 int (*pid_parse)(struct dvb_frontend *fe, int onoff);
44 int (*fifo_ctrl)(struct dvb_frontend *fe, int onoff);
45 int (*pid_ctrl)(struct dvb_frontend *fe, int index, int pid, int onoff);
46 int (*tuner_pass_ctrl)(struct dvb_frontend *fe, int onoff, u8 pll_ctrl);
47};
48
49extern struct dvb_frontend* dib3000mb_attach(const struct dib3000_config* config,
50 struct i2c_adapter* i2c, struct dib_fe_xfer_ops *xfer_ops);
51
52extern struct dvb_frontend* dib3000mc_attach(const struct dib3000_config* config,
53 struct i2c_adapter* i2c, struct dib_fe_xfer_ops *xfer_ops);
54#endif // DIB3000_H
diff --git a/drivers/media/dvb/frontends/dib3000mb.c b/drivers/media/dvb/frontends/dib3000mb.c
new file mode 100644
index 000000000000..a853d12a26f1
--- /dev/null
+++ b/drivers/media/dvb/frontends/dib3000mb.c
@@ -0,0 +1,784 @@
1/*
2 * Frontend driver for mobile DVB-T demodulator DiBcom 3000M-B
3 * DiBcom (http://www.dibcom.fr/)
4 *
5 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
6 *
7 * based on GPL code from DibCom, which has
8 *
9 * Copyright (C) 2004 Amaury Demol for DiBcom (ademol@dibcom.fr)
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 as
13 * published by the Free Software Foundation, version 2.
14 *
15 * Acknowledgements
16 *
17 * Amaury Demol (ademol@dibcom.fr) from DiBcom for providing specs and driver
18 * sources, on which this driver (and the dvb-dibusb) are based.
19 *
20 * see Documentation/dvb/README.dibusb for more information
21 *
22 */
23
24#include <linux/config.h>
25#include <linux/kernel.h>
26#include <linux/version.h>
27#include <linux/module.h>
28#include <linux/moduleparam.h>
29#include <linux/init.h>
30#include <linux/delay.h>
31
32#include "dib3000-common.h"
33#include "dib3000mb_priv.h"
34#include "dib3000.h"
35
36/* Version information */
37#define DRIVER_VERSION "0.1"
38#define DRIVER_DESC "DiBcom 3000M-B DVB-T demodulator"
39#define DRIVER_AUTHOR "Patrick Boettcher, patrick.boettcher@desy.de"
40
41#ifdef CONFIG_DVB_DIBCOM_DEBUG
42static int debug;
43module_param(debug, int, 0644);
44MODULE_PARM_DESC(debug, "set debugging level (1=info,2=xfer,4=setfe,8=getfe (|-able)).");
45#endif
46#define deb_info(args...) dprintk(0x01,args)
47#define deb_xfer(args...) dprintk(0x02,args)
48#define deb_setf(args...) dprintk(0x04,args)
49#define deb_getf(args...) dprintk(0x08,args)
50
51static int dib3000mb_tuner_pass_ctrl(struct dvb_frontend *fe, int onoff, u8 pll_addr);
52
53static int dib3000mb_get_frontend(struct dvb_frontend* fe,
54 struct dvb_frontend_parameters *fep);
55
56static int dib3000mb_set_frontend(struct dvb_frontend* fe,
57 struct dvb_frontend_parameters *fep, int tuner)
58{
59 struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
60 struct dvb_ofdm_parameters *ofdm = &fep->u.ofdm;
61 fe_code_rate_t fe_cr = FEC_NONE;
62 int search_state, seq;
63
64 if (tuner) {
65 dib3000mb_tuner_pass_ctrl(fe,1,state->config.pll_addr(fe));
66 state->config.pll_set(fe, fep, NULL);
67 dib3000mb_tuner_pass_ctrl(fe,0,state->config.pll_addr(fe));
68
69 deb_setf("bandwidth: ");
70 switch (ofdm->bandwidth) {
71 case BANDWIDTH_8_MHZ:
72 deb_setf("8 MHz\n");
73 wr_foreach(dib3000mb_reg_timing_freq, dib3000mb_timing_freq[2]);
74 wr_foreach(dib3000mb_reg_bandwidth, dib3000mb_bandwidth_8mhz);
75 break;
76 case BANDWIDTH_7_MHZ:
77 deb_setf("7 MHz\n");
78 wr_foreach(dib3000mb_reg_timing_freq, dib3000mb_timing_freq[1]);
79 wr_foreach(dib3000mb_reg_bandwidth, dib3000mb_bandwidth_7mhz);
80 break;
81 case BANDWIDTH_6_MHZ:
82 deb_setf("6 MHz\n");
83 wr_foreach(dib3000mb_reg_timing_freq, dib3000mb_timing_freq[0]);
84 wr_foreach(dib3000mb_reg_bandwidth, dib3000mb_bandwidth_6mhz);
85 break;
86 case BANDWIDTH_AUTO:
87 return -EOPNOTSUPP;
88 default:
89 err("unkown bandwidth value.");
90 return -EINVAL;
91 }
92 }
93 wr(DIB3000MB_REG_LOCK1_MASK, DIB3000MB_LOCK1_SEARCH_4);
94
95 deb_setf("transmission mode: ");
96 switch (ofdm->transmission_mode) {
97 case TRANSMISSION_MODE_2K:
98 deb_setf("2k\n");
99 wr(DIB3000MB_REG_FFT, DIB3000_TRANSMISSION_MODE_2K);
100 break;
101 case TRANSMISSION_MODE_8K:
102 deb_setf("8k\n");
103 wr(DIB3000MB_REG_FFT, DIB3000_TRANSMISSION_MODE_8K);
104 break;
105 case TRANSMISSION_MODE_AUTO:
106 deb_setf("auto\n");
107 break;
108 default:
109 return -EINVAL;
110 }
111
112 deb_setf("guard: ");
113 switch (ofdm->guard_interval) {
114 case GUARD_INTERVAL_1_32:
115 deb_setf("1_32\n");
116 wr(DIB3000MB_REG_GUARD_TIME, DIB3000_GUARD_TIME_1_32);
117 break;
118 case GUARD_INTERVAL_1_16:
119 deb_setf("1_16\n");
120 wr(DIB3000MB_REG_GUARD_TIME, DIB3000_GUARD_TIME_1_16);
121 break;
122 case GUARD_INTERVAL_1_8:
123 deb_setf("1_8\n");
124 wr(DIB3000MB_REG_GUARD_TIME, DIB3000_GUARD_TIME_1_8);
125 break;
126 case GUARD_INTERVAL_1_4:
127 deb_setf("1_4\n");
128 wr(DIB3000MB_REG_GUARD_TIME, DIB3000_GUARD_TIME_1_4);
129 break;
130 case GUARD_INTERVAL_AUTO:
131 deb_setf("auto\n");
132 break;
133 default:
134 return -EINVAL;
135 }
136
137 deb_setf("inversion: ");
138 switch (fep->inversion) {
139 case INVERSION_OFF:
140 deb_setf("off\n");
141 wr(DIB3000MB_REG_DDS_INV, DIB3000_DDS_INVERSION_OFF);
142 break;
143 case INVERSION_AUTO:
144 deb_setf("auto ");
145 break;
146 case INVERSION_ON:
147 deb_setf("on\n");
148 wr(DIB3000MB_REG_DDS_INV, DIB3000_DDS_INVERSION_ON);
149 break;
150 default:
151 return -EINVAL;
152 }
153
154 deb_setf("constellation: ");
155 switch (ofdm->constellation) {
156 case QPSK:
157 deb_setf("qpsk\n");
158 wr(DIB3000MB_REG_QAM, DIB3000_CONSTELLATION_QPSK);
159 break;
160 case QAM_16:
161 deb_setf("qam16\n");
162 wr(DIB3000MB_REG_QAM, DIB3000_CONSTELLATION_16QAM);
163 break;
164 case QAM_64:
165 deb_setf("qam64\n");
166 wr(DIB3000MB_REG_QAM, DIB3000_CONSTELLATION_64QAM);
167 break;
168 case QAM_AUTO:
169 break;
170 default:
171 return -EINVAL;
172 }
173 deb_setf("hierachy: ");
174 switch (ofdm->hierarchy_information) {
175 case HIERARCHY_NONE:
176 deb_setf("none ");
177 /* fall through */
178 case HIERARCHY_1:
179 deb_setf("alpha=1\n");
180 wr(DIB3000MB_REG_VIT_ALPHA, DIB3000_ALPHA_1);
181 break;
182 case HIERARCHY_2:
183 deb_setf("alpha=2\n");
184 wr(DIB3000MB_REG_VIT_ALPHA, DIB3000_ALPHA_2);
185 break;
186 case HIERARCHY_4:
187 deb_setf("alpha=4\n");
188 wr(DIB3000MB_REG_VIT_ALPHA, DIB3000_ALPHA_4);
189 break;
190 case HIERARCHY_AUTO:
191 deb_setf("alpha=auto\n");
192 break;
193 default:
194 return -EINVAL;
195 }
196
197 deb_setf("hierarchy: ");
198 if (ofdm->hierarchy_information == HIERARCHY_NONE) {
199 deb_setf("none\n");
200 wr(DIB3000MB_REG_VIT_HRCH, DIB3000_HRCH_OFF);
201 wr(DIB3000MB_REG_VIT_HP, DIB3000_SELECT_HP);
202 fe_cr = ofdm->code_rate_HP;
203 } else if (ofdm->hierarchy_information != HIERARCHY_AUTO) {
204 deb_setf("on\n");
205 wr(DIB3000MB_REG_VIT_HRCH, DIB3000_HRCH_ON);
206 wr(DIB3000MB_REG_VIT_HP, DIB3000_SELECT_LP);
207 fe_cr = ofdm->code_rate_LP;
208 }
209 deb_setf("fec: ");
210 switch (fe_cr) {
211 case FEC_1_2:
212 deb_setf("1_2\n");
213 wr(DIB3000MB_REG_VIT_CODE_RATE, DIB3000_FEC_1_2);
214 break;
215 case FEC_2_3:
216 deb_setf("2_3\n");
217 wr(DIB3000MB_REG_VIT_CODE_RATE, DIB3000_FEC_2_3);
218 break;
219 case FEC_3_4:
220 deb_setf("3_4\n");
221 wr(DIB3000MB_REG_VIT_CODE_RATE, DIB3000_FEC_3_4);
222 break;
223 case FEC_5_6:
224 deb_setf("5_6\n");
225 wr(DIB3000MB_REG_VIT_CODE_RATE, DIB3000_FEC_5_6);
226 break;
227 case FEC_7_8:
228 deb_setf("7_8\n");
229 wr(DIB3000MB_REG_VIT_CODE_RATE, DIB3000_FEC_7_8);
230 break;
231 case FEC_NONE:
232 deb_setf("none ");
233 break;
234 case FEC_AUTO:
235 deb_setf("auto\n");
236 break;
237 default:
238 return -EINVAL;
239 }
240
241 seq = dib3000_seq
242 [ofdm->transmission_mode == TRANSMISSION_MODE_AUTO]
243 [ofdm->guard_interval == GUARD_INTERVAL_AUTO]
244 [fep->inversion == INVERSION_AUTO];
245
246 deb_setf("seq? %d\n", seq);
247
248 wr(DIB3000MB_REG_SEQ, seq);
249
250 wr(DIB3000MB_REG_ISI, seq ? DIB3000MB_ISI_INHIBIT : DIB3000MB_ISI_ACTIVATE);
251
252 if (ofdm->transmission_mode == TRANSMISSION_MODE_2K) {
253 if (ofdm->guard_interval == GUARD_INTERVAL_1_8) {
254 wr(DIB3000MB_REG_SYNC_IMPROVEMENT, DIB3000MB_SYNC_IMPROVE_2K_1_8);
255 } else {
256 wr(DIB3000MB_REG_SYNC_IMPROVEMENT, DIB3000MB_SYNC_IMPROVE_DEFAULT);
257 }
258
259 wr(DIB3000MB_REG_UNK_121, DIB3000MB_UNK_121_2K);
260 } else {
261 wr(DIB3000MB_REG_UNK_121, DIB3000MB_UNK_121_DEFAULT);
262 }
263
264 wr(DIB3000MB_REG_MOBILE_ALGO, DIB3000MB_MOBILE_ALGO_OFF);
265 wr(DIB3000MB_REG_MOBILE_MODE_QAM, DIB3000MB_MOBILE_MODE_QAM_OFF);
266 wr(DIB3000MB_REG_MOBILE_MODE, DIB3000MB_MOBILE_MODE_OFF);
267
268 wr_foreach(dib3000mb_reg_agc_bandwidth, dib3000mb_agc_bandwidth_high);
269
270 wr(DIB3000MB_REG_ISI, DIB3000MB_ISI_ACTIVATE);
271
272 wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_AGC + DIB3000MB_RESTART_CTRL);
273 wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_OFF);
274
275 /* wait for AGC lock */
276 msleep(70);
277
278 wr_foreach(dib3000mb_reg_agc_bandwidth, dib3000mb_agc_bandwidth_low);
279
280 /* something has to be auto searched */
281 if (ofdm->constellation == QAM_AUTO ||
282 ofdm->hierarchy_information == HIERARCHY_AUTO ||
283 fe_cr == FEC_AUTO ||
284 fep->inversion == INVERSION_AUTO) {
285 int as_count=0;
286
287 deb_setf("autosearch enabled.\n");
288
289 wr(DIB3000MB_REG_ISI, DIB3000MB_ISI_INHIBIT);
290
291 wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_AUTO_SEARCH);
292 wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_OFF);
293
294 while ((search_state =
295 dib3000_search_status(
296 rd(DIB3000MB_REG_AS_IRQ_PENDING),
297 rd(DIB3000MB_REG_LOCK2_VALUE))) < 0 && as_count++ < 100)
298 msleep(1);
299
300 deb_setf("search_state after autosearch %d after %d checks\n",search_state,as_count);
301
302 if (search_state == 1) {
303 struct dvb_frontend_parameters feps;
304 if (dib3000mb_get_frontend(fe, &feps) == 0) {
305 deb_setf("reading tuning data from frontend succeeded.\n");
306 return dib3000mb_set_frontend(fe, &feps, 0);
307 }
308 }
309
310 } else {
311 wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_CTRL);
312 wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_OFF);
313 }
314
315 return 0;
316}
317
318static int dib3000mb_fe_init(struct dvb_frontend* fe, int mobile_mode)
319{
320 struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
321
322 deb_info("dib3000mb is getting up.\n");
323 wr(DIB3000MB_REG_POWER_CONTROL, DIB3000MB_POWER_UP);
324
325 wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_AGC);
326
327 wr(DIB3000MB_REG_RESET_DEVICE, DIB3000MB_RESET_DEVICE);
328 wr(DIB3000MB_REG_RESET_DEVICE, DIB3000MB_RESET_DEVICE_RST);
329
330 wr(DIB3000MB_REG_CLOCK, DIB3000MB_CLOCK_DEFAULT);
331
332 wr(DIB3000MB_REG_ELECT_OUT_MODE, DIB3000MB_ELECT_OUT_MODE_ON);
333
334 wr(DIB3000MB_REG_DDS_FREQ_MSB, DIB3000MB_DDS_FREQ_MSB);
335 wr(DIB3000MB_REG_DDS_FREQ_LSB, DIB3000MB_DDS_FREQ_LSB);
336
337 wr_foreach(dib3000mb_reg_timing_freq, dib3000mb_timing_freq[2]);
338
339 wr_foreach(dib3000mb_reg_impulse_noise,
340 dib3000mb_impulse_noise_values[DIB3000MB_IMPNOISE_OFF]);
341
342 wr_foreach(dib3000mb_reg_agc_gain, dib3000mb_default_agc_gain);
343
344 wr(DIB3000MB_REG_PHASE_NOISE, DIB3000MB_PHASE_NOISE_DEFAULT);
345
346 wr_foreach(dib3000mb_reg_phase_noise, dib3000mb_default_noise_phase);
347
348 wr_foreach(dib3000mb_reg_lock_duration, dib3000mb_default_lock_duration);
349
350 wr_foreach(dib3000mb_reg_agc_bandwidth, dib3000mb_agc_bandwidth_low);
351
352 wr(DIB3000MB_REG_LOCK0_MASK, DIB3000MB_LOCK0_DEFAULT);
353 wr(DIB3000MB_REG_LOCK1_MASK, DIB3000MB_LOCK1_SEARCH_4);
354 wr(DIB3000MB_REG_LOCK2_MASK, DIB3000MB_LOCK2_DEFAULT);
355 wr(DIB3000MB_REG_SEQ, dib3000_seq[1][1][1]);
356
357 wr_foreach(dib3000mb_reg_bandwidth, dib3000mb_bandwidth_8mhz);
358
359 wr(DIB3000MB_REG_UNK_68, DIB3000MB_UNK_68);
360 wr(DIB3000MB_REG_UNK_69, DIB3000MB_UNK_69);
361 wr(DIB3000MB_REG_UNK_71, DIB3000MB_UNK_71);
362 wr(DIB3000MB_REG_UNK_77, DIB3000MB_UNK_77);
363 wr(DIB3000MB_REG_UNK_78, DIB3000MB_UNK_78);
364 wr(DIB3000MB_REG_ISI, DIB3000MB_ISI_INHIBIT);
365 wr(DIB3000MB_REG_UNK_92, DIB3000MB_UNK_92);
366 wr(DIB3000MB_REG_UNK_96, DIB3000MB_UNK_96);
367 wr(DIB3000MB_REG_UNK_97, DIB3000MB_UNK_97);
368 wr(DIB3000MB_REG_UNK_106, DIB3000MB_UNK_106);
369 wr(DIB3000MB_REG_UNK_107, DIB3000MB_UNK_107);
370 wr(DIB3000MB_REG_UNK_108, DIB3000MB_UNK_108);
371 wr(DIB3000MB_REG_UNK_122, DIB3000MB_UNK_122);
372 wr(DIB3000MB_REG_MOBILE_MODE_QAM, DIB3000MB_MOBILE_MODE_QAM_OFF);
373 wr(DIB3000MB_REG_BERLEN, DIB3000MB_BERLEN_DEFAULT);
374
375 wr_foreach(dib3000mb_reg_filter_coeffs, dib3000mb_filter_coeffs);
376
377 wr(DIB3000MB_REG_MOBILE_ALGO, DIB3000MB_MOBILE_ALGO_ON);
378 wr(DIB3000MB_REG_MULTI_DEMOD_MSB, DIB3000MB_MULTI_DEMOD_MSB);
379 wr(DIB3000MB_REG_MULTI_DEMOD_LSB, DIB3000MB_MULTI_DEMOD_LSB);
380
381 wr(DIB3000MB_REG_OUTPUT_MODE, DIB3000MB_OUTPUT_MODE_SLAVE);
382
383 wr(DIB3000MB_REG_FIFO_142, DIB3000MB_FIFO_142);
384 wr(DIB3000MB_REG_MPEG2_OUT_MODE, DIB3000MB_MPEG2_OUT_MODE_188);
385 wr(DIB3000MB_REG_PID_PARSE, DIB3000MB_PID_PARSE_ACTIVATE);
386 wr(DIB3000MB_REG_FIFO, DIB3000MB_FIFO_INHIBIT);
387 wr(DIB3000MB_REG_FIFO_146, DIB3000MB_FIFO_146);
388 wr(DIB3000MB_REG_FIFO_147, DIB3000MB_FIFO_147);
389
390 wr(DIB3000MB_REG_DATA_IN_DIVERSITY, DIB3000MB_DATA_DIVERSITY_IN_OFF);
391
392 if (state->config.pll_init) {
393 dib3000mb_tuner_pass_ctrl(fe,1,state->config.pll_addr(fe));
394 state->config.pll_init(fe,NULL);
395 dib3000mb_tuner_pass_ctrl(fe,0,state->config.pll_addr(fe));
396 }
397
398 return 0;
399}
400
401static int dib3000mb_get_frontend(struct dvb_frontend* fe,
402 struct dvb_frontend_parameters *fep)
403{
404 struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
405 struct dvb_ofdm_parameters *ofdm = &fep->u.ofdm;
406 fe_code_rate_t *cr;
407 u16 tps_val;
408 int inv_test1,inv_test2;
409 u32 dds_val, threshold = 0x800000;
410
411 if (!rd(DIB3000MB_REG_TPS_LOCK))
412 return 0;
413
414 dds_val = ((rd(DIB3000MB_REG_DDS_VALUE_MSB) & 0xff) << 16) + rd(DIB3000MB_REG_DDS_VALUE_LSB);
415 deb_getf("DDS_VAL: %x %x %x",dds_val, rd(DIB3000MB_REG_DDS_VALUE_MSB), rd(DIB3000MB_REG_DDS_VALUE_LSB));
416 if (dds_val < threshold)
417 inv_test1 = 0;
418 else if (dds_val == threshold)
419 inv_test1 = 1;
420 else
421 inv_test1 = 2;
422
423 dds_val = ((rd(DIB3000MB_REG_DDS_FREQ_MSB) & 0xff) << 16) + rd(DIB3000MB_REG_DDS_FREQ_LSB);
424 deb_getf("DDS_FREQ: %x %x %x",dds_val, rd(DIB3000MB_REG_DDS_FREQ_MSB), rd(DIB3000MB_REG_DDS_FREQ_LSB));
425 if (dds_val < threshold)
426 inv_test2 = 0;
427 else if (dds_val == threshold)
428 inv_test2 = 1;
429 else
430 inv_test2 = 2;
431
432 fep->inversion =
433 ((inv_test2 == 2) && (inv_test1==1 || inv_test1==0)) ||
434 ((inv_test2 == 0) && (inv_test1==1 || inv_test1==2)) ?
435 INVERSION_ON : INVERSION_OFF;
436
437 deb_getf("inversion %d %d, %d\n", inv_test2, inv_test1, fep->inversion);
438
439 switch ((tps_val = rd(DIB3000MB_REG_TPS_QAM))) {
440 case DIB3000_CONSTELLATION_QPSK:
441 deb_getf("QPSK ");
442 ofdm->constellation = QPSK;
443 break;
444 case DIB3000_CONSTELLATION_16QAM:
445 deb_getf("QAM16 ");
446 ofdm->constellation = QAM_16;
447 break;
448 case DIB3000_CONSTELLATION_64QAM:
449 deb_getf("QAM64 ");
450 ofdm->constellation = QAM_64;
451 break;
452 default:
453 err("Unexpected constellation returned by TPS (%d)", tps_val);
454 break;
455 }
456 deb_getf("TPS: %d\n", tps_val);
457
458 if (rd(DIB3000MB_REG_TPS_HRCH)) {
459 deb_getf("HRCH ON\n");
460 cr = &ofdm->code_rate_LP;
461 ofdm->code_rate_HP = FEC_NONE;
462 switch ((tps_val = rd(DIB3000MB_REG_TPS_VIT_ALPHA))) {
463 case DIB3000_ALPHA_0:
464 deb_getf("HIERARCHY_NONE ");
465 ofdm->hierarchy_information = HIERARCHY_NONE;
466 break;
467 case DIB3000_ALPHA_1:
468 deb_getf("HIERARCHY_1 ");
469 ofdm->hierarchy_information = HIERARCHY_1;
470 break;
471 case DIB3000_ALPHA_2:
472 deb_getf("HIERARCHY_2 ");
473 ofdm->hierarchy_information = HIERARCHY_2;
474 break;
475 case DIB3000_ALPHA_4:
476 deb_getf("HIERARCHY_4 ");
477 ofdm->hierarchy_information = HIERARCHY_4;
478 break;
479 default:
480 err("Unexpected ALPHA value returned by TPS (%d)", tps_val);
481 break;
482 }
483 deb_getf("TPS: %d\n", tps_val);
484
485 tps_val = rd(DIB3000MB_REG_TPS_CODE_RATE_LP);
486 } else {
487 deb_getf("HRCH OFF\n");
488 cr = &ofdm->code_rate_HP;
489 ofdm->code_rate_LP = FEC_NONE;
490 ofdm->hierarchy_information = HIERARCHY_NONE;
491
492 tps_val = rd(DIB3000MB_REG_TPS_CODE_RATE_HP);
493 }
494
495 switch (tps_val) {
496 case DIB3000_FEC_1_2:
497 deb_getf("FEC_1_2 ");
498 *cr = FEC_1_2;
499 break;
500 case DIB3000_FEC_2_3:
501 deb_getf("FEC_2_3 ");
502 *cr = FEC_2_3;
503 break;
504 case DIB3000_FEC_3_4:
505 deb_getf("FEC_3_4 ");
506 *cr = FEC_3_4;
507 break;
508 case DIB3000_FEC_5_6:
509 deb_getf("FEC_5_6 ");
510 *cr = FEC_4_5;
511 break;
512 case DIB3000_FEC_7_8:
513 deb_getf("FEC_7_8 ");
514 *cr = FEC_7_8;
515 break;
516 default:
517 err("Unexpected FEC returned by TPS (%d)", tps_val);
518 break;
519 }
520 deb_getf("TPS: %d\n",tps_val);
521
522 switch ((tps_val = rd(DIB3000MB_REG_TPS_GUARD_TIME))) {
523 case DIB3000_GUARD_TIME_1_32:
524 deb_getf("GUARD_INTERVAL_1_32 ");
525 ofdm->guard_interval = GUARD_INTERVAL_1_32;
526 break;
527 case DIB3000_GUARD_TIME_1_16:
528 deb_getf("GUARD_INTERVAL_1_16 ");
529 ofdm->guard_interval = GUARD_INTERVAL_1_16;
530 break;
531 case DIB3000_GUARD_TIME_1_8:
532 deb_getf("GUARD_INTERVAL_1_8 ");
533 ofdm->guard_interval = GUARD_INTERVAL_1_8;
534 break;
535 case DIB3000_GUARD_TIME_1_4:
536 deb_getf("GUARD_INTERVAL_1_4 ");
537 ofdm->guard_interval = GUARD_INTERVAL_1_4;
538 break;
539 default:
540 err("Unexpected Guard Time returned by TPS (%d)", tps_val);
541 break;
542 }
543 deb_getf("TPS: %d\n", tps_val);
544
545 switch ((tps_val = rd(DIB3000MB_REG_TPS_FFT))) {
546 case DIB3000_TRANSMISSION_MODE_2K:
547 deb_getf("TRANSMISSION_MODE_2K ");
548 ofdm->transmission_mode = TRANSMISSION_MODE_2K;
549 break;
550 case DIB3000_TRANSMISSION_MODE_8K:
551 deb_getf("TRANSMISSION_MODE_8K ");
552 ofdm->transmission_mode = TRANSMISSION_MODE_8K;
553 break;
554 default:
555 err("unexpected transmission mode return by TPS (%d)", tps_val);
556 break;
557 }
558 deb_getf("TPS: %d\n", tps_val);
559
560 return 0;
561}
562
563static int dib3000mb_read_status(struct dvb_frontend* fe, fe_status_t *stat)
564{
565 struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
566
567 *stat = 0;
568
569 if (rd(DIB3000MB_REG_AGC_LOCK))
570 *stat |= FE_HAS_SIGNAL;
571 if (rd(DIB3000MB_REG_CARRIER_LOCK))
572 *stat |= FE_HAS_CARRIER;
573 if (rd(DIB3000MB_REG_VIT_LCK))
574 *stat |= FE_HAS_VITERBI;
575 if (rd(DIB3000MB_REG_TS_SYNC_LOCK))
576 *stat |= (FE_HAS_SYNC | FE_HAS_LOCK);
577
578 deb_getf("actual status is %2x\n",*stat);
579
580 deb_getf("autoval: tps: %d, qam: %d, hrch: %d, alpha: %d, hp: %d, lp: %d, guard: %d, fft: %d cell: %d\n",
581 rd(DIB3000MB_REG_TPS_LOCK),
582 rd(DIB3000MB_REG_TPS_QAM),
583 rd(DIB3000MB_REG_TPS_HRCH),
584 rd(DIB3000MB_REG_TPS_VIT_ALPHA),
585 rd(DIB3000MB_REG_TPS_CODE_RATE_HP),
586 rd(DIB3000MB_REG_TPS_CODE_RATE_LP),
587 rd(DIB3000MB_REG_TPS_GUARD_TIME),
588 rd(DIB3000MB_REG_TPS_FFT),
589 rd(DIB3000MB_REG_TPS_CELL_ID));
590
591 //*stat = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
592 return 0;
593}
594
595static int dib3000mb_read_ber(struct dvb_frontend* fe, u32 *ber)
596{
597 struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
598
599 *ber = ((rd(DIB3000MB_REG_BER_MSB) << 16) | rd(DIB3000MB_REG_BER_LSB));
600 return 0;
601}
602
603/* see dib3000-watch dvb-apps for exact calcuations of signal_strength and snr */
604static int dib3000mb_read_signal_strength(struct dvb_frontend* fe, u16 *strength)
605{
606 struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
607
608 *strength = rd(DIB3000MB_REG_SIGNAL_POWER) * 0xffff / 0x170;
609 return 0;
610}
611
612static int dib3000mb_read_snr(struct dvb_frontend* fe, u16 *snr)
613{
614 struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
615 short sigpow = rd(DIB3000MB_REG_SIGNAL_POWER);
616 int icipow = ((rd(DIB3000MB_REG_NOISE_POWER_MSB) & 0xff) << 16) |
617 rd(DIB3000MB_REG_NOISE_POWER_LSB);
618 *snr = (sigpow << 8) / ((icipow > 0) ? icipow : 1);
619 return 0;
620}
621
622static int dib3000mb_read_unc_blocks(struct dvb_frontend* fe, u32 *unc)
623{
624 struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
625
626 *unc = rd(DIB3000MB_REG_UNC);
627 return 0;
628}
629
630static int dib3000mb_sleep(struct dvb_frontend* fe)
631{
632 struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
633 deb_info("dib3000mb is going to bed.\n");
634 wr(DIB3000MB_REG_POWER_CONTROL, DIB3000MB_POWER_DOWN);
635 return 0;
636}
637
638static int dib3000mb_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
639{
640 tune->min_delay_ms = 800;
641 tune->step_size = 166667;
642 tune->max_drift = 166667 * 2;
643
644 return 0;
645}
646
647static int dib3000mb_fe_init_nonmobile(struct dvb_frontend* fe)
648{
649 return dib3000mb_fe_init(fe, 0);
650}
651
652static int dib3000mb_set_frontend_and_tuner(struct dvb_frontend* fe, struct dvb_frontend_parameters *fep)
653{
654 return dib3000mb_set_frontend(fe, fep, 1);
655}
656
657static void dib3000mb_release(struct dvb_frontend* fe)
658{
659 struct dib3000_state *state = (struct dib3000_state*) fe->demodulator_priv;
660 kfree(state);
661}
662
663/* pid filter and transfer stuff */
664static int dib3000mb_pid_control(struct dvb_frontend *fe,int index, int pid,int onoff)
665{
666 struct dib3000_state *state = fe->demodulator_priv;
667 pid = (onoff ? pid | DIB3000_ACTIVATE_PID_FILTERING : 0);
668 wr(index+DIB3000MB_REG_FIRST_PID,pid);
669 return 0;
670}
671
672static int dib3000mb_fifo_control(struct dvb_frontend *fe, int onoff)
673{
674 struct dib3000_state *state = (struct dib3000_state*) fe->demodulator_priv;
675
676 deb_xfer("%s fifo\n",onoff ? "enabling" : "disabling");
677 if (onoff) {
678 wr(DIB3000MB_REG_FIFO, DIB3000MB_FIFO_ACTIVATE);
679 } else {
680 wr(DIB3000MB_REG_FIFO, DIB3000MB_FIFO_INHIBIT);
681 }
682 return 0;
683}
684
685static int dib3000mb_pid_parse(struct dvb_frontend *fe, int onoff)
686{
687 struct dib3000_state *state = fe->demodulator_priv;
688 deb_xfer("%s pid parsing\n",onoff ? "enabling" : "disabling");
689 wr(DIB3000MB_REG_PID_PARSE,onoff);
690 return 0;
691}
692
693static int dib3000mb_tuner_pass_ctrl(struct dvb_frontend *fe, int onoff, u8 pll_addr)
694{
695 struct dib3000_state *state = (struct dib3000_state*) fe->demodulator_priv;
696 if (onoff) {
697 wr(DIB3000MB_REG_TUNER, DIB3000_TUNER_WRITE_ENABLE(pll_addr));
698 } else {
699 wr(DIB3000MB_REG_TUNER, DIB3000_TUNER_WRITE_DISABLE(pll_addr));
700 }
701 return 0;
702}
703
704static struct dvb_frontend_ops dib3000mb_ops;
705
706struct dvb_frontend* dib3000mb_attach(const struct dib3000_config* config,
707 struct i2c_adapter* i2c, struct dib_fe_xfer_ops *xfer_ops)
708{
709 struct dib3000_state* state = NULL;
710
711 /* allocate memory for the internal state */
712 state = (struct dib3000_state*) kmalloc(sizeof(struct dib3000_state), GFP_KERNEL);
713 if (state == NULL)
714 goto error;
715 memset(state,0,sizeof(struct dib3000_state));
716
717 /* setup the state */
718 state->i2c = i2c;
719 memcpy(&state->config,config,sizeof(struct dib3000_config));
720 memcpy(&state->ops, &dib3000mb_ops, sizeof(struct dvb_frontend_ops));
721
722 /* check for the correct demod */
723 if (rd(DIB3000_REG_MANUFACTOR_ID) != DIB3000_I2C_ID_DIBCOM)
724 goto error;
725
726 if (rd(DIB3000_REG_DEVICE_ID) != DIB3000MB_DEVICE_ID)
727 goto error;
728
729 /* create dvb_frontend */
730 state->frontend.ops = &state->ops;
731 state->frontend.demodulator_priv = state;
732
733 /* set the xfer operations */
734 xfer_ops->pid_parse = dib3000mb_pid_parse;
735 xfer_ops->fifo_ctrl = dib3000mb_fifo_control;
736 xfer_ops->pid_ctrl = dib3000mb_pid_control;
737 xfer_ops->tuner_pass_ctrl = dib3000mb_tuner_pass_ctrl;
738
739 return &state->frontend;
740
741error:
742 kfree(state);
743 return NULL;
744}
745
746static struct dvb_frontend_ops dib3000mb_ops = {
747
748 .info = {
749 .name = "DiBcom 3000M-B DVB-T",
750 .type = FE_OFDM,
751 .frequency_min = 44250000,
752 .frequency_max = 867250000,
753 .frequency_stepsize = 62500,
754 .caps = FE_CAN_INVERSION_AUTO |
755 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
756 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
757 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
758 FE_CAN_TRANSMISSION_MODE_AUTO |
759 FE_CAN_GUARD_INTERVAL_AUTO |
760 FE_CAN_RECOVER |
761 FE_CAN_HIERARCHY_AUTO,
762 },
763
764 .release = dib3000mb_release,
765
766 .init = dib3000mb_fe_init_nonmobile,
767 .sleep = dib3000mb_sleep,
768
769 .set_frontend = dib3000mb_set_frontend_and_tuner,
770 .get_frontend = dib3000mb_get_frontend,
771 .get_tune_settings = dib3000mb_fe_get_tune_settings,
772
773 .read_status = dib3000mb_read_status,
774 .read_ber = dib3000mb_read_ber,
775 .read_signal_strength = dib3000mb_read_signal_strength,
776 .read_snr = dib3000mb_read_snr,
777 .read_ucblocks = dib3000mb_read_unc_blocks,
778};
779
780MODULE_AUTHOR(DRIVER_AUTHOR);
781MODULE_DESCRIPTION(DRIVER_DESC);
782MODULE_LICENSE("GPL");
783
784EXPORT_SYMBOL(dib3000mb_attach);
diff --git a/drivers/media/dvb/frontends/dib3000mb_priv.h b/drivers/media/dvb/frontends/dib3000mb_priv.h
new file mode 100644
index 000000000000..57e61aa5b07b
--- /dev/null
+++ b/drivers/media/dvb/frontends/dib3000mb_priv.h
@@ -0,0 +1,467 @@
1/*
2 * dib3000mb_priv.h
3 *
4 * Copyright (C) 2004 Patrick Boettcher (patrick.boettcher@desy.de)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation, version 2.
9 *
10 * for more information see dib3000mb.c .
11 */
12
13#ifndef __DIB3000MB_PRIV_H_INCLUDED__
14#define __DIB3000MB_PRIV_H_INCLUDED__
15
16/* register addresses and some of their default values */
17
18/* restart subsystems */
19#define DIB3000MB_REG_RESTART ( 0)
20
21#define DIB3000MB_RESTART_OFF ( 0)
22#define DIB3000MB_RESTART_AUTO_SEARCH (1 << 1)
23#define DIB3000MB_RESTART_CTRL (1 << 2)
24#define DIB3000MB_RESTART_AGC (1 << 3)
25
26/* FFT size */
27#define DIB3000MB_REG_FFT ( 1)
28
29/* Guard time */
30#define DIB3000MB_REG_GUARD_TIME ( 2)
31
32/* QAM */
33#define DIB3000MB_REG_QAM ( 3)
34
35/* Alpha coefficient high priority Viterbi algorithm */
36#define DIB3000MB_REG_VIT_ALPHA ( 4)
37
38/* spectrum inversion */
39#define DIB3000MB_REG_DDS_INV ( 5)
40
41/* DDS frequency value (IF position) ad ? values don't match reg_3000mb.txt */
42#define DIB3000MB_REG_DDS_FREQ_MSB ( 6)
43#define DIB3000MB_REG_DDS_FREQ_LSB ( 7)
44#define DIB3000MB_DDS_FREQ_MSB ( 178)
45#define DIB3000MB_DDS_FREQ_LSB ( 8990)
46
47/* timing frequency (carrier spacing) */
48static u16 dib3000mb_reg_timing_freq[] = { 8,9 };
49static u16 dib3000mb_timing_freq[][2] = {
50 { 126 , 48873 }, /* 6 MHz */
51 { 147 , 57019 }, /* 7 MHz */
52 { 168 , 65164 }, /* 8 MHz */
53};
54
55/* impulse noise parameter */
56/* 36 ??? */
57
58static u16 dib3000mb_reg_impulse_noise[] = { 10,11,12,15,36 };
59
60enum dib3000mb_impulse_noise_type {
61 DIB3000MB_IMPNOISE_OFF,
62 DIB3000MB_IMPNOISE_MOBILE,
63 DIB3000MB_IMPNOISE_FIXED,
64 DIB3000MB_IMPNOISE_DEFAULT
65};
66
67static u16 dib3000mb_impulse_noise_values[][5] = {
68 { 0x0000, 0x0004, 0x0014, 0x01ff, 0x0399 }, /* off */
69 { 0x0001, 0x0004, 0x0014, 0x01ff, 0x037b }, /* mobile */
70 { 0x0001, 0x0004, 0x0020, 0x01bd, 0x0399 }, /* fixed */
71 { 0x0000, 0x0002, 0x000a, 0x01ff, 0x0399 }, /* default */
72};
73
74/*
75 * Dual Automatic-Gain-Control
76 * - gains RF in tuner (AGC1)
77 * - gains IF after filtering (AGC2)
78 */
79
80/* also from 16 to 18 */
81static u16 dib3000mb_reg_agc_gain[] = {
82 19,20,21,22,23,24,25,26,27,28,29,30,31,32
83};
84
85static u16 dib3000mb_default_agc_gain[] =
86 { 0x0001, 52429, 623, 128, 166, 195, 61, /* RF ??? */
87 0x0001, 53766, 38011, 0, 90, 33, 23 }; /* IF ??? */
88
89/* phase noise */
90/* 36 is set when setting the impulse noise */
91static u16 dib3000mb_reg_phase_noise[] = { 33,34,35,37,38 };
92
93static u16 dib3000mb_default_noise_phase[] = { 2, 544, 0, 5, 4 };
94
95/* lock duration */
96static u16 dib3000mb_reg_lock_duration[] = { 39,40 };
97static u16 dib3000mb_default_lock_duration[] = { 135, 135 };
98
99/* AGC loop bandwidth */
100static u16 dib3000mb_reg_agc_bandwidth[] = { 43,44,45,46,47,48,49,50 };
101
102static u16 dib3000mb_agc_bandwidth_low[] =
103 { 2088, 10, 2088, 10, 3448, 5, 3448, 5 };
104static u16 dib3000mb_agc_bandwidth_high[] =
105 { 2349, 5, 2349, 5, 2586, 2, 2586, 2 };
106
107/*
108 * lock0 definition (coff_lock)
109 */
110#define DIB3000MB_REG_LOCK0_MASK ( 51)
111#define DIB3000MB_LOCK0_DEFAULT ( 4)
112
113/*
114 * lock1 definition (cpil_lock)
115 * for auto search
116 * which values hide behind the lock masks
117 */
118#define DIB3000MB_REG_LOCK1_MASK ( 52)
119#define DIB3000MB_LOCK1_SEARCH_4 (0x0004)
120#define DIB3000MB_LOCK1_SEARCH_2048 (0x0800)
121#define DIB3000MB_LOCK1_DEFAULT (0x0001)
122
123/*
124 * lock2 definition (fec_lock) */
125#define DIB3000MB_REG_LOCK2_MASK ( 53)
126#define DIB3000MB_LOCK2_DEFAULT (0x0080)
127
128/*
129 * SEQ ? what was that again ... :)
130 * changes when, inversion, guard time and fft is
131 * either automatically detected or not
132 */
133#define DIB3000MB_REG_SEQ ( 54)
134
135/* bandwidth */
136static u16 dib3000mb_reg_bandwidth[] = { 55,56,57,58,59,60,61,62,63,64,65,66,67 };
137static u16 dib3000mb_bandwidth_6mhz[] =
138 { 0, 33, 53312, 112, 46635, 563, 36565, 0, 1000, 0, 1010, 1, 45264 };
139
140static u16 dib3000mb_bandwidth_7mhz[] =
141 { 0, 28, 64421, 96, 39973, 483, 3255, 0, 1000, 0, 1010, 1, 45264 };
142
143static u16 dib3000mb_bandwidth_8mhz[] =
144 { 0, 25, 23600, 84, 34976, 422, 43808, 0, 1000, 0, 1010, 1, 45264 };
145
146#define DIB3000MB_REG_UNK_68 ( 68)
147#define DIB3000MB_UNK_68 ( 0)
148
149#define DIB3000MB_REG_UNK_69 ( 69)
150#define DIB3000MB_UNK_69 ( 0)
151
152#define DIB3000MB_REG_UNK_71 ( 71)
153#define DIB3000MB_UNK_71 ( 0)
154
155#define DIB3000MB_REG_UNK_77 ( 77)
156#define DIB3000MB_UNK_77 ( 6)
157
158#define DIB3000MB_REG_UNK_78 ( 78)
159#define DIB3000MB_UNK_78 (0x0080)
160
161/* isi */
162#define DIB3000MB_REG_ISI ( 79)
163#define DIB3000MB_ISI_ACTIVATE ( 0)
164#define DIB3000MB_ISI_INHIBIT ( 1)
165
166/* sync impovement */
167#define DIB3000MB_REG_SYNC_IMPROVEMENT ( 84)
168#define DIB3000MB_SYNC_IMPROVE_2K_1_8 ( 3)
169#define DIB3000MB_SYNC_IMPROVE_DEFAULT ( 0)
170
171/* phase noise compensation inhibition */
172#define DIB3000MB_REG_PHASE_NOISE ( 87)
173#define DIB3000MB_PHASE_NOISE_DEFAULT ( 0)
174
175#define DIB3000MB_REG_UNK_92 ( 92)
176#define DIB3000MB_UNK_92 (0x0080)
177
178#define DIB3000MB_REG_UNK_96 ( 96)
179#define DIB3000MB_UNK_96 (0x0010)
180
181#define DIB3000MB_REG_UNK_97 ( 97)
182#define DIB3000MB_UNK_97 (0x0009)
183
184/* mobile mode ??? */
185#define DIB3000MB_REG_MOBILE_MODE ( 101)
186#define DIB3000MB_MOBILE_MODE_ON ( 1)
187#define DIB3000MB_MOBILE_MODE_OFF ( 0)
188
189#define DIB3000MB_REG_UNK_106 ( 106)
190#define DIB3000MB_UNK_106 (0x0080)
191
192#define DIB3000MB_REG_UNK_107 ( 107)
193#define DIB3000MB_UNK_107 (0x0080)
194
195#define DIB3000MB_REG_UNK_108 ( 108)
196#define DIB3000MB_UNK_108 (0x0080)
197
198/* fft */
199#define DIB3000MB_REG_UNK_121 ( 121)
200#define DIB3000MB_UNK_121_2K ( 7)
201#define DIB3000MB_UNK_121_DEFAULT ( 5)
202
203#define DIB3000MB_REG_UNK_122 ( 122)
204#define DIB3000MB_UNK_122 ( 2867)
205
206/* QAM for mobile mode */
207#define DIB3000MB_REG_MOBILE_MODE_QAM ( 126)
208#define DIB3000MB_MOBILE_MODE_QAM_64 ( 3)
209#define DIB3000MB_MOBILE_MODE_QAM_QPSK_16 ( 1)
210#define DIB3000MB_MOBILE_MODE_QAM_OFF ( 0)
211
212/*
213 * data diversity when having more than one chip on-board
214 * see also DIB3000MB_OUTPUT_MODE_DATA_DIVERSITY
215 */
216#define DIB3000MB_REG_DATA_IN_DIVERSITY ( 127)
217#define DIB3000MB_DATA_DIVERSITY_IN_OFF ( 0)
218#define DIB3000MB_DATA_DIVERSITY_IN_ON ( 2)
219
220/* vit hrch */
221#define DIB3000MB_REG_VIT_HRCH ( 128)
222
223/* vit code rate */
224#define DIB3000MB_REG_VIT_CODE_RATE ( 129)
225
226/* vit select hp */
227#define DIB3000MB_REG_VIT_HP ( 130)
228
229/* time frame for Bit-Error-Rate calculation */
230#define DIB3000MB_REG_BERLEN ( 135)
231#define DIB3000MB_BERLEN_LONG ( 0)
232#define DIB3000MB_BERLEN_DEFAULT ( 1)
233#define DIB3000MB_BERLEN_MEDIUM ( 2)
234#define DIB3000MB_BERLEN_SHORT ( 3)
235
236/* 142 - 152 FIFO parameters
237 * which is what ?
238 */
239
240#define DIB3000MB_REG_FIFO_142 ( 142)
241#define DIB3000MB_FIFO_142 ( 0)
242
243/* MPEG2 TS output mode */
244#define DIB3000MB_REG_MPEG2_OUT_MODE ( 143)
245#define DIB3000MB_MPEG2_OUT_MODE_204 ( 0)
246#define DIB3000MB_MPEG2_OUT_MODE_188 ( 1)
247
248#define DIB3000MB_REG_PID_PARSE ( 144)
249#define DIB3000MB_PID_PARSE_INHIBIT ( 0)
250#define DIB3000MB_PID_PARSE_ACTIVATE ( 1)
251
252#define DIB3000MB_REG_FIFO ( 145)
253#define DIB3000MB_FIFO_INHIBIT ( 1)
254#define DIB3000MB_FIFO_ACTIVATE ( 0)
255
256#define DIB3000MB_REG_FIFO_146 ( 146)
257#define DIB3000MB_FIFO_146 ( 3)
258
259#define DIB3000MB_REG_FIFO_147 ( 147)
260#define DIB3000MB_FIFO_147 (0x0100)
261
262/*
263 * pidfilter
264 * it is not a hardware pidfilter but a filter which drops all pids
265 * except the ones set. Necessary because of the limited USB1.1 bandwidth.
266 * regs 153-168
267 */
268
269#define DIB3000MB_REG_FIRST_PID ( 153)
270#define DIB3000MB_NUM_PIDS ( 16)
271
272/*
273 * output mode
274 * USB devices have to use 'slave'-mode
275 * see also DIB3000MB_REG_ELECT_OUT_MODE
276 */
277#define DIB3000MB_REG_OUTPUT_MODE ( 169)
278#define DIB3000MB_OUTPUT_MODE_GATED_CLK ( 0)
279#define DIB3000MB_OUTPUT_MODE_CONT_CLK ( 1)
280#define DIB3000MB_OUTPUT_MODE_SERIAL ( 2)
281#define DIB3000MB_OUTPUT_MODE_DATA_DIVERSITY ( 5)
282#define DIB3000MB_OUTPUT_MODE_SLAVE ( 6)
283
284/* irq event mask */
285#define DIB3000MB_REG_IRQ_EVENT_MASK ( 170)
286#define DIB3000MB_IRQ_EVENT_MASK ( 0)
287
288/* filter coefficients */
289static u16 dib3000mb_reg_filter_coeffs[] = {
290 171, 172, 173, 174, 175, 176, 177, 178,
291 179, 180, 181, 182, 183, 184, 185, 186,
292 188, 189, 190, 191, 192, 194
293};
294
295static u16 dib3000mb_filter_coeffs[] = {
296 226, 160, 29,
297 979, 998, 19,
298 22, 1019, 1006,
299 1022, 12, 6,
300 1017, 1017, 3,
301 6, 1019,
302 1021, 2, 3,
303 1, 0,
304};
305
306/*
307 * mobile algorithm (when you are moving with your device)
308 * but not faster than 90 km/h
309 */
310#define DIB3000MB_REG_MOBILE_ALGO ( 195)
311#define DIB3000MB_MOBILE_ALGO_ON ( 0)
312#define DIB3000MB_MOBILE_ALGO_OFF ( 1)
313
314/* multiple demodulators algorithm */
315#define DIB3000MB_REG_MULTI_DEMOD_MSB ( 206)
316#define DIB3000MB_REG_MULTI_DEMOD_LSB ( 207)
317
318/* terminator, no more demods */
319#define DIB3000MB_MULTI_DEMOD_MSB ( 32767)
320#define DIB3000MB_MULTI_DEMOD_LSB ( 4095)
321
322/* bring the device into a known */
323#define DIB3000MB_REG_RESET_DEVICE ( 1024)
324#define DIB3000MB_RESET_DEVICE (0x812c)
325#define DIB3000MB_RESET_DEVICE_RST ( 0)
326
327/* hardware clock configuration */
328#define DIB3000MB_REG_CLOCK ( 1027)
329#define DIB3000MB_CLOCK_DEFAULT (0x9000)
330#define DIB3000MB_CLOCK_DIVERSITY (0x92b0)
331
332/* power down config */
333#define DIB3000MB_REG_POWER_CONTROL ( 1028)
334#define DIB3000MB_POWER_DOWN ( 1)
335#define DIB3000MB_POWER_UP ( 0)
336
337/* electrical output mode */
338#define DIB3000MB_REG_ELECT_OUT_MODE ( 1029)
339#define DIB3000MB_ELECT_OUT_MODE_OFF ( 0)
340#define DIB3000MB_ELECT_OUT_MODE_ON ( 1)
341
342/* set the tuner i2c address */
343#define DIB3000MB_REG_TUNER ( 1089)
344
345/* monitoring registers (read only) */
346
347/* agc loop locked (size: 1) */
348#define DIB3000MB_REG_AGC_LOCK ( 324)
349
350/* agc power (size: 16) */
351#define DIB3000MB_REG_AGC_POWER ( 325)
352
353/* agc1 value (16) */
354#define DIB3000MB_REG_AGC1_VALUE ( 326)
355
356/* agc2 value (16) */
357#define DIB3000MB_REG_AGC2_VALUE ( 327)
358
359/* total RF power (16), can be used for signal strength */
360#define DIB3000MB_REG_RF_POWER ( 328)
361
362/* dds_frequency with offset (24) */
363#define DIB3000MB_REG_DDS_VALUE_MSB ( 339)
364#define DIB3000MB_REG_DDS_VALUE_LSB ( 340)
365
366/* timing offset signed (24) */
367#define DIB3000MB_REG_TIMING_OFFSET_MSB ( 341)
368#define DIB3000MB_REG_TIMING_OFFSET_LSB ( 342)
369
370/* fft start position (13) */
371#define DIB3000MB_REG_FFT_WINDOW_POS ( 353)
372
373/* carriers locked (1) */
374#define DIB3000MB_REG_CARRIER_LOCK ( 355)
375
376/* noise power (24) */
377#define DIB3000MB_REG_NOISE_POWER_MSB ( 372)
378#define DIB3000MB_REG_NOISE_POWER_LSB ( 373)
379
380#define DIB3000MB_REG_MOBILE_NOISE_MSB ( 374)
381#define DIB3000MB_REG_MOBILE_NOISE_LSB ( 375)
382
383/*
384 * signal power (16), this and the above can be
385 * used to calculate the signal/noise - ratio
386 */
387#define DIB3000MB_REG_SIGNAL_POWER ( 380)
388
389/* mer (24) */
390#define DIB3000MB_REG_MER_MSB ( 381)
391#define DIB3000MB_REG_MER_LSB ( 382)
392
393/*
394 * Transmission Parameter Signalling (TPS)
395 * the following registers can be used to get TPS-information.
396 * The values are according to the DVB-T standard.
397 */
398
399/* TPS locked (1) */
400#define DIB3000MB_REG_TPS_LOCK ( 394)
401
402/* QAM from TPS (2) (values according to DIB3000MB_REG_QAM) */
403#define DIB3000MB_REG_TPS_QAM ( 398)
404
405/* hierarchy from TPS (1) */
406#define DIB3000MB_REG_TPS_HRCH ( 399)
407
408/* alpha from TPS (3) (values according to DIB3000MB_REG_VIT_ALPHA) */
409#define DIB3000MB_REG_TPS_VIT_ALPHA ( 400)
410
411/* code rate high priority from TPS (3) (values according to DIB3000MB_FEC_*) */
412#define DIB3000MB_REG_TPS_CODE_RATE_HP ( 401)
413
414/* code rate low priority from TPS (3) if DIB3000MB_REG_TPS_VIT_ALPHA */
415#define DIB3000MB_REG_TPS_CODE_RATE_LP ( 402)
416
417/* guard time from TPS (2) (values according to DIB3000MB_REG_GUARD_TIME */
418#define DIB3000MB_REG_TPS_GUARD_TIME ( 403)
419
420/* fft size from TPS (2) (values according to DIB3000MB_REG_FFT) */
421#define DIB3000MB_REG_TPS_FFT ( 404)
422
423/* cell id from TPS (16) */
424#define DIB3000MB_REG_TPS_CELL_ID ( 406)
425
426/* TPS (68) */
427#define DIB3000MB_REG_TPS_1 ( 408)
428#define DIB3000MB_REG_TPS_2 ( 409)
429#define DIB3000MB_REG_TPS_3 ( 410)
430#define DIB3000MB_REG_TPS_4 ( 411)
431#define DIB3000MB_REG_TPS_5 ( 412)
432
433/* bit error rate (before RS correction) (21) */
434#define DIB3000MB_REG_BER_MSB ( 414)
435#define DIB3000MB_REG_BER_LSB ( 415)
436
437/* packet error rate (uncorrected TS packets) (16) */
438#define DIB3000MB_REG_PACKET_ERROR_RATE ( 417)
439
440/* uncorrected packet count (16) */
441#define DIB3000MB_REG_UNC ( 420)
442
443/* viterbi locked (1) */
444#define DIB3000MB_REG_VIT_LCK ( 421)
445
446/* viterbi inidcator (16) */
447#define DIB3000MB_REG_VIT_INDICATOR ( 422)
448
449/* transport stream sync lock (1) */
450#define DIB3000MB_REG_TS_SYNC_LOCK ( 423)
451
452/* transport stream RS lock (1) */
453#define DIB3000MB_REG_TS_RS_LOCK ( 424)
454
455/* lock mask 0 value (1) */
456#define DIB3000MB_REG_LOCK0_VALUE ( 425)
457
458/* lock mask 1 value (1) */
459#define DIB3000MB_REG_LOCK1_VALUE ( 426)
460
461/* lock mask 2 value (1) */
462#define DIB3000MB_REG_LOCK2_VALUE ( 427)
463
464/* interrupt pending for auto search */
465#define DIB3000MB_REG_AS_IRQ_PENDING ( 434)
466
467#endif
diff --git a/drivers/media/dvb/frontends/dib3000mc.c b/drivers/media/dvb/frontends/dib3000mc.c
new file mode 100644
index 000000000000..4a31c05eaecd
--- /dev/null
+++ b/drivers/media/dvb/frontends/dib3000mc.c
@@ -0,0 +1,931 @@
1/*
2 * Frontend driver for mobile DVB-T demodulator DiBcom 3000P/M-C
3 * DiBcom (http://www.dibcom.fr/)
4 *
5 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
6 *
7 * based on GPL code from DiBCom, which has
8 *
9 * Copyright (C) 2004 Amaury Demol for DiBcom (ademol@dibcom.fr)
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 as
13 * published by the Free Software Foundation, version 2.
14 *
15 * Acknowledgements
16 *
17 * Amaury Demol (ademol@dibcom.fr) from DiBcom for providing specs and driver
18 * sources, on which this driver (and the dvb-dibusb) are based.
19 *
20 * see Documentation/dvb/README.dibusb for more information
21 *
22 */
23#include <linux/config.h>
24#include <linux/kernel.h>
25#include <linux/version.h>
26#include <linux/module.h>
27#include <linux/moduleparam.h>
28#include <linux/init.h>
29#include <linux/delay.h>
30
31#include "dib3000-common.h"
32#include "dib3000mc_priv.h"
33#include "dib3000.h"
34
35/* Version information */
36#define DRIVER_VERSION "0.1"
37#define DRIVER_DESC "DiBcom 3000M-C DVB-T demodulator"
38#define DRIVER_AUTHOR "Patrick Boettcher, patrick.boettcher@desy.de"
39
40#ifdef CONFIG_DVB_DIBCOM_DEBUG
41static int debug;
42module_param(debug, int, 0644);
43MODULE_PARM_DESC(debug, "set debugging level (1=info,2=xfer,4=setfe,8=getfe,16=stat (|-able)).");
44#endif
45#define deb_info(args...) dprintk(0x01,args)
46#define deb_xfer(args...) dprintk(0x02,args)
47#define deb_setf(args...) dprintk(0x04,args)
48#define deb_getf(args...) dprintk(0x08,args)
49#define deb_stat(args...) dprintk(0x10,args)
50
51static int dib3000mc_tuner_pass_ctrl(struct dvb_frontend *fe, int onoff, u8 pll_addr);
52
53static int dib3000mc_set_impulse_noise(struct dib3000_state * state, int mode,
54 fe_transmit_mode_t transmission_mode, fe_bandwidth_t bandwidth)
55{
56 switch (transmission_mode) {
57 case TRANSMISSION_MODE_2K:
58 wr_foreach(dib3000mc_reg_fft,dib3000mc_fft_modes[0]);
59 break;
60 case TRANSMISSION_MODE_8K:
61 wr_foreach(dib3000mc_reg_fft,dib3000mc_fft_modes[1]);
62 break;
63 default:
64 break;
65 }
66
67 switch (bandwidth) {
68/* case BANDWIDTH_5_MHZ:
69 wr_foreach(dib3000mc_reg_impulse_noise,dib3000mc_impluse_noise[0]);
70 break; */
71 case BANDWIDTH_6_MHZ:
72 wr_foreach(dib3000mc_reg_impulse_noise,dib3000mc_impluse_noise[1]);
73 break;
74 case BANDWIDTH_7_MHZ:
75 wr_foreach(dib3000mc_reg_impulse_noise,dib3000mc_impluse_noise[2]);
76 break;
77 case BANDWIDTH_8_MHZ:
78 wr_foreach(dib3000mc_reg_impulse_noise,dib3000mc_impluse_noise[3]);
79 break;
80 default:
81 break;
82 }
83
84 switch (mode) {
85 case 0: /* no impulse */ /* fall through */
86 wr_foreach(dib3000mc_reg_imp_noise_ctl,dib3000mc_imp_noise_ctl[0]);
87 break;
88 case 1: /* new algo */
89 wr_foreach(dib3000mc_reg_imp_noise_ctl,dib3000mc_imp_noise_ctl[1]);
90 set_or(DIB3000MC_REG_IMP_NOISE_55,DIB3000MC_IMP_NEW_ALGO(0)); /* gives 1<<10 */
91 break;
92 default: /* old algo */
93 wr_foreach(dib3000mc_reg_imp_noise_ctl,dib3000mc_imp_noise_ctl[3]);
94 break;
95 }
96 return 0;
97}
98
99static int dib3000mc_set_timing(struct dib3000_state *state, int upd_offset,
100 fe_transmit_mode_t fft, fe_bandwidth_t bw)
101{
102 u16 timf_msb,timf_lsb;
103 s32 tim_offset,tim_sgn;
104 u64 comp1,comp2,comp=0;
105
106 switch (bw) {
107 case BANDWIDTH_8_MHZ: comp = DIB3000MC_CLOCK_REF*8; break;
108 case BANDWIDTH_7_MHZ: comp = DIB3000MC_CLOCK_REF*7; break;
109 case BANDWIDTH_6_MHZ: comp = DIB3000MC_CLOCK_REF*6; break;
110 default: err("unknown bandwidth (%d)",bw); break;
111 }
112 timf_msb = (comp >> 16) & 0xff;
113 timf_lsb = (comp & 0xffff);
114
115 // Update the timing offset ;
116 if (upd_offset > 0) {
117 if (!state->timing_offset_comp_done) {
118 msleep(200);
119 state->timing_offset_comp_done = 1;
120 }
121 tim_offset = rd(DIB3000MC_REG_TIMING_OFFS_MSB);
122 if ((tim_offset & 0x2000) == 0x2000)
123 tim_offset |= 0xC000;
124 if (fft == TRANSMISSION_MODE_2K)
125 tim_offset <<= 2;
126 state->timing_offset += tim_offset;
127 }
128
129 tim_offset = state->timing_offset;
130 if (tim_offset < 0) {
131 tim_sgn = 1;
132 tim_offset = -tim_offset;
133 } else
134 tim_sgn = 0;
135
136 comp1 = (u32)tim_offset * (u32)timf_lsb ;
137 comp2 = (u32)tim_offset * (u32)timf_msb ;
138 comp = ((comp1 >> 16) + comp2) >> 7;
139
140 if (tim_sgn == 0)
141 comp = (u32)(timf_msb << 16) + (u32) timf_lsb + comp;
142 else
143 comp = (u32)(timf_msb << 16) + (u32) timf_lsb - comp ;
144
145 timf_msb = (comp >> 16) & 0xff;
146 timf_lsb = comp & 0xffff;
147
148 wr(DIB3000MC_REG_TIMING_FREQ_MSB,timf_msb);
149 wr(DIB3000MC_REG_TIMING_FREQ_LSB,timf_lsb);
150 return 0;
151}
152
153static int dib3000mc_init_auto_scan(struct dib3000_state *state, fe_bandwidth_t bw, int boost)
154{
155 if (boost) {
156 wr(DIB3000MC_REG_SCAN_BOOST,DIB3000MC_SCAN_BOOST_ON);
157 } else {
158 wr(DIB3000MC_REG_SCAN_BOOST,DIB3000MC_SCAN_BOOST_OFF);
159 }
160 switch (bw) {
161 case BANDWIDTH_8_MHZ:
162 wr_foreach(dib3000mc_reg_bandwidth,dib3000mc_bandwidth_8mhz);
163 break;
164 case BANDWIDTH_7_MHZ:
165 wr_foreach(dib3000mc_reg_bandwidth,dib3000mc_bandwidth_7mhz);
166 break;
167 case BANDWIDTH_6_MHZ:
168 wr_foreach(dib3000mc_reg_bandwidth,dib3000mc_bandwidth_6mhz);
169 break;
170/* case BANDWIDTH_5_MHZ:
171 wr_foreach(dib3000mc_reg_bandwidth,dib3000mc_bandwidth_5mhz);
172 break;*/
173 case BANDWIDTH_AUTO:
174 return -EOPNOTSUPP;
175 default:
176 err("unknown bandwidth value (%d).",bw);
177 return -EINVAL;
178 }
179 if (boost) {
180 u32 timeout = (rd(DIB3000MC_REG_BW_TIMOUT_MSB) << 16) +
181 rd(DIB3000MC_REG_BW_TIMOUT_LSB);
182 timeout *= 85; timeout >>= 7;
183 wr(DIB3000MC_REG_BW_TIMOUT_MSB,(timeout >> 16) & 0xffff);
184 wr(DIB3000MC_REG_BW_TIMOUT_LSB,timeout & 0xffff);
185 }
186 return 0;
187}
188
189static int dib3000mc_set_adp_cfg(struct dib3000_state *state, fe_modulation_t con)
190{
191 switch (con) {
192 case QAM_64:
193 wr_foreach(dib3000mc_reg_adp_cfg,dib3000mc_adp_cfg[2]);
194 break;
195 case QAM_16:
196 wr_foreach(dib3000mc_reg_adp_cfg,dib3000mc_adp_cfg[1]);
197 break;
198 case QPSK:
199 wr_foreach(dib3000mc_reg_adp_cfg,dib3000mc_adp_cfg[0]);
200 break;
201 case QAM_AUTO:
202 break;
203 default:
204 warn("unkown constellation.");
205 break;
206 }
207 return 0;
208}
209
210static int dib3000mc_set_general_cfg(struct dib3000_state *state, struct dvb_frontend_parameters *fep, int *auto_val)
211{
212 struct dvb_ofdm_parameters *ofdm = &fep->u.ofdm;
213 fe_code_rate_t fe_cr = FEC_NONE;
214 u8 fft=0, guard=0, qam=0, alpha=0, sel_hp=0, cr=0, hrch=0;
215 int seq;
216
217 switch (ofdm->transmission_mode) {
218 case TRANSMISSION_MODE_2K: fft = DIB3000_TRANSMISSION_MODE_2K; break;
219 case TRANSMISSION_MODE_8K: fft = DIB3000_TRANSMISSION_MODE_8K; break;
220 case TRANSMISSION_MODE_AUTO: break;
221 default: return -EINVAL;
222 }
223 switch (ofdm->guard_interval) {
224 case GUARD_INTERVAL_1_32: guard = DIB3000_GUARD_TIME_1_32; break;
225 case GUARD_INTERVAL_1_16: guard = DIB3000_GUARD_TIME_1_16; break;
226 case GUARD_INTERVAL_1_8: guard = DIB3000_GUARD_TIME_1_8; break;
227 case GUARD_INTERVAL_1_4: guard = DIB3000_GUARD_TIME_1_4; break;
228 case GUARD_INTERVAL_AUTO: break;
229 default: return -EINVAL;
230 }
231 switch (ofdm->constellation) {
232 case QPSK: qam = DIB3000_CONSTELLATION_QPSK; break;
233 case QAM_16: qam = DIB3000_CONSTELLATION_16QAM; break;
234 case QAM_64: qam = DIB3000_CONSTELLATION_64QAM; break;
235 case QAM_AUTO: break;
236 default: return -EINVAL;
237 }
238 switch (ofdm->hierarchy_information) {
239 case HIERARCHY_NONE: /* fall through */
240 case HIERARCHY_1: alpha = DIB3000_ALPHA_1; break;
241 case HIERARCHY_2: alpha = DIB3000_ALPHA_2; break;
242 case HIERARCHY_4: alpha = DIB3000_ALPHA_4; break;
243 case HIERARCHY_AUTO: break;
244 default: return -EINVAL;
245 }
246 if (ofdm->hierarchy_information == HIERARCHY_NONE) {
247 hrch = DIB3000_HRCH_OFF;
248 sel_hp = DIB3000_SELECT_HP;
249 fe_cr = ofdm->code_rate_HP;
250 } else if (ofdm->hierarchy_information != HIERARCHY_AUTO) {
251 hrch = DIB3000_HRCH_ON;
252 sel_hp = DIB3000_SELECT_LP;
253 fe_cr = ofdm->code_rate_LP;
254 }
255 switch (fe_cr) {
256 case FEC_1_2: cr = DIB3000_FEC_1_2; break;
257 case FEC_2_3: cr = DIB3000_FEC_2_3; break;
258 case FEC_3_4: cr = DIB3000_FEC_3_4; break;
259 case FEC_5_6: cr = DIB3000_FEC_5_6; break;
260 case FEC_7_8: cr = DIB3000_FEC_7_8; break;
261 case FEC_NONE: break;
262 case FEC_AUTO: break;
263 default: return -EINVAL;
264 }
265
266 wr(DIB3000MC_REG_DEMOD_PARM,DIB3000MC_DEMOD_PARM(alpha,qam,guard,fft));
267 wr(DIB3000MC_REG_HRCH_PARM,DIB3000MC_HRCH_PARM(sel_hp,cr,hrch));
268
269 switch (fep->inversion) {
270 case INVERSION_OFF:
271 wr(DIB3000MC_REG_SET_DDS_FREQ_MSB,DIB3000MC_DDS_FREQ_MSB_INV_OFF);
272 break;
273 case INVERSION_AUTO: /* fall through */
274 case INVERSION_ON:
275 wr(DIB3000MC_REG_SET_DDS_FREQ_MSB,DIB3000MC_DDS_FREQ_MSB_INV_ON);
276 break;
277 default:
278 return -EINVAL;
279 }
280
281 seq = dib3000_seq
282 [ofdm->transmission_mode == TRANSMISSION_MODE_AUTO]
283 [ofdm->guard_interval == GUARD_INTERVAL_AUTO]
284 [fep->inversion == INVERSION_AUTO];
285
286 deb_setf("seq? %d\n", seq);
287 wr(DIB3000MC_REG_SEQ_TPS,DIB3000MC_SEQ_TPS(seq,1));
288 *auto_val = ofdm->constellation == QAM_AUTO ||
289 ofdm->hierarchy_information == HIERARCHY_AUTO ||
290 ofdm->guard_interval == GUARD_INTERVAL_AUTO ||
291 ofdm->transmission_mode == TRANSMISSION_MODE_AUTO ||
292 fe_cr == FEC_AUTO ||
293 fep->inversion == INVERSION_AUTO;
294 return 0;
295}
296
297static int dib3000mc_get_frontend(struct dvb_frontend* fe,
298 struct dvb_frontend_parameters *fep)
299{
300 struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
301 struct dvb_ofdm_parameters *ofdm = &fep->u.ofdm;
302 fe_code_rate_t *cr;
303 u16 tps_val,cr_val;
304 int inv_test1,inv_test2;
305 u32 dds_val, threshold = 0x1000000;
306
307 if (!(rd(DIB3000MC_REG_LOCK_507) & DIB3000MC_LOCK_507))
308 return 0;
309
310 dds_val = (rd(DIB3000MC_REG_DDS_FREQ_MSB) << 16) + rd(DIB3000MC_REG_DDS_FREQ_LSB);
311 deb_getf("DDS_FREQ: %6x\n",dds_val);
312 if (dds_val < threshold)
313 inv_test1 = 0;
314 else if (dds_val == threshold)
315 inv_test1 = 1;
316 else
317 inv_test1 = 2;
318
319 dds_val = (rd(DIB3000MC_REG_SET_DDS_FREQ_MSB) << 16) + rd(DIB3000MC_REG_SET_DDS_FREQ_LSB);
320 deb_getf("DDS_SET_FREQ: %6x\n",dds_val);
321 if (dds_val < threshold)
322 inv_test2 = 0;
323 else if (dds_val == threshold)
324 inv_test2 = 1;
325 else
326 inv_test2 = 2;
327
328 fep->inversion =
329 ((inv_test2 == 2) && (inv_test1==1 || inv_test1==0)) ||
330 ((inv_test2 == 0) && (inv_test1==1 || inv_test1==2)) ?
331 INVERSION_ON : INVERSION_OFF;
332
333 deb_getf("inversion %d %d, %d\n", inv_test2, inv_test1, fep->inversion);
334
335 fep->frequency = state->last_tuned_freq;
336 fep->u.ofdm.bandwidth= state->last_tuned_bw;
337
338 tps_val = rd(DIB3000MC_REG_TUNING_PARM);
339
340 switch (DIB3000MC_TP_QAM(tps_val)) {
341 case DIB3000_CONSTELLATION_QPSK:
342 deb_getf("QPSK ");
343 ofdm->constellation = QPSK;
344 break;
345 case DIB3000_CONSTELLATION_16QAM:
346 deb_getf("QAM16 ");
347 ofdm->constellation = QAM_16;
348 break;
349 case DIB3000_CONSTELLATION_64QAM:
350 deb_getf("QAM64 ");
351 ofdm->constellation = QAM_64;
352 break;
353 default:
354 err("Unexpected constellation returned by TPS (%d)", tps_val);
355 break;
356 }
357
358 if (DIB3000MC_TP_HRCH(tps_val)) {
359 deb_getf("HRCH ON ");
360 cr = &ofdm->code_rate_LP;
361 ofdm->code_rate_HP = FEC_NONE;
362 switch (DIB3000MC_TP_ALPHA(tps_val)) {
363 case DIB3000_ALPHA_0:
364 deb_getf("HIERARCHY_NONE ");
365 ofdm->hierarchy_information = HIERARCHY_NONE;
366 break;
367 case DIB3000_ALPHA_1:
368 deb_getf("HIERARCHY_1 ");
369 ofdm->hierarchy_information = HIERARCHY_1;
370 break;
371 case DIB3000_ALPHA_2:
372 deb_getf("HIERARCHY_2 ");
373 ofdm->hierarchy_information = HIERARCHY_2;
374 break;
375 case DIB3000_ALPHA_4:
376 deb_getf("HIERARCHY_4 ");
377 ofdm->hierarchy_information = HIERARCHY_4;
378 break;
379 default:
380 err("Unexpected ALPHA value returned by TPS (%d)", tps_val);
381 break;
382 }
383 cr_val = DIB3000MC_TP_FEC_CR_LP(tps_val);
384 } else {
385 deb_getf("HRCH OFF ");
386 cr = &ofdm->code_rate_HP;
387 ofdm->code_rate_LP = FEC_NONE;
388 ofdm->hierarchy_information = HIERARCHY_NONE;
389 cr_val = DIB3000MC_TP_FEC_CR_HP(tps_val);
390 }
391
392 switch (cr_val) {
393 case DIB3000_FEC_1_2:
394 deb_getf("FEC_1_2 ");
395 *cr = FEC_1_2;
396 break;
397 case DIB3000_FEC_2_3:
398 deb_getf("FEC_2_3 ");
399 *cr = FEC_2_3;
400 break;
401 case DIB3000_FEC_3_4:
402 deb_getf("FEC_3_4 ");
403 *cr = FEC_3_4;
404 break;
405 case DIB3000_FEC_5_6:
406 deb_getf("FEC_5_6 ");
407 *cr = FEC_4_5;
408 break;
409 case DIB3000_FEC_7_8:
410 deb_getf("FEC_7_8 ");
411 *cr = FEC_7_8;
412 break;
413 default:
414 err("Unexpected FEC returned by TPS (%d)", tps_val);
415 break;
416 }
417
418 switch (DIB3000MC_TP_GUARD(tps_val)) {
419 case DIB3000_GUARD_TIME_1_32:
420 deb_getf("GUARD_INTERVAL_1_32 ");
421 ofdm->guard_interval = GUARD_INTERVAL_1_32;
422 break;
423 case DIB3000_GUARD_TIME_1_16:
424 deb_getf("GUARD_INTERVAL_1_16 ");
425 ofdm->guard_interval = GUARD_INTERVAL_1_16;
426 break;
427 case DIB3000_GUARD_TIME_1_8:
428 deb_getf("GUARD_INTERVAL_1_8 ");
429 ofdm->guard_interval = GUARD_INTERVAL_1_8;
430 break;
431 case DIB3000_GUARD_TIME_1_4:
432 deb_getf("GUARD_INTERVAL_1_4 ");
433 ofdm->guard_interval = GUARD_INTERVAL_1_4;
434 break;
435 default:
436 err("Unexpected Guard Time returned by TPS (%d)", tps_val);
437 break;
438 }
439
440 switch (DIB3000MC_TP_FFT(tps_val)) {
441 case DIB3000_TRANSMISSION_MODE_2K:
442 deb_getf("TRANSMISSION_MODE_2K ");
443 ofdm->transmission_mode = TRANSMISSION_MODE_2K;
444 break;
445 case DIB3000_TRANSMISSION_MODE_8K:
446 deb_getf("TRANSMISSION_MODE_8K ");
447 ofdm->transmission_mode = TRANSMISSION_MODE_8K;
448 break;
449 default:
450 err("unexpected transmission mode return by TPS (%d)", tps_val);
451 break;
452 }
453 deb_getf("\n");
454
455 return 0;
456}
457
458static int dib3000mc_set_frontend(struct dvb_frontend* fe,
459 struct dvb_frontend_parameters *fep, int tuner)
460{
461 struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
462 struct dvb_ofdm_parameters *ofdm = &fep->u.ofdm;
463 int search_state,auto_val;
464 u16 val;
465
466 if (tuner) { /* initial call from dvb */
467 dib3000mc_tuner_pass_ctrl(fe,1,state->config.pll_addr(fe));
468 state->config.pll_set(fe,fep,NULL);
469 dib3000mc_tuner_pass_ctrl(fe,0,state->config.pll_addr(fe));
470
471 state->last_tuned_freq = fep->frequency;
472 // if (!scanboost) {
473 dib3000mc_set_timing(state,0,ofdm->transmission_mode,ofdm->bandwidth);
474 dib3000mc_init_auto_scan(state, ofdm->bandwidth, 0);
475 state->last_tuned_bw = ofdm->bandwidth;
476
477 wr_foreach(dib3000mc_reg_agc_bandwidth,dib3000mc_agc_bandwidth);
478 wr(DIB3000MC_REG_RESTART,DIB3000MC_RESTART_AGC);
479 wr(DIB3000MC_REG_RESTART,DIB3000MC_RESTART_OFF);
480
481 /* Default cfg isi offset adp */
482 wr_foreach(dib3000mc_reg_offset,dib3000mc_offset[0]);
483
484 wr(DIB3000MC_REG_ISI,DIB3000MC_ISI_DEFAULT | DIB3000MC_ISI_INHIBIT);
485 dib3000mc_set_adp_cfg(state,ofdm->constellation);
486 wr(DIB3000MC_REG_UNK_133,DIB3000MC_UNK_133);
487
488 wr_foreach(dib3000mc_reg_bandwidth_general,dib3000mc_bandwidth_general);
489 /* power smoothing */
490 if (ofdm->bandwidth != BANDWIDTH_8_MHZ) {
491 wr_foreach(dib3000mc_reg_bw,dib3000mc_bw[0]);
492 } else {
493 wr_foreach(dib3000mc_reg_bw,dib3000mc_bw[3]);
494 }
495 auto_val = 0;
496 dib3000mc_set_general_cfg(state,fep,&auto_val);
497 dib3000mc_set_impulse_noise(state,0,ofdm->constellation,ofdm->bandwidth);
498
499 val = rd(DIB3000MC_REG_DEMOD_PARM);
500 wr(DIB3000MC_REG_DEMOD_PARM,val|DIB3000MC_DEMOD_RST_DEMOD_ON);
501 wr(DIB3000MC_REG_DEMOD_PARM,val);
502 // }
503 msleep(70);
504
505 /* something has to be auto searched */
506 if (auto_val) {
507 int as_count=0;
508
509 deb_setf("autosearch enabled.\n");
510
511 val = rd(DIB3000MC_REG_DEMOD_PARM);
512 wr(DIB3000MC_REG_DEMOD_PARM,val | DIB3000MC_DEMOD_RST_AUTO_SRCH_ON);
513 wr(DIB3000MC_REG_DEMOD_PARM,val);
514
515 while ((search_state = dib3000_search_status(
516 rd(DIB3000MC_REG_AS_IRQ),1)) < 0 && as_count++ < 100)
517 msleep(10);
518
519 deb_info("search_state after autosearch %d after %d checks\n",search_state,as_count);
520
521 if (search_state == 1) {
522 struct dvb_frontend_parameters feps;
523 if (dib3000mc_get_frontend(fe, &feps) == 0) {
524 deb_setf("reading tuning data from frontend succeeded.\n");
525 return dib3000mc_set_frontend(fe, &feps, 0);
526 }
527 }
528 } else {
529 dib3000mc_set_impulse_noise(state,0,ofdm->transmission_mode,ofdm->bandwidth);
530 wr(DIB3000MC_REG_ISI,DIB3000MC_ISI_DEFAULT|DIB3000MC_ISI_ACTIVATE);
531 dib3000mc_set_adp_cfg(state,ofdm->constellation);
532
533 /* set_offset_cfg */
534 wr_foreach(dib3000mc_reg_offset,
535 dib3000mc_offset[(ofdm->transmission_mode == TRANSMISSION_MODE_8K)+1]);
536 }
537 } else { /* second call, after autosearch (fka: set_WithKnownParams) */
538// dib3000mc_set_timing(state,1,ofdm->transmission_mode,ofdm->bandwidth);
539
540 auto_val = 0;
541 dib3000mc_set_general_cfg(state,fep,&auto_val);
542 if (auto_val)
543 deb_info("auto_val is true, even though an auto search was already performed.\n");
544
545 dib3000mc_set_impulse_noise(state,0,ofdm->constellation,ofdm->bandwidth);
546
547 val = rd(DIB3000MC_REG_DEMOD_PARM);
548 wr(DIB3000MC_REG_DEMOD_PARM,val | DIB3000MC_DEMOD_RST_AUTO_SRCH_ON);
549 wr(DIB3000MC_REG_DEMOD_PARM,val);
550
551 msleep(30);
552
553 wr(DIB3000MC_REG_ISI,DIB3000MC_ISI_DEFAULT|DIB3000MC_ISI_ACTIVATE);
554 dib3000mc_set_adp_cfg(state,ofdm->constellation);
555 wr_foreach(dib3000mc_reg_offset,
556 dib3000mc_offset[(ofdm->transmission_mode == TRANSMISSION_MODE_8K)+1]);
557
558
559 }
560 return 0;
561}
562
563static int dib3000mc_fe_init(struct dvb_frontend* fe, int mobile_mode)
564{
565 struct dib3000_state *state;
566
567 deb_info("init start\n");
568
569 state = fe->demodulator_priv;
570 state->timing_offset = 0;
571 state->timing_offset_comp_done = 0;
572
573 wr(DIB3000MC_REG_RESTART,DIB3000MC_RESTART_CONFIG);
574 wr(DIB3000MC_REG_RESTART,DIB3000MC_RESTART_OFF);
575 wr(DIB3000MC_REG_CLK_CFG_1,DIB3000MC_CLK_CFG_1_POWER_UP);
576 wr(DIB3000MC_REG_CLK_CFG_2,DIB3000MC_CLK_CFG_2_PUP_MOBILE);
577 wr(DIB3000MC_REG_CLK_CFG_3,DIB3000MC_CLK_CFG_3_POWER_UP);
578 wr(DIB3000MC_REG_CLK_CFG_7,DIB3000MC_CLK_CFG_7_INIT);
579
580 wr(DIB3000MC_REG_RST_UNC,DIB3000MC_RST_UNC_OFF);
581 wr(DIB3000MC_REG_UNK_19,DIB3000MC_UNK_19);
582
583 wr(33,5);
584 wr(36,81);
585 wr(DIB3000MC_REG_UNK_88,DIB3000MC_UNK_88);
586
587 wr(DIB3000MC_REG_UNK_99,DIB3000MC_UNK_99);
588 wr(DIB3000MC_REG_UNK_111,DIB3000MC_UNK_111_PH_N_MODE_0); /* phase noise algo off */
589
590 /* mobile mode - portable reception */
591 wr_foreach(dib3000mc_reg_mobile_mode,dib3000mc_mobile_mode[1]);
592
593/* TUNER_PANASONIC_ENV57H12D5: */
594 wr_foreach(dib3000mc_reg_agc_bandwidth,dib3000mc_agc_bandwidth);
595 wr_foreach(dib3000mc_reg_agc_bandwidth_general,dib3000mc_agc_bandwidth_general);
596 wr_foreach(dib3000mc_reg_agc,dib3000mc_agc_tuner[1]);
597
598 wr(DIB3000MC_REG_UNK_110,DIB3000MC_UNK_110);
599 wr(26,0x6680);
600 wr(DIB3000MC_REG_UNK_1,DIB3000MC_UNK_1);
601 wr(DIB3000MC_REG_UNK_2,DIB3000MC_UNK_2);
602 wr(DIB3000MC_REG_UNK_3,DIB3000MC_UNK_3);
603 wr(DIB3000MC_REG_SEQ_TPS,DIB3000MC_SEQ_TPS_DEFAULT);
604
605 wr_foreach(dib3000mc_reg_bandwidth,dib3000mc_bandwidth_8mhz);
606 wr_foreach(dib3000mc_reg_bandwidth_general,dib3000mc_bandwidth_general);
607
608 wr(DIB3000MC_REG_UNK_4,DIB3000MC_UNK_4);
609
610 wr(DIB3000MC_REG_SET_DDS_FREQ_MSB,DIB3000MC_DDS_FREQ_MSB_INV_OFF);
611 wr(DIB3000MC_REG_SET_DDS_FREQ_LSB,DIB3000MC_DDS_FREQ_LSB);
612
613 dib3000mc_set_timing(state,0,TRANSMISSION_MODE_8K,BANDWIDTH_8_MHZ);
614// wr_foreach(dib3000mc_reg_timing_freq,dib3000mc_timing_freq[3]);
615
616 wr(DIB3000MC_REG_UNK_120,DIB3000MC_UNK_120);
617 wr(DIB3000MC_REG_UNK_134,DIB3000MC_UNK_134);
618 wr(DIB3000MC_REG_FEC_CFG,DIB3000MC_FEC_CFG);
619
620 wr(DIB3000MC_REG_DIVERSITY3,DIB3000MC_DIVERSITY3_IN_OFF);
621
622 dib3000mc_set_impulse_noise(state,0,TRANSMISSION_MODE_8K,BANDWIDTH_8_MHZ);
623
624/* output mode control, just the MPEG2_SLAVE */
625// set_or(DIB3000MC_REG_OUTMODE,DIB3000MC_OM_SLAVE);
626 wr(DIB3000MC_REG_OUTMODE,DIB3000MC_OM_SLAVE);
627 wr(DIB3000MC_REG_SMO_MODE,DIB3000MC_SMO_MODE_SLAVE);
628 wr(DIB3000MC_REG_FIFO_THRESHOLD,DIB3000MC_FIFO_THRESHOLD_SLAVE);
629 wr(DIB3000MC_REG_ELEC_OUT,DIB3000MC_ELEC_OUT_SLAVE);
630
631/* MPEG2_PARALLEL_CONTINUOUS_CLOCK
632 wr(DIB3000MC_REG_OUTMODE,
633 DIB3000MC_SET_OUTMODE(DIB3000MC_OM_PAR_CONT_CLK,
634 rd(DIB3000MC_REG_OUTMODE)));
635
636 wr(DIB3000MC_REG_SMO_MODE,
637 DIB3000MC_SMO_MODE_DEFAULT |
638 DIB3000MC_SMO_MODE_188);
639
640 wr(DIB3000MC_REG_FIFO_THRESHOLD,DIB3000MC_FIFO_THRESHOLD_DEFAULT);
641 wr(DIB3000MC_REG_ELEC_OUT,DIB3000MC_ELEC_OUT_DIV_OUT_ON);
642*/
643
644/* diversity */
645 wr(DIB3000MC_REG_DIVERSITY1,DIB3000MC_DIVERSITY1_DEFAULT);
646 wr(DIB3000MC_REG_DIVERSITY2,DIB3000MC_DIVERSITY2_DEFAULT);
647
648 set_and(DIB3000MC_REG_DIVERSITY3,DIB3000MC_DIVERSITY3_IN_OFF);
649
650 set_or(DIB3000MC_REG_CLK_CFG_7,DIB3000MC_CLK_CFG_7_DIV_IN_OFF);
651
652/* if (state->config->pll_init) {
653 dib3000mc_tuner_pass_ctrl(fe,1,state->config.pll_addr(fe));
654 state->config->pll_init(fe,NULL);
655 dib3000mc_tuner_pass_ctrl(fe,0,state->config.pll_addr(fe));
656 }*/
657 deb_info("init end\n");
658 return 0;
659}
660static int dib3000mc_read_status(struct dvb_frontend* fe, fe_status_t *stat)
661{
662 struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
663 u16 lock = rd(DIB3000MC_REG_LOCKING);
664
665 *stat = 0;
666 if (DIB3000MC_AGC_LOCK(lock))
667 *stat |= FE_HAS_SIGNAL;
668 if (DIB3000MC_CARRIER_LOCK(lock))
669 *stat |= FE_HAS_CARRIER;
670 if (DIB3000MC_TPS_LOCK(lock))
671 *stat |= FE_HAS_VITERBI;
672 if (DIB3000MC_MPEG_SYNC_LOCK(lock))
673 *stat |= (FE_HAS_SYNC | FE_HAS_LOCK);
674
675 deb_stat("actual status is %2x fifo_level: %x,244: %x, 206: %x, 207: %x, 1040: %x\n",*stat,rd(510),rd(244),rd(206),rd(207),rd(1040));
676
677 return 0;
678}
679
680static int dib3000mc_read_ber(struct dvb_frontend* fe, u32 *ber)
681{
682 struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
683 *ber = ((rd(DIB3000MC_REG_BER_MSB) << 16) | rd(DIB3000MC_REG_BER_LSB));
684 return 0;
685}
686
687static int dib3000mc_read_unc_blocks(struct dvb_frontend* fe, u32 *unc)
688{
689 struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
690
691 *unc = rd(DIB3000MC_REG_PACKET_ERROR_COUNT);
692 return 0;
693}
694
695/* see dib3000mb.c for calculation comments */
696static int dib3000mc_read_signal_strength(struct dvb_frontend* fe, u16 *strength)
697{
698 struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
699 u16 val = rd(DIB3000MC_REG_SIGNAL_NOISE_LSB);
700 *strength = (((val >> 6) & 0xff) << 8) + (val & 0x3f);
701
702 deb_stat("signal: mantisse = %d, exponent = %d\n",(*strength >> 8) & 0xff, *strength & 0xff);
703 return 0;
704}
705
706/* see dib3000mb.c for calculation comments */
707static int dib3000mc_read_snr(struct dvb_frontend* fe, u16 *snr)
708{
709 struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
710 u16 val = rd(DIB3000MC_REG_SIGNAL_NOISE_LSB),
711 val2 = rd(DIB3000MC_REG_SIGNAL_NOISE_MSB);
712 u16 sig,noise;
713
714 sig = (((val >> 6) & 0xff) << 8) + (val & 0x3f);
715 noise = (((val >> 4) & 0xff) << 8) + ((val & 0xf) << 2) + ((val2 >> 14) & 0x3);
716 if (noise == 0)
717 *snr = 0xffff;
718 else
719 *snr = (u16) sig/noise;
720
721 deb_stat("signal: mantisse = %d, exponent = %d\n",(sig >> 8) & 0xff, sig & 0xff);
722 deb_stat("noise: mantisse = %d, exponent = %d\n",(noise >> 8) & 0xff, noise & 0xff);
723 deb_stat("snr: %d\n",*snr);
724 return 0;
725}
726
727static int dib3000mc_sleep(struct dvb_frontend* fe)
728{
729 struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv;
730
731 set_or(DIB3000MC_REG_CLK_CFG_7,DIB3000MC_CLK_CFG_7_PWR_DOWN);
732 wr(DIB3000MC_REG_CLK_CFG_1,DIB3000MC_CLK_CFG_1_POWER_DOWN);
733 wr(DIB3000MC_REG_CLK_CFG_2,DIB3000MC_CLK_CFG_2_POWER_DOWN);
734 wr(DIB3000MC_REG_CLK_CFG_3,DIB3000MC_CLK_CFG_3_POWER_DOWN);
735 return 0;
736}
737
738static int dib3000mc_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
739{
740 tune->min_delay_ms = 2000;
741 tune->step_size = 166667;
742 tune->max_drift = 166667 * 2;
743
744 return 0;
745}
746
747static int dib3000mc_fe_init_nonmobile(struct dvb_frontend* fe)
748{
749 return dib3000mc_fe_init(fe, 0);
750}
751
752static int dib3000mc_set_frontend_and_tuner(struct dvb_frontend* fe, struct dvb_frontend_parameters *fep)
753{
754 return dib3000mc_set_frontend(fe, fep, 1);
755}
756
757static void dib3000mc_release(struct dvb_frontend* fe)
758{
759 struct dib3000_state *state = (struct dib3000_state *) fe->demodulator_priv;
760 kfree(state);
761}
762
763/* pid filter and transfer stuff */
764static int dib3000mc_pid_control(struct dvb_frontend *fe,int index, int pid,int onoff)
765{
766 struct dib3000_state *state = fe->demodulator_priv;
767 pid = (onoff ? pid | DIB3000_ACTIVATE_PID_FILTERING : 0);
768 wr(index+DIB3000MC_REG_FIRST_PID,pid);
769 return 0;
770}
771
772static int dib3000mc_fifo_control(struct dvb_frontend *fe, int onoff)
773{
774 struct dib3000_state *state = (struct dib3000_state*) fe->demodulator_priv;
775 u16 tmp = rd(DIB3000MC_REG_SMO_MODE);
776
777 deb_xfer("%s fifo\n",onoff ? "enabling" : "disabling");
778
779 if (onoff) {
780 deb_xfer("%d %x\n",tmp & DIB3000MC_SMO_MODE_FIFO_UNFLUSH,tmp & DIB3000MC_SMO_MODE_FIFO_UNFLUSH);
781 wr(DIB3000MC_REG_SMO_MODE,tmp & DIB3000MC_SMO_MODE_FIFO_UNFLUSH);
782 } else {
783 deb_xfer("%d %x\n",tmp | DIB3000MC_SMO_MODE_FIFO_FLUSH,tmp | DIB3000MC_SMO_MODE_FIFO_FLUSH);
784 wr(DIB3000MC_REG_SMO_MODE,tmp | DIB3000MC_SMO_MODE_FIFO_FLUSH);
785 }
786 return 0;
787}
788
789static int dib3000mc_pid_parse(struct dvb_frontend *fe, int onoff)
790{
791 struct dib3000_state *state = fe->demodulator_priv;
792 u16 tmp = rd(DIB3000MC_REG_SMO_MODE);
793
794 deb_xfer("%s pid parsing\n",onoff ? "enabling" : "disabling");
795
796 if (onoff) {
797 wr(DIB3000MC_REG_SMO_MODE,tmp | DIB3000MC_SMO_MODE_PID_PARSE);
798 } else {
799 wr(DIB3000MC_REG_SMO_MODE,tmp & DIB3000MC_SMO_MODE_NO_PID_PARSE);
800 }
801 return 0;
802}
803
804static int dib3000mc_tuner_pass_ctrl(struct dvb_frontend *fe, int onoff, u8 pll_addr)
805{
806 struct dib3000_state *state = (struct dib3000_state*) fe->demodulator_priv;
807 if (onoff) {
808 wr(DIB3000MC_REG_TUNER, DIB3000_TUNER_WRITE_ENABLE(pll_addr));
809 } else {
810 wr(DIB3000MC_REG_TUNER, DIB3000_TUNER_WRITE_DISABLE(pll_addr));
811 }
812 return 0;
813}
814
815static int dib3000mc_demod_init(struct dib3000_state *state)
816{
817 u16 default_addr = 0x0a;
818 /* first init */
819 if (state->config.demod_address != default_addr) {
820 deb_info("initializing the demod the first time. Setting demod addr to 0x%x\n",default_addr);
821 wr(DIB3000MC_REG_ELEC_OUT,DIB3000MC_ELEC_OUT_DIV_OUT_ON);
822 wr(DIB3000MC_REG_OUTMODE,DIB3000MC_OM_PAR_CONT_CLK);
823
824 wr(DIB3000MC_REG_RST_I2C_ADDR,
825 DIB3000MC_DEMOD_ADDR(default_addr) |
826 DIB3000MC_DEMOD_ADDR_ON);
827
828 state->config.demod_address = default_addr;
829
830 wr(DIB3000MC_REG_RST_I2C_ADDR,
831 DIB3000MC_DEMOD_ADDR(default_addr));
832 } else
833 deb_info("demod is already initialized. Demod addr: 0x%x\n",state->config.demod_address);
834 return 0;
835}
836
837
838static struct dvb_frontend_ops dib3000mc_ops;
839
840struct dvb_frontend* dib3000mc_attach(const struct dib3000_config* config,
841 struct i2c_adapter* i2c, struct dib_fe_xfer_ops *xfer_ops)
842{
843 struct dib3000_state* state = NULL;
844 u16 devid;
845
846 /* allocate memory for the internal state */
847 state = (struct dib3000_state*) kmalloc(sizeof(struct dib3000_state), GFP_KERNEL);
848 if (state == NULL)
849 goto error;
850 memset(state,0,sizeof(struct dib3000_state));
851
852 /* setup the state */
853 state->i2c = i2c;
854 memcpy(&state->config,config,sizeof(struct dib3000_config));
855 memcpy(&state->ops, &dib3000mc_ops, sizeof(struct dvb_frontend_ops));
856
857 /* check for the correct demod */
858 if (rd(DIB3000_REG_MANUFACTOR_ID) != DIB3000_I2C_ID_DIBCOM)
859 goto error;
860
861 devid = rd(DIB3000_REG_DEVICE_ID);
862 if (devid != DIB3000MC_DEVICE_ID && devid != DIB3000P_DEVICE_ID)
863 goto error;
864
865 switch (devid) {
866 case DIB3000MC_DEVICE_ID:
867 info("Found a DiBcom 3000M-C, interesting...");
868 break;
869 case DIB3000P_DEVICE_ID:
870 info("Found a DiBcom 3000P.");
871 break;
872 }
873
874 /* create dvb_frontend */
875 state->frontend.ops = &state->ops;
876 state->frontend.demodulator_priv = state;
877
878 /* set the xfer operations */
879 xfer_ops->pid_parse = dib3000mc_pid_parse;
880 xfer_ops->fifo_ctrl = dib3000mc_fifo_control;
881 xfer_ops->pid_ctrl = dib3000mc_pid_control;
882 xfer_ops->tuner_pass_ctrl = dib3000mc_tuner_pass_ctrl;
883
884 dib3000mc_demod_init(state);
885
886 return &state->frontend;
887
888error:
889 kfree(state);
890 return NULL;
891}
892
893static struct dvb_frontend_ops dib3000mc_ops = {
894
895 .info = {
896 .name = "DiBcom 3000P/M-C DVB-T",
897 .type = FE_OFDM,
898 .frequency_min = 44250000,
899 .frequency_max = 867250000,
900 .frequency_stepsize = 62500,
901 .caps = FE_CAN_INVERSION_AUTO |
902 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
903 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
904 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
905 FE_CAN_TRANSMISSION_MODE_AUTO |
906 FE_CAN_GUARD_INTERVAL_AUTO |
907 FE_CAN_RECOVER |
908 FE_CAN_HIERARCHY_AUTO,
909 },
910
911 .release = dib3000mc_release,
912
913 .init = dib3000mc_fe_init_nonmobile,
914 .sleep = dib3000mc_sleep,
915
916 .set_frontend = dib3000mc_set_frontend_and_tuner,
917 .get_frontend = dib3000mc_get_frontend,
918 .get_tune_settings = dib3000mc_fe_get_tune_settings,
919
920 .read_status = dib3000mc_read_status,
921 .read_ber = dib3000mc_read_ber,
922 .read_signal_strength = dib3000mc_read_signal_strength,
923 .read_snr = dib3000mc_read_snr,
924 .read_ucblocks = dib3000mc_read_unc_blocks,
925};
926
927MODULE_AUTHOR(DRIVER_AUTHOR);
928MODULE_DESCRIPTION(DRIVER_DESC);
929MODULE_LICENSE("GPL");
930
931EXPORT_SYMBOL(dib3000mc_attach);
diff --git a/drivers/media/dvb/frontends/dib3000mc_priv.h b/drivers/media/dvb/frontends/dib3000mc_priv.h
new file mode 100644
index 000000000000..2930aac7591b
--- /dev/null
+++ b/drivers/media/dvb/frontends/dib3000mc_priv.h
@@ -0,0 +1,428 @@
1/*
2 * dib3000mc_priv.h
3 *
4 * Copyright (C) 2004 Patrick Boettcher (patrick.boettcher@desy.de)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation, version 2.
9 *
10 * for more information see dib3000mc.c .
11 */
12
13#ifndef __DIB3000MC_PRIV_H__
14#define __DIB3000MC_PRIV_H__
15
16/*
17 * Demodulator parameters
18 * reg: 0 1 1 1 11 11 111
19 * | | | | | |
20 * | | | | | +-- alpha (000=0, 001=1, 010=2, 100=4)
21 * | | | | +----- constellation (00=QPSK, 01=16QAM, 10=64QAM)
22 * | | | +-------- guard (00=1/32, 01=1/16, 10=1/8, 11=1/4)
23 * | | +----------- transmission mode (0=2k, 1=8k)
24 * | |
25 * | +-------------- restart autosearch for parameters
26 * +---------------- restart the demodulator
27 * reg: 181 1 111 1
28 * | | |
29 * | | +- FEC applies for HP or LP (0=LP, 1=HP)
30 * | +---- FEC rate (001=1/2, 010=2/3, 011=3/4, 101=5/6, 111=7/8)
31 * +------- hierarchy on (0=no, 1=yes)
32 */
33
34/* demodulator tuning parameter and restart options */
35#define DIB3000MC_REG_DEMOD_PARM ( 0)
36#define DIB3000MC_DEMOD_PARM(a,c,g,t) ( \
37 (0x7 & a) | \
38 ((0x3 & c) << 3) | \
39 ((0x3 & g) << 5) | \
40 ((0x1 & t) << 7) )
41#define DIB3000MC_DEMOD_RST_AUTO_SRCH_ON (1 << 8)
42#define DIB3000MC_DEMOD_RST_AUTO_SRCH_OFF (0 << 8)
43#define DIB3000MC_DEMOD_RST_DEMOD_ON (1 << 9)
44#define DIB3000MC_DEMOD_RST_DEMOD_OFF (0 << 9)
45
46/* register for hierarchy parameters */
47#define DIB3000MC_REG_HRCH_PARM ( 181)
48#define DIB3000MC_HRCH_PARM(s,f,h) ( \
49 (0x1 & s) | \
50 ((0x7 & f) << 1) | \
51 ((0x1 & h) << 4) )
52
53/* timeout ??? */
54#define DIB3000MC_REG_UNK_1 ( 1)
55#define DIB3000MC_UNK_1 ( 0x04)
56
57/* timeout ??? */
58#define DIB3000MC_REG_UNK_2 ( 2)
59#define DIB3000MC_UNK_2 ( 0x04)
60
61/* timeout ??? */
62#define DIB3000MC_REG_UNK_3 ( 3)
63#define DIB3000MC_UNK_3 (0x1000)
64
65#define DIB3000MC_REG_UNK_4 ( 4)
66#define DIB3000MC_UNK_4 (0x0814)
67
68/* timeout ??? */
69#define DIB3000MC_REG_SEQ_TPS ( 5)
70#define DIB3000MC_SEQ_TPS_DEFAULT ( 1)
71#define DIB3000MC_SEQ_TPS(s,t) ( \
72 ((s & 0x0f) << 4) | \
73 ((t & 0x01) << 8) )
74#define DIB3000MC_IS_TPS(v) ((v << 8) & 0x1)
75#define DIB3000MC_IS_AS(v) ((v >> 4) & 0xf)
76
77/* parameters for the bandwidth */
78#define DIB3000MC_REG_BW_TIMOUT_MSB ( 6)
79#define DIB3000MC_REG_BW_TIMOUT_LSB ( 7)
80
81static u16 dib3000mc_reg_bandwidth[] = { 6,7,8,9,10,11,16,17 };
82
83/*static u16 dib3000mc_bandwidth_5mhz[] =
84 { 0x28, 0x9380, 0x87, 0x4100, 0x2a4, 0x4500, 0x1, 0xb0d0 };*/
85
86static u16 dib3000mc_bandwidth_6mhz[] =
87 { 0x21, 0xd040, 0x70, 0xb62b, 0x233, 0x8ed5, 0x1, 0xb0d0 };
88
89static u16 dib3000mc_bandwidth_7mhz[] =
90 { 0x1c, 0xfba5, 0x60, 0x9c25, 0x1e3, 0x0cb7, 0x1, 0xb0d0 };
91
92static u16 dib3000mc_bandwidth_8mhz[] =
93 { 0x19, 0x5c30, 0x54, 0x88a0, 0x1a6, 0xab20, 0x1, 0xb0d0 };
94
95static u16 dib3000mc_reg_bandwidth_general[] = { 12,13,14,15 };
96static u16 dib3000mc_bandwidth_general[] = { 0x0000, 0x03e8, 0x0000, 0x03f2 };
97
98/* lock mask */
99#define DIB3000MC_REG_LOCK_MASK ( 15)
100#define DIB3000MC_ACTIVATE_LOCK_MASK (0x0800)
101
102/* reset the uncorrected packet count (??? do it 5 times) */
103#define DIB3000MC_REG_RST_UNC ( 18)
104#define DIB3000MC_RST_UNC_ON ( 1)
105#define DIB3000MC_RST_UNC_OFF ( 0)
106
107#define DIB3000MC_REG_UNK_19 ( 19)
108#define DIB3000MC_UNK_19 ( 0)
109
110/* DDS frequency value (IF position) and inversion bit */
111#define DIB3000MC_REG_INVERSION ( 21)
112#define DIB3000MC_REG_SET_DDS_FREQ_MSB ( 21)
113#define DIB3000MC_DDS_FREQ_MSB_INV_OFF (0x0164)
114#define DIB3000MC_DDS_FREQ_MSB_INV_ON (0x0364)
115
116#define DIB3000MC_REG_SET_DDS_FREQ_LSB ( 22)
117#define DIB3000MC_DDS_FREQ_LSB (0x463d)
118
119/* timing frequencies setting */
120#define DIB3000MC_REG_TIMING_FREQ_MSB ( 23)
121#define DIB3000MC_REG_TIMING_FREQ_LSB ( 24)
122#define DIB3000MC_CLOCK_REF (0x151fd1)
123
124//static u16 dib3000mc_reg_timing_freq[] = { 23,24 };
125
126//static u16 dib3000mc_timing_freq[][2] = {
127// { 0x69, 0x9f18 }, /* 5 MHz */
128// { 0x7e ,0xbee9 }, /* 6 MHz */
129// { 0x93 ,0xdebb }, /* 7 MHz */
130// { 0xa8 ,0xfe8c }, /* 8 MHz */
131//};
132
133/* timeout ??? */
134static u16 dib3000mc_reg_offset[] = { 26,33 };
135
136static u16 dib3000mc_offset[][2] = {
137 { 26240, 5 }, /* default */
138 { 30336, 6 }, /* 8K */
139 { 38528, 8 }, /* 2K */
140};
141
142#define DIB3000MC_REG_ISI ( 29)
143#define DIB3000MC_ISI_DEFAULT (0x1073)
144#define DIB3000MC_ISI_ACTIVATE (0x0000)
145#define DIB3000MC_ISI_INHIBIT (0x0200)
146
147/* impulse noise control */
148static u16 dib3000mc_reg_imp_noise_ctl[] = { 34,35 };
149
150static u16 dib3000mc_imp_noise_ctl[][2] = {
151 { 0x1294, 0x1ff8 }, /* mode 0 */
152 { 0x1294, 0x1ff8 }, /* mode 1 */
153 { 0x1294, 0x1ff8 }, /* mode 2 */
154 { 0x1294, 0x1ff8 }, /* mode 3 */
155 { 0x1294, 0x1ff8 }, /* mode 4 */
156};
157
158/* AGC registers */
159static u16 dib3000mc_reg_agc[] = {
160 36,37,38,39,42,43,44,45,46,47,48,49
161};
162
163static u16 dib3000mc_agc_tuner[][12] = {
164 { 0x0051, 0x301d, 0x0000, 0x1cc7, 0xcf5c, 0x6666,
165 0xbae1, 0xa148, 0x3b5e, 0x3c1c, 0x001a, 0x2019
166 }, /* TUNER_PANASONIC_ENV77H04D5, */
167
168 { 0x0051, 0x301d, 0x0000, 0x1cc7, 0xdc29, 0x570a,
169 0xbae1, 0x8ccd, 0x3b6d, 0x551d, 0x000a, 0x951e
170 }, /* TUNER_PANASONIC_ENV57H13D5, TUNER_PANASONIC_ENV57H12D5 */
171
172 { 0x0051, 0x301d, 0x0000, 0x1cc7, 0xffff, 0xffff,
173 0xffff, 0x0000, 0xfdfd, 0x4040, 0x00fd, 0x4040
174 }, /* TUNER_SAMSUNG_DTOS333IH102, TUNER_RFAGCIN_UNKNOWN */
175
176 { 0x0196, 0x301d, 0x0000, 0x1cc7, 0xbd71, 0x5c29,
177 0xb5c3, 0x6148, 0x6569, 0x5127, 0x0033, 0x3537
178 }, /* TUNER_PROVIDER_X */
179 /* TODO TUNER_PANASONIC_ENV57H10D8, TUNER_PANASONIC_ENV57H11D8 */
180};
181
182/* AGC loop bandwidth */
183static u16 dib3000mc_reg_agc_bandwidth[] = { 40,41 };
184static u16 dib3000mc_agc_bandwidth[] = { 0x119,0x330 };
185
186static u16 dib3000mc_reg_agc_bandwidth_general[] = { 50,51,52,53,54 };
187static u16 dib3000mc_agc_bandwidth_general[] =
188 { 0x8000, 0x91ca, 0x01ba, 0x0087, 0x0087 };
189
190#define DIB3000MC_REG_IMP_NOISE_55 ( 55)
191#define DIB3000MC_IMP_NEW_ALGO(w) (w | (1<<10))
192
193/* Impulse noise params */
194static u16 dib3000mc_reg_impulse_noise[] = { 55,56,57 };
195static u16 dib3000mc_impluse_noise[][3] = {
196 { 0x489, 0x89, 0x72 }, /* 5 MHz */
197 { 0x4a5, 0xa5, 0x89 }, /* 6 MHz */
198 { 0x4c0, 0xc0, 0xa0 }, /* 7 MHz */
199 { 0x4db, 0xdb, 0xb7 }, /* 8 Mhz */
200};
201
202static u16 dib3000mc_reg_fft[] = {
203 58,59,60,61,62,63,64,65,66,67,68,69,
204 70,71,72,73,74,75,76,77,78,79,80,81,
205 82,83,84,85,86
206};
207
208static u16 dib3000mc_fft_modes[][29] = {
209 { 0x38, 0x6d9, 0x3f28, 0x7a7, 0x3a74, 0x196, 0x32a, 0x48c,
210 0x3ffe, 0x7f3, 0x2d94, 0x76, 0x53d,
211 0x3ff8, 0x7e3, 0x3320, 0x76, 0x5b3,
212 0x3feb, 0x7d2, 0x365e, 0x76, 0x48c,
213 0x3ffe, 0x5b3, 0x3feb, 0x76, 0x0, 0xd
214 }, /* fft mode 0 */
215 { 0x3b, 0x6d9, 0x3f28, 0x7a7, 0x3a74, 0x196, 0x32a, 0x48c,
216 0x3ffe, 0x7f3, 0x2d94, 0x76, 0x53d,
217 0x3ff8, 0x7e3, 0x3320, 0x76, 0x5b3,
218 0x3feb, 0x7d2, 0x365e, 0x76, 0x48c,
219 0x3ffe, 0x5b3, 0x3feb, 0x0, 0x8200, 0xd
220 }, /* fft mode 1 */
221};
222
223#define DIB3000MC_REG_UNK_88 ( 88)
224#define DIB3000MC_UNK_88 (0x0410)
225
226static u16 dib3000mc_reg_bw[] = { 93,94,95,96,97,98 };
227static u16 dib3000mc_bw[][6] = {
228 { 0,0,0,0,0,0 }, /* 5 MHz */
229 { 0,0,0,0,0,0 }, /* 6 MHz */
230 { 0,0,0,0,0,0 }, /* 7 MHz */
231 { 0x20, 0x21, 0x20, 0x23, 0x20, 0x27 }, /* 8 MHz */
232};
233
234
235/* phase noise control */
236#define DIB3000MC_REG_UNK_99 ( 99)
237#define DIB3000MC_UNK_99 (0x0220)
238
239#define DIB3000MC_REG_SCAN_BOOST ( 100)
240#define DIB3000MC_SCAN_BOOST_ON ((11 << 6) + 6)
241#define DIB3000MC_SCAN_BOOST_OFF ((16 << 6) + 9)
242
243/* timeout ??? */
244#define DIB3000MC_REG_UNK_110 ( 110)
245#define DIB3000MC_UNK_110 ( 3277)
246
247#define DIB3000MC_REG_UNK_111 ( 111)
248#define DIB3000MC_UNK_111_PH_N_MODE_0 ( 0)
249#define DIB3000MC_UNK_111_PH_N_MODE_1 (1 << 1)
250
251/* superious rm config */
252#define DIB3000MC_REG_UNK_120 ( 120)
253#define DIB3000MC_UNK_120 ( 8207)
254
255#define DIB3000MC_REG_UNK_133 ( 133)
256#define DIB3000MC_UNK_133 ( 15564)
257
258#define DIB3000MC_REG_UNK_134 ( 134)
259#define DIB3000MC_UNK_134 ( 0)
260
261/* adapter config for constellation */
262static u16 dib3000mc_reg_adp_cfg[] = { 129, 130, 131, 132 };
263
264static u16 dib3000mc_adp_cfg[][4] = {
265 { 0x99a, 0x7fae, 0x333, 0x7ff0 }, /* QPSK */
266 { 0x23d, 0x7fdf, 0x0a4, 0x7ff0 }, /* 16-QAM */
267 { 0x148, 0x7ff0, 0x0a4, 0x7ff8 }, /* 64-QAM */
268};
269
270static u16 dib3000mc_reg_mobile_mode[] = { 139, 140, 141, 175, 1032 };
271
272static u16 dib3000mc_mobile_mode[][5] = {
273 { 0x01, 0x0, 0x0, 0x00, 0x12c }, /* fixed */
274 { 0x01, 0x0, 0x0, 0x00, 0x12c }, /* portable */
275 { 0x00, 0x0, 0x0, 0x02, 0x000 }, /* mobile */
276 { 0x00, 0x0, 0x0, 0x02, 0x000 }, /* auto */
277};
278
279#define DIB3000MC_REG_DIVERSITY1 ( 177)
280#define DIB3000MC_DIVERSITY1_DEFAULT ( 1)
281
282#define DIB3000MC_REG_DIVERSITY2 ( 178)
283#define DIB3000MC_DIVERSITY2_DEFAULT ( 1)
284
285#define DIB3000MC_REG_DIVERSITY3 ( 180)
286#define DIB3000MC_DIVERSITY3_IN_OFF (0xfff0)
287#define DIB3000MC_DIVERSITY3_IN_ON (0xfff6)
288
289#define DIB3000MC_REG_FEC_CFG ( 195)
290#define DIB3000MC_FEC_CFG ( 0x10)
291
292/*
293 * reg 206, output mode
294 * 1111 1111
295 * |||| ||||
296 * |||| |||+- unk
297 * |||| ||+-- unk
298 * |||| |+--- unk (on by default)
299 * |||| +---- fifo_ctrl (1 = inhibit (flushed), 0 = active (unflushed))
300 * |||+------ pid_parse (1 = enabled, 0 = disabled)
301 * ||+------- outp_188 (1 = TS packet size 188, 0 = packet size 204)
302 * |+-------- unk
303 * +--------- unk
304 */
305
306#define DIB3000MC_REG_SMO_MODE ( 206)
307#define DIB3000MC_SMO_MODE_DEFAULT (1 << 2)
308#define DIB3000MC_SMO_MODE_FIFO_FLUSH (1 << 3)
309#define DIB3000MC_SMO_MODE_FIFO_UNFLUSH (0xfff7)
310#define DIB3000MC_SMO_MODE_PID_PARSE (1 << 4)
311#define DIB3000MC_SMO_MODE_NO_PID_PARSE (0xffef)
312#define DIB3000MC_SMO_MODE_188 (1 << 5)
313#define DIB3000MC_SMO_MODE_SLAVE (DIB3000MC_SMO_MODE_DEFAULT | \
314 DIB3000MC_SMO_MODE_188 | DIB3000MC_SMO_MODE_PID_PARSE | (1<<1))
315
316#define DIB3000MC_REG_FIFO_THRESHOLD ( 207)
317#define DIB3000MC_FIFO_THRESHOLD_DEFAULT ( 1792)
318#define DIB3000MC_FIFO_THRESHOLD_SLAVE ( 512)
319/*
320 * pidfilter
321 * it is not a hardware pidfilter but a filter which drops all pids
322 * except the ones set. When connected to USB1.1 bandwidth this is important.
323 * DiB3000P/M-C can filter up to 32 PIDs
324 */
325#define DIB3000MC_REG_FIRST_PID ( 212)
326#define DIB3000MC_NUM_PIDS ( 32)
327
328#define DIB3000MC_REG_OUTMODE ( 244)
329#define DIB3000MC_OM_PARALLEL_GATED_CLK ( 0)
330#define DIB3000MC_OM_PAR_CONT_CLK (1 << 11)
331#define DIB3000MC_OM_SERIAL (2 << 11)
332#define DIB3000MC_OM_DIVOUT_ON (4 << 11)
333#define DIB3000MC_OM_SLAVE (DIB3000MC_OM_DIVOUT_ON | DIB3000MC_OM_PAR_CONT_CLK)
334
335#define DIB3000MC_REG_RF_POWER ( 392)
336
337#define DIB3000MC_REG_FFT_POSITION ( 407)
338
339#define DIB3000MC_REG_DDS_FREQ_MSB ( 414)
340#define DIB3000MC_REG_DDS_FREQ_LSB ( 415)
341
342#define DIB3000MC_REG_TIMING_OFFS_MSB ( 416)
343#define DIB3000MC_REG_TIMING_OFFS_LSB ( 417)
344
345#define DIB3000MC_REG_TUNING_PARM ( 458)
346#define DIB3000MC_TP_QAM(v) ((v >> 13) & 0x03)
347#define DIB3000MC_TP_HRCH(v) ((v >> 12) & 0x01)
348#define DIB3000MC_TP_ALPHA(v) ((v >> 9) & 0x07)
349#define DIB3000MC_TP_FFT(v) ((v >> 8) & 0x01)
350#define DIB3000MC_TP_FEC_CR_HP(v) ((v >> 5) & 0x07)
351#define DIB3000MC_TP_FEC_CR_LP(v) ((v >> 2) & 0x07)
352#define DIB3000MC_TP_GUARD(v) (v & 0x03)
353
354#define DIB3000MC_REG_SIGNAL_NOISE_MSB ( 483)
355#define DIB3000MC_REG_SIGNAL_NOISE_LSB ( 484)
356
357#define DIB3000MC_REG_MER ( 485)
358
359#define DIB3000MC_REG_BER_MSB ( 500)
360#define DIB3000MC_REG_BER_LSB ( 501)
361
362#define DIB3000MC_REG_PACKET_ERRORS ( 503)
363
364#define DIB3000MC_REG_PACKET_ERROR_COUNT ( 506)
365
366#define DIB3000MC_REG_LOCK_507 ( 507)
367#define DIB3000MC_LOCK_507 (0x0002) // ? name correct ?
368
369#define DIB3000MC_REG_LOCKING ( 509)
370#define DIB3000MC_AGC_LOCK(v) (v & 0x8000)
371#define DIB3000MC_CARRIER_LOCK(v) (v & 0x2000)
372#define DIB3000MC_MPEG_SYNC_LOCK(v) (v & 0x0080)
373#define DIB3000MC_MPEG_DATA_LOCK(v) (v & 0x0040)
374#define DIB3000MC_TPS_LOCK(v) (v & 0x0004)
375
376#define DIB3000MC_REG_AS_IRQ ( 511)
377#define DIB3000MC_AS_IRQ_SUCCESS (1 << 1)
378#define DIB3000MC_AS_IRQ_FAIL ( 1)
379
380#define DIB3000MC_REG_TUNER ( 769)
381
382#define DIB3000MC_REG_RST_I2C_ADDR ( 1024)
383#define DIB3000MC_DEMOD_ADDR_ON ( 1)
384#define DIB3000MC_DEMOD_ADDR(a) ((a << 4) & 0x03F0)
385
386#define DIB3000MC_REG_RESTART ( 1027)
387#define DIB3000MC_RESTART_OFF (0x0000)
388#define DIB3000MC_RESTART_AGC (0x0800)
389#define DIB3000MC_RESTART_CONFIG (0x8000)
390
391#define DIB3000MC_REG_RESTART_VIT ( 1028)
392#define DIB3000MC_RESTART_VIT_OFF ( 0)
393#define DIB3000MC_RESTART_VIT_ON ( 1)
394
395#define DIB3000MC_REG_CLK_CFG_1 ( 1031)
396#define DIB3000MC_CLK_CFG_1_POWER_UP ( 0)
397#define DIB3000MC_CLK_CFG_1_POWER_DOWN (0xffff)
398
399#define DIB3000MC_REG_CLK_CFG_2 ( 1032)
400#define DIB3000MC_CLK_CFG_2_PUP_FIXED (0x012c)
401#define DIB3000MC_CLK_CFG_2_PUP_PORT (0x0104)
402#define DIB3000MC_CLK_CFG_2_PUP_MOBILE (0x0000)
403#define DIB3000MC_CLK_CFG_2_POWER_DOWN (0xffff)
404
405#define DIB3000MC_REG_CLK_CFG_3 ( 1033)
406#define DIB3000MC_CLK_CFG_3_POWER_UP ( 0)
407#define DIB3000MC_CLK_CFG_3_POWER_DOWN (0xfff5)
408
409#define DIB3000MC_REG_CLK_CFG_7 ( 1037)
410#define DIB3000MC_CLK_CFG_7_INIT ( 12592)
411#define DIB3000MC_CLK_CFG_7_POWER_UP (~0x0003)
412#define DIB3000MC_CLK_CFG_7_PWR_DOWN (0x0003)
413#define DIB3000MC_CLK_CFG_7_DIV_IN_OFF (1 << 8)
414
415/* was commented out ??? */
416#define DIB3000MC_REG_CLK_CFG_8 ( 1038)
417#define DIB3000MC_CLK_CFG_8_POWER_UP (0x160c)
418
419#define DIB3000MC_REG_CLK_CFG_9 ( 1039)
420#define DIB3000MC_CLK_CFG_9_POWER_UP ( 0)
421
422/* also clock ??? */
423#define DIB3000MC_REG_ELEC_OUT ( 1040)
424#define DIB3000MC_ELEC_OUT_HIGH_Z ( 0)
425#define DIB3000MC_ELEC_OUT_DIV_OUT_ON ( 1)
426#define DIB3000MC_ELEC_OUT_SLAVE ( 3)
427
428#endif
diff --git a/drivers/media/dvb/frontends/dvb-pll.c b/drivers/media/dvb/frontends/dvb-pll.c
new file mode 100644
index 000000000000..2a3c2ce7b2aa
--- /dev/null
+++ b/drivers/media/dvb/frontends/dvb-pll.c
@@ -0,0 +1,168 @@
1/*
2 * $Id: dvb-pll.c,v 1.7 2005/02/10 11:52:02 kraxel Exp $
3 *
4 * descriptions + helper functions for simple dvb plls.
5 *
6 * (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#include <linux/module.h>
24#include <linux/dvb/frontend.h>
25#include <asm/types.h>
26
27#include "dvb-pll.h"
28
29/* ----------------------------------------------------------- */
30/* descriptions */
31
32struct dvb_pll_desc dvb_pll_thomson_dtt7579 = {
33 .name = "Thomson dtt7579",
34 .min = 177000000,
35 .max = 858000000,
36 .count = 5,
37 .entries = {
38 { 0, 36166667, 166666, 0xb4, 0x03 }, /* go sleep */
39 { 443250000, 36166667, 166666, 0xb4, 0x02 },
40 { 542000000, 36166667, 166666, 0xb4, 0x08 },
41 { 771000000, 36166667, 166666, 0xbc, 0x08 },
42 { 999999999, 36166667, 166666, 0xf4, 0x08 },
43 },
44};
45EXPORT_SYMBOL(dvb_pll_thomson_dtt7579);
46
47struct dvb_pll_desc dvb_pll_thomson_dtt7610 = {
48 .name = "Thomson dtt7610",
49 .min = 44000000,
50 .max = 958000000,
51 .count = 3,
52 .entries = {
53 { 157250000, 44000000, 62500, 0x8e, 0x39 },
54 { 454000000, 44000000, 62500, 0x8e, 0x3a },
55 { 999999999, 44000000, 62500, 0x8e, 0x3c },
56 },
57};
58EXPORT_SYMBOL(dvb_pll_thomson_dtt7610);
59
60static void thomson_dtt759x_bw(u8 *buf, int bandwidth)
61{
62 if (BANDWIDTH_7_MHZ == bandwidth)
63 buf[3] |= 0x10;
64}
65
66struct dvb_pll_desc dvb_pll_thomson_dtt759x = {
67 .name = "Thomson dtt759x",
68 .min = 177000000,
69 .max = 896000000,
70 .setbw = thomson_dtt759x_bw,
71 .count = 6,
72 .entries = {
73 { 0, 36166667, 166666, 0x84, 0x03 },
74 { 264000000, 36166667, 166666, 0xb4, 0x02 },
75 { 470000000, 36166667, 166666, 0xbc, 0x02 },
76 { 735000000, 36166667, 166666, 0xbc, 0x08 },
77 { 835000000, 36166667, 166666, 0xf4, 0x08 },
78 { 999999999, 36166667, 166666, 0xfc, 0x08 },
79 },
80};
81EXPORT_SYMBOL(dvb_pll_thomson_dtt759x);
82
83struct dvb_pll_desc dvb_pll_lg_z201 = {
84 .name = "LG z201",
85 .min = 174000000,
86 .max = 862000000,
87 .count = 5,
88 .entries = {
89 { 0, 36166667, 166666, 0xbc, 0x03 },
90 { 443250000, 36166667, 166666, 0xbc, 0x01 },
91 { 542000000, 36166667, 166666, 0xbc, 0x02 },
92 { 830000000, 36166667, 166666, 0xf4, 0x02 },
93 { 999999999, 36166667, 166666, 0xfc, 0x02 },
94 },
95};
96EXPORT_SYMBOL(dvb_pll_lg_z201);
97
98struct dvb_pll_desc dvb_pll_unknown_1 = {
99 .name = "unknown 1", /* used by dntv live dvb-t */
100 .min = 174000000,
101 .max = 862000000,
102 .count = 9,
103 .entries = {
104 { 150000000, 36166667, 166666, 0xb4, 0x01 },
105 { 173000000, 36166667, 166666, 0xbc, 0x01 },
106 { 250000000, 36166667, 166666, 0xb4, 0x02 },
107 { 400000000, 36166667, 166666, 0xbc, 0x02 },
108 { 420000000, 36166667, 166666, 0xf4, 0x02 },
109 { 470000000, 36166667, 166666, 0xfc, 0x02 },
110 { 600000000, 36166667, 166666, 0xbc, 0x08 },
111 { 730000000, 36166667, 166666, 0xf4, 0x08 },
112 { 999999999, 36166667, 166666, 0xfc, 0x08 },
113 },
114};
115EXPORT_SYMBOL(dvb_pll_unknown_1);
116
117/* ----------------------------------------------------------- */
118/* code */
119
120static int debug = 0;
121module_param(debug, int, 0644);
122MODULE_PARM_DESC(debug, "enable verbose debug messages");
123
124int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf,
125 u32 freq, int bandwidth)
126{
127 u32 div;
128 int i;
129
130 if (freq != 0 && (freq < desc->min || freq > desc->max))
131 return -EINVAL;
132
133 for (i = 0; i < desc->count; i++) {
134 if (freq > desc->entries[i].limit)
135 continue;
136 break;
137 }
138 if (debug)
139 printk("pll: %s: freq=%d bw=%d | i=%d/%d\n",
140 desc->name, freq, bandwidth, i, desc->count);
141 BUG_ON(i == desc->count);
142
143 div = (freq + desc->entries[i].offset) / desc->entries[i].stepsize;
144 buf[0] = div >> 8;
145 buf[1] = div & 0xff;
146 buf[2] = desc->entries[i].cb1;
147 buf[3] = desc->entries[i].cb2;
148
149 if (desc->setbw)
150 desc->setbw(buf, bandwidth);
151
152 if (debug)
153 printk("pll: %s: div=%d | buf=0x%02x,0x%02x,0x%02x,0x%02x\n",
154 desc->name, div, buf[0], buf[1], buf[2], buf[3]);
155
156 return 0;
157}
158EXPORT_SYMBOL(dvb_pll_configure);
159
160MODULE_DESCRIPTION("dvb pll library");
161MODULE_AUTHOR("Gerd Knorr");
162MODULE_LICENSE("GPL");
163
164/*
165 * Local variables:
166 * c-basic-offset: 8
167 * End:
168 */
diff --git a/drivers/media/dvb/frontends/dvb-pll.h b/drivers/media/dvb/frontends/dvb-pll.h
new file mode 100644
index 000000000000..016c794a5677
--- /dev/null
+++ b/drivers/media/dvb/frontends/dvb-pll.h
@@ -0,0 +1,34 @@
1/*
2 * $Id: dvb-pll.h,v 1.2 2005/02/10 11:43:41 kraxel Exp $
3 */
4
5struct dvb_pll_desc {
6 char *name;
7 u32 min;
8 u32 max;
9 void (*setbw)(u8 *buf, int bandwidth);
10 int count;
11 struct {
12 u32 limit;
13 u32 offset;
14 u32 stepsize;
15 u8 cb1;
16 u8 cb2;
17 } entries[9];
18};
19
20extern struct dvb_pll_desc dvb_pll_thomson_dtt7579;
21extern struct dvb_pll_desc dvb_pll_thomson_dtt759x;
22extern struct dvb_pll_desc dvb_pll_thomson_dtt7610;
23extern struct dvb_pll_desc dvb_pll_lg_z201;
24extern struct dvb_pll_desc dvb_pll_unknown_1;
25
26int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf,
27 u32 freq, int bandwidth);
28
29/*
30 * Local variables:
31 * c-basic-offset: 8
32 * compile-command: "make DVB=1"
33 * End:
34 */
diff --git a/drivers/media/dvb/frontends/dvb_dummy_fe.c b/drivers/media/dvb/frontends/dvb_dummy_fe.c
new file mode 100644
index 000000000000..c05a9b05600c
--- /dev/null
+++ b/drivers/media/dvb/frontends/dvb_dummy_fe.c
@@ -0,0 +1,279 @@
1/*
2 * Driver for Dummy Frontend
3 *
4 * Written by Emard <emard@softhome.net>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
20 */
21
22#include <linux/module.h>
23#include <linux/moduleparam.h>
24#include <linux/init.h>
25
26#include "dvb_frontend.h"
27#include "dvb_dummy_fe.h"
28
29
30struct dvb_dummy_fe_state {
31 struct dvb_frontend_ops ops;
32 struct dvb_frontend frontend;
33};
34
35
36static int dvb_dummy_fe_read_status(struct dvb_frontend* fe, fe_status_t* status)
37{
38 *status = FE_HAS_SIGNAL
39 | FE_HAS_CARRIER
40 | FE_HAS_VITERBI
41 | FE_HAS_SYNC
42 | FE_HAS_LOCK;
43
44 return 0;
45}
46
47static int dvb_dummy_fe_read_ber(struct dvb_frontend* fe, u32* ber)
48{
49 *ber = 0;
50 return 0;
51}
52
53static int dvb_dummy_fe_read_signal_strength(struct dvb_frontend* fe, u16* strength)
54{
55 *strength = 0;
56 return 0;
57}
58
59static int dvb_dummy_fe_read_snr(struct dvb_frontend* fe, u16* snr)
60{
61 *snr = 0;
62 return 0;
63}
64
65static int dvb_dummy_fe_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
66{
67 *ucblocks = 0;
68 return 0;
69}
70
71static int dvb_dummy_fe_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
72{
73 return 0;
74}
75
76static int dvb_dummy_fe_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
77{
78 return 0;
79}
80
81static int dvb_dummy_fe_sleep(struct dvb_frontend* fe)
82{
83 return 0;
84}
85
86static int dvb_dummy_fe_init(struct dvb_frontend* fe)
87{
88 return 0;
89}
90
91static int dvb_dummy_fe_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
92{
93 return 0;
94}
95
96static int dvb_dummy_fe_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
97{
98 return 0;
99}
100
101static void dvb_dummy_fe_release(struct dvb_frontend* fe)
102{
103 struct dvb_dummy_fe_state* state = (struct dvb_dummy_fe_state*) fe->demodulator_priv;
104 kfree(state);
105}
106
107static struct dvb_frontend_ops dvb_dummy_fe_ofdm_ops;
108
109struct dvb_frontend* dvb_dummy_fe_ofdm_attach(void)
110{
111 struct dvb_dummy_fe_state* state = NULL;
112
113 /* allocate memory for the internal state */
114 state = (struct dvb_dummy_fe_state*) kmalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL);
115 if (state == NULL) goto error;
116
117 /* setup the state */
118 memcpy(&state->ops, &dvb_dummy_fe_ofdm_ops, sizeof(struct dvb_frontend_ops));
119
120 /* create dvb_frontend */
121 state->frontend.ops = &state->ops;
122 state->frontend.demodulator_priv = state;
123 return &state->frontend;
124
125error:
126 kfree(state);
127 return NULL;
128}
129
130static struct dvb_frontend_ops dvb_dummy_fe_qpsk_ops;
131
132struct dvb_frontend* dvb_dummy_fe_qpsk_attach()
133{
134 struct dvb_dummy_fe_state* state = NULL;
135
136 /* allocate memory for the internal state */
137 state = (struct dvb_dummy_fe_state*) kmalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL);
138 if (state == NULL) goto error;
139
140 /* setup the state */
141 memcpy(&state->ops, &dvb_dummy_fe_qpsk_ops, sizeof(struct dvb_frontend_ops));
142
143 /* create dvb_frontend */
144 state->frontend.ops = &state->ops;
145 state->frontend.demodulator_priv = state;
146 return &state->frontend;
147
148error:
149 if (state) kfree(state);
150 return NULL;
151}
152
153static struct dvb_frontend_ops dvb_dummy_fe_qam_ops;
154
155struct dvb_frontend* dvb_dummy_fe_qam_attach()
156{
157 struct dvb_dummy_fe_state* state = NULL;
158
159 /* allocate memory for the internal state */
160 state = (struct dvb_dummy_fe_state*) kmalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL);
161 if (state == NULL) goto error;
162
163 /* setup the state */
164 memcpy(&state->ops, &dvb_dummy_fe_qam_ops, sizeof(struct dvb_frontend_ops));
165
166 /* create dvb_frontend */
167 state->frontend.ops = &state->ops;
168 state->frontend.demodulator_priv = state;
169 return &state->frontend;
170
171error:
172 if (state) kfree(state);
173 return NULL;
174}
175
176static struct dvb_frontend_ops dvb_dummy_fe_ofdm_ops = {
177
178 .info = {
179 .name = "Dummy DVB-T",
180 .type = FE_OFDM,
181 .frequency_min = 0,
182 .frequency_max = 863250000,
183 .frequency_stepsize = 62500,
184 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
185 FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 |
186 FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO |
187 FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
188 FE_CAN_TRANSMISSION_MODE_AUTO |
189 FE_CAN_GUARD_INTERVAL_AUTO |
190 FE_CAN_HIERARCHY_AUTO,
191 },
192
193 .release = dvb_dummy_fe_release,
194
195 .init = dvb_dummy_fe_init,
196 .sleep = dvb_dummy_fe_sleep,
197
198 .set_frontend = dvb_dummy_fe_set_frontend,
199 .get_frontend = dvb_dummy_fe_get_frontend,
200
201 .read_status = dvb_dummy_fe_read_status,
202 .read_ber = dvb_dummy_fe_read_ber,
203 .read_signal_strength = dvb_dummy_fe_read_signal_strength,
204 .read_snr = dvb_dummy_fe_read_snr,
205 .read_ucblocks = dvb_dummy_fe_read_ucblocks,
206};
207
208static struct dvb_frontend_ops dvb_dummy_fe_qam_ops = {
209
210 .info = {
211 .name = "Dummy DVB-C",
212 .type = FE_QAM,
213 .frequency_stepsize = 62500,
214 .frequency_min = 51000000,
215 .frequency_max = 858000000,
216 .symbol_rate_min = (57840000/2)/64, /* SACLK/64 == (XIN/2)/64 */
217 .symbol_rate_max = (57840000/2)/4, /* SACLK/4 */
218 .caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
219 FE_CAN_QAM_128 | FE_CAN_QAM_256 |
220 FE_CAN_FEC_AUTO | FE_CAN_INVERSION_AUTO
221 },
222
223 .release = dvb_dummy_fe_release,
224
225 .init = dvb_dummy_fe_init,
226 .sleep = dvb_dummy_fe_sleep,
227
228 .set_frontend = dvb_dummy_fe_set_frontend,
229 .get_frontend = dvb_dummy_fe_get_frontend,
230
231 .read_status = dvb_dummy_fe_read_status,
232 .read_ber = dvb_dummy_fe_read_ber,
233 .read_signal_strength = dvb_dummy_fe_read_signal_strength,
234 .read_snr = dvb_dummy_fe_read_snr,
235 .read_ucblocks = dvb_dummy_fe_read_ucblocks,
236};
237
238static struct dvb_frontend_ops dvb_dummy_fe_qpsk_ops = {
239
240 .info = {
241 .name = "Dummy DVB-S",
242 .type = FE_QPSK,
243 .frequency_min = 950000,
244 .frequency_max = 2150000,
245 .frequency_stepsize = 250, /* kHz for QPSK frontends */
246 .frequency_tolerance = 29500,
247 .symbol_rate_min = 1000000,
248 .symbol_rate_max = 45000000,
249 .caps = FE_CAN_INVERSION_AUTO |
250 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
251 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
252 FE_CAN_QPSK
253 },
254
255 .release = dvb_dummy_fe_release,
256
257 .init = dvb_dummy_fe_init,
258 .sleep = dvb_dummy_fe_sleep,
259
260 .set_frontend = dvb_dummy_fe_set_frontend,
261 .get_frontend = dvb_dummy_fe_get_frontend,
262
263 .read_status = dvb_dummy_fe_read_status,
264 .read_ber = dvb_dummy_fe_read_ber,
265 .read_signal_strength = dvb_dummy_fe_read_signal_strength,
266 .read_snr = dvb_dummy_fe_read_snr,
267 .read_ucblocks = dvb_dummy_fe_read_ucblocks,
268
269 .set_voltage = dvb_dummy_fe_set_voltage,
270 .set_tone = dvb_dummy_fe_set_tone,
271};
272
273MODULE_DESCRIPTION("DVB DUMMY Frontend");
274MODULE_AUTHOR("Emard");
275MODULE_LICENSE("GPL");
276
277EXPORT_SYMBOL(dvb_dummy_fe_ofdm_attach);
278EXPORT_SYMBOL(dvb_dummy_fe_qam_attach);
279EXPORT_SYMBOL(dvb_dummy_fe_qpsk_attach);
diff --git a/drivers/media/dvb/frontends/dvb_dummy_fe.h b/drivers/media/dvb/frontends/dvb_dummy_fe.h
new file mode 100644
index 000000000000..8210f19d56ce
--- /dev/null
+++ b/drivers/media/dvb/frontends/dvb_dummy_fe.h
@@ -0,0 +1,32 @@
1/*
2 * Driver for Dummy Frontend
3 *
4 * Written by Emard <emard@softhome.net>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
20 */
21
22#ifndef DVB_DUMMY_FE_H
23#define DVB_DUMMY_FE_H
24
25#include <linux/dvb/frontend.h>
26#include "dvb_frontend.h"
27
28extern struct dvb_frontend* dvb_dummy_fe_ofdm_attach(void);
29extern struct dvb_frontend* dvb_dummy_fe_qpsk_attach(void);
30extern struct dvb_frontend* dvb_dummy_fe_qam_attach(void);
31
32#endif // DVB_DUMMY_FE_H
diff --git a/drivers/media/dvb/frontends/l64781.c b/drivers/media/dvb/frontends/l64781.c
new file mode 100644
index 000000000000..9ac95de9834d
--- /dev/null
+++ b/drivers/media/dvb/frontends/l64781.c
@@ -0,0 +1,602 @@
1/*
2 driver for LSI L64781 COFDM demodulator
3
4 Copyright (C) 2001 Holger Waechtler for Convergence Integrated Media GmbH
5 Marko Kohtala <marko.kohtala@luukku.com>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21*/
22
23#include <linux/init.h>
24#include <linux/kernel.h>
25#include <linux/module.h>
26#include <linux/moduleparam.h>
27#include <linux/string.h>
28#include <linux/slab.h>
29#include "dvb_frontend.h"
30#include "l64781.h"
31
32
33struct l64781_state {
34 struct i2c_adapter* i2c;
35 struct dvb_frontend_ops ops;
36 const struct l64781_config* config;
37 struct dvb_frontend frontend;
38
39 /* private demodulator data */
40 int first:1;
41};
42
43#define dprintk(args...) \
44 do { \
45 if (debug) printk(KERN_DEBUG "l64781: " args); \
46 } while (0)
47
48static int debug;
49
50module_param(debug, int, 0644);
51MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
52
53
54static int l64781_writereg (struct l64781_state* state, u8 reg, u8 data)
55{
56 int ret;
57 u8 buf [] = { reg, data };
58 struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 };
59
60 if ((ret = i2c_transfer(state->i2c, &msg, 1)) != 1)
61 dprintk ("%s: write_reg error (reg == %02x) = %02x!\n",
62 __FUNCTION__, reg, ret);
63
64 return (ret != 1) ? -1 : 0;
65}
66
67static int l64781_readreg (struct l64781_state* state, u8 reg)
68{
69 int ret;
70 u8 b0 [] = { reg };
71 u8 b1 [] = { 0 };
72 struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 },
73 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
74
75 ret = i2c_transfer(state->i2c, msg, 2);
76
77 if (ret != 2) return ret;
78
79 return b1[0];
80}
81
82static void apply_tps (struct l64781_state* state)
83{
84 l64781_writereg (state, 0x2a, 0x00);
85 l64781_writereg (state, 0x2a, 0x01);
86
87 /* This here is a little bit questionable because it enables
88 the automatic update of TPS registers. I think we'd need to
89 handle the IRQ from FE to update some other registers as
90 well, or at least implement some magic to tuning to correct
91 to the TPS received from transmission. */
92 l64781_writereg (state, 0x2a, 0x02);
93}
94
95
96static void reset_afc (struct l64781_state* state)
97{
98 /* Set AFC stall for the AFC_INIT_FRQ setting, TIM_STALL for
99 timing offset */
100 l64781_writereg (state, 0x07, 0x9e); /* stall AFC */
101 l64781_writereg (state, 0x08, 0); /* AFC INIT FREQ */
102 l64781_writereg (state, 0x09, 0);
103 l64781_writereg (state, 0x0a, 0);
104 l64781_writereg (state, 0x07, 0x8e);
105 l64781_writereg (state, 0x0e, 0); /* AGC gain to zero in beginning */
106 l64781_writereg (state, 0x11, 0x80); /* stall TIM */
107 l64781_writereg (state, 0x10, 0); /* TIM_OFFSET_LSB */
108 l64781_writereg (state, 0x12, 0);
109 l64781_writereg (state, 0x13, 0);
110 l64781_writereg (state, 0x11, 0x00);
111}
112
113static int reset_and_configure (struct l64781_state* state)
114{
115 u8 buf [] = { 0x06 };
116 struct i2c_msg msg = { .addr = 0x00, .flags = 0, .buf = buf, .len = 1 };
117 // NOTE: this is correct in writing to address 0x00
118
119 return (i2c_transfer(state->i2c, &msg, 1) == 1) ? 0 : -ENODEV;
120}
121
122static int apply_frontend_param (struct dvb_frontend* fe, struct dvb_frontend_parameters *param)
123{
124 struct l64781_state* state = (struct l64781_state*) fe->demodulator_priv;
125 /* The coderates for FEC_NONE, FEC_4_5 and FEC_FEC_6_7 are arbitrary */
126 static const u8 fec_tab[] = { 7, 0, 1, 2, 9, 3, 10, 4 };
127 /* QPSK, QAM_16, QAM_64 */
128 static const u8 qam_tab [] = { 2, 4, 0, 6 };
129 static const u8 bw_tab [] = { 8, 7, 6 }; /* 8Mhz, 7MHz, 6MHz */
130 static const u8 guard_tab [] = { 1, 2, 4, 8 };
131 /* The Grundig 29504-401.04 Tuner comes with 18.432MHz crystal. */
132 static const u32 ppm = 8000;
133 struct dvb_ofdm_parameters *p = &param->u.ofdm;
134 u32 ddfs_offset_fixed;
135/* u32 ddfs_offset_variable = 0x6000-((1000000UL+ppm)/ */
136/* bw_tab[p->bandWidth]<<10)/15625; */
137 u32 init_freq;
138 u32 spi_bias;
139 u8 val0x04;
140 u8 val0x05;
141 u8 val0x06;
142 int bw = p->bandwidth - BANDWIDTH_8_MHZ;
143
144 state->config->pll_set(fe, param);
145
146 if (param->inversion != INVERSION_ON &&
147 param->inversion != INVERSION_OFF)
148 return -EINVAL;
149
150 if (bw < 0 || bw > 2)
151 return -EINVAL;
152
153 if (p->code_rate_HP != FEC_1_2 && p->code_rate_HP != FEC_2_3 &&
154 p->code_rate_HP != FEC_3_4 && p->code_rate_HP != FEC_5_6 &&
155 p->code_rate_HP != FEC_7_8)
156 return -EINVAL;
157
158 if (p->hierarchy_information != HIERARCHY_NONE &&
159 (p->code_rate_LP != FEC_1_2 && p->code_rate_LP != FEC_2_3 &&
160 p->code_rate_LP != FEC_3_4 && p->code_rate_LP != FEC_5_6 &&
161 p->code_rate_LP != FEC_7_8))
162 return -EINVAL;
163
164 if (p->constellation != QPSK && p->constellation != QAM_16 &&
165 p->constellation != QAM_64)
166 return -EINVAL;
167
168 if (p->transmission_mode != TRANSMISSION_MODE_2K &&
169 p->transmission_mode != TRANSMISSION_MODE_8K)
170 return -EINVAL;
171
172 if (p->guard_interval < GUARD_INTERVAL_1_32 ||
173 p->guard_interval > GUARD_INTERVAL_1_4)
174 return -EINVAL;
175
176 if (p->hierarchy_information < HIERARCHY_NONE ||
177 p->hierarchy_information > HIERARCHY_4)
178 return -EINVAL;
179
180 ddfs_offset_fixed = 0x4000-(ppm<<16)/bw_tab[p->bandwidth]/1000000;
181
182 /* This works up to 20000 ppm, it overflows if too large ppm! */
183 init_freq = (((8UL<<25) + (8UL<<19) / 25*ppm / (15625/25)) /
184 bw_tab[p->bandwidth] & 0xFFFFFF);
185
186 /* SPI bias calculation is slightly modified to fit in 32bit */
187 /* will work for high ppm only... */
188 spi_bias = 378 * (1 << 10);
189 spi_bias *= 16;
190 spi_bias *= bw_tab[p->bandwidth];
191 spi_bias *= qam_tab[p->constellation];
192 spi_bias /= p->code_rate_HP + 1;
193 spi_bias /= (guard_tab[p->guard_interval] + 32);
194 spi_bias *= 1000ULL;
195 spi_bias /= 1000ULL + ppm/1000;
196 spi_bias *= p->code_rate_HP;
197
198 val0x04 = (p->transmission_mode << 2) | p->guard_interval;
199 val0x05 = fec_tab[p->code_rate_HP];
200
201 if (p->hierarchy_information != HIERARCHY_NONE)
202 val0x05 |= (p->code_rate_LP - FEC_1_2) << 3;
203
204 val0x06 = (p->hierarchy_information << 2) | p->constellation;
205
206 l64781_writereg (state, 0x04, val0x04);
207 l64781_writereg (state, 0x05, val0x05);
208 l64781_writereg (state, 0x06, val0x06);
209
210 reset_afc (state);
211
212 /* Technical manual section 2.6.1, TIM_IIR_GAIN optimal values */
213 l64781_writereg (state, 0x15,
214 p->transmission_mode == TRANSMISSION_MODE_2K ? 1 : 3);
215 l64781_writereg (state, 0x16, init_freq & 0xff);
216 l64781_writereg (state, 0x17, (init_freq >> 8) & 0xff);
217 l64781_writereg (state, 0x18, (init_freq >> 16) & 0xff);
218
219 l64781_writereg (state, 0x1b, spi_bias & 0xff);
220 l64781_writereg (state, 0x1c, (spi_bias >> 8) & 0xff);
221 l64781_writereg (state, 0x1d, ((spi_bias >> 16) & 0x7f) |
222 (param->inversion == INVERSION_ON ? 0x80 : 0x00));
223
224 l64781_writereg (state, 0x22, ddfs_offset_fixed & 0xff);
225 l64781_writereg (state, 0x23, (ddfs_offset_fixed >> 8) & 0x3f);
226
227 l64781_readreg (state, 0x00); /* clear interrupt registers... */
228 l64781_readreg (state, 0x01); /* dto. */
229
230 apply_tps (state);
231
232 return 0;
233}
234
235static int get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters* param)
236{
237 struct l64781_state* state = (struct l64781_state*) fe->demodulator_priv;
238 int tmp;
239
240
241 tmp = l64781_readreg(state, 0x04);
242 switch(tmp & 3) {
243 case 0:
244 param->u.ofdm.guard_interval = GUARD_INTERVAL_1_32;
245 break;
246 case 1:
247 param->u.ofdm.guard_interval = GUARD_INTERVAL_1_16;
248 break;
249 case 2:
250 param->u.ofdm.guard_interval = GUARD_INTERVAL_1_8;
251 break;
252 case 3:
253 param->u.ofdm.guard_interval = GUARD_INTERVAL_1_4;
254 break;
255 }
256 switch((tmp >> 2) & 3) {
257 case 0:
258 param->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K;
259 break;
260 case 1:
261 param->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K;
262 break;
263 default:
264 printk("Unexpected value for transmission_mode\n");
265 }
266
267
268
269 tmp = l64781_readreg(state, 0x05);
270 switch(tmp & 7) {
271 case 0:
272 param->u.ofdm.code_rate_HP = FEC_1_2;
273 break;
274 case 1:
275 param->u.ofdm.code_rate_HP = FEC_2_3;
276 break;
277 case 2:
278 param->u.ofdm.code_rate_HP = FEC_3_4;
279 break;
280 case 3:
281 param->u.ofdm.code_rate_HP = FEC_5_6;
282 break;
283 case 4:
284 param->u.ofdm.code_rate_HP = FEC_7_8;
285 break;
286 default:
287 printk("Unexpected value for code_rate_HP\n");
288 }
289 switch((tmp >> 3) & 7) {
290 case 0:
291 param->u.ofdm.code_rate_LP = FEC_1_2;
292 break;
293 case 1:
294 param->u.ofdm.code_rate_LP = FEC_2_3;
295 break;
296 case 2:
297 param->u.ofdm.code_rate_LP = FEC_3_4;
298 break;
299 case 3:
300 param->u.ofdm.code_rate_LP = FEC_5_6;
301 break;
302 case 4:
303 param->u.ofdm.code_rate_LP = FEC_7_8;
304 break;
305 default:
306 printk("Unexpected value for code_rate_LP\n");
307 }
308
309
310 tmp = l64781_readreg(state, 0x06);
311 switch(tmp & 3) {
312 case 0:
313 param->u.ofdm.constellation = QPSK;
314 break;
315 case 1:
316 param->u.ofdm.constellation = QAM_16;
317 break;
318 case 2:
319 param->u.ofdm.constellation = QAM_64;
320 break;
321 default:
322 printk("Unexpected value for constellation\n");
323 }
324 switch((tmp >> 2) & 7) {
325 case 0:
326 param->u.ofdm.hierarchy_information = HIERARCHY_NONE;
327 break;
328 case 1:
329 param->u.ofdm.hierarchy_information = HIERARCHY_1;
330 break;
331 case 2:
332 param->u.ofdm.hierarchy_information = HIERARCHY_2;
333 break;
334 case 3:
335 param->u.ofdm.hierarchy_information = HIERARCHY_4;
336 break;
337 default:
338 printk("Unexpected value for hierarchy\n");
339 }
340
341
342 tmp = l64781_readreg (state, 0x1d);
343 param->inversion = (tmp & 0x80) ? INVERSION_ON : INVERSION_OFF;
344
345 tmp = (int) (l64781_readreg (state, 0x08) |
346 (l64781_readreg (state, 0x09) << 8) |
347 (l64781_readreg (state, 0x0a) << 16));
348 param->frequency += tmp;
349
350 return 0;
351}
352
353static int l64781_read_status(struct dvb_frontend* fe, fe_status_t* status)
354{
355 struct l64781_state* state = (struct l64781_state*) fe->demodulator_priv;
356 int sync = l64781_readreg (state, 0x32);
357 int gain = l64781_readreg (state, 0x0e);
358
359 l64781_readreg (state, 0x00); /* clear interrupt registers... */
360 l64781_readreg (state, 0x01); /* dto. */
361
362 *status = 0;
363
364 if (gain > 5)
365 *status |= FE_HAS_SIGNAL;
366
367 if (sync & 0x02) /* VCXO locked, this criteria should be ok */
368 *status |= FE_HAS_CARRIER;
369
370 if (sync & 0x20)
371 *status |= FE_HAS_VITERBI;
372
373 if (sync & 0x40)
374 *status |= FE_HAS_SYNC;
375
376 if (sync == 0x7f)
377 *status |= FE_HAS_LOCK;
378
379 return 0;
380}
381
382static int l64781_read_ber(struct dvb_frontend* fe, u32* ber)
383{
384 struct l64781_state* state = (struct l64781_state*) fe->demodulator_priv;
385
386 /* XXX FIXME: set up counting period (reg 0x26...0x28)
387 */
388 *ber = l64781_readreg (state, 0x39)
389 | (l64781_readreg (state, 0x3a) << 8);
390
391 return 0;
392}
393
394static int l64781_read_signal_strength(struct dvb_frontend* fe, u16* signal_strength)
395{
396 struct l64781_state* state = (struct l64781_state*) fe->demodulator_priv;
397
398 u8 gain = l64781_readreg (state, 0x0e);
399 *signal_strength = (gain << 8) | gain;
400
401 return 0;
402}
403
404static int l64781_read_snr(struct dvb_frontend* fe, u16* snr)
405{
406 struct l64781_state* state = (struct l64781_state*) fe->demodulator_priv;
407
408 u8 avg_quality = 0xff - l64781_readreg (state, 0x33);
409 *snr = (avg_quality << 8) | avg_quality; /* not exact, but...*/
410
411 return 0;
412}
413
414static int l64781_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
415{
416 struct l64781_state* state = (struct l64781_state*) fe->demodulator_priv;
417
418 *ucblocks = l64781_readreg (state, 0x37)
419 | (l64781_readreg (state, 0x38) << 8);
420
421 return 0;
422}
423
424static int l64781_sleep(struct dvb_frontend* fe)
425{
426 struct l64781_state* state = (struct l64781_state*) fe->demodulator_priv;
427
428 /* Power down */
429 return l64781_writereg (state, 0x3e, 0x5a);
430}
431
432static int l64781_init(struct dvb_frontend* fe)
433{
434 struct l64781_state* state = (struct l64781_state*) fe->demodulator_priv;
435
436 reset_and_configure (state);
437
438 /* Power up */
439 l64781_writereg (state, 0x3e, 0xa5);
440
441 /* Reset hard */
442 l64781_writereg (state, 0x2a, 0x04);
443 l64781_writereg (state, 0x2a, 0x00);
444
445 /* Set tuner specific things */
446 /* AFC_POL, set also in reset_afc */
447 l64781_writereg (state, 0x07, 0x8e);
448
449 /* Use internal ADC */
450 l64781_writereg (state, 0x0b, 0x81);
451
452 /* AGC loop gain, and polarity is positive */
453 l64781_writereg (state, 0x0c, 0x84);
454
455 /* Internal ADC outputs two's complement */
456 l64781_writereg (state, 0x0d, 0x8c);
457
458 /* With ppm=8000, it seems the DTR_SENSITIVITY will result in
459 value of 2 with all possible bandwidths and guard
460 intervals, which is the initial value anyway. */
461 /*l64781_writereg (state, 0x19, 0x92);*/
462
463 /* Everything is two's complement, soft bit and CSI_OUT too */
464 l64781_writereg (state, 0x1e, 0x09);
465
466 if (state->config->pll_init) state->config->pll_init(fe);
467
468 /* delay a bit after first init attempt */
469 if (state->first) {
470 state->first = 0;
471 msleep(200);
472 }
473
474 return 0;
475}
476
477static int l64781_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
478{
479 fesettings->min_delay_ms = 200;
480 fesettings->step_size = 166667;
481 fesettings->max_drift = 166667*2;
482 return 0;
483}
484
485static void l64781_release(struct dvb_frontend* fe)
486{
487 struct l64781_state* state = (struct l64781_state*) fe->demodulator_priv;
488 kfree(state);
489}
490
491static struct dvb_frontend_ops l64781_ops;
492
493struct dvb_frontend* l64781_attach(const struct l64781_config* config,
494 struct i2c_adapter* i2c)
495{
496 struct l64781_state* state = NULL;
497 int reg0x3e = -1;
498 u8 b0 [] = { 0x1a };
499 u8 b1 [] = { 0x00 };
500 struct i2c_msg msg [] = { { .addr = config->demod_address, .flags = 0, .buf = b0, .len = 1 },
501 { .addr = config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
502
503 /* allocate memory for the internal state */
504 state = (struct l64781_state*) kmalloc(sizeof(struct l64781_state), GFP_KERNEL);
505 if (state == NULL) goto error;
506
507 /* setup the state */
508 state->config = config;
509 state->i2c = i2c;
510 memcpy(&state->ops, &l64781_ops, sizeof(struct dvb_frontend_ops));
511 state->first = 1;
512
513 /**
514 * the L64781 won't show up before we send the reset_and_configure()
515 * broadcast. If nothing responds there is no L64781 on the bus...
516 */
517 if (reset_and_configure(state) < 0) {
518 dprintk("No response to reset and configure broadcast...\n");
519 goto error;
520 }
521
522 /* The chip always responds to reads */
523 if (i2c_transfer(state->i2c, msg, 2) != 2) {
524 dprintk("No response to read on I2C bus\n");
525 goto error;
526 }
527
528 /* Save current register contents for bailout */
529 reg0x3e = l64781_readreg(state, 0x3e);
530
531 /* Reading the POWER_DOWN register always returns 0 */
532 if (reg0x3e != 0) {
533 dprintk("Device doesn't look like L64781\n");
534 goto error;
535 }
536
537 /* Turn the chip off */
538 l64781_writereg (state, 0x3e, 0x5a);
539
540 /* Responds to all reads with 0 */
541 if (l64781_readreg(state, 0x1a) != 0) {
542 dprintk("Read 1 returned unexpcted value\n");
543 goto error;
544 }
545
546 /* Turn the chip on */
547 l64781_writereg (state, 0x3e, 0xa5);
548
549 /* Responds with register default value */
550 if (l64781_readreg(state, 0x1a) != 0xa1) {
551 dprintk("Read 2 returned unexpcted value\n");
552 goto error;
553 }
554
555 /* create dvb_frontend */
556 state->frontend.ops = &state->ops;
557 state->frontend.demodulator_priv = state;
558 return &state->frontend;
559
560error:
561 if (reg0x3e >= 0) l64781_writereg (state, 0x3e, reg0x3e); /* restore reg 0x3e */
562 kfree(state);
563 return NULL;
564}
565
566static struct dvb_frontend_ops l64781_ops = {
567
568 .info = {
569 .name = "LSI L64781 DVB-T",
570 .type = FE_OFDM,
571 /* .frequency_min = ???,*/
572 /* .frequency_max = ???,*/
573 .frequency_stepsize = 166666,
574 /* .frequency_tolerance = ???,*/
575 /* .symbol_rate_tolerance = ???,*/
576 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
577 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
578 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 |
579 FE_CAN_MUTE_TS
580 },
581
582 .release = l64781_release,
583
584 .init = l64781_init,
585 .sleep = l64781_sleep,
586
587 .set_frontend = apply_frontend_param,
588 .get_frontend = get_frontend,
589 .get_tune_settings = l64781_get_tune_settings,
590
591 .read_status = l64781_read_status,
592 .read_ber = l64781_read_ber,
593 .read_signal_strength = l64781_read_signal_strength,
594 .read_snr = l64781_read_snr,
595 .read_ucblocks = l64781_read_ucblocks,
596};
597
598MODULE_DESCRIPTION("LSI L64781 DVB-T Demodulator driver");
599MODULE_AUTHOR("Holger Waechtler, Marko Kohtala");
600MODULE_LICENSE("GPL");
601
602EXPORT_SYMBOL(l64781_attach);
diff --git a/drivers/media/dvb/frontends/l64781.h b/drivers/media/dvb/frontends/l64781.h
new file mode 100644
index 000000000000..7e30fb0fdfa7
--- /dev/null
+++ b/drivers/media/dvb/frontends/l64781.h
@@ -0,0 +1,42 @@
1/*
2 driver for LSI L64781 COFDM demodulator
3
4 Copyright (C) 2001 Holger Waechtler for Convergence Integrated Media GmbH
5 Marko Kohtala <marko.kohtala@luukku.com>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21*/
22
23#ifndef L64781_H
24#define L64781_H
25
26#include <linux/dvb/frontend.h>
27
28struct l64781_config
29{
30 /* the demodulator's i2c address */
31 u8 demod_address;
32
33 /* PLL maintenance */
34 int (*pll_init)(struct dvb_frontend* fe);
35 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
36};
37
38
39extern struct dvb_frontend* l64781_attach(const struct l64781_config* config,
40 struct i2c_adapter* i2c);
41
42#endif // L64781_H
diff --git a/drivers/media/dvb/frontends/mt312.c b/drivers/media/dvb/frontends/mt312.c
new file mode 100644
index 000000000000..176a22e3441b
--- /dev/null
+++ b/drivers/media/dvb/frontends/mt312.c
@@ -0,0 +1,729 @@
1/*
2 Driver for Zarlink VP310/MT312 Satellite Channel Decoder
3
4 Copyright (C) 2003 Andreas Oberritter <obi@linuxtv.org>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21 References:
22 http://products.zarlink.com/product_profiles/MT312.htm
23 http://products.zarlink.com/product_profiles/SL1935.htm
24*/
25
26#include <linux/delay.h>
27#include <linux/errno.h>
28#include <linux/init.h>
29#include <linux/kernel.h>
30#include <linux/module.h>
31#include <linux/moduleparam.h>
32
33#include "dvb_frontend.h"
34#include "mt312_priv.h"
35#include "mt312.h"
36
37
38struct mt312_state {
39 struct i2c_adapter* i2c;
40 struct dvb_frontend_ops ops;
41 /* configuration settings */
42 const struct mt312_config* config;
43 struct dvb_frontend frontend;
44
45 u8 id;
46 u8 frequency;
47};
48
49static int debug;
50#define dprintk(args...) \
51 do { \
52 if (debug) printk(KERN_DEBUG "mt312: " args); \
53 } while (0)
54
55#define MT312_SYS_CLK 90000000UL /* 90 MHz */
56#define MT312_LPOWER_SYS_CLK 60000000UL /* 60 MHz */
57#define MT312_PLL_CLK 10000000UL /* 10 MHz */
58
59static int mt312_read(struct mt312_state* state, const enum mt312_reg_addr reg,
60 void *buf, const size_t count)
61{
62 int ret;
63 struct i2c_msg msg[2];
64 u8 regbuf[1] = { reg };
65
66 msg[0].addr = state->config->demod_address;
67 msg[0].flags = 0;
68 msg[0].buf = regbuf;
69 msg[0].len = 1;
70 msg[1].addr = state->config->demod_address;
71 msg[1].flags = I2C_M_RD;
72 msg[1].buf = buf;
73 msg[1].len = count;
74
75 ret = i2c_transfer(state->i2c, msg, 2);
76
77 if (ret != 2) {
78 printk(KERN_ERR "%s: ret == %d\n", __FUNCTION__, ret);
79 return -EREMOTEIO;
80 }
81
82 if(debug) {
83 int i;
84 dprintk("R(%d):", reg & 0x7f);
85 for (i = 0; i < count; i++)
86 printk(" %02x", ((const u8 *) buf)[i]);
87 printk("\n");
88 }
89
90 return 0;
91}
92
93static int mt312_write(struct mt312_state* state, const enum mt312_reg_addr reg,
94 const void *src, const size_t count)
95{
96 int ret;
97 u8 buf[count + 1];
98 struct i2c_msg msg;
99
100 if(debug) {
101 int i;
102 dprintk("W(%d):", reg & 0x7f);
103 for (i = 0; i < count; i++)
104 printk(" %02x", ((const u8 *) src)[i]);
105 printk("\n");
106 }
107
108 buf[0] = reg;
109 memcpy(&buf[1], src, count);
110
111 msg.addr = state->config->demod_address;
112 msg.flags = 0;
113 msg.buf = buf;
114 msg.len = count + 1;
115
116 ret = i2c_transfer(state->i2c, &msg, 1);
117
118 if (ret != 1) {
119 dprintk("%s: ret == %d\n", __FUNCTION__, ret);
120 return -EREMOTEIO;
121 }
122
123 return 0;
124}
125
126static inline int mt312_readreg(struct mt312_state* state,
127 const enum mt312_reg_addr reg, u8 *val)
128{
129 return mt312_read(state, reg, val, 1);
130}
131
132static inline int mt312_writereg(struct mt312_state* state,
133 const enum mt312_reg_addr reg, const u8 val)
134{
135 return mt312_write(state, reg, &val, 1);
136}
137
138static inline u32 mt312_div(u32 a, u32 b)
139{
140 return (a + (b / 2)) / b;
141}
142
143static int mt312_reset(struct mt312_state* state, const u8 full)
144{
145 return mt312_writereg(state, RESET, full ? 0x80 : 0x40);
146}
147
148static int mt312_get_inversion(struct mt312_state* state,
149 fe_spectral_inversion_t *i)
150{
151 int ret;
152 u8 vit_mode;
153
154 if ((ret = mt312_readreg(state, VIT_MODE, &vit_mode)) < 0)
155 return ret;
156
157 if (vit_mode & 0x80) /* auto inversion was used */
158 *i = (vit_mode & 0x40) ? INVERSION_ON : INVERSION_OFF;
159
160 return 0;
161}
162
163static int mt312_get_symbol_rate(struct mt312_state* state, u32 *sr)
164{
165 int ret;
166 u8 sym_rate_h;
167 u8 dec_ratio;
168 u16 sym_rat_op;
169 u16 monitor;
170 u8 buf[2];
171
172 if ((ret = mt312_readreg(state, SYM_RATE_H, &sym_rate_h)) < 0)
173 return ret;
174
175 if (sym_rate_h & 0x80) { /* symbol rate search was used */
176 if ((ret = mt312_writereg(state, MON_CTRL, 0x03)) < 0)
177 return ret;
178
179 if ((ret = mt312_read(state, MONITOR_H, buf, sizeof(buf))) < 0)
180 return ret;
181
182 monitor = (buf[0] << 8) | buf[1];
183
184 dprintk(KERN_DEBUG "sr(auto) = %u\n",
185 mt312_div(monitor * 15625, 4));
186 } else {
187 if ((ret = mt312_writereg(state, MON_CTRL, 0x05)) < 0)
188 return ret;
189
190 if ((ret = mt312_read(state, MONITOR_H, buf, sizeof(buf))) < 0)
191 return ret;
192
193 dec_ratio = ((buf[0] >> 5) & 0x07) * 32;
194
195 if ((ret = mt312_read(state, SYM_RAT_OP_H, buf, sizeof(buf))) < 0)
196 return ret;
197
198 sym_rat_op = (buf[0] << 8) | buf[1];
199
200 dprintk(KERN_DEBUG "sym_rat_op=%d dec_ratio=%d\n",
201 sym_rat_op, dec_ratio);
202 dprintk(KERN_DEBUG "*sr(manual) = %lu\n",
203 (((MT312_PLL_CLK * 8192) / (sym_rat_op + 8192)) *
204 2) - dec_ratio);
205 }
206
207 return 0;
208}
209
210static int mt312_get_code_rate(struct mt312_state* state, fe_code_rate_t *cr)
211{
212 const fe_code_rate_t fec_tab[8] =
213 { FEC_1_2, FEC_2_3, FEC_3_4, FEC_5_6, FEC_6_7, FEC_7_8,
214 FEC_AUTO, FEC_AUTO };
215
216 int ret;
217 u8 fec_status;
218
219 if ((ret = mt312_readreg(state, FEC_STATUS, &fec_status)) < 0)
220 return ret;
221
222 *cr = fec_tab[(fec_status >> 4) & 0x07];
223
224 return 0;
225}
226
227static int mt312_initfe(struct dvb_frontend* fe)
228{
229 struct mt312_state *state = (struct mt312_state*) fe->demodulator_priv;
230 int ret;
231 u8 buf[2];
232
233 /* wake up */
234 if ((ret = mt312_writereg(state, CONFIG, (state->frequency == 60 ? 0x88 : 0x8c))) < 0)
235 return ret;
236
237 /* wait at least 150 usec */
238 udelay(150);
239
240 /* full reset */
241 if ((ret = mt312_reset(state, 1)) < 0)
242 return ret;
243
244// Per datasheet, write correct values. 09/28/03 ACCJr.
245// If we don't do this, we won't get FE_HAS_VITERBI in the VP310.
246 {
247 u8 buf_def[8]={0x14, 0x12, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00};
248
249 if ((ret = mt312_write(state, VIT_SETUP, buf_def, sizeof(buf_def))) < 0)
250 return ret;
251 }
252
253 /* SYS_CLK */
254 buf[0] = mt312_div((state->frequency == 60 ? MT312_LPOWER_SYS_CLK : MT312_SYS_CLK) * 2, 1000000);
255
256 /* DISEQC_RATIO */
257 buf[1] = mt312_div(MT312_PLL_CLK, 15000 * 4);
258
259 if ((ret = mt312_write(state, SYS_CLK, buf, sizeof(buf))) < 0)
260 return ret;
261
262 if ((ret = mt312_writereg(state, SNR_THS_HIGH, 0x32)) < 0)
263 return ret;
264
265 if ((ret = mt312_writereg(state, OP_CTRL, 0x53)) < 0)
266 return ret;
267
268 /* TS_SW_LIM */
269 buf[0] = 0x8c;
270 buf[1] = 0x98;
271
272 if ((ret = mt312_write(state, TS_SW_LIM_L, buf, sizeof(buf))) < 0)
273 return ret;
274
275 if ((ret = mt312_writereg(state, CS_SW_LIM, 0x69)) < 0)
276 return ret;
277
278 if (state->config->pll_init) {
279 mt312_writereg(state, GPP_CTRL, 0x40);
280 state->config->pll_init(fe);
281 mt312_writereg(state, GPP_CTRL, 0x00);
282 }
283
284 return 0;
285}
286
287static int mt312_send_master_cmd(struct dvb_frontend* fe,
288 struct dvb_diseqc_master_cmd *c)
289{
290 struct mt312_state *state = (struct mt312_state*) fe->demodulator_priv;
291 int ret;
292 u8 diseqc_mode;
293
294 if ((c->msg_len == 0) || (c->msg_len > sizeof(c->msg)))
295 return -EINVAL;
296
297 if ((ret = mt312_readreg(state, DISEQC_MODE, &diseqc_mode)) < 0)
298 return ret;
299
300 if ((ret =
301 mt312_write(state, (0x80 | DISEQC_INSTR), c->msg, c->msg_len)) < 0)
302 return ret;
303
304 if ((ret =
305 mt312_writereg(state, DISEQC_MODE,
306 (diseqc_mode & 0x40) | ((c->msg_len - 1) << 3)
307 | 0x04)) < 0)
308 return ret;
309
310 /* set DISEQC_MODE[2:0] to zero if a return message is expected */
311 if (c->msg[0] & 0x02)
312 if ((ret =
313 mt312_writereg(state, DISEQC_MODE, (diseqc_mode & 0x40))) < 0)
314 return ret;
315
316 return 0;
317}
318
319static int mt312_send_burst(struct dvb_frontend* fe, const fe_sec_mini_cmd_t c)
320{
321 struct mt312_state *state = (struct mt312_state*) fe->demodulator_priv;
322 const u8 mini_tab[2] = { 0x02, 0x03 };
323
324 int ret;
325 u8 diseqc_mode;
326
327 if (c > SEC_MINI_B)
328 return -EINVAL;
329
330 if ((ret = mt312_readreg(state, DISEQC_MODE, &diseqc_mode)) < 0)
331 return ret;
332
333 if ((ret =
334 mt312_writereg(state, DISEQC_MODE,
335 (diseqc_mode & 0x40) | mini_tab[c])) < 0)
336 return ret;
337
338 return 0;
339}
340
341static int mt312_set_tone(struct dvb_frontend* fe, const fe_sec_tone_mode_t t)
342{
343 struct mt312_state *state = (struct mt312_state*) fe->demodulator_priv;
344 const u8 tone_tab[2] = { 0x01, 0x00 };
345
346 int ret;
347 u8 diseqc_mode;
348
349 if (t > SEC_TONE_OFF)
350 return -EINVAL;
351
352 if ((ret = mt312_readreg(state, DISEQC_MODE, &diseqc_mode)) < 0)
353 return ret;
354
355 if ((ret =
356 mt312_writereg(state, DISEQC_MODE,
357 (diseqc_mode & 0x40) | tone_tab[t])) < 0)
358 return ret;
359
360 return 0;
361}
362
363static int mt312_set_voltage(struct dvb_frontend* fe, const fe_sec_voltage_t v)
364{
365 struct mt312_state *state = (struct mt312_state*) fe->demodulator_priv;
366 const u8 volt_tab[3] = { 0x00, 0x40, 0x00 };
367
368 if (v > SEC_VOLTAGE_OFF)
369 return -EINVAL;
370
371 return mt312_writereg(state, DISEQC_MODE, volt_tab[v]);
372}
373
374static int mt312_read_status(struct dvb_frontend* fe, fe_status_t *s)
375{
376 struct mt312_state *state = (struct mt312_state*) fe->demodulator_priv;
377 int ret;
378 u8 status[3];
379
380 *s = 0;
381
382 if ((ret = mt312_read(state, QPSK_STAT_H, status, sizeof(status))) < 0)
383 return ret;
384
385 dprintk(KERN_DEBUG "QPSK_STAT_H: 0x%02x, QPSK_STAT_L: 0x%02x, FEC_STATUS: 0x%02x\n", status[0], status[1], status[2]);
386
387 if (status[0] & 0xc0)
388 *s |= FE_HAS_SIGNAL; /* signal noise ratio */
389 if (status[0] & 0x04)
390 *s |= FE_HAS_CARRIER; /* qpsk carrier lock */
391 if (status[2] & 0x02)
392 *s |= FE_HAS_VITERBI; /* viterbi lock */
393 if (status[2] & 0x04)
394 *s |= FE_HAS_SYNC; /* byte align lock */
395 if (status[0] & 0x01)
396 *s |= FE_HAS_LOCK; /* qpsk lock */
397
398 return 0;
399}
400
401static int mt312_read_ber(struct dvb_frontend* fe, u32 *ber)
402{
403 struct mt312_state *state = (struct mt312_state*) fe->demodulator_priv;
404 int ret;
405 u8 buf[3];
406
407 if ((ret = mt312_read(state, RS_BERCNT_H, buf, 3)) < 0)
408 return ret;
409
410 *ber = ((buf[0] << 16) | (buf[1] << 8) | buf[2]) * 64;
411
412 return 0;
413}
414
415static int mt312_read_signal_strength(struct dvb_frontend* fe, u16 *signal_strength)
416{
417 struct mt312_state *state = (struct mt312_state*) fe->demodulator_priv;
418 int ret;
419 u8 buf[3];
420 u16 agc;
421 s16 err_db;
422
423 if ((ret = mt312_read(state, AGC_H, buf, sizeof(buf))) < 0)
424 return ret;
425
426 agc = (buf[0] << 6) | (buf[1] >> 2);
427 err_db = (s16) (((buf[1] & 0x03) << 14) | buf[2] << 6) >> 6;
428
429 *signal_strength = agc;
430
431 dprintk(KERN_DEBUG "agc=%08x err_db=%hd\n", agc, err_db);
432
433 return 0;
434}
435
436static int mt312_read_snr(struct dvb_frontend* fe, u16 *snr)
437{
438 struct mt312_state *state = (struct mt312_state*) fe->demodulator_priv;
439 int ret;
440 u8 buf[2];
441
442 if ((ret = mt312_read(state, M_SNR_H, &buf, sizeof(buf))) < 0)
443 return ret;
444
445 *snr = 0xFFFF - ((((buf[0] & 0x7f) << 8) | buf[1]) << 1);
446
447 return 0;
448}
449
450static int mt312_read_ucblocks(struct dvb_frontend* fe, u32 *ubc)
451{
452 struct mt312_state *state = (struct mt312_state*) fe->demodulator_priv;
453 int ret;
454 u8 buf[2];
455
456 if ((ret = mt312_read(state, RS_UBC_H, &buf, sizeof(buf))) < 0)
457 return ret;
458
459 *ubc = (buf[0] << 8) | buf[1];
460
461 return 0;
462}
463
464static int mt312_set_frontend(struct dvb_frontend* fe,
465 struct dvb_frontend_parameters *p)
466{
467 struct mt312_state *state = (struct mt312_state*) fe->demodulator_priv;
468 int ret;
469 u8 buf[5], config_val;
470 u16 sr;
471
472 const u8 fec_tab[10] =
473 { 0x00, 0x01, 0x02, 0x04, 0x3f, 0x08, 0x10, 0x20, 0x3f, 0x3f };
474 const u8 inv_tab[3] = { 0x00, 0x40, 0x80 };
475
476 dprintk("%s: Freq %d\n", __FUNCTION__, p->frequency);
477
478 if ((p->frequency < fe->ops->info.frequency_min)
479 || (p->frequency > fe->ops->info.frequency_max))
480 return -EINVAL;
481
482 if ((p->inversion < INVERSION_OFF)
483 || (p->inversion > INVERSION_ON))
484 return -EINVAL;
485
486 if ((p->u.qpsk.symbol_rate < fe->ops->info.symbol_rate_min)
487 || (p->u.qpsk.symbol_rate > fe->ops->info.symbol_rate_max))
488 return -EINVAL;
489
490 if ((p->u.qpsk.fec_inner < FEC_NONE)
491 || (p->u.qpsk.fec_inner > FEC_AUTO))
492 return -EINVAL;
493
494 if ((p->u.qpsk.fec_inner == FEC_4_5)
495 || (p->u.qpsk.fec_inner == FEC_8_9))
496 return -EINVAL;
497
498 switch (state->id) {
499 case ID_VP310:
500 // For now we will do this only for the VP310.
501 // It should be better for the mt312 as well, but tunning will be slower. ACCJr 09/29/03
502 if ((ret = mt312_readreg(state, CONFIG, &config_val) < 0))
503 return ret;
504 if (p->u.qpsk.symbol_rate >= 30000000) //Note that 30MS/s should use 90MHz
505 {
506 if ((config_val & 0x0c) == 0x08) { //We are running 60MHz
507 state->frequency = 90;
508 if ((ret = mt312_initfe(fe)) < 0)
509 return ret;
510 }
511 }
512 else
513 {
514 if ((config_val & 0x0c) == 0x0C) { //We are running 90MHz
515 state->frequency = 60;
516 if ((ret = mt312_initfe(fe)) < 0)
517 return ret;
518 }
519 }
520 break;
521
522 case ID_MT312:
523 break;
524
525 default:
526 return -EINVAL;
527 }
528
529 mt312_writereg(state, GPP_CTRL, 0x40);
530 state->config->pll_set(fe, p);
531 mt312_writereg(state, GPP_CTRL, 0x00);
532
533 /* sr = (u16)(sr * 256.0 / 1000000.0) */
534 sr = mt312_div(p->u.qpsk.symbol_rate * 4, 15625);
535
536 /* SYM_RATE */
537 buf[0] = (sr >> 8) & 0x3f;
538 buf[1] = (sr >> 0) & 0xff;
539
540 /* VIT_MODE */
541 buf[2] = inv_tab[p->inversion] | fec_tab[p->u.qpsk.fec_inner];
542
543 /* QPSK_CTRL */
544 buf[3] = 0x40; /* swap I and Q before QPSK demodulation */
545
546 if (p->u.qpsk.symbol_rate < 10000000)
547 buf[3] |= 0x04; /* use afc mode */
548
549 /* GO */
550 buf[4] = 0x01;
551
552 if ((ret = mt312_write(state, SYM_RATE_H, buf, sizeof(buf))) < 0)
553 return ret;
554
555 mt312_reset(state, 0);
556
557 return 0;
558}
559
560static int mt312_get_frontend(struct dvb_frontend* fe,
561 struct dvb_frontend_parameters *p)
562{
563 struct mt312_state *state = (struct mt312_state*) fe->demodulator_priv;
564 int ret;
565
566 if ((ret = mt312_get_inversion(state, &p->inversion)) < 0)
567 return ret;
568
569 if ((ret = mt312_get_symbol_rate(state, &p->u.qpsk.symbol_rate)) < 0)
570 return ret;
571
572 if ((ret = mt312_get_code_rate(state, &p->u.qpsk.fec_inner)) < 0)
573 return ret;
574
575 return 0;
576}
577
578static int mt312_sleep(struct dvb_frontend* fe)
579{
580 struct mt312_state *state = (struct mt312_state*) fe->demodulator_priv;
581 int ret;
582 u8 config;
583
584 /* reset all registers to defaults */
585 if ((ret = mt312_reset(state, 1)) < 0)
586 return ret;
587
588 if ((ret = mt312_readreg(state, CONFIG, &config)) < 0)
589 return ret;
590
591 /* enter standby */
592 if ((ret = mt312_writereg(state, CONFIG, config & 0x7f)) < 0)
593 return ret;
594
595 return 0;
596}
597
598static int mt312_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
599{
600 fesettings->min_delay_ms = 50;
601 fesettings->step_size = 0;
602 fesettings->max_drift = 0;
603 return 0;
604}
605
606static void mt312_release(struct dvb_frontend* fe)
607{
608 struct mt312_state* state = (struct mt312_state*) fe->demodulator_priv;
609 kfree(state);
610}
611
612static struct dvb_frontend_ops vp310_mt312_ops;
613
614struct dvb_frontend* vp310_attach(const struct mt312_config* config,
615 struct i2c_adapter* i2c)
616{
617 struct mt312_state* state = NULL;
618
619 /* allocate memory for the internal state */
620 state = (struct mt312_state*) kmalloc(sizeof(struct mt312_state), GFP_KERNEL);
621 if (state == NULL)
622 goto error;
623
624 /* setup the state */
625 state->config = config;
626 state->i2c = i2c;
627 memcpy(&state->ops, &vp310_mt312_ops, sizeof(struct dvb_frontend_ops));
628 strcpy(state->ops.info.name, "Zarlink VP310 DVB-S");
629
630 /* check if the demod is there */
631 if (mt312_readreg(state, ID, &state->id) < 0)
632 goto error;
633 if (state->id != ID_VP310) {
634 goto error;
635 }
636
637 /* create dvb_frontend */
638 state->frequency = 90;
639 state->frontend.ops = &state->ops;
640 state->frontend.demodulator_priv = state;
641 return &state->frontend;
642
643error:
644 kfree(state);
645 return NULL;
646}
647
648struct dvb_frontend* mt312_attach(const struct mt312_config* config,
649 struct i2c_adapter* i2c)
650{
651 struct mt312_state* state = NULL;
652
653 /* allocate memory for the internal state */
654 state = (struct mt312_state*) kmalloc(sizeof(struct mt312_state), GFP_KERNEL);
655 if (state == NULL)
656 goto error;
657
658 /* setup the state */
659 state->config = config;
660 state->i2c = i2c;
661 memcpy(&state->ops, &vp310_mt312_ops, sizeof(struct dvb_frontend_ops));
662 strcpy(state->ops.info.name, "Zarlink MT312 DVB-S");
663
664 /* check if the demod is there */
665 if (mt312_readreg(state, ID, &state->id) < 0)
666 goto error;
667 if (state->id != ID_MT312) {
668 goto error;
669 }
670
671 /* create dvb_frontend */
672 state->frequency = 60;
673 state->frontend.ops = &state->ops;
674 state->frontend.demodulator_priv = state;
675 return &state->frontend;
676
677error:
678 if (state)
679 kfree(state);
680 return NULL;
681}
682
683static struct dvb_frontend_ops vp310_mt312_ops = {
684
685 .info = {
686 .name = "Zarlink ???? DVB-S",
687 .type = FE_QPSK,
688 .frequency_min = 950000,
689 .frequency_max = 2150000,
690 .frequency_stepsize = (MT312_PLL_CLK / 1000) / 128,
691 .symbol_rate_min = MT312_SYS_CLK / 128,
692 .symbol_rate_max = MT312_SYS_CLK / 2,
693 .caps =
694 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
695 FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
696 FE_CAN_FEC_AUTO | FE_CAN_QPSK | FE_CAN_MUTE_TS |
697 FE_CAN_RECOVER
698 },
699
700 .release = mt312_release,
701
702 .init = mt312_initfe,
703 .sleep = mt312_sleep,
704
705 .set_frontend = mt312_set_frontend,
706 .get_frontend = mt312_get_frontend,
707 .get_tune_settings = mt312_get_tune_settings,
708
709 .read_status = mt312_read_status,
710 .read_ber = mt312_read_ber,
711 .read_signal_strength = mt312_read_signal_strength,
712 .read_snr = mt312_read_snr,
713 .read_ucblocks = mt312_read_ucblocks,
714
715 .diseqc_send_master_cmd = mt312_send_master_cmd,
716 .diseqc_send_burst = mt312_send_burst,
717 .set_tone = mt312_set_tone,
718 .set_voltage = mt312_set_voltage,
719};
720
721module_param(debug, int, 0644);
722MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
723
724MODULE_DESCRIPTION("Zarlink VP310/MT312 DVB-S Demodulator driver");
725MODULE_AUTHOR("Andreas Oberritter <obi@linuxtv.org>");
726MODULE_LICENSE("GPL");
727
728EXPORT_SYMBOL(mt312_attach);
729EXPORT_SYMBOL(vp310_attach);
diff --git a/drivers/media/dvb/frontends/mt312.h b/drivers/media/dvb/frontends/mt312.h
new file mode 100644
index 000000000000..b3a53a73a117
--- /dev/null
+++ b/drivers/media/dvb/frontends/mt312.h
@@ -0,0 +1,47 @@
1/*
2 Driver for Zarlink MT312 Satellite Channel Decoder
3
4 Copyright (C) 2003 Andreas Oberritter <obi@linuxtv.org>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21 References:
22 http://products.zarlink.com/product_profiles/MT312.htm
23 http://products.zarlink.com/product_profiles/SL1935.htm
24*/
25
26#ifndef MT312_H
27#define MT312_H
28
29#include <linux/dvb/frontend.h>
30
31struct mt312_config
32{
33 /* the demodulator's i2c address */
34 u8 demod_address;
35
36 /* PLL maintenance */
37 int (*pll_init)(struct dvb_frontend* fe);
38 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
39};
40
41extern struct dvb_frontend* mt312_attach(const struct mt312_config* config,
42 struct i2c_adapter* i2c);
43
44extern struct dvb_frontend* vp310_attach(const struct mt312_config* config,
45 struct i2c_adapter* i2c);
46
47#endif // MT312_H
diff --git a/drivers/media/dvb/frontends/mt312_priv.h b/drivers/media/dvb/frontends/mt312_priv.h
new file mode 100644
index 000000000000..5e0b95b5337b
--- /dev/null
+++ b/drivers/media/dvb/frontends/mt312_priv.h
@@ -0,0 +1,162 @@
1/*
2 Driver for Zarlink MT312 QPSK Frontend
3
4 Copyright (C) 2003 Andreas Oberritter <obi@linuxtv.org>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21*/
22
23#ifndef _DVB_FRONTENDS_MT312_PRIV
24#define _DVB_FRONTENDS_MT312_PRIV
25
26enum mt312_reg_addr {
27 QPSK_INT_H = 0,
28 QPSK_INT_M = 1,
29 QPSK_INT_L = 2,
30 FEC_INT = 3,
31 QPSK_STAT_H = 4,
32 QPSK_STAT_L = 5,
33 FEC_STATUS = 6,
34 LNB_FREQ_H = 7,
35 LNB_FREQ_L = 8,
36 M_SNR_H = 9,
37 M_SNR_L = 10,
38 VIT_ERRCNT_H = 11,
39 VIT_ERRCNT_M = 12,
40 VIT_ERRCNT_L = 13,
41 RS_BERCNT_H = 14,
42 RS_BERCNT_M = 15,
43 RS_BERCNT_L = 16,
44 RS_UBC_H = 17,
45 RS_UBC_L = 18,
46 SIG_LEVEL = 19,
47 GPP_CTRL = 20,
48 RESET = 21,
49 DISEQC_MODE = 22,
50 SYM_RATE_H = 23,
51 SYM_RATE_L = 24,
52 VIT_MODE = 25,
53 QPSK_CTRL = 26,
54 GO = 27,
55 IE_QPSK_H = 28,
56 IE_QPSK_M = 29,
57 IE_QPSK_L = 30,
58 IE_FEC = 31,
59 QPSK_STAT_EN = 32,
60 FEC_STAT_EN = 33,
61 SYS_CLK = 34,
62 DISEQC_RATIO = 35,
63 DISEQC_INSTR = 36,
64 FR_LIM = 37,
65 FR_OFF = 38,
66 AGC_CTRL = 39,
67 AGC_INIT = 40,
68 AGC_REF = 41,
69 AGC_MAX = 42,
70 AGC_MIN = 43,
71 AGC_LK_TH = 44,
72 TS_AGC_LK_TH = 45,
73 AGC_PWR_SET = 46,
74 QPSK_MISC = 47,
75 SNR_THS_LOW = 48,
76 SNR_THS_HIGH = 49,
77 TS_SW_RATE = 50,
78 TS_SW_LIM_L = 51,
79 TS_SW_LIM_H = 52,
80 CS_SW_RATE_1 = 53,
81 CS_SW_RATE_2 = 54,
82 CS_SW_RATE_3 = 55,
83 CS_SW_RATE_4 = 56,
84 CS_SW_LIM = 57,
85 TS_LPK = 58,
86 TS_LPK_M = 59,
87 TS_LPK_L = 60,
88 CS_KPROP_H = 61,
89 CS_KPROP_L = 62,
90 CS_KINT_H = 63,
91 CS_KINT_L = 64,
92 QPSK_SCALE = 65,
93 TLD_OUTCLK_TH = 66,
94 TLD_INCLK_TH = 67,
95 FLD_TH = 68,
96 PLD_OUTLK3 = 69,
97 PLD_OUTLK2 = 70,
98 PLD_OUTLK1 = 71,
99 PLD_OUTLK0 = 72,
100 PLD_INLK3 = 73,
101 PLD_INLK2 = 74,
102 PLD_INLK1 = 75,
103 PLD_INLK0 = 76,
104 PLD_ACC_TIME = 77,
105 SWEEP_PAR = 78,
106 STARTUP_TIME = 79,
107 LOSSLOCK_TH = 80,
108 FEC_LOCK_TM = 81,
109 LOSSLOCK_TM = 82,
110 VIT_ERRPER_H = 83,
111 VIT_ERRPER_M = 84,
112 VIT_ERRPER_L = 85,
113 VIT_SETUP = 86,
114 VIT_REF0 = 87,
115 VIT_REF1 = 88,
116 VIT_REF2 = 89,
117 VIT_REF3 = 90,
118 VIT_REF4 = 91,
119 VIT_REF5 = 92,
120 VIT_REF6 = 93,
121 VIT_MAXERR = 94,
122 BA_SETUPT = 95,
123 OP_CTRL = 96,
124 FEC_SETUP = 97,
125 PROG_SYNC = 98,
126 AFC_SEAR_TH = 99,
127 CSACC_DIF_TH = 100,
128 QPSK_LK_CT = 101,
129 QPSK_ST_CT = 102,
130 MON_CTRL = 103,
131 QPSK_RESET = 104,
132 QPSK_TST_CT = 105,
133 QPSK_TST_ST = 106,
134 TEST_R = 107,
135 AGC_H = 108,
136 AGC_M = 109,
137 AGC_L = 110,
138 FREQ_ERR1_H = 111,
139 FREQ_ERR1_M = 112,
140 FREQ_ERR1_L = 113,
141 FREQ_ERR2_H = 114,
142 FREQ_ERR2_L = 115,
143 SYM_RAT_OP_H = 116,
144 SYM_RAT_OP_L = 117,
145 DESEQC2_INT = 118,
146 DISEQC2_STAT = 119,
147 DISEQC2_FIFO = 120,
148 DISEQC2_CTRL1 = 121,
149 DISEQC2_CTRL2 = 122,
150 MONITOR_H = 123,
151 MONITOR_L = 124,
152 TEST_MODE = 125,
153 ID = 126,
154 CONFIG = 127
155};
156
157enum mt312_model_id {
158 ID_VP310 = 1,
159 ID_MT312 = 3
160};
161
162#endif /* DVB_FRONTENDS_MT312_PRIV */
diff --git a/drivers/media/dvb/frontends/mt352.c b/drivers/media/dvb/frontends/mt352.c
new file mode 100644
index 000000000000..50326c7248fa
--- /dev/null
+++ b/drivers/media/dvb/frontends/mt352.c
@@ -0,0 +1,610 @@
1/*
2 * Driver for Zarlink DVB-T MT352 demodulator
3 *
4 * Written by Holger Waechtler <holger@qanu.de>
5 * and Daniel Mack <daniel@qanu.de>
6 *
7 * AVerMedia AVerTV DVB-T 771 support by
8 * Wolfram Joost <dbox2@frokaschwei.de>
9 *
10 * Support for Samsung TDTC9251DH01C(M) tuner
11 * Copyright (C) 2004 Antonio Mancuso <antonio.mancuso@digitaltelevision.it>
12 * Amauri Celani <acelani@essegi.net>
13 *
14 * DVICO FusionHDTV DVB-T1 and DVICO FusionHDTV DVB-T Lite support by
15 * Christopher Pascoe <c.pascoe@itee.uq.edu.au>
16 *
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation; either version 2 of the License, or
20 * (at your option) any later version.
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 *
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#include <linux/kernel.h>
34#include <linux/module.h>
35#include <linux/moduleparam.h>
36#include <linux/init.h>
37#include <linux/delay.h>
38
39#include "dvb_frontend.h"
40#include "mt352_priv.h"
41#include "mt352.h"
42
43struct mt352_state {
44 struct i2c_adapter* i2c;
45 struct dvb_frontend frontend;
46 struct dvb_frontend_ops ops;
47
48 /* configuration settings */
49 const struct mt352_config* config;
50};
51
52static int debug;
53#define dprintk(args...) \
54 do { \
55 if (debug) printk(KERN_DEBUG "mt352: " args); \
56 } while (0)
57
58static int mt352_single_write(struct dvb_frontend *fe, u8 reg, u8 val)
59{
60 struct mt352_state* state = fe->demodulator_priv;
61 u8 buf[2] = { reg, val };
62 struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0,
63 .buf = buf, .len = 2 };
64 int err = i2c_transfer(state->i2c, &msg, 1);
65 if (err != 1) {
66 printk("mt352_write() to reg %x failed (err = %d)!\n", reg, err);
67 return err;
68 }
69 return 0;
70}
71
72int mt352_write(struct dvb_frontend* fe, u8* ibuf, int ilen)
73{
74 int err,i;
75 for (i=0; i < ilen-1; i++)
76 if ((err = mt352_single_write(fe,ibuf[0]+i,ibuf[i+1])))
77 return err;
78
79 return 0;
80}
81
82static int mt352_read_register(struct mt352_state* state, u8 reg)
83{
84 int ret;
85 u8 b0 [] = { reg };
86 u8 b1 [] = { 0 };
87 struct i2c_msg msg [] = { { .addr = state->config->demod_address,
88 .flags = 0,
89 .buf = b0, .len = 1 },
90 { .addr = state->config->demod_address,
91 .flags = I2C_M_RD,
92 .buf = b1, .len = 1 } };
93
94 ret = i2c_transfer(state->i2c, msg, 2);
95
96 if (ret != 2) {
97 printk("%s: readreg error (reg=%d, ret==%i)\n",
98 __FUNCTION__, reg, ret);
99 return ret;
100 }
101
102 return b1[0];
103}
104
105int mt352_read(struct dvb_frontend *fe, u8 reg)
106{
107 return mt352_read_register(fe->demodulator_priv,reg);
108}
109
110static int mt352_sleep(struct dvb_frontend* fe)
111{
112 static u8 mt352_softdown[] = { CLOCK_CTL, 0x20, 0x08 };
113
114 mt352_write(fe, mt352_softdown, sizeof(mt352_softdown));
115 return 0;
116}
117
118static void mt352_calc_nominal_rate(struct mt352_state* state,
119 enum fe_bandwidth bandwidth,
120 unsigned char *buf)
121{
122 u32 adc_clock = 20480; /* 20.340 MHz */
123 u32 bw,value;
124
125 switch (bandwidth) {
126 case BANDWIDTH_6_MHZ:
127 bw = 6;
128 break;
129 case BANDWIDTH_7_MHZ:
130 bw = 7;
131 break;
132 case BANDWIDTH_8_MHZ:
133 default:
134 bw = 8;
135 break;
136 }
137 if (state->config->adc_clock)
138 adc_clock = state->config->adc_clock;
139
140 value = 64 * bw * (1<<16) / (7 * 8);
141 value = value * 1000 / adc_clock;
142 dprintk("%s: bw %d, adc_clock %d => 0x%x\n",
143 __FUNCTION__, bw, adc_clock, value);
144 buf[0] = msb(value);
145 buf[1] = lsb(value);
146}
147
148static void mt352_calc_input_freq(struct mt352_state* state,
149 unsigned char *buf)
150{
151 int adc_clock = 20480; /* 20.480000 MHz */
152 int if2 = 36167; /* 36.166667 MHz */
153 int ife,value;
154
155 if (state->config->adc_clock)
156 adc_clock = state->config->adc_clock;
157 if (state->config->if2)
158 if2 = state->config->if2;
159
160 ife = (2*adc_clock - if2);
161 value = -16374 * ife / adc_clock;
162 dprintk("%s: if2 %d, ife %d, adc_clock %d => %d / 0x%x\n",
163 __FUNCTION__, if2, ife, adc_clock, value, value & 0x3fff);
164 buf[0] = msb(value);
165 buf[1] = lsb(value);
166}
167
168static int mt352_set_parameters(struct dvb_frontend* fe,
169 struct dvb_frontend_parameters *param)
170{
171 struct mt352_state* state = fe->demodulator_priv;
172 unsigned char buf[13];
173 static unsigned char tuner_go[] = { 0x5d, 0x01 };
174 static unsigned char fsm_go[] = { 0x5e, 0x01 };
175 unsigned int tps = 0;
176 struct dvb_ofdm_parameters *op = &param->u.ofdm;
177
178 switch (op->code_rate_HP) {
179 case FEC_2_3:
180 tps |= (1 << 7);
181 break;
182 case FEC_3_4:
183 tps |= (2 << 7);
184 break;
185 case FEC_5_6:
186 tps |= (3 << 7);
187 break;
188 case FEC_7_8:
189 tps |= (4 << 7);
190 break;
191 case FEC_1_2:
192 case FEC_AUTO:
193 break;
194 default:
195 return -EINVAL;
196 }
197
198 switch (op->code_rate_LP) {
199 case FEC_2_3:
200 tps |= (1 << 4);
201 break;
202 case FEC_3_4:
203 tps |= (2 << 4);
204 break;
205 case FEC_5_6:
206 tps |= (3 << 4);
207 break;
208 case FEC_7_8:
209 tps |= (4 << 4);
210 break;
211 case FEC_1_2:
212 case FEC_AUTO:
213 break;
214 case FEC_NONE:
215 if (op->hierarchy_information == HIERARCHY_AUTO ||
216 op->hierarchy_information == HIERARCHY_NONE)
217 break;
218 default:
219 return -EINVAL;
220 }
221
222 switch (op->constellation) {
223 case QPSK:
224 break;
225 case QAM_AUTO:
226 case QAM_16:
227 tps |= (1 << 13);
228 break;
229 case QAM_64:
230 tps |= (2 << 13);
231 break;
232 default:
233 return -EINVAL;
234 }
235
236 switch (op->transmission_mode) {
237 case TRANSMISSION_MODE_2K:
238 case TRANSMISSION_MODE_AUTO:
239 break;
240 case TRANSMISSION_MODE_8K:
241 tps |= (1 << 0);
242 break;
243 default:
244 return -EINVAL;
245 }
246
247 switch (op->guard_interval) {
248 case GUARD_INTERVAL_1_32:
249 case GUARD_INTERVAL_AUTO:
250 break;
251 case GUARD_INTERVAL_1_16:
252 tps |= (1 << 2);
253 break;
254 case GUARD_INTERVAL_1_8:
255 tps |= (2 << 2);
256 break;
257 case GUARD_INTERVAL_1_4:
258 tps |= (3 << 2);
259 break;
260 default:
261 return -EINVAL;
262 }
263
264 switch (op->hierarchy_information) {
265 case HIERARCHY_AUTO:
266 case HIERARCHY_NONE:
267 break;
268 case HIERARCHY_1:
269 tps |= (1 << 10);
270 break;
271 case HIERARCHY_2:
272 tps |= (2 << 10);
273 break;
274 case HIERARCHY_4:
275 tps |= (3 << 10);
276 break;
277 default:
278 return -EINVAL;
279 }
280
281
282 buf[0] = TPS_GIVEN_1; /* TPS_GIVEN_1 and following registers */
283
284 buf[1] = msb(tps); /* TPS_GIVEN_(1|0) */
285 buf[2] = lsb(tps);
286
287 buf[3] = 0x50; // old
288// buf[3] = 0xf4; // pinnacle
289
290 mt352_calc_nominal_rate(state, op->bandwidth, buf+4);
291 mt352_calc_input_freq(state, buf+6);
292 state->config->pll_set(fe, param, buf+8);
293
294 mt352_write(fe, buf, sizeof(buf));
295 if (state->config->no_tuner) {
296 /* start decoding */
297 mt352_write(fe, fsm_go, 2);
298 } else {
299 /* start tuning */
300 mt352_write(fe, tuner_go, 2);
301 }
302 return 0;
303}
304
305static int mt352_get_parameters(struct dvb_frontend* fe,
306 struct dvb_frontend_parameters *param)
307{
308 struct mt352_state* state = fe->demodulator_priv;
309 u16 tps;
310 u16 div;
311 u8 trl;
312 struct dvb_ofdm_parameters *op = &param->u.ofdm;
313 static const u8 tps_fec_to_api[8] =
314 {
315 FEC_1_2,
316 FEC_2_3,
317 FEC_3_4,
318 FEC_5_6,
319 FEC_7_8,
320 FEC_AUTO,
321 FEC_AUTO,
322 FEC_AUTO
323 };
324
325 if ( (mt352_read_register(state,0x00) & 0xC0) != 0xC0 )
326 return -EINVAL;
327
328 /* Use TPS_RECEIVED-registers, not the TPS_CURRENT-registers because
329 * the mt352 sometimes works with the wrong parameters
330 */
331 tps = (mt352_read_register(state, TPS_RECEIVED_1) << 8) | mt352_read_register(state, TPS_RECEIVED_0);
332 div = (mt352_read_register(state, CHAN_START_1) << 8) | mt352_read_register(state, CHAN_START_0);
333 trl = mt352_read_register(state, TRL_NOMINAL_RATE_1);
334
335 op->code_rate_HP = tps_fec_to_api[(tps >> 7) & 7];
336 op->code_rate_LP = tps_fec_to_api[(tps >> 4) & 7];
337
338 switch ( (tps >> 13) & 3)
339 {
340 case 0:
341 op->constellation = QPSK;
342 break;
343 case 1:
344 op->constellation = QAM_16;
345 break;
346 case 2:
347 op->constellation = QAM_64;
348 break;
349 default:
350 op->constellation = QAM_AUTO;
351 break;
352 }
353
354 op->transmission_mode = (tps & 0x01) ? TRANSMISSION_MODE_8K : TRANSMISSION_MODE_2K;
355
356 switch ( (tps >> 2) & 3)
357 {
358 case 0:
359 op->guard_interval = GUARD_INTERVAL_1_32;
360 break;
361 case 1:
362 op->guard_interval = GUARD_INTERVAL_1_16;
363 break;
364 case 2:
365 op->guard_interval = GUARD_INTERVAL_1_8;
366 break;
367 case 3:
368 op->guard_interval = GUARD_INTERVAL_1_4;
369 break;
370 default:
371 op->guard_interval = GUARD_INTERVAL_AUTO;
372 break;
373 }
374
375 switch ( (tps >> 10) & 7)
376 {
377 case 0:
378 op->hierarchy_information = HIERARCHY_NONE;
379 break;
380 case 1:
381 op->hierarchy_information = HIERARCHY_1;
382 break;
383 case 2:
384 op->hierarchy_information = HIERARCHY_2;
385 break;
386 case 3:
387 op->hierarchy_information = HIERARCHY_4;
388 break;
389 default:
390 op->hierarchy_information = HIERARCHY_AUTO;
391 break;
392 }
393
394 param->frequency = ( 500 * (div - IF_FREQUENCYx6) ) / 3 * 1000;
395
396 if (trl == 0x72)
397 op->bandwidth = BANDWIDTH_8_MHZ;
398 else if (trl == 0x64)
399 op->bandwidth = BANDWIDTH_7_MHZ;
400 else
401 op->bandwidth = BANDWIDTH_6_MHZ;
402
403
404 if (mt352_read_register(state, STATUS_2) & 0x02)
405 param->inversion = INVERSION_OFF;
406 else
407 param->inversion = INVERSION_ON;
408
409 return 0;
410}
411
412static int mt352_read_status(struct dvb_frontend* fe, fe_status_t* status)
413{
414 struct mt352_state* state = fe->demodulator_priv;
415 int s0, s1, s3;
416
417 /* FIXME:
418 *
419 * The MT352 design manual from Zarlink states (page 46-47):
420 *
421 * Notes about the TUNER_GO register:
422 *
423 * If the Read_Tuner_Byte (bit-1) is activated, then the tuner status
424 * byte is copied from the tuner to the STATUS_3 register and
425 * completion of the read operation is indicated by bit-5 of the
426 * INTERRUPT_3 register.
427 */
428
429 if ((s0 = mt352_read_register(state, STATUS_0)) < 0)
430 return -EREMOTEIO;
431 if ((s1 = mt352_read_register(state, STATUS_1)) < 0)
432 return -EREMOTEIO;
433 if ((s3 = mt352_read_register(state, STATUS_3)) < 0)
434 return -EREMOTEIO;
435
436 *status = 0;
437 if (s0 & (1 << 4))
438 *status |= FE_HAS_CARRIER;
439 if (s0 & (1 << 1))
440 *status |= FE_HAS_VITERBI;
441 if (s0 & (1 << 5))
442 *status |= FE_HAS_LOCK;
443 if (s1 & (1 << 1))
444 *status |= FE_HAS_SYNC;
445 if (s3 & (1 << 6))
446 *status |= FE_HAS_SIGNAL;
447
448 if ((*status & (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC)) !=
449 (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC))
450 *status &= ~FE_HAS_LOCK;
451
452 return 0;
453}
454
455static int mt352_read_ber(struct dvb_frontend* fe, u32* ber)
456{
457 struct mt352_state* state = fe->demodulator_priv;
458
459 *ber = (mt352_read_register (state, RS_ERR_CNT_2) << 16) |
460 (mt352_read_register (state, RS_ERR_CNT_1) << 8) |
461 (mt352_read_register (state, RS_ERR_CNT_0));
462
463 return 0;
464}
465
466static int mt352_read_signal_strength(struct dvb_frontend* fe, u16* strength)
467{
468 struct mt352_state* state = fe->demodulator_priv;
469
470 u16 signal = ((mt352_read_register(state, AGC_GAIN_1) << 8) & 0x0f) |
471 (mt352_read_register(state, AGC_GAIN_0));
472
473 *strength = ~signal;
474 return 0;
475}
476
477static int mt352_read_snr(struct dvb_frontend* fe, u16* snr)
478{
479 struct mt352_state* state = fe->demodulator_priv;
480
481 u8 _snr = mt352_read_register (state, SNR);
482 *snr = (_snr << 8) | _snr;
483
484 return 0;
485}
486
487static int mt352_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
488{
489 struct mt352_state* state = fe->demodulator_priv;
490
491 *ucblocks = (mt352_read_register (state, RS_UBC_1) << 8) |
492 (mt352_read_register (state, RS_UBC_0));
493
494 return 0;
495}
496
497static int mt352_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fe_tune_settings)
498{
499 fe_tune_settings->min_delay_ms = 800;
500 fe_tune_settings->step_size = 0;
501 fe_tune_settings->max_drift = 0;
502
503 return 0;
504}
505
506static int mt352_init(struct dvb_frontend* fe)
507{
508 struct mt352_state* state = fe->demodulator_priv;
509
510 static u8 mt352_reset_attach [] = { RESET, 0xC0 };
511
512 dprintk("%s: hello\n",__FUNCTION__);
513
514 if ((mt352_read_register(state, CLOCK_CTL) & 0x10) == 0 ||
515 (mt352_read_register(state, CONFIG) & 0x20) == 0) {
516
517 /* Do a "hard" reset */
518 mt352_write(fe, mt352_reset_attach, sizeof(mt352_reset_attach));
519 return state->config->demod_init(fe);
520 }
521
522 return 0;
523}
524
525static void mt352_release(struct dvb_frontend* fe)
526{
527 struct mt352_state* state = fe->demodulator_priv;
528 kfree(state);
529}
530
531static struct dvb_frontend_ops mt352_ops;
532
533struct dvb_frontend* mt352_attach(const struct mt352_config* config,
534 struct i2c_adapter* i2c)
535{
536 struct mt352_state* state = NULL;
537
538 /* allocate memory for the internal state */
539 state = kmalloc(sizeof(struct mt352_state), GFP_KERNEL);
540 if (state == NULL) goto error;
541 memset(state,0,sizeof(*state));
542
543 /* setup the state */
544 state->config = config;
545 state->i2c = i2c;
546 memcpy(&state->ops, &mt352_ops, sizeof(struct dvb_frontend_ops));
547
548 /* check if the demod is there */
549 if (mt352_read_register(state, CHIP_ID) != ID_MT352) goto error;
550
551 /* create dvb_frontend */
552 state->frontend.ops = &state->ops;
553 state->frontend.demodulator_priv = state;
554 return &state->frontend;
555
556error:
557 kfree(state);
558 return NULL;
559}
560
561static struct dvb_frontend_ops mt352_ops = {
562
563 .info = {
564 .name = "Zarlink MT352 DVB-T",
565 .type = FE_OFDM,
566 .frequency_min = 174000000,
567 .frequency_max = 862000000,
568 .frequency_stepsize = 166667,
569 .frequency_tolerance = 0,
570 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
571 FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
572 FE_CAN_FEC_AUTO |
573 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
574 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
575 FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER |
576 FE_CAN_MUTE_TS
577 },
578
579 .release = mt352_release,
580
581 .init = mt352_init,
582 .sleep = mt352_sleep,
583
584 .set_frontend = mt352_set_parameters,
585 .get_frontend = mt352_get_parameters,
586 .get_tune_settings = mt352_get_tune_settings,
587
588 .read_status = mt352_read_status,
589 .read_ber = mt352_read_ber,
590 .read_signal_strength = mt352_read_signal_strength,
591 .read_snr = mt352_read_snr,
592 .read_ucblocks = mt352_read_ucblocks,
593};
594
595module_param(debug, int, 0644);
596MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
597
598MODULE_DESCRIPTION("Zarlink MT352 DVB-T Demodulator driver");
599MODULE_AUTHOR("Holger Waechtler, Daniel Mack, Antonio Mancuso");
600MODULE_LICENSE("GPL");
601
602EXPORT_SYMBOL(mt352_attach);
603EXPORT_SYMBOL(mt352_write);
604EXPORT_SYMBOL(mt352_read);
605/*
606 * Local variables:
607 * c-basic-offset: 8
608 * compile-command: "make DVB=1"
609 * End:
610 */
diff --git a/drivers/media/dvb/frontends/mt352.h b/drivers/media/dvb/frontends/mt352.h
new file mode 100644
index 000000000000..f5d8a5aed8a9
--- /dev/null
+++ b/drivers/media/dvb/frontends/mt352.h
@@ -0,0 +1,72 @@
1/*
2 * Driver for Zarlink DVB-T MT352 demodulator
3 *
4 * Written by Holger Waechtler <holger@qanu.de>
5 * and Daniel Mack <daniel@qanu.de>
6 *
7 * AVerMedia AVerTV DVB-T 771 support by
8 * Wolfram Joost <dbox2@frokaschwei.de>
9 *
10 * Support for Samsung TDTC9251DH01C(M) tuner
11 * Copyright (C) 2004 Antonio Mancuso <antonio.mancuso@digitaltelevision.it>
12 * Amauri Celani <acelani@essegi.net>
13 *
14 * DVICO FusionHDTV DVB-T1 and DVICO FusionHDTV DVB-T Lite support by
15 * Christopher Pascoe <c.pascoe@itee.uq.edu.au>
16 *
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation; either version 2 of the License, or
20 * (at your option) any later version.
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 *
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#ifndef MT352_H
34#define MT352_H
35
36#include <linux/dvb/frontend.h>
37
38struct mt352_config
39{
40 /* the demodulator's i2c address */
41 u8 demod_address;
42
43 /* frequencies in kHz */
44 int adc_clock; // default: 20480
45 int if2; // default: 36166
46
47 /* set if no pll is connected to the secondary i2c bus */
48 int no_tuner;
49
50 /* Initialise the demodulator and PLL. Cannot be NULL */
51 int (*demod_init)(struct dvb_frontend* fe);
52
53 /* PLL setup - fill out the supplied 5 byte buffer with your PLL settings.
54 * byte0: Set to pll i2c address (nonlinux; left shifted by 1)
55 * byte1-4: PLL configuration.
56 */
57 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u8* pllbuf);
58};
59
60extern struct dvb_frontend* mt352_attach(const struct mt352_config* config,
61 struct i2c_adapter* i2c);
62
63extern int mt352_write(struct dvb_frontend* fe, u8* ibuf, int ilen);
64extern int mt352_read(struct dvb_frontend *fe, u8 reg);
65
66#endif // MT352_H
67
68/*
69 * Local variables:
70 * c-basic-offset: 8
71 * End:
72 */
diff --git a/drivers/media/dvb/frontends/mt352_priv.h b/drivers/media/dvb/frontends/mt352_priv.h
new file mode 100644
index 000000000000..44ad0d4c8f12
--- /dev/null
+++ b/drivers/media/dvb/frontends/mt352_priv.h
@@ -0,0 +1,127 @@
1/*
2 * Driver for Zarlink DVB-T MT352 demodulator
3 *
4 * Written by Holger Waechtler <holger@qanu.de>
5 * and Daniel Mack <daniel@qanu.de>
6 *
7 * AVerMedia AVerTV DVB-T 771 support by
8 * Wolfram Joost <dbox2@frokaschwei.de>
9 *
10 * Support for Samsung TDTC9251DH01C(M) tuner
11 * Copyright (C) 2004 Antonio Mancuso <antonio.mancuso@digitaltelevision.it>
12 * Amauri Celani <acelani@essegi.net>
13 *
14 * DVICO FusionHDTV DVB-T1 and DVICO FusionHDTV DVB-T Lite support by
15 * Christopher Pascoe <c.pascoe@itee.uq.edu.au>
16 *
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation; either version 2 of the License, or
20 * (at your option) any later version.
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 *
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#ifndef _MT352_PRIV_
34#define _MT352_PRIV_
35
36#define ID_MT352 0x13
37
38#define msb(x) (((x) >> 8) & 0xff)
39#define lsb(x) ((x) & 0xff)
40
41enum mt352_reg_addr {
42 STATUS_0 = 0x00,
43 STATUS_1 = 0x01,
44 STATUS_2 = 0x02,
45 STATUS_3 = 0x03,
46 STATUS_4 = 0x04,
47 INTERRUPT_0 = 0x05,
48 INTERRUPT_1 = 0x06,
49 INTERRUPT_2 = 0x07,
50 INTERRUPT_3 = 0x08,
51 SNR = 0x09,
52 VIT_ERR_CNT_2 = 0x0A,
53 VIT_ERR_CNT_1 = 0x0B,
54 VIT_ERR_CNT_0 = 0x0C,
55 RS_ERR_CNT_2 = 0x0D,
56 RS_ERR_CNT_1 = 0x0E,
57 RS_ERR_CNT_0 = 0x0F,
58 RS_UBC_1 = 0x10,
59 RS_UBC_0 = 0x11,
60 AGC_GAIN_3 = 0x12,
61 AGC_GAIN_2 = 0x13,
62 AGC_GAIN_1 = 0x14,
63 AGC_GAIN_0 = 0x15,
64 FREQ_OFFSET_2 = 0x17,
65 FREQ_OFFSET_1 = 0x18,
66 FREQ_OFFSET_0 = 0x19,
67 TIMING_OFFSET_1 = 0x1A,
68 TIMING_OFFSET_0 = 0x1B,
69 CHAN_FREQ_1 = 0x1C,
70 CHAN_FREQ_0 = 0x1D,
71 TPS_RECEIVED_1 = 0x1E,
72 TPS_RECEIVED_0 = 0x1F,
73 TPS_CURRENT_1 = 0x20,
74 TPS_CURRENT_0 = 0x21,
75 TPS_CELL_ID_1 = 0x22,
76 TPS_CELL_ID_0 = 0x23,
77 TPS_MISC_DATA_2 = 0x24,
78 TPS_MISC_DATA_1 = 0x25,
79 TPS_MISC_DATA_0 = 0x26,
80 RESET = 0x50,
81 TPS_GIVEN_1 = 0x51,
82 TPS_GIVEN_0 = 0x52,
83 ACQ_CTL = 0x53,
84 TRL_NOMINAL_RATE_1 = 0x54,
85 TRL_NOMINAL_RATE_0 = 0x55,
86 INPUT_FREQ_1 = 0x56,
87 INPUT_FREQ_0 = 0x57,
88 TUNER_ADDR = 0x58,
89 CHAN_START_1 = 0x59,
90 CHAN_START_0 = 0x5A,
91 CONT_1 = 0x5B,
92 CONT_0 = 0x5C,
93 TUNER_GO = 0x5D,
94 STATUS_EN_0 = 0x5F,
95 STATUS_EN_1 = 0x60,
96 INTERRUPT_EN_0 = 0x61,
97 INTERRUPT_EN_1 = 0x62,
98 INTERRUPT_EN_2 = 0x63,
99 INTERRUPT_EN_3 = 0x64,
100 AGC_TARGET = 0x67,
101 AGC_CTL = 0x68,
102 CAPT_RANGE = 0x75,
103 SNR_SELECT_1 = 0x79,
104 SNR_SELECT_0 = 0x7A,
105 RS_ERR_PER_1 = 0x7C,
106 RS_ERR_PER_0 = 0x7D,
107 CHIP_ID = 0x7F,
108 CHAN_STOP_1 = 0x80,
109 CHAN_STOP_0 = 0x81,
110 CHAN_STEP_1 = 0x82,
111 CHAN_STEP_0 = 0x83,
112 FEC_LOCK_TIME = 0x85,
113 OFDM_LOCK_TIME = 0x86,
114 ACQ_DELAY = 0x87,
115 SCAN_CTL = 0x88,
116 CLOCK_CTL = 0x89,
117 CONFIG = 0x8A,
118 MCLK_RATIO = 0x8B,
119 GPP_CTL = 0x8C,
120 ADC_CTL_1 = 0x8E,
121 ADC_CTL_0 = 0x8F
122};
123
124/* here we assume 1/6MHz == 166.66kHz stepsize */
125#define IF_FREQUENCYx6 217 /* 6 * 36.16666666667MHz */
126
127#endif /* _MT352_PRIV_ */
diff --git a/drivers/media/dvb/frontends/nxt2002.c b/drivers/media/dvb/frontends/nxt2002.c
new file mode 100644
index 000000000000..4743aa17406e
--- /dev/null
+++ b/drivers/media/dvb/frontends/nxt2002.c
@@ -0,0 +1,705 @@
1/*
2 Support for B2C2/BBTI Technisat Air2PC - ATSC
3
4 Copyright (C) 2004 Taylor Jacob <rtjacob@earthlink.net>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19
20*/
21
22/*
23 * This driver needs external firmware. Please use the command
24 * "<kerneldir>/Documentation/dvb/get_dvb_firmware nxt2002" to
25 * download/extract it, and then copy it to /usr/lib/hotplug/firmware.
26 */
27#define NXT2002_DEFAULT_FIRMWARE "dvb-fe-nxt2002.fw"
28#define CRC_CCIT_MASK 0x1021
29
30#include <linux/init.h>
31#include <linux/module.h>
32#include <linux/moduleparam.h>
33#include <linux/device.h>
34#include <linux/firmware.h>
35
36#include "dvb_frontend.h"
37#include "nxt2002.h"
38
39struct nxt2002_state {
40
41 struct i2c_adapter* i2c;
42 struct dvb_frontend_ops ops;
43 const struct nxt2002_config* config;
44 struct dvb_frontend frontend;
45
46 /* demodulator private data */
47 u8 initialised:1;
48};
49
50static int debug;
51#define dprintk(args...) \
52 do { \
53 if (debug) printk(KERN_DEBUG "nxt2002: " args); \
54 } while (0)
55
56static int i2c_writebytes (struct nxt2002_state* state, u8 reg, u8 *buf, u8 len)
57{
58 /* probbably a much better way or doing this */
59 u8 buf2 [256],x;
60 int err;
61 struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf2, .len = len + 1 };
62
63 buf2[0] = reg;
64 for (x = 0 ; x < len ; x++)
65 buf2[x+1] = buf[x];
66
67 if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
68 printk ("%s: i2c write error (addr %02x, err == %i)\n",
69 __FUNCTION__, state->config->demod_address, err);
70 return -EREMOTEIO;
71 }
72
73 return 0;
74}
75
76static u8 i2c_readbytes (struct nxt2002_state* state, u8 reg, u8* buf, u8 len)
77{
78 u8 reg2 [] = { reg };
79
80 struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = reg2, .len = 1 },
81 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = buf, .len = len } };
82
83 int err;
84
85 if ((err = i2c_transfer (state->i2c, msg, 2)) != 2) {
86 printk ("%s: i2c read error (addr %02x, err == %i)\n",
87 __FUNCTION__, state->config->demod_address, err);
88 return -EREMOTEIO;
89 }
90
91 return 0;
92}
93
94static u16 nxt2002_crc(u16 crc, u8 c)
95{
96
97 u8 i;
98 u16 input = (u16) c & 0xFF;
99
100 input<<=8;
101 for(i=0 ;i<8 ;i++) {
102 if((crc ^ input) & 0x8000)
103 crc=(crc<<1)^CRC_CCIT_MASK;
104 else
105 crc<<=1;
106 input<<=1;
107 }
108 return crc;
109}
110
111static int nxt2002_writereg_multibyte (struct nxt2002_state* state, u8 reg, u8* data, u8 len)
112{
113 u8 buf;
114 dprintk("%s\n", __FUNCTION__);
115
116 /* set multi register length */
117 i2c_writebytes(state,0x34,&len,1);
118
119 /* set mutli register register */
120 i2c_writebytes(state,0x35,&reg,1);
121
122 /* send the actual data */
123 i2c_writebytes(state,0x36,data,len);
124
125 /* toggle the multireg write bit*/
126 buf = 0x02;
127 i2c_writebytes(state,0x21,&buf,1);
128
129 i2c_readbytes(state,0x21,&buf,1);
130
131 if ((buf & 0x02) == 0)
132 return 0;
133
134 dprintk("Error writing multireg register %02X\n",reg);
135
136 return 0;
137}
138
139static int nxt2002_readreg_multibyte (struct nxt2002_state* state, u8 reg, u8* data, u8 len)
140{
141 u8 len2;
142 dprintk("%s\n", __FUNCTION__);
143
144 /* set multi register length */
145 len2 = len & 0x80;
146 i2c_writebytes(state,0x34,&len2,1);
147
148 /* set mutli register register */
149 i2c_writebytes(state,0x35,&reg,1);
150
151 /* send the actual data */
152 i2c_readbytes(state,reg,data,len);
153
154 return 0;
155}
156
157static void nxt2002_microcontroller_stop (struct nxt2002_state* state)
158{
159 u8 buf[2],counter = 0;
160 dprintk("%s\n", __FUNCTION__);
161
162 buf[0] = 0x80;
163 i2c_writebytes(state,0x22,buf,1);
164
165 while (counter < 20) {
166 i2c_readbytes(state,0x31,buf,1);
167 if (buf[0] & 0x40)
168 return;
169 msleep(10);
170 counter++;
171 }
172
173 dprintk("Timeout waiting for micro to stop.. This is ok after firmware upload\n");
174 return;
175}
176
177static void nxt2002_microcontroller_start (struct nxt2002_state* state)
178{
179 u8 buf;
180 dprintk("%s\n", __FUNCTION__);
181
182 buf = 0x00;
183 i2c_writebytes(state,0x22,&buf,1);
184}
185
186static int nxt2002_writetuner (struct nxt2002_state* state, u8* data)
187{
188 u8 buf,count = 0;
189
190 dprintk("Tuner Bytes: %02X %02X %02X %02X\n",data[0],data[1],data[2],data[3]);
191
192 dprintk("%s\n", __FUNCTION__);
193 /* stop the micro first */
194 nxt2002_microcontroller_stop(state);
195
196 /* set the i2c transfer speed to the tuner */
197 buf = 0x03;
198 i2c_writebytes(state,0x20,&buf,1);
199
200 /* setup to transfer 4 bytes via i2c */
201 buf = 0x04;
202 i2c_writebytes(state,0x34,&buf,1);
203
204 /* write actual tuner bytes */
205 i2c_writebytes(state,0x36,data,4);
206
207 /* set tuner i2c address */
208 buf = 0xC2;
209 i2c_writebytes(state,0x35,&buf,1);
210
211 /* write UC Opmode to begin transfer */
212 buf = 0x80;
213 i2c_writebytes(state,0x21,&buf,1);
214
215 while (count < 20) {
216 i2c_readbytes(state,0x21,&buf,1);
217 if ((buf & 0x80)== 0x00)
218 return 0;
219 msleep(100);
220 count++;
221 }
222
223 printk("nxt2002: timeout error writing tuner\n");
224 return 0;
225}
226
227static void nxt2002_agc_reset(struct nxt2002_state* state)
228{
229 u8 buf;
230 dprintk("%s\n", __FUNCTION__);
231
232 buf = 0x08;
233 i2c_writebytes(state,0x08,&buf,1);
234
235 buf = 0x00;
236 i2c_writebytes(state,0x08,&buf,1);
237
238 return;
239}
240
241static int nxt2002_load_firmware (struct dvb_frontend* fe, const struct firmware *fw)
242{
243
244 struct nxt2002_state* state = (struct nxt2002_state*) fe->demodulator_priv;
245 u8 buf[256],written = 0,chunkpos = 0;
246 u16 rambase,position,crc = 0;
247
248 dprintk("%s\n", __FUNCTION__);
249 dprintk("Firmware is %zu bytes\n",fw->size);
250
251 /* Get the RAM base for this nxt2002 */
252 i2c_readbytes(state,0x10,buf,1);
253
254 if (buf[0] & 0x10)
255 rambase = 0x1000;
256 else
257 rambase = 0x0000;
258
259 dprintk("rambase on this nxt2002 is %04X\n",rambase);
260
261 /* Hold the micro in reset while loading firmware */
262 buf[0] = 0x80;
263 i2c_writebytes(state,0x2B,buf,1);
264
265 for (position = 0; position < fw->size ; position++) {
266 if (written == 0) {
267 crc = 0;
268 chunkpos = 0x28;
269 buf[0] = ((rambase + position) >> 8);
270 buf[1] = (rambase + position) & 0xFF;
271 buf[2] = 0x81;
272 /* write starting address */
273 i2c_writebytes(state,0x29,buf,3);
274 }
275 written++;
276 chunkpos++;
277
278 if ((written % 4) == 0)
279 i2c_writebytes(state,chunkpos,&fw->data[position-3],4);
280
281 crc = nxt2002_crc(crc,fw->data[position]);
282
283 if ((written == 255) || (position+1 == fw->size)) {
284 /* write remaining bytes of firmware */
285 i2c_writebytes(state, chunkpos+4-(written %4),
286 &fw->data[position-(written %4) + 1],
287 written %4);
288 buf[0] = crc << 8;
289 buf[1] = crc & 0xFF;
290
291 /* write crc */
292 i2c_writebytes(state,0x2C,buf,2);
293
294 /* do a read to stop things */
295 i2c_readbytes(state,0x2A,buf,1);
296
297 /* set transfer mode to complete */
298 buf[0] = 0x80;
299 i2c_writebytes(state,0x2B,buf,1);
300
301 written = 0;
302 }
303 }
304
305 printk ("done.\n");
306 return 0;
307};
308
309static int nxt2002_setup_frontend_parameters (struct dvb_frontend* fe,
310 struct dvb_frontend_parameters *p)
311{
312 struct nxt2002_state* state = (struct nxt2002_state*) fe->demodulator_priv;
313 u32 freq = 0;
314 u16 tunerfreq = 0;
315 u8 buf[4];
316
317 freq = 44000 + ( p->frequency / 1000 );
318
319 dprintk("freq = %d p->frequency = %d\n",freq,p->frequency);
320
321 tunerfreq = freq * 24/4000;
322
323 buf[0] = (tunerfreq >> 8) & 0x7F;
324 buf[1] = (tunerfreq & 0xFF);
325
326 if (p->frequency <= 214000000) {
327 buf[2] = 0x84 + (0x06 << 3);
328 buf[3] = (p->frequency <= 172000000) ? 0x01 : 0x02;
329 } else if (p->frequency <= 721000000) {
330 buf[2] = 0x84 + (0x07 << 3);
331 buf[3] = (p->frequency <= 467000000) ? 0x02 : 0x08;
332 } else if (p->frequency <= 841000000) {
333 buf[2] = 0x84 + (0x0E << 3);
334 buf[3] = 0x08;
335 } else {
336 buf[2] = 0x84 + (0x0F << 3);
337 buf[3] = 0x02;
338 }
339
340 /* write frequency information */
341 nxt2002_writetuner(state,buf);
342
343 /* reset the agc now that tuning has been completed */
344 nxt2002_agc_reset(state);
345
346
347
348 /* set target power level */
349 switch (p->u.vsb.modulation) {
350 case QAM_64:
351 case QAM_256:
352 buf[0] = 0x74;
353 break;
354 case VSB_8:
355 buf[0] = 0x70;
356 break;
357 default:
358 return -EINVAL;
359 break;
360 }
361 i2c_writebytes(state,0x42,buf,1);
362
363 /* configure sdm */
364 buf[0] = 0x87;
365 i2c_writebytes(state,0x57,buf,1);
366
367 /* write sdm1 input */
368 buf[0] = 0x10;
369 buf[1] = 0x00;
370 nxt2002_writereg_multibyte(state,0x58,buf,2);
371
372 /* write sdmx input */
373 switch (p->u.vsb.modulation) {
374 case QAM_64:
375 buf[0] = 0x68;
376 break;
377 case QAM_256:
378 buf[0] = 0x64;
379 break;
380 case VSB_8:
381 buf[0] = 0x60;
382 break;
383 default:
384 return -EINVAL;
385 break;
386 }
387 buf[1] = 0x00;
388 nxt2002_writereg_multibyte(state,0x5C,buf,2);
389
390 /* write adc power lpf fc */
391 buf[0] = 0x05;
392 i2c_writebytes(state,0x43,buf,1);
393
394 /* write adc power lpf fc */
395 buf[0] = 0x05;
396 i2c_writebytes(state,0x43,buf,1);
397
398 /* write accumulator2 input */
399 buf[0] = 0x80;
400 buf[1] = 0x00;
401 nxt2002_writereg_multibyte(state,0x4B,buf,2);
402
403 /* write kg1 */
404 buf[0] = 0x00;
405 i2c_writebytes(state,0x4D,buf,1);
406
407 /* write sdm12 lpf fc */
408 buf[0] = 0x44;
409 i2c_writebytes(state,0x55,buf,1);
410
411 /* write agc control reg */
412 buf[0] = 0x04;
413 i2c_writebytes(state,0x41,buf,1);
414
415 /* write agc ucgp0 */
416 switch (p->u.vsb.modulation) {
417 case QAM_64:
418 buf[0] = 0x02;
419 break;
420 case QAM_256:
421 buf[0] = 0x03;
422 break;
423 case VSB_8:
424 buf[0] = 0x00;
425 break;
426 default:
427 return -EINVAL;
428 break;
429 }
430 i2c_writebytes(state,0x30,buf,1);
431
432 /* write agc control reg */
433 buf[0] = 0x00;
434 i2c_writebytes(state,0x41,buf,1);
435
436 /* write accumulator2 input */
437 buf[0] = 0x80;
438 buf[1] = 0x00;
439 nxt2002_writereg_multibyte(state,0x49,buf,2);
440 nxt2002_writereg_multibyte(state,0x4B,buf,2);
441
442 /* write agc control reg */
443 buf[0] = 0x04;
444 i2c_writebytes(state,0x41,buf,1);
445
446 nxt2002_microcontroller_start(state);
447
448 /* adjacent channel detection should be done here, but I don't
449 have any stations with this need so I cannot test it */
450
451 return 0;
452}
453
454static int nxt2002_read_status(struct dvb_frontend* fe, fe_status_t* status)
455{
456 struct nxt2002_state* state = (struct nxt2002_state*) fe->demodulator_priv;
457 u8 lock;
458 i2c_readbytes(state,0x31,&lock,1);
459
460 *status = 0;
461 if (lock & 0x20) {
462 *status |= FE_HAS_SIGNAL;
463 *status |= FE_HAS_CARRIER;
464 *status |= FE_HAS_VITERBI;
465 *status |= FE_HAS_SYNC;
466 *status |= FE_HAS_LOCK;
467 }
468 return 0;
469}
470
471static int nxt2002_read_ber(struct dvb_frontend* fe, u32* ber)
472{
473 struct nxt2002_state* state = (struct nxt2002_state*) fe->demodulator_priv;
474 u8 b[3];
475
476 nxt2002_readreg_multibyte(state,0xE6,b,3);
477
478 *ber = ((b[0] << 8) + b[1]) * 8;
479
480 return 0;
481}
482
483static int nxt2002_read_signal_strength(struct dvb_frontend* fe, u16* strength)
484{
485 struct nxt2002_state* state = (struct nxt2002_state*) fe->demodulator_priv;
486 u8 b[2];
487 u16 temp = 0;
488
489 /* setup to read cluster variance */
490 b[0] = 0x00;
491 i2c_writebytes(state,0xA1,b,1);
492
493 /* get multreg val */
494 nxt2002_readreg_multibyte(state,0xA6,b,2);
495
496 temp = (b[0] << 8) | b[1];
497 *strength = ((0x7FFF - temp) & 0x0FFF) * 16;
498
499 return 0;
500}
501
502static int nxt2002_read_snr(struct dvb_frontend* fe, u16* snr)
503{
504
505 struct nxt2002_state* state = (struct nxt2002_state*) fe->demodulator_priv;
506 u8 b[2];
507 u16 temp = 0, temp2;
508 u32 snrdb = 0;
509
510 /* setup to read cluster variance */
511 b[0] = 0x00;
512 i2c_writebytes(state,0xA1,b,1);
513
514 /* get multreg val from 0xA6 */
515 nxt2002_readreg_multibyte(state,0xA6,b,2);
516
517 temp = (b[0] << 8) | b[1];
518 temp2 = 0x7FFF - temp;
519
520 /* snr will be in db */
521 if (temp2 > 0x7F00)
522 snrdb = 1000*24 + ( 1000*(30-24) * ( temp2 - 0x7F00 ) / ( 0x7FFF - 0x7F00 ) );
523 else if (temp2 > 0x7EC0)
524 snrdb = 1000*18 + ( 1000*(24-18) * ( temp2 - 0x7EC0 ) / ( 0x7F00 - 0x7EC0 ) );
525 else if (temp2 > 0x7C00)
526 snrdb = 1000*12 + ( 1000*(18-12) * ( temp2 - 0x7C00 ) / ( 0x7EC0 - 0x7C00 ) );
527 else
528 snrdb = 1000*0 + ( 1000*(12-0) * ( temp2 - 0 ) / ( 0x7C00 - 0 ) );
529
530 /* the value reported back from the frontend will be FFFF=32db 0000=0db */
531
532 *snr = snrdb * (0xFFFF/32000);
533
534 return 0;
535}
536
537static int nxt2002_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
538{
539 struct nxt2002_state* state = (struct nxt2002_state*) fe->demodulator_priv;
540 u8 b[3];
541
542 nxt2002_readreg_multibyte(state,0xE6,b,3);
543 *ucblocks = b[2];
544
545 return 0;
546}
547
548static int nxt2002_sleep(struct dvb_frontend* fe)
549{
550 return 0;
551}
552
553static int nxt2002_init(struct dvb_frontend* fe)
554{
555 struct nxt2002_state* state = (struct nxt2002_state*) fe->demodulator_priv;
556 const struct firmware *fw;
557 int ret;
558 u8 buf[2];
559
560 if (!state->initialised) {
561 /* request the firmware, this will block until someone uploads it */
562 printk("nxt2002: Waiting for firmware upload (%s)...\n", NXT2002_DEFAULT_FIRMWARE);
563 ret = state->config->request_firmware(fe, &fw, NXT2002_DEFAULT_FIRMWARE);
564 printk("nxt2002: Waiting for firmware upload(2)...\n");
565 if (ret) {
566 printk("nxt2002: no firmware upload (timeout or file not found?)\n");
567 return ret;
568 }
569
570 ret = nxt2002_load_firmware(fe, fw);
571 if (ret) {
572 printk("nxt2002: writing firmware to device failed\n");
573 release_firmware(fw);
574 return ret;
575 }
576 printk("nxt2002: firmware upload complete\n");
577
578 /* Put the micro into reset */
579 nxt2002_microcontroller_stop(state);
580
581 /* ensure transfer is complete */
582 buf[0]=0;
583 i2c_writebytes(state,0x2B,buf,1);
584
585 /* Put the micro into reset for real this time */
586 nxt2002_microcontroller_stop(state);
587
588 /* soft reset everything (agc,frontend,eq,fec)*/
589 buf[0] = 0x0F;
590 i2c_writebytes(state,0x08,buf,1);
591 buf[0] = 0x00;
592 i2c_writebytes(state,0x08,buf,1);
593
594 /* write agc sdm configure */
595 buf[0] = 0xF1;
596 i2c_writebytes(state,0x57,buf,1);
597
598 /* write mod output format */
599 buf[0] = 0x20;
600 i2c_writebytes(state,0x09,buf,1);
601
602 /* write fec mpeg mode */
603 buf[0] = 0x7E;
604 buf[1] = 0x00;
605 i2c_writebytes(state,0xE9,buf,2);
606
607 /* write mux selection */
608 buf[0] = 0x00;
609 i2c_writebytes(state,0xCC,buf,1);
610
611 state->initialised = 1;
612 }
613
614 return 0;
615}
616
617static int nxt2002_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
618{
619 fesettings->min_delay_ms = 500;
620 fesettings->step_size = 0;
621 fesettings->max_drift = 0;
622 return 0;
623}
624
625static void nxt2002_release(struct dvb_frontend* fe)
626{
627 struct nxt2002_state* state = (struct nxt2002_state*) fe->demodulator_priv;
628 kfree(state);
629}
630
631static struct dvb_frontend_ops nxt2002_ops;
632
633struct dvb_frontend* nxt2002_attach(const struct nxt2002_config* config,
634 struct i2c_adapter* i2c)
635{
636 struct nxt2002_state* state = NULL;
637 u8 buf [] = {0,0,0,0,0};
638
639 /* allocate memory for the internal state */
640 state = (struct nxt2002_state*) kmalloc(sizeof(struct nxt2002_state), GFP_KERNEL);
641 if (state == NULL) goto error;
642
643 /* setup the state */
644 state->config = config;
645 state->i2c = i2c;
646 memcpy(&state->ops, &nxt2002_ops, sizeof(struct dvb_frontend_ops));
647 state->initialised = 0;
648
649 /* Check the first 5 registers to ensure this a revision we can handle */
650
651 i2c_readbytes(state, 0x00, buf, 5);
652 if (buf[0] != 0x04) goto error; /* device id */
653 if (buf[1] != 0x02) goto error; /* fab id */
654 if (buf[2] != 0x11) goto error; /* month */
655 if (buf[3] != 0x20) goto error; /* year msb */
656 if (buf[4] != 0x00) goto error; /* year lsb */
657
658 /* create dvb_frontend */
659 state->frontend.ops = &state->ops;
660 state->frontend.demodulator_priv = state;
661 return &state->frontend;
662
663error:
664 kfree(state);
665 return NULL;
666}
667
668static struct dvb_frontend_ops nxt2002_ops = {
669
670 .info = {
671 .name = "Nextwave nxt2002 VSB/QAM frontend",
672 .type = FE_ATSC,
673 .frequency_min = 54000000,
674 .frequency_max = 860000000,
675 /* stepsize is just a guess */
676 .frequency_stepsize = 166666,
677 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
678 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
679 FE_CAN_8VSB | FE_CAN_QAM_64 | FE_CAN_QAM_256
680 },
681
682 .release = nxt2002_release,
683
684 .init = nxt2002_init,
685 .sleep = nxt2002_sleep,
686
687 .set_frontend = nxt2002_setup_frontend_parameters,
688 .get_tune_settings = nxt2002_get_tune_settings,
689
690 .read_status = nxt2002_read_status,
691 .read_ber = nxt2002_read_ber,
692 .read_signal_strength = nxt2002_read_signal_strength,
693 .read_snr = nxt2002_read_snr,
694 .read_ucblocks = nxt2002_read_ucblocks,
695
696};
697
698module_param(debug, int, 0644);
699MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
700
701MODULE_DESCRIPTION("NXT2002 ATSC (8VSB & ITU J83 AnnexB FEC QAM64/256) demodulator driver");
702MODULE_AUTHOR("Taylor Jacob");
703MODULE_LICENSE("GPL");
704
705EXPORT_SYMBOL(nxt2002_attach);
diff --git a/drivers/media/dvb/frontends/nxt2002.h b/drivers/media/dvb/frontends/nxt2002.h
new file mode 100644
index 000000000000..462301f577ee
--- /dev/null
+++ b/drivers/media/dvb/frontends/nxt2002.h
@@ -0,0 +1,23 @@
1/*
2 Driver for the Nxt2002 demodulator
3*/
4
5#ifndef NXT2002_H
6#define NXT2002_H
7
8#include <linux/dvb/frontend.h>
9#include <linux/firmware.h>
10
11struct nxt2002_config
12{
13 /* the demodulator's i2c address */
14 u8 demod_address;
15
16 /* request firmware for device */
17 int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name);
18};
19
20extern struct dvb_frontend* nxt2002_attach(const struct nxt2002_config* config,
21 struct i2c_adapter* i2c);
22
23#endif // NXT2002_H
diff --git a/drivers/media/dvb/frontends/nxt6000.c b/drivers/media/dvb/frontends/nxt6000.c
new file mode 100644
index 000000000000..a41f7da8b842
--- /dev/null
+++ b/drivers/media/dvb/frontends/nxt6000.c
@@ -0,0 +1,554 @@
1/*
2 NxtWave Communications - NXT6000 demodulator driver
3
4 Copyright (C) 2002-2003 Florian Schirmer <jolt@tuxbox.org>
5 Copyright (C) 2003 Paul Andreassen <paul@andreassen.com.au>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20*/
21
22#include <linux/init.h>
23#include <linux/kernel.h>
24#include <linux/module.h>
25#include <linux/string.h>
26#include <linux/slab.h>
27
28#include "dvb_frontend.h"
29#include "nxt6000_priv.h"
30#include "nxt6000.h"
31
32
33
34struct nxt6000_state {
35 struct i2c_adapter* i2c;
36 struct dvb_frontend_ops ops;
37 /* configuration settings */
38 const struct nxt6000_config* config;
39 struct dvb_frontend frontend;
40};
41
42static int debug = 0;
43#define dprintk if (debug) printk
44
45static int nxt6000_writereg(struct nxt6000_state* state, u8 reg, u8 data)
46{
47 u8 buf[] = { reg, data };
48 struct i2c_msg msg = {.addr = state->config->demod_address,.flags = 0,.buf = buf,.len = 2 };
49 int ret;
50
51 if ((ret = i2c_transfer(state->i2c, &msg, 1)) != 1)
52 dprintk("nxt6000: nxt6000_write error (reg: 0x%02X, data: 0x%02X, ret: %d)\n", reg, data, ret);
53
54 return (ret != 1) ? -EFAULT : 0;
55}
56
57static u8 nxt6000_readreg(struct nxt6000_state* state, u8 reg)
58{
59 int ret;
60 u8 b0[] = { reg };
61 u8 b1[] = { 0 };
62 struct i2c_msg msgs[] = {
63 {.addr = state->config->demod_address,.flags = 0,.buf = b0,.len = 1},
64 {.addr = state->config->demod_address,.flags = I2C_M_RD,.buf = b1,.len = 1}
65 };
66
67 ret = i2c_transfer(state->i2c, msgs, 2);
68
69 if (ret != 2)
70 dprintk("nxt6000: nxt6000_read error (reg: 0x%02X, ret: %d)\n", reg, ret);
71
72 return b1[0];
73}
74
75static void nxt6000_reset(struct nxt6000_state* state)
76{
77 u8 val;
78
79 val = nxt6000_readreg(state, OFDM_COR_CTL);
80
81 nxt6000_writereg(state, OFDM_COR_CTL, val & ~COREACT);
82 nxt6000_writereg(state, OFDM_COR_CTL, val | COREACT);
83}
84
85static int nxt6000_set_bandwidth(struct nxt6000_state* state, fe_bandwidth_t bandwidth)
86{
87 u16 nominal_rate;
88 int result;
89
90 switch (bandwidth) {
91
92 case BANDWIDTH_6_MHZ:
93 nominal_rate = 0x55B7;
94 break;
95
96 case BANDWIDTH_7_MHZ:
97 nominal_rate = 0x6400;
98 break;
99
100 case BANDWIDTH_8_MHZ:
101 nominal_rate = 0x7249;
102 break;
103
104 default:
105 return -EINVAL;
106 }
107
108 if ((result = nxt6000_writereg(state, OFDM_TRL_NOMINALRATE_1, nominal_rate & 0xFF)) < 0)
109 return result;
110
111 return nxt6000_writereg(state, OFDM_TRL_NOMINALRATE_2, (nominal_rate >> 8) & 0xFF);
112}
113
114static int nxt6000_set_guard_interval(struct nxt6000_state* state, fe_guard_interval_t guard_interval)
115{
116 switch (guard_interval) {
117
118 case GUARD_INTERVAL_1_32:
119 return nxt6000_writereg(state, OFDM_COR_MODEGUARD, 0x00 | (nxt6000_readreg(state, OFDM_COR_MODEGUARD) & ~0x03));
120
121 case GUARD_INTERVAL_1_16:
122 return nxt6000_writereg(state, OFDM_COR_MODEGUARD, 0x01 | (nxt6000_readreg(state, OFDM_COR_MODEGUARD) & ~0x03));
123
124 case GUARD_INTERVAL_AUTO:
125 case GUARD_INTERVAL_1_8:
126 return nxt6000_writereg(state, OFDM_COR_MODEGUARD, 0x02 | (nxt6000_readreg(state, OFDM_COR_MODEGUARD) & ~0x03));
127
128 case GUARD_INTERVAL_1_4:
129 return nxt6000_writereg(state, OFDM_COR_MODEGUARD, 0x03 | (nxt6000_readreg(state, OFDM_COR_MODEGUARD) & ~0x03));
130
131 default:
132 return -EINVAL;
133 }
134}
135
136static int nxt6000_set_inversion(struct nxt6000_state* state, fe_spectral_inversion_t inversion)
137{
138 switch (inversion) {
139
140 case INVERSION_OFF:
141 return nxt6000_writereg(state, OFDM_ITB_CTL, 0x00);
142
143 case INVERSION_ON:
144 return nxt6000_writereg(state, OFDM_ITB_CTL, ITBINV);
145
146 default:
147 return -EINVAL;
148
149 }
150}
151
152static int nxt6000_set_transmission_mode(struct nxt6000_state* state, fe_transmit_mode_t transmission_mode)
153{
154 int result;
155
156 switch (transmission_mode) {
157
158 case TRANSMISSION_MODE_2K:
159 if ((result = nxt6000_writereg(state, EN_DMD_RACQ, 0x00 | (nxt6000_readreg(state, EN_DMD_RACQ) & ~0x03))) < 0)
160 return result;
161
162 return nxt6000_writereg(state, OFDM_COR_MODEGUARD, (0x00 << 2) | (nxt6000_readreg(state, OFDM_COR_MODEGUARD) & ~0x04));
163
164 case TRANSMISSION_MODE_8K:
165 case TRANSMISSION_MODE_AUTO:
166 if ((result = nxt6000_writereg(state, EN_DMD_RACQ, 0x02 | (nxt6000_readreg(state, EN_DMD_RACQ) & ~0x03))) < 0)
167 return result;
168
169 return nxt6000_writereg(state, OFDM_COR_MODEGUARD, (0x01 << 2) | (nxt6000_readreg(state, OFDM_COR_MODEGUARD) & ~0x04));
170
171 default:
172 return -EINVAL;
173
174 }
175}
176
177static void nxt6000_setup(struct dvb_frontend* fe)
178{
179 struct nxt6000_state* state = (struct nxt6000_state*) fe->demodulator_priv;
180
181 nxt6000_writereg(state, RS_COR_SYNC_PARAM, SYNC_PARAM);
182 nxt6000_writereg(state, BER_CTRL, /*(1 << 2) | */ (0x01 << 1) | 0x01);
183 nxt6000_writereg(state, VIT_COR_CTL, VIT_COR_RESYNC);
184 nxt6000_writereg(state, OFDM_COR_CTL, (0x01 << 5) | (nxt6000_readreg(state, OFDM_COR_CTL) & 0x0F));
185 nxt6000_writereg(state, OFDM_COR_MODEGUARD, FORCEMODE8K | 0x02);
186 nxt6000_writereg(state, OFDM_AGC_CTL, AGCLAST | INITIAL_AGC_BW);
187 nxt6000_writereg(state, OFDM_ITB_FREQ_1, 0x06);
188 nxt6000_writereg(state, OFDM_ITB_FREQ_2, 0x31);
189 nxt6000_writereg(state, OFDM_CAS_CTL, (0x01 << 7) | (0x02 << 3) | 0x04);
190 nxt6000_writereg(state, CAS_FREQ, 0xBB); /* CHECKME */
191 nxt6000_writereg(state, OFDM_SYR_CTL, 1 << 2);
192 nxt6000_writereg(state, OFDM_PPM_CTL_1, PPM256);
193 nxt6000_writereg(state, OFDM_TRL_NOMINALRATE_1, 0x49);
194 nxt6000_writereg(state, OFDM_TRL_NOMINALRATE_2, 0x72);
195 nxt6000_writereg(state, ANALOG_CONTROL_0, 1 << 5);
196 nxt6000_writereg(state, EN_DMD_RACQ, (1 << 7) | (3 << 4) | 2);
197 nxt6000_writereg(state, DIAG_CONFIG, TB_SET);
198
199 if (state->config->clock_inversion)
200 nxt6000_writereg(state, SUB_DIAG_MODE_SEL, CLKINVERSION);
201 else
202 nxt6000_writereg(state, SUB_DIAG_MODE_SEL, 0);
203
204 nxt6000_writereg(state, TS_FORMAT, 0);
205
206 if (state->config->pll_init) {
207 nxt6000_writereg(state, ENABLE_TUNER_IIC, 0x01); /* open i2c bus switch */
208 state->config->pll_init(fe);
209 nxt6000_writereg(state, ENABLE_TUNER_IIC, 0x00); /* close i2c bus switch */
210 }
211}
212
213static void nxt6000_dump_status(struct nxt6000_state *state)
214{
215 u8 val;
216
217/*
218 printk("RS_COR_STAT: 0x%02X\n", nxt6000_readreg(fe, RS_COR_STAT));
219 printk("VIT_SYNC_STATUS: 0x%02X\n", nxt6000_readreg(fe, VIT_SYNC_STATUS));
220 printk("OFDM_COR_STAT: 0x%02X\n", nxt6000_readreg(fe, OFDM_COR_STAT));
221 printk("OFDM_SYR_STAT: 0x%02X\n", nxt6000_readreg(fe, OFDM_SYR_STAT));
222 printk("OFDM_TPS_RCVD_1: 0x%02X\n", nxt6000_readreg(fe, OFDM_TPS_RCVD_1));
223 printk("OFDM_TPS_RCVD_2: 0x%02X\n", nxt6000_readreg(fe, OFDM_TPS_RCVD_2));
224 printk("OFDM_TPS_RCVD_3: 0x%02X\n", nxt6000_readreg(fe, OFDM_TPS_RCVD_3));
225 printk("OFDM_TPS_RCVD_4: 0x%02X\n", nxt6000_readreg(fe, OFDM_TPS_RCVD_4));
226 printk("OFDM_TPS_RESERVED_1: 0x%02X\n", nxt6000_readreg(fe, OFDM_TPS_RESERVED_1));
227 printk("OFDM_TPS_RESERVED_2: 0x%02X\n", nxt6000_readreg(fe, OFDM_TPS_RESERVED_2));
228*/
229 printk("NXT6000 status:");
230
231 val = nxt6000_readreg(state, RS_COR_STAT);
232
233 printk(" DATA DESCR LOCK: %d,", val & 0x01);
234 printk(" DATA SYNC LOCK: %d,", (val >> 1) & 0x01);
235
236 val = nxt6000_readreg(state, VIT_SYNC_STATUS);
237
238 printk(" VITERBI LOCK: %d,", (val >> 7) & 0x01);
239
240 switch ((val >> 4) & 0x07) {
241
242 case 0x00:
243 printk(" VITERBI CODERATE: 1/2,");
244 break;
245
246 case 0x01:
247 printk(" VITERBI CODERATE: 2/3,");
248 break;
249
250 case 0x02:
251 printk(" VITERBI CODERATE: 3/4,");
252 break;
253
254 case 0x03:
255 printk(" VITERBI CODERATE: 5/6,");
256 break;
257
258 case 0x04:
259 printk(" VITERBI CODERATE: 7/8,");
260 break;
261
262 default:
263 printk(" VITERBI CODERATE: Reserved,");
264
265 }
266
267 val = nxt6000_readreg(state, OFDM_COR_STAT);
268
269 printk(" CHCTrack: %d,", (val >> 7) & 0x01);
270 printk(" TPSLock: %d,", (val >> 6) & 0x01);
271 printk(" SYRLock: %d,", (val >> 5) & 0x01);
272 printk(" AGCLock: %d,", (val >> 4) & 0x01);
273
274 switch (val & 0x0F) {
275
276 case 0x00:
277 printk(" CoreState: IDLE,");
278 break;
279
280 case 0x02:
281 printk(" CoreState: WAIT_AGC,");
282 break;
283
284 case 0x03:
285 printk(" CoreState: WAIT_SYR,");
286 break;
287
288 case 0x04:
289 printk(" CoreState: WAIT_PPM,");
290 break;
291
292 case 0x01:
293 printk(" CoreState: WAIT_TRL,");
294 break;
295
296 case 0x05:
297 printk(" CoreState: WAIT_TPS,");
298 break;
299
300 case 0x06:
301 printk(" CoreState: MONITOR_TPS,");
302 break;
303
304 default:
305 printk(" CoreState: Reserved,");
306
307 }
308
309 val = nxt6000_readreg(state, OFDM_SYR_STAT);
310
311 printk(" SYRLock: %d,", (val >> 4) & 0x01);
312 printk(" SYRMode: %s,", (val >> 2) & 0x01 ? "8K" : "2K");
313
314 switch ((val >> 4) & 0x03) {
315
316 case 0x00:
317 printk(" SYRGuard: 1/32,");
318 break;
319
320 case 0x01:
321 printk(" SYRGuard: 1/16,");
322 break;
323
324 case 0x02:
325 printk(" SYRGuard: 1/8,");
326 break;
327
328 case 0x03:
329 printk(" SYRGuard: 1/4,");
330 break;
331 }
332
333 val = nxt6000_readreg(state, OFDM_TPS_RCVD_3);
334
335 switch ((val >> 4) & 0x07) {
336
337 case 0x00:
338 printk(" TPSLP: 1/2,");
339 break;
340
341 case 0x01:
342 printk(" TPSLP: 2/3,");
343 break;
344
345 case 0x02:
346 printk(" TPSLP: 3/4,");
347 break;
348
349 case 0x03:
350 printk(" TPSLP: 5/6,");
351 break;
352
353 case 0x04:
354 printk(" TPSLP: 7/8,");
355 break;
356
357 default:
358 printk(" TPSLP: Reserved,");
359
360 }
361
362 switch (val & 0x07) {
363
364 case 0x00:
365 printk(" TPSHP: 1/2,");
366 break;
367
368 case 0x01:
369 printk(" TPSHP: 2/3,");
370 break;
371
372 case 0x02:
373 printk(" TPSHP: 3/4,");
374 break;
375
376 case 0x03:
377 printk(" TPSHP: 5/6,");
378 break;
379
380 case 0x04:
381 printk(" TPSHP: 7/8,");
382 break;
383
384 default:
385 printk(" TPSHP: Reserved,");
386
387 }
388
389 val = nxt6000_readreg(state, OFDM_TPS_RCVD_4);
390
391 printk(" TPSMode: %s,", val & 0x01 ? "8K" : "2K");
392
393 switch ((val >> 4) & 0x03) {
394
395 case 0x00:
396 printk(" TPSGuard: 1/32,");
397 break;
398
399 case 0x01:
400 printk(" TPSGuard: 1/16,");
401 break;
402
403 case 0x02:
404 printk(" TPSGuard: 1/8,");
405 break;
406
407 case 0x03:
408 printk(" TPSGuard: 1/4,");
409 break;
410
411 }
412
413 /* Strange magic required to gain access to RF_AGC_STATUS */
414 nxt6000_readreg(state, RF_AGC_VAL_1);
415 val = nxt6000_readreg(state, RF_AGC_STATUS);
416 val = nxt6000_readreg(state, RF_AGC_STATUS);
417
418 printk(" RF AGC LOCK: %d,", (val >> 4) & 0x01);
419 printk("\n");
420}
421
422static int nxt6000_read_status(struct dvb_frontend* fe, fe_status_t* status)
423{
424 u8 core_status;
425 struct nxt6000_state* state = (struct nxt6000_state*) fe->demodulator_priv;
426
427 *status = 0;
428
429 core_status = nxt6000_readreg(state, OFDM_COR_STAT);
430
431 if (core_status & AGCLOCKED)
432 *status |= FE_HAS_SIGNAL;
433
434 if (nxt6000_readreg(state, OFDM_SYR_STAT) & GI14_SYR_LOCK)
435 *status |= FE_HAS_CARRIER;
436
437 if (nxt6000_readreg(state, VIT_SYNC_STATUS) & VITINSYNC)
438 *status |= FE_HAS_VITERBI;
439
440 if (nxt6000_readreg(state, RS_COR_STAT) & RSCORESTATUS)
441 *status |= FE_HAS_SYNC;
442
443 if ((core_status & TPSLOCKED) && (*status == (FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC)))
444 *status |= FE_HAS_LOCK;
445
446 if (debug)
447 nxt6000_dump_status(state);
448
449 return 0;
450}
451
452static int nxt6000_init(struct dvb_frontend* fe)
453{
454 struct nxt6000_state* state = (struct nxt6000_state*) fe->demodulator_priv;
455
456 nxt6000_reset(state);
457 nxt6000_setup(fe);
458
459 return 0;
460}
461
462static int nxt6000_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *param)
463{
464 struct nxt6000_state* state = (struct nxt6000_state*) fe->demodulator_priv;
465 int result;
466
467 nxt6000_writereg(state, ENABLE_TUNER_IIC, 0x01); /* open i2c bus switch */
468 state->config->pll_set(fe, param);
469 nxt6000_writereg(state, ENABLE_TUNER_IIC, 0x00); /* close i2c bus switch */
470
471 if ((result = nxt6000_set_bandwidth(state, param->u.ofdm.bandwidth)) < 0)
472 return result;
473 if ((result = nxt6000_set_guard_interval(state, param->u.ofdm.guard_interval)) < 0)
474 return result;
475 if ((result = nxt6000_set_transmission_mode(state, param->u.ofdm.transmission_mode)) < 0)
476 return result;
477 if ((result = nxt6000_set_inversion(state, param->inversion)) < 0)
478 return result;
479
480 return 0;
481}
482
483static void nxt6000_release(struct dvb_frontend* fe)
484{
485 struct nxt6000_state* state = (struct nxt6000_state*) fe->demodulator_priv;
486 kfree(state);
487}
488
489static struct dvb_frontend_ops nxt6000_ops;
490
491struct dvb_frontend* nxt6000_attach(const struct nxt6000_config* config,
492 struct i2c_adapter* i2c)
493{
494 struct nxt6000_state* state = NULL;
495
496 /* allocate memory for the internal state */
497 state = (struct nxt6000_state*) kmalloc(sizeof(struct nxt6000_state), GFP_KERNEL);
498 if (state == NULL) goto error;
499
500 /* setup the state */
501 state->config = config;
502 state->i2c = i2c;
503 memcpy(&state->ops, &nxt6000_ops, sizeof(struct dvb_frontend_ops));
504
505 /* check if the demod is there */
506 if (nxt6000_readreg(state, OFDM_MSC_REV) != NXT6000ASICDEVICE) goto error;
507
508 /* create dvb_frontend */
509 state->frontend.ops = &state->ops;
510 state->frontend.demodulator_priv = state;
511 return &state->frontend;
512
513error:
514 kfree(state);
515 return NULL;
516}
517
518static struct dvb_frontend_ops nxt6000_ops = {
519
520 .info = {
521 .name = "NxtWave NXT6000 DVB-T",
522 .type = FE_OFDM,
523 .frequency_min = 0,
524 .frequency_max = 863250000,
525 .frequency_stepsize = 62500,
526 /*.frequency_tolerance = *//* FIXME: 12% of SR */
527 .symbol_rate_min = 0, /* FIXME */
528 .symbol_rate_max = 9360000, /* FIXME */
529 .symbol_rate_tolerance = 4000,
530 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
531 FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 |
532 FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO |
533 FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
534 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
535 FE_CAN_HIERARCHY_AUTO,
536 },
537
538 .release = nxt6000_release,
539
540 .init = nxt6000_init,
541
542 .set_frontend = nxt6000_set_frontend,
543
544 .read_status = nxt6000_read_status,
545};
546
547module_param(debug, int, 0644);
548MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
549
550MODULE_DESCRIPTION("NxtWave NXT6000 DVB-T demodulator driver");
551MODULE_AUTHOR("Florian Schirmer");
552MODULE_LICENSE("GPL");
553
554EXPORT_SYMBOL(nxt6000_attach);
diff --git a/drivers/media/dvb/frontends/nxt6000.h b/drivers/media/dvb/frontends/nxt6000.h
new file mode 100644
index 000000000000..b7d9bead3002
--- /dev/null
+++ b/drivers/media/dvb/frontends/nxt6000.h
@@ -0,0 +1,43 @@
1/*
2 NxtWave Communications - NXT6000 demodulator driver
3
4 Copyright (C) 2002-2003 Florian Schirmer <jolt@tuxbox.org>
5 Copyright (C) 2003 Paul Andreassen <paul@andreassen.com.au>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20*/
21
22#ifndef NXT6000_H
23#define NXT6000_H
24
25#include <linux/dvb/frontend.h>
26
27struct nxt6000_config
28{
29 /* the demodulator's i2c address */
30 u8 demod_address;
31
32 /* should clock inversion be used? */
33 u8 clock_inversion:1;
34
35 /* PLL maintenance */
36 int (*pll_init)(struct dvb_frontend* fe);
37 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
38};
39
40extern struct dvb_frontend* nxt6000_attach(const struct nxt6000_config* config,
41 struct i2c_adapter* i2c);
42
43#endif // NXT6000_H
diff --git a/drivers/media/dvb/frontends/nxt6000_priv.h b/drivers/media/dvb/frontends/nxt6000_priv.h
new file mode 100644
index 000000000000..64b1a89b2a22
--- /dev/null
+++ b/drivers/media/dvb/frontends/nxt6000_priv.h
@@ -0,0 +1,265 @@
1/*
2 * Public Include File for DRV6000 users
3 * (ie. NxtWave Communications - NXT6000 demodulator driver)
4 *
5 * Copyright (C) 2001 NxtWave Communications, Inc.
6 *
7 */
8
9/* Nxt6000 Register Addresses and Bit Masks */
10
11/* Maximum Register Number */
12#define MAXNXT6000REG (0x9A)
13
14/* 0x1B A_VIT_BER_0 aka 0x3A */
15#define A_VIT_BER_0 (0x1B)
16
17/* 0x1D A_VIT_BER_TIMER_0 aka 0x38 */
18#define A_VIT_BER_TIMER_0 (0x1D)
19
20/* 0x21 RS_COR_STAT */
21#define RS_COR_STAT (0x21)
22#define RSCORESTATUS (0x03)
23
24/* 0x22 RS_COR_INTEN */
25#define RS_COR_INTEN (0x22)
26
27/* 0x23 RS_COR_INSTAT */
28#define RS_COR_INSTAT (0x23)
29#define INSTAT_ERROR (0x04)
30#define LOCK_LOSS_BITS (0x03)
31
32/* 0x24 RS_COR_SYNC_PARAM */
33#define RS_COR_SYNC_PARAM (0x24)
34#define SYNC_PARAM (0x03)
35
36/* 0x25 BER_CTRL */
37#define BER_CTRL (0x25)
38#define BER_ENABLE (0x02)
39#define BER_RESET (0x01)
40
41/* 0x26 BER_PAY */
42#define BER_PAY (0x26)
43
44/* 0x27 BER_PKT_L */
45#define BER_PKT_L (0x27)
46#define BER_PKTOVERFLOW (0x80)
47
48/* 0x30 VIT_COR_CTL */
49#define VIT_COR_CTL (0x30)
50#define BER_CONTROL (0x02)
51#define VIT_COR_MASK (0x82)
52#define VIT_COR_RESYNC (0x80)
53
54
55/* 0x32 VIT_SYNC_STATUS */
56#define VIT_SYNC_STATUS (0x32)
57#define VITINSYNC (0x80)
58
59/* 0x33 VIT_COR_INTEN */
60#define VIT_COR_INTEN (0x33)
61#define GLOBAL_ENABLE (0x80)
62
63/* 0x34 VIT_COR_INTSTAT */
64#define VIT_COR_INTSTAT (0x34)
65#define BER_DONE (0x08)
66#define BER_OVERFLOW (0x10)
67
68 /* 0x38 OFDM_BERTimer *//* Use the alias registers */
69#define A_VIT_BER_TIMER_0 (0x1D)
70
71 /* 0x3A VIT_BER_TIMER_0 *//* Use the alias registers */
72#define A_VIT_BER_0 (0x1B)
73
74/* 0x40 OFDM_COR_CTL */
75#define OFDM_COR_CTL (0x40)
76#define COREACT (0x20)
77#define HOLDSM (0x10)
78#define WAIT_AGC (0x02)
79#define WAIT_SYR (0x03)
80
81/* 0x41 OFDM_COR_STAT */
82#define OFDM_COR_STAT (0x41)
83#define COR_STATUS (0x0F)
84#define MONITOR_TPS (0x06)
85#define TPSLOCKED (0x40)
86#define AGCLOCKED (0x10)
87
88/* 0x42 OFDM_COR_INTEN */
89#define OFDM_COR_INTEN (0x42)
90#define TPSRCVBAD (0x04)
91#define TPSRCVCHANGED (0x02)
92#define TPSRCVUPDATE (0x01)
93
94/* 0x43 OFDM_COR_INSTAT */
95#define OFDM_COR_INSTAT (0x43)
96
97/* 0x44 OFDM_COR_MODEGUARD */
98#define OFDM_COR_MODEGUARD (0x44)
99#define FORCEMODE (0x08)
100#define FORCEMODE8K (0x04)
101
102/* 0x45 OFDM_AGC_CTL */
103#define OFDM_AGC_CTL (0x45)
104#define INITIAL_AGC_BW (0x08)
105#define AGCNEG (0x02)
106#define AGCLAST (0x10)
107
108/* 0x48 OFDM_AGC_TARGET */
109#define OFDM_AGC_TARGET (0x48)
110#define OFDM_AGC_TARGET_DEFAULT (0x28)
111#define OFDM_AGC_TARGET_IMPULSE (0x38)
112
113/* 0x49 OFDM_AGC_GAIN_1 */
114#define OFDM_AGC_GAIN_1 (0x49)
115
116/* 0x4B OFDM_ITB_CTL */
117#define OFDM_ITB_CTL (0x4B)
118#define ITBINV (0x01)
119
120/* 0x4C OFDM_ITB_FREQ_1 */
121#define OFDM_ITB_FREQ_1 (0x4C)
122
123/* 0x4D OFDM_ITB_FREQ_2 */
124#define OFDM_ITB_FREQ_2 (0x4D)
125
126/* 0x4E OFDM_CAS_CTL */
127#define OFDM_CAS_CTL (0x4E)
128#define ACSDIS (0x40)
129#define CCSEN (0x80)
130
131/* 0x4F CAS_FREQ */
132#define CAS_FREQ (0x4F)
133
134/* 0x51 OFDM_SYR_CTL */
135#define OFDM_SYR_CTL (0x51)
136#define SIXTH_ENABLE (0x80)
137#define SYR_TRACKING_DISABLE (0x01)
138
139/* 0x52 OFDM_SYR_STAT */
140#define OFDM_SYR_STAT (0x52)
141#define GI14_2K_SYR_LOCK (0x13)
142#define GI14_8K_SYR_LOCK (0x17)
143#define GI14_SYR_LOCK (0x10)
144
145/* 0x55 OFDM_SYR_OFFSET_1 */
146#define OFDM_SYR_OFFSET_1 (0x55)
147
148/* 0x56 OFDM_SYR_OFFSET_2 */
149#define OFDM_SYR_OFFSET_2 (0x56)
150
151/* 0x58 OFDM_SCR_CTL */
152#define OFDM_SCR_CTL (0x58)
153#define SYR_ADJ_DECAY_MASK (0x70)
154#define SYR_ADJ_DECAY (0x30)
155
156/* 0x59 OFDM_PPM_CTL_1 */
157#define OFDM_PPM_CTL_1 (0x59)
158#define PPMMAX_MASK (0x30)
159#define PPM256 (0x30)
160
161/* 0x5B OFDM_TRL_NOMINALRATE_1 */
162#define OFDM_TRL_NOMINALRATE_1 (0x5B)
163
164/* 0x5C OFDM_TRL_NOMINALRATE_2 */
165#define OFDM_TRL_NOMINALRATE_2 (0x5C)
166
167/* 0x5D OFDM_TRL_TIME_1 */
168#define OFDM_TRL_TIME_1 (0x5D)
169
170/* 0x60 OFDM_CRL_FREQ_1 */
171#define OFDM_CRL_FREQ_1 (0x60)
172
173/* 0x63 OFDM_CHC_CTL_1 */
174#define OFDM_CHC_CTL_1 (0x63)
175#define MANMEAN1 (0xF0);
176#define CHCFIR (0x01)
177
178/* 0x64 OFDM_CHC_SNR */
179#define OFDM_CHC_SNR (0x64)
180
181/* 0x65 OFDM_BDI_CTL */
182#define OFDM_BDI_CTL (0x65)
183#define LP_SELECT (0x02)
184
185/* 0x67 OFDM_TPS_RCVD_1 */
186#define OFDM_TPS_RCVD_1 (0x67)
187#define TPSFRAME (0x03)
188
189/* 0x68 OFDM_TPS_RCVD_2 */
190#define OFDM_TPS_RCVD_2 (0x68)
191
192/* 0x69 OFDM_TPS_RCVD_3 */
193#define OFDM_TPS_RCVD_3 (0x69)
194
195/* 0x6A OFDM_TPS_RCVD_4 */
196#define OFDM_TPS_RCVD_4 (0x6A)
197
198/* 0x6B OFDM_TPS_RESERVED_1 */
199#define OFDM_TPS_RESERVED_1 (0x6B)
200
201/* 0x6C OFDM_TPS_RESERVED_2 */
202#define OFDM_TPS_RESERVED_2 (0x6C)
203
204/* 0x73 OFDM_MSC_REV */
205#define OFDM_MSC_REV (0x73)
206
207/* 0x76 OFDM_SNR_CARRIER_2 */
208#define OFDM_SNR_CARRIER_2 (0x76)
209#define MEAN_MASK (0x80)
210#define MEANBIT (0x80)
211
212/* 0x80 ANALOG_CONTROL_0 */
213#define ANALOG_CONTROL_0 (0x80)
214#define POWER_DOWN_ADC (0x40)
215
216/* 0x81 ENABLE_TUNER_IIC */
217#define ENABLE_TUNER_IIC (0x81)
218#define ENABLE_TUNER_BIT (0x01)
219
220/* 0x82 EN_DMD_RACQ */
221#define EN_DMD_RACQ (0x82)
222#define EN_DMD_RACQ_REG_VAL (0x81)
223#define EN_DMD_RACQ_REG_VAL_14 (0x01)
224
225/* 0x84 SNR_COMMAND */
226#define SNR_COMMAND (0x84)
227#define SNRStat (0x80)
228
229/* 0x85 SNRCARRIERNUMBER_LSB */
230#define SNRCARRIERNUMBER_LSB (0x85)
231
232/* 0x87 SNRMINTHRESHOLD_LSB */
233#define SNRMINTHRESHOLD_LSB (0x87)
234
235/* 0x89 SNR_PER_CARRIER_LSB */
236#define SNR_PER_CARRIER_LSB (0x89)
237
238/* 0x8B SNRBELOWTHRESHOLD_LSB */
239#define SNRBELOWTHRESHOLD_LSB (0x8B)
240
241/* 0x91 RF_AGC_VAL_1 */
242#define RF_AGC_VAL_1 (0x91)
243
244/* 0x92 RF_AGC_STATUS */
245#define RF_AGC_STATUS (0x92)
246
247/* 0x98 DIAG_CONFIG */
248#define DIAG_CONFIG (0x98)
249#define DIAG_MASK (0x70)
250#define TB_SET (0x10)
251#define TRAN_SELECT (0x07)
252#define SERIAL_SELECT (0x01)
253
254/* 0x99 SUB_DIAG_MODE_SEL */
255#define SUB_DIAG_MODE_SEL (0x99)
256#define CLKINVERSION (0x01)
257
258/* 0x9A TS_FORMAT */
259#define TS_FORMAT (0x9A)
260#define ERROR_SENSE (0x08)
261#define VALID_SENSE (0x04)
262#define SYNC_SENSE (0x02)
263#define GATED_CLOCK (0x01)
264
265#define NXT6000ASICDEVICE (0x0b)
diff --git a/drivers/media/dvb/frontends/or51132.c b/drivers/media/dvb/frontends/or51132.c
new file mode 100644
index 000000000000..df5dee7760a3
--- /dev/null
+++ b/drivers/media/dvb/frontends/or51132.c
@@ -0,0 +1,628 @@
1/*
2 * Support for OR51132 (pcHDTV HD-3000) - VSB/QAM
3 *
4 * Copyright (C) 2005 Kirk Lapray <kirk_lapray@bigfoot.com>
5 *
6 * Based on code from Jack Kelliher (kelliher@xmission.com)
7 * Copyright (C) 2002 & pcHDTV, inc.
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/*
26 * This driver needs two external firmware files. Please copy
27 * "dvb-fe-or51132-vsb.fw" and "dvb-fe-or51132-qam.fw" to
28 * /usr/lib/hotplug/firmware/ or /lib/firmware/
29 * (depending on configuration of firmware hotplug).
30 */
31#define OR51132_VSB_FIRMWARE "dvb-fe-or51132-vsb.fw"
32#define OR51132_QAM_FIRMWARE "dvb-fe-or51132-qam.fw"
33
34#include <linux/kernel.h>
35#include <linux/module.h>
36#include <linux/moduleparam.h>
37#include <linux/init.h>
38#include <linux/delay.h>
39#include <asm/byteorder.h>
40
41#include "dvb_frontend.h"
42#include "dvb-pll.h"
43#include "or51132.h"
44
45static int debug;
46#define dprintk(args...) \
47 do { \
48 if (debug) printk(KERN_DEBUG "or51132: " args); \
49 } while (0)
50
51
52struct or51132_state
53{
54 struct i2c_adapter* i2c;
55 struct dvb_frontend_ops ops;
56
57 /* Configuration settings */
58 const struct or51132_config* config;
59
60 struct dvb_frontend frontend;
61
62 /* Demodulator private data */
63 fe_modulation_t current_modulation;
64
65 /* Tuner private data */
66 u32 current_frequency;
67};
68
69static int i2c_writebytes (struct or51132_state* state, u8 reg, u8 *buf, int len)
70{
71 int err;
72 struct i2c_msg msg;
73 msg.addr = reg;
74 msg.flags = 0;
75 msg.len = len;
76 msg.buf = buf;
77
78 if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {
79 printk(KERN_WARNING "or51132: i2c_writebytes error (addr %02x, err == %i)\n", reg, err);
80 return -EREMOTEIO;
81 }
82
83 return 0;
84}
85
86static u8 i2c_readbytes (struct or51132_state* state, u8 reg, u8* buf, int len)
87{
88 int err;
89 struct i2c_msg msg;
90 msg.addr = reg;
91 msg.flags = I2C_M_RD;
92 msg.len = len;
93 msg.buf = buf;
94
95 if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {
96 printk(KERN_WARNING "or51132: i2c_readbytes error (addr %02x, err == %i)\n", reg, err);
97 return -EREMOTEIO;
98 }
99
100 return 0;
101}
102
103static int or51132_load_firmware (struct dvb_frontend* fe, const struct firmware *fw)
104{
105 struct or51132_state* state = (struct or51132_state*) fe->demodulator_priv;
106 static u8 run_buf[] = {0x7F,0x01};
107 static u8 get_ver_buf[] = {0x04,0x00,0x30,0x00,0x00};
108 u8 rec_buf[14];
109 u8 cmd_buf[14];
110 u32 firmwareAsize, firmwareBsize;
111 int i,ret;
112
113 dprintk("Firmware is %Zd bytes\n",fw->size);
114
115 /* Get size of firmware A and B */
116 firmwareAsize = le32_to_cpu(*((u32*)fw->data));
117 dprintk("FirmwareA is %i bytes\n",firmwareAsize);
118 firmwareBsize = le32_to_cpu(*((u32*)(fw->data+4)));
119 dprintk("FirmwareB is %i bytes\n",firmwareBsize);
120
121 /* Upload firmware */
122 if ((ret = i2c_writebytes(state,state->config->demod_address,
123 &fw->data[8],firmwareAsize))) {
124 printk(KERN_WARNING "or51132: load_firmware error 1\n");
125 return ret;
126 }
127 msleep(1); /* 1ms */
128 if ((ret = i2c_writebytes(state,state->config->demod_address,
129 &fw->data[8+firmwareAsize],firmwareBsize))) {
130 printk(KERN_WARNING "or51132: load_firmware error 2\n");
131 return ret;
132 }
133 msleep(1); /* 1ms */
134
135 if ((ret = i2c_writebytes(state,state->config->demod_address,
136 run_buf,2))) {
137 printk(KERN_WARNING "or51132: load_firmware error 3\n");
138 return ret;
139 }
140
141 /* Wait at least 5 msec */
142 msleep(20); /* 10ms */
143
144 if ((ret = i2c_writebytes(state,state->config->demod_address,
145 run_buf,2))) {
146 printk(KERN_WARNING "or51132: load_firmware error 4\n");
147 return ret;
148 }
149
150 /* 50ms for operation to begin */
151 msleep(50);
152
153 /* Read back ucode version to besure we loaded correctly and are really up and running */
154 /* Get uCode version */
155 cmd_buf[0] = 0x10;
156 cmd_buf[1] = 0x10;
157 cmd_buf[2] = 0x00;
158 cmd_buf[3] = 0x00;
159 msleep(20); /* 20ms */
160 if ((ret = i2c_writebytes(state,state->config->demod_address,
161 cmd_buf,3))) {
162 printk(KERN_WARNING "or51132: load_firmware error a\n");
163 return ret;
164 }
165
166 cmd_buf[0] = 0x04;
167 cmd_buf[1] = 0x17;
168 cmd_buf[2] = 0x00;
169 cmd_buf[3] = 0x00;
170 msleep(20); /* 20ms */
171 if ((ret = i2c_writebytes(state,state->config->demod_address,
172 cmd_buf,2))) {
173 printk(KERN_WARNING "or51132: load_firmware error b\n");
174 return ret;
175 }
176
177 cmd_buf[0] = 0x00;
178 cmd_buf[1] = 0x00;
179 cmd_buf[2] = 0x00;
180 cmd_buf[3] = 0x00;
181 msleep(20); /* 20ms */
182 if ((ret = i2c_writebytes(state,state->config->demod_address,
183 cmd_buf,2))) {
184 printk(KERN_WARNING "or51132: load_firmware error c\n");
185 return ret;
186 }
187
188 for(i=0;i<4;i++) {
189 msleep(20); /* 20ms */
190 get_ver_buf[4] = i+1;
191 if ((ret = i2c_readbytes(state,state->config->demod_address,
192 &rec_buf[i*2],2))) {
193 printk(KERN_WARNING
194 "or51132: load_firmware error d - %d\n",i);
195 return ret;
196 }
197 }
198
199 printk(KERN_WARNING
200 "or51132: Version: %02X%02X%02X%02X-%02X%02X%02X%02X (%02X%01X-%01X-%02X%01X-%01X)\n",
201 rec_buf[1],rec_buf[0],rec_buf[3],rec_buf[2],
202 rec_buf[5],rec_buf[4],rec_buf[7],rec_buf[6],
203 rec_buf[3],rec_buf[2]>>4,rec_buf[2]&0x0f,
204 rec_buf[5],rec_buf[4]>>4,rec_buf[4]&0x0f);
205
206 cmd_buf[0] = 0x10;
207 cmd_buf[1] = 0x00;
208 cmd_buf[2] = 0x00;
209 cmd_buf[3] = 0x00;
210 msleep(20); /* 20ms */
211 if ((ret = i2c_writebytes(state,state->config->demod_address,
212 cmd_buf,3))) {
213 printk(KERN_WARNING "or51132: load_firmware error e\n");
214 return ret;
215 }
216 return 0;
217};
218
219static int or51132_init(struct dvb_frontend* fe)
220{
221 return 0;
222}
223
224static int or51132_read_ber(struct dvb_frontend* fe, u32* ber)
225{
226 *ber = 0;
227 return 0;
228}
229
230static int or51132_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
231{
232 *ucblocks = 0;
233 return 0;
234}
235
236static int or51132_sleep(struct dvb_frontend* fe)
237{
238 return 0;
239}
240
241static int or51132_setmode(struct dvb_frontend* fe)
242{
243 struct or51132_state* state = (struct or51132_state*) fe->demodulator_priv;
244 unsigned char cmd_buf[4];
245
246 dprintk("setmode %d\n",(int)state->current_modulation);
247 /* set operation mode in Receiver 1 register; */
248 cmd_buf[0] = 0x04;
249 cmd_buf[1] = 0x01;
250 switch (state->current_modulation) {
251 case QAM_256:
252 case QAM_64:
253 case QAM_AUTO:
254 /* Auto-deinterleave; MPEG ser, MPEG2tr, phase noise-high*/
255 cmd_buf[2] = 0x5F;
256 break;
257 case VSB_8:
258 /* Auto CH, Auto NTSC rej, MPEGser, MPEG2tr, phase noise-high*/
259 cmd_buf[2] = 0x50;
260 break;
261 default:
262 printk("setmode:Modulation set to unsupported value\n");
263 };
264 cmd_buf[3] = 0x00;
265 if (i2c_writebytes(state,state->config->demod_address,
266 cmd_buf,3)) {
267 printk(KERN_WARNING "or51132: set_mode error 1\n");
268 return -1;
269 }
270 dprintk("or51132: set #1 to %02x\n", cmd_buf[2]);
271
272 /* Set operation mode in Receiver 6 register */
273 cmd_buf[0] = 0x1C;
274 switch (state->current_modulation) {
275 case QAM_AUTO:
276 /* REC MODE Normal Carrier Lock */
277 cmd_buf[1] = 0x00;
278 /* Channel MODE Auto QAM64/256 */
279 cmd_buf[2] = 0x4f;
280 break;
281 case QAM_256:
282 /* REC MODE Normal Carrier Lock */
283 cmd_buf[1] = 0x00;
284 /* Channel MODE QAM256 */
285 cmd_buf[2] = 0x45;
286 break;
287 case QAM_64:
288 /* REC MODE Normal Carrier Lock */
289 cmd_buf[1] = 0x00;
290 /* Channel MODE QAM64 */
291 cmd_buf[2] = 0x43;
292 break;
293 case VSB_8:
294 /* REC MODE inv IF spectrum, Normal */
295 cmd_buf[1] = 0x03;
296 /* Channel MODE ATSC/VSB8 */
297 cmd_buf[2] = 0x06;
298 break;
299 default:
300 printk("setmode: Modulation set to unsupported value\n");
301 };
302 cmd_buf[3] = 0x00;
303 msleep(20); /* 20ms */
304 if (i2c_writebytes(state,state->config->demod_address,
305 cmd_buf,3)) {
306 printk(KERN_WARNING "or51132: set_mode error 2\n");
307 return -1;
308 }
309 dprintk("or51132: set #6 to 0x%02x%02x\n", cmd_buf[1], cmd_buf[2]);
310
311 return 0;
312}
313
314static int or51132_set_parameters(struct dvb_frontend* fe,
315 struct dvb_frontend_parameters *param)
316{
317 int ret;
318 u8 buf[4];
319 struct or51132_state* state = (struct or51132_state*) fe->demodulator_priv;
320 const struct firmware *fw;
321
322 /* Change only if we are actually changing the modulation */
323 if (state->current_modulation != param->u.vsb.modulation) {
324 switch(param->u.vsb.modulation) {
325 case VSB_8:
326 dprintk("set_parameters VSB MODE\n");
327 printk("or51132: Waiting for firmware upload(%s)...\n",
328 OR51132_VSB_FIRMWARE);
329 ret = request_firmware(&fw, OR51132_VSB_FIRMWARE,
330 &state->i2c->dev);
331 if (ret){
332 printk(KERN_WARNING "or51132: No firmware up"
333 "loaded(timeout or file not found?)\n");
334 return ret;
335 }
336 /* Set non-punctured clock for VSB */
337 state->config->set_ts_params(fe, 0);
338 break;
339 case QAM_AUTO:
340 case QAM_64:
341 case QAM_256:
342 dprintk("set_parameters QAM MODE\n");
343 printk("or51132: Waiting for firmware upload(%s)...\n",
344 OR51132_QAM_FIRMWARE);
345 ret = request_firmware(&fw, OR51132_QAM_FIRMWARE,
346 &state->i2c->dev);
347 if (ret){
348 printk(KERN_WARNING "or51132: No firmware up"
349 "loaded(timeout or file not found?)\n");
350 return ret;
351 }
352 /* Set punctured clock for QAM */
353 state->config->set_ts_params(fe, 1);
354 break;
355 default:
356 printk("or51132:Modulation type(%d) UNSUPPORTED\n",
357 param->u.vsb.modulation);
358 return -1;
359 };
360 ret = or51132_load_firmware(fe, fw);
361 release_firmware(fw);
362 if (ret) {
363 printk(KERN_WARNING "or51132: Writing firmware to "
364 "device failed!\n");
365 return ret;
366 }
367 printk("or51132: Firmware upload complete.\n");
368
369 state->current_modulation = param->u.vsb.modulation;
370 or51132_setmode(fe);
371 }
372
373 /* Change only if we are actually changing the channel */
374 if (state->current_frequency != param->frequency) {
375 dvb_pll_configure(state->config->pll_desc, buf,
376 param->frequency, 0);
377 dprintk("set_parameters tuner bytes: 0x%02x 0x%02x "
378 "0x%02x 0x%02x\n",buf[0],buf[1],buf[2],buf[3]);
379 if (i2c_writebytes(state, state->config->pll_address ,buf, 4))
380 printk(KERN_WARNING "or51132: set_parameters error "
381 "writing to tuner\n");
382
383 /* Set to current mode */
384 or51132_setmode(fe);
385
386 /* Update current frequency */
387 state->current_frequency = param->frequency;
388 }
389 return 0;
390}
391
392static int or51132_read_status(struct dvb_frontend* fe, fe_status_t* status)
393{
394 struct or51132_state* state = (struct or51132_state*) fe->demodulator_priv;
395 unsigned char rec_buf[2];
396 unsigned char snd_buf[2];
397 *status = 0;
398
399 /* Receiver Status */
400 snd_buf[0]=0x04;
401 snd_buf[1]=0x00;
402 msleep(30); /* 30ms */
403 if (i2c_writebytes(state,state->config->demod_address,snd_buf,2)) {
404 printk(KERN_WARNING "or51132: read_status write error\n");
405 return -1;
406 }
407 msleep(30); /* 30ms */
408 if (i2c_readbytes(state,state->config->demod_address,rec_buf,2)) {
409 printk(KERN_WARNING "or51132: read_status read error\n");
410 return -1;
411 }
412 dprintk("read_status %x %x\n",rec_buf[0],rec_buf[1]);
413
414 if (rec_buf[1] & 0x01) { /* Receiver Lock */
415 *status |= FE_HAS_SIGNAL;
416 *status |= FE_HAS_CARRIER;
417 *status |= FE_HAS_VITERBI;
418 *status |= FE_HAS_SYNC;
419 *status |= FE_HAS_LOCK;
420 }
421 return 0;
422}
423
424/* log10-1 table at .5 increments from 1 to 100.5 */
425static unsigned int i100x20log10[] = {
426 0, 352, 602, 795, 954, 1088, 1204, 1306, 1397, 1480,
427 1556, 1625, 1690, 1750, 1806, 1858, 1908, 1955, 2000, 2042,
428 2082, 2121, 2158, 2193, 2227, 2260, 2292, 2322, 2352, 2380,
429 2408, 2434, 2460, 2486, 2510, 2534, 2557, 2580, 2602, 2623,
430 2644, 2664, 2684, 2704, 2723, 2742, 2760, 2778, 2795, 2813,
431 2829, 2846, 2862, 2878, 2894, 2909, 2924, 2939, 2954, 2968,
432 2982, 2996, 3010, 3023, 3037, 3050, 3062, 3075, 3088, 3100,
433 3112, 3124, 3136, 3148, 3159, 3170, 3182, 3193, 3204, 3214,
434 3225, 3236, 3246, 3256, 3266, 3276, 3286, 3296, 3306, 3316,
435 3325, 3334, 3344, 3353, 3362, 3371, 3380, 3389, 3397, 3406,
436 3415, 3423, 3432, 3440, 3448, 3456, 3464, 3472, 3480, 3488,
437 3496, 3504, 3511, 3519, 3526, 3534, 3541, 3549, 3556, 3563,
438 3570, 3577, 3584, 3591, 3598, 3605, 3612, 3619, 3625, 3632,
439 3639, 3645, 3652, 3658, 3665, 3671, 3677, 3683, 3690, 3696,
440 3702, 3708, 3714, 3720, 3726, 3732, 3738, 3744, 3750, 3755,
441 3761, 3767, 3772, 3778, 3784, 3789, 3795, 3800, 3806, 3811,
442 3816, 3822, 3827, 3832, 3838, 3843, 3848, 3853, 3858, 3863,
443 3868, 3874, 3879, 3884, 3888, 3893, 3898, 3903, 3908, 3913,
444 3918, 3922, 3927, 3932, 3936, 3941, 3946, 3950, 3955, 3960,
445 3964, 3969, 3973, 3978, 3982, 3986, 3991, 3995, 4000, 4004,
446};
447
448static unsigned int denom[] = {1,1,100,1000,10000,100000,1000000,10000000,100000000};
449
450static unsigned int i20Log10(unsigned short val)
451{
452 unsigned int rntval = 100;
453 unsigned int tmp = val;
454 unsigned int exp = 1;
455
456 while(tmp > 100) {tmp /= 100; exp++;}
457
458 val = (2 * val)/denom[exp];
459 if (exp > 1) rntval = 2000*exp;
460
461 rntval += i100x20log10[val];
462 return rntval;
463}
464
465static int or51132_read_signal_strength(struct dvb_frontend* fe, u16* strength)
466{
467 struct or51132_state* state = (struct or51132_state*) fe->demodulator_priv;
468 unsigned char rec_buf[2];
469 unsigned char snd_buf[2];
470 u8 rcvr_stat;
471 u16 snr_equ;
472 int usK;
473
474 snd_buf[0]=0x04;
475 snd_buf[1]=0x02; /* SNR after Equalizer */
476 msleep(30); /* 30ms */
477 if (i2c_writebytes(state,state->config->demod_address,snd_buf,2)) {
478 printk(KERN_WARNING "or51132: read_status write error\n");
479 return -1;
480 }
481 msleep(30); /* 30ms */
482 if (i2c_readbytes(state,state->config->demod_address,rec_buf,2)) {
483 printk(KERN_WARNING "or51132: read_status read error\n");
484 return -1;
485 }
486 snr_equ = rec_buf[0] | (rec_buf[1] << 8);
487 dprintk("read_signal_strength snr_equ %x %x (%i)\n",rec_buf[0],rec_buf[1],snr_equ);
488
489 /* Receiver Status */
490 snd_buf[0]=0x04;
491 snd_buf[1]=0x00;
492 msleep(30); /* 30ms */
493 if (i2c_writebytes(state,state->config->demod_address,snd_buf,2)) {
494 printk(KERN_WARNING "or51132: read_signal_strength read_status write error\n");
495 return -1;
496 }
497 msleep(30); /* 30ms */
498 if (i2c_readbytes(state,state->config->demod_address,rec_buf,2)) {
499 printk(KERN_WARNING "or51132: read_signal_strength read_status read error\n");
500 return -1;
501 }
502 dprintk("read_signal_strength read_status %x %x\n",rec_buf[0],rec_buf[1]);
503 rcvr_stat = rec_buf[1];
504 usK = (rcvr_stat & 0x10) ? 3 : 0;
505
506 /* The value reported back from the frontend will be FFFF=100% 0000=0% */
507 *strength = (((8952 - i20Log10(snr_equ) - usK*100)/3+5)*65535)/1000;
508 dprintk("read_signal_strength %i\n",*strength);
509
510 return 0;
511}
512
513static int or51132_read_snr(struct dvb_frontend* fe, u16* snr)
514{
515 struct or51132_state* state = (struct or51132_state*) fe->demodulator_priv;
516 unsigned char rec_buf[2];
517 unsigned char snd_buf[2];
518 u16 snr_equ;
519
520 snd_buf[0]=0x04;
521 snd_buf[1]=0x02; /* SNR after Equalizer */
522 msleep(30); /* 30ms */
523 if (i2c_writebytes(state,state->config->demod_address,snd_buf,2)) {
524 printk(KERN_WARNING "or51132: read_snr write error\n");
525 return -1;
526 }
527 msleep(30); /* 30ms */
528 if (i2c_readbytes(state,state->config->demod_address,rec_buf,2)) {
529 printk(KERN_WARNING "or51132: read_snr dvr read error\n");
530 return -1;
531 }
532 snr_equ = rec_buf[0] | (rec_buf[1] << 8);
533 dprintk("read_snr snr_equ %x %x (%i)\n",rec_buf[0],rec_buf[1],snr_equ);
534
535 *snr = 0xFFFF - snr_equ;
536 dprintk("read_snr %i\n",*snr);
537
538 return 0;
539}
540
541static int or51132_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fe_tune_settings)
542{
543 fe_tune_settings->min_delay_ms = 500;
544 fe_tune_settings->step_size = 0;
545 fe_tune_settings->max_drift = 0;
546
547 return 0;
548}
549
550static void or51132_release(struct dvb_frontend* fe)
551{
552 struct or51132_state* state = (struct or51132_state*) fe->demodulator_priv;
553 kfree(state);
554}
555
556static struct dvb_frontend_ops or51132_ops;
557
558struct dvb_frontend* or51132_attach(const struct or51132_config* config,
559 struct i2c_adapter* i2c)
560{
561 struct or51132_state* state = NULL;
562
563 /* Allocate memory for the internal state */
564 state = kmalloc(sizeof(struct or51132_state), GFP_KERNEL);
565 if (state == NULL)
566 goto error;
567
568 /* Setup the state */
569 state->config = config;
570 state->i2c = i2c;
571 memcpy(&state->ops, &or51132_ops, sizeof(struct dvb_frontend_ops));
572 state->current_frequency = -1;
573 state->current_modulation = -1;
574
575 /* Create dvb_frontend */
576 state->frontend.ops = &state->ops;
577 state->frontend.demodulator_priv = state;
578 return &state->frontend;
579
580error:
581 if (state)
582 kfree(state);
583 return NULL;
584}
585
586static struct dvb_frontend_ops or51132_ops = {
587
588 .info = {
589 .name = "Oren OR51132 VSB/QAM Frontend",
590 .type = FE_ATSC,
591 .frequency_min = 44000000,
592 .frequency_max = 958000000,
593 .frequency_stepsize = 166666,
594 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
595 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
596 FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_QAM_AUTO |
597 FE_CAN_8VSB
598 },
599
600 .release = or51132_release,
601
602 .init = or51132_init,
603 .sleep = or51132_sleep,
604
605 .set_frontend = or51132_set_parameters,
606 .get_tune_settings = or51132_get_tune_settings,
607
608 .read_status = or51132_read_status,
609 .read_ber = or51132_read_ber,
610 .read_signal_strength = or51132_read_signal_strength,
611 .read_snr = or51132_read_snr,
612 .read_ucblocks = or51132_read_ucblocks,
613};
614
615module_param(debug, int, 0644);
616MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
617
618MODULE_DESCRIPTION("OR51132 ATSC [pcHDTV HD-3000] (8VSB & ITU J83 AnnexB FEC QAM64/256) Demodulator Driver");
619MODULE_AUTHOR("Kirk Lapray");
620MODULE_LICENSE("GPL");
621
622EXPORT_SYMBOL(or51132_attach);
623
624/*
625 * Local variables:
626 * c-basic-offset: 8
627 * End:
628 */
diff --git a/drivers/media/dvb/frontends/or51132.h b/drivers/media/dvb/frontends/or51132.h
new file mode 100644
index 000000000000..622cdd18381b
--- /dev/null
+++ b/drivers/media/dvb/frontends/or51132.h
@@ -0,0 +1,48 @@
1/*
2 * Support for OR51132 (pcHDTV HD-3000) - VSB/QAM
3 *
4 * Copyright (C) 2005 Kirk Lapray <kirk_lapray@bigfoot.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 *
20*/
21
22#ifndef OR51132_H
23#define OR51132_H
24
25#include <linux/firmware.h>
26#include <linux/dvb/frontend.h>
27
28struct or51132_config
29{
30 /* The demodulator's i2c address */
31 u8 demod_address;
32 u8 pll_address;
33 struct dvb_pll_desc *pll_desc;
34
35 /* Need to set device param for start_dma */
36 int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured);
37};
38
39extern struct dvb_frontend* or51132_attach(const struct or51132_config* config,
40 struct i2c_adapter* i2c);
41
42#endif // OR51132_H
43
44/*
45 * Local variables:
46 * c-basic-offset: 8
47 * End:
48 */
diff --git a/drivers/media/dvb/frontends/or51211.c b/drivers/media/dvb/frontends/or51211.c
new file mode 100644
index 000000000000..ad56a9958404
--- /dev/null
+++ b/drivers/media/dvb/frontends/or51211.c
@@ -0,0 +1,631 @@
1/*
2 * Support for OR51211 (pcHDTV HD-2000) - VSB
3 *
4 * Copyright (C) 2005 Kirk Lapray <kirk_lapray@bigfoot.com>
5 *
6 * Based on code from Jack Kelliher (kelliher@xmission.com)
7 * Copyright (C) 2002 & pcHDTV, inc.
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/*
26 * This driver needs external firmware. Please use the command
27 * "<kerneldir>/Documentation/dvb/get_dvb_firmware or51211" to
28 * download/extract it, and then copy it to /usr/lib/hotplug/firmware.
29 */
30#define OR51211_DEFAULT_FIRMWARE "dvb-fe-or51211.fw"
31
32#include <linux/kernel.h>
33#include <linux/module.h>
34#include <linux/moduleparam.h>
35#include <linux/device.h>
36#include <linux/firmware.h>
37#include <asm/byteorder.h>
38
39#include "dvb_frontend.h"
40#include "or51211.h"
41
42static int debug;
43#define dprintk(args...) \
44 do { \
45 if (debug) printk(KERN_DEBUG "or51211: " args); \
46 } while (0)
47
48static u8 run_buf[] = {0x7f,0x01};
49static u8 cmd_buf[] = {0x04,0x01,0x50,0x80,0x06}; // ATSC
50
51struct or51211_state {
52
53 struct i2c_adapter* i2c;
54 struct dvb_frontend_ops ops;
55
56 /* Configuration settings */
57 const struct or51211_config* config;
58
59 struct dvb_frontend frontend;
60 struct bt878* bt;
61
62 /* Demodulator private data */
63 u8 initialized:1;
64
65 /* Tuner private data */
66 u32 current_frequency;
67};
68
69static int i2c_writebytes (struct or51211_state* state, u8 reg, u8 *buf,
70 int len)
71{
72 int err;
73 struct i2c_msg msg;
74 msg.addr = reg;
75 msg.flags = 0;
76 msg.len = len;
77 msg.buf = buf;
78
79 if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
80 printk(KERN_WARNING "or51211: i2c_writebytes error "
81 "(addr %02x, err == %i)\n", reg, err);
82 return -EREMOTEIO;
83 }
84
85 return 0;
86}
87
88static u8 i2c_readbytes (struct or51211_state* state, u8 reg, u8* buf, int len)
89{
90 int err;
91 struct i2c_msg msg;
92 msg.addr = reg;
93 msg.flags = I2C_M_RD;
94 msg.len = len;
95 msg.buf = buf;
96
97 if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
98 printk(KERN_WARNING "or51211: i2c_readbytes error "
99 "(addr %02x, err == %i)\n", reg, err);
100 return -EREMOTEIO;
101 }
102
103 return 0;
104}
105
106static int or51211_load_firmware (struct dvb_frontend* fe,
107 const struct firmware *fw)
108{
109 struct or51211_state* state = fe->demodulator_priv;
110 u8 tudata[585];
111 int i;
112
113 dprintk("Firmware is %d bytes\n",fw->size);
114
115 /* Get eprom data */
116 tudata[0] = 17;
117 if (i2c_writebytes(state,0x50,tudata,1)) {
118 printk(KERN_WARNING "or51211:load_firmware error eprom addr\n");
119 return -1;
120 }
121 if (i2c_readbytes(state,0x50,&tudata[145],192)) {
122 printk(KERN_WARNING "or51211: load_firmware error eprom\n");
123 return -1;
124 }
125
126 /* Create firmware buffer */
127 for (i = 0; i < 145; i++)
128 tudata[i] = fw->data[i];
129
130 for (i = 0; i < 248; i++)
131 tudata[i+337] = fw->data[145+i];
132
133 state->config->reset(fe);
134
135 if (i2c_writebytes(state,state->config->demod_address,tudata,585)) {
136 printk(KERN_WARNING "or51211: load_firmware error 1\n");
137 return -1;
138 }
139 msleep(1);
140
141 if (i2c_writebytes(state,state->config->demod_address,
142 &fw->data[393],8125)) {
143 printk(KERN_WARNING "or51211: load_firmware error 2\n");
144 return -1;
145 }
146 msleep(1);
147
148 if (i2c_writebytes(state,state->config->demod_address,run_buf,2)) {
149 printk(KERN_WARNING "or51211: load_firmware error 3\n");
150 return -1;
151 }
152
153 /* Wait at least 5 msec */
154 msleep(10);
155 if (i2c_writebytes(state,state->config->demod_address,run_buf,2)) {
156 printk(KERN_WARNING "or51211: load_firmware error 4\n");
157 return -1;
158 }
159 msleep(10);
160
161 printk("or51211: Done.\n");
162 return 0;
163};
164
165static int or51211_setmode(struct dvb_frontend* fe, int mode)
166{
167 struct or51211_state* state = fe->demodulator_priv;
168 u8 rec_buf[14];
169
170 state->config->setmode(fe, mode);
171
172 if (i2c_writebytes(state,state->config->demod_address,run_buf,2)) {
173 printk(KERN_WARNING "or51211: setmode error 1\n");
174 return -1;
175 }
176
177 /* Wait at least 5 msec */
178 msleep(10);
179 if (i2c_writebytes(state,state->config->demod_address,run_buf,2)) {
180 printk(KERN_WARNING "or51211: setmode error 2\n");
181 return -1;
182 }
183
184 msleep(10);
185
186 /* Set operation mode in Receiver 1 register;
187 * type 1:
188 * data 0x50h Automatic sets receiver channel conditions
189 * Automatic NTSC rejection filter
190 * Enable MPEG serial data output
191 * MPEG2tr
192 * High tuner phase noise
193 * normal +/-150kHz Carrier acquisition range
194 */
195 if (i2c_writebytes(state,state->config->demod_address,cmd_buf,3)) {
196 printk(KERN_WARNING "or51211: setmode error 3\n");
197 return -1;
198 }
199
200 rec_buf[0] = 0x04;
201 rec_buf[1] = 0x00;
202 rec_buf[2] = 0x03;
203 rec_buf[3] = 0x00;
204 msleep(20);
205 if (i2c_writebytes(state,state->config->demod_address,rec_buf,3)) {
206 printk(KERN_WARNING "or51211: setmode error 5\n");
207 }
208 msleep(3);
209 if (i2c_readbytes(state,state->config->demod_address,&rec_buf[10],2)) {
210 printk(KERN_WARNING "or51211: setmode error 6");
211 return -1;
212 }
213 dprintk("setmode rec status %02x %02x\n",rec_buf[10],rec_buf[11]);
214
215 return 0;
216}
217
218static int or51211_set_parameters(struct dvb_frontend* fe,
219 struct dvb_frontend_parameters *param)
220{
221 struct or51211_state* state = fe->demodulator_priv;
222 u32 freq = 0;
223 u16 tunerfreq = 0;
224 u8 buf[4];
225
226 /* Change only if we are actually changing the channel */
227 if (state->current_frequency != param->frequency) {
228 freq = 44000 + (param->frequency/1000);
229 tunerfreq = freq * 16/1000;
230
231 dprintk("set_parameters frequency = %d (tunerfreq = %d)\n",
232 param->frequency,tunerfreq);
233
234 buf[0] = (tunerfreq >> 8) & 0x7F;
235 buf[1] = (tunerfreq & 0xFF);
236 buf[2] = 0x8E;
237
238 if (param->frequency < 157250000) {
239 buf[3] = 0xA0;
240 dprintk("set_parameters VHF low range\n");
241 } else if (param->frequency < 454000000) {
242 buf[3] = 0x90;
243 dprintk("set_parameters VHF high range\n");
244 } else {
245 buf[3] = 0x30;
246 dprintk("set_parameters UHF range\n");
247 }
248 dprintk("set_parameters tuner bytes: 0x%02x 0x%02x "
249 "0x%02x 0x%02x\n",buf[0],buf[1],buf[2],buf[3]);
250
251 if (i2c_writebytes(state,0xC2>>1,buf,4))
252 printk(KERN_WARNING "or51211:set_parameters error "
253 "writing to tuner\n");
254
255 /* Set to ATSC mode */
256 or51211_setmode(fe,0);
257
258 /* Update current frequency */
259 state->current_frequency = param->frequency;
260 }
261 return 0;
262}
263
264static int or51211_read_status(struct dvb_frontend* fe, fe_status_t* status)
265{
266 struct or51211_state* state = fe->demodulator_priv;
267 unsigned char rec_buf[2];
268 unsigned char snd_buf[] = {0x04,0x00,0x03,0x00};
269 *status = 0;
270
271 /* Receiver Status */
272 if (i2c_writebytes(state,state->config->demod_address,snd_buf,3)) {
273 printk(KERN_WARNING "or51132: read_status write error\n");
274 return -1;
275 }
276 msleep(3);
277 if (i2c_readbytes(state,state->config->demod_address,rec_buf,2)) {
278 printk(KERN_WARNING "or51132: read_status read error\n");
279 return -1;
280 }
281 dprintk("read_status %x %x\n",rec_buf[0],rec_buf[1]);
282
283 if (rec_buf[0] & 0x01) { /* Receiver Lock */
284 *status |= FE_HAS_SIGNAL;
285 *status |= FE_HAS_CARRIER;
286 *status |= FE_HAS_VITERBI;
287 *status |= FE_HAS_SYNC;
288 *status |= FE_HAS_LOCK;
289 }
290 return 0;
291}
292
293/* log10-1 table at .5 increments from 1 to 100.5 */
294static unsigned int i100x20log10[] = {
295 0, 352, 602, 795, 954, 1088, 1204, 1306, 1397, 1480,
296 1556, 1625, 1690, 1750, 1806, 1858, 1908, 1955, 2000, 2042,
297 2082, 2121, 2158, 2193, 2227, 2260, 2292, 2322, 2352, 2380,
298 2408, 2434, 2460, 2486, 2510, 2534, 2557, 2580, 2602, 2623,
299 2644, 2664, 2684, 2704, 2723, 2742, 2760, 2778, 2795, 2813,
300 2829, 2846, 2862, 2878, 2894, 2909, 2924, 2939, 2954, 2968,
301 2982, 2996, 3010, 3023, 3037, 3050, 3062, 3075, 3088, 3100,
302 3112, 3124, 3136, 3148, 3159, 3170, 3182, 3193, 3204, 3214,
303 3225, 3236, 3246, 3256, 3266, 3276, 3286, 3296, 3306, 3316,
304 3325, 3334, 3344, 3353, 3362, 3371, 3380, 3389, 3397, 3406,
305 3415, 3423, 3432, 3440, 3448, 3456, 3464, 3472, 3480, 3488,
306 3496, 3504, 3511, 3519, 3526, 3534, 3541, 3549, 3556, 3563,
307 3570, 3577, 3584, 3591, 3598, 3605, 3612, 3619, 3625, 3632,
308 3639, 3645, 3652, 3658, 3665, 3671, 3677, 3683, 3690, 3696,
309 3702, 3708, 3714, 3720, 3726, 3732, 3738, 3744, 3750, 3755,
310 3761, 3767, 3772, 3778, 3784, 3789, 3795, 3800, 3806, 3811,
311 3816, 3822, 3827, 3832, 3838, 3843, 3848, 3853, 3858, 3863,
312 3868, 3874, 3879, 3884, 3888, 3893, 3898, 3903, 3908, 3913,
313 3918, 3922, 3927, 3932, 3936, 3941, 3946, 3950, 3955, 3960,
314 3964, 3969, 3973, 3978, 3982, 3986, 3991, 3995, 4000, 4004,
315};
316
317static unsigned int denom[] = {1,1,100,1000,10000,100000,1000000,10000000,100000000};
318
319static unsigned int i20Log10(unsigned short val)
320{
321 unsigned int rntval = 100;
322 unsigned int tmp = val;
323 unsigned int exp = 1;
324
325 while(tmp > 100) {tmp /= 100; exp++;}
326
327 val = (2 * val)/denom[exp];
328 if (exp > 1) rntval = 2000*exp;
329
330 rntval += i100x20log10[val];
331 return rntval;
332}
333
334static int or51211_read_signal_strength(struct dvb_frontend* fe, u16* strength)
335{
336 struct or51211_state* state = fe->demodulator_priv;
337 u8 rec_buf[2];
338 u8 snd_buf[4];
339 u8 snr_equ;
340
341 /* SNR after Equalizer */
342 snd_buf[0] = 0x04;
343 snd_buf[1] = 0x00;
344 snd_buf[2] = 0x04;
345 snd_buf[3] = 0x00;
346
347 if (i2c_writebytes(state,state->config->demod_address,snd_buf,3)) {
348 printk(KERN_WARNING "or51211: read_status write error\n");
349 return -1;
350 }
351 msleep(3);
352 if (i2c_readbytes(state,state->config->demod_address,rec_buf,2)) {
353 printk(KERN_WARNING "or51211: read_status read error\n");
354 return -1;
355 }
356 snr_equ = rec_buf[0] & 0xff;
357
358 /* The value reported back from the frontend will be FFFF=100% 0000=0% */
359 *strength = (((5334 - i20Log10(snr_equ))/3+5)*65535)/1000;
360
361 dprintk("read_signal_strength %i\n",*strength);
362
363 return 0;
364}
365
366static int or51211_read_snr(struct dvb_frontend* fe, u16* snr)
367{
368 struct or51211_state* state = fe->demodulator_priv;
369 u8 rec_buf[2];
370 u8 snd_buf[4];
371
372 /* SNR after Equalizer */
373 snd_buf[0] = 0x04;
374 snd_buf[1] = 0x00;
375 snd_buf[2] = 0x04;
376 snd_buf[3] = 0x00;
377
378 if (i2c_writebytes(state,state->config->demod_address,snd_buf,3)) {
379 printk(KERN_WARNING "or51211: read_status write error\n");
380 return -1;
381 }
382 msleep(3);
383 if (i2c_readbytes(state,state->config->demod_address,rec_buf,2)) {
384 printk(KERN_WARNING "or51211: read_status read error\n");
385 return -1;
386 }
387 *snr = rec_buf[0] & 0xff;
388
389 dprintk("read_snr %i\n",*snr);
390
391 return 0;
392}
393
394static int or51211_read_ber(struct dvb_frontend* fe, u32* ber)
395{
396 *ber = -ENOSYS;
397 return 0;
398}
399
400static int or51211_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
401{
402 *ucblocks = -ENOSYS;
403 return 0;
404}
405
406static int or51211_sleep(struct dvb_frontend* fe)
407{
408 return 0;
409}
410
411static int or51211_init(struct dvb_frontend* fe)
412{
413 struct or51211_state* state = fe->demodulator_priv;
414 const struct or51211_config* config = state->config;
415 const struct firmware* fw;
416 unsigned char get_ver_buf[] = {0x04,0x00,0x30,0x00,0x00};
417 unsigned char rec_buf[14];
418 int ret,i;
419
420 if (!state->initialized) {
421 /* Request the firmware, this will block until it uploads */
422 printk(KERN_INFO "or51211: Waiting for firmware upload "
423 "(%s)...\n", OR51211_DEFAULT_FIRMWARE);
424 ret = config->request_firmware(fe, &fw,
425 OR51211_DEFAULT_FIRMWARE);
426 printk(KERN_INFO "or51211:Got Hotplug firmware\n");
427 if (ret) {
428 printk(KERN_WARNING "or51211: No firmware uploaded "
429 "(timeout or file not found?)\n");
430 return ret;
431 }
432
433 ret = or51211_load_firmware(fe, fw);
434 if (ret) {
435 printk(KERN_WARNING "or51211: Writing firmware to "
436 "device failed!\n");
437 release_firmware(fw);
438 return ret;
439 }
440 printk(KERN_INFO "or51211: Firmware upload complete.\n");
441
442 /* Set operation mode in Receiver 1 register;
443 * type 1:
444 * data 0x50h Automatic sets receiver channel conditions
445 * Automatic NTSC rejection filter
446 * Enable MPEG serial data output
447 * MPEG2tr
448 * High tuner phase noise
449 * normal +/-150kHz Carrier acquisition range
450 */
451 if (i2c_writebytes(state,state->config->demod_address,
452 cmd_buf,3)) {
453 printk(KERN_WARNING "or51211: Load DVR Error 5\n");
454 return -1;
455 }
456
457 /* Read back ucode version to besure we loaded correctly */
458 /* and are really up and running */
459 rec_buf[0] = 0x04;
460 rec_buf[1] = 0x00;
461 rec_buf[2] = 0x03;
462 rec_buf[3] = 0x00;
463 msleep(30);
464 if (i2c_writebytes(state,state->config->demod_address,
465 rec_buf,3)) {
466 printk(KERN_WARNING "or51211: Load DVR Error A\n");
467 return -1;
468 }
469 msleep(3);
470 if (i2c_readbytes(state,state->config->demod_address,
471 &rec_buf[10],2)) {
472 printk(KERN_WARNING "or51211: Load DVR Error B\n");
473 return -1;
474 }
475
476 rec_buf[0] = 0x04;
477 rec_buf[1] = 0x00;
478 rec_buf[2] = 0x01;
479 rec_buf[3] = 0x00;
480 msleep(20);
481 if (i2c_writebytes(state,state->config->demod_address,
482 rec_buf,3)) {
483 printk(KERN_WARNING "or51211: Load DVR Error C\n");
484 return -1;
485 }
486 msleep(3);
487 if (i2c_readbytes(state,state->config->demod_address,
488 &rec_buf[12],2)) {
489 printk(KERN_WARNING "or51211: Load DVR Error D\n");
490 return -1;
491 }
492
493 for (i = 0; i < 8; i++)
494 rec_buf[i]=0xed;
495
496 for (i = 0; i < 5; i++) {
497 msleep(30);
498 get_ver_buf[4] = i+1;
499 if (i2c_writebytes(state,state->config->demod_address,
500 get_ver_buf,5)) {
501 printk(KERN_WARNING "or51211:Load DVR Error 6"
502 " - %d\n",i);
503 return -1;
504 }
505 msleep(3);
506
507 if (i2c_readbytes(state,state->config->demod_address,
508 &rec_buf[i*2],2)) {
509 printk(KERN_WARNING "or51211:Load DVR Error 7"
510 " - %d\n",i);
511 return -1;
512 }
513 /* If we didn't receive the right index, try again */
514 if ((int)rec_buf[i*2+1]!=i+1){
515 i--;
516 }
517 }
518 dprintk("read_fwbits %x %x %x %x %x %x %x %x %x %x\n",
519 rec_buf[0], rec_buf[1], rec_buf[2], rec_buf[3],
520 rec_buf[4], rec_buf[5], rec_buf[6], rec_buf[7],
521 rec_buf[8], rec_buf[9]);
522
523 printk(KERN_INFO "or51211: ver TU%02x%02x%02x VSB mode %02x"
524 " Status %02x\n",
525 rec_buf[2], rec_buf[4],rec_buf[6],
526 rec_buf[12],rec_buf[10]);
527
528 rec_buf[0] = 0x04;
529 rec_buf[1] = 0x00;
530 rec_buf[2] = 0x03;
531 rec_buf[3] = 0x00;
532 msleep(20);
533 if (i2c_writebytes(state,state->config->demod_address,
534 rec_buf,3)) {
535 printk(KERN_WARNING "or51211: Load DVR Error 8\n");
536 return -1;
537 }
538 msleep(20);
539 if (i2c_readbytes(state,state->config->demod_address,
540 &rec_buf[8],2)) {
541 printk(KERN_WARNING "or51211: Load DVR Error 9\n");
542 return -1;
543 }
544 state->initialized = 1;
545 }
546
547 return 0;
548}
549
550static int or51211_get_tune_settings(struct dvb_frontend* fe,
551 struct dvb_frontend_tune_settings* fesettings)
552{
553 fesettings->min_delay_ms = 500;
554 fesettings->step_size = 0;
555 fesettings->max_drift = 0;
556 return 0;
557}
558
559static void or51211_release(struct dvb_frontend* fe)
560{
561 struct or51211_state* state = fe->demodulator_priv;
562 state->config->sleep(fe);
563 kfree(state);
564}
565
566static struct dvb_frontend_ops or51211_ops;
567
568struct dvb_frontend* or51211_attach(const struct or51211_config* config,
569 struct i2c_adapter* i2c)
570{
571 struct or51211_state* state = NULL;
572
573 /* Allocate memory for the internal state */
574 state = kmalloc(sizeof(struct or51211_state), GFP_KERNEL);
575 if (state == NULL)
576 goto error;
577
578 /* Setup the state */
579 state->config = config;
580 state->i2c = i2c;
581 memcpy(&state->ops, &or51211_ops, sizeof(struct dvb_frontend_ops));
582 state->initialized = 0;
583 state->current_frequency = 0;
584
585 /* Create dvb_frontend */
586 state->frontend.ops = &state->ops;
587 state->frontend.demodulator_priv = state;
588 return &state->frontend;
589
590error:
591 kfree(state);
592 return NULL;
593}
594
595static struct dvb_frontend_ops or51211_ops = {
596
597 .info = {
598 .name = "Oren OR51211 VSB Frontend",
599 .type = FE_ATSC,
600 .frequency_min = 44000000,
601 .frequency_max = 958000000,
602 .frequency_stepsize = 166666,
603 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
604 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
605 FE_CAN_8VSB
606 },
607
608 .release = or51211_release,
609
610 .init = or51211_init,
611 .sleep = or51211_sleep,
612
613 .set_frontend = or51211_set_parameters,
614 .get_tune_settings = or51211_get_tune_settings,
615
616 .read_status = or51211_read_status,
617 .read_ber = or51211_read_ber,
618 .read_signal_strength = or51211_read_signal_strength,
619 .read_snr = or51211_read_snr,
620 .read_ucblocks = or51211_read_ucblocks,
621};
622
623module_param(debug, int, 0644);
624MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
625
626MODULE_DESCRIPTION("Oren OR51211 VSB [pcHDTV HD-2000] Demodulator Driver");
627MODULE_AUTHOR("Kirk Lapray");
628MODULE_LICENSE("GPL");
629
630EXPORT_SYMBOL(or51211_attach);
631
diff --git a/drivers/media/dvb/frontends/or51211.h b/drivers/media/dvb/frontends/or51211.h
new file mode 100644
index 000000000000..13a5a3afbf8b
--- /dev/null
+++ b/drivers/media/dvb/frontends/or51211.h
@@ -0,0 +1,44 @@
1/*
2 * Support for OR51211 (pcHDTV HD-2000) - VSB
3 *
4 * Copyright (C) 2005 Kirk Lapray <kirk_lapray@bigfoot.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 *
20*/
21
22#ifndef OR51211_H
23#define OR51211_H
24
25#include <linux/dvb/frontend.h>
26#include <linux/firmware.h>
27
28struct or51211_config
29{
30 /* The demodulator's i2c address */
31 u8 demod_address;
32
33 /* Request firmware for device */
34 int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name);
35 void (*setmode)(struct dvb_frontend * fe, int mode);
36 void (*reset)(struct dvb_frontend * fe);
37 void (*sleep)(struct dvb_frontend * fe);
38};
39
40extern struct dvb_frontend* or51211_attach(const struct or51211_config* config,
41 struct i2c_adapter* i2c);
42
43#endif // OR51211_H
44
diff --git a/drivers/media/dvb/frontends/sp8870.c b/drivers/media/dvb/frontends/sp8870.c
new file mode 100644
index 000000000000..58ad34ef0a00
--- /dev/null
+++ b/drivers/media/dvb/frontends/sp8870.c
@@ -0,0 +1,614 @@
1/*
2 Driver for Spase SP8870 demodulator
3
4 Copyright (C) 1999 Juergen Peitz
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21*/
22/*
23 * This driver needs external firmware. Please use the command
24 * "<kerneldir>/Documentation/dvb/get_dvb_firmware alps_tdlb7" to
25 * download/extract it, and then copy it to /usr/lib/hotplug/firmware.
26 */
27#define SP8870_DEFAULT_FIRMWARE "dvb-fe-sp8870.fw"
28
29#include <linux/init.h>
30#include <linux/module.h>
31#include <linux/moduleparam.h>
32#include <linux/device.h>
33#include <linux/firmware.h>
34#include <linux/delay.h>
35
36#include "dvb_frontend.h"
37#include "sp8870.h"
38
39
40struct sp8870_state {
41
42 struct i2c_adapter* i2c;
43
44 struct dvb_frontend_ops ops;
45
46 const struct sp8870_config* config;
47
48 struct dvb_frontend frontend;
49
50 /* demodulator private data */
51 u8 initialised:1;
52};
53
54static int debug;
55#define dprintk(args...) \
56 do { \
57 if (debug) printk(KERN_DEBUG "sp8870: " args); \
58 } while (0)
59
60/* firmware size for sp8870 */
61#define SP8870_FIRMWARE_SIZE 16382
62
63/* starting point for firmware in file 'Sc_main.mc' */
64#define SP8870_FIRMWARE_OFFSET 0x0A
65
66static int sp8870_writereg (struct sp8870_state* state, u16 reg, u16 data)
67{
68 u8 buf [] = { reg >> 8, reg & 0xff, data >> 8, data & 0xff };
69 struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 4 };
70 int err;
71
72 if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
73 dprintk ("%s: writereg error (err == %i, reg == 0x%02x, data == 0x%02x)\n", __FUNCTION__, err, reg, data);
74 return -EREMOTEIO;
75 }
76
77 return 0;
78}
79
80static int sp8870_readreg (struct sp8870_state* state, u16 reg)
81{
82 int ret;
83 u8 b0 [] = { reg >> 8 , reg & 0xff };
84 u8 b1 [] = { 0, 0 };
85 struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 2 },
86 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 2 } };
87
88 ret = i2c_transfer (state->i2c, msg, 2);
89
90 if (ret != 2) {
91 dprintk("%s: readreg error (ret == %i)\n", __FUNCTION__, ret);
92 return -1;
93 }
94
95 return (b1[0] << 8 | b1[1]);
96}
97
98static int sp8870_firmware_upload (struct sp8870_state* state, const struct firmware *fw)
99{
100 struct i2c_msg msg;
101 char *fw_buf = fw->data;
102 int fw_pos;
103 u8 tx_buf[255];
104 int tx_len;
105 int err = 0;
106
107 dprintk ("%s: ...\n", __FUNCTION__);
108
109 if (fw->size < SP8870_FIRMWARE_SIZE + SP8870_FIRMWARE_OFFSET)
110 return -EINVAL;
111
112 // system controller stop
113 sp8870_writereg(state, 0x0F00, 0x0000);
114
115 // instruction RAM register hiword
116 sp8870_writereg(state, 0x8F08, ((SP8870_FIRMWARE_SIZE / 2) & 0xFFFF));
117
118 // instruction RAM MWR
119 sp8870_writereg(state, 0x8F0A, ((SP8870_FIRMWARE_SIZE / 2) >> 16));
120
121 // do firmware upload
122 fw_pos = SP8870_FIRMWARE_OFFSET;
123 while (fw_pos < SP8870_FIRMWARE_SIZE + SP8870_FIRMWARE_OFFSET){
124 tx_len = (fw_pos <= SP8870_FIRMWARE_SIZE + SP8870_FIRMWARE_OFFSET - 252) ? 252 : SP8870_FIRMWARE_SIZE + SP8870_FIRMWARE_OFFSET - fw_pos;
125 // write register 0xCF0A
126 tx_buf[0] = 0xCF;
127 tx_buf[1] = 0x0A;
128 memcpy(&tx_buf[2], fw_buf + fw_pos, tx_len);
129 msg.addr = state->config->demod_address;
130 msg.flags = 0;
131 msg.buf = tx_buf;
132 msg.len = tx_len + 2;
133 if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
134 printk("%s: firmware upload failed!\n", __FUNCTION__);
135 printk ("%s: i2c error (err == %i)\n", __FUNCTION__, err);
136 return err;
137 }
138 fw_pos += tx_len;
139 }
140
141 dprintk ("%s: done!\n", __FUNCTION__);
142 return 0;
143};
144
145static void sp8870_microcontroller_stop (struct sp8870_state* state)
146{
147 sp8870_writereg(state, 0x0F08, 0x000);
148 sp8870_writereg(state, 0x0F09, 0x000);
149
150 // microcontroller STOP
151 sp8870_writereg(state, 0x0F00, 0x000);
152}
153
154static void sp8870_microcontroller_start (struct sp8870_state* state)
155{
156 sp8870_writereg(state, 0x0F08, 0x000);
157 sp8870_writereg(state, 0x0F09, 0x000);
158
159 // microcontroller START
160 sp8870_writereg(state, 0x0F00, 0x001);
161 // not documented but if we don't read 0x0D01 out here
162 // we don't get a correct data valid signal
163 sp8870_readreg(state, 0x0D01);
164}
165
166static int sp8870_read_data_valid_signal(struct sp8870_state* state)
167{
168 return (sp8870_readreg(state, 0x0D02) > 0);
169}
170
171static int configure_reg0xc05 (struct dvb_frontend_parameters *p, u16 *reg0xc05)
172{
173 int known_parameters = 1;
174
175 *reg0xc05 = 0x000;
176
177 switch (p->u.ofdm.constellation) {
178 case QPSK:
179 break;
180 case QAM_16:
181 *reg0xc05 |= (1 << 10);
182 break;
183 case QAM_64:
184 *reg0xc05 |= (2 << 10);
185 break;
186 case QAM_AUTO:
187 known_parameters = 0;
188 break;
189 default:
190 return -EINVAL;
191 };
192
193 switch (p->u.ofdm.hierarchy_information) {
194 case HIERARCHY_NONE:
195 break;
196 case HIERARCHY_1:
197 *reg0xc05 |= (1 << 7);
198 break;
199 case HIERARCHY_2:
200 *reg0xc05 |= (2 << 7);
201 break;
202 case HIERARCHY_4:
203 *reg0xc05 |= (3 << 7);
204 break;
205 case HIERARCHY_AUTO:
206 known_parameters = 0;
207 break;
208 default:
209 return -EINVAL;
210 };
211
212 switch (p->u.ofdm.code_rate_HP) {
213 case FEC_1_2:
214 break;
215 case FEC_2_3:
216 *reg0xc05 |= (1 << 3);
217 break;
218 case FEC_3_4:
219 *reg0xc05 |= (2 << 3);
220 break;
221 case FEC_5_6:
222 *reg0xc05 |= (3 << 3);
223 break;
224 case FEC_7_8:
225 *reg0xc05 |= (4 << 3);
226 break;
227 case FEC_AUTO:
228 known_parameters = 0;
229 break;
230 default:
231 return -EINVAL;
232 };
233
234 if (known_parameters)
235 *reg0xc05 |= (2 << 1); /* use specified parameters */
236 else
237 *reg0xc05 |= (1 << 1); /* enable autoprobing */
238
239 return 0;
240}
241
242static int sp8870_wake_up(struct sp8870_state* state)
243{
244 // enable TS output and interface pins
245 return sp8870_writereg(state, 0xC18, 0x00D);
246}
247
248static int sp8870_set_frontend_parameters (struct dvb_frontend* fe,
249 struct dvb_frontend_parameters *p)
250{
251 struct sp8870_state* state = (struct sp8870_state*) fe->demodulator_priv;
252 int err;
253 u16 reg0xc05;
254
255 if ((err = configure_reg0xc05(p, &reg0xc05)))
256 return err;
257
258 // system controller stop
259 sp8870_microcontroller_stop(state);
260
261 // set tuner parameters
262 sp8870_writereg(state, 0x206, 0x001);
263 state->config->pll_set(fe, p);
264 sp8870_writereg(state, 0x206, 0x000);
265
266 // sample rate correction bit [23..17]
267 sp8870_writereg(state, 0x0319, 0x000A);
268
269 // sample rate correction bit [16..0]
270 sp8870_writereg(state, 0x031A, 0x0AAB);
271
272 // integer carrier offset
273 sp8870_writereg(state, 0x0309, 0x0400);
274
275 // fractional carrier offset
276 sp8870_writereg(state, 0x030A, 0x0000);
277
278 // filter for 6/7/8 Mhz channel
279 if (p->u.ofdm.bandwidth == BANDWIDTH_6_MHZ)
280 sp8870_writereg(state, 0x0311, 0x0002);
281 else if (p->u.ofdm.bandwidth == BANDWIDTH_7_MHZ)
282 sp8870_writereg(state, 0x0311, 0x0001);
283 else
284 sp8870_writereg(state, 0x0311, 0x0000);
285
286 // scan order: 2k first = 0x0000, 8k first = 0x0001
287 if (p->u.ofdm.transmission_mode == TRANSMISSION_MODE_2K)
288 sp8870_writereg(state, 0x0338, 0x0000);
289 else
290 sp8870_writereg(state, 0x0338, 0x0001);
291
292 sp8870_writereg(state, 0xc05, reg0xc05);
293
294 // read status reg in order to clear pending irqs
295 sp8870_readreg(state, 0x200);
296
297 // system controller start
298 sp8870_microcontroller_start(state);
299
300 return 0;
301}
302
303static int sp8870_init (struct dvb_frontend* fe)
304{
305 struct sp8870_state* state = (struct sp8870_state*) fe->demodulator_priv;
306 const struct firmware *fw = NULL;
307
308 sp8870_wake_up(state);
309 if (state->initialised) return 0;
310 state->initialised = 1;
311
312 dprintk ("%s\n", __FUNCTION__);
313
314
315 /* request the firmware, this will block until someone uploads it */
316 printk("sp8870: waiting for firmware upload (%s)...\n", SP8870_DEFAULT_FIRMWARE);
317 if (state->config->request_firmware(fe, &fw, SP8870_DEFAULT_FIRMWARE)) {
318 printk("sp8870: no firmware upload (timeout or file not found?)\n");
319 release_firmware(fw);
320 return -EIO;
321 }
322
323 if (sp8870_firmware_upload(state, fw)) {
324 printk("sp8870: writing firmware to device failed\n");
325 release_firmware(fw);
326 return -EIO;
327 }
328 printk("sp8870: firmware upload complete\n");
329
330 /* enable TS output and interface pins */
331 sp8870_writereg(state, 0xc18, 0x00d);
332
333 // system controller stop
334 sp8870_microcontroller_stop(state);
335
336 // ADC mode
337 sp8870_writereg(state, 0x0301, 0x0003);
338
339 // Reed Solomon parity bytes passed to output
340 sp8870_writereg(state, 0x0C13, 0x0001);
341
342 // MPEG clock is suppressed if no valid data
343 sp8870_writereg(state, 0x0C14, 0x0001);
344
345 /* bit 0x010: enable data valid signal */
346 sp8870_writereg(state, 0x0D00, 0x010);
347 sp8870_writereg(state, 0x0D01, 0x000);
348
349 /* setup PLL */
350 if (state->config->pll_init) {
351 sp8870_writereg(state, 0x206, 0x001);
352 state->config->pll_init(fe);
353 sp8870_writereg(state, 0x206, 0x000);
354 }
355
356 return 0;
357}
358
359static int sp8870_read_status (struct dvb_frontend* fe, fe_status_t * fe_status)
360{
361 struct sp8870_state* state = (struct sp8870_state*) fe->demodulator_priv;
362 int status;
363 int signal;
364
365 *fe_status = 0;
366
367 status = sp8870_readreg (state, 0x0200);
368 if (status < 0)
369 return -EIO;
370
371 signal = sp8870_readreg (state, 0x0303);
372 if (signal < 0)
373 return -EIO;
374
375 if (signal > 0x0F)
376 *fe_status |= FE_HAS_SIGNAL;
377 if (status & 0x08)
378 *fe_status |= FE_HAS_SYNC;
379 if (status & 0x04)
380 *fe_status |= FE_HAS_LOCK | FE_HAS_CARRIER | FE_HAS_VITERBI;
381
382 return 0;
383}
384
385static int sp8870_read_ber (struct dvb_frontend* fe, u32 * ber)
386{
387 struct sp8870_state* state = (struct sp8870_state*) fe->demodulator_priv;
388 int ret;
389 u32 tmp;
390
391 *ber = 0;
392
393 ret = sp8870_readreg(state, 0xC08);
394 if (ret < 0)
395 return -EIO;
396
397 tmp = ret & 0x3F;
398
399 ret = sp8870_readreg(state, 0xC07);
400 if (ret < 0)
401 return -EIO;
402
403 tmp = ret << 6;
404
405 if (tmp >= 0x3FFF0)
406 tmp = ~0;
407
408 *ber = tmp;
409
410 return 0;
411}
412
413static int sp8870_read_signal_strength(struct dvb_frontend* fe, u16 * signal)
414{
415 struct sp8870_state* state = (struct sp8870_state*) fe->demodulator_priv;
416 int ret;
417 u16 tmp;
418
419 *signal = 0;
420
421 ret = sp8870_readreg (state, 0x306);
422 if (ret < 0)
423 return -EIO;
424
425 tmp = ret << 8;
426
427 ret = sp8870_readreg (state, 0x303);
428 if (ret < 0)
429 return -EIO;
430
431 tmp |= ret;
432
433 if (tmp)
434 *signal = 0xFFFF - tmp;
435
436 return 0;
437}
438
439static int sp8870_read_uncorrected_blocks (struct dvb_frontend* fe, u32* ublocks)
440{
441 struct sp8870_state* state = (struct sp8870_state*) fe->demodulator_priv;
442 int ret;
443
444 *ublocks = 0;
445
446 ret = sp8870_readreg(state, 0xC0C);
447 if (ret < 0)
448 return -EIO;
449
450 if (ret == 0xFFFF)
451 ret = ~0;
452
453 *ublocks = ret;
454
455 return 0;
456}
457
458// number of trials to recover from lockup
459#define MAXTRIALS 5
460// maximum checks for data valid signal
461#define MAXCHECKS 100
462
463// only for debugging: counter for detected lockups
464static int lockups = 0;
465// only for debugging: counter for channel switches
466static int switches = 0;
467
468static int sp8870_set_frontend (struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
469{
470 struct sp8870_state* state = (struct sp8870_state*) fe->demodulator_priv;
471
472 /*
473 The firmware of the sp8870 sometimes locks up after setting frontend parameters.
474 We try to detect this by checking the data valid signal.
475 If it is not set after MAXCHECKS we try to recover the lockup by setting
476 the frontend parameters again.
477 */
478
479 int err = 0;
480 int valid = 0;
481 int trials = 0;
482 int check_count = 0;
483
484 dprintk("%s: frequency = %i\n", __FUNCTION__, p->frequency);
485
486 for (trials = 1; trials <= MAXTRIALS; trials++) {
487
488 if ((err = sp8870_set_frontend_parameters(fe, p)))
489 return err;
490
491 for (check_count = 0; check_count < MAXCHECKS; check_count++) {
492// valid = ((sp8870_readreg(i2c, 0x0200) & 4) == 0);
493 valid = sp8870_read_data_valid_signal(state);
494 if (valid) {
495 dprintk("%s: delay = %i usec\n",
496 __FUNCTION__, check_count * 10);
497 break;
498 }
499 udelay(10);
500 }
501 if (valid)
502 break;
503 }
504
505 if (!valid) {
506 printk("%s: firmware crash!!!!!!\n", __FUNCTION__);
507 return -EIO;
508 }
509
510 if (debug) {
511 if (valid) {
512 if (trials > 1) {
513 printk("%s: firmware lockup!!!\n", __FUNCTION__);
514 printk("%s: recovered after %i trial(s))\n", __FUNCTION__, trials - 1);
515 lockups++;
516 }
517 }
518 switches++;
519 printk("%s: switches = %i lockups = %i\n", __FUNCTION__, switches, lockups);
520 }
521
522 return 0;
523}
524
525static int sp8870_sleep(struct dvb_frontend* fe)
526{
527 struct sp8870_state* state = (struct sp8870_state*) fe->demodulator_priv;
528
529 // tristate TS output and disable interface pins
530 return sp8870_writereg(state, 0xC18, 0x000);
531}
532
533static int sp8870_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
534{
535 fesettings->min_delay_ms = 350;
536 fesettings->step_size = 0;
537 fesettings->max_drift = 0;
538 return 0;
539}
540
541static void sp8870_release(struct dvb_frontend* fe)
542{
543 struct sp8870_state* state = (struct sp8870_state*) fe->demodulator_priv;
544 kfree(state);
545}
546
547static struct dvb_frontend_ops sp8870_ops;
548
549struct dvb_frontend* sp8870_attach(const struct sp8870_config* config,
550 struct i2c_adapter* i2c)
551{
552 struct sp8870_state* state = NULL;
553
554 /* allocate memory for the internal state */
555 state = (struct sp8870_state*) kmalloc(sizeof(struct sp8870_state), GFP_KERNEL);
556 if (state == NULL) goto error;
557
558 /* setup the state */
559 state->config = config;
560 state->i2c = i2c;
561 memcpy(&state->ops, &sp8870_ops, sizeof(struct dvb_frontend_ops));
562 state->initialised = 0;
563
564 /* check if the demod is there */
565 if (sp8870_readreg(state, 0x0200) < 0) goto error;
566
567 /* create dvb_frontend */
568 state->frontend.ops = &state->ops;
569 state->frontend.demodulator_priv = state;
570 return &state->frontend;
571
572error:
573 kfree(state);
574 return NULL;
575}
576
577static struct dvb_frontend_ops sp8870_ops = {
578
579 .info = {
580 .name = "Spase SP8870 DVB-T",
581 .type = FE_OFDM,
582 .frequency_min = 470000000,
583 .frequency_max = 860000000,
584 .frequency_stepsize = 166666,
585 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
586 FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 |
587 FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
588 FE_CAN_QPSK | FE_CAN_QAM_16 |
589 FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
590 FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER
591 },
592
593 .release = sp8870_release,
594
595 .init = sp8870_init,
596 .sleep = sp8870_sleep,
597
598 .set_frontend = sp8870_set_frontend,
599 .get_tune_settings = sp8870_get_tune_settings,
600
601 .read_status = sp8870_read_status,
602 .read_ber = sp8870_read_ber,
603 .read_signal_strength = sp8870_read_signal_strength,
604 .read_ucblocks = sp8870_read_uncorrected_blocks,
605};
606
607module_param(debug, int, 0644);
608MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
609
610MODULE_DESCRIPTION("Spase SP8870 DVB-T Demodulator driver");
611MODULE_AUTHOR("Juergen Peitz");
612MODULE_LICENSE("GPL");
613
614EXPORT_SYMBOL(sp8870_attach);
diff --git a/drivers/media/dvb/frontends/sp8870.h b/drivers/media/dvb/frontends/sp8870.h
new file mode 100644
index 000000000000..f3b555dbc960
--- /dev/null
+++ b/drivers/media/dvb/frontends/sp8870.h
@@ -0,0 +1,45 @@
1/*
2 Driver for Spase SP8870 demodulator
3
4 Copyright (C) 1999 Juergen Peitz
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21*/
22
23#ifndef SP8870_H
24#define SP8870_H
25
26#include <linux/dvb/frontend.h>
27#include <linux/firmware.h>
28
29struct sp8870_config
30{
31 /* the demodulator's i2c address */
32 u8 demod_address;
33
34 /* PLL maintenance */
35 int (*pll_init)(struct dvb_frontend* fe);
36 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
37
38 /* request firmware for device */
39 int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name);
40};
41
42extern struct dvb_frontend* sp8870_attach(const struct sp8870_config* config,
43 struct i2c_adapter* i2c);
44
45#endif // SP8870_H
diff --git a/drivers/media/dvb/frontends/sp887x.c b/drivers/media/dvb/frontends/sp887x.c
new file mode 100644
index 000000000000..7eae833ece49
--- /dev/null
+++ b/drivers/media/dvb/frontends/sp887x.c
@@ -0,0 +1,606 @@
1/*
2 Driver for the Spase sp887x demodulator
3*/
4
5/*
6 * This driver needs external firmware. Please use the command
7 * "<kerneldir>/Documentation/dvb/get_dvb_firmware sp887x" to
8 * download/extract it, and then copy it to /usr/lib/hotplug/firmware.
9 */
10#define SP887X_DEFAULT_FIRMWARE "dvb-fe-sp887x.fw"
11
12#include <linux/init.h>
13#include <linux/module.h>
14#include <linux/moduleparam.h>
15#include <linux/device.h>
16#include <linux/firmware.h>
17
18#include "dvb_frontend.h"
19#include "sp887x.h"
20
21
22struct sp887x_state {
23 struct i2c_adapter* i2c;
24 struct dvb_frontend_ops ops;
25 const struct sp887x_config* config;
26 struct dvb_frontend frontend;
27
28 /* demodulator private data */
29 u8 initialised:1;
30};
31
32static int debug;
33#define dprintk(args...) \
34 do { \
35 if (debug) printk(KERN_DEBUG "sp887x: " args); \
36 } while (0)
37
38static int i2c_writebytes (struct sp887x_state* state, u8 *buf, u8 len)
39{
40 struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = len };
41 int err;
42
43 if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
44 printk ("%s: i2c write error (addr %02x, err == %i)\n",
45 __FUNCTION__, state->config->demod_address, err);
46 return -EREMOTEIO;
47 }
48
49 return 0;
50}
51
52static int sp887x_writereg (struct sp887x_state* state, u16 reg, u16 data)
53{
54 u8 b0 [] = { reg >> 8 , reg & 0xff, data >> 8, data & 0xff };
55 struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 4 };
56 int ret;
57
58 if ((ret = i2c_transfer(state->i2c, &msg, 1)) != 1) {
59 /**
60 * in case of soft reset we ignore ACK errors...
61 */
62 if (!(reg == 0xf1a && data == 0x000 &&
63 (ret == -EREMOTEIO || ret == -EFAULT)))
64 {
65 printk("%s: writereg error "
66 "(reg %03x, data %03x, ret == %i)\n",
67 __FUNCTION__, reg & 0xffff, data & 0xffff, ret);
68 return ret;
69 }
70 }
71
72 return 0;
73}
74
75static int sp887x_readreg (struct sp887x_state* state, u16 reg)
76{
77 u8 b0 [] = { reg >> 8 , reg & 0xff };
78 u8 b1 [2];
79 int ret;
80 struct i2c_msg msg[] = {{ .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 2 },
81 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 2 }};
82
83 if ((ret = i2c_transfer(state->i2c, msg, 2)) != 2) {
84 printk("%s: readreg error (ret == %i)\n", __FUNCTION__, ret);
85 return -1;
86 }
87
88 return (((b1[0] << 8) | b1[1]) & 0xfff);
89}
90
91static void sp887x_microcontroller_stop (struct sp887x_state* state)
92{
93 dprintk("%s\n", __FUNCTION__);
94 sp887x_writereg(state, 0xf08, 0x000);
95 sp887x_writereg(state, 0xf09, 0x000);
96
97 /* microcontroller STOP */
98 sp887x_writereg(state, 0xf00, 0x000);
99}
100
101static void sp887x_microcontroller_start (struct sp887x_state* state)
102{
103 dprintk("%s\n", __FUNCTION__);
104 sp887x_writereg(state, 0xf08, 0x000);
105 sp887x_writereg(state, 0xf09, 0x000);
106
107 /* microcontroller START */
108 sp887x_writereg(state, 0xf00, 0x001);
109}
110
111static void sp887x_setup_agc (struct sp887x_state* state)
112{
113 /* setup AGC parameters */
114 dprintk("%s\n", __FUNCTION__);
115 sp887x_writereg(state, 0x33c, 0x054);
116 sp887x_writereg(state, 0x33b, 0x04c);
117 sp887x_writereg(state, 0x328, 0x000);
118 sp887x_writereg(state, 0x327, 0x005);
119 sp887x_writereg(state, 0x326, 0x001);
120 sp887x_writereg(state, 0x325, 0x001);
121 sp887x_writereg(state, 0x324, 0x001);
122 sp887x_writereg(state, 0x318, 0x050);
123 sp887x_writereg(state, 0x317, 0x3fe);
124 sp887x_writereg(state, 0x316, 0x001);
125 sp887x_writereg(state, 0x313, 0x005);
126 sp887x_writereg(state, 0x312, 0x002);
127 sp887x_writereg(state, 0x306, 0x000);
128 sp887x_writereg(state, 0x303, 0x000);
129}
130
131#define BLOCKSIZE 30
132#define FW_SIZE 0x4000
133/**
134 * load firmware and setup MPEG interface...
135 */
136static int sp887x_initial_setup (struct dvb_frontend* fe, const struct firmware *fw)
137{
138 struct sp887x_state* state = (struct sp887x_state*) fe->demodulator_priv;
139 u8 buf [BLOCKSIZE+2];
140 int i;
141 int fw_size = fw->size;
142 unsigned char *mem = fw->data;
143
144 dprintk("%s\n", __FUNCTION__);
145
146 /* ignore the first 10 bytes, then we expect 0x4000 bytes of firmware */
147 if (fw_size < FW_SIZE+10)
148 return -ENODEV;
149
150 mem = fw->data + 10;
151
152 /* soft reset */
153 sp887x_writereg(state, 0xf1a, 0x000);
154
155 sp887x_microcontroller_stop (state);
156
157 printk ("%s: firmware upload... ", __FUNCTION__);
158
159 /* setup write pointer to -1 (end of memory) */
160 /* bit 0x8000 in address is set to enable 13bit mode */
161 sp887x_writereg(state, 0x8f08, 0x1fff);
162
163 /* dummy write (wrap around to start of memory) */
164 sp887x_writereg(state, 0x8f0a, 0x0000);
165
166 for (i = 0; i < FW_SIZE; i += BLOCKSIZE) {
167 int c = BLOCKSIZE;
168 int err;
169
170 if (i+c > FW_SIZE)
171 c = FW_SIZE - i;
172
173 /* bit 0x8000 in address is set to enable 13bit mode */
174 /* bit 0x4000 enables multibyte read/write transfers */
175 /* write register is 0xf0a */
176 buf[0] = 0xcf;
177 buf[1] = 0x0a;
178
179 memcpy(&buf[2], mem + i, c);
180
181 if ((err = i2c_writebytes (state, buf, c+2)) < 0) {
182 printk ("failed.\n");
183 printk ("%s: i2c error (err == %i)\n", __FUNCTION__, err);
184 return err;
185 }
186 }
187
188 /* don't write RS bytes between packets */
189 sp887x_writereg(state, 0xc13, 0x001);
190
191 /* suppress clock if (!data_valid) */
192 sp887x_writereg(state, 0xc14, 0x000);
193
194 /* setup MPEG interface... */
195 sp887x_writereg(state, 0xc1a, 0x872);
196 sp887x_writereg(state, 0xc1b, 0x001);
197 sp887x_writereg(state, 0xc1c, 0x000); /* parallel mode (serial mode == 1) */
198 sp887x_writereg(state, 0xc1a, 0x871);
199
200 /* ADC mode, 2 for MT8872, 3 for SP8870/SP8871 */
201 sp887x_writereg(state, 0x301, 0x002);
202
203 sp887x_setup_agc(state);
204
205 /* bit 0x010: enable data valid signal */
206 sp887x_writereg(state, 0xd00, 0x010);
207 sp887x_writereg(state, 0x0d1, 0x000);
208
209 /* setup the PLL */
210 if (state->config->pll_init) {
211 sp887x_writereg(state, 0x206, 0x001);
212 state->config->pll_init(fe);
213 sp887x_writereg(state, 0x206, 0x000);
214 }
215
216 printk ("done.\n");
217 return 0;
218};
219
220static int configure_reg0xc05 (struct dvb_frontend_parameters *p, u16 *reg0xc05)
221{
222 int known_parameters = 1;
223
224 *reg0xc05 = 0x000;
225
226 switch (p->u.ofdm.constellation) {
227 case QPSK:
228 break;
229 case QAM_16:
230 *reg0xc05 |= (1 << 10);
231 break;
232 case QAM_64:
233 *reg0xc05 |= (2 << 10);
234 break;
235 case QAM_AUTO:
236 known_parameters = 0;
237 break;
238 default:
239 return -EINVAL;
240 };
241
242 switch (p->u.ofdm.hierarchy_information) {
243 case HIERARCHY_NONE:
244 break;
245 case HIERARCHY_1:
246 *reg0xc05 |= (1 << 7);
247 break;
248 case HIERARCHY_2:
249 *reg0xc05 |= (2 << 7);
250 break;
251 case HIERARCHY_4:
252 *reg0xc05 |= (3 << 7);
253 break;
254 case HIERARCHY_AUTO:
255 known_parameters = 0;
256 break;
257 default:
258 return -EINVAL;
259 };
260
261 switch (p->u.ofdm.code_rate_HP) {
262 case FEC_1_2:
263 break;
264 case FEC_2_3:
265 *reg0xc05 |= (1 << 3);
266 break;
267 case FEC_3_4:
268 *reg0xc05 |= (2 << 3);
269 break;
270 case FEC_5_6:
271 *reg0xc05 |= (3 << 3);
272 break;
273 case FEC_7_8:
274 *reg0xc05 |= (4 << 3);
275 break;
276 case FEC_AUTO:
277 known_parameters = 0;
278 break;
279 default:
280 return -EINVAL;
281 };
282
283 if (known_parameters)
284 *reg0xc05 |= (2 << 1); /* use specified parameters */
285 else
286 *reg0xc05 |= (1 << 1); /* enable autoprobing */
287
288 return 0;
289}
290
291/**
292 * estimates division of two 24bit numbers,
293 * derived from the ves1820/stv0299 driver code
294 */
295static void divide (int n, int d, int *quotient_i, int *quotient_f)
296{
297 unsigned int q, r;
298
299 r = (n % d) << 8;
300 q = (r / d);
301
302 if (quotient_i)
303 *quotient_i = q;
304
305 if (quotient_f) {
306 r = (r % d) << 8;
307 q = (q << 8) | (r / d);
308 r = (r % d) << 8;
309 *quotient_f = (q << 8) | (r / d);
310 }
311}
312
313static void sp887x_correct_offsets (struct sp887x_state* state,
314 struct dvb_frontend_parameters *p,
315 int actual_freq)
316{
317 static const u32 srate_correction [] = { 1879617, 4544878, 8098561 };
318 int bw_index = p->u.ofdm.bandwidth - BANDWIDTH_8_MHZ;
319 int freq_offset = actual_freq - p->frequency;
320 int sysclock = 61003; //[kHz]
321 int ifreq = 36000000;
322 int freq;
323 int frequency_shift;
324
325 if (p->inversion == INVERSION_ON)
326 freq = ifreq - freq_offset;
327 else
328 freq = ifreq + freq_offset;
329
330 divide(freq / 333, sysclock, NULL, &frequency_shift);
331
332 if (p->inversion == INVERSION_ON)
333 frequency_shift = -frequency_shift;
334
335 /* sample rate correction */
336 sp887x_writereg(state, 0x319, srate_correction[bw_index] >> 12);
337 sp887x_writereg(state, 0x31a, srate_correction[bw_index] & 0xfff);
338
339 /* carrier offset correction */
340 sp887x_writereg(state, 0x309, frequency_shift >> 12);
341 sp887x_writereg(state, 0x30a, frequency_shift & 0xfff);
342}
343
344static int sp887x_setup_frontend_parameters (struct dvb_frontend* fe,
345 struct dvb_frontend_parameters *p)
346{
347 struct sp887x_state* state = (struct sp887x_state*) fe->demodulator_priv;
348 int actual_freq, err;
349 u16 val, reg0xc05;
350
351 if (p->u.ofdm.bandwidth != BANDWIDTH_8_MHZ &&
352 p->u.ofdm.bandwidth != BANDWIDTH_7_MHZ &&
353 p->u.ofdm.bandwidth != BANDWIDTH_6_MHZ)
354 return -EINVAL;
355
356 if ((err = configure_reg0xc05(p, &reg0xc05)))
357 return err;
358
359 sp887x_microcontroller_stop(state);
360
361 /* setup the PLL */
362 sp887x_writereg(state, 0x206, 0x001);
363 actual_freq = state->config->pll_set(fe, p);
364 sp887x_writereg(state, 0x206, 0x000);
365
366 /* read status reg in order to clear <pending irqs */
367 sp887x_readreg(state, 0x200);
368
369 sp887x_correct_offsets(state, p, actual_freq);
370
371 /* filter for 6/7/8 Mhz channel */
372 if (p->u.ofdm.bandwidth == BANDWIDTH_6_MHZ)
373 val = 2;
374 else if (p->u.ofdm.bandwidth == BANDWIDTH_7_MHZ)
375 val = 1;
376 else
377 val = 0;
378
379 sp887x_writereg(state, 0x311, val);
380
381 /* scan order: 2k first = 0, 8k first = 1 */
382 if (p->u.ofdm.transmission_mode == TRANSMISSION_MODE_2K)
383 sp887x_writereg(state, 0x338, 0x000);
384 else
385 sp887x_writereg(state, 0x338, 0x001);
386
387 sp887x_writereg(state, 0xc05, reg0xc05);
388
389 if (p->u.ofdm.bandwidth == BANDWIDTH_6_MHZ)
390 val = 2 << 3;
391 else if (p->u.ofdm.bandwidth == BANDWIDTH_7_MHZ)
392 val = 3 << 3;
393 else
394 val = 0 << 3;
395
396 /* enable OFDM and SAW bits as lock indicators in sync register 0xf17,
397 * optimize algorithm for given bandwidth...
398 */
399 sp887x_writereg(state, 0xf14, 0x160 | val);
400 sp887x_writereg(state, 0xf15, 0x000);
401
402 sp887x_microcontroller_start(state);
403 return 0;
404}
405
406static int sp887x_read_status(struct dvb_frontend* fe, fe_status_t* status)
407{
408 struct sp887x_state* state = (struct sp887x_state*) fe->demodulator_priv;
409 u16 snr12 = sp887x_readreg(state, 0xf16);
410 u16 sync0x200 = sp887x_readreg(state, 0x200);
411 u16 sync0xf17 = sp887x_readreg(state, 0xf17);
412
413 *status = 0;
414
415 if (snr12 > 0x00f)
416 *status |= FE_HAS_SIGNAL;
417
418 //if (sync0x200 & 0x004)
419 // *status |= FE_HAS_SYNC | FE_HAS_CARRIER;
420
421 //if (sync0x200 & 0x008)
422 // *status |= FE_HAS_VITERBI;
423
424 if ((sync0xf17 & 0x00f) == 0x002) {
425 *status |= FE_HAS_LOCK;
426 *status |= FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_CARRIER;
427 }
428
429 if (sync0x200 & 0x001) { /* tuner adjustment requested...*/
430 int steps = (sync0x200 >> 4) & 0x00f;
431 if (steps & 0x008)
432 steps = -steps;
433 dprintk("sp887x: implement tuner adjustment (%+i steps)!!\n",
434 steps);
435 }
436
437 return 0;
438}
439
440static int sp887x_read_ber(struct dvb_frontend* fe, u32* ber)
441{
442 struct sp887x_state* state = (struct sp887x_state*) fe->demodulator_priv;
443
444 *ber = (sp887x_readreg(state, 0xc08) & 0x3f) |
445 (sp887x_readreg(state, 0xc07) << 6);
446 sp887x_writereg(state, 0xc08, 0x000);
447 sp887x_writereg(state, 0xc07, 0x000);
448 if (*ber >= 0x3fff0)
449 *ber = ~0;
450
451 return 0;
452}
453
454static int sp887x_read_signal_strength(struct dvb_frontend* fe, u16* strength)
455{
456 struct sp887x_state* state = (struct sp887x_state*) fe->demodulator_priv;
457
458 u16 snr12 = sp887x_readreg(state, 0xf16);
459 u32 signal = 3 * (snr12 << 4);
460 *strength = (signal < 0xffff) ? signal : 0xffff;
461
462 return 0;
463}
464
465static int sp887x_read_snr(struct dvb_frontend* fe, u16* snr)
466{
467 struct sp887x_state* state = (struct sp887x_state*) fe->demodulator_priv;
468
469 u16 snr12 = sp887x_readreg(state, 0xf16);
470 *snr = (snr12 << 4) | (snr12 >> 8);
471
472 return 0;
473}
474
475static int sp887x_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
476{
477 struct sp887x_state* state = (struct sp887x_state*) fe->demodulator_priv;
478
479 *ucblocks = sp887x_readreg(state, 0xc0c);
480 if (*ucblocks == 0xfff)
481 *ucblocks = ~0;
482
483 return 0;
484}
485
486static int sp887x_sleep(struct dvb_frontend* fe)
487{
488 struct sp887x_state* state = (struct sp887x_state*) fe->demodulator_priv;
489
490 /* tristate TS output and disable interface pins */
491 sp887x_writereg(state, 0xc18, 0x000);
492
493 return 0;
494}
495
496static int sp887x_init(struct dvb_frontend* fe)
497{
498 struct sp887x_state* state = (struct sp887x_state*) fe->demodulator_priv;
499 const struct firmware *fw = NULL;
500 int ret;
501
502 if (!state->initialised) {
503 /* request the firmware, this will block until someone uploads it */
504 printk("sp887x: waiting for firmware upload (%s)...\n", SP887X_DEFAULT_FIRMWARE);
505 ret = state->config->request_firmware(fe, &fw, SP887X_DEFAULT_FIRMWARE);
506 if (ret) {
507 printk("sp887x: no firmware upload (timeout or file not found?)\n");
508 return ret;
509 }
510
511 ret = sp887x_initial_setup(fe, fw);
512 if (ret) {
513 printk("sp887x: writing firmware to device failed\n");
514 release_firmware(fw);
515 return ret;
516 }
517 printk("sp887x: firmware upload complete\n");
518 state->initialised = 1;
519 }
520
521 /* enable TS output and interface pins */
522 sp887x_writereg(state, 0xc18, 0x00d);
523
524 return 0;
525}
526
527static int sp887x_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
528{
529 fesettings->min_delay_ms = 350;
530 fesettings->step_size = 166666*2;
531 fesettings->max_drift = (166666*2)+1;
532 return 0;
533}
534
535static void sp887x_release(struct dvb_frontend* fe)
536{
537 struct sp887x_state* state = (struct sp887x_state*) fe->demodulator_priv;
538 kfree(state);
539}
540
541static struct dvb_frontend_ops sp887x_ops;
542
543struct dvb_frontend* sp887x_attach(const struct sp887x_config* config,
544 struct i2c_adapter* i2c)
545{
546 struct sp887x_state* state = NULL;
547
548 /* allocate memory for the internal state */
549 state = (struct sp887x_state*) kmalloc(sizeof(struct sp887x_state), GFP_KERNEL);
550 if (state == NULL) goto error;
551
552 /* setup the state */
553 state->config = config;
554 state->i2c = i2c;
555 memcpy(&state->ops, &sp887x_ops, sizeof(struct dvb_frontend_ops));
556 state->initialised = 0;
557
558 /* check if the demod is there */
559 if (sp887x_readreg(state, 0x0200) < 0) goto error;
560
561 /* create dvb_frontend */
562 state->frontend.ops = &state->ops;
563 state->frontend.demodulator_priv = state;
564 return &state->frontend;
565
566error:
567 kfree(state);
568 return NULL;
569}
570
571static struct dvb_frontend_ops sp887x_ops = {
572
573 .info = {
574 .name = "Spase SP887x DVB-T",
575 .type = FE_OFDM,
576 .frequency_min = 50500000,
577 .frequency_max = 858000000,
578 .frequency_stepsize = 166666,
579 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
580 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
581 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 |
582 FE_CAN_RECOVER
583 },
584
585 .release = sp887x_release,
586
587 .init = sp887x_init,
588 .sleep = sp887x_sleep,
589
590 .set_frontend = sp887x_setup_frontend_parameters,
591 .get_tune_settings = sp887x_get_tune_settings,
592
593 .read_status = sp887x_read_status,
594 .read_ber = sp887x_read_ber,
595 .read_signal_strength = sp887x_read_signal_strength,
596 .read_snr = sp887x_read_snr,
597 .read_ucblocks = sp887x_read_ucblocks,
598};
599
600module_param(debug, int, 0644);
601MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
602
603MODULE_DESCRIPTION("Spase sp887x DVB-T demodulator driver");
604MODULE_LICENSE("GPL");
605
606EXPORT_SYMBOL(sp887x_attach);
diff --git a/drivers/media/dvb/frontends/sp887x.h b/drivers/media/dvb/frontends/sp887x.h
new file mode 100644
index 000000000000..6a05d8f8e8cc
--- /dev/null
+++ b/drivers/media/dvb/frontends/sp887x.h
@@ -0,0 +1,29 @@
1/*
2 Driver for the Spase sp887x demodulator
3*/
4
5#ifndef SP887X_H
6#define SP887X_H
7
8#include <linux/dvb/frontend.h>
9#include <linux/firmware.h>
10
11struct sp887x_config
12{
13 /* the demodulator's i2c address */
14 u8 demod_address;
15
16 /* PLL maintenance */
17 int (*pll_init)(struct dvb_frontend* fe);
18
19 /* this should return the actual frequency tuned to */
20 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
21
22 /* request firmware for device */
23 int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name);
24};
25
26extern struct dvb_frontend* sp887x_attach(const struct sp887x_config* config,
27 struct i2c_adapter* i2c);
28
29#endif // SP887X_H
diff --git a/drivers/media/dvb/frontends/stv0297.c b/drivers/media/dvb/frontends/stv0297.c
new file mode 100644
index 000000000000..502c6403dfc6
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv0297.c
@@ -0,0 +1,798 @@
1/*
2 Driver for STV0297 demodulator
3
4 Copyright (C) 2004 Andrew de Quincey <adq_dvb@lidskialf.net>
5 Copyright (C) 2003-2004 Dennis Noermann <dennis.noermann@noernet.de>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20*/
21
22#include <linux/init.h>
23#include <linux/kernel.h>
24#include <linux/module.h>
25#include <linux/string.h>
26#include <linux/delay.h>
27
28#include "dvb_frontend.h"
29#include "stv0297.h"
30
31struct stv0297_state {
32 struct i2c_adapter *i2c;
33 struct dvb_frontend_ops ops;
34 const struct stv0297_config *config;
35 struct dvb_frontend frontend;
36
37 unsigned long base_freq;
38 u8 pwm;
39};
40
41#if 1
42#define dprintk(x...) printk(x)
43#else
44#define dprintk(x...)
45#endif
46
47#define STV0297_CLOCK_KHZ 28900
48
49static u8 init_tab[] = {
50 0x00, 0x09,
51 0x01, 0x69,
52 0x03, 0x00,
53 0x04, 0x00,
54 0x07, 0x00,
55 0x08, 0x00,
56 0x20, 0x00,
57 0x21, 0x40,
58 0x22, 0x00,
59 0x23, 0x00,
60 0x24, 0x40,
61 0x25, 0x88,
62 0x30, 0xff,
63 0x31, 0x00,
64 0x32, 0xff,
65 0x33, 0x00,
66 0x34, 0x50,
67 0x35, 0x7f,
68 0x36, 0x00,
69 0x37, 0x20,
70 0x38, 0x00,
71 0x40, 0x1c,
72 0x41, 0xff,
73 0x42, 0x29,
74 0x43, 0x00,
75 0x44, 0xff,
76 0x45, 0x00,
77 0x46, 0x00,
78 0x49, 0x04,
79 0x4a, 0xff,
80 0x4b, 0x7f,
81 0x52, 0x30,
82 0x55, 0xae,
83 0x56, 0x47,
84 0x57, 0xe1,
85 0x58, 0x3a,
86 0x5a, 0x1e,
87 0x5b, 0x34,
88 0x60, 0x00,
89 0x63, 0x00,
90 0x64, 0x00,
91 0x65, 0x00,
92 0x66, 0x00,
93 0x67, 0x00,
94 0x68, 0x00,
95 0x69, 0x00,
96 0x6a, 0x02,
97 0x6b, 0x00,
98 0x70, 0xff,
99 0x71, 0x00,
100 0x72, 0x00,
101 0x73, 0x00,
102 0x74, 0x0c,
103 0x80, 0x00,
104 0x81, 0x00,
105 0x82, 0x00,
106 0x83, 0x00,
107 0x84, 0x04,
108 0x85, 0x80,
109 0x86, 0x24,
110 0x87, 0x78,
111 0x88, 0x00,
112 0x89, 0x00,
113 0x90, 0x01,
114 0x91, 0x01,
115 0xa0, 0x00,
116 0xa1, 0x00,
117 0xa2, 0x00,
118 0xb0, 0x91,
119 0xb1, 0x0b,
120 0xc0, 0x53,
121 0xc1, 0x70,
122 0xc2, 0x12,
123 0xd0, 0x00,
124 0xd1, 0x00,
125 0xd2, 0x00,
126 0xd3, 0x00,
127 0xd4, 0x00,
128 0xd5, 0x00,
129 0xde, 0x00,
130 0xdf, 0x00,
131 0x61, 0x49,
132 0x62, 0x0b,
133 0x53, 0x08,
134 0x59, 0x08,
135};
136
137
138static int stv0297_writereg(struct stv0297_state *state, u8 reg, u8 data)
139{
140 int ret;
141 u8 buf[] = { reg, data };
142 struct i2c_msg msg = {.addr = state->config->demod_address,.flags = 0,.buf = buf,.len = 2 };
143
144 ret = i2c_transfer(state->i2c, &msg, 1);
145
146 if (ret != 1)
147 dprintk("%s: writereg error (reg == 0x%02x, val == 0x%02x, "
148 "ret == %i)\n", __FUNCTION__, reg, data, ret);
149
150 return (ret != 1) ? -1 : 0;
151}
152
153static int stv0297_readreg(struct stv0297_state *state, u8 reg)
154{
155 int ret;
156 u8 b0[] = { reg };
157 u8 b1[] = { 0 };
158 struct i2c_msg msg[] = { {.addr = state->config->demod_address,.flags = 0,.buf = b0,.len =
159 1},
160 {.addr = state->config->demod_address,.flags = I2C_M_RD,.buf = b1,.len = 1}
161 };
162
163 // this device needs a STOP between the register and data
164 if ((ret = i2c_transfer(state->i2c, &msg[0], 1)) != 1) {
165 dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg, ret);
166 return -1;
167 }
168 if ((ret = i2c_transfer(state->i2c, &msg[1], 1)) != 1) {
169 dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg, ret);
170 return -1;
171 }
172
173 return b1[0];
174}
175
176static int stv0297_writereg_mask(struct stv0297_state *state, u8 reg, u8 mask, u8 data)
177{
178 int val;
179
180 val = stv0297_readreg(state, reg);
181 val &= ~mask;
182 val |= (data & mask);
183 stv0297_writereg(state, reg, val);
184
185 return 0;
186}
187
188static int stv0297_readregs(struct stv0297_state *state, u8 reg1, u8 * b, u8 len)
189{
190 int ret;
191 struct i2c_msg msg[] = { {.addr = state->config->demod_address,.flags = 0,.buf =
192 &reg1,.len = 1},
193 {.addr = state->config->demod_address,.flags = I2C_M_RD,.buf = b,.len = len}
194 };
195
196 // this device needs a STOP between the register and data
197 if ((ret = i2c_transfer(state->i2c, &msg[0], 1)) != 1) {
198 dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg1, ret);
199 return -1;
200 }
201 if ((ret = i2c_transfer(state->i2c, &msg[1], 1)) != 1) {
202 dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg1, ret);
203 return -1;
204 }
205
206 return 0;
207}
208
209static u32 stv0297_get_symbolrate(struct stv0297_state *state)
210{
211 u64 tmp;
212
213 tmp = stv0297_readreg(state, 0x55);
214 tmp |= stv0297_readreg(state, 0x56) << 8;
215 tmp |= stv0297_readreg(state, 0x57) << 16;
216 tmp |= stv0297_readreg(state, 0x58) << 24;
217
218 tmp *= STV0297_CLOCK_KHZ;
219 tmp >>= 32;
220
221 return (u32) tmp;
222}
223
224static void stv0297_set_symbolrate(struct stv0297_state *state, u32 srate)
225{
226 long tmp;
227
228 tmp = 131072L * srate; /* 131072 = 2^17 */
229 tmp = tmp / (STV0297_CLOCK_KHZ / 4); /* 1/4 = 2^-2 */
230 tmp = tmp * 8192L; /* 8192 = 2^13 */
231
232 stv0297_writereg(state, 0x55, (unsigned char) (tmp & 0xFF));
233 stv0297_writereg(state, 0x56, (unsigned char) (tmp >> 8));
234 stv0297_writereg(state, 0x57, (unsigned char) (tmp >> 16));
235 stv0297_writereg(state, 0x58, (unsigned char) (tmp >> 24));
236}
237
238static void stv0297_set_sweeprate(struct stv0297_state *state, short fshift, long symrate)
239{
240 long tmp;
241
242 tmp = (long) fshift *262144L; /* 262144 = 2*18 */
243 tmp /= symrate;
244 tmp *= 1024; /* 1024 = 2*10 */
245
246 // adjust
247 if (tmp >= 0) {
248 tmp += 500000;
249 } else {
250 tmp -= 500000;
251 }
252 tmp /= 1000000;
253
254 stv0297_writereg(state, 0x60, tmp & 0xFF);
255 stv0297_writereg_mask(state, 0x69, 0xF0, (tmp >> 4) & 0xf0);
256}
257
258static void stv0297_set_carrieroffset(struct stv0297_state *state, long offset)
259{
260 long tmp;
261
262 /* symrate is hardcoded to 10000 */
263 tmp = offset * 26844L; /* (2**28)/10000 */
264 if (tmp < 0)
265 tmp += 0x10000000;
266 tmp &= 0x0FFFFFFF;
267
268 stv0297_writereg(state, 0x66, (unsigned char) (tmp & 0xFF));
269 stv0297_writereg(state, 0x67, (unsigned char) (tmp >> 8));
270 stv0297_writereg(state, 0x68, (unsigned char) (tmp >> 16));
271 stv0297_writereg_mask(state, 0x69, 0x0F, (tmp >> 24) & 0x0f);
272}
273
274/*
275static long stv0297_get_carrieroffset(struct stv0297_state *state)
276{
277 s64 tmp;
278
279 stv0297_writereg(state, 0x6B, 0x00);
280
281 tmp = stv0297_readreg(state, 0x66);
282 tmp |= (stv0297_readreg(state, 0x67) << 8);
283 tmp |= (stv0297_readreg(state, 0x68) << 16);
284 tmp |= (stv0297_readreg(state, 0x69) & 0x0F) << 24;
285
286 tmp *= stv0297_get_symbolrate(state);
287 tmp >>= 28;
288
289 return (s32) tmp;
290}
291*/
292
293static void stv0297_set_initialdemodfreq(struct stv0297_state *state, long freq)
294{
295 s32 tmp;
296
297 if (freq > 10000)
298 freq -= STV0297_CLOCK_KHZ;
299
300 tmp = (STV0297_CLOCK_KHZ * 1000) / (1 << 16);
301 tmp = (freq * 1000) / tmp;
302 if (tmp > 0xffff)
303 tmp = 0xffff;
304
305 stv0297_writereg_mask(state, 0x25, 0x80, 0x80);
306 stv0297_writereg(state, 0x21, tmp >> 8);
307 stv0297_writereg(state, 0x20, tmp);
308}
309
310static int stv0297_set_qam(struct stv0297_state *state, fe_modulation_t modulation)
311{
312 int val = 0;
313
314 switch (modulation) {
315 case QAM_16:
316 val = 0;
317 break;
318
319 case QAM_32:
320 val = 1;
321 break;
322
323 case QAM_64:
324 val = 4;
325 break;
326
327 case QAM_128:
328 val = 2;
329 break;
330
331 case QAM_256:
332 val = 3;
333 break;
334
335 default:
336 return -EINVAL;
337 }
338
339 stv0297_writereg_mask(state, 0x00, 0x70, val << 4);
340
341 return 0;
342}
343
344static int stv0297_set_inversion(struct stv0297_state *state, fe_spectral_inversion_t inversion)
345{
346 int val = 0;
347
348 switch (inversion) {
349 case INVERSION_OFF:
350 val = 0;
351 break;
352
353 case INVERSION_ON:
354 val = 1;
355 break;
356
357 default:
358 return -EINVAL;
359 }
360
361 stv0297_writereg_mask(state, 0x83, 0x08, val << 3);
362
363 return 0;
364}
365
366int stv0297_enable_plli2c(struct dvb_frontend *fe)
367{
368 struct stv0297_state *state = (struct stv0297_state *) fe->demodulator_priv;
369
370 stv0297_writereg(state, 0x87, 0x78);
371 stv0297_writereg(state, 0x86, 0xc8);
372
373 return 0;
374}
375
376static int stv0297_init(struct dvb_frontend *fe)
377{
378 struct stv0297_state *state = (struct stv0297_state *) fe->demodulator_priv;
379 int i;
380
381 /* soft reset */
382 stv0297_writereg_mask(state, 0x80, 1, 1);
383 stv0297_writereg_mask(state, 0x80, 1, 0);
384
385 /* reset deinterleaver */
386 stv0297_writereg_mask(state, 0x81, 1, 1);
387 stv0297_writereg_mask(state, 0x81, 1, 0);
388
389 /* load init table */
390 for (i = 0; i < sizeof(init_tab); i += 2) {
391 stv0297_writereg(state, init_tab[i], init_tab[i + 1]);
392 }
393
394 /* set a dummy symbol rate */
395 stv0297_set_symbolrate(state, 6900);
396
397 /* invert AGC1 polarity */
398 stv0297_writereg_mask(state, 0x88, 0x10, 0x10);
399
400 /* setup bit error counting */
401 stv0297_writereg_mask(state, 0xA0, 0x80, 0x00);
402 stv0297_writereg_mask(state, 0xA0, 0x10, 0x00);
403 stv0297_writereg_mask(state, 0xA0, 0x08, 0x00);
404 stv0297_writereg_mask(state, 0xA0, 0x07, 0x04);
405
406 /* min + max PWM */
407 stv0297_writereg(state, 0x4a, 0x00);
408 stv0297_writereg(state, 0x4b, state->pwm);
409 msleep(200);
410
411 if (state->config->pll_init)
412 state->config->pll_init(fe);
413
414 return 0;
415}
416
417static int stv0297_sleep(struct dvb_frontend *fe)
418{
419 struct stv0297_state *state = (struct stv0297_state *) fe->demodulator_priv;
420
421 stv0297_writereg_mask(state, 0x80, 1, 1);
422
423 return 0;
424}
425
426static int stv0297_read_status(struct dvb_frontend *fe, fe_status_t * status)
427{
428 struct stv0297_state *state = (struct stv0297_state *) fe->demodulator_priv;
429
430 u8 sync = stv0297_readreg(state, 0xDF);
431
432 *status = 0;
433 if (sync & 0x80)
434 *status |=
435 FE_HAS_SYNC | FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_LOCK;
436 return 0;
437}
438
439static int stv0297_read_ber(struct dvb_frontend *fe, u32 * ber)
440{
441 struct stv0297_state *state = (struct stv0297_state *) fe->demodulator_priv;
442 u8 BER[3];
443
444 stv0297_writereg(state, 0xA0, 0x80); // Start Counting bit errors for 4096 Bytes
445 mdelay(25); // Hopefully got 4096 Bytes
446 stv0297_readregs(state, 0xA0, BER, 3);
447 mdelay(25);
448 *ber = (BER[2] << 8 | BER[1]) / (8 * 4096);
449
450 return 0;
451}
452
453
454static int stv0297_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
455{
456 struct stv0297_state *state = (struct stv0297_state *) fe->demodulator_priv;
457 u8 STRENGTH[2];
458
459 stv0297_readregs(state, 0x41, STRENGTH, 2);
460 *strength = (STRENGTH[1] & 0x03) << 8 | STRENGTH[0];
461
462 return 0;
463}
464
465static int stv0297_read_snr(struct dvb_frontend *fe, u16 * snr)
466{
467 struct stv0297_state *state = (struct stv0297_state *) fe->demodulator_priv;
468 u8 SNR[2];
469
470 stv0297_readregs(state, 0x07, SNR, 2);
471 *snr = SNR[1] << 8 | SNR[0];
472
473 return 0;
474}
475
476static int stv0297_read_ucblocks(struct dvb_frontend *fe, u32 * ucblocks)
477{
478 struct stv0297_state *state = (struct stv0297_state *) fe->demodulator_priv;
479
480 *ucblocks = (stv0297_readreg(state, 0xD5) << 8)
481 | stv0297_readreg(state, 0xD4);
482
483 return 0;
484}
485
486static int stv0297_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p)
487{
488 struct stv0297_state *state = (struct stv0297_state *) fe->demodulator_priv;
489 int u_threshold;
490 int initial_u;
491 int blind_u;
492 int delay;
493 int sweeprate;
494 int carrieroffset;
495 unsigned long starttime;
496 unsigned long timeout;
497 fe_spectral_inversion_t inversion;
498
499 switch (p->u.qam.modulation) {
500 case QAM_16:
501 case QAM_32:
502 case QAM_64:
503 delay = 100;
504 sweeprate = 1500;
505 break;
506
507 case QAM_128:
508 delay = 150;
509 sweeprate = 1000;
510 break;
511
512 case QAM_256:
513 delay = 200;
514 sweeprate = 500;
515 break;
516
517 default:
518 return -EINVAL;
519 }
520
521 // determine inversion dependant parameters
522 inversion = p->inversion;
523 if (state->config->invert)
524 inversion = (inversion == INVERSION_ON) ? INVERSION_OFF : INVERSION_ON;
525 carrieroffset = -330;
526 switch (inversion) {
527 case INVERSION_OFF:
528 break;
529
530 case INVERSION_ON:
531 sweeprate = -sweeprate;
532 carrieroffset = -carrieroffset;
533 break;
534
535 default:
536 return -EINVAL;
537 }
538
539 stv0297_init(fe);
540 state->config->pll_set(fe, p);
541
542 /* clear software interrupts */
543 stv0297_writereg(state, 0x82, 0x0);
544
545 /* set initial demodulation frequency */
546 stv0297_set_initialdemodfreq(state, 7250);
547
548 /* setup AGC */
549 stv0297_writereg_mask(state, 0x43, 0x10, 0x00);
550 stv0297_writereg(state, 0x41, 0x00);
551 stv0297_writereg_mask(state, 0x42, 0x03, 0x01);
552 stv0297_writereg_mask(state, 0x36, 0x60, 0x00);
553 stv0297_writereg_mask(state, 0x36, 0x18, 0x00);
554 stv0297_writereg_mask(state, 0x71, 0x80, 0x80);
555 stv0297_writereg(state, 0x72, 0x00);
556 stv0297_writereg(state, 0x73, 0x00);
557 stv0297_writereg_mask(state, 0x74, 0x0F, 0x00);
558 stv0297_writereg_mask(state, 0x43, 0x08, 0x00);
559 stv0297_writereg_mask(state, 0x71, 0x80, 0x00);
560
561 /* setup STL */
562 stv0297_writereg_mask(state, 0x5a, 0x20, 0x20);
563 stv0297_writereg_mask(state, 0x5b, 0x02, 0x02);
564 stv0297_writereg_mask(state, 0x5b, 0x02, 0x00);
565 stv0297_writereg_mask(state, 0x5b, 0x01, 0x00);
566 stv0297_writereg_mask(state, 0x5a, 0x40, 0x40);
567
568 /* disable frequency sweep */
569 stv0297_writereg_mask(state, 0x6a, 0x01, 0x00);
570
571 /* reset deinterleaver */
572 stv0297_writereg_mask(state, 0x81, 0x01, 0x01);
573 stv0297_writereg_mask(state, 0x81, 0x01, 0x00);
574
575 /* ??? */
576 stv0297_writereg_mask(state, 0x83, 0x20, 0x20);
577 stv0297_writereg_mask(state, 0x83, 0x20, 0x00);
578
579 /* reset equaliser */
580 u_threshold = stv0297_readreg(state, 0x00) & 0xf;
581 initial_u = stv0297_readreg(state, 0x01) >> 4;
582 blind_u = stv0297_readreg(state, 0x01) & 0xf;
583 stv0297_writereg_mask(state, 0x84, 0x01, 0x01);
584 stv0297_writereg_mask(state, 0x84, 0x01, 0x00);
585 stv0297_writereg_mask(state, 0x00, 0x0f, u_threshold);
586 stv0297_writereg_mask(state, 0x01, 0xf0, initial_u << 4);
587 stv0297_writereg_mask(state, 0x01, 0x0f, blind_u);
588
589 /* data comes from internal A/D */
590 stv0297_writereg_mask(state, 0x87, 0x80, 0x00);
591
592 /* clear phase registers */
593 stv0297_writereg(state, 0x63, 0x00);
594 stv0297_writereg(state, 0x64, 0x00);
595 stv0297_writereg(state, 0x65, 0x00);
596 stv0297_writereg(state, 0x66, 0x00);
597 stv0297_writereg(state, 0x67, 0x00);
598 stv0297_writereg(state, 0x68, 0x00);
599 stv0297_writereg_mask(state, 0x69, 0x0f, 0x00);
600
601 /* set parameters */
602 stv0297_set_qam(state, p->u.qam.modulation);
603 stv0297_set_symbolrate(state, p->u.qam.symbol_rate / 1000);
604 stv0297_set_sweeprate(state, sweeprate, p->u.qam.symbol_rate / 1000);
605 stv0297_set_carrieroffset(state, carrieroffset);
606 stv0297_set_inversion(state, inversion);
607
608 /* kick off lock */
609 stv0297_writereg_mask(state, 0x88, 0x08, 0x08);
610 stv0297_writereg_mask(state, 0x5a, 0x20, 0x00);
611 stv0297_writereg_mask(state, 0x6a, 0x01, 0x01);
612 stv0297_writereg_mask(state, 0x43, 0x40, 0x40);
613 stv0297_writereg_mask(state, 0x5b, 0x30, 0x00);
614 stv0297_writereg_mask(state, 0x03, 0x0c, 0x0c);
615 stv0297_writereg_mask(state, 0x03, 0x03, 0x03);
616 stv0297_writereg_mask(state, 0x43, 0x10, 0x10);
617
618 /* wait for WGAGC lock */
619 starttime = jiffies;
620 timeout = jiffies + (200 * HZ) / 1000;
621 while (time_before(jiffies, timeout)) {
622 msleep(10);
623 if (stv0297_readreg(state, 0x43) & 0x08)
624 break;
625 }
626 if (time_after(jiffies, timeout)) {
627 goto timeout;
628 }
629 msleep(20);
630
631 /* wait for equaliser partial convergence */
632 timeout = jiffies + (50 * HZ) / 1000;
633 while (time_before(jiffies, timeout)) {
634 msleep(10);
635
636 if (stv0297_readreg(state, 0x82) & 0x04) {
637 break;
638 }
639 }
640 if (time_after(jiffies, timeout)) {
641 goto timeout;
642 }
643
644 /* wait for equaliser full convergence */
645 timeout = jiffies + (delay * HZ) / 1000;
646 while (time_before(jiffies, timeout)) {
647 msleep(10);
648
649 if (stv0297_readreg(state, 0x82) & 0x08) {
650 break;
651 }
652 }
653 if (time_after(jiffies, timeout)) {
654 goto timeout;
655 }
656
657 /* disable sweep */
658 stv0297_writereg_mask(state, 0x6a, 1, 0);
659 stv0297_writereg_mask(state, 0x88, 8, 0);
660
661 /* wait for main lock */
662 timeout = jiffies + (20 * HZ) / 1000;
663 while (time_before(jiffies, timeout)) {
664 msleep(10);
665
666 if (stv0297_readreg(state, 0xDF) & 0x80) {
667 break;
668 }
669 }
670 if (time_after(jiffies, timeout)) {
671 goto timeout;
672 }
673 msleep(100);
674
675 /* is it still locked after that delay? */
676 if (!(stv0297_readreg(state, 0xDF) & 0x80)) {
677 goto timeout;
678 }
679
680 /* success!! */
681 stv0297_writereg_mask(state, 0x5a, 0x40, 0x00);
682 state->base_freq = p->frequency;
683 return 0;
684
685timeout:
686 stv0297_writereg_mask(state, 0x6a, 0x01, 0x00);
687 return 0;
688}
689
690static int stv0297_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p)
691{
692 struct stv0297_state *state = (struct stv0297_state *) fe->demodulator_priv;
693 int reg_00, reg_83;
694
695 reg_00 = stv0297_readreg(state, 0x00);
696 reg_83 = stv0297_readreg(state, 0x83);
697
698 p->frequency = state->base_freq;
699 p->inversion = (reg_83 & 0x08) ? INVERSION_ON : INVERSION_OFF;
700 if (state->config->invert)
701 p->inversion = (p->inversion == INVERSION_ON) ? INVERSION_OFF : INVERSION_ON;
702 p->u.qam.symbol_rate = stv0297_get_symbolrate(state) * 1000;
703 p->u.qam.fec_inner = FEC_NONE;
704
705 switch ((reg_00 >> 4) & 0x7) {
706 case 0:
707 p->u.qam.modulation = QAM_16;
708 break;
709 case 1:
710 p->u.qam.modulation = QAM_32;
711 break;
712 case 2:
713 p->u.qam.modulation = QAM_128;
714 break;
715 case 3:
716 p->u.qam.modulation = QAM_256;
717 break;
718 case 4:
719 p->u.qam.modulation = QAM_64;
720 break;
721 }
722
723 return 0;
724}
725
726static void stv0297_release(struct dvb_frontend *fe)
727{
728 struct stv0297_state *state = (struct stv0297_state *) fe->demodulator_priv;
729 kfree(state);
730}
731
732static struct dvb_frontend_ops stv0297_ops;
733
734struct dvb_frontend *stv0297_attach(const struct stv0297_config *config,
735 struct i2c_adapter *i2c, int pwm)
736{
737 struct stv0297_state *state = NULL;
738
739 /* allocate memory for the internal state */
740 state = (struct stv0297_state *) kmalloc(sizeof(struct stv0297_state), GFP_KERNEL);
741 if (state == NULL)
742 goto error;
743
744 /* setup the state */
745 state->config = config;
746 state->i2c = i2c;
747 memcpy(&state->ops, &stv0297_ops, sizeof(struct dvb_frontend_ops));
748 state->base_freq = 0;
749 state->pwm = pwm;
750
751 /* check if the demod is there */
752 if ((stv0297_readreg(state, 0x80) & 0x70) != 0x20)
753 goto error;
754
755 /* create dvb_frontend */
756 state->frontend.ops = &state->ops;
757 state->frontend.demodulator_priv = state;
758 return &state->frontend;
759
760error:
761 kfree(state);
762 return NULL;
763}
764
765static struct dvb_frontend_ops stv0297_ops = {
766
767 .info = {
768 .name = "ST STV0297 DVB-C",
769 .type = FE_QAM,
770 .frequency_min = 64000000,
771 .frequency_max = 1300000000,
772 .frequency_stepsize = 62500,
773 .symbol_rate_min = 870000,
774 .symbol_rate_max = 11700000,
775 .caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
776 FE_CAN_QAM_128 | FE_CAN_QAM_256 | FE_CAN_FEC_AUTO},
777
778 .release = stv0297_release,
779
780 .init = stv0297_init,
781 .sleep = stv0297_sleep,
782
783 .set_frontend = stv0297_set_frontend,
784 .get_frontend = stv0297_get_frontend,
785
786 .read_status = stv0297_read_status,
787 .read_ber = stv0297_read_ber,
788 .read_signal_strength = stv0297_read_signal_strength,
789 .read_snr = stv0297_read_snr,
790 .read_ucblocks = stv0297_read_ucblocks,
791};
792
793MODULE_DESCRIPTION("ST STV0297 DVB-C Demodulator driver");
794MODULE_AUTHOR("Dennis Noermann and Andrew de Quincey");
795MODULE_LICENSE("GPL");
796
797EXPORT_SYMBOL(stv0297_attach);
798EXPORT_SYMBOL(stv0297_enable_plli2c);
diff --git a/drivers/media/dvb/frontends/stv0297.h b/drivers/media/dvb/frontends/stv0297.h
new file mode 100644
index 000000000000..3be535989302
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv0297.h
@@ -0,0 +1,44 @@
1/*
2 Driver for STV0297 demodulator
3
4 Copyright (C) 2003-2004 Dennis Noermann <dennis.noermann@noernet.de>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19*/
20
21#ifndef STV0297_H
22#define STV0297_H
23
24#include <linux/dvb/frontend.h>
25#include "dvb_frontend.h"
26
27struct stv0297_config
28{
29 /* the demodulator's i2c address */
30 u8 demod_address;
31
32 /* does the "inversion" need inverted? */
33 u8 invert:1;
34
35 /* PLL maintenance */
36 int (*pll_init)(struct dvb_frontend* fe);
37 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
38};
39
40extern struct dvb_frontend* stv0297_attach(const struct stv0297_config* config,
41 struct i2c_adapter* i2c, int pwm);
42extern int stv0297_enable_plli2c(struct dvb_frontend* fe);
43
44#endif // STV0297_H
diff --git a/drivers/media/dvb/frontends/stv0299.c b/drivers/media/dvb/frontends/stv0299.c
new file mode 100644
index 000000000000..15b40541b62d
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv0299.c
@@ -0,0 +1,731 @@
1/*
2 Driver for ST STV0299 demodulator
3
4 Copyright (C) 2001-2002 Convergence Integrated Media GmbH
5 <ralph@convergence.de>,
6 <holger@convergence.de>,
7 <js@convergence.de>
8
9
10 Philips SU1278/SH
11
12 Copyright (C) 2002 by Peter Schildmann <peter.schildmann@web.de>
13
14
15 LG TDQF-S001F
16
17 Copyright (C) 2002 Felix Domke <tmbinc@elitedvb.net>
18 & Andreas Oberritter <obi@linuxtv.org>
19
20
21 Support for Samsung TBMU24112IMB used on Technisat SkyStar2 rev. 2.6B
22
23 Copyright (C) 2003 Vadim Catana <skystar@moldova.cc>:
24
25 Support for Philips SU1278 on Technotrend hardware
26
27 Copyright (C) 2004 Andrew de Quincey <adq_dvb@lidskialf.net>
28
29 This program is free software; you can redistribute it and/or modify
30 it under the terms of the GNU General Public License as published by
31 the Free Software Foundation; either version 2 of the License, or
32 (at your option) any later version.
33
34 This program is distributed in the hope that it will be useful,
35 but WITHOUT ANY WARRANTY; without even the implied warranty of
36 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
37 GNU General Public License for more details.
38
39 You should have received a copy of the GNU General Public License
40 along with this program; if not, write to the Free Software
41 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
42
43*/
44
45#include <linux/init.h>
46#include <linux/kernel.h>
47#include <linux/module.h>
48#include <linux/moduleparam.h>
49#include <linux/string.h>
50#include <linux/slab.h>
51#include <asm/div64.h>
52
53#include "dvb_frontend.h"
54#include "stv0299.h"
55
56struct stv0299_state {
57 struct i2c_adapter* i2c;
58 struct dvb_frontend_ops ops;
59 const struct stv0299_config* config;
60 struct dvb_frontend frontend;
61
62 u8 initialised:1;
63 u32 tuner_frequency;
64 u32 symbol_rate;
65 fe_code_rate_t fec_inner;
66 int errmode;
67};
68
69#define STATUS_BER 0
70#define STATUS_UCBLOCKS 1
71
72static int debug;
73#define dprintk(args...) \
74 do { \
75 if (debug) printk(KERN_DEBUG "stv0299: " args); \
76 } while (0)
77
78
79static int stv0299_writeregI (struct stv0299_state* state, u8 reg, u8 data)
80{
81 int ret;
82 u8 buf [] = { reg, data };
83 struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 };
84
85 ret = i2c_transfer (state->i2c, &msg, 1);
86
87 if (ret != 1)
88 dprintk("%s: writereg error (reg == 0x%02x, val == 0x%02x, "
89 "ret == %i)\n", __FUNCTION__, reg, data, ret);
90
91 return (ret != 1) ? -EREMOTEIO : 0;
92}
93
94int stv0299_writereg (struct dvb_frontend* fe, u8 reg, u8 data)
95{
96 struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv;
97
98 return stv0299_writeregI(state, reg, data);
99}
100
101static u8 stv0299_readreg (struct stv0299_state* state, u8 reg)
102{
103 int ret;
104 u8 b0 [] = { reg };
105 u8 b1 [] = { 0 };
106 struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 },
107 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
108
109 ret = i2c_transfer (state->i2c, msg, 2);
110
111 if (ret != 2)
112 dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n",
113 __FUNCTION__, reg, ret);
114
115 return b1[0];
116}
117
118static int stv0299_readregs (struct stv0299_state* state, u8 reg1, u8 *b, u8 len)
119{
120 int ret;
121 struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = &reg1, .len = 1 },
122 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b, .len = len } };
123
124 ret = i2c_transfer (state->i2c, msg, 2);
125
126 if (ret != 2)
127 dprintk("%s: readreg error (ret == %i)\n", __FUNCTION__, ret);
128
129 return ret == 2 ? 0 : ret;
130}
131
132static int stv0299_set_FEC (struct stv0299_state* state, fe_code_rate_t fec)
133{
134 dprintk ("%s\n", __FUNCTION__);
135
136 switch (fec) {
137 case FEC_AUTO:
138 {
139 return stv0299_writeregI (state, 0x31, 0x1f);
140 }
141 case FEC_1_2:
142 {
143 return stv0299_writeregI (state, 0x31, 0x01);
144 }
145 case FEC_2_3:
146 {
147 return stv0299_writeregI (state, 0x31, 0x02);
148 }
149 case FEC_3_4:
150 {
151 return stv0299_writeregI (state, 0x31, 0x04);
152 }
153 case FEC_5_6:
154 {
155 return stv0299_writeregI (state, 0x31, 0x08);
156 }
157 case FEC_7_8:
158 {
159 return stv0299_writeregI (state, 0x31, 0x10);
160 }
161 default:
162 {
163 return -EINVAL;
164 }
165 }
166}
167
168static fe_code_rate_t stv0299_get_fec (struct stv0299_state* state)
169{
170 static fe_code_rate_t fec_tab [] = { FEC_2_3, FEC_3_4, FEC_5_6,
171 FEC_7_8, FEC_1_2 };
172 u8 index;
173
174 dprintk ("%s\n", __FUNCTION__);
175
176 index = stv0299_readreg (state, 0x1b);
177 index &= 0x7;
178
179 if (index > 4)
180 return FEC_AUTO;
181
182 return fec_tab [index];
183}
184
185static int stv0299_wait_diseqc_fifo (struct stv0299_state* state, int timeout)
186{
187 unsigned long start = jiffies;
188
189 dprintk ("%s\n", __FUNCTION__);
190
191 while (stv0299_readreg(state, 0x0a) & 1) {
192 if (jiffies - start > timeout) {
193 dprintk ("%s: timeout!!\n", __FUNCTION__);
194 return -ETIMEDOUT;
195 }
196 msleep(10);
197 };
198
199 return 0;
200}
201
202static int stv0299_wait_diseqc_idle (struct stv0299_state* state, int timeout)
203{
204 unsigned long start = jiffies;
205
206 dprintk ("%s\n", __FUNCTION__);
207
208 while ((stv0299_readreg(state, 0x0a) & 3) != 2 ) {
209 if (jiffies - start > timeout) {
210 dprintk ("%s: timeout!!\n", __FUNCTION__);
211 return -ETIMEDOUT;
212 }
213 msleep(10);
214 };
215
216 return 0;
217}
218
219static int stv0299_set_symbolrate (struct dvb_frontend* fe, u32 srate)
220{
221 struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv;
222 u64 big = srate;
223 u32 ratio;
224
225 // check rate is within limits
226 if ((srate < 1000000) || (srate > 45000000)) return -EINVAL;
227
228 // calculate value to program
229 big = big << 20;
230 big += (state->config->mclk-1); // round correctly
231 do_div(big, state->config->mclk);
232 ratio = big << 4;
233
234 return state->config->set_symbol_rate(fe, srate, ratio);
235}
236
237static int stv0299_get_symbolrate (struct stv0299_state* state)
238{
239 u32 Mclk = state->config->mclk / 4096L;
240 u32 srate;
241 s32 offset;
242 u8 sfr[3];
243 s8 rtf;
244
245 dprintk ("%s\n", __FUNCTION__);
246
247 stv0299_readregs (state, 0x1f, sfr, 3);
248 stv0299_readregs (state, 0x1a, &rtf, 1);
249
250 srate = (sfr[0] << 8) | sfr[1];
251 srate *= Mclk;
252 srate /= 16;
253 srate += (sfr[2] >> 4) * Mclk / 256;
254 offset = (s32) rtf * (srate / 4096L);
255 offset /= 128;
256
257 dprintk ("%s : srate = %i\n", __FUNCTION__, srate);
258 dprintk ("%s : ofset = %i\n", __FUNCTION__, offset);
259
260 srate += offset;
261
262 srate += 1000;
263 srate /= 2000;
264 srate *= 2000;
265
266 return srate;
267}
268
269static int stv0299_send_diseqc_msg (struct dvb_frontend* fe,
270 struct dvb_diseqc_master_cmd *m)
271{
272 struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv;
273 u8 val;
274 int i;
275
276 dprintk ("%s\n", __FUNCTION__);
277
278 if (stv0299_wait_diseqc_idle (state, 100) < 0)
279 return -ETIMEDOUT;
280
281 val = stv0299_readreg (state, 0x08);
282
283 if (stv0299_writeregI (state, 0x08, (val & ~0x7) | 0x6)) /* DiSEqC mode */
284 return -EREMOTEIO;
285
286 for (i=0; i<m->msg_len; i++) {
287 if (stv0299_wait_diseqc_fifo (state, 100) < 0)
288 return -ETIMEDOUT;
289
290 if (stv0299_writeregI (state, 0x09, m->msg[i]))
291 return -EREMOTEIO;
292 }
293
294 if (stv0299_wait_diseqc_idle (state, 100) < 0)
295 return -ETIMEDOUT;
296
297 return 0;
298}
299
300static int stv0299_send_diseqc_burst (struct dvb_frontend* fe, fe_sec_mini_cmd_t burst)
301{
302 struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv;
303 u8 val;
304
305 dprintk ("%s\n", __FUNCTION__);
306
307 if (stv0299_wait_diseqc_idle (state, 100) < 0)
308 return -ETIMEDOUT;
309
310 val = stv0299_readreg (state, 0x08);
311
312 if (stv0299_writeregI (state, 0x08, (val & ~0x7) | 0x2)) /* burst mode */
313 return -EREMOTEIO;
314
315 if (stv0299_writeregI (state, 0x09, burst == SEC_MINI_A ? 0x00 : 0xff))
316 return -EREMOTEIO;
317
318 if (stv0299_wait_diseqc_idle (state, 100) < 0)
319 return -ETIMEDOUT;
320
321 if (stv0299_writeregI (state, 0x08, val))
322 return -EREMOTEIO;
323
324 return 0;
325}
326
327static int stv0299_set_tone (struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
328{
329 struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv;
330 u8 val;
331
332 if (stv0299_wait_diseqc_idle (state, 100) < 0)
333 return -ETIMEDOUT;
334
335 val = stv0299_readreg (state, 0x08);
336
337 switch (tone) {
338 case SEC_TONE_ON:
339 return stv0299_writeregI (state, 0x08, val | 0x3);
340
341 case SEC_TONE_OFF:
342 return stv0299_writeregI (state, 0x08, (val & ~0x3) | 0x02);
343
344 default:
345 return -EINVAL;
346 }
347}
348
349static int stv0299_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltage)
350{
351 struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv;
352 u8 reg0x08;
353 u8 reg0x0c;
354
355 dprintk("%s: %s\n", __FUNCTION__,
356 voltage == SEC_VOLTAGE_13 ? "SEC_VOLTAGE_13" :
357 voltage == SEC_VOLTAGE_18 ? "SEC_VOLTAGE_18" : "??");
358
359 reg0x08 = stv0299_readreg (state, 0x08);
360 reg0x0c = stv0299_readreg (state, 0x0c);
361
362 /**
363 * H/V switching over OP0, OP1 and OP2 are LNB power enable bits
364 */
365 reg0x0c &= 0x0f;
366
367 if (voltage == SEC_VOLTAGE_OFF) {
368 stv0299_writeregI (state, 0x0c, 0x00); /* LNB power off! */
369 return stv0299_writeregI (state, 0x08, 0x00); /* LNB power off! */
370 }
371
372 stv0299_writeregI (state, 0x08, (reg0x08 & 0x3f) | (state->config->lock_output << 6));
373
374 switch (voltage) {
375 case SEC_VOLTAGE_13:
376 if (state->config->volt13_op0_op1 == STV0299_VOLT13_OP0) reg0x0c |= 0x10;
377 else reg0x0c |= 0x40;
378
379 return stv0299_writeregI(state, 0x0c, reg0x0c);
380
381 case SEC_VOLTAGE_18:
382 return stv0299_writeregI(state, 0x0c, reg0x0c | 0x50);
383 default:
384 return -EINVAL;
385 };
386}
387
388static int stv0299_send_legacy_dish_cmd(struct dvb_frontend* fe, u32 cmd)
389{
390 u8 last = 1;
391 int i;
392
393 /* reset voltage at the end
394 if((0x50 & stv0299_readreg (i2c, 0x0c)) == 0x50)
395 cmd |= 0x80;
396 else
397 cmd &= 0x7F;
398 */
399
400 cmd = cmd << 1;
401 dprintk("%s switch command: 0x%04x\n",__FUNCTION__, cmd);
402
403 stv0299_set_voltage(fe,SEC_VOLTAGE_18);
404 msleep(32);
405
406 for (i=0; i<9; i++) {
407 if((cmd & 0x01) != last) {
408 stv0299_set_voltage(fe, last ? SEC_VOLTAGE_13 : SEC_VOLTAGE_18);
409 last = (last) ? 0 : 1;
410 }
411
412 cmd = cmd >> 1;
413
414 if (i != 8)
415 msleep(8);
416 }
417
418 return 0;
419}
420
421static int stv0299_init (struct dvb_frontend* fe)
422{
423 struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv;
424 int i;
425
426 dprintk("stv0299: init chip\n");
427
428 for (i=0; !(state->config->inittab[i] == 0xff && state->config->inittab[i+1] == 0xff); i+=2)
429 stv0299_writeregI(state, state->config->inittab[i], state->config->inittab[i+1]);
430
431 if (state->config->pll_init) {
432 stv0299_writeregI(state, 0x05, 0xb5); /* enable i2c repeater on stv0299 */
433 state->config->pll_init(fe);
434 stv0299_writeregI(state, 0x05, 0x35); /* disable i2c repeater on stv0299 */
435 }
436
437 return 0;
438}
439
440static int stv0299_read_status(struct dvb_frontend* fe, fe_status_t* status)
441{
442 struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv;
443
444 u8 signal = 0xff - stv0299_readreg (state, 0x18);
445 u8 sync = stv0299_readreg (state, 0x1b);
446
447 dprintk ("%s : FE_READ_STATUS : VSTATUS: 0x%02x\n", __FUNCTION__, sync);
448 *status = 0;
449
450 if (signal > 10)
451 *status |= FE_HAS_SIGNAL;
452
453 if (sync & 0x80)
454 *status |= FE_HAS_CARRIER;
455
456 if (sync & 0x10)
457 *status |= FE_HAS_VITERBI;
458
459 if (sync & 0x08)
460 *status |= FE_HAS_SYNC;
461
462 if ((sync & 0x98) == 0x98)
463 *status |= FE_HAS_LOCK;
464
465 return 0;
466}
467
468static int stv0299_read_ber(struct dvb_frontend* fe, u32* ber)
469{
470 struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv;
471
472 if (state->errmode != STATUS_BER) return 0;
473 *ber = (stv0299_readreg (state, 0x1d) << 8) | stv0299_readreg (state, 0x1e);
474
475 return 0;
476}
477
478static int stv0299_read_signal_strength(struct dvb_frontend* fe, u16* strength)
479{
480 struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv;
481
482 s32 signal = 0xffff - ((stv0299_readreg (state, 0x18) << 8)
483 | stv0299_readreg (state, 0x19));
484
485 dprintk ("%s : FE_READ_SIGNAL_STRENGTH : AGC2I: 0x%02x%02x, signal=0x%04x\n", __FUNCTION__,
486 stv0299_readreg (state, 0x18),
487 stv0299_readreg (state, 0x19), (int) signal);
488
489 signal = signal * 5 / 4;
490 *strength = (signal > 0xffff) ? 0xffff : (signal < 0) ? 0 : signal;
491
492 return 0;
493}
494
495static int stv0299_read_snr(struct dvb_frontend* fe, u16* snr)
496{
497 struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv;
498
499 s32 xsnr = 0xffff - ((stv0299_readreg (state, 0x24) << 8)
500 | stv0299_readreg (state, 0x25));
501 xsnr = 3 * (xsnr - 0xa100);
502 *snr = (xsnr > 0xffff) ? 0xffff : (xsnr < 0) ? 0 : xsnr;
503
504 return 0;
505}
506
507static int stv0299_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
508{
509 struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv;
510
511 if (state->errmode != STATUS_UCBLOCKS) *ucblocks = 0;
512 else *ucblocks = (stv0299_readreg (state, 0x1d) << 8) | stv0299_readreg (state, 0x1e);
513
514 return 0;
515}
516
517static int stv0299_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters * p)
518{
519 struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv;
520 int invval = 0;
521
522 dprintk ("%s : FE_SET_FRONTEND\n", __FUNCTION__);
523
524 // set the inversion
525 if (p->inversion == INVERSION_OFF) invval = 0;
526 else if (p->inversion == INVERSION_ON) invval = 1;
527 else {
528 printk("stv0299 does not support auto-inversion\n");
529 return -EINVAL;
530 }
531 if (state->config->invert) invval = (~invval) & 1;
532 stv0299_writeregI(state, 0x0c, (stv0299_readreg(state, 0x0c) & 0xfe) | invval);
533
534 if (state->config->enhanced_tuning) {
535 /* check if we should do a finetune */
536 int frequency_delta = p->frequency - state->tuner_frequency;
537 int minmax = p->u.qpsk.symbol_rate / 2000;
538 if (minmax < 5000) minmax = 5000;
539
540 if ((frequency_delta > -minmax) && (frequency_delta < minmax) && (frequency_delta != 0) &&
541 (state->fec_inner == p->u.qpsk.fec_inner) &&
542 (state->symbol_rate == p->u.qpsk.symbol_rate)) {
543 int Drot_freq = (frequency_delta << 16) / (state->config->mclk / 1000);
544
545 // zap the derotator registers first
546 stv0299_writeregI(state, 0x22, 0x00);
547 stv0299_writeregI(state, 0x23, 0x00);
548
549 // now set them as we want
550 stv0299_writeregI(state, 0x22, Drot_freq >> 8);
551 stv0299_writeregI(state, 0x23, Drot_freq);
552 } else {
553 /* A "normal" tune is requested */
554 stv0299_writeregI(state, 0x05, 0xb5); /* enable i2c repeater on stv0299 */
555 state->config->pll_set(fe, p);
556 stv0299_writeregI(state, 0x05, 0x35); /* disable i2c repeater on stv0299 */
557
558 stv0299_writeregI(state, 0x32, 0x80);
559 stv0299_writeregI(state, 0x22, 0x00);
560 stv0299_writeregI(state, 0x23, 0x00);
561 stv0299_writeregI(state, 0x32, 0x19);
562 stv0299_set_symbolrate (fe, p->u.qpsk.symbol_rate);
563 stv0299_set_FEC (state, p->u.qpsk.fec_inner);
564 }
565 } else {
566 stv0299_writeregI(state, 0x05, 0xb5); /* enable i2c repeater on stv0299 */
567 state->config->pll_set(fe, p);
568 stv0299_writeregI(state, 0x05, 0x35); /* disable i2c repeater on stv0299 */
569
570 stv0299_set_FEC (state, p->u.qpsk.fec_inner);
571 stv0299_set_symbolrate (fe, p->u.qpsk.symbol_rate);
572 stv0299_writeregI(state, 0x22, 0x00);
573 stv0299_writeregI(state, 0x23, 0x00);
574 stv0299_readreg (state, 0x23);
575 stv0299_writeregI(state, 0x12, 0xb9);
576 }
577
578 state->tuner_frequency = p->frequency;
579 state->fec_inner = p->u.qpsk.fec_inner;
580 state->symbol_rate = p->u.qpsk.symbol_rate;
581
582 return 0;
583}
584
585static int stv0299_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters * p)
586{
587 struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv;
588 s32 derot_freq;
589 int invval;
590
591 derot_freq = (s32)(s16) ((stv0299_readreg (state, 0x22) << 8)
592 | stv0299_readreg (state, 0x23));
593
594 derot_freq *= (state->config->mclk >> 16);
595 derot_freq += 500;
596 derot_freq /= 1000;
597
598 p->frequency += derot_freq;
599
600 invval = stv0299_readreg (state, 0x0c) & 1;
601 if (state->config->invert) invval = (~invval) & 1;
602 p->inversion = invval ? INVERSION_ON : INVERSION_OFF;
603
604 p->u.qpsk.fec_inner = stv0299_get_fec (state);
605 p->u.qpsk.symbol_rate = stv0299_get_symbolrate (state);
606
607 return 0;
608}
609
610static int stv0299_sleep(struct dvb_frontend* fe)
611{
612 struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv;
613
614 stv0299_writeregI(state, 0x02, 0x80);
615 state->initialised = 0;
616
617 return 0;
618}
619
620static int stv0299_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
621{
622 struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv;
623
624 fesettings->min_delay_ms = state->config->min_delay_ms;
625 if (fesettings->parameters.u.qpsk.symbol_rate < 10000000) {
626 fesettings->step_size = fesettings->parameters.u.qpsk.symbol_rate / 32000;
627 fesettings->max_drift = 5000;
628 } else {
629 fesettings->step_size = fesettings->parameters.u.qpsk.symbol_rate / 16000;
630 fesettings->max_drift = fesettings->parameters.u.qpsk.symbol_rate / 2000;
631 }
632 return 0;
633}
634
635static void stv0299_release(struct dvb_frontend* fe)
636{
637 struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv;
638 kfree(state);
639}
640
641static struct dvb_frontend_ops stv0299_ops;
642
643struct dvb_frontend* stv0299_attach(const struct stv0299_config* config,
644 struct i2c_adapter* i2c)
645{
646 struct stv0299_state* state = NULL;
647 int id;
648
649 /* allocate memory for the internal state */
650 state = (struct stv0299_state*) kmalloc(sizeof(struct stv0299_state), GFP_KERNEL);
651 if (state == NULL) goto error;
652
653 /* setup the state */
654 state->config = config;
655 state->i2c = i2c;
656 memcpy(&state->ops, &stv0299_ops, sizeof(struct dvb_frontend_ops));
657 state->initialised = 0;
658 state->tuner_frequency = 0;
659 state->symbol_rate = 0;
660 state->fec_inner = 0;
661 state->errmode = STATUS_BER;
662
663 /* check if the demod is there */
664 stv0299_writeregI(state, 0x02, 0x34); /* standby off */
665 msleep(200);
666 id = stv0299_readreg(state, 0x00);
667
668 /* register 0x00 contains 0xa1 for STV0299 and STV0299B */
669 /* register 0x00 might contain 0x80 when returning from standby */
670 if (id != 0xa1 && id != 0x80) goto error;
671
672 /* create dvb_frontend */
673 state->frontend.ops = &state->ops;
674 state->frontend.demodulator_priv = state;
675 return &state->frontend;
676
677error:
678 kfree(state);
679 return NULL;
680}
681
682static struct dvb_frontend_ops stv0299_ops = {
683
684 .info = {
685 .name = "ST STV0299 DVB-S",
686 .type = FE_QPSK,
687 .frequency_min = 950000,
688 .frequency_max = 2150000,
689 .frequency_stepsize = 125, /* kHz for QPSK frontends */
690 .frequency_tolerance = 0,
691 .symbol_rate_min = 1000000,
692 .symbol_rate_max = 45000000,
693 .symbol_rate_tolerance = 500, /* ppm */
694 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
695 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
696 FE_CAN_QPSK |
697 FE_CAN_FEC_AUTO
698 },
699
700 .release = stv0299_release,
701
702 .init = stv0299_init,
703 .sleep = stv0299_sleep,
704
705 .set_frontend = stv0299_set_frontend,
706 .get_frontend = stv0299_get_frontend,
707 .get_tune_settings = stv0299_get_tune_settings,
708
709 .read_status = stv0299_read_status,
710 .read_ber = stv0299_read_ber,
711 .read_signal_strength = stv0299_read_signal_strength,
712 .read_snr = stv0299_read_snr,
713 .read_ucblocks = stv0299_read_ucblocks,
714
715 .diseqc_send_master_cmd = stv0299_send_diseqc_msg,
716 .diseqc_send_burst = stv0299_send_diseqc_burst,
717 .set_tone = stv0299_set_tone,
718 .set_voltage = stv0299_set_voltage,
719 .dishnetwork_send_legacy_command = stv0299_send_legacy_dish_cmd,
720};
721
722module_param(debug, int, 0644);
723MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
724
725MODULE_DESCRIPTION("ST STV0299 DVB Demodulator driver");
726MODULE_AUTHOR("Ralph Metzler, Holger Waechtler, Peter Schildmann, Felix Domke, "
727 "Andreas Oberritter, Andrew de Quincey, Kenneth Aafløy");
728MODULE_LICENSE("GPL");
729
730EXPORT_SYMBOL(stv0299_writereg);
731EXPORT_SYMBOL(stv0299_attach);
diff --git a/drivers/media/dvb/frontends/stv0299.h b/drivers/media/dvb/frontends/stv0299.h
new file mode 100644
index 000000000000..79457a80a11f
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv0299.h
@@ -0,0 +1,104 @@
1/*
2 Driver for ST STV0299 demodulator
3
4 Copyright (C) 2001-2002 Convergence Integrated Media GmbH
5 <ralph@convergence.de>,
6 <holger@convergence.de>,
7 <js@convergence.de>
8
9
10 Philips SU1278/SH
11
12 Copyright (C) 2002 by Peter Schildmann <peter.schildmann@web.de>
13
14
15 LG TDQF-S001F
16
17 Copyright (C) 2002 Felix Domke <tmbinc@elitedvb.net>
18 & Andreas Oberritter <obi@linuxtv.org>
19
20
21 Support for Samsung TBMU24112IMB used on Technisat SkyStar2 rev. 2.6B
22
23 Copyright (C) 2003 Vadim Catana <skystar@moldova.cc>:
24
25 Support for Philips SU1278 on Technotrend hardware
26
27 Copyright (C) 2004 Andrew de Quincey <adq_dvb@lidskialf.net>
28
29 This program is free software; you can redistribute it and/or modify
30 it under the terms of the GNU General Public License as published by
31 the Free Software Foundation; either version 2 of the License, or
32 (at your option) any later version.
33
34 This program is distributed in the hope that it will be useful,
35 but WITHOUT ANY WARRANTY; without even the implied warranty of
36 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
37 GNU General Public License for more details.
38
39 You should have received a copy of the GNU General Public License
40 along with this program; if not, write to the Free Software
41 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
42
43*/
44
45#ifndef STV0299_H
46#define STV0299_H
47
48#include <linux/dvb/frontend.h>
49#include "dvb_frontend.h"
50
51#define STV0229_LOCKOUTPUT_0 0
52#define STV0229_LOCKOUTPUT_1 1
53#define STV0229_LOCKOUTPUT_CF 2
54#define STV0229_LOCKOUTPUT_LK 3
55
56#define STV0299_VOLT13_OP0 0
57#define STV0299_VOLT13_OP1 1
58
59struct stv0299_config
60{
61 /* the demodulator's i2c address */
62 u8 demod_address;
63
64 /* inittab - array of pairs of values.
65 * First of each pair is the register, second is the value.
66 * List should be terminated with an 0xff, 0xff pair.
67 */
68 u8* inittab;
69
70 /* master clock to use */
71 u32 mclk;
72
73 /* does the inversion require inversion? */
74 u8 invert:1;
75
76 /* Should the enhanced tuning code be used? */
77 u8 enhanced_tuning:1;
78
79 /* Skip reinitialisation? */
80 u8 skip_reinit:1;
81
82 /* LOCK OUTPUT setting */
83 u8 lock_output:2;
84
85 /* Is 13v controlled by OP0 or OP1? */
86 u8 volt13_op0_op1:1;
87
88 /* minimum delay before retuning */
89 int min_delay_ms;
90
91 /* Set the symbol rate */
92 int (*set_symbol_rate)(struct dvb_frontend* fe, u32 srate, u32 ratio);
93
94 /* PLL maintenance */
95 int (*pll_init)(struct dvb_frontend* fe);
96 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
97};
98
99extern int stv0299_writereg (struct dvb_frontend* fe, u8 reg, u8 data);
100
101extern struct dvb_frontend* stv0299_attach(const struct stv0299_config* config,
102 struct i2c_adapter* i2c);
103
104#endif // STV0299_H
diff --git a/drivers/media/dvb/frontends/tda10021.c b/drivers/media/dvb/frontends/tda10021.c
new file mode 100644
index 000000000000..4e40d95ee95d
--- /dev/null
+++ b/drivers/media/dvb/frontends/tda10021.c
@@ -0,0 +1,469 @@
1/*
2 TDA10021 - Single Chip Cable Channel Receiver driver module
3 used on the the Siemens DVB-C cards
4
5 Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de>
6 Copyright (C) 2004 Markus Schulz <msc@antzsystem.de>
7 Support for TDA10021
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#include <linux/config.h>
25#include <linux/delay.h>
26#include <linux/errno.h>
27#include <linux/init.h>
28#include <linux/kernel.h>
29#include <linux/module.h>
30#include <linux/string.h>
31#include <linux/slab.h>
32
33#include "dvb_frontend.h"
34#include "tda10021.h"
35
36
37struct tda10021_state {
38 struct i2c_adapter* i2c;
39 struct dvb_frontend_ops ops;
40 /* configuration settings */
41 const struct tda10021_config* config;
42 struct dvb_frontend frontend;
43
44 u8 pwm;
45 u8 reg0;
46};
47
48
49#if 0
50#define dprintk(x...) printk(x)
51#else
52#define dprintk(x...)
53#endif
54
55static int verbose;
56
57#define XIN 57840000UL
58#define DISABLE_INVERSION(reg0) do { reg0 |= 0x20; } while (0)
59#define ENABLE_INVERSION(reg0) do { reg0 &= ~0x20; } while (0)
60#define HAS_INVERSION(reg0) (!(reg0 & 0x20))
61
62#define FIN (XIN >> 4)
63
64static int tda10021_inittab_size = 0x40;
65static u8 tda10021_inittab[0x40]=
66{
67 0x73, 0x6a, 0x23, 0x0a, 0x02, 0x37, 0x77, 0x1a,
68 0x37, 0x6a, 0x17, 0x8a, 0x1e, 0x86, 0x43, 0x40,
69 0xb8, 0x3f, 0xa0, 0x00, 0xcd, 0x01, 0x00, 0xff,
70 0x11, 0x00, 0x7c, 0x31, 0x30, 0x20, 0x00, 0x00,
71 0x02, 0x00, 0x00, 0x7d, 0x00, 0x00, 0x00, 0x00,
72 0x07, 0x00, 0x33, 0x11, 0x0d, 0x95, 0x08, 0x58,
73 0x00, 0x00, 0x80, 0x00, 0x80, 0xff, 0x00, 0x00,
74 0x04, 0x2d, 0x2f, 0xff, 0x00, 0x00, 0x00, 0x00,
75};
76
77static int tda10021_writereg (struct tda10021_state* state, u8 reg, u8 data)
78{
79 u8 buf[] = { reg, data };
80 struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 };
81 int ret;
82
83 ret = i2c_transfer (state->i2c, &msg, 1);
84 if (ret != 1)
85 printk("DVB: TDA10021(%d): %s, writereg error "
86 "(reg == 0x%02x, val == 0x%02x, ret == %i)\n",
87 state->frontend.dvb->num, __FUNCTION__, reg, data, ret);
88
89 msleep(10);
90 return (ret != 1) ? -EREMOTEIO : 0;
91}
92
93static u8 tda10021_readreg (struct tda10021_state* state, u8 reg)
94{
95 u8 b0 [] = { reg };
96 u8 b1 [] = { 0 };
97 struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 },
98 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
99 int ret;
100
101 ret = i2c_transfer (state->i2c, msg, 2);
102 if (ret != 2)
103 printk("DVB: TDA10021(%d): %s: readreg error (ret == %i)\n",
104 state->frontend.dvb->num, __FUNCTION__, ret);
105 return b1[0];
106}
107
108//get access to tuner
109static int lock_tuner(struct tda10021_state* state)
110{
111 u8 buf[2] = { 0x0f, tda10021_inittab[0x0f] | 0x80 };
112 struct i2c_msg msg = {.addr=state->config->demod_address, .flags=0, .buf=buf, .len=2};
113
114 if(i2c_transfer(state->i2c, &msg, 1) != 1)
115 {
116 printk("tda10021: lock tuner fails\n");
117 return -EREMOTEIO;
118 }
119 return 0;
120}
121
122//release access from tuner
123static int unlock_tuner(struct tda10021_state* state)
124{
125 u8 buf[2] = { 0x0f, tda10021_inittab[0x0f] & 0x7f };
126 struct i2c_msg msg_post={.addr=state->config->demod_address, .flags=0, .buf=buf, .len=2};
127
128 if(i2c_transfer(state->i2c, &msg_post, 1) != 1)
129 {
130 printk("tda10021: unlock tuner fails\n");
131 return -EREMOTEIO;
132 }
133 return 0;
134}
135
136static int tda10021_setup_reg0 (struct tda10021_state* state, u8 reg0,
137 fe_spectral_inversion_t inversion)
138{
139 reg0 |= state->reg0 & 0x63;
140
141 if (INVERSION_ON == inversion)
142 ENABLE_INVERSION(reg0);
143 else if (INVERSION_OFF == inversion)
144 DISABLE_INVERSION(reg0);
145
146 tda10021_writereg (state, 0x00, reg0 & 0xfe);
147 tda10021_writereg (state, 0x00, reg0 | 0x01);
148
149 state->reg0 = reg0;
150 return 0;
151}
152
153static int tda10021_set_symbolrate (struct tda10021_state* state, u32 symbolrate)
154{
155 s32 BDR;
156 s32 BDRI;
157 s16 SFIL=0;
158 u16 NDEC = 0;
159 u32 tmp, ratio;
160
161 if (symbolrate > XIN/2)
162 symbolrate = XIN/2;
163 if (symbolrate < 500000)
164 symbolrate = 500000;
165
166 if (symbolrate < XIN/16) NDEC = 1;
167 if (symbolrate < XIN/32) NDEC = 2;
168 if (symbolrate < XIN/64) NDEC = 3;
169
170 if (symbolrate < (u32)(XIN/12.3)) SFIL = 1;
171 if (symbolrate < (u32)(XIN/16)) SFIL = 0;
172 if (symbolrate < (u32)(XIN/24.6)) SFIL = 1;
173 if (symbolrate < (u32)(XIN/32)) SFIL = 0;
174 if (symbolrate < (u32)(XIN/49.2)) SFIL = 1;
175 if (symbolrate < (u32)(XIN/64)) SFIL = 0;
176 if (symbolrate < (u32)(XIN/98.4)) SFIL = 1;
177
178 symbolrate <<= NDEC;
179 ratio = (symbolrate << 4) / FIN;
180 tmp = ((symbolrate << 4) % FIN) << 8;
181 ratio = (ratio << 8) + tmp / FIN;
182 tmp = (tmp % FIN) << 8;
183 ratio = (ratio << 8) + (tmp + FIN/2) / FIN;
184
185 BDR = ratio;
186 BDRI = (((XIN << 5) / symbolrate) + 1) / 2;
187
188 if (BDRI > 0xFF)
189 BDRI = 0xFF;
190
191 SFIL = (SFIL << 4) | tda10021_inittab[0x0E];
192
193 NDEC = (NDEC << 6) | tda10021_inittab[0x03];
194
195 tda10021_writereg (state, 0x03, NDEC);
196 tda10021_writereg (state, 0x0a, BDR&0xff);
197 tda10021_writereg (state, 0x0b, (BDR>> 8)&0xff);
198 tda10021_writereg (state, 0x0c, (BDR>>16)&0x3f);
199
200 tda10021_writereg (state, 0x0d, BDRI);
201 tda10021_writereg (state, 0x0e, SFIL);
202
203 return 0;
204}
205
206static int tda10021_init (struct dvb_frontend *fe)
207{
208 struct tda10021_state* state = (struct tda10021_state*) fe->demodulator_priv;
209 int i;
210
211 dprintk("DVB: TDA10021(%d): init chip\n", fe->adapter->num);
212
213 //tda10021_writereg (fe, 0, 0);
214
215 for (i=0; i<tda10021_inittab_size; i++)
216 tda10021_writereg (state, i, tda10021_inittab[i]);
217
218 tda10021_writereg (state, 0x34, state->pwm);
219
220 //Comment by markus
221 //0x2A[3-0] == PDIV -> P multiplaying factor (P=PDIV+1)(default 0)
222 //0x2A[4] == BYPPLL -> Power down mode (default 1)
223 //0x2A[5] == LCK -> PLL Lock Flag
224 //0x2A[6] == POLAXIN -> Polarity of the input reference clock (default 0)
225
226 //Activate PLL
227 tda10021_writereg(state, 0x2a, tda10021_inittab[0x2a] & 0xef);
228
229 if (state->config->pll_init) {
230 lock_tuner(state);
231 state->config->pll_init(fe);
232 unlock_tuner(state);
233 }
234
235 return 0;
236}
237
238static int tda10021_set_parameters (struct dvb_frontend *fe,
239 struct dvb_frontend_parameters *p)
240{
241 struct tda10021_state* state = (struct tda10021_state*) fe->demodulator_priv;
242
243 //table for QAM4-QAM256 ready QAM4 QAM16 QAM32 QAM64 QAM128 QAM256
244 //CONF
245 static const u8 reg0x00 [] = { 0x14, 0x00, 0x04, 0x08, 0x0c, 0x10 };
246 //AGCREF value
247 static const u8 reg0x01 [] = { 0x78, 0x8c, 0x8c, 0x6a, 0x78, 0x5c };
248 //LTHR value
249 static const u8 reg0x05 [] = { 0x78, 0x87, 0x64, 0x46, 0x36, 0x26 };
250 //MSETH
251 static const u8 reg0x08 [] = { 0x8c, 0xa2, 0x74, 0x43, 0x34, 0x23 };
252 //AREF
253 static const u8 reg0x09 [] = { 0x96, 0x91, 0x96, 0x6a, 0x7e, 0x6b };
254
255 int qam = p->u.qam.modulation;
256
257 if (qam < 0 || qam > 5)
258 return -EINVAL;
259
260 //printk("tda10021: set frequency to %d qam=%d symrate=%d\n", p->frequency,qam,p->u.qam.symbol_rate);
261
262 lock_tuner(state);
263 state->config->pll_set(fe, p);
264 unlock_tuner(state);
265
266 tda10021_set_symbolrate (state, p->u.qam.symbol_rate);
267 tda10021_writereg (state, 0x34, state->pwm);
268
269 tda10021_writereg (state, 0x01, reg0x01[qam]);
270 tda10021_writereg (state, 0x05, reg0x05[qam]);
271 tda10021_writereg (state, 0x08, reg0x08[qam]);
272 tda10021_writereg (state, 0x09, reg0x09[qam]);
273
274 tda10021_setup_reg0 (state, reg0x00[qam], p->inversion);
275
276 return 0;
277}
278
279static int tda10021_read_status(struct dvb_frontend* fe, fe_status_t* status)
280{
281 struct tda10021_state* state = (struct tda10021_state*) fe->demodulator_priv;
282 int sync;
283
284 *status = 0;
285 //0x11[0] == EQALGO -> Equalizer algorithms state
286 //0x11[1] == CARLOCK -> Carrier locked
287 //0x11[2] == FSYNC -> Frame synchronisation
288 //0x11[3] == FEL -> Front End locked
289 //0x11[6] == NODVB -> DVB Mode Information
290 sync = tda10021_readreg (state, 0x11);
291
292 if (sync & 2)
293 *status |= FE_HAS_SIGNAL|FE_HAS_CARRIER;
294
295 if (sync & 4)
296 *status |= FE_HAS_SYNC|FE_HAS_VITERBI;
297
298 if (sync & 8)
299 *status |= FE_HAS_LOCK;
300
301 return 0;
302}
303
304static int tda10021_read_ber(struct dvb_frontend* fe, u32* ber)
305{
306 struct tda10021_state* state = (struct tda10021_state*) fe->demodulator_priv;
307
308 u32 _ber = tda10021_readreg(state, 0x14) |
309 (tda10021_readreg(state, 0x15) << 8) |
310 ((tda10021_readreg(state, 0x16) & 0x0f) << 16);
311 *ber = 10 * _ber;
312
313 return 0;
314}
315
316static int tda10021_read_signal_strength(struct dvb_frontend* fe, u16* strength)
317{
318 struct tda10021_state* state = (struct tda10021_state*) fe->demodulator_priv;
319
320 u8 gain = tda10021_readreg(state, 0x17);
321 *strength = (gain << 8) | gain;
322
323 return 0;
324}
325
326static int tda10021_read_snr(struct dvb_frontend* fe, u16* snr)
327{
328 struct tda10021_state* state = (struct tda10021_state*) fe->demodulator_priv;
329
330 u8 quality = ~tda10021_readreg(state, 0x18);
331 *snr = (quality << 8) | quality;
332
333 return 0;
334}
335
336static int tda10021_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
337{
338 struct tda10021_state* state = (struct tda10021_state*) fe->demodulator_priv;
339
340 *ucblocks = tda10021_readreg (state, 0x13) & 0x7f;
341 if (*ucblocks == 0x7f)
342 *ucblocks = 0xffffffff;
343
344 /* reset uncorrected block counter */
345 tda10021_writereg (state, 0x10, tda10021_inittab[0x10] & 0xdf);
346 tda10021_writereg (state, 0x10, tda10021_inittab[0x10]);
347
348 return 0;
349}
350
351static int tda10021_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
352{
353 struct tda10021_state* state = (struct tda10021_state*) fe->demodulator_priv;
354 int sync;
355 s8 afc = 0;
356
357 sync = tda10021_readreg(state, 0x11);
358 afc = tda10021_readreg(state, 0x19);
359 if (verbose) {
360 /* AFC only valid when carrier has been recovered */
361 printk(sync & 2 ? "DVB: TDA10021(%d): AFC (%d) %dHz\n" :
362 "DVB: TDA10021(%d): [AFC (%d) %dHz]\n",
363 state->frontend.dvb->num, afc,
364 -((s32)p->u.qam.symbol_rate * afc) >> 10);
365 }
366
367 p->inversion = HAS_INVERSION(state->reg0) ? INVERSION_ON : INVERSION_OFF;
368 p->u.qam.modulation = ((state->reg0 >> 2) & 7) + QAM_16;
369
370 p->u.qam.fec_inner = FEC_NONE;
371 p->frequency = ((p->frequency + 31250) / 62500) * 62500;
372
373 if (sync & 2)
374 p->frequency -= ((s32)p->u.qam.symbol_rate * afc) >> 10;
375
376 return 0;
377}
378
379static int tda10021_sleep(struct dvb_frontend* fe)
380{
381 struct tda10021_state* state = (struct tda10021_state*) fe->demodulator_priv;
382
383 tda10021_writereg (state, 0x1b, 0x02); /* pdown ADC */
384 tda10021_writereg (state, 0x00, 0x80); /* standby */
385
386 return 0;
387}
388
389static void tda10021_release(struct dvb_frontend* fe)
390{
391 struct tda10021_state* state = (struct tda10021_state*) fe->demodulator_priv;
392 kfree(state);
393}
394
395static struct dvb_frontend_ops tda10021_ops;
396
397struct dvb_frontend* tda10021_attach(const struct tda10021_config* config,
398 struct i2c_adapter* i2c,
399 u8 pwm)
400{
401 struct tda10021_state* state = NULL;
402
403 /* allocate memory for the internal state */
404 state = (struct tda10021_state*) kmalloc(sizeof(struct tda10021_state), GFP_KERNEL);
405 if (state == NULL) goto error;
406
407 /* setup the state */
408 state->config = config;
409 state->i2c = i2c;
410 memcpy(&state->ops, &tda10021_ops, sizeof(struct dvb_frontend_ops));
411 state->pwm = pwm;
412 state->reg0 = tda10021_inittab[0];
413
414 /* check if the demod is there */
415 if ((tda10021_readreg(state, 0x1a) & 0xf0) != 0x70) goto error;
416
417 /* create dvb_frontend */
418 state->frontend.ops = &state->ops;
419 state->frontend.demodulator_priv = state;
420 return &state->frontend;
421
422error:
423 kfree(state);
424 return NULL;
425}
426
427static struct dvb_frontend_ops tda10021_ops = {
428
429 .info = {
430 .name = "Philips TDA10021 DVB-C",
431 .type = FE_QAM,
432 .frequency_stepsize = 62500,
433 .frequency_min = 51000000,
434 .frequency_max = 858000000,
435 .symbol_rate_min = (XIN/2)/64, /* SACLK/64 == (XIN/2)/64 */
436 .symbol_rate_max = (XIN/2)/4, /* SACLK/4 */
437 #if 0
438 .frequency_tolerance = ???,
439 .symbol_rate_tolerance = ???, /* ppm */ /* == 8% (spec p. 5) */
440 #endif
441 .caps = 0x400 | //FE_CAN_QAM_4
442 FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
443 FE_CAN_QAM_128 | FE_CAN_QAM_256 |
444 FE_CAN_FEC_AUTO
445 },
446
447 .release = tda10021_release,
448
449 .init = tda10021_init,
450 .sleep = tda10021_sleep,
451
452 .set_frontend = tda10021_set_parameters,
453 .get_frontend = tda10021_get_frontend,
454
455 .read_status = tda10021_read_status,
456 .read_ber = tda10021_read_ber,
457 .read_signal_strength = tda10021_read_signal_strength,
458 .read_snr = tda10021_read_snr,
459 .read_ucblocks = tda10021_read_ucblocks,
460};
461
462module_param(verbose, int, 0644);
463MODULE_PARM_DESC(verbose, "print AFC offset after tuning for debugging the PWM setting");
464
465MODULE_DESCRIPTION("Philips TDA10021 DVB-C demodulator driver");
466MODULE_AUTHOR("Ralph Metzler, Holger Waechtler, Markus Schulz");
467MODULE_LICENSE("GPL");
468
469EXPORT_SYMBOL(tda10021_attach);
diff --git a/drivers/media/dvb/frontends/tda10021.h b/drivers/media/dvb/frontends/tda10021.h
new file mode 100644
index 000000000000..7d6a51ce291e
--- /dev/null
+++ b/drivers/media/dvb/frontends/tda10021.h
@@ -0,0 +1,42 @@
1/*
2 TDA10021 - Single Chip Cable Channel Receiver driver module
3 used on the the Siemens DVB-C cards
4
5 Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de>
6 Copyright (C) 2004 Markus Schulz <msc@antzsystem.de>
7 Support for TDA10021
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#ifndef TDA10021_H
25#define TDA10021_H
26
27#include <linux/dvb/frontend.h>
28
29struct tda10021_config
30{
31 /* the demodulator's i2c address */
32 u8 demod_address;
33
34 /* PLL maintenance */
35 int (*pll_init)(struct dvb_frontend* fe);
36 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
37};
38
39extern struct dvb_frontend* tda10021_attach(const struct tda10021_config* config,
40 struct i2c_adapter* i2c, u8 pwm);
41
42#endif // TDA10021_H
diff --git a/drivers/media/dvb/frontends/tda1004x.c b/drivers/media/dvb/frontends/tda1004x.c
new file mode 100644
index 000000000000..687ad9cf3384
--- /dev/null
+++ b/drivers/media/dvb/frontends/tda1004x.c
@@ -0,0 +1,1206 @@
1 /*
2 Driver for Philips tda1004xh OFDM Demodulator
3
4 (c) 2003, 2004 Andrew de Quincey & Robert Schlabbach
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21 */
22/*
23 * This driver needs external firmware. Please use the commands
24 * "<kerneldir>/Documentation/dvb/get_dvb_firmware tda10045",
25 * "<kerneldir>/Documentation/dvb/get_dvb_firmware tda10046" to
26 * download/extract them, and then copy them to /usr/lib/hotplug/firmware.
27 */
28#define TDA10045_DEFAULT_FIRMWARE "dvb-fe-tda10045.fw"
29#define TDA10046_DEFAULT_FIRMWARE "dvb-fe-tda10046.fw"
30
31#include <linux/init.h>
32#include <linux/module.h>
33#include <linux/moduleparam.h>
34#include <linux/device.h>
35#include "dvb_frontend.h"
36#include "tda1004x.h"
37
38#define TDA1004X_DEMOD_TDA10045 0
39#define TDA1004X_DEMOD_TDA10046 1
40
41
42struct tda1004x_state {
43 struct i2c_adapter* i2c;
44 struct dvb_frontend_ops ops;
45 const struct tda1004x_config* config;
46 struct dvb_frontend frontend;
47
48 /* private demod data */
49 u8 initialised:1;
50 u8 demod_type;
51};
52
53
54static int debug;
55#define dprintk(args...) \
56 do { \
57 if (debug) printk(KERN_DEBUG "tda1004x: " args); \
58 } while (0)
59
60#define TDA1004X_CHIPID 0x00
61#define TDA1004X_AUTO 0x01
62#define TDA1004X_IN_CONF1 0x02
63#define TDA1004X_IN_CONF2 0x03
64#define TDA1004X_OUT_CONF1 0x04
65#define TDA1004X_OUT_CONF2 0x05
66#define TDA1004X_STATUS_CD 0x06
67#define TDA1004X_CONFC4 0x07
68#define TDA1004X_DSSPARE2 0x0C
69#define TDA10045H_CODE_IN 0x0D
70#define TDA10045H_FWPAGE 0x0E
71#define TDA1004X_SCAN_CPT 0x10
72#define TDA1004X_DSP_CMD 0x11
73#define TDA1004X_DSP_ARG 0x12
74#define TDA1004X_DSP_DATA1 0x13
75#define TDA1004X_DSP_DATA2 0x14
76#define TDA1004X_CONFADC1 0x15
77#define TDA1004X_CONFC1 0x16
78#define TDA10045H_S_AGC 0x1a
79#define TDA10046H_AGC_TUN_LEVEL 0x1a
80#define TDA1004X_SNR 0x1c
81#define TDA1004X_CONF_TS1 0x1e
82#define TDA1004X_CONF_TS2 0x1f
83#define TDA1004X_CBER_RESET 0x20
84#define TDA1004X_CBER_MSB 0x21
85#define TDA1004X_CBER_LSB 0x22
86#define TDA1004X_CVBER_LUT 0x23
87#define TDA1004X_VBER_MSB 0x24
88#define TDA1004X_VBER_MID 0x25
89#define TDA1004X_VBER_LSB 0x26
90#define TDA1004X_UNCOR 0x27
91
92#define TDA10045H_CONFPLL_P 0x2D
93#define TDA10045H_CONFPLL_M_MSB 0x2E
94#define TDA10045H_CONFPLL_M_LSB 0x2F
95#define TDA10045H_CONFPLL_N 0x30
96
97#define TDA10046H_CONFPLL1 0x2D
98#define TDA10046H_CONFPLL2 0x2F
99#define TDA10046H_CONFPLL3 0x30
100#define TDA10046H_TIME_WREF1 0x31
101#define TDA10046H_TIME_WREF2 0x32
102#define TDA10046H_TIME_WREF3 0x33
103#define TDA10046H_TIME_WREF4 0x34
104#define TDA10046H_TIME_WREF5 0x35
105
106#define TDA10045H_UNSURW_MSB 0x31
107#define TDA10045H_UNSURW_LSB 0x32
108#define TDA10045H_WREF_MSB 0x33
109#define TDA10045H_WREF_MID 0x34
110#define TDA10045H_WREF_LSB 0x35
111#define TDA10045H_MUXOUT 0x36
112#define TDA1004X_CONFADC2 0x37
113
114#define TDA10045H_IOFFSET 0x38
115
116#define TDA10046H_CONF_TRISTATE1 0x3B
117#define TDA10046H_CONF_TRISTATE2 0x3C
118#define TDA10046H_CONF_POLARITY 0x3D
119#define TDA10046H_FREQ_OFFSET 0x3E
120#define TDA10046H_GPIO_OUT_SEL 0x41
121#define TDA10046H_GPIO_SELECT 0x42
122#define TDA10046H_AGC_CONF 0x43
123#define TDA10046H_AGC_GAINS 0x46
124#define TDA10046H_AGC_TUN_MIN 0x47
125#define TDA10046H_AGC_TUN_MAX 0x48
126#define TDA10046H_AGC_IF_MIN 0x49
127#define TDA10046H_AGC_IF_MAX 0x4A
128
129#define TDA10046H_FREQ_PHY2_MSB 0x4D
130#define TDA10046H_FREQ_PHY2_LSB 0x4E
131
132#define TDA10046H_CVBER_CTRL 0x4F
133#define TDA10046H_AGC_IF_LEVEL 0x52
134#define TDA10046H_CODE_CPT 0x57
135#define TDA10046H_CODE_IN 0x58
136
137
138static int tda1004x_write_byteI(struct tda1004x_state *state, int reg, int data)
139{
140 int ret;
141 u8 buf[] = { reg, data };
142 struct i2c_msg msg = { .addr=0, .flags=0, .buf=buf, .len=2 };
143
144 dprintk("%s: reg=0x%x, data=0x%x\n", __FUNCTION__, reg, data);
145
146 msg.addr = state->config->demod_address;
147 ret = i2c_transfer(state->i2c, &msg, 1);
148
149 if (ret != 1)
150 dprintk("%s: error reg=0x%x, data=0x%x, ret=%i\n",
151 __FUNCTION__, reg, data, ret);
152
153 dprintk("%s: success reg=0x%x, data=0x%x, ret=%i\n", __FUNCTION__,
154 reg, data, ret);
155 return (ret != 1) ? -1 : 0;
156}
157
158static int tda1004x_read_byte(struct tda1004x_state *state, int reg)
159{
160 int ret;
161 u8 b0[] = { reg };
162 u8 b1[] = { 0 };
163 struct i2c_msg msg[] = {{ .addr=0, .flags=0, .buf=b0, .len=1},
164 { .addr=0, .flags=I2C_M_RD, .buf=b1, .len = 1}};
165
166 dprintk("%s: reg=0x%x\n", __FUNCTION__, reg);
167
168 msg[0].addr = state->config->demod_address;
169 msg[1].addr = state->config->demod_address;
170 ret = i2c_transfer(state->i2c, msg, 2);
171
172 if (ret != 2) {
173 dprintk("%s: error reg=0x%x, ret=%i\n", __FUNCTION__, reg,
174 ret);
175 return -1;
176 }
177
178 dprintk("%s: success reg=0x%x, data=0x%x, ret=%i\n", __FUNCTION__,
179 reg, b1[0], ret);
180 return b1[0];
181}
182
183static int tda1004x_write_mask(struct tda1004x_state *state, int reg, int mask, int data)
184{
185 int val;
186 dprintk("%s: reg=0x%x, mask=0x%x, data=0x%x\n", __FUNCTION__, reg,
187 mask, data);
188
189 // read a byte and check
190 val = tda1004x_read_byte(state, reg);
191 if (val < 0)
192 return val;
193
194 // mask if off
195 val = val & ~mask;
196 val |= data & 0xff;
197
198 // write it out again
199 return tda1004x_write_byteI(state, reg, val);
200}
201
202static int tda1004x_write_buf(struct tda1004x_state *state, int reg, unsigned char *buf, int len)
203{
204 int i;
205 int result;
206
207 dprintk("%s: reg=0x%x, len=0x%x\n", __FUNCTION__, reg, len);
208
209 result = 0;
210 for (i = 0; i < len; i++) {
211 result = tda1004x_write_byteI(state, reg + i, buf[i]);
212 if (result != 0)
213 break;
214 }
215
216 return result;
217}
218
219static int tda1004x_enable_tuner_i2c(struct tda1004x_state *state)
220{
221 int result;
222 dprintk("%s\n", __FUNCTION__);
223
224 result = tda1004x_write_mask(state, TDA1004X_CONFC4, 2, 2);
225 msleep(1);
226 return result;
227}
228
229static int tda1004x_disable_tuner_i2c(struct tda1004x_state *state)
230{
231 dprintk("%s\n", __FUNCTION__);
232
233 return tda1004x_write_mask(state, TDA1004X_CONFC4, 2, 0);
234}
235
236static int tda10045h_set_bandwidth(struct tda1004x_state *state,
237 fe_bandwidth_t bandwidth)
238{
239 static u8 bandwidth_6mhz[] = { 0x02, 0x00, 0x3d, 0x00, 0x60, 0x1e, 0xa7, 0x45, 0x4f };
240 static u8 bandwidth_7mhz[] = { 0x02, 0x00, 0x37, 0x00, 0x4a, 0x2f, 0x6d, 0x76, 0xdb };
241 static u8 bandwidth_8mhz[] = { 0x02, 0x00, 0x3d, 0x00, 0x48, 0x17, 0x89, 0xc7, 0x14 };
242
243 switch (bandwidth) {
244 case BANDWIDTH_6_MHZ:
245 tda1004x_write_buf(state, TDA10045H_CONFPLL_P, bandwidth_6mhz, sizeof(bandwidth_6mhz));
246 break;
247
248 case BANDWIDTH_7_MHZ:
249 tda1004x_write_buf(state, TDA10045H_CONFPLL_P, bandwidth_7mhz, sizeof(bandwidth_7mhz));
250 break;
251
252 case BANDWIDTH_8_MHZ:
253 tda1004x_write_buf(state, TDA10045H_CONFPLL_P, bandwidth_8mhz, sizeof(bandwidth_8mhz));
254 break;
255
256 default:
257 return -EINVAL;
258 }
259
260 tda1004x_write_byteI(state, TDA10045H_IOFFSET, 0);
261
262 return 0;
263}
264
265static int tda10046h_set_bandwidth(struct tda1004x_state *state,
266 fe_bandwidth_t bandwidth)
267{
268 static u8 bandwidth_6mhz[] = { 0x80, 0x15, 0xfe, 0xab, 0x8e };
269 static u8 bandwidth_7mhz[] = { 0x6e, 0x02, 0x53, 0xc8, 0x25 };
270 static u8 bandwidth_8mhz[] = { 0x60, 0x12, 0xa8, 0xe4, 0xbd };
271
272 switch (bandwidth) {
273 case BANDWIDTH_6_MHZ:
274 tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_6mhz, sizeof(bandwidth_6mhz));
275 break;
276
277 case BANDWIDTH_7_MHZ:
278 tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_7mhz, sizeof(bandwidth_7mhz));
279 break;
280
281 case BANDWIDTH_8_MHZ:
282 tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_8mhz, sizeof(bandwidth_8mhz));
283 break;
284
285 default:
286 return -EINVAL;
287 }
288
289 return 0;
290}
291
292static int tda1004x_do_upload(struct tda1004x_state *state,
293 unsigned char *mem, unsigned int len,
294 u8 dspCodeCounterReg, u8 dspCodeInReg)
295{
296 u8 buf[65];
297 struct i2c_msg fw_msg = {.addr = 0,.flags = 0,.buf = buf,.len = 0 };
298 int tx_size;
299 int pos = 0;
300
301 /* clear code counter */
302 tda1004x_write_byteI(state, dspCodeCounterReg, 0);
303 fw_msg.addr = state->config->demod_address;
304
305 buf[0] = dspCodeInReg;
306 while (pos != len) {
307
308 // work out how much to send this time
309 tx_size = len - pos;
310 if (tx_size > 0x10) {
311 tx_size = 0x10;
312 }
313
314 // send the chunk
315 memcpy(buf + 1, mem + pos, tx_size);
316 fw_msg.len = tx_size + 1;
317 if (i2c_transfer(state->i2c, &fw_msg, 1) != 1) {
318 printk("tda1004x: Error during firmware upload\n");
319 return -EIO;
320 }
321 pos += tx_size;
322
323 dprintk("%s: fw_pos=0x%x\n", __FUNCTION__, pos);
324 }
325 return 0;
326}
327
328static int tda1004x_check_upload_ok(struct tda1004x_state *state, u8 dspVersion)
329{
330 u8 data1, data2;
331
332 // check upload was OK
333 tda1004x_write_mask(state, TDA1004X_CONFC4, 0x10, 0); // we want to read from the DSP
334 tda1004x_write_byteI(state, TDA1004X_DSP_CMD, 0x67);
335
336 data1 = tda1004x_read_byte(state, TDA1004X_DSP_DATA1);
337 data2 = tda1004x_read_byte(state, TDA1004X_DSP_DATA2);
338 if (data1 != 0x67 || data2 != dspVersion) {
339 return -EIO;
340 }
341
342 return 0;
343}
344
345static int tda10045_fwupload(struct dvb_frontend* fe)
346{
347 struct tda1004x_state* state = fe->demodulator_priv;
348 int ret;
349 const struct firmware *fw;
350
351
352 /* don't re-upload unless necessary */
353 if (tda1004x_check_upload_ok(state, 0x2c) == 0) return 0;
354
355 /* request the firmware, this will block until someone uploads it */
356 printk("tda1004x: waiting for firmware upload (%s)...\n", TDA10045_DEFAULT_FIRMWARE);
357 ret = state->config->request_firmware(fe, &fw, TDA10045_DEFAULT_FIRMWARE);
358 if (ret) {
359 printk("tda1004x: no firmware upload (timeout or file not found?)\n");
360 return ret;
361 }
362
363 /* reset chip */
364 tda1004x_write_mask(state, TDA1004X_CONFC4, 0x10, 0);
365 tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 8);
366 tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 0);
367 msleep(10);
368
369 /* set parameters */
370 tda10045h_set_bandwidth(state, BANDWIDTH_8_MHZ);
371
372 ret = tda1004x_do_upload(state, fw->data, fw->size, TDA10045H_FWPAGE, TDA10045H_CODE_IN);
373 if (ret)
374 return ret;
375 printk("tda1004x: firmware upload complete\n");
376
377 /* wait for DSP to initialise */
378 /* DSPREADY doesn't seem to work on the TDA10045H */
379 msleep(100);
380
381 return tda1004x_check_upload_ok(state, 0x2c);
382}
383
384static int tda10046_fwupload(struct dvb_frontend* fe)
385{
386 struct tda1004x_state* state = fe->demodulator_priv;
387 unsigned long timeout;
388 int ret;
389 const struct firmware *fw;
390
391 /* reset + wake up chip */
392 tda1004x_write_mask(state, TDA1004X_CONFC4, 1, 0);
393 tda1004x_write_mask(state, TDA10046H_CONF_TRISTATE1, 1, 0);
394 msleep(100);
395
396 /* don't re-upload unless necessary */
397 if (tda1004x_check_upload_ok(state, 0x20) == 0) return 0;
398
399 /* request the firmware, this will block until someone uploads it */
400 printk("tda1004x: waiting for firmware upload (%s)...\n", TDA10046_DEFAULT_FIRMWARE);
401 ret = state->config->request_firmware(fe, &fw, TDA10046_DEFAULT_FIRMWARE);
402 if (ret) {
403 printk("tda1004x: no firmware upload (timeout or file not found?)\n");
404 return ret;
405 }
406
407 /* set parameters */
408 tda1004x_write_byteI(state, TDA10046H_CONFPLL2, 10);
409 tda1004x_write_byteI(state, TDA10046H_CONFPLL3, 0);
410 tda1004x_write_byteI(state, TDA10046H_FREQ_OFFSET, 99);
411 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0xd4);
412 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x2c);
413 tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 8); // going to boot from HOST
414
415 ret = tda1004x_do_upload(state, fw->data, fw->size, TDA10046H_CODE_CPT, TDA10046H_CODE_IN);
416 if (ret)
417 return ret;
418 printk("tda1004x: firmware upload complete\n");
419
420 /* wait for DSP to initialise */
421 timeout = jiffies + HZ;
422 while(!(tda1004x_read_byte(state, TDA1004X_STATUS_CD) & 0x20)) {
423 if (time_after(jiffies, timeout)) {
424 printk("tda1004x: DSP failed to initialised.\n");
425 return -EIO;
426 }
427 msleep(1);
428 }
429
430 return tda1004x_check_upload_ok(state, 0x20);
431}
432
433static int tda1004x_encode_fec(int fec)
434{
435 // convert known FEC values
436 switch (fec) {
437 case FEC_1_2:
438 return 0;
439 case FEC_2_3:
440 return 1;
441 case FEC_3_4:
442 return 2;
443 case FEC_5_6:
444 return 3;
445 case FEC_7_8:
446 return 4;
447 }
448
449 // unsupported
450 return -EINVAL;
451}
452
453static int tda1004x_decode_fec(int tdafec)
454{
455 // convert known FEC values
456 switch (tdafec) {
457 case 0:
458 return FEC_1_2;
459 case 1:
460 return FEC_2_3;
461 case 2:
462 return FEC_3_4;
463 case 3:
464 return FEC_5_6;
465 case 4:
466 return FEC_7_8;
467 }
468
469 // unsupported
470 return -1;
471}
472
473int tda1004x_write_byte(struct dvb_frontend* fe, int reg, int data)
474{
475 struct tda1004x_state* state = fe->demodulator_priv;
476
477 return tda1004x_write_byteI(state, reg, data);
478}
479
480static int tda10045_init(struct dvb_frontend* fe)
481{
482 struct tda1004x_state* state = fe->demodulator_priv;
483
484 dprintk("%s\n", __FUNCTION__);
485
486 if (state->initialised) return 0;
487
488 if (tda10045_fwupload(fe)) {
489 printk("tda1004x: firmware upload failed\n");
490 return -EIO;
491 }
492
493 tda1004x_write_mask(state, TDA1004X_CONFADC1, 0x10, 0); // wake up the ADC
494
495 // Init the PLL
496 if (state->config->pll_init) {
497 tda1004x_enable_tuner_i2c(state);
498 state->config->pll_init(fe);
499 tda1004x_disable_tuner_i2c(state);
500 }
501
502 // tda setup
503 tda1004x_write_mask(state, TDA1004X_CONFC4, 0x20, 0); // disable DSP watchdog timer
504 tda1004x_write_mask(state, TDA1004X_AUTO, 8, 0); // select HP stream
505 tda1004x_write_mask(state, TDA1004X_CONFC1, 0x40, 0); // set polarity of VAGC signal
506 tda1004x_write_mask(state, TDA1004X_CONFC1, 0x80, 0x80); // enable pulse killer
507 tda1004x_write_mask(state, TDA1004X_AUTO, 0x10, 0x10); // enable auto offset
508 tda1004x_write_mask(state, TDA1004X_IN_CONF2, 0xC0, 0x0); // no frequency offset
509 tda1004x_write_byteI(state, TDA1004X_CONF_TS1, 0); // setup MPEG2 TS interface
510 tda1004x_write_byteI(state, TDA1004X_CONF_TS2, 0); // setup MPEG2 TS interface
511 tda1004x_write_mask(state, TDA1004X_VBER_MSB, 0xe0, 0xa0); // 10^6 VBER measurement bits
512 tda1004x_write_mask(state, TDA1004X_CONFC1, 0x10, 0); // VAGC polarity
513 tda1004x_write_byteI(state, TDA1004X_CONFADC1, 0x2e);
514
515 tda1004x_write_mask(state, 0x1f, 0x01, state->config->invert_oclk);
516
517 state->initialised = 1;
518 return 0;
519}
520
521static int tda10046_init(struct dvb_frontend* fe)
522{
523 struct tda1004x_state* state = fe->demodulator_priv;
524 dprintk("%s\n", __FUNCTION__);
525
526 if (state->initialised) return 0;
527
528 if (tda10046_fwupload(fe)) {
529 printk("tda1004x: firmware upload failed\n");
530 return -EIO;
531 }
532
533 tda1004x_write_mask(state, TDA1004X_CONFC4, 1, 0); // wake up the chip
534
535 // Init the PLL
536 if (state->config->pll_init) {
537 tda1004x_enable_tuner_i2c(state);
538 state->config->pll_init(fe);
539 tda1004x_disable_tuner_i2c(state);
540 }
541
542 // tda setup
543 tda1004x_write_mask(state, TDA1004X_CONFC4, 0x20, 0); // disable DSP watchdog timer
544 tda1004x_write_mask(state, TDA1004X_CONFC1, 0x40, 0x40);
545 tda1004x_write_mask(state, TDA1004X_AUTO, 8, 0); // select HP stream
546 tda1004x_write_mask(state, TDA1004X_CONFC1, 0x80, 0); // disable pulse killer
547 tda1004x_write_byteI(state, TDA10046H_CONFPLL2, 10); // PLL M = 10
548 tda1004x_write_byteI(state, TDA10046H_CONFPLL3, 0); // PLL P = N = 0
549 tda1004x_write_byteI(state, TDA10046H_FREQ_OFFSET, 99); // FREQOFFS = 99
550 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0xd4); // } PHY2 = -11221
551 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x2c); // }
552 tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0); // AGC setup
553 tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0x60, 0x60); // set AGC polarities
554 tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MIN, 0); // }
555 tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MAX, 0xff); // } AGC min/max values
556 tda1004x_write_byteI(state, TDA10046H_AGC_IF_MIN, 0); // }
557 tda1004x_write_byteI(state, TDA10046H_AGC_IF_MAX, 0xff); // }
558 tda1004x_write_mask(state, TDA10046H_CVBER_CTRL, 0x30, 0x10); // 10^6 VBER measurement bits
559 tda1004x_write_byteI(state, TDA10046H_AGC_GAINS, 1); // IF gain 2, TUN gain 1
560 tda1004x_write_mask(state, TDA1004X_AUTO, 0x80, 0); // crystal is 50ppm
561 tda1004x_write_byteI(state, TDA1004X_CONF_TS1, 7); // MPEG2 interface config
562 tda1004x_write_mask(state, TDA1004X_CONF_TS2, 0x31, 0); // MPEG2 interface config
563 tda1004x_write_mask(state, TDA10046H_CONF_TRISTATE1, 0x9e, 0); // disable AGC_TUN
564 tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE2, 0xe1); // tristate setup
565 tda1004x_write_byteI(state, TDA10046H_GPIO_OUT_SEL, 0xcc); // GPIO output config
566 tda1004x_write_mask(state, TDA10046H_GPIO_SELECT, 8, 8); // GPIO select
567 tda10046h_set_bandwidth(state, BANDWIDTH_8_MHZ); // default bandwidth 8 MHz
568
569 tda1004x_write_mask(state, 0x3a, 0x80, state->config->invert_oclk << 7);
570
571 state->initialised = 1;
572 return 0;
573}
574
575static int tda1004x_set_fe(struct dvb_frontend* fe,
576 struct dvb_frontend_parameters *fe_params)
577{
578 struct tda1004x_state* state = fe->demodulator_priv;
579 int tmp;
580 int inversion;
581
582 dprintk("%s\n", __FUNCTION__);
583
584 if (state->demod_type == TDA1004X_DEMOD_TDA10046) {
585 // setup auto offset
586 tda1004x_write_mask(state, TDA1004X_AUTO, 0x10, 0x10);
587 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x80, 0);
588 tda1004x_write_mask(state, TDA1004X_IN_CONF2, 0xC0, 0);
589
590 // disable agc_conf[2]
591 tda1004x_write_mask(state, TDA10046H_AGC_CONF, 4, 0);
592 }
593
594 // set frequency
595 tda1004x_enable_tuner_i2c(state);
596 state->config->pll_set(fe, fe_params);
597 tda1004x_disable_tuner_i2c(state);
598
599 if (state->demod_type == TDA1004X_DEMOD_TDA10046)
600 tda1004x_write_mask(state, TDA10046H_AGC_CONF, 4, 4);
601
602 // Hardcoded to use auto as much as possible on the TDA10045 as it
603 // is very unreliable if AUTO mode is _not_ used.
604 if (state->demod_type == TDA1004X_DEMOD_TDA10045) {
605 fe_params->u.ofdm.code_rate_HP = FEC_AUTO;
606 fe_params->u.ofdm.guard_interval = GUARD_INTERVAL_AUTO;
607 fe_params->u.ofdm.transmission_mode = TRANSMISSION_MODE_AUTO;
608 }
609
610 // Set standard params.. or put them to auto
611 if ((fe_params->u.ofdm.code_rate_HP == FEC_AUTO) ||
612 (fe_params->u.ofdm.code_rate_LP == FEC_AUTO) ||
613 (fe_params->u.ofdm.constellation == QAM_AUTO) ||
614 (fe_params->u.ofdm.hierarchy_information == HIERARCHY_AUTO)) {
615 tda1004x_write_mask(state, TDA1004X_AUTO, 1, 1); // enable auto
616 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x03, 0); // turn off constellation bits
617 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x60, 0); // turn off hierarchy bits
618 tda1004x_write_mask(state, TDA1004X_IN_CONF2, 0x3f, 0); // turn off FEC bits
619 } else {
620 tda1004x_write_mask(state, TDA1004X_AUTO, 1, 0); // disable auto
621
622 // set HP FEC
623 tmp = tda1004x_encode_fec(fe_params->u.ofdm.code_rate_HP);
624 if (tmp < 0) return tmp;
625 tda1004x_write_mask(state, TDA1004X_IN_CONF2, 7, tmp);
626
627 // set LP FEC
628 tmp = tda1004x_encode_fec(fe_params->u.ofdm.code_rate_LP);
629 if (tmp < 0) return tmp;
630 tda1004x_write_mask(state, TDA1004X_IN_CONF2, 0x38, tmp << 3);
631
632 // set constellation
633 switch (fe_params->u.ofdm.constellation) {
634 case QPSK:
635 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 3, 0);
636 break;
637
638 case QAM_16:
639 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 3, 1);
640 break;
641
642 case QAM_64:
643 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 3, 2);
644 break;
645
646 default:
647 return -EINVAL;
648 }
649
650 // set hierarchy
651 switch (fe_params->u.ofdm.hierarchy_information) {
652 case HIERARCHY_NONE:
653 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x60, 0 << 5);
654 break;
655
656 case HIERARCHY_1:
657 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x60, 1 << 5);
658 break;
659
660 case HIERARCHY_2:
661 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x60, 2 << 5);
662 break;
663
664 case HIERARCHY_4:
665 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x60, 3 << 5);
666 break;
667
668 default:
669 return -EINVAL;
670 }
671 }
672
673 // set bandwidth
674 switch(state->demod_type) {
675 case TDA1004X_DEMOD_TDA10045:
676 tda10045h_set_bandwidth(state, fe_params->u.ofdm.bandwidth);
677 break;
678
679 case TDA1004X_DEMOD_TDA10046:
680 tda10046h_set_bandwidth(state, fe_params->u.ofdm.bandwidth);
681 break;
682 }
683
684 // set inversion
685 inversion = fe_params->inversion;
686 if (state->config->invert) inversion = inversion ? INVERSION_OFF : INVERSION_ON;
687 switch (inversion) {
688 case INVERSION_OFF:
689 tda1004x_write_mask(state, TDA1004X_CONFC1, 0x20, 0);
690 break;
691
692 case INVERSION_ON:
693 tda1004x_write_mask(state, TDA1004X_CONFC1, 0x20, 0x20);
694 break;
695
696 default:
697 return -EINVAL;
698 }
699
700 // set guard interval
701 switch (fe_params->u.ofdm.guard_interval) {
702 case GUARD_INTERVAL_1_32:
703 tda1004x_write_mask(state, TDA1004X_AUTO, 2, 0);
704 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x0c, 0 << 2);
705 break;
706
707 case GUARD_INTERVAL_1_16:
708 tda1004x_write_mask(state, TDA1004X_AUTO, 2, 0);
709 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x0c, 1 << 2);
710 break;
711
712 case GUARD_INTERVAL_1_8:
713 tda1004x_write_mask(state, TDA1004X_AUTO, 2, 0);
714 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x0c, 2 << 2);
715 break;
716
717 case GUARD_INTERVAL_1_4:
718 tda1004x_write_mask(state, TDA1004X_AUTO, 2, 0);
719 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x0c, 3 << 2);
720 break;
721
722 case GUARD_INTERVAL_AUTO:
723 tda1004x_write_mask(state, TDA1004X_AUTO, 2, 2);
724 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x0c, 0 << 2);
725 break;
726
727 default:
728 return -EINVAL;
729 }
730
731 // set transmission mode
732 switch (fe_params->u.ofdm.transmission_mode) {
733 case TRANSMISSION_MODE_2K:
734 tda1004x_write_mask(state, TDA1004X_AUTO, 4, 0);
735 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x10, 0 << 4);
736 break;
737
738 case TRANSMISSION_MODE_8K:
739 tda1004x_write_mask(state, TDA1004X_AUTO, 4, 0);
740 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x10, 1 << 4);
741 break;
742
743 case TRANSMISSION_MODE_AUTO:
744 tda1004x_write_mask(state, TDA1004X_AUTO, 4, 4);
745 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x10, 0);
746 break;
747
748 default:
749 return -EINVAL;
750 }
751
752 // start the lock
753 switch(state->demod_type) {
754 case TDA1004X_DEMOD_TDA10045:
755 tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 8);
756 tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 0);
757 msleep(10);
758 break;
759
760 case TDA1004X_DEMOD_TDA10046:
761 tda1004x_write_mask(state, TDA1004X_AUTO, 0x40, 0x40);
762 msleep(10);
763 break;
764 }
765
766 return 0;
767}
768
769static int tda1004x_get_fe(struct dvb_frontend* fe, struct dvb_frontend_parameters *fe_params)
770{
771 struct tda1004x_state* state = fe->demodulator_priv;
772 dprintk("%s\n", __FUNCTION__);
773
774 // inversion status
775 fe_params->inversion = INVERSION_OFF;
776 if (tda1004x_read_byte(state, TDA1004X_CONFC1) & 0x20) {
777 fe_params->inversion = INVERSION_ON;
778 }
779 if (state->config->invert) fe_params->inversion = fe_params->inversion ? INVERSION_OFF : INVERSION_ON;
780
781 // bandwidth
782 switch(state->demod_type) {
783 case TDA1004X_DEMOD_TDA10045:
784 switch (tda1004x_read_byte(state, TDA10045H_WREF_LSB)) {
785 case 0x14:
786 fe_params->u.ofdm.bandwidth = BANDWIDTH_8_MHZ;
787 break;
788 case 0xdb:
789 fe_params->u.ofdm.bandwidth = BANDWIDTH_7_MHZ;
790 break;
791 case 0x4f:
792 fe_params->u.ofdm.bandwidth = BANDWIDTH_6_MHZ;
793 break;
794 }
795 break;
796
797 case TDA1004X_DEMOD_TDA10046:
798 switch (tda1004x_read_byte(state, TDA10046H_TIME_WREF1)) {
799 case 0x60:
800 fe_params->u.ofdm.bandwidth = BANDWIDTH_8_MHZ;
801 break;
802 case 0x6e:
803 fe_params->u.ofdm.bandwidth = BANDWIDTH_7_MHZ;
804 break;
805 case 0x80:
806 fe_params->u.ofdm.bandwidth = BANDWIDTH_6_MHZ;
807 break;
808 }
809 break;
810 }
811
812 // FEC
813 fe_params->u.ofdm.code_rate_HP =
814 tda1004x_decode_fec(tda1004x_read_byte(state, TDA1004X_OUT_CONF2) & 7);
815 fe_params->u.ofdm.code_rate_LP =
816 tda1004x_decode_fec((tda1004x_read_byte(state, TDA1004X_OUT_CONF2) >> 3) & 7);
817
818 // constellation
819 switch (tda1004x_read_byte(state, TDA1004X_OUT_CONF1) & 3) {
820 case 0:
821 fe_params->u.ofdm.constellation = QPSK;
822 break;
823 case 1:
824 fe_params->u.ofdm.constellation = QAM_16;
825 break;
826 case 2:
827 fe_params->u.ofdm.constellation = QAM_64;
828 break;
829 }
830
831 // transmission mode
832 fe_params->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K;
833 if (tda1004x_read_byte(state, TDA1004X_OUT_CONF1) & 0x10) {
834 fe_params->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K;
835 }
836
837 // guard interval
838 switch ((tda1004x_read_byte(state, TDA1004X_OUT_CONF1) & 0x0c) >> 2) {
839 case 0:
840 fe_params->u.ofdm.guard_interval = GUARD_INTERVAL_1_32;
841 break;
842 case 1:
843 fe_params->u.ofdm.guard_interval = GUARD_INTERVAL_1_16;
844 break;
845 case 2:
846 fe_params->u.ofdm.guard_interval = GUARD_INTERVAL_1_8;
847 break;
848 case 3:
849 fe_params->u.ofdm.guard_interval = GUARD_INTERVAL_1_4;
850 break;
851 }
852
853 // hierarchy
854 switch ((tda1004x_read_byte(state, TDA1004X_OUT_CONF1) & 0x60) >> 5) {
855 case 0:
856 fe_params->u.ofdm.hierarchy_information = HIERARCHY_NONE;
857 break;
858 case 1:
859 fe_params->u.ofdm.hierarchy_information = HIERARCHY_1;
860 break;
861 case 2:
862 fe_params->u.ofdm.hierarchy_information = HIERARCHY_2;
863 break;
864 case 3:
865 fe_params->u.ofdm.hierarchy_information = HIERARCHY_4;
866 break;
867 }
868
869 return 0;
870}
871
872static int tda1004x_read_status(struct dvb_frontend* fe, fe_status_t * fe_status)
873{
874 struct tda1004x_state* state = fe->demodulator_priv;
875 int status;
876 int cber;
877 int vber;
878
879 dprintk("%s\n", __FUNCTION__);
880
881 // read status
882 status = tda1004x_read_byte(state, TDA1004X_STATUS_CD);
883 if (status == -1) {
884 return -EIO;
885 }
886
887 // decode
888 *fe_status = 0;
889 if (status & 4) *fe_status |= FE_HAS_SIGNAL;
890 if (status & 2) *fe_status |= FE_HAS_CARRIER;
891 if (status & 8) *fe_status |= FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
892
893 // if we don't already have VITERBI (i.e. not LOCKED), see if the viterbi
894 // is getting anything valid
895 if (!(*fe_status & FE_HAS_VITERBI)) {
896 // read the CBER
897 cber = tda1004x_read_byte(state, TDA1004X_CBER_LSB);
898 if (cber == -1) return -EIO;
899 status = tda1004x_read_byte(state, TDA1004X_CBER_MSB);
900 if (status == -1) return -EIO;
901 cber |= (status << 8);
902 tda1004x_read_byte(state, TDA1004X_CBER_RESET);
903
904 if (cber != 65535) {
905 *fe_status |= FE_HAS_VITERBI;
906 }
907 }
908
909 // if we DO have some valid VITERBI output, but don't already have SYNC
910 // bytes (i.e. not LOCKED), see if the RS decoder is getting anything valid.
911 if ((*fe_status & FE_HAS_VITERBI) && (!(*fe_status & FE_HAS_SYNC))) {
912 // read the VBER
913 vber = tda1004x_read_byte(state, TDA1004X_VBER_LSB);
914 if (vber == -1) return -EIO;
915 status = tda1004x_read_byte(state, TDA1004X_VBER_MID);
916 if (status == -1) return -EIO;
917 vber |= (status << 8);
918 status = tda1004x_read_byte(state, TDA1004X_VBER_MSB);
919 if (status == -1) return -EIO;
920 vber |= ((status << 16) & 0x0f);
921 tda1004x_read_byte(state, TDA1004X_CVBER_LUT);
922
923 // if RS has passed some valid TS packets, then we must be
924 // getting some SYNC bytes
925 if (vber < 16632) {
926 *fe_status |= FE_HAS_SYNC;
927 }
928 }
929
930 // success
931 dprintk("%s: fe_status=0x%x\n", __FUNCTION__, *fe_status);
932 return 0;
933}
934
935static int tda1004x_read_signal_strength(struct dvb_frontend* fe, u16 * signal)
936{
937 struct tda1004x_state* state = fe->demodulator_priv;
938 int tmp;
939 int reg = 0;
940
941 dprintk("%s\n", __FUNCTION__);
942
943 // determine the register to use
944 switch(state->demod_type) {
945 case TDA1004X_DEMOD_TDA10045:
946 reg = TDA10045H_S_AGC;
947 break;
948
949 case TDA1004X_DEMOD_TDA10046:
950 reg = TDA10046H_AGC_IF_LEVEL;
951 break;
952 }
953
954 // read it
955 tmp = tda1004x_read_byte(state, reg);
956 if (tmp < 0)
957 return -EIO;
958
959 *signal = (tmp << 8) | tmp;
960 dprintk("%s: signal=0x%x\n", __FUNCTION__, *signal);
961 return 0;
962}
963
964static int tda1004x_read_snr(struct dvb_frontend* fe, u16 * snr)
965{
966 struct tda1004x_state* state = fe->demodulator_priv;
967 int tmp;
968
969 dprintk("%s\n", __FUNCTION__);
970
971 // read it
972 tmp = tda1004x_read_byte(state, TDA1004X_SNR);
973 if (tmp < 0)
974 return -EIO;
975 if (tmp) {
976 tmp = 255 - tmp;
977 }
978
979 *snr = ((tmp << 8) | tmp);
980 dprintk("%s: snr=0x%x\n", __FUNCTION__, *snr);
981 return 0;
982}
983
984static int tda1004x_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
985{
986 struct tda1004x_state* state = fe->demodulator_priv;
987 int tmp;
988 int tmp2;
989 int counter;
990
991 dprintk("%s\n", __FUNCTION__);
992
993 // read the UCBLOCKS and reset
994 counter = 0;
995 tmp = tda1004x_read_byte(state, TDA1004X_UNCOR);
996 if (tmp < 0)
997 return -EIO;
998 tmp &= 0x7f;
999 while (counter++ < 5) {
1000 tda1004x_write_mask(state, TDA1004X_UNCOR, 0x80, 0);
1001 tda1004x_write_mask(state, TDA1004X_UNCOR, 0x80, 0);
1002 tda1004x_write_mask(state, TDA1004X_UNCOR, 0x80, 0);
1003
1004 tmp2 = tda1004x_read_byte(state, TDA1004X_UNCOR);
1005 if (tmp2 < 0)
1006 return -EIO;
1007 tmp2 &= 0x7f;
1008 if ((tmp2 < tmp) || (tmp2 == 0))
1009 break;
1010 }
1011
1012 if (tmp != 0x7f) {
1013 *ucblocks = tmp;
1014 } else {
1015 *ucblocks = 0xffffffff;
1016 }
1017 dprintk("%s: ucblocks=0x%x\n", __FUNCTION__, *ucblocks);
1018 return 0;
1019}
1020
1021static int tda1004x_read_ber(struct dvb_frontend* fe, u32* ber)
1022{
1023 struct tda1004x_state* state = fe->demodulator_priv;
1024 int tmp;
1025
1026 dprintk("%s\n", __FUNCTION__);
1027
1028 // read it in
1029 tmp = tda1004x_read_byte(state, TDA1004X_CBER_LSB);
1030 if (tmp < 0) return -EIO;
1031 *ber = tmp << 1;
1032 tmp = tda1004x_read_byte(state, TDA1004X_CBER_MSB);
1033 if (tmp < 0) return -EIO;
1034 *ber |= (tmp << 9);
1035 tda1004x_read_byte(state, TDA1004X_CBER_RESET);
1036
1037 dprintk("%s: ber=0x%x\n", __FUNCTION__, *ber);
1038 return 0;
1039}
1040
1041static int tda1004x_sleep(struct dvb_frontend* fe)
1042{
1043 struct tda1004x_state* state = fe->demodulator_priv;
1044
1045 switch(state->demod_type) {
1046 case TDA1004X_DEMOD_TDA10045:
1047 tda1004x_write_mask(state, TDA1004X_CONFADC1, 0x10, 0x10);
1048 break;
1049
1050 case TDA1004X_DEMOD_TDA10046:
1051 tda1004x_write_mask(state, TDA1004X_CONFC4, 1, 1);
1052 break;
1053 }
1054 state->initialised = 0;
1055
1056 return 0;
1057}
1058
1059static int tda1004x_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
1060{
1061 fesettings->min_delay_ms = 800;
1062 fesettings->step_size = 166667;
1063 fesettings->max_drift = 166667*2;
1064 return 0;
1065}
1066
1067static void tda1004x_release(struct dvb_frontend* fe)
1068{
1069 struct tda1004x_state* state = (struct tda1004x_state*) fe->demodulator_priv;
1070 kfree(state);
1071}
1072
1073static struct dvb_frontend_ops tda10045_ops;
1074
1075struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config,
1076 struct i2c_adapter* i2c)
1077{
1078 struct tda1004x_state* state = NULL;
1079
1080 /* allocate memory for the internal state */
1081 state = (struct tda1004x_state*) kmalloc(sizeof(struct tda1004x_state), GFP_KERNEL);
1082 if (state == NULL) goto error;
1083
1084 /* setup the state */
1085 state->config = config;
1086 state->i2c = i2c;
1087 memcpy(&state->ops, &tda10045_ops, sizeof(struct dvb_frontend_ops));
1088 state->initialised = 0;
1089 state->demod_type = TDA1004X_DEMOD_TDA10045;
1090
1091 /* check if the demod is there */
1092 if (tda1004x_read_byte(state, TDA1004X_CHIPID) != 0x25) goto error;
1093
1094 /* create dvb_frontend */
1095 state->frontend.ops = &state->ops;
1096 state->frontend.demodulator_priv = state;
1097 return &state->frontend;
1098
1099error:
1100 kfree(state);
1101 return NULL;
1102}
1103
1104static struct dvb_frontend_ops tda10046_ops;
1105
1106struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config,
1107 struct i2c_adapter* i2c)
1108{
1109 struct tda1004x_state* state = NULL;
1110
1111 /* allocate memory for the internal state */
1112 state = (struct tda1004x_state*) kmalloc(sizeof(struct tda1004x_state), GFP_KERNEL);
1113 if (state == NULL) goto error;
1114
1115 /* setup the state */
1116 state->config = config;
1117 state->i2c = i2c;
1118 memcpy(&state->ops, &tda10046_ops, sizeof(struct dvb_frontend_ops));
1119 state->initialised = 0;
1120 state->demod_type = TDA1004X_DEMOD_TDA10046;
1121
1122 /* check if the demod is there */
1123 if (tda1004x_read_byte(state, TDA1004X_CHIPID) != 0x46) goto error;
1124
1125 /* create dvb_frontend */
1126 state->frontend.ops = &state->ops;
1127 state->frontend.demodulator_priv = state;
1128 return &state->frontend;
1129
1130error:
1131 if (state) kfree(state);
1132 return NULL;
1133}
1134
1135static struct dvb_frontend_ops tda10045_ops = {
1136
1137 .info = {
1138 .name = "Philips TDA10045H DVB-T",
1139 .type = FE_OFDM,
1140 .frequency_min = 51000000,
1141 .frequency_max = 858000000,
1142 .frequency_stepsize = 166667,
1143 .caps =
1144 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
1145 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
1146 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
1147 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO
1148 },
1149
1150 .release = tda1004x_release,
1151
1152 .init = tda10045_init,
1153 .sleep = tda1004x_sleep,
1154
1155 .set_frontend = tda1004x_set_fe,
1156 .get_frontend = tda1004x_get_fe,
1157 .get_tune_settings = tda1004x_get_tune_settings,
1158
1159 .read_status = tda1004x_read_status,
1160 .read_ber = tda1004x_read_ber,
1161 .read_signal_strength = tda1004x_read_signal_strength,
1162 .read_snr = tda1004x_read_snr,
1163 .read_ucblocks = tda1004x_read_ucblocks,
1164};
1165
1166static struct dvb_frontend_ops tda10046_ops = {
1167
1168 .info = {
1169 .name = "Philips TDA10046H DVB-T",
1170 .type = FE_OFDM,
1171 .frequency_min = 51000000,
1172 .frequency_max = 858000000,
1173 .frequency_stepsize = 166667,
1174 .caps =
1175 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
1176 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
1177 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
1178 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO
1179 },
1180
1181 .release = tda1004x_release,
1182
1183 .init = tda10046_init,
1184 .sleep = tda1004x_sleep,
1185
1186 .set_frontend = tda1004x_set_fe,
1187 .get_frontend = tda1004x_get_fe,
1188 .get_tune_settings = tda1004x_get_tune_settings,
1189
1190 .read_status = tda1004x_read_status,
1191 .read_ber = tda1004x_read_ber,
1192 .read_signal_strength = tda1004x_read_signal_strength,
1193 .read_snr = tda1004x_read_snr,
1194 .read_ucblocks = tda1004x_read_ucblocks,
1195};
1196
1197module_param(debug, int, 0644);
1198MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
1199
1200MODULE_DESCRIPTION("Philips TDA10045H & TDA10046H DVB-T Demodulator");
1201MODULE_AUTHOR("Andrew de Quincey & Robert Schlabbach");
1202MODULE_LICENSE("GPL");
1203
1204EXPORT_SYMBOL(tda10045_attach);
1205EXPORT_SYMBOL(tda10046_attach);
1206EXPORT_SYMBOL(tda1004x_write_byte);
diff --git a/drivers/media/dvb/frontends/tda1004x.h b/drivers/media/dvb/frontends/tda1004x.h
new file mode 100644
index 000000000000..e452fc0bad11
--- /dev/null
+++ b/drivers/media/dvb/frontends/tda1004x.h
@@ -0,0 +1,56 @@
1 /*
2 Driver for Philips tda1004xh OFDM Frontend
3
4 (c) 2004 Andrew de Quincey
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21 */
22
23#ifndef TDA1004X_H
24#define TDA1004X_H
25
26#include <linux/dvb/frontend.h>
27#include <linux/firmware.h>
28
29struct tda1004x_config
30{
31 /* the demodulator's i2c address */
32 u8 demod_address;
33
34 /* does the "inversion" need inverted? */
35 u8 invert:1;
36
37 /* Does the OCLK signal need inverted? */
38 u8 invert_oclk:1;
39
40 /* PLL maintenance */
41 int (*pll_init)(struct dvb_frontend* fe);
42 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
43
44 /* request firmware for device */
45 int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name);
46};
47
48extern struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config,
49 struct i2c_adapter* i2c);
50
51extern struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config,
52 struct i2c_adapter* i2c);
53
54extern int tda1004x_write_byte(struct dvb_frontend* fe, int reg, int data);
55
56#endif // TDA1004X_H
diff --git a/drivers/media/dvb/frontends/tda8083.c b/drivers/media/dvb/frontends/tda8083.c
new file mode 100644
index 000000000000..da82e90d6d13
--- /dev/null
+++ b/drivers/media/dvb/frontends/tda8083.c
@@ -0,0 +1,456 @@
1/*
2 Driver for Philips TDA8083 based QPSK Demodulator
3
4 Copyright (C) 2001 Convergence Integrated Media GmbH
5
6 written by Ralph Metzler <ralph@convergence.de>
7
8 adoption to the new DVB frontend API and diagnostic ioctl's
9 by Holger Waechtler <holger@convergence.de>
10
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2 of the License, or
14 (at your option) any later version.
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 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24
25*/
26
27#include <linux/init.h>
28#include <linux/kernel.h>
29#include <linux/module.h>
30#include <linux/moduleparam.h>
31#include <linux/string.h>
32#include <linux/slab.h>
33#include "dvb_frontend.h"
34#include "tda8083.h"
35
36
37struct tda8083_state {
38 struct i2c_adapter* i2c;
39 struct dvb_frontend_ops ops;
40 /* configuration settings */
41 const struct tda8083_config* config;
42 struct dvb_frontend frontend;
43};
44
45static int debug;
46#define dprintk(args...) \
47 do { \
48 if (debug) printk(KERN_DEBUG "tda8083: " args); \
49 } while (0)
50
51
52static u8 tda8083_init_tab [] = {
53 0x04, 0x00, 0x4a, 0x79, 0x04, 0x00, 0xff, 0xea,
54 0x48, 0x42, 0x79, 0x60, 0x70, 0x52, 0x9a, 0x10,
55 0x0e, 0x10, 0xf2, 0xa7, 0x93, 0x0b, 0x05, 0xc8,
56 0x9d, 0x00, 0x42, 0x80, 0x00, 0x60, 0x40, 0x00,
57 0x00, 0x75, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00,
58 0x00, 0x00, 0x00, 0x00
59};
60
61
62static int tda8083_writereg (struct tda8083_state* state, u8 reg, u8 data)
63{
64 int ret;
65 u8 buf [] = { reg, data };
66 struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 };
67
68 ret = i2c_transfer(state->i2c, &msg, 1);
69
70 if (ret != 1)
71 dprintk ("%s: writereg error (reg %02x, ret == %i)\n",
72 __FUNCTION__, reg, ret);
73
74 return (ret != 1) ? -1 : 0;
75}
76
77static int tda8083_readregs (struct tda8083_state* state, u8 reg1, u8 *b, u8 len)
78{
79 int ret;
80 struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = &reg1, .len = 1 },
81 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b, .len = len } };
82
83 ret = i2c_transfer(state->i2c, msg, 2);
84
85 if (ret != 2)
86 dprintk ("%s: readreg error (reg %02x, ret == %i)\n",
87 __FUNCTION__, reg1, ret);
88
89 return ret == 2 ? 0 : -1;
90}
91
92static inline u8 tda8083_readreg (struct tda8083_state* state, u8 reg)
93{
94 u8 val;
95
96 tda8083_readregs (state, reg, &val, 1);
97
98 return val;
99}
100
101static int tda8083_set_inversion (struct tda8083_state* state, fe_spectral_inversion_t inversion)
102{
103 /* XXX FIXME: implement other modes than FEC_AUTO */
104 if (inversion == INVERSION_AUTO)
105 return 0;
106
107 return -EINVAL;
108}
109
110static int tda8083_set_fec (struct tda8083_state* state, fe_code_rate_t fec)
111{
112 if (fec == FEC_AUTO)
113 return tda8083_writereg (state, 0x07, 0xff);
114
115 if (fec >= FEC_1_2 && fec <= FEC_8_9)
116 return tda8083_writereg (state, 0x07, 1 << (FEC_8_9 - fec));
117
118 return -EINVAL;
119}
120
121static fe_code_rate_t tda8083_get_fec (struct tda8083_state* state)
122{
123 u8 index;
124 static fe_code_rate_t fec_tab [] = { FEC_8_9, FEC_1_2, FEC_2_3, FEC_3_4,
125 FEC_4_5, FEC_5_6, FEC_6_7, FEC_7_8 };
126
127 index = tda8083_readreg(state, 0x0e) & 0x07;
128
129 return fec_tab [index];
130}
131
132static int tda8083_set_symbolrate (struct tda8083_state* state, u32 srate)
133{
134 u32 ratio;
135 u32 tmp;
136 u8 filter;
137
138 if (srate > 32000000)
139 srate = 32000000;
140 if (srate < 500000)
141 srate = 500000;
142
143 filter = 0;
144 if (srate < 24000000)
145 filter = 2;
146 if (srate < 16000000)
147 filter = 3;
148
149 tmp = 31250 << 16;
150 ratio = tmp / srate;
151
152 tmp = (tmp % srate) << 8;
153 ratio = (ratio << 8) + tmp / srate;
154
155 tmp = (tmp % srate) << 8;
156 ratio = (ratio << 8) + tmp / srate;
157
158 dprintk("tda8083: ratio == %08x\n", (unsigned int) ratio);
159
160 tda8083_writereg (state, 0x05, filter);
161 tda8083_writereg (state, 0x02, (ratio >> 16) & 0xff);
162 tda8083_writereg (state, 0x03, (ratio >> 8) & 0xff);
163 tda8083_writereg (state, 0x04, (ratio ) & 0xff);
164
165 tda8083_writereg (state, 0x00, 0x3c);
166 tda8083_writereg (state, 0x00, 0x04);
167
168 return 1;
169}
170
171static void tda8083_wait_diseqc_fifo (struct tda8083_state* state, int timeout)
172{
173 unsigned long start = jiffies;
174
175 while (jiffies - start < timeout &&
176 !(tda8083_readreg(state, 0x02) & 0x80))
177 {
178 msleep(50);
179 };
180}
181
182static int tda8083_set_tone (struct tda8083_state* state, fe_sec_tone_mode_t tone)
183{
184 tda8083_writereg (state, 0x26, 0xf1);
185
186 switch (tone) {
187 case SEC_TONE_OFF:
188 return tda8083_writereg (state, 0x29, 0x00);
189 case SEC_TONE_ON:
190 return tda8083_writereg (state, 0x29, 0x80);
191 default:
192 return -EINVAL;
193 };
194}
195
196static int tda8083_set_voltage (struct tda8083_state* state, fe_sec_voltage_t voltage)
197{
198 switch (voltage) {
199 case SEC_VOLTAGE_13:
200 return tda8083_writereg (state, 0x20, 0x00);
201 case SEC_VOLTAGE_18:
202 return tda8083_writereg (state, 0x20, 0x11);
203 default:
204 return -EINVAL;
205 };
206}
207
208static int tda8083_send_diseqc_burst (struct tda8083_state* state, fe_sec_mini_cmd_t burst)
209{
210 switch (burst) {
211 case SEC_MINI_A:
212 tda8083_writereg (state, 0x29, (5 << 2)); /* send burst A */
213 break;
214 case SEC_MINI_B:
215 tda8083_writereg (state, 0x29, (7 << 2)); /* send B */
216 break;
217 default:
218 return -EINVAL;
219 };
220
221 tda8083_wait_diseqc_fifo (state, 100);
222
223 return 0;
224}
225
226static int tda8083_send_diseqc_msg (struct dvb_frontend* fe,
227 struct dvb_diseqc_master_cmd *m)
228{
229 struct tda8083_state* state = (struct tda8083_state*) fe->demodulator_priv;
230 int i;
231
232 tda8083_writereg (state, 0x29, (m->msg_len - 3) | (1 << 2)); /* enable */
233
234 for (i=0; i<m->msg_len; i++)
235 tda8083_writereg (state, 0x23 + i, m->msg[i]);
236
237 tda8083_writereg (state, 0x29, (m->msg_len - 3) | (3 << 2)); /* send!! */
238
239 tda8083_wait_diseqc_fifo (state, 100);
240
241 return 0;
242}
243
244static int tda8083_read_status(struct dvb_frontend* fe, fe_status_t* status)
245{
246 struct tda8083_state* state = (struct tda8083_state*) fe->demodulator_priv;
247
248 u8 signal = ~tda8083_readreg (state, 0x01);
249 u8 sync = tda8083_readreg (state, 0x02);
250
251 *status = 0;
252
253 if (signal > 10)
254 *status |= FE_HAS_SIGNAL;
255
256 if (sync & 0x01)
257 *status |= FE_HAS_CARRIER;
258
259 if (sync & 0x02)
260 *status |= FE_HAS_VITERBI;
261
262 if (sync & 0x10)
263 *status |= FE_HAS_SYNC;
264
265 if ((sync & 0x1f) == 0x1f)
266 *status |= FE_HAS_LOCK;
267
268 return 0;
269}
270
271static int tda8083_read_signal_strength(struct dvb_frontend* fe, u16* strength)
272{
273 struct tda8083_state* state = (struct tda8083_state*) fe->demodulator_priv;
274
275 u8 signal = ~tda8083_readreg (state, 0x01);
276 *strength = (signal << 8) | signal;
277
278 return 0;
279}
280
281static int tda8083_read_snr(struct dvb_frontend* fe, u16* snr)
282{
283 struct tda8083_state* state = (struct tda8083_state*) fe->demodulator_priv;
284
285 u8 _snr = tda8083_readreg (state, 0x08);
286 *snr = (_snr << 8) | _snr;
287
288 return 0;
289}
290
291static int tda8083_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
292{
293 struct tda8083_state* state = (struct tda8083_state*) fe->demodulator_priv;
294
295 state->config->pll_set(fe, p);
296 tda8083_set_inversion (state, p->inversion);
297 tda8083_set_fec (state, p->u.qpsk.fec_inner);
298 tda8083_set_symbolrate (state, p->u.qpsk.symbol_rate);
299
300 tda8083_writereg (state, 0x00, 0x3c);
301 tda8083_writereg (state, 0x00, 0x04);
302
303 return 0;
304}
305
306static int tda8083_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
307{
308 struct tda8083_state* state = (struct tda8083_state*) fe->demodulator_priv;
309
310 /* FIXME: get symbolrate & frequency offset...*/
311 /*p->frequency = ???;*/
312 p->inversion = (tda8083_readreg (state, 0x0e) & 0x80) ?
313 INVERSION_ON : INVERSION_OFF;
314 p->u.qpsk.fec_inner = tda8083_get_fec (state);
315 /*p->u.qpsk.symbol_rate = tda8083_get_symbolrate (state);*/
316
317 return 0;
318}
319
320static int tda8083_sleep(struct dvb_frontend* fe)
321{
322 struct tda8083_state* state = (struct tda8083_state*) fe->demodulator_priv;
323
324 tda8083_writereg (state, 0x00, 0x02);
325 return 0;
326}
327
328static int tda8083_init(struct dvb_frontend* fe)
329{
330 struct tda8083_state* state = (struct tda8083_state*) fe->demodulator_priv;
331 int i;
332
333 for (i=0; i<44; i++)
334 tda8083_writereg (state, i, tda8083_init_tab[i]);
335
336 if (state->config->pll_init) state->config->pll_init(fe);
337
338 tda8083_writereg (state, 0x00, 0x3c);
339 tda8083_writereg (state, 0x00, 0x04);
340
341 return 0;
342}
343
344static int tda8083_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t burst)
345{
346 struct tda8083_state* state = (struct tda8083_state*) fe->demodulator_priv;
347
348 tda8083_send_diseqc_burst (state, burst);
349 tda8083_writereg (state, 0x00, 0x3c);
350 tda8083_writereg (state, 0x00, 0x04);
351
352 return 0;
353}
354
355static int tda8083_diseqc_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
356{
357 struct tda8083_state* state = (struct tda8083_state*) fe->demodulator_priv;
358
359 tda8083_set_tone (state, tone);
360 tda8083_writereg (state, 0x00, 0x3c);
361 tda8083_writereg (state, 0x00, 0x04);
362
363 return 0;
364}
365
366static int tda8083_diseqc_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
367{
368 struct tda8083_state* state = (struct tda8083_state*) fe->demodulator_priv;
369
370 tda8083_set_voltage (state, voltage);
371 tda8083_writereg (state, 0x00, 0x3c);
372 tda8083_writereg (state, 0x00, 0x04);
373
374 return 0;
375}
376
377static void tda8083_release(struct dvb_frontend* fe)
378{
379 struct tda8083_state* state = (struct tda8083_state*) fe->demodulator_priv;
380 kfree(state);
381}
382
383static struct dvb_frontend_ops tda8083_ops;
384
385struct dvb_frontend* tda8083_attach(const struct tda8083_config* config,
386 struct i2c_adapter* i2c)
387{
388 struct tda8083_state* state = NULL;
389
390 /* allocate memory for the internal state */
391 state = (struct tda8083_state*) kmalloc(sizeof(struct tda8083_state), GFP_KERNEL);
392 if (state == NULL) goto error;
393
394 /* setup the state */
395 state->config = config;
396 state->i2c = i2c;
397 memcpy(&state->ops, &tda8083_ops, sizeof(struct dvb_frontend_ops));
398
399 /* check if the demod is there */
400 if ((tda8083_readreg(state, 0x00)) != 0x05) goto error;
401
402 /* create dvb_frontend */
403 state->frontend.ops = &state->ops;
404 state->frontend.demodulator_priv = state;
405 return &state->frontend;
406
407error:
408 kfree(state);
409 return NULL;
410}
411
412static struct dvb_frontend_ops tda8083_ops = {
413
414 .info = {
415 .name = "Philips TDA8083 DVB-S",
416 .type = FE_QPSK,
417 .frequency_min = 950000, /* FIXME: guessed! */
418 .frequency_max = 1400000, /* FIXME: guessed! */
419 .frequency_stepsize = 125, /* kHz for QPSK frontends */
420 /* .frequency_tolerance = ???,*/
421 .symbol_rate_min = 1000000, /* FIXME: guessed! */
422 .symbol_rate_max = 45000000, /* FIXME: guessed! */
423 /* .symbol_rate_tolerance = ???,*/
424 .caps = FE_CAN_INVERSION_AUTO |
425 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
426 FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 |
427 FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO |
428 FE_CAN_QPSK | FE_CAN_MUTE_TS
429 },
430
431 .release = tda8083_release,
432
433 .init = tda8083_init,
434 .sleep = tda8083_sleep,
435
436 .set_frontend = tda8083_set_frontend,
437 .get_frontend = tda8083_get_frontend,
438
439 .read_status = tda8083_read_status,
440 .read_signal_strength = tda8083_read_signal_strength,
441 .read_snr = tda8083_read_snr,
442
443 .diseqc_send_master_cmd = tda8083_send_diseqc_msg,
444 .diseqc_send_burst = tda8083_diseqc_send_burst,
445 .set_tone = tda8083_diseqc_set_tone,
446 .set_voltage = tda8083_diseqc_set_voltage,
447};
448
449module_param(debug, int, 0644);
450MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
451
452MODULE_DESCRIPTION("Philips TDA8083 DVB-S Demodulator");
453MODULE_AUTHOR("Ralph Metzler, Holger Waechtler");
454MODULE_LICENSE("GPL");
455
456EXPORT_SYMBOL(tda8083_attach);
diff --git a/drivers/media/dvb/frontends/tda8083.h b/drivers/media/dvb/frontends/tda8083.h
new file mode 100644
index 000000000000..466663307bf1
--- /dev/null
+++ b/drivers/media/dvb/frontends/tda8083.h
@@ -0,0 +1,45 @@
1/*
2 Driver for Grundig 29504-491, a Philips TDA8083 based QPSK Frontend
3
4 Copyright (C) 2001 Convergence Integrated Media GmbH
5
6 written by Ralph Metzler <ralph@convergence.de>
7
8 adoption to the new DVB frontend API and diagnostic ioctl's
9 by Holger Waechtler <holger@convergence.de>
10
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2 of the License, or
14 (at your option) any later version.
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 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24
25*/
26
27#ifndef TDA8083_H
28#define TDA8083_H
29
30#include <linux/dvb/frontend.h>
31
32struct tda8083_config
33{
34 /* the demodulator's i2c address */
35 u8 demod_address;
36
37 /* PLL maintenance */
38 int (*pll_init)(struct dvb_frontend* fe);
39 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
40};
41
42extern struct dvb_frontend* tda8083_attach(const struct tda8083_config* config,
43 struct i2c_adapter* i2c);
44
45#endif // TDA8083_H
diff --git a/drivers/media/dvb/frontends/tda80xx.c b/drivers/media/dvb/frontends/tda80xx.c
new file mode 100644
index 000000000000..c99632114283
--- /dev/null
+++ b/drivers/media/dvb/frontends/tda80xx.c
@@ -0,0 +1,734 @@
1/*
2 * tda80xx.c
3 *
4 * Philips TDA8044 / TDA8083 QPSK demodulator driver
5 *
6 * Copyright (C) 2001 Felix Domke <tmbinc@elitedvb.net>
7 * Copyright (C) 2002-2004 Andreas Oberritter <obi@linuxtv.org>
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#include <linux/config.h>
25#include <linux/delay.h>
26#include <linux/init.h>
27#include <linux/spinlock.h>
28#include <linux/threads.h>
29#include <linux/interrupt.h>
30#include <asm/irq.h>
31#include <linux/kernel.h>
32#include <linux/module.h>
33#include <linux/slab.h>
34#include <asm/div64.h>
35
36#include "dvb_frontend.h"
37#include "tda80xx.h"
38
39enum {
40 ID_TDA8044 = 0x04,
41 ID_TDA8083 = 0x05,
42};
43
44
45struct tda80xx_state {
46
47 struct i2c_adapter* i2c;
48
49 struct dvb_frontend_ops ops;
50
51 /* configuration settings */
52 const struct tda80xx_config* config;
53
54 struct dvb_frontend frontend;
55
56 u32 clk;
57 int afc_loop;
58 struct work_struct worklet;
59 fe_code_rate_t code_rate;
60 fe_spectral_inversion_t spectral_inversion;
61 fe_status_t status;
62 u8 id;
63};
64
65static int debug = 1;
66#define dprintk if (debug) printk
67
68static u8 tda8044_inittab_pre[] = {
69 0x02, 0x00, 0x6f, 0xb5, 0x86, 0x22, 0x00, 0xea,
70 0x30, 0x42, 0x98, 0x68, 0x70, 0x42, 0x99, 0x58,
71 0x95, 0x10, 0xf5, 0xe7, 0x93, 0x0b, 0x15, 0x68,
72 0x9a, 0x90, 0x61, 0x80, 0x00, 0xe0, 0x40, 0x00,
73 0x0f, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
74 0x00, 0x00
75};
76
77static u8 tda8044_inittab_post[] = {
78 0x04, 0x00, 0x6f, 0xb5, 0x86, 0x22, 0x00, 0xea,
79 0x30, 0x42, 0x98, 0x68, 0x70, 0x42, 0x99, 0x50,
80 0x95, 0x10, 0xf5, 0xe7, 0x93, 0x0b, 0x15, 0x68,
81 0x9a, 0x90, 0x61, 0x80, 0x00, 0xe0, 0x40, 0x6c,
82 0x0f, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
83 0x00, 0x00
84};
85
86static u8 tda8083_inittab[] = {
87 0x04, 0x00, 0x4a, 0x79, 0x04, 0x00, 0xff, 0xea,
88 0x48, 0x42, 0x79, 0x60, 0x70, 0x52, 0x9a, 0x10,
89 0x0e, 0x10, 0xf2, 0xa7, 0x93, 0x0b, 0x05, 0xc8,
90 0x9d, 0x00, 0x42, 0x80, 0x00, 0x60, 0x40, 0x00,
91 0x00, 0x75, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00,
92 0x00, 0x00, 0x00, 0x00
93};
94
95static __inline__ u32 tda80xx_div(u32 a, u32 b)
96{
97 return (a + (b / 2)) / b;
98}
99
100static __inline__ u32 tda80xx_gcd(u32 a, u32 b)
101{
102 u32 r;
103
104 while ((r = a % b)) {
105 a = b;
106 b = r;
107 }
108
109 return b;
110}
111
112static int tda80xx_read(struct tda80xx_state* state, u8 reg, u8 *buf, u8 len)
113{
114 int ret;
115 struct i2c_msg msg[] = { { .addr = state->config->demod_address, .flags = 0, .buf = &reg, .len = 1 },
116 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = buf, .len = len } };
117
118 ret = i2c_transfer(state->i2c, msg, 2);
119
120 if (ret != 2)
121 dprintk("%s: readreg error (reg %02x, ret == %i)\n",
122 __FUNCTION__, reg, ret);
123
124 mdelay(10);
125
126 return (ret == 2) ? 0 : -EREMOTEIO;
127}
128
129static int tda80xx_write(struct tda80xx_state* state, u8 reg, const u8 *buf, u8 len)
130{
131 int ret;
132 u8 wbuf[len + 1];
133 struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = wbuf, .len = len + 1 };
134
135 wbuf[0] = reg;
136 memcpy(&wbuf[1], buf, len);
137
138 ret = i2c_transfer(state->i2c, &msg, 1);
139
140 if (ret != 1)
141 dprintk("%s: i2c xfer error (ret == %i)\n", __FUNCTION__, ret);
142
143 mdelay(10);
144
145 return (ret == 1) ? 0 : -EREMOTEIO;
146}
147
148static __inline__ u8 tda80xx_readreg(struct tda80xx_state* state, u8 reg)
149{
150 u8 val;
151
152 tda80xx_read(state, reg, &val, 1);
153
154 return val;
155}
156
157static __inline__ int tda80xx_writereg(struct tda80xx_state* state, u8 reg, u8 data)
158{
159 return tda80xx_write(state, reg, &data, 1);
160}
161
162static int tda80xx_set_parameters(struct tda80xx_state* state,
163 fe_spectral_inversion_t inversion,
164 u32 symbol_rate,
165 fe_code_rate_t fec_inner)
166{
167 u8 buf[15];
168 u64 ratio;
169 u32 clk;
170 u32 k;
171 u32 sr = symbol_rate;
172 u32 gcd;
173 u8 scd;
174
175 if (symbol_rate > (state->clk * 3) / 16)
176 scd = 0;
177 else if (symbol_rate > (state->clk * 3) / 32)
178 scd = 1;
179 else if (symbol_rate > (state->clk * 3) / 64)
180 scd = 2;
181 else
182 scd = 3;
183
184 clk = scd ? (state->clk / (scd * 2)) : state->clk;
185
186 /*
187 * Viterbi decoder:
188 * Differential decoding off
189 * Spectral inversion unknown
190 * QPSK modulation
191 */
192 if (inversion == INVERSION_ON)
193 buf[0] = 0x60;
194 else if (inversion == INVERSION_OFF)
195 buf[0] = 0x20;
196 else
197 buf[0] = 0x00;
198
199 /*
200 * CLK ratio:
201 * system clock frequency is up to 64 or 96 MHz
202 *
203 * formula:
204 * r = k * clk / symbol_rate
205 *
206 * k: 2^21 for caa 0..3,
207 * 2^20 for caa 4..5,
208 * 2^19 for caa 6..7
209 */
210 if (symbol_rate <= (clk * 3) / 32)
211 k = (1 << 19);
212 else if (symbol_rate <= (clk * 3) / 16)
213 k = (1 << 20);
214 else
215 k = (1 << 21);
216
217 gcd = tda80xx_gcd(clk, sr);
218 clk /= gcd;
219 sr /= gcd;
220
221 gcd = tda80xx_gcd(k, sr);
222 k /= gcd;
223 sr /= gcd;
224
225 ratio = (u64)k * (u64)clk;
226 do_div(ratio, sr);
227
228 buf[1] = ratio >> 16;
229 buf[2] = ratio >> 8;
230 buf[3] = ratio;
231
232 /* nyquist filter roll-off factor 35% */
233 buf[4] = 0x20;
234
235 clk = scd ? (state->clk / (scd * 2)) : state->clk;
236
237 /* Anti Alias Filter */
238 if (symbol_rate < (clk * 3) / 64)
239 printk("tda80xx: unsupported symbol rate: %u\n", symbol_rate);
240 else if (symbol_rate <= clk / 16)
241 buf[4] |= 0x07;
242 else if (symbol_rate <= (clk * 3) / 32)
243 buf[4] |= 0x06;
244 else if (symbol_rate <= clk / 8)
245 buf[4] |= 0x05;
246 else if (symbol_rate <= (clk * 3) / 16)
247 buf[4] |= 0x04;
248 else if (symbol_rate <= clk / 4)
249 buf[4] |= 0x03;
250 else if (symbol_rate <= (clk * 3) / 8)
251 buf[4] |= 0x02;
252 else if (symbol_rate <= clk / 2)
253 buf[4] |= 0x01;
254 else
255 buf[4] |= 0x00;
256
257 /* Sigma Delta converter */
258 buf[5] = 0x00;
259
260 /* FEC: Possible puncturing rates */
261 if (fec_inner == FEC_NONE)
262 buf[6] = 0x00;
263 else if ((fec_inner >= FEC_1_2) && (fec_inner <= FEC_8_9))
264 buf[6] = (1 << (8 - fec_inner));
265 else if (fec_inner == FEC_AUTO)
266 buf[6] = 0xff;
267 else
268 return -EINVAL;
269
270 /* carrier lock detector threshold value */
271 buf[7] = 0x30;
272 /* AFC1: proportional part settings */
273 buf[8] = 0x42;
274 /* AFC1: integral part settings */
275 buf[9] = 0x98;
276 /* PD: Leaky integrator SCPC mode */
277 buf[10] = 0x28;
278 /* AFC2, AFC1 controls */
279 buf[11] = 0x30;
280 /* PD: proportional part settings */
281 buf[12] = 0x42;
282 /* PD: integral part settings */
283 buf[13] = 0x99;
284 /* AGC */
285 buf[14] = 0x50 | scd;
286
287 printk("symbol_rate=%u clk=%u\n", symbol_rate, clk);
288
289 return tda80xx_write(state, 0x01, buf, sizeof(buf));
290}
291
292static int tda80xx_set_clk(struct tda80xx_state* state)
293{
294 u8 buf[2];
295
296 /* CLK proportional part */
297 buf[0] = (0x06 << 5) | 0x08; /* CMP[2:0], CSP[4:0] */
298 /* CLK integral part */
299 buf[1] = (0x04 << 5) | 0x1a; /* CMI[2:0], CSI[4:0] */
300
301 return tda80xx_write(state, 0x17, buf, sizeof(buf));
302}
303
304#if 0
305static int tda80xx_set_scpc_freq_offset(struct tda80xx_state* state)
306{
307 /* a constant value is nonsense here imho */
308 return tda80xx_writereg(state, 0x22, 0xf9);
309}
310#endif
311
312static int tda80xx_close_loop(struct tda80xx_state* state)
313{
314 u8 buf[2];
315
316 /* PD: Loop closed, LD: lock detect enable, SCPC: Sweep mode - AFC1 loop closed */
317 buf[0] = 0x68;
318 /* AFC1: Loop closed, CAR Feedback: 8192 */
319 buf[1] = 0x70;
320
321 return tda80xx_write(state, 0x0b, buf, sizeof(buf));
322}
323
324static irqreturn_t tda80xx_irq(int irq, void *priv, struct pt_regs *pt)
325{
326 schedule_work(priv);
327
328 return IRQ_HANDLED;
329}
330
331static void tda80xx_read_status_int(struct tda80xx_state* state)
332{
333 u8 val;
334
335 static const fe_spectral_inversion_t inv_tab[] = {
336 INVERSION_OFF, INVERSION_ON
337 };
338
339 static const fe_code_rate_t fec_tab[] = {
340 FEC_8_9, FEC_1_2, FEC_2_3, FEC_3_4,
341 FEC_4_5, FEC_5_6, FEC_6_7, FEC_7_8,
342 };
343
344 val = tda80xx_readreg(state, 0x02);
345
346 state->status = 0;
347
348 if (val & 0x01) /* demodulator lock */
349 state->status |= FE_HAS_SIGNAL;
350 if (val & 0x02) /* clock recovery lock */
351 state->status |= FE_HAS_CARRIER;
352 if (val & 0x04) /* viterbi lock */
353 state->status |= FE_HAS_VITERBI;
354 if (val & 0x08) /* deinterleaver lock (packet sync) */
355 state->status |= FE_HAS_SYNC;
356 if (val & 0x10) /* derandomizer lock (frame sync) */
357 state->status |= FE_HAS_LOCK;
358 if (val & 0x20) /* frontend can not lock */
359 state->status |= FE_TIMEDOUT;
360
361 if ((state->status & (FE_HAS_CARRIER)) && (state->afc_loop)) {
362 printk("tda80xx: closing loop\n");
363 tda80xx_close_loop(state);
364 state->afc_loop = 0;
365 }
366
367 if (state->status & (FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK)) {
368 val = tda80xx_readreg(state, 0x0e);
369 state->code_rate = fec_tab[val & 0x07];
370 if (state->status & (FE_HAS_SYNC | FE_HAS_LOCK))
371 state->spectral_inversion = inv_tab[(val >> 7) & 0x01];
372 else
373 state->spectral_inversion = INVERSION_AUTO;
374 }
375 else {
376 state->code_rate = FEC_AUTO;
377 }
378}
379
380static void tda80xx_worklet(void *priv)
381{
382 struct tda80xx_state *state = priv;
383
384 tda80xx_writereg(state, 0x00, 0x04);
385 enable_irq(state->config->irq);
386
387 tda80xx_read_status_int(state);
388}
389
390static void tda80xx_wait_diseqc_fifo(struct tda80xx_state* state)
391{
392 size_t i;
393
394 for (i = 0; i < 100; i++) {
395 if (tda80xx_readreg(state, 0x02) & 0x80)
396 break;
397 msleep(10);
398 }
399}
400
401static int tda8044_init(struct dvb_frontend* fe)
402{
403 struct tda80xx_state* state = (struct tda80xx_state*) fe->demodulator_priv;
404 int ret;
405
406 /*
407 * this function is a mess...
408 */
409
410 if ((ret = tda80xx_write(state, 0x00, tda8044_inittab_pre, sizeof(tda8044_inittab_pre))))
411 return ret;
412
413 tda80xx_writereg(state, 0x0f, 0x50);
414#if 1
415 tda80xx_writereg(state, 0x20, 0x8F); /* FIXME */
416 tda80xx_writereg(state, 0x20, state->config->volt18setting); /* FIXME */
417 //tda80xx_writereg(state, 0x00, 0x04);
418 tda80xx_writereg(state, 0x00, 0x0C);
419#endif
420 //tda80xx_writereg(state, 0x00, 0x08); /* Reset AFC1 loop filter */
421
422 tda80xx_write(state, 0x00, tda8044_inittab_post, sizeof(tda8044_inittab_post));
423
424 if (state->config->pll_init) {
425 tda80xx_writereg(state, 0x1c, 0x80);
426 state->config->pll_init(fe);
427 tda80xx_writereg(state, 0x1c, 0x00);
428 }
429
430 return 0;
431}
432
433static int tda8083_init(struct dvb_frontend* fe)
434{
435 struct tda80xx_state* state = (struct tda80xx_state*) fe->demodulator_priv;
436
437 tda80xx_write(state, 0x00, tda8083_inittab, sizeof(tda8083_inittab));
438
439 if (state->config->pll_init) {
440 tda80xx_writereg(state, 0x1c, 0x80);
441 state->config->pll_init(fe);
442 tda80xx_writereg(state, 0x1c, 0x00);
443 }
444
445 return 0;
446}
447
448static int tda80xx_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
449{
450 struct tda80xx_state* state = (struct tda80xx_state*) fe->demodulator_priv;
451
452 switch (voltage) {
453 case SEC_VOLTAGE_13:
454 return tda80xx_writereg(state, 0x20, state->config->volt13setting);
455 case SEC_VOLTAGE_18:
456 return tda80xx_writereg(state, 0x20, state->config->volt18setting);
457 case SEC_VOLTAGE_OFF:
458 return tda80xx_writereg(state, 0x20, 0);
459 default:
460 return -EINVAL;
461 }
462}
463
464static int tda80xx_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
465{
466 struct tda80xx_state* state = (struct tda80xx_state*) fe->demodulator_priv;
467
468 switch (tone) {
469 case SEC_TONE_OFF:
470 return tda80xx_writereg(state, 0x29, 0x00);
471 case SEC_TONE_ON:
472 return tda80xx_writereg(state, 0x29, 0x80);
473 default:
474 return -EINVAL;
475 }
476}
477
478static int tda80xx_send_diseqc_msg(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd *cmd)
479{
480 struct tda80xx_state* state = (struct tda80xx_state*) fe->demodulator_priv;
481
482 if (cmd->msg_len > 6)
483 return -EINVAL;
484
485 tda80xx_writereg(state, 0x29, 0x08 | (cmd->msg_len - 3));
486 tda80xx_write(state, 0x23, cmd->msg, cmd->msg_len);
487 tda80xx_writereg(state, 0x29, 0x0c | (cmd->msg_len - 3));
488 tda80xx_wait_diseqc_fifo(state);
489
490 return 0;
491}
492
493static int tda80xx_send_diseqc_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t cmd)
494{
495 struct tda80xx_state* state = (struct tda80xx_state*) fe->demodulator_priv;
496
497 switch (cmd) {
498 case SEC_MINI_A:
499 tda80xx_writereg(state, 0x29, 0x14);
500 break;
501 case SEC_MINI_B:
502 tda80xx_writereg(state, 0x29, 0x1c);
503 break;
504 default:
505 return -EINVAL;
506 }
507
508 tda80xx_wait_diseqc_fifo(state);
509
510 return 0;
511}
512
513static int tda80xx_sleep(struct dvb_frontend* fe)
514{
515 struct tda80xx_state* state = (struct tda80xx_state*) fe->demodulator_priv;
516
517 tda80xx_writereg(state, 0x00, 0x02); /* enter standby */
518
519 return 0;
520}
521
522static int tda80xx_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
523{
524 struct tda80xx_state* state = (struct tda80xx_state*) fe->demodulator_priv;
525
526 tda80xx_writereg(state, 0x1c, 0x80);
527 state->config->pll_set(fe, p);
528 tda80xx_writereg(state, 0x1c, 0x00);
529
530 tda80xx_set_parameters(state, p->inversion, p->u.qpsk.symbol_rate, p->u.qpsk.fec_inner);
531 tda80xx_set_clk(state);
532 //tda80xx_set_scpc_freq_offset(state);
533 state->afc_loop = 1;
534
535 return 0;
536}
537
538static int tda80xx_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
539{
540 struct tda80xx_state* state = (struct tda80xx_state*) fe->demodulator_priv;
541
542 if (!state->config->irq)
543 tda80xx_read_status_int(state);
544
545 p->inversion = state->spectral_inversion;
546 p->u.qpsk.fec_inner = state->code_rate;
547
548 return 0;
549}
550
551static int tda80xx_read_status(struct dvb_frontend* fe, fe_status_t* status)
552{
553 struct tda80xx_state* state = (struct tda80xx_state*) fe->demodulator_priv;
554
555 if (!state->config->irq)
556 tda80xx_read_status_int(state);
557 *status = state->status;
558
559 return 0;
560}
561
562static int tda80xx_read_ber(struct dvb_frontend* fe, u32* ber)
563{
564 struct tda80xx_state* state = (struct tda80xx_state*) fe->demodulator_priv;
565 int ret;
566 u8 buf[3];
567
568 if ((ret = tda80xx_read(state, 0x0b, buf, sizeof(buf))))
569 return ret;
570
571 *ber = ((buf[0] & 0x1f) << 16) | (buf[1] << 8) | buf[2];
572
573 return 0;
574}
575
576static int tda80xx_read_signal_strength(struct dvb_frontend* fe, u16* strength)
577{
578 struct tda80xx_state* state = (struct tda80xx_state*) fe->demodulator_priv;
579
580 u8 gain = ~tda80xx_readreg(state, 0x01);
581 *strength = (gain << 8) | gain;
582
583 return 0;
584}
585
586static int tda80xx_read_snr(struct dvb_frontend* fe, u16* snr)
587{
588 struct tda80xx_state* state = (struct tda80xx_state*) fe->demodulator_priv;
589
590 u8 quality = tda80xx_readreg(state, 0x08);
591 *snr = (quality << 8) | quality;
592
593 return 0;
594}
595
596static int tda80xx_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
597{
598 struct tda80xx_state* state = (struct tda80xx_state*) fe->demodulator_priv;
599
600 *ucblocks = tda80xx_readreg(state, 0x0f);
601 if (*ucblocks == 0xff)
602 *ucblocks = 0xffffffff;
603
604 return 0;
605}
606
607static int tda80xx_init(struct dvb_frontend* fe)
608{
609 struct tda80xx_state* state = (struct tda80xx_state*) fe->demodulator_priv;
610
611 switch(state->id) {
612 case ID_TDA8044:
613 return tda8044_init(fe);
614
615 case ID_TDA8083:
616 return tda8083_init(fe);
617 }
618 return 0;
619}
620
621static void tda80xx_release(struct dvb_frontend* fe)
622{
623 struct tda80xx_state* state = (struct tda80xx_state*) fe->demodulator_priv;
624
625 if (state->config->irq)
626 free_irq(state->config->irq, &state->worklet);
627
628 kfree(state);
629}
630
631static struct dvb_frontend_ops tda80xx_ops;
632
633struct dvb_frontend* tda80xx_attach(const struct tda80xx_config* config,
634 struct i2c_adapter* i2c)
635{
636 struct tda80xx_state* state = NULL;
637 int ret;
638
639 /* allocate memory for the internal state */
640 state = (struct tda80xx_state*) kmalloc(sizeof(struct tda80xx_state), GFP_KERNEL);
641 if (state == NULL) goto error;
642
643 /* setup the state */
644 state->config = config;
645 state->i2c = i2c;
646 memcpy(&state->ops, &tda80xx_ops, sizeof(struct dvb_frontend_ops));
647 state->spectral_inversion = INVERSION_AUTO;
648 state->code_rate = FEC_AUTO;
649 state->status = 0;
650 state->afc_loop = 0;
651
652 /* check if the demod is there */
653 if (tda80xx_writereg(state, 0x89, 0x00) < 0) goto error;
654 state->id = tda80xx_readreg(state, 0x00);
655
656 switch (state->id) {
657 case ID_TDA8044:
658 state->clk = 96000000;
659 printk("tda80xx: Detected tda8044\n");
660 break;
661
662 case ID_TDA8083:
663 state->clk = 64000000;
664 printk("tda80xx: Detected tda8083\n");
665 break;
666
667 default:
668 goto error;
669 }
670
671 /* setup IRQ */
672 if (state->config->irq) {
673 INIT_WORK(&state->worklet, tda80xx_worklet, state);
674 if ((ret = request_irq(state->config->irq, tda80xx_irq, SA_ONESHOT, "tda80xx", &state->worklet)) < 0) {
675 printk(KERN_ERR "tda80xx: request_irq failed (%d)\n", ret);
676 goto error;
677 }
678 }
679
680 /* create dvb_frontend */
681 state->frontend.ops = &state->ops;
682 state->frontend.demodulator_priv = state;
683 return &state->frontend;
684
685error:
686 kfree(state);
687 return NULL;
688}
689
690static struct dvb_frontend_ops tda80xx_ops = {
691
692 .info = {
693 .name = "Philips TDA80xx DVB-S",
694 .type = FE_QPSK,
695 .frequency_min = 500000,
696 .frequency_max = 2700000,
697 .frequency_stepsize = 125,
698 .symbol_rate_min = 4500000,
699 .symbol_rate_max = 45000000,
700 .caps = FE_CAN_INVERSION_AUTO |
701 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
702 FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 |
703 FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO |
704 FE_CAN_QPSK |
705 FE_CAN_MUTE_TS
706 },
707
708 .release = tda80xx_release,
709
710 .init = tda80xx_init,
711 .sleep = tda80xx_sleep,
712
713 .set_frontend = tda80xx_set_frontend,
714 .get_frontend = tda80xx_get_frontend,
715
716 .read_status = tda80xx_read_status,
717 .read_ber = tda80xx_read_ber,
718 .read_signal_strength = tda80xx_read_signal_strength,
719 .read_snr = tda80xx_read_snr,
720 .read_ucblocks = tda80xx_read_ucblocks,
721
722 .diseqc_send_master_cmd = tda80xx_send_diseqc_msg,
723 .diseqc_send_burst = tda80xx_send_diseqc_burst,
724 .set_tone = tda80xx_set_tone,
725 .set_voltage = tda80xx_set_voltage,
726};
727
728module_param(debug, int, 0644);
729
730MODULE_DESCRIPTION("Philips TDA8044 / TDA8083 DVB-S Demodulator driver");
731MODULE_AUTHOR("Felix Domke, Andreas Oberritter");
732MODULE_LICENSE("GPL");
733
734EXPORT_SYMBOL(tda80xx_attach);
diff --git a/drivers/media/dvb/frontends/tda80xx.h b/drivers/media/dvb/frontends/tda80xx.h
new file mode 100644
index 000000000000..cd639a0aad55
--- /dev/null
+++ b/drivers/media/dvb/frontends/tda80xx.h
@@ -0,0 +1,51 @@
1/*
2 * tda80xx.c
3 *
4 * Philips TDA8044 / TDA8083 QPSK demodulator driver
5 *
6 * Copyright (C) 2001 Felix Domke <tmbinc@elitedvb.net>
7 * Copyright (C) 2002-2004 Andreas Oberritter <obi@linuxtv.org>
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#ifndef TDA80XX_H
25#define TDA80XX_H
26
27#include <linux/dvb/frontend.h>
28
29struct tda80xx_config
30{
31 /* the demodulator's i2c address */
32 u8 demod_address;
33
34 /* IRQ to use (0=>no IRQ used) */
35 u32 irq;
36
37 /* Register setting to use for 13v */
38 u8 volt13setting;
39
40 /* Register setting to use for 18v */
41 u8 volt18setting;
42
43 /* PLL maintenance */
44 int (*pll_init)(struct dvb_frontend* fe);
45 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
46};
47
48extern struct dvb_frontend* tda80xx_attach(const struct tda80xx_config* config,
49 struct i2c_adapter* i2c);
50
51#endif // TDA80XX_H
diff --git a/drivers/media/dvb/frontends/ves1820.c b/drivers/media/dvb/frontends/ves1820.c
new file mode 100644
index 000000000000..9c0d23e1d9e5
--- /dev/null
+++ b/drivers/media/dvb/frontends/ves1820.c
@@ -0,0 +1,450 @@
1/*
2 VES1820 - Single Chip Cable Channel Receiver driver module
3
4 Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19*/
20
21#include <linux/config.h>
22#include <linux/delay.h>
23#include <linux/errno.h>
24#include <linux/init.h>
25#include <linux/kernel.h>
26#include <linux/module.h>
27#include <linux/string.h>
28#include <linux/slab.h>
29#include <asm/div64.h>
30
31#include "dvb_frontend.h"
32#include "ves1820.h"
33
34
35
36struct ves1820_state {
37 struct i2c_adapter* i2c;
38 struct dvb_frontend_ops ops;
39 /* configuration settings */
40 const struct ves1820_config* config;
41 struct dvb_frontend frontend;
42
43 /* private demodulator data */
44 u8 reg0;
45 u8 pwm;
46};
47
48
49static int verbose;
50
51static u8 ves1820_inittab[] = {
52 0x69, 0x6A, 0x93, 0x12, 0x12, 0x46, 0x26, 0x1A,
53 0x43, 0x6A, 0xAA, 0xAA, 0x1E, 0x85, 0x43, 0x20,
54 0xE0, 0x00, 0xA1, 0x00, 0x00, 0x00, 0x00, 0x00,
55 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
56 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
57 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
58 0x00, 0x00, 0x00, 0x00, 0x40
59};
60
61static int ves1820_writereg(struct ves1820_state *state, u8 reg, u8 data)
62{
63 u8 buf[] = { 0x00, reg, data };
64 struct i2c_msg msg = {.addr = state->config->demod_address,.flags = 0,.buf = buf,.len = 3 };
65 int ret;
66
67 ret = i2c_transfer(state->i2c, &msg, 1);
68
69 if (ret != 1)
70 printk("ves1820: %s(): writereg error (reg == 0x%02x,"
71 "val == 0x%02x, ret == %i)\n", __FUNCTION__, reg, data, ret);
72
73 msleep(10);
74 return (ret != 1) ? -EREMOTEIO : 0;
75}
76
77static u8 ves1820_readreg(struct ves1820_state *state, u8 reg)
78{
79 u8 b0[] = { 0x00, reg };
80 u8 b1[] = { 0 };
81 struct i2c_msg msg[] = {
82 {.addr = state->config->demod_address,.flags = 0,.buf = b0,.len = 2},
83 {.addr = state->config->demod_address,.flags = I2C_M_RD,.buf = b1,.len = 1}
84 };
85 int ret;
86
87 ret = i2c_transfer(state->i2c, msg, 2);
88
89 if (ret != 2)
90 printk("ves1820: %s(): readreg error (reg == 0x%02x,"
91 "ret == %i)\n", __FUNCTION__, reg, ret);
92
93 return b1[0];
94}
95
96static int ves1820_setup_reg0(struct ves1820_state *state, u8 reg0, fe_spectral_inversion_t inversion)
97{
98 reg0 |= state->reg0 & 0x62;
99
100 if (INVERSION_ON == inversion) {
101 if (!state->config->invert) reg0 |= 0x20;
102 else reg0 &= ~0x20;
103 } else if (INVERSION_OFF == inversion) {
104 if (!state->config->invert) reg0 &= ~0x20;
105 else reg0 |= 0x20;
106 }
107
108 ves1820_writereg(state, 0x00, reg0 & 0xfe);
109 ves1820_writereg(state, 0x00, reg0 | 0x01);
110
111 state->reg0 = reg0;
112
113 return 0;
114}
115
116static int ves1820_set_symbolrate(struct ves1820_state *state, u32 symbolrate)
117{
118 s32 BDR;
119 s32 BDRI;
120 s16 SFIL = 0;
121 u16 NDEC = 0;
122 u32 ratio;
123 u32 fin;
124 u32 tmp;
125 u64 fptmp;
126 u64 fpxin;
127
128 if (symbolrate > state->config->xin / 2)
129 symbolrate = state->config->xin / 2;
130
131 if (symbolrate < 500000)
132 symbolrate = 500000;
133
134 if (symbolrate < state->config->xin / 16)
135 NDEC = 1;
136 if (symbolrate < state->config->xin / 32)
137 NDEC = 2;
138 if (symbolrate < state->config->xin / 64)
139 NDEC = 3;
140
141 /* yeuch! */
142 fpxin = state->config->xin * 10;
143 fptmp = fpxin; do_div(fptmp, 123);
144 if (symbolrate < fptmp);
145 SFIL = 1;
146 fptmp = fpxin; do_div(fptmp, 160);
147 if (symbolrate < fptmp);
148 SFIL = 0;
149 fptmp = fpxin; do_div(fptmp, 246);
150 if (symbolrate < fptmp);
151 SFIL = 1;
152 fptmp = fpxin; do_div(fptmp, 320);
153 if (symbolrate < fptmp);
154 SFIL = 0;
155 fptmp = fpxin; do_div(fptmp, 492);
156 if (symbolrate < fptmp);
157 SFIL = 1;
158 fptmp = fpxin; do_div(fptmp, 640);
159 if (symbolrate < fptmp);
160 SFIL = 0;
161 fptmp = fpxin; do_div(fptmp, 984);
162 if (symbolrate < fptmp);
163 SFIL = 1;
164
165 fin = state->config->xin >> 4;
166 symbolrate <<= NDEC;
167 ratio = (symbolrate << 4) / fin;
168 tmp = ((symbolrate << 4) % fin) << 8;
169 ratio = (ratio << 8) + tmp / fin;
170 tmp = (tmp % fin) << 8;
171 ratio = (ratio << 8) + (tmp + fin / 2) / fin;
172
173 BDR = ratio;
174 BDRI = (((state->config->xin << 5) / symbolrate) + 1) / 2;
175
176 if (BDRI > 0xFF)
177 BDRI = 0xFF;
178
179 SFIL = (SFIL << 4) | ves1820_inittab[0x0E];
180
181 NDEC = (NDEC << 6) | ves1820_inittab[0x03];
182
183 ves1820_writereg(state, 0x03, NDEC);
184 ves1820_writereg(state, 0x0a, BDR & 0xff);
185 ves1820_writereg(state, 0x0b, (BDR >> 8) & 0xff);
186 ves1820_writereg(state, 0x0c, (BDR >> 16) & 0x3f);
187
188 ves1820_writereg(state, 0x0d, BDRI);
189 ves1820_writereg(state, 0x0e, SFIL);
190
191 return 0;
192}
193
194static int ves1820_init(struct dvb_frontend* fe)
195{
196 struct ves1820_state* state = (struct ves1820_state*) fe->demodulator_priv;
197 int i;
198 int val;
199
200 ves1820_writereg(state, 0, 0);
201
202 for (i = 0; i < 53; i++) {
203 val = ves1820_inittab[i];
204 if ((i == 2) && (state->config->selagc)) val |= 0x08;
205 ves1820_writereg(state, i, val);
206 }
207
208 ves1820_writereg(state, 0x34, state->pwm);
209
210 if (state->config->pll_init) state->config->pll_init(fe);
211
212 return 0;
213}
214
215static int ves1820_set_parameters(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
216{
217 struct ves1820_state* state = (struct ves1820_state*) fe->demodulator_priv;
218 static const u8 reg0x00[] = { 0x00, 0x04, 0x08, 0x0c, 0x10 };
219 static const u8 reg0x01[] = { 140, 140, 106, 100, 92 };
220 static const u8 reg0x05[] = { 135, 100, 70, 54, 38 };
221 static const u8 reg0x08[] = { 162, 116, 67, 52, 35 };
222 static const u8 reg0x09[] = { 145, 150, 106, 126, 107 };
223 int real_qam = p->u.qam.modulation - QAM_16;
224
225 if (real_qam < 0 || real_qam > 4)
226 return -EINVAL;
227
228 state->config->pll_set(fe, p);
229 ves1820_set_symbolrate(state, p->u.qam.symbol_rate);
230 ves1820_writereg(state, 0x34, state->pwm);
231
232 ves1820_writereg(state, 0x01, reg0x01[real_qam]);
233 ves1820_writereg(state, 0x05, reg0x05[real_qam]);
234 ves1820_writereg(state, 0x08, reg0x08[real_qam]);
235 ves1820_writereg(state, 0x09, reg0x09[real_qam]);
236
237 ves1820_setup_reg0(state, reg0x00[real_qam], p->inversion);
238
239 return 0;
240}
241
242static int ves1820_read_status(struct dvb_frontend* fe, fe_status_t* status)
243{
244 struct ves1820_state* state = (struct ves1820_state*) fe->demodulator_priv;
245 int sync;
246
247 *status = 0;
248 sync = ves1820_readreg(state, 0x11);
249
250 if (sync & 1)
251 *status |= FE_HAS_SIGNAL;
252
253 if (sync & 2)
254 *status |= FE_HAS_CARRIER;
255
256 if (sync & 2) /* XXX FIXME! */
257 *status |= FE_HAS_VITERBI;
258
259 if (sync & 4)
260 *status |= FE_HAS_SYNC;
261
262 if (sync & 8)
263 *status |= FE_HAS_LOCK;
264
265 return 0;
266}
267
268static int ves1820_read_ber(struct dvb_frontend* fe, u32* ber)
269{
270 struct ves1820_state* state = (struct ves1820_state*) fe->demodulator_priv;
271
272 u32 _ber = ves1820_readreg(state, 0x14) |
273 (ves1820_readreg(state, 0x15) << 8) |
274 ((ves1820_readreg(state, 0x16) & 0x0f) << 16);
275 *ber = 10 * _ber;
276
277 return 0;
278}
279
280static int ves1820_read_signal_strength(struct dvb_frontend* fe, u16* strength)
281{
282 struct ves1820_state* state = (struct ves1820_state*) fe->demodulator_priv;
283
284 u8 gain = ves1820_readreg(state, 0x17);
285 *strength = (gain << 8) | gain;
286
287 return 0;
288}
289
290static int ves1820_read_snr(struct dvb_frontend* fe, u16* snr)
291{
292 struct ves1820_state* state = (struct ves1820_state*) fe->demodulator_priv;
293
294 u8 quality = ~ves1820_readreg(state, 0x18);
295 *snr = (quality << 8) | quality;
296
297 return 0;
298}
299
300static int ves1820_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
301{
302 struct ves1820_state* state = (struct ves1820_state*) fe->demodulator_priv;
303
304 *ucblocks = ves1820_readreg(state, 0x13) & 0x7f;
305 if (*ucblocks == 0x7f)
306 *ucblocks = 0xffffffff;
307
308 /* reset uncorrected block counter */
309 ves1820_writereg(state, 0x10, ves1820_inittab[0x10] & 0xdf);
310 ves1820_writereg(state, 0x10, ves1820_inittab[0x10]);
311
312 return 0;
313}
314
315static int ves1820_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
316{
317 struct ves1820_state* state = (struct ves1820_state*) fe->demodulator_priv;
318 int sync;
319 s8 afc = 0;
320
321 sync = ves1820_readreg(state, 0x11);
322 afc = ves1820_readreg(state, 0x19);
323 if (verbose) {
324 /* AFC only valid when carrier has been recovered */
325 printk(sync & 2 ? "ves1820: AFC (%d) %dHz\n" :
326 "ves1820: [AFC (%d) %dHz]\n", afc, -((s32) p->u.qam.symbol_rate * afc) >> 10);
327 }
328
329 if (!state->config->invert) {
330 p->inversion = (state->reg0 & 0x20) ? INVERSION_ON : INVERSION_OFF;
331 } else {
332 p->inversion = (!(state->reg0 & 0x20)) ? INVERSION_ON : INVERSION_OFF;
333 }
334
335 p->u.qam.modulation = ((state->reg0 >> 2) & 7) + QAM_16;
336
337 p->u.qam.fec_inner = FEC_NONE;
338
339 p->frequency = ((p->frequency + 31250) / 62500) * 62500;
340 if (sync & 2)
341 p->frequency -= ((s32) p->u.qam.symbol_rate * afc) >> 10;
342
343 return 0;
344}
345
346static int ves1820_sleep(struct dvb_frontend* fe)
347{
348 struct ves1820_state* state = (struct ves1820_state*) fe->demodulator_priv;
349
350 ves1820_writereg(state, 0x1b, 0x02); /* pdown ADC */
351 ves1820_writereg(state, 0x00, 0x80); /* standby */
352
353 return 0;
354}
355
356static int ves1820_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
357{
358
359 fesettings->min_delay_ms = 200;
360 fesettings->step_size = 0;
361 fesettings->max_drift = 0;
362 return 0;
363}
364
365static void ves1820_release(struct dvb_frontend* fe)
366{
367 struct ves1820_state* state = (struct ves1820_state*) fe->demodulator_priv;
368 kfree(state);
369}
370
371static struct dvb_frontend_ops ves1820_ops;
372
373struct dvb_frontend* ves1820_attach(const struct ves1820_config* config,
374 struct i2c_adapter* i2c,
375 u8 pwm)
376{
377 struct ves1820_state* state = NULL;
378
379 /* allocate memory for the internal state */
380 state = (struct ves1820_state*) kmalloc(sizeof(struct ves1820_state), GFP_KERNEL);
381 if (state == NULL)
382 goto error;
383
384 /* setup the state */
385 memcpy(&state->ops, &ves1820_ops, sizeof(struct dvb_frontend_ops));
386 state->reg0 = ves1820_inittab[0];
387 state->config = config;
388 state->i2c = i2c;
389 state->pwm = pwm;
390
391 /* check if the demod is there */
392 if ((ves1820_readreg(state, 0x1a) & 0xf0) != 0x70)
393 goto error;
394
395 if (verbose)
396 printk("ves1820: pwm=0x%02x\n", state->pwm);
397
398 state->ops.info.symbol_rate_min = (state->config->xin / 2) / 64; /* SACLK/64 == (XIN/2)/64 */
399 state->ops.info.symbol_rate_max = (state->config->xin / 2) / 4; /* SACLK/4 */
400
401 /* create dvb_frontend */
402 state->frontend.ops = &state->ops;
403 state->frontend.demodulator_priv = state;
404 return &state->frontend;
405
406error:
407 kfree(state);
408 return NULL;
409}
410
411static struct dvb_frontend_ops ves1820_ops = {
412
413 .info = {
414 .name = "VLSI VES1820 DVB-C",
415 .type = FE_QAM,
416 .frequency_stepsize = 62500,
417 .frequency_min = 51000000,
418 .frequency_max = 858000000,
419 .caps = FE_CAN_QAM_16 |
420 FE_CAN_QAM_32 |
421 FE_CAN_QAM_64 |
422 FE_CAN_QAM_128 |
423 FE_CAN_QAM_256 |
424 FE_CAN_FEC_AUTO
425 },
426
427 .release = ves1820_release,
428
429 .init = ves1820_init,
430 .sleep = ves1820_sleep,
431
432 .set_frontend = ves1820_set_parameters,
433 .get_frontend = ves1820_get_frontend,
434 .get_tune_settings = ves1820_get_tune_settings,
435
436 .read_status = ves1820_read_status,
437 .read_ber = ves1820_read_ber,
438 .read_signal_strength = ves1820_read_signal_strength,
439 .read_snr = ves1820_read_snr,
440 .read_ucblocks = ves1820_read_ucblocks,
441};
442
443module_param(verbose, int, 0644);
444MODULE_PARM_DESC(verbose, "print AFC offset after tuning for debugging the PWM setting");
445
446MODULE_DESCRIPTION("VLSI VES1820 DVB-C Demodulator driver");
447MODULE_AUTHOR("Ralph Metzler, Holger Waechtler");
448MODULE_LICENSE("GPL");
449
450EXPORT_SYMBOL(ves1820_attach);
diff --git a/drivers/media/dvb/frontends/ves1820.h b/drivers/media/dvb/frontends/ves1820.h
new file mode 100644
index 000000000000..355f130b1be8
--- /dev/null
+++ b/drivers/media/dvb/frontends/ves1820.h
@@ -0,0 +1,51 @@
1/*
2 VES1820 - Single Chip Cable Channel Receiver driver module
3
4 Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19*/
20
21#ifndef VES1820_H
22#define VES1820_H
23
24#include <linux/dvb/frontend.h>
25
26#define VES1820_SELAGC_PWM 0
27#define VES1820_SELAGC_SIGNAMPERR 1
28
29struct ves1820_config
30{
31 /* the demodulator's i2c address */
32 u8 demod_address;
33
34 /* value of XIN to use */
35 u32 xin;
36
37 /* does inversion need inverted? */
38 u8 invert:1;
39
40 /* SELAGC control */
41 u8 selagc:1;
42
43 /* PLL maintenance */
44 int (*pll_init)(struct dvb_frontend* fe);
45 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
46};
47
48extern struct dvb_frontend* ves1820_attach(const struct ves1820_config* config,
49 struct i2c_adapter* i2c, u8 pwm);
50
51#endif // VES1820_H
diff --git a/drivers/media/dvb/frontends/ves1x93.c b/drivers/media/dvb/frontends/ves1x93.c
new file mode 100644
index 000000000000..edcad283aa86
--- /dev/null
+++ b/drivers/media/dvb/frontends/ves1x93.c
@@ -0,0 +1,545 @@
1/*
2 Driver for VES1893 and VES1993 QPSK Demodulators
3
4 Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de>
5 Copyright (C) 2001 Ronny Strutz <3des@elitedvb.de>
6 Copyright (C) 2002 Dennis Noermann <dennis.noermann@noernet.de>
7 Copyright (C) 2002-2003 Andreas Oberritter <obi@linuxtv.org>
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
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., 675 Mass Ave, Cambridge, MA 02139, USA.
23
24*/
25
26#include <linux/kernel.h>
27#include <linux/module.h>
28#include <linux/init.h>
29#include <linux/string.h>
30#include <linux/slab.h>
31#include <linux/delay.h>
32
33#include "dvb_frontend.h"
34#include "ves1x93.h"
35
36
37struct ves1x93_state {
38 struct i2c_adapter* i2c;
39 struct dvb_frontend_ops ops;
40 /* configuration settings */
41 const struct ves1x93_config* config;
42 struct dvb_frontend frontend;
43
44 /* previous uncorrected block counter */
45 fe_spectral_inversion_t inversion;
46 u8 *init_1x93_tab;
47 u8 *init_1x93_wtab;
48 u8 tab_size;
49 u8 demod_type;
50};
51
52static int debug = 0;
53#define dprintk if (debug) printk
54
55#define DEMOD_VES1893 0
56#define DEMOD_VES1993 1
57
58static u8 init_1893_tab [] = {
59 0x01, 0xa4, 0x35, 0x80, 0x2a, 0x0b, 0x55, 0xc4,
60 0x09, 0x69, 0x00, 0x86, 0x4c, 0x28, 0x7f, 0x00,
61 0x00, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
62 0x80, 0x00, 0x21, 0xb0, 0x14, 0x00, 0xdc, 0x00,
63 0x81, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
64 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
65 0x00, 0x55, 0x00, 0x00, 0x7f, 0x00
66};
67
68static u8 init_1993_tab [] = {
69 0x00, 0x9c, 0x35, 0x80, 0x6a, 0x09, 0x72, 0x8c,
70 0x09, 0x6b, 0x00, 0x00, 0x4c, 0x08, 0x00, 0x00,
71 0x00, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
72 0x80, 0x40, 0x21, 0xb0, 0x00, 0x00, 0x00, 0x10,
73 0x81, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
74 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00,
75 0x00, 0x55, 0x03, 0x00, 0x00, 0x00, 0x00, 0x03,
76 0x00, 0x00, 0x0e, 0x80, 0x00
77};
78
79static u8 init_1893_wtab[] =
80{
81 1,1,1,1,1,1,1,1, 1,1,0,0,1,1,0,0,
82 0,1,0,0,0,0,0,0, 1,0,1,1,0,0,0,1,
83 1,1,1,0,0,0,0,0, 0,0,1,1,0,0,0,0,
84 1,1,1,0,1,1
85};
86
87static u8 init_1993_wtab[] =
88{
89 1,1,1,1,1,1,1,1, 1,1,0,0,1,1,0,0,
90 0,1,0,0,0,0,0,0, 1,1,1,1,0,0,0,1,
91 1,1,1,0,0,0,0,0, 0,0,1,1,0,0,0,0,
92 1,1,1,0,1,1,1,1, 1,1,1,1,1
93};
94
95static int ves1x93_writereg (struct ves1x93_state* state, u8 reg, u8 data)
96{
97 u8 buf [] = { 0x00, reg, data };
98 struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 3 };
99 int err;
100
101 if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
102 dprintk ("%s: writereg error (err == %i, reg == 0x%02x, data == 0x%02x)\n", __FUNCTION__, err, reg, data);
103 return -EREMOTEIO;
104 }
105
106 return 0;
107}
108
109static u8 ves1x93_readreg (struct ves1x93_state* state, u8 reg)
110{
111 int ret;
112 u8 b0 [] = { 0x00, reg };
113 u8 b1 [] = { 0 };
114 struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 2 },
115 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
116
117 ret = i2c_transfer (state->i2c, msg, 2);
118
119 if (ret != 2) return ret;
120
121 return b1[0];
122}
123
124static int ves1x93_clr_bit (struct ves1x93_state* state)
125{
126 msleep(10);
127 ves1x93_writereg (state, 0, state->init_1x93_tab[0] & 0xfe);
128 ves1x93_writereg (state, 0, state->init_1x93_tab[0]);
129 msleep(50);
130 return 0;
131}
132
133static int ves1x93_set_inversion (struct ves1x93_state* state, fe_spectral_inversion_t inversion)
134{
135 u8 val;
136
137 /*
138 * inversion on/off are interchanged because i and q seem to
139 * be swapped on the hardware
140 */
141
142 switch (inversion) {
143 case INVERSION_OFF:
144 val = 0xc0;
145 break;
146 case INVERSION_ON:
147 val = 0x80;
148 break;
149 case INVERSION_AUTO:
150 val = 0x00;
151 break;
152 default:
153 return -EINVAL;
154 }
155
156 return ves1x93_writereg (state, 0x0c, (state->init_1x93_tab[0x0c] & 0x3f) | val);
157}
158
159static int ves1x93_set_fec (struct ves1x93_state* state, fe_code_rate_t fec)
160{
161 if (fec == FEC_AUTO)
162 return ves1x93_writereg (state, 0x0d, 0x08);
163 else if (fec < FEC_1_2 || fec > FEC_8_9)
164 return -EINVAL;
165 else
166 return ves1x93_writereg (state, 0x0d, fec - FEC_1_2);
167}
168
169static fe_code_rate_t ves1x93_get_fec (struct ves1x93_state* state)
170{
171 return FEC_1_2 + ((ves1x93_readreg (state, 0x0d) >> 4) & 0x7);
172}
173
174static int ves1x93_set_symbolrate (struct ves1x93_state* state, u32 srate)
175{
176 u32 BDR;
177 u32 ratio;
178 u8 ADCONF, FCONF, FNR, AGCR;
179 u32 BDRI;
180 u32 tmp;
181 u32 FIN;
182
183 dprintk("%s: srate == %d\n", __FUNCTION__, (unsigned int) srate);
184
185 if (srate > state->config->xin/2)
186 srate = state->config->xin/2;
187
188 if (srate < 500000)
189 srate = 500000;
190
191#define MUL (1UL<<26)
192
193 FIN = (state->config->xin + 6000) >> 4;
194
195 tmp = srate << 6;
196 ratio = tmp / FIN;
197
198 tmp = (tmp % FIN) << 8;
199 ratio = (ratio << 8) + tmp / FIN;
200
201 tmp = (tmp % FIN) << 8;
202 ratio = (ratio << 8) + tmp / FIN;
203
204 FNR = 0xff;
205
206 if (ratio < MUL/3) FNR = 0;
207 if (ratio < (MUL*11)/50) FNR = 1;
208 if (ratio < MUL/6) FNR = 2;
209 if (ratio < MUL/9) FNR = 3;
210 if (ratio < MUL/12) FNR = 4;
211 if (ratio < (MUL*11)/200) FNR = 5;
212 if (ratio < MUL/24) FNR = 6;
213 if (ratio < (MUL*27)/1000) FNR = 7;
214 if (ratio < MUL/48) FNR = 8;
215 if (ratio < (MUL*137)/10000) FNR = 9;
216
217 if (FNR == 0xff) {
218 ADCONF = 0x89;
219 FCONF = 0x80;
220 FNR = 0;
221 } else {
222 ADCONF = 0x81;
223 FCONF = 0x88 | (FNR >> 1) | ((FNR & 0x01) << 5);
224 /*FCONF = 0x80 | ((FNR & 0x01) << 5) | (((FNR > 1) & 0x03) << 3) | ((FNR >> 1) & 0x07);*/
225 }
226
227 BDR = (( (ratio << (FNR >> 1)) >> 4) + 1) >> 1;
228 BDRI = ( ((FIN << 8) / ((srate << (FNR >> 1)) >> 2)) + 1) >> 1;
229
230 dprintk("FNR= %d\n", FNR);
231 dprintk("ratio= %08x\n", (unsigned int) ratio);
232 dprintk("BDR= %08x\n", (unsigned int) BDR);
233 dprintk("BDRI= %02x\n", (unsigned int) BDRI);
234
235 if (BDRI > 0xff)
236 BDRI = 0xff;
237
238 ves1x93_writereg (state, 0x06, 0xff & BDR);
239 ves1x93_writereg (state, 0x07, 0xff & (BDR >> 8));
240 ves1x93_writereg (state, 0x08, 0x0f & (BDR >> 16));
241
242 ves1x93_writereg (state, 0x09, BDRI);
243 ves1x93_writereg (state, 0x20, ADCONF);
244 ves1x93_writereg (state, 0x21, FCONF);
245
246 AGCR = state->init_1x93_tab[0x05];
247 if (state->config->invert_pwm)
248 AGCR |= 0x20;
249
250 if (srate < 6000000)
251 AGCR |= 0x80;
252 else
253 AGCR &= ~0x80;
254
255 ves1x93_writereg (state, 0x05, AGCR);
256
257 /* ves1993 hates this, will lose lock */
258 if (state->demod_type != DEMOD_VES1993)
259 ves1x93_clr_bit (state);
260
261 return 0;
262}
263
264static int ves1x93_init (struct dvb_frontend* fe)
265{
266 struct ves1x93_state* state = (struct ves1x93_state*) fe->demodulator_priv;
267 int i;
268 int val;
269
270 dprintk("%s: init chip\n", __FUNCTION__);
271
272 for (i = 0; i < state->tab_size; i++) {
273 if (state->init_1x93_wtab[i]) {
274 val = state->init_1x93_tab[i];
275
276 if (state->config->invert_pwm && (i == 0x05)) val |= 0x20; /* invert PWM */
277 ves1x93_writereg (state, i, val);
278 }
279 }
280
281 if (state->config->pll_init) {
282 ves1x93_writereg(state, 0x00, 0x11);
283 state->config->pll_init(fe);
284 ves1x93_writereg(state, 0x00, 0x01);
285 }
286
287 return 0;
288}
289
290static int ves1x93_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltage)
291{
292 struct ves1x93_state* state = (struct ves1x93_state*) fe->demodulator_priv;
293
294 switch (voltage) {
295 case SEC_VOLTAGE_13:
296 return ves1x93_writereg (state, 0x1f, 0x20);
297 case SEC_VOLTAGE_18:
298 return ves1x93_writereg (state, 0x1f, 0x30);
299 case SEC_VOLTAGE_OFF:
300 return ves1x93_writereg (state, 0x1f, 0x00);
301 default:
302 return -EINVAL;
303 }
304}
305
306static int ves1x93_read_status(struct dvb_frontend* fe, fe_status_t* status)
307{
308 struct ves1x93_state* state = (struct ves1x93_state*) fe->demodulator_priv;
309
310 u8 sync = ves1x93_readreg (state, 0x0e);
311
312 /*
313 * The ves1893 sometimes returns sync values that make no sense,
314 * because, e.g., the SIGNAL bit is 0, while some of the higher
315 * bits are 1 (and how can there be a CARRIER w/o a SIGNAL?).
316 * Tests showed that the the VITERBI and SYNC bits are returned
317 * reliably, while the SIGNAL and CARRIER bits ar sometimes wrong.
318 * If such a case occurs, we read the value again, until we get a
319 * valid value.
320 */
321 int maxtry = 10; /* just for safety - let's not get stuck here */
322 while ((sync & 0x03) != 0x03 && (sync & 0x0c) && maxtry--) {
323 msleep(10);
324 sync = ves1x93_readreg (state, 0x0e);
325 }
326
327 *status = 0;
328
329 if (sync & 1)
330 *status |= FE_HAS_SIGNAL;
331
332 if (sync & 2)
333 *status |= FE_HAS_CARRIER;
334
335 if (sync & 4)
336 *status |= FE_HAS_VITERBI;
337
338 if (sync & 8)
339 *status |= FE_HAS_SYNC;
340
341 if ((sync & 0x1f) == 0x1f)
342 *status |= FE_HAS_LOCK;
343
344 return 0;
345}
346
347static int ves1x93_read_ber(struct dvb_frontend* fe, u32* ber)
348{
349 struct ves1x93_state* state = (struct ves1x93_state*) fe->demodulator_priv;
350
351 *ber = ves1x93_readreg (state, 0x15);
352 *ber |= (ves1x93_readreg (state, 0x16) << 8);
353 *ber |= ((ves1x93_readreg (state, 0x17) & 0x0F) << 16);
354 *ber *= 10;
355
356 return 0;
357}
358
359static int ves1x93_read_signal_strength(struct dvb_frontend* fe, u16* strength)
360{
361 struct ves1x93_state* state = (struct ves1x93_state*) fe->demodulator_priv;
362
363 u8 signal = ~ves1x93_readreg (state, 0x0b);
364 *strength = (signal << 8) | signal;
365
366 return 0;
367}
368
369static int ves1x93_read_snr(struct dvb_frontend* fe, u16* snr)
370{
371 struct ves1x93_state* state = (struct ves1x93_state*) fe->demodulator_priv;
372
373 u8 _snr = ~ves1x93_readreg (state, 0x1c);
374 *snr = (_snr << 8) | _snr;
375
376 return 0;
377}
378
379static int ves1x93_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
380{
381 struct ves1x93_state* state = (struct ves1x93_state*) fe->demodulator_priv;
382
383 *ucblocks = ves1x93_readreg (state, 0x18) & 0x7f;
384
385 if (*ucblocks == 0x7f)
386 *ucblocks = 0xffffffff; /* counter overflow... */
387
388 ves1x93_writereg (state, 0x18, 0x00); /* reset the counter */
389 ves1x93_writereg (state, 0x18, 0x80); /* dto. */
390
391 return 0;
392}
393
394static int ves1x93_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
395{
396 struct ves1x93_state* state = (struct ves1x93_state*) fe->demodulator_priv;
397
398 ves1x93_writereg(state, 0x00, 0x11);
399 state->config->pll_set(fe, p);
400 ves1x93_writereg(state, 0x00, 0x01);
401 ves1x93_set_inversion (state, p->inversion);
402 ves1x93_set_fec (state, p->u.qpsk.fec_inner);
403 ves1x93_set_symbolrate (state, p->u.qpsk.symbol_rate);
404 state->inversion = p->inversion;
405
406 return 0;
407}
408
409static int ves1x93_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
410{
411 struct ves1x93_state* state = (struct ves1x93_state*) fe->demodulator_priv;
412 int afc;
413
414 afc = ((int)((char)(ves1x93_readreg (state, 0x0a) << 1)))/2;
415 afc = (afc * (int)(p->u.qpsk.symbol_rate/1000/8))/16;
416
417 p->frequency -= afc;
418
419 /*
420 * inversion indicator is only valid
421 * if auto inversion was used
422 */
423 if (state->inversion == INVERSION_AUTO)
424 p->inversion = (ves1x93_readreg (state, 0x0f) & 2) ?
425 INVERSION_OFF : INVERSION_ON;
426 p->u.qpsk.fec_inner = ves1x93_get_fec (state);
427 /* XXX FIXME: timing offset !! */
428
429 return 0;
430}
431
432static int ves1x93_sleep(struct dvb_frontend* fe)
433{
434 struct ves1x93_state* state = (struct ves1x93_state*) fe->demodulator_priv;
435
436 return ves1x93_writereg (state, 0x00, 0x08);
437}
438
439static void ves1x93_release(struct dvb_frontend* fe)
440{
441 struct ves1x93_state* state = (struct ves1x93_state*) fe->demodulator_priv;
442 kfree(state);
443}
444
445static struct dvb_frontend_ops ves1x93_ops;
446
447struct dvb_frontend* ves1x93_attach(const struct ves1x93_config* config,
448 struct i2c_adapter* i2c)
449{
450 struct ves1x93_state* state = NULL;
451 u8 identity;
452
453 /* allocate memory for the internal state */
454 state = (struct ves1x93_state*) kmalloc(sizeof(struct ves1x93_state), GFP_KERNEL);
455 if (state == NULL) goto error;
456
457 /* setup the state */
458 state->config = config;
459 state->i2c = i2c;
460 memcpy(&state->ops, &ves1x93_ops, sizeof(struct dvb_frontend_ops));
461 state->inversion = INVERSION_OFF;
462
463 /* check if the demod is there + identify it */
464 identity = ves1x93_readreg(state, 0x1e);
465 switch (identity) {
466 case 0xdc: /* VES1893A rev1 */
467 printk("ves1x93: Detected ves1893a rev1\n");
468 state->demod_type = DEMOD_VES1893;
469 state->init_1x93_tab = init_1893_tab;
470 state->init_1x93_wtab = init_1893_wtab;
471 state->tab_size = sizeof(init_1893_tab);
472 break;
473
474 case 0xdd: /* VES1893A rev2 */
475 printk("ves1x93: Detected ves1893a rev2\n");
476 state->demod_type = DEMOD_VES1893;
477 state->init_1x93_tab = init_1893_tab;
478 state->init_1x93_wtab = init_1893_wtab;
479 state->tab_size = sizeof(init_1893_tab);
480 break;
481
482 case 0xde: /* VES1993 */
483 printk("ves1x93: Detected ves1993\n");
484 state->demod_type = DEMOD_VES1993;
485 state->init_1x93_tab = init_1993_tab;
486 state->init_1x93_wtab = init_1993_wtab;
487 state->tab_size = sizeof(init_1993_tab);
488 break;
489
490 default:
491 goto error;
492 }
493
494 /* create dvb_frontend */
495 state->frontend.ops = &state->ops;
496 state->frontend.demodulator_priv = state;
497 return &state->frontend;
498
499error:
500 kfree(state);
501 return NULL;
502}
503
504static struct dvb_frontend_ops ves1x93_ops = {
505
506 .info = {
507 .name = "VLSI VES1x93 DVB-S",
508 .type = FE_QPSK,
509 .frequency_min = 950000,
510 .frequency_max = 2150000,
511 .frequency_stepsize = 125, /* kHz for QPSK frontends */
512 .frequency_tolerance = 29500,
513 .symbol_rate_min = 1000000,
514 .symbol_rate_max = 45000000,
515 /* .symbol_rate_tolerance = ???,*/
516 .caps = FE_CAN_INVERSION_AUTO |
517 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
518 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
519 FE_CAN_QPSK
520 },
521
522 .release = ves1x93_release,
523
524 .init = ves1x93_init,
525 .sleep = ves1x93_sleep,
526
527 .set_frontend = ves1x93_set_frontend,
528 .get_frontend = ves1x93_get_frontend,
529
530 .read_status = ves1x93_read_status,
531 .read_ber = ves1x93_read_ber,
532 .read_signal_strength = ves1x93_read_signal_strength,
533 .read_snr = ves1x93_read_snr,
534 .read_ucblocks = ves1x93_read_ucblocks,
535
536 .set_voltage = ves1x93_set_voltage,
537};
538
539module_param(debug, int, 0644);
540
541MODULE_DESCRIPTION("VLSI VES1x93 DVB-S Demodulator driver");
542MODULE_AUTHOR("Ralph Metzler");
543MODULE_LICENSE("GPL");
544
545EXPORT_SYMBOL(ves1x93_attach);
diff --git a/drivers/media/dvb/frontends/ves1x93.h b/drivers/media/dvb/frontends/ves1x93.h
new file mode 100644
index 000000000000..1627e37c57a4
--- /dev/null
+++ b/drivers/media/dvb/frontends/ves1x93.h
@@ -0,0 +1,50 @@
1/*
2 Driver for VES1893 and VES1993 QPSK Demodulators
3
4 Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de>
5 Copyright (C) 2001 Ronny Strutz <3des@elitedvb.de>
6 Copyright (C) 2002 Dennis Noermann <dennis.noermann@noernet.de>
7 Copyright (C) 2002-2003 Andreas Oberritter <obi@linuxtv.org>
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
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., 675 Mass Ave, Cambridge, MA 02139, USA.
23
24*/
25
26#ifndef VES1X93_H
27#define VES1X93_H
28
29#include <linux/dvb/frontend.h>
30
31struct ves1x93_config
32{
33 /* the demodulator's i2c address */
34 u8 demod_address;
35
36 /* value of XIN to use */
37 u32 xin;
38
39 /* should PWM be inverted? */
40 u8 invert_pwm:1;
41
42 /* PLL maintenance */
43 int (*pll_init)(struct dvb_frontend* fe);
44 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
45};
46
47extern struct dvb_frontend* ves1x93_attach(const struct ves1x93_config* config,
48 struct i2c_adapter* i2c);
49
50#endif // VES1X93_H
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
diff --git a/drivers/media/dvb/ttusb-budget/Kconfig b/drivers/media/dvb/ttusb-budget/Kconfig
new file mode 100644
index 000000000000..4aa714ab4c28
--- /dev/null
+++ b/drivers/media/dvb/ttusb-budget/Kconfig
@@ -0,0 +1,15 @@
1config DVB_TTUSB_BUDGET
2 tristate "Technotrend/Hauppauge Nova-USB devices"
3 depends on DVB_CORE && USB
4 select DVB_CX22700
5 select DVB_TDA1004X
6 select DVB_TDA8083
7 select DVB_STV0299
8 help
9 Support for external USB adapters designed by Technotrend and
10 produced by Hauppauge, shipped under the brand name 'Nova-USB'.
11
12 These devices don't have a MPEG decoder built in, so you need
13 an external software decoder to watch TV.
14
15 Say Y if you own such a device and want to use it.
diff --git a/drivers/media/dvb/ttusb-budget/Makefile b/drivers/media/dvb/ttusb-budget/Makefile
new file mode 100644
index 000000000000..6ab97f6b53fc
--- /dev/null
+++ b/drivers/media/dvb/ttusb-budget/Makefile
@@ -0,0 +1,3 @@
1obj-$(CONFIG_DVB_TTUSB_BUDGET) += dvb-ttusb-budget.o
2
3EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends
diff --git a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
new file mode 100644
index 000000000000..4c046ece883a
--- /dev/null
+++ b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
@@ -0,0 +1,1610 @@
1/*
2 * TTUSB DVB driver
3 *
4 * Copyright (c) 2002 Holger Waechtler <holger@convergence.de>
5 * Copyright (c) 2003 Felix Domke <tmbinc@elitedvb.net>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of
10 * the License, or (at your option) any later version.
11 */
12#include <linux/init.h>
13#include <linux/slab.h>
14#include <linux/wait.h>
15#include <linux/module.h>
16#include <linux/moduleparam.h>
17#include <linux/usb.h>
18#include <linux/delay.h>
19#include <linux/time.h>
20#include <linux/errno.h>
21#include <asm/semaphore.h>
22
23#include "dvb_frontend.h"
24#include "dmxdev.h"
25#include "dvb_demux.h"
26#include "dvb_net.h"
27#include "cx22700.h"
28#include "tda1004x.h"
29#include "stv0299.h"
30#include "tda8083.h"
31
32#include <linux/dvb/frontend.h>
33#include <linux/dvb/dmx.h>
34#include <linux/pci.h>
35
36
37/*
38 TTUSB_HWSECTIONS:
39 the DSP supports filtering in hardware, however, since the "muxstream"
40 is a bit braindead (no matching channel masks or no matching filter mask),
41 we won't support this - yet. it doesn't event support negative filters,
42 so the best way is maybe to keep TTUSB_HWSECTIONS undef'd and just
43 parse TS data. USB bandwith will be a problem when having large
44 datastreams, especially for dvb-net, but hey, that's not my problem.
45
46 TTUSB_DISEQC, TTUSB_TONE:
47 let the STC do the diseqc/tone stuff. this isn't supported at least with
48 my TTUSB, so let it undef'd unless you want to implement another
49 frontend. never tested.
50
51 DEBUG:
52 define it to > 3 for really hardcore debugging. you probably don't want
53 this unless the device doesn't load at all. > 2 for bandwidth statistics.
54*/
55
56static int debug;
57
58module_param(debug, int, 0644);
59MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
60
61#define dprintk(x...) do { if (debug) printk(KERN_DEBUG x); } while (0)
62
63#define ISO_BUF_COUNT 4
64#define FRAMES_PER_ISO_BUF 4
65#define ISO_FRAME_SIZE 912
66#define TTUSB_MAXCHANNEL 32
67#ifdef TTUSB_HWSECTIONS
68#define TTUSB_MAXFILTER 16 /* ??? */
69#endif
70
71#define TTUSB_REV_2_2 0x22
72#define TTUSB_BUDGET_NAME "ttusb_stc_fw"
73
74/**
75 * since we're casting (struct ttusb*) <-> (struct dvb_demux*) around
76 * the dvb_demux field must be the first in struct!!
77 */
78struct ttusb {
79 struct dvb_demux dvb_demux;
80 struct dmxdev dmxdev;
81 struct dvb_net dvbnet;
82
83 /* and one for USB access. */
84 struct semaphore semi2c;
85 struct semaphore semusb;
86
87 struct dvb_adapter *adapter;
88 struct usb_device *dev;
89
90 struct i2c_adapter i2c_adap;
91
92 int disconnecting;
93 int iso_streaming;
94
95 unsigned int bulk_out_pipe;
96 unsigned int bulk_in_pipe;
97 unsigned int isoc_in_pipe;
98
99 void *iso_buffer;
100 dma_addr_t iso_dma_handle;
101
102 struct urb *iso_urb[ISO_BUF_COUNT];
103
104 int running_feed_count;
105 int last_channel;
106 int last_filter;
107
108 u8 c; /* transaction counter, wraps around... */
109 fe_sec_tone_mode_t tone;
110 fe_sec_voltage_t voltage;
111
112 int mux_state; // 0..2 - MuxSyncWord, 3 - nMuxPacks, 4 - muxpack
113 u8 mux_npacks;
114 u8 muxpack[256 + 8];
115 int muxpack_ptr, muxpack_len;
116
117 int insync;
118
119 int cc; /* MuxCounter - will increment on EVERY MUX PACKET */
120 /* (including stuffing. yes. really.) */
121
122 u8 last_result[32];
123
124 int revision;
125
126#if 0
127 devfs_handle_t stc_devfs_handle;
128#endif
129
130 struct dvb_frontend* fe;
131};
132
133/* ugly workaround ... don't know why it's neccessary to read */
134/* all result codes. */
135
136#define DEBUG 0
137static int ttusb_cmd(struct ttusb *ttusb,
138 const u8 * data, int len, int needresult)
139{
140 int actual_len;
141 int err;
142#if DEBUG >= 3
143 int i;
144
145 printk(">");
146 for (i = 0; i < len; ++i)
147 printk(" %02x", data[i]);
148 printk("\n");
149#endif
150
151 if (down_interruptible(&ttusb->semusb) < 0)
152 return -EAGAIN;
153
154 err = usb_bulk_msg(ttusb->dev, ttusb->bulk_out_pipe,
155 (u8 *) data, len, &actual_len, 1000);
156 if (err != 0) {
157 dprintk("%s: usb_bulk_msg(send) failed, err == %i!\n",
158 __FUNCTION__, err);
159 up(&ttusb->semusb);
160 return err;
161 }
162 if (actual_len != len) {
163 dprintk("%s: only wrote %d of %d bytes\n", __FUNCTION__,
164 actual_len, len);
165 up(&ttusb->semusb);
166 return -1;
167 }
168
169 err = usb_bulk_msg(ttusb->dev, ttusb->bulk_in_pipe,
170 ttusb->last_result, 32, &actual_len, 1000);
171
172 if (err != 0) {
173 printk("%s: failed, receive error %d\n", __FUNCTION__,
174 err);
175 up(&ttusb->semusb);
176 return err;
177 }
178#if DEBUG >= 3
179 actual_len = ttusb->last_result[3] + 4;
180 printk("<");
181 for (i = 0; i < actual_len; ++i)
182 printk(" %02x", ttusb->last_result[i]);
183 printk("\n");
184#endif
185 if (!needresult)
186 up(&ttusb->semusb);
187 return 0;
188}
189
190static int ttusb_result(struct ttusb *ttusb, u8 * data, int len)
191{
192 memcpy(data, ttusb->last_result, len);
193 up(&ttusb->semusb);
194 return 0;
195}
196
197static int ttusb_i2c_msg(struct ttusb *ttusb,
198 u8 addr, u8 * snd_buf, u8 snd_len, u8 * rcv_buf,
199 u8 rcv_len)
200{
201 u8 b[0x28];
202 u8 id = ++ttusb->c;
203 int i, err;
204
205 if (snd_len > 0x28 - 7 || rcv_len > 0x20 - 7)
206 return -EINVAL;
207
208 b[0] = 0xaa;
209 b[1] = id;
210 b[2] = 0x31;
211 b[3] = snd_len + 3;
212 b[4] = addr << 1;
213 b[5] = snd_len;
214 b[6] = rcv_len;
215
216 for (i = 0; i < snd_len; i++)
217 b[7 + i] = snd_buf[i];
218
219 err = ttusb_cmd(ttusb, b, snd_len + 7, 1);
220
221 if (err)
222 return -EREMOTEIO;
223
224 err = ttusb_result(ttusb, b, 0x20);
225
226 /* check if the i2c transaction was successful */
227 if ((snd_len != b[5]) || (rcv_len != b[6])) return -EREMOTEIO;
228
229 if (rcv_len > 0) {
230
231 if (err || b[0] != 0x55 || b[1] != id) {
232 dprintk
233 ("%s: usb_bulk_msg(recv) failed, err == %i, id == %02x, b == ",
234 __FUNCTION__, err, id);
235 return -EREMOTEIO;
236 }
237
238 for (i = 0; i < rcv_len; i++)
239 rcv_buf[i] = b[7 + i];
240 }
241
242 return rcv_len;
243}
244
245static int master_xfer(struct i2c_adapter* adapter, struct i2c_msg *msg, int num)
246{
247 struct ttusb *ttusb = i2c_get_adapdata(adapter);
248 int i = 0;
249 int inc;
250
251 if (down_interruptible(&ttusb->semi2c) < 0)
252 return -EAGAIN;
253
254 while (i < num) {
255 u8 addr, snd_len, rcv_len, *snd_buf, *rcv_buf;
256 int err;
257
258 if (num > i + 1 && (msg[i + 1].flags & I2C_M_RD)) {
259 addr = msg[i].addr;
260 snd_buf = msg[i].buf;
261 snd_len = msg[i].len;
262 rcv_buf = msg[i + 1].buf;
263 rcv_len = msg[i + 1].len;
264 inc = 2;
265 } else {
266 addr = msg[i].addr;
267 snd_buf = msg[i].buf;
268 snd_len = msg[i].len;
269 rcv_buf = NULL;
270 rcv_len = 0;
271 inc = 1;
272 }
273
274 err = ttusb_i2c_msg(ttusb, addr,
275 snd_buf, snd_len, rcv_buf, rcv_len);
276
277 if (err < rcv_len) {
278 dprintk("%s: i == %i\n", __FUNCTION__, i);
279 break;
280 }
281
282 i += inc;
283 }
284
285 up(&ttusb->semi2c);
286 return i;
287}
288
289#include "dvb-ttusb-dspbootcode.h"
290
291static int ttusb_boot_dsp(struct ttusb *ttusb)
292{
293 int i, err;
294 u8 b[40];
295
296 /* BootBlock */
297 b[0] = 0xaa;
298 b[2] = 0x13;
299 b[3] = 28;
300
301 /* upload dsp code in 32 byte steps (36 didn't work for me ...) */
302 /* 32 is max packet size, no messages should be splitted. */
303 for (i = 0; i < sizeof(dsp_bootcode); i += 28) {
304 memcpy(&b[4], &dsp_bootcode[i], 28);
305
306 b[1] = ++ttusb->c;
307
308 err = ttusb_cmd(ttusb, b, 32, 0);
309 if (err)
310 goto done;
311 }
312
313 /* last block ... */
314 b[1] = ++ttusb->c;
315 b[2] = 0x13;
316 b[3] = 0;
317
318 err = ttusb_cmd(ttusb, b, 4, 0);
319 if (err)
320 goto done;
321
322 /* BootEnd */
323 b[1] = ++ttusb->c;
324 b[2] = 0x14;
325 b[3] = 0;
326
327 err = ttusb_cmd(ttusb, b, 4, 0);
328
329 done:
330 if (err) {
331 dprintk("%s: usb_bulk_msg() failed, return value %i!\n",
332 __FUNCTION__, err);
333 }
334
335 return err;
336}
337
338static int ttusb_set_channel(struct ttusb *ttusb, int chan_id, int filter_type,
339 int pid)
340{
341 int err;
342 /* SetChannel */
343 u8 b[] = { 0xaa, ++ttusb->c, 0x22, 4, chan_id, filter_type,
344 (pid >> 8) & 0xff, pid & 0xff
345 };
346
347 err = ttusb_cmd(ttusb, b, sizeof(b), 0);
348 return err;
349}
350
351static int ttusb_del_channel(struct ttusb *ttusb, int channel_id)
352{
353 int err;
354 /* DelChannel */
355 u8 b[] = { 0xaa, ++ttusb->c, 0x23, 1, channel_id };
356
357 err = ttusb_cmd(ttusb, b, sizeof(b), 0);
358 return err;
359}
360
361#ifdef TTUSB_HWSECTIONS
362static int ttusb_set_filter(struct ttusb *ttusb, int filter_id,
363 int associated_chan, u8 filter[8], u8 mask[8])
364{
365 int err;
366 /* SetFilter */
367 u8 b[] = { 0xaa, 0, 0x24, 0x1a, filter_id, associated_chan,
368 filter[0], filter[1], filter[2], filter[3],
369 filter[4], filter[5], filter[6], filter[7],
370 filter[8], filter[9], filter[10], filter[11],
371 mask[0], mask[1], mask[2], mask[3],
372 mask[4], mask[5], mask[6], mask[7],
373 mask[8], mask[9], mask[10], mask[11]
374 };
375
376 err = ttusb_cmd(ttusb, b, sizeof(b), 0);
377 return err;
378}
379
380static int ttusb_del_filter(struct ttusb *ttusb, int filter_id)
381{
382 int err;
383 /* DelFilter */
384 u8 b[] = { 0xaa, ++ttusb->c, 0x25, 1, filter_id };
385
386 err = ttusb_cmd(ttusb, b, sizeof(b), 0);
387 return err;
388}
389#endif
390
391static int ttusb_init_controller(struct ttusb *ttusb)
392{
393 u8 b0[] = { 0xaa, ++ttusb->c, 0x15, 1, 0 };
394 u8 b1[] = { 0xaa, ++ttusb->c, 0x15, 1, 1 };
395 u8 b2[] = { 0xaa, ++ttusb->c, 0x32, 1, 0 };
396 /* i2c write read: 5 bytes, addr 0x10, 0x02 bytes write, 1 bytes read. */
397 u8 b3[] =
398 { 0xaa, ++ttusb->c, 0x31, 5, 0x10, 0x02, 0x01, 0x00, 0x1e };
399 u8 b4[] =
400 { 0x55, ttusb->c, 0x31, 4, 0x10, 0x02, 0x01, 0x00, 0x1e };
401
402 u8 get_version[] = { 0xaa, ++ttusb->c, 0x17, 5, 0, 0, 0, 0, 0 };
403 u8 get_dsp_version[0x20] =
404 { 0xaa, ++ttusb->c, 0x26, 28, 0, 0, 0, 0, 0 };
405 int err;
406
407 /* reset board */
408 if ((err = ttusb_cmd(ttusb, b0, sizeof(b0), 0)))
409 return err;
410
411 /* reset board (again?) */
412 if ((err = ttusb_cmd(ttusb, b1, sizeof(b1), 0)))
413 return err;
414
415 ttusb_boot_dsp(ttusb);
416
417 /* set i2c bit rate */
418 if ((err = ttusb_cmd(ttusb, b2, sizeof(b2), 0)))
419 return err;
420
421 if ((err = ttusb_cmd(ttusb, b3, sizeof(b3), 1)))
422 return err;
423
424 err = ttusb_result(ttusb, b4, sizeof(b4));
425
426 if ((err = ttusb_cmd(ttusb, get_version, sizeof(get_version), 1)))
427 return err;
428
429 if ((err = ttusb_result(ttusb, get_version, sizeof(get_version))))
430 return err;
431
432 dprintk("%s: stc-version: %c%c%c%c%c\n", __FUNCTION__,
433 get_version[4], get_version[5], get_version[6],
434 get_version[7], get_version[8]);
435
436 if (memcmp(get_version + 4, "V 0.0", 5) &&
437 memcmp(get_version + 4, "V 1.1", 5) &&
438 memcmp(get_version + 4, "V 2.1", 5) &&
439 memcmp(get_version + 4, "V 2.2", 5)) {
440 printk
441 ("%s: unknown STC version %c%c%c%c%c, please report!\n",
442 __FUNCTION__, get_version[4], get_version[5],
443 get_version[6], get_version[7], get_version[8]);
444 }
445
446 ttusb->revision = ((get_version[6] - '0') << 4) |
447 (get_version[8] - '0');
448
449 err =
450 ttusb_cmd(ttusb, get_dsp_version, sizeof(get_dsp_version), 1);
451 if (err)
452 return err;
453
454 err =
455 ttusb_result(ttusb, get_dsp_version, sizeof(get_dsp_version));
456 if (err)
457 return err;
458 printk("%s: dsp-version: %c%c%c\n", __FUNCTION__,
459 get_dsp_version[4], get_dsp_version[5], get_dsp_version[6]);
460 return 0;
461}
462
463#ifdef TTUSB_DISEQC
464static int ttusb_send_diseqc(struct dvb_frontend* fe,
465 const struct dvb_diseqc_master_cmd *cmd)
466{
467 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
468 u8 b[12] = { 0xaa, ++ttusb->c, 0x18 };
469
470 int err;
471
472 b[3] = 4 + 2 + cmd->msg_len;
473 b[4] = 0xFF; /* send diseqc master, not burst */
474 b[5] = cmd->msg_len;
475
476 memcpy(b + 5, cmd->msg, cmd->msg_len);
477
478 /* Diseqc */
479 if ((err = ttusb_cmd(ttusb, b, 4 + b[3], 0))) {
480 dprintk("%s: usb_bulk_msg() failed, return value %i!\n",
481 __FUNCTION__, err);
482 }
483
484 return err;
485}
486#endif
487
488static int lnbp21_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
489{
490 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
491 int ret;
492 u8 data[1];
493 struct i2c_msg msg = { .addr = 0x08, .flags = 0, .buf = data, .len = sizeof(data) };
494
495 switch(voltage) {
496 case SEC_VOLTAGE_OFF:
497 data[0] = 0x00;
498 break;
499 case SEC_VOLTAGE_13:
500 data[0] = 0x44;
501 break;
502 case SEC_VOLTAGE_18:
503 data[0] = 0x4c;
504 break;
505 default:
506 return -EINVAL;
507 };
508
509 ret = i2c_transfer(&ttusb->i2c_adap, &msg, 1);
510 return (ret != 1) ? -EIO : 0;
511}
512
513static int ttusb_update_lnb(struct ttusb *ttusb)
514{
515 u8 b[] = { 0xaa, ++ttusb->c, 0x16, 5, /*power: */ 1,
516 ttusb->voltage == SEC_VOLTAGE_18 ? 0 : 1,
517 ttusb->tone == SEC_TONE_ON ? 1 : 0, 1, 1
518 };
519 int err;
520
521 /* SetLNB */
522 if ((err = ttusb_cmd(ttusb, b, sizeof(b), 0))) {
523 dprintk("%s: usb_bulk_msg() failed, return value %i!\n",
524 __FUNCTION__, err);
525 }
526
527 return err;
528}
529
530static int ttusb_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
531{
532 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
533
534 ttusb->voltage = voltage;
535 return ttusb_update_lnb(ttusb);
536}
537
538#ifdef TTUSB_TONE
539static int ttusb_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
540{
541 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
542
543 ttusb->tone = tone;
544 return ttusb_update_lnb(ttusb);
545}
546#endif
547
548
549#if 0
550static void ttusb_set_led_freq(struct ttusb *ttusb, u8 freq)
551{
552 u8 b[] = { 0xaa, ++ttusb->c, 0x19, 1, freq };
553 int err, actual_len;
554
555 err = ttusb_cmd(ttusb, b, sizeof(b), 0);
556 if (err) {
557 dprintk("%s: usb_bulk_msg() failed, return value %i!\n",
558 __FUNCTION__, err);
559 }
560}
561#endif
562
563/*****************************************************************************/
564
565#ifdef TTUSB_HWSECTIONS
566static void ttusb_handle_ts_data(struct ttusb_channel *channel,
567 const u8 * data, int len);
568static void ttusb_handle_sec_data(struct ttusb_channel *channel,
569 const u8 * data, int len);
570#endif
571
572static int numpkt = 0, lastj, numts, numstuff, numsec, numinvalid;
573
574static void ttusb_process_muxpack(struct ttusb *ttusb, const u8 * muxpack,
575 int len)
576{
577 u16 csum = 0, cc;
578 int i;
579 for (i = 0; i < len; i += 2)
580 csum ^= le16_to_cpup((u16 *) (muxpack + i));
581 if (csum) {
582 printk("%s: muxpack with incorrect checksum, ignoring\n",
583 __FUNCTION__);
584 numinvalid++;
585 return;
586 }
587
588 cc = (muxpack[len - 4] << 8) | muxpack[len - 3];
589 cc &= 0x7FFF;
590 if ((cc != ttusb->cc) && (ttusb->cc != -1))
591 printk("%s: cc discontinuity (%d frames missing)\n",
592 __FUNCTION__, (cc - ttusb->cc) & 0x7FFF);
593 ttusb->cc = (cc + 1) & 0x7FFF;
594 if (muxpack[0] & 0x80) {
595#ifdef TTUSB_HWSECTIONS
596 /* section data */
597 int pusi = muxpack[0] & 0x40;
598 int channel = muxpack[0] & 0x1F;
599 int payload = muxpack[1];
600 const u8 *data = muxpack + 2;
601 /* check offset flag */
602 if (muxpack[0] & 0x20)
603 data++;
604
605 ttusb_handle_sec_data(ttusb->channel + channel, data,
606 payload);
607 data += payload;
608
609 if ((!!(ttusb->muxpack[0] & 0x20)) ^
610 !!(ttusb->muxpack[1] & 1))
611 data++;
612#warning TODO: pusi
613 printk("cc: %04x\n", (data[0] << 8) | data[1]);
614#endif
615 numsec++;
616 } else if (muxpack[0] == 0x47) {
617#ifdef TTUSB_HWSECTIONS
618 /* we have TS data here! */
619 int pid = ((muxpack[1] & 0x0F) << 8) | muxpack[2];
620 int channel;
621 for (channel = 0; channel < TTUSB_MAXCHANNEL; ++channel)
622 if (ttusb->channel[channel].active
623 && (pid == ttusb->channel[channel].pid))
624 ttusb_handle_ts_data(ttusb->channel +
625 channel, muxpack,
626 188);
627#endif
628 numts++;
629 dvb_dmx_swfilter_packets(&ttusb->dvb_demux, muxpack, 1);
630 } else if (muxpack[0] != 0) {
631 numinvalid++;
632 printk("illegal muxpack type %02x\n", muxpack[0]);
633 } else
634 numstuff++;
635}
636
637static void ttusb_process_frame(struct ttusb *ttusb, u8 * data, int len)
638{
639 int maxwork = 1024;
640 while (len) {
641 if (!(maxwork--)) {
642 printk("%s: too much work\n", __FUNCTION__);
643 break;
644 }
645
646 switch (ttusb->mux_state) {
647 case 0:
648 case 1:
649 case 2:
650 len--;
651 if (*data++ == 0xAA)
652 ++ttusb->mux_state;
653 else {
654 ttusb->mux_state = 0;
655#if DEBUG > 3
656 if (ttusb->insync)
657 printk("%02x ", data[-1]);
658#else
659 if (ttusb->insync) {
660 printk("%s: lost sync.\n",
661 __FUNCTION__);
662 ttusb->insync = 0;
663 }
664#endif
665 }
666 break;
667 case 3:
668 ttusb->insync = 1;
669 len--;
670 ttusb->mux_npacks = *data++;
671 ++ttusb->mux_state;
672 ttusb->muxpack_ptr = 0;
673 /* maximum bytes, until we know the length */
674 ttusb->muxpack_len = 2;
675 break;
676 case 4:
677 {
678 int avail;
679 avail = len;
680 if (avail >
681 (ttusb->muxpack_len -
682 ttusb->muxpack_ptr))
683 avail =
684 ttusb->muxpack_len -
685 ttusb->muxpack_ptr;
686 memcpy(ttusb->muxpack + ttusb->muxpack_ptr,
687 data, avail);
688 ttusb->muxpack_ptr += avail;
689 if (ttusb->muxpack_ptr > 264)
690 BUG();
691 data += avail;
692 len -= avail;
693 /* determine length */
694 if (ttusb->muxpack_ptr == 2) {
695 if (ttusb->muxpack[0] & 0x80) {
696 ttusb->muxpack_len =
697 ttusb->muxpack[1] + 2;
698 if (ttusb->
699 muxpack[0] & 0x20)
700 ttusb->
701 muxpack_len++;
702 if ((!!
703 (ttusb->
704 muxpack[0] & 0x20)) ^
705 !!(ttusb->
706 muxpack[1] & 1))
707 ttusb->
708 muxpack_len++;
709 ttusb->muxpack_len += 4;
710 } else if (ttusb->muxpack[0] ==
711 0x47)
712 ttusb->muxpack_len =
713 188 + 4;
714 else if (ttusb->muxpack[0] == 0x00)
715 ttusb->muxpack_len =
716 ttusb->muxpack[1] + 2 +
717 4;
718 else {
719 dprintk
720 ("%s: invalid state: first byte is %x\n",
721 __FUNCTION__,
722 ttusb->muxpack[0]);
723 ttusb->mux_state = 0;
724 }
725 }
726
727 /**
728 * if length is valid and we reached the end:
729 * goto next muxpack
730 */
731 if ((ttusb->muxpack_ptr >= 2) &&
732 (ttusb->muxpack_ptr ==
733 ttusb->muxpack_len)) {
734 ttusb_process_muxpack(ttusb,
735 ttusb->
736 muxpack,
737 ttusb->
738 muxpack_ptr);
739 ttusb->muxpack_ptr = 0;
740 /* maximum bytes, until we know the length */
741 ttusb->muxpack_len = 2;
742
743 /**
744 * no muxpacks left?
745 * return to search-sync state
746 */
747 if (!ttusb->mux_npacks--) {
748 ttusb->mux_state = 0;
749 break;
750 }
751 }
752 break;
753 }
754 default:
755 BUG();
756 break;
757 }
758 }
759}
760
761static void ttusb_iso_irq(struct urb *urb, struct pt_regs *ptregs)
762{
763 struct ttusb *ttusb = urb->context;
764
765 if (!ttusb->iso_streaming)
766 return;
767
768#if 0
769 printk("%s: status %d, errcount == %d, length == %i\n",
770 __FUNCTION__,
771 urb->status, urb->error_count, urb->actual_length);
772#endif
773
774 if (!urb->status) {
775 int i;
776 for (i = 0; i < urb->number_of_packets; ++i) {
777 struct usb_iso_packet_descriptor *d;
778 u8 *data;
779 int len;
780 numpkt++;
781 if ((jiffies - lastj) >= HZ) {
782#if DEBUG > 2
783 printk
784 ("frames/s: %d (ts: %d, stuff %d, sec: %d, invalid: %d, all: %d)\n",
785 numpkt * HZ / (jiffies - lastj),
786 numts, numstuff, numsec, numinvalid,
787 numts + numstuff + numsec +
788 numinvalid);
789#endif
790 numts = numstuff = numsec = numinvalid = 0;
791 lastj = jiffies;
792 numpkt = 0;
793 }
794 d = &urb->iso_frame_desc[i];
795 data = urb->transfer_buffer + d->offset;
796 len = d->actual_length;
797 d->actual_length = 0;
798 d->status = 0;
799 ttusb_process_frame(ttusb, data, len);
800 }
801 }
802 usb_submit_urb(urb, GFP_ATOMIC);
803}
804
805static void ttusb_free_iso_urbs(struct ttusb *ttusb)
806{
807 int i;
808
809 for (i = 0; i < ISO_BUF_COUNT; i++)
810 if (ttusb->iso_urb[i])
811 usb_free_urb(ttusb->iso_urb[i]);
812
813 pci_free_consistent(NULL,
814 ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF *
815 ISO_BUF_COUNT, ttusb->iso_buffer,
816 ttusb->iso_dma_handle);
817}
818
819static int ttusb_alloc_iso_urbs(struct ttusb *ttusb)
820{
821 int i;
822
823 ttusb->iso_buffer = pci_alloc_consistent(NULL,
824 ISO_FRAME_SIZE *
825 FRAMES_PER_ISO_BUF *
826 ISO_BUF_COUNT,
827 &ttusb->iso_dma_handle);
828
829 memset(ttusb->iso_buffer, 0,
830 ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF * ISO_BUF_COUNT);
831
832 for (i = 0; i < ISO_BUF_COUNT; i++) {
833 struct urb *urb;
834
835 if (!
836 (urb =
837 usb_alloc_urb(FRAMES_PER_ISO_BUF, GFP_ATOMIC))) {
838 ttusb_free_iso_urbs(ttusb);
839 return -ENOMEM;
840 }
841
842 ttusb->iso_urb[i] = urb;
843 }
844
845 return 0;
846}
847
848static void ttusb_stop_iso_xfer(struct ttusb *ttusb)
849{
850 int i;
851
852 for (i = 0; i < ISO_BUF_COUNT; i++)
853 usb_kill_urb(ttusb->iso_urb[i]);
854
855 ttusb->iso_streaming = 0;
856}
857
858static int ttusb_start_iso_xfer(struct ttusb *ttusb)
859{
860 int i, j, err, buffer_offset = 0;
861
862 if (ttusb->iso_streaming) {
863 printk("%s: iso xfer already running!\n", __FUNCTION__);
864 return 0;
865 }
866
867 ttusb->cc = -1;
868 ttusb->insync = 0;
869 ttusb->mux_state = 0;
870
871 for (i = 0; i < ISO_BUF_COUNT; i++) {
872 int frame_offset = 0;
873 struct urb *urb = ttusb->iso_urb[i];
874
875 urb->dev = ttusb->dev;
876 urb->context = ttusb;
877 urb->complete = ttusb_iso_irq;
878 urb->pipe = ttusb->isoc_in_pipe;
879 urb->transfer_flags = URB_ISO_ASAP;
880 urb->interval = 1;
881 urb->number_of_packets = FRAMES_PER_ISO_BUF;
882 urb->transfer_buffer_length =
883 ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF;
884 urb->transfer_buffer = ttusb->iso_buffer + buffer_offset;
885 buffer_offset += ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF;
886
887 for (j = 0; j < FRAMES_PER_ISO_BUF; j++) {
888 urb->iso_frame_desc[j].offset = frame_offset;
889 urb->iso_frame_desc[j].length = ISO_FRAME_SIZE;
890 frame_offset += ISO_FRAME_SIZE;
891 }
892 }
893
894 for (i = 0; i < ISO_BUF_COUNT; i++) {
895 if ((err = usb_submit_urb(ttusb->iso_urb[i], GFP_ATOMIC))) {
896 ttusb_stop_iso_xfer(ttusb);
897 printk
898 ("%s: failed urb submission (%i: err = %i)!\n",
899 __FUNCTION__, i, err);
900 return err;
901 }
902 }
903
904 ttusb->iso_streaming = 1;
905
906 return 0;
907}
908
909#ifdef TTUSB_HWSECTIONS
910static void ttusb_handle_ts_data(struct dvb_demux_feed *dvbdmxfeed, const u8 * data,
911 int len)
912{
913 dvbdmxfeed->cb.ts(data, len, 0, 0, &dvbdmxfeed->feed.ts, 0);
914}
915
916static void ttusb_handle_sec_data(struct dvb_demux_feed *dvbdmxfeed, const u8 * data,
917 int len)
918{
919// struct dvb_demux_feed *dvbdmxfeed = channel->dvbdmxfeed;
920#error TODO: handle ugly stuff
921// dvbdmxfeed->cb.sec(data, len, 0, 0, &dvbdmxfeed->feed.sec, 0);
922}
923#endif
924
925static int ttusb_start_feed(struct dvb_demux_feed *dvbdmxfeed)
926{
927 struct ttusb *ttusb = (struct ttusb *) dvbdmxfeed->demux;
928 int feed_type = 1;
929
930 dprintk("ttusb_start_feed\n");
931
932 switch (dvbdmxfeed->type) {
933 case DMX_TYPE_TS:
934 break;
935 case DMX_TYPE_SEC:
936 break;
937 default:
938 return -EINVAL;
939 }
940
941 if (dvbdmxfeed->type == DMX_TYPE_TS) {
942 switch (dvbdmxfeed->pes_type) {
943 case DMX_TS_PES_VIDEO:
944 case DMX_TS_PES_AUDIO:
945 case DMX_TS_PES_TELETEXT:
946 case DMX_TS_PES_PCR:
947 case DMX_TS_PES_OTHER:
948 break;
949 default:
950 return -EINVAL;
951 }
952 }
953
954#ifdef TTUSB_HWSECTIONS
955#error TODO: allocate filters
956 if (dvbdmxfeed->type == DMX_TYPE_TS) {
957 feed_type = 1;
958 } else if (dvbdmxfeed->type == DMX_TYPE_SEC) {
959 feed_type = 2;
960 }
961#endif
962
963 ttusb_set_channel(ttusb, dvbdmxfeed->index, feed_type, dvbdmxfeed->pid);
964
965 if (0 == ttusb->running_feed_count++)
966 ttusb_start_iso_xfer(ttusb);
967
968 return 0;
969}
970
971static int ttusb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
972{
973 struct ttusb *ttusb = (struct ttusb *) dvbdmxfeed->demux;
974
975 ttusb_del_channel(ttusb, dvbdmxfeed->index);
976
977 if (--ttusb->running_feed_count == 0)
978 ttusb_stop_iso_xfer(ttusb);
979
980 return 0;
981}
982
983static int ttusb_setup_interfaces(struct ttusb *ttusb)
984{
985 usb_set_interface(ttusb->dev, 1, 1);
986
987 ttusb->bulk_out_pipe = usb_sndbulkpipe(ttusb->dev, 1);
988 ttusb->bulk_in_pipe = usb_rcvbulkpipe(ttusb->dev, 1);
989 ttusb->isoc_in_pipe = usb_rcvisocpipe(ttusb->dev, 2);
990
991 return 0;
992}
993
994#if 0
995static u8 stc_firmware[8192];
996
997static int stc_open(struct inode *inode, struct file *file)
998{
999 struct ttusb *ttusb = file->private_data;
1000 int addr;
1001
1002 for (addr = 0; addr < 8192; addr += 16) {
1003 u8 snd_buf[2] = { addr >> 8, addr & 0xFF };
1004 ttusb_i2c_msg(ttusb, 0x50, snd_buf, 2, stc_firmware + addr,
1005 16);
1006 }
1007
1008 return 0;
1009}
1010
1011static ssize_t stc_read(struct file *file, char *buf, size_t count,
1012 loff_t * offset)
1013{
1014 int tc = count;
1015
1016 if ((tc + *offset) > 8192)
1017 tc = 8192 - *offset;
1018
1019 if (tc < 0)
1020 return 0;
1021
1022 if (copy_to_user(buf, stc_firmware + *offset, tc))
1023 return -EFAULT;
1024
1025 *offset += tc;
1026
1027 return tc;
1028}
1029
1030static int stc_release(struct inode *inode, struct file *file)
1031{
1032 return 0;
1033}
1034
1035static struct file_operations stc_fops = {
1036 .owner = THIS_MODULE,
1037 .read = stc_read,
1038 .open = stc_open,
1039 .release = stc_release,
1040};
1041#endif
1042
1043static u32 functionality(struct i2c_adapter *adapter)
1044{
1045 return I2C_FUNC_I2C;
1046}
1047
1048
1049
1050static int alps_tdmb7_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
1051{
1052 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
1053 u8 data[4];
1054 struct i2c_msg msg = {.addr=0x61, .flags=0, .buf=data, .len=sizeof(data) };
1055 u32 div;
1056
1057 div = (params->frequency + 36166667) / 166667;
1058
1059 data[0] = (div >> 8) & 0x7f;
1060 data[1] = div & 0xff;
1061 data[2] = ((div >> 10) & 0x60) | 0x85;
1062 data[3] = params->frequency < 592000000 ? 0x40 : 0x80;
1063
1064 if (i2c_transfer(&ttusb->i2c_adap, &msg, 1) != 1) return -EIO;
1065 return 0;
1066}
1067
1068struct cx22700_config alps_tdmb7_config = {
1069 .demod_address = 0x43,
1070 .pll_set = alps_tdmb7_pll_set,
1071};
1072
1073
1074
1075
1076
1077static int philips_tdm1316l_pll_init(struct dvb_frontend* fe)
1078{
1079 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
1080 static u8 td1316_init[] = { 0x0b, 0xf5, 0x85, 0xab };
1081 static u8 disable_mc44BC374c[] = { 0x1d, 0x74, 0xa0, 0x68 };
1082 struct i2c_msg tuner_msg = { .addr=0x60, .flags=0, .buf=td1316_init, .len=sizeof(td1316_init) };
1083
1084 // setup PLL configuration
1085 if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1) return -EIO;
1086 msleep(1);
1087
1088 // disable the mc44BC374c (do not check for errors)
1089 tuner_msg.addr = 0x65;
1090 tuner_msg.buf = disable_mc44BC374c;
1091 tuner_msg.len = sizeof(disable_mc44BC374c);
1092 if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1) {
1093 i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1);
1094 }
1095
1096 return 0;
1097}
1098
1099static int philips_tdm1316l_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
1100{
1101 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
1102 u8 tuner_buf[4];
1103 struct i2c_msg tuner_msg = {.addr=0x60, .flags=0, .buf=tuner_buf, .len=sizeof(tuner_buf) };
1104 int tuner_frequency = 0;
1105 u8 band, cp, filter;
1106
1107 // determine charge pump
1108 tuner_frequency = params->frequency + 36130000;
1109 if (tuner_frequency < 87000000) return -EINVAL;
1110 else if (tuner_frequency < 130000000) cp = 3;
1111 else if (tuner_frequency < 160000000) cp = 5;
1112 else if (tuner_frequency < 200000000) cp = 6;
1113 else if (tuner_frequency < 290000000) cp = 3;
1114 else if (tuner_frequency < 420000000) cp = 5;
1115 else if (tuner_frequency < 480000000) cp = 6;
1116 else if (tuner_frequency < 620000000) cp = 3;
1117 else if (tuner_frequency < 830000000) cp = 5;
1118 else if (tuner_frequency < 895000000) cp = 7;
1119 else return -EINVAL;
1120
1121 // determine band
1122 if (params->frequency < 49000000) return -EINVAL;
1123 else if (params->frequency < 159000000) band = 1;
1124 else if (params->frequency < 444000000) band = 2;
1125 else if (params->frequency < 861000000) band = 4;
1126 else return -EINVAL;
1127
1128 // setup PLL filter
1129 switch (params->u.ofdm.bandwidth) {
1130 case BANDWIDTH_6_MHZ:
1131 tda1004x_write_byte(fe, 0x0C, 0);
1132 filter = 0;
1133 break;
1134
1135 case BANDWIDTH_7_MHZ:
1136 tda1004x_write_byte(fe, 0x0C, 0);
1137 filter = 0;
1138 break;
1139
1140 case BANDWIDTH_8_MHZ:
1141 tda1004x_write_byte(fe, 0x0C, 0xFF);
1142 filter = 1;
1143 break;
1144
1145 default:
1146 return -EINVAL;
1147 }
1148
1149 // calculate divisor
1150 // ((36130000+((1000000/6)/2)) + Finput)/(1000000/6)
1151 tuner_frequency = (((params->frequency / 1000) * 6) + 217280) / 1000;
1152
1153 // setup tuner buffer
1154 tuner_buf[0] = tuner_frequency >> 8;
1155 tuner_buf[1] = tuner_frequency & 0xff;
1156 tuner_buf[2] = 0xca;
1157 tuner_buf[3] = (cp << 5) | (filter << 3) | band;
1158
1159 if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1)
1160 return -EIO;
1161
1162 msleep(1);
1163 return 0;
1164}
1165
1166static int philips_tdm1316l_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name)
1167{
1168 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
1169
1170 return request_firmware(fw, name, &ttusb->dev->dev);
1171}
1172
1173static struct tda1004x_config philips_tdm1316l_config = {
1174
1175 .demod_address = 0x8,
1176 .invert = 1,
1177 .invert_oclk = 0,
1178 .pll_init = philips_tdm1316l_pll_init,
1179 .pll_set = philips_tdm1316l_pll_set,
1180 .request_firmware = philips_tdm1316l_request_firmware,
1181};
1182
1183static u8 alps_bsbe1_inittab[] = {
1184 0x01, 0x15,
1185 0x02, 0x30,
1186 0x03, 0x00,
1187 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
1188 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */
1189 0x06, 0x40, /* DAC not used, set to high impendance mode */
1190 0x07, 0x00, /* DAC LSB */
1191 0x08, 0x40, /* DiSEqC off, LNB power on OP2/LOCK pin on */
1192 0x09, 0x00, /* FIFO */
1193 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
1194 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */
1195 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
1196 0x10, 0x3f, // AGC2 0x3d
1197 0x11, 0x84,
1198 0x12, 0xb5, // Lock detect: -64 Carrier freq detect:on
1199 0x15, 0xc9, // lock detector threshold
1200 0x16, 0x00,
1201 0x17, 0x00,
1202 0x18, 0x00,
1203 0x19, 0x00,
1204 0x1a, 0x00,
1205 0x1f, 0x50,
1206 0x20, 0x00,
1207 0x21, 0x00,
1208 0x22, 0x00,
1209 0x23, 0x00,
1210 0x28, 0x00, // out imp: normal out type: parallel FEC mode:0
1211 0x29, 0x1e, // 1/2 threshold
1212 0x2a, 0x14, // 2/3 threshold
1213 0x2b, 0x0f, // 3/4 threshold
1214 0x2c, 0x09, // 5/6 threshold
1215 0x2d, 0x05, // 7/8 threshold
1216 0x2e, 0x01,
1217 0x31, 0x1f, // test all FECs
1218 0x32, 0x19, // viterbi and synchro search
1219 0x33, 0xfc, // rs control
1220 0x34, 0x93, // error control
1221 0x0f, 0x92,
1222 0xff, 0xff
1223};
1224
1225static u8 alps_bsru6_inittab[] = {
1226 0x01, 0x15,
1227 0x02, 0x30,
1228 0x03, 0x00,
1229 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
1230 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */
1231 0x06, 0x40, /* DAC not used, set to high impendance mode */
1232 0x07, 0x00, /* DAC LSB */
1233 0x08, 0x40, /* DiSEqC off, LNB power on OP2/LOCK pin on */
1234 0x09, 0x00, /* FIFO */
1235 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
1236 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */
1237 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
1238 0x10, 0x3f, // AGC2 0x3d
1239 0x11, 0x84,
1240 0x12, 0xb5, // Lock detect: -64 Carrier freq detect:on
1241 0x15, 0xc9, // lock detector threshold
1242 0x16, 0x00,
1243 0x17, 0x00,
1244 0x18, 0x00,
1245 0x19, 0x00,
1246 0x1a, 0x00,
1247 0x1f, 0x50,
1248 0x20, 0x00,
1249 0x21, 0x00,
1250 0x22, 0x00,
1251 0x23, 0x00,
1252 0x28, 0x00, // out imp: normal out type: parallel FEC mode:0
1253 0x29, 0x1e, // 1/2 threshold
1254 0x2a, 0x14, // 2/3 threshold
1255 0x2b, 0x0f, // 3/4 threshold
1256 0x2c, 0x09, // 5/6 threshold
1257 0x2d, 0x05, // 7/8 threshold
1258 0x2e, 0x01,
1259 0x31, 0x1f, // test all FECs
1260 0x32, 0x19, // viterbi and synchro search
1261 0x33, 0xfc, // rs control
1262 0x34, 0x93, // error control
1263 0x0f, 0x52,
1264 0xff, 0xff
1265};
1266
1267static int alps_stv0299_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32 ratio)
1268{
1269 u8 aclk = 0;
1270 u8 bclk = 0;
1271
1272 if (srate < 1500000) {
1273 aclk = 0xb7;
1274 bclk = 0x47;
1275 } else if (srate < 3000000) {
1276 aclk = 0xb7;
1277 bclk = 0x4b;
1278 } else if (srate < 7000000) {
1279 aclk = 0xb7;
1280 bclk = 0x4f;
1281 } else if (srate < 14000000) {
1282 aclk = 0xb7;
1283 bclk = 0x53;
1284 } else if (srate < 30000000) {
1285 aclk = 0xb6;
1286 bclk = 0x53;
1287 } else if (srate < 45000000) {
1288 aclk = 0xb4;
1289 bclk = 0x51;
1290 }
1291
1292 stv0299_writereg(fe, 0x13, aclk);
1293 stv0299_writereg(fe, 0x14, bclk);
1294 stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
1295 stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
1296 stv0299_writereg(fe, 0x21, (ratio) & 0xf0);
1297
1298 return 0;
1299}
1300
1301static int philips_tsa5059_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
1302{
1303 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
1304 u8 buf[4];
1305 u32 div;
1306 struct i2c_msg msg = {.addr = 0x61,.flags = 0,.buf = buf,.len = sizeof(buf) };
1307
1308 if ((params->frequency < 950000) || (params->frequency > 2150000))
1309 return -EINVAL;
1310
1311 div = (params->frequency + (125 - 1)) / 125; // round correctly
1312 buf[0] = (div >> 8) & 0x7f;
1313 buf[1] = div & 0xff;
1314 buf[2] = 0x80 | ((div & 0x18000) >> 10) | 4;
1315 buf[3] = 0xC4;
1316
1317 if (params->frequency > 1530000)
1318 buf[3] = 0xC0;
1319
1320 /* BSBE1 wants XCE bit set */
1321 if (ttusb->revision == TTUSB_REV_2_2)
1322 buf[3] |= 0x20;
1323
1324 if (i2c_transfer(&ttusb->i2c_adap, &msg, 1) != 1)
1325 return -EIO;
1326
1327 return 0;
1328}
1329
1330static struct stv0299_config alps_stv0299_config = {
1331 .demod_address = 0x68,
1332 .inittab = alps_bsru6_inittab,
1333 .mclk = 88000000UL,
1334 .invert = 1,
1335 .enhanced_tuning = 0,
1336 .skip_reinit = 0,
1337 .lock_output = STV0229_LOCKOUTPUT_1,
1338 .volt13_op0_op1 = STV0299_VOLT13_OP1,
1339 .min_delay_ms = 100,
1340 .set_symbol_rate = alps_stv0299_set_symbol_rate,
1341 .pll_set = philips_tsa5059_pll_set,
1342};
1343
1344static int ttusb_novas_grundig_29504_491_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
1345{
1346 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
1347 u8 buf[4];
1348 u32 div;
1349 struct i2c_msg msg = {.addr = 0x61,.flags = 0,.buf = buf,.len = sizeof(buf) };
1350
1351 div = params->frequency / 125;
1352
1353 buf[0] = (div >> 8) & 0x7f;
1354 buf[1] = div & 0xff;
1355 buf[2] = 0x8e;
1356 buf[3] = 0x00;
1357
1358 if (i2c_transfer(&ttusb->i2c_adap, &msg, 1) != 1)
1359 return -EIO;
1360
1361 return 0;
1362}
1363
1364static struct tda8083_config ttusb_novas_grundig_29504_491_config = {
1365
1366 .demod_address = 0x68,
1367 .pll_set = ttusb_novas_grundig_29504_491_pll_set,
1368};
1369
1370
1371
1372static void frontend_init(struct ttusb* ttusb)
1373{
1374 switch(le16_to_cpu(ttusb->dev->descriptor.idProduct)) {
1375 case 0x1003: // Hauppauge/TT Nova-USB-S budget (stv0299/ALPS BSRU6|BSBE1(tsa5059))
1376 // try the stv0299 based first
1377 ttusb->fe = stv0299_attach(&alps_stv0299_config, &ttusb->i2c_adap);
1378 if (ttusb->fe != NULL) {
1379 if(ttusb->revision == TTUSB_REV_2_2) { // ALPS BSBE1
1380 alps_stv0299_config.inittab = alps_bsbe1_inittab;
1381 ttusb->fe->ops->set_voltage = lnbp21_set_voltage;
1382 } else { // ALPS BSRU6
1383 ttusb->fe->ops->set_voltage = ttusb_set_voltage;
1384 }
1385 break;
1386 }
1387
1388 // Grundig 29504-491
1389 ttusb->fe = tda8083_attach(&ttusb_novas_grundig_29504_491_config, &ttusb->i2c_adap);
1390 if (ttusb->fe != NULL) {
1391 ttusb->fe->ops->set_voltage = ttusb_set_voltage;
1392 break;
1393 }
1394
1395 break;
1396
1397 case 0x1005: // Hauppauge/TT Nova-USB-t budget (tda10046/Philips td1316(tda6651tt) OR cx22700/ALPS TDMB7(??))
1398 // try the ALPS TDMB7 first
1399 ttusb->fe = cx22700_attach(&alps_tdmb7_config, &ttusb->i2c_adap);
1400 if (ttusb->fe != NULL)
1401 break;
1402
1403 // Philips td1316
1404 ttusb->fe = tda10046_attach(&philips_tdm1316l_config, &ttusb->i2c_adap);
1405 if (ttusb->fe != NULL)
1406 break;
1407 break;
1408 }
1409
1410 if (ttusb->fe == NULL) {
1411 printk("dvb-ttusb-budget: A frontend driver was not found for device %04x/%04x\n",
1412 le16_to_cpu(ttusb->dev->descriptor.idVendor),
1413 le16_to_cpu(ttusb->dev->descriptor.idProduct));
1414 } else {
1415 if (dvb_register_frontend(ttusb->adapter, ttusb->fe)) {
1416 printk("dvb-ttusb-budget: Frontend registration failed!\n");
1417 if (ttusb->fe->ops->release)
1418 ttusb->fe->ops->release(ttusb->fe);
1419 ttusb->fe = NULL;
1420 }
1421 }
1422}
1423
1424
1425
1426static struct i2c_algorithm ttusb_dec_algo = {
1427 .name = "ttusb dec i2c algorithm",
1428 .id = I2C_ALGO_BIT,
1429 .master_xfer = master_xfer,
1430 .functionality = functionality,
1431};
1432
1433static int ttusb_probe(struct usb_interface *intf, const struct usb_device_id *id)
1434{
1435 struct usb_device *udev;
1436 struct ttusb *ttusb;
1437 int result;
1438
1439 dprintk("%s: TTUSB DVB connected\n", __FUNCTION__);
1440
1441 udev = interface_to_usbdev(intf);
1442
1443 if (intf->altsetting->desc.bInterfaceNumber != 1) return -ENODEV;
1444
1445 if (!(ttusb = kmalloc(sizeof(struct ttusb), GFP_KERNEL)))
1446 return -ENOMEM;
1447
1448 memset(ttusb, 0, sizeof(struct ttusb));
1449
1450 ttusb->dev = udev;
1451 ttusb->c = 0;
1452 ttusb->mux_state = 0;
1453 sema_init(&ttusb->semi2c, 0);
1454 sema_init(&ttusb->semusb, 1);
1455
1456 ttusb_setup_interfaces(ttusb);
1457
1458 ttusb_alloc_iso_urbs(ttusb);
1459 if (ttusb_init_controller(ttusb))
1460 printk("ttusb_init_controller: error\n");
1461
1462 up(&ttusb->semi2c);
1463
1464 dvb_register_adapter(&ttusb->adapter, "Technotrend/Hauppauge Nova-USB", THIS_MODULE);
1465 ttusb->adapter->priv = ttusb;
1466
1467 /* i2c */
1468 memset(&ttusb->i2c_adap, 0, sizeof(struct i2c_adapter));
1469 strcpy(ttusb->i2c_adap.name, "TTUSB DEC");
1470
1471 i2c_set_adapdata(&ttusb->i2c_adap, ttusb);
1472
1473#ifdef I2C_ADAP_CLASS_TV_DIGITAL
1474 ttusb->i2c_adap.class = I2C_ADAP_CLASS_TV_DIGITAL;
1475#else
1476 ttusb->i2c_adap.class = I2C_CLASS_TV_DIGITAL;
1477#endif
1478 ttusb->i2c_adap.algo = &ttusb_dec_algo;
1479 ttusb->i2c_adap.algo_data = NULL;
1480 ttusb->i2c_adap.id = I2C_ALGO_BIT;
1481
1482 result = i2c_add_adapter(&ttusb->i2c_adap);
1483 if (result) {
1484 dvb_unregister_adapter (ttusb->adapter);
1485 return result;
1486 }
1487
1488 memset(&ttusb->dvb_demux, 0, sizeof(ttusb->dvb_demux));
1489
1490 ttusb->dvb_demux.dmx.capabilities =
1491 DMX_TS_FILTERING | DMX_SECTION_FILTERING;
1492 ttusb->dvb_demux.priv = NULL;
1493#ifdef TTUSB_HWSECTIONS
1494 ttusb->dvb_demux.filternum = TTUSB_MAXFILTER;
1495#else
1496 ttusb->dvb_demux.filternum = 32;
1497#endif
1498 ttusb->dvb_demux.feednum = TTUSB_MAXCHANNEL;
1499 ttusb->dvb_demux.start_feed = ttusb_start_feed;
1500 ttusb->dvb_demux.stop_feed = ttusb_stop_feed;
1501 ttusb->dvb_demux.write_to_decoder = NULL;
1502
1503 if ((result = dvb_dmx_init(&ttusb->dvb_demux)) < 0) {
1504 printk("ttusb_dvb: dvb_dmx_init failed (errno = %d)\n", result);
1505 i2c_del_adapter(&ttusb->i2c_adap);
1506 dvb_unregister_adapter (ttusb->adapter);
1507 return -ENODEV;
1508 }
1509//FIXME dmxdev (nur WAS?)
1510 ttusb->dmxdev.filternum = ttusb->dvb_demux.filternum;
1511 ttusb->dmxdev.demux = &ttusb->dvb_demux.dmx;
1512 ttusb->dmxdev.capabilities = 0;
1513
1514 if ((result = dvb_dmxdev_init(&ttusb->dmxdev, ttusb->adapter)) < 0) {
1515 printk("ttusb_dvb: dvb_dmxdev_init failed (errno = %d)\n",
1516 result);
1517 dvb_dmx_release(&ttusb->dvb_demux);
1518 i2c_del_adapter(&ttusb->i2c_adap);
1519 dvb_unregister_adapter (ttusb->adapter);
1520 return -ENODEV;
1521 }
1522
1523 if (dvb_net_init(ttusb->adapter, &ttusb->dvbnet, &ttusb->dvb_demux.dmx)) {
1524 printk("ttusb_dvb: dvb_net_init failed!\n");
1525 dvb_dmxdev_release(&ttusb->dmxdev);
1526 dvb_dmx_release(&ttusb->dvb_demux);
1527 i2c_del_adapter(&ttusb->i2c_adap);
1528 dvb_unregister_adapter (ttusb->adapter);
1529 return -ENODEV;
1530 }
1531
1532#if 0
1533 ttusb->stc_devfs_handle =
1534 devfs_register(ttusb->adapter->devfs_handle, TTUSB_BUDGET_NAME,
1535 DEVFS_FL_DEFAULT, 0, 192,
1536 S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP
1537 | S_IROTH | S_IWOTH, &stc_fops, ttusb);
1538#endif
1539 usb_set_intfdata(intf, (void *) ttusb);
1540
1541 frontend_init(ttusb);
1542
1543 return 0;
1544}
1545
1546static void ttusb_disconnect(struct usb_interface *intf)
1547{
1548 struct ttusb *ttusb = usb_get_intfdata(intf);
1549
1550 usb_set_intfdata(intf, NULL);
1551
1552 ttusb->disconnecting = 1;
1553
1554 ttusb_stop_iso_xfer(ttusb);
1555
1556 ttusb->dvb_demux.dmx.close(&ttusb->dvb_demux.dmx);
1557 dvb_net_release(&ttusb->dvbnet);
1558 dvb_dmxdev_release(&ttusb->dmxdev);
1559 dvb_dmx_release(&ttusb->dvb_demux);
1560 if (ttusb->fe != NULL) dvb_unregister_frontend(ttusb->fe);
1561 i2c_del_adapter(&ttusb->i2c_adap);
1562 dvb_unregister_adapter(ttusb->adapter);
1563
1564 ttusb_free_iso_urbs(ttusb);
1565
1566 kfree(ttusb);
1567
1568 dprintk("%s: TTUSB DVB disconnected\n", __FUNCTION__);
1569}
1570
1571static struct usb_device_id ttusb_table[] = {
1572 {USB_DEVICE(0xb48, 0x1003)},
1573/* {USB_DEVICE(0xb48, 0x1004)},UNDEFINED HARDWARE - mail linuxtv.org list*/ /* to be confirmed ???? */
1574 {USB_DEVICE(0xb48, 0x1005)},
1575 {}
1576};
1577
1578MODULE_DEVICE_TABLE(usb, ttusb_table);
1579
1580static struct usb_driver ttusb_driver = {
1581 .name = "Technotrend/Hauppauge USB-Nova",
1582 .probe = ttusb_probe,
1583 .disconnect = ttusb_disconnect,
1584 .id_table = ttusb_table,
1585};
1586
1587static int __init ttusb_init(void)
1588{
1589 int err;
1590
1591 if ((err = usb_register(&ttusb_driver)) < 0) {
1592 printk("%s: usb_register failed! Error number %d",
1593 __FILE__, err);
1594 return err;
1595 }
1596
1597 return 0;
1598}
1599
1600static void __exit ttusb_exit(void)
1601{
1602 usb_deregister(&ttusb_driver);
1603}
1604
1605module_init(ttusb_init);
1606module_exit(ttusb_exit);
1607
1608MODULE_AUTHOR("Holger Waechtler <holger@convergence.de>");
1609MODULE_DESCRIPTION("TTUSB DVB Driver");
1610MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/ttusb-budget/dvb-ttusb-dspbootcode.h b/drivers/media/dvb/ttusb-budget/dvb-ttusb-dspbootcode.h
new file mode 100644
index 000000000000..95ee7995455e
--- /dev/null
+++ b/drivers/media/dvb/ttusb-budget/dvb-ttusb-dspbootcode.h
@@ -0,0 +1,1644 @@
1
2#include <asm/types.h>
3
4static u8 dsp_bootcode [] = {
5 0x08, 0xaa, 0x00, 0x18, 0x00, 0x03, 0x08, 0x00,
6 0x00, 0x10, 0x00, 0x00, 0x01, 0x80, 0x18, 0x5f,
7 0x00, 0x00, 0x01, 0x80, 0x77, 0x18, 0x2a, 0xeb,
8 0x6b, 0xf8, 0x00, 0x18, 0x03, 0xff, 0x68, 0xf8,
9 0x00, 0x18, 0xff, 0xfe, 0xf7, 0xb8, 0xf7, 0xbe,
10 0xf6, 0xb9, 0xf4, 0xa0, 0xf6, 0xb7, 0xf6, 0xb5,
11 0xf6, 0xb6, 0xf0, 0x20, 0x19, 0xdf, 0xf1, 0x00,
12 0x00, 0x01, 0xf8, 0x4d, 0x01, 0xab, 0xf6, 0xb8,
13 0xf0, 0x20, 0x19, 0xdf, 0xf0, 0x73, 0x01, 0xa5,
14 0x7e, 0xf8, 0x00, 0x12, 0xf0, 0x00, 0x00, 0x01,
15 0x47, 0xf8, 0x00, 0x11, 0x7e, 0x92, 0x00, 0xf8,
16 0x00, 0x11, 0xf0, 0x00, 0x00, 0x01, 0x7e, 0xf8,
17 0x00, 0x11, 0xf0, 0x00, 0x00, 0x01, 0x6c, 0x89,
18 0x01, 0x9a, 0xf7, 0xb8, 0xee, 0xfc, 0xf0, 0x20,
19 0xff, 0xff, 0xf1, 0x00, 0x00, 0x01, 0xf8, 0x4d,
20 0x01, 0xbf, 0xf2, 0x73, 0x01, 0xb9, 0x4e, 0x02,
21 0xf4, 0x95, 0xf5, 0xe3, 0x56, 0x02, 0x7e, 0x00,
22 0x11, 0x00, 0xfa, 0x4c, 0x01, 0xb7, 0x6b, 0x03,
23 0x00, 0x01, 0xf6, 0xb8, 0xee, 0x04, 0xf0, 0x74,
24 0x0d, 0xa7, 0xf0, 0x74, 0x01, 0xc5, 0x4a, 0x11,
25 0x4a, 0x16, 0x72, 0x11, 0x2a, 0xe6, 0x10, 0xf8,
26 0x00, 0x11, 0xfa, 0x45, 0x01, 0xdb, 0xf4, 0x95,
27 0xee, 0xff, 0x48, 0x11, 0xf0, 0x00, 0x2a, 0xc6,
28 0x88, 0x16, 0xf4, 0x95, 0xf4, 0x95, 0x10, 0xee,
29 0xff, 0xff, 0xf4, 0xe3, 0x6c, 0xe9, 0xff, 0xff,
30 0x01, 0xd5, 0x10, 0xf8, 0x2a, 0xe7, 0xf8, 0x45,
31 0x01, 0xe2, 0x10, 0xf8, 0x2a, 0xe7, 0xf4, 0xe3,
32 0xf0, 0x74, 0x01, 0xff, 0xee, 0x01, 0x8a, 0x16,
33 0x8a, 0x11, 0xfc, 0x00, 0xf7, 0xb8, 0xe9, 0x20,
34 0x4a, 0x11, 0x09, 0xf8, 0x2a, 0xe6, 0xf8, 0x4e,
35 0x01, 0xf3, 0xf2, 0x73, 0x01, 0xfd, 0xf4, 0x95,
36 0xe8, 0x01, 0x72, 0x11, 0x2a, 0xe6, 0x49, 0x11,
37 0x80, 0xe1, 0x2a, 0xc6, 0xf3, 0x00, 0x00, 0x01,
38 0xe8, 0x00, 0x81, 0xf8, 0x2a, 0xe6, 0x8a, 0x11,
39 0xfc, 0x00, 0xf4, 0x95, 0xf0, 0x73, 0x02, 0x00,
40 0x10, 0xf8, 0x2a, 0x0f, 0xfc, 0x00, 0x4a, 0x11,
41 0xf0, 0x74, 0x02, 0x02, 0x80, 0xf8, 0x2a, 0x10,
42 0x73, 0x08, 0x00, 0x09, 0x40, 0xf8, 0x2a, 0x15,
43 0x82, 0xf8, 0x00, 0x11, 0xf4, 0x95, 0x77, 0x10,
44 0x03, 0xe8, 0xf5, 0xa9, 0xf8, 0x30, 0x02, 0x21,
45 0x71, 0xf8, 0x2a, 0x10, 0x2a, 0x15, 0x56, 0xf8,
46 0x2a, 0x0c, 0xf0, 0xe3, 0x4e, 0xf8, 0x2a, 0x16,
47 0xe8, 0x00, 0x4e, 0xf8, 0x2a, 0x0c, 0x8a, 0x11,
48 0xfc, 0x00, 0x4a, 0x06, 0x4a, 0x07, 0x4a, 0x1d,
49 0x68, 0xf8, 0x00, 0x07, 0x7d, 0x3f, 0x69, 0xf8,
50 0x00, 0x07, 0x40, 0x00, 0x68, 0xf8, 0x00, 0x1d,
51 0xff, 0xfc, 0x6b, 0xf8, 0x2a, 0x0f, 0x00, 0x01,
52 0x8a, 0x1d, 0x8a, 0x07, 0x8a, 0x06, 0xf4, 0xeb,
53 0xee, 0xfd, 0x76, 0xf8, 0x2a, 0x0f, 0x00, 0x00,
54 0x76, 0x00, 0x00, 0x00, 0xfb, 0x80, 0x19, 0x4c,
55 0xf4, 0x95, 0xe8, 0x00, 0x80, 0xf8, 0x2a, 0x11,
56 0xf9, 0x80, 0x19, 0x07, 0x80, 0xf8, 0x2a, 0x0e,
57 0xf9, 0x80, 0x16, 0x66, 0x76, 0x00, 0x2a, 0x12,
58 0x10, 0xf8, 0x2a, 0x11, 0xf9, 0x80, 0x18, 0xe3,
59 0x10, 0xf8, 0x2a, 0x0e, 0xf9, 0x80, 0x16, 0x66,
60 0x10, 0xf8, 0x2a, 0x0e, 0xf9, 0x80, 0x16, 0x87,
61 0xee, 0x03, 0xfc, 0x00, 0x4a, 0x11, 0xf6, 0xb8,
62 0xf4, 0x95, 0xf0, 0x20, 0x80, 0x00, 0x11, 0xf8,
63 0x2a, 0x5a, 0xf8, 0x4d, 0x02, 0x93, 0x11, 0xf8,
64 0x2a, 0x9f, 0xf8, 0x4c, 0x02, 0x7c, 0x77, 0x12,
65 0x2a, 0x39, 0x49, 0x12, 0x01, 0xf8, 0x2a, 0x9f,
66 0x89, 0x11, 0xf4, 0x95, 0xf4, 0x95, 0x71, 0x81,
67 0x00, 0x11, 0x6c, 0xe1, 0xff, 0xab, 0x02, 0x93,
68 0x6b, 0xf8, 0x2a, 0x9f, 0x00, 0x01, 0xe9, 0x05,
69 0x01, 0xe2, 0x00, 0x03, 0x81, 0xf8, 0x2a, 0xa0,
70 0xf0, 0x73, 0x02, 0x95, 0x72, 0x11, 0x2a, 0x9f,
71 0xf4, 0x95, 0x10, 0xe1, 0x2a, 0x39, 0x6b, 0xf8,
72 0x2a, 0x9f, 0x00, 0x01, 0x11, 0xf8, 0x2a, 0x9f,
73 0x09, 0xf8, 0x2a, 0xa0, 0xf8, 0x4c, 0x02, 0x93,
74 0x76, 0xf8, 0x2a, 0x5a, 0x00, 0x00, 0x76, 0xf8,
75 0x2a, 0x9f, 0x00, 0x00, 0x76, 0xf8, 0x2a, 0xa0,
76 0x00, 0x00, 0x88, 0x11, 0xf4, 0x95, 0x48, 0x11,
77 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0xee, 0xfe,
78 0x10, 0xf8, 0x2a, 0x5a, 0xf8, 0x44, 0x02, 0xb2,
79 0x76, 0xf8, 0x2a, 0x5a, 0x00, 0x01, 0xf0, 0x74,
80 0x02, 0x58, 0x88, 0x11, 0xf4, 0x95, 0x77, 0x10,
81 0x80, 0x00, 0xf4, 0xa9, 0xf8, 0x30, 0x02, 0xb2,
82 0x48, 0x11, 0xf0, 0x30, 0x00, 0xff, 0x80, 0x00,
83 0x10, 0xf8, 0x2a, 0x5b, 0xf9, 0x80, 0x18, 0xd6,
84 0xee, 0x02, 0x8a, 0x11, 0xfc, 0x00, 0xf4, 0x95,
85 0x4a, 0x08, 0x4a, 0x09, 0x4a, 0x0a, 0x4a, 0x0b,
86 0x4a, 0x0c, 0x4a, 0x0d, 0x4a, 0x10, 0x4a, 0x11,
87 0x4a, 0x12, 0x4a, 0x13, 0x4a, 0x14, 0x4a, 0x15,
88 0x4a, 0x16, 0x4a, 0x17, 0x4a, 0x17, 0x4a, 0x19,
89 0x4a, 0x0e, 0x4a, 0x06, 0x4a, 0x07, 0x4a, 0x1a,
90 0x4a, 0x1d, 0x4a, 0x1b, 0x4a, 0x1c, 0x68, 0xf8,
91 0x00, 0x07, 0x7d, 0x3f, 0x69, 0xf8, 0x00, 0x07,
92 0x40, 0x00, 0x68, 0xf8, 0x00, 0x1d, 0xff, 0xfc,
93 0x48, 0x18, 0x68, 0xf8, 0x00, 0x18, 0xff, 0xfe,
94 0xf4, 0x95, 0xf4, 0x95, 0x4a, 0x08, 0xee, 0xfd,
95 0xf0, 0x74, 0x02, 0x58, 0x88, 0x11, 0xf4, 0x95,
96 0x77, 0x10, 0x80, 0x00, 0xf4, 0xa9, 0xf8, 0x30,
97 0x02, 0xef, 0x48, 0x11, 0xf0, 0x30, 0x00, 0xff,
98 0x80, 0x00, 0x10, 0xf8, 0x2a, 0x5b, 0xf9, 0x80,
99 0x18, 0xd6, 0xee, 0x03, 0x8a, 0x18, 0xf4, 0x95,
100 0x8a, 0x1c, 0x8a, 0x1b, 0x8a, 0x1d, 0x8a, 0x1a,
101 0x8a, 0x07, 0x8a, 0x06, 0x8a, 0x0e, 0x8a, 0x19,
102 0x8a, 0x17, 0x8a, 0x17, 0x8a, 0x16, 0x8a, 0x15,
103 0x8a, 0x14, 0x8a, 0x13, 0x8a, 0x12, 0x8a, 0x11,
104 0x8a, 0x10, 0x8a, 0x0d, 0x8a, 0x0c, 0x8a, 0x0b,
105 0x8a, 0x0a, 0x8a, 0x09, 0x8a, 0x08, 0xf4, 0xeb,
106 0x4a, 0x11, 0x77, 0x11, 0x2a, 0x39, 0x76, 0x81,
107 0x00, 0x55, 0x77, 0x12, 0x2a, 0x18, 0x10, 0xe2,
108 0x00, 0x01, 0x80, 0xe1, 0x00, 0x01, 0x10, 0xe2,
109 0x00, 0x02, 0x80, 0xe1, 0x00, 0x02, 0x76, 0xe1,
110 0x00, 0x03, 0x00, 0x00, 0x76, 0xe1, 0x00, 0x04,
111 0x00, 0xaa, 0xf0, 0x74, 0x02, 0x98, 0x8a, 0x11,
112 0xfc, 0x00, 0x4a, 0x11, 0x88, 0x11, 0xf4, 0x95,
113 0xf4, 0x95, 0x10, 0x81, 0x6f, 0xf8, 0x2a, 0x9e,
114 0x0c, 0x88, 0xe8, 0xff, 0x18, 0xe1, 0x00, 0x01,
115 0x1a, 0xf8, 0x2a, 0x9e, 0xf0, 0x30, 0x1f, 0xff,
116 0x80, 0xf8, 0x2a, 0x9e, 0x8a, 0x11, 0xfc, 0x00,
117 0x4a, 0x11, 0x77, 0x11, 0x2a, 0x39, 0x76, 0x81,
118 0x00, 0x55, 0x77, 0x12, 0x2a, 0x18, 0x11, 0xe2,
119 0x00, 0x01, 0x81, 0xe1, 0x00, 0x01, 0x11, 0xe2,
120 0x00, 0x02, 0x81, 0xe1, 0x00, 0x02, 0x76, 0xe1,
121 0x00, 0x03, 0x00, 0x02, 0x48, 0x08, 0x6f, 0xe1,
122 0x00, 0x04, 0x0c, 0x98, 0xf0, 0x30, 0x00, 0xff,
123 0x80, 0xe1, 0x00, 0x05, 0x76, 0xe1, 0x00, 0x06,
124 0x00, 0xaa, 0xf0, 0x74, 0x02, 0x98, 0x8a, 0x11,
125 0xfc, 0x00, 0x4a, 0x11, 0x77, 0x11, 0x2a, 0x39,
126 0x76, 0x81, 0x00, 0x55, 0x77, 0x12, 0x2a, 0x18,
127 0x10, 0xe2, 0x00, 0x01, 0x80, 0xe1, 0x00, 0x01,
128 0x10, 0xe2, 0x00, 0x02, 0x80, 0xe1, 0x00, 0x02,
129 0x76, 0xe1, 0x00, 0x03, 0x00, 0x04, 0x48, 0x11,
130 0xf0, 0x00, 0x00, 0x04, 0x88, 0x12, 0xf4, 0x95,
131 0x77, 0x13, 0x2a, 0x76, 0xe9, 0x00, 0xe5, 0x98,
132 0xf3, 0x00, 0x00, 0x01, 0xf6, 0xb8, 0x48, 0x0b,
133 0x08, 0xf8, 0x2a, 0x3c, 0xf8, 0x43, 0x03, 0x71,
134 0x76, 0x82, 0x00, 0xaa, 0xf0, 0x74, 0x02, 0x98,
135 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0xee, 0xf0,
136 0x88, 0x11, 0xf4, 0x95, 0xf4, 0x95, 0x71, 0x81,
137 0x00, 0x14, 0x71, 0xe1, 0x00, 0x01, 0x00, 0x15,
138 0x49, 0x11, 0xf3, 0x00, 0x00, 0x02, 0x89, 0x11,
139 0xe7, 0x82, 0x6d, 0xea, 0x00, 0x04, 0xe7, 0x83,
140 0x6d, 0xeb, 0x00, 0x0a, 0x77, 0x1a, 0x00, 0x05,
141 0xf0, 0x72, 0x03, 0xaa, 0x11, 0x81, 0xf2, 0xe8,
142 0x80, 0x82, 0xe9, 0xff, 0x19, 0xe1, 0x00, 0x01,
143 0xf1, 0xa0, 0x81, 0x92, 0x11, 0xe1, 0x00, 0x0c,
144 0xf2, 0xe8, 0x80, 0x83, 0xe9, 0xff, 0x19, 0xe1,
145 0x00, 0x0d, 0xf1, 0xa0, 0x81, 0x93, 0x6d, 0xe9,
146 0x00, 0x02, 0x48, 0x18, 0x49, 0x18, 0x70, 0x00,
147 0x00, 0x15, 0xf0, 0x00, 0x00, 0x04, 0xf3, 0x00,
148 0x00, 0x0a, 0x80, 0x01, 0x81, 0x02, 0xf2, 0x74,
149 0x0e, 0x54, 0xf4, 0x95, 0x48, 0x14, 0xee, 0x10,
150 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0xf0, 0x74,
151 0x0c, 0x5e, 0x80, 0xf8, 0x2a, 0x5c, 0x77, 0x12,
152 0x2a, 0x39, 0x76, 0x82, 0x00, 0x55, 0x77, 0x11,
153 0x2a, 0x18, 0x10, 0xe1, 0x00, 0x01, 0x80, 0xe2,
154 0x00, 0x01, 0x10, 0xe1, 0x00, 0x02, 0x80, 0xe2,
155 0x00, 0x02, 0x76, 0xe2, 0x00, 0x03, 0x00, 0x1c,
156 0xf6, 0xb8, 0x56, 0xf8, 0x2a, 0x16, 0xf0, 0xf0,
157 0xf0, 0xf8, 0x80, 0xe2, 0x00, 0x07, 0x56, 0xf8,
158 0x2a, 0x16, 0xf1, 0xf0, 0xe8, 0xff, 0xf2, 0x80,
159 0x80, 0xe2, 0x00, 0x06, 0x56, 0xf8, 0x2a, 0x16,
160 0xf1, 0xf8, 0xe8, 0xff, 0xf2, 0x80, 0x80, 0xe2,
161 0x00, 0x05, 0x57, 0xf8, 0x2a, 0x16, 0xe8, 0xff,
162 0xf2, 0x80, 0x80, 0xe2, 0x00, 0x04, 0x56, 0xf8,
163 0x27, 0x6c, 0xf0, 0xf0, 0xf0, 0xf8, 0x80, 0xe2,
164 0x00, 0x0b, 0x56, 0xf8, 0x27, 0x6c, 0xf1, 0xf0,
165 0xe8, 0xff, 0xf2, 0x80, 0x80, 0xe2, 0x00, 0x0a,
166 0x56, 0xf8, 0x27, 0x6c, 0xf1, 0xf8, 0xe8, 0xff,
167 0xf2, 0x80, 0x80, 0xe2, 0x00, 0x09, 0xe8, 0xff,
168 0x57, 0xf8, 0x27, 0x6c, 0xf2, 0x80, 0x80, 0xe2,
169 0x00, 0x08, 0x56, 0xf8, 0x27, 0x6a, 0xf0, 0xf0,
170 0xf0, 0xf8, 0x80, 0xe2, 0x00, 0x0f, 0x56, 0xf8,
171 0x27, 0x6a, 0xf1, 0xf0, 0xe8, 0xff, 0xf2, 0x80,
172 0x80, 0xe2, 0x00, 0x0e, 0x56, 0xf8, 0x27, 0x6a,
173 0xf1, 0xf8, 0xe8, 0xff, 0xf2, 0x80, 0x80, 0xe2,
174 0x00, 0x0d, 0x57, 0xf8, 0x27, 0x6a, 0xe8, 0xff,
175 0xf2, 0x80, 0x80, 0xe2, 0x00, 0x0c, 0x76, 0xe2,
176 0x00, 0x13, 0x00, 0x00, 0x76, 0xe2, 0x00, 0x12,
177 0x00, 0x00, 0x6f, 0xf8, 0x2a, 0x5c, 0x0c, 0x58,
178 0x80, 0xe2, 0x00, 0x11, 0xe8, 0xff, 0x18, 0xf8,
179 0x2a, 0x5c, 0x80, 0xe2, 0x00, 0x10, 0x76, 0xe2,
180 0x00, 0x17, 0x00, 0x00, 0x76, 0xe2, 0x00, 0x16,
181 0x00, 0x00, 0x6f, 0xf8, 0x2a, 0x9e, 0x0c, 0x58,
182 0x80, 0xe2, 0x00, 0x15, 0xe8, 0xff, 0x18, 0xf8,
183 0x2a, 0x9e, 0x80, 0xe2, 0x00, 0x14, 0x76, 0xe2,
184 0x00, 0x1b, 0x00, 0x00, 0x76, 0xe2, 0x00, 0x1a,
185 0x00, 0x00, 0x76, 0xe2, 0x00, 0x19, 0x00, 0x00,
186 0x70, 0xe2, 0x00, 0x18, 0x27, 0x6e, 0x76, 0xe2,
187 0x00, 0x1f, 0x00, 0x00, 0x76, 0xe2, 0x00, 0x1e,
188 0x00, 0x00, 0x76, 0xe2, 0x00, 0x1d, 0x00, 0x00,
189 0x76, 0xe2, 0x00, 0x1c, 0x00, 0x00, 0x76, 0xe2,
190 0x00, 0x20, 0x00, 0xaa, 0xf0, 0x74, 0x02, 0x98,
191 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0xee, 0xfe,
192 0x10, 0xf8, 0x2a, 0x38, 0xf8, 0x45, 0x04, 0xed,
193 0x77, 0x12, 0x2a, 0x18, 0x10, 0xe2, 0x00, 0x02,
194 0x88, 0x11, 0xf4, 0x95, 0x77, 0x10, 0x00, 0x08,
195 0x6d, 0xe9, 0xff, 0xdf, 0xf6, 0xa9, 0xf8, 0x20,
196 0x04, 0x75, 0xf0, 0x73, 0x04, 0x7d, 0xf0, 0x10,
197 0x00, 0x21, 0xf0, 0x00, 0x1a, 0x83, 0x48, 0x08,
198 0x7e, 0xf8, 0x00, 0x08, 0xf4, 0xe2, 0xf0, 0x74,
199 0x03, 0x0a, 0xf0, 0x73, 0x04, 0xea, 0x48, 0x12,
200 0xf2, 0x74, 0x03, 0x23, 0xf0, 0x00, 0x00, 0x04,
201 0xf2, 0x74, 0x03, 0x36, 0xf4, 0x95, 0xe8, 0x00,
202 0xf0, 0x73, 0x04, 0xea, 0x77, 0x11, 0x2a, 0x18,
203 0xe8, 0xff, 0x6f, 0xe1, 0x00, 0x04, 0x0d, 0x48,
204 0x18, 0xe1, 0x00, 0x05, 0xf2, 0x74, 0x09, 0x69,
205 0xf4, 0x95, 0xf2, 0xa0, 0xf0, 0x74, 0x03, 0x36,
206 0xf0, 0x73, 0x04, 0xea, 0x77, 0x11, 0x2a, 0x18,
207 0xe8, 0xff, 0x6f, 0xe1, 0x00, 0x04, 0x0d, 0x48,
208 0x18, 0xe1, 0x00, 0x05, 0xf2, 0x74, 0x09, 0x41,
209 0xf4, 0x95, 0xf2, 0xa0, 0xf0, 0x74, 0x03, 0x36,
210 0xf0, 0x73, 0x04, 0xea, 0xf0, 0x74, 0x03, 0x57,
211 0xf0, 0x73, 0x04, 0xea, 0x10, 0xf8, 0x2a, 0x1c,
212 0xf0, 0x74, 0x12, 0xa4, 0xf2, 0x74, 0x03, 0x36,
213 0xf4, 0x95, 0xe8, 0x00, 0xf0, 0x73, 0x04, 0xea,
214 0x48, 0x12, 0xf2, 0x74, 0x03, 0x80, 0xf0, 0x00,
215 0x00, 0x04, 0xf2, 0x74, 0x03, 0x36, 0xf4, 0x95,
216 0xe8, 0x00, 0xf0, 0x73, 0x04, 0xea, 0x10, 0xf8,
217 0x2a, 0x1c, 0xf0, 0x74, 0x12, 0xc5, 0xf2, 0x74,
218 0x03, 0x36, 0xf4, 0x95, 0xe8, 0x00, 0xf0, 0x73,
219 0x04, 0xea, 0x77, 0x11, 0x2a, 0x18, 0xe8, 0xff,
220 0x6f, 0xe1, 0x00, 0x06, 0x0d, 0x48, 0x18, 0xe1,
221 0x00, 0x07, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12,
222 0xf2, 0xa0, 0x70, 0x00, 0x00, 0x12, 0x80, 0x01,
223 0x10, 0xe1, 0x00, 0x04, 0xf0, 0x74, 0x0e, 0x7a,
224 0xf2, 0x74, 0x03, 0x36, 0xf4, 0x95, 0xe8, 0x00,
225 0xf0, 0x73, 0x04, 0xea, 0xf0, 0x74, 0x03, 0xbc,
226 0x76, 0xf8, 0x2a, 0x38, 0x00, 0x00, 0xee, 0x02,
227 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0x77, 0x11,
228 0x2a, 0x39, 0x76, 0x81, 0x00, 0x55, 0x77, 0x12,
229 0x2a, 0x18, 0x10, 0xe2, 0x00, 0x01, 0x80, 0xe1,
230 0x00, 0x01, 0x10, 0xe2, 0x00, 0x02, 0x80, 0xe1,
231 0x00, 0x02, 0x76, 0xe1, 0x00, 0x03, 0x00, 0x09,
232 0x48, 0x11, 0xf0, 0x00, 0x00, 0x04, 0x88, 0x12,
233 0xf4, 0x95, 0x77, 0x13, 0x2a, 0x86, 0xe9, 0x00,
234 0xe5, 0x98, 0xf3, 0x00, 0x00, 0x01, 0xf6, 0xb8,
235 0x48, 0x0b, 0x08, 0xf8, 0x2a, 0x3c, 0xf8, 0x43,
236 0x05, 0x0a, 0x76, 0x82, 0x00, 0xaa, 0xf0, 0x74,
237 0x02, 0x98, 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11,
238 0x77, 0x11, 0x2a, 0x39, 0x76, 0x81, 0x00, 0x55,
239 0x77, 0x13, 0x2a, 0x18, 0x10, 0xe3, 0x00, 0x01,
240 0x80, 0xe1, 0x00, 0x01, 0x10, 0xe3, 0x00, 0x02,
241 0x80, 0xe1, 0x00, 0x02, 0x13, 0xe3, 0x00, 0x03,
242 0x81, 0xe1, 0x00, 0x03, 0x48, 0x11, 0x77, 0x11,
243 0x00, 0x00, 0xf8, 0x4d, 0x05, 0x44, 0xf0, 0x00,
244 0x00, 0x04, 0x88, 0x12, 0x48, 0x13, 0xf0, 0x00,
245 0x00, 0x04, 0x88, 0x13, 0xf4, 0x95, 0xf4, 0x95,
246 0xe5, 0x98, 0x6d, 0x91, 0xf6, 0xb8, 0x48, 0x11,
247 0x08, 0xf8, 0x2a, 0x3c, 0xf8, 0x43, 0x05, 0x3a,
248 0xf0, 0x20, 0x2a, 0x39, 0x49, 0x11, 0xf5, 0x00,
249 0x89, 0x11, 0xf4, 0x95, 0xf4, 0x95, 0x76, 0xe1,
250 0x00, 0x04, 0x00, 0xaa, 0xf0, 0x74, 0x02, 0x98,
251 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0x77, 0x11,
252 0x2a, 0x39, 0x76, 0x81, 0x00, 0x55, 0x77, 0x12,
253 0x2a, 0x18, 0x10, 0xe2, 0x00, 0x01, 0x80, 0xe1,
254 0x00, 0x01, 0x10, 0xe2, 0x00, 0x02, 0x80, 0xe1,
255 0x00, 0x02, 0x76, 0xe1, 0x00, 0x03, 0x00, 0x0c,
256 0x48, 0x11, 0xf0, 0x00, 0x00, 0x04, 0x88, 0x12,
257 0xf4, 0x95, 0x77, 0x13, 0x2a, 0x7a, 0xe9, 0x00,
258 0xe5, 0x98, 0xf3, 0x00, 0x00, 0x01, 0xf6, 0xb8,
259 0x48, 0x0b, 0x08, 0xf8, 0x2a, 0x3c, 0xf8, 0x43,
260 0x05, 0x6a, 0x76, 0x82, 0x00, 0xaa, 0xf0, 0x74,
261 0x02, 0x98, 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11,
262 0x77, 0x11, 0x2a, 0x39, 0x76, 0x81, 0x00, 0x55,
263 0x77, 0x12, 0x2a, 0x18, 0x10, 0xe2, 0x00, 0x01,
264 0x80, 0xe1, 0x00, 0x01, 0x10, 0xe2, 0x00, 0x02,
265 0x80, 0xe1, 0x00, 0x02, 0x76, 0xe1, 0x00, 0x03,
266 0x00, 0x19, 0x48, 0x11, 0xf0, 0x00, 0x00, 0x04,
267 0x88, 0x12, 0xf4, 0x95, 0x77, 0x13, 0x2a, 0x5d,
268 0xe9, 0x00, 0xe5, 0x98, 0xf3, 0x00, 0x00, 0x01,
269 0xf6, 0xb8, 0x48, 0x0b, 0x08, 0xf8, 0x2a, 0x3c,
270 0xf8, 0x43, 0x05, 0x93, 0x76, 0x82, 0x00, 0xaa,
271 0xf0, 0x74, 0x02, 0x98, 0x8a, 0x11, 0xfc, 0x00,
272 0x4a, 0x11, 0x88, 0x11, 0x10, 0xf8, 0x2a, 0x38,
273 0xf8, 0x44, 0x05, 0xe3, 0x10, 0xf8, 0x2a, 0xa1,
274 0xf8, 0x44, 0x05, 0xba, 0x6c, 0xe1, 0xff, 0x56,
275 0x05, 0xe3, 0x72, 0x12, 0x2a, 0xa1, 0xf4, 0x95,
276 0x70, 0xe2, 0x2a, 0x18, 0x00, 0x11, 0x6b, 0xf8,
277 0x2a, 0xa1, 0x00, 0x01, 0xf0, 0x73, 0x05, 0xe3,
278 0x72, 0x12, 0x2a, 0xa1, 0xf4, 0x95, 0x70, 0xe2,
279 0x2a, 0x18, 0x00, 0x11, 0x10, 0xf8, 0x2a, 0xa1,
280 0xf0, 0x00, 0x00, 0x01, 0x88, 0x12, 0xf4, 0x95,
281 0xf4, 0x95, 0x6e, 0xe2, 0xff, 0xfc, 0x05, 0xd1,
282 0x73, 0x12, 0x2a, 0xa1, 0x48, 0x11, 0xf0, 0x00,
283 0x00, 0x05, 0x80, 0xf8, 0x2a, 0xa2, 0x10, 0xf8,
284 0x2a, 0xa1, 0x08, 0xf8, 0x2a, 0xa2, 0xf8, 0x44,
285 0x05, 0xe3, 0x6c, 0xe1, 0xff, 0xab, 0x05, 0xdd,
286 0x76, 0xf8, 0x2a, 0x38, 0x00, 0x01, 0x76, 0xf8,
287 0x2a, 0xa1, 0x00, 0x00, 0x76, 0xf8, 0x2a, 0xa2,
288 0x00, 0x00, 0x8a, 0x11, 0xfc, 0x00, 0xf4, 0x95,
289 0x4a, 0x08, 0x4a, 0x09, 0x4a, 0x0a, 0x4a, 0x0b,
290 0x4a, 0x0c, 0x4a, 0x0d, 0x4a, 0x10, 0x4a, 0x11,
291 0x4a, 0x12, 0x4a, 0x13, 0x4a, 0x14, 0x4a, 0x15,
292 0x4a, 0x16, 0x4a, 0x17, 0x4a, 0x17, 0x4a, 0x19,
293 0x4a, 0x0e, 0x4a, 0x06, 0x4a, 0x07, 0x4a, 0x1a,
294 0x4a, 0x1d, 0x4a, 0x1b, 0x4a, 0x1c, 0x68, 0xf8,
295 0x00, 0x07, 0x7d, 0x3f, 0x69, 0xf8, 0x00, 0x07,
296 0x40, 0x00, 0x68, 0xf8, 0x00, 0x1d, 0xff, 0xfc,
297 0x48, 0x18, 0x68, 0xf8, 0x00, 0x18, 0xff, 0xfe,
298 0xf4, 0x95, 0xf4, 0x95, 0x4a, 0x08, 0xee, 0xff,
299 0x10, 0xf8, 0x2a, 0x5b, 0xf9, 0x80, 0x18, 0x04,
300 0xf0, 0x74, 0x05, 0xa2, 0xee, 0x01, 0x8a, 0x18,
301 0xf4, 0x95, 0x8a, 0x1c, 0x8a, 0x1b, 0x8a, 0x1d,
302 0x8a, 0x1a, 0x8a, 0x07, 0x8a, 0x06, 0x8a, 0x0e,
303 0x8a, 0x19, 0x8a, 0x17, 0x8a, 0x17, 0x8a, 0x16,
304 0x8a, 0x15, 0x8a, 0x14, 0x8a, 0x13, 0x8a, 0x12,
305 0x8a, 0x11, 0x8a, 0x10, 0x8a, 0x0d, 0x8a, 0x0c,
306 0x8a, 0x0b, 0x8a, 0x0a, 0x8a, 0x09, 0x8a, 0x08,
307 0xf4, 0xeb, 0xee, 0xfd, 0x76, 0xf8, 0x2a, 0x38,
308 0x00, 0x00, 0x76, 0xf8, 0x2a, 0x5a, 0x00, 0x00,
309 0xe8, 0x01, 0x4e, 0x00, 0xfb, 0x80, 0x17, 0xd6,
310 0xf4, 0x95, 0xe8, 0x01, 0x80, 0xf8, 0x2a, 0x5b,
311 0x76, 0x00, 0x2a, 0x8f, 0xf9, 0x80, 0x16, 0xaa,
312 0x10, 0xf8, 0x2a, 0x5b, 0xf9, 0x80, 0x17, 0x5c,
313 0x10, 0xf8, 0x2a, 0x5b, 0xf9, 0x80, 0x17, 0x6f,
314 0xfb, 0x80, 0x16, 0x66, 0xf4, 0x95, 0xe8, 0x1a,
315 0xfb, 0x80, 0x16, 0x87, 0xf4, 0x95, 0xe8, 0x1a,
316 0xfb, 0x80, 0x16, 0x66, 0xf4, 0x95, 0xe8, 0x1b,
317 0xfb, 0x80, 0x16, 0x87, 0xf4, 0x95, 0xe8, 0x1b,
318 0xee, 0x03, 0xfc, 0x00, 0x4a, 0x11, 0xf4, 0x95,
319 0x13, 0x02, 0x88, 0x11, 0xe8, 0x00, 0xf8, 0x4d,
320 0x06, 0x6a, 0xf3, 0x10, 0x00, 0x01, 0x89, 0x1a,
321 0xf4, 0x95, 0xf0, 0x72, 0x06, 0x69, 0x1c, 0x91,
322 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0x88, 0x11,
323 0x12, 0x03, 0x11, 0x02, 0xf8, 0x45, 0x06, 0x79,
324 0xf0, 0x10, 0x00, 0x01, 0x88, 0x1a, 0xf4, 0x95,
325 0xf0, 0x72, 0x06, 0x78, 0x81, 0x91, 0x8a, 0x11,
326 0xfc, 0x00, 0x4a, 0x11, 0xf4, 0x95, 0x71, 0x02,
327 0x00, 0x11, 0x11, 0x03, 0x61, 0xf8, 0x00, 0x11,
328 0x00, 0x01, 0xf8, 0x30, 0x06, 0x91, 0xf6, 0xb8,
329 0x6f, 0xf8, 0x00, 0x11, 0x0c, 0x1f, 0x88, 0x11,
330 0xf3, 0xe8, 0xe8, 0xff, 0x18, 0x81, 0xf1, 0xa0,
331 0x81, 0x81, 0xf0, 0x73, 0x06, 0x9d, 0xf6, 0xb8,
332 0x6f, 0xf8, 0x00, 0x11, 0x0c, 0x1f, 0x88, 0x11,
333 0xf3, 0x30, 0x00, 0xff, 0xf0, 0x20, 0xff, 0x00,
334 0x18, 0x81, 0xf1, 0xa0, 0x81, 0x81, 0x8a, 0x11,
335 0xfc, 0x00, 0x4a, 0x11, 0xf4, 0x95, 0x11, 0x02,
336 0x61, 0xf8, 0x00, 0x0b, 0x00, 0x01, 0xf8, 0x20,
337 0x06, 0xb1, 0x49, 0x0b, 0xf6, 0x1f, 0x88, 0x11,
338 0xf4, 0x95, 0xf4, 0x95, 0x10, 0x81, 0xf2, 0x73,
339 0x06, 0xb8, 0xf0, 0x30, 0x00, 0xff, 0x49, 0x0b,
340 0xf6, 0x1f, 0x88, 0x11, 0xf4, 0x95, 0xf4, 0x95,
341 0x12, 0x81, 0xf4, 0x78, 0x8a, 0x11, 0xfc, 0x00,
342 0x4a, 0x11, 0xf4, 0x95, 0x71, 0x02, 0x00, 0x12,
343 0x13, 0x03, 0x88, 0x11, 0xe8, 0x00, 0xf8, 0x4d,
344 0x06, 0xcc, 0xf3, 0x10, 0x00, 0x01, 0x89, 0x1a,
345 0xf4, 0x95, 0xf0, 0x72, 0x06, 0xcb, 0x11, 0x92,
346 0xf2, 0xc0, 0x81, 0x91, 0x8a, 0x11, 0xfc, 0x00,
347 0x88, 0x12, 0x12, 0x02, 0x71, 0x01, 0x00, 0x13,
348 0xf8, 0x45, 0x06, 0xdb, 0xf0, 0x10, 0x00, 0x01,
349 0x88, 0x1a, 0xf4, 0x95, 0xf0, 0x72, 0x06, 0xda,
350 0xe5, 0x98, 0xfc, 0x00, 0x4a, 0x11, 0xee, 0xfe,
351 0x88, 0x11, 0x11, 0x04, 0x10, 0x06, 0x71, 0x05,
352 0x00, 0x12, 0x61, 0xf8, 0x00, 0x12, 0x00, 0x01,
353 0xf8, 0x20, 0x06, 0xea, 0xf0, 0x00, 0x00, 0x01,
354 0xf6, 0xb8, 0xf0, 0x00, 0x00, 0x01, 0x6f, 0xf8,
355 0x00, 0x12, 0x0f, 0x1f, 0x48, 0x08, 0x81, 0x00,
356 0xf4, 0x7f, 0x80, 0x01, 0xf2, 0x74, 0x06, 0xba,
357 0xf4, 0x95, 0x48, 0x11, 0xee, 0x02, 0x8a, 0x11,
358 0xfc, 0x00, 0x4a, 0x11, 0xee, 0xfe, 0x88, 0x12,
359 0x11, 0x04, 0x10, 0x06, 0x71, 0x05, 0x00, 0x13,
360 0x61, 0xf8, 0x00, 0x13, 0x00, 0x01, 0xf8, 0x20,
361 0x07, 0x09, 0xf0, 0x00, 0x00, 0x01, 0xf0, 0x00,
362 0x00, 0x01, 0x88, 0x11, 0xf6, 0xb8, 0x6f, 0xf8,
363 0x00, 0x13, 0x0f, 0x1f, 0x81, 0x00, 0x48, 0x11,
364 0xf4, 0x7f, 0x80, 0x01, 0xf2, 0x74, 0x06, 0xce,
365 0xf4, 0x95, 0x48, 0x12, 0x48, 0x11, 0xf0, 0x30,
366 0xff, 0xfe, 0xee, 0x02, 0x8a, 0x11, 0xfc, 0x00,
367 0x4a, 0x11, 0x4a, 0x16, 0x4a, 0x17, 0xee, 0xfc,
368 0xf4, 0x95, 0x80, 0x02, 0x71, 0x08, 0x00, 0x16,
369 0x10, 0x09, 0x71, 0x0b, 0x00, 0x17, 0x80, 0x03,
370 0x71, 0x0a, 0x00, 0x11, 0x48, 0x17, 0xf8, 0x45,
371 0x07, 0x3f, 0x70, 0x00, 0x00, 0x11, 0x10, 0x03,
372 0xf0, 0x74, 0x06, 0x9f, 0x80, 0x01, 0x70, 0x00,
373 0x00, 0x16, 0x10, 0x02, 0xf0, 0x74, 0x06, 0x7b,
374 0x6d, 0x91, 0x6d, 0x96, 0x6c, 0xef, 0xff, 0xff,
375 0x07, 0x2f, 0xee, 0x04, 0x8a, 0x17, 0x8a, 0x16,
376 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0xee, 0xfe,
377 0x10, 0xf8, 0x2a, 0xe8, 0x08, 0xf8, 0x2a, 0xe9,
378 0xf8, 0x45, 0x07, 0x64, 0x76, 0x00, 0x00, 0x01,
379 0x62, 0xf8, 0x2a, 0xe9, 0x00, 0x5e, 0xf2, 0x74,
380 0x12, 0x0b, 0xf0, 0x00, 0x30, 0x40, 0x72, 0x11,
381 0x2a, 0xe9, 0x77, 0x10, 0x00, 0x0f, 0xf5, 0xa9,
382 0xf8, 0x20, 0x07, 0x61, 0x6b, 0xf8, 0x2a, 0xe9,
383 0x00, 0x01, 0xf0, 0x73, 0x07, 0x64, 0x76, 0xf8,
384 0x2a, 0xe9, 0x00, 0x00, 0xee, 0x02, 0x8a, 0x11,
385 0xfc, 0x00, 0x4a, 0x11, 0x88, 0x11, 0xe8, 0x00,
386 0x75, 0xf8, 0x00, 0x08, 0x00, 0x08, 0xe8, 0x00,
387 0x75, 0xf8, 0x00, 0x08, 0x00, 0x09, 0xf6, 0xb8,
388 0xf4, 0x95, 0xf0, 0x20, 0xfc, 0x3f, 0x75, 0xf8,
389 0x00, 0x08, 0x00, 0x0d, 0xf0, 0x20, 0x0c, 0x30,
390 0x75, 0xf8, 0x00, 0x08, 0x00, 0x0c, 0x76, 0xf8,
391 0x2a, 0xe8, 0x00, 0x00, 0x76, 0xf8, 0x2a, 0xe9,
392 0x00, 0x00, 0x6c, 0x81, 0x07, 0x92, 0x76, 0xf8,
393 0x2a, 0xea, 0x00, 0x00, 0xfb, 0x80, 0x16, 0x76,
394 0xf4, 0x95, 0xe8, 0x10, 0xe8, 0x00, 0x75, 0xf8,
395 0x00, 0x08, 0x00, 0x00, 0xf0, 0x73, 0x07, 0xa8,
396 0x76, 0xf8, 0x2a, 0xea, 0x00, 0x01, 0xfb, 0x80,
397 0x16, 0x66, 0xf4, 0x95, 0xe8, 0x10, 0xfb, 0x80,
398 0x16, 0x87, 0xf4, 0x95, 0xe8, 0x10, 0xe8, 0x00,
399 0x75, 0xf8, 0x00, 0x08, 0x00, 0x00, 0xf6, 0xb8,
400 0xf4, 0x95, 0xf0, 0x20, 0xff, 0xff, 0x75, 0xf8,
401 0x00, 0x08, 0x00, 0x00, 0x8a, 0x11, 0xfc, 0x00,
402 0xf4, 0x95, 0x4a, 0x08, 0x4a, 0x09, 0x4a, 0x0a,
403 0x4a, 0x06, 0x4a, 0x07, 0x4a, 0x1d, 0x68, 0xf8,
404 0x00, 0x07, 0x7d, 0x3f, 0x69, 0xf8, 0x00, 0x07,
405 0x40, 0x00, 0x68, 0xf8, 0x00, 0x1d, 0xff, 0xfc,
406 0x10, 0xf8, 0x2a, 0xea, 0xf8, 0x45, 0x07, 0xe1,
407 0x10, 0xf8, 0x2a, 0xe8, 0xf0, 0x00, 0x00, 0x01,
408 0xf0, 0x30, 0x00, 0x0f, 0x80, 0xf8, 0x2a, 0xe8,
409 0x10, 0xf8, 0x2a, 0xe8, 0xf8, 0x44, 0x07, 0xd6,
410 0xf6, 0xb8, 0xf4, 0x95, 0xf0, 0x20, 0xfc, 0x3f,
411 0x75, 0xf8, 0x00, 0x08, 0x00, 0x0d, 0xf0, 0x20,
412 0x0c, 0x30, 0x75, 0xf8, 0x00, 0x08, 0x00, 0x0c,
413 0xe8, 0x00, 0x75, 0xf8, 0x00, 0x08, 0x00, 0x00,
414 0xf6, 0xb8, 0xf4, 0x95, 0xf0, 0x20, 0xff, 0xff,
415 0x75, 0xf8, 0x00, 0x08, 0x00, 0x00, 0x8a, 0x1d,
416 0x8a, 0x07, 0x8a, 0x06, 0x8a, 0x0a, 0x8a, 0x09,
417 0x8a, 0x08, 0xf4, 0xeb, 0xee, 0xff, 0xf2, 0x74,
418 0x07, 0x67, 0xf4, 0x95, 0xe8, 0x01, 0xee, 0x01,
419 0xfc, 0x00, 0x4a, 0x07, 0x4a, 0x1d, 0x68, 0xf8,
420 0x00, 0x07, 0x7d, 0x3f, 0x69, 0xf8, 0x00, 0x07,
421 0x40, 0x00, 0x68, 0xf8, 0x00, 0x1d, 0xff, 0xfc,
422 0x8a, 0x1d, 0x8a, 0x07, 0xf4, 0xeb, 0x4a, 0x11,
423 0x77, 0x11, 0x00, 0x28, 0x76, 0x81, 0x24, 0x00,
424 0xe8, 0x00, 0x75, 0xf8, 0x00, 0x08, 0x00, 0x01,
425 0xf2, 0x74, 0x07, 0x67, 0xf4, 0x95, 0xe8, 0x00,
426 0x77, 0x11, 0x00, 0x1d, 0x68, 0x81, 0x00, 0x7f,
427 0xf6, 0xb8, 0xf4, 0x95, 0xf0, 0x20, 0xff, 0x80,
428 0x77, 0x11, 0x00, 0x1d, 0xf0, 0x30, 0x01, 0x00,
429 0x1a, 0x81, 0x80, 0x81, 0xf0, 0x74, 0x0a, 0x33,
430 0xf0, 0x74, 0x11, 0xac, 0xf9, 0x80, 0x13, 0x25,
431 0xf9, 0x80, 0x16, 0x53, 0xf9, 0x80, 0x17, 0x82,
432 0xf0, 0x74, 0x06, 0x2f, 0xf9, 0x80, 0x14, 0xb2,
433 0xf9, 0x80, 0x19, 0x10, 0xf0, 0x74, 0x0d, 0xe3,
434 0xf0, 0x74, 0x07, 0xe8, 0xf0, 0x74, 0x02, 0x36,
435 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0x60, 0xf8,
436 0x27, 0x7b, 0xff, 0xff, 0xf8, 0x30, 0x08, 0x39,
437 0x71, 0xf8, 0x27, 0x7b, 0x27, 0x79, 0x60, 0xf8,
438 0x27, 0x79, 0xff, 0xff, 0xf8, 0x30, 0x08, 0xb2,
439 0x10, 0xf8, 0x29, 0x86, 0x08, 0xf8, 0x27, 0x79,
440 0xf0, 0x30, 0x7f, 0xff, 0x88, 0x11, 0xf4, 0x95,
441 0x77, 0x10, 0x40, 0x00, 0xf6, 0xa9, 0xf8, 0x30,
442 0x08, 0x58, 0x10, 0xf8, 0x27, 0x79, 0x08, 0xf8,
443 0x27, 0x7a, 0xf0, 0x30, 0x7f, 0xff, 0x88, 0x11,
444 0xf4, 0x95, 0x77, 0x10, 0x40, 0x00, 0xf6, 0xa9,
445 0xf8, 0x20, 0x08, 0x63, 0x76, 0xf8, 0x27, 0x79,
446 0xff, 0xff, 0x76, 0xf8, 0x27, 0x7b, 0xff, 0xff,
447 0xf7, 0xb8, 0xf2, 0x73, 0x08, 0xd9, 0xf0, 0x20,
448 0xff, 0xff, 0xf6, 0xb8, 0x56, 0xf8, 0x27, 0x74,
449 0xf0, 0xf9, 0x88, 0x11, 0x56, 0xf8, 0x27, 0x72,
450 0xf0, 0xf9, 0x88, 0x12, 0xf4, 0x95, 0xf4, 0x95,
451 0xe7, 0x20, 0xf4, 0xa9, 0xf8, 0x30, 0x08, 0x8f,
452 0xf1, 0x20, 0x27, 0x7c, 0x48, 0x11, 0xf6, 0x00,
453 0x88, 0x13, 0xf4, 0x95, 0xf4, 0x95, 0x10, 0x83,
454 0x08, 0xf8, 0x27, 0x79, 0xf0, 0x30, 0x7f, 0xff,
455 0x88, 0x13, 0xf4, 0x95, 0x77, 0x10, 0x40, 0x00,
456 0xf5, 0xab, 0xf8, 0x30, 0x08, 0x8f, 0x6d, 0x91,
457 0x48, 0x11, 0xf0, 0x30, 0x01, 0xff, 0x88, 0x11,
458 0xf4, 0x95, 0xe7, 0x20, 0xf7, 0xa9, 0xf8, 0x30,
459 0x08, 0x74, 0x6d, 0x89, 0x48, 0x11, 0xf0, 0x30,
460 0x01, 0xff, 0xf0, 0xe7, 0xf4, 0x95, 0x48, 0x08,
461 0x4e, 0xf8, 0x27, 0x74, 0x48, 0x08, 0xf1, 0xf9,
462 0x89, 0x11, 0xf4, 0x95, 0xf4, 0x95, 0x71, 0xe1,
463 0x27, 0x7c, 0x27, 0x7a, 0x60, 0xf8, 0x27, 0x7b,
464 0xff, 0xff, 0xf8, 0x30, 0x08, 0xab, 0x48, 0x08,
465 0x4e, 0xf8, 0x27, 0x72, 0x76, 0xf8, 0x27, 0x7b,
466 0xff, 0xff, 0x76, 0xf8, 0x27, 0x79, 0xff, 0xff,
467 0xf2, 0x73, 0x08, 0xd9, 0xf4, 0x95, 0xe8, 0x00,
468 0x44, 0xf8, 0x27, 0x73, 0x40, 0xf8, 0x27, 0x75,
469 0x82, 0xf8, 0x00, 0x11, 0xf4, 0x95, 0x77, 0x10,
470 0x80, 0x00, 0xf6, 0xa9, 0xf8, 0x20, 0x08, 0xd8,
471 0xf6, 0xb8, 0x10, 0xf8, 0x27, 0x73, 0xf0, 0x00,
472 0x80, 0x00, 0x48, 0x08, 0x4e, 0xf8, 0x27, 0x74,
473 0x48, 0x08, 0xf0, 0xf9, 0x88, 0x11, 0xf4, 0x95,
474 0xf4, 0x95, 0x71, 0xe1, 0x27, 0x7c, 0x27, 0x7a,
475 0xf7, 0xb8, 0x57, 0xf8, 0x27, 0x74, 0xf0, 0x62,
476 0xff, 0xff, 0xf0, 0x40, 0xff, 0x80, 0xf2, 0x80,
477 0x4e, 0xf8, 0x27, 0x74, 0xe8, 0x00, 0x8a, 0x11,
478 0xfc, 0x00, 0x4a, 0x11, 0x4a, 0x16, 0xee, 0xfb,
479 0x11, 0xf8, 0x27, 0x71, 0x09, 0xf8, 0x27, 0x73,
480 0x89, 0x11, 0x88, 0x10, 0xf4, 0x95, 0xf4, 0x95,
481 0xf6, 0xa9, 0xf8, 0x20, 0x08, 0xed, 0xf2, 0x73,
482 0x09, 0x0e, 0xf4, 0x95, 0xe8, 0x00, 0xf6, 0x20,
483 0x76, 0x00, 0x00, 0x41, 0xf0, 0x74, 0x12, 0xee,
484 0x88, 0x16, 0xf4, 0x95, 0xf7, 0xb8, 0x6d, 0x96,
485 0x10, 0xf8, 0x00, 0x16, 0xf8, 0x47, 0x09, 0x0a,
486 0xe7, 0x61, 0x76, 0x00, 0x00, 0x00, 0x76, 0x01,
487 0x00, 0x80, 0x76, 0x02, 0x00, 0xff, 0x76, 0x03,
488 0x00, 0x00, 0xf2, 0x74, 0x0c, 0xb9, 0xf4, 0x95,
489 0xe8, 0x00, 0x6c, 0xe9, 0xff, 0xff, 0x08, 0xfb,
490 0x73, 0x16, 0x00, 0x0e, 0xf0, 0x66, 0x00, 0x41,
491 0xee, 0x05, 0x8a, 0x16, 0x8a, 0x11, 0xfc, 0x00,
492 0x4a, 0x11, 0xf4, 0x95, 0x71, 0x02, 0x00, 0x13,
493 0xf6, 0xb8, 0x77, 0x11, 0x7f, 0xff, 0x57, 0xf8,
494 0x27, 0x72, 0x48, 0x11, 0xf2, 0x80, 0xf0, 0x00,
495 0x80, 0x00, 0x88, 0x11, 0xf6, 0x40, 0xf0, 0xe0,
496 0xf1, 0xf1, 0xe8, 0x01, 0xf2, 0x80, 0x80, 0xf8,
497 0x27, 0x78, 0x77, 0x12, 0x80, 0x00, 0x57, 0xf8,
498 0x27, 0x72, 0x48, 0x12, 0xf2, 0x80, 0x88, 0x12,
499 0xf4, 0x95, 0xf4, 0x95, 0x6c, 0x82, 0x09, 0x38,
500 0xe8, 0x00, 0x75, 0xf8, 0x00, 0x08, 0x00, 0x01,
501 0xf0, 0x73, 0x09, 0x3d, 0xf0, 0x20, 0x80, 0x01,
502 0x75, 0xf8, 0x00, 0x08, 0x00, 0x01, 0x70, 0x81,
503 0x00, 0x13, 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11,
504 0xf0, 0x30, 0x7f, 0xff, 0x11, 0xf8, 0x29, 0x86,
505 0xf5, 0x20, 0xf3, 0x30, 0x7f, 0xff, 0x89, 0x11,
506 0xf4, 0x95, 0x77, 0x10, 0x40, 0x00, 0xf6, 0xa9,
507 0xf8, 0x20, 0x09, 0x54, 0xf2, 0x73, 0x09, 0x67,
508 0xf4, 0x95, 0xe8, 0x02, 0x6f, 0xf8, 0x27, 0x7a,
509 0x0d, 0x20, 0xf3, 0x30, 0x7f, 0xff, 0x89, 0x11,
510 0xf4, 0x95, 0x77, 0x10, 0x40, 0x00, 0xf6, 0xa9,
511 0xf8, 0x20, 0x09, 0x64, 0xf2, 0x73, 0x09, 0x67,
512 0xf4, 0x95, 0xe8, 0x01, 0x80, 0xf8, 0x27, 0x7b,
513 0xe8, 0x00, 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11,
514 0x11, 0xf8, 0x29, 0x86, 0xf5, 0x20, 0xf3, 0x30,
515 0x7f, 0xff, 0x89, 0x11, 0xf4, 0x95, 0x77, 0x10,
516 0x40, 0x00, 0xf6, 0xa9, 0xf8, 0x20, 0x09, 0x7a,
517 0xf2, 0x73, 0x09, 0x8d, 0xf4, 0x95, 0xe8, 0x02,
518 0x6f, 0xf8, 0x27, 0x7a, 0x0d, 0x20, 0xf3, 0x30,
519 0x7f, 0xff, 0x89, 0x11, 0xf4, 0x95, 0x77, 0x10,
520 0x40, 0x00, 0xf6, 0xa9, 0xf8, 0x20, 0x09, 0x8a,
521 0xf2, 0x73, 0x09, 0x8d, 0xf4, 0x95, 0xe8, 0x01,
522 0x80, 0xf8, 0x27, 0x79, 0xe8, 0x00, 0x8a, 0x11,
523 0xfc, 0x00, 0x4a, 0x11, 0xf4, 0x95, 0x71, 0x02,
524 0x00, 0x12, 0x88, 0x11, 0xf6, 0xb8, 0x57, 0xf8,
525 0x27, 0x72, 0xf0, 0x20, 0x7f, 0xff, 0xf2, 0x80,
526 0xf0, 0x00, 0x80, 0x00, 0x80, 0x81, 0x57, 0xf8,
527 0x27, 0x72, 0xe8, 0x01, 0xf3, 0xf1, 0xf2, 0x80,
528 0x80, 0xf8, 0x27, 0x78, 0x77, 0x11, 0x80, 0x00,
529 0x48, 0x11, 0x57, 0xf8, 0x27, 0x72, 0xf2, 0x80,
530 0x88, 0x11, 0xf4, 0x95, 0xf4, 0x95, 0x6c, 0x81,
531 0x09, 0xb5, 0xe8, 0x00, 0x75, 0xf8, 0x00, 0x08,
532 0x00, 0x01, 0xf0, 0x73, 0x09, 0xba, 0xf0, 0x20,
533 0x80, 0x01, 0x75, 0xf8, 0x00, 0x08, 0x00, 0x01,
534 0x45, 0xf8, 0x27, 0x71, 0x43, 0xf8, 0x27, 0x73,
535 0x83, 0xf8, 0x00, 0x11, 0xf4, 0x95, 0xe7, 0x20,
536 0xf6, 0xa9, 0xf8, 0x30, 0x09, 0xc9, 0xf2, 0x73,
537 0x09, 0xe4, 0x77, 0x12, 0x00, 0x00, 0x57, 0xf8,
538 0x27, 0x72, 0xf0, 0x20, 0x7f, 0xff, 0xf2, 0x80,
539 0x49, 0x12, 0xf5, 0x00, 0xf3, 0x00, 0x80, 0x00,
540 0x61, 0xf8, 0x00, 0x0b, 0x80, 0x00, 0xf8, 0x30,
541 0x09, 0xdc, 0xf1, 0x20, 0x80, 0x00, 0xf5, 0x20,
542 0x89, 0x12, 0xf4, 0x95, 0x48, 0x12, 0x6f, 0xf8,
543 0x27, 0x73, 0x0d, 0x00, 0xf4, 0x95, 0x49, 0x0b,
544 0x4f, 0xf8, 0x27, 0x72, 0x8a, 0x11, 0xfe, 0x00,
545 0x48, 0x12, 0xf4, 0x95, 0x4a, 0x11, 0x4a, 0x16,
546 0x4a, 0x17, 0xee, 0xfc, 0xf4, 0x95, 0x71, 0x08,
547 0x00, 0x16, 0x88, 0x17, 0xf0, 0x74, 0x08, 0x30,
548 0x48, 0x18, 0x70, 0x00, 0x00, 0x16, 0xf2, 0x74,
549 0x09, 0x8f, 0xf0, 0x00, 0x00, 0x02, 0x88, 0x11,
550 0xf4, 0x95, 0xf4, 0x95, 0x6c, 0x81, 0x0a, 0x0a,
551 0xf2, 0x74, 0x08, 0xdb, 0xf4, 0x95, 0x48, 0x16,
552 0x48, 0x18, 0x70, 0x00, 0x00, 0x16, 0xf2, 0x74,
553 0x09, 0x8f, 0xf0, 0x00, 0x00, 0x02, 0x88, 0x11,
554 0x10, 0x02, 0x70, 0x01, 0x00, 0x11, 0x80, 0x00,
555 0xf2, 0x74, 0x06, 0xce, 0xf4, 0x95, 0x48, 0x17,
556 0x49, 0x11, 0x48, 0x17, 0xf6, 0x00, 0x88, 0x17,
557 0xe7, 0x60, 0xf5, 0xa9, 0xf8, 0x20, 0x0a, 0x2d,
558 0x48, 0x16, 0xf6, 0x20, 0x88, 0x11, 0x48, 0x18,
559 0x70, 0x00, 0x00, 0x11, 0xf2, 0x74, 0x09, 0x8f,
560 0xf0, 0x00, 0x00, 0x02, 0x88, 0x11, 0x70, 0x01,
561 0x00, 0x11, 0x10, 0x02, 0x80, 0x00, 0xf2, 0x74,
562 0x06, 0xce, 0xf4, 0x95, 0x48, 0x17, 0xee, 0x04,
563 0x48, 0x16, 0x8a, 0x17, 0x8a, 0x16, 0x8a, 0x11,
564 0xfc, 0x00, 0xee, 0xfd, 0xe8, 0x00, 0x4e, 0xf8,
565 0x27, 0x70, 0xe8, 0x00, 0x4e, 0xf8, 0x27, 0x72,
566 0xe8, 0x00, 0x4e, 0xf8, 0x27, 0x74, 0xe8, 0x00,
567 0x4e, 0xf8, 0x27, 0x76, 0x76, 0xf8, 0x27, 0x79,
568 0xff, 0xff, 0x76, 0xf8, 0x27, 0x7a, 0x00, 0x00,
569 0x76, 0xf8, 0x27, 0x7b, 0xff, 0xff, 0x76, 0xf8,
570 0x27, 0x78, 0x00, 0x00, 0xe8, 0x00, 0x75, 0xf8,
571 0x00, 0x08, 0x00, 0x01, 0x76, 0x00, 0x00, 0x00,
572 0x76, 0x01, 0x02, 0x00, 0xf2, 0x74, 0x12, 0xdc,
573 0xf0, 0x20, 0x27, 0x7c, 0xee, 0x03, 0xfc, 0x00,
574 0x4a, 0x11, 0xee, 0xfc, 0xf4, 0x95, 0x4e, 0x00,
575 0x77, 0x12, 0x7f, 0xff, 0xf6, 0xb8, 0x49, 0x12,
576 0xf1, 0x80, 0xf3, 0x00, 0x80, 0x00, 0x89, 0x12,
577 0xf0, 0xe0, 0xf1, 0xf1, 0x4f, 0x02, 0xe9, 0x01,
578 0xf4, 0x95, 0x48, 0x0b, 0xf5, 0x40, 0x56, 0x02,
579 0xf1, 0x80, 0x81, 0xf8, 0x27, 0x78, 0x77, 0x11,
580 0x80, 0x00, 0x56, 0x00, 0x49, 0x11, 0xf1, 0x80,
581 0x89, 0x11, 0xf4, 0x95, 0xf4, 0x95, 0x6c, 0x81,
582 0x0a, 0x81, 0xe8, 0x00, 0x75, 0xf8, 0x00, 0x08,
583 0x00, 0x01, 0xf0, 0x73, 0x0a, 0x86, 0xf0, 0x20,
584 0x80, 0x01, 0x75, 0xf8, 0x00, 0x08, 0x00, 0x01,
585 0x10, 0x82, 0xee, 0x04, 0x8a, 0x11, 0xfc, 0x00,
586 0x4a, 0x11, 0xee, 0xfe, 0xf4, 0x95, 0x4e, 0x00,
587 0x77, 0x11, 0x7f, 0xff, 0xf6, 0xb8, 0x49, 0x11,
588 0xf1, 0x80, 0xf3, 0x00, 0x80, 0x00, 0x89, 0x11,
589 0xf0, 0xe0, 0xf1, 0xf1, 0xe8, 0x01, 0xf2, 0x80,
590 0x80, 0xf8, 0x27, 0x78, 0x56, 0x00, 0xf1, 0x20,
591 0x80, 0x00, 0xf1, 0x80, 0xf4, 0x95, 0x49, 0x0b,
592 0xf8, 0x4d, 0x0a, 0xab, 0xf0, 0x20, 0x80, 0x01,
593 0x75, 0xf8, 0x00, 0x08, 0x00, 0x01, 0xf0, 0x73,
594 0x0a, 0xaf, 0xe8, 0x00, 0x75, 0xf8, 0x00, 0x08,
595 0x00, 0x01, 0xee, 0x02, 0x48, 0x11, 0x8a, 0x11,
596 0xfc, 0x00, 0x4a, 0x11, 0x88, 0x12, 0x13, 0x02,
597 0x77, 0x11, 0x00, 0x00, 0xf8, 0x4d, 0x0a, 0xcb,
598 0xf3, 0x10, 0x00, 0x01, 0x89, 0x1a, 0xf4, 0x95,
599 0xf0, 0x72, 0x0a, 0xca, 0x48, 0x11, 0x1c, 0xf8,
600 0x29, 0x7e, 0x88, 0x11, 0x11, 0xf8, 0x29, 0x7e,
601 0xf2, 0x00, 0x00, 0x01, 0x80, 0xf8, 0x29, 0x7e,
602 0x81, 0x92, 0x48, 0x11, 0x8a, 0x11, 0xfc, 0x00,
603 0x4a, 0x11, 0xf4, 0x95, 0x71, 0x02, 0x00, 0x11,
604 0x88, 0x12, 0xf6, 0xb8, 0xf0, 0x20, 0x7f, 0xff,
605 0x57, 0xf8, 0x27, 0x70, 0xf2, 0x80, 0xf0, 0x00,
606 0x80, 0x00, 0x80, 0x82, 0x57, 0xf8, 0x27, 0x70,
607 0xe8, 0x01, 0xf3, 0xf1, 0xf2, 0x80, 0x80, 0xf8,
608 0x27, 0x78, 0x77, 0x12, 0x80, 0x00, 0x48, 0x12,
609 0x57, 0xf8, 0x27, 0x70, 0xf2, 0x80, 0x88, 0x12,
610 0xf4, 0x95, 0xf4, 0x95, 0x6c, 0x82, 0x0a, 0xf4,
611 0xe8, 0x00, 0x75, 0xf8, 0x00, 0x08, 0x00, 0x01,
612 0xf0, 0x73, 0x0a, 0xf9, 0xf0, 0x20, 0x80, 0x01,
613 0x75, 0xf8, 0x00, 0x08, 0x00, 0x01, 0x45, 0xf8,
614 0x27, 0x75, 0xe7, 0x10, 0x43, 0xf8, 0x27, 0x71,
615 0x83, 0xf8, 0x00, 0x12, 0x6d, 0xe8, 0x00, 0x04,
616 0x6d, 0x8a, 0xf6, 0xaa, 0xf8, 0x30, 0x0b, 0x0a,
617 0xf2, 0x73, 0x0b, 0x25, 0x77, 0x11, 0x00, 0x00,
618 0x57, 0xf8, 0x27, 0x70, 0xf0, 0x20, 0x7f, 0xff,
619 0xf2, 0x80, 0x49, 0x11, 0xf5, 0x00, 0xf3, 0x00,
620 0x80, 0x00, 0x61, 0xf8, 0x00, 0x0b, 0x80, 0x00,
621 0xf8, 0x30, 0x0b, 0x1d, 0xf1, 0x20, 0x80, 0x00,
622 0xf5, 0x20, 0x89, 0x11, 0xf4, 0x95, 0x48, 0x11,
623 0x6f, 0xf8, 0x27, 0x71, 0x0d, 0x00, 0xf4, 0x95,
624 0x49, 0x0b, 0x4f, 0xf8, 0x27, 0x70, 0x48, 0x11,
625 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0x4a, 0x16,
626 0x4a, 0x17, 0xee, 0xf0, 0x88, 0x17, 0x10, 0x17,
627 0x80, 0x05, 0x10, 0x16, 0x80, 0x06, 0x10, 0x15,
628 0x80, 0x07, 0x71, 0x14, 0x00, 0x11, 0x10, 0x05,
629 0xf0, 0x30, 0x00, 0x01, 0x88, 0x10, 0x10, 0x06,
630 0xf0, 0x30, 0x00, 0x01, 0x80, 0x08, 0x49, 0x11,
631 0x10, 0x05, 0xf6, 0x01, 0x80, 0x09, 0x10, 0x06,
632 0x61, 0xf8, 0x00, 0x08, 0x00, 0x01, 0xf8, 0x20,
633 0x0b, 0x4b, 0x10, 0x09, 0xf0, 0x00, 0x00, 0x01,
634 0x80, 0x09, 0x71, 0x08, 0x00, 0x12, 0xf4, 0xaa,
635 0xf8, 0x30, 0x0b, 0x54, 0x10, 0x09, 0xf0, 0x00,
636 0x00, 0x01, 0x80, 0x09, 0x12, 0x09, 0x49, 0x11,
637 0xf4, 0x7f, 0x80, 0x09, 0xf6, 0x20, 0x80, 0x0a,
638 0x56, 0xf8, 0x27, 0x70, 0x4e, 0x0c, 0x10, 0x09,
639 0x80, 0x00, 0x48, 0x18, 0xf2, 0x74, 0x0a, 0xce,
640 0xf0, 0x00, 0x00, 0x04, 0x88, 0x16, 0xf4, 0x95,
641 0xf4, 0x95, 0x6c, 0x86, 0x0b, 0x6d, 0xf2, 0x73,
642 0x0c, 0x59, 0xf4, 0x95, 0xe8, 0x00, 0xf6, 0xb8,
643 0xf4, 0x95, 0x56, 0x0c, 0xf0, 0xf9, 0x88, 0x12,
644 0xf4, 0x95, 0xf4, 0x95, 0x70, 0xe2, 0x27, 0x7c,
645 0x29, 0x86, 0xe8, 0x00, 0x80, 0x0e, 0x48, 0x11,
646 0xf8, 0x45, 0x0b, 0xcc, 0x77, 0x10, 0x00, 0x01,
647 0xf4, 0xa9, 0xf8, 0x30, 0x0b, 0x89, 0x6c, 0xe1,
648 0xff, 0xfd, 0x0b, 0x8b, 0x10, 0xe7, 0x00, 0x02,
649 0x80, 0x0e, 0xf0, 0x73, 0x0b, 0x8b, 0x10, 0x87,
650 0x80, 0x0e, 0xe7, 0x10, 0xf5, 0xae, 0xf8, 0x20,
651 0x0b, 0xb2, 0x70, 0x00, 0x00, 0x17, 0x70, 0x01,
652 0x00, 0x16, 0x10, 0x04, 0xf0, 0x74, 0x06, 0xce,
653 0x48, 0x17, 0x49, 0x16, 0xf6, 0x00, 0x88, 0x17,
654 0x48, 0x11, 0xf6, 0x20, 0x88, 0x11, 0x10, 0x09,
655 0xf6, 0x20, 0x80, 0x00, 0x48, 0x18, 0xf2, 0x74,
656 0x0a, 0xce, 0xf0, 0x00, 0x00, 0x04, 0x88, 0x16,
657 0x10, 0x04, 0x70, 0x00, 0x00, 0x17, 0x70, 0x01,
658 0x00, 0x11, 0xf0, 0x74, 0x06, 0xce, 0x48, 0x11,
659 0x00, 0x04, 0x80, 0x04, 0xf0, 0x73, 0x0b, 0xbc,
660 0x70, 0x00, 0x00, 0x17, 0x70, 0x01, 0x00, 0x11,
661 0x10, 0x04, 0xf0, 0x74, 0x06, 0xce, 0x48, 0x11,
662 0x00, 0x04, 0x80, 0x04, 0x49, 0x11, 0x48, 0x16,
663 0xf6, 0x20, 0x88, 0x16, 0xf4, 0x95, 0xf4, 0x95,
664 0x6c, 0x86, 0x0b, 0xcc, 0x10, 0x0a, 0x80, 0x00,
665 0x48, 0x18, 0xf2, 0x74, 0x0a, 0xce, 0xf0, 0x00,
666 0x00, 0x04, 0x88, 0x16, 0x12, 0x0a, 0xf8, 0x45,
667 0x0c, 0x33, 0x71, 0x0a, 0x00, 0x10, 0xf4, 0xae,
668 0xf8, 0x30, 0x0c, 0x1c, 0x48, 0x16, 0xf0, 0xe1,
669 0x88, 0x11, 0x12, 0x08, 0xf8, 0x45, 0x0b, 0xdb,
670 0x6d, 0x89, 0x12, 0x07, 0xf8, 0x45, 0x0b, 0xe9,
671 0x10, 0x07, 0x80, 0x00, 0x70, 0x02, 0x00, 0x11,
672 0x10, 0x06, 0x80, 0x01, 0x10, 0x04, 0xf0, 0x74,
673 0x06, 0xdc, 0xf0, 0x73, 0x0b, 0xef, 0x48, 0x11,
674 0x6f, 0x00, 0x0c, 0x9f, 0x10, 0x04, 0xf0, 0x74,
675 0x0a, 0xb3, 0x11, 0x0e, 0xf1, 0xc0, 0x81, 0x0e,
676 0x10, 0x06, 0x49, 0x11, 0xf6, 0x00, 0x80, 0x06,
677 0x10, 0x05, 0xf6, 0x20, 0x88, 0x11, 0xf0, 0x00,
678 0x00, 0x01, 0x48, 0x08, 0x6f, 0x00, 0x0c, 0x9f,
679 0x48, 0x18, 0xf2, 0x74, 0x0a, 0xce, 0xf0, 0x00,
680 0x00, 0x04, 0x12, 0x07, 0xf8, 0x45, 0x0c, 0x11,
681 0x10, 0x07, 0x80, 0x00, 0x70, 0x02, 0x00, 0x11,
682 0x10, 0x06, 0x80, 0x01, 0x10, 0x04, 0xf0, 0x74,
683 0x06, 0xdc, 0xf0, 0x73, 0x0c, 0x17, 0x48, 0x11,
684 0x6f, 0x00, 0x0c, 0x9f, 0x10, 0x04, 0xf0, 0x74,
685 0x0a, 0xb3, 0x11, 0x0e, 0xf1, 0xc0, 0x81, 0x0e,
686 0xf0, 0x73, 0x0c, 0x33, 0x12, 0x07, 0xf8, 0x45,
687 0x0c, 0x2a, 0x10, 0x07, 0x80, 0x00, 0x10, 0x06,
688 0x80, 0x01, 0x10, 0x05, 0x80, 0x02, 0x10, 0x04,
689 0xf0, 0x74, 0x06, 0xdc, 0xf0, 0x73, 0x0c, 0x30,
690 0x12, 0x05, 0x6f, 0x00, 0x0c, 0x9f, 0x10, 0x04,
691 0xf0, 0x74, 0x0a, 0xb3, 0x11, 0x0e, 0xf1, 0xc0,
692 0x81, 0x0e, 0x76, 0x00, 0x00, 0x01, 0x48, 0x18,
693 0xf2, 0x74, 0x0a, 0xce, 0xf0, 0x00, 0x00, 0x04,
694 0x71, 0x04, 0x00, 0x11, 0x70, 0x81, 0x29, 0x86,
695 0x10, 0x0e, 0x1c, 0xf8, 0x29, 0x86, 0x80, 0x0e,
696 0x76, 0x00, 0x00, 0x01, 0x48, 0x18, 0xf2, 0x74,
697 0x0a, 0xce, 0xf0, 0x00, 0x00, 0x04, 0x10, 0x0e,
698 0x71, 0x04, 0x00, 0x11, 0x80, 0x81, 0x10, 0xf8,
699 0x29, 0x86, 0xf0, 0x00, 0x00, 0x01, 0xf0, 0x30,
700 0x7f, 0xff, 0x80, 0xf8, 0x29, 0x86, 0x10, 0x09,
701 0xf0, 0x00, 0x00, 0x02, 0x80, 0x09, 0xee, 0x10,
702 0x8a, 0x17, 0x8a, 0x16, 0x8a, 0x11, 0xfc, 0x00,
703 0x10, 0xf8, 0x27, 0x75, 0x08, 0xf8, 0x27, 0x71,
704 0xf0, 0x10, 0x00, 0x01, 0x48, 0x08, 0xfc, 0x00,
705 0x4a, 0x11, 0x4a, 0x16, 0xee, 0xff, 0xf4, 0x95,
706 0x71, 0x04, 0x00, 0x16, 0xf0, 0x00, 0x00, 0x01,
707 0x48, 0x08, 0x4e, 0xf8, 0x29, 0x7c, 0x6d, 0xee,
708 0xff, 0xfd, 0x48, 0x16, 0xf8, 0x45, 0x0c, 0x99,
709 0x56, 0xf8, 0x29, 0x7c, 0xf0, 0x74, 0x0a, 0x5a,
710 0x88, 0x11, 0x10, 0xf8, 0x29, 0x7d, 0xf0, 0x00,
711 0x00, 0x01, 0x48, 0x08, 0x4e, 0xf8, 0x29, 0x7c,
712 0x10, 0xf8, 0x29, 0x82, 0xf0, 0x00, 0x00, 0x01,
713 0x88, 0x10, 0xf4, 0x95, 0xf4, 0x95, 0xf4, 0xa9,
714 0xfa, 0x30, 0x0c, 0x96, 0x80, 0xf8, 0x29, 0x82,
715 0x56, 0xf8, 0x29, 0x80, 0xf0, 0x00, 0x00, 0x01,
716 0x4e, 0xf8, 0x29, 0x80, 0x73, 0x11, 0x29, 0x82,
717 0x6c, 0xee, 0xff, 0xff, 0x0c, 0x76, 0xee, 0x01,
718 0x8a, 0x16, 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11,
719 0x76, 0xf8, 0x29, 0x84, 0x00, 0x00, 0x76, 0xf8,
720 0x29, 0x85, 0x00, 0x01, 0xe8, 0x00, 0x4e, 0xf8,
721 0x2a, 0x0c, 0x76, 0xf8, 0x29, 0x86, 0x00, 0x00,
722 0x76, 0xf8, 0x29, 0x87, 0x00, 0x00, 0x77, 0x11,
723 0x29, 0x88, 0x76, 0x81, 0xaa, 0xaa, 0x76, 0xe1,
724 0x00, 0x01, 0xaa, 0xaa, 0x76, 0xe1, 0x00, 0x02,
725 0x00, 0x00, 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11,
726 0xee, 0xfc, 0xf4, 0x95, 0x71, 0x06, 0x00, 0x14,
727 0x71, 0x07, 0x00, 0x13, 0x71, 0x08, 0x00, 0x12,
728 0x71, 0x09, 0x00, 0x15, 0x77, 0x10, 0x00, 0xff,
729 0xf4, 0xaa, 0xf8, 0x30, 0x0d, 0x44, 0x49, 0x13,
730 0x53, 0xf8, 0x2a, 0x0c, 0x4f, 0xf8, 0x2a, 0x0c,
731 0x73, 0x12, 0x00, 0x0e, 0xf1, 0x66, 0x00, 0x0d,
732 0x89, 0x11, 0xf4, 0x95, 0x77, 0x10, 0x00, 0x01,
733 0x71, 0xe1, 0x24, 0x00, 0x00, 0x11, 0xf4, 0xa9,
734 0xf8, 0x30, 0x0d, 0x17, 0x77, 0x10, 0x00, 0x02,
735 0xf4, 0xa9, 0xf8, 0x30, 0x0c, 0xec, 0x77, 0x11,
736 0x29, 0x8a, 0x76, 0x81, 0x00, 0x00, 0xe8, 0x00,
737 0x77, 0x14, 0x00, 0x00, 0x77, 0x13, 0x00, 0x00,
738 0xf0, 0x73, 0x0d, 0x48, 0x6c, 0x83, 0x0c, 0xfa,
739 0x77, 0x11, 0x29, 0x8a, 0x48, 0x12, 0xf0, 0xe8,
740 0xf0, 0x40, 0x80, 0x00, 0x80, 0x81, 0xe8, 0x00,
741 0x77, 0x14, 0x00, 0x00, 0xf0, 0x73, 0x0d, 0x48,
742 0x49, 0x13, 0xf3, 0x40, 0x80, 0x00, 0x81, 0xf8,
743 0x29, 0x8a, 0x61, 0xf8, 0x00, 0x15, 0x00, 0x01,
744 0xf8, 0x20, 0x0d, 0x07, 0x69, 0xf8, 0x29, 0x8a,
745 0x40, 0x00, 0x61, 0xf8, 0x00, 0x14, 0x00, 0x01,
746 0xf8, 0x20, 0x0d, 0x0f, 0x69, 0xf8, 0x29, 0x8a,
747 0x20, 0x00, 0x77, 0x11, 0x29, 0x8a, 0x49, 0x12,
748 0xf3, 0xe8, 0x1b, 0x81, 0x81, 0x81, 0xf0, 0x73,
749 0x0d, 0x48, 0x11, 0xf8, 0x29, 0x84, 0xf8, 0x4c,
750 0x0d, 0x37, 0x77, 0x11, 0x29, 0x88, 0x76, 0x81,
751 0xaa, 0xaa, 0x11, 0xf8, 0x29, 0x85, 0xf3, 0x10,
752 0x00, 0x01, 0xf3, 0x40, 0xaa, 0x00, 0x81, 0xe1,
753 0x00, 0x01, 0x76, 0x00, 0x00, 0x02, 0x80, 0x01,
754 0x70, 0x02, 0x00, 0x14, 0x70, 0x03, 0x00, 0x13,
755 0xf2, 0x74, 0x0b, 0x28, 0xf4, 0x95, 0x48, 0x11,
756 0x71, 0xf8, 0x29, 0x85, 0x29, 0x84, 0xf0, 0x73,
757 0x0d, 0x73, 0x76, 0x00, 0x00, 0x00, 0x80, 0x01,
758 0x76, 0x02, 0x00, 0x00, 0x70, 0x03, 0x00, 0x13,
759 0xf2, 0x74, 0x0b, 0x28, 0xf4, 0x95, 0xe8, 0x00,
760 0xf0, 0x73, 0x0d, 0x73, 0x77, 0x11, 0x29, 0x8a,
761 0x70, 0x81, 0x00, 0x13, 0x11, 0xf8, 0x29, 0x84,
762 0xf8, 0x4c, 0x0d, 0x68, 0x77, 0x11, 0x29, 0x88,
763 0x76, 0x81, 0xaa, 0xaa, 0x11, 0xf8, 0x29, 0x85,
764 0xf3, 0x10, 0x00, 0x01, 0xf3, 0x40, 0xaa, 0x00,
765 0x81, 0xe1, 0x00, 0x01, 0x76, 0x00, 0x00, 0x03,
766 0x80, 0x01, 0x70, 0x02, 0x00, 0x14, 0x70, 0x03,
767 0x00, 0x13, 0xf2, 0x74, 0x0b, 0x28, 0xf4, 0x95,
768 0x48, 0x11, 0x71, 0xf8, 0x29, 0x85, 0x29, 0x84,
769 0xf0, 0x73, 0x0d, 0x73, 0x76, 0x00, 0x00, 0x01,
770 0x80, 0x01, 0x70, 0x02, 0x00, 0x14, 0x70, 0x03,
771 0x00, 0x13, 0xf2, 0x74, 0x0b, 0x28, 0xf4, 0x95,
772 0x48, 0x11, 0x6b, 0xf8, 0x29, 0x84, 0xff, 0xff,
773 0xee, 0x04, 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11,
774 0xf5, 0x40, 0xf4, 0x95, 0x48, 0x0b, 0xf4, 0x78,
775 0x88, 0x11, 0xf4, 0x95, 0xf4, 0x95, 0x6c, 0xe1,
776 0xff, 0xb9, 0x0d, 0x88, 0xf2, 0x73, 0x0d, 0xa5,
777 0xf4, 0x95, 0xe8, 0x60, 0xf2, 0x00, 0x00, 0x06,
778 0x61, 0xf8, 0x00, 0x11, 0x00, 0x20, 0xf8, 0x30,
779 0x0d, 0x98, 0x61, 0xf8, 0x00, 0x0b, 0x00, 0x01,
780 0xf8, 0x20, 0x0d, 0xa3, 0xf2, 0x00, 0x00, 0x07,
781 0xf0, 0x73, 0x0d, 0xa3, 0x61, 0xf8, 0x00, 0x0b,
782 0x00, 0x01, 0xf8, 0x20, 0x0d, 0xa1, 0xf2, 0x73,
783 0x0d, 0xa3, 0xf0, 0x00, 0x00, 0x01, 0xf0, 0x00,
784 0x00, 0x02, 0x48, 0x08, 0xf4, 0x7f, 0x8a, 0x11,
785 0xfc, 0x00, 0xee, 0xff, 0xf0, 0x74, 0x07, 0xfd,
786 0xf0, 0x74, 0x07, 0x44, 0xf0, 0x74, 0x0d, 0xb4,
787 0xf0, 0x74, 0x02, 0x05, 0xf0, 0x74, 0x04, 0x60,
788 0xf0, 0x73, 0x0d, 0xaa, 0xee, 0xfd, 0x10, 0xf8,
789 0x2a, 0xa3, 0xf8, 0x44, 0x0d, 0xcb, 0x10, 0xf8,
790 0x2a, 0xa4, 0xf8, 0x45, 0x0d, 0xd7, 0x76, 0x00,
791 0x02, 0x00, 0xf2, 0x74, 0x09, 0xe8, 0xf0, 0x20,
792 0x22, 0x00, 0x76, 0xf8, 0x2a, 0xa4, 0x00, 0x00,
793 0x76, 0xf8, 0x2a, 0xa7, 0x00, 0x00, 0xf0, 0x73,
794 0x0d, 0xd7, 0x76, 0x00, 0x02, 0x00, 0xf2, 0x74,
795 0x09, 0xe8, 0xf0, 0x20, 0x20, 0x00, 0x76, 0xf8,
796 0x2a, 0xa3, 0x00, 0x00, 0x76, 0xf8, 0x2a, 0xa7,
797 0x00, 0x01, 0xf0, 0x74, 0x0c, 0x5e, 0xf0, 0xe0,
798 0xf0, 0x10, 0x3a, 0x98, 0xf8, 0x47, 0x0d, 0xe1,
799 0x76, 0xf8, 0x27, 0x6e, 0x00, 0x00, 0xee, 0x03,
800 0xfc, 0x00, 0x4a, 0x11, 0xee, 0xfe, 0x77, 0x11,
801 0x20, 0x00, 0x76, 0x00, 0xaa, 0xaa, 0x76, 0x01,
802 0x02, 0x00, 0xf2, 0x74, 0x06, 0x6c, 0xf4, 0x95,
803 0x48, 0x11, 0x76, 0x00, 0x55, 0x55, 0x76, 0x01,
804 0x02, 0x00, 0x48, 0x11, 0xf2, 0x74, 0x06, 0x6c,
805 0xf0, 0x00, 0x02, 0x00, 0x76, 0xf8, 0x2a, 0xa3,
806 0x00, 0x00, 0x76, 0xf8, 0x2a, 0xa4, 0x00, 0x00,
807 0xe8, 0x00, 0x4e, 0x00, 0xfb, 0x80, 0x15, 0x3e,
808 0xf4, 0x95, 0xe8, 0x04, 0x80, 0xf8, 0x2a, 0xa5,
809 0x76, 0x00, 0x2a, 0xa8, 0xf9, 0x80, 0x14, 0x87,
810 0x76, 0x00, 0x2a, 0xad, 0xfb, 0x80, 0x13, 0x62,
811 0xf4, 0x95, 0xe8, 0x02, 0x10, 0xf8, 0x2a, 0xa5,
812 0xf9, 0x80, 0x14, 0x63, 0xfb, 0x80, 0x16, 0x66,
813 0xf4, 0x95, 0xe8, 0x1c, 0xfb, 0x80, 0x16, 0x87,
814 0xf4, 0x95, 0xe8, 0x1c, 0xe8, 0x01, 0x4e, 0x00,
815 0xfb, 0x80, 0x17, 0xd6, 0xf4, 0x95, 0xe8, 0x00,
816 0x80, 0xf8, 0x2a, 0xa6, 0x76, 0x00, 0x2a, 0xb7,
817 0xf9, 0x80, 0x16, 0xaa, 0x10, 0xf8, 0x2a, 0xa6,
818 0xf9, 0x80, 0x17, 0x5c, 0x10, 0xf8, 0x2a, 0xa6,
819 0xf9, 0x80, 0x17, 0x6f, 0xee, 0x02, 0x8a, 0x11,
820 0xfc, 0x00, 0xf4, 0x95, 0x4a, 0x08, 0x4a, 0x09,
821 0x4a, 0x0a, 0x4a, 0x07, 0x4a, 0x1d, 0x68, 0xf8,
822 0x00, 0x07, 0x7d, 0x3f, 0x69, 0xf8, 0x00, 0x07,
823 0x40, 0x00, 0x68, 0xf8, 0x00, 0x1d, 0xff, 0xfc,
824 0x10, 0xf8, 0x2a, 0xa7, 0xf8, 0x44, 0x0e, 0x4b,
825 0x76, 0xf8, 0x2a, 0xa3, 0x00, 0x01, 0xf0, 0x73,
826 0x0e, 0x4e, 0x76, 0xf8, 0x2a, 0xa4, 0x00, 0x01,
827 0x8a, 0x1d, 0x8a, 0x07, 0x8a, 0x0a, 0x8a, 0x09,
828 0x8a, 0x08, 0xf4, 0xeb, 0x4a, 0x11, 0x4a, 0x16,
829 0x4a, 0x17, 0xee, 0xfe, 0x88, 0x0e, 0x71, 0x08,
830 0x00, 0x16, 0x71, 0x06, 0x00, 0x17, 0x11, 0x07,
831 0xf0, 0x66, 0x00, 0x0d, 0xf0, 0x00, 0x25, 0xa0,
832 0x88, 0x11, 0x76, 0x01, 0x00, 0x06, 0x81, 0x00,
833 0xf2, 0x74, 0x06, 0xce, 0xf0, 0x00, 0x00, 0x01,
834 0x76, 0x01, 0x00, 0x06, 0x70, 0x00, 0x00, 0x16,
835 0x48, 0x11, 0xf2, 0x74, 0x06, 0xce, 0xf0, 0x00,
836 0x00, 0x07, 0x70, 0x81, 0x00, 0x17, 0xee, 0x02,
837 0x8a, 0x17, 0x8a, 0x16, 0x8a, 0x11, 0xfc, 0x00,
838 0x4a, 0x11, 0x88, 0x0e, 0x71, 0x02, 0x00, 0x12,
839 0x11, 0x03, 0xf0, 0x66, 0x00, 0x0d, 0xf0, 0x00,
840 0x24, 0x00, 0x88, 0x11, 0xf4, 0x95, 0x70, 0x81,
841 0x00, 0x12, 0x6e, 0xe2, 0xff, 0xfe, 0x0e, 0x8d,
842 0xf4, 0x95, 0xe8, 0x00, 0xe8, 0x01, 0x80, 0xe1,
843 0x00, 0x02, 0x76, 0xe1, 0x00, 0x03, 0x00, 0xff,
844 0x76, 0xe1, 0x00, 0x04, 0x00, 0x00, 0x76, 0xe1,
845 0x00, 0x0b, 0x00, 0x00, 0x76, 0xe1, 0x00, 0x0c,
846 0x00, 0x00, 0x81, 0xe1, 0x00, 0x01, 0x8a, 0x11,
847 0xfc, 0x00, 0x4a, 0x11, 0xee, 0xfc, 0x88, 0x0e,
848 0xf4, 0x95, 0xf1, 0x66, 0x00, 0x0d, 0xf3, 0x00,
849 0x24, 0x00, 0x89, 0x11, 0xf4, 0x95, 0xf4, 0x95,
850 0x76, 0xe1, 0x00, 0x0c, 0x00, 0x00, 0x76, 0xe1,
851 0x00, 0x0b, 0x00, 0x00, 0x76, 0xe1, 0x00, 0x02,
852 0x00, 0x01, 0x76, 0x00, 0x00, 0x00, 0x76, 0x01,
853 0x00, 0x00, 0x80, 0x02, 0x76, 0x03, 0x00, 0x00,
854 0xf2, 0x74, 0x0c, 0xb9, 0xf4, 0x95, 0xe8, 0x00,
855 0xee, 0x04, 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11,
856 0x88, 0x19, 0xf4, 0x95, 0x73, 0x19, 0x00, 0x0e,
857 0xf1, 0x66, 0x00, 0x0d, 0xf2, 0x00, 0x24, 0x00,
858 0x77, 0x15, 0x25, 0xa0, 0x77, 0x14, 0x00, 0x00,
859 0x77, 0x1a, 0x00, 0x1f, 0xf0, 0x72, 0x0f, 0x14,
860 0xf6, 0xb8, 0x49, 0x19, 0x09, 0x85, 0xf8, 0x4c,
861 0x0f, 0x13, 0xf1, 0x00, 0x00, 0x05, 0x89, 0x11,
862 0x49, 0x15, 0xf3, 0x00, 0x00, 0x01, 0x89, 0x13,
863 0x49, 0x15, 0xf3, 0x00, 0x00, 0x07, 0x89, 0x12,
864 0x11, 0x93, 0x1d, 0x91, 0x19, 0x92, 0x89, 0x10,
865 0xf4, 0x95, 0xf4, 0x95, 0x6c, 0x80, 0x0f, 0x13,
866 0x11, 0x93, 0x1d, 0x91, 0x19, 0x92, 0x89, 0x10,
867 0xf4, 0x95, 0xf4, 0x95, 0x6c, 0x80, 0x0f, 0x13,
868 0x11, 0x93, 0x1d, 0x91, 0x19, 0x92, 0x89, 0x10,
869 0xf4, 0x95, 0xf4, 0x95, 0x6c, 0x80, 0x0f, 0x13,
870 0x11, 0x93, 0x1d, 0x91, 0x19, 0x92, 0x89, 0x10,
871 0xf4, 0x95, 0xf4, 0x95, 0x6c, 0x80, 0x0f, 0x13,
872 0x11, 0x93, 0x1d, 0x91, 0x19, 0x92, 0x89, 0x10,
873 0xf4, 0x95, 0xf4, 0x95, 0x6c, 0x80, 0x0f, 0x13,
874 0x11, 0x93, 0x1d, 0x91, 0x19, 0x92, 0x89, 0x11,
875 0xf4, 0x95, 0xf4, 0x95, 0x6c, 0x81, 0x0f, 0x13,
876 0x6d, 0x94, 0x6d, 0xed, 0x00, 0x0d, 0x48, 0x14,
877 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0x4a, 0x16,
878 0x4a, 0x17, 0xee, 0xf8, 0x88, 0x17, 0x10, 0x0d,
879 0x80, 0x04, 0x10, 0x0c, 0x80, 0x05, 0x71, 0x0e,
880 0x00, 0x16, 0x73, 0x17, 0x00, 0x0e, 0xf0, 0x66,
881 0x00, 0x0d, 0xf0, 0x00, 0x24, 0x00, 0x88, 0x11,
882 0x10, 0xf8, 0x27, 0x63, 0xf8, 0x45, 0x0f, 0x32,
883 0xf2, 0x74, 0x0e, 0x9f, 0xf4, 0x95, 0x48, 0x17,
884 0x10, 0xf8, 0x27, 0x60, 0xf8, 0x44, 0x0f, 0x3d,
885 0x60, 0xe1, 0x00, 0x02, 0x00, 0x01, 0xf8, 0x20,
886 0x0f, 0x6d, 0xf0, 0x73, 0x11, 0x33, 0x10, 0x04,
887 0x80, 0x00, 0x10, 0x05, 0xf0, 0x74, 0x06, 0x9f,
888 0x11, 0x04, 0xf3, 0x00, 0x00, 0x01, 0x81, 0x04,
889 0x6d, 0x8e, 0x77, 0x10, 0x00, 0x01, 0x71, 0xe1,
890 0x00, 0x02, 0x00, 0x12, 0xf4, 0xaa, 0xf8, 0x30,
891 0x0f, 0x62, 0x77, 0x10, 0x00, 0x02, 0xf4, 0xaa,
892 0xf8, 0x30, 0x0f, 0x6d, 0x45, 0xe1, 0x00, 0x0b,
893 0x88, 0x10, 0x43, 0xe1, 0x00, 0x0c, 0x83, 0xf8,
894 0x00, 0x12, 0xf4, 0x95, 0xf4, 0x95, 0xf4, 0xaa,
895 0xf8, 0x30, 0x0f, 0x6d, 0xf0, 0x73, 0x0f, 0x96,
896 0xf5, 0x00, 0x81, 0x04, 0x49, 0x16, 0xf5, 0x20,
897 0x89, 0x16, 0x76, 0xe1, 0x00, 0x0c, 0x00, 0x00,
898 0x76, 0xe1, 0x00, 0x04, 0x00, 0x00, 0x48, 0x16,
899 0xf8, 0x45, 0x11, 0x33, 0xf7, 0xb8, 0x71, 0xe1,
900 0x00, 0x02, 0x00, 0x12, 0x10, 0xf8, 0x00, 0x12,
901 0xf0, 0x10, 0x00, 0x03, 0xf8, 0x46, 0x0f, 0x8c,
902 0x10, 0xf8, 0x00, 0x12, 0xf0, 0x10, 0x00, 0x03,
903 0xf8, 0x45, 0x10, 0x16, 0x77, 0x10, 0x00, 0x01,
904 0xf4, 0xaa, 0xf8, 0x30, 0x0f, 0x9c, 0x77, 0x10,
905 0x00, 0x02, 0xf4, 0xaa, 0xf8, 0x30, 0x0f, 0xa8,
906 0xf0, 0x73, 0x0f, 0x96, 0x77, 0x10, 0x00, 0x04,
907 0xf4, 0xaa, 0xf8, 0x30, 0x10, 0xb7, 0x77, 0x10,
908 0x00, 0x05, 0xf4, 0xaa, 0xf8, 0x30, 0x10, 0xbc,
909 0xf2, 0x74, 0x0e, 0x9f, 0xf4, 0x95, 0x48, 0x17,
910 0xf0, 0x73, 0x11, 0x31, 0x76, 0xe1, 0x00, 0x0c,
911 0x00, 0x00, 0x76, 0xe1, 0x00, 0x0b, 0x00, 0x00,
912 0x76, 0xe1, 0x00, 0x04, 0x00, 0x00, 0x76, 0xe1,
913 0x00, 0x02, 0x00, 0x02, 0x11, 0xe1, 0x00, 0x0c,
914 0xe8, 0x03, 0xf6, 0x20, 0x89, 0x12, 0xf4, 0x95,
915 0x77, 0x10, 0x00, 0x03, 0xf5, 0xaa, 0xf8, 0x30,
916 0x0f, 0xb6, 0x6b, 0xf8, 0x27, 0x6f, 0x00, 0x01,
917 0x88, 0x10, 0xf4, 0x95, 0xf4, 0x95, 0xf5, 0xae,
918 0xf8, 0x20, 0x0f, 0xbd, 0x48, 0x16, 0x80, 0x06,
919 0x88, 0x13, 0xf4, 0x95, 0x77, 0x10, 0x00, 0x03,
920 0xf6, 0xab, 0xf8, 0x20, 0x0f, 0xc8, 0x6b, 0xf8,
921 0x27, 0x6f, 0x00, 0x01, 0x12, 0x06, 0xf8, 0x45,
922 0x10, 0x00, 0x10, 0xe1, 0x00, 0x04, 0x80, 0x00,
923 0x10, 0x05, 0x80, 0x01, 0x10, 0x04, 0x80, 0x02,
924 0x10, 0x06, 0x80, 0x03, 0x48, 0x11, 0xf2, 0x74,
925 0x07, 0x1e, 0xf0, 0x00, 0x00, 0x05, 0x10, 0x06,
926 0x00, 0xe1, 0x00, 0x04, 0x80, 0xe1, 0x00, 0x04,
927 0x10, 0x06, 0x00, 0xe1, 0x00, 0x0c, 0x80, 0xe1,
928 0x00, 0x0c, 0x88, 0x12, 0x11, 0x06, 0x10, 0x04,
929 0xf6, 0x00, 0x80, 0x04, 0x48, 0x16, 0xf6, 0x20,
930 0x88, 0x16, 0x89, 0x13, 0xf4, 0x95, 0x77, 0x10,
931 0x00, 0x03, 0xf6, 0xab, 0xf8, 0x20, 0x0f, 0xf5,
932 0x6b, 0xf8, 0x27, 0x6f, 0x00, 0x01, 0x77, 0x10,
933 0x00, 0x0c, 0x71, 0xe1, 0x00, 0x04, 0x00, 0x13,
934 0xf6, 0xab, 0xf8, 0x20, 0x10, 0x00, 0x6b, 0xf8,
935 0x27, 0x6f, 0x00, 0x01, 0x6c, 0xe2, 0xff, 0xfd,
936 0x11, 0x31, 0xf6, 0xb8, 0x6f, 0xe1, 0x00, 0x05,
937 0x0c, 0x48, 0x6f, 0xe1, 0x00, 0x06, 0x0c, 0x18,
938 0xf0, 0x30, 0x0f, 0xff, 0xf0, 0x00, 0x00, 0x03,
939 0x80, 0xe1, 0x00, 0x0b, 0x76, 0xe1, 0x00, 0x02,
940 0x00, 0x03, 0x48, 0x16, 0xf8, 0x45, 0x11, 0x33,
941 0x71, 0xe1, 0x00, 0x0c, 0x00, 0x12, 0x10, 0xe1,
942 0x00, 0x0b, 0x49, 0x12, 0xf6, 0x20, 0x88, 0x13,
943 0xe8, 0x0c, 0xf6, 0x20, 0x88, 0x10, 0xf4, 0x95,
944 0xf4, 0x95, 0xf5, 0xab, 0xf8, 0x20, 0x10, 0x27,
945 0x48, 0x13, 0x80, 0x06, 0x88, 0x10, 0xf4, 0x95,
946 0xf4, 0x95, 0xf5, 0xae, 0xf8, 0x20, 0x10, 0x30,
947 0x70, 0x06, 0x00, 0x16, 0x12, 0x06, 0xf8, 0x45,
948 0x10, 0x5f, 0x10, 0xe1, 0x00, 0x04, 0x80, 0x00,
949 0x10, 0x05, 0x80, 0x01, 0x10, 0x04, 0x80, 0x02,
950 0x10, 0x06, 0x80, 0x03, 0x48, 0x11, 0xf2, 0x74,
951 0x07, 0x1e, 0xf0, 0x00, 0x00, 0x05, 0x10, 0x06,
952 0x00, 0xe1, 0x00, 0x04, 0x80, 0xe1, 0x00, 0x04,
953 0x10, 0x06, 0x00, 0xe1, 0x00, 0x0c, 0x80, 0xe1,
954 0x00, 0x0c, 0x88, 0x12, 0x11, 0x06, 0x10, 0x04,
955 0xf6, 0x00, 0x80, 0x04, 0x48, 0x16, 0xf6, 0x20,
956 0x88, 0x16, 0xf4, 0x95, 0x77, 0x10, 0x00, 0x0c,
957 0x71, 0xe1, 0x00, 0x04, 0x00, 0x13, 0xf6, 0xab,
958 0xf8, 0x20, 0x10, 0x5f, 0x6b, 0xf8, 0x27, 0x6f,
959 0x00, 0x01, 0x77, 0x10, 0x00, 0x0c, 0xf6, 0xaa,
960 0xf8, 0x20, 0x10, 0x6b, 0xf2, 0x74, 0x0e, 0x9f,
961 0xf4, 0x95, 0x48, 0x17, 0x71, 0xe1, 0x00, 0x0c,
962 0x00, 0x12, 0x77, 0x10, 0x00, 0x0c, 0xf4, 0xaa,
963 0xf8, 0x30, 0x10, 0x7c, 0x77, 0x10, 0x00, 0x0c,
964 0x71, 0xe1, 0x00, 0x0b, 0x00, 0x13, 0xf6, 0xab,
965 0xf8, 0x30, 0x10, 0xb4, 0xe7, 0x30, 0xf7, 0xaa,
966 0xf8, 0x30, 0x10, 0xb4, 0xf2, 0x74, 0x0e, 0xc1,
967 0xf4, 0x95, 0x48, 0x17, 0x88, 0x12, 0xf4, 0x95,
968 0xf4, 0x95, 0x6c, 0x82, 0x10, 0x8d, 0x76, 0xe1,
969 0x00, 0x04, 0x00, 0x00, 0x76, 0xe1, 0x00, 0x02,
970 0x00, 0x05, 0xf0, 0x73, 0x10, 0xb4, 0x76, 0xe1,
971 0x00, 0x02, 0x00, 0x04, 0x77, 0x10, 0x00, 0x0c,
972 0x71, 0xe1, 0x00, 0x0b, 0x00, 0x12, 0xf5, 0xaa,
973 0xf8, 0x20, 0x10, 0x9a, 0xf0, 0x73, 0x10, 0x9c,
974 0x77, 0x12, 0x00, 0x0c, 0x76, 0x00, 0x00, 0x00,
975 0x70, 0x01, 0x00, 0x12, 0x70, 0x02, 0x00, 0x17,
976 0x76, 0x03, 0x00, 0x01, 0x48, 0x11, 0xf2, 0x74,
977 0x0c, 0xb9, 0xf0, 0x00, 0x00, 0x05, 0x76, 0xe1,
978 0x00, 0x04, 0x00, 0x00, 0x77, 0x10, 0x00, 0x0c,
979 0x71, 0xe1, 0x00, 0x0b, 0x00, 0x12, 0xf6, 0xaa,
980 0xf8, 0x20, 0x11, 0x1c, 0x48, 0x16, 0xf8, 0x45,
981 0x11, 0x33, 0x60, 0xe1, 0x00, 0x02, 0x00, 0x05,
982 0xf8, 0x20, 0x10, 0xdf, 0x10, 0xe1, 0x00, 0x0b,
983 0x08, 0xe1, 0x00, 0x0c, 0x11, 0xe1, 0x00, 0x04,
984 0xf8, 0x4d, 0x10, 0xc7, 0x6b, 0xf8, 0x27, 0x6f,
985 0x00, 0x01, 0x88, 0x10, 0xf4, 0x95, 0xf4, 0x95,
986 0xf5, 0xae, 0xf8, 0x20, 0x10, 0xcf, 0x48, 0x16,
987 0xf4, 0x95, 0x48, 0x08, 0xf8, 0x45, 0x11, 0x16,
988 0x6f, 0xe1, 0x00, 0x0c, 0x0d, 0x00, 0x81, 0xe1,
989 0x00, 0x0c, 0x11, 0x04, 0xf5, 0x00, 0x81, 0x04,
990 0x49, 0x16, 0xf5, 0x20, 0x89, 0x16, 0xf0, 0x73,
991 0x11, 0x0e, 0x10, 0xe1, 0x00, 0x0b, 0x71, 0xe1,
992 0x00, 0x0c, 0x00, 0x12, 0x88, 0x10, 0xf4, 0x95,
993 0xf4, 0x95, 0xf6, 0xaa, 0xf8, 0x30, 0x11, 0x16,
994 0x49, 0x12, 0xf6, 0x20, 0x88, 0x10, 0xf4, 0x95,
995 0xf4, 0x95, 0xf5, 0xae, 0xf8, 0x20, 0x10, 0xf3,
996 0x48, 0x16, 0x80, 0x06, 0x48, 0x08, 0xf8, 0x45,
997 0x11, 0x16, 0x10, 0x04, 0x70, 0x02, 0x00, 0x17,
998 0x80, 0x00, 0x76, 0x03, 0x00, 0x00, 0x10, 0x06,
999 0x80, 0x01, 0x10, 0x05, 0xf0, 0x74, 0x0c, 0xb9,
1000 0x10, 0x06, 0x00, 0xe1, 0x00, 0x0c, 0x80, 0xe1,
1001 0x00, 0x0c, 0x11, 0x06, 0x10, 0x04, 0xf6, 0x00,
1002 0x80, 0x04, 0x48, 0x16, 0xf6, 0x20, 0x88, 0x16,
1003 0x10, 0xe1, 0x00, 0x0c, 0x08, 0xe1, 0x00, 0x0b,
1004 0xf8, 0x45, 0x11, 0x1c, 0xf0, 0x73, 0x11, 0x31,
1005 0xf2, 0x74, 0x0e, 0x9f, 0xf4, 0x95, 0x48, 0x17,
1006 0xf0, 0x73, 0x11, 0x33, 0x76, 0xe1, 0x00, 0x0c,
1007 0x00, 0x00, 0x76, 0xe1, 0x00, 0x0b, 0x00, 0x00,
1008 0x76, 0xe1, 0x00, 0x02, 0x00, 0x01, 0x10, 0x04,
1009 0x80, 0x00, 0x10, 0x05, 0xf0, 0x74, 0x06, 0x9f,
1010 0x88, 0x12, 0xf4, 0x95, 0x77, 0x10, 0x00, 0xff,
1011 0xf4, 0xaa, 0xf8, 0x30, 0x11, 0x33, 0x6c, 0x86,
1012 0x0f, 0x70, 0xee, 0x08, 0x8a, 0x17, 0x8a, 0x16,
1013 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0xee, 0xfc,
1014 0xf4, 0x95, 0x71, 0x06, 0x00, 0x12, 0x88, 0x11,
1015 0x73, 0x12, 0x00, 0x0e, 0xf1, 0x66, 0x00, 0x0d,
1016 0xf3, 0x00, 0x24, 0x00, 0x89, 0x14, 0x13, 0x81,
1017 0xf7, 0x7a, 0xf3, 0x30, 0x00, 0x01, 0x81, 0xf8,
1018 0x27, 0x60, 0x13, 0xe1, 0x00, 0x01, 0xf7, 0x7c,
1019 0xf3, 0x30, 0x00, 0x03, 0x81, 0xf8, 0x27, 0x61,
1020 0xe9, 0x0f, 0x19, 0xe1, 0x00, 0x01, 0x81, 0xf8,
1021 0x27, 0x62, 0x71, 0xe4, 0x00, 0x03, 0x00, 0x13,
1022 0xf6, 0xb8, 0x49, 0x13, 0xf3, 0x00, 0x00, 0x01,
1023 0xf3, 0x30, 0x00, 0x0f, 0x49, 0x0b, 0x09, 0xf8,
1024 0x27, 0x62, 0xf8, 0x4d, 0x11, 0x75, 0x77, 0x10,
1025 0x00, 0xff, 0xf4, 0xab, 0xf8, 0x30, 0x11, 0x75,
1026 0x57, 0xf8, 0x27, 0x6c, 0xf3, 0x00, 0x00, 0x01,
1027 0x4f, 0xf8, 0x27, 0x6c, 0x76, 0xf8, 0x27, 0x63,
1028 0x00, 0x01, 0xf0, 0x73, 0x11, 0x78, 0x76, 0xf8,
1029 0x27, 0x63, 0x00, 0x00, 0x70, 0xe4, 0x00, 0x03,
1030 0x27, 0x62, 0x76, 0xf8, 0x27, 0x64, 0x00, 0x00,
1031 0x11, 0xf8, 0x27, 0x61, 0x61, 0xf8, 0x00, 0x0b,
1032 0x00, 0x02, 0xf8, 0x20, 0x11, 0x8d, 0xe9, 0x01,
1033 0x6f, 0xe1, 0x00, 0x02, 0x0f, 0x18, 0x81, 0xf8,
1034 0x27, 0x64, 0x11, 0xf8, 0x27, 0x61, 0x61, 0xf8,
1035 0x00, 0x0b, 0x00, 0x01, 0xf8, 0x20, 0x11, 0xa9,
1036 0x10, 0xf8, 0x27, 0x64, 0xf1, 0x00, 0x00, 0x04,
1037 0x89, 0x13, 0xe9, 0xb8, 0xf5, 0x20, 0x81, 0xf8,
1038 0x27, 0x65, 0x60, 0x84, 0x00, 0x02, 0xf8, 0x20,
1039 0x11, 0xa9, 0x70, 0x00, 0x00, 0x11, 0x70, 0x01,
1040 0x00, 0x13, 0x70, 0x02, 0x27, 0x65, 0xf2, 0x74,
1041 0x0f, 0x18, 0xf4, 0x95, 0x48, 0x12, 0xee, 0x04,
1042 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0x4a, 0x16,
1043 0x4a, 0x17, 0xee, 0xfc, 0xe8, 0x00, 0x4e, 0xf8,
1044 0x27, 0x66, 0xe8, 0x00, 0x4e, 0xf8, 0x27, 0x68,
1045 0xe8, 0x00, 0x4e, 0xf8, 0x27, 0x6c, 0xe8, 0x00,
1046 0x4e, 0xf8, 0x27, 0x6a, 0x77, 0x12, 0x27, 0x40,
1047 0x77, 0x11, 0x24, 0x00, 0x77, 0x1a, 0x00, 0x1f,
1048 0xf0, 0x72, 0x11, 0xdb, 0x70, 0x92, 0x00, 0x11,
1049 0x76, 0xe1, 0x00, 0x01, 0xff, 0xff, 0x76, 0x81,
1050 0x00, 0x00, 0x76, 0xe1, 0x00, 0x02, 0x00, 0x00,
1051 0x76, 0xe1, 0x00, 0x03, 0x00, 0xff, 0x76, 0xe1,
1052 0x00, 0x0c, 0x00, 0x00, 0x76, 0xe1, 0x00, 0x0b,
1053 0x00, 0x00, 0x76, 0xe1, 0x00, 0x04, 0x00, 0x00,
1054 0x6d, 0xe9, 0x00, 0x0d, 0xf0, 0x20, 0x25, 0xa0,
1055 0xf1, 0x00, 0x00, 0x07, 0x89, 0x11, 0xf1, 0x00,
1056 0x00, 0x01, 0x81, 0x02, 0x88, 0x16, 0xf4, 0x95,
1057 0x77, 0x17, 0x00, 0x20, 0x76, 0x86, 0x00, 0xff,
1058 0x76, 0x00, 0x00, 0x00, 0x76, 0x01, 0x00, 0x06,
1059 0x10, 0x02, 0xf0, 0x74, 0x06, 0x6c, 0x76, 0x00,
1060 0x00, 0x00, 0x76, 0x01, 0x00, 0x06, 0xf2, 0x74,
1061 0x06, 0x6c, 0xf4, 0x95, 0x48, 0x11, 0x10, 0x02,
1062 0xf0, 0x00, 0x00, 0x0d, 0x80, 0x02, 0x6d, 0xe9,
1063 0x00, 0x0d, 0x6d, 0xee, 0x00, 0x0d, 0x6c, 0xef,
1064 0xff, 0xff, 0x11, 0xe8, 0xf0, 0x74, 0x0c, 0x9d,
1065 0xee, 0x04, 0x8a, 0x17, 0x8a, 0x16, 0x8a, 0x11,
1066 0xfc, 0x00, 0x4a, 0x11, 0x4a, 0x16, 0x4a, 0x17,
1067 0xee, 0xfa, 0x88, 0x11, 0x10, 0x0a, 0x49, 0x11,
1068 0xf8, 0x4d, 0x12, 0x9f, 0x48, 0x08, 0xf8, 0x45,
1069 0x12, 0x9f, 0x80, 0x04, 0x12, 0x81, 0xf5, 0x78,
1070 0x89, 0x12, 0xf4, 0x95, 0xf4, 0x95, 0x6c, 0xe2,
1071 0xff, 0xb9, 0x12, 0x8a, 0x61, 0xf8, 0x00, 0x08,
1072 0x00, 0x80, 0xf8, 0x30, 0x12, 0x8a, 0x13, 0xe1,
1073 0x00, 0x01, 0xf0, 0xe8, 0xf7, 0x78, 0xf1, 0xa0,
1074 0xf2, 0x30, 0x1f, 0xff, 0x88, 0x17, 0xf4, 0x95,
1075 0x77, 0x12, 0x24, 0x00, 0x77, 0x16, 0x00, 0x00,
1076 0x77, 0x13, 0x00, 0x20, 0xf6, 0xb8, 0x48, 0x17,
1077 0x08, 0xe2, 0x00, 0x01, 0xf8, 0x45, 0x12, 0x42,
1078 0x6d, 0xea, 0x00, 0x0d, 0x6d, 0x96, 0x6c, 0xeb,
1079 0xff, 0xff, 0x12, 0x34, 0xf0, 0x73, 0x12, 0x90,
1080 0x56, 0xf8, 0x27, 0x6a, 0xf0, 0x00, 0x00, 0x01,
1081 0x4e, 0xf8, 0x27, 0x6a, 0x60, 0x82, 0x00, 0x01,
1082 0xf8, 0x30, 0x12, 0x54, 0x70, 0x00, 0x00, 0x16,
1083 0xf2, 0x74, 0x11, 0x38, 0xf4, 0x95, 0x48, 0x11,
1084 0xf0, 0x73, 0x12, 0x90, 0x70, 0x00, 0x00, 0x16,
1085 0xf2, 0x74, 0x11, 0x38, 0xf4, 0x95, 0x48, 0x11,
1086 0x72, 0x10, 0x2a, 0x9e, 0xf4, 0x95, 0xf4, 0xaf,
1087 0xf8, 0x30, 0x12, 0x6e, 0x76, 0x00, 0x00, 0x00,
1088 0x76, 0x01, 0x00, 0xbc, 0x70, 0x02, 0x00, 0x16,
1089 0x76, 0x03, 0x00, 0x00, 0xf2, 0x74, 0x0c, 0xb9,
1090 0xf4, 0x95, 0x48, 0x11, 0xf0, 0x73, 0x12, 0x90,
1091 0x10, 0xf8, 0x27, 0x6e, 0xf8, 0x44, 0x12, 0x90,
1092 0x76, 0x00, 0x00, 0x00, 0x76, 0x01, 0x00, 0xbc,
1093 0x70, 0x02, 0x00, 0x16, 0x76, 0x03, 0x00, 0x00,
1094 0xf2, 0x74, 0x0c, 0xb9, 0xf4, 0x95, 0x48, 0x11,
1095 0xf0, 0x74, 0x0c, 0x5e, 0xf0, 0xe0, 0xf0, 0x10,
1096 0x13, 0x88, 0xf8, 0x42, 0x12, 0x90, 0x76, 0xf8,
1097 0x27, 0x6e, 0x00, 0x01, 0xf0, 0x73, 0x12, 0x90,
1098 0x56, 0xf8, 0x27, 0x66, 0xf0, 0x00, 0x00, 0x01,
1099 0x4e, 0xf8, 0x27, 0x66, 0x6d, 0xe9, 0x00, 0x5e,
1100 0x56, 0xf8, 0x27, 0x68, 0xf0, 0x00, 0x00, 0x01,
1101 0x4e, 0xf8, 0x27, 0x68, 0x71, 0x04, 0x00, 0x12,
1102 0x6e, 0xea, 0xff, 0xff, 0x12, 0x18, 0x70, 0x04,
1103 0x00, 0x12, 0xee, 0x06, 0x8a, 0x17, 0x8a, 0x16,
1104 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0xee, 0xfe,
1105 0x88, 0x0e, 0xf4, 0x95, 0xf0, 0x66, 0x00, 0x0d,
1106 0xf0, 0x00, 0x25, 0xa0, 0x88, 0x11, 0xf4, 0x95,
1107 0xf4, 0x95, 0x76, 0x81, 0x00, 0xff, 0x76, 0x00,
1108 0x00, 0x00, 0x76, 0x01, 0x00, 0x06, 0xf2, 0x74,
1109 0x06, 0x6c, 0xf0, 0x00, 0x00, 0x01, 0x76, 0x00,
1110 0x00, 0x00, 0x76, 0x01, 0x00, 0x06, 0x48, 0x11,
1111 0xf2, 0x74, 0x06, 0x6c, 0xf0, 0x00, 0x00, 0x07,
1112 0xee, 0x02, 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11,
1113 0x88, 0x0e, 0xf4, 0x95, 0xf0, 0x66, 0x00, 0x0d,
1114 0xf0, 0x00, 0x24, 0x00, 0x88, 0x11, 0xf4, 0x95,
1115 0xf4, 0x95, 0x76, 0xe1, 0x00, 0x01, 0xff, 0xff,
1116 0x76, 0x81, 0x00, 0x00, 0x76, 0xe1, 0x00, 0x02,
1117 0x00, 0x00, 0x76, 0xe1, 0x00, 0x03, 0x00, 0xff,
1118 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0xf4, 0x95,
1119 0x13, 0x03, 0x88, 0x11, 0xfa, 0x4d, 0x12, 0xec,
1120 0x71, 0x02, 0x00, 0x12, 0xf3, 0x10, 0x00, 0x01,
1121 0x89, 0x1a, 0xf4, 0x95, 0xf0, 0x72, 0x12, 0xeb,
1122 0x70, 0x91, 0x00, 0x12, 0x8a, 0x11, 0xfc, 0x00,
1123 0xf4, 0x95, 0x4a, 0x0b, 0x4a, 0x0c, 0x4a, 0x0d,
1124 0xf7, 0xb8, 0xee, 0xfe, 0x10, 0xf8, 0x00, 0x08,
1125 0x11, 0x06, 0xf1, 0xc0, 0x83, 0x00, 0xf4, 0x85,
1126 0x11, 0x06, 0xf7, 0x85, 0x81, 0x06, 0xf6, 0xb8,
1127 0xec, 0x0f, 0x1e, 0x06, 0x61, 0x00, 0x80, 0x00,
1128 0xf8, 0x20, 0x13, 0x05, 0xf4, 0x84, 0xee, 0x02,
1129 0x8a, 0x0d, 0x8a, 0x0c, 0x8a, 0x0b, 0xfc, 0x00,
1130 0xf4, 0x95, 0x4a, 0x0b, 0x4a, 0x0c, 0x4a, 0x0d,
1131 0xee, 0xfe, 0xf7, 0xb8, 0x80, 0x00, 0x10, 0xf8,
1132 0x00, 0x08, 0xf4, 0x85, 0x11, 0x06, 0xf7, 0x85,
1133 0x81, 0x06, 0xf6, 0xb8, 0xec, 0x0f, 0x1e, 0x06,
1134 0xf0, 0xf0, 0x61, 0x00, 0x80, 0x00, 0xf8, 0x20,
1135 0x13, 0x20, 0xf4, 0x84, 0xee, 0x02, 0x8a, 0x0d,
1136 0x8a, 0x0c, 0x8a, 0x0b, 0xfc, 0x00, 0x4a, 0x11,
1137 0x77, 0x11, 0x00, 0x7b, 0x76, 0x81, 0x2e, 0xec,
1138 0x77, 0x11, 0x00, 0x7b, 0xee, 0xff, 0x71, 0x81,
1139 0x00, 0x11, 0xee, 0x01, 0x76, 0xe1, 0x00, 0x01,
1140 0x00, 0x00, 0x76, 0xe1, 0x00, 0x04, 0x00, 0x00,
1141 0x76, 0xe1, 0x00, 0x06, 0x00, 0x00, 0x76, 0xe1,
1142 0x00, 0x62, 0x00, 0x00, 0x76, 0xe1, 0x00, 0x76,
1143 0x00, 0x00, 0x76, 0xe1, 0x00, 0x92, 0x00, 0x00,
1144 0x76, 0xe1, 0x00, 0x94, 0x00, 0x00, 0x76, 0xe1,
1145 0x00, 0xb0, 0x00, 0x00, 0x76, 0xe1, 0x00, 0xb3,
1146 0x00, 0x00, 0x76, 0xe1, 0x00, 0xbe, 0x00, 0x00,
1147 0x76, 0xe1, 0x00, 0xbf, 0x00, 0x00, 0x76, 0xe1,
1148 0x00, 0xc1, 0x00, 0x00, 0x76, 0xe1, 0x00, 0xc3,
1149 0x00, 0x00, 0x76, 0xe1, 0x00, 0xc5, 0x00, 0x00,
1150 0x76, 0xe1, 0x00, 0xc7, 0x00, 0x00, 0x76, 0x81,
1151 0x00, 0x00, 0x8a, 0x11, 0xf4, 0x95, 0xf4, 0xe4,
1152 0x4a, 0x11, 0x4a, 0x16, 0x4a, 0x17, 0xee, 0xff,
1153 0xf4, 0x95, 0x71, 0x06, 0x00, 0x16, 0xfb, 0x80,
1154 0x16, 0xa2, 0x88, 0x17, 0xf4, 0x95, 0xf7, 0xb8,
1155 0x10, 0xf8, 0x00, 0x17, 0xf0, 0x10, 0x00, 0x02,
1156 0xfa, 0x46, 0x13, 0x88, 0x77, 0x11, 0x00, 0x00,
1157 0x10, 0xf8, 0x00, 0x17, 0xf0, 0x10, 0x00, 0x02,
1158 0xf8, 0x45, 0x13, 0xf9, 0x10, 0xf8, 0x00, 0x17,
1159 0xf8, 0x45, 0x14, 0x39, 0x10, 0xf8, 0x00, 0x17,
1160 0xf0, 0x10, 0x00, 0x01, 0xf8, 0x45, 0x14, 0x1f,
1161 0xf0, 0x73, 0x14, 0x52, 0x10, 0xf8, 0x00, 0x17,
1162 0xf0, 0x10, 0x00, 0x03, 0xf8, 0x45, 0x13, 0xd3,
1163 0x10, 0xf8, 0x00, 0x17, 0xf0, 0x10, 0x00, 0x06,
1164 0xf8, 0x44, 0x14, 0x52, 0x77, 0x12, 0x00, 0x7b,
1165 0x71, 0x82, 0x00, 0x14, 0x61, 0xe4, 0x00, 0x07,
1166 0x00, 0x40, 0xf8, 0x30, 0x14, 0x52, 0x49, 0x14,
1167 0x48, 0x17, 0xf6, 0x00, 0x88, 0x12, 0xf4, 0x95,
1168 0x77, 0x13, 0x00, 0x55, 0x77, 0x11, 0x00, 0x57,
1169 0x6d, 0xea, 0x00, 0x3b, 0xe5, 0x01, 0x10, 0xe6,
1170 0x00, 0x06, 0x80, 0x81, 0x48, 0x14, 0x00, 0xf8,
1171 0x00, 0x17, 0x88, 0x12, 0xf4, 0x95, 0x77, 0x11,
1172 0x00, 0x55, 0x10, 0xe2, 0x00, 0x40, 0x80, 0x81,
1173 0x77, 0x11, 0x00, 0x57, 0x10, 0xe6, 0x00, 0x07,
1174 0x80, 0x81, 0x77, 0x11, 0x00, 0x55, 0x10, 0xe2,
1175 0x00, 0x45, 0x80, 0x81, 0x10, 0xe6, 0x00, 0x08,
1176 0x77, 0x11, 0x00, 0x57, 0x80, 0x81, 0x77, 0x11,
1177 0x00, 0x55, 0x10, 0xe2, 0x00, 0x4a, 0x80, 0x81,
1178 0x77, 0x11, 0x00, 0x57, 0x10, 0xe6, 0x00, 0x09,
1179 0x80, 0x81, 0xf2, 0x73, 0x14, 0x52, 0x77, 0x11,
1180 0x03, 0xc0, 0x77, 0x12, 0x00, 0x7b, 0x10, 0x82,
1181 0xf0, 0x00, 0x00, 0x07, 0x88, 0x13, 0xf4, 0x95,
1182 0xf4, 0x95, 0x96, 0x1b, 0xf8, 0x30, 0x14, 0x52,
1183 0x10, 0xe3, 0x00, 0x35, 0x77, 0x12, 0x00, 0x55,
1184 0x80, 0x82, 0x77, 0x12, 0x00, 0x57, 0x10, 0xe6,
1185 0x00, 0x04, 0x80, 0x82, 0x77, 0x12, 0x00, 0x55,
1186 0x10, 0xe3, 0x00, 0x37, 0x80, 0x82, 0x77, 0x12,
1187 0x00, 0x57, 0x10, 0xe6, 0x00, 0x05, 0x80, 0x82,
1188 0x48, 0x11, 0xf0, 0x40, 0x00, 0x10, 0xf2, 0x73,
1189 0x14, 0x50, 0xf0, 0x40, 0x00, 0x20, 0x77, 0x12,
1190 0x00, 0x7b, 0x10, 0x82, 0xf0, 0x00, 0x00, 0x07,
1191 0x88, 0x12, 0xf4, 0x95, 0xf4, 0x95, 0x96, 0x0d,
1192 0xf8, 0x30, 0x14, 0x52, 0x10, 0xe2, 0x00, 0x34,
1193 0x77, 0x13, 0x00, 0x55, 0x80, 0x83, 0x77, 0x13,
1194 0x00, 0x57, 0x10, 0xe6, 0x00, 0x02, 0x80, 0x83,
1195 0x10, 0xe2, 0x00, 0x36, 0x77, 0x12, 0x00, 0x55,
1196 0x80, 0x82, 0x77, 0x12, 0x00, 0x57, 0x10, 0xe6,
1197 0x00, 0x03, 0x80, 0x82, 0x48, 0x11, 0xf0, 0x40,
1198 0x00, 0x04, 0xf2, 0x73, 0x14, 0x50, 0xf0, 0x40,
1199 0x00, 0x08, 0x77, 0x12, 0x00, 0x7b, 0x10, 0x82,
1200 0xf0, 0x00, 0x00, 0x07, 0x88, 0x12, 0xf4, 0x95,
1201 0xf4, 0x95, 0x96, 0x0e, 0xf8, 0x30, 0x14, 0x52,
1202 0x10, 0xe2, 0x00, 0x33, 0x77, 0x12, 0x00, 0x55,
1203 0x80, 0x82, 0x77, 0x12, 0x00, 0x57, 0x10, 0xe6,
1204 0x00, 0x01, 0x80, 0x82, 0x48, 0x11, 0xf2, 0x73,
1205 0x14, 0x50, 0xf0, 0x40, 0x00, 0x02, 0x77, 0x12,
1206 0x00, 0x7b, 0x10, 0x82, 0xf0, 0x00, 0x00, 0x07,
1207 0x88, 0x12, 0xf4, 0x95, 0xf4, 0x95, 0x96, 0x0f,
1208 0xf8, 0x30, 0x14, 0x52, 0x10, 0xe2, 0x00, 0x32,
1209 0x77, 0x12, 0x00, 0x55, 0x77, 0x13, 0x00, 0x57,
1210 0x80, 0x82, 0x48, 0x11, 0xe7, 0x62, 0xf0, 0x40,
1211 0x00, 0x01, 0xe5, 0x01, 0x88, 0x11, 0xf4, 0x95,
1212 0x77, 0x12, 0x00, 0x7b, 0x48, 0x11, 0x71, 0x82,
1213 0x00, 0x12, 0x1a, 0xe2, 0x00, 0x07, 0x80, 0xe2,
1214 0x00, 0x07, 0xf9, 0x80, 0x16, 0x9a, 0xee, 0x01,
1215 0x8a, 0x17, 0x48, 0x11, 0x8a, 0x16, 0x8a, 0x11,
1216 0xf4, 0xe4, 0x4a, 0x11, 0x88, 0x11, 0x77, 0x0e,
1217 0x00, 0x05, 0x77, 0x12, 0x00, 0x55, 0xe8, 0x04,
1218 0xf6, 0xb8, 0x28, 0xe1, 0x00, 0x02, 0xee, 0xff,
1219 0x80, 0x82, 0x77, 0x12, 0x00, 0x57, 0xf0, 0x20,
1220 0x80, 0x00, 0xee, 0x01, 0x1a, 0x82, 0x77, 0x12,
1221 0x00, 0x57, 0x80, 0x82, 0xe8, 0x01, 0x32, 0xe1,
1222 0x00, 0x02, 0xf5, 0x82, 0x77, 0x11, 0x00, 0x54,
1223 0xf6, 0x93, 0x18, 0x81, 0x77, 0x11, 0x00, 0x54,
1224 0xf2, 0xa0, 0x80, 0x81, 0x8a, 0x11, 0xf4, 0x95,
1225 0xf4, 0xe4, 0x4a, 0x11, 0x4a, 0x16, 0xf4, 0x95,
1226 0x71, 0x04, 0x00, 0x11, 0xfb, 0x80, 0x16, 0xa2,
1227 0x88, 0x16, 0xf4, 0x95, 0x77, 0x12, 0x00, 0x55,
1228 0x10, 0xe6, 0x00, 0x03, 0x80, 0x82, 0x77, 0x12,
1229 0x00, 0x56, 0x10, 0xe1, 0x00, 0x02, 0x77, 0x13,
1230 0x00, 0x56, 0x80, 0x82, 0x77, 0x12, 0x00, 0x56,
1231 0x10, 0xe1, 0x00, 0x03, 0x80, 0x82, 0x10, 0xe1,
1232 0x00, 0x04, 0x77, 0x12, 0x00, 0x56, 0x80, 0x82,
1233 0x77, 0x12, 0x00, 0x56, 0x10, 0xe1, 0x00, 0x01,
1234 0x80, 0x82, 0xe7, 0x12, 0xe5, 0x01, 0xf9, 0x80,
1235 0x16, 0x9a, 0x8a, 0x16, 0x8a, 0x11, 0xf4, 0xe4,
1236 0x4a, 0x11, 0x4a, 0x16, 0x4a, 0x17, 0xee, 0xf9,
1237 0x77, 0x11, 0x00, 0x7b, 0x76, 0x00, 0x00, 0x16,
1238 0x76, 0x01, 0x00, 0x17, 0x76, 0x02, 0x00, 0x1a,
1239 0x76, 0x03, 0x00, 0x1b, 0x76, 0x04, 0x00, 0x1c,
1240 0x76, 0x05, 0x00, 0x1d, 0x71, 0x81, 0x00, 0x17,
1241 0x71, 0xe7, 0x00, 0x06, 0x00, 0x11, 0x10, 0x81,
1242 0xf8, 0x44, 0x14, 0xdf, 0xf9, 0x80, 0x16, 0x53,
1243 0xf6, 0xb8, 0xfb, 0x80, 0x15, 0x85, 0xf0, 0x20,
1244 0xff, 0xff, 0xf6, 0xb8, 0xfb, 0x80, 0x16, 0x08,
1245 0xf0, 0x20, 0xff, 0xff, 0x77, 0x11, 0x00, 0x7b,
1246 0x71, 0x81, 0x00, 0x17, 0x76, 0xe7, 0x00, 0x06,
1247 0x00, 0x01, 0x48, 0x17, 0x77, 0x16, 0x00, 0x00,
1248 0x77, 0x10, 0x00, 0x04, 0x77, 0x15, 0x00, 0x03,
1249 0x77, 0x14, 0x00, 0x02, 0x77, 0x13, 0x00, 0x01,
1250 0xf0, 0x00, 0x00, 0x39, 0x76, 0xe7, 0x00, 0x08,
1251 0x00, 0x1f, 0x76, 0xe7, 0x00, 0x07, 0x00, 0x00,
1252 0x88, 0x0e, 0x77, 0x1a, 0x00, 0x05, 0x48, 0x17,
1253 0xf0, 0x00, 0x00, 0x09, 0x88, 0x12, 0x48, 0x18,
1254 0x88, 0x19, 0xe8, 0x00, 0xf0, 0x72, 0x15, 0x2c,
1255 0x73, 0x19, 0x00, 0x11, 0x76, 0x82, 0x00, 0x00,
1256 0x11, 0x91, 0x73, 0x11, 0x00, 0x19, 0x70, 0xe2,
1257 0x00, 0x03, 0x00, 0x16, 0x70, 0xe2, 0x00, 0x04,
1258 0x00, 0x13, 0x70, 0xe2, 0x00, 0x05, 0x00, 0x14,
1259 0x81, 0xe2, 0x00, 0x01, 0x70, 0xe2, 0x00, 0x06,
1260 0x00, 0x15, 0x70, 0xe2, 0x00, 0x07, 0x00, 0x10,
1261 0x80, 0xe2, 0x00, 0x02, 0x73, 0x0e, 0x00, 0x11,
1262 0xf1, 0x00, 0x00, 0x1e, 0x6d, 0xee, 0x00, 0x05,
1263 0x6d, 0xeb, 0x00, 0x05, 0x6d, 0xec, 0x00, 0x05,
1264 0x6d, 0xed, 0x00, 0x05, 0x6d, 0xe8, 0x00, 0x05,
1265 0xf0, 0x00, 0x00, 0x01, 0x81, 0x91, 0x6d, 0xea,
1266 0x00, 0x08, 0x73, 0x11, 0x00, 0x0e, 0xee, 0x07,
1267 0x76, 0xe7, 0x00, 0x41, 0x00, 0x24, 0x76, 0xe7,
1268 0x00, 0x46, 0x00, 0x25, 0x76, 0xe7, 0x00, 0x4b,
1269 0x00, 0x26, 0x76, 0xe7, 0x00, 0x50, 0x00, 0x27,
1270 0x8a, 0x17, 0x8a, 0x16, 0x8a, 0x11, 0xf4, 0xe4,
1271 0x4a, 0x11, 0x4a, 0x16, 0xee, 0xfe, 0x88, 0x11,
1272 0x56, 0x06, 0x4e, 0x00, 0xf9, 0x80, 0x16, 0xa2,
1273 0xf7, 0xb8, 0x10, 0xf8, 0x00, 0x11, 0xf0, 0x10,
1274 0xff, 0xff, 0xfa, 0x45, 0x15, 0x60, 0x77, 0x16,
1275 0xff, 0xff, 0x77, 0x12, 0x00, 0x7b, 0x49, 0x11,
1276 0x10, 0x82, 0xf6, 0x03, 0xf0, 0x00, 0x00, 0x09,
1277 0x88, 0x11, 0xf4, 0x95, 0xf4, 0x95, 0x10, 0x81,
1278 0xf8, 0x44, 0x15, 0x71, 0xf2, 0x73, 0x15, 0x71,
1279 0xf4, 0x95, 0xe7, 0x16, 0x77, 0x11, 0x00, 0x7b,
1280 0x10, 0x81, 0xf0, 0x00, 0x00, 0x09, 0x88, 0x11,
1281 0xf4, 0x95, 0x77, 0x12, 0x00, 0x06, 0x10, 0x81,
1282 0xf8, 0x45, 0x15, 0x5c, 0x6e, 0xea, 0xff, 0xff,
1283 0x15, 0x69, 0x6d, 0xe9, 0x00, 0x08, 0x76, 0x86,
1284 0x00, 0x01, 0xe9, 0x01, 0x56, 0x00, 0xf1, 0x80,
1285 0x10, 0xf8, 0x00, 0x0b, 0xf8, 0x45, 0x15, 0x7e,
1286 0xfb, 0x80, 0x15, 0x85, 0xf4, 0x95, 0x48, 0x16,
1287 0xf9, 0x80, 0x16, 0x9a, 0xee, 0x02, 0x48, 0x16,
1288 0x8a, 0x16, 0x8a, 0x11, 0xf4, 0xe4, 0x4a, 0x11,
1289 0xee, 0xff, 0xfb, 0x80, 0x16, 0xa2, 0x88, 0x11,
1290 0xf4, 0x95, 0x77, 0x10, 0xff, 0xff, 0xf4, 0xa9,
1291 0xf8, 0x30, 0x15, 0xc4, 0x10, 0xe1, 0x00, 0x03,
1292 0x77, 0x12, 0x00, 0x55, 0x80, 0x82, 0x77, 0x12,
1293 0x00, 0x56, 0x76, 0x82, 0x00, 0x00, 0x77, 0x12,
1294 0x00, 0x56, 0x76, 0x82, 0x00, 0x00, 0x77, 0x12,
1295 0x00, 0x56, 0x76, 0x82, 0x00, 0x00, 0x77, 0x12,
1296 0x00, 0x56, 0x76, 0x82, 0x00, 0x00, 0x77, 0x12,
1297 0x00, 0x56, 0x76, 0x82, 0x00, 0x00, 0x10, 0xe1,
1298 0x00, 0x02, 0xf0, 0x00, 0x00, 0x08, 0x32, 0xf8,
1299 0x00, 0x08, 0x77, 0x12, 0x00, 0x54, 0xe8, 0x01,
1300 0xf4, 0x82, 0xf4, 0x93, 0x18, 0x82, 0x77, 0x12,
1301 0x00, 0x54, 0xf0, 0x40, 0x00, 0x00, 0x80, 0x82,
1302 0x10, 0xe1, 0x00, 0x01, 0xf9, 0x80, 0x16, 0x76,
1303 0x10, 0xe1, 0x00, 0x01, 0xf9, 0x80, 0x16, 0x66,
1304 0xf0, 0x73, 0x16, 0x03, 0x77, 0x11, 0x00, 0x7b,
1305 0x71, 0x81, 0x00, 0x11, 0x71, 0xe1, 0x00, 0x07,
1306 0x00, 0x12, 0x76, 0x82, 0x00, 0x00, 0x10, 0xe1,
1307 0x00, 0x09, 0xf9, 0x80, 0x15, 0x85, 0x77, 0x11,
1308 0x00, 0x7b, 0x71, 0x81, 0x00, 0x11, 0x10, 0xe1,
1309 0x00, 0x09, 0xfb, 0x80, 0x15, 0x85, 0xf0, 0x00,
1310 0x00, 0x08, 0x77, 0x11, 0x00, 0x7b, 0x71, 0x81,
1311 0x00, 0x11, 0x10, 0xe1, 0x00, 0x09, 0xfb, 0x80,
1312 0x15, 0x85, 0xf0, 0x00, 0x00, 0x10, 0x77, 0x11,
1313 0x00, 0x7b, 0x71, 0x81, 0x00, 0x11, 0x10, 0xe1,
1314 0x00, 0x09, 0xfb, 0x80, 0x15, 0x85, 0xf0, 0x00,
1315 0x00, 0x18, 0x77, 0x11, 0x00, 0x7b, 0x71, 0x81,
1316 0x00, 0x11, 0x10, 0xe1, 0x00, 0x09, 0xfb, 0x80,
1317 0x15, 0x85, 0xf0, 0x00, 0x00, 0x20, 0x77, 0x11,
1318 0x00, 0x7b, 0x71, 0x81, 0x00, 0x11, 0x10, 0xe1,
1319 0x00, 0x09, 0xfb, 0x80, 0x15, 0x85, 0xf0, 0x00,
1320 0x00, 0x28, 0xf9, 0x80, 0x16, 0x9a, 0xee, 0x01,
1321 0x8a, 0x11, 0xf4, 0xe4, 0x4a, 0x11, 0xee, 0xff,
1322 0xfb, 0x80, 0x16, 0xa2, 0x88, 0x11, 0xf4, 0x95,
1323 0x77, 0x10, 0xff, 0xff, 0xf4, 0xa9, 0xf8, 0x30,
1324 0x16, 0x41, 0x77, 0x11, 0x00, 0x55, 0x76, 0x81,
1325 0x00, 0x1e, 0x77, 0x11, 0x00, 0x56, 0x76, 0x81,
1326 0x00, 0x00, 0x77, 0x11, 0x00, 0x56, 0x76, 0x81,
1327 0x00, 0x00, 0x77, 0x11, 0x00, 0x56, 0x76, 0x81,
1328 0x00, 0x00, 0x77, 0x11, 0x00, 0x56, 0x76, 0x81,
1329 0x00, 0x00, 0x77, 0x11, 0x00, 0x56, 0x76, 0x81,
1330 0x00, 0x00, 0x77, 0x11, 0x00, 0x56, 0x76, 0x81,
1331 0x00, 0x00, 0x77, 0x11, 0x00, 0x56, 0x76, 0x81,
1332 0x00, 0x00, 0x77, 0x11, 0x00, 0x56, 0x76, 0x81,
1333 0x00, 0x00, 0x77, 0x11, 0x00, 0x56, 0x76, 0x81,
1334 0x00, 0x00, 0x77, 0x11, 0x00, 0x56, 0xf2, 0x73,
1335 0x16, 0x4e, 0x76, 0x81, 0x00, 0x00, 0x77, 0x11,
1336 0x00, 0x7b, 0x71, 0x81, 0x00, 0x11, 0x71, 0xe1,
1337 0x00, 0x07, 0x00, 0x12, 0x76, 0x82, 0x00, 0x00,
1338 0x10, 0xe1, 0x00, 0x39, 0xf9, 0x80, 0x16, 0x08,
1339 0xf9, 0x80, 0x16, 0x9a, 0xee, 0x01, 0x8a, 0x11,
1340 0xf4, 0xe4, 0x4a, 0x11, 0x77, 0x11, 0x00, 0x7b,
1341 0x10, 0x81, 0xf0, 0x00, 0x00, 0x04, 0x88, 0x11,
1342 0xf4, 0x95, 0xf4, 0x95, 0x10, 0x81, 0xfa, 0x44,
1343 0x16, 0x63, 0xf4, 0x95, 0xee, 0xff, 0x76, 0x81,
1344 0x00, 0x01, 0xee, 0x01, 0x8a, 0x11, 0xf4, 0xe4,
1345 0xf0, 0x10, 0x00, 0x10, 0x4a, 0x11, 0x32, 0xf8,
1346 0x00, 0x08, 0xee, 0xff, 0x77, 0x11, 0x00, 0x01,
1347 0xe8, 0x01, 0xee, 0x01, 0xf4, 0x82, 0x1a, 0x81,
1348 0x80, 0x81, 0x8a, 0x11, 0xf4, 0x95, 0xf4, 0xe4,
1349 0xf0, 0x10, 0x00, 0x10, 0x4a, 0x11, 0x32, 0xf8,
1350 0x00, 0x08, 0xee, 0xff, 0xe8, 0x01, 0x77, 0x11,
1351 0x00, 0x00, 0xf4, 0x82, 0xee, 0x01, 0xf4, 0x93,
1352 0x18, 0x81, 0x80, 0x81, 0x8a, 0x11, 0xf4, 0x95,
1353 0xf4, 0xe4, 0x4a, 0x11, 0xf0, 0x10, 0x00, 0x10,
1354 0x77, 0x11, 0x00, 0x00, 0x32, 0xf8, 0x00, 0x08,
1355 0xee, 0xff, 0x11, 0x81, 0xe8, 0x01, 0xee, 0x01,
1356 0x77, 0x11, 0x00, 0x00, 0xf4, 0x82, 0xf2, 0xa0,
1357 0x80, 0x81, 0x8a, 0x11, 0xf4, 0x95, 0xf4, 0xe4,
1358 0xf2, 0x73, 0x16, 0x9e, 0xf6, 0xbb, 0xf4, 0x95,
1359 0xf4, 0x95, 0xf4, 0x95, 0xf4, 0x95, 0xf4, 0xe4,
1360 0xf2, 0x73, 0x16, 0xa6, 0xf7, 0xbb, 0xf4, 0x95,
1361 0xf4, 0x95, 0xf4, 0x95, 0xf4, 0x95, 0xf4, 0xe4,
1362 0x4a, 0x11, 0x4a, 0x16, 0xf4, 0x95, 0x71, 0x04,
1363 0x00, 0x16, 0xfb, 0x80, 0x16, 0xa2, 0x88, 0x11,
1364 0xf4, 0x95, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12,
1365 0x76, 0x82, 0x00, 0x0e, 0x10, 0xe6, 0x00, 0x0e,
1366 0x71, 0xe1, 0x00, 0x06, 0x00, 0x12, 0x80, 0x82,
1367 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12, 0x76, 0x82,
1368 0x00, 0x0d, 0x71, 0xe1, 0x00, 0x06, 0x00, 0x12,
1369 0x10, 0xe6, 0x00, 0x0d, 0x80, 0x82, 0x71, 0xe1,
1370 0x00, 0x05, 0x00, 0x12, 0x76, 0x82, 0x00, 0x0c,
1371 0x10, 0xe6, 0x00, 0x0c, 0x71, 0xe1, 0x00, 0x06,
1372 0x00, 0x12, 0x80, 0x82, 0x71, 0xe1, 0x00, 0x05,
1373 0x00, 0x12, 0x76, 0x82, 0x00, 0x0b, 0x10, 0xe6,
1374 0x00, 0x0b, 0x71, 0xe1, 0x00, 0x06, 0x00, 0x12,
1375 0x80, 0x82, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12,
1376 0x76, 0x82, 0x00, 0x0a, 0x71, 0xe1, 0x00, 0x06,
1377 0x00, 0x12, 0x10, 0xe6, 0x00, 0x0a, 0x80, 0x82,
1378 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12, 0x76, 0x82,
1379 0x00, 0x09, 0x10, 0xe6, 0x00, 0x09, 0x71, 0xe1,
1380 0x00, 0x06, 0x00, 0x12, 0x80, 0x82, 0x71, 0xe1,
1381 0x00, 0x05, 0x00, 0x12, 0x76, 0x82, 0x00, 0x08,
1382 0x71, 0xe1, 0x00, 0x06, 0x00, 0x12, 0x10, 0xe6,
1383 0x00, 0x08, 0x80, 0x82, 0x71, 0xe1, 0x00, 0x05,
1384 0x00, 0x12, 0x76, 0x82, 0x00, 0x07, 0x10, 0xe6,
1385 0x00, 0x07, 0x71, 0xe1, 0x00, 0x06, 0x00, 0x12,
1386 0x80, 0x82, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12,
1387 0x76, 0x82, 0x00, 0x06, 0x71, 0xe1, 0x00, 0x06,
1388 0x00, 0x12, 0x10, 0xe6, 0x00, 0x06, 0x80, 0x82,
1389 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12, 0x76, 0x82,
1390 0x00, 0x05, 0x71, 0xe1, 0x00, 0x06, 0x00, 0x12,
1391 0x10, 0xe6, 0x00, 0x05, 0x80, 0x82, 0x71, 0xe1,
1392 0x00, 0x05, 0x00, 0x12, 0x76, 0x82, 0x00, 0x04,
1393 0x71, 0xe1, 0x00, 0x06, 0x00, 0x12, 0x10, 0xe6,
1394 0x00, 0x04, 0x80, 0x82, 0x71, 0xe1, 0x00, 0x05,
1395 0x00, 0x12, 0x76, 0x82, 0x00, 0x03, 0x71, 0xe1,
1396 0x00, 0x06, 0x00, 0x12, 0x10, 0xe6, 0x00, 0x03,
1397 0x80, 0x82, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12,
1398 0x76, 0x82, 0x00, 0x02, 0x10, 0xe6, 0x00, 0x02,
1399 0x71, 0xe1, 0x00, 0x06, 0x00, 0x12, 0x80, 0x82,
1400 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12, 0x76, 0x82,
1401 0x00, 0x01, 0x10, 0xe6, 0x00, 0x01, 0x71, 0xe1,
1402 0x00, 0x06, 0x00, 0x12, 0x80, 0x82, 0x71, 0xe1,
1403 0x00, 0x05, 0x00, 0x12, 0x76, 0x82, 0x00, 0x00,
1404 0x71, 0xe1, 0x00, 0x06, 0x00, 0x13, 0xe7, 0x62,
1405 0xe5, 0x01, 0xf9, 0x80, 0x16, 0x9a, 0x8a, 0x16,
1406 0x8a, 0x11, 0xf4, 0xe4, 0x4a, 0x11, 0x88, 0x11,
1407 0xf4, 0x95, 0xf4, 0x95, 0x71, 0xe1, 0x00, 0x05,
1408 0x00, 0x12, 0xee, 0xff, 0x76, 0x82, 0x00, 0x00,
1409 0xee, 0x01, 0x71, 0xe1, 0x00, 0x06, 0x00, 0x11,
1410 0x69, 0x81, 0x00, 0x01, 0x8a, 0x11, 0xf4, 0x95,
1411 0xf4, 0xe4, 0x4a, 0x11, 0x88, 0x11, 0xf4, 0x95,
1412 0xf4, 0x95, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12,
1413 0xee, 0xff, 0x76, 0x82, 0x00, 0x01, 0xee, 0x01,
1414 0x71, 0xe1, 0x00, 0x06, 0x00, 0x11, 0x69, 0x81,
1415 0x00, 0x01, 0x8a, 0x11, 0xf4, 0x95, 0xf4, 0xe4,
1416 0x4a, 0x11, 0x77, 0x11, 0x00, 0x7b, 0x10, 0x81,
1417 0xf0, 0x00, 0x00, 0x94, 0x88, 0x11, 0xf4, 0x95,
1418 0xf4, 0x95, 0x10, 0x81, 0xfa, 0x44, 0x17, 0x9c,
1419 0xf4, 0x95, 0xee, 0xff, 0xf9, 0x80, 0x16, 0x53,
1420 0x77, 0x11, 0x00, 0x7b, 0x10, 0x81, 0xf0, 0x00,
1421 0x00, 0x94, 0x88, 0x11, 0xf4, 0x95, 0xf4, 0x95,
1422 0x76, 0x81, 0x00, 0x01, 0xee, 0x01, 0x76, 0xe1,
1423 0x00, 0x01, 0x00, 0x00, 0x76, 0xe1, 0x00, 0x02,
1424 0x00, 0x21, 0x76, 0xe1, 0x00, 0x03, 0x00, 0x20,
1425 0x76, 0xe1, 0x00, 0x04, 0x00, 0x23, 0x76, 0xe1,
1426 0x00, 0x05, 0x00, 0x22, 0x76, 0xe1, 0x00, 0x06,
1427 0x00, 0x38, 0x76, 0xe1, 0x00, 0x07, 0x00, 0x39,
1428 0x76, 0xe1, 0x00, 0x08, 0x00, 0x15, 0x76, 0xe1,
1429 0x00, 0x09, 0x00, 0x14, 0x76, 0xe1, 0x00, 0x0a,
1430 0x00, 0x00, 0x76, 0xe1, 0x00, 0x0b, 0x00, 0x41,
1431 0x76, 0xe1, 0x00, 0x0c, 0x00, 0x40, 0x76, 0xe1,
1432 0x00, 0x0d, 0x00, 0x43, 0x76, 0xe1, 0x00, 0x0e,
1433 0x00, 0x42, 0x76, 0xe1, 0x00, 0x0f, 0x00, 0x48,
1434 0x76, 0xe1, 0x00, 0x10, 0x00, 0x49, 0x76, 0xe1,
1435 0x00, 0x11, 0x00, 0x1b, 0x76, 0xe1, 0x00, 0x12,
1436 0x00, 0x1a, 0x8a, 0x11, 0xf4, 0x95, 0xf4, 0xe4,
1437 0x4a, 0x11, 0xee, 0xfd, 0x88, 0x11, 0x56, 0x06,
1438 0x4e, 0x00, 0xf9, 0x80, 0x16, 0xa2, 0x77, 0x12,
1439 0x00, 0x7b, 0x77, 0x0e, 0x00, 0x09, 0x10, 0x82,
1440 0x28, 0xf8, 0x00, 0x11, 0xf0, 0x00, 0x00, 0x95,
1441 0x88, 0x11, 0xf4, 0x95, 0xf4, 0x95, 0x10, 0x81,
1442 0xf8, 0x45, 0x17, 0xf0, 0xf2, 0x73, 0x17, 0xfd,
1443 0x77, 0x11, 0xff, 0xff, 0x76, 0x81, 0x00, 0x01,
1444 0xe9, 0x01, 0x56, 0x00, 0xf1, 0x80, 0x10, 0xf8,
1445 0x00, 0x0b, 0xf8, 0x45, 0x17, 0xfd, 0xfb, 0x80,
1446 0x18, 0x10, 0xf4, 0x95, 0x48, 0x11, 0xf9, 0x80,
1447 0x16, 0x9a, 0xee, 0x03, 0x48, 0x11, 0x8a, 0x11,
1448 0xf4, 0x95, 0xf4, 0xe4, 0x4a, 0x11, 0x88, 0x11,
1449 0xf4, 0x95, 0xee, 0xff, 0x71, 0xe1, 0x00, 0x01,
1450 0x00, 0x11, 0xee, 0x01, 0x10, 0x81, 0x8a, 0x11,
1451 0xf4, 0x95, 0xf4, 0xe4, 0x4a, 0x11, 0xee, 0xff,
1452 0xfb, 0x80, 0x16, 0xa2, 0x88, 0x11, 0xf4, 0x95,
1453 0x77, 0x10, 0xff, 0xff, 0xf4, 0xa9, 0xf8, 0x30,
1454 0x18, 0xc3, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12,
1455 0x76, 0x82, 0x00, 0x00, 0x71, 0xe1, 0x00, 0x06,
1456 0x00, 0x12, 0x76, 0x82, 0x00, 0x00, 0x71, 0xe1,
1457 0x00, 0x05, 0x00, 0x12, 0x76, 0x82, 0x00, 0x01,
1458 0x71, 0xe1, 0x00, 0x06, 0x00, 0x12, 0x76, 0x82,
1459 0x00, 0x00, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12,
1460 0x76, 0x82, 0x00, 0x02, 0x71, 0xe1, 0x00, 0x06,
1461 0x00, 0x12, 0x76, 0x82, 0x00, 0x00, 0x71, 0xe1,
1462 0x00, 0x05, 0x00, 0x12, 0x76, 0x82, 0x00, 0x03,
1463 0x71, 0xe1, 0x00, 0x06, 0x00, 0x12, 0x76, 0x82,
1464 0x00, 0x00, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12,
1465 0x76, 0x82, 0x00, 0x04, 0x71, 0xe1, 0x00, 0x06,
1466 0x00, 0x12, 0x76, 0x82, 0x00, 0x00, 0x71, 0xe1,
1467 0x00, 0x05, 0x00, 0x12, 0x76, 0x82, 0x00, 0x05,
1468 0x71, 0xe1, 0x00, 0x06, 0x00, 0x12, 0x76, 0x82,
1469 0x00, 0x00, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12,
1470 0x76, 0x82, 0x00, 0x06, 0x71, 0xe1, 0x00, 0x06,
1471 0x00, 0x12, 0x76, 0x82, 0x00, 0x01, 0x71, 0xe1,
1472 0x00, 0x05, 0x00, 0x12, 0x76, 0x82, 0x00, 0x07,
1473 0x71, 0xe1, 0x00, 0x06, 0x00, 0x12, 0x76, 0x82,
1474 0x20, 0x00, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12,
1475 0x76, 0x82, 0x00, 0x08, 0x71, 0xe1, 0x00, 0x06,
1476 0x00, 0x12, 0x76, 0x82, 0x00, 0x00, 0x71, 0xe1,
1477 0x00, 0x05, 0x00, 0x12, 0x76, 0x82, 0x00, 0x09,
1478 0x71, 0xe1, 0x00, 0x06, 0x00, 0x12, 0x76, 0x82,
1479 0x00, 0x00, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12,
1480 0x76, 0x82, 0x00, 0x0a, 0x71, 0xe1, 0x00, 0x06,
1481 0x00, 0x12, 0x76, 0x82, 0x00, 0x00, 0x71, 0xe1,
1482 0x00, 0x05, 0x00, 0x12, 0x76, 0x82, 0x00, 0x0b,
1483 0x71, 0xe1, 0x00, 0x06, 0x00, 0x12, 0x76, 0x82,
1484 0x00, 0x00, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12,
1485 0x76, 0x82, 0x00, 0x0c, 0x71, 0xe1, 0x00, 0x06,
1486 0x00, 0x12, 0x76, 0x82, 0x00, 0x00, 0x71, 0xe1,
1487 0x00, 0x05, 0x00, 0x12, 0x76, 0x82, 0x00, 0x0d,
1488 0x71, 0xe1, 0x00, 0x06, 0x00, 0x12, 0x76, 0x82,
1489 0x00, 0x00, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12,
1490 0x76, 0x82, 0x00, 0x0e, 0x71, 0xe1, 0x00, 0x06,
1491 0x00, 0x12, 0x76, 0x82, 0x00, 0x00, 0x10, 0xe1,
1492 0x00, 0x07, 0xf9, 0x80, 0x16, 0x76, 0x10, 0xe1,
1493 0x00, 0x08, 0xf9, 0x80, 0x16, 0x76, 0x10, 0xe1,
1494 0x00, 0x07, 0xf9, 0x80, 0x16, 0x66, 0x10, 0xe1,
1495 0x00, 0x08, 0xf9, 0x80, 0x16, 0x66, 0xf0, 0x73,
1496 0x18, 0xd1, 0x77, 0x11, 0x00, 0x7b, 0x10, 0x81,
1497 0xfb, 0x80, 0x18, 0x10, 0xf0, 0x00, 0x00, 0x95,
1498 0x77, 0x11, 0x00, 0x7b, 0x10, 0x81, 0xfb, 0x80,
1499 0x18, 0x10, 0xf0, 0x00, 0x00, 0x9e, 0xf9, 0x80,
1500 0x16, 0x9a, 0xee, 0x01, 0x8a, 0x11, 0xf4, 0xe4,
1501 0x4a, 0x11, 0x88, 0x11, 0xee, 0xff, 0xf4, 0x95,
1502 0x10, 0x04, 0x71, 0xe1, 0x00, 0x03, 0x00, 0x11,
1503 0xee, 0x01, 0x80, 0x81, 0x8a, 0x11, 0xf4, 0x95,
1504 0xf4, 0xe4, 0x4a, 0x11, 0x4a, 0x16, 0xf4, 0x95,
1505 0x71, 0x04, 0x00, 0x16, 0xfb, 0x80, 0x16, 0xa2,
1506 0x88, 0x11, 0xf4, 0x95, 0x71, 0xe1, 0x00, 0x02,
1507 0x00, 0x12, 0x76, 0x82, 0x00, 0x10, 0x10, 0xe6,
1508 0x00, 0x01, 0x71, 0xe1, 0x00, 0x03, 0x00, 0x12,
1509 0x80, 0x82, 0x71, 0xe1, 0x00, 0x04, 0x00, 0x12,
1510 0x10, 0xe6, 0x00, 0x02, 0x80, 0x82, 0xe7, 0x62,
1511 0x71, 0xe1, 0x00, 0x02, 0x00, 0x13, 0xe5, 0x01,
1512 0xf9, 0x80, 0x16, 0x9a, 0x8a, 0x16, 0x8a, 0x11,
1513 0xf4, 0xe4, 0x4a, 0x11, 0x88, 0x11, 0xee, 0xff,
1514 0xee, 0x01, 0x10, 0xe1, 0x00, 0x01, 0x8a, 0x11,
1515 0xf4, 0x95, 0xf4, 0xe4, 0x4a, 0x11, 0x77, 0x11,
1516 0x00, 0x7b, 0x10, 0x81, 0xf0, 0x00, 0x00, 0xb3,
1517 0x88, 0x11, 0xf4, 0x95, 0xf4, 0x95, 0x10, 0x81,
1518 0xfa, 0x44, 0x19, 0x2a, 0xf4, 0x95, 0xee, 0xff,
1519 0xf9, 0x80, 0x16, 0x53, 0x77, 0x11, 0x00, 0x7b,
1520 0x10, 0x81, 0xf0, 0x00, 0x00, 0xb3, 0x88, 0x11,
1521 0xf4, 0x95, 0xf4, 0x95, 0x76, 0x81, 0x00, 0x01,
1522 0xee, 0x01, 0x76, 0xe1, 0x00, 0x01, 0x00, 0x00,
1523 0x76, 0xe1, 0x00, 0x02, 0x00, 0x13, 0x76, 0xe1,
1524 0x00, 0x03, 0x00, 0x26, 0x76, 0xe1, 0x00, 0x04,
1525 0x00, 0x25, 0x76, 0xe1, 0x00, 0x05, 0x00, 0x24,
1526 0x76, 0xe1, 0x00, 0x06, 0x00, 0x00, 0x76, 0xe1,
1527 0x00, 0x07, 0x00, 0x17, 0x76, 0xe1, 0x00, 0x08,
1528 0x00, 0x32, 0x76, 0xe1, 0x00, 0x09, 0x00, 0x31,
1529 0x76, 0xe1, 0x00, 0x0a, 0x00, 0x30, 0x8a, 0x11,
1530 0xf4, 0x95, 0xf4, 0xe4, 0x4a, 0x11, 0x4a, 0x16,
1531 0x4a, 0x17, 0xee, 0xff, 0xf4, 0x95, 0x71, 0x06,
1532 0x00, 0x17, 0xfb, 0x80, 0x16, 0xa2, 0x88, 0x11,
1533 0xf4, 0x95, 0xf7, 0xb8, 0x10, 0xf8, 0x00, 0x11,
1534 0xf0, 0x10, 0xff, 0xff, 0xfa, 0x45, 0x19, 0x73,
1535 0x77, 0x16, 0xff, 0xff, 0x77, 0x12, 0x00, 0x7b,
1536 0x77, 0x0e, 0x00, 0x05, 0x10, 0x82, 0x28, 0xf8,
1537 0x00, 0x11, 0xf0, 0x00, 0x00, 0xb4, 0x88, 0x11,
1538 0xf4, 0x95, 0xf4, 0x95, 0x10, 0x81, 0xf8, 0x44,
1539 0x19, 0x84, 0xf2, 0x73, 0x19, 0x84, 0xf4, 0x95,
1540 0xe7, 0x16, 0x77, 0x11, 0x00, 0x7b, 0x10, 0x81,
1541 0xf0, 0x00, 0x00, 0xb4, 0x88, 0x11, 0xf4, 0x95,
1542 0x77, 0x12, 0x00, 0x02, 0x10, 0x81, 0xf8, 0x45,
1543 0x19, 0x6f, 0x6e, 0xea, 0xff, 0xff, 0x19, 0x7c,
1544 0x6d, 0xe9, 0x00, 0x05, 0x61, 0xf8, 0x00, 0x17,
1545 0x00, 0x01, 0xfa, 0x20, 0x19, 0x8f, 0x76, 0x86,
1546 0x00, 0x01, 0xfb, 0x80, 0x19, 0x97, 0xf4, 0x95,
1547 0x48, 0x16, 0xf9, 0x80, 0x16, 0x9a, 0xee, 0x01,
1548 0x8a, 0x17, 0x48, 0x16, 0x8a, 0x16, 0x8a, 0x11,
1549 0xf4, 0xe4, 0x4a, 0x11, 0xee, 0xff, 0xfb, 0x80,
1550 0x16, 0xa2, 0x88, 0x11, 0xf4, 0x95, 0x77, 0x10,
1551 0xff, 0xff, 0xf4, 0xa9, 0xf8, 0x30, 0x19, 0xcc,
1552 0x71, 0xe1, 0x00, 0x02, 0x00, 0x12, 0x69, 0x82,
1553 0x00, 0x10, 0x71, 0xe1, 0x00, 0x02, 0x00, 0x12,
1554 0x68, 0x82, 0xf7, 0xff, 0x71, 0xe1, 0x00, 0x02,
1555 0x00, 0x12, 0x68, 0x82, 0xfb, 0xff, 0x71, 0xe1,
1556 0x00, 0x02, 0x00, 0x12, 0x68, 0x82, 0xff, 0xf0,
1557 0x71, 0xe1, 0x00, 0x03, 0x00, 0x12, 0x76, 0x82,
1558 0xff, 0xff, 0x71, 0xe1, 0x00, 0x04, 0x00, 0x12,
1559 0x76, 0x82, 0xff, 0xff, 0x71, 0xe1, 0x00, 0x02,
1560 0x00, 0x12, 0x69, 0x82, 0x00, 0x20, 0x71, 0xe1,
1561 0x00, 0x02, 0x00, 0x11, 0xf2, 0x73, 0x19, 0xda,
1562 0x68, 0x81, 0xff, 0xef, 0x77, 0x11, 0x00, 0x7b,
1563 0x10, 0x81, 0xfb, 0x80, 0x19, 0x97, 0xf0, 0x00,
1564 0x00, 0xb4, 0x77, 0x11, 0x00, 0x7b, 0x10, 0x81,
1565 0xfb, 0x80, 0x19, 0x97, 0xf0, 0x00, 0x00, 0xb9,
1566 0xf9, 0x80, 0x16, 0x9a, 0xee, 0x01, 0x8a, 0x11,
1567 0xf4, 0xe4, 0x00, 0xa4, 0x00, 0x00, 0x19, 0xdf,
1568 0x00, 0x01, 0x2a, 0xe6, 0x00, 0x00, 0x00, 0x01,
1569 0x2a, 0xe7, 0x00, 0x00, 0x00, 0x03, 0x2a, 0x12,
1570 0x0c, 0x01, 0xc3, 0x4f, 0x00, 0x00, 0x00, 0x01,
1571 0x2a, 0x15, 0x00, 0x00, 0x00, 0x02, 0x2a, 0x16,
1572 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x2a, 0x5d,
1573 0x00, 0x43, 0x00, 0x6f, 0x00, 0x70, 0x00, 0x79,
1574 0x00, 0x72, 0x00, 0x69, 0x00, 0x67, 0x00, 0x68,
1575 0x00, 0x74, 0x00, 0x20, 0x00, 0x54, 0x00, 0x65,
1576 0x00, 0x63, 0x00, 0x68, 0x00, 0x6e, 0x00, 0x6f,
1577 0x00, 0x54, 0x00, 0x72, 0x00, 0x65, 0x00, 0x6e,
1578 0x00, 0x64, 0x00, 0x20, 0x00, 0x41, 0x00, 0x47,
1579 0x00, 0x00, 0x00, 0x04, 0x2a, 0x76, 0x00, 0x30,
1580 0x00, 0x2e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x0c,
1581 0x2a, 0x7a, 0x00, 0x46, 0x00, 0x65, 0x00, 0x62,
1582 0x00, 0x20, 0x00, 0x32, 0x00, 0x37, 0x00, 0x20,
1583 0x00, 0x32, 0x00, 0x30, 0x00, 0x30, 0x00, 0x31,
1584 0x00, 0x00, 0x00, 0x09, 0x2a, 0x86, 0x00, 0x31,
1585 0x00, 0x34, 0x00, 0x3a, 0x00, 0x33, 0x00, 0x35,
1586 0x00, 0x3a, 0x00, 0x33, 0x00, 0x33, 0x00, 0x00,
1587 0x00, 0x0f, 0x2a, 0x8f, 0x00, 0x00, 0x00, 0x00,
1588 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
1589 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1590 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1591 0x00, 0x00, 0x00, 0x01, 0x2a, 0x9e, 0x00, 0x00,
1592 0x00, 0x01, 0x2a, 0x9f, 0x00, 0x00, 0x00, 0x01,
1593 0x2a, 0xa0, 0x00, 0x00, 0x00, 0x01, 0x2a, 0xa1,
1594 0x00, 0x00, 0x00, 0x01, 0x2a, 0xa2, 0x00, 0x00,
1595 0x00, 0x01, 0x29, 0x7e, 0x00, 0x00, 0x00, 0x02,
1596 0x29, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
1597 0x29, 0x82, 0xff, 0xff, 0x00, 0x01, 0x2a, 0xa7,
1598 0x00, 0x00, 0x00, 0x05, 0x2a, 0xa8, 0x71, 0x41,
1599 0x20, 0x00, 0x20, 0x00, 0x00, 0x23, 0x04, 0x00,
1600 0x00, 0x0a, 0x2a, 0xad, 0x00, 0x00, 0x00, 0x00,
1601 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1602 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1603 0x00, 0x0f, 0x2a, 0xb7, 0x00, 0x00, 0x00, 0x00,
1604 0x00, 0x00, 0x00, 0x40, 0x00, 0xa0, 0x82, 0x40,
1605 0x00, 0x08, 0x30, 0x7f, 0x00, 0x80, 0x01, 0x80,
1606 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1607 0x00, 0x00, 0x00, 0x01, 0x27, 0x6e, 0x00, 0x00,
1608 0x00, 0x01, 0x27, 0x6f, 0x00, 0x00, 0x00, 0x00,
1609 0x00, 0x09, 0x00, 0x00, 0x1a, 0x83, 0x04, 0xe8,
1610 0x04, 0xcf, 0x04, 0xc5, 0x04, 0xba, 0x04, 0xb0,
1611 0x04, 0xac, 0x04, 0x9c, 0x04, 0x8c, 0x04, 0x81,
1612 0x00, 0x78, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x73,
1613 0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
1614 0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
1615 0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
1616 0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
1617 0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
1618 0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
1619 0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
1620 0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
1621 0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
1622 0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
1623 0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
1624 0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
1625 0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
1626 0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
1627 0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
1628 0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
1629 0x07, 0xaa, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
1630 0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
1631 0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
1632 0x02, 0x23, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
1633 0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
1634 0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
1635 0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
1636 0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
1637 0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
1638 0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
1639 0x05, 0xe5, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
1640 0x02, 0xb5, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
1641 0x0e, 0x33, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
1642 0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0x00, 0x00,
1643};
1644
diff --git a/drivers/media/dvb/ttusb-dec/Kconfig b/drivers/media/dvb/ttusb-dec/Kconfig
new file mode 100644
index 000000000000..c334526af66f
--- /dev/null
+++ b/drivers/media/dvb/ttusb-dec/Kconfig
@@ -0,0 +1,21 @@
1config DVB_TTUSB_DEC
2 tristate "Technotrend/Hauppauge USB DEC devices"
3 depends on DVB_CORE && USB
4 select FW_LOADER
5 select CRC32
6 help
7 Support for external USB adapters designed by Technotrend and
8 produced by Hauppauge, shipped under the brand name 'DEC2000-t'
9 and 'DEC3000-s'.
10
11 Even if these devices have a MPEG decoder built in, they transmit
12 only compressed MPEG data over the USB bus, so you need
13 an external software decoder to watch TV on your computer.
14
15 This driver needs external firmware. Please use the commands
16 "<kerneldir>/Documentation/dvb/get_dvb_firmware dec2000t",
17 "<kerneldir>/Documentation/dvb/get_dvb_firmware dec2540t",
18 "<kerneldir>/Documentation/dvb/get_dvb_firmware dec3000s",
19 download/extract them, and then copy them to /usr/lib/hotplug/firmware.
20
21 Say Y if you own such a device and want to use it.
diff --git a/drivers/media/dvb/ttusb-dec/Makefile b/drivers/media/dvb/ttusb-dec/Makefile
new file mode 100644
index 000000000000..b41bf1f06a9f
--- /dev/null
+++ b/drivers/media/dvb/ttusb-dec/Makefile
@@ -0,0 +1,3 @@
1obj-$(CONFIG_DVB_TTUSB_DEC) += ttusb_dec.o ttusbdecfe.o
2
3EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/
diff --git a/drivers/media/dvb/ttusb-dec/ttusb_dec.c b/drivers/media/dvb/ttusb-dec/ttusb_dec.c
new file mode 100644
index 000000000000..64e771bd8907
--- /dev/null
+++ b/drivers/media/dvb/ttusb-dec/ttusb_dec.c
@@ -0,0 +1,1744 @@
1/*
2 * TTUSB DEC Driver
3 *
4 * Copyright (C) 2003-2004 Alex Woods <linux-dvb@giblets.org>
5 * IR support by Peter Beutner <p.beutner@gmx.net>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 *
21 */
22
23#include <asm/semaphore.h>
24#include <linux/list.h>
25#include <linux/module.h>
26#include <linux/moduleparam.h>
27#include <linux/pci.h>
28#include <linux/slab.h>
29#include <linux/spinlock.h>
30#include <linux/usb.h>
31#include <linux/version.h>
32#include <linux/interrupt.h>
33#include <linux/firmware.h>
34#include <linux/crc32.h>
35#include <linux/init.h>
36#include <linux/input.h>
37
38#include "dmxdev.h"
39#include "dvb_demux.h"
40#include "dvb_filter.h"
41#include "dvb_frontend.h"
42#include "dvb_net.h"
43#include "ttusbdecfe.h"
44
45static int debug;
46static int output_pva;
47static int enable_rc;
48
49module_param(debug, int, 0644);
50MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
51module_param(output_pva, int, 0444);
52MODULE_PARM_DESC(output_pva, "Output PVA from dvr device (default:off)");
53module_param(enable_rc, int, 0644);
54MODULE_PARM_DESC(enable_rc, "Turn on/off IR remote control(default: off)");
55
56#define dprintk if (debug) printk
57
58#define DRIVER_NAME "TechnoTrend/Hauppauge DEC USB"
59
60#define COMMAND_PIPE 0x03
61#define RESULT_PIPE 0x04
62#define IN_PIPE 0x08
63#define OUT_PIPE 0x07
64#define IRQ_PIPE 0x0A
65
66#define COMMAND_PACKET_SIZE 0x3c
67#define ARM_PACKET_SIZE 0x1000
68#define IRQ_PACKET_SIZE 0x8
69
70#define ISO_BUF_COUNT 0x04
71#define FRAMES_PER_ISO_BUF 0x04
72#define ISO_FRAME_SIZE 0x0380
73
74#define MAX_PVA_LENGTH 6144
75
76enum ttusb_dec_model {
77 TTUSB_DEC2000T,
78 TTUSB_DEC2540T,
79 TTUSB_DEC3000S
80};
81
82enum ttusb_dec_packet_type {
83 TTUSB_DEC_PACKET_PVA,
84 TTUSB_DEC_PACKET_SECTION,
85 TTUSB_DEC_PACKET_EMPTY
86};
87
88enum ttusb_dec_interface {
89 TTUSB_DEC_INTERFACE_INITIAL,
90 TTUSB_DEC_INTERFACE_IN,
91 TTUSB_DEC_INTERFACE_OUT
92};
93
94struct ttusb_dec {
95 enum ttusb_dec_model model;
96 char *model_name;
97 char *firmware_name;
98 int can_playback;
99
100 /* DVB bits */
101 struct dvb_adapter *adapter;
102 struct dmxdev dmxdev;
103 struct dvb_demux demux;
104 struct dmx_frontend frontend;
105 struct dvb_net dvb_net;
106 struct dvb_frontend* fe;
107
108 u16 pid[DMX_PES_OTHER];
109
110 /* USB bits */
111 struct usb_device *udev;
112 u8 trans_count;
113 unsigned int command_pipe;
114 unsigned int result_pipe;
115 unsigned int in_pipe;
116 unsigned int out_pipe;
117 unsigned int irq_pipe;
118 enum ttusb_dec_interface interface;
119 struct semaphore usb_sem;
120
121 void *irq_buffer;
122 struct urb *irq_urb;
123 dma_addr_t irq_dma_handle;
124 void *iso_buffer;
125 dma_addr_t iso_dma_handle;
126 struct urb *iso_urb[ISO_BUF_COUNT];
127 int iso_stream_count;
128 struct semaphore iso_sem;
129
130 u8 packet[MAX_PVA_LENGTH + 4];
131 enum ttusb_dec_packet_type packet_type;
132 int packet_state;
133 int packet_length;
134 int packet_payload_length;
135 u16 next_packet_id;
136
137 int pva_stream_count;
138 int filter_stream_count;
139
140 struct dvb_filter_pes2ts a_pes2ts;
141 struct dvb_filter_pes2ts v_pes2ts;
142
143 u8 v_pes[16 + MAX_PVA_LENGTH];
144 int v_pes_length;
145 int v_pes_postbytes;
146
147 struct list_head urb_frame_list;
148 struct tasklet_struct urb_tasklet;
149 spinlock_t urb_frame_list_lock;
150
151 struct dvb_demux_filter *audio_filter;
152 struct dvb_demux_filter *video_filter;
153 struct list_head filter_info_list;
154 spinlock_t filter_info_list_lock;
155
156 struct input_dev rc_input_dev;
157
158 int active; /* Loaded successfully */
159};
160
161struct urb_frame {
162 u8 data[ISO_FRAME_SIZE];
163 int length;
164 struct list_head urb_frame_list;
165};
166
167struct filter_info {
168 u8 stream_id;
169 struct dvb_demux_filter *filter;
170 struct list_head filter_info_list;
171};
172
173static u16 rc_keys[] = {
174 KEY_POWER,
175 KEY_MUTE,
176 KEY_1,
177 KEY_2,
178 KEY_3,
179 KEY_4,
180 KEY_5,
181 KEY_6,
182 KEY_7,
183 KEY_8,
184 KEY_9,
185 KEY_0,
186 KEY_CHANNELUP,
187 KEY_VOLUMEDOWN,
188 KEY_OK,
189 KEY_VOLUMEUP,
190 KEY_CHANNELDOWN,
191 KEY_PREVIOUS,
192 KEY_ESC,
193 KEY_RED,
194 KEY_GREEN,
195 KEY_YELLOW,
196 KEY_BLUE,
197 KEY_OPTION,
198 KEY_M,
199 KEY_RADIO
200};
201
202static void ttusb_dec_set_model(struct ttusb_dec *dec,
203 enum ttusb_dec_model model);
204
205static void ttusb_dec_handle_irq( struct urb *urb, struct pt_regs *regs)
206{
207 struct ttusb_dec * dec = urb->context;
208 char *buffer = dec->irq_buffer;
209 int retval;
210
211 switch(urb->status) {
212 case 0: /*success*/
213 break;
214 case -ECONNRESET:
215 case -ENOENT:
216 case -ESHUTDOWN:
217 case -ETIMEDOUT:
218 /* this urb is dead, cleanup */
219 dprintk("%s:urb shutting down with status: %d\n",
220 __FUNCTION__, urb->status);
221 return;
222 default:
223 dprintk("%s:nonzero status received: %d\n",
224 __FUNCTION__,urb->status);
225 goto exit;
226 }
227
228 if( (buffer[0] == 0x1) && (buffer[2] == 0x15) ) {
229 /* IR - Event */
230 /* this is an fact a bit too simple implementation;
231 * the box also reports a keyrepeat signal
232 * (with buffer[3] == 0x40) in an intervall of ~100ms.
233 * But to handle this correctly we had to imlemenent some
234 * kind of timer which signals a 'key up' event if no
235 * keyrepeat signal is recieved for lets say 200ms.
236 * this should/could be added later ...
237 * for now lets report each signal as a key down and up*/
238 dprintk("%s:rc signal:%d\n", __FUNCTION__, buffer[4]);
239 input_report_key(&dec->rc_input_dev,rc_keys[buffer[4]-1],1);
240 input_report_key(&dec->rc_input_dev,rc_keys[buffer[4]-1],0);
241 input_sync(&dec->rc_input_dev);
242 }
243
244exit: retval = usb_submit_urb(urb, GFP_ATOMIC);
245 if(retval)
246 printk("%s - usb_commit_urb failed with result: %d\n",
247 __FUNCTION__, retval);
248}
249
250static u16 crc16(u16 crc, const u8 *buf, size_t len)
251{
252 u16 tmp;
253
254 while (len--) {
255 crc ^= *buf++;
256 crc ^= (u8)crc >> 4;
257 tmp = (u8)crc;
258 crc ^= (tmp ^ (tmp << 1)) << 4;
259 }
260 return crc;
261}
262
263static int ttusb_dec_send_command(struct ttusb_dec *dec, const u8 command,
264 int param_length, const u8 params[],
265 int *result_length, u8 cmd_result[])
266{
267 int result, actual_len, i;
268 u8 *b;
269
270 dprintk("%s\n", __FUNCTION__);
271
272 b = kmalloc(COMMAND_PACKET_SIZE + 4, GFP_KERNEL);
273 if (!b)
274 return -ENOMEM;
275
276 if ((result = down_interruptible(&dec->usb_sem))) {
277 kfree(b);
278 printk("%s: Failed to down usb semaphore.\n", __FUNCTION__);
279 return result;
280 }
281
282 b[0] = 0xaa;
283 b[1] = ++dec->trans_count;
284 b[2] = command;
285 b[3] = param_length;
286
287 if (params)
288 memcpy(&b[4], params, param_length);
289
290 if (debug) {
291 printk("%s: command: ", __FUNCTION__);
292 for (i = 0; i < param_length + 4; i++)
293 printk("0x%02X ", b[i]);
294 printk("\n");
295 }
296
297 result = usb_bulk_msg(dec->udev, dec->command_pipe, b,
298 COMMAND_PACKET_SIZE + 4, &actual_len, 1000);
299
300 if (result) {
301 printk("%s: command bulk message failed: error %d\n",
302 __FUNCTION__, result);
303 up(&dec->usb_sem);
304 kfree(b);
305 return result;
306 }
307
308 result = usb_bulk_msg(dec->udev, dec->result_pipe, b,
309 COMMAND_PACKET_SIZE + 4, &actual_len, 1000);
310
311 if (result) {
312 printk("%s: result bulk message failed: error %d\n",
313 __FUNCTION__, result);
314 up(&dec->usb_sem);
315 kfree(b);
316 return result;
317 } else {
318 if (debug) {
319 printk("%s: result: ", __FUNCTION__);
320 for (i = 0; i < actual_len; i++)
321 printk("0x%02X ", b[i]);
322 printk("\n");
323 }
324
325 if (result_length)
326 *result_length = b[3];
327 if (cmd_result && b[3] > 0)
328 memcpy(cmd_result, &b[4], b[3]);
329
330 up(&dec->usb_sem);
331
332 kfree(b);
333 return 0;
334 }
335}
336
337static int ttusb_dec_get_stb_state (struct ttusb_dec *dec, unsigned int *mode,
338 unsigned int *model, unsigned int *version)
339{
340 u8 c[COMMAND_PACKET_SIZE];
341 int c_length;
342 int result;
343 unsigned int tmp;
344
345 dprintk("%s\n", __FUNCTION__);
346
347 result = ttusb_dec_send_command(dec, 0x08, 0, NULL, &c_length, c);
348 if (result)
349 return result;
350
351 if (c_length >= 0x0c) {
352 if (mode != NULL) {
353 memcpy(&tmp, c, 4);
354 *mode = ntohl(tmp);
355 }
356 if (model != NULL) {
357 memcpy(&tmp, &c[4], 4);
358 *model = ntohl(tmp);
359 }
360 if (version != NULL) {
361 memcpy(&tmp, &c[8], 4);
362 *version = ntohl(tmp);
363 }
364 return 0;
365 } else {
366 return -1;
367 }
368}
369
370static int ttusb_dec_audio_pes2ts_cb(void *priv, unsigned char *data)
371{
372 struct ttusb_dec *dec = (struct ttusb_dec *)priv;
373
374 dec->audio_filter->feed->cb.ts(data, 188, NULL, 0,
375 &dec->audio_filter->feed->feed.ts,
376 DMX_OK);
377
378 return 0;
379}
380
381static int ttusb_dec_video_pes2ts_cb(void *priv, unsigned char *data)
382{
383 struct ttusb_dec *dec = (struct ttusb_dec *)priv;
384
385 dec->video_filter->feed->cb.ts(data, 188, NULL, 0,
386 &dec->video_filter->feed->feed.ts,
387 DMX_OK);
388
389 return 0;
390}
391
392static void ttusb_dec_set_pids(struct ttusb_dec *dec)
393{
394 u8 b[] = { 0x00, 0x00, 0x00, 0x00,
395 0x00, 0x00, 0xff, 0xff,
396 0xff, 0xff, 0xff, 0xff };
397
398 u16 pcr = htons(dec->pid[DMX_PES_PCR]);
399 u16 audio = htons(dec->pid[DMX_PES_AUDIO]);
400 u16 video = htons(dec->pid[DMX_PES_VIDEO]);
401
402 dprintk("%s\n", __FUNCTION__);
403
404 memcpy(&b[0], &pcr, 2);
405 memcpy(&b[2], &audio, 2);
406 memcpy(&b[4], &video, 2);
407
408 ttusb_dec_send_command(dec, 0x50, sizeof(b), b, NULL, NULL);
409
410 dvb_filter_pes2ts_init(&dec->a_pes2ts, dec->pid[DMX_PES_AUDIO],
411 ttusb_dec_audio_pes2ts_cb, dec);
412 dvb_filter_pes2ts_init(&dec->v_pes2ts, dec->pid[DMX_PES_VIDEO],
413 ttusb_dec_video_pes2ts_cb, dec);
414 dec->v_pes_length = 0;
415 dec->v_pes_postbytes = 0;
416}
417
418static void ttusb_dec_process_pva(struct ttusb_dec *dec, u8 *pva, int length)
419{
420 if (length < 8) {
421 printk("%s: packet too short - discarding\n", __FUNCTION__);
422 return;
423 }
424
425 if (length > 8 + MAX_PVA_LENGTH) {
426 printk("%s: packet too long - discarding\n", __FUNCTION__);
427 return;
428 }
429
430 switch (pva[2]) {
431
432 case 0x01: { /* VideoStream */
433 int prebytes = pva[5] & 0x03;
434 int postbytes = (pva[5] & 0x0c) >> 2;
435 u16 v_pes_payload_length;
436
437 if (output_pva) {
438 dec->video_filter->feed->cb.ts(pva, length, NULL, 0,
439 &dec->video_filter->feed->feed.ts, DMX_OK);
440 return;
441 }
442
443 if (dec->v_pes_postbytes > 0 &&
444 dec->v_pes_postbytes == prebytes) {
445 memcpy(&dec->v_pes[dec->v_pes_length],
446 &pva[12], prebytes);
447
448 dvb_filter_pes2ts(&dec->v_pes2ts, dec->v_pes,
449 dec->v_pes_length + prebytes, 1);
450 }
451
452 if (pva[5] & 0x10) {
453 dec->v_pes[7] = 0x80;
454 dec->v_pes[8] = 0x05;
455
456 dec->v_pes[9] = 0x21 | ((pva[8] & 0xc0) >> 5);
457 dec->v_pes[10] = ((pva[8] & 0x3f) << 2) |
458 ((pva[9] & 0xc0) >> 6);
459 dec->v_pes[11] = 0x01 |
460 ((pva[9] & 0x3f) << 2) |
461 ((pva[10] & 0x80) >> 6);
462 dec->v_pes[12] = ((pva[10] & 0x7f) << 1) |
463 ((pva[11] & 0xc0) >> 7);
464 dec->v_pes[13] = 0x01 | ((pva[11] & 0x7f) << 1);
465
466 memcpy(&dec->v_pes[14], &pva[12 + prebytes],
467 length - 12 - prebytes);
468 dec->v_pes_length = 14 + length - 12 - prebytes;
469 } else {
470 dec->v_pes[7] = 0x00;
471 dec->v_pes[8] = 0x00;
472
473 memcpy(&dec->v_pes[9], &pva[8], length - 8);
474 dec->v_pes_length = 9 + length - 8;
475 }
476
477 dec->v_pes_postbytes = postbytes;
478
479 if (dec->v_pes[9 + dec->v_pes[8]] == 0x00 &&
480 dec->v_pes[10 + dec->v_pes[8]] == 0x00 &&
481 dec->v_pes[11 + dec->v_pes[8]] == 0x01)
482 dec->v_pes[6] = 0x84;
483 else
484 dec->v_pes[6] = 0x80;
485
486 v_pes_payload_length = htons(dec->v_pes_length - 6 +
487 postbytes);
488 memcpy(&dec->v_pes[4], &v_pes_payload_length, 2);
489
490 if (postbytes == 0)
491 dvb_filter_pes2ts(&dec->v_pes2ts, dec->v_pes,
492 dec->v_pes_length, 1);
493
494 break;
495 }
496
497 case 0x02: /* MainAudioStream */
498 if (output_pva) {
499 dec->audio_filter->feed->cb.ts(pva, length, NULL, 0,
500 &dec->audio_filter->feed->feed.ts, DMX_OK);
501 return;
502 }
503
504 dvb_filter_pes2ts(&dec->a_pes2ts, &pva[8], length - 8,
505 pva[5] & 0x10);
506 break;
507
508 default:
509 printk("%s: unknown PVA type: %02x.\n", __FUNCTION__,
510 pva[2]);
511 break;
512 }
513}
514
515static void ttusb_dec_process_filter(struct ttusb_dec *dec, u8 *packet,
516 int length)
517{
518 struct list_head *item;
519 struct filter_info *finfo;
520 struct dvb_demux_filter *filter = NULL;
521 unsigned long flags;
522 u8 sid;
523
524 sid = packet[1];
525 spin_lock_irqsave(&dec->filter_info_list_lock, flags);
526 for (item = dec->filter_info_list.next; item != &dec->filter_info_list;
527 item = item->next) {
528 finfo = list_entry(item, struct filter_info, filter_info_list);
529 if (finfo->stream_id == sid) {
530 filter = finfo->filter;
531 break;
532 }
533 }
534 spin_unlock_irqrestore(&dec->filter_info_list_lock, flags);
535
536 if (filter)
537 filter->feed->cb.sec(&packet[2], length - 2, NULL, 0,
538 &filter->filter, DMX_OK);
539}
540
541static void ttusb_dec_process_packet(struct ttusb_dec *dec)
542{
543 int i;
544 u16 csum = 0;
545 u16 packet_id;
546
547 if (dec->packet_length % 2) {
548 printk("%s: odd sized packet - discarding\n", __FUNCTION__);
549 return;
550 }
551
552 for (i = 0; i < dec->packet_length; i += 2)
553 csum ^= ((dec->packet[i] << 8) + dec->packet[i + 1]);
554
555 if (csum) {
556 printk("%s: checksum failed - discarding\n", __FUNCTION__);
557 return;
558 }
559
560 packet_id = dec->packet[dec->packet_length - 4] << 8;
561 packet_id += dec->packet[dec->packet_length - 3];
562
563 if ((packet_id != dec->next_packet_id) && dec->next_packet_id) {
564 printk("%s: warning: lost packets between %u and %u\n",
565 __FUNCTION__, dec->next_packet_id - 1, packet_id);
566 }
567
568 if (packet_id == 0xffff)
569 dec->next_packet_id = 0x8000;
570 else
571 dec->next_packet_id = packet_id + 1;
572
573 switch (dec->packet_type) {
574 case TTUSB_DEC_PACKET_PVA:
575 if (dec->pva_stream_count)
576 ttusb_dec_process_pva(dec, dec->packet,
577 dec->packet_payload_length);
578 break;
579
580 case TTUSB_DEC_PACKET_SECTION:
581 if (dec->filter_stream_count)
582 ttusb_dec_process_filter(dec, dec->packet,
583 dec->packet_payload_length);
584 break;
585
586 case TTUSB_DEC_PACKET_EMPTY:
587 break;
588 }
589}
590
591static void swap_bytes(u8 *b, int length)
592{
593 u8 c;
594
595 length -= length % 2;
596 for (; length; b += 2, length -= 2) {
597 c = *b;
598 *b = *(b + 1);
599 *(b + 1) = c;
600 }
601}
602
603static void ttusb_dec_process_urb_frame(struct ttusb_dec *dec, u8 *b,
604 int length)
605{
606 swap_bytes(b, length);
607
608 while (length) {
609 switch (dec->packet_state) {
610
611 case 0:
612 case 1:
613 case 2:
614 if (*b++ == 0xaa)
615 dec->packet_state++;
616 else
617 dec->packet_state = 0;
618
619 length--;
620 break;
621
622 case 3:
623 if (*b == 0x00) {
624 dec->packet_state++;
625 dec->packet_length = 0;
626 } else if (*b != 0xaa) {
627 dec->packet_state = 0;
628 }
629
630 b++;
631 length--;
632 break;
633
634 case 4:
635 dec->packet[dec->packet_length++] = *b++;
636
637 if (dec->packet_length == 2) {
638 if (dec->packet[0] == 'A' &&
639 dec->packet[1] == 'V') {
640 dec->packet_type =
641 TTUSB_DEC_PACKET_PVA;
642 dec->packet_state++;
643 } else if (dec->packet[0] == 'S') {
644 dec->packet_type =
645 TTUSB_DEC_PACKET_SECTION;
646 dec->packet_state++;
647 } else if (dec->packet[0] == 0x00) {
648 dec->packet_type =
649 TTUSB_DEC_PACKET_EMPTY;
650 dec->packet_payload_length = 2;
651 dec->packet_state = 7;
652 } else {
653 printk("%s: unknown packet type: "
654 "%02x%02x\n", __FUNCTION__,
655 dec->packet[0], dec->packet[1]);
656 dec->packet_state = 0;
657 }
658 }
659
660 length--;
661 break;
662
663 case 5:
664 dec->packet[dec->packet_length++] = *b++;
665
666 if (dec->packet_type == TTUSB_DEC_PACKET_PVA &&
667 dec->packet_length == 8) {
668 dec->packet_state++;
669 dec->packet_payload_length = 8 +
670 (dec->packet[6] << 8) +
671 dec->packet[7];
672 } else if (dec->packet_type ==
673 TTUSB_DEC_PACKET_SECTION &&
674 dec->packet_length == 5) {
675 dec->packet_state++;
676 dec->packet_payload_length = 5 +
677 ((dec->packet[3] & 0x0f) << 8) +
678 dec->packet[4];
679 }
680
681 length--;
682 break;
683
684 case 6: {
685 int remainder = dec->packet_payload_length -
686 dec->packet_length;
687
688 if (length >= remainder) {
689 memcpy(dec->packet + dec->packet_length,
690 b, remainder);
691 dec->packet_length += remainder;
692 b += remainder;
693 length -= remainder;
694 dec->packet_state++;
695 } else {
696 memcpy(&dec->packet[dec->packet_length],
697 b, length);
698 dec->packet_length += length;
699 length = 0;
700 }
701
702 break;
703 }
704
705 case 7: {
706 int tail = 4;
707
708 dec->packet[dec->packet_length++] = *b++;
709
710 if (dec->packet_type == TTUSB_DEC_PACKET_SECTION &&
711 dec->packet_payload_length % 2)
712 tail++;
713
714 if (dec->packet_length ==
715 dec->packet_payload_length + tail) {
716 ttusb_dec_process_packet(dec);
717 dec->packet_state = 0;
718 }
719
720 length--;
721 break;
722 }
723
724 default:
725 printk("%s: illegal packet state encountered.\n",
726 __FUNCTION__);
727 dec->packet_state = 0;
728 }
729 }
730}
731
732static void ttusb_dec_process_urb_frame_list(unsigned long data)
733{
734 struct ttusb_dec *dec = (struct ttusb_dec *)data;
735 struct list_head *item;
736 struct urb_frame *frame;
737 unsigned long flags;
738
739 while (1) {
740 spin_lock_irqsave(&dec->urb_frame_list_lock, flags);
741 if ((item = dec->urb_frame_list.next) != &dec->urb_frame_list) {
742 frame = list_entry(item, struct urb_frame,
743 urb_frame_list);
744 list_del(&frame->urb_frame_list);
745 } else {
746 spin_unlock_irqrestore(&dec->urb_frame_list_lock,
747 flags);
748 return;
749 }
750 spin_unlock_irqrestore(&dec->urb_frame_list_lock, flags);
751
752 ttusb_dec_process_urb_frame(dec, frame->data, frame->length);
753 kfree(frame);
754 }
755}
756
757static void ttusb_dec_process_urb(struct urb *urb, struct pt_regs *ptregs)
758{
759 struct ttusb_dec *dec = urb->context;
760
761 if (!urb->status) {
762 int i;
763
764 for (i = 0; i < FRAMES_PER_ISO_BUF; i++) {
765 struct usb_iso_packet_descriptor *d;
766 u8 *b;
767 int length;
768 struct urb_frame *frame;
769
770 d = &urb->iso_frame_desc[i];
771 b = urb->transfer_buffer + d->offset;
772 length = d->actual_length;
773
774 if ((frame = kmalloc(sizeof(struct urb_frame),
775 GFP_ATOMIC))) {
776 unsigned long flags;
777
778 memcpy(frame->data, b, length);
779 frame->length = length;
780
781 spin_lock_irqsave(&dec->urb_frame_list_lock,
782 flags);
783 list_add_tail(&frame->urb_frame_list,
784 &dec->urb_frame_list);
785 spin_unlock_irqrestore(&dec->urb_frame_list_lock,
786 flags);
787
788 tasklet_schedule(&dec->urb_tasklet);
789 }
790 }
791 } else {
792 /* -ENOENT is expected when unlinking urbs */
793 if (urb->status != -ENOENT)
794 dprintk("%s: urb error: %d\n", __FUNCTION__,
795 urb->status);
796 }
797
798 if (dec->iso_stream_count)
799 usb_submit_urb(urb, GFP_ATOMIC);
800}
801
802static void ttusb_dec_setup_urbs(struct ttusb_dec *dec)
803{
804 int i, j, buffer_offset = 0;
805
806 dprintk("%s\n", __FUNCTION__);
807
808 for (i = 0; i < ISO_BUF_COUNT; i++) {
809 int frame_offset = 0;
810 struct urb *urb = dec->iso_urb[i];
811
812 urb->dev = dec->udev;
813 urb->context = dec;
814 urb->complete = ttusb_dec_process_urb;
815 urb->pipe = dec->in_pipe;
816 urb->transfer_flags = URB_ISO_ASAP;
817 urb->interval = 1;
818 urb->number_of_packets = FRAMES_PER_ISO_BUF;
819 urb->transfer_buffer_length = ISO_FRAME_SIZE *
820 FRAMES_PER_ISO_BUF;
821 urb->transfer_buffer = dec->iso_buffer + buffer_offset;
822 buffer_offset += ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF;
823
824 for (j = 0; j < FRAMES_PER_ISO_BUF; j++) {
825 urb->iso_frame_desc[j].offset = frame_offset;
826 urb->iso_frame_desc[j].length = ISO_FRAME_SIZE;
827 frame_offset += ISO_FRAME_SIZE;
828 }
829 }
830}
831
832static void ttusb_dec_stop_iso_xfer(struct ttusb_dec *dec)
833{
834 int i;
835
836 dprintk("%s\n", __FUNCTION__);
837
838 if (down_interruptible(&dec->iso_sem))
839 return;
840
841 dec->iso_stream_count--;
842
843 if (!dec->iso_stream_count) {
844 for (i = 0; i < ISO_BUF_COUNT; i++)
845 usb_kill_urb(dec->iso_urb[i]);
846 }
847
848 up(&dec->iso_sem);
849}
850
851/* Setting the interface of the DEC tends to take down the USB communications
852 * for a short period, so it's important not to call this function just before
853 * trying to talk to it.
854 */
855static int ttusb_dec_set_interface(struct ttusb_dec *dec,
856 enum ttusb_dec_interface interface)
857{
858 int result = 0;
859 u8 b[] = { 0x05 };
860
861 if (interface != dec->interface) {
862 switch (interface) {
863 case TTUSB_DEC_INTERFACE_INITIAL:
864 result = usb_set_interface(dec->udev, 0, 0);
865 break;
866 case TTUSB_DEC_INTERFACE_IN:
867 result = ttusb_dec_send_command(dec, 0x80, sizeof(b),
868 b, NULL, NULL);
869 if (result)
870 return result;
871 result = usb_set_interface(dec->udev, 0, 8);
872 break;
873 case TTUSB_DEC_INTERFACE_OUT:
874 result = usb_set_interface(dec->udev, 0, 1);
875 break;
876 }
877
878 if (result)
879 return result;
880
881 dec->interface = interface;
882 }
883
884 return 0;
885}
886
887static int ttusb_dec_start_iso_xfer(struct ttusb_dec *dec)
888{
889 int i, result;
890
891 dprintk("%s\n", __FUNCTION__);
892
893 if (down_interruptible(&dec->iso_sem))
894 return -EAGAIN;
895
896 if (!dec->iso_stream_count) {
897 ttusb_dec_setup_urbs(dec);
898
899 dec->packet_state = 0;
900 dec->v_pes_postbytes = 0;
901 dec->next_packet_id = 0;
902
903 for (i = 0; i < ISO_BUF_COUNT; i++) {
904 if ((result = usb_submit_urb(dec->iso_urb[i],
905 GFP_ATOMIC))) {
906 printk("%s: failed urb submission %d: "
907 "error %d\n", __FUNCTION__, i, result);
908
909 while (i) {
910 usb_kill_urb(dec->iso_urb[i - 1]);
911 i--;
912 }
913
914 up(&dec->iso_sem);
915 return result;
916 }
917 }
918 }
919
920 dec->iso_stream_count++;
921
922 up(&dec->iso_sem);
923
924 return 0;
925}
926
927static int ttusb_dec_start_ts_feed(struct dvb_demux_feed *dvbdmxfeed)
928{
929 struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
930 struct ttusb_dec *dec = dvbdmx->priv;
931 u8 b0[] = { 0x05 };
932 int result = 0;
933
934 dprintk("%s\n", __FUNCTION__);
935
936 dprintk(" ts_type:");
937
938 if (dvbdmxfeed->ts_type & TS_DECODER)
939 dprintk(" TS_DECODER");
940
941 if (dvbdmxfeed->ts_type & TS_PACKET)
942 dprintk(" TS_PACKET");
943
944 if (dvbdmxfeed->ts_type & TS_PAYLOAD_ONLY)
945 dprintk(" TS_PAYLOAD_ONLY");
946
947 dprintk("\n");
948
949 switch (dvbdmxfeed->pes_type) {
950
951 case DMX_TS_PES_VIDEO:
952 dprintk(" pes_type: DMX_TS_PES_VIDEO\n");
953 dec->pid[DMX_PES_PCR] = dvbdmxfeed->pid;
954 dec->pid[DMX_PES_VIDEO] = dvbdmxfeed->pid;
955 dec->video_filter = dvbdmxfeed->filter;
956 ttusb_dec_set_pids(dec);
957 break;
958
959 case DMX_TS_PES_AUDIO:
960 dprintk(" pes_type: DMX_TS_PES_AUDIO\n");
961 dec->pid[DMX_PES_AUDIO] = dvbdmxfeed->pid;
962 dec->audio_filter = dvbdmxfeed->filter;
963 ttusb_dec_set_pids(dec);
964 break;
965
966 case DMX_TS_PES_TELETEXT:
967 dec->pid[DMX_PES_TELETEXT] = dvbdmxfeed->pid;
968 dprintk(" pes_type: DMX_TS_PES_TELETEXT\n");
969 break;
970
971 case DMX_TS_PES_PCR:
972 dprintk(" pes_type: DMX_TS_PES_PCR\n");
973 dec->pid[DMX_PES_PCR] = dvbdmxfeed->pid;
974 ttusb_dec_set_pids(dec);
975 break;
976
977 case DMX_TS_PES_OTHER:
978 dprintk(" pes_type: DMX_TS_PES_OTHER\n");
979 break;
980
981 default:
982 dprintk(" pes_type: unknown (%d)\n", dvbdmxfeed->pes_type);
983 return -EINVAL;
984
985 }
986
987 result = ttusb_dec_send_command(dec, 0x80, sizeof(b0), b0, NULL, NULL);
988 if (result)
989 return result;
990
991 dec->pva_stream_count++;
992 return ttusb_dec_start_iso_xfer(dec);
993}
994
995static int ttusb_dec_start_sec_feed(struct dvb_demux_feed *dvbdmxfeed)
996{
997 struct ttusb_dec *dec = dvbdmxfeed->demux->priv;
998 u8 b0[] = { 0x00, 0x00, 0x00, 0x01,
999 0x00, 0x00, 0x00, 0x00,
1000 0x00, 0x00, 0x00, 0x00,
1001 0x00, 0x00, 0x00, 0x00,
1002 0x00, 0xff, 0x00, 0x00,
1003 0x00, 0x00, 0x00, 0x00,
1004 0x00, 0x00, 0x00, 0x00,
1005 0x00 };
1006 u16 pid;
1007 u8 c[COMMAND_PACKET_SIZE];
1008 int c_length;
1009 int result;
1010 struct filter_info *finfo;
1011 unsigned long flags;
1012 u8 x = 1;
1013
1014 dprintk("%s\n", __FUNCTION__);
1015
1016 pid = htons(dvbdmxfeed->pid);
1017 memcpy(&b0[0], &pid, 2);
1018 memcpy(&b0[4], &x, 1);
1019 memcpy(&b0[5], &dvbdmxfeed->filter->filter.filter_value[0], 1);
1020
1021 result = ttusb_dec_send_command(dec, 0x60, sizeof(b0), b0,
1022 &c_length, c);
1023
1024 if (!result) {
1025 if (c_length == 2) {
1026 if (!(finfo = kmalloc(sizeof(struct filter_info),
1027 GFP_ATOMIC)))
1028 return -ENOMEM;
1029
1030 finfo->stream_id = c[1];
1031 finfo->filter = dvbdmxfeed->filter;
1032
1033 spin_lock_irqsave(&dec->filter_info_list_lock, flags);
1034 list_add_tail(&finfo->filter_info_list,
1035 &dec->filter_info_list);
1036 spin_unlock_irqrestore(&dec->filter_info_list_lock,
1037 flags);
1038
1039 dvbdmxfeed->priv = finfo;
1040
1041 dec->filter_stream_count++;
1042 return ttusb_dec_start_iso_xfer(dec);
1043 }
1044
1045 return -EAGAIN;
1046 } else
1047 return result;
1048}
1049
1050static int ttusb_dec_start_feed(struct dvb_demux_feed *dvbdmxfeed)
1051{
1052 struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
1053
1054 dprintk("%s\n", __FUNCTION__);
1055
1056 if (!dvbdmx->dmx.frontend)
1057 return -EINVAL;
1058
1059 dprintk(" pid: 0x%04X\n", dvbdmxfeed->pid);
1060
1061 switch (dvbdmxfeed->type) {
1062
1063 case DMX_TYPE_TS:
1064 return ttusb_dec_start_ts_feed(dvbdmxfeed);
1065 break;
1066
1067 case DMX_TYPE_SEC:
1068 return ttusb_dec_start_sec_feed(dvbdmxfeed);
1069 break;
1070
1071 default:
1072 dprintk(" type: unknown (%d)\n", dvbdmxfeed->type);
1073 return -EINVAL;
1074
1075 }
1076}
1077
1078static int ttusb_dec_stop_ts_feed(struct dvb_demux_feed *dvbdmxfeed)
1079{
1080 struct ttusb_dec *dec = dvbdmxfeed->demux->priv;
1081 u8 b0[] = { 0x00 };
1082
1083 ttusb_dec_send_command(dec, 0x81, sizeof(b0), b0, NULL, NULL);
1084
1085 dec->pva_stream_count--;
1086
1087 ttusb_dec_stop_iso_xfer(dec);
1088
1089 return 0;
1090}
1091
1092static int ttusb_dec_stop_sec_feed(struct dvb_demux_feed *dvbdmxfeed)
1093{
1094 struct ttusb_dec *dec = dvbdmxfeed->demux->priv;
1095 u8 b0[] = { 0x00, 0x00 };
1096 struct filter_info *finfo = (struct filter_info *)dvbdmxfeed->priv;
1097 unsigned long flags;
1098
1099 b0[1] = finfo->stream_id;
1100 spin_lock_irqsave(&dec->filter_info_list_lock, flags);
1101 list_del(&finfo->filter_info_list);
1102 spin_unlock_irqrestore(&dec->filter_info_list_lock, flags);
1103 kfree(finfo);
1104 ttusb_dec_send_command(dec, 0x62, sizeof(b0), b0, NULL, NULL);
1105
1106 dec->filter_stream_count--;
1107
1108 ttusb_dec_stop_iso_xfer(dec);
1109
1110 return 0;
1111}
1112
1113static int ttusb_dec_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
1114{
1115 dprintk("%s\n", __FUNCTION__);
1116
1117 switch (dvbdmxfeed->type) {
1118 case DMX_TYPE_TS:
1119 return ttusb_dec_stop_ts_feed(dvbdmxfeed);
1120 break;
1121
1122 case DMX_TYPE_SEC:
1123 return ttusb_dec_stop_sec_feed(dvbdmxfeed);
1124 break;
1125 }
1126
1127 return 0;
1128}
1129
1130static void ttusb_dec_free_iso_urbs(struct ttusb_dec *dec)
1131{
1132 int i;
1133
1134 dprintk("%s\n", __FUNCTION__);
1135
1136 for (i = 0; i < ISO_BUF_COUNT; i++)
1137 if (dec->iso_urb[i])
1138 usb_free_urb(dec->iso_urb[i]);
1139
1140 pci_free_consistent(NULL,
1141 ISO_FRAME_SIZE * (FRAMES_PER_ISO_BUF *
1142 ISO_BUF_COUNT),
1143 dec->iso_buffer, dec->iso_dma_handle);
1144}
1145
1146static int ttusb_dec_alloc_iso_urbs(struct ttusb_dec *dec)
1147{
1148 int i;
1149
1150 dprintk("%s\n", __FUNCTION__);
1151
1152 dec->iso_buffer = pci_alloc_consistent(NULL,
1153 ISO_FRAME_SIZE *
1154 (FRAMES_PER_ISO_BUF *
1155 ISO_BUF_COUNT),
1156 &dec->iso_dma_handle);
1157
1158 memset(dec->iso_buffer, 0,
1159 ISO_FRAME_SIZE * (FRAMES_PER_ISO_BUF * ISO_BUF_COUNT));
1160
1161 for (i = 0; i < ISO_BUF_COUNT; i++) {
1162 struct urb *urb;
1163
1164 if (!(urb = usb_alloc_urb(FRAMES_PER_ISO_BUF, GFP_ATOMIC))) {
1165 ttusb_dec_free_iso_urbs(dec);
1166 return -ENOMEM;
1167 }
1168
1169 dec->iso_urb[i] = urb;
1170 }
1171
1172 ttusb_dec_setup_urbs(dec);
1173
1174 return 0;
1175}
1176
1177static void ttusb_dec_init_tasklet(struct ttusb_dec *dec)
1178{
1179 spin_lock_init(&dec->urb_frame_list_lock);
1180 INIT_LIST_HEAD(&dec->urb_frame_list);
1181 tasklet_init(&dec->urb_tasklet, ttusb_dec_process_urb_frame_list,
1182 (unsigned long)dec);
1183}
1184
1185static void ttusb_init_rc( struct ttusb_dec *dec)
1186{
1187 u8 b[] = { 0x00, 0x01 };
1188 int i;
1189
1190 init_input_dev(&dec->rc_input_dev);
1191
1192 dec->rc_input_dev.name = "ttusb_dec remote control";
1193 dec->rc_input_dev.evbit[0] = BIT(EV_KEY);
1194 dec->rc_input_dev.keycodesize = sizeof(u16);
1195 dec->rc_input_dev.keycodemax = 0x1a;
1196 dec->rc_input_dev.keycode = rc_keys;
1197
1198 for (i = 0; i < sizeof(rc_keys)/sizeof(rc_keys[0]); i++)
1199 set_bit(rc_keys[i], dec->rc_input_dev.keybit);
1200
1201 input_register_device(&dec->rc_input_dev);
1202
1203 if(usb_submit_urb(dec->irq_urb,GFP_KERNEL)) {
1204 printk("%s: usb_submit_urb failed\n",__FUNCTION__);
1205 }
1206 /* enable irq pipe */
1207 ttusb_dec_send_command(dec,0xb0,sizeof(b),b,NULL,NULL);
1208}
1209
1210static void ttusb_dec_init_v_pes(struct ttusb_dec *dec)
1211{
1212 dprintk("%s\n", __FUNCTION__);
1213
1214 dec->v_pes[0] = 0x00;
1215 dec->v_pes[1] = 0x00;
1216 dec->v_pes[2] = 0x01;
1217 dec->v_pes[3] = 0xe0;
1218}
1219
1220static int ttusb_dec_init_usb(struct ttusb_dec *dec)
1221{
1222 dprintk("%s\n", __FUNCTION__);
1223
1224 sema_init(&dec->usb_sem, 1);
1225 sema_init(&dec->iso_sem, 1);
1226
1227 dec->command_pipe = usb_sndbulkpipe(dec->udev, COMMAND_PIPE);
1228 dec->result_pipe = usb_rcvbulkpipe(dec->udev, RESULT_PIPE);
1229 dec->in_pipe = usb_rcvisocpipe(dec->udev, IN_PIPE);
1230 dec->out_pipe = usb_sndisocpipe(dec->udev, OUT_PIPE);
1231 dec->irq_pipe = usb_rcvintpipe(dec->udev, IRQ_PIPE);
1232
1233 if(enable_rc) {
1234 dec->irq_urb = usb_alloc_urb(0, GFP_KERNEL);
1235 if(!dec->irq_urb) {
1236 return -ENOMEM;
1237 }
1238 dec->irq_buffer = usb_buffer_alloc(dec->udev,IRQ_PACKET_SIZE,
1239 SLAB_ATOMIC, &dec->irq_dma_handle);
1240 if(!dec->irq_buffer) {
1241 return -ENOMEM;
1242 }
1243 usb_fill_int_urb(dec->irq_urb, dec->udev,dec->irq_pipe,
1244 dec->irq_buffer, IRQ_PACKET_SIZE,
1245 ttusb_dec_handle_irq, dec, 1);
1246 dec->irq_urb->transfer_dma = dec->irq_dma_handle;
1247 dec->irq_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
1248 }
1249
1250 return ttusb_dec_alloc_iso_urbs(dec);
1251}
1252
1253static int ttusb_dec_boot_dsp(struct ttusb_dec *dec)
1254{
1255 int i, j, actual_len, result, size, trans_count;
1256 u8 b0[] = { 0x00, 0x00, 0x00, 0x00,
1257 0x00, 0x00, 0x00, 0x00,
1258 0x61, 0x00 };
1259 u8 b1[] = { 0x61 };
1260 u8 *b;
1261 char idstring[21];
1262 u8 *firmware = NULL;
1263 size_t firmware_size = 0;
1264 u16 firmware_csum = 0;
1265 u16 firmware_csum_ns;
1266 u32 firmware_size_nl;
1267 u32 crc32_csum, crc32_check, tmp;
1268 const struct firmware *fw_entry = NULL;
1269
1270 dprintk("%s\n", __FUNCTION__);
1271
1272 if (request_firmware(&fw_entry, dec->firmware_name, &dec->udev->dev)) {
1273 printk(KERN_ERR "%s: Firmware (%s) unavailable.\n",
1274 __FUNCTION__, dec->firmware_name);
1275 return 1;
1276 }
1277
1278 firmware = fw_entry->data;
1279 firmware_size = fw_entry->size;
1280
1281 if (firmware_size < 60) {
1282 printk("%s: firmware size too small for DSP code (%zu < 60).\n",
1283 __FUNCTION__, firmware_size);
1284 return -1;
1285 }
1286
1287 /* a 32 bit checksum over the first 56 bytes of the DSP Code is stored
1288 at offset 56 of file, so use it to check if the firmware file is
1289 valid. */
1290 crc32_csum = crc32(~0L, firmware, 56) ^ ~0L;
1291 memcpy(&tmp, &firmware[56], 4);
1292 crc32_check = htonl(tmp);
1293 if (crc32_csum != crc32_check) {
1294 printk("%s: crc32 check of DSP code failed (calculated "
1295 "0x%08x != 0x%08x in file), file invalid.\n",
1296 __FUNCTION__, crc32_csum, crc32_check);
1297 return -1;
1298 }
1299 memcpy(idstring, &firmware[36], 20);
1300 idstring[20] = '\0';
1301 printk(KERN_INFO "ttusb_dec: found DSP code \"%s\".\n", idstring);
1302
1303 firmware_size_nl = htonl(firmware_size);
1304 memcpy(b0, &firmware_size_nl, 4);
1305 firmware_csum = crc16(~0, firmware, firmware_size) ^ ~0;
1306 firmware_csum_ns = htons(firmware_csum);
1307 memcpy(&b0[6], &firmware_csum_ns, 2);
1308
1309 result = ttusb_dec_send_command(dec, 0x41, sizeof(b0), b0, NULL, NULL);
1310
1311 if (result)
1312 return result;
1313
1314 trans_count = 0;
1315 j = 0;
1316
1317 b = kmalloc(ARM_PACKET_SIZE, GFP_KERNEL);
1318 if (b == NULL)
1319 return -ENOMEM;
1320
1321 for (i = 0; i < firmware_size; i += COMMAND_PACKET_SIZE) {
1322 size = firmware_size - i;
1323 if (size > COMMAND_PACKET_SIZE)
1324 size = COMMAND_PACKET_SIZE;
1325
1326 b[j + 0] = 0xaa;
1327 b[j + 1] = trans_count++;
1328 b[j + 2] = 0xf0;
1329 b[j + 3] = size;
1330 memcpy(&b[j + 4], &firmware[i], size);
1331
1332 j += COMMAND_PACKET_SIZE + 4;
1333
1334 if (j >= ARM_PACKET_SIZE) {
1335 result = usb_bulk_msg(dec->udev, dec->command_pipe, b,
1336 ARM_PACKET_SIZE, &actual_len,
1337 100);
1338 j = 0;
1339 } else if (size < COMMAND_PACKET_SIZE) {
1340 result = usb_bulk_msg(dec->udev, dec->command_pipe, b,
1341 j - COMMAND_PACKET_SIZE + size,
1342 &actual_len, 100);
1343 }
1344 }
1345
1346 result = ttusb_dec_send_command(dec, 0x43, sizeof(b1), b1, NULL, NULL);
1347
1348 kfree(b);
1349
1350 return result;
1351}
1352
1353static int ttusb_dec_init_stb(struct ttusb_dec *dec)
1354{
1355 int result;
1356 unsigned int mode, model, version;
1357
1358 dprintk("%s\n", __FUNCTION__);
1359
1360 result = ttusb_dec_get_stb_state(dec, &mode, &model, &version);
1361
1362 if (!result) {
1363 if (!mode) {
1364 if (version == 0xABCDEFAB)
1365 printk(KERN_INFO "ttusb_dec: no version "
1366 "info in Firmware\n");
1367 else
1368 printk(KERN_INFO "ttusb_dec: Firmware "
1369 "%x.%02x%c%c\n",
1370 version >> 24, (version >> 16) & 0xff,
1371 (version >> 8) & 0xff, version & 0xff);
1372
1373 result = ttusb_dec_boot_dsp(dec);
1374 if (result)
1375 return result;
1376 else
1377 return 1;
1378 } else {
1379 /* We can't trust the USB IDs that some firmwares
1380 give the box */
1381 switch (model) {
1382 case 0x00070008:
1383 case 0x0007000c:
1384 ttusb_dec_set_model(dec, TTUSB_DEC3000S);
1385 break;
1386 case 0x00070009:
1387 case 0x00070013:
1388 ttusb_dec_set_model(dec, TTUSB_DEC2000T);
1389 break;
1390 case 0x00070011:
1391 ttusb_dec_set_model(dec, TTUSB_DEC2540T);
1392 break;
1393 default:
1394 printk(KERN_ERR "%s: unknown model returned "
1395 "by firmware (%08x) - please report\n",
1396 __FUNCTION__, model);
1397 return -1;
1398 break;
1399 }
1400
1401 if (version >= 0x01770000)
1402 dec->can_playback = 1;
1403
1404 return 0;
1405 }
1406 }
1407 else
1408 return result;
1409}
1410
1411static int ttusb_dec_init_dvb(struct ttusb_dec *dec)
1412{
1413 int result;
1414
1415 dprintk("%s\n", __FUNCTION__);
1416
1417 if ((result = dvb_register_adapter(&dec->adapter,
1418 dec->model_name, THIS_MODULE)) < 0) {
1419 printk("%s: dvb_register_adapter failed: error %d\n",
1420 __FUNCTION__, result);
1421
1422 return result;
1423 }
1424
1425 dec->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING;
1426
1427 dec->demux.priv = (void *)dec;
1428 dec->demux.filternum = 31;
1429 dec->demux.feednum = 31;
1430 dec->demux.start_feed = ttusb_dec_start_feed;
1431 dec->demux.stop_feed = ttusb_dec_stop_feed;
1432 dec->demux.write_to_decoder = NULL;
1433
1434 if ((result = dvb_dmx_init(&dec->demux)) < 0) {
1435 printk("%s: dvb_dmx_init failed: error %d\n", __FUNCTION__,
1436 result);
1437
1438 dvb_unregister_adapter(dec->adapter);
1439
1440 return result;
1441 }
1442
1443 dec->dmxdev.filternum = 32;
1444 dec->dmxdev.demux = &dec->demux.dmx;
1445 dec->dmxdev.capabilities = 0;
1446
1447 if ((result = dvb_dmxdev_init(&dec->dmxdev, dec->adapter)) < 0) {
1448 printk("%s: dvb_dmxdev_init failed: error %d\n",
1449 __FUNCTION__, result);
1450
1451 dvb_dmx_release(&dec->demux);
1452 dvb_unregister_adapter(dec->adapter);
1453
1454 return result;
1455 }
1456
1457 dec->frontend.source = DMX_FRONTEND_0;
1458
1459 if ((result = dec->demux.dmx.add_frontend(&dec->demux.dmx,
1460 &dec->frontend)) < 0) {
1461 printk("%s: dvb_dmx_init failed: error %d\n", __FUNCTION__,
1462 result);
1463
1464 dvb_dmxdev_release(&dec->dmxdev);
1465 dvb_dmx_release(&dec->demux);
1466 dvb_unregister_adapter(dec->adapter);
1467
1468 return result;
1469 }
1470
1471 if ((result = dec->demux.dmx.connect_frontend(&dec->demux.dmx,
1472 &dec->frontend)) < 0) {
1473 printk("%s: dvb_dmx_init failed: error %d\n", __FUNCTION__,
1474 result);
1475
1476 dec->demux.dmx.remove_frontend(&dec->demux.dmx, &dec->frontend);
1477 dvb_dmxdev_release(&dec->dmxdev);
1478 dvb_dmx_release(&dec->demux);
1479 dvb_unregister_adapter(dec->adapter);
1480
1481 return result;
1482 }
1483
1484 dvb_net_init(dec->adapter, &dec->dvb_net, &dec->demux.dmx);
1485
1486 return 0;
1487}
1488
1489static void ttusb_dec_exit_dvb(struct ttusb_dec *dec)
1490{
1491 dprintk("%s\n", __FUNCTION__);
1492
1493 dvb_net_release(&dec->dvb_net);
1494 dec->demux.dmx.close(&dec->demux.dmx);
1495 dec->demux.dmx.remove_frontend(&dec->demux.dmx, &dec->frontend);
1496 dvb_dmxdev_release(&dec->dmxdev);
1497 dvb_dmx_release(&dec->demux);
1498 if (dec->fe) dvb_unregister_frontend(dec->fe);
1499 dvb_unregister_adapter(dec->adapter);
1500}
1501
1502static void ttusb_dec_exit_rc(struct ttusb_dec *dec)
1503{
1504
1505 dprintk("%s\n", __FUNCTION__);
1506 /* we have to check whether the irq URB is already submitted.
1507 * As the irq is submitted after the interface is changed,
1508 * this is the best method i figured out.
1509 * Any others?*/
1510 if(dec->interface == TTUSB_DEC_INTERFACE_IN)
1511 usb_kill_urb(dec->irq_urb);
1512
1513 usb_free_urb(dec->irq_urb);
1514
1515 usb_buffer_free(dec->udev,IRQ_PACKET_SIZE,
1516 dec->irq_buffer, dec->irq_dma_handle);
1517
1518 input_unregister_device(&dec->rc_input_dev);
1519}
1520
1521
1522static void ttusb_dec_exit_usb(struct ttusb_dec *dec)
1523{
1524 int i;
1525
1526 dprintk("%s\n", __FUNCTION__);
1527
1528 dec->iso_stream_count = 0;
1529
1530 for (i = 0; i < ISO_BUF_COUNT; i++)
1531 usb_kill_urb(dec->iso_urb[i]);
1532
1533 ttusb_dec_free_iso_urbs(dec);
1534}
1535
1536static void ttusb_dec_exit_tasklet(struct ttusb_dec *dec)
1537{
1538 struct list_head *item;
1539 struct urb_frame *frame;
1540
1541 tasklet_kill(&dec->urb_tasklet);
1542
1543 while ((item = dec->urb_frame_list.next) != &dec->urb_frame_list) {
1544 frame = list_entry(item, struct urb_frame, urb_frame_list);
1545 list_del(&frame->urb_frame_list);
1546 kfree(frame);
1547 }
1548}
1549
1550static void ttusb_dec_init_filters(struct ttusb_dec *dec)
1551{
1552 INIT_LIST_HEAD(&dec->filter_info_list);
1553 spin_lock_init(&dec->filter_info_list_lock);
1554}
1555
1556static void ttusb_dec_exit_filters(struct ttusb_dec *dec)
1557{
1558 struct list_head *item;
1559 struct filter_info *finfo;
1560
1561 while ((item = dec->filter_info_list.next) != &dec->filter_info_list) {
1562 finfo = list_entry(item, struct filter_info, filter_info_list);
1563 list_del(&finfo->filter_info_list);
1564 kfree(finfo);
1565 }
1566}
1567
1568int fe_send_command(struct dvb_frontend* fe, const u8 command,
1569 int param_length, const u8 params[],
1570 int *result_length, u8 cmd_result[])
1571{
1572 struct ttusb_dec* dec = (struct ttusb_dec*) fe->dvb->priv;
1573 return ttusb_dec_send_command(dec, command, param_length, params, result_length, cmd_result);
1574}
1575
1576struct ttusbdecfe_config fe_config = {
1577 .send_command = fe_send_command
1578};
1579
1580static int ttusb_dec_probe(struct usb_interface *intf,
1581 const struct usb_device_id *id)
1582{
1583 struct usb_device *udev;
1584 struct ttusb_dec *dec;
1585
1586 dprintk("%s\n", __FUNCTION__);
1587
1588 udev = interface_to_usbdev(intf);
1589
1590 if (!(dec = kmalloc(sizeof(struct ttusb_dec), GFP_KERNEL))) {
1591 printk("%s: couldn't allocate memory.\n", __FUNCTION__);
1592 return -ENOMEM;
1593 }
1594
1595 usb_set_intfdata(intf, (void *)dec);
1596
1597 memset(dec, 0, sizeof(struct ttusb_dec));
1598
1599 switch (le16_to_cpu(id->idProduct)) {
1600 case 0x1006:
1601 ttusb_dec_set_model(dec, TTUSB_DEC3000S);
1602 break;
1603
1604 case 0x1008:
1605 ttusb_dec_set_model(dec, TTUSB_DEC2000T);
1606 break;
1607
1608 case 0x1009:
1609 ttusb_dec_set_model(dec, TTUSB_DEC2540T);
1610 break;
1611 }
1612
1613 dec->udev = udev;
1614
1615 if (ttusb_dec_init_usb(dec))
1616 return 0;
1617 if (ttusb_dec_init_stb(dec)) {
1618 ttusb_dec_exit_usb(dec);
1619 return 0;
1620 }
1621 ttusb_dec_init_dvb(dec);
1622
1623 dec->adapter->priv = dec;
1624 switch (le16_to_cpu(id->idProduct)) {
1625 case 0x1006:
1626 dec->fe = ttusbdecfe_dvbs_attach(&fe_config);
1627 break;
1628
1629 case 0x1008:
1630 case 0x1009:
1631 dec->fe = ttusbdecfe_dvbt_attach(&fe_config);
1632 break;
1633 }
1634
1635 if (dec->fe == NULL) {
1636 printk("dvb-ttusb-dec: A frontend driver was not found for device %04x/%04x\n",
1637 le16_to_cpu(dec->udev->descriptor.idVendor),
1638 le16_to_cpu(dec->udev->descriptor.idProduct));
1639 } else {
1640 if (dvb_register_frontend(dec->adapter, dec->fe)) {
1641 printk("budget-ci: Frontend registration failed!\n");
1642 if (dec->fe->ops->release)
1643 dec->fe->ops->release(dec->fe);
1644 dec->fe = NULL;
1645 }
1646 }
1647
1648 ttusb_dec_init_v_pes(dec);
1649 ttusb_dec_init_filters(dec);
1650 ttusb_dec_init_tasklet(dec);
1651
1652 dec->active = 1;
1653
1654 ttusb_dec_set_interface(dec, TTUSB_DEC_INTERFACE_IN);
1655
1656 if(enable_rc)
1657 ttusb_init_rc(dec);
1658
1659 return 0;
1660}
1661
1662static void ttusb_dec_disconnect(struct usb_interface *intf)
1663{
1664 struct ttusb_dec *dec = usb_get_intfdata(intf);
1665
1666 usb_set_intfdata(intf, NULL);
1667
1668 dprintk("%s\n", __FUNCTION__);
1669
1670 if (dec->active) {
1671 ttusb_dec_exit_tasklet(dec);
1672 ttusb_dec_exit_filters(dec);
1673 if(enable_rc)
1674 ttusb_dec_exit_rc(dec);
1675 ttusb_dec_exit_usb(dec);
1676 ttusb_dec_exit_dvb(dec);
1677 }
1678
1679 kfree(dec);
1680}
1681
1682static void ttusb_dec_set_model(struct ttusb_dec *dec,
1683 enum ttusb_dec_model model)
1684{
1685 dec->model = model;
1686
1687 switch (model) {
1688 case TTUSB_DEC2000T:
1689 dec->model_name = "DEC2000-t";
1690 dec->firmware_name = "dvb-ttusb-dec-2000t.fw";
1691 break;
1692
1693 case TTUSB_DEC2540T:
1694 dec->model_name = "DEC2540-t";
1695 dec->firmware_name = "dvb-ttusb-dec-2540t.fw";
1696 break;
1697
1698 case TTUSB_DEC3000S:
1699 dec->model_name = "DEC3000-s";
1700 dec->firmware_name = "dvb-ttusb-dec-3000s.fw";
1701 break;
1702 }
1703}
1704
1705static struct usb_device_id ttusb_dec_table[] = {
1706 {USB_DEVICE(0x0b48, 0x1006)}, /* DEC3000-s */
1707 /*{USB_DEVICE(0x0b48, 0x1007)}, Unconfirmed */
1708 {USB_DEVICE(0x0b48, 0x1008)}, /* DEC2000-t */
1709 {USB_DEVICE(0x0b48, 0x1009)}, /* DEC2540-t */
1710 {}
1711};
1712
1713static struct usb_driver ttusb_dec_driver = {
1714 .name = "ttusb-dec",
1715 .probe = ttusb_dec_probe,
1716 .disconnect = ttusb_dec_disconnect,
1717 .id_table = ttusb_dec_table,
1718};
1719
1720static int __init ttusb_dec_init(void)
1721{
1722 int result;
1723
1724 if ((result = usb_register(&ttusb_dec_driver)) < 0) {
1725 printk("%s: initialisation failed: error %d.\n", __FUNCTION__,
1726 result);
1727 return result;
1728 }
1729
1730 return 0;
1731}
1732
1733static void __exit ttusb_dec_exit(void)
1734{
1735 usb_deregister(&ttusb_dec_driver);
1736}
1737
1738module_init(ttusb_dec_init);
1739module_exit(ttusb_dec_exit);
1740
1741MODULE_AUTHOR("Alex Woods <linux-dvb@giblets.org>");
1742MODULE_DESCRIPTION(DRIVER_NAME);
1743MODULE_LICENSE("GPL");
1744MODULE_DEVICE_TABLE(usb, ttusb_dec_table);
diff --git a/drivers/media/dvb/ttusb-dec/ttusbdecfe.c b/drivers/media/dvb/ttusb-dec/ttusbdecfe.c
new file mode 100644
index 000000000000..1699cc9f6bb0
--- /dev/null
+++ b/drivers/media/dvb/ttusb-dec/ttusbdecfe.c
@@ -0,0 +1,255 @@
1/*
2 * TTUSB DEC Frontend Driver
3 *
4 * Copyright (C) 2003-2004 Alex Woods <linux-dvb@giblets.org>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 *
20 */
21
22#include "dvb_frontend.h"
23#include "ttusbdecfe.h"
24
25
26#define LOF_HI 10600000
27#define LOF_LO 9750000
28
29struct ttusbdecfe_state {
30
31 struct dvb_frontend_ops ops;
32
33 /* configuration settings */
34 const struct ttusbdecfe_config* config;
35
36 struct dvb_frontend frontend;
37
38 u8 hi_band;
39 u8 voltage;
40};
41
42
43static int ttusbdecfe_read_status(struct dvb_frontend* fe, fe_status_t* status)
44{
45 *status = FE_HAS_SIGNAL | FE_HAS_VITERBI |
46 FE_HAS_SYNC | FE_HAS_CARRIER | FE_HAS_LOCK;
47
48 return 0;
49}
50
51static int ttusbdecfe_dvbt_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
52{
53 struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
54 u8 b[] = { 0x00, 0x00, 0x00, 0x03,
55 0x00, 0x00, 0x00, 0x00,
56 0x00, 0x00, 0x00, 0x01,
57 0x00, 0x00, 0x00, 0xff,
58 0x00, 0x00, 0x00, 0xff };
59
60 u32 freq = htonl(p->frequency / 1000);
61 memcpy(&b[4], &freq, sizeof (u32));
62 state->config->send_command(fe, 0x71, sizeof(b), b, NULL, NULL);
63
64 return 0;
65}
66
67static int ttusbdecfe_dvbs_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
68{
69 struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
70
71 u8 b[] = { 0x00, 0x00, 0x00, 0x01,
72 0x00, 0x00, 0x00, 0x00,
73 0x00, 0x00, 0x00, 0x01,
74 0x00, 0x00, 0x00, 0x00,
75 0x00, 0x00, 0x00, 0x00,
76 0x00, 0x00, 0x00, 0x00,
77 0x00, 0x00, 0x00, 0x00,
78 0x00, 0x00, 0x00, 0x00,
79 0x00, 0x00, 0x00, 0x00,
80 0x00, 0x00, 0x00, 0x00 };
81 u32 freq;
82 u32 sym_rate;
83 u32 band;
84 u32 lnb_voltage;
85
86 freq = htonl(p->frequency +
87 (state->hi_band ? LOF_HI : LOF_LO));
88 memcpy(&b[4], &freq, sizeof(u32));
89 sym_rate = htonl(p->u.qam.symbol_rate);
90 memcpy(&b[12], &sym_rate, sizeof(u32));
91 band = htonl(state->hi_band ? LOF_HI : LOF_LO);
92 memcpy(&b[24], &band, sizeof(u32));
93 lnb_voltage = htonl(state->voltage);
94 memcpy(&b[28], &lnb_voltage, sizeof(u32));
95
96 state->config->send_command(fe, 0x71, sizeof(b), b, NULL, NULL);
97
98 return 0;
99}
100
101static int ttusbdecfe_dvbs_diseqc_send_master_cmd(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd *cmd)
102{
103 struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
104 u8 b[] = { 0x00, 0xff, 0x00, 0x00,
105 0x00, 0x00, 0x00, 0x00,
106 0x00, 0x00 };
107
108 memcpy(&b[4], cmd->msg, cmd->msg_len);
109
110 state->config->send_command(fe, 0x72,
111 sizeof(b) - (6 - cmd->msg_len), b,
112 NULL, NULL);
113
114 return 0;
115}
116
117
118static int ttusbdecfe_dvbs_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
119{
120 struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
121
122 state->hi_band = (SEC_TONE_ON == tone);
123
124 return 0;
125}
126
127
128static int ttusbdecfe_dvbs_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
129{
130 struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
131
132 switch (voltage) {
133 case SEC_VOLTAGE_13:
134 state->voltage = 13;
135 break;
136 case SEC_VOLTAGE_18:
137 state->voltage = 18;
138 break;
139 default:
140 return -EINVAL;
141 }
142
143 return 0;
144}
145
146static void ttusbdecfe_release(struct dvb_frontend* fe)
147{
148 struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
149 kfree(state);
150}
151
152static struct dvb_frontend_ops ttusbdecfe_dvbt_ops;
153
154struct dvb_frontend* ttusbdecfe_dvbt_attach(const struct ttusbdecfe_config* config)
155{
156 struct ttusbdecfe_state* state = NULL;
157
158 /* allocate memory for the internal state */
159 state = (struct ttusbdecfe_state*) kmalloc(sizeof(struct ttusbdecfe_state), GFP_KERNEL);
160 if (state == NULL) goto error;
161
162 /* setup the state */
163 state->config = config;
164 memcpy(&state->ops, &ttusbdecfe_dvbt_ops, sizeof(struct dvb_frontend_ops));
165
166 /* create dvb_frontend */
167 state->frontend.ops = &state->ops;
168 state->frontend.demodulator_priv = state;
169 return &state->frontend;
170
171error:
172 kfree(state);
173 return NULL;
174}
175
176static struct dvb_frontend_ops ttusbdecfe_dvbs_ops;
177
178struct dvb_frontend* ttusbdecfe_dvbs_attach(const struct ttusbdecfe_config* config)
179{
180 struct ttusbdecfe_state* state = NULL;
181
182 /* allocate memory for the internal state */
183 state = (struct ttusbdecfe_state*) kmalloc(sizeof(struct ttusbdecfe_state), GFP_KERNEL);
184 if (state == NULL) goto error;
185
186 /* setup the state */
187 state->config = config;
188 state->voltage = 0;
189 state->hi_band = 0;
190 memcpy(&state->ops, &ttusbdecfe_dvbs_ops, sizeof(struct dvb_frontend_ops));
191
192 /* create dvb_frontend */
193 state->frontend.ops = &state->ops;
194 state->frontend.demodulator_priv = state;
195 return &state->frontend;
196
197error:
198 kfree(state);
199 return NULL;
200}
201
202static struct dvb_frontend_ops ttusbdecfe_dvbt_ops = {
203
204 .info = {
205 .name = "TechnoTrend/Hauppauge DEC2000-t Frontend",
206 .type = FE_OFDM,
207 .frequency_min = 51000000,
208 .frequency_max = 858000000,
209 .frequency_stepsize = 62500,
210 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
211 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
212 FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
213 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
214 FE_CAN_HIERARCHY_AUTO,
215 },
216
217 .release = ttusbdecfe_release,
218
219 .set_frontend = ttusbdecfe_dvbt_set_frontend,
220
221 .read_status = ttusbdecfe_read_status,
222};
223
224static struct dvb_frontend_ops ttusbdecfe_dvbs_ops = {
225
226 .info = {
227 .name = "TechnoTrend/Hauppauge DEC3000-s Frontend",
228 .type = FE_QPSK,
229 .frequency_min = 950000,
230 .frequency_max = 2150000,
231 .frequency_stepsize = 125,
232 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
233 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
234 FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
235 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
236 FE_CAN_HIERARCHY_AUTO,
237 },
238
239 .release = ttusbdecfe_release,
240
241 .set_frontend = ttusbdecfe_dvbs_set_frontend,
242
243 .read_status = ttusbdecfe_read_status,
244
245 .diseqc_send_master_cmd = ttusbdecfe_dvbs_diseqc_send_master_cmd,
246 .set_voltage = ttusbdecfe_dvbs_set_voltage,
247 .set_tone = ttusbdecfe_dvbs_set_tone,
248};
249
250MODULE_DESCRIPTION("TTUSB DEC DVB-T/S Demodulator driver");
251MODULE_AUTHOR("Alex Woods/Andrew de Quincey");
252MODULE_LICENSE("GPL");
253
254EXPORT_SYMBOL(ttusbdecfe_dvbt_attach);
255EXPORT_SYMBOL(ttusbdecfe_dvbs_attach);
diff --git a/drivers/media/dvb/ttusb-dec/ttusbdecfe.h b/drivers/media/dvb/ttusb-dec/ttusbdecfe.h
new file mode 100644
index 000000000000..15ccc3d1a20e
--- /dev/null
+++ b/drivers/media/dvb/ttusb-dec/ttusbdecfe.h
@@ -0,0 +1,38 @@
1/*
2 * TTUSB DEC Driver
3 *
4 * Copyright (C) 2003-2004 Alex Woods <linux-dvb@giblets.org>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 *
20 */
21
22#ifndef TTUSBDECFE_H
23#define TTUSBDECFE_H
24
25#include <linux/dvb/frontend.h>
26
27struct ttusbdecfe_config
28{
29 int (*send_command)(struct dvb_frontend* fe, const u8 command,
30 int param_length, const u8 params[],
31 int *result_length, u8 cmd_result[]);
32};
33
34extern struct dvb_frontend* ttusbdecfe_dvbs_attach(const struct ttusbdecfe_config* config);
35
36extern struct dvb_frontend* ttusbdecfe_dvbt_attach(const struct ttusbdecfe_config* config);
37
38#endif // TTUSBDECFE_H