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 struct dvb_frontend_parameters *params) 157{ 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 switch (params->u.ofdm.bandwidth) { 169 case BANDWIDTH_6_MHZ: 170 if_freq = 4000000; 171 break; 172 case BANDWIDTH_7_MHZ: 173 if_freq = 4500000; 174 break; 175 default: /* 8 MHz or Auto */ 176 if_freq = 5000000; 177 break; 178 } 179 tuner_freq = params->frequency + if_freq; 180 181 i = 0; 182 while (tda827x_table[i].lomax < tuner_freq) { 183 if (tda827x_table[i + 1].lomax == 0) 184 break; 185 i++; 186 } 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 = params->frequency; 222 priv->bandwidth = (fe->ops.info.type == FE_OFDM) ? params->u.ofdm.bandwidth : 0; 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 0: /* no LNA */ 483 break; 484 case 1: /* switch is GPIO 0 of tda8290 */ 485 case 2: 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 == 2) 503 buf[1] = high ? 1 : 0; 504 tuner_transfer(fe, &msg, 1); 505 break; 506 case 3: /* 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 struct dvb_frontend_parameters *params) 516{ 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 switch (params->u.ofdm.bandwidth) { 533 case BANDWIDTH_6_MHZ: 534 if_freq = 4000000; 535 break; 536 case BANDWIDTH_7_MHZ: 537 if_freq = 4500000; 538 break; 539 default: /* 8 MHz or Auto */ 540 if_freq = 5000000; 541 break; 542 } 543 tuner_freq = params->frequency + if_freq; 544 545 if (fe->ops.info.type == FE_QAM) { 546 dprintk("%s select tda827xa_dvbc\n", __func__); 547 frequency_map = tda827xa_dvbc; 548 } 549 550 i = 0; 551 while (frequency_map[i].lomax < tuner_freq) { 552 if (frequency_map[i + 1].lomax == 0) 553 break; 554 i++; 555 } 556 557 N = ((tuner_freq + 31250) / 62500) << frequency_map[i].spd; 558 buf[0] = 0; // subaddress 559 buf[1] = N >> 8; 560 buf[2] = N & 0xff; 561 buf[3] = 0; 562 buf[4] = 0x16; 563 buf[5] = (frequency_map[i].spd << 5) + (frequency_map[i].svco << 3) + 564 frequency_map[i].sbs; 565 buf[6] = 0x4b + (frequency_map[i].gc3 << 4); 566 buf[7] = 0x1c; 567 buf[8] = 0x06; 568 buf[9] = 0x24; 569 buf[10] = 0x00; 570 msg.len = 11; 571 rc = tuner_transfer(fe, &msg, 1); 572 if (rc < 0) 573 goto err; 574 575 buf[0] = 0x90; 576 buf[1] = 0xff; 577 buf[2] = 0x60; 578 buf[3] = 0x00; 579 buf[4] = 0x59; // lpsel, for 6MHz + 2 580 msg.len = 5; 581 rc = tuner_transfer(fe, &msg, 1); 582 if (rc < 0) 583 goto err; 584 585 buf[0] = 0xa0; 586 buf[1] = 0x40; 587 msg.len = 2; 588 rc = tuner_transfer(fe, &msg, 1); 589 if (rc < 0) 590 goto err; 591 592 msleep(11); 593 msg.flags = I2C_M_RD; 594 rc = tuner_transfer(fe, &msg, 1); 595 if (rc < 0) 596 goto err; 597 msg.flags = 0; 598 599 buf[1] >>= 4; 600 dprintk("tda8275a AGC2 gain is: %d\n", buf[1]); 601 if ((buf[1]) < 2) { 602 tda827xa_lna_gain(fe, 0, NULL); 603 buf[0] = 0x60; 604 buf[1] = 0x0c; 605 rc = tuner_transfer(fe, &msg, 1); 606 if (rc < 0) 607 goto err; 608 } 609 610 buf[0] = 0xc0; 611 buf[1] = 0x99; // lpsel, for 6MHz + 2 612 rc = tuner_transfer(fe, &msg, 1); 613 if (rc < 0) 614 goto err; 615 616 buf[0] = 0x60; 617 buf[1] = 0x3c; 618 rc = tuner_transfer(fe, &msg, 1); 619 if (rc < 0) 620 goto err; 621 622 /* correct CP value */ 623 buf[0] = 0x30; 624 buf[1] = 0x10 + frequency_map[i].scr; 625 rc = tuner_transfer(fe, &msg, 1); 626 if (rc < 0) 627 goto err; 628 629 msleep(163); 630 buf[0] = 0xc0; 631 buf[1] = 0x39; // lpsel, for 6MHz + 2 632 rc = tuner_transfer(fe, &msg, 1); 633 if (rc < 0) 634 goto err; 635 636 msleep(3); 637 /* freeze AGC1 */ 638 buf[0] = 0x50; 639 buf[1] = 0x4f + (frequency_map[i].gc3 << 4); 640 rc = tuner_transfer(fe, &msg, 1); 641 if (rc < 0) 642 goto err; 643 644 priv->frequency = params->frequency; 645 priv->bandwidth = (fe->ops.info.type == FE_OFDM) ? params->u.ofdm.bandwidth : 0; 646 647 648 return 0; 649 650err: 651 printk(KERN_ERR "%s: could not write to tuner at addr: 0x%02x\n", 652 __func__, priv->i2c_addr << 1); 653 return rc; 654} 655 656 657static int tda827xa_set_analog_params(struct dvb_frontend *fe, 658 struct analog_parameters *params) 659{ 660 unsigned char tuner_reg[11]; 661 u32 N; 662 int i; 663 struct tda827x_priv *priv = fe->tuner_priv; 664 struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0, 665 .buf = tuner_reg, .len = sizeof(tuner_reg) }; 666 unsigned int freq = params->frequency; 667 668 tda827x_set_std(fe, params); 669 670 tda827xa_lna_gain(fe, 1, params); 671 msleep(10); 672 673 if (params->mode == V4L2_TUNER_RADIO) 674 freq = freq / 1000; 675 676 N = freq + priv->sgIF; 677 678 i = 0; 679 while (tda827xa_analog[i].lomax < N * 62500) { 680 if (tda827xa_analog[i + 1].lomax == 0) 681 break; 682 i++; 683 } 684 685 N = N << tda827xa_analog[i].spd; 686 687 tuner_reg[0] = 0; 688 tuner_reg[1] = (unsigned char)(N>>8); 689 tuner_reg[2] = (unsigned char) N; 690 tuner_reg[3] = 0; 691 tuner_reg[4] = 0x16; 692 tuner_reg[5] = (tda827xa_analog[i].spd << 5) + 693 (tda827xa_analog[i].svco << 3) + 694 tda827xa_analog[i].sbs; 695 tuner_reg[6] = 0x8b + (tda827xa_analog[i].gc3 << 4); 696 tuner_reg[7] = 0x1c; 697 tuner_reg[8] = 4; 698 tuner_reg[9] = 0x20; 699 tuner_reg[10] = 0x00; 700 msg.len = 11; 701 tuner_transfer(fe, &msg, 1); 702 703 tuner_reg[0] = 0x90; 704 tuner_reg[1] = 0xff; 705 tuner_reg[2] = 0xe0; 706 tuner_reg[3] = 0; 707 tuner_reg[4] = 0x99 + (priv->lpsel << 1); 708 msg.len = 5; 709 tuner_transfer(fe, &msg, 1); 710 711 tuner_reg[0] = 0xa0; 712 tuner_reg[1] = 0xc0; 713 msg.len = 2; 714 tuner_transfer(fe, &msg, 1); 715 716 tuner_reg[0] = 0x30; 717 tuner_reg[1] = 0x10 + tda827xa_analog[i].scr; 718 tuner_transfer(fe, &msg, 1); 719 720 msg.flags = I2C_M_RD; 721 tuner_transfer(fe, &msg, 1); 722 msg.flags = 0; 723 tuner_reg[1] >>= 4; 724 dprintk("AGC2 gain is: %d\n", tuner_reg[1]); 725 if (tuner_reg[1] < 1) 726 tda827xa_lna_gain(fe, 0, params); 727 728 msleep(100); 729 tuner_reg[0] = 0x60; 730 tuner_reg[1] = 0x3c; 731 tuner_transfer(fe, &msg, 1); 732 733 msleep(163); 734 tuner_reg[0] = 0x50; 735 tuner_reg[1] = 0x8f + (tda827xa_analog[i].gc3 << 4); 736 tuner_transfer(fe, &msg, 1); 737 738 tuner_reg[0] = 0x80; 739 tuner_reg[1] = 0x28; 740 tuner_transfer(fe, &msg, 1); 741 742 tuner_reg[0] = 0xb0; 743 tuner_reg[1] = 0x01; 744 tuner_transfer(fe, &msg, 1); 745 746 tuner_reg[0] = 0xc0; 747 tuner_reg[1] = 0x19 + (priv->lpsel << 1); 748 tuner_transfer(fe, &msg, 1); 749 750 priv->frequency = params->frequency; 751 752 return 0; 753} 754 755static void tda827xa_agcf(struct dvb_frontend *fe) 756{ 757 struct tda827x_priv *priv = fe->tuner_priv; 758 unsigned char data[] = {0x80, 0x2c}; 759 struct i2c_msg msg = {.addr = priv->i2c_addr, .flags = 0, 760 .buf = data, .len = 2}; 761 tuner_transfer(fe, &msg, 1); 762} 763 764/* ------------------------------------------------------------------ */ 765 766static int tda827x_release(struct dvb_frontend *fe) 767{ 768 kfree(fe->tuner_priv); 769 fe->tuner_priv = NULL; 770 return 0; 771} 772 773static int tda827x_get_frequency(struct dvb_frontend *fe, u32 *frequency) 774{ 775 struct tda827x_priv *priv = fe->tuner_priv; 776 *frequency = priv->frequency; 777 return 0; 778} 779 780static int tda827x_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth) 781{ 782 struct tda827x_priv *priv = fe->tuner_priv; 783 *bandwidth = priv->bandwidth; 784 return 0; 785} 786 787static int tda827x_init(struct dvb_frontend *fe) 788{ 789 struct tda827x_priv *priv = fe->tuner_priv; 790 dprintk("%s:\n", __func__); 791 if (priv->cfg && priv->cfg->init) 792 priv->cfg->init(fe); 793 794 return 0; 795} 796 797static int tda827x_probe_version(struct dvb_frontend *fe); 798 799static int tda827x_initial_init(struct dvb_frontend *fe) 800{ 801 int ret; 802 ret = tda827x_probe_version(fe); 803 if (ret) 804 return ret; 805 return fe->ops.tuner_ops.init(fe); 806} 807 808static int tda827x_initial_sleep(struct dvb_frontend *fe) 809{ 810 int ret; 811 ret = tda827x_probe_version(fe); 812 if (ret) 813 return ret; 814 return fe->ops.tuner_ops.sleep(fe); 815} 816 817static struct dvb_tuner_ops tda827xo_tuner_ops = { 818 .info = { 819 .name = "Philips TDA827X", 820 .frequency_min = 55000000, 821 .frequency_max = 860000000, 822 .frequency_step = 250000 823 }, 824 .release = tda827x_release, 825 .init = tda827x_initial_init, 826 .sleep = tda827x_initial_sleep, 827 .set_params = tda827xo_set_params, 828 .set_analog_params = tda827xo_set_analog_params, 829 .get_frequency = tda827x_get_frequency, 830 .get_bandwidth = tda827x_get_bandwidth, 831}; 832 833static struct dvb_tuner_ops tda827xa_tuner_ops = { 834 .info = { 835 .name = "Philips TDA827XA", 836 .frequency_min = 44000000, 837 .frequency_max = 906000000, 838 .frequency_step = 62500 839 }, 840 .release = tda827x_release, 841 .init = tda827x_init, 842 .sleep = tda827xa_sleep, 843 .set_params = tda827xa_set_params, 844 .set_analog_params = tda827xa_set_analog_params, 845 .get_frequency = tda827x_get_frequency, 846 .get_bandwidth = tda827x_get_bandwidth, 847}; 848 849static int tda827x_probe_version(struct dvb_frontend *fe) 850{ 851 u8 data; 852 int rc; 853 struct tda827x_priv *priv = fe->tuner_priv; 854 struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = I2C_M_RD, 855 .buf = &data, .len = 1 }; 856 857 rc = tuner_transfer(fe, &msg, 1); 858 859 if (rc < 0) { 860 printk("%s: could not read from tuner at addr: 0x%02x\n", 861 __func__, msg.addr << 1); 862 return rc; 863 } 864 if ((data & 0x3c) == 0) { 865 dprintk("tda827x tuner found\n"); 866 fe->ops.tuner_ops.init = tda827x_init; 867 fe->ops.tuner_ops.sleep = tda827xo_sleep; 868 if (priv->cfg) 869 priv->cfg->agcf = tda827xo_agcf; 870 } else { 871 dprintk("tda827xa tuner found\n"); 872 memcpy(&fe->ops.tuner_ops, &tda827xa_tuner_ops, sizeof(struct dvb_tuner_ops)); 873 if (priv->cfg) 874 priv->cfg->agcf = tda827xa_agcf; 875 } 876 return 0; 877} 878 879struct dvb_frontend *tda827x_attach(struct dvb_frontend *fe, int addr, 880 struct i2c_adapter *i2c, 881 struct tda827x_config *cfg) 882{ 883 struct tda827x_priv *priv = NULL; 884 885 dprintk("%s:\n", __func__); 886 priv = kzalloc(sizeof(struct tda827x_priv), GFP_KERNEL); 887 if (priv == NULL) 888 return NULL; 889 890 priv->i2c_addr = addr; 891 priv->i2c_adap = i2c; 892 priv->cfg = cfg; 893 memcpy(&fe->ops.tuner_ops, &tda827xo_tuner_ops, sizeof(struct dvb_tuner_ops)); 894 fe->tuner_priv = priv; 895 896 dprintk("type set to %s\n", fe->ops.tuner_ops.info.name); 897 898 return fe; 899} 900EXPORT_SYMBOL_GPL(tda827x_attach); 901 902MODULE_DESCRIPTION("DVB TDA827x driver"); 903MODULE_AUTHOR("Hartmut Hackmann <hartmut.hackmann@t-online.de>"); 904MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>"); 905MODULE_LICENSE("GPL"); 906 907/* 908 * Overrides for Emacs so that we follow Linus's tabbing style. 909 * --------------------------------------------------------------------------- 910 * Local variables: 911 * c-basic-offset: 8 912 * End: 913 */ 914