aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/dvb')
-rw-r--r--drivers/media/dvb/Kconfig5
-rw-r--r--drivers/media/dvb/Makefile2
-rw-r--r--drivers/media/dvb/b2c2/flexcop-dma.c2
-rw-r--r--drivers/media/dvb/bt8xx/dvb-bt8xx.c2
-rw-r--r--drivers/media/dvb/cinergyT2/Kconfig85
-rw-r--r--drivers/media/dvb/cinergyT2/Makefile3
-rw-r--r--drivers/media/dvb/cinergyT2/cinergyT2.c1105
-rw-r--r--drivers/media/dvb/dm1105/Kconfig18
-rw-r--r--drivers/media/dvb/dm1105/Makefile3
-rw-r--r--drivers/media/dvb/dm1105/dm1105.c911
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.c666
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.h32
-rw-r--r--drivers/media/dvb/dvb-usb/Kconfig42
-rw-r--r--drivers/media/dvb/dvb-usb/Makefile10
-rw-r--r--drivers/media/dvb/dvb-usb/af9005-remote.c2
-rw-r--r--drivers/media/dvb/dvb-usb/af9005-script.h2
-rw-r--r--drivers/media/dvb/dvb-usb/af9005.c23
-rw-r--r--drivers/media/dvb/dvb-usb/af9015.c1474
-rw-r--r--drivers/media/dvb/dvb-usb/af9015.h524
-rw-r--r--drivers/media/dvb/dvb-usb/anysee.c30
-rw-r--r--drivers/media/dvb/dvb-usb/cinergyT2-core.c268
-rw-r--r--drivers/media/dvb/dvb-usb/cinergyT2-fe.c351
-rw-r--r--drivers/media/dvb/dvb-usb/cinergyT2.h95
-rw-r--r--drivers/media/dvb/dvb-usb/cxusb.c504
-rw-r--r--drivers/media/dvb/dvb-usb/dib0700.h4
-rw-r--r--drivers/media/dvb/dvb-usb/dib0700_core.c115
-rw-r--r--drivers/media/dvb/dvb-usb/dib0700_devices.c195
-rw-r--r--drivers/media/dvb/dvb-usb/dtv5100.c240
-rw-r--r--drivers/media/dvb/dvb-usb/dtv5100.h51
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-ids.h29
-rw-r--r--drivers/media/dvb/dvb-usb/dw2102.c572
-rw-r--r--drivers/media/dvb/dvb-usb/dw2102.h1
-rw-r--r--drivers/media/dvb/frontends/Kconfig47
-rw-r--r--drivers/media/dvb/frontends/Makefile7
-rw-r--r--drivers/media/dvb/frontends/af9013.c1685
-rw-r--r--drivers/media/dvb/frontends/af9013.h107
-rw-r--r--drivers/media/dvb/frontends/af9013_priv.h869
-rw-r--r--drivers/media/dvb/frontends/au8522.c133
-rw-r--r--drivers/media/dvb/frontends/au8522.h17
-rw-r--r--drivers/media/dvb/frontends/cx24110.h15
-rw-r--r--drivers/media/dvb/frontends/cx24116.c1423
-rw-r--r--drivers/media/dvb/frontends/cx24116.h53
-rw-r--r--drivers/media/dvb/frontends/dib0070.h8
-rw-r--r--drivers/media/dvb/frontends/dib7000m.c6
-rw-r--r--drivers/media/dvb/frontends/dib7000p.c3
-rw-r--r--drivers/media/dvb/frontends/dib7000p.h41
-rw-r--r--drivers/media/dvb/frontends/drx397xD.c288
-rw-r--r--drivers/media/dvb/frontends/drx397xD.h6
-rw-r--r--drivers/media/dvb/frontends/dvb_dummy_fe.c11
-rw-r--r--drivers/media/dvb/frontends/eds1547.h133
-rw-r--r--drivers/media/dvb/frontends/lgs8gl5.c454
-rw-r--r--drivers/media/dvb/frontends/lgs8gl5.h45
-rw-r--r--drivers/media/dvb/frontends/nxt200x.c4
-rw-r--r--drivers/media/dvb/frontends/or51211.c2
-rw-r--r--drivers/media/dvb/frontends/si21xx.c974
-rw-r--r--drivers/media/dvb/frontends/si21xx.h37
-rw-r--r--drivers/media/dvb/frontends/sp887x.c3
-rw-r--r--drivers/media/dvb/frontends/stb6000.c255
-rw-r--r--drivers/media/dvb/frontends/stb6000.h51
-rw-r--r--drivers/media/dvb/frontends/stv0288.c618
-rw-r--r--drivers/media/dvb/frontends/stv0288.h67
-rw-r--r--drivers/media/dvb/frontends/stv0299.c2
-rw-r--r--drivers/media/dvb/frontends/stv0299.h13
-rw-r--r--drivers/media/dvb/frontends/tdhd1.h73
-rw-r--r--drivers/media/dvb/ttpci/Kconfig1
-rw-r--r--drivers/media/dvb/ttpci/av7110.c127
-rw-r--r--drivers/media/dvb/ttpci/av7110.h1
-rw-r--r--drivers/media/dvb/ttpci/av7110_av.c3
-rw-r--r--drivers/media/dvb/ttpci/budget-av.c8
-rw-r--r--drivers/media/dvb/ttpci/budget-ci.c7
-rw-r--r--drivers/media/dvb/ttpci/budget-core.c6
-rw-r--r--drivers/media/dvb/ttpci/budget-patch.c9
-rw-r--r--drivers/media/dvb/ttpci/budget.c25
-rw-r--r--drivers/media/dvb/ttpci/budget.h2
-rw-r--r--drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c2
-rw-r--r--drivers/media/dvb/ttusb-dec/ttusb_dec.c2
-rw-r--r--drivers/media/dvb/ttusb-dec/ttusbdecfe.c16
77 files changed, 13471 insertions, 1554 deletions
diff --git a/drivers/media/dvb/Kconfig b/drivers/media/dvb/Kconfig
index 8bc1445bd33b..0bcd852576d6 100644
--- a/drivers/media/dvb/Kconfig
+++ b/drivers/media/dvb/Kconfig
@@ -20,7 +20,6 @@ comment "Supported USB Adapters"
20source "drivers/media/dvb/dvb-usb/Kconfig" 20source "drivers/media/dvb/dvb-usb/Kconfig"
21source "drivers/media/dvb/ttusb-budget/Kconfig" 21source "drivers/media/dvb/ttusb-budget/Kconfig"
22source "drivers/media/dvb/ttusb-dec/Kconfig" 22source "drivers/media/dvb/ttusb-dec/Kconfig"
23source "drivers/media/dvb/cinergyT2/Kconfig"
24source "drivers/media/dvb/siano/Kconfig" 23source "drivers/media/dvb/siano/Kconfig"
25 24
26comment "Supported FlexCopII (B2C2) Adapters" 25comment "Supported FlexCopII (B2C2) Adapters"
@@ -35,6 +34,10 @@ comment "Supported Pluto2 Adapters"
35 depends on DVB_CORE && PCI && I2C 34 depends on DVB_CORE && PCI && I2C
36source "drivers/media/dvb/pluto2/Kconfig" 35source "drivers/media/dvb/pluto2/Kconfig"
37 36
37comment "Supported SDMC DM1105 Adapters"
38 depends on DVB_CORE && PCI && I2C
39source "drivers/media/dvb/dm1105/Kconfig"
40
38comment "Supported DVB Frontends" 41comment "Supported DVB Frontends"
39 depends on DVB_CORE 42 depends on DVB_CORE
40source "drivers/media/dvb/frontends/Kconfig" 43source "drivers/media/dvb/frontends/Kconfig"
diff --git a/drivers/media/dvb/Makefile b/drivers/media/dvb/Makefile
index d6ba4d195201..f91e9eb15e52 100644
--- a/drivers/media/dvb/Makefile
+++ b/drivers/media/dvb/Makefile
@@ -2,4 +2,4 @@
2# Makefile for the kernel multimedia device drivers. 2# Makefile for the kernel multimedia device drivers.
3# 3#
4 4
5obj-y := dvb-core/ frontends/ ttpci/ ttusb-dec/ ttusb-budget/ b2c2/ bt8xx/ cinergyT2/ dvb-usb/ pluto2/ siano/ 5obj-y := dvb-core/ frontends/ ttpci/ ttusb-dec/ ttusb-budget/ b2c2/ bt8xx/ dvb-usb/ pluto2/ siano/ dm1105/
diff --git a/drivers/media/dvb/b2c2/flexcop-dma.c b/drivers/media/dvb/b2c2/flexcop-dma.c
index a91ed28f03a4..26f0011a5078 100644
--- a/drivers/media/dvb/b2c2/flexcop-dma.c
+++ b/drivers/media/dvb/b2c2/flexcop-dma.c
@@ -10,7 +10,7 @@
10int flexcop_dma_allocate(struct pci_dev *pdev, struct flexcop_dma *dma, u32 size) 10int flexcop_dma_allocate(struct pci_dev *pdev, struct flexcop_dma *dma, u32 size)
11{ 11{
12 u8 *tcpu; 12 u8 *tcpu;
13 dma_addr_t tdma; 13 dma_addr_t tdma = 0;
14 14
15 if (size % 2) { 15 if (size % 2) {
16 err("dma buffersize has to be even."); 16 err("dma buffersize has to be even.");
diff --git a/drivers/media/dvb/bt8xx/dvb-bt8xx.c b/drivers/media/dvb/bt8xx/dvb-bt8xx.c
index 6afbfbbef0ce..48762a2b9e42 100644
--- a/drivers/media/dvb/bt8xx/dvb-bt8xx.c
+++ b/drivers/media/dvb/bt8xx/dvb-bt8xx.c
@@ -702,7 +702,7 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
702 } 702 }
703 703
704 if (card->fe == NULL) 704 if (card->fe == NULL)
705 printk("dvb-bt8xx: A frontend driver was not found for device %04x/%04x subsystem %04x/%04x\n", 705 printk("dvb-bt8xx: A frontend driver was not found for device [%04x:%04x] subsystem [%04x:%04x]\n",
706 card->bt->dev->vendor, 706 card->bt->dev->vendor,
707 card->bt->dev->device, 707 card->bt->dev->device,
708 card->bt->dev->subsystem_vendor, 708 card->bt->dev->subsystem_vendor,
diff --git a/drivers/media/dvb/cinergyT2/Kconfig b/drivers/media/dvb/cinergyT2/Kconfig
deleted file mode 100644
index c03513b2ccae..000000000000
--- a/drivers/media/dvb/cinergyT2/Kconfig
+++ /dev/null
@@ -1,85 +0,0 @@
1config DVB_CINERGYT2
2 tristate "Terratec CinergyT2/qanu USB2 DVB-T receiver"
3 depends on DVB_CORE && USB && INPUT
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 reception 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 y
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 "50"
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
deleted file mode 100644
index d762d8cb0cf1..000000000000
--- a/drivers/media/dvb/cinergyT2/Makefile
+++ /dev/null
@@ -1,3 +0,0 @@
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
deleted file mode 100644
index a824f3719f81..000000000000
--- a/drivers/media/dvb/cinergyT2/cinergyT2.c
+++ /dev/null
@@ -1,1105 +0,0 @@
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/init.h>
26#include <linux/module.h>
27#include <linux/slab.h>
28#include <linux/usb.h>
29#include <linux/input.h>
30#include <linux/dvb/frontend.h>
31#include <linux/mutex.h>
32#include <linux/mm.h>
33#include <asm/io.h>
34
35#include "dmxdev.h"
36#include "dvb_demux.h"
37#include "dvb_net.h"
38
39#ifdef CONFIG_DVB_CINERGYT2_TUNING
40 #define STREAM_URB_COUNT (CONFIG_DVB_CINERGYT2_STREAM_URB_COUNT)
41 #define STREAM_BUF_SIZE (CONFIG_DVB_CINERGYT2_STREAM_BUF_SIZE)
42 #define QUERY_INTERVAL (CONFIG_DVB_CINERGYT2_QUERY_INTERVAL)
43 #ifdef CONFIG_DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE
44 #define RC_QUERY_INTERVAL (CONFIG_DVB_CINERGYT2_RC_QUERY_INTERVAL)
45 #define ENABLE_RC (1)
46 #endif
47#else
48 #define STREAM_URB_COUNT (32)
49 #define STREAM_BUF_SIZE (512) /* bytes */
50 #define ENABLE_RC (1)
51 #define RC_QUERY_INTERVAL (50) /* milliseconds */
52 #define QUERY_INTERVAL (333) /* milliseconds */
53#endif
54
55#define DRIVER_NAME "TerraTec/qanu USB2.0 Highspeed DVB-T Receiver"
56
57static int debug;
58module_param_named(debug, debug, int, 0644);
59MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
60
61DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
62
63#define dprintk(level, args...) \
64do { \
65 if ((debug & level)) { \
66 printk("%s: %s(): ", KBUILD_MODNAME, \
67 __func__); \
68 printk(args); } \
69} while (0)
70
71enum cinergyt2_ep1_cmd {
72 CINERGYT2_EP1_PID_TABLE_RESET = 0x01,
73 CINERGYT2_EP1_PID_SETUP = 0x02,
74 CINERGYT2_EP1_CONTROL_STREAM_TRANSFER = 0x03,
75 CINERGYT2_EP1_SET_TUNER_PARAMETERS = 0x04,
76 CINERGYT2_EP1_GET_TUNER_STATUS = 0x05,
77 CINERGYT2_EP1_START_SCAN = 0x06,
78 CINERGYT2_EP1_CONTINUE_SCAN = 0x07,
79 CINERGYT2_EP1_GET_RC_EVENTS = 0x08,
80 CINERGYT2_EP1_SLEEP_MODE = 0x09
81};
82
83struct dvbt_set_parameters_msg {
84 uint8_t cmd;
85 __le32 freq;
86 uint8_t bandwidth;
87 __le16 tps;
88 uint8_t flags;
89} __attribute__((packed));
90
91struct dvbt_get_status_msg {
92 __le32 freq;
93 uint8_t bandwidth;
94 __le16 tps;
95 uint8_t flags;
96 __le16 gain;
97 uint8_t snr;
98 __le32 viterbi_error_rate;
99 __le32 rs_error_rate;
100 __le32 uncorrected_block_count;
101 uint8_t lock_bits;
102 uint8_t prev_lock_bits;
103} __attribute__((packed));
104
105static struct dvb_frontend_info cinergyt2_fe_info = {
106 .name = DRIVER_NAME,
107 .type = FE_OFDM,
108 .frequency_min = 174000000,
109 .frequency_max = 862000000,
110 .frequency_stepsize = 166667,
111 .caps = FE_CAN_INVERSION_AUTO | FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
112 FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
113 FE_CAN_FEC_AUTO |
114 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
115 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
116 FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER | FE_CAN_MUTE_TS
117};
118
119struct cinergyt2 {
120 struct dvb_demux demux;
121 struct usb_device *udev;
122 struct mutex sem;
123 struct mutex wq_sem;
124 struct dvb_adapter adapter;
125 struct dvb_device *fedev;
126 struct dmxdev dmxdev;
127 struct dvb_net dvbnet;
128
129 int streaming;
130 int sleeping;
131
132 struct dvbt_set_parameters_msg param;
133 struct dvbt_get_status_msg status;
134 struct delayed_work query_work;
135
136 wait_queue_head_t poll_wq;
137 int pending_fe_events;
138 int disconnect_pending;
139 unsigned int uncorrected_block_count;
140 atomic_t inuse;
141
142 void *streambuf;
143 dma_addr_t streambuf_dmahandle;
144 struct urb *stream_urb [STREAM_URB_COUNT];
145
146#ifdef ENABLE_RC
147 struct input_dev *rc_input_dev;
148 char phys[64];
149 struct delayed_work rc_query_work;
150 int rc_input_event;
151 __le32 rc_last_code;
152 unsigned long last_event_jiffies;
153#endif
154};
155
156enum {
157 CINERGYT2_RC_EVENT_TYPE_NONE = 0x00,
158 CINERGYT2_RC_EVENT_TYPE_NEC = 0x01,
159 CINERGYT2_RC_EVENT_TYPE_RC5 = 0x02
160};
161
162struct cinergyt2_rc_event {
163 char type;
164 __le32 value;
165} __attribute__((packed));
166
167static const uint32_t rc_keys[] = {
168 CINERGYT2_RC_EVENT_TYPE_NEC, 0xfe01eb04, KEY_POWER,
169 CINERGYT2_RC_EVENT_TYPE_NEC, 0xfd02eb04, KEY_1,
170 CINERGYT2_RC_EVENT_TYPE_NEC, 0xfc03eb04, KEY_2,
171 CINERGYT2_RC_EVENT_TYPE_NEC, 0xfb04eb04, KEY_3,
172 CINERGYT2_RC_EVENT_TYPE_NEC, 0xfa05eb04, KEY_4,
173 CINERGYT2_RC_EVENT_TYPE_NEC, 0xf906eb04, KEY_5,
174 CINERGYT2_RC_EVENT_TYPE_NEC, 0xf807eb04, KEY_6,
175 CINERGYT2_RC_EVENT_TYPE_NEC, 0xf708eb04, KEY_7,
176 CINERGYT2_RC_EVENT_TYPE_NEC, 0xf609eb04, KEY_8,
177 CINERGYT2_RC_EVENT_TYPE_NEC, 0xf50aeb04, KEY_9,
178 CINERGYT2_RC_EVENT_TYPE_NEC, 0xf30ceb04, KEY_0,
179 CINERGYT2_RC_EVENT_TYPE_NEC, 0xf40beb04, KEY_VIDEO,
180 CINERGYT2_RC_EVENT_TYPE_NEC, 0xf20deb04, KEY_REFRESH,
181 CINERGYT2_RC_EVENT_TYPE_NEC, 0xf10eeb04, KEY_SELECT,
182 CINERGYT2_RC_EVENT_TYPE_NEC, 0xf00feb04, KEY_EPG,
183 CINERGYT2_RC_EVENT_TYPE_NEC, 0xef10eb04, KEY_UP,
184 CINERGYT2_RC_EVENT_TYPE_NEC, 0xeb14eb04, KEY_DOWN,
185 CINERGYT2_RC_EVENT_TYPE_NEC, 0xee11eb04, KEY_LEFT,
186 CINERGYT2_RC_EVENT_TYPE_NEC, 0xec13eb04, KEY_RIGHT,
187 CINERGYT2_RC_EVENT_TYPE_NEC, 0xed12eb04, KEY_OK,
188 CINERGYT2_RC_EVENT_TYPE_NEC, 0xea15eb04, KEY_TEXT,
189 CINERGYT2_RC_EVENT_TYPE_NEC, 0xe916eb04, KEY_INFO,
190 CINERGYT2_RC_EVENT_TYPE_NEC, 0xe817eb04, KEY_RED,
191 CINERGYT2_RC_EVENT_TYPE_NEC, 0xe718eb04, KEY_GREEN,
192 CINERGYT2_RC_EVENT_TYPE_NEC, 0xe619eb04, KEY_YELLOW,
193 CINERGYT2_RC_EVENT_TYPE_NEC, 0xe51aeb04, KEY_BLUE,
194 CINERGYT2_RC_EVENT_TYPE_NEC, 0xe31ceb04, KEY_VOLUMEUP,
195 CINERGYT2_RC_EVENT_TYPE_NEC, 0xe11eeb04, KEY_VOLUMEDOWN,
196 CINERGYT2_RC_EVENT_TYPE_NEC, 0xe21deb04, KEY_MUTE,
197 CINERGYT2_RC_EVENT_TYPE_NEC, 0xe41beb04, KEY_CHANNELUP,
198 CINERGYT2_RC_EVENT_TYPE_NEC, 0xe01feb04, KEY_CHANNELDOWN,
199 CINERGYT2_RC_EVENT_TYPE_NEC, 0xbf40eb04, KEY_PAUSE,
200 CINERGYT2_RC_EVENT_TYPE_NEC, 0xb34ceb04, KEY_PLAY,
201 CINERGYT2_RC_EVENT_TYPE_NEC, 0xa758eb04, KEY_RECORD,
202 CINERGYT2_RC_EVENT_TYPE_NEC, 0xab54eb04, KEY_PREVIOUS,
203 CINERGYT2_RC_EVENT_TYPE_NEC, 0xb748eb04, KEY_STOP,
204 CINERGYT2_RC_EVENT_TYPE_NEC, 0xa35ceb04, KEY_NEXT
205};
206
207static int cinergyt2_command (struct cinergyt2 *cinergyt2,
208 char *send_buf, int send_buf_len,
209 char *recv_buf, int recv_buf_len)
210{
211 int actual_len;
212 char dummy;
213 int ret;
214
215 ret = usb_bulk_msg(cinergyt2->udev, usb_sndbulkpipe(cinergyt2->udev, 1),
216 send_buf, send_buf_len, &actual_len, 1000);
217
218 if (ret)
219 dprintk(1, "usb_bulk_msg (send) failed, err %i\n", ret);
220
221 if (!recv_buf)
222 recv_buf = &dummy;
223
224 ret = usb_bulk_msg(cinergyt2->udev, usb_rcvbulkpipe(cinergyt2->udev, 1),
225 recv_buf, recv_buf_len, &actual_len, 1000);
226
227 if (ret)
228 dprintk(1, "usb_bulk_msg (read) failed, err %i\n", ret);
229
230 return ret ? ret : actual_len;
231}
232
233static void cinergyt2_control_stream_transfer (struct cinergyt2 *cinergyt2, int enable)
234{
235 char buf [] = { CINERGYT2_EP1_CONTROL_STREAM_TRANSFER, enable ? 1 : 0 };
236 cinergyt2_command(cinergyt2, buf, sizeof(buf), NULL, 0);
237}
238
239static void cinergyt2_sleep (struct cinergyt2 *cinergyt2, int sleep)
240{
241 char buf [] = { CINERGYT2_EP1_SLEEP_MODE, sleep ? 1 : 0 };
242 cinergyt2_command(cinergyt2, buf, sizeof(buf), NULL, 0);
243 cinergyt2->sleeping = sleep;
244}
245
246static void cinergyt2_stream_irq (struct urb *urb);
247
248static int cinergyt2_submit_stream_urb (struct cinergyt2 *cinergyt2, struct urb *urb)
249{
250 int err;
251
252 usb_fill_bulk_urb(urb,
253 cinergyt2->udev,
254 usb_rcvbulkpipe(cinergyt2->udev, 0x2),
255 urb->transfer_buffer,
256 STREAM_BUF_SIZE,
257 cinergyt2_stream_irq,
258 cinergyt2);
259
260 if ((err = usb_submit_urb(urb, GFP_ATOMIC)))
261 dprintk(1, "urb submission failed (err = %i)!\n", err);
262
263 return err;
264}
265
266static void cinergyt2_stream_irq (struct urb *urb)
267{
268 struct cinergyt2 *cinergyt2 = urb->context;
269
270 if (urb->actual_length > 0)
271 dvb_dmx_swfilter(&cinergyt2->demux,
272 urb->transfer_buffer, urb->actual_length);
273
274 if (cinergyt2->streaming)
275 cinergyt2_submit_stream_urb(cinergyt2, urb);
276}
277
278static void cinergyt2_free_stream_urbs (struct cinergyt2 *cinergyt2)
279{
280 int i;
281
282 for (i=0; i<STREAM_URB_COUNT; i++)
283 usb_free_urb(cinergyt2->stream_urb[i]);
284
285 usb_buffer_free(cinergyt2->udev, STREAM_URB_COUNT*STREAM_BUF_SIZE,
286 cinergyt2->streambuf, cinergyt2->streambuf_dmahandle);
287}
288
289static int cinergyt2_alloc_stream_urbs (struct cinergyt2 *cinergyt2)
290{
291 int i;
292
293 cinergyt2->streambuf = usb_buffer_alloc(cinergyt2->udev, STREAM_URB_COUNT*STREAM_BUF_SIZE,
294 GFP_KERNEL, &cinergyt2->streambuf_dmahandle);
295 if (!cinergyt2->streambuf) {
296 dprintk(1, "failed to alloc consistent stream memory area, bailing out!\n");
297 return -ENOMEM;
298 }
299
300 memset(cinergyt2->streambuf, 0, STREAM_URB_COUNT*STREAM_BUF_SIZE);
301
302 for (i=0; i<STREAM_URB_COUNT; i++) {
303 struct urb *urb;
304
305 if (!(urb = usb_alloc_urb(0, GFP_ATOMIC))) {
306 dprintk(1, "failed to alloc consistent stream urbs, bailing out!\n");
307 cinergyt2_free_stream_urbs(cinergyt2);
308 return -ENOMEM;
309 }
310
311 urb->transfer_buffer = cinergyt2->streambuf + i * STREAM_BUF_SIZE;
312 urb->transfer_buffer_length = STREAM_BUF_SIZE;
313
314 cinergyt2->stream_urb[i] = urb;
315 }
316
317 return 0;
318}
319
320static void cinergyt2_stop_stream_xfer (struct cinergyt2 *cinergyt2)
321{
322 int i;
323
324 cinergyt2_control_stream_transfer(cinergyt2, 0);
325
326 for (i=0; i<STREAM_URB_COUNT; i++)
327 usb_kill_urb(cinergyt2->stream_urb[i]);
328}
329
330static int cinergyt2_start_stream_xfer (struct cinergyt2 *cinergyt2)
331{
332 int i, err;
333
334 for (i=0; i<STREAM_URB_COUNT; i++) {
335 if ((err = cinergyt2_submit_stream_urb(cinergyt2, cinergyt2->stream_urb[i]))) {
336 cinergyt2_stop_stream_xfer(cinergyt2);
337 dprintk(1, "failed urb submission (%i: err = %i)!\n", i, err);
338 return err;
339 }
340 }
341
342 cinergyt2_control_stream_transfer(cinergyt2, 1);
343 return 0;
344}
345
346static int cinergyt2_start_feed(struct dvb_demux_feed *dvbdmxfeed)
347{
348 struct dvb_demux *demux = dvbdmxfeed->demux;
349 struct cinergyt2 *cinergyt2 = demux->priv;
350
351 if (cinergyt2->disconnect_pending)
352 return -EAGAIN;
353 if (mutex_lock_interruptible(&cinergyt2->sem))
354 return -ERESTARTSYS;
355
356 if (cinergyt2->streaming == 0)
357 cinergyt2_start_stream_xfer(cinergyt2);
358
359 cinergyt2->streaming++;
360 mutex_unlock(&cinergyt2->sem);
361 return 0;
362}
363
364static int cinergyt2_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
365{
366 struct dvb_demux *demux = dvbdmxfeed->demux;
367 struct cinergyt2 *cinergyt2 = demux->priv;
368
369 if (cinergyt2->disconnect_pending)
370 return -EAGAIN;
371 if (mutex_lock_interruptible(&cinergyt2->sem))
372 return -ERESTARTSYS;
373
374 if (--cinergyt2->streaming == 0)
375 cinergyt2_stop_stream_xfer(cinergyt2);
376
377 mutex_unlock(&cinergyt2->sem);
378 return 0;
379}
380
381/**
382 * convert linux-dvb frontend parameter set into TPS.
383 * See ETSI ETS-300744, section 4.6.2, table 9 for details.
384 *
385 * This function is probably reusable and may better get placed in a support
386 * library.
387 *
388 * We replace errornous fields by default TPS fields (the ones with value 0).
389 */
390static uint16_t compute_tps (struct dvb_frontend_parameters *p)
391{
392 struct dvb_ofdm_parameters *op = &p->u.ofdm;
393 uint16_t tps = 0;
394
395 switch (op->code_rate_HP) {
396 case FEC_2_3:
397 tps |= (1 << 7);
398 break;
399 case FEC_3_4:
400 tps |= (2 << 7);
401 break;
402 case FEC_5_6:
403 tps |= (3 << 7);
404 break;
405 case FEC_7_8:
406 tps |= (4 << 7);
407 break;
408 case FEC_1_2:
409 case FEC_AUTO:
410 default:
411 /* tps |= (0 << 7) */;
412 }
413
414 switch (op->code_rate_LP) {
415 case FEC_2_3:
416 tps |= (1 << 4);
417 break;
418 case FEC_3_4:
419 tps |= (2 << 4);
420 break;
421 case FEC_5_6:
422 tps |= (3 << 4);
423 break;
424 case FEC_7_8:
425 tps |= (4 << 4);
426 break;
427 case FEC_1_2:
428 case FEC_AUTO:
429 default:
430 /* tps |= (0 << 4) */;
431 }
432
433 switch (op->constellation) {
434 case QAM_16:
435 tps |= (1 << 13);
436 break;
437 case QAM_64:
438 tps |= (2 << 13);
439 break;
440 case QPSK:
441 default:
442 /* tps |= (0 << 13) */;
443 }
444
445 switch (op->transmission_mode) {
446 case TRANSMISSION_MODE_8K:
447 tps |= (1 << 0);
448 break;
449 case TRANSMISSION_MODE_2K:
450 default:
451 /* tps |= (0 << 0) */;
452 }
453
454 switch (op->guard_interval) {
455 case GUARD_INTERVAL_1_16:
456 tps |= (1 << 2);
457 break;
458 case GUARD_INTERVAL_1_8:
459 tps |= (2 << 2);
460 break;
461 case GUARD_INTERVAL_1_4:
462 tps |= (3 << 2);
463 break;
464 case GUARD_INTERVAL_1_32:
465 default:
466 /* tps |= (0 << 2) */;
467 }
468
469 switch (op->hierarchy_information) {
470 case HIERARCHY_1:
471 tps |= (1 << 10);
472 break;
473 case HIERARCHY_2:
474 tps |= (2 << 10);
475 break;
476 case HIERARCHY_4:
477 tps |= (3 << 10);
478 break;
479 case HIERARCHY_NONE:
480 default:
481 /* tps |= (0 << 10) */;
482 }
483
484 return tps;
485}
486
487static int cinergyt2_open (struct inode *inode, struct file *file)
488{
489 struct dvb_device *dvbdev = file->private_data;
490 struct cinergyt2 *cinergyt2 = dvbdev->priv;
491 int err = -EAGAIN;
492
493 if (cinergyt2->disconnect_pending)
494 goto out;
495 err = mutex_lock_interruptible(&cinergyt2->wq_sem);
496 if (err)
497 goto out;
498
499 err = mutex_lock_interruptible(&cinergyt2->sem);
500 if (err)
501 goto out_unlock1;
502
503 if ((err = dvb_generic_open(inode, file)))
504 goto out_unlock2;
505
506 if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
507 cinergyt2_sleep(cinergyt2, 0);
508 schedule_delayed_work(&cinergyt2->query_work, HZ/2);
509 }
510
511 atomic_inc(&cinergyt2->inuse);
512
513out_unlock2:
514 mutex_unlock(&cinergyt2->sem);
515out_unlock1:
516 mutex_unlock(&cinergyt2->wq_sem);
517out:
518 return err;
519}
520
521static void cinergyt2_unregister(struct cinergyt2 *cinergyt2)
522{
523 dvb_net_release(&cinergyt2->dvbnet);
524 dvb_dmxdev_release(&cinergyt2->dmxdev);
525 dvb_dmx_release(&cinergyt2->demux);
526 dvb_unregister_device(cinergyt2->fedev);
527 dvb_unregister_adapter(&cinergyt2->adapter);
528
529 cinergyt2_free_stream_urbs(cinergyt2);
530 kfree(cinergyt2);
531}
532
533static int cinergyt2_release (struct inode *inode, struct file *file)
534{
535 struct dvb_device *dvbdev = file->private_data;
536 struct cinergyt2 *cinergyt2 = dvbdev->priv;
537
538 mutex_lock(&cinergyt2->wq_sem);
539
540 if (!cinergyt2->disconnect_pending && (file->f_flags & O_ACCMODE) != O_RDONLY) {
541 cancel_rearming_delayed_work(&cinergyt2->query_work);
542
543 mutex_lock(&cinergyt2->sem);
544 cinergyt2_sleep(cinergyt2, 1);
545 mutex_unlock(&cinergyt2->sem);
546 }
547
548 mutex_unlock(&cinergyt2->wq_sem);
549
550 if (atomic_dec_and_test(&cinergyt2->inuse) && cinergyt2->disconnect_pending) {
551 warn("delayed unregister in release");
552 cinergyt2_unregister(cinergyt2);
553 }
554
555 return dvb_generic_release(inode, file);
556}
557
558static unsigned int cinergyt2_poll (struct file *file, struct poll_table_struct *wait)
559{
560 struct dvb_device *dvbdev = file->private_data;
561 struct cinergyt2 *cinergyt2 = dvbdev->priv;
562 unsigned int mask = 0;
563
564 if (cinergyt2->disconnect_pending)
565 return -EAGAIN;
566 if (mutex_lock_interruptible(&cinergyt2->sem))
567 return -ERESTARTSYS;
568
569 poll_wait(file, &cinergyt2->poll_wq, wait);
570
571 if (cinergyt2->pending_fe_events != 0)
572 mask |= (POLLIN | POLLRDNORM | POLLPRI);
573
574 mutex_unlock(&cinergyt2->sem);
575
576 return mask;
577}
578
579
580static int cinergyt2_ioctl (struct inode *inode, struct file *file,
581 unsigned cmd, unsigned long arg)
582{
583 struct dvb_device *dvbdev = file->private_data;
584 struct cinergyt2 *cinergyt2 = dvbdev->priv;
585 struct dvbt_get_status_msg *stat = &cinergyt2->status;
586 fe_status_t status = 0;
587
588 switch (cmd) {
589 case FE_GET_INFO:
590 return copy_to_user((void __user*) arg, &cinergyt2_fe_info,
591 sizeof(struct dvb_frontend_info));
592
593 case FE_READ_STATUS:
594 if (0xffff - le16_to_cpu(stat->gain) > 30)
595 status |= FE_HAS_SIGNAL;
596 if (stat->lock_bits & (1 << 6))
597 status |= FE_HAS_LOCK;
598 if (stat->lock_bits & (1 << 5))
599 status |= FE_HAS_SYNC;
600 if (stat->lock_bits & (1 << 4))
601 status |= FE_HAS_CARRIER;
602 if (stat->lock_bits & (1 << 1))
603 status |= FE_HAS_VITERBI;
604
605 return copy_to_user((void __user*) arg, &status, sizeof(status));
606
607 case FE_READ_BER:
608 return put_user(le32_to_cpu(stat->viterbi_error_rate),
609 (__u32 __user *) arg);
610
611 case FE_READ_SIGNAL_STRENGTH:
612 return put_user(0xffff - le16_to_cpu(stat->gain),
613 (__u16 __user *) arg);
614
615 case FE_READ_SNR:
616 return put_user((stat->snr << 8) | stat->snr,
617 (__u16 __user *) arg);
618
619 case FE_READ_UNCORRECTED_BLOCKS:
620 {
621 uint32_t unc_count;
622
623 if (mutex_lock_interruptible(&cinergyt2->sem))
624 return -ERESTARTSYS;
625 unc_count = cinergyt2->uncorrected_block_count;
626 cinergyt2->uncorrected_block_count = 0;
627 mutex_unlock(&cinergyt2->sem);
628
629 /* UNC are already converted to host byte order... */
630 return put_user(unc_count,(__u32 __user *) arg);
631 }
632 case FE_SET_FRONTEND:
633 {
634 struct dvbt_set_parameters_msg *param = &cinergyt2->param;
635 struct dvb_frontend_parameters p;
636 int err;
637
638 if ((file->f_flags & O_ACCMODE) == O_RDONLY)
639 return -EPERM;
640
641 if (copy_from_user(&p, (void __user*) arg, sizeof(p)))
642 return -EFAULT;
643
644 if (cinergyt2->disconnect_pending)
645 return -EAGAIN;
646 if (mutex_lock_interruptible(&cinergyt2->sem))
647 return -ERESTARTSYS;
648
649 param->cmd = CINERGYT2_EP1_SET_TUNER_PARAMETERS;
650 param->tps = cpu_to_le16(compute_tps(&p));
651 param->freq = cpu_to_le32(p.frequency / 1000);
652 param->bandwidth = 8 - p.u.ofdm.bandwidth - BANDWIDTH_8_MHZ;
653
654 stat->lock_bits = 0;
655 cinergyt2->pending_fe_events++;
656 wake_up_interruptible(&cinergyt2->poll_wq);
657
658 err = cinergyt2_command(cinergyt2,
659 (char *) param, sizeof(*param),
660 NULL, 0);
661
662 mutex_unlock(&cinergyt2->sem);
663
664 return (err < 0) ? err : 0;
665 }
666
667 case FE_GET_FRONTEND:
668 /**
669 * trivial to implement (see struct dvbt_get_status_msg).
670 * equivalent to FE_READ ioctls, but needs
671 * TPS -> linux-dvb parameter set conversion. Feel free
672 * to implement this and send us a patch if you need this
673 * functionality.
674 */
675 break;
676
677 case FE_GET_EVENT:
678 {
679 /**
680 * for now we only fill the status field. the parameters
681 * are trivial to fill as soon FE_GET_FRONTEND is done.
682 */
683 struct dvb_frontend_event __user *e = (void __user *) arg;
684 if (cinergyt2->pending_fe_events == 0) {
685 if (file->f_flags & O_NONBLOCK)
686 return -EWOULDBLOCK;
687 wait_event_interruptible(cinergyt2->poll_wq,
688 cinergyt2->pending_fe_events > 0);
689 }
690 cinergyt2->pending_fe_events = 0;
691 return cinergyt2_ioctl(inode, file, FE_READ_STATUS,
692 (unsigned long) &e->status);
693 }
694
695 default:
696 ;
697 }
698
699 return -EINVAL;
700}
701
702static int cinergyt2_mmap(struct file *file, struct vm_area_struct *vma)
703{
704 struct dvb_device *dvbdev = file->private_data;
705 struct cinergyt2 *cinergyt2 = dvbdev->priv;
706 int ret = 0;
707
708 lock_kernel();
709
710 if (vma->vm_flags & (VM_WRITE | VM_EXEC)) {
711 ret = -EPERM;
712 goto bailout;
713 }
714
715 if (vma->vm_end > vma->vm_start + STREAM_URB_COUNT * STREAM_BUF_SIZE) {
716 ret = -EINVAL;
717 goto bailout;
718 }
719
720 vma->vm_flags |= (VM_IO | VM_DONTCOPY);
721 vma->vm_file = file;
722
723 ret = remap_pfn_range(vma, vma->vm_start,
724 virt_to_phys(cinergyt2->streambuf) >> PAGE_SHIFT,
725 vma->vm_end - vma->vm_start,
726 vma->vm_page_prot) ? -EAGAIN : 0;
727bailout:
728 unlock_kernel();
729 return ret;
730}
731
732static struct file_operations cinergyt2_fops = {
733 .owner = THIS_MODULE,
734 .ioctl = cinergyt2_ioctl,
735 .poll = cinergyt2_poll,
736 .open = cinergyt2_open,
737 .release = cinergyt2_release,
738 .mmap = cinergyt2_mmap
739};
740
741static struct dvb_device cinergyt2_fe_template = {
742 .users = ~0,
743 .writers = 1,
744 .readers = (~0)-1,
745 .fops = &cinergyt2_fops
746};
747
748#ifdef ENABLE_RC
749
750static void cinergyt2_query_rc (struct work_struct *work)
751{
752 struct cinergyt2 *cinergyt2 =
753 container_of(work, struct cinergyt2, rc_query_work.work);
754 char buf[1] = { CINERGYT2_EP1_GET_RC_EVENTS };
755 struct cinergyt2_rc_event rc_events[12];
756 int n, len, i;
757
758 if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem))
759 return;
760
761 len = cinergyt2_command(cinergyt2, buf, sizeof(buf),
762 (char *) rc_events, sizeof(rc_events));
763 if (len < 0)
764 goto out;
765 if (len == 0) {
766 if (time_after(jiffies, cinergyt2->last_event_jiffies +
767 msecs_to_jiffies(150))) {
768 /* stop key repeat */
769 if (cinergyt2->rc_input_event != KEY_MAX) {
770 dprintk(1, "rc_input_event=%d Up\n", cinergyt2->rc_input_event);
771 input_report_key(cinergyt2->rc_input_dev,
772 cinergyt2->rc_input_event, 0);
773 input_sync(cinergyt2->rc_input_dev);
774 cinergyt2->rc_input_event = KEY_MAX;
775 }
776 cinergyt2->rc_last_code = cpu_to_le32(~0);
777 }
778 goto out;
779 }
780 cinergyt2->last_event_jiffies = jiffies;
781
782 for (n = 0; n < (len / sizeof(rc_events[0])); n++) {
783 dprintk(1, "rc_events[%d].value = %x, type=%x\n",
784 n, le32_to_cpu(rc_events[n].value), rc_events[n].type);
785
786 if (rc_events[n].type == CINERGYT2_RC_EVENT_TYPE_NEC &&
787 rc_events[n].value == cpu_to_le32(~0)) {
788 /* keyrepeat bit -> just repeat last rc_input_event */
789 } else {
790 cinergyt2->rc_input_event = KEY_MAX;
791 for (i = 0; i < ARRAY_SIZE(rc_keys); i += 3) {
792 if (rc_keys[i + 0] == rc_events[n].type &&
793 rc_keys[i + 1] == le32_to_cpu(rc_events[n].value)) {
794 cinergyt2->rc_input_event = rc_keys[i + 2];
795 break;
796 }
797 }
798 }
799
800 if (cinergyt2->rc_input_event != KEY_MAX) {
801 if (rc_events[n].value == cinergyt2->rc_last_code &&
802 cinergyt2->rc_last_code != cpu_to_le32(~0)) {
803 /* emit a key-up so the double event is recognized */
804 dprintk(1, "rc_input_event=%d UP\n", cinergyt2->rc_input_event);
805 input_report_key(cinergyt2->rc_input_dev,
806 cinergyt2->rc_input_event, 0);
807 }
808 dprintk(1, "rc_input_event=%d\n", cinergyt2->rc_input_event);
809 input_report_key(cinergyt2->rc_input_dev,
810 cinergyt2->rc_input_event, 1);
811 input_sync(cinergyt2->rc_input_dev);
812 cinergyt2->rc_last_code = rc_events[n].value;
813 }
814 }
815
816out:
817 schedule_delayed_work(&cinergyt2->rc_query_work,
818 msecs_to_jiffies(RC_QUERY_INTERVAL));
819
820 mutex_unlock(&cinergyt2->sem);
821}
822
823static int cinergyt2_register_rc(struct cinergyt2 *cinergyt2)
824{
825 struct input_dev *input_dev;
826 int i;
827 int err;
828
829 input_dev = input_allocate_device();
830 if (!input_dev)
831 return -ENOMEM;
832
833 usb_make_path(cinergyt2->udev, cinergyt2->phys, sizeof(cinergyt2->phys));
834 strlcat(cinergyt2->phys, "/input0", sizeof(cinergyt2->phys));
835 cinergyt2->rc_input_event = KEY_MAX;
836 cinergyt2->rc_last_code = cpu_to_le32(~0);
837 INIT_DELAYED_WORK(&cinergyt2->rc_query_work, cinergyt2_query_rc);
838
839 input_dev->name = DRIVER_NAME " remote control";
840 input_dev->phys = cinergyt2->phys;
841 input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
842 for (i = 0; i < ARRAY_SIZE(rc_keys); i += 3)
843 set_bit(rc_keys[i + 2], input_dev->keybit);
844 input_dev->keycodesize = 0;
845 input_dev->keycodemax = 0;
846 input_dev->id.bustype = BUS_USB;
847 input_dev->id.vendor = le16_to_cpu(cinergyt2->udev->descriptor.idVendor);
848 input_dev->id.product = le16_to_cpu(cinergyt2->udev->descriptor.idProduct);
849 input_dev->id.version = 1;
850 input_dev->dev.parent = &cinergyt2->udev->dev;
851
852 err = input_register_device(input_dev);
853 if (err) {
854 input_free_device(input_dev);
855 return err;
856 }
857
858 cinergyt2->rc_input_dev = input_dev;
859 schedule_delayed_work(&cinergyt2->rc_query_work, HZ/2);
860
861 return 0;
862}
863
864static void cinergyt2_unregister_rc(struct cinergyt2 *cinergyt2)
865{
866 cancel_rearming_delayed_work(&cinergyt2->rc_query_work);
867 input_unregister_device(cinergyt2->rc_input_dev);
868}
869
870static inline void cinergyt2_suspend_rc(struct cinergyt2 *cinergyt2)
871{
872 cancel_rearming_delayed_work(&cinergyt2->rc_query_work);
873}
874
875static inline void cinergyt2_resume_rc(struct cinergyt2 *cinergyt2)
876{
877 schedule_delayed_work(&cinergyt2->rc_query_work, HZ/2);
878}
879
880#else
881
882static inline int cinergyt2_register_rc(struct cinergyt2 *cinergyt2) { return 0; }
883static inline void cinergyt2_unregister_rc(struct cinergyt2 *cinergyt2) { }
884static inline void cinergyt2_suspend_rc(struct cinergyt2 *cinergyt2) { }
885static inline void cinergyt2_resume_rc(struct cinergyt2 *cinergyt2) { }
886
887#endif /* ENABLE_RC */
888
889static void cinergyt2_query (struct work_struct *work)
890{
891 struct cinergyt2 *cinergyt2 =
892 container_of(work, struct cinergyt2, query_work.work);
893 char cmd [] = { CINERGYT2_EP1_GET_TUNER_STATUS };
894 struct dvbt_get_status_msg *s = &cinergyt2->status;
895 uint8_t lock_bits;
896
897 if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem))
898 return;
899
900 lock_bits = s->lock_bits;
901
902 cinergyt2_command(cinergyt2, cmd, sizeof(cmd), (char *) s, sizeof(*s));
903
904 cinergyt2->uncorrected_block_count +=
905 le32_to_cpu(s->uncorrected_block_count);
906
907 if (lock_bits != s->lock_bits) {
908 wake_up_interruptible(&cinergyt2->poll_wq);
909 cinergyt2->pending_fe_events++;
910 }
911
912 schedule_delayed_work(&cinergyt2->query_work,
913 msecs_to_jiffies(QUERY_INTERVAL));
914
915 mutex_unlock(&cinergyt2->sem);
916}
917
918static int cinergyt2_probe (struct usb_interface *intf,
919 const struct usb_device_id *id)
920{
921 struct cinergyt2 *cinergyt2;
922 int err;
923
924 if (!(cinergyt2 = kzalloc (sizeof(struct cinergyt2), GFP_KERNEL))) {
925 dprintk(1, "out of memory?!?\n");
926 return -ENOMEM;
927 }
928
929 usb_set_intfdata (intf, (void *) cinergyt2);
930
931 mutex_init(&cinergyt2->sem);
932 mutex_init(&cinergyt2->wq_sem);
933 init_waitqueue_head (&cinergyt2->poll_wq);
934 INIT_DELAYED_WORK(&cinergyt2->query_work, cinergyt2_query);
935
936 cinergyt2->udev = interface_to_usbdev(intf);
937 cinergyt2->param.cmd = CINERGYT2_EP1_SET_TUNER_PARAMETERS;
938
939 if (cinergyt2_alloc_stream_urbs (cinergyt2) < 0) {
940 dprintk(1, "unable to allocate stream urbs\n");
941 kfree(cinergyt2);
942 return -ENOMEM;
943 }
944
945 err = dvb_register_adapter(&cinergyt2->adapter, DRIVER_NAME,
946 THIS_MODULE, &cinergyt2->udev->dev,
947 adapter_nr);
948 if (err < 0) {
949 kfree(cinergyt2);
950 return err;
951 }
952
953 cinergyt2->demux.priv = cinergyt2;
954 cinergyt2->demux.filternum = 256;
955 cinergyt2->demux.feednum = 256;
956 cinergyt2->demux.start_feed = cinergyt2_start_feed;
957 cinergyt2->demux.stop_feed = cinergyt2_stop_feed;
958 cinergyt2->demux.dmx.capabilities = DMX_TS_FILTERING |
959 DMX_SECTION_FILTERING |
960 DMX_MEMORY_BASED_FILTERING;
961
962 if ((err = dvb_dmx_init(&cinergyt2->demux)) < 0) {
963 dprintk(1, "dvb_dmx_init() failed (err = %d)\n", err);
964 goto bailout;
965 }
966
967 cinergyt2->dmxdev.filternum = cinergyt2->demux.filternum;
968 cinergyt2->dmxdev.demux = &cinergyt2->demux.dmx;
969 cinergyt2->dmxdev.capabilities = 0;
970
971 if ((err = dvb_dmxdev_init(&cinergyt2->dmxdev, &cinergyt2->adapter)) < 0) {
972 dprintk(1, "dvb_dmxdev_init() failed (err = %d)\n", err);
973 goto bailout;
974 }
975
976 if (dvb_net_init(&cinergyt2->adapter, &cinergyt2->dvbnet, &cinergyt2->demux.dmx))
977 dprintk(1, "dvb_net_init() failed!\n");
978
979 dvb_register_device(&cinergyt2->adapter, &cinergyt2->fedev,
980 &cinergyt2_fe_template, cinergyt2,
981 DVB_DEVICE_FRONTEND);
982
983 err = cinergyt2_register_rc(cinergyt2);
984 if (err)
985 goto bailout;
986
987 return 0;
988
989bailout:
990 dvb_net_release(&cinergyt2->dvbnet);
991 dvb_dmxdev_release(&cinergyt2->dmxdev);
992 dvb_dmx_release(&cinergyt2->demux);
993 dvb_unregister_adapter(&cinergyt2->adapter);
994 cinergyt2_free_stream_urbs(cinergyt2);
995 kfree(cinergyt2);
996 return -ENOMEM;
997}
998
999static void cinergyt2_disconnect (struct usb_interface *intf)
1000{
1001 struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf);
1002
1003 cinergyt2_unregister_rc(cinergyt2);
1004 cancel_rearming_delayed_work(&cinergyt2->query_work);
1005 wake_up_interruptible(&cinergyt2->poll_wq);
1006
1007 cinergyt2->demux.dmx.close(&cinergyt2->demux.dmx);
1008 cinergyt2->disconnect_pending = 1;
1009
1010 if (!atomic_read(&cinergyt2->inuse))
1011 cinergyt2_unregister(cinergyt2);
1012}
1013
1014static int cinergyt2_suspend (struct usb_interface *intf, pm_message_t state)
1015{
1016 struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf);
1017
1018 if (cinergyt2->disconnect_pending)
1019 return -EAGAIN;
1020 if (mutex_lock_interruptible(&cinergyt2->wq_sem))
1021 return -ERESTARTSYS;
1022
1023 cinergyt2_suspend_rc(cinergyt2);
1024 cancel_rearming_delayed_work(&cinergyt2->query_work);
1025
1026 mutex_lock(&cinergyt2->sem);
1027 if (cinergyt2->streaming)
1028 cinergyt2_stop_stream_xfer(cinergyt2);
1029 cinergyt2_sleep(cinergyt2, 1);
1030 mutex_unlock(&cinergyt2->sem);
1031
1032 mutex_unlock(&cinergyt2->wq_sem);
1033
1034 return 0;
1035}
1036
1037static int cinergyt2_resume (struct usb_interface *intf)
1038{
1039 struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf);
1040 struct dvbt_set_parameters_msg *param = &cinergyt2->param;
1041 int err = -EAGAIN;
1042
1043 if (cinergyt2->disconnect_pending)
1044 goto out;
1045 err = mutex_lock_interruptible(&cinergyt2->wq_sem);
1046 if (err)
1047 goto out;
1048
1049 err = mutex_lock_interruptible(&cinergyt2->sem);
1050 if (err)
1051 goto out_unlock1;
1052
1053 if (!cinergyt2->sleeping) {
1054 cinergyt2_sleep(cinergyt2, 0);
1055 cinergyt2_command(cinergyt2, (char *) param, sizeof(*param), NULL, 0);
1056 if (cinergyt2->streaming)
1057 cinergyt2_start_stream_xfer(cinergyt2);
1058 schedule_delayed_work(&cinergyt2->query_work, HZ/2);
1059 }
1060
1061 cinergyt2_resume_rc(cinergyt2);
1062
1063 mutex_unlock(&cinergyt2->sem);
1064out_unlock1:
1065 mutex_unlock(&cinergyt2->wq_sem);
1066out:
1067 return err;
1068}
1069
1070static const struct usb_device_id cinergyt2_table [] __devinitdata = {
1071 { USB_DEVICE(0x0ccd, 0x0038) },
1072 { 0 }
1073};
1074
1075MODULE_DEVICE_TABLE(usb, cinergyt2_table);
1076
1077static struct usb_driver cinergyt2_driver = {
1078 .name = "cinergyT2",
1079 .probe = cinergyt2_probe,
1080 .disconnect = cinergyt2_disconnect,
1081 .suspend = cinergyt2_suspend,
1082 .resume = cinergyt2_resume,
1083 .id_table = cinergyt2_table
1084};
1085
1086static int __init cinergyt2_init (void)
1087{
1088 int err;
1089
1090 if ((err = usb_register(&cinergyt2_driver)) < 0)
1091 dprintk(1, "usb_register() failed! (err %i)\n", err);
1092
1093 return err;
1094}
1095
1096static void __exit cinergyt2_exit (void)
1097{
1098 usb_deregister(&cinergyt2_driver);
1099}
1100
1101module_init (cinergyt2_init);
1102module_exit (cinergyt2_exit);
1103
1104MODULE_LICENSE("GPL");
1105MODULE_AUTHOR("Holger Waechtler, Daniel Mack");
diff --git a/drivers/media/dvb/dm1105/Kconfig b/drivers/media/dvb/dm1105/Kconfig
new file mode 100644
index 000000000000..1332301ef3ae
--- /dev/null
+++ b/drivers/media/dvb/dm1105/Kconfig
@@ -0,0 +1,18 @@
1config DVB_DM1105
2 tristate "SDMC DM1105 based PCI cards"
3 depends on DVB_CORE && PCI && I2C
4 select DVB_PLL if !DVB_FE_CUSTOMISE
5 select DVB_STV0299 if !DVB_FE_CUSTOMISE
6 select DVB_STV0288 if !DVB_FE_CUSTOMISE
7 select DVB_STB6000 if !DVB_FE_CUSTOMISE
8 select DVB_CX24116 if !DVB_FE_CUSTOMISE
9 select DVB_SI21XX if !DVB_FE_CUSTOMISE
10 help
11 Support for cards based on the SDMC DM1105 PCI chip like
12 DvbWorld 2002
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 or M if you own such a device and want to use it.
diff --git a/drivers/media/dvb/dm1105/Makefile b/drivers/media/dvb/dm1105/Makefile
new file mode 100644
index 000000000000..8ac28b0546af
--- /dev/null
+++ b/drivers/media/dvb/dm1105/Makefile
@@ -0,0 +1,3 @@
1obj-$(CONFIG_DVB_DM1105) += dm1105.o
2
3EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends
diff --git a/drivers/media/dvb/dm1105/dm1105.c b/drivers/media/dvb/dm1105/dm1105.c
new file mode 100644
index 000000000000..f7321448b4b1
--- /dev/null
+++ b/drivers/media/dvb/dm1105/dm1105.c
@@ -0,0 +1,911 @@
1/*
2 * dm1105.c - driver for DVB cards based on SDMC DM1105 PCI chip
3 *
4 * Copyright (C) 2008 Igor M. Liplianin <liplianin@me.by>
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/version.h>
23#include <linux/i2c.h>
24#include <linux/init.h>
25#include <linux/kernel.h>
26#include <linux/module.h>
27#include <linux/proc_fs.h>
28#include <linux/pci.h>
29#include <linux/dma-mapping.h>
30#include <linux/input.h>
31#include <media/ir-common.h>
32
33#include "demux.h"
34#include "dmxdev.h"
35#include "dvb_demux.h"
36#include "dvb_frontend.h"
37#include "dvb_net.h"
38#include "dvbdev.h"
39#include "dvb-pll.h"
40
41#include "stv0299.h"
42#include "stv0288.h"
43#include "stb6000.h"
44#include "si21xx.h"
45#include "cx24116.h"
46#include "z0194a.h"
47
48/* ----------------------------------------------- */
49/*
50 * PCI ID's
51 */
52#ifndef PCI_VENDOR_ID_TRIGEM
53#define PCI_VENDOR_ID_TRIGEM 0x109f
54#endif
55#ifndef PCI_DEVICE_ID_DM1105
56#define PCI_DEVICE_ID_DM1105 0x036f
57#endif
58#ifndef PCI_DEVICE_ID_DW2002
59#define PCI_DEVICE_ID_DW2002 0x2002
60#endif
61#ifndef PCI_DEVICE_ID_DW2004
62#define PCI_DEVICE_ID_DW2004 0x2004
63#endif
64/* ----------------------------------------------- */
65/* sdmc dm1105 registers */
66
67/* TS Control */
68#define DM1105_TSCTR 0x00
69#define DM1105_DTALENTH 0x04
70
71/* GPIO Interface */
72#define DM1105_GPIOVAL 0x08
73#define DM1105_GPIOCTR 0x0c
74
75/* PID serial number */
76#define DM1105_PIDN 0x10
77
78/* Odd-even secret key select */
79#define DM1105_CWSEL 0x14
80
81/* Host Command Interface */
82#define DM1105_HOST_CTR 0x18
83#define DM1105_HOST_AD 0x1c
84
85/* PCI Interface */
86#define DM1105_CR 0x30
87#define DM1105_RST 0x34
88#define DM1105_STADR 0x38
89#define DM1105_RLEN 0x3c
90#define DM1105_WRP 0x40
91#define DM1105_INTCNT 0x44
92#define DM1105_INTMAK 0x48
93#define DM1105_INTSTS 0x4c
94
95/* CW Value */
96#define DM1105_ODD 0x50
97#define DM1105_EVEN 0x58
98
99/* PID Value */
100#define DM1105_PID 0x60
101
102/* IR Control */
103#define DM1105_IRCTR 0x64
104#define DM1105_IRMODE 0x68
105#define DM1105_SYSTEMCODE 0x6c
106#define DM1105_IRCODE 0x70
107
108/* Unknown Values */
109#define DM1105_ENCRYPT 0x74
110#define DM1105_VER 0x7c
111
112/* I2C Interface */
113#define DM1105_I2CCTR 0x80
114#define DM1105_I2CSTS 0x81
115#define DM1105_I2CDAT 0x82
116#define DM1105_I2C_RA 0x83
117/* ----------------------------------------------- */
118/* Interrupt Mask Bits */
119
120#define INTMAK_TSIRQM 0x01
121#define INTMAK_HIRQM 0x04
122#define INTMAK_IRM 0x08
123#define INTMAK_ALLMASK (INTMAK_TSIRQM | \
124 INTMAK_HIRQM | \
125 INTMAK_IRM)
126#define INTMAK_NONEMASK 0x00
127
128/* Interrupt Status Bits */
129#define INTSTS_TSIRQ 0x01
130#define INTSTS_HIRQ 0x04
131#define INTSTS_IR 0x08
132
133/* IR Control Bits */
134#define DM1105_IR_EN 0x01
135#define DM1105_SYS_CHK 0x02
136#define DM1105_REP_FLG 0x08
137
138/* EEPROM addr */
139#define IIC_24C01_addr 0xa0
140/* Max board count */
141#define DM1105_MAX 0x04
142
143#define DRIVER_NAME "dm1105"
144
145#define DM1105_DMA_PACKETS 47
146#define DM1105_DMA_PACKET_LENGTH (128*4)
147#define DM1105_DMA_BYTES (128 * 4 * DM1105_DMA_PACKETS)
148
149/* GPIO's for LNB power control */
150#define DM1105_LNB_MASK 0x00000000
151#define DM1105_LNB_13V 0x00010100
152#define DM1105_LNB_18V 0x00000100
153
154static int ir_debug;
155module_param(ir_debug, int, 0644);
156MODULE_PARM_DESC(ir_debug, "enable debugging information for IR decoding");
157
158DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
159
160static u16 ir_codes_dm1105_nec[128] = {
161 [0x0a] = KEY_Q, /*power*/
162 [0x0c] = KEY_M, /*mute*/
163 [0x11] = KEY_1,
164 [0x12] = KEY_2,
165 [0x13] = KEY_3,
166 [0x14] = KEY_4,
167 [0x15] = KEY_5,
168 [0x16] = KEY_6,
169 [0x17] = KEY_7,
170 [0x18] = KEY_8,
171 [0x19] = KEY_9,
172 [0x10] = KEY_0,
173 [0x1c] = KEY_PAGEUP, /*ch+*/
174 [0x0f] = KEY_PAGEDOWN, /*ch-*/
175 [0x1a] = KEY_O, /*vol+*/
176 [0x0e] = KEY_Z, /*vol-*/
177 [0x04] = KEY_R, /*rec*/
178 [0x09] = KEY_D, /*fav*/
179 [0x08] = KEY_BACKSPACE, /*rewind*/
180 [0x07] = KEY_A, /*fast*/
181 [0x0b] = KEY_P, /*pause*/
182 [0x02] = KEY_ESC, /*cancel*/
183 [0x03] = KEY_G, /*tab*/
184 [0x00] = KEY_UP, /*up*/
185 [0x1f] = KEY_ENTER, /*ok*/
186 [0x01] = KEY_DOWN, /*down*/
187 [0x05] = KEY_C, /*cap*/
188 [0x06] = KEY_S, /*stop*/
189 [0x40] = KEY_F, /*full*/
190 [0x1e] = KEY_W, /*tvmode*/
191 [0x1b] = KEY_B, /*recall*/
192};
193
194/* infrared remote control */
195struct infrared {
196 u16 key_map[128];
197 struct input_dev *input_dev;
198 char input_phys[32];
199 struct tasklet_struct ir_tasklet;
200 u32 ir_command;
201};
202
203struct dm1105dvb {
204 /* pci */
205 struct pci_dev *pdev;
206 u8 __iomem *io_mem;
207
208 /* ir */
209 struct infrared ir;
210
211 /* dvb */
212 struct dmx_frontend hw_frontend;
213 struct dmx_frontend mem_frontend;
214 struct dmxdev dmxdev;
215 struct dvb_adapter dvb_adapter;
216 struct dvb_demux demux;
217 struct dvb_frontend *fe;
218 struct dvb_net dvbnet;
219 unsigned int full_ts_users;
220
221 /* i2c */
222 struct i2c_adapter i2c_adap;
223
224 /* dma */
225 dma_addr_t dma_addr;
226 unsigned char *ts_buf;
227 u32 wrp;
228 u32 buffer_size;
229 unsigned int PacketErrorCount;
230 unsigned int dmarst;
231 spinlock_t lock;
232
233};
234
235#define dm_io_mem(reg) ((unsigned long)(&dm1105dvb->io_mem[reg]))
236
237static struct dm1105dvb *dm1105dvb_local;
238
239static int dm1105_i2c_xfer(struct i2c_adapter *i2c_adap,
240 struct i2c_msg *msgs, int num)
241{
242 struct dm1105dvb *dm1105dvb ;
243
244 int addr, rc, i, j, k, len, byte, data;
245 u8 status;
246
247 dm1105dvb = i2c_adap->algo_data;
248 for (i = 0; i < num; i++) {
249 outb(0x00, dm_io_mem(DM1105_I2CCTR));
250 if (msgs[i].flags & I2C_M_RD) {
251 /* read bytes */
252 addr = msgs[i].addr << 1;
253 addr |= 1;
254 outb(addr, dm_io_mem(DM1105_I2CDAT));
255 for (byte = 0; byte < msgs[i].len; byte++)
256 outb(0, dm_io_mem(DM1105_I2CDAT + byte + 1));
257
258 outb(0x81 + msgs[i].len, dm_io_mem(DM1105_I2CCTR));
259 for (j = 0; j < 55; j++) {
260 mdelay(10);
261 status = inb(dm_io_mem(DM1105_I2CSTS));
262 if ((status & 0xc0) == 0x40)
263 break;
264 }
265 if (j >= 55)
266 return -1;
267
268 for (byte = 0; byte < msgs[i].len; byte++) {
269 rc = inb(dm_io_mem(DM1105_I2CDAT + byte + 1));
270 if (rc < 0)
271 goto err;
272 msgs[i].buf[byte] = rc;
273 }
274 } else {
275 if ((msgs[i].buf[0] == 0xf7) && (msgs[i].addr == 0x55)) {
276 /* prepaired for cx24116 firmware */
277 /* Write in small blocks */
278 len = msgs[i].len - 1;
279 k = 1;
280 do {
281 outb(msgs[i].addr << 1, dm_io_mem(DM1105_I2CDAT));
282 outb(0xf7, dm_io_mem(DM1105_I2CDAT + 1));
283 for (byte = 0; byte < (len > 48 ? 48 : len); byte++) {
284 data = msgs[i].buf[k+byte];
285 outb(data, dm_io_mem(DM1105_I2CDAT + byte + 2));
286 }
287 outb(0x82 + (len > 48 ? 48 : len), dm_io_mem(DM1105_I2CCTR));
288 for (j = 0; j < 25; j++) {
289 mdelay(10);
290 status = inb(dm_io_mem(DM1105_I2CSTS));
291 if ((status & 0xc0) == 0x40)
292 break;
293 }
294
295 if (j >= 25)
296 return -1;
297
298 k += 48;
299 len -= 48;
300 } while (len > 0);
301 } else {
302 /* write bytes */
303 outb(msgs[i].addr<<1, dm_io_mem(DM1105_I2CDAT));
304 for (byte = 0; byte < msgs[i].len; byte++) {
305 data = msgs[i].buf[byte];
306 outb(data, dm_io_mem(DM1105_I2CDAT + byte + 1));
307 }
308 outb(0x81 + msgs[i].len, dm_io_mem(DM1105_I2CCTR));
309 for (j = 0; j < 25; j++) {
310 mdelay(10);
311 status = inb(dm_io_mem(DM1105_I2CSTS));
312 if ((status & 0xc0) == 0x40)
313 break;
314 }
315
316 if (j >= 25)
317 return -1;
318 }
319 }
320 }
321 return num;
322 err:
323 return rc;
324}
325
326static u32 functionality(struct i2c_adapter *adap)
327{
328 return I2C_FUNC_I2C;
329}
330
331static struct i2c_algorithm dm1105_algo = {
332 .master_xfer = dm1105_i2c_xfer,
333 .functionality = functionality,
334};
335
336static inline struct dm1105dvb *feed_to_dm1105dvb(struct dvb_demux_feed *feed)
337{
338 return container_of(feed->demux, struct dm1105dvb, demux);
339}
340
341static inline struct dm1105dvb *frontend_to_dm1105dvb(struct dvb_frontend *fe)
342{
343 return container_of(fe->dvb, struct dm1105dvb, dvb_adapter);
344}
345
346static int dm1105dvb_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
347{
348 struct dm1105dvb *dm1105dvb = frontend_to_dm1105dvb(fe);
349
350 if (voltage == SEC_VOLTAGE_18) {
351 outl(DM1105_LNB_MASK, dm_io_mem(DM1105_GPIOCTR));
352 outl(DM1105_LNB_18V, dm_io_mem(DM1105_GPIOVAL));
353 } else {
354 /*LNB ON-13V by default!*/
355 outl(DM1105_LNB_MASK, dm_io_mem(DM1105_GPIOCTR));
356 outl(DM1105_LNB_13V, dm_io_mem(DM1105_GPIOVAL));
357 }
358
359 return 0;
360}
361
362static void dm1105dvb_set_dma_addr(struct dm1105dvb *dm1105dvb)
363{
364 outl(cpu_to_le32(dm1105dvb->dma_addr), dm_io_mem(DM1105_STADR));
365}
366
367static int __devinit dm1105dvb_dma_map(struct dm1105dvb *dm1105dvb)
368{
369 dm1105dvb->ts_buf = pci_alloc_consistent(dm1105dvb->pdev, 6*DM1105_DMA_BYTES, &dm1105dvb->dma_addr);
370
371 return pci_dma_mapping_error(dm1105dvb->pdev, dm1105dvb->dma_addr);
372}
373
374static void dm1105dvb_dma_unmap(struct dm1105dvb *dm1105dvb)
375{
376 pci_free_consistent(dm1105dvb->pdev, 6*DM1105_DMA_BYTES, dm1105dvb->ts_buf, dm1105dvb->dma_addr);
377}
378
379static void __devinit dm1105dvb_enable_irqs(struct dm1105dvb *dm1105dvb)
380{
381 outb(INTMAK_ALLMASK, dm_io_mem(DM1105_INTMAK));
382 outb(1, dm_io_mem(DM1105_CR));
383}
384
385static void dm1105dvb_disable_irqs(struct dm1105dvb *dm1105dvb)
386{
387 outb(INTMAK_IRM, dm_io_mem(DM1105_INTMAK));
388 outb(0, dm_io_mem(DM1105_CR));
389}
390
391static int dm1105dvb_start_feed(struct dvb_demux_feed *f)
392{
393 struct dm1105dvb *dm1105dvb = feed_to_dm1105dvb(f);
394
395 if (dm1105dvb->full_ts_users++ == 0)
396 dm1105dvb_enable_irqs(dm1105dvb);
397
398 return 0;
399}
400
401static int dm1105dvb_stop_feed(struct dvb_demux_feed *f)
402{
403 struct dm1105dvb *dm1105dvb = feed_to_dm1105dvb(f);
404
405 if (--dm1105dvb->full_ts_users == 0)
406 dm1105dvb_disable_irqs(dm1105dvb);
407
408 return 0;
409}
410
411/* ir tasklet */
412static void dm1105_emit_key(unsigned long parm)
413{
414 struct infrared *ir = (struct infrared *) parm;
415 u32 ircom = ir->ir_command;
416 u8 data;
417 u16 keycode;
418
419 data = (ircom >> 8) & 0x7f;
420
421 input_event(ir->input_dev, EV_MSC, MSC_RAW, (0x0000f8 << 16) | data);
422 input_event(ir->input_dev, EV_MSC, MSC_SCAN, data);
423 keycode = ir->key_map[data];
424
425 if (!keycode)
426 return;
427
428 input_event(ir->input_dev, EV_KEY, keycode, 1);
429 input_sync(ir->input_dev);
430 input_event(ir->input_dev, EV_KEY, keycode, 0);
431 input_sync(ir->input_dev);
432
433}
434
435static irqreturn_t dm1105dvb_irq(int irq, void *dev_id)
436{
437 struct dm1105dvb *dm1105dvb = dev_id;
438 unsigned int piece;
439 unsigned int nbpackets;
440 u32 command;
441 u32 nextwrp;
442 u32 oldwrp;
443
444 /* Read-Write INSTS Ack's Interrupt for DM1105 chip 16.03.2008 */
445 unsigned int intsts = inb(dm_io_mem(DM1105_INTSTS));
446 outb(intsts, dm_io_mem(DM1105_INTSTS));
447
448 switch (intsts) {
449 case INTSTS_TSIRQ:
450 case (INTSTS_TSIRQ | INTSTS_IR):
451 nextwrp = inl(dm_io_mem(DM1105_WRP)) -
452 inl(dm_io_mem(DM1105_STADR)) ;
453 oldwrp = dm1105dvb->wrp;
454 spin_lock(&dm1105dvb->lock);
455 if (!((dm1105dvb->ts_buf[oldwrp] == 0x47) &&
456 (dm1105dvb->ts_buf[oldwrp + 188] == 0x47) &&
457 (dm1105dvb->ts_buf[oldwrp + 188 * 2] == 0x47))) {
458 dm1105dvb->PacketErrorCount++;
459 /* bad packet found */
460 if ((dm1105dvb->PacketErrorCount >= 2) &&
461 (dm1105dvb->dmarst == 0)) {
462 outb(1, dm_io_mem(DM1105_RST));
463 dm1105dvb->wrp = 0;
464 dm1105dvb->PacketErrorCount = 0;
465 dm1105dvb->dmarst = 0;
466 spin_unlock(&dm1105dvb->lock);
467 return IRQ_HANDLED;
468 }
469 }
470 if (nextwrp < oldwrp) {
471 piece = dm1105dvb->buffer_size - oldwrp;
472 memcpy(dm1105dvb->ts_buf + dm1105dvb->buffer_size, dm1105dvb->ts_buf, nextwrp);
473 nbpackets = (piece + nextwrp)/188;
474 } else {
475 nbpackets = (nextwrp - oldwrp)/188;
476 }
477 dvb_dmx_swfilter_packets(&dm1105dvb->demux, &dm1105dvb->ts_buf[oldwrp], nbpackets);
478 dm1105dvb->wrp = nextwrp;
479 spin_unlock(&dm1105dvb->lock);
480 break;
481 case INTSTS_IR:
482 command = inl(dm_io_mem(DM1105_IRCODE));
483 if (ir_debug)
484 printk("dm1105: received byte 0x%04x\n", command);
485
486 dm1105dvb->ir.ir_command = command;
487 tasklet_schedule(&dm1105dvb->ir.ir_tasklet);
488 break;
489 }
490 return IRQ_HANDLED;
491
492
493}
494
495/* register with input layer */
496static void input_register_keys(struct infrared *ir)
497{
498 int i;
499
500 memset(ir->input_dev->keybit, 0, sizeof(ir->input_dev->keybit));
501
502 for (i = 0; i < ARRAY_SIZE(ir->key_map); i++)
503 set_bit(ir->key_map[i], ir->input_dev->keybit);
504
505 ir->input_dev->keycode = ir->key_map;
506 ir->input_dev->keycodesize = sizeof(ir->key_map[0]);
507 ir->input_dev->keycodemax = ARRAY_SIZE(ir->key_map);
508}
509
510int __devinit dm1105_ir_init(struct dm1105dvb *dm1105)
511{
512 struct input_dev *input_dev;
513 int err;
514
515 dm1105dvb_local = dm1105;
516
517 input_dev = input_allocate_device();
518 if (!input_dev)
519 return -ENOMEM;
520
521 dm1105->ir.input_dev = input_dev;
522 snprintf(dm1105->ir.input_phys, sizeof(dm1105->ir.input_phys),
523 "pci-%s/ir0", pci_name(dm1105->pdev));
524
525 input_dev->evbit[0] = BIT(EV_KEY);
526 input_dev->name = "DVB on-card IR receiver";
527
528 input_dev->phys = dm1105->ir.input_phys;
529 input_dev->id.bustype = BUS_PCI;
530 input_dev->id.version = 2;
531 if (dm1105->pdev->subsystem_vendor) {
532 input_dev->id.vendor = dm1105->pdev->subsystem_vendor;
533 input_dev->id.product = dm1105->pdev->subsystem_device;
534 } else {
535 input_dev->id.vendor = dm1105->pdev->vendor;
536 input_dev->id.product = dm1105->pdev->device;
537 }
538 input_dev->dev.parent = &dm1105->pdev->dev;
539 /* initial keymap */
540 memcpy(dm1105->ir.key_map, ir_codes_dm1105_nec, sizeof dm1105->ir.key_map);
541 input_register_keys(&dm1105->ir);
542 err = input_register_device(input_dev);
543 if (err) {
544 input_free_device(input_dev);
545 return err;
546 }
547
548 tasklet_init(&dm1105->ir.ir_tasklet, dm1105_emit_key, (unsigned long) &dm1105->ir);
549
550 return 0;
551}
552
553
554void __devexit dm1105_ir_exit(struct dm1105dvb *dm1105)
555{
556 tasklet_kill(&dm1105->ir.ir_tasklet);
557 input_unregister_device(dm1105->ir.input_dev);
558
559}
560
561static int __devinit dm1105dvb_hw_init(struct dm1105dvb *dm1105dvb)
562{
563 dm1105dvb_disable_irqs(dm1105dvb);
564
565 outb(0, dm_io_mem(DM1105_HOST_CTR));
566
567 /*DATALEN 188,*/
568 outb(188, dm_io_mem(DM1105_DTALENTH));
569 /*TS_STRT TS_VALP MSBFIRST TS_MODE ALPAS TSPES*/
570 outw(0xc10a, dm_io_mem(DM1105_TSCTR));
571
572 /* map DMA and set address */
573 dm1105dvb_dma_map(dm1105dvb);
574 dm1105dvb_set_dma_addr(dm1105dvb);
575 /* big buffer */
576 outl(5*DM1105_DMA_BYTES, dm_io_mem(DM1105_RLEN));
577 outb(47, dm_io_mem(DM1105_INTCNT));
578
579 /* IR NEC mode enable */
580 outb((DM1105_IR_EN | DM1105_SYS_CHK), dm_io_mem(DM1105_IRCTR));
581 outb(0, dm_io_mem(DM1105_IRMODE));
582 outw(0, dm_io_mem(DM1105_SYSTEMCODE));
583
584 return 0;
585}
586
587static void dm1105dvb_hw_exit(struct dm1105dvb *dm1105dvb)
588{
589 dm1105dvb_disable_irqs(dm1105dvb);
590
591 /* IR disable */
592 outb(0, dm_io_mem(DM1105_IRCTR));
593 outb(INTMAK_NONEMASK, dm_io_mem(DM1105_INTMAK));
594
595 dm1105dvb_dma_unmap(dm1105dvb);
596}
597
598static struct stv0288_config earda_config = {
599 .demod_address = 0x68,
600 .min_delay_ms = 100,
601};
602
603static struct si21xx_config serit_config = {
604 .demod_address = 0x68,
605 .min_delay_ms = 100,
606
607};
608
609static struct cx24116_config serit_sp2633_config = {
610 .demod_address = 0x55,
611};
612
613static int __devinit frontend_init(struct dm1105dvb *dm1105dvb)
614{
615 int ret;
616
617 switch (dm1105dvb->pdev->subsystem_device) {
618 case PCI_DEVICE_ID_DW2002:
619 dm1105dvb->fe = dvb_attach(
620 stv0299_attach, &sharp_z0194a_config,
621 &dm1105dvb->i2c_adap);
622
623 if (dm1105dvb->fe) {
624 dm1105dvb->fe->ops.set_voltage =
625 dm1105dvb_set_voltage;
626 dvb_attach(dvb_pll_attach, dm1105dvb->fe, 0x60,
627 &dm1105dvb->i2c_adap, DVB_PLL_OPERA1);
628 }
629
630 if (!dm1105dvb->fe) {
631 dm1105dvb->fe = dvb_attach(
632 stv0288_attach, &earda_config,
633 &dm1105dvb->i2c_adap);
634 if (dm1105dvb->fe) {
635 dm1105dvb->fe->ops.set_voltage =
636 dm1105dvb_set_voltage;
637 dvb_attach(stb6000_attach, dm1105dvb->fe, 0x61,
638 &dm1105dvb->i2c_adap);
639 }
640 }
641
642 if (!dm1105dvb->fe) {
643 dm1105dvb->fe = dvb_attach(
644 si21xx_attach, &serit_config,
645 &dm1105dvb->i2c_adap);
646 if (dm1105dvb->fe)
647 dm1105dvb->fe->ops.set_voltage =
648 dm1105dvb_set_voltage;
649 }
650 break;
651 case PCI_DEVICE_ID_DW2004:
652 dm1105dvb->fe = dvb_attach(
653 cx24116_attach, &serit_sp2633_config,
654 &dm1105dvb->i2c_adap);
655 if (dm1105dvb->fe)
656 dm1105dvb->fe->ops.set_voltage = dm1105dvb_set_voltage;
657 break;
658 }
659
660 if (!dm1105dvb->fe) {
661 dev_err(&dm1105dvb->pdev->dev, "could not attach frontend\n");
662 return -ENODEV;
663 }
664
665 ret = dvb_register_frontend(&dm1105dvb->dvb_adapter, dm1105dvb->fe);
666 if (ret < 0) {
667 if (dm1105dvb->fe->ops.release)
668 dm1105dvb->fe->ops.release(dm1105dvb->fe);
669 dm1105dvb->fe = NULL;
670 return ret;
671 }
672
673 return 0;
674}
675
676static void __devinit dm1105dvb_read_mac(struct dm1105dvb *dm1105dvb, u8 *mac)
677{
678 static u8 command[1] = { 0x28 };
679
680 struct i2c_msg msg[] = {
681 { .addr = IIC_24C01_addr >> 1, .flags = 0,
682 .buf = command, .len = 1 },
683 { .addr = IIC_24C01_addr >> 1, .flags = I2C_M_RD,
684 .buf = mac, .len = 6 },
685 };
686
687 dm1105_i2c_xfer(&dm1105dvb->i2c_adap, msg , 2);
688 dev_info(&dm1105dvb->pdev->dev, "MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
689 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
690}
691
692static int __devinit dm1105_probe(struct pci_dev *pdev,
693 const struct pci_device_id *ent)
694{
695 struct dm1105dvb *dm1105dvb;
696 struct dvb_adapter *dvb_adapter;
697 struct dvb_demux *dvbdemux;
698 struct dmx_demux *dmx;
699 int ret = -ENOMEM;
700
701 dm1105dvb = kzalloc(sizeof(struct dm1105dvb), GFP_KERNEL);
702 if (!dm1105dvb)
703 goto out;
704
705 dm1105dvb->pdev = pdev;
706 dm1105dvb->buffer_size = 5 * DM1105_DMA_BYTES;
707 dm1105dvb->PacketErrorCount = 0;
708 dm1105dvb->dmarst = 0;
709
710 ret = pci_enable_device(pdev);
711 if (ret < 0)
712 goto err_kfree;
713
714 ret = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
715 if (ret < 0)
716 goto err_pci_disable_device;
717
718 pci_set_master(pdev);
719
720 ret = pci_request_regions(pdev, DRIVER_NAME);
721 if (ret < 0)
722 goto err_pci_disable_device;
723
724 dm1105dvb->io_mem = pci_iomap(pdev, 0, pci_resource_len(pdev, 0));
725 if (!dm1105dvb->io_mem) {
726 ret = -EIO;
727 goto err_pci_release_regions;
728 }
729
730 spin_lock_init(&dm1105dvb->lock);
731 pci_set_drvdata(pdev, dm1105dvb);
732
733 ret = request_irq(pdev->irq, dm1105dvb_irq, IRQF_SHARED, DRIVER_NAME, dm1105dvb);
734 if (ret < 0)
735 goto err_pci_iounmap;
736
737 ret = dm1105dvb_hw_init(dm1105dvb);
738 if (ret < 0)
739 goto err_free_irq;
740
741 /* i2c */
742 i2c_set_adapdata(&dm1105dvb->i2c_adap, dm1105dvb);
743 strcpy(dm1105dvb->i2c_adap.name, DRIVER_NAME);
744 dm1105dvb->i2c_adap.owner = THIS_MODULE;
745 dm1105dvb->i2c_adap.class = I2C_CLASS_TV_DIGITAL;
746 dm1105dvb->i2c_adap.dev.parent = &pdev->dev;
747 dm1105dvb->i2c_adap.algo = &dm1105_algo;
748 dm1105dvb->i2c_adap.algo_data = dm1105dvb;
749 ret = i2c_add_adapter(&dm1105dvb->i2c_adap);
750
751 if (ret < 0)
752 goto err_dm1105dvb_hw_exit;
753
754 /* dvb */
755 ret = dvb_register_adapter(&dm1105dvb->dvb_adapter, DRIVER_NAME,
756 THIS_MODULE, &pdev->dev, adapter_nr);
757 if (ret < 0)
758 goto err_i2c_del_adapter;
759
760 dvb_adapter = &dm1105dvb->dvb_adapter;
761
762 dm1105dvb_read_mac(dm1105dvb, dvb_adapter->proposed_mac);
763
764 dvbdemux = &dm1105dvb->demux;
765 dvbdemux->filternum = 256;
766 dvbdemux->feednum = 256;
767 dvbdemux->start_feed = dm1105dvb_start_feed;
768 dvbdemux->stop_feed = dm1105dvb_stop_feed;
769 dvbdemux->dmx.capabilities = (DMX_TS_FILTERING |
770 DMX_SECTION_FILTERING | DMX_MEMORY_BASED_FILTERING);
771 ret = dvb_dmx_init(dvbdemux);
772 if (ret < 0)
773 goto err_dvb_unregister_adapter;
774
775 dmx = &dvbdemux->dmx;
776 dm1105dvb->dmxdev.filternum = 256;
777 dm1105dvb->dmxdev.demux = dmx;
778 dm1105dvb->dmxdev.capabilities = 0;
779
780 ret = dvb_dmxdev_init(&dm1105dvb->dmxdev, dvb_adapter);
781 if (ret < 0)
782 goto err_dvb_dmx_release;
783
784 dm1105dvb->hw_frontend.source = DMX_FRONTEND_0;
785
786 ret = dmx->add_frontend(dmx, &dm1105dvb->hw_frontend);
787 if (ret < 0)
788 goto err_dvb_dmxdev_release;
789
790 dm1105dvb->mem_frontend.source = DMX_MEMORY_FE;
791
792 ret = dmx->add_frontend(dmx, &dm1105dvb->mem_frontend);
793 if (ret < 0)
794 goto err_remove_hw_frontend;
795
796 ret = dmx->connect_frontend(dmx, &dm1105dvb->hw_frontend);
797 if (ret < 0)
798 goto err_remove_mem_frontend;
799
800 ret = frontend_init(dm1105dvb);
801 if (ret < 0)
802 goto err_disconnect_frontend;
803
804 dvb_net_init(dvb_adapter, &dm1105dvb->dvbnet, dmx);
805 dm1105_ir_init(dm1105dvb);
806out:
807 return ret;
808
809err_disconnect_frontend:
810 dmx->disconnect_frontend(dmx);
811err_remove_mem_frontend:
812 dmx->remove_frontend(dmx, &dm1105dvb->mem_frontend);
813err_remove_hw_frontend:
814 dmx->remove_frontend(dmx, &dm1105dvb->hw_frontend);
815err_dvb_dmxdev_release:
816 dvb_dmxdev_release(&dm1105dvb->dmxdev);
817err_dvb_dmx_release:
818 dvb_dmx_release(dvbdemux);
819err_dvb_unregister_adapter:
820 dvb_unregister_adapter(dvb_adapter);
821err_i2c_del_adapter:
822 i2c_del_adapter(&dm1105dvb->i2c_adap);
823err_dm1105dvb_hw_exit:
824 dm1105dvb_hw_exit(dm1105dvb);
825err_free_irq:
826 free_irq(pdev->irq, dm1105dvb);
827err_pci_iounmap:
828 pci_iounmap(pdev, dm1105dvb->io_mem);
829err_pci_release_regions:
830 pci_release_regions(pdev);
831err_pci_disable_device:
832 pci_disable_device(pdev);
833err_kfree:
834 pci_set_drvdata(pdev, NULL);
835 kfree(dm1105dvb);
836 goto out;
837}
838
839static void __devexit dm1105_remove(struct pci_dev *pdev)
840{
841 struct dm1105dvb *dm1105dvb = pci_get_drvdata(pdev);
842 struct dvb_adapter *dvb_adapter = &dm1105dvb->dvb_adapter;
843 struct dvb_demux *dvbdemux = &dm1105dvb->demux;
844 struct dmx_demux *dmx = &dvbdemux->dmx;
845
846 dm1105_ir_exit(dm1105dvb);
847 dmx->close(dmx);
848 dvb_net_release(&dm1105dvb->dvbnet);
849 if (dm1105dvb->fe)
850 dvb_unregister_frontend(dm1105dvb->fe);
851
852 dmx->disconnect_frontend(dmx);
853 dmx->remove_frontend(dmx, &dm1105dvb->mem_frontend);
854 dmx->remove_frontend(dmx, &dm1105dvb->hw_frontend);
855 dvb_dmxdev_release(&dm1105dvb->dmxdev);
856 dvb_dmx_release(dvbdemux);
857 dvb_unregister_adapter(dvb_adapter);
858 if (&dm1105dvb->i2c_adap)
859 i2c_del_adapter(&dm1105dvb->i2c_adap);
860
861 dm1105dvb_hw_exit(dm1105dvb);
862 synchronize_irq(pdev->irq);
863 free_irq(pdev->irq, dm1105dvb);
864 pci_iounmap(pdev, dm1105dvb->io_mem);
865 pci_release_regions(pdev);
866 pci_disable_device(pdev);
867 pci_set_drvdata(pdev, NULL);
868 kfree(dm1105dvb);
869}
870
871static struct pci_device_id dm1105_id_table[] __devinitdata = {
872 {
873 .vendor = PCI_VENDOR_ID_TRIGEM,
874 .device = PCI_DEVICE_ID_DM1105,
875 .subvendor = PCI_ANY_ID,
876 .subdevice = PCI_DEVICE_ID_DW2002,
877 }, {
878 .vendor = PCI_VENDOR_ID_TRIGEM,
879 .device = PCI_DEVICE_ID_DM1105,
880 .subvendor = PCI_ANY_ID,
881 .subdevice = PCI_DEVICE_ID_DW2004,
882 }, {
883 /* empty */
884 },
885};
886
887MODULE_DEVICE_TABLE(pci, dm1105_id_table);
888
889static struct pci_driver dm1105_driver = {
890 .name = DRIVER_NAME,
891 .id_table = dm1105_id_table,
892 .probe = dm1105_probe,
893 .remove = __devexit_p(dm1105_remove),
894};
895
896static int __init dm1105_init(void)
897{
898 return pci_register_driver(&dm1105_driver);
899}
900
901static void __exit dm1105_exit(void)
902{
903 pci_unregister_driver(&dm1105_driver);
904}
905
906module_init(dm1105_init);
907module_exit(dm1105_exit);
908
909MODULE_AUTHOR("Igor M. Liplianin <liplianin@me.by>");
910MODULE_DESCRIPTION("SDMC DM1105 DVB driver");
911MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c
index 3526e3ee9487..f170e822fadc 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -40,6 +40,7 @@
40 40
41#include "dvb_frontend.h" 41#include "dvb_frontend.h"
42#include "dvbdev.h" 42#include "dvbdev.h"
43#include <linux/dvb/version.h>
43 44
44static int dvb_frontend_debug; 45static int dvb_frontend_debug;
45static int dvb_shutdown_timeout; 46static int dvb_shutdown_timeout;
@@ -755,6 +756,539 @@ static int dvb_frontend_check_parameters(struct dvb_frontend *fe,
755 return 0; 756 return 0;
756} 757}
757 758
759struct dtv_cmds_h dtv_cmds[] = {
760 [DTV_TUNE] = {
761 .name = "DTV_TUNE",
762 .cmd = DTV_TUNE,
763 .set = 1,
764 },
765 [DTV_CLEAR] = {
766 .name = "DTV_CLEAR",
767 .cmd = DTV_CLEAR,
768 .set = 1,
769 },
770
771 /* Set */
772 [DTV_FREQUENCY] = {
773 .name = "DTV_FREQUENCY",
774 .cmd = DTV_FREQUENCY,
775 .set = 1,
776 },
777 [DTV_BANDWIDTH_HZ] = {
778 .name = "DTV_BANDWIDTH_HZ",
779 .cmd = DTV_BANDWIDTH_HZ,
780 .set = 1,
781 },
782 [DTV_MODULATION] = {
783 .name = "DTV_MODULATION",
784 .cmd = DTV_MODULATION,
785 .set = 1,
786 },
787 [DTV_INVERSION] = {
788 .name = "DTV_INVERSION",
789 .cmd = DTV_INVERSION,
790 .set = 1,
791 },
792 [DTV_DISEQC_MASTER] = {
793 .name = "DTV_DISEQC_MASTER",
794 .cmd = DTV_DISEQC_MASTER,
795 .set = 1,
796 .buffer = 1,
797 },
798 [DTV_SYMBOL_RATE] = {
799 .name = "DTV_SYMBOL_RATE",
800 .cmd = DTV_SYMBOL_RATE,
801 .set = 1,
802 },
803 [DTV_INNER_FEC] = {
804 .name = "DTV_INNER_FEC",
805 .cmd = DTV_INNER_FEC,
806 .set = 1,
807 },
808 [DTV_VOLTAGE] = {
809 .name = "DTV_VOLTAGE",
810 .cmd = DTV_VOLTAGE,
811 .set = 1,
812 },
813 [DTV_TONE] = {
814 .name = "DTV_TONE",
815 .cmd = DTV_TONE,
816 .set = 1,
817 },
818 [DTV_PILOT] = {
819 .name = "DTV_PILOT",
820 .cmd = DTV_PILOT,
821 .set = 1,
822 },
823 [DTV_ROLLOFF] = {
824 .name = "DTV_ROLLOFF",
825 .cmd = DTV_ROLLOFF,
826 .set = 1,
827 },
828 [DTV_DELIVERY_SYSTEM] = {
829 .name = "DTV_DELIVERY_SYSTEM",
830 .cmd = DTV_DELIVERY_SYSTEM,
831 .set = 1,
832 },
833 [DTV_HIERARCHY] = {
834 .name = "DTV_HIERARCHY",
835 .cmd = DTV_HIERARCHY,
836 .set = 1,
837 },
838 [DTV_CODE_RATE_HP] = {
839 .name = "DTV_CODE_RATE_HP",
840 .cmd = DTV_CODE_RATE_HP,
841 .set = 1,
842 },
843 [DTV_CODE_RATE_LP] = {
844 .name = "DTV_CODE_RATE_LP",
845 .cmd = DTV_CODE_RATE_LP,
846 .set = 1,
847 },
848 [DTV_GUARD_INTERVAL] = {
849 .name = "DTV_GUARD_INTERVAL",
850 .cmd = DTV_GUARD_INTERVAL,
851 .set = 1,
852 },
853 [DTV_TRANSMISSION_MODE] = {
854 .name = "DTV_TRANSMISSION_MODE",
855 .cmd = DTV_TRANSMISSION_MODE,
856 .set = 1,
857 },
858 /* Get */
859 [DTV_DISEQC_SLAVE_REPLY] = {
860 .name = "DTV_DISEQC_SLAVE_REPLY",
861 .cmd = DTV_DISEQC_SLAVE_REPLY,
862 .set = 0,
863 .buffer = 1,
864 },
865 [DTV_API_VERSION] = {
866 .name = "DTV_API_VERSION",
867 .cmd = DTV_API_VERSION,
868 .set = 0,
869 },
870 [DTV_CODE_RATE_HP] = {
871 .name = "DTV_CODE_RATE_HP",
872 .cmd = DTV_CODE_RATE_HP,
873 .set = 0,
874 },
875 [DTV_CODE_RATE_LP] = {
876 .name = "DTV_CODE_RATE_LP",
877 .cmd = DTV_CODE_RATE_LP,
878 .set = 0,
879 },
880 [DTV_GUARD_INTERVAL] = {
881 .name = "DTV_GUARD_INTERVAL",
882 .cmd = DTV_GUARD_INTERVAL,
883 .set = 0,
884 },
885 [DTV_TRANSMISSION_MODE] = {
886 .name = "DTV_TRANSMISSION_MODE",
887 .cmd = DTV_TRANSMISSION_MODE,
888 .set = 0,
889 },
890 [DTV_HIERARCHY] = {
891 .name = "DTV_HIERARCHY",
892 .cmd = DTV_HIERARCHY,
893 .set = 0,
894 },
895};
896
897void dtv_property_dump(struct dtv_property *tvp)
898{
899 int i;
900
901 if (tvp->cmd <= 0 || tvp->cmd > DTV_MAX_COMMAND) {
902 printk("%s: tvp.cmd = 0x%08x (undefined/unknown/invalid)\n",
903 __func__, tvp->cmd);
904 return;
905 }
906
907 printk("%s() tvp.cmd = 0x%08x (%s)\n"
908 ,__FUNCTION__
909 ,tvp->cmd
910 ,dtv_cmds[ tvp->cmd ].name);
911
912 if(dtv_cmds[ tvp->cmd ].buffer) {
913
914 printk("%s() tvp.u.buffer.len = 0x%02x\n"
915 ,__FUNCTION__
916 ,tvp->u.buffer.len);
917
918 for(i = 0; i < tvp->u.buffer.len; i++)
919 printk("%s() tvp.u.buffer.data[0x%02x] = 0x%02x\n"
920 ,__FUNCTION__
921 ,i
922 ,tvp->u.buffer.data[i]);
923
924 } else
925 printk("%s() tvp.u.data = 0x%08x\n", __FUNCTION__, tvp->u.data);
926}
927
928int is_legacy_delivery_system(fe_delivery_system_t s)
929{
930 if((s == SYS_UNDEFINED) || (s == SYS_DVBC_ANNEX_AC) ||
931 (s == SYS_DVBC_ANNEX_B) || (s == SYS_DVBT) || (s == SYS_DVBS))
932 return 1;
933
934 return 0;
935}
936
937/* Synchronise the legacy tuning parameters into the cache, so that demodulator
938 * drivers can use a single set_frontend tuning function, regardless of whether
939 * it's being used for the legacy or new API, reducing code and complexity.
940 */
941void dtv_property_cache_sync(struct dvb_frontend *fe, struct dvb_frontend_parameters *p)
942{
943 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
944
945 printk("%s()\n", __FUNCTION__);
946
947 c->frequency = p->frequency;
948 c->inversion = p->inversion;
949
950 switch (fe->ops.info.type) {
951 case FE_QPSK:
952 c->modulation = QPSK; /* implied for DVB-S in legacy API */
953 c->rolloff = ROLLOFF_35;/* implied for DVB-S */
954 c->symbol_rate = p->u.qpsk.symbol_rate;
955 c->fec_inner = p->u.qpsk.fec_inner;
956 c->delivery_system = SYS_DVBS;
957 break;
958 case FE_QAM:
959 c->symbol_rate = p->u.qam.symbol_rate;
960 c->fec_inner = p->u.qam.fec_inner;
961 c->modulation = p->u.qam.modulation;
962 c->delivery_system = SYS_DVBC_ANNEX_AC;
963 break;
964 case FE_OFDM:
965 if (p->u.ofdm.bandwidth == BANDWIDTH_6_MHZ)
966 c->bandwidth_hz = 6000000;
967 else if (p->u.ofdm.bandwidth == BANDWIDTH_7_MHZ)
968 c->bandwidth_hz = 7000000;
969 else if (p->u.ofdm.bandwidth == BANDWIDTH_8_MHZ)
970 c->bandwidth_hz = 8000000;
971 else
972 /* Including BANDWIDTH_AUTO */
973 c->bandwidth_hz = 0;
974 c->code_rate_HP = p->u.ofdm.code_rate_HP;
975 c->code_rate_LP = p->u.ofdm.code_rate_LP;
976 c->modulation = p->u.ofdm.constellation;
977 c->transmission_mode = p->u.ofdm.transmission_mode;
978 c->guard_interval = p->u.ofdm.guard_interval;
979 c->hierarchy = p->u.ofdm.hierarchy_information;
980 c->delivery_system = SYS_DVBT;
981 break;
982 case FE_ATSC:
983 c->modulation = p->u.vsb.modulation;
984 if ((c->modulation == VSB_8) || (c->modulation == VSB_16))
985 c->delivery_system = SYS_ATSC;
986 else
987 c->delivery_system = SYS_DVBC_ANNEX_B;
988 break;
989 }
990}
991
992/* Ensure the cached values are set correctly in the frontend
993 * legacy tuning structures, for the advanced tuning API.
994 */
995void dtv_property_legacy_params_sync(struct dvb_frontend *fe)
996{
997 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
998 struct dvb_frontend_private *fepriv = fe->frontend_priv;
999 struct dvb_frontend_parameters *p = &fepriv->parameters;
1000
1001 printk("%s()\n", __FUNCTION__);
1002
1003 p->frequency = c->frequency;
1004 p->inversion = c->inversion;
1005
1006 switch (fe->ops.info.type) {
1007 case FE_QPSK:
1008 printk("%s() Preparing QPSK req\n", __FUNCTION__);
1009 p->u.qpsk.symbol_rate = c->symbol_rate;
1010 p->u.qpsk.fec_inner = c->fec_inner;
1011 c->delivery_system = SYS_DVBS;
1012 break;
1013 case FE_QAM:
1014 printk("%s() Preparing QAM req\n", __FUNCTION__);
1015 p->u.qam.symbol_rate = c->symbol_rate;
1016 p->u.qam.fec_inner = c->fec_inner;
1017 p->u.qam.modulation = c->modulation;
1018 c->delivery_system = SYS_DVBC_ANNEX_AC;
1019 break;
1020 case FE_OFDM:
1021 printk("%s() Preparing OFDM req\n", __FUNCTION__);
1022 if (c->bandwidth_hz == 6000000)
1023 p->u.ofdm.bandwidth = BANDWIDTH_6_MHZ;
1024 else if (c->bandwidth_hz == 7000000)
1025 p->u.ofdm.bandwidth = BANDWIDTH_7_MHZ;
1026 else if (c->bandwidth_hz == 8000000)
1027 p->u.ofdm.bandwidth = BANDWIDTH_8_MHZ;
1028 else
1029 p->u.ofdm.bandwidth = BANDWIDTH_AUTO;
1030 p->u.ofdm.code_rate_HP = c->code_rate_HP;
1031 p->u.ofdm.code_rate_LP = c->code_rate_LP;
1032 p->u.ofdm.constellation = c->modulation;
1033 p->u.ofdm.transmission_mode = c->transmission_mode;
1034 p->u.ofdm.guard_interval = c->guard_interval;
1035 p->u.ofdm.hierarchy_information = c->hierarchy;
1036 c->delivery_system = SYS_DVBT;
1037 break;
1038 case FE_ATSC:
1039 printk("%s() Preparing VSB req\n", __FUNCTION__);
1040 p->u.vsb.modulation = c->modulation;
1041 if ((c->modulation == VSB_8) || (c->modulation == VSB_16))
1042 c->delivery_system = SYS_ATSC;
1043 else
1044 c->delivery_system = SYS_DVBC_ANNEX_B;
1045 break;
1046 }
1047}
1048
1049/* Ensure the cached values are set correctly in the frontend
1050 * legacy tuning structures, for the legacy tuning API.
1051 */
1052void dtv_property_adv_params_sync(struct dvb_frontend *fe)
1053{
1054 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
1055 struct dvb_frontend_private *fepriv = fe->frontend_priv;
1056 struct dvb_frontend_parameters *p = &fepriv->parameters;
1057
1058 printk("%s()\n", __FUNCTION__);
1059
1060 p->frequency = c->frequency;
1061 p->inversion = c->inversion;
1062
1063 switch(c->modulation) {
1064 case PSK_8:
1065 case APSK_16:
1066 case QPSK:
1067 p->u.qpsk.symbol_rate = c->symbol_rate;
1068 p->u.qpsk.fec_inner = c->fec_inner;
1069 break;
1070 default:
1071 break;
1072 }
1073
1074 if(c->delivery_system == SYS_ISDBT) {
1075 /* Fake out a generic DVB-T request so we pass validation in the ioctl */
1076 p->frequency = c->frequency;
1077 p->inversion = INVERSION_AUTO;
1078 p->u.ofdm.constellation = QAM_AUTO;
1079 p->u.ofdm.code_rate_HP = FEC_AUTO;
1080 p->u.ofdm.code_rate_LP = FEC_AUTO;
1081 p->u.ofdm.bandwidth = BANDWIDTH_AUTO;
1082 p->u.ofdm.transmission_mode = TRANSMISSION_MODE_AUTO;
1083 p->u.ofdm.guard_interval = GUARD_INTERVAL_AUTO;
1084 p->u.ofdm.hierarchy_information = HIERARCHY_AUTO;
1085 }
1086}
1087
1088void dtv_property_cache_submit(struct dvb_frontend *fe)
1089{
1090 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
1091
1092 printk("%s()\n", __FUNCTION__);
1093
1094 /* For legacy delivery systems we don't need the delivery_system to
1095 * be specified, but we populate the older structures from the cache
1096 * so we can call set_frontend on older drivers.
1097 */
1098 if(is_legacy_delivery_system(c->delivery_system)) {
1099
1100 printk("%s() legacy, modulation = %d\n", __FUNCTION__, c->modulation);
1101 dtv_property_legacy_params_sync(fe);
1102
1103 } else {
1104 printk("%s() adv, modulation = %d\n", __FUNCTION__, c->modulation);
1105
1106 /* For advanced delivery systems / modulation types ...
1107 * we seed the lecacy dvb_frontend_parameters structure
1108 * so that the sanity checking code later in the IOCTL processing
1109 * can validate our basic frequency ranges, symbolrates, modulation
1110 * etc.
1111 */
1112 dtv_property_adv_params_sync(fe);
1113 }
1114}
1115
1116static int dvb_frontend_ioctl_legacy(struct inode *inode, struct file *file,
1117 unsigned int cmd, void *parg);
1118static int dvb_frontend_ioctl_properties(struct inode *inode, struct file *file,
1119 unsigned int cmd, void *parg);
1120
1121int dtv_property_process_get(struct dvb_frontend *fe, struct dtv_property *tvp,
1122 struct inode *inode, struct file *file)
1123{
1124 int r = 0;
1125
1126 printk("%s()\n", __FUNCTION__);
1127
1128 dtv_property_dump(tvp);
1129
1130 /* Allow the frontend to validate incoming properties */
1131 if (fe->ops.get_property)
1132 r = fe->ops.get_property(fe, tvp);
1133
1134 if (r < 0)
1135 return r;
1136
1137 switch(tvp->cmd) {
1138 case DTV_FREQUENCY:
1139 tvp->u.data = fe->dtv_property_cache.frequency;
1140 break;
1141 case DTV_MODULATION:
1142 tvp->u.data = fe->dtv_property_cache.modulation;
1143 break;
1144 case DTV_BANDWIDTH_HZ:
1145 tvp->u.data = fe->dtv_property_cache.bandwidth_hz;
1146 break;
1147 case DTV_INVERSION:
1148 tvp->u.data = fe->dtv_property_cache.inversion;
1149 break;
1150 case DTV_SYMBOL_RATE:
1151 tvp->u.data = fe->dtv_property_cache.symbol_rate;
1152 break;
1153 case DTV_INNER_FEC:
1154 tvp->u.data = fe->dtv_property_cache.fec_inner;
1155 break;
1156 case DTV_PILOT:
1157 tvp->u.data = fe->dtv_property_cache.pilot;
1158 break;
1159 case DTV_ROLLOFF:
1160 tvp->u.data = fe->dtv_property_cache.rolloff;
1161 break;
1162 case DTV_DELIVERY_SYSTEM:
1163 tvp->u.data = fe->dtv_property_cache.delivery_system;
1164 break;
1165 case DTV_VOLTAGE:
1166 tvp->u.data = fe->dtv_property_cache.voltage;
1167 break;
1168 case DTV_TONE:
1169 tvp->u.data = fe->dtv_property_cache.sectone;
1170 break;
1171 case DTV_API_VERSION:
1172 tvp->u.data = (DVB_API_VERSION << 8) | DVB_API_VERSION_MINOR;
1173 break;
1174 case DTV_CODE_RATE_HP:
1175 tvp->u.data = fe->dtv_property_cache.code_rate_HP;
1176 break;
1177 case DTV_CODE_RATE_LP:
1178 tvp->u.data = fe->dtv_property_cache.code_rate_LP;
1179 break;
1180 case DTV_GUARD_INTERVAL:
1181 tvp->u.data = fe->dtv_property_cache.guard_interval;
1182 break;
1183 case DTV_TRANSMISSION_MODE:
1184 tvp->u.data = fe->dtv_property_cache.transmission_mode;
1185 break;
1186 case DTV_HIERARCHY:
1187 tvp->u.data = fe->dtv_property_cache.hierarchy;
1188 break;
1189 default:
1190 r = -1;
1191 }
1192
1193 return r;
1194}
1195
1196int dtv_property_process_set(struct dvb_frontend *fe, struct dtv_property *tvp,
1197 struct inode *inode, struct file *file)
1198{
1199 int r = 0;
1200 struct dvb_frontend_private *fepriv = fe->frontend_priv;
1201 printk("%s()\n", __FUNCTION__);
1202 dtv_property_dump(tvp);
1203
1204 /* Allow the frontend to validate incoming properties */
1205 if (fe->ops.set_property)
1206 r = fe->ops.set_property(fe, tvp);
1207
1208 if (r < 0)
1209 return r;
1210
1211 switch(tvp->cmd) {
1212 case DTV_CLEAR:
1213 /* Reset a cache of data specific to the frontend here. This does
1214 * not effect hardware.
1215 */
1216 printk("%s() Flushing property cache\n", __FUNCTION__);
1217 memset(&fe->dtv_property_cache, 0, sizeof(struct dtv_frontend_properties));
1218 fe->dtv_property_cache.state = tvp->cmd;
1219 fe->dtv_property_cache.delivery_system = SYS_UNDEFINED;
1220 break;
1221 case DTV_TUNE:
1222 /* interpret the cache of data, build either a traditional frontend
1223 * tunerequest so we can pass validation in the FE_SET_FRONTEND
1224 * ioctl.
1225 */
1226 fe->dtv_property_cache.state = tvp->cmd;
1227 printk("%s() Finalised property cache\n", __FUNCTION__);
1228 dtv_property_cache_submit(fe);
1229
1230 r |= dvb_frontend_ioctl_legacy(inode, file, FE_SET_FRONTEND,
1231 &fepriv->parameters);
1232 break;
1233 case DTV_FREQUENCY:
1234 fe->dtv_property_cache.frequency = tvp->u.data;
1235 break;
1236 case DTV_MODULATION:
1237 fe->dtv_property_cache.modulation = tvp->u.data;
1238 break;
1239 case DTV_BANDWIDTH_HZ:
1240 fe->dtv_property_cache.bandwidth_hz = tvp->u.data;
1241 break;
1242 case DTV_INVERSION:
1243 fe->dtv_property_cache.inversion = tvp->u.data;
1244 break;
1245 case DTV_SYMBOL_RATE:
1246 fe->dtv_property_cache.symbol_rate = tvp->u.data;
1247 break;
1248 case DTV_INNER_FEC:
1249 fe->dtv_property_cache.fec_inner = tvp->u.data;
1250 break;
1251 case DTV_PILOT:
1252 fe->dtv_property_cache.pilot = tvp->u.data;
1253 break;
1254 case DTV_ROLLOFF:
1255 fe->dtv_property_cache.rolloff = tvp->u.data;
1256 break;
1257 case DTV_DELIVERY_SYSTEM:
1258 fe->dtv_property_cache.delivery_system = tvp->u.data;
1259 break;
1260 case DTV_VOLTAGE:
1261 fe->dtv_property_cache.voltage = tvp->u.data;
1262 r = dvb_frontend_ioctl_legacy(inode, file, FE_SET_VOLTAGE,
1263 (void *)fe->dtv_property_cache.voltage);
1264 break;
1265 case DTV_TONE:
1266 fe->dtv_property_cache.sectone = tvp->u.data;
1267 r = dvb_frontend_ioctl_legacy(inode, file, FE_SET_TONE,
1268 (void *)fe->dtv_property_cache.sectone);
1269 break;
1270 case DTV_CODE_RATE_HP:
1271 fe->dtv_property_cache.code_rate_HP = tvp->u.data;
1272 break;
1273 case DTV_CODE_RATE_LP:
1274 fe->dtv_property_cache.code_rate_LP = tvp->u.data;
1275 break;
1276 case DTV_GUARD_INTERVAL:
1277 fe->dtv_property_cache.guard_interval = tvp->u.data;
1278 break;
1279 case DTV_TRANSMISSION_MODE:
1280 fe->dtv_property_cache.transmission_mode = tvp->u.data;
1281 break;
1282 case DTV_HIERARCHY:
1283 fe->dtv_property_cache.hierarchy = tvp->u.data;
1284 break;
1285 default:
1286 r = -1;
1287 }
1288
1289 return r;
1290}
1291
758static int dvb_frontend_ioctl(struct inode *inode, struct file *file, 1292static int dvb_frontend_ioctl(struct inode *inode, struct file *file,
759 unsigned int cmd, void *parg) 1293 unsigned int cmd, void *parg)
760{ 1294{
@@ -776,6 +1310,116 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file,
776 if (down_interruptible (&fepriv->sem)) 1310 if (down_interruptible (&fepriv->sem))
777 return -ERESTARTSYS; 1311 return -ERESTARTSYS;
778 1312
1313 if ((cmd == FE_SET_PROPERTY) || (cmd == FE_GET_PROPERTY))
1314 err = dvb_frontend_ioctl_properties(inode, file, cmd, parg);
1315 else {
1316 fe->dtv_property_cache.state = DTV_UNDEFINED;
1317 err = dvb_frontend_ioctl_legacy(inode, file, cmd, parg);
1318 }
1319
1320 up(&fepriv->sem);
1321 return err;
1322}
1323
1324static int dvb_frontend_ioctl_properties(struct inode *inode, struct file *file,
1325 unsigned int cmd, void *parg)
1326{
1327 struct dvb_device *dvbdev = file->private_data;
1328 struct dvb_frontend *fe = dvbdev->priv;
1329 int err = 0;
1330
1331 struct dtv_properties *tvps = NULL;
1332 struct dtv_property *tvp = NULL;
1333 int i;
1334
1335 dprintk("%s\n", __func__);
1336
1337 if(cmd == FE_SET_PROPERTY) {
1338 printk("%s() FE_SET_PROPERTY\n", __FUNCTION__);
1339
1340 tvps = (struct dtv_properties __user *)parg;
1341
1342 printk("%s() properties.num = %d\n", __FUNCTION__, tvps->num);
1343 printk("%s() properties.props = %p\n", __FUNCTION__, tvps->props);
1344
1345 /* Put an arbitrary limit on the number of messages that can
1346 * be sent at once */
1347 if ((tvps->num == 0) || (tvps->num > DTV_IOCTL_MAX_MSGS))
1348 return -EINVAL;
1349
1350 tvp = (struct dtv_property *) kmalloc(tvps->num *
1351 sizeof(struct dtv_property), GFP_KERNEL);
1352 if (!tvp) {
1353 err = -ENOMEM;
1354 goto out;
1355 }
1356
1357 if (copy_from_user(tvp, tvps->props, tvps->num * sizeof(struct dtv_property))) {
1358 err = -EFAULT;
1359 goto out;
1360 }
1361
1362 for (i = 0; i < tvps->num; i++) {
1363 (tvp + i)->result = dtv_property_process_set(fe, tvp + i, inode, file);
1364 err |= (tvp + i)->result;
1365 }
1366
1367 if(fe->dtv_property_cache.state == DTV_TUNE) {
1368 printk("%s() Property cache is full, tuning\n", __FUNCTION__);
1369 }
1370
1371 } else
1372 if(cmd == FE_GET_PROPERTY) {
1373 printk("%s() FE_GET_PROPERTY\n", __FUNCTION__);
1374
1375 tvps = (struct dtv_properties __user *)parg;
1376
1377 printk("%s() properties.num = %d\n", __FUNCTION__, tvps->num);
1378 printk("%s() properties.props = %p\n", __FUNCTION__, tvps->props);
1379
1380 /* Put an arbitrary limit on the number of messages that can
1381 * be sent at once */
1382 if ((tvps->num == 0) || (tvps->num > DTV_IOCTL_MAX_MSGS))
1383 return -EINVAL;
1384
1385 tvp = (struct dtv_property *) kmalloc(tvps->num *
1386 sizeof(struct dtv_property), GFP_KERNEL);
1387 if (!tvp) {
1388 err = -ENOMEM;
1389 goto out;
1390 }
1391
1392 if (copy_from_user(tvp, tvps->props, tvps->num * sizeof(struct dtv_property))) {
1393 err = -EFAULT;
1394 goto out;
1395 }
1396
1397 for (i = 0; i < tvps->num; i++) {
1398 (tvp + i)->result = dtv_property_process_get(fe, tvp + i, inode, file);
1399 err |= (tvp + i)->result;
1400 }
1401
1402 if (copy_to_user(tvps->props, tvp, tvps->num * sizeof(struct dtv_property))) {
1403 err = -EFAULT;
1404 goto out;
1405 }
1406
1407 } else
1408 err = -EOPNOTSUPP;
1409
1410out:
1411 kfree(tvp);
1412 return err;
1413}
1414
1415static int dvb_frontend_ioctl_legacy(struct inode *inode, struct file *file,
1416 unsigned int cmd, void *parg)
1417{
1418 struct dvb_device *dvbdev = file->private_data;
1419 struct dvb_frontend *fe = dvbdev->priv;
1420 struct dvb_frontend_private *fepriv = fe->frontend_priv;
1421 int err = -EOPNOTSUPP;
1422
779 switch (cmd) { 1423 switch (cmd) {
780 case FE_GET_INFO: { 1424 case FE_GET_INFO: {
781 struct dvb_frontend_info* info = parg; 1425 struct dvb_frontend_info* info = parg;
@@ -942,13 +1586,21 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file,
942 case FE_SET_FRONTEND: { 1586 case FE_SET_FRONTEND: {
943 struct dvb_frontend_tune_settings fetunesettings; 1587 struct dvb_frontend_tune_settings fetunesettings;
944 1588
945 if (dvb_frontend_check_parameters(fe, parg) < 0) { 1589 if(fe->dtv_property_cache.state == DTV_TUNE) {
946 err = -EINVAL; 1590 if (dvb_frontend_check_parameters(fe, &fepriv->parameters) < 0) {
947 break; 1591 err = -EINVAL;
948 } 1592 break;
1593 }
1594 } else {
1595 if (dvb_frontend_check_parameters(fe, parg) < 0) {
1596 err = -EINVAL;
1597 break;
1598 }
949 1599
950 memcpy (&fepriv->parameters, parg, 1600 memcpy (&fepriv->parameters, parg,
951 sizeof (struct dvb_frontend_parameters)); 1601 sizeof (struct dvb_frontend_parameters));
1602 dtv_property_cache_sync(fe, &fepriv->parameters);
1603 }
952 1604
953 memset(&fetunesettings, 0, sizeof(struct dvb_frontend_tune_settings)); 1605 memset(&fetunesettings, 0, sizeof(struct dvb_frontend_tune_settings));
954 memcpy(&fetunesettings.parameters, parg, 1606 memcpy(&fetunesettings.parameters, parg,
@@ -1027,10 +1679,10 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file,
1027 break; 1679 break;
1028 }; 1680 };
1029 1681
1030 up (&fepriv->sem);
1031 return err; 1682 return err;
1032} 1683}
1033 1684
1685
1034static unsigned int dvb_frontend_poll(struct file *file, struct poll_table_struct *wait) 1686static unsigned int dvb_frontend_poll(struct file *file, struct poll_table_struct *wait)
1035{ 1687{
1036 struct dvb_device *dvbdev = file->private_data; 1688 struct dvb_device *dvbdev = file->private_data;
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.h b/drivers/media/dvb/dvb-core/dvb_frontend.h
index aa4133f0bd19..3055301ff3ca 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.h
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.h
@@ -169,6 +169,9 @@ struct dvb_frontend_ops {
169 169
170 struct dvb_tuner_ops tuner_ops; 170 struct dvb_tuner_ops tuner_ops;
171 struct analog_demod_ops analog_ops; 171 struct analog_demod_ops analog_ops;
172
173 int (*set_property)(struct dvb_frontend* fe, struct dtv_property* tvp);
174 int (*get_property)(struct dvb_frontend* fe, struct dtv_property* tvp);
172}; 175};
173 176
174#define MAX_EVENT 8 177#define MAX_EVENT 8
@@ -182,6 +185,32 @@ struct dvb_fe_events {
182 struct mutex mtx; 185 struct mutex mtx;
183}; 186};
184 187
188struct dtv_frontend_properties {
189
190 /* Cache State */
191 u32 state;
192
193 u32 frequency;
194 fe_modulation_t modulation;
195
196 fe_sec_voltage_t voltage;
197 fe_sec_tone_mode_t sectone;
198 fe_spectral_inversion_t inversion;
199 fe_code_rate_t fec_inner;
200 fe_transmit_mode_t transmission_mode;
201 u32 bandwidth_hz; /* 0 = AUTO */
202 fe_guard_interval_t guard_interval;
203 fe_hierarchy_t hierarchy;
204 u32 symbol_rate;
205 fe_code_rate_t code_rate_HP;
206 fe_code_rate_t code_rate_LP;
207
208 fe_pilot_t pilot;
209 fe_rolloff_t rolloff;
210
211 fe_delivery_system_t delivery_system;
212};
213
185struct dvb_frontend { 214struct dvb_frontend {
186 struct dvb_frontend_ops ops; 215 struct dvb_frontend_ops ops;
187 struct dvb_adapter *dvb; 216 struct dvb_adapter *dvb;
@@ -190,6 +219,9 @@ struct dvb_frontend {
190 void *frontend_priv; 219 void *frontend_priv;
191 void *sec_priv; 220 void *sec_priv;
192 void *analog_demod_priv; 221 void *analog_demod_priv;
222 struct dtv_frontend_properties dtv_property_cache;
223#define DVB_FRONTEND_COMPONENT_TUNER 0
224 int (*callback)(void *adapter_priv, int component, int cmd, int arg);
193}; 225};
194 226
195extern int dvb_register_frontend(struct dvb_adapter *dvb, 227extern int dvb_register_frontend(struct dvb_adapter *dvb,
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig
index e84152b7576d..3c13bcfa6385 100644
--- a/drivers/media/dvb/dvb-usb/Kconfig
+++ b/drivers/media/dvb/dvb-usb/Kconfig
@@ -72,9 +72,11 @@ config DVB_USB_DIB0700
72 select DVB_DIB7000P 72 select DVB_DIB7000P
73 select DVB_DIB7000M 73 select DVB_DIB7000M
74 select DVB_DIB3000MC 74 select DVB_DIB3000MC
75 select DVB_S5H1411 if !DVB_FE_CUSTOMISE
75 select MEDIA_TUNER_MT2060 if !DVB_FE_CUSTOMISE 76 select MEDIA_TUNER_MT2060 if !DVB_FE_CUSTOMISE
76 select MEDIA_TUNER_MT2266 if !DVB_FE_CUSTOMISE 77 select MEDIA_TUNER_MT2266 if !DVB_FE_CUSTOMISE
77 select MEDIA_TUNER_XC2028 if !DVB_FE_CUSTOMISE 78 select MEDIA_TUNER_XC2028 if !DVB_FE_CUSTOMISE
79 select MEDIA_TUNER_XC5000 if !DVB_FE_CUSTOMIZE
78 select DVB_TUNER_DIB0070 80 select DVB_TUNER_DIB0070
79 help 81 help
80 Support for USB2.0/1.1 DVB receivers based on the DiB0700 USB bridge. The 82 Support for USB2.0/1.1 DVB receivers based on the DiB0700 USB bridge. The
@@ -108,6 +110,8 @@ config DVB_USB_CXUSB
108 select MEDIA_TUNER_SIMPLE if !DVB_FE_CUSTOMISE 110 select MEDIA_TUNER_SIMPLE if !DVB_FE_CUSTOMISE
109 select MEDIA_TUNER_XC2028 if !DVB_FE_CUSTOMISE 111 select MEDIA_TUNER_XC2028 if !DVB_FE_CUSTOMISE
110 select MEDIA_TUNER_MXL5005S if !DVB_FE_CUSTOMISE 112 select MEDIA_TUNER_MXL5005S if !DVB_FE_CUSTOMISE
113 select DVB_DIB7000P if !DVB_FE_CUSTOMISE
114 select DVB_TUNER_DIB0070 if !DVB_FE_CUSTOMISE
111 help 115 help
112 Say Y here to support the Conexant USB2.0 hybrid reference design. 116 Say Y here to support the Conexant USB2.0 hybrid reference design.
113 Currently, only DVB and ATSC modes are supported, analog mode 117 Currently, only DVB and ATSC modes are supported, analog mode
@@ -245,12 +249,25 @@ config DVB_USB_AF9005_REMOTE
245 Afatech AF9005 based receiver. 249 Afatech AF9005 based receiver.
246 250
247config DVB_USB_DW2102 251config DVB_USB_DW2102
248 tristate "DvbWorld 2102 DVB-S USB2.0 receiver" 252 tristate "DvbWorld DVB-S/S2 USB2.0 support"
249 depends on DVB_USB 253 depends on DVB_USB
250 select DVB_STV0299 if !DVB_FE_CUSTOMISE
251 select DVB_PLL if !DVB_FE_CUSTOMISE 254 select DVB_PLL if !DVB_FE_CUSTOMISE
255 select DVB_STV0299 if !DVB_FE_CUSTOMISE
256 select DVB_STV0288 if !DVB_FE_CUSTOMISE
257 select DVB_STB6000 if !DVB_FE_CUSTOMISE
258 select DVB_CX24116 if !DVB_FE_CUSTOMISE
259 select DVB_SI21XX if !DVB_FE_CUSTOMISE
252 help 260 help
253 Say Y here to support the DvbWorld 2102 DVB-S USB2.0 receiver. 261 Say Y here to support the DvbWorld DVB-S/S2 USB2.0 receivers
262 and the TeVii S650.
263
264config DVB_USB_CINERGY_T2
265 tristate "Terratec CinergyT2/qanu USB 2.0 DVB-T receiver"
266 depends on DVB_USB
267 help
268 Support for "TerraTec CinergyT2" USB2.0 Highspeed DVB Receivers
269
270 Say Y if you own such a device and want to use it.
254 271
255config DVB_USB_ANYSEE 272config DVB_USB_ANYSEE
256 tristate "Anysee DVB-T/C USB2.0 support" 273 tristate "Anysee DVB-T/C USB2.0 support"
@@ -262,3 +279,22 @@ config DVB_USB_ANYSEE
262 help 279 help
263 Say Y here to support the Anysee E30, Anysee E30 Plus or 280 Say Y here to support the Anysee E30, Anysee E30 Plus or
264 Anysee E30 C Plus DVB USB2.0 receiver. 281 Anysee E30 C Plus DVB USB2.0 receiver.
282
283config DVB_USB_DTV5100
284 tristate "AME DTV-5100 USB2.0 DVB-T support"
285 depends on DVB_USB
286 select MEDIA_TUNER_QT1010 if !DVB_FE_CUSTOMISE
287 help
288 Say Y here to support the AME DTV-5100 USB2.0 DVB-T receiver.
289
290config DVB_USB_AF9015
291 tristate "Afatech AF9015 DVB-T USB2.0 support"
292 depends on DVB_USB && EXPERIMENTAL
293 select DVB_AF9013
294 select DVB_PLL if !DVB_FE_CUSTOMISE
295 select MEDIA_TUNER_MT2060 if !DVB_FE_CUSTOMISE
296 select MEDIA_TUNER_QT1010 if !DVB_FE_CUSTOMISE
297 select MEDIA_TUNER_TDA18271 if !DVB_FE_CUSTOMISE
298 select MEDIA_TUNER_MXL5005S if !DVB_FE_CUSTOMISE
299 help
300 Say Y here to support the Afatech AF9015 based DVB-T USB2.0 receiver
diff --git a/drivers/media/dvb/dvb-usb/Makefile b/drivers/media/dvb/dvb-usb/Makefile
index e206f1ea0027..3122b7cc2c23 100644
--- a/drivers/media/dvb/dvb-usb/Makefile
+++ b/drivers/media/dvb/dvb-usb/Makefile
@@ -67,6 +67,16 @@ obj-$(CONFIG_DVB_USB_ANYSEE) += dvb-usb-anysee.o
67dvb-usb-dw2102-objs = dw2102.o 67dvb-usb-dw2102-objs = dw2102.o
68obj-$(CONFIG_DVB_USB_DW2102) += dvb-usb-dw2102.o 68obj-$(CONFIG_DVB_USB_DW2102) += dvb-usb-dw2102.o
69 69
70dvb-usb-dtv5100-objs = dtv5100.o
71obj-$(CONFIG_DVB_USB_DTV5100) += dvb-usb-dtv5100.o
72
73dvb-usb-af9015-objs = af9015.o
74obj-$(CONFIG_DVB_USB_AF9015) += dvb-usb-af9015.o
75
76dvb-usb-cinergyT2-objs = cinergyT2-core.o cinergyT2-fe.o
77obj-$(CONFIG_DVB_USB_CINERGY_T2) += dvb-usb-cinergyT2.o
78
79
70EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/ 80EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
71# due to tuner-xc3028 81# due to tuner-xc3028
72EXTRA_CFLAGS += -Idrivers/media/common/tuners 82EXTRA_CFLAGS += -Idrivers/media/common/tuners
diff --git a/drivers/media/dvb/dvb-usb/af9005-remote.c b/drivers/media/dvb/dvb-usb/af9005-remote.c
index ff00c0e8f4a1..7c596f926764 100644
--- a/drivers/media/dvb/dvb-usb/af9005-remote.c
+++ b/drivers/media/dvb/dvb-usb/af9005-remote.c
@@ -25,7 +25,7 @@
25 */ 25 */
26#include "af9005.h" 26#include "af9005.h"
27/* debug */ 27/* debug */
28int dvb_usb_af9005_remote_debug; 28static int dvb_usb_af9005_remote_debug;
29module_param_named(debug, dvb_usb_af9005_remote_debug, int, 0644); 29module_param_named(debug, dvb_usb_af9005_remote_debug, int, 0644);
30MODULE_PARM_DESC(debug, 30MODULE_PARM_DESC(debug,
31 "enable (1) or disable (0) debug messages." 31 "enable (1) or disable (0) debug messages."
diff --git a/drivers/media/dvb/dvb-usb/af9005-script.h b/drivers/media/dvb/dvb-usb/af9005-script.h
index 6eeaae51b1ca..4d69045426dd 100644
--- a/drivers/media/dvb/dvb-usb/af9005-script.h
+++ b/drivers/media/dvb/dvb-usb/af9005-script.h
@@ -14,7 +14,7 @@ typedef struct {
14 u8 val; 14 u8 val;
15} RegDesc; 15} RegDesc;
16 16
17RegDesc script[] = { 17static RegDesc script[] = {
18 {0xa180, 0x0, 0x8, 0xa}, 18 {0xa180, 0x0, 0x8, 0xa},
19 {0xa181, 0x0, 0x8, 0xd7}, 19 {0xa181, 0x0, 0x8, 0xd7},
20 {0xa182, 0x0, 0x8, 0xa3}, 20 {0xa182, 0x0, 0x8, 0xa3},
diff --git a/drivers/media/dvb/dvb-usb/af9005.c b/drivers/media/dvb/dvb-usb/af9005.c
index cfe71feefcad..ca5a0a4d2a47 100644
--- a/drivers/media/dvb/dvb-usb/af9005.c
+++ b/drivers/media/dvb/dvb-usb/af9005.c
@@ -35,17 +35,17 @@ module_param_named(led, dvb_usb_af9005_led, bool, 0644);
35MODULE_PARM_DESC(led, "enable led (default: 1)."); 35MODULE_PARM_DESC(led, "enable led (default: 1).");
36 36
37/* eeprom dump */ 37/* eeprom dump */
38int dvb_usb_af9005_dump_eeprom = 0; 38static int dvb_usb_af9005_dump_eeprom;
39module_param_named(dump_eeprom, dvb_usb_af9005_dump_eeprom, int, 0); 39module_param_named(dump_eeprom, dvb_usb_af9005_dump_eeprom, int, 0);
40MODULE_PARM_DESC(dump_eeprom, "dump contents of the eeprom."); 40MODULE_PARM_DESC(dump_eeprom, "dump contents of the eeprom.");
41 41
42DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); 42DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
43 43
44/* remote control decoder */ 44/* remote control decoder */
45int (*rc_decode) (struct dvb_usb_device * d, u8 * data, int len, u32 * event, 45static int (*rc_decode) (struct dvb_usb_device *d, u8 *data, int len,
46 int *state); 46 u32 *event, int *state);
47void *rc_keys; 47static void *rc_keys;
48int *rc_keys_size; 48static int *rc_keys_size;
49 49
50u8 regmask[8] = { 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff }; 50u8 regmask[8] = { 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff };
51 51
@@ -54,8 +54,8 @@ struct af9005_device_state {
54 int led_state; 54 int led_state;
55}; 55};
56 56
57int af9005_usb_generic_rw(struct dvb_usb_device *d, u8 * wbuf, u16 wlen, 57static int af9005_usb_generic_rw(struct dvb_usb_device *d, u8 *wbuf, u16 wlen,
58 u8 * rbuf, u16 rlen, int delay_ms) 58 u8 *rbuf, u16 rlen, int delay_ms)
59{ 59{
60 int actlen, ret = -ENOMEM; 60 int actlen, ret = -ENOMEM;
61 61
@@ -98,12 +98,7 @@ int af9005_usb_generic_rw(struct dvb_usb_device *d, u8 * wbuf, u16 wlen,
98 return ret; 98 return ret;
99} 99}
100 100
101int af9005_usb_generic_write(struct dvb_usb_device *d, u8 * buf, u16 len) 101static int af9005_generic_read_write(struct dvb_usb_device *d, u16 reg,
102{
103 return af9005_usb_generic_rw(d, buf, len, NULL, 0, 0);
104}
105
106int af9005_generic_read_write(struct dvb_usb_device *d, u16 reg,
107 int readwrite, int type, u8 * values, int len) 102 int readwrite, int type, u8 * values, int len)
108{ 103{
109 struct af9005_device_state *st = d->priv; 104 struct af9005_device_state *st = d->priv;
@@ -765,7 +760,7 @@ static int af9005_boot_packet(struct usb_device *udev, int type, u8 * reply)
765 return 0; 760 return 0;
766} 761}
767 762
768int af9005_download_firmware(struct usb_device *udev, const struct firmware *fw) 763static int af9005_download_firmware(struct usb_device *udev, const struct firmware *fw)
769{ 764{
770 int i, packets, ret, act_len; 765 int i, packets, ret, act_len;
771 766
diff --git a/drivers/media/dvb/dvb-usb/af9015.c b/drivers/media/dvb/dvb-usb/af9015.c
new file mode 100644
index 000000000000..cb0829c038ce
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/af9015.c
@@ -0,0 +1,1474 @@
1/*
2 * DVB USB Linux driver for Afatech AF9015 DVB-T USB2.0 receiver
3 *
4 * Copyright (C) 2007 Antti Palosaari <crope@iki.fi>
5 *
6 * Thanks to Afatech who kindly provided information.
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
24#include "af9015.h"
25#include "af9013.h"
26#include "mt2060.h"
27#include "qt1010.h"
28#include "tda18271.h"
29#include "mxl5005s.h"
30#if 0
31#include "mc44s80x.h"
32#endif
33
34int dvb_usb_af9015_debug;
35module_param_named(debug, dvb_usb_af9015_debug, int, 0644);
36MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS);
37int dvb_usb_af9015_remote;
38module_param_named(remote, dvb_usb_af9015_remote, int, 0644);
39MODULE_PARM_DESC(remote, "select remote");
40int dvb_usb_af9015_dual_mode;
41module_param_named(dual_mode, dvb_usb_af9015_dual_mode, int, 0644);
42MODULE_PARM_DESC(dual_mode, "enable dual mode");
43DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
44
45static DEFINE_MUTEX(af9015_usb_mutex);
46
47static struct af9015_config af9015_config;
48static struct dvb_usb_device_properties af9015_properties[2];
49int af9015_properties_count = ARRAY_SIZE(af9015_properties);
50
51static struct af9013_config af9015_af9013_config[] = {
52 {
53 .demod_address = AF9015_I2C_DEMOD,
54 .output_mode = AF9013_OUTPUT_MODE_USB,
55 .api_version = { 0, 1, 9, 0 },
56 .gpio[0] = AF9013_GPIO_HI,
57 .gpio[3] = AF9013_GPIO_TUNER_ON,
58
59 }, {
60 .output_mode = AF9013_OUTPUT_MODE_SERIAL,
61 .api_version = { 0, 1, 9, 0 },
62 .gpio[0] = AF9013_GPIO_TUNER_ON,
63 .gpio[1] = AF9013_GPIO_LO,
64 }
65};
66
67static int af9015_rw_udev(struct usb_device *udev, struct req_t *req)
68{
69 int act_len, ret;
70 u8 buf[64];
71 u8 write = 1;
72 u8 msg_len = 8;
73 static u8 seq; /* packet sequence number */
74
75 if (mutex_lock_interruptible(&af9015_usb_mutex) < 0)
76 return -EAGAIN;
77
78 buf[0] = req->cmd;
79 buf[1] = seq++;
80 buf[2] = req->i2c_addr;
81 buf[3] = req->addr >> 8;
82 buf[4] = req->addr & 0xff;
83 buf[5] = req->mbox;
84 buf[6] = req->addr_len;
85 buf[7] = req->data_len;
86
87 switch (req->cmd) {
88 case GET_CONFIG:
89 case BOOT:
90 case READ_MEMORY:
91 case RECONNECT_USB:
92 case GET_IR_CODE:
93 write = 0;
94 break;
95 case READ_I2C:
96 write = 0;
97 buf[2] |= 0x01; /* set I2C direction */
98 case WRITE_I2C:
99 buf[0] = READ_WRITE_I2C;
100 break;
101 case WRITE_MEMORY:
102 if (((req->addr & 0xff00) == 0xff00) ||
103 ((req->addr & 0xae00) == 0xae00))
104 buf[0] = WRITE_VIRTUAL_MEMORY;
105 case WRITE_VIRTUAL_MEMORY:
106 case COPY_FIRMWARE:
107 case DOWNLOAD_FIRMWARE:
108 break;
109 default:
110 err("unknown command:%d", req->cmd);
111 ret = -1;
112 goto error_unlock;
113 }
114
115 /* write requested */
116 if (write) {
117 memcpy(&buf[8], req->data, req->data_len);
118 msg_len += req->data_len;
119 }
120 deb_xfer(">>> ");
121 debug_dump(buf, msg_len, deb_xfer);
122
123 /* send req */
124 ret = usb_bulk_msg(udev, usb_sndbulkpipe(udev, 0x02), buf, msg_len,
125 &act_len, AF9015_USB_TIMEOUT);
126 if (ret)
127 err("bulk message failed:%d (%d/%d)", ret, msg_len, act_len);
128 else
129 if (act_len != msg_len)
130 ret = -1; /* all data is not send */
131 if (ret)
132 goto error_unlock;
133
134 /* no ack for those packets */
135 if (req->cmd == DOWNLOAD_FIRMWARE || req->cmd == RECONNECT_USB)
136 goto exit_unlock;
137
138 /* receive ack and data if read req */
139 msg_len = 1 + 1 + req->data_len; /* seq + status + data len */
140 ret = usb_bulk_msg(udev, usb_rcvbulkpipe(udev, 0x81), buf, msg_len,
141 &act_len, AF9015_USB_TIMEOUT);
142 if (ret) {
143 err("recv bulk message failed:%d", ret);
144 ret = -1;
145 goto error_unlock;
146 }
147
148 deb_xfer("<<< ");
149 debug_dump(buf, act_len, deb_xfer);
150
151 /* remote controller query status is 1 if remote code is not received */
152 if (req->cmd == GET_IR_CODE && buf[1] == 1) {
153 buf[1] = 0; /* clear command "error" status */
154 memset(&buf[2], 0, req->data_len);
155 buf[3] = 1; /* no remote code received mark */
156 }
157
158 /* check status */
159 if (buf[1]) {
160 err("command failed:%d", buf[1]);
161 ret = -1;
162 goto error_unlock;
163 }
164
165 /* read request, copy returned data to return buf */
166 if (!write)
167 memcpy(req->data, &buf[2], req->data_len);
168
169error_unlock:
170exit_unlock:
171 mutex_unlock(&af9015_usb_mutex);
172
173 return ret;
174}
175
176static int af9015_ctrl_msg(struct dvb_usb_device *d, struct req_t *req)
177{
178 return af9015_rw_udev(d->udev, req);
179}
180
181static int af9015_write_regs(struct dvb_usb_device *d, u16 addr, u8 *val,
182 u8 len)
183{
184 struct req_t req = {WRITE_MEMORY, AF9015_I2C_DEMOD, addr, 0, 0, len,
185 val};
186 return af9015_ctrl_msg(d, &req);
187}
188
189static int af9015_write_reg(struct dvb_usb_device *d, u16 addr, u8 val)
190{
191 return af9015_write_regs(d, addr, &val, 1);
192}
193
194static int af9015_read_reg(struct dvb_usb_device *d, u16 addr, u8 *val)
195{
196 struct req_t req = {READ_MEMORY, AF9015_I2C_DEMOD, addr, 0, 0, 1, val};
197 return af9015_ctrl_msg(d, &req);
198}
199
200static int af9015_write_reg_i2c(struct dvb_usb_device *d, u8 addr, u16 reg,
201 u8 val)
202{
203 struct req_t req = {WRITE_I2C, addr, reg, 1, 1, 1, &val};
204
205 if (addr == af9015_af9013_config[0].demod_address ||
206 addr == af9015_af9013_config[1].demod_address)
207 req.addr_len = 3;
208
209 return af9015_ctrl_msg(d, &req);
210}
211
212static int af9015_read_reg_i2c(struct dvb_usb_device *d, u8 addr, u16 reg,
213 u8 *val)
214{
215 struct req_t req = {READ_I2C, addr, reg, 0, 1, 1, val};
216
217 if (addr == af9015_af9013_config[0].demod_address ||
218 addr == af9015_af9013_config[1].demod_address)
219 req.addr_len = 3;
220
221 return af9015_ctrl_msg(d, &req);
222}
223
224static int af9015_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
225 int num)
226{
227 struct dvb_usb_device *d = i2c_get_adapdata(adap);
228 int ret = 0, i = 0;
229 u16 addr;
230 u8 mbox, addr_len;
231 struct req_t req;
232
233/* TODO: implement bus lock
234
235The bus lock is needed because there is two tuners both using same I2C-address.
236Due to that the only way to select correct tuner is use demodulator I2C-gate.
237
238................................................
239. AF9015 includes integrated AF9013 demodulator.
240. ____________ ____________ . ____________
241.| uC | | demod | . | tuner |
242.|------------| |------------| . |------------|
243.| AF9015 | | AF9013/5 | . | MXL5003 |
244.| |--+----I2C-------|-----/ -----|-.-----I2C-------| |
245.| | | | addr 0x38 | . | addr 0xc6 |
246.|____________| | |____________| . |____________|
247.................|..............................
248 | ____________ ____________
249 | | demod | | tuner |
250 | |------------| |------------|
251 | | AF9013 | | MXL5003 |
252 +----I2C-------|-----/ -----|-------I2C-------| |
253 | addr 0x3a | | addr 0xc6 |
254 |____________| |____________|
255*/
256 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
257 return -EAGAIN;
258
259 while (i < num) {
260 if (msg[i].addr == af9015_af9013_config[0].demod_address ||
261 msg[i].addr == af9015_af9013_config[1].demod_address) {
262 addr = msg[i].buf[0] << 8;
263 addr += msg[i].buf[1];
264 mbox = msg[i].buf[2];
265 addr_len = 3;
266 } else {
267 addr = msg[i].buf[0];
268 addr_len = 1;
269 mbox = 0;
270 }
271
272 if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) {
273 if (msg[i].addr ==
274 af9015_af9013_config[0].demod_address)
275 req.cmd = READ_MEMORY;
276 else
277 req.cmd = READ_I2C;
278 req.i2c_addr = msg[i].addr;
279 req.addr = addr;
280 req.mbox = mbox;
281 req.addr_len = addr_len;
282 req.data_len = msg[i+1].len;
283 req.data = &msg[i+1].buf[0];
284 ret = af9015_ctrl_msg(d, &req);
285 i += 2;
286 } else {
287 if (msg[i].addr ==
288 af9015_af9013_config[0].demod_address)
289 req.cmd = WRITE_MEMORY;
290 else
291 req.cmd = WRITE_I2C;
292 req.i2c_addr = msg[i].addr;
293 req.addr = addr;
294 req.mbox = mbox;
295 req.addr_len = addr_len;
296 req.data_len = msg[i].len-addr_len;
297 req.data = &msg[i].buf[addr_len];
298 ret = af9015_ctrl_msg(d, &req);
299 i += 1;
300 }
301 if (ret)
302 goto error;
303
304 }
305 ret = i;
306
307error:
308 mutex_unlock(&d->i2c_mutex);
309
310 return ret;
311}
312
313static u32 af9015_i2c_func(struct i2c_adapter *adapter)
314{
315 return I2C_FUNC_I2C;
316}
317
318static struct i2c_algorithm af9015_i2c_algo = {
319 .master_xfer = af9015_i2c_xfer,
320 .functionality = af9015_i2c_func,
321};
322
323static int af9015_do_reg_bit(struct dvb_usb_device *d, u16 addr, u8 bit, u8 op)
324{
325 int ret;
326 u8 val, mask = 0x01;
327
328 ret = af9015_read_reg(d, addr, &val);
329 if (ret)
330 return ret;
331
332 mask <<= bit;
333 if (op) {
334 /* set bit */
335 val |= mask;
336 } else {
337 /* clear bit */
338 mask ^= 0xff;
339 val &= mask;
340 }
341
342 return af9015_write_reg(d, addr, val);
343}
344
345static int af9015_set_reg_bit(struct dvb_usb_device *d, u16 addr, u8 bit)
346{
347 return af9015_do_reg_bit(d, addr, bit, 1);
348}
349
350static int af9015_clear_reg_bit(struct dvb_usb_device *d, u16 addr, u8 bit)
351{
352 return af9015_do_reg_bit(d, addr, bit, 0);
353}
354
355static int af9015_init_endpoint(struct dvb_usb_device *d)
356{
357 int ret;
358 u16 frame_size;
359 u8 packet_size;
360 deb_info("%s: USB speed:%d\n", __func__, d->udev->speed);
361
362#define TS_PACKET_SIZE 188
363
364#define TS_USB20_PACKET_COUNT 348
365#define TS_USB20_FRAME_SIZE (TS_PACKET_SIZE*TS_USB20_PACKET_COUNT)
366
367#define TS_USB11_PACKET_COUNT 21
368#define TS_USB11_FRAME_SIZE (TS_PACKET_SIZE*TS_USB11_PACKET_COUNT)
369
370#define TS_USB20_MAX_PACKET_SIZE 512
371#define TS_USB11_MAX_PACKET_SIZE 64
372
373 if (d->udev->speed == USB_SPEED_FULL) {
374 frame_size = TS_USB11_FRAME_SIZE/4;
375 packet_size = TS_USB11_MAX_PACKET_SIZE/4;
376 } else {
377 frame_size = TS_USB20_FRAME_SIZE/4;
378 packet_size = TS_USB20_MAX_PACKET_SIZE/4;
379 }
380
381 ret = af9015_set_reg_bit(d, 0xd507, 2); /* assert EP4 reset */
382 if (ret)
383 goto error;
384 ret = af9015_set_reg_bit(d, 0xd50b, 1); /* assert EP5 reset */
385 if (ret)
386 goto error;
387 ret = af9015_clear_reg_bit(d, 0xdd11, 5); /* disable EP4 */
388 if (ret)
389 goto error;
390 ret = af9015_clear_reg_bit(d, 0xdd11, 6); /* disable EP5 */
391 if (ret)
392 goto error;
393 ret = af9015_set_reg_bit(d, 0xdd11, 5); /* enable EP4 */
394 if (ret)
395 goto error;
396 if (af9015_config.dual_mode) {
397 ret = af9015_set_reg_bit(d, 0xdd11, 6); /* enable EP5 */
398 if (ret)
399 goto error;
400 }
401 ret = af9015_clear_reg_bit(d, 0xdd13, 5); /* disable EP4 NAK */
402 if (ret)
403 goto error;
404 if (af9015_config.dual_mode) {
405 ret = af9015_clear_reg_bit(d, 0xdd13, 6); /* disable EP5 NAK */
406 if (ret)
407 goto error;
408 }
409 /* EP4 xfer length */
410 ret = af9015_write_reg(d, 0xdd88, frame_size & 0xff);
411 if (ret)
412 goto error;
413 ret = af9015_write_reg(d, 0xdd89, frame_size >> 8);
414 if (ret)
415 goto error;
416 /* EP5 xfer length */
417 ret = af9015_write_reg(d, 0xdd8a, frame_size & 0xff);
418 if (ret)
419 goto error;
420 ret = af9015_write_reg(d, 0xdd8b, frame_size >> 8);
421 if (ret)
422 goto error;
423 ret = af9015_write_reg(d, 0xdd0c, packet_size); /* EP4 packet size */
424 if (ret)
425 goto error;
426 ret = af9015_write_reg(d, 0xdd0d, packet_size); /* EP5 packet size */
427 if (ret)
428 goto error;
429 ret = af9015_clear_reg_bit(d, 0xd507, 2); /* negate EP4 reset */
430 if (ret)
431 goto error;
432 if (af9015_config.dual_mode) {
433 ret = af9015_clear_reg_bit(d, 0xd50b, 1); /* negate EP5 reset */
434 if (ret)
435 goto error;
436 }
437
438 /* enable / disable mp2if2 */
439 if (af9015_config.dual_mode)
440 ret = af9015_set_reg_bit(d, 0xd50b, 0);
441 else
442 ret = af9015_clear_reg_bit(d, 0xd50b, 0);
443error:
444 if (ret)
445 err("endpoint init failed:%d", ret);
446 return ret;
447}
448
449static int af9015_copy_firmware(struct dvb_usb_device *d)
450{
451 int ret;
452 u8 fw_params[4];
453 u8 val, i;
454 struct req_t req = {COPY_FIRMWARE, 0, 0x5100, 0, 0, sizeof(fw_params),
455 fw_params };
456 deb_info("%s:\n", __func__);
457
458 fw_params[0] = af9015_config.firmware_size >> 8;
459 fw_params[1] = af9015_config.firmware_size & 0xff;
460 fw_params[2] = af9015_config.firmware_checksum >> 8;
461 fw_params[3] = af9015_config.firmware_checksum & 0xff;
462
463 /* wait 2nd demodulator ready */
464 msleep(100);
465
466 ret = af9015_read_reg_i2c(d, 0x3a, 0x98be, &val);
467 if (ret)
468 goto error;
469 else
470 deb_info("%s: firmware status:%02x\n", __func__, val);
471
472 if (val == 0x0c) /* fw is running, no need for download */
473 goto exit;
474
475 /* set I2C master clock to fast (to speed up firmware copy) */
476 ret = af9015_write_reg(d, 0xd416, 0x04); /* 0x04 * 400ns */
477 if (ret)
478 goto error;
479
480 msleep(50);
481
482 /* copy firmware */
483 ret = af9015_ctrl_msg(d, &req);
484 if (ret)
485 err("firmware copy cmd failed:%d", ret);
486 deb_info("%s: firmware copy done\n", __func__);
487
488 /* set I2C master clock back to normal */
489 ret = af9015_write_reg(d, 0xd416, 0x14); /* 0x14 * 400ns */
490 if (ret)
491 goto error;
492
493 /* request boot firmware */
494 ret = af9015_write_reg_i2c(d, af9015_af9013_config[1].demod_address,
495 0xe205, 1);
496 deb_info("%s: firmware boot cmd status:%d\n", __func__, ret);
497 if (ret)
498 goto error;
499
500 for (i = 0; i < 15; i++) {
501 msleep(100);
502
503 /* check firmware status */
504 ret = af9015_read_reg_i2c(d,
505 af9015_af9013_config[1].demod_address, 0x98be, &val);
506 deb_info("%s: firmware status cmd status:%d fw status:%02x\n",
507 __func__, ret, val);
508 if (ret)
509 goto error;
510
511 if (val == 0x0c || val == 0x04) /* success or fail */
512 break;
513 }
514
515 if (val == 0x04) {
516 err("firmware did not run");
517 ret = -1;
518 } else if (val != 0x0c) {
519 err("firmware boot timeout");
520 ret = -1;
521 }
522
523error:
524exit:
525 return ret;
526}
527
528/* dump eeprom */
529static int af9015_eeprom_dump(struct dvb_usb_device *d)
530{
531 char buf[52], buf2[4];
532 u8 reg, val;
533
534 for (reg = 0; ; reg++) {
535 if (reg % 16 == 0) {
536 if (reg)
537 deb_info("%s\n", buf);
538 sprintf(buf, "%02x: ", reg);
539 }
540 if (af9015_read_reg_i2c(d, AF9015_I2C_EEPROM, reg, &val) == 0)
541 sprintf(buf2, "%02x ", val);
542 else
543 strcpy(buf2, "-- ");
544 strcat(buf, buf2);
545 if (reg == 0xff)
546 break;
547 }
548 deb_info("%s\n", buf);
549 return 0;
550}
551
552int af9015_download_ir_table(struct dvb_usb_device *d)
553{
554 int i, packets = 0, ret;
555 u16 addr = 0x9a56; /* ir-table start address */
556 struct req_t req = {WRITE_MEMORY, 0, 0, 0, 0, 1, NULL};
557 u8 *data = NULL;
558 deb_info("%s:\n", __func__);
559
560 data = af9015_config.ir_table;
561 packets = af9015_config.ir_table_size;
562
563 /* no remote */
564 if (!packets)
565 goto exit;
566
567 /* load remote ir-table */
568 for (i = 0; i < packets; i++) {
569 req.addr = addr + i;
570 req.data = &data[i];
571 ret = af9015_ctrl_msg(d, &req);
572 if (ret) {
573 err("ir-table download failed at packet %d with " \
574 "code %d", i, ret);
575 return ret;
576 }
577 }
578
579exit:
580 return 0;
581}
582
583static int af9015_init(struct dvb_usb_device *d)
584{
585 int ret;
586 deb_info("%s:\n", __func__);
587
588 ret = af9015_init_endpoint(d);
589 if (ret)
590 goto error;
591
592 ret = af9015_download_ir_table(d);
593 if (ret)
594 goto error;
595
596error:
597 return ret;
598}
599
600static int af9015_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff)
601{
602 int ret;
603 deb_info("%s: onoff:%d\n", __func__, onoff);
604
605 if (onoff)
606 ret = af9015_set_reg_bit(adap->dev, 0xd503, 0);
607 else
608 ret = af9015_clear_reg_bit(adap->dev, 0xd503, 0);
609
610 return ret;
611}
612
613static int af9015_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid,
614 int onoff)
615{
616 int ret;
617 u8 idx;
618
619 deb_info("%s: set pid filter, index %d, pid %x, onoff %d\n",
620 __func__, index, pid, onoff);
621
622 ret = af9015_write_reg(adap->dev, 0xd505, (pid & 0xff));
623 if (ret)
624 goto error;
625
626 ret = af9015_write_reg(adap->dev, 0xd506, (pid >> 8));
627 if (ret)
628 goto error;
629
630 idx = ((index & 0x1f) | (1 << 5));
631 ret = af9015_write_reg(adap->dev, 0xd504, idx);
632
633error:
634 return ret;
635}
636
637static int af9015_download_firmware(struct usb_device *udev,
638 const struct firmware *fw)
639{
640 int i, len, packets, remainder, ret;
641 struct req_t req = {DOWNLOAD_FIRMWARE, 0, 0, 0, 0, 0, NULL};
642 u16 addr = 0x5100; /* firmware start address */
643 u16 checksum = 0;
644
645 deb_info("%s:\n", __func__);
646
647 /* calc checksum */
648 for (i = 0; i < fw->size; i++)
649 checksum += fw->data[i];
650
651 af9015_config.firmware_size = fw->size;
652 af9015_config.firmware_checksum = checksum;
653
654 #define FW_PACKET_MAX_DATA 55
655
656 packets = fw->size / FW_PACKET_MAX_DATA;
657 remainder = fw->size % FW_PACKET_MAX_DATA;
658 len = FW_PACKET_MAX_DATA;
659 for (i = 0; i <= packets; i++) {
660 if (i == packets) /* set size of the last packet */
661 len = remainder;
662
663 req.data_len = len;
664 req.data = (u8 *)(fw->data + i * FW_PACKET_MAX_DATA);
665 req.addr = addr;
666 addr += FW_PACKET_MAX_DATA;
667
668 ret = af9015_rw_udev(udev, &req);
669 if (ret) {
670 err("firmware download failed at packet %d with " \
671 "code %d", i, ret);
672 goto error;
673 }
674 }
675
676 /* firmware loaded, request boot */
677 req.cmd = BOOT;
678 ret = af9015_rw_udev(udev, &req);
679 if (ret) {
680 err("firmware boot failed:%d", ret);
681 goto error;
682 }
683
684 /* firmware is running, reconnect device in the usb bus */
685 req.cmd = RECONNECT_USB;
686 ret = af9015_rw_udev(udev, &req);
687 if (ret)
688 err("reconnect failed: %d", ret);
689
690error:
691 return ret;
692}
693
694static int af9015_read_config(struct usb_device *udev)
695{
696 int ret;
697 u8 val, i, offset = 0;
698 struct req_t req = {READ_I2C, AF9015_I2C_EEPROM, 0, 0, 1, 1, &val};
699 char manufacturer[10];
700
701 /* IR remote controller */
702 req.addr = AF9015_EEPROM_IR_MODE;
703 ret = af9015_rw_udev(udev, &req);
704 if (ret)
705 goto error;
706 deb_info("%s: IR mode:%d\n", __func__, val);
707 for (i = 0; i < af9015_properties_count; i++) {
708 if (val == AF9015_IR_MODE_DISABLED || val == 0x04) {
709 af9015_properties[i].rc_key_map = NULL;
710 af9015_properties[i].rc_key_map_size = 0;
711 } else if (dvb_usb_af9015_remote) {
712 /* load remote defined as module param */
713 switch (dvb_usb_af9015_remote) {
714 case AF9015_REMOTE_A_LINK_DTU_M:
715 af9015_properties[i].rc_key_map =
716 af9015_rc_keys_a_link;
717 af9015_properties[i].rc_key_map_size =
718 ARRAY_SIZE(af9015_rc_keys_a_link);
719 af9015_config.ir_table = af9015_ir_table_a_link;
720 af9015_config.ir_table_size =
721 ARRAY_SIZE(af9015_ir_table_a_link);
722 break;
723 case AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3:
724 af9015_properties[i].rc_key_map =
725 af9015_rc_keys_msi;
726 af9015_properties[i].rc_key_map_size =
727 ARRAY_SIZE(af9015_rc_keys_msi);
728 af9015_config.ir_table = af9015_ir_table_msi;
729 af9015_config.ir_table_size =
730 ARRAY_SIZE(af9015_ir_table_msi);
731 break;
732 case AF9015_REMOTE_MYGICTV_U718:
733 af9015_properties[i].rc_key_map =
734 af9015_rc_keys_mygictv;
735 af9015_properties[i].rc_key_map_size =
736 ARRAY_SIZE(af9015_rc_keys_mygictv);
737 af9015_config.ir_table =
738 af9015_ir_table_mygictv;
739 af9015_config.ir_table_size =
740 ARRAY_SIZE(af9015_ir_table_mygictv);
741 break;
742 }
743 } else {
744 switch (udev->descriptor.idVendor) {
745 case USB_VID_LEADTEK:
746 af9015_properties[i].rc_key_map =
747 af9015_rc_keys_leadtek;
748 af9015_properties[i].rc_key_map_size =
749 ARRAY_SIZE(af9015_rc_keys_leadtek);
750 af9015_config.ir_table =
751 af9015_ir_table_leadtek;
752 af9015_config.ir_table_size =
753 ARRAY_SIZE(af9015_ir_table_leadtek);
754 break;
755 case USB_VID_VISIONPLUS:
756 if (udev->descriptor.idProduct ==
757 USB_PID_AZUREWAVE_AD_TU700) {
758 af9015_properties[i].rc_key_map =
759 af9015_rc_keys_twinhan;
760 af9015_properties[i].rc_key_map_size =
761 ARRAY_SIZE(af9015_rc_keys_twinhan);
762 af9015_config.ir_table =
763 af9015_ir_table_twinhan;
764 af9015_config.ir_table_size =
765 ARRAY_SIZE(af9015_ir_table_twinhan);
766 }
767 break;
768 case USB_VID_KWORLD_2:
769 /* TODO: use correct rc keys */
770 af9015_properties[i].rc_key_map =
771 af9015_rc_keys_twinhan;
772 af9015_properties[i].rc_key_map_size =
773 ARRAY_SIZE(af9015_rc_keys_twinhan);
774 af9015_config.ir_table = af9015_ir_table_kworld;
775 af9015_config.ir_table_size =
776 ARRAY_SIZE(af9015_ir_table_kworld);
777 break;
778 /* Check USB manufacturer and product strings and try
779 to determine correct remote in case of chip vendor
780 reference IDs are used. */
781 case USB_VID_AFATECH:
782 memset(manufacturer, 0, sizeof(manufacturer));
783 usb_string(udev, udev->descriptor.iManufacturer,
784 manufacturer, sizeof(manufacturer));
785 if (!strcmp("Geniatech", manufacturer)) {
786 /* iManufacturer 1 Geniatech
787 iProduct 2 AF9015 */
788 af9015_properties[i].rc_key_map =
789 af9015_rc_keys_mygictv;
790 af9015_properties[i].rc_key_map_size =
791 ARRAY_SIZE(af9015_rc_keys_mygictv);
792 af9015_config.ir_table =
793 af9015_ir_table_mygictv;
794 af9015_config.ir_table_size =
795 ARRAY_SIZE(af9015_ir_table_mygictv);
796 } else if (!strcmp("MSI", manufacturer)) {
797 /* iManufacturer 1 MSI
798 iProduct 2 MSI K-VOX */
799 af9015_properties[i].rc_key_map =
800 af9015_rc_keys_msi;
801 af9015_properties[i].rc_key_map_size =
802 ARRAY_SIZE(af9015_rc_keys_msi);
803 af9015_config.ir_table =
804 af9015_ir_table_msi;
805 af9015_config.ir_table_size =
806 ARRAY_SIZE(af9015_ir_table_msi);
807 }
808 break;
809 }
810 }
811 }
812
813 /* TS mode - one or two receivers */
814 req.addr = AF9015_EEPROM_TS_MODE;
815 ret = af9015_rw_udev(udev, &req);
816 if (ret)
817 goto error;
818 af9015_config.dual_mode = val;
819 deb_info("%s: TS mode:%d\n", __func__, af9015_config.dual_mode);
820 /* disable dual mode by default because it is buggy */
821 if (!dvb_usb_af9015_dual_mode)
822 af9015_config.dual_mode = 0;
823
824 /* set buffer size according to USB port speed */
825 for (i = 0; i < af9015_properties_count; i++) {
826 /* USB1.1 set smaller buffersize and disable 2nd adapter */
827 if (udev->speed == USB_SPEED_FULL) {
828 af9015_properties[i].adapter->stream.u.bulk.buffersize =
829 TS_USB11_MAX_PACKET_SIZE;
830 /* disable 2nd adapter because we don't have
831 PID-filters */
832 af9015_config.dual_mode = 0;
833 } else {
834 af9015_properties[i].adapter->stream.u.bulk.buffersize =
835 TS_USB20_MAX_PACKET_SIZE;
836 }
837 }
838
839 if (af9015_config.dual_mode) {
840 /* read 2nd demodulator I2C address */
841 req.addr = AF9015_EEPROM_DEMOD2_I2C;
842 ret = af9015_rw_udev(udev, &req);
843 if (ret)
844 goto error;
845 af9015_af9013_config[1].demod_address = val;
846
847 /* enable 2nd adapter */
848 for (i = 0; i < af9015_properties_count; i++)
849 af9015_properties[i].num_adapters = 2;
850
851 } else {
852 /* disable 2nd adapter */
853 for (i = 0; i < af9015_properties_count; i++)
854 af9015_properties[i].num_adapters = 1;
855 }
856
857 for (i = 0; i < af9015_properties[0].num_adapters; i++) {
858 if (i == 1)
859 offset = AF9015_EEPROM_OFFSET;
860 /* xtal */
861 req.addr = AF9015_EEPROM_XTAL_TYPE1 + offset;
862 ret = af9015_rw_udev(udev, &req);
863 if (ret)
864 goto error;
865 switch (val) {
866 case 0:
867 af9015_af9013_config[i].adc_clock = 28800;
868 break;
869 case 1:
870 af9015_af9013_config[i].adc_clock = 20480;
871 break;
872 case 2:
873 af9015_af9013_config[i].adc_clock = 28000;
874 break;
875 case 3:
876 af9015_af9013_config[i].adc_clock = 25000;
877 break;
878 };
879 deb_info("%s: [%d] xtal:%d set adc_clock:%d\n", __func__, i,
880 val, af9015_af9013_config[i].adc_clock);
881
882 /* tuner IF */
883 req.addr = AF9015_EEPROM_IF1H + offset;
884 ret = af9015_rw_udev(udev, &req);
885 if (ret)
886 goto error;
887 af9015_af9013_config[i].tuner_if = val << 8;
888 req.addr = AF9015_EEPROM_IF1L + offset;
889 ret = af9015_rw_udev(udev, &req);
890 if (ret)
891 goto error;
892 af9015_af9013_config[i].tuner_if += val;
893 deb_info("%s: [%d] IF1:%d\n", __func__, i,
894 af9015_af9013_config[0].tuner_if);
895
896 /* MT2060 IF1 */
897 req.addr = AF9015_EEPROM_MT2060_IF1H + offset;
898 ret = af9015_rw_udev(udev, &req);
899 if (ret)
900 goto error;
901 af9015_config.mt2060_if1[i] = val << 8;
902 req.addr = AF9015_EEPROM_MT2060_IF1L + offset;
903 ret = af9015_rw_udev(udev, &req);
904 if (ret)
905 goto error;
906 af9015_config.mt2060_if1[i] += val;
907 deb_info("%s: [%d] MT2060 IF1:%d\n", __func__, i,
908 af9015_config.mt2060_if1[i]);
909
910 /* tuner */
911 req.addr = AF9015_EEPROM_TUNER_ID1 + offset;
912 ret = af9015_rw_udev(udev, &req);
913 if (ret)
914 goto error;
915 switch (val) {
916 case AF9013_TUNER_ENV77H11D5:
917 case AF9013_TUNER_MT2060:
918 case AF9013_TUNER_MC44S803:
919 case AF9013_TUNER_QT1010:
920 case AF9013_TUNER_UNKNOWN:
921 case AF9013_TUNER_MT2060_2:
922 case AF9013_TUNER_TDA18271:
923 case AF9013_TUNER_QT1010A:
924 af9015_af9013_config[i].rf_spec_inv = 1;
925 break;
926 case AF9013_TUNER_MXL5003D:
927 case AF9013_TUNER_MXL5005D:
928 case AF9013_TUNER_MXL5005R:
929 af9015_af9013_config[i].rf_spec_inv = 0;
930 break;
931 default:
932 warn("tuner id:%d not supported, please report!", val);
933 return -ENODEV;
934 };
935
936 af9015_af9013_config[i].tuner = val;
937 deb_info("%s: [%d] tuner id:%d\n", __func__, i, val);
938 }
939
940error:
941 if (ret)
942 err("eeprom read failed:%d", ret);
943
944 return ret;
945}
946
947static int af9015_identify_state(struct usb_device *udev,
948 struct dvb_usb_device_properties *props,
949 struct dvb_usb_device_description **desc,
950 int *cold)
951{
952 int ret;
953 u8 reply;
954 struct req_t req = {GET_CONFIG, 0, 0, 0, 0, 1, &reply};
955
956 ret = af9015_rw_udev(udev, &req);
957 if (ret)
958 return ret;
959
960 deb_info("%s: reply:%02x\n", __func__, reply);
961 if (reply == 0x02)
962 *cold = 0;
963 else
964 *cold = 1;
965
966 return ret;
967}
968
969static int af9015_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
970{
971 u8 buf[8];
972 struct req_t req = {GET_IR_CODE, 0, 0, 0, 0, sizeof(buf), buf};
973 struct dvb_usb_rc_key *keymap = d->props.rc_key_map;
974 int i, ret;
975
976 memset(buf, 0, sizeof(buf));
977
978 ret = af9015_ctrl_msg(d, &req);
979 if (ret)
980 return ret;
981
982 *event = 0;
983 *state = REMOTE_NO_KEY_PRESSED;
984
985 for (i = 0; i < d->props.rc_key_map_size; i++) {
986 if (!buf[1] && keymap[i].custom == buf[0] &&
987 keymap[i].data == buf[2]) {
988 *event = keymap[i].event;
989 *state = REMOTE_KEY_PRESSED;
990 break;
991 }
992 }
993 if (!buf[1])
994 deb_rc("%s: %02x %02x %02x %02x %02x %02x %02x %02x\n",
995 __func__, buf[0], buf[1], buf[2], buf[3], buf[4],
996 buf[5], buf[6], buf[7]);
997
998 return 0;
999}
1000
1001/* init 2nd I2C adapter */
1002int af9015_i2c_init(struct dvb_usb_device *d)
1003{
1004 int ret;
1005 struct af9015_state *state = d->priv;
1006 deb_info("%s:\n", __func__);
1007
1008 strncpy(state->i2c_adap.name, d->desc->name,
1009 sizeof(state->i2c_adap.name));
1010#ifdef I2C_ADAP_CLASS_TV_DIGITAL
1011 state->i2c_adap.class = I2C_ADAP_CLASS_TV_DIGITAL,
1012#else
1013 state->i2c_adap.class = I2C_CLASS_TV_DIGITAL,
1014#endif
1015 state->i2c_adap.algo = d->props.i2c_algo;
1016 state->i2c_adap.algo_data = NULL;
1017 state->i2c_adap.dev.parent = &d->udev->dev;
1018
1019 i2c_set_adapdata(&state->i2c_adap, d);
1020
1021 ret = i2c_add_adapter(&state->i2c_adap);
1022 if (ret < 0)
1023 err("could not add i2c adapter");
1024
1025 return ret;
1026}
1027
1028static int af9015_af9013_frontend_attach(struct dvb_usb_adapter *adap)
1029{
1030 int ret;
1031 struct af9015_state *state = adap->dev->priv;
1032 struct i2c_adapter *i2c_adap;
1033
1034 if (adap->id == 0) {
1035 /* select I2C adapter */
1036 i2c_adap = &adap->dev->i2c_adap;
1037
1038 deb_info("%s: init I2C\n", __func__);
1039 ret = af9015_i2c_init(adap->dev);
1040
1041 /* dump eeprom (debug) */
1042 ret = af9015_eeprom_dump(adap->dev);
1043 if (ret)
1044 return ret;
1045 } else {
1046 /* select I2C adapter */
1047 i2c_adap = &state->i2c_adap;
1048
1049 /* copy firmware to 2nd demodulator */
1050 if (af9015_config.dual_mode) {
1051 ret = af9015_copy_firmware(adap->dev);
1052 if (ret) {
1053 err("firmware copy to 2nd frontend " \
1054 "failed, will disable it");
1055 af9015_config.dual_mode = 0;
1056 return -ENODEV;
1057 }
1058 } else {
1059 return -ENODEV;
1060 }
1061 }
1062
1063 /* attach demodulator */
1064 adap->fe = dvb_attach(af9013_attach, &af9015_af9013_config[adap->id],
1065 i2c_adap);
1066
1067 return adap->fe == NULL ? -ENODEV : 0;
1068}
1069
1070static struct mt2060_config af9015_mt2060_config = {
1071 .i2c_address = 0xc0,
1072 .clock_out = 0,
1073};
1074
1075static struct qt1010_config af9015_qt1010_config = {
1076 .i2c_address = 0xc4,
1077};
1078
1079static struct tda18271_config af9015_tda18271_config = {
1080 .gate = TDA18271_GATE_DIGITAL,
1081 .small_i2c = 1,
1082};
1083
1084static struct mxl5005s_config af9015_mxl5003_config = {
1085 .i2c_address = 0xc6,
1086 .if_freq = IF_FREQ_4570000HZ,
1087 .xtal_freq = CRYSTAL_FREQ_16000000HZ,
1088 .agc_mode = MXL_SINGLE_AGC,
1089 .tracking_filter = MXL_TF_DEFAULT,
1090 .rssi_enable = MXL_RSSI_ENABLE,
1091 .cap_select = MXL_CAP_SEL_ENABLE,
1092 .div_out = MXL_DIV_OUT_4,
1093 .clock_out = MXL_CLOCK_OUT_DISABLE,
1094 .output_load = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
1095 .top = MXL5005S_TOP_25P2,
1096 .mod_mode = MXL_DIGITAL_MODE,
1097 .if_mode = MXL_ZERO_IF,
1098 .AgcMasterByte = 0x00,
1099};
1100
1101static struct mxl5005s_config af9015_mxl5005_config = {
1102 .i2c_address = 0xc6,
1103 .if_freq = IF_FREQ_4570000HZ,
1104 .xtal_freq = CRYSTAL_FREQ_16000000HZ,
1105 .agc_mode = MXL_SINGLE_AGC,
1106 .tracking_filter = MXL_TF_OFF,
1107 .rssi_enable = MXL_RSSI_ENABLE,
1108 .cap_select = MXL_CAP_SEL_ENABLE,
1109 .div_out = MXL_DIV_OUT_4,
1110 .clock_out = MXL_CLOCK_OUT_DISABLE,
1111 .output_load = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
1112 .top = MXL5005S_TOP_25P2,
1113 .mod_mode = MXL_DIGITAL_MODE,
1114 .if_mode = MXL_ZERO_IF,
1115 .AgcMasterByte = 0x00,
1116};
1117
1118static int af9015_tuner_attach(struct dvb_usb_adapter *adap)
1119{
1120 struct af9015_state *state = adap->dev->priv;
1121 struct i2c_adapter *i2c_adap;
1122 int ret;
1123 deb_info("%s: \n", __func__);
1124
1125 /* select I2C adapter */
1126 if (adap->id == 0)
1127 i2c_adap = &adap->dev->i2c_adap;
1128 else
1129 i2c_adap = &state->i2c_adap;
1130
1131 switch (af9015_af9013_config[adap->id].tuner) {
1132 case AF9013_TUNER_MT2060:
1133 case AF9013_TUNER_MT2060_2:
1134 ret = dvb_attach(mt2060_attach, adap->fe, i2c_adap,
1135 &af9015_mt2060_config,
1136 af9015_config.mt2060_if1[adap->id])
1137 == NULL ? -ENODEV : 0;
1138 break;
1139 case AF9013_TUNER_QT1010:
1140 case AF9013_TUNER_QT1010A:
1141 ret = dvb_attach(qt1010_attach, adap->fe, i2c_adap,
1142 &af9015_qt1010_config) == NULL ? -ENODEV : 0;
1143 break;
1144 case AF9013_TUNER_TDA18271:
1145 ret = dvb_attach(tda18271_attach, adap->fe, 0xc0, i2c_adap,
1146 &af9015_tda18271_config) == NULL ? -ENODEV : 0;
1147 break;
1148 case AF9013_TUNER_MXL5003D:
1149 ret = dvb_attach(mxl5005s_attach, adap->fe, i2c_adap,
1150 &af9015_mxl5003_config) == NULL ? -ENODEV : 0;
1151 break;
1152 case AF9013_TUNER_MXL5005D:
1153 case AF9013_TUNER_MXL5005R:
1154 ret = dvb_attach(mxl5005s_attach, adap->fe, i2c_adap,
1155 &af9015_mxl5005_config) == NULL ? -ENODEV : 0;
1156 break;
1157 case AF9013_TUNER_ENV77H11D5:
1158 ret = dvb_attach(dvb_pll_attach, adap->fe, 0xc0, i2c_adap,
1159 DVB_PLL_TDA665X) == NULL ? -ENODEV : 0;
1160 break;
1161 case AF9013_TUNER_MC44S803:
1162#if 0
1163 ret = dvb_attach(mc44s80x_attach, adap->fe, i2c_adap)
1164 == NULL ? -ENODEV : 0;
1165#else
1166 ret = -ENODEV;
1167 info("Freescale MC44S803 tuner found but no driver for that" \
1168 "tuner. Look at the Linuxtv.org for tuner driver" \
1169 "status.");
1170#endif
1171 break;
1172 case AF9013_TUNER_UNKNOWN:
1173 default:
1174 ret = -ENODEV;
1175 err("Unknown tuner id:%d",
1176 af9015_af9013_config[adap->id].tuner);
1177 }
1178 return ret;
1179}
1180
1181static struct usb_device_id af9015_usb_table[] = {
1182/* 0 */{USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9015_9015)},
1183 {USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9015_9016)},
1184 {USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_GOLD)},
1185 {USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV71E)},
1186 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_399U)},
1187/* 5 */{USB_DEVICE(USB_VID_VISIONPLUS,
1188 USB_PID_TINYTWIN)},
1189 {USB_DEVICE(USB_VID_VISIONPLUS,
1190 USB_PID_AZUREWAVE_AD_TU700)},
1191 {USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_USB_XE_REV2)},
1192 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_PC160_2T)},
1193 {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_X)},
1194/* 10 */{USB_DEVICE(USB_VID_XTENSIONS, USB_PID_XTENSIONS_XD_380)},
1195 {USB_DEVICE(USB_VID_MSI_2, USB_PID_MSI_DIGIVOX_DUO)},
1196 {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_X_2)},
1197 {USB_DEVICE(USB_VID_TELESTAR, USB_PID_TELESTAR_STARSTICK_2)},
1198 {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A309)},
1199/* 15 */{USB_DEVICE(USB_VID_MSI_2, USB_PID_MSI_DIGI_VOX_MINI_III)},
1200 {0},
1201};
1202MODULE_DEVICE_TABLE(usb, af9015_usb_table);
1203
1204static struct dvb_usb_device_properties af9015_properties[] = {
1205 {
1206 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1207
1208 .usb_ctrl = DEVICE_SPECIFIC,
1209 .download_firmware = af9015_download_firmware,
1210 .firmware = "dvb-usb-af9015.fw",
1211
1212 .size_of_priv = sizeof(struct af9015_state), \
1213
1214 .num_adapters = 2,
1215 .adapter = {
1216 {
1217 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
1218 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
1219
1220 .pid_filter_count = 32,
1221 .pid_filter = af9015_pid_filter,
1222 .pid_filter_ctrl = af9015_pid_filter_ctrl,
1223
1224 .frontend_attach =
1225 af9015_af9013_frontend_attach,
1226 .tuner_attach = af9015_tuner_attach,
1227 .stream = {
1228 .type = USB_BULK,
1229 .count = 6,
1230 .endpoint = 0x84,
1231 },
1232 },
1233 {
1234 .frontend_attach =
1235 af9015_af9013_frontend_attach,
1236 .tuner_attach = af9015_tuner_attach,
1237 .stream = {
1238 .type = USB_BULK,
1239 .count = 6,
1240 .endpoint = 0x85,
1241 },
1242 }
1243 },
1244
1245 .identify_state = af9015_identify_state,
1246
1247 .rc_query = af9015_rc_query,
1248 .rc_interval = 150,
1249
1250 .i2c_algo = &af9015_i2c_algo,
1251
1252 .num_device_descs = 9,
1253 .devices = {
1254 {
1255 .name = "Afatech AF9015 DVB-T USB2.0 stick",
1256 .cold_ids = {&af9015_usb_table[0],
1257 &af9015_usb_table[1], NULL},
1258 .warm_ids = {NULL},
1259 },
1260 {
1261 .name = "Leadtek WinFast DTV Dongle Gold",
1262 .cold_ids = {&af9015_usb_table[2], NULL},
1263 .warm_ids = {NULL},
1264 },
1265 {
1266 .name = "Pinnacle PCTV 71e",
1267 .cold_ids = {&af9015_usb_table[3], NULL},
1268 .warm_ids = {NULL},
1269 },
1270 {
1271 .name = "KWorld PlusTV Dual DVB-T Stick " \
1272 "(DVB-T 399U)",
1273 .cold_ids = {&af9015_usb_table[4], NULL},
1274 .warm_ids = {NULL},
1275 },
1276 {
1277 .name = "DigitalNow TinyTwin DVB-T Receiver",
1278 .cold_ids = {&af9015_usb_table[5], NULL},
1279 .warm_ids = {NULL},
1280 },
1281 {
1282 .name = "TwinHan AzureWave AD-TU700(704J)",
1283 .cold_ids = {&af9015_usb_table[6], NULL},
1284 .warm_ids = {NULL},
1285 },
1286 {
1287 .name = "TerraTec Cinergy T USB XE",
1288 .cold_ids = {&af9015_usb_table[7], NULL},
1289 .warm_ids = {NULL},
1290 },
1291 {
1292 .name = "KWorld PlusTV Dual DVB-T PCI " \
1293 "(DVB-T PC160-2T)",
1294 .cold_ids = {&af9015_usb_table[8], NULL},
1295 .warm_ids = {NULL},
1296 },
1297 {
1298 .name = "AVerMedia AVerTV DVB-T Volar X",
1299 .cold_ids = {&af9015_usb_table[9], NULL},
1300 .warm_ids = {NULL},
1301 },
1302 }
1303 }, {
1304 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1305
1306 .usb_ctrl = DEVICE_SPECIFIC,
1307 .download_firmware = af9015_download_firmware,
1308 .firmware = "dvb-usb-af9015.fw",
1309
1310 .size_of_priv = sizeof(struct af9015_state), \
1311
1312 .num_adapters = 2,
1313 .adapter = {
1314 {
1315 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
1316 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
1317
1318 .pid_filter_count = 32,
1319 .pid_filter = af9015_pid_filter,
1320 .pid_filter_ctrl = af9015_pid_filter_ctrl,
1321
1322 .frontend_attach =
1323 af9015_af9013_frontend_attach,
1324 .tuner_attach = af9015_tuner_attach,
1325 .stream = {
1326 .type = USB_BULK,
1327 .count = 6,
1328 .endpoint = 0x84,
1329 },
1330 },
1331 {
1332 .frontend_attach =
1333 af9015_af9013_frontend_attach,
1334 .tuner_attach = af9015_tuner_attach,
1335 .stream = {
1336 .type = USB_BULK,
1337 .count = 6,
1338 .endpoint = 0x85,
1339 },
1340 }
1341 },
1342
1343 .identify_state = af9015_identify_state,
1344
1345 .rc_query = af9015_rc_query,
1346 .rc_interval = 150,
1347
1348 .i2c_algo = &af9015_i2c_algo,
1349
1350 .num_device_descs = 6,
1351 .devices = {
1352 {
1353 .name = "Xtensions XD-380",
1354 .cold_ids = {&af9015_usb_table[10], NULL},
1355 .warm_ids = {NULL},
1356 },
1357 {
1358 .name = "MSI DIGIVOX Duo",
1359 .cold_ids = {&af9015_usb_table[11], NULL},
1360 .warm_ids = {NULL},
1361 },
1362 {
1363 .name = "Fujitsu-Siemens Slim Mobile USB DVB-T",
1364 .cold_ids = {&af9015_usb_table[12], NULL},
1365 .warm_ids = {NULL},
1366 },
1367 {
1368 .name = "Telestar Starstick 2",
1369 .cold_ids = {&af9015_usb_table[13], NULL},
1370 .warm_ids = {NULL},
1371 },
1372 {
1373 .name = "AVerMedia A309",
1374 .cold_ids = {&af9015_usb_table[14], NULL},
1375 .warm_ids = {NULL},
1376 },
1377 {
1378 .name = "MSI Digi VOX mini III",
1379 .cold_ids = {&af9015_usb_table[15], NULL},
1380 .warm_ids = {NULL},
1381 },
1382 }
1383 }
1384};
1385
1386static int af9015_usb_probe(struct usb_interface *intf,
1387 const struct usb_device_id *id)
1388{
1389 int ret = 0;
1390 struct dvb_usb_device *d = NULL;
1391 struct usb_device *udev = interface_to_usbdev(intf);
1392 u8 i;
1393
1394 deb_info("%s: interface:%d\n", __func__,
1395 intf->cur_altsetting->desc.bInterfaceNumber);
1396
1397 /* interface 0 is used by DVB-T receiver and
1398 interface 1 is for remote controller (HID) */
1399 if (intf->cur_altsetting->desc.bInterfaceNumber == 0) {
1400 ret = af9015_read_config(udev);
1401 if (ret)
1402 return ret;
1403
1404 for (i = 0; i < af9015_properties_count; i++) {
1405 ret = dvb_usb_device_init(intf, &af9015_properties[i],
1406 THIS_MODULE, &d, adapter_nr);
1407 if (!ret)
1408 break;
1409 if (ret != -ENODEV)
1410 return ret;
1411 }
1412 if (ret)
1413 return ret;
1414
1415 if (d)
1416 ret = af9015_init(d);
1417 }
1418
1419 return ret;
1420}
1421
1422void af9015_i2c_exit(struct dvb_usb_device *d)
1423{
1424 struct af9015_state *state = d->priv;
1425 deb_info("%s: \n", __func__);
1426
1427 /* remove 2nd I2C adapter */
1428 if (d->state & DVB_USB_STATE_I2C)
1429 i2c_del_adapter(&state->i2c_adap);
1430}
1431
1432static void af9015_usb_device_exit(struct usb_interface *intf)
1433{
1434 struct dvb_usb_device *d = usb_get_intfdata(intf);
1435 deb_info("%s: \n", __func__);
1436
1437 /* remove 2nd I2C adapter */
1438 if (d != NULL && d->desc != NULL)
1439 af9015_i2c_exit(d);
1440
1441 dvb_usb_device_exit(intf);
1442}
1443
1444/* usb specific object needed to register this driver with the usb subsystem */
1445static struct usb_driver af9015_usb_driver = {
1446 .name = "dvb_usb_af9015",
1447 .probe = af9015_usb_probe,
1448 .disconnect = af9015_usb_device_exit,
1449 .id_table = af9015_usb_table,
1450};
1451
1452/* module stuff */
1453static int __init af9015_usb_module_init(void)
1454{
1455 int ret;
1456 ret = usb_register(&af9015_usb_driver);
1457 if (ret)
1458 err("module init failed:%d", ret);
1459
1460 return ret;
1461}
1462
1463static void __exit af9015_usb_module_exit(void)
1464{
1465 /* deregister this driver from the USB subsystem */
1466 usb_deregister(&af9015_usb_driver);
1467}
1468
1469module_init(af9015_usb_module_init);
1470module_exit(af9015_usb_module_exit);
1471
1472MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
1473MODULE_DESCRIPTION("Driver for Afatech AF9015 DVB-T");
1474MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/af9015.h b/drivers/media/dvb/dvb-usb/af9015.h
new file mode 100644
index 000000000000..882e8a4b3681
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/af9015.h
@@ -0,0 +1,524 @@
1/*
2 * DVB USB Linux driver for Afatech AF9015 DVB-T USB2.0 receiver
3 *
4 * Copyright (C) 2007 Antti Palosaari <crope@iki.fi>
5 *
6 * Thanks to Afatech who kindly provided information.
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
24#ifndef _DVB_USB_AF9015_H_
25#define _DVB_USB_AF9015_H_
26
27#define DVB_USB_LOG_PREFIX "af9015"
28#include "dvb-usb.h"
29
30extern int dvb_usb_af9015_debug;
31#define deb_info(args...) dprintk(dvb_usb_af9015_debug, 0x01, args)
32#define deb_rc(args...) dprintk(dvb_usb_af9015_debug, 0x02, args)
33#define deb_xfer(args...) dprintk(dvb_usb_af9015_debug, 0x04, args)
34#define deb_reg(args...) dprintk(dvb_usb_af9015_debug, 0x08, args)
35#define deb_i2c(args...) dprintk(dvb_usb_af9015_debug, 0x10, args)
36#define deb_fw(args...) dprintk(dvb_usb_af9015_debug, 0x20, args)
37
38#define AF9015_I2C_EEPROM 0xa0
39#define AF9015_I2C_DEMOD 0x38
40#define AF9015_USB_TIMEOUT 2000
41
42/* EEPROM locations */
43#define AF9015_EEPROM_IR_MODE 0x18
44#define AF9015_EEPROM_IR_REMOTE_TYPE 0x34
45#define AF9015_EEPROM_TS_MODE 0x31
46#define AF9015_EEPROM_DEMOD2_I2C 0x32
47
48#define AF9015_EEPROM_SAW_BW1 0x35
49#define AF9015_EEPROM_XTAL_TYPE1 0x36
50#define AF9015_EEPROM_SPEC_INV1 0x37
51#define AF9015_EEPROM_IF1L 0x38
52#define AF9015_EEPROM_IF1H 0x39
53#define AF9015_EEPROM_MT2060_IF1L 0x3a
54#define AF9015_EEPROM_MT2060_IF1H 0x3b
55#define AF9015_EEPROM_TUNER_ID1 0x3c
56
57#define AF9015_EEPROM_SAW_BW2 0x45
58#define AF9015_EEPROM_XTAL_TYPE2 0x46
59#define AF9015_EEPROM_SPEC_INV2 0x47
60#define AF9015_EEPROM_IF2L 0x48
61#define AF9015_EEPROM_IF2H 0x49
62#define AF9015_EEPROM_MT2060_IF2L 0x4a
63#define AF9015_EEPROM_MT2060_IF2H 0x4b
64#define AF9015_EEPROM_TUNER_ID2 0x4c
65
66#define AF9015_EEPROM_OFFSET (AF9015_EEPROM_SAW_BW2 - AF9015_EEPROM_SAW_BW1)
67
68#define AF9015_GPIO_ON (1 << 0)
69#define AF9015_GPIO_EN (1 << 1)
70#define AF9015_GPIO_O (1 << 2)
71#define AF9015_GPIO_I (1 << 3)
72
73#define AF9015_GPIO_TUNER_ON (AF9015_GPIO_ON|AF9015_GPIO_EN)
74#define AF9015_GPIO_TUNER_OFF (AF9015_GPIO_ON|AF9015_GPIO_EN|AF9015_GPIO_O)
75
76struct req_t {
77 u8 cmd; /* [0] */
78 /* seq */ /* [1] */
79 u8 i2c_addr; /* [2] */
80 u16 addr; /* [3|4] */
81 u8 mbox; /* [5] */
82 u8 addr_len; /* [6] */
83 u8 data_len; /* [7] */
84 u8 *data;
85};
86
87enum af9015_cmd {
88 GET_CONFIG = 0x10,
89 DOWNLOAD_FIRMWARE = 0x11,
90 BOOT = 0x13,
91 READ_MEMORY = 0x20,
92 WRITE_MEMORY = 0x21,
93 READ_WRITE_I2C = 0x22,
94 COPY_FIRMWARE = 0x23,
95 RECONNECT_USB = 0x5a,
96 WRITE_VIRTUAL_MEMORY = 0x26,
97 GET_IR_CODE = 0x27,
98 READ_I2C,
99 WRITE_I2C,
100};
101
102enum af9015_ir_mode {
103 AF9015_IR_MODE_DISABLED = 0,
104 AF9015_IR_MODE_HID,
105 AF9015_IR_MODE_RLC,
106 AF9015_IR_MODE_RC6,
107};
108
109struct af9015_state {
110 struct i2c_adapter i2c_adap; /* I2C adapter for 2nd FE */
111};
112
113struct af9015_config {
114 u8 dual_mode:1;
115 u16 mt2060_if1[2];
116 u16 firmware_size;
117 u16 firmware_checksum;
118 u8 *ir_table;
119 u16 ir_table_size;
120};
121
122enum af9015_remote {
123 AF9015_REMOTE_NONE = 0,
124 AF9015_REMOTE_A_LINK_DTU_M,
125 AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3,
126 AF9015_REMOTE_MYGICTV_U718,
127};
128
129/* Leadtek WinFast DTV Dongle Gold */
130static struct dvb_usb_rc_key af9015_rc_keys_leadtek[] = {
131 { 0x00, 0x1e, KEY_1 },
132 { 0x00, 0x1f, KEY_2 },
133 { 0x00, 0x20, KEY_3 },
134 { 0x00, 0x21, KEY_4 },
135 { 0x00, 0x22, KEY_5 },
136 { 0x00, 0x23, KEY_6 },
137 { 0x00, 0x24, KEY_7 },
138 { 0x00, 0x25, KEY_8 },
139 { 0x00, 0x26, KEY_9 },
140 { 0x00, 0x27, KEY_0 },
141 { 0x00, 0x28, KEY_ENTER },
142 { 0x00, 0x4f, KEY_VOLUMEUP },
143 { 0x00, 0x50, KEY_VOLUMEDOWN },
144 { 0x00, 0x51, KEY_CHANNELDOWN },
145 { 0x00, 0x52, KEY_CHANNELUP },
146};
147
148static u8 af9015_ir_table_leadtek[] = {
149 0x03, 0xfc, 0x00, 0xff, 0x1a, 0x01, 0x00,
150 0x03, 0xfc, 0x56, 0xa9, 0x00, 0x00, 0x00,
151 0x03, 0xfc, 0x4b, 0xb4, 0x00, 0x00, 0x00,
152 0x03, 0xfc, 0x4c, 0xb3, 0xb2, 0x04, 0x00,
153 0x03, 0xfc, 0x4d, 0xb2, 0x00, 0x00, 0x00,
154 0x03, 0xfc, 0x4e, 0xb1, 0x00, 0x00, 0x00,
155 0x03, 0xfc, 0x1f, 0xe0, 0x3d, 0x00, 0x00,
156 0x03, 0xfc, 0x40, 0xbf, 0x13, 0x01, 0x00,
157 0x03, 0xfc, 0x14, 0xeb, 0x10, 0x00, 0x00,
158 0x03, 0xfc, 0x49, 0xb6, 0x05, 0x01, 0x00,
159 0x03, 0xfc, 0x50, 0xaf, 0x29, 0x00, 0x00,
160 0x03, 0xfc, 0x0c, 0xf3, 0x52, 0x00, 0x00,
161 0x03, 0xfc, 0x03, 0xfc, 0x09, 0x00, 0x00,
162 0x03, 0xfc, 0x08, 0xf7, 0x50, 0x00, 0x00,
163 0x03, 0xfc, 0x13, 0xec, 0x28, 0x00, 0x00,
164 0x03, 0xfc, 0x04, 0xfb, 0x4f, 0x00, 0x00,
165 0x03, 0xfc, 0x4f, 0xb0, 0x0f, 0x01, 0x00,
166 0x03, 0xfc, 0x10, 0xef, 0x51, 0x00, 0x00,
167 0x03, 0xfc, 0x51, 0xae, 0x3f, 0x00, 0x00,
168 0x03, 0xfc, 0x42, 0xbd, 0x13, 0x00, 0x00,
169 0x03, 0xfc, 0x43, 0xbc, 0x00, 0x00, 0x00,
170 0x03, 0xfc, 0x44, 0xbb, 0x11, 0x00, 0x00,
171 0x03, 0xfc, 0x52, 0xad, 0x19, 0x00, 0x00,
172 0x03, 0xfc, 0x54, 0xab, 0x05, 0x00, 0x00,
173 0x03, 0xfc, 0x46, 0xb9, 0x29, 0x00, 0x00,
174 0x03, 0xfc, 0x55, 0xaa, 0x2b, 0x00, 0x00,
175 0x03, 0xfc, 0x53, 0xac, 0x41, 0x00, 0x00,
176 0x03, 0xfc, 0x05, 0xfa, 0x1e, 0x00, 0x00,
177 0x03, 0xfc, 0x06, 0xf9, 0x1f, 0x00, 0x00,
178 0x03, 0xfc, 0x07, 0xf8, 0x20, 0x00, 0x00,
179 0x03, 0xfc, 0x1e, 0xe1, 0x19, 0x00, 0x00,
180 0x03, 0xfc, 0x09, 0xf6, 0x21, 0x00, 0x00,
181 0x03, 0xfc, 0x0a, 0xf5, 0x22, 0x00, 0x00,
182 0x03, 0xfc, 0x0b, 0xf4, 0x23, 0x00, 0x00,
183 0x03, 0xfc, 0x1b, 0xe4, 0x16, 0x00, 0x00,
184 0x03, 0xfc, 0x0d, 0xf2, 0x24, 0x00, 0x00,
185 0x03, 0xfc, 0x0e, 0xf1, 0x25, 0x00, 0x00,
186 0x03, 0xfc, 0x0f, 0xf0, 0x26, 0x00, 0x00,
187 0x03, 0xfc, 0x16, 0xe9, 0x28, 0x00, 0x00,
188 0x03, 0xfc, 0x41, 0xbe, 0x37, 0x00, 0x00,
189 0x03, 0xfc, 0x12, 0xed, 0x27, 0x00, 0x00,
190 0x03, 0xfc, 0x11, 0xee, 0x2a, 0x00, 0x00,
191 0x03, 0xfc, 0x48, 0xb7, 0x2c, 0x00, 0x00,
192 0x03, 0xfc, 0x4a, 0xb5, 0x3c, 0x00, 0x00,
193 0x03, 0xfc, 0x47, 0xb8, 0x15, 0x01, 0x00,
194 0x03, 0xfc, 0x45, 0xba, 0x0b, 0x01, 0x00,
195 0x03, 0xfc, 0x5e, 0xa1, 0x43, 0x00, 0x00,
196 0x03, 0xfc, 0x5a, 0xa5, 0x42, 0x00, 0x00,
197 0x03, 0xfc, 0x5b, 0xa4, 0x4b, 0x00, 0x00,
198 0x03, 0xfc, 0x5f, 0xa0, 0x4e, 0x00, 0x00,
199};
200
201/* TwinHan AzureWave AD-TU700(704J) */
202static struct dvb_usb_rc_key af9015_rc_keys_twinhan[] = {
203 { 0x05, 0x3f, KEY_POWER },
204 { 0x00, 0x19, KEY_FAVORITES }, /* Favorite List */
205 { 0x00, 0x04, KEY_TEXT }, /* Teletext */
206 { 0x00, 0x0e, KEY_POWER },
207 { 0x00, 0x0e, KEY_INFO }, /* Preview */
208 { 0x00, 0x08, KEY_EPG }, /* Info/EPG */
209 { 0x00, 0x0f, KEY_LIST }, /* Record List */
210 { 0x00, 0x1e, KEY_1 },
211 { 0x00, 0x1f, KEY_2 },
212 { 0x00, 0x20, KEY_3 },
213 { 0x00, 0x21, KEY_4 },
214 { 0x00, 0x22, KEY_5 },
215 { 0x00, 0x23, KEY_6 },
216 { 0x00, 0x24, KEY_7 },
217 { 0x00, 0x25, KEY_8 },
218 { 0x00, 0x26, KEY_9 },
219 { 0x00, 0x27, KEY_0 },
220 { 0x00, 0x29, KEY_CANCEL }, /* Cancel */
221 { 0x00, 0x4c, KEY_CLEAR }, /* Clear */
222 { 0x00, 0x2a, KEY_BACK }, /* Back */
223 { 0x00, 0x2b, KEY_TAB }, /* Tab */
224 { 0x00, 0x52, KEY_UP }, /* up arrow */
225 { 0x00, 0x51, KEY_DOWN }, /* down arrow */
226 { 0x00, 0x4f, KEY_RIGHT }, /* right arrow */
227 { 0x00, 0x50, KEY_LEFT }, /* left arrow */
228 { 0x00, 0x28, KEY_ENTER }, /* Enter / ok */
229 { 0x02, 0x52, KEY_VOLUMEUP },
230 { 0x02, 0x51, KEY_VOLUMEDOWN },
231 { 0x00, 0x4e, KEY_CHANNELDOWN },
232 { 0x00, 0x4b, KEY_CHANNELUP },
233 { 0x00, 0x4a, KEY_RECORD },
234 { 0x01, 0x11, KEY_PLAY },
235 { 0x00, 0x17, KEY_PAUSE },
236 { 0x00, 0x0c, KEY_REWIND }, /* FR << */
237 { 0x00, 0x11, KEY_FASTFORWARD }, /* FF >> */
238 { 0x01, 0x15, KEY_PREVIOUS }, /* Replay */
239 { 0x01, 0x0e, KEY_NEXT }, /* Skip */
240 { 0x00, 0x13, KEY_CAMERA }, /* Capture */
241 { 0x01, 0x0f, KEY_LANGUAGE }, /* SAP */
242 { 0x01, 0x13, KEY_TV2 }, /* PIP */
243 { 0x00, 0x1d, KEY_ZOOM }, /* Full Screen */
244 { 0x01, 0x17, KEY_SUBTITLE }, /* Subtitle / CC */
245 { 0x00, 0x10, KEY_MUTE },
246 { 0x01, 0x19, KEY_AUDIO }, /* L/R */ /* TODO better event */
247 { 0x01, 0x16, KEY_SLEEP }, /* Hibernate */
248 { 0x01, 0x16, KEY_SWITCHVIDEOMODE },
249 /* A/V */ /* TODO does not work */
250 { 0x00, 0x06, KEY_AGAIN }, /* Recall */
251 { 0x01, 0x16, KEY_KPPLUS }, /* Zoom+ */ /* TODO does not work */
252 { 0x01, 0x16, KEY_KPMINUS }, /* Zoom- */ /* TODO does not work */
253 { 0x02, 0x15, KEY_RED },
254 { 0x02, 0x0a, KEY_GREEN },
255 { 0x02, 0x1c, KEY_YELLOW },
256 { 0x02, 0x05, KEY_BLUE },
257};
258
259static u8 af9015_ir_table_twinhan[] = {
260 0x00, 0xff, 0x16, 0xe9, 0x3f, 0x05, 0x00,
261 0x00, 0xff, 0x07, 0xf8, 0x16, 0x01, 0x00,
262 0x00, 0xff, 0x14, 0xeb, 0x11, 0x01, 0x00,
263 0x00, 0xff, 0x1a, 0xe5, 0x4d, 0x00, 0x00,
264 0x00, 0xff, 0x4c, 0xb3, 0x17, 0x00, 0x00,
265 0x00, 0xff, 0x12, 0xed, 0x11, 0x00, 0x00,
266 0x00, 0xff, 0x40, 0xbf, 0x0c, 0x00, 0x00,
267 0x00, 0xff, 0x11, 0xee, 0x4a, 0x00, 0x00,
268 0x00, 0xff, 0x54, 0xab, 0x13, 0x00, 0x00,
269 0x00, 0xff, 0x41, 0xbe, 0x15, 0x01, 0x00,
270 0x00, 0xff, 0x42, 0xbd, 0x0e, 0x01, 0x00,
271 0x00, 0xff, 0x43, 0xbc, 0x17, 0x01, 0x00,
272 0x00, 0xff, 0x50, 0xaf, 0x0f, 0x01, 0x00,
273 0x00, 0xff, 0x4d, 0xb2, 0x1d, 0x00, 0x00,
274 0x00, 0xff, 0x47, 0xb8, 0x13, 0x01, 0x00,
275 0x00, 0xff, 0x05, 0xfa, 0x4b, 0x00, 0x00,
276 0x00, 0xff, 0x02, 0xfd, 0x4e, 0x00, 0x00,
277 0x00, 0xff, 0x0e, 0xf1, 0x06, 0x00, 0x00,
278 0x00, 0xff, 0x1e, 0xe1, 0x52, 0x02, 0x00,
279 0x00, 0xff, 0x0a, 0xf5, 0x51, 0x02, 0x00,
280 0x00, 0xff, 0x10, 0xef, 0x10, 0x00, 0x00,
281 0x00, 0xff, 0x49, 0xb6, 0x19, 0x01, 0x00,
282 0x00, 0xff, 0x15, 0xea, 0x27, 0x00, 0x00,
283 0x00, 0xff, 0x03, 0xfc, 0x1e, 0x00, 0x00,
284 0x00, 0xff, 0x01, 0xfe, 0x1f, 0x00, 0x00,
285 0x00, 0xff, 0x06, 0xf9, 0x20, 0x00, 0x00,
286 0x00, 0xff, 0x09, 0xf6, 0x21, 0x00, 0x00,
287 0x00, 0xff, 0x1d, 0xe2, 0x22, 0x00, 0x00,
288 0x00, 0xff, 0x1f, 0xe0, 0x23, 0x00, 0x00,
289 0x00, 0xff, 0x0d, 0xf2, 0x24, 0x00, 0x00,
290 0x00, 0xff, 0x19, 0xe6, 0x25, 0x00, 0x00,
291 0x00, 0xff, 0x1b, 0xe4, 0x26, 0x00, 0x00,
292 0x00, 0xff, 0x00, 0xff, 0x2b, 0x00, 0x00,
293 0x00, 0xff, 0x4a, 0xb5, 0x4c, 0x00, 0x00,
294 0x00, 0xff, 0x4b, 0xb4, 0x52, 0x00, 0x00,
295 0x00, 0xff, 0x51, 0xae, 0x51, 0x00, 0x00,
296 0x00, 0xff, 0x52, 0xad, 0x4f, 0x00, 0x00,
297 0x00, 0xff, 0x4e, 0xb1, 0x50, 0x00, 0x00,
298 0x00, 0xff, 0x0c, 0xf3, 0x29, 0x00, 0x00,
299 0x00, 0xff, 0x4f, 0xb0, 0x28, 0x00, 0x00,
300 0x00, 0xff, 0x13, 0xec, 0x2a, 0x00, 0x00,
301 0x00, 0xff, 0x17, 0xe8, 0x19, 0x00, 0x00,
302 0x00, 0xff, 0x04, 0xfb, 0x0f, 0x00, 0x00,
303 0x00, 0xff, 0x48, 0xb7, 0x0e, 0x00, 0x00,
304 0x00, 0xff, 0x0f, 0xf0, 0x04, 0x00, 0x00,
305 0x00, 0xff, 0x1c, 0xe3, 0x08, 0x00, 0x00,
306 0x00, 0xff, 0x18, 0xe7, 0x15, 0x02, 0x00,
307 0x00, 0xff, 0x53, 0xac, 0x0a, 0x02, 0x00,
308 0x00, 0xff, 0x5e, 0xa1, 0x1c, 0x02, 0x00,
309 0x00, 0xff, 0x5f, 0xa0, 0x05, 0x02, 0x00,
310};
311
312/* A-Link DTU(m) */
313static struct dvb_usb_rc_key af9015_rc_keys_a_link[] = {
314 { 0x00, 0x1e, KEY_1 },
315 { 0x00, 0x1f, KEY_2 },
316 { 0x00, 0x20, KEY_3 },
317 { 0x00, 0x21, KEY_4 },
318 { 0x00, 0x22, KEY_5 },
319 { 0x00, 0x23, KEY_6 },
320 { 0x00, 0x24, KEY_7 },
321 { 0x00, 0x25, KEY_8 },
322 { 0x00, 0x26, KEY_9 },
323 { 0x00, 0x27, KEY_0 },
324 { 0x00, 0x2e, KEY_CHANNELUP },
325 { 0x00, 0x2d, KEY_CHANNELDOWN },
326 { 0x04, 0x28, KEY_ZOOM },
327 { 0x00, 0x41, KEY_MUTE },
328 { 0x00, 0x42, KEY_VOLUMEDOWN },
329 { 0x00, 0x43, KEY_VOLUMEUP },
330 { 0x00, 0x44, KEY_GOTO }, /* jump */
331 { 0x05, 0x45, KEY_POWER },
332};
333
334static u8 af9015_ir_table_a_link[] = {
335 0x08, 0xf7, 0x12, 0xed, 0x45, 0x05, 0x00, /* power */
336 0x08, 0xf7, 0x1a, 0xe5, 0x41, 0x00, 0x00, /* mute */
337 0x08, 0xf7, 0x01, 0xfe, 0x1e, 0x00, 0x00, /* 1 */
338 0x08, 0xf7, 0x1c, 0xe3, 0x21, 0x00, 0x00, /* 4 */
339 0x08, 0xf7, 0x03, 0xfc, 0x24, 0x00, 0x00, /* 7 */
340 0x08, 0xf7, 0x05, 0xfa, 0x28, 0x04, 0x00, /* zoom */
341 0x08, 0xf7, 0x00, 0xff, 0x43, 0x00, 0x00, /* volume up */
342 0x08, 0xf7, 0x16, 0xe9, 0x42, 0x00, 0x00, /* volume down */
343 0x08, 0xf7, 0x0f, 0xf0, 0x1f, 0x00, 0x00, /* 2 */
344 0x08, 0xf7, 0x0d, 0xf2, 0x22, 0x00, 0x00, /* 5 */
345 0x08, 0xf7, 0x1b, 0xe4, 0x25, 0x00, 0x00, /* 8 */
346 0x08, 0xf7, 0x06, 0xf9, 0x27, 0x00, 0x00, /* 0 */
347 0x08, 0xf7, 0x14, 0xeb, 0x2e, 0x00, 0x00, /* channel up */
348 0x08, 0xf7, 0x1d, 0xe2, 0x2d, 0x00, 0x00, /* channel down */
349 0x08, 0xf7, 0x02, 0xfd, 0x20, 0x00, 0x00, /* 3 */
350 0x08, 0xf7, 0x18, 0xe7, 0x23, 0x00, 0x00, /* 6 */
351 0x08, 0xf7, 0x04, 0xfb, 0x26, 0x00, 0x00, /* 9 */
352 0x08, 0xf7, 0x07, 0xf8, 0x44, 0x00, 0x00, /* jump */
353};
354
355/* MSI DIGIVOX mini II V3.0 */
356static struct dvb_usb_rc_key af9015_rc_keys_msi[] = {
357 { 0x00, 0x1e, KEY_1 },
358 { 0x00, 0x1f, KEY_2 },
359 { 0x00, 0x20, KEY_3 },
360 { 0x00, 0x21, KEY_4 },
361 { 0x00, 0x22, KEY_5 },
362 { 0x00, 0x23, KEY_6 },
363 { 0x00, 0x24, KEY_7 },
364 { 0x00, 0x25, KEY_8 },
365 { 0x00, 0x26, KEY_9 },
366 { 0x00, 0x27, KEY_0 },
367 { 0x03, 0x0f, KEY_CHANNELUP },
368 { 0x03, 0x0e, KEY_CHANNELDOWN },
369 { 0x00, 0x42, KEY_VOLUMEDOWN },
370 { 0x00, 0x43, KEY_VOLUMEUP },
371 { 0x05, 0x45, KEY_POWER },
372 { 0x00, 0x52, KEY_UP }, /* up */
373 { 0x00, 0x51, KEY_DOWN }, /* down */
374 { 0x00, 0x28, KEY_ENTER },
375};
376
377static u8 af9015_ir_table_msi[] = {
378 0x03, 0xfc, 0x17, 0xe8, 0x45, 0x05, 0x00, /* power */
379 0x03, 0xfc, 0x0d, 0xf2, 0x51, 0x00, 0x00, /* down */
380 0x03, 0xfc, 0x03, 0xfc, 0x52, 0x00, 0x00, /* up */
381 0x03, 0xfc, 0x1a, 0xe5, 0x1e, 0x00, 0x00, /* 1 */
382 0x03, 0xfc, 0x02, 0xfd, 0x1f, 0x00, 0x00, /* 2 */
383 0x03, 0xfc, 0x04, 0xfb, 0x20, 0x00, 0x00, /* 3 */
384 0x03, 0xfc, 0x1c, 0xe3, 0x21, 0x00, 0x00, /* 4 */
385 0x03, 0xfc, 0x08, 0xf7, 0x22, 0x00, 0x00, /* 5 */
386 0x03, 0xfc, 0x1d, 0xe2, 0x23, 0x00, 0x00, /* 6 */
387 0x03, 0xfc, 0x11, 0xee, 0x24, 0x00, 0x00, /* 7 */
388 0x03, 0xfc, 0x0b, 0xf4, 0x25, 0x00, 0x00, /* 8 */
389 0x03, 0xfc, 0x10, 0xef, 0x26, 0x00, 0x00, /* 9 */
390 0x03, 0xfc, 0x09, 0xf6, 0x27, 0x00, 0x00, /* 0 */
391 0x03, 0xfc, 0x14, 0xeb, 0x43, 0x00, 0x00, /* volume up */
392 0x03, 0xfc, 0x1f, 0xe0, 0x42, 0x00, 0x00, /* volume down */
393 0x03, 0xfc, 0x15, 0xea, 0x0f, 0x03, 0x00, /* channel up */
394 0x03, 0xfc, 0x05, 0xfa, 0x0e, 0x03, 0x00, /* channel down */
395 0x03, 0xfc, 0x16, 0xe9, 0x28, 0x00, 0x00, /* enter */
396};
397
398/* MYGICTV U718 */
399static struct dvb_usb_rc_key af9015_rc_keys_mygictv[] = {
400 { 0x00, 0x3d, KEY_SWITCHVIDEOMODE },
401 /* TV / AV */
402 { 0x05, 0x45, KEY_POWER },
403 { 0x00, 0x1e, KEY_1 },
404 { 0x00, 0x1f, KEY_2 },
405 { 0x00, 0x20, KEY_3 },
406 { 0x00, 0x21, KEY_4 },
407 { 0x00, 0x22, KEY_5 },
408 { 0x00, 0x23, KEY_6 },
409 { 0x00, 0x24, KEY_7 },
410 { 0x00, 0x25, KEY_8 },
411 { 0x00, 0x26, KEY_9 },
412 { 0x00, 0x27, KEY_0 },
413 { 0x00, 0x41, KEY_MUTE },
414 { 0x00, 0x2a, KEY_ESC }, /* Esc */
415 { 0x00, 0x2e, KEY_CHANNELUP },
416 { 0x00, 0x2d, KEY_CHANNELDOWN },
417 { 0x00, 0x42, KEY_VOLUMEDOWN },
418 { 0x00, 0x43, KEY_VOLUMEUP },
419 { 0x00, 0x52, KEY_UP }, /* up arrow */
420 { 0x00, 0x51, KEY_DOWN }, /* down arrow */
421 { 0x00, 0x4f, KEY_RIGHT }, /* right arrow */
422 { 0x00, 0x50, KEY_LEFT }, /* left arrow */
423 { 0x00, 0x28, KEY_ENTER }, /* ok */
424 { 0x01, 0x15, KEY_RECORD },
425 { 0x03, 0x13, KEY_PLAY },
426 { 0x01, 0x13, KEY_PAUSE },
427 { 0x01, 0x16, KEY_STOP },
428 { 0x03, 0x07, KEY_REWIND }, /* FR << */
429 { 0x03, 0x09, KEY_FASTFORWARD }, /* FF >> */
430 { 0x00, 0x3b, KEY_TIME }, /* TimeShift */
431 { 0x00, 0x3e, KEY_CAMERA }, /* Snapshot */
432 { 0x03, 0x16, KEY_CYCLEWINDOWS }, /* yellow, min / max */
433 { 0x00, 0x00, KEY_ZOOM }, /* 'select' (?) */
434 { 0x03, 0x16, KEY_SHUFFLE }, /* Shuffle */
435 { 0x03, 0x45, KEY_POWER },
436};
437
438static u8 af9015_ir_table_mygictv[] = {
439 0x02, 0xbd, 0x0c, 0xf3, 0x3d, 0x00, 0x00, /* TV / AV */
440 0x02, 0xbd, 0x14, 0xeb, 0x45, 0x05, 0x00, /* power */
441 0x02, 0xbd, 0x00, 0xff, 0x1e, 0x00, 0x00, /* 1 */
442 0x02, 0xbd, 0x01, 0xfe, 0x1f, 0x00, 0x00, /* 2 */
443 0x02, 0xbd, 0x02, 0xfd, 0x20, 0x00, 0x00, /* 3 */
444 0x02, 0xbd, 0x03, 0xfc, 0x21, 0x00, 0x00, /* 4 */
445 0x02, 0xbd, 0x04, 0xfb, 0x22, 0x00, 0x00, /* 5 */
446 0x02, 0xbd, 0x05, 0xfa, 0x23, 0x00, 0x00, /* 6 */
447 0x02, 0xbd, 0x06, 0xf9, 0x24, 0x00, 0x00, /* 7 */
448 0x02, 0xbd, 0x07, 0xf8, 0x25, 0x00, 0x00, /* 8 */
449 0x02, 0xbd, 0x08, 0xf7, 0x26, 0x00, 0x00, /* 9 */
450 0x02, 0xbd, 0x09, 0xf6, 0x27, 0x00, 0x00, /* 0 */
451 0x02, 0xbd, 0x0a, 0xf5, 0x41, 0x00, 0x00, /* mute */
452 0x02, 0xbd, 0x1c, 0xe3, 0x2a, 0x00, 0x00, /* esc */
453 0x02, 0xbd, 0x1f, 0xe0, 0x43, 0x00, 0x00, /* volume up */
454 0x02, 0xbd, 0x12, 0xed, 0x52, 0x00, 0x00, /* up arrow */
455 0x02, 0xbd, 0x11, 0xee, 0x50, 0x00, 0x00, /* left arrow */
456 0x02, 0xbd, 0x15, 0xea, 0x28, 0x00, 0x00, /* ok */
457 0x02, 0xbd, 0x10, 0xef, 0x4f, 0x00, 0x00, /* right arrow */
458 0x02, 0xbd, 0x13, 0xec, 0x51, 0x00, 0x00, /* down arrow */
459 0x02, 0xbd, 0x0e, 0xf1, 0x42, 0x00, 0x00, /* volume down */
460 0x02, 0xbd, 0x19, 0xe6, 0x15, 0x01, 0x00, /* record */
461 0x02, 0xbd, 0x1e, 0xe1, 0x13, 0x03, 0x00, /* play */
462 0x02, 0xbd, 0x16, 0xe9, 0x16, 0x01, 0x00, /* stop */
463 0x02, 0xbd, 0x0b, 0xf4, 0x28, 0x04, 0x00, /* yellow, min / max */
464 0x02, 0xbd, 0x0f, 0xf0, 0x3b, 0x00, 0x00, /* time shift */
465 0x02, 0xbd, 0x18, 0xe7, 0x2e, 0x00, 0x00, /* channel up */
466 0x02, 0xbd, 0x1a, 0xe5, 0x2d, 0x00, 0x00, /* channel down */
467 0x02, 0xbd, 0x17, 0xe8, 0x3e, 0x00, 0x00, /* snapshot */
468 0x02, 0xbd, 0x40, 0xbf, 0x13, 0x01, 0x00, /* pause */
469 0x02, 0xbd, 0x41, 0xbe, 0x09, 0x03, 0x00, /* FF >> */
470 0x02, 0xbd, 0x42, 0xbd, 0x07, 0x03, 0x00, /* FR << */
471 0x02, 0xbd, 0x43, 0xbc, 0x00, 0x00, 0x00, /* 'select' (?) */
472 0x02, 0xbd, 0x44, 0xbb, 0x16, 0x03, 0x00, /* shuffle */
473 0x02, 0xbd, 0x45, 0xba, 0x45, 0x03, 0x00, /* power */
474};
475
476/* KWorld PlusTV Dual DVB-T Stick (DVB-T 399U) */
477static u8 af9015_ir_table_kworld[] = {
478 0x86, 0x6b, 0x0c, 0xf3, 0x2e, 0x07, 0x00,
479 0x86, 0x6b, 0x16, 0xe9, 0x2d, 0x07, 0x00,
480 0x86, 0x6b, 0x1d, 0xe2, 0x37, 0x07, 0x00,
481 0x86, 0x6b, 0x00, 0xff, 0x1e, 0x07, 0x00,
482 0x86, 0x6b, 0x01, 0xfe, 0x1f, 0x07, 0x00,
483 0x86, 0x6b, 0x02, 0xfd, 0x20, 0x07, 0x00,
484 0x86, 0x6b, 0x03, 0xfc, 0x21, 0x07, 0x00,
485 0x86, 0x6b, 0x04, 0xfb, 0x22, 0x07, 0x00,
486 0x86, 0x6b, 0x05, 0xfa, 0x23, 0x07, 0x00,
487 0x86, 0x6b, 0x06, 0xf9, 0x24, 0x07, 0x00,
488 0x86, 0x6b, 0x07, 0xf8, 0x25, 0x07, 0x00,
489 0x86, 0x6b, 0x08, 0xf7, 0x26, 0x07, 0x00,
490 0x86, 0x6b, 0x09, 0xf6, 0x4d, 0x07, 0x00,
491 0x86, 0x6b, 0x0a, 0xf5, 0x4e, 0x07, 0x00,
492 0x86, 0x6b, 0x14, 0xeb, 0x4f, 0x07, 0x00,
493 0x86, 0x6b, 0x1e, 0xe1, 0x50, 0x07, 0x00,
494 0x86, 0x6b, 0x17, 0xe8, 0x52, 0x07, 0x00,
495 0x86, 0x6b, 0x1f, 0xe0, 0x51, 0x07, 0x00,
496 0x86, 0x6b, 0x0e, 0xf1, 0x0b, 0x07, 0x00,
497 0x86, 0x6b, 0x20, 0xdf, 0x0c, 0x07, 0x00,
498 0x86, 0x6b, 0x42, 0xbd, 0x0d, 0x07, 0x00,
499 0x86, 0x6b, 0x0b, 0xf4, 0x0e, 0x07, 0x00,
500 0x86, 0x6b, 0x43, 0xbc, 0x0f, 0x07, 0x00,
501 0x86, 0x6b, 0x10, 0xef, 0x10, 0x07, 0x00,
502 0x86, 0x6b, 0x21, 0xde, 0x11, 0x07, 0x00,
503 0x86, 0x6b, 0x13, 0xec, 0x12, 0x07, 0x00,
504 0x86, 0x6b, 0x11, 0xee, 0x13, 0x07, 0x00,
505 0x86, 0x6b, 0x12, 0xed, 0x14, 0x07, 0x00,
506 0x86, 0x6b, 0x19, 0xe6, 0x15, 0x07, 0x00,
507 0x86, 0x6b, 0x1a, 0xe5, 0x16, 0x07, 0x00,
508 0x86, 0x6b, 0x1b, 0xe4, 0x17, 0x07, 0x00,
509 0x86, 0x6b, 0x4b, 0xb4, 0x18, 0x07, 0x00,
510 0x86, 0x6b, 0x40, 0xbf, 0x19, 0x07, 0x00,
511 0x86, 0x6b, 0x44, 0xbb, 0x1a, 0x07, 0x00,
512 0x86, 0x6b, 0x41, 0xbe, 0x1b, 0x07, 0x00,
513 0x86, 0x6b, 0x22, 0xdd, 0x1c, 0x07, 0x00,
514 0x86, 0x6b, 0x15, 0xea, 0x1d, 0x07, 0x00,
515 0x86, 0x6b, 0x0f, 0xf0, 0x3f, 0x07, 0x00,
516 0x86, 0x6b, 0x1c, 0xe3, 0x40, 0x07, 0x00,
517 0x86, 0x6b, 0x4a, 0xb5, 0x41, 0x07, 0x00,
518 0x86, 0x6b, 0x48, 0xb7, 0x42, 0x07, 0x00,
519 0x86, 0x6b, 0x49, 0xb6, 0x43, 0x07, 0x00,
520 0x86, 0x6b, 0x18, 0xe7, 0x44, 0x07, 0x00,
521 0x86, 0x6b, 0x23, 0xdc, 0x45, 0x07, 0x00,
522};
523
524#endif
diff --git a/drivers/media/dvb/dvb-usb/anysee.c b/drivers/media/dvb/dvb-usb/anysee.c
index 2f408d2e1ef3..c786359fba03 100644
--- a/drivers/media/dvb/dvb-usb/anysee.c
+++ b/drivers/media/dvb/dvb-usb/anysee.c
@@ -41,6 +41,9 @@
41static int dvb_usb_anysee_debug; 41static int dvb_usb_anysee_debug;
42module_param_named(debug, dvb_usb_anysee_debug, int, 0644); 42module_param_named(debug, dvb_usb_anysee_debug, int, 0644);
43MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS); 43MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS);
44int dvb_usb_anysee_delsys;
45module_param_named(delsys, dvb_usb_anysee_delsys, int, 0644);
46MODULE_PARM_DESC(delsys, "select delivery mode (0=DVB-C, 1=DVB-T)");
44DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); 47DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
45 48
46static struct mutex anysee_usb_mutex; 49static struct mutex anysee_usb_mutex;
@@ -178,14 +181,14 @@ static int anysee_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msg,
178 inc = 1; 181 inc = 1;
179 } 182 }
180 if (ret) 183 if (ret)
181 return ret; 184 break;
182 185
183 i += inc; 186 i += inc;
184 } 187 }
185 188
186 mutex_unlock(&d->i2c_mutex); 189 mutex_unlock(&d->i2c_mutex);
187 190
188 return i; 191 return ret ? ret : i;
189} 192}
190 193
191static u32 anysee_i2c_func(struct i2c_adapter *adapter) 194static u32 anysee_i2c_func(struct i2c_adapter *adapter)
@@ -272,9 +275,11 @@ static int anysee_frontend_attach(struct dvb_usb_adapter *adap)
272 model demod hw firmware 275 model demod hw firmware
273 1. E30 MT352 02 0.2.1 276 1. E30 MT352 02 0.2.1
274 2. E30 ZL10353 02 0.2.1 277 2. E30 ZL10353 02 0.2.1
275 3. E30 Plus ZL10353 06 0.1.0 278 3. E30 Combo ZL10353 0f 0.1.2 DVB-T/C combo
276 4. E30C Plus TDA10023 0a 0.1.0 rev 0.2 279 4. E30 Plus ZL10353 06 0.1.0
277 4. E30C Plus TDA10023 0f 0.1.2 rev 0.4 280 5. E30C Plus TDA10023 0a 0.1.0 rev 0.2
281 E30C Plus TDA10023 0f 0.1.2 rev 0.4
282 E30 Combo TDA10023 0f 0.1.2 DVB-T/C combo
278 */ 283 */
279 284
280 /* Zarlink MT352 DVB-T demod inside of Samsung DNOS404ZH102A NIM */ 285 /* Zarlink MT352 DVB-T demod inside of Samsung DNOS404ZH102A NIM */
@@ -293,6 +298,21 @@ static int anysee_frontend_attach(struct dvb_usb_adapter *adap)
293 return 0; 298 return 0;
294 } 299 }
295 300
301 /* for E30 Combo Plus DVB-T demodulator */
302 if (dvb_usb_anysee_delsys) {
303 ret = anysee_write_reg(adap->dev, 0xb0, 0x01);
304 if (ret)
305 return ret;
306
307 /* Zarlink ZL10353 DVB-T demod */
308 adap->fe = dvb_attach(zl10353_attach, &anysee_zl10353_config,
309 &adap->dev->i2c_adap);
310 if (adap->fe != NULL) {
311 state->tuner = DVB_PLL_SAMSUNG_DTOS403IH102A;
312 return 0;
313 }
314 }
315
296 /* connect demod on IO port D for TDA10023 & ZL10353 */ 316 /* connect demod on IO port D for TDA10023 & ZL10353 */
297 ret = anysee_write_reg(adap->dev, 0xb0, 0x25); 317 ret = anysee_write_reg(adap->dev, 0xb0, 0x25);
298 if (ret) 318 if (ret)
diff --git a/drivers/media/dvb/dvb-usb/cinergyT2-core.c b/drivers/media/dvb/dvb-usb/cinergyT2-core.c
new file mode 100644
index 000000000000..3ac9f74e9fbf
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/cinergyT2-core.c
@@ -0,0 +1,268 @@
1/*
2 * TerraTec Cinergy T2/qanu USB2 DVB-T adapter.
3 *
4 * Copyright (C) 2007 Tomi Orava (tomimo@ncircle.nullnet.fi)
5 *
6 * Based on the dvb-usb-framework code and the
7 * original Terratec Cinergy T2 driver by:
8 *
9 * Copyright (C) 2004 Daniel Mack <daniel@qanu.de> and
10 * Holger Waechtler <holger@qanu.de>
11 *
12 * Protocol Spec published on http://qanu.de/specs/terratec_cinergyT2.pdf
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
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., 675 Mass Ave, Cambridge, MA 02139, USA.
27 *
28 */
29
30#include "cinergyT2.h"
31
32
33/* debug */
34int dvb_usb_cinergyt2_debug;
35int disable_remote;
36
37module_param_named(debug, dvb_usb_cinergyt2_debug, int, 0644);
38MODULE_PARM_DESC(debug, "set debugging level (1=info, xfer=2, rc=4 "
39 "(or-able)).");
40
41DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
42
43struct cinergyt2_state {
44 u8 rc_counter;
45};
46
47/* We are missing a release hook with usb_device data */
48struct dvb_usb_device *cinergyt2_usb_device;
49
50static struct dvb_usb_device_properties cinergyt2_properties;
51
52static int cinergyt2_streaming_ctrl(struct dvb_usb_adapter *adap, int enable)
53{
54 char buf[] = { CINERGYT2_EP1_CONTROL_STREAM_TRANSFER, enable ? 1 : 0 };
55 char result[64];
56 return dvb_usb_generic_rw(adap->dev, buf, sizeof(buf), result,
57 sizeof(result), 0);
58}
59
60static int cinergyt2_power_ctrl(struct dvb_usb_device *d, int enable)
61{
62 char buf[] = { CINERGYT2_EP1_SLEEP_MODE, enable ? 0 : 1 };
63 char state[3];
64 return dvb_usb_generic_rw(d, buf, sizeof(buf), state, sizeof(state), 0);
65}
66
67static int cinergyt2_frontend_attach(struct dvb_usb_adapter *adap)
68{
69 char query[] = { CINERGYT2_EP1_GET_FIRMWARE_VERSION };
70 char state[3];
71 int ret;
72
73 adap->fe = cinergyt2_fe_attach(adap->dev);
74
75 ret = dvb_usb_generic_rw(adap->dev, query, sizeof(query), state,
76 sizeof(state), 0);
77 if (ret < 0) {
78 deb_rc("cinergyt2_power_ctrl() Failed to retrieve sleep "
79 "state info\n");
80 }
81
82 /* Copy this pointer as we are gonna need it in the release phase */
83 cinergyt2_usb_device = adap->dev;
84
85 return 0;
86}
87
88static struct dvb_usb_rc_key cinergyt2_rc_keys[] = {
89 { 0x04, 0x01, KEY_POWER },
90 { 0x04, 0x02, KEY_1 },
91 { 0x04, 0x03, KEY_2 },
92 { 0x04, 0x04, KEY_3 },
93 { 0x04, 0x05, KEY_4 },
94 { 0x04, 0x06, KEY_5 },
95 { 0x04, 0x07, KEY_6 },
96 { 0x04, 0x08, KEY_7 },
97 { 0x04, 0x09, KEY_8 },
98 { 0x04, 0x0a, KEY_9 },
99 { 0x04, 0x0c, KEY_0 },
100 { 0x04, 0x0b, KEY_VIDEO },
101 { 0x04, 0x0d, KEY_REFRESH },
102 { 0x04, 0x0e, KEY_SELECT },
103 { 0x04, 0x0f, KEY_EPG },
104 { 0x04, 0x10, KEY_UP },
105 { 0x04, 0x14, KEY_DOWN },
106 { 0x04, 0x11, KEY_LEFT },
107 { 0x04, 0x13, KEY_RIGHT },
108 { 0x04, 0x12, KEY_OK },
109 { 0x04, 0x15, KEY_TEXT },
110 { 0x04, 0x16, KEY_INFO },
111 { 0x04, 0x17, KEY_RED },
112 { 0x04, 0x18, KEY_GREEN },
113 { 0x04, 0x19, KEY_YELLOW },
114 { 0x04, 0x1a, KEY_BLUE },
115 { 0x04, 0x1c, KEY_VOLUMEUP },
116 { 0x04, 0x1e, KEY_VOLUMEDOWN },
117 { 0x04, 0x1d, KEY_MUTE },
118 { 0x04, 0x1b, KEY_CHANNELUP },
119 { 0x04, 0x1f, KEY_CHANNELDOWN },
120 { 0x04, 0x40, KEY_PAUSE },
121 { 0x04, 0x4c, KEY_PLAY },
122 { 0x04, 0x58, KEY_RECORD },
123 { 0x04, 0x54, KEY_PREVIOUS },
124 { 0x04, 0x48, KEY_STOP },
125 { 0x04, 0x5c, KEY_NEXT }
126};
127
128/* Number of keypresses to ignore before detect repeating */
129#define RC_REPEAT_DELAY 3
130
131static int repeatable_keys[] = {
132 KEY_UP,
133 KEY_DOWN,
134 KEY_LEFT,
135 KEY_RIGHT,
136 KEY_VOLUMEUP,
137 KEY_VOLUMEDOWN,
138 KEY_CHANNELUP,
139 KEY_CHANNELDOWN
140};
141
142static int cinergyt2_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
143{
144 struct cinergyt2_state *st = d->priv;
145 u8 key[5] = {0, 0, 0, 0, 0}, cmd = CINERGYT2_EP1_GET_RC_EVENTS;
146 int i;
147
148 *state = REMOTE_NO_KEY_PRESSED;
149
150 dvb_usb_generic_rw(d, &cmd, 1, key, sizeof(key), 0);
151 if (key[4] == 0xff) {
152 /* key repeat */
153 st->rc_counter++;
154 if (st->rc_counter > RC_REPEAT_DELAY) {
155 for (i = 0; i < ARRAY_SIZE(repeatable_keys); i++) {
156 if (d->last_event == repeatable_keys[i]) {
157 *state = REMOTE_KEY_REPEAT;
158 *event = d->last_event;
159 deb_rc("repeat key, event %x\n",
160 *event);
161 return 0;
162 }
163 }
164 deb_rc("repeated key (non repeatable)\n");
165 }
166 return 0;
167 }
168
169 /* hack to pass checksum on the custom field */
170 key[2] = ~key[1];
171 dvb_usb_nec_rc_key_to_event(d, key, event, state);
172 if (key[0] != 0) {
173 if (*event != d->last_event)
174 st->rc_counter = 0;
175
176 deb_rc("key: %x %x %x %x %x\n",
177 key[0], key[1], key[2], key[3], key[4]);
178 }
179 return 0;
180}
181
182static int cinergyt2_usb_probe(struct usb_interface *intf,
183 const struct usb_device_id *id)
184{
185 return dvb_usb_device_init(intf, &cinergyt2_properties,
186 THIS_MODULE, NULL, adapter_nr);
187}
188
189
190static struct usb_device_id cinergyt2_usb_table[] = {
191 { USB_DEVICE(USB_VID_TERRATEC, 0x0038) },
192 { 0 }
193};
194
195MODULE_DEVICE_TABLE(usb, cinergyt2_usb_table);
196
197static struct dvb_usb_device_properties cinergyt2_properties = {
198 .size_of_priv = sizeof(struct cinergyt2_state),
199 .num_adapters = 1,
200 .adapter = {
201 {
202 .streaming_ctrl = cinergyt2_streaming_ctrl,
203 .frontend_attach = cinergyt2_frontend_attach,
204
205 /* parameter for the MPEG2-data transfer */
206 .stream = {
207 .type = USB_BULK,
208 .count = 5,
209 .endpoint = 0x02,
210 .u = {
211 .bulk = {
212 .buffersize = 512,
213 }
214 }
215 },
216 }
217 },
218
219 .power_ctrl = cinergyt2_power_ctrl,
220
221 .rc_interval = 50,
222 .rc_key_map = cinergyt2_rc_keys,
223 .rc_key_map_size = ARRAY_SIZE(cinergyt2_rc_keys),
224 .rc_query = cinergyt2_rc_query,
225
226 .generic_bulk_ctrl_endpoint = 1,
227
228 .num_device_descs = 1,
229 .devices = {
230 { .name = "TerraTec/qanu USB2.0 Highspeed DVB-T Receiver",
231 .cold_ids = {NULL},
232 .warm_ids = { &cinergyt2_usb_table[0], NULL },
233 },
234 { NULL },
235 }
236};
237
238
239static struct usb_driver cinergyt2_driver = {
240 .name = "cinergyT2",
241 .probe = cinergyt2_usb_probe,
242 .disconnect = dvb_usb_device_exit,
243 .id_table = cinergyt2_usb_table
244};
245
246static int __init cinergyt2_usb_init(void)
247{
248 int err;
249
250 err = usb_register(&cinergyt2_driver);
251 if (err) {
252 err("usb_register() failed! (err %i)\n", err);
253 return err;
254 }
255 return 0;
256}
257
258static void __exit cinergyt2_usb_exit(void)
259{
260 usb_deregister(&cinergyt2_driver);
261}
262
263module_init(cinergyt2_usb_init);
264module_exit(cinergyt2_usb_exit);
265
266MODULE_DESCRIPTION("Terratec Cinergy T2 DVB-T driver");
267MODULE_LICENSE("GPL");
268MODULE_AUTHOR("Tomi Orava");
diff --git a/drivers/media/dvb/dvb-usb/cinergyT2-fe.c b/drivers/media/dvb/dvb-usb/cinergyT2-fe.c
new file mode 100644
index 000000000000..649f25cca49e
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/cinergyT2-fe.c
@@ -0,0 +1,351 @@
1/*
2 * TerraTec Cinergy T2/qanu USB2 DVB-T adapter.
3 *
4 * Copyright (C) 2007 Tomi Orava (tomimo@ncircle.nullnet.fi)
5 *
6 * Based on the dvb-usb-framework code and the
7 * original Terratec Cinergy T2 driver by:
8 *
9 * Copyright (C) 2004 Daniel Mack <daniel@qanu.de> and
10 * Holger Waechtler <holger@qanu.de>
11 *
12 * Protocol Spec published on http://qanu.de/specs/terratec_cinergyT2.pdf
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
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., 675 Mass Ave, Cambridge, MA 02139, USA.
27 *
28 */
29
30#include "cinergyT2.h"
31
32
33/**
34 * convert linux-dvb frontend parameter set into TPS.
35 * See ETSI ETS-300744, section 4.6.2, table 9 for details.
36 *
37 * This function is probably reusable and may better get placed in a support
38 * library.
39 *
40 * We replace errornous fields by default TPS fields (the ones with value 0).
41 */
42
43static uint16_t compute_tps(struct dvb_frontend_parameters *p)
44{
45 struct dvb_ofdm_parameters *op = &p->u.ofdm;
46 uint16_t tps = 0;
47
48 switch (op->code_rate_HP) {
49 case FEC_2_3:
50 tps |= (1 << 7);
51 break;
52 case FEC_3_4:
53 tps |= (2 << 7);
54 break;
55 case FEC_5_6:
56 tps |= (3 << 7);
57 break;
58 case FEC_7_8:
59 tps |= (4 << 7);
60 break;
61 case FEC_1_2:
62 case FEC_AUTO:
63 default:
64 /* tps |= (0 << 7) */;
65 }
66
67 switch (op->code_rate_LP) {
68 case FEC_2_3:
69 tps |= (1 << 4);
70 break;
71 case FEC_3_4:
72 tps |= (2 << 4);
73 break;
74 case FEC_5_6:
75 tps |= (3 << 4);
76 break;
77 case FEC_7_8:
78 tps |= (4 << 4);
79 break;
80 case FEC_1_2:
81 case FEC_AUTO:
82 default:
83 /* tps |= (0 << 4) */;
84 }
85
86 switch (op->constellation) {
87 case QAM_16:
88 tps |= (1 << 13);
89 break;
90 case QAM_64:
91 tps |= (2 << 13);
92 break;
93 case QPSK:
94 default:
95 /* tps |= (0 << 13) */;
96 }
97
98 switch (op->transmission_mode) {
99 case TRANSMISSION_MODE_8K:
100 tps |= (1 << 0);
101 break;
102 case TRANSMISSION_MODE_2K:
103 default:
104 /* tps |= (0 << 0) */;
105 }
106
107 switch (op->guard_interval) {
108 case GUARD_INTERVAL_1_16:
109 tps |= (1 << 2);
110 break;
111 case GUARD_INTERVAL_1_8:
112 tps |= (2 << 2);
113 break;
114 case GUARD_INTERVAL_1_4:
115 tps |= (3 << 2);
116 break;
117 case GUARD_INTERVAL_1_32:
118 default:
119 /* tps |= (0 << 2) */;
120 }
121
122 switch (op->hierarchy_information) {
123 case HIERARCHY_1:
124 tps |= (1 << 10);
125 break;
126 case HIERARCHY_2:
127 tps |= (2 << 10);
128 break;
129 case HIERARCHY_4:
130 tps |= (3 << 10);
131 break;
132 case HIERARCHY_NONE:
133 default:
134 /* tps |= (0 << 10) */;
135 }
136
137 return tps;
138}
139
140struct cinergyt2_fe_state {
141 struct dvb_frontend fe;
142 struct dvb_usb_device *d;
143};
144
145static int cinergyt2_fe_read_status(struct dvb_frontend *fe,
146 fe_status_t *status)
147{
148 struct cinergyt2_fe_state *state = fe->demodulator_priv;
149 struct dvbt_get_status_msg result;
150 u8 cmd[] = { CINERGYT2_EP1_GET_TUNER_STATUS };
151 int ret;
152
153 ret = dvb_usb_generic_rw(state->d, cmd, sizeof(cmd), (u8 *)&result,
154 sizeof(result), 0);
155 if (ret < 0)
156 return ret;
157
158 *status = 0;
159
160 if (0xffff - le16_to_cpu(result.gain) > 30)
161 *status |= FE_HAS_SIGNAL;
162 if (result.lock_bits & (1 << 6))
163 *status |= FE_HAS_LOCK;
164 if (result.lock_bits & (1 << 5))
165 *status |= FE_HAS_SYNC;
166 if (result.lock_bits & (1 << 4))
167 *status |= FE_HAS_CARRIER;
168 if (result.lock_bits & (1 << 1))
169 *status |= FE_HAS_VITERBI;
170
171 if ((*status & (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC)) !=
172 (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC))
173 *status &= ~FE_HAS_LOCK;
174
175 return 0;
176}
177
178static int cinergyt2_fe_read_ber(struct dvb_frontend *fe, u32 *ber)
179{
180 struct cinergyt2_fe_state *state = fe->demodulator_priv;
181 struct dvbt_get_status_msg status;
182 char cmd[] = { CINERGYT2_EP1_GET_TUNER_STATUS };
183 int ret;
184
185 ret = dvb_usb_generic_rw(state->d, cmd, sizeof(cmd), (char *)&status,
186 sizeof(status), 0);
187 if (ret < 0)
188 return ret;
189
190 *ber = le32_to_cpu(status.viterbi_error_rate);
191 return 0;
192}
193
194static int cinergyt2_fe_read_unc_blocks(struct dvb_frontend *fe, u32 *unc)
195{
196 struct cinergyt2_fe_state *state = fe->demodulator_priv;
197 struct dvbt_get_status_msg status;
198 u8 cmd[] = { CINERGYT2_EP1_GET_TUNER_STATUS };
199 int ret;
200
201 ret = dvb_usb_generic_rw(state->d, cmd, sizeof(cmd), (u8 *)&status,
202 sizeof(status), 0);
203 if (ret < 0) {
204 err("cinergyt2_fe_read_unc_blocks() Failed! (Error=%d)\n",
205 ret);
206 return ret;
207 }
208 *unc = le32_to_cpu(status.uncorrected_block_count);
209 return 0;
210}
211
212static int cinergyt2_fe_read_signal_strength(struct dvb_frontend *fe,
213 u16 *strength)
214{
215 struct cinergyt2_fe_state *state = fe->demodulator_priv;
216 struct dvbt_get_status_msg status;
217 char cmd[] = { CINERGYT2_EP1_GET_TUNER_STATUS };
218 int ret;
219
220 ret = dvb_usb_generic_rw(state->d, cmd, sizeof(cmd), (char *)&status,
221 sizeof(status), 0);
222 if (ret < 0) {
223 err("cinergyt2_fe_read_signal_strength() Failed!"
224 " (Error=%d)\n", ret);
225 return ret;
226 }
227 *strength = (0xffff - le16_to_cpu(status.gain));
228 return 0;
229}
230
231static int cinergyt2_fe_read_snr(struct dvb_frontend *fe, u16 *snr)
232{
233 struct cinergyt2_fe_state *state = fe->demodulator_priv;
234 struct dvbt_get_status_msg status;
235 char cmd[] = { CINERGYT2_EP1_GET_TUNER_STATUS };
236 int ret;
237
238 ret = dvb_usb_generic_rw(state->d, cmd, sizeof(cmd), (char *)&status,
239 sizeof(status), 0);
240 if (ret < 0) {
241 err("cinergyt2_fe_read_snr() Failed! (Error=%d)\n", ret);
242 return ret;
243 }
244 *snr = (status.snr << 8) | status.snr;
245 return 0;
246}
247
248static int cinergyt2_fe_init(struct dvb_frontend *fe)
249{
250 return 0;
251}
252
253static int cinergyt2_fe_sleep(struct dvb_frontend *fe)
254{
255 deb_info("cinergyt2_fe_sleep() Called\n");
256 return 0;
257}
258
259static int cinergyt2_fe_get_tune_settings(struct dvb_frontend *fe,
260 struct dvb_frontend_tune_settings *tune)
261{
262 tune->min_delay_ms = 800;
263 return 0;
264}
265
266static int cinergyt2_fe_set_frontend(struct dvb_frontend *fe,
267 struct dvb_frontend_parameters *fep)
268{
269 struct cinergyt2_fe_state *state = fe->demodulator_priv;
270 struct dvbt_set_parameters_msg param;
271 char result[2];
272 int err;
273
274 param.cmd = CINERGYT2_EP1_SET_TUNER_PARAMETERS;
275 param.tps = cpu_to_le16(compute_tps(fep));
276 param.freq = cpu_to_le32(fep->frequency / 1000);
277 param.bandwidth = 8 - fep->u.ofdm.bandwidth - BANDWIDTH_8_MHZ;
278
279 err = dvb_usb_generic_rw(state->d,
280 (char *)&param, sizeof(param),
281 result, sizeof(result), 0);
282 if (err < 0)
283 err("cinergyt2_fe_set_frontend() Failed! err=%d\n", err);
284
285 return (err < 0) ? err : 0;
286}
287
288static int cinergyt2_fe_get_frontend(struct dvb_frontend *fe,
289 struct dvb_frontend_parameters *fep)
290{
291 return 0;
292}
293
294static void cinergyt2_fe_release(struct dvb_frontend *fe)
295{
296 struct cinergyt2_fe_state *state = fe->demodulator_priv;
297 if (state != NULL)
298 kfree(state);
299}
300
301static struct dvb_frontend_ops cinergyt2_fe_ops;
302
303struct dvb_frontend *cinergyt2_fe_attach(struct dvb_usb_device *d)
304{
305 struct cinergyt2_fe_state *s = kzalloc(sizeof(
306 struct cinergyt2_fe_state), GFP_KERNEL);
307 if (s == NULL)
308 return NULL;
309
310 s->d = d;
311 memcpy(&s->fe.ops, &cinergyt2_fe_ops, sizeof(struct dvb_frontend_ops));
312 s->fe.demodulator_priv = s;
313 return &s->fe;
314}
315
316
317static struct dvb_frontend_ops cinergyt2_fe_ops = {
318 .info = {
319 .name = DRIVER_NAME,
320 .type = FE_OFDM,
321 .frequency_min = 174000000,
322 .frequency_max = 862000000,
323 .frequency_stepsize = 166667,
324 .caps = FE_CAN_INVERSION_AUTO | FE_CAN_FEC_1_2
325 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4
326 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8
327 | FE_CAN_FEC_AUTO | FE_CAN_QPSK
328 | FE_CAN_QAM_16 | FE_CAN_QAM_64
329 | FE_CAN_QAM_AUTO
330 | FE_CAN_TRANSMISSION_MODE_AUTO
331 | FE_CAN_GUARD_INTERVAL_AUTO
332 | FE_CAN_HIERARCHY_AUTO
333 | FE_CAN_RECOVER
334 | FE_CAN_MUTE_TS
335 },
336
337 .release = cinergyt2_fe_release,
338
339 .init = cinergyt2_fe_init,
340 .sleep = cinergyt2_fe_sleep,
341
342 .set_frontend = cinergyt2_fe_set_frontend,
343 .get_frontend = cinergyt2_fe_get_frontend,
344 .get_tune_settings = cinergyt2_fe_get_tune_settings,
345
346 .read_status = cinergyt2_fe_read_status,
347 .read_ber = cinergyt2_fe_read_ber,
348 .read_signal_strength = cinergyt2_fe_read_signal_strength,
349 .read_snr = cinergyt2_fe_read_snr,
350 .read_ucblocks = cinergyt2_fe_read_unc_blocks,
351};
diff --git a/drivers/media/dvb/dvb-usb/cinergyT2.h b/drivers/media/dvb/dvb-usb/cinergyT2.h
new file mode 100644
index 000000000000..11d79eb384c8
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/cinergyT2.h
@@ -0,0 +1,95 @@
1/*
2 * TerraTec Cinergy T2/qanu USB2 DVB-T adapter.
3 *
4 * Copyright (C) 2007 Tomi Orava (tomimo@ncircle.nullnet.fi)
5 *
6 * Based on the dvb-usb-framework code and the
7 * original Terratec Cinergy T2 driver by:
8 *
9 * Copyright (C) 2004 Daniel Mack <daniel@qanu.de> and
10 * Holger Waechtler <holger@qanu.de>
11 *
12 * Protocol Spec published on http://qanu.de/specs/terratec_cinergyT2.pdf
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
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., 675 Mass Ave, Cambridge, MA 02139, USA.
27 *
28 */
29
30#ifndef _DVB_USB_CINERGYT2_H_
31#define _DVB_USB_CINERGYT2_H_
32
33#include <linux/usb/input.h>
34
35#define DVB_USB_LOG_PREFIX "cinergyT2"
36#include "dvb-usb.h"
37
38#define DRIVER_NAME "TerraTec/qanu USB2.0 Highspeed DVB-T Receiver"
39
40extern int dvb_usb_cinergyt2_debug;
41
42#define deb_info(args...) dprintk(dvb_usb_cinergyt2_debug, 0x001, args)
43#define deb_xfer(args...) dprintk(dvb_usb_cinergyt2_debug, 0x002, args)
44#define deb_pll(args...) dprintk(dvb_usb_cinergyt2_debug, 0x004, args)
45#define deb_ts(args...) dprintk(dvb_usb_cinergyt2_debug, 0x008, args)
46#define deb_err(args...) dprintk(dvb_usb_cinergyt2_debug, 0x010, args)
47#define deb_rc(args...) dprintk(dvb_usb_cinergyt2_debug, 0x020, args)
48#define deb_fw(args...) dprintk(dvb_usb_cinergyt2_debug, 0x040, args)
49#define deb_mem(args...) dprintk(dvb_usb_cinergyt2_debug, 0x080, args)
50#define deb_uxfer(args...) dprintk(dvb_usb_cinergyt2_debug, 0x100, args)
51
52
53
54enum cinergyt2_ep1_cmd {
55 CINERGYT2_EP1_PID_TABLE_RESET = 0x01,
56 CINERGYT2_EP1_PID_SETUP = 0x02,
57 CINERGYT2_EP1_CONTROL_STREAM_TRANSFER = 0x03,
58 CINERGYT2_EP1_SET_TUNER_PARAMETERS = 0x04,
59 CINERGYT2_EP1_GET_TUNER_STATUS = 0x05,
60 CINERGYT2_EP1_START_SCAN = 0x06,
61 CINERGYT2_EP1_CONTINUE_SCAN = 0x07,
62 CINERGYT2_EP1_GET_RC_EVENTS = 0x08,
63 CINERGYT2_EP1_SLEEP_MODE = 0x09,
64 CINERGYT2_EP1_GET_FIRMWARE_VERSION = 0x0A
65};
66
67
68struct dvbt_get_status_msg {
69 uint32_t freq;
70 uint8_t bandwidth;
71 uint16_t tps;
72 uint8_t flags;
73 uint16_t gain;
74 uint8_t snr;
75 uint32_t viterbi_error_rate;
76 uint32_t rs_error_rate;
77 uint32_t uncorrected_block_count;
78 uint8_t lock_bits;
79 uint8_t prev_lock_bits;
80} __attribute__((packed));
81
82
83struct dvbt_set_parameters_msg {
84 uint8_t cmd;
85 uint32_t freq;
86 uint8_t bandwidth;
87 uint16_t tps;
88 uint8_t flags;
89} __attribute__((packed));
90
91
92extern struct dvb_frontend *cinergyt2_fe_attach(struct dvb_usb_device *d);
93
94#endif /* _DVB_USB_CINERGYT2_H_ */
95
diff --git a/drivers/media/dvb/dvb-usb/cxusb.c b/drivers/media/dvb/dvb-usb/cxusb.c
index 563400277a42..406d7fba369d 100644
--- a/drivers/media/dvb/dvb-usb/cxusb.c
+++ b/drivers/media/dvb/dvb-usb/cxusb.c
@@ -36,6 +36,9 @@
36#include "tuner-xc2028.h" 36#include "tuner-xc2028.h"
37#include "tuner-simple.h" 37#include "tuner-simple.h"
38#include "mxl5005s.h" 38#include "mxl5005s.h"
39#include "dib7000p.h"
40#include "dib0070.h"
41#include "lgs8gl5.h"
39 42
40/* debug */ 43/* debug */
41static int dvb_usb_cxusb_debug; 44static int dvb_usb_cxusb_debug;
@@ -109,6 +112,25 @@ static void cxusb_nano2_led(struct dvb_usb_device *d, int onoff)
109 cxusb_bluebird_gpio_rw(d, 0x40, onoff ? 0 : 0x40); 112 cxusb_bluebird_gpio_rw(d, 0x40, onoff ? 0 : 0x40);
110} 113}
111 114
115static int cxusb_d680_dmb_gpio_tuner(struct dvb_usb_device *d,
116 u8 addr, int onoff)
117{
118 u8 o[2] = {addr, onoff};
119 u8 i;
120 int rc;
121
122 rc = cxusb_ctrl_msg(d, CMD_GPIO_WRITE, o, 2, &i, 1);
123
124 if (rc < 0)
125 return rc;
126 if (i == 0x01)
127 return 0;
128 else {
129 deb_info("gpio_write failed.\n");
130 return -EIO;
131 }
132}
133
112/* I2C */ 134/* I2C */
113static int cxusb_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], 135static int cxusb_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
114 int num) 136 int num)
@@ -262,6 +284,20 @@ static int cxusb_nano2_power_ctrl(struct dvb_usb_device *d, int onoff)
262 return rc; 284 return rc;
263} 285}
264 286
287static int cxusb_d680_dmb_power_ctrl(struct dvb_usb_device *d, int onoff)
288{
289 int ret;
290 u8 b;
291 ret = cxusb_power_ctrl(d, onoff);
292 if (!onoff)
293 return ret;
294
295 msleep(128);
296 cxusb_ctrl_msg(d, CMD_DIGITAL, NULL, 0, &b, 1);
297 msleep(100);
298 return ret;
299}
300
265static int cxusb_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) 301static int cxusb_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
266{ 302{
267 u8 buf[2] = { 0x03, 0x00 }; 303 u8 buf[2] = { 0x03, 0x00 };
@@ -283,6 +319,67 @@ static int cxusb_aver_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
283 return 0; 319 return 0;
284} 320}
285 321
322static void cxusb_d680_dmb_drain_message(struct dvb_usb_device *d)
323{
324 int ep = d->props.generic_bulk_ctrl_endpoint;
325 const int timeout = 100;
326 const int junk_len = 32;
327 u8 *junk;
328 int rd_count;
329
330 /* Discard remaining data in video pipe */
331 junk = kmalloc(junk_len, GFP_KERNEL);
332 if (!junk)
333 return;
334 while (1) {
335 if (usb_bulk_msg(d->udev,
336 usb_rcvbulkpipe(d->udev, ep),
337 junk, junk_len, &rd_count, timeout) < 0)
338 break;
339 if (!rd_count)
340 break;
341 }
342 kfree(junk);
343}
344
345static void cxusb_d680_dmb_drain_video(struct dvb_usb_device *d)
346{
347 struct usb_data_stream_properties *p = &d->props.adapter[0].stream;
348 const int timeout = 100;
349 const int junk_len = p->u.bulk.buffersize;
350 u8 *junk;
351 int rd_count;
352
353 /* Discard remaining data in video pipe */
354 junk = kmalloc(junk_len, GFP_KERNEL);
355 if (!junk)
356 return;
357 while (1) {
358 if (usb_bulk_msg(d->udev,
359 usb_rcvbulkpipe(d->udev, p->endpoint),
360 junk, junk_len, &rd_count, timeout) < 0)
361 break;
362 if (!rd_count)
363 break;
364 }
365 kfree(junk);
366}
367
368static int cxusb_d680_dmb_streaming_ctrl(
369 struct dvb_usb_adapter *adap, int onoff)
370{
371 if (onoff) {
372 u8 buf[2] = { 0x03, 0x00 };
373 cxusb_d680_dmb_drain_video(adap->dev);
374 return cxusb_ctrl_msg(adap->dev, CMD_STREAMING_ON,
375 buf, sizeof(buf), NULL, 0);
376 } else {
377 int ret = cxusb_ctrl_msg(adap->dev,
378 CMD_STREAMING_OFF, NULL, 0, NULL, 0);
379 return ret;
380 }
381}
382
286static int cxusb_rc_query(struct dvb_usb_device *d, u32 *event, int *state) 383static int cxusb_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
287{ 384{
288 struct dvb_usb_rc_key *keymap = d->props.rc_key_map; 385 struct dvb_usb_rc_key *keymap = d->props.rc_key_map;
@@ -335,6 +432,32 @@ static int cxusb_bluebird2_rc_query(struct dvb_usb_device *d, u32 *event,
335 return 0; 432 return 0;
336} 433}
337 434
435static int cxusb_d680_dmb_rc_query(struct dvb_usb_device *d, u32 *event,
436 int *state)
437{
438 struct dvb_usb_rc_key *keymap = d->props.rc_key_map;
439 u8 ircode[2];
440 int i;
441
442 *event = 0;
443 *state = REMOTE_NO_KEY_PRESSED;
444
445 if (cxusb_ctrl_msg(d, 0x10, NULL, 0, ircode, 2) < 0)
446 return 0;
447
448 for (i = 0; i < d->props.rc_key_map_size; i++) {
449 if (keymap[i].custom == ircode[0] &&
450 keymap[i].data == ircode[1]) {
451 *event = keymap[i].event;
452 *state = REMOTE_KEY_PRESSED;
453
454 return 0;
455 }
456 }
457
458 return 0;
459}
460
338static struct dvb_usb_rc_key dvico_mce_rc_keys[] = { 461static struct dvb_usb_rc_key dvico_mce_rc_keys[] = {
339 { 0xfe, 0x02, KEY_TV }, 462 { 0xfe, 0x02, KEY_TV },
340 { 0xfe, 0x0e, KEY_MP3 }, 463 { 0xfe, 0x0e, KEY_MP3 },
@@ -422,6 +545,44 @@ static struct dvb_usb_rc_key dvico_portable_rc_keys[] = {
422 { 0xfc, 0x00, KEY_UNKNOWN }, /* HD */ 545 { 0xfc, 0x00, KEY_UNKNOWN }, /* HD */
423}; 546};
424 547
548static struct dvb_usb_rc_key d680_dmb_rc_keys[] = {
549 { 0x00, 0x38, KEY_UNKNOWN }, /* TV/AV */
550 { 0x08, 0x0c, KEY_ZOOM },
551 { 0x08, 0x00, KEY_0 },
552 { 0x00, 0x01, KEY_1 },
553 { 0x08, 0x02, KEY_2 },
554 { 0x00, 0x03, KEY_3 },
555 { 0x08, 0x04, KEY_4 },
556 { 0x00, 0x05, KEY_5 },
557 { 0x08, 0x06, KEY_6 },
558 { 0x00, 0x07, KEY_7 },
559 { 0x08, 0x08, KEY_8 },
560 { 0x00, 0x09, KEY_9 },
561 { 0x00, 0x0a, KEY_MUTE },
562 { 0x08, 0x29, KEY_BACK },
563 { 0x00, 0x12, KEY_CHANNELUP },
564 { 0x08, 0x13, KEY_CHANNELDOWN },
565 { 0x00, 0x2b, KEY_VOLUMEUP },
566 { 0x08, 0x2c, KEY_VOLUMEDOWN },
567 { 0x00, 0x20, KEY_UP },
568 { 0x08, 0x21, KEY_DOWN },
569 { 0x00, 0x11, KEY_LEFT },
570 { 0x08, 0x10, KEY_RIGHT },
571 { 0x00, 0x0d, KEY_OK },
572 { 0x08, 0x1f, KEY_RECORD },
573 { 0x00, 0x17, KEY_PLAYPAUSE },
574 { 0x08, 0x16, KEY_PLAYPAUSE },
575 { 0x00, 0x0b, KEY_STOP },
576 { 0x08, 0x27, KEY_FASTFORWARD },
577 { 0x00, 0x26, KEY_REWIND },
578 { 0x08, 0x1e, KEY_UNKNOWN }, /* Time Shift */
579 { 0x00, 0x0e, KEY_UNKNOWN }, /* Snapshot */
580 { 0x08, 0x2d, KEY_UNKNOWN }, /* Mouse Cursor */
581 { 0x00, 0x0f, KEY_UNKNOWN }, /* Minimize/Maximize */
582 { 0x08, 0x14, KEY_UNKNOWN }, /* Shuffle */
583 { 0x00, 0x25, KEY_POWER },
584};
585
425static int cxusb_dee1601_demod_init(struct dvb_frontend* fe) 586static int cxusb_dee1601_demod_init(struct dvb_frontend* fe)
426{ 587{
427 static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x28 }; 588 static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x28 };
@@ -527,6 +688,24 @@ static struct mxl5005s_config aver_a868r_tuner = {
527 .AgcMasterByte = 0x00, 688 .AgcMasterByte = 0x00,
528}; 689};
529 690
691/* FIXME: needs tweaking */
692static struct mxl5005s_config d680_dmb_tuner = {
693 .i2c_address = 0x63,
694 .if_freq = 36125000UL,
695 .xtal_freq = CRYSTAL_FREQ_16000000HZ,
696 .agc_mode = MXL_SINGLE_AGC,
697 .tracking_filter = MXL_TF_C,
698 .rssi_enable = MXL_RSSI_ENABLE,
699 .cap_select = MXL_CAP_SEL_ENABLE,
700 .div_out = MXL_DIV_OUT_4,
701 .clock_out = MXL_CLOCK_OUT_DISABLE,
702 .output_load = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
703 .top = MXL5005S_TOP_25P2,
704 .mod_mode = MXL_DIGITAL_MODE,
705 .if_mode = MXL_ZERO_IF,
706 .AgcMasterByte = 0x00,
707};
708
530/* Callbacks for DVB USB */ 709/* Callbacks for DVB USB */
531static int cxusb_fmd1216me_tuner_attach(struct dvb_usb_adapter *adap) 710static int cxusb_fmd1216me_tuner_attach(struct dvb_usb_adapter *adap)
532{ 711{
@@ -563,7 +742,8 @@ static int cxusb_lgh064f_tuner_attach(struct dvb_usb_adapter *adap)
563 return 0; 742 return 0;
564} 743}
565 744
566static int dvico_bluebird_xc2028_callback(void *ptr, int command, int arg) 745static int dvico_bluebird_xc2028_callback(void *ptr, int component,
746 int command, int arg)
567{ 747{
568 struct dvb_usb_adapter *adap = ptr; 748 struct dvb_usb_adapter *adap = ptr;
569 struct dvb_usb_device *d = adap->dev; 749 struct dvb_usb_device *d = adap->dev;
@@ -591,14 +771,16 @@ static int cxusb_dvico_xc3028_tuner_attach(struct dvb_usb_adapter *adap)
591 struct xc2028_config cfg = { 771 struct xc2028_config cfg = {
592 .i2c_adap = &adap->dev->i2c_adap, 772 .i2c_adap = &adap->dev->i2c_adap,
593 .i2c_addr = 0x61, 773 .i2c_addr = 0x61,
594 .callback = dvico_bluebird_xc2028_callback,
595 }; 774 };
596 static struct xc2028_ctrl ctl = { 775 static struct xc2028_ctrl ctl = {
597 .fname = "xc3028-v27.fw", 776 .fname = XC2028_DEFAULT_FIRMWARE,
598 .max_len = 64, 777 .max_len = 64,
599 .demod = XC3028_FE_ZARLINK456, 778 .demod = XC3028_FE_ZARLINK456,
600 }; 779 };
601 780
781 /* FIXME: generalize & move to common area */
782 adap->fe->callback = dvico_bluebird_xc2028_callback;
783
602 fe = dvb_attach(xc2028_attach, adap->fe, &cfg); 784 fe = dvb_attach(xc2028_attach, adap->fe, &cfg);
603 if (fe == NULL || fe->ops.tuner_ops.set_config == NULL) 785 if (fe == NULL || fe->ops.tuner_ops.set_config == NULL)
604 return -EIO; 786 return -EIO;
@@ -615,6 +797,14 @@ static int cxusb_mxl5003s_tuner_attach(struct dvb_usb_adapter *adap)
615 return 0; 797 return 0;
616} 798}
617 799
800static int cxusb_d680_dmb_tuner_attach(struct dvb_usb_adapter *adap)
801{
802 struct dvb_frontend *fe;
803 fe = dvb_attach(mxl5005s_attach, adap->fe,
804 &adap->dev->i2c_adap, &d680_dmb_tuner);
805 return (fe == NULL) ? -EIO : 0;
806}
807
618static int cxusb_cx22702_frontend_attach(struct dvb_usb_adapter *adap) 808static int cxusb_cx22702_frontend_attach(struct dvb_usb_adapter *adap)
619{ 809{
620 u8 b; 810 u8 b;
@@ -726,6 +916,159 @@ no_IR:
726 return 0; 916 return 0;
727} 917}
728 918
919static struct dibx000_agc_config dib7070_agc_config = {
920 .band_caps = BAND_UHF | BAND_VHF | BAND_LBAND | BAND_SBAND,
921
922 /*
923 * P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=5,
924 * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0,
925 * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0
926 */
927 .setup = (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) |
928 (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0),
929 .inv_gain = 600,
930 .time_stabiliz = 10,
931 .alpha_level = 0,
932 .thlock = 118,
933 .wbd_inv = 0,
934 .wbd_ref = 3530,
935 .wbd_sel = 1,
936 .wbd_alpha = 5,
937 .agc1_max = 65535,
938 .agc1_min = 0,
939 .agc2_max = 65535,
940 .agc2_min = 0,
941 .agc1_pt1 = 0,
942 .agc1_pt2 = 40,
943 .agc1_pt3 = 183,
944 .agc1_slope1 = 206,
945 .agc1_slope2 = 255,
946 .agc2_pt1 = 72,
947 .agc2_pt2 = 152,
948 .agc2_slope1 = 88,
949 .agc2_slope2 = 90,
950 .alpha_mant = 17,
951 .alpha_exp = 27,
952 .beta_mant = 23,
953 .beta_exp = 51,
954 .perform_agc_softsplit = 0,
955};
956
957static struct dibx000_bandwidth_config dib7070_bw_config_12_mhz = {
958 .internal = 60000,
959 .sampling = 15000,
960 .pll_prediv = 1,
961 .pll_ratio = 20,
962 .pll_range = 3,
963 .pll_reset = 1,
964 .pll_bypass = 0,
965 .enable_refdiv = 0,
966 .bypclk_div = 0,
967 .IO_CLK_en_core = 1,
968 .ADClkSrc = 1,
969 .modulo = 2,
970 /* refsel, sel, freq_15k */
971 .sad_cfg = (3 << 14) | (1 << 12) | (524 << 0),
972 .ifreq = (0 << 25) | 0,
973 .timf = 20452225,
974 .xtal_hz = 12000000,
975};
976
977static struct dib7000p_config cxusb_dualdig4_rev2_config = {
978 .output_mode = OUTMODE_MPEG2_PAR_GATED_CLK,
979 .output_mpeg2_in_188_bytes = 1,
980
981 .agc_config_count = 1,
982 .agc = &dib7070_agc_config,
983 .bw = &dib7070_bw_config_12_mhz,
984 .tuner_is_baseband = 1,
985 .spur_protect = 1,
986
987 .gpio_dir = 0xfcef,
988 .gpio_val = 0x0110,
989
990 .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
991
992 .hostbus_diversity = 1,
993};
994
995static int cxusb_dualdig4_rev2_frontend_attach(struct dvb_usb_adapter *adap)
996{
997 if (usb_set_interface(adap->dev->udev, 0, 1) < 0)
998 err("set interface failed");
999
1000 cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
1001
1002 cxusb_bluebird_gpio_pulse(adap->dev, 0x02, 1);
1003
1004 dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
1005 &cxusb_dualdig4_rev2_config);
1006
1007 adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80,
1008 &cxusb_dualdig4_rev2_config);
1009 if (adap->fe == NULL)
1010 return -EIO;
1011
1012 return 0;
1013}
1014
1015static int dib7070_tuner_reset(struct dvb_frontend *fe, int onoff)
1016{
1017 return dib7000p_set_gpio(fe, 8, 0, !onoff);
1018}
1019
1020static int dib7070_tuner_sleep(struct dvb_frontend *fe, int onoff)
1021{
1022 return 0;
1023}
1024
1025static struct dib0070_config dib7070p_dib0070_config = {
1026 .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
1027 .reset = dib7070_tuner_reset,
1028 .sleep = dib7070_tuner_sleep,
1029 .clock_khz = 12000,
1030};
1031
1032struct dib0700_adapter_state {
1033 int (*set_param_save) (struct dvb_frontend *,
1034 struct dvb_frontend_parameters *);
1035};
1036
1037static int dib7070_set_param_override(struct dvb_frontend *fe,
1038 struct dvb_frontend_parameters *fep)
1039{
1040 struct dvb_usb_adapter *adap = fe->dvb->priv;
1041 struct dib0700_adapter_state *state = adap->priv;
1042
1043 u16 offset;
1044 u8 band = BAND_OF_FREQUENCY(fep->frequency/1000);
1045 switch (band) {
1046 case BAND_VHF: offset = 950; break;
1047 default:
1048 case BAND_UHF: offset = 550; break;
1049 }
1050
1051 dib7000p_set_wbd_ref(fe, offset + dib0070_wbd_offset(fe));
1052
1053 return state->set_param_save(fe, fep);
1054}
1055
1056static int cxusb_dualdig4_rev2_tuner_attach(struct dvb_usb_adapter *adap)
1057{
1058 struct dib0700_adapter_state *st = adap->priv;
1059 struct i2c_adapter *tun_i2c =
1060 dib7000p_get_i2c_master(adap->fe,
1061 DIBX000_I2C_INTERFACE_TUNER, 1);
1062
1063 if (dvb_attach(dib0070_attach, adap->fe, tun_i2c,
1064 &dib7070p_dib0070_config) == NULL)
1065 return -ENODEV;
1066
1067 st->set_param_save = adap->fe->ops.tuner_ops.set_params;
1068 adap->fe->ops.tuner_ops.set_params = dib7070_set_param_override;
1069 return 0;
1070}
1071
729static int cxusb_nano2_frontend_attach(struct dvb_usb_adapter *adap) 1072static int cxusb_nano2_frontend_attach(struct dvb_usb_adapter *adap)
730{ 1073{
731 if (usb_set_interface(adap->dev->udev, 0, 1) < 0) 1074 if (usb_set_interface(adap->dev->udev, 0, 1) < 0)
@@ -751,6 +1094,54 @@ static int cxusb_nano2_frontend_attach(struct dvb_usb_adapter *adap)
751 return -EIO; 1094 return -EIO;
752} 1095}
753 1096
1097static struct lgs8gl5_config lgs8gl5_cfg = {
1098 .demod_address = 0x19,
1099};
1100
1101static int cxusb_d680_dmb_frontend_attach(struct dvb_usb_adapter *adap)
1102{
1103 struct dvb_usb_device *d = adap->dev;
1104 int n;
1105
1106 /* Select required USB configuration */
1107 if (usb_set_interface(d->udev, 0, 0) < 0)
1108 err("set interface failed");
1109
1110 /* Unblock all USB pipes */
1111 usb_clear_halt(d->udev,
1112 usb_sndbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint));
1113 usb_clear_halt(d->udev,
1114 usb_rcvbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint));
1115 usb_clear_halt(d->udev,
1116 usb_rcvbulkpipe(d->udev, d->props.adapter[0].stream.endpoint));
1117
1118 /* Drain USB pipes to avoid hang after reboot */
1119 for (n = 0; n < 5; n++) {
1120 cxusb_d680_dmb_drain_message(d);
1121 cxusb_d680_dmb_drain_video(d);
1122 msleep(200);
1123 }
1124
1125 /* Reset the tuner */
1126 if (cxusb_d680_dmb_gpio_tuner(d, 0x07, 0) < 0) {
1127 err("clear tuner gpio failed");
1128 return -EIO;
1129 }
1130 msleep(100);
1131 if (cxusb_d680_dmb_gpio_tuner(d, 0x07, 1) < 0) {
1132 err("set tuner gpio failed");
1133 return -EIO;
1134 }
1135 msleep(100);
1136
1137 /* Attach frontend */
1138 adap->fe = dvb_attach(lgs8gl5_attach, &lgs8gl5_cfg, &d->i2c_adap);
1139 if (adap->fe == NULL)
1140 return -EIO;
1141
1142 return 0;
1143}
1144
754/* 1145/*
755 * DViCO has shipped two devices with the same USB ID, but only one of them 1146 * DViCO has shipped two devices with the same USB ID, but only one of them
756 * needs a firmware download. Check the device class details to see if they 1147 * needs a firmware download. Check the device class details to see if they
@@ -826,9 +1217,11 @@ static struct dvb_usb_device_properties cxusb_bluebird_dee1601_properties;
826static struct dvb_usb_device_properties cxusb_bluebird_lgz201_properties; 1217static struct dvb_usb_device_properties cxusb_bluebird_lgz201_properties;
827static struct dvb_usb_device_properties cxusb_bluebird_dtt7579_properties; 1218static struct dvb_usb_device_properties cxusb_bluebird_dtt7579_properties;
828static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_properties; 1219static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_properties;
1220static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_rev2_properties;
829static struct dvb_usb_device_properties cxusb_bluebird_nano2_properties; 1221static struct dvb_usb_device_properties cxusb_bluebird_nano2_properties;
830static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_properties; 1222static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_properties;
831static struct dvb_usb_device_properties cxusb_aver_a868r_properties; 1223static struct dvb_usb_device_properties cxusb_aver_a868r_properties;
1224static struct dvb_usb_device_properties cxusb_d680_dmb_properties;
832 1225
833static int cxusb_probe(struct usb_interface *intf, 1226static int cxusb_probe(struct usb_interface *intf,
834 const struct usb_device_id *id) 1227 const struct usb_device_id *id)
@@ -852,6 +1245,11 @@ static int cxusb_probe(struct usb_interface *intf,
852 THIS_MODULE, NULL, adapter_nr) || 1245 THIS_MODULE, NULL, adapter_nr) ||
853 0 == dvb_usb_device_init(intf, &cxusb_aver_a868r_properties, 1246 0 == dvb_usb_device_init(intf, &cxusb_aver_a868r_properties,
854 THIS_MODULE, NULL, adapter_nr) || 1247 THIS_MODULE, NULL, adapter_nr) ||
1248 0 == dvb_usb_device_init(intf,
1249 &cxusb_bluebird_dualdig4_rev2_properties,
1250 THIS_MODULE, NULL, adapter_nr) ||
1251 0 == dvb_usb_device_init(intf, &cxusb_d680_dmb_properties,
1252 THIS_MODULE, NULL, adapter_nr) ||
855 0) 1253 0)
856 return 0; 1254 return 0;
857 1255
@@ -876,6 +1274,8 @@ static struct usb_device_id cxusb_table [] = {
876 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2) }, 1274 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2) },
877 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2_NFW_WARM) }, 1275 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2_NFW_WARM) },
878 { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_A868R) }, 1276 { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_A868R) },
1277 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_4_REV_2) },
1278 { USB_DEVICE(USB_VID_CONEXANT, USB_PID_CONEXANT_D680_DMB) },
879 {} /* Terminating entry */ 1279 {} /* Terminating entry */
880}; 1280};
881MODULE_DEVICE_TABLE (usb, cxusb_table); 1281MODULE_DEVICE_TABLE (usb, cxusb_table);
@@ -1321,6 +1721,104 @@ static struct dvb_usb_device_properties cxusb_aver_a868r_properties = {
1321 } 1721 }
1322}; 1722};
1323 1723
1724static
1725struct dvb_usb_device_properties cxusb_bluebird_dualdig4_rev2_properties = {
1726 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1727
1728 .usb_ctrl = CYPRESS_FX2,
1729
1730 .size_of_priv = sizeof(struct cxusb_state),
1731
1732 .num_adapters = 1,
1733 .adapter = {
1734 {
1735 .streaming_ctrl = cxusb_streaming_ctrl,
1736 .frontend_attach = cxusb_dualdig4_rev2_frontend_attach,
1737 .tuner_attach = cxusb_dualdig4_rev2_tuner_attach,
1738 .size_of_priv = sizeof(struct dib0700_adapter_state),
1739 /* parameter for the MPEG2-data transfer */
1740 .stream = {
1741 .type = USB_BULK,
1742 .count = 7,
1743 .endpoint = 0x02,
1744 .u = {
1745 .bulk = {
1746 .buffersize = 4096,
1747 }
1748 }
1749 },
1750 },
1751 },
1752
1753 .power_ctrl = cxusb_bluebird_power_ctrl,
1754
1755 .i2c_algo = &cxusb_i2c_algo,
1756
1757 .generic_bulk_ctrl_endpoint = 0x01,
1758
1759 .rc_interval = 100,
1760 .rc_key_map = dvico_mce_rc_keys,
1761 .rc_key_map_size = ARRAY_SIZE(dvico_mce_rc_keys),
1762 .rc_query = cxusb_rc_query,
1763
1764 .num_device_descs = 1,
1765 .devices = {
1766 { "DViCO FusionHDTV DVB-T Dual Digital 4 (rev 2)",
1767 { NULL },
1768 { &cxusb_table[17], NULL },
1769 },
1770 }
1771};
1772
1773static struct dvb_usb_device_properties cxusb_d680_dmb_properties = {
1774 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1775
1776 .usb_ctrl = CYPRESS_FX2,
1777
1778 .size_of_priv = sizeof(struct cxusb_state),
1779
1780 .num_adapters = 1,
1781 .adapter = {
1782 {
1783 .streaming_ctrl = cxusb_d680_dmb_streaming_ctrl,
1784 .frontend_attach = cxusb_d680_dmb_frontend_attach,
1785 .tuner_attach = cxusb_d680_dmb_tuner_attach,
1786
1787 /* parameter for the MPEG2-data transfer */
1788 .stream = {
1789 .type = USB_BULK,
1790 .count = 5,
1791 .endpoint = 0x02,
1792 .u = {
1793 .bulk = {
1794 .buffersize = 8192,
1795 }
1796 }
1797 },
1798 },
1799 },
1800
1801 .power_ctrl = cxusb_d680_dmb_power_ctrl,
1802
1803 .i2c_algo = &cxusb_i2c_algo,
1804
1805 .generic_bulk_ctrl_endpoint = 0x01,
1806
1807 .rc_interval = 100,
1808 .rc_key_map = d680_dmb_rc_keys,
1809 .rc_key_map_size = ARRAY_SIZE(d680_dmb_rc_keys),
1810 .rc_query = cxusb_d680_dmb_rc_query,
1811
1812 .num_device_descs = 1,
1813 .devices = {
1814 {
1815 "Conexant DMB-TH Stick",
1816 { NULL },
1817 { &cxusb_table[18], NULL },
1818 },
1819 }
1820};
1821
1324static struct usb_driver cxusb_driver = { 1822static struct usb_driver cxusb_driver = {
1325 .name = "dvb_usb_cxusb", 1823 .name = "dvb_usb_cxusb",
1326 .probe = cxusb_probe, 1824 .probe = cxusb_probe,
diff --git a/drivers/media/dvb/dvb-usb/dib0700.h b/drivers/media/dvb/dvb-usb/dib0700.h
index 66d4dc6ba46f..739193943c17 100644
--- a/drivers/media/dvb/dvb-usb/dib0700.h
+++ b/drivers/media/dvb/dvb-usb/dib0700.h
@@ -31,6 +31,8 @@ extern int dvb_usb_dib0700_debug;
31 // 2 Byte: MPEG2 mode: 4MSB(1 = Master Mode, 0 = Slave Mode) 4LSB(Channel 1 = bit0, Channel 2 = bit1) 31 // 2 Byte: MPEG2 mode: 4MSB(1 = Master Mode, 0 = Slave Mode) 4LSB(Channel 1 = bit0, Channel 2 = bit1)
32 // 2 Byte: Analog mode: 4MSB(0 = 625 lines, 1 = 525 lines) 4LSB( " " ) 32 // 2 Byte: Analog mode: 4MSB(0 = 625 lines, 1 = 525 lines) 4LSB( " " )
33#define REQUEST_SET_RC 0x11 33#define REQUEST_SET_RC 0x11
34#define REQUEST_NEW_I2C_READ 0x12
35#define REQUEST_NEW_I2C_WRITE 0x13
34#define REQUEST_GET_VERSION 0x15 36#define REQUEST_GET_VERSION 0x15
35 37
36struct dib0700_state { 38struct dib0700_state {
@@ -39,6 +41,8 @@ struct dib0700_state {
39 u8 rc_toggle; 41 u8 rc_toggle;
40 u8 rc_counter; 42 u8 rc_counter;
41 u8 is_dib7000pc; 43 u8 is_dib7000pc;
44 u8 fw_use_new_i2c_api;
45 u8 disable_streaming_master_mode;
42}; 46};
43 47
44extern int dib0700_set_gpio(struct dvb_usb_device *, enum dib07x0_gpios gpio, u8 gpio_dir, u8 gpio_val); 48extern int dib0700_set_gpio(struct dvb_usb_device *, enum dib07x0_gpios gpio, u8 gpio_dir, u8 gpio_val);
diff --git a/drivers/media/dvb/dvb-usb/dib0700_core.c b/drivers/media/dvb/dvb-usb/dib0700_core.c
index 595a04696c87..dd53cee3896d 100644
--- a/drivers/media/dvb/dvb-usb/dib0700_core.c
+++ b/drivers/media/dvb/dvb-usb/dib0700_core.c
@@ -82,9 +82,98 @@ int dib0700_set_gpio(struct dvb_usb_device *d, enum dib07x0_gpios gpio, u8 gpio_
82} 82}
83 83
84/* 84/*
85 * I2C master xfer function 85 * I2C master xfer function (supported in 1.20 firmware)
86 */ 86 */
87static int dib0700_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg *msg,int num) 87static int dib0700_i2c_xfer_new(struct i2c_adapter *adap, struct i2c_msg *msg,
88 int num)
89{
90 /* The new i2c firmware messages are more reliable and in particular
91 properly support i2c read calls not preceded by a write */
92
93 struct dvb_usb_device *d = i2c_get_adapdata(adap);
94 uint8_t bus_mode = 1; /* 0=eeprom bus, 1=frontend bus */
95 uint8_t gen_mode = 0; /* 0=master i2c, 1=gpio i2c */
96 uint8_t en_start = 0;
97 uint8_t en_stop = 0;
98 uint8_t buf[255]; /* TBV: malloc ? */
99 int result, i;
100
101 /* Ensure nobody else hits the i2c bus while we're sending our
102 sequence of messages, (such as the remote control thread) */
103 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
104 return -EAGAIN;
105
106 for (i = 0; i < num; i++) {
107 if (i == 0) {
108 /* First message in the transaction */
109 en_start = 1;
110 } else if (!(msg[i].flags & I2C_M_NOSTART)) {
111 /* Device supports repeated-start */
112 en_start = 1;
113 } else {
114 /* Not the first packet and device doesn't support
115 repeated start */
116 en_start = 0;
117 }
118 if (i == (num - 1)) {
119 /* Last message in the transaction */
120 en_stop = 1;
121 }
122
123 if (msg[i].flags & I2C_M_RD) {
124 /* Read request */
125 u16 index, value;
126 uint8_t i2c_dest;
127
128 i2c_dest = (msg[i].addr << 1);
129 value = ((en_start << 7) | (en_stop << 6) |
130 (msg[i].len & 0x3F)) << 8 | i2c_dest;
131 /* I2C ctrl + FE bus; */
132 index = ((gen_mode<<6)&0xC0) | ((bus_mode<<4)&0x30);
133
134 result = usb_control_msg(d->udev,
135 usb_rcvctrlpipe(d->udev, 0),
136 REQUEST_NEW_I2C_READ,
137 USB_TYPE_VENDOR | USB_DIR_IN,
138 value, index, msg[i].buf,
139 msg[i].len,
140 USB_CTRL_GET_TIMEOUT);
141 if (result < 0) {
142 err("i2c read error (status = %d)\n", result);
143 break;
144 }
145 } else {
146 /* Write request */
147 buf[0] = REQUEST_NEW_I2C_WRITE;
148 buf[1] = (msg[i].addr << 1);
149 buf[2] = (en_start << 7) | (en_stop << 6) |
150 (msg[i].len & 0x3F);
151 /* I2C ctrl + FE bus; */
152 buf[3] = ((gen_mode<<6)&0xC0) | ((bus_mode<<4)&0x30);
153 /* The Actual i2c payload */
154 memcpy(&buf[4], msg[i].buf, msg[i].len);
155
156 result = usb_control_msg(d->udev,
157 usb_sndctrlpipe(d->udev, 0),
158 REQUEST_NEW_I2C_WRITE,
159 USB_TYPE_VENDOR | USB_DIR_OUT,
160 0, 0, buf, msg[i].len + 4,
161 USB_CTRL_GET_TIMEOUT);
162 if (result < 0) {
163 err("i2c write error (status = %d)\n", result);
164 break;
165 }
166 }
167 }
168 mutex_unlock(&d->i2c_mutex);
169 return i;
170}
171
172/*
173 * I2C master xfer function (pre-1.20 firmware)
174 */
175static int dib0700_i2c_xfer_legacy(struct i2c_adapter *adap,
176 struct i2c_msg *msg, int num)
88{ 177{
89 struct dvb_usb_device *d = i2c_get_adapdata(adap); 178 struct dvb_usb_device *d = i2c_get_adapdata(adap);
90 int i,len; 179 int i,len;
@@ -124,6 +213,21 @@ static int dib0700_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg *msg,int num
124 return i; 213 return i;
125} 214}
126 215
216static int dib0700_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msg,
217 int num)
218{
219 struct dvb_usb_device *d = i2c_get_adapdata(adap);
220 struct dib0700_state *st = d->priv;
221
222 if (st->fw_use_new_i2c_api == 1) {
223 /* User running at least fw 1.20 */
224 return dib0700_i2c_xfer_new(adap, msg, num);
225 } else {
226 /* Use legacy calls */
227 return dib0700_i2c_xfer_legacy(adap, msg, num);
228 }
229}
230
127static u32 dib0700_i2c_func(struct i2c_adapter *adapter) 231static u32 dib0700_i2c_func(struct i2c_adapter *adapter)
128{ 232{
129 return I2C_FUNC_I2C; 233 return I2C_FUNC_I2C;
@@ -246,7 +350,12 @@ int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
246 350
247 b[0] = REQUEST_ENABLE_VIDEO; 351 b[0] = REQUEST_ENABLE_VIDEO;
248 b[1] = (onoff << 4) | 0x00; /* this bit gives a kind of command, rather than enabling something or not */ 352 b[1] = (onoff << 4) | 0x00; /* this bit gives a kind of command, rather than enabling something or not */
249 b[2] = (0x01 << 4); /* Master mode */ 353
354 if (st->disable_streaming_master_mode == 1)
355 b[2] = 0x00;
356 else
357 b[2] = (0x01 << 4); /* Master mode */
358
250 b[3] = 0x00; 359 b[3] = 0x00;
251 360
252 deb_info("modifying (%d) streaming state for %d\n", onoff, adap->id); 361 deb_info("modifying (%d) streaming state for %d\n", onoff, adap->id);
diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c
index 6c0e5c5f4362..0cfccc24b190 100644
--- a/drivers/media/dvb/dvb-usb/dib0700_devices.c
+++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c
@@ -14,6 +14,8 @@
14#include "mt2060.h" 14#include "mt2060.h"
15#include "mt2266.h" 15#include "mt2266.h"
16#include "tuner-xc2028.h" 16#include "tuner-xc2028.h"
17#include "xc5000.h"
18#include "s5h1411.h"
17#include "dib0070.h" 19#include "dib0070.h"
18 20
19static int force_lna_activation; 21static int force_lna_activation;
@@ -366,7 +368,8 @@ static struct dib7000p_config stk7700ph_dib7700_xc3028_config = {
366 .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS, 368 .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
367}; 369};
368 370
369static int stk7700ph_xc3028_callback(void *ptr, int command, int arg) 371static int stk7700ph_xc3028_callback(void *ptr, int component,
372 int command, int arg)
370{ 373{
371 struct dvb_usb_adapter *adap = ptr; 374 struct dvb_usb_adapter *adap = ptr;
372 375
@@ -394,7 +397,6 @@ static struct xc2028_ctrl stk7700ph_xc3028_ctrl = {
394 397
395static struct xc2028_config stk7700ph_xc3028_config = { 398static struct xc2028_config stk7700ph_xc3028_config = {
396 .i2c_addr = 0x61, 399 .i2c_addr = 0x61,
397 .callback = stk7700ph_xc3028_callback,
398 .ctrl = &stk7700ph_xc3028_ctrl, 400 .ctrl = &stk7700ph_xc3028_ctrl,
399}; 401};
400 402
@@ -435,7 +437,9 @@ static int stk7700ph_tuner_attach(struct dvb_usb_adapter *adap)
435 DIBX000_I2C_INTERFACE_TUNER, 1); 437 DIBX000_I2C_INTERFACE_TUNER, 1);
436 438
437 stk7700ph_xc3028_config.i2c_adap = tun_i2c; 439 stk7700ph_xc3028_config.i2c_adap = tun_i2c;
438 stk7700ph_xc3028_config.video_dev = adap; 440
441 /* FIXME: generalize & move to common area */
442 adap->fe->callback = stk7700ph_xc3028_callback;
439 443
440 return dvb_attach(xc2028_attach, adap->fe, &stk7700ph_xc3028_config) 444 return dvb_attach(xc2028_attach, adap->fe, &stk7700ph_xc3028_config)
441 == NULL ? -ENODEV : 0; 445 == NULL ? -ENODEV : 0;
@@ -677,6 +681,43 @@ static struct dvb_usb_rc_key dib0700_rc_keys[] = {
677 { 0x01, 0x7d, KEY_VOLUMEDOWN }, 681 { 0x01, 0x7d, KEY_VOLUMEDOWN },
678 { 0x02, 0x42, KEY_CHANNELUP }, 682 { 0x02, 0x42, KEY_CHANNELUP },
679 { 0x00, 0x7d, KEY_CHANNELDOWN }, 683 { 0x00, 0x7d, KEY_CHANNELDOWN },
684
685 /* Key codes for Nova-TD "credit card" remote control. */
686 { 0x1d, 0x00, KEY_0 },
687 { 0x1d, 0x01, KEY_1 },
688 { 0x1d, 0x02, KEY_2 },
689 { 0x1d, 0x03, KEY_3 },
690 { 0x1d, 0x04, KEY_4 },
691 { 0x1d, 0x05, KEY_5 },
692 { 0x1d, 0x06, KEY_6 },
693 { 0x1d, 0x07, KEY_7 },
694 { 0x1d, 0x08, KEY_8 },
695 { 0x1d, 0x09, KEY_9 },
696 { 0x1d, 0x0a, KEY_TEXT },
697 { 0x1d, 0x0d, KEY_MENU },
698 { 0x1d, 0x0f, KEY_MUTE },
699 { 0x1d, 0x10, KEY_VOLUMEUP },
700 { 0x1d, 0x11, KEY_VOLUMEDOWN },
701 { 0x1d, 0x12, KEY_CHANNEL },
702 { 0x1d, 0x14, KEY_UP },
703 { 0x1d, 0x15, KEY_DOWN },
704 { 0x1d, 0x16, KEY_LEFT },
705 { 0x1d, 0x17, KEY_RIGHT },
706 { 0x1d, 0x1c, KEY_TV },
707 { 0x1d, 0x1e, KEY_NEXT },
708 { 0x1d, 0x1f, KEY_BACK },
709 { 0x1d, 0x20, KEY_CHANNELUP },
710 { 0x1d, 0x21, KEY_CHANNELDOWN },
711 { 0x1d, 0x24, KEY_LAST },
712 { 0x1d, 0x25, KEY_OK },
713 { 0x1d, 0x30, KEY_PAUSE },
714 { 0x1d, 0x32, KEY_REWIND },
715 { 0x1d, 0x34, KEY_FASTFORWARD },
716 { 0x1d, 0x35, KEY_PLAY },
717 { 0x1d, 0x36, KEY_STOP },
718 { 0x1d, 0x37, KEY_RECORD },
719 { 0x1d, 0x3b, KEY_GOTO },
720 { 0x1d, 0x3d, KEY_POWER },
680}; 721};
681 722
682/* STK7700P: Hauppauge Nova-T Stick, AVerMedia Volar */ 723/* STK7700P: Hauppauge Nova-T Stick, AVerMedia Volar */
@@ -1078,6 +1119,97 @@ static int stk7070pd_frontend_attach1(struct dvb_usb_adapter *adap)
1078 return adap->fe == NULL ? -ENODEV : 0; 1119 return adap->fe == NULL ? -ENODEV : 0;
1079} 1120}
1080 1121
1122/* S5H1411 */
1123static struct s5h1411_config pinnacle_801e_config = {
1124 .output_mode = S5H1411_PARALLEL_OUTPUT,
1125 .gpio = S5H1411_GPIO_OFF,
1126 .mpeg_timing = S5H1411_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK,
1127 .qam_if = S5H1411_IF_44000,
1128 .vsb_if = S5H1411_IF_44000,
1129 .inversion = S5H1411_INVERSION_OFF,
1130 .status_mode = S5H1411_DEMODLOCKING
1131};
1132
1133/* Pinnacle PCTV HD Pro 801e GPIOs map:
1134 GPIO0 - currently unknown
1135 GPIO1 - xc5000 tuner reset
1136 GPIO2 - CX25843 sleep
1137 GPIO3 - currently unknown
1138 GPIO4 - currently unknown
1139 GPIO6 - currently unknown
1140 GPIO7 - currently unknown
1141 GPIO9 - currently unknown
1142 GPIO10 - CX25843 reset
1143 */
1144static int s5h1411_frontend_attach(struct dvb_usb_adapter *adap)
1145{
1146 struct dib0700_state *st = adap->dev->priv;
1147
1148 /* Make use of the new i2c functions from FW 1.20 */
1149 st->fw_use_new_i2c_api = 1;
1150
1151 /* The s5h1411 requires the dib0700 to not be in master mode */
1152 st->disable_streaming_master_mode = 1;
1153
1154 /* All msleep values taken from Windows USB trace */
1155 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 0);
1156 dib0700_set_gpio(adap->dev, GPIO3, GPIO_OUT, 0);
1157 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
1158 msleep(400);
1159 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
1160 msleep(60);
1161 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
1162 msleep(30);
1163 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
1164 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
1165 dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
1166 dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
1167 dib0700_set_gpio(adap->dev, GPIO2, GPIO_OUT, 0);
1168 msleep(30);
1169
1170 /* Put the CX25843 to sleep for now since we're in digital mode */
1171 dib0700_set_gpio(adap->dev, GPIO2, GPIO_OUT, 1);
1172
1173 /* GPIOs are initialized, do the attach */
1174 adap->fe = dvb_attach(s5h1411_attach, &pinnacle_801e_config,
1175 &adap->dev->i2c_adap);
1176 return adap->fe == NULL ? -ENODEV : 0;
1177}
1178
1179static int dib0700_xc5000_tuner_callback(void *priv, int component,
1180 int command, int arg)
1181{
1182 struct dvb_usb_adapter *adap = priv;
1183
1184 if (command == XC5000_TUNER_RESET) {
1185 /* Reset the tuner */
1186 dib0700_set_gpio(adap->dev, GPIO1, GPIO_OUT, 0);
1187 msleep(330); /* from Windows USB trace */
1188 dib0700_set_gpio(adap->dev, GPIO1, GPIO_OUT, 1);
1189 msleep(330); /* from Windows USB trace */
1190 } else {
1191 err("xc5000: unknown tuner callback command: %d\n", command);
1192 return -EINVAL;
1193 }
1194
1195 return 0;
1196}
1197
1198static struct xc5000_config s5h1411_xc5000_tunerconfig = {
1199 .i2c_address = 0x64,
1200 .if_khz = 5380,
1201};
1202
1203static int xc5000_tuner_attach(struct dvb_usb_adapter *adap)
1204{
1205 /* FIXME: generalize & move to common area */
1206 adap->fe->callback = dib0700_xc5000_tuner_callback;
1207
1208 return dvb_attach(xc5000_attach, adap->fe, &adap->dev->i2c_adap,
1209 &s5h1411_xc5000_tunerconfig)
1210 == NULL ? -ENODEV : 0;
1211}
1212
1081/* DVB-USB and USB stuff follows */ 1213/* DVB-USB and USB stuff follows */
1082struct usb_device_id dib0700_usb_id_table[] = { 1214struct usb_device_id dib0700_usb_id_table[] = {
1083/* 0 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK7700P) }, 1215/* 0 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK7700P) },
@@ -1119,6 +1251,11 @@ struct usb_device_id dib0700_usb_id_table[] = {
1119 { USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_STK7700P_2) }, 1251 { USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_STK7700P_2) },
1120/* 35 */{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_TD_STICK_52009) }, 1252/* 35 */{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_TD_STICK_52009) },
1121 { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_500_3) }, 1253 { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_500_3) },
1254 { USB_DEVICE(USB_VID_GIGABYTE, USB_PID_GIGABYTE_U8000) },
1255 { USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_STK7700PH) },
1256 { USB_DEVICE(USB_VID_ASUS, USB_PID_ASUS_U3000H) },
1257/* 40 */{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV801E) },
1258 { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV801E_SE) },
1122 { 0 } /* Terminating entry */ 1259 { 0 } /* Terminating entry */
1123}; 1260};
1124MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table); 1261MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table);
@@ -1126,7 +1263,7 @@ MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table);
1126#define DIB0700_DEFAULT_DEVICE_PROPERTIES \ 1263#define DIB0700_DEFAULT_DEVICE_PROPERTIES \
1127 .caps = DVB_USB_IS_AN_I2C_ADAPTER, \ 1264 .caps = DVB_USB_IS_AN_I2C_ADAPTER, \
1128 .usb_ctrl = DEVICE_SPECIFIC, \ 1265 .usb_ctrl = DEVICE_SPECIFIC, \
1129 .firmware = "dvb-usb-dib0700-1.10.fw", \ 1266 .firmware = "dvb-usb-dib0700-1.20.fw", \
1130 .download_firmware = dib0700_download_firmware, \ 1267 .download_firmware = dib0700_download_firmware, \
1131 .no_reconnect = 1, \ 1268 .no_reconnect = 1, \
1132 .size_of_priv = sizeof(struct dib0700_state), \ 1269 .size_of_priv = sizeof(struct dib0700_state), \
@@ -1293,7 +1430,12 @@ struct dvb_usb_device_properties dib0700_devices[] = {
1293 { &dib0700_usb_id_table[31], NULL }, 1430 { &dib0700_usb_id_table[31], NULL },
1294 { NULL }, 1431 { NULL },
1295 } 1432 }
1296 } 1433 },
1434
1435 .rc_interval = DEFAULT_RC_INTERVAL,
1436 .rc_key_map = dib0700_rc_keys,
1437 .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys),
1438 .rc_query = dib0700_rc_query
1297 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, 1439 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
1298 1440
1299 .num_adapters = 1, 1441 .num_adapters = 1,
@@ -1408,7 +1550,7 @@ struct dvb_usb_device_properties dib0700_devices[] = {
1408 }, 1550 },
1409 }, 1551 },
1410 1552
1411 .num_device_descs = 3, 1553 .num_device_descs = 5,
1412 .devices = { 1554 .devices = {
1413 { "Terratec Cinergy HT USB XE", 1555 { "Terratec Cinergy HT USB XE",
1414 { &dib0700_usb_id_table[27], NULL }, 1556 { &dib0700_usb_id_table[27], NULL },
@@ -1422,6 +1564,47 @@ struct dvb_usb_device_properties dib0700_devices[] = {
1422 { &dib0700_usb_id_table[32], NULL }, 1564 { &dib0700_usb_id_table[32], NULL },
1423 { NULL }, 1565 { NULL },
1424 }, 1566 },
1567 { "Gigabyte U8000-RH",
1568 { &dib0700_usb_id_table[37], NULL },
1569 { NULL },
1570 },
1571 { "YUAN High-Tech STK7700PH",
1572 { &dib0700_usb_id_table[38], NULL },
1573 { NULL },
1574 },
1575 { "Asus My Cinema-U3000Hybrid",
1576 { &dib0700_usb_id_table[39], NULL },
1577 { NULL },
1578 },
1579 },
1580 .rc_interval = DEFAULT_RC_INTERVAL,
1581 .rc_key_map = dib0700_rc_keys,
1582 .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys),
1583 .rc_query = dib0700_rc_query
1584 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
1585 .num_adapters = 1,
1586 .adapter = {
1587 {
1588 .frontend_attach = s5h1411_frontend_attach,
1589 .tuner_attach = xc5000_tuner_attach,
1590
1591 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
1592
1593 .size_of_priv = sizeof(struct
1594 dib0700_adapter_state),
1595 },
1596 },
1597
1598 .num_device_descs = 2,
1599 .devices = {
1600 { "Pinnacle PCTV HD Pro USB Stick",
1601 { &dib0700_usb_id_table[40], NULL },
1602 { NULL },
1603 },
1604 { "Pinnacle PCTV HD USB Stick",
1605 { &dib0700_usb_id_table[41], NULL },
1606 { NULL },
1607 },
1425 }, 1608 },
1426 .rc_interval = DEFAULT_RC_INTERVAL, 1609 .rc_interval = DEFAULT_RC_INTERVAL,
1427 .rc_key_map = dib0700_rc_keys, 1610 .rc_key_map = dib0700_rc_keys,
diff --git a/drivers/media/dvb/dvb-usb/dtv5100.c b/drivers/media/dvb/dvb-usb/dtv5100.c
new file mode 100644
index 000000000000..078ce92ca436
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dtv5100.c
@@ -0,0 +1,240 @@
1/*
2 * DVB USB Linux driver for AME DTV-5100 USB2.0 DVB-T
3 *
4 * Copyright (C) 2008 Antoine Jacquet <royale@zerezo.com>
5 * http://royale.zerezo.com/dtv5100/
6 *
7 * Inspired by gl861.c and au6610.c drivers
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
24#include "dtv5100.h"
25#include "zl10353.h"
26#include "qt1010.h"
27
28/* debug */
29static int dvb_usb_dtv5100_debug;
30module_param_named(debug, dvb_usb_dtv5100_debug, int, 0644);
31MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS);
32DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
33
34static int dtv5100_i2c_msg(struct dvb_usb_device *d, u8 addr,
35 u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen)
36{
37 u8 request;
38 u8 type;
39 u16 value;
40 u16 index;
41
42 switch (wlen) {
43 case 1:
44 /* write { reg }, read { value } */
45 request = (addr == DTV5100_DEMOD_ADDR ? DTV5100_DEMOD_READ :
46 DTV5100_TUNER_READ);
47 type = USB_TYPE_VENDOR | USB_DIR_IN;
48 value = 0;
49 break;
50 case 2:
51 /* write { reg, value } */
52 request = (addr == DTV5100_DEMOD_ADDR ? DTV5100_DEMOD_WRITE :
53 DTV5100_TUNER_WRITE);
54 type = USB_TYPE_VENDOR | USB_DIR_OUT;
55 value = wbuf[1];
56 break;
57 default:
58 warn("wlen = %x, aborting.", wlen);
59 return -EINVAL;
60 }
61 index = (addr << 8) + wbuf[0];
62
63 msleep(1); /* avoid I2C errors */
64 return usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), request,
65 type, value, index, rbuf, rlen,
66 DTV5100_USB_TIMEOUT);
67}
68
69/* I2C */
70static int dtv5100_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
71 int num)
72{
73 struct dvb_usb_device *d = i2c_get_adapdata(adap);
74 int i;
75
76 if (num > 2)
77 return -EINVAL;
78
79 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
80 return -EAGAIN;
81
82 for (i = 0; i < num; i++) {
83 /* write/read request */
84 if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) {
85 if (dtv5100_i2c_msg(d, msg[i].addr, msg[i].buf,
86 msg[i].len, msg[i+1].buf,
87 msg[i+1].len) < 0)
88 break;
89 i++;
90 } else if (dtv5100_i2c_msg(d, msg[i].addr, msg[i].buf,
91 msg[i].len, NULL, 0) < 0)
92 break;
93 }
94
95 mutex_unlock(&d->i2c_mutex);
96 return i;
97}
98
99static u32 dtv5100_i2c_func(struct i2c_adapter *adapter)
100{
101 return I2C_FUNC_I2C;
102}
103
104static struct i2c_algorithm dtv5100_i2c_algo = {
105 .master_xfer = dtv5100_i2c_xfer,
106 .functionality = dtv5100_i2c_func,
107};
108
109/* Callbacks for DVB USB */
110static struct zl10353_config dtv5100_zl10353_config = {
111 .demod_address = DTV5100_DEMOD_ADDR,
112 .no_tuner = 1,
113 .parallel_ts = 1,
114};
115
116static int dtv5100_frontend_attach(struct dvb_usb_adapter *adap)
117{
118 adap->fe = dvb_attach(zl10353_attach, &dtv5100_zl10353_config,
119 &adap->dev->i2c_adap);
120 if (adap->fe == NULL)
121 return -EIO;
122
123 /* disable i2c gate, or it won't work... is this safe? */
124 adap->fe->ops.i2c_gate_ctrl = NULL;
125
126 return 0;
127}
128
129static struct qt1010_config dtv5100_qt1010_config = {
130 .i2c_address = DTV5100_TUNER_ADDR
131};
132
133static int dtv5100_tuner_attach(struct dvb_usb_adapter *adap)
134{
135 return dvb_attach(qt1010_attach,
136 adap->fe, &adap->dev->i2c_adap,
137 &dtv5100_qt1010_config) == NULL ? -ENODEV : 0;
138}
139
140/* DVB USB Driver stuff */
141static struct dvb_usb_device_properties dtv5100_properties;
142
143static int dtv5100_probe(struct usb_interface *intf,
144 const struct usb_device_id *id)
145{
146 int i, ret;
147 struct usb_device *udev = interface_to_usbdev(intf);
148
149 /* initialize non qt1010/zl10353 part? */
150 for (i = 0; dtv5100_init[i].request; i++) {
151 ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
152 dtv5100_init[i].request,
153 USB_TYPE_VENDOR | USB_DIR_OUT,
154 dtv5100_init[i].value,
155 dtv5100_init[i].index, NULL, 0,
156 DTV5100_USB_TIMEOUT);
157 if (ret)
158 return ret;
159 }
160
161 ret = dvb_usb_device_init(intf, &dtv5100_properties,
162 THIS_MODULE, NULL, adapter_nr);
163 if (ret)
164 return ret;
165
166 return 0;
167}
168
169static struct usb_device_id dtv5100_table[] = {
170 { USB_DEVICE(0x06be, 0xa232) },
171 { } /* Terminating entry */
172};
173MODULE_DEVICE_TABLE(usb, dtv5100_table);
174
175static struct dvb_usb_device_properties dtv5100_properties = {
176 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
177 .usb_ctrl = DEVICE_SPECIFIC,
178
179 .size_of_priv = 0,
180
181 .num_adapters = 1,
182 .adapter = {{
183 .frontend_attach = dtv5100_frontend_attach,
184 .tuner_attach = dtv5100_tuner_attach,
185
186 .stream = {
187 .type = USB_BULK,
188 .count = 8,
189 .endpoint = 0x82,
190 .u = {
191 .bulk = {
192 .buffersize = 4096,
193 }
194 }
195 },
196 } },
197
198 .i2c_algo = &dtv5100_i2c_algo,
199
200 .num_device_descs = 1,
201 .devices = {
202 {
203 .name = "AME DTV-5100 USB2.0 DVB-T",
204 .cold_ids = { NULL },
205 .warm_ids = { &dtv5100_table[0], NULL },
206 },
207 }
208};
209
210static struct usb_driver dtv5100_driver = {
211 .name = "dvb_usb_dtv5100",
212 .probe = dtv5100_probe,
213 .disconnect = dvb_usb_device_exit,
214 .id_table = dtv5100_table,
215};
216
217/* module stuff */
218static int __init dtv5100_module_init(void)
219{
220 int ret;
221
222 ret = usb_register(&dtv5100_driver);
223 if (ret)
224 err("usb_register failed. Error number %d", ret);
225
226 return ret;
227}
228
229static void __exit dtv5100_module_exit(void)
230{
231 /* deregister this driver from the USB subsystem */
232 usb_deregister(&dtv5100_driver);
233}
234
235module_init(dtv5100_module_init);
236module_exit(dtv5100_module_exit);
237
238MODULE_AUTHOR(DRIVER_AUTHOR);
239MODULE_DESCRIPTION(DRIVER_DESC);
240MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/dtv5100.h b/drivers/media/dvb/dvb-usb/dtv5100.h
new file mode 100644
index 000000000000..93e96e04a82a
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dtv5100.h
@@ -0,0 +1,51 @@
1/*
2 * DVB USB Linux driver for AME DTV-5100 USB2.0 DVB-T
3 *
4 * Copyright (C) 2008 Antoine Jacquet <royale@zerezo.com>
5 * http://royale.zerezo.com/dtv5100/
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22#ifndef _DVB_USB_DTV5100_H_
23#define _DVB_USB_DTV5100_H_
24
25#define DVB_USB_LOG_PREFIX "dtv5100"
26#include "dvb-usb.h"
27
28#define DTV5100_USB_TIMEOUT 500
29
30#define DTV5100_DEMOD_ADDR 0x00
31#define DTV5100_DEMOD_WRITE 0xc0
32#define DTV5100_DEMOD_READ 0xc1
33
34#define DTV5100_TUNER_ADDR 0xc4
35#define DTV5100_TUNER_WRITE 0xc7
36#define DTV5100_TUNER_READ 0xc8
37
38#define DRIVER_AUTHOR "Antoine Jacquet, http://royale.zerezo.com/"
39#define DRIVER_DESC "AME DTV-5100 USB2.0 DVB-T"
40
41static struct {
42 u8 request;
43 u8 value;
44 u16 index;
45} dtv5100_init[] = {
46 { 0x000000c5, 0x00000000, 0x00000001 },
47 { 0x000000c5, 0x00000001, 0x00000001 },
48 { } /* Terminating entry */
49};
50
51#endif
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
index 03dfb9f2fe30..7380b94b3b36 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
@@ -22,6 +22,7 @@
22#define USB_VID_AVERMEDIA 0x07ca 22#define USB_VID_AVERMEDIA 0x07ca
23#define USB_VID_COMPRO 0x185b 23#define USB_VID_COMPRO 0x185b
24#define USB_VID_COMPRO_UNK 0x145f 24#define USB_VID_COMPRO_UNK 0x145f
25#define USB_VID_CONEXANT 0x0572
25#define USB_VID_CYPRESS 0x04b4 26#define USB_VID_CYPRESS 0x04b4
26#define USB_VID_DIBCOM 0x10b8 27#define USB_VID_DIBCOM 0x10b8
27#define USB_VID_DPOSH 0x1498 28#define USB_VID_DPOSH 0x1498
@@ -33,16 +34,19 @@
33#define USB_VID_HAUPPAUGE 0x2040 34#define USB_VID_HAUPPAUGE 0x2040
34#define USB_VID_HYPER_PALTEK 0x1025 35#define USB_VID_HYPER_PALTEK 0x1025
35#define USB_VID_KWORLD 0xeb2a 36#define USB_VID_KWORLD 0xeb2a
37#define USB_VID_KWORLD_2 0x1b80
36#define USB_VID_KYE 0x0458 38#define USB_VID_KYE 0x0458
37#define USB_VID_LEADTEK 0x0413 39#define USB_VID_LEADTEK 0x0413
38#define USB_VID_LITEON 0x04ca 40#define USB_VID_LITEON 0x04ca
39#define USB_VID_MEDION 0x1660 41#define USB_VID_MEDION 0x1660
40#define USB_VID_MIGLIA 0x18f3 42#define USB_VID_MIGLIA 0x18f3
41#define USB_VID_MSI 0x0db0 43#define USB_VID_MSI 0x0db0
44#define USB_VID_MSI_2 0x1462
42#define USB_VID_OPERA1 0x695c 45#define USB_VID_OPERA1 0x695c
43#define USB_VID_PINNACLE 0x2304 46#define USB_VID_PINNACLE 0x2304
44#define USB_VID_TECHNOTREND 0x0b48 47#define USB_VID_TECHNOTREND 0x0b48
45#define USB_VID_TERRATEC 0x0ccd 48#define USB_VID_TERRATEC 0x0ccd
49#define USB_VID_TELESTAR 0x10b9
46#define USB_VID_VISIONPLUS 0x13d3 50#define USB_VID_VISIONPLUS 0x13d3
47#define USB_VID_TWINHAN 0x1822 51#define USB_VID_TWINHAN 0x1822
48#define USB_VID_ULTIMA_ELECTRONIC 0x05d8 52#define USB_VID_ULTIMA_ELECTRONIC 0x05d8
@@ -50,15 +54,18 @@
50#define USB_VID_WIDEVIEW 0x14aa 54#define USB_VID_WIDEVIEW 0x14aa
51#define USB_VID_GIGABYTE 0x1044 55#define USB_VID_GIGABYTE 0x1044
52#define USB_VID_YUAN 0x1164 56#define USB_VID_YUAN 0x1164
53 57#define USB_VID_XTENSIONS 0x1ae7
54 58
55/* Product IDs */ 59/* Product IDs */
56#define USB_PID_ADSTECH_USB2_COLD 0xa333 60#define USB_PID_ADSTECH_USB2_COLD 0xa333
57#define USB_PID_ADSTECH_USB2_WARM 0xa334 61#define USB_PID_ADSTECH_USB2_WARM 0xa334
58#define USB_PID_AFATECH_AF9005 0x9020 62#define USB_PID_AFATECH_AF9005 0x9020
63#define USB_PID_AFATECH_AF9015_9015 0x9015
64#define USB_PID_AFATECH_AF9015_9016 0x9016
59#define USB_VID_ALINK_DTU 0xf170 65#define USB_VID_ALINK_DTU 0xf170
60#define USB_PID_ANSONIC_DVBT_USB 0x6000 66#define USB_PID_ANSONIC_DVBT_USB 0x6000
61#define USB_PID_ANYSEE 0x861f 67#define USB_PID_ANYSEE 0x861f
68#define USB_PID_AZUREWAVE_AD_TU700 0x3237
62#define USB_PID_AVERMEDIA_DVBT_USB_COLD 0x0001 69#define USB_PID_AVERMEDIA_DVBT_USB_COLD 0x0001
63#define USB_PID_AVERMEDIA_DVBT_USB_WARM 0x0002 70#define USB_PID_AVERMEDIA_DVBT_USB_WARM 0x0002
64#define USB_PID_AVERMEDIA_DVBT_USB2_COLD 0xa800 71#define USB_PID_AVERMEDIA_DVBT_USB2_COLD 0xa800
@@ -69,6 +76,7 @@
69#define USB_PID_COMPRO_DVBU2000_UNK_WARM 0x010d 76#define USB_PID_COMPRO_DVBU2000_UNK_WARM 0x010d
70#define USB_PID_COMPRO_VIDEOMATE_U500 0x1e78 77#define USB_PID_COMPRO_VIDEOMATE_U500 0x1e78
71#define USB_PID_COMPRO_VIDEOMATE_U500_PC 0x1e80 78#define USB_PID_COMPRO_VIDEOMATE_U500_PC 0x1e80
79#define USB_PID_CONEXANT_D680_DMB 0x86d6
72#define USB_PID_DIBCOM_HOOK_DEFAULT 0x0064 80#define USB_PID_DIBCOM_HOOK_DEFAULT 0x0064
73#define USB_PID_DIBCOM_HOOK_DEFAULT_REENUM 0x0065 81#define USB_PID_DIBCOM_HOOK_DEFAULT_REENUM 0x0065
74#define USB_PID_DIBCOM_MOD3000_COLD 0x0bb8 82#define USB_PID_DIBCOM_MOD3000_COLD 0x0bb8
@@ -87,9 +95,12 @@
87#define USB_PID_UNIWILL_STK7700P 0x6003 95#define USB_PID_UNIWILL_STK7700P 0x6003
88#define USB_PID_GRANDTEC_DVBT_USB_COLD 0x0fa0 96#define USB_PID_GRANDTEC_DVBT_USB_COLD 0x0fa0
89#define USB_PID_GRANDTEC_DVBT_USB_WARM 0x0fa1 97#define USB_PID_GRANDTEC_DVBT_USB_WARM 0x0fa1
98#define USB_PID_KWORLD_399U 0xe399
99#define USB_PID_KWORLD_PC160_2T 0xc160
90#define USB_PID_KWORLD_VSTREAM_COLD 0x17de 100#define USB_PID_KWORLD_VSTREAM_COLD 0x17de
91#define USB_PID_KWORLD_VSTREAM_WARM 0x17df 101#define USB_PID_KWORLD_VSTREAM_WARM 0x17df
92#define USB_PID_TERRATEC_CINERGY_T_USB_XE 0x0055 102#define USB_PID_TERRATEC_CINERGY_T_USB_XE 0x0055
103#define USB_PID_TERRATEC_CINERGY_T_USB_XE_REV2 0x0069
93#define USB_PID_TWINHAN_VP7041_COLD 0x3201 104#define USB_PID_TWINHAN_VP7041_COLD 0x3201
94#define USB_PID_TWINHAN_VP7041_WARM 0x3202 105#define USB_PID_TWINHAN_VP7041_WARM 0x3202
95#define USB_PID_TWINHAN_VP7020_COLD 0x3203 106#define USB_PID_TWINHAN_VP7020_COLD 0x3203
@@ -98,6 +109,7 @@
98#define USB_PID_TWINHAN_VP7045_WARM 0x3206 109#define USB_PID_TWINHAN_VP7045_WARM 0x3206
99#define USB_PID_TWINHAN_VP7021_COLD 0x3207 110#define USB_PID_TWINHAN_VP7021_COLD 0x3207
100#define USB_PID_TWINHAN_VP7021_WARM 0x3208 111#define USB_PID_TWINHAN_VP7021_WARM 0x3208
112#define USB_PID_TINYTWIN 0x3226
101#define USB_PID_DNTV_TINYUSB2_COLD 0x3223 113#define USB_PID_DNTV_TINYUSB2_COLD 0x3223
102#define USB_PID_DNTV_TINYUSB2_WARM 0x3224 114#define USB_PID_DNTV_TINYUSB2_WARM 0x3224
103#define USB_PID_ULTIMA_TVBOX_COLD 0x8105 115#define USB_PID_ULTIMA_TVBOX_COLD 0x8105
@@ -144,6 +156,9 @@
144#define USB_PID_AVERMEDIA_HYBRID_ULTRA_USB_M039R 0x0039 156#define USB_PID_AVERMEDIA_HYBRID_ULTRA_USB_M039R 0x0039
145#define USB_PID_AVERMEDIA_HYBRID_ULTRA_USB_M039R_ATSC 0x1039 157#define USB_PID_AVERMEDIA_HYBRID_ULTRA_USB_M039R_ATSC 0x1039
146#define USB_PID_AVERMEDIA_HYBRID_ULTRA_USB_M039R_DVBT 0x2039 158#define USB_PID_AVERMEDIA_HYBRID_ULTRA_USB_M039R_DVBT 0x2039
159#define USB_PID_AVERMEDIA_VOLAR_X 0xa815
160#define USB_PID_AVERMEDIA_VOLAR_X_2 0x8150
161#define USB_PID_AVERMEDIA_A309 0xa309
147#define USB_PID_TECHNOTREND_CONNECT_S2400 0x3006 162#define USB_PID_TECHNOTREND_CONNECT_S2400 0x3006
148#define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY 0x005a 163#define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY 0x005a
149#define USB_PID_TERRATEC_CINERGY_HT_USB_XE 0x0058 164#define USB_PID_TERRATEC_CINERGY_HT_USB_XE 0x0058
@@ -153,8 +168,11 @@
153#define USB_PID_PINNACLE_PCTV2000E 0x022c 168#define USB_PID_PINNACLE_PCTV2000E 0x022c
154#define USB_PID_PINNACLE_PCTV_DVB_T_FLASH 0x0228 169#define USB_PID_PINNACLE_PCTV_DVB_T_FLASH 0x0228
155#define USB_PID_PINNACLE_PCTV_DUAL_DIVERSITY_DVB_T 0x0229 170#define USB_PID_PINNACLE_PCTV_DUAL_DIVERSITY_DVB_T 0x0229
171#define USB_PID_PINNACLE_PCTV71E 0x022b
156#define USB_PID_PINNACLE_PCTV72E 0x0236 172#define USB_PID_PINNACLE_PCTV72E 0x0236
157#define USB_PID_PINNACLE_PCTV73E 0x0237 173#define USB_PID_PINNACLE_PCTV73E 0x0237
174#define USB_PID_PINNACLE_PCTV801E 0x023a
175#define USB_PID_PINNACLE_PCTV801E_SE 0x023b
158#define USB_PID_PCTV_200E 0x020e 176#define USB_PID_PCTV_200E 0x020e
159#define USB_PID_PCTV_400E 0x020f 177#define USB_PID_PCTV_400E 0x020f
160#define USB_PID_PCTV_450E 0x0222 178#define USB_PID_PCTV_450E 0x0222
@@ -171,6 +189,7 @@
171#define USB_PID_DVICO_BLUEBIRD_DUAL_2_COLD 0xdb58 189#define USB_PID_DVICO_BLUEBIRD_DUAL_2_COLD 0xdb58
172#define USB_PID_DVICO_BLUEBIRD_DUAL_2_WARM 0xdb59 190#define USB_PID_DVICO_BLUEBIRD_DUAL_2_WARM 0xdb59
173#define USB_PID_DVICO_BLUEBIRD_DUAL_4 0xdb78 191#define USB_PID_DVICO_BLUEBIRD_DUAL_4 0xdb78
192#define USB_PID_DVICO_BLUEBIRD_DUAL_4_REV_2 0xdb98
174#define USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2 0xdb70 193#define USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2 0xdb70
175#define USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2_NFW_WARM 0xdb71 194#define USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2_NFW_WARM 0xdb71
176#define USB_PID_DIGITALNOW_BLUEBIRD_DUAL_1_COLD 0xdb54 195#define USB_PID_DIGITALNOW_BLUEBIRD_DUAL_1_COLD 0xdb54
@@ -190,6 +209,7 @@
190#define USB_PID_WINFAST_DTV_DONGLE_WARM 0x6026 209#define USB_PID_WINFAST_DTV_DONGLE_WARM 0x6026
191#define USB_PID_WINFAST_DTV_DONGLE_STK7700P 0x6f00 210#define USB_PID_WINFAST_DTV_DONGLE_STK7700P 0x6f00
192#define USB_PID_WINFAST_DTV_DONGLE_STK7700P_2 0x6f01 211#define USB_PID_WINFAST_DTV_DONGLE_STK7700P_2 0x6f01
212#define USB_PID_WINFAST_DTV_DONGLE_GOLD 0x6029
193#define USB_PID_GENPIX_8PSK_REV_1_COLD 0x0200 213#define USB_PID_GENPIX_8PSK_REV_1_COLD 0x0200
194#define USB_PID_GENPIX_8PSK_REV_1_WARM 0x0201 214#define USB_PID_GENPIX_8PSK_REV_1_WARM 0x0201
195#define USB_PID_GENPIX_8PSK_REV_2 0x0202 215#define USB_PID_GENPIX_8PSK_REV_2 0x0202
@@ -197,14 +217,21 @@
197#define USB_PID_GENPIX_SKYWALKER_CW3K 0x0204 217#define USB_PID_GENPIX_SKYWALKER_CW3K 0x0204
198#define USB_PID_SIGMATEK_DVB_110 0x6610 218#define USB_PID_SIGMATEK_DVB_110 0x6610
199#define USB_PID_MSI_DIGI_VOX_MINI_II 0x1513 219#define USB_PID_MSI_DIGI_VOX_MINI_II 0x1513
220#define USB_PID_MSI_DIGIVOX_DUO 0x8801
200#define USB_PID_OPERA1_COLD 0x2830 221#define USB_PID_OPERA1_COLD 0x2830
201#define USB_PID_OPERA1_WARM 0x3829 222#define USB_PID_OPERA1_WARM 0x3829
202#define USB_PID_LIFEVIEW_TV_WALKER_TWIN_COLD 0x0514 223#define USB_PID_LIFEVIEW_TV_WALKER_TWIN_COLD 0x0514
203#define USB_PID_LIFEVIEW_TV_WALKER_TWIN_WARM 0x0513 224#define USB_PID_LIFEVIEW_TV_WALKER_TWIN_WARM 0x0513
204#define USB_PID_GIGABYTE_U7000 0x7001 225#define USB_PID_GIGABYTE_U7000 0x7001
226#define USB_PID_GIGABYTE_U8000 0x7002
205#define USB_PID_ASUS_U3000 0x171f 227#define USB_PID_ASUS_U3000 0x171f
228#define USB_PID_ASUS_U3000H 0x1736
206#define USB_PID_ASUS_U3100 0x173f 229#define USB_PID_ASUS_U3100 0x173f
207#define USB_PID_YUAN_EC372S 0x1edc 230#define USB_PID_YUAN_EC372S 0x1edc
231#define USB_PID_YUAN_STK7700PH 0x1f08
208#define USB_PID_DW2102 0x2102 232#define USB_PID_DW2102 0x2102
233#define USB_PID_XTENSIONS_XD_380 0x0381
234#define USB_PID_TELESTAR_STARSTICK_2 0x8000
235#define USB_PID_MSI_DIGI_VOX_MINI_III 0x8807
209 236
210#endif 237#endif
diff --git a/drivers/media/dvb/dvb-usb/dw2102.c b/drivers/media/dvb/dvb-usb/dw2102.c
index a4d898b44e55..ca53df61caa8 100644
--- a/drivers/media/dvb/dvb-usb/dw2102.c
+++ b/drivers/media/dvb/dvb-usb/dw2102.c
@@ -1,4 +1,5 @@
1/* DVB USB framework compliant Linux driver for the DVBWorld DVB-S 2102 Card 1/* DVB USB framework compliant Linux driver for the
2* DVBWorld DVB-S 2101, 2102, DVB-S2 2104 Card
2* 3*
3* Copyright (C) 2008 Igor M. Liplianin (liplianin@me.by) 4* Copyright (C) 2008 Igor M. Liplianin (liplianin@me.by)
4* 5*
@@ -10,62 +11,74 @@
10*/ 11*/
11#include <linux/version.h> 12#include <linux/version.h>
12#include "dw2102.h" 13#include "dw2102.h"
14#include "si21xx.h"
13#include "stv0299.h" 15#include "stv0299.h"
14#include "z0194a.h" 16#include "z0194a.h"
17#include "stv0288.h"
18#include "stb6000.h"
19#include "eds1547.h"
20#include "cx24116.h"
15 21
16#ifndef USB_PID_DW2102 22#ifndef USB_PID_DW2102
17#define USB_PID_DW2102 0x2102 23#define USB_PID_DW2102 0x2102
18#endif 24#endif
19 25
20#define DW2102_READ_MSG 0 26#ifndef USB_PID_DW2104
21#define DW2102_WRITE_MSG 1 27#define USB_PID_DW2104 0x2104
28#endif
29
30#define DW210X_READ_MSG 0
31#define DW210X_WRITE_MSG 1
22 32
23#define REG_1F_SYMBOLRATE_BYTE0 0x1f 33#define REG_1F_SYMBOLRATE_BYTE0 0x1f
24#define REG_20_SYMBOLRATE_BYTE1 0x20 34#define REG_20_SYMBOLRATE_BYTE1 0x20
25#define REG_21_SYMBOLRATE_BYTE2 0x21 35#define REG_21_SYMBOLRATE_BYTE2 0x21
26 36/* on my own*/
27#define DW2102_VOLTAGE_CTRL (0x1800) 37#define DW2102_VOLTAGE_CTRL (0x1800)
28#define DW2102_RC_QUERY (0x1a00) 38#define DW2102_RC_QUERY (0x1a00)
29 39
30struct dw2102_state { 40struct dw210x_state {
31 u32 last_key_pressed; 41 u32 last_key_pressed;
32}; 42};
33struct dw2102_rc_keys { 43struct dw210x_rc_keys {
34 u32 keycode; 44 u32 keycode;
35 u32 event; 45 u32 event;
36}; 46};
37 47
48/* debug */
49static int dvb_usb_dw2102_debug;
50module_param_named(debug, dvb_usb_dw2102_debug, int, 0644);
51MODULE_PARM_DESC(debug, "set debugging level (1=info 2=xfer (or-able))." DVB_USB_DEBUG_STATUS);
52
38DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); 53DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
39 54
40static int dw2102_op_rw(struct usb_device *dev, u8 request, u16 value, 55static int dw210x_op_rw(struct usb_device *dev, u8 request, u16 value,
41 u8 *data, u16 len, int flags) 56 u16 index, u8 * data, u16 len, int flags)
42{ 57{
43 int ret; 58 int ret;
44 u8 u8buf[len]; 59 u8 u8buf[len];
45 60
46 unsigned int pipe = (flags == DW2102_READ_MSG) ? 61 unsigned int pipe = (flags == DW210X_READ_MSG) ?
47 usb_rcvctrlpipe(dev, 0) : usb_sndctrlpipe(dev, 0); 62 usb_rcvctrlpipe(dev, 0) : usb_sndctrlpipe(dev, 0);
48 u8 request_type = (flags == DW2102_READ_MSG) ? USB_DIR_IN : USB_DIR_OUT; 63 u8 request_type = (flags == DW210X_READ_MSG) ? USB_DIR_IN : USB_DIR_OUT;
49 64
50 if (flags == DW2102_WRITE_MSG) 65 if (flags == DW210X_WRITE_MSG)
51 memcpy(u8buf, data, len); 66 memcpy(u8buf, data, len);
52 ret = usb_control_msg(dev, pipe, request, 67 ret = usb_control_msg(dev, pipe, request, request_type | USB_TYPE_VENDOR,
53 request_type | USB_TYPE_VENDOR, value, 0 , u8buf, len, 2000); 68 value, index , u8buf, len, 2000);
54 69
55 if (flags == DW2102_READ_MSG) 70 if (flags == DW210X_READ_MSG)
56 memcpy(data, u8buf, len); 71 memcpy(data, u8buf, len);
57 return ret; 72 return ret;
58} 73}
59 74
60/* I2C */ 75/* I2C */
61
62static int dw2102_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], 76static int dw2102_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
63 int num) 77 int num)
64{ 78{
65struct dvb_usb_device *d = i2c_get_adapdata(adap); 79struct dvb_usb_device *d = i2c_get_adapdata(adap);
66 int i = 0, ret = 0; 80 int i = 0, ret = 0;
67 u8 buf6[] = {0x2c, 0x05, 0xc0, 0, 0, 0, 0}; 81 u8 buf6[] = {0x2c, 0x05, 0xc0, 0, 0, 0, 0};
68 u8 request;
69 u16 value; 82 u16 value;
70 83
71 if (!d) 84 if (!d)
@@ -76,14 +89,12 @@ struct dvb_usb_device *d = i2c_get_adapdata(adap);
76 switch (num) { 89 switch (num) {
77 case 2: 90 case 2:
78 /* read stv0299 register */ 91 /* read stv0299 register */
79 request = 0xb5;
80 value = msg[0].buf[0];/* register */ 92 value = msg[0].buf[0];/* register */
81 for (i = 0; i < msg[1].len; i++) { 93 for (i = 0; i < msg[1].len; i++) {
82 value = value + i; 94 value = value + i;
83 ret = dw2102_op_rw(d->udev, 0xb5, 95 ret = dw210x_op_rw(d->udev, 0xb5, value, 0,
84 value, buf6, 2, DW2102_READ_MSG); 96 buf6, 2, DW210X_READ_MSG);
85 msg[1].buf[i] = buf6[0]; 97 msg[1].buf[i] = buf6[0];
86
87 } 98 }
88 break; 99 break;
89 case 1: 100 case 1:
@@ -93,8 +104,8 @@ struct dvb_usb_device *d = i2c_get_adapdata(adap);
93 buf6[0] = 0x2a; 104 buf6[0] = 0x2a;
94 buf6[1] = msg[0].buf[0]; 105 buf6[1] = msg[0].buf[0];
95 buf6[2] = msg[0].buf[1]; 106 buf6[2] = msg[0].buf[1];
96 ret = dw2102_op_rw(d->udev, 0xb2, 107 ret = dw210x_op_rw(d->udev, 0xb2, 0, 0,
97 0, buf6, 3, DW2102_WRITE_MSG); 108 buf6, 3, DW210X_WRITE_MSG);
98 break; 109 break;
99 case 0x60: 110 case 0x60:
100 if (msg[0].flags == 0) { 111 if (msg[0].flags == 0) {
@@ -106,26 +117,26 @@ struct dvb_usb_device *d = i2c_get_adapdata(adap);
106 buf6[4] = msg[0].buf[1]; 117 buf6[4] = msg[0].buf[1];
107 buf6[5] = msg[0].buf[2]; 118 buf6[5] = msg[0].buf[2];
108 buf6[6] = msg[0].buf[3]; 119 buf6[6] = msg[0].buf[3];
109 ret = dw2102_op_rw(d->udev, 0xb2, 120 ret = dw210x_op_rw(d->udev, 0xb2, 0, 0,
110 0, buf6, 7, DW2102_WRITE_MSG); 121 buf6, 7, DW210X_WRITE_MSG);
111 } else { 122 } else {
112 /* write to tuner pll */ 123 /* read from tuner */
113 ret = dw2102_op_rw(d->udev, 0xb5, 124 ret = dw210x_op_rw(d->udev, 0xb5, 0, 0,
114 0, buf6, 1, DW2102_READ_MSG); 125 buf6, 1, DW210X_READ_MSG);
115 msg[0].buf[0] = buf6[0]; 126 msg[0].buf[0] = buf6[0];
116 } 127 }
117 break; 128 break;
118 case (DW2102_RC_QUERY): 129 case (DW2102_RC_QUERY):
119 ret = dw2102_op_rw(d->udev, 0xb8, 130 ret = dw210x_op_rw(d->udev, 0xb8, 0, 0,
120 0, buf6, 2, DW2102_READ_MSG); 131 buf6, 2, DW210X_READ_MSG);
121 msg[0].buf[0] = buf6[0]; 132 msg[0].buf[0] = buf6[0];
122 msg[0].buf[1] = buf6[1]; 133 msg[0].buf[1] = buf6[1];
123 break; 134 break;
124 case (DW2102_VOLTAGE_CTRL): 135 case (DW2102_VOLTAGE_CTRL):
125 buf6[0] = 0x30; 136 buf6[0] = 0x30;
126 buf6[1] = msg[0].buf[0]; 137 buf6[1] = msg[0].buf[0];
127 ret = dw2102_op_rw(d->udev, 0xb2, 138 ret = dw210x_op_rw(d->udev, 0xb2, 0, 0,
128 0, buf6, 2, DW2102_WRITE_MSG); 139 buf6, 2, DW210X_WRITE_MSG);
129 break; 140 break;
130 } 141 }
131 142
@@ -136,17 +147,265 @@ struct dvb_usb_device *d = i2c_get_adapdata(adap);
136 return num; 147 return num;
137} 148}
138 149
139static u32 dw2102_i2c_func(struct i2c_adapter *adapter) 150static int dw2102_serit_i2c_transfer(struct i2c_adapter *adap,
151 struct i2c_msg msg[], int num)
152{
153 struct dvb_usb_device *d = i2c_get_adapdata(adap);
154 int ret = 0;
155 u8 buf6[] = {0, 0, 0, 0, 0, 0, 0};
156
157 if (!d)
158 return -ENODEV;
159 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
160 return -EAGAIN;
161
162 switch (num) {
163 case 2:
164 /* read si2109 register by number */
165 buf6[0] = 0xd0;
166 buf6[1] = msg[0].len;
167 buf6[2] = msg[0].buf[0];
168 ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
169 buf6, msg[0].len + 2, DW210X_WRITE_MSG);
170 /* read si2109 register */
171 ret = dw210x_op_rw(d->udev, 0xc3, 0xd0, 0,
172 buf6, msg[1].len + 2, DW210X_READ_MSG);
173 memcpy(msg[1].buf, buf6 + 2, msg[1].len);
174
175 break;
176 case 1:
177 switch (msg[0].addr) {
178 case 0x68:
179 /* write to si2109 register */
180 buf6[0] = 0xd0;
181 buf6[1] = msg[0].len;
182 memcpy(buf6 + 2, msg[0].buf, msg[0].len);
183 ret = dw210x_op_rw(d->udev, 0xc2, 0, 0, buf6,
184 msg[0].len + 2, DW210X_WRITE_MSG);
185 break;
186 case(DW2102_RC_QUERY):
187 ret = dw210x_op_rw(d->udev, 0xb8, 0, 0,
188 buf6, 2, DW210X_READ_MSG);
189 msg[0].buf[0] = buf6[0];
190 msg[0].buf[1] = buf6[1];
191 break;
192 case(DW2102_VOLTAGE_CTRL):
193 buf6[0] = 0x30;
194 buf6[1] = msg[0].buf[0];
195 ret = dw210x_op_rw(d->udev, 0xb2, 0, 0,
196 buf6, 2, DW210X_WRITE_MSG);
197 break;
198 }
199 break;
200 }
201
202 mutex_unlock(&d->i2c_mutex);
203 return num;
204}
205static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num)
206{
207 struct dvb_usb_device *d = i2c_get_adapdata(adap);
208 int ret = 0;
209
210 if (!d)
211 return -ENODEV;
212 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
213 return -EAGAIN;
214
215 switch (num) {
216 case 2: {
217 /* read */
218 /* first write first register number */
219 u8 ibuf [msg[1].len + 2], obuf[3];
220 obuf[0] = 0xd0;
221 obuf[1] = msg[0].len;
222 obuf[2] = msg[0].buf[0];
223 ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
224 obuf, msg[0].len + 2, DW210X_WRITE_MSG);
225 /* second read registers */
226 ret = dw210x_op_rw(d->udev, 0xc3, 0xd1 , 0,
227 ibuf, msg[1].len + 2, DW210X_READ_MSG);
228 memcpy(msg[1].buf, ibuf + 2, msg[1].len);
229
230 break;
231 }
232 case 1:
233 switch (msg[0].addr) {
234 case 0x68: {
235 /* write to register */
236 u8 obuf[msg[0].len + 2];
237 obuf[0] = 0xd0;
238 obuf[1] = msg[0].len;
239 memcpy(obuf + 2, msg[0].buf, msg[0].len);
240 ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
241 obuf, msg[0].len + 2, DW210X_WRITE_MSG);
242 break;
243 }
244 case 0x61: {
245 /* write to tuner */
246 u8 obuf[msg[0].len + 2];
247 obuf[0] = 0xc2;
248 obuf[1] = msg[0].len;
249 memcpy(obuf + 2, msg[0].buf, msg[0].len);
250 ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
251 obuf, msg[0].len + 2, DW210X_WRITE_MSG);
252 break;
253 }
254 case(DW2102_RC_QUERY): {
255 u8 ibuf[2];
256 ret = dw210x_op_rw(d->udev, 0xb8, 0, 0,
257 ibuf, 2, DW210X_READ_MSG);
258 memcpy(msg[0].buf, ibuf , 2);
259 break;
260 }
261 case(DW2102_VOLTAGE_CTRL): {
262 u8 obuf[2];
263 obuf[0] = 0x30;
264 obuf[1] = msg[0].buf[0];
265 ret = dw210x_op_rw(d->udev, 0xb2, 0, 0,
266 obuf, 2, DW210X_WRITE_MSG);
267 break;
268 }
269 }
270
271 break;
272 }
273
274 mutex_unlock(&d->i2c_mutex);
275 return num;
276}
277
278static int dw2104_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num)
279{
280 struct dvb_usb_device *d = i2c_get_adapdata(adap);
281 int ret = 0;
282 int len, i;
283
284 if (!d)
285 return -ENODEV;
286 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
287 return -EAGAIN;
288
289 switch (num) {
290 case 2: {
291 /* read */
292 /* first write first register number */
293 u8 ibuf [msg[1].len + 2], obuf[3];
294 obuf[0] = 0xaa;
295 obuf[1] = msg[0].len;
296 obuf[2] = msg[0].buf[0];
297 ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
298 obuf, msg[0].len + 2, DW210X_WRITE_MSG);
299 /* second read registers */
300 ret = dw210x_op_rw(d->udev, 0xc3, 0xab , 0,
301 ibuf, msg[1].len + 2, DW210X_READ_MSG);
302 memcpy(msg[1].buf, ibuf + 2, msg[1].len);
303
304 break;
305 }
306 case 1:
307 switch (msg[0].addr) {
308 case 0x55: {
309 if (msg[0].buf[0] == 0xf7) {
310 /* firmware */
311 /* Write in small blocks */
312 u8 obuf[19];
313 obuf[0] = 0xaa;
314 obuf[1] = 0x11;
315 obuf[2] = 0xf7;
316 len = msg[0].len - 1;
317 i = 1;
318 do {
319 memcpy(obuf + 3, msg[0].buf + i, (len > 16 ? 16 : len));
320 ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
321 obuf, (len > 16 ? 16 : len) + 3, DW210X_WRITE_MSG);
322 i += 16;
323 len -= 16;
324 } while (len > 0);
325 } else {
326 /* write to register */
327 u8 obuf[msg[0].len + 2];
328 obuf[0] = 0xaa;
329 obuf[1] = msg[0].len;
330 memcpy(obuf + 2, msg[0].buf, msg[0].len);
331 ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
332 obuf, msg[0].len + 2, DW210X_WRITE_MSG);
333 }
334 break;
335 }
336 case(DW2102_RC_QUERY): {
337 u8 ibuf[2];
338 ret = dw210x_op_rw(d->udev, 0xb8, 0, 0,
339 ibuf, 2, DW210X_READ_MSG);
340 memcpy(msg[0].buf, ibuf , 2);
341 break;
342 }
343 case(DW2102_VOLTAGE_CTRL): {
344 u8 obuf[2];
345 obuf[0] = 0x30;
346 obuf[1] = msg[0].buf[0];
347 ret = dw210x_op_rw(d->udev, 0xb2, 0, 0,
348 obuf, 2, DW210X_WRITE_MSG);
349 break;
350 }
351 }
352
353 break;
354 }
355
356 mutex_unlock(&d->i2c_mutex);
357 return num;
358}
359
360static u32 dw210x_i2c_func(struct i2c_adapter *adapter)
140{ 361{
141 return I2C_FUNC_I2C; 362 return I2C_FUNC_I2C;
142} 363}
143 364
144static struct i2c_algorithm dw2102_i2c_algo = { 365static struct i2c_algorithm dw2102_i2c_algo = {
145 .master_xfer = dw2102_i2c_transfer, 366 .master_xfer = dw2102_i2c_transfer,
146 .functionality = dw2102_i2c_func, 367 .functionality = dw210x_i2c_func,
368};
369
370static struct i2c_algorithm dw2102_serit_i2c_algo = {
371 .master_xfer = dw2102_serit_i2c_transfer,
372 .functionality = dw210x_i2c_func,
373};
374
375static struct i2c_algorithm dw2102_earda_i2c_algo = {
376 .master_xfer = dw2102_earda_i2c_transfer,
377 .functionality = dw210x_i2c_func,
378};
379
380static struct i2c_algorithm dw2104_i2c_algo = {
381 .master_xfer = dw2104_i2c_transfer,
382 .functionality = dw210x_i2c_func,
147}; 383};
148 384
149static int dw2102_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) 385static int dw210x_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
386{
387 int i;
388 u8 ibuf[] = {0, 0};
389 u8 eeprom[256], eepromline[16];
390
391 for (i = 0; i < 256; i++) {
392 if (dw210x_op_rw(d->udev, 0xb6, 0xa0 , i, ibuf, 2, DW210X_READ_MSG) < 0) {
393 err("read eeprom failed.");
394 return -1;
395 } else {
396 eepromline[i%16] = ibuf[0];
397 eeprom[i] = ibuf[0];
398 }
399 if ((i % 16) == 15) {
400 deb_xfer("%02x: ", i - 15);
401 debug_dump(eepromline, 16, deb_xfer);
402 }
403 }
404 memcpy(mac, eeprom + 8, 6);
405 return 0;
406};
407
408static int dw210x_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
150{ 409{
151 static u8 command_13v[1] = {0x00}; 410 static u8 command_13v[1] = {0x00};
152 static u8 command_18v[1] = {0x01}; 411 static u8 command_18v[1] = {0x01};
@@ -163,18 +422,66 @@ static int dw2102_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
163 return 0; 422 return 0;
164} 423}
165 424
166static int dw2102_frontend_attach(struct dvb_usb_adapter *d) 425static struct cx24116_config dw2104_config = {
426 .demod_address = 0x55,
427 .mpg_clk_pos_pol = 0x01,
428};
429
430static struct si21xx_config serit_sp1511lhb_config = {
431 .demod_address = 0x68,
432 .min_delay_ms = 100,
433
434};
435
436static int dw2104_frontend_attach(struct dvb_usb_adapter *d)
167{ 437{
168 d->fe = dvb_attach(stv0299_attach, &sharp_z0194a_config, 438 if ((d->fe = dvb_attach(cx24116_attach, &dw2104_config,
169 &d->dev->i2c_adap); 439 &d->dev->i2c_adap)) != NULL) {
170 if (d->fe != NULL) { 440 d->fe->ops.set_voltage = dw210x_set_voltage;
171 d->fe->ops.set_voltage = dw2102_set_voltage; 441 info("Attached cx24116!\n");
172 info("Attached stv0299!\n");
173 return 0; 442 return 0;
174 } 443 }
175 return -EIO; 444 return -EIO;
176} 445}
177 446
447static struct dvb_usb_device_properties dw2102_properties;
448
449static int dw2102_frontend_attach(struct dvb_usb_adapter *d)
450{
451 if (dw2102_properties.i2c_algo == &dw2102_serit_i2c_algo) {
452 /*dw2102_properties.adapter->tuner_attach = NULL;*/
453 d->fe = dvb_attach(si21xx_attach, &serit_sp1511lhb_config,
454 &d->dev->i2c_adap);
455 if (d->fe != NULL) {
456 d->fe->ops.set_voltage = dw210x_set_voltage;
457 info("Attached si21xx!\n");
458 return 0;
459 }
460 }
461 if (dw2102_properties.i2c_algo == &dw2102_earda_i2c_algo) {
462 /*dw2102_properties.adapter->tuner_attach = dw2102_tuner_attach;*/
463 d->fe = dvb_attach(stv0288_attach, &earda_config,
464 &d->dev->i2c_adap);
465 if (d->fe != NULL) {
466 d->fe->ops.set_voltage = dw210x_set_voltage;
467 info("Attached stv0288!\n");
468 return 0;
469 }
470 }
471
472 if (dw2102_properties.i2c_algo == &dw2102_i2c_algo) {
473 /*dw2102_properties.adapter->tuner_attach = dw2102_tuner_attach;*/
474 d->fe = dvb_attach(stv0299_attach, &sharp_z0194a_config,
475 &d->dev->i2c_adap);
476 if (d->fe != NULL) {
477 d->fe->ops.set_voltage = dw210x_set_voltage;
478 info("Attached stv0299!\n");
479 return 0;
480 }
481 }
482 return -EIO;
483}
484
178static int dw2102_tuner_attach(struct dvb_usb_adapter *adap) 485static int dw2102_tuner_attach(struct dvb_usb_adapter *adap)
179{ 486{
180 dvb_attach(dvb_pll_attach, adap->fe, 0x60, 487 dvb_attach(dvb_pll_attach, adap->fe, 0x60,
@@ -182,7 +489,15 @@ static int dw2102_tuner_attach(struct dvb_usb_adapter *adap)
182 return 0; 489 return 0;
183} 490}
184 491
185static struct dvb_usb_rc_key dw2102_rc_keys[] = { 492static int dw2102_earda_tuner_attach(struct dvb_usb_adapter *adap)
493{
494 dvb_attach(stb6000_attach, adap->fe, 0x61,
495 &adap->dev->i2c_adap);
496
497 return 0;
498}
499
500static struct dvb_usb_rc_key dw210x_rc_keys[] = {
186 { 0xf8, 0x0a, KEY_Q }, /*power*/ 501 { 0xf8, 0x0a, KEY_Q }, /*power*/
187 { 0xf8, 0x0c, KEY_M }, /*mute*/ 502 { 0xf8, 0x0c, KEY_M }, /*mute*/
188 { 0xf8, 0x11, KEY_1 }, 503 { 0xf8, 0x11, KEY_1 },
@@ -221,7 +536,7 @@ static struct dvb_usb_rc_key dw2102_rc_keys[] = {
221 536
222static int dw2102_rc_query(struct dvb_usb_device *d, u32 *event, int *state) 537static int dw2102_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
223{ 538{
224 struct dw2102_state *st = d->priv; 539 struct dw210x_state *st = d->priv;
225 u8 key[2]; 540 u8 key[2];
226 struct i2c_msg msg[] = { 541 struct i2c_msg msg[] = {
227 {.addr = DW2102_RC_QUERY, .flags = I2C_M_RD, .buf = key, 542 {.addr = DW2102_RC_QUERY, .flags = I2C_M_RD, .buf = key,
@@ -231,12 +546,12 @@ static int dw2102_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
231 546
232 *state = REMOTE_NO_KEY_PRESSED; 547 *state = REMOTE_NO_KEY_PRESSED;
233 if (dw2102_i2c_transfer(&d->i2c_adap, msg, 1) == 1) { 548 if (dw2102_i2c_transfer(&d->i2c_adap, msg, 1) == 1) {
234 for (i = 0; i < ARRAY_SIZE(dw2102_rc_keys); i++) { 549 for (i = 0; i < ARRAY_SIZE(dw210x_rc_keys); i++) {
235 if (dw2102_rc_keys[i].data == msg[0].buf[0]) { 550 if (dw210x_rc_keys[i].data == msg[0].buf[0]) {
236 *state = REMOTE_KEY_PRESSED; 551 *state = REMOTE_KEY_PRESSED;
237 *event = dw2102_rc_keys[i].event; 552 *event = dw210x_rc_keys[i].event;
238 st->last_key_pressed = 553 st->last_key_pressed =
239 dw2102_rc_keys[i].event; 554 dw210x_rc_keys[i].event;
240 break; 555 break;
241 } 556 }
242 st->last_key_pressed = 0; 557 st->last_key_pressed = 0;
@@ -249,6 +564,8 @@ static int dw2102_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
249static struct usb_device_id dw2102_table[] = { 564static struct usb_device_id dw2102_table[] = {
250 {USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW2102)}, 565 {USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW2102)},
251 {USB_DEVICE(USB_VID_CYPRESS, 0x2101)}, 566 {USB_DEVICE(USB_VID_CYPRESS, 0x2101)},
567 {USB_DEVICE(USB_VID_CYPRESS, 0x2104)},
568 {USB_DEVICE(0x9022, 0xd650)},
252 { } 569 { }
253}; 570};
254 571
@@ -260,7 +577,7 @@ static int dw2102_load_firmware(struct usb_device *dev,
260 u8 *b, *p; 577 u8 *b, *p;
261 int ret = 0, i; 578 int ret = 0, i;
262 u8 reset; 579 u8 reset;
263 u8 reset16 [] = {0, 0, 0, 0, 0, 0, 0}; 580 u8 reset16[] = {0, 0, 0, 0, 0, 0, 0};
264 const struct firmware *fw; 581 const struct firmware *fw;
265 const char *filename = "dvb-usb-dw2101.fw"; 582 const char *filename = "dvb-usb-dw2101.fw";
266 switch (dev->descriptor.idProduct) { 583 switch (dev->descriptor.idProduct) {
@@ -273,25 +590,23 @@ static int dw2102_load_firmware(struct usb_device *dev,
273 return ret; 590 return ret;
274 } 591 }
275 break; 592 break;
276 case USB_PID_DW2102: 593 default:
277 fw = frmwr; 594 fw = frmwr;
278 break; 595 break;
279 } 596 }
280 info("start downloading DW2102 firmware"); 597 info("start downloading DW210X firmware");
281 p = kmalloc(fw->size, GFP_KERNEL); 598 p = kmalloc(fw->size, GFP_KERNEL);
282 reset = 1; 599 reset = 1;
283 /*stop the CPU*/ 600 /*stop the CPU*/
284 dw2102_op_rw(dev, 0xa0, 0x7f92, &reset, 1, DW2102_WRITE_MSG); 601 dw210x_op_rw(dev, 0xa0, 0x7f92, 0, &reset, 1, DW210X_WRITE_MSG);
285 dw2102_op_rw(dev, 0xa0, 0xe600, &reset, 1, DW2102_WRITE_MSG); 602 dw210x_op_rw(dev, 0xa0, 0xe600, 0, &reset, 1, DW210X_WRITE_MSG);
286 603
287 if (p != NULL) { 604 if (p != NULL) {
288 memcpy(p, fw->data, fw->size); 605 memcpy(p, fw->data, fw->size);
289 for (i = 0; i < fw->size; i += 0x40) { 606 for (i = 0; i < fw->size; i += 0x40) {
290 b = (u8 *) p + i; 607 b = (u8 *) p + i;
291 if (dw2102_op_rw 608 if (dw210x_op_rw(dev, 0xa0, i, 0, b , 0x40,
292 (dev, 0xa0, i, b , 0x40, 609 DW210X_WRITE_MSG) != 0x40) {
293 DW2102_WRITE_MSG) != 0x40
294 ) {
295 err("error while transferring firmware"); 610 err("error while transferring firmware");
296 ret = -EINVAL; 611 ret = -EINVAL;
297 break; 612 break;
@@ -299,43 +614,66 @@ static int dw2102_load_firmware(struct usb_device *dev,
299 } 614 }
300 /* restart the CPU */ 615 /* restart the CPU */
301 reset = 0; 616 reset = 0;
302 if (ret || dw2102_op_rw 617 if (ret || dw210x_op_rw(dev, 0xa0, 0x7f92, 0, &reset, 1,
303 (dev, 0xa0, 0x7f92, &reset, 1, 618 DW210X_WRITE_MSG) != 1) {
304 DW2102_WRITE_MSG) != 1) {
305 err("could not restart the USB controller CPU."); 619 err("could not restart the USB controller CPU.");
306 ret = -EINVAL; 620 ret = -EINVAL;
307 } 621 }
308 if (ret || dw2102_op_rw 622 if (ret || dw210x_op_rw(dev, 0xa0, 0xe600, 0, &reset, 1,
309 (dev, 0xa0, 0xe600, &reset, 1, 623 DW210X_WRITE_MSG) != 1) {
310 DW2102_WRITE_MSG) != 1) {
311 err("could not restart the USB controller CPU."); 624 err("could not restart the USB controller CPU.");
312 ret = -EINVAL; 625 ret = -EINVAL;
313 } 626 }
314 /* init registers */ 627 /* init registers */
315 switch (dev->descriptor.idProduct) { 628 switch (dev->descriptor.idProduct) {
316 case USB_PID_DW2102: 629 case USB_PID_DW2104:
317 dw2102_op_rw 630 case 0xd650:
318 (dev, 0xbf, 0x0040, &reset, 0, 631 reset = 1;
319 DW2102_WRITE_MSG); 632 dw210x_op_rw(dev, 0xc4, 0x0000, 0, &reset, 1,
320 dw2102_op_rw 633 DW210X_WRITE_MSG);
321 (dev, 0xb9, 0x0000, &reset16[0], 2, 634 reset = 0;
322 DW2102_READ_MSG); 635 dw210x_op_rw(dev, 0xbf, 0x0040, 0, &reset, 0,
636 DW210X_WRITE_MSG);
323 break; 637 break;
638 case USB_PID_DW2102:
639 dw210x_op_rw(dev, 0xbf, 0x0040, 0, &reset, 0,
640 DW210X_WRITE_MSG);
641 dw210x_op_rw(dev, 0xb9, 0x0000, 0, &reset16[0], 2,
642 DW210X_READ_MSG);
643 /* check STV0299 frontend */
644 dw210x_op_rw(dev, 0xb5, 0, 0, &reset16[0], 2,
645 DW210X_READ_MSG);
646 if (reset16[0] == 0xa1) {
647 dw2102_properties.i2c_algo = &dw2102_i2c_algo;
648 dw2102_properties.adapter->tuner_attach = &dw2102_tuner_attach;
649 break;
650 } else {
651 /* check STV0288 frontend */
652 reset16[0] = 0xd0;
653 reset16[1] = 1;
654 reset16[2] = 0;
655 dw210x_op_rw(dev, 0xc2, 0, 0, &reset16[0], 3,
656 DW210X_WRITE_MSG);
657 dw210x_op_rw(dev, 0xc3, 0xd1, 0, &reset16[0], 3,
658 DW210X_READ_MSG);
659 if (reset16[2] == 0x11) {
660 dw2102_properties.i2c_algo = &dw2102_earda_i2c_algo;
661 dw2102_properties.adapter->tuner_attach = &dw2102_earda_tuner_attach;
662 break;
663 }
664 }
324 case 0x2101: 665 case 0x2101:
325 dw2102_op_rw 666 dw210x_op_rw(dev, 0xbc, 0x0030, 0, &reset16[0], 2,
326 (dev, 0xbc, 0x0030, &reset16[0], 2, 667 DW210X_READ_MSG);
327 DW2102_READ_MSG); 668 dw210x_op_rw(dev, 0xba, 0x0000, 0, &reset16[0], 7,
328 dw2102_op_rw 669 DW210X_READ_MSG);
329 (dev, 0xba, 0x0000, &reset16[0], 7, 670 dw210x_op_rw(dev, 0xba, 0x0000, 0, &reset16[0], 7,
330 DW2102_READ_MSG); 671 DW210X_READ_MSG);
331 dw2102_op_rw 672 dw210x_op_rw(dev, 0xb9, 0x0000, 0, &reset16[0], 2,
332 (dev, 0xba, 0x0000, &reset16[0], 7, 673 DW210X_READ_MSG);
333 DW2102_READ_MSG);
334 dw2102_op_rw
335 (dev, 0xb9, 0x0000, &reset16[0], 2,
336 DW2102_READ_MSG);
337 break; 674 break;
338 } 675 }
676 msleep(100);
339 kfree(p); 677 kfree(p);
340 } 678 }
341 return ret; 679 return ret;
@@ -345,12 +683,12 @@ static struct dvb_usb_device_properties dw2102_properties = {
345 .caps = DVB_USB_IS_AN_I2C_ADAPTER, 683 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
346 .usb_ctrl = DEVICE_SPECIFIC, 684 .usb_ctrl = DEVICE_SPECIFIC,
347 .firmware = "dvb-usb-dw2102.fw", 685 .firmware = "dvb-usb-dw2102.fw",
348 .size_of_priv = sizeof(struct dw2102_state), 686 .size_of_priv = sizeof(struct dw210x_state),
349 .no_reconnect = 1, 687 .no_reconnect = 1,
350 688
351 .i2c_algo = &dw2102_i2c_algo, 689 .i2c_algo = &dw2102_serit_i2c_algo,
352 .rc_key_map = dw2102_rc_keys, 690 .rc_key_map = dw210x_rc_keys,
353 .rc_key_map_size = ARRAY_SIZE(dw2102_rc_keys), 691 .rc_key_map_size = ARRAY_SIZE(dw210x_rc_keys),
354 .rc_interval = 150, 692 .rc_interval = 150,
355 .rc_query = dw2102_rc_query, 693 .rc_query = dw2102_rc_query,
356 694
@@ -358,11 +696,12 @@ static struct dvb_usb_device_properties dw2102_properties = {
358 /* parameter for the MPEG2-data transfer */ 696 /* parameter for the MPEG2-data transfer */
359 .num_adapters = 1, 697 .num_adapters = 1,
360 .download_firmware = dw2102_load_firmware, 698 .download_firmware = dw2102_load_firmware,
361 .adapter = { 699 .read_mac_address = dw210x_read_mac_address,
700 .adapter = {
362 { 701 {
363 .frontend_attach = dw2102_frontend_attach, 702 .frontend_attach = dw2102_frontend_attach,
364 .streaming_ctrl = NULL, 703 .streaming_ctrl = NULL,
365 .tuner_attach = dw2102_tuner_attach, 704 .tuner_attach = NULL,
366 .stream = { 705 .stream = {
367 .type = USB_BULK, 706 .type = USB_BULK,
368 .count = 8, 707 .count = 8,
@@ -388,11 +727,64 @@ static struct dvb_usb_device_properties dw2102_properties = {
388 } 727 }
389}; 728};
390 729
730static struct dvb_usb_device_properties dw2104_properties = {
731 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
732 .usb_ctrl = DEVICE_SPECIFIC,
733 .firmware = "dvb-usb-dw2104.fw",
734 .size_of_priv = sizeof(struct dw210x_state),
735 .no_reconnect = 1,
736
737 .i2c_algo = &dw2104_i2c_algo,
738 .rc_key_map = dw210x_rc_keys,
739 .rc_key_map_size = ARRAY_SIZE(dw210x_rc_keys),
740 .rc_interval = 150,
741 .rc_query = dw2102_rc_query,
742
743 .generic_bulk_ctrl_endpoint = 0x81,
744 /* parameter for the MPEG2-data transfer */
745 .num_adapters = 1,
746 .download_firmware = dw2102_load_firmware,
747 .read_mac_address = dw210x_read_mac_address,
748 .adapter = {
749 {
750 .frontend_attach = dw2104_frontend_attach,
751 .streaming_ctrl = NULL,
752 /*.tuner_attach = dw2104_tuner_attach,*/
753 .stream = {
754 .type = USB_BULK,
755 .count = 8,
756 .endpoint = 0x82,
757 .u = {
758 .bulk = {
759 .buffersize = 4096,
760 }
761 }
762 },
763 }
764 },
765 .num_device_descs = 2,
766 .devices = {
767 { "DVBWorld DW2104 USB2.0",
768 {&dw2102_table[2], NULL},
769 {NULL},
770 },
771 { "TeVii S650 USB2.0",
772 {&dw2102_table[3], NULL},
773 {NULL},
774 },
775 }
776};
777
391static int dw2102_probe(struct usb_interface *intf, 778static int dw2102_probe(struct usb_interface *intf,
392 const struct usb_device_id *id) 779 const struct usb_device_id *id)
393{ 780{
394 return dvb_usb_device_init(intf, &dw2102_properties, 781 if (0 == dvb_usb_device_init(intf, &dw2102_properties,
395 THIS_MODULE, NULL, adapter_nr); 782 THIS_MODULE, NULL, adapter_nr) ||
783 0 == dvb_usb_device_init(intf, &dw2104_properties,
784 THIS_MODULE, NULL, adapter_nr)) {
785 return 0;
786 }
787 return -ENODEV;
396} 788}
397 789
398static struct usb_driver dw2102_driver = { 790static struct usb_driver dw2102_driver = {
@@ -420,6 +812,6 @@ module_init(dw2102_module_init);
420module_exit(dw2102_module_exit); 812module_exit(dw2102_module_exit);
421 813
422MODULE_AUTHOR("Igor M. Liplianin (c) liplianin@me.by"); 814MODULE_AUTHOR("Igor M. Liplianin (c) liplianin@me.by");
423MODULE_DESCRIPTION("Driver for DVBWorld DVB-S 2101 2102 USB2.0 device"); 815MODULE_DESCRIPTION("Driver for DVBWorld DVB-S 2101, 2102, DVB-S2 2104 USB2.0 device");
424MODULE_VERSION("0.1"); 816MODULE_VERSION("0.1");
425MODULE_LICENSE("GPL"); 817MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/dw2102.h b/drivers/media/dvb/dvb-usb/dw2102.h
index 7a310f906837..e3370734e95a 100644
--- a/drivers/media/dvb/dvb-usb/dw2102.h
+++ b/drivers/media/dvb/dvb-usb/dw2102.h
@@ -4,6 +4,5 @@
4#define DVB_USB_LOG_PREFIX "dw2102" 4#define DVB_USB_LOG_PREFIX "dw2102"
5#include "dvb-usb.h" 5#include "dvb-usb.h"
6 6
7extern int dvb_usb_dw2102_debug;
8#define deb_xfer(args...) dprintk(dvb_usb_dw2102_debug, 0x02, args) 7#define deb_xfer(args...) dprintk(dvb_usb_dw2102_debug, 0x02, args)
9#endif 8#endif
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig
index 7dbb4a223c99..96b93e21a84b 100644
--- a/drivers/media/dvb/frontends/Kconfig
+++ b/drivers/media/dvb/frontends/Kconfig
@@ -43,6 +43,20 @@ config DVB_S5H1420
43 help 43 help
44 A DVB-S tuner module. Say Y when you want to support this frontend. 44 A DVB-S tuner module. Say Y when you want to support this frontend.
45 45
46config DVB_STV0288
47 tristate "ST STV0288 based"
48 depends on DVB_CORE && I2C
49 default m if DVB_FE_CUSTOMISE
50 help
51 A DVB-S tuner module. Say Y when you want to support this frontend.
52
53config DVB_STB6000
54 tristate "ST STB6000 silicon tuner"
55 depends on DVB_CORE && I2C
56 default m if DVB_FE_CUSTOMISE
57 help
58 A DVB-S silicon tuner module. Say Y when you want to support this tuner.
59
46config DVB_STV0299 60config DVB_STV0299
47 tristate "ST STV0299 based" 61 tristate "ST STV0299 based"
48 depends on DVB_CORE && I2C 62 depends on DVB_CORE && I2C
@@ -92,6 +106,20 @@ config DVB_TUA6100
92 help 106 help
93 A DVB-S PLL chip. 107 A DVB-S PLL chip.
94 108
109config DVB_CX24116
110 tristate "Conexant CX24116 based"
111 depends on DVB_CORE && I2C
112 default m if DVB_FE_CUSTOMISE
113 help
114 A DVB-S/S2 tuner module. Say Y when you want to support this frontend.
115
116config DVB_SI21XX
117 tristate "Silicon Labs SI21XX based"
118 depends on DVB_CORE && I2C
119 default m if DVB_FE_CUSTOMISE
120 help
121 A DVB-S tuner module. Say Y when you want to support this frontend.
122
95comment "DVB-T (terrestrial) frontends" 123comment "DVB-T (terrestrial) frontends"
96 depends on DVB_CORE 124 depends on DVB_CORE
97 125
@@ -385,4 +413,23 @@ config DVB_ISL6421
385 help 413 help
386 An SEC control chip. 414 An SEC control chip.
387 415
416config DVB_LGS8GL5
417 tristate "Silicon Legend LGS-8GL5 demodulator (OFDM)"
418 depends on DVB_CORE && I2C
419 default m if DVB_FE_CUSTOMISE
420 help
421 A DMB-TH tuner module. Say Y when you want to support this frontend.
422
423comment "Tools to develop new frontends"
424
425config DVB_DUMMY_FE
426 tristate "Dummy frontend driver"
427 default n
428
429config DVB_AF9013
430 tristate "Afatech AF9013 demodulator"
431 depends on DVB_CORE && I2C
432 default m if DVB_FE_CUSTOMISE
433 help
434 Say Y when you want to support this frontend.
388endmenu 435endmenu
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile
index 028da55611c0..aba79f4a63a7 100644
--- a/drivers/media/dvb/frontends/Makefile
+++ b/drivers/media/dvb/frontends/Makefile
@@ -48,3 +48,10 @@ obj-$(CONFIG_DVB_TUNER_ITD1000) += itd1000.o
48obj-$(CONFIG_DVB_AU8522) += au8522.o 48obj-$(CONFIG_DVB_AU8522) += au8522.o
49obj-$(CONFIG_DVB_TDA10048) += tda10048.o 49obj-$(CONFIG_DVB_TDA10048) += tda10048.o
50obj-$(CONFIG_DVB_S5H1411) += s5h1411.o 50obj-$(CONFIG_DVB_S5H1411) += s5h1411.o
51obj-$(CONFIG_DVB_LGS8GL5) += lgs8gl5.o
52obj-$(CONFIG_DVB_DUMMY_FE) += dvb_dummy_fe.o
53obj-$(CONFIG_DVB_AF9013) += af9013.o
54obj-$(CONFIG_DVB_CX24116) += cx24116.o
55obj-$(CONFIG_DVB_SI21XX) += si21xx.o
56obj-$(CONFIG_DVB_STV0288) += stv0288.o
57obj-$(CONFIG_DVB_STB6000) += stb6000.o
diff --git a/drivers/media/dvb/frontends/af9013.c b/drivers/media/dvb/frontends/af9013.c
new file mode 100644
index 000000000000..21c1060cf10e
--- /dev/null
+++ b/drivers/media/dvb/frontends/af9013.c
@@ -0,0 +1,1685 @@
1/*
2 * DVB USB Linux driver for Afatech AF9015 DVB-T USB2.0 receiver
3 *
4 * Copyright (C) 2007 Antti Palosaari <crope@iki.fi>
5 *
6 * Thanks to Afatech who kindly provided information.
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
24#include <linux/kernel.h>
25#include <linux/module.h>
26#include <linux/moduleparam.h>
27#include <linux/init.h>
28#include <linux/delay.h>
29#include <linux/string.h>
30#include <linux/slab.h>
31#include <linux/firmware.h>
32
33#include "dvb_frontend.h"
34#include "af9013_priv.h"
35#include "af9013.h"
36
37int af9013_debug;
38
39struct af9013_state {
40 struct i2c_adapter *i2c;
41 struct dvb_frontend frontend;
42
43 struct af9013_config config;
44
45 u16 signal_strength;
46 u32 ber;
47 u32 ucblocks;
48 u16 snr;
49 u32 frequency;
50 unsigned long next_statistics_check;
51};
52
53static u8 regmask[8] = { 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff };
54
55static int af9013_write_regs(struct af9013_state *state, u8 mbox, u16 reg,
56 u8 *val, u8 len)
57{
58 u8 buf[3+len];
59 struct i2c_msg msg = {
60 .addr = state->config.demod_address,
61 .flags = 0,
62 .len = sizeof(buf),
63 .buf = buf };
64
65 buf[0] = reg >> 8;
66 buf[1] = reg & 0xff;
67 buf[2] = mbox;
68 memcpy(&buf[3], val, len);
69
70 if (i2c_transfer(state->i2c, &msg, 1) != 1) {
71 warn("I2C write failed reg:%04x len:%d", reg, len);
72 return -EREMOTEIO;
73 }
74 return 0;
75}
76
77static int af9013_write_ofdm_regs(struct af9013_state *state, u16 reg, u8 *val,
78 u8 len)
79{
80 u8 mbox = (1 << 0)|(1 << 1)|((len - 1) << 2)|(0 << 6)|(0 << 7);
81 return af9013_write_regs(state, mbox, reg, val, len);
82}
83
84static int af9013_write_ofsm_regs(struct af9013_state *state, u16 reg, u8 *val,
85 u8 len)
86{
87 u8 mbox = (1 << 0)|(1 << 1)|((len - 1) << 2)|(1 << 6)|(1 << 7);
88 return af9013_write_regs(state, mbox, reg, val, len);
89}
90
91/* write single register */
92static int af9013_write_reg(struct af9013_state *state, u16 reg, u8 val)
93{
94 return af9013_write_ofdm_regs(state, reg, &val, 1);
95}
96
97/* read single register */
98static int af9013_read_reg(struct af9013_state *state, u16 reg, u8 *val)
99{
100 u8 obuf[3] = { reg >> 8, reg & 0xff, 0 };
101 u8 ibuf[1];
102 struct i2c_msg msg[2] = {
103 {
104 .addr = state->config.demod_address,
105 .flags = 0,
106 .len = sizeof(obuf),
107 .buf = obuf
108 }, {
109 .addr = state->config.demod_address,
110 .flags = I2C_M_RD,
111 .len = sizeof(ibuf),
112 .buf = ibuf
113 }
114 };
115
116 if (i2c_transfer(state->i2c, msg, 2) != 2) {
117 warn("I2C read failed reg:%04x", reg);
118 return -EREMOTEIO;
119 }
120 *val = ibuf[0];
121 return 0;
122}
123
124static int af9013_write_reg_bits(struct af9013_state *state, u16 reg, u8 pos,
125 u8 len, u8 val)
126{
127 int ret;
128 u8 tmp, mask;
129
130 ret = af9013_read_reg(state, reg, &tmp);
131 if (ret)
132 return ret;
133
134 mask = regmask[len - 1] << pos;
135 tmp = (tmp & ~mask) | ((val << pos) & mask);
136
137 return af9013_write_reg(state, reg, tmp);
138}
139
140static int af9013_read_reg_bits(struct af9013_state *state, u16 reg, u8 pos,
141 u8 len, u8 *val)
142{
143 int ret;
144 u8 tmp;
145
146 ret = af9013_read_reg(state, reg, &tmp);
147 if (ret)
148 return ret;
149 *val = (tmp >> pos) & regmask[len - 1];
150 return 0;
151}
152
153static int af9013_set_gpio(struct af9013_state *state, u8 gpio, u8 gpioval)
154{
155 int ret;
156 u8 pos;
157 u16 addr;
158 deb_info("%s: gpio:%d gpioval:%02x\n", __func__, gpio, gpioval);
159
160/* GPIO0 & GPIO1 0xd735
161 GPIO2 & GPIO3 0xd736 */
162
163 switch (gpio) {
164 case 0:
165 case 1:
166 addr = 0xd735;
167 break;
168 case 2:
169 case 3:
170 addr = 0xd736;
171 break;
172
173 default:
174 err("invalid gpio:%d\n", gpio);
175 ret = -EINVAL;
176 goto error;
177 };
178
179 switch (gpio) {
180 case 0:
181 case 2:
182 pos = 0;
183 break;
184 case 1:
185 case 3:
186 default:
187 pos = 4;
188 break;
189 };
190
191 ret = af9013_write_reg_bits(state, addr, pos, 4, gpioval);
192
193error:
194 return ret;
195}
196
197static u32 af913_div(u32 a, u32 b, u32 x)
198{
199 u32 r = 0, c = 0, i;
200 deb_info("%s: a:%d b:%d x:%d\n", __func__, a, b, x);
201
202 if (a > b) {
203 c = a / b;
204 a = a - c * b;
205 }
206
207 for (i = 0; i < x; i++) {
208 if (a >= b) {
209 r += 1;
210 a -= b;
211 }
212 a <<= 1;
213 r <<= 1;
214 }
215 r = (c << (u32)x) + r;
216
217 deb_info("%s: a:%d b:%d x:%d r:%d r:%x\n", __func__, a, b, x, r, r);
218 return r;
219}
220
221static int af9013_set_coeff(struct af9013_state *state, fe_bandwidth_t bw)
222{
223 int ret = 0;
224 u8 i = 0;
225 u8 buf[24];
226 u32 ns_coeff1_2048nu;
227 u32 ns_coeff1_8191nu;
228 u32 ns_coeff1_8192nu;
229 u32 ns_coeff1_8193nu;
230 u32 ns_coeff2_2k;
231 u32 ns_coeff2_8k;
232
233 deb_info("%s: adc_clock:%d bw:%d\n", __func__,
234 state->config.adc_clock, bw);
235
236 switch (state->config.adc_clock) {
237 case 28800: /* 28.800 MHz */
238 switch (bw) {
239 case BANDWIDTH_6_MHZ:
240 ns_coeff1_2048nu = 0x01e79e7a;
241 ns_coeff1_8191nu = 0x0079eb6e;
242 ns_coeff1_8192nu = 0x0079e79e;
243 ns_coeff1_8193nu = 0x0079e3cf;
244 ns_coeff2_2k = 0x00f3cf3d;
245 ns_coeff2_8k = 0x003cf3cf;
246 break;
247 case BANDWIDTH_7_MHZ:
248 ns_coeff1_2048nu = 0x0238e38e;
249 ns_coeff1_8191nu = 0x008e3d55;
250 ns_coeff1_8192nu = 0x008e38e4;
251 ns_coeff1_8193nu = 0x008e3472;
252 ns_coeff2_2k = 0x011c71c7;
253 ns_coeff2_8k = 0x00471c72;
254 break;
255 case BANDWIDTH_8_MHZ:
256 ns_coeff1_2048nu = 0x028a28a3;
257 ns_coeff1_8191nu = 0x00a28f3d;
258 ns_coeff1_8192nu = 0x00a28a29;
259 ns_coeff1_8193nu = 0x00a28514;
260 ns_coeff2_2k = 0x01451451;
261 ns_coeff2_8k = 0x00514514;
262 break;
263 default:
264 ret = -EINVAL;
265 }
266 break;
267 case 20480: /* 20.480 MHz */
268 switch (bw) {
269 case BANDWIDTH_6_MHZ:
270 ns_coeff1_2048nu = 0x02adb6dc;
271 ns_coeff1_8191nu = 0x00ab7313;
272 ns_coeff1_8192nu = 0x00ab6db7;
273 ns_coeff1_8193nu = 0x00ab685c;
274 ns_coeff2_2k = 0x0156db6e;
275 ns_coeff2_8k = 0x0055b6dc;
276 break;
277 case BANDWIDTH_7_MHZ:
278 ns_coeff1_2048nu = 0x03200001;
279 ns_coeff1_8191nu = 0x00c80640;
280 ns_coeff1_8192nu = 0x00c80000;
281 ns_coeff1_8193nu = 0x00c7f9c0;
282 ns_coeff2_2k = 0x01900000;
283 ns_coeff2_8k = 0x00640000;
284 break;
285 case BANDWIDTH_8_MHZ:
286 ns_coeff1_2048nu = 0x03924926;
287 ns_coeff1_8191nu = 0x00e4996e;
288 ns_coeff1_8192nu = 0x00e49249;
289 ns_coeff1_8193nu = 0x00e48b25;
290 ns_coeff2_2k = 0x01c92493;
291 ns_coeff2_8k = 0x00724925;
292 break;
293 default:
294 ret = -EINVAL;
295 }
296 break;
297 case 28000: /* 28.000 MHz */
298 switch (bw) {
299 case BANDWIDTH_6_MHZ:
300 ns_coeff1_2048nu = 0x01f58d10;
301 ns_coeff1_8191nu = 0x007d672f;
302 ns_coeff1_8192nu = 0x007d6344;
303 ns_coeff1_8193nu = 0x007d5f59;
304 ns_coeff2_2k = 0x00fac688;
305 ns_coeff2_8k = 0x003eb1a2;
306 break;
307 case BANDWIDTH_7_MHZ:
308 ns_coeff1_2048nu = 0x02492492;
309 ns_coeff1_8191nu = 0x00924db7;
310 ns_coeff1_8192nu = 0x00924925;
311 ns_coeff1_8193nu = 0x00924492;
312 ns_coeff2_2k = 0x01249249;
313 ns_coeff2_8k = 0x00492492;
314 break;
315 case BANDWIDTH_8_MHZ:
316 ns_coeff1_2048nu = 0x029cbc15;
317 ns_coeff1_8191nu = 0x00a7343f;
318 ns_coeff1_8192nu = 0x00a72f05;
319 ns_coeff1_8193nu = 0x00a729cc;
320 ns_coeff2_2k = 0x014e5e0a;
321 ns_coeff2_8k = 0x00539783;
322 break;
323 default:
324 ret = -EINVAL;
325 }
326 break;
327 case 25000: /* 25.000 MHz */
328 switch (bw) {
329 case BANDWIDTH_6_MHZ:
330 ns_coeff1_2048nu = 0x0231bcb5;
331 ns_coeff1_8191nu = 0x008c7391;
332 ns_coeff1_8192nu = 0x008c6f2d;
333 ns_coeff1_8193nu = 0x008c6aca;
334 ns_coeff2_2k = 0x0118de5b;
335 ns_coeff2_8k = 0x00463797;
336 break;
337 case BANDWIDTH_7_MHZ:
338 ns_coeff1_2048nu = 0x028f5c29;
339 ns_coeff1_8191nu = 0x00a3dc29;
340 ns_coeff1_8192nu = 0x00a3d70a;
341 ns_coeff1_8193nu = 0x00a3d1ec;
342 ns_coeff2_2k = 0x0147ae14;
343 ns_coeff2_8k = 0x0051eb85;
344 break;
345 case BANDWIDTH_8_MHZ:
346 ns_coeff1_2048nu = 0x02ecfb9d;
347 ns_coeff1_8191nu = 0x00bb44c1;
348 ns_coeff1_8192nu = 0x00bb3ee7;
349 ns_coeff1_8193nu = 0x00bb390d;
350 ns_coeff2_2k = 0x01767dce;
351 ns_coeff2_8k = 0x005d9f74;
352 break;
353 default:
354 ret = -EINVAL;
355 }
356 break;
357 default:
358 err("invalid xtal");
359 return -EINVAL;
360 }
361 if (ret) {
362 err("invalid bandwidth");
363 return ret;
364 }
365
366 buf[i++] = (u8) ((ns_coeff1_2048nu & 0x03000000) >> 24);
367 buf[i++] = (u8) ((ns_coeff1_2048nu & 0x00ff0000) >> 16);
368 buf[i++] = (u8) ((ns_coeff1_2048nu & 0x0000ff00) >> 8);
369 buf[i++] = (u8) ((ns_coeff1_2048nu & 0x000000ff));
370 buf[i++] = (u8) ((ns_coeff2_2k & 0x01c00000) >> 22);
371 buf[i++] = (u8) ((ns_coeff2_2k & 0x003fc000) >> 14);
372 buf[i++] = (u8) ((ns_coeff2_2k & 0x00003fc0) >> 6);
373 buf[i++] = (u8) ((ns_coeff2_2k & 0x0000003f));
374 buf[i++] = (u8) ((ns_coeff1_8191nu & 0x03000000) >> 24);
375 buf[i++] = (u8) ((ns_coeff1_8191nu & 0x00ffc000) >> 16);
376 buf[i++] = (u8) ((ns_coeff1_8191nu & 0x0000ff00) >> 8);
377 buf[i++] = (u8) ((ns_coeff1_8191nu & 0x000000ff));
378 buf[i++] = (u8) ((ns_coeff1_8192nu & 0x03000000) >> 24);
379 buf[i++] = (u8) ((ns_coeff1_8192nu & 0x00ffc000) >> 16);
380 buf[i++] = (u8) ((ns_coeff1_8192nu & 0x0000ff00) >> 8);
381 buf[i++] = (u8) ((ns_coeff1_8192nu & 0x000000ff));
382 buf[i++] = (u8) ((ns_coeff1_8193nu & 0x03000000) >> 24);
383 buf[i++] = (u8) ((ns_coeff1_8193nu & 0x00ffc000) >> 16);
384 buf[i++] = (u8) ((ns_coeff1_8193nu & 0x0000ff00) >> 8);
385 buf[i++] = (u8) ((ns_coeff1_8193nu & 0x000000ff));
386 buf[i++] = (u8) ((ns_coeff2_8k & 0x01c00000) >> 22);
387 buf[i++] = (u8) ((ns_coeff2_8k & 0x003fc000) >> 14);
388 buf[i++] = (u8) ((ns_coeff2_8k & 0x00003fc0) >> 6);
389 buf[i++] = (u8) ((ns_coeff2_8k & 0x0000003f));
390
391 deb_info("%s: coeff:", __func__);
392 debug_dump(buf, sizeof(buf), deb_info);
393
394 /* program */
395 for (i = 0; i < sizeof(buf); i++) {
396 ret = af9013_write_reg(state, 0xae00 + i, buf[i]);
397 if (ret)
398 break;
399 }
400
401 return ret;
402}
403
404static int af9013_set_adc_ctrl(struct af9013_state *state)
405{
406 int ret;
407 u8 buf[3], tmp, i;
408 u32 adc_cw;
409
410 deb_info("%s: adc_clock:%d\n", __func__, state->config.adc_clock);
411
412 /* adc frequency type */
413 switch (state->config.adc_clock) {
414 case 28800: /* 28.800 MHz */
415 tmp = 0;
416 break;
417 case 20480: /* 20.480 MHz */
418 tmp = 1;
419 break;
420 case 28000: /* 28.000 MHz */
421 tmp = 2;
422 break;
423 case 25000: /* 25.000 MHz */
424 tmp = 3;
425 break;
426 default:
427 err("invalid xtal");
428 return -EINVAL;
429 }
430
431 adc_cw = af913_div(state->config.adc_clock*1000, 1000000ul, 19ul);
432
433 buf[0] = (u8) ((adc_cw & 0x000000ff));
434 buf[1] = (u8) ((adc_cw & 0x0000ff00) >> 8);
435 buf[2] = (u8) ((adc_cw & 0x00ff0000) >> 16);
436
437 deb_info("%s: adc_cw:", __func__);
438 debug_dump(buf, sizeof(buf), deb_info);
439
440 /* program */
441 for (i = 0; i < sizeof(buf); i++) {
442 ret = af9013_write_reg(state, 0xd180 + i, buf[i]);
443 if (ret)
444 goto error;
445 }
446 ret = af9013_write_reg_bits(state, 0x9bd2, 0, 4, tmp);
447error:
448 return ret;
449}
450
451static int af9013_set_freq_ctrl(struct af9013_state *state, fe_bandwidth_t bw)
452{
453 int ret;
454 u16 addr;
455 u8 buf[3], i, j;
456 u32 adc_freq, freq_cw;
457 s8 bfs_spec_inv;
458 int if_sample_freq;
459
460 for (j = 0; j < 3; j++) {
461 if (j == 0) {
462 addr = 0xd140; /* fcw normal */
463 bfs_spec_inv = state->config.rf_spec_inv ? -1 : 1;
464 } else if (j == 1) {
465 addr = 0x9be7; /* fcw dummy ram */
466 bfs_spec_inv = state->config.rf_spec_inv ? -1 : 1;
467 } else {
468 addr = 0x9bea; /* fcw inverted */
469 bfs_spec_inv = state->config.rf_spec_inv ? 1 : -1;
470 }
471
472 adc_freq = state->config.adc_clock * 1000;
473 if_sample_freq = state->config.tuner_if * 1000;
474
475 /* TDA18271 uses different sampling freq for every bw */
476 if (state->config.tuner == AF9013_TUNER_TDA18271) {
477 switch (bw) {
478 case BANDWIDTH_6_MHZ:
479 if_sample_freq = 3300000; /* 3.3 MHz */
480 break;
481 case BANDWIDTH_7_MHZ:
482 if_sample_freq = 3800000; /* 3.8 MHz */
483 break;
484 case BANDWIDTH_8_MHZ:
485 default:
486 if_sample_freq = 4300000; /* 4.3 MHz */
487 break;
488 }
489 }
490
491 while (if_sample_freq > (adc_freq / 2))
492 if_sample_freq = if_sample_freq - adc_freq;
493
494 if (if_sample_freq >= 0)
495 bfs_spec_inv = bfs_spec_inv * (-1);
496 else
497 if_sample_freq = if_sample_freq * (-1);
498
499 freq_cw = af913_div(if_sample_freq, adc_freq, 23ul);
500
501 if (bfs_spec_inv == -1)
502 freq_cw = 0x00800000 - freq_cw;
503
504 buf[0] = (u8) ((freq_cw & 0x000000ff));
505 buf[1] = (u8) ((freq_cw & 0x0000ff00) >> 8);
506 buf[2] = (u8) ((freq_cw & 0x007f0000) >> 16);
507
508
509 deb_info("%s: freq_cw:", __func__);
510 debug_dump(buf, sizeof(buf), deb_info);
511
512 /* program */
513 for (i = 0; i < sizeof(buf); i++) {
514 ret = af9013_write_reg(state, addr++, buf[i]);
515 if (ret)
516 goto error;
517 }
518 }
519error:
520 return ret;
521}
522
523static int af9013_set_ofdm_params(struct af9013_state *state,
524 struct dvb_ofdm_parameters *params, u8 *auto_mode)
525{
526 int ret;
527 u8 i, buf[3] = {0, 0, 0};
528 *auto_mode = 0; /* set if parameters are requested to auto set */
529
530 switch (params->transmission_mode) {
531 case TRANSMISSION_MODE_AUTO:
532 *auto_mode = 1;
533 case TRANSMISSION_MODE_2K:
534 break;
535 case TRANSMISSION_MODE_8K:
536 buf[0] |= (1 << 0);
537 break;
538 default:
539 return -EINVAL;
540 }
541
542 switch (params->guard_interval) {
543 case GUARD_INTERVAL_AUTO:
544 *auto_mode = 1;
545 case GUARD_INTERVAL_1_32:
546 break;
547 case GUARD_INTERVAL_1_16:
548 buf[0] |= (1 << 2);
549 break;
550 case GUARD_INTERVAL_1_8:
551 buf[0] |= (2 << 2);
552 break;
553 case GUARD_INTERVAL_1_4:
554 buf[0] |= (3 << 2);
555 break;
556 default:
557 return -EINVAL;
558 }
559
560 switch (params->hierarchy_information) {
561 case HIERARCHY_AUTO:
562 *auto_mode = 1;
563 case HIERARCHY_NONE:
564 break;
565 case HIERARCHY_1:
566 buf[0] |= (1 << 4);
567 break;
568 case HIERARCHY_2:
569 buf[0] |= (2 << 4);
570 break;
571 case HIERARCHY_4:
572 buf[0] |= (3 << 4);
573 break;
574 default:
575 return -EINVAL;
576 };
577
578 switch (params->constellation) {
579 case QAM_AUTO:
580 *auto_mode = 1;
581 case QPSK:
582 break;
583 case QAM_16:
584 buf[1] |= (1 << 6);
585 break;
586 case QAM_64:
587 buf[1] |= (2 << 6);
588 break;
589 default:
590 return -EINVAL;
591 }
592
593 /* Use HP. How and which case we can switch to LP? */
594 buf[1] |= (1 << 4);
595
596 switch (params->code_rate_HP) {
597 case FEC_AUTO:
598 *auto_mode = 1;
599 case FEC_1_2:
600 break;
601 case FEC_2_3:
602 buf[2] |= (1 << 0);
603 break;
604 case FEC_3_4:
605 buf[2] |= (2 << 0);
606 break;
607 case FEC_5_6:
608 buf[2] |= (3 << 0);
609 break;
610 case FEC_7_8:
611 buf[2] |= (4 << 0);
612 break;
613 default:
614 return -EINVAL;
615 }
616
617 switch (params->code_rate_LP) {
618 case FEC_AUTO:
619 /* if HIERARCHY_NONE and FEC_NONE then LP FEC is set to FEC_AUTO
620 by dvb_frontend.c for compatibility */
621 if (params->hierarchy_information != HIERARCHY_NONE)
622 *auto_mode = 1;
623 case FEC_1_2:
624 break;
625 case FEC_2_3:
626 buf[2] |= (1 << 3);
627 break;
628 case FEC_3_4:
629 buf[2] |= (2 << 3);
630 break;
631 case FEC_5_6:
632 buf[2] |= (3 << 3);
633 break;
634 case FEC_7_8:
635 buf[2] |= (4 << 3);
636 break;
637 case FEC_NONE:
638 if (params->hierarchy_information == HIERARCHY_AUTO)
639 break;
640 default:
641 return -EINVAL;
642 }
643
644 switch (params->bandwidth) {
645 case BANDWIDTH_6_MHZ:
646 break;
647 case BANDWIDTH_7_MHZ:
648 buf[1] |= (1 << 2);
649 break;
650 case BANDWIDTH_8_MHZ:
651 buf[1] |= (2 << 2);
652 break;
653 default:
654 return -EINVAL;
655 }
656
657 /* program */
658 for (i = 0; i < sizeof(buf); i++) {
659 ret = af9013_write_reg(state, 0xd3c0 + i, buf[i]);
660 if (ret)
661 break;
662 }
663
664 return ret;
665}
666
667static int af9013_reset(struct af9013_state *state, u8 sleep)
668{
669 int ret;
670 u8 tmp, i;
671 deb_info("%s\n", __func__);
672
673 /* enable OFDM reset */
674 ret = af9013_write_reg_bits(state, 0xd417, 4, 1, 1);
675 if (ret)
676 goto error;
677
678 /* start reset mechanism */
679 ret = af9013_write_reg(state, 0xaeff, 1);
680 if (ret)
681 goto error;
682
683 /* reset is done when bit 1 is set */
684 for (i = 0; i < 150; i++) {
685 ret = af9013_read_reg_bits(state, 0xd417, 1, 1, &tmp);
686 if (ret)
687 goto error;
688 if (tmp)
689 break; /* reset done */
690 msleep(10);
691 }
692 if (!tmp)
693 return -ETIMEDOUT;
694
695 /* don't clear reset when going to sleep */
696 if (!sleep) {
697 /* clear OFDM reset */
698 ret = af9013_write_reg_bits(state, 0xd417, 1, 1, 0);
699 if (ret)
700 goto error;
701
702 /* disable OFDM reset */
703 ret = af9013_write_reg_bits(state, 0xd417, 4, 1, 0);
704 }
705error:
706 return ret;
707}
708
709static int af9013_power_ctrl(struct af9013_state *state, u8 onoff)
710{
711 int ret;
712 deb_info("%s: onoff:%d\n", __func__, onoff);
713
714 if (onoff) {
715 /* power on */
716 ret = af9013_write_reg_bits(state, 0xd73a, 3, 1, 0);
717 if (ret)
718 goto error;
719 ret = af9013_write_reg_bits(state, 0xd417, 1, 1, 0);
720 if (ret)
721 goto error;
722 ret = af9013_write_reg_bits(state, 0xd417, 4, 1, 0);
723 } else {
724 /* power off */
725 ret = af9013_reset(state, 1);
726 if (ret)
727 goto error;
728 ret = af9013_write_reg_bits(state, 0xd73a, 3, 1, 1);
729 }
730error:
731 return ret;
732}
733
734static int af9013_lock_led(struct af9013_state *state, u8 onoff)
735{
736 deb_info("%s: onoff:%d\n", __func__, onoff);
737
738 return af9013_write_reg_bits(state, 0xd730, 0, 1, onoff);
739}
740
741static int af9013_set_frontend(struct dvb_frontend *fe,
742 struct dvb_frontend_parameters *params)
743{
744 struct af9013_state *state = fe->demodulator_priv;
745 int ret;
746 u8 auto_mode; /* auto set TPS */
747
748 deb_info("%s: freq:%d bw:%d\n", __func__, params->frequency,
749 params->u.ofdm.bandwidth);
750
751 state->frequency = params->frequency;
752
753 /* program CFOE coefficients */
754 ret = af9013_set_coeff(state, params->u.ofdm.bandwidth);
755 if (ret)
756 goto error;
757
758 /* program frequency control */
759 ret = af9013_set_freq_ctrl(state, params->u.ofdm.bandwidth);
760 if (ret)
761 goto error;
762
763 /* clear TPS lock flag (inverted flag) */
764 ret = af9013_write_reg_bits(state, 0xd330, 3, 1, 1);
765 if (ret)
766 goto error;
767
768 /* clear MPEG2 lock flag */
769 ret = af9013_write_reg_bits(state, 0xd507, 6, 1, 0);
770 if (ret)
771 goto error;
772
773 /* empty channel function */
774 ret = af9013_write_reg_bits(state, 0x9bfe, 0, 1, 0);
775 if (ret)
776 goto error;
777
778 /* empty DVB-T channel function */
779 ret = af9013_write_reg_bits(state, 0x9bc2, 0, 1, 0);
780 if (ret)
781 goto error;
782
783 /* program tuner */
784 if (fe->ops.tuner_ops.set_params)
785 fe->ops.tuner_ops.set_params(fe, params);
786
787 /* program TPS and bandwidth, check if auto mode needed */
788 ret = af9013_set_ofdm_params(state, &params->u.ofdm, &auto_mode);
789 if (ret)
790 goto error;
791
792 if (auto_mode) {
793 /* clear easy mode flag */
794 ret = af9013_write_reg(state, 0xaefd, 0);
795 deb_info("%s: auto TPS\n", __func__);
796 } else {
797 /* set easy mode flag */
798 ret = af9013_write_reg(state, 0xaefd, 1);
799 if (ret)
800 goto error;
801 ret = af9013_write_reg(state, 0xaefe, 0);
802 deb_info("%s: manual TPS\n", __func__);
803 }
804 if (ret)
805 goto error;
806
807 /* everything is set, lets try to receive channel - OFSM GO! */
808 ret = af9013_write_reg(state, 0xffff, 0);
809 if (ret)
810 goto error;
811
812error:
813 return ret;
814}
815
816static int af9013_get_frontend(struct dvb_frontend *fe,
817 struct dvb_frontend_parameters *p)
818{
819 struct af9013_state *state = fe->demodulator_priv;
820 int ret;
821 u8 i, buf[3];
822 deb_info("%s\n", __func__);
823
824 /* read TPS registers */
825 for (i = 0; i < 3; i++) {
826 ret = af9013_read_reg(state, 0xd3c0 + i, &buf[i]);
827 if (ret)
828 goto error;
829 }
830
831 switch ((buf[1] >> 6) & 3) {
832 case 0:
833 p->u.ofdm.constellation = QPSK;
834 break;
835 case 1:
836 p->u.ofdm.constellation = QAM_16;
837 break;
838 case 2:
839 p->u.ofdm.constellation = QAM_64;
840 break;
841 }
842
843 switch ((buf[0] >> 0) & 3) {
844 case 0:
845 p->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K;
846 break;
847 case 1:
848 p->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K;
849 }
850
851 switch ((buf[0] >> 2) & 3) {
852 case 0:
853 p->u.ofdm.guard_interval = GUARD_INTERVAL_1_32;
854 break;
855 case 1:
856 p->u.ofdm.guard_interval = GUARD_INTERVAL_1_16;
857 break;
858 case 2:
859 p->u.ofdm.guard_interval = GUARD_INTERVAL_1_8;
860 break;
861 case 3:
862 p->u.ofdm.guard_interval = GUARD_INTERVAL_1_4;
863 break;
864 }
865
866 switch ((buf[0] >> 4) & 7) {
867 case 0:
868 p->u.ofdm.hierarchy_information = HIERARCHY_NONE;
869 break;
870 case 1:
871 p->u.ofdm.hierarchy_information = HIERARCHY_1;
872 break;
873 case 2:
874 p->u.ofdm.hierarchy_information = HIERARCHY_2;
875 break;
876 case 3:
877 p->u.ofdm.hierarchy_information = HIERARCHY_4;
878 break;
879 }
880
881 switch ((buf[2] >> 0) & 7) {
882 case 0:
883 p->u.ofdm.code_rate_HP = FEC_1_2;
884 break;
885 case 1:
886 p->u.ofdm.code_rate_HP = FEC_2_3;
887 break;
888 case 2:
889 p->u.ofdm.code_rate_HP = FEC_3_4;
890 break;
891 case 3:
892 p->u.ofdm.code_rate_HP = FEC_5_6;
893 break;
894 case 4:
895 p->u.ofdm.code_rate_HP = FEC_7_8;
896 break;
897 }
898
899 switch ((buf[2] >> 3) & 7) {
900 case 0:
901 p->u.ofdm.code_rate_LP = FEC_1_2;
902 break;
903 case 1:
904 p->u.ofdm.code_rate_LP = FEC_2_3;
905 break;
906 case 2:
907 p->u.ofdm.code_rate_LP = FEC_3_4;
908 break;
909 case 3:
910 p->u.ofdm.code_rate_LP = FEC_5_6;
911 break;
912 case 4:
913 p->u.ofdm.code_rate_LP = FEC_7_8;
914 break;
915 }
916
917 switch ((buf[1] >> 2) & 3) {
918 case 0:
919 p->u.ofdm.bandwidth = BANDWIDTH_6_MHZ;
920 break;
921 case 1:
922 p->u.ofdm.bandwidth = BANDWIDTH_7_MHZ;
923 break;
924 case 2:
925 p->u.ofdm.bandwidth = BANDWIDTH_8_MHZ;
926 break;
927 }
928
929 p->inversion = INVERSION_AUTO;
930 p->frequency = state->frequency;
931
932error:
933 return ret;
934}
935
936static int af9013_update_ber_unc(struct dvb_frontend *fe)
937{
938 struct af9013_state *state = fe->demodulator_priv;
939 int ret;
940 u8 buf[3], i;
941 u32 error_bit_count = 0;
942 u32 total_bit_count = 0;
943 u32 abort_packet_count = 0;
944
945 state->ber = 0;
946
947 /* check if error bit count is ready */
948 ret = af9013_read_reg_bits(state, 0xd391, 4, 1, &buf[0]);
949 if (ret)
950 goto error;
951 if (!buf[0])
952 goto exit;
953
954 /* get RSD packet abort count */
955 for (i = 0; i < 2; i++) {
956 ret = af9013_read_reg(state, 0xd38a + i, &buf[i]);
957 if (ret)
958 goto error;
959 }
960 abort_packet_count = (buf[1] << 8) + buf[0];
961
962 /* get error bit count */
963 for (i = 0; i < 3; i++) {
964 ret = af9013_read_reg(state, 0xd387 + i, &buf[i]);
965 if (ret)
966 goto error;
967 }
968 error_bit_count = (buf[2] << 16) + (buf[1] << 8) + buf[0];
969 error_bit_count = error_bit_count - abort_packet_count * 8 * 8;
970
971 /* get used RSD counting period (10000 RSD packets used) */
972 for (i = 0; i < 2; i++) {
973 ret = af9013_read_reg(state, 0xd385 + i, &buf[i]);
974 if (ret)
975 goto error;
976 }
977 total_bit_count = (buf[1] << 8) + buf[0];
978 total_bit_count = total_bit_count - abort_packet_count;
979 total_bit_count = total_bit_count * 204 * 8;
980
981 if (total_bit_count)
982 state->ber = error_bit_count * 1000000000 / total_bit_count;
983
984 state->ucblocks += abort_packet_count;
985
986 deb_info("%s: err bits:%d total bits:%d abort count:%d\n", __func__,
987 error_bit_count, total_bit_count, abort_packet_count);
988
989 /* set BER counting range */
990 ret = af9013_write_reg(state, 0xd385, 10000 & 0xff);
991 if (ret)
992 goto error;
993 ret = af9013_write_reg(state, 0xd386, 10000 >> 8);
994 if (ret)
995 goto error;
996 /* reset and start BER counter */
997 ret = af9013_write_reg_bits(state, 0xd391, 4, 1, 1);
998 if (ret)
999 goto error;
1000
1001exit:
1002error:
1003 return ret;
1004}
1005
1006static int af9013_update_snr(struct dvb_frontend *fe)
1007{
1008 struct af9013_state *state = fe->demodulator_priv;
1009 int ret;
1010 u8 buf[3], i, len;
1011 u32 quant = 0;
1012 struct snr_table *snr_table;
1013
1014 /* check if quantizer ready (for snr) */
1015 ret = af9013_read_reg_bits(state, 0xd2e1, 3, 1, &buf[0]);
1016 if (ret)
1017 goto error;
1018 if (buf[0]) {
1019 /* quantizer ready - read it */
1020 for (i = 0; i < 3; i++) {
1021 ret = af9013_read_reg(state, 0xd2e3 + i, &buf[i]);
1022 if (ret)
1023 goto error;
1024 }
1025 quant = (buf[2] << 16) + (buf[1] << 8) + buf[0];
1026
1027 /* read current constellation */
1028 ret = af9013_read_reg(state, 0xd3c1, &buf[0]);
1029 if (ret)
1030 goto error;
1031
1032 switch ((buf[0] >> 6) & 3) {
1033 case 0:
1034 len = ARRAY_SIZE(qpsk_snr_table);
1035 snr_table = qpsk_snr_table;
1036 break;
1037 case 1:
1038 len = ARRAY_SIZE(qam16_snr_table);
1039 snr_table = qam16_snr_table;
1040 break;
1041 case 2:
1042 len = ARRAY_SIZE(qam64_snr_table);
1043 snr_table = qam64_snr_table;
1044 break;
1045 default:
1046 len = 0;
1047 break;
1048 }
1049
1050 if (len) {
1051 for (i = 0; i < len; i++) {
1052 if (quant < snr_table[i].val) {
1053 state->snr = snr_table[i].snr * 10;
1054 break;
1055 }
1056 }
1057 }
1058
1059 /* set quantizer super frame count */
1060 ret = af9013_write_reg(state, 0xd2e2, 1);
1061 if (ret)
1062 goto error;
1063
1064 /* check quantizer availability */
1065 for (i = 0; i < 10; i++) {
1066 msleep(10);
1067 ret = af9013_read_reg_bits(state, 0xd2e6, 0, 1,
1068 &buf[0]);
1069 if (ret)
1070 goto error;
1071 if (!buf[0])
1072 break;
1073 }
1074
1075 /* reset quantizer */
1076 ret = af9013_write_reg_bits(state, 0xd2e1, 3, 1, 1);
1077 if (ret)
1078 goto error;
1079 }
1080
1081error:
1082 return ret;
1083}
1084
1085static int af9013_update_signal_strength(struct dvb_frontend *fe)
1086{
1087 struct af9013_state *state = fe->demodulator_priv;
1088 int ret;
1089 u8 tmp0;
1090 u8 rf_gain, rf_50, rf_80, if_gain, if_50, if_80;
1091 int signal_strength;
1092
1093 deb_info("%s\n", __func__);
1094
1095 state->signal_strength = 0;
1096
1097 ret = af9013_read_reg_bits(state, 0x9bee, 0, 1, &tmp0);
1098 if (ret)
1099 goto error;
1100 if (tmp0) {
1101 ret = af9013_read_reg(state, 0x9bbd, &rf_50);
1102 if (ret)
1103 goto error;
1104 ret = af9013_read_reg(state, 0x9bd0, &rf_80);
1105 if (ret)
1106 goto error;
1107 ret = af9013_read_reg(state, 0x9be2, &if_50);
1108 if (ret)
1109 goto error;
1110 ret = af9013_read_reg(state, 0x9be4, &if_80);
1111 if (ret)
1112 goto error;
1113 ret = af9013_read_reg(state, 0xd07c, &rf_gain);
1114 if (ret)
1115 goto error;
1116 ret = af9013_read_reg(state, 0xd07d, &if_gain);
1117 if (ret)
1118 goto error;
1119 signal_strength = (0xffff / (9 * (rf_50 + if_50) - \
1120 11 * (rf_80 + if_80))) * (10 * (rf_gain + if_gain) - \
1121 11 * (rf_80 + if_80));
1122 if (signal_strength < 0)
1123 signal_strength = 0;
1124 else if (signal_strength > 0xffff)
1125 signal_strength = 0xffff;
1126
1127 state->signal_strength = signal_strength;
1128 }
1129
1130error:
1131 return ret;
1132}
1133
1134static int af9013_update_statistics(struct dvb_frontend *fe)
1135{
1136 struct af9013_state *state = fe->demodulator_priv;
1137 int ret;
1138
1139 if (time_before(jiffies, state->next_statistics_check))
1140 return 0;
1141
1142 /* set minimum statistic update interval */
1143 state->next_statistics_check = jiffies + msecs_to_jiffies(1200);
1144
1145 ret = af9013_update_signal_strength(fe);
1146 if (ret)
1147 goto error;
1148 ret = af9013_update_snr(fe);
1149 if (ret)
1150 goto error;
1151 ret = af9013_update_ber_unc(fe);
1152 if (ret)
1153 goto error;
1154
1155error:
1156 return ret;
1157}
1158
1159static int af9013_get_tune_settings(struct dvb_frontend *fe,
1160 struct dvb_frontend_tune_settings *fesettings)
1161{
1162 fesettings->min_delay_ms = 800;
1163 fesettings->step_size = 0;
1164 fesettings->max_drift = 0;
1165
1166 return 0;
1167}
1168
1169static int af9013_read_status(struct dvb_frontend *fe, fe_status_t *status)
1170{
1171 struct af9013_state *state = fe->demodulator_priv;
1172 int ret = 0;
1173 u8 tmp;
1174 *status = 0;
1175
1176 /* TPS lock */
1177 ret = af9013_read_reg_bits(state, 0xd330, 3, 1, &tmp);
1178 if (ret)
1179 goto error;
1180 if (tmp)
1181 *status |= FE_HAS_VITERBI | FE_HAS_CARRIER | FE_HAS_SIGNAL;
1182
1183 /* MPEG2 lock */
1184 ret = af9013_read_reg_bits(state, 0xd507, 6, 1, &tmp);
1185 if (ret)
1186 goto error;
1187 if (tmp)
1188 *status |= FE_HAS_SYNC | FE_HAS_LOCK;
1189
1190 if (!*status & FE_HAS_SIGNAL) {
1191 /* AGC lock */
1192 ret = af9013_read_reg_bits(state, 0xd1a0, 6, 1, &tmp);
1193 if (ret)
1194 goto error;
1195 if (tmp)
1196 *status |= FE_HAS_SIGNAL;
1197 }
1198
1199 if (!*status & FE_HAS_CARRIER) {
1200 /* CFO lock */
1201 ret = af9013_read_reg_bits(state, 0xd333, 7, 1, &tmp);
1202 if (ret)
1203 goto error;
1204 if (tmp)
1205 *status |= FE_HAS_CARRIER;
1206 }
1207
1208 if (!*status & FE_HAS_CARRIER) {
1209 /* SFOE lock */
1210 ret = af9013_read_reg_bits(state, 0xd334, 6, 1, &tmp);
1211 if (ret)
1212 goto error;
1213 if (tmp)
1214 *status |= FE_HAS_CARRIER;
1215 }
1216
1217 ret = af9013_update_statistics(fe);
1218
1219error:
1220 return ret;
1221}
1222
1223
1224static int af9013_read_ber(struct dvb_frontend *fe, u32 *ber)
1225{
1226 struct af9013_state *state = fe->demodulator_priv;
1227 int ret;
1228 ret = af9013_update_statistics(fe);
1229 *ber = state->ber;
1230 return ret;
1231}
1232
1233static int af9013_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
1234{
1235 struct af9013_state *state = fe->demodulator_priv;
1236 int ret;
1237 ret = af9013_update_statistics(fe);
1238 *strength = state->signal_strength;
1239 return ret;
1240}
1241
1242static int af9013_read_snr(struct dvb_frontend *fe, u16 *snr)
1243{
1244 struct af9013_state *state = fe->demodulator_priv;
1245 int ret;
1246 ret = af9013_update_statistics(fe);
1247 *snr = state->snr;
1248 return ret;
1249}
1250
1251static int af9013_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
1252{
1253 struct af9013_state *state = fe->demodulator_priv;
1254 int ret;
1255 ret = af9013_update_statistics(fe);
1256 *ucblocks = state->ucblocks;
1257 return ret;
1258}
1259
1260static int af9013_sleep(struct dvb_frontend *fe)
1261{
1262 struct af9013_state *state = fe->demodulator_priv;
1263 int ret;
1264 deb_info("%s\n", __func__);
1265
1266 ret = af9013_lock_led(state, 0);
1267 if (ret)
1268 goto error;
1269
1270 ret = af9013_power_ctrl(state, 0);
1271error:
1272 return ret;
1273}
1274
1275static int af9013_init(struct dvb_frontend *fe)
1276{
1277 struct af9013_state *state = fe->demodulator_priv;
1278 int ret, i, len;
1279 u8 tmp0, tmp1;
1280 struct regdesc *init;
1281 deb_info("%s\n", __func__);
1282
1283 /* reset OFDM */
1284 ret = af9013_reset(state, 0);
1285 if (ret)
1286 goto error;
1287
1288 /* power on */
1289 ret = af9013_power_ctrl(state, 1);
1290 if (ret)
1291 goto error;
1292
1293 /* enable ADC */
1294 ret = af9013_write_reg(state, 0xd73a, 0xa4);
1295 if (ret)
1296 goto error;
1297
1298 /* write API version to firmware */
1299 for (i = 0; i < sizeof(state->config.api_version); i++) {
1300 ret = af9013_write_reg(state, 0x9bf2 + i,
1301 state->config.api_version[i]);
1302 if (ret)
1303 goto error;
1304 }
1305
1306 /* program ADC control */
1307 ret = af9013_set_adc_ctrl(state);
1308 if (ret)
1309 goto error;
1310
1311 /* set I2C master clock */
1312 ret = af9013_write_reg(state, 0xd416, 0x14);
1313 if (ret)
1314 goto error;
1315
1316 /* set 16 embx */
1317 ret = af9013_write_reg_bits(state, 0xd700, 1, 1, 1);
1318 if (ret)
1319 goto error;
1320
1321 /* set no trigger */
1322 ret = af9013_write_reg_bits(state, 0xd700, 2, 1, 0);
1323 if (ret)
1324 goto error;
1325
1326 /* set read-update bit for constellation */
1327 ret = af9013_write_reg_bits(state, 0xd371, 1, 1, 1);
1328 if (ret)
1329 goto error;
1330
1331 /* enable FEC monitor */
1332 ret = af9013_write_reg_bits(state, 0xd392, 1, 1, 1);
1333 if (ret)
1334 goto error;
1335
1336 /* load OFSM settings */
1337 deb_info("%s: load ofsm settings\n", __func__);
1338 len = ARRAY_SIZE(ofsm_init);
1339 init = ofsm_init;
1340 for (i = 0; i < len; i++) {
1341 ret = af9013_write_reg_bits(state, init[i].addr, init[i].pos,
1342 init[i].len, init[i].val);
1343 if (ret)
1344 goto error;
1345 }
1346
1347 /* load tuner specific settings */
1348 deb_info("%s: load tuner specific settings\n", __func__);
1349 switch (state->config.tuner) {
1350 case AF9013_TUNER_MXL5003D:
1351 len = ARRAY_SIZE(tuner_init_mxl5003d);
1352 init = tuner_init_mxl5003d;
1353 break;
1354 case AF9013_TUNER_MXL5005D:
1355 case AF9013_TUNER_MXL5005R:
1356 len = ARRAY_SIZE(tuner_init_mxl5005);
1357 init = tuner_init_mxl5005;
1358 break;
1359 case AF9013_TUNER_ENV77H11D5:
1360 len = ARRAY_SIZE(tuner_init_env77h11d5);
1361 init = tuner_init_env77h11d5;
1362 break;
1363 case AF9013_TUNER_MT2060:
1364 len = ARRAY_SIZE(tuner_init_mt2060);
1365 init = tuner_init_mt2060;
1366 break;
1367 case AF9013_TUNER_MC44S803:
1368 len = ARRAY_SIZE(tuner_init_mc44s803);
1369 init = tuner_init_mc44s803;
1370 break;
1371 case AF9013_TUNER_QT1010:
1372 case AF9013_TUNER_QT1010A:
1373 len = ARRAY_SIZE(tuner_init_qt1010);
1374 init = tuner_init_qt1010;
1375 break;
1376 case AF9013_TUNER_MT2060_2:
1377 len = ARRAY_SIZE(tuner_init_mt2060_2);
1378 init = tuner_init_mt2060_2;
1379 break;
1380 case AF9013_TUNER_TDA18271:
1381 len = ARRAY_SIZE(tuner_init_tda18271);
1382 init = tuner_init_tda18271;
1383 break;
1384 case AF9013_TUNER_UNKNOWN:
1385 default:
1386 len = ARRAY_SIZE(tuner_init_unknown);
1387 init = tuner_init_unknown;
1388 break;
1389 }
1390
1391 for (i = 0; i < len; i++) {
1392 ret = af9013_write_reg_bits(state, init[i].addr, init[i].pos,
1393 init[i].len, init[i].val);
1394 if (ret)
1395 goto error;
1396 }
1397
1398 /* set TS mode */
1399 deb_info("%s: setting ts mode\n", __func__);
1400 tmp0 = 0; /* parallel mode */
1401 tmp1 = 0; /* serial mode */
1402 switch (state->config.output_mode) {
1403 case AF9013_OUTPUT_MODE_PARALLEL:
1404 tmp0 = 1;
1405 break;
1406 case AF9013_OUTPUT_MODE_SERIAL:
1407 tmp1 = 1;
1408 break;
1409 case AF9013_OUTPUT_MODE_USB:
1410 /* usb mode for AF9015 */
1411 default:
1412 break;
1413 }
1414 ret = af9013_write_reg_bits(state, 0xd500, 1, 1, tmp0); /* parallel */
1415 if (ret)
1416 goto error;
1417 ret = af9013_write_reg_bits(state, 0xd500, 2, 1, tmp1); /* serial */
1418 if (ret)
1419 goto error;
1420
1421 /* enable lock led */
1422 ret = af9013_lock_led(state, 1);
1423 if (ret)
1424 goto error;
1425
1426error:
1427 return ret;
1428}
1429
1430static struct dvb_frontend_ops af9013_ops;
1431
1432static int af9013_download_firmware(struct af9013_state *state)
1433{
1434 int i, len, packets, remainder, ret;
1435 const struct firmware *fw;
1436 u16 addr = 0x5100; /* firmware start address */
1437 u16 checksum = 0;
1438 u8 val;
1439 u8 fw_params[4];
1440 u8 *data;
1441 u8 *fw_file = AF9013_DEFAULT_FIRMWARE;
1442
1443 msleep(100);
1444 /* check whether firmware is already running */
1445 ret = af9013_read_reg(state, 0x98be, &val);
1446 if (ret)
1447 goto error;
1448 else
1449 deb_info("%s: firmware status:%02x\n", __func__, val);
1450
1451 if (val == 0x0c) /* fw is running, no need for download */
1452 goto exit;
1453
1454 info("found a '%s' in cold state, will try to load a firmware",
1455 af9013_ops.info.name);
1456
1457 /* request the firmware, this will block and timeout */
1458 ret = request_firmware(&fw, fw_file, &state->i2c->dev);
1459 if (ret) {
1460 err("did not find the firmware file. (%s) "
1461 "Please see linux/Documentation/dvb/ for more details" \
1462 " on firmware-problems. (%d)",
1463 fw_file, ret);
1464 goto error;
1465 }
1466
1467 info("downloading firmware from file '%s'", fw_file);
1468
1469 /* calc checksum */
1470 for (i = 0; i < fw->size; i++)
1471 checksum += fw->data[i];
1472
1473 fw_params[0] = checksum >> 8;
1474 fw_params[1] = checksum & 0xff;
1475 fw_params[2] = fw->size >> 8;
1476 fw_params[3] = fw->size & 0xff;
1477
1478 /* write fw checksum & size */
1479 ret = af9013_write_ofsm_regs(state, 0x50fc,
1480 fw_params, sizeof(fw_params));
1481 if (ret)
1482 goto error_release;
1483
1484 #define FW_PACKET_MAX_DATA 16
1485
1486 packets = fw->size / FW_PACKET_MAX_DATA;
1487 remainder = fw->size % FW_PACKET_MAX_DATA;
1488 len = FW_PACKET_MAX_DATA;
1489 for (i = 0; i <= packets; i++) {
1490 if (i == packets) /* set size of the last packet */
1491 len = remainder;
1492
1493 data = (u8 *)(fw->data + i * FW_PACKET_MAX_DATA);
1494 ret = af9013_write_ofsm_regs(state, addr, data, len);
1495 addr += FW_PACKET_MAX_DATA;
1496
1497 if (ret) {
1498 err("firmware download failed at %d with %d", i, ret);
1499 goto error_release;
1500 }
1501 }
1502
1503 /* request boot firmware */
1504 ret = af9013_write_reg(state, 0xe205, 1);
1505 if (ret)
1506 goto error_release;
1507
1508 for (i = 0; i < 15; i++) {
1509 msleep(100);
1510
1511 /* check firmware status */
1512 ret = af9013_read_reg(state, 0x98be, &val);
1513 if (ret)
1514 goto error_release;
1515
1516 deb_info("%s: firmware status:%02x\n", __func__, val);
1517
1518 if (val == 0x0c || val == 0x04) /* success or fail */
1519 break;
1520 }
1521
1522 if (val == 0x04) {
1523 err("firmware did not run");
1524 ret = -1;
1525 } else if (val != 0x0c) {
1526 err("firmware boot timeout");
1527 ret = -1;
1528 }
1529
1530error_release:
1531 release_firmware(fw);
1532error:
1533exit:
1534 if (!ret)
1535 info("found a '%s' in warm state.", af9013_ops.info.name);
1536 return ret;
1537}
1538
1539static int af9013_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
1540{
1541 int ret;
1542 struct af9013_state *state = fe->demodulator_priv;
1543 deb_info("%s: enable:%d\n", __func__, enable);
1544
1545 if (state->config.output_mode == AF9013_OUTPUT_MODE_USB)
1546 ret = af9013_write_reg_bits(state, 0xd417, 3, 1, enable);
1547 else
1548 ret = af9013_write_reg_bits(state, 0xd607, 2, 1, enable);
1549
1550 return ret;
1551}
1552
1553static void af9013_release(struct dvb_frontend *fe)
1554{
1555 struct af9013_state *state = fe->demodulator_priv;
1556 kfree(state);
1557}
1558
1559static struct dvb_frontend_ops af9013_ops;
1560
1561struct dvb_frontend *af9013_attach(const struct af9013_config *config,
1562 struct i2c_adapter *i2c)
1563{
1564 int ret;
1565 struct af9013_state *state = NULL;
1566 u8 buf[3], i;
1567
1568 /* allocate memory for the internal state */
1569 state = kzalloc(sizeof(struct af9013_state), GFP_KERNEL);
1570 if (state == NULL)
1571 goto error;
1572
1573 /* setup the state */
1574 state->i2c = i2c;
1575 memcpy(&state->config, config, sizeof(struct af9013_config));
1576
1577 /* chip version */
1578 ret = af9013_read_reg_bits(state, 0xd733, 4, 4, &buf[2]);
1579 if (ret)
1580 goto error;
1581
1582 /* ROM version */
1583 for (i = 0; i < 2; i++) {
1584 ret = af9013_read_reg(state, 0x116b + i, &buf[i]);
1585 if (ret)
1586 goto error;
1587 }
1588 deb_info("%s: chip version:%d ROM version:%d.%d\n", __func__,
1589 buf[2], buf[0], buf[1]);
1590
1591 /* download firmware */
1592 if (state->config.output_mode != AF9013_OUTPUT_MODE_USB) {
1593 ret = af9013_download_firmware(state);
1594 if (ret)
1595 goto error;
1596 }
1597
1598 /* firmware version */
1599 for (i = 0; i < 3; i++) {
1600 ret = af9013_read_reg(state, 0x5103 + i, &buf[i]);
1601 if (ret)
1602 goto error;
1603 }
1604 info("firmware version:%d.%d.%d", buf[0], buf[1], buf[2]);
1605
1606 /* settings for mp2if */
1607 if (state->config.output_mode == AF9013_OUTPUT_MODE_USB) {
1608 /* AF9015 split PSB to 1.5k + 0.5k */
1609 ret = af9013_write_reg_bits(state, 0xd50b, 2, 1, 1);
1610 } else {
1611 /* AF9013 change the output bit to data7 */
1612 ret = af9013_write_reg_bits(state, 0xd500, 3, 1, 1);
1613 if (ret)
1614 goto error;
1615 /* AF9013 set mpeg to full speed */
1616 ret = af9013_write_reg_bits(state, 0xd502, 4, 1, 1);
1617 }
1618 if (ret)
1619 goto error;
1620 ret = af9013_write_reg_bits(state, 0xd520, 4, 1, 1);
1621 if (ret)
1622 goto error;
1623
1624 /* set GPIOs */
1625 for (i = 0; i < sizeof(state->config.gpio); i++) {
1626 ret = af9013_set_gpio(state, i, state->config.gpio[i]);
1627 if (ret)
1628 goto error;
1629 }
1630
1631 /* create dvb_frontend */
1632 memcpy(&state->frontend.ops, &af9013_ops,
1633 sizeof(struct dvb_frontend_ops));
1634 state->frontend.demodulator_priv = state;
1635
1636 return &state->frontend;
1637error:
1638 kfree(state);
1639 return NULL;
1640}
1641EXPORT_SYMBOL(af9013_attach);
1642
1643static struct dvb_frontend_ops af9013_ops = {
1644 .info = {
1645 .name = "Afatech AF9013 DVB-T",
1646 .type = FE_OFDM,
1647 .frequency_min = 174000000,
1648 .frequency_max = 862000000,
1649 .frequency_stepsize = 250000,
1650 .frequency_tolerance = 0,
1651 .caps =
1652 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
1653 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
1654 FE_CAN_QPSK | FE_CAN_QAM_16 |
1655 FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
1656 FE_CAN_TRANSMISSION_MODE_AUTO |
1657 FE_CAN_GUARD_INTERVAL_AUTO |
1658 FE_CAN_HIERARCHY_AUTO |
1659 FE_CAN_RECOVER |
1660 FE_CAN_MUTE_TS
1661 },
1662
1663 .release = af9013_release,
1664 .init = af9013_init,
1665 .sleep = af9013_sleep,
1666 .i2c_gate_ctrl = af9013_i2c_gate_ctrl,
1667
1668 .set_frontend = af9013_set_frontend,
1669 .get_frontend = af9013_get_frontend,
1670
1671 .get_tune_settings = af9013_get_tune_settings,
1672
1673 .read_status = af9013_read_status,
1674 .read_ber = af9013_read_ber,
1675 .read_signal_strength = af9013_read_signal_strength,
1676 .read_snr = af9013_read_snr,
1677 .read_ucblocks = af9013_read_ucblocks,
1678};
1679
1680module_param_named(debug, af9013_debug, int, 0644);
1681MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
1682
1683MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
1684MODULE_DESCRIPTION("Afatech AF9013 DVB-T demodulator driver");
1685MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/af9013.h b/drivers/media/dvb/frontends/af9013.h
new file mode 100644
index 000000000000..28b90c91c766
--- /dev/null
+++ b/drivers/media/dvb/frontends/af9013.h
@@ -0,0 +1,107 @@
1/*
2 * DVB USB Linux driver for Afatech AF9015 DVB-T USB2.0 receiver
3 *
4 * Copyright (C) 2007 Antti Palosaari <crope@iki.fi>
5 *
6 * Thanks to Afatech who kindly provided information.
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
24#ifndef _AF9013_H_
25#define _AF9013_H_
26
27#include <linux/dvb/frontend.h>
28
29enum af9013_ts_mode {
30 AF9013_OUTPUT_MODE_PARALLEL,
31 AF9013_OUTPUT_MODE_SERIAL,
32 AF9013_OUTPUT_MODE_USB, /* only for AF9015 */
33};
34
35enum af9013_tuner {
36 AF9013_TUNER_MXL5003D = 3, /* MaxLinear */
37 AF9013_TUNER_MXL5005D = 13, /* MaxLinear */
38 AF9013_TUNER_MXL5005R = 30, /* MaxLinear */
39 AF9013_TUNER_ENV77H11D5 = 129, /* Panasonic */
40 AF9013_TUNER_MT2060 = 130, /* Microtune */
41 AF9013_TUNER_MC44S803 = 133, /* Freescale */
42 AF9013_TUNER_QT1010 = 134, /* Quantek */
43 AF9013_TUNER_UNKNOWN = 140, /* for can tuners ? */
44 AF9013_TUNER_MT2060_2 = 147, /* Microtune */
45 AF9013_TUNER_TDA18271 = 156, /* NXP */
46 AF9013_TUNER_QT1010A = 162, /* Quantek */
47};
48
49/* AF9013/5 GPIOs (mostly guessed)
50 demod#1-gpio#0 - set demod#2 i2c-addr for dual devices
51 demod#1-gpio#1 - xtal setting (?)
52 demod#1-gpio#3 - tuner#1
53 demod#2-gpio#0 - tuner#2
54 demod#2-gpio#1 - xtal setting (?)
55*/
56#define AF9013_GPIO_ON (1 << 0)
57#define AF9013_GPIO_EN (1 << 1)
58#define AF9013_GPIO_O (1 << 2)
59#define AF9013_GPIO_I (1 << 3)
60
61#define AF9013_GPIO_LO (AF9013_GPIO_ON|AF9013_GPIO_EN)
62#define AF9013_GPIO_HI (AF9013_GPIO_ON|AF9013_GPIO_EN|AF9013_GPIO_O)
63
64#define AF9013_GPIO_TUNER_ON (AF9013_GPIO_ON|AF9013_GPIO_EN)
65#define AF9013_GPIO_TUNER_OFF (AF9013_GPIO_ON|AF9013_GPIO_EN|AF9013_GPIO_O)
66
67struct af9013_config {
68 /* demodulator's I2C address */
69 u8 demod_address;
70
71 /* frequencies in kHz */
72 u32 adc_clock;
73
74 /* tuner ID */
75 u8 tuner;
76
77 /* tuner IF */
78 u16 tuner_if;
79
80 /* TS data output mode */
81 u8 output_mode:2;
82
83 /* RF spectrum inversion */
84 u8 rf_spec_inv:1;
85
86 /* API version */
87 u8 api_version[4];
88
89 /* GPIOs */
90 u8 gpio[4];
91};
92
93
94#if defined(CONFIG_DVB_AF9013) || \
95 (defined(CONFIG_DVB_AF9013_MODULE) && defined(MODULE))
96extern struct dvb_frontend *af9013_attach(const struct af9013_config *config,
97 struct i2c_adapter *i2c);
98#else
99static inline struct dvb_frontend *af9013_attach(
100const struct af9013_config *config, struct i2c_adapter *i2c)
101{
102 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
103 return NULL;
104}
105#endif /* CONFIG_DVB_AF9013 */
106
107#endif /* _AF9013_H_ */
diff --git a/drivers/media/dvb/frontends/af9013_priv.h b/drivers/media/dvb/frontends/af9013_priv.h
new file mode 100644
index 000000000000..163e251d0b73
--- /dev/null
+++ b/drivers/media/dvb/frontends/af9013_priv.h
@@ -0,0 +1,869 @@
1/*
2 * DVB USB Linux driver for Afatech AF9015 DVB-T USB2.0 receiver
3 *
4 * Copyright (C) 2007 Antti Palosaari <crope@iki.fi>
5 *
6 * Thanks to Afatech who kindly provided information.
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
24#ifndef _AF9013_PRIV_
25#define _AF9013_PRIV_
26
27#define LOG_PREFIX "af9013"
28extern int af9013_debug;
29
30#define dprintk(var, level, args...) \
31 do { if ((var & level)) printk(args); } while (0)
32
33#define debug_dump(b, l, func) {\
34 int loop_; \
35 for (loop_ = 0; loop_ < l; loop_++) \
36 func("%02x ", b[loop_]); \
37 func("\n");\
38}
39
40#define deb_info(args...) dprintk(af9013_debug, 0x01, args)
41
42#undef err
43#define err(f, arg...) printk(KERN_ERR LOG_PREFIX": " f "\n" , ## arg)
44#undef info
45#define info(f, arg...) printk(KERN_INFO LOG_PREFIX": " f "\n" , ## arg)
46#undef warn
47#define warn(f, arg...) printk(KERN_WARNING LOG_PREFIX": " f "\n" , ## arg)
48
49#define AF9013_DEFAULT_FIRMWARE "dvb-fe-af9013.fw"
50
51struct regdesc {
52 u16 addr;
53 u8 pos:4;
54 u8 len:4;
55 u8 val;
56};
57
58struct snr_table {
59 u32 val;
60 u8 snr;
61};
62
63/* QPSK SNR lookup table */
64static struct snr_table qpsk_snr_table[] = {
65 { 0x0b4771, 0 },
66 { 0x0c1aed, 1 },
67 { 0x0d0d27, 2 },
68 { 0x0e4d19, 3 },
69 { 0x0e5da8, 4 },
70 { 0x107097, 5 },
71 { 0x116975, 6 },
72 { 0x1252d9, 7 },
73 { 0x131fa4, 8 },
74 { 0x13d5e1, 9 },
75 { 0x148e53, 10 },
76 { 0x15358b, 11 },
77 { 0x15dd29, 12 },
78 { 0x168112, 13 },
79 { 0x170b61, 14 },
80 { 0xffffff, 15 },
81};
82
83/* QAM16 SNR lookup table */
84static struct snr_table qam16_snr_table[] = {
85 { 0x05eb62, 5 },
86 { 0x05fecf, 6 },
87 { 0x060b80, 7 },
88 { 0x062501, 8 },
89 { 0x064865, 9 },
90 { 0x069604, 10 },
91 { 0x06f356, 11 },
92 { 0x07706a, 12 },
93 { 0x0804d3, 13 },
94 { 0x089d1a, 14 },
95 { 0x093e3d, 15 },
96 { 0x09e35d, 16 },
97 { 0x0a7c3c, 17 },
98 { 0x0afaf8, 18 },
99 { 0x0b719d, 19 },
100 { 0xffffff, 20 },
101};
102
103/* QAM64 SNR lookup table */
104static struct snr_table qam64_snr_table[] = {
105 { 0x03109b, 12 },
106 { 0x0310d4, 13 },
107 { 0x031920, 14 },
108 { 0x0322d0, 15 },
109 { 0x0339fc, 16 },
110 { 0x0364a1, 17 },
111 { 0x038bcc, 18 },
112 { 0x03c7d3, 19 },
113 { 0x0408cc, 20 },
114 { 0x043bed, 21 },
115 { 0x048061, 22 },
116 { 0x04be95, 23 },
117 { 0x04fa7d, 24 },
118 { 0x052405, 25 },
119 { 0x05570d, 26 },
120 { 0xffffff, 27 },
121};
122
123static struct regdesc ofsm_init[] = {
124 { 0xd73a, 0, 8, 0xa1 },
125 { 0xd73b, 0, 8, 0x1f },
126 { 0xd73c, 4, 4, 0x0a },
127 { 0xd732, 3, 1, 0x00 },
128 { 0xd731, 4, 2, 0x03 },
129 { 0xd73d, 7, 1, 0x01 },
130 { 0xd740, 0, 1, 0x00 },
131 { 0xd740, 1, 1, 0x00 },
132 { 0xd740, 2, 1, 0x00 },
133 { 0xd740, 3, 1, 0x01 },
134 { 0xd3c1, 4, 1, 0x01 },
135 { 0xd3a2, 0, 8, 0x00 },
136 { 0xd3a3, 0, 8, 0x04 },
137 { 0xd305, 0, 8, 0x32 },
138 { 0xd306, 0, 8, 0x10 },
139 { 0xd304, 0, 8, 0x04 },
140 { 0x9112, 0, 1, 0x01 },
141 { 0x911d, 0, 1, 0x01 },
142 { 0x911a, 0, 1, 0x01 },
143 { 0x911b, 0, 1, 0x01 },
144 { 0x9bce, 0, 4, 0x02 },
145 { 0x9116, 0, 1, 0x01 },
146 { 0x9bd1, 0, 1, 0x01 },
147 { 0xd2e0, 0, 8, 0xd0 },
148 { 0xd2e9, 0, 4, 0x0d },
149 { 0xd38c, 0, 8, 0xfc },
150 { 0xd38d, 0, 8, 0x00 },
151 { 0xd38e, 0, 8, 0x7e },
152 { 0xd38f, 0, 8, 0x00 },
153 { 0xd390, 0, 8, 0x2f },
154 { 0xd145, 4, 1, 0x01 },
155 { 0xd1a9, 4, 1, 0x01 },
156 { 0xd158, 5, 3, 0x01 },
157 { 0xd159, 0, 6, 0x06 },
158 { 0xd167, 0, 8, 0x00 },
159 { 0xd168, 0, 4, 0x07 },
160 { 0xd1c3, 5, 3, 0x00 },
161 { 0xd1c4, 0, 6, 0x00 },
162 { 0xd1c5, 0, 7, 0x10 },
163 { 0xd1c6, 0, 3, 0x02 },
164 { 0xd080, 2, 5, 0x03 },
165 { 0xd081, 4, 4, 0x09 },
166 { 0xd098, 4, 4, 0x0f },
167 { 0xd098, 0, 4, 0x03 },
168 { 0xdbc0, 3, 1, 0x01 },
169 { 0xdbc0, 4, 1, 0x01 },
170 { 0xdbc7, 0, 8, 0x08 },
171 { 0xdbc8, 4, 4, 0x00 },
172 { 0xdbc9, 0, 5, 0x01 },
173 { 0xd280, 0, 8, 0xe0 },
174 { 0xd281, 0, 8, 0xff },
175 { 0xd282, 0, 8, 0xff },
176 { 0xd283, 0, 8, 0xc3 },
177 { 0xd284, 0, 8, 0xff },
178 { 0xd285, 0, 4, 0x01 },
179 { 0xd0f0, 0, 7, 0x1a },
180 { 0xd0f1, 4, 1, 0x01 },
181 { 0xd0f2, 0, 8, 0x0c },
182 { 0xd103, 0, 4, 0x08 },
183 { 0xd0f8, 0, 7, 0x20 },
184 { 0xd111, 5, 1, 0x00 },
185 { 0xd111, 6, 1, 0x00 },
186 { 0x910b, 0, 8, 0x0a },
187 { 0x9115, 0, 8, 0x02 },
188 { 0x910c, 0, 8, 0x02 },
189 { 0x910d, 0, 8, 0x08 },
190 { 0x910e, 0, 8, 0x0a },
191 { 0x9bf6, 0, 8, 0x06 },
192 { 0x9bf8, 0, 8, 0x02 },
193 { 0x9bf7, 0, 8, 0x05 },
194 { 0x9bf9, 0, 8, 0x0f },
195 { 0x9bfc, 0, 8, 0x13 },
196 { 0x9bd3, 0, 8, 0xff },
197 { 0x9bbe, 0, 1, 0x01 },
198 { 0x9bcc, 0, 1, 0x01 },
199};
200
201/* Panasonic ENV77H11D5 tuner init
202 AF9013_TUNER_ENV77H11D5 = 129 */
203static struct regdesc tuner_init_env77h11d5[] = {
204 { 0x9bd5, 0, 8, 0x01 },
205 { 0x9bd6, 0, 8, 0x03 },
206 { 0x9bbe, 0, 8, 0x01 },
207 { 0xd1a0, 1, 1, 0x01 },
208 { 0xd000, 0, 1, 0x01 },
209 { 0xd000, 1, 1, 0x00 },
210 { 0xd001, 1, 1, 0x01 },
211 { 0xd001, 0, 1, 0x00 },
212 { 0xd001, 5, 1, 0x00 },
213 { 0xd002, 0, 5, 0x19 },
214 { 0xd003, 0, 5, 0x1a },
215 { 0xd004, 0, 5, 0x19 },
216 { 0xd005, 0, 5, 0x1a },
217 { 0xd00e, 0, 5, 0x10 },
218 { 0xd00f, 0, 3, 0x04 },
219 { 0xd00f, 3, 3, 0x05 },
220 { 0xd010, 0, 3, 0x04 },
221 { 0xd010, 3, 3, 0x05 },
222 { 0xd016, 4, 4, 0x03 },
223 { 0xd01f, 0, 6, 0x0a },
224 { 0xd020, 0, 6, 0x0a },
225 { 0x9bda, 0, 8, 0x00 },
226 { 0x9be3, 0, 8, 0x00 },
227 { 0xd015, 0, 8, 0x50 },
228 { 0xd016, 0, 1, 0x00 },
229 { 0xd044, 0, 8, 0x46 },
230 { 0xd045, 0, 1, 0x00 },
231 { 0xd008, 0, 8, 0xdf },
232 { 0xd009, 0, 2, 0x02 },
233 { 0xd006, 0, 8, 0x44 },
234 { 0xd007, 0, 2, 0x01 },
235 { 0xd00c, 0, 8, 0xeb },
236 { 0xd00d, 0, 2, 0x02 },
237 { 0xd00a, 0, 8, 0xf4 },
238 { 0xd00b, 0, 2, 0x01 },
239 { 0x9bba, 0, 8, 0xf9 },
240 { 0x9bc3, 0, 8, 0xdf },
241 { 0x9bc4, 0, 8, 0x02 },
242 { 0x9bc5, 0, 8, 0xeb },
243 { 0x9bc6, 0, 8, 0x02 },
244 { 0x9bc9, 0, 8, 0x52 },
245 { 0xd011, 0, 8, 0x3c },
246 { 0xd012, 0, 2, 0x01 },
247 { 0xd013, 0, 8, 0xf7 },
248 { 0xd014, 0, 2, 0x02 },
249 { 0xd040, 0, 8, 0x0b },
250 { 0xd041, 0, 2, 0x02 },
251 { 0xd042, 0, 8, 0x4d },
252 { 0xd043, 0, 2, 0x00 },
253 { 0xd045, 1, 1, 0x00 },
254 { 0x9bcf, 0, 1, 0x01 },
255 { 0xd045, 2, 1, 0x01 },
256 { 0xd04f, 0, 8, 0x9a },
257 { 0xd050, 0, 1, 0x01 },
258 { 0xd051, 0, 8, 0x5a },
259 { 0xd052, 0, 1, 0x01 },
260 { 0xd053, 0, 8, 0x50 },
261 { 0xd054, 0, 8, 0x46 },
262 { 0x9bd7, 0, 8, 0x0a },
263 { 0x9bd8, 0, 8, 0x14 },
264 { 0x9bd9, 0, 8, 0x08 },
265};
266
267/* Microtune MT2060 tuner init
268 AF9013_TUNER_MT2060 = 130 */
269static struct regdesc tuner_init_mt2060[] = {
270 { 0x9bd5, 0, 8, 0x01 },
271 { 0x9bd6, 0, 8, 0x07 },
272 { 0xd1a0, 1, 1, 0x01 },
273 { 0xd000, 0, 1, 0x01 },
274 { 0xd000, 1, 1, 0x00 },
275 { 0xd001, 1, 1, 0x01 },
276 { 0xd001, 0, 1, 0x00 },
277 { 0xd001, 5, 1, 0x00 },
278 { 0xd002, 0, 5, 0x19 },
279 { 0xd003, 0, 5, 0x1a },
280 { 0xd004, 0, 5, 0x19 },
281 { 0xd005, 0, 5, 0x1a },
282 { 0xd00e, 0, 5, 0x10 },
283 { 0xd00f, 0, 3, 0x04 },
284 { 0xd00f, 3, 3, 0x05 },
285 { 0xd010, 0, 3, 0x04 },
286 { 0xd010, 3, 3, 0x05 },
287 { 0xd016, 4, 4, 0x03 },
288 { 0xd01f, 0, 6, 0x0a },
289 { 0xd020, 0, 6, 0x0a },
290 { 0x9bda, 0, 8, 0x00 },
291 { 0x9be3, 0, 8, 0x00 },
292 { 0x9bbe, 0, 1, 0x00 },
293 { 0x9bcc, 0, 1, 0x00 },
294 { 0x9bb9, 0, 8, 0x75 },
295 { 0x9bcd, 0, 8, 0x24 },
296 { 0x9bff, 0, 8, 0x30 },
297 { 0xd015, 0, 8, 0x46 },
298 { 0xd016, 0, 1, 0x00 },
299 { 0xd044, 0, 8, 0x46 },
300 { 0xd045, 0, 1, 0x00 },
301 { 0xd008, 0, 8, 0x0f },
302 { 0xd009, 0, 2, 0x02 },
303 { 0xd006, 0, 8, 0x32 },
304 { 0xd007, 0, 2, 0x01 },
305 { 0xd00c, 0, 8, 0x36 },
306 { 0xd00d, 0, 2, 0x03 },
307 { 0xd00a, 0, 8, 0x35 },
308 { 0xd00b, 0, 2, 0x01 },
309 { 0x9bc7, 0, 8, 0x07 },
310 { 0x9bc8, 0, 8, 0x90 },
311 { 0x9bc3, 0, 8, 0x0f },
312 { 0x9bc4, 0, 8, 0x02 },
313 { 0x9bc5, 0, 8, 0x36 },
314 { 0x9bc6, 0, 8, 0x03 },
315 { 0x9bba, 0, 8, 0xc9 },
316 { 0x9bc9, 0, 8, 0x79 },
317 { 0xd011, 0, 8, 0x10 },
318 { 0xd012, 0, 2, 0x01 },
319 { 0xd013, 0, 8, 0x45 },
320 { 0xd014, 0, 2, 0x03 },
321 { 0xd040, 0, 8, 0x98 },
322 { 0xd041, 0, 2, 0x00 },
323 { 0xd042, 0, 8, 0xcf },
324 { 0xd043, 0, 2, 0x03 },
325 { 0xd045, 1, 1, 0x00 },
326 { 0x9bcf, 0, 1, 0x01 },
327 { 0xd045, 2, 1, 0x01 },
328 { 0xd04f, 0, 8, 0x9a },
329 { 0xd050, 0, 1, 0x01 },
330 { 0xd051, 0, 8, 0x5a },
331 { 0xd052, 0, 1, 0x01 },
332 { 0xd053, 0, 8, 0x50 },
333 { 0xd054, 0, 8, 0x46 },
334 { 0x9bd7, 0, 8, 0x0a },
335 { 0x9bd8, 0, 8, 0x14 },
336 { 0x9bd9, 0, 8, 0x08 },
337 { 0x9bd0, 0, 8, 0xcc },
338 { 0x9be4, 0, 8, 0xa0 },
339 { 0x9bbd, 0, 8, 0x8e },
340 { 0x9be2, 0, 8, 0x4d },
341 { 0x9bee, 0, 1, 0x01 },
342};
343
344/* Microtune MT2060 tuner init
345 AF9013_TUNER_MT2060_2 = 147 */
346static struct regdesc tuner_init_mt2060_2[] = {
347 { 0x9bd5, 0, 8, 0x01 },
348 { 0x9bd6, 0, 8, 0x06 },
349 { 0x9bbe, 0, 8, 0x01 },
350 { 0xd1a0, 1, 1, 0x01 },
351 { 0xd000, 0, 1, 0x01 },
352 { 0xd000, 1, 1, 0x00 },
353 { 0xd001, 1, 1, 0x01 },
354 { 0xd001, 0, 1, 0x00 },
355 { 0xd001, 5, 1, 0x00 },
356 { 0xd002, 0, 5, 0x19 },
357 { 0xd003, 0, 5, 0x1a },
358 { 0xd004, 0, 5, 0x19 },
359 { 0xd005, 0, 5, 0x1a },
360 { 0xd00e, 0, 5, 0x10 },
361 { 0xd00f, 0, 3, 0x04 },
362 { 0xd00f, 3, 3, 0x05 },
363 { 0xd010, 0, 3, 0x04 },
364 { 0xd010, 3, 3, 0x05 },
365 { 0xd016, 4, 4, 0x03 },
366 { 0xd01f, 0, 6, 0x0a },
367 { 0xd020, 0, 6, 0x0a },
368 { 0xd015, 0, 8, 0x46 },
369 { 0xd016, 0, 1, 0x00 },
370 { 0xd044, 0, 8, 0x46 },
371 { 0xd045, 0, 1, 0x00 },
372 { 0xd008, 0, 8, 0x0f },
373 { 0xd009, 0, 2, 0x02 },
374 { 0xd006, 0, 8, 0x32 },
375 { 0xd007, 0, 2, 0x01 },
376 { 0xd00c, 0, 8, 0x36 },
377 { 0xd00d, 0, 2, 0x03 },
378 { 0xd00a, 0, 8, 0x35 },
379 { 0xd00b, 0, 2, 0x01 },
380 { 0x9bc7, 0, 8, 0x07 },
381 { 0x9bc8, 0, 8, 0x90 },
382 { 0x9bc3, 0, 8, 0x0f },
383 { 0x9bc4, 0, 8, 0x02 },
384 { 0x9bc5, 0, 8, 0x36 },
385 { 0x9bc6, 0, 8, 0x03 },
386 { 0x9bba, 0, 8, 0xc9 },
387 { 0x9bc9, 0, 8, 0x79 },
388 { 0xd011, 0, 8, 0x10 },
389 { 0xd012, 0, 2, 0x01 },
390 { 0xd013, 0, 8, 0x45 },
391 { 0xd014, 0, 2, 0x03 },
392 { 0xd040, 0, 8, 0x98 },
393 { 0xd041, 0, 2, 0x00 },
394 { 0xd042, 0, 8, 0xcf },
395 { 0xd043, 0, 2, 0x03 },
396 { 0xd045, 1, 1, 0x00 },
397 { 0x9bcf, 0, 8, 0x01 },
398 { 0xd045, 2, 1, 0x01 },
399 { 0xd04f, 0, 8, 0x9a },
400 { 0xd050, 0, 1, 0x01 },
401 { 0xd051, 0, 8, 0x5a },
402 { 0xd052, 0, 1, 0x01 },
403 { 0xd053, 0, 8, 0x96 },
404 { 0xd054, 0, 8, 0x46 },
405 { 0xd045, 7, 1, 0x00 },
406 { 0x9bd7, 0, 8, 0x0a },
407 { 0x9bd8, 0, 8, 0x14 },
408 { 0x9bd9, 0, 8, 0x08 },
409};
410
411/* MaxLinear MXL5003 tuner init
412 AF9013_TUNER_MXL5003D = 3 */
413static struct regdesc tuner_init_mxl5003d[] = {
414 { 0x9bd5, 0, 8, 0x01 },
415 { 0x9bd6, 0, 8, 0x09 },
416 { 0xd1a0, 1, 1, 0x01 },
417 { 0xd000, 0, 1, 0x01 },
418 { 0xd000, 1, 1, 0x00 },
419 { 0xd001, 1, 1, 0x01 },
420 { 0xd001, 0, 1, 0x00 },
421 { 0xd001, 5, 1, 0x00 },
422 { 0xd002, 0, 5, 0x19 },
423 { 0xd003, 0, 5, 0x1a },
424 { 0xd004, 0, 5, 0x19 },
425 { 0xd005, 0, 5, 0x1a },
426 { 0xd00e, 0, 5, 0x10 },
427 { 0xd00f, 0, 3, 0x04 },
428 { 0xd00f, 3, 3, 0x05 },
429 { 0xd010, 0, 3, 0x04 },
430 { 0xd010, 3, 3, 0x05 },
431 { 0xd016, 4, 4, 0x03 },
432 { 0xd01f, 0, 6, 0x0a },
433 { 0xd020, 0, 6, 0x0a },
434 { 0x9bda, 0, 8, 0x00 },
435 { 0x9be3, 0, 8, 0x00 },
436 { 0x9bfc, 0, 8, 0x0f },
437 { 0x9bf6, 0, 8, 0x01 },
438 { 0x9bbe, 0, 1, 0x01 },
439 { 0xd015, 0, 8, 0x33 },
440 { 0xd016, 0, 1, 0x00 },
441 { 0xd044, 0, 8, 0x40 },
442 { 0xd045, 0, 1, 0x00 },
443 { 0xd008, 0, 8, 0x0f },
444 { 0xd009, 0, 2, 0x02 },
445 { 0xd006, 0, 8, 0x6c },
446 { 0xd007, 0, 2, 0x00 },
447 { 0xd00c, 0, 8, 0x3d },
448 { 0xd00d, 0, 2, 0x00 },
449 { 0xd00a, 0, 8, 0x45 },
450 { 0xd00b, 0, 2, 0x01 },
451 { 0x9bc7, 0, 8, 0x07 },
452 { 0x9bc8, 0, 8, 0x52 },
453 { 0x9bc3, 0, 8, 0x0f },
454 { 0x9bc4, 0, 8, 0x02 },
455 { 0x9bc5, 0, 8, 0x3d },
456 { 0x9bc6, 0, 8, 0x00 },
457 { 0x9bba, 0, 8, 0xa2 },
458 { 0x9bc9, 0, 8, 0xa0 },
459 { 0xd011, 0, 8, 0x56 },
460 { 0xd012, 0, 2, 0x00 },
461 { 0xd013, 0, 8, 0x50 },
462 { 0xd014, 0, 2, 0x00 },
463 { 0xd040, 0, 8, 0x56 },
464 { 0xd041, 0, 2, 0x00 },
465 { 0xd042, 0, 8, 0x50 },
466 { 0xd043, 0, 2, 0x00 },
467 { 0xd045, 1, 1, 0x00 },
468 { 0x9bcf, 0, 8, 0x01 },
469 { 0xd045, 2, 1, 0x01 },
470 { 0xd04f, 0, 8, 0x9a },
471 { 0xd050, 0, 1, 0x01 },
472 { 0xd051, 0, 8, 0x5a },
473 { 0xd052, 0, 1, 0x01 },
474 { 0xd053, 0, 8, 0x50 },
475 { 0xd054, 0, 8, 0x46 },
476 { 0x9bd7, 0, 8, 0x0a },
477 { 0x9bd8, 0, 8, 0x14 },
478 { 0x9bd9, 0, 8, 0x08 },
479};
480
481/* MaxLinear MXL5005 tuner init
482 AF9013_TUNER_MXL5005D = 13
483 AF9013_TUNER_MXL5005R = 30 */
484static struct regdesc tuner_init_mxl5005[] = {
485 { 0x9bd5, 0, 8, 0x01 },
486 { 0x9bd6, 0, 8, 0x07 },
487 { 0xd1a0, 1, 1, 0x01 },
488 { 0xd000, 0, 1, 0x01 },
489 { 0xd000, 1, 1, 0x00 },
490 { 0xd001, 1, 1, 0x01 },
491 { 0xd001, 0, 1, 0x00 },
492 { 0xd001, 5, 1, 0x00 },
493 { 0xd002, 0, 5, 0x19 },
494 { 0xd003, 0, 5, 0x1a },
495 { 0xd004, 0, 5, 0x19 },
496 { 0xd005, 0, 5, 0x1a },
497 { 0xd00e, 0, 5, 0x10 },
498 { 0xd00f, 0, 3, 0x04 },
499 { 0xd00f, 3, 3, 0x05 },
500 { 0xd010, 0, 3, 0x04 },
501 { 0xd010, 3, 3, 0x05 },
502 { 0xd016, 4, 4, 0x03 },
503 { 0xd01f, 0, 6, 0x0a },
504 { 0xd020, 0, 6, 0x0a },
505 { 0x9bda, 0, 8, 0x01 },
506 { 0x9be3, 0, 8, 0x01 },
507 { 0x9bbe, 0, 1, 0x01 },
508 { 0x9bcc, 0, 1, 0x01 },
509 { 0x9bb9, 0, 8, 0x00 },
510 { 0x9bcd, 0, 8, 0x28 },
511 { 0x9bff, 0, 8, 0x24 },
512 { 0xd015, 0, 8, 0x40 },
513 { 0xd016, 0, 1, 0x00 },
514 { 0xd044, 0, 8, 0x40 },
515 { 0xd045, 0, 1, 0x00 },
516 { 0xd008, 0, 8, 0x0f },
517 { 0xd009, 0, 2, 0x02 },
518 { 0xd006, 0, 8, 0x73 },
519 { 0xd007, 0, 2, 0x01 },
520 { 0xd00c, 0, 8, 0xfa },
521 { 0xd00d, 0, 2, 0x01 },
522 { 0xd00a, 0, 8, 0xff },
523 { 0xd00b, 0, 2, 0x01 },
524 { 0x9bc7, 0, 8, 0x23 },
525 { 0x9bc8, 0, 8, 0x55 },
526 { 0x9bc3, 0, 8, 0x01 },
527 { 0x9bc4, 0, 8, 0x02 },
528 { 0x9bc5, 0, 8, 0xfa },
529 { 0x9bc6, 0, 8, 0x01 },
530 { 0x9bba, 0, 8, 0xff },
531 { 0x9bc9, 0, 8, 0xff },
532 { 0x9bd3, 0, 8, 0x95 },
533 { 0xd011, 0, 8, 0x70 },
534 { 0xd012, 0, 2, 0x01 },
535 { 0xd013, 0, 8, 0xfb },
536 { 0xd014, 0, 2, 0x01 },
537 { 0xd040, 0, 8, 0x70 },
538 { 0xd041, 0, 2, 0x01 },
539 { 0xd042, 0, 8, 0xfb },
540 { 0xd043, 0, 2, 0x01 },
541 { 0xd045, 1, 1, 0x00 },
542 { 0x9bcf, 0, 1, 0x01 },
543 { 0xd045, 2, 1, 0x01 },
544 { 0xd04f, 0, 8, 0x9a },
545 { 0xd050, 0, 1, 0x01 },
546 { 0xd051, 0, 8, 0x5a },
547 { 0xd052, 0, 1, 0x01 },
548 { 0xd053, 0, 8, 0x50 },
549 { 0xd054, 0, 8, 0x46 },
550 { 0x9bd7, 0, 8, 0x0a },
551 { 0x9bd8, 0, 8, 0x14 },
552 { 0x9bd9, 0, 8, 0x08 },
553 { 0x9bd0, 0, 8, 0x93 },
554 { 0x9be4, 0, 8, 0xfe },
555 { 0x9bbd, 0, 8, 0x63 },
556 { 0x9be2, 0, 8, 0xfe },
557 { 0x9bee, 0, 1, 0x01 },
558};
559
560/* Quantek QT1010 tuner init
561 AF9013_TUNER_QT1010 = 134
562 AF9013_TUNER_QT1010A = 162 */
563static struct regdesc tuner_init_qt1010[] = {
564 { 0x9bd5, 0, 8, 0x01 },
565 { 0x9bd6, 0, 8, 0x09 },
566 { 0xd1a0, 1, 1, 0x01 },
567 { 0xd000, 0, 1, 0x01 },
568 { 0xd000, 1, 1, 0x00 },
569 { 0xd001, 1, 1, 0x01 },
570 { 0xd001, 0, 1, 0x00 },
571 { 0xd001, 5, 1, 0x00 },
572 { 0xd002, 0, 5, 0x19 },
573 { 0xd003, 0, 5, 0x1a },
574 { 0xd004, 0, 5, 0x19 },
575 { 0xd005, 0, 5, 0x1a },
576 { 0xd00e, 0, 5, 0x10 },
577 { 0xd00f, 0, 3, 0x04 },
578 { 0xd00f, 3, 3, 0x05 },
579 { 0xd010, 0, 3, 0x04 },
580 { 0xd010, 3, 3, 0x05 },
581 { 0xd016, 4, 4, 0x03 },
582 { 0xd01f, 0, 6, 0x0a },
583 { 0xd020, 0, 6, 0x0a },
584 { 0x9bda, 0, 8, 0x01 },
585 { 0x9be3, 0, 8, 0x01 },
586 { 0xd015, 0, 8, 0x46 },
587 { 0xd016, 0, 1, 0x00 },
588 { 0xd044, 0, 8, 0x46 },
589 { 0xd045, 0, 1, 0x00 },
590 { 0x9bbe, 0, 1, 0x01 },
591 { 0x9bcc, 0, 1, 0x01 },
592 { 0x9bb9, 0, 8, 0x00 },
593 { 0x9bcd, 0, 8, 0x28 },
594 { 0x9bff, 0, 8, 0x20 },
595 { 0xd008, 0, 8, 0x0f },
596 { 0xd009, 0, 2, 0x02 },
597 { 0xd006, 0, 8, 0x99 },
598 { 0xd007, 0, 2, 0x01 },
599 { 0xd00c, 0, 8, 0x0f },
600 { 0xd00d, 0, 2, 0x02 },
601 { 0xd00a, 0, 8, 0x50 },
602 { 0xd00b, 0, 2, 0x01 },
603 { 0x9bc7, 0, 8, 0x00 },
604 { 0x9bc8, 0, 8, 0x00 },
605 { 0x9bc3, 0, 8, 0x0f },
606 { 0x9bc4, 0, 8, 0x02 },
607 { 0x9bc5, 0, 8, 0x0f },
608 { 0x9bc6, 0, 8, 0x02 },
609 { 0x9bba, 0, 8, 0xc5 },
610 { 0x9bc9, 0, 8, 0xff },
611 { 0xd011, 0, 8, 0x58 },
612 { 0xd012, 0, 2, 0x02 },
613 { 0xd013, 0, 8, 0x89 },
614 { 0xd014, 0, 2, 0x01 },
615 { 0xd040, 0, 8, 0x58 },
616 { 0xd041, 0, 2, 0x02 },
617 { 0xd042, 0, 8, 0x89 },
618 { 0xd043, 0, 2, 0x01 },
619 { 0xd045, 1, 1, 0x00 },
620 { 0x9bcf, 0, 1, 0x01 },
621 { 0xd045, 2, 1, 0x01 },
622 { 0xd04f, 0, 8, 0x9a },
623 { 0xd050, 0, 1, 0x01 },
624 { 0xd051, 0, 8, 0x5a },
625 { 0xd052, 0, 1, 0x01 },
626 { 0xd053, 0, 8, 0x50 },
627 { 0xd054, 0, 8, 0x46 },
628 { 0x9bd7, 0, 8, 0x0a },
629 { 0x9bd8, 0, 8, 0x14 },
630 { 0x9bd9, 0, 8, 0x08 },
631 { 0x9bd0, 0, 8, 0xcd },
632 { 0x9be4, 0, 8, 0xbb },
633 { 0x9bbd, 0, 8, 0x93 },
634 { 0x9be2, 0, 8, 0x80 },
635 { 0x9bee, 0, 1, 0x01 },
636};
637
638/* Freescale MC44S803 tuner init
639 AF9013_TUNER_MC44S803 = 133 */
640static struct regdesc tuner_init_mc44s803[] = {
641 { 0x9bd5, 0, 8, 0x01 },
642 { 0x9bd6, 0, 8, 0x06 },
643 { 0xd1a0, 1, 1, 0x01 },
644 { 0xd000, 0, 1, 0x01 },
645 { 0xd000, 1, 1, 0x00 },
646 { 0xd001, 1, 1, 0x01 },
647 { 0xd001, 0, 1, 0x00 },
648 { 0xd001, 5, 1, 0x00 },
649 { 0xd002, 0, 5, 0x19 },
650 { 0xd003, 0, 5, 0x1a },
651 { 0xd004, 0, 5, 0x19 },
652 { 0xd005, 0, 5, 0x1a },
653 { 0xd00e, 0, 5, 0x10 },
654 { 0xd00f, 0, 3, 0x04 },
655 { 0xd00f, 3, 3, 0x05 },
656 { 0xd010, 0, 3, 0x04 },
657 { 0xd010, 3, 3, 0x05 },
658 { 0xd016, 4, 4, 0x03 },
659 { 0xd01f, 0, 6, 0x0a },
660 { 0xd020, 0, 6, 0x0a },
661 { 0x9bda, 0, 8, 0x00 },
662 { 0x9be3, 0, 8, 0x00 },
663 { 0x9bf6, 0, 8, 0x01 },
664 { 0x9bf8, 0, 8, 0x02 },
665 { 0x9bf9, 0, 8, 0x02 },
666 { 0x9bfc, 0, 8, 0x1f },
667 { 0x9bbe, 0, 1, 0x01 },
668 { 0x9bcc, 0, 1, 0x01 },
669 { 0x9bb9, 0, 8, 0x00 },
670 { 0x9bcd, 0, 8, 0x24 },
671 { 0x9bff, 0, 8, 0x24 },
672 { 0xd015, 0, 8, 0x46 },
673 { 0xd016, 0, 1, 0x00 },
674 { 0xd044, 0, 8, 0x46 },
675 { 0xd045, 0, 1, 0x00 },
676 { 0xd008, 0, 8, 0x01 },
677 { 0xd009, 0, 2, 0x02 },
678 { 0xd006, 0, 8, 0x7b },
679 { 0xd007, 0, 2, 0x00 },
680 { 0xd00c, 0, 8, 0x7c },
681 { 0xd00d, 0, 2, 0x02 },
682 { 0xd00a, 0, 8, 0xfe },
683 { 0xd00b, 0, 2, 0x01 },
684 { 0x9bc7, 0, 8, 0x08 },
685 { 0x9bc8, 0, 8, 0x9a },
686 { 0x9bc3, 0, 8, 0x01 },
687 { 0x9bc4, 0, 8, 0x02 },
688 { 0x9bc5, 0, 8, 0x7c },
689 { 0x9bc6, 0, 8, 0x02 },
690 { 0x9bba, 0, 8, 0xfc },
691 { 0x9bc9, 0, 8, 0xaa },
692 { 0xd011, 0, 8, 0x6b },
693 { 0xd012, 0, 2, 0x00 },
694 { 0xd013, 0, 8, 0x88 },
695 { 0xd014, 0, 2, 0x02 },
696 { 0xd040, 0, 8, 0x6b },
697 { 0xd041, 0, 2, 0x00 },
698 { 0xd042, 0, 8, 0x7c },
699 { 0xd043, 0, 2, 0x02 },
700 { 0xd045, 1, 1, 0x00 },
701 { 0x9bcf, 0, 1, 0x01 },
702 { 0xd045, 2, 1, 0x01 },
703 { 0xd04f, 0, 8, 0x9a },
704 { 0xd050, 0, 1, 0x01 },
705 { 0xd051, 0, 8, 0x5a },
706 { 0xd052, 0, 1, 0x01 },
707 { 0xd053, 0, 8, 0x50 },
708 { 0xd054, 0, 8, 0x46 },
709 { 0x9bd7, 0, 8, 0x0a },
710 { 0x9bd8, 0, 8, 0x14 },
711 { 0x9bd9, 0, 8, 0x08 },
712 { 0x9bd0, 0, 8, 0x9e },
713 { 0x9be4, 0, 8, 0xff },
714 { 0x9bbd, 0, 8, 0x9e },
715 { 0x9be2, 0, 8, 0x25 },
716 { 0x9bee, 0, 1, 0x01 },
717 { 0xd73b, 3, 1, 0x00 },
718};
719
720/* unknown, probably for tin can tuner, tuner init
721 AF9013_TUNER_UNKNOWN = 140 */
722static struct regdesc tuner_init_unknown[] = {
723 { 0x9bd5, 0, 8, 0x01 },
724 { 0x9bd6, 0, 8, 0x02 },
725 { 0xd1a0, 1, 1, 0x01 },
726 { 0xd000, 0, 1, 0x01 },
727 { 0xd000, 1, 1, 0x00 },
728 { 0xd001, 1, 1, 0x01 },
729 { 0xd001, 0, 1, 0x00 },
730 { 0xd001, 5, 1, 0x00 },
731 { 0xd002, 0, 5, 0x19 },
732 { 0xd003, 0, 5, 0x1a },
733 { 0xd004, 0, 5, 0x19 },
734 { 0xd005, 0, 5, 0x1a },
735 { 0xd00e, 0, 5, 0x10 },
736 { 0xd00f, 0, 3, 0x04 },
737 { 0xd00f, 3, 3, 0x05 },
738 { 0xd010, 0, 3, 0x04 },
739 { 0xd010, 3, 3, 0x05 },
740 { 0xd016, 4, 4, 0x03 },
741 { 0xd01f, 0, 6, 0x0a },
742 { 0xd020, 0, 6, 0x0a },
743 { 0x9bda, 0, 8, 0x01 },
744 { 0x9be3, 0, 8, 0x01 },
745 { 0xd1a0, 1, 1, 0x00 },
746 { 0x9bbe, 0, 1, 0x01 },
747 { 0x9bcc, 0, 1, 0x01 },
748 { 0x9bb9, 0, 8, 0x00 },
749 { 0x9bcd, 0, 8, 0x18 },
750 { 0x9bff, 0, 8, 0x2c },
751 { 0xd015, 0, 8, 0x46 },
752 { 0xd016, 0, 1, 0x00 },
753 { 0xd044, 0, 8, 0x46 },
754 { 0xd045, 0, 1, 0x00 },
755 { 0xd008, 0, 8, 0xdf },
756 { 0xd009, 0, 2, 0x02 },
757 { 0xd006, 0, 8, 0x44 },
758 { 0xd007, 0, 2, 0x01 },
759 { 0xd00c, 0, 8, 0x00 },
760 { 0xd00d, 0, 2, 0x02 },
761 { 0xd00a, 0, 8, 0xf6 },
762 { 0xd00b, 0, 2, 0x01 },
763 { 0x9bba, 0, 8, 0xf9 },
764 { 0x9bc8, 0, 8, 0xaa },
765 { 0x9bc3, 0, 8, 0xdf },
766 { 0x9bc4, 0, 8, 0x02 },
767 { 0x9bc5, 0, 8, 0x00 },
768 { 0x9bc6, 0, 8, 0x02 },
769 { 0x9bc9, 0, 8, 0xf0 },
770 { 0xd011, 0, 8, 0x3c },
771 { 0xd012, 0, 2, 0x01 },
772 { 0xd013, 0, 8, 0xf7 },
773 { 0xd014, 0, 2, 0x02 },
774 { 0xd040, 0, 8, 0x0b },
775 { 0xd041, 0, 2, 0x02 },
776 { 0xd042, 0, 8, 0x4d },
777 { 0xd043, 0, 2, 0x00 },
778 { 0xd045, 1, 1, 0x00 },
779 { 0x9bcf, 0, 1, 0x01 },
780 { 0xd045, 2, 1, 0x01 },
781 { 0xd04f, 0, 8, 0x9a },
782 { 0xd050, 0, 1, 0x01 },
783 { 0xd051, 0, 8, 0x5a },
784 { 0xd052, 0, 1, 0x01 },
785 { 0xd053, 0, 8, 0x50 },
786 { 0xd054, 0, 8, 0x46 },
787 { 0x9bd7, 0, 8, 0x0a },
788 { 0x9bd8, 0, 8, 0x14 },
789 { 0x9bd9, 0, 8, 0x08 },
790};
791
792/* NXP TDA18271 tuner init
793 AF9013_TUNER_TDA18271 = 156 */
794static struct regdesc tuner_init_tda18271[] = {
795 { 0x9bd5, 0, 8, 0x01 },
796 { 0x9bd6, 0, 8, 0x04 },
797 { 0xd1a0, 1, 1, 0x01 },
798 { 0xd000, 0, 1, 0x01 },
799 { 0xd000, 1, 1, 0x00 },
800 { 0xd001, 1, 1, 0x01 },
801 { 0xd001, 0, 1, 0x00 },
802 { 0xd001, 5, 1, 0x00 },
803 { 0xd002, 0, 5, 0x19 },
804 { 0xd003, 0, 5, 0x1a },
805 { 0xd004, 0, 5, 0x19 },
806 { 0xd005, 0, 5, 0x1a },
807 { 0xd00e, 0, 5, 0x10 },
808 { 0xd00f, 0, 3, 0x04 },
809 { 0xd00f, 3, 3, 0x05 },
810 { 0xd010, 0, 3, 0x04 },
811 { 0xd010, 3, 3, 0x05 },
812 { 0xd016, 4, 4, 0x03 },
813 { 0xd01f, 0, 6, 0x0a },
814 { 0xd020, 0, 6, 0x0a },
815 { 0x9bda, 0, 8, 0x01 },
816 { 0x9be3, 0, 8, 0x01 },
817 { 0xd1a0, 1, 1, 0x00 },
818 { 0x9bbe, 0, 1, 0x01 },
819 { 0x9bcc, 0, 1, 0x01 },
820 { 0x9bb9, 0, 8, 0x00 },
821 { 0x9bcd, 0, 8, 0x18 },
822 { 0x9bff, 0, 8, 0x2c },
823 { 0xd015, 0, 8, 0x46 },
824 { 0xd016, 0, 1, 0x00 },
825 { 0xd044, 0, 8, 0x46 },
826 { 0xd045, 0, 1, 0x00 },
827 { 0xd008, 0, 8, 0xdf },
828 { 0xd009, 0, 2, 0x02 },
829 { 0xd006, 0, 8, 0x44 },
830 { 0xd007, 0, 2, 0x01 },
831 { 0xd00c, 0, 8, 0x00 },
832 { 0xd00d, 0, 2, 0x02 },
833 { 0xd00a, 0, 8, 0xf6 },
834 { 0xd00b, 0, 2, 0x01 },
835 { 0x9bba, 0, 8, 0xf9 },
836 { 0x9bc8, 0, 8, 0xaa },
837 { 0x9bc3, 0, 8, 0xdf },
838 { 0x9bc4, 0, 8, 0x02 },
839 { 0x9bc5, 0, 8, 0x00 },
840 { 0x9bc6, 0, 8, 0x02 },
841 { 0x9bc9, 0, 8, 0xf0 },
842 { 0xd011, 0, 8, 0x3c },
843 { 0xd012, 0, 2, 0x01 },
844 { 0xd013, 0, 8, 0xf7 },
845 { 0xd014, 0, 2, 0x02 },
846 { 0xd040, 0, 8, 0x0b },
847 { 0xd041, 0, 2, 0x02 },
848 { 0xd042, 0, 8, 0x4d },
849 { 0xd043, 0, 2, 0x00 },
850 { 0xd045, 1, 1, 0x00 },
851 { 0x9bcf, 0, 1, 0x01 },
852 { 0xd045, 2, 1, 0x01 },
853 { 0xd04f, 0, 8, 0x9a },
854 { 0xd050, 0, 1, 0x01 },
855 { 0xd051, 0, 8, 0x5a },
856 { 0xd052, 0, 1, 0x01 },
857 { 0xd053, 0, 8, 0x50 },
858 { 0xd054, 0, 8, 0x46 },
859 { 0x9bd7, 0, 8, 0x0a },
860 { 0x9bd8, 0, 8, 0x14 },
861 { 0x9bd9, 0, 8, 0x08 },
862 { 0x9bd0, 0, 8, 0xa8 },
863 { 0x9be4, 0, 8, 0x7f },
864 { 0x9bbd, 0, 8, 0xa8 },
865 { 0x9be2, 0, 8, 0x20 },
866 { 0x9bee, 0, 1, 0x01 },
867};
868
869#endif /* _AF9013_PRIV_ */
diff --git a/drivers/media/dvb/frontends/au8522.c b/drivers/media/dvb/frontends/au8522.c
index 0b82cc2a1e16..eabf9a68e7ec 100644
--- a/drivers/media/dvb/frontends/au8522.c
+++ b/drivers/media/dvb/frontends/au8522.c
@@ -40,6 +40,8 @@ struct au8522_state {
40 u32 current_frequency; 40 u32 current_frequency;
41 fe_modulation_t current_modulation; 41 fe_modulation_t current_modulation;
42 42
43 u32 fe_status;
44 unsigned int led_state;
43}; 45};
44 46
45static int debug; 47static int debug;
@@ -538,11 +540,98 @@ static int au8522_init(struct dvb_frontend *fe)
538 return 0; 540 return 0;
539} 541}
540 542
543static int au8522_led_gpio_enable(struct au8522_state *state, int onoff)
544{
545 struct au8522_led_config *led_config = state->config->led_cfg;
546 u8 val;
547
548 /* bail out if we cant control an LED */
549 if (!led_config || !led_config->gpio_output ||
550 !led_config->gpio_output_enable || !led_config->gpio_output_disable)
551 return 0;
552
553 val = au8522_readreg(state, 0x4000 |
554 (led_config->gpio_output & ~0xc000));
555 if (onoff) {
556 /* enable GPIO output */
557 val &= ~((led_config->gpio_output_enable >> 8) & 0xff);
558 val |= (led_config->gpio_output_enable & 0xff);
559 } else {
560 /* disable GPIO output */
561 val &= ~((led_config->gpio_output_disable >> 8) & 0xff);
562 val |= (led_config->gpio_output_disable & 0xff);
563 }
564 return au8522_writereg(state, 0x8000 |
565 (led_config->gpio_output & ~0xc000), val);
566}
567
568/* led = 0 | off
569 * led = 1 | signal ok
570 * led = 2 | signal strong
571 * led < 0 | only light led if leds are currently off
572 */
573static int au8522_led_ctrl(struct au8522_state *state, int led)
574{
575 struct au8522_led_config *led_config = state->config->led_cfg;
576 int i, ret = 0;
577
578 /* bail out if we cant control an LED */
579 if (!led_config || !led_config->gpio_leds ||
580 !led_config->num_led_states || !led_config->led_states)
581 return 0;
582
583 if (led < 0) {
584 /* if LED is already lit, then leave it as-is */
585 if (state->led_state)
586 return 0;
587 else
588 led *= -1;
589 }
590
591 /* toggle LED if changing state */
592 if (state->led_state != led) {
593 u8 val;
594
595 dprintk("%s: %d\n", __func__, led);
596
597 au8522_led_gpio_enable(state, 1);
598
599 val = au8522_readreg(state, 0x4000 |
600 (led_config->gpio_leds & ~0xc000));
601
602 /* start with all leds off */
603 for (i = 0; i < led_config->num_led_states; i++)
604 val &= ~led_config->led_states[i];
605
606 /* set selected LED state */
607 if (led < led_config->num_led_states)
608 val |= led_config->led_states[led];
609 else if (led_config->num_led_states)
610 val |=
611 led_config->led_states[led_config->num_led_states - 1];
612
613 ret = au8522_writereg(state, 0x8000 |
614 (led_config->gpio_leds & ~0xc000), val);
615 if (ret < 0)
616 return ret;
617
618 state->led_state = led;
619
620 if (led == 0)
621 au8522_led_gpio_enable(state, 0);
622 }
623
624 return 0;
625}
626
541static int au8522_sleep(struct dvb_frontend *fe) 627static int au8522_sleep(struct dvb_frontend *fe)
542{ 628{
543 struct au8522_state *state = fe->demodulator_priv; 629 struct au8522_state *state = fe->demodulator_priv;
544 dprintk("%s()\n", __func__); 630 dprintk("%s()\n", __func__);
545 631
632 /* turn off led */
633 au8522_led_ctrl(state, 0);
634
546 state->current_frequency = 0; 635 state->current_frequency = 0;
547 636
548 return 0; 637 return 0;
@@ -592,12 +681,53 @@ static int au8522_read_status(struct dvb_frontend *fe, fe_status_t *status)
592 *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL; 681 *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL;
593 break; 682 break;
594 } 683 }
684 state->fe_status = *status;
685
686 if (*status & FE_HAS_LOCK)
687 /* turn on LED, if it isn't on already */
688 au8522_led_ctrl(state, -1);
689 else
690 /* turn off LED */
691 au8522_led_ctrl(state, 0);
595 692
596 dprintk("%s() status 0x%08x\n", __func__, *status); 693 dprintk("%s() status 0x%08x\n", __func__, *status);
597 694
598 return 0; 695 return 0;
599} 696}
600 697
698static int au8522_led_status(struct au8522_state *state, const u16 *snr)
699{
700 struct au8522_led_config *led_config = state->config->led_cfg;
701 int led;
702 u16 strong;
703
704 /* bail out if we cant control an LED */
705 if (!led_config)
706 return 0;
707
708 if (0 == (state->fe_status & FE_HAS_LOCK))
709 return au8522_led_ctrl(state, 0);
710 else if (state->current_modulation == QAM_256)
711 strong = led_config->qam256_strong;
712 else if (state->current_modulation == QAM_64)
713 strong = led_config->qam64_strong;
714 else /* (state->current_modulation == VSB_8) */
715 strong = led_config->vsb8_strong;
716
717 if (*snr >= strong)
718 led = 2;
719 else
720 led = 1;
721
722 if ((state->led_state) &&
723 (((strong < *snr) ? (*snr - strong) : (strong - *snr)) <= 10))
724 /* snr didn't change enough to bother
725 * changing the color of the led */
726 return 0;
727
728 return au8522_led_ctrl(state, led);
729}
730
601static int au8522_read_snr(struct dvb_frontend *fe, u16 *snr) 731static int au8522_read_snr(struct dvb_frontend *fe, u16 *snr)
602{ 732{
603 struct au8522_state *state = fe->demodulator_priv; 733 struct au8522_state *state = fe->demodulator_priv;
@@ -621,6 +751,9 @@ static int au8522_read_snr(struct dvb_frontend *fe, u16 *snr)
621 au8522_readreg(state, 0x4311), 751 au8522_readreg(state, 0x4311),
622 snr); 752 snr);
623 753
754 if (state->config->led_cfg)
755 au8522_led_status(state, snr);
756
624 return ret; 757 return ret;
625} 758}
626 759
diff --git a/drivers/media/dvb/frontends/au8522.h b/drivers/media/dvb/frontends/au8522.h
index 595915ade8c3..7b94f554a093 100644
--- a/drivers/media/dvb/frontends/au8522.h
+++ b/drivers/media/dvb/frontends/au8522.h
@@ -30,6 +30,21 @@ enum au8522_if_freq {
30 AU8522_IF_3_25MHZ, 30 AU8522_IF_3_25MHZ,
31}; 31};
32 32
33struct au8522_led_config {
34 u16 vsb8_strong;
35 u16 qam64_strong;
36 u16 qam256_strong;
37
38 u16 gpio_output;
39 /* unset hi bits, set low bits */
40 u16 gpio_output_enable;
41 u16 gpio_output_disable;
42
43 u16 gpio_leds;
44 u8 *led_states;
45 unsigned int num_led_states;
46};
47
33struct au8522_config { 48struct au8522_config {
34 /* the demodulator's i2c address */ 49 /* the demodulator's i2c address */
35 u8 demod_address; 50 u8 demod_address;
@@ -39,6 +54,8 @@ struct au8522_config {
39#define AU8522_DEMODLOCKING 1 54#define AU8522_DEMODLOCKING 1
40 u8 status_mode; 55 u8 status_mode;
41 56
57 struct au8522_led_config *led_cfg;
58
42 enum au8522_if_freq vsb_if; 59 enum au8522_if_freq vsb_if;
43 enum au8522_if_freq qam_if; 60 enum au8522_if_freq qam_if;
44}; 61};
diff --git a/drivers/media/dvb/frontends/cx24110.h b/drivers/media/dvb/frontends/cx24110.h
index 1792adb23c4d..fdcceee91f3a 100644
--- a/drivers/media/dvb/frontends/cx24110.h
+++ b/drivers/media/dvb/frontends/cx24110.h
@@ -33,12 +33,17 @@ struct cx24110_config
33 u8 demod_address; 33 u8 demod_address;
34}; 34};
35 35
36static inline int cx24110_pll_write(struct dvb_frontend *fe, u32 val) { 36static inline int cx24110_pll_write(struct dvb_frontend *fe, u32 val)
37 int r = 0; 37{
38 u8 buf[] = {(u8) (val>>24), (u8) (val>>16), (u8) (val>>8)}; 38 u8 buf[] = {
39 (u8)((val >> 24) & 0xff),
40 (u8)((val >> 16) & 0xff),
41 (u8)((val >> 8) & 0xff)
42 };
43
39 if (fe->ops.write) 44 if (fe->ops.write)
40 r = fe->ops.write(fe, buf, 3); 45 return fe->ops.write(fe, buf, 3);
41 return r; 46 return 0;
42} 47}
43 48
44#if defined(CONFIG_DVB_CX24110) || (defined(CONFIG_DVB_CX24110_MODULE) && defined(MODULE)) 49#if defined(CONFIG_DVB_CX24110) || (defined(CONFIG_DVB_CX24110_MODULE) && defined(MODULE))
diff --git a/drivers/media/dvb/frontends/cx24116.c b/drivers/media/dvb/frontends/cx24116.c
new file mode 100644
index 000000000000..deb36f469ada
--- /dev/null
+++ b/drivers/media/dvb/frontends/cx24116.c
@@ -0,0 +1,1423 @@
1/*
2 Conexant cx24116/cx24118 - DVBS/S2 Satellite demod/tuner driver
3
4 Copyright (C) 2006-2008 Steven Toth <stoth@hauppauge.com>
5 Copyright (C) 2006-2007 Georg Acher
6 Copyright (C) 2007-2008 Darron Broad
7 March 2007
8 Fixed some bugs.
9 Added diseqc support.
10 Added corrected signal strength support.
11 August 2007
12 Sync with legacy version.
13 Some clean ups.
14 Copyright (C) 2008 Igor Liplianin
15 September, 9th 2008
16 Fixed locking on high symbol rates (>30000).
17 Implement MPEG initialization parameter.
18
19 This program is free software; you can redistribute it and/or modify
20 it under the terms of the GNU General Public License as published by
21 the Free Software Foundation; either version 2 of the License, or
22 (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 General Public License
30 along with this program; if not, write to the Free Software
31 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
32*/
33
34#include <linux/slab.h>
35#include <linux/kernel.h>
36#include <linux/module.h>
37#include <linux/moduleparam.h>
38#include <linux/init.h>
39#include <linux/firmware.h>
40
41#include "dvb_frontend.h"
42#include "cx24116.h"
43
44static int debug = 0;
45#define dprintk(args...) \
46 do { \
47 if (debug) printk ("cx24116: " args); \
48 } while (0)
49
50#define CX24116_DEFAULT_FIRMWARE "dvb-fe-cx24116.fw"
51#define CX24116_SEARCH_RANGE_KHZ 5000
52
53/* known registers */
54#define CX24116_REG_COMMAND (0x00) /* command args 0x00..0x1e */
55#define CX24116_REG_EXECUTE (0x1f) /* execute command */
56#define CX24116_REG_MAILBOX (0x96) /* FW or multipurpose mailbox? */
57#define CX24116_REG_RESET (0x20) /* reset status > 0 */
58#define CX24116_REG_SIGNAL (0x9e) /* signal low */
59#define CX24116_REG_SSTATUS (0x9d) /* signal high / status */
60#define CX24116_REG_QUALITY8 (0xa3)
61#define CX24116_REG_QSTATUS (0xbc)
62#define CX24116_REG_QUALITY0 (0xd5)
63#define CX24116_REG_BER0 (0xc9)
64#define CX24116_REG_BER8 (0xc8)
65#define CX24116_REG_BER16 (0xc7)
66#define CX24116_REG_BER24 (0xc6)
67#define CX24116_REG_UCB0 (0xcb)
68#define CX24116_REG_UCB8 (0xca)
69#define CX24116_REG_CLKDIV (0xf3)
70#define CX24116_REG_RATEDIV (0xf9)
71#define CX24116_REG_FECSTATUS (0x9c) /* configured fec (not tuned) or actual FEC (tuned) 1=1/2 2=2/3 etc */
72
73/* FECSTATUS bits */
74#define CX24116_FEC_FECMASK (0x1f) /* mask to determine configured fec (not tuned) or actual fec (tuned) */
75#define CX24116_FEC_DVBS (0x20) /* Select DVB-S demodulator, else DVB-S2 */
76#define CX24116_FEC_UNKNOWN (0x40) /* Unknown/unused */
77#define CX24116_FEC_PILOT (0x80) /* Pilot mode requested when tuning else always reset when tuned */
78
79/* arg buffer size */
80#define CX24116_ARGLEN (0x1e)
81
82/* rolloff */
83#define CX24116_ROLLOFF_020 (0x00)
84#define CX24116_ROLLOFF_025 (0x01)
85#define CX24116_ROLLOFF_035 (0x02)
86
87/* pilot bit */
88#define CX24116_PILOT_OFF (0x00)
89#define CX24116_PILOT_ON (0x40)
90
91/* signal status */
92#define CX24116_HAS_SIGNAL (0x01)
93#define CX24116_HAS_CARRIER (0x02)
94#define CX24116_HAS_VITERBI (0x04)
95#define CX24116_HAS_SYNCLOCK (0x08)
96#define CX24116_HAS_UNKNOWN1 (0x10)
97#define CX24116_HAS_UNKNOWN2 (0x20)
98#define CX24116_STATUS_MASK (0x3f)
99#define CX24116_SIGNAL_MASK (0xc0)
100
101#define CX24116_DISEQC_TONEOFF (0) /* toneburst never sent */
102#define CX24116_DISEQC_TONECACHE (1) /* toneburst cached */
103#define CX24116_DISEQC_MESGCACHE (2) /* message cached */
104
105/* arg offset for DiSEqC */
106#define CX24116_DISEQC_BURST (1)
107#define CX24116_DISEQC_ARG2_2 (2) /* unknown value=2 */
108#define CX24116_DISEQC_ARG3_0 (3) /* unknown value=0 */
109#define CX24116_DISEQC_ARG4_0 (4) /* unknown value=0 */
110#define CX24116_DISEQC_MSGLEN (5)
111#define CX24116_DISEQC_MSGOFS (6)
112
113/* DiSEqC burst */
114#define CX24116_DISEQC_MINI_A (0)
115#define CX24116_DISEQC_MINI_B (1)
116
117/* DiSEqC tone burst */
118static int toneburst = 1;
119
120/* SNR measurements */
121static int esno_snr = 0;
122
123enum cmds
124{
125 CMD_SET_VCO = 0x10,
126 CMD_TUNEREQUEST = 0x11,
127 CMD_MPEGCONFIG = 0x13,
128 CMD_TUNERINIT = 0x14,
129 CMD_BANDWIDTH = 0x15,
130 CMD_GETAGC = 0x19,
131 CMD_LNBCONFIG = 0x20,
132 CMD_LNBSEND = 0x21, /* Formerly CMD_SEND_DISEQC */
133 CMD_SET_TONEPRE = 0x22,
134 CMD_SET_TONE = 0x23,
135 CMD_UPDFWVERS = 0x35,
136 CMD_TUNERSLEEP = 0x36,
137 CMD_AGCCONTROL = 0x3b, /* Unknown */
138};
139
140/* The Demod/Tuner can't easily provide these, we cache them */
141struct cx24116_tuning
142{
143 u32 frequency;
144 u32 symbol_rate;
145 fe_spectral_inversion_t inversion;
146 fe_code_rate_t fec;
147
148 fe_modulation_t modulation;
149 fe_pilot_t pilot;
150 fe_rolloff_t rolloff;
151
152 /* Demod values */
153 u8 fec_val;
154 u8 fec_mask;
155 u8 inversion_val;
156 u8 pilot_val;
157 u8 rolloff_val;
158};
159
160/* Basic commands that are sent to the firmware */
161struct cx24116_cmd
162{
163 u8 len;
164 u8 args[CX24116_ARGLEN];
165};
166
167struct cx24116_state
168{
169 struct i2c_adapter* i2c;
170 const struct cx24116_config* config;
171
172 struct dvb_frontend frontend;
173
174 struct cx24116_tuning dcur;
175 struct cx24116_tuning dnxt;
176
177 u8 skip_fw_load;
178 u8 burst;
179 struct cx24116_cmd dsec_cmd;
180};
181
182static int cx24116_writereg(struct cx24116_state* state, int reg, int data)
183{
184 u8 buf[] = { reg, data };
185 struct i2c_msg msg = { .addr = state->config->demod_address,
186 .flags = 0, .buf = buf, .len = 2 };
187 int err;
188
189 if (debug>1)
190 printk("cx24116: %s: write reg 0x%02x, value 0x%02x\n",
191 __func__,reg, data);
192
193 if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {
194 printk("%s: writereg error(err == %i, reg == 0x%02x,"
195 " value == 0x%02x)\n", __func__, err, reg, data);
196 return -EREMOTEIO;
197 }
198
199 return 0;
200}
201
202/* Bulk byte writes to a single I2C address, for 32k firmware load */
203static int cx24116_writeregN(struct cx24116_state* state, int reg, u8 *data, u16 len)
204{
205 int ret = -EREMOTEIO;
206 struct i2c_msg msg;
207 u8 *buf;
208
209 buf = kmalloc(len + 1, GFP_KERNEL);
210 if (buf == NULL) {
211 printk("Unable to kmalloc\n");
212 ret = -ENOMEM;
213 goto error;
214 }
215
216 *(buf) = reg;
217 memcpy(buf + 1, data, len);
218
219 msg.addr = state->config->demod_address;
220 msg.flags = 0;
221 msg.buf = buf;
222 msg.len = len + 1;
223
224 if (debug>1)
225 printk("cx24116: %s: write regN 0x%02x, len = %d\n",
226 __func__,reg, len);
227
228 if ((ret = i2c_transfer(state->i2c, &msg, 1)) != 1) {
229 printk("%s: writereg error(err == %i, reg == 0x%02x\n",
230 __func__, ret, reg);
231 ret = -EREMOTEIO;
232 }
233
234error:
235 kfree(buf);
236
237 return ret;
238}
239
240static int cx24116_readreg(struct cx24116_state* state, u8 reg)
241{
242 int ret;
243 u8 b0[] = { reg };
244 u8 b1[] = { 0 };
245 struct i2c_msg msg[] = {
246 { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 },
247 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 }
248 };
249
250 ret = i2c_transfer(state->i2c, msg, 2);
251
252 if (ret != 2) {
253 printk("%s: reg=0x%x (error=%d)\n", __func__, reg, ret);
254 return ret;
255 }
256
257 if (debug>1)
258 printk("cx24116: read reg 0x%02x, value 0x%02x\n",reg, b1[0]);
259
260 return b1[0];
261}
262
263static int cx24116_set_inversion(struct cx24116_state* state, fe_spectral_inversion_t inversion)
264{
265 dprintk("%s(%d)\n", __func__, inversion);
266
267 switch (inversion) {
268 case INVERSION_OFF:
269 state->dnxt.inversion_val = 0x00;
270 break;
271 case INVERSION_ON:
272 state->dnxt.inversion_val = 0x04;
273 break;
274 case INVERSION_AUTO:
275 state->dnxt.inversion_val = 0x0C;
276 break;
277 default:
278 return -EINVAL;
279 }
280
281 state->dnxt.inversion = inversion;
282
283 return 0;
284}
285
286/*
287 * modfec (modulation and FEC)
288 * ===========================
289 *
290 * MOD FEC mask/val standard
291 * ---- -------- ----------- --------
292 * QPSK FEC_1_2 0x02 0x02+X DVB-S
293 * QPSK FEC_2_3 0x04 0x02+X DVB-S
294 * QPSK FEC_3_4 0x08 0x02+X DVB-S
295 * QPSK FEC_4_5 0x10 0x02+X DVB-S (?)
296 * QPSK FEC_5_6 0x20 0x02+X DVB-S
297 * QPSK FEC_6_7 0x40 0x02+X DVB-S
298 * QPSK FEC_7_8 0x80 0x02+X DVB-S
299 * QPSK FEC_8_9 0x01 0x02+X DVB-S (?) (NOT SUPPORTED?)
300 * QPSK AUTO 0xff 0x02+X DVB-S
301 *
302 * For DVB-S high byte probably represents FEC
303 * and low byte selects the modulator. The high
304 * byte is search range mask. Bit 5 may turn
305 * on DVB-S and remaining bits represent some
306 * kind of calibration (how/what i do not know).
307 *
308 * Eg.(2/3) szap "Zone Horror"
309 *
310 * mask/val = 0x04, 0x20
311 * status 1f | signal c3c0 | snr a333 | ber 00000098 | unc 00000000 | FE_HAS_LOCK
312 *
313 * mask/val = 0x04, 0x30
314 * status 1f | signal c3c0 | snr a333 | ber 00000000 | unc 00000000 | FE_HAS_LOCK
315 *
316 * After tuning FECSTATUS contains actual FEC
317 * in use numbered 1 through to 8 for 1/2 .. 2/3 etc
318 *
319 * NBC=NOT/NON BACKWARD COMPATIBLE WITH DVB-S (DVB-S2 only)
320 *
321 * NBC-QPSK FEC_1_2 0x00, 0x04 DVB-S2
322 * NBC-QPSK FEC_3_5 0x00, 0x05 DVB-S2
323 * NBC-QPSK FEC_2_3 0x00, 0x06 DVB-S2
324 * NBC-QPSK FEC_3_4 0x00, 0x07 DVB-S2
325 * NBC-QPSK FEC_4_5 0x00, 0x08 DVB-S2
326 * NBC-QPSK FEC_5_6 0x00, 0x09 DVB-S2
327 * NBC-QPSK FEC_8_9 0x00, 0x0a DVB-S2
328 * NBC-QPSK FEC_9_10 0x00, 0x0b DVB-S2
329 *
330 * NBC-8PSK FEC_3_5 0x00, 0x0c DVB-S2
331 * NBC-8PSK FEC_2_3 0x00, 0x0d DVB-S2
332 * NBC-8PSK FEC_3_4 0x00, 0x0e DVB-S2
333 * NBC-8PSK FEC_5_6 0x00, 0x0f DVB-S2
334 * NBC-8PSK FEC_8_9 0x00, 0x10 DVB-S2
335 * NBC-8PSK FEC_9_10 0x00, 0x11 DVB-S2
336 *
337 * For DVB-S2 low bytes selects both modulator
338 * and FEC. High byte is meaningless here. To
339 * set pilot, bit 6 (0x40) is set. When inspecting
340 * FECSTATUS bit 7 (0x80) represents the pilot
341 * selection whilst not tuned. When tuned, actual FEC
342 * in use is found in FECSTATUS as per above. Pilot
343 * value is reset.
344 */
345
346/* A table of modulation, fec and configuration bytes for the demod.
347 * Not all S2 mmodulation schemes are support and not all rates with
348 * a scheme are support. Especially, no auto detect when in S2 mode.
349 */
350struct cx24116_modfec {
351 fe_delivery_system_t delivery_system;
352 fe_modulation_t modulation;
353 fe_code_rate_t fec;
354 u8 mask; /* In DVBS mode this is used to autodetect */
355 u8 val; /* Passed to the firmware to indicate mode selection */
356} CX24116_MODFEC_MODES[] = {
357 /* QPSK. For unknown rates we set hardware to auto detect 0xfe 0x30 */
358
359 /*mod fec mask val */
360 { SYS_DVBS, QPSK, FEC_NONE, 0xfe, 0x30 },
361 { SYS_DVBS, QPSK, FEC_1_2, 0x02, 0x2e }, /* 00000010 00101110 */
362 { SYS_DVBS, QPSK, FEC_2_3, 0x04, 0x2f }, /* 00000100 00101111 */
363 { SYS_DVBS, QPSK, FEC_3_4, 0x08, 0x30 }, /* 00001000 00110000 */
364 { SYS_DVBS, QPSK, FEC_4_5, 0xfe, 0x30 }, /* 000?0000 ? */
365 { SYS_DVBS, QPSK, FEC_5_6, 0x20, 0x31 }, /* 00100000 00110001 */
366 { SYS_DVBS, QPSK, FEC_6_7, 0xfe, 0x30 }, /* 0?000000 ? */
367 { SYS_DVBS, QPSK, FEC_7_8, 0x80, 0x32 }, /* 10000000 00110010 */
368 { SYS_DVBS, QPSK, FEC_8_9, 0xfe, 0x30 }, /* 0000000? ? */
369 { SYS_DVBS, QPSK, FEC_AUTO, 0xfe, 0x30 },
370 /* NBC-QPSK */
371 { SYS_DVBS2, QPSK, FEC_1_2, 0x00, 0x04 },
372 { SYS_DVBS2, QPSK, FEC_3_5, 0x00, 0x05 },
373 { SYS_DVBS2, QPSK, FEC_2_3, 0x00, 0x06 },
374 { SYS_DVBS2, QPSK, FEC_3_4, 0x00, 0x07 },
375 { SYS_DVBS2, QPSK, FEC_4_5, 0x00, 0x08 },
376 { SYS_DVBS2, QPSK, FEC_5_6, 0x00, 0x09 },
377 { SYS_DVBS2, QPSK, FEC_8_9, 0x00, 0x0a },
378 { SYS_DVBS2, QPSK, FEC_9_10, 0x00, 0x0b },
379 /* 8PSK */
380 { SYS_DVBS2, PSK_8, FEC_3_5, 0x00, 0x0c },
381 { SYS_DVBS2, PSK_8, FEC_2_3, 0x00, 0x0d },
382 { SYS_DVBS2, PSK_8, FEC_3_4, 0x00, 0x0e },
383 { SYS_DVBS2, PSK_8, FEC_5_6, 0x00, 0x0f },
384 { SYS_DVBS2, PSK_8, FEC_8_9, 0x00, 0x10 },
385 { SYS_DVBS2, PSK_8, FEC_9_10, 0x00, 0x11 },
386 /*
387 * `val' can be found in the FECSTATUS register when tuning.
388 * FECSTATUS will give the actual FEC in use if tuning was successful.
389 */
390};
391
392static int cx24116_lookup_fecmod(struct cx24116_state* state,
393 fe_modulation_t m, fe_code_rate_t f)
394{
395 int i, ret = -EOPNOTSUPP;
396
397 dprintk("%s(0x%02x,0x%02x)\n", __func__, m, f);
398
399 for(i=0 ; i < sizeof(CX24116_MODFEC_MODES) / sizeof(struct cx24116_modfec) ; i++)
400 {
401 if( (m == CX24116_MODFEC_MODES[i].modulation) &&
402 (f == CX24116_MODFEC_MODES[i].fec) )
403 {
404 ret = i;
405 break;
406 }
407 }
408
409 return ret;
410}
411
412static int cx24116_set_fec(struct cx24116_state* state, fe_modulation_t mod, fe_code_rate_t fec)
413{
414 int ret = 0;
415
416 dprintk("%s(0x%02x,0x%02x)\n", __func__, mod, fec);
417
418 ret = cx24116_lookup_fecmod(state, mod, fec);
419
420 if(ret < 0)
421 return ret;
422
423 state->dnxt.fec = fec;
424 state->dnxt.fec_val = CX24116_MODFEC_MODES[ret].val;
425 state->dnxt.fec_mask = CX24116_MODFEC_MODES[ret].mask;
426 dprintk("%s() mask/val = 0x%02x/0x%02x\n", __func__,
427 state->dnxt.fec_mask, state->dnxt.fec_val);
428
429 return 0;
430}
431
432static int cx24116_set_symbolrate(struct cx24116_state* state, u32 rate)
433{
434 dprintk("%s(%d)\n", __func__, rate);
435
436 /* check if symbol rate is within limits */
437 if ((rate > state->frontend.ops.info.symbol_rate_max) ||
438 (rate < state->frontend.ops.info.symbol_rate_min)) {
439 dprintk("%s() unsupported symbol_rate = %d\n", __func__, rate);
440 return -EOPNOTSUPP;
441 }
442
443 state->dnxt.symbol_rate = rate;
444 dprintk("%s() symbol_rate = %d\n", __func__, rate);
445
446 return 0;
447}
448
449static int cx24116_load_firmware (struct dvb_frontend* fe, const struct firmware *fw);
450
451static int cx24116_firmware_ondemand(struct dvb_frontend* fe)
452{
453 struct cx24116_state *state = fe->demodulator_priv;
454 const struct firmware *fw;
455 int ret = 0;
456
457 dprintk("%s()\n",__func__);
458
459 if (cx24116_readreg(state, 0x20) > 0)
460 {
461
462 if (state->skip_fw_load)
463 return 0;
464
465 /* Load firmware */
466 /* request the firmware, this will block until someone uploads it */
467 printk("%s: Waiting for firmware upload (%s)...\n", __func__, CX24116_DEFAULT_FIRMWARE);
468 ret = request_firmware(&fw, CX24116_DEFAULT_FIRMWARE, &state->i2c->dev);
469 printk("%s: Waiting for firmware upload(2)...\n", __func__);
470 if (ret) {
471 printk("%s: No firmware uploaded (timeout or file not found?)\n", __func__);
472 return ret;
473 }
474
475 /* Make sure we don't recurse back through here during loading */
476 state->skip_fw_load = 1;
477
478 ret = cx24116_load_firmware(fe, fw);
479 if (ret)
480 printk("%s: Writing firmware to device failed\n", __func__);
481
482 release_firmware(fw);
483
484 printk("%s: Firmware upload %s\n", __func__, ret == 0 ? "complete" : "failed");
485
486 /* Ensure firmware is always loaded if required */
487 state->skip_fw_load = 0;
488 }
489
490 return ret;
491}
492
493/* Take a basic firmware command structure, format it and forward it for processing */
494static int cx24116_cmd_execute(struct dvb_frontend* fe, struct cx24116_cmd *cmd)
495{
496 struct cx24116_state *state = fe->demodulator_priv;
497 int i, ret;
498
499 dprintk("%s()\n", __func__);
500
501 /* Load the firmware if required */
502 if ( (ret = cx24116_firmware_ondemand(fe)) != 0)
503 {
504 printk("%s(): Unable initialise the firmware\n", __func__);
505 return ret;
506 }
507
508 /* Write the command */
509 for(i = 0; i < cmd->len ; i++)
510 {
511 dprintk("%s: 0x%02x == 0x%02x\n", __func__, i, cmd->args[i]);
512 cx24116_writereg(state, i, cmd->args[i]);
513 }
514
515 /* Start execution and wait for cmd to terminate */
516 cx24116_writereg(state, CX24116_REG_EXECUTE, 0x01);
517 while( cx24116_readreg(state, CX24116_REG_EXECUTE) )
518 {
519 msleep(10);
520 if(i++ > 64)
521 {
522 /* Avoid looping forever if the firmware does no respond */
523 printk("%s() Firmware not responding\n", __func__);
524 return -EREMOTEIO;
525 }
526 }
527 return 0;
528}
529
530static int cx24116_load_firmware (struct dvb_frontend* fe, const struct firmware *fw)
531{
532 struct cx24116_state* state = fe->demodulator_priv;
533 struct cx24116_cmd cmd;
534 int i, ret;
535 unsigned char vers[4];
536
537 dprintk("%s\n", __func__);
538 dprintk("Firmware is %zu bytes (%02x %02x .. %02x %02x)\n"
539 ,fw->size
540 ,fw->data[0]
541 ,fw->data[1]
542 ,fw->data[ fw->size-2 ]
543 ,fw->data[ fw->size-1 ]
544 );
545
546 /* Toggle 88x SRST pin to reset demod */
547 if (state->config->reset_device)
548 state->config->reset_device(fe);
549
550 /* Begin the firmware load process */
551 /* Prepare the demod, load the firmware, cleanup after load */
552
553 /* Init PLL */
554 cx24116_writereg(state, 0xE5, 0x00);
555 cx24116_writereg(state, 0xF1, 0x08);
556 cx24116_writereg(state, 0xF2, 0x13);
557
558 /* Start PLL */
559 cx24116_writereg(state, 0xe0, 0x03);
560 cx24116_writereg(state, 0xe0, 0x00);
561
562 /* Unknown */
563 cx24116_writereg(state, CX24116_REG_CLKDIV, 0x46);
564 cx24116_writereg(state, CX24116_REG_RATEDIV, 0x00);
565
566 /* Unknown */
567 cx24116_writereg(state, 0xF0, 0x03);
568 cx24116_writereg(state, 0xF4, 0x81);
569 cx24116_writereg(state, 0xF5, 0x00);
570 cx24116_writereg(state, 0xF6, 0x00);
571
572 /* write the entire firmware as one transaction */
573 cx24116_writeregN(state, 0xF7, fw->data, fw->size);
574
575 cx24116_writereg(state, 0xF4, 0x10);
576 cx24116_writereg(state, 0xF0, 0x00);
577 cx24116_writereg(state, 0xF8, 0x06);
578
579 /* Firmware CMD 10: VCO config */
580 cmd.args[0x00] = CMD_SET_VCO;
581 cmd.args[0x01] = 0x05;
582 cmd.args[0x02] = 0xdc;
583 cmd.args[0x03] = 0xda;
584 cmd.args[0x04] = 0xae;
585 cmd.args[0x05] = 0xaa;
586 cmd.args[0x06] = 0x04;
587 cmd.args[0x07] = 0x9d;
588 cmd.args[0x08] = 0xfc;
589 cmd.args[0x09] = 0x06;
590 cmd.len= 0x0a;
591 ret = cx24116_cmd_execute(fe, &cmd);
592 if (ret != 0)
593 return ret;
594
595 cx24116_writereg(state, CX24116_REG_SSTATUS, 0x00);
596
597 /* Firmware CMD 14: Tuner config */
598 cmd.args[0x00] = CMD_TUNERINIT;
599 cmd.args[0x01] = 0x00;
600 cmd.args[0x02] = 0x00;
601 cmd.len= 0x03;
602 ret = cx24116_cmd_execute(fe, &cmd);
603 if (ret != 0)
604 return ret;
605
606 cx24116_writereg(state, 0xe5, 0x00);
607
608 /* Firmware CMD 13: MPEG config */
609 cmd.args[0x00] = CMD_MPEGCONFIG;
610 cmd.args[0x01] = 0x01;
611 cmd.args[0x02] = 0x75;
612 cmd.args[0x03] = 0x00;
613 if (state->config->mpg_clk_pos_pol)
614 cmd.args[0x04] = state->config->mpg_clk_pos_pol;
615 else
616 cmd.args[0x04] = 0x02;
617 cmd.args[0x05] = 0x00;
618 cmd.len= 0x06;
619 ret = cx24116_cmd_execute(fe, &cmd);
620 if (ret != 0)
621 return ret;
622
623 /* Firmware CMD 35: Get firmware version */
624 cmd.args[0x00] = CMD_UPDFWVERS;
625 cmd.len= 0x02;
626 for(i=0; i<4; i++) {
627 cmd.args[0x01] = i;
628 ret = cx24116_cmd_execute(fe, &cmd);
629 if (ret != 0)
630 return ret;
631 vers[i]= cx24116_readreg(state, CX24116_REG_MAILBOX);
632 }
633 printk("%s: FW version %i.%i.%i.%i\n", __func__,
634 vers[0], vers[1], vers[2], vers[3]);
635
636 return 0;
637}
638
639static int cx24116_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
640{
641 /* The isl6421 module will override this function in the fops. */
642 dprintk("%s() This should never appear if the isl6421 module is loaded correctly\n",__func__);
643
644 return -EOPNOTSUPP;
645}
646
647static int cx24116_read_status(struct dvb_frontend* fe, fe_status_t* status)
648{
649 struct cx24116_state *state = fe->demodulator_priv;
650
651 int lock = cx24116_readreg(state, CX24116_REG_SSTATUS);
652
653 dprintk("%s: status = 0x%02x\n", __func__, lock);
654
655 *status = 0;
656
657 if (lock & CX24116_HAS_SIGNAL)
658 *status |= FE_HAS_SIGNAL;
659 if (lock & CX24116_HAS_CARRIER)
660 *status |= FE_HAS_CARRIER;
661 if (lock & CX24116_HAS_VITERBI)
662 *status |= FE_HAS_VITERBI;
663 if (lock & CX24116_HAS_SYNCLOCK)
664 *status |= FE_HAS_SYNC | FE_HAS_LOCK;
665
666 return 0;
667}
668
669static int cx24116_read_ber(struct dvb_frontend* fe, u32* ber)
670{
671 struct cx24116_state *state = fe->demodulator_priv;
672
673 dprintk("%s()\n", __func__);
674
675 *ber = ( cx24116_readreg(state, CX24116_REG_BER24) << 24 ) |
676 ( cx24116_readreg(state, CX24116_REG_BER16) << 16 ) |
677 ( cx24116_readreg(state, CX24116_REG_BER8 ) << 8 ) |
678 cx24116_readreg(state, CX24116_REG_BER0 );
679
680 return 0;
681}
682
683/* TODO Determine function and scale appropriately */
684static int cx24116_read_signal_strength(struct dvb_frontend* fe, u16* signal_strength)
685{
686 struct cx24116_state *state = fe->demodulator_priv;
687 struct cx24116_cmd cmd;
688 int ret;
689 u16 sig_reading;
690
691 dprintk("%s()\n", __func__);
692
693 /* Firmware CMD 19: Get AGC */
694 cmd.args[0x00] = CMD_GETAGC;
695 cmd.len= 0x01;
696 ret = cx24116_cmd_execute(fe, &cmd);
697 if (ret != 0)
698 return ret;
699
700 sig_reading = ( cx24116_readreg(state, CX24116_REG_SSTATUS) & CX24116_SIGNAL_MASK ) |
701 ( cx24116_readreg(state, CX24116_REG_SIGNAL) << 6 );
702 *signal_strength= 0 - sig_reading;
703
704 dprintk("%s: raw / cooked = 0x%04x / 0x%04x\n", __func__, sig_reading, *signal_strength);
705
706 return 0;
707}
708
709/* SNR (0..100)% = (sig & 0xf0) * 10 + (sig & 0x0f) * 10 / 16 */
710static int cx24116_read_snr_pct(struct dvb_frontend* fe, u16* snr)
711{
712 struct cx24116_state *state = fe->demodulator_priv;
713 u8 snr_reading;
714 static const u32 snr_tab[] = { /* 10 x Table (rounded up) */
715 0x00000,0x0199A,0x03333,0x04ccD,0x06667,
716 0x08000,0x0999A,0x0b333,0x0cccD,0x0e667,
717 0x10000,0x1199A,0x13333,0x14ccD,0x16667,0x18000 };
718
719 dprintk("%s()\n", __func__);
720
721 snr_reading = cx24116_readreg(state, CX24116_REG_QUALITY0);
722
723 if(snr_reading >= 0xa0 /* 100% */)
724 *snr = 0xffff;
725 else
726 *snr = snr_tab [ ( snr_reading & 0xf0 ) >> 4 ] +
727 ( snr_tab [ ( snr_reading & 0x0f ) ] >> 4 );
728
729 dprintk("%s: raw / cooked = 0x%02x / 0x%04x\n", __func__,
730 snr_reading, *snr);
731
732 return 0;
733}
734
735/* The reelbox patches show the value in the registers represents
736 * ESNO, from 0->30db (values 0->300). We provide this value by
737 * default.
738 */
739static int cx24116_read_snr_esno(struct dvb_frontend* fe, u16* snr)
740{
741 struct cx24116_state *state = fe->demodulator_priv;
742
743 dprintk("%s()\n", __func__);
744
745 *snr = cx24116_readreg(state, CX24116_REG_QUALITY8) << 8 |
746 cx24116_readreg(state, CX24116_REG_QUALITY0);
747
748 dprintk("%s: raw 0x%04x\n", __func__, *snr);
749
750 return 0;
751}
752
753static int cx24116_read_snr(struct dvb_frontend* fe, u16* snr)
754{
755 if (esno_snr == 1)
756 return cx24116_read_snr_esno(fe, snr);
757 else
758 return cx24116_read_snr_pct(fe, snr);
759}
760
761static int cx24116_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
762{
763 struct cx24116_state *state = fe->demodulator_priv;
764
765 dprintk("%s()\n", __func__);
766
767 *ucblocks = ( cx24116_readreg(state, CX24116_REG_UCB8) << 8 ) |
768 cx24116_readreg(state, CX24116_REG_UCB0);
769
770 return 0;
771}
772
773/* Overwrite the current tuning params, we are about to tune */
774static void cx24116_clone_params(struct dvb_frontend* fe)
775{
776 struct cx24116_state *state = fe->demodulator_priv;
777 memcpy(&state->dcur, &state->dnxt, sizeof(state->dcur));
778}
779
780/* Wait for LNB */
781static int cx24116_wait_for_lnb(struct dvb_frontend* fe)
782{
783 struct cx24116_state *state = fe->demodulator_priv;
784 int i;
785
786 dprintk("%s() qstatus = 0x%02x\n", __func__,
787 cx24116_readreg(state, CX24116_REG_QSTATUS));
788
789 /* Wait for up to 300 ms */
790 for(i = 0; i < 30 ; i++) {
791 if (cx24116_readreg(state, CX24116_REG_QSTATUS) & 0x20)
792 return 0;
793 msleep(10);
794 }
795
796 dprintk("%s(): LNB not ready\n", __func__);
797
798 return -ETIMEDOUT; /* -EBUSY ? */
799}
800
801static int cx24116_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
802{
803 struct cx24116_cmd cmd;
804 int ret;
805
806 dprintk("%s(%d)\n", __func__, tone);
807 if ( (tone != SEC_TONE_ON) && (tone != SEC_TONE_OFF) ) {
808 printk("%s: Invalid, tone=%d\n", __func__, tone);
809 return -EINVAL;
810 }
811
812 /* Wait for LNB ready */
813 ret = cx24116_wait_for_lnb(fe);
814 if(ret != 0)
815 return ret;
816
817 /* Min delay time after DiSEqC send */
818 msleep(15); /* XXX determine is FW does this, see send_diseqc/burst */
819
820 /* This is always done before the tone is set */
821 cmd.args[0x00] = CMD_SET_TONEPRE;
822 cmd.args[0x01] = 0x00;
823 cmd.len= 0x02;
824 ret = cx24116_cmd_execute(fe, &cmd);
825 if (ret != 0)
826 return ret;
827
828 /* Now we set the tone */
829 cmd.args[0x00] = CMD_SET_TONE;
830 cmd.args[0x01] = 0x00;
831 cmd.args[0x02] = 0x00;
832
833 switch (tone) {
834 case SEC_TONE_ON:
835 dprintk("%s: setting tone on\n", __func__);
836 cmd.args[0x03] = 0x01;
837 break;
838 case SEC_TONE_OFF:
839 dprintk("%s: setting tone off\n",__func__);
840 cmd.args[0x03] = 0x00;
841 break;
842 }
843 cmd.len= 0x04;
844
845 /* Min delay time before DiSEqC send */
846 msleep(15); /* XXX determine is FW does this, see send_diseqc/burst */
847
848 return cx24116_cmd_execute(fe, &cmd);
849}
850
851/* Initialise DiSEqC */
852static int cx24116_diseqc_init(struct dvb_frontend* fe)
853{
854 struct cx24116_state *state = fe->demodulator_priv;
855 struct cx24116_cmd cmd;
856 int ret;
857
858 /* Firmware CMD 20: LNB/DiSEqC config */
859 cmd.args[0x00] = CMD_LNBCONFIG;
860 cmd.args[0x01] = 0x00;
861 cmd.args[0x02] = 0x10;
862 cmd.args[0x03] = 0x00;
863 cmd.args[0x04] = 0x8f;
864 cmd.args[0x05] = 0x28;
865 cmd.args[0x06] = (toneburst == CX24116_DISEQC_TONEOFF) ? 0x00 : 0x01;
866 cmd.args[0x07] = 0x01;
867 cmd.len= 0x08;
868 ret = cx24116_cmd_execute(fe, &cmd);
869 if (ret != 0)
870 return ret;
871
872 /* Prepare a DiSEqC command */
873 state->dsec_cmd.args[0x00] = CMD_LNBSEND;
874
875 /* DiSEqC burst */
876 state->dsec_cmd.args[CX24116_DISEQC_BURST] = CX24116_DISEQC_MINI_A;
877
878 /* Unknown */
879 state->dsec_cmd.args[CX24116_DISEQC_ARG2_2] = 0x02;
880 state->dsec_cmd.args[CX24116_DISEQC_ARG3_0] = 0x00;
881 state->dsec_cmd.args[CX24116_DISEQC_ARG4_0] = 0x00; /* Continuation flag? */
882
883 /* DiSEqC message length */
884 state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] = 0x00;
885
886 /* Command length */
887 state->dsec_cmd.len= CX24116_DISEQC_MSGOFS;
888
889 return 0;
890}
891
892/* Send DiSEqC message with derived burst (hack) || previous burst */
893static int cx24116_send_diseqc_msg(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd *d)
894{
895 struct cx24116_state *state = fe->demodulator_priv;
896 int i, ret;
897
898 /* Dump DiSEqC message */
899 if (debug) {
900 printk("cx24116: %s(", __func__);
901 for(i = 0 ; i < d->msg_len ;) {
902 printk("0x%02x", d->msg[i]);
903 if(++i < d->msg_len)
904 printk(", ");
905 }
906 printk(") toneburst=%d\n", toneburst);
907 }
908
909 /* Validate length */
910 if(d->msg_len > (CX24116_ARGLEN - CX24116_DISEQC_MSGOFS))
911 return -EINVAL;
912
913 /* DiSEqC message */
914 for (i = 0; i < d->msg_len; i++)
915 state->dsec_cmd.args[CX24116_DISEQC_MSGOFS + i] = d->msg[i];
916
917 /* DiSEqC message length */
918 state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] = d->msg_len;
919
920 /* Command length */
921 state->dsec_cmd.len= CX24116_DISEQC_MSGOFS + state->dsec_cmd.args[CX24116_DISEQC_MSGLEN];
922
923 /* DiSEqC toneburst */
924 if(toneburst == CX24116_DISEQC_MESGCACHE)
925 /* Message is cached */
926 return 0;
927
928 else if(toneburst == CX24116_DISEQC_TONEOFF)
929 /* Message is sent without burst */
930 state->dsec_cmd.args[CX24116_DISEQC_BURST] = 0;
931
932 else if(toneburst == CX24116_DISEQC_TONECACHE) {
933 /*
934 * Message is sent with derived else cached burst
935 *
936 * WRITE PORT GROUP COMMAND 38
937 *
938 * 0/A/A: E0 10 38 F0..F3
939 * 1/B/B: E0 10 38 F4..F7
940 * 2/C/A: E0 10 38 F8..FB
941 * 3/D/B: E0 10 38 FC..FF
942 *
943 * databyte[3]= 8421:8421
944 * ABCD:WXYZ
945 * CLR :SET
946 *
947 * WX= PORT SELECT 0..3 (X=TONEBURST)
948 * Y = VOLTAGE (0=13V, 1=18V)
949 * Z = BAND (0=LOW, 1=HIGH(22K))
950 */
951 if(d->msg_len >= 4 && d->msg[2] == 0x38)
952 state->dsec_cmd.args[CX24116_DISEQC_BURST] = ((d->msg[3] & 4) >> 2);
953 if(debug)
954 dprintk("%s burst=%d\n", __func__, state->dsec_cmd.args[CX24116_DISEQC_BURST]);
955 }
956
957 /* Wait for LNB ready */
958 ret = cx24116_wait_for_lnb(fe);
959 if(ret != 0)
960 return ret;
961
962 /* Wait for voltage/min repeat delay */
963 msleep(100);
964
965 /* Command */
966 ret = cx24116_cmd_execute(fe, &state->dsec_cmd);
967 if(ret != 0)
968 return ret;
969 /*
970 * Wait for send
971 *
972 * Eutelsat spec:
973 * >15ms delay + (XXX determine if FW does this, see set_tone)
974 * 13.5ms per byte +
975 * >15ms delay +
976 * 12.5ms burst +
977 * >15ms delay (XXX determine if FW does this, see set_tone)
978 */
979 msleep( (state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] << 4) + ((toneburst == CX24116_DISEQC_TONEOFF) ? 30 : 60) );
980
981 return 0;
982}
983
984/* Send DiSEqC burst */
985static int cx24116_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t burst)
986{
987 struct cx24116_state *state = fe->demodulator_priv;
988 int ret;
989
990 dprintk("%s(%d) toneburst=%d\n",__func__, burst, toneburst);
991
992 /* DiSEqC burst */
993 if (burst == SEC_MINI_A)
994 state->dsec_cmd.args[CX24116_DISEQC_BURST] = CX24116_DISEQC_MINI_A;
995 else if(burst == SEC_MINI_B)
996 state->dsec_cmd.args[CX24116_DISEQC_BURST] = CX24116_DISEQC_MINI_B;
997 else
998 return -EINVAL;
999
1000 /* DiSEqC toneburst */
1001 if(toneburst != CX24116_DISEQC_MESGCACHE)
1002 /* Burst is cached */
1003 return 0;
1004
1005 /* Burst is to be sent with cached message */
1006
1007 /* Wait for LNB ready */
1008 ret = cx24116_wait_for_lnb(fe);
1009 if(ret != 0)
1010 return ret;
1011
1012 /* Wait for voltage/min repeat delay */
1013 msleep(100);
1014
1015 /* Command */
1016 ret = cx24116_cmd_execute(fe, &state->dsec_cmd);
1017 if(ret != 0)
1018 return ret;
1019
1020 /*
1021 * Wait for send
1022 *
1023 * Eutelsat spec:
1024 * >15ms delay + (XXX determine if FW does this, see set_tone)
1025 * 13.5ms per byte +
1026 * >15ms delay +
1027 * 12.5ms burst +
1028 * >15ms delay (XXX determine if FW does this, see set_tone)
1029 */
1030 msleep( (state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] << 4) + 60 );
1031
1032 return 0;
1033}
1034
1035static void cx24116_release(struct dvb_frontend* fe)
1036{
1037 struct cx24116_state* state = fe->demodulator_priv;
1038 dprintk("%s\n",__func__);
1039 kfree(state);
1040}
1041
1042static struct dvb_frontend_ops cx24116_ops;
1043
1044struct dvb_frontend* cx24116_attach(const struct cx24116_config* config,
1045 struct i2c_adapter* i2c)
1046{
1047 struct cx24116_state* state = NULL;
1048 int ret;
1049
1050 dprintk("%s\n",__func__);
1051
1052 /* allocate memory for the internal state */
1053 state = kmalloc(sizeof(struct cx24116_state), GFP_KERNEL);
1054 if (state == NULL) {
1055 printk("Unable to kmalloc\n");
1056 goto error1;
1057 }
1058
1059 /* setup the state */
1060 memset(state, 0, sizeof(struct cx24116_state));
1061
1062 state->config = config;
1063 state->i2c = i2c;
1064
1065 /* check if the demod is present */
1066 ret = (cx24116_readreg(state, 0xFF) << 8) | cx24116_readreg(state, 0xFE);
1067 if (ret != 0x0501) {
1068 printk("Invalid probe, probably not a CX24116 device\n");
1069 goto error2;
1070 }
1071
1072 /* create dvb_frontend */
1073 memcpy(&state->frontend.ops, &cx24116_ops, sizeof(struct dvb_frontend_ops));
1074 state->frontend.demodulator_priv = state;
1075 return &state->frontend;
1076
1077error2: kfree(state);
1078error1: return NULL;
1079}
1080/*
1081 * Initialise or wake up device
1082 *
1083 * Power config will reset and load initial firmware if required
1084 */
1085static int cx24116_initfe(struct dvb_frontend* fe)
1086{
1087 struct cx24116_state* state = fe->demodulator_priv;
1088 struct cx24116_cmd cmd;
1089 int ret;
1090
1091 dprintk("%s()\n",__func__);
1092
1093 /* Power on */
1094 cx24116_writereg(state, 0xe0, 0);
1095 cx24116_writereg(state, 0xe1, 0);
1096 cx24116_writereg(state, 0xea, 0);
1097
1098 /* Firmware CMD 36: Power config */
1099 cmd.args[0x00] = CMD_TUNERSLEEP;
1100 cmd.args[0x01] = 0;
1101 cmd.len= 0x02;
1102 ret = cx24116_cmd_execute(fe, &cmd);
1103 if(ret != 0)
1104 return ret;
1105
1106 return cx24116_diseqc_init(fe);
1107}
1108
1109/*
1110 * Put device to sleep
1111 */
1112static int cx24116_sleep(struct dvb_frontend* fe)
1113{
1114 struct cx24116_state* state = fe->demodulator_priv;
1115 struct cx24116_cmd cmd;
1116 int ret;
1117
1118 dprintk("%s()\n",__func__);
1119
1120 /* Firmware CMD 36: Power config */
1121 cmd.args[0x00] = CMD_TUNERSLEEP;
1122 cmd.args[0x01] = 1;
1123 cmd.len= 0x02;
1124 ret = cx24116_cmd_execute(fe, &cmd);
1125 if(ret != 0)
1126 return ret;
1127
1128 /* Power off (Shutdown clocks) */
1129 cx24116_writereg(state, 0xea, 0xff);
1130 cx24116_writereg(state, 0xe1, 1);
1131 cx24116_writereg(state, 0xe0, 1);
1132
1133 return 0;
1134}
1135
1136static int cx24116_set_property(struct dvb_frontend *fe, struct dtv_property* tvp)
1137{
1138 dprintk("%s(..)\n", __func__);
1139 return 0;
1140}
1141
1142static int cx24116_get_property(struct dvb_frontend *fe, struct dtv_property* tvp)
1143{
1144 dprintk("%s(..)\n", __func__);
1145 return 0;
1146}
1147
1148/* dvb-core told us to tune, the tv property cache will be complete,
1149 * it's safe for is to pull values and use them for tuning purposes.
1150 */
1151static int cx24116_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
1152{
1153 struct cx24116_state *state = fe->demodulator_priv;
1154 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
1155 struct cx24116_cmd cmd;
1156 fe_status_t tunerstat;
1157 int i, status, ret, retune;
1158
1159 dprintk("%s()\n",__func__);
1160
1161 switch(c->delivery_system) {
1162 case SYS_DVBS:
1163 dprintk("%s: DVB-S delivery system selected\n",__func__);
1164
1165 /* Only QPSK is supported for DVB-S */
1166 if(c->modulation != QPSK) {
1167 dprintk("%s: unsupported modulation selected (%d)\n",
1168 __func__, c->modulation);
1169 return -EOPNOTSUPP;
1170 }
1171
1172 /* Pilot doesn't exist in DVB-S, turn bit off */
1173 state->dnxt.pilot_val = CX24116_PILOT_OFF;
1174 retune = 1;
1175
1176 /* DVB-S only supports 0.35 */
1177 if(c->rolloff != ROLLOFF_35) {
1178 dprintk("%s: unsupported rolloff selected (%d)\n",
1179 __func__, c->rolloff);
1180 return -EOPNOTSUPP;
1181 }
1182 state->dnxt.rolloff_val = CX24116_ROLLOFF_035;
1183 break;
1184
1185 case SYS_DVBS2:
1186 dprintk("%s: DVB-S2 delivery system selected\n",__func__);
1187
1188 /*
1189 * NBC 8PSK/QPSK with DVB-S is supported for DVB-S2,
1190 * but not hardware auto detection
1191 */
1192 if(c->modulation != PSK_8 && c->modulation != QPSK) {
1193 dprintk("%s: unsupported modulation selected (%d)\n",
1194 __func__, c->modulation);
1195 return -EOPNOTSUPP;
1196 }
1197
1198 switch(c->pilot) {
1199 case PILOT_AUTO: /* Not supported but emulated */
1200 retune = 2; /* Fall-through */
1201 case PILOT_OFF:
1202 state->dnxt.pilot_val = CX24116_PILOT_OFF;
1203 break;
1204 case PILOT_ON:
1205 state->dnxt.pilot_val = CX24116_PILOT_ON;
1206 break;
1207 default:
1208 dprintk("%s: unsupported pilot mode selected (%d)\n",
1209 __func__, c->pilot);
1210 return -EOPNOTSUPP;
1211 }
1212
1213 switch(c->rolloff) {
1214 case ROLLOFF_20:
1215 state->dnxt.rolloff_val= CX24116_ROLLOFF_020;
1216 break;
1217 case ROLLOFF_25:
1218 state->dnxt.rolloff_val= CX24116_ROLLOFF_025;
1219 break;
1220 case ROLLOFF_35:
1221 state->dnxt.rolloff_val= CX24116_ROLLOFF_035;
1222 break;
1223 case ROLLOFF_AUTO: /* Rolloff must be explicit */
1224 default:
1225 dprintk("%s: unsupported rolloff selected (%d)\n",
1226 __func__, c->rolloff);
1227 return -EOPNOTSUPP;
1228 }
1229 break;
1230
1231 default:
1232 dprintk("%s: unsupported delivery system selected (%d)\n",
1233 __func__, c->delivery_system);
1234 return -EOPNOTSUPP;
1235 }
1236 state->dnxt.modulation = c->modulation;
1237 state->dnxt.frequency = c->frequency;
1238 state->dnxt.pilot = c->pilot;
1239 state->dnxt.rolloff = c->rolloff;
1240
1241 if ((ret = cx24116_set_inversion(state, c->inversion)) != 0)
1242 return ret;
1243
1244 /* FEC_NONE/AUTO for DVB-S2 is not supported and detected here */
1245 if ((ret = cx24116_set_fec(state, c->modulation, c->fec_inner)) != 0)
1246 return ret;
1247
1248 if ((ret = cx24116_set_symbolrate(state, c->symbol_rate)) != 0)
1249 return ret;
1250
1251 /* discard the 'current' tuning parameters and prepare to tune */
1252 cx24116_clone_params(fe);
1253
1254 dprintk("%s: modulation = %d\n", __func__, state->dcur.modulation);
1255 dprintk("%s: frequency = %d\n", __func__, state->dcur.frequency);
1256 dprintk("%s: pilot = %d (val = 0x%02x)\n", __func__,
1257 state->dcur.pilot, state->dcur.pilot_val);
1258 dprintk("%s: retune = %d\n", __func__, retune);
1259 dprintk("%s: rolloff = %d (val = 0x%02x)\n", __func__,
1260 state->dcur.rolloff, state->dcur.rolloff_val);
1261 dprintk("%s: symbol_rate = %d\n", __func__, state->dcur.symbol_rate);
1262 dprintk("%s: FEC = %d (mask/val = 0x%02x/0x%02x)\n", __func__,
1263 state->dcur.fec, state->dcur.fec_mask, state->dcur.fec_val);
1264 dprintk("%s: Inversion = %d (val = 0x%02x)\n", __func__,
1265 state->dcur.inversion, state->dcur.inversion_val);
1266
1267 /* This is also done in advise/acquire on HVR4000 but not on LITE */
1268 if (state->config->set_ts_params)
1269 state->config->set_ts_params(fe, 0);
1270
1271 /* Set/Reset B/W */
1272 cmd.args[0x00] = CMD_BANDWIDTH;
1273 cmd.args[0x01] = 0x01;
1274 cmd.len= 0x02;
1275 ret = cx24116_cmd_execute(fe, &cmd);
1276 if (ret != 0)
1277 return ret;
1278
1279 /* Prepare a tune request */
1280 cmd.args[0x00] = CMD_TUNEREQUEST;
1281
1282 /* Frequency */
1283 cmd.args[0x01] = (state->dcur.frequency & 0xff0000) >> 16;
1284 cmd.args[0x02] = (state->dcur.frequency & 0x00ff00) >> 8;
1285 cmd.args[0x03] = (state->dcur.frequency & 0x0000ff);
1286
1287 /* Symbol Rate */
1288 cmd.args[0x04] = ((state->dcur.symbol_rate / 1000) & 0xff00) >> 8;
1289 cmd.args[0x05] = ((state->dcur.symbol_rate / 1000) & 0x00ff);
1290
1291 /* Automatic Inversion */
1292 cmd.args[0x06] = state->dcur.inversion_val;
1293
1294 /* Modulation / FEC / Pilot */
1295 cmd.args[0x07] = state->dcur.fec_val | state->dcur.pilot_val;
1296
1297 cmd.args[0x08] = CX24116_SEARCH_RANGE_KHZ >> 8;
1298 cmd.args[0x09] = CX24116_SEARCH_RANGE_KHZ & 0xff;
1299 cmd.args[0x0a] = 0x00;
1300 cmd.args[0x0b] = 0x00;
1301 cmd.args[0x0c] = state->dcur.rolloff_val;
1302 cmd.args[0x0d] = state->dcur.fec_mask;
1303
1304 if (state->dcur.symbol_rate > 30000000) {
1305 cmd.args[0x0e] = 0x04;
1306 cmd.args[0x0f] = 0x00;
1307 cmd.args[0x10] = 0x01;
1308 cmd.args[0x11] = 0x77;
1309 cmd.args[0x12] = 0x36;
1310 cx24116_writereg(state, CX24116_REG_CLKDIV, 0x44);
1311 cx24116_writereg(state, CX24116_REG_RATEDIV, 0x01);
1312 } else {
1313 cmd.args[0x0e] = 0x06;
1314 cmd.args[0x0f] = 0x00;
1315 cmd.args[0x10] = 0x00;
1316 cmd.args[0x11] = 0xFA;
1317 cmd.args[0x12] = 0x24;
1318 cx24116_writereg(state, CX24116_REG_CLKDIV, 0x46);
1319 cx24116_writereg(state, CX24116_REG_RATEDIV, 0x00);
1320 }
1321
1322 cmd.len= 0x13;
1323
1324 /* We need to support pilot and non-pilot tuning in the
1325 * driver automatically. This is a workaround for because
1326 * the demod does not support autodetect.
1327 */
1328 do {
1329 /* Reset status register */
1330 status = cx24116_readreg(state, CX24116_REG_SSTATUS) & CX24116_SIGNAL_MASK;
1331 cx24116_writereg(state, CX24116_REG_SSTATUS, status);
1332
1333 /* Tune */
1334 ret = cx24116_cmd_execute(fe, &cmd);
1335 if( ret != 0 )
1336 break;
1337
1338 /*
1339 * Wait for up to 500 ms before retrying
1340 *
1341 * If we are able to tune then generally it occurs within 100ms.
1342 * If it takes longer, try a different toneburst setting.
1343 */
1344 for(i = 0; i < 50 ; i++) {
1345 cx24116_read_status(fe, &tunerstat);
1346 status = tunerstat & (FE_HAS_SIGNAL | FE_HAS_SYNC);
1347 if(status == (FE_HAS_SIGNAL | FE_HAS_SYNC)) {
1348 dprintk("%s: Tuned\n",__func__);
1349 goto tuned;
1350 }
1351 msleep(10);
1352 }
1353
1354 dprintk("%s: Not tuned\n",__func__);
1355
1356 /* Toggle pilot bit when in auto-pilot */
1357 if(state->dcur.pilot == PILOT_AUTO)
1358 cmd.args[0x07] ^= CX24116_PILOT_ON;
1359 }
1360 while(--retune);
1361
1362tuned: /* Set/Reset B/W */
1363 cmd.args[0x00] = CMD_BANDWIDTH;
1364 cmd.args[0x01] = 0x00;
1365 cmd.len= 0x02;
1366 ret = cx24116_cmd_execute(fe, &cmd);
1367 if (ret != 0)
1368 return ret;
1369
1370 return ret;
1371}
1372
1373static struct dvb_frontend_ops cx24116_ops = {
1374
1375 .info = {
1376 .name = "Conexant CX24116/CX24118",
1377 .type = FE_QPSK,
1378 .frequency_min = 950000,
1379 .frequency_max = 2150000,
1380 .frequency_stepsize = 1011, /* kHz for QPSK frontends */
1381 .frequency_tolerance = 5000,
1382 .symbol_rate_min = 1000000,
1383 .symbol_rate_max = 45000000,
1384 .caps = FE_CAN_INVERSION_AUTO |
1385 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
1386 FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 |
1387 FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
1388 FE_CAN_QPSK | FE_CAN_RECOVER
1389 },
1390
1391 .release = cx24116_release,
1392
1393 .init = cx24116_initfe,
1394 .sleep = cx24116_sleep,
1395 .read_status = cx24116_read_status,
1396 .read_ber = cx24116_read_ber,
1397 .read_signal_strength = cx24116_read_signal_strength,
1398 .read_snr = cx24116_read_snr,
1399 .read_ucblocks = cx24116_read_ucblocks,
1400 .set_tone = cx24116_set_tone,
1401 .set_voltage = cx24116_set_voltage,
1402 .diseqc_send_master_cmd = cx24116_send_diseqc_msg,
1403 .diseqc_send_burst = cx24116_diseqc_send_burst,
1404
1405 .set_property = cx24116_set_property,
1406 .get_property = cx24116_get_property,
1407 .set_frontend = cx24116_set_frontend,
1408};
1409
1410module_param(debug, int, 0644);
1411MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)");
1412
1413module_param(toneburst, int, 0644);
1414MODULE_PARM_DESC(toneburst, "DiSEqC toneburst 0=OFF, 1=TONE CACHE, 2=MESSAGE CACHE (default:1)");
1415
1416module_param(esno_snr, int, 0644);
1417MODULE_PARM_DESC(debug, "SNR return units, 0=PERCENTAGE 0-100, 1=ESNO(db * 10) (default:0)");
1418
1419MODULE_DESCRIPTION("DVB Frontend module for Conexant cx24116/cx24118 hardware");
1420MODULE_AUTHOR("Steven Toth");
1421MODULE_LICENSE("GPL");
1422
1423EXPORT_SYMBOL(cx24116_attach);
diff --git a/drivers/media/dvb/frontends/cx24116.h b/drivers/media/dvb/frontends/cx24116.h
new file mode 100644
index 000000000000..8dbcec268394
--- /dev/null
+++ b/drivers/media/dvb/frontends/cx24116.h
@@ -0,0 +1,53 @@
1/*
2 Conexant cx24116/cx24118 - DVBS/S2 Satellite demod/tuner driver
3
4 Copyright (C) 2006 Steven Toth <stoth@linuxtv.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#ifndef CX24116_H
22#define CX24116_H
23
24#include <linux/dvb/frontend.h>
25
26struct cx24116_config
27{
28 /* the demodulator's i2c address */
29 u8 demod_address;
30
31 /* Need to set device param for start_dma */
32 int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured);
33
34 /* Need to reset device during firmware loading */
35 int (*reset_device)(struct dvb_frontend* fe);
36
37 /* Need to set MPEG parameters */
38 u8 mpg_clk_pos_pol:0x02;
39};
40
41#if defined(CONFIG_DVB_CX24116) || defined(CONFIG_DVB_CX24116_MODULE)
42extern struct dvb_frontend* cx24116_attach(const struct cx24116_config* config,
43 struct i2c_adapter* i2c);
44#else
45static inline struct dvb_frontend* cx24116_attach(const struct cx24116_config* config,
46 struct i2c_adapter* i2c)
47{
48 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
49 return NULL;
50}
51#endif // CONFIG_DVB_CX24116
52
53#endif /* CX24116_H */
diff --git a/drivers/media/dvb/frontends/dib0070.h b/drivers/media/dvb/frontends/dib0070.h
index 3eedfdf505bc..21f2c5161af4 100644
--- a/drivers/media/dvb/frontends/dib0070.h
+++ b/drivers/media/dvb/frontends/dib0070.h
@@ -41,6 +41,7 @@ struct dib0070_config {
41extern struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, 41extern struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe,
42 struct i2c_adapter *i2c, 42 struct i2c_adapter *i2c,
43 struct dib0070_config *cfg); 43 struct dib0070_config *cfg);
44extern u16 dib0070_wbd_offset(struct dvb_frontend *);
44#else 45#else
45static inline struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, 46static inline struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe,
46 struct i2c_adapter *i2c, 47 struct i2c_adapter *i2c,
@@ -49,9 +50,14 @@ static inline struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe,
49 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); 50 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
50 return NULL; 51 return NULL;
51} 52}
53
54static inline u16 dib0070_wbd_offset(struct dvb_frontend *fe)
55{
56 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
57 return -ENODEV;
58}
52#endif 59#endif
53 60
54extern void dib0070_ctrl_agc_filter(struct dvb_frontend *, uint8_t open); 61extern void dib0070_ctrl_agc_filter(struct dvb_frontend *, uint8_t open);
55extern u16 dib0070_wbd_offset(struct dvb_frontend *);
56 62
57#endif 63#endif
diff --git a/drivers/media/dvb/frontends/dib7000m.c b/drivers/media/dvb/frontends/dib7000m.c
index 5f1375e30dfc..0109720353bd 100644
--- a/drivers/media/dvb/frontends/dib7000m.c
+++ b/drivers/media/dvb/frontends/dib7000m.c
@@ -1284,7 +1284,10 @@ struct i2c_adapter * dib7000m_get_i2c_master(struct dvb_frontend *demod, enum di
1284} 1284}
1285EXPORT_SYMBOL(dib7000m_get_i2c_master); 1285EXPORT_SYMBOL(dib7000m_get_i2c_master);
1286 1286
1287int dib7000m_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib7000m_config cfg[]) 1287#if 0
1288/* used with some prototype boards */
1289int dib7000m_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods,
1290 u8 default_addr, struct dib7000m_config cfg[])
1288{ 1291{
1289 struct dib7000m_state st = { .i2c_adap = i2c }; 1292 struct dib7000m_state st = { .i2c_adap = i2c };
1290 int k = 0; 1293 int k = 0;
@@ -1329,6 +1332,7 @@ int dib7000m_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 defau
1329 return 0; 1332 return 0;
1330} 1333}
1331EXPORT_SYMBOL(dib7000m_i2c_enumeration); 1334EXPORT_SYMBOL(dib7000m_i2c_enumeration);
1335#endif
1332 1336
1333static struct dvb_frontend_ops dib7000m_ops; 1337static struct dvb_frontend_ops dib7000m_ops;
1334struct dvb_frontend * dib7000m_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000m_config *cfg) 1338struct dvb_frontend * dib7000m_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000m_config *cfg)
diff --git a/drivers/media/dvb/frontends/dib7000p.c b/drivers/media/dvb/frontends/dib7000p.c
index 1a0142e0d741..8217e5b38f47 100644
--- a/drivers/media/dvb/frontends/dib7000p.c
+++ b/drivers/media/dvb/frontends/dib7000p.c
@@ -1333,7 +1333,8 @@ struct dvb_frontend * dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr,
1333 /* Ensure the output mode remains at the previous default if it's 1333 /* Ensure the output mode remains at the previous default if it's
1334 * not specifically set by the caller. 1334 * not specifically set by the caller.
1335 */ 1335 */
1336 if (st->cfg.output_mode != OUTMODE_MPEG2_SERIAL) 1336 if ((st->cfg.output_mode != OUTMODE_MPEG2_SERIAL) &&
1337 (st->cfg.output_mode != OUTMODE_MPEG2_PAR_GATED_CLK))
1337 st->cfg.output_mode = OUTMODE_MPEG2_FIFO; 1338 st->cfg.output_mode = OUTMODE_MPEG2_FIFO;
1338 1339
1339 demod = &st->demod; 1340 demod = &st->demod;
diff --git a/drivers/media/dvb/frontends/dib7000p.h b/drivers/media/dvb/frontends/dib7000p.h
index 07c4d12ed5b7..3e8126857127 100644
--- a/drivers/media/dvb/frontends/dib7000p.h
+++ b/drivers/media/dvb/frontends/dib7000p.h
@@ -41,6 +41,14 @@ struct dib7000p_config {
41extern struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, 41extern struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap,
42 u8 i2c_addr, 42 u8 i2c_addr,
43 struct dib7000p_config *cfg); 43 struct dib7000p_config *cfg);
44extern struct i2c_adapter *dib7000p_get_i2c_master(struct dvb_frontend *,
45 enum dibx000_i2c_interface,
46 int);
47extern int dib7000p_i2c_enumeration(struct i2c_adapter *i2c,
48 int no_of_demods, u8 default_addr,
49 struct dib7000p_config cfg[]);
50extern int dib7000p_set_gpio(struct dvb_frontend *, u8 num, u8 dir, u8 val);
51extern int dib7000p_set_wbd_ref(struct dvb_frontend *, u16 value);
44#else 52#else
45static inline struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, 53static inline struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap,
46 u8 i2c_addr, 54 u8 i2c_addr,
@@ -49,13 +57,36 @@ static inline struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap,
49 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); 57 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
50 return NULL; 58 return NULL;
51} 59}
52#endif
53 60
54extern int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib7000p_config cfg[]); 61static inline
62struct i2c_adapter *dib7000p_get_i2c_master(struct dvb_frontend *fe,
63 enum dibx000_i2c_interface i, int x)
64{
65 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
66 return NULL;
67}
68
69extern int dib7000p_i2c_enumeration(struct i2c_adapter *i2c,
70 int no_of_demods, u8 default_addr,
71 struct dib7000p_config cfg[])
72{
73 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
74 return -ENODEV;
75}
76
77extern int dib7000p_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val)
78{
79 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
80 return -ENODEV;
81}
82
83extern int dib7000p_set_wbd_ref(struct dvb_frontend *fe, u16 value)
84{
85 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
86 return -ENODEV;
87}
88#endif
55 89
56extern struct i2c_adapter * dib7000p_get_i2c_master(struct dvb_frontend *, enum dibx000_i2c_interface, int);
57extern int dib7000pc_detection(struct i2c_adapter *i2c_adap); 90extern int dib7000pc_detection(struct i2c_adapter *i2c_adap);
58extern int dib7000p_set_gpio(struct dvb_frontend *, u8 num, u8 dir, u8 val);
59extern int dib7000p_set_wbd_ref(struct dvb_frontend *, u16 value);
60 91
61#endif 92#endif
diff --git a/drivers/media/dvb/frontends/drx397xD.c b/drivers/media/dvb/frontends/drx397xD.c
index 3cbed874a6f8..b9ca5c8d2dd9 100644
--- a/drivers/media/dvb/frontends/drx397xD.c
+++ b/drivers/media/dvb/frontends/drx397xD.c
@@ -38,35 +38,32 @@ static const char mod_name[] = "drx397xD";
38#define F_SET_0D0h 1 38#define F_SET_0D0h 1
39#define F_SET_0D4h 2 39#define F_SET_0D4h 2
40 40
41typedef enum fw_ix { 41enum fw_ix {
42#define _FW_ENTRY(a, b) b 42#define _FW_ENTRY(a, b) b
43#include "drx397xD_fw.h" 43#include "drx397xD_fw.h"
44} fw_ix_t; 44};
45 45
46/* chip specifics */ 46/* chip specifics */
47struct drx397xD_state { 47struct drx397xD_state {
48 struct i2c_adapter *i2c; 48 struct i2c_adapter *i2c;
49 struct dvb_frontend frontend; 49 struct dvb_frontend frontend;
50 struct drx397xD_config config; 50 struct drx397xD_config config;
51 fw_ix_t chip_rev; 51 enum fw_ix chip_rev;
52 int flags; 52 int flags;
53 u32 bandwidth_parm; /* internal bandwidth conversions */ 53 u32 bandwidth_parm; /* internal bandwidth conversions */
54 u32 f_osc; /* w90: actual osc frequency [Hz] */ 54 u32 f_osc; /* w90: actual osc frequency [Hz] */
55}; 55};
56 56
57/******************************************************************************* 57/* Firmware */
58 * Firmware
59 ******************************************************************************/
60
61static const char *blob_name[] = { 58static const char *blob_name[] = {
62#define _BLOB_ENTRY(a, b) a 59#define _BLOB_ENTRY(a, b) a
63#include "drx397xD_fw.h" 60#include "drx397xD_fw.h"
64}; 61};
65 62
66typedef enum blob_ix { 63enum blob_ix {
67#define _BLOB_ENTRY(a, b) b 64#define _BLOB_ENTRY(a, b) b
68#include "drx397xD_fw.h" 65#include "drx397xD_fw.h"
69} blob_ix_t; 66};
70 67
71static struct { 68static struct {
72 const char *name; 69 const char *name;
@@ -85,7 +82,7 @@ static struct {
85}; 82};
86 83
87/* use only with writer lock aquired */ 84/* use only with writer lock aquired */
88static void _drx_release_fw(struct drx397xD_state *s, fw_ix_t ix) 85static void _drx_release_fw(struct drx397xD_state *s, enum fw_ix ix)
89{ 86{
90 memset(&fw[ix].data[0], 0, sizeof(fw[0].data)); 87 memset(&fw[ix].data[0], 0, sizeof(fw[0].data));
91 if (fw[ix].file) 88 if (fw[ix].file)
@@ -94,9 +91,9 @@ static void _drx_release_fw(struct drx397xD_state *s, fw_ix_t ix)
94 91
95static void drx_release_fw(struct drx397xD_state *s) 92static void drx_release_fw(struct drx397xD_state *s)
96{ 93{
97 fw_ix_t ix = s->chip_rev; 94 enum fw_ix ix = s->chip_rev;
98 95
99 pr_debug("%s\n", __FUNCTION__); 96 pr_debug("%s\n", __func__);
100 97
101 write_lock(&fw[ix].lock); 98 write_lock(&fw[ix].lock);
102 if (fw[ix].refcnt) { 99 if (fw[ix].refcnt) {
@@ -107,13 +104,13 @@ static void drx_release_fw(struct drx397xD_state *s)
107 write_unlock(&fw[ix].lock); 104 write_unlock(&fw[ix].lock);
108} 105}
109 106
110static int drx_load_fw(struct drx397xD_state *s, fw_ix_t ix) 107static int drx_load_fw(struct drx397xD_state *s, enum fw_ix ix)
111{ 108{
112 const u8 *data; 109 const u8 *data;
113 size_t size, len; 110 size_t size, len;
114 int i = 0, j, rc = -EINVAL; 111 int i = 0, j, rc = -EINVAL;
115 112
116 pr_debug("%s\n", __FUNCTION__); 113 pr_debug("%s\n", __func__);
117 114
118 if (ix < 0 || ix >= ARRAY_SIZE(fw)) 115 if (ix < 0 || ix >= ARRAY_SIZE(fw))
119 return -EINVAL; 116 return -EINVAL;
@@ -175,32 +172,34 @@ static int drx_load_fw(struct drx397xD_state *s, fw_ix_t ix)
175 goto exit_corrupt; 172 goto exit_corrupt;
176 } 173 }
177 } while (i < size); 174 } while (i < size);
178 exit_corrupt: 175
176exit_corrupt:
179 printk(KERN_ERR "%s: Firmware is corrupt\n", mod_name); 177 printk(KERN_ERR "%s: Firmware is corrupt\n", mod_name);
180 exit_err: 178exit_err:
181 _drx_release_fw(s, ix); 179 _drx_release_fw(s, ix);
182 fw[ix].refcnt--; 180 fw[ix].refcnt--;
183 exit_ok: 181exit_ok:
184 fw[ix].refcnt++; 182 fw[ix].refcnt++;
185 write_unlock(&fw[ix].lock); 183 write_unlock(&fw[ix].lock);
184
186 return rc; 185 return rc;
187} 186}
188 187
189/******************************************************************************* 188/* i2c bus IO */
190 * i2c bus IO 189static int write_fw(struct drx397xD_state *s, enum blob_ix ix)
191 ******************************************************************************/
192
193static int write_fw(struct drx397xD_state *s, blob_ix_t ix)
194{ 190{
195 struct i2c_msg msg = {.addr = s->config.demod_address,.flags = 0 };
196 const u8 *data; 191 const u8 *data;
197 int len, rc = 0, i = 0; 192 int len, rc = 0, i = 0;
193 struct i2c_msg msg = {
194 .addr = s->config.demod_address,
195 .flags = 0
196 };
198 197
199 if (ix < 0 || ix >= ARRAY_SIZE(blob_name)) { 198 if (ix < 0 || ix >= ARRAY_SIZE(blob_name)) {
200 pr_debug("%s drx_fw_ix_t out of range\n", __FUNCTION__); 199 pr_debug("%s drx_fw_ix_t out of range\n", __func__);
201 return -EINVAL; 200 return -EINVAL;
202 } 201 }
203 pr_debug("%s %s\n", __FUNCTION__, blob_name[ix]); 202 pr_debug("%s %s\n", __func__, blob_name[ix]);
204 203
205 read_lock(&fw[s->chip_rev].lock); 204 read_lock(&fw[s->chip_rev].lock);
206 data = fw[s->chip_rev].data[ix]; 205 data = fw[s->chip_rev].data[ix];
@@ -229,33 +228,33 @@ static int write_fw(struct drx397xD_state *s, blob_ix_t ix)
229 goto exit_rc; 228 goto exit_rc;
230 } 229 }
231 } 230 }
232 exit_rc: 231exit_rc:
233 read_unlock(&fw[s->chip_rev].lock); 232 read_unlock(&fw[s->chip_rev].lock);
233
234 return 0; 234 return 0;
235} 235}
236 236
237/* Function is not endian safe, use the RD16 wrapper below */ 237/* Function is not endian safe, use the RD16 wrapper below */
238static int _read16(struct drx397xD_state *s, u32 i2c_adr) 238static int _read16(struct drx397xD_state *s, __le32 i2c_adr)
239{ 239{
240 int rc; 240 int rc;
241 u8 a[4]; 241 u8 a[4];
242 u16 v; 242 __le16 v;
243 struct i2c_msg msg[2] = { 243 struct i2c_msg msg[2] = {
244 { 244 {
245 .addr = s->config.demod_address, 245 .addr = s->config.demod_address,
246 .flags = 0, 246 .flags = 0,
247 .buf = a, 247 .buf = a,
248 .len = sizeof(a) 248 .len = sizeof(a)
249 } 249 }, {
250 , { 250 .addr = s->config.demod_address,
251 .addr = s->config.demod_address, 251 .flags = I2C_M_RD,
252 .flags = I2C_M_RD, 252 .buf = (u8 *)&v,
253 .buf = (u8 *) & v, 253 .len = sizeof(v)
254 .len = sizeof(v) 254 }
255 }
256 }; 255 };
257 256
258 *(u32 *) a = i2c_adr; 257 *(__le32 *) a = i2c_adr;
259 258
260 rc = i2c_transfer(s->i2c, msg, 2); 259 rc = i2c_transfer(s->i2c, msg, 2);
261 if (rc != 2) 260 if (rc != 2)
@@ -265,7 +264,7 @@ static int _read16(struct drx397xD_state *s, u32 i2c_adr)
265} 264}
266 265
267/* Function is not endian safe, use the WR16.. wrappers below */ 266/* Function is not endian safe, use the WR16.. wrappers below */
268static int _write16(struct drx397xD_state *s, u32 i2c_adr, u16 val) 267static int _write16(struct drx397xD_state *s, __le32 i2c_adr, __le16 val)
269{ 268{
270 u8 a[6]; 269 u8 a[6];
271 int rc; 270 int rc;
@@ -276,28 +275,28 @@ static int _write16(struct drx397xD_state *s, u32 i2c_adr, u16 val)
276 .len = sizeof(a) 275 .len = sizeof(a)
277 }; 276 };
278 277
279 *(u32 *) a = i2c_adr; 278 *(__le32 *)a = i2c_adr;
280 *(u16 *) & a[4] = val; 279 *(__le16 *)&a[4] = val;
281 280
282 rc = i2c_transfer(s->i2c, &msg, 1); 281 rc = i2c_transfer(s->i2c, &msg, 1);
283 if (rc != 1) 282 if (rc != 1)
284 return -EIO; 283 return -EIO;
284
285 return 0; 285 return 0;
286} 286}
287 287
288#define WR16(ss,adr, val) \ 288#define WR16(ss, adr, val) \
289 _write16(ss, I2C_ADR_C0(adr), cpu_to_le16(val)) 289 _write16(ss, I2C_ADR_C0(adr), cpu_to_le16(val))
290#define WR16_E0(ss,adr, val) \ 290#define WR16_E0(ss, adr, val) \
291 _write16(ss, I2C_ADR_E0(adr), cpu_to_le16(val)) 291 _write16(ss, I2C_ADR_E0(adr), cpu_to_le16(val))
292#define RD16(ss,adr) \ 292#define RD16(ss, adr) \
293 _read16(ss, I2C_ADR_C0(adr)) 293 _read16(ss, I2C_ADR_C0(adr))
294 294
295#define EXIT_RC( cmd ) if ( (rc = (cmd)) < 0) goto exit_rc 295#define EXIT_RC(cmd) \
296 296 if ((rc = (cmd)) < 0) \
297/******************************************************************************* 297 goto exit_rc
298 * Tuner callback
299 ******************************************************************************/
300 298
299/* Tuner callback */
301static int PLL_Set(struct drx397xD_state *s, 300static int PLL_Set(struct drx397xD_state *s,
302 struct dvb_frontend_parameters *fep, int *df_tuner) 301 struct dvb_frontend_parameters *fep, int *df_tuner)
303{ 302{
@@ -305,7 +304,7 @@ static int PLL_Set(struct drx397xD_state *s,
305 u32 f_tuner, f = fep->frequency; 304 u32 f_tuner, f = fep->frequency;
306 int rc; 305 int rc;
307 306
308 pr_debug("%s\n", __FUNCTION__); 307 pr_debug("%s\n", __func__);
309 308
310 if ((f > s->frontend.ops.tuner_ops.info.frequency_max) || 309 if ((f > s->frontend.ops.tuner_ops.info.frequency_max) ||
311 (f < s->frontend.ops.tuner_ops.info.frequency_min)) 310 (f < s->frontend.ops.tuner_ops.info.frequency_min))
@@ -325,28 +324,26 @@ static int PLL_Set(struct drx397xD_state *s,
325 return rc; 324 return rc;
326 325
327 *df_tuner = f_tuner - f; 326 *df_tuner = f_tuner - f;
328 pr_debug("%s requested %d [Hz] tuner %d [Hz]\n", __FUNCTION__, f, 327 pr_debug("%s requested %d [Hz] tuner %d [Hz]\n", __func__, f,
329 f_tuner); 328 f_tuner);
330 329
331 return 0; 330 return 0;
332} 331}
333 332
334/******************************************************************************* 333/* Demodulator helper functions */
335 * Demodulator helper functions
336 ******************************************************************************/
337
338static int SC_WaitForReady(struct drx397xD_state *s) 334static int SC_WaitForReady(struct drx397xD_state *s)
339{ 335{
340 int cnt = 1000; 336 int cnt = 1000;
341 int rc; 337 int rc;
342 338
343 pr_debug("%s\n", __FUNCTION__); 339 pr_debug("%s\n", __func__);
344 340
345 while (cnt--) { 341 while (cnt--) {
346 rc = RD16(s, 0x820043); 342 rc = RD16(s, 0x820043);
347 if (rc == 0) 343 if (rc == 0)
348 return 0; 344 return 0;
349 } 345 }
346
350 return -1; 347 return -1;
351} 348}
352 349
@@ -354,13 +351,14 @@ static int SC_SendCommand(struct drx397xD_state *s, int cmd)
354{ 351{
355 int rc; 352 int rc;
356 353
357 pr_debug("%s\n", __FUNCTION__); 354 pr_debug("%s\n", __func__);
358 355
359 WR16(s, 0x820043, cmd); 356 WR16(s, 0x820043, cmd);
360 SC_WaitForReady(s); 357 SC_WaitForReady(s);
361 rc = RD16(s, 0x820042); 358 rc = RD16(s, 0x820042);
362 if ((rc & 0xffff) == 0xffff) 359 if ((rc & 0xffff) == 0xffff)
363 return -1; 360 return -1;
361
364 return 0; 362 return 0;
365} 363}
366 364
@@ -368,7 +366,7 @@ static int HI_Command(struct drx397xD_state *s, u16 cmd)
368{ 366{
369 int rc, cnt = 1000; 367 int rc, cnt = 1000;
370 368
371 pr_debug("%s\n", __FUNCTION__); 369 pr_debug("%s\n", __func__);
372 370
373 rc = WR16(s, 0x420032, cmd); 371 rc = WR16(s, 0x420032, cmd);
374 if (rc < 0) 372 if (rc < 0)
@@ -383,22 +381,24 @@ static int HI_Command(struct drx397xD_state *s, u16 cmd)
383 if (rc < 0) 381 if (rc < 0)
384 return rc; 382 return rc;
385 } while (--cnt); 383 } while (--cnt);
384
386 return rc; 385 return rc;
387} 386}
388 387
389static int HI_CfgCommand(struct drx397xD_state *s) 388static int HI_CfgCommand(struct drx397xD_state *s)
390{ 389{
391 390
392 pr_debug("%s\n", __FUNCTION__); 391 pr_debug("%s\n", __func__);
393 392
394 WR16(s, 0x420033, 0x3973); 393 WR16(s, 0x420033, 0x3973);
395 WR16(s, 0x420034, s->config.w50); // code 4, log 4 394 WR16(s, 0x420034, s->config.w50); /* code 4, log 4 */
396 WR16(s, 0x420035, s->config.w52); // code 15, log 9 395 WR16(s, 0x420035, s->config.w52); /* code 15, log 9 */
397 WR16(s, 0x420036, s->config.demod_address << 1); 396 WR16(s, 0x420036, s->config.demod_address << 1);
398 WR16(s, 0x420037, s->config.w56); // code (set_i2c ?? initX 1 ), log 1 397 WR16(s, 0x420037, s->config.w56); /* code (set_i2c ?? initX 1 ), log 1 */
399// WR16(s, 0x420033, 0x3973); 398 /* WR16(s, 0x420033, 0x3973); */
400 if ((s->config.w56 & 8) == 0) 399 if ((s->config.w56 & 8) == 0)
401 return HI_Command(s, 3); 400 return HI_Command(s, 3);
401
402 return WR16(s, 0x420032, 0x3); 402 return WR16(s, 0x420032, 0x3);
403} 403}
404 404
@@ -419,7 +419,7 @@ static int SetCfgIfAgc(struct drx397xD_state *s, struct drx397xD_CfgIfAgc *agc)
419 u16 w0C = agc->w0C; 419 u16 w0C = agc->w0C;
420 int quot, rem, i, rc = -EINVAL; 420 int quot, rem, i, rc = -EINVAL;
421 421
422 pr_debug("%s\n", __FUNCTION__); 422 pr_debug("%s\n", __func__);
423 423
424 if (agc->w04 > 0x3ff) 424 if (agc->w04 > 0x3ff)
425 goto exit_rc; 425 goto exit_rc;
@@ -468,7 +468,7 @@ static int SetCfgIfAgc(struct drx397xD_state *s, struct drx397xD_CfgIfAgc *agc)
468 i = slowIncrDecLUT_15272[rem / 28]; 468 i = slowIncrDecLUT_15272[rem / 28];
469 EXIT_RC(WR16(s, 0x0c2002b, i)); 469 EXIT_RC(WR16(s, 0x0c2002b, i));
470 rc = WR16(s, 0x0c2002c, i); 470 rc = WR16(s, 0x0c2002c, i);
471 exit_rc: 471exit_rc:
472 return rc; 472 return rc;
473} 473}
474 474
@@ -478,7 +478,7 @@ static int SetCfgRfAgc(struct drx397xD_state *s, struct drx397xD_CfgRfAgc *agc)
478 u16 w06 = agc->w06; 478 u16 w06 = agc->w06;
479 int rc = -1; 479 int rc = -1;
480 480
481 pr_debug("%s %d 0x%x 0x%x\n", __FUNCTION__, agc->d00, w04, w06); 481 pr_debug("%s %d 0x%x 0x%x\n", __func__, agc->d00, w04, w06);
482 482
483 if (w04 > 0x3ff) 483 if (w04 > 0x3ff)
484 goto exit_rc; 484 goto exit_rc;
@@ -498,7 +498,7 @@ static int SetCfgRfAgc(struct drx397xD_state *s, struct drx397xD_CfgRfAgc *agc)
498 rc &= ~2; 498 rc &= ~2;
499 break; 499 break;
500 case 0: 500 case 0:
501 // loc_8000659 501 /* loc_8000659 */
502 s->config.w9C &= ~2; 502 s->config.w9C &= ~2;
503 EXIT_RC(WR16(s, 0x0c20015, s->config.w9C)); 503 EXIT_RC(WR16(s, 0x0c20015, s->config.w9C));
504 EXIT_RC(RD16(s, 0x0c20010)); 504 EXIT_RC(RD16(s, 0x0c20010));
@@ -522,7 +522,8 @@ static int SetCfgRfAgc(struct drx397xD_state *s, struct drx397xD_CfgRfAgc *agc)
522 rc |= 2; 522 rc |= 2;
523 } 523 }
524 rc = WR16(s, 0x0c20013, rc); 524 rc = WR16(s, 0x0c20013, rc);
525 exit_rc: 525
526exit_rc:
526 return rc; 527 return rc;
527} 528}
528 529
@@ -554,7 +555,7 @@ static int CorrectSysClockDeviation(struct drx397xD_state *s)
554 int lockstat; 555 int lockstat;
555 u32 clk, clk_limit; 556 u32 clk, clk_limit;
556 557
557 pr_debug("%s\n", __FUNCTION__); 558 pr_debug("%s\n", __func__);
558 559
559 if (s->config.d5C == 0) { 560 if (s->config.d5C == 0) {
560 EXIT_RC(WR16(s, 0x08200e8, 0x010)); 561 EXIT_RC(WR16(s, 0x08200e8, 0x010));
@@ -598,11 +599,12 @@ static int CorrectSysClockDeviation(struct drx397xD_state *s)
598 599
599 if (clk - s->config.f_osc * 1000 + clk_limit <= 2 * clk_limit) { 600 if (clk - s->config.f_osc * 1000 + clk_limit <= 2 * clk_limit) {
600 s->f_osc = clk; 601 s->f_osc = clk;
601 pr_debug("%s: osc %d %d [Hz]\n", __FUNCTION__, 602 pr_debug("%s: osc %d %d [Hz]\n", __func__,
602 s->config.f_osc * 1000, clk - s->config.f_osc * 1000); 603 s->config.f_osc * 1000, clk - s->config.f_osc * 1000);
603 } 604 }
604 rc = WR16(s, 0x08200e8, 0); 605 rc = WR16(s, 0x08200e8, 0);
605 exit_rc: 606
607exit_rc:
606 return rc; 608 return rc;
607} 609}
608 610
@@ -610,7 +612,7 @@ static int ConfigureMPEGOutput(struct drx397xD_state *s, int type)
610{ 612{
611 int rc, si, bp; 613 int rc, si, bp;
612 614
613 pr_debug("%s\n", __FUNCTION__); 615 pr_debug("%s\n", __func__);
614 616
615 si = s->config.wA0; 617 si = s->config.wA0;
616 if (s->config.w98 == 0) { 618 if (s->config.w98 == 0) {
@@ -620,17 +622,17 @@ static int ConfigureMPEGOutput(struct drx397xD_state *s, int type)
620 si &= ~1; 622 si &= ~1;
621 bp = 0x200; 623 bp = 0x200;
622 } 624 }
623 if (s->config.w9A == 0) { 625 if (s->config.w9A == 0)
624 si |= 0x80; 626 si |= 0x80;
625 } else { 627 else
626 si &= ~0x80; 628 si &= ~0x80;
627 }
628 629
629 EXIT_RC(WR16(s, 0x2150045, 0)); 630 EXIT_RC(WR16(s, 0x2150045, 0));
630 EXIT_RC(WR16(s, 0x2150010, si)); 631 EXIT_RC(WR16(s, 0x2150010, si));
631 EXIT_RC(WR16(s, 0x2150011, bp)); 632 EXIT_RC(WR16(s, 0x2150011, bp));
632 rc = WR16(s, 0x2150012, (type == 0 ? 0xfff : 0)); 633 rc = WR16(s, 0x2150012, (type == 0 ? 0xfff : 0));
633 exit_rc: 634
635exit_rc:
634 return rc; 636 return rc;
635} 637}
636 638
@@ -646,7 +648,7 @@ static int drx_tune(struct drx397xD_state *s,
646 648
647 int rc, df_tuner; 649 int rc, df_tuner;
648 int a, b, c, d; 650 int a, b, c, d;
649 pr_debug("%s %d\n", __FUNCTION__, s->config.d60); 651 pr_debug("%s %d\n", __func__, s->config.d60);
650 652
651 if (s->config.d60 != 2) 653 if (s->config.d60 != 2)
652 goto set_tuner; 654 goto set_tuner;
@@ -658,7 +660,7 @@ static int drx_tune(struct drx397xD_state *s,
658 rc = ConfigureMPEGOutput(s, 0); 660 rc = ConfigureMPEGOutput(s, 0);
659 if (rc < 0) 661 if (rc < 0)
660 goto set_tuner; 662 goto set_tuner;
661 set_tuner: 663set_tuner:
662 664
663 rc = PLL_Set(s, fep, &df_tuner); 665 rc = PLL_Set(s, fep, &df_tuner);
664 if (rc < 0) { 666 if (rc < 0) {
@@ -835,16 +837,16 @@ static int drx_tune(struct drx397xD_state *s,
835 rc = WR16(s, 0x2010012, 0); 837 rc = WR16(s, 0x2010012, 0);
836 if (rc < 0) 838 if (rc < 0)
837 goto exit_rc; 839 goto exit_rc;
838 // QPSK QAM16 QAM64 840 /* QPSK QAM16 QAM64 */
839 ebx = 0x19f; // 62 841 ebx = 0x19f; /* 62 */
840 ebp = 0x1fb; // 15 842 ebp = 0x1fb; /* 15 */
841 v20 = 0x16a; // 62 843 v20 = 0x16a; /* 62 */
842 v1E = 0x195; // 62 844 v1E = 0x195; /* 62 */
843 v16 = 0x1bb; // 15 845 v16 = 0x1bb; /* 15 */
844 v14 = 0x1ef; // 15 846 v14 = 0x1ef; /* 15 */
845 v12 = 5; // 16 847 v12 = 5; /* 16 */
846 v10 = 5; // 16 848 v10 = 5; /* 16 */
847 v0E = 5; // 16 849 v0E = 5; /* 16 */
848 } 850 }
849 851
850 switch (fep->u.ofdm.constellation) { 852 switch (fep->u.ofdm.constellation) {
@@ -997,17 +999,17 @@ static int drx_tune(struct drx397xD_state *s,
997 case BANDWIDTH_8_MHZ: /* 0 */ 999 case BANDWIDTH_8_MHZ: /* 0 */
998 case BANDWIDTH_AUTO: 1000 case BANDWIDTH_AUTO:
999 rc = WR16(s, 0x0c2003f, 0x32); 1001 rc = WR16(s, 0x0c2003f, 0x32);
1000 s->bandwidth_parm = ebx = 0x8b8249; // 9142857 1002 s->bandwidth_parm = ebx = 0x8b8249;
1001 edx = 0; 1003 edx = 0;
1002 break; 1004 break;
1003 case BANDWIDTH_7_MHZ: 1005 case BANDWIDTH_7_MHZ:
1004 rc = WR16(s, 0x0c2003f, 0x3b); 1006 rc = WR16(s, 0x0c2003f, 0x3b);
1005 s->bandwidth_parm = ebx = 0x7a1200; // 8000000 1007 s->bandwidth_parm = ebx = 0x7a1200;
1006 edx = 0x4807; 1008 edx = 0x4807;
1007 break; 1009 break;
1008 case BANDWIDTH_6_MHZ: 1010 case BANDWIDTH_6_MHZ:
1009 rc = WR16(s, 0x0c2003f, 0x47); 1011 rc = WR16(s, 0x0c2003f, 0x47);
1010 s->bandwidth_parm = ebx = 0x68a1b6; // 6857142 1012 s->bandwidth_parm = ebx = 0x68a1b6;
1011 edx = 0x0f07; 1013 edx = 0x0f07;
1012 break; 1014 break;
1013 }; 1015 };
@@ -1060,8 +1062,6 @@ static int drx_tune(struct drx397xD_state *s,
1060 WR16(s, 0x0820040, 1); 1062 WR16(s, 0x0820040, 1);
1061 SC_SendCommand(s, 1); 1063 SC_SendCommand(s, 1);
1062 1064
1063// rc = WR16(s, 0x2150000, 1);
1064// if (rc < 0) goto exit_rc;
1065 1065
1066 rc = WR16(s, 0x2150000, 2); 1066 rc = WR16(s, 0x2150000, 2);
1067 rc = WR16(s, 0x2150016, a); 1067 rc = WR16(s, 0x2150016, a);
@@ -1069,7 +1069,8 @@ static int drx_tune(struct drx397xD_state *s,
1069 rc = WR16(s, 0x2150036, 0); 1069 rc = WR16(s, 0x2150036, 0);
1070 rc = WR16(s, 0x2150000, 1); 1070 rc = WR16(s, 0x2150000, 1);
1071 s->config.d60 = 2; 1071 s->config.d60 = 2;
1072 exit_rc: 1072
1073exit_rc:
1073 return rc; 1074 return rc;
1074} 1075}
1075 1076
@@ -1082,7 +1083,7 @@ static int drx397x_init(struct dvb_frontend *fe)
1082 struct drx397xD_state *s = fe->demodulator_priv; 1083 struct drx397xD_state *s = fe->demodulator_priv;
1083 int rc; 1084 int rc;
1084 1085
1085 pr_debug("%s\n", __FUNCTION__); 1086 pr_debug("%s\n", __func__);
1086 1087
1087 s->config.rfagc.d00 = 2; /* 0x7c */ 1088 s->config.rfagc.d00 = 2; /* 0x7c */
1088 s->config.rfagc.w04 = 0; 1089 s->config.rfagc.w04 = 0;
@@ -1102,18 +1103,18 @@ static int drx397x_init(struct dvb_frontend *fe)
1102 1103
1103 /* HI_CfgCommand */ 1104 /* HI_CfgCommand */
1104 s->config.w50 = 4; 1105 s->config.w50 = 4;
1105 s->config.w52 = 9; // 0xf; 1106 s->config.w52 = 9;
1106 1107
1107 s->config.f_if = 42800000; /* d14: intermediate frequency [Hz] */ 1108 s->config.f_if = 42800000; /* d14: intermediate frequency [Hz] */
1108 s->config.f_osc = 48000; /* s66 : oscillator frequency [kHz] */ 1109 s->config.f_osc = 48000; /* s66 : oscillator frequency [kHz] */
1109 s->config.w92 = 12000; // 20000; 1110 s->config.w92 = 12000;
1110 1111
1111 s->config.w9C = 0x000e; 1112 s->config.w9C = 0x000e;
1112 s->config.w9E = 0x0000; 1113 s->config.w9E = 0x0000;
1113 1114
1114 /* ConfigureMPEGOutput params */ 1115 /* ConfigureMPEGOutput params */
1115 s->config.wA0 = 4; 1116 s->config.wA0 = 4;
1116 s->config.w98 = 1; // 0; 1117 s->config.w98 = 1;
1117 s->config.w9A = 1; 1118 s->config.w9A = 1;
1118 1119
1119 /* get chip revision */ 1120 /* get chip revision */
@@ -1248,7 +1249,7 @@ static int drx397x_init(struct dvb_frontend *fe)
1248 rc = WR16(s, 0x0c20012, 1); 1249 rc = WR16(s, 0x0c20012, 1);
1249 } 1250 }
1250 1251
1251 write_DRXD_InitFE_1: 1252write_DRXD_InitFE_1:
1252 1253
1253 rc = write_fw(s, DRXD_InitFE_1); 1254 rc = write_fw(s, DRXD_InitFE_1);
1254 if (rc < 0) 1255 if (rc < 0)
@@ -1311,7 +1312,8 @@ static int drx397x_init(struct dvb_frontend *fe)
1311 s->config.d5C = 0; 1312 s->config.d5C = 0;
1312 s->config.d60 = 1; 1313 s->config.d60 = 1;
1313 s->config.d48 = 1; 1314 s->config.d48 = 1;
1314 error: 1315
1316error:
1315 return rc; 1317 return rc;
1316} 1318}
1317 1319
@@ -1326,7 +1328,8 @@ static int drx397x_set_frontend(struct dvb_frontend *fe,
1326{ 1328{
1327 struct drx397xD_state *s = fe->demodulator_priv; 1329 struct drx397xD_state *s = fe->demodulator_priv;
1328 1330
1329 s->config.s20d24 = 1; // 0; 1331 s->config.s20d24 = 1;
1332
1330 return drx_tune(s, params); 1333 return drx_tune(s, params);
1331} 1334}
1332 1335
@@ -1337,18 +1340,16 @@ static int drx397x_get_tune_settings(struct dvb_frontend *fe,
1337 fe_tune_settings->min_delay_ms = 10000; 1340 fe_tune_settings->min_delay_ms = 10000;
1338 fe_tune_settings->step_size = 0; 1341 fe_tune_settings->step_size = 0;
1339 fe_tune_settings->max_drift = 0; 1342 fe_tune_settings->max_drift = 0;
1343
1340 return 0; 1344 return 0;
1341} 1345}
1342 1346
1343static int drx397x_read_status(struct dvb_frontend *fe, fe_status_t * status) 1347static int drx397x_read_status(struct dvb_frontend *fe, fe_status_t *status)
1344{ 1348{
1345 struct drx397xD_state *s = fe->demodulator_priv; 1349 struct drx397xD_state *s = fe->demodulator_priv;
1346 int lockstat; 1350 int lockstat;
1347 1351
1348 GetLockStatus(s, &lockstat); 1352 GetLockStatus(s, &lockstat);
1349 /* TODO */
1350// if (lockstat & 1)
1351// CorrectSysClockDeviation(s);
1352 1353
1353 *status = 0; 1354 *status = 0;
1354 if (lockstat & 2) { 1355 if (lockstat & 2) {
@@ -1356,9 +1357,8 @@ static int drx397x_read_status(struct dvb_frontend *fe, fe_status_t * status)
1356 ConfigureMPEGOutput(s, 1); 1357 ConfigureMPEGOutput(s, 1);
1357 *status = FE_HAS_LOCK | FE_HAS_SYNC | FE_HAS_VITERBI; 1358 *status = FE_HAS_LOCK | FE_HAS_SYNC | FE_HAS_VITERBI;
1358 } 1359 }
1359 if (lockstat & 4) { 1360 if (lockstat & 4)
1360 *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL; 1361 *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL;
1361 }
1362 1362
1363 return 0; 1363 return 0;
1364} 1364}
@@ -1366,16 +1366,18 @@ static int drx397x_read_status(struct dvb_frontend *fe, fe_status_t * status)
1366static int drx397x_read_ber(struct dvb_frontend *fe, unsigned int *ber) 1366static int drx397x_read_ber(struct dvb_frontend *fe, unsigned int *ber)
1367{ 1367{
1368 *ber = 0; 1368 *ber = 0;
1369
1369 return 0; 1370 return 0;
1370} 1371}
1371 1372
1372static int drx397x_read_snr(struct dvb_frontend *fe, u16 * snr) 1373static int drx397x_read_snr(struct dvb_frontend *fe, u16 *snr)
1373{ 1374{
1374 *snr = 0; 1375 *snr = 0;
1376
1375 return 0; 1377 return 0;
1376} 1378}
1377 1379
1378static int drx397x_read_signal_strength(struct dvb_frontend *fe, u16 * strength) 1380static int drx397x_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
1379{ 1381{
1380 struct drx397xD_state *s = fe->demodulator_priv; 1382 struct drx397xD_state *s = fe->demodulator_priv;
1381 int rc; 1383 int rc;
@@ -1401,6 +1403,7 @@ static int drx397x_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
1401 * The following does the same but with less rounding errors: 1403 * The following does the same but with less rounding errors:
1402 */ 1404 */
1403 *strength = ~(7720 + (rc * 30744 >> 10)); 1405 *strength = ~(7720 + (rc * 30744 >> 10));
1406
1404 return 0; 1407 return 0;
1405} 1408}
1406 1409
@@ -1408,6 +1411,7 @@ static int drx397x_read_ucblocks(struct dvb_frontend *fe,
1408 unsigned int *ucblocks) 1411 unsigned int *ucblocks)
1409{ 1412{
1410 *ucblocks = 0; 1413 *ucblocks = 0;
1414
1411 return 0; 1415 return 0;
1412} 1416}
1413 1417
@@ -1436,22 +1440,22 @@ static struct dvb_frontend_ops drx397x_ops = {
1436 .frequency_max = 855250000, 1440 .frequency_max = 855250000,
1437 .frequency_stepsize = 166667, 1441 .frequency_stepsize = 166667,
1438 .frequency_tolerance = 0, 1442 .frequency_tolerance = 0,
1439 .caps = /* 0x0C01B2EAE */ 1443 .caps = /* 0x0C01B2EAE */
1440 FE_CAN_FEC_1_2 | // = 0x2, 1444 FE_CAN_FEC_1_2 | /* = 0x2, */
1441 FE_CAN_FEC_2_3 | // = 0x4, 1445 FE_CAN_FEC_2_3 | /* = 0x4, */
1442 FE_CAN_FEC_3_4 | // = 0x8, 1446 FE_CAN_FEC_3_4 | /* = 0x8, */
1443 FE_CAN_FEC_5_6 | // = 0x20, 1447 FE_CAN_FEC_5_6 | /* = 0x20, */
1444 FE_CAN_FEC_7_8 | // = 0x80, 1448 FE_CAN_FEC_7_8 | /* = 0x80, */
1445 FE_CAN_FEC_AUTO | // = 0x200, 1449 FE_CAN_FEC_AUTO | /* = 0x200, */
1446 FE_CAN_QPSK | // = 0x400, 1450 FE_CAN_QPSK | /* = 0x400, */
1447 FE_CAN_QAM_16 | // = 0x800, 1451 FE_CAN_QAM_16 | /* = 0x800, */
1448 FE_CAN_QAM_64 | // = 0x2000, 1452 FE_CAN_QAM_64 | /* = 0x2000, */
1449 FE_CAN_QAM_AUTO | // = 0x10000, 1453 FE_CAN_QAM_AUTO | /* = 0x10000, */
1450 FE_CAN_TRANSMISSION_MODE_AUTO | // = 0x20000, 1454 FE_CAN_TRANSMISSION_MODE_AUTO | /* = 0x20000, */
1451 FE_CAN_GUARD_INTERVAL_AUTO | // = 0x80000, 1455 FE_CAN_GUARD_INTERVAL_AUTO | /* = 0x80000, */
1452 FE_CAN_HIERARCHY_AUTO | // = 0x100000, 1456 FE_CAN_HIERARCHY_AUTO | /* = 0x100000, */
1453 FE_CAN_RECOVER | // = 0x40000000, 1457 FE_CAN_RECOVER | /* = 0x40000000, */
1454 FE_CAN_MUTE_TS // = 0x80000000 1458 FE_CAN_MUTE_TS /* = 0x80000000 */
1455 }, 1459 },
1456 1460
1457 .release = drx397x_release, 1461 .release = drx397x_release,
@@ -1472,33 +1476,35 @@ static struct dvb_frontend_ops drx397x_ops = {
1472struct dvb_frontend *drx397xD_attach(const struct drx397xD_config *config, 1476struct dvb_frontend *drx397xD_attach(const struct drx397xD_config *config,
1473 struct i2c_adapter *i2c) 1477 struct i2c_adapter *i2c)
1474{ 1478{
1475 struct drx397xD_state *s = NULL; 1479 struct drx397xD_state *state;
1476 1480
1477 /* allocate memory for the internal state */ 1481 /* allocate memory for the internal state */
1478 s = kzalloc(sizeof(struct drx397xD_state), GFP_KERNEL); 1482 state = kzalloc(sizeof(struct drx397xD_state), GFP_KERNEL);
1479 if (s == NULL) 1483 if (!state)
1480 goto error; 1484 goto error;
1481 1485
1482 /* setup the state */ 1486 /* setup the state */
1483 s->i2c = i2c; 1487 state->i2c = i2c;
1484 memcpy(&s->config, config, sizeof(struct drx397xD_config)); 1488 memcpy(&state->config, config, sizeof(struct drx397xD_config));
1485 1489
1486 /* check if the demod is there */ 1490 /* check if the demod is there */
1487 if (RD16(s, 0x2410019) < 0) 1491 if (RD16(state, 0x2410019) < 0)
1488 goto error; 1492 goto error;
1489 1493
1490 /* create dvb_frontend */ 1494 /* create dvb_frontend */
1491 memcpy(&s->frontend.ops, &drx397x_ops, sizeof(struct dvb_frontend_ops)); 1495 memcpy(&state->frontend.ops, &drx397x_ops,
1492 s->frontend.demodulator_priv = s; 1496 sizeof(struct dvb_frontend_ops));
1497 state->frontend.demodulator_priv = state;
1498
1499 return &state->frontend;
1500error:
1501 kfree(state);
1493 1502
1494 return &s->frontend;
1495 error:
1496 kfree(s);
1497 return NULL; 1503 return NULL;
1498} 1504}
1505EXPORT_SYMBOL(drx397xD_attach);
1499 1506
1500MODULE_DESCRIPTION("Micronas DRX397xD DVB-T Frontend"); 1507MODULE_DESCRIPTION("Micronas DRX397xD DVB-T Frontend");
1501MODULE_AUTHOR("Henk Vergonet"); 1508MODULE_AUTHOR("Henk Vergonet");
1502MODULE_LICENSE("GPL"); 1509MODULE_LICENSE("GPL");
1503 1510
1504EXPORT_SYMBOL(drx397xD_attach);
diff --git a/drivers/media/dvb/frontends/drx397xD.h b/drivers/media/dvb/frontends/drx397xD.h
index ddc7a07971b7..ba05d17290c6 100644
--- a/drivers/media/dvb/frontends/drx397xD.h
+++ b/drivers/media/dvb/frontends/drx397xD.h
@@ -28,7 +28,7 @@
28#define DRX_F_OFFSET 36000000 28#define DRX_F_OFFSET 36000000
29 29
30#define I2C_ADR_C0(x) \ 30#define I2C_ADR_C0(x) \
31( (u32)cpu_to_le32( \ 31( cpu_to_le32( \
32 (u32)( \ 32 (u32)( \
33 (((u32)(x) & (u32)0x000000ffUL) ) | \ 33 (((u32)(x) & (u32)0x000000ffUL) ) | \
34 (((u32)(x) & (u32)0x0000ff00UL) << 16) | \ 34 (((u32)(x) & (u32)0x0000ff00UL) << 16) | \
@@ -38,7 +38,7 @@
38) 38)
39 39
40#define I2C_ADR_E0(x) \ 40#define I2C_ADR_E0(x) \
41( (u32)cpu_to_le32( \ 41( cpu_to_le32( \
42 (u32)( \ 42 (u32)( \
43 (((u32)(x) & (u32)0x000000ffUL) ) | \ 43 (((u32)(x) & (u32)0x000000ffUL) ) | \
44 (((u32)(x) & (u32)0x0000ff00UL) << 16) | \ 44 (((u32)(x) & (u32)0x0000ff00UL) << 16) | \
@@ -122,7 +122,7 @@ extern struct dvb_frontend* drx397xD_attach(const struct drx397xD_config *config
122static inline struct dvb_frontend* drx397xD_attach(const struct drx397xD_config *config, 122static inline struct dvb_frontend* drx397xD_attach(const struct drx397xD_config *config,
123 struct i2c_adapter *i2c) 123 struct i2c_adapter *i2c)
124{ 124{
125 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); 125 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
126 return NULL; 126 return NULL;
127} 127}
128#endif /* CONFIG_DVB_DRX397XD */ 128#endif /* CONFIG_DVB_DRX397XD */
diff --git a/drivers/media/dvb/frontends/dvb_dummy_fe.c b/drivers/media/dvb/frontends/dvb_dummy_fe.c
index fed09dfb2b7c..db8a937cc630 100644
--- a/drivers/media/dvb/frontends/dvb_dummy_fe.c
+++ b/drivers/media/dvb/frontends/dvb_dummy_fe.c
@@ -75,9 +75,10 @@ static int dvb_dummy_fe_get_frontend(struct dvb_frontend* fe, struct dvb_fronten
75 75
76static int dvb_dummy_fe_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) 76static int dvb_dummy_fe_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
77{ 77{
78 if (fe->ops->tuner_ops->set_params) { 78 if (fe->ops.tuner_ops.set_params) {
79 fe->ops->tuner_ops->set_params(fe, p); 79 fe->ops.tuner_ops.set_params(fe, p);
80 if (fe->ops->i2c_gate_ctrl) fe->ops->i2c_gate_ctrl(fe, 0); 80 if (fe->ops.i2c_gate_ctrl)
81 fe->ops.i2c_gate_ctrl(fe, 0);
81 } 82 }
82 83
83 return 0; 84 return 0;
@@ -131,7 +132,7 @@ error:
131 132
132static struct dvb_frontend_ops dvb_dummy_fe_qpsk_ops; 133static struct dvb_frontend_ops dvb_dummy_fe_qpsk_ops;
133 134
134struct dvb_frontend* dvb_dummy_fe_qpsk_attach() 135struct dvb_frontend *dvb_dummy_fe_qpsk_attach(void)
135{ 136{
136 struct dvb_dummy_fe_state* state = NULL; 137 struct dvb_dummy_fe_state* state = NULL;
137 138
@@ -151,7 +152,7 @@ error:
151 152
152static struct dvb_frontend_ops dvb_dummy_fe_qam_ops; 153static struct dvb_frontend_ops dvb_dummy_fe_qam_ops;
153 154
154struct dvb_frontend* dvb_dummy_fe_qam_attach() 155struct dvb_frontend *dvb_dummy_fe_qam_attach(void)
155{ 156{
156 struct dvb_dummy_fe_state* state = NULL; 157 struct dvb_dummy_fe_state* state = NULL;
157 158
diff --git a/drivers/media/dvb/frontends/eds1547.h b/drivers/media/dvb/frontends/eds1547.h
new file mode 100644
index 000000000000..fa79b7c83dd2
--- /dev/null
+++ b/drivers/media/dvb/frontends/eds1547.h
@@ -0,0 +1,133 @@
1/* eds1547.h Earda EDS-1547 tuner support
2*
3* Copyright (C) 2008 Igor M. Liplianin (liplianin@me.by)
4*
5* This program is free software; you can redistribute it and/or modify it
6* under the terms of the GNU General Public License as published by the
7* Free Software Foundation, version 2.
8*
9* see Documentation/dvb/README.dvb-usb for more information
10*/
11
12#ifndef EDS1547
13#define EDS1547
14
15static u8 stv0288_earda_inittab[] = {
16 0x01, 0x57,
17 0x02, 0x20,
18 0x03, 0x8e,
19 0x04, 0x8e,
20 0x05, 0x12,
21 0x06, 0x00,
22 0x07, 0x00,
23 0x09, 0x00,
24 0x0a, 0x04,
25 0x0b, 0x00,
26 0x0c, 0x00,
27 0x0d, 0x00,
28 0x0e, 0xd4,
29 0x0f, 0x30,
30 0x11, 0x44,
31 0x12, 0x03,
32 0x13, 0x48,
33 0x14, 0x84,
34 0x15, 0x45,
35 0x16, 0xb7,
36 0x17, 0x9c,
37 0x18, 0x00,
38 0x19, 0xa6,
39 0x1a, 0x88,
40 0x1b, 0x8f,
41 0x1c, 0xf0,
42 0x20, 0x0b,
43 0x21, 0x54,
44 0x22, 0x00,
45 0x23, 0x00,
46 0x2b, 0xff,
47 0x2c, 0xf7,
48 0x30, 0x00,
49 0x31, 0x1e,
50 0x32, 0x14,
51 0x33, 0x0f,
52 0x34, 0x09,
53 0x35, 0x0c,
54 0x36, 0x05,
55 0x37, 0x2f,
56 0x38, 0x16,
57 0x39, 0xbd,
58 0x3a, 0x00,
59 0x3b, 0x13,
60 0x3c, 0x11,
61 0x3d, 0x30,
62 0x40, 0x63,
63 0x41, 0x04,
64 0x42, 0x60,
65 0x43, 0x00,
66 0x44, 0x00,
67 0x45, 0x00,
68 0x46, 0x00,
69 0x47, 0x00,
70 0x4a, 0x00,
71 0x50, 0x10,
72 0x51, 0x36,
73 0x52, 0x09,
74 0x53, 0x94,
75 0x54, 0x62,
76 0x55, 0x29,
77 0x56, 0x64,
78 0x57, 0x2b,
79 0x58, 0x54,
80 0x59, 0x86,
81 0x5a, 0x00,
82 0x5b, 0x9b,
83 0x5c, 0x08,
84 0x5d, 0x7f,
85 0x5e, 0x00,
86 0x5f, 0xff,
87 0x70, 0x00,
88 0x71, 0x00,
89 0x72, 0x00,
90 0x74, 0x00,
91 0x75, 0x00,
92 0x76, 0x00,
93 0x81, 0x00,
94 0x82, 0x3f,
95 0x83, 0x3f,
96 0x84, 0x00,
97 0x85, 0x00,
98 0x88, 0x00,
99 0x89, 0x00,
100 0x8a, 0x00,
101 0x8b, 0x00,
102 0x8c, 0x00,
103 0x90, 0x00,
104 0x91, 0x00,
105 0x92, 0x00,
106 0x93, 0x00,
107 0x94, 0x1c,
108 0x97, 0x00,
109 0xa0, 0x48,
110 0xa1, 0x00,
111 0xb0, 0xb8,
112 0xb1, 0x3a,
113 0xb2, 0x10,
114 0xb3, 0x82,
115 0xb4, 0x80,
116 0xb5, 0x82,
117 0xb6, 0x82,
118 0xb7, 0x82,
119 0xb8, 0x20,
120 0xb9, 0x00,
121 0xf0, 0x00,
122 0xf1, 0x00,
123 0xf2, 0xc0,
124 0xff,0xff,
125};
126
127static struct stv0288_config earda_config = {
128 .demod_address = 0x68,
129 .min_delay_ms = 100,
130 .inittab = stv0288_earda_inittab,
131};
132
133#endif
diff --git a/drivers/media/dvb/frontends/lgs8gl5.c b/drivers/media/dvb/frontends/lgs8gl5.c
new file mode 100644
index 000000000000..855852fddf22
--- /dev/null
+++ b/drivers/media/dvb/frontends/lgs8gl5.c
@@ -0,0 +1,454 @@
1/*
2 Legend Silicon LGS-8GL5 DMB-TH OFDM demodulator driver
3
4 Copyright (C) 2008 Sirius International (Hong Kong) Limited
5 Timothy Lee <timothy.lee@siriushk.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/kernel.h>
24#include <linux/init.h>
25#include <linux/module.h>
26#include <linux/string.h>
27#include <linux/slab.h>
28#include "dvb_frontend.h"
29#include "lgs8gl5.h"
30
31
32#define REG_RESET 0x02
33#define REG_RESET_OFF 0x01
34#define REG_03 0x03
35#define REG_04 0x04
36#define REG_07 0x07
37#define REG_09 0x09
38#define REG_0A 0x0a
39#define REG_0B 0x0b
40#define REG_0C 0x0c
41#define REG_37 0x37
42#define REG_STRENGTH 0x4b
43#define REG_STRENGTH_MASK 0x7f
44#define REG_STRENGTH_CARRIER 0x80
45#define REG_INVERSION 0x7c
46#define REG_INVERSION_ON 0x80
47#define REG_7D 0x7d
48#define REG_7E 0x7e
49#define REG_A2 0xa2
50#define REG_STATUS 0xa4
51#define REG_STATUS_SYNC 0x04
52#define REG_STATUS_LOCK 0x01
53
54
55struct lgs8gl5_state {
56 struct i2c_adapter *i2c;
57 const struct lgs8gl5_config *config;
58 struct dvb_frontend frontend;
59};
60
61
62static int debug;
63#define dprintk(args...) \
64 do { \
65 if (debug) \
66 printk(KERN_DEBUG "lgs8gl5: " args); \
67 } while (0)
68
69
70/* Writes into demod's register */
71static int
72lgs8gl5_write_reg(struct lgs8gl5_state *state, u8 reg, u8 data)
73{
74 int ret;
75 u8 buf[] = {reg, data};
76 struct i2c_msg msg = {
77 .addr = state->config->demod_address,
78 .flags = 0,
79 .buf = buf,
80 .len = 2
81 };
82
83 ret = i2c_transfer(state->i2c, &msg, 1);
84 if (ret != 1)
85 dprintk("%s: error (reg=0x%02x, val=0x%02x, ret=%i)\n",
86 __func__, reg, data, ret);
87 return (ret != 1) ? -1 : 0;
88}
89
90
91/* Reads from demod's register */
92static int
93lgs8gl5_read_reg(struct lgs8gl5_state *state, u8 reg)
94{
95 int ret;
96 u8 b0[] = {reg};
97 u8 b1[] = {0};
98 struct i2c_msg msg[2] = {
99 {
100 .addr = state->config->demod_address,
101 .flags = 0,
102 .buf = b0,
103 .len = 1
104 },
105 {
106 .addr = state->config->demod_address,
107 .flags = I2C_M_RD,
108 .buf = b1,
109 .len = 1
110 }
111 };
112
113 ret = i2c_transfer(state->i2c, msg, 2);
114 if (ret != 2)
115 return -EIO;
116
117 return b1[0];
118}
119
120
121static int
122lgs8gl5_update_reg(struct lgs8gl5_state *state, u8 reg, u8 data)
123{
124 lgs8gl5_read_reg(state, reg);
125 lgs8gl5_write_reg(state, reg, data);
126 return 0;
127}
128
129
130/* Writes into alternate device's register */
131/* TODO: Find out what that device is for! */
132static int
133lgs8gl5_update_alt_reg(struct lgs8gl5_state *state, u8 reg, u8 data)
134{
135 int ret;
136 u8 b0[] = {reg};
137 u8 b1[] = {0};
138 u8 b2[] = {reg, data};
139 struct i2c_msg msg[3] = {
140 {
141 .addr = state->config->demod_address + 2,
142 .flags = 0,
143 .buf = b0,
144 .len = 1
145 },
146 {
147 .addr = state->config->demod_address + 2,
148 .flags = I2C_M_RD,
149 .buf = b1,
150 .len = 1
151 },
152 {
153 .addr = state->config->demod_address + 2,
154 .flags = 0,
155 .buf = b2,
156 .len = 2
157 },
158 };
159
160 ret = i2c_transfer(state->i2c, msg, 3);
161 return (ret != 3) ? -1 : 0;
162}
163
164
165static void
166lgs8gl5_soft_reset(struct lgs8gl5_state *state)
167{
168 u8 val;
169
170 dprintk("%s\n", __func__);
171
172 val = lgs8gl5_read_reg(state, REG_RESET);
173 lgs8gl5_write_reg(state, REG_RESET, val & ~REG_RESET_OFF);
174 lgs8gl5_write_reg(state, REG_RESET, val | REG_RESET_OFF);
175 msleep(5);
176}
177
178
179/* Starts demodulation */
180static void
181lgs8gl5_start_demod(struct lgs8gl5_state *state)
182{
183 u8 val;
184 int n;
185
186 dprintk("%s\n", __func__);
187
188 lgs8gl5_update_alt_reg(state, 0xc2, 0x28);
189 lgs8gl5_soft_reset(state);
190 lgs8gl5_update_reg(state, REG_07, 0x10);
191 lgs8gl5_update_reg(state, REG_07, 0x10);
192 lgs8gl5_write_reg(state, REG_09, 0x0e);
193 lgs8gl5_write_reg(state, REG_0A, 0xe5);
194 lgs8gl5_write_reg(state, REG_0B, 0x35);
195 lgs8gl5_write_reg(state, REG_0C, 0x30);
196
197 lgs8gl5_update_reg(state, REG_03, 0x00);
198 lgs8gl5_update_reg(state, REG_7E, 0x01);
199 lgs8gl5_update_alt_reg(state, 0xc5, 0x00);
200 lgs8gl5_update_reg(state, REG_04, 0x02);
201 lgs8gl5_update_reg(state, REG_37, 0x01);
202 lgs8gl5_soft_reset(state);
203
204 /* Wait for carrier */
205 for (n = 0; n < 10; n++) {
206 val = lgs8gl5_read_reg(state, REG_STRENGTH);
207 dprintk("Wait for carrier[%d] 0x%02X\n", n, val);
208 if (val & REG_STRENGTH_CARRIER)
209 break;
210 msleep(4);
211 }
212 if (!(val & REG_STRENGTH_CARRIER))
213 return;
214
215 /* Wait for lock */
216 for (n = 0; n < 20; n++) {
217 val = lgs8gl5_read_reg(state, REG_STATUS);
218 dprintk("Wait for lock[%d] 0x%02X\n", n, val);
219 if (val & REG_STATUS_LOCK)
220 break;
221 msleep(12);
222 }
223 if (!(val & REG_STATUS_LOCK))
224 return;
225
226 lgs8gl5_write_reg(state, REG_7D, lgs8gl5_read_reg(state, REG_A2));
227 lgs8gl5_soft_reset(state);
228}
229
230
231static int
232lgs8gl5_init(struct dvb_frontend *fe)
233{
234 struct lgs8gl5_state *state = fe->demodulator_priv;
235
236 dprintk("%s\n", __func__);
237
238 lgs8gl5_update_alt_reg(state, 0xc2, 0x28);
239 lgs8gl5_soft_reset(state);
240 lgs8gl5_update_reg(state, REG_07, 0x10);
241 lgs8gl5_update_reg(state, REG_07, 0x10);
242 lgs8gl5_write_reg(state, REG_09, 0x0e);
243 lgs8gl5_write_reg(state, REG_0A, 0xe5);
244 lgs8gl5_write_reg(state, REG_0B, 0x35);
245 lgs8gl5_write_reg(state, REG_0C, 0x30);
246
247 return 0;
248}
249
250
251static int
252lgs8gl5_read_status(struct dvb_frontend *fe, fe_status_t *status)
253{
254 struct lgs8gl5_state *state = fe->demodulator_priv;
255 u8 level = lgs8gl5_read_reg(state, REG_STRENGTH);
256 u8 flags = lgs8gl5_read_reg(state, REG_STATUS);
257
258 *status = 0;
259
260 if ((level & REG_STRENGTH_MASK) > 0)
261 *status |= FE_HAS_SIGNAL;
262 if (level & REG_STRENGTH_CARRIER)
263 *status |= FE_HAS_CARRIER;
264 if (flags & REG_STATUS_SYNC)
265 *status |= FE_HAS_SYNC;
266 if (flags & REG_STATUS_LOCK)
267 *status |= FE_HAS_LOCK;
268
269 return 0;
270}
271
272
273static int
274lgs8gl5_read_ber(struct dvb_frontend *fe, u32 *ber)
275{
276 *ber = 0;
277
278 return 0;
279}
280
281
282static int
283lgs8gl5_read_signal_strength(struct dvb_frontend *fe, u16 *signal_strength)
284{
285 struct lgs8gl5_state *state = fe->demodulator_priv;
286 u8 level = lgs8gl5_read_reg(state, REG_STRENGTH);
287 *signal_strength = (level & REG_STRENGTH_MASK) << 8;
288
289 return 0;
290}
291
292
293static int
294lgs8gl5_read_snr(struct dvb_frontend *fe, u16 *snr)
295{
296 struct lgs8gl5_state *state = fe->demodulator_priv;
297 u8 level = lgs8gl5_read_reg(state, REG_STRENGTH);
298 *snr = (level & REG_STRENGTH_MASK) << 8;
299
300 return 0;
301}
302
303
304static int
305lgs8gl5_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
306{
307 *ucblocks = 0;
308
309 return 0;
310}
311
312
313static int
314lgs8gl5_set_frontend(struct dvb_frontend *fe,
315 struct dvb_frontend_parameters *p)
316{
317 struct lgs8gl5_state *state = fe->demodulator_priv;
318
319 dprintk("%s\n", __func__);
320
321 if (p->u.ofdm.bandwidth != BANDWIDTH_8_MHZ)
322 return -EINVAL;
323
324 if (fe->ops.tuner_ops.set_params) {
325 fe->ops.tuner_ops.set_params(fe, p);
326 if (fe->ops.i2c_gate_ctrl)
327 fe->ops.i2c_gate_ctrl(fe, 0);
328 }
329
330 /* lgs8gl5_set_inversion(state, p->inversion); */
331
332 lgs8gl5_start_demod(state);
333
334 return 0;
335}
336
337
338static int
339lgs8gl5_get_frontend(struct dvb_frontend *fe,
340 struct dvb_frontend_parameters *p)
341{
342 struct lgs8gl5_state *state = fe->demodulator_priv;
343 u8 inv = lgs8gl5_read_reg(state, REG_INVERSION);
344 struct dvb_ofdm_parameters *o = &p->u.ofdm;
345
346 p->inversion = (inv & REG_INVERSION_ON) ? INVERSION_ON : INVERSION_OFF;
347
348 o->code_rate_HP = FEC_1_2;
349 o->code_rate_LP = FEC_7_8;
350 o->guard_interval = GUARD_INTERVAL_1_32;
351 o->transmission_mode = TRANSMISSION_MODE_2K;
352 o->constellation = QAM_64;
353 o->hierarchy_information = HIERARCHY_NONE;
354 o->bandwidth = BANDWIDTH_8_MHZ;
355
356 return 0;
357}
358
359
360static int
361lgs8gl5_get_tune_settings(struct dvb_frontend *fe,
362 struct dvb_frontend_tune_settings *fesettings)
363{
364 fesettings->min_delay_ms = 240;
365 fesettings->step_size = 0;
366 fesettings->max_drift = 0;
367 return 0;
368}
369
370
371static void
372lgs8gl5_release(struct dvb_frontend *fe)
373{
374 struct lgs8gl5_state *state = fe->demodulator_priv;
375 kfree(state);
376}
377
378
379static struct dvb_frontend_ops lgs8gl5_ops;
380
381
382struct dvb_frontend*
383lgs8gl5_attach(const struct lgs8gl5_config *config, struct i2c_adapter *i2c)
384{
385 struct lgs8gl5_state *state = NULL;
386
387 dprintk("%s\n", __func__);
388
389 /* Allocate memory for the internal state */
390 state = kmalloc(sizeof(struct lgs8gl5_state), GFP_KERNEL);
391 if (state == NULL)
392 goto error;
393
394 /* Setup the state */
395 state->config = config;
396 state->i2c = i2c;
397
398 /* Check if the demod is there */
399 if (lgs8gl5_read_reg(state, REG_RESET) < 0)
400 goto error;
401
402 /* Create dvb_frontend */
403 memcpy(&state->frontend.ops, &lgs8gl5_ops,
404 sizeof(struct dvb_frontend_ops));
405 state->frontend.demodulator_priv = state;
406 return &state->frontend;
407
408error:
409 kfree(state);
410 return NULL;
411}
412EXPORT_SYMBOL(lgs8gl5_attach);
413
414
415static struct dvb_frontend_ops lgs8gl5_ops = {
416 .info = {
417 .name = "Legend Silicon LGS-8GL5 DMB-TH",
418 .type = FE_OFDM,
419 .frequency_min = 474000000,
420 .frequency_max = 858000000,
421 .frequency_stepsize = 10000,
422 .frequency_tolerance = 0,
423 .caps = FE_CAN_FEC_AUTO |
424 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_32 |
425 FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
426 FE_CAN_TRANSMISSION_MODE_AUTO |
427 FE_CAN_BANDWIDTH_AUTO |
428 FE_CAN_GUARD_INTERVAL_AUTO |
429 FE_CAN_HIERARCHY_AUTO |
430 FE_CAN_RECOVER
431 },
432
433 .release = lgs8gl5_release,
434
435 .init = lgs8gl5_init,
436
437 .set_frontend = lgs8gl5_set_frontend,
438 .get_frontend = lgs8gl5_get_frontend,
439 .get_tune_settings = lgs8gl5_get_tune_settings,
440
441 .read_status = lgs8gl5_read_status,
442 .read_ber = lgs8gl5_read_ber,
443 .read_signal_strength = lgs8gl5_read_signal_strength,
444 .read_snr = lgs8gl5_read_snr,
445 .read_ucblocks = lgs8gl5_read_ucblocks,
446};
447
448
449module_param(debug, int, 0644);
450MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
451
452MODULE_DESCRIPTION("Legend Silicon LGS-8GL5 DMB-TH Demodulator driver");
453MODULE_AUTHOR("Timothy Lee");
454MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/lgs8gl5.h b/drivers/media/dvb/frontends/lgs8gl5.h
new file mode 100644
index 000000000000..d14176787a7d
--- /dev/null
+++ b/drivers/media/dvb/frontends/lgs8gl5.h
@@ -0,0 +1,45 @@
1/*
2 Legend Silicon LGS-8GL5 DMB-TH OFDM demodulator driver
3
4 Copyright (C) 2008 Sirius International (Hong Kong) Limited
5 Timothy Lee <timothy.lee@siriushk.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 LGS8GL5_H
24#define LGS8GL5_H
25
26#include <linux/dvb/frontend.h>
27
28struct lgs8gl5_config {
29 /* the demodulator's i2c address */
30 u8 demod_address;
31};
32
33#if defined(CONFIG_DVB_LGS8GL5) || \
34 (defined(CONFIG_DVB_LGS8GL5_MODULE) && defined(MODULE))
35extern struct dvb_frontend *lgs8gl5_attach(
36 const struct lgs8gl5_config *config, struct i2c_adapter *i2c);
37#else
38static inline struct dvb_frontend *lgs8gl5_attach(
39 const struct lgs8gl5_config *config, struct i2c_adapter *i2c) {
40 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
41 return NULL;
42}
43#endif /* CONFIG_DVB_LGS8GL5 */
44
45#endif /* LGS8GL5_H */
diff --git a/drivers/media/dvb/frontends/nxt200x.c b/drivers/media/dvb/frontends/nxt200x.c
index af298358e822..a8429ebfa8a2 100644
--- a/drivers/media/dvb/frontends/nxt200x.c
+++ b/drivers/media/dvb/frontends/nxt200x.c
@@ -80,7 +80,7 @@ static int i2c_writebytes (struct nxt200x_state* state, u8 addr, u8 *buf, u8 len
80 return 0; 80 return 0;
81} 81}
82 82
83static u8 i2c_readbytes (struct nxt200x_state* state, u8 addr, u8* buf, u8 len) 83static int i2c_readbytes(struct nxt200x_state *state, u8 addr, u8 *buf, u8 len)
84{ 84{
85 int err; 85 int err;
86 struct i2c_msg msg = { .addr = addr, .flags = I2C_M_RD, .buf = buf, .len = len }; 86 struct i2c_msg msg = { .addr = addr, .flags = I2C_M_RD, .buf = buf, .len = len };
@@ -111,7 +111,7 @@ static int nxt200x_writebytes (struct nxt200x_state* state, u8 reg,
111 return 0; 111 return 0;
112} 112}
113 113
114static u8 nxt200x_readbytes (struct nxt200x_state* state, u8 reg, u8* buf, u8 len) 114static int nxt200x_readbytes(struct nxt200x_state *state, u8 reg, u8 *buf, u8 len)
115{ 115{
116 u8 reg2 [] = { reg }; 116 u8 reg2 [] = { reg };
117 117
diff --git a/drivers/media/dvb/frontends/or51211.c b/drivers/media/dvb/frontends/or51211.c
index 6afe12aaca4e..16cf2fdd5d7d 100644
--- a/drivers/media/dvb/frontends/or51211.c
+++ b/drivers/media/dvb/frontends/or51211.c
@@ -88,7 +88,7 @@ static int i2c_writebytes (struct or51211_state* state, u8 reg, const u8 *buf,
88 return 0; 88 return 0;
89} 89}
90 90
91static u8 i2c_readbytes (struct or51211_state* state, u8 reg, u8* buf, int len) 91static int i2c_readbytes(struct or51211_state *state, u8 reg, u8 *buf, int len)
92{ 92{
93 int err; 93 int err;
94 struct i2c_msg msg; 94 struct i2c_msg msg;
diff --git a/drivers/media/dvb/frontends/si21xx.c b/drivers/media/dvb/frontends/si21xx.c
new file mode 100644
index 000000000000..3ddbe69c45ce
--- /dev/null
+++ b/drivers/media/dvb/frontends/si21xx.c
@@ -0,0 +1,974 @@
1/* DVB compliant Linux driver for the DVB-S si2109/2110 demodulator
2*
3* Copyright (C) 2008 Igor M. Liplianin (liplianin@me.by)
4*
5* This program is free software; you can redistribute it and/or modify
6* it under the terms of the GNU General Public License as published by
7* the Free Software Foundation; either version 2 of the License, or
8* (at your option) any later version.
9*
10*/
11#include <linux/version.h>
12#include <linux/init.h>
13#include <linux/kernel.h>
14#include <linux/module.h>
15#include <linux/string.h>
16#include <linux/slab.h>
17#include <linux/jiffies.h>
18#include <asm/div64.h>
19
20#include "dvb_frontend.h"
21#include "si21xx.h"
22
23#define REVISION_REG 0x00
24#define SYSTEM_MODE_REG 0x01
25#define TS_CTRL_REG_1 0x02
26#define TS_CTRL_REG_2 0x03
27#define PIN_CTRL_REG_1 0x04
28#define PIN_CTRL_REG_2 0x05
29#define LOCK_STATUS_REG_1 0x0f
30#define LOCK_STATUS_REG_2 0x10
31#define ACQ_STATUS_REG 0x11
32#define ACQ_CTRL_REG_1 0x13
33#define ACQ_CTRL_REG_2 0x14
34#define PLL_DIVISOR_REG 0x15
35#define COARSE_TUNE_REG 0x16
36#define FINE_TUNE_REG_L 0x17
37#define FINE_TUNE_REG_H 0x18
38
39#define ANALOG_AGC_POWER_LEVEL_REG 0x28
40#define CFO_ESTIMATOR_CTRL_REG_1 0x29
41#define CFO_ESTIMATOR_CTRL_REG_2 0x2a
42#define CFO_ESTIMATOR_CTRL_REG_3 0x2b
43
44#define SYM_RATE_ESTIMATE_REG_L 0x31
45#define SYM_RATE_ESTIMATE_REG_M 0x32
46#define SYM_RATE_ESTIMATE_REG_H 0x33
47
48#define CFO_ESTIMATOR_OFFSET_REG_L 0x36
49#define CFO_ESTIMATOR_OFFSET_REG_H 0x37
50#define CFO_ERROR_REG_L 0x38
51#define CFO_ERROR_REG_H 0x39
52#define SYM_RATE_ESTIMATOR_CTRL_REG 0x3a
53
54#define SYM_RATE_REG_L 0x3f
55#define SYM_RATE_REG_M 0x40
56#define SYM_RATE_REG_H 0x41
57#define SYM_RATE_ESTIMATOR_MAXIMUM_REG 0x42
58#define SYM_RATE_ESTIMATOR_MINIMUM_REG 0x43
59
60#define C_N_ESTIMATOR_CTRL_REG 0x7c
61#define C_N_ESTIMATOR_THRSHLD_REG 0x7d
62#define C_N_ESTIMATOR_LEVEL_REG_L 0x7e
63#define C_N_ESTIMATOR_LEVEL_REG_H 0x7f
64
65#define BLIND_SCAN_CTRL_REG 0x80
66
67#define LSA_CTRL_REG_1 0x8D
68#define SPCTRM_TILT_CORR_THRSHLD_REG 0x8f
69#define ONE_DB_BNDWDTH_THRSHLD_REG 0x90
70#define TWO_DB_BNDWDTH_THRSHLD_REG 0x91
71#define THREE_DB_BNDWDTH_THRSHLD_REG 0x92
72#define INBAND_POWER_THRSHLD_REG 0x93
73#define REF_NOISE_LVL_MRGN_THRSHLD_REG 0x94
74
75#define VIT_SRCH_CTRL_REG_1 0xa0
76#define VIT_SRCH_CTRL_REG_2 0xa1
77#define VIT_SRCH_CTRL_REG_3 0xa2
78#define VIT_SRCH_STATUS_REG 0xa3
79#define VITERBI_BER_COUNT_REG_L 0xab
80#define REED_SOLOMON_CTRL_REG 0xb0
81#define REED_SOLOMON_ERROR_COUNT_REG_L 0xb1
82#define PRBS_CTRL_REG 0xb5
83
84#define LNB_CTRL_REG_1 0xc0
85#define LNB_CTRL_REG_2 0xc1
86#define LNB_CTRL_REG_3 0xc2
87#define LNB_CTRL_REG_4 0xc3
88#define LNB_CTRL_STATUS_REG 0xc4
89#define LNB_FIFO_REGS_0 0xc5
90#define LNB_FIFO_REGS_1 0xc6
91#define LNB_FIFO_REGS_2 0xc7
92#define LNB_FIFO_REGS_3 0xc8
93#define LNB_FIFO_REGS_4 0xc9
94#define LNB_FIFO_REGS_5 0xca
95#define LNB_SUPPLY_CTRL_REG_1 0xcb
96#define LNB_SUPPLY_CTRL_REG_2 0xcc
97#define LNB_SUPPLY_CTRL_REG_3 0xcd
98#define LNB_SUPPLY_CTRL_REG_4 0xce
99#define LNB_SUPPLY_STATUS_REG 0xcf
100
101#define FALSE 0
102#define TRUE 1
103#define FAIL -1
104#define PASS 0
105
106#define ALLOWABLE_FS_COUNT 10
107#define STATUS_BER 0
108#define STATUS_UCBLOCKS 1
109
110static int debug;
111#define dprintk(args...) \
112 do { \
113 if (debug) \
114 printk(KERN_DEBUG "si21xx: " args); \
115 } while (0)
116
117enum {
118 ACTIVE_HIGH,
119 ACTIVE_LOW
120};
121enum {
122 BYTE_WIDE,
123 BIT_WIDE
124};
125enum {
126 CLK_GAPPED_MODE,
127 CLK_CONTINUOUS_MODE
128};
129enum {
130 RISING_EDGE,
131 FALLING_EDGE
132};
133enum {
134 MSB_FIRST,
135 LSB_FIRST
136};
137enum {
138 SERIAL,
139 PARALLEL
140};
141
142struct si21xx_state {
143 struct i2c_adapter *i2c;
144 const struct si21xx_config *config;
145 struct dvb_frontend frontend;
146 u8 initialised:1;
147 int errmode;
148 int fs; /*Sampling rate of the ADC in MHz*/
149};
150
151/* register default initialization */
152static u8 serit_sp1511lhb_inittab[] = {
153 0x01, 0x28, /* set i2c_inc_disable */
154 0x20, 0x03,
155 0x27, 0x20,
156 0xe0, 0x45,
157 0xe1, 0x08,
158 0xfe, 0x01,
159 0x01, 0x28,
160 0x89, 0x09,
161 0x04, 0x80,
162 0x05, 0x01,
163 0x06, 0x00,
164 0x20, 0x03,
165 0x24, 0x88,
166 0x29, 0x09,
167 0x2a, 0x0f,
168 0x2c, 0x10,
169 0x2d, 0x19,
170 0x2e, 0x08,
171 0x2f, 0x10,
172 0x30, 0x19,
173 0x34, 0x20,
174 0x35, 0x03,
175 0x45, 0x02,
176 0x46, 0x45,
177 0x47, 0xd0,
178 0x48, 0x00,
179 0x49, 0x40,
180 0x4a, 0x03,
181 0x4c, 0xfd,
182 0x4f, 0x2e,
183 0x50, 0x2e,
184 0x51, 0x10,
185 0x52, 0x10,
186 0x56, 0x92,
187 0x59, 0x00,
188 0x5a, 0x2d,
189 0x5b, 0x33,
190 0x5c, 0x1f,
191 0x5f, 0x76,
192 0x62, 0xc0,
193 0x63, 0xc0,
194 0x64, 0xf3,
195 0x65, 0xf3,
196 0x79, 0x40,
197 0x6a, 0x40,
198 0x6b, 0x0a,
199 0x6c, 0x80,
200 0x6d, 0x27,
201 0x71, 0x06,
202 0x75, 0x60,
203 0x78, 0x00,
204 0x79, 0xb5,
205 0x7c, 0x05,
206 0x7d, 0x1a,
207 0x87, 0x55,
208 0x88, 0x72,
209 0x8f, 0x08,
210 0x90, 0xe0,
211 0x94, 0x40,
212 0xa0, 0x3f,
213 0xa1, 0xc0,
214 0xa4, 0xcc,
215 0xa5, 0x66,
216 0xa6, 0x66,
217 0xa7, 0x7b,
218 0xa8, 0x7b,
219 0xa9, 0x7b,
220 0xaa, 0x9a,
221 0xed, 0x04,
222 0xad, 0x00,
223 0xae, 0x03,
224 0xcc, 0xab,
225 0x01, 0x08,
226 0xff, 0xff
227};
228
229/* low level read/writes */
230static int si21_writeregs(struct si21xx_state *state, u8 reg1,
231 u8 *data, int len)
232{
233 int ret;
234 u8 buf[60];/* = { reg1, data };*/
235 struct i2c_msg msg = {
236 .addr = state->config->demod_address,
237 .flags = 0,
238 .buf = buf,
239 .len = len + 1
240 };
241
242 msg.buf[0] = reg1;
243 memcpy(msg.buf + 1, data, len);
244
245 ret = i2c_transfer(state->i2c, &msg, 1);
246
247 if (ret != 1)
248 dprintk("%s: writereg error (reg1 == 0x%02x, data == 0x%02x, "
249 "ret == %i)\n", __func__, reg1, data[0], ret);
250
251 return (ret != 1) ? -EREMOTEIO : 0;
252}
253
254static int si21_writereg(struct si21xx_state *state, u8 reg, u8 data)
255{
256 int ret;
257 u8 buf[] = { reg, data };
258 struct i2c_msg msg = {
259 .addr = state->config->demod_address,
260 .flags = 0,
261 .buf = buf,
262 .len = 2
263 };
264
265 ret = i2c_transfer(state->i2c, &msg, 1);
266
267 if (ret != 1)
268 dprintk("%s: writereg error (reg == 0x%02x, data == 0x%02x, "
269 "ret == %i)\n", __func__, reg, data, ret);
270
271 return (ret != 1) ? -EREMOTEIO : 0;
272}
273
274static int si21_write(struct dvb_frontend *fe, u8 *buf, int len)
275{
276 struct si21xx_state *state = fe->demodulator_priv;
277
278 if (len != 2)
279 return -EINVAL;
280
281 return si21_writereg(state, buf[0], buf[1]);
282}
283
284static u8 si21_readreg(struct si21xx_state *state, u8 reg)
285{
286 int ret;
287 u8 b0[] = { reg };
288 u8 b1[] = { 0 };
289 struct i2c_msg msg[] = {
290 {
291 .addr = state->config->demod_address,
292 .flags = 0,
293 .buf = b0,
294 .len = 1
295 }, {
296 .addr = state->config->demod_address,
297 .flags = I2C_M_RD,
298 .buf = b1,
299 .len = 1
300 }
301 };
302
303 ret = i2c_transfer(state->i2c, msg, 2);
304
305 if (ret != 2)
306 dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n",
307 __func__, reg, ret);
308
309 return b1[0];
310}
311
312static int si21_readregs(struct si21xx_state *state, u8 reg1, u8 *b, u8 len)
313{
314 int ret;
315 struct i2c_msg msg[] = {
316 {
317 .addr = state->config->demod_address,
318 .flags = 0,
319 .buf = &reg1,
320 .len = 1
321 }, {
322 .addr = state->config->demod_address,
323 .flags = I2C_M_RD,
324 .buf = b,
325 .len = len
326 }
327 };
328
329 ret = i2c_transfer(state->i2c, msg, 2);
330
331 if (ret != 2)
332 dprintk("%s: readreg error (ret == %i)\n", __func__, ret);
333
334 return ret == 2 ? 0 : -1;
335}
336
337static int si21xx_wait_diseqc_idle(struct si21xx_state *state, int timeout)
338{
339 unsigned long start = jiffies;
340
341 dprintk("%s\n", __func__);
342
343 while ((si21_readreg(state, LNB_CTRL_REG_1) & 0x8) == 8) {
344 if (jiffies - start > timeout) {
345 dprintk("%s: timeout!!\n", __func__);
346 return -ETIMEDOUT;
347 }
348 msleep(10);
349 };
350
351 return 0;
352}
353
354static int si21xx_set_symbolrate(struct dvb_frontend *fe, u32 srate)
355{
356 struct si21xx_state *state = fe->demodulator_priv;
357 u32 sym_rate, data_rate;
358 int i;
359 u8 sym_rate_bytes[3];
360
361 dprintk("%s : srate = %i\n", __func__ , srate);
362
363 if ((srate < 1000000) || (srate > 45000000))
364 return -EINVAL;
365
366 data_rate = srate;
367 sym_rate = 0;
368
369 for (i = 0; i < 4; ++i) {
370 sym_rate /= 100;
371 sym_rate = sym_rate + ((data_rate % 100) * 0x800000) /
372 state->fs;
373 data_rate /= 100;
374 }
375 for (i = 0; i < 3; ++i)
376 sym_rate_bytes[i] = (u8)((sym_rate >> (i * 8)) & 0xff);
377
378 si21_writeregs(state, SYM_RATE_REG_L, sym_rate_bytes, 0x03);
379
380 return 0;
381}
382
383static int si21xx_send_diseqc_msg(struct dvb_frontend *fe,
384 struct dvb_diseqc_master_cmd *m)
385{
386 struct si21xx_state *state = fe->demodulator_priv;
387 u8 lnb_status;
388 u8 LNB_CTRL_1;
389 int status;
390
391 dprintk("%s\n", __func__);
392
393 status = PASS;
394 LNB_CTRL_1 = 0;
395
396 status |= si21_readregs(state, LNB_CTRL_STATUS_REG, &lnb_status, 0x01);
397 status |= si21_readregs(state, LNB_CTRL_REG_1, &lnb_status, 0x01);
398
399 /*fill the FIFO*/
400 status |= si21_writeregs(state, LNB_FIFO_REGS_0, m->msg, m->msg_len);
401
402 LNB_CTRL_1 = (lnb_status & 0x70);
403 LNB_CTRL_1 |= m->msg_len;
404
405 LNB_CTRL_1 |= 0x80; /* begin LNB signaling */
406
407 status |= si21_writeregs(state, LNB_CTRL_REG_1, &LNB_CTRL_1, 0x01);
408
409 return status;
410}
411
412static int si21xx_send_diseqc_burst(struct dvb_frontend *fe,
413 fe_sec_mini_cmd_t burst)
414{
415 struct si21xx_state *state = fe->demodulator_priv;
416 u8 val;
417
418 dprintk("%s\n", __func__);
419
420 if (si21xx_wait_diseqc_idle(state, 100) < 0)
421 return -ETIMEDOUT;
422
423 val = (0x80 | si21_readreg(state, 0xc1));
424 if (si21_writereg(state, LNB_CTRL_REG_1,
425 burst == SEC_MINI_A ? (val & ~0x10) : (val | 0x10)))
426 return -EREMOTEIO;
427
428 if (si21xx_wait_diseqc_idle(state, 100) < 0)
429 return -ETIMEDOUT;
430
431 if (si21_writereg(state, LNB_CTRL_REG_1, val))
432 return -EREMOTEIO;
433
434 return 0;
435}
436/* 30.06.2008 */
437static int si21xx_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
438{
439 struct si21xx_state *state = fe->demodulator_priv;
440 u8 val;
441
442 dprintk("%s\n", __func__);
443 val = (0x80 | si21_readreg(state, LNB_CTRL_REG_1));
444
445 switch (tone) {
446 case SEC_TONE_ON:
447 return si21_writereg(state, LNB_CTRL_REG_1, val | 0x20);
448
449 case SEC_TONE_OFF:
450 return si21_writereg(state, LNB_CTRL_REG_1, (val & ~0x20));
451
452 default:
453 return -EINVAL;
454 }
455}
456
457static int si21xx_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t volt)
458{
459 struct si21xx_state *state = fe->demodulator_priv;
460
461 u8 val;
462 dprintk("%s: %s\n", __func__,
463 volt == SEC_VOLTAGE_13 ? "SEC_VOLTAGE_13" :
464 volt == SEC_VOLTAGE_18 ? "SEC_VOLTAGE_18" : "??");
465
466
467 val = (0x80 | si21_readreg(state, LNB_CTRL_REG_1));
468
469 switch (volt) {
470 case SEC_VOLTAGE_18:
471 return si21_writereg(state, LNB_CTRL_REG_1, val | 0x40);
472 break;
473 case SEC_VOLTAGE_13:
474 return si21_writereg(state, LNB_CTRL_REG_1, (val & ~0x40));
475 break;
476 default:
477 return -EINVAL;
478 };
479}
480
481static int si21xx_init(struct dvb_frontend *fe)
482{
483 struct si21xx_state *state = fe->demodulator_priv;
484 int i;
485 int status = 0;
486 u8 reg1;
487 u8 val;
488 u8 reg2[2];
489
490 dprintk("%s\n", __func__);
491
492 for (i = 0; ; i += 2) {
493 reg1 = serit_sp1511lhb_inittab[i];
494 val = serit_sp1511lhb_inittab[i+1];
495 if (reg1 == 0xff && val == 0xff)
496 break;
497 si21_writeregs(state, reg1, &val, 1);
498 }
499
500 /*DVB QPSK SYSTEM MODE REG*/
501 reg1 = 0x08;
502 si21_writeregs(state, SYSTEM_MODE_REG, &reg1, 0x01);
503
504 /*transport stream config*/
505 /*
506 mode = PARALLEL;
507 sdata_form = LSB_FIRST;
508 clk_edge = FALLING_EDGE;
509 clk_mode = CLK_GAPPED_MODE;
510 strt_len = BYTE_WIDE;
511 sync_pol = ACTIVE_HIGH;
512 val_pol = ACTIVE_HIGH;
513 err_pol = ACTIVE_HIGH;
514 sclk_rate = 0x00;
515 parity = 0x00 ;
516 data_delay = 0x00;
517 clk_delay = 0x00;
518 pclk_smooth = 0x00;
519 */
520 reg2[0] =
521 PARALLEL + (LSB_FIRST << 1)
522 + (FALLING_EDGE << 2) + (CLK_GAPPED_MODE << 3)
523 + (BYTE_WIDE << 4) + (ACTIVE_HIGH << 5)
524 + (ACTIVE_HIGH << 6) + (ACTIVE_HIGH << 7);
525
526 reg2[1] = 0;
527 /* sclk_rate + (parity << 2)
528 + (data_delay << 3) + (clk_delay << 4)
529 + (pclk_smooth << 5);
530 */
531 status |= si21_writeregs(state, TS_CTRL_REG_1, reg2, 0x02);
532 if (status != 0)
533 dprintk(" %s : TS Set Error\n", __func__);
534
535 return 0;
536
537}
538
539static int si21_read_status(struct dvb_frontend *fe, fe_status_t *status)
540{
541 struct si21xx_state *state = fe->demodulator_priv;
542 u8 regs_read[2];
543 u8 reg_read;
544 u8 i;
545 u8 lock;
546 u8 signal = si21_readreg(state, ANALOG_AGC_POWER_LEVEL_REG);
547
548 si21_readregs(state, LOCK_STATUS_REG_1, regs_read, 0x02);
549 reg_read = 0;
550
551 for (i = 0; i < 7; ++i)
552 reg_read |= ((regs_read[0] >> i) & 0x01) << (6 - i);
553
554 lock = ((reg_read & 0x7f) | (regs_read[1] & 0x80));
555
556 dprintk("%s : FE_READ_STATUS : VSTATUS: 0x%02x\n", __func__, lock);
557 *status = 0;
558
559 if (signal > 10)
560 *status |= FE_HAS_SIGNAL;
561
562 if (lock & 0x2)
563 *status |= FE_HAS_CARRIER;
564
565 if (lock & 0x20)
566 *status |= FE_HAS_VITERBI;
567
568 if (lock & 0x40)
569 *status |= FE_HAS_SYNC;
570
571 if ((lock & 0x7b) == 0x7b)
572 *status |= FE_HAS_LOCK;
573
574 return 0;
575}
576
577static int si21_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
578{
579 struct si21xx_state *state = fe->demodulator_priv;
580
581 /*status = si21_readreg(state, ANALOG_AGC_POWER_LEVEL_REG,
582 (u8*)agclevel, 0x01);*/
583
584 u16 signal = (3 * si21_readreg(state, 0x27) *
585 si21_readreg(state, 0x28));
586
587 dprintk("%s : AGCPWR: 0x%02x%02x, signal=0x%04x\n", __func__,
588 si21_readreg(state, 0x27),
589 si21_readreg(state, 0x28), (int) signal);
590
591 signal <<= 4;
592 *strength = signal;
593
594 return 0;
595}
596
597static int si21_read_ber(struct dvb_frontend *fe, u32 *ber)
598{
599 struct si21xx_state *state = fe->demodulator_priv;
600
601 dprintk("%s\n", __func__);
602
603 if (state->errmode != STATUS_BER)
604 return 0;
605
606 *ber = (si21_readreg(state, 0x1d) << 8) |
607 si21_readreg(state, 0x1e);
608
609 return 0;
610}
611
612static int si21_read_snr(struct dvb_frontend *fe, u16 *snr)
613{
614 struct si21xx_state *state = fe->demodulator_priv;
615
616 s32 xsnr = 0xffff - ((si21_readreg(state, 0x24) << 8) |
617 si21_readreg(state, 0x25));
618 xsnr = 3 * (xsnr - 0xa100);
619 *snr = (xsnr > 0xffff) ? 0xffff : (xsnr < 0) ? 0 : xsnr;
620
621 dprintk("%s\n", __func__);
622
623 return 0;
624}
625
626static int si21_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
627{
628 struct si21xx_state *state = fe->demodulator_priv;
629
630 dprintk("%s\n", __func__);
631
632 if (state->errmode != STATUS_UCBLOCKS)
633 *ucblocks = 0;
634 else
635 *ucblocks = (si21_readreg(state, 0x1d) << 8) |
636 si21_readreg(state, 0x1e);
637
638 return 0;
639}
640
641/* initiates a channel acquisition sequence
642 using the specified symbol rate and code rate */
643static int si21xx_setacquire(struct dvb_frontend *fe, int symbrate,
644 fe_code_rate_t crate)
645{
646
647 struct si21xx_state *state = fe->demodulator_priv;
648 u8 coderates[] = {
649 0x0, 0x01, 0x02, 0x04, 0x00,
650 0x8, 0x10, 0x20, 0x00, 0x3f
651 };
652
653 u8 coderate_ptr;
654 int status;
655 u8 start_acq = 0x80;
656 u8 reg, regs[3];
657
658 dprintk("%s\n", __func__);
659
660 status = PASS;
661 coderate_ptr = coderates[crate];
662
663 si21xx_set_symbolrate(fe, symbrate);
664
665 /* write code rates to use in the Viterbi search */
666 status |= si21_writeregs(state,
667 VIT_SRCH_CTRL_REG_1,
668 &coderate_ptr, 0x01);
669
670 /* clear acq_start bit */
671 status |= si21_readregs(state, ACQ_CTRL_REG_2, &reg, 0x01);
672 reg &= ~start_acq;
673 status |= si21_writeregs(state, ACQ_CTRL_REG_2, &reg, 0x01);
674
675 /* use new Carrier Frequency Offset Estimator (QuickLock) */
676 regs[0] = 0xCB;
677 regs[1] = 0x40;
678 regs[2] = 0xCB;
679
680 status |= si21_writeregs(state,
681 TWO_DB_BNDWDTH_THRSHLD_REG,
682 &regs[0], 0x03);
683 reg = 0x56;
684 status |= si21_writeregs(state,
685 LSA_CTRL_REG_1, &reg, 1);
686 reg = 0x05;
687 status |= si21_writeregs(state,
688 BLIND_SCAN_CTRL_REG, &reg, 1);
689 /* start automatic acq */
690 status |= si21_writeregs(state,
691 ACQ_CTRL_REG_2, &start_acq, 0x01);
692
693 return status;
694}
695
696static int si21xx_set_property(struct dvb_frontend *fe, struct dtv_property *p)
697{
698 dprintk("%s(..)\n", __func__);
699 return 0;
700}
701
702static int si21xx_get_property(struct dvb_frontend *fe, struct dtv_property *p)
703{
704 dprintk("%s(..)\n", __func__);
705 return 0;
706}
707
708static int si21xx_set_frontend(struct dvb_frontend *fe,
709 struct dvb_frontend_parameters *dfp)
710{
711 struct si21xx_state *state = fe->demodulator_priv;
712 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
713
714 /* freq Channel carrier frequency in KHz (i.e. 1550000 KHz)
715 datarate Channel symbol rate in Sps (i.e. 22500000 Sps)*/
716
717 /* in MHz */
718 unsigned char coarse_tune_freq;
719 int fine_tune_freq;
720 unsigned char sample_rate = 0;
721 /* boolean */
722 unsigned int inband_interferer_ind;
723
724 /* INTERMEDIATE VALUES */
725 int icoarse_tune_freq; /* MHz */
726 int ifine_tune_freq; /* MHz */
727 unsigned int band_high;
728 unsigned int band_low;
729 unsigned int x1;
730 unsigned int x2;
731 int i;
732 unsigned int inband_interferer_div2[ALLOWABLE_FS_COUNT] = {
733 FALSE, FALSE, FALSE, FALSE, FALSE,
734 FALSE, FALSE, FALSE, FALSE, FALSE
735 };
736 unsigned int inband_interferer_div4[ALLOWABLE_FS_COUNT] = {
737 FALSE, FALSE, FALSE, FALSE, FALSE,
738 FALSE, FALSE, FALSE, FALSE, FALSE
739 };
740
741 int status;
742
743 /* allowable sample rates for ADC in MHz */
744 int afs[ALLOWABLE_FS_COUNT] = { 200, 192, 193, 194, 195,
745 196, 204, 205, 206, 207
746 };
747 /* in MHz */
748 int if_limit_high;
749 int if_limit_low;
750 int lnb_lo;
751 int lnb_uncertanity;
752
753 int rf_freq;
754 int data_rate;
755 unsigned char regs[4];
756
757 dprintk("%s : FE_SET_FRONTEND\n", __func__);
758
759 if (c->delivery_system != SYS_DVBS) {
760 dprintk("%s: unsupported delivery system selected (%d)\n",
761 __func__, c->delivery_system);
762 return -EOPNOTSUPP;
763 }
764
765 for (i = 0; i < ALLOWABLE_FS_COUNT; ++i)
766 inband_interferer_div2[i] = inband_interferer_div4[i] = FALSE;
767
768 if_limit_high = -700000;
769 if_limit_low = -100000;
770 /* in MHz */
771 lnb_lo = 0;
772 lnb_uncertanity = 0;
773
774 rf_freq = 10 * c->frequency ;
775 data_rate = c->symbol_rate / 100;
776
777 status = PASS;
778
779 band_low = (rf_freq - lnb_lo) - ((lnb_uncertanity * 200)
780 + (data_rate * 135)) / 200;
781
782 band_high = (rf_freq - lnb_lo) + ((lnb_uncertanity * 200)
783 + (data_rate * 135)) / 200;
784
785
786 icoarse_tune_freq = 100000 *
787 (((rf_freq - lnb_lo) -
788 (if_limit_low + if_limit_high) / 2)
789 / 100000);
790
791 ifine_tune_freq = (rf_freq - lnb_lo) - icoarse_tune_freq ;
792
793 for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) {
794 x1 = ((rf_freq - lnb_lo) / (afs[i] * 2500)) *
795 (afs[i] * 2500) + afs[i] * 2500;
796
797 x2 = ((rf_freq - lnb_lo) / (afs[i] * 2500)) *
798 (afs[i] * 2500);
799
800 if (((band_low < x1) && (x1 < band_high)) ||
801 ((band_low < x2) && (x2 < band_high)))
802 inband_interferer_div4[i] = TRUE;
803
804 }
805
806 for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) {
807 x1 = ((rf_freq - lnb_lo) / (afs[i] * 5000)) *
808 (afs[i] * 5000) + afs[i] * 5000;
809
810 x2 = ((rf_freq - lnb_lo) / (afs[i] * 5000)) *
811 (afs[i] * 5000);
812
813 if (((band_low < x1) && (x1 < band_high)) ||
814 ((band_low < x2) && (x2 < band_high)))
815 inband_interferer_div2[i] = TRUE;
816 }
817
818 inband_interferer_ind = TRUE;
819 for (i = 0; i < ALLOWABLE_FS_COUNT; ++i)
820 inband_interferer_ind &= inband_interferer_div2[i] |
821 inband_interferer_div4[i];
822
823 if (inband_interferer_ind) {
824 for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) {
825 if (inband_interferer_div2[i] == FALSE) {
826 sample_rate = (u8) afs[i];
827 break;
828 }
829 }
830 } else {
831 for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) {
832 if ((inband_interferer_div2[i] |
833 inband_interferer_div4[i]) == FALSE) {
834 sample_rate = (u8) afs[i];
835 break;
836 }
837 }
838
839 }
840
841 if (sample_rate > 207 || sample_rate < 192)
842 sample_rate = 200;
843
844 fine_tune_freq = ((0x4000 * (ifine_tune_freq / 10)) /
845 ((sample_rate) * 1000));
846
847 coarse_tune_freq = (u8)(icoarse_tune_freq / 100000);
848
849 regs[0] = sample_rate;
850 regs[1] = coarse_tune_freq;
851 regs[2] = fine_tune_freq & 0xFF;
852 regs[3] = fine_tune_freq >> 8 & 0xFF;
853
854 status |= si21_writeregs(state, PLL_DIVISOR_REG, &regs[0], 0x04);
855
856 state->fs = sample_rate;/*ADC MHz*/
857 si21xx_setacquire(fe, c->symbol_rate, c->fec_inner);
858
859 return 0;
860}
861
862static int si21xx_sleep(struct dvb_frontend *fe)
863{
864 struct si21xx_state *state = fe->demodulator_priv;
865 u8 regdata;
866
867 dprintk("%s\n", __func__);
868
869 si21_readregs(state, SYSTEM_MODE_REG, &regdata, 0x01);
870 regdata |= 1 << 6;
871 si21_writeregs(state, SYSTEM_MODE_REG, &regdata, 0x01);
872 state->initialised = 0;
873
874 return 0;
875}
876
877static void si21xx_release(struct dvb_frontend *fe)
878{
879 struct si21xx_state *state = fe->demodulator_priv;
880
881 dprintk("%s\n", __func__);
882
883 kfree(state);
884}
885
886static struct dvb_frontend_ops si21xx_ops = {
887
888 .info = {
889 .name = "SL SI21XX DVB-S",
890 .type = FE_QPSK,
891 .frequency_min = 950000,
892 .frequency_max = 2150000,
893 .frequency_stepsize = 125, /* kHz for QPSK frontends */
894 .frequency_tolerance = 0,
895 .symbol_rate_min = 1000000,
896 .symbol_rate_max = 45000000,
897 .symbol_rate_tolerance = 500, /* ppm */
898 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
899 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
900 FE_CAN_QPSK |
901 FE_CAN_FEC_AUTO
902 },
903
904 .release = si21xx_release,
905 .init = si21xx_init,
906 .sleep = si21xx_sleep,
907 .write = si21_write,
908 .read_status = si21_read_status,
909 .read_ber = si21_read_ber,
910 .read_signal_strength = si21_read_signal_strength,
911 .read_snr = si21_read_snr,
912 .read_ucblocks = si21_read_ucblocks,
913 .diseqc_send_master_cmd = si21xx_send_diseqc_msg,
914 .diseqc_send_burst = si21xx_send_diseqc_burst,
915 .set_tone = si21xx_set_tone,
916 .set_voltage = si21xx_set_voltage,
917
918 .set_property = si21xx_set_property,
919 .get_property = si21xx_get_property,
920 .set_frontend = si21xx_set_frontend,
921};
922
923struct dvb_frontend *si21xx_attach(const struct si21xx_config *config,
924 struct i2c_adapter *i2c)
925{
926 struct si21xx_state *state = NULL;
927 int id;
928
929 dprintk("%s\n", __func__);
930
931 /* allocate memory for the internal state */
932 state = kmalloc(sizeof(struct si21xx_state), GFP_KERNEL);
933 if (state == NULL)
934 goto error;
935
936 /* setup the state */
937 state->config = config;
938 state->i2c = i2c;
939 state->initialised = 0;
940 state->errmode = STATUS_BER;
941
942 /* check if the demod is there */
943 id = si21_readreg(state, SYSTEM_MODE_REG);
944 si21_writereg(state, SYSTEM_MODE_REG, id | 0x40); /* standby off */
945 msleep(200);
946 id = si21_readreg(state, 0x00);
947
948 /* register 0x00 contains:
949 0x34 for SI2107
950 0x24 for SI2108
951 0x14 for SI2109
952 0x04 for SI2110
953 */
954 if (id != 0x04 && id != 0x14)
955 goto error;
956
957 /* create dvb_frontend */
958 memcpy(&state->frontend.ops, &si21xx_ops,
959 sizeof(struct dvb_frontend_ops));
960 state->frontend.demodulator_priv = state;
961 return &state->frontend;
962
963error:
964 kfree(state);
965 return NULL;
966}
967EXPORT_SYMBOL(si21xx_attach);
968
969module_param(debug, int, 0644);
970MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
971
972MODULE_DESCRIPTION("SL SI21XX DVB Demodulator driver");
973MODULE_AUTHOR("Igor M. Liplianin");
974MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/si21xx.h b/drivers/media/dvb/frontends/si21xx.h
new file mode 100644
index 000000000000..141b5b8a5f63
--- /dev/null
+++ b/drivers/media/dvb/frontends/si21xx.h
@@ -0,0 +1,37 @@
1#ifndef SI21XX_H
2#define SI21XX_H
3
4#include <linux/dvb/frontend.h>
5#include "dvb_frontend.h"
6
7struct si21xx_config {
8 /* the demodulator's i2c address */
9 u8 demod_address;
10
11 /* minimum delay before retuning */
12 int min_delay_ms;
13};
14
15#if defined(CONFIG_DVB_SI21XX) || \
16 (defined(CONFIG_DVB_SI21XX_MODULE) && defined(MODULE))
17extern struct dvb_frontend *si21xx_attach(const struct si21xx_config *config,
18 struct i2c_adapter *i2c);
19#else
20static inline struct dvb_frontend *si21xx_attach(
21 const struct si21xx_config *config, struct i2c_adapter *i2c)
22{
23 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
24 return NULL;
25}
26#endif
27
28static inline int si21xx_writeregister(struct dvb_frontend *fe, u8 reg, u8 val)
29{
30 int r = 0;
31 u8 buf[] = {reg, val};
32 if (fe->ops.write)
33 r = fe->ops.write(fe, buf, 2);
34 return r;
35}
36
37#endif
diff --git a/drivers/media/dvb/frontends/sp887x.c b/drivers/media/dvb/frontends/sp887x.c
index 4543609e1816..559509ab4dab 100644
--- a/drivers/media/dvb/frontends/sp887x.c
+++ b/drivers/media/dvb/frontends/sp887x.c
@@ -337,7 +337,8 @@ static int sp887x_setup_frontend_parameters (struct dvb_frontend* fe,
337 struct dvb_frontend_parameters *p) 337 struct dvb_frontend_parameters *p)
338{ 338{
339 struct sp887x_state* state = fe->demodulator_priv; 339 struct sp887x_state* state = fe->demodulator_priv;
340 int actual_freq, err; 340 unsigned actual_freq;
341 int err;
341 u16 val, reg0xc05; 342 u16 val, reg0xc05;
342 343
343 if (p->u.ofdm.bandwidth != BANDWIDTH_8_MHZ && 344 if (p->u.ofdm.bandwidth != BANDWIDTH_8_MHZ &&
diff --git a/drivers/media/dvb/frontends/stb6000.c b/drivers/media/dvb/frontends/stb6000.c
new file mode 100644
index 000000000000..0e2cb0df1441
--- /dev/null
+++ b/drivers/media/dvb/frontends/stb6000.c
@@ -0,0 +1,255 @@
1 /*
2 Driver for ST STB6000 DVBS Silicon tuner
3
4 Copyright (C) 2008 Igor M. Liplianin (liplianin@me.by)
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/module.h>
24#include <linux/dvb/frontend.h>
25#include <asm/types.h>
26
27#include "stb6000.h"
28
29static int debug;
30#define dprintk(args...) \
31 do { \
32 if (debug) \
33 printk(KERN_DEBUG "stb6000: " args); \
34 } while (0)
35
36struct stb6000_priv {
37 /* i2c details */
38 int i2c_address;
39 struct i2c_adapter *i2c;
40 u32 frequency;
41};
42
43static int stb6000_release(struct dvb_frontend *fe)
44{
45 kfree(fe->tuner_priv);
46 fe->tuner_priv = NULL;
47 return 0;
48}
49
50static int stb6000_sleep(struct dvb_frontend *fe)
51{
52 struct stb6000_priv *priv = fe->tuner_priv;
53 int ret;
54 u8 buf[] = { 10, 0 };
55 struct i2c_msg msg = {
56 .addr = priv->i2c_address,
57 .flags = 0,
58 .buf = buf,
59 .len = 2
60 };
61
62 dprintk("%s:\n", __func__);
63
64 if (fe->ops.i2c_gate_ctrl)
65 fe->ops.i2c_gate_ctrl(fe, 1);
66
67 ret = i2c_transfer(priv->i2c, &msg, 1);
68 if (ret != 1)
69 dprintk("%s: i2c error\n", __func__);
70
71 if (fe->ops.i2c_gate_ctrl)
72 fe->ops.i2c_gate_ctrl(fe, 0);
73
74 return (ret == 1) ? 0 : ret;
75}
76
77static int stb6000_set_params(struct dvb_frontend *fe,
78 struct dvb_frontend_parameters *params)
79{
80 struct stb6000_priv *priv = fe->tuner_priv;
81 unsigned int n, m;
82 int ret;
83 u32 freq_mhz;
84 int bandwidth;
85 u8 buf[12];
86 struct i2c_msg msg = {
87 .addr = priv->i2c_address,
88 .flags = 0,
89 .buf = buf,
90 .len = 12
91 };
92
93 dprintk("%s:\n", __func__);
94
95 freq_mhz = params->frequency / 1000;
96 bandwidth = params->u.qpsk.symbol_rate / 1000000;
97
98 if (bandwidth > 31)
99 bandwidth = 31;
100
101 if ((freq_mhz > 949) && (freq_mhz < 2151)) {
102 buf[0] = 0x01;
103 buf[1] = 0xac;
104 if (freq_mhz < 1950)
105 buf[1] = 0xaa;
106 if (freq_mhz < 1800)
107 buf[1] = 0xa8;
108 if (freq_mhz < 1650)
109 buf[1] = 0xa6;
110 if (freq_mhz < 1530)
111 buf[1] = 0xa5;
112 if (freq_mhz < 1470)
113 buf[1] = 0xa4;
114 if (freq_mhz < 1370)
115 buf[1] = 0xa2;
116 if (freq_mhz < 1300)
117 buf[1] = 0xa1;
118 if (freq_mhz < 1200)
119 buf[1] = 0xa0;
120 if (freq_mhz < 1075)
121 buf[1] = 0xbc;
122 if (freq_mhz < 1000)
123 buf[1] = 0xba;
124 if (freq_mhz < 1075) {
125 n = freq_mhz / 8; /* vco=lo*4 */
126 m = 2;
127 } else {
128 n = freq_mhz / 16; /* vco=lo*2 */
129 m = 1;
130 }
131 buf[2] = n >> 1;
132 buf[3] = (unsigned char)(((n & 1) << 7) |
133 (m * freq_mhz - n * 16) | 0x60);
134 buf[4] = 0x04;
135 buf[5] = 0x0e;
136
137 buf[6] = (unsigned char)(bandwidth);
138
139 buf[7] = 0xd8;
140 buf[8] = 0xd0;
141 buf[9] = 0x50;
142 buf[10] = 0xeb;
143 buf[11] = 0x4f;
144
145 if (fe->ops.i2c_gate_ctrl)
146 fe->ops.i2c_gate_ctrl(fe, 1);
147
148 ret = i2c_transfer(priv->i2c, &msg, 1);
149 if (ret != 1)
150 dprintk("%s: i2c error\n", __func__);
151
152 udelay(10);
153 if (fe->ops.i2c_gate_ctrl)
154 fe->ops.i2c_gate_ctrl(fe, 0);
155
156 buf[0] = 0x07;
157 buf[1] = 0xdf;
158 buf[2] = 0xd0;
159 buf[3] = 0x50;
160 buf[4] = 0xfb;
161 msg.len = 5;
162
163 if (fe->ops.i2c_gate_ctrl)
164 fe->ops.i2c_gate_ctrl(fe, 1);
165
166 ret = i2c_transfer(priv->i2c, &msg, 1);
167 if (ret != 1)
168 dprintk("%s: i2c error\n", __func__);
169
170 udelay(10);
171 if (fe->ops.i2c_gate_ctrl)
172 fe->ops.i2c_gate_ctrl(fe, 0);
173
174 priv->frequency = freq_mhz * 1000;
175
176 return (ret == 1) ? 0 : ret;
177 }
178 return -1;
179}
180
181static int stb6000_get_frequency(struct dvb_frontend *fe, u32 *frequency)
182{
183 struct stb6000_priv *priv = fe->tuner_priv;
184 *frequency = priv->frequency;
185 return 0;
186}
187
188static struct dvb_tuner_ops stb6000_tuner_ops = {
189 .info = {
190 .name = "ST STB6000",
191 .frequency_min = 950000,
192 .frequency_max = 2150000
193 },
194 .release = stb6000_release,
195 .sleep = stb6000_sleep,
196 .set_params = stb6000_set_params,
197 .get_frequency = stb6000_get_frequency,
198};
199
200struct dvb_frontend *stb6000_attach(struct dvb_frontend *fe, int addr,
201 struct i2c_adapter *i2c)
202{
203 struct stb6000_priv *priv = NULL;
204 u8 b0[] = { 0 };
205 u8 b1[] = { 0, 0 };
206 struct i2c_msg msg[2] = {
207 {
208 .addr = addr,
209 .flags = 0,
210 .buf = b0,
211 .len = 0
212 }, {
213 .addr = addr,
214 .flags = I2C_M_RD,
215 .buf = b1,
216 .len = 2
217 }
218 };
219 int ret;
220
221 dprintk("%s:\n", __func__);
222
223 if (fe->ops.i2c_gate_ctrl)
224 fe->ops.i2c_gate_ctrl(fe, 1);
225
226 /* is some i2c device here ? */
227 ret = i2c_transfer(i2c, msg, 2);
228 if (fe->ops.i2c_gate_ctrl)
229 fe->ops.i2c_gate_ctrl(fe, 0);
230
231 if (ret != 2)
232 return NULL;
233
234 priv = kzalloc(sizeof(struct stb6000_priv), GFP_KERNEL);
235 if (priv == NULL)
236 return NULL;
237
238 priv->i2c_address = addr;
239 priv->i2c = i2c;
240
241 memcpy(&fe->ops.tuner_ops, &stb6000_tuner_ops,
242 sizeof(struct dvb_tuner_ops));
243
244 fe->tuner_priv = priv;
245
246 return fe;
247}
248EXPORT_SYMBOL(stb6000_attach);
249
250module_param(debug, int, 0644);
251MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
252
253MODULE_DESCRIPTION("DVB STB6000 driver");
254MODULE_AUTHOR("Igor M. Liplianin <liplianin@me.by>");
255MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/stb6000.h b/drivers/media/dvb/frontends/stb6000.h
new file mode 100644
index 000000000000..7be479c22d5b
--- /dev/null
+++ b/drivers/media/dvb/frontends/stb6000.h
@@ -0,0 +1,51 @@
1 /*
2 Driver for ST stb6000 DVBS Silicon tuner
3
4 Copyright (C) 2008 Igor M. Liplianin (liplianin@me.by)
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_STB6000_H__
24#define __DVB_STB6000_H__
25
26#include <linux/i2c.h>
27#include "dvb_frontend.h"
28
29/**
30 * Attach a stb6000 tuner to the supplied frontend structure.
31 *
32 * @param fe Frontend to attach to.
33 * @param addr i2c address of the tuner.
34 * @param i2c i2c adapter to use.
35 * @return FE pointer on success, NULL on failure.
36 */
37#if defined(CONFIG_DVB_STB6000) || (defined(CONFIG_DVB_STB6000_MODULE) \
38 && defined(MODULE))
39extern struct dvb_frontend *stb6000_attach(struct dvb_frontend *fe, int addr,
40 struct i2c_adapter *i2c);
41#else
42static inline struct dvb_frontend *stb6000_attach(struct dvb_frontend *fe,
43 int addr,
44 struct i2c_adapter *i2c)
45{
46 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
47 return NULL;
48}
49#endif /* CONFIG_DVB_STB6000 */
50
51#endif /* __DVB_STB6000_H__ */
diff --git a/drivers/media/dvb/frontends/stv0288.c b/drivers/media/dvb/frontends/stv0288.c
new file mode 100644
index 000000000000..ff1194de34c0
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv0288.c
@@ -0,0 +1,618 @@
1/*
2 Driver for ST STV0288 demodulator
3 Copyright (C) 2006 Georg Acher, BayCom GmbH, acher (at) baycom (dot) de
4 for Reel Multimedia
5 Copyright (C) 2008 TurboSight.com, Bob Liu <bob@turbosight.com>
6 Copyright (C) 2008 Igor M. Liplianin <liplianin@me.by>
7 Removed stb6000 specific tuner code and revised some
8 procedures.
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*/
25
26#include <linux/init.h>
27#include <linux/kernel.h>
28#include <linux/module.h>
29#include <linux/string.h>
30#include <linux/slab.h>
31#include <linux/jiffies.h>
32#include <asm/div64.h>
33
34#include "dvb_frontend.h"
35#include "stv0288.h"
36
37struct stv0288_state {
38 struct i2c_adapter *i2c;
39 const struct stv0288_config *config;
40 struct dvb_frontend frontend;
41
42 u8 initialised:1;
43 u32 tuner_frequency;
44 u32 symbol_rate;
45 fe_code_rate_t fec_inner;
46 int errmode;
47};
48
49#define STATUS_BER 0
50#define STATUS_UCBLOCKS 1
51
52static int debug;
53static int debug_legacy_dish_switch;
54#define dprintk(args...) \
55 do { \
56 if (debug) \
57 printk(KERN_DEBUG "stv0288: " args); \
58 } while (0)
59
60
61static int stv0288_writeregI(struct stv0288_state *state, u8 reg, u8 data)
62{
63 int ret;
64 u8 buf[] = { reg, data };
65 struct i2c_msg msg = {
66 .addr = state->config->demod_address,
67 .flags = 0,
68 .buf = buf,
69 .len = 2
70 };
71
72 ret = i2c_transfer(state->i2c, &msg, 1);
73
74 if (ret != 1)
75 dprintk("%s: writereg error (reg == 0x%02x, val == 0x%02x, "
76 "ret == %i)\n", __func__, reg, data, ret);
77
78 return (ret != 1) ? -EREMOTEIO : 0;
79}
80
81static int stv0288_write(struct dvb_frontend *fe, u8 *buf, int len)
82{
83 struct stv0288_state *state = fe->demodulator_priv;
84
85 if (len != 2)
86 return -EINVAL;
87
88 return stv0288_writeregI(state, buf[0], buf[1]);
89}
90
91static u8 stv0288_readreg(struct stv0288_state *state, u8 reg)
92{
93 int ret;
94 u8 b0[] = { reg };
95 u8 b1[] = { 0 };
96 struct i2c_msg msg[] = {
97 {
98 .addr = state->config->demod_address,
99 .flags = 0,
100 .buf = b0,
101 .len = 1
102 }, {
103 .addr = state->config->demod_address,
104 .flags = I2C_M_RD,
105 .buf = b1,
106 .len = 1
107 }
108 };
109
110 ret = i2c_transfer(state->i2c, msg, 2);
111
112 if (ret != 2)
113 dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n",
114 __func__, reg, ret);
115
116 return b1[0];
117}
118
119static int stv0288_set_symbolrate(struct dvb_frontend *fe, u32 srate)
120{
121 struct stv0288_state *state = fe->demodulator_priv;
122 unsigned int temp;
123 unsigned char b[3];
124
125 if ((srate < 1000000) || (srate > 45000000))
126 return -EINVAL;
127
128 temp = (unsigned int)srate / 1000;
129
130 temp = temp * 32768;
131 temp = temp / 25;
132 temp = temp / 125;
133 b[0] = (unsigned char)((temp >> 12) & 0xff);
134 b[1] = (unsigned char)((temp >> 4) & 0xff);
135 b[2] = (unsigned char)((temp << 4) & 0xf0);
136 stv0288_writeregI(state, 0x28, 0x80); /* SFRH */
137 stv0288_writeregI(state, 0x29, 0); /* SFRM */
138 stv0288_writeregI(state, 0x2a, 0); /* SFRL */
139
140 stv0288_writeregI(state, 0x28, b[0]);
141 stv0288_writeregI(state, 0x29, b[1]);
142 stv0288_writeregI(state, 0x2a, b[2]);
143 dprintk("stv0288: stv0288_set_symbolrate\n");
144
145 return 0;
146}
147
148static int stv0288_send_diseqc_msg(struct dvb_frontend *fe,
149 struct dvb_diseqc_master_cmd *m)
150{
151 struct stv0288_state *state = fe->demodulator_priv;
152
153 int i;
154
155 dprintk("%s\n", __func__);
156
157 stv0288_writeregI(state, 0x09, 0);
158 msleep(30);
159 stv0288_writeregI(state, 0x05, 0x16);
160
161 for (i = 0; i < m->msg_len; i++) {
162 if (stv0288_writeregI(state, 0x06, m->msg[i]))
163 return -EREMOTEIO;
164 msleep(12);
165 }
166
167 return 0;
168}
169
170static int stv0288_send_diseqc_burst(struct dvb_frontend *fe,
171 fe_sec_mini_cmd_t burst)
172{
173 struct stv0288_state *state = fe->demodulator_priv;
174
175 dprintk("%s\n", __func__);
176
177 if (stv0288_writeregI(state, 0x05, 0x16))/* burst mode */
178 return -EREMOTEIO;
179
180 if (stv0288_writeregI(state, 0x06, burst == SEC_MINI_A ? 0x00 : 0xff))
181 return -EREMOTEIO;
182
183 if (stv0288_writeregI(state, 0x06, 0x12))
184 return -EREMOTEIO;
185
186 return 0;
187}
188
189static int stv0288_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
190{
191 struct stv0288_state *state = fe->demodulator_priv;
192
193 switch (tone) {
194 case SEC_TONE_ON:
195 if (stv0288_writeregI(state, 0x05, 0x10))/* burst mode */
196 return -EREMOTEIO;
197 return stv0288_writeregI(state, 0x06, 0xff);
198
199 case SEC_TONE_OFF:
200 if (stv0288_writeregI(state, 0x05, 0x13))/* burst mode */
201 return -EREMOTEIO;
202 return stv0288_writeregI(state, 0x06, 0x00);
203
204 default:
205 return -EINVAL;
206 }
207}
208
209static u8 stv0288_inittab[] = {
210 0x01, 0x15,
211 0x02, 0x20,
212 0x09, 0x0,
213 0x0a, 0x4,
214 0x0b, 0x0,
215 0x0c, 0x0,
216 0x0d, 0x0,
217 0x0e, 0xd4,
218 0x0f, 0x30,
219 0x11, 0x80,
220 0x12, 0x03,
221 0x13, 0x48,
222 0x14, 0x84,
223 0x15, 0x45,
224 0x16, 0xb7,
225 0x17, 0x9c,
226 0x18, 0x0,
227 0x19, 0xa6,
228 0x1a, 0x88,
229 0x1b, 0x8f,
230 0x1c, 0xf0,
231 0x20, 0x0b,
232 0x21, 0x54,
233 0x22, 0x0,
234 0x23, 0x0,
235 0x2b, 0xff,
236 0x2c, 0xf7,
237 0x30, 0x0,
238 0x31, 0x1e,
239 0x32, 0x14,
240 0x33, 0x0f,
241 0x34, 0x09,
242 0x35, 0x0c,
243 0x36, 0x05,
244 0x37, 0x2f,
245 0x38, 0x16,
246 0x39, 0xbe,
247 0x3a, 0x0,
248 0x3b, 0x13,
249 0x3c, 0x11,
250 0x3d, 0x30,
251 0x40, 0x63,
252 0x41, 0x04,
253 0x42, 0x60,
254 0x43, 0x00,
255 0x44, 0x00,
256 0x45, 0x00,
257 0x46, 0x00,
258 0x47, 0x00,
259 0x4a, 0x00,
260 0x50, 0x10,
261 0x51, 0x38,
262 0x52, 0x21,
263 0x58, 0x54,
264 0x59, 0x86,
265 0x5a, 0x0,
266 0x5b, 0x9b,
267 0x5c, 0x08,
268 0x5d, 0x7f,
269 0x5e, 0x0,
270 0x5f, 0xff,
271 0x70, 0x0,
272 0x71, 0x0,
273 0x72, 0x0,
274 0x74, 0x0,
275 0x75, 0x0,
276 0x76, 0x0,
277 0x81, 0x0,
278 0x82, 0x3f,
279 0x83, 0x3f,
280 0x84, 0x0,
281 0x85, 0x0,
282 0x88, 0x0,
283 0x89, 0x0,
284 0x8a, 0x0,
285 0x8b, 0x0,
286 0x8c, 0x0,
287 0x90, 0x0,
288 0x91, 0x0,
289 0x92, 0x0,
290 0x93, 0x0,
291 0x94, 0x1c,
292 0x97, 0x0,
293 0xa0, 0x48,
294 0xa1, 0x0,
295 0xb0, 0xb8,
296 0xb1, 0x3a,
297 0xb2, 0x10,
298 0xb3, 0x82,
299 0xb4, 0x80,
300 0xb5, 0x82,
301 0xb6, 0x82,
302 0xb7, 0x82,
303 0xb8, 0x20,
304 0xb9, 0x0,
305 0xf0, 0x0,
306 0xf1, 0x0,
307 0xf2, 0xc0,
308 0x51, 0x36,
309 0x52, 0x09,
310 0x53, 0x94,
311 0x54, 0x62,
312 0x55, 0x29,
313 0x56, 0x64,
314 0x57, 0x2b,
315 0xff, 0xff,
316};
317
318static int stv0288_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t volt)
319{
320 dprintk("%s: %s\n", __func__,
321 volt == SEC_VOLTAGE_13 ? "SEC_VOLTAGE_13" :
322 volt == SEC_VOLTAGE_18 ? "SEC_VOLTAGE_18" : "??");
323
324 return 0;
325}
326
327static int stv0288_init(struct dvb_frontend *fe)
328{
329 struct stv0288_state *state = fe->demodulator_priv;
330 int i;
331 u8 reg;
332 u8 val;
333
334 dprintk("stv0288: init chip\n");
335 stv0288_writeregI(state, 0x41, 0x04);
336 msleep(50);
337
338 /* we have default inittab */
339 if (state->config->inittab == NULL) {
340 for (i = 0; !(stv0288_inittab[i] == 0xff &&
341 stv0288_inittab[i + 1] == 0xff); i += 2)
342 stv0288_writeregI(state, stv0288_inittab[i],
343 stv0288_inittab[i + 1]);
344 } else {
345 for (i = 0; ; i += 2) {
346 reg = state->config->inittab[i];
347 val = state->config->inittab[i+1];
348 if (reg == 0xff && val == 0xff)
349 break;
350 stv0288_writeregI(state, reg, val);
351 }
352 }
353 return 0;
354}
355
356static int stv0288_read_status(struct dvb_frontend *fe, fe_status_t *status)
357{
358 struct stv0288_state *state = fe->demodulator_priv;
359
360 u8 sync = stv0288_readreg(state, 0x24);
361 if (sync == 255)
362 sync = 0;
363
364 dprintk("%s : FE_READ_STATUS : VSTATUS: 0x%02x\n", __func__, sync);
365
366 *status = 0;
367
368 if ((sync & 0x08) == 0x08) {
369 *status |= FE_HAS_LOCK;
370 dprintk("stv0288 has locked\n");
371 }
372
373 return 0;
374}
375
376static int stv0288_read_ber(struct dvb_frontend *fe, u32 *ber)
377{
378 struct stv0288_state *state = fe->demodulator_priv;
379
380 if (state->errmode != STATUS_BER)
381 return 0;
382 *ber = (stv0288_readreg(state, 0x26) << 8) |
383 stv0288_readreg(state, 0x27);
384 dprintk("stv0288_read_ber %d\n", *ber);
385
386 return 0;
387}
388
389
390static int stv0288_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
391{
392 struct stv0288_state *state = fe->demodulator_priv;
393
394 s32 signal = 0xffff - ((stv0288_readreg(state, 0x10) << 8));
395
396
397 signal = signal * 5 / 4;
398 *strength = (signal > 0xffff) ? 0xffff : (signal < 0) ? 0 : signal;
399 dprintk("stv0288_read_signal_strength %d\n", *strength);
400
401 return 0;
402}
403static int stv0288_sleep(struct dvb_frontend *fe)
404{
405 struct stv0288_state *state = fe->demodulator_priv;
406
407 stv0288_writeregI(state, 0x41, 0x84);
408 state->initialised = 0;
409
410 return 0;
411}
412static int stv0288_read_snr(struct dvb_frontend *fe, u16 *snr)
413{
414 struct stv0288_state *state = fe->demodulator_priv;
415
416 s32 xsnr = 0xffff - ((stv0288_readreg(state, 0x2d) << 8)
417 | stv0288_readreg(state, 0x2e));
418 xsnr = 3 * (xsnr - 0xa100);
419 *snr = (xsnr > 0xffff) ? 0xffff : (xsnr < 0) ? 0 : xsnr;
420 dprintk("stv0288_read_snr %d\n", *snr);
421
422 return 0;
423}
424
425static int stv0288_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
426{
427 struct stv0288_state *state = fe->demodulator_priv;
428
429 if (state->errmode != STATUS_BER)
430 return 0;
431 *ucblocks = (stv0288_readreg(state, 0x26) << 8) |
432 stv0288_readreg(state, 0x27);
433 dprintk("stv0288_read_ber %d\n", *ucblocks);
434
435 return 0;
436}
437
438static int stv0288_set_property(struct dvb_frontend *fe, struct dtv_property *p)
439{
440 dprintk("%s(..)\n", __func__);
441 return 0;
442}
443
444static int stv0288_get_property(struct dvb_frontend *fe, struct dtv_property *p)
445{
446 dprintk("%s(..)\n", __func__);
447 return 0;
448}
449
450static int stv0288_set_frontend(struct dvb_frontend *fe,
451 struct dvb_frontend_parameters *dfp)
452{
453 struct stv0288_state *state = fe->demodulator_priv;
454 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
455
456 char tm;
457 unsigned char tda[3];
458
459 dprintk("%s : FE_SET_FRONTEND\n", __func__);
460
461 if (c->delivery_system != SYS_DVBS) {
462 dprintk("%s: unsupported delivery "
463 "system selected (%d)\n",
464 __func__, c->delivery_system);
465 return -EOPNOTSUPP;
466 }
467
468 if (state->config->set_ts_params)
469 state->config->set_ts_params(fe, 0);
470
471 /* only frequency & symbol_rate are used for tuner*/
472 dfp->frequency = c->frequency;
473 dfp->u.qpsk.symbol_rate = c->symbol_rate;
474 if (fe->ops.tuner_ops.set_params) {
475 fe->ops.tuner_ops.set_params(fe, dfp);
476 if (fe->ops.i2c_gate_ctrl)
477 fe->ops.i2c_gate_ctrl(fe, 0);
478 }
479
480 udelay(10);
481 stv0288_set_symbolrate(fe, c->symbol_rate);
482 /* Carrier lock control register */
483 stv0288_writeregI(state, 0x15, 0xc5);
484
485 tda[0] = 0x2b; /* CFRM */
486 tda[2] = 0x0; /* CFRL */
487 for (tm = -6; tm < 7;) {
488 /* Viterbi status */
489 if (stv0288_readreg(state, 0x24) & 0x80)
490 break;
491
492 tda[2] += 40;
493 if (tda[2] < 40)
494 tm++;
495 tda[1] = (unsigned char)tm;
496 stv0288_writeregI(state, 0x2b, tda[1]);
497 stv0288_writeregI(state, 0x2c, tda[2]);
498 udelay(30);
499 }
500
501 state->tuner_frequency = c->frequency;
502 state->fec_inner = FEC_AUTO;
503 state->symbol_rate = c->symbol_rate;
504
505 return 0;
506}
507
508static int stv0288_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
509{
510 struct stv0288_state *state = fe->demodulator_priv;
511
512 if (enable)
513 stv0288_writeregI(state, 0x01, 0xb5);
514 else
515 stv0288_writeregI(state, 0x01, 0x35);
516
517 udelay(1);
518
519 return 0;
520}
521
522static void stv0288_release(struct dvb_frontend *fe)
523{
524 struct stv0288_state *state = fe->demodulator_priv;
525 kfree(state);
526}
527
528static struct dvb_frontend_ops stv0288_ops = {
529
530 .info = {
531 .name = "ST STV0288 DVB-S",
532 .type = FE_QPSK,
533 .frequency_min = 950000,
534 .frequency_max = 2150000,
535 .frequency_stepsize = 1000, /* kHz for QPSK frontends */
536 .frequency_tolerance = 0,
537 .symbol_rate_min = 1000000,
538 .symbol_rate_max = 45000000,
539 .symbol_rate_tolerance = 500, /* ppm */
540 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
541 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
542 FE_CAN_QPSK |
543 FE_CAN_FEC_AUTO
544 },
545
546 .release = stv0288_release,
547 .init = stv0288_init,
548 .sleep = stv0288_sleep,
549 .write = stv0288_write,
550 .i2c_gate_ctrl = stv0288_i2c_gate_ctrl,
551 .read_status = stv0288_read_status,
552 .read_ber = stv0288_read_ber,
553 .read_signal_strength = stv0288_read_signal_strength,
554 .read_snr = stv0288_read_snr,
555 .read_ucblocks = stv0288_read_ucblocks,
556 .diseqc_send_master_cmd = stv0288_send_diseqc_msg,
557 .diseqc_send_burst = stv0288_send_diseqc_burst,
558 .set_tone = stv0288_set_tone,
559 .set_voltage = stv0288_set_voltage,
560
561 .set_property = stv0288_set_property,
562 .get_property = stv0288_get_property,
563 .set_frontend = stv0288_set_frontend,
564};
565
566struct dvb_frontend *stv0288_attach(const struct stv0288_config *config,
567 struct i2c_adapter *i2c)
568{
569 struct stv0288_state *state = NULL;
570 int id;
571
572 /* allocate memory for the internal state */
573 state = kmalloc(sizeof(struct stv0288_state), GFP_KERNEL);
574 if (state == NULL)
575 goto error;
576
577 /* setup the state */
578 state->config = config;
579 state->i2c = i2c;
580 state->initialised = 0;
581 state->tuner_frequency = 0;
582 state->symbol_rate = 0;
583 state->fec_inner = 0;
584 state->errmode = STATUS_BER;
585
586 stv0288_writeregI(state, 0x41, 0x04);
587 msleep(200);
588 id = stv0288_readreg(state, 0x00);
589 dprintk("stv0288 id %x\n", id);
590
591 /* register 0x00 contains 0x11 for STV0288 */
592 if (id != 0x11)
593 goto error;
594
595 /* create dvb_frontend */
596 memcpy(&state->frontend.ops, &stv0288_ops,
597 sizeof(struct dvb_frontend_ops));
598 state->frontend.demodulator_priv = state;
599 return &state->frontend;
600
601error:
602 kfree(state);
603
604 return NULL;
605}
606EXPORT_SYMBOL(stv0288_attach);
607
608module_param(debug_legacy_dish_switch, int, 0444);
609MODULE_PARM_DESC(debug_legacy_dish_switch,
610 "Enable timing analysis for Dish Network legacy switches");
611
612module_param(debug, int, 0644);
613MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
614
615MODULE_DESCRIPTION("ST STV0288 DVB Demodulator driver");
616MODULE_AUTHOR("Georg Acher, Bob Liu, Igor liplianin");
617MODULE_LICENSE("GPL");
618
diff --git a/drivers/media/dvb/frontends/stv0288.h b/drivers/media/dvb/frontends/stv0288.h
new file mode 100644
index 000000000000..f2b53db0606d
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv0288.h
@@ -0,0 +1,67 @@
1/*
2 Driver for ST STV0288 demodulator
3
4 Copyright (C) 2006 Georg Acher, BayCom GmbH, acher (at) baycom (dot) de
5 for Reel Multimedia
6 Copyright (C) 2008 TurboSight.com, <bob@turbosight.com>
7 Copyright (C) 2008 Igor M. Liplianin <liplianin@me.by>
8 Removed stb6000 specific tuner code and revised some
9 procedures.
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 STV0288_H
28#define STV0288_H
29
30#include <linux/dvb/frontend.h>
31#include "dvb_frontend.h"
32
33struct stv0288_config {
34 /* the demodulator's i2c address */
35 u8 demod_address;
36
37 u8* inittab;
38
39 /* minimum delay before retuning */
40 int min_delay_ms;
41
42 int (*set_ts_params)(struct dvb_frontend *fe, int is_punctured);
43};
44
45#if defined(CONFIG_DVB_STV0288) || (defined(CONFIG_DVB_STV0288_MODULE) && \
46 defined(MODULE))
47extern struct dvb_frontend *stv0288_attach(const struct stv0288_config *config,
48 struct i2c_adapter *i2c);
49#else
50static inline struct dvb_frontend *stv0288_attach(const struct stv0288_config *config,
51 struct i2c_adapter *i2c)
52{
53 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
54 return NULL;
55}
56#endif /* CONFIG_DVB_STV0288 */
57
58static inline int stv0288_writereg(struct dvb_frontend *fe, u8 reg, u8 val)
59{
60 int r = 0;
61 u8 buf[] = { reg, val };
62 if (fe->ops.write)
63 r = fe->ops.write(fe, buf, 2);
64 return r;
65}
66
67#endif /* STV0288_H */
diff --git a/drivers/media/dvb/frontends/stv0299.c b/drivers/media/dvb/frontends/stv0299.c
index 35435bef8e79..6c1cb1973c6e 100644
--- a/drivers/media/dvb/frontends/stv0299.c
+++ b/drivers/media/dvb/frontends/stv0299.c
@@ -559,6 +559,8 @@ static int stv0299_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par
559 int invval = 0; 559 int invval = 0;
560 560
561 dprintk ("%s : FE_SET_FRONTEND\n", __func__); 561 dprintk ("%s : FE_SET_FRONTEND\n", __func__);
562 if (state->config->set_ts_params)
563 state->config->set_ts_params(fe, 0);
562 564
563 // set the inversion 565 // set the inversion
564 if (p->inversion == INVERSION_OFF) invval = 0; 566 if (p->inversion == INVERSION_OFF) invval = 0;
diff --git a/drivers/media/dvb/frontends/stv0299.h b/drivers/media/dvb/frontends/stv0299.h
index 3282f43022f5..0fd96e22b650 100644
--- a/drivers/media/dvb/frontends/stv0299.h
+++ b/drivers/media/dvb/frontends/stv0299.h
@@ -89,15 +89,18 @@ struct stv0299_config
89 int min_delay_ms; 89 int min_delay_ms;
90 90
91 /* Set the symbol rate */ 91 /* Set the symbol rate */
92 int (*set_symbol_rate)(struct dvb_frontend* fe, u32 srate, u32 ratio); 92 int (*set_symbol_rate)(struct dvb_frontend *fe, u32 srate, u32 ratio);
93
94 /* Set device param to start dma */
95 int (*set_ts_params)(struct dvb_frontend *fe, int is_punctured);
93}; 96};
94 97
95#if defined(CONFIG_DVB_STV0299) || (defined(CONFIG_DVB_STV0299_MODULE) && defined(MODULE)) 98#if defined(CONFIG_DVB_STV0299) || (defined(CONFIG_DVB_STV0299_MODULE) && defined(MODULE))
96extern struct dvb_frontend* stv0299_attach(const struct stv0299_config* config, 99extern struct dvb_frontend *stv0299_attach(const struct stv0299_config *config,
97 struct i2c_adapter* i2c); 100 struct i2c_adapter *i2c);
98#else 101#else
99static inline struct dvb_frontend* stv0299_attach(const struct stv0299_config* config, 102static inline struct dvb_frontend *stv0299_attach(const struct stv0299_config *config,
100 struct i2c_adapter* i2c) 103 struct i2c_adapter *i2c)
101{ 104{
102 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); 105 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
103 return NULL; 106 return NULL;
diff --git a/drivers/media/dvb/frontends/tdhd1.h b/drivers/media/dvb/frontends/tdhd1.h
new file mode 100644
index 000000000000..51f170678650
--- /dev/null
+++ b/drivers/media/dvb/frontends/tdhd1.h
@@ -0,0 +1,73 @@
1/*
2 * tdhd1.h - ALPS TDHD1-204A tuner support
3 *
4 * Copyright (C) 2008 Oliver Endriss <o.endriss@gmx.de>
5 *
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
9 * as published by the Free Software Foundation; either version 2
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 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 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
21 *
22 *
23 * The project's page is at http://www.linuxtv.org
24 */
25
26#ifndef TDHD1_H
27#define TDHD1_H
28
29#include "tda1004x.h"
30
31static int alps_tdhd1_204_request_firmware(struct dvb_frontend *fe, const struct firmware **fw, char *name);
32
33static struct tda1004x_config alps_tdhd1_204a_config = {
34 .demod_address = 0x8,
35 .invert = 1,
36 .invert_oclk = 0,
37 .xtal_freq = TDA10046_XTAL_4M,
38 .agc_config = TDA10046_AGC_DEFAULT,
39 .if_freq = TDA10046_FREQ_3617,
40 .request_firmware = alps_tdhd1_204_request_firmware
41};
42
43static int alps_tdhd1_204a_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
44{
45 struct i2c_adapter *i2c = fe->tuner_priv;
46 u8 data[4];
47 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
48 u32 div;
49
50 div = (params->frequency + 36166666) / 166666;
51
52 data[0] = (div >> 8) & 0x7f;
53 data[1] = div & 0xff;
54 data[2] = 0x85;
55
56 if (params->frequency >= 174000000 && params->frequency <= 230000000)
57 data[3] = 0x02;
58 else if (params->frequency >= 470000000 && params->frequency <= 823000000)
59 data[3] = 0x0C;
60 else if (params->frequency > 823000000 && params->frequency <= 862000000)
61 data[3] = 0x8C;
62 else
63 return -EINVAL;
64
65 if (fe->ops.i2c_gate_ctrl)
66 fe->ops.i2c_gate_ctrl(fe, 1);
67 if (i2c_transfer(i2c, &msg, 1) != 1)
68 return -EIO;
69
70 return 0;
71}
72
73#endif /* TDHD1_H */
diff --git a/drivers/media/dvb/ttpci/Kconfig b/drivers/media/dvb/ttpci/Kconfig
index 41b5a988b619..867027ceab3e 100644
--- a/drivers/media/dvb/ttpci/Kconfig
+++ b/drivers/media/dvb/ttpci/Kconfig
@@ -86,6 +86,7 @@ config DVB_BUDGET
86 select DVB_TDA10086 if !DVB_FE_CUSTOMISE 86 select DVB_TDA10086 if !DVB_FE_CUSTOMISE
87 select DVB_TDA826X if !DVB_FE_CUSTOMISE 87 select DVB_TDA826X if !DVB_FE_CUSTOMISE
88 select DVB_LNBP21 if !DVB_FE_CUSTOMISE 88 select DVB_LNBP21 if !DVB_FE_CUSTOMISE
89 select DVB_TDA1004X if !DVB_FE_CUSTOMISE
89 help 90 help
90 Support for simple SAA7146 based DVB cards (so called Budget- 91 Support for simple SAA7146 based DVB cards (so called Budget-
91 or Nova-PCI cards) without onboard MPEG2 decoder, and without 92 or Nova-PCI cards) without onboard MPEG2 decoder, and without
diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c
index 0777e8f9544b..c7c770c28988 100644
--- a/drivers/media/dvb/ttpci/av7110.c
+++ b/drivers/media/dvb/ttpci/av7110.c
@@ -88,6 +88,7 @@ static int budgetpatch;
88static int wss_cfg_4_3 = 0x4008; 88static int wss_cfg_4_3 = 0x4008;
89static int wss_cfg_16_9 = 0x0007; 89static int wss_cfg_16_9 = 0x0007;
90static int tv_standard; 90static int tv_standard;
91static int full_ts;
91 92
92module_param_named(debug, av7110_debug, int, 0644); 93module_param_named(debug, av7110_debug, int, 0644);
93MODULE_PARM_DESC(debug, "debug level (bitmask, default 0)"); 94MODULE_PARM_DESC(debug, "debug level (bitmask, default 0)");
@@ -106,6 +107,8 @@ module_param(volume, int, 0444);
106MODULE_PARM_DESC(volume, "initial volume: default 255 (range 0-255)"); 107MODULE_PARM_DESC(volume, "initial volume: default 255 (range 0-255)");
107module_param(budgetpatch, int, 0444); 108module_param(budgetpatch, int, 0444);
108MODULE_PARM_DESC(budgetpatch, "use budget-patch hardware modification: default 0 (0 no, 1 autodetect, 2 always)"); 109MODULE_PARM_DESC(budgetpatch, "use budget-patch hardware modification: default 0 (0 no, 1 autodetect, 2 always)");
110module_param(full_ts, int, 0444);
111MODULE_PARM_DESC(full_ts, "enable code for full-ts hardware modification: 0 disable (default), 1 enable");
109module_param(wss_cfg_4_3, int, 0444); 112module_param(wss_cfg_4_3, int, 0444);
110MODULE_PARM_DESC(wss_cfg_4_3, "WSS 4:3 - default 0x4008 - bit 15: disable, 14: burst mode, 13..0: wss data"); 113MODULE_PARM_DESC(wss_cfg_4_3, "WSS 4:3 - default 0x4008 - bit 15: disable, 14: burst mode, 13..0: wss data");
111module_param(wss_cfg_16_9, int, 0444); 114module_param(wss_cfg_16_9, int, 0444);
@@ -116,6 +119,8 @@ MODULE_PARM_DESC(tv_standard, "TV standard: 0 PAL (default), 1 NTSC");
116DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); 119DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
117 120
118static void restart_feeds(struct av7110 *av7110); 121static void restart_feeds(struct av7110 *av7110);
122static int budget_start_feed(struct dvb_demux_feed *feed);
123static int budget_stop_feed(struct dvb_demux_feed *feed);
119 124
120static int av7110_num; 125static int av7110_num;
121 126
@@ -376,9 +381,9 @@ static inline void start_debi_dma(struct av7110 *av7110, int dir,
376 irdebi(av7110, DEBISWAB, addr, 0, len); 381 irdebi(av7110, DEBISWAB, addr, 0, len);
377} 382}
378 383
379static void debiirq(unsigned long data) 384static void debiirq(unsigned long cookie)
380{ 385{
381 struct av7110 *av7110 = (struct av7110 *) data; 386 struct av7110 *av7110 = (struct av7110 *)cookie;
382 int type = av7110->debitype; 387 int type = av7110->debitype;
383 int handle = (type >> 8) & 0x1f; 388 int handle = (type >> 8) & 0x1f;
384 unsigned int xfer = 0; 389 unsigned int xfer = 0;
@@ -487,9 +492,9 @@ debi_done:
487} 492}
488 493
489/* irq from av7110 firmware writing the mailbox register in the DPRAM */ 494/* irq from av7110 firmware writing the mailbox register in the DPRAM */
490static void gpioirq(unsigned long data) 495static void gpioirq(unsigned long cookie)
491{ 496{
492 struct av7110 *av7110 = (struct av7110 *) data; 497 struct av7110 *av7110 = (struct av7110 *)cookie;
493 u32 rxbuf, txbuf; 498 u32 rxbuf, txbuf;
494 int len; 499 int len;
495 500
@@ -806,6 +811,9 @@ static int StartHWFilter(struct dvb_demux_filter *dvbdmxfilter)
806 811
807 dprintk(4, "%p\n", av7110); 812 dprintk(4, "%p\n", av7110);
808 813
814 if (av7110->full_ts)
815 return 0;
816
809 if (dvbdmxfilter->type == DMX_TYPE_SEC) { 817 if (dvbdmxfilter->type == DMX_TYPE_SEC) {
810 if (hw_sections) { 818 if (hw_sections) {
811 buf[4] = (dvbdmxfilter->filter.filter_value[0] << 8) | 819 buf[4] = (dvbdmxfilter->filter.filter_value[0] << 8) |
@@ -854,6 +862,9 @@ static int StopHWFilter(struct dvb_demux_filter *dvbdmxfilter)
854 862
855 dprintk(4, "%p\n", av7110); 863 dprintk(4, "%p\n", av7110);
856 864
865 if (av7110->full_ts)
866 return 0;
867
857 handle = dvbdmxfilter->hw_handle; 868 handle = dvbdmxfilter->hw_handle;
858 if (handle >= 32) { 869 if (handle >= 32) {
859 printk("%s tried to stop invalid filter %04x, filter type = %x\n", 870 printk("%s tried to stop invalid filter %04x, filter type = %x\n",
@@ -913,7 +924,7 @@ static int dvb_feed_start_pid(struct dvb_demux_feed *dvbdmxfeed)
913 return ret; 924 return ret;
914 } 925 }
915 926
916 if ((dvbdmxfeed->ts_type & TS_PACKET)) { 927 if ((dvbdmxfeed->ts_type & TS_PACKET) && !av7110->full_ts) {
917 if (dvbdmxfeed->pes_type == 0 && !(dvbdmx->pids[0] & 0x8000)) 928 if (dvbdmxfeed->pes_type == 0 && !(dvbdmx->pids[0] & 0x8000))
918 ret = av7110_av_start_record(av7110, RP_AUDIO, dvbdmxfeed); 929 ret = av7110_av_start_record(av7110, RP_AUDIO, dvbdmxfeed);
919 if (dvbdmxfeed->pes_type == 1 && !(dvbdmx->pids[1] & 0x8000)) 930 if (dvbdmxfeed->pes_type == 1 && !(dvbdmx->pids[1] & 0x8000))
@@ -974,7 +985,7 @@ static int av7110_start_feed(struct dvb_demux_feed *feed)
974 if (!demux->dmx.frontend) 985 if (!demux->dmx.frontend)
975 return -EINVAL; 986 return -EINVAL;
976 987
977 if (feed->pid > 0x1fff) 988 if (!av7110->full_ts && feed->pid > 0x1fff)
978 return -EINVAL; 989 return -EINVAL;
979 990
980 if (feed->type == DMX_TYPE_TS) { 991 if (feed->type == DMX_TYPE_TS) {
@@ -1003,7 +1014,12 @@ static int av7110_start_feed(struct dvb_demux_feed *feed)
1003 } 1014 }
1004 } 1015 }
1005 1016
1006 else if (feed->type == DMX_TYPE_SEC) { 1017 if (av7110->full_ts) {
1018 budget_start_feed(feed);
1019 return ret;
1020 }
1021
1022 if (feed->type == DMX_TYPE_SEC) {
1007 int i; 1023 int i;
1008 1024
1009 for (i = 0; i < demux->filternum; i++) { 1025 for (i = 0; i < demux->filternum; i++) {
@@ -1050,7 +1066,12 @@ static int av7110_stop_feed(struct dvb_demux_feed *feed)
1050 ret = StopHWFilter(feed->filter); 1066 ret = StopHWFilter(feed->filter);
1051 } 1067 }
1052 1068
1053 if (!ret && feed->type == DMX_TYPE_SEC) { 1069 if (av7110->full_ts) {
1070 budget_stop_feed(feed);
1071 return ret;
1072 }
1073
1074 if (feed->type == DMX_TYPE_SEC) {
1054 for (i = 0; i<demux->filternum; i++) { 1075 for (i = 0; i<demux->filternum; i++) {
1055 if (demux->filter[i].state == DMX_STATE_GO && 1076 if (demux->filter[i].state == DMX_STATE_GO &&
1056 demux->filter[i].filter.parent == &feed->feed.sec) { 1077 demux->filter[i].filter.parent == &feed->feed.sec) {
@@ -1074,6 +1095,7 @@ static void restart_feeds(struct av7110 *av7110)
1074 struct dvb_demux *dvbdmx = &av7110->demux; 1095 struct dvb_demux *dvbdmx = &av7110->demux;
1075 struct dvb_demux_feed *feed; 1096 struct dvb_demux_feed *feed;
1076 int mode; 1097 int mode;
1098 int feeding;
1077 int i, j; 1099 int i, j;
1078 1100
1079 dprintk(4, "%p\n", av7110); 1101 dprintk(4, "%p\n", av7110);
@@ -1082,6 +1104,8 @@ static void restart_feeds(struct av7110 *av7110)
1082 av7110->playing = 0; 1104 av7110->playing = 0;
1083 av7110->rec_mode = 0; 1105 av7110->rec_mode = 0;
1084 1106
1107 feeding = av7110->feeding1; /* full_ts mod */
1108
1085 for (i = 0; i < dvbdmx->feednum; i++) { 1109 for (i = 0; i < dvbdmx->feednum; i++) {
1086 feed = &dvbdmx->feed[i]; 1110 feed = &dvbdmx->feed[i];
1087 if (feed->state == DMX_STATE_GO) { 1111 if (feed->state == DMX_STATE_GO) {
@@ -1099,6 +1123,8 @@ static void restart_feeds(struct av7110 *av7110)
1099 } 1123 }
1100 } 1124 }
1101 1125
1126 av7110->feeding1 = feeding; /* full_ts mod */
1127
1102 if (mode) 1128 if (mode)
1103 av7110_av_start_play(av7110, mode); 1129 av7110_av_start_play(av7110, mode);
1104} 1130}
@@ -1197,8 +1223,9 @@ static int start_ts_capture(struct av7110 *budget)
1197 1223
1198 if (budget->feeding1) 1224 if (budget->feeding1)
1199 return ++budget->feeding1; 1225 return ++budget->feeding1;
1200 memset(budget->grabbing, 0x00, TS_HEIGHT * TS_WIDTH); 1226 memset(budget->grabbing, 0x00, TS_BUFLEN);
1201 budget->ttbp = 0; 1227 budget->ttbp = 0;
1228 SAA7146_ISR_CLEAR(budget->dev, MASK_10); /* VPE */
1202 SAA7146_IER_ENABLE(budget->dev, MASK_10); /* VPE */ 1229 SAA7146_IER_ENABLE(budget->dev, MASK_10); /* VPE */
1203 saa7146_write(budget->dev, MC1, (MASK_04 | MASK_20)); /* DMA3 on */ 1230 saa7146_write(budget->dev, MC1, (MASK_04 | MASK_20)); /* DMA3 on */
1204 return ++budget->feeding1; 1231 return ++budget->feeding1;
@@ -1233,18 +1260,14 @@ static int budget_stop_feed(struct dvb_demux_feed *feed)
1233 return status; 1260 return status;
1234} 1261}
1235 1262
1236static void vpeirq(unsigned long data) 1263static void vpeirq(unsigned long cookie)
1237{ 1264{
1238 struct av7110 *budget = (struct av7110 *) data; 1265 struct av7110 *budget = (struct av7110 *)cookie;
1239 u8 *mem = (u8 *) (budget->grabbing); 1266 u8 *mem = (u8 *) (budget->grabbing);
1240 u32 olddma = budget->ttbp; 1267 u32 olddma = budget->ttbp;
1241 u32 newdma = saa7146_read(budget->dev, PCI_VDP3); 1268 u32 newdma = saa7146_read(budget->dev, PCI_VDP3);
1269 struct dvb_demux *demux = budget->full_ts ? &budget->demux : &budget->demux1;
1242 1270
1243 if (!budgetpatch) {
1244 printk("av7110.c: vpeirq() called while budgetpatch disabled!"
1245 " check saa7146 IER register\n");
1246 BUG();
1247 }
1248 /* nearest lower position divisible by 188 */ 1271 /* nearest lower position divisible by 188 */
1249 newdma -= newdma % 188; 1272 newdma -= newdma % 188;
1250 1273
@@ -1268,11 +1291,11 @@ static void vpeirq(unsigned long data)
1268 1291
1269 if (newdma > olddma) 1292 if (newdma > olddma)
1270 /* no wraparound, dump olddma..newdma */ 1293 /* no wraparound, dump olddma..newdma */
1271 dvb_dmx_swfilter_packets(&budget->demux1, mem + olddma, (newdma - olddma) / 188); 1294 dvb_dmx_swfilter_packets(demux, mem + olddma, (newdma - olddma) / 188);
1272 else { 1295 else {
1273 /* wraparound, dump olddma..buflen and 0..newdma */ 1296 /* wraparound, dump olddma..buflen and 0..newdma */
1274 dvb_dmx_swfilter_packets(&budget->demux1, mem + olddma, (TS_BUFLEN - olddma) / 188); 1297 dvb_dmx_swfilter_packets(demux, mem + olddma, (TS_BUFLEN - olddma) / 188);
1275 dvb_dmx_swfilter_packets(&budget->demux1, mem, newdma / 188); 1298 dvb_dmx_swfilter_packets(demux, mem, newdma / 188);
1276 } 1299 }
1277} 1300}
1278 1301
@@ -1294,8 +1317,8 @@ static int av7110_register(struct av7110 *av7110)
1294 for (i = 0; i < 32; i++) 1317 for (i = 0; i < 32; i++)
1295 av7110->handle2filter[i] = NULL; 1318 av7110->handle2filter[i] = NULL;
1296 1319
1297 dvbdemux->filternum = 32; 1320 dvbdemux->filternum = (av7110->full_ts) ? 256 : 32;
1298 dvbdemux->feednum = 32; 1321 dvbdemux->feednum = (av7110->full_ts) ? 256 : 32;
1299 dvbdemux->start_feed = av7110_start_feed; 1322 dvbdemux->start_feed = av7110_start_feed;
1300 dvbdemux->stop_feed = av7110_stop_feed; 1323 dvbdemux->stop_feed = av7110_stop_feed;
1301 dvbdemux->write_to_decoder = av7110_write_to_decoder; 1324 dvbdemux->write_to_decoder = av7110_write_to_decoder;
@@ -1305,7 +1328,7 @@ static int av7110_register(struct av7110 *av7110)
1305 dvb_dmx_init(&av7110->demux); 1328 dvb_dmx_init(&av7110->demux);
1306 av7110->demux.dmx.get_stc = dvb_get_stc; 1329 av7110->demux.dmx.get_stc = dvb_get_stc;
1307 1330
1308 av7110->dmxdev.filternum = 32; 1331 av7110->dmxdev.filternum = (av7110->full_ts) ? 256 : 32;
1309 av7110->dmxdev.demux = &dvbdemux->dmx; 1332 av7110->dmxdev.demux = &dvbdemux->dmx;
1310 av7110->dmxdev.capabilities = 0; 1333 av7110->dmxdev.capabilities = 0;
1311 1334
@@ -1422,7 +1445,6 @@ int i2c_writereg(struct av7110 *av7110, u8 id, u8 reg, u8 val)
1422 return i2c_transfer(&av7110->i2c_adap, &msgs, 1); 1445 return i2c_transfer(&av7110->i2c_adap, &msgs, 1);
1423} 1446}
1424 1447
1425#if 0
1426u8 i2c_readreg(struct av7110 *av7110, u8 id, u8 reg) 1448u8 i2c_readreg(struct av7110 *av7110, u8 id, u8 reg)
1427{ 1449{
1428 u8 mm1[] = {0x00}; 1450 u8 mm1[] = {0x00};
@@ -1439,7 +1461,6 @@ u8 i2c_readreg(struct av7110 *av7110, u8 id, u8 reg)
1439 1461
1440 return mm2[0]; 1462 return mm2[0];
1441} 1463}
1442#endif
1443 1464
1444/**************************************************************************** 1465/****************************************************************************
1445 * INITIALIZATION 1466 * INITIALIZATION
@@ -2256,7 +2277,7 @@ static int frontend_init(struct av7110 *av7110)
2256 if (!av7110->fe) { 2277 if (!av7110->fe) {
2257 /* FIXME: propagate the failure code from the lower layers */ 2278 /* FIXME: propagate the failure code from the lower layers */
2258 ret = -ENOMEM; 2279 ret = -ENOMEM;
2259 printk("dvb-ttpci: A frontend driver was not found for device %04x/%04x subsystem %04x/%04x\n", 2280 printk("dvb-ttpci: A frontend driver was not found for device [%04x:%04x] subsystem [%04x:%04x]\n",
2260 av7110->dev->pci->vendor, 2281 av7110->dev->pci->vendor,
2261 av7110->dev->pci->device, 2282 av7110->dev->pci->device,
2262 av7110->dev->pci->subsystem_vendor, 2283 av7110->dev->pci->subsystem_vendor,
@@ -2484,7 +2505,47 @@ static int __devinit av7110_attach(struct saa7146_dev* dev,
2484 av7110->dvb_adapter.proposed_mac); 2505 av7110->dvb_adapter.proposed_mac);
2485 ret = -ENOMEM; 2506 ret = -ENOMEM;
2486 2507
2487 if (budgetpatch) { 2508 /* full-ts mod? */
2509 if (full_ts)
2510 av7110->full_ts = true;
2511
2512 /* check for full-ts flag in eeprom */
2513 if (i2c_readreg(av7110, 0xaa, 0) == 0x4f && i2c_readreg(av7110, 0xaa, 1) == 0x45) {
2514 u8 flags = i2c_readreg(av7110, 0xaa, 2);
2515 if (flags != 0xff && (flags & 0x01))
2516 av7110->full_ts = true;
2517 }
2518
2519 if (av7110->full_ts) {
2520 printk(KERN_INFO "dvb-ttpci: full-ts mode enabled for saa7146 port B\n");
2521 spin_lock_init(&av7110->feedlock1);
2522 av7110->grabbing = saa7146_vmalloc_build_pgtable(pdev, length,
2523 &av7110->pt);
2524 if (!av7110->grabbing)
2525 goto err_i2c_del_3;
2526
2527 saa7146_write(dev, DD1_STREAM_B, 0x00000000);
2528 saa7146_write(dev, MC2, (MASK_10 | MASK_26));
2529
2530 saa7146_write(dev, DD1_INIT, 0x00000600);
2531 saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
2532
2533 saa7146_write(dev, BRS_CTRL, 0x60000000);
2534 saa7146_write(dev, MC2, MASK_08 | MASK_24);
2535
2536 /* dma3 */
2537 saa7146_write(dev, PCI_BT_V1, 0x001c0000 | (saa7146_read(dev, PCI_BT_V1) & ~0x001f0000));
2538 saa7146_write(dev, BASE_ODD3, 0);
2539 saa7146_write(dev, BASE_EVEN3, 0);
2540 saa7146_write(dev, PROT_ADDR3, TS_WIDTH * TS_HEIGHT);
2541 saa7146_write(dev, PITCH3, TS_WIDTH);
2542 saa7146_write(dev, BASE_PAGE3, av7110->pt.dma | ME1 | 0x90);
2543 saa7146_write(dev, NUM_LINE_BYTE3, (TS_HEIGHT << 16) | TS_WIDTH);
2544 saa7146_write(dev, MC2, MASK_04 | MASK_20);
2545
2546 tasklet_init(&av7110->vpe_tasklet, vpeirq, (unsigned long) av7110);
2547
2548 } else if (budgetpatch) {
2488 spin_lock_init(&av7110->feedlock1); 2549 spin_lock_init(&av7110->feedlock1);
2489 av7110->grabbing = saa7146_vmalloc_build_pgtable(pdev, length, 2550 av7110->grabbing = saa7146_vmalloc_build_pgtable(pdev, length,
2490 &av7110->pt); 2551 &av7110->pt);
@@ -2710,11 +2771,13 @@ static int __devexit av7110_detach(struct saa7146_dev* saa)
2710#if defined(CONFIG_INPUT_EVDEV) || defined(CONFIG_INPUT_EVDEV_MODULE) 2771#if defined(CONFIG_INPUT_EVDEV) || defined(CONFIG_INPUT_EVDEV_MODULE)
2711 av7110_ir_exit(av7110); 2772 av7110_ir_exit(av7110);
2712#endif 2773#endif
2713 if (budgetpatch) { 2774 if (budgetpatch || av7110->full_ts) {
2714 /* Disable RPS1 */ 2775 if (budgetpatch) {
2715 saa7146_write(saa, MC1, MASK_29); 2776 /* Disable RPS1 */
2716 /* VSYNC LOW (inactive) */ 2777 saa7146_write(saa, MC1, MASK_29);
2717 saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO); 2778 /* VSYNC LOW (inactive) */
2779 saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO);
2780 }
2718 saa7146_write(saa, MC1, MASK_20); /* DMA3 off */ 2781 saa7146_write(saa, MC1, MASK_20); /* DMA3 off */
2719 SAA7146_IER_DISABLE(saa, MASK_10); 2782 SAA7146_IER_DISABLE(saa, MASK_10);
2720 SAA7146_ISR_CLEAR(saa, MASK_10); 2783 SAA7146_ISR_CLEAR(saa, MASK_10);
@@ -2794,7 +2857,7 @@ static void av7110_irq(struct saa7146_dev* dev, u32 *isr)
2794 tasklet_schedule(&av7110->gpio_tasklet); 2857 tasklet_schedule(&av7110->gpio_tasklet);
2795 } 2858 }
2796 2859
2797 if ((*isr & MASK_10) && budgetpatch) 2860 if (*isr & MASK_10)
2798 tasklet_schedule(&av7110->vpe_tasklet); 2861 tasklet_schedule(&av7110->vpe_tasklet);
2799} 2862}
2800 2863
diff --git a/drivers/media/dvb/ttpci/av7110.h b/drivers/media/dvb/ttpci/av7110.h
index 55f23ddcb994..d85b8512ac30 100644
--- a/drivers/media/dvb/ttpci/av7110.h
+++ b/drivers/media/dvb/ttpci/av7110.h
@@ -192,6 +192,7 @@ struct av7110 {
192 unsigned char *grabbing; 192 unsigned char *grabbing;
193 struct saa7146_pgtable pt; 193 struct saa7146_pgtable pt;
194 struct tasklet_struct vpe_tasklet; 194 struct tasklet_struct vpe_tasklet;
195 bool full_ts;
195 196
196 int fe_synced; 197 int fe_synced;
197 struct mutex pid_mutex; 198 struct mutex pid_mutex;
diff --git a/drivers/media/dvb/ttpci/av7110_av.c b/drivers/media/dvb/ttpci/av7110_av.c
index 184647ad1c7c..bdc62acf2099 100644
--- a/drivers/media/dvb/ttpci/av7110_av.c
+++ b/drivers/media/dvb/ttpci/av7110_av.c
@@ -788,6 +788,9 @@ int av7110_write_to_decoder(struct dvb_demux_feed *feed, const u8 *buf, size_t l
788 788
789 dprintk(2, "av7110:%p, \n", av7110); 789 dprintk(2, "av7110:%p, \n", av7110);
790 790
791 if (av7110->full_ts && demux->dmx.frontend->source != DMX_MEMORY_FE)
792 return 0;
793
791 switch (feed->pes_type) { 794 switch (feed->pes_type) {
792 case 0: 795 case 0:
793 if (av7110->audiostate.stream_source == AUDIO_SOURCE_MEMORY) 796 if (av7110->audiostate.stream_source == AUDIO_SOURCE_MEMORY)
diff --git a/drivers/media/dvb/ttpci/budget-av.c b/drivers/media/dvb/ttpci/budget-av.c
index b7d1f2f18d3a..1032ea77837e 100644
--- a/drivers/media/dvb/ttpci/budget-av.c
+++ b/drivers/media/dvb/ttpci/budget-av.c
@@ -57,6 +57,8 @@
57#define SLOTSTATUS_READY 8 57#define SLOTSTATUS_READY 8
58#define SLOTSTATUS_OCCUPIED (SLOTSTATUS_PRESENT|SLOTSTATUS_RESET|SLOTSTATUS_READY) 58#define SLOTSTATUS_OCCUPIED (SLOTSTATUS_PRESENT|SLOTSTATUS_RESET|SLOTSTATUS_READY)
59 59
60DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
61
60struct budget_av { 62struct budget_av {
61 struct budget budget; 63 struct budget budget;
62 struct video_device *vd; 64 struct video_device *vd;
@@ -1049,7 +1051,7 @@ static void frontend_init(struct budget_av *budget_av)
1049 1051
1050 if (fe == NULL) { 1052 if (fe == NULL) {
1051 printk(KERN_ERR "budget-av: A frontend driver was not found " 1053 printk(KERN_ERR "budget-av: A frontend driver was not found "
1052 "for device %04x/%04x subsystem %04x/%04x\n", 1054 "for device [%04x:%04x] subsystem [%04x:%04x]\n",
1053 saa->pci->vendor, 1055 saa->pci->vendor,
1054 saa->pci->device, 1056 saa->pci->device,
1055 saa->pci->subsystem_vendor, 1057 saa->pci->subsystem_vendor,
@@ -1127,7 +1129,9 @@ static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extensio
1127 1129
1128 dev->ext_priv = budget_av; 1130 dev->ext_priv = budget_av;
1129 1131
1130 if ((err = ttpci_budget_init(&budget_av->budget, dev, info, THIS_MODULE))) { 1132 err = ttpci_budget_init(&budget_av->budget, dev, info, THIS_MODULE,
1133 adapter_nr);
1134 if (err) {
1131 kfree(budget_av); 1135 kfree(budget_av);
1132 return err; 1136 return err;
1133 } 1137 }
diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c
index 060e7c785326..0a5aad45435d 100644
--- a/drivers/media/dvb/ttpci/budget-ci.c
+++ b/drivers/media/dvb/ttpci/budget-ci.c
@@ -92,6 +92,8 @@ static int ir_debug;
92module_param(ir_debug, int, 0644); 92module_param(ir_debug, int, 0644);
93MODULE_PARM_DESC(ir_debug, "enable debugging information for IR decoding"); 93MODULE_PARM_DESC(ir_debug, "enable debugging information for IR decoding");
94 94
95DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
96
95struct budget_ci_ir { 97struct budget_ci_ir {
96 struct input_dev *dev; 98 struct input_dev *dev;
97 struct tasklet_struct msp430_irq_tasklet; 99 struct tasklet_struct msp430_irq_tasklet;
@@ -1153,7 +1155,7 @@ static void frontend_init(struct budget_ci *budget_ci)
1153 } 1155 }
1154 1156
1155 if (budget_ci->budget.dvb_frontend == NULL) { 1157 if (budget_ci->budget.dvb_frontend == NULL) {
1156 printk("budget-ci: A frontend driver was not found for device %04x/%04x subsystem %04x/%04x\n", 1158 printk("budget-ci: A frontend driver was not found for device [%04x:%04x] subsystem [%04x:%04x]\n",
1157 budget_ci->budget.dev->pci->vendor, 1159 budget_ci->budget.dev->pci->vendor,
1158 budget_ci->budget.dev->pci->device, 1160 budget_ci->budget.dev->pci->device,
1159 budget_ci->budget.dev->pci->subsystem_vendor, 1161 budget_ci->budget.dev->pci->subsystem_vendor,
@@ -1183,7 +1185,8 @@ static int budget_ci_attach(struct saa7146_dev *dev, struct saa7146_pci_extensio
1183 1185
1184 dev->ext_priv = budget_ci; 1186 dev->ext_priv = budget_ci;
1185 1187
1186 err = ttpci_budget_init(&budget_ci->budget, dev, info, THIS_MODULE); 1188 err = ttpci_budget_init(&budget_ci->budget, dev, info, THIS_MODULE,
1189 adapter_nr);
1187 if (err) 1190 if (err)
1188 goto out2; 1191 goto out2;
1189 1192
diff --git a/drivers/media/dvb/ttpci/budget-core.c b/drivers/media/dvb/ttpci/budget-core.c
index 6f4ddb643fee..ba18e56d5f11 100644
--- a/drivers/media/dvb/ttpci/budget-core.c
+++ b/drivers/media/dvb/ttpci/budget-core.c
@@ -57,8 +57,6 @@ module_param_named(bufsize, dma_buffer_size, int, 0444);
57MODULE_PARM_DESC(debug, "Turn on/off budget debugging (default:off)."); 57MODULE_PARM_DESC(debug, "Turn on/off budget debugging (default:off).");
58MODULE_PARM_DESC(bufsize, "DMA buffer size in KB, default: 188, min: 188, max: 1410 (Activy: 564)"); 58MODULE_PARM_DESC(bufsize, "DMA buffer size in KB, default: 188, min: 188, max: 1410 (Activy: 564)");
59 59
60DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
61
62/**************************************************************************** 60/****************************************************************************
63 * TT budget / WinTV Nova 61 * TT budget / WinTV Nova
64 ****************************************************************************/ 62 ****************************************************************************/
@@ -411,7 +409,7 @@ static void budget_unregister(struct budget *budget)
411 409
412int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev, 410int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev,
413 struct saa7146_pci_extension_data *info, 411 struct saa7146_pci_extension_data *info,
414 struct module *owner) 412 struct module *owner, short *adapter_nums)
415{ 413{
416 int ret = 0; 414 int ret = 0;
417 struct budget_info *bi = info->ext_priv; 415 struct budget_info *bi = info->ext_priv;
@@ -474,7 +472,7 @@ int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev,
474 printk("%s: dma buffer size %u\n", budget->dev->name, budget->buffer_size); 472 printk("%s: dma buffer size %u\n", budget->dev->name, budget->buffer_size);
475 473
476 ret = dvb_register_adapter(&budget->dvb_adapter, budget->card->name, 474 ret = dvb_register_adapter(&budget->dvb_adapter, budget->card->name,
477 owner, &budget->dev->pci->dev, adapter_nr); 475 owner, &budget->dev->pci->dev, adapter_nums);
478 if (ret < 0) 476 if (ret < 0)
479 return ret; 477 return ret;
480 478
diff --git a/drivers/media/dvb/ttpci/budget-patch.c b/drivers/media/dvb/ttpci/budget-patch.c
index aa5ed4ef19f2..60136688a9a4 100644
--- a/drivers/media/dvb/ttpci/budget-patch.c
+++ b/drivers/media/dvb/ttpci/budget-patch.c
@@ -39,6 +39,8 @@
39 39
40#include "bsru6.h" 40#include "bsru6.h"
41 41
42DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
43
42#define budget_patch budget 44#define budget_patch budget
43 45
44static struct saa7146_extension budget_extension; 46static struct saa7146_extension budget_extension;
@@ -360,7 +362,7 @@ static void frontend_init(struct budget_patch* budget)
360 } 362 }
361 363
362 if (budget->dvb_frontend == NULL) { 364 if (budget->dvb_frontend == NULL) {
363 printk("dvb-ttpci: A frontend driver was not found for device %04x/%04x subsystem %04x/%04x\n", 365 printk("dvb-ttpci: A frontend driver was not found for device [%04x:%04x] subsystem [%04x:%04x]\n",
364 budget->dev->pci->vendor, 366 budget->dev->pci->vendor,
365 budget->dev->pci->device, 367 budget->dev->pci->device,
366 budget->dev->pci->subsystem_vendor, 368 budget->dev->pci->subsystem_vendor,
@@ -592,8 +594,9 @@ static int budget_patch_attach (struct saa7146_dev* dev, struct saa7146_pci_exte
592 594
593 dprintk(2, "budget: %p\n", budget); 595 dprintk(2, "budget: %p\n", budget);
594 596
595 if ((err = ttpci_budget_init (budget, dev, info, THIS_MODULE))) { 597 err = ttpci_budget_init(budget, dev, info, THIS_MODULE, adapter_nr);
596 kfree (budget); 598 if (err) {
599 kfree(budget);
597 return err; 600 return err;
598 } 601 }
599 602
diff --git a/drivers/media/dvb/ttpci/budget.c b/drivers/media/dvb/ttpci/budget.c
index f0068996ac07..1638e1d9f538 100644
--- a/drivers/media/dvb/ttpci/budget.c
+++ b/drivers/media/dvb/ttpci/budget.c
@@ -46,11 +46,14 @@
46#include "lnbp21.h" 46#include "lnbp21.h"
47#include "bsru6.h" 47#include "bsru6.h"
48#include "bsbe1.h" 48#include "bsbe1.h"
49#include "tdhd1.h"
49 50
50static int diseqc_method; 51static int diseqc_method;
51module_param(diseqc_method, int, 0444); 52module_param(diseqc_method, int, 0444);
52MODULE_PARM_DESC(diseqc_method, "Select DiSEqC method for subsystem id 13c2:1003, 0: default, 1: more reliable (for newer revisions only)"); 53MODULE_PARM_DESC(diseqc_method, "Select DiSEqC method for subsystem id 13c2:1003, 0: default, 1: more reliable (for newer revisions only)");
53 54
55DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
56
54static void Set22K (struct budget *budget, int state) 57static void Set22K (struct budget *budget, int state)
55{ 58{
56 struct saa7146_dev *dev=budget->dev; 59 struct saa7146_dev *dev=budget->dev;
@@ -390,6 +393,13 @@ static struct stv0299_config alps_bsbe1_config_activy = {
390 .set_symbol_rate = alps_bsbe1_set_symbol_rate, 393 .set_symbol_rate = alps_bsbe1_set_symbol_rate,
391}; 394};
392 395
396static int alps_tdhd1_204_request_firmware(struct dvb_frontend *fe, const struct firmware **fw, char *name)
397{
398 struct budget *budget = (struct budget *)fe->dvb->priv;
399
400 return request_firmware(fw, name, &budget->dev->pci->dev);
401}
402
393 403
394static int i2c_readreg(struct i2c_adapter *i2c, u8 adr, u8 reg) 404static int i2c_readreg(struct i2c_adapter *i2c, u8 adr, u8 reg)
395{ 405{
@@ -511,6 +521,14 @@ static void frontend_init(struct budget *budget)
511 } 521 }
512 break; 522 break;
513 523
524 case 0x5f60: /* Fujitsu Siemens Activy Budget-T PCI rev AL (tda10046/ALPS TDHD1-204A) */
525 budget->dvb_frontend = dvb_attach(tda10046_attach, &alps_tdhd1_204a_config, &budget->i2c_adap);
526 if (budget->dvb_frontend) {
527 budget->dvb_frontend->ops.tuner_ops.set_params = alps_tdhd1_204a_tuner_set_params;
528 budget->dvb_frontend->tuner_priv = &budget->i2c_adap;
529 }
530 break;
531
514 case 0x5f61: /* Fujitsu Siemens Activy Budget-T PCI rev GR (L64781/Grundig 29504-401(tsa5060)) */ 532 case 0x5f61: /* Fujitsu Siemens Activy Budget-T PCI rev GR (L64781/Grundig 29504-401(tsa5060)) */
515 budget->dvb_frontend = dvb_attach(l64781_attach, &grundig_29504_401_config_activy, &budget->i2c_adap); 533 budget->dvb_frontend = dvb_attach(l64781_attach, &grundig_29504_401_config_activy, &budget->i2c_adap);
516 if (budget->dvb_frontend) { 534 if (budget->dvb_frontend) {
@@ -550,7 +568,7 @@ static void frontend_init(struct budget *budget)
550 } 568 }
551 569
552 if (budget->dvb_frontend == NULL) { 570 if (budget->dvb_frontend == NULL) {
553 printk("budget: A frontend driver was not found for device %04x/%04x subsystem %04x/%04x\n", 571 printk("budget: A frontend driver was not found for device [%04x:%04x] subsystem [%04x:%04x]\n",
554 budget->dev->pci->vendor, 572 budget->dev->pci->vendor,
555 budget->dev->pci->device, 573 budget->dev->pci->device,
556 budget->dev->pci->subsystem_vendor, 574 budget->dev->pci->subsystem_vendor,
@@ -582,7 +600,8 @@ static int budget_attach (struct saa7146_dev* dev, struct saa7146_pci_extension_
582 600
583 dev->ext_priv = budget; 601 dev->ext_priv = budget;
584 602
585 if ((err = ttpci_budget_init (budget, dev, info, THIS_MODULE))) { 603 err = ttpci_budget_init(budget, dev, info, THIS_MODULE, adapter_nr);
604 if (err) {
586 printk("==> failed\n"); 605 printk("==> failed\n");
587 kfree (budget); 606 kfree (budget);
588 return err; 607 return err;
@@ -624,6 +643,7 @@ MAKE_BUDGET_INFO(ttbs1401, "TT-Budget-S-1401 PCI", BUDGET_TT);
624MAKE_BUDGET_INFO(fsacs0, "Fujitsu Siemens Activy Budget-S PCI (rev GR/grundig frontend)", BUDGET_FS_ACTIVY); 643MAKE_BUDGET_INFO(fsacs0, "Fujitsu Siemens Activy Budget-S PCI (rev GR/grundig frontend)", BUDGET_FS_ACTIVY);
625MAKE_BUDGET_INFO(fsacs1, "Fujitsu Siemens Activy Budget-S PCI (rev AL/alps frontend)", BUDGET_FS_ACTIVY); 644MAKE_BUDGET_INFO(fsacs1, "Fujitsu Siemens Activy Budget-S PCI (rev AL/alps frontend)", BUDGET_FS_ACTIVY);
626MAKE_BUDGET_INFO(fsact, "Fujitsu Siemens Activy Budget-T PCI (rev GR/Grundig frontend)", BUDGET_FS_ACTIVY); 645MAKE_BUDGET_INFO(fsact, "Fujitsu Siemens Activy Budget-T PCI (rev GR/Grundig frontend)", BUDGET_FS_ACTIVY);
646MAKE_BUDGET_INFO(fsact1, "Fujitsu Siemens Activy Budget-T PCI (rev AL/ALPS TDHD1-204A)", BUDGET_FS_ACTIVY);
627 647
628static struct pci_device_id pci_tbl[] = { 648static struct pci_device_id pci_tbl[] = {
629 MAKE_EXTENSION_PCI(ttbs, 0x13c2, 0x1003), 649 MAKE_EXTENSION_PCI(ttbs, 0x13c2, 0x1003),
@@ -634,6 +654,7 @@ static struct pci_device_id pci_tbl[] = {
634 MAKE_EXTENSION_PCI(ttbs1401, 0x13c2, 0x1018), 654 MAKE_EXTENSION_PCI(ttbs1401, 0x13c2, 0x1018),
635 MAKE_EXTENSION_PCI(fsacs1,0x1131, 0x4f60), 655 MAKE_EXTENSION_PCI(fsacs1,0x1131, 0x4f60),
636 MAKE_EXTENSION_PCI(fsacs0,0x1131, 0x4f61), 656 MAKE_EXTENSION_PCI(fsacs0,0x1131, 0x4f61),
657 MAKE_EXTENSION_PCI(fsact1, 0x1131, 0x5f60),
637 MAKE_EXTENSION_PCI(fsact, 0x1131, 0x5f61), 658 MAKE_EXTENSION_PCI(fsact, 0x1131, 0x5f61),
638 { 659 {
639 .vendor = 0, 660 .vendor = 0,
diff --git a/drivers/media/dvb/ttpci/budget.h b/drivers/media/dvb/ttpci/budget.h
index dd450b739bff..86435bf16260 100644
--- a/drivers/media/dvb/ttpci/budget.h
+++ b/drivers/media/dvb/ttpci/budget.h
@@ -109,7 +109,7 @@ static struct saa7146_pci_extension_data x_var = { \
109 109
110extern int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev, 110extern int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev,
111 struct saa7146_pci_extension_data *info, 111 struct saa7146_pci_extension_data *info,
112 struct module *owner); 112 struct module *owner, short *adapter_nums);
113extern void ttpci_budget_init_hooks(struct budget *budget); 113extern void ttpci_budget_init_hooks(struct budget *budget);
114extern int ttpci_budget_deinit(struct budget *budget); 114extern int ttpci_budget_deinit(struct budget *budget);
115extern void ttpci_budget_irq10_handler(struct saa7146_dev *dev, u32 * isr); 115extern void ttpci_budget_irq10_handler(struct saa7146_dev *dev, u32 * isr);
diff --git a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
index e6c9cd2e3b94..66ab0c6e9783 100644
--- a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
+++ b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
@@ -1614,7 +1614,7 @@ static void frontend_init(struct ttusb* ttusb)
1614 } 1614 }
1615 1615
1616 if (ttusb->fe == NULL) { 1616 if (ttusb->fe == NULL) {
1617 printk("dvb-ttusb-budget: A frontend driver was not found for device %04x/%04x\n", 1617 printk("dvb-ttusb-budget: A frontend driver was not found for device [%04x:%04x]\n",
1618 le16_to_cpu(ttusb->dev->descriptor.idVendor), 1618 le16_to_cpu(ttusb->dev->descriptor.idVendor),
1619 le16_to_cpu(ttusb->dev->descriptor.idProduct)); 1619 le16_to_cpu(ttusb->dev->descriptor.idProduct));
1620 } else { 1620 } else {
diff --git a/drivers/media/dvb/ttusb-dec/ttusb_dec.c b/drivers/media/dvb/ttusb-dec/ttusb_dec.c
index de5829b863fd..ab33fec8a19f 100644
--- a/drivers/media/dvb/ttusb-dec/ttusb_dec.c
+++ b/drivers/media/dvb/ttusb-dec/ttusb_dec.c
@@ -1665,7 +1665,7 @@ static int ttusb_dec_probe(struct usb_interface *intf,
1665 } 1665 }
1666 1666
1667 if (dec->fe == NULL) { 1667 if (dec->fe == NULL) {
1668 printk("dvb-ttusb-dec: A frontend driver was not found for device %04x/%04x\n", 1668 printk("dvb-ttusb-dec: A frontend driver was not found for device [%04x:%04x]\n",
1669 le16_to_cpu(dec->udev->descriptor.idVendor), 1669 le16_to_cpu(dec->udev->descriptor.idVendor),
1670 le16_to_cpu(dec->udev->descriptor.idProduct)); 1670 le16_to_cpu(dec->udev->descriptor.idProduct));
1671 } else { 1671 } else {
diff --git a/drivers/media/dvb/ttusb-dec/ttusbdecfe.c b/drivers/media/dvb/ttusb-dec/ttusbdecfe.c
index 443af24097f3..21260aad1e54 100644
--- a/drivers/media/dvb/ttusb-dec/ttusbdecfe.c
+++ b/drivers/media/dvb/ttusb-dec/ttusbdecfe.c
@@ -38,7 +38,17 @@ struct ttusbdecfe_state {
38}; 38};
39 39
40 40
41static int ttusbdecfe_read_status(struct dvb_frontend* fe, fe_status_t* status) 41static int ttusbdecfe_dvbs_read_status(struct dvb_frontend *fe,
42 fe_status_t *status)
43{
44 *status = FE_HAS_SIGNAL | FE_HAS_VITERBI |
45 FE_HAS_SYNC | FE_HAS_CARRIER | FE_HAS_LOCK;
46 return 0;
47}
48
49
50static int ttusbdecfe_dvbt_read_status(struct dvb_frontend *fe,
51 fe_status_t *status)
42{ 52{
43 struct ttusbdecfe_state* state = fe->demodulator_priv; 53 struct ttusbdecfe_state* state = fe->demodulator_priv;
44 u8 b[] = { 0x00, 0x00, 0x00, 0x00, 54 u8 b[] = { 0x00, 0x00, 0x00, 0x00,
@@ -251,7 +261,7 @@ static struct dvb_frontend_ops ttusbdecfe_dvbt_ops = {
251 261
252 .get_tune_settings = ttusbdecfe_dvbt_get_tune_settings, 262 .get_tune_settings = ttusbdecfe_dvbt_get_tune_settings,
253 263
254 .read_status = ttusbdecfe_read_status, 264 .read_status = ttusbdecfe_dvbt_read_status,
255}; 265};
256 266
257static struct dvb_frontend_ops ttusbdecfe_dvbs_ops = { 267static struct dvb_frontend_ops ttusbdecfe_dvbs_ops = {
@@ -273,7 +283,7 @@ static struct dvb_frontend_ops ttusbdecfe_dvbs_ops = {
273 283
274 .set_frontend = ttusbdecfe_dvbs_set_frontend, 284 .set_frontend = ttusbdecfe_dvbs_set_frontend,
275 285
276 .read_status = ttusbdecfe_read_status, 286 .read_status = ttusbdecfe_dvbs_read_status,
277 287
278 .diseqc_send_master_cmd = ttusbdecfe_dvbs_diseqc_send_master_cmd, 288 .diseqc_send_master_cmd = ttusbdecfe_dvbs_diseqc_send_master_cmd,
279 .set_voltage = ttusbdecfe_dvbs_set_voltage, 289 .set_voltage = ttusbdecfe_dvbs_set_voltage,