Skip to contentSkip to conversation

cx25840: Add non-default crystal frequency support

PATCH Superseded Brad Love 1 participant 5 messages Feb 12, 2018 Media (V4L/DVB)

lore
Share & tools
lore

Brad Love

author
#0 lore raw

cover cx25840: Add non-default crystal frequency support

This patch set requires:

https://patchwork.linuxtv.org/patch/46346/

Hauppauge produced a revision of ImpactVCBe using an 888, with a 25MHz crystal, instead of using the default third overtone 50Mhz crystal. Custom configuration of the cx25840 is required to load the firmware and properly decode video.

This patch set add an extra clocking option to the cx25840 driver. If a cx2388x board is produced using non-default crystal, then clk_freq can be set in the board profile and then used by the cx25840 to set up the PLL's. To pass frequency, the cx23885 driver sets the cx25840 v4l subdev host data to a pointer to clk_freq.

The only additional clock rate included is cx23888 with 25MHz crystal.

Brad Love (4):
cx25840: Use subdev host data for PLL override
cx23885: change 887/888 default to 888
cx23885: Set subdev host data to clk_freq pointer
cx23885: Override 888 ImpactVCBe crystal frequency

 drivers/media/i2c/cx25840/cx25840-core.c  | 28 ++++++++++++++++++++++------
 drivers/media/pci/cx23885/cx23885-cards.c |  4 ++++
 drivers/media/pci/cx23885/cx23885-core.c  | 16 +++++++++++++---
 3 files changed, 39 insertions(+), 9 deletions(-)
Signature · 1 line
2.7.4
author
#1 lore raw

PATCH 1/4 cx25840: Use subdev host data for PLL override

The cx25840 driver currently configures 885, 887, and 888 using default divisors for each chip. This check to see if the cx23885 driver has passed the cx25840 a non-default clock rate for a specific chip. If a cx23885 board has left clk_freq at 0, the clock default values will be used to configure the PLLs.

This patch only has effect on 888 boards who set clk_freq to 25M.

---
 drivers/media/i2c/cx25840/cx25840-core.c | 28 ++++++++++++++++++++++------
 1 file changed, 22 insertions(+), 6 deletions(-)
drivers/media/i2c/cx25840/cx25840-core.c +22 -6
index 98be63a..841c6bb 100644
@@ -463,8 +463,13 @@ static void cx23885_initialize(struct i2c_client *client)
 {
 	DEFINE_WAIT(wait);
 	struct cx25840_state *state = to_state(i2c_get_clientdata(client));
+	u32 clk_freq = 0;
 	struct workqueue_struct *q;
 
+	/* cx23885 sets hostdata to clk_freq pointer */
+	if (v4l2_get_subdev_hostdata(&state->sd))
+		clk_freq = *((u32 *)v4l2_get_subdev_hostdata(&state->sd));
+
 	/*
 	 * Come out of digital power down
 	 * The CX23888, at least, needs this, otherwise registers aside from
@@ -500,8 +505,13 @@ static void cx23885_initialize(struct i2c_client *client)
 		 * 50.0 MHz * (0xb + 0xe8ba26/0x2000000)/4 = 5 * 28.636363 MHz
 		 * 572.73 MHz before post divide
 		 */
-		/* HVR1850 or 50MHz xtal */
-		cx25840_write(client, 0x2, 0x71);
+		if (clk_freq == 25000000) {
+			/* 888/ImpactVCBe or 25Mhz xtal */
+			; /* nothing to do */
+		} else {
+			/* HVR1850 or 50MHz xtal */
+			cx25840_write(client, 0x2, 0x71);
+		}
 		cx25840_write4(client, 0x11c, 0x01d1744c);
 		cx25840_write4(client, 0x118, 0x00000416);
 		cx25840_write4(client, 0x404, 0x0010253e);
@@ -544,9 +554,15 @@ static void cx23885_initialize(struct i2c_client *client)
 	/* HVR1850 */
 	switch (state->id) {
 	case CX23888_AV:
-		/* 888/HVR1250 specific */
-		cx25840_write4(client, 0x10c, 0x13333333);
-		cx25840_write4(client, 0x108, 0x00000515);
+		if (clk_freq == 25000000) {
+			/* 888/ImpactVCBe or 25MHz xtal */
+			cx25840_write4(client, 0x10c, 0x01b6db7b);
+			cx25840_write4(client, 0x108, 0x00000512);
+		} else {
+			/* 888/HVR1250 or 50MHz xtal */
+			cx25840_write4(client, 0x10c, 0x13333333);
+			cx25840_write4(client, 0x108, 0x00000515);
+		}
 		break;
 	default:
 		cx25840_write4(client, 0x10c, 0x002be2c9);
@@ -576,7 +592,7 @@ static void cx23885_initialize(struct i2c_client *client)
 		 * 368.64 MHz before post divide
 		 * 122.88 MHz / 0xa = 12.288 MHz
 		 */
-		/* HVR1850  or 50MHz xtal */
+		/* HVR1850 or 50MHz xtal or 25MHz xtal */
 		cx25840_write4(client, 0x114, 0x017dbf48);
 		cx25840_write4(client, 0x110, 0x000a030e);
 		break;
Signature · 1 line
2.7.4
author
#2 lore raw

PATCH 2/4 cx23885: change 887/888 default to 888

In reply to Brad Love

Proper cx2388x chip type is detected in cx25840 probe, the clock rate is untouched however in probe. The cx25840 only checks for non default clock values for 888 and provides custom settings for 25MHz 888. This change ensures that cx23888 chips with default 50MHz crystals will not get configured as if they have 25MHz crystals. A cx23887 board will continue to be configured for 25Hz crystal as there is no custom clock support included for it.

---
 drivers/media/pci/cx23885/cx23885-core.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/media/pci/cx23885/cx23885-core.c +3 -3
index 8afddd6..2c76a02 100644
@@ -839,10 +839,10 @@ static int cx23885_dev_setup(struct cx23885_dev *dev)
 
 	/* Configure the internal memory */
 	if (dev->pci->device == 0x8880) {
-		/* Could be 887 or 888, assume a default */
-		dev->bridge = CX23885_BRIDGE_887;
+		/* Could be 887 or 888, assume an 888 default */
+		dev->bridge = CX23885_BRIDGE_888;
 		/* Apply a sensible clock frequency for the PCIe bridge */
-		dev->clk_freq = 25000000;
+		dev->clk_freq = 50000000;
 		dev->sram_channels = cx23887_sram_channels;
 	} else
 	if (dev->pci->device == 0x8852) {
Signature · 1 line
2.7.4
author
#3 lore raw

PATCH 3/4 cx23885: Set subdev host data to clk_freq pointer

In reply to Brad Love

Currently clk_freq is ignored entirely, because the cx235840 driver configures the xtal at the chip defaults. This is an issue if a board is produced with a non-default frequency crystal. If clk_freq is not zero the cx25840 will attempt to use the setting provided, or fall back to defaults otherwise.

---
 drivers/media/pci/cx23885/cx23885-cards.c | 4 ++++
 1 file changed, 4 insertions(+)
drivers/media/pci/cx23885/cx23885-cards.c +4 -0
index bd28f9c..45fd2e7 100644
@@ -2346,6 +2346,10 @@ void cx23885_card_setup(struct cx23885_dev *dev)
 				&dev->i2c_bus[2].i2c_adap,
 				"cx25840", 0x88 >> 1, NULL);
 		if (dev->sd_cx25840) {
+			/* set host data for clk_freq configuration */
+			v4l2_set_subdev_hostdata(dev->sd_cx25840,
+						&dev->clk_freq);
+
 			dev->sd_cx25840->grp_id = CX23885_HW_AV_CORE;
 			v4l2_subdev_call(dev->sd_cx25840, core, load_fw);
 		}
Signature · 1 line
2.7.4
author
#4 lore raw

PATCH 4/4 cx23885: Override 888 ImpactVCBe crystal frequency

In reply to Brad Love

Hauppauge produced a revision of ImpactVCBe using an 888, with a 25MHz crystal, instead of using the default third overtone 50Mhz crystal. This overrides that frequency so that the cx25840 is properly configured.

---
 drivers/media/pci/cx23885/cx23885-core.c | 10 ++++++++++
 1 file changed, 10 insertions(+)
drivers/media/pci/cx23885/cx23885-core.c +10 -0
index 2c76a02..101904b 100644
@@ -881,6 +881,16 @@ static int cx23885_dev_setup(struct cx23885_dev *dev)
 	if (cx23885_boards[dev->board].clk_freq > 0)
 		dev->clk_freq = cx23885_boards[dev->board].clk_freq;
 
+	if (dev->board == CX23885_BOARD_HAUPPAUGE_IMPACTVCBE &&
+		dev->pci->subsystem_device == 0x7137) {
+		/* Hauppauge ImpactVCBe device ID 0x7137 is populated
+		 * with an 888, and a 25Mhz crystal, instead of the
+		 * usual third overtone 50Mhz. The default clock rate must
+		 * be overridden so the cx25840 is properly configured
+		 */
+		dev->clk_freq = 25000000;
+	}
+
 	dev->pci_bus  = dev->pci->bus->number;
 	dev->pci_slot = PCI_SLOT(dev->pci->devfn);
 	cx23885_irq_add(dev, 0x001f00);
Signature · 1 line
2.7.4