sp8870.c (14092B)
1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 Driver for Spase SP8870 demodulator 4 5 Copyright (C) 1999 Juergen Peitz 6 7 8*/ 9/* 10 * This driver needs external firmware. Please use the command 11 * "<kerneldir>/scripts/get_dvb_firmware alps_tdlb7" to 12 * download/extract it, and then copy it to /usr/lib/hotplug/firmware 13 * or /lib/firmware (depending on configuration of firmware hotplug). 14 */ 15#define SP8870_DEFAULT_FIRMWARE "dvb-fe-sp8870.fw" 16 17#include <linux/init.h> 18#include <linux/module.h> 19#include <linux/device.h> 20#include <linux/firmware.h> 21#include <linux/delay.h> 22#include <linux/string.h> 23#include <linux/slab.h> 24 25#include <media/dvb_frontend.h> 26#include "sp8870.h" 27 28 29struct sp8870_state { 30 31 struct i2c_adapter* i2c; 32 33 const struct sp8870_config* config; 34 35 struct dvb_frontend frontend; 36 37 /* demodulator private data */ 38 u8 initialised:1; 39}; 40 41static int debug; 42#define dprintk(args...) \ 43 do { \ 44 if (debug) printk(KERN_DEBUG "sp8870: " args); \ 45 } while (0) 46 47/* firmware size for sp8870 */ 48#define SP8870_FIRMWARE_SIZE 16382 49 50/* starting point for firmware in file 'Sc_main.mc' */ 51#define SP8870_FIRMWARE_OFFSET 0x0A 52 53static int sp8870_writereg (struct sp8870_state* state, u16 reg, u16 data) 54{ 55 u8 buf [] = { reg >> 8, reg & 0xff, data >> 8, data & 0xff }; 56 struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 4 }; 57 int err; 58 59 if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) { 60 dprintk ("%s: writereg error (err == %i, reg == 0x%02x, data == 0x%02x)\n", __func__, err, reg, data); 61 return -EREMOTEIO; 62 } 63 64 return 0; 65} 66 67static int sp8870_readreg (struct sp8870_state* state, u16 reg) 68{ 69 int ret; 70 u8 b0 [] = { reg >> 8 , reg & 0xff }; 71 u8 b1 [] = { 0, 0 }; 72 struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 2 }, 73 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 2 } }; 74 75 ret = i2c_transfer (state->i2c, msg, 2); 76 77 if (ret != 2) { 78 dprintk("%s: readreg error (ret == %i)\n", __func__, ret); 79 return -1; 80 } 81 82 return (b1[0] << 8 | b1[1]); 83} 84 85static int sp8870_firmware_upload (struct sp8870_state* state, const struct firmware *fw) 86{ 87 struct i2c_msg msg; 88 const char *fw_buf = fw->data; 89 int fw_pos; 90 u8 tx_buf[255]; 91 int tx_len; 92 int err = 0; 93 94 dprintk ("%s: ...\n", __func__); 95 96 if (fw->size < SP8870_FIRMWARE_SIZE + SP8870_FIRMWARE_OFFSET) 97 return -EINVAL; 98 99 // system controller stop 100 sp8870_writereg(state, 0x0F00, 0x0000); 101 102 // instruction RAM register hiword 103 sp8870_writereg(state, 0x8F08, ((SP8870_FIRMWARE_SIZE / 2) & 0xFFFF)); 104 105 // instruction RAM MWR 106 sp8870_writereg(state, 0x8F0A, ((SP8870_FIRMWARE_SIZE / 2) >> 16)); 107 108 // do firmware upload 109 fw_pos = SP8870_FIRMWARE_OFFSET; 110 while (fw_pos < SP8870_FIRMWARE_SIZE + SP8870_FIRMWARE_OFFSET){ 111 tx_len = (fw_pos <= SP8870_FIRMWARE_SIZE + SP8870_FIRMWARE_OFFSET - 252) ? 252 : SP8870_FIRMWARE_SIZE + SP8870_FIRMWARE_OFFSET - fw_pos; 112 // write register 0xCF0A 113 tx_buf[0] = 0xCF; 114 tx_buf[1] = 0x0A; 115 memcpy(&tx_buf[2], fw_buf + fw_pos, tx_len); 116 msg.addr = state->config->demod_address; 117 msg.flags = 0; 118 msg.buf = tx_buf; 119 msg.len = tx_len + 2; 120 if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) { 121 printk("%s: firmware upload failed!\n", __func__); 122 printk ("%s: i2c error (err == %i)\n", __func__, err); 123 return err; 124 } 125 fw_pos += tx_len; 126 } 127 128 dprintk ("%s: done!\n", __func__); 129 return 0; 130}; 131 132static void sp8870_microcontroller_stop (struct sp8870_state* state) 133{ 134 sp8870_writereg(state, 0x0F08, 0x000); 135 sp8870_writereg(state, 0x0F09, 0x000); 136 137 // microcontroller STOP 138 sp8870_writereg(state, 0x0F00, 0x000); 139} 140 141static void sp8870_microcontroller_start (struct sp8870_state* state) 142{ 143 sp8870_writereg(state, 0x0F08, 0x000); 144 sp8870_writereg(state, 0x0F09, 0x000); 145 146 // microcontroller START 147 sp8870_writereg(state, 0x0F00, 0x001); 148 // not documented but if we don't read 0x0D01 out here 149 // we don't get a correct data valid signal 150 sp8870_readreg(state, 0x0D01); 151} 152 153static int sp8870_read_data_valid_signal(struct sp8870_state* state) 154{ 155 return (sp8870_readreg(state, 0x0D02) > 0); 156} 157 158static int configure_reg0xc05 (struct dtv_frontend_properties *p, u16 *reg0xc05) 159{ 160 int known_parameters = 1; 161 162 *reg0xc05 = 0x000; 163 164 switch (p->modulation) { 165 case QPSK: 166 break; 167 case QAM_16: 168 *reg0xc05 |= (1 << 10); 169 break; 170 case QAM_64: 171 *reg0xc05 |= (2 << 10); 172 break; 173 case QAM_AUTO: 174 known_parameters = 0; 175 break; 176 default: 177 return -EINVAL; 178 } 179 180 switch (p->hierarchy) { 181 case HIERARCHY_NONE: 182 break; 183 case HIERARCHY_1: 184 *reg0xc05 |= (1 << 7); 185 break; 186 case HIERARCHY_2: 187 *reg0xc05 |= (2 << 7); 188 break; 189 case HIERARCHY_4: 190 *reg0xc05 |= (3 << 7); 191 break; 192 case HIERARCHY_AUTO: 193 known_parameters = 0; 194 break; 195 default: 196 return -EINVAL; 197 } 198 199 switch (p->code_rate_HP) { 200 case FEC_1_2: 201 break; 202 case FEC_2_3: 203 *reg0xc05 |= (1 << 3); 204 break; 205 case FEC_3_4: 206 *reg0xc05 |= (2 << 3); 207 break; 208 case FEC_5_6: 209 *reg0xc05 |= (3 << 3); 210 break; 211 case FEC_7_8: 212 *reg0xc05 |= (4 << 3); 213 break; 214 case FEC_AUTO: 215 known_parameters = 0; 216 break; 217 default: 218 return -EINVAL; 219 } 220 221 if (known_parameters) 222 *reg0xc05 |= (2 << 1); /* use specified parameters */ 223 else 224 *reg0xc05 |= (1 << 1); /* enable autoprobing */ 225 226 return 0; 227} 228 229static int sp8870_wake_up(struct sp8870_state* state) 230{ 231 // enable TS output and interface pins 232 return sp8870_writereg(state, 0xC18, 0x00D); 233} 234 235static int sp8870_set_frontend_parameters(struct dvb_frontend *fe) 236{ 237 struct dtv_frontend_properties *p = &fe->dtv_property_cache; 238 struct sp8870_state* state = fe->demodulator_priv; 239 int err; 240 u16 reg0xc05; 241 242 if ((err = configure_reg0xc05(p, ®0xc05))) 243 return err; 244 245 // system controller stop 246 sp8870_microcontroller_stop(state); 247 248 // set tuner parameters 249 if (fe->ops.tuner_ops.set_params) { 250 fe->ops.tuner_ops.set_params(fe); 251 if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); 252 } 253 254 // sample rate correction bit [23..17] 255 sp8870_writereg(state, 0x0319, 0x000A); 256 257 // sample rate correction bit [16..0] 258 sp8870_writereg(state, 0x031A, 0x0AAB); 259 260 // integer carrier offset 261 sp8870_writereg(state, 0x0309, 0x0400); 262 263 // fractional carrier offset 264 sp8870_writereg(state, 0x030A, 0x0000); 265 266 // filter for 6/7/8 Mhz channel 267 if (p->bandwidth_hz == 6000000) 268 sp8870_writereg(state, 0x0311, 0x0002); 269 else if (p->bandwidth_hz == 7000000) 270 sp8870_writereg(state, 0x0311, 0x0001); 271 else 272 sp8870_writereg(state, 0x0311, 0x0000); 273 274 // scan order: 2k first = 0x0000, 8k first = 0x0001 275 if (p->transmission_mode == TRANSMISSION_MODE_2K) 276 sp8870_writereg(state, 0x0338, 0x0000); 277 else 278 sp8870_writereg(state, 0x0338, 0x0001); 279 280 sp8870_writereg(state, 0xc05, reg0xc05); 281 282 // read status reg in order to clear pending irqs 283 err = sp8870_readreg(state, 0x200); 284 if (err < 0) 285 return err; 286 287 // system controller start 288 sp8870_microcontroller_start(state); 289 290 return 0; 291} 292 293static int sp8870_init (struct dvb_frontend* fe) 294{ 295 struct sp8870_state* state = fe->demodulator_priv; 296 const struct firmware *fw = NULL; 297 298 sp8870_wake_up(state); 299 if (state->initialised) return 0; 300 state->initialised = 1; 301 302 dprintk ("%s\n", __func__); 303 304 305 /* request the firmware, this will block until someone uploads it */ 306 printk("sp8870: waiting for firmware upload (%s)...\n", SP8870_DEFAULT_FIRMWARE); 307 if (state->config->request_firmware(fe, &fw, SP8870_DEFAULT_FIRMWARE)) { 308 printk("sp8870: no firmware upload (timeout or file not found?)\n"); 309 return -EIO; 310 } 311 312 if (sp8870_firmware_upload(state, fw)) { 313 printk("sp8870: writing firmware to device failed\n"); 314 release_firmware(fw); 315 return -EIO; 316 } 317 release_firmware(fw); 318 printk("sp8870: firmware upload complete\n"); 319 320 /* enable TS output and interface pins */ 321 sp8870_writereg(state, 0xc18, 0x00d); 322 323 // system controller stop 324 sp8870_microcontroller_stop(state); 325 326 // ADC mode 327 sp8870_writereg(state, 0x0301, 0x0003); 328 329 // Reed Solomon parity bytes passed to output 330 sp8870_writereg(state, 0x0C13, 0x0001); 331 332 // MPEG clock is suppressed if no valid data 333 sp8870_writereg(state, 0x0C14, 0x0001); 334 335 /* bit 0x010: enable data valid signal */ 336 sp8870_writereg(state, 0x0D00, 0x010); 337 sp8870_writereg(state, 0x0D01, 0x000); 338 339 return 0; 340} 341 342static int sp8870_read_status(struct dvb_frontend *fe, 343 enum fe_status *fe_status) 344{ 345 struct sp8870_state* state = fe->demodulator_priv; 346 int status; 347 int signal; 348 349 *fe_status = 0; 350 351 status = sp8870_readreg (state, 0x0200); 352 if (status < 0) 353 return -EIO; 354 355 signal = sp8870_readreg (state, 0x0303); 356 if (signal < 0) 357 return -EIO; 358 359 if (signal > 0x0F) 360 *fe_status |= FE_HAS_SIGNAL; 361 if (status & 0x08) 362 *fe_status |= FE_HAS_SYNC; 363 if (status & 0x04) 364 *fe_status |= FE_HAS_LOCK | FE_HAS_CARRIER | FE_HAS_VITERBI; 365 366 return 0; 367} 368 369static int sp8870_read_ber (struct dvb_frontend* fe, u32 * ber) 370{ 371 struct sp8870_state* state = fe->demodulator_priv; 372 int ret; 373 u32 tmp; 374 375 *ber = 0; 376 377 ret = sp8870_readreg(state, 0xC08); 378 if (ret < 0) 379 return -EIO; 380 381 tmp = ret & 0x3F; 382 383 ret = sp8870_readreg(state, 0xC07); 384 if (ret < 0) 385 return -EIO; 386 387 tmp = ret << 6; 388 if (tmp >= 0x3FFF0) 389 tmp = ~0; 390 391 *ber = tmp; 392 393 return 0; 394} 395 396static int sp8870_read_signal_strength(struct dvb_frontend* fe, u16 * signal) 397{ 398 struct sp8870_state* state = fe->demodulator_priv; 399 int ret; 400 u16 tmp; 401 402 *signal = 0; 403 404 ret = sp8870_readreg (state, 0x306); 405 if (ret < 0) 406 return -EIO; 407 408 tmp = ret << 8; 409 410 ret = sp8870_readreg (state, 0x303); 411 if (ret < 0) 412 return -EIO; 413 414 tmp |= ret; 415 416 if (tmp) 417 *signal = 0xFFFF - tmp; 418 419 return 0; 420} 421 422static int sp8870_read_uncorrected_blocks (struct dvb_frontend* fe, u32* ublocks) 423{ 424 struct sp8870_state* state = fe->demodulator_priv; 425 int ret; 426 427 *ublocks = 0; 428 429 ret = sp8870_readreg(state, 0xC0C); 430 if (ret < 0) 431 return -EIO; 432 433 if (ret == 0xFFFF) 434 ret = ~0; 435 436 *ublocks = ret; 437 438 return 0; 439} 440 441/* number of trials to recover from lockup */ 442#define MAXTRIALS 5 443/* maximum checks for data valid signal */ 444#define MAXCHECKS 100 445 446/* only for debugging: counter for detected lockups */ 447static int lockups; 448/* only for debugging: counter for channel switches */ 449static int switches; 450 451static int sp8870_set_frontend(struct dvb_frontend *fe) 452{ 453 struct dtv_frontend_properties *p = &fe->dtv_property_cache; 454 struct sp8870_state* state = fe->demodulator_priv; 455 456 /* 457 The firmware of the sp8870 sometimes locks up after setting frontend parameters. 458 We try to detect this by checking the data valid signal. 459 If it is not set after MAXCHECKS we try to recover the lockup by setting 460 the frontend parameters again. 461 */ 462 463 int err = 0; 464 int valid = 0; 465 int trials = 0; 466 int check_count = 0; 467 468 dprintk("%s: frequency = %i\n", __func__, p->frequency); 469 470 for (trials = 1; trials <= MAXTRIALS; trials++) { 471 472 err = sp8870_set_frontend_parameters(fe); 473 if (err) 474 return err; 475 476 for (check_count = 0; check_count < MAXCHECKS; check_count++) { 477// valid = ((sp8870_readreg(i2c, 0x0200) & 4) == 0); 478 valid = sp8870_read_data_valid_signal(state); 479 if (valid) { 480 dprintk("%s: delay = %i usec\n", 481 __func__, check_count * 10); 482 break; 483 } 484 udelay(10); 485 } 486 if (valid) 487 break; 488 } 489 490 if (!valid) { 491 printk("%s: firmware crash!!!!!!\n", __func__); 492 return -EIO; 493 } 494 495 if (debug) { 496 if (valid) { 497 if (trials > 1) { 498 printk("%s: firmware lockup!!!\n", __func__); 499 printk("%s: recovered after %i trial(s))\n", __func__, trials - 1); 500 lockups++; 501 } 502 } 503 switches++; 504 printk("%s: switches = %i lockups = %i\n", __func__, switches, lockups); 505 } 506 507 return 0; 508} 509 510static int sp8870_sleep(struct dvb_frontend* fe) 511{ 512 struct sp8870_state* state = fe->demodulator_priv; 513 514 // tristate TS output and disable interface pins 515 return sp8870_writereg(state, 0xC18, 0x000); 516} 517 518static int sp8870_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings) 519{ 520 fesettings->min_delay_ms = 350; 521 fesettings->step_size = 0; 522 fesettings->max_drift = 0; 523 return 0; 524} 525 526static int sp8870_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) 527{ 528 struct sp8870_state* state = fe->demodulator_priv; 529 530 if (enable) { 531 return sp8870_writereg(state, 0x206, 0x001); 532 } else { 533 return sp8870_writereg(state, 0x206, 0x000); 534 } 535} 536 537static void sp8870_release(struct dvb_frontend* fe) 538{ 539 struct sp8870_state* state = fe->demodulator_priv; 540 kfree(state); 541} 542 543static const struct dvb_frontend_ops sp8870_ops; 544 545struct dvb_frontend* sp8870_attach(const struct sp8870_config* config, 546 struct i2c_adapter* i2c) 547{ 548 struct sp8870_state* state = NULL; 549 550 /* allocate memory for the internal state */ 551 state = kzalloc(sizeof(struct sp8870_state), GFP_KERNEL); 552 if (state == NULL) goto error; 553 554 /* setup the state */ 555 state->config = config; 556 state->i2c = i2c; 557 state->initialised = 0; 558 559 /* check if the demod is there */ 560 if (sp8870_readreg(state, 0x0200) < 0) goto error; 561 562 /* create dvb_frontend */ 563 memcpy(&state->frontend.ops, &sp8870_ops, sizeof(struct dvb_frontend_ops)); 564 state->frontend.demodulator_priv = state; 565 return &state->frontend; 566 567error: 568 kfree(state); 569 return NULL; 570} 571 572static const struct dvb_frontend_ops sp8870_ops = { 573 .delsys = { SYS_DVBT }, 574 .info = { 575 .name = "Spase SP8870 DVB-T", 576 .frequency_min_hz = 470 * MHz, 577 .frequency_max_hz = 860 * MHz, 578 .frequency_stepsize_hz = 166666, 579 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | 580 FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | 581 FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | 582 FE_CAN_QPSK | FE_CAN_QAM_16 | 583 FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | 584 FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER 585 }, 586 587 .release = sp8870_release, 588 589 .init = sp8870_init, 590 .sleep = sp8870_sleep, 591 .i2c_gate_ctrl = sp8870_i2c_gate_ctrl, 592 593 .set_frontend = sp8870_set_frontend, 594 .get_tune_settings = sp8870_get_tune_settings, 595 596 .read_status = sp8870_read_status, 597 .read_ber = sp8870_read_ber, 598 .read_signal_strength = sp8870_read_signal_strength, 599 .read_ucblocks = sp8870_read_uncorrected_blocks, 600}; 601 602module_param(debug, int, 0644); 603MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); 604 605MODULE_DESCRIPTION("Spase SP8870 DVB-T Demodulator driver"); 606MODULE_AUTHOR("Juergen Peitz"); 607MODULE_LICENSE("GPL"); 608 609EXPORT_SYMBOL(sp8870_attach);