summaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb-frontends
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/dvb-frontends')
-rw-r--r--drivers/media/dvb-frontends/Kconfig2
-rw-r--r--drivers/media/dvb-frontends/ascot2e.c2
-rw-r--r--drivers/media/dvb-frontends/cxd2820r.h26
-rw-r--r--drivers/media/dvb-frontends/cxd2820r_c.c302
-rw-r--r--drivers/media/dvb-frontends/cxd2820r_core.c597
-rw-r--r--drivers/media/dvb-frontends/cxd2820r_priv.h42
-rw-r--r--drivers/media/dvb-frontends/cxd2820r_t.c300
-rw-r--r--drivers/media/dvb-frontends/cxd2820r_t2.c278
-rw-r--r--drivers/media/dvb-frontends/cxd2841er.c108
-rw-r--r--drivers/media/dvb-frontends/drxk_hard.c2
-rw-r--r--drivers/media/dvb-frontends/dvb-pll.c2
-rw-r--r--drivers/media/dvb-frontends/helene.c12
-rw-r--r--drivers/media/dvb-frontends/horus3a.c2
-rw-r--r--drivers/media/dvb-frontends/ix2505v.c2
-rw-r--r--drivers/media/dvb-frontends/lgdt3306a.c18
-rw-r--r--drivers/media/dvb-frontends/mb86a20s.c104
-rw-r--r--drivers/media/dvb-frontends/si2165.c228
-rw-r--r--drivers/media/dvb-frontends/si2165.h27
-rw-r--r--drivers/media/dvb-frontends/si2165_priv.h17
-rw-r--r--drivers/media/dvb-frontends/stb6000.c2
-rw-r--r--drivers/media/dvb-frontends/stb6100.c2
-rw-r--r--drivers/media/dvb-frontends/stv6110.c2
-rw-r--r--drivers/media/dvb-frontends/stv6110x.c2
-rw-r--r--drivers/media/dvb-frontends/tda18271c2dd.c2
-rw-r--r--drivers/media/dvb-frontends/tda665x.c2
-rw-r--r--drivers/media/dvb-frontends/tda8261.c2
-rw-r--r--drivers/media/dvb-frontends/tda826x.c2
-rw-r--r--drivers/media/dvb-frontends/ts2020.c2
-rw-r--r--drivers/media/dvb-frontends/tua6100.c2
-rw-r--r--drivers/media/dvb-frontends/zl10036.c2
-rw-r--r--drivers/media/dvb-frontends/zl10039.c2
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 = &reg,
- }, {
- .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;