0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/module.h>
0009 #include <linux/slab.h>
0010 #include <asm/types.h>
0011 #include <linux/dvb/frontend.h>
0012 #include <linux/videodev2.h>
0013
0014 #include "tda827x.h"
0015
0016 static int debug;
0017 module_param(debug, int, 0644);
0018 MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
0019
0020 #define dprintk(args...) \
0021 do { \
0022 if (debug) printk(KERN_DEBUG "tda827x: " args); \
0023 } while (0)
0024
0025 struct tda827x_priv {
0026 int i2c_addr;
0027 struct i2c_adapter *i2c_adap;
0028 struct tda827x_config *cfg;
0029
0030 unsigned int sgIF;
0031 unsigned char lpsel;
0032
0033 u32 frequency;
0034 u32 bandwidth;
0035 };
0036
0037 static void tda827x_set_std(struct dvb_frontend *fe,
0038 struct analog_parameters *params)
0039 {
0040 struct tda827x_priv *priv = fe->tuner_priv;
0041 char *mode;
0042
0043 priv->lpsel = 0;
0044 if (params->std & V4L2_STD_MN) {
0045 priv->sgIF = 92;
0046 priv->lpsel = 1;
0047 mode = "MN";
0048 } else if (params->std & V4L2_STD_B) {
0049 priv->sgIF = 108;
0050 mode = "B";
0051 } else if (params->std & V4L2_STD_GH) {
0052 priv->sgIF = 124;
0053 mode = "GH";
0054 } else if (params->std & V4L2_STD_PAL_I) {
0055 priv->sgIF = 124;
0056 mode = "I";
0057 } else if (params->std & V4L2_STD_DK) {
0058 priv->sgIF = 124;
0059 mode = "DK";
0060 } else if (params->std & V4L2_STD_SECAM_L) {
0061 priv->sgIF = 124;
0062 mode = "L";
0063 } else if (params->std & V4L2_STD_SECAM_LC) {
0064 priv->sgIF = 20;
0065 mode = "LC";
0066 } else {
0067 priv->sgIF = 124;
0068 mode = "xx";
0069 }
0070
0071 if (params->mode == V4L2_TUNER_RADIO) {
0072 priv->sgIF = 88;
0073 dprintk("setting tda827x to radio FM\n");
0074 } else
0075 dprintk("setting tda827x to system %s\n", mode);
0076 }
0077
0078
0079
0080
0081 struct tda827x_data {
0082 u32 lomax;
0083 u8 spd;
0084 u8 bs;
0085 u8 bp;
0086 u8 cp;
0087 u8 gc3;
0088 u8 div1p5;
0089 };
0090
0091 static const struct tda827x_data tda827x_table[] = {
0092 { .lomax = 62000000, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 1},
0093 { .lomax = 66000000, .spd = 3, .bs = 3, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 1},
0094 { .lomax = 76000000, .spd = 3, .bs = 1, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 0},
0095 { .lomax = 84000000, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 0},
0096 { .lomax = 93000000, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 1, .div1p5 = 0},
0097 { .lomax = 98000000, .spd = 3, .bs = 3, .bp = 0, .cp = 0, .gc3 = 1, .div1p5 = 0},
0098 { .lomax = 109000000, .spd = 3, .bs = 3, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0},
0099 { .lomax = 123000000, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 1},
0100 { .lomax = 133000000, .spd = 2, .bs = 3, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 1},
0101 { .lomax = 151000000, .spd = 2, .bs = 1, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0},
0102 { .lomax = 154000000, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0},
0103 { .lomax = 181000000, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 0, .div1p5 = 0},
0104 { .lomax = 185000000, .spd = 2, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0},
0105 { .lomax = 217000000, .spd = 2, .bs = 3, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0},
0106 { .lomax = 244000000, .spd = 1, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 1},
0107 { .lomax = 265000000, .spd = 1, .bs = 3, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 1},
0108 { .lomax = 302000000, .spd = 1, .bs = 1, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0},
0109 { .lomax = 324000000, .spd = 1, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0},
0110 { .lomax = 370000000, .spd = 1, .bs = 2, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0},
0111 { .lomax = 454000000, .spd = 1, .bs = 3, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0},
0112 { .lomax = 493000000, .spd = 0, .bs = 2, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 1},
0113 { .lomax = 530000000, .spd = 0, .bs = 3, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 1},
0114 { .lomax = 554000000, .spd = 0, .bs = 1, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0},
0115 { .lomax = 604000000, .spd = 0, .bs = 1, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0},
0116 { .lomax = 696000000, .spd = 0, .bs = 2, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0},
0117 { .lomax = 740000000, .spd = 0, .bs = 2, .bp = 4, .cp = 1, .gc3 = 0, .div1p5 = 0},
0118 { .lomax = 820000000, .spd = 0, .bs = 3, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0},
0119 { .lomax = 865000000, .spd = 0, .bs = 3, .bp = 4, .cp = 1, .gc3 = 0, .div1p5 = 0},
0120 { .lomax = 0, .spd = 0, .bs = 0, .bp = 0, .cp = 0, .gc3 = 0, .div1p5 = 0}
0121 };
0122
0123 static int tuner_transfer(struct dvb_frontend *fe,
0124 struct i2c_msg *msg,
0125 const int size)
0126 {
0127 int rc;
0128 struct tda827x_priv *priv = fe->tuner_priv;
0129
0130 if (fe->ops.i2c_gate_ctrl)
0131 fe->ops.i2c_gate_ctrl(fe, 1);
0132 rc = i2c_transfer(priv->i2c_adap, msg, size);
0133 if (fe->ops.i2c_gate_ctrl)
0134 fe->ops.i2c_gate_ctrl(fe, 0);
0135
0136 if (rc >= 0 && rc != size)
0137 return -EIO;
0138
0139 return rc;
0140 }
0141
0142 static int tda827xo_set_params(struct dvb_frontend *fe)
0143 {
0144 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
0145 struct tda827x_priv *priv = fe->tuner_priv;
0146 u8 buf[14];
0147 int rc;
0148
0149 struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
0150 .buf = buf, .len = sizeof(buf) };
0151 int i, tuner_freq, if_freq;
0152 u32 N;
0153
0154 dprintk("%s:\n", __func__);
0155 if (c->bandwidth_hz == 0) {
0156 if_freq = 5000000;
0157 } else if (c->bandwidth_hz <= 6000000) {
0158 if_freq = 4000000;
0159 } else if (c->bandwidth_hz <= 7000000) {
0160 if_freq = 4500000;
0161 } else {
0162 if_freq = 5000000;
0163 }
0164 tuner_freq = c->frequency;
0165
0166 i = 0;
0167 while (tda827x_table[i].lomax < tuner_freq) {
0168 if (tda827x_table[i + 1].lomax == 0)
0169 break;
0170 i++;
0171 }
0172
0173 tuner_freq += if_freq;
0174
0175 N = ((tuner_freq + 125000) / 250000) << (tda827x_table[i].spd + 2);
0176 buf[0] = 0;
0177 buf[1] = (N>>8) | 0x40;
0178 buf[2] = N & 0xff;
0179 buf[3] = 0;
0180 buf[4] = 0x52;
0181 buf[5] = (tda827x_table[i].spd << 6) + (tda827x_table[i].div1p5 << 5) +
0182 (tda827x_table[i].bs << 3) +
0183 tda827x_table[i].bp;
0184 buf[6] = (tda827x_table[i].gc3 << 4) + 0x8f;
0185 buf[7] = 0xbf;
0186 buf[8] = 0x2a;
0187 buf[9] = 0x05;
0188 buf[10] = 0xff;
0189 buf[11] = 0x00;
0190 buf[12] = 0x00;
0191 buf[13] = 0x40;
0192
0193 msg.len = 14;
0194 rc = tuner_transfer(fe, &msg, 1);
0195 if (rc < 0)
0196 goto err;
0197
0198 msleep(500);
0199
0200 buf[0] = 0x30;
0201 buf[1] = 0x50 + tda827x_table[i].cp;
0202 msg.len = 2;
0203
0204 rc = tuner_transfer(fe, &msg, 1);
0205 if (rc < 0)
0206 goto err;
0207
0208 priv->frequency = c->frequency;
0209 priv->bandwidth = c->bandwidth_hz;
0210
0211 return 0;
0212
0213 err:
0214 printk(KERN_ERR "%s: could not write to tuner at addr: 0x%02x\n",
0215 __func__, priv->i2c_addr << 1);
0216 return rc;
0217 }
0218
0219 static int tda827xo_sleep(struct dvb_frontend *fe)
0220 {
0221 struct tda827x_priv *priv = fe->tuner_priv;
0222 static u8 buf[] = { 0x30, 0xd0 };
0223 struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
0224 .buf = buf, .len = sizeof(buf) };
0225
0226 dprintk("%s:\n", __func__);
0227 tuner_transfer(fe, &msg, 1);
0228
0229 if (priv->cfg && priv->cfg->sleep)
0230 priv->cfg->sleep(fe);
0231
0232 return 0;
0233 }
0234
0235
0236
0237 static int tda827xo_set_analog_params(struct dvb_frontend *fe,
0238 struct analog_parameters *params)
0239 {
0240 unsigned char tuner_reg[8];
0241 unsigned char reg2[2];
0242 u32 N;
0243 int i;
0244 struct tda827x_priv *priv = fe->tuner_priv;
0245 struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0 };
0246 unsigned int freq = params->frequency;
0247
0248 tda827x_set_std(fe, params);
0249
0250 if (params->mode == V4L2_TUNER_RADIO)
0251 freq = freq / 1000;
0252
0253 N = freq + priv->sgIF;
0254
0255 i = 0;
0256 while (tda827x_table[i].lomax < N * 62500) {
0257 if (tda827x_table[i + 1].lomax == 0)
0258 break;
0259 i++;
0260 }
0261
0262 N = N << tda827x_table[i].spd;
0263
0264 tuner_reg[0] = 0;
0265 tuner_reg[1] = (unsigned char)(N>>8);
0266 tuner_reg[2] = (unsigned char) N;
0267 tuner_reg[3] = 0x40;
0268 tuner_reg[4] = 0x52 + (priv->lpsel << 5);
0269 tuner_reg[5] = (tda827x_table[i].spd << 6) +
0270 (tda827x_table[i].div1p5 << 5) +
0271 (tda827x_table[i].bs << 3) + tda827x_table[i].bp;
0272 tuner_reg[6] = 0x8f + (tda827x_table[i].gc3 << 4);
0273 tuner_reg[7] = 0x8f;
0274
0275 msg.buf = tuner_reg;
0276 msg.len = 8;
0277 tuner_transfer(fe, &msg, 1);
0278
0279 msg.buf = reg2;
0280 msg.len = 2;
0281 reg2[0] = 0x80;
0282 reg2[1] = 0;
0283 tuner_transfer(fe, &msg, 1);
0284
0285 reg2[0] = 0x60;
0286 reg2[1] = 0xbf;
0287 tuner_transfer(fe, &msg, 1);
0288
0289 reg2[0] = 0x30;
0290 reg2[1] = tuner_reg[4] + 0x80;
0291 tuner_transfer(fe, &msg, 1);
0292
0293 msleep(1);
0294 reg2[0] = 0x30;
0295 reg2[1] = tuner_reg[4] + 4;
0296 tuner_transfer(fe, &msg, 1);
0297
0298 msleep(1);
0299 reg2[0] = 0x30;
0300 reg2[1] = tuner_reg[4];
0301 tuner_transfer(fe, &msg, 1);
0302
0303 msleep(550);
0304 reg2[0] = 0x30;
0305 reg2[1] = (tuner_reg[4] & 0xfc) + tda827x_table[i].cp;
0306 tuner_transfer(fe, &msg, 1);
0307
0308 reg2[0] = 0x60;
0309 reg2[1] = 0x3f;
0310 tuner_transfer(fe, &msg, 1);
0311
0312 reg2[0] = 0x80;
0313 reg2[1] = 0x08;
0314 tuner_transfer(fe, &msg, 1);
0315
0316 priv->frequency = params->frequency;
0317
0318 return 0;
0319 }
0320
0321 static void tda827xo_agcf(struct dvb_frontend *fe)
0322 {
0323 struct tda827x_priv *priv = fe->tuner_priv;
0324 unsigned char data[] = { 0x80, 0x0c };
0325 struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
0326 .buf = data, .len = 2};
0327
0328 tuner_transfer(fe, &msg, 1);
0329 }
0330
0331
0332
0333 struct tda827xa_data {
0334 u32 lomax;
0335 u8 svco;
0336 u8 spd;
0337 u8 scr;
0338 u8 sbs;
0339 u8 gc3;
0340 };
0341
0342 static struct tda827xa_data tda827xa_dvbt[] = {
0343 { .lomax = 56875000, .svco = 3, .spd = 4, .scr = 0, .sbs = 0, .gc3 = 1},
0344 { .lomax = 67250000, .svco = 0, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1},
0345 { .lomax = 81250000, .svco = 1, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1},
0346 { .lomax = 97500000, .svco = 2, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1},
0347 { .lomax = 113750000, .svco = 3, .spd = 3, .scr = 0, .sbs = 1, .gc3 = 1},
0348 { .lomax = 134500000, .svco = 0, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
0349 { .lomax = 154000000, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
0350 { .lomax = 162500000, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
0351 { .lomax = 183000000, .svco = 2, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
0352 { .lomax = 195000000, .svco = 2, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 1},
0353 { .lomax = 227500000, .svco = 3, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 1},
0354 { .lomax = 269000000, .svco = 0, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 1},
0355 { .lomax = 290000000, .svco = 1, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 1},
0356 { .lomax = 325000000, .svco = 1, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 1},
0357 { .lomax = 390000000, .svco = 2, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 1},
0358 { .lomax = 455000000, .svco = 3, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 1},
0359 { .lomax = 520000000, .svco = 0, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1},
0360 { .lomax = 538000000, .svco = 0, .spd = 0, .scr = 1, .sbs = 3, .gc3 = 1},
0361 { .lomax = 550000000, .svco = 1, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1},
0362 { .lomax = 620000000, .svco = 1, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},
0363 { .lomax = 650000000, .svco = 1, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},
0364 { .lomax = 700000000, .svco = 2, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},
0365 { .lomax = 780000000, .svco = 2, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},
0366 { .lomax = 820000000, .svco = 3, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},
0367 { .lomax = 870000000, .svco = 3, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},
0368 { .lomax = 911000000, .svco = 3, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 0},
0369 { .lomax = 0, .svco = 0, .spd = 0, .scr = 0, .sbs = 0, .gc3 = 0}
0370 };
0371
0372 static struct tda827xa_data tda827xa_dvbc[] = {
0373 { .lomax = 50125000, .svco = 2, .spd = 4, .scr = 2, .sbs = 0, .gc3 = 3},
0374 { .lomax = 58500000, .svco = 3, .spd = 4, .scr = 2, .sbs = 0, .gc3 = 3},
0375 { .lomax = 69250000, .svco = 0, .spd = 3, .scr = 2, .sbs = 0, .gc3 = 3},
0376 { .lomax = 83625000, .svco = 1, .spd = 3, .scr = 2, .sbs = 0, .gc3 = 3},
0377 { .lomax = 97500000, .svco = 2, .spd = 3, .scr = 2, .sbs = 0, .gc3 = 3},
0378 { .lomax = 100250000, .svco = 2, .spd = 3, .scr = 2, .sbs = 1, .gc3 = 1},
0379 { .lomax = 117000000, .svco = 3, .spd = 3, .scr = 2, .sbs = 1, .gc3 = 1},
0380 { .lomax = 138500000, .svco = 0, .spd = 2, .scr = 2, .sbs = 1, .gc3 = 1},
0381 { .lomax = 167250000, .svco = 1, .spd = 2, .scr = 2, .sbs = 1, .gc3 = 1},
0382 { .lomax = 187000000, .svco = 2, .spd = 2, .scr = 2, .sbs = 1, .gc3 = 1},
0383 { .lomax = 200500000, .svco = 2, .spd = 2, .scr = 2, .sbs = 2, .gc3 = 1},
0384 { .lomax = 234000000, .svco = 3, .spd = 2, .scr = 2, .sbs = 2, .gc3 = 3},
0385 { .lomax = 277000000, .svco = 0, .spd = 1, .scr = 2, .sbs = 2, .gc3 = 3},
0386 { .lomax = 325000000, .svco = 1, .spd = 1, .scr = 2, .sbs = 2, .gc3 = 1},
0387 { .lomax = 334500000, .svco = 1, .spd = 1, .scr = 2, .sbs = 3, .gc3 = 3},
0388 { .lomax = 401000000, .svco = 2, .spd = 1, .scr = 2, .sbs = 3, .gc3 = 3},
0389 { .lomax = 468000000, .svco = 3, .spd = 1, .scr = 2, .sbs = 3, .gc3 = 1},
0390 { .lomax = 535000000, .svco = 0, .spd = 0, .scr = 1, .sbs = 3, .gc3 = 1},
0391 { .lomax = 554000000, .svco = 0, .spd = 0, .scr = 2, .sbs = 3, .gc3 = 1},
0392 { .lomax = 638000000, .svco = 1, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 1},
0393 { .lomax = 669000000, .svco = 1, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 1},
0394 { .lomax = 720000000, .svco = 2, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 1},
0395 { .lomax = 802000000, .svco = 2, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 1},
0396 { .lomax = 835000000, .svco = 3, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 1},
0397 { .lomax = 885000000, .svco = 3, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 1},
0398 { .lomax = 911000000, .svco = 3, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 1},
0399 { .lomax = 0, .svco = 0, .spd = 0, .scr = 0, .sbs = 0, .gc3 = 0}
0400 };
0401
0402 static struct tda827xa_data tda827xa_analog[] = {
0403 { .lomax = 56875000, .svco = 3, .spd = 4, .scr = 0, .sbs = 0, .gc3 = 3},
0404 { .lomax = 67250000, .svco = 0, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 3},
0405 { .lomax = 81250000, .svco = 1, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 3},
0406 { .lomax = 97500000, .svco = 2, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 3},
0407 { .lomax = 113750000, .svco = 3, .spd = 3, .scr = 0, .sbs = 1, .gc3 = 1},
0408 { .lomax = 134500000, .svco = 0, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
0409 { .lomax = 154000000, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
0410 { .lomax = 162500000, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
0411 { .lomax = 183000000, .svco = 2, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
0412 { .lomax = 195000000, .svco = 2, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 1},
0413 { .lomax = 227500000, .svco = 3, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 3},
0414 { .lomax = 269000000, .svco = 0, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 3},
0415 { .lomax = 325000000, .svco = 1, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 1},
0416 { .lomax = 390000000, .svco = 2, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 3},
0417 { .lomax = 455000000, .svco = 3, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 3},
0418 { .lomax = 520000000, .svco = 0, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1},
0419 { .lomax = 538000000, .svco = 0, .spd = 0, .scr = 1, .sbs = 3, .gc3 = 1},
0420 { .lomax = 554000000, .svco = 1, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1},
0421 { .lomax = 620000000, .svco = 1, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},
0422 { .lomax = 650000000, .svco = 1, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},
0423 { .lomax = 700000000, .svco = 2, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},
0424 { .lomax = 780000000, .svco = 2, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},
0425 { .lomax = 820000000, .svco = 3, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},
0426 { .lomax = 870000000, .svco = 3, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},
0427 { .lomax = 911000000, .svco = 3, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 0},
0428 { .lomax = 0, .svco = 0, .spd = 0, .scr = 0, .sbs = 0, .gc3 = 0}
0429 };
0430
0431 static int tda827xa_sleep(struct dvb_frontend *fe)
0432 {
0433 struct tda827x_priv *priv = fe->tuner_priv;
0434 static u8 buf[] = { 0x30, 0x90 };
0435 struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
0436 .buf = buf, .len = sizeof(buf) };
0437
0438 dprintk("%s:\n", __func__);
0439
0440 tuner_transfer(fe, &msg, 1);
0441
0442 if (priv->cfg && priv->cfg->sleep)
0443 priv->cfg->sleep(fe);
0444
0445 return 0;
0446 }
0447
0448 static void tda827xa_lna_gain(struct dvb_frontend *fe, int high,
0449 struct analog_parameters *params)
0450 {
0451 struct tda827x_priv *priv = fe->tuner_priv;
0452 unsigned char buf[] = {0x22, 0x01};
0453 int arg;
0454 int gp_func;
0455 struct i2c_msg msg = { .flags = 0, .buf = buf, .len = sizeof(buf) };
0456
0457 if (NULL == priv->cfg) {
0458 dprintk("tda827x_config not defined, cannot set LNA gain!\n");
0459 return;
0460 }
0461 msg.addr = priv->cfg->switch_addr;
0462 if (priv->cfg->config) {
0463 if (high)
0464 dprintk("setting LNA to high gain\n");
0465 else
0466 dprintk("setting LNA to low gain\n");
0467 }
0468 switch (priv->cfg->config) {
0469 case TDA8290_LNA_OFF:
0470 break;
0471 case TDA8290_LNA_GP0_HIGH_ON:
0472 case TDA8290_LNA_GP0_HIGH_OFF:
0473 if (params == NULL) {
0474 gp_func = 0;
0475 arg = 0;
0476 } else {
0477
0478 gp_func = 1;
0479 if (params->std & V4L2_STD_MN)
0480 arg = 1;
0481 else
0482 arg = 0;
0483 }
0484 if (fe->callback)
0485 fe->callback(priv->i2c_adap->algo_data,
0486 DVB_FRONTEND_COMPONENT_TUNER,
0487 gp_func, arg);
0488 buf[1] = high ? 0 : 1;
0489 if (priv->cfg->config == TDA8290_LNA_GP0_HIGH_OFF)
0490 buf[1] = high ? 1 : 0;
0491 tuner_transfer(fe, &msg, 1);
0492 break;
0493 case TDA8290_LNA_ON_BRIDGE:
0494 if (fe->callback)
0495 fe->callback(priv->i2c_adap->algo_data,
0496 DVB_FRONTEND_COMPONENT_TUNER, 0, high);
0497 break;
0498 }
0499 }
0500
0501 static int tda827xa_set_params(struct dvb_frontend *fe)
0502 {
0503 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
0504 struct tda827x_priv *priv = fe->tuner_priv;
0505 struct tda827xa_data *frequency_map = tda827xa_dvbt;
0506 u8 buf[11];
0507
0508 struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
0509 .buf = buf, .len = sizeof(buf) };
0510
0511 int i, tuner_freq, if_freq, rc;
0512 u32 N;
0513
0514 dprintk("%s:\n", __func__);
0515
0516 tda827xa_lna_gain(fe, 1, NULL);
0517 msleep(20);
0518
0519 if (c->bandwidth_hz == 0) {
0520 if_freq = 5000000;
0521 } else if (c->bandwidth_hz <= 6000000) {
0522 if_freq = 4000000;
0523 } else if (c->bandwidth_hz <= 7000000) {
0524 if_freq = 4500000;
0525 } else {
0526 if_freq = 5000000;
0527 }
0528 tuner_freq = c->frequency;
0529
0530 switch (c->delivery_system) {
0531 case SYS_DVBC_ANNEX_A:
0532 case SYS_DVBC_ANNEX_C:
0533 dprintk("%s select tda827xa_dvbc\n", __func__);
0534 frequency_map = tda827xa_dvbc;
0535 break;
0536 default:
0537 break;
0538 }
0539
0540 i = 0;
0541 while (frequency_map[i].lomax < tuner_freq) {
0542 if (frequency_map[i + 1].lomax == 0)
0543 break;
0544 i++;
0545 }
0546
0547 tuner_freq += if_freq;
0548
0549 N = ((tuner_freq + 31250) / 62500) << frequency_map[i].spd;
0550 buf[0] = 0;
0551 buf[1] = N >> 8;
0552 buf[2] = N & 0xff;
0553 buf[3] = 0;
0554 buf[4] = 0x16;
0555 buf[5] = (frequency_map[i].spd << 5) + (frequency_map[i].svco << 3) +
0556 frequency_map[i].sbs;
0557 buf[6] = 0x4b + (frequency_map[i].gc3 << 4);
0558 buf[7] = 0x1c;
0559 buf[8] = 0x06;
0560 buf[9] = 0x24;
0561 buf[10] = 0x00;
0562 msg.len = 11;
0563 rc = tuner_transfer(fe, &msg, 1);
0564 if (rc < 0)
0565 goto err;
0566
0567 buf[0] = 0x90;
0568 buf[1] = 0xff;
0569 buf[2] = 0x60;
0570 buf[3] = 0x00;
0571 buf[4] = 0x59;
0572 msg.len = 5;
0573 rc = tuner_transfer(fe, &msg, 1);
0574 if (rc < 0)
0575 goto err;
0576
0577 buf[0] = 0xa0;
0578 buf[1] = 0x40;
0579 msg.len = 2;
0580 rc = tuner_transfer(fe, &msg, 1);
0581 if (rc < 0)
0582 goto err;
0583
0584 msleep(11);
0585 msg.flags = I2C_M_RD;
0586 rc = tuner_transfer(fe, &msg, 1);
0587 if (rc < 0)
0588 goto err;
0589 msg.flags = 0;
0590
0591 buf[1] >>= 4;
0592 dprintk("tda8275a AGC2 gain is: %d\n", buf[1]);
0593 if ((buf[1]) < 2) {
0594 tda827xa_lna_gain(fe, 0, NULL);
0595 buf[0] = 0x60;
0596 buf[1] = 0x0c;
0597 rc = tuner_transfer(fe, &msg, 1);
0598 if (rc < 0)
0599 goto err;
0600 }
0601
0602 buf[0] = 0xc0;
0603 buf[1] = 0x99;
0604 rc = tuner_transfer(fe, &msg, 1);
0605 if (rc < 0)
0606 goto err;
0607
0608 buf[0] = 0x60;
0609 buf[1] = 0x3c;
0610 rc = tuner_transfer(fe, &msg, 1);
0611 if (rc < 0)
0612 goto err;
0613
0614
0615 buf[0] = 0x30;
0616 buf[1] = 0x10 + frequency_map[i].scr;
0617 rc = tuner_transfer(fe, &msg, 1);
0618 if (rc < 0)
0619 goto err;
0620
0621 msleep(163);
0622 buf[0] = 0xc0;
0623 buf[1] = 0x39;
0624 rc = tuner_transfer(fe, &msg, 1);
0625 if (rc < 0)
0626 goto err;
0627
0628 msleep(3);
0629
0630 buf[0] = 0x50;
0631 buf[1] = 0x4f + (frequency_map[i].gc3 << 4);
0632 rc = tuner_transfer(fe, &msg, 1);
0633 if (rc < 0)
0634 goto err;
0635
0636 priv->frequency = c->frequency;
0637 priv->bandwidth = c->bandwidth_hz;
0638
0639 return 0;
0640
0641 err:
0642 printk(KERN_ERR "%s: could not write to tuner at addr: 0x%02x\n",
0643 __func__, priv->i2c_addr << 1);
0644 return rc;
0645 }
0646
0647
0648 static int tda827xa_set_analog_params(struct dvb_frontend *fe,
0649 struct analog_parameters *params)
0650 {
0651 unsigned char tuner_reg[11];
0652 u32 N;
0653 int i;
0654 struct tda827x_priv *priv = fe->tuner_priv;
0655 struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
0656 .buf = tuner_reg, .len = sizeof(tuner_reg) };
0657 unsigned int freq = params->frequency;
0658
0659 tda827x_set_std(fe, params);
0660
0661 tda827xa_lna_gain(fe, 1, params);
0662 msleep(10);
0663
0664 if (params->mode == V4L2_TUNER_RADIO)
0665 freq = freq / 1000;
0666
0667 N = freq + priv->sgIF;
0668
0669 i = 0;
0670 while (tda827xa_analog[i].lomax < N * 62500) {
0671 if (tda827xa_analog[i + 1].lomax == 0)
0672 break;
0673 i++;
0674 }
0675
0676 N = N << tda827xa_analog[i].spd;
0677
0678 tuner_reg[0] = 0;
0679 tuner_reg[1] = (unsigned char)(N>>8);
0680 tuner_reg[2] = (unsigned char) N;
0681 tuner_reg[3] = 0;
0682 tuner_reg[4] = 0x16;
0683 tuner_reg[5] = (tda827xa_analog[i].spd << 5) +
0684 (tda827xa_analog[i].svco << 3) +
0685 tda827xa_analog[i].sbs;
0686 tuner_reg[6] = 0x8b + (tda827xa_analog[i].gc3 << 4);
0687 tuner_reg[7] = 0x1c;
0688 tuner_reg[8] = 4;
0689 tuner_reg[9] = 0x20;
0690 tuner_reg[10] = 0x00;
0691 msg.len = 11;
0692 tuner_transfer(fe, &msg, 1);
0693
0694 tuner_reg[0] = 0x90;
0695 tuner_reg[1] = 0xff;
0696 tuner_reg[2] = 0xe0;
0697 tuner_reg[3] = 0;
0698 tuner_reg[4] = 0x99 + (priv->lpsel << 1);
0699 msg.len = 5;
0700 tuner_transfer(fe, &msg, 1);
0701
0702 tuner_reg[0] = 0xa0;
0703 tuner_reg[1] = 0xc0;
0704 msg.len = 2;
0705 tuner_transfer(fe, &msg, 1);
0706
0707 tuner_reg[0] = 0x30;
0708 tuner_reg[1] = 0x10 + tda827xa_analog[i].scr;
0709 tuner_transfer(fe, &msg, 1);
0710
0711 msg.flags = I2C_M_RD;
0712 tuner_transfer(fe, &msg, 1);
0713 msg.flags = 0;
0714 tuner_reg[1] >>= 4;
0715 dprintk("AGC2 gain is: %d\n", tuner_reg[1]);
0716 if (tuner_reg[1] < 1)
0717 tda827xa_lna_gain(fe, 0, params);
0718
0719 msleep(100);
0720 tuner_reg[0] = 0x60;
0721 tuner_reg[1] = 0x3c;
0722 tuner_transfer(fe, &msg, 1);
0723
0724 msleep(163);
0725 tuner_reg[0] = 0x50;
0726 tuner_reg[1] = 0x8f + (tda827xa_analog[i].gc3 << 4);
0727 tuner_transfer(fe, &msg, 1);
0728
0729 tuner_reg[0] = 0x80;
0730 tuner_reg[1] = 0x28;
0731 tuner_transfer(fe, &msg, 1);
0732
0733 tuner_reg[0] = 0xb0;
0734 tuner_reg[1] = 0x01;
0735 tuner_transfer(fe, &msg, 1);
0736
0737 tuner_reg[0] = 0xc0;
0738 tuner_reg[1] = 0x19 + (priv->lpsel << 1);
0739 tuner_transfer(fe, &msg, 1);
0740
0741 priv->frequency = params->frequency;
0742
0743 return 0;
0744 }
0745
0746 static void tda827xa_agcf(struct dvb_frontend *fe)
0747 {
0748 struct tda827x_priv *priv = fe->tuner_priv;
0749 unsigned char data[] = {0x80, 0x2c};
0750 struct i2c_msg msg = {.addr = priv->i2c_addr, .flags = 0,
0751 .buf = data, .len = 2};
0752 tuner_transfer(fe, &msg, 1);
0753 }
0754
0755
0756
0757 static void tda827x_release(struct dvb_frontend *fe)
0758 {
0759 kfree(fe->tuner_priv);
0760 fe->tuner_priv = NULL;
0761 }
0762
0763 static int tda827x_get_frequency(struct dvb_frontend *fe, u32 *frequency)
0764 {
0765 struct tda827x_priv *priv = fe->tuner_priv;
0766 *frequency = priv->frequency;
0767 return 0;
0768 }
0769
0770 static int tda827x_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
0771 {
0772 struct tda827x_priv *priv = fe->tuner_priv;
0773 *bandwidth = priv->bandwidth;
0774 return 0;
0775 }
0776
0777 static int tda827x_init(struct dvb_frontend *fe)
0778 {
0779 struct tda827x_priv *priv = fe->tuner_priv;
0780 dprintk("%s:\n", __func__);
0781 if (priv->cfg && priv->cfg->init)
0782 priv->cfg->init(fe);
0783
0784 return 0;
0785 }
0786
0787 static int tda827x_probe_version(struct dvb_frontend *fe);
0788
0789 static int tda827x_initial_init(struct dvb_frontend *fe)
0790 {
0791 int ret;
0792 ret = tda827x_probe_version(fe);
0793 if (ret)
0794 return ret;
0795 return fe->ops.tuner_ops.init(fe);
0796 }
0797
0798 static int tda827x_initial_sleep(struct dvb_frontend *fe)
0799 {
0800 int ret;
0801 ret = tda827x_probe_version(fe);
0802 if (ret)
0803 return ret;
0804 return fe->ops.tuner_ops.sleep(fe);
0805 }
0806
0807 static const struct dvb_tuner_ops tda827xo_tuner_ops = {
0808 .info = {
0809 .name = "Philips TDA827X",
0810 .frequency_min_hz = 55 * MHz,
0811 .frequency_max_hz = 860 * MHz,
0812 .frequency_step_hz = 250 * kHz
0813 },
0814 .release = tda827x_release,
0815 .init = tda827x_initial_init,
0816 .sleep = tda827x_initial_sleep,
0817 .set_params = tda827xo_set_params,
0818 .set_analog_params = tda827xo_set_analog_params,
0819 .get_frequency = tda827x_get_frequency,
0820 .get_bandwidth = tda827x_get_bandwidth,
0821 };
0822
0823 static const struct dvb_tuner_ops tda827xa_tuner_ops = {
0824 .info = {
0825 .name = "Philips TDA827XA",
0826 .frequency_min_hz = 44 * MHz,
0827 .frequency_max_hz = 906 * MHz,
0828 .frequency_step_hz = 62500
0829 },
0830 .release = tda827x_release,
0831 .init = tda827x_init,
0832 .sleep = tda827xa_sleep,
0833 .set_params = tda827xa_set_params,
0834 .set_analog_params = tda827xa_set_analog_params,
0835 .get_frequency = tda827x_get_frequency,
0836 .get_bandwidth = tda827x_get_bandwidth,
0837 };
0838
0839 static int tda827x_probe_version(struct dvb_frontend *fe)
0840 {
0841 u8 data;
0842 int rc;
0843 struct tda827x_priv *priv = fe->tuner_priv;
0844 struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = I2C_M_RD,
0845 .buf = &data, .len = 1 };
0846
0847 rc = tuner_transfer(fe, &msg, 1);
0848
0849 if (rc < 0) {
0850 printk("%s: could not read from tuner at addr: 0x%02x\n",
0851 __func__, msg.addr << 1);
0852 return rc;
0853 }
0854 if ((data & 0x3c) == 0) {
0855 dprintk("tda827x tuner found\n");
0856 fe->ops.tuner_ops.init = tda827x_init;
0857 fe->ops.tuner_ops.sleep = tda827xo_sleep;
0858 if (priv->cfg)
0859 priv->cfg->agcf = tda827xo_agcf;
0860 } else {
0861 dprintk("tda827xa tuner found\n");
0862 memcpy(&fe->ops.tuner_ops, &tda827xa_tuner_ops, sizeof(struct dvb_tuner_ops));
0863 if (priv->cfg)
0864 priv->cfg->agcf = tda827xa_agcf;
0865 }
0866 return 0;
0867 }
0868
0869 struct dvb_frontend *tda827x_attach(struct dvb_frontend *fe, int addr,
0870 struct i2c_adapter *i2c,
0871 struct tda827x_config *cfg)
0872 {
0873 struct tda827x_priv *priv = NULL;
0874
0875 dprintk("%s:\n", __func__);
0876 priv = kzalloc(sizeof(struct tda827x_priv), GFP_KERNEL);
0877 if (priv == NULL)
0878 return NULL;
0879
0880 priv->i2c_addr = addr;
0881 priv->i2c_adap = i2c;
0882 priv->cfg = cfg;
0883 memcpy(&fe->ops.tuner_ops, &tda827xo_tuner_ops, sizeof(struct dvb_tuner_ops));
0884 fe->tuner_priv = priv;
0885
0886 dprintk("type set to %s\n", fe->ops.tuner_ops.info.name);
0887
0888 return fe;
0889 }
0890 EXPORT_SYMBOL_GPL(tda827x_attach);
0891
0892 MODULE_DESCRIPTION("DVB TDA827x driver");
0893 MODULE_AUTHOR("Hartmut Hackmann <hartmut.hackmann@t-online.de>");
0894 MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>");
0895 MODULE_LICENSE("GPL");