aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/frontends/mt2131.c
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@infradead.org>2008-04-29 20:38:45 -0400
committerMauro Carvalho Chehab <mchehab@infradead.org>2008-04-29 17:41:38 -0400
commitb094516f9589245617eb5d0452769826063f72ac (patch)
tree45593c7f1ae4c180d97ed7b9cbc27a85c03f55d1 /drivers/media/dvb/frontends/mt2131.c
parentdf7aaaf3a74016cbc72382b6388c7c62f3df49b2 (diff)
V4L/DVB (7769): Move other terrestrial tuners to common/tuners
Those tuners are currently used only under media/dvb. However, they can support also analog TV. Better to move them to the same place as the other hybrid tuners. This would make easier to use those tuners also by analog drivers. Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/dvb/frontends/mt2131.c')
-rw-r--r--drivers/media/dvb/frontends/mt2131.c314
1 files changed, 0 insertions, 314 deletions
diff --git a/drivers/media/dvb/frontends/mt2131.c b/drivers/media/dvb/frontends/mt2131.c
deleted file mode 100644
index e254bcfc2efb..000000000000
--- a/drivers/media/dvb/frontends/mt2131.c
+++ /dev/null
@@ -1,314 +0,0 @@
1/*
2 * Driver for Microtune MT2131 "QAM/8VSB single chip tuner"
3 *
4 * Copyright (c) 2006 Steven Toth <stoth@hauppauge.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include <linux/module.h>
23#include <linux/delay.h>
24#include <linux/dvb/frontend.h>
25#include <linux/i2c.h>
26
27#include "dvb_frontend.h"
28
29#include "mt2131.h"
30#include "mt2131_priv.h"
31
32static int debug;
33module_param(debug, int, 0644);
34MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
35
36#define dprintk(level,fmt, arg...) if (debug >= level) \
37 printk(KERN_INFO "%s: " fmt, "mt2131", ## arg)
38
39static u8 mt2131_config1[] = {
40 0x01,
41 0x50, 0x00, 0x50, 0x80, 0x00, 0x49, 0xfa, 0x88,
42 0x08, 0x77, 0x41, 0x04, 0x00, 0x00, 0x00, 0x32,
43 0x7f, 0xda, 0x4c, 0x00, 0x10, 0xaa, 0x78, 0x80,
44 0xff, 0x68, 0xa0, 0xff, 0xdd, 0x00, 0x00
45};
46
47static u8 mt2131_config2[] = {
48 0x10,
49 0x7f, 0xc8, 0x0a, 0x5f, 0x00, 0x04
50};
51
52static int mt2131_readreg(struct mt2131_priv *priv, u8 reg, u8 *val)
53{
54 struct i2c_msg msg[2] = {
55 { .addr = priv->cfg->i2c_address, .flags = 0,
56 .buf = &reg, .len = 1 },
57 { .addr = priv->cfg->i2c_address, .flags = I2C_M_RD,
58 .buf = val, .len = 1 },
59 };
60
61 if (i2c_transfer(priv->i2c, msg, 2) != 2) {
62 printk(KERN_WARNING "mt2131 I2C read failed\n");
63 return -EREMOTEIO;
64 }
65 return 0;
66}
67
68static int mt2131_writereg(struct mt2131_priv *priv, u8 reg, u8 val)
69{
70 u8 buf[2] = { reg, val };
71 struct i2c_msg msg = { .addr = priv->cfg->i2c_address, .flags = 0,
72 .buf = buf, .len = 2 };
73
74 if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
75 printk(KERN_WARNING "mt2131 I2C write failed\n");
76 return -EREMOTEIO;
77 }
78 return 0;
79}
80
81static int mt2131_writeregs(struct mt2131_priv *priv,u8 *buf, u8 len)
82{
83 struct i2c_msg msg = { .addr = priv->cfg->i2c_address,
84 .flags = 0, .buf = buf, .len = len };
85
86 if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
87 printk(KERN_WARNING "mt2131 I2C write failed (len=%i)\n",
88 (int)len);
89 return -EREMOTEIO;
90 }
91 return 0;
92}
93
94static int mt2131_set_params(struct dvb_frontend *fe,
95 struct dvb_frontend_parameters *params)
96{
97 struct mt2131_priv *priv;
98 int ret=0, i;
99 u32 freq;
100 u8 if_band_center;
101 u32 f_lo1, f_lo2;
102 u32 div1, num1, div2, num2;
103 u8 b[8];
104 u8 lockval = 0;
105
106 priv = fe->tuner_priv;
107 if (fe->ops.info.type == FE_OFDM)
108 priv->bandwidth = params->u.ofdm.bandwidth;
109 else
110 priv->bandwidth = 0;
111
112 freq = params->frequency / 1000; // Hz -> kHz
113 dprintk(1, "%s() freq=%d\n", __func__, freq);
114
115 f_lo1 = freq + MT2131_IF1 * 1000;
116 f_lo1 = (f_lo1 / 250) * 250;
117 f_lo2 = f_lo1 - freq - MT2131_IF2;
118
119 priv->frequency = (f_lo1 - f_lo2 - MT2131_IF2) * 1000;
120
121 /* Frequency LO1 = 16MHz * (DIV1 + NUM1/8192 ) */
122 num1 = f_lo1 * 64 / (MT2131_FREF / 128);
123 div1 = num1 / 8192;
124 num1 &= 0x1fff;
125
126 /* Frequency LO2 = 16MHz * (DIV2 + NUM2/8192 ) */
127 num2 = f_lo2 * 64 / (MT2131_FREF / 128);
128 div2 = num2 / 8192;
129 num2 &= 0x1fff;
130
131 if (freq <= 82500) if_band_center = 0x00; else
132 if (freq <= 137500) if_band_center = 0x01; else
133 if (freq <= 192500) if_band_center = 0x02; else
134 if (freq <= 247500) if_band_center = 0x03; else
135 if (freq <= 302500) if_band_center = 0x04; else
136 if (freq <= 357500) if_band_center = 0x05; else
137 if (freq <= 412500) if_band_center = 0x06; else
138 if (freq <= 467500) if_band_center = 0x07; else
139 if (freq <= 522500) if_band_center = 0x08; else
140 if (freq <= 577500) if_band_center = 0x09; else
141 if (freq <= 632500) if_band_center = 0x0A; else
142 if (freq <= 687500) if_band_center = 0x0B; else
143 if (freq <= 742500) if_band_center = 0x0C; else
144 if (freq <= 797500) if_band_center = 0x0D; else
145 if (freq <= 852500) if_band_center = 0x0E; else
146 if (freq <= 907500) if_band_center = 0x0F; else
147 if (freq <= 962500) if_band_center = 0x10; else
148 if (freq <= 1017500) if_band_center = 0x11; else
149 if (freq <= 1072500) if_band_center = 0x12; else if_band_center = 0x13;
150
151 b[0] = 1;
152 b[1] = (num1 >> 5) & 0xFF;
153 b[2] = (num1 & 0x1F);
154 b[3] = div1;
155 b[4] = (num2 >> 5) & 0xFF;
156 b[5] = num2 & 0x1F;
157 b[6] = div2;
158
159 dprintk(1, "IF1: %dMHz IF2: %dMHz\n", MT2131_IF1, MT2131_IF2);
160 dprintk(1, "PLL freq=%dkHz band=%d\n", (int)freq, (int)if_band_center);
161 dprintk(1, "PLL f_lo1=%dkHz f_lo2=%dkHz\n", (int)f_lo1, (int)f_lo2);
162 dprintk(1, "PLL div1=%d num1=%d div2=%d num2=%d\n",
163 (int)div1, (int)num1, (int)div2, (int)num2);
164 dprintk(1, "PLL [1..6]: %2x %2x %2x %2x %2x %2x\n",
165 (int)b[1], (int)b[2], (int)b[3], (int)b[4], (int)b[5],
166 (int)b[6]);
167
168 ret = mt2131_writeregs(priv,b,7);
169 if (ret < 0)
170 return ret;
171
172 mt2131_writereg(priv, 0x0b, if_band_center);
173
174 /* Wait for lock */
175 i = 0;
176 do {
177 mt2131_readreg(priv, 0x08, &lockval);
178 if ((lockval & 0x88) == 0x88)
179 break;
180 msleep(4);
181 i++;
182 } while (i < 10);
183
184 return ret;
185}
186
187static int mt2131_get_frequency(struct dvb_frontend *fe, u32 *frequency)
188{
189 struct mt2131_priv *priv = fe->tuner_priv;
190 dprintk(1, "%s()\n", __func__);
191 *frequency = priv->frequency;
192 return 0;
193}
194
195static int mt2131_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
196{
197 struct mt2131_priv *priv = fe->tuner_priv;
198 dprintk(1, "%s()\n", __func__);
199 *bandwidth = priv->bandwidth;
200 return 0;
201}
202
203static int mt2131_get_status(struct dvb_frontend *fe, u32 *status)
204{
205 struct mt2131_priv *priv = fe->tuner_priv;
206 u8 lock_status = 0;
207 u8 afc_status = 0;
208
209 *status = 0;
210
211 mt2131_readreg(priv, 0x08, &lock_status);
212 if ((lock_status & 0x88) == 0x88)
213 *status = TUNER_STATUS_LOCKED;
214
215 mt2131_readreg(priv, 0x09, &afc_status);
216 dprintk(1, "%s() - LO Status = 0x%x, AFC Status = 0x%x\n",
217 __func__, lock_status, afc_status);
218
219 return 0;
220}
221
222static int mt2131_init(struct dvb_frontend *fe)
223{
224 struct mt2131_priv *priv = fe->tuner_priv;
225 int ret;
226 dprintk(1, "%s()\n", __func__);
227
228 if ((ret = mt2131_writeregs(priv, mt2131_config1,
229 sizeof(mt2131_config1))) < 0)
230 return ret;
231
232 mt2131_writereg(priv, 0x0b, 0x09);
233 mt2131_writereg(priv, 0x15, 0x47);
234 mt2131_writereg(priv, 0x07, 0xf2);
235 mt2131_writereg(priv, 0x0b, 0x01);
236
237 if ((ret = mt2131_writeregs(priv, mt2131_config2,
238 sizeof(mt2131_config2))) < 0)
239 return ret;
240
241 return ret;
242}
243
244static int mt2131_release(struct dvb_frontend *fe)
245{
246 dprintk(1, "%s()\n", __func__);
247 kfree(fe->tuner_priv);
248 fe->tuner_priv = NULL;
249 return 0;
250}
251
252static const struct dvb_tuner_ops mt2131_tuner_ops = {
253 .info = {
254 .name = "Microtune MT2131",
255 .frequency_min = 48000000,
256 .frequency_max = 860000000,
257 .frequency_step = 50000,
258 },
259
260 .release = mt2131_release,
261 .init = mt2131_init,
262
263 .set_params = mt2131_set_params,
264 .get_frequency = mt2131_get_frequency,
265 .get_bandwidth = mt2131_get_bandwidth,
266 .get_status = mt2131_get_status
267};
268
269struct dvb_frontend * mt2131_attach(struct dvb_frontend *fe,
270 struct i2c_adapter *i2c,
271 struct mt2131_config *cfg, u16 if1)
272{
273 struct mt2131_priv *priv = NULL;
274 u8 id = 0;
275
276 dprintk(1, "%s()\n", __func__);
277
278 priv = kzalloc(sizeof(struct mt2131_priv), GFP_KERNEL);
279 if (priv == NULL)
280 return NULL;
281
282 priv->cfg = cfg;
283 priv->bandwidth = 6000000; /* 6MHz */
284 priv->i2c = i2c;
285
286 if (mt2131_readreg(priv, 0, &id) != 0) {
287 kfree(priv);
288 return NULL;
289 }
290 if ( (id != 0x3E) && (id != 0x3F) ) {
291 printk(KERN_ERR "MT2131: Device not found at addr 0x%02x\n",
292 cfg->i2c_address);
293 kfree(priv);
294 return NULL;
295 }
296
297 printk(KERN_INFO "MT2131: successfully identified at address 0x%02x\n",
298 cfg->i2c_address);
299 memcpy(&fe->ops.tuner_ops, &mt2131_tuner_ops,
300 sizeof(struct dvb_tuner_ops));
301
302 fe->tuner_priv = priv;
303 return fe;
304}
305EXPORT_SYMBOL(mt2131_attach);
306
307MODULE_AUTHOR("Steven Toth");
308MODULE_DESCRIPTION("Microtune MT2131 silicon tuner driver");
309MODULE_LICENSE("GPL");
310
311/*
312 * Local variables:
313 * c-basic-offset: 8
314 */