aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorOlivier DANET <odanet@caramail.com>2007-11-12 08:48:51 -0500
committerMauro Carvalho Chehab <mchehab@infradead.org>2008-01-25 16:02:09 -0500
commit542794be2caf46b5fe95cbb7cd878d884597647e (patch)
tree5f97aad070c81f3debd8c79c9ac13fc8c339e751 /drivers
parent67053a409af94ac3d67e0ef0651c42c8c10f5394 (diff)
V4L/DVB (6590): Adding support for VHF with MT2266-devices
MT2266 : - support for VHF - Minor enhancements Signed-off-by: Olivier DANET <odanet@caramail.com> Signed-off-by: Patrick Boettcher <pb@linuxtv.org> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/dvb/frontends/mt2266.c204
1 files changed, 134 insertions, 70 deletions
diff --git a/drivers/media/dvb/frontends/mt2266.c b/drivers/media/dvb/frontends/mt2266.c
index 03fe8265745f..54b18f94b14b 100644
--- a/drivers/media/dvb/frontends/mt2266.c
+++ b/drivers/media/dvb/frontends/mt2266.c
@@ -38,8 +38,12 @@ struct mt2266_priv {
38 38
39 u32 frequency; 39 u32 frequency;
40 u32 bandwidth; 40 u32 bandwidth;
41 u8 band;
41}; 42};
42 43
44#define MT2266_VHF 1
45#define MT2266_UHF 0
46
43/* Here, frequencies are expressed in kiloHertz to avoid 32 bits overflows */ 47/* Here, frequencies are expressed in kiloHertz to avoid 32 bits overflows */
44 48
45static int debug; 49static int debug;
@@ -90,26 +94,30 @@ static int mt2266_writeregs(struct mt2266_priv *priv,u8 *buf, u8 len)
90} 94}
91 95
92// Initialisation sequences 96// Initialisation sequences
93static u8 mt2266_init1[] = { 97static u8 mt2266_init1[] = { REG_TUNE, 0x00, 0x00, 0x28,
94 REG_TUNE, 98 0x00, 0x52, 0x99, 0x3f };
95 0x00, 0x00, 0x28, 0x00, 0x52, 0x99, 0x3f };
96 99
97static u8 mt2266_init2[] = { 100static u8 mt2266_init2[] = {
98 0x17, 0x6d, 0x71, 0x61, 0xc0, 0xbf, 0xff, 0xdc, 0x00, 0x0a, 101 0x17, 0x6d, 0x71, 0x61, 0xc0, 0xbf, 0xff, 0xdc, 0x00, 0x0a, 0xd4,
99 0xd4, 0x03, 0x64, 0x64, 0x64, 0x64, 0x22, 0xaa, 0xf2, 0x1e, 0x80, 0x14, 0x01, 0x01, 0x01, 0x01, 102 0x03, 0x64, 0x64, 0x64, 0x64, 0x22, 0xaa, 0xf2, 0x1e, 0x80, 0x14,
100 0x01, 0x01, 0x7f, 0x5e, 0x3f, 0xff, 0xff, 0xff, 0x00, 0x77, 0x0f, 0x2d }; 103 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x7f, 0x5e, 0x3f, 0xff, 0xff,
104 0xff, 0x00, 0x77, 0x0f, 0x2d
105};
106
107static u8 mt2266_init_8mhz[] = { REG_BANDWIDTH, 0x22, 0x22, 0x22, 0x22,
108 0x22, 0x22, 0x22, 0x22 };
101 109
102static u8 mt2266_init_8mhz[] = { 110static u8 mt2266_init_7mhz[] = { REG_BANDWIDTH, 0x32, 0x32, 0x32, 0x32,
103 REG_BANDWIDTH, 111 0x32, 0x32, 0x32, 0x32 };
104 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 };
105 112
106static u8 mt2266_init_7mhz[] = { 113static u8 mt2266_init_6mhz[] = { REG_BANDWIDTH, 0xa7, 0xa7, 0xa7, 0xa7,
107 REG_BANDWIDTH, 114 0xa7, 0xa7, 0xa7, 0xa7 };
108 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32 };
109 115
110static u8 mt2266_init_6mhz[] = { 116static u8 mt2266_uhf[] = { 0x1d, 0xdc, 0x00, 0x0a, 0xd4, 0x03, 0x64, 0x64,
111 REG_BANDWIDTH, 117 0x64, 0x64, 0x22, 0xaa, 0xf2, 0x1e, 0x80, 0x14 };
112 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7 }; 118
119static u8 mt2266_vhf[] = { 0x1d, 0xfe, 0x00, 0x00, 0xb4, 0x03, 0xa5, 0xa5,
120 0xa5, 0xa5, 0x82, 0xaa, 0xf1, 0x17, 0x80, 0x1f };
113 121
114#define FREF 30000 // Quartz oscillator 30 MHz 122#define FREF 30000 // Quartz oscillator 30 MHz
115 123
@@ -122,35 +130,78 @@ static int mt2266_set_params(struct dvb_frontend *fe, struct dvb_frontend_parame
122 u8 lnaband; 130 u8 lnaband;
123 u8 b[10]; 131 u8 b[10];
124 int i; 132 int i;
133 u8 band;
125 134
126 priv = fe->tuner_priv; 135 priv = fe->tuner_priv;
127 136
128 mt2266_writereg(priv,0x17,0x6d);
129 mt2266_writereg(priv,0x1c,0xff);
130
131 freq = params->frequency / 1000; // Hz -> kHz 137 freq = params->frequency / 1000; // Hz -> kHz
138 if (freq < 470000 && freq > 230000)
139 return -EINVAL; /* Gap between VHF and UHF bands */
132 priv->bandwidth = (fe->ops.info.type == FE_OFDM) ? params->u.ofdm.bandwidth : 0; 140 priv->bandwidth = (fe->ops.info.type == FE_OFDM) ? params->u.ofdm.bandwidth : 0;
133 priv->frequency = freq * 1000; 141 priv->frequency = freq * 1000;
134 tune=2 * freq * (8192/16) / (FREF/16); 142
135 143 tune = 2 * freq * (8192/16) / (FREF/16);
136 if (freq <= 495000) lnaband = 0xEE; else 144 band = (freq < 300000) ? MT2266_VHF : MT2266_UHF;
137 if (freq <= 525000) lnaband = 0xDD; else 145 if (band == MT2266_VHF)
138 if (freq <= 550000) lnaband = 0xCC; else 146 tune *= 2;
139 if (freq <= 580000) lnaband = 0xBB; else 147
140 if (freq <= 605000) lnaband = 0xAA; else 148 switch (params->u.ofdm.bandwidth) {
141 if (freq <= 630000) lnaband = 0x99; else 149 case BANDWIDTH_6_MHZ:
142 if (freq <= 655000) lnaband = 0x88; else 150 mt2266_writeregs(priv, mt2266_init_6mhz,
143 if (freq <= 685000) lnaband = 0x77; else 151 sizeof(mt2266_init_6mhz));
144 if (freq <= 710000) lnaband = 0x66; else 152 break;
145 if (freq <= 735000) lnaband = 0x55; else 153 case BANDWIDTH_7_MHZ:
146 if (freq <= 765000) lnaband = 0x44; else 154 mt2266_writeregs(priv, mt2266_init_7mhz,
147 if (freq <= 802000) lnaband = 0x33; else 155 sizeof(mt2266_init_7mhz));
148 if (freq <= 840000) lnaband = 0x22; else lnaband = 0x11; 156 break;
149 157 case BANDWIDTH_8_MHZ:
150 msleep(100); 158 default:
151 mt2266_writeregs(priv,(params->u.ofdm.bandwidth==BANDWIDTH_6_MHZ)?mt2266_init_6mhz: 159 mt2266_writeregs(priv, mt2266_init_8mhz,
152 (params->u.ofdm.bandwidth==BANDWIDTH_7_MHZ)?mt2266_init_7mhz: 160 sizeof(mt2266_init_8mhz));
153 mt2266_init_8mhz,sizeof(mt2266_init_8mhz)); 161 break;
162 }
163
164 if (band == MT2266_VHF && priv->band == MT2266_UHF) {
165 dprintk("Switch from UHF to VHF");
166 mt2266_writereg(priv, 0x05, 0x04);
167 mt2266_writereg(priv, 0x19, 0x61);
168 mt2266_writeregs(priv, mt2266_vhf, sizeof(mt2266_vhf));
169 } else if (band == MT2266_UHF && priv->band == MT2266_VHF) {
170 dprintk("Switch from VHF to UHF");
171 mt2266_writereg(priv, 0x05, 0x52);
172 mt2266_writereg(priv, 0x19, 0x61);
173 mt2266_writeregs(priv, mt2266_uhf, sizeof(mt2266_uhf));
174 }
175 msleep(10);
176
177 if (freq <= 495000)
178 lnaband = 0xEE;
179 else if (freq <= 525000)
180 lnaband = 0xDD;
181 else if (freq <= 550000)
182 lnaband = 0xCC;
183 else if (freq <= 580000)
184 lnaband = 0xBB;
185 else if (freq <= 605000)
186 lnaband = 0xAA;
187 else if (freq <= 630000)
188 lnaband = 0x99;
189 else if (freq <= 655000)
190 lnaband = 0x88;
191 else if (freq <= 685000)
192 lnaband = 0x77;
193 else if (freq <= 710000)
194 lnaband = 0x66;
195 else if (freq <= 735000)
196 lnaband = 0x55;
197 else if (freq <= 765000)
198 lnaband = 0x44;
199 else if (freq <= 802000)
200 lnaband = 0x33;
201 else if (freq <= 840000)
202 lnaband = 0x22;
203 else
204 lnaband = 0x11;
154 205
155 b[0] = REG_TUNE; 206 b[0] = REG_TUNE;
156 b[1] = (tune >> 8) & 0x1F; 207 b[1] = (tune >> 8) & 0x1F;
@@ -158,47 +209,54 @@ static int mt2266_set_params(struct dvb_frontend *fe, struct dvb_frontend_parame
158 b[3] = tune >> 13; 209 b[3] = tune >> 13;
159 mt2266_writeregs(priv,b,4); 210 mt2266_writeregs(priv,b,4);
160 211
161 dprintk("set_parms: tune=%d band=%d",(int)tune,(int)lnaband); 212 dprintk("set_parms: tune=%d band=%d %s",
162 dprintk("set_parms: [1..3]: %2x %2x %2x",(int)b[1],(int)b[2],(int)b[3]); 213 (int) tune, (int) lnaband,
163 214 (band == MT2266_UHF) ? "UHF" : "VHF");
164 b[0] = 0x05; 215 dprintk("set_parms: [1..3]: %2x %2x %2x",
165 b[1] = 0x62; 216 (int) b[1], (int) b[2], (int)b[3]);
166 b[2] = lnaband; 217
167 mt2266_writeregs(priv,b,3); 218 if (band == MT2266_UHF) {
219 b[0] = 0x05;
220 b[1] = (priv->band == MT2266_VHF) ? 0x52 : 0x62;
221 b[2] = lnaband;
222 mt2266_writeregs(priv, b, 3);
223 }
168 224
169 //Waits for pll lock or timeout 225 /* Wait for pll lock or timeout */
170 i = 0; 226 i = 0;
171 do { 227 do {
172 mt2266_readreg(priv,REG_LOCK,b); 228 mt2266_readreg(priv,REG_LOCK,b);
173 if ((b[0] & 0x40)==0x40) 229 if (b[0] & 0x40)
174 break; 230 break;
175 msleep(10); 231 msleep(10);
176 i++; 232 i++;
177 } while (i<10); 233 } while (i<10);
178 dprintk("Lock when i=%i",(int)i); 234 dprintk("Lock when i=%i",(int)i);
235
236 if (band == MT2266_UHF && priv->band == MT2266_VHF)
237 mt2266_writereg(priv, 0x05, 0x62);
238
239 priv->band = band;
240
179 return ret; 241 return ret;
180} 242}
181 243
182static void mt2266_calibrate(struct mt2266_priv *priv) 244static void mt2266_calibrate(struct mt2266_priv *priv)
183{ 245{
184 mt2266_writereg(priv,0x11,0x03); 246 mt2266_writereg(priv, 0x11, 0x03);
185 mt2266_writereg(priv,0x11,0x01); 247 mt2266_writereg(priv, 0x11, 0x01);
186 248 mt2266_writeregs(priv, mt2266_init1, sizeof(mt2266_init1));
187 mt2266_writeregs(priv,mt2266_init1,sizeof(mt2266_init1)); 249 mt2266_writeregs(priv, mt2266_init2, sizeof(mt2266_init2));
188 mt2266_writeregs(priv,mt2266_init2,sizeof(mt2266_init2)); 250 mt2266_writereg(priv, 0x33, 0x5e);
189 251 mt2266_writereg(priv, 0x10, 0x10);
190 mt2266_writereg(priv,0x33,0x5e); 252 mt2266_writereg(priv, 0x10, 0x00);
191 mt2266_writereg(priv,0x10,0x10); 253 mt2266_writeregs(priv, mt2266_init_8mhz, sizeof(mt2266_init_8mhz));
192 mt2266_writereg(priv,0x10,0x00);
193
194 mt2266_writeregs(priv,mt2266_init_8mhz,sizeof(mt2266_init_8mhz));
195
196 msleep(25); 254 msleep(25);
197 mt2266_writereg(priv,0x17,0x6d); 255 mt2266_writereg(priv, 0x17, 0x6d);
198 mt2266_writereg(priv,0x1c,0x00); 256 mt2266_writereg(priv, 0x1c, 0x00);
199 msleep(75); 257 msleep(75);
200 mt2266_writereg(priv,0x17,0x6d); 258 mt2266_writereg(priv, 0x17, 0x6d);
201 mt2266_writereg(priv,0x1c,0xff); 259 mt2266_writereg(priv, 0x1c, 0xff);
202} 260}
203 261
204static int mt2266_get_frequency(struct dvb_frontend *fe, u32 *frequency) 262static int mt2266_get_frequency(struct dvb_frontend *fe, u32 *frequency)
@@ -217,17 +275,22 @@ static int mt2266_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
217 275
218static int mt2266_init(struct dvb_frontend *fe) 276static int mt2266_init(struct dvb_frontend *fe)
219{ 277{
278 int ret;
220 struct mt2266_priv *priv = fe->tuner_priv; 279 struct mt2266_priv *priv = fe->tuner_priv;
221 mt2266_writereg(priv,0x17,0x6d); 280 ret = mt2266_writereg(priv, 0x17, 0x6d);
222 mt2266_writereg(priv,0x1c,0xff); 281 if (ret < 0)
282 return ret;
283 ret = mt2266_writereg(priv, 0x1c, 0xff);
284 if (ret < 0)
285 return ret;
223 return 0; 286 return 0;
224} 287}
225 288
226static int mt2266_sleep(struct dvb_frontend *fe) 289static int mt2266_sleep(struct dvb_frontend *fe)
227{ 290{
228 struct mt2266_priv *priv = fe->tuner_priv; 291 struct mt2266_priv *priv = fe->tuner_priv;
229 mt2266_writereg(priv,0x17,0x6d); 292 mt2266_writereg(priv, 0x17, 0x6d);
230 mt2266_writereg(priv,0x1c,0x00); 293 mt2266_writereg(priv, 0x1c, 0x00);
231 return 0; 294 return 0;
232} 295}
233 296
@@ -241,8 +304,8 @@ static int mt2266_release(struct dvb_frontend *fe)
241static const struct dvb_tuner_ops mt2266_tuner_ops = { 304static const struct dvb_tuner_ops mt2266_tuner_ops = {
242 .info = { 305 .info = {
243 .name = "Microtune MT2266", 306 .name = "Microtune MT2266",
244 .frequency_min = 470000000, 307 .frequency_min = 174000000,
245 .frequency_max = 860000000, 308 .frequency_max = 862000000,
246 .frequency_step = 50000, 309 .frequency_step = 50000,
247 }, 310 },
248 .release = mt2266_release, 311 .release = mt2266_release,
@@ -264,8 +327,9 @@ struct dvb_frontend * mt2266_attach(struct dvb_frontend *fe, struct i2c_adapter
264 327
265 priv->cfg = cfg; 328 priv->cfg = cfg;
266 priv->i2c = i2c; 329 priv->i2c = i2c;
330 priv->band = MT2266_UHF;
267 331
268 if (mt2266_readreg(priv,0,&id) != 0) { 332 if (mt2266_readreg(priv, 0, &id)) {
269 kfree(priv); 333 kfree(priv);
270 return NULL; 334 return NULL;
271 } 335 }