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