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