linux/drivers/media/dvb-frontends/sp8870.c
<<
>>
Prefs
   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, &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
 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);
 610