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 "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                default:
 542                        return -EINVAL;
 543        }
 544        cmd.ACQUIRE0.OFFSET = 0;
 545        cmd.ACQUIRE0.NTSCSWEEP = 1;
 546        cmd.ACQUIRE0.FA = 1;
 547        cmd.ACQUIRE0.BW = 0;
 548
 549/*      if (enableOffset) {
 550                cmd.IF_OFFSET0 = xx;
 551                cmd.IF_OFFSET1 = xx;
 552
 553                cmd.SYM_OFFSET0 = xx;
 554                cmd.SYM_OFFSET1 = xx;
 555                if (enableNtscSweep) {
 556                        cmd.NTSC_OFFSET0;
 557                        cmd.NTSC_OFFSET1;
 558                }
 559        } */
 560        bcm3510_do_hab_cmd(st, CMD_ACQUIRE, MSGID_EXT_TUNER_ACQUIRE, (u8 *) &cmd, sizeof(cmd), NULL, 0);
 561
 562/* doing it with different MSGIDs, data book and source differs */
 563        bert.BE = 0;
 564        bert.unused = 0;
 565        bcm3510_do_hab_cmd(st, CMD_STATE_CONTROL, MSGID_BERT_CONTROL, (u8 *) &bert, sizeof(bert), NULL, 0);
 566        bcm3510_do_hab_cmd(st, CMD_STATE_CONTROL, MSGID_BERT_SET, (u8 *) &bert, sizeof(bert), NULL, 0);
 567
 568        bcm3510_bert_reset(st);
 569
 570        ret = bcm3510_set_freq(st, c->frequency);
 571        if (ret < 0)
 572                return ret;
 573
 574        memset(&st->status1,0,sizeof(st->status1));
 575        memset(&st->status2,0,sizeof(st->status2));
 576        st->status_check_interval = 500;
 577
 578/* Give the AP some time */
 579        msleep(200);
 580
 581        return 0;
 582}
 583
 584static int bcm3510_sleep(struct dvb_frontend* fe)
 585{
 586        return 0;
 587}
 588
 589static int bcm3510_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *s)
 590{
 591        s->min_delay_ms = 1000;
 592        s->step_size = 0;
 593        s->max_drift = 0;
 594        return 0;
 595}
 596
 597static void bcm3510_release(struct dvb_frontend* fe)
 598{
 599        struct bcm3510_state* state = fe->demodulator_priv;
 600        kfree(state);
 601}
 602
 603/* firmware download:
 604 * firmware file is build up like this:
 605 * 16bit addr, 16bit length, 8byte of length
 606 */
 607#define BCM3510_DEFAULT_FIRMWARE "dvb-fe-bcm3510-01.fw"
 608
 609static int bcm3510_write_ram(struct bcm3510_state *st, u16 addr, const u8 *b,
 610                             u16 len)
 611{
 612        int ret = 0,i;
 613        bcm3510_register_value vH, vL,vD;
 614
 615        vH.MADRH_a9 = addr >> 8;
 616        vL.MADRL_aa = addr;
 617        if ((ret = bcm3510_writeB(st,0xa9,vH)) < 0) return ret;
 618        if ((ret = bcm3510_writeB(st,0xaa,vL)) < 0) return ret;
 619
 620        for (i = 0; i < len; i++) {
 621                vD.MDATA_ab = b[i];
 622                if ((ret = bcm3510_writeB(st,0xab,vD)) < 0)
 623                        return ret;
 624        }
 625
 626        return 0;
 627}
 628
 629static int bcm3510_download_firmware(struct dvb_frontend* fe)
 630{
 631        struct bcm3510_state* st = fe->demodulator_priv;
 632        const struct firmware *fw;
 633        u16 addr,len;
 634        const u8 *b;
 635        int ret,i;
 636
 637        deb_info("requesting firmware\n");
 638        if ((ret = st->config->request_firmware(fe, &fw, BCM3510_DEFAULT_FIRMWARE)) < 0) {
 639                err("could not load firmware (%s): %d",BCM3510_DEFAULT_FIRMWARE,ret);
 640                return ret;
 641        }
 642        deb_info("got firmware: %zu\n", fw->size);
 643
 644        b = fw->data;
 645        for (i = 0; i < fw->size;) {
 646                addr = le16_to_cpu(*((__le16 *)&b[i]));
 647                len  = le16_to_cpu(*((__le16 *)&b[i+2]));
 648                deb_info("firmware chunk, addr: 0x%04x, len: 0x%04x, total length: 0x%04zx\n",addr,len,fw->size);
 649                if ((ret = bcm3510_write_ram(st,addr,&b[i+4],len)) < 0) {
 650                        err("firmware download failed: %d\n",ret);
 651                        return ret;
 652                }
 653                i += 4 + len;
 654        }
 655        release_firmware(fw);
 656        deb_info("firmware download successfully completed\n");
 657        return 0;
 658}
 659
 660static int bcm3510_check_firmware_version(struct bcm3510_state *st)
 661{
 662        struct bcm3510_hab_cmd_get_version_info ver;
 663        bcm3510_do_hab_cmd(st,CMD_GET_VERSION_INFO,MSGID_GET_VERSION_INFO,NULL,0,(u8*)&ver,sizeof(ver));
 664
 665        deb_info("Version information: 0x%02x 0x%02x 0x%02x 0x%02x\n",
 666                ver.microcode_version, ver.script_version, ver.config_version, ver.demod_version);
 667
 668        if (ver.script_version == BCM3510_DEF_SCRIPT_VERSION &&
 669                ver.config_version == BCM3510_DEF_CONFIG_VERSION &&
 670                ver.demod_version  == BCM3510_DEF_DEMOD_VERSION)
 671                return 0;
 672
 673        deb_info("version check failed\n");
 674        return -ENODEV;
 675}
 676
 677/* (un)resetting the AP */
 678static int bcm3510_reset(struct bcm3510_state *st)
 679{
 680        int ret;
 681        unsigned long  t;
 682        bcm3510_register_value v;
 683
 684        bcm3510_readB(st,0xa0,&v); v.HCTL1_a0.RESET = 1;
 685        if ((ret = bcm3510_writeB(st,0xa0,v)) < 0)
 686                return ret;
 687
 688        t = jiffies + 3*HZ;
 689        while (time_before(jiffies, t)) {
 690                msleep(10);
 691                if ((ret = bcm3510_readB(st,0xa2,&v)) < 0)
 692                        return ret;
 693
 694                if (v.APSTAT1_a2.RESET)
 695                        return 0;
 696        }
 697        deb_info("reset timed out\n");
 698        return -ETIMEDOUT;
 699}
 700
 701static int bcm3510_clear_reset(struct bcm3510_state *st)
 702{
 703        bcm3510_register_value v;
 704        int ret;
 705        unsigned long t;
 706
 707        v.raw = 0;
 708        if ((ret = bcm3510_writeB(st,0xa0,v)) < 0)
 709                return ret;
 710
 711        t = jiffies + 3*HZ;
 712        while (time_before(jiffies, t)) {
 713                msleep(10);
 714                if ((ret = bcm3510_readB(st,0xa2,&v)) < 0)
 715                        return ret;
 716
 717                /* verify that reset is cleared */
 718                if (!v.APSTAT1_a2.RESET)
 719                        return 0;
 720        }
 721        deb_info("reset clear timed out\n");
 722        return -ETIMEDOUT;
 723}
 724
 725static int bcm3510_init_cold(struct bcm3510_state *st)
 726{
 727        int ret;
 728        bcm3510_register_value v;
 729
 730        /* read Acquisation Processor status register and check it is not in RUN mode */
 731        if ((ret = bcm3510_readB(st,0xa2,&v)) < 0)
 732                return ret;
 733        if (v.APSTAT1_a2.RUN) {
 734                deb_info("AP is already running - firmware already loaded.\n");
 735                return 0;
 736        }
 737
 738        deb_info("reset?\n");
 739        if ((ret = bcm3510_reset(st)) < 0)
 740                return ret;
 741
 742        deb_info("tristate?\n");
 743        /* tri-state */
 744        v.TSTCTL_2e.CTL = 0;
 745        if ((ret = bcm3510_writeB(st,0x2e,v)) < 0)
 746                return ret;
 747
 748        deb_info("firmware?\n");
 749        if ((ret = bcm3510_download_firmware(&st->frontend)) < 0 ||
 750                (ret = bcm3510_clear_reset(st)) < 0)
 751                return ret;
 752
 753        /* anything left here to Let the acquisition processor begin execution at program counter 0000 ??? */
 754
 755        return 0;
 756}
 757
 758static int bcm3510_init(struct dvb_frontend* fe)
 759{
 760        struct bcm3510_state* st = fe->demodulator_priv;
 761        bcm3510_register_value j;
 762        struct bcm3510_hab_cmd_set_agc c;
 763        int ret;
 764
 765        if ((ret = bcm3510_readB(st,0xca,&j)) < 0)
 766                return ret;
 767
 768        deb_info("JDEC: %02x\n",j.raw);
 769
 770        switch (j.JDEC_ca.JDEC) {
 771                case JDEC_WAIT_AT_RAM:
 772                        deb_info("attempting to download firmware\n");
 773                        if ((ret = bcm3510_init_cold(st)) < 0)
 774                                return ret;
 775                case JDEC_EEPROM_LOAD_WAIT: /* fall-through is wanted */
 776                        deb_info("firmware is loaded\n");
 777                        bcm3510_check_firmware_version(st);
 778                        break;
 779                default:
 780                        return -ENODEV;
 781        }
 782
 783        memset(&c,0,1);
 784        c.SEL = 1;
 785        bcm3510_do_hab_cmd(st,CMD_AUTO_PARAM,MSGID_SET_RF_AGC_SEL,(u8 *)&c,sizeof(c),NULL,0);
 786
 787        return 0;
 788}
 789
 790
 791static struct dvb_frontend_ops bcm3510_ops;
 792
 793struct dvb_frontend* bcm3510_attach(const struct bcm3510_config *config,
 794                                   struct i2c_adapter *i2c)
 795{
 796        struct bcm3510_state* state = NULL;
 797        int ret;
 798        bcm3510_register_value v;
 799
 800        /* allocate memory for the internal state */
 801        state = kzalloc(sizeof(struct bcm3510_state), GFP_KERNEL);
 802        if (state == NULL)
 803                goto error;
 804
 805        /* setup the state */
 806
 807        state->config = config;
 808        state->i2c = i2c;
 809
 810        /* create dvb_frontend */
 811        memcpy(&state->frontend.ops, &bcm3510_ops, sizeof(struct dvb_frontend_ops));
 812        state->frontend.demodulator_priv = state;
 813
 814        mutex_init(&state->hab_mutex);
 815
 816        if ((ret = bcm3510_readB(state,0xe0,&v)) < 0)
 817                goto error;
 818
 819        deb_info("Revision: 0x%1x, Layer: 0x%1x.\n",v.REVID_e0.REV,v.REVID_e0.LAYER);
 820
 821        if ((v.REVID_e0.REV != 0x1 && v.REVID_e0.LAYER != 0xb) && /* cold */
 822                (v.REVID_e0.REV != 0x8 && v.REVID_e0.LAYER != 0x0))   /* warm */
 823                goto error;
 824
 825        info("Revision: 0x%1x, Layer: 0x%1x.",v.REVID_e0.REV,v.REVID_e0.LAYER);
 826
 827        bcm3510_reset(state);
 828
 829        return &state->frontend;
 830
 831error:
 832        kfree(state);
 833        return NULL;
 834}
 835EXPORT_SYMBOL(bcm3510_attach);
 836
 837static struct dvb_frontend_ops bcm3510_ops = {
 838        .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B },
 839        .info = {
 840                .name = "Broadcom BCM3510 VSB/QAM frontend",
 841                .frequency_min =  54000000,
 842                .frequency_max = 803000000,
 843                /* stepsize is just a guess */
 844                .frequency_stepsize = 0,
 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