diff options
Diffstat (limited to 'drivers/media/dvb/frontends')
-rw-r--r-- | drivers/media/dvb/frontends/Kconfig | 12 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/Makefile | 1 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/bcm3510.c | 9 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/bsbe1.h | 123 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/bsru6.h | 140 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/cx24110.c | 13 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/cx24110.h | 1 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/dvb-pll.c | 61 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/dvb-pll.h | 7 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/lnbp21.h | 139 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/tda1004x.c | 25 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/tda1004x.h | 3 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/zl10353.c | 311 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/zl10353.h | 43 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/zl10353_priv.h | 42 |
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 | ||
119 | config 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 | |||
119 | config DVB_DIB3000MB | 125 | config 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 | ||
157 | config DVB_NXT200X | 163 | config 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 | ||
171 | config DVB_OR51211 | 177 | config 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 | ||
178 | config DVB_OR51132 | 184 | config 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 | |||
20 | obj-$(CONFIG_DVB_SP887X) += sp887x.o | 20 | obj-$(CONFIG_DVB_SP887X) += sp887x.o |
21 | obj-$(CONFIG_DVB_NXT6000) += nxt6000.o | 21 | obj-$(CONFIG_DVB_NXT6000) += nxt6000.o |
22 | obj-$(CONFIG_DVB_MT352) += mt352.o | 22 | obj-$(CONFIG_DVB_MT352) += mt352.o |
23 | obj-$(CONFIG_DVB_ZL10353) += zl10353.o | ||
23 | obj-$(CONFIG_DVB_CX22702) += cx22702.o | 24 | obj-$(CONFIG_DVB_CX22702) += cx22702.o |
24 | obj-$(CONFIG_DVB_TDA10021) += tda10021.o | 25 | obj-$(CONFIG_DVB_TDA10021) += tda10021.o |
25 | obj-$(CONFIG_DVB_STV0297) += stv0297.o | 26 | obj-$(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); |
228 | error: | 229 | error: |
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 | |||
28 | static 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 | |||
71 | static 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 | |||
92 | static 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 | |||
112 | static 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 | |||
28 | static 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 | |||
70 | static 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 | |||
104 | static 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 | |||
127 | static 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 | ||
374 | static 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 | |||
374 | static int cx24110_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltage) | 383 | static 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 | ||
40 | extern struct dvb_frontend* cx24110_attach(const struct cx24110_config* config, | 41 | extern 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 | }; |
363 | EXPORT_SYMBOL(dvb_pll_philips_sd1878_tda8261); | 363 | EXPORT_SYMBOL(dvb_pll_philips_sd1878_tda8261); |
364 | 364 | ||
365 | /* | ||
366 | * Philips TD1316 Tuner. | ||
367 | */ | ||
368 | static 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 | |||
387 | struct 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 | }; | ||
405 | EXPORT_SYMBOL(dvb_pll_philips_td1316); | ||
406 | |||
407 | /* FE6600 used on DViCO Hybrid */ | ||
408 | struct 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 | }; | ||
420 | EXPORT_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; | |||
40 | extern struct dvb_pll_desc dvb_pll_tdhu2; | 40 | extern struct dvb_pll_desc dvb_pll_tdhu2; |
41 | extern struct dvb_pll_desc dvb_pll_samsung_tbmv; | 41 | extern struct dvb_pll_desc dvb_pll_samsung_tbmv; |
42 | extern struct dvb_pll_desc dvb_pll_philips_sd1878_tda8261; | 42 | extern struct dvb_pll_desc dvb_pll_philips_sd1878_tda8261; |
43 | extern struct dvb_pll_desc dvb_pll_philips_td1316; | ||
44 | |||
45 | extern struct dvb_pll_desc dvb_pll_thomson_fe6600; | ||
43 | 46 | ||
44 | int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf, | 47 | int 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 | |||
40 | struct 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 | |||
48 | static 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 | |||
76 | static 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 | |||
94 | static 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 | |||
109 | static 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 | ||
41 | enum tda10046_if { | 42 | enum 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 | |||
34 | struct 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 | |||
42 | static int debug_regs = 0; | ||
43 | |||
44 | static 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 | |||
58 | int 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 | |||
68 | static 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 | |||
91 | static 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 | |||
117 | static 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 | |||
125 | static 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 | |||
159 | static 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 | |||
190 | static 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 | |||
204 | static 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 | |||
215 | static 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 | |||
235 | static void zl10353_release(struct dvb_frontend *fe) | ||
236 | { | ||
237 | struct zl10353_state *state = fe->demodulator_priv; | ||
238 | |||
239 | kfree(state); | ||
240 | } | ||
241 | |||
242 | static struct dvb_frontend_ops zl10353_ops; | ||
243 | |||
244 | struct 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; | ||
268 | error: | ||
269 | kfree(state); | ||
270 | return NULL; | ||
271 | } | ||
272 | |||
273 | static 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 | |||
303 | module_param(debug_regs, int, 0644); | ||
304 | MODULE_PARM_DESC(debug_regs, "Turn on/off frontend register dumps (default:off)."); | ||
305 | |||
306 | MODULE_DESCRIPTION("Zarlink ZL10353 DVB-T demodulator driver"); | ||
307 | MODULE_AUTHOR("Chris Pascoe"); | ||
308 | MODULE_LICENSE("GPL"); | ||
309 | |||
310 | EXPORT_SYMBOL(zl10353_attach); | ||
311 | EXPORT_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 | |||
27 | struct 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 | |||
38 | extern struct dvb_frontend* zl10353_attach(const struct zl10353_config *config, | ||
39 | struct i2c_adapter *i2c); | ||
40 | |||
41 | extern 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 | |||
27 | enum 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_ */ | ||