mt2131.c revision 6d8976164dd7d10d25fe940b8546265f60ad52cd
1f47623a04dab402fb2c18fe516a174bc02005629Steven Toth/*
2f47623a04dab402fb2c18fe516a174bc02005629Steven Toth *  Driver for Microtune MT2131 "QAM/8VSB single chip tuner"
3f47623a04dab402fb2c18fe516a174bc02005629Steven Toth *
46d8976164dd7d10d25fe940b8546265f60ad52cdSteven Toth *  Copyright (c) 2006 Steven Toth <stoth@linuxtv.org>
5f47623a04dab402fb2c18fe516a174bc02005629Steven Toth *
6f47623a04dab402fb2c18fe516a174bc02005629Steven Toth *  This program is free software; you can redistribute it and/or modify
7f47623a04dab402fb2c18fe516a174bc02005629Steven Toth *  it under the terms of the GNU General Public License as published by
8f47623a04dab402fb2c18fe516a174bc02005629Steven Toth *  the Free Software Foundation; either version 2 of the License, or
9f47623a04dab402fb2c18fe516a174bc02005629Steven Toth *  (at your option) any later version.
10f47623a04dab402fb2c18fe516a174bc02005629Steven Toth *
11f47623a04dab402fb2c18fe516a174bc02005629Steven Toth *  This program is distributed in the hope that it will be useful,
12f47623a04dab402fb2c18fe516a174bc02005629Steven Toth *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13f47623a04dab402fb2c18fe516a174bc02005629Steven Toth *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14f47623a04dab402fb2c18fe516a174bc02005629Steven Toth *
15f47623a04dab402fb2c18fe516a174bc02005629Steven Toth *  GNU General Public License for more details.
16f47623a04dab402fb2c18fe516a174bc02005629Steven Toth *
17f47623a04dab402fb2c18fe516a174bc02005629Steven Toth *  You should have received a copy of the GNU General Public License
18f47623a04dab402fb2c18fe516a174bc02005629Steven Toth *  along with this program; if not, write to the Free Software
19f47623a04dab402fb2c18fe516a174bc02005629Steven Toth *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20f47623a04dab402fb2c18fe516a174bc02005629Steven Toth */
21f47623a04dab402fb2c18fe516a174bc02005629Steven Toth
22f47623a04dab402fb2c18fe516a174bc02005629Steven Toth#include <linux/module.h>
23f47623a04dab402fb2c18fe516a174bc02005629Steven Toth#include <linux/delay.h>
24f47623a04dab402fb2c18fe516a174bc02005629Steven Toth#include <linux/dvb/frontend.h>
25f47623a04dab402fb2c18fe516a174bc02005629Steven Toth#include <linux/i2c.h>
26f47623a04dab402fb2c18fe516a174bc02005629Steven Toth
27f47623a04dab402fb2c18fe516a174bc02005629Steven Toth#include "dvb_frontend.h"
28f47623a04dab402fb2c18fe516a174bc02005629Steven Toth
29f47623a04dab402fb2c18fe516a174bc02005629Steven Toth#include "mt2131.h"
30f47623a04dab402fb2c18fe516a174bc02005629Steven Toth#include "mt2131_priv.h"
31f47623a04dab402fb2c18fe516a174bc02005629Steven Toth
32f47623a04dab402fb2c18fe516a174bc02005629Steven Tothstatic int debug;
33f47623a04dab402fb2c18fe516a174bc02005629Steven Tothmodule_param(debug, int, 0644);
34f47623a04dab402fb2c18fe516a174bc02005629Steven TothMODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
35f47623a04dab402fb2c18fe516a174bc02005629Steven Toth
36f47623a04dab402fb2c18fe516a174bc02005629Steven Toth#define dprintk(level,fmt, arg...) if (debug >= level) \
37f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	printk(KERN_INFO "%s: " fmt, "mt2131", ## arg)
38f47623a04dab402fb2c18fe516a174bc02005629Steven Toth
39f47623a04dab402fb2c18fe516a174bc02005629Steven Tothstatic u8 mt2131_config1[] = {
40f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	0x01,
41f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	0x50, 0x00, 0x50, 0x80, 0x00, 0x49, 0xfa, 0x88,
42f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	0x08, 0x77, 0x41, 0x04, 0x00, 0x00, 0x00, 0x32,
43f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	0x7f, 0xda, 0x4c, 0x00, 0x10, 0xaa, 0x78, 0x80,
44f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	0xff, 0x68, 0xa0, 0xff, 0xdd, 0x00, 0x00
45f47623a04dab402fb2c18fe516a174bc02005629Steven Toth};
46f47623a04dab402fb2c18fe516a174bc02005629Steven Toth
47f47623a04dab402fb2c18fe516a174bc02005629Steven Tothstatic u8 mt2131_config2[] = {
48f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	0x10,
49f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	0x7f, 0xc8, 0x0a, 0x5f, 0x00, 0x04
50f47623a04dab402fb2c18fe516a174bc02005629Steven Toth};
51f47623a04dab402fb2c18fe516a174bc02005629Steven Toth
52f47623a04dab402fb2c18fe516a174bc02005629Steven Tothstatic int mt2131_readreg(struct mt2131_priv *priv, u8 reg, u8 *val)
53f47623a04dab402fb2c18fe516a174bc02005629Steven Toth{
54f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	struct i2c_msg msg[2] = {
553873dd041465799cfdeb642531c0ade4fb6614e5Michael Krufky		{ .addr = priv->cfg->i2c_address, .flags = 0,
563873dd041465799cfdeb642531c0ade4fb6614e5Michael Krufky		  .buf = &reg, .len = 1 },
573873dd041465799cfdeb642531c0ade4fb6614e5Michael Krufky		{ .addr = priv->cfg->i2c_address, .flags = I2C_M_RD,
583873dd041465799cfdeb642531c0ade4fb6614e5Michael Krufky		  .buf = val,  .len = 1 },
59f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	};
60f47623a04dab402fb2c18fe516a174bc02005629Steven Toth
61f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	if (i2c_transfer(priv->i2c, msg, 2) != 2) {
62f47623a04dab402fb2c18fe516a174bc02005629Steven Toth		printk(KERN_WARNING "mt2131 I2C read failed\n");
63f47623a04dab402fb2c18fe516a174bc02005629Steven Toth		return -EREMOTEIO;
64f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	}
65f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	return 0;
66f47623a04dab402fb2c18fe516a174bc02005629Steven Toth}
67f47623a04dab402fb2c18fe516a174bc02005629Steven Toth
68f47623a04dab402fb2c18fe516a174bc02005629Steven Tothstatic int mt2131_writereg(struct mt2131_priv *priv, u8 reg, u8 val)
69f47623a04dab402fb2c18fe516a174bc02005629Steven Toth{
70f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	u8 buf[2] = { reg, val };
713873dd041465799cfdeb642531c0ade4fb6614e5Michael Krufky	struct i2c_msg msg = { .addr = priv->cfg->i2c_address, .flags = 0,
723873dd041465799cfdeb642531c0ade4fb6614e5Michael Krufky			       .buf = buf, .len = 2 };
73f47623a04dab402fb2c18fe516a174bc02005629Steven Toth
74f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
75f47623a04dab402fb2c18fe516a174bc02005629Steven Toth		printk(KERN_WARNING "mt2131 I2C write failed\n");
76f47623a04dab402fb2c18fe516a174bc02005629Steven Toth		return -EREMOTEIO;
77f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	}
78f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	return 0;
79f47623a04dab402fb2c18fe516a174bc02005629Steven Toth}
80f47623a04dab402fb2c18fe516a174bc02005629Steven Toth
81f47623a04dab402fb2c18fe516a174bc02005629Steven Tothstatic int mt2131_writeregs(struct mt2131_priv *priv,u8 *buf, u8 len)
82f47623a04dab402fb2c18fe516a174bc02005629Steven Toth{
833873dd041465799cfdeb642531c0ade4fb6614e5Michael Krufky	struct i2c_msg msg = { .addr = priv->cfg->i2c_address,
843873dd041465799cfdeb642531c0ade4fb6614e5Michael Krufky			       .flags = 0, .buf = buf, .len = len };
85f47623a04dab402fb2c18fe516a174bc02005629Steven Toth
86f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
873873dd041465799cfdeb642531c0ade4fb6614e5Michael Krufky		printk(KERN_WARNING "mt2131 I2C write failed (len=%i)\n",
883873dd041465799cfdeb642531c0ade4fb6614e5Michael Krufky		       (int)len);
89f47623a04dab402fb2c18fe516a174bc02005629Steven Toth		return -EREMOTEIO;
90f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	}
91f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	return 0;
92f47623a04dab402fb2c18fe516a174bc02005629Steven Toth}
93f47623a04dab402fb2c18fe516a174bc02005629Steven Toth
943873dd041465799cfdeb642531c0ade4fb6614e5Michael Krufkystatic int mt2131_set_params(struct dvb_frontend *fe,
953873dd041465799cfdeb642531c0ade4fb6614e5Michael Krufky			     struct dvb_frontend_parameters *params)
96f47623a04dab402fb2c18fe516a174bc02005629Steven Toth{
97f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	struct mt2131_priv *priv;
98f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	int ret=0, i;
99f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	u32 freq;
100f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	u8  if_band_center;
1013873dd041465799cfdeb642531c0ade4fb6614e5Michael Krufky	u32 f_lo1, f_lo2;
1023873dd041465799cfdeb642531c0ade4fb6614e5Michael Krufky	u32 div1, num1, div2, num2;
103f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	u8  b[8];
104f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	u8 lockval = 0;
105f47623a04dab402fb2c18fe516a174bc02005629Steven Toth
106f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	priv = fe->tuner_priv;
107f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	if (fe->ops.info.type == FE_OFDM)
108f47623a04dab402fb2c18fe516a174bc02005629Steven Toth		priv->bandwidth = params->u.ofdm.bandwidth;
109f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	else
110f47623a04dab402fb2c18fe516a174bc02005629Steven Toth		priv->bandwidth = 0;
111f47623a04dab402fb2c18fe516a174bc02005629Steven Toth
112f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	freq = params->frequency / 1000;  // Hz -> kHz
113271ddbf702c3a4e6b18f6464180eda0f62efd9a5Harvey Harrison	dprintk(1, "%s() freq=%d\n", __func__, freq);
114f47623a04dab402fb2c18fe516a174bc02005629Steven Toth
115f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	f_lo1 = freq + MT2131_IF1 * 1000;
116f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	f_lo1 = (f_lo1 / 250) * 250;
117f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	f_lo2 = f_lo1 - freq - MT2131_IF2;
118f47623a04dab402fb2c18fe516a174bc02005629Steven Toth
119195ccf67738f41eae557ba0322b33b15a39fd88fSteven Toth	priv->frequency =  (f_lo1 - f_lo2 - MT2131_IF2) * 1000;
120f47623a04dab402fb2c18fe516a174bc02005629Steven Toth
121f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	/* Frequency LO1 = 16MHz * (DIV1 + NUM1/8192 ) */
122f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	num1 = f_lo1 * 64 / (MT2131_FREF / 128);
123f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	div1 = num1 / 8192;
124f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	num1 &= 0x1fff;
125f47623a04dab402fb2c18fe516a174bc02005629Steven Toth
126f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	/* Frequency LO2 = 16MHz * (DIV2 + NUM2/8192 ) */
127f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	num2 = f_lo2 * 64 / (MT2131_FREF / 128);
128f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	div2 = num2 / 8192;
129f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	num2 &= 0x1fff;
130f47623a04dab402fb2c18fe516a174bc02005629Steven Toth
131f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	if (freq <=   82500) if_band_center = 0x00; else
132f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	if (freq <=  137500) if_band_center = 0x01; else
133f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	if (freq <=  192500) if_band_center = 0x02; else
134f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	if (freq <=  247500) if_band_center = 0x03; else
135f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	if (freq <=  302500) if_band_center = 0x04; else
136f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	if (freq <=  357500) if_band_center = 0x05; else
137f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	if (freq <=  412500) if_band_center = 0x06; else
138f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	if (freq <=  467500) if_band_center = 0x07; else
139f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	if (freq <=  522500) if_band_center = 0x08; else
140f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	if (freq <=  577500) if_band_center = 0x09; else
141f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	if (freq <=  632500) if_band_center = 0x0A; else
142f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	if (freq <=  687500) if_band_center = 0x0B; else
143f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	if (freq <=  742500) if_band_center = 0x0C; else
144f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	if (freq <=  797500) if_band_center = 0x0D; else
145f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	if (freq <=  852500) if_band_center = 0x0E; else
146f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	if (freq <=  907500) if_band_center = 0x0F; else
147f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	if (freq <=  962500) if_band_center = 0x10; else
148f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	if (freq <= 1017500) if_band_center = 0x11; else
149f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	if (freq <= 1072500) if_band_center = 0x12; else if_band_center = 0x13;
150f47623a04dab402fb2c18fe516a174bc02005629Steven Toth
151f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	b[0] = 1;
152f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	b[1] = (num1 >> 5) & 0xFF;
153f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	b[2] = (num1 & 0x1F);
154f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	b[3] = div1;
155f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	b[4] = (num2 >> 5) & 0xFF;
156f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	b[5] = num2 & 0x1F;
157f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	b[6] = div2;
158f47623a04dab402fb2c18fe516a174bc02005629Steven Toth
159f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	dprintk(1, "IF1: %dMHz IF2: %dMHz\n", MT2131_IF1, MT2131_IF2);
160f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	dprintk(1, "PLL freq=%dkHz  band=%d\n", (int)freq, (int)if_band_center);
161f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	dprintk(1, "PLL f_lo1=%dkHz  f_lo2=%dkHz\n", (int)f_lo1, (int)f_lo2);
162f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	dprintk(1, "PLL div1=%d  num1=%d  div2=%d  num2=%d\n",
163f47623a04dab402fb2c18fe516a174bc02005629Steven Toth		(int)div1, (int)num1, (int)div2, (int)num2);
164f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	dprintk(1, "PLL [1..6]: %2x %2x %2x %2x %2x %2x\n",
165f47623a04dab402fb2c18fe516a174bc02005629Steven Toth		(int)b[1], (int)b[2], (int)b[3], (int)b[4], (int)b[5],
166f47623a04dab402fb2c18fe516a174bc02005629Steven Toth		(int)b[6]);
167f47623a04dab402fb2c18fe516a174bc02005629Steven Toth
168f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	ret = mt2131_writeregs(priv,b,7);
169f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	if (ret < 0)
170f47623a04dab402fb2c18fe516a174bc02005629Steven Toth		return ret;
171f47623a04dab402fb2c18fe516a174bc02005629Steven Toth
172f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	mt2131_writereg(priv, 0x0b, if_band_center);
173f47623a04dab402fb2c18fe516a174bc02005629Steven Toth
174f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	/* Wait for lock */
175f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	i = 0;
176f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	do {
177f47623a04dab402fb2c18fe516a174bc02005629Steven Toth		mt2131_readreg(priv, 0x08, &lockval);
178f47623a04dab402fb2c18fe516a174bc02005629Steven Toth		if ((lockval & 0x88) == 0x88)
179f47623a04dab402fb2c18fe516a174bc02005629Steven Toth			break;
180f47623a04dab402fb2c18fe516a174bc02005629Steven Toth		msleep(4);
181f47623a04dab402fb2c18fe516a174bc02005629Steven Toth		i++;
182f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	} while (i < 10);
183f47623a04dab402fb2c18fe516a174bc02005629Steven Toth
184f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	return ret;
185f47623a04dab402fb2c18fe516a174bc02005629Steven Toth}
186f47623a04dab402fb2c18fe516a174bc02005629Steven Toth
187f47623a04dab402fb2c18fe516a174bc02005629Steven Tothstatic int mt2131_get_frequency(struct dvb_frontend *fe, u32 *frequency)
188f47623a04dab402fb2c18fe516a174bc02005629Steven Toth{
189f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	struct mt2131_priv *priv = fe->tuner_priv;
190271ddbf702c3a4e6b18f6464180eda0f62efd9a5Harvey Harrison	dprintk(1, "%s()\n", __func__);
191f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	*frequency = priv->frequency;
192f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	return 0;
193f47623a04dab402fb2c18fe516a174bc02005629Steven Toth}
194f47623a04dab402fb2c18fe516a174bc02005629Steven Toth
195f47623a04dab402fb2c18fe516a174bc02005629Steven Tothstatic int mt2131_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
196f47623a04dab402fb2c18fe516a174bc02005629Steven Toth{
197f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	struct mt2131_priv *priv = fe->tuner_priv;
198271ddbf702c3a4e6b18f6464180eda0f62efd9a5Harvey Harrison	dprintk(1, "%s()\n", __func__);
199f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	*bandwidth = priv->bandwidth;
200f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	return 0;
201f47623a04dab402fb2c18fe516a174bc02005629Steven Toth}
202f47623a04dab402fb2c18fe516a174bc02005629Steven Toth
203f47623a04dab402fb2c18fe516a174bc02005629Steven Tothstatic int mt2131_get_status(struct dvb_frontend *fe, u32 *status)
204f47623a04dab402fb2c18fe516a174bc02005629Steven Toth{
205f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	struct mt2131_priv *priv = fe->tuner_priv;
206f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	u8 lock_status = 0;
207f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	u8 afc_status = 0;
208f47623a04dab402fb2c18fe516a174bc02005629Steven Toth
209f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	*status = 0;
210f47623a04dab402fb2c18fe516a174bc02005629Steven Toth
211f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	mt2131_readreg(priv, 0x08, &lock_status);
212f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	if ((lock_status & 0x88) == 0x88)
213f47623a04dab402fb2c18fe516a174bc02005629Steven Toth		*status = TUNER_STATUS_LOCKED;
214f47623a04dab402fb2c18fe516a174bc02005629Steven Toth
215f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	mt2131_readreg(priv, 0x09, &afc_status);
216f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	dprintk(1, "%s() - LO Status = 0x%x, AFC Status = 0x%x\n",
217271ddbf702c3a4e6b18f6464180eda0f62efd9a5Harvey Harrison		__func__, lock_status, afc_status);
218f47623a04dab402fb2c18fe516a174bc02005629Steven Toth
219f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	return 0;
220f47623a04dab402fb2c18fe516a174bc02005629Steven Toth}
221f47623a04dab402fb2c18fe516a174bc02005629Steven Toth
222f47623a04dab402fb2c18fe516a174bc02005629Steven Tothstatic int mt2131_init(struct dvb_frontend *fe)
223f47623a04dab402fb2c18fe516a174bc02005629Steven Toth{
224f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	struct mt2131_priv *priv = fe->tuner_priv;
225f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	int ret;
226271ddbf702c3a4e6b18f6464180eda0f62efd9a5Harvey Harrison	dprintk(1, "%s()\n", __func__);
227f47623a04dab402fb2c18fe516a174bc02005629Steven Toth
2283873dd041465799cfdeb642531c0ade4fb6614e5Michael Krufky	if ((ret = mt2131_writeregs(priv, mt2131_config1,
2293873dd041465799cfdeb642531c0ade4fb6614e5Michael Krufky				    sizeof(mt2131_config1))) < 0)
230f47623a04dab402fb2c18fe516a174bc02005629Steven Toth		return ret;
231f47623a04dab402fb2c18fe516a174bc02005629Steven Toth
232f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	mt2131_writereg(priv, 0x0b, 0x09);
233f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	mt2131_writereg(priv, 0x15, 0x47);
234f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	mt2131_writereg(priv, 0x07, 0xf2);
235f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	mt2131_writereg(priv, 0x0b, 0x01);
236f47623a04dab402fb2c18fe516a174bc02005629Steven Toth
2373873dd041465799cfdeb642531c0ade4fb6614e5Michael Krufky	if ((ret = mt2131_writeregs(priv, mt2131_config2,
2383873dd041465799cfdeb642531c0ade4fb6614e5Michael Krufky				    sizeof(mt2131_config2))) < 0)
239f47623a04dab402fb2c18fe516a174bc02005629Steven Toth		return ret;
240f47623a04dab402fb2c18fe516a174bc02005629Steven Toth
241f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	return ret;
242f47623a04dab402fb2c18fe516a174bc02005629Steven Toth}
243f47623a04dab402fb2c18fe516a174bc02005629Steven Toth
244f47623a04dab402fb2c18fe516a174bc02005629Steven Tothstatic int mt2131_release(struct dvb_frontend *fe)
245f47623a04dab402fb2c18fe516a174bc02005629Steven Toth{
246271ddbf702c3a4e6b18f6464180eda0f62efd9a5Harvey Harrison	dprintk(1, "%s()\n", __func__);
247f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	kfree(fe->tuner_priv);
248f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	fe->tuner_priv = NULL;
249f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	return 0;
250f47623a04dab402fb2c18fe516a174bc02005629Steven Toth}
251f47623a04dab402fb2c18fe516a174bc02005629Steven Toth
252f47623a04dab402fb2c18fe516a174bc02005629Steven Tothstatic const struct dvb_tuner_ops mt2131_tuner_ops = {
253f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	.info = {
254f47623a04dab402fb2c18fe516a174bc02005629Steven Toth		.name           = "Microtune MT2131",
255f47623a04dab402fb2c18fe516a174bc02005629Steven Toth		.frequency_min  =  48000000,
256f47623a04dab402fb2c18fe516a174bc02005629Steven Toth		.frequency_max  = 860000000,
257f47623a04dab402fb2c18fe516a174bc02005629Steven Toth		.frequency_step =     50000,
258f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	},
259f47623a04dab402fb2c18fe516a174bc02005629Steven Toth
260f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	.release       = mt2131_release,
261f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	.init          = mt2131_init,
262f47623a04dab402fb2c18fe516a174bc02005629Steven Toth
263f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	.set_params    = mt2131_set_params,
264f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	.get_frequency = mt2131_get_frequency,
265f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	.get_bandwidth = mt2131_get_bandwidth,
266f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	.get_status    = mt2131_get_status
267f47623a04dab402fb2c18fe516a174bc02005629Steven Toth};
268f47623a04dab402fb2c18fe516a174bc02005629Steven Toth
2693873dd041465799cfdeb642531c0ade4fb6614e5Michael Krufkystruct dvb_frontend * mt2131_attach(struct dvb_frontend *fe,
2703873dd041465799cfdeb642531c0ade4fb6614e5Michael Krufky				    struct i2c_adapter *i2c,
2713873dd041465799cfdeb642531c0ade4fb6614e5Michael Krufky				    struct mt2131_config *cfg, u16 if1)
272f47623a04dab402fb2c18fe516a174bc02005629Steven Toth{
273f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	struct mt2131_priv *priv = NULL;
274f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	u8 id = 0;
275f47623a04dab402fb2c18fe516a174bc02005629Steven Toth
276271ddbf702c3a4e6b18f6464180eda0f62efd9a5Harvey Harrison	dprintk(1, "%s()\n", __func__);
277f47623a04dab402fb2c18fe516a174bc02005629Steven Toth
278f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	priv = kzalloc(sizeof(struct mt2131_priv), GFP_KERNEL);
279f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	if (priv == NULL)
280f47623a04dab402fb2c18fe516a174bc02005629Steven Toth		return NULL;
281f47623a04dab402fb2c18fe516a174bc02005629Steven Toth
282f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	priv->cfg = cfg;
283f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	priv->bandwidth = 6000000; /* 6MHz */
284f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	priv->i2c = i2c;
285f47623a04dab402fb2c18fe516a174bc02005629Steven Toth
286f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	if (mt2131_readreg(priv, 0, &id) != 0) {
287f47623a04dab402fb2c18fe516a174bc02005629Steven Toth		kfree(priv);
288f47623a04dab402fb2c18fe516a174bc02005629Steven Toth		return NULL;
289f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	}
290f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	if ( (id != 0x3E) && (id != 0x3F) ) {
2913873dd041465799cfdeb642531c0ade4fb6614e5Michael Krufky		printk(KERN_ERR "MT2131: Device not found at addr 0x%02x\n",
2923873dd041465799cfdeb642531c0ade4fb6614e5Michael Krufky		       cfg->i2c_address);
293f47623a04dab402fb2c18fe516a174bc02005629Steven Toth		kfree(priv);
294f47623a04dab402fb2c18fe516a174bc02005629Steven Toth		return NULL;
295f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	}
296f47623a04dab402fb2c18fe516a174bc02005629Steven Toth
2973873dd041465799cfdeb642531c0ade4fb6614e5Michael Krufky	printk(KERN_INFO "MT2131: successfully identified at address 0x%02x\n",
2983873dd041465799cfdeb642531c0ade4fb6614e5Michael Krufky	       cfg->i2c_address);
2993873dd041465799cfdeb642531c0ade4fb6614e5Michael Krufky	memcpy(&fe->ops.tuner_ops, &mt2131_tuner_ops,
3003873dd041465799cfdeb642531c0ade4fb6614e5Michael Krufky	       sizeof(struct dvb_tuner_ops));
301f47623a04dab402fb2c18fe516a174bc02005629Steven Toth
302f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	fe->tuner_priv = priv;
303f47623a04dab402fb2c18fe516a174bc02005629Steven Toth	return fe;
304f47623a04dab402fb2c18fe516a174bc02005629Steven Toth}
305f47623a04dab402fb2c18fe516a174bc02005629Steven TothEXPORT_SYMBOL(mt2131_attach);
306f47623a04dab402fb2c18fe516a174bc02005629Steven Toth
307f47623a04dab402fb2c18fe516a174bc02005629Steven TothMODULE_AUTHOR("Steven Toth");
308f47623a04dab402fb2c18fe516a174bc02005629Steven TothMODULE_DESCRIPTION("Microtune MT2131 silicon tuner driver");
309f47623a04dab402fb2c18fe516a174bc02005629Steven TothMODULE_LICENSE("GPL");
3103873dd041465799cfdeb642531c0ade4fb6614e5Michael Krufky
3113873dd041465799cfdeb642531c0ade4fb6614e5Michael Krufky/*
3123873dd041465799cfdeb642531c0ade4fb6614e5Michael Krufky * Local variables:
3133873dd041465799cfdeb642531c0ade4fb6614e5Michael Krufky * c-basic-offset: 8
3143873dd041465799cfdeb642531c0ade4fb6614e5Michael Krufky */
315