1 /* 2 STV6110(A) Silicon tuner driver 3 4 Copyright (C) Manu Abraham <abraham.manu@gmail.com> 5 6 Copyright (C) ST Microelectronics 7 8 This program is free software; you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by 10 the Free Software Foundation; either version 2 of the License, or 11 (at your option) any later version. 12 13 This program is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with this program; if not, write to the Free Software 20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 21 */ 22 23 #include <linux/init.h> 24 #include <linux/kernel.h> 25 #include <linux/module.h> 26 #include <linux/slab.h> 27 #include <linux/string.h> 28 29 #include <media/dvb_frontend.h> 30 31 #include "stv6110x_reg.h" 32 #include "stv6110x.h" 33 #include "stv6110x_priv.h" 34 35 /* Max transfer size done by I2C transfer functions */ 36 #define MAX_XFER_SIZE 64 37 38 static unsigned int verbose; 39 module_param(verbose, int, 0644); 40 MODULE_PARM_DESC(verbose, "Set Verbosity level"); 41 42 static int stv6110x_read_reg(struct stv6110x_state *stv6110x, u8 reg, u8 *data) 43 { 44 int ret; 45 const struct stv6110x_config *config = stv6110x->config; 46 u8 b0[] = { reg }; 47 u8 b1[] = { 0 }; 48 struct i2c_msg msg[] = { 49 { .addr = config->addr, .flags = 0, .buf = b0, .len = 1 }, 50 { .addr = config->addr, .flags = I2C_M_RD, .buf = b1, .len = 1 } 51 }; 52 53 ret = i2c_transfer(stv6110x->i2c, msg, 2); 54 if (ret != 2) { 55 dprintk(FE_ERROR, 1, "I/O Error"); 56 return -EREMOTEIO; 57 } 58 *data = b1[0]; 59 60 return 0; 61 } 62 63 static int stv6110x_write_regs(struct stv6110x_state *stv6110x, int start, u8 data[], int len) 64 { 65 int ret; 66 const struct stv6110x_config *config = stv6110x->config; 67 u8 buf[MAX_XFER_SIZE]; 68 69 struct i2c_msg msg = { 70 .addr = config->addr, 71 .flags = 0, 72 .buf = buf, 73 .len = len + 1 74 }; 75 76 if (1 + len > sizeof(buf)) { 77 printk(KERN_WARNING 78 "%s: i2c wr: len=%d is too big!\n", 79 KBUILD_MODNAME, len); 80 return -EINVAL; 81 } 82 83 if (start + len > 8) 84 return -EINVAL; 85 86 buf[0] = start; 87 memcpy(&buf[1], data, len); 88 89 ret = i2c_transfer(stv6110x->i2c, &msg, 1); 90 if (ret != 1) { 91 dprintk(FE_ERROR, 1, "I/O Error"); 92 return -EREMOTEIO; 93 } 94 95 return 0; 96 } 97 98 static int stv6110x_write_reg(struct stv6110x_state *stv6110x, u8 reg, u8 data) 99 { 100 u8 tmp = data; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */ 101 102 return stv6110x_write_regs(stv6110x, reg, &tmp, 1); 103 } 104 105 static int stv6110x_init(struct dvb_frontend *fe) 106 { 107 struct stv6110x_state *stv6110x = fe->tuner_priv; 108 int ret; 109 110 ret = stv6110x_write_regs(stv6110x, 0, stv6110x->regs, 111 ARRAY_SIZE(stv6110x->regs)); 112 if (ret < 0) { 113 dprintk(FE_ERROR, 1, "Initialization failed"); 114 return -1; 115 } 116 117 return 0; 118 } 119 120 static int stv6110x_set_frequency(struct dvb_frontend *fe, u32 frequency) 121 { 122 struct stv6110x_state *stv6110x = fe->tuner_priv; 123 u32 rDiv, divider; 124 s32 pVal, pCalc, rDivOpt = 0, pCalcOpt = 1000; 125 u8 i; 126 127 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_K, (REFCLOCK_MHz - 16)); 128 129 if (frequency <= 1023000) { 130 STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_DIV4SEL, 1); 131 STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_PRESC32_ON, 0); 132 pVal = 40; 133 } else if (frequency <= 1300000) { 134 STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_DIV4SEL, 1); 135 STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_PRESC32_ON, 1); 136 pVal = 40; 137 } else if (frequency <= 2046000) { 138 STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_DIV4SEL, 0); 139 STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_PRESC32_ON, 0); 140 pVal = 20; 141 } else { 142 STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_DIV4SEL, 0); 143 STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_PRESC32_ON, 1); 144 pVal = 20; 145 } 146 147 for (rDiv = 0; rDiv <= 3; rDiv++) { 148 pCalc = (REFCLOCK_kHz / 100) / R_DIV(rDiv); 149 150 if ((abs((s32)(pCalc - pVal))) < (abs((s32)(pCalcOpt - pVal)))) 151 rDivOpt = rDiv; 152 153 pCalcOpt = (REFCLOCK_kHz / 100) / R_DIV(rDivOpt); 154 } 155 156 divider = (frequency * R_DIV(rDivOpt) * pVal) / REFCLOCK_kHz; 157 divider = (divider + 5) / 10; 158 159 STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_R_DIV, rDivOpt); 160 STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_N_DIV_11_8, MSB(divider)); 161 STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG0], TNG0_N_DIV_7_0, LSB(divider)); 162 163 /* VCO Auto calibration */ 164 STV6110x_SETFIELD(stv6110x->regs[STV6110x_STAT1], STAT1_CALVCO_STRT, 1); 165 166 stv6110x_write_reg(stv6110x, STV6110x_CTRL1, stv6110x->regs[STV6110x_CTRL1]); 167 stv6110x_write_reg(stv6110x, STV6110x_TNG1, stv6110x->regs[STV6110x_TNG1]); 168 stv6110x_write_reg(stv6110x, STV6110x_TNG0, stv6110x->regs[STV6110x_TNG0]); 169 stv6110x_write_reg(stv6110x, STV6110x_STAT1, stv6110x->regs[STV6110x_STAT1]); 170 171 for (i = 0; i < TRIALS; i++) { 172 stv6110x_read_reg(stv6110x, STV6110x_STAT1, &stv6110x->regs[STV6110x_STAT1]); 173 if (!STV6110x_GETFIELD(STAT1_CALVCO_STRT, stv6110x->regs[STV6110x_STAT1])) 174 break; 175 msleep(1); 176 } 177 178 return 0; 179 } 180 181 static int stv6110x_get_frequency(struct dvb_frontend *fe, u32 *frequency) 182 { 183 struct stv6110x_state *stv6110x = fe->tuner_priv; 184 185 stv6110x_read_reg(stv6110x, STV6110x_TNG1, &stv6110x->regs[STV6110x_TNG1]); 186 stv6110x_read_reg(stv6110x, STV6110x_TNG0, &stv6110x->regs[STV6110x_TNG0]); 187 188 *frequency = (MAKEWORD16(STV6110x_GETFIELD(TNG1_N_DIV_11_8, stv6110x->regs[STV6110x_TNG1]), 189 STV6110x_GETFIELD(TNG0_N_DIV_7_0, stv6110x->regs[STV6110x_TNG0]))) * REFCLOCK_kHz; 190 191 *frequency /= (1 << (STV6110x_GETFIELD(TNG1_R_DIV, stv6110x->regs[STV6110x_TNG1]) + 192 STV6110x_GETFIELD(TNG1_DIV4SEL, stv6110x->regs[STV6110x_TNG1]))); 193 194 *frequency >>= 2; 195 196 return 0; 197 } 198 199 static int stv6110x_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth) 200 { 201 struct stv6110x_state *stv6110x = fe->tuner_priv; 202 u32 halfbw; 203 u8 i; 204 205 halfbw = bandwidth >> 1; 206 207 if (halfbw > 36000000) 208 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL3], CTRL3_CF, 31); /* LPF */ 209 else if (halfbw < 5000000) 210 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL3], CTRL3_CF, 0); /* LPF */ 211 else 212 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL3], CTRL3_CF, ((halfbw / 1000000) - 5)); /* LPF */ 213 214 215 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL3], CTRL3_RCCLK_OFF, 0x0); /* cal. clk activated */ 216 STV6110x_SETFIELD(stv6110x->regs[STV6110x_STAT1], STAT1_CALRC_STRT, 0x1); /* LPF auto cal */ 217 218 stv6110x_write_reg(stv6110x, STV6110x_CTRL3, stv6110x->regs[STV6110x_CTRL3]); 219 stv6110x_write_reg(stv6110x, STV6110x_STAT1, stv6110x->regs[STV6110x_STAT1]); 220 221 for (i = 0; i < TRIALS; i++) { 222 stv6110x_read_reg(stv6110x, STV6110x_STAT1, &stv6110x->regs[STV6110x_STAT1]); 223 if (!STV6110x_GETFIELD(STAT1_CALRC_STRT, stv6110x->regs[STV6110x_STAT1])) 224 break; 225 msleep(1); 226 } 227 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL3], CTRL3_RCCLK_OFF, 0x1); /* cal. done */ 228 stv6110x_write_reg(stv6110x, STV6110x_CTRL3, stv6110x->regs[STV6110x_CTRL3]); 229 230 return 0; 231 } 232 233 static int stv6110x_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth) 234 { 235 struct stv6110x_state *stv6110x = fe->tuner_priv; 236 237 stv6110x_read_reg(stv6110x, STV6110x_CTRL3, &stv6110x->regs[STV6110x_CTRL3]); 238 *bandwidth = (STV6110x_GETFIELD(CTRL3_CF, stv6110x->regs[STV6110x_CTRL3]) + 5) * 2000000; 239 240 return 0; 241 } 242 243 static int stv6110x_set_refclock(struct dvb_frontend *fe, u32 refclock) 244 { 245 struct stv6110x_state *stv6110x = fe->tuner_priv; 246 247 /* setup divider */ 248 switch (refclock) { 249 default: 250 case 1: 251 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 0); 252 break; 253 case 2: 254 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 1); 255 break; 256 case 4: 257 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 2); 258 break; 259 case 8: 260 case 0: 261 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 3); 262 break; 263 } 264 stv6110x_write_reg(stv6110x, STV6110x_CTRL2, stv6110x->regs[STV6110x_CTRL2]); 265 266 return 0; 267 } 268 269 static int stv6110x_get_bbgain(struct dvb_frontend *fe, u32 *gain) 270 { 271 struct stv6110x_state *stv6110x = fe->tuner_priv; 272 273 stv6110x_read_reg(stv6110x, STV6110x_CTRL2, &stv6110x->regs[STV6110x_CTRL2]); 274 *gain = 2 * STV6110x_GETFIELD(CTRL2_BBGAIN, stv6110x->regs[STV6110x_CTRL2]); 275 276 return 0; 277 } 278 279 static int stv6110x_set_bbgain(struct dvb_frontend *fe, u32 gain) 280 { 281 struct stv6110x_state *stv6110x = fe->tuner_priv; 282 283 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_BBGAIN, gain / 2); 284 stv6110x_write_reg(stv6110x, STV6110x_CTRL2, stv6110x->regs[STV6110x_CTRL2]); 285 286 return 0; 287 } 288 289 static int stv6110x_set_mode(struct dvb_frontend *fe, enum tuner_mode mode) 290 { 291 struct stv6110x_state *stv6110x = fe->tuner_priv; 292 int ret; 293 294 switch (mode) { 295 case TUNER_SLEEP: 296 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_SYN, 0); 297 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_RX, 0); 298 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_LPT, 0); 299 break; 300 301 case TUNER_WAKE: 302 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_SYN, 1); 303 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_RX, 1); 304 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_LPT, 1); 305 break; 306 } 307 308 ret = stv6110x_write_reg(stv6110x, STV6110x_CTRL1, stv6110x->regs[STV6110x_CTRL1]); 309 if (ret < 0) { 310 dprintk(FE_ERROR, 1, "I/O Error"); 311 return -EIO; 312 } 313 314 return 0; 315 } 316 317 static int stv6110x_sleep(struct dvb_frontend *fe) 318 { 319 if (fe->tuner_priv) 320 return stv6110x_set_mode(fe, TUNER_SLEEP); 321 322 return 0; 323 } 324 325 static int stv6110x_get_status(struct dvb_frontend *fe, u32 *status) 326 { 327 struct stv6110x_state *stv6110x = fe->tuner_priv; 328 329 stv6110x_read_reg(stv6110x, STV6110x_STAT1, &stv6110x->regs[STV6110x_STAT1]); 330 331 if (STV6110x_GETFIELD(STAT1_LOCK, stv6110x->regs[STV6110x_STAT1])) 332 *status = TUNER_PHASELOCKED; 333 else 334 *status = 0; 335 336 return 0; 337 } 338 339 340 static void stv6110x_release(struct dvb_frontend *fe) 341 { 342 struct stv6110x_state *stv6110x = fe->tuner_priv; 343 344 fe->tuner_priv = NULL; 345 kfree(stv6110x); 346 } 347 348 static const struct dvb_tuner_ops stv6110x_ops = { 349 .info = { 350 .name = "STV6110(A) Silicon Tuner", 351 .frequency_min = 950000, 352 .frequency_max = 2150000, 353 .frequency_step = 0, 354 }, 355 .release = stv6110x_release 356 }; 357 358 static const struct stv6110x_devctl stv6110x_ctl = { 359 .tuner_init = stv6110x_init, 360 .tuner_sleep = stv6110x_sleep, 361 .tuner_set_mode = stv6110x_set_mode, 362 .tuner_set_frequency = stv6110x_set_frequency, 363 .tuner_get_frequency = stv6110x_get_frequency, 364 .tuner_set_bandwidth = stv6110x_set_bandwidth, 365 .tuner_get_bandwidth = stv6110x_get_bandwidth, 366 .tuner_set_bbgain = stv6110x_set_bbgain, 367 .tuner_get_bbgain = stv6110x_get_bbgain, 368 .tuner_set_refclk = stv6110x_set_refclock, 369 .tuner_get_status = stv6110x_get_status, 370 }; 371 372 const struct stv6110x_devctl *stv6110x_attach(struct dvb_frontend *fe, 373 const struct stv6110x_config *config, 374 struct i2c_adapter *i2c) 375 { 376 struct stv6110x_state *stv6110x; 377 u8 default_regs[] = {0x07, 0x11, 0xdc, 0x85, 0x17, 0x01, 0xe6, 0x1e}; 378 379 stv6110x = kzalloc(sizeof (struct stv6110x_state), GFP_KERNEL); 380 if (!stv6110x) 381 return NULL; 382 383 stv6110x->i2c = i2c; 384 stv6110x->config = config; 385 stv6110x->devctl = &stv6110x_ctl; 386 memcpy(stv6110x->regs, default_regs, 8); 387 388 /* setup divider */ 389 switch (stv6110x->config->clk_div) { 390 default: 391 case 1: 392 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 0); 393 break; 394 case 2: 395 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 1); 396 break; 397 case 4: 398 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 2); 399 break; 400 case 8: 401 case 0: 402 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 3); 403 break; 404 } 405 406 fe->tuner_priv = stv6110x; 407 fe->ops.tuner_ops = stv6110x_ops; 408 409 printk(KERN_INFO "%s: Attaching STV6110x\n", __func__); 410 return stv6110x->devctl; 411 } 412 EXPORT_SYMBOL(stv6110x_attach); 413 414 MODULE_AUTHOR("Manu Abraham"); 415 MODULE_DESCRIPTION("STV6110x Silicon tuner"); 416 MODULE_LICENSE("GPL"); 417