1/* 2 * 3 * (c) 2005 Hartmut Hackmann 4 * (c) 2007 Michael Krufky 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. 19 */ 20 21#include <linux/module.h> 22#include <linux/slab.h> 23#include <asm/types.h> 24#include <linux/dvb/frontend.h> 25#include <linux/videodev2.h> 26 27#include "tda827x.h" 28 29static int debug; 30module_param(debug, int, 0644); 31MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); 32 33#define dprintk(args...) \ 34 do { \ 35 if (debug) printk(KERN_DEBUG "tda827x: " args); \ 36 } while (0) 37 38struct tda827x_priv { 39 int i2c_addr; 40 struct i2c_adapter *i2c_adap; 41 struct tda827x_config *cfg; 42 43 unsigned int sgIF; 44 unsigned char lpsel; 45 46 u32 frequency; 47 u32 bandwidth; 48}; 49 50static void tda827x_set_std(struct dvb_frontend *fe, 51 struct analog_parameters *params) 52{ 53 struct tda827x_priv *priv = fe->tuner_priv; 54 char *mode; 55 56 priv->lpsel = 0; 57 if (params->std & V4L2_STD_MN) { 58 priv->sgIF = 92; 59 priv->lpsel = 1; 60 mode = "MN"; 61 } else if (params->std & V4L2_STD_B) { 62 priv->sgIF = 108; 63 mode = "B"; 64 } else if (params->std & V4L2_STD_GH) { 65 priv->sgIF = 124; 66 mode = "GH"; 67 } else if (params->std & V4L2_STD_PAL_I) { 68 priv->sgIF = 124; 69 mode = "I"; 70 } else if (params->std & V4L2_STD_DK) { 71 priv->sgIF = 124; 72 mode = "DK"; 73 } else if (params->std & V4L2_STD_SECAM_L) { 74 priv->sgIF = 124; 75 mode = "L"; 76 } else if (params->std & V4L2_STD_SECAM_LC) { 77 priv->sgIF = 20; 78 mode = "LC"; 79 } else { 80 priv->sgIF = 124; 81 mode = "xx"; 82 } 83 84 if (params->mode == V4L2_TUNER_RADIO) { 85 priv->sgIF = 88; /* if frequency is 5.5 MHz */ 86 dprintk("setting tda827x to radio FM\n"); 87 } else 88 dprintk("setting tda827x to system %s\n", mode); 89} 90 91 92/* ------------------------------------------------------------------ */ 93 94struct tda827x_data { 95 u32 lomax; 96 u8 spd; 97 u8 bs; 98 u8 bp; 99 u8 cp; 100 u8 gc3; 101 u8 div1p5; 102}; 103 104static const struct tda827x_data tda827x_table[] = { 105 { .lomax = 62000000, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 1}, 106 { .lomax = 66000000, .spd = 3, .bs = 3, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 1}, 107 { .lomax = 76000000, .spd = 3, .bs = 1, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 0}, 108 { .lomax = 84000000, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 0}, 109 { .lomax = 93000000, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 1, .div1p5 = 0}, 110 { .lomax = 98000000, .spd = 3, .bs = 3, .bp = 0, .cp = 0, .gc3 = 1, .div1p5 = 0}, 111 { .lomax = 109000000, .spd = 3, .bs = 3, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0}, 112 { .lomax = 123000000, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 1}, 113 { .lomax = 133000000, .spd = 2, .bs = 3, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 1}, 114 { .lomax = 151000000, .spd = 2, .bs = 1, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0}, 115 { .lomax = 154000000, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0}, 116 { .lomax = 181000000, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 0, .div1p5 = 0}, 117 { .lomax = 185000000, .spd = 2, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0}, 118 { .lomax = 217000000, .spd = 2, .bs = 3, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0}, 119 { .lomax = 244000000, .spd = 1, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 1}, 120 { .lomax = 265000000, .spd = 1, .bs = 3, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 1}, 121 { .lomax = 302000000, .spd = 1, .bs = 1, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0}, 122 { .lomax = 324000000, .spd = 1, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0}, 123 { .lomax = 370000000, .spd = 1, .bs = 2, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0}, 124 { .lomax = 454000000, .spd = 1, .bs = 3, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0}, 125 { .lomax = 493000000, .spd = 0, .bs = 2, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 1}, 126 { .lomax = 530000000, .spd = 0, .bs = 3, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 1}, 127 { .lomax = 554000000, .spd = 0, .bs = 1, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0}, 128 { .lomax = 604000000, .spd = 0, .bs = 1, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0}, 129 { .lomax = 696000000, .spd = 0, .bs = 2, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0}, 130 { .lomax = 740000000, .spd = 0, .bs = 2, .bp = 4, .cp = 1, .gc3 = 0, .div1p5 = 0}, 131 { .lomax = 820000000, .spd = 0, .bs = 3, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0}, 132 { .lomax = 865000000, .spd = 0, .bs = 3, .bp = 4, .cp = 1, .gc3 = 0, .div1p5 = 0}, 133 { .lomax = 0, .spd = 0, .bs = 0, .bp = 0, .cp = 0, .gc3 = 0, .div1p5 = 0} 134}; 135 136static int tuner_transfer(struct dvb_frontend *fe, 137 struct i2c_msg *msg, 138 const int size) 139{ 140 int rc; 141 struct tda827x_priv *priv = fe->tuner_priv; 142 143 if (fe->ops.i2c_gate_ctrl) 144 fe->ops.i2c_gate_ctrl(fe, 1); 145 rc = i2c_transfer(priv->i2c_adap, msg, size); 146 if (fe->ops.i2c_gate_ctrl) 147 fe->ops.i2c_gate_ctrl(fe, 0); 148 149 if (rc >= 0 && rc != size) 150 return -EIO; 151 152 return rc; 153} 154 155static int tda827xo_set_params(struct dvb_frontend *fe) 156{ 157 struct dtv_frontend_properties *c = &fe->dtv_property_cache; 158 struct tda827x_priv *priv = fe->tuner_priv; 159 u8 buf[14]; 160 int rc; 161 162 struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0, 163 .buf = buf, .len = sizeof(buf) }; 164 int i, tuner_freq, if_freq; 165 u32 N; 166 167 dprintk("%s:\n", __func__); 168 if (c->bandwidth_hz == 0) { 169 if_freq = 5000000; 170 } else if (c->bandwidth_hz <= 6000000) { 171 if_freq = 4000000; 172 } else if (c->bandwidth_hz <= 7000000) { 173 if_freq = 4500000; 174 } else { /* 8 MHz */ 175 if_freq = 5000000; 176 } 177 tuner_freq = c->frequency; 178 179 i = 0; 180 while (tda827x_table[i].lomax < tuner_freq) { 181 if (tda827x_table[i + 1].lomax == 0) 182 break; 183 i++; 184 } 185 186 tuner_freq += if_freq; 187 188 N = ((tuner_freq + 125000) / 250000) << (tda827x_table[i].spd + 2); 189 buf[0] = 0; 190 buf[1] = (N>>8) | 0x40; 191 buf[2] = N & 0xff; 192 buf[3] = 0; 193 buf[4] = 0x52; 194 buf[5] = (tda827x_table[i].spd << 6) + (tda827x_table[i].div1p5 << 5) + 195 (tda827x_table[i].bs << 3) + 196 tda827x_table[i].bp; 197 buf[6] = (tda827x_table[i].gc3 << 4) + 0x8f; 198 buf[7] = 0xbf; 199 buf[8] = 0x2a; 200 buf[9] = 0x05; 201 buf[10] = 0xff; 202 buf[11] = 0x00; 203 buf[12] = 0x00; 204 buf[13] = 0x40; 205 206 msg.len = 14; 207 rc = tuner_transfer(fe, &msg, 1); 208 if (rc < 0) 209 goto err; 210 211 msleep(500); 212 /* correct CP value */ 213 buf[0] = 0x30; 214 buf[1] = 0x50 + tda827x_table[i].cp; 215 msg.len = 2; 216 217 rc = tuner_transfer(fe, &msg, 1); 218 if (rc < 0) 219 goto err; 220 221 priv->frequency = c->frequency; 222 priv->bandwidth = c->bandwidth_hz; 223 224 return 0; 225 226err: 227 printk(KERN_ERR "%s: could not write to tuner at addr: 0x%02x\n", 228 __func__, priv->i2c_addr << 1); 229 return rc; 230} 231 232static int tda827xo_sleep(struct dvb_frontend *fe) 233{ 234 struct tda827x_priv *priv = fe->tuner_priv; 235 static u8 buf[] = { 0x30, 0xd0 }; 236 struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0, 237 .buf = buf, .len = sizeof(buf) }; 238 239 dprintk("%s:\n", __func__); 240 tuner_transfer(fe, &msg, 1); 241 242 if (priv->cfg && priv->cfg->sleep) 243 priv->cfg->sleep(fe); 244 245 return 0; 246} 247 248/* ------------------------------------------------------------------ */ 249 250static int tda827xo_set_analog_params(struct dvb_frontend *fe, 251 struct analog_parameters *params) 252{ 253 unsigned char tuner_reg[8]; 254 unsigned char reg2[2]; 255 u32 N; 256 int i; 257 struct tda827x_priv *priv = fe->tuner_priv; 258 struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0 }; 259 unsigned int freq = params->frequency; 260 261 tda827x_set_std(fe, params); 262 263 if (params->mode == V4L2_TUNER_RADIO) 264 freq = freq / 1000; 265 266 N = freq + priv->sgIF; 267 268 i = 0; 269 while (tda827x_table[i].lomax < N * 62500) { 270 if (tda827x_table[i + 1].lomax == 0) 271 break; 272 i++; 273 } 274 275 N = N << tda827x_table[i].spd; 276 277 tuner_reg[0] = 0; 278 tuner_reg[1] = (unsigned char)(N>>8); 279 tuner_reg[2] = (unsigned char) N; 280 tuner_reg[3] = 0x40; 281 tuner_reg[4] = 0x52 + (priv->lpsel << 5); 282 tuner_reg[5] = (tda827x_table[i].spd << 6) + 283 (tda827x_table[i].div1p5 << 5) + 284 (tda827x_table[i].bs << 3) + tda827x_table[i].bp; 285 tuner_reg[6] = 0x8f + (tda827x_table[i].gc3 << 4); 286 tuner_reg[7] = 0x8f; 287 288 msg.buf = tuner_reg; 289 msg.len = 8; 290 tuner_transfer(fe, &msg, 1); 291 292 msg.buf = reg2; 293 msg.len = 2; 294 reg2[0] = 0x80; 295 reg2[1] = 0; 296 tuner_transfer(fe, &msg, 1); 297 298 reg2[0] = 0x60; 299 reg2[1] = 0xbf; 300 tuner_transfer(fe, &msg, 1); 301 302 reg2[0] = 0x30; 303 reg2[1] = tuner_reg[4] + 0x80; 304 tuner_transfer(fe, &msg, 1); 305 306 msleep(1); 307 reg2[0] = 0x30; 308 reg2[1] = tuner_reg[4] + 4; 309 tuner_transfer(fe, &msg, 1); 310 311 msleep(1); 312 reg2[0] = 0x30; 313 reg2[1] = tuner_reg[4]; 314 tuner_transfer(fe, &msg, 1); 315 316 msleep(550); 317 reg2[0] = 0x30; 318 reg2[1] = (tuner_reg[4] & 0xfc) + tda827x_table[i].cp; 319 tuner_transfer(fe, &msg, 1); 320 321 reg2[0] = 0x60; 322 reg2[1] = 0x3f; 323 tuner_transfer(fe, &msg, 1); 324 325 reg2[0] = 0x80; 326 reg2[1] = 0x08; /* Vsync en */ 327 tuner_transfer(fe, &msg, 1); 328 329 priv->frequency = params->frequency; 330 331 return 0; 332} 333 334static void tda827xo_agcf(struct dvb_frontend *fe) 335{ 336 struct tda827x_priv *priv = fe->tuner_priv; 337 unsigned char data[] = { 0x80, 0x0c }; 338 struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0, 339 .buf = data, .len = 2}; 340 341 tuner_transfer(fe, &msg, 1); 342} 343 344/* ------------------------------------------------------------------ */ 345 346struct tda827xa_data { 347 u32 lomax; 348 u8 svco; 349 u8 spd; 350 u8 scr; 351 u8 sbs; 352 u8 gc3; 353}; 354 355static struct tda827xa_data tda827xa_dvbt[] = { 356 { .lomax = 56875000, .svco = 3, .spd = 4, .scr = 0, .sbs = 0, .gc3 = 1}, 357 { .lomax = 67250000, .svco = 0, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1}, 358 { .lomax = 81250000, .svco = 1, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1}, 359 { .lomax = 97500000, .svco = 2, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1}, 360 { .lomax = 113750000, .svco = 3, .spd = 3, .scr = 0, .sbs = 1, .gc3 = 1}, 361 { .lomax = 134500000, .svco = 0, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1}, 362 { .lomax = 154000000, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1}, 363 { .lomax = 162500000, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1}, 364 { .lomax = 183000000, .svco = 2, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1}, 365 { .lomax = 195000000, .svco = 2, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 1}, 366 { .lomax = 227500000, .svco = 3, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 1}, 367 { .lomax = 269000000, .svco = 0, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 1}, 368 { .lomax = 290000000, .svco = 1, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 1}, 369 { .lomax = 325000000, .svco = 1, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 1}, 370 { .lomax = 390000000, .svco = 2, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 1}, 371 { .lomax = 455000000, .svco = 3, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 1}, 372 { .lomax = 520000000, .svco = 0, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1}, 373 { .lomax = 538000000, .svco = 0, .spd = 0, .scr = 1, .sbs = 3, .gc3 = 1}, 374 { .lomax = 550000000, .svco = 1, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1}, 375 { .lomax = 620000000, .svco = 1, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0}, 376 { .lomax = 650000000, .svco = 1, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0}, 377 { .lomax = 700000000, .svco = 2, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0}, 378 { .lomax = 780000000, .svco = 2, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0}, 379 { .lomax = 820000000, .svco = 3, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0}, 380 { .lomax = 870000000, .svco = 3, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0}, 381 { .lomax = 911000000, .svco = 3, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 0}, 382 { .lomax = 0, .svco = 0, .spd = 0, .scr = 0, .sbs = 0, .gc3 = 0} 383}; 384 385static struct tda827xa_data tda827xa_dvbc[] = { 386 { .lomax = 50125000, .svco = 2, .spd = 4, .scr = 2, .sbs = 0, .gc3 = 3}, 387 { .lomax = 58500000, .svco = 3, .spd = 4, .scr = 2, .sbs = 0, .gc3 = 3}, 388 { .lomax = 69250000, .svco = 0, .spd = 3, .scr = 2, .sbs = 0, .gc3 = 3}, 389 { .lomax = 83625000, .svco = 1, .spd = 3, .scr = 2, .sbs = 0, .gc3 = 3}, 390 { .lomax = 97500000, .svco = 2, .spd = 3, .scr = 2, .sbs = 0, .gc3 = 3}, 391 { .lomax = 100250000, .svco = 2, .spd = 3, .scr = 2, .sbs = 1, .gc3 = 1}, 392 { .lomax = 117000000, .svco = 3, .spd = 3, .scr = 2, .sbs = 1, .gc3 = 1}, 393 { .lomax = 138500000, .svco = 0, .spd = 2, .scr = 2, .sbs = 1, .gc3 = 1}, 394 { .lomax = 167250000, .svco = 1, .spd = 2, .scr = 2, .sbs = 1, .gc3 = 1}, 395 { .lomax = 187000000, .svco = 2, .spd = 2, .scr = 2, .sbs = 1, .gc3 = 1}, 396 { .lomax = 200500000, .svco = 2, .spd = 2, .scr = 2, .sbs = 2, .gc3 = 1}, 397 { .lomax = 234000000, .svco = 3, .spd = 2, .scr = 2, .sbs = 2, .gc3 = 3}, 398 { .lomax = 277000000, .svco = 0, .spd = 1, .scr = 2, .sbs = 2, .gc3 = 3}, 399 { .lomax = 325000000, .svco = 1, .spd = 1, .scr = 2, .sbs = 2, .gc3 = 1}, 400 { .lomax = 334500000, .svco = 1, .spd = 1, .scr = 2, .sbs = 3, .gc3 = 3}, 401 { .lomax = 401000000, .svco = 2, .spd = 1, .scr = 2, .sbs = 3, .gc3 = 3}, 402 { .lomax = 468000000, .svco = 3, .spd = 1, .scr = 2, .sbs = 3, .gc3 = 1}, 403 { .lomax = 535000000, .svco = 0, .spd = 0, .scr = 1, .sbs = 3, .gc3 = 1}, 404 { .lomax = 554000000, .svco = 0, .spd = 0, .scr = 2, .sbs = 3, .gc3 = 1}, 405 { .lomax = 638000000, .svco = 1, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 1}, 406 { .lomax = 669000000, .svco = 1, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 1}, 407 { .lomax = 720000000, .svco = 2, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 1}, 408 { .lomax = 802000000, .svco = 2, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 1}, 409 { .lomax = 835000000, .svco = 3, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 1}, 410 { .lomax = 885000000, .svco = 3, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 1}, 411 { .lomax = 911000000, .svco = 3, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 1}, 412 { .lomax = 0, .svco = 0, .spd = 0, .scr = 0, .sbs = 0, .gc3 = 0} 413}; 414 415static struct tda827xa_data tda827xa_analog[] = { 416 { .lomax = 56875000, .svco = 3, .spd = 4, .scr = 0, .sbs = 0, .gc3 = 3}, 417 { .lomax = 67250000, .svco = 0, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 3}, 418 { .lomax = 81250000, .svco = 1, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 3}, 419 { .lomax = 97500000, .svco = 2, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 3}, 420 { .lomax = 113750000, .svco = 3, .spd = 3, .scr = 0, .sbs = 1, .gc3 = 1}, 421 { .lomax = 134500000, .svco = 0, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1}, 422 { .lomax = 154000000, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1}, 423 { .lomax = 162500000, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1}, 424 { .lomax = 183000000, .svco = 2, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1}, 425 { .lomax = 195000000, .svco = 2, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 1}, 426 { .lomax = 227500000, .svco = 3, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 3}, 427 { .lomax = 269000000, .svco = 0, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 3}, 428 { .lomax = 325000000, .svco = 1, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 1}, 429 { .lomax = 390000000, .svco = 2, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 3}, 430 { .lomax = 455000000, .svco = 3, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 3}, 431 { .lomax = 520000000, .svco = 0, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1}, 432 { .lomax = 538000000, .svco = 0, .spd = 0, .scr = 1, .sbs = 3, .gc3 = 1}, 433 { .lomax = 554000000, .svco = 1, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1}, 434 { .lomax = 620000000, .svco = 1, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0}, 435 { .lomax = 650000000, .svco = 1, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0}, 436 { .lomax = 700000000, .svco = 2, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0}, 437 { .lomax = 780000000, .svco = 2, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0}, 438 { .lomax = 820000000, .svco = 3, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0}, 439 { .lomax = 870000000, .svco = 3, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0}, 440 { .lomax = 911000000, .svco = 3, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 0}, 441 { .lomax = 0, .svco = 0, .spd = 0, .scr = 0, .sbs = 0, .gc3 = 0} 442}; 443 444static int tda827xa_sleep(struct dvb_frontend *fe) 445{ 446 struct tda827x_priv *priv = fe->tuner_priv; 447 static u8 buf[] = { 0x30, 0x90 }; 448 struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0, 449 .buf = buf, .len = sizeof(buf) }; 450 451 dprintk("%s:\n", __func__); 452 453 tuner_transfer(fe, &msg, 1); 454 455 if (priv->cfg && priv->cfg->sleep) 456 priv->cfg->sleep(fe); 457 458 return 0; 459} 460 461static void tda827xa_lna_gain(struct dvb_frontend *fe, int high, 462 struct analog_parameters *params) 463{ 464 struct tda827x_priv *priv = fe->tuner_priv; 465 unsigned char buf[] = {0x22, 0x01}; 466 int arg; 467 int gp_func; 468 struct i2c_msg msg = { .flags = 0, .buf = buf, .len = sizeof(buf) }; 469 470 if (NULL == priv->cfg) { 471 dprintk("tda827x_config not defined, cannot set LNA gain!\n"); 472 return; 473 } 474 msg.addr = priv->cfg->switch_addr; 475 if (priv->cfg->config) { 476 if (high) 477 dprintk("setting LNA to high gain\n"); 478 else 479 dprintk("setting LNA to low gain\n"); 480 } 481 switch (priv->cfg->config) { 482 case TDA8290_LNA_OFF: /* no LNA */ 483 break; 484 case TDA8290_LNA_GP0_HIGH_ON: /* switch is GPIO 0 of tda8290 */ 485 case TDA8290_LNA_GP0_HIGH_OFF: 486 if (params == NULL) { 487 gp_func = 0; 488 arg = 0; 489 } else { 490 /* turn Vsync on */ 491 gp_func = 1; 492 if (params->std & V4L2_STD_MN) 493 arg = 1; 494 else 495 arg = 0; 496 } 497 if (fe->callback) 498 fe->callback(priv->i2c_adap->algo_data, 499 DVB_FRONTEND_COMPONENT_TUNER, 500 gp_func, arg); 501 buf[1] = high ? 0 : 1; 502 if (priv->cfg->config == TDA8290_LNA_GP0_HIGH_OFF) 503 buf[1] = high ? 1 : 0; 504 tuner_transfer(fe, &msg, 1); 505 break; 506 case TDA8290_LNA_ON_BRIDGE: /* switch with GPIO of saa713x */ 507 if (fe->callback) 508 fe->callback(priv->i2c_adap->algo_data, 509 DVB_FRONTEND_COMPONENT_TUNER, 0, high); 510 break; 511 } 512} 513 514static int tda827xa_set_params(struct dvb_frontend *fe) 515{ 516 struct dtv_frontend_properties *c = &fe->dtv_property_cache; 517 struct tda827x_priv *priv = fe->tuner_priv; 518 struct tda827xa_data *frequency_map = tda827xa_dvbt; 519 u8 buf[11]; 520 521 struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0, 522 .buf = buf, .len = sizeof(buf) }; 523 524 int i, tuner_freq, if_freq, rc; 525 u32 N; 526 527 dprintk("%s:\n", __func__); 528 529 tda827xa_lna_gain(fe, 1, NULL); 530 msleep(20); 531 532 if (c->bandwidth_hz == 0) { 533 if_freq = 5000000; 534 } else if (c->bandwidth_hz <= 6000000) { 535 if_freq = 4000000; 536 } else if (c->bandwidth_hz <= 7000000) { 537 if_freq = 4500000; 538 } else { /* 8 MHz */ 539 if_freq = 5000000; 540 } 541 tuner_freq = c->frequency; 542 543 switch (c->delivery_system) { 544 case SYS_DVBC_ANNEX_A: 545 case SYS_DVBC_ANNEX_C: 546 dprintk("%s select tda827xa_dvbc\n", __func__); 547 frequency_map = tda827xa_dvbc; 548 break; 549 default: 550 break; 551 } 552 553 i = 0; 554 while (frequency_map[i].lomax < tuner_freq) { 555 if (frequency_map[i + 1].lomax == 0) 556 break; 557 i++; 558 } 559 560 tuner_freq += if_freq; 561 562 N = ((tuner_freq + 31250) / 62500) << frequency_map[i].spd; 563 buf[0] = 0; // subaddress 564 buf[1] = N >> 8; 565 buf[2] = N & 0xff; 566 buf[3] = 0; 567 buf[4] = 0x16; 568 buf[5] = (frequency_map[i].spd << 5) + (frequency_map[i].svco << 3) + 569 frequency_map[i].sbs; 570 buf[6] = 0x4b + (frequency_map[i].gc3 << 4); 571 buf[7] = 0x1c; 572 buf[8] = 0x06; 573 buf[9] = 0x24; 574 buf[10] = 0x00; 575 msg.len = 11; 576 rc = tuner_transfer(fe, &msg, 1); 577 if (rc < 0) 578 goto err; 579 580 buf[0] = 0x90; 581 buf[1] = 0xff; 582 buf[2] = 0x60; 583 buf[3] = 0x00; 584 buf[4] = 0x59; // lpsel, for 6MHz + 2 585 msg.len = 5; 586 rc = tuner_transfer(fe, &msg, 1); 587 if (rc < 0) 588 goto err; 589 590 buf[0] = 0xa0; 591 buf[1] = 0x40; 592 msg.len = 2; 593 rc = tuner_transfer(fe, &msg, 1); 594 if (rc < 0) 595 goto err; 596 597 msleep(11); 598 msg.flags = I2C_M_RD; 599 rc = tuner_transfer(fe, &msg, 1); 600 if (rc < 0) 601 goto err; 602 msg.flags = 0; 603 604 buf[1] >>= 4; 605 dprintk("tda8275a AGC2 gain is: %d\n", buf[1]); 606 if ((buf[1]) < 2) { 607 tda827xa_lna_gain(fe, 0, NULL); 608 buf[0] = 0x60; 609 buf[1] = 0x0c; 610 rc = tuner_transfer(fe, &msg, 1); 611 if (rc < 0) 612 goto err; 613 } 614 615 buf[0] = 0xc0; 616 buf[1] = 0x99; // lpsel, for 6MHz + 2 617 rc = tuner_transfer(fe, &msg, 1); 618 if (rc < 0) 619 goto err; 620 621 buf[0] = 0x60; 622 buf[1] = 0x3c; 623 rc = tuner_transfer(fe, &msg, 1); 624 if (rc < 0) 625 goto err; 626 627 /* correct CP value */ 628 buf[0] = 0x30; 629 buf[1] = 0x10 + frequency_map[i].scr; 630 rc = tuner_transfer(fe, &msg, 1); 631 if (rc < 0) 632 goto err; 633 634 msleep(163); 635 buf[0] = 0xc0; 636 buf[1] = 0x39; // lpsel, for 6MHz + 2 637 rc = tuner_transfer(fe, &msg, 1); 638 if (rc < 0) 639 goto err; 640 641 msleep(3); 642 /* freeze AGC1 */ 643 buf[0] = 0x50; 644 buf[1] = 0x4f + (frequency_map[i].gc3 << 4); 645 rc = tuner_transfer(fe, &msg, 1); 646 if (rc < 0) 647 goto err; 648 649 priv->frequency = c->frequency; 650 priv->bandwidth = c->bandwidth_hz; 651 652 return 0; 653 654err: 655 printk(KERN_ERR "%s: could not write to tuner at addr: 0x%02x\n", 656 __func__, priv->i2c_addr << 1); 657 return rc; 658} 659 660 661static int tda827xa_set_analog_params(struct dvb_frontend *fe, 662 struct analog_parameters *params) 663{ 664 unsigned char tuner_reg[11]; 665 u32 N; 666 int i; 667 struct tda827x_priv *priv = fe->tuner_priv; 668 struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0, 669 .buf = tuner_reg, .len = sizeof(tuner_reg) }; 670 unsigned int freq = params->frequency; 671 672 tda827x_set_std(fe, params); 673 674 tda827xa_lna_gain(fe, 1, params); 675 msleep(10); 676 677 if (params->mode == V4L2_TUNER_RADIO) 678 freq = freq / 1000; 679 680 N = freq + priv->sgIF; 681 682 i = 0; 683 while (tda827xa_analog[i].lomax < N * 62500) { 684 if (tda827xa_analog[i + 1].lomax == 0) 685 break; 686 i++; 687 } 688 689 N = N << tda827xa_analog[i].spd; 690 691 tuner_reg[0] = 0; 692 tuner_reg[1] = (unsigned char)(N>>8); 693 tuner_reg[2] = (unsigned char) N; 694 tuner_reg[3] = 0; 695 tuner_reg[4] = 0x16; 696 tuner_reg[5] = (tda827xa_analog[i].spd << 5) + 697 (tda827xa_analog[i].svco << 3) + 698 tda827xa_analog[i].sbs; 699 tuner_reg[6] = 0x8b + (tda827xa_analog[i].gc3 << 4); 700 tuner_reg[7] = 0x1c; 701 tuner_reg[8] = 4; 702 tuner_reg[9] = 0x20; 703 tuner_reg[10] = 0x00; 704 msg.len = 11; 705 tuner_transfer(fe, &msg, 1); 706 707 tuner_reg[0] = 0x90; 708 tuner_reg[1] = 0xff; 709 tuner_reg[2] = 0xe0; 710 tuner_reg[3] = 0; 711 tuner_reg[4] = 0x99 + (priv->lpsel << 1); 712 msg.len = 5; 713 tuner_transfer(fe, &msg, 1); 714 715 tuner_reg[0] = 0xa0; 716 tuner_reg[1] = 0xc0; 717 msg.len = 2; 718 tuner_transfer(fe, &msg, 1); 719 720 tuner_reg[0] = 0x30; 721 tuner_reg[1] = 0x10 + tda827xa_analog[i].scr; 722 tuner_transfer(fe, &msg, 1); 723 724 msg.flags = I2C_M_RD; 725 tuner_transfer(fe, &msg, 1); 726 msg.flags = 0; 727 tuner_reg[1] >>= 4; 728 dprintk("AGC2 gain is: %d\n", tuner_reg[1]); 729 if (tuner_reg[1] < 1) 730 tda827xa_lna_gain(fe, 0, params); 731 732 msleep(100); 733 tuner_reg[0] = 0x60; 734 tuner_reg[1] = 0x3c; 735 tuner_transfer(fe, &msg, 1); 736 737 msleep(163); 738 tuner_reg[0] = 0x50; 739 tuner_reg[1] = 0x8f + (tda827xa_analog[i].gc3 << 4); 740 tuner_transfer(fe, &msg, 1); 741 742 tuner_reg[0] = 0x80; 743 tuner_reg[1] = 0x28; 744 tuner_transfer(fe, &msg, 1); 745 746 tuner_reg[0] = 0xb0; 747 tuner_reg[1] = 0x01; 748 tuner_transfer(fe, &msg, 1); 749 750 tuner_reg[0] = 0xc0; 751 tuner_reg[1] = 0x19 + (priv->lpsel << 1); 752 tuner_transfer(fe, &msg, 1); 753 754 priv->frequency = params->frequency; 755 756 return 0; 757} 758 759static void tda827xa_agcf(struct dvb_frontend *fe) 760{ 761 struct tda827x_priv *priv = fe->tuner_priv; 762 unsigned char data[] = {0x80, 0x2c}; 763 struct i2c_msg msg = {.addr = priv->i2c_addr, .flags = 0, 764 .buf = data, .len = 2}; 765 tuner_transfer(fe, &msg, 1); 766} 767 768/* ------------------------------------------------------------------ */ 769 770static int tda827x_release(struct dvb_frontend *fe) 771{ 772 kfree(fe->tuner_priv); 773 fe->tuner_priv = NULL; 774 return 0; 775} 776 777static int tda827x_get_frequency(struct dvb_frontend *fe, u32 *frequency) 778{ 779 struct tda827x_priv *priv = fe->tuner_priv; 780 *frequency = priv->frequency; 781 return 0; 782} 783 784static int tda827x_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth) 785{ 786 struct tda827x_priv *priv = fe->tuner_priv; 787 *bandwidth = priv->bandwidth; 788 return 0; 789} 790 791static int tda827x_init(struct dvb_frontend *fe) 792{ 793 struct tda827x_priv *priv = fe->tuner_priv; 794 dprintk("%s:\n", __func__); 795 if (priv->cfg && priv->cfg->init) 796 priv->cfg->init(fe); 797 798 return 0; 799} 800 801static int tda827x_probe_version(struct dvb_frontend *fe); 802 803static int tda827x_initial_init(struct dvb_frontend *fe) 804{ 805 int ret; 806 ret = tda827x_probe_version(fe); 807 if (ret) 808 return ret; 809 return fe->ops.tuner_ops.init(fe); 810} 811 812static int tda827x_initial_sleep(struct dvb_frontend *fe) 813{ 814 int ret; 815 ret = tda827x_probe_version(fe); 816 if (ret) 817 return ret; 818 return fe->ops.tuner_ops.sleep(fe); 819} 820 821static struct dvb_tuner_ops tda827xo_tuner_ops = { 822 .info = { 823 .name = "Philips TDA827X", 824 .frequency_min = 55000000, 825 .frequency_max = 860000000, 826 .frequency_step = 250000 827 }, 828 .release = tda827x_release, 829 .init = tda827x_initial_init, 830 .sleep = tda827x_initial_sleep, 831 .set_params = tda827xo_set_params, 832 .set_analog_params = tda827xo_set_analog_params, 833 .get_frequency = tda827x_get_frequency, 834 .get_bandwidth = tda827x_get_bandwidth, 835}; 836 837static struct dvb_tuner_ops tda827xa_tuner_ops = { 838 .info = { 839 .name = "Philips TDA827XA", 840 .frequency_min = 44000000, 841 .frequency_max = 906000000, 842 .frequency_step = 62500 843 }, 844 .release = tda827x_release, 845 .init = tda827x_init, 846 .sleep = tda827xa_sleep, 847 .set_params = tda827xa_set_params, 848 .set_analog_params = tda827xa_set_analog_params, 849 .get_frequency = tda827x_get_frequency, 850 .get_bandwidth = tda827x_get_bandwidth, 851}; 852 853static int tda827x_probe_version(struct dvb_frontend *fe) 854{ 855 u8 data; 856 int rc; 857 struct tda827x_priv *priv = fe->tuner_priv; 858 struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = I2C_M_RD, 859 .buf = &data, .len = 1 }; 860 861 rc = tuner_transfer(fe, &msg, 1); 862 863 if (rc < 0) { 864 printk("%s: could not read from tuner at addr: 0x%02x\n", 865 __func__, msg.addr << 1); 866 return rc; 867 } 868 if ((data & 0x3c) == 0) { 869 dprintk("tda827x tuner found\n"); 870 fe->ops.tuner_ops.init = tda827x_init; 871 fe->ops.tuner_ops.sleep = tda827xo_sleep; 872 if (priv->cfg) 873 priv->cfg->agcf = tda827xo_agcf; 874 } else { 875 dprintk("tda827xa tuner found\n"); 876 memcpy(&fe->ops.tuner_ops, &tda827xa_tuner_ops, sizeof(struct dvb_tuner_ops)); 877 if (priv->cfg) 878 priv->cfg->agcf = tda827xa_agcf; 879 } 880 return 0; 881} 882 883struct dvb_frontend *tda827x_attach(struct dvb_frontend *fe, int addr, 884 struct i2c_adapter *i2c, 885 struct tda827x_config *cfg) 886{ 887 struct tda827x_priv *priv = NULL; 888 889 dprintk("%s:\n", __func__); 890 priv = kzalloc(sizeof(struct tda827x_priv), GFP_KERNEL); 891 if (priv == NULL) 892 return NULL; 893 894 priv->i2c_addr = addr; 895 priv->i2c_adap = i2c; 896 priv->cfg = cfg; 897 memcpy(&fe->ops.tuner_ops, &tda827xo_tuner_ops, sizeof(struct dvb_tuner_ops)); 898 fe->tuner_priv = priv; 899 900 dprintk("type set to %s\n", fe->ops.tuner_ops.info.name); 901 902 return fe; 903} 904EXPORT_SYMBOL_GPL(tda827x_attach); 905 906MODULE_DESCRIPTION("DVB TDA827x driver"); 907MODULE_AUTHOR("Hartmut Hackmann <hartmut.hackmann@t-online.de>"); 908MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>"); 909MODULE_LICENSE("GPL"); 910