0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034 #include <linux/init.h>
0035 #include <linux/module.h>
0036 #include <linux/device.h>
0037 #include <linux/firmware.h>
0038 #include <linux/jiffies.h>
0039 #include <linux/string.h>
0040 #include <linux/slab.h>
0041 #include <linux/mutex.h>
0042
0043 #include <media/dvb_frontend.h>
0044 #include "bcm3510.h"
0045 #include "bcm3510_priv.h"
0046
0047
0048 #define MAX_XFER_SIZE 128
0049
0050 struct bcm3510_state {
0051
0052 struct i2c_adapter* i2c;
0053 const struct bcm3510_config* config;
0054 struct dvb_frontend frontend;
0055
0056
0057 struct mutex hab_mutex;
0058 u8 firmware_loaded:1;
0059
0060 unsigned long next_status_check;
0061 unsigned long status_check_interval;
0062 struct bcm3510_hab_cmd_status1 status1;
0063 struct bcm3510_hab_cmd_status2 status2;
0064 };
0065
0066 static int debug;
0067 module_param(debug, int, 0644);
0068 MODULE_PARM_DESC(debug, "set debugging level (1=info,2=i2c (|-able)).");
0069
0070 #define dprintk(level,x...) if (level & debug) printk(x)
0071 #define dbufout(b,l,m) {\
0072 int i; \
0073 for (i = 0; i < l; i++) \
0074 m("%02x ",b[i]); \
0075 }
0076 #define deb_info(args...) dprintk(0x01,args)
0077 #define deb_i2c(args...) dprintk(0x02,args)
0078 #define deb_hab(args...) dprintk(0x04,args)
0079
0080
0081 static int bcm3510_writebytes (struct bcm3510_state *state, u8 reg, u8 *buf, u8 len)
0082 {
0083 u8 b[256];
0084 int err;
0085 struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = b, .len = len + 1 };
0086
0087 b[0] = reg;
0088 memcpy(&b[1],buf,len);
0089
0090 deb_i2c("i2c wr %02x: ",reg);
0091 dbufout(buf,len,deb_i2c);
0092 deb_i2c("\n");
0093
0094 if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
0095
0096 deb_info("%s: i2c write error (addr %02x, reg %02x, err == %i)\n",
0097 __func__, state->config->demod_address, reg, err);
0098 return -EREMOTEIO;
0099 }
0100
0101 return 0;
0102 }
0103
0104 static int bcm3510_readbytes (struct bcm3510_state *state, u8 reg, u8 *buf, u8 len)
0105 {
0106 struct i2c_msg msg[] = {
0107 { .addr = state->config->demod_address, .flags = 0, .buf = ®, .len = 1 },
0108 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = buf, .len = len }
0109 };
0110 int err;
0111
0112 memset(buf,0,len);
0113
0114 if ((err = i2c_transfer (state->i2c, msg, 2)) != 2) {
0115 deb_info("%s: i2c read error (addr %02x, reg %02x, err == %i)\n",
0116 __func__, state->config->demod_address, reg, err);
0117 return -EREMOTEIO;
0118 }
0119 deb_i2c("i2c rd %02x: ",reg);
0120 dbufout(buf,len,deb_i2c);
0121 deb_i2c("\n");
0122
0123 return 0;
0124 }
0125
0126 static int bcm3510_writeB(struct bcm3510_state *state, u8 reg, bcm3510_register_value v)
0127 {
0128 return bcm3510_writebytes(state,reg,&v.raw,1);
0129 }
0130
0131 static int bcm3510_readB(struct bcm3510_state *state, u8 reg, bcm3510_register_value *v)
0132 {
0133 return bcm3510_readbytes(state,reg,&v->raw,1);
0134 }
0135
0136
0137 static int bcm3510_hab_get_response(struct bcm3510_state *st, u8 *buf, int len)
0138 {
0139 bcm3510_register_value v;
0140 int ret,i;
0141
0142 v.HABADR_a6.HABADR = 0;
0143 if ((ret = bcm3510_writeB(st,0xa6,v)) < 0)
0144 return ret;
0145
0146 for (i = 0; i < len; i++) {
0147 if ((ret = bcm3510_readB(st,0xa7,&v)) < 0)
0148 return ret;
0149 buf[i] = v.HABDATA_a7;
0150 }
0151 return 0;
0152 }
0153
0154 static int bcm3510_hab_send_request(struct bcm3510_state *st, u8 *buf, int len)
0155 {
0156 bcm3510_register_value v,hab;
0157 int ret,i;
0158 unsigned long t;
0159
0160
0161
0162 if ((ret = bcm3510_readB(st,0xa8,&v)) < 0)
0163 return ret;
0164 if (v.HABSTAT_a8.HABR) {
0165 deb_info("HAB is running already - clearing it.\n");
0166 v.HABSTAT_a8.HABR = 0;
0167 bcm3510_writeB(st,0xa8,v);
0168
0169 }
0170
0171
0172
0173 hab.HABADR_a6.HABADR = 0;
0174 if ((ret = bcm3510_writeB(st,0xa6,hab)) < 0)
0175 return ret;
0176
0177 for (i = 0; i < len; i++) {
0178 hab.HABDATA_a7 = buf[i];
0179 if ((ret = bcm3510_writeB(st,0xa7,hab)) < 0)
0180 return ret;
0181 }
0182
0183
0184
0185 v.raw = 0; v.HABSTAT_a8.HABR = 1; v.HABSTAT_a8.LDHABR = 1;
0186 if ((ret = bcm3510_writeB(st,0xa8,v)) < 0)
0187 return ret;
0188
0189
0190 t = jiffies + 1*HZ;
0191 while (time_before(jiffies, t)) {
0192 deb_info("waiting for HAB to complete\n");
0193 msleep(10);
0194 if ((ret = bcm3510_readB(st,0xa8,&v)) < 0)
0195 return ret;
0196
0197 if (!v.HABSTAT_a8.HABR)
0198 return 0;
0199 }
0200
0201 deb_info("send_request execution timed out.\n");
0202 return -ETIMEDOUT;
0203 }
0204
0205 static int bcm3510_do_hab_cmd(struct bcm3510_state *st, u8 cmd, u8 msgid, u8 *obuf, u8 olen, u8 *ibuf, u8 ilen)
0206 {
0207 u8 ob[MAX_XFER_SIZE], ib[MAX_XFER_SIZE];
0208 int ret = 0;
0209
0210 if (ilen + 2 > sizeof(ib)) {
0211 deb_hab("do_hab_cmd: ilen=%d is too big!\n", ilen);
0212 return -EINVAL;
0213 }
0214
0215 if (olen + 2 > sizeof(ob)) {
0216 deb_hab("do_hab_cmd: olen=%d is too big!\n", olen);
0217 return -EINVAL;
0218 }
0219
0220 ob[0] = cmd;
0221 ob[1] = msgid;
0222 memcpy(&ob[2],obuf,olen);
0223
0224 deb_hab("hab snd: ");
0225 dbufout(ob,olen+2,deb_hab);
0226 deb_hab("\n");
0227
0228 if (mutex_lock_interruptible(&st->hab_mutex) < 0)
0229 return -EAGAIN;
0230
0231 if ((ret = bcm3510_hab_send_request(st, ob, olen+2)) < 0 ||
0232 (ret = bcm3510_hab_get_response(st, ib, ilen+2)) < 0)
0233 goto error;
0234
0235 deb_hab("hab get: ");
0236 dbufout(ib,ilen+2,deb_hab);
0237 deb_hab("\n");
0238
0239 memcpy(ibuf,&ib[2],ilen);
0240 error:
0241 mutex_unlock(&st->hab_mutex);
0242 return ret;
0243 }
0244
0245 #if 0
0246
0247 static int bcm3510_is_ap_ready(struct bcm3510_state *st)
0248 {
0249 bcm3510_register_value ap,hab;
0250 int ret;
0251
0252 if ((ret = bcm3510_readB(st,0xa8,&hab)) < 0 ||
0253 (ret = bcm3510_readB(st,0xa2,&ap) < 0))
0254 return ret;
0255
0256 if (ap.APSTAT1_a2.RESET || ap.APSTAT1_a2.IDLE || ap.APSTAT1_a2.STOP || hab.HABSTAT_a8.HABR) {
0257 deb_info("AP is busy\n");
0258 return -EBUSY;
0259 }
0260
0261 return 0;
0262 }
0263 #endif
0264
0265 static int bcm3510_bert_reset(struct bcm3510_state *st)
0266 {
0267 bcm3510_register_value b;
0268 int ret;
0269
0270 if ((ret = bcm3510_readB(st,0xfa,&b)) < 0)
0271 return ret;
0272
0273 b.BERCTL_fa.RESYNC = 0; bcm3510_writeB(st,0xfa,b);
0274 b.BERCTL_fa.RESYNC = 1; bcm3510_writeB(st,0xfa,b);
0275 b.BERCTL_fa.RESYNC = 0; bcm3510_writeB(st,0xfa,b);
0276 b.BERCTL_fa.CNTCTL = 1; b.BERCTL_fa.BITCNT = 1; bcm3510_writeB(st,0xfa,b);
0277
0278
0279 return 0;
0280 }
0281
0282 static int bcm3510_refresh_state(struct bcm3510_state *st)
0283 {
0284 if (time_after(jiffies,st->next_status_check)) {
0285 bcm3510_do_hab_cmd(st, CMD_STATUS, MSGID_STATUS1, NULL,0, (u8 *)&st->status1, sizeof(st->status1));
0286 bcm3510_do_hab_cmd(st, CMD_STATUS, MSGID_STATUS2, NULL,0, (u8 *)&st->status2, sizeof(st->status2));
0287 st->next_status_check = jiffies + (st->status_check_interval*HZ)/1000;
0288 }
0289 return 0;
0290 }
0291
0292 static int bcm3510_read_status(struct dvb_frontend *fe, enum fe_status *status)
0293 {
0294 struct bcm3510_state* st = fe->demodulator_priv;
0295 bcm3510_refresh_state(st);
0296
0297 *status = 0;
0298 if (st->status1.STATUS1.RECEIVER_LOCK)
0299 *status |= FE_HAS_LOCK | FE_HAS_SYNC;
0300
0301 if (st->status1.STATUS1.FEC_LOCK)
0302 *status |= FE_HAS_VITERBI;
0303
0304 if (st->status1.STATUS1.OUT_PLL_LOCK)
0305 *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER;
0306
0307 if (*status & FE_HAS_LOCK)
0308 st->status_check_interval = 1500;
0309 else
0310 st->status_check_interval = 500;
0311
0312 deb_info("real_status: %02x\n",*status);
0313 return 0;
0314 }
0315
0316 static int bcm3510_read_ber(struct dvb_frontend* fe, u32* ber)
0317 {
0318 struct bcm3510_state* st = fe->demodulator_priv;
0319 bcm3510_refresh_state(st);
0320
0321 *ber = (st->status2.LDBER0 << 16) | (st->status2.LDBER1 << 8) | st->status2.LDBER2;
0322 return 0;
0323 }
0324
0325 static int bcm3510_read_unc(struct dvb_frontend* fe, u32* unc)
0326 {
0327 struct bcm3510_state* st = fe->demodulator_priv;
0328 bcm3510_refresh_state(st);
0329 *unc = (st->status2.LDUERC0 << 8) | st->status2.LDUERC1;
0330 return 0;
0331 }
0332
0333 static int bcm3510_read_signal_strength(struct dvb_frontend* fe, u16* strength)
0334 {
0335 struct bcm3510_state* st = fe->demodulator_priv;
0336 s32 t;
0337
0338 bcm3510_refresh_state(st);
0339 t = st->status2.SIGNAL;
0340
0341 if (t > 190)
0342 t = 190;
0343 if (t < 90)
0344 t = 90;
0345
0346 t -= 90;
0347 t = t * 0xff / 100;
0348
0349 *strength = (t << 8) | t;
0350 return 0;
0351 }
0352
0353 static int bcm3510_read_snr(struct dvb_frontend* fe, u16* snr)
0354 {
0355 struct bcm3510_state* st = fe->demodulator_priv;
0356 bcm3510_refresh_state(st);
0357
0358 *snr = st->status1.SNR_EST0*1000 + ((st->status1.SNR_EST1*1000) >> 8);
0359 return 0;
0360 }
0361
0362
0363 static int bcm3510_tuner_cmd(struct bcm3510_state* st,u8 bc, u16 n, u8 a)
0364 {
0365 struct bcm3510_hab_cmd_tune c;
0366 memset(&c,0,sizeof(struct bcm3510_hab_cmd_tune));
0367
0368
0369 c.length = 0x10;
0370 c.clock_width = 0;
0371
0372
0373 c.misc = 0x10;
0374
0375 c.TUNCTL_state = 0x40;
0376
0377
0378 c.ctl_dat[0].ctrl.size = BITS_8;
0379 c.ctl_dat[0].data = 0x80 | bc;
0380
0381
0382 c.ctl_dat[1].ctrl.size = BITS_8;
0383 c.ctl_dat[1].data = 4;
0384
0385
0386 c.ctl_dat[2].ctrl.size = BITS_3;
0387 c.ctl_dat[2].data = 0x20;
0388
0389
0390 c.ctl_dat[3].ctrl.size = BITS_3;
0391 c.ctl_dat[3].ctrl.clk_off = 1;
0392 c.ctl_dat[3].ctrl.cs0 = 1;
0393 c.ctl_dat[3].data = 0x40;
0394
0395
0396 c.ctl_dat[4].ctrl.size = BITS_8;
0397 c.ctl_dat[4].data = n >> 3;
0398
0399
0400 c.ctl_dat[5].ctrl.size = BITS_8;
0401 c.ctl_dat[5].data = ((n & 0x7) << 5) | (a >> 2);
0402
0403
0404 c.ctl_dat[6].ctrl.size = BITS_3;
0405 c.ctl_dat[6].data = (a << 6) & 0xdf;
0406
0407
0408 c.ctl_dat[7].ctrl.size = BITS_3;
0409 c.ctl_dat[7].ctrl.clk_off = 1;
0410 c.ctl_dat[7].ctrl.cs0 = 1;
0411 c.ctl_dat[7].data = 0x40;
0412
0413
0414 c.ctl_dat[8].ctrl.size = BITS_8;
0415 c.ctl_dat[8].data = 0x80;
0416
0417
0418 c.ctl_dat[9].ctrl.size = BITS_8;
0419 c.ctl_dat[9].data = 0x10;
0420
0421
0422 c.ctl_dat[10].ctrl.size = BITS_3;
0423 c.ctl_dat[10].data = 0x20;
0424
0425
0426 c.ctl_dat[11].ctrl.size = BITS_3;
0427 c.ctl_dat[11].ctrl.clk_off = 1;
0428 c.ctl_dat[11].ctrl.cs1 = 1;
0429 c.ctl_dat[11].data = 0x40;
0430
0431
0432 c.ctl_dat[12].ctrl.size = BITS_8;
0433 c.ctl_dat[12].data = 0x2a;
0434
0435
0436 c.ctl_dat[13].ctrl.size = BITS_8;
0437 c.ctl_dat[13].data = 0x8e;
0438
0439
0440 c.ctl_dat[14].ctrl.size = BITS_3;
0441 c.ctl_dat[14].data = 0;
0442
0443
0444 c.ctl_dat[15].ctrl.size = BITS_3;
0445 c.ctl_dat[15].ctrl.clk_off = 1;
0446 c.ctl_dat[15].ctrl.cs1 = 1;
0447 c.ctl_dat[15].data = 0x40;
0448
0449 return bcm3510_do_hab_cmd(st,CMD_TUNE, MSGID_TUNE,(u8 *) &c,sizeof(c), NULL, 0);
0450 }
0451
0452 static int bcm3510_set_freq(struct bcm3510_state* st,u32 freq)
0453 {
0454 u8 bc,a;
0455 u16 n;
0456 s32 YIntercept,Tfvco1;
0457
0458 freq /= 1000;
0459
0460 deb_info("%dkHz:",freq);
0461
0462 if (freq <= 168000)
0463 bc = 0x1c;
0464 else if (freq <= 378000)
0465 bc = 0x2c;
0466 else
0467 bc = 0x30;
0468
0469 if (freq >= 470000) {
0470 freq -= 470001;
0471 YIntercept = 18805;
0472 } else if (freq >= 90000) {
0473 freq -= 90001;
0474 YIntercept = 15005;
0475 } else if (freq >= 76000){
0476 freq -= 76001;
0477 YIntercept = 14865;
0478 } else {
0479 freq -= 54001;
0480 YIntercept = 14645;
0481 }
0482
0483 Tfvco1 = (((freq/6000)*60 + YIntercept)*4)/10;
0484
0485 n = Tfvco1 >> 6;
0486 a = Tfvco1 & 0x3f;
0487
0488 deb_info(" BC1_2_3_4: %x, N: %x A: %x\n", bc, n, a);
0489 if (n >= 16 && n <= 2047)
0490 return bcm3510_tuner_cmd(st,bc,n,a);
0491
0492 return -EINVAL;
0493 }
0494
0495 static int bcm3510_set_frontend(struct dvb_frontend *fe)
0496 {
0497 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
0498 struct bcm3510_state* st = fe->demodulator_priv;
0499 struct bcm3510_hab_cmd_ext_acquire cmd;
0500 struct bcm3510_hab_cmd_bert_control bert;
0501 int ret;
0502
0503 memset(&cmd,0,sizeof(cmd));
0504 switch (c->modulation) {
0505 case QAM_256:
0506 cmd.ACQUIRE0.MODE = 0x1;
0507 cmd.ACQUIRE1.SYM_RATE = 0x1;
0508 cmd.ACQUIRE1.IF_FREQ = 0x1;
0509 break;
0510 case QAM_64:
0511 cmd.ACQUIRE0.MODE = 0x2;
0512 cmd.ACQUIRE1.SYM_RATE = 0x2;
0513 cmd.ACQUIRE1.IF_FREQ = 0x1;
0514 break;
0515 #if 0
0516 case QAM_256:
0517 cmd.ACQUIRE0.MODE = 0x3;
0518 break;
0519 case QAM_128:
0520 cmd.ACQUIRE0.MODE = 0x4;
0521 break;
0522 case QAM_64:
0523 cmd.ACQUIRE0.MODE = 0x5;
0524 break;
0525 case QAM_32:
0526 cmd.ACQUIRE0.MODE = 0x6;
0527 break;
0528 case QAM_16:
0529 cmd.ACQUIRE0.MODE = 0x7;
0530 break;
0531 #endif
0532 case VSB_8:
0533 cmd.ACQUIRE0.MODE = 0x8;
0534 cmd.ACQUIRE1.SYM_RATE = 0x0;
0535 cmd.ACQUIRE1.IF_FREQ = 0x0;
0536 break;
0537 case VSB_16:
0538 cmd.ACQUIRE0.MODE = 0x9;
0539 cmd.ACQUIRE1.SYM_RATE = 0x0;
0540 cmd.ACQUIRE1.IF_FREQ = 0x0;
0541 break;
0542 default:
0543 return -EINVAL;
0544 }
0545 cmd.ACQUIRE0.OFFSET = 0;
0546 cmd.ACQUIRE0.NTSCSWEEP = 1;
0547 cmd.ACQUIRE0.FA = 1;
0548 cmd.ACQUIRE0.BW = 0;
0549
0550
0551
0552
0553
0554
0555
0556
0557
0558
0559
0560
0561 bcm3510_do_hab_cmd(st, CMD_ACQUIRE, MSGID_EXT_TUNER_ACQUIRE, (u8 *) &cmd, sizeof(cmd), NULL, 0);
0562
0563
0564 bert.BE = 0;
0565 bert.unused = 0;
0566 bcm3510_do_hab_cmd(st, CMD_STATE_CONTROL, MSGID_BERT_CONTROL, (u8 *) &bert, sizeof(bert), NULL, 0);
0567 bcm3510_do_hab_cmd(st, CMD_STATE_CONTROL, MSGID_BERT_SET, (u8 *) &bert, sizeof(bert), NULL, 0);
0568
0569 bcm3510_bert_reset(st);
0570
0571 ret = bcm3510_set_freq(st, c->frequency);
0572 if (ret < 0)
0573 return ret;
0574
0575 memset(&st->status1,0,sizeof(st->status1));
0576 memset(&st->status2,0,sizeof(st->status2));
0577 st->status_check_interval = 500;
0578
0579
0580 msleep(200);
0581
0582 return 0;
0583 }
0584
0585 static int bcm3510_sleep(struct dvb_frontend* fe)
0586 {
0587 return 0;
0588 }
0589
0590 static int bcm3510_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *s)
0591 {
0592 s->min_delay_ms = 1000;
0593 s->step_size = 0;
0594 s->max_drift = 0;
0595 return 0;
0596 }
0597
0598 static void bcm3510_release(struct dvb_frontend* fe)
0599 {
0600 struct bcm3510_state* state = fe->demodulator_priv;
0601 kfree(state);
0602 }
0603
0604
0605
0606
0607
0608 #define BCM3510_DEFAULT_FIRMWARE "dvb-fe-bcm3510-01.fw"
0609
0610 static int bcm3510_write_ram(struct bcm3510_state *st, u16 addr, const u8 *b,
0611 u16 len)
0612 {
0613 int ret = 0,i;
0614 bcm3510_register_value vH, vL,vD;
0615
0616 vH.MADRH_a9 = addr >> 8;
0617 vL.MADRL_aa = addr;
0618 if ((ret = bcm3510_writeB(st,0xa9,vH)) < 0) return ret;
0619 if ((ret = bcm3510_writeB(st,0xaa,vL)) < 0) return ret;
0620
0621 for (i = 0; i < len; i++) {
0622 vD.MDATA_ab = b[i];
0623 if ((ret = bcm3510_writeB(st,0xab,vD)) < 0)
0624 return ret;
0625 }
0626
0627 return 0;
0628 }
0629
0630 static int bcm3510_download_firmware(struct dvb_frontend* fe)
0631 {
0632 struct bcm3510_state* st = fe->demodulator_priv;
0633 const struct firmware *fw;
0634 u16 addr,len;
0635 const u8 *b;
0636 int ret,i;
0637
0638 deb_info("requesting firmware\n");
0639 if ((ret = st->config->request_firmware(fe, &fw, BCM3510_DEFAULT_FIRMWARE)) < 0) {
0640 err("could not load firmware (%s): %d",BCM3510_DEFAULT_FIRMWARE,ret);
0641 return ret;
0642 }
0643 deb_info("got firmware: %zu\n", fw->size);
0644
0645 b = fw->data;
0646 for (i = 0; i < fw->size;) {
0647 addr = le16_to_cpu(*((__le16 *)&b[i]));
0648 len = le16_to_cpu(*((__le16 *)&b[i+2]));
0649 deb_info("firmware chunk, addr: 0x%04x, len: 0x%04x, total length: 0x%04zx\n",addr,len,fw->size);
0650 if ((ret = bcm3510_write_ram(st,addr,&b[i+4],len)) < 0) {
0651 err("firmware download failed: %d\n",ret);
0652 return ret;
0653 }
0654 i += 4 + len;
0655 }
0656 release_firmware(fw);
0657 deb_info("firmware download successfully completed\n");
0658 return 0;
0659 }
0660
0661 static int bcm3510_check_firmware_version(struct bcm3510_state *st)
0662 {
0663 struct bcm3510_hab_cmd_get_version_info ver;
0664 bcm3510_do_hab_cmd(st,CMD_GET_VERSION_INFO,MSGID_GET_VERSION_INFO,NULL,0,(u8*)&ver,sizeof(ver));
0665
0666 deb_info("Version information: 0x%02x 0x%02x 0x%02x 0x%02x\n",
0667 ver.microcode_version, ver.script_version, ver.config_version, ver.demod_version);
0668
0669 if (ver.script_version == BCM3510_DEF_SCRIPT_VERSION &&
0670 ver.config_version == BCM3510_DEF_CONFIG_VERSION &&
0671 ver.demod_version == BCM3510_DEF_DEMOD_VERSION)
0672 return 0;
0673
0674 deb_info("version check failed\n");
0675 return -ENODEV;
0676 }
0677
0678
0679 static int bcm3510_reset(struct bcm3510_state *st)
0680 {
0681 int ret;
0682 unsigned long t;
0683 bcm3510_register_value v;
0684
0685 bcm3510_readB(st,0xa0,&v); v.HCTL1_a0.RESET = 1;
0686 if ((ret = bcm3510_writeB(st,0xa0,v)) < 0)
0687 return ret;
0688
0689 t = jiffies + 3*HZ;
0690 while (time_before(jiffies, t)) {
0691 msleep(10);
0692 if ((ret = bcm3510_readB(st,0xa2,&v)) < 0)
0693 return ret;
0694
0695 if (v.APSTAT1_a2.RESET)
0696 return 0;
0697 }
0698 deb_info("reset timed out\n");
0699 return -ETIMEDOUT;
0700 }
0701
0702 static int bcm3510_clear_reset(struct bcm3510_state *st)
0703 {
0704 bcm3510_register_value v;
0705 int ret;
0706 unsigned long t;
0707
0708 v.raw = 0;
0709 if ((ret = bcm3510_writeB(st,0xa0,v)) < 0)
0710 return ret;
0711
0712 t = jiffies + 3*HZ;
0713 while (time_before(jiffies, t)) {
0714 msleep(10);
0715 if ((ret = bcm3510_readB(st,0xa2,&v)) < 0)
0716 return ret;
0717
0718
0719 if (!v.APSTAT1_a2.RESET)
0720 return 0;
0721 }
0722 deb_info("reset clear timed out\n");
0723 return -ETIMEDOUT;
0724 }
0725
0726 static int bcm3510_init_cold(struct bcm3510_state *st)
0727 {
0728 int ret;
0729 bcm3510_register_value v;
0730
0731
0732 if ((ret = bcm3510_readB(st,0xa2,&v)) < 0)
0733 return ret;
0734 if (v.APSTAT1_a2.RUN) {
0735 deb_info("AP is already running - firmware already loaded.\n");
0736 return 0;
0737 }
0738
0739 deb_info("reset?\n");
0740 if ((ret = bcm3510_reset(st)) < 0)
0741 return ret;
0742
0743 deb_info("tristate?\n");
0744
0745 v.TSTCTL_2e.CTL = 0;
0746 if ((ret = bcm3510_writeB(st,0x2e,v)) < 0)
0747 return ret;
0748
0749 deb_info("firmware?\n");
0750 if ((ret = bcm3510_download_firmware(&st->frontend)) < 0 ||
0751 (ret = bcm3510_clear_reset(st)) < 0)
0752 return ret;
0753
0754
0755
0756 return 0;
0757 }
0758
0759 static int bcm3510_init(struct dvb_frontend* fe)
0760 {
0761 struct bcm3510_state* st = fe->demodulator_priv;
0762 bcm3510_register_value j;
0763 struct bcm3510_hab_cmd_set_agc c;
0764 int ret;
0765
0766 if ((ret = bcm3510_readB(st,0xca,&j)) < 0)
0767 return ret;
0768
0769 deb_info("JDEC: %02x\n",j.raw);
0770
0771 switch (j.JDEC_ca.JDEC) {
0772 case JDEC_WAIT_AT_RAM:
0773 deb_info("attempting to download firmware\n");
0774 if ((ret = bcm3510_init_cold(st)) < 0)
0775 return ret;
0776 fallthrough;
0777 case JDEC_EEPROM_LOAD_WAIT:
0778 deb_info("firmware is loaded\n");
0779 bcm3510_check_firmware_version(st);
0780 break;
0781 default:
0782 return -ENODEV;
0783 }
0784
0785 memset(&c,0,1);
0786 c.SEL = 1;
0787 bcm3510_do_hab_cmd(st,CMD_AUTO_PARAM,MSGID_SET_RF_AGC_SEL,(u8 *)&c,sizeof(c),NULL,0);
0788
0789 return 0;
0790 }
0791
0792
0793 static const struct dvb_frontend_ops bcm3510_ops;
0794
0795 struct dvb_frontend* bcm3510_attach(const struct bcm3510_config *config,
0796 struct i2c_adapter *i2c)
0797 {
0798 struct bcm3510_state* state = NULL;
0799 int ret;
0800 bcm3510_register_value v;
0801
0802
0803 state = kzalloc(sizeof(struct bcm3510_state), GFP_KERNEL);
0804 if (state == NULL)
0805 goto error;
0806
0807
0808
0809 state->config = config;
0810 state->i2c = i2c;
0811
0812
0813 memcpy(&state->frontend.ops, &bcm3510_ops, sizeof(struct dvb_frontend_ops));
0814 state->frontend.demodulator_priv = state;
0815
0816 mutex_init(&state->hab_mutex);
0817
0818 if ((ret = bcm3510_readB(state,0xe0,&v)) < 0)
0819 goto error;
0820
0821 deb_info("Revision: 0x%1x, Layer: 0x%1x.\n",v.REVID_e0.REV,v.REVID_e0.LAYER);
0822
0823 if ((v.REVID_e0.REV != 0x1 && v.REVID_e0.LAYER != 0xb) &&
0824 (v.REVID_e0.REV != 0x8 && v.REVID_e0.LAYER != 0x0))
0825 goto error;
0826
0827 info("Revision: 0x%1x, Layer: 0x%1x.",v.REVID_e0.REV,v.REVID_e0.LAYER);
0828
0829 bcm3510_reset(state);
0830
0831 return &state->frontend;
0832
0833 error:
0834 kfree(state);
0835 return NULL;
0836 }
0837 EXPORT_SYMBOL(bcm3510_attach);
0838
0839 static const struct dvb_frontend_ops bcm3510_ops = {
0840 .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B },
0841 .info = {
0842 .name = "Broadcom BCM3510 VSB/QAM frontend",
0843 .frequency_min_hz = 54 * MHz,
0844 .frequency_max_hz = 803 * MHz,
0845 .caps =
0846 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
0847 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
0848 FE_CAN_8VSB | FE_CAN_16VSB |
0849 FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_128 | FE_CAN_QAM_256
0850 },
0851
0852 .release = bcm3510_release,
0853
0854 .init = bcm3510_init,
0855 .sleep = bcm3510_sleep,
0856
0857 .set_frontend = bcm3510_set_frontend,
0858 .get_tune_settings = bcm3510_get_tune_settings,
0859
0860 .read_status = bcm3510_read_status,
0861 .read_ber = bcm3510_read_ber,
0862 .read_signal_strength = bcm3510_read_signal_strength,
0863 .read_snr = bcm3510_read_snr,
0864 .read_ucblocks = bcm3510_read_unc,
0865 };
0866
0867 MODULE_DESCRIPTION("Broadcom BCM3510 ATSC (8VSB/16VSB & ITU J83 AnnexB FEC QAM64/256) demodulator driver");
0868 MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@posteo.de>");
0869 MODULE_LICENSE("GPL");