linux/drivers/media/dvb-frontends/bcm3510.c
<<
>>
Prefs
   1/*
   2 * Support for the Broadcom BCM3510 ATSC demodulator (1st generation Air2PC)
   3 *
   4 *  Copyright (C) 2001-5, B2C2 inc.
   5 *
   6 *  GPL/Linux driver written by Patrick Boettcher <patrick.boettcher@posteo.de>
   7 *
   8 *  This driver is "hard-coded" to be used with the 1st generation of
   9 *  Technisat/B2C2's Air2PC ATSC PCI/USB cards/boxes. The pll-programming
  10 *  (Panasonic CT10S) is located here, which is actually wrong. Unless there is
  11 *  another device with a BCM3510, this is no problem.
  12 *
  13 *  The driver works also with QAM64 DVB-C, but had an unreasonable high
  14 *  UNC. (Tested with the Air2PC ATSC 1st generation)
  15 *
  16 *  You'll need a firmware for this driver in order to get it running. It is
  17 *  called "dvb-fe-bcm3510-01.fw".
  18 *
  19 * This program is free software; you can redistribute it and/or modify it
  20 * under the terms of the GNU General Public License as published by the Free
  21 * Software Foundation; either version 2 of the License, or (at your option)
  22 * any later version.
  23 *
  24 * This program is distributed in the hope that it will be useful, but WITHOUT
  25 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  26 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  27 * more details.
  28 *
  29 * You should have received a copy of the GNU General Public License along with
  30 * this program; if not, write to the Free Software Foundation, Inc., 675 Mass
  31 * Ave, Cambridge, MA 02139, USA.
  32 */
  33
  34#include <linux/init.h>
  35#include <linux/module.h>
  36#include <linux/device.h>
  37#include <linux/firmware.h>
  38#include <linux/jiffies.h>
  39#include <linux/string.h>
  40#include <linux/slab.h>
  41#include <linux/mutex.h>
  42
  43#include <media/dvb_frontend.h>
  44#include "bcm3510.h"
  45#include "bcm3510_priv.h"
  46
  47/* Max transfer size done by bcm3510_do_hab_cmd() function */
  48#define MAX_XFER_SIZE   128
  49
  50struct bcm3510_state {
  51
  52        struct i2c_adapter* i2c;
  53        const struct bcm3510_config* config;
  54        struct dvb_frontend frontend;
  55
  56        /* demodulator private data */
  57        struct mutex hab_mutex;
  58        u8 firmware_loaded:1;
  59
  60        unsigned long next_status_check;
  61        unsigned long status_check_interval;
  62        struct bcm3510_hab_cmd_status1 status1;
  63        struct bcm3510_hab_cmd_status2 status2;
  64};
  65
  66static int debug;
  67module_param(debug, int, 0644);
  68MODULE_PARM_DESC(debug, "set debugging level (1=info,2=i2c (|-able)).");
  69
  70#define dprintk(level,x...) if (level & debug) printk(x)
  71#define dbufout(b,l,m) {\
  72            int i; \
  73            for (i = 0; i < l; i++) \
  74                m("%02x ",b[i]); \
  75}
  76#define deb_info(args...) dprintk(0x01,args)
  77#define deb_i2c(args...)  dprintk(0x02,args)
  78#define deb_hab(args...)  dprintk(0x04,args)
  79
  80/* transfer functions */
  81static int bcm3510_writebytes (struct bcm3510_state *state, u8 reg, u8 *buf, u8 len)
  82{
  83        u8 b[256];
  84        int err;
  85        struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = b, .len = len + 1 };
  86
  87        b[0] = reg;
  88        memcpy(&b[1],buf,len);
  89
  90        deb_i2c("i2c wr %02x: ",reg);
  91        dbufout(buf,len,deb_i2c);
  92        deb_i2c("\n");
  93
  94        if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
  95
  96                deb_info("%s: i2c write error (addr %02x, reg %02x, err == %i)\n",
  97                        __func__, state->config->demod_address, reg,  err);
  98                return -EREMOTEIO;
  99        }
 100
 101        return 0;
 102}
 103
 104static int bcm3510_readbytes (struct bcm3510_state *state, u8 reg, u8 *buf, u8 len)
 105{
 106        struct i2c_msg msg[] = {
 107                { .addr = state->config->demod_address, .flags = 0,        .buf = &reg, .len = 1 },
 108                { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = buf,  .len = len }
 109        };
 110        int err;
 111
 112        memset(buf,0,len);
 113
 114        if ((err = i2c_transfer (state->i2c, msg, 2)) != 2) {
 115                deb_info("%s: i2c read error (addr %02x, reg %02x, err == %i)\n",
 116                        __func__, state->config->demod_address, reg,  err);
 117                return -EREMOTEIO;
 118        }
 119        deb_i2c("i2c rd %02x: ",reg);
 120        dbufout(buf,len,deb_i2c);
 121        deb_i2c("\n");
 122
 123        return 0;
 124}
 125
 126static int bcm3510_writeB(struct bcm3510_state *state, u8 reg, bcm3510_register_value v)
 127{
 128        return bcm3510_writebytes(state,reg,&v.raw,1);
 129}
 130
 131static int bcm3510_readB(struct bcm3510_state *state, u8 reg, bcm3510_register_value *v)
 132{
 133        return bcm3510_readbytes(state,reg,&v->raw,1);
 134}
 135
 136/* Host Access Buffer transfers */
 137static int bcm3510_hab_get_response(struct bcm3510_state *st, u8 *buf, int len)
 138{
 139        bcm3510_register_value v;
 140        int ret,i;
 141
 142        v.HABADR_a6.HABADR = 0;
 143        if ((ret = bcm3510_writeB(st,0xa6,v)) < 0)
 144                return ret;
 145
 146        for (i = 0; i < len; i++) {
 147                if ((ret = bcm3510_readB(st,0xa7,&v)) < 0)
 148                        return ret;
 149                buf[i] = v.HABDATA_a7;
 150        }
 151        return 0;
 152}
 153
 154static int bcm3510_hab_send_request(struct bcm3510_state *st, u8 *buf, int len)
 155{
 156        bcm3510_register_value v,hab;
 157        int ret,i;
 158        unsigned long t;
 159
 160/* Check if any previous HAB request still needs to be serviced by the
 161 * Acquisition Processor before sending new request */
 162        if ((ret = bcm3510_readB(st,0xa8,&v)) < 0)
 163                return ret;
 164        if (v.HABSTAT_a8.HABR) {
 165                deb_info("HAB is running already - clearing it.\n");
 166                v.HABSTAT_a8.HABR = 0;
 167                bcm3510_writeB(st,0xa8,v);
 168//              return -EBUSY;
 169        }
 170
 171/* Send the start HAB Address (automatically incremented after write of
 172 * HABDATA) and write the HAB Data */
 173        hab.HABADR_a6.HABADR = 0;
 174        if ((ret = bcm3510_writeB(st,0xa6,hab)) < 0)
 175                return ret;
 176
 177        for (i = 0; i < len; i++) {
 178                hab.HABDATA_a7 = buf[i];
 179                if ((ret = bcm3510_writeB(st,0xa7,hab)) < 0)
 180                        return ret;
 181        }
 182
 183/* Set the HABR bit to indicate AP request in progress (LBHABR allows HABR to
 184 * be written) */
 185        v.raw = 0; v.HABSTAT_a8.HABR = 1; v.HABSTAT_a8.LDHABR = 1;
 186        if ((ret = bcm3510_writeB(st,0xa8,v)) < 0)
 187                return ret;
 188
 189/* Polling method: Wait until the AP finishes processing the HAB request */
 190        t = jiffies + 1*HZ;
 191        while (time_before(jiffies, t)) {
 192                deb_info("waiting for HAB to complete\n");
 193                msleep(10);
 194                if ((ret = bcm3510_readB(st,0xa8,&v)) < 0)
 195                        return ret;
 196
 197                if (!v.HABSTAT_a8.HABR)
 198                        return 0;
 199        }
 200
 201        deb_info("send_request execution timed out.\n");
 202        return -ETIMEDOUT;
 203}
 204
 205static int bcm3510_do_hab_cmd(struct bcm3510_state *st, u8 cmd, u8 msgid, u8 *obuf, u8 olen, u8 *ibuf, u8 ilen)
 206{
 207        u8 ob[MAX_XFER_SIZE], ib[MAX_XFER_SIZE];
 208        int ret = 0;
 209
 210        if (ilen + 2 > sizeof(ib)) {
 211                deb_hab("do_hab_cmd: ilen=%d is too big!\n", ilen);
 212                return -EINVAL;
 213        }
 214
 215        if (olen + 2 > sizeof(ob)) {
 216                deb_hab("do_hab_cmd: olen=%d is too big!\n", olen);
 217                return -EINVAL;
 218        }
 219
 220        ob[0] = cmd;
 221        ob[1] = msgid;
 222        memcpy(&ob[2],obuf,olen);
 223
 224        deb_hab("hab snd: ");
 225        dbufout(ob,olen+2,deb_hab);
 226        deb_hab("\n");
 227
 228        if (mutex_lock_interruptible(&st->hab_mutex) < 0)
 229                return -EAGAIN;
 230
 231        if ((ret = bcm3510_hab_send_request(st, ob, olen+2)) < 0 ||
 232                (ret = bcm3510_hab_get_response(st, ib, ilen+2)) < 0)
 233                goto error;
 234
 235        deb_hab("hab get: ");
 236        dbufout(ib,ilen+2,deb_hab);
 237        deb_hab("\n");
 238
 239        memcpy(ibuf,&ib[2],ilen);
 240error:
 241        mutex_unlock(&st->hab_mutex);
 242        return ret;
 243}
 244
 245#if 0
 246/* not needed, we use a semaphore to prevent HAB races */
 247static int bcm3510_is_ap_ready(struct bcm3510_state *st)
 248{
 249        bcm3510_register_value ap,hab;
 250        int ret;
 251
 252        if ((ret = bcm3510_readB(st,0xa8,&hab)) < 0 ||
 253                (ret = bcm3510_readB(st,0xa2,&ap) < 0))
 254                return ret;
 255
 256        if (ap.APSTAT1_a2.RESET || ap.APSTAT1_a2.IDLE || ap.APSTAT1_a2.STOP || hab.HABSTAT_a8.HABR) {
 257                deb_info("AP is busy\n");
 258                return -EBUSY;
 259        }
 260
 261        return 0;
 262}
 263#endif
 264
 265static int bcm3510_bert_reset(struct bcm3510_state *st)
 266{
 267        bcm3510_register_value b;
 268        int ret;
 269
 270        if ((ret = bcm3510_readB(st,0xfa,&b)) < 0)
 271                return ret;
 272
 273        b.BERCTL_fa.RESYNC = 0; bcm3510_writeB(st,0xfa,b);
 274        b.BERCTL_fa.RESYNC = 1; bcm3510_writeB(st,0xfa,b);
 275        b.BERCTL_fa.RESYNC = 0; bcm3510_writeB(st,0xfa,b);
 276        b.BERCTL_fa.CNTCTL = 1; b.BERCTL_fa.BITCNT = 1; bcm3510_writeB(st,0xfa,b);
 277
 278        /* clear residual bit counter TODO  */
 279        return 0;
 280}
 281
 282static int bcm3510_refresh_state(struct bcm3510_state *st)
 283{
 284        if (time_after(jiffies,st->next_status_check)) {
 285                bcm3510_do_hab_cmd(st, CMD_STATUS, MSGID_STATUS1, NULL,0, (u8 *)&st->status1, sizeof(st->status1));
 286                bcm3510_do_hab_cmd(st, CMD_STATUS, MSGID_STATUS2, NULL,0, (u8 *)&st->status2, sizeof(st->status2));
 287                st->next_status_check = jiffies + (st->status_check_interval*HZ)/1000;
 288        }
 289        return 0;
 290}
 291
 292static int bcm3510_read_status(struct dvb_frontend *fe, enum fe_status *status)
 293{
 294        struct bcm3510_state* st = fe->demodulator_priv;
 295        bcm3510_refresh_state(st);
 296
 297        *status = 0;
 298        if (st->status1.STATUS1.RECEIVER_LOCK)
 299                *status |= FE_HAS_LOCK | FE_HAS_SYNC;
 300
 301        if (st->status1.STATUS1.FEC_LOCK)
 302                *status |= FE_HAS_VITERBI;
 303
 304        if (st->status1.STATUS1.OUT_PLL_LOCK)
 305                *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER;
 306
 307        if (*status & FE_HAS_LOCK)
 308                st->status_check_interval = 1500;
 309        else /* more frequently checks if no lock has been achieved yet */
 310                st->status_check_interval = 500;
 311
 312        deb_info("real_status: %02x\n",*status);
 313        return 0;
 314}
 315
 316static int bcm3510_read_ber(struct dvb_frontend* fe, u32* ber)
 317{
 318        struct bcm3510_state* st = fe->demodulator_priv;
 319        bcm3510_refresh_state(st);
 320
 321        *ber = (st->status2.LDBER0 << 16) | (st->status2.LDBER1 << 8) | st->status2.LDBER2;
 322        return 0;
 323}
 324
 325static int bcm3510_read_unc(struct dvb_frontend* fe, u32* unc)
 326{
 327        struct bcm3510_state* st = fe->demodulator_priv;
 328        bcm3510_refresh_state(st);
 329        *unc = (st->status2.LDUERC0 << 8) | st->status2.LDUERC1;
 330        return 0;
 331}
 332
 333static int bcm3510_read_signal_strength(struct dvb_frontend* fe, u16* strength)
 334{
 335        struct bcm3510_state* st = fe->demodulator_priv;
 336        s32 t;
 337
 338        bcm3510_refresh_state(st);
 339        t = st->status2.SIGNAL;
 340
 341        if (t > 190)
 342                t = 190;
 343        if (t < 90)
 344                t = 90;
 345
 346        t -= 90;
 347        t = t * 0xff / 100;
 348        /* normalize if necessary */
 349        *strength = (t << 8) | t;
 350        return 0;
 351}
 352
 353static int bcm3510_read_snr(struct dvb_frontend* fe, u16* snr)
 354{
 355        struct bcm3510_state* st = fe->demodulator_priv;
 356        bcm3510_refresh_state(st);
 357
 358        *snr = st->status1.SNR_EST0*1000 + ((st->status1.SNR_EST1*1000) >> 8);
 359        return 0;
 360}
 361
 362/* tuner frontend programming */
 363static int bcm3510_tuner_cmd(struct bcm3510_state* st,u8 bc, u16 n, u8 a)
 364{
 365        struct bcm3510_hab_cmd_tune c;
 366        memset(&c,0,sizeof(struct bcm3510_hab_cmd_tune));
 367
 368/* I2C Mode disabled,  set 16 control / Data pairs */
 369        c.length = 0x10;
 370        c.clock_width = 0;
 371/* CS1, CS0, DATA, CLK bits control the tuner RF_AGC_SEL pin is set to
 372 * logic high (as Configuration) */
 373        c.misc = 0x10;
 374/* Set duration of the initial state of TUNCTL = 3.34 micro Sec */
 375        c.TUNCTL_state = 0x40;
 376
 377/* PRESCALER DIVIDE RATIO | BC1_2_3_4; (band switch), 1stosc REFERENCE COUNTER REF_S12 and REF_S11 */
 378        c.ctl_dat[0].ctrl.size = BITS_8;
 379        c.ctl_dat[0].data      = 0x80 | bc;
 380
 381/* Control DATA pin, 1stosc REFERENCE COUNTER REF_S10 to REF_S3 */
 382        c.ctl_dat[1].ctrl.size = BITS_8;
 383        c.ctl_dat[1].data      = 4;
 384
 385/* set CONTROL BIT 1 to 1, 1stosc REFERENCE COUNTER REF_S2 to REF_S1 */
 386        c.ctl_dat[2].ctrl.size = BITS_3;
 387        c.ctl_dat[2].data      = 0x20;
 388
 389/* control CS0 pin, pulse byte ? */
 390        c.ctl_dat[3].ctrl.size = BITS_3;
 391        c.ctl_dat[3].ctrl.clk_off = 1;
 392        c.ctl_dat[3].ctrl.cs0  = 1;
 393        c.ctl_dat[3].data      = 0x40;
 394
 395/* PGM_S18 to PGM_S11 */
 396        c.ctl_dat[4].ctrl.size = BITS_8;
 397        c.ctl_dat[4].data      = n >> 3;
 398
 399/* PGM_S10 to PGM_S8, SWL_S7 to SWL_S3 */
 400        c.ctl_dat[5].ctrl.size = BITS_8;
 401        c.ctl_dat[5].data      = ((n & 0x7) << 5) | (a >> 2);
 402
 403/* SWL_S2 and SWL_S1, set CONTROL BIT 2 to 0 */
 404        c.ctl_dat[6].ctrl.size = BITS_3;
 405        c.ctl_dat[6].data      = (a << 6) & 0xdf;
 406
 407/* control CS0 pin, pulse byte ? */
 408        c.ctl_dat[7].ctrl.size = BITS_3;
 409        c.ctl_dat[7].ctrl.clk_off = 1;
 410        c.ctl_dat[7].ctrl.cs0  = 1;
 411        c.ctl_dat[7].data      = 0x40;
 412
 413/* PRESCALER DIVIDE RATIO, 2ndosc REFERENCE COUNTER REF_S12 and REF_S11 */
 414        c.ctl_dat[8].ctrl.size = BITS_8;
 415        c.ctl_dat[8].data      = 0x80;
 416
 417/* 2ndosc REFERENCE COUNTER REF_S10 to REF_S3 */
 418        c.ctl_dat[9].ctrl.size = BITS_8;
 419        c.ctl_dat[9].data      = 0x10;
 420
 421/* set CONTROL BIT 1 to 1, 2ndosc REFERENCE COUNTER REF_S2 to REF_S1 */
 422        c.ctl_dat[10].ctrl.size = BITS_3;
 423        c.ctl_dat[10].data      = 0x20;
 424
 425/* pulse byte */
 426        c.ctl_dat[11].ctrl.size = BITS_3;
 427        c.ctl_dat[11].ctrl.clk_off = 1;
 428        c.ctl_dat[11].ctrl.cs1  = 1;
 429        c.ctl_dat[11].data      = 0x40;
 430
 431/* PGM_S18 to PGM_S11 */
 432        c.ctl_dat[12].ctrl.size = BITS_8;
 433        c.ctl_dat[12].data      = 0x2a;
 434
 435/* PGM_S10 to PGM_S8 and SWL_S7 to SWL_S3 */
 436        c.ctl_dat[13].ctrl.size = BITS_8;
 437        c.ctl_dat[13].data      = 0x8e;
 438
 439/* SWL_S2 and SWL_S1 and set CONTROL BIT 2 to 0 */
 440        c.ctl_dat[14].ctrl.size = BITS_3;
 441        c.ctl_dat[14].data      = 0;
 442
 443/* Pulse Byte */
 444        c.ctl_dat[15].ctrl.size = BITS_3;
 445        c.ctl_dat[15].ctrl.clk_off = 1;
 446        c.ctl_dat[15].ctrl.cs1  = 1;
 447        c.ctl_dat[15].data      = 0x40;
 448
 449        return bcm3510_do_hab_cmd(st,CMD_TUNE, MSGID_TUNE,(u8 *) &c,sizeof(c), NULL, 0);
 450}
 451
 452static int bcm3510_set_freq(struct bcm3510_state* st,u32 freq)
 453{
 454        u8 bc,a;
 455        u16 n;
 456        s32 YIntercept,Tfvco1;
 457
 458        freq /= 1000;
 459
 460        deb_info("%dkHz:",freq);
 461        /* set Band Switch */
 462        if (freq <= 168000)
 463                bc = 0x1c;
 464        else if (freq <= 378000)
 465                bc = 0x2c;
 466        else
 467                bc = 0x30;
 468
 469        if (freq >= 470000) {
 470                freq -= 470001;
 471                YIntercept = 18805;
 472        } else if (freq >= 90000) {
 473                freq -= 90001;
 474                YIntercept = 15005;
 475        } else if (freq >= 76000){
 476                freq -= 76001;
 477                YIntercept = 14865;
 478        } else {
 479                freq -= 54001;
 480                YIntercept = 14645;
 481        }
 482
 483        Tfvco1 = (((freq/6000)*60 + YIntercept)*4)/10;
 484
 485        n = Tfvco1 >> 6;
 486        a = Tfvco1 & 0x3f;
 487
 488        deb_info(" BC1_2_3_4: %x, N: %x A: %x\n", bc, n, a);
 489        if (n >= 16 && n <= 2047)
 490                return bcm3510_tuner_cmd(st,bc,n,a);
 491
 492        return -EINVAL;
 493}
 494
 495static int bcm3510_set_frontend(struct dvb_frontend *fe)
 496{
 497        struct dtv_frontend_properties *c = &fe->dtv_property_cache;
 498        struct bcm3510_state* st = fe->demodulator_priv;
 499        struct bcm3510_hab_cmd_ext_acquire cmd;
 500        struct bcm3510_hab_cmd_bert_control bert;
 501        int ret;
 502
 503        memset(&cmd,0,sizeof(cmd));
 504        switch (c->modulation) {
 505                case QAM_256:
 506                        cmd.ACQUIRE0.MODE = 0x1;
 507                        cmd.ACQUIRE1.SYM_RATE = 0x1;
 508                        cmd.ACQUIRE1.IF_FREQ = 0x1;
 509                        break;
 510                case QAM_64:
 511                        cmd.ACQUIRE0.MODE = 0x2;
 512                        cmd.ACQUIRE1.SYM_RATE = 0x2;
 513                        cmd.ACQUIRE1.IF_FREQ = 0x1;
 514                        break;
 515#if 0
 516                case QAM_256:
 517                        cmd.ACQUIRE0.MODE = 0x3;
 518                        break;
 519                case QAM_128:
 520                        cmd.ACQUIRE0.MODE = 0x4;
 521                        break;
 522                case QAM_64:
 523                        cmd.ACQUIRE0.MODE = 0x5;
 524                        break;
 525                case QAM_32:
 526                        cmd.ACQUIRE0.MODE = 0x6;
 527                        break;
 528                case QAM_16:
 529                        cmd.ACQUIRE0.MODE = 0x7;
 530                        break;
 531#endif
 532                case VSB_8:
 533                        cmd.ACQUIRE0.MODE = 0x8;
 534                        cmd.ACQUIRE1.SYM_RATE = 0x0;
 535                        cmd.ACQUIRE1.IF_FREQ = 0x0;
 536                        break;
 537                case VSB_16:
 538                        cmd.ACQUIRE0.MODE = 0x9;
 539                        cmd.ACQUIRE1.SYM_RATE = 0x0;
 540                        cmd.ACQUIRE1.IF_FREQ = 0x0;
 541                        break;
 542                default:
 543                        return -EINVAL;
 544        }
 545        cmd.ACQUIRE0.OFFSET = 0;
 546        cmd.ACQUIRE0.NTSCSWEEP = 1;
 547        cmd.ACQUIRE0.FA = 1;
 548        cmd.ACQUIRE0.BW = 0;
 549
 550/*      if (enableOffset) {
 551                cmd.IF_OFFSET0 = xx;
 552                cmd.IF_OFFSET1 = xx;
 553
 554                cmd.SYM_OFFSET0 = xx;
 555                cmd.SYM_OFFSET1 = xx;
 556                if (enableNtscSweep) {
 557                        cmd.NTSC_OFFSET0;
 558                        cmd.NTSC_OFFSET1;
 559                }
 560        } */
 561        bcm3510_do_hab_cmd(st, CMD_ACQUIRE, MSGID_EXT_TUNER_ACQUIRE, (u8 *) &cmd, sizeof(cmd), NULL, 0);
 562
 563/* doing it with different MSGIDs, data book and source differs */
 564        bert.BE = 0;
 565        bert.unused = 0;
 566        bcm3510_do_hab_cmd(st, CMD_STATE_CONTROL, MSGID_BERT_CONTROL, (u8 *) &bert, sizeof(bert), NULL, 0);
 567        bcm3510_do_hab_cmd(st, CMD_STATE_CONTROL, MSGID_BERT_SET, (u8 *) &bert, sizeof(bert), NULL, 0);
 568
 569        bcm3510_bert_reset(st);
 570
 571        ret = bcm3510_set_freq(st, c->frequency);
 572        if (ret < 0)
 573                return ret;
 574
 575        memset(&st->status1,0,sizeof(st->status1));
 576        memset(&st->status2,0,sizeof(st->status2));
 577        st->status_check_interval = 500;
 578
 579/* Give the AP some time */
 580        msleep(200);
 581
 582        return 0;
 583}
 584
 585static int bcm3510_sleep(struct dvb_frontend* fe)
 586{
 587        return 0;
 588}
 589
 590static int bcm3510_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *s)
 591{
 592        s->min_delay_ms = 1000;
 593        s->step_size = 0;
 594        s->max_drift = 0;
 595        return 0;
 596}
 597
 598static void bcm3510_release(struct dvb_frontend* fe)
 599{
 600        struct bcm3510_state* state = fe->demodulator_priv;
 601        kfree(state);
 602}
 603
 604/* firmware download:
 605 * firmware file is build up like this:
 606 * 16bit addr, 16bit length, 8byte of length
 607 */
 608#define BCM3510_DEFAULT_FIRMWARE "dvb-fe-bcm3510-01.fw"
 609
 610static int bcm3510_write_ram(struct bcm3510_state *st, u16 addr, const u8 *b,
 611                             u16 len)
 612{
 613        int ret = 0,i;
 614        bcm3510_register_value vH, vL,vD;
 615
 616        vH.MADRH_a9 = addr >> 8;
 617        vL.MADRL_aa = addr;
 618        if ((ret = bcm3510_writeB(st,0xa9,vH)) < 0) return ret;
 619        if ((ret = bcm3510_writeB(st,0xaa,vL)) < 0) return ret;
 620
 621        for (i = 0; i < len; i++) {
 622                vD.MDATA_ab = b[i];
 623                if ((ret = bcm3510_writeB(st,0xab,vD)) < 0)
 624                        return ret;
 625        }
 626
 627        return 0;
 628}
 629
 630static int bcm3510_download_firmware(struct dvb_frontend* fe)
 631{
 632        struct bcm3510_state* st = fe->demodulator_priv;
 633        const struct firmware *fw;
 634        u16 addr,len;
 635        const u8 *b;
 636        int ret,i;
 637
 638        deb_info("requesting firmware\n");
 639        if ((ret = st->config->request_firmware(fe, &fw, BCM3510_DEFAULT_FIRMWARE)) < 0) {
 640                err("could not load firmware (%s): %d",BCM3510_DEFAULT_FIRMWARE,ret);
 641                return ret;
 642        }
 643        deb_info("got firmware: %zu\n", fw->size);
 644
 645        b = fw->data;
 646        for (i = 0; i < fw->size;) {
 647                addr = le16_to_cpu(*((__le16 *)&b[i]));
 648                len  = le16_to_cpu(*((__le16 *)&b[i+2]));
 649                deb_info("firmware chunk, addr: 0x%04x, len: 0x%04x, total length: 0x%04zx\n",addr,len,fw->size);
 650                if ((ret = bcm3510_write_ram(st,addr,&b[i+4],len)) < 0) {
 651                        err("firmware download failed: %d\n",ret);
 652                        return ret;
 653                }
 654                i += 4 + len;
 655        }
 656        release_firmware(fw);
 657        deb_info("firmware download successfully completed\n");
 658        return 0;
 659}
 660
 661static int bcm3510_check_firmware_version(struct bcm3510_state *st)
 662{
 663        struct bcm3510_hab_cmd_get_version_info ver;
 664        bcm3510_do_hab_cmd(st,CMD_GET_VERSION_INFO,MSGID_GET_VERSION_INFO,NULL,0,(u8*)&ver,sizeof(ver));
 665
 666        deb_info("Version information: 0x%02x 0x%02x 0x%02x 0x%02x\n",
 667                ver.microcode_version, ver.script_version, ver.config_version, ver.demod_version);
 668
 669        if (ver.script_version == BCM3510_DEF_SCRIPT_VERSION &&
 670                ver.config_version == BCM3510_DEF_CONFIG_VERSION &&
 671                ver.demod_version  == BCM3510_DEF_DEMOD_VERSION)
 672                return 0;
 673
 674        deb_info("version check failed\n");
 675        return -ENODEV;
 676}
 677
 678/* (un)resetting the AP */
 679static int bcm3510_reset(struct bcm3510_state *st)
 680{
 681        int ret;
 682        unsigned long  t;
 683        bcm3510_register_value v;
 684
 685        bcm3510_readB(st,0xa0,&v); v.HCTL1_a0.RESET = 1;
 686        if ((ret = bcm3510_writeB(st,0xa0,v)) < 0)
 687                return ret;
 688
 689        t = jiffies + 3*HZ;
 690        while (time_before(jiffies, t)) {
 691                msleep(10);
 692                if ((ret = bcm3510_readB(st,0xa2,&v)) < 0)
 693                        return ret;
 694
 695                if (v.APSTAT1_a2.RESET)
 696                        return 0;
 697        }
 698        deb_info("reset timed out\n");
 699        return -ETIMEDOUT;
 700}
 701
 702static int bcm3510_clear_reset(struct bcm3510_state *st)
 703{
 704        bcm3510_register_value v;
 705        int ret;
 706        unsigned long t;
 707
 708        v.raw = 0;
 709        if ((ret = bcm3510_writeB(st,0xa0,v)) < 0)
 710                return ret;
 711
 712        t = jiffies + 3*HZ;
 713        while (time_before(jiffies, t)) {
 714                msleep(10);
 715                if ((ret = bcm3510_readB(st,0xa2,&v)) < 0)
 716                        return ret;
 717
 718                /* verify that reset is cleared */
 719                if (!v.APSTAT1_a2.RESET)
 720                        return 0;
 721        }
 722        deb_info("reset clear timed out\n");
 723        return -ETIMEDOUT;
 724}
 725
 726static int bcm3510_init_cold(struct bcm3510_state *st)
 727{
 728        int ret;
 729        bcm3510_register_value v;
 730
 731        /* read Acquisation Processor status register and check it is not in RUN mode */
 732        if ((ret = bcm3510_readB(st,0xa2,&v)) < 0)
 733                return ret;
 734        if (v.APSTAT1_a2.RUN) {
 735                deb_info("AP is already running - firmware already loaded.\n");
 736                return 0;
 737        }
 738
 739        deb_info("reset?\n");
 740        if ((ret = bcm3510_reset(st)) < 0)
 741                return ret;
 742
 743        deb_info("tristate?\n");
 744        /* tri-state */
 745        v.TSTCTL_2e.CTL = 0;
 746        if ((ret = bcm3510_writeB(st,0x2e,v)) < 0)
 747                return ret;
 748
 749        deb_info("firmware?\n");
 750        if ((ret = bcm3510_download_firmware(&st->frontend)) < 0 ||
 751                (ret = bcm3510_clear_reset(st)) < 0)
 752                return ret;
 753
 754        /* anything left here to Let the acquisition processor begin execution at program counter 0000 ??? */
 755
 756        return 0;
 757}
 758
 759static int bcm3510_init(struct dvb_frontend* fe)
 760{
 761        struct bcm3510_state* st = fe->demodulator_priv;
 762        bcm3510_register_value j;
 763        struct bcm3510_hab_cmd_set_agc c;
 764        int ret;
 765
 766        if ((ret = bcm3510_readB(st,0xca,&j)) < 0)
 767                return ret;
 768
 769        deb_info("JDEC: %02x\n",j.raw);
 770
 771        switch (j.JDEC_ca.JDEC) {
 772                case JDEC_WAIT_AT_RAM:
 773                        deb_info("attempting to download firmware\n");
 774                        if ((ret = bcm3510_init_cold(st)) < 0)
 775                                return ret;
 776                        fallthrough;
 777                case JDEC_EEPROM_LOAD_WAIT:
 778                        deb_info("firmware is loaded\n");
 779                        bcm3510_check_firmware_version(st);
 780                        break;
 781                default:
 782                        return -ENODEV;
 783        }
 784
 785        memset(&c,0,1);
 786        c.SEL = 1;
 787        bcm3510_do_hab_cmd(st,CMD_AUTO_PARAM,MSGID_SET_RF_AGC_SEL,(u8 *)&c,sizeof(c),NULL,0);
 788
 789        return 0;
 790}
 791
 792
 793static const struct dvb_frontend_ops bcm3510_ops;
 794
 795struct dvb_frontend* bcm3510_attach(const struct bcm3510_config *config,
 796                                   struct i2c_adapter *i2c)
 797{
 798        struct bcm3510_state* state = NULL;
 799        int ret;
 800        bcm3510_register_value v;
 801
 802        /* allocate memory for the internal state */
 803        state = kzalloc(sizeof(struct bcm3510_state), GFP_KERNEL);
 804        if (state == NULL)
 805                goto error;
 806
 807        /* setup the state */
 808
 809        state->config = config;
 810        state->i2c = i2c;
 811
 812        /* create dvb_frontend */
 813        memcpy(&state->frontend.ops, &bcm3510_ops, sizeof(struct dvb_frontend_ops));
 814        state->frontend.demodulator_priv = state;
 815
 816        mutex_init(&state->hab_mutex);
 817
 818        if ((ret = bcm3510_readB(state,0xe0,&v)) < 0)
 819                goto error;
 820
 821        deb_info("Revision: 0x%1x, Layer: 0x%1x.\n",v.REVID_e0.REV,v.REVID_e0.LAYER);
 822
 823        if ((v.REVID_e0.REV != 0x1 && v.REVID_e0.LAYER != 0xb) && /* cold */
 824                (v.REVID_e0.REV != 0x8 && v.REVID_e0.LAYER != 0x0))   /* warm */
 825                goto error;
 826
 827        info("Revision: 0x%1x, Layer: 0x%1x.",v.REVID_e0.REV,v.REVID_e0.LAYER);
 828
 829        bcm3510_reset(state);
 830
 831        return &state->frontend;
 832
 833error:
 834        kfree(state);
 835        return NULL;
 836}
 837EXPORT_SYMBOL(bcm3510_attach);
 838
 839static const struct dvb_frontend_ops bcm3510_ops = {
 840        .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B },
 841        .info = {
 842                .name = "Broadcom BCM3510 VSB/QAM frontend",
 843                .frequency_min_hz =  54 * MHz,
 844                .frequency_max_hz = 803 * MHz,
 845                .caps =
 846                        FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
 847                        FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
 848                        FE_CAN_8VSB | FE_CAN_16VSB |
 849                        FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_128 | FE_CAN_QAM_256
 850        },
 851
 852        .release = bcm3510_release,
 853
 854        .init = bcm3510_init,
 855        .sleep = bcm3510_sleep,
 856
 857        .set_frontend = bcm3510_set_frontend,
 858        .get_tune_settings = bcm3510_get_tune_settings,
 859
 860        .read_status = bcm3510_read_status,
 861        .read_ber = bcm3510_read_ber,
 862        .read_signal_strength = bcm3510_read_signal_strength,
 863        .read_snr = bcm3510_read_snr,
 864        .read_ucblocks = bcm3510_read_unc,
 865};
 866
 867MODULE_DESCRIPTION("Broadcom BCM3510 ATSC (8VSB/16VSB & ITU J83 AnnexB FEC QAM64/256) demodulator driver");
 868MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@posteo.de>");
 869MODULE_LICENSE("GPL");
 870