cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

bcm3510.c (22219B)


      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");