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 "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 return stv6110x_write_regs(stv6110x, reg, &data, 1); 101 } 102 103 static int stv6110x_init(struct dvb_frontend *fe) 104 { 105 struct stv6110x_state *stv6110x = fe->tuner_priv; 106 int ret; 107 108 ret = stv6110x_write_regs(stv6110x, 0, stv6110x->regs, 109 ARRAY_SIZE(stv6110x->regs)); 110 if (ret < 0) { 111 dprintk(FE_ERROR, 1, "Initialization failed"); 112 return -1; 113 } 114 115 return 0; 116 } 117 118 static int stv6110x_set_frequency(struct dvb_frontend *fe, u32 frequency) 119 { 120 struct stv6110x_state *stv6110x = fe->tuner_priv; 121 u32 rDiv, divider; 122 s32 pVal, pCalc, rDivOpt = 0, pCalcOpt = 1000; 123 u8 i; 124 125 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_K, (REFCLOCK_MHz - 16)); 126 127 if (frequency <= 1023000) { 128 STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_DIV4SEL, 1); 129 STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_PRESC32_ON, 0); 130 pVal = 40; 131 } else if (frequency <= 1300000) { 132 STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_DIV4SEL, 1); 133 STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_PRESC32_ON, 1); 134 pVal = 40; 135 } else if (frequency <= 2046000) { 136 STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_DIV4SEL, 0); 137 STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_PRESC32_ON, 0); 138 pVal = 20; 139 } else { 140 STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_DIV4SEL, 0); 141 STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_PRESC32_ON, 1); 142 pVal = 20; 143 } 144 145 for (rDiv = 0; rDiv <= 3; rDiv++) { 146 pCalc = (REFCLOCK_kHz / 100) / R_DIV(rDiv); 147 148 if ((abs((s32)(pCalc - pVal))) < (abs((s32)(pCalcOpt - pVal)))) 149 rDivOpt = rDiv; 150 151 pCalcOpt = (REFCLOCK_kHz / 100) / R_DIV(rDivOpt); 152 } 153 154 divider = (frequency * R_DIV(rDivOpt) * pVal) / REFCLOCK_kHz; 155 divider = (divider + 5) / 10; 156 157 STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_R_DIV, rDivOpt); 158 STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_N_DIV_11_8, MSB(divider)); 159 STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG0], TNG0_N_DIV_7_0, LSB(divider)); 160 161 /* VCO Auto calibration */ 162 STV6110x_SETFIELD(stv6110x->regs[STV6110x_STAT1], STAT1_CALVCO_STRT, 1); 163 164 stv6110x_write_reg(stv6110x, STV6110x_CTRL1, stv6110x->regs[STV6110x_CTRL1]); 165 stv6110x_write_reg(stv6110x, STV6110x_TNG1, stv6110x->regs[STV6110x_TNG1]); 166 stv6110x_write_reg(stv6110x, STV6110x_TNG0, stv6110x->regs[STV6110x_TNG0]); 167 stv6110x_write_reg(stv6110x, STV6110x_STAT1, stv6110x->regs[STV6110x_STAT1]); 168 169 for (i = 0; i < TRIALS; i++) { 170 stv6110x_read_reg(stv6110x, STV6110x_STAT1, &stv6110x->regs[STV6110x_STAT1]); 171 if (!STV6110x_GETFIELD(STAT1_CALVCO_STRT, stv6110x->regs[STV6110x_STAT1])) 172 break; 173 msleep(1); 174 } 175 176 return 0; 177 } 178 179 static int stv6110x_get_frequency(struct dvb_frontend *fe, u32 *frequency) 180 { 181 struct stv6110x_state *stv6110x = fe->tuner_priv; 182 183 stv6110x_read_reg(stv6110x, STV6110x_TNG1, &stv6110x->regs[STV6110x_TNG1]); 184 stv6110x_read_reg(stv6110x, STV6110x_TNG0, &stv6110x->regs[STV6110x_TNG0]); 185 186 *frequency = (MAKEWORD16(STV6110x_GETFIELD(TNG1_N_DIV_11_8, stv6110x->regs[STV6110x_TNG1]), 187 STV6110x_GETFIELD(TNG0_N_DIV_7_0, stv6110x->regs[STV6110x_TNG0]))) * REFCLOCK_kHz; 188 189 *frequency /= (1 << (STV6110x_GETFIELD(TNG1_R_DIV, stv6110x->regs[STV6110x_TNG1]) + 190 STV6110x_GETFIELD(TNG1_DIV4SEL, stv6110x->regs[STV6110x_TNG1]))); 191 192 *frequency >>= 2; 193 194 return 0; 195 } 196 197 static int stv6110x_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth) 198 { 199 struct stv6110x_state *stv6110x = fe->tuner_priv; 200 u32 halfbw; 201 u8 i; 202 203 halfbw = bandwidth >> 1; 204 205 if (halfbw > 36000000) 206 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL3], CTRL3_CF, 31); /* LPF */ 207 else if (halfbw < 5000000) 208 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL3], CTRL3_CF, 0); /* LPF */ 209 else 210 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL3], CTRL3_CF, ((halfbw / 1000000) - 5)); /* LPF */ 211 212 213 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL3], CTRL3_RCCLK_OFF, 0x0); /* cal. clk activated */ 214 STV6110x_SETFIELD(stv6110x->regs[STV6110x_STAT1], STAT1_CALRC_STRT, 0x1); /* LPF auto cal */ 215 216 stv6110x_write_reg(stv6110x, STV6110x_CTRL3, stv6110x->regs[STV6110x_CTRL3]); 217 stv6110x_write_reg(stv6110x, STV6110x_STAT1, stv6110x->regs[STV6110x_STAT1]); 218 219 for (i = 0; i < TRIALS; i++) { 220 stv6110x_read_reg(stv6110x, STV6110x_STAT1, &stv6110x->regs[STV6110x_STAT1]); 221 if (!STV6110x_GETFIELD(STAT1_CALRC_STRT, stv6110x->regs[STV6110x_STAT1])) 222 break; 223 msleep(1); 224 } 225 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL3], CTRL3_RCCLK_OFF, 0x1); /* cal. done */ 226 stv6110x_write_reg(stv6110x, STV6110x_CTRL3, stv6110x->regs[STV6110x_CTRL3]); 227 228 return 0; 229 } 230 231 static int stv6110x_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth) 232 { 233 struct stv6110x_state *stv6110x = fe->tuner_priv; 234 235 stv6110x_read_reg(stv6110x, STV6110x_CTRL3, &stv6110x->regs[STV6110x_CTRL3]); 236 *bandwidth = (STV6110x_GETFIELD(CTRL3_CF, stv6110x->regs[STV6110x_CTRL3]) + 5) * 2000000; 237 238 return 0; 239 } 240 241 static int stv6110x_set_refclock(struct dvb_frontend *fe, u32 refclock) 242 { 243 struct stv6110x_state *stv6110x = fe->tuner_priv; 244 245 /* setup divider */ 246 switch (refclock) { 247 default: 248 case 1: 249 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 0); 250 break; 251 case 2: 252 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 1); 253 break; 254 case 4: 255 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 2); 256 break; 257 case 8: 258 case 0: 259 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 3); 260 break; 261 } 262 stv6110x_write_reg(stv6110x, STV6110x_CTRL2, stv6110x->regs[STV6110x_CTRL2]); 263 264 return 0; 265 } 266 267 static int stv6110x_get_bbgain(struct dvb_frontend *fe, u32 *gain) 268 { 269 struct stv6110x_state *stv6110x = fe->tuner_priv; 270 271 stv6110x_read_reg(stv6110x, STV6110x_CTRL2, &stv6110x->regs[STV6110x_CTRL2]); 272 *gain = 2 * STV6110x_GETFIELD(CTRL2_BBGAIN, stv6110x->regs[STV6110x_CTRL2]); 273 274 return 0; 275 } 276 277 static int stv6110x_set_bbgain(struct dvb_frontend *fe, u32 gain) 278 { 279 struct stv6110x_state *stv6110x = fe->tuner_priv; 280 281 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_BBGAIN, gain / 2); 282 stv6110x_write_reg(stv6110x, STV6110x_CTRL2, stv6110x->regs[STV6110x_CTRL2]); 283 284 return 0; 285 } 286 287 static int stv6110x_set_mode(struct dvb_frontend *fe, enum tuner_mode mode) 288 { 289 struct stv6110x_state *stv6110x = fe->tuner_priv; 290 int ret; 291 292 switch (mode) { 293 case TUNER_SLEEP: 294 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_SYN, 0); 295 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_RX, 0); 296 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_LPT, 0); 297 break; 298 299 case TUNER_WAKE: 300 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_SYN, 1); 301 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_RX, 1); 302 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_LPT, 1); 303 break; 304 } 305 306 ret = stv6110x_write_reg(stv6110x, STV6110x_CTRL1, stv6110x->regs[STV6110x_CTRL1]); 307 if (ret < 0) { 308 dprintk(FE_ERROR, 1, "I/O Error"); 309 return -EIO; 310 } 311 312 return 0; 313 } 314 315 static int stv6110x_sleep(struct dvb_frontend *fe) 316 { 317 if (fe->tuner_priv) 318 return stv6110x_set_mode(fe, TUNER_SLEEP); 319 320 return 0; 321 } 322 323 static int stv6110x_get_status(struct dvb_frontend *fe, u32 *status) 324 { 325 struct stv6110x_state *stv6110x = fe->tuner_priv; 326 327 stv6110x_read_reg(stv6110x, STV6110x_STAT1, &stv6110x->regs[STV6110x_STAT1]); 328 329 if (STV6110x_GETFIELD(STAT1_LOCK, stv6110x->regs[STV6110x_STAT1])) 330 *status = TUNER_PHASELOCKED; 331 else 332 *status = 0; 333 334 return 0; 335 } 336 337 338 static const struct dvb_tuner_ops stv6110x_ops = { 339 .info = { 340 .name = "STV6110(A) Silicon Tuner", 341 .frequency_min = 950000, 342 .frequency_max = 2150000, 343 .frequency_step = 0, 344 }, 345 .release = dvb_tuner_simple_release, 346 }; 347 348 static const struct stv6110x_devctl stv6110x_ctl = { 349 .tuner_init = stv6110x_init, 350 .tuner_sleep = stv6110x_sleep, 351 .tuner_set_mode = stv6110x_set_mode, 352 .tuner_set_frequency = stv6110x_set_frequency, 353 .tuner_get_frequency = stv6110x_get_frequency, 354 .tuner_set_bandwidth = stv6110x_set_bandwidth, 355 .tuner_get_bandwidth = stv6110x_get_bandwidth, 356 .tuner_set_bbgain = stv6110x_set_bbgain, 357 .tuner_get_bbgain = stv6110x_get_bbgain, 358 .tuner_set_refclk = stv6110x_set_refclock, 359 .tuner_get_status = stv6110x_get_status, 360 }; 361 362 const struct stv6110x_devctl *stv6110x_attach(struct dvb_frontend *fe, 363 const struct stv6110x_config *config, 364 struct i2c_adapter *i2c) 365 { 366 struct stv6110x_state *stv6110x; 367 u8 default_regs[] = {0x07, 0x11, 0xdc, 0x85, 0x17, 0x01, 0xe6, 0x1e}; 368 369 stv6110x = kzalloc(sizeof (struct stv6110x_state), GFP_KERNEL); 370 if (!stv6110x) 371 return NULL; 372 373 stv6110x->i2c = i2c; 374 stv6110x->config = config; 375 stv6110x->devctl = &stv6110x_ctl; 376 memcpy(stv6110x->regs, default_regs, 8); 377 378 /* setup divider */ 379 switch (stv6110x->config->clk_div) { 380 default: 381 case 1: 382 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 0); 383 break; 384 case 2: 385 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 1); 386 break; 387 case 4: 388 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 2); 389 break; 390 case 8: 391 case 0: 392 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 3); 393 break; 394 } 395 396 fe->tuner_priv = stv6110x; 397 fe->ops.tuner_ops = stv6110x_ops; 398 399 printk(KERN_INFO "%s: Attaching STV6110x\n", __func__); 400 return stv6110x->devctl; 401 } 402 EXPORT_SYMBOL(stv6110x_attach); 403 404 MODULE_AUTHOR("Manu Abraham"); 405 MODULE_DESCRIPTION("STV6110x Silicon tuner"); 406 MODULE_LICENSE("GPL"); 407