aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/frontends
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/dvb/frontends')
-rw-r--r--drivers/media/dvb/frontends/Kconfig12
-rw-r--r--drivers/media/dvb/frontends/Makefile1
-rw-r--r--drivers/media/dvb/frontends/bcm3510.c9
-rw-r--r--drivers/media/dvb/frontends/bsbe1.h123
-rw-r--r--drivers/media/dvb/frontends/bsru6.h140
-rw-r--r--drivers/media/dvb/frontends/cx24110.c13
-rw-r--r--drivers/media/dvb/frontends/cx24110.h1
-rw-r--r--drivers/media/dvb/frontends/dvb-pll.c61
-rw-r--r--drivers/media/dvb/frontends/dvb-pll.h7
-rw-r--r--drivers/media/dvb/frontends/lnbp21.h139
-rw-r--r--drivers/media/dvb/frontends/tda1004x.c25
-rw-r--r--drivers/media/dvb/frontends/tda1004x.h3
-rw-r--r--drivers/media/dvb/frontends/zl10353.c311
-rw-r--r--drivers/media/dvb/frontends/zl10353.h43
-rw-r--r--drivers/media/dvb/frontends/zl10353_priv.h42
15 files changed, 914 insertions, 16 deletions
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig
index c676b1e23ab0..94233168d241 100644
--- a/drivers/media/dvb/frontends/Kconfig
+++ b/drivers/media/dvb/frontends/Kconfig
@@ -116,6 +116,12 @@ config DVB_MT352
116 help 116 help
117 A DVB-T tuner module. Say Y when you want to support this frontend. 117 A DVB-T tuner module. Say Y when you want to support this frontend.
118 118
119config DVB_ZL10353
120 tristate "Zarlink ZL10353 based"
121 depends on DVB_CORE
122 help
123 A DVB-T tuner module. Say Y when you want to support this frontend.
124
119config DVB_DIB3000MB 125config DVB_DIB3000MB
120 tristate "DiBcom 3000M-B" 126 tristate "DiBcom 3000M-B"
121 depends on DVB_CORE 127 depends on DVB_CORE
@@ -155,7 +161,7 @@ comment "ATSC (North American/Korean Terresterial DTV) frontends"
155 depends on DVB_CORE 161 depends on DVB_CORE
156 162
157config DVB_NXT200X 163config DVB_NXT200X
158 tristate "Nextwave NXT2002/NXT2004 based" 164 tristate "NxtWave Communications NXT2002/NXT2004 based"
159 depends on DVB_CORE 165 depends on DVB_CORE
160 select FW_LOADER 166 select FW_LOADER
161 help 167 help
@@ -169,14 +175,14 @@ config DVB_NXT200X
169 or /lib/firmware (depending on configuration of firmware hotplug). 175 or /lib/firmware (depending on configuration of firmware hotplug).
170 176
171config DVB_OR51211 177config DVB_OR51211
172 tristate "or51211 based (pcHDTV HD2000 card)" 178 tristate "Oren OR51211 based"
173 depends on DVB_CORE 179 depends on DVB_CORE
174 select FW_LOADER 180 select FW_LOADER
175 help 181 help
176 An ATSC 8VSB tuner module. Say Y when you want to support this frontend. 182 An ATSC 8VSB tuner module. Say Y when you want to support this frontend.
177 183
178config DVB_OR51132 184config DVB_OR51132
179 tristate "OR51132 based (pcHDTV HD3000 card)" 185 tristate "Oren OR51132 based"
180 depends on DVB_CORE 186 depends on DVB_CORE
181 select FW_LOADER 187 select FW_LOADER
182 help 188 help
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile
index 1af769cd90c0..d09b6071fbaf 100644
--- a/drivers/media/dvb/frontends/Makefile
+++ b/drivers/media/dvb/frontends/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_DVB_TDA1004X) += tda1004x.o
20obj-$(CONFIG_DVB_SP887X) += sp887x.o 20obj-$(CONFIG_DVB_SP887X) += sp887x.o
21obj-$(CONFIG_DVB_NXT6000) += nxt6000.o 21obj-$(CONFIG_DVB_NXT6000) += nxt6000.o
22obj-$(CONFIG_DVB_MT352) += mt352.o 22obj-$(CONFIG_DVB_MT352) += mt352.o
23obj-$(CONFIG_DVB_ZL10353) += zl10353.o
23obj-$(CONFIG_DVB_CX22702) += cx22702.o 24obj-$(CONFIG_DVB_CX22702) += cx22702.o
24obj-$(CONFIG_DVB_TDA10021) += tda10021.o 25obj-$(CONFIG_DVB_TDA10021) += tda10021.o
25obj-$(CONFIG_DVB_STV0297) += stv0297.o 26obj-$(CONFIG_DVB_STV0297) += stv0297.o
diff --git a/drivers/media/dvb/frontends/bcm3510.c b/drivers/media/dvb/frontends/bcm3510.c
index caaee893ca76..1708a1d4893e 100644
--- a/drivers/media/dvb/frontends/bcm3510.c
+++ b/drivers/media/dvb/frontends/bcm3510.c
@@ -39,6 +39,7 @@
39#include <linux/jiffies.h> 39#include <linux/jiffies.h>
40#include <linux/string.h> 40#include <linux/string.h>
41#include <linux/slab.h> 41#include <linux/slab.h>
42#include <linux/mutex.h>
42 43
43#include "dvb_frontend.h" 44#include "dvb_frontend.h"
44#include "bcm3510.h" 45#include "bcm3510.h"
@@ -52,7 +53,7 @@ struct bcm3510_state {
52 struct dvb_frontend frontend; 53 struct dvb_frontend frontend;
53 54
54 /* demodulator private data */ 55 /* demodulator private data */
55 struct semaphore hab_sem; 56 struct mutex hab_mutex;
56 u8 firmware_loaded:1; 57 u8 firmware_loaded:1;
57 58
58 unsigned long next_status_check; 59 unsigned long next_status_check;
@@ -213,7 +214,7 @@ static int bcm3510_do_hab_cmd(struct bcm3510_state *st, u8 cmd, u8 msgid, u8 *ob
213 dbufout(ob,olen+2,deb_hab); 214 dbufout(ob,olen+2,deb_hab);
214 deb_hab("\n"); 215 deb_hab("\n");
215 216
216 if (down_interruptible(&st->hab_sem) < 0) 217 if (mutex_lock_interruptible(&st->hab_mutex) < 0)
217 return -EAGAIN; 218 return -EAGAIN;
218 219
219 if ((ret = bcm3510_hab_send_request(st, ob, olen+2)) < 0 || 220 if ((ret = bcm3510_hab_send_request(st, ob, olen+2)) < 0 ||
@@ -226,7 +227,7 @@ static int bcm3510_do_hab_cmd(struct bcm3510_state *st, u8 cmd, u8 msgid, u8 *ob
226 227
227 memcpy(ibuf,&ib[2],ilen); 228 memcpy(ibuf,&ib[2],ilen);
228error: 229error:
229 up(&st->hab_sem); 230 mutex_unlock(&st->hab_mutex);
230 return ret; 231 return ret;
231} 232}
232 233
@@ -796,7 +797,7 @@ struct dvb_frontend* bcm3510_attach(const struct bcm3510_config *config,
796 state->frontend.ops = &state->ops; 797 state->frontend.ops = &state->ops;
797 state->frontend.demodulator_priv = state; 798 state->frontend.demodulator_priv = state;
798 799
799 sema_init(&state->hab_sem, 1); 800 mutex_init(&state->hab_mutex);
800 801
801 if ((ret = bcm3510_readB(state,0xe0,&v)) < 0) 802 if ((ret = bcm3510_readB(state,0xe0,&v)) < 0)
802 goto error; 803 goto error;
diff --git a/drivers/media/dvb/frontends/bsbe1.h b/drivers/media/dvb/frontends/bsbe1.h
new file mode 100644
index 000000000000..78573b22ada9
--- /dev/null
+++ b/drivers/media/dvb/frontends/bsbe1.h
@@ -0,0 +1,123 @@
1/*
2 * bsbe1.h - ALPS BSBE1 tuner support (moved from av7110.c)
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
20 *
21 *
22 * the project's page is at http://www.linuxtv.org
23 */
24
25#ifndef BSBE1_H
26#define BSBE1_H
27
28static u8 alps_bsbe1_inittab[] = {
29 0x01, 0x15,
30 0x02, 0x30,
31 0x03, 0x00,
32 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
33 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */
34 0x06, 0x40, /* DAC not used, set to high impendance mode */
35 0x07, 0x00, /* DAC LSB */
36 0x08, 0x40, /* DiSEqC off, LNB power on OP2/LOCK pin on */
37 0x09, 0x00, /* FIFO */
38 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
39 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */
40 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
41 0x10, 0x3f, // AGC2 0x3d
42 0x11, 0x84,
43 0x12, 0xb9,
44 0x15, 0xc9, // lock detector threshold
45 0x16, 0x00,
46 0x17, 0x00,
47 0x18, 0x00,
48 0x19, 0x00,
49 0x1a, 0x00,
50 0x1f, 0x50,
51 0x20, 0x00,
52 0x21, 0x00,
53 0x22, 0x00,
54 0x23, 0x00,
55 0x28, 0x00, // out imp: normal out type: parallel FEC mode:0
56 0x29, 0x1e, // 1/2 threshold
57 0x2a, 0x14, // 2/3 threshold
58 0x2b, 0x0f, // 3/4 threshold
59 0x2c, 0x09, // 5/6 threshold
60 0x2d, 0x05, // 7/8 threshold
61 0x2e, 0x01,
62 0x31, 0x1f, // test all FECs
63 0x32, 0x19, // viterbi and synchro search
64 0x33, 0xfc, // rs control
65 0x34, 0x93, // error control
66 0x0f, 0x92,
67 0xff, 0xff
68};
69
70
71static int alps_bsbe1_set_symbol_rate(struct dvb_frontend* fe, u32 srate, u32 ratio)
72{
73 u8 aclk = 0;
74 u8 bclk = 0;
75
76 if (srate < 1500000) { aclk = 0xb7; bclk = 0x47; }
77 else if (srate < 3000000) { aclk = 0xb7; bclk = 0x4b; }
78 else if (srate < 7000000) { aclk = 0xb7; bclk = 0x4f; }
79 else if (srate < 14000000) { aclk = 0xb7; bclk = 0x53; }
80 else if (srate < 30000000) { aclk = 0xb6; bclk = 0x53; }
81 else if (srate < 45000000) { aclk = 0xb4; bclk = 0x51; }
82
83 stv0299_writereg(fe, 0x13, aclk);
84 stv0299_writereg(fe, 0x14, bclk);
85 stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
86 stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
87 stv0299_writereg(fe, 0x21, (ratio ) & 0xf0);
88
89 return 0;
90}
91
92static int alps_bsbe1_pll_set(struct dvb_frontend* fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters* params)
93{
94 int ret;
95 u8 data[4];
96 u32 div;
97 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
98
99 if ((params->frequency < 950000) || (params->frequency > 2150000))
100 return -EINVAL;
101
102 div = (params->frequency + (125 - 1)) / 125; // round correctly
103 data[0] = (div >> 8) & 0x7f;
104 data[1] = div & 0xff;
105 data[2] = 0x80 | ((div & 0x18000) >> 10) | 4;
106 data[3] = (params->frequency > 1530000) ? 0xE0 : 0xE4;
107
108 ret = i2c_transfer(i2c, &msg, 1);
109 return (ret != 1) ? -EIO : 0;
110}
111
112static struct stv0299_config alps_bsbe1_config = {
113 .demod_address = 0x68,
114 .inittab = alps_bsbe1_inittab,
115 .mclk = 88000000UL,
116 .invert = 1,
117 .skip_reinit = 0,
118 .min_delay_ms = 100,
119 .set_symbol_rate = alps_bsbe1_set_symbol_rate,
120 .pll_set = alps_bsbe1_pll_set,
121};
122
123#endif
diff --git a/drivers/media/dvb/frontends/bsru6.h b/drivers/media/dvb/frontends/bsru6.h
new file mode 100644
index 000000000000..2a5366ce79cc
--- /dev/null
+++ b/drivers/media/dvb/frontends/bsru6.h
@@ -0,0 +1,140 @@
1/*
2 * bsru6.h - ALPS BSRU6 tuner support (moved from budget-ci.c)
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
20 *
21 *
22 * the project's page is at http://www.linuxtv.org
23 */
24
25#ifndef BSRU6_H
26#define BSRU6_H
27
28static u8 alps_bsru6_inittab[] = {
29 0x01, 0x15,
30 0x02, 0x00,
31 0x03, 0x00,
32 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
33 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */
34 0x06, 0x40, /* DAC not used, set to high impendance mode */
35 0x07, 0x00, /* DAC LSB */
36 0x08, 0x40, /* DiSEqC off, LNB power on OP2/LOCK pin on */
37 0x09, 0x00, /* FIFO */
38 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
39 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */
40 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
41 0x10, 0x3f, // AGC2 0x3d
42 0x11, 0x84,
43 0x12, 0xb9,
44 0x15, 0xc9, // lock detector threshold
45 0x16, 0x00,
46 0x17, 0x00,
47 0x18, 0x00,
48 0x19, 0x00,
49 0x1a, 0x00,
50 0x1f, 0x50,
51 0x20, 0x00,
52 0x21, 0x00,
53 0x22, 0x00,
54 0x23, 0x00,
55 0x28, 0x00, // out imp: normal out type: parallel FEC mode:0
56 0x29, 0x1e, // 1/2 threshold
57 0x2a, 0x14, // 2/3 threshold
58 0x2b, 0x0f, // 3/4 threshold
59 0x2c, 0x09, // 5/6 threshold
60 0x2d, 0x05, // 7/8 threshold
61 0x2e, 0x01,
62 0x31, 0x1f, // test all FECs
63 0x32, 0x19, // viterbi and synchro search
64 0x33, 0xfc, // rs control
65 0x34, 0x93, // error control
66 0x0f, 0x52,
67 0xff, 0xff
68};
69
70static int alps_bsru6_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32 ratio)
71{
72 u8 aclk = 0;
73 u8 bclk = 0;
74
75 if (srate < 1500000) {
76 aclk = 0xb7;
77 bclk = 0x47;
78 } else if (srate < 3000000) {
79 aclk = 0xb7;
80 bclk = 0x4b;
81 } else if (srate < 7000000) {
82 aclk = 0xb7;
83 bclk = 0x4f;
84 } else if (srate < 14000000) {
85 aclk = 0xb7;
86 bclk = 0x53;
87 } else if (srate < 30000000) {
88 aclk = 0xb6;
89 bclk = 0x53;
90 } else if (srate < 45000000) {
91 aclk = 0xb4;
92 bclk = 0x51;
93 }
94
95 stv0299_writereg(fe, 0x13, aclk);
96 stv0299_writereg(fe, 0x14, bclk);
97 stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
98 stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
99 stv0299_writereg(fe, 0x21, ratio & 0xf0);
100
101 return 0;
102}
103
104static int alps_bsru6_pll_set(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters *params)
105{
106 u8 buf[4];
107 u32 div;
108 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
109
110 if ((params->frequency < 950000) || (params->frequency > 2150000))
111 return -EINVAL;
112
113 div = (params->frequency + (125 - 1)) / 125; // round correctly
114 buf[0] = (div >> 8) & 0x7f;
115 buf[1] = div & 0xff;
116 buf[2] = 0x80 | ((div & 0x18000) >> 10) | 4;
117 buf[3] = 0xC4;
118
119 if (params->frequency > 1530000)
120 buf[3] = 0xc0;
121
122 if (i2c_transfer(i2c, &msg, 1) != 1)
123 return -EIO;
124 return 0;
125}
126
127static struct stv0299_config alps_bsru6_config = {
128 .demod_address = 0x68,
129 .inittab = alps_bsru6_inittab,
130 .mclk = 88000000UL,
131 .invert = 1,
132 .skip_reinit = 0,
133 .lock_output = STV0229_LOCKOUTPUT_1,
134 .volt13_op0_op1 = STV0299_VOLT13_OP1,
135 .min_delay_ms = 100,
136 .set_symbol_rate = alps_bsru6_set_symbol_rate,
137 .pll_set = alps_bsru6_pll_set,
138};
139
140#endif
diff --git a/drivers/media/dvb/frontends/cx24110.c b/drivers/media/dvb/frontends/cx24110.c
index d15d32c51dc5..f3edf8b517dd 100644
--- a/drivers/media/dvb/frontends/cx24110.c
+++ b/drivers/media/dvb/frontends/cx24110.c
@@ -371,6 +371,15 @@ static int cx24110_initfe(struct dvb_frontend* fe)
371 return 0; 371 return 0;
372} 372}
373 373
374static int cx24110_sleep(struct dvb_frontend *fe)
375{
376 struct cx24110_state *state = fe->demodulator_priv;
377
378 if (state->config->pll_sleep)
379 return state->config->pll_sleep(fe);
380 return 0;
381}
382
374static int cx24110_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltage) 383static int cx24110_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltage)
375{ 384{
376 struct cx24110_state *state = fe->demodulator_priv; 385 struct cx24110_state *state = fe->demodulator_priv;
@@ -418,6 +427,9 @@ static int cx24110_send_diseqc_msg(struct dvb_frontend* fe,
418 struct cx24110_state *state = fe->demodulator_priv; 427 struct cx24110_state *state = fe->demodulator_priv;
419 unsigned long timeout; 428 unsigned long timeout;
420 429
430 if (cmd->msg_len < 3 || cmd->msg_len > 6)
431 return -EINVAL; /* not implemented */
432
421 for (i = 0; i < cmd->msg_len; i++) 433 for (i = 0; i < cmd->msg_len; i++)
422 cx24110_writereg(state, 0x79 + i, cmd->msg[i]); 434 cx24110_writereg(state, 0x79 + i, cmd->msg[i]);
423 435
@@ -639,6 +651,7 @@ static struct dvb_frontend_ops cx24110_ops = {
639 .release = cx24110_release, 651 .release = cx24110_release,
640 652
641 .init = cx24110_initfe, 653 .init = cx24110_initfe,
654 .sleep = cx24110_sleep,
642 .set_frontend = cx24110_set_frontend, 655 .set_frontend = cx24110_set_frontend,
643 .get_frontend = cx24110_get_frontend, 656 .get_frontend = cx24110_get_frontend,
644 .read_status = cx24110_read_status, 657 .read_status = cx24110_read_status,
diff --git a/drivers/media/dvb/frontends/cx24110.h b/drivers/media/dvb/frontends/cx24110.h
index b63ecf26421a..609ac642b406 100644
--- a/drivers/media/dvb/frontends/cx24110.h
+++ b/drivers/media/dvb/frontends/cx24110.h
@@ -35,6 +35,7 @@ struct cx24110_config
35 /* PLL maintenance */ 35 /* PLL maintenance */
36 int (*pll_init)(struct dvb_frontend* fe); 36 int (*pll_init)(struct dvb_frontend* fe);
37 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); 37 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
38 int (*pll_sleep)(struct dvb_frontend* fe);
38}; 39};
39 40
40extern struct dvb_frontend* cx24110_attach(const struct cx24110_config* config, 41extern struct dvb_frontend* cx24110_attach(const struct cx24110_config* config,
diff --git a/drivers/media/dvb/frontends/dvb-pll.c b/drivers/media/dvb/frontends/dvb-pll.c
index 4dcb6050d4fa..b6e2c387a04c 100644
--- a/drivers/media/dvb/frontends/dvb-pll.c
+++ b/drivers/media/dvb/frontends/dvb-pll.c
@@ -362,6 +362,63 @@ struct dvb_pll_desc dvb_pll_philips_sd1878_tda8261 = {
362}; 362};
363EXPORT_SYMBOL(dvb_pll_philips_sd1878_tda8261); 363EXPORT_SYMBOL(dvb_pll_philips_sd1878_tda8261);
364 364
365/*
366 * Philips TD1316 Tuner.
367 */
368static void td1316_bw(u8 *buf, u32 freq, int bandwidth)
369{
370 u8 band;
371
372 /* determine band */
373 if (freq < 161000000)
374 band = 1;
375 else if (freq < 444000000)
376 band = 2;
377 else
378 band = 4;
379
380 buf[3] |= band;
381
382 /* setup PLL filter */
383 if (bandwidth == BANDWIDTH_8_MHZ)
384 buf[3] |= 1 << 3;
385}
386
387struct dvb_pll_desc dvb_pll_philips_td1316 = {
388 .name = "Philips TD1316",
389 .min = 87000000,
390 .max = 895000000,
391 .setbw = td1316_bw,
392 .count = 9,
393 .entries = {
394 { 93834000, 36166000, 166666, 0xca, 0x60},
395 { 123834000, 36166000, 166666, 0xca, 0xa0},
396 { 163834000, 36166000, 166666, 0xca, 0xc0},
397 { 253834000, 36166000, 166666, 0xca, 0x60},
398 { 383834000, 36166000, 166666, 0xca, 0xa0},
399 { 443834000, 36166000, 166666, 0xca, 0xc0},
400 { 583834000, 36166000, 166666, 0xca, 0x60},
401 { 793834000, 36166000, 166666, 0xca, 0xa0},
402 { 858834000, 36166000, 166666, 0xca, 0xe0},
403 },
404};
405EXPORT_SYMBOL(dvb_pll_philips_td1316);
406
407/* FE6600 used on DViCO Hybrid */
408struct dvb_pll_desc dvb_pll_thomson_fe6600 = {
409 .name = "Thomson FE6600",
410 .min = 44250000,
411 .max = 858000000,
412 .count = 4,
413 .entries = {
414 { 250000000, 36213333, 166667, 0xb4, 0x12 },
415 { 455000000, 36213333, 166667, 0xfe, 0x11 },
416 { 775500000, 36213333, 166667, 0xbc, 0x18 },
417 { 999999999, 36213333, 166667, 0xf4, 0x18 },
418 }
419};
420EXPORT_SYMBOL(dvb_pll_thomson_fe6600);
421
365/* ----------------------------------------------------------- */ 422/* ----------------------------------------------------------- */
366/* code */ 423/* code */
367 424
@@ -391,8 +448,8 @@ int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf,
391 div = (freq + desc->entries[i].offset) / desc->entries[i].stepsize; 448 div = (freq + desc->entries[i].offset) / desc->entries[i].stepsize;
392 buf[0] = div >> 8; 449 buf[0] = div >> 8;
393 buf[1] = div & 0xff; 450 buf[1] = div & 0xff;
394 buf[2] = desc->entries[i].cb1; 451 buf[2] = desc->entries[i].config;
395 buf[3] = desc->entries[i].cb2; 452 buf[3] = desc->entries[i].cb;
396 453
397 if (desc->setbw) 454 if (desc->setbw)
398 desc->setbw(buf, freq, bandwidth); 455 desc->setbw(buf, freq, bandwidth);
diff --git a/drivers/media/dvb/frontends/dvb-pll.h b/drivers/media/dvb/frontends/dvb-pll.h
index bb8d4b4eb183..2b8461784989 100644
--- a/drivers/media/dvb/frontends/dvb-pll.h
+++ b/drivers/media/dvb/frontends/dvb-pll.h
@@ -15,8 +15,8 @@ struct dvb_pll_desc {
15 u32 limit; 15 u32 limit;
16 u32 offset; 16 u32 offset;
17 u32 stepsize; 17 u32 stepsize;
18 u8 cb1; 18 u8 config;
19 u8 cb2; 19 u8 cb;
20 } entries[12]; 20 } entries[12];
21}; 21};
22 22
@@ -40,6 +40,9 @@ extern struct dvb_pll_desc dvb_pll_tuv1236d;
40extern struct dvb_pll_desc dvb_pll_tdhu2; 40extern struct dvb_pll_desc dvb_pll_tdhu2;
41extern struct dvb_pll_desc dvb_pll_samsung_tbmv; 41extern struct dvb_pll_desc dvb_pll_samsung_tbmv;
42extern struct dvb_pll_desc dvb_pll_philips_sd1878_tda8261; 42extern struct dvb_pll_desc dvb_pll_philips_sd1878_tda8261;
43extern struct dvb_pll_desc dvb_pll_philips_td1316;
44
45extern struct dvb_pll_desc dvb_pll_thomson_fe6600;
43 46
44int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf, 47int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf,
45 u32 freq, int bandwidth); 48 u32 freq, int bandwidth);
diff --git a/drivers/media/dvb/frontends/lnbp21.h b/drivers/media/dvb/frontends/lnbp21.h
new file mode 100644
index 000000000000..0dcbe61b61b1
--- /dev/null
+++ b/drivers/media/dvb/frontends/lnbp21.h
@@ -0,0 +1,139 @@
1/*
2 * lnbp21.h - driver for lnb supply and control ic lnbp21
3 *
4 * Copyright (C) 2006 Oliver Endriss
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
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 *
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
22 *
23 *
24 * the project's page is at http://www.linuxtv.org
25 */
26
27#ifndef _LNBP21_H
28#define _LNBP21_H
29
30/* system register */
31#define LNBP21_OLF 0x01
32#define LNBP21_OTF 0x02
33#define LNBP21_EN 0x04
34#define LNBP21_VSEL 0x08
35#define LNBP21_LLC 0x10
36#define LNBP21_TEN 0x20
37#define LNBP21_ISEL 0x40
38#define LNBP21_PCL 0x80
39
40struct lnbp21 {
41 u8 config;
42 u8 override_or;
43 u8 override_and;
44 struct i2c_adapter *i2c;
45 void (*release_chain)(struct dvb_frontend* fe);
46};
47
48static int lnbp21_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
49{
50 struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->misc_priv;
51 struct i2c_msg msg = { .addr = 0x08, .flags = 0,
52 .buf = &lnbp21->config,
53 .len = sizeof(lnbp21->config) };
54
55 lnbp21->config &= ~(LNBP21_VSEL | LNBP21_EN);
56
57 switch(voltage) {
58 case SEC_VOLTAGE_OFF:
59 break;
60 case SEC_VOLTAGE_13:
61 lnbp21->config |= LNBP21_EN;
62 break;
63 case SEC_VOLTAGE_18:
64 lnbp21->config |= (LNBP21_EN | LNBP21_VSEL);
65 break;
66 default:
67 return -EINVAL;
68 };
69
70 lnbp21->config |= lnbp21->override_or;
71 lnbp21->config &= lnbp21->override_and;
72
73 return (i2c_transfer(lnbp21->i2c, &msg, 1) == 1) ? 0 : -EIO;
74}
75
76static int lnbp21_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg)
77{
78 struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->misc_priv;
79 struct i2c_msg msg = { .addr = 0x08, .flags = 0,
80 .buf = &lnbp21->config,
81 .len = sizeof(lnbp21->config) };
82
83 if (arg)
84 lnbp21->config |= LNBP21_LLC;
85 else
86 lnbp21->config &= ~LNBP21_LLC;
87
88 lnbp21->config |= lnbp21->override_or;
89 lnbp21->config &= lnbp21->override_and;
90
91 return (i2c_transfer(lnbp21->i2c, &msg, 1) == 1) ? 0 : -EIO;
92}
93
94static void lnbp21_exit(struct dvb_frontend *fe)
95{
96 struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->misc_priv;
97
98 /* LNBP power off */
99 lnbp21_set_voltage(fe, SEC_VOLTAGE_OFF);
100
101 /* free data & call next release routine */
102 fe->ops->release = lnbp21->release_chain;
103 kfree(fe->misc_priv);
104 fe->misc_priv = NULL;
105 if (fe->ops->release)
106 fe->ops->release(fe);
107}
108
109static int lnbp21_init(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 override_set, u8 override_clear)
110{
111 struct lnbp21 *lnbp21 = kmalloc(sizeof(struct lnbp21), GFP_KERNEL);
112
113 if (!lnbp21)
114 return -ENOMEM;
115
116 /* default configuration */
117 lnbp21->config = LNBP21_ISEL;
118
119 /* bits which should be forced to '1' */
120 lnbp21->override_or = override_set;
121
122 /* bits which should be forced to '0' */
123 lnbp21->override_and = ~override_clear;
124
125 /* install release callback */
126 lnbp21->release_chain = fe->ops->release;
127 fe->ops->release = lnbp21_exit;
128
129 /* override frontend ops */
130 fe->ops->set_voltage = lnbp21_set_voltage;
131 fe->ops->enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage;
132
133 lnbp21->i2c = i2c;
134 fe->misc_priv = lnbp21;
135
136 return lnbp21_set_voltage(fe, SEC_VOLTAGE_OFF);
137}
138
139#endif
diff --git a/drivers/media/dvb/frontends/tda1004x.c b/drivers/media/dvb/frontends/tda1004x.c
index c63e9a5084eb..8e8df7b4ca0e 100644
--- a/drivers/media/dvb/frontends/tda1004x.c
+++ b/drivers/media/dvb/frontends/tda1004x.c
@@ -229,7 +229,7 @@ static int tda1004x_enable_tuner_i2c(struct tda1004x_state *state)
229 dprintk("%s\n", __FUNCTION__); 229 dprintk("%s\n", __FUNCTION__);
230 230
231 result = tda1004x_write_mask(state, TDA1004X_CONFC4, 2, 2); 231 result = tda1004x_write_mask(state, TDA1004X_CONFC4, 2, 2);
232 msleep(1); 232 msleep(20);
233 return result; 233 return result;
234} 234}
235 235
@@ -502,7 +502,12 @@ static int tda10046_fwupload(struct dvb_frontend* fe)
502 const struct firmware *fw; 502 const struct firmware *fw;
503 503
504 /* reset + wake up chip */ 504 /* reset + wake up chip */
505 tda1004x_write_byteI(state, TDA1004X_CONFC4, 0); 505 if (state->config->xtal_freq == TDA10046_XTAL_4M) {
506 tda1004x_write_byteI(state, TDA1004X_CONFC4, 0);
507 } else {
508 dprintk("%s: 16MHz Xtal, reducing I2C speed\n", __FUNCTION__);
509 tda1004x_write_byteI(state, TDA1004X_CONFC4, 0x80);
510 }
506 tda1004x_write_mask(state, TDA10046H_CONF_TRISTATE1, 1, 0); 511 tda1004x_write_mask(state, TDA10046H_CONF_TRISTATE1, 1, 0);
507 /* let the clocks recover from sleep */ 512 /* let the clocks recover from sleep */
508 msleep(5); 513 msleep(5);
@@ -651,7 +656,7 @@ static int tda10046_init(struct dvb_frontend* fe)
651 // tda setup 656 // tda setup
652 tda1004x_write_mask(state, TDA1004X_CONFC4, 0x20, 0); // disable DSP watchdog timer 657 tda1004x_write_mask(state, TDA1004X_CONFC4, 0x20, 0); // disable DSP watchdog timer
653 tda1004x_write_byteI(state, TDA1004X_AUTO, 0x87); // 100 ppm crystal, select HP stream 658 tda1004x_write_byteI(state, TDA1004X_AUTO, 0x87); // 100 ppm crystal, select HP stream
654 tda1004x_write_byteI(state, TDA1004X_CONFC1, 8); // disable pulse killer 659 tda1004x_write_byteI(state, TDA1004X_CONFC1, 0x88); // enable pulse killer
655 660
656 switch (state->config->agc_config) { 661 switch (state->config->agc_config) {
657 case TDA10046_AGC_DEFAULT: 662 case TDA10046_AGC_DEFAULT:
@@ -672,6 +677,12 @@ static int tda10046_init(struct dvb_frontend* fe)
672 tda1004x_write_byteI(state, TDA10046H_AGC_RENORM, 0x08); // Gain Renormalize 677 tda1004x_write_byteI(state, TDA10046H_AGC_RENORM, 0x08); // Gain Renormalize
673 tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x6a); // set AGC polarities 678 tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x6a); // set AGC polarities
674 break; 679 break;
680 case TDA10046_AGC_TDA827X_GPL:
681 tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x02); // AGC setup
682 tda1004x_write_byteI(state, TDA10046H_AGC_THR, 0x70); // AGC Threshold
683 tda1004x_write_byteI(state, TDA10046H_AGC_RENORM, 0x08); // Gain Renormalize
684 tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x60); // set AGC polarities
685 break;
675 } 686 }
676 tda1004x_write_byteI(state, TDA1004X_CONFADC2, 0x38); 687 tda1004x_write_byteI(state, TDA1004X_CONFADC2, 0x38);
677 tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE1, 0x61); // Turn both AGC outputs on 688 tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE1, 0x61); // Turn both AGC outputs on
@@ -683,6 +694,7 @@ static int tda10046_init(struct dvb_frontend* fe)
683 tda1004x_write_byteI(state, TDA10046H_CVBER_CTRL, 0x1a); // 10^6 VBER measurement bits 694 tda1004x_write_byteI(state, TDA10046H_CVBER_CTRL, 0x1a); // 10^6 VBER measurement bits
684 tda1004x_write_byteI(state, TDA1004X_CONF_TS1, 7); // MPEG2 interface config 695 tda1004x_write_byteI(state, TDA1004X_CONF_TS1, 7); // MPEG2 interface config
685 tda1004x_write_byteI(state, TDA1004X_CONF_TS2, 0xc0); // MPEG2 interface config 696 tda1004x_write_byteI(state, TDA1004X_CONF_TS2, 0xc0); // MPEG2 interface config
697 // tda1004x_write_mask(state, 0x50, 0x80, 0x80); // handle out of guard echoes
686 tda1004x_write_mask(state, 0x3a, 0x80, state->config->invert_oclk << 7); 698 tda1004x_write_mask(state, 0x3a, 0x80, state->config->invert_oclk << 7);
687 699
688 state->initialised = 1; 700 state->initialised = 1;
@@ -1027,6 +1039,7 @@ static int tda1004x_read_status(struct dvb_frontend* fe, fe_status_t * fe_status
1027 if (status == -1) 1039 if (status == -1)
1028 return -EIO; 1040 return -EIO;
1029 cber |= (status << 8); 1041 cber |= (status << 8);
1042 // The address 0x20 should be read to cope with a TDA10046 bug
1030 tda1004x_read_byte(state, TDA1004X_CBER_RESET); 1043 tda1004x_read_byte(state, TDA1004X_CBER_RESET);
1031 1044
1032 if (cber != 65535) 1045 if (cber != 65535)
@@ -1047,7 +1060,8 @@ static int tda1004x_read_status(struct dvb_frontend* fe, fe_status_t * fe_status
1047 status = tda1004x_read_byte(state, TDA1004X_VBER_MSB); 1060 status = tda1004x_read_byte(state, TDA1004X_VBER_MSB);
1048 if (status == -1) 1061 if (status == -1)
1049 return -EIO; 1062 return -EIO;
1050 vber |= ((status << 16) & 0x0f); 1063 vber |= (status & 0x0f) << 16;
1064 // The CVBER_LUT should be read to cope with TDA10046 hardware bug
1051 tda1004x_read_byte(state, TDA1004X_CVBER_LUT); 1065 tda1004x_read_byte(state, TDA1004X_CVBER_LUT);
1052 1066
1053 // if RS has passed some valid TS packets, then we must be 1067 // if RS has passed some valid TS packets, then we must be
@@ -1161,6 +1175,7 @@ static int tda1004x_read_ber(struct dvb_frontend* fe, u32* ber)
1161 if (tmp < 0) 1175 if (tmp < 0)
1162 return -EIO; 1176 return -EIO;
1163 *ber |= (tmp << 9); 1177 *ber |= (tmp << 9);
1178 // The address 0x20 should be read to cope with a TDA10046 bug
1164 tda1004x_read_byte(state, TDA1004X_CBER_RESET); 1179 tda1004x_read_byte(state, TDA1004X_CBER_RESET);
1165 1180
1166 dprintk("%s: ber=0x%x\n", __FUNCTION__, *ber); 1181 dprintk("%s: ber=0x%x\n", __FUNCTION__, *ber);
@@ -1187,6 +1202,8 @@ static int tda1004x_sleep(struct dvb_frontend* fe)
1187 tda1004x_disable_tuner_i2c(state); 1202 tda1004x_disable_tuner_i2c(state);
1188 } 1203 }
1189 } 1204 }
1205 /* set outputs to tristate */
1206 tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE1, 0xff);
1190 tda1004x_write_mask(state, TDA1004X_CONFC4, 1, 1); 1207 tda1004x_write_mask(state, TDA1004X_CONFC4, 1, 1);
1191 break; 1208 break;
1192 } 1209 }
diff --git a/drivers/media/dvb/frontends/tda1004x.h b/drivers/media/dvb/frontends/tda1004x.h
index 8659c52647ad..cc0c4af64067 100644
--- a/drivers/media/dvb/frontends/tda1004x.h
+++ b/drivers/media/dvb/frontends/tda1004x.h
@@ -35,7 +35,8 @@ enum tda10046_agc {
35 TDA10046_AGC_DEFAULT, /* original configuration */ 35 TDA10046_AGC_DEFAULT, /* original configuration */
36 TDA10046_AGC_IFO_AUTO_NEG, /* IF AGC only, automatic, negtive */ 36 TDA10046_AGC_IFO_AUTO_NEG, /* IF AGC only, automatic, negtive */
37 TDA10046_AGC_IFO_AUTO_POS, /* IF AGC only, automatic, positive */ 37 TDA10046_AGC_IFO_AUTO_POS, /* IF AGC only, automatic, positive */
38 TDA10046_AGC_TDA827X, /* IF AGC only, special setup for tda827x */ 38 TDA10046_AGC_TDA827X, /* IF AGC only, special setup for tda827x */
39 TDA10046_AGC_TDA827X_GPL, /* same as above, but GPIOs 0 */
39}; 40};
40 41
41enum tda10046_if { 42enum tda10046_if {
diff --git a/drivers/media/dvb/frontends/zl10353.c b/drivers/media/dvb/frontends/zl10353.c
new file mode 100644
index 000000000000..d7d9f59d76d2
--- /dev/null
+++ b/drivers/media/dvb/frontends/zl10353.c
@@ -0,0 +1,311 @@
1/*
2 * Driver for Zarlink DVB-T ZL10353 demodulator
3 *
4 * Copyright (C) 2006 Christopher Pascoe <c.pascoe@itee.uq.edu.au>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
20 */
21
22#include <linux/kernel.h>
23#include <linux/module.h>
24#include <linux/moduleparam.h>
25#include <linux/init.h>
26#include <linux/delay.h>
27#include <linux/string.h>
28#include <linux/slab.h>
29
30#include "dvb_frontend.h"
31#include "zl10353_priv.h"
32#include "zl10353.h"
33
34struct zl10353_state {
35 struct i2c_adapter *i2c;
36 struct dvb_frontend frontend;
37 struct dvb_frontend_ops ops;
38
39 struct zl10353_config config;
40};
41
42static int debug_regs = 0;
43
44static int zl10353_single_write(struct dvb_frontend *fe, u8 reg, u8 val)
45{
46 struct zl10353_state *state = fe->demodulator_priv;
47 u8 buf[2] = { reg, val };
48 struct i2c_msg msg = { .addr = state->config.demod_address, .flags = 0,
49 .buf = buf, .len = 2 };
50 int err = i2c_transfer(state->i2c, &msg, 1);
51 if (err != 1) {
52 printk("zl10353: write to reg %x failed (err = %d)!\n", reg, err);
53 return err;
54 }
55 return 0;
56}
57
58int zl10353_write(struct dvb_frontend *fe, u8 *ibuf, int ilen)
59{
60 int err, i;
61 for (i = 0; i < ilen - 1; i++)
62 if ((err = zl10353_single_write(fe, ibuf[0] + i, ibuf[i + 1])))
63 return err;
64
65 return 0;
66}
67
68static int zl10353_read_register(struct zl10353_state *state, u8 reg)
69{
70 int ret;
71 u8 b0[1] = { reg };
72 u8 b1[1] = { 0 };
73 struct i2c_msg msg[2] = { { .addr = state->config.demod_address,
74 .flags = 0,
75 .buf = b0, .len = 1 },
76 { .addr = state->config.demod_address,
77 .flags = I2C_M_RD,
78 .buf = b1, .len = 1 } };
79
80 ret = i2c_transfer(state->i2c, msg, 2);
81
82 if (ret != 2) {
83 printk("%s: readreg error (reg=%d, ret==%i)\n",
84 __FUNCTION__, reg, ret);
85 return ret;
86 }
87
88 return b1[0];
89}
90
91static void zl10353_dump_regs(struct dvb_frontend *fe)
92{
93 struct zl10353_state *state = fe->demodulator_priv;
94 char buf[52], buf2[4];
95 int ret;
96 u8 reg;
97
98 /* Dump all registers. */
99 for (reg = 0; ; reg++) {
100 if (reg % 16 == 0) {
101 if (reg)
102 printk(KERN_DEBUG "%s\n", buf);
103 sprintf(buf, "%02x: ", reg);
104 }
105 ret = zl10353_read_register(state, reg);
106 if (ret >= 0)
107 sprintf(buf2, "%02x ", (u8)ret);
108 else
109 strcpy(buf2, "-- ");
110 strcat(buf, buf2);
111 if (reg == 0xff)
112 break;
113 }
114 printk(KERN_DEBUG "%s\n", buf);
115}
116
117static int zl10353_sleep(struct dvb_frontend *fe)
118{
119 static u8 zl10353_softdown[] = { 0x50, 0x0C, 0x44 };
120
121 zl10353_write(fe, zl10353_softdown, sizeof(zl10353_softdown));
122 return 0;
123}
124
125static int zl10353_set_parameters(struct dvb_frontend *fe,
126 struct dvb_frontend_parameters *param)
127{
128 struct zl10353_state *state = fe->demodulator_priv;
129 u8 pllbuf[6] = { 0x67 };
130
131 /* These settings set "auto-everything" and start the FSM. */
132 zl10353_single_write(fe, 0x55, 0x80);
133 udelay(200);
134 zl10353_single_write(fe, 0xEA, 0x01);
135 udelay(200);
136 zl10353_single_write(fe, 0xEA, 0x00);
137
138 zl10353_single_write(fe, 0x56, 0x28);
139 zl10353_single_write(fe, 0x89, 0x20);
140 zl10353_single_write(fe, 0x5E, 0x00);
141 zl10353_single_write(fe, 0x65, 0x5A);
142 zl10353_single_write(fe, 0x66, 0xE9);
143 zl10353_single_write(fe, 0x62, 0x0A);
144
145 state->config.pll_set(fe, param, pllbuf + 1);
146 zl10353_write(fe, pllbuf, sizeof(pllbuf));
147
148 zl10353_single_write(fe, 0x70, 0x01);
149 udelay(250);
150 zl10353_single_write(fe, 0xE4, 0x00);
151 zl10353_single_write(fe, 0xE5, 0x2A);
152 zl10353_single_write(fe, 0xE9, 0x02);
153 zl10353_single_write(fe, 0xE7, 0x40);
154 zl10353_single_write(fe, 0xE8, 0x10);
155
156 return 0;
157}
158
159static int zl10353_read_status(struct dvb_frontend *fe, fe_status_t *status)
160{
161 struct zl10353_state *state = fe->demodulator_priv;
162 int s6, s7, s8;
163
164 if ((s6 = zl10353_read_register(state, STATUS_6)) < 0)
165 return -EREMOTEIO;
166 if ((s7 = zl10353_read_register(state, STATUS_7)) < 0)
167 return -EREMOTEIO;
168 if ((s8 = zl10353_read_register(state, STATUS_8)) < 0)
169 return -EREMOTEIO;
170
171 *status = 0;
172 if (s6 & (1 << 2))
173 *status |= FE_HAS_CARRIER;
174 if (s6 & (1 << 1))
175 *status |= FE_HAS_VITERBI;
176 if (s6 & (1 << 5))
177 *status |= FE_HAS_LOCK;
178 if (s7 & (1 << 4))
179 *status |= FE_HAS_SYNC;
180 if (s8 & (1 << 6))
181 *status |= FE_HAS_SIGNAL;
182
183 if ((*status & (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC)) !=
184 (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC))
185 *status &= ~FE_HAS_LOCK;
186
187 return 0;
188}
189
190static int zl10353_read_snr(struct dvb_frontend *fe, u16 *snr)
191{
192 struct zl10353_state *state = fe->demodulator_priv;
193 u8 _snr;
194
195 if (debug_regs)
196 zl10353_dump_regs(fe);
197
198 _snr = zl10353_read_register(state, SNR);
199 *snr = (_snr << 8) | _snr;
200
201 return 0;
202}
203
204static int zl10353_get_tune_settings(struct dvb_frontend *fe,
205 struct dvb_frontend_tune_settings
206 *fe_tune_settings)
207{
208 fe_tune_settings->min_delay_ms = 1000;
209 fe_tune_settings->step_size = 0;
210 fe_tune_settings->max_drift = 0;
211
212 return 0;
213}
214
215static int zl10353_init(struct dvb_frontend *fe)
216{
217 struct zl10353_state *state = fe->demodulator_priv;
218 u8 zl10353_reset_attach[6] = { 0x50, 0x03, 0x64, 0x46, 0x15, 0x0F };
219 int rc = 0;
220
221 if (debug_regs)
222 zl10353_dump_regs(fe);
223
224 /* Do a "hard" reset if not already done */
225 if (zl10353_read_register(state, 0x50) != 0x03) {
226 rc = zl10353_write(fe, zl10353_reset_attach,
227 sizeof(zl10353_reset_attach));
228 if (debug_regs)
229 zl10353_dump_regs(fe);
230 }
231
232 return 0;
233}
234
235static void zl10353_release(struct dvb_frontend *fe)
236{
237 struct zl10353_state *state = fe->demodulator_priv;
238
239 kfree(state);
240}
241
242static struct dvb_frontend_ops zl10353_ops;
243
244struct dvb_frontend *zl10353_attach(const struct zl10353_config *config,
245 struct i2c_adapter *i2c)
246{
247 struct zl10353_state *state = NULL;
248
249 /* allocate memory for the internal state */
250 state = kzalloc(sizeof(struct zl10353_state), GFP_KERNEL);
251 if (state == NULL)
252 goto error;
253
254 /* setup the state */
255 state->i2c = i2c;
256 memcpy(&state->config, config, sizeof(struct zl10353_config));
257 memcpy(&state->ops, &zl10353_ops, sizeof(struct dvb_frontend_ops));
258
259 /* check if the demod is there */
260 if (zl10353_read_register(state, CHIP_ID) != ID_ZL10353)
261 goto error;
262
263 /* create dvb_frontend */
264 state->frontend.ops = &state->ops;
265 state->frontend.demodulator_priv = state;
266
267 return &state->frontend;
268error:
269 kfree(state);
270 return NULL;
271}
272
273static struct dvb_frontend_ops zl10353_ops = {
274
275 .info = {
276 .name = "Zarlink ZL10353 DVB-T",
277 .type = FE_OFDM,
278 .frequency_min = 174000000,
279 .frequency_max = 862000000,
280 .frequency_stepsize = 166667,
281 .frequency_tolerance = 0,
282 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
283 FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
284 FE_CAN_FEC_AUTO |
285 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
286 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
287 FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER |
288 FE_CAN_MUTE_TS
289 },
290
291 .release = zl10353_release,
292
293 .init = zl10353_init,
294 .sleep = zl10353_sleep,
295
296 .set_frontend = zl10353_set_parameters,
297 .get_tune_settings = zl10353_get_tune_settings,
298
299 .read_status = zl10353_read_status,
300 .read_snr = zl10353_read_snr,
301};
302
303module_param(debug_regs, int, 0644);
304MODULE_PARM_DESC(debug_regs, "Turn on/off frontend register dumps (default:off).");
305
306MODULE_DESCRIPTION("Zarlink ZL10353 DVB-T demodulator driver");
307MODULE_AUTHOR("Chris Pascoe");
308MODULE_LICENSE("GPL");
309
310EXPORT_SYMBOL(zl10353_attach);
311EXPORT_SYMBOL(zl10353_write);
diff --git a/drivers/media/dvb/frontends/zl10353.h b/drivers/media/dvb/frontends/zl10353.h
new file mode 100644
index 000000000000..5cc4ae718d8c
--- /dev/null
+++ b/drivers/media/dvb/frontends/zl10353.h
@@ -0,0 +1,43 @@
1/*
2 * Driver for Zarlink DVB-T ZL10353 demodulator
3 *
4 * Copyright (C) 2006 Christopher Pascoe <c.pascoe@itee.uq.edu.au>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
20 */
21
22#ifndef ZL10353_H
23#define ZL10353_H
24
25#include <linux/dvb/frontend.h>
26
27struct zl10353_config
28{
29 /* demodulator's I2C address */
30 u8 demod_address;
31
32 /* function which configures the PLL buffer (for secondary I2C
33 * connected tuner) or tunes the PLL (for direct connected tuner) */
34 int (*pll_set)(struct dvb_frontend *fe,
35 struct dvb_frontend_parameters *params, u8 *pllbuf);
36};
37
38extern struct dvb_frontend* zl10353_attach(const struct zl10353_config *config,
39 struct i2c_adapter *i2c);
40
41extern int zl10353_write(struct dvb_frontend *fe, u8 *ibuf, int ilen);
42
43#endif /* ZL10353_H */
diff --git a/drivers/media/dvb/frontends/zl10353_priv.h b/drivers/media/dvb/frontends/zl10353_priv.h
new file mode 100644
index 000000000000..b72224bd7dde
--- /dev/null
+++ b/drivers/media/dvb/frontends/zl10353_priv.h
@@ -0,0 +1,42 @@
1/*
2 * Driver for Zarlink DVB-T ZL10353 demodulator
3 *
4 * Copyright (C) 2006 Christopher Pascoe <c.pascoe@itee.uq.edu.au>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
20 */
21
22#ifndef _ZL10353_PRIV_
23#define _ZL10353_PRIV_
24
25#define ID_ZL10353 0x14
26
27enum zl10353_reg_addr {
28 INTERRUPT_0 = 0x00,
29 INTERRUPT_1 = 0x01,
30 INTERRUPT_2 = 0x02,
31 INTERRUPT_3 = 0x03,
32 INTERRUPT_4 = 0x04,
33 INTERRUPT_5 = 0x05,
34 STATUS_6 = 0x06,
35 STATUS_7 = 0x07,
36 STATUS_8 = 0x08,
37 STATUS_9 = 0x09,
38 SNR = 0x10,
39 CHIP_ID = 0x7F,
40};
41
42#endif /* _ZL10353_PRIV_ */