diff -Nrup 2-v4l-dvb_xc-bluebird_dd4.au/linux/drivers/media/dvb/frontends/xc3028-fe.c 3-v4l-dvb_xc-bluebird_dd4.au_xc-status/linux/drivers/media/dvb/frontends/xc3028-fe.c --- 2-v4l-dvb_xc-bluebird_dd4.au/linux/drivers/media/dvb/frontends/xc3028-fe.c 2007-11-14 11:18:32.000000000 +1000 +++ 3-v4l-dvb_xc-bluebird_dd4.au_xc-status/linux/drivers/media/dvb/frontends/xc3028-fe.c 2007-11-14 11:19:31.000000000 +1000 @@ -140,6 +140,7 @@ static int xc3028_i2c_xfer(struct i2c_ad } /* ---------------------------------------------------------------------- */ +static int xc3028_get_status(struct dvb_frontend *fe, u32 *status); static int xc3028_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) @@ -152,6 +153,7 @@ static int xc3028_set_params(struct dvb_ int bandwidth; int i; enum v4l2_tuner_type type; + u32 status; if (fe->ops.info.type == FE_ATSC) { type = V4L2_TUNER_ATSC_TV; @@ -269,6 +271,10 @@ static int xc3028_set_params(struct dvb_ #endif xc3028_i2c_xfer(priv->i2c_adap,"\x80\x02\x00\x00",4); xc3028_i2c_xfer(priv->i2c_adap,chanbuf,4); + + msleep(50); + xc3028_get_status(fe, &status); + return 0; } @@ -473,6 +479,61 @@ static int xc3028_set_mode(struct dvb_fr return 0; } +static int xc3028_read_reg(struct dvb_frontend *fe, u8 reg, u16 *data) +{ + struct xc3028_priv *priv = fe->tuner_priv; + u8 wbuf[] = { 0x00, reg }; + u8 rbuf[2]; + int ret; + struct i2c_msg msg[] = { + { .addr = XC3028_I2C_ADDR, .flags = 0, + .buf = wbuf, .len = sizeof(wbuf) }, + { .addr = XC3028_I2C_ADDR, .flags = I2C_M_RD, + .buf = rbuf, .len = sizeof(rbuf) }, + }; + + *data = 0; + + ret = i2c_transfer(priv->i2c_adap, msg, 2); + + if (ret != 2) { + printk("%s: i2c_transfer returned: %d\n", __FUNCTION__, ret); + return ret; + } + + *data = (rbuf[0] << 8) | (rbuf[1] << 0); + + return 0; +}; + +static int xc3028_get_status(struct dvb_frontend *fe, u32 *status) +{ + u16 data; + + *status = 0; + + xc3028_read_reg(fe, 0x08, &data); + + printk("%s: product id: %d\n", __FUNCTION__, data); + + xc3028_read_reg(fe, 0x04, &data); + + printk("%s: hw version: 0x%x 0x%x, fw version: 0x%x 0x%x\n", __FUNCTION__, + (data>>12) & 0x0f, + (data>>8) & 0x0f, + (data>>4) & 0x0f, + (data>>0) & 0x0f); + + xc3028_read_reg(fe, 0x02, &data); + + if ((data & 0xff) == 1) { + *status = TUNER_STATUS_LOCKED; + printk("%s: tuner is locked.\n", __FUNCTION__); + } + + return 0; +} + /* dvb tuner api */ static int xc3028_release(struct dvb_frontend *fe) { @@ -509,6 +570,9 @@ static const struct dvb_tuner_ops xc3028 .set_params = xc3028_set_params, .get_frequency = xc3028_get_frequency, .get_bandwidth = xc3028_get_bandwidth, +#if 0 + .get_status = xc3028_get_status, +#endif }; struct dvb_frontend *xc3028_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct xc3028_config *cfg)