Skip to contentSkip to conversation

cxd2841er/ddbridge: support Sony CXD28xx hardware

PATCH In review Daniel Scheller 2 participants 41 messages Apr 9, 2017 – May 31, 2017 1 message not in the archive

Subsystems (4)
lore
Share & tools
lore
#0 lore raw

cover cxd2841er/ddbridge: support Sony CXD28xx hardware

From: Daniel Scheller <[email protected]>

Important note: This series depends on the stv0367/ddbridge series posted earlier (patches 12 [1] and 13 [2], depending on the I2C functions and the TDA18212 attach function).

This series improves the cxd2841er demodulator driver and adds some bits to make it more versatile to be used in more scenarios. Also, the ddbridge code is updated to recognize all hardware (PCIe cards/bridges and DuoFlex modules) with Sony CXD28xx tuners, including the newly introduced MaxA8 eight-tuner C2T2 cards.

The series has been tested (together with the STV0367 series) on a wide variety of cards, including CineCTv7, DuoFlex C(2)T2 modules and MaxA8 cards without any issues. Testing was done with TVHeadend, VDR and MythTV.

Note that the i2c_gate_ctrl() flag is needed in this series aswell since the i2c_gate_ctrl function needs to be remapped and mutex_lock protected for the same reasons as in the STV0367 series.

Besides printk() warnings, checkpatch.pl doesn't complain.

Comments and reviews appreciated.

[1] https://patchwork.linuxtv.org/patch/40398/
[2] https://patchwork.linuxtv.org/patch/40399/

Daniel Scheller (19):
[media] dvb-frontends/cxd2841er: remove kernel log spam in non-debug
levels
[media] dvb-frontends/cxd2841er: do I2C reads in one go [media] dvb-frontends/cxd2841er: immediately unfreeze regs when done [media] dvb-frontends/cxd2841er: support CXD2837/38/43ER demods/Chip
IDs
[media] dvb-frontends/cxd2841er: replace IFFREQ calc macros into
functions
[media] dvb-frontends/cxd2841er: add variable for configuration flags [media] dvb-frontends/cxd2841er: make call to i2c_gate_ctrl optional [media] dvb-frontends/cxd2841er: support IF speed calc from tuner
values
[media] dvb-frontends/cxd2841er: TS_SERIAL config flag [media] dvb-frontends/cxd2841er: make ASCOT use optional [media] dvb-frontends/cxd2841er: optionally tune earlier in
set_frontend()
[media] dvb-frontends/cxd2841er: make lock wait in set_fe_tc()
optional
[media] dvb-frontends/cxd2841er: configurable IFAGCNEG [media] dvb-frontends/cxd2841er: more configurable TSBITS [media] dvb-frontends/cxd2841er: improved snr reporting [media] ddbridge: board control setup, ts quirk flags [media] ddbridge: add I2C functions, add XO2 module support [media] ddbridge: support for Sony CXD28xx C/C2/T/T2 tuner modules [media] ddbridge: hardware IDs for new C2T2 cards and other devices

 drivers/media/dvb-frontends/cxd2841er.c            | 302 +++++++++++------
 drivers/media/dvb-frontends/cxd2841er.h            |  10 +
 drivers/media/dvb-frontends/cxd2841er_priv.h       |   3 +
 drivers/media/pci/ddbridge/Kconfig                 |   3 +
 drivers/media/pci/ddbridge/ddbridge-core.c         | 356 ++++++++++++++++++++-
 drivers/media/pci/ddbridge/ddbridge-regs.h         |   4 +
 drivers/media/pci/ddbridge/ddbridge.h              |  40 ++-
 drivers/media/pci/netup_unidvb/netup_unidvb_core.c |   3 +-
 8 files changed, 615 insertions(+), 106 deletions(-)
Signature · 1 line
2.10.2
#1 lore raw

PATCH 1/19 dvb-frontends/cxd2841er: remove kernel log spam in non-debug levels

From: Daniel Scheller <[email protected]>

This moves the I2C debug dump into the preceding dev_dbg() call by utilising the %*ph format macro and removes the call to print_hex_debug_bytes().

---
 drivers/media/dvb-frontends/cxd2841er.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)
drivers/media/dvb-frontends/cxd2841er.c +2 -4
index 614bfb3..60d85ce 100644
@@ -214,10 +214,8 @@ static void cxd2841er_i2c_debug(struct cxd2841er_priv *priv,
 				const u8 *data, u32 len)
 {
 	dev_dbg(&priv->i2c->dev,
-		"cxd2841er: I2C %s addr %02x reg 0x%02x size %d\n",
-		(write == 0 ? "read" : "write"), addr, reg, len);
-	print_hex_dump_bytes("cxd2841er: I2C data: ",
-		DUMP_PREFIX_OFFSET, data, len);
+		"cxd2841er: I2C %s addr %02x reg 0x%02x size %d data %*ph\n",
+		(write == 0 ? "read" : "write"), addr, reg, len, len, data);
 }
 
 static int cxd2841er_write_regs(struct cxd2841er_priv *priv,
Signature · 1 line
2.10.2
Acked-by on v1 1/19
#2 lore raw

Re: [PATCH 01/19] [media] dvb-frontends/cxd2841er: remove kernel log spam in non-debug levels

2017-04-09 15:38 GMT-04:00 Daniel Scheller <[email protected]>:

Quoted 31 lines

From: Daniel Scheller <[email protected]>

This moves the I2C debug dump into the preceding dev_dbg() call by utilising the %*ph format macro and removes the call to print_hex_debug_bytes().

---
 drivers/media/dvb-frontends/cxd2841er.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)
drivers/media/dvb-frontends/cxd2841er.c +2 -5
index 614bfb3..60d85ce 100644
@@ -214,10 +214,8 @@ static void cxd2841er_i2c_debug(struct cxd2841er_priv *priv,
                                const u8 *data, u32 len)
 {
        dev_dbg(&priv->i2c->dev,
-               "cxd2841er: I2C %s addr %02x reg 0x%02x size %d\n",
-               (write == 0 ? "read" : "write"), addr, reg, len);
-       print_hex_dump_bytes("cxd2841er: I2C data: ",
-               DUMP_PREFIX_OFFSET, data, len);
+               "cxd2841er: I2C %s addr %02x reg 0x%02x size %d data %*ph\n",
+               (write == 0 ? "read" : "write"), addr, reg, len, len, data);
 }
 
 static int cxd2841er_write_regs(struct cxd2841er_priv *priv,
--

2.10.2

Signature · 3 lines
Abylay Ospan,
NetUP Inc.
http://www.netup.tv
#3 lore raw

PATCH 2/19 dvb-frontends/cxd2841er: do I2C reads in one go

In reply to Daniel Scheller

From: Daniel Scheller <[email protected]>

Doing the I2C read operation with two calls to i2c_transfer() causes the exclusive I2C bus lock of the underlying adapter to be released. While this isn't an issue if only one demodulator is attached to the bus, having two or even more causes troubles in that concurrent accesses to the different demods will cause all kinds of issues due to wrong data being returned on read operations (for example, the TS config register will be set wrong). This changes the read_regs() function to do the operation in one go (by calling i2c_transfer with the whole msg list instead of one by one) to not loose the I2C bus lock, fixing all sorts of random runtime failures.

---
 drivers/media/dvb-frontends/cxd2841er.c | 13 ++-----------
 1 file changed, 2 insertions(+), 11 deletions(-)
drivers/media/dvb-frontends/cxd2841er.c +2 -11
index 60d85ce..525d006 100644
@@ -282,17 +282,8 @@ static int cxd2841er_read_regs(struct cxd2841er_priv *priv,
 		}
 	};
 
-	ret = i2c_transfer(priv->i2c, &msg[0], 1);
-	if (ret >= 0 && ret != 1)
-		ret = -EIO;
-	if (ret < 0) {
-		dev_warn(&priv->i2c->dev,
-			"%s: i2c rw failed=%d addr=%02x reg=%02x\n",
-			KBUILD_MODNAME, ret, i2c_addr, reg);
-		return ret;
-	}
-	ret = i2c_transfer(priv->i2c, &msg[1], 1);
-	if (ret >= 0 && ret != 1)
+	ret = i2c_transfer(priv->i2c, msg, 2);
+	if (ret >= 0 && ret != 2)
 		ret = -EIO;
 	if (ret < 0) {
 		dev_warn(&priv->i2c->dev,
Signature · 1 line
2.10.2
Acked-by on v1 2/19
#4 lore raw

Re: [PATCH 02/19] [media] dvb-frontends/cxd2841er: do I2C reads in one go

2017-04-09 15:38 GMT-04:00 Daniel Scheller <[email protected]>:

Quoted 44 lines

From: Daniel Scheller <[email protected]>

Doing the I2C read operation with two calls to i2c_transfer() causes the exclusive I2C bus lock of the underlying adapter to be released. While this isn't an issue if only one demodulator is attached to the bus, having two or even more causes troubles in that concurrent accesses to the different demods will cause all kinds of issues due to wrong data being returned on read operations (for example, the TS config register will be set wrong). This changes the read_regs() function to do the operation in one go (by calling i2c_transfer with the whole msg list instead of one by one) to not loose the I2C bus lock, fixing all sorts of random runtime failures.

---
 drivers/media/dvb-frontends/cxd2841er.c | 13 ++-----------
 1 file changed, 2 insertions(+), 11 deletions(-)
drivers/media/dvb-frontends/cxd2841er.c +2 -12
index 60d85ce..525d006 100644
@@ -282,17 +282,8 @@ static int cxd2841er_read_regs(struct cxd2841er_priv *priv,
                }
        };
 
-       ret = i2c_transfer(priv->i2c, &msg[0], 1);
-       if (ret >= 0 && ret != 1)
-               ret = -EIO;
-       if (ret < 0) {
-               dev_warn(&priv->i2c->dev,
-                       "%s: i2c rw failed=%d addr=%02x reg=%02x\n",
-                       KBUILD_MODNAME, ret, i2c_addr, reg);
-               return ret;
-       }
-       ret = i2c_transfer(priv->i2c, &msg[1], 1);
-       if (ret >= 0 && ret != 1)
+       ret = i2c_transfer(priv->i2c, msg, 2);
+       if (ret >= 0 && ret != 2)
                ret = -EIO;
        if (ret < 0) {
                dev_warn(&priv->i2c->dev,
--

2.10.2

Signature · 3 lines
Abylay Ospan,
NetUP Inc.
http://www.netup.tv
#5 lore raw

PATCH 3/19 dvb-frontends/cxd2841er: immediately unfreeze regs when done

In reply to Daniel Scheller

From: Daniel Scheller <[email protected]>

Do unfreeze_regs() directly when accessing the demod registers is done, and don't have multiple unfreeze's on different conditions, which even can get prone to errors.

---
 drivers/media/dvb-frontends/cxd2841er.c | 23 ++++++++++-------------
 1 file changed, 10 insertions(+), 13 deletions(-)
drivers/media/dvb-frontends/cxd2841er.c +10 -13
index 525d006..09c25d7 100644
@@ -1410,11 +1410,11 @@ static int cxd2841er_read_ber_i(struct cxd2841er_priv *priv,
 	cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x60);
 	cxd2841er_read_regs(priv, I2C_SLVT, 0x5B, pktnum, sizeof(pktnum));
 	cxd2841er_read_regs(priv, I2C_SLVT, 0x16, data, sizeof(data));
+	cxd2841er_unfreeze_regs(priv);
 
 	if (!pktnum[0] && !pktnum[1]) {
 		dev_dbg(&priv->i2c->dev,
 				"%s(): no valid BER data\n", __func__);
-		cxd2841er_unfreeze_regs(priv);
 		return -EINVAL;
 	}
 
@@ -1424,7 +1424,6 @@ static int cxd2841er_read_ber_i(struct cxd2841er_priv *priv,
 	dev_dbg(&priv->i2c->dev, "%s(): bit_error=%u bit_count=%u\n",
 			__func__, *bit_error, *bit_count);
 
-	cxd2841er_unfreeze_regs(priv);
 	return 0;
 }
 
@@ -1634,6 +1633,8 @@ static u32 cxd2841er_dvbs_read_snr(struct cxd2841er_priv *priv,
 	 * <SLV-T>    A1h       12h       [7:0]   ICPM_QUICKCNDT[7:0]
 	 */
 	cxd2841er_read_regs(priv, I2C_SLVT, 0x10, data, 3);
+	cxd2841er_unfreeze_regs(priv);
+
 	if (data[0] & 0x01) {
 		value = ((u32)(data[1] & 0x1F) << 8) | (u32)(data[2] & 0xFF);
 		min_index = 0;
@@ -1676,11 +1677,9 @@ static u32 cxd2841er_dvbs_read_snr(struct cxd2841er_priv *priv,
 	} else {
 		dev_dbg(&priv->i2c->dev,
 			"%s(): no data available\n", __func__);
-		cxd2841er_unfreeze_regs(priv);
 		return -EINVAL;
 	}
 done:
-	cxd2841er_unfreeze_regs(priv);
 	*snr = res;
 	return 0;
 }
@@ -1709,12 +1708,12 @@ static int cxd2841er_read_snr_c(struct cxd2841er_priv *priv, u32 *snr)
 	cxd2841er_read_regs(priv, I2C_SLVT, 0x19, data, 1);
 	qam = (enum sony_dvbc_constellation_t) (data[0] & 0x07);
 	cxd2841er_read_regs(priv, I2C_SLVT, 0x4C, data, 2);
+	cxd2841er_unfreeze_regs(priv);
 
 	reg = ((u32)(data[0]&0x1f) << 8) | (u32)data[1];
 	if (reg == 0) {
 		dev_dbg(&priv->i2c->dev,
 				"%s(): reg value out of range\n", __func__);
-		cxd2841er_unfreeze_regs(priv);
 		return 0;
 	}
 
@@ -1735,11 +1734,9 @@ static int cxd2841er_read_snr_c(struct cxd2841er_priv *priv, u32 *snr)
 		*snr = -88 * (int32_t)sony_log(reg) + 86999;
 		break;
 	default:
-		cxd2841er_unfreeze_regs(priv);
 		return -EINVAL;
 	}
 
-	cxd2841er_unfreeze_regs(priv);
 	return 0;
 }
 
@@ -1758,17 +1755,17 @@ static int cxd2841er_read_snr_t(struct cxd2841er_priv *priv, u32 *snr)
 	cxd2841er_freeze_regs(priv);
 	cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10);
 	cxd2841er_read_regs(priv, I2C_SLVT, 0x28, data, sizeof(data));
+	cxd2841er_unfreeze_regs(priv);
+
 	reg = ((u32)data[0] << 8) | (u32)data[1];
 	if (reg == 0) {
 		dev_dbg(&priv->i2c->dev,
 			"%s(): reg value out of range\n", __func__);
-		cxd2841er_unfreeze_regs(priv);
 		return 0;
 	}
 	if (reg > 4996)
 		reg = 4996;
 	*snr = 10000 * ((intlog10(reg) - intlog10(5350 - reg)) >> 24) + 28500;
-	cxd2841er_unfreeze_regs(priv);
 	return 0;
 }
 
@@ -1787,18 +1784,18 @@ static int cxd2841er_read_snr_t2(struct cxd2841er_priv *priv, u32 *snr)
 	cxd2841er_freeze_regs(priv);
 	cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x20);
 	cxd2841er_read_regs(priv, I2C_SLVT, 0x28, data, sizeof(data));
+	cxd2841er_unfreeze_regs(priv);
+
 	reg = ((u32)data[0] << 8) | (u32)data[1];
 	if (reg == 0) {
 		dev_dbg(&priv->i2c->dev,
 			"%s(): reg value out of range\n", __func__);
-		cxd2841er_unfreeze_regs(priv);
 		return 0;
 	}
 	if (reg > 10876)
 		reg = 10876;
 	*snr = 10000 * ((intlog10(reg) -
 		intlog10(12600 - reg)) >> 24) + 32000;
-	cxd2841er_unfreeze_regs(priv);
 	return 0;
 }
 
@@ -1818,15 +1815,15 @@ static int cxd2841er_read_snr_i(struct cxd2841er_priv *priv, u32 *snr)
 	cxd2841er_freeze_regs(priv);
 	cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x60);
 	cxd2841er_read_regs(priv, I2C_SLVT, 0x28, data, sizeof(data));
+	cxd2841er_unfreeze_regs(priv);
+
 	reg = ((u32)data[0] << 8) | (u32)data[1];
 	if (reg == 0) {
 		dev_dbg(&priv->i2c->dev,
 				"%s(): reg value out of range\n", __func__);
-		cxd2841er_unfreeze_regs(priv);
 		return 0;
 	}
 	*snr = 10000 * (intlog10(reg) >> 24) - 9031;
-	cxd2841er_unfreeze_regs(priv);
 	return 0;
 }
 
Signature · 1 line
2.10.2
Acked-by on v1 3/19
#6 lore raw

Re: [PATCH 03/19] [media] dvb-frontends/cxd2841er: immediately unfreeze regs when done

2017-04-09 15:38 GMT-04:00 Daniel Scheller <[email protected]>:

Quoted 145 lines

From: Daniel Scheller <[email protected]>

Do unfreeze_regs() directly when accessing the demod registers is done, and don't have multiple unfreeze's on different conditions, which even can get prone to errors.

---
 drivers/media/dvb-frontends/cxd2841er.c | 23 ++++++++++-------------
 1 file changed, 10 insertions(+), 13 deletions(-)
drivers/media/dvb-frontends/cxd2841er.c +10 -14
index 525d006..09c25d7 100644
@@ -1410,11 +1410,11 @@ static int cxd2841er_read_ber_i(struct cxd2841er_priv *priv,
        cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x60);
        cxd2841er_read_regs(priv, I2C_SLVT, 0x5B, pktnum, sizeof(pktnum));
        cxd2841er_read_regs(priv, I2C_SLVT, 0x16, data, sizeof(data));
+       cxd2841er_unfreeze_regs(priv);
 
        if (!pktnum[0] && !pktnum[1]) {
                dev_dbg(&priv->i2c->dev,
                                "%s(): no valid BER data\n", __func__);
-               cxd2841er_unfreeze_regs(priv);
                return -EINVAL;
        }
 
@@ -1424,7 +1424,6 @@ static int cxd2841er_read_ber_i(struct cxd2841er_priv *priv,
        dev_dbg(&priv->i2c->dev, "%s(): bit_error=%u bit_count=%u\n",
                        __func__, *bit_error, *bit_count);
 
-       cxd2841er_unfreeze_regs(priv);
        return 0;
 }
 
@@ -1634,6 +1633,8 @@ static u32 cxd2841er_dvbs_read_snr(struct cxd2841er_priv *priv,
         * <SLV-T>    A1h       12h       [7:0]   ICPM_QUICKCNDT[7:0]
         */
        cxd2841er_read_regs(priv, I2C_SLVT, 0x10, data, 3);
+       cxd2841er_unfreeze_regs(priv);
+
        if (data[0] & 0x01) {
                value = ((u32)(data[1] & 0x1F) << 8) | (u32)(data[2] & 0xFF);
                min_index = 0;
@@ -1676,11 +1677,9 @@ static u32 cxd2841er_dvbs_read_snr(struct cxd2841er_priv *priv,
        } else {
                dev_dbg(&priv->i2c->dev,
                        "%s(): no data available\n", __func__);
-               cxd2841er_unfreeze_regs(priv);
                return -EINVAL;
        }
 done:
-       cxd2841er_unfreeze_regs(priv);
        *snr = res;
        return 0;
 }
@@ -1709,12 +1708,12 @@ static int cxd2841er_read_snr_c(struct cxd2841er_priv *priv, u32 *snr)
        cxd2841er_read_regs(priv, I2C_SLVT, 0x19, data, 1);
        qam = (enum sony_dvbc_constellation_t) (data[0] & 0x07);
        cxd2841er_read_regs(priv, I2C_SLVT, 0x4C, data, 2);
+       cxd2841er_unfreeze_regs(priv);
 
        reg = ((u32)(data[0]&0x1f) << 8) | (u32)data[1];
        if (reg == 0) {
                dev_dbg(&priv->i2c->dev,
                                "%s(): reg value out of range\n", __func__);
-               cxd2841er_unfreeze_regs(priv);
                return 0;
        }
 
@@ -1735,11 +1734,9 @@ static int cxd2841er_read_snr_c(struct cxd2841er_priv *priv, u32 *snr)
                *snr = -88 * (int32_t)sony_log(reg) + 86999;
                break;
        default:
-               cxd2841er_unfreeze_regs(priv);
                return -EINVAL;
        }
 
-       cxd2841er_unfreeze_regs(priv);
        return 0;
 }
 
@@ -1758,17 +1755,17 @@ static int cxd2841er_read_snr_t(struct cxd2841er_priv *priv, u32 *snr)
        cxd2841er_freeze_regs(priv);
        cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10);
        cxd2841er_read_regs(priv, I2C_SLVT, 0x28, data, sizeof(data));
+       cxd2841er_unfreeze_regs(priv);
+
        reg = ((u32)data[0] << 8) | (u32)data[1];
        if (reg == 0) {
                dev_dbg(&priv->i2c->dev,
                        "%s(): reg value out of range\n", __func__);
-               cxd2841er_unfreeze_regs(priv);
                return 0;
        }
        if (reg > 4996)
                reg = 4996;
        *snr = 10000 * ((intlog10(reg) - intlog10(5350 - reg)) >> 24) + 28500;
-       cxd2841er_unfreeze_regs(priv);
        return 0;
 }
 
@@ -1787,18 +1784,18 @@ static int cxd2841er_read_snr_t2(struct cxd2841er_priv *priv, u32 *snr)
        cxd2841er_freeze_regs(priv);
        cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x20);
        cxd2841er_read_regs(priv, I2C_SLVT, 0x28, data, sizeof(data));
+       cxd2841er_unfreeze_regs(priv);
+
        reg = ((u32)data[0] << 8) | (u32)data[1];
        if (reg == 0) {
                dev_dbg(&priv->i2c->dev,
                        "%s(): reg value out of range\n", __func__);
-               cxd2841er_unfreeze_regs(priv);
                return 0;
        }
        if (reg > 10876)
                reg = 10876;
        *snr = 10000 * ((intlog10(reg) -
                intlog10(12600 - reg)) >> 24) + 32000;
-       cxd2841er_unfreeze_regs(priv);
        return 0;
 }
 
@@ -1818,15 +1815,15 @@ static int cxd2841er_read_snr_i(struct cxd2841er_priv *priv, u32 *snr)
        cxd2841er_freeze_regs(priv);
        cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x60);
        cxd2841er_read_regs(priv, I2C_SLVT, 0x28, data, sizeof(data));
+       cxd2841er_unfreeze_regs(priv);
+
        reg = ((u32)data[0] << 8) | (u32)data[1];
        if (reg == 0) {
                dev_dbg(&priv->i2c->dev,
                                "%s(): reg value out of range\n", __func__);
-               cxd2841er_unfreeze_regs(priv);
                return 0;
        }
        *snr = 10000 * (intlog10(reg) >> 24) - 9031;
-       cxd2841er_unfreeze_regs(priv);
        return 0;
 }
 
--

2.10.2

Signature · 3 lines
Abylay Ospan,
NetUP Inc.
http://www.netup.tv
#7 lore raw

PATCH 4/19 dvb-frontends/cxd2841er: support CXD2837/38/43ER demods/Chip IDs

In reply to Daniel Scheller

From: Daniel Scheller <[email protected]>

Those demods are programmed in the same way as the CXD2841ER/54ER and can be handled by this driver. Support added in a way matching the existing code, supported delivery systems are set according to what each demod supports.

Updates the type string setting used for printing the "attaching..." log line aswell.

---
 drivers/media/dvb-frontends/cxd2841er.c      | 24 +++++++++++++++++++++++-
 drivers/media/dvb-frontends/cxd2841er_priv.h |  3 +++
 2 files changed, 26 insertions(+), 1 deletion(-)
drivers/media/dvb-frontends/cxd2841er.c +23 -1
index 09c25d7..72a27cc 100644
@@ -3733,16 +3733,39 @@ static struct dvb_frontend *cxd2841er_attach(struct cxd2841er_config *cfg,
 		priv->i2c_addr_slvx, priv->i2c_addr_slvt);
 	chip_id = cxd2841er_chip_id(priv);
 	switch (chip_id) {
+	case CXD2837ER_CHIP_ID:
+		snprintf(cxd2841er_t_c_ops.info.name, 128,
+				"Sony CXD2837ER DVB-T/T2/C demodulator");
+		name = "CXD2837ER";
+		type = "C/T/T2";
+		break;
+	case CXD2838ER_CHIP_ID:
+		snprintf(cxd2841er_t_c_ops.info.name, 128,
+				"Sony CXD2838ER ISDB-T demodulator");
+		cxd2841er_t_c_ops.delsys[0] = SYS_ISDBT;
+		cxd2841er_t_c_ops.delsys[1] = SYS_UNDEFINED;
+		cxd2841er_t_c_ops.delsys[2] = SYS_UNDEFINED;
+		name = "CXD2838ER";
+		type = "ISDB-T";
+		break;
 	case CXD2841ER_CHIP_ID:
 		snprintf(cxd2841er_t_c_ops.info.name, 128,
 				"Sony CXD2841ER DVB-T/T2/C demodulator");
 		name = "CXD2841ER";
+		type = "T/T2/C/ISDB-T";
+		break;
+	case CXD2843ER_CHIP_ID:
+		snprintf(cxd2841er_t_c_ops.info.name, 128,
+				"Sony CXD2843ER DVB-T/T2/C/C2 demodulator");
+		name = "CXD2843ER";
+		type = "C/C2/T/T2";
 		break;
 	case CXD2854ER_CHIP_ID:
 		snprintf(cxd2841er_t_c_ops.info.name, 128,
 				"Sony CXD2854ER DVB-T/T2/C and ISDB-T demodulator");
 		cxd2841er_t_c_ops.delsys[3] = SYS_ISDBT;
 		name = "CXD2854ER";
+		type = "C/C2/T/T2/ISDB-T";
 		break;
 	default:
 		dev_err(&priv->i2c->dev, "%s(): invalid chip ID 0x%02x\n",
@@ -3762,7 +3785,6 @@ static struct dvb_frontend *cxd2841er_attach(struct cxd2841er_config *cfg,
 		memcpy(&priv->frontend.ops,
 			&cxd2841er_t_c_ops,
 			sizeof(struct dvb_frontend_ops));
-		type = "T/T2/C/ISDB-T";
 	}
 
 	dev_info(&priv->i2c->dev,
drivers/media/dvb-frontends/cxd2841er_priv.h +3 -0
index 0bbce45..6a71264 100644
@@ -25,7 +25,10 @@
 #define I2C_SLVX			0
 #define I2C_SLVT			1
 
+#define CXD2837ER_CHIP_ID		0xb1
+#define CXD2838ER_CHIP_ID		0xb0
 #define CXD2841ER_CHIP_ID		0xa7
+#define CXD2843ER_CHIP_ID		0xa4
 #define CXD2854ER_CHIP_ID		0xc1
 
 #define CXD2841ER_DVBS_POLLING_INVL	10
Signature · 1 line
2.10.2
Acked-by on v1 4/19
#8 lore raw

Re: [PATCH 04/19] [media] dvb-frontends/cxd2841er: support CXD2837/38/43ER demods/Chip IDs

2017-04-09 15:38 GMT-04:00 Daniel Scheller <[email protected]>:

Quoted 86 lines

From: Daniel Scheller <[email protected]>

Those demods are programmed in the same way as the CXD2841ER/54ER and can be handled by this driver. Support added in a way matching the existing code, supported delivery systems are set according to what each demod supports.

Updates the type string setting used for printing the "attaching..." log line aswell.

---
 drivers/media/dvb-frontends/cxd2841er.c      | 24 +++++++++++++++++++++++-
 drivers/media/dvb-frontends/cxd2841er_priv.h |  3 +++
 2 files changed, 26 insertions(+), 1 deletion(-)
drivers/media/dvb-frontends/cxd2841er.c +23 -1
index 09c25d7..72a27cc 100644
@@ -3733,16 +3733,39 @@ static struct dvb_frontend *cxd2841er_attach(struct cxd2841er_config *cfg,
                priv->i2c_addr_slvx, priv->i2c_addr_slvt);
        chip_id = cxd2841er_chip_id(priv);
        switch (chip_id) {
+       case CXD2837ER_CHIP_ID:
+               snprintf(cxd2841er_t_c_ops.info.name, 128,
+                               "Sony CXD2837ER DVB-T/T2/C demodulator");
+               name = "CXD2837ER";
+               type = "C/T/T2";
+               break;
+       case CXD2838ER_CHIP_ID:
+               snprintf(cxd2841er_t_c_ops.info.name, 128,
+                               "Sony CXD2838ER ISDB-T demodulator");
+               cxd2841er_t_c_ops.delsys[0] = SYS_ISDBT;
+               cxd2841er_t_c_ops.delsys[1] = SYS_UNDEFINED;
+               cxd2841er_t_c_ops.delsys[2] = SYS_UNDEFINED;
+               name = "CXD2838ER";
+               type = "ISDB-T";
+               break;
        case CXD2841ER_CHIP_ID:
                snprintf(cxd2841er_t_c_ops.info.name, 128,
                                "Sony CXD2841ER DVB-T/T2/C demodulator");
                name = "CXD2841ER";
+               type = "T/T2/C/ISDB-T";
+               break;
+       case CXD2843ER_CHIP_ID:
+               snprintf(cxd2841er_t_c_ops.info.name, 128,
+                               "Sony CXD2843ER DVB-T/T2/C/C2 demodulator");
+               name = "CXD2843ER";
+               type = "C/C2/T/T2";
                break;
        case CXD2854ER_CHIP_ID:
                snprintf(cxd2841er_t_c_ops.info.name, 128,
                                "Sony CXD2854ER DVB-T/T2/C and ISDB-T demodulator");
                cxd2841er_t_c_ops.delsys[3] = SYS_ISDBT;
                name = "CXD2854ER";
+               type = "C/C2/T/T2/ISDB-T";
                break;
        default:
                dev_err(&priv->i2c->dev, "%s(): invalid chip ID 0x%02x\n",
@@ -3762,7 +3785,6 @@ static struct dvb_frontend *cxd2841er_attach(struct cxd2841er_config *cfg,
                memcpy(&priv->frontend.ops,
                        &cxd2841er_t_c_ops,
                        sizeof(struct dvb_frontend_ops));
-               type = "T/T2/C/ISDB-T";
        }
 
        dev_info(&priv->i2c->dev,
drivers/media/dvb-frontends/cxd2841er_priv.h +3 -1
index 0bbce45..6a71264 100644
@@ -25,7 +25,10 @@
 #define I2C_SLVX                       0
 #define I2C_SLVT                       1
 
+#define CXD2837ER_CHIP_ID              0xb1
+#define CXD2838ER_CHIP_ID              0xb0
 #define CXD2841ER_CHIP_ID              0xa7
+#define CXD2843ER_CHIP_ID              0xa4
 #define CXD2854ER_CHIP_ID              0xc1
 
 #define CXD2841ER_DVBS_POLLING_INVL    10
--

2.10.2

Signature · 3 lines
Abylay Ospan,
NetUP Inc.
http://www.netup.tv
#9 lore raw

PATCH 5/19 dvb-frontends/cxd2841er: replace IFFREQ calc macros into functions

In reply to Daniel Scheller

From: Daniel Scheller <[email protected]>

The way the MAKE_IFFREQ_CONFIG macros are written make it impossible to pass regular integers for iffreq calculation, since this will cause "SSE register return with SSE disabled" compile errors. This changes the calculation into C functions which also might help when debugging. Also, expand all passed frequencies from MHz to Hz scale.

---
 drivers/media/dvb-frontends/cxd2841er.c | 48 ++++++++++++++++++++-------------
 1 file changed, 29 insertions(+), 19 deletions(-)
drivers/media/dvb-frontends/cxd2841er.c +29 -19
index 72a27cc..6648bd1 100644
@@ -201,11 +201,6 @@ static const struct cxd2841er_cnr_data s2_cn_data[] = {
 	{ 0x0016, 19700 }, { 0x0015, 19900 }, { 0x0014, 20000 },
 };
 
-#define MAKE_IFFREQ_CONFIG(iffreq) ((u32)(((iffreq)/41.0)*16777216.0 + 0.5))
-#define MAKE_IFFREQ_CONFIG_XTAL(xtal, iffreq) ((xtal == SONY_XTAL_24000) ? \
-		(u32)(((iffreq)/48.0)*16777216.0 + 0.5) : \
-		(u32)(((iffreq)/41.0)*16777216.0 + 0.5))
-
 static int cxd2841er_freeze_regs(struct cxd2841er_priv *priv);
 static int cxd2841er_unfreeze_regs(struct cxd2841er_priv *priv);
 
@@ -316,6 +311,21 @@ static int cxd2841er_set_reg_bits(struct cxd2841er_priv *priv,
 	return cxd2841er_write_reg(priv, addr, reg, data);
 }
 
+static u32 cxd2841er_calc_iffreq_xtal(enum cxd2841er_xtal xtal, u32 ifhz)
+{
+	u64 tmp;
+
+	tmp = (u64) ifhz * 16777216;
+	do_div(tmp, ((xtal == SONY_XTAL_24000) ? 48000000 : 41000000));
+
+	return (u32) tmp;
+}
+
+static u32 cxd2841er_calc_iffreq(u32 ifhz)
+{
+	return cxd2841er_calc_iffreq_xtal(SONY_XTAL_20500, ifhz);
+}
+
 static int cxd2841er_dvbs2_set_symbol_rate(struct cxd2841er_priv *priv,
 					   u32 symbol_rate)
 {
@@ -2228,7 +2238,7 @@ static int cxd2841er_sleep_tc_to_active_t2_band(struct cxd2841er_priv *priv,
 		cxd2841er_write_regs(priv, I2C_SLVT,
 				0xA6, itbCoef8bw[priv->xtal], 14);
 		/* <IF freq setting> */
-		iffreq = MAKE_IFFREQ_CONFIG_XTAL(priv->xtal, 4.80);
+		iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, 4800000);
 		data[0] = (u8) ((iffreq >> 16) & 0xff);
 		data[1] = (u8)((iffreq >> 8) & 0xff);
 		data[2] = (u8)(iffreq & 0xff);
@@ -2256,7 +2266,7 @@ static int cxd2841er_sleep_tc_to_active_t2_band(struct cxd2841er_priv *priv,
 		cxd2841er_write_regs(priv, I2C_SLVT,
 				0xA6, itbCoef7bw[priv->xtal], 14);
 		/* <IF freq setting> */
-		iffreq = MAKE_IFFREQ_CONFIG_XTAL(priv->xtal, 4.20);
+		iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, 4200000);
 		data[0] = (u8) ((iffreq >> 16) & 0xff);
 		data[1] = (u8)((iffreq >> 8) & 0xff);
 		data[2] = (u8)(iffreq & 0xff);
@@ -2284,7 +2294,7 @@ static int cxd2841er_sleep_tc_to_active_t2_band(struct cxd2841er_priv *priv,
 		cxd2841er_write_regs(priv, I2C_SLVT,
 				0xA6, itbCoef6bw[priv->xtal], 14);
 		/* <IF freq setting> */
-		iffreq = MAKE_IFFREQ_CONFIG_XTAL(priv->xtal, 3.60);
+		iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, 3600000);
 		data[0] = (u8) ((iffreq >> 16) & 0xff);
 		data[1] = (u8)((iffreq >> 8) & 0xff);
 		data[2] = (u8)(iffreq & 0xff);
@@ -2312,7 +2322,7 @@ static int cxd2841er_sleep_tc_to_active_t2_band(struct cxd2841er_priv *priv,
 		cxd2841er_write_regs(priv, I2C_SLVT,
 				0xA6, itbCoef5bw[priv->xtal], 14);
 		/* <IF freq setting> */
-		iffreq = MAKE_IFFREQ_CONFIG_XTAL(priv->xtal, 3.60);
+		iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, 3600000);
 		data[0] = (u8) ((iffreq >> 16) & 0xff);
 		data[1] = (u8)((iffreq >> 8) & 0xff);
 		data[2] = (u8)(iffreq & 0xff);
@@ -2340,7 +2350,7 @@ static int cxd2841er_sleep_tc_to_active_t2_band(struct cxd2841er_priv *priv,
 		cxd2841er_write_regs(priv, I2C_SLVT,
 				0xA6, itbCoef17bw[priv->xtal], 14);
 		/* <IF freq setting> */
-		iffreq = MAKE_IFFREQ_CONFIG_XTAL(priv->xtal, 3.50);
+		iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, 3500000);
 		data[0] = (u8) ((iffreq >> 16) & 0xff);
 		data[1] = (u8)((iffreq >> 8) & 0xff);
 		data[2] = (u8)(iffreq & 0xff);
@@ -2439,7 +2449,7 @@ static int cxd2841er_sleep_tc_to_active_t_band(
 		cxd2841er_write_regs(priv, I2C_SLVT,
 				0xA6, itbCoef8bw[priv->xtal], 14);
 		/* <IF freq setting> */
-		iffreq = MAKE_IFFREQ_CONFIG_XTAL(priv->xtal, 4.80);
+		iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, 4800000);
 		data[0] = (u8) ((iffreq >> 16) & 0xff);
 		data[1] = (u8)((iffreq >> 8) & 0xff);
 		data[2] = (u8)(iffreq & 0xff);
@@ -2474,7 +2484,7 @@ static int cxd2841er_sleep_tc_to_active_t_band(
 		cxd2841er_write_regs(priv, I2C_SLVT,
 				0xA6, itbCoef7bw[priv->xtal], 14);
 		/* <IF freq setting> */
-		iffreq = MAKE_IFFREQ_CONFIG_XTAL(priv->xtal, 4.20);
+		iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, 4200000);
 		data[0] = (u8) ((iffreq >> 16) & 0xff);
 		data[1] = (u8)((iffreq >> 8) & 0xff);
 		data[2] = (u8)(iffreq & 0xff);
@@ -2509,7 +2519,7 @@ static int cxd2841er_sleep_tc_to_active_t_band(
 		cxd2841er_write_regs(priv, I2C_SLVT,
 				0xA6, itbCoef6bw[priv->xtal], 14);
 		/* <IF freq setting> */
-		iffreq = MAKE_IFFREQ_CONFIG_XTAL(priv->xtal, 3.60);
+		iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, 3600000);
 		data[0] = (u8) ((iffreq >> 16) & 0xff);
 		data[1] = (u8)((iffreq >> 8) & 0xff);
 		data[2] = (u8)(iffreq & 0xff);
@@ -2544,7 +2554,7 @@ static int cxd2841er_sleep_tc_to_active_t_band(
 		cxd2841er_write_regs(priv, I2C_SLVT,
 				0xA6, itbCoef5bw[priv->xtal], 14);
 		/* <IF freq setting> */
-		iffreq = MAKE_IFFREQ_CONFIG_XTAL(priv->xtal, 3.60);
+		iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, 3600000);
 		data[0] = (u8) ((iffreq >> 16) & 0xff);
 		data[1] = (u8)((iffreq >> 8) & 0xff);
 		data[2] = (u8)(iffreq & 0xff);
@@ -2646,7 +2656,7 @@ static int cxd2841er_sleep_tc_to_active_i_band(
 				0xA6, itbCoef8bw[priv->xtal], 14);
 
 		/* IF freq setting */
-		iffreq = MAKE_IFFREQ_CONFIG_XTAL(priv->xtal, 4.75);
+		iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, 4750000);
 		data[0] = (u8) ((iffreq >> 16) & 0xff);
 		data[1] = (u8)((iffreq >> 8) & 0xff);
 		data[2] = (u8)(iffreq & 0xff);
@@ -2675,7 +2685,7 @@ static int cxd2841er_sleep_tc_to_active_i_band(
 				0xA6, itbCoef7bw[priv->xtal], 14);
 
 		/* IF freq setting */
-		iffreq = MAKE_IFFREQ_CONFIG_XTAL(priv->xtal, 4.15);
+		iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, 4150000);
 		data[0] = (u8) ((iffreq >> 16) & 0xff);
 		data[1] = (u8)((iffreq >> 8) & 0xff);
 		data[2] = (u8)(iffreq & 0xff);
@@ -2704,7 +2714,7 @@ static int cxd2841er_sleep_tc_to_active_i_band(
 				0xA6, itbCoef6bw[priv->xtal], 14);
 
 		/* IF freq setting */
-		iffreq = MAKE_IFFREQ_CONFIG_XTAL(priv->xtal, 3.55);
+		iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, 3550000);
 		data[0] = (u8) ((iffreq >> 16) & 0xff);
 		data[1] = (u8)((iffreq >> 8) & 0xff);
 		data[2] = (u8)(iffreq & 0xff);
@@ -2765,13 +2775,13 @@ static int cxd2841er_sleep_tc_to_active_c_band(struct cxd2841er_priv *priv,
 		cxd2841er_write_regs(
 			priv, I2C_SLVT, 0xa6,
 			bw7_8mhz_b10_a6, sizeof(bw7_8mhz_b10_a6));
-		iffreq = MAKE_IFFREQ_CONFIG(4.9);
+		iffreq = cxd2841er_calc_iffreq(4900000);
 		break;
 	case 6000000:
 		cxd2841er_write_regs(
 			priv, I2C_SLVT, 0xa6,
 			bw6mhz_b10_a6, sizeof(bw6mhz_b10_a6));
-		iffreq = MAKE_IFFREQ_CONFIG(3.7);
+		iffreq = cxd2841er_calc_iffreq(3700000);
 		break;
 	default:
 		dev_err(&priv->i2c->dev, "%s(): unsupported bandwidth %d\n",
Signature · 1 line
2.10.2
Acked-by on v1 5/19
#10 lore raw

Re: [PATCH 05/19] [media] dvb-frontends/cxd2841er: replace IFFREQ calc macros into functions

2017-04-09 15:38 GMT-04:00 Daniel Scheller <[email protected]>:

Quoted 178 lines

From: Daniel Scheller <[email protected]>

The way the MAKE_IFFREQ_CONFIG macros are written make it impossible to pass regular integers for iffreq calculation, since this will cause "SSE register return with SSE disabled" compile errors. This changes the calculation into C functions which also might help when debugging. Also, expand all passed frequencies from MHz to Hz scale.

---
 drivers/media/dvb-frontends/cxd2841er.c | 48 ++++++++++++++++++++-------------
 1 file changed, 29 insertions(+), 19 deletions(-)
drivers/media/dvb-frontends/cxd2841er.c +29 -20
index 72a27cc..6648bd1 100644
@@ -201,11 +201,6 @@ static const struct cxd2841er_cnr_data s2_cn_data[] = {
        { 0x0016, 19700 }, { 0x0015, 19900 }, { 0x0014, 20000 },
 };
 
-#define MAKE_IFFREQ_CONFIG(iffreq) ((u32)(((iffreq)/41.0)*16777216.0 + 0.5))
-#define MAKE_IFFREQ_CONFIG_XTAL(xtal, iffreq) ((xtal == SONY_XTAL_24000) ? \
-               (u32)(((iffreq)/48.0)*16777216.0 + 0.5) : \
-               (u32)(((iffreq)/41.0)*16777216.0 + 0.5))
-
 static int cxd2841er_freeze_regs(struct cxd2841er_priv *priv);
 static int cxd2841er_unfreeze_regs(struct cxd2841er_priv *priv);
 
@@ -316,6 +311,21 @@ static int cxd2841er_set_reg_bits(struct cxd2841er_priv *priv,
        return cxd2841er_write_reg(priv, addr, reg, data);
 }
 
+static u32 cxd2841er_calc_iffreq_xtal(enum cxd2841er_xtal xtal, u32 ifhz)
+{
+       u64 tmp;
+
+       tmp = (u64) ifhz * 16777216;
+       do_div(tmp, ((xtal == SONY_XTAL_24000) ? 48000000 : 41000000));
+
+       return (u32) tmp;
+}
+
+static u32 cxd2841er_calc_iffreq(u32 ifhz)
+{
+       return cxd2841er_calc_iffreq_xtal(SONY_XTAL_20500, ifhz);
+}
+
 static int cxd2841er_dvbs2_set_symbol_rate(struct cxd2841er_priv *priv,
                                           u32 symbol_rate)
 {
@@ -2228,7 +2238,7 @@ static int cxd2841er_sleep_tc_to_active_t2_band(struct cxd2841er_priv *priv,
                cxd2841er_write_regs(priv, I2C_SLVT,
                                0xA6, itbCoef8bw[priv->xtal], 14);
                /* <IF freq setting> */
-               iffreq = MAKE_IFFREQ_CONFIG_XTAL(priv->xtal, 4.80);
+               iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, 4800000);
                data[0] = (u8) ((iffreq >> 16) & 0xff);
                data[1] = (u8)((iffreq >> 8) & 0xff);
                data[2] = (u8)(iffreq & 0xff);
@@ -2256,7 +2266,7 @@ static int cxd2841er_sleep_tc_to_active_t2_band(struct cxd2841er_priv *priv,
                cxd2841er_write_regs(priv, I2C_SLVT,
                                0xA6, itbCoef7bw[priv->xtal], 14);
                /* <IF freq setting> */
-               iffreq = MAKE_IFFREQ_CONFIG_XTAL(priv->xtal, 4.20);
+               iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, 4200000);
                data[0] = (u8) ((iffreq >> 16) & 0xff);
                data[1] = (u8)((iffreq >> 8) & 0xff);
                data[2] = (u8)(iffreq & 0xff);
@@ -2284,7 +2294,7 @@ static int cxd2841er_sleep_tc_to_active_t2_band(struct cxd2841er_priv *priv,
                cxd2841er_write_regs(priv, I2C_SLVT,
                                0xA6, itbCoef6bw[priv->xtal], 14);
                /* <IF freq setting> */
-               iffreq = MAKE_IFFREQ_CONFIG_XTAL(priv->xtal, 3.60);
+               iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, 3600000);
                data[0] = (u8) ((iffreq >> 16) & 0xff);
                data[1] = (u8)((iffreq >> 8) & 0xff);
                data[2] = (u8)(iffreq & 0xff);
@@ -2312,7 +2322,7 @@ static int cxd2841er_sleep_tc_to_active_t2_band(struct cxd2841er_priv *priv,
                cxd2841er_write_regs(priv, I2C_SLVT,
                                0xA6, itbCoef5bw[priv->xtal], 14);
                /* <IF freq setting> */
-               iffreq = MAKE_IFFREQ_CONFIG_XTAL(priv->xtal, 3.60);
+               iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, 3600000);
                data[0] = (u8) ((iffreq >> 16) & 0xff);
                data[1] = (u8)((iffreq >> 8) & 0xff);
                data[2] = (u8)(iffreq & 0xff);
@@ -2340,7 +2350,7 @@ static int cxd2841er_sleep_tc_to_active_t2_band(struct cxd2841er_priv *priv,
                cxd2841er_write_regs(priv, I2C_SLVT,
                                0xA6, itbCoef17bw[priv->xtal], 14);
                /* <IF freq setting> */
-               iffreq = MAKE_IFFREQ_CONFIG_XTAL(priv->xtal, 3.50);
+               iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, 3500000);
                data[0] = (u8) ((iffreq >> 16) & 0xff);
                data[1] = (u8)((iffreq >> 8) & 0xff);
                data[2] = (u8)(iffreq & 0xff);
@@ -2439,7 +2449,7 @@ static int cxd2841er_sleep_tc_to_active_t_band(
                cxd2841er_write_regs(priv, I2C_SLVT,
                                0xA6, itbCoef8bw[priv->xtal], 14);
                /* <IF freq setting> */
-               iffreq = MAKE_IFFREQ_CONFIG_XTAL(priv->xtal, 4.80);
+               iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, 4800000);
                data[0] = (u8) ((iffreq >> 16) & 0xff);
                data[1] = (u8)((iffreq >> 8) & 0xff);
                data[2] = (u8)(iffreq & 0xff);
@@ -2474,7 +2484,7 @@ static int cxd2841er_sleep_tc_to_active_t_band(
                cxd2841er_write_regs(priv, I2C_SLVT,
                                0xA6, itbCoef7bw[priv->xtal], 14);
                /* <IF freq setting> */
-               iffreq = MAKE_IFFREQ_CONFIG_XTAL(priv->xtal, 4.20);
+               iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, 4200000);
                data[0] = (u8) ((iffreq >> 16) & 0xff);
                data[1] = (u8)((iffreq >> 8) & 0xff);
                data[2] = (u8)(iffreq & 0xff);
@@ -2509,7 +2519,7 @@ static int cxd2841er_sleep_tc_to_active_t_band(
                cxd2841er_write_regs(priv, I2C_SLVT,
                                0xA6, itbCoef6bw[priv->xtal], 14);
                /* <IF freq setting> */
-               iffreq = MAKE_IFFREQ_CONFIG_XTAL(priv->xtal, 3.60);
+               iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, 3600000);
                data[0] = (u8) ((iffreq >> 16) & 0xff);
                data[1] = (u8)((iffreq >> 8) & 0xff);
                data[2] = (u8)(iffreq & 0xff);
@@ -2544,7 +2554,7 @@ static int cxd2841er_sleep_tc_to_active_t_band(
                cxd2841er_write_regs(priv, I2C_SLVT,
                                0xA6, itbCoef5bw[priv->xtal], 14);
                /* <IF freq setting> */
-               iffreq = MAKE_IFFREQ_CONFIG_XTAL(priv->xtal, 3.60);
+               iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, 3600000);
                data[0] = (u8) ((iffreq >> 16) & 0xff);
                data[1] = (u8)((iffreq >> 8) & 0xff);
                data[2] = (u8)(iffreq & 0xff);
@@ -2646,7 +2656,7 @@ static int cxd2841er_sleep_tc_to_active_i_band(
                                0xA6, itbCoef8bw[priv->xtal], 14);
 
                /* IF freq setting */
-               iffreq = MAKE_IFFREQ_CONFIG_XTAL(priv->xtal, 4.75);
+               iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, 4750000);
                data[0] = (u8) ((iffreq >> 16) & 0xff);
                data[1] = (u8)((iffreq >> 8) & 0xff);
                data[2] = (u8)(iffreq & 0xff);
@@ -2675,7 +2685,7 @@ static int cxd2841er_sleep_tc_to_active_i_band(
                                0xA6, itbCoef7bw[priv->xtal], 14);
 
                /* IF freq setting */
-               iffreq = MAKE_IFFREQ_CONFIG_XTAL(priv->xtal, 4.15);
+               iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, 4150000);
                data[0] = (u8) ((iffreq >> 16) & 0xff);
                data[1] = (u8)((iffreq >> 8) & 0xff);
                data[2] = (u8)(iffreq & 0xff);
@@ -2704,7 +2714,7 @@ static int cxd2841er_sleep_tc_to_active_i_band(
                                0xA6, itbCoef6bw[priv->xtal], 14);
 
                /* IF freq setting */
-               iffreq = MAKE_IFFREQ_CONFIG_XTAL(priv->xtal, 3.55);
+               iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, 3550000);
                data[0] = (u8) ((iffreq >> 16) & 0xff);
                data[1] = (u8)((iffreq >> 8) & 0xff);
                data[2] = (u8)(iffreq & 0xff);
@@ -2765,13 +2775,13 @@ static int cxd2841er_sleep_tc_to_active_c_band(struct cxd2841er_priv *priv,
                cxd2841er_write_regs(
                        priv, I2C_SLVT, 0xa6,
                        bw7_8mhz_b10_a6, sizeof(bw7_8mhz_b10_a6));
-               iffreq = MAKE_IFFREQ_CONFIG(4.9);
+               iffreq = cxd2841er_calc_iffreq(4900000);
                break;
        case 6000000:
                cxd2841er_write_regs(
                        priv, I2C_SLVT, 0xa6,
                        bw6mhz_b10_a6, sizeof(bw6mhz_b10_a6));
-               iffreq = MAKE_IFFREQ_CONFIG(3.7);
+               iffreq = cxd2841er_calc_iffreq(3700000);
                break;
        default:
                dev_err(&priv->i2c->dev, "%s(): unsupported bandwidth %d\n",
--

2.10.2

Signature · 3 lines
Abylay Ospan,
NetUP Inc.
http://www.netup.tv
#11 lore raw

PATCH 6/19 dvb-frontends/cxd2841er: add variable for configuration flags

In reply to Daniel Scheller

From: Daniel Scheller <[email protected]>

Throughout the patch series some configuration flags will be added to the demod driver. This patch prepares this by adding the flags var to struct cxd2841er_config, which will serve as a bitmask to toggle various options and behaviour in the driver.

---
 drivers/media/dvb-frontends/cxd2841er.c | 2 ++
 drivers/media/dvb-frontends/cxd2841er.h | 1 +
 2 files changed, 3 insertions(+)
drivers/media/dvb-frontends/cxd2841er.c +2 -0
index 6648bd1..f49a09b 100644
@@ -65,6 +65,7 @@ struct cxd2841er_priv {
 	u8				system;
 	enum cxd2841er_xtal		xtal;
 	enum fe_caps caps;
+	u32				flags;
 };
 
 static const struct cxd2841er_cnr_data s_cn_data[] = {
@@ -3736,6 +3737,7 @@ static struct dvb_frontend *cxd2841er_attach(struct cxd2841er_config *cfg,
 	priv->i2c_addr_slvx = (cfg->i2c_addr + 4) >> 1;
 	priv->i2c_addr_slvt = (cfg->i2c_addr) >> 1;
 	priv->xtal = cfg->xtal;
+	priv->flags = cfg->flags;
 	priv->frontend.demodulator_priv = priv;
 	dev_info(&priv->i2c->dev,
 		"%s(): I2C adapter %p SLVX addr %x SLVT addr %x\n",
drivers/media/dvb-frontends/cxd2841er.h +1 -0
index 7f1acfb..2fb8b38 100644
@@ -33,6 +33,7 @@ enum cxd2841er_xtal {
 struct cxd2841er_config {
 	u8	i2c_addr;
 	enum cxd2841er_xtal	xtal;
+	u32	flags;
 };
 
 #if IS_REACHABLE(CONFIG_DVB_CXD2841ER)
Signature · 1 line
2.10.2
Acked-by on v1 6/19
#12 lore raw

Re: [PATCH 06/19] [media] dvb-frontends/cxd2841er: add variable for configuration flags

2017-04-09 15:38 GMT-04:00 Daniel Scheller <[email protected]>:

Quoted 48 lines

From: Daniel Scheller <[email protected]>

Throughout the patch series some configuration flags will be added to the demod driver. This patch prepares this by adding the flags var to struct cxd2841er_config, which will serve as a bitmask to toggle various options and behaviour in the driver.

---
 drivers/media/dvb-frontends/cxd2841er.c | 2 ++
 drivers/media/dvb-frontends/cxd2841er.h | 1 +
 2 files changed, 3 insertions(+)
drivers/media/dvb-frontends/cxd2841er.c +2 -0
index 6648bd1..f49a09b 100644
@@ -65,6 +65,7 @@ struct cxd2841er_priv {
        u8                              system;
        enum cxd2841er_xtal             xtal;
        enum fe_caps caps;
+       u32                             flags;
 };
 
 static const struct cxd2841er_cnr_data s_cn_data[] = {
@@ -3736,6 +3737,7 @@ static struct dvb_frontend *cxd2841er_attach(struct cxd2841er_config *cfg,
        priv->i2c_addr_slvx = (cfg->i2c_addr + 4) >> 1;
        priv->i2c_addr_slvt = (cfg->i2c_addr) >> 1;
        priv->xtal = cfg->xtal;
+       priv->flags = cfg->flags;
        priv->frontend.demodulator_priv = priv;
        dev_info(&priv->i2c->dev,
                "%s(): I2C adapter %p SLVX addr %x SLVT addr %x\n",
drivers/media/dvb-frontends/cxd2841er.h +1 -1
index 7f1acfb..2fb8b38 100644
@@ -33,6 +33,7 @@ enum cxd2841er_xtal {
 struct cxd2841er_config {
        u8      i2c_addr;
        enum cxd2841er_xtal     xtal;
+       u32     flags;
 };
 
 #if IS_REACHABLE(CONFIG_DVB_CXD2841ER)
--

2.10.2

Signature · 3 lines
Abylay Ospan,
NetUP Inc.
http://www.netup.tv
#13 lore raw

PATCH 7/19 dvb-frontends/cxd2841er: make call to i2c_gate_ctrl optional

In reply to Daniel Scheller

From: Daniel Scheller <[email protected]>

Some cards/bridges wrap i2c_gate_ctrl handling with a mutex_lock(). This is e.g. done in ddbridge to protect against concurrent tuner access with regards to the dual tuner HW, where concurrent tuner reconfiguration can result in tuning fails or bad reception quality. When the tuner driver additionally tries to open the I2C gate (which e.g. the tda18212 driver does) when the demod already did this, this will lead to a deadlock. This makes the calls to i2c_gatectrl from the demod driver optional when the flag is set, leaving this to the tuner driver. For readability reasons and to not have the check duplicated multiple times, the setup is factored into cxd2841er_tuner_set().

This commit also updates the netup card driver (which seems to be the only consumer of the cxd2841er as of now).

---
 drivers/media/dvb-frontends/cxd2841er.c            | 32 ++++++++++++++--------
 drivers/media/dvb-frontends/cxd2841er.h            |  2 ++
 drivers/media/pci/netup_unidvb/netup_unidvb_core.c |  3 +-
 3 files changed, 24 insertions(+), 13 deletions(-)
drivers/media/dvb-frontends/cxd2841er.c +20 -12
index f49a09b..162a0f5 100644
@@ -327,6 +327,20 @@ static u32 cxd2841er_calc_iffreq(u32 ifhz)
 	return cxd2841er_calc_iffreq_xtal(SONY_XTAL_20500, ifhz);
 }
 
+static int cxd2841er_tuner_set(struct dvb_frontend *fe)
+{
+	struct cxd2841er_priv *priv = fe->demodulator_priv;
+
+	if ((priv->flags & CXD2841ER_USE_GATECTRL) && fe->ops.i2c_gate_ctrl)
+		fe->ops.i2c_gate_ctrl(fe, 1);
+	if (fe->ops.tuner_ops.set_params)
+		fe->ops.tuner_ops.set_params(fe);
+	if ((priv->flags & CXD2841ER_USE_GATECTRL) && fe->ops.i2c_gate_ctrl)
+		fe->ops.i2c_gate_ctrl(fe, 0);
+
+	return 0;
+}
+
 static int cxd2841er_dvbs2_set_symbol_rate(struct cxd2841er_priv *priv,
 					   u32 symbol_rate)
 {
@@ -3251,12 +3265,9 @@ static int cxd2841er_set_frontend_s(struct dvb_frontend *fe)
 		dev_dbg(&priv->i2c->dev, "%s(): tune failed\n", __func__);
 		goto done;
 	}
-	if (fe->ops.i2c_gate_ctrl)
-		fe->ops.i2c_gate_ctrl(fe, 1);
-	if (fe->ops.tuner_ops.set_params)
-		fe->ops.tuner_ops.set_params(fe);
-	if (fe->ops.i2c_gate_ctrl)
-		fe->ops.i2c_gate_ctrl(fe, 0);
+
+	cxd2841er_tuner_set(fe);
+
 	cxd2841er_tune_done(priv);
 	timeout = ((3000000 + (symbol_rate - 1)) / symbol_rate) + 150;
 	for (i = 0; i < timeout / CXD2841ER_DVBS_POLLING_INVL; i++) {
@@ -3376,12 +3387,9 @@ static int cxd2841er_set_frontend_tc(struct dvb_frontend *fe)
 	}
 	if (ret)
 		goto done;
-	if (fe->ops.i2c_gate_ctrl)
-		fe->ops.i2c_gate_ctrl(fe, 1);
-	if (fe->ops.tuner_ops.set_params)
-		fe->ops.tuner_ops.set_params(fe);
-	if (fe->ops.i2c_gate_ctrl)
-		fe->ops.i2c_gate_ctrl(fe, 0);
+
+	cxd2841er_tuner_set(fe);
+
 	cxd2841er_tune_done(priv);
 	timeout = 2500;
 	while (timeout > 0) {
drivers/media/dvb-frontends/cxd2841er.h +2 -0
index 2fb8b38..15564af 100644
@@ -24,6 +24,8 @@
 
 #include <linux/dvb/frontend.h>
 
+#define CXD2841ER_USE_GATECTRL	1
+
 enum cxd2841er_xtal {
 	SONY_XTAL_20500, /* 20.5 MHz */
 	SONY_XTAL_24000, /* 24 MHz */
drivers/media/pci/netup_unidvb/netup_unidvb_core.c +2 -1
index 191bd82..5e6553f 100644
@@ -122,7 +122,8 @@ static void netup_unidvb_queue_cleanup(struct netup_dma *dma);
 
 static struct cxd2841er_config demod_config = {
 	.i2c_addr = 0xc8,
-	.xtal = SONY_XTAL_24000
+	.xtal = SONY_XTAL_24000,
+	.flags = CXD2841ER_USE_GATECTRL
 };
 
 static struct horus3a_config horus3a_conf = {
Signature · 1 line
2.10.2
Acked-by on v1 7/19
#14 lore raw

Re: [PATCH 07/19] [media] dvb-frontends/cxd2841er: make call to i2c_gate_ctrl optional

2017-04-09 15:38 GMT-04:00 Daniel Scheller <[email protected]>:

Quoted 110 lines

From: Daniel Scheller <[email protected]>

Some cards/bridges wrap i2c_gate_ctrl handling with a mutex_lock(). This is e.g. done in ddbridge to protect against concurrent tuner access with regards to the dual tuner HW, where concurrent tuner reconfiguration can result in tuning fails or bad reception quality. When the tuner driver additionally tries to open the I2C gate (which e.g. the tda18212 driver does) when the demod already did this, this will lead to a deadlock. This makes the calls to i2c_gatectrl from the demod driver optional when the flag is set, leaving this to the tuner driver. For readability reasons and to not have the check duplicated multiple times, the setup is factored into cxd2841er_tuner_set().

This commit also updates the netup card driver (which seems to be the only consumer of the cxd2841er as of now).

---
 drivers/media/dvb-frontends/cxd2841er.c            | 32 ++++++++++++++--------
 drivers/media/dvb-frontends/cxd2841er.h            |  2 ++
 drivers/media/pci/netup_unidvb/netup_unidvb_core.c |  3 +-
 3 files changed, 24 insertions(+), 13 deletions(-)
drivers/media/dvb-frontends/cxd2841er.c +20 -12
index f49a09b..162a0f5 100644
@@ -327,6 +327,20 @@ static u32 cxd2841er_calc_iffreq(u32 ifhz)
        return cxd2841er_calc_iffreq_xtal(SONY_XTAL_20500, ifhz);
 }
 
+static int cxd2841er_tuner_set(struct dvb_frontend *fe)
+{
+       struct cxd2841er_priv *priv = fe->demodulator_priv;
+
+       if ((priv->flags & CXD2841ER_USE_GATECTRL) && fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+       if (fe->ops.tuner_ops.set_params)
+               fe->ops.tuner_ops.set_params(fe);
+       if ((priv->flags & CXD2841ER_USE_GATECTRL) && fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 0);
+
+       return 0;
+}
+
 static int cxd2841er_dvbs2_set_symbol_rate(struct cxd2841er_priv *priv,
                                           u32 symbol_rate)
 {
@@ -3251,12 +3265,9 @@ static int cxd2841er_set_frontend_s(struct dvb_frontend *fe)
                dev_dbg(&priv->i2c->dev, "%s(): tune failed\n", __func__);
                goto done;
        }
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-       if (fe->ops.tuner_ops.set_params)
-               fe->ops.tuner_ops.set_params(fe);
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 0);
+
+       cxd2841er_tuner_set(fe);
+
        cxd2841er_tune_done(priv);
        timeout = ((3000000 + (symbol_rate - 1)) / symbol_rate) + 150;
        for (i = 0; i < timeout / CXD2841ER_DVBS_POLLING_INVL; i++) {
@@ -3376,12 +3387,9 @@ static int cxd2841er_set_frontend_tc(struct dvb_frontend *fe)
        }
        if (ret)
                goto done;
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-       if (fe->ops.tuner_ops.set_params)
-               fe->ops.tuner_ops.set_params(fe);
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 0);
+
+       cxd2841er_tuner_set(fe);
+
        cxd2841er_tune_done(priv);
        timeout = 2500;
        while (timeout > 0) {
drivers/media/dvb-frontends/cxd2841er.h +2 -0
index 2fb8b38..15564af 100644
@@ -24,6 +24,8 @@
 
 #include <linux/dvb/frontend.h>
 
+#define CXD2841ER_USE_GATECTRL 1
+
 enum cxd2841er_xtal {
        SONY_XTAL_20500, /* 20.5 MHz */
        SONY_XTAL_24000, /* 24 MHz */
drivers/media/pci/netup_unidvb/netup_unidvb_core.c +2 -2
index 191bd82..5e6553f 100644
@@ -122,7 +122,8 @@ static void netup_unidvb_queue_cleanup(struct netup_dma *dma);
 
 static struct cxd2841er_config demod_config = {
        .i2c_addr = 0xc8,
-       .xtal = SONY_XTAL_24000
+       .xtal = SONY_XTAL_24000,
+       .flags = CXD2841ER_USE_GATECTRL
 };
 
 static struct horus3a_config horus3a_conf = {
--

2.10.2

Signature · 3 lines
Abylay Ospan,
NetUP Inc.
http://www.netup.tv
#15 lore raw

PATCH 8/19 dvb-frontends/cxd2841er: support IF speed calc from tuner values

In reply to Daniel Scheller

From: Daniel Scheller <[email protected]>

Add a AUTO_IFHZ flag and a function that will read IF speed values from any attached tuner if the tuner supports this and if AUTO_IFHZ is enabled, and else the passed default value (which probably matches Sony ASCOT tuners) will be passed back. The returned value is then used to calculate the iffeq which the demod will be programmed with.

---
 drivers/media/dvb-frontends/cxd2841er.c | 64 +++++++++++++++++++++++----------
 drivers/media/dvb-frontends/cxd2841er.h |  1 +
 2 files changed, 47 insertions(+), 18 deletions(-)
drivers/media/dvb-frontends/cxd2841er.c +46 -18
index 162a0f5..fa6a963 100644
@@ -327,6 +327,20 @@ static u32 cxd2841er_calc_iffreq(u32 ifhz)
 	return cxd2841er_calc_iffreq_xtal(SONY_XTAL_20500, ifhz);
 }
 
+static int cxd2841er_get_if_hz(struct cxd2841er_priv *priv, u32 def_hz)
+{
+	u32 hz;
+
+	if (priv->frontend.ops.tuner_ops.get_if_frequency
+			&& (priv->flags & CXD2841ER_AUTO_IFHZ))
+		priv->frontend.ops.tuner_ops.get_if_frequency(
+			&priv->frontend, &hz);
+	else
+		hz = def_hz;
+
+	return hz;
+}
+
 static int cxd2841er_tuner_set(struct dvb_frontend *fe)
 {
 	struct cxd2841er_priv *priv = fe->demodulator_priv;
@@ -2147,7 +2161,7 @@ static int cxd2841er_dvbt2_set_plp_config(struct cxd2841er_priv *priv,
 static int cxd2841er_sleep_tc_to_active_t2_band(struct cxd2841er_priv *priv,
 						u32 bandwidth)
 {
-	u32 iffreq;
+	u32 iffreq, ifhz;
 	u8 data[MAX_WRITE_REGSIZE];
 
 	const uint8_t nominalRate8bw[3][5] = {
@@ -2253,7 +2267,8 @@ static int cxd2841er_sleep_tc_to_active_t2_band(struct cxd2841er_priv *priv,
 		cxd2841er_write_regs(priv, I2C_SLVT,
 				0xA6, itbCoef8bw[priv->xtal], 14);
 		/* <IF freq setting> */
-		iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, 4800000);
+		ifhz = cxd2841er_get_if_hz(priv, 4800000);
+		iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, ifhz);
 		data[0] = (u8) ((iffreq >> 16) & 0xff);
 		data[1] = (u8)((iffreq >> 8) & 0xff);
 		data[2] = (u8)(iffreq & 0xff);
@@ -2281,7 +2296,8 @@ static int cxd2841er_sleep_tc_to_active_t2_band(struct cxd2841er_priv *priv,
 		cxd2841er_write_regs(priv, I2C_SLVT,
 				0xA6, itbCoef7bw[priv->xtal], 14);
 		/* <IF freq setting> */
-		iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, 4200000);
+		ifhz = cxd2841er_get_if_hz(priv, 4200000);
+		iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, ifhz);
 		data[0] = (u8) ((iffreq >> 16) & 0xff);
 		data[1] = (u8)((iffreq >> 8) & 0xff);
 		data[2] = (u8)(iffreq & 0xff);
@@ -2309,7 +2325,8 @@ static int cxd2841er_sleep_tc_to_active_t2_band(struct cxd2841er_priv *priv,
 		cxd2841er_write_regs(priv, I2C_SLVT,
 				0xA6, itbCoef6bw[priv->xtal], 14);
 		/* <IF freq setting> */
-		iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, 3600000);
+		ifhz = cxd2841er_get_if_hz(priv, 3600000);
+		iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, ifhz);
 		data[0] = (u8) ((iffreq >> 16) & 0xff);
 		data[1] = (u8)((iffreq >> 8) & 0xff);
 		data[2] = (u8)(iffreq & 0xff);
@@ -2337,7 +2354,8 @@ static int cxd2841er_sleep_tc_to_active_t2_band(struct cxd2841er_priv *priv,
 		cxd2841er_write_regs(priv, I2C_SLVT,
 				0xA6, itbCoef5bw[priv->xtal], 14);
 		/* <IF freq setting> */
-		iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, 3600000);
+		ifhz = cxd2841er_get_if_hz(priv, 3600000);
+		iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, ifhz);
 		data[0] = (u8) ((iffreq >> 16) & 0xff);
 		data[1] = (u8)((iffreq >> 8) & 0xff);
 		data[2] = (u8)(iffreq & 0xff);
@@ -2365,7 +2383,8 @@ static int cxd2841er_sleep_tc_to_active_t2_band(struct cxd2841er_priv *priv,
 		cxd2841er_write_regs(priv, I2C_SLVT,
 				0xA6, itbCoef17bw[priv->xtal], 14);
 		/* <IF freq setting> */
-		iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, 3500000);
+		ifhz = cxd2841er_get_if_hz(priv, 3500000);
+		iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, ifhz);
 		data[0] = (u8) ((iffreq >> 16) & 0xff);
 		data[1] = (u8)((iffreq >> 8) & 0xff);
 		data[2] = (u8)(iffreq & 0xff);
@@ -2384,7 +2403,7 @@ static int cxd2841er_sleep_tc_to_active_t_band(
 		struct cxd2841er_priv *priv, u32 bandwidth)
 {
 	u8 data[MAX_WRITE_REGSIZE];
-	u32 iffreq;
+	u32 iffreq, ifhz;
 	u8 nominalRate8bw[3][5] = {
 		/* TRCG Nominal Rate [37:0] */
 		{0x11, 0xF0, 0x00, 0x00, 0x00}, /* 20.5MHz XTal */
@@ -2464,7 +2483,8 @@ static int cxd2841er_sleep_tc_to_active_t_band(
 		cxd2841er_write_regs(priv, I2C_SLVT,
 				0xA6, itbCoef8bw[priv->xtal], 14);
 		/* <IF freq setting> */
-		iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, 4800000);
+		ifhz = cxd2841er_get_if_hz(priv, 4800000);
+		iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, ifhz);
 		data[0] = (u8) ((iffreq >> 16) & 0xff);
 		data[1] = (u8)((iffreq >> 8) & 0xff);
 		data[2] = (u8)(iffreq & 0xff);
@@ -2499,7 +2519,8 @@ static int cxd2841er_sleep_tc_to_active_t_band(
 		cxd2841er_write_regs(priv, I2C_SLVT,
 				0xA6, itbCoef7bw[priv->xtal], 14);
 		/* <IF freq setting> */
-		iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, 4200000);
+		ifhz = cxd2841er_get_if_hz(priv, 4200000);
+		iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, ifhz);
 		data[0] = (u8) ((iffreq >> 16) & 0xff);
 		data[1] = (u8)((iffreq >> 8) & 0xff);
 		data[2] = (u8)(iffreq & 0xff);
@@ -2534,7 +2555,8 @@ static int cxd2841er_sleep_tc_to_active_t_band(
 		cxd2841er_write_regs(priv, I2C_SLVT,
 				0xA6, itbCoef6bw[priv->xtal], 14);
 		/* <IF freq setting> */
-		iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, 3600000);
+		ifhz = cxd2841er_get_if_hz(priv, 3600000);
+		iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, ifhz);
 		data[0] = (u8) ((iffreq >> 16) & 0xff);
 		data[1] = (u8)((iffreq >> 8) & 0xff);
 		data[2] = (u8)(iffreq & 0xff);
@@ -2569,7 +2591,8 @@ static int cxd2841er_sleep_tc_to_active_t_band(
 		cxd2841er_write_regs(priv, I2C_SLVT,
 				0xA6, itbCoef5bw[priv->xtal], 14);
 		/* <IF freq setting> */
-		iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, 3600000);
+		ifhz = cxd2841er_get_if_hz(priv, 3600000);
+		iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, ifhz);
 		data[0] = (u8) ((iffreq >> 16) & 0xff);
 		data[1] = (u8)((iffreq >> 8) & 0xff);
 		data[2] = (u8)(iffreq & 0xff);
@@ -2602,7 +2625,7 @@ static int cxd2841er_sleep_tc_to_active_t_band(
 static int cxd2841er_sleep_tc_to_active_i_band(
 		struct cxd2841er_priv *priv, u32 bandwidth)
 {
-	u32 iffreq;
+	u32 iffreq, ifhz;
 	u8 data[3];
 
 	/* TRCG Nominal Rate */
@@ -2671,7 +2694,8 @@ static int cxd2841er_sleep_tc_to_active_i_band(
 				0xA6, itbCoef8bw[priv->xtal], 14);
 
 		/* IF freq setting */
-		iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, 4750000);
+		ifhz = cxd2841er_get_if_hz(priv, 4750000);
+		iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, ifhz);
 		data[0] = (u8) ((iffreq >> 16) & 0xff);
 		data[1] = (u8)((iffreq >> 8) & 0xff);
 		data[2] = (u8)(iffreq & 0xff);
@@ -2700,7 +2724,8 @@ static int cxd2841er_sleep_tc_to_active_i_band(
 				0xA6, itbCoef7bw[priv->xtal], 14);
 
 		/* IF freq setting */
-		iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, 4150000);
+		ifhz = cxd2841er_get_if_hz(priv, 4150000);
+		iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, ifhz);
 		data[0] = (u8) ((iffreq >> 16) & 0xff);
 		data[1] = (u8)((iffreq >> 8) & 0xff);
 		data[2] = (u8)(iffreq & 0xff);
@@ -2729,7 +2754,8 @@ static int cxd2841er_sleep_tc_to_active_i_band(
 				0xA6, itbCoef6bw[priv->xtal], 14);
 
 		/* IF freq setting */
-		iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, 3550000);
+		ifhz = cxd2841er_get_if_hz(priv, 3550000);
+		iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, ifhz);
 		data[0] = (u8) ((iffreq >> 16) & 0xff);
 		data[1] = (u8)((iffreq >> 8) & 0xff);
 		data[2] = (u8)(iffreq & 0xff);
@@ -2772,7 +2798,7 @@ static int cxd2841er_sleep_tc_to_active_c_band(struct cxd2841er_priv *priv,
 		0x27, 0xA7, 0x28, 0xB3, 0x02, 0xF0, 0x01, 0xE8,
 		0x00, 0xCF, 0x00, 0xE6, 0x23, 0xA4 };
 	u8 b10_b6[3];
-	u32 iffreq;
+	u32 iffreq, ifhz;
 
 	if (bandwidth != 6000000 &&
 			bandwidth != 7000000 &&
@@ -2790,13 +2816,15 @@ static int cxd2841er_sleep_tc_to_active_c_band(struct cxd2841er_priv *priv,
 		cxd2841er_write_regs(
 			priv, I2C_SLVT, 0xa6,
 			bw7_8mhz_b10_a6, sizeof(bw7_8mhz_b10_a6));
-		iffreq = cxd2841er_calc_iffreq(4900000);
+		ifhz = cxd2841er_get_if_hz(priv, 4900000);
+		iffreq = cxd2841er_calc_iffreq(ifhz);
 		break;
 	case 6000000:
 		cxd2841er_write_regs(
 			priv, I2C_SLVT, 0xa6,
 			bw6mhz_b10_a6, sizeof(bw6mhz_b10_a6));
-		iffreq = cxd2841er_calc_iffreq(3700000);
+		ifhz = cxd2841er_get_if_hz(priv, 3700000);
+		iffreq = cxd2841er_calc_iffreq(ifhz);
 		break;
 	default:
 		dev_err(&priv->i2c->dev, "%s(): unsupported bandwidth %d\n",
drivers/media/dvb-frontends/cxd2841er.h +1 -0
index 15564af..38d7f9f 100644
@@ -25,6 +25,7 @@
 #include <linux/dvb/frontend.h>
 
 #define CXD2841ER_USE_GATECTRL	1
+#define CXD2841ER_AUTO_IFHZ	2
 
 enum cxd2841er_xtal {
 	SONY_XTAL_20500, /* 20.5 MHz */
Signature · 1 line
2.10.2
Acked-by on v1 8/19
#16 lore raw

Re: [PATCH 08/19] [media] dvb-frontends/cxd2841er: support IF speed calc from tuner values

2017-04-09 15:38 GMT-04:00 Daniel Scheller <[email protected]>:

Quoted 228 lines

From: Daniel Scheller <[email protected]>

Add a AUTO_IFHZ flag and a function that will read IF speed values from any attached tuner if the tuner supports this and if AUTO_IFHZ is enabled, and else the passed default value (which probably matches Sony ASCOT tuners) will be passed back. The returned value is then used to calculate the iffeq which the demod will be programmed with.

---
 drivers/media/dvb-frontends/cxd2841er.c | 64 +++++++++++++++++++++++----------
 drivers/media/dvb-frontends/cxd2841er.h |  1 +
 2 files changed, 47 insertions(+), 18 deletions(-)
drivers/media/dvb-frontends/cxd2841er.c +46 -18
index 162a0f5..fa6a963 100644
@@ -327,6 +327,20 @@ static u32 cxd2841er_calc_iffreq(u32 ifhz)
        return cxd2841er_calc_iffreq_xtal(SONY_XTAL_20500, ifhz);
 }
 
+static int cxd2841er_get_if_hz(struct cxd2841er_priv *priv, u32 def_hz)
+{
+       u32 hz;
+
+       if (priv->frontend.ops.tuner_ops.get_if_frequency
+                       && (priv->flags & CXD2841ER_AUTO_IFHZ))
+               priv->frontend.ops.tuner_ops.get_if_frequency(
+                       &priv->frontend, &hz);
+       else
+               hz = def_hz;
+
+       return hz;
+}
+
 static int cxd2841er_tuner_set(struct dvb_frontend *fe)
 {
        struct cxd2841er_priv *priv = fe->demodulator_priv;
@@ -2147,7 +2161,7 @@ static int cxd2841er_dvbt2_set_plp_config(struct cxd2841er_priv *priv,
 static int cxd2841er_sleep_tc_to_active_t2_band(struct cxd2841er_priv *priv,
                                                u32 bandwidth)
 {
-       u32 iffreq;
+       u32 iffreq, ifhz;
        u8 data[MAX_WRITE_REGSIZE];
 
        const uint8_t nominalRate8bw[3][5] = {
@@ -2253,7 +2267,8 @@ static int cxd2841er_sleep_tc_to_active_t2_band(struct cxd2841er_priv *priv,
                cxd2841er_write_regs(priv, I2C_SLVT,
                                0xA6, itbCoef8bw[priv->xtal], 14);
                /* <IF freq setting> */
-               iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, 4800000);
+               ifhz = cxd2841er_get_if_hz(priv, 4800000);
+               iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, ifhz);
                data[0] = (u8) ((iffreq >> 16) & 0xff);
                data[1] = (u8)((iffreq >> 8) & 0xff);
                data[2] = (u8)(iffreq & 0xff);
@@ -2281,7 +2296,8 @@ static int cxd2841er_sleep_tc_to_active_t2_band(struct cxd2841er_priv *priv,
                cxd2841er_write_regs(priv, I2C_SLVT,
                                0xA6, itbCoef7bw[priv->xtal], 14);
                /* <IF freq setting> */
-               iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, 4200000);
+               ifhz = cxd2841er_get_if_hz(priv, 4200000);
+               iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, ifhz);
                data[0] = (u8) ((iffreq >> 16) & 0xff);
                data[1] = (u8)((iffreq >> 8) & 0xff);
                data[2] = (u8)(iffreq & 0xff);
@@ -2309,7 +2325,8 @@ static int cxd2841er_sleep_tc_to_active_t2_band(struct cxd2841er_priv *priv,
                cxd2841er_write_regs(priv, I2C_SLVT,
                                0xA6, itbCoef6bw[priv->xtal], 14);
                /* <IF freq setting> */
-               iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, 3600000);
+               ifhz = cxd2841er_get_if_hz(priv, 3600000);
+               iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, ifhz);
                data[0] = (u8) ((iffreq >> 16) & 0xff);
                data[1] = (u8)((iffreq >> 8) & 0xff);
                data[2] = (u8)(iffreq & 0xff);
@@ -2337,7 +2354,8 @@ static int cxd2841er_sleep_tc_to_active_t2_band(struct cxd2841er_priv *priv,
                cxd2841er_write_regs(priv, I2C_SLVT,
                                0xA6, itbCoef5bw[priv->xtal], 14);
                /* <IF freq setting> */
-               iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, 3600000);
+               ifhz = cxd2841er_get_if_hz(priv, 3600000);
+               iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, ifhz);
                data[0] = (u8) ((iffreq >> 16) & 0xff);
                data[1] = (u8)((iffreq >> 8) & 0xff);
                data[2] = (u8)(iffreq & 0xff);
@@ -2365,7 +2383,8 @@ static int cxd2841er_sleep_tc_to_active_t2_band(struct cxd2841er_priv *priv,
                cxd2841er_write_regs(priv, I2C_SLVT,
                                0xA6, itbCoef17bw[priv->xtal], 14);
                /* <IF freq setting> */
-               iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, 3500000);
+               ifhz = cxd2841er_get_if_hz(priv, 3500000);
+               iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, ifhz);
                data[0] = (u8) ((iffreq >> 16) & 0xff);
                data[1] = (u8)((iffreq >> 8) & 0xff);
                data[2] = (u8)(iffreq & 0xff);
@@ -2384,7 +2403,7 @@ static int cxd2841er_sleep_tc_to_active_t_band(
                struct cxd2841er_priv *priv, u32 bandwidth)
 {
        u8 data[MAX_WRITE_REGSIZE];
-       u32 iffreq;
+       u32 iffreq, ifhz;
        u8 nominalRate8bw[3][5] = {
                /* TRCG Nominal Rate [37:0] */
                {0x11, 0xF0, 0x00, 0x00, 0x00}, /* 20.5MHz XTal */
@@ -2464,7 +2483,8 @@ static int cxd2841er_sleep_tc_to_active_t_band(
                cxd2841er_write_regs(priv, I2C_SLVT,
                                0xA6, itbCoef8bw[priv->xtal], 14);
                /* <IF freq setting> */
-               iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, 4800000);
+               ifhz = cxd2841er_get_if_hz(priv, 4800000);
+               iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, ifhz);
                data[0] = (u8) ((iffreq >> 16) & 0xff);
                data[1] = (u8)((iffreq >> 8) & 0xff);
                data[2] = (u8)(iffreq & 0xff);
@@ -2499,7 +2519,8 @@ static int cxd2841er_sleep_tc_to_active_t_band(
                cxd2841er_write_regs(priv, I2C_SLVT,
                                0xA6, itbCoef7bw[priv->xtal], 14);
                /* <IF freq setting> */
-               iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, 4200000);
+               ifhz = cxd2841er_get_if_hz(priv, 4200000);
+               iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, ifhz);
                data[0] = (u8) ((iffreq >> 16) & 0xff);
                data[1] = (u8)((iffreq >> 8) & 0xff);
                data[2] = (u8)(iffreq & 0xff);
@@ -2534,7 +2555,8 @@ static int cxd2841er_sleep_tc_to_active_t_band(
                cxd2841er_write_regs(priv, I2C_SLVT,
                                0xA6, itbCoef6bw[priv->xtal], 14);
                /* <IF freq setting> */
-               iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, 3600000);
+               ifhz = cxd2841er_get_if_hz(priv, 3600000);
+               iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, ifhz);
                data[0] = (u8) ((iffreq >> 16) & 0xff);
                data[1] = (u8)((iffreq >> 8) & 0xff);
                data[2] = (u8)(iffreq & 0xff);
@@ -2569,7 +2591,8 @@ static int cxd2841er_sleep_tc_to_active_t_band(
                cxd2841er_write_regs(priv, I2C_SLVT,
                                0xA6, itbCoef5bw[priv->xtal], 14);
                /* <IF freq setting> */
-               iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, 3600000);
+               ifhz = cxd2841er_get_if_hz(priv, 3600000);
+               iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, ifhz);
                data[0] = (u8) ((iffreq >> 16) & 0xff);
                data[1] = (u8)((iffreq >> 8) & 0xff);
                data[2] = (u8)(iffreq & 0xff);
@@ -2602,7 +2625,7 @@ static int cxd2841er_sleep_tc_to_active_t_band(
 static int cxd2841er_sleep_tc_to_active_i_band(
                struct cxd2841er_priv *priv, u32 bandwidth)
 {
-       u32 iffreq;
+       u32 iffreq, ifhz;
        u8 data[3];
 
        /* TRCG Nominal Rate */
@@ -2671,7 +2694,8 @@ static int cxd2841er_sleep_tc_to_active_i_band(
                                0xA6, itbCoef8bw[priv->xtal], 14);
 
                /* IF freq setting */
-               iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, 4750000);
+               ifhz = cxd2841er_get_if_hz(priv, 4750000);
+               iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, ifhz);
                data[0] = (u8) ((iffreq >> 16) & 0xff);
                data[1] = (u8)((iffreq >> 8) & 0xff);
                data[2] = (u8)(iffreq & 0xff);
@@ -2700,7 +2724,8 @@ static int cxd2841er_sleep_tc_to_active_i_band(
                                0xA6, itbCoef7bw[priv->xtal], 14);
 
                /* IF freq setting */
-               iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, 4150000);
+               ifhz = cxd2841er_get_if_hz(priv, 4150000);
+               iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, ifhz);
                data[0] = (u8) ((iffreq >> 16) & 0xff);
                data[1] = (u8)((iffreq >> 8) & 0xff);
                data[2] = (u8)(iffreq & 0xff);
@@ -2729,7 +2754,8 @@ static int cxd2841er_sleep_tc_to_active_i_band(
                                0xA6, itbCoef6bw[priv->xtal], 14);
 
                /* IF freq setting */
-               iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, 3550000);
+               ifhz = cxd2841er_get_if_hz(priv, 3550000);
+               iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, ifhz);
                data[0] = (u8) ((iffreq >> 16) & 0xff);
                data[1] = (u8)((iffreq >> 8) & 0xff);
                data[2] = (u8)(iffreq & 0xff);
@@ -2772,7 +2798,7 @@ static int cxd2841er_sleep_tc_to_active_c_band(struct cxd2841er_priv *priv,
                0x27, 0xA7, 0x28, 0xB3, 0x02, 0xF0, 0x01, 0xE8,
                0x00, 0xCF, 0x00, 0xE6, 0x23, 0xA4 };
        u8 b10_b6[3];
-       u32 iffreq;
+       u32 iffreq, ifhz;
 
        if (bandwidth != 6000000 &&
                        bandwidth != 7000000 &&
@@ -2790,13 +2816,15 @@ static int cxd2841er_sleep_tc_to_active_c_band(struct cxd2841er_priv *priv,
                cxd2841er_write_regs(
                        priv, I2C_SLVT, 0xa6,
                        bw7_8mhz_b10_a6, sizeof(bw7_8mhz_b10_a6));
-               iffreq = cxd2841er_calc_iffreq(4900000);
+               ifhz = cxd2841er_get_if_hz(priv, 4900000);
+               iffreq = cxd2841er_calc_iffreq(ifhz);
                break;
        case 6000000:
                cxd2841er_write_regs(
                        priv, I2C_SLVT, 0xa6,
                        bw6mhz_b10_a6, sizeof(bw6mhz_b10_a6));
-               iffreq = cxd2841er_calc_iffreq(3700000);
+               ifhz = cxd2841er_get_if_hz(priv, 3700000);
+               iffreq = cxd2841er_calc_iffreq(ifhz);
                break;
        default:
                dev_err(&priv->i2c->dev, "%s(): unsupported bandwidth %d\n",
drivers/media/dvb-frontends/cxd2841er.h +1 -1
index 15564af..38d7f9f 100644
@@ -25,6 +25,7 @@
 #include <linux/dvb/frontend.h>
 
 #define CXD2841ER_USE_GATECTRL 1
+#define CXD2841ER_AUTO_IFHZ    2
 
 enum cxd2841er_xtal {
        SONY_XTAL_20500, /* 20.5 MHz */
--

2.10.2

Signature · 3 lines
Abylay Ospan,
NetUP Inc.
http://www.netup.tv
#17 lore raw

PATCH 9/19 dvb-frontends/cxd2841er: TS_SERIAL config flag

In reply to Daniel Scheller

From: Daniel Scheller <[email protected]>

Some constellations work/need a serial TS transport mode. This adds a flag that will toggle set up of such mode.

---
 drivers/media/dvb-frontends/cxd2841er.c | 18 ++++++++++++++++--
 drivers/media/dvb-frontends/cxd2841er.h |  5 +++--
 2 files changed, 19 insertions(+), 4 deletions(-)
drivers/media/dvb-frontends/cxd2841er.c +16 -2
index fa6a963..1df95c4 100644
@@ -912,6 +912,18 @@ static void cxd2841er_set_ts_clock_mode(struct cxd2841er_priv *priv,
 
 	/*
 	 * slave    Bank    Addr    Bit    default    Name
+	 * <SLV-T>  00h     C4h     [1:0]  2'b??      OSERCKMODE
+	 */
+	cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xc4,
+		((priv->flags & CXD2841ER_TS_SERIAL) ? 0x01 : 0x00), 0x03);
+	/*
+	 * slave    Bank    Addr    Bit    default    Name
+	 * <SLV-T>  00h     D1h     [1:0]  2'b??      OSERDUTYMODE
+	 */
+	cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xd1,
+		((priv->flags & CXD2841ER_TS_SERIAL) ? 0x01 : 0x00), 0x03);
+	/*
+	 * slave    Bank    Addr    Bit    default    Name
 	 * <SLV-T>  00h     D9h     [7:0]  8'h08      OTSCKPERIOD
 	 */
 	cxd2841er_write_reg(priv, I2C_SLVT, 0xd9, 0x08);
@@ -925,7 +937,8 @@ static void cxd2841er_set_ts_clock_mode(struct cxd2841er_priv *priv,
 	 * slave    Bank    Addr    Bit    default    Name
 	 * <SLV-T>  00h     33h     [1:0]  2'b01      OREG_CKSEL_TSIF
 	 */
-	cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x33, 0x00, 0x03);
+	cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x33,
+		((priv->flags & CXD2841ER_TS_SERIAL) ? 0x01 : 0x00), 0x03);
 	/*
 	 * Enable TS IF Clock
 	 * slave    Bank    Addr    Bit    default    Name
@@ -3745,7 +3758,8 @@ static int cxd2841er_init_tc(struct dvb_frontend *fe)
 	cxd2841er_write_reg(priv, I2C_SLVT, 0xcd, 0x50);
 	/* SONY_DEMOD_CONFIG_PARALLEL_SEL = 1 */
 	cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00);
-	cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xc4, 0x00, 0x80);
+	cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xc4,
+		((priv->flags & CXD2841ER_TS_SERIAL) ? 0x80 : 0x00), 0x80);
 
 	cxd2841er_init_stats(fe);
 
drivers/media/dvb-frontends/cxd2841er.h +3 -2
index 38d7f9f..58fbd98 100644
@@ -24,8 +24,9 @@
 
 #include <linux/dvb/frontend.h>
 
-#define CXD2841ER_USE_GATECTRL	1
-#define CXD2841ER_AUTO_IFHZ	2
+#define CXD2841ER_USE_GATECTRL	1	/* bit 0 */
+#define CXD2841ER_AUTO_IFHZ	2	/* bit 1 */
+#define CXD2841ER_TS_SERIAL	4	/* bit 2 */
 
 enum cxd2841er_xtal {
 	SONY_XTAL_20500, /* 20.5 MHz */
Signature · 1 line
2.10.2
Acked-by on v1 9/19
#18 lore raw

Re: [PATCH 09/19] [media] dvb-frontends/cxd2841er: TS_SERIAL config flag

2017-04-09 15:38 GMT-04:00 Daniel Scheller <[email protected]>:

Quoted 73 lines

From: Daniel Scheller <[email protected]>

Some constellations work/need a serial TS transport mode. This adds a flag that will toggle set up of such mode.

---
 drivers/media/dvb-frontends/cxd2841er.c | 18 ++++++++++++++++--
 drivers/media/dvb-frontends/cxd2841er.h |  5 +++--
 2 files changed, 19 insertions(+), 4 deletions(-)
drivers/media/dvb-frontends/cxd2841er.c +16 -2
index fa6a963..1df95c4 100644
@@ -912,6 +912,18 @@ static void cxd2841er_set_ts_clock_mode(struct cxd2841er_priv *priv,
 
        /*
         * slave    Bank    Addr    Bit    default    Name
+        * <SLV-T>  00h     C4h     [1:0]  2'b??      OSERCKMODE
+        */
+       cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xc4,
+               ((priv->flags & CXD2841ER_TS_SERIAL) ? 0x01 : 0x00), 0x03);
+       /*
+        * slave    Bank    Addr    Bit    default    Name
+        * <SLV-T>  00h     D1h     [1:0]  2'b??      OSERDUTYMODE
+        */
+       cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xd1,
+               ((priv->flags & CXD2841ER_TS_SERIAL) ? 0x01 : 0x00), 0x03);
+       /*
+        * slave    Bank    Addr    Bit    default    Name
         * <SLV-T>  00h     D9h     [7:0]  8'h08      OTSCKPERIOD
         */
        cxd2841er_write_reg(priv, I2C_SLVT, 0xd9, 0x08);
@@ -925,7 +937,8 @@ static void cxd2841er_set_ts_clock_mode(struct cxd2841er_priv *priv,
         * slave    Bank    Addr    Bit    default    Name
         * <SLV-T>  00h     33h     [1:0]  2'b01      OREG_CKSEL_TSIF
         */
-       cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x33, 0x00, 0x03);
+       cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x33,
+               ((priv->flags & CXD2841ER_TS_SERIAL) ? 0x01 : 0x00), 0x03);
        /*
         * Enable TS IF Clock
         * slave    Bank    Addr    Bit    default    Name
@@ -3745,7 +3758,8 @@ static int cxd2841er_init_tc(struct dvb_frontend *fe)
        cxd2841er_write_reg(priv, I2C_SLVT, 0xcd, 0x50);
        /* SONY_DEMOD_CONFIG_PARALLEL_SEL = 1 */
        cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00);
-       cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xc4, 0x00, 0x80);
+       cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xc4,
+               ((priv->flags & CXD2841ER_TS_SERIAL) ? 0x80 : 0x00), 0x80);
 
        cxd2841er_init_stats(fe);
 
drivers/media/dvb-frontends/cxd2841er.h +3 -3
index 38d7f9f..58fbd98 100644
@@ -24,8 +24,9 @@
 
 #include <linux/dvb/frontend.h>
 
-#define CXD2841ER_USE_GATECTRL 1
-#define CXD2841ER_AUTO_IFHZ    2
+#define CXD2841ER_USE_GATECTRL 1       /* bit 0 */
+#define CXD2841ER_AUTO_IFHZ    2       /* bit 1 */
+#define CXD2841ER_TS_SERIAL    4       /* bit 2 */
 
 enum cxd2841er_xtal {
        SONY_XTAL_20500, /* 20.5 MHz */
--

2.10.2

Signature · 3 lines
Abylay Ospan,
NetUP Inc.
http://www.netup.tv
#19 lore raw

PATCH 10/19 dvb-frontends/cxd2841er: make ASCOT use optional

In reply to Daniel Scheller

From: Daniel Scheller <[email protected]>

The Sony CXD28xx demods may have other tuner types attached to them (e.g. NXP TDA18212), so don't mandatorily configure and enable the ASCOT functionality, but make this conditional by a config flag.

---
 drivers/media/dvb-frontends/cxd2841er.c            | 70 ++++++++++++++--------
 drivers/media/dvb-frontends/cxd2841er.h            |  1 +
 drivers/media/pci/netup_unidvb/netup_unidvb_core.c |  2 +-
 3 files changed, 46 insertions(+), 27 deletions(-)
drivers/media/dvb-frontends/cxd2841er.c +44 -26
index 1df95c4..7ca589a 100644
@@ -2277,7 +2277,8 @@ static int cxd2841er_sleep_tc_to_active_t2_band(struct cxd2841er_priv *priv,
 		/* Group delay equaliser settings for
 		 * ASCOT2D, ASCOT2E and ASCOT3 tuners
 		 */
-		cxd2841er_write_regs(priv, I2C_SLVT,
+		if (priv->flags & CXD2841ER_ASCOT)
+			cxd2841er_write_regs(priv, I2C_SLVT,
 				0xA6, itbCoef8bw[priv->xtal], 14);
 		/* <IF freq setting> */
 		ifhz = cxd2841er_get_if_hz(priv, 4800000);
@@ -2306,7 +2307,8 @@ static int cxd2841er_sleep_tc_to_active_t2_band(struct cxd2841er_priv *priv,
 		/* Group delay equaliser settings for
 		 * ASCOT2D, ASCOT2E and ASCOT3 tuners
 		 */
-		cxd2841er_write_regs(priv, I2C_SLVT,
+		if (priv->flags & CXD2841ER_ASCOT)
+			cxd2841er_write_regs(priv, I2C_SLVT,
 				0xA6, itbCoef7bw[priv->xtal], 14);
 		/* <IF freq setting> */
 		ifhz = cxd2841er_get_if_hz(priv, 4200000);
@@ -2335,7 +2337,8 @@ static int cxd2841er_sleep_tc_to_active_t2_band(struct cxd2841er_priv *priv,
 		/* Group delay equaliser settings for
 		 * ASCOT2D, ASCOT2E and ASCOT3 tuners
 		 */
-		cxd2841er_write_regs(priv, I2C_SLVT,
+		if (priv->flags & CXD2841ER_ASCOT)
+			cxd2841er_write_regs(priv, I2C_SLVT,
 				0xA6, itbCoef6bw[priv->xtal], 14);
 		/* <IF freq setting> */
 		ifhz = cxd2841er_get_if_hz(priv, 3600000);
@@ -2364,7 +2367,8 @@ static int cxd2841er_sleep_tc_to_active_t2_band(struct cxd2841er_priv *priv,
 		/* Group delay equaliser settings for
 		 * ASCOT2D, ASCOT2E and ASCOT3 tuners
 		 */
-		cxd2841er_write_regs(priv, I2C_SLVT,
+		if (priv->flags & CXD2841ER_ASCOT)
+			cxd2841er_write_regs(priv, I2C_SLVT,
 				0xA6, itbCoef5bw[priv->xtal], 14);
 		/* <IF freq setting> */
 		ifhz = cxd2841er_get_if_hz(priv, 3600000);
@@ -2393,7 +2397,8 @@ static int cxd2841er_sleep_tc_to_active_t2_band(struct cxd2841er_priv *priv,
 		/* Group delay equaliser settings for
 		 * ASCOT2D, ASCOT2E and ASCOT3 tuners
 		 */
-		cxd2841er_write_regs(priv, I2C_SLVT,
+		if (priv->flags & CXD2841ER_ASCOT)
+			cxd2841er_write_regs(priv, I2C_SLVT,
 				0xA6, itbCoef17bw[priv->xtal], 14);
 		/* <IF freq setting> */
 		ifhz = cxd2841er_get_if_hz(priv, 3500000);
@@ -2493,7 +2498,8 @@ static int cxd2841er_sleep_tc_to_active_t_band(
 		/* Group delay equaliser settings for
 		 * ASCOT2D, ASCOT2E and ASCOT3 tuners
 		*/
-		cxd2841er_write_regs(priv, I2C_SLVT,
+		if (priv->flags & CXD2841ER_ASCOT)
+			cxd2841er_write_regs(priv, I2C_SLVT,
 				0xA6, itbCoef8bw[priv->xtal], 14);
 		/* <IF freq setting> */
 		ifhz = cxd2841er_get_if_hz(priv, 4800000);
@@ -2529,7 +2535,8 @@ static int cxd2841er_sleep_tc_to_active_t_band(
 		/* Group delay equaliser settings for
 		 * ASCOT2D, ASCOT2E and ASCOT3 tuners
 		*/
-		cxd2841er_write_regs(priv, I2C_SLVT,
+		if (priv->flags & CXD2841ER_ASCOT)
+			cxd2841er_write_regs(priv, I2C_SLVT,
 				0xA6, itbCoef7bw[priv->xtal], 14);
 		/* <IF freq setting> */
 		ifhz = cxd2841er_get_if_hz(priv, 4200000);
@@ -2565,7 +2572,8 @@ static int cxd2841er_sleep_tc_to_active_t_band(
 		/* Group delay equaliser settings for
 		 * ASCOT2D, ASCOT2E and ASCOT3 tuners
 		*/
-		cxd2841er_write_regs(priv, I2C_SLVT,
+		if (priv->flags & CXD2841ER_ASCOT)
+			cxd2841er_write_regs(priv, I2C_SLVT,
 				0xA6, itbCoef6bw[priv->xtal], 14);
 		/* <IF freq setting> */
 		ifhz = cxd2841er_get_if_hz(priv, 3600000);
@@ -2601,7 +2609,8 @@ static int cxd2841er_sleep_tc_to_active_t_band(
 		/* Group delay equaliser settings for
 		 * ASCOT2D, ASCOT2E and ASCOT3 tuners
 		*/
-		cxd2841er_write_regs(priv, I2C_SLVT,
+		if (priv->flags & CXD2841ER_ASCOT)
+			cxd2841er_write_regs(priv, I2C_SLVT,
 				0xA6, itbCoef5bw[priv->xtal], 14);
 		/* <IF freq setting> */
 		ifhz = cxd2841er_get_if_hz(priv, 3600000);
@@ -2703,7 +2712,8 @@ static int cxd2841er_sleep_tc_to_active_i_band(
 		cxd2841er_write_regs(priv, I2C_SLVT,
 				0x9F, nominalRate8bw[priv->xtal], 5);
 		/*  Group delay equaliser settings for ASCOT tuners optimized */
-		cxd2841er_write_regs(priv, I2C_SLVT,
+		if (priv->flags & CXD2841ER_ASCOT)
+			cxd2841er_write_regs(priv, I2C_SLVT,
 				0xA6, itbCoef8bw[priv->xtal], 14);
 
 		/* IF freq setting */
@@ -2733,7 +2743,8 @@ static int cxd2841er_sleep_tc_to_active_i_band(
 		cxd2841er_write_regs(priv, I2C_SLVT,
 				0x9F, nominalRate7bw[priv->xtal], 5);
 		/*  Group delay equaliser settings for ASCOT tuners optimized */
-		cxd2841er_write_regs(priv, I2C_SLVT,
+		if (priv->flags & CXD2841ER_ASCOT)
+			cxd2841er_write_regs(priv, I2C_SLVT,
 				0xA6, itbCoef7bw[priv->xtal], 14);
 
 		/* IF freq setting */
@@ -2763,7 +2774,8 @@ static int cxd2841er_sleep_tc_to_active_i_band(
 		cxd2841er_write_regs(priv, I2C_SLVT,
 				0x9F, nominalRate6bw[priv->xtal], 5);
 		/*  Group delay equaliser settings for ASCOT tuners optimized */
-		cxd2841er_write_regs(priv, I2C_SLVT,
+		if (priv->flags & CXD2841ER_ASCOT)
+			cxd2841er_write_regs(priv, I2C_SLVT,
 				0xA6, itbCoef6bw[priv->xtal], 14);
 
 		/* IF freq setting */
@@ -2826,16 +2838,18 @@ static int cxd2841er_sleep_tc_to_active_c_band(struct cxd2841er_priv *priv,
 	switch (bandwidth) {
 	case 8000000:
 	case 7000000:
-		cxd2841er_write_regs(
-			priv, I2C_SLVT, 0xa6,
-			bw7_8mhz_b10_a6, sizeof(bw7_8mhz_b10_a6));
+		if (priv->flags & CXD2841ER_ASCOT)
+			cxd2841er_write_regs(
+				priv, I2C_SLVT, 0xa6,
+				bw7_8mhz_b10_a6, sizeof(bw7_8mhz_b10_a6));
 		ifhz = cxd2841er_get_if_hz(priv, 4900000);
 		iffreq = cxd2841er_calc_iffreq(ifhz);
 		break;
 	case 6000000:
-		cxd2841er_write_regs(
-			priv, I2C_SLVT, 0xa6,
-			bw6mhz_b10_a6, sizeof(bw6mhz_b10_a6));
+		if (priv->flags & CXD2841ER_ASCOT)
+			cxd2841er_write_regs(
+				priv, I2C_SLVT, 0xa6,
+				bw6mhz_b10_a6, sizeof(bw6mhz_b10_a6));
 		ifhz = cxd2841er_get_if_hz(priv, 3700000);
 		iffreq = cxd2841er_calc_iffreq(ifhz);
 		break;
@@ -2924,8 +2938,9 @@ static int cxd2841er_sleep_tc_to_active_t(struct cxd2841er_priv *priv,
 	cxd2841er_write_reg(priv, I2C_SLVT, 0x6a, 0x50);
 	/* Set SLV-T Bank : 0x10 */
 	cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10);
-	/* ASCOT setting ON */
-	cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xa5, 0x01, 0x01);
+	/* ASCOT setting */
+	cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xa5,
+		((priv->flags & CXD2841ER_ASCOT) ? 0x01 : 0x00), 0x01);
 	/* Set SLV-T Bank : 0x18 */
 	cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x18);
 	/* Pre-RS BER moniter setting */
@@ -3002,8 +3017,9 @@ static int cxd2841er_sleep_tc_to_active_t2(struct cxd2841er_priv *priv,
 	cxd2841er_write_reg(priv, I2C_SLVT, 0x6a, 0x50);
 	/* Set SLV-T Bank : 0x10 */
 	cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10);
-	/* ASCOT setting ON */
-	cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xa5, 0x01, 0x01);
+	/* ASCOT setting */
+	cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xa5,
+		((priv->flags & CXD2841ER_ASCOT) ? 0x01 : 0x00), 0x01);
 	/* Set SLV-T Bank : 0x20 */
 	cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x20);
 	/* Acquisition optimization setting */
@@ -3140,8 +3156,9 @@ static int cxd2841er_sleep_tc_to_active_i(struct cxd2841er_priv *priv,
 	cxd2841er_write_regs(priv, I2C_SLVT, 0x43, data, 2);
 	/* Enable ADC 4 */
 	cxd2841er_write_reg(priv, I2C_SLVX, 0x18, 0x00);
-	/* ASCOT setting ON */
-	cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xa5, 0x01, 0x01);
+	/* ASCOT setting */
+	cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xa5,
+		((priv->flags & CXD2841ER_ASCOT) ? 0x01 : 0x00), 0x01);
 	/* FEC Auto Recovery setting */
 	cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x30, 0x01, 0x01);
 	cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x31, 0x00, 0x01);
@@ -3225,8 +3242,9 @@ static int cxd2841er_sleep_tc_to_active_c(struct cxd2841er_priv *priv,
 	cxd2841er_write_reg(priv, I2C_SLVT, 0x6a, 0x48);
 	/* Set SLV-T Bank : 0x10 */
 	cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10);
-	/* ASCOT setting ON */
-	cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xa5, 0x01, 0x01);
+	/* ASCOT setting */
+	cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xa5,
+		((priv->flags & CXD2841ER_ASCOT) ? 0x01 : 0x00), 0x01);
 	/* Set SLV-T Bank : 0x40 */
 	cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x40);
 	/* Demod setting */
drivers/media/dvb-frontends/cxd2841er.h +1 -0
index 58fbd98..90ced97 100644
@@ -27,6 +27,7 @@
 #define CXD2841ER_USE_GATECTRL	1	/* bit 0 */
 #define CXD2841ER_AUTO_IFHZ	2	/* bit 1 */
 #define CXD2841ER_TS_SERIAL	4	/* bit 2 */
+#define CXD2841ER_ASCOT		8	/* bit 3 */
 
 enum cxd2841er_xtal {
 	SONY_XTAL_20500, /* 20.5 MHz */
drivers/media/pci/netup_unidvb/netup_unidvb_core.c +1 -1
index 5e6553f..8b389b3 100644
@@ -123,7 +123,7 @@ static void netup_unidvb_queue_cleanup(struct netup_dma *dma);
 static struct cxd2841er_config demod_config = {
 	.i2c_addr = 0xc8,
 	.xtal = SONY_XTAL_24000,
-	.flags = CXD2841ER_USE_GATECTRL
+	.flags = CXD2841ER_USE_GATECTRL | CXD2841ER_ASCOT
 };
 
 static struct horus3a_config horus3a_conf = {
Signature · 1 line
2.10.2
Acked-by on v1 10/19
#20 lore raw

Re: [PATCH 10/19] [media] dvb-frontends/cxd2841er: make ASCOT use optional

2017-04-09 15:38 GMT-04:00 Daniel Scheller <[email protected]>:

Quoted 238 lines

From: Daniel Scheller <[email protected]>

The Sony CXD28xx demods may have other tuner types attached to them (e.g. NXP TDA18212), so don't mandatorily configure and enable the ASCOT functionality, but make this conditional by a config flag.

---
 drivers/media/dvb-frontends/cxd2841er.c            | 70 ++++++++++++++--------
 drivers/media/dvb-frontends/cxd2841er.h            |  1 +
 drivers/media/pci/netup_unidvb/netup_unidvb_core.c |  2 +-
 3 files changed, 46 insertions(+), 27 deletions(-)
drivers/media/dvb-frontends/cxd2841er.c +44 -26
index 1df95c4..7ca589a 100644
@@ -2277,7 +2277,8 @@ static int cxd2841er_sleep_tc_to_active_t2_band(struct cxd2841er_priv *priv,
                /* Group delay equaliser settings for
                 * ASCOT2D, ASCOT2E and ASCOT3 tuners
                 */
-               cxd2841er_write_regs(priv, I2C_SLVT,
+               if (priv->flags & CXD2841ER_ASCOT)
+                       cxd2841er_write_regs(priv, I2C_SLVT,
                                0xA6, itbCoef8bw[priv->xtal], 14);
                /* <IF freq setting> */
                ifhz = cxd2841er_get_if_hz(priv, 4800000);
@@ -2306,7 +2307,8 @@ static int cxd2841er_sleep_tc_to_active_t2_band(struct cxd2841er_priv *priv,
                /* Group delay equaliser settings for
                 * ASCOT2D, ASCOT2E and ASCOT3 tuners
                 */
-               cxd2841er_write_regs(priv, I2C_SLVT,
+               if (priv->flags & CXD2841ER_ASCOT)
+                       cxd2841er_write_regs(priv, I2C_SLVT,
                                0xA6, itbCoef7bw[priv->xtal], 14);
                /* <IF freq setting> */
                ifhz = cxd2841er_get_if_hz(priv, 4200000);
@@ -2335,7 +2337,8 @@ static int cxd2841er_sleep_tc_to_active_t2_band(struct cxd2841er_priv *priv,
                /* Group delay equaliser settings for
                 * ASCOT2D, ASCOT2E and ASCOT3 tuners
                 */
-               cxd2841er_write_regs(priv, I2C_SLVT,
+               if (priv->flags & CXD2841ER_ASCOT)
+                       cxd2841er_write_regs(priv, I2C_SLVT,
                                0xA6, itbCoef6bw[priv->xtal], 14);
                /* <IF freq setting> */
                ifhz = cxd2841er_get_if_hz(priv, 3600000);
@@ -2364,7 +2367,8 @@ static int cxd2841er_sleep_tc_to_active_t2_band(struct cxd2841er_priv *priv,
                /* Group delay equaliser settings for
                 * ASCOT2D, ASCOT2E and ASCOT3 tuners
                 */
-               cxd2841er_write_regs(priv, I2C_SLVT,
+               if (priv->flags & CXD2841ER_ASCOT)
+                       cxd2841er_write_regs(priv, I2C_SLVT,
                                0xA6, itbCoef5bw[priv->xtal], 14);
                /* <IF freq setting> */
                ifhz = cxd2841er_get_if_hz(priv, 3600000);
@@ -2393,7 +2397,8 @@ static int cxd2841er_sleep_tc_to_active_t2_band(struct cxd2841er_priv *priv,
                /* Group delay equaliser settings for
                 * ASCOT2D, ASCOT2E and ASCOT3 tuners
                 */
-               cxd2841er_write_regs(priv, I2C_SLVT,
+               if (priv->flags & CXD2841ER_ASCOT)
+                       cxd2841er_write_regs(priv, I2C_SLVT,
                                0xA6, itbCoef17bw[priv->xtal], 14);
                /* <IF freq setting> */
                ifhz = cxd2841er_get_if_hz(priv, 3500000);
@@ -2493,7 +2498,8 @@ static int cxd2841er_sleep_tc_to_active_t_band(
                /* Group delay equaliser settings for
                 * ASCOT2D, ASCOT2E and ASCOT3 tuners
                */
-               cxd2841er_write_regs(priv, I2C_SLVT,
+               if (priv->flags & CXD2841ER_ASCOT)
+                       cxd2841er_write_regs(priv, I2C_SLVT,
                                0xA6, itbCoef8bw[priv->xtal], 14);
                /* <IF freq setting> */
                ifhz = cxd2841er_get_if_hz(priv, 4800000);
@@ -2529,7 +2535,8 @@ static int cxd2841er_sleep_tc_to_active_t_band(
                /* Group delay equaliser settings for
                 * ASCOT2D, ASCOT2E and ASCOT3 tuners
                */
-               cxd2841er_write_regs(priv, I2C_SLVT,
+               if (priv->flags & CXD2841ER_ASCOT)
+                       cxd2841er_write_regs(priv, I2C_SLVT,
                                0xA6, itbCoef7bw[priv->xtal], 14);
                /* <IF freq setting> */
                ifhz = cxd2841er_get_if_hz(priv, 4200000);
@@ -2565,7 +2572,8 @@ static int cxd2841er_sleep_tc_to_active_t_band(
                /* Group delay equaliser settings for
                 * ASCOT2D, ASCOT2E and ASCOT3 tuners
                */
-               cxd2841er_write_regs(priv, I2C_SLVT,
+               if (priv->flags & CXD2841ER_ASCOT)
+                       cxd2841er_write_regs(priv, I2C_SLVT,
                                0xA6, itbCoef6bw[priv->xtal], 14);
                /* <IF freq setting> */
                ifhz = cxd2841er_get_if_hz(priv, 3600000);
@@ -2601,7 +2609,8 @@ static int cxd2841er_sleep_tc_to_active_t_band(
                /* Group delay equaliser settings for
                 * ASCOT2D, ASCOT2E and ASCOT3 tuners
                */
-               cxd2841er_write_regs(priv, I2C_SLVT,
+               if (priv->flags & CXD2841ER_ASCOT)
+                       cxd2841er_write_regs(priv, I2C_SLVT,
                                0xA6, itbCoef5bw[priv->xtal], 14);
                /* <IF freq setting> */
                ifhz = cxd2841er_get_if_hz(priv, 3600000);
@@ -2703,7 +2712,8 @@ static int cxd2841er_sleep_tc_to_active_i_band(
                cxd2841er_write_regs(priv, I2C_SLVT,
                                0x9F, nominalRate8bw[priv->xtal], 5);
                /*  Group delay equaliser settings for ASCOT tuners optimized */
-               cxd2841er_write_regs(priv, I2C_SLVT,
+               if (priv->flags & CXD2841ER_ASCOT)
+                       cxd2841er_write_regs(priv, I2C_SLVT,
                                0xA6, itbCoef8bw[priv->xtal], 14);
 
                /* IF freq setting */
@@ -2733,7 +2743,8 @@ static int cxd2841er_sleep_tc_to_active_i_band(
                cxd2841er_write_regs(priv, I2C_SLVT,
                                0x9F, nominalRate7bw[priv->xtal], 5);
                /*  Group delay equaliser settings for ASCOT tuners optimized */
-               cxd2841er_write_regs(priv, I2C_SLVT,
+               if (priv->flags & CXD2841ER_ASCOT)
+                       cxd2841er_write_regs(priv, I2C_SLVT,
                                0xA6, itbCoef7bw[priv->xtal], 14);
 
                /* IF freq setting */
@@ -2763,7 +2774,8 @@ static int cxd2841er_sleep_tc_to_active_i_band(
                cxd2841er_write_regs(priv, I2C_SLVT,
                                0x9F, nominalRate6bw[priv->xtal], 5);
                /*  Group delay equaliser settings for ASCOT tuners optimized */
-               cxd2841er_write_regs(priv, I2C_SLVT,
+               if (priv->flags & CXD2841ER_ASCOT)
+                       cxd2841er_write_regs(priv, I2C_SLVT,
                                0xA6, itbCoef6bw[priv->xtal], 14);
 
                /* IF freq setting */
@@ -2826,16 +2838,18 @@ static int cxd2841er_sleep_tc_to_active_c_band(struct cxd2841er_priv *priv,
        switch (bandwidth) {
        case 8000000:
        case 7000000:
-               cxd2841er_write_regs(
-                       priv, I2C_SLVT, 0xa6,
-                       bw7_8mhz_b10_a6, sizeof(bw7_8mhz_b10_a6));
+               if (priv->flags & CXD2841ER_ASCOT)
+                       cxd2841er_write_regs(
+                               priv, I2C_SLVT, 0xa6,
+                               bw7_8mhz_b10_a6, sizeof(bw7_8mhz_b10_a6));
                ifhz = cxd2841er_get_if_hz(priv, 4900000);
                iffreq = cxd2841er_calc_iffreq(ifhz);
                break;
        case 6000000:
-               cxd2841er_write_regs(
-                       priv, I2C_SLVT, 0xa6,
-                       bw6mhz_b10_a6, sizeof(bw6mhz_b10_a6));
+               if (priv->flags & CXD2841ER_ASCOT)
+                       cxd2841er_write_regs(
+                               priv, I2C_SLVT, 0xa6,
+                               bw6mhz_b10_a6, sizeof(bw6mhz_b10_a6));
                ifhz = cxd2841er_get_if_hz(priv, 3700000);
                iffreq = cxd2841er_calc_iffreq(ifhz);
                break;
@@ -2924,8 +2938,9 @@ static int cxd2841er_sleep_tc_to_active_t(struct cxd2841er_priv *priv,
        cxd2841er_write_reg(priv, I2C_SLVT, 0x6a, 0x50);
        /* Set SLV-T Bank : 0x10 */
        cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10);
-       /* ASCOT setting ON */
-       cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xa5, 0x01, 0x01);
+       /* ASCOT setting */
+       cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xa5,
+               ((priv->flags & CXD2841ER_ASCOT) ? 0x01 : 0x00), 0x01);
        /* Set SLV-T Bank : 0x18 */
        cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x18);
        /* Pre-RS BER moniter setting */
@@ -3002,8 +3017,9 @@ static int cxd2841er_sleep_tc_to_active_t2(struct cxd2841er_priv *priv,
        cxd2841er_write_reg(priv, I2C_SLVT, 0x6a, 0x50);
        /* Set SLV-T Bank : 0x10 */
        cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10);
-       /* ASCOT setting ON */
-       cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xa5, 0x01, 0x01);
+       /* ASCOT setting */
+       cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xa5,
+               ((priv->flags & CXD2841ER_ASCOT) ? 0x01 : 0x00), 0x01);
        /* Set SLV-T Bank : 0x20 */
        cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x20);
        /* Acquisition optimization setting */
@@ -3140,8 +3156,9 @@ static int cxd2841er_sleep_tc_to_active_i(struct cxd2841er_priv *priv,
        cxd2841er_write_regs(priv, I2C_SLVT, 0x43, data, 2);
        /* Enable ADC 4 */
        cxd2841er_write_reg(priv, I2C_SLVX, 0x18, 0x00);
-       /* ASCOT setting ON */
-       cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xa5, 0x01, 0x01);
+       /* ASCOT setting */
+       cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xa5,
+               ((priv->flags & CXD2841ER_ASCOT) ? 0x01 : 0x00), 0x01);
        /* FEC Auto Recovery setting */
        cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x30, 0x01, 0x01);
        cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x31, 0x00, 0x01);
@@ -3225,8 +3242,9 @@ static int cxd2841er_sleep_tc_to_active_c(struct cxd2841er_priv *priv,
        cxd2841er_write_reg(priv, I2C_SLVT, 0x6a, 0x48);
        /* Set SLV-T Bank : 0x10 */
        cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10);
-       /* ASCOT setting ON */
-       cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xa5, 0x01, 0x01);
+       /* ASCOT setting */
+       cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xa5,
+               ((priv->flags & CXD2841ER_ASCOT) ? 0x01 : 0x00), 0x01);
        /* Set SLV-T Bank : 0x40 */
        cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x40);
        /* Demod setting */
drivers/media/dvb-frontends/cxd2841er.h +1 -0
index 58fbd98..90ced97 100644
@@ -27,6 +27,7 @@
 #define CXD2841ER_USE_GATECTRL 1       /* bit 0 */
 #define CXD2841ER_AUTO_IFHZ    2       /* bit 1 */
 #define CXD2841ER_TS_SERIAL    4       /* bit 2 */
+#define CXD2841ER_ASCOT                8       /* bit 3 */
 
 enum cxd2841er_xtal {
        SONY_XTAL_20500, /* 20.5 MHz */
drivers/media/pci/netup_unidvb/netup_unidvb_core.c +1 -2
index 5e6553f..8b389b3 100644
@@ -123,7 +123,7 @@ static void netup_unidvb_queue_cleanup(struct netup_dma *dma);
 static struct cxd2841er_config demod_config = {
        .i2c_addr = 0xc8,
        .xtal = SONY_XTAL_24000,
-       .flags = CXD2841ER_USE_GATECTRL
+       .flags = CXD2841ER_USE_GATECTRL | CXD2841ER_ASCOT
 };
 
 static struct horus3a_config horus3a_conf = {
--

2.10.2

Signature · 3 lines
Abylay Ospan,
NetUP Inc.
http://www.netup.tv
#21 lore raw

PATCH 11/19 dvb-frontends/cxd2841er: optionally tune earlier in set_frontend()

In reply to Daniel Scheller

From: Daniel Scheller <[email protected]>

When AUTO_IFHZ is set and the tuner is supposed to provide proper IF speed values, it should be possible to have the tuner setup take place before the demod is configured, else the demod might be configured with either wrong (old), or even no values at all, which obviously will cause issues. To set this behaviour in the most flexible way, this is done with a separate flag instead of making this depend on AUTO_IFHZ.

It should be evaluated if tuning shouldn't take place earlier in all cases and hardware constellations.

---
 drivers/media/dvb-frontends/cxd2841er.c | 14 ++++++++++++--
 drivers/media/dvb-frontends/cxd2841er.h |  1 +
 2 files changed, 13 insertions(+), 2 deletions(-)
drivers/media/dvb-frontends/cxd2841er.c +12 -2
index 7ca589a..894cb5a 100644
@@ -3306,6 +3306,10 @@ static int cxd2841er_set_frontend_s(struct dvb_frontend *fe)
 		__func__,
 		(p->delivery_system == SYS_DVBS ? "DVB-S" : "DVB-S2"),
 		 p->frequency, symbol_rate, priv->xtal);
+
+	if (priv->flags & CXD2841ER_EARLY_TUNE)
+		cxd2841er_tuner_set(fe);
+
 	switch (priv->state) {
 	case STATE_SLEEP_S:
 		ret = cxd2841er_sleep_s_to_active_s(
@@ -3325,7 +3329,8 @@ static int cxd2841er_set_frontend_s(struct dvb_frontend *fe)
 		goto done;
 	}
 
-	cxd2841er_tuner_set(fe);
+	if (!(priv->flags & CXD2841ER_EARLY_TUNE))
+		cxd2841er_tuner_set(fe);
 
 	cxd2841er_tune_done(priv);
 	timeout = ((3000000 + (symbol_rate - 1)) / symbol_rate) + 150;
@@ -3365,6 +3370,10 @@ static int cxd2841er_set_frontend_tc(struct dvb_frontend *fe)
 
 	dev_dbg(&priv->i2c->dev, "%s() delivery_system=%d bandwidth_hz=%d\n",
 		 __func__, p->delivery_system, p->bandwidth_hz);
+
+	if (priv->flags & CXD2841ER_EARLY_TUNE)
+		cxd2841er_tuner_set(fe);
+
 	if (p->delivery_system == SYS_DVBT) {
 		priv->system = SYS_DVBT;
 		switch (priv->state) {
@@ -3447,7 +3456,8 @@ static int cxd2841er_set_frontend_tc(struct dvb_frontend *fe)
 	if (ret)
 		goto done;
 
-	cxd2841er_tuner_set(fe);
+	if (!(priv->flags & CXD2841ER_EARLY_TUNE))
+		cxd2841er_tuner_set(fe);
 
 	cxd2841er_tune_done(priv);
 	timeout = 2500;
drivers/media/dvb-frontends/cxd2841er.h +1 -0
index 90ced97..061e551 100644
@@ -28,6 +28,7 @@
 #define CXD2841ER_AUTO_IFHZ	2	/* bit 1 */
 #define CXD2841ER_TS_SERIAL	4	/* bit 2 */
 #define CXD2841ER_ASCOT		8	/* bit 3 */
+#define CXD2841ER_EARLY_TUNE	16	/* bit 4 */
 
 enum cxd2841er_xtal {
 	SONY_XTAL_20500, /* 20.5 MHz */
Signature · 1 line
2.10.2
Acked-by on v1 11/19
#22 lore raw

Re: [PATCH 11/19] [media] dvb-frontends/cxd2841er: optionally tune earlier in set_frontend()

2017-04-09 15:38 GMT-04:00 Daniel Scheller <[email protected]>:

Quoted 79 lines

From: Daniel Scheller <[email protected]>

When AUTO_IFHZ is set and the tuner is supposed to provide proper IF speed values, it should be possible to have the tuner setup take place before the demod is configured, else the demod might be configured with either wrong (old), or even no values at all, which obviously will cause issues. To set this behaviour in the most flexible way, this is done with a separate flag instead of making this depend on AUTO_IFHZ.

It should be evaluated if tuning shouldn't take place earlier in all cases and hardware constellations.

---
 drivers/media/dvb-frontends/cxd2841er.c | 14 ++++++++++++--
 drivers/media/dvb-frontends/cxd2841er.h |  1 +
 2 files changed, 13 insertions(+), 2 deletions(-)
drivers/media/dvb-frontends/cxd2841er.c +12 -2
index 7ca589a..894cb5a 100644
@@ -3306,6 +3306,10 @@ static int cxd2841er_set_frontend_s(struct dvb_frontend *fe)
                __func__,
                (p->delivery_system == SYS_DVBS ? "DVB-S" : "DVB-S2"),
                 p->frequency, symbol_rate, priv->xtal);
+
+       if (priv->flags & CXD2841ER_EARLY_TUNE)
+               cxd2841er_tuner_set(fe);
+
        switch (priv->state) {
        case STATE_SLEEP_S:
                ret = cxd2841er_sleep_s_to_active_s(
@@ -3325,7 +3329,8 @@ static int cxd2841er_set_frontend_s(struct dvb_frontend *fe)
                goto done;
        }
 
-       cxd2841er_tuner_set(fe);
+       if (!(priv->flags & CXD2841ER_EARLY_TUNE))
+               cxd2841er_tuner_set(fe);
 
        cxd2841er_tune_done(priv);
        timeout = ((3000000 + (symbol_rate - 1)) / symbol_rate) + 150;
@@ -3365,6 +3370,10 @@ static int cxd2841er_set_frontend_tc(struct dvb_frontend *fe)
 
        dev_dbg(&priv->i2c->dev, "%s() delivery_system=%d bandwidth_hz=%d\n",
                 __func__, p->delivery_system, p->bandwidth_hz);
+
+       if (priv->flags & CXD2841ER_EARLY_TUNE)
+               cxd2841er_tuner_set(fe);
+
        if (p->delivery_system == SYS_DVBT) {
                priv->system = SYS_DVBT;
                switch (priv->state) {
@@ -3447,7 +3456,8 @@ static int cxd2841er_set_frontend_tc(struct dvb_frontend *fe)
        if (ret)
                goto done;
 
-       cxd2841er_tuner_set(fe);
+       if (!(priv->flags & CXD2841ER_EARLY_TUNE))
+               cxd2841er_tuner_set(fe);
 
        cxd2841er_tune_done(priv);
        timeout = 2500;
drivers/media/dvb-frontends/cxd2841er.h +1 -1
index 90ced97..061e551 100644
@@ -28,6 +28,7 @@
 #define CXD2841ER_AUTO_IFHZ    2       /* bit 1 */
 #define CXD2841ER_TS_SERIAL    4       /* bit 2 */
 #define CXD2841ER_ASCOT                8       /* bit 3 */
+#define CXD2841ER_EARLY_TUNE   16      /* bit 4 */
 
 enum cxd2841er_xtal {
        SONY_XTAL_20500, /* 20.5 MHz */
--

2.10.2

Signature · 3 lines
Abylay Ospan,
NetUP Inc.
http://www.netup.tv
#23 lore raw

PATCH 12/19 dvb-frontends/cxd2841er: make lock wait in set_fe_tc() optional

In reply to Daniel Scheller

From: Daniel Scheller <[email protected]>

Don't wait for FE_HAS_LOCK in set_frontend_tc() and thus don't hammer the lock status register with inquiries when CXD2841ER_NO_WAIT_LOCK is set in the configuration, which also unneccessarily blocks applications until a TS LOCK has been acquired. Rather, API and applications will check for a TS LOCK by utilising the tune fe_op, read_status and get_frontend ops, which is sufficient.

---
 drivers/media/dvb-frontends/cxd2841er.c | 4 ++++
 drivers/media/dvb-frontends/cxd2841er.h | 1 +
 2 files changed, 5 insertions(+)
drivers/media/dvb-frontends/cxd2841er.c +4 -0
index 894cb5a..67d4399 100644
@@ -3460,6 +3460,10 @@ static int cxd2841er_set_frontend_tc(struct dvb_frontend *fe)
 		cxd2841er_tuner_set(fe);
 
 	cxd2841er_tune_done(priv);
+
+	if (priv->flags & CXD2841ER_NO_WAIT_LOCK)
+		goto done;
+
 	timeout = 2500;
 	while (timeout > 0) {
 		ret = cxd2841er_read_status_tc(fe, &status);
drivers/media/dvb-frontends/cxd2841er.h +1 -0
index 061e551..d77b59f 100644
@@ -29,6 +29,7 @@
 #define CXD2841ER_TS_SERIAL	4	/* bit 2 */
 #define CXD2841ER_ASCOT		8	/* bit 3 */
 #define CXD2841ER_EARLY_TUNE	16	/* bit 4 */
+#define CXD2841ER_NO_WAIT_LOCK	32	/* bit 5 */
 
 enum cxd2841er_xtal {
 	SONY_XTAL_20500, /* 20.5 MHz */
Signature · 1 line
2.10.2
Acked-by on v1 12/19
#24 lore raw

Re: [PATCH 12/19] [media] dvb-frontends/cxd2841er: make lock wait in set_fe_tc() optional

2017-04-09 15:38 GMT-04:00 Daniel Scheller <[email protected]>:

Quoted 45 lines

From: Daniel Scheller <[email protected]>

Don't wait for FE_HAS_LOCK in set_frontend_tc() and thus don't hammer the lock status register with inquiries when CXD2841ER_NO_WAIT_LOCK is set in the configuration, which also unneccessarily blocks applications until a TS LOCK has been acquired. Rather, API and applications will check for a TS LOCK by utilising the tune fe_op, read_status and get_frontend ops, which is sufficient.

---
 drivers/media/dvb-frontends/cxd2841er.c | 4 ++++
 drivers/media/dvb-frontends/cxd2841er.h | 1 +
 2 files changed, 5 insertions(+)
drivers/media/dvb-frontends/cxd2841er.c +4 -0
index 894cb5a..67d4399 100644
@@ -3460,6 +3460,10 @@ static int cxd2841er_set_frontend_tc(struct dvb_frontend *fe)
                cxd2841er_tuner_set(fe);
 
        cxd2841er_tune_done(priv);
+
+       if (priv->flags & CXD2841ER_NO_WAIT_LOCK)
+               goto done;
+
        timeout = 2500;
        while (timeout > 0) {
                ret = cxd2841er_read_status_tc(fe, &status);
drivers/media/dvb-frontends/cxd2841er.h +1 -1
index 061e551..d77b59f 100644
@@ -29,6 +29,7 @@
 #define CXD2841ER_TS_SERIAL    4       /* bit 2 */
 #define CXD2841ER_ASCOT                8       /* bit 3 */
 #define CXD2841ER_EARLY_TUNE   16      /* bit 4 */
+#define CXD2841ER_NO_WAIT_LOCK 32      /* bit 5 */
 
 enum cxd2841er_xtal {
        SONY_XTAL_20500, /* 20.5 MHz */
--

2.10.2

Signature · 3 lines
Abylay Ospan,
NetUP Inc.
http://www.netup.tv
#25 lore raw

PATCH 13/19 dvb-frontends/cxd2841er: configurable IFAGCNEG

In reply to Daniel Scheller

From: Daniel Scheller <[email protected]>

Adds a flag to enable or disable the IFAGCNEG bit in cxd2841er_init_tc().

---
 drivers/media/dvb-frontends/cxd2841er.c | 5 +++--
 drivers/media/dvb-frontends/cxd2841er.h | 1 +
 2 files changed, 4 insertions(+), 2 deletions(-)
drivers/media/dvb-frontends/cxd2841er.c +3 -2
index 67d4399..67bd13c 100644
@@ -3783,9 +3783,10 @@ static int cxd2841er_init_tc(struct dvb_frontend *fe)
 	dev_dbg(&priv->i2c->dev, "%s() bandwidth_hz=%d\n",
 			__func__, p->bandwidth_hz);
 	cxd2841er_shutdown_to_sleep_tc(priv);
-	/* SONY_DEMOD_CONFIG_IFAGCNEG = 1 */
+	/* SONY_DEMOD_CONFIG_IFAGCNEG = 1 (0 for NO_AGCNEG */
 	cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10);
-	cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xcb, 0x40, 0x40);
+	cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xcb,
+		((priv->flags & CXD2841ER_NO_AGCNEG) ? 0x00 : 0x40), 0x40);
 	/* SONY_DEMOD_CONFIG_IFAGC_ADC_FS = 0 */
 	cxd2841er_write_reg(priv, I2C_SLVT, 0xcd, 0x50);
 	/* SONY_DEMOD_CONFIG_PARALLEL_SEL = 1 */
drivers/media/dvb-frontends/cxd2841er.h +1 -0
index d77b59f..4f94422 100644
@@ -30,6 +30,7 @@
 #define CXD2841ER_ASCOT		8	/* bit 3 */
 #define CXD2841ER_EARLY_TUNE	16	/* bit 4 */
 #define CXD2841ER_NO_WAIT_LOCK	32	/* bit 5 */
+#define CXD2841ER_NO_AGCNEG	64	/* bit 6 */
 
 enum cxd2841er_xtal {
 	SONY_XTAL_20500, /* 20.5 MHz */
Signature · 1 line
2.10.2
Acked-by on v1 13/19
#26 lore raw

Re: [PATCH 13/19] [media] dvb-frontends/cxd2841er: configurable IFAGCNEG

2017-04-09 15:38 GMT-04:00 Daniel Scheller <[email protected]>:

Quoted 42 lines

From: Daniel Scheller <[email protected]>

Adds a flag to enable or disable the IFAGCNEG bit in cxd2841er_init_tc().

---
 drivers/media/dvb-frontends/cxd2841er.c | 5 +++--
 drivers/media/dvb-frontends/cxd2841er.h | 1 +
 2 files changed, 4 insertions(+), 2 deletions(-)
drivers/media/dvb-frontends/cxd2841er.c +3 -2
index 67d4399..67bd13c 100644
@@ -3783,9 +3783,10 @@ static int cxd2841er_init_tc(struct dvb_frontend *fe)
        dev_dbg(&priv->i2c->dev, "%s() bandwidth_hz=%d\n",
                        __func__, p->bandwidth_hz);
        cxd2841er_shutdown_to_sleep_tc(priv);
-       /* SONY_DEMOD_CONFIG_IFAGCNEG = 1 */
+       /* SONY_DEMOD_CONFIG_IFAGCNEG = 1 (0 for NO_AGCNEG */
        cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10);
-       cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xcb, 0x40, 0x40);
+       cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xcb,
+               ((priv->flags & CXD2841ER_NO_AGCNEG) ? 0x00 : 0x40), 0x40);
        /* SONY_DEMOD_CONFIG_IFAGC_ADC_FS = 0 */
        cxd2841er_write_reg(priv, I2C_SLVT, 0xcd, 0x50);
        /* SONY_DEMOD_CONFIG_PARALLEL_SEL = 1 */
drivers/media/dvb-frontends/cxd2841er.h +1 -1
index d77b59f..4f94422 100644
@@ -30,6 +30,7 @@
 #define CXD2841ER_ASCOT                8       /* bit 3 */
 #define CXD2841ER_EARLY_TUNE   16      /* bit 4 */
 #define CXD2841ER_NO_WAIT_LOCK 32      /* bit 5 */
+#define CXD2841ER_NO_AGCNEG    64      /* bit 6 */
 
 enum cxd2841er_xtal {
        SONY_XTAL_20500, /* 20.5 MHz */
--

2.10.2

Signature · 3 lines
Abylay Ospan,
NetUP Inc.
http://www.netup.tv
#27 lore raw

PATCH 14/19 dvb-frontends/cxd2841er: more configurable TSBITS

In reply to Daniel Scheller

From: Daniel Scheller <[email protected]>

Bits 3 and 4 of the TSCONFIG register are important for certain hardware constellations, in that they need to be zeroed. Add a configuration flag to toggle this.

---
 drivers/media/dvb-frontends/cxd2841er.c | 4 ++++
 drivers/media/dvb-frontends/cxd2841er.h | 1 +
 2 files changed, 5 insertions(+)
drivers/media/dvb-frontends/cxd2841er.c +4 -0
index 67bd13c..efb2795 100644
@@ -3794,6 +3794,10 @@ static int cxd2841er_init_tc(struct dvb_frontend *fe)
 	cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xc4,
 		((priv->flags & CXD2841ER_TS_SERIAL) ? 0x80 : 0x00), 0x80);
 
+	/* clear TSCFG bits 3+4 */
+	if (priv->flags & CXD2841ER_TSBITS)
+		cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xc4, 0x00, 0x18);
+
 	cxd2841er_init_stats(fe);
 
 	return 0;
drivers/media/dvb-frontends/cxd2841er.h +1 -0
index 4f94422..dc32f5fb 100644
@@ -31,6 +31,7 @@
 #define CXD2841ER_EARLY_TUNE	16	/* bit 4 */
 #define CXD2841ER_NO_WAIT_LOCK	32	/* bit 5 */
 #define CXD2841ER_NO_AGCNEG	64	/* bit 6 */
+#define CXD2841ER_TSBITS	128	/* bit 7 */
 
 enum cxd2841er_xtal {
 	SONY_XTAL_20500, /* 20.5 MHz */
Signature · 1 line
2.10.2
Acked-by on v1 14/19
#28 lore raw

Re: [PATCH 14/19] [media] dvb-frontends/cxd2841er: more configurable TSBITS

2017-04-09 15:38 GMT-04:00 Daniel Scheller <[email protected]>:

Quoted 42 lines

From: Daniel Scheller <[email protected]>

Bits 3 and 4 of the TSCONFIG register are important for certain hardware constellations, in that they need to be zeroed. Add a configuration flag to toggle this.

---
 drivers/media/dvb-frontends/cxd2841er.c | 4 ++++
 drivers/media/dvb-frontends/cxd2841er.h | 1 +
 2 files changed, 5 insertions(+)
drivers/media/dvb-frontends/cxd2841er.c +4 -0
index 67bd13c..efb2795 100644
@@ -3794,6 +3794,10 @@ static int cxd2841er_init_tc(struct dvb_frontend *fe)
        cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xc4,
                ((priv->flags & CXD2841ER_TS_SERIAL) ? 0x80 : 0x00), 0x80);
 
+       /* clear TSCFG bits 3+4 */
+       if (priv->flags & CXD2841ER_TSBITS)
+               cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xc4, 0x00, 0x18);
+
        cxd2841er_init_stats(fe);
 
        return 0;
drivers/media/dvb-frontends/cxd2841er.h +1 -1
index 4f94422..dc32f5fb 100644
@@ -31,6 +31,7 @@
 #define CXD2841ER_EARLY_TUNE   16      /* bit 4 */
 #define CXD2841ER_NO_WAIT_LOCK 32      /* bit 5 */
 #define CXD2841ER_NO_AGCNEG    64      /* bit 6 */
+#define CXD2841ER_TSBITS       128     /* bit 7 */
 
 enum cxd2841er_xtal {
        SONY_XTAL_20500, /* 20.5 MHz */
--

2.10.2

Signature · 3 lines
Abylay Ospan,
NetUP Inc.
http://www.netup.tv
#29 lore raw

PATCH 15/19 dvb-frontends/cxd2841er: improved snr reporting

In reply to Daniel Scheller

From: Daniel Scheller <[email protected]>

On DVB-T/T2 at least, SNR might be reported as >2500dB, which not only is just wrong but also ridiculous, so fix this by improving the conversion of the register value.

The INTLOG10X100 function/macro and the way the values are converted were both taken from DD's cxd2843 driver.

---
 drivers/media/dvb-frontends/cxd2841er.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)
drivers/media/dvb-frontends/cxd2841er.c +4 -3
index efb2795..a01ac58 100644
@@ -38,6 +38,8 @@
 #define MAX_WRITE_REGSIZE	16
 #define LOG2_E_100X 144
 
+#define INTLOG10X100(x) ((u32) (((u64) intlog10(x) * 100) >> 24))
+
 /* DVB-C constellation */
 enum sony_dvbc_constellation_t {
 	SONY_DVBC_CONSTELLATION_16QAM,
@@ -1817,7 +1819,7 @@ static int cxd2841er_read_snr_t(struct cxd2841er_priv *priv, u32 *snr)
 	}
 	if (reg > 4996)
 		reg = 4996;
-	*snr = 10000 * ((intlog10(reg) - intlog10(5350 - reg)) >> 24) + 28500;
+	*snr = 100 * ((INTLOG10X100(reg) - INTLOG10X100(5350 - reg)) + 285);
 	return 0;
 }
 
@@ -1846,8 +1848,7 @@ static int cxd2841er_read_snr_t2(struct cxd2841er_priv *priv, u32 *snr)
 	}
 	if (reg > 10876)
 		reg = 10876;
-	*snr = 10000 * ((intlog10(reg) -
-		intlog10(12600 - reg)) >> 24) + 32000;
+	*snr = 100 * ((INTLOG10X100(reg) - INTLOG10X100(12600 - reg)) + 320);
 	return 0;
 }
 
Signature · 1 line
2.10.2
Acked-by on v1 15/19
#30 lore raw

Re: [PATCH 15/19] [media] dvb-frontends/cxd2841er: improved snr reporting

2017-04-09 15:38 GMT-04:00 Daniel Scheller <[email protected]>:

Quoted 49 lines

From: Daniel Scheller <[email protected]>

On DVB-T/T2 at least, SNR might be reported as >2500dB, which not only is just wrong but also ridiculous, so fix this by improving the conversion of the register value.

The INTLOG10X100 function/macro and the way the values are converted were both taken from DD's cxd2843 driver.

---
 drivers/media/dvb-frontends/cxd2841er.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)
drivers/media/dvb-frontends/cxd2841er.c +4 -4
index efb2795..a01ac58 100644
@@ -38,6 +38,8 @@
 #define MAX_WRITE_REGSIZE      16
 #define LOG2_E_100X 144
 
+#define INTLOG10X100(x) ((u32) (((u64) intlog10(x) * 100) >> 24))
+
 /* DVB-C constellation */
 enum sony_dvbc_constellation_t {
        SONY_DVBC_CONSTELLATION_16QAM,
@@ -1817,7 +1819,7 @@ static int cxd2841er_read_snr_t(struct cxd2841er_priv *priv, u32 *snr)
        }
        if (reg > 4996)
                reg = 4996;
-       *snr = 10000 * ((intlog10(reg) - intlog10(5350 - reg)) >> 24) + 28500;
+       *snr = 100 * ((INTLOG10X100(reg) - INTLOG10X100(5350 - reg)) + 285);
        return 0;
 }
 
@@ -1846,8 +1848,7 @@ static int cxd2841er_read_snr_t2(struct cxd2841er_priv *priv, u32 *snr)
        }
        if (reg > 10876)
                reg = 10876;
-       *snr = 10000 * ((intlog10(reg) -
-               intlog10(12600 - reg)) >> 24) + 32000;
+       *snr = 100 * ((INTLOG10X100(reg) - INTLOG10X100(12600 - reg)) + 320);
        return 0;
 }
 
--

2.10.2

Signature · 3 lines
Abylay Ospan,
NetUP Inc.
http://www.netup.tv
#31 lore raw

PATCH 16/19 ddbridge: board control setup, ts quirk flags

In reply to Daniel Scheller

From: Daniel Scheller <[email protected]>

This is a backport of the board control setup from the vendor provided dddvb driver package, which does additional device initialisation based on the board_control device info values. Also backports the TS quirk flags which is used to control setup and usage of the tuner modules soldered on the bridge cards (e.g. CineCTv7, CineS2 V7, MaxA8 and the likes).

Functionality originates from ddbridge vendor driver. Permission for reuse and kernel inclusion was formally granted by Ralph Metzler <[email protected]>.

---
 drivers/media/pci/ddbridge/ddbridge-core.c | 13 +++++++++++++
 drivers/media/pci/ddbridge/ddbridge-regs.h |  4 ++++
 drivers/media/pci/ddbridge/ddbridge.h      | 10 ++++++++++
 3 files changed, 27 insertions(+)
drivers/media/pci/ddbridge/ddbridge-core.c +13 -0
index 12f5aa3..6b49fa9 100644
@@ -1763,6 +1763,19 @@ static int ddb_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 	ddbwritel(0xfff0f, INTERRUPT_ENABLE);
 	ddbwritel(0, MSI1_ENABLE);
 
+	/* board control */
+	if (dev->info->board_control) {
+		ddbwritel(0, DDB_LINK_TAG(0) | BOARD_CONTROL);
+		msleep(100);
+		ddbwritel(dev->info->board_control_2,
+			DDB_LINK_TAG(0) | BOARD_CONTROL);
+		usleep_range(2000, 3000);
+		ddbwritel(dev->info->board_control_2
+			| dev->info->board_control,
+			DDB_LINK_TAG(0) | BOARD_CONTROL);
+		usleep_range(2000, 3000);
+	}
+
 	if (ddb_i2c_init(dev) < 0)
 		goto fail1;
 	ddb_ports_init(dev);
drivers/media/pci/ddbridge/ddbridge-regs.h +4 -0
index 6ae8103..98cebb9 100644
@@ -34,6 +34,10 @@
 
 /* ------------------------------------------------------------------------- */
 
+#define BOARD_CONTROL    0x30
+
+/* ------------------------------------------------------------------------- */
+
 /* Interrupt controller                                     */
 /* How many MSI's are available depends on HW (Min 2 max 8) */
 /* How many are usable also depends on Host platform        */
drivers/media/pci/ddbridge/ddbridge.h +10 -0
index 0898f60..734e18e 100644
@@ -43,6 +43,10 @@
 #define DDB_MAX_PORT    4
 #define DDB_MAX_INPUT   8
 #define DDB_MAX_OUTPUT  4
+#define DDB_MAX_LINK    4
+#define DDB_LINK_SHIFT 28
+
+#define DDB_LINK_TAG(_x) (_x << DDB_LINK_SHIFT)
 
 struct ddb_info {
 	int   type;
@@ -51,6 +55,12 @@ struct ddb_info {
 	char *name;
 	int   port_num;
 	u32   port_type[DDB_MAX_PORT];
+	u32   board_control;
+	u32   board_control_2;
+	u8    ts_quirks;
+#define TS_QUIRK_SERIAL   1
+#define TS_QUIRK_REVERSED 2
+#define TS_QUIRK_ALT_OSC  8
 };
 
 /* DMA_SIZE MUST be divisible by 188 and 128 !!! */
Signature · 1 line
2.10.2
#32 lore raw

Re: [PATCH 16/19] [media] ddbridge: board control setup, ts quirk flags

not related to cxd2841er. I'm skipping this ...

2017-04-09 15:38 GMT-04:00 Daniel Scheller <[email protected]>:

Quoted 91 lines

From: Daniel Scheller <[email protected]>

This is a backport of the board control setup from the vendor provided dddvb driver package, which does additional device initialisation based on the board_control device info values. Also backports the TS quirk flags which is used to control setup and usage of the tuner modules soldered on the bridge cards (e.g. CineCTv7, CineS2 V7, MaxA8 and the likes).

Functionality originates from ddbridge vendor driver. Permission for reuse and kernel inclusion was formally granted by Ralph Metzler <[email protected]>.

---
 drivers/media/pci/ddbridge/ddbridge-core.c | 13 +++++++++++++
 drivers/media/pci/ddbridge/ddbridge-regs.h |  4 ++++
 drivers/media/pci/ddbridge/ddbridge.h      | 10 ++++++++++
 3 files changed, 27 insertions(+)
drivers/media/pci/ddbridge/ddbridge-core.c +13 -0
index 12f5aa3..6b49fa9 100644
@@ -1763,6 +1763,19 @@ static int ddb_probe(struct pci_dev *pdev, const struct pci_device_id *id)
        ddbwritel(0xfff0f, INTERRUPT_ENABLE);
        ddbwritel(0, MSI1_ENABLE);
 
+       /* board control */
+       if (dev->info->board_control) {
+               ddbwritel(0, DDB_LINK_TAG(0) | BOARD_CONTROL);
+               msleep(100);
+               ddbwritel(dev->info->board_control_2,
+                       DDB_LINK_TAG(0) | BOARD_CONTROL);
+               usleep_range(2000, 3000);
+               ddbwritel(dev->info->board_control_2
+                       | dev->info->board_control,
+                       DDB_LINK_TAG(0) | BOARD_CONTROL);
+               usleep_range(2000, 3000);
+       }
+
        if (ddb_i2c_init(dev) < 0)
                goto fail1;
        ddb_ports_init(dev);
drivers/media/pci/ddbridge/ddbridge-regs.h +4 -0
index 6ae8103..98cebb9 100644
@@ -34,6 +34,10 @@
 
 /* ------------------------------------------------------------------------- */
 
+#define BOARD_CONTROL    0x30
+
+/* ------------------------------------------------------------------------- */
+
 /* Interrupt controller                                     */
 /* How many MSI's are available depends on HW (Min 2 max 8) */
 /* How many are usable also depends on Host platform        */
drivers/media/pci/ddbridge/ddbridge.h +10 -1
index 0898f60..734e18e 100644
@@ -43,6 +43,10 @@
 #define DDB_MAX_PORT    4
 #define DDB_MAX_INPUT   8
 #define DDB_MAX_OUTPUT  4
+#define DDB_MAX_LINK    4
+#define DDB_LINK_SHIFT 28
+
+#define DDB_LINK_TAG(_x) (_x << DDB_LINK_SHIFT)
 
 struct ddb_info {
        int   type;
@@ -51,6 +55,12 @@ struct ddb_info {
        char *name;
        int   port_num;
        u32   port_type[DDB_MAX_PORT];
+       u32   board_control;
+       u32   board_control_2;
+       u8    ts_quirks;
+#define TS_QUIRK_SERIAL   1
+#define TS_QUIRK_REVERSED 2
+#define TS_QUIRK_ALT_OSC  8
 };
 
 /* DMA_SIZE MUST be divisible by 188 and 128 !!! */
--

2.10.2

Signature · 3 lines
Abylay Ospan,
NetUP Inc.
http://www.netup.tv
#33 lore raw

PATCH 17/19 ddbridge: add I2C functions, add XO2 module support

In reply to Daniel Scheller

From: Daniel Scheller <[email protected]>

Some Flex modules (mostly with anyof C/C2/T/T2 demods based on the Sony CXD28xxER series) are equipped with an interface named XO2 (which appears to be the Lattice MachXO2). Add functionality to detect such links and initialise them, so any tuner module with such an interface can be used.

This also adds dummy detection for any possible connected module, telling the user it isn't supported at this very moment.

Also adds i2c_io(), i2c_write() and i2c_write_reg(), all required for the XO2 handling functionality.

---
 drivers/media/pci/ddbridge/ddbridge-core.c | 147 +++++++++++++++++++++++++++++
 drivers/media/pci/ddbridge/ddbridge.h      |  11 +++
 2 files changed, 158 insertions(+)
drivers/media/pci/ddbridge/ddbridge-core.c +147 -0
index 6b49fa9..ab88fcf 100644
@@ -43,6 +43,10 @@
 #include "stv0367_priv.h"
 #include "tda18212.h"
 
+static int xo2_speed = 2;
+module_param(xo2_speed, int, 0444);
+MODULE_PARM_DESC(xo2_speed, "default transfer speed for xo2 based duoflex, 0=55,1=75,2=90,3=104 MBit/s, default=2, use attribute to change for individual cards");
+
 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
 
 /* MSI had problems with lost interrupts, fixed but needs testing */
@@ -50,6 +54,24 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
 
 /******************************************************************************/
 
+static int i2c_io(struct i2c_adapter *adapter, u8 adr,
+		  u8 *wbuf, u32 wlen, u8 *rbuf, u32 rlen)
+{
+	struct i2c_msg msgs[2] = {{.addr = adr,  .flags = 0,
+				   .buf  = wbuf, .len   = wlen },
+				  {.addr = adr,  .flags = I2C_M_RD,
+				   .buf  = rbuf,  .len   = rlen } };
+	return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1;
+}
+
+static int i2c_write(struct i2c_adapter *adap, u8 adr, u8 *data, int len)
+{
+	struct i2c_msg msg = {.addr = adr, .flags = 0,
+			      .buf = data, .len = len};
+
+	return (i2c_transfer(adap, &msg, 1) == 1) ? 0 : -1;
+}
+
 static int i2c_read(struct i2c_adapter *adapter, u8 adr, u8 *val)
 {
 	struct i2c_msg msgs[1] = {{.addr = adr,  .flags = I2C_M_RD,
@@ -83,6 +105,14 @@ static int i2c_read_reg16(struct i2c_adapter *adapter, u8 adr,
 	return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1;
 }
 
+static int i2c_write_reg(struct i2c_adapter *adap, u8 adr,
+			 u8 reg, u8 val)
+{
+	u8 msg[2] = {reg, val};
+
+	return i2c_write(adap, adr, msg, 2);
+}
+
 static int ddb_i2c_cmd(struct ddb_i2c *i2c, u32 adr, u32 cmd)
 {
 	struct ddb *dev = i2c->dev;
@@ -1272,6 +1302,70 @@ static void ddb_ports_detach(struct ddb *dev)
 /****************************************************************************/
 /****************************************************************************/
 
+static int init_xo2(struct ddb_port *port)
+{
+	struct i2c_adapter *i2c = &port->i2c->adap;
+	u8 val, data[2];
+	int res;
+
+	res = i2c_read_regs(i2c, 0x10, 0x04, data, 2);
+	if (res < 0)
+		return res;
+
+	if (data[0] != 0x01)  {
+		pr_info("Port %d: invalid XO2\n", port->nr);
+		return -1;
+	}
+
+	i2c_read_reg(i2c, 0x10, 0x08, &val);
+	if (val != 0) {
+		i2c_write_reg(i2c, 0x10, 0x08, 0x00);
+		msleep(100);
+	}
+	/* Enable tuner power, disable pll, reset demods */
+	i2c_write_reg(i2c, 0x10, 0x08, 0x04);
+	usleep_range(2000, 3000);
+	/* Release demod resets */
+	i2c_write_reg(i2c, 0x10, 0x08, 0x07);
+
+	/* speed: 0=55,1=75,2=90,3=104 MBit/s */
+	i2c_write_reg(i2c, 0x10, 0x09,
+		((xo2_speed >= 0 && xo2_speed <= 3) ? xo2_speed : 2));
+
+	i2c_write_reg(i2c, 0x10, 0x0a, 0x01);
+	i2c_write_reg(i2c, 0x10, 0x0b, 0x01);
+
+	usleep_range(2000, 3000);
+	/* Start XO2 PLL */
+	i2c_write_reg(i2c, 0x10, 0x08, 0x87);
+
+	return 0;
+}
+
+static int port_has_xo2(struct ddb_port *port, u8 *type, u8 *id)
+{
+	u8 probe[1] = { 0x00 }, data[4];
+
+	*type = DDB_XO2_TYPE_NONE;
+
+	if (i2c_io(&port->i2c->adap, 0x10, probe, 1, data, 4))
+		return 0;
+	if (data[0] == 'D' && data[1] == 'F') {
+		*id = data[2];
+		*type = DDB_XO2_TYPE_DUOFLEX;
+		return 1;
+	}
+	if (data[0] == 'C' && data[1] == 'I') {
+		*id = data[2];
+		*type = DDB_XO2_TYPE_CI;
+		return 1;
+	}
+	return 0;
+}
+
+/****************************************************************************/
+/****************************************************************************/
+
 static int port_has_ci(struct ddb_port *port)
 {
 	u8 val;
@@ -1322,6 +1416,7 @@ static void ddb_port_probe(struct ddb_port *port)
 {
 	struct ddb *dev = port->dev;
 	char *modname = "NO MODULE";
+	u8 xo2_type, xo2_id;
 
 	port->class = DDB_PORT_NONE;
 
@@ -1329,6 +1424,58 @@ static void ddb_port_probe(struct ddb_port *port)
 		modname = "CI";
 		port->class = DDB_PORT_CI;
 		ddbwritel(I2C_SPEED_400, port->i2c->regs + I2C_TIMING);
+	} else if (port_has_xo2(port, &xo2_type, &xo2_id)) {
+		printk(KERN_INFO "Port %d (TAB %d): XO2 type: %d, id: %d\n",
+			port->nr, port->nr+1, xo2_type, xo2_id);
+
+		ddbwritel(I2C_SPEED_400, port->i2c->regs + I2C_TIMING);
+
+		switch (xo2_type) {
+		case DDB_XO2_TYPE_DUOFLEX:
+			init_xo2(port);
+			switch (xo2_id >> 2) {
+			case 0:
+				modname = "DUAL DVB-S2 (unsupported)";
+				port->class = DDB_PORT_NONE;
+				port->type = DDB_TUNER_XO2_DVBS_STV0910;
+				break;
+			case 1:
+				modname = "DUAL DVB-C/T/T2 (unsupported)";
+				port->class = DDB_PORT_NONE;
+				port->type = DDB_TUNER_XO2_DVBCT2_SONY;
+				break;
+			case 2:
+				modname = "DUAL DVB-ISDBT (unsupported)";
+				port->class = DDB_PORT_NONE;
+				port->type = DDB_TUNER_XO2_ISDBT_SONY;
+				break;
+			case 3:
+				modname = "DUAL DVB-C/C2/T/T2 (unsupported)";
+				port->class = DDB_PORT_NONE;
+				port->type = DDB_TUNER_XO2_DVBC2T2_SONY;
+				break;
+			case 4:
+				modname = "DUAL ATSC (unsupported)";
+				port->class = DDB_PORT_NONE;
+				port->type = DDB_TUNER_XO2_ATSC_ST;
+				break;
+			case 5:
+				modname = "DUAL DVB-C/C2/T/T2/ISDBT (unsupported)";
+				port->class = DDB_PORT_NONE;
+				port->type = DDB_TUNER_XO2_DVBC2T2I_SONY;
+				break;
+			default:
+				modname = "Unknown XO2 DuoFlex module\n";
+				break;
+			}
+			break;
+		case DDB_XO2_TYPE_CI:
+			printk(KERN_INFO "DuoFlex CI modules not supported\n");
+			break;
+		default:
+			printk(KERN_INFO "Unknown XO2 DuoFlex module\n");
+			break;
+		}
 	} else if (port_has_stv0900(port)) {
 		modname = "DUAL DVB-S2";
 		port->class = DDB_PORT_TUNER;
drivers/media/pci/ddbridge/ddbridge.h +11 -0
index 734e18e..4e49faa 100644
@@ -48,6 +48,10 @@
 
 #define DDB_LINK_TAG(_x) (_x << DDB_LINK_SHIFT)
 
+#define DDB_XO2_TYPE_NONE	0
+#define DDB_XO2_TYPE_DUOFLEX	1
+#define DDB_XO2_TYPE_CI		2
+
 struct ddb_info {
 	int   type;
 #define DDB_NONE         0
@@ -154,6 +158,13 @@ struct ddb_port {
 #define DDB_TUNER_DVBS_ST_AA    2
 #define DDB_TUNER_DVBCT_TR     16
 #define DDB_TUNER_DVBCT_ST     17
+#define DDB_TUNER_XO2_DVBS_STV0910	32
+#define DDB_TUNER_XO2_DVBCT2_SONY	33
+#define DDB_TUNER_XO2_ISDBT_SONY	34
+#define DDB_TUNER_XO2_DVBC2T2_SONY	35
+#define DDB_TUNER_XO2_ATSC_ST		36
+#define DDB_TUNER_XO2_DVBC2T2I_SONY	37
+
 	u32                    adr;
 
 	struct ddb_input      *input[2];
Signature · 1 line
2.10.2
#34 lore raw

Re: [PATCH 17/19] [media] ddbridge: add I2C functions, add XO2 module support

not related to cxd2841er. I'm skipping this ...
same for rest of the patches (18/19, 19/19).

2017-04-09 15:38 GMT-04:00 Daniel Scheller <[email protected]>:

Quoted 245 lines

From: Daniel Scheller <[email protected]>

Some Flex modules (mostly with anyof C/C2/T/T2 demods based on the Sony CXD28xxER series) are equipped with an interface named XO2 (which appears to be the Lattice MachXO2). Add functionality to detect such links and initialise them, so any tuner module with such an interface can be used.

This also adds dummy detection for any possible connected module, telling the user it isn't supported at this very moment.

Also adds i2c_io(), i2c_write() and i2c_write_reg(), all required for the XO2 handling functionality.

---
 drivers/media/pci/ddbridge/ddbridge-core.c | 147 +++++++++++++++++++++++++++++
 drivers/media/pci/ddbridge/ddbridge.h      |  11 +++
 2 files changed, 158 insertions(+)
drivers/media/pci/ddbridge/ddbridge-core.c +147 -0
index 6b49fa9..ab88fcf 100644
@@ -43,6 +43,10 @@
 #include "stv0367_priv.h"
 #include "tda18212.h"
 
+static int xo2_speed = 2;
+module_param(xo2_speed, int, 0444);
+MODULE_PARM_DESC(xo2_speed, "default transfer speed for xo2 based duoflex, 0=55,1=75,2=90,3=104 MBit/s, default=2, use attribute to change for individual cards");
+
 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
 
 /* MSI had problems with lost interrupts, fixed but needs testing */
@@ -50,6 +54,24 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
 
 /******************************************************************************/
 
+static int i2c_io(struct i2c_adapter *adapter, u8 adr,
+                 u8 *wbuf, u32 wlen, u8 *rbuf, u32 rlen)
+{
+       struct i2c_msg msgs[2] = {{.addr = adr,  .flags = 0,
+                                  .buf  = wbuf, .len   = wlen },
+                                 {.addr = adr,  .flags = I2C_M_RD,
+                                  .buf  = rbuf,  .len   = rlen } };
+       return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1;
+}
+
+static int i2c_write(struct i2c_adapter *adap, u8 adr, u8 *data, int len)
+{
+       struct i2c_msg msg = {.addr = adr, .flags = 0,
+                             .buf = data, .len = len};
+
+       return (i2c_transfer(adap, &msg, 1) == 1) ? 0 : -1;
+}
+
 static int i2c_read(struct i2c_adapter *adapter, u8 adr, u8 *val)
 {
        struct i2c_msg msgs[1] = {{.addr = adr,  .flags = I2C_M_RD,
@@ -83,6 +105,14 @@ static int i2c_read_reg16(struct i2c_adapter *adapter, u8 adr,
        return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1;
 }
 
+static int i2c_write_reg(struct i2c_adapter *adap, u8 adr,
+                        u8 reg, u8 val)
+{
+       u8 msg[2] = {reg, val};
+
+       return i2c_write(adap, adr, msg, 2);
+}
+
 static int ddb_i2c_cmd(struct ddb_i2c *i2c, u32 adr, u32 cmd)
 {
        struct ddb *dev = i2c->dev;
@@ -1272,6 +1302,70 @@ static void ddb_ports_detach(struct ddb *dev)
 /****************************************************************************/
 /****************************************************************************/
 
+static int init_xo2(struct ddb_port *port)
+{
+       struct i2c_adapter *i2c = &port->i2c->adap;
+       u8 val, data[2];
+       int res;
+
+       res = i2c_read_regs(i2c, 0x10, 0x04, data, 2);
+       if (res < 0)
+               return res;
+
+       if (data[0] != 0x01)  {
+               pr_info("Port %d: invalid XO2\n", port->nr);
+               return -1;
+       }
+
+       i2c_read_reg(i2c, 0x10, 0x08, &val);
+       if (val != 0) {
+               i2c_write_reg(i2c, 0x10, 0x08, 0x00);
+               msleep(100);
+       }
+       /* Enable tuner power, disable pll, reset demods */
+       i2c_write_reg(i2c, 0x10, 0x08, 0x04);
+       usleep_range(2000, 3000);
+       /* Release demod resets */
+       i2c_write_reg(i2c, 0x10, 0x08, 0x07);
+
+       /* speed: 0=55,1=75,2=90,3=104 MBit/s */
+       i2c_write_reg(i2c, 0x10, 0x09,
+               ((xo2_speed >= 0 && xo2_speed <= 3) ? xo2_speed : 2));
+
+       i2c_write_reg(i2c, 0x10, 0x0a, 0x01);
+       i2c_write_reg(i2c, 0x10, 0x0b, 0x01);
+
+       usleep_range(2000, 3000);
+       /* Start XO2 PLL */
+       i2c_write_reg(i2c, 0x10, 0x08, 0x87);
+
+       return 0;
+}
+
+static int port_has_xo2(struct ddb_port *port, u8 *type, u8 *id)
+{
+       u8 probe[1] = { 0x00 }, data[4];
+
+       *type = DDB_XO2_TYPE_NONE;
+
+       if (i2c_io(&port->i2c->adap, 0x10, probe, 1, data, 4))
+               return 0;
+       if (data[0] == 'D' && data[1] == 'F') {
+               *id = data[2];
+               *type = DDB_XO2_TYPE_DUOFLEX;
+               return 1;
+       }
+       if (data[0] == 'C' && data[1] == 'I') {
+               *id = data[2];
+               *type = DDB_XO2_TYPE_CI;
+               return 1;
+       }
+       return 0;
+}
+
+/****************************************************************************/
+/****************************************************************************/
+
 static int port_has_ci(struct ddb_port *port)
 {
        u8 val;
@@ -1322,6 +1416,7 @@ static void ddb_port_probe(struct ddb_port *port)
 {
        struct ddb *dev = port->dev;
        char *modname = "NO MODULE";
+       u8 xo2_type, xo2_id;
 
        port->class = DDB_PORT_NONE;
 
@@ -1329,6 +1424,58 @@ static void ddb_port_probe(struct ddb_port *port)
                modname = "CI";
                port->class = DDB_PORT_CI;
                ddbwritel(I2C_SPEED_400, port->i2c->regs + I2C_TIMING);
+       } else if (port_has_xo2(port, &xo2_type, &xo2_id)) {
+               printk(KERN_INFO "Port %d (TAB %d): XO2 type: %d, id: %d\n",
+                       port->nr, port->nr+1, xo2_type, xo2_id);
+
+               ddbwritel(I2C_SPEED_400, port->i2c->regs + I2C_TIMING);
+
+               switch (xo2_type) {
+               case DDB_XO2_TYPE_DUOFLEX:
+                       init_xo2(port);
+                       switch (xo2_id >> 2) {
+                       case 0:
+                               modname = "DUAL DVB-S2 (unsupported)";
+                               port->class = DDB_PORT_NONE;
+                               port->type = DDB_TUNER_XO2_DVBS_STV0910;
+                               break;
+                       case 1:
+                               modname = "DUAL DVB-C/T/T2 (unsupported)";
+                               port->class = DDB_PORT_NONE;
+                               port->type = DDB_TUNER_XO2_DVBCT2_SONY;
+                               break;
+                       case 2:
+                               modname = "DUAL DVB-ISDBT (unsupported)";
+                               port->class = DDB_PORT_NONE;
+                               port->type = DDB_TUNER_XO2_ISDBT_SONY;
+                               break;
+                       case 3:
+                               modname = "DUAL DVB-C/C2/T/T2 (unsupported)";
+                               port->class = DDB_PORT_NONE;
+                               port->type = DDB_TUNER_XO2_DVBC2T2_SONY;
+                               break;
+                       case 4:
+                               modname = "DUAL ATSC (unsupported)";
+                               port->class = DDB_PORT_NONE;
+                               port->type = DDB_TUNER_XO2_ATSC_ST;
+                               break;
+                       case 5:
+                               modname = "DUAL DVB-C/C2/T/T2/ISDBT (unsupported)";
+                               port->class = DDB_PORT_NONE;
+                               port->type = DDB_TUNER_XO2_DVBC2T2I_SONY;
+                               break;
+                       default:
+                               modname = "Unknown XO2 DuoFlex module\n";
+                               break;
+                       }
+                       break;
+               case DDB_XO2_TYPE_CI:
+                       printk(KERN_INFO "DuoFlex CI modules not supported\n");
+                       break;
+               default:
+                       printk(KERN_INFO "Unknown XO2 DuoFlex module\n");
+                       break;
+               }
        } else if (port_has_stv0900(port)) {
                modname = "DUAL DVB-S2";
                port->class = DDB_PORT_TUNER;
drivers/media/pci/ddbridge/ddbridge.h +11 -1
index 734e18e..4e49faa 100644
@@ -48,6 +48,10 @@
 
 #define DDB_LINK_TAG(_x) (_x << DDB_LINK_SHIFT)
 
+#define DDB_XO2_TYPE_NONE      0
+#define DDB_XO2_TYPE_DUOFLEX   1
+#define DDB_XO2_TYPE_CI                2
+
 struct ddb_info {
        int   type;
 #define DDB_NONE         0
@@ -154,6 +158,13 @@ struct ddb_port {
 #define DDB_TUNER_DVBS_ST_AA    2
 #define DDB_TUNER_DVBCT_TR     16
 #define DDB_TUNER_DVBCT_ST     17
+#define DDB_TUNER_XO2_DVBS_STV0910     32
+#define DDB_TUNER_XO2_DVBCT2_SONY      33
+#define DDB_TUNER_XO2_ISDBT_SONY       34
+#define DDB_TUNER_XO2_DVBC2T2_SONY     35
+#define DDB_TUNER_XO2_ATSC_ST          36
+#define DDB_TUNER_XO2_DVBC2T2I_SONY    37
+
        u32                    adr;
 
        struct ddb_input      *input[2];
--

2.10.2

Signature · 3 lines
Abylay Ospan,
NetUP Inc.
http://www.netup.tv
#35 lore raw

PATCH 18/19 ddbridge: support for Sony CXD28xx C/C2/T/T2 tuner modules

In reply to Daniel Scheller

From: Daniel Scheller <[email protected]>

Properly detect and attach Ports and Flex modules with the Sony CXD28xxER series demods. This makes newer Cine cards and most DuoFlex C/C2/T/T2 (or any combination of these systems) work, PCI IDs need to be added though.

Note: This utilises the CXD2841ER demod driver, which requires the changes from this patch series to properly work. Without those changes, it won't function properly (if at all).

---
 drivers/media/pci/ddbridge/Kconfig         |   2 +
 drivers/media/pci/ddbridge/ddbridge-core.c | 130 +++++++++++++++++++++++++++--
 drivers/media/pci/ddbridge/ddbridge.h      |  14 ++--
 3 files changed, 132 insertions(+), 14 deletions(-)
drivers/media/pci/ddbridge/Kconfig +2 -0
index 16ede23..ac6a48d7 100644
@@ -7,6 +7,7 @@ config DVB_DDBRIDGE
 	select DVB_DRXK if MEDIA_SUBDRV_AUTOSELECT
 	select DVB_TDA18271C2DD if MEDIA_SUBDRV_AUTOSELECT
 	select DVB_STV0367 if MEDIA_SUBDRV_AUTOSELECT
+	select DVB_CXD2841ER if MEDIA_SUBDRV_AUTOSELECT
 	select MEDIA_TUNER_TDA18212 if MEDIA_SUBDRV_AUTOSELECT
 	---help---
 	  Support for cards with the Digital Devices PCI express bridge:
@@ -17,5 +18,6 @@ config DVB_DDBRIDGE
 	  - DuoFlex CT Octopus
 	  - cineS2(v6)
 	  - CineCTv6 and DuoFlex CT (STV0367-based)
+	  - DuoFlex CT2/C2T2/C2T2I (Sony CXD28xx-based)
 
 	  Say Y if you own such a card and want to use it.
drivers/media/pci/ddbridge/ddbridge-core.c +121 -9

188 lines not on this page · raw message

drivers/media/pci/ddbridge/ddbridge.h +9 -5
index 4e49faa..58baddb 100644
@@ -153,11 +153,15 @@ struct ddb_port {
 #define DDB_PORT_CI             1
 #define DDB_PORT_TUNER          2
 	u32                    type;
-#define DDB_TUNER_NONE          0
-#define DDB_TUNER_DVBS_ST       1
-#define DDB_TUNER_DVBS_ST_AA    2
-#define DDB_TUNER_DVBCT_TR     16
-#define DDB_TUNER_DVBCT_ST     17
+#define DDB_TUNER_NONE			0
+#define DDB_TUNER_DVBS_ST		1
+#define DDB_TUNER_DVBS_ST_AA		2
+#define DDB_TUNER_DVBCT2_SONY_P		7
+#define DDB_TUNER_DVBC2T2_SONY_P	8
+#define DDB_TUNER_ISDBT_SONY_P		9
+#define DDB_TUNER_DVBC2T2I_SONY_P	15
+#define DDB_TUNER_DVBCT_TR		16
+#define DDB_TUNER_DVBCT_ST		17
 #define DDB_TUNER_XO2_DVBS_STV0910	32
 #define DDB_TUNER_XO2_DVBCT2_SONY	33
 #define DDB_TUNER_XO2_ISDBT_SONY	34
Signature · 1 line
2.10.2
#36 lore raw

PATCH 19/19 ddbridge: hardware IDs for new C2T2 cards and other devices

In reply to Daniel Scheller

From: Daniel Scheller <[email protected]>

Adds hardware IDs for all Sony CXD-based Cine-cards and MaxA8 devices, also adds some other yet missing IDs like the Octopus V3, Octopus OEM and Octopus Mini, as well as cards with unknown/deleted sub-ids.

---
 drivers/media/pci/ddbridge/Kconfig         |  3 +-
 drivers/media/pci/ddbridge/ddbridge-core.c | 84 +++++++++++++++++++++++++++++-
 drivers/media/pci/ddbridge/ddbridge.h      |  5 +-
 3 files changed, 88 insertions(+), 4 deletions(-)
drivers/media/pci/ddbridge/Kconfig +2 -1
index ac6a48d7..ffed78c 100644
@@ -18,6 +18,7 @@ config DVB_DDBRIDGE
 	  - DuoFlex CT Octopus
 	  - cineS2(v6)
 	  - CineCTv6 and DuoFlex CT (STV0367-based)
-	  - DuoFlex CT2/C2T2/C2T2I (Sony CXD28xx-based)
+	  - CineCTv7 and DuoFlex CT2/C2T2/C2T2I (Sony CXD28xx-based)
+	  - MaxA8 series
 
 	  Say Y if you own such a card and want to use it.
drivers/media/pci/ddbridge/ddbridge-core.c +83 -1

116 lines not on this page · raw message

drivers/media/pci/ddbridge/ddbridge.h +3 -2
index 58baddb..4a0e328 100644
@@ -54,8 +54,9 @@
 
 struct ddb_info {
 	int   type;
-#define DDB_NONE         0
-#define DDB_OCTOPUS      1
+#define DDB_NONE		0
+#define DDB_OCTOPUS		1
+#define DDB_OCTOPUS_MAX_CT	6
 	char *name;
 	int   port_num;
 	u32   port_type[DDB_MAX_PORT];
Signature · 1 line
2.10.2
#37 lore raw
In reply to Daniel Scheller

Am Sun, 9 Apr 2017 21:38:09 +0200
schrieb Daniel Scheller <[email protected]>:

Quoted 15 lines

Important note: This series depends on the stv0367/ddbridge series posted earlier (patches 12 [1] and 13 [2], depending on the I2C functions and the TDA18212 attach function).

This series improves the cxd2841er demodulator driver and adds some bits to make it more versatile to be used in more scenarios. Also, the ddbridge code is updated to recognize all hardware (PCIe cards/bridges and DuoFlex modules) with Sony CXD28xx tuners, including the newly introduced MaxA8 eight-tuner C2T2 cards.

The series has been tested (together with the STV0367 series) on a wide variety of cards, including CineCTv7, DuoFlex C(2)T2 modules and MaxA8 cards without any issues. Testing was done with TVHeadend, VDR and MythTV.

Quoted 5 lines

Note that the i2c_gate_ctrl() flag is needed in this series aswell since the i2c_gate_ctrl function needs to be remapped and mutex_lock protected for the same reasons as in the STV0367 series.

Besides printk() warnings, checkpatch.pl doesn't complain.

Ping on this series aswell.

Abylay, would you please mind taking a look at the cxd2841er changes and check if you're fine with them?

Regards,
Daniel

A message that is not in the archive (sent off-list or not yet received): CAK3bHNW9sM0fZFqYEX-mEhv-Rax82u25KdgjQftGcoY6wV1O0A@mail.gmail.com

#39 lore raw

Hi Daniel,

I have ack'ed all patches related to cxd2841er. Please check am i missing something ?

I see some good flags (CXD2841ER_NO_WAIT_LOCK and CXD2841ER_EARLY_TUNE). I should check it for our boards too :)

2017-05-30 10:31 GMT-04:00 Abylay Ospan <[email protected]>:

Quoted 54 lines

Hi Daniel,

I have checked your patches. Basically it looks good:
* compilation is clean (no warnings)
* Our card (NetUP Universal DVB Rev 1.4) works fine with this patches
* All patches looks reasonable and don't break other cards
* All patches has good comments

I will send ack's to ML.

Thanks for your work !

2017-05-28 17:47 GMT-04:00 Daniel Scheller <[email protected]>:

Quoted 26 lines

Am Sun, 9 Apr 2017 21:38:09 +0200
schrieb Daniel Scheller <[email protected]>:

Quoted 15 lines

Important note: This series depends on the stv0367/ddbridge series posted earlier (patches 12 [1] and 13 [2], depending on the I2C functions and the TDA18212 attach function).

This series improves the cxd2841er demodulator driver and adds some bits to make it more versatile to be used in more scenarios. Also, the ddbridge code is updated to recognize all hardware (PCIe cards/bridges and DuoFlex modules) with Sony CXD28xx tuners, including the newly introduced MaxA8 eight-tuner C2T2 cards.

The series has been tested (together with the STV0367 series) on a wide variety of cards, including CineCTv7, DuoFlex C(2)T2 modules and MaxA8 cards without any issues. Testing was done with TVHeadend, VDR and MythTV.

Quoted 5 lines

Note that the i2c_gate_ctrl() flag is needed in this series aswell since the i2c_gate_ctrl function needs to be remapped and mutex_lock protected for the same reasons as in the STV0367 series.

Besides printk() warnings, checkpatch.pl doesn't complain.

Quoted 7 lines

Ping on this series aswell.

Abylay, would you please mind taking a look at the cxd2841er changes and check if you're fine with them?

Regards,
Daniel

--
Abylay Ospan,
NetUP Inc.
http://www.netup.tv

Signature · 3 lines
Abylay Ospan,
NetUP Inc.
http://www.netup.tv
#40 lore raw

Am Wed, 31 May 2017 08:30:34 -0400
schrieb Abylay Ospan <[email protected]>:

Hi Abylay,

Quoted 2 lines

I have ack'ed all patches related to cxd2841er. Please check am i missing something ?

Thank you very much for your review and your ACKs, and in general taking time to look into them! You didn't miss any of the patches :) Will add your ACKs to the cxd2841er patches in a very likely upcoming V2 of the series.

Quoted 2 lines

I see some good flags (CXD2841ER_NO_WAIT_LOCK and CXD2841ER_EARLY_TUNE). I should check it for our boards too :)

Re EARLY_TUNE - I wasn't sure if the order of tuner/demod setup is of importance on your devices. When picking the IF freq from the tuner though, we first need to tune and then set up the demod since the demod queries the tuner about this. If your hardware also works with the "earlier tune", maybe we should drop this flag/condition and just move the tune call up.

Re NO_WAIT_LOCK - works fine with or without this. However, when e.g. using TVH and looking at the stats, the Web UI will freeze if a retune occurs. Again, not sure if it's absolutely required on your hardware/software - if not, I suggest to remove the flag together with the wait lock entirely.

Looking forward for your results and opinions! :-)

Best regards,
Daniel Scheller

#41 lore raw

Hi Daniel,

ok, perfect !
Will check this flags later when I switch back to driver :) Current situation with configurable flags is ok.

2017-05-31 16:32 GMT-04:00 Daniel Scheller <[email protected]>:

Quoted 33 lines

Am Wed, 31 May 2017 08:30:34 -0400
schrieb Abylay Ospan <[email protected]>:

Hi Abylay,

Quoted 2 lines

I have ack'ed all patches related to cxd2841er. Please check am i missing something ?

Thank you very much for your review and your ACKs, and in general taking time to look into them! You didn't miss any of the patches :) Will add your ACKs to the cxd2841er patches in a very likely upcoming V2 of the series.

Quoted 2 lines

I see some good flags (CXD2841ER_NO_WAIT_LOCK and CXD2841ER_EARLY_TUNE). I should check it for our boards too :)

Re EARLY_TUNE - I wasn't sure if the order of tuner/demod setup is of importance on your devices. When picking the IF freq from the tuner though, we first need to tune and then set up the demod since the demod queries the tuner about this. If your hardware also works with the "earlier tune", maybe we should drop this flag/condition and just move the tune call up.

Re NO_WAIT_LOCK - works fine with or without this. However, when e.g. using TVH and looking at the stats, the Web UI will freeze if a retune occurs. Again, not sure if it's absolutely required on your hardware/software - if not, I suggest to remove the flag together with the wait lock entirely.

Looking forward for your results and opinions! :-)

Best regards,
Daniel Scheller

Signature · 3 lines
Abylay Ospan,
NetUP Inc.
http://www.netup.tv