]> bbs.cooldavid.org Git - net-next-2.6.git/blame - drivers/media/video/tda8290.c
V4L/DVB (6431): Improve firmware format
[net-next-2.6.git] / drivers / media / video / tda8290.c
CommitLineData
1da177e4 1/*
de48eebc
HH
2
3 i2c tv tuner chip device driver
4 controls the philips tda8290+75 tuner chip combo.
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 GNU General Public License for more details.
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., 675 Mass Ave, Cambridge, MA 02139, USA.
910bb3e3
MK
19
20 This "tda8290" module was split apart from the original "tuner" module.
de48eebc
HH
21*/
22
1da177e4 23#include <linux/i2c.h>
1da177e4 24#include <linux/delay.h>
ffbb807c 25#include <linux/videodev.h>
910bb3e3
MK
26#include "tuner-i2c.h"
27#include "tda8290.h"
28
29static int debug = 0;
30module_param(debug, int, 0644);
31MODULE_PARM_DESC(debug, "enable verbose debug messages");
32
33#define PREFIX "tda8290 "
1da177e4
LT
34
35/* ---------------------------------------------------------------------- */
36
b2083199 37struct tda8290_priv {
db8a6956
MK
38 struct tuner_i2c_props i2c_props;
39
b2083199
MK
40 unsigned char tda8290_easy_mode;
41 unsigned char tda827x_lpsel;
42 unsigned char tda827x_addr;
43 unsigned char tda827x_ver;
44 unsigned int sgIF;
910bb3e3
MK
45
46 u32 frequency;
47
48 unsigned int *lna_cfg;
49 int (*tuner_callback) (void *dev, int command,int arg);
b2083199
MK
50};
51
52/* ---------------------------------------------------------------------- */
53
de48eebc
HH
54struct tda827x_data {
55 u32 lomax;
56 u8 spd;
57 u8 bs;
58 u8 bp;
59 u8 cp;
60 u8 gc3;
61 u8 div1p5;
1da177e4
LT
62};
63
de48eebc
HH
64 /* Note lomax entry is lo / 62500 */
65
66static struct tda827x_data tda827x_analog[] = {
67 { .lomax = 992, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 1}, /* 62 MHz */
68 { .lomax = 1056, .spd = 3, .bs = 3, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 1}, /* 66 MHz */
69 { .lomax = 1216, .spd = 3, .bs = 1, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 0}, /* 76 MHz */
70 { .lomax = 1344, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 0}, /* 84 MHz */
71 { .lomax = 1488, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 93 MHz */
72 { .lomax = 1568, .spd = 3, .bs = 3, .bp = 0, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 98 MHz */
73 { .lomax = 1744, .spd = 3, .bs = 3, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 109 MHz */
74 { .lomax = 1968, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 1}, /* 123 MHz */
75 { .lomax = 2128, .spd = 2, .bs = 3, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 1}, /* 133 MHz */
76 { .lomax = 2416, .spd = 2, .bs = 1, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 151 MHz */
77 { .lomax = 2464, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 154 MHz */
78 { .lomax = 2896, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 0, .div1p5 = 0}, /* 181 MHz */
79 { .lomax = 2960, .spd = 2, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 185 MHz */
80 { .lomax = 3472, .spd = 2, .bs = 3, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 217 MHz */
81 { .lomax = 3904, .spd = 1, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 1}, /* 244 MHz */
82 { .lomax = 4240, .spd = 1, .bs = 3, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 1}, /* 265 MHz */
83 { .lomax = 4832, .spd = 1, .bs = 1, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 302 MHz */
84 { .lomax = 5184, .spd = 1, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 324 MHz */
85 { .lomax = 5920, .spd = 1, .bs = 2, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 370 MHz */
86 { .lomax = 7264, .spd = 1, .bs = 3, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 454 MHz */
87 { .lomax = 7888, .spd = 0, .bs = 2, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 1}, /* 493 MHz */
88 { .lomax = 8480, .spd = 0, .bs = 3, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 1}, /* 530 MHz */
89 { .lomax = 8864, .spd = 0, .bs = 1, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 554 MHz */
90 { .lomax = 9664, .spd = 0, .bs = 1, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0}, /* 604 MHz */
91 { .lomax = 11088, .spd = 0, .bs = 2, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0}, /* 696 MHz */
92 { .lomax = 11840, .spd = 0, .bs = 2, .bp = 4, .cp = 1, .gc3 = 0, .div1p5 = 0}, /* 740 MHz */
93 { .lomax = 13120, .spd = 0, .bs = 3, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0}, /* 820 MHz */
94 { .lomax = 13840, .spd = 0, .bs = 3, .bp = 4, .cp = 1, .gc3 = 0, .div1p5 = 0}, /* 865 MHz */
95 { .lomax = 0, .spd = 0, .bs = 0, .bp = 0, .cp = 0, .gc3 = 0, .div1p5 = 0} /* End */
1da177e4
LT
96};
97
910bb3e3
MK
98static void tda827x_set_analog_params(struct dvb_frontend *fe,
99 struct analog_parameters *params)
de48eebc
HH
100{
101 unsigned char tuner_reg[8];
102 unsigned char reg2[2];
103 u32 N;
104 int i;
910bb3e3 105 struct tda8290_priv *priv = fe->tuner_priv;
b2083199 106 struct i2c_msg msg = {.addr = priv->tda827x_addr, .flags = 0};
910bb3e3 107 unsigned int freq = params->frequency;
1da177e4 108
910bb3e3 109 if (params->mode == V4L2_TUNER_RADIO)
de48eebc
HH
110 freq = freq / 1000;
111
910bb3e3 112 N = freq + priv->sgIF;
de48eebc
HH
113 i = 0;
114 while (tda827x_analog[i].lomax < N) {
115 if(tda827x_analog[i + 1].lomax == 0)
116 break;
117 i++;
118 }
119
120 N = N << tda827x_analog[i].spd;
121
122 tuner_reg[0] = 0;
123 tuner_reg[1] = (unsigned char)(N>>8);
124 tuner_reg[2] = (unsigned char) N;
125 tuner_reg[3] = 0x40;
b2083199 126 tuner_reg[4] = 0x52 + (priv->tda827x_lpsel << 5);
de48eebc 127 tuner_reg[5] = (tda827x_analog[i].spd << 6) + (tda827x_analog[i].div1p5 <<5) +
9a741ec9 128 (tda827x_analog[i].bs <<3) + tda827x_analog[i].bp;
de48eebc
HH
129 tuner_reg[6] = 0x8f + (tda827x_analog[i].gc3 << 4);
130 tuner_reg[7] = 0x8f;
131
132 msg.buf = tuner_reg;
133 msg.len = 8;
db8a6956 134 i2c_transfer(priv->i2c_props.adap, &msg, 1);
de48eebc
HH
135
136 msg.buf= reg2;
137 msg.len = 2;
138 reg2[0] = 0x80;
139 reg2[1] = 0;
db8a6956 140 i2c_transfer(priv->i2c_props.adap, &msg, 1);
de48eebc
HH
141
142 reg2[0] = 0x60;
143 reg2[1] = 0xbf;
db8a6956 144 i2c_transfer(priv->i2c_props.adap, &msg, 1);
de48eebc
HH
145
146 reg2[0] = 0x30;
147 reg2[1] = tuner_reg[4] + 0x80;
db8a6956 148 i2c_transfer(priv->i2c_props.adap, &msg, 1);
de48eebc
HH
149
150 msleep(1);
151 reg2[0] = 0x30;
152 reg2[1] = tuner_reg[4] + 4;
db8a6956 153 i2c_transfer(priv->i2c_props.adap, &msg, 1);
de48eebc
HH
154
155 msleep(1);
156 reg2[0] = 0x30;
157 reg2[1] = tuner_reg[4];
db8a6956 158 i2c_transfer(priv->i2c_props.adap, &msg, 1);
de48eebc
HH
159
160 msleep(550);
161 reg2[0] = 0x30;
162 reg2[1] = (tuner_reg[4] & 0xfc) + tda827x_analog[i].cp ;
db8a6956 163 i2c_transfer(priv->i2c_props.adap, &msg, 1);
1da177e4 164
de48eebc 165 reg2[0] = 0x60;
95736034 166 reg2[1] = 0x3f;
db8a6956 167 i2c_transfer(priv->i2c_props.adap, &msg, 1);
de48eebc
HH
168
169 reg2[0] = 0x80;
170 reg2[1] = 0x08; // Vsync en
db8a6956 171 i2c_transfer(priv->i2c_props.adap, &msg, 1);
de48eebc
HH
172}
173
910bb3e3 174static void tda827x_agcf(struct dvb_frontend *fe)
1da177e4 175{
910bb3e3 176 struct tda8290_priv *priv = fe->tuner_priv;
de48eebc 177 unsigned char data[] = {0x80, 0x0c};
b2083199 178 struct i2c_msg msg = {.addr = priv->tda827x_addr, .buf = data,
de48eebc 179 .flags = 0, .len = 2};
db8a6956 180 i2c_transfer(priv->i2c_props.adap, &msg, 1);
1da177e4
LT
181}
182
183/* ---------------------------------------------------------------------- */
184
de48eebc
HH
185struct tda827xa_data {
186 u32 lomax;
187 u8 svco;
188 u8 spd;
189 u8 scr;
190 u8 sbs;
191 u8 gc3;
1da177e4
LT
192};
193
de48eebc
HH
194static struct tda827xa_data tda827xa_analog[] = {
195 { .lomax = 910, .svco = 3, .spd = 4, .scr = 0, .sbs = 0, .gc3 = 3}, /* 56.875 MHz */
196 { .lomax = 1076, .svco = 0, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 3}, /* 67.25 MHz */
197 { .lomax = 1300, .svco = 1, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 3}, /* 81.25 MHz */
198 { .lomax = 1560, .svco = 2, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 3}, /* 97.5 MHz */
199 { .lomax = 1820, .svco = 3, .spd = 3, .scr = 0, .sbs = 1, .gc3 = 1}, /* 113.75 MHz */
200 { .lomax = 2152, .svco = 0, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1}, /* 134.5 MHz */
201 { .lomax = 2464, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1}, /* 154 MHz */
202 { .lomax = 2600, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1}, /* 162.5 MHz */
203 { .lomax = 2928, .svco = 2, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1}, /* 183 MHz */
204 { .lomax = 3120, .svco = 2, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 1}, /* 195 MHz */
205 { .lomax = 3640, .svco = 3, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 3}, /* 227.5 MHz */
206 { .lomax = 4304, .svco = 0, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 3}, /* 269 MHz */
207 { .lomax = 5200, .svco = 1, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 1}, /* 325 MHz */
208 { .lomax = 6240, .svco = 2, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 3}, /* 390 MHz */
209 { .lomax = 7280, .svco = 3, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 3}, /* 455 MHz */
210 { .lomax = 8320, .svco = 0, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1}, /* 520 MHz */
211 { .lomax = 8608, .svco = 0, .spd = 0, .scr = 1, .sbs = 3, .gc3 = 1}, /* 538 MHz */
212 { .lomax = 8864, .svco = 1, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1}, /* 554 MHz */
213 { .lomax = 9920, .svco = 1, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0}, /* 620 MHz */
214 { .lomax = 10400, .svco = 1, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0}, /* 650 MHz */
215 { .lomax = 11200, .svco = 2, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0}, /* 700 MHz */
216 { .lomax = 12480, .svco = 2, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0}, /* 780 MHz */
217 { .lomax = 13120, .svco = 3, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0}, /* 820 MHz */
218 { .lomax = 13920, .svco = 3, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0}, /* 870 MHz */
219 { .lomax = 14576, .svco = 3, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 0}, /* 911 MHz */
220 { .lomax = 0, .svco = 0, .spd = 0, .scr = 0, .sbs = 0, .gc3 = 0} /* End */
1da177e4
LT
221};
222
910bb3e3
MK
223static void tda827xa_lna_gain(struct dvb_frontend *fe, int high,
224 struct analog_parameters *params)
58ef4f92 225{
910bb3e3 226 struct tda8290_priv *priv = fe->tuner_priv;
58ef4f92
HH
227 unsigned char buf[] = {0x22, 0x01};
228 int arg;
db8a6956 229 struct i2c_msg msg = {.addr = priv->i2c_props.addr, .flags = 0, .buf = buf, .len = sizeof(buf)};
910bb3e3
MK
230
231 if ((priv->lna_cfg == NULL) || (priv->tuner_callback == NULL))
232 return;
233
234 if (*priv->lna_cfg) {
58ef4f92
HH
235 if (high)
236 tuner_dbg("setting LNA to high gain\n");
237 else
238 tuner_dbg("setting LNA to low gain\n");
239 }
910bb3e3 240 switch (*priv->lna_cfg) {
58ef4f92
HH
241 case 0: /* no LNA */
242 break;
243 case 1: /* switch is GPIO 0 of tda8290 */
244 case 2:
245 /* turn Vsync on */
910bb3e3 246 if (params->std & V4L2_STD_MN)
cfeb8839 247 arg = 1;
58ef4f92 248 else
cfeb8839 249 arg = 0;
910bb3e3
MK
250 if (priv->tuner_callback)
251 priv->tuner_callback(priv->i2c_props.adap->algo_data, 1, arg);
58ef4f92 252 buf[1] = high ? 0 : 1;
910bb3e3 253 if (*priv->lna_cfg == 2)
58ef4f92 254 buf[1] = high ? 1 : 0;
db8a6956 255 i2c_transfer(priv->i2c_props.adap, &msg, 1);
58ef4f92
HH
256 break;
257 case 3: /* switch with GPIO of saa713x */
910bb3e3
MK
258 if (priv->tuner_callback)
259 priv->tuner_callback(priv->i2c_props.adap->algo_data, 0, high);
58ef4f92
HH
260 break;
261 }
262}
263
910bb3e3
MK
264static void tda827xa_set_analog_params(struct dvb_frontend *fe,
265 struct analog_parameters *params)
de48eebc 266{
58ef4f92 267 unsigned char tuner_reg[11];
de48eebc
HH
268 u32 N;
269 int i;
910bb3e3 270 struct tda8290_priv *priv = fe->tuner_priv;
b2083199 271 struct i2c_msg msg = {.addr = priv->tda827x_addr, .flags = 0, .buf = tuner_reg};
910bb3e3 272 unsigned int freq = params->frequency;
58ef4f92 273
910bb3e3 274 tda827xa_lna_gain(fe, 1, params);
58ef4f92 275 msleep(10);
1da177e4 276
910bb3e3 277 if (params->mode == V4L2_TUNER_RADIO)
de48eebc 278 freq = freq / 1000;
1da177e4 279
910bb3e3 280 N = freq + priv->sgIF;
de48eebc
HH
281 i = 0;
282 while (tda827xa_analog[i].lomax < N) {
283 if(tda827xa_analog[i + 1].lomax == 0)
284 break;
285 i++;
286 }
287
288 N = N << tda827xa_analog[i].spd;
289
290 tuner_reg[0] = 0;
291 tuner_reg[1] = (unsigned char)(N>>8);
292 tuner_reg[2] = (unsigned char) N;
293 tuner_reg[3] = 0;
294 tuner_reg[4] = 0x16;
295 tuner_reg[5] = (tda827xa_analog[i].spd << 5) + (tda827xa_analog[i].svco << 3) +
9a741ec9 296 tda827xa_analog[i].sbs;
de48eebc 297 tuner_reg[6] = 0x8b + (tda827xa_analog[i].gc3 << 4);
58ef4f92 298 tuner_reg[7] = 0x1c;
de48eebc
HH
299 tuner_reg[8] = 4;
300 tuner_reg[9] = 0x20;
58ef4f92
HH
301 tuner_reg[10] = 0x00;
302 msg.len = 11;
db8a6956 303 i2c_transfer(priv->i2c_props.adap, &msg, 1);
de48eebc 304
58ef4f92
HH
305 tuner_reg[0] = 0x90;
306 tuner_reg[1] = 0xff;
307 tuner_reg[2] = 0xe0;
308 tuner_reg[3] = 0;
b2083199 309 tuner_reg[4] = 0x99 + (priv->tda827x_lpsel << 1);
58ef4f92 310 msg.len = 5;
db8a6956 311 i2c_transfer(priv->i2c_props.adap, &msg, 1);
de48eebc 312
58ef4f92
HH
313 tuner_reg[0] = 0xa0;
314 tuner_reg[1] = 0xc0;
de48eebc 315 msg.len = 2;
db8a6956 316 i2c_transfer(priv->i2c_props.adap, &msg, 1);
de48eebc 317
58ef4f92
HH
318 tuner_reg[0] = 0x30;
319 tuner_reg[1] = 0x10 + tda827xa_analog[i].scr;
db8a6956 320 i2c_transfer(priv->i2c_props.adap, &msg, 1);
de48eebc 321
58ef4f92 322 msg.flags = I2C_M_RD;
db8a6956 323 i2c_transfer(priv->i2c_props.adap, &msg, 1);
58ef4f92
HH
324 msg.flags = 0;
325 tuner_reg[1] >>= 4;
326 tuner_dbg("AGC2 gain is: %d\n", tuner_reg[1]);
327 if (tuner_reg[1] < 1)
910bb3e3 328 tda827xa_lna_gain(fe, 0, params);
58ef4f92
HH
329
330 msleep(100);
331 tuner_reg[0] = 0x60;
332 tuner_reg[1] = 0x3c;
db8a6956 333 i2c_transfer(priv->i2c_props.adap, &msg, 1);
de48eebc 334
58ef4f92
HH
335 msleep(163);
336 tuner_reg[0] = 0x50;
337 tuner_reg[1] = 0x8f + (tda827xa_analog[i].gc3 << 4);
db8a6956 338 i2c_transfer(priv->i2c_props.adap, &msg, 1);
de48eebc 339
58ef4f92
HH
340 tuner_reg[0] = 0x80;
341 tuner_reg[1] = 0x28;
db8a6956 342 i2c_transfer(priv->i2c_props.adap, &msg, 1);
de48eebc 343
58ef4f92
HH
344 tuner_reg[0] = 0xb0;
345 tuner_reg[1] = 0x01;
db8a6956 346 i2c_transfer(priv->i2c_props.adap, &msg, 1);
793cf9e6 347
58ef4f92 348 tuner_reg[0] = 0xc0;
b2083199 349 tuner_reg[1] = 0x19 + (priv->tda827x_lpsel << 1);
db8a6956 350 i2c_transfer(priv->i2c_props.adap, &msg, 1);
de48eebc
HH
351}
352
910bb3e3 353static void tda827xa_agcf(struct dvb_frontend *fe)
1da177e4 354{
910bb3e3 355 struct tda8290_priv *priv = fe->tuner_priv;
de48eebc 356 unsigned char data[] = {0x80, 0x2c};
b2083199 357 struct i2c_msg msg = {.addr = priv->tda827x_addr, .buf = data,
de48eebc 358 .flags = 0, .len = 2};
db8a6956 359 i2c_transfer(priv->i2c_props.adap, &msg, 1);
de48eebc 360}
1da177e4 361
de48eebc 362/*---------------------------------------------------------------------*/
1da177e4 363
910bb3e3 364static void tda8290_i2c_bridge(struct dvb_frontend *fe, int close)
de48eebc 365{
910bb3e3 366 struct tda8290_priv *priv = fe->tuner_priv;
db8a6956 367
de48eebc 368 unsigned char enable[2] = { 0x21, 0xC0 };
0157a9cc 369 unsigned char disable[2] = { 0x21, 0x00 };
de48eebc
HH
370 unsigned char *msg;
371 if(close) {
372 msg = enable;
db8a6956 373 tuner_i2c_xfer_send(&priv->i2c_props, msg, 2);
de48eebc
HH
374 /* let the bridge stabilize */
375 msleep(20);
376 } else {
377 msg = disable;
db8a6956 378 tuner_i2c_xfer_send(&priv->i2c_props, msg, 2);
de48eebc 379 }
1da177e4
LT
380}
381
de48eebc
HH
382/*---------------------------------------------------------------------*/
383
910bb3e3
MK
384static void set_audio(struct dvb_frontend *fe,
385 struct analog_parameters *params)
1da177e4 386{
910bb3e3
MK
387 struct tda8290_priv *priv = fe->tuner_priv;
388 char* mode;
389
390 priv->tda827x_lpsel = 0;
391 if (params->std & V4L2_STD_MN) {
392 priv->sgIF = 92;
393 priv->tda8290_easy_mode = 0x01;
394 priv->tda827x_lpsel = 1;
395 mode = "MN";
396 } else if (params->std & V4L2_STD_B) {
397 priv->sgIF = 108;
398 priv->tda8290_easy_mode = 0x02;
399 mode = "B";
400 } else if (params->std & V4L2_STD_GH) {
401 priv->sgIF = 124;
402 priv->tda8290_easy_mode = 0x04;
403 mode = "GH";
404 } else if (params->std & V4L2_STD_PAL_I) {
405 priv->sgIF = 124;
406 priv->tda8290_easy_mode = 0x08;
407 mode = "I";
408 } else if (params->std & V4L2_STD_DK) {
409 priv->sgIF = 124;
410 priv->tda8290_easy_mode = 0x10;
411 mode = "DK";
412 } else if (params->std & V4L2_STD_SECAM_L) {
413 priv->sgIF = 124;
414 priv->tda8290_easy_mode = 0x20;
415 mode = "L";
416 } else if (params->std & V4L2_STD_SECAM_LC) {
417 priv->sgIF = 20;
418 priv->tda8290_easy_mode = 0x40;
419 mode = "LC";
420 } else {
421 priv->sgIF = 124;
422 priv->tda8290_easy_mode = 0x10;
423 mode = "xx";
424 }
425
426 if (params->mode == V4L2_TUNER_RADIO)
427 priv->sgIF = 88; /* if frequency is 5.5 MHz */
428
429 tuner_dbg("setting tda8290 to system %s\n", mode);
430}
431
432static int tda8290_set_params(struct dvb_frontend *fe,
433 struct analog_parameters *params)
434{
435 struct tda8290_priv *priv = fe->tuner_priv;
de48eebc 436 unsigned char soft_reset[] = { 0x00, 0x00 };
b2083199 437 unsigned char easy_mode[] = { 0x01, priv->tda8290_easy_mode };
de48eebc 438 unsigned char expert_mode[] = { 0x01, 0x80 };
0157a9cc 439 unsigned char agc_out_on[] = { 0x02, 0x00 };
de48eebc
HH
440 unsigned char gainset_off[] = { 0x28, 0x14 };
441 unsigned char if_agc_spd[] = { 0x0f, 0x88 };
442 unsigned char adc_head_6[] = { 0x05, 0x04 };
443 unsigned char adc_head_9[] = { 0x05, 0x02 };
444 unsigned char adc_head_12[] = { 0x05, 0x01 };
445 unsigned char pll_bw_nom[] = { 0x0d, 0x47 };
446 unsigned char pll_bw_low[] = { 0x0d, 0x27 };
447 unsigned char gainset_2[] = { 0x28, 0x64 };
448 unsigned char agc_rst_on[] = { 0x0e, 0x0b };
449 unsigned char agc_rst_off[] = { 0x0e, 0x09 };
450 unsigned char if_agc_set[] = { 0x0f, 0x81 };
451 unsigned char addr_adc_sat = 0x1a;
452 unsigned char addr_agc_stat = 0x1d;
453 unsigned char addr_pll_stat = 0x1b;
454 unsigned char adc_sat, agc_stat,
9a741ec9 455 pll_stat;
58ef4f92 456 int i;
de48eebc 457
910bb3e3
MK
458 set_audio(fe, params);
459
460 if (priv->lna_cfg)
461 tuner_dbg("tda827xa config is 0x%02x\n", *priv->lna_cfg);
db8a6956
MK
462 tuner_i2c_xfer_send(&priv->i2c_props, easy_mode, 2);
463 tuner_i2c_xfer_send(&priv->i2c_props, agc_out_on, 2);
464 tuner_i2c_xfer_send(&priv->i2c_props, soft_reset, 2);
de48eebc
HH
465 msleep(1);
466
b2083199 467 expert_mode[1] = priv->tda8290_easy_mode + 0x80;
db8a6956
MK
468 tuner_i2c_xfer_send(&priv->i2c_props, expert_mode, 2);
469 tuner_i2c_xfer_send(&priv->i2c_props, gainset_off, 2);
470 tuner_i2c_xfer_send(&priv->i2c_props, if_agc_spd, 2);
b2083199 471 if (priv->tda8290_easy_mode & 0x60)
db8a6956 472 tuner_i2c_xfer_send(&priv->i2c_props, adc_head_9, 2);
de48eebc 473 else
db8a6956
MK
474 tuner_i2c_xfer_send(&priv->i2c_props, adc_head_6, 2);
475 tuner_i2c_xfer_send(&priv->i2c_props, pll_bw_nom, 2);
de48eebc 476
910bb3e3 477 tda8290_i2c_bridge(fe, 1);
b2083199 478 if (priv->tda827x_ver != 0)
910bb3e3 479 tda827xa_set_analog_params(fe, params);
de48eebc 480 else
910bb3e3 481 tda827x_set_analog_params(fe, params);
58ef4f92 482 for (i = 0; i < 3; i++) {
db8a6956
MK
483 tuner_i2c_xfer_send(&priv->i2c_props, &addr_pll_stat, 1);
484 tuner_i2c_xfer_recv(&priv->i2c_props, &pll_stat, 1);
58ef4f92 485 if (pll_stat & 0x80) {
db8a6956
MK
486 tuner_i2c_xfer_send(&priv->i2c_props, &addr_adc_sat, 1);
487 tuner_i2c_xfer_recv(&priv->i2c_props, &adc_sat, 1);
488 tuner_i2c_xfer_send(&priv->i2c_props, &addr_agc_stat, 1);
489 tuner_i2c_xfer_recv(&priv->i2c_props, &agc_stat, 1);
58ef4f92
HH
490 tuner_dbg("tda8290 is locked, AGC: %d\n", agc_stat);
491 break;
492 } else {
493 tuner_dbg("tda8290 not locked, no signal?\n");
494 msleep(100);
495 }
496 }
de48eebc 497 /* adjust headroom resp. gain */
4ac95af9
HH
498 if ((agc_stat > 115) || (!(pll_stat & 0x80) && (adc_sat < 20))) {
499 tuner_dbg("adjust gain, step 1. Agc: %d, ADC stat: %d, lock: %d\n",
500 agc_stat, adc_sat, pll_stat & 0x80);
db8a6956 501 tuner_i2c_xfer_send(&priv->i2c_props, gainset_2, 2);
de48eebc 502 msleep(100);
db8a6956
MK
503 tuner_i2c_xfer_send(&priv->i2c_props, &addr_agc_stat, 1);
504 tuner_i2c_xfer_recv(&priv->i2c_props, &agc_stat, 1);
505 tuner_i2c_xfer_send(&priv->i2c_props, &addr_pll_stat, 1);
506 tuner_i2c_xfer_recv(&priv->i2c_props, &pll_stat, 1);
de48eebc 507 if ((agc_stat > 115) || !(pll_stat & 0x80)) {
4ac95af9
HH
508 tuner_dbg("adjust gain, step 2. Agc: %d, lock: %d\n",
509 agc_stat, pll_stat & 0x80);
b2083199 510 if (priv->tda827x_ver != 0)
910bb3e3 511 tda827xa_agcf(fe);
de48eebc 512 else
910bb3e3 513 tda827x_agcf(fe);
de48eebc 514 msleep(100);
db8a6956
MK
515 tuner_i2c_xfer_send(&priv->i2c_props, &addr_agc_stat, 1);
516 tuner_i2c_xfer_recv(&priv->i2c_props, &agc_stat, 1);
517 tuner_i2c_xfer_send(&priv->i2c_props, &addr_pll_stat, 1);
518 tuner_i2c_xfer_recv(&priv->i2c_props, &pll_stat, 1);
de48eebc
HH
519 if((agc_stat > 115) || !(pll_stat & 0x80)) {
520 tuner_dbg("adjust gain, step 3. Agc: %d\n", agc_stat);
db8a6956
MK
521 tuner_i2c_xfer_send(&priv->i2c_props, adc_head_12, 2);
522 tuner_i2c_xfer_send(&priv->i2c_props, pll_bw_low, 2);
de48eebc
HH
523 msleep(100);
524 }
525 }
526 }
1da177e4 527
de48eebc 528 /* l/ l' deadlock? */
b2083199 529 if(priv->tda8290_easy_mode & 0x60) {
db8a6956
MK
530 tuner_i2c_xfer_send(&priv->i2c_props, &addr_adc_sat, 1);
531 tuner_i2c_xfer_recv(&priv->i2c_props, &adc_sat, 1);
532 tuner_i2c_xfer_send(&priv->i2c_props, &addr_pll_stat, 1);
533 tuner_i2c_xfer_recv(&priv->i2c_props, &pll_stat, 1);
de48eebc 534 if ((adc_sat > 20) || !(pll_stat & 0x80)) {
4ac95af9 535 tuner_dbg("trying to resolve SECAM L deadlock\n");
db8a6956 536 tuner_i2c_xfer_send(&priv->i2c_props, agc_rst_on, 2);
de48eebc 537 msleep(40);
db8a6956 538 tuner_i2c_xfer_send(&priv->i2c_props, agc_rst_off, 2);
de48eebc
HH
539 }
540 }
586b0cab 541
910bb3e3 542 tda8290_i2c_bridge(fe, 0);
db8a6956 543 tuner_i2c_xfer_send(&priv->i2c_props, if_agc_set, 2);
910bb3e3
MK
544
545 priv->frequency = (V4L2_TUNER_RADIO == params->mode) ?
546 params->frequency * 125 / 2 : params->frequency * 62500;
547
de48eebc 548 return 0;
1da177e4
LT
549}
550
de48eebc
HH
551/*---------------------------------------------------------------------*/
552
910bb3e3 553static int tda8290_has_signal(struct dvb_frontend *fe)
1da177e4 554{
910bb3e3 555 struct tda8290_priv *priv = fe->tuner_priv;
3782e050 556 int ret;
1da177e4 557
910bb3e3
MK
558 unsigned char i2c_get_afc[1] = { 0x1B };
559 unsigned char afc = 0;
1da177e4 560
3782e050 561 /* for now, report based on afc status */
910bb3e3
MK
562 tuner_i2c_xfer_send(&priv->i2c_props, i2c_get_afc, ARRAY_SIZE(i2c_get_afc));
563 tuner_i2c_xfer_recv(&priv->i2c_props, &afc, 1);
3782e050
MK
564
565 ret = (afc & 0x80) ? 65535 : 0;
566
567 tuner_dbg("AFC status: %d\n", ret);
568
569 return ret;
1da177e4
LT
570}
571
910bb3e3 572static int tda8290_get_status(struct dvb_frontend *fe, u32 *status)
1da177e4 573{
910bb3e3 574 *status = 0;
db8a6956 575
3782e050 576 if (tda8290_has_signal(fe))
910bb3e3 577 *status = TUNER_STATUS_LOCKED;
1da177e4 578
3782e050
MK
579 return 0;
580}
581
582static int tda8290_get_rf_strength(struct dvb_frontend *fe, u16 *strength)
583{
584 *strength = tda8290_has_signal(fe);
910bb3e3
MK
585
586 return 0;
1da177e4
LT
587}
588
de48eebc
HH
589/*---------------------------------------------------------------------*/
590
910bb3e3 591static int tda8290_standby(struct dvb_frontend *fe)
793cf9e6 592{
910bb3e3 593 struct tda8290_priv *priv = fe->tuner_priv;
de48eebc
HH
594 unsigned char cb1[] = { 0x30, 0xD0 };
595 unsigned char tda8290_standby[] = { 0x00, 0x02 };
0157a9cc 596 unsigned char tda8290_agc_tri[] = { 0x02, 0x20 };
b2083199 597 struct i2c_msg msg = {.addr = priv->tda827x_addr, .flags=0, .buf=cb1, .len = 2};
de48eebc 598
910bb3e3 599 tda8290_i2c_bridge(fe, 1);
b2083199 600 if (priv->tda827x_ver != 0)
de48eebc 601 cb1[1] = 0x90;
db8a6956 602 i2c_transfer(priv->i2c_props.adap, &msg, 1);
910bb3e3 603 tda8290_i2c_bridge(fe, 0);
db8a6956
MK
604 tuner_i2c_xfer_send(&priv->i2c_props, tda8290_agc_tri, 2);
605 tuner_i2c_xfer_send(&priv->i2c_props, tda8290_standby, 2);
910bb3e3
MK
606
607 return 0;
793cf9e6
MCC
608}
609
de48eebc 610
910bb3e3 611static void tda8290_init_if(struct dvb_frontend *fe)
de48eebc 612{
910bb3e3 613 struct tda8290_priv *priv = fe->tuner_priv;
db8a6956 614
de48eebc 615 unsigned char set_VS[] = { 0x30, 0x6F };
58ef4f92 616 unsigned char set_GP00_CF[] = { 0x20, 0x01 };
de48eebc
HH
617 unsigned char set_GP01_CF[] = { 0x20, 0x0B };
618
910bb3e3
MK
619 if ((priv->lna_cfg) &&
620 ((*priv->lna_cfg == 1) || (*priv->lna_cfg == 2)))
db8a6956 621 tuner_i2c_xfer_send(&priv->i2c_props, set_GP00_CF, 2);
58ef4f92 622 else
db8a6956
MK
623 tuner_i2c_xfer_send(&priv->i2c_props, set_GP01_CF, 2);
624 tuner_i2c_xfer_send(&priv->i2c_props, set_VS, 2);
de48eebc
HH
625}
626
910bb3e3 627static void tda8290_init_tuner(struct dvb_frontend *fe)
1da177e4 628{
910bb3e3 629 struct tda8290_priv *priv = fe->tuner_priv;
de48eebc 630 unsigned char tda8275_init[] = { 0x00, 0x00, 0x00, 0x40, 0xdC, 0x04, 0xAf,
9a741ec9 631 0x3F, 0x2A, 0x04, 0xFF, 0x00, 0x00, 0x40 };
de48eebc 632 unsigned char tda8275a_init[] = { 0x00, 0x00, 0x00, 0x00, 0xdC, 0x05, 0x8b,
9a741ec9 633 0x0c, 0x04, 0x20, 0xFF, 0x00, 0x00, 0x4b };
b2083199 634 struct i2c_msg msg = {.addr = priv->tda827x_addr, .flags=0,
c2f6f9d8 635 .buf=tda8275_init, .len = 14};
b2083199 636 if (priv->tda827x_ver != 0)
de48eebc
HH
637 msg.buf = tda8275a_init;
638
910bb3e3 639 tda8290_i2c_bridge(fe, 1);
db8a6956 640 i2c_transfer(priv->i2c_props.adap, &msg, 1);
910bb3e3 641 tda8290_i2c_bridge(fe, 0);
de48eebc
HH
642}
643
644/*---------------------------------------------------------------------*/
1da177e4 645
910bb3e3 646static int tda8290_release(struct dvb_frontend *fe)
024cf530 647{
910bb3e3
MK
648 kfree(fe->tuner_priv);
649 fe->tuner_priv = NULL;
650
651 return 0;
024cf530
MK
652}
653
910bb3e3
MK
654static int tda8290_get_frequency(struct dvb_frontend *fe, u32 *frequency)
655{
656 struct tda8290_priv *priv = fe->tuner_priv;
657 *frequency = priv->frequency;
658 return 0;
659}
660
661static struct dvb_tuner_ops tda8290_tuner_ops = {
662 .sleep = tda8290_standby,
663 .set_analog_params = tda8290_set_params,
664 .release = tda8290_release,
665 .get_frequency = tda8290_get_frequency,
666 .get_status = tda8290_get_status,
3782e050 667 .get_rf_strength = tda8290_get_rf_strength,
7fd8b263
MK
668};
669
910bb3e3
MK
670struct dvb_frontend *tda8290_attach(struct dvb_frontend *fe,
671 struct i2c_adapter* i2c_adap,
672 u8 i2c_addr,
673 struct tda8290_config *cfg)
de48eebc 674{
b2083199 675 struct tda8290_priv *priv = NULL;
de48eebc
HH
676 u8 data;
677 int i, ret, tuners_found;
678 u32 tuner_addrs;
679 struct i2c_msg msg = {.flags=I2C_M_RD, .buf=&data, .len = 1};
680
b2083199
MK
681 priv = kzalloc(sizeof(struct tda8290_priv), GFP_KERNEL);
682 if (priv == NULL)
910bb3e3
MK
683 return NULL;
684 fe->tuner_priv = priv;
685
686 priv->i2c_props.addr = i2c_addr;
687 priv->i2c_props.adap = i2c_adap;
688 if (cfg) {
689 priv->lna_cfg = cfg->lna_cfg;
690 priv->tuner_callback = cfg->tuner_callback;
691 }
db8a6956 692
910bb3e3 693 tda8290_i2c_bridge(fe, 1);
de48eebc
HH
694 /* probe for tuner chip */
695 tuners_found = 0;
696 tuner_addrs = 0;
697 for (i=0x60; i<= 0x63; i++) {
698 msg.addr = i;
db8a6956 699 ret = i2c_transfer(priv->i2c_props.adap, &msg, 1);
de48eebc
HH
700 if (ret == 1) {
701 tuners_found++;
702 tuner_addrs = (tuner_addrs << 8) + i;
703 }
704 }
705 /* if there is more than one tuner, we expect the right one is
706 behind the bridge and we choose the highest address that doesn't
707 give a response now
708 */
910bb3e3 709 tda8290_i2c_bridge(fe, 0);
de48eebc
HH
710 if(tuners_found > 1)
711 for (i = 0; i < tuners_found; i++) {
712 msg.addr = tuner_addrs & 0xff;
db8a6956 713 ret = i2c_transfer(priv->i2c_props.adap, &msg, 1);
de48eebc
HH
714 if(ret == 1)
715 tuner_addrs = tuner_addrs >> 8;
716 else
717 break;
718 }
719 if (tuner_addrs == 0) {
720 tuner_addrs = 0x61;
910bb3e3 721 tuner_info("could not clearly identify tuner address, defaulting to %x\n",
01cb9633 722 tuner_addrs);
de48eebc
HH
723 } else {
724 tuner_addrs = tuner_addrs & 0xff;
910bb3e3 725 tuner_info("setting tuner address to %x\n", tuner_addrs);
de48eebc 726 }
b2083199 727 priv->tda827x_addr = tuner_addrs;
de48eebc
HH
728 msg.addr = tuner_addrs;
729
910bb3e3 730 tda8290_i2c_bridge(fe, 1);
db8a6956 731 ret = i2c_transfer(priv->i2c_props.adap, &msg, 1);
de48eebc 732 if( ret != 1)
910bb3e3
MK
733 tuner_warn("TDA827x access failed!\n");
734
735 memcpy(&fe->ops.tuner_ops, &tda8290_tuner_ops,
736 sizeof(struct dvb_tuner_ops));
737
de48eebc 738 if ((data & 0x3c) == 0) {
910bb3e3
MK
739 strlcpy(fe->ops.tuner_ops.info.name, "tda8290+75",
740 sizeof(fe->ops.tuner_ops.info.name));
741 fe->ops.tuner_ops.info.frequency_min = 55000000;
742 fe->ops.tuner_ops.info.frequency_max = 860000000;
743 fe->ops.tuner_ops.info.frequency_step = 250000;
b2083199 744 priv->tda827x_ver = 0;
de48eebc 745 } else {
910bb3e3
MK
746 strlcpy(fe->ops.tuner_ops.info.name, "tda8290+75a",
747 sizeof(fe->ops.tuner_ops.info.name));
748 fe->ops.tuner_ops.info.frequency_min = 44000000;
749 fe->ops.tuner_ops.info.frequency_max = 906000000;
750 fe->ops.tuner_ops.info.frequency_step = 62500;
b2083199 751 priv->tda827x_ver = 2;
de48eebc 752 }
7fd8b263 753
b2083199 754 priv->tda827x_lpsel = 0;
1da177e4 755
910bb3e3
MK
756 tda8290_init_tuner(fe);
757 tda8290_init_if(fe);
758 return fe;
1da177e4
LT
759}
760
910bb3e3 761int tda8290_probe(struct i2c_adapter* i2c_adap, u8 i2c_addr)
95736034 762{
910bb3e3
MK
763 struct tuner_i2c_props i2c_props = {
764 .adap = i2c_adap,
765 .addr = i2c_addr
766 };
db8a6956 767
44fd06fa
HH
768 unsigned char soft_reset[] = { 0x00, 0x00 };
769 unsigned char easy_mode_b[] = { 0x01, 0x02 };
770 unsigned char easy_mode_g[] = { 0x01, 0x04 };
771 unsigned char restore_9886[] = { 0x00, 0xd6, 0x30 };
95736034
HH
772 unsigned char addr_dto_lsb = 0x07;
773 unsigned char data;
774
910bb3e3
MK
775 tuner_i2c_xfer_send(&i2c_props, easy_mode_b, 2);
776 tuner_i2c_xfer_send(&i2c_props, soft_reset, 2);
777 tuner_i2c_xfer_send(&i2c_props, &addr_dto_lsb, 1);
778 tuner_i2c_xfer_recv(&i2c_props, &data, 1);
95736034 779 if (data == 0) {
910bb3e3
MK
780 tuner_i2c_xfer_send(&i2c_props, easy_mode_g, 2);
781 tuner_i2c_xfer_send(&i2c_props, soft_reset, 2);
782 tuner_i2c_xfer_send(&i2c_props, &addr_dto_lsb, 1);
783 tuner_i2c_xfer_recv(&i2c_props, &data, 1);
95736034
HH
784 if (data == 0x7b) {
785 return 0;
786 }
787 }
910bb3e3 788 tuner_i2c_xfer_send(&i2c_props, restore_9886, 3);
95736034
HH
789 return -1;
790}
791
910bb3e3
MK
792EXPORT_SYMBOL_GPL(tda8290_probe);
793EXPORT_SYMBOL_GPL(tda8290_attach);
794
795MODULE_DESCRIPTION("Philips TDA8290 + TDA8275 / TDA8275a tuner driver");
796MODULE_AUTHOR("Gerd Knorr, Hartmut Hackmann");
797MODULE_LICENSE("GPL");
798
1da177e4
LT
799/*
800 * Overrides for Emacs so that we follow Linus's tabbing style.
801 * ---------------------------------------------------------------------------
802 * Local variables:
803 * c-basic-offset: 8
804 * End:
805 */