* [PATCH 1/8] m88ds3103: do not return error from get_frontend() when not ready
@ 2015-05-18 5:08 Antti Palosaari
2015-05-18 5:08 ` [PATCH 2/8] m88ds3103: implement DVBv5 CNR statistics Antti Palosaari
` (7 more replies)
0 siblings, 8 replies; 9+ messages in thread
From: Antti Palosaari @ 2015-05-18 5:08 UTC (permalink / raw)
To: linux-media; +Cc: Antti Palosaari
Do not return error from get_frontend() when status is queried, but
device is not ready. dvbv5-zap has habit to call that IOCTL before
device is tuned and it also refuses to use DVBv5 statistic after
that...
Signed-off-by: Antti Palosaari <crope@iki.fi>
---
drivers/media/dvb-frontends/m88ds3103.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/media/dvb-frontends/m88ds3103.c b/drivers/media/dvb-frontends/m88ds3103.c
index d3d928e..03dceb5 100644
--- a/drivers/media/dvb-frontends/m88ds3103.c
+++ b/drivers/media/dvb-frontends/m88ds3103.c
@@ -742,7 +742,7 @@ static int m88ds3103_get_frontend(struct dvb_frontend *fe)
dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
if (!priv->warm || !(priv->fe_status & FE_HAS_LOCK)) {
- ret = -EAGAIN;
+ ret = 0;
goto err;
}
--
http://palosaari.fi/
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 2/8] m88ds3103: implement DVBv5 CNR statistics
2015-05-18 5:08 [PATCH 1/8] m88ds3103: do not return error from get_frontend() when not ready Antti Palosaari
@ 2015-05-18 5:08 ` Antti Palosaari
2015-05-18 5:08 ` [PATCH 3/8] m88ds3103: wrap legacy DVBv3 SNR to DVBv5 CNR Antti Palosaari
` (6 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Antti Palosaari @ 2015-05-18 5:08 UTC (permalink / raw)
To: linux-media; +Cc: Antti Palosaari
Implement DVBv5 CNR statistics.
Signed-off-by: Antti Palosaari <crope@iki.fi>
---
drivers/media/dvb-frontends/m88ds3103.c | 80 ++++++++++++++++++++++++++++++++-
1 file changed, 78 insertions(+), 2 deletions(-)
diff --git a/drivers/media/dvb-frontends/m88ds3103.c b/drivers/media/dvb-frontends/m88ds3103.c
index 03dceb5..980a89e 100644
--- a/drivers/media/dvb-frontends/m88ds3103.c
+++ b/drivers/media/dvb-frontends/m88ds3103.c
@@ -190,8 +190,9 @@ static int m88ds3103_read_status(struct dvb_frontend *fe, fe_status_t *status)
{
struct m88ds3103_priv *priv = fe->demodulator_priv;
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
- int ret;
+ int ret, i, itmp;
u8 u8tmp;
+ u8 buf[3];
*status = 0;
@@ -233,6 +234,77 @@ static int m88ds3103_read_status(struct dvb_frontend *fe, fe_status_t *status)
dev_dbg(&priv->i2c->dev, "%s: lock=%02x status=%02x\n",
__func__, u8tmp, *status);
+ /* CNR */
+ if (priv->fe_status & FE_HAS_VITERBI) {
+ unsigned int cnr, noise, signal, noise_tot, signal_tot;
+
+ cnr = 0;
+ /* more iterations for more accurate estimation */
+ #define M88DS3103_SNR_ITERATIONS 3
+
+ switch (c->delivery_system) {
+ case SYS_DVBS:
+ itmp = 0;
+
+ for (i = 0; i < M88DS3103_SNR_ITERATIONS; i++) {
+ ret = m88ds3103_rd_reg(priv, 0xff, &buf[0]);
+ if (ret)
+ goto err;
+
+ itmp += buf[0];
+ }
+
+ /* use of single register limits max value to 15 dB */
+ /* SNR(X) dB = 10 * ln(X) / ln(10) dB */
+ itmp = DIV_ROUND_CLOSEST(itmp, 8 * M88DS3103_SNR_ITERATIONS);
+ if (itmp)
+ cnr = div_u64((u64) 10000 * intlog2(itmp), intlog2(10));
+ break;
+ case SYS_DVBS2:
+ noise_tot = 0;
+ signal_tot = 0;
+
+ for (i = 0; i < M88DS3103_SNR_ITERATIONS; i++) {
+ ret = m88ds3103_rd_regs(priv, 0x8c, buf, 3);
+ if (ret)
+ goto err;
+
+ noise = buf[1] << 6; /* [13:6] */
+ noise |= buf[0] & 0x3f; /* [5:0] */
+ noise >>= 2;
+ signal = buf[2] * buf[2];
+ signal >>= 1;
+
+ noise_tot += noise;
+ signal_tot += signal;
+ }
+
+ noise = noise_tot / M88DS3103_SNR_ITERATIONS;
+ signal = signal_tot / M88DS3103_SNR_ITERATIONS;
+
+ /* SNR(X) dB = 10 * log10(X) dB */
+ if (signal > noise) {
+ itmp = signal / noise;
+ cnr = div_u64((u64) 10000 * intlog10(itmp), (1 << 24));
+ }
+ break;
+ default:
+ dev_dbg(&priv->i2c->dev,
+ "%s: invalid delivery_system\n", __func__);
+ ret = -EINVAL;
+ goto err;
+ }
+
+ if (cnr) {
+ c->cnr.stat[0].scale = FE_SCALE_DECIBEL;
+ c->cnr.stat[0].svalue = cnr;
+ } else {
+ c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+ }
+ } else {
+ c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+ }
+
return 0;
err:
dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
@@ -577,6 +649,7 @@ err:
static int m88ds3103_init(struct dvb_frontend *fe)
{
struct m88ds3103_priv *priv = fe->demodulator_priv;
+ struct dtv_frontend_properties *c = &fe->dtv_property_cache;
int ret, len, remaining;
const struct firmware *fw = NULL;
u8 *fw_file;
@@ -684,7 +757,9 @@ static int m88ds3103_init(struct dvb_frontend *fe)
skip_fw_download:
/* warm state */
priv->warm = true;
-
+ /* init stats here in order signal app which stats are supported */
+ c->cnr.len = 1;
+ c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
return 0;
error_fw_release:
@@ -702,6 +777,7 @@ static int m88ds3103_sleep(struct dvb_frontend *fe)
dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
+ priv->fe_status = 0;
priv->delivery_system = SYS_UNDEFINED;
/* TS Hi-Z */
--
http://palosaari.fi/
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 3/8] m88ds3103: wrap legacy DVBv3 SNR to DVBv5 CNR
2015-05-18 5:08 [PATCH 1/8] m88ds3103: do not return error from get_frontend() when not ready Antti Palosaari
2015-05-18 5:08 ` [PATCH 2/8] m88ds3103: implement DVBv5 CNR statistics Antti Palosaari
@ 2015-05-18 5:08 ` Antti Palosaari
2015-05-18 5:08 ` [PATCH 4/8] m88ds3103: implement DVBv5 BER Antti Palosaari
` (5 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Antti Palosaari @ 2015-05-18 5:08 UTC (permalink / raw)
To: linux-media; +Cc: Antti Palosaari
Use DVBv5 CNR logic to calculate DVBv3 SNR too.
Signed-off-by: Antti Palosaari <crope@iki.fi>
---
drivers/media/dvb-frontends/m88ds3103.c | 74 ++-------------------------------
1 file changed, 4 insertions(+), 70 deletions(-)
diff --git a/drivers/media/dvb-frontends/m88ds3103.c b/drivers/media/dvb-frontends/m88ds3103.c
index 980a89e..381a8ad 100644
--- a/drivers/media/dvb-frontends/m88ds3103.c
+++ b/drivers/media/dvb-frontends/m88ds3103.c
@@ -984,80 +984,14 @@ err:
static int m88ds3103_read_snr(struct dvb_frontend *fe, u16 *snr)
{
- struct m88ds3103_priv *priv = fe->demodulator_priv;
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
- int ret, i, tmp;
- u8 buf[3];
- u16 noise, signal;
- u32 noise_tot, signal_tot;
-
- dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
- /* reports SNR in resolution of 0.1 dB */
-
- /* more iterations for more accurate estimation */
- #define M88DS3103_SNR_ITERATIONS 3
- switch (c->delivery_system) {
- case SYS_DVBS:
- tmp = 0;
-
- for (i = 0; i < M88DS3103_SNR_ITERATIONS; i++) {
- ret = m88ds3103_rd_reg(priv, 0xff, &buf[0]);
- if (ret)
- goto err;
-
- tmp += buf[0];
- }
-
- /* use of one register limits max value to 15 dB */
- /* SNR(X) dB = 10 * ln(X) / ln(10) dB */
- tmp = DIV_ROUND_CLOSEST(tmp, 8 * M88DS3103_SNR_ITERATIONS);
- if (tmp)
- *snr = div_u64((u64) 100 * intlog2(tmp), intlog2(10));
- else
- *snr = 0;
- break;
- case SYS_DVBS2:
- noise_tot = 0;
- signal_tot = 0;
-
- for (i = 0; i < M88DS3103_SNR_ITERATIONS; i++) {
- ret = m88ds3103_rd_regs(priv, 0x8c, buf, 3);
- if (ret)
- goto err;
-
- noise = buf[1] << 6; /* [13:6] */
- noise |= buf[0] & 0x3f; /* [5:0] */
- noise >>= 2;
- signal = buf[2] * buf[2];
- signal >>= 1;
-
- noise_tot += noise;
- signal_tot += signal;
- }
-
- noise = noise_tot / M88DS3103_SNR_ITERATIONS;
- signal = signal_tot / M88DS3103_SNR_ITERATIONS;
-
- /* SNR(X) dB = 10 * log10(X) dB */
- if (signal > noise) {
- tmp = signal / noise;
- *snr = div_u64((u64) 100 * intlog10(tmp), (1 << 24));
- } else {
- *snr = 0;
- }
- break;
- default:
- dev_dbg(&priv->i2c->dev, "%s: invalid delivery_system\n",
- __func__);
- ret = -EINVAL;
- goto err;
- }
+ if (c->cnr.stat[0].scale == FE_SCALE_DECIBEL)
+ *snr = div_s64(c->cnr.stat[0].svalue, 100);
+ else
+ *snr = 0;
return 0;
-err:
- dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
- return ret;
}
static int m88ds3103_read_ber(struct dvb_frontend *fe, u32 *ber)
--
http://palosaari.fi/
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 4/8] m88ds3103: implement DVBv5 BER
2015-05-18 5:08 [PATCH 1/8] m88ds3103: do not return error from get_frontend() when not ready Antti Palosaari
2015-05-18 5:08 ` [PATCH 2/8] m88ds3103: implement DVBv5 CNR statistics Antti Palosaari
2015-05-18 5:08 ` [PATCH 3/8] m88ds3103: wrap legacy DVBv3 SNR to DVBv5 CNR Antti Palosaari
@ 2015-05-18 5:08 ` Antti Palosaari
2015-05-18 5:08 ` [PATCH 5/8] m88ds3103: wrap legacy DVBv3 BER to " Antti Palosaari
` (4 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Antti Palosaari @ 2015-05-18 5:08 UTC (permalink / raw)
To: linux-media; +Cc: Antti Palosaari
Implement DVBv5 BER statistics.
Signed-off-by: Antti Palosaari <crope@iki.fi>
---
drivers/media/dvb-frontends/m88ds3103.c | 88 ++++++++++++++++++++++++++++
drivers/media/dvb-frontends/m88ds3103_priv.h | 2 +
2 files changed, 90 insertions(+)
diff --git a/drivers/media/dvb-frontends/m88ds3103.c b/drivers/media/dvb-frontends/m88ds3103.c
index 381a8ad..3cf89b6 100644
--- a/drivers/media/dvb-frontends/m88ds3103.c
+++ b/drivers/media/dvb-frontends/m88ds3103.c
@@ -305,6 +305,90 @@ static int m88ds3103_read_status(struct dvb_frontend *fe, fe_status_t *status)
c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
}
+ /* BER */
+ if (priv->fe_status & FE_HAS_LOCK) {
+ unsigned int utmp, post_bit_error, post_bit_count;
+
+ switch (c->delivery_system) {
+ case SYS_DVBS:
+ ret = m88ds3103_wr_reg(priv, 0xf9, 0x04);
+ if (ret)
+ goto err;
+
+ ret = m88ds3103_rd_reg(priv, 0xf8, &u8tmp);
+ if (ret)
+ goto err;
+
+ /* measurement ready? */
+ if (!(u8tmp & 0x10)) {
+ ret = m88ds3103_rd_regs(priv, 0xf6, buf, 2);
+ if (ret)
+ goto err;
+
+ post_bit_error = buf[1] << 8 | buf[0] << 0;
+ post_bit_count = 0x800000;
+ priv->post_bit_error += post_bit_error;
+ priv->post_bit_count += post_bit_count;
+
+ /* restart measurement */
+ u8tmp |= 0x10;
+ ret = m88ds3103_wr_reg(priv, 0xf8, u8tmp);
+ if (ret)
+ goto err;
+ }
+ break;
+ case SYS_DVBS2:
+ ret = m88ds3103_rd_regs(priv, 0xd5, buf, 3);
+ if (ret)
+ goto err;
+
+ utmp = buf[2] << 16 | buf[1] << 8 | buf[0] << 0;
+
+ /* enough data? */
+ if (utmp > 4000) {
+ ret = m88ds3103_rd_regs(priv, 0xf7, buf, 2);
+ if (ret)
+ goto err;
+
+ post_bit_error = buf[1] << 8 | buf[0] << 0;
+ post_bit_count = 32 * utmp; /* TODO: FEC */
+ priv->post_bit_error += post_bit_error;
+ priv->post_bit_count += post_bit_count;
+
+ /* restart measurement */
+ ret = m88ds3103_wr_reg(priv, 0xd1, 0x01);
+ if (ret)
+ goto err;
+
+ ret = m88ds3103_wr_reg(priv, 0xf9, 0x01);
+ if (ret)
+ goto err;
+
+ ret = m88ds3103_wr_reg(priv, 0xf9, 0x00);
+ if (ret)
+ goto err;
+
+ ret = m88ds3103_wr_reg(priv, 0xd1, 0x00);
+ if (ret)
+ goto err;
+ }
+ break;
+ default:
+ dev_dbg(&priv->i2c->dev,
+ "%s: invalid delivery_system\n", __func__);
+ ret = -EINVAL;
+ goto err;
+ }
+
+ c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
+ c->post_bit_error.stat[0].uvalue = priv->post_bit_error;
+ c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER;
+ c->post_bit_count.stat[0].uvalue = priv->post_bit_count;
+ } else {
+ c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+ c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+ }
+
return 0;
err:
dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
@@ -760,6 +844,10 @@ skip_fw_download:
/* init stats here in order signal app which stats are supported */
c->cnr.len = 1;
c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+ c->post_bit_error.len = 1;
+ c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+ c->post_bit_count.len = 1;
+ c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
return 0;
error_fw_release:
diff --git a/drivers/media/dvb-frontends/m88ds3103_priv.h b/drivers/media/dvb-frontends/m88ds3103_priv.h
index a2c0958..aafa28c 100644
--- a/drivers/media/dvb-frontends/m88ds3103_priv.h
+++ b/drivers/media/dvb-frontends/m88ds3103_priv.h
@@ -45,6 +45,8 @@ struct m88ds3103_priv {
u8 chip_id;
/* main mclk is calculated for M88RS6000 dynamically */
u32 mclk_khz;
+ u64 post_bit_error;
+ u64 post_bit_count;
};
struct m88ds3103_reg_val {
--
http://palosaari.fi/
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 5/8] m88ds3103: wrap legacy DVBv3 BER to DVBv5 BER
2015-05-18 5:08 [PATCH 1/8] m88ds3103: do not return error from get_frontend() when not ready Antti Palosaari
` (2 preceding siblings ...)
2015-05-18 5:08 ` [PATCH 4/8] m88ds3103: implement DVBv5 BER Antti Palosaari
@ 2015-05-18 5:08 ` Antti Palosaari
2015-05-18 5:08 ` [PATCH 6/8] m88ds3103: use jiffies when polling DiSEqC TX ready Antti Palosaari
` (3 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Antti Palosaari @ 2015-05-18 5:08 UTC (permalink / raw)
To: linux-media; +Cc: Antti Palosaari
Use DVBv5 BER logic to calculate DVBv3 BER too.
Signed-off-by: Antti Palosaari <crope@iki.fi>
---
drivers/media/dvb-frontends/m88ds3103.c | 77 ++--------------------------
drivers/media/dvb-frontends/m88ds3103_priv.h | 2 +-
2 files changed, 4 insertions(+), 75 deletions(-)
diff --git a/drivers/media/dvb-frontends/m88ds3103.c b/drivers/media/dvb-frontends/m88ds3103.c
index 3cf89b6..33d8c19 100644
--- a/drivers/media/dvb-frontends/m88ds3103.c
+++ b/drivers/media/dvb-frontends/m88ds3103.c
@@ -329,6 +329,7 @@ static int m88ds3103_read_status(struct dvb_frontend *fe, fe_status_t *status)
post_bit_count = 0x800000;
priv->post_bit_error += post_bit_error;
priv->post_bit_count += post_bit_count;
+ priv->dvbv3_ber = post_bit_error;
/* restart measurement */
u8tmp |= 0x10;
@@ -354,6 +355,7 @@ static int m88ds3103_read_status(struct dvb_frontend *fe, fe_status_t *status)
post_bit_count = 32 * utmp; /* TODO: FEC */
priv->post_bit_error += post_bit_error;
priv->post_bit_count += post_bit_count;
+ priv->dvbv3_ber = post_bit_error;
/* restart measurement */
ret = m88ds3103_wr_reg(priv, 0xd1, 0x01);
@@ -1085,83 +1087,10 @@ static int m88ds3103_read_snr(struct dvb_frontend *fe, u16 *snr)
static int m88ds3103_read_ber(struct dvb_frontend *fe, u32 *ber)
{
struct m88ds3103_priv *priv = fe->demodulator_priv;
- struct dtv_frontend_properties *c = &fe->dtv_property_cache;
- int ret;
- unsigned int utmp;
- u8 buf[3], u8tmp;
-
- dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
-
- switch (c->delivery_system) {
- case SYS_DVBS:
- ret = m88ds3103_wr_reg(priv, 0xf9, 0x04);
- if (ret)
- goto err;
- ret = m88ds3103_rd_reg(priv, 0xf8, &u8tmp);
- if (ret)
- goto err;
-
- if (!(u8tmp & 0x10)) {
- u8tmp |= 0x10;
-
- ret = m88ds3103_rd_regs(priv, 0xf6, buf, 2);
- if (ret)
- goto err;
-
- priv->ber = (buf[1] << 8) | (buf[0] << 0);
-
- /* restart counters */
- ret = m88ds3103_wr_reg(priv, 0xf8, u8tmp);
- if (ret)
- goto err;
- }
- break;
- case SYS_DVBS2:
- ret = m88ds3103_rd_regs(priv, 0xd5, buf, 3);
- if (ret)
- goto err;
-
- utmp = (buf[2] << 16) | (buf[1] << 8) | (buf[0] << 0);
-
- if (utmp > 3000) {
- ret = m88ds3103_rd_regs(priv, 0xf7, buf, 2);
- if (ret)
- goto err;
-
- priv->ber = (buf[1] << 8) | (buf[0] << 0);
-
- /* restart counters */
- ret = m88ds3103_wr_reg(priv, 0xd1, 0x01);
- if (ret)
- goto err;
-
- ret = m88ds3103_wr_reg(priv, 0xf9, 0x01);
- if (ret)
- goto err;
-
- ret = m88ds3103_wr_reg(priv, 0xf9, 0x00);
- if (ret)
- goto err;
-
- ret = m88ds3103_wr_reg(priv, 0xd1, 0x00);
- if (ret)
- goto err;
- }
- break;
- default:
- dev_dbg(&priv->i2c->dev, "%s: invalid delivery_system\n",
- __func__);
- ret = -EINVAL;
- goto err;
- }
-
- *ber = priv->ber;
+ *ber = priv->dvbv3_ber;
return 0;
-err:
- dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
- return ret;
}
static int m88ds3103_set_tone(struct dvb_frontend *fe,
diff --git a/drivers/media/dvb-frontends/m88ds3103_priv.h b/drivers/media/dvb-frontends/m88ds3103_priv.h
index aafa28c..78e58e3 100644
--- a/drivers/media/dvb-frontends/m88ds3103_priv.h
+++ b/drivers/media/dvb-frontends/m88ds3103_priv.h
@@ -38,7 +38,7 @@ struct m88ds3103_priv {
struct dvb_frontend fe;
fe_delivery_system_t delivery_system;
fe_status_t fe_status;
- u32 ber;
+ u32 dvbv3_ber; /* for old DVBv3 API read_ber */
bool warm; /* FW running */
struct i2c_adapter *i2c_adapter;
/* auto detect chip id to do different config */
--
http://palosaari.fi/
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 6/8] m88ds3103: use jiffies when polling DiSEqC TX ready
2015-05-18 5:08 [PATCH 1/8] m88ds3103: do not return error from get_frontend() when not ready Antti Palosaari
` (3 preceding siblings ...)
2015-05-18 5:08 ` [PATCH 5/8] m88ds3103: wrap legacy DVBv3 BER to " Antti Palosaari
@ 2015-05-18 5:08 ` Antti Palosaari
2015-05-18 5:08 ` [PATCH 7/8] m88ds3103: add I2C client binding Antti Palosaari
` (2 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Antti Palosaari @ 2015-05-18 5:08 UTC (permalink / raw)
To: linux-media; +Cc: Antti Palosaari
Use jiffies to set timeout for DiSEqC TX ready polling. Using jiffies
is more elegant solution than looping N times with sleep.
Signed-off-by: Antti Palosaari <crope@iki.fi>
---
drivers/media/dvb-frontends/m88ds3103.c | 53 +++++++++++++++++++++------------
1 file changed, 34 insertions(+), 19 deletions(-)
diff --git a/drivers/media/dvb-frontends/m88ds3103.c b/drivers/media/dvb-frontends/m88ds3103.c
index 33d8c19..e45641f 100644
--- a/drivers/media/dvb-frontends/m88ds3103.c
+++ b/drivers/media/dvb-frontends/m88ds3103.c
@@ -1195,7 +1195,8 @@ static int m88ds3103_diseqc_send_master_cmd(struct dvb_frontend *fe,
struct dvb_diseqc_master_cmd *diseqc_cmd)
{
struct m88ds3103_priv *priv = fe->demodulator_priv;
- int ret, i;
+ int ret;
+ unsigned long timeout;
u8 u8tmp;
dev_dbg(&priv->i2c->dev, "%s: msg=%*ph\n", __func__,
@@ -1226,21 +1227,24 @@ static int m88ds3103_diseqc_send_master_cmd(struct dvb_frontend *fe,
if (ret)
goto err;
- /* DiSEqC message typical period is 54 ms */
- usleep_range(40000, 60000);
-
/* wait DiSEqC TX ready */
- for (i = 20, u8tmp = 1; i && u8tmp; i--) {
- usleep_range(5000, 10000);
+ #define SEND_MASTER_CMD_TIMEOUT 120
+ timeout = jiffies + msecs_to_jiffies(SEND_MASTER_CMD_TIMEOUT);
+
+ /* DiSEqC message typical period is 54 ms */
+ usleep_range(50000, 54000);
+ for (u8tmp = 1; !time_after(jiffies, timeout) && u8tmp;) {
ret = m88ds3103_rd_reg_mask(priv, 0xa1, &u8tmp, 0x40);
if (ret)
goto err;
}
- dev_dbg(&priv->i2c->dev, "%s: loop=%d\n", __func__, i);
-
- if (i == 0) {
+ if (u8tmp == 0) {
+ dev_dbg(&priv->i2c->dev, "%s: diseqc tx took %u ms\n", __func__,
+ jiffies_to_msecs(jiffies) -
+ (jiffies_to_msecs(timeout) - SEND_MASTER_CMD_TIMEOUT));
+ } else {
dev_dbg(&priv->i2c->dev, "%s: diseqc tx timeout\n", __func__);
ret = m88ds3103_wr_reg_mask(priv, 0xa1, 0x40, 0xc0);
@@ -1252,7 +1256,7 @@ static int m88ds3103_diseqc_send_master_cmd(struct dvb_frontend *fe,
if (ret)
goto err;
- if (i == 0) {
+ if (u8tmp == 1) {
ret = -ETIMEDOUT;
goto err;
}
@@ -1267,7 +1271,8 @@ static int m88ds3103_diseqc_send_burst(struct dvb_frontend *fe,
fe_sec_mini_cmd_t fe_sec_mini_cmd)
{
struct m88ds3103_priv *priv = fe->demodulator_priv;
- int ret, i;
+ int ret;
+ unsigned long timeout;
u8 u8tmp, burst;
dev_dbg(&priv->i2c->dev, "%s: fe_sec_mini_cmd=%d\n", __func__,
@@ -1301,26 +1306,36 @@ static int m88ds3103_diseqc_send_burst(struct dvb_frontend *fe,
if (ret)
goto err;
- /* DiSEqC ToneBurst period is 12.5 ms */
- usleep_range(11000, 20000);
-
/* wait DiSEqC TX ready */
- for (i = 5, u8tmp = 1; i && u8tmp; i--) {
- usleep_range(800, 2000);
+ #define SEND_BURST_TIMEOUT 40
+ timeout = jiffies + msecs_to_jiffies(SEND_BURST_TIMEOUT);
+
+ /* DiSEqC ToneBurst period is 12.5 ms */
+ usleep_range(8500, 12500);
+ for (u8tmp = 1; !time_after(jiffies, timeout) && u8tmp;) {
ret = m88ds3103_rd_reg_mask(priv, 0xa1, &u8tmp, 0x40);
if (ret)
goto err;
}
- dev_dbg(&priv->i2c->dev, "%s: loop=%d\n", __func__, i);
+ if (u8tmp == 0) {
+ dev_dbg(&priv->i2c->dev, "%s: diseqc tx took %u ms\n", __func__,
+ jiffies_to_msecs(jiffies) -
+ (jiffies_to_msecs(timeout) - SEND_BURST_TIMEOUT));
+ } else {
+ dev_dbg(&priv->i2c->dev, "%s: diseqc tx timeout\n", __func__);
+
+ ret = m88ds3103_wr_reg_mask(priv, 0xa1, 0x40, 0xc0);
+ if (ret)
+ goto err;
+ }
ret = m88ds3103_wr_reg_mask(priv, 0xa2, 0x80, 0xc0);
if (ret)
goto err;
- if (i == 0) {
- dev_dbg(&priv->i2c->dev, "%s: diseqc tx timeout\n", __func__);
+ if (u8tmp == 1) {
ret = -ETIMEDOUT;
goto err;
}
--
http://palosaari.fi/
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 7/8] m88ds3103: add I2C client binding
2015-05-18 5:08 [PATCH 1/8] m88ds3103: do not return error from get_frontend() when not ready Antti Palosaari
` (4 preceding siblings ...)
2015-05-18 5:08 ` [PATCH 6/8] m88ds3103: use jiffies when polling DiSEqC TX ready Antti Palosaari
@ 2015-05-18 5:08 ` Antti Palosaari
2015-05-18 5:08 ` [PATCH 8/8] m88ds3103: wrap media attach to driver I2C probe Antti Palosaari
2015-05-18 8:36 ` [PATCH 1/8] m88ds3103: do not return error from get_frontend() when not ready Jemma Denson
7 siblings, 0 replies; 9+ messages in thread
From: Antti Palosaari @ 2015-05-18 5:08 UTC (permalink / raw)
To: linux-media; +Cc: Antti Palosaari
Implement I2C client device binding.
Signed-off-by: Antti Palosaari <crope@iki.fi>
---
drivers/media/dvb-frontends/m88ds3103.c | 159 +++++++++++++++++++++++++++
drivers/media/dvb-frontends/m88ds3103.h | 51 +++++++++
drivers/media/dvb-frontends/m88ds3103_priv.h | 2 +
3 files changed, 212 insertions(+)
diff --git a/drivers/media/dvb-frontends/m88ds3103.c b/drivers/media/dvb-frontends/m88ds3103.c
index e45641f..d837dd2 100644
--- a/drivers/media/dvb-frontends/m88ds3103.c
+++ b/drivers/media/dvb-frontends/m88ds3103.c
@@ -1541,6 +1541,165 @@ static struct dvb_frontend_ops m88ds3103_ops = {
.set_voltage = m88ds3103_set_voltage,
};
+static struct dvb_frontend *m88ds3103_get_dvb_frontend(struct i2c_client *client)
+{
+ struct m88ds3103_priv *dev = i2c_get_clientdata(client);
+
+ dev_dbg(&client->dev, "\n");
+
+ return &dev->fe;
+}
+
+static struct i2c_adapter *m88ds3103_get_i2c_adapter(struct i2c_client *client)
+{
+ struct m88ds3103_priv *dev = i2c_get_clientdata(client);
+
+ dev_dbg(&client->dev, "\n");
+
+ return dev->i2c_adapter;
+}
+
+static int m88ds3103_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct m88ds3103_priv *dev;
+ struct m88ds3103_platform_data *pdata = client->dev.platform_data;
+ int ret;
+ u8 chip_id, u8tmp;
+
+ dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+ if (!dev) {
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ dev->client = client;
+ dev->i2c = client->adapter;
+ dev->config.i2c_addr = client->addr;
+ dev->config.clock = pdata->clk;
+ dev->config.i2c_wr_max = pdata->i2c_wr_max;
+ dev->config.ts_mode = pdata->ts_mode;
+ dev->config.ts_clk = pdata->ts_clk;
+ dev->config.ts_clk_pol = pdata->ts_clk_pol;
+ dev->config.spec_inv = pdata->spec_inv;
+ dev->config.agc_inv = pdata->agc_inv;
+ dev->config.clock_out = pdata->clk_out;
+ dev->config.envelope_mode = pdata->envelope_mode;
+ dev->config.agc = pdata->agc;
+ dev->config.lnb_hv_pol = pdata->lnb_hv_pol;
+ dev->config.lnb_en_pol = pdata->lnb_en_pol;
+ dev->cfg = &dev->config;
+ mutex_init(&dev->i2c_mutex);
+
+ /* 0x00: chip id[6:0], 0x01: chip ver[7:0], 0x02: chip ver[15:8] */
+ ret = m88ds3103_rd_reg(dev, 0x00, &chip_id);
+ if (ret)
+ goto err_kfree;
+
+ chip_id >>= 1;
+ dev_dbg(&client->dev, "chip_id=%02x\n", chip_id);
+
+ switch (chip_id) {
+ case M88RS6000_CHIP_ID:
+ case M88DS3103_CHIP_ID:
+ break;
+ default:
+ goto err_kfree;
+ }
+ dev->chip_id = chip_id;
+
+ switch (dev->cfg->clock_out) {
+ case M88DS3103_CLOCK_OUT_DISABLED:
+ u8tmp = 0x80;
+ break;
+ case M88DS3103_CLOCK_OUT_ENABLED:
+ u8tmp = 0x00;
+ break;
+ case M88DS3103_CLOCK_OUT_ENABLED_DIV2:
+ u8tmp = 0x10;
+ break;
+ default:
+ goto err_kfree;
+ }
+
+ /* 0x29 register is defined differently for m88rs6000. */
+ /* set internal tuner address to 0x21 */
+ if (chip_id == M88RS6000_CHIP_ID)
+ u8tmp = 0x00;
+
+ ret = m88ds3103_wr_reg(dev, 0x29, u8tmp);
+ if (ret)
+ goto err_kfree;
+
+ /* sleep */
+ ret = m88ds3103_wr_reg_mask(dev, 0x08, 0x00, 0x01);
+ if (ret)
+ goto err_kfree;
+ ret = m88ds3103_wr_reg_mask(dev, 0x04, 0x01, 0x01);
+ if (ret)
+ goto err_kfree;
+ ret = m88ds3103_wr_reg_mask(dev, 0x23, 0x10, 0x10);
+ if (ret)
+ goto err_kfree;
+
+ /* create mux i2c adapter for tuner */
+ dev->i2c_adapter = i2c_add_mux_adapter(client->adapter, &client->dev,
+ dev, 0, 0, 0, m88ds3103_select,
+ m88ds3103_deselect);
+ if (dev->i2c_adapter == NULL)
+ goto err_kfree;
+
+ /* create dvb_frontend */
+ memcpy(&dev->fe.ops, &m88ds3103_ops, sizeof(struct dvb_frontend_ops));
+ if (dev->chip_id == M88RS6000_CHIP_ID)
+ strncpy(dev->fe.ops.info.name,
+ "Montage M88RS6000", sizeof(dev->fe.ops.info.name));
+ dev->fe.ops.release = NULL;
+ dev->fe.demodulator_priv = dev;
+ i2c_set_clientdata(client, dev);
+
+ /* setup callbacks */
+ pdata->get_dvb_frontend = m88ds3103_get_dvb_frontend;
+ pdata->get_i2c_adapter = m88ds3103_get_i2c_adapter;
+ return 0;
+err_kfree:
+ kfree(dev);
+err:
+ dev_dbg(&client->dev, "failed=%d\n", ret);
+ return ret;
+}
+
+static int m88ds3103_remove(struct i2c_client *client)
+{
+ struct m88ds3103_priv *dev = i2c_get_clientdata(client);
+
+ dev_dbg(&client->dev, "\n");
+
+ i2c_del_mux_adapter(dev->i2c_adapter);
+
+ kfree(dev);
+ return 0;
+}
+
+static const struct i2c_device_id m88ds3103_id_table[] = {
+ {"m88ds3103", 0},
+ {}
+};
+MODULE_DEVICE_TABLE(i2c, m88ds3103_id_table);
+
+static struct i2c_driver m88ds3103_driver = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "m88ds3103",
+ .suppress_bind_attrs = true,
+ },
+ .probe = m88ds3103_probe,
+ .remove = m88ds3103_remove,
+ .id_table = m88ds3103_id_table,
+};
+
+module_i2c_driver(m88ds3103_driver);
+
MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
MODULE_DESCRIPTION("Montage M88DS3103 DVB-S/S2 demodulator driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb-frontends/m88ds3103.h b/drivers/media/dvb-frontends/m88ds3103.h
index 9b3b496..ddcd10a 100644
--- a/drivers/media/dvb-frontends/m88ds3103.h
+++ b/drivers/media/dvb-frontends/m88ds3103.h
@@ -19,6 +19,57 @@
#include <linux/dvb/frontend.h>
+/*
+ * I2C address
+ * 0x68,
+ */
+
+/**
+ * struct m88ds3103_platform_data - Platform data for the m88ds3103 driver
+ * @clk: Clock frequency.
+ * @i2c_wr_max: Max bytes I2C adapter can write at once.
+ * @ts_mode: TS mode.
+ * @ts_clk: TS clock (KHz).
+ * @ts_clk_pol: TS clk polarity. 1-active at falling edge; 0-active at rising
+ * edge.
+ * @spec_inv: Input spectrum inversion.
+ * @agc: AGC configuration.
+ * @agc_inv: AGC polarity.
+ * @clk_out: Clock output.
+ * @envelope_mode: DiSEqC envelope mode.
+ * @lnb_hv_pol: LNB H/V pin polarity. 0: pin high set to VOLTAGE_18, pin low to
+ * set VOLTAGE_13. 1: pin high set to VOLTAGE_13, pin low to set VOLTAGE_18.
+ * @lnb_en_pol: LNB enable pin polarity. 0: pin high to disable, pin low to
+ * enable. 1: pin high to enable, pin low to disable.
+ * @get_dvb_frontend: Get DVB frontend.
+ * @get_i2c_adapter: Get I2C adapter.
+ */
+
+struct m88ds3103_platform_data {
+ u32 clk;
+ u16 i2c_wr_max;
+#define M88DS3103_TS_SERIAL 0 /* TS output pin D0, normal */
+#define M88DS3103_TS_SERIAL_D7 1 /* TS output pin D7 */
+#define M88DS3103_TS_PARALLEL 2 /* TS Parallel mode */
+#define M88DS3103_TS_CI 3 /* TS CI Mode */
+ u8 ts_mode:2;
+ u32 ts_clk;
+ u8 ts_clk_pol:1;
+ u8 spec_inv:1;
+ u8 agc;
+ u8 agc_inv:1;
+#define M88DS3103_CLOCK_OUT_DISABLED 0
+#define M88DS3103_CLOCK_OUT_ENABLED 1
+#define M88DS3103_CLOCK_OUT_ENABLED_DIV2 2
+ u8 clk_out:2;
+ u8 envelope_mode:1;
+ u8 lnb_hv_pol:1;
+ u8 lnb_en_pol:1;
+
+ struct dvb_frontend* (*get_dvb_frontend)(struct i2c_client *);
+ struct i2c_adapter* (*get_i2c_adapter)(struct i2c_client *);
+};
+
struct m88ds3103_config {
/*
* I2C address
diff --git a/drivers/media/dvb-frontends/m88ds3103_priv.h b/drivers/media/dvb-frontends/m88ds3103_priv.h
index 78e58e3..6217d92 100644
--- a/drivers/media/dvb-frontends/m88ds3103_priv.h
+++ b/drivers/media/dvb-frontends/m88ds3103_priv.h
@@ -32,8 +32,10 @@
struct m88ds3103_priv {
struct i2c_adapter *i2c;
+ struct i2c_client *client;
/* mutex needed due to own tuner I2C adapter */
struct mutex i2c_mutex;
+ struct m88ds3103_config config;
const struct m88ds3103_config *cfg;
struct dvb_frontend fe;
fe_delivery_system_t delivery_system;
--
http://palosaari.fi/
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 8/8] m88ds3103: wrap media attach to driver I2C probe
2015-05-18 5:08 [PATCH 1/8] m88ds3103: do not return error from get_frontend() when not ready Antti Palosaari
` (5 preceding siblings ...)
2015-05-18 5:08 ` [PATCH 7/8] m88ds3103: add I2C client binding Antti Palosaari
@ 2015-05-18 5:08 ` Antti Palosaari
2015-05-18 8:36 ` [PATCH 1/8] m88ds3103: do not return error from get_frontend() when not ready Jemma Denson
7 siblings, 0 replies; 9+ messages in thread
From: Antti Palosaari @ 2015-05-18 5:08 UTC (permalink / raw)
To: linux-media; +Cc: Antti Palosaari
Add wrapper from m88ds3103_attach() to m88ds3103_probe() via driver
core in order to provide proper I2C client for legacy media attach
binding.
Signed-off-by: Antti Palosaari <crope@iki.fi>
---
drivers/media/dvb-frontends/m88ds3103.c | 129 +++++++++-----------------------
drivers/media/dvb-frontends/m88ds3103.h | 12 +--
2 files changed, 43 insertions(+), 98 deletions(-)
diff --git a/drivers/media/dvb-frontends/m88ds3103.c b/drivers/media/dvb-frontends/m88ds3103.c
index d837dd2..01b9ded 100644
--- a/drivers/media/dvb-frontends/m88ds3103.c
+++ b/drivers/media/dvb-frontends/m88ds3103.c
@@ -1357,9 +1357,9 @@ static int m88ds3103_get_tune_settings(struct dvb_frontend *fe,
static void m88ds3103_release(struct dvb_frontend *fe)
{
struct m88ds3103_priv *priv = fe->demodulator_priv;
+ struct i2c_client *client = priv->client;
- i2c_del_mux_adapter(priv->i2c_adapter);
- kfree(priv);
+ i2c_unregister_device(client);
}
static int m88ds3103_select(struct i2c_adapter *adap, void *mux_priv, u32 chan)
@@ -1401,98 +1401,42 @@ static int m88ds3103_deselect(struct i2c_adapter *adap, void *mux_priv,
return 0;
}
+/*
+ * XXX: That is wrapper to m88ds3103_probe() via driver core in order to provide
+ * proper I2C client for legacy media attach binding.
+ * New users must use I2C client binding directly!
+ */
struct dvb_frontend *m88ds3103_attach(const struct m88ds3103_config *cfg,
struct i2c_adapter *i2c, struct i2c_adapter **tuner_i2c_adapter)
{
- int ret;
- struct m88ds3103_priv *priv;
- u8 chip_id, u8tmp;
-
- /* allocate memory for the internal priv */
- priv = kzalloc(sizeof(*priv), GFP_KERNEL);
- if (!priv) {
- ret = -ENOMEM;
- dev_err(&i2c->dev, "%s: kzalloc() failed\n", KBUILD_MODNAME);
- goto err;
- }
-
- priv->cfg = cfg;
- priv->i2c = i2c;
- mutex_init(&priv->i2c_mutex);
-
- /* 0x00: chip id[6:0], 0x01: chip ver[7:0], 0x02: chip ver[15:8] */
- ret = m88ds3103_rd_reg(priv, 0x00, &chip_id);
- if (ret)
- goto err;
-
- chip_id >>= 1;
- dev_info(&priv->i2c->dev, "%s: chip_id=%02x\n", __func__, chip_id);
-
- switch (chip_id) {
- case M88RS6000_CHIP_ID:
- case M88DS3103_CHIP_ID:
- break;
- default:
- goto err;
- }
- priv->chip_id = chip_id;
-
- switch (priv->cfg->clock_out) {
- case M88DS3103_CLOCK_OUT_DISABLED:
- u8tmp = 0x80;
- break;
- case M88DS3103_CLOCK_OUT_ENABLED:
- u8tmp = 0x00;
- break;
- case M88DS3103_CLOCK_OUT_ENABLED_DIV2:
- u8tmp = 0x10;
- break;
- default:
- goto err;
- }
-
- /* 0x29 register is defined differently for m88rs6000. */
- /* set internal tuner address to 0x21 */
- if (chip_id == M88RS6000_CHIP_ID)
- u8tmp = 0x00;
-
- ret = m88ds3103_wr_reg(priv, 0x29, u8tmp);
- if (ret)
- goto err;
-
- /* sleep */
- ret = m88ds3103_wr_reg_mask(priv, 0x08, 0x00, 0x01);
- if (ret)
- goto err;
-
- ret = m88ds3103_wr_reg_mask(priv, 0x04, 0x01, 0x01);
- if (ret)
- goto err;
-
- ret = m88ds3103_wr_reg_mask(priv, 0x23, 0x10, 0x10);
- if (ret)
- goto err;
-
- /* create mux i2c adapter for tuner */
- priv->i2c_adapter = i2c_add_mux_adapter(i2c, &i2c->dev, priv, 0, 0, 0,
- m88ds3103_select, m88ds3103_deselect);
- if (priv->i2c_adapter == NULL)
- goto err;
-
- *tuner_i2c_adapter = priv->i2c_adapter;
-
- /* create dvb_frontend */
- memcpy(&priv->fe.ops, &m88ds3103_ops, sizeof(struct dvb_frontend_ops));
- if (priv->chip_id == M88RS6000_CHIP_ID)
- strncpy(priv->fe.ops.info.name,
- "Montage M88RS6000", sizeof(priv->fe.ops.info.name));
- priv->fe.demodulator_priv = priv;
-
- return &priv->fe;
-err:
- dev_dbg(&i2c->dev, "%s: failed=%d\n", __func__, ret);
- kfree(priv);
- return NULL;
+ struct i2c_client *client;
+ struct i2c_board_info board_info;
+ struct m88ds3103_platform_data pdata;
+
+ pdata.clk = cfg->clock;
+ pdata.i2c_wr_max = cfg->i2c_wr_max;
+ pdata.ts_mode = cfg->ts_mode;
+ pdata.ts_clk = cfg->ts_clk;
+ pdata.ts_clk_pol = cfg->ts_clk_pol;
+ pdata.spec_inv = cfg->spec_inv;
+ pdata.agc = cfg->agc;
+ pdata.agc_inv = cfg->agc_inv;
+ pdata.clk_out = cfg->clock_out;
+ pdata.envelope_mode = cfg->envelope_mode;
+ pdata.lnb_hv_pol = cfg->lnb_hv_pol;
+ pdata.lnb_en_pol = cfg->lnb_en_pol;
+ pdata.attach_in_use = true;
+
+ memset(&board_info, 0, sizeof(board_info));
+ strlcpy(board_info.type, "m88ds3103", I2C_NAME_SIZE);
+ board_info.addr = cfg->i2c_addr;
+ board_info.platform_data = &pdata;
+ client = i2c_new_device(i2c, &board_info);
+ if (!client || !client->dev.driver)
+ return NULL;
+
+ *tuner_i2c_adapter = pdata.get_i2c_adapter(client);
+ return pdata.get_dvb_frontend(client);
}
EXPORT_SYMBOL(m88ds3103_attach);
@@ -1654,7 +1598,8 @@ static int m88ds3103_probe(struct i2c_client *client,
if (dev->chip_id == M88RS6000_CHIP_ID)
strncpy(dev->fe.ops.info.name,
"Montage M88RS6000", sizeof(dev->fe.ops.info.name));
- dev->fe.ops.release = NULL;
+ if (!pdata->attach_in_use)
+ dev->fe.ops.release = NULL;
dev->fe.demodulator_priv = dev;
i2c_set_clientdata(client, dev);
diff --git a/drivers/media/dvb-frontends/m88ds3103.h b/drivers/media/dvb-frontends/m88ds3103.h
index ddcd10a..3811468 100644
--- a/drivers/media/dvb-frontends/m88ds3103.h
+++ b/drivers/media/dvb-frontends/m88ds3103.h
@@ -68,8 +68,14 @@ struct m88ds3103_platform_data {
struct dvb_frontend* (*get_dvb_frontend)(struct i2c_client *);
struct i2c_adapter* (*get_i2c_adapter)(struct i2c_client *);
+
+/* private: For legacy media attach wrapper. Do not set value. */
+ u8 attach_in_use:1;
};
+/*
+ * Do not add new m88ds3103_attach() users! Use I2C bindings instead.
+ */
struct m88ds3103_config {
/*
* I2C address
@@ -164,12 +170,6 @@ struct m88ds3103_config {
u8 lnb_en_pol:1;
};
-/*
- * Driver implements own I2C-adapter for tuner I2C access. That's since chip
- * has I2C-gate control which closes gate automatically after I2C transfer.
- * Using own I2C adapter we can workaround that.
- */
-
#if defined(CONFIG_DVB_M88DS3103) || \
(defined(CONFIG_DVB_M88DS3103_MODULE) && defined(MODULE))
extern struct dvb_frontend *m88ds3103_attach(
--
http://palosaari.fi/
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH 1/8] m88ds3103: do not return error from get_frontend() when not ready
2015-05-18 5:08 [PATCH 1/8] m88ds3103: do not return error from get_frontend() when not ready Antti Palosaari
` (6 preceding siblings ...)
2015-05-18 5:08 ` [PATCH 8/8] m88ds3103: wrap media attach to driver I2C probe Antti Palosaari
@ 2015-05-18 8:36 ` Jemma Denson
7 siblings, 0 replies; 9+ messages in thread
From: Jemma Denson @ 2015-05-18 8:36 UTC (permalink / raw)
To: Antti Palosaari, linux-media
Hi Antti,
On 18/05/15 06:08, Antti Palosaari wrote:
> Do not return error from get_frontend() when status is queried, but
> device is not ready. dvbv5-zap has habit to call that IOCTL before
> device is tuned and it also refuses to use DVBv5 statistic after
> that...
In the driver I'm working on I noticed that in dvb5-zap too. I also saw
a timing issue if holding fe_status in the priv struct - fe_status will
remain at FE_HAS_LOCK until read_status() spins around again and this
can cause get_frontend to proceed when it probably shouldn't. The end
result is this early call to get_frontend() overwrites the property
cache before zap has sent it through to set_frontend() and tuning then
fails.
Do we need to be fixing these issues at a driver level?
Jemma.
>
> Signed-off-by: Antti Palosaari <crope@iki.fi>
> ---
> drivers/media/dvb-frontends/m88ds3103.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/media/dvb-frontends/m88ds3103.c b/drivers/media/dvb-frontends/m88ds3103.c
> index d3d928e..03dceb5 100644
> --- a/drivers/media/dvb-frontends/m88ds3103.c
> +++ b/drivers/media/dvb-frontends/m88ds3103.c
> @@ -742,7 +742,7 @@ static int m88ds3103_get_frontend(struct dvb_frontend *fe)
> dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
>
> if (!priv->warm || !(priv->fe_status & FE_HAS_LOCK)) {
> - ret = -EAGAIN;
> + ret = 0;
> goto err;
> }
>
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2015-05-18 8:36 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-05-18 5:08 [PATCH 1/8] m88ds3103: do not return error from get_frontend() when not ready Antti Palosaari
2015-05-18 5:08 ` [PATCH 2/8] m88ds3103: implement DVBv5 CNR statistics Antti Palosaari
2015-05-18 5:08 ` [PATCH 3/8] m88ds3103: wrap legacy DVBv3 SNR to DVBv5 CNR Antti Palosaari
2015-05-18 5:08 ` [PATCH 4/8] m88ds3103: implement DVBv5 BER Antti Palosaari
2015-05-18 5:08 ` [PATCH 5/8] m88ds3103: wrap legacy DVBv3 BER to " Antti Palosaari
2015-05-18 5:08 ` [PATCH 6/8] m88ds3103: use jiffies when polling DiSEqC TX ready Antti Palosaari
2015-05-18 5:08 ` [PATCH 7/8] m88ds3103: add I2C client binding Antti Palosaari
2015-05-18 5:08 ` [PATCH 8/8] m88ds3103: wrap media attach to driver I2C probe Antti Palosaari
2015-05-18 8:36 ` [PATCH 1/8] m88ds3103: do not return error from get_frontend() when not ready Jemma Denson
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).