diff options
Diffstat (limited to 'drivers/media/dvb-frontends')
31 files changed, 1095 insertions, 1000 deletions
diff --git a/drivers/media/dvb-frontends/Kconfig b/drivers/media/dvb-frontends/Kconfig index c645aa81f423..012225587c25 100644 --- a/drivers/media/dvb-frontends/Kconfig +++ b/drivers/media/dvb-frontends/Kconfig @@ -67,6 +67,7 @@ config DVB_TDA18271C2DD config DVB_SI2165 tristate "Silicon Labs si2165 based" depends on DVB_CORE && I2C + select REGMAP_I2C default m if !MEDIA_SUBDRV_AUTOSELECT help A DVB-C/T demodulator. @@ -463,6 +464,7 @@ config DVB_STV0367 config DVB_CXD2820R tristate "Sony CXD2820R" depends on DVB_CORE && I2C + select REGMAP_I2C default m if !MEDIA_SUBDRV_AUTOSELECT help Say Y when you want to support this frontend. diff --git a/drivers/media/dvb-frontends/ascot2e.c b/drivers/media/dvb-frontends/ascot2e.c index 8cc8c4597b6a..ad304eed656d 100644 --- a/drivers/media/dvb-frontends/ascot2e.c +++ b/drivers/media/dvb-frontends/ascot2e.c @@ -464,7 +464,7 @@ static int ascot2e_get_frequency(struct dvb_frontend *fe, u32 *frequency) return 0; } -static struct dvb_tuner_ops ascot2e_tuner_ops = { +static const struct dvb_tuner_ops ascot2e_tuner_ops = { .info = { .name = "Sony ASCOT2E", .frequency_min = 1000000, diff --git a/drivers/media/dvb-frontends/cxd2820r.h b/drivers/media/dvb-frontends/cxd2820r.h index 56d42760263d..d77afe0b8a9e 100644 --- a/drivers/media/dvb-frontends/cxd2820r.h +++ b/drivers/media/dvb-frontends/cxd2820r.h @@ -37,6 +37,32 @@ #define CXD2820R_TS_PARALLEL 0x30 #define CXD2820R_TS_PARALLEL_MSB 0x70 +/* + * I2C address: 0x6c, 0x6d + */ + +/** + * struct cxd2820r_platform_data - Platform data for the cxd2820r driver + * @ts_mode: TS mode. + * @ts_clk_inv: TS clock inverted. + * @if_agc_polarity: IF AGC polarity. + * @spec_inv: Input spectrum inverted. + * @gpio_chip_base: GPIO. + * @get_dvb_frontend: Get DVB frontend. + */ + +struct cxd2820r_platform_data { + u8 ts_mode; + bool ts_clk_inv; + bool if_agc_polarity; + bool spec_inv; + int **gpio_chip_base; + + struct dvb_frontend* (*get_dvb_frontend)(struct i2c_client *); +/* private: For legacy media attach wrapper. Do not set value. */ + bool attach_in_use; +}; + struct cxd2820r_config { /* Demodulator I2C address. * Driver determines DVB-C slave I2C address automatically from master diff --git a/drivers/media/dvb-frontends/cxd2820r_c.c b/drivers/media/dvb-frontends/cxd2820r_c.c index a674a6312c38..d75b0776d5b5 100644 --- a/drivers/media/dvb-frontends/cxd2820r_c.c +++ b/drivers/media/dvb-frontends/cxd2820r_c.c @@ -24,12 +24,12 @@ int cxd2820r_set_frontend_c(struct dvb_frontend *fe) { struct cxd2820r_priv *priv = fe->demodulator_priv; + struct i2c_client *client = priv->client[0]; struct dtv_frontend_properties *c = &fe->dtv_property_cache; - int ret, i; + int ret; + unsigned int utmp; u8 buf[2]; - u32 if_freq; - u16 if_ctl; - u64 num; + u32 if_frequency; struct reg_val_mask tab[] = { { 0x00080, 0x01, 0xff }, { 0x00081, 0x05, 0xff }, @@ -43,25 +43,24 @@ int cxd2820r_set_frontend_c(struct dvb_frontend *fe) { 0x10059, 0x50, 0xff }, { 0x10087, 0x0c, 0x3c }, { 0x1008b, 0x07, 0xff }, - { 0x1001f, priv->cfg.if_agc_polarity << 7, 0x80 }, - { 0x10070, priv->cfg.ts_mode, 0xff }, - { 0x10071, !priv->cfg.ts_clock_inv << 4, 0x10 }, + { 0x1001f, priv->if_agc_polarity << 7, 0x80 }, + { 0x10070, priv->ts_mode, 0xff }, + { 0x10071, !priv->ts_clk_inv << 4, 0x10 }, }; - dev_dbg(&priv->i2c->dev, "%s: frequency=%d symbol_rate=%d\n", __func__, - c->frequency, c->symbol_rate); + dev_dbg(&client->dev, + "delivery_system=%d modulation=%d frequency=%u symbol_rate=%u inversion=%d\n", + c->delivery_system, c->modulation, c->frequency, + c->symbol_rate, c->inversion); /* program tuner */ if (fe->ops.tuner_ops.set_params) fe->ops.tuner_ops.set_params(fe); if (priv->delivery_system != SYS_DVBC_ANNEX_A) { - for (i = 0; i < ARRAY_SIZE(tab); i++) { - ret = cxd2820r_wr_reg_mask(priv, tab[i].reg, - tab[i].val, tab[i].mask); - if (ret) - goto error; - } + ret = cxd2820r_wr_reg_val_mask_tab(priv, tab, ARRAY_SIZE(tab)); + if (ret) + goto error; } priv->delivery_system = SYS_DVBC_ANNEX_A; @@ -69,35 +68,33 @@ int cxd2820r_set_frontend_c(struct dvb_frontend *fe) /* program IF frequency */ if (fe->ops.tuner_ops.get_if_frequency) { - ret = fe->ops.tuner_ops.get_if_frequency(fe, &if_freq); + ret = fe->ops.tuner_ops.get_if_frequency(fe, &if_frequency); if (ret) goto error; - } else - if_freq = 0; - - dev_dbg(&priv->i2c->dev, "%s: if_freq=%d\n", __func__, if_freq); - - num = if_freq / 1000; /* Hz => kHz */ - num *= 0x4000; - if_ctl = 0x4000 - DIV_ROUND_CLOSEST_ULL(num, 41000); - buf[0] = (if_ctl >> 8) & 0x3f; - buf[1] = (if_ctl >> 0) & 0xff; + dev_dbg(&client->dev, "if_frequency=%u\n", if_frequency); + } else { + ret = -EINVAL; + goto error; + } - ret = cxd2820r_wr_regs(priv, 0x10042, buf, 2); + utmp = 0x4000 - DIV_ROUND_CLOSEST_ULL((u64)if_frequency * 0x4000, CXD2820R_CLK); + buf[0] = (utmp >> 8) & 0xff; + buf[1] = (utmp >> 0) & 0xff; + ret = regmap_bulk_write(priv->regmap[1], 0x0042, buf, 2); if (ret) goto error; - ret = cxd2820r_wr_reg(priv, 0x000ff, 0x08); + ret = regmap_write(priv->regmap[0], 0x00ff, 0x08); if (ret) goto error; - ret = cxd2820r_wr_reg(priv, 0x000fe, 0x01); + ret = regmap_write(priv->regmap[0], 0x00fe, 0x01); if (ret) goto error; return ret; error: - dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); + dev_dbg(&client->dev, "failed=%d\n", ret); return ret; } @@ -105,20 +102,24 @@ int cxd2820r_get_frontend_c(struct dvb_frontend *fe, struct dtv_frontend_properties *c) { struct cxd2820r_priv *priv = fe->demodulator_priv; + struct i2c_client *client = priv->client[0]; int ret; + unsigned int utmp; u8 buf[2]; - ret = cxd2820r_rd_regs(priv, 0x1001a, buf, 2); + dev_dbg(&client->dev, "\n"); + + ret = regmap_bulk_read(priv->regmap[1], 0x001a, buf, 2); if (ret) goto error; c->symbol_rate = 2500 * ((buf[0] & 0x0f) << 8 | buf[1]); - ret = cxd2820r_rd_reg(priv, 0x10019, &buf[0]); + ret = regmap_read(priv->regmap[1], 0x0019, &utmp); if (ret) goto error; - switch ((buf[0] >> 0) & 0x07) { + switch ((utmp >> 0) & 0x07) { case 0: c->modulation = QAM_16; break; @@ -136,7 +137,7 @@ int cxd2820r_get_frontend_c(struct dvb_frontend *fe, break; } - switch ((buf[0] >> 7) & 0x01) { + switch ((utmp >> 7) & 0x01) { case 0: c->inversion = INVERSION_OFF; break; @@ -147,167 +148,169 @@ int cxd2820r_get_frontend_c(struct dvb_frontend *fe, return ret; error: - dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); + dev_dbg(&client->dev, "failed=%d\n", ret); return ret; } -int cxd2820r_read_ber_c(struct dvb_frontend *fe, u32 *ber) +int cxd2820r_read_status_c(struct dvb_frontend *fe, enum fe_status *status) { struct cxd2820r_priv *priv = fe->demodulator_priv; + struct i2c_client *client = priv->client[0]; + struct dtv_frontend_properties *c = &fe->dtv_property_cache; int ret; - u8 buf[3], start_ber = 0; - *ber = 0; + unsigned int utmp, utmp1, utmp2; + u8 buf[3]; - if (priv->ber_running) { - ret = cxd2820r_rd_regs(priv, 0x10076, buf, sizeof(buf)); - if (ret) - goto error; + /* Lock detection */ + ret = regmap_bulk_read(priv->regmap[1], 0x0088, &buf[0], 1); + if (ret) + goto error; + ret = regmap_bulk_read(priv->regmap[1], 0x0073, &buf[1], 1); + if (ret) + goto error; - if ((buf[2] >> 7) & 0x01 || (buf[2] >> 4) & 0x01) { - *ber = (buf[2] & 0x0f) << 16 | buf[1] << 8 | buf[0]; - start_ber = 1; - } + utmp1 = (buf[0] >> 0) & 0x01; + utmp2 = (buf[1] >> 3) & 0x01; + + if (utmp1 == 1 && utmp2 == 1) { + *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | + FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; + } else if (utmp1 == 1 || utmp2 == 1) { + *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | + FE_HAS_VITERBI | FE_HAS_SYNC; } else { - priv->ber_running = true; - start_ber = 1; + *status = 0; } - if (start_ber) { - /* (re)start BER */ - ret = cxd2820r_wr_reg(priv, 0x10079, 0x01); - if (ret) - goto error; - } + dev_dbg(&client->dev, "status=%02x raw=%*ph sync=%u ts=%u\n", + *status, 2, buf, utmp1, utmp2); - return ret; -error: - dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); - return ret; -} + /* Signal strength */ + if (*status & FE_HAS_SIGNAL) { + unsigned int strength; -int cxd2820r_read_signal_strength_c(struct dvb_frontend *fe, - u16 *strength) -{ - struct cxd2820r_priv *priv = fe->demodulator_priv; - int ret; - u8 buf[2]; - u16 tmp; + ret = regmap_bulk_read(priv->regmap[1], 0x0049, buf, 2); + if (ret) + goto error; - ret = cxd2820r_rd_regs(priv, 0x10049, buf, sizeof(buf)); - if (ret) - goto error; + utmp = buf[0] << 8 | buf[1] << 0; + utmp = 511 - sign_extend32(utmp, 9); + /* Scale value to 0x0000-0xffff */ + strength = utmp << 6 | utmp >> 4; - tmp = (buf[0] & 0x03) << 8 | buf[1]; - tmp = (~tmp & 0x03ff); + c->strength.len = 1; + c->strength.stat[0].scale = FE_SCALE_RELATIVE; + c->strength.stat[0].uvalue = strength; + } else { + c->strength.len = 1; + c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + } - if (tmp == 512) - /* ~no signal */ - tmp = 0; - else if (tmp > 350) - tmp = 350; + /* CNR */ + if (*status & FE_HAS_VITERBI) { + unsigned int cnr, const_a, const_b; - /* scale value to 0x0000-0xffff */ - *strength = tmp * 0xffff / (350-0); + ret = regmap_read(priv->regmap[1], 0x0019, &utmp); + if (ret) + goto error; - return ret; -error: - dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); - return ret; -} + if (((utmp >> 0) & 0x03) % 2) { + const_a = 8750; + const_b = 650; + } else { + const_a = 9500; + const_b = 760; + } -int cxd2820r_read_snr_c(struct dvb_frontend *fe, u16 *snr) -{ - struct cxd2820r_priv *priv = fe->demodulator_priv; - int ret; - u8 tmp; - unsigned int A, B; - /* report SNR in dB * 10 */ + ret = regmap_read(priv->regmap[1], 0x004d, &utmp); + if (ret) + goto error; - ret = cxd2820r_rd_reg(priv, 0x10019, &tmp); - if (ret) - goto error; + #define CXD2820R_LOG2_E_24 24204406 /* log2(e) << 24 */ + if (utmp) + cnr = div_u64((u64)(intlog2(const_b) - intlog2(utmp)) + * const_a, CXD2820R_LOG2_E_24); + else + cnr = 0; - if (((tmp >> 0) & 0x03) % 2) { - A = 875; - B = 650; + c->cnr.len = 1; + c->cnr.stat[0].scale = FE_SCALE_DECIBEL; + c->cnr.stat[0].svalue = cnr; } else { - A = 950; - B = 760; + c->cnr.len = 1; + c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; } - ret = cxd2820r_rd_reg(priv, 0x1004d, &tmp); - if (ret) - goto error; - - #define CXD2820R_LOG2_E_24 24204406 /* log2(e) << 24 */ - if (tmp) - *snr = A * (intlog2(B / tmp) >> 5) / (CXD2820R_LOG2_E_24 >> 5) - / 10; - else - *snr = 0; - - return ret; -error: - dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); - return ret; -} + /* BER */ + if (*status & FE_HAS_SYNC) { + unsigned int post_bit_error; + bool start_ber; -int cxd2820r_read_ucblocks_c(struct dvb_frontend *fe, u32 *ucblocks) -{ - *ucblocks = 0; - /* no way to read ? */ - return 0; -} + if (priv->ber_running) { + ret = regmap_bulk_read(priv->regmap[1], 0x0076, buf, 3); + if (ret) + goto error; -int cxd2820r_read_status_c(struct dvb_frontend *fe, enum fe_status *status) -{ - struct cxd2820r_priv *priv = fe->demodulator_priv; - int ret; - u8 buf[2]; - *status = 0; + if ((buf[2] >> 7) & 0x01) { + post_bit_error = buf[2] << 16 | buf[1] << 8 | + buf[0] << 0; + post_bit_error &= 0x0fffff; + start_ber = true; + } else { + post_bit_error = 0; + start_ber = false; + } + } else { + post_bit_error = 0; + start_ber = true; + } - ret = cxd2820r_rd_regs(priv, 0x10088, buf, sizeof(buf)); - if (ret) - goto error; + if (start_ber) { + ret = regmap_write(priv->regmap[1], 0x0079, 0x01); + if (ret) + goto error; + priv->ber_running = true; + } - if (((buf[0] >> 0) & 0x01) == 1) { - *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER | - FE_HAS_VITERBI | FE_HAS_SYNC; + priv->post_bit_error += post_bit_error; - if (((buf[1] >> 3) & 0x01) == 1) { - *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER | - FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; - } + c->post_bit_error.len = 1; + c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER; + c->post_bit_error.stat[0].uvalue = priv->post_bit_error; + } else { + c->post_bit_error.len = 1; + c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; } - dev_dbg(&priv->i2c->dev, "%s: lock=%02x %02x\n", __func__, buf[0], - buf[1]); - return ret; error: - dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); + dev_dbg(&client->dev, "failed=%d\n", ret); return ret; } int cxd2820r_init_c(struct dvb_frontend *fe) { struct cxd2820r_priv *priv = fe->demodulator_priv; + struct i2c_client *client = priv->client[0]; int ret; - ret = cxd2820r_wr_reg(priv, 0x00085, 0x07); + dev_dbg(&client->dev, "\n"); + + ret = regmap_write(priv->regmap[0], 0x0085, 0x07); if (ret) goto error; return ret; error: - dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); + dev_dbg(&client->dev, "failed=%d\n", ret); return ret; } int cxd2820r_sleep_c(struct dvb_frontend *fe) { struct cxd2820r_priv *priv = fe->demodulator_priv; - int ret, i; + struct i2c_client *client = priv->client[0]; + int ret; struct reg_val_mask tab[] = { { 0x000ff, 0x1f, 0xff }, { 0x00085, 0x00, 0xff }, @@ -316,20 +319,17 @@ int cxd2820r_sleep_c(struct dvb_frontend *fe) { 0x00080, 0x00, 0xff }, }; - dev_dbg(&priv->i2c->dev, "%s\n", __func__); + dev_dbg(&client->dev, "\n"); priv->delivery_system = SYS_UNDEFINED; - for (i = 0; i < ARRAY_SIZE(tab); i++) { - ret = cxd2820r_wr_reg_mask(priv, tab[i].reg, tab[i].val, - tab[i].mask); - if (ret) - goto error; - } + ret = cxd2820r_wr_reg_val_mask_tab(priv, tab, ARRAY_SIZE(tab)); + if (ret) + goto error; return ret; error: - dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); + dev_dbg(&client->dev, "failed=%d\n", ret); return ret; } diff --git a/drivers/media/dvb-frontends/cxd2820r_core.c b/drivers/media/dvb-frontends/cxd2820r_core.c index 314d3b8c1080..95267c6edb3a 100644 --- a/drivers/media/dvb-frontends/cxd2820r_core.c +++ b/drivers/media/dvb-frontends/cxd2820r_core.c @@ -21,178 +21,50 @@ #include "cxd2820r_priv.h" -/* Max transfer size done by I2C transfer functions */ -#define MAX_XFER_SIZE 64 - -/* write multiple registers */ -static int cxd2820r_wr_regs_i2c(struct cxd2820r_priv *priv, u8 i2c, u8 reg, - u8 *val, int len) -{ - int ret; - u8 buf[MAX_XFER_SIZE]; - struct i2c_msg msg[1] = { - { - .addr = i2c, - .flags = 0, - .len = len + 1, - .buf = buf, - } - }; - - if (1 + len > sizeof(buf)) { - dev_warn(&priv->i2c->dev, - "%s: i2c wr reg=%04x: len=%d is too big!\n", - KBUILD_MODNAME, reg, len); - return -EINVAL; - } - - buf[0] = reg; - memcpy(&buf[1], val, len); - - ret = i2c_transfer(priv->i2c, msg, 1); - if (ret == 1) { - ret = 0; - } else { - dev_warn(&priv->i2c->dev, "%s: i2c wr failed=%d reg=%02x " \ - "len=%d\n", KBUILD_MODNAME, ret, reg, len); - ret = -EREMOTEIO; - } - return ret; -} - -/* read multiple registers */ -static int cxd2820r_rd_regs_i2c(struct cxd2820r_priv *priv, u8 i2c, u8 reg, - u8 *val, int len) -{ - int ret; - u8 buf[MAX_XFER_SIZE]; - struct i2c_msg msg[2] = { - { - .addr = i2c, - .flags = 0, - .len = 1, - .buf = ®, - }, { - .addr = i2c, - .flags = I2C_M_RD, - .len = len, - .buf = buf, - } - }; - - if (len > sizeof(buf)) { - dev_warn(&priv->i2c->dev, - "%s: i2c wr reg=%04x: len=%d is too big!\n", - KBUILD_MODNAME, reg, len); - return -EINVAL; - } - - ret = i2c_transfer(priv->i2c, msg, 2); - if (ret == 2) { - memcpy(val, buf, len); - ret = 0; - } else { - dev_warn(&priv->i2c->dev, "%s: i2c rd failed=%d reg=%02x " \ - "len=%d\n", KBUILD_MODNAME, ret, reg, len); - ret = -EREMOTEIO; - } - - return ret; -} - -/* write multiple registers */ -int cxd2820r_wr_regs(struct cxd2820r_priv *priv, u32 reginfo, u8 *val, - int len) +/* Write register table */ +int cxd2820r_wr_reg_val_mask_tab(struct cxd2820r_priv *priv, + const struct reg_val_mask *tab, int tab_len) { + struct i2c_client *client = priv->client[0]; int ret; - u8 i2c_addr; - u8 reg = (reginfo >> 0) & 0xff; - u8 bank = (reginfo >> 8) & 0xff; - u8 i2c = (reginfo >> 16) & 0x01; - - /* select I2C */ - if (i2c) - i2c_addr = priv->cfg.i2c_address | (1 << 1); /* DVB-C */ - else - i2c_addr = priv->cfg.i2c_address; /* DVB-T/T2 */ + unsigned int i, reg, mask, val; + struct regmap *regmap; - /* switch bank if needed */ - if (bank != priv->bank[i2c]) { - ret = cxd2820r_wr_regs_i2c(priv, i2c_addr, 0x00, &bank, 1); - if (ret) - return ret; - priv->bank[i2c] = bank; - } - return cxd2820r_wr_regs_i2c(priv, i2c_addr, reg, val, len); -} - -/* read multiple registers */ -int cxd2820r_rd_regs(struct cxd2820r_priv *priv, u32 reginfo, u8 *val, - int len) -{ - int ret; - u8 i2c_addr; - u8 reg = (reginfo >> 0) & 0xff; - u8 bank = (reginfo >> 8) & 0xff; - u8 i2c = (reginfo >> 16) & 0x01; - - /* select I2C */ - if (i2c) - i2c_addr = priv->cfg.i2c_address | (1 << 1); /* DVB-C */ - else - i2c_addr = priv->cfg.i2c_address; /* DVB-T/T2 */ + dev_dbg(&client->dev, "tab_len=%d\n", tab_len); - /* switch bank if needed */ - if (bank != priv->bank[i2c]) { - ret = cxd2820r_wr_regs_i2c(priv, i2c_addr, 0x00, &bank, 1); - if (ret) - return ret; - priv->bank[i2c] = bank; - } - return cxd2820r_rd_regs_i2c(priv, i2c_addr, reg, val, len); -} - -/* write single register */ -int cxd2820r_wr_reg(struct cxd2820r_priv *priv, u32 reg, u8 val) -{ - return cxd2820r_wr_regs(priv, reg, &val, 1); -} - -/* read single register */ -int cxd2820r_rd_reg(struct cxd2820r_priv *priv, u32 reg, u8 *val) -{ - return cxd2820r_rd_regs(priv, reg, val, 1); -} + for (i = 0; i < tab_len; i++) { + if ((tab[i].reg >> 16) & 0x1) + regmap = priv->regmap[1]; + else + regmap = priv->regmap[0]; -/* write single register with mask */ -int cxd2820r_wr_reg_mask(struct cxd2820r_priv *priv, u32 reg, u8 val, - u8 mask) -{ - int ret; - u8 tmp; + reg = (tab[i].reg >> 0) & 0xffff; + val = tab[i].val; + mask = tab[i].mask; - /* no need for read if whole reg is written */ - if (mask != 0xff) { - ret = cxd2820r_rd_reg(priv, reg, &tmp); + if (mask == 0xff) + ret = regmap_write(regmap, reg, val); + else + ret = regmap_write_bits(regmap, reg, mask, val); if (ret) - return ret; - - val &= mask; - tmp &= ~mask; - val |= tmp; + goto error; } - return cxd2820r_wr_reg(priv, reg, val); + return 0; +error: + dev_dbg(&client->dev, "failed=%d\n", ret); + return ret; } int cxd2820r_gpio(struct dvb_frontend *fe, u8 *gpio) { struct cxd2820r_priv *priv = fe->demodulator_priv; + struct i2c_client *client = priv->client[0]; + struct dtv_frontend_properties *c = &fe->dtv_property_cache; int ret, i; u8 tmp0, tmp1; - dev_dbg(&priv->i2c->dev, "%s: delsys=%d\n", __func__, - fe->dtv_property_cache.delivery_system); + dev_dbg(&client->dev, "delivery_system=%d\n", c->delivery_system); /* update GPIOs only when needed */ if (!memcmp(gpio, priv->gpio, sizeof(priv->gpio))) @@ -219,20 +91,18 @@ int cxd2820r_gpio(struct dvb_frontend *fe, u8 *gpio) else tmp1 |= (0 << (0 + i)); - dev_dbg(&priv->i2c->dev, "%s: gpio i=%d %02x %02x\n", __func__, - i, tmp0, tmp1); + dev_dbg(&client->dev, "gpio i=%d %02x %02x\n", i, tmp0, tmp1); } - dev_dbg(&priv->i2c->dev, "%s: wr gpio=%02x %02x\n", __func__, tmp0, - tmp1); + dev_dbg(&client->dev, "wr gpio=%02x %02x\n", tmp0, tmp1); /* write bits [7:2] */ - ret = cxd2820r_wr_reg_mask(priv, 0x00089, tmp0, 0xfc); + ret = regmap_update_bits(priv->regmap[0], 0x0089, 0xfc, tmp0); if (ret) goto error; /* write bits [5:0] */ - ret = cxd2820r_wr_reg_mask(priv, 0x0008e, tmp1, 0x3f); + ret = regmap_update_bits(priv->regmap[0], 0x008e, 0x3f, tmp1); if (ret) goto error; @@ -240,18 +110,18 @@ int cxd2820r_gpio(struct dvb_frontend *fe, u8 *gpio) return ret; error: - dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); + dev_dbg(&client->dev, "failed=%d\n", ret); return ret; } static int cxd2820r_set_frontend(struct dvb_frontend *fe) { struct cxd2820r_priv *priv = fe->demodulator_priv; + struct i2c_client *client = priv->client[0]; struct dtv_frontend_properties *c = &fe->dtv_property_cache; int ret; - dev_dbg(&priv->i2c->dev, "%s: delsys=%d\n", __func__, - fe->dtv_property_cache.delivery_system); + dev_dbg(&client->dev, "delivery_system=%d\n", c->delivery_system); switch (c->delivery_system) { case SYS_DVBT: @@ -279,8 +149,7 @@ static int cxd2820r_set_frontend(struct dvb_frontend *fe) goto err; break; default: - dev_dbg(&priv->i2c->dev, "%s: error state=%d\n", __func__, - fe->dtv_property_cache.delivery_system); + dev_dbg(&client->dev, "invalid delivery_system\n"); ret = -EINVAL; break; } @@ -291,12 +160,13 @@ err: static int cxd2820r_read_status(struct dvb_frontend *fe, enum fe_status *status) { struct cxd2820r_priv *priv = fe->demodulator_priv; + struct i2c_client *client = priv->client[0]; + struct dtv_frontend_properties *c = &fe->dtv_property_cache; int ret; - dev_dbg(&priv->i2c->dev, "%s: delsys=%d\n", __func__, - fe->dtv_property_cache.delivery_system); + dev_dbg(&client->dev, "delivery_system=%d\n", c->delivery_system); - switch (fe->dtv_property_cache.delivery_system) { + switch (c->delivery_system) { case SYS_DVBT: ret = cxd2820r_read_status_t(fe, status); break; @@ -317,15 +187,16 @@ static int cxd2820r_get_frontend(struct dvb_frontend *fe, struct dtv_frontend_properties *p) { struct cxd2820r_priv *priv = fe->demodulator_priv; + struct i2c_client *client = priv->client[0]; + struct dtv_frontend_properties *c = &fe->dtv_property_cache; int ret; - dev_dbg(&priv->i2c->dev, "%s: delsys=%d\n", __func__, - fe->dtv_property_cache.delivery_system); + dev_dbg(&client->dev, "delivery_system=%d\n", c->delivery_system); if (priv->delivery_system == SYS_UNDEFINED) return 0; - switch (fe->dtv_property_cache.delivery_system) { + switch (c->delivery_system) { case SYS_DVBT: ret = cxd2820r_get_frontend_t(fe, p); break; @@ -345,101 +216,60 @@ static int cxd2820r_get_frontend(struct dvb_frontend *fe, static int cxd2820r_read_ber(struct dvb_frontend *fe, u32 *ber) { struct cxd2820r_priv *priv = fe->demodulator_priv; - int ret; + struct i2c_client *client = priv->client[0]; + struct dtv_frontend_properties *c = &fe->dtv_property_cache; - dev_dbg(&priv->i2c->dev, "%s: delsys=%d\n", __func__, - fe->dtv_property_cache.delivery_system); + dev_dbg(&client->dev, "delivery_system=%d\n", c->delivery_system); - switch (fe->dtv_property_cache.delivery_system) { - case SYS_DVBT: - ret = cxd2820r_read_ber_t(fe, ber); - break; - case SYS_DVBT2: - ret = cxd2820r_read_ber_t2(fe, ber); - break; - case SYS_DVBC_ANNEX_A: - ret = cxd2820r_read_ber_c(fe, ber); - break; - default: - ret = -EINVAL; - break; - } - return ret; + *ber = (priv->post_bit_error - priv->post_bit_error_prev_dvbv3); + priv->post_bit_error_prev_dvbv3 = priv->post_bit_error; + + return 0; } static int cxd2820r_read_signal_strength(struct dvb_frontend *fe, u16 *strength) { struct cxd2820r_priv *priv = fe->demodulator_priv; - int ret; + struct i2c_client *client = priv->client[0]; + struct dtv_frontend_properties *c = &fe->dtv_property_cache; - dev_dbg(&priv->i2c->dev, "%s: delsys=%d\n", __func__, - fe->dtv_property_cache.delivery_system); + dev_dbg(&client->dev, "delivery_system=%d\n", c->delivery_system); - switch (fe->dtv_property_cache.delivery_system) { - case SYS_DVBT: - ret = cxd2820r_read_signal_strength_t(fe, strength); - break; - case SYS_DVBT2: - ret = cxd2820r_read_signal_strength_t2(fe, strength); - break; - case SYS_DVBC_ANNEX_A: - ret = cxd2820r_read_signal_strength_c(fe, strength); - break; - default: - ret = -EINVAL; - break; - } - return ret; + if (c->strength.stat[0].scale == FE_SCALE_RELATIVE) + *strength = c->strength.stat[0].uvalue; + else + *strength = 0; + + return 0; } static int cxd2820r_read_snr(struct dvb_frontend *fe, u16 *snr) { struct cxd2820r_priv *priv = fe->demodulator_priv; - int ret; + struct i2c_client *client = priv->client[0]; + struct dtv_frontend_properties *c = &fe->dtv_property_cache; - dev_dbg(&priv->i2c->dev, "%s: delsys=%d\n", __func__, - fe->dtv_property_cache.delivery_system); + dev_dbg(&client->dev, "delivery_system=%d\n", c->delivery_system); - switch (fe->dtv_property_cache.delivery_system) { - case SYS_DVBT: - ret = cxd2820r_read_snr_t(fe, snr); - break; - case SYS_DVBT2: - ret = cxd2820r_read_snr_t2(fe, snr); - break; - case SYS_DVBC_ANNEX_A: - ret = cxd2820r_read_snr_c(fe, snr); - break; - default: - ret = -EINVAL; - break; |