linux-media.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/5] cx23855: add support for DVBSky T980C (no CI support)
@ 2014-09-29  7:44 Olli Salonen
  2014-09-29  7:44 ` [PATCH 2/5] sp2: fix incorrect struct Olli Salonen
                   ` (5 more replies)
  0 siblings, 6 replies; 12+ messages in thread
From: Olli Salonen @ 2014-09-29  7:44 UTC (permalink / raw)
  To: linux-media; +Cc: Olli Salonen

This patch adds basic support for DVBSky T980C card. CI interface is not supported.

DVBSky T980C is a PCIe card with the following components:
- CX23885 PCIe bridge
- Si2168-A20 demodulator
- Si2158-A20 tuner
- CIMaX SP2 CI chip

The demodulator and tuner need firmware. They're the same as used with TT CT2-4650 CI:
https://www.mail-archive.com/linux-media@vger.kernel.org/msg78033.html

Signed-off-by: Olli Salonen <olli.salonen@iki.fi>
---
 drivers/media/pci/cx23885/cx23885-cards.c | 40 ++++++++++++++++++++
 drivers/media/pci/cx23885/cx23885-dvb.c   | 61 +++++++++++++++++++++++++++++++
 drivers/media/pci/cx23885/cx23885.h       |  1 +
 3 files changed, 102 insertions(+)

diff --git a/drivers/media/pci/cx23885/cx23885-cards.c b/drivers/media/pci/cx23885/cx23885-cards.c
index 88c257d..e8965e6 100644
--- a/drivers/media/pci/cx23885/cx23885-cards.c
+++ b/drivers/media/pci/cx23885/cx23885-cards.c
@@ -680,6 +680,10 @@ struct cx23885_board cx23885_boards[] = {
 		.portb		= CX23885_MPEG_DVB,
 		.portc		= CX23885_MPEG_DVB,
 	},
+	[CX23885_BOARD_DVBSKY_T980C] = {
+		.name		= "DVBSky T980C",
+		.portb		= CX23885_MPEG_DVB,
+	},
 };
 const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards);
 
@@ -939,6 +943,10 @@ struct cx23885_subid cx23885_subids[] = {
 		.subvendor = 0x4254,
 		.subdevice = 0x9580,
 		.card      = CX23885_BOARD_DVBSKY_T9580,
+	}, {
+		.subvendor = 0x4254,
+		.subdevice = 0x980c,
+		.card      = CX23885_BOARD_DVBSKY_T980C,
 	},
 };
 const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids);
@@ -1541,6 +1549,36 @@ void cx23885_gpio_setup(struct cx23885_dev *dev)
 		mdelay(100);
 		cx23885_gpio_set(dev, GPIO_2 | GPIO_11);
 		break;
+	case CX23885_BOARD_DVBSKY_T980C:
+		/*
+		 * GPIO-0 INTA from CiMax, input
+		 * GPIO-1 reset CiMax, output, high active
+		 * GPIO-2 reset demod, output, low active
+		 * GPIO-3 to GPIO-10 data/addr for CAM
+		 * GPIO-11 ~CS0 to CiMax1
+		 * GPIO-12 ~CS1 to CiMax2
+		 * GPIO-13 ADL0 load LSB addr
+		 * GPIO-14 ADL1 load MSB addr
+		 * GPIO-15 ~RDY from CiMax
+		 * GPIO-17 ~RD to CiMax
+		 * GPIO-18 ~WR to CiMax
+		 */
+
+		cx_set(GP0_IO, 0x00060002); /* GPIO 1/2 as output */
+		cx_clear(GP0_IO, 0x00010004); /* GPIO 0 as input */
+		mdelay(100); /* reset delay */
+		cx_set(GP0_IO, 0x00060004); /* GPIO as out, reset high */
+		cx_clear(GP0_IO, 0x00010002);
+		cx_write(MC417_CTL, 0x00000037); /* enable GPIO3-18 pins */
+
+		/* GPIO-15 IN as ~ACK, rest as OUT */
+		cx_write(MC417_OEN, 0x00001000);
+
+		/* ~RD, ~WR high; ADL0, ADL1 low; ~CS0, ~CS1 high */
+		cx_write(MC417_RWD, 0x0000c300);
+
+		/* enable irq */
+		cx_write(GPIO_ISM, 0x00000000); /* INTERRUPTS active low */
 	}
 }
 
@@ -1817,6 +1855,7 @@ void cx23885_card_setup(struct cx23885_dev *dev)
 	case CX23885_BOARD_TEVII_S471:
 	case CX23885_BOARD_DVBWORLD_2005:
 	case CX23885_BOARD_PROF_8000:
+	case CX23885_BOARD_DVBSKY_T980C:
 		ts1->gen_ctrl_val  = 0x5; /* Parallel */
 		ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */
 		ts1->src_sel_val   = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
@@ -1935,6 +1974,7 @@ void cx23885_card_setup(struct cx23885_dev *dev)
 	case CX23885_BOARD_TBS_6980:
 	case CX23885_BOARD_TBS_6981:
 	case CX23885_BOARD_DVBSKY_T9580:
+	case CX23885_BOARD_DVBSKY_T980C:
 		dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev,
 				&dev->i2c_bus[2].i2c_adap,
 				"cx25840", 0x88 >> 1, NULL);
diff --git a/drivers/media/pci/cx23885/cx23885-dvb.c b/drivers/media/pci/cx23885/cx23885-dvb.c
index 2f532c9..d327459 100644
--- a/drivers/media/pci/cx23885/cx23885-dvb.c
+++ b/drivers/media/pci/cx23885/cx23885-dvb.c
@@ -1681,6 +1681,52 @@ static int dvb_register(struct cx23885_tsport *port)
 			break;
 		}
 		break;
+	case CX23885_BOARD_DVBSKY_T980C:
+		i2c_bus = &dev->i2c_bus[1];
+
+		/* attach frontend */
+		memset(&si2168_config, 0, sizeof(si2168_config));
+		si2168_config.i2c_adapter = &adapter;
+		si2168_config.fe = &fe0->dvb.frontend;
+		si2168_config.ts_mode = SI2168_TS_PARALLEL;
+		memset(&info, 0, sizeof(struct i2c_board_info));
+		strlcpy(info.type, "si2168", I2C_NAME_SIZE);
+		info.addr = 0x64;
+		info.platform_data = &si2168_config;
+		request_module(info.type);
+		client_demod = i2c_new_device(&i2c_bus->i2c_adap, &info);
+		if (client_demod == NULL ||
+				client_demod->dev.driver == NULL)
+			goto frontend_detach;
+		if (!try_module_get(client_demod->dev.driver->owner)) {
+			i2c_unregister_device(client_demod);
+			goto frontend_detach;
+		}
+		port->i2c_client_demod = client_demod;
+
+		/* attach tuner */
+		memset(&si2157_config, 0, sizeof(si2157_config));
+		si2157_config.fe = fe0->dvb.frontend;
+		memset(&info, 0, sizeof(struct i2c_board_info));
+		strlcpy(info.type, "si2157", I2C_NAME_SIZE);
+		info.addr = 0x60;
+		info.platform_data = &si2157_config;
+		request_module(info.type);
+		client_tuner = i2c_new_device(adapter, &info);
+		if (client_tuner == NULL ||
+				client_tuner->dev.driver == NULL) {
+			module_put(client_demod->dev.driver->owner);
+			i2c_unregister_device(client_demod);
+			goto frontend_detach;
+		}
+		if (!try_module_get(client_tuner->dev.driver->owner)) {
+			i2c_unregister_device(client_tuner);
+			module_put(client_demod->dev.driver->owner);
+			i2c_unregister_device(client_demod);
+			goto frontend_detach;
+		}
+		port->i2c_client_tuner = client_tuner;
+		break;
 	default:
 		printk(KERN_INFO "%s: The frontend of your DVB/ATSC card "
 			" isn't supported yet\n",
@@ -1771,6 +1817,21 @@ static int dvb_register(struct cx23885_tsport *port)
 			(port->nr-1) * 8, 6);
 		break;
 		}
+	case CX23885_BOARD_DVBSKY_T980C: {
+		u8 eeprom[256]; /* 24C02 i2c eeprom */
+
+		if (port->nr != 1)
+			break;
+
+		/* Read entire EEPROM */
+		dev->i2c_bus[0].i2c_client.addr = 0xa0 >> 1;
+		tveeprom_read(&dev->i2c_bus[0].i2c_client, eeprom,
+				sizeof(eeprom));
+		printk(KERN_INFO "DVBSky T980C MAC address: %pM\n",
+			eeprom + 0xc0);
+		memcpy(port->frontends.adapter.proposed_mac, eeprom + 0xc0, 6);
+		break;
+		}
 	}
 
 	return ret;
diff --git a/drivers/media/pci/cx23885/cx23885.h b/drivers/media/pci/cx23885/cx23885.h
index 06088a0..1792d1a 100644
--- a/drivers/media/pci/cx23885/cx23885.h
+++ b/drivers/media/pci/cx23885/cx23885.h
@@ -93,6 +93,7 @@
 #define CX23885_BOARD_HAUPPAUGE_IMPACTVCBE     43
 #define CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP2 44
 #define CX23885_BOARD_DVBSKY_T9580             45
+#define CX23885_BOARD_DVBSKY_T980C             46
 
 #define GPIO_0 0x00000001
 #define GPIO_1 0x00000002
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 2/5] sp2: fix incorrect struct
  2014-09-29  7:44 [PATCH 1/5] cx23855: add support for DVBSky T980C (no CI support) Olli Salonen
@ 2014-09-29  7:44 ` Olli Salonen
  2014-10-01 19:57   ` Antti Palosaari
  2014-09-29  7:44 ` [PATCH 3/5] sp2: improve debug logging Olli Salonen
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 12+ messages in thread
From: Olli Salonen @ 2014-09-29  7:44 UTC (permalink / raw)
  To: linux-media; +Cc: Olli Salonen

Incorrect struct used in the SP2 driver.

Reported-by: Max Nibble <nibble.max@gmail.com>
Signed-off-by: Olli Salonen <olli.salonen@iki.fi>
---
 drivers/media/dvb-frontends/sp2.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/dvb-frontends/sp2.c b/drivers/media/dvb-frontends/sp2.c
index 9b684d5..1f4f250 100644
--- a/drivers/media/dvb-frontends/sp2.c
+++ b/drivers/media/dvb-frontends/sp2.c
@@ -407,7 +407,7 @@ err:
 
 static int sp2_remove(struct i2c_client *client)
 {
-	struct si2157 *s = i2c_get_clientdata(client);
+	struct sp2 *s = i2c_get_clientdata(client);
 
 	dev_dbg(&client->dev, "\n");
 
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 3/5] sp2: improve debug logging
  2014-09-29  7:44 [PATCH 1/5] cx23855: add support for DVBSky T980C (no CI support) Olli Salonen
  2014-09-29  7:44 ` [PATCH 2/5] sp2: fix incorrect struct Olli Salonen
@ 2014-09-29  7:44 ` Olli Salonen
  2014-10-01 19:57   ` Antti Palosaari
  2014-09-29  7:44 ` [PATCH 4/5] cx23885: add I2C client for CI into state and handle unregistering Olli Salonen
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 12+ messages in thread
From: Olli Salonen @ 2014-09-29  7:44 UTC (permalink / raw)
  To: linux-media; +Cc: Olli Salonen

Improve debugging output.

Signed-off-by: Olli Salonen <olli.salonen@iki.fi>
---
 drivers/media/dvb-frontends/sp2.c | 19 +++++++++++--------
 1 file changed, 11 insertions(+), 8 deletions(-)

diff --git a/drivers/media/dvb-frontends/sp2.c b/drivers/media/dvb-frontends/sp2.c
index 1f4f250..320cbe9 100644
--- a/drivers/media/dvb-frontends/sp2.c
+++ b/drivers/media/dvb-frontends/sp2.c
@@ -92,6 +92,9 @@ static int sp2_write_i2c(struct sp2 *s, u8 reg, u8 *buf, int len)
 			return -EIO;
 	}
 
+	dev_dbg(&s->client->dev, "addr=0x%04x, reg = 0x%02x, data = %*ph\n",
+				client->addr, reg, len, buf);
+
 	return 0;
 }
 
@@ -103,9 +106,6 @@ static int sp2_ci_op_cam(struct dvb_ca_en50221 *en50221, int slot, u8 acs,
 	int mem, ret;
 	int (*ci_op_cam)(void*, u8, int, u8, int*) = s->ci_control;
 
-	dev_dbg(&s->client->dev, "slot=%d, acs=0x%02x, addr=0x%04x, data = 0x%02x",
-			slot, acs, addr, data);
-
 	if (slot != 0)
 		return -EINVAL;
 
@@ -140,13 +140,16 @@ static int sp2_ci_op_cam(struct dvb_ca_en50221 *en50221, int slot, u8 acs,
 	if (ret)
 		return ret;
 
-	if (read) {
-		dev_dbg(&s->client->dev, "cam read, addr=0x%04x, data = 0x%04x",
-				addr, mem);
+	dev_dbg(&s->client->dev, "%s: slot=%d, addr=0x%04x, %s, data=%x",
+			(read) ? "read" : "write", slot, addr,
+			(acs == SP2_CI_ATTR_ACS) ? "attr" : "io",
+			(read) ? mem : data);
+
+	if (read)
 		return mem;
-	} else {
+	else
 		return 0;
-	}
+
 }
 
 int sp2_ci_read_attribute_mem(struct dvb_ca_en50221 *en50221,
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 4/5] cx23885: add I2C client for CI into state and handle unregistering
  2014-09-29  7:44 [PATCH 1/5] cx23855: add support for DVBSky T980C (no CI support) Olli Salonen
  2014-09-29  7:44 ` [PATCH 2/5] sp2: fix incorrect struct Olli Salonen
  2014-09-29  7:44 ` [PATCH 3/5] sp2: improve debug logging Olli Salonen
@ 2014-09-29  7:44 ` Olli Salonen
  2014-10-01 20:02   ` Antti Palosaari
  2014-09-29  7:44 ` [PATCH 5/5] cx23855: add CI support for DVBSky T980C Olli Salonen
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 12+ messages in thread
From: Olli Salonen @ 2014-09-29  7:44 UTC (permalink / raw)
  To: linux-media; +Cc: Olli Salonen

If the CI chip has an I2C driver, we need to store I2C client into state.

Signed-off-by: Olli Salonen <olli.salonen@iki.fi>
---
 drivers/media/pci/cx23885/cx23885-dvb.c | 7 +++++++
 drivers/media/pci/cx23885/cx23885.h     | 1 +
 2 files changed, 8 insertions(+)

diff --git a/drivers/media/pci/cx23885/cx23885-dvb.c b/drivers/media/pci/cx23885/cx23885-dvb.c
index d327459..cc88997 100644
--- a/drivers/media/pci/cx23885/cx23885-dvb.c
+++ b/drivers/media/pci/cx23885/cx23885-dvb.c
@@ -1923,6 +1923,13 @@ int cx23885_dvb_unregister(struct cx23885_tsport *port)
 	 * implement MFE support.
 	 */
 
+	/* remove I2C client for CI */
+	client = port->i2c_client_ci;
+	if (client) {
+		module_put(client->dev.driver->owner);
+		i2c_unregister_device(client);
+	}
+
 	/* remove I2C client for tuner */
 	client = port->i2c_client_tuner;
 	if (client) {
diff --git a/drivers/media/pci/cx23885/cx23885.h b/drivers/media/pci/cx23885/cx23885.h
index 1792d1a..c35ba2d 100644
--- a/drivers/media/pci/cx23885/cx23885.h
+++ b/drivers/media/pci/cx23885/cx23885.h
@@ -297,6 +297,7 @@ struct cx23885_tsport {
 
 	struct i2c_client *i2c_client_demod;
 	struct i2c_client *i2c_client_tuner;
+	struct i2c_client *i2c_client_ci;
 
 	int (*set_frontend)(struct dvb_frontend *fe);
 	int (*fe_set_voltage)(struct dvb_frontend *fe,
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 5/5] cx23855: add CI support for DVBSky T980C
  2014-09-29  7:44 [PATCH 1/5] cx23855: add support for DVBSky T980C (no CI support) Olli Salonen
                   ` (2 preceding siblings ...)
  2014-09-29  7:44 ` [PATCH 4/5] cx23885: add I2C client for CI into state and handle unregistering Olli Salonen
@ 2014-09-29  7:44 ` Olli Salonen
  2014-10-01 20:16   ` Antti Palosaari
  2014-09-29 12:05 ` Nibble Max
  2014-10-01 19:56 ` [PATCH 1/5] cx23855: add support for DVBSky T980C (no CI support) Antti Palosaari
  5 siblings, 1 reply; 12+ messages in thread
From: Olli Salonen @ 2014-09-29  7:44 UTC (permalink / raw)
  To: linux-media; +Cc: Olli Salonen

Add CI support for DVBSky T980C.

I used the new host device independent CIMaX SP2 I2C driver to implement it.

cx23885_sp2_ci_ctrl function is borrowed entirely from cimax2.c.

Signed-off-by: Olli Salonen <olli.salonen@iki.fi>
---
 drivers/media/pci/cx23885/cx23885-dvb.c | 105 +++++++++++++++++++++++++++++++-
 1 file changed, 103 insertions(+), 2 deletions(-)

diff --git a/drivers/media/pci/cx23885/cx23885-dvb.c b/drivers/media/pci/cx23885/cx23885-dvb.c
index cc88997..70dbcd6 100644
--- a/drivers/media/pci/cx23885/cx23885-dvb.c
+++ b/drivers/media/pci/cx23885/cx23885-dvb.c
@@ -71,6 +71,7 @@
 #include "si2165.h"
 #include "si2168.h"
 #include "si2157.h"
+#include "sp2.h"
 #include "m88ds3103.h"
 #include "m88ts2022.h"
 
@@ -616,6 +617,76 @@ static int dvbsky_t9580_set_voltage(struct dvb_frontend *fe,
 	return 0;
 }
 
+static int cx23885_sp2_ci_ctrl(void *priv, u8 read, int addr,
+				u8 data, int *mem)
+{
+
+	/* MC417 */
+	#define SP2_DATA              0x000000ff
+	#define SP2_WR                0x00008000
+	#define SP2_RD                0x00004000
+	#define SP2_ACK               0x00001000
+	#define SP2_ADHI              0x00000800
+	#define SP2_ADLO              0x00000400
+	#define SP2_CS1               0x00000200
+	#define SP2_CS0               0x00000100
+	#define SP2_EN_ALL            0x00001000
+	#define SP2_CTRL_OFF          (SP2_CS1 | SP2_CS0 | SP2_WR | SP2_RD)
+
+	struct cx23885_tsport *port = priv;
+	struct cx23885_dev *dev = port->dev;
+	int ret;
+	int tmp;
+	unsigned long timeout;
+
+	mutex_lock(&dev->gpio_lock);
+
+	/* write addr */
+	cx_write(MC417_OEN, SP2_EN_ALL);
+	cx_write(MC417_RWD, SP2_CTRL_OFF |
+				SP2_ADLO | (0xff & addr));
+	cx_clear(MC417_RWD, SP2_ADLO);
+	cx_write(MC417_RWD, SP2_CTRL_OFF |
+				SP2_ADHI | (0xff & (addr >> 8)));
+	cx_clear(MC417_RWD, SP2_ADHI);
+
+	if (read) { /* data in */
+		cx_write(MC417_OEN, SP2_EN_ALL | SP2_DATA);
+	} else /* data out */
+		cx_write(MC417_RWD, SP2_CTRL_OFF | data);
+
+	/* chip select 0 */
+	cx_clear(MC417_RWD, SP2_CS0);
+
+	/* read/write */
+	cx_clear(MC417_RWD, (read) ? SP2_RD : SP2_WR);
+
+	timeout = jiffies + msecs_to_jiffies(1);
+	for (;;) {
+		tmp = cx_read(MC417_RWD);
+		if ((tmp & SP2_ACK) == 0)
+			break;
+		if (time_after(jiffies, timeout))
+			break;
+		udelay(1);
+	}
+
+	cx_set(MC417_RWD, SP2_CTRL_OFF);
+	*mem = tmp & 0xff;
+
+	mutex_unlock(&dev->gpio_lock);
+
+	if (!read)
+		if (*mem < 0) {
+			ret = -EREMOTEIO;
+			goto err;
+		}
+
+	return 0;
+err:
+	return ret;
+}
+
 static int cx23885_dvb_set_frontend(struct dvb_frontend *fe)
 {
 	struct dtv_frontend_properties *p = &fe->dtv_property_cache;
@@ -944,11 +1015,11 @@ static int dvb_register(struct cx23885_tsport *port)
 	struct vb2_dvb_frontend *fe0, *fe1 = NULL;
 	struct si2168_config si2168_config;
 	struct si2157_config si2157_config;
+	struct sp2_config sp2_config;
 	struct m88ts2022_config m88ts2022_config;
 	struct i2c_board_info info;
 	struct i2c_adapter *adapter;
-	struct i2c_client *client_demod;
-	struct i2c_client *client_tuner;
+	struct i2c_client *client_demod, *client_tuner, *client_ci;
 	int mfe_shared = 0; /* bus not shared by default */
 	int ret;
 
@@ -1683,6 +1754,7 @@ static int dvb_register(struct cx23885_tsport *port)
 		break;
 	case CX23885_BOARD_DVBSKY_T980C:
 		i2c_bus = &dev->i2c_bus[1];
+		i2c_bus2 = &dev->i2c_bus[0];
 
 		/* attach frontend */
 		memset(&si2168_config, 0, sizeof(si2168_config));
@@ -1820,6 +1892,35 @@ static int dvb_register(struct cx23885_tsport *port)
 	case CX23885_BOARD_DVBSKY_T980C: {
 		u8 eeprom[256]; /* 24C02 i2c eeprom */
 
+		/* attach CI */
+		memset(&sp2_config, 0, sizeof(sp2_config));
+		sp2_config.dvb_adap = &port->frontends.adapter;
+		sp2_config.priv = port;
+		sp2_config.ci_control = cx23885_sp2_ci_ctrl;
+		memset(&info, 0, sizeof(struct i2c_board_info));
+		strlcpy(info.type, "sp2", I2C_NAME_SIZE);
+		info.addr = 0x40;
+		info.platform_data = &sp2_config;
+		request_module(info.type);
+		client_ci = i2c_new_device(&i2c_bus2->i2c_adap, &info);
+		if (client_ci == NULL ||
+				client_ci->dev.driver == NULL) {
+			module_put(client_tuner->dev.driver->owner);
+			i2c_unregister_device(client_tuner);
+			module_put(client_demod->dev.driver->owner);
+			i2c_unregister_device(client_demod);
+			goto frontend_detach;
+		}
+		if (!try_module_get(client_ci->dev.driver->owner)) {
+			i2c_unregister_device(client_ci);
+			module_put(client_tuner->dev.driver->owner);
+			i2c_unregister_device(client_tuner);
+			module_put(client_demod->dev.driver->owner);
+			i2c_unregister_device(client_demod);
+			goto frontend_detach;
+		}
+		port->i2c_client_ci = client_ci;
+
 		if (port->nr != 1)
 			break;
 
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [PATCH 5/5] cx23855: add CI support for DVBSky T980C
  2014-09-29  7:44 [PATCH 1/5] cx23855: add support for DVBSky T980C (no CI support) Olli Salonen
                   ` (3 preceding siblings ...)
  2014-09-29  7:44 ` [PATCH 5/5] cx23855: add CI support for DVBSky T980C Olli Salonen
@ 2014-09-29 12:05 ` Nibble Max
  2014-09-29 12:44   ` Olli Salonen
  2014-10-01 19:56 ` [PATCH 1/5] cx23855: add support for DVBSky T980C (no CI support) Antti Palosaari
  5 siblings, 1 reply; 12+ messages in thread
From: Nibble Max @ 2014-09-29 12:05 UTC (permalink / raw)
  To: Olli Salonen; +Cc: linux-media

Hello,
In hardware design, the CI host controller is wired with GPIO_0 of CX23885.
The GPIO_0 can be configed as the interrupt source.
Interrupt mode in PCIe driver is more faster than poll mode to detect CAM insert/remove operations etc.

>Add CI support for DVBSky T980C.
>
>I used the new host device independent CIMaX SP2 I2C driver to implement it.
>
>cx23885_sp2_ci_ctrl function is borrowed entirely from cimax2.c.
>
>Signed-off-by: Olli Salonen <olli.salonen@iki.fi>
>---
> drivers/media/pci/cx23885/cx23885-dvb.c | 105 +++++++++++++++++++++++++++++++-
> 1 file changed, 103 insertions(+), 2 deletions(-)
>
>diff --git a/drivers/media/pci/cx23885/cx23885-dvb.c b/drivers/media/pci/cx23885/cx23885-dvb.c
>index cc88997..70dbcd6 100644
>--- a/drivers/media/pci/cx23885/cx23885-dvb.c
>+++ b/drivers/media/pci/cx23885/cx23885-dvb.c
>@@ -71,6 +71,7 @@
> #include "si2165.h"
> #include "si2168.h"
> #include "si2157.h"
>+#include "sp2.h"
> #include "m88ds3103.h"
> #include "m88ts2022.h"
> 
>@@ -616,6 +617,76 @@ static int dvbsky_t9580_set_voltage(struct dvb_frontend *fe,
> 	return 0;
> }
> 
>+static int cx23885_sp2_ci_ctrl(void *priv, u8 read, int addr,
>+				u8 data, int *mem)
>+{
>+
>+	/* MC417 */
>+	#define SP2_DATA              0x000000ff
>+	#define SP2_WR                0x00008000
>+	#define SP2_RD                0x00004000
>+	#define SP2_ACK               0x00001000
>+	#define SP2_ADHI              0x00000800
>+	#define SP2_ADLO              0x00000400
>+	#define SP2_CS1               0x00000200
>+	#define SP2_CS0               0x00000100
>+	#define SP2_EN_ALL            0x00001000
>+	#define SP2_CTRL_OFF          (SP2_CS1 | SP2_CS0 | SP2_WR | SP2_RD)
>+
>+	struct cx23885_tsport *port = priv;
>+	struct cx23885_dev *dev = port->dev;
>+	int ret;
>+	int tmp;
>+	unsigned long timeout;
>+
>+	mutex_lock(&dev->gpio_lock);
>+
>+	/* write addr */
>+	cx_write(MC417_OEN, SP2_EN_ALL);
>+	cx_write(MC417_RWD, SP2_CTRL_OFF |
>+				SP2_ADLO | (0xff & addr));
>+	cx_clear(MC417_RWD, SP2_ADLO);
>+	cx_write(MC417_RWD, SP2_CTRL_OFF |
>+				SP2_ADHI | (0xff & (addr >> 8)));
>+	cx_clear(MC417_RWD, SP2_ADHI);
>+
>+	if (read) { /* data in */
>+		cx_write(MC417_OEN, SP2_EN_ALL | SP2_DATA);
>+	} else /* data out */
>+		cx_write(MC417_RWD, SP2_CTRL_OFF | data);
>+
>+	/* chip select 0 */
>+	cx_clear(MC417_RWD, SP2_CS0);
>+
>+	/* read/write */
>+	cx_clear(MC417_RWD, (read) ? SP2_RD : SP2_WR);
>+
>+	timeout = jiffies + msecs_to_jiffies(1);
>+	for (;;) {
>+		tmp = cx_read(MC417_RWD);
>+		if ((tmp & SP2_ACK) == 0)
>+			break;
>+		if (time_after(jiffies, timeout))
>+			break;
>+		udelay(1);
>+	}
>+
>+	cx_set(MC417_RWD, SP2_CTRL_OFF);
>+	*mem = tmp & 0xff;
>+
>+	mutex_unlock(&dev->gpio_lock);
>+
>+	if (!read)
>+		if (*mem < 0) {
>+			ret = -EREMOTEIO;
>+			goto err;
>+		}
>+
>+	return 0;
>+err:
>+	return ret;
>+}
>+
> static int cx23885_dvb_set_frontend(struct dvb_frontend *fe)
> {
> 	struct dtv_frontend_properties *p = &fe->dtv_property_cache;
>@@ -944,11 +1015,11 @@ static int dvb_register(struct cx23885_tsport *port)
> 	struct vb2_dvb_frontend *fe0, *fe1 = NULL;
> 	struct si2168_config si2168_config;
> 	struct si2157_config si2157_config;
>+	struct sp2_config sp2_config;
> 	struct m88ts2022_config m88ts2022_config;
> 	struct i2c_board_info info;
> 	struct i2c_adapter *adapter;
>-	struct i2c_client *client_demod;
>-	struct i2c_client *client_tuner;
>+	struct i2c_client *client_demod, *client_tuner, *client_ci;
> 	int mfe_shared = 0; /* bus not shared by default */
> 	int ret;
> 
>@@ -1683,6 +1754,7 @@ static int dvb_register(struct cx23885_tsport *port)
> 		break;
> 	case CX23885_BOARD_DVBSKY_T980C:
> 		i2c_bus = &dev->i2c_bus[1];
>+		i2c_bus2 = &dev->i2c_bus[0];
> 
> 		/* attach frontend */
> 		memset(&si2168_config, 0, sizeof(si2168_config));
>@@ -1820,6 +1892,35 @@ static int dvb_register(struct cx23885_tsport *port)
> 	case CX23885_BOARD_DVBSKY_T980C: {
> 		u8 eeprom[256]; /* 24C02 i2c eeprom */
> 
>+		/* attach CI */
>+		memset(&sp2_config, 0, sizeof(sp2_config));
>+		sp2_config.dvb_adap = &port->frontends.adapter;
>+		sp2_config.priv = port;
>+		sp2_config.ci_control = cx23885_sp2_ci_ctrl;
>+		memset(&info, 0, sizeof(struct i2c_board_info));
>+		strlcpy(info.type, "sp2", I2C_NAME_SIZE);
>+		info.addr = 0x40;
>+		info.platform_data = &sp2_config;
>+		request_module(info.type);
>+		client_ci = i2c_new_device(&i2c_bus2->i2c_adap, &info);
>+		if (client_ci == NULL ||
>+				client_ci->dev.driver == NULL) {
>+			module_put(client_tuner->dev.driver->owner);
>+			i2c_unregister_device(client_tuner);
>+			module_put(client_demod->dev.driver->owner);
>+			i2c_unregister_device(client_demod);
>+			goto frontend_detach;
>+		}
>+		if (!try_module_get(client_ci->dev.driver->owner)) {
>+			i2c_unregister_device(client_ci);
>+			module_put(client_tuner->dev.driver->owner);
>+			i2c_unregister_device(client_tuner);
>+			module_put(client_demod->dev.driver->owner);
>+			i2c_unregister_device(client_demod);
>+			goto frontend_detach;
>+		}
>+		port->i2c_client_ci = client_ci;
>+
> 		if (port->nr != 1)
> 			break;
> 
>-- 
>1.9.1
>
>--
>To unsubscribe from this list: send the line "unsubscribe linux-media" in
>the body of a message to majordomo@vger.kernel.org
>More majordomo info at  http://vger.kernel.org/majordomo-info.html
>.


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 5/5] cx23855: add CI support for DVBSky T980C
  2014-09-29 12:05 ` Nibble Max
@ 2014-09-29 12:44   ` Olli Salonen
  0 siblings, 0 replies; 12+ messages in thread
From: Olli Salonen @ 2014-09-29 12:44 UTC (permalink / raw)
  To: Nibble Max; +Cc: linux-media

Hi Max,

Thanks for the comments. I looked through the existing CIMaX driver
and came to the conclusion that it can be implemented either with the
IRQs or then just to rely on the polling like the USB devices have to
do. I don't think it's that important, as the user probably will not
add/remove the CAM that often. That being said, of course it would be
nice if we had a config option to choose if IRQ is supported or not.
If you have a patch for that, I'm happy to have it in.

Cheers,
-olli


On 29 September 2014 15:05, Nibble Max <nibble.max@gmail.com> wrote:
> Hello,
> In hardware design, the CI host controller is wired with GPIO_0 of CX23885.
> The GPIO_0 can be configed as the interrupt source.
> Interrupt mode in PCIe driver is more faster than poll mode to detect CAM insert/remove operations etc.
>
>>Add CI support for DVBSky T980C.
>>
>>I used the new host device independent CIMaX SP2 I2C driver to implement it.
>>
>>cx23885_sp2_ci_ctrl function is borrowed entirely from cimax2.c.
>>
>>Signed-off-by: Olli Salonen <olli.salonen@iki.fi>
>>---
>> drivers/media/pci/cx23885/cx23885-dvb.c | 105 +++++++++++++++++++++++++++++++-
>> 1 file changed, 103 insertions(+), 2 deletions(-)
>>
>>diff --git a/drivers/media/pci/cx23885/cx23885-dvb.c b/drivers/media/pci/cx23885/cx23885-dvb.c
>>index cc88997..70dbcd6 100644
>>--- a/drivers/media/pci/cx23885/cx23885-dvb.c
>>+++ b/drivers/media/pci/cx23885/cx23885-dvb.c
>>@@ -71,6 +71,7 @@
>> #include "si2165.h"
>> #include "si2168.h"
>> #include "si2157.h"
>>+#include "sp2.h"
>> #include "m88ds3103.h"
>> #include "m88ts2022.h"
>>
>>@@ -616,6 +617,76 @@ static int dvbsky_t9580_set_voltage(struct dvb_frontend *fe,
>>       return 0;
>> }
>>
>>+static int cx23885_sp2_ci_ctrl(void *priv, u8 read, int addr,
>>+                              u8 data, int *mem)
>>+{
>>+
>>+      /* MC417 */
>>+      #define SP2_DATA              0x000000ff
>>+      #define SP2_WR                0x00008000
>>+      #define SP2_RD                0x00004000
>>+      #define SP2_ACK               0x00001000
>>+      #define SP2_ADHI              0x00000800
>>+      #define SP2_ADLO              0x00000400
>>+      #define SP2_CS1               0x00000200
>>+      #define SP2_CS0               0x00000100
>>+      #define SP2_EN_ALL            0x00001000
>>+      #define SP2_CTRL_OFF          (SP2_CS1 | SP2_CS0 | SP2_WR | SP2_RD)
>>+
>>+      struct cx23885_tsport *port = priv;
>>+      struct cx23885_dev *dev = port->dev;
>>+      int ret;
>>+      int tmp;
>>+      unsigned long timeout;
>>+
>>+      mutex_lock(&dev->gpio_lock);
>>+
>>+      /* write addr */
>>+      cx_write(MC417_OEN, SP2_EN_ALL);
>>+      cx_write(MC417_RWD, SP2_CTRL_OFF |
>>+                              SP2_ADLO | (0xff & addr));
>>+      cx_clear(MC417_RWD, SP2_ADLO);
>>+      cx_write(MC417_RWD, SP2_CTRL_OFF |
>>+                              SP2_ADHI | (0xff & (addr >> 8)));
>>+      cx_clear(MC417_RWD, SP2_ADHI);
>>+
>>+      if (read) { /* data in */
>>+              cx_write(MC417_OEN, SP2_EN_ALL | SP2_DATA);
>>+      } else /* data out */
>>+              cx_write(MC417_RWD, SP2_CTRL_OFF | data);
>>+
>>+      /* chip select 0 */
>>+      cx_clear(MC417_RWD, SP2_CS0);
>>+
>>+      /* read/write */
>>+      cx_clear(MC417_RWD, (read) ? SP2_RD : SP2_WR);
>>+
>>+      timeout = jiffies + msecs_to_jiffies(1);
>>+      for (;;) {
>>+              tmp = cx_read(MC417_RWD);
>>+              if ((tmp & SP2_ACK) == 0)
>>+                      break;
>>+              if (time_after(jiffies, timeout))
>>+                      break;
>>+              udelay(1);
>>+      }
>>+
>>+      cx_set(MC417_RWD, SP2_CTRL_OFF);
>>+      *mem = tmp & 0xff;
>>+
>>+      mutex_unlock(&dev->gpio_lock);
>>+
>>+      if (!read)
>>+              if (*mem < 0) {
>>+                      ret = -EREMOTEIO;
>>+                      goto err;
>>+              }
>>+
>>+      return 0;
>>+err:
>>+      return ret;
>>+}
>>+
>> static int cx23885_dvb_set_frontend(struct dvb_frontend *fe)
>> {
>>       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
>>@@ -944,11 +1015,11 @@ static int dvb_register(struct cx23885_tsport *port)
>>       struct vb2_dvb_frontend *fe0, *fe1 = NULL;
>>       struct si2168_config si2168_config;
>>       struct si2157_config si2157_config;
>>+      struct sp2_config sp2_config;
>>       struct m88ts2022_config m88ts2022_config;
>>       struct i2c_board_info info;
>>       struct i2c_adapter *adapter;
>>-      struct i2c_client *client_demod;
>>-      struct i2c_client *client_tuner;
>>+      struct i2c_client *client_demod, *client_tuner, *client_ci;
>>       int mfe_shared = 0; /* bus not shared by default */
>>       int ret;
>>
>>@@ -1683,6 +1754,7 @@ static int dvb_register(struct cx23885_tsport *port)
>>               break;
>>       case CX23885_BOARD_DVBSKY_T980C:
>>               i2c_bus = &dev->i2c_bus[1];
>>+              i2c_bus2 = &dev->i2c_bus[0];
>>
>>               /* attach frontend */
>>               memset(&si2168_config, 0, sizeof(si2168_config));
>>@@ -1820,6 +1892,35 @@ static int dvb_register(struct cx23885_tsport *port)
>>       case CX23885_BOARD_DVBSKY_T980C: {
>>               u8 eeprom[256]; /* 24C02 i2c eeprom */
>>
>>+              /* attach CI */
>>+              memset(&sp2_config, 0, sizeof(sp2_config));
>>+              sp2_config.dvb_adap = &port->frontends.adapter;
>>+              sp2_config.priv = port;
>>+              sp2_config.ci_control = cx23885_sp2_ci_ctrl;
>>+              memset(&info, 0, sizeof(struct i2c_board_info));
>>+              strlcpy(info.type, "sp2", I2C_NAME_SIZE);
>>+              info.addr = 0x40;
>>+              info.platform_data = &sp2_config;
>>+              request_module(info.type);
>>+              client_ci = i2c_new_device(&i2c_bus2->i2c_adap, &info);
>>+              if (client_ci == NULL ||
>>+                              client_ci->dev.driver == NULL) {
>>+                      module_put(client_tuner->dev.driver->owner);
>>+                      i2c_unregister_device(client_tuner);
>>+                      module_put(client_demod->dev.driver->owner);
>>+                      i2c_unregister_device(client_demod);
>>+                      goto frontend_detach;
>>+              }
>>+              if (!try_module_get(client_ci->dev.driver->owner)) {
>>+                      i2c_unregister_device(client_ci);
>>+                      module_put(client_tuner->dev.driver->owner);
>>+                      i2c_unregister_device(client_tuner);
>>+                      module_put(client_demod->dev.driver->owner);
>>+                      i2c_unregister_device(client_demod);
>>+                      goto frontend_detach;
>>+              }
>>+              port->i2c_client_ci = client_ci;
>>+
>>               if (port->nr != 1)
>>                       break;
>>
>>--
>>1.9.1
>>
>>--
>>To unsubscribe from this list: send the line "unsubscribe linux-media" in
>>the body of a message to majordomo@vger.kernel.org
>>More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>.
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-media" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 1/5] cx23855: add support for DVBSky T980C (no CI support)
  2014-09-29  7:44 [PATCH 1/5] cx23855: add support for DVBSky T980C (no CI support) Olli Salonen
                   ` (4 preceding siblings ...)
  2014-09-29 12:05 ` Nibble Max
@ 2014-10-01 19:56 ` Antti Palosaari
  5 siblings, 0 replies; 12+ messages in thread
From: Antti Palosaari @ 2014-10-01 19:56 UTC (permalink / raw)
  To: Olli Salonen, linux-media

Reviewed-by: Antti Palosaari <crope@iki.fi>

Antti

On 09/29/2014 10:44 AM, Olli Salonen wrote:
> This patch adds basic support for DVBSky T980C card. CI interface is not supported.
>
> DVBSky T980C is a PCIe card with the following components:
> - CX23885 PCIe bridge
> - Si2168-A20 demodulator
> - Si2158-A20 tuner
> - CIMaX SP2 CI chip
>
> The demodulator and tuner need firmware. They're the same as used with TT CT2-4650 CI:
> https://www.mail-archive.com/linux-media@vger.kernel.org/msg78033.html
>
> Signed-off-by: Olli Salonen <olli.salonen@iki.fi>
> ---
>   drivers/media/pci/cx23885/cx23885-cards.c | 40 ++++++++++++++++++++
>   drivers/media/pci/cx23885/cx23885-dvb.c   | 61 +++++++++++++++++++++++++++++++
>   drivers/media/pci/cx23885/cx23885.h       |  1 +
>   3 files changed, 102 insertions(+)
>
> diff --git a/drivers/media/pci/cx23885/cx23885-cards.c b/drivers/media/pci/cx23885/cx23885-cards.c
> index 88c257d..e8965e6 100644
> --- a/drivers/media/pci/cx23885/cx23885-cards.c
> +++ b/drivers/media/pci/cx23885/cx23885-cards.c
> @@ -680,6 +680,10 @@ struct cx23885_board cx23885_boards[] = {
>   		.portb		= CX23885_MPEG_DVB,
>   		.portc		= CX23885_MPEG_DVB,
>   	},
> +	[CX23885_BOARD_DVBSKY_T980C] = {
> +		.name		= "DVBSky T980C",
> +		.portb		= CX23885_MPEG_DVB,
> +	},
>   };
>   const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards);
>
> @@ -939,6 +943,10 @@ struct cx23885_subid cx23885_subids[] = {
>   		.subvendor = 0x4254,
>   		.subdevice = 0x9580,
>   		.card      = CX23885_BOARD_DVBSKY_T9580,
> +	}, {
> +		.subvendor = 0x4254,
> +		.subdevice = 0x980c,
> +		.card      = CX23885_BOARD_DVBSKY_T980C,
>   	},
>   };
>   const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids);
> @@ -1541,6 +1549,36 @@ void cx23885_gpio_setup(struct cx23885_dev *dev)
>   		mdelay(100);
>   		cx23885_gpio_set(dev, GPIO_2 | GPIO_11);
>   		break;
> +	case CX23885_BOARD_DVBSKY_T980C:
> +		/*
> +		 * GPIO-0 INTA from CiMax, input
> +		 * GPIO-1 reset CiMax, output, high active
> +		 * GPIO-2 reset demod, output, low active
> +		 * GPIO-3 to GPIO-10 data/addr for CAM
> +		 * GPIO-11 ~CS0 to CiMax1
> +		 * GPIO-12 ~CS1 to CiMax2
> +		 * GPIO-13 ADL0 load LSB addr
> +		 * GPIO-14 ADL1 load MSB addr
> +		 * GPIO-15 ~RDY from CiMax
> +		 * GPIO-17 ~RD to CiMax
> +		 * GPIO-18 ~WR to CiMax
> +		 */
> +
> +		cx_set(GP0_IO, 0x00060002); /* GPIO 1/2 as output */
> +		cx_clear(GP0_IO, 0x00010004); /* GPIO 0 as input */
> +		mdelay(100); /* reset delay */
> +		cx_set(GP0_IO, 0x00060004); /* GPIO as out, reset high */
> +		cx_clear(GP0_IO, 0x00010002);
> +		cx_write(MC417_CTL, 0x00000037); /* enable GPIO3-18 pins */
> +
> +		/* GPIO-15 IN as ~ACK, rest as OUT */
> +		cx_write(MC417_OEN, 0x00001000);
> +
> +		/* ~RD, ~WR high; ADL0, ADL1 low; ~CS0, ~CS1 high */
> +		cx_write(MC417_RWD, 0x0000c300);
> +
> +		/* enable irq */
> +		cx_write(GPIO_ISM, 0x00000000); /* INTERRUPTS active low */
>   	}
>   }
>
> @@ -1817,6 +1855,7 @@ void cx23885_card_setup(struct cx23885_dev *dev)
>   	case CX23885_BOARD_TEVII_S471:
>   	case CX23885_BOARD_DVBWORLD_2005:
>   	case CX23885_BOARD_PROF_8000:
> +	case CX23885_BOARD_DVBSKY_T980C:
>   		ts1->gen_ctrl_val  = 0x5; /* Parallel */
>   		ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */
>   		ts1->src_sel_val   = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
> @@ -1935,6 +1974,7 @@ void cx23885_card_setup(struct cx23885_dev *dev)
>   	case CX23885_BOARD_TBS_6980:
>   	case CX23885_BOARD_TBS_6981:
>   	case CX23885_BOARD_DVBSKY_T9580:
> +	case CX23885_BOARD_DVBSKY_T980C:
>   		dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev,
>   				&dev->i2c_bus[2].i2c_adap,
>   				"cx25840", 0x88 >> 1, NULL);
> diff --git a/drivers/media/pci/cx23885/cx23885-dvb.c b/drivers/media/pci/cx23885/cx23885-dvb.c
> index 2f532c9..d327459 100644
> --- a/drivers/media/pci/cx23885/cx23885-dvb.c
> +++ b/drivers/media/pci/cx23885/cx23885-dvb.c
> @@ -1681,6 +1681,52 @@ static int dvb_register(struct cx23885_tsport *port)
>   			break;
>   		}
>   		break;
> +	case CX23885_BOARD_DVBSKY_T980C:
> +		i2c_bus = &dev->i2c_bus[1];
> +
> +		/* attach frontend */
> +		memset(&si2168_config, 0, sizeof(si2168_config));
> +		si2168_config.i2c_adapter = &adapter;
> +		si2168_config.fe = &fe0->dvb.frontend;
> +		si2168_config.ts_mode = SI2168_TS_PARALLEL;
> +		memset(&info, 0, sizeof(struct i2c_board_info));
> +		strlcpy(info.type, "si2168", I2C_NAME_SIZE);
> +		info.addr = 0x64;
> +		info.platform_data = &si2168_config;
> +		request_module(info.type);
> +		client_demod = i2c_new_device(&i2c_bus->i2c_adap, &info);
> +		if (client_demod == NULL ||
> +				client_demod->dev.driver == NULL)
> +			goto frontend_detach;
> +		if (!try_module_get(client_demod->dev.driver->owner)) {
> +			i2c_unregister_device(client_demod);
> +			goto frontend_detach;
> +		}
> +		port->i2c_client_demod = client_demod;
> +
> +		/* attach tuner */
> +		memset(&si2157_config, 0, sizeof(si2157_config));
> +		si2157_config.fe = fe0->dvb.frontend;
> +		memset(&info, 0, sizeof(struct i2c_board_info));
> +		strlcpy(info.type, "si2157", I2C_NAME_SIZE);
> +		info.addr = 0x60;
> +		info.platform_data = &si2157_config;
> +		request_module(info.type);
> +		client_tuner = i2c_new_device(adapter, &info);
> +		if (client_tuner == NULL ||
> +				client_tuner->dev.driver == NULL) {
> +			module_put(client_demod->dev.driver->owner);
> +			i2c_unregister_device(client_demod);
> +			goto frontend_detach;
> +		}
> +		if (!try_module_get(client_tuner->dev.driver->owner)) {
> +			i2c_unregister_device(client_tuner);
> +			module_put(client_demod->dev.driver->owner);
> +			i2c_unregister_device(client_demod);
> +			goto frontend_detach;
> +		}
> +		port->i2c_client_tuner = client_tuner;
> +		break;
>   	default:
>   		printk(KERN_INFO "%s: The frontend of your DVB/ATSC card "
>   			" isn't supported yet\n",
> @@ -1771,6 +1817,21 @@ static int dvb_register(struct cx23885_tsport *port)
>   			(port->nr-1) * 8, 6);
>   		break;
>   		}
> +	case CX23885_BOARD_DVBSKY_T980C: {
> +		u8 eeprom[256]; /* 24C02 i2c eeprom */
> +
> +		if (port->nr != 1)
> +			break;
> +
> +		/* Read entire EEPROM */
> +		dev->i2c_bus[0].i2c_client.addr = 0xa0 >> 1;
> +		tveeprom_read(&dev->i2c_bus[0].i2c_client, eeprom,
> +				sizeof(eeprom));
> +		printk(KERN_INFO "DVBSky T980C MAC address: %pM\n",
> +			eeprom + 0xc0);
> +		memcpy(port->frontends.adapter.proposed_mac, eeprom + 0xc0, 6);
> +		break;
> +		}
>   	}
>
>   	return ret;
> diff --git a/drivers/media/pci/cx23885/cx23885.h b/drivers/media/pci/cx23885/cx23885.h
> index 06088a0..1792d1a 100644
> --- a/drivers/media/pci/cx23885/cx23885.h
> +++ b/drivers/media/pci/cx23885/cx23885.h
> @@ -93,6 +93,7 @@
>   #define CX23885_BOARD_HAUPPAUGE_IMPACTVCBE     43
>   #define CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP2 44
>   #define CX23885_BOARD_DVBSKY_T9580             45
> +#define CX23885_BOARD_DVBSKY_T980C             46
>
>   #define GPIO_0 0x00000001
>   #define GPIO_1 0x00000002
>

-- 
http://palosaari.fi/

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 2/5] sp2: fix incorrect struct
  2014-09-29  7:44 ` [PATCH 2/5] sp2: fix incorrect struct Olli Salonen
@ 2014-10-01 19:57   ` Antti Palosaari
  0 siblings, 0 replies; 12+ messages in thread
From: Antti Palosaari @ 2014-10-01 19:57 UTC (permalink / raw)
  To: Olli Salonen, linux-media

Reviewed-by: Antti Palosaari <crope@iki.fi>

Antti

On 09/29/2014 10:44 AM, Olli Salonen wrote:
> Incorrect struct used in the SP2 driver.
>
> Reported-by: Max Nibble <nibble.max@gmail.com>
> Signed-off-by: Olli Salonen <olli.salonen@iki.fi>
> ---
>   drivers/media/dvb-frontends/sp2.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/media/dvb-frontends/sp2.c b/drivers/media/dvb-frontends/sp2.c
> index 9b684d5..1f4f250 100644
> --- a/drivers/media/dvb-frontends/sp2.c
> +++ b/drivers/media/dvb-frontends/sp2.c
> @@ -407,7 +407,7 @@ err:
>
>   static int sp2_remove(struct i2c_client *client)
>   {
> -	struct si2157 *s = i2c_get_clientdata(client);
> +	struct sp2 *s = i2c_get_clientdata(client);
>
>   	dev_dbg(&client->dev, "\n");
>
>

-- 
http://palosaari.fi/

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 3/5] sp2: improve debug logging
  2014-09-29  7:44 ` [PATCH 3/5] sp2: improve debug logging Olli Salonen
@ 2014-10-01 19:57   ` Antti Palosaari
  0 siblings, 0 replies; 12+ messages in thread
From: Antti Palosaari @ 2014-10-01 19:57 UTC (permalink / raw)
  To: Olli Salonen, linux-media

Reviewed-by: Antti Palosaari <crope@iki.fi>

Antti

On 09/29/2014 10:44 AM, Olli Salonen wrote:
> Improve debugging output.
>
> Signed-off-by: Olli Salonen <olli.salonen@iki.fi>
> ---
>   drivers/media/dvb-frontends/sp2.c | 19 +++++++++++--------
>   1 file changed, 11 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/media/dvb-frontends/sp2.c b/drivers/media/dvb-frontends/sp2.c
> index 1f4f250..320cbe9 100644
> --- a/drivers/media/dvb-frontends/sp2.c
> +++ b/drivers/media/dvb-frontends/sp2.c
> @@ -92,6 +92,9 @@ static int sp2_write_i2c(struct sp2 *s, u8 reg, u8 *buf, int len)
>   			return -EIO;
>   	}
>
> +	dev_dbg(&s->client->dev, "addr=0x%04x, reg = 0x%02x, data = %*ph\n",
> +				client->addr, reg, len, buf);
> +
>   	return 0;
>   }
>
> @@ -103,9 +106,6 @@ static int sp2_ci_op_cam(struct dvb_ca_en50221 *en50221, int slot, u8 acs,
>   	int mem, ret;
>   	int (*ci_op_cam)(void*, u8, int, u8, int*) = s->ci_control;
>
> -	dev_dbg(&s->client->dev, "slot=%d, acs=0x%02x, addr=0x%04x, data = 0x%02x",
> -			slot, acs, addr, data);
> -
>   	if (slot != 0)
>   		return -EINVAL;
>
> @@ -140,13 +140,16 @@ static int sp2_ci_op_cam(struct dvb_ca_en50221 *en50221, int slot, u8 acs,
>   	if (ret)
>   		return ret;
>
> -	if (read) {
> -		dev_dbg(&s->client->dev, "cam read, addr=0x%04x, data = 0x%04x",
> -				addr, mem);
> +	dev_dbg(&s->client->dev, "%s: slot=%d, addr=0x%04x, %s, data=%x",
> +			(read) ? "read" : "write", slot, addr,
> +			(acs == SP2_CI_ATTR_ACS) ? "attr" : "io",
> +			(read) ? mem : data);
> +
> +	if (read)
>   		return mem;
> -	} else {
> +	else
>   		return 0;
> -	}
> +
>   }
>
>   int sp2_ci_read_attribute_mem(struct dvb_ca_en50221 *en50221,
>

-- 
http://palosaari.fi/

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 4/5] cx23885: add I2C client for CI into state and handle unregistering
  2014-09-29  7:44 ` [PATCH 4/5] cx23885: add I2C client for CI into state and handle unregistering Olli Salonen
@ 2014-10-01 20:02   ` Antti Palosaari
  0 siblings, 0 replies; 12+ messages in thread
From: Antti Palosaari @ 2014-10-01 20:02 UTC (permalink / raw)
  To: Olli Salonen, linux-media

Reviewed-by: Antti Palosaari <crope@iki.fi>

I was looking where is the CI I2C client pointer stored to that, but 
realized it was upcoming patch which will use that...

regards
Antti

On 09/29/2014 10:44 AM, Olli Salonen wrote:
> If the CI chip has an I2C driver, we need to store I2C client into state.
>
> Signed-off-by: Olli Salonen <olli.salonen@iki.fi>
> ---
>   drivers/media/pci/cx23885/cx23885-dvb.c | 7 +++++++
>   drivers/media/pci/cx23885/cx23885.h     | 1 +
>   2 files changed, 8 insertions(+)
>
> diff --git a/drivers/media/pci/cx23885/cx23885-dvb.c b/drivers/media/pci/cx23885/cx23885-dvb.c
> index d327459..cc88997 100644
> --- a/drivers/media/pci/cx23885/cx23885-dvb.c
> +++ b/drivers/media/pci/cx23885/cx23885-dvb.c
> @@ -1923,6 +1923,13 @@ int cx23885_dvb_unregister(struct cx23885_tsport *port)
>   	 * implement MFE support.
>   	 */
>
> +	/* remove I2C client for CI */
> +	client = port->i2c_client_ci;
> +	if (client) {
> +		module_put(client->dev.driver->owner);
> +		i2c_unregister_device(client);
> +	}
> +
>   	/* remove I2C client for tuner */
>   	client = port->i2c_client_tuner;
>   	if (client) {
> diff --git a/drivers/media/pci/cx23885/cx23885.h b/drivers/media/pci/cx23885/cx23885.h
> index 1792d1a..c35ba2d 100644
> --- a/drivers/media/pci/cx23885/cx23885.h
> +++ b/drivers/media/pci/cx23885/cx23885.h
> @@ -297,6 +297,7 @@ struct cx23885_tsport {
>
>   	struct i2c_client *i2c_client_demod;
>   	struct i2c_client *i2c_client_tuner;
> +	struct i2c_client *i2c_client_ci;
>
>   	int (*set_frontend)(struct dvb_frontend *fe);
>   	int (*fe_set_voltage)(struct dvb_frontend *fe,
>

-- 
http://palosaari.fi/

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 5/5] cx23855: add CI support for DVBSky T980C
  2014-09-29  7:44 ` [PATCH 5/5] cx23855: add CI support for DVBSky T980C Olli Salonen
@ 2014-10-01 20:16   ` Antti Palosaari
  0 siblings, 0 replies; 12+ messages in thread
From: Antti Palosaari @ 2014-10-01 20:16 UTC (permalink / raw)
  To: Olli Salonen, linux-media



On 09/29/2014 10:44 AM, Olli Salonen wrote:
> Add CI support for DVBSky T980C.
>
> I used the new host device independent CIMaX SP2 I2C driver to implement it.
>
> cx23885_sp2_ci_ctrl function is borrowed entirely from cimax2.c.
>
> Signed-off-by: Olli Salonen <olli.salonen@iki.fi>
> ---
>   drivers/media/pci/cx23885/cx23885-dvb.c | 105 +++++++++++++++++++++++++++++++-
>   1 file changed, 103 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/media/pci/cx23885/cx23885-dvb.c b/drivers/media/pci/cx23885/cx23885-dvb.c
> index cc88997..70dbcd6 100644
> --- a/drivers/media/pci/cx23885/cx23885-dvb.c
> +++ b/drivers/media/pci/cx23885/cx23885-dvb.c
> @@ -71,6 +71,7 @@
>   #include "si2165.h"
>   #include "si2168.h"
>   #include "si2157.h"
> +#include "sp2.h"
>   #include "m88ds3103.h"
>   #include "m88ts2022.h"
>
> @@ -616,6 +617,76 @@ static int dvbsky_t9580_set_voltage(struct dvb_frontend *fe,
>   	return 0;
>   }
>
> +static int cx23885_sp2_ci_ctrl(void *priv, u8 read, int addr,
> +				u8 data, int *mem)
> +{
> +

here is empty line. forget to ran checkpatch.pl?

> +	/* MC417 */
> +	#define SP2_DATA              0x000000ff
> +	#define SP2_WR                0x00008000
> +	#define SP2_RD                0x00004000
> +	#define SP2_ACK               0x00001000
> +	#define SP2_ADHI              0x00000800
> +	#define SP2_ADLO              0x00000400
> +	#define SP2_CS1               0x00000200
> +	#define SP2_CS0               0x00000100
> +	#define SP2_EN_ALL            0x00001000
> +	#define SP2_CTRL_OFF          (SP2_CS1 | SP2_CS0 | SP2_WR | SP2_RD)
> +
> +	struct cx23885_tsport *port = priv;
> +	struct cx23885_dev *dev = port->dev;
> +	int ret;
> +	int tmp;
> +	unsigned long timeout;
> +
> +	mutex_lock(&dev->gpio_lock);
> +
> +	/* write addr */
> +	cx_write(MC417_OEN, SP2_EN_ALL);
> +	cx_write(MC417_RWD, SP2_CTRL_OFF |
> +				SP2_ADLO | (0xff & addr));
> +	cx_clear(MC417_RWD, SP2_ADLO);
> +	cx_write(MC417_RWD, SP2_CTRL_OFF |
> +				SP2_ADHI | (0xff & (addr >> 8)));
> +	cx_clear(MC417_RWD, SP2_ADHI);
> +
> +	if (read) { /* data in */
> +		cx_write(MC417_OEN, SP2_EN_ALL | SP2_DATA);
> +	} else /* data out */
> +		cx_write(MC417_RWD, SP2_CTRL_OFF | data);

wrong parenthesis usage. checkpatch.pl? see CodingStyle doc

> +
> +	/* chip select 0 */
> +	cx_clear(MC417_RWD, SP2_CS0);
> +
> +	/* read/write */
> +	cx_clear(MC417_RWD, (read) ? SP2_RD : SP2_WR);
> +
> +	timeout = jiffies + msecs_to_jiffies(1);
> +	for (;;) {
> +		tmp = cx_read(MC417_RWD);
> +		if ((tmp & SP2_ACK) == 0)
> +			break;
> +		if (time_after(jiffies, timeout))
> +			break;
> +		udelay(1);

gaga, 1us delay in a busy waiting loop is very bad. It seems to read 
some register until value is correct. In a loop which is limited to one 
ms, using 1us delay. I cannot understand that, but is there some very 
critical timing needed this kind of code? That kind of code is nightmare 
for system performance, especially when it is on hot path (how often 
that code is executed?).

See also timers documentation about these delays from kernel documentation.

> +	}
> +
> +	cx_set(MC417_RWD, SP2_CTRL_OFF);
> +	*mem = tmp & 0xff;
> +
> +	mutex_unlock(&dev->gpio_lock);
> +
> +	if (!read)
> +		if (*mem < 0) {
> +			ret = -EREMOTEIO;
> +			goto err;
> +		}

I think missing parenthesis

> +
> +	return 0;
> +err:
> +	return ret;
> +}
> +
>   static int cx23885_dvb_set_frontend(struct dvb_frontend *fe)
>   {
>   	struct dtv_frontend_properties *p = &fe->dtv_property_cache;
> @@ -944,11 +1015,11 @@ static int dvb_register(struct cx23885_tsport *port)
>   	struct vb2_dvb_frontend *fe0, *fe1 = NULL;
>   	struct si2168_config si2168_config;
>   	struct si2157_config si2157_config;
> +	struct sp2_config sp2_config;
>   	struct m88ts2022_config m88ts2022_config;
>   	struct i2c_board_info info;
>   	struct i2c_adapter *adapter;
> -	struct i2c_client *client_demod;
> -	struct i2c_client *client_tuner;
> +	struct i2c_client *client_demod, *client_tuner, *client_ci;
>   	int mfe_shared = 0; /* bus not shared by default */
>   	int ret;
>
> @@ -1683,6 +1754,7 @@ static int dvb_register(struct cx23885_tsport *port)
>   		break;
>   	case CX23885_BOARD_DVBSKY_T980C:
>   		i2c_bus = &dev->i2c_bus[1];
> +		i2c_bus2 = &dev->i2c_bus[0];
>
>   		/* attach frontend */
>   		memset(&si2168_config, 0, sizeof(si2168_config));
> @@ -1820,6 +1892,35 @@ static int dvb_register(struct cx23885_tsport *port)
>   	case CX23885_BOARD_DVBSKY_T980C: {
>   		u8 eeprom[256]; /* 24C02 i2c eeprom */
>
> +		/* attach CI */
> +		memset(&sp2_config, 0, sizeof(sp2_config));
> +		sp2_config.dvb_adap = &port->frontends.adapter;
> +		sp2_config.priv = port;
> +		sp2_config.ci_control = cx23885_sp2_ci_ctrl;
> +		memset(&info, 0, sizeof(struct i2c_board_info));
> +		strlcpy(info.type, "sp2", I2C_NAME_SIZE);
> +		info.addr = 0x40;
> +		info.platform_data = &sp2_config;
> +		request_module(info.type);
> +		client_ci = i2c_new_device(&i2c_bus2->i2c_adap, &info);
> +		if (client_ci == NULL ||
> +				client_ci->dev.driver == NULL) {
> +			module_put(client_tuner->dev.driver->owner);
> +			i2c_unregister_device(client_tuner);
> +			module_put(client_demod->dev.driver->owner);
> +			i2c_unregister_device(client_demod);
> +			goto frontend_detach;
> +		}
> +		if (!try_module_get(client_ci->dev.driver->owner)) {
> +			i2c_unregister_device(client_ci);
> +			module_put(client_tuner->dev.driver->owner);
> +			i2c_unregister_device(client_tuner);
> +			module_put(client_demod->dev.driver->owner);
> +			i2c_unregister_device(client_demod);
> +			goto frontend_detach;
> +		}
> +		port->i2c_client_ci = client_ci;
> +
>   		if (port->nr != 1)
>   			break;
>
>

regards
Antti

-- 
http://palosaari.fi/

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2014-10-01 20:16 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-09-29  7:44 [PATCH 1/5] cx23855: add support for DVBSky T980C (no CI support) Olli Salonen
2014-09-29  7:44 ` [PATCH 2/5] sp2: fix incorrect struct Olli Salonen
2014-10-01 19:57   ` Antti Palosaari
2014-09-29  7:44 ` [PATCH 3/5] sp2: improve debug logging Olli Salonen
2014-10-01 19:57   ` Antti Palosaari
2014-09-29  7:44 ` [PATCH 4/5] cx23885: add I2C client for CI into state and handle unregistering Olli Salonen
2014-10-01 20:02   ` Antti Palosaari
2014-09-29  7:44 ` [PATCH 5/5] cx23855: add CI support for DVBSky T980C Olli Salonen
2014-10-01 20:16   ` Antti Palosaari
2014-09-29 12:05 ` Nibble Max
2014-09-29 12:44   ` Olli Salonen
2014-10-01 19:56 ` [PATCH 1/5] cx23855: add support for DVBSky T980C (no CI support) Antti Palosaari

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).