root/drivers/media/dvb-frontends/sp8870.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. sp8870_writereg
  2. sp8870_readreg
  3. sp8870_firmware_upload
  4. sp8870_microcontroller_stop
  5. sp8870_microcontroller_start
  6. sp8870_read_data_valid_signal
  7. configure_reg0xc05
  8. sp8870_wake_up
  9. sp8870_set_frontend_parameters
  10. sp8870_init
  11. sp8870_read_status
  12. sp8870_read_ber
  13. sp8870_read_signal_strength
  14. sp8870_read_uncorrected_blocks
  15. sp8870_set_frontend
  16. sp8870_sleep
  17. sp8870_get_tune_settings
  18. sp8870_i2c_gate_ctrl
  19. sp8870_release
  20. sp8870_attach

   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 
  29 struct 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 
  41 static 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 
  53 static 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 
  67 static 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 
  85 static 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 
 132 static 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 
 141 static 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 
 153 static int sp8870_read_data_valid_signal(struct sp8870_state* state)
 154 {
 155         return (sp8870_readreg(state, 0x0D02) > 0);
 156 }
 157 
 158 static 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 
 229 static 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 
 235 static 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, &reg0xc05)))
 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)
 285                 return err;
 286 
 287         // system controller start
 288         sp8870_microcontroller_start(state);
 289 
 290         return 0;
 291 }
 292 
 293 static 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 
 342 static 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 
 369 static 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 
 396 static 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 
 422 static 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 */
 447 static int lockups;
 448 /* only for debugging: counter for channel switches */
 449 static int switches;
 450 
 451 static 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 
 510 static 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 
 518 static 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 
 526 static 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 
 537 static void sp8870_release(struct dvb_frontend* fe)
 538 {
 539         struct sp8870_state* state = fe->demodulator_priv;
 540         kfree(state);
 541 }
 542 
 543 static const struct dvb_frontend_ops sp8870_ops;
 544 
 545 struct 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 
 567 error:
 568         kfree(state);
 569         return NULL;
 570 }
 571 
 572 static 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 
 602 module_param(debug, int, 0644);
 603 MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
 604 
 605 MODULE_DESCRIPTION("Spase SP8870 DVB-T Demodulator driver");
 606 MODULE_AUTHOR("Juergen Peitz");
 607 MODULE_LICENSE("GPL");
 608 
 609 EXPORT_SYMBOL(sp8870_attach);

/* [<][>][^][v][top][bottom][index][help] */