ves1x93.c (13494B)
1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 Driver for VES1893 and VES1993 QPSK Demodulators 4 5 Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de> 6 Copyright (C) 2001 Ronny Strutz <3des@elitedvb.de> 7 Copyright (C) 2002 Dennis Noermann <dennis.noermann@noernet.de> 8 Copyright (C) 2002-2003 Andreas Oberritter <obi@linuxtv.org> 9 10 11*/ 12 13#include <linux/kernel.h> 14#include <linux/module.h> 15#include <linux/init.h> 16#include <linux/string.h> 17#include <linux/slab.h> 18#include <linux/delay.h> 19 20#include <media/dvb_frontend.h> 21#include "ves1x93.h" 22 23 24struct ves1x93_state { 25 struct i2c_adapter* i2c; 26 /* configuration settings */ 27 const struct ves1x93_config* config; 28 struct dvb_frontend frontend; 29 30 /* previous uncorrected block counter */ 31 enum fe_spectral_inversion inversion; 32 u8 *init_1x93_tab; 33 u8 *init_1x93_wtab; 34 u8 tab_size; 35 u8 demod_type; 36 u32 frequency; 37}; 38 39static int debug; 40#define dprintk if (debug) printk 41 42#define DEMOD_VES1893 0 43#define DEMOD_VES1993 1 44 45static u8 init_1893_tab [] = { 46 0x01, 0xa4, 0x35, 0x80, 0x2a, 0x0b, 0x55, 0xc4, 47 0x09, 0x69, 0x00, 0x86, 0x4c, 0x28, 0x7f, 0x00, 48 0x00, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 49 0x80, 0x00, 0x21, 0xb0, 0x14, 0x00, 0xdc, 0x00, 50 0x81, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 51 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 52 0x00, 0x55, 0x00, 0x00, 0x7f, 0x00 53}; 54 55static u8 init_1993_tab [] = { 56 0x00, 0x9c, 0x35, 0x80, 0x6a, 0x09, 0x72, 0x8c, 57 0x09, 0x6b, 0x00, 0x00, 0x4c, 0x08, 0x00, 0x00, 58 0x00, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 59 0x80, 0x40, 0x21, 0xb0, 0x00, 0x00, 0x00, 0x10, 60 0x81, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 61 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 62 0x00, 0x55, 0x03, 0x00, 0x00, 0x00, 0x00, 0x03, 63 0x00, 0x00, 0x0e, 0x80, 0x00 64}; 65 66static u8 init_1893_wtab[] = 67{ 68 1,1,1,1,1,1,1,1, 1,1,0,0,1,1,0,0, 69 0,1,0,0,0,0,0,0, 1,0,1,1,0,0,0,1, 70 1,1,1,0,0,0,0,0, 0,0,1,1,0,0,0,0, 71 1,1,1,0,1,1 72}; 73 74static u8 init_1993_wtab[] = 75{ 76 1,1,1,1,1,1,1,1, 1,1,0,0,1,1,0,0, 77 0,1,0,0,0,0,0,0, 1,1,1,1,0,0,0,1, 78 1,1,1,0,0,0,0,0, 0,0,1,1,0,0,0,0, 79 1,1,1,0,1,1,1,1, 1,1,1,1,1 80}; 81 82static int ves1x93_writereg (struct ves1x93_state* state, u8 reg, u8 data) 83{ 84 u8 buf [] = { 0x00, reg, data }; 85 struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 3 }; 86 int err; 87 88 if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) { 89 dprintk ("%s: writereg error (err == %i, reg == 0x%02x, data == 0x%02x)\n", __func__, err, reg, data); 90 return -EREMOTEIO; 91 } 92 93 return 0; 94} 95 96static u8 ves1x93_readreg (struct ves1x93_state* state, u8 reg) 97{ 98 int ret; 99 u8 b0 [] = { 0x00, reg }; 100 u8 b1 [] = { 0 }; 101 struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 2 }, 102 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } }; 103 104 ret = i2c_transfer (state->i2c, msg, 2); 105 106 if (ret != 2) return ret; 107 108 return b1[0]; 109} 110 111static int ves1x93_clr_bit (struct ves1x93_state* state) 112{ 113 msleep(10); 114 ves1x93_writereg (state, 0, state->init_1x93_tab[0] & 0xfe); 115 ves1x93_writereg (state, 0, state->init_1x93_tab[0]); 116 msleep(50); 117 return 0; 118} 119 120static int ves1x93_set_inversion(struct ves1x93_state *state, 121 enum fe_spectral_inversion inversion) 122{ 123 u8 val; 124 125 /* 126 * inversion on/off are interchanged because i and q seem to 127 * be swapped on the hardware 128 */ 129 130 switch (inversion) { 131 case INVERSION_OFF: 132 val = 0xc0; 133 break; 134 case INVERSION_ON: 135 val = 0x80; 136 break; 137 case INVERSION_AUTO: 138 val = 0x00; 139 break; 140 default: 141 return -EINVAL; 142 } 143 144 return ves1x93_writereg (state, 0x0c, (state->init_1x93_tab[0x0c] & 0x3f) | val); 145} 146 147static int ves1x93_set_fec(struct ves1x93_state *state, enum fe_code_rate fec) 148{ 149 if (fec == FEC_AUTO) 150 return ves1x93_writereg (state, 0x0d, 0x08); 151 else if (fec < FEC_1_2 || fec > FEC_8_9) 152 return -EINVAL; 153 else 154 return ves1x93_writereg (state, 0x0d, fec - FEC_1_2); 155} 156 157static enum fe_code_rate ves1x93_get_fec(struct ves1x93_state *state) 158{ 159 return FEC_1_2 + ((ves1x93_readreg (state, 0x0d) >> 4) & 0x7); 160} 161 162static int ves1x93_set_symbolrate (struct ves1x93_state* state, u32 srate) 163{ 164 u32 BDR; 165 u32 ratio; 166 u8 ADCONF, FCONF, FNR, AGCR; 167 u32 BDRI; 168 u32 tmp; 169 u32 FIN; 170 171 dprintk("%s: srate == %d\n", __func__, (unsigned int) srate); 172 173 if (srate > state->config->xin/2) 174 srate = state->config->xin/2; 175 176 if (srate < 500000) 177 srate = 500000; 178 179#define MUL (1UL<<26) 180 181 FIN = (state->config->xin + 6000) >> 4; 182 183 tmp = srate << 6; 184 ratio = tmp / FIN; 185 186 tmp = (tmp % FIN) << 8; 187 ratio = (ratio << 8) + tmp / FIN; 188 189 tmp = (tmp % FIN) << 8; 190 ratio = (ratio << 8) + tmp / FIN; 191 192 FNR = 0xff; 193 194 if (ratio < MUL/3) FNR = 0; 195 if (ratio < (MUL*11)/50) FNR = 1; 196 if (ratio < MUL/6) FNR = 2; 197 if (ratio < MUL/9) FNR = 3; 198 if (ratio < MUL/12) FNR = 4; 199 if (ratio < (MUL*11)/200) FNR = 5; 200 if (ratio < MUL/24) FNR = 6; 201 if (ratio < (MUL*27)/1000) FNR = 7; 202 if (ratio < MUL/48) FNR = 8; 203 if (ratio < (MUL*137)/10000) FNR = 9; 204 205 if (FNR == 0xff) { 206 ADCONF = 0x89; 207 FCONF = 0x80; 208 FNR = 0; 209 } else { 210 ADCONF = 0x81; 211 FCONF = 0x88 | (FNR >> 1) | ((FNR & 0x01) << 5); 212 /*FCONF = 0x80 | ((FNR & 0x01) << 5) | (((FNR > 1) & 0x03) << 3) | ((FNR >> 1) & 0x07);*/ 213 } 214 215 BDR = (( (ratio << (FNR >> 1)) >> 4) + 1) >> 1; 216 BDRI = ( ((FIN << 8) / ((srate << (FNR >> 1)) >> 2)) + 1) >> 1; 217 218 dprintk("FNR= %d\n", FNR); 219 dprintk("ratio= %08x\n", (unsigned int) ratio); 220 dprintk("BDR= %08x\n", (unsigned int) BDR); 221 dprintk("BDRI= %02x\n", (unsigned int) BDRI); 222 223 if (BDRI > 0xff) 224 BDRI = 0xff; 225 226 ves1x93_writereg (state, 0x06, 0xff & BDR); 227 ves1x93_writereg (state, 0x07, 0xff & (BDR >> 8)); 228 ves1x93_writereg (state, 0x08, 0x0f & (BDR >> 16)); 229 230 ves1x93_writereg (state, 0x09, BDRI); 231 ves1x93_writereg (state, 0x20, ADCONF); 232 ves1x93_writereg (state, 0x21, FCONF); 233 234 AGCR = state->init_1x93_tab[0x05]; 235 if (state->config->invert_pwm) 236 AGCR |= 0x20; 237 238 if (srate < 6000000) 239 AGCR |= 0x80; 240 else 241 AGCR &= ~0x80; 242 243 ves1x93_writereg (state, 0x05, AGCR); 244 245 /* ves1993 hates this, will lose lock */ 246 if (state->demod_type != DEMOD_VES1993) 247 ves1x93_clr_bit (state); 248 249 return 0; 250} 251 252static int ves1x93_init (struct dvb_frontend* fe) 253{ 254 struct ves1x93_state* state = fe->demodulator_priv; 255 int i; 256 int val; 257 258 dprintk("%s: init chip\n", __func__); 259 260 for (i = 0; i < state->tab_size; i++) { 261 if (state->init_1x93_wtab[i]) { 262 val = state->init_1x93_tab[i]; 263 264 if (state->config->invert_pwm && (i == 0x05)) val |= 0x20; /* invert PWM */ 265 ves1x93_writereg (state, i, val); 266 } 267 } 268 269 return 0; 270} 271 272static int ves1x93_set_voltage(struct dvb_frontend *fe, 273 enum fe_sec_voltage voltage) 274{ 275 struct ves1x93_state* state = fe->demodulator_priv; 276 277 switch (voltage) { 278 case SEC_VOLTAGE_13: 279 return ves1x93_writereg (state, 0x1f, 0x20); 280 case SEC_VOLTAGE_18: 281 return ves1x93_writereg (state, 0x1f, 0x30); 282 case SEC_VOLTAGE_OFF: 283 return ves1x93_writereg (state, 0x1f, 0x00); 284 default: 285 return -EINVAL; 286 } 287} 288 289static int ves1x93_read_status(struct dvb_frontend *fe, 290 enum fe_status *status) 291{ 292 struct ves1x93_state* state = fe->demodulator_priv; 293 294 u8 sync = ves1x93_readreg (state, 0x0e); 295 296 /* 297 * The ves1893 sometimes returns sync values that make no sense, 298 * because, e.g., the SIGNAL bit is 0, while some of the higher 299 * bits are 1 (and how can there be a CARRIER w/o a SIGNAL?). 300 * Tests showed that the VITERBI and SYNC bits are returned 301 * reliably, while the SIGNAL and CARRIER bits ar sometimes wrong. 302 * If such a case occurs, we read the value again, until we get a 303 * valid value. 304 */ 305 int maxtry = 10; /* just for safety - let's not get stuck here */ 306 while ((sync & 0x03) != 0x03 && (sync & 0x0c) && maxtry--) { 307 msleep(10); 308 sync = ves1x93_readreg (state, 0x0e); 309 } 310 311 *status = 0; 312 313 if (sync & 1) 314 *status |= FE_HAS_SIGNAL; 315 316 if (sync & 2) 317 *status |= FE_HAS_CARRIER; 318 319 if (sync & 4) 320 *status |= FE_HAS_VITERBI; 321 322 if (sync & 8) 323 *status |= FE_HAS_SYNC; 324 325 if ((sync & 0x1f) == 0x1f) 326 *status |= FE_HAS_LOCK; 327 328 return 0; 329} 330 331static int ves1x93_read_ber(struct dvb_frontend* fe, u32* ber) 332{ 333 struct ves1x93_state* state = fe->demodulator_priv; 334 335 *ber = ves1x93_readreg (state, 0x15); 336 *ber |= (ves1x93_readreg (state, 0x16) << 8); 337 *ber |= ((ves1x93_readreg (state, 0x17) & 0x0F) << 16); 338 *ber *= 10; 339 340 return 0; 341} 342 343static int ves1x93_read_signal_strength(struct dvb_frontend* fe, u16* strength) 344{ 345 struct ves1x93_state* state = fe->demodulator_priv; 346 347 u8 signal = ~ves1x93_readreg (state, 0x0b); 348 *strength = (signal << 8) | signal; 349 350 return 0; 351} 352 353static int ves1x93_read_snr(struct dvb_frontend* fe, u16* snr) 354{ 355 struct ves1x93_state* state = fe->demodulator_priv; 356 357 u8 _snr = ~ves1x93_readreg (state, 0x1c); 358 *snr = (_snr << 8) | _snr; 359 360 return 0; 361} 362 363static int ves1x93_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) 364{ 365 struct ves1x93_state* state = fe->demodulator_priv; 366 367 *ucblocks = ves1x93_readreg (state, 0x18) & 0x7f; 368 369 if (*ucblocks == 0x7f) 370 *ucblocks = 0xffffffff; /* counter overflow... */ 371 372 ves1x93_writereg (state, 0x18, 0x00); /* reset the counter */ 373 ves1x93_writereg (state, 0x18, 0x80); /* dto. */ 374 375 return 0; 376} 377 378static int ves1x93_set_frontend(struct dvb_frontend *fe) 379{ 380 struct dtv_frontend_properties *p = &fe->dtv_property_cache; 381 struct ves1x93_state* state = fe->demodulator_priv; 382 383 if (fe->ops.tuner_ops.set_params) { 384 fe->ops.tuner_ops.set_params(fe); 385 if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); 386 } 387 ves1x93_set_inversion (state, p->inversion); 388 ves1x93_set_fec(state, p->fec_inner); 389 ves1x93_set_symbolrate(state, p->symbol_rate); 390 state->inversion = p->inversion; 391 state->frequency = p->frequency; 392 393 return 0; 394} 395 396static int ves1x93_get_frontend(struct dvb_frontend *fe, 397 struct dtv_frontend_properties *p) 398{ 399 struct ves1x93_state* state = fe->demodulator_priv; 400 int afc; 401 402 afc = ((int)((char)(ves1x93_readreg (state, 0x0a) << 1)))/2; 403 afc = (afc * (int)(p->symbol_rate/1000/8))/16; 404 405 p->frequency = state->frequency - afc; 406 407 /* 408 * inversion indicator is only valid 409 * if auto inversion was used 410 */ 411 if (state->inversion == INVERSION_AUTO) 412 p->inversion = (ves1x93_readreg (state, 0x0f) & 2) ? 413 INVERSION_OFF : INVERSION_ON; 414 p->fec_inner = ves1x93_get_fec(state); 415 /* XXX FIXME: timing offset !! */ 416 417 return 0; 418} 419 420static int ves1x93_sleep(struct dvb_frontend* fe) 421{ 422 struct ves1x93_state* state = fe->demodulator_priv; 423 424 return ves1x93_writereg (state, 0x00, 0x08); 425} 426 427static void ves1x93_release(struct dvb_frontend* fe) 428{ 429 struct ves1x93_state* state = fe->demodulator_priv; 430 kfree(state); 431} 432 433static int ves1x93_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) 434{ 435 struct ves1x93_state* state = fe->demodulator_priv; 436 437 if (enable) { 438 return ves1x93_writereg(state, 0x00, 0x11); 439 } else { 440 return ves1x93_writereg(state, 0x00, 0x01); 441 } 442} 443 444static const struct dvb_frontend_ops ves1x93_ops; 445 446struct dvb_frontend* ves1x93_attach(const struct ves1x93_config* config, 447 struct i2c_adapter* i2c) 448{ 449 struct ves1x93_state* state = NULL; 450 u8 identity; 451 452 /* allocate memory for the internal state */ 453 state = kzalloc(sizeof(struct ves1x93_state), GFP_KERNEL); 454 if (state == NULL) goto error; 455 456 /* setup the state */ 457 state->config = config; 458 state->i2c = i2c; 459 state->inversion = INVERSION_OFF; 460 461 /* check if the demod is there + identify it */ 462 identity = ves1x93_readreg(state, 0x1e); 463 switch (identity) { 464 case 0xdc: /* VES1893A rev1 */ 465 printk("ves1x93: Detected ves1893a rev1\n"); 466 state->demod_type = DEMOD_VES1893; 467 state->init_1x93_tab = init_1893_tab; 468 state->init_1x93_wtab = init_1893_wtab; 469 state->tab_size = sizeof(init_1893_tab); 470 break; 471 472 case 0xdd: /* VES1893A rev2 */ 473 printk("ves1x93: Detected ves1893a rev2\n"); 474 state->demod_type = DEMOD_VES1893; 475 state->init_1x93_tab = init_1893_tab; 476 state->init_1x93_wtab = init_1893_wtab; 477 state->tab_size = sizeof(init_1893_tab); 478 break; 479 480 case 0xde: /* VES1993 */ 481 printk("ves1x93: Detected ves1993\n"); 482 state->demod_type = DEMOD_VES1993; 483 state->init_1x93_tab = init_1993_tab; 484 state->init_1x93_wtab = init_1993_wtab; 485 state->tab_size = sizeof(init_1993_tab); 486 break; 487 488 default: 489 goto error; 490 } 491 492 /* create dvb_frontend */ 493 memcpy(&state->frontend.ops, &ves1x93_ops, sizeof(struct dvb_frontend_ops)); 494 state->frontend.demodulator_priv = state; 495 return &state->frontend; 496 497error: 498 kfree(state); 499 return NULL; 500} 501 502static const struct dvb_frontend_ops ves1x93_ops = { 503 .delsys = { SYS_DVBS }, 504 .info = { 505 .name = "VLSI VES1x93 DVB-S", 506 .frequency_min_hz = 950 * MHz, 507 .frequency_max_hz = 2150 * MHz, 508 .frequency_stepsize_hz = 125 * kHz, 509 .frequency_tolerance_hz = 29500 * kHz, 510 .symbol_rate_min = 1000000, 511 .symbol_rate_max = 45000000, 512 /* .symbol_rate_tolerance = ???,*/ 513 .caps = FE_CAN_INVERSION_AUTO | 514 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | 515 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | 516 FE_CAN_QPSK 517 }, 518 519 .release = ves1x93_release, 520 521 .init = ves1x93_init, 522 .sleep = ves1x93_sleep, 523 .i2c_gate_ctrl = ves1x93_i2c_gate_ctrl, 524 525 .set_frontend = ves1x93_set_frontend, 526 .get_frontend = ves1x93_get_frontend, 527 528 .read_status = ves1x93_read_status, 529 .read_ber = ves1x93_read_ber, 530 .read_signal_strength = ves1x93_read_signal_strength, 531 .read_snr = ves1x93_read_snr, 532 .read_ucblocks = ves1x93_read_ucblocks, 533 534 .set_voltage = ves1x93_set_voltage, 535}; 536 537module_param(debug, int, 0644); 538 539MODULE_DESCRIPTION("VLSI VES1x93 DVB-S Demodulator driver"); 540MODULE_AUTHOR("Ralph Metzler"); 541MODULE_LICENSE("GPL"); 542 543EXPORT_SYMBOL(ves1x93_attach);