Skip to contentSkip to conversation

Add initial support for Broadcom Cygnus SoC

PATCH Superseded Jonathan Richardson 12 participants 92 messages Sep 16, 2014 – Mar 12, 2015 3 messages not in the archive

Subsystems (13)
lore
Share & tools
lore

A message that is not in the archive (sent off-list or not yet received): Jonathan Richardson <[email protected]

#1 lore raw

cover Add initial support for Broadcom Cygnus SoC

Hi,

This patchset contains initial support for Broadcom's Cygnus SoC based on our iProc architecture. Initial support is minimal and includes just the mach platform code, clock driver, and a basic device tree configuration. Peripheral drivers will be submitted soon, as will device tree configurations for other Cygnus board variants.

Jonathan Richardson (5):
ARM: cygnus: Initial support for Broadcom Cygnus SoC
clk: Clock driver support for Broadcom Cygnus SoC
dt-bindings: Document Broadcom Cygnus SoC and clock driver
ARM: dts: Enable Broadcom Cygnus SoC
ARM: cygnus defconfig : Initial defconfig for Broadcom Cygnus SoC
MAINTAINERS: Entry for Cygnus/iproc arm architecture and clock
drivers

 Documentation/devicetree/bindings/arm/cygnus.txt   |   12 +
 .../devicetree/bindings/clock/clk-cygnus.txt       |  121 ++
 .../devicetree/bindings/clock/clk-iproc.txt        |   48 +
 MAINTAINERS                                        |   21 +
 arch/arm/boot/dts/Makefile                         |    1 +
 arch/arm/boot/dts/bcm-cygnus.dtsi                  |  344 ++++++
 arch/arm/boot/dts/bcm911360_entphn.dts             |   17 +
 arch/arm/configs/bcm_cygnus_defconfig              |  223 ++++
 arch/arm/mach-bcm/Kconfig                          |   34 +
 arch/arm/mach-bcm/Makefile                         |    3 +
 arch/arm/mach-bcm/board_bcm_cygnus.c               |  166 +++
 drivers/clk/Makefile                               |    1 +
 drivers/clk/bcm/Makefile                           |    2 +
 drivers/clk/bcm/clk-cygnus.c                       | 1179 ++++++++++++++++++++
 drivers/clk/bcm/clk-iproc.c                        |  446 ++++++++
 15 files changed, 2618 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/cygnus.txt
 create mode 100644 Documentation/devicetree/bindings/clock/clk-cygnus.txt
 create mode 100644 Documentation/devicetree/bindings/clock/clk-iproc.txt
 create mode 100644 arch/arm/boot/dts/bcm-cygnus.dtsi
 create mode 100644 arch/arm/boot/dts/bcm911360_entphn.dts
 create mode 100644 arch/arm/configs/bcm_cygnus_defconfig
 create mode 100644 arch/arm/mach-bcm/board_bcm_cygnus.c
 create mode 100644 drivers/clk/bcm/clk-cygnus.c
 create mode 100644 drivers/clk/bcm/clk-iproc.c
Signature · 1 line
1.7.9.5
#2 lore raw

PATCH 1/6 ARM: cygnus: Initial support for Broadcom Cygnus SoC

Adds initial support for the Cygnus SoC based on Broadcom’s iProc series.

---
 arch/arm/mach-bcm/Kconfig            |   34 +++++++
 arch/arm/mach-bcm/Makefile           |    3 +
 arch/arm/mach-bcm/board_bcm_cygnus.c |  166 ++++++++++++++++++++++++++++++++++
 3 files changed, 203 insertions(+)
 create mode 100644 arch/arm/mach-bcm/board_bcm_cygnus.c
arch/arm/mach-bcm/Kconfig +34 -0
index fc93800..58e0f20 100644
@@ -5,6 +5,40 @@ menuconfig ARCH_BCM
 
 if ARCH_BCM
 
+config ARCH_BCM_IPROC
+	bool "Broadcom ARMv7 iProc boards" if ARCH_MULTI_V7
+	select ARM_GIC
+	select CACHE_L2X0
+	select HAVE_ARM_SCU if SMP
+	select HAVE_ARM_TWD if LOCAL_TIMERS
+	select HAVE_CLK
+	select CLKSRC_OF
+	select CLKSRC_MMIO
+	select LOCAL_TIMERS if SMP
+	select GENERIC_CLOCKEVENTS_BUILD
+	select GENERIC_CLOCKEVENTS
+	select ARM_GLOBAL_TIMER
+	select ARCH_REQUIRE_GPIOLIB
+	select ARM_AMBA
+	select PINCTRL
+	select DEBUG_UART_8250
+	help
+	  This enables support for systems based on Broadcom IPROC architected SoCs.
+	  The IPROC complex contains one or more ARM CPUs along with common
+	  core periperals. Application specific SoCs are created by adding a
+	  uArchitecture containing peripherals outside of the IPROC complex.
+	  Currently supported SoCs are Cygnus.
+
+menu "iProc SoC based Machine types"
+	depends on ARCH_BCM_IPROC
+
+	config ARCH_BCM_CYGNUS
+		bool "Support Broadcom Cygnus board"
+		select USB_ARCH_HAS_EHCI if USB_SUPPORT
+		help
+		  Support for Broadcom Cygnus SoC.
+endmenu
+
 config ARCH_BCM_MOBILE
 	bool "Broadcom Mobile SoC Support" if ARCH_MULTI_V7
 	select ARCH_REQUIRE_GPIOLIB
arch/arm/mach-bcm/Makefile +3 -0
index b19a396..dd14a10 100644
@@ -10,6 +10,9 @@
 # of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU General Public License for more details.
 
+# Cygnus
+obj-$(CONFIG_ARCH_BCM_CYGNUS) +=  board_bcm_cygnus.o
+
 # BCM281XX
 obj-$(CONFIG_ARCH_BCM_281XX)	+= board_bcm281xx.o
 
arch/arm/mach-bcm/board_bcm_cygnus.c new file +166 -0

166 lines not on this page · raw message

Signature · 1 line
1.7.9.5
#3 lore raw

Re: [PATCH 1/6] ARM: cygnus: Initial support for Broadcom Cygnus SoC

Quoted 11 lines · Jonathan Richardson

Adds initial support for the Cygnus SoC based on Broadcom?s iProc series.

---
 arch/arm/mach-bcm/Kconfig            |   34 +++++++
 arch/arm/mach-bcm/Makefile           |    3 +
 arch/arm/mach-bcm/board_bcm_cygnus.c |  166 ++++++++++++++++++++++++++++++++++

Is Cygnus an SoC or a board?

Quoted 8 lines
 3 files changed, 203 insertions(+)
 create mode 100644 arch/arm/mach-bcm/board_bcm_cygnus.c
arch/arm/mach-bcm/Kconfig +0 -0
index fc93800..58e0f20 100644

arch/arm/mach-bcm/Kconfig menuconfig ARCH_BCM · line 12

Quoted 8 lines
arch/arm/mach-bcm/Kconfig +5 -0
@@ -5,6 +5,40 @@ menuconfig ARCH_BCM
 
 if ARCH_BCM
 
+config ARCH_BCM_IPROC
+	bool "Broadcom ARMv7 iProc boards" if ARCH_MULTI_V7
+	select ARM_GIC
+	select CACHE_L2X0
+	select HAVE_ARM_SCU if SMP

I didn't spot any SMP code in this series.

arch/arm/mach-bcm/Kconfig menuconfig ARCH_BCM · line 18

Quoted 6 lines
arch/arm/mach-bcm/Kconfig +6 -0
+	select HAVE_ARM_TWD if LOCAL_TIMERS
+	select HAVE_CLK
+	select CLKSRC_OF
+	select CLKSRC_MMIO
+	select LOCAL_TIMERS if SMP
+	select GENERIC_CLOCKEVENTS_BUILD

You don't need to select this.

Quoted 46 lines
arch/arm/mach-bcm/Kconfig +23 -0
+	select GENERIC_CLOCKEVENTS
+	select ARM_GLOBAL_TIMER
+	select ARCH_REQUIRE_GPIOLIB
+	select ARM_AMBA
+	select PINCTRL
+	select DEBUG_UART_8250
+	help
+	  This enables support for systems based on Broadcom IPROC architected SoCs.
+	  The IPROC complex contains one or more ARM CPUs along with common
+	  core periperals. Application specific SoCs are created by adding a
+	  uArchitecture containing peripherals outside of the IPROC complex.
+	  Currently supported SoCs are Cygnus.
+
+menu "iProc SoC based Machine types"
+	depends on ARCH_BCM_IPROC
+
+	config ARCH_BCM_CYGNUS
+		bool "Support Broadcom Cygnus board"
+		select USB_ARCH_HAS_EHCI if USB_SUPPORT
+		help
+		  Support for Broadcom Cygnus SoC.
+endmenu
+
 config ARCH_BCM_MOBILE
 	bool "Broadcom Mobile SoC Support" if ARCH_MULTI_V7
 	select ARCH_REQUIRE_GPIOLIB
arch/arm/mach-bcm/Makefile +3 -0
index b19a396..dd14a10 100644
@@ -10,6 +10,9 @@
 # of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU General Public License for more details.
 
+# Cygnus
+obj-$(CONFIG_ARCH_BCM_CYGNUS) +=  board_bcm_cygnus.o
+
 # BCM281XX
 obj-$(CONFIG_ARCH_BCM_281XX)	+= board_bcm281xx.o
 
arch/arm/mach-bcm/board_bcm_cygnus.c new file +0 -0
new file mode 100644
index 0000000..d67555a

arch/arm/mach-bcm/board_bcm_cygnus.c line 7

Quoted 7 lines
arch/arm/mach-bcm/board_bcm_cygnus.c new file +7 -0
@@ -0,0 +1,166 @@
+/*
+ * Copyright 2014 Broadcom Corporation.  All rights reserved.
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2, available at
+ * http://www.broadcom.com/licenses/GPLv2.php (the "GPL").

Why don't we point at the gnu.org copy as we do elsewhere?

arch/arm/mach-bcm/board_bcm_cygnus.c line 20

Quoted 13 lines
arch/arm/mach-bcm/board_bcm_cygnus.c new file +13 -0
+ */
+
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/clocksource.h>
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/proc-fns.h>
+#include <asm/hardware/cache-l2x0.h>
+
+#define CRMU_MAIL_BOX1      0x03024028

Please don't hard code addresses in board files.

arch/arm/mach-bcm/board_bcm_cygnus.c line 28

Quoted 8 lines
arch/arm/mach-bcm/board_bcm_cygnus.c new file +8 -0
+#define CRMU_SOFT_RESET_CMD 0xFFFFFFFF
+
+/* CRU_RESET register */
+static void * __iomem crmu_mail_box1_reg;
+
+#ifdef CONFIG_NEON
+
+#define CRU_BASE                  0x1800e000

Another hard coded address that needs to go.

Quoted 8 lines
arch/arm/mach-bcm/board_bcm_cygnus.c new file +8 -0
+#define CRU_SIZE                  0x34
+#define CRU_CONTROL_OFFSET        0x0
+#define CRU_PWRDWN_EN_OFFSET      0x4
+#define CRU_PWRDWN_STATUS_OFFSET  0x8
+#define CRU_NEON0_HW_RESET  6
+#define CRU_CLAMP_ON_NEON0  20
+#define CRU_PWRONIN_NEON0   21
+#define CRU_PWRONOUT_NEON0  21

arch/arm/mach-bcm/board_bcm_cygnus.c line 46

Quoted 10 lines
arch/arm/mach-bcm/board_bcm_cygnus.c new file +10 -0
+#define CRU_PWROKIN_NEON0   22
+#define CRU_PWROKOUT_NEON0  22
+#define CRU_STATUS_DELAY_NS 500
+#define CRU_MAX_RETRY_COUNT 10
+#define CRU_RETRY_INTVL_US  1
+
+/* Power up the NEON/VFPv3 block. */
+static void bcm_cygnus_powerup_neon(void)
+{
+	void * __iomem cru_base = ioremap_nocache(CRU_BASE, CRU_SIZE);

Why not plain ioremap?

arch/arm/mach-bcm/board_bcm_cygnus.c line 49

Quoted 3 lines
arch/arm/mach-bcm/board_bcm_cygnus.c new file +3 -0
+	u32 reg, i;
+
+	BUG_ON(!cru_base);

This seems a little extreme. Can;t we continue without NEON?

Quoted 15 lines
arch/arm/mach-bcm/board_bcm_cygnus.c new file +15 -0
+
+	/* De-assert the neon hardware block reset */
+	reg = readl(cru_base + CRU_CONTROL_OFFSET);
+	reg &= ~(1 << CRU_NEON0_HW_RESET);
+	writel(reg, cru_base + CRU_CONTROL_OFFSET);
+
+	/* Assert the power ON register bit */
+	reg = readl(cru_base + CRU_PWRDWN_EN_OFFSET);
+	reg |= (1 << CRU_PWRONIN_NEON0);
+	writel(reg, cru_base + CRU_PWRDWN_EN_OFFSET);
+
+	/*
+	 * Wait up to 10 usec in 1 usec increments for the
+	 * status register to acknowledge the power ON assert
+	 */

arch/arm/mach-bcm/board_bcm_cygnus.c line 74

Quoted 10 lines
arch/arm/mach-bcm/board_bcm_cygnus.c new file +10 -0
+	for (i = 0; i < CRU_MAX_RETRY_COUNT; i++) {
+		reg = readl(cru_base + CRU_PWRDWN_STATUS_OFFSET);
+		if (reg & CRU_PWRONOUT_NEON0)
+			break;
+
+		udelay(CRU_RETRY_INTVL_US);
+	}
+
+	if (i == CRU_MAX_RETRY_COUNT)
+		panic("NEON power ON register not acknowledged\n");

We can't just disable NEON if we fail to enable the HW block?

[...]

arch/arm/mach-bcm/board_bcm_cygnus.c line 125

Quoted 7 lines
arch/arm/mach-bcm/board_bcm_cygnus.c new file +7 -0
+static void __init bcm_cygnus_timer_init(void)
+{
+	/* Initialize all clocks declared in device tree */
+	of_clk_init(NULL);
+
+	clocksource_of_init();
+}

If you take a look at time_init in arch/arm/kernel/time.c you'll see this is redundant.

Get rid of this.

arch/arm/mach-bcm/board_bcm_cygnus.c line 133

Quoted 8 lines
arch/arm/mach-bcm/board_bcm_cygnus.c new file +8 -0
+
+static void __init bcm_cygnus_init(void)
+{
+	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+
+	l2x0_of_init(0, ~0UL);
+
+	crmu_mail_box1_reg = ioremap_nocache(CRMU_MAIL_BOX1, SZ_4);

Why not plain ioremap?

arch/arm/mach-bcm/board_bcm_cygnus.c line 134

Quoted 1 line
arch/arm/mach-bcm/board_bcm_cygnus.c new file +1 -0
+	BUG_ON(!crmu_mail_box1_reg);

We only use this for reboot later on, so do we need to blow up so spectacularly in this case?

Quoted 9 lines
arch/arm/mach-bcm/board_bcm_cygnus.c new file +9 -0
+
+#ifdef CONFIG_NEON
+	bcm_cygnus_powerup_neon();
+#endif
+}
+
+/*
+ * Reset the system
+ */

arch/arm/mach-bcm/board_bcm_cygnus.c line 153

Quoted 10 lines
arch/arm/mach-bcm/board_bcm_cygnus.c new file +10 -0
+void bcm_cygnus_restart(enum reboot_mode mode, const char *cmd)
+{
+	/* Send reset command to M0 via Mailbox. */
+	writel(CRMU_SOFT_RESET_CMD, crmu_mail_box1_reg);
+	iounmap(crmu_mail_box1_reg);
+
+	/* Wait for M0 to reset the chip. */
+	while (1)
+		cpu_do_idle();
+}

This doesn't have to live in the machine descriptor. It could be a separate driver.

Thanks,
Mark.

#4 lore raw

Re: [PATCH 1/6] ARM: cygnus: Initial support for Broadcom Cygnus SoC

Hi Mark,

Thanks for the feedback.

Quoted 13 lines · Mark Rutland
Quoted 11 lines · Jonathan Richardson

Adds initial support for the Cygnus SoC based on Broadcom?s iProc series.

---
 arch/arm/mach-bcm/Kconfig            |   34 +++++++
 arch/arm/mach-bcm/Makefile           |    3 +
 arch/arm/mach-bcm/board_bcm_cygnus.c |  166 ++++++++++++++++++++++++++++++++++
Quoted 1 line

Is Cygnus an SoC or a board?

SoC. I will rename it to bcm_cygnus.c

Quoted 12 lines
Quoted 12 lines
 3 files changed, 203 insertions(+)
 create mode 100644 arch/arm/mach-bcm/board_bcm_cygnus.c
arch/arm/mach-bcm/Kconfig +0 -0
index fc93800..58e0f20 100644
@@ -5,6 +5,40 @@ menuconfig ARCH_BCM
 
 if ARCH_BCM
 
Quoted 7 lines

arch/arm/mach-bcm/Kconfig menuconfig ARCH_BCM · line 12

Quoted 5 lines
arch/arm/mach-bcm/Kconfig +5 -0
+config ARCH_BCM_IPROC
+	bool "Broadcom ARMv7 iProc boards" if ARCH_MULTI_V7
+	select ARM_GIC
+	select CACHE_L2X0
+	select HAVE_ARM_SCU if SMP

I didn't spot any SMP code in this series.

It's single core. Will fix.

Quoted 9 lines

arch/arm/mach-bcm/Kconfig menuconfig ARCH_BCM · line 18

Quoted 7 lines
arch/arm/mach-bcm/Kconfig +6 -0
+	select HAVE_ARM_TWD if LOCAL_TIMERS
+	select HAVE_CLK
+	select CLKSRC_OF
+	select CLKSRC_MMIO
+	select LOCAL_TIMERS if SMP
+	select GENERIC_CLOCKEVENTS_BUILD

You don't need to select this.

Will fix.

Quoted 41 lines
Quoted 41 lines
arch/arm/mach-bcm/Kconfig +23 -0
+	select GENERIC_CLOCKEVENTS
+	select ARM_GLOBAL_TIMER
+	select ARCH_REQUIRE_GPIOLIB
+	select ARM_AMBA
+	select PINCTRL
+	select DEBUG_UART_8250
+	help
+	  This enables support for systems based on Broadcom IPROC architected SoCs.
+	  The IPROC complex contains one or more ARM CPUs along with common
+	  core periperals. Application specific SoCs are created by adding a
+	  uArchitecture containing peripherals outside of the IPROC complex.
+	  Currently supported SoCs are Cygnus.
+
+menu "iProc SoC based Machine types"
+	depends on ARCH_BCM_IPROC
+
+	config ARCH_BCM_CYGNUS
+		bool "Support Broadcom Cygnus board"
+		select USB_ARCH_HAS_EHCI if USB_SUPPORT
+		help
+		  Support for Broadcom Cygnus SoC.
+endmenu
+
 config ARCH_BCM_MOBILE
 	bool "Broadcom Mobile SoC Support" if ARCH_MULTI_V7
 	select ARCH_REQUIRE_GPIOLIB
arch/arm/mach-bcm/Makefile +3 -0
index b19a396..dd14a10 100644
@@ -10,6 +10,9 @@
 # of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU General Public License for more details.
 
+# Cygnus
+obj-$(CONFIG_ARCH_BCM_CYGNUS) +=  board_bcm_cygnus.o
+
 # BCM281XX
 obj-$(CONFIG_ARCH_BCM_281XX)	+= board_bcm281xx.o
 
Quoted 16 lines

arch/arm/mach-bcm/board_bcm_cygnus.c line 7

Quoted 13 lines
arch/arm/mach-bcm/board_bcm_cygnus.c new file +7 -0
new file mode 100644
index 0000000..d67555a
@@ -0,0 +1,166 @@
+/*
+ * Copyright 2014 Broadcom Corporation.  All rights reserved.
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2, available at
+ * http://www.broadcom.com/licenses/GPLv2.php (the "GPL").

Why don't we point at the gnu.org copy as we do elsewhere?

I am enquiring.

Quoted 7 lines
Quoted 7 lines
arch/arm/mach-bcm/board_bcm_cygnus.c new file +7 -0
+ */
+
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/clocksource.h>
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
Quoted 8 lines

arch/arm/mach-bcm/board_bcm_cygnus.c line 20

Quoted 6 lines
arch/arm/mach-bcm/board_bcm_cygnus.c new file +6 -0
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/proc-fns.h>
+#include <asm/hardware/cache-l2x0.h>
+
+#define CRMU_MAIL_BOX1      0x03024028

Please don't hard code addresses in board files.

Would a separate header file be sufficient? I notice this approach was taken in vexpress A9x4 (out of date?). I couldn't find a home for them in dt and I don't think anyone would want to see them there. They shouldn't ever change.

We have a couple of more addresses that will be added in future revisions of this file for DMA and LCD (for reset/power up procedures), as those drivers are added.

Quoted 33 lines

arch/arm/mach-bcm/board_bcm_cygnus.c line 28

Quoted 9 lines
arch/arm/mach-bcm/board_bcm_cygnus.c new file +8 -0
+#define CRMU_SOFT_RESET_CMD 0xFFFFFFFF
+
+/* CRU_RESET register */
+static void * __iomem crmu_mail_box1_reg;
+
+#ifdef CONFIG_NEON
+
+#define CRU_BASE                  0x1800e000

Another hard coded address that needs to go.

Quoted 8 lines
arch/arm/mach-bcm/board_bcm_cygnus.c new file +8 -0
+#define CRU_SIZE                  0x34
+#define CRU_CONTROL_OFFSET        0x0
+#define CRU_PWRDWN_EN_OFFSET      0x4
+#define CRU_PWRDWN_STATUS_OFFSET  0x8
+#define CRU_NEON0_HW_RESET  6
+#define CRU_CLAMP_ON_NEON0  20
+#define CRU_PWRONIN_NEON0   21
+#define CRU_PWRONOUT_NEON0  21

arch/arm/mach-bcm/board_bcm_cygnus.c line 46

Quoted 10 lines
arch/arm/mach-bcm/board_bcm_cygnus.c new file +10 -0
+#define CRU_PWROKIN_NEON0   22
+#define CRU_PWROKOUT_NEON0  22
+#define CRU_STATUS_DELAY_NS 500
+#define CRU_MAX_RETRY_COUNT 10
+#define CRU_RETRY_INTVL_US  1
+
+/* Power up the NEON/VFPv3 block. */
+static void bcm_cygnus_powerup_neon(void)
+{
+	void * __iomem cru_base = ioremap_nocache(CRU_BASE, CRU_SIZE);

Why not plain ioremap?

Quoted 5 lines

arch/arm/mach-bcm/board_bcm_cygnus.c line 49

Quoted 3 lines
arch/arm/mach-bcm/board_bcm_cygnus.c new file +3 -0
+	u32 reg, i;
+
+	BUG_ON(!cru_base);

This seems a little extreme. Can;t we continue without NEON?

We can yes. The reason for this was to prevent difficult troubleshooting if it ever failed. But a WARN_ON would probably be sufficient.

Quoted 31 lines
Quoted 16 lines
arch/arm/mach-bcm/board_bcm_cygnus.c new file +15 -0
+
+	/* De-assert the neon hardware block reset */
+	reg = readl(cru_base + CRU_CONTROL_OFFSET);
+	reg &= ~(1 << CRU_NEON0_HW_RESET);
+	writel(reg, cru_base + CRU_CONTROL_OFFSET);
+
+	/* Assert the power ON register bit */
+	reg = readl(cru_base + CRU_PWRDWN_EN_OFFSET);
+	reg |= (1 << CRU_PWRONIN_NEON0);
+	writel(reg, cru_base + CRU_PWRDWN_EN_OFFSET);
+
+	/*
+	 * Wait up to 10 usec in 1 usec increments for the
+	 * status register to acknowledge the power ON assert
+	 */

arch/arm/mach-bcm/board_bcm_cygnus.c line 74

Quoted 10 lines
arch/arm/mach-bcm/board_bcm_cygnus.c new file +10 -0
+	for (i = 0; i < CRU_MAX_RETRY_COUNT; i++) {
+		reg = readl(cru_base + CRU_PWRDWN_STATUS_OFFSET);
+		if (reg & CRU_PWRONOUT_NEON0)
+			break;
+
+		udelay(CRU_RETRY_INTVL_US);
+	}
+
+	if (i == CRU_MAX_RETRY_COUNT)
+		panic("NEON power ON register not acknowledged\n");

We can't just disable NEON if we fail to enable the HW block?

[...]

Quoted 10 lines

arch/arm/mach-bcm/board_bcm_cygnus.c line 125

Quoted 7 lines
arch/arm/mach-bcm/board_bcm_cygnus.c new file +7 -0
+static void __init bcm_cygnus_timer_init(void)
+{
+	/* Initialize all clocks declared in device tree */
+	of_clk_init(NULL);
+
+	clocksource_of_init();
+}

If you take a look at time_init in arch/arm/kernel/time.c you'll see this is redundant.

Will fix.

Quoted 13 lines

Get rid of this.

arch/arm/mach-bcm/board_bcm_cygnus.c line 133

Quoted 8 lines
arch/arm/mach-bcm/board_bcm_cygnus.c new file +8 -0
+
+static void __init bcm_cygnus_init(void)
+{
+	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+
+	l2x0_of_init(0, ~0UL);
+
+	crmu_mail_box1_reg = ioremap_nocache(CRMU_MAIL_BOX1, SZ_4);

Why not plain ioremap?

I will change them to ioremap.

Quoted 5 lines

arch/arm/mach-bcm/board_bcm_cygnus.c line 134

Quoted 2 lines
arch/arm/mach-bcm/board_bcm_cygnus.c new file +1 -0
+	BUG_ON(!crmu_mail_box1_reg);

We only use this for reboot later on, so do we need to blow up so spectacularly in this case?

Will fix.

Quoted 15 lines
Quoted 15 lines
arch/arm/mach-bcm/board_bcm_cygnus.c new file +14 -0
+
+#ifdef CONFIG_NEON
+	bcm_cygnus_powerup_neon();
+#endif
+}
+
+/*
+ * Reset the system
+ */
+void bcm_cygnus_restart(enum reboot_mode mode, const char *cmd)
+{
+	/* Send reset command to M0 via Mailbox. */
+	writel(CRMU_SOFT_RESET_CMD, crmu_mail_box1_reg);
+	iounmap(crmu_mail_box1_reg);
Quoted 8 lines

arch/arm/mach-bcm/board_bcm_cygnus.c line 153

Quoted 5 lines
arch/arm/mach-bcm/board_bcm_cygnus.c new file +5 -0
+
+	/* Wait for M0 to reset the chip. */
+	while (1)
+		cpu_do_idle();
+}

This doesn't have to live in the machine descriptor. It could be a separate driver.

I'm not sure if a separate driver is the way we want to go with this right now. If we had more of this M0 communication then I would agree, and we may in the future. But if we don't then there would just be a reset handler in the driver. If more interaction and a driver is required we would move this to a driver.

Was your suggestion more related to the hard coded addresses in this file or the mysterious nature of the reset procedure?

Quoted 4 lines

Thanks,
Mark.

Thanks.
Jon

#5 lore raw

PATCH 2/6 clk: Clock driver support for Broadcom Cygnus SoC

In reply to Jonathan Richardson

The iProc clock driver controls PLL's common across iProc chips. The cygnus driver controls cygnus specific features and variations.

---
 drivers/clk/Makefile         |    1 +
 drivers/clk/bcm/Makefile     |    2 +
 drivers/clk/bcm/clk-cygnus.c | 1179 ++++++++++++++++++++++++++++++++++++++++++
 drivers/clk/bcm/clk-iproc.c  |  446 ++++++++++++++++
 4 files changed, 1628 insertions(+)
 create mode 100644 drivers/clk/bcm/clk-cygnus.c
 create mode 100644 drivers/clk/bcm/clk-iproc.c
drivers/clk/Makefile +1 -0
index f537a0b..8ac0a31 100644
@@ -37,6 +37,7 @@ obj-$(CONFIG_ARCH_VT8500)		+= clk-vt8500.o
 obj-$(CONFIG_COMMON_CLK_WM831X)		+= clk-wm831x.o
 obj-$(CONFIG_COMMON_CLK_XGENE)		+= clk-xgene.o
 obj-$(CONFIG_COMMON_CLK_AT91)		+= at91/
+obj-$(CONFIG_ARCH_BCM_IPROC)	+= bcm/
 obj-$(CONFIG_ARCH_BCM_MOBILE)		+= bcm/
 obj-$(CONFIG_ARCH_BERLIN)		+= berlin/
 obj-$(CONFIG_ARCH_HI3xxx)		+= hisilicon/
drivers/clk/bcm/Makefile +2 -0
index 6297d05..f803919 100644
@@ -2,3 +2,5 @@ obj-$(CONFIG_CLK_BCM_KONA)	+= clk-kona.o
 obj-$(CONFIG_CLK_BCM_KONA)	+= clk-kona-setup.o
 obj-$(CONFIG_CLK_BCM_KONA)	+= clk-bcm281xx.o
 obj-$(CONFIG_CLK_BCM_KONA)	+= clk-bcm21664.o
+obj-$(CONFIG_ARCH_BCM_IPROC)	+= clk-iproc.o
+obj-$(CONFIG_ARCH_BCM_CYGNUS)	+= clk-cygnus.o
drivers/clk/bcm/clk-cygnus.c new file +1179 -0

1,179 lines not on this page · raw message

drivers/clk/bcm/clk-iproc.c new file +446 -0

446 lines not on this page · raw message

Signature · 1 line
1.7.9.5
#6 lore raw

Re: [PATCH 2/6] clk: Clock driver support for Broadcom Cygnus SoC

Quoted 1 line · Jonathan Richardson

The iProc clock driver controls PLL's common across iProc chips. The

Nit: s/PLL's/PLLs/ (we aren't greengrocers [1]).

Quoted 14 lines

cygnus driver controls cygnus specific features and variations.

---
 drivers/clk/Makefile         |    1 +
 drivers/clk/bcm/Makefile     |    2 +
 drivers/clk/bcm/clk-cygnus.c | 1179 ++++++++++++++++++++++++++++++++++++++++++
 drivers/clk/bcm/clk-iproc.c  |  446 ++++++++++++++++
 4 files changed, 1628 insertions(+)
 create mode 100644 drivers/clk/bcm/clk-cygnus.c
 create mode 100644 drivers/clk/bcm/clk-iproc.c

[...]

drivers/clk/bcm/clk-cygnus.c line 173

Quoted 11 lines
drivers/clk/bcm/clk-cygnus.c new file +11 -0
+/*
+ * Enable clocks controlled through the top clock gating control.
+ *
+ * @param state true = enable clock, false = disable clock
+ */
+static void cygnus_clkgate_enable(void __iomem *clkgate_reg,
+       enum cygnus_top_clk_gating_ctrl_offsets offset, bool state)
+{
+       u32 val = readl(clkgate_reg);
+
+       /* Enable or disable the clock. */

This function is misnamed if it does both, and 'state' is not a very descriptive name.

Quoted 18 lines
drivers/clk/bcm/clk-cygnus.c new file +18 -0
+       if (state)
+               val |= 1 << offset;
+       else
+               val &= ~(1 << offset);
+
+       writel(val, clkgate_reg);
+}
+
+/*
+ * Powers on/off the MIPI GENPLL using CRMU_PLL_AON_CTRL register.
+ *
+ * @param state true to power on PLL, false to power off
+ */
+static void cygnus_mipi_genpll_poweron(void __iomem *pll_ctrl_reg,
+       bool state)
+{
+       u32 val;
+       u32 pll_ldo_on = ((1 << ASIU_MIPI_GENPLL_PWRON_SHIFT) |

drivers/clk/bcm/clk-cygnus.c line 201

Quoted 10 lines
drivers/clk/bcm/clk-cygnus.c new file +10 -0
+               (1 << ASIU_MIPI_GENPLL_PWRON_PLL_SHIFT) |
+               (1 << ASIU_MIPI_GENPLL_PWRON_BG_SHIFT)  |
+               (1 << ASIU_MIPI_GENPLL_PWRON_LDO_SHIFT));
+
+       val = readl(pll_ctrl_reg);
+
+       /*
+        * Set PLL on/off. Set input isolation mode to 1 when disabled, 0 when
+        * enabled.
+        */

As with cygnus_clkgate_enable, this function is misnamed and 'state' is a confusing parameter name.

Quoted 20 lines
drivers/clk/bcm/clk-cygnus.c new file +20 -0
+       if (state) {
+               val |= pll_ldo_on;
+               val &= ~(1 << ASIU_MIPI_GENPLL_ISO_IN_SHIFT);
+       } else {
+               val &= ~pll_ldo_on;
+               val |= 1 << ASIU_MIPI_GENPLL_ISO_IN_SHIFT;
+       }
+
+       writel(val, pll_ctrl_reg);
+}
+
+/*
+ * Powers on/off the audio PLL using CRMU_PLL_AON_CTRL register.
+ *
+ * @param state true to power on PLL, false to power off
+ */
+static void cygnus_audio_genpll_poweron(void __iomem *pll_ctrl_reg,
+       bool state)
+{
+       u32 val;

drivers/clk/bcm/clk-cygnus.c line 231

Quoted 10 lines
drivers/clk/bcm/clk-cygnus.c new file +10 -0
+       u32 pll_ldo_on = ((1 << ASIU_AUDIO_GENPLL_PWRON_PLL_SHIFT) |
+               (1 << ASIU_AUDIO_GENPLL_PWRON_BG_SHIFT) |
+               (1 << ASIU_AUDIO_GENPLL_PWRON_LDO_SHIFT));
+
+       val = readl(pll_ctrl_reg);
+
+       /*
+        * Set PLL on/off. Set input isolation mode to 1 when disabled, 0 when
+        * enabled.
+        */

Misnamed function, confusing parameter name.

Quoted 10 lines
drivers/clk/bcm/clk-cygnus.c new file +10 -0
+       if (state) {
+               val |= pll_ldo_on;
+               val &= ~(1 << ASIU_AUDIO_GENPLL_ISO_IN);
+       } else {
+               val &= ~pll_ldo_on;
+               val |= 1 << ASIU_AUDIO_GENPLL_ISO_IN;
+       }
+
+       writel(val, pll_ctrl_reg);
+}

[...]

Quoted 21 lines
drivers/clk/bcm/clk-cygnus.c new file +21 -0
+static __init struct clk *cygnus_clock_init(struct device_node *node,
+       const struct clk_ops *ops)
+{
+       u32 channel = 0;
+       struct clk *clk;
+       struct cygnus_clk *cygnus_clk;
+       const char *clk_name = node->name;
+       const char *parent_name;
+       struct clk_init_data init;
+       int rc;
+
+       pr_debug("Clock name %s\n", node->name);
+
+       of_property_read_u32(node, "channel", &channel);
+       cygnus_clk = kzalloc(sizeof(*cygnus_clk), GFP_KERNEL);
+       if (WARN_ON(!cygnus_clk))
+               return NULL;
+
+       cygnus_clk->state = CLK_DISABLED;
+
+       /* Read base address from device tree and map to virtual address. */

drivers/clk/bcm/clk-cygnus.c line 647

Quoted 10 lines
drivers/clk/bcm/clk-cygnus.c new file +10 -0
+       cygnus_clk->regs_base = of_iomap(node, CYGNUS_CLK_BASE_REG);
+       if (WARN_ON(!cygnus_clk->regs_base))
+               goto err_alloc;
+
+       /* Read optional base addresses for PLL control and clock gating. */
+       cygnus_clk->clock_gate_ctrl_reg = of_iomap(node,
+               CYGNUS_CLK_GATE_CTRL_REG);
+       cygnus_clk->pll_ctrl_reg = of_iomap(node, CYGNUS_PLL_CTRL_REG);
+
+       of_property_read_u32(node, "channel", &channel);

Why do we read this twice?

drivers/clk/bcm/clk-cygnus.c line 649

Quoted 2 lines
drivers/clk/bcm/clk-cygnus.c new file +2 -0
+       cygnus_clk->chan = channel;
+       of_property_read_string(node, "clock-output-names", &clk_name);

What happens if this is missing from the dt?

Quoted 37 lines
drivers/clk/bcm/clk-cygnus.c new file +37 -0
+
+       /*
+        * Internal divider is optional and used for PLL derived clocks with
+        * hardcoded dividers.
+        */
+       cygnus_clk->internal_div = CLK_RATE_NO_DIV;
+       of_property_read_u32(node, "div", &cygnus_clk->internal_div);
+
+       init.name = clk_name;
+       init.ops = ops;
+       init.flags = CLK_GET_RATE_NOCACHE;
+       parent_name = of_clk_get_parent_name(node, 0);
+       init.parent_names = &parent_name;
+       init.num_parents = 1;
+
+       cygnus_clk->hw.init = &init;
+
+       clk = clk_register(NULL, &cygnus_clk->hw);
+       if (WARN_ON(IS_ERR(clk)))
+               goto err_unmap;
+
+       rc = of_clk_add_provider(node, of_clk_src_simple_get, clk);
+       if (WARN_ON(IS_ERR_VALUE(rc)))
+               goto err_unregister;
+
+       rc = clk_register_clkdev(clk, clk_name, NULL);
+       if (WARN_ON(IS_ERR_VALUE(rc)))
+               goto err_provider;
+
+       return clk;
+
+err_provider:
+       of_clk_del_provider(node);
+
+err_unregister:
+       clk_unregister(clk);
+

drivers/clk/bcm/clk-cygnus.c line 696

Quoted 10 lines
drivers/clk/bcm/clk-cygnus.c new file +10 -0
+err_unmap:
+       iounmap(cygnus_clk->regs_base);
+       iounmap(cygnus_clk->clock_gate_ctrl_reg);
+       iounmap(cygnus_clk->pll_ctrl_reg);
+
+err_alloc:
+       kfree(cygnus_clk);
+
+       return NULL;
+}

Thanks,
Mark.

[1] http://en.wikipedia.org/wiki/Apostrophe#Superfluous_apostrophes_.28.22greengrocers.27_apostrophes.22.29

#7 lore raw

Re: [PATCH 2/6] clk: Clock driver support for Broadcom Cygnus SoC

Quoted 4 lines · Mark Rutland
Quoted 1 line · Jonathan Richardson

The iProc clock driver controls PLL's common across iProc chips. The

Nit: s/PLL's/PLLs/ (we aren't greengrocers [1]).

Will fix.

Quoted 18 lines
Quoted 15 lines

cygnus driver controls cygnus specific features and variations.

---
 drivers/clk/Makefile         |    1 +
 drivers/clk/bcm/Makefile     |    2 +
 drivers/clk/bcm/clk-cygnus.c | 1179 ++++++++++++++++++++++++++++++++++++++++++
 drivers/clk/bcm/clk-iproc.c  |  446 ++++++++++++++++
 4 files changed, 1628 insertions(+)
 create mode 100644 drivers/clk/bcm/clk-cygnus.c
 create mode 100644 drivers/clk/bcm/clk-iproc.c

[...]

Quoted 14 lines

drivers/clk/bcm/clk-cygnus.c line 173

Quoted 11 lines
drivers/clk/bcm/clk-cygnus.c new file +11 -0
+/*
+ * Enable clocks controlled through the top clock gating control.
+ *
+ * @param state true = enable clock, false = disable clock
+ */
+static void cygnus_clkgate_enable(void __iomem *clkgate_reg,
+       enum cygnus_top_clk_gating_ctrl_offsets offset, bool state)
+{
+       u32 val = readl(clkgate_reg);
+
+       /* Enable or disable the clock. */

This function is misnamed if it does both, and 'state' is not a very descriptive name.

Will fix.

Quoted 24 lines
Quoted 24 lines
drivers/clk/bcm/clk-cygnus.c new file +23 -0
+       if (state)
+               val |= 1 << offset;
+       else
+               val &= ~(1 << offset);
+
+       writel(val, clkgate_reg);
+}
+
+/*
+ * Powers on/off the MIPI GENPLL using CRMU_PLL_AON_CTRL register.
+ *
+ * @param state true to power on PLL, false to power off
+ */
+static void cygnus_mipi_genpll_poweron(void __iomem *pll_ctrl_reg,
+       bool state)
+{
+       u32 val;
+       u32 pll_ldo_on = ((1 << ASIU_MIPI_GENPLL_PWRON_SHIFT) |
+               (1 << ASIU_MIPI_GENPLL_PWRON_PLL_SHIFT) |
+               (1 << ASIU_MIPI_GENPLL_PWRON_BG_SHIFT)  |
+               (1 << ASIU_MIPI_GENPLL_PWRON_LDO_SHIFT));
+
+       val = readl(pll_ctrl_reg);
Quoted 8 lines

drivers/clk/bcm/clk-cygnus.c line 201

Quoted 5 lines
drivers/clk/bcm/clk-cygnus.c new file +5 -0
+
+       /*
+        * Set PLL on/off. Set input isolation mode to 1 when disabled, 0 when
+        * enabled.
+        */

As with cygnus_clkgate_enable, this function is misnamed and 'state' is a confusing parameter name.

Will fix.

Quoted 25 lines
Quoted 25 lines
drivers/clk/bcm/clk-cygnus.c new file +24 -0
+       if (state) {
+               val |= pll_ldo_on;
+               val &= ~(1 << ASIU_MIPI_GENPLL_ISO_IN_SHIFT);
+       } else {
+               val &= ~pll_ldo_on;
+               val |= 1 << ASIU_MIPI_GENPLL_ISO_IN_SHIFT;
+       }
+
+       writel(val, pll_ctrl_reg);
+}
+
+/*
+ * Powers on/off the audio PLL using CRMU_PLL_AON_CTRL register.
+ *
+ * @param state true to power on PLL, false to power off
+ */
+static void cygnus_audio_genpll_poweron(void __iomem *pll_ctrl_reg,
+       bool state)
+{
+       u32 val;
+       u32 pll_ldo_on = ((1 << ASIU_AUDIO_GENPLL_PWRON_PLL_SHIFT) |
+               (1 << ASIU_AUDIO_GENPLL_PWRON_BG_SHIFT) |
+               (1 << ASIU_AUDIO_GENPLL_PWRON_LDO_SHIFT));
+
Quoted 8 lines

drivers/clk/bcm/clk-cygnus.c line 201

Quoted 6 lines
drivers/clk/bcm/clk-cygnus.c new file +6 -0
+       val = readl(pll_ctrl_reg);
+
+       /*
+        * Set PLL on/off. Set input isolation mode to 1 when disabled, 0 when
+        * enabled.
+        */

Misnamed function, confusing parameter name.

Will fix.

Quoted 39 lines
Quoted 11 lines
drivers/clk/bcm/clk-cygnus.c new file +10 -0
+       if (state) {
+               val |= pll_ldo_on;
+               val &= ~(1 << ASIU_AUDIO_GENPLL_ISO_IN);
+       } else {
+               val &= ~pll_ldo_on;
+               val |= 1 << ASIU_AUDIO_GENPLL_ISO_IN;
+       }
+
+       writel(val, pll_ctrl_reg);
+}

[...]

Quoted 25 lines
drivers/clk/bcm/clk-cygnus.c new file +25 -0
+static __init struct clk *cygnus_clock_init(struct device_node *node,
+       const struct clk_ops *ops)
+{
+       u32 channel = 0;
+       struct clk *clk;
+       struct cygnus_clk *cygnus_clk;
+       const char *clk_name = node->name;
+       const char *parent_name;
+       struct clk_init_data init;
+       int rc;
+
+       pr_debug("Clock name %s\n", node->name);
+
+       of_property_read_u32(node, "channel", &channel);
+       cygnus_clk = kzalloc(sizeof(*cygnus_clk), GFP_KERNEL);
+       if (WARN_ON(!cygnus_clk))
+               return NULL;
+
+       cygnus_clk->state = CLK_DISABLED;
+
+       /* Read base address from device tree and map to virtual address. */
+       cygnus_clk->regs_base = of_iomap(node, CYGNUS_CLK_BASE_REG);
+       if (WARN_ON(!cygnus_clk->regs_base))
+               goto err_alloc;
+
Quoted 8 lines

drivers/clk/bcm/clk-cygnus.c line 647

Quoted 6 lines
drivers/clk/bcm/clk-cygnus.c new file +6 -0
+       /* Read optional base addresses for PLL control and clock gating. */
+       cygnus_clk->clock_gate_ctrl_reg = of_iomap(node,
+               CYGNUS_CLK_GATE_CTRL_REG);
+       cygnus_clk->pll_ctrl_reg = of_iomap(node, CYGNUS_PLL_CTRL_REG);
+
+       of_property_read_u32(node, "channel", &channel);

Why do we read this twice?

Missed that one. Will fix.

Quoted 5 lines

drivers/clk/bcm/clk-cygnus.c line 649

Quoted 3 lines
drivers/clk/bcm/clk-cygnus.c new file +2 -0
+       cygnus_clk->chan = channel;
+       of_property_read_string(node, "clock-output-names", &clk_name);

What happens if this is missing from the dt?

It will (and does) fail and uses the name of the DT node instead. Please see default value at beginning of function:

const char *clk_name = node->name;

Quoted 52 lines
Quoted 38 lines
drivers/clk/bcm/clk-cygnus.c new file +37 -0
+
+       /*
+        * Internal divider is optional and used for PLL derived clocks with
+        * hardcoded dividers.
+        */
+       cygnus_clk->internal_div = CLK_RATE_NO_DIV;
+       of_property_read_u32(node, "div", &cygnus_clk->internal_div);
+
+       init.name = clk_name;
+       init.ops = ops;
+       init.flags = CLK_GET_RATE_NOCACHE;
+       parent_name = of_clk_get_parent_name(node, 0);
+       init.parent_names = &parent_name;
+       init.num_parents = 1;
+
+       cygnus_clk->hw.init = &init;
+
+       clk = clk_register(NULL, &cygnus_clk->hw);
+       if (WARN_ON(IS_ERR(clk)))
+               goto err_unmap;
+
+       rc = of_clk_add_provider(node, of_clk_src_simple_get, clk);
+       if (WARN_ON(IS_ERR_VALUE(rc)))
+               goto err_unregister;
+
+       rc = clk_register_clkdev(clk, clk_name, NULL);
+       if (WARN_ON(IS_ERR_VALUE(rc)))
+               goto err_provider;
+
+       return clk;
+
+err_provider:
+       of_clk_del_provider(node);
+
+err_unregister:
+       clk_unregister(clk);
+

drivers/clk/bcm/clk-cygnus.c line 696

Quoted 10 lines
drivers/clk/bcm/clk-cygnus.c new file +10 -0
+err_unmap:
+       iounmap(cygnus_clk->regs_base);
+       iounmap(cygnus_clk->clock_gate_ctrl_reg);
+       iounmap(cygnus_clk->pll_ctrl_reg);
+
+err_alloc:
+       kfree(cygnus_clk);
+
+       return NULL;
+}

Thanks,
Mark.

Quoted 7 lines

[1] http://en.wikipedia.org/wiki/Apostrophe#Superfluous_apostrophes_.28.22greengrocers.27_apostrophes.22.29
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

Thanks for the feedback.

Jon

#8 lore raw

PATCH 3/6 dt-bindings: Document Broadcom Cygnus SoC and clock driver

In reply to Jonathan Richardson
---
 Documentation/devicetree/bindings/arm/cygnus.txt   |   12 ++
 .../devicetree/bindings/clock/clk-cygnus.txt       |  121 ++++++++++++++++++++
 .../devicetree/bindings/clock/clk-iproc.txt        |   48 ++++++++
 3 files changed, 181 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/cygnus.txt
 create mode 100644 Documentation/devicetree/bindings/clock/clk-cygnus.txt
 create mode 100644 Documentation/devicetree/bindings/clock/clk-iproc.txt
Documentation/devicetree/bindings/arm/cygnus.txt new file +12 -0
new file mode 100644
index 0000000..a210377
@@ -0,0 +1,12 @@
+Broadcom Cygnus device tree bindings
+------------------------------------
+
+All Cygnus boards shall have the following properties:
+
+Required root node property:
+	- compatible = "brcm,cygnus";
+
+Boards variants shall have the following additional properties:
+
+Required root node property for the BCM911360_ENTPHN board:
+	- compatible = "brcm,bcm911360_entphn";
Documentation/devicetree/bindings/clock/clk-cygnus.txt new file +121 -0

121 lines not on this page · raw message

Documentation/devicetree/bindings/clock/clk-iproc.txt new file +48 -0

48 lines not on this page · raw message

Signature · 1 line
1.7.9.5
#9 lore raw

PATCH 4/6 ARM: dts: Enable Broadcom Cygnus SoC

In reply to Jonathan Richardson

DT files to enable cygnus consisting of the enterprise phone board variant and cygnus core configuration.

---
 arch/arm/boot/dts/Makefile             |    1 +
 arch/arm/boot/dts/bcm-cygnus.dtsi      |  344 ++++++++++++++++++++++++++++++++
 arch/arm/boot/dts/bcm911360_entphn.dts |   17 ++
 3 files changed, 362 insertions(+)
 create mode 100644 arch/arm/boot/dts/bcm-cygnus.dtsi
 create mode 100644 arch/arm/boot/dts/bcm911360_entphn.dts
arch/arm/boot/dts/Makefile +1 -0
index b8c5cd3..b95d41d 100644
@@ -52,6 +52,7 @@ dtb-$(CONFIG_ARCH_AT91)	+= sama5d36ek.dtb
 dtb-$(CONFIG_ARCH_ATLAS6) += atlas6-evb.dtb
 dtb-$(CONFIG_ARCH_AXXIA) += axm5516-amarillo.dtb
 dtb-$(CONFIG_ARCH_BCM2835) += bcm2835-rpi-b.dtb
+dtb-$(CONFIG_ARCH_BCM_CYGNUS) += bcm911360_entphn.dtb
 dtb-$(CONFIG_ARCH_BCM_5301X) += bcm4708-netgear-r6250.dtb
 dtb-$(CONFIG_ARCH_BCM_MOBILE) += bcm28155-ap.dtb \
 	bcm21664-garnet.dtb
arch/arm/boot/dts/bcm-cygnus.dtsi new file +344 -0

344 lines not on this page · raw message

arch/arm/boot/dts/bcm911360_entphn.dts new file +17 -0
new file mode 100644
index 0000000..db48004
@@ -0,0 +1,17 @@
+/*
+ * Copyright 2014 Broadcom Corporation.  All rights reserved.
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2, available at
+ * http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+ */
+
+/dts-v1/;
+
+#include "bcm-cygnus.dtsi"
+
+/ {
+	model = "Cygnus Enterprise Phone (BCM911360_ENTPHN)";
+	compatible = "brcm,bcm911360_entphn", "brcm,cygnus";
+};
Signature · 1 line
1.7.9.5
#10 lore raw

PATCH 5/6 ARM: cygnus defconfig : Initial defconfig for Broadcom Cygnus SoC

In reply to Jonathan Richardson
---
 arch/arm/configs/bcm_cygnus_defconfig |  223 +++++++++++++++++++++++++++++++++
 1 file changed, 223 insertions(+)
 create mode 100644 arch/arm/configs/bcm_cygnus_defconfig
arch/arm/configs/bcm_cygnus_defconfig new file +223 -0
new file mode 100644
index 0000000..effed85
@@ -0,0 +1,223 @@
+CONFIG_KERNEL_XZ=y
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_IRQ_DOMAIN_DEBUG=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=19
+CONFIG_CGROUPS=y
+CONFIG_CGROUP_FREEZER=y
+CONFIG_CGROUP_DEVICE=y
+CONFIG_CGROUP_CPUACCT=y
+CONFIG_RESOURCE_COUNTERS=y
+CONFIG_CGROUP_SCHED=y
+CONFIG_BLK_CGROUP=y
+CONFIG_NAMESPACES=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_EMBEDDED=y
+CONFIG_PERF_EVENTS=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_ARCH_BCM=y
+CONFIG_ARCH_BCM_IPROC=y
+CONFIG_ARCH_BCM_CYGNUS=y
+CONFIG_ARM_THUMBEE=y
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+CONFIG_HIGHMEM=y
+# CONFIG_COMPACTION is not set
+# CONFIG_ATAGS is not set
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_ARM_APPENDED_DTB=y
+CONFIG_CPU_IDLE=y
+CONFIG_VFP=y
+CONFIG_NEON=y
+# CONFIG_SUSPEND is not set
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_MROUTE_MULTIPLE_TABLES=y
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+CONFIG_TCP_CONG_ADVANCED=y
+# CONFIG_TCP_CONG_BIC is not set
+# CONFIG_TCP_CONG_WESTWOOD is not set
+# CONFIG_TCP_CONG_HTCP is not set
+CONFIG_IPV6=y
+# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET6_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET6_XFRM_MODE_BEET is not set
+# CONFIG_IPV6_SIT is not set
+CONFIG_IPV6_MULTIPLE_TABLES=y
+CONFIG_IPV6_SUBTREES=y
+CONFIG_IPV6_MROUTE=y
+CONFIG_NETFILTER=y
+# CONFIG_BRIDGE_NETFILTER is not set
+CONFIG_NF_CONNTRACK=y
+# CONFIG_NF_CONNTRACK_PROCFS is not set
+CONFIG_NF_CONNTRACK_FTP=y
+CONFIG_NF_CONNTRACK_IPV4=y
+CONFIG_IP_NF_IPTABLES=y
+CONFIG_IP_NF_FILTER=y
+CONFIG_IP_NF_TARGET_REJECT=y
+CONFIG_NF_NAT_IPV4=y
+CONFIG_IP_NF_TARGET_MASQUERADE=y
+CONFIG_IP_NF_TARGET_REDIRECT=y
+CONFIG_IP_NF_MANGLE=y
+CONFIG_IP_NF_RAW=y
+CONFIG_NF_CONNTRACK_IPV6=y
+CONFIG_IP6_NF_IPTABLES=y
+CONFIG_IP6_NF_MATCH_AH=y
+CONFIG_IP6_NF_MATCH_EUI64=y
+CONFIG_IP6_NF_MATCH_FRAG=y
+CONFIG_IP6_NF_MATCH_OPTS=y
+CONFIG_IP6_NF_MATCH_IPV6HEADER=y
+CONFIG_IP6_NF_MATCH_MH=y
+CONFIG_IP6_NF_MATCH_RT=y
+CONFIG_IP6_NF_FILTER=y
+CONFIG_IP6_NF_TARGET_REJECT=y
+CONFIG_IP6_NF_MANGLE=y
+CONFIG_IP6_NF_RAW=y
+CONFIG_BRIDGE=y
+# CONFIG_BRIDGE_IGMP_SNOOPING is not set
+CONFIG_VLAN_8021Q=y
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_FQ_CODEL=y
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_MTD=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_UBI=y
+# CONFIG_BLK_DEV is not set
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_NETDEVICES=y
+# CONFIG_NET_CADENCE is not set
+# CONFIG_NET_VENDOR_CIRRUS is not set
+# CONFIG_NET_VENDOR_FARADAY is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
+CONFIG_PHYLIB=y
+CONFIG_BROADCOM_PHY=y
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_SERIAL_8250=y
+# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=2
+CONFIG_SERIAL_8250_RUNTIME_UARTS=2
+CONFIG_SERIAL_8250_DW=y
+CONFIG_SERIAL_OF_PLATFORM=y
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+# CONFIG_I2C_HELPER_AUTO is not set
+CONFIG_I2C_SMBUS=y
+CONFIG_SPI=y
+CONFIG_SPI_PL022=y
+CONFIG_SPI_SPIDEV=y
+CONFIG_GPIO_SYSFS=y
+# CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_ARM_SP805_WATCHDOG=y
+CONFIG_FB=y
+CONFIG_FB_ARMCLCD=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+# CONFIG_LCD_CLASS_DEVICE is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+# CONFIG_BACKLIGHT_GENERIC is not set
+CONFIG_BACKLIGHT_PWM=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_DYNAMIC_MINORS=y
+CONFIG_SND_VERBOSE_PRINTK=y
+CONFIG_SND_DEBUG=y
+CONFIG_SND_USB_AUDIO=y
+CONFIG_SND_SOC=y
+CONFIG_USB=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_EHCI_HCD_PLATFORM=y
+CONFIG_USB_STORAGE=y
+CONFIG_MMC=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_PWM=y
+CONFIG_EXT4_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_NTFS_FS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_UBIFS_FS=y
+CONFIG_NFS_FS=y
+CONFIG_ROOT_NFS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_UTF8=y
+CONFIG_DYNAMIC_DEBUG=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_INFO_REDUCED=y
+CONFIG_STRIP_ASM_SYMS=y
+CONFIG_DEBUG_FS=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_OBJECTS=y
+CONFIG_DEBUG_OBJECTS_RCU_HEAD=y
+CONFIG_SLUB_DEBUG_ON=y
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_DEBUG_SHIRQ=y
+CONFIG_DETECT_HUNG_TASK=y
+CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=110
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC=y
+# CONFIG_SCHED_DEBUG is not set
+CONFIG_SCHEDSTATS=y
+CONFIG_DEBUG_RT_MUTEXES=y
+CONFIG_PROVE_LOCKING=y
+CONFIG_DEBUG_ATOMIC_SLEEP=y
+# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_SG=y
+CONFIG_DEBUG_NOTIFIERS=y
+CONFIG_DEBUG_CREDENTIALS=y
+CONFIG_PROVE_RCU=y
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_LL=y
+CONFIG_DEBUG_LL_UART_8250=y
+CONFIG_DEBUG_UART_PHYS=0x18023000
+CONFIG_DEBUG_UART_VIRT=0xf1023000
+CONFIG_EARLY_PRINTK=y
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
Signature · 1 line
1.7.9.5
#11 lore raw

PATCH 6/6 MAINTAINERS: Entry for Cygnus/iproc arm architecture and clock drivers

In reply to Jonathan Richardson
---
 MAINTAINERS |   21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)
MAINTAINERS +21 -0
index 809ecd6..2152ee0 100644
@@ -2070,6 +2070,27 @@ L:	[email protected]
 S:	Supported
 F:	drivers/scsi/bnx2i/
 
+BROADCOM CYGNUS/IPROC ARM ARCHITECTURE
+M:	Jonathan Richardson <[email protected]>
+M:	Scott Branden <[email protected]>
+L:	[email protected] (moderated for non-subscribers)
+S:	Maintained
+F:	Documentation/devicetree/bindings/arm/cygnus.txt
+F:	arch/arm/boot/dts/bcm-cygnus.dtsi
+F:	arch/arm/boot/dts/bcm911360_entphn.dts
+F:	arch/arm/configs/bcm_cygnus_defconfig
+F:	arch/arm/mach-bcm/board_bcm_cygnus.c
+
+BROADCOM CYGNUS/IPROC CLOCK DRIVERS
+M:	Jonathan Richardson <[email protected]>
+M:	Scott Branden <[email protected]>
+L:	[email protected] (moderated for non-subscribers)
+S:	Maintained
+F:	Documentation/devicetree/bindings/clock/clk-cygnus.txt
+F:	Documentation/devicetree/bindings/clock/clk-iproc.txt
+F:	drivers/clk/bcm/clk-cygnus.c
+F:	drivers/clk/bcm/clk-iproc.c
+
 BROADCOM KONA GPIO DRIVER
 M:	Ray Jui <[email protected]>
 L:	[email protected]
Signature · 1 line
1.7.9.5
#12 lore raw
In reply to Jonathan Richardson
Quoted 7 lines · Jonathan Richardson

Hi,

This patchset contains initial support for Broadcom's Cygnus SoC based on our iProc architecture. Initial support is minimal and includes just the mach platform code, clock driver, and a basic device tree configuration. Peripheral drivers will be submitted soon, as will device tree configurations for other Cygnus board variants.

This SoC looks similar to the BCM5301X (Northstar) SoCs even some cores are at the same memory addresses. Does this SoC use an AXI bus with Broadcom Plugins at address 0x18000000 ?

The BCM5301X (Northstar) SoCs also has an iProc Clock Control Unit and I will try to use your driver for that SoC.

Is Broadcom Cygnus similar to BCM563XX or is it actually the same SoC?

Do you have some description of the hardware features of this SoC? Does it have PCIe, or Ethernet?

Hauke

#13 lore raw
Quoted 9 lines · Hauke Mehrtens
Quoted 7 lines · Jonathan Richardson

Hi,

This patchset contains initial support for Broadcom's Cygnus SoC based on our iProc architecture. Initial support is minimal and includes just the mach platform code, clock driver, and a basic device tree configuration. Peripheral drivers will be submitted soon, as will device tree configurations for other Cygnus board variants.

Quoted 8 lines

This SoC looks similar to the BCM5301X (Northstar) SoCs even some cores are at the same memory addresses. Does this SoC use an AXI bus with Broadcom Plugins at address 0x18000000 ?

The BCM5301X (Northstar) SoCs also has an iProc Clock Control Unit and I will try to use your driver for that SoC.

Is Broadcom Cygnus similar to BCM563XX or is it actually the same SoC?

According to this link:
http://lists.denx.de/pipermail/u-boot/2014-August/186086.html

these SoCs, in particular BCM58622 would belong to the StrataGX network processors:
http://www.broadcom.com/products/Processors/Home-and-Small-Business/BCM5862X-Series.

Quoted 5 lines

Do you have some description of the hardware features of this SoC? Does it have PCIe, or Ethernet?

From the link above, it has Ethernet for sure, and certainly PCIe since

the Wi-Fi chips mentioned in the link above are PCIe chips.

It would be really good if all the work you and Rafal did was usable for the Cygnus SoCs.
--
Florian

#14 lore raw
Quoted 17 lines · Florian Fainelli
Quoted 16 lines · Hauke Mehrtens
Quoted 7 lines · Jonathan Richardson

Hi,

This patchset contains initial support for Broadcom's Cygnus SoC based on our iProc architecture. Initial support is minimal and includes just the mach platform code, clock driver, and a basic device tree configuration. Peripheral drivers will be submitted soon, as will device tree configurations for other Cygnus board variants.

This SoC looks similar to the BCM5301X (Northstar) SoCs even some cores are at the same memory addresses. Does this SoC use an AXI bus with Broadcom Plugins at address 0x18000000 ?

The BCM5301X (Northstar) SoCs also has an iProc Clock Control Unit and I will try to use your driver for that SoC.

Quoted 8 lines
Quoted 1 line

Is Broadcom Cygnus similar to BCM563XX or is it actually the same SoC?

According to this link:
http://lists.denx.de/pipermail/u-boot/2014-August/186086.html

these SoCs, in particular BCM58622 would belong to the StrataGX network processors:
http://www.broadcom.com/products/Processors/Home-and-Small-Business/BCM5862X-Series.

Broadcom claims that this SoC is pin and software compatible to BCM5301X:

Quoted 4 lines

Pin compatible and software compatible products with previous generation BCM5301x products enable single design with easy upgradeable path

Quoted 8 lines
Quoted 2 lines

Do you have some description of the hardware features of this SoC? Does it have PCIe, or Ethernet?

From the link above, it has Ethernet for sure, and certainly PCIe since the Wi-Fi chips mentioned in the link above are PCIe chips.

It would be really good if all the work you and Rafal did was usable for the Cygnus SoCs.

I also hope you can use much of the code and improve it. ;-)

Hauke

maintainer
#15 lore raw
Quoted 11 lines · Hauke Mehrtens
Quoted 10 lines · Florian Fainelli
Quoted 9 lines · Hauke Mehrtens
Quoted 7 lines · Jonathan Richardson

Hi,

This patchset contains initial support for Broadcom's Cygnus SoC based on our iProc architecture. Initial support is minimal and includes just the mach platform code, clock driver, and a basic device tree configuration. Peripheral drivers will be submitted soon, as will device tree configurations for other Cygnus board variants.

Quoted 8 lines
Quoted 8 lines
Quoted 8 lines

This SoC looks similar to the BCM5301X (Northstar) SoCs even some cores are at the same memory addresses. Does this SoC use an AXI bus with Broadcom Plugins at address 0x18000000 ?

The BCM5301X (Northstar) SoCs also has an iProc Clock Control Unit and I will try to use your driver for that SoC.

Is Broadcom Cygnus similar to BCM563XX or is it actually the same SoC?

Cygnus is a next generation product with similarities to other Broadcom SoC's. It takes technology from other parts for sure. Our first step is to upstream the core IPROC code and Cygnus code. From there we will upstream individual drivers which are reusable on some other Broadcom chips (or will need minor additions/quirks added as identified). There are also other IPROC-based Broadcom chips that can also be upstreamed more easily with this patchset going forward.

I know the BCM5301X iProc Clock Control Unit is an older. I think you may run into some difficulties running this code as is. But hopefully we can build up more support for other chips from this initial submission for Cygnus support.

Quoted 15 lines
Quoted 7 lines

According to this link:
http://lists.denx.de/pipermail/u-boot/2014-August/186086.html

these SoCs, in particular BCM58622 would belong to the StrataGX network processors:
http://www.broadcom.com/products/Processors/Home-and-Small-Business/BCM5862X-Series.

Broadcom claims that this SoC is pin and software compatible to BCM5301X:

Quoted 6 lines

Pin compatible and software compatible products with previous generation BCM5301x products enable single design with easy upgradeable path

Quoted 2 lines

Do you have some description of the hardware features of this SoC? Does it have PCIe, or Ethernet?

Yes, Some variants of Cygnus do have PCIe or Ethernet. Drivers to be upstreamed once cleaned up fully. The drivers will be built into our bcm_cygnus_defconfig and then enabled in device tree.

Quoted 12 lines
Quoted 6 lines

From the link above, it has Ethernet for sure, and certainly PCIe since
the Wi-Fi chips mentioned in the link above are PCIe chips.

It would be really good if all the work you and Rafal did was usable for the Cygnus SoCs.

I also hope you can use much of the code and improve it. ;-)

Hauke

#16 lore raw

v2 cover Add initial support for Broadcom Cygnus SoC

In reply to a message not in the archive

Hi,

This patchset contains initial support for Broadcom's Cygnus SoC based on our iProc architecture. Initial support is minimal and includes just the mach platform code, clock driver, and a basic device tree configuration. Peripheral drivers will be submitted soon, as will device tree configurations for other Cygnus board variants.

Changes from v1:
- Address code review comments as per previous responses.
- Copyright headers updated to remove Broadcom URL.
- mach platform code still contains hard coded adresses. These address are the same for all Cygnus variants. Could you please provide guidance on where they should go if you would still like them changed.

Thanks,
Jon

Jonathan Richardson (6):
ARM: cygnus: Initial support for Broadcom Cygnus SoC
clk: Clock driver support for Broadcom Cygnus SoC
dt-bindings: Document Broadcom Cygnus SoC and clock driver
ARM: dts: Enable Broadcom Cygnus SoC
ARM: cygnus defconfig : Initial defconfig for Broadcom Cygnus SoC
MAINTAINERS: Entry for Cygnus/iproc arm architecture and clock
drivers

 Documentation/devicetree/bindings/arm/cygnus.txt   |   12 +
 .../devicetree/bindings/clock/clk-cygnus.txt       |  121 ++
 .../devicetree/bindings/clock/clk-iproc.txt        |   48 +
 MAINTAINERS                                        |   21 +
 arch/arm/boot/dts/Makefile                         |    1 +
 arch/arm/boot/dts/bcm-cygnus.dtsi                  |  349 ++++++
 arch/arm/boot/dts/bcm911360_entphn.dts             |   22 +
 arch/arm/configs/bcm_cygnus_defconfig              |  223 ++++
 arch/arm/mach-bcm/Kconfig                          |   31 +
 arch/arm/mach-bcm/Makefile                         |    3 +
 arch/arm/mach-bcm/bcm_cygnus.c                     |  166 +++
 drivers/clk/Makefile                               |    1 +
 drivers/clk/bcm/Makefile                           |    2 +
 drivers/clk/bcm/clk-cygnus.c                       | 1186 ++++++++++++++++++++
 drivers/clk/bcm/clk-iproc.c                        |  451 ++++++++
 15 files changed, 2637 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/cygnus.txt
 create mode 100644 Documentation/devicetree/bindings/clock/clk-cygnus.txt
 create mode 100644 Documentation/devicetree/bindings/clock/clk-iproc.txt
 create mode 100644 arch/arm/boot/dts/bcm-cygnus.dtsi
 create mode 100644 arch/arm/boot/dts/bcm911360_entphn.dts
 create mode 100644 arch/arm/configs/bcm_cygnus_defconfig
 create mode 100644 arch/arm/mach-bcm/bcm_cygnus.c
 create mode 100644 drivers/clk/bcm/clk-cygnus.c
 create mode 100644 drivers/clk/bcm/clk-iproc.c
Signature · 1 line
1.7.9.5
#17 lore raw

PATCH v2 1/6 ARM: cygnus: Initial support for Broadcom Cygnus SoC

Adds initial support for the Cygnus SoC based on Broadcom?s iProc series.

---
 arch/arm/mach-bcm/Kconfig      |   31 ++++++++
 arch/arm/mach-bcm/Makefile     |    3 +
 arch/arm/mach-bcm/bcm_cygnus.c |  166 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 200 insertions(+)
 create mode 100644 arch/arm/mach-bcm/bcm_cygnus.c
arch/arm/mach-bcm/Kconfig +31 -0
index fc93800..2dd3f78 100644
@@ -5,6 +5,37 @@ menuconfig ARCH_BCM
 
 if ARCH_BCM
 
+config ARCH_BCM_IPROC
+	bool "Broadcom ARMv7 iProc boards" if ARCH_MULTI_V7
+	select ARM_GIC
+	select CACHE_L2X0
+	select HAVE_ARM_TWD if LOCAL_TIMERS
+	select HAVE_CLK
+	select CLKSRC_OF
+	select CLKSRC_MMIO
+	select GENERIC_CLOCKEVENTS
+	select ARM_GLOBAL_TIMER
+	select ARCH_REQUIRE_GPIOLIB
+	select ARM_AMBA
+	select PINCTRL
+	select DEBUG_UART_8250
+	help
+	  This enables support for systems based on Broadcom IPROC architected SoCs.
+	  The IPROC complex contains one or more ARM CPUs along with common
+	  core periperals. Application specific SoCs are created by adding a
+	  uArchitecture containing peripherals outside of the IPROC complex.
+	  Currently supported SoCs are Cygnus.
+
+menu "iProc SoC based Machine types"
+	depends on ARCH_BCM_IPROC
+
+	config ARCH_BCM_CYGNUS
+		bool "Support Broadcom Cygnus board"
+		select USB_ARCH_HAS_EHCI if USB_SUPPORT
+		help
+		  Support for Broadcom Cygnus SoC.
+endmenu
+
 config ARCH_BCM_MOBILE
 	bool "Broadcom Mobile SoC Support" if ARCH_MULTI_V7
 	select ARCH_REQUIRE_GPIOLIB
arch/arm/mach-bcm/Makefile +3 -0
index b19a396..46e092a 100644
@@ -10,6 +10,9 @@
 # of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU General Public License for more details.
 
+# Cygnus
+obj-$(CONFIG_ARCH_BCM_CYGNUS) +=  bcm_cygnus.o
+
 # BCM281XX
 obj-$(CONFIG_ARCH_BCM_281XX)	+= board_bcm281xx.o
 
arch/arm/mach-bcm/bcm_cygnus.c new file +166 -0

166 lines not on this page · raw message

Signature · 1 line
1.7.9.5
#18 lore raw

PATCH v2 2/6 clk: Clock driver support for Broadcom Cygnus SoC

In reply to Jonathan Richardson

The iProc clock driver controls PLLs common across iProc chips. The cygnus driver controls cygnus specific features and variations.

---
 drivers/clk/Makefile         |    1 +
 drivers/clk/bcm/Makefile     |    2 +
 drivers/clk/bcm/clk-cygnus.c | 1186 ++++++++++++++++++++++++++++++++++++++++++
 drivers/clk/bcm/clk-iproc.c  |  451 ++++++++++++++++
 4 files changed, 1640 insertions(+)
 create mode 100644 drivers/clk/bcm/clk-cygnus.c
 create mode 100644 drivers/clk/bcm/clk-iproc.c
drivers/clk/Makefile +1 -0
index f537a0b..8ac0a31 100644
@@ -37,6 +37,7 @@ obj-$(CONFIG_ARCH_VT8500)		+= clk-vt8500.o
 obj-$(CONFIG_COMMON_CLK_WM831X)		+= clk-wm831x.o
 obj-$(CONFIG_COMMON_CLK_XGENE)		+= clk-xgene.o
 obj-$(CONFIG_COMMON_CLK_AT91)		+= at91/
+obj-$(CONFIG_ARCH_BCM_IPROC)	+= bcm/
 obj-$(CONFIG_ARCH_BCM_MOBILE)		+= bcm/
 obj-$(CONFIG_ARCH_BERLIN)		+= berlin/
 obj-$(CONFIG_ARCH_HI3xxx)		+= hisilicon/
drivers/clk/bcm/Makefile +2 -0
index 6297d05..f803919 100644
@@ -2,3 +2,5 @@ obj-$(CONFIG_CLK_BCM_KONA)	+= clk-kona.o
 obj-$(CONFIG_CLK_BCM_KONA)	+= clk-kona-setup.o
 obj-$(CONFIG_CLK_BCM_KONA)	+= clk-bcm281xx.o
 obj-$(CONFIG_CLK_BCM_KONA)	+= clk-bcm21664.o
+obj-$(CONFIG_ARCH_BCM_IPROC)	+= clk-iproc.o
+obj-$(CONFIG_ARCH_BCM_CYGNUS)	+= clk-cygnus.o
drivers/clk/bcm/clk-cygnus.c new file +1186 -0

1,186 lines not on this page · raw message

drivers/clk/bcm/clk-iproc.c new file +451 -0

451 lines not on this page · raw message

Signature · 1 line
1.7.9.5
#19 lore raw

PATCH v2 3/6 dt-bindings: Document Broadcom Cygnus SoC and clock driver

In reply to Jonathan Richardson
---
 Documentation/devicetree/bindings/arm/cygnus.txt   |   12 ++
 .../devicetree/bindings/clock/clk-cygnus.txt       |  121 ++++++++++++++++++++
 .../devicetree/bindings/clock/clk-iproc.txt        |   48 ++++++++
 3 files changed, 181 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/cygnus.txt
 create mode 100644 Documentation/devicetree/bindings/clock/clk-cygnus.txt
 create mode 100644 Documentation/devicetree/bindings/clock/clk-iproc.txt
Documentation/devicetree/bindings/arm/cygnus.txt new file +12 -0
new file mode 100644
index 0000000..a210377
@@ -0,0 +1,12 @@
+Broadcom Cygnus device tree bindings
+------------------------------------
+
+All Cygnus boards shall have the following properties:
+
+Required root node property:
+	- compatible = "brcm,cygnus";
+
+Boards variants shall have the following additional properties:
+
+Required root node property for the BCM911360_ENTPHN board:
+	- compatible = "brcm,bcm911360_entphn";
Documentation/devicetree/bindings/clock/clk-cygnus.txt new file +121 -0

121 lines not on this page · raw message

Documentation/devicetree/bindings/clock/clk-iproc.txt new file +48 -0

48 lines not on this page · raw message

Signature · 1 line
1.7.9.5
#20 lore raw

PATCH v2 4/6 ARM: dts: Enable Broadcom Cygnus SoC

In reply to Jonathan Richardson

DT files to enable cygnus consisting of the enterprise phone board variant and cygnus core configuration.

---
 arch/arm/boot/dts/Makefile             |    1 +
 arch/arm/boot/dts/bcm-cygnus.dtsi      |  349 ++++++++++++++++++++++++++++++++
 arch/arm/boot/dts/bcm911360_entphn.dts |   22 ++
 3 files changed, 372 insertions(+)
 create mode 100644 arch/arm/boot/dts/bcm-cygnus.dtsi
 create mode 100644 arch/arm/boot/dts/bcm911360_entphn.dts
arch/arm/boot/dts/Makefile +1 -0
index b8c5cd3..b95d41d 100644
@@ -52,6 +52,7 @@ dtb-$(CONFIG_ARCH_AT91)	+= sama5d36ek.dtb
 dtb-$(CONFIG_ARCH_ATLAS6) += atlas6-evb.dtb
 dtb-$(CONFIG_ARCH_AXXIA) += axm5516-amarillo.dtb
 dtb-$(CONFIG_ARCH_BCM2835) += bcm2835-rpi-b.dtb
+dtb-$(CONFIG_ARCH_BCM_CYGNUS) += bcm911360_entphn.dtb
 dtb-$(CONFIG_ARCH_BCM_5301X) += bcm4708-netgear-r6250.dtb
 dtb-$(CONFIG_ARCH_BCM_MOBILE) += bcm28155-ap.dtb \
 	bcm21664-garnet.dtb
arch/arm/boot/dts/bcm-cygnus.dtsi new file +349 -0

349 lines not on this page · raw message

arch/arm/boot/dts/bcm911360_entphn.dts new file +22 -0
new file mode 100644
index 0000000..cee4aff
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2014 Broadcom Corporation.  All rights reserved.
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+
+#include "bcm-cygnus.dtsi"
+
+/ {
+	model = "Cygnus Enterprise Phone (BCM911360_ENTPHN)";
+	compatible = "brcm,bcm911360_entphn", "brcm,cygnus";
+};
Signature · 1 line
1.7.9.5
#21 lore raw

PATCH v2 5/6 ARM: cygnus defconfig : Initial defconfig for Broadcom Cygnus SoC

In reply to Jonathan Richardson
---
 arch/arm/configs/bcm_cygnus_defconfig |  223 +++++++++++++++++++++++++++++++++
 1 file changed, 223 insertions(+)
 create mode 100644 arch/arm/configs/bcm_cygnus_defconfig
arch/arm/configs/bcm_cygnus_defconfig new file +223 -0
new file mode 100644
index 0000000..effed85
@@ -0,0 +1,223 @@
+CONFIG_KERNEL_XZ=y
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_IRQ_DOMAIN_DEBUG=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=19
+CONFIG_CGROUPS=y
+CONFIG_CGROUP_FREEZER=y
+CONFIG_CGROUP_DEVICE=y
+CONFIG_CGROUP_CPUACCT=y
+CONFIG_RESOURCE_COUNTERS=y
+CONFIG_CGROUP_SCHED=y
+CONFIG_BLK_CGROUP=y
+CONFIG_NAMESPACES=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_EMBEDDED=y
+CONFIG_PERF_EVENTS=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_ARCH_BCM=y
+CONFIG_ARCH_BCM_IPROC=y
+CONFIG_ARCH_BCM_CYGNUS=y
+CONFIG_ARM_THUMBEE=y
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+CONFIG_HIGHMEM=y
+# CONFIG_COMPACTION is not set
+# CONFIG_ATAGS is not set
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_ARM_APPENDED_DTB=y
+CONFIG_CPU_IDLE=y
+CONFIG_VFP=y
+CONFIG_NEON=y
+# CONFIG_SUSPEND is not set
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_MROUTE_MULTIPLE_TABLES=y
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+CONFIG_TCP_CONG_ADVANCED=y
+# CONFIG_TCP_CONG_BIC is not set
+# CONFIG_TCP_CONG_WESTWOOD is not set
+# CONFIG_TCP_CONG_HTCP is not set
+CONFIG_IPV6=y
+# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET6_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET6_XFRM_MODE_BEET is not set
+# CONFIG_IPV6_SIT is not set
+CONFIG_IPV6_MULTIPLE_TABLES=y
+CONFIG_IPV6_SUBTREES=y
+CONFIG_IPV6_MROUTE=y
+CONFIG_NETFILTER=y
+# CONFIG_BRIDGE_NETFILTER is not set
+CONFIG_NF_CONNTRACK=y
+# CONFIG_NF_CONNTRACK_PROCFS is not set
+CONFIG_NF_CONNTRACK_FTP=y
+CONFIG_NF_CONNTRACK_IPV4=y
+CONFIG_IP_NF_IPTABLES=y
+CONFIG_IP_NF_FILTER=y
+CONFIG_IP_NF_TARGET_REJECT=y
+CONFIG_NF_NAT_IPV4=y
+CONFIG_IP_NF_TARGET_MASQUERADE=y
+CONFIG_IP_NF_TARGET_REDIRECT=y
+CONFIG_IP_NF_MANGLE=y
+CONFIG_IP_NF_RAW=y
+CONFIG_NF_CONNTRACK_IPV6=y
+CONFIG_IP6_NF_IPTABLES=y
+CONFIG_IP6_NF_MATCH_AH=y
+CONFIG_IP6_NF_MATCH_EUI64=y
+CONFIG_IP6_NF_MATCH_FRAG=y
+CONFIG_IP6_NF_MATCH_OPTS=y
+CONFIG_IP6_NF_MATCH_IPV6HEADER=y
+CONFIG_IP6_NF_MATCH_MH=y
+CONFIG_IP6_NF_MATCH_RT=y
+CONFIG_IP6_NF_FILTER=y
+CONFIG_IP6_NF_TARGET_REJECT=y
+CONFIG_IP6_NF_MANGLE=y
+CONFIG_IP6_NF_RAW=y
+CONFIG_BRIDGE=y
+# CONFIG_BRIDGE_IGMP_SNOOPING is not set
+CONFIG_VLAN_8021Q=y
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_FQ_CODEL=y
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_MTD=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_UBI=y
+# CONFIG_BLK_DEV is not set
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_NETDEVICES=y
+# CONFIG_NET_CADENCE is not set
+# CONFIG_NET_VENDOR_CIRRUS is not set
+# CONFIG_NET_VENDOR_FARADAY is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
+CONFIG_PHYLIB=y
+CONFIG_BROADCOM_PHY=y
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_SERIAL_8250=y
+# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=2
+CONFIG_SERIAL_8250_RUNTIME_UARTS=2
+CONFIG_SERIAL_8250_DW=y
+CONFIG_SERIAL_OF_PLATFORM=y
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+# CONFIG_I2C_HELPER_AUTO is not set
+CONFIG_I2C_SMBUS=y
+CONFIG_SPI=y
+CONFIG_SPI_PL022=y
+CONFIG_SPI_SPIDEV=y
+CONFIG_GPIO_SYSFS=y
+# CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_ARM_SP805_WATCHDOG=y
+CONFIG_FB=y
+CONFIG_FB_ARMCLCD=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+# CONFIG_LCD_CLASS_DEVICE is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+# CONFIG_BACKLIGHT_GENERIC is not set
+CONFIG_BACKLIGHT_PWM=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_DYNAMIC_MINORS=y
+CONFIG_SND_VERBOSE_PRINTK=y
+CONFIG_SND_DEBUG=y
+CONFIG_SND_USB_AUDIO=y
+CONFIG_SND_SOC=y
+CONFIG_USB=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_EHCI_HCD_PLATFORM=y
+CONFIG_USB_STORAGE=y
+CONFIG_MMC=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_PWM=y
+CONFIG_EXT4_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_NTFS_FS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_UBIFS_FS=y
+CONFIG_NFS_FS=y
+CONFIG_ROOT_NFS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_UTF8=y
+CONFIG_DYNAMIC_DEBUG=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_INFO_REDUCED=y
+CONFIG_STRIP_ASM_SYMS=y
+CONFIG_DEBUG_FS=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_OBJECTS=y
+CONFIG_DEBUG_OBJECTS_RCU_HEAD=y
+CONFIG_SLUB_DEBUG_ON=y
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_DEBUG_SHIRQ=y
+CONFIG_DETECT_HUNG_TASK=y
+CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=110
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC=y
+# CONFIG_SCHED_DEBUG is not set
+CONFIG_SCHEDSTATS=y
+CONFIG_DEBUG_RT_MUTEXES=y
+CONFIG_PROVE_LOCKING=y
+CONFIG_DEBUG_ATOMIC_SLEEP=y
+# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_SG=y
+CONFIG_DEBUG_NOTIFIERS=y
+CONFIG_DEBUG_CREDENTIALS=y
+CONFIG_PROVE_RCU=y
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_LL=y
+CONFIG_DEBUG_LL_UART_8250=y
+CONFIG_DEBUG_UART_PHYS=0x18023000
+CONFIG_DEBUG_UART_VIRT=0xf1023000
+CONFIG_EARLY_PRINTK=y
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
Signature · 1 line
1.7.9.5
#22 lore raw

PATCH v2 6/6 MAINTAINERS: Entry for Cygnus/iproc arm architecture and clock drivers

In reply to Jonathan Richardson
---
 MAINTAINERS |   21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)
MAINTAINERS +21 -0
index 670b3dc..beb3e06 100644
@@ -2070,6 +2070,27 @@ L:	[email protected]
 S:	Supported
 F:	drivers/scsi/bnx2i/
 
+BROADCOM CYGNUS/IPROC ARM ARCHITECTURE
+M:	Jonathan Richardson <[email protected]>
+M:	Scott Branden <[email protected]>
+L:	[email protected] (moderated for non-subscribers)
+S:	Maintained
+F:	Documentation/devicetree/bindings/arm/cygnus.txt
+F:	arch/arm/boot/dts/bcm-cygnus.dtsi
+F:	arch/arm/boot/dts/bcm911360_entphn.dts
+F:	arch/arm/configs/bcm_cygnus_defconfig
+F:	arch/arm/mach-bcm/board_bcm_cygnus.c
+
+BROADCOM CYGNUS/IPROC CLOCK DRIVERS
+M:	Jonathan Richardson <[email protected]>
+M:	Scott Branden <[email protected]>
+L:	[email protected] (moderated for non-subscribers)
+S:	Maintained
+F:	Documentation/devicetree/bindings/clock/clk-cygnus.txt
+F:	Documentation/devicetree/bindings/clock/clk-iproc.txt
+F:	drivers/clk/bcm/clk-cygnus.c
+F:	drivers/clk/bcm/clk-iproc.c
+
 BROADCOM KONA GPIO DRIVER
 M:	Ray Jui <[email protected]>
 L:	[email protected]
Signature · 1 line
1.7.9.5
maintainer
#23 lore raw
In reply to Jonathan Richardson

Hi Matt/Christian (and others),

We would like to move forward in getting our base Cygnus support into the mainline kernel. From there we will be able to contribute additional drivers.

Is somebody willing to accept this pull request to get this patchset accepted by the open source community?

Regards,
Scott

Quoted 53 lines · Jonathan Richardson

Hi,

This patchset contains initial support for Broadcom's Cygnus SoC based on our iProc architecture. Initial support is minimal and includes just the mach platform code, clock driver, and a basic device tree configuration. Peripheral drivers will be submitted soon, as will device tree configurations for other Cygnus board variants.

Changes from v1:
- Address code review comments as per previous responses.
- Copyright headers updated to remove Broadcom URL.
- mach platform code still contains hard coded adresses. These address are the same for all Cygnus variants. Could you please provide guidance on where they should go if you would still like them changed.

Thanks,
Jon

Jonathan Richardson (6):
ARM: cygnus: Initial support for Broadcom Cygnus SoC
clk: Clock driver support for Broadcom Cygnus SoC
dt-bindings: Document Broadcom Cygnus SoC and clock driver
ARM: dts: Enable Broadcom Cygnus SoC
ARM: cygnus defconfig : Initial defconfig for Broadcom Cygnus SoC
MAINTAINERS: Entry for Cygnus/iproc arm architecture and clock
drivers

  Documentation/devicetree/bindings/arm/cygnus.txt   |   12 +
  .../devicetree/bindings/clock/clk-cygnus.txt       |  121 ++
  .../devicetree/bindings/clock/clk-iproc.txt        |   48 +
  MAINTAINERS                                        |   21 +
  arch/arm/boot/dts/Makefile                         |    1 +
  arch/arm/boot/dts/bcm-cygnus.dtsi                  |  349 ++++++
  arch/arm/boot/dts/bcm911360_entphn.dts             |   22 +
  arch/arm/configs/bcm_cygnus_defconfig              |  223 ++++
  arch/arm/mach-bcm/Kconfig                          |   31 +
  arch/arm/mach-bcm/Makefile                         |    3 +
  arch/arm/mach-bcm/bcm_cygnus.c                     |  166 +++
  drivers/clk/Makefile                               |    1 +
  drivers/clk/bcm/Makefile                           |    2 +
  drivers/clk/bcm/clk-cygnus.c                       | 1186 ++++++++++++++++++++
  drivers/clk/bcm/clk-iproc.c                        |  451 ++++++++
  15 files changed, 2637 insertions(+)

create mode 100644 Documentation/devicetree/bindings/arm/cygnus.txt create mode 100644 Documentation/devicetree/bindings/clock/clk-cygnus.txt create mode 100644 Documentation/devicetree/bindings/clock/clk-iproc.txt create mode 100644 arch/arm/boot/dts/bcm-cygnus.dtsi
create mode 100644 arch/arm/boot/dts/bcm911360_entphn.dts create mode 100644 arch/arm/configs/bcm_cygnus_defconfig create mode 100644 arch/arm/mach-bcm/bcm_cygnus.c
create mode 100644 drivers/clk/bcm/clk-cygnus.c
create mode 100644 drivers/clk/bcm/clk-iproc.c

#24 lore raw

Hi Scott,

Quoted 8 lines · Scott Branden

Hi Matt/Christian (and others),

We would like to move forward in getting our base Cygnus support into the mainline kernel. From there we will be able to contribute additional drivers.

Is somebody willing to accept this pull request to get this patchset accepted by the open source community?

I am fine with taking the ARM patches and putting them at
http://github/brcm/linux.git, with C code in cygnus/board and the Device Tree files in cygnus/dt for instance?

The clock driver patch will have to go through Mike Turquette's tree unless he wants to delegate that one.

Quoted 73 lines

Regards,
Scott

Quoted 49 lines · Jonathan Richardson

Hi,

This patchset contains initial support for Broadcom's Cygnus SoC based on our
iProc architecture. Initial support is minimal and includes just the mach platform code, clock driver, and a basic device tree configuration. Peripheral
drivers will be submitted soon, as will device tree configurations for other
Cygnus board variants.

Changes from v1:
- Address code review comments as per previous responses.
- Copyright headers updated to remove Broadcom URL.
- mach platform code still contains hard coded adresses. These
address are
the same for all Cygnus variants. Could you please provide
guidance on where
they should go if you would still like them changed.

Thanks,
Jon

Jonathan Richardson (6):
ARM: cygnus: Initial support for Broadcom Cygnus SoC
clk: Clock driver support for Broadcom Cygnus SoC
dt-bindings: Document Broadcom Cygnus SoC and clock driver
ARM: dts: Enable Broadcom Cygnus SoC
ARM: cygnus defconfig : Initial defconfig for Broadcom Cygnus SoC
MAINTAINERS: Entry for Cygnus/iproc arm architecture and clock
drivers

  Documentation/devicetree/bindings/arm/cygnus.txt   |   12 +
  .../devicetree/bindings/clock/clk-cygnus.txt       |  121 ++
  .../devicetree/bindings/clock/clk-iproc.txt        |   48 +
  MAINTAINERS                                        |   21 +
  arch/arm/boot/dts/Makefile                         |    1 +
  arch/arm/boot/dts/bcm-cygnus.dtsi                  |  349 ++++++
  arch/arm/boot/dts/bcm911360_entphn.dts             |   22 +
  arch/arm/configs/bcm_cygnus_defconfig              |  223 ++++
  arch/arm/mach-bcm/Kconfig                          |   31 +
  arch/arm/mach-bcm/Makefile                         |    3 +
  arch/arm/mach-bcm/bcm_cygnus.c                     |  166 +++
  drivers/clk/Makefile                               |    1 +
  drivers/clk/bcm/Makefile                           |    2 +
  drivers/clk/bcm/clk-cygnus.c                       | 1186
++++++++++++++++++++
  drivers/clk/bcm/clk-iproc.c                        |  451 ++++++++
  15 files changed, 2637 insertions(+)
Quoted 12 lines

create mode 100644 Documentation/devicetree/bindings/arm/cygnus.txt create mode 100644
Documentation/devicetree/bindings/clock/clk-cygnus.txt
create mode 100644
Documentation/devicetree/bindings/clock/clk-iproc.txt
create mode 100644 arch/arm/boot/dts/bcm-cygnus.dtsi create mode 100644 arch/arm/boot/dts/bcm911360_entphn.dts create mode 100644 arch/arm/configs/bcm_cygnus_defconfig create mode 100644 arch/arm/mach-bcm/bcm_cygnus.c
create mode 100644 drivers/clk/bcm/clk-cygnus.c
create mode 100644 drivers/clk/bcm/clk-iproc.c

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

#25 lore raw

Scott, Jonathan,

Quoted 12 lines · Florian Fainelli

Hi Scott,

Quoted 8 lines · Scott Branden

Hi Matt/Christian (and others),

We would like to move forward in getting our base Cygnus support into the mainline kernel. From there we will be able to contribute additional drivers.

Is somebody willing to accept this pull request to get this patchset accepted by the open source community?

Quoted 6 lines

I am fine with taking the ARM patches and putting them at
http://github/brcm/linux.git, with C code in cygnus/board and the Device Tree files in cygnus/dt for instance?

The clock driver patch will have to go through Mike Turquette's tree unless he wants to delegate that one.

Could you resend patch 3 without the clock binding, patch 4 without the clocks node, and patch 6 without the drivers/clk changes? Once you do that, I can assemble these patches quickly and send a pull request which does only contain ARM SoC and DTS changes, and you can get the clock driver to be reviewed separately by its maintainer?

Thanks!

Quoted 75 lines
Quoted 74 lines

Regards,
Scott

Quoted 49 lines · Jonathan Richardson

Hi,

This patchset contains initial support for Broadcom's Cygnus SoC based on our
iProc architecture. Initial support is minimal and includes just the mach platform code, clock driver, and a basic device tree configuration. Peripheral
drivers will be submitted soon, as will device tree configurations for other
Cygnus board variants.

Changes from v1:
- Address code review comments as per previous responses.
- Copyright headers updated to remove Broadcom URL.
- mach platform code still contains hard coded adresses. These
address are
the same for all Cygnus variants. Could you please provide
guidance on where
they should go if you would still like them changed.

Thanks,
Jon

Jonathan Richardson (6):
ARM: cygnus: Initial support for Broadcom Cygnus SoC
clk: Clock driver support for Broadcom Cygnus SoC
dt-bindings: Document Broadcom Cygnus SoC and clock driver
ARM: dts: Enable Broadcom Cygnus SoC
ARM: cygnus defconfig : Initial defconfig for Broadcom Cygnus SoC
MAINTAINERS: Entry for Cygnus/iproc arm architecture and clock
drivers

  Documentation/devicetree/bindings/arm/cygnus.txt   |   12 +
  .../devicetree/bindings/clock/clk-cygnus.txt       |  121 ++
  .../devicetree/bindings/clock/clk-iproc.txt        |   48 +
  MAINTAINERS                                        |   21 +
  arch/arm/boot/dts/Makefile                         |    1 +
  arch/arm/boot/dts/bcm-cygnus.dtsi                  |  349 ++++++
  arch/arm/boot/dts/bcm911360_entphn.dts             |   22 +
  arch/arm/configs/bcm_cygnus_defconfig              |  223 ++++
  arch/arm/mach-bcm/Kconfig                          |   31 +
  arch/arm/mach-bcm/Makefile                         |    3 +
  arch/arm/mach-bcm/bcm_cygnus.c                     |  166 +++
  drivers/clk/Makefile                               |    1 +
  drivers/clk/bcm/Makefile                           |    2 +
  drivers/clk/bcm/clk-cygnus.c                       | 1186
++++++++++++++++++++
  drivers/clk/bcm/clk-iproc.c                        |  451 ++++++++
  15 files changed, 2637 insertions(+)
Quoted 12 lines

create mode 100644 Documentation/devicetree/bindings/arm/cygnus.txt create mode 100644
Documentation/devicetree/bindings/clock/clk-cygnus.txt
create mode 100644
Documentation/devicetree/bindings/clock/clk-iproc.txt
create mode 100644 arch/arm/boot/dts/bcm-cygnus.dtsi create mode 100644 arch/arm/boot/dts/bcm911360_entphn.dts create mode 100644 arch/arm/configs/bcm_cygnus_defconfig create mode 100644 arch/arm/mach-bcm/bcm_cygnus.c
create mode 100644 drivers/clk/bcm/clk-cygnus.c
create mode 100644 drivers/clk/bcm/clk-iproc.c

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

#26 lore raw
Quoted 19 lines · Florian Fainelli

Scott, Jonathan,

Quoted 16 lines · Florian Fainelli

Hi Scott,

Quoted 8 lines · Scott Branden

Hi Matt/Christian (and others),

We would like to move forward in getting our base Cygnus support into the mainline kernel. From there we will be able to contribute additional drivers.

Is somebody willing to accept this pull request to get this patchset accepted by the open source community?

I am fine with taking the ARM patches and putting them at
http://github/brcm/linux.git, with C code in cygnus/board and the Device Tree files in cygnus/dt for instance?

Quoted 8 lines
Quoted 2 lines

The clock driver patch will have to go through Mike Turquette's tree unless he wants to delegate that one.

Could you resend patch 3 without the clock binding, patch 4 without the clocks node, and patch 6 without the drivers/clk changes? Once you do that, I can assemble these patches quickly and send a pull request which does only contain ARM SoC and DTS changes, and you can get the clock driver to be reviewed separately by its maintainer?

The serial driver needs a clock so probably better not to pull out the clock nodes. It's part of the core functionality we'd like in the initial Cygnus support. I didn't hear from Mike (cc'd), though Mark reviewed it.

Thanks.

Quoted 79 lines

Thanks!

Quoted 75 lines
Quoted 74 lines

Regards,
Scott

Quoted 49 lines · Jonathan Richardson

Hi,

This patchset contains initial support for Broadcom's Cygnus SoC based on our
iProc architecture. Initial support is minimal and includes just the mach platform code, clock driver, and a basic device tree configuration. Peripheral
drivers will be submitted soon, as will device tree configurations for other
Cygnus board variants.

Changes from v1:
- Address code review comments as per previous responses.
- Copyright headers updated to remove Broadcom URL.
- mach platform code still contains hard coded adresses. These
address are
the same for all Cygnus variants. Could you please provide
guidance on where
they should go if you would still like them changed.

Thanks,
Jon

Jonathan Richardson (6):
ARM: cygnus: Initial support for Broadcom Cygnus SoC
clk: Clock driver support for Broadcom Cygnus SoC
dt-bindings: Document Broadcom Cygnus SoC and clock driver
ARM: dts: Enable Broadcom Cygnus SoC
ARM: cygnus defconfig : Initial defconfig for Broadcom Cygnus SoC
MAINTAINERS: Entry for Cygnus/iproc arm architecture and clock
drivers

  Documentation/devicetree/bindings/arm/cygnus.txt   |   12 +
  .../devicetree/bindings/clock/clk-cygnus.txt       |  121 ++
  .../devicetree/bindings/clock/clk-iproc.txt        |   48 +
  MAINTAINERS                                        |   21 +
  arch/arm/boot/dts/Makefile                         |    1 +
  arch/arm/boot/dts/bcm-cygnus.dtsi                  |  349 ++++++
  arch/arm/boot/dts/bcm911360_entphn.dts             |   22 +
  arch/arm/configs/bcm_cygnus_defconfig              |  223 ++++
  arch/arm/mach-bcm/Kconfig                          |   31 +
  arch/arm/mach-bcm/Makefile                         |    3 +
  arch/arm/mach-bcm/bcm_cygnus.c                     |  166 +++
  drivers/clk/Makefile                               |    1 +
  drivers/clk/bcm/Makefile                           |    2 +
  drivers/clk/bcm/clk-cygnus.c                       | 1186
++++++++++++++++++++
  drivers/clk/bcm/clk-iproc.c                        |  451 ++++++++
  15 files changed, 2637 insertions(+)
Quoted 12 lines

create mode 100644 Documentation/devicetree/bindings/arm/cygnus.txt create mode 100644
Documentation/devicetree/bindings/clock/clk-cygnus.txt
create mode 100644
Documentation/devicetree/bindings/clock/clk-iproc.txt
create mode 100644 arch/arm/boot/dts/bcm-cygnus.dtsi create mode 100644 arch/arm/boot/dts/bcm911360_entphn.dts create mode 100644 arch/arm/configs/bcm_cygnus_defconfig create mode 100644 arch/arm/mach-bcm/bcm_cygnus.c
create mode 100644 drivers/clk/bcm/clk-cygnus.c
create mode 100644 drivers/clk/bcm/clk-iproc.c

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

#27 lore raw
Quoted 29 lines · Jonathan Richardson
Quoted 19 lines · Florian Fainelli

Scott, Jonathan,

Quoted 16 lines · Florian Fainelli

Hi Scott,

Quoted 8 lines · Scott Branden

Hi Matt/Christian (and others),

We would like to move forward in getting our base Cygnus support into the mainline kernel. From there we will be able to contribute additional drivers.

Is somebody willing to accept this pull request to get this patchset accepted by the open source community?

I am fine with taking the ARM patches and putting them at
http://github/brcm/linux.git, with C code in cygnus/board and the Device Tree files in cygnus/dt for instance?

Quoted 8 lines
Quoted 2 lines

The clock driver patch will have to go through Mike Turquette's tree unless he wants to delegate that one.

Could you resend patch 3 without the clock binding, patch 4 without the clocks node, and patch 6 without the drivers/clk changes? Once you do that, I can assemble these patches quickly and send a pull request which does only contain ARM SoC and DTS changes, and you can get the clock driver to be reviewed separately by its maintainer?

Quoted 4 lines

The serial driver needs a clock so probably better not to pull out the clock nodes. It's part of the core functionality we'd like in the initial Cygnus support. I didn't hear from Mike (cc'd), though Mark reviewed it.

I just sent out the pull request, we'll see how it goes from there. Thanks! --
Florian

#28 lore raw

PATCH v2 1/2 pwm: kona: Fix incorrect enable, config, and disable procedures

In reply to a message not in the archive

The config procedure doesn't follow the spec which periodically results in failing to enable the output signal. This happens one in ten or twenty attempts. Following the spec and adding a 400ns delay in the appropriate locations resolves this problem. It also ensures that the signal transition is smooth.

If config is called when the pwm is disabled and there is nothing to do, the while loop to calculate duty cycle and period doesn't need to be done. The function now just returns if the pwm state is disabled.

The disable procedure now also follows the spec to ensure a smooth transition. Not following the spec can cause non-smooth transitions.

The enable procedure now clears the enabled bit if enabling failed. Enabling can fail if an invalid duty cycle and period is set. This prevents the sysfs interface from reporting the pwm is enabled after a failed call to enable.

---
 drivers/pwm/pwm-bcm-kona.c |   91 ++++++++++++++++++++++++++++++++------------
 1 file changed, 67 insertions(+), 24 deletions(-)
drivers/pwm/pwm-bcm-kona.c +67 -24
index 02bc048..6d92026 100644
@@ -80,15 +80,19 @@ static void kona_pwmc_apply_settings(struct kona_pwmc *kp, unsigned int chan)
 {
 	unsigned int value = readl(kp->base + PWM_CONTROL_OFFSET);
 
-	/* Clear trigger bit but set smooth bit to maintain old output */
-	value |= 1 << PWM_CONTROL_SMOOTH_SHIFT(chan);
-	value &= ~(1 << PWM_CONTROL_TRIGGER_SHIFT(chan));
-	writel(value, kp->base + PWM_CONTROL_OFFSET);
+	/*
+	 * There must be a min 400ns delay between clearing enable and setting
+	 * it. Failing to do this may result in no PWM signal.
+	 */
+	ndelay(400);
 
 	/* Set trigger bit and clear smooth bit to apply new settings */
 	value &= ~(1 << PWM_CONTROL_SMOOTH_SHIFT(chan));
 	value |= 1 << PWM_CONTROL_TRIGGER_SHIFT(chan);
 	writel(value, kp->base + PWM_CONTROL_OFFSET);
+
+	/* PWMOUT_ENABLE must be held high for at least 400 ns. */
+	ndelay(400);
 }
 
 static int kona_pwmc_config(struct pwm_chip *chip, struct pwm_device *pwm,
@@ -99,6 +103,9 @@ static int kona_pwmc_config(struct pwm_chip *chip, struct pwm_device *pwm,
 	unsigned long prescale = PRESCALE_MIN, pc, dc;
 	unsigned int value, chan = pwm->hwpwm;
 
+	if (!test_bit(PWMF_ENABLED, &pwm->flags))
+		return 0;
+
 	/*
 	 * Find period count, duty count and prescale to suit duty_ns and
 	 * period_ns. This is done according to formulas described below:
@@ -121,31 +128,60 @@ static int kona_pwmc_config(struct pwm_chip *chip, struct pwm_device *pwm,
 		dc = div64_u64(val, div);
 
 		/* If duty_ns or period_ns are not achievable then return */
-		if (pc < PERIOD_COUNT_MIN || dc < DUTY_CYCLE_HIGH_MIN)
+		if (pc < PERIOD_COUNT_MIN) {
+			dev_warn(chip->dev,
+				"%s: pwm[%d]: period=%d is not achievable, pc=%lu, prescale=%lu\n",
+				__func__, chan, period_ns, pc, prescale);
 			return -EINVAL;
+		}
+
+		/* If duty_ns is not achievable then return */
+		if (dc < DUTY_CYCLE_HIGH_MIN) {
+			if (0 != duty_ns) {
+				dev_warn(chip->dev,
+					"%s: pwm[%d]: duty cycle=%d is not achievable, dc=%lu, prescale=%lu\n",
+					__func__, chan, duty_ns, dc, prescale);
+			}
+			return -EINVAL;
+		}
 
 		/* If pc and dc are in bounds, the calculation is done */
 		if (pc <= PERIOD_COUNT_MAX && dc <= DUTY_CYCLE_HIGH_MAX)
 			break;
 
 		/* Otherwise, increase prescale and recalculate pc and dc */
-		if (++prescale > PRESCALE_MAX)
+		if (++prescale > PRESCALE_MAX) {
+			dev_warn(chip->dev,
+				"%s: pwm[%d]: Prescale (=%lu) within max (=%d) for period=%d and duty cycle=%d is not achievable\n",
+				__func__, chan, prescale, PRESCALE_MAX,
+				period_ns, duty_ns);
 			return -EINVAL;
+		}
 	}
 
-	/* If the PWM channel is enabled, write the settings to the HW */
-	if (test_bit(PWMF_ENABLED, &pwm->flags)) {
-		value = readl(kp->base + PRESCALE_OFFSET);
-		value &= ~PRESCALE_MASK(chan);
-		value |= prescale << PRESCALE_SHIFT(chan);
-		writel(value, kp->base + PRESCALE_OFFSET);
+	dev_dbg(chip->dev, "pwm[%d]: period=%lu, duty_high=%lu, prescale=%lu\n",
+		chan, pc, dc, prescale);
 
-		writel(pc, kp->base + PERIOD_COUNT_OFFSET(chan));
+	value = readl(kp->base + PWM_CONTROL_OFFSET);
 
-		writel(dc, kp->base + DUTY_CYCLE_HIGH_OFFSET(chan));
+	/*
+	 * Clear trigger bit but set smooth bit to maintain old
+	 * output.
+	 */
+	value |= 1 << PWM_CONTROL_SMOOTH_SHIFT(chan);
+	value &= ~(1 << PWM_CONTROL_TRIGGER_SHIFT(chan));
+	writel(value, kp->base + PWM_CONTROL_OFFSET);
 
-		kona_pwmc_apply_settings(kp, chan);
-	}
+	value = readl(kp->base + PRESCALE_OFFSET);
+	value &= ~PRESCALE_MASK(chan);
+	value |= prescale << PRESCALE_SHIFT(chan);
+	writel(value, kp->base + PRESCALE_OFFSET);
+
+	writel(pc, kp->base + PERIOD_COUNT_OFFSET(chan));
+
+	writel(dc, kp->base + DUTY_CYCLE_HIGH_OFFSET(chan));
+
+	kona_pwmc_apply_settings(kp, chan);
 
 	return 0;
 }
@@ -173,11 +209,6 @@ static int kona_pwmc_set_polarity(struct pwm_chip *chip, struct pwm_device *pwm,
 
 	writel(value, kp->base + PWM_CONTROL_OFFSET);
 
-	kona_pwmc_apply_settings(kp, chan);
-
-	/* Wait for waveform to settle before gating off the clock */
-	ndelay(400);
-
 	clk_disable_unprepare(kp->clk);
 
 	return 0;
@@ -190,12 +221,14 @@ static int kona_pwmc_enable(struct pwm_chip *chip, struct pwm_device *pwm)
 
 	ret = clk_prepare_enable(kp->clk);
 	if (ret < 0) {
+		clear_bit(PWMF_ENABLED, &pwm->flags);
 		dev_err(chip->dev, "failed to enable clock: %d\n", ret);
 		return ret;
 	}
 
 	ret = kona_pwmc_config(chip, pwm, pwm->duty_cycle, pwm->period);
 	if (ret < 0) {
+		clear_bit(PWMF_ENABLED, &pwm->flags);
 		clk_disable_unprepare(kp->clk);
 		return ret;
 	}
@@ -207,13 +240,23 @@ static void kona_pwmc_disable(struct pwm_chip *chip, struct pwm_device *pwm)
 {
 	struct kona_pwmc *kp = to_kona_pwmc(chip);
 	unsigned int chan = pwm->hwpwm;
+	unsigned int value = readl(kp->base + PWM_CONTROL_OFFSET);
+
+	/* Set smooth type to 0 and disable */
+	value &= ~(1 << PWM_CONTROL_SMOOTH_SHIFT(chan));
+	value &= ~(1 << PWM_CONTROL_TRIGGER_SHIFT(chan));
+	writel(value, kp->base + PWM_CONTROL_OFFSET);
 
 	/* Simulate a disable by configuring for zero duty */
 	writel(0, kp->base + DUTY_CYCLE_HIGH_OFFSET(chan));
-	kona_pwmc_apply_settings(kp, chan);
+	writel(0, kp->base + PERIOD_COUNT_OFFSET(chan));
 
-	/* Wait for waveform to settle before gating off the clock */
-	ndelay(400);
+	/* Set prescale to 0 for this channel */
+	value = readl(kp->base + PRESCALE_OFFSET);
+	value &= ~PRESCALE_MASK(chan);
+	writel(value, kp->base + PRESCALE_OFFSET);
+
+	kona_pwmc_apply_settings(kp, chan);
 
 	clk_disable_unprepare(kp->clk);
 }
Signature · 1 line
1.7.9.5
#29 lore raw

PATCH v2 2/2 pwm: kona: Remove setting default smooth type and polarity for all channels

Setting the default polarity in probe to normal for all channels caused the speaker pwm channel to click. The polarity does need to be set to normal because the hw default is inversed whereas the pwm framework defaults to normal. If a channel is enabled without setting the polarity then the signal would be inversed while linux reports normal. A check is now done prior to enabling the channel to ensure that the hw polarity matches the desired polarity and is changed if there is a discrepency. This prevents unnecessary settings being applied to unused channels but still ensures the correct polarity to be set.

---
 drivers/pwm/pwm-bcm-kona.c |   38 ++++++++++++++++++++++++++++++++++----
 1 file changed, 34 insertions(+), 4 deletions(-)
drivers/pwm/pwm-bcm-kona.c +34 -4
index 6d92026..46a3da5 100644
@@ -95,6 +95,32 @@ static void kona_pwmc_apply_settings(struct kona_pwmc *kp, unsigned int chan)
 	ndelay(400);
 }
 
+static void kona_pwmc_check_set_polarity(struct pwm_chip *chip,
+	struct pwm_device *pwm)
+{
+	struct kona_pwmc *kp = to_kona_pwmc(chip);
+	unsigned int chan = pwm->hwpwm;
+	enum pwm_polarity polarity = pwm->polarity;
+	unsigned int hw_pol;
+	unsigned int value = 0;
+
+	value = hw_pol = readl(kp->base + PWM_CONTROL_OFFSET);
+	hw_pol = (hw_pol >> PWM_CONTROL_POLARITY_SHIFT(chan)) & 0x1;
+
+	/*
+	 * If current polarity not the same as h/w then set polarity so that
+	 * they match.
+	 */
+	if (!hw_pol != polarity) {
+		if (polarity == PWM_POLARITY_NORMAL)
+			value |= 1 << PWM_CONTROL_POLARITY_SHIFT(chan);
+		else
+			value &= ~(1 << PWM_CONTROL_POLARITY_SHIFT(chan));
+
+		writel(value, kp->base + PWM_CONTROL_OFFSET);
+	}
+}
+
 static int kona_pwmc_config(struct pwm_chip *chip, struct pwm_device *pwm,
 			    int duty_ns, int period_ns)
 {
@@ -162,6 +188,13 @@ static int kona_pwmc_config(struct pwm_chip *chip, struct pwm_device *pwm,
 	dev_dbg(chip->dev, "pwm[%d]: period=%lu, duty_high=%lu, prescale=%lu\n",
 		chan, pc, dc, prescale);
 
+	/*
+	 * Ensure polarity is set properly. The default value for h/w and the
+	 * PWM framework are different. If a channel is enabled without setting
+	 * the polarity, the default value would be inconsistent to the signal.
+	 */
+	kona_pwmc_check_set_polarity(chip, pwm);
+
 	value = readl(kp->base + PWM_CONTROL_OFFSET);
 
 	/*
@@ -310,11 +343,8 @@ static int kona_pwmc_probe(struct platform_device *pdev)
 	}
 
 	/* Set smooth mode, push/pull, and normal polarity for all channels */
-	for (chan = 0; chan < kp->chip.npwm; chan++) {
-		value |= (1 << PWM_CONTROL_SMOOTH_SHIFT(chan));
+	for (chan = 0; chan < kp->chip.npwm; chan++)
 		value |= (1 << PWM_CONTROL_TYPE_SHIFT(chan));
-		value |= (1 << PWM_CONTROL_POLARITY_SHIFT(chan));
-	}
 
 	writel(value, kp->base + PWM_CONTROL_OFFSET);
 
Signature · 1 line
1.7.9.5
#30 lore raw

Re: [PATCH v2 1/2] pwm: kona: Fix incorrect enable, config, and disable procedures

In reply to Jonathan Richardson
Quoted 3 lines · Jonathan Richardson

If config is called when the pwm is disabled and there is nothing to do, the while loop to calculate duty cycle and period doesn't need to be done. The function now just returns if the pwm state is disabled.

It doesn't take long to figure out whether the duty and period are achievable.

If the caller specifies bad settings, why not return an error immediately?

Quoted 17 lines
drivers/pwm/pwm-bcm-kona.c +7 -2
@@ -207,13 +240,23 @@ static void kona_pwmc_disable(struct pwm_chip *chip, struct pwm_device *pwm)
 {
        struct kona_pwmc *kp = to_kona_pwmc(chip);
        unsigned int chan = pwm->hwpwm;
+       unsigned int value = readl(kp->base + PWM_CONTROL_OFFSET);
+
+       /* Set smooth type to 0 and disable */
+       value &= ~(1 << PWM_CONTROL_SMOOTH_SHIFT(chan));
+       value &= ~(1 << PWM_CONTROL_TRIGGER_SHIFT(chan));
+       writel(value, kp->base + PWM_CONTROL_OFFSET);
 
        /* Simulate a disable by configuring for zero duty */
        writel(0, kp->base + DUTY_CYCLE_HIGH_OFFSET(chan));
-       kona_pwmc_apply_settings(kp, chan);
+       writel(0, kp->base + PERIOD_COUNT_OFFSET(chan));
 
-       /* Wait for waveform to settle before gating off the clock */

drivers/pwm/pwm-bcm-kona.c static void kona_pwmc_disable(struct pwm_chip *chip, struct pwm_device *pwm) · line 262

Quoted 10 lines
drivers/pwm/pwm-bcm-kona.c +6 -1
-       ndelay(400);
+       /* Set prescale to 0 for this channel */
+       value = readl(kp->base + PRESCALE_OFFSET);
+       value &= ~PRESCALE_MASK(chan);
+       writel(value, kp->base + PRESCALE_OFFSET);
+
+       kona_pwmc_apply_settings(kp, chan);
 
        clk_disable_unprepare(kp->clk);
 }

I've mentioned this before but I will say it again, when the smooth and trigger bit are both low, the output is constant high.

If you look at the PWM output on a scope you will see it go high for 400 ns during your disable even if the duty prior to the disable was zero.

How are you testing your proposed changes?

Thanks,
Tim Kryger

#31 lore raw

Re: [PATCH v2 1/2] pwm: kona: Fix incorrect enable, config, and disable procedures

Quoted 10 lines · Tim Kryger
Quoted 3 lines · Jonathan Richardson

If config is called when the pwm is disabled and there is nothing to do, the while loop to calculate duty cycle and period doesn't need to be done. The function now just returns if the pwm state is disabled.

It doesn't take long to figure out whether the duty and period are achievable.

If the caller specifies bad settings, why not return an error immediately?

Sorry, not sure what you're suggesting here. It's returning as soon as it can isn't it? Nothing changed in the way the period and duty cycle were calculated and checked in the while loop.

Quoted 32 lines
Quoted 18 lines
drivers/pwm/pwm-bcm-kona.c +7 -2
@@ -207,13 +240,23 @@ static void kona_pwmc_disable(struct pwm_chip *chip, struct pwm_device *pwm)
 {
        struct kona_pwmc *kp = to_kona_pwmc(chip);
        unsigned int chan = pwm->hwpwm;
+       unsigned int value = readl(kp->base + PWM_CONTROL_OFFSET);
+
+       /* Set smooth type to 0 and disable */
+       value &= ~(1 << PWM_CONTROL_SMOOTH_SHIFT(chan));
+       value &= ~(1 << PWM_CONTROL_TRIGGER_SHIFT(chan));
+       writel(value, kp->base + PWM_CONTROL_OFFSET);
 
        /* Simulate a disable by configuring for zero duty */
        writel(0, kp->base + DUTY_CYCLE_HIGH_OFFSET(chan));
-       kona_pwmc_apply_settings(kp, chan);
+       writel(0, kp->base + PERIOD_COUNT_OFFSET(chan));
 
-       /* Wait for waveform to settle before gating off the clock */

drivers/pwm/pwm-bcm-kona.c static void kona_pwmc_disable(struct pwm_chip *chip, struct pwm_device *pwm) · line 262

Quoted 10 lines
drivers/pwm/pwm-bcm-kona.c +6 -1
-       ndelay(400);
+       /* Set prescale to 0 for this channel */
+       value = readl(kp->base + PRESCALE_OFFSET);
+       value &= ~PRESCALE_MASK(chan);
+       writel(value, kp->base + PRESCALE_OFFSET);
+
+       kona_pwmc_apply_settings(kp, chan);
 
        clk_disable_unprepare(kp->clk);
 }

I've mentioned this before but I will say it again, when the smooth and trigger bit are both low, the output is constant high.

Quoted 6 lines

If you look at the PWM output on a scope you will see it go high for 400 ns during your disable even if the duty prior to the disable was zero.

How are you testing your proposed changes?

I see what you mean now and verified it. For a smooth transition even on disable the smooth bit should be set high, not low. It's the same procedure as in config. Setting the bit high instead of low gets rid of the 400ns transition high. I can make this change.

Quoted 3 lines

Thanks,
Tim Kryger

#32 lore raw

PATCH v3 1/2 pwm: kona: Fix incorrect enable, config, and disable procedures

In reply to a message not in the archive

The config procedure doesn't follow the spec which periodically results in failing to enable the output signal. This happens one in ten or twenty attempts. Following the spec and adding a 400ns delay in the appropriate locations resolves this problem. It also ensures that the signal transition is smooth.

If config is called when the pwm is disabled and there is nothing to do, the while loop to calculate duty cycle and period doesn't need to be done. The function now just returns if the pwm state is disabled.

The disable procedure now also follows the spec to ensure a smooth transition. Not following the spec can cause non-smooth transitions.

The enable procedure now clears the enabled bit if enabling failed. Enabling can fail if an invalid duty cycle and period is set. This prevents the sysfs interface from reporting the pwm is enabled after a failed call to enable.

---
 drivers/pwm/pwm-bcm-kona.c |   91 ++++++++++++++++++++++++++++++++------------
 1 file changed, 67 insertions(+), 24 deletions(-)
drivers/pwm/pwm-bcm-kona.c +67 -24
index 02bc048..a831bb2 100644
@@ -80,15 +80,19 @@ static void kona_pwmc_apply_settings(struct kona_pwmc *kp, unsigned int chan)
 {
 	unsigned int value = readl(kp->base + PWM_CONTROL_OFFSET);
 
-	/* Clear trigger bit but set smooth bit to maintain old output */
-	value |= 1 << PWM_CONTROL_SMOOTH_SHIFT(chan);
-	value &= ~(1 << PWM_CONTROL_TRIGGER_SHIFT(chan));
-	writel(value, kp->base + PWM_CONTROL_OFFSET);
+	/*
+	 * There must be a min 400ns delay between clearing enable and setting
+	 * it. Failing to do this may result in no PWM signal.
+	 */
+	ndelay(400);
 
 	/* Set trigger bit and clear smooth bit to apply new settings */
 	value &= ~(1 << PWM_CONTROL_SMOOTH_SHIFT(chan));
 	value |= 1 << PWM_CONTROL_TRIGGER_SHIFT(chan);
 	writel(value, kp->base + PWM_CONTROL_OFFSET);
+
+	/* PWMOUT_ENABLE must be held high for at least 400 ns. */
+	ndelay(400);
 }
 
 static int kona_pwmc_config(struct pwm_chip *chip, struct pwm_device *pwm,
@@ -99,6 +103,9 @@ static int kona_pwmc_config(struct pwm_chip *chip, struct pwm_device *pwm,
 	unsigned long prescale = PRESCALE_MIN, pc, dc;
 	unsigned int value, chan = pwm->hwpwm;
 
+	if (!test_bit(PWMF_ENABLED, &pwm->flags))
+		return 0;
+
 	/*
 	 * Find period count, duty count and prescale to suit duty_ns and
 	 * period_ns. This is done according to formulas described below:
@@ -121,31 +128,60 @@ static int kona_pwmc_config(struct pwm_chip *chip, struct pwm_device *pwm,
 		dc = div64_u64(val, div);
 
 		/* If duty_ns or period_ns are not achievable then return */
-		if (pc < PERIOD_COUNT_MIN || dc < DUTY_CYCLE_HIGH_MIN)
+		if (pc < PERIOD_COUNT_MIN) {
+			dev_warn(chip->dev,
+				"%s: pwm[%d]: period=%d is not achievable, pc=%lu, prescale=%lu\n",
+				__func__, chan, period_ns, pc, prescale);
 			return -EINVAL;
+		}
+
+		/* If duty_ns is not achievable then return */
+		if (dc < DUTY_CYCLE_HIGH_MIN) {
+			if (0 != duty_ns) {
+				dev_warn(chip->dev,
+					"%s: pwm[%d]: duty cycle=%d is not achievable, dc=%lu, prescale=%lu\n",
+					__func__, chan, duty_ns, dc, prescale);
+			}
+			return -EINVAL;
+		}
 
 		/* If pc and dc are in bounds, the calculation is done */
 		if (pc <= PERIOD_COUNT_MAX && dc <= DUTY_CYCLE_HIGH_MAX)
 			break;
 
 		/* Otherwise, increase prescale and recalculate pc and dc */
-		if (++prescale > PRESCALE_MAX)
+		if (++prescale > PRESCALE_MAX) {
+			dev_warn(chip->dev,
+				"%s: pwm[%d]: Prescale (=%lu) within max (=%d) for period=%d and duty cycle=%d is not achievable\n",
+				__func__, chan, prescale, PRESCALE_MAX,
+				period_ns, duty_ns);
 			return -EINVAL;
+		}
 	}
 
-	/* If the PWM channel is enabled, write the settings to the HW */
-	if (test_bit(PWMF_ENABLED, &pwm->flags)) {
-		value = readl(kp->base + PRESCALE_OFFSET);
-		value &= ~PRESCALE_MASK(chan);
-		value |= prescale << PRESCALE_SHIFT(chan);
-		writel(value, kp->base + PRESCALE_OFFSET);
+	dev_dbg(chip->dev, "pwm[%d]: period=%lu, duty_high=%lu, prescale=%lu\n",
+		chan, pc, dc, prescale);
 
-		writel(pc, kp->base + PERIOD_COUNT_OFFSET(chan));
+	value = readl(kp->base + PWM_CONTROL_OFFSET);
 
-		writel(dc, kp->base + DUTY_CYCLE_HIGH_OFFSET(chan));
+	/*
+	 * Clear trigger bit but set smooth bit to maintain old
+	 * output.
+	 */
+	value |= 1 << PWM_CONTROL_SMOOTH_SHIFT(chan);
+	value &= ~(1 << PWM_CONTROL_TRIGGER_SHIFT(chan));
+	writel(value, kp->base + PWM_CONTROL_OFFSET);
 
-		kona_pwmc_apply_settings(kp, chan);
-	}
+	value = readl(kp->base + PRESCALE_OFFSET);
+	value &= ~PRESCALE_MASK(chan);
+	value |= prescale << PRESCALE_SHIFT(chan);
+	writel(value, kp->base + PRESCALE_OFFSET);
+
+	writel(pc, kp->base + PERIOD_COUNT_OFFSET(chan));
+
+	writel(dc, kp->base + DUTY_CYCLE_HIGH_OFFSET(chan));
+
+	kona_pwmc_apply_settings(kp, chan);
 
 	return 0;
 }
@@ -173,11 +209,6 @@ static int kona_pwmc_set_polarity(struct pwm_chip *chip, struct pwm_device *pwm,
 
 	writel(value, kp->base + PWM_CONTROL_OFFSET);
 
-	kona_pwmc_apply_settings(kp, chan);
-
-	/* Wait for waveform to settle before gating off the clock */
-	ndelay(400);
-
 	clk_disable_unprepare(kp->clk);
 
 	return 0;
@@ -190,12 +221,14 @@ static int kona_pwmc_enable(struct pwm_chip *chip, struct pwm_device *pwm)
 
 	ret = clk_prepare_enable(kp->clk);
 	if (ret < 0) {
+		clear_bit(PWMF_ENABLED, &pwm->flags);
 		dev_err(chip->dev, "failed to enable clock: %d\n", ret);
 		return ret;
 	}
 
 	ret = kona_pwmc_config(chip, pwm, pwm->duty_cycle, pwm->period);
 	if (ret < 0) {
+		clear_bit(PWMF_ENABLED, &pwm->flags);
 		clk_disable_unprepare(kp->clk);
 		return ret;
 	}
@@ -207,13 +240,23 @@ static void kona_pwmc_disable(struct pwm_chip *chip, struct pwm_device *pwm)
 {
 	struct kona_pwmc *kp = to_kona_pwmc(chip);
 	unsigned int chan = pwm->hwpwm;
+	unsigned int value = readl(kp->base + PWM_CONTROL_OFFSET);
+
+	/* Set smooth type to 1 and disable */
+	value |= 1 << PWM_CONTROL_SMOOTH_SHIFT(chan);
+	value &= ~(1 << PWM_CONTROL_TRIGGER_SHIFT(chan));
+	writel(value, kp->base + PWM_CONTROL_OFFSET);
 
 	/* Simulate a disable by configuring for zero duty */
 	writel(0, kp->base + DUTY_CYCLE_HIGH_OFFSET(chan));
-	kona_pwmc_apply_settings(kp, chan);
+	writel(0, kp->base + PERIOD_COUNT_OFFSET(chan));
 
-	/* Wait for waveform to settle before gating off the clock */
-	ndelay(400);
+	/* Set prescale to 0 for this channel */
+	value = readl(kp->base + PRESCALE_OFFSET);
+	value &= ~PRESCALE_MASK(chan);
+	writel(value, kp->base + PRESCALE_OFFSET);
+
+	kona_pwmc_apply_settings(kp, chan);
 
 	clk_disable_unprepare(kp->clk);
 }
Signature · 1 line
1.7.9.5
#33 lore raw

PATCH v3 2/2 pwm: kona: Remove setting default smooth type and polarity for all channels

Setting the default polarity in probe to normal for all channels caused the speaker pwm channel to click. The polarity does need to be set to normal because the hw default is inversed whereas the pwm framework defaults to normal. If a channel is enabled without setting the polarity then the signal would be inversed while linux reports normal. A check is now done prior to enabling the channel to ensure that the hw polarity matches the desired polarity and is changed if there is a discrepency. This prevents unnecessary settings being applied to unused channels but still ensures the correct polarity to be set.

---
 drivers/pwm/pwm-bcm-kona.c |   38 ++++++++++++++++++++++++++++++++++----
 1 file changed, 34 insertions(+), 4 deletions(-)
drivers/pwm/pwm-bcm-kona.c +34 -4
index a831bb2..101137d 100644
@@ -95,6 +95,32 @@ static void kona_pwmc_apply_settings(struct kona_pwmc *kp, unsigned int chan)
 	ndelay(400);
 }
 
+static void kona_pwmc_check_set_polarity(struct pwm_chip *chip,
+	struct pwm_device *pwm)
+{
+	struct kona_pwmc *kp = to_kona_pwmc(chip);
+	unsigned int chan = pwm->hwpwm;
+	enum pwm_polarity polarity = pwm->polarity;
+	unsigned int hw_pol;
+	unsigned int value = 0;
+
+	value = hw_pol = readl(kp->base + PWM_CONTROL_OFFSET);
+	hw_pol = (hw_pol >> PWM_CONTROL_POLARITY_SHIFT(chan)) & 0x1;
+
+	/*
+	 * If current polarity not the same as h/w then set polarity so that
+	 * they match.
+	 */
+	if (!hw_pol != polarity) {
+		if (polarity == PWM_POLARITY_NORMAL)
+			value |= 1 << PWM_CONTROL_POLARITY_SHIFT(chan);
+		else
+			value &= ~(1 << PWM_CONTROL_POLARITY_SHIFT(chan));
+
+		writel(value, kp->base + PWM_CONTROL_OFFSET);
+	}
+}
+
 static int kona_pwmc_config(struct pwm_chip *chip, struct pwm_device *pwm,
 			    int duty_ns, int period_ns)
 {
@@ -162,6 +188,13 @@ static int kona_pwmc_config(struct pwm_chip *chip, struct pwm_device *pwm,
 	dev_dbg(chip->dev, "pwm[%d]: period=%lu, duty_high=%lu, prescale=%lu\n",
 		chan, pc, dc, prescale);
 
+	/*
+	 * Ensure polarity is set properly. The default value for h/w and the
+	 * PWM framework are different. If a channel is enabled without setting
+	 * the polarity, the default value would be inconsistent to the signal.
+	 */
+	kona_pwmc_check_set_polarity(chip, pwm);
+
 	value = readl(kp->base + PWM_CONTROL_OFFSET);
 
 	/*
@@ -310,11 +343,8 @@ static int kona_pwmc_probe(struct platform_device *pdev)
 	}
 
 	/* Set smooth mode, push/pull, and normal polarity for all channels */
-	for (chan = 0; chan < kp->chip.npwm; chan++) {
-		value |= (1 << PWM_CONTROL_SMOOTH_SHIFT(chan));
+	for (chan = 0; chan < kp->chip.npwm; chan++)
 		value |= (1 << PWM_CONTROL_TYPE_SHIFT(chan));
-		value |= (1 << PWM_CONTROL_POLARITY_SHIFT(chan));
-	}
 
 	writel(value, kp->base + PWM_CONTROL_OFFSET);
 
Signature · 1 line
1.7.9.5
#34 lore raw

Re: [PATCH v3 1/2] pwm: kona: Fix incorrect enable, config, and disable procedures

In reply to Jonathan Richardson
Quoted 5 lines · Jonathan Richardson

The config procedure doesn't follow the spec which periodically results in failing to enable the output signal. This happens one in ten or twenty attempts. Following the spec and adding a 400ns delay in the appropriate locations resolves this problem. It also ensures that the signal transition is smooth.

This patch does not result in smooth transitions.

Please ensure that your commit message reflects the code.

Quoted 13 lines

If config is called when the pwm is disabled and there is nothing to do, the while loop to calculate duty cycle and period doesn't need to be done. The function now just returns if the pwm state is disabled.

The disable procedure now also follows the spec to ensure a smooth transition. Not following the spec can cause non-smooth transitions.

The enable procedure now clears the enabled bit if enabling failed. Enabling can fail if an invalid duty cycle and period is set. This prevents the sysfs interface from reporting the pwm is enabled after a failed call to enable.

Quoted 4 lines

Normally when people send a multi-part patch series they include a cover letter that describes the overall purpose of the changes with a description of changes introduced in each revision of the series.

Please follow this convention.

Quoted 21 lines
---
 drivers/pwm/pwm-bcm-kona.c |   91 ++++++++++++++++++++++++++++++++------------
 1 file changed, 67 insertions(+), 24 deletions(-)
drivers/pwm/pwm-bcm-kona.c +5 -4
index 02bc048..a831bb2 100644
@@ -80,15 +80,19 @@ static void kona_pwmc_apply_settings(struct kona_pwmc *kp, unsigned int chan)
 {
        unsigned int value = readl(kp->base + PWM_CONTROL_OFFSET);
 
-       /* Clear trigger bit but set smooth bit to maintain old output */
-       value |= 1 << PWM_CONTROL_SMOOTH_SHIFT(chan);
-       value &= ~(1 << PWM_CONTROL_TRIGGER_SHIFT(chan));
-       writel(value, kp->base + PWM_CONTROL_OFFSET);
+       /*
+        * There must be a min 400ns delay between clearing enable and setting
+        * it. Failing to do this may result in no PWM signal.
+        */
+       ndelay(400);

drivers/pwm/pwm-bcm-kona.c static void kona_pwmc_apply_settings(struct kona_pwmc *kp, unsigned int chan) · line 97

Quoted 10 lines
drivers/pwm/pwm-bcm-kona.c +3 -0
 
        /* Set trigger bit and clear smooth bit to apply new settings */
        value &= ~(1 << PWM_CONTROL_SMOOTH_SHIFT(chan));
        value |= 1 << PWM_CONTROL_TRIGGER_SHIFT(chan);
        writel(value, kp->base + PWM_CONTROL_OFFSET);
+
+       /* PWMOUT_ENABLE must be held high for at least 400 ns. */
+       ndelay(400);
 }
 

Can you try to get a better understanding of what these timing requirements actually are?

When I wrote this driver, the documentation simply stated that if the trigger bit didn't stay high for 400 ns then the new settings would not get applied.

It wasn't essential that we wait 400 ns here because the only time when the trigger bit would be lowered is when we were about to load even newer settings which meant we didn't care if the previous settings were lost.

drivers/pwm/pwm-bcm-kona.c static int kona_pwmc_config(struct pwm_chip *chip, struct pwm_device *pwm, · line 111

Quoted 11 lines
drivers/pwm/pwm-bcm-kona.c +3 -0
 static int kona_pwmc_config(struct pwm_chip *chip, struct pwm_device *pwm,
@@ -99,6 +103,9 @@ static int kona_pwmc_config(struct pwm_chip *chip, struct pwm_device *pwm,
        unsigned long prescale = PRESCALE_MIN, pc, dc;
        unsigned int value, chan = pwm->hwpwm;
 
+       if (!test_bit(PWMF_ENABLED, &pwm->flags))
+               return 0;
+
        /*
         * Find period count, duty count and prescale to suit duty_ns and
         * period_ns. This is done according to formulas described below:

Like I said last time, this is wrong. You need to sanity check the requested period and duty cycle here.

You can't just return success immediately when the channel isn't enabled.

Quoted 63 lines
drivers/pwm/pwm-bcm-kona.c +34 -12
@@ -121,31 +128,60 @@ static int kona_pwmc_config(struct pwm_chip *chip, struct pwm_device *pwm,
                dc = div64_u64(val, div);
 
                /* If duty_ns or period_ns are not achievable then return */
-               if (pc < PERIOD_COUNT_MIN || dc < DUTY_CYCLE_HIGH_MIN)
+               if (pc < PERIOD_COUNT_MIN) {
+                       dev_warn(chip->dev,
+                               "%s: pwm[%d]: period=%d is not achievable, pc=%lu, prescale=%lu\n",
+                               __func__, chan, period_ns, pc, prescale);
                        return -EINVAL;
+               }
+
+               /* If duty_ns is not achievable then return */
+               if (dc < DUTY_CYCLE_HIGH_MIN) {
+                       if (0 != duty_ns) {
+                               dev_warn(chip->dev,
+                                       "%s: pwm[%d]: duty cycle=%d is not achievable, dc=%lu, prescale=%lu\n",
+                                       __func__, chan, duty_ns, dc, prescale);
+                       }
+                       return -EINVAL;
+               }
 
                /* If pc and dc are in bounds, the calculation is done */
                if (pc <= PERIOD_COUNT_MAX && dc <= DUTY_CYCLE_HIGH_MAX)
                        break;
 
                /* Otherwise, increase prescale and recalculate pc and dc */
-               if (++prescale > PRESCALE_MAX)
+               if (++prescale > PRESCALE_MAX) {
+                       dev_warn(chip->dev,
+                               "%s: pwm[%d]: Prescale (=%lu) within max (=%d) for period=%d and duty cycle=%d is not achievable\n",
+                               __func__, chan, prescale, PRESCALE_MAX,
+                               period_ns, duty_ns);
                        return -EINVAL;
+               }
        }
 
-       /* If the PWM channel is enabled, write the settings to the HW */
-       if (test_bit(PWMF_ENABLED, &pwm->flags)) {
-               value = readl(kp->base + PRESCALE_OFFSET);
-               value &= ~PRESCALE_MASK(chan);
-               value |= prescale << PRESCALE_SHIFT(chan);
-               writel(value, kp->base + PRESCALE_OFFSET);
+       dev_dbg(chip->dev, "pwm[%d]: period=%lu, duty_high=%lu, prescale=%lu\n",
+               chan, pc, dc, prescale);
 
-               writel(pc, kp->base + PERIOD_COUNT_OFFSET(chan));
+       value = readl(kp->base + PWM_CONTROL_OFFSET);
 
-               writel(dc, kp->base + DUTY_CYCLE_HIGH_OFFSET(chan));
+       /*
+        * Clear trigger bit but set smooth bit to maintain old
+        * output.
+        */
+       value |= 1 << PWM_CONTROL_SMOOTH_SHIFT(chan);
+       value &= ~(1 << PWM_CONTROL_TRIGGER_SHIFT(chan));
+       writel(value, kp->base + PWM_CONTROL_OFFSET);
 
-               kona_pwmc_apply_settings(kp, chan);
-       }
+       value = readl(kp->base + PRESCALE_OFFSET);
+       value &= ~PRESCALE_MASK(chan);
+       value |= prescale << PRESCALE_SHIFT(chan);

drivers/pwm/pwm-bcm-kona.c static int kona_pwmc_config(struct pwm_chip *chip, struct pwm_device *pwm, · line 187

Quoted 10 lines
drivers/pwm/pwm-bcm-kona.c +7 -0
+       writel(value, kp->base + PRESCALE_OFFSET);
+
+       writel(pc, kp->base + PERIOD_COUNT_OFFSET(chan));
+
+       writel(dc, kp->base + DUTY_CYCLE_HIGH_OFFSET(chan));
+
+       kona_pwmc_apply_settings(kp, chan);
 
        return 0;
 }

There is no requirement to lower the trigger bit prior to writing the period and duty registers.

This change is unnecessary. The old sequence was fine.

drivers/pwm/pwm-bcm-kona.c static int kona_pwmc_set_polarity(struct pwm_chip *chip, struct pwm_device *pwm, · line 214

Quoted 12 lines
drivers/pwm/pwm-bcm-kona.c +0 -5
@@ -173,11 +209,6 @@ static int kona_pwmc_set_polarity(struct pwm_chip *chip, struct pwm_device *pwm,
 
        writel(value, kp->base + PWM_CONTROL_OFFSET);
 
-       kona_pwmc_apply_settings(kp, chan);
-
-       /* Wait for waveform to settle before gating off the clock */
-       ndelay(400);
-
        clk_disable_unprepare(kp->clk);
 
        return 0;

I'm not completely convinced that changing the polarity behavior is beneficial.

Please mention this change in your commit description and provide appropriate justification.

Quoted 5 lines
drivers/pwm/pwm-bcm-kona.c +1 -0
@@ -190,12 +221,14 @@ static int kona_pwmc_enable(struct pwm_chip *chip, struct pwm_device *pwm)
 
        ret = clk_prepare_enable(kp->clk);
        if (ret < 0) {
+               clear_bit(PWMF_ENABLED, &pwm->flags);

drivers/pwm/pwm-bcm-kona.c static int kona_pwmc_enable(struct pwm_chip *chip, struct pwm_device *pwm) · line 234

Quoted 10 lines
drivers/pwm/pwm-bcm-kona.c +1 -0
                dev_err(chip->dev, "failed to enable clock: %d\n", ret);
                return ret;
        }
 
        ret = kona_pwmc_config(chip, pwm, pwm->duty_cycle, pwm->period);
        if (ret < 0) {
+               clear_bit(PWMF_ENABLED, &pwm->flags);
                clk_disable_unprepare(kp->clk);
                return ret;
        }

Don't try to fix this in the Kona PWM driver, fix it in the PWM core.

Quoted 12 lines
drivers/pwm/pwm-bcm-kona.c +6 -0
@@ -207,13 +240,23 @@ static void kona_pwmc_disable(struct pwm_chip *chip, struct pwm_device *pwm)
 {
        struct kona_pwmc *kp = to_kona_pwmc(chip);
        unsigned int chan = pwm->hwpwm;
+       unsigned int value = readl(kp->base + PWM_CONTROL_OFFSET);
+
+       /* Set smooth type to 1 and disable */
+       value |= 1 << PWM_CONTROL_SMOOTH_SHIFT(chan);
+       value &= ~(1 << PWM_CONTROL_TRIGGER_SHIFT(chan));
+       writel(value, kp->base + PWM_CONTROL_OFFSET);
 
        /* Simulate a disable by configuring for zero duty */

drivers/pwm/pwm-bcm-kona.c static void kona_pwmc_disable(struct pwm_chip *chip, struct pwm_device *pwm) · line 257

Quoted 10 lines
drivers/pwm/pwm-bcm-kona.c +5 -3
        writel(0, kp->base + DUTY_CYCLE_HIGH_OFFSET(chan));
-       kona_pwmc_apply_settings(kp, chan);
+       writel(0, kp->base + PERIOD_COUNT_OFFSET(chan));
 
-       /* Wait for waveform to settle before gating off the clock */
-       ndelay(400);
+       /* Set prescale to 0 for this channel */
+       value = readl(kp->base + PRESCALE_OFFSET);
+       value &= ~PRESCALE_MASK(chan);
+       writel(value, kp->base + PRESCALE_OFFSET);

Can you explain why it is necessary to change the prescale here?

Quoted 8 lines
drivers/pwm/pwm-bcm-kona.c +2 -1
+
+       kona_pwmc_apply_settings(kp, chan);
 
        clk_disable_unprepare(kp->clk);
 }
--

1.7.9.5

#35 lore raw

Re: [PATCH v3 1/2] pwm: kona: Fix incorrect enable, config, and disable procedures

Quoted 11 lines · Tim Kryger
Quoted 5 lines · Jonathan Richardson

The config procedure doesn't follow the spec which periodically results in failing to enable the output signal. This happens one in ten or twenty attempts. Following the spec and adding a 400ns delay in the appropriate locations resolves this problem. It also ensures that the signal transition is smooth.

This patch does not result in smooth transitions.

Please ensure that your commit message reflects the code.

I'll remove the last sentence. I would have to re-verify that it's accurate.

Quoted 19 lines
Quoted 14 lines

If config is called when the pwm is disabled and there is nothing to do, the while loop to calculate duty cycle and period doesn't need to be done. The function now just returns if the pwm state is disabled.

The disable procedure now also follows the spec to ensure a smooth transition. Not following the spec can cause non-smooth transitions.

The enable procedure now clears the enabled bit if enabling failed. Enabling can fail if an invalid duty cycle and period is set. This prevents the sysfs interface from reporting the pwm is enabled after a failed call to enable.

Quoted 4 lines
Quoted 5 lines

Normally when people send a multi-part patch series they include a cover letter that describes the overall purpose of the changes with a description of changes introduced in each revision of the series.

Please follow this convention.

Will do.

Quoted 36 lines
Quoted 22 lines
---
 drivers/pwm/pwm-bcm-kona.c |   91 ++++++++++++++++++++++++++++++++------------
 1 file changed, 67 insertions(+), 24 deletions(-)
drivers/pwm/pwm-bcm-kona.c +5 -4
index 02bc048..a831bb2 100644
@@ -80,15 +80,19 @@ static void kona_pwmc_apply_settings(struct kona_pwmc *kp, unsigned int chan)
 {
        unsigned int value = readl(kp->base + PWM_CONTROL_OFFSET);
 
-       /* Clear trigger bit but set smooth bit to maintain old output */
-       value |= 1 << PWM_CONTROL_SMOOTH_SHIFT(chan);
-       value &= ~(1 << PWM_CONTROL_TRIGGER_SHIFT(chan));
-       writel(value, kp->base + PWM_CONTROL_OFFSET);
+       /*
+        * There must be a min 400ns delay between clearing enable and setting
+        * it. Failing to do this may result in no PWM signal.
+        */
+       ndelay(400);

drivers/pwm/pwm-bcm-kona.c static void kona_pwmc_apply_settings(struct kona_pwmc *kp, unsigned int chan) · line 97

Quoted 10 lines
drivers/pwm/pwm-bcm-kona.c +3 -0
 
        /* Set trigger bit and clear smooth bit to apply new settings */
        value &= ~(1 << PWM_CONTROL_SMOOTH_SHIFT(chan));
        value |= 1 << PWM_CONTROL_TRIGGER_SHIFT(chan);
        writel(value, kp->base + PWM_CONTROL_OFFSET);
+
+       /* PWMOUT_ENABLE must be held high for at least 400 ns. */
+       ndelay(400);
 }
 

Can you try to get a better understanding of what these timing requirements actually are?

Quoted 8 lines

When I wrote this driver, the documentation simply stated that if the trigger bit didn't stay high for 400 ns then the new settings would not get applied.

It wasn't essential that we wait 400 ns here because the only time when the trigger bit would be lowered is when we were about to load even newer settings which meant we didn't care if the previous settings were lost.

I'm not spending any more time trying to understand exactly why these delays are required. All I know is that they are required. Failing to follow the updated documentation from the ASIC engineers sometimes resulted in no output signal as stated in the commit message. The docs you had at the time may have been inaccurate or incomplete.

Quoted 6 lines
Quoted 6 lines
drivers/pwm/pwm-bcm-kona.c +0 -0
 static int kona_pwmc_config(struct pwm_chip *chip, struct pwm_device *pwm,
@@ -99,6 +103,9 @@ static int kona_pwmc_config(struct pwm_chip *chip, struct pwm_device *pwm,
        unsigned long prescale = PRESCALE_MIN, pc, dc;
        unsigned int value, chan = pwm->hwpwm;
 
Quoted 9 lines

drivers/pwm/pwm-bcm-kona.c static int kona_pwmc_config(struct pwm_chip *chip, struct pwm_device *pwm, · line 111

Quoted 6 lines
drivers/pwm/pwm-bcm-kona.c +3 -0
+       if (!test_bit(PWMF_ENABLED, &pwm->flags))
+               return 0;
+
        /*
         * Find period count, duty count and prescale to suit duty_ns and
         * period_ns. This is done according to formulas described below:

Like I said last time, this is wrong. You need to sanity check the requested period and duty cycle here.

I don't agree. I actually like the code in its original form in this case. The period and duty cycle are calculated as a function of the prescale so the loop is responsible for figuring out what values are correct or not as it iterates. Unless there is a more compelling reason to change it, I'm going to leave it as is.

Quoted 2 lines

You can't just return success immediately when the channel isn't enabled.

I'll make it return an error.

Quoted 72 lines
Quoted 72 lines
drivers/pwm/pwm-bcm-kona.c +41 -12
@@ -121,31 +128,60 @@ static int kona_pwmc_config(struct pwm_chip *chip, struct pwm_device *pwm,
                dc = div64_u64(val, div);
 
                /* If duty_ns or period_ns are not achievable then return */
-               if (pc < PERIOD_COUNT_MIN || dc < DUTY_CYCLE_HIGH_MIN)
+               if (pc < PERIOD_COUNT_MIN) {
+                       dev_warn(chip->dev,
+                               "%s: pwm[%d]: period=%d is not achievable, pc=%lu, prescale=%lu\n",
+                               __func__, chan, period_ns, pc, prescale);
                        return -EINVAL;
+               }
+
+               /* If duty_ns is not achievable then return */
+               if (dc < DUTY_CYCLE_HIGH_MIN) {
+                       if (0 != duty_ns) {
+                               dev_warn(chip->dev,
+                                       "%s: pwm[%d]: duty cycle=%d is not achievable, dc=%lu, prescale=%lu\n",
+                                       __func__, chan, duty_ns, dc, prescale);
+                       }
+                       return -EINVAL;
+               }
 
                /* If pc and dc are in bounds, the calculation is done */
                if (pc <= PERIOD_COUNT_MAX && dc <= DUTY_CYCLE_HIGH_MAX)
                        break;
 
                /* Otherwise, increase prescale and recalculate pc and dc */
-               if (++prescale > PRESCALE_MAX)
+               if (++prescale > PRESCALE_MAX) {
+                       dev_warn(chip->dev,
+                               "%s: pwm[%d]: Prescale (=%lu) within max (=%d) for period=%d and duty cycle=%d is not achievable\n",
+                               __func__, chan, prescale, PRESCALE_MAX,
+                               period_ns, duty_ns);
                        return -EINVAL;
+               }
        }
 
-       /* If the PWM channel is enabled, write the settings to the HW */
-       if (test_bit(PWMF_ENABLED, &pwm->flags)) {
-               value = readl(kp->base + PRESCALE_OFFSET);
-               value &= ~PRESCALE_MASK(chan);
-               value |= prescale << PRESCALE_SHIFT(chan);
-               writel(value, kp->base + PRESCALE_OFFSET);
+       dev_dbg(chip->dev, "pwm[%d]: period=%lu, duty_high=%lu, prescale=%lu\n",
+               chan, pc, dc, prescale);
 
-               writel(pc, kp->base + PERIOD_COUNT_OFFSET(chan));
+       value = readl(kp->base + PWM_CONTROL_OFFSET);
 
-               writel(dc, kp->base + DUTY_CYCLE_HIGH_OFFSET(chan));
+       /*
+        * Clear trigger bit but set smooth bit to maintain old
+        * output.
+        */
+       value |= 1 << PWM_CONTROL_SMOOTH_SHIFT(chan);
+       value &= ~(1 << PWM_CONTROL_TRIGGER_SHIFT(chan));
+       writel(value, kp->base + PWM_CONTROL_OFFSET);
 
-               kona_pwmc_apply_settings(kp, chan);
-       }
+       value = readl(kp->base + PRESCALE_OFFSET);
+       value &= ~PRESCALE_MASK(chan);
+       value |= prescale << PRESCALE_SHIFT(chan);
+       writel(value, kp->base + PRESCALE_OFFSET);
+
+       writel(pc, kp->base + PERIOD_COUNT_OFFSET(chan));
+
+       writel(dc, kp->base + DUTY_CYCLE_HIGH_OFFSET(chan));
+
+       kona_pwmc_apply_settings(kp, chan);
 
Quoted 7 lines

drivers/pwm/pwm-bcm-kona.c static int kona_pwmc_config(struct pwm_chip *chip, struct pwm_device *pwm, · line 187

Quoted 2 lines
drivers/pwm/pwm-bcm-kona.c +0 -0
        return 0;
 }

There is no requirement to lower the trigger bit prior to writing the period and duty registers.

This change is unnecessary. The old sequence was fine.

Incorrect. The old sequence was flawed as already discussed. I'll refer you the updated spec in previous discussion that was already sent to you. Not following the spec really does occasionally result in no output signal as the commit message states.

Quoted 12 lines
Quoted 12 lines
drivers/pwm/pwm-bcm-kona.c +0 -5
@@ -173,11 +209,6 @@ static int kona_pwmc_set_polarity(struct pwm_chip *chip, struct pwm_device *pwm,
 
        writel(value, kp->base + PWM_CONTROL_OFFSET);
 
-       kona_pwmc_apply_settings(kp, chan);
-
-       /* Wait for waveform to settle before gating off the clock */
-       ndelay(400);
-
        clk_disable_unprepare(kp->clk);
 
Quoted 6 lines

drivers/pwm/pwm-bcm-kona.c static int kona_pwmc_set_polarity(struct pwm_chip *chip, struct pwm_device *pwm, · line 214

Quoted 1 line
drivers/pwm/pwm-bcm-kona.c +0 -0
        return 0;

I'm not completely convinced that changing the polarity behavior is beneficial.

Please mention this change in your commit description and provide appropriate justification.

I'll update the commit message. You won't get any polarity change without the added code. It doesn't work.

Quoted 10 lines
Quoted 10 lines
drivers/pwm/pwm-bcm-kona.c +1 -0
@@ -190,12 +221,14 @@ static int kona_pwmc_enable(struct pwm_chip *chip, struct pwm_device *pwm)
 
        ret = clk_prepare_enable(kp->clk);
        if (ret < 0) {
+               clear_bit(PWMF_ENABLED, &pwm->flags);
                dev_err(chip->dev, "failed to enable clock: %d\n", ret);
                return ret;
        }
 
Quoted 8 lines

drivers/pwm/pwm-bcm-kona.c static int kona_pwmc_enable(struct pwm_chip *chip, struct pwm_device *pwm) · line 234

Quoted 6 lines
drivers/pwm/pwm-bcm-kona.c +1 -0
        ret = kona_pwmc_config(chip, pwm, pwm->duty_cycle, pwm->period);
        if (ret < 0) {
+               clear_bit(PWMF_ENABLED, &pwm->flags);
                clk_disable_unprepare(kp->clk);
                return ret;
        }

Don't try to fix this in the Kona PWM driver, fix it in the PWM core.

I agree that's where the fix should go. I wasn't sure I could make the change or not. I'll make the change and put it in a different commit.

Quoted 17 lines
Quoted 17 lines
drivers/pwm/pwm-bcm-kona.c +7 -1
@@ -207,13 +240,23 @@ static void kona_pwmc_disable(struct pwm_chip *chip, struct pwm_device *pwm)
 {
        struct kona_pwmc *kp = to_kona_pwmc(chip);
        unsigned int chan = pwm->hwpwm;
+       unsigned int value = readl(kp->base + PWM_CONTROL_OFFSET);
+
+       /* Set smooth type to 1 and disable */
+       value |= 1 << PWM_CONTROL_SMOOTH_SHIFT(chan);
+       value &= ~(1 << PWM_CONTROL_TRIGGER_SHIFT(chan));
+       writel(value, kp->base + PWM_CONTROL_OFFSET);
 
        /* Simulate a disable by configuring for zero duty */
        writel(0, kp->base + DUTY_CYCLE_HIGH_OFFSET(chan));
-       kona_pwmc_apply_settings(kp, chan);
+       writel(0, kp->base + PERIOD_COUNT_OFFSET(chan));
 
Quoted 8 lines

drivers/pwm/pwm-bcm-kona.c static void kona_pwmc_disable(struct pwm_chip *chip, struct pwm_device *pwm) · line 257

Quoted 6 lines
drivers/pwm/pwm-bcm-kona.c +4 -2
-       /* Wait for waveform to settle before gating off the clock */
-       ndelay(400);
+       /* Set prescale to 0 for this channel */
+       value = readl(kp->base + PRESCALE_OFFSET);
+       value &= ~PRESCALE_MASK(chan);
+       writel(value, kp->base + PRESCALE_OFFSET);

Can you explain why it is necessary to change the prescale here?

Spec recommendation and it's cleaner. We'd like the code to match the spec now that we have more detailed documentation. There is nothing dysfunctional about setting the prescale to the default value on disable that I can see.

Quoted 15 lines
Quoted 9 lines
drivers/pwm/pwm-bcm-kona.c +2 -1
+
+       kona_pwmc_apply_settings(kp, chan);
 
        clk_disable_unprepare(kp->clk);
 }
--

1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

#36 lore raw

cover Add support for Broadcom iProc touchscreen

In reply to a message not in the archive

This patchset contains initial support for the touchscreen on the Broadcom iProc family of SoCs. This driver has been validated with Cygnus and is expected to work on other iProc family of SoCs that use the same touchscreen controller.

Jonathan Richardson (2):
Input: touchscreen-iproc: Add Broadcom iProc touchscreen driver
Input: touchscreen-iproc: add device tree bindings

 .../input/touchscreen/brcm,iproc-touchscreen.txt   |   70 +++
 drivers/input/touchscreen/Kconfig                  |   11 +
 drivers/input/touchscreen/Makefile                 |    1 +
 drivers/input/touchscreen/bcm_iproc_tsc.c          |  559 ++++++++++++++++++++
 4 files changed, 641 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/input/touchscreen/brcm,iproc-touchscreen.txt
 create mode 100644 drivers/input/touchscreen/bcm_iproc_tsc.c
Signature · 1 line
1.7.9.5
#37 lore raw

PATCH 1/2 Input: touchscreen-iproc: Add Broadcom iProc touchscreen driver

Add initial version of the Broadcom touchscreen driver.

---
 drivers/input/touchscreen/Kconfig         |   11 +
 drivers/input/touchscreen/Makefile        |    1 +
 drivers/input/touchscreen/bcm_iproc_tsc.c |  559 +++++++++++++++++++++++++++++
 3 files changed, 571 insertions(+)
 create mode 100644 drivers/input/touchscreen/bcm_iproc_tsc.c
drivers/input/touchscreen/Kconfig +11 -0
index e1d8003..77ff531 100644
@@ -310,6 +310,17 @@ config TOUCHSCREEN_ILI210X
 	  To compile this driver as a module, choose M here: the
 	  module will be called ili210x.
 
+config TOUCHSCREEN_IPROC
+	tristate "IPROC touch panel driver support"
+	help
+	  Say Y here if you want to add support for the IPROC touch
+	  controller to your system.
+
+	  If unsure, say N.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called iproc-ts.
+
 config TOUCHSCREEN_S3C2410
 	tristate "Samsung S3C2410/generic touchscreen input driver"
 	depends on ARCH_S3C24XX || SAMSUNG_DEV_TS
drivers/input/touchscreen/Makefile +1 -0
index 090e61c..f7e6de9 100644
@@ -37,6 +37,7 @@ obj-$(CONFIG_TOUCHSCREEN_FUJITSU)	+= fujitsu_ts.o
 obj-$(CONFIG_TOUCHSCREEN_ILI210X)	+= ili210x.o
 obj-$(CONFIG_TOUCHSCREEN_INEXIO)	+= inexio.o
 obj-$(CONFIG_TOUCHSCREEN_INTEL_MID)	+= intel-mid-touch.o
+obj-$(CONFIG_TOUCHSCREEN_IPROC)		+= bcm_iproc_tsc.o
 obj-$(CONFIG_TOUCHSCREEN_LPC32XX)	+= lpc32xx_ts.o
 obj-$(CONFIG_TOUCHSCREEN_MAX11801)	+= max11801_ts.o
 obj-$(CONFIG_TOUCHSCREEN_MC13783)	+= mc13783_ts.o
drivers/input/touchscreen/bcm_iproc_tsc.c new file +559 -0

559 lines not on this page · raw message

Signature · 1 line
1.7.9.5
#38 lore raw

Re: [PATCH 1/2] Input: touchscreen-iproc: Add Broadcom iProc touchscreen driver

Quoted 1 line · Jonathan Richardson

Add initial version of the Broadcom touchscreen driver.

trivia:

drivers/input/touchscreen/bcm_iproc_tsc.c line 88

Quoted 11 lines
drivers/input/touchscreen/bcm_iproc_tsc.c +9 -0
 
+/* Bit values for REGCTL2 */
+#define TS_CONTROLLER_EN_BIT    (1 << 16)
+#define TS_CONTROLLER_AVGDATA_SHIFT 8
+#define TS_CONTROLLER_AVGDATA_MASK (0x7 << TS_CONTROLLER_AVGDATA_SHIFT)
+#define TS_CONTROLLER_PWR_LDO   (1<<5)
+#define TS_CONTROLLER_PWR_ADC   (1<<4)
+#define TS_CONTROLLER_PWR_BGP   (1<<3)
+#define TS_CONTROLLER_PWR_TS    (1<<2)
+#define TS_WIRE_MODE_BIT        (1<<1)

Be nicer to use the same spacing around <<
or maybe use the BIT macro.

[]

Quoted 6 lines
drivers/input/touchscreen/bcm_iproc_tsc.c +6 -0
+static int get_tsc_config(struct device_node *np, struct iproc_ts_priv *priv)
+{
+	int ret;
+	u32 val;
+	struct device *dev = &priv->pdev->dev;
+

drivers/input/touchscreen/bcm_iproc_tsc.c line 378

Quoted 10 lines
drivers/input/touchscreen/bcm_iproc_tsc.c +10 -0
+	priv->cfg_params = default_config;
+
+	ret = of_property_read_u32(np, "scanning_period", &val);
+	if (ret >= 0) {
+		if ((1 <= val) && (val <= 256))
+			priv->cfg_params.scanning_period = val;
+		else {
+			dev_err(dev, "scanning_period must be [1-256]");
+			return -EINVAL;
+		}

ret is never used so I'd probably remove it
from all these blocks.

It's probably be nicer to invert the logic ald
remove the else.

There's a missing terminating newline too.

Something like:

	if (of_property_read_u32(np, "scanning_period", &val) >= 0) {
		if (val < 1 || val > 256) {
			dev_err(dev, "scanning_period must be [1-256]\n");
			return -EINVAL;
		}
		priv->cfg_params.scanning_period = val;
	}

etc...

#39 lore raw

Re: [PATCH 1/2] Input: touchscreen-iproc: Add Broadcom iProc touchscreen driver

Thanks Joe. I'll send out a new patch set with your suggestions/fixes shortly.

Quoted 65 lines · Joe Perches
Quoted 1 line · Jonathan Richardson

Add initial version of the Broadcom touchscreen driver.

trivia:

drivers/input/touchscreen/bcm_iproc_tsc.c line 88

Quoted 11 lines
drivers/input/touchscreen/bcm_iproc_tsc.c +9 -0
 
+/* Bit values for REGCTL2 */
+#define TS_CONTROLLER_EN_BIT    (1 << 16)
+#define TS_CONTROLLER_AVGDATA_SHIFT 8
+#define TS_CONTROLLER_AVGDATA_MASK (0x7 << TS_CONTROLLER_AVGDATA_SHIFT)
+#define TS_CONTROLLER_PWR_LDO   (1<<5)
+#define TS_CONTROLLER_PWR_ADC   (1<<4)
+#define TS_CONTROLLER_PWR_BGP   (1<<3)
+#define TS_CONTROLLER_PWR_TS    (1<<2)
+#define TS_WIRE_MODE_BIT        (1<<1)

Be nicer to use the same spacing around <<
or maybe use the BIT macro.

[]

Quoted 6 lines
drivers/input/touchscreen/bcm_iproc_tsc.c +6 -0
+static int get_tsc_config(struct device_node *np, struct iproc_ts_priv *priv)
+{
+	int ret;
+	u32 val;
+	struct device *dev = &priv->pdev->dev;
+

drivers/input/touchscreen/bcm_iproc_tsc.c line 378

Quoted 10 lines
drivers/input/touchscreen/bcm_iproc_tsc.c +10 -0
+	priv->cfg_params = default_config;
+
+	ret = of_property_read_u32(np, "scanning_period", &val);
+	if (ret >= 0) {
+		if ((1 <= val) && (val <= 256))
+			priv->cfg_params.scanning_period = val;
+		else {
+			dev_err(dev, "scanning_period must be [1-256]");
+			return -EINVAL;
+		}

ret is never used so I'd probably remove it
from all these blocks.

It's probably be nicer to invert the logic ald
remove the else.

There's a missing terminating newline too.

Something like:

	if (of_property_read_u32(np, "scanning_period", &val) >= 0) {
		if (val < 1 || val > 256) {
			dev_err(dev, "scanning_period must be [1-256]\n");
			return -EINVAL;
		}
		priv->cfg_params.scanning_period = val;
	}

etc...

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html

maintainer
#40 lore raw

Re: [PATCH 1/2] Input: touchscreen-iproc: Add Broadcom iProc touchscreen driver

Quoted 2 lines · Jonathan Richardson

Thanks Joe. I'll send out a new patch set with your suggestions/fixes shortly.

You can also drop the remove() code since we clear drvdata automatically and input device is managed so does not need to be unregistered explicitly.

Thanks.

Signature · 1 line
Dmitry
#41 lore raw

PATCH 2/2 Input: touchscreen-iproc: add device tree bindings

In reply to Jonathan Richardson

Documents the touchscreen device tree binding for Broadcom iProc family of SoCs.

---
 .../input/touchscreen/brcm,iproc-touchscreen.txt   |   70 ++++++++++++++++++++
 1 file changed, 70 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/input/touchscreen/brcm,iproc-touchscreen.txt
Documentation/devicetree/bindings/input/touchscreen/brcm,iproc-touchscreen.txt new file +70 -0
new file mode 100644
index 0000000..eb28822
@@ -0,0 +1,70 @@
+* Broadcom's IPROC Touchscreen Controller
+
+Required properties:
+- compatible: must be "brcm,iproc-touchscreen"
+- reg: physical base address of the controller and length of memory mapped
+  region.
+- clocks:  The clock provided by the SOC to driver the tsc
+- clock-name:  name for the clock
+- interrupts: The touchscreen controller's interrupt
+
+Optional properties:
+- scanning_period: Time between scans. Each step is 1024 us.  Valid 1-256.
+- debounce_timeout: Each step is 512 us.  Valid 0-255
+- settling_timeout: The settling duration (in ms) is the amount of time
+                    the tsc waits to allow the voltage to settle after
+                    turning on the drivers in detection mode.
+                    Valid values: 0-11
+                    0 =  0.008 ms
+                    1 =  0.01 ms
+                    2 =  0.02 ms
+                    3 =  0.04 ms
+                    4 =  0.08 ms
+                    5 =  0.16 ms
+                    6 =  0.32 ms
+                    7 =  0.64 ms
+                    8 =  1.28 ms
+                    9 =  2.56 ms
+                   10 =  5.12 ms
+                   11 = 10.24 ms
+- touch_timeout: The continuous number of scan periods in which touch is
+                not detected before the controller returns to idle state.
+                Valid values 0-255.
+- average_data: Number of data samples which are averaged before a final
+                data point is placed into the FIFO
+                Valid values 0-7
+                0 =   1 sample
+                1 =   2 samples
+                2 =   4 samples
+                3 =   8 samples
+                4 =  16 samples
+                5 =  32 samples
+                6 =  64 samples
+                7 = 128 samples
+- fifo_threshold: Interrupt is generated whenever the number of fifo
+                entries exceeds this value
+                Valid values 0-31
+- ts-rotation: Touch screen controller and display panel orientation angle.
+		0 = Tsc x_min y_min placed at LCD x_min y_min. None
+		1 = Tsc x_min y_max placed at LCD x_min y_min. 90 degrees
+		2 = Tsc x_max y_max placed at LCD x_min y_min. 180 degrees
+		3 = Tsc x_max y_min placed at LCD x_min y_min. 270 degrees
+Example:
+
+	touchscreen: tsc at 0x180A6000 {
+		compatible = "brcm,iproc-touchscreen";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		reg = <0x180A6000 0x40>;
+		clocks = <&adc_clk>;
+		clock-names = "tsc_clk";
+		interrupts = <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>;
+
+		scanning_period = <5>;
+		debounce_timeout = <40>;
+		settling_timeout = <7>;
+		touch_timeout = <10>;
+		average_data = <5>;
+		fifo_threshold = <1>;
+		ts-rotation = <2>;
+	};
Signature · 1 line
1.7.9.5
#42 lore raw

v2 cover Add support for Broadcom iProc touchscreen

In reply to a message not in the archive

This patchset contains initial support for the touchscreen on the Broadcom iProc family of SoCs. This driver has been validated with Cygnus and is expected to work on other iProc family of SoCs that use the same touchscreen controller.

Changes from v1:
- Add missing newlines to debug messages
- Use BIT macro for defines
- Fix logic in get_tsc_config to improve readability
- Get rid of unnecessary remove() function

Jonathan Richardson (2):
Input: touchscreen-iproc: Add Broadcom iProc touchscreen driver
Input: touchscreen-iproc: add device tree bindings

 .../input/touchscreen/brcm,iproc-touchscreen.txt   |   70 +++
 drivers/input/touchscreen/Kconfig                  |   11 +
 drivers/input/touchscreen/Makefile                 |    1 +
 drivers/input/touchscreen/bcm_iproc_tsc.c          |  535 ++++++++++++++++++++
 4 files changed, 617 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/input/touchscreen/brcm,iproc-touchscreen.txt
 create mode 100644 drivers/input/touchscreen/bcm_iproc_tsc.c
Signature · 1 line
1.7.9.5
#43 lore raw

PATCH v2 1/2 Input: touchscreen-iproc: Add Broadcom iProc touchscreen driver

Add initial version of the Broadcom touchscreen driver.

---
 drivers/input/touchscreen/Kconfig         |   11 +
 drivers/input/touchscreen/Makefile        |    1 +
 drivers/input/touchscreen/bcm_iproc_tsc.c |  535 +++++++++++++++++++++++++++++
 3 files changed, 547 insertions(+)
 create mode 100644 drivers/input/touchscreen/bcm_iproc_tsc.c
drivers/input/touchscreen/Kconfig +11 -0
index e1d8003..77ff531 100644
@@ -310,6 +310,17 @@ config TOUCHSCREEN_ILI210X
 	  To compile this driver as a module, choose M here: the
 	  module will be called ili210x.
 
+config TOUCHSCREEN_IPROC
+	tristate "IPROC touch panel driver support"
+	help
+	  Say Y here if you want to add support for the IPROC touch
+	  controller to your system.
+
+	  If unsure, say N.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called iproc-ts.
+
 config TOUCHSCREEN_S3C2410
 	tristate "Samsung S3C2410/generic touchscreen input driver"
 	depends on ARCH_S3C24XX || SAMSUNG_DEV_TS
drivers/input/touchscreen/Makefile +1 -0
index 090e61c..f7e6de9 100644
@@ -37,6 +37,7 @@ obj-$(CONFIG_TOUCHSCREEN_FUJITSU)	+= fujitsu_ts.o
 obj-$(CONFIG_TOUCHSCREEN_ILI210X)	+= ili210x.o
 obj-$(CONFIG_TOUCHSCREEN_INEXIO)	+= inexio.o
 obj-$(CONFIG_TOUCHSCREEN_INTEL_MID)	+= intel-mid-touch.o
+obj-$(CONFIG_TOUCHSCREEN_IPROC)		+= bcm_iproc_tsc.o
 obj-$(CONFIG_TOUCHSCREEN_LPC32XX)	+= lpc32xx_ts.o
 obj-$(CONFIG_TOUCHSCREEN_MAX11801)	+= max11801_ts.o
 obj-$(CONFIG_TOUCHSCREEN_MC13783)	+= mc13783_ts.o
drivers/input/touchscreen/bcm_iproc_tsc.c new file +535 -0

535 lines not on this page · raw message

Signature · 1 line
1.7.9.5
#44 lore raw

Re: [PATCH v2 1/2] Input: touchscreen-iproc: Add Broadcom iProc touchscreen driver

Quoted 1 line · Jonathan Richardson

Add initial version of the Broadcom touchscreen driver.

more trivia:

drivers/input/touchscreen/bcm_iproc_tsc.c

Quoted 1 line
drivers/input/touchscreen/bcm_iproc_tsc.c +0 -0

[]

drivers/input/touchscreen/bcm_iproc_tsc.c line 365

Quoted 3 lines
drivers/input/touchscreen/bcm_iproc_tsc.c +3 -0
+static int get_tsc_config(struct device_node *np, struct iproc_ts_priv *priv)
+{
+	u32 val;

[]

drivers/input/touchscreen/bcm_iproc_tsc.c line 383

Quoted 6 lines
drivers/input/touchscreen/bcm_iproc_tsc.c +6 -0
+	if (of_property_read_u32(np, "debounce_timeout", &val) >= 0) {
+		if (val < 0 || val > 255) {
+			dev_err(dev, "debounce_timeout must be [0-255]\n");
+			return -EINVAL;
+		}
+		priv->cfg_params.debounce_timeout = val;

Doesn't the compiler generate a warning message
about an impossible "unsigned < 0" test for all
of these "val < 0" uses?

drivers/input/touchscreen/bcm_iproc_tsc.c line 387

Quoted 4 lines
drivers/input/touchscreen/bcm_iproc_tsc.c +4 -0
+	}
+
+	if (of_property_read_u32(np, "settling_timeout", &val) >= 0) {
+		if (val < 0 || val > 11) {

[]

drivers/input/touchscreen/bcm_iproc_tsc.c line 395

Quoted 2 lines
drivers/input/touchscreen/bcm_iproc_tsc.c +2 -0
+	if (of_property_read_u32(np, "touch_timeout", &val) >= 0) {
+		if (val < 0 || val > 255) {

[]

drivers/input/touchscreen/bcm_iproc_tsc.c line 403

Quoted 2 lines
drivers/input/touchscreen/bcm_iproc_tsc.c +2 -0
+	if (of_property_read_u32(np, "average_data", &val) >= 0) {
+		if (val < 0 || val > 8) {

[]

Quoted 2 lines
drivers/input/touchscreen/bcm_iproc_tsc.c +2 -0
+	if (of_property_read_u32(np, "fifo_threshold", &val) >= 0) {
+		if (val < 0 || val > 31) {
#45 lore raw

Re: [PATCH v2 1/2] Input: touchscreen-iproc: Add Broadcom iProc touchscreen driver

Quoted 11 lines · Joe Perches
Quoted 1 line · Jonathan Richardson

Add initial version of the Broadcom touchscreen driver.

more trivia:

drivers/input/touchscreen/bcm_iproc_tsc.c

Quoted 1 line
drivers/input/touchscreen/bcm_iproc_tsc.c +0 -0

[]

drivers/input/touchscreen/bcm_iproc_tsc.c line 365

Quoted 3 lines
drivers/input/touchscreen/bcm_iproc_tsc.c +3 -0
+static int get_tsc_config(struct device_node *np, struct iproc_ts_priv *priv)
+{
+	u32 val;

[]

Quoted 11 lines

drivers/input/touchscreen/bcm_iproc_tsc.c line 383

Quoted 6 lines
drivers/input/touchscreen/bcm_iproc_tsc.c +6 -0
+	if (of_property_read_u32(np, "debounce_timeout", &val) >= 0) {
+		if (val < 0 || val > 255) {
+			dev_err(dev, "debounce_timeout must be [0-255]\n");
+			return -EINVAL;
+		}
+		priv->cfg_params.debounce_timeout = val;

Doesn't the compiler generate a warning message
about an impossible "unsigned < 0" test for all
of these "val < 0" uses?

Actually no it doesn't. The gcc output shows that neither -Wtype-limits nor -Wextra are used to compile that file. I assume this is because there would be just too many warnings.

Quoted 15 lines

drivers/input/touchscreen/bcm_iproc_tsc.c line 387

Quoted 4 lines
drivers/input/touchscreen/bcm_iproc_tsc.c +4 -0
+	}
+
+	if (of_property_read_u32(np, "settling_timeout", &val) >= 0) {
+		if (val < 0 || val > 11) {

[]

drivers/input/touchscreen/bcm_iproc_tsc.c line 395

Quoted 2 lines
drivers/input/touchscreen/bcm_iproc_tsc.c +2 -0
+	if (of_property_read_u32(np, "touch_timeout", &val) >= 0) {
+		if (val < 0 || val > 255) {

[]

drivers/input/touchscreen/bcm_iproc_tsc.c line 403

Quoted 2 lines
drivers/input/touchscreen/bcm_iproc_tsc.c +2 -0
+	if (of_property_read_u32(np, "average_data", &val) >= 0) {
+		if (val < 0 || val > 8) {

[]

Quoted 2 lines
drivers/input/touchscreen/bcm_iproc_tsc.c +2 -0
+	if (of_property_read_u32(np, "fifo_threshold", &val) >= 0) {
+		if (val < 0 || val > 31) {
#46 lore raw

Re: [PATCH v2 1/2] Input: touchscreen-iproc: Add Broadcom iProc touchscreen driver

Hi,

Would anyone be able to look at this to help us move forward? Thanks.

Quoted 45 lines · Jonathan Richardson
Quoted 11 lines · Joe Perches
Quoted 1 line · Jonathan Richardson

Add initial version of the Broadcom touchscreen driver.

more trivia:

drivers/input/touchscreen/bcm_iproc_tsc.c

Quoted 1 line
drivers/input/touchscreen/bcm_iproc_tsc.c +0 -0

[]

drivers/input/touchscreen/bcm_iproc_tsc.c line 365

Quoted 3 lines
drivers/input/touchscreen/bcm_iproc_tsc.c +3 -0
+static int get_tsc_config(struct device_node *np, struct iproc_ts_priv *priv)
+{
+	u32 val;

[]

Quoted 11 lines

drivers/input/touchscreen/bcm_iproc_tsc.c line 383

Quoted 6 lines
drivers/input/touchscreen/bcm_iproc_tsc.c +6 -0
+	if (of_property_read_u32(np, "debounce_timeout", &val) >= 0) {
+		if (val < 0 || val > 255) {
+			dev_err(dev, "debounce_timeout must be [0-255]\n");
+			return -EINVAL;
+		}
+		priv->cfg_params.debounce_timeout = val;

Doesn't the compiler generate a warning message
about an impossible "unsigned < 0" test for all
of these "val < 0" uses?

Actually no it doesn't. The gcc output shows that neither -Wtype-limits nor -Wextra are used to compile that file. I assume this is because there would be just too many warnings.

Quoted 15 lines

drivers/input/touchscreen/bcm_iproc_tsc.c line 387

Quoted 4 lines
drivers/input/touchscreen/bcm_iproc_tsc.c +4 -0
+	}
+
+	if (of_property_read_u32(np, "settling_timeout", &val) >= 0) {
+		if (val < 0 || val > 11) {

[]

drivers/input/touchscreen/bcm_iproc_tsc.c line 395

Quoted 2 lines
drivers/input/touchscreen/bcm_iproc_tsc.c +2 -0
+	if (of_property_read_u32(np, "touch_timeout", &val) >= 0) {
+		if (val < 0 || val > 255) {

[]

drivers/input/touchscreen/bcm_iproc_tsc.c line 403

Quoted 2 lines
drivers/input/touchscreen/bcm_iproc_tsc.c +2 -0
+	if (of_property_read_u32(np, "average_data", &val) >= 0) {
+		if (val < 0 || val > 8) {

[]

Quoted 2 lines
drivers/input/touchscreen/bcm_iproc_tsc.c +2 -0
+	if (of_property_read_u32(np, "fifo_threshold", &val) >= 0) {
+		if (val < 0 || val > 31) {
#47 lore raw

Re: [PATCH v2 1/2] Input: touchscreen-iproc: Add Broadcom iProc touchscreen driver

In reply to Jonathan Richardson
Quoted 12 lines · Jonathan Richardson
Quoted 11 lines · Joe Perches
Quoted 1 line · Jonathan Richardson

Add initial version of the Broadcom touchscreen driver.

more trivia:

drivers/input/touchscreen/bcm_iproc_tsc.c

Quoted 1 line
drivers/input/touchscreen/bcm_iproc_tsc.c +0 -0

[]

drivers/input/touchscreen/bcm_iproc_tsc.c line 365

Quoted 3 lines
drivers/input/touchscreen/bcm_iproc_tsc.c +3 -0
+static int get_tsc_config(struct device_node *np, struct iproc_ts_priv *priv)
+{
+	u32 val;

[]

Quoted 6 lines
Quoted 6 lines

drivers/input/touchscreen/bcm_iproc_tsc.c line 383

Quoted 6 lines
drivers/input/touchscreen/bcm_iproc_tsc.c +6 -0
+	if (of_property_read_u32(np, "debounce_timeout", &val) >= 0) {
+		if (val < 0 || val > 255) {
+			dev_err(dev, "debounce_timeout must be [0-255]\n");
+			return -EINVAL;
+		}
+		priv->cfg_params.debounce_timeout = val;

BTW, common practice for DT properties is to use a dash instead of an underscore for multi-worded properties.

Quoted 33 lines
Quoted 5 lines

Doesn't the compiler generate a warning message
about an impossible "unsigned < 0" test for all
of these "val < 0" uses?

Actually no it doesn't. The gcc output shows that neither -Wtype-limits nor -Wextra are used to compile that file. I assume this is because there would be just too many warnings.

Quoted 5 lines

drivers/input/touchscreen/bcm_iproc_tsc.c line 387

Quoted 4 lines
drivers/input/touchscreen/bcm_iproc_tsc.c +4 -0
+	}
+
+	if (of_property_read_u32(np, "settling_timeout", &val) >= 0) {
+		if (val < 0 || val > 11) {

[]

Quoted 10 lines

drivers/input/touchscreen/bcm_iproc_tsc.c line 395

Quoted 2 lines
drivers/input/touchscreen/bcm_iproc_tsc.c +2 -0
+	if (of_property_read_u32(np, "touch_timeout", &val) >= 0) {
+		if (val < 0 || val > 255) {

[]

drivers/input/touchscreen/bcm_iproc_tsc.c line 403

Quoted 2 lines
drivers/input/touchscreen/bcm_iproc_tsc.c +2 -0
+	if (of_property_read_u32(np, "average_data", &val) >= 0) {
+		if (val < 0 || val > 8) {

[]

drivers/input/touchscreen/bcm_iproc_tsc.c line 411

Quoted 2 lines
drivers/input/touchscreen/bcm_iproc_tsc.c +2 -0
+	if (of_property_read_u32(np, "fifo_threshold", &val) >= 0) {
+		if (val < 0 || val > 31) {

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Signature · 1 line
Florian
#48 lore raw

Re: [PATCH v2 1/2] Input: touchscreen-iproc: Add Broadcom iProc touchscreen driver

Quoted 13 lines · Florian Fainelli
Quoted 12 lines · Jonathan Richardson
Quoted 11 lines · Joe Perches
Quoted 1 line · Jonathan Richardson

Add initial version of the Broadcom touchscreen driver.

more trivia:

drivers/input/touchscreen/bcm_iproc_tsc.c

Quoted 1 line
drivers/input/touchscreen/bcm_iproc_tsc.c +0 -0

[]

drivers/input/touchscreen/bcm_iproc_tsc.c line 365

Quoted 3 lines
drivers/input/touchscreen/bcm_iproc_tsc.c +3 -0
+static int get_tsc_config(struct device_node *np, struct iproc_ts_priv *priv)
+{
+	u32 val;

[]

Quoted 9 lines
Quoted 6 lines
Quoted 6 lines

drivers/input/touchscreen/bcm_iproc_tsc.c line 383

Quoted 6 lines
drivers/input/touchscreen/bcm_iproc_tsc.c +6 -0
+	if (of_property_read_u32(np, "debounce_timeout", &val) >= 0) {
+		if (val < 0 || val > 255) {
+			dev_err(dev, "debounce_timeout must be [0-255]\n");
+			return -EINVAL;
+		}
+		priv->cfg_params.debounce_timeout = val;

BTW, common practice for DT properties is to use a dash instead of an underscore for multi-worded properties.

ts-rotation is done that way already so I'll change the others to be consistent. Thanks.

Quoted 36 lines
Quoted 34 lines
Quoted 6 lines

Doesn't the compiler generate a warning message
about an impossible "unsigned < 0" test for all
of these "val < 0" uses?

Actually no it doesn't. The gcc output shows that neither -Wtype-limits nor -Wextra are used to compile that file. I assume this is because there would be just too many warnings.

Quoted 5 lines

drivers/input/touchscreen/bcm_iproc_tsc.c line 387

Quoted 4 lines
drivers/input/touchscreen/bcm_iproc_tsc.c +4 -0
+	}
+
+	if (of_property_read_u32(np, "settling_timeout", &val) >= 0) {
+		if (val < 0 || val > 11) {

[]

Quoted 10 lines

drivers/input/touchscreen/bcm_iproc_tsc.c line 395

Quoted 2 lines
drivers/input/touchscreen/bcm_iproc_tsc.c +2 -0
+	if (of_property_read_u32(np, "touch_timeout", &val) >= 0) {
+		if (val < 0 || val > 255) {

[]

drivers/input/touchscreen/bcm_iproc_tsc.c line 403

Quoted 2 lines
drivers/input/touchscreen/bcm_iproc_tsc.c +2 -0
+	if (of_property_read_u32(np, "average_data", &val) >= 0) {
+		if (val < 0 || val > 8) {

[]

drivers/input/touchscreen/bcm_iproc_tsc.c line 411

Quoted 2 lines
drivers/input/touchscreen/bcm_iproc_tsc.c +2 -0
+	if (of_property_read_u32(np, "fifo_threshold", &val) >= 0) {
+		if (val < 0 || val > 31) {

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

maintainer
#49 lore raw

Re: [PATCH v2 1/2] Input: touchscreen-iproc: Add Broadcom iProc touchscreen driver

In reply to Jonathan Richardson

Hi Jonathan,

Quoted 37 lines · Jonathan Richardson
drivers/input/touchscreen/bcm_iproc_tsc.c new file +37 -0
+	if (of_property_read_u32(np, "scanning_period", &val) >= 0) {
+		if (val < 1 || val > 256) {
+			dev_err(dev, "scanning_period must be [1-256]\n");
+			return -EINVAL;
+		}
+		priv->cfg_params.scanning_period = val;
+	}
+
+	if (of_property_read_u32(np, "debounce_timeout", &val) >= 0) {
+		if (val < 0 || val > 255) {
+			dev_err(dev, "debounce_timeout must be [0-255]\n");
+			return -EINVAL;
+		}
+		priv->cfg_params.debounce_timeout = val;
+	}
+
+	if (of_property_read_u32(np, "settling_timeout", &val) >= 0) {
+		if (val < 0 || val > 11) {
+			dev_err(dev, "settling_timeout must be [0-11]\n");
+			return -EINVAL;
+		}
+		priv->cfg_params.settling_timeout = val;
+	}
+
+	if (of_property_read_u32(np, "touch_timeout", &val) >= 0) {
+		if (val < 0 || val > 255) {
+			dev_err(dev, "touch_timeout must be [0-255]\n");
+			return -EINVAL;
+		}
+		priv->cfg_params.touch_timeout = val;
+	}
+
+	if (of_property_read_u32(np, "average_data", &val) >= 0) {
+		if (val < 0 || val > 8) {
+			dev_err(dev, "average_data must be [0-8]\n");
+			return -EINVAL;
+		}

drivers/input/touchscreen/bcm_iproc_tsc.c line 416

Quoted 10 lines
drivers/input/touchscreen/bcm_iproc_tsc.c new file +10 -0
+		priv->cfg_params.average_data = val;
+	}
+
+	if (of_property_read_u32(np, "fifo_threshold", &val) >= 0) {
+		if (val < 0 || val > 31) {
+			dev_err(dev, "fifo_threshold must be [0-31]\n");
+			return -EINVAL;
+		}
+		priv->cfg_params.fifo_threshold = val;
+	}

I think these are dveice specific and thus should have "brcm," prefix.

drivers/input/touchscreen/bcm_iproc_tsc.c line 423

Quoted 7 lines
drivers/input/touchscreen/bcm_iproc_tsc.c new file +7 -0
+
+	priv->ts_rotation = TS_ROTATION_0;
+	if (of_property_read_u32(np, "ts-rotation", &val) >= 0) {
+		priv->ts_rotation = val;
+		dev_dbg(dev, "ts rotation [%d] degrees\n",
+			90 * priv->ts_rotation);
+	}

This I am not quite sure about - if we want rotation or swap+invert. You are CCed on another email (tsc2007) that talks about need of generic touchscreen transforms in input core/of bindings.

Thanks.

Signature · 1 line
Dmitry
maintainer
#50 lore raw

Re: [PATCH v2 1/2] Input: touchscreen-iproc: Add Broadcom iProc touchscreen driver

Quoted 44 lines · Dmitry Torokhov

Hi Jonathan,

Quoted 41 lines · Jonathan Richardson
drivers/input/touchscreen/bcm_iproc_tsc.c new file +41 -0
+	if (of_property_read_u32(np, "scanning_period", &val) >= 0) {
+		if (val < 1 || val > 256) {
+			dev_err(dev, "scanning_period must be [1-256]\n");
+			return -EINVAL;
+		}
+		priv->cfg_params.scanning_period = val;
+	}
+
+	if (of_property_read_u32(np, "debounce_timeout", &val) >= 0) {
+		if (val < 0 || val > 255) {
+			dev_err(dev, "debounce_timeout must be [0-255]\n");
+			return -EINVAL;
+		}
+		priv->cfg_params.debounce_timeout = val;
+	}
+
+	if (of_property_read_u32(np, "settling_timeout", &val) >= 0) {
+		if (val < 0 || val > 11) {
+			dev_err(dev, "settling_timeout must be [0-11]\n");
+			return -EINVAL;
+		}
+		priv->cfg_params.settling_timeout = val;
+	}
+
+	if (of_property_read_u32(np, "touch_timeout", &val) >= 0) {
+		if (val < 0 || val > 255) {
+			dev_err(dev, "touch_timeout must be [0-255]\n");
+			return -EINVAL;
+		}
+		priv->cfg_params.touch_timeout = val;
+	}
+
+	if (of_property_read_u32(np, "average_data", &val) >= 0) {
+		if (val < 0 || val > 8) {
+			dev_err(dev, "average_data must be [0-8]\n");
+			return -EINVAL;
+		}
+		priv->cfg_params.average_data = val;
+	}
+
+	if (of_property_read_u32(np, "fifo_threshold", &val) >= 0) {
Quoted 8 lines

drivers/input/touchscreen/bcm_iproc_tsc.c line 416

Quoted 6 lines
drivers/input/touchscreen/bcm_iproc_tsc.c new file +6 -0
+		if (val < 0 || val > 31) {
+			dev_err(dev, "fifo_threshold must be [0-31]\n");
+			return -EINVAL;
+		}
+		priv->cfg_params.fifo_threshold = val;
+	}

I think these are dveice specific and thus should have "brcm," prefix.

I'm confused as to why we need the brcm prefix? Other device tree bindings we have for other drivers do not need such prefix. Is this convention documented somewhere?

Quoted 12 lines

drivers/input/touchscreen/bcm_iproc_tsc.c line 423

Quoted 8 lines
drivers/input/touchscreen/bcm_iproc_tsc.c new file +7 -0
+
+	priv->ts_rotation = TS_ROTATION_0;
+	if (of_property_read_u32(np, "ts-rotation", &val) >= 0) {
+		priv->ts_rotation = val;
+		dev_dbg(dev, "ts rotation [%d] degrees\n",
+			90 * priv->ts_rotation);
+	}

This I am not quite sure about - if we want rotation or swap+invert. You are CCed on another email (tsc2007) that talks about need of generic touchscreen transforms in input core/of bindings.

Does such generic binding exist today? If not, I would like to go with this implementation and update to the new binding if/when it exists?

Quoted 3 lines

Thanks.

maintainer
#51 lore raw

Re: [PATCH v2 1/2] Input: touchscreen-iproc: Add Broadcom iProc touchscreen driver

Quoted 53 lines · Scott Branden
Quoted 44 lines · Dmitry Torokhov

Hi Jonathan,

Quoted 41 lines · Jonathan Richardson
drivers/input/touchscreen/bcm_iproc_tsc.c new file +41 -0
+	if (of_property_read_u32(np, "scanning_period", &val) >= 0) {
+		if (val < 1 || val > 256) {
+			dev_err(dev, "scanning_period must be [1-256]\n");
+			return -EINVAL;
+		}
+		priv->cfg_params.scanning_period = val;
+	}
+
+	if (of_property_read_u32(np, "debounce_timeout", &val) >= 0) {
+		if (val < 0 || val > 255) {
+			dev_err(dev, "debounce_timeout must be [0-255]\n");
+			return -EINVAL;
+		}
+		priv->cfg_params.debounce_timeout = val;
+	}
+
+	if (of_property_read_u32(np, "settling_timeout", &val) >= 0) {
+		if (val < 0 || val > 11) {
+			dev_err(dev, "settling_timeout must be [0-11]\n");
+			return -EINVAL;
+		}
+		priv->cfg_params.settling_timeout = val;
+	}
+
+	if (of_property_read_u32(np, "touch_timeout", &val) >= 0) {
+		if (val < 0 || val > 255) {
+			dev_err(dev, "touch_timeout must be [0-255]\n");
+			return -EINVAL;
+		}
+		priv->cfg_params.touch_timeout = val;
+	}
+
+	if (of_property_read_u32(np, "average_data", &val) >= 0) {
+		if (val < 0 || val > 8) {
+			dev_err(dev, "average_data must be [0-8]\n");
+			return -EINVAL;
+		}
+		priv->cfg_params.average_data = val;
+	}
+
+	if (of_property_read_u32(np, "fifo_threshold", &val) >= 0) {
Quoted 8 lines

drivers/input/touchscreen/bcm_iproc_tsc.c line 416

Quoted 6 lines
drivers/input/touchscreen/bcm_iproc_tsc.c new file +6 -0
+		if (val < 0 || val > 31) {
+			dev_err(dev, "fifo_threshold must be [0-31]\n");
+			return -EINVAL;
+		}
+		priv->cfg_params.fifo_threshold = val;
+	}

I think these are dveice specific and thus should have "brcm," prefix.

Quoted 2 lines

I'm confused as to why we need the brcm prefix? Other device tree bindings we have for other drivers do not need such prefix.

Properties that are not standard on the system (reg, interrupts, clkocks, etc) or subsystem level customarily carry the vendor prefix so that they do not clash with newly added global or subsystem properties.

Quoted 2 lines

Is this
convention documented somewhere?

Not sure. I glanced through Documentation/devicetree and do not see it spelled out. Device tree overlords, what say you?

Quoted 12 lines
Quoted 12 lines

drivers/input/touchscreen/bcm_iproc_tsc.c line 423

Quoted 8 lines
drivers/input/touchscreen/bcm_iproc_tsc.c new file +7 -0
+
+	priv->ts_rotation = TS_ROTATION_0;
+	if (of_property_read_u32(np, "ts-rotation", &val) >= 0) {
+		priv->ts_rotation = val;
+		dev_dbg(dev, "ts rotation [%d] degrees\n",
+			90 * priv->ts_rotation);
+	}

This I am not quite sure about - if we want rotation or swap+invert. You are CCed on another email (tsc2007) that talks about need of generic touchscreen transforms in input core/of bindings.

Quoted 3 lines

Does such generic binding exist today? If not, I would like to go with this implementation and update to the new binding if/when it exists?

Not yet but there several people interested. I think we have enough time till 3.20 to hash it out properly.

Thanks.

Signature · 1 line
Dmitry
#52 lore raw

Re: [PATCH v2 1/2] Input: touchscreen-iproc: Add Broadcom iProc touchscreen driver

Hi Dmitry,

Quoted 61 lines · Dmitry Torokhov
Quoted 53 lines · Scott Branden
Quoted 44 lines · Dmitry Torokhov

Hi Jonathan,

Quoted 41 lines · Jonathan Richardson
drivers/input/touchscreen/bcm_iproc_tsc.c new file +41 -0
+	if (of_property_read_u32(np, "scanning_period", &val) >= 0) {
+		if (val < 1 || val > 256) {
+			dev_err(dev, "scanning_period must be [1-256]\n");
+			return -EINVAL;
+		}
+		priv->cfg_params.scanning_period = val;
+	}
+
+	if (of_property_read_u32(np, "debounce_timeout", &val) >= 0) {
+		if (val < 0 || val > 255) {
+			dev_err(dev, "debounce_timeout must be [0-255]\n");
+			return -EINVAL;
+		}
+		priv->cfg_params.debounce_timeout = val;
+	}
+
+	if (of_property_read_u32(np, "settling_timeout", &val) >= 0) {
+		if (val < 0 || val > 11) {
+			dev_err(dev, "settling_timeout must be [0-11]\n");
+			return -EINVAL;
+		}
+		priv->cfg_params.settling_timeout = val;
+	}
+
+	if (of_property_read_u32(np, "touch_timeout", &val) >= 0) {
+		if (val < 0 || val > 255) {
+			dev_err(dev, "touch_timeout must be [0-255]\n");
+			return -EINVAL;
+		}
+		priv->cfg_params.touch_timeout = val;
+	}
+
+	if (of_property_read_u32(np, "average_data", &val) >= 0) {
+		if (val < 0 || val > 8) {
+			dev_err(dev, "average_data must be [0-8]\n");
+			return -EINVAL;
+		}
+		priv->cfg_params.average_data = val;
+	}
+
+	if (of_property_read_u32(np, "fifo_threshold", &val) >= 0) {
Quoted 8 lines

drivers/input/touchscreen/bcm_iproc_tsc.c line 416

Quoted 6 lines
drivers/input/touchscreen/bcm_iproc_tsc.c new file +6 -0
+		if (val < 0 || val > 31) {
+			dev_err(dev, "fifo_threshold must be [0-31]\n");
+			return -EINVAL;
+		}
+		priv->cfg_params.fifo_threshold = val;
+	}

I think these are dveice specific and thus should have "brcm," prefix.

Quoted 2 lines

I'm confused as to why we need the brcm prefix? Other device tree bindings we have for other drivers do not need such prefix.

Properties that are not standard on the system (reg, interrupts, clkocks, etc) or subsystem level customarily carry the vendor prefix so that they do not clash with newly added global or subsystem properties.

Quoted 5 lines
Quoted 2 lines

Is this
convention documented somewhere?

Not sure. I glanced through Documentation/devicetree and do not see it spelled out. Device tree overlords, what say you?

Let me know. I haven't seen this before either. I will change the entries to use dashes though instead of underscores but will wait until these other issues are decided on before sending out another patch.

Quoted 13 lines
Quoted 13 lines
Quoted 13 lines

drivers/input/touchscreen/bcm_iproc_tsc.c line 423

Quoted 9 lines
drivers/input/touchscreen/bcm_iproc_tsc.c new file +7 -0
+
+	priv->ts_rotation = TS_ROTATION_0;
+	if (of_property_read_u32(np, "ts-rotation", &val) >= 0) {
+		priv->ts_rotation = val;
+		dev_dbg(dev, "ts rotation [%d] degrees\n",
+			90 * priv->ts_rotation);
+	}

This I am not quite sure about - if we want rotation or swap+invert. You are CCed on another email (tsc2007) that talks about need of generic touchscreen transforms in input core/of bindings.

Quoted 6 lines
Quoted 3 lines

Does such generic binding exist today? If not, I would like to go with this implementation and update to the new binding if/when it exists?

Not yet but there several people interested. I think we have enough time till 3.20 to hash it out properly.

I think the rotation is simpler personally. Everyone would understand rotation refers to how it's oriented but I'm not sure everyone would immediately know how it is wired. Let me know what is decided and I'll make any changes required.

Thanks,
Jon

Quoted 3 lines

Thanks.

#53 lore raw

Re: [PATCH v2 1/2] Input: touchscreen-iproc: Add Broadcom iProc touchscreen driver

Pinging maintainers... Am I ok to go ahead with the current rotation implementation? I haven't heard anything further. Any feedback on naming conventions from DT people?

Thanks!

Quoted 107 lines · Jonathan Richardson

Hi Dmitry,

Quoted 61 lines · Dmitry Torokhov
Quoted 53 lines · Scott Branden
Quoted 44 lines · Dmitry Torokhov

Hi Jonathan,

Quoted 41 lines · Jonathan Richardson
drivers/input/touchscreen/bcm_iproc_tsc.c new file +41 -0
+	if (of_property_read_u32(np, "scanning_period", &val) >= 0) {
+		if (val < 1 || val > 256) {
+			dev_err(dev, "scanning_period must be [1-256]\n");
+			return -EINVAL;
+		}
+		priv->cfg_params.scanning_period = val;
+	}
+
+	if (of_property_read_u32(np, "debounce_timeout", &val) >= 0) {
+		if (val < 0 || val > 255) {
+			dev_err(dev, "debounce_timeout must be [0-255]\n");
+			return -EINVAL;
+		}
+		priv->cfg_params.debounce_timeout = val;
+	}
+
+	if (of_property_read_u32(np, "settling_timeout", &val) >= 0) {
+		if (val < 0 || val > 11) {
+			dev_err(dev, "settling_timeout must be [0-11]\n");
+			return -EINVAL;
+		}
+		priv->cfg_params.settling_timeout = val;
+	}
+
+	if (of_property_read_u32(np, "touch_timeout", &val) >= 0) {
+		if (val < 0 || val > 255) {
+			dev_err(dev, "touch_timeout must be [0-255]\n");
+			return -EINVAL;
+		}
+		priv->cfg_params.touch_timeout = val;
+	}
+
+	if (of_property_read_u32(np, "average_data", &val) >= 0) {
+		if (val < 0 || val > 8) {
+			dev_err(dev, "average_data must be [0-8]\n");
+			return -EINVAL;
+		}
+		priv->cfg_params.average_data = val;
+	}
+
+	if (of_property_read_u32(np, "fifo_threshold", &val) >= 0) {
Quoted 8 lines

drivers/input/touchscreen/bcm_iproc_tsc.c line 416

Quoted 6 lines
drivers/input/touchscreen/bcm_iproc_tsc.c new file +6 -0
+		if (val < 0 || val > 31) {
+			dev_err(dev, "fifo_threshold must be [0-31]\n");
+			return -EINVAL;
+		}
+		priv->cfg_params.fifo_threshold = val;
+	}

I think these are dveice specific and thus should have "brcm," prefix.

Quoted 2 lines

I'm confused as to why we need the brcm prefix? Other device tree bindings we have for other drivers do not need such prefix.

Properties that are not standard on the system (reg, interrupts, clkocks, etc) or subsystem level customarily carry the vendor prefix so that they do not clash with newly added global or subsystem properties.

Quoted 5 lines
Quoted 2 lines

Is this
convention documented somewhere?

Not sure. I glanced through Documentation/devicetree and do not see it spelled out. Device tree overlords, what say you?

Let me know. I haven't seen this before either. I will change the entries to use dashes though instead of underscores but will wait until these other issues are decided on before sending out another patch.

Quoted 13 lines
Quoted 13 lines
Quoted 13 lines

drivers/input/touchscreen/bcm_iproc_tsc.c line 423

Quoted 9 lines
drivers/input/touchscreen/bcm_iproc_tsc.c new file +7 -0
+
+	priv->ts_rotation = TS_ROTATION_0;
+	if (of_property_read_u32(np, "ts-rotation", &val) >= 0) {
+		priv->ts_rotation = val;
+		dev_dbg(dev, "ts rotation [%d] degrees\n",
+			90 * priv->ts_rotation);
+	}

This I am not quite sure about - if we want rotation or swap+invert. You are CCed on another email (tsc2007) that talks about need of generic touchscreen transforms in input core/of bindings.

Quoted 6 lines
Quoted 3 lines

Does such generic binding exist today? If not, I would like to go with this implementation and update to the new binding if/when it exists?

Not yet but there several people interested. I think we have enough time till 3.20 to hash it out properly.

I think the rotation is simpler personally. Everyone would understand rotation refers to how it's oriented but I'm not sure everyone would immediately know how it is wired. Let me know what is decided and I'll make any changes required.

Thanks,
Jon

Quoted 3 lines

Thanks.

maintainer
#54 lore raw

Re: [PATCH v2 1/2] Input: touchscreen-iproc: Add Broadcom iProc touchscreen driver

Jonathan,

Quoted 4 lines · Jonathan Richardson

Pinging maintainers... Am I ok to go ahead with the current rotation implementation? I haven't heard anything further. Any feedback on naming conventions from DT people?

I believe we should go with touchscreen-inverted-x, touchscreen-inverted-y and touchscreen-swapped-x-y properties since rotation can't really describe all permutations of potential connections.

I'll be taking Hans de Goede's patch adding this new property to the bindings (adjusting the name slightly).

Thanks.

Quoted 111 lines

Thanks!

Quoted 107 lines · Jonathan Richardson

Hi Dmitry,

Quoted 61 lines · Dmitry Torokhov
Quoted 53 lines · Scott Branden
Quoted 44 lines · Dmitry Torokhov

Hi Jonathan,

Quoted 41 lines · Jonathan Richardson
drivers/input/touchscreen/bcm_iproc_tsc.c new file +41 -0
+	if (of_property_read_u32(np, "scanning_period", &val) >= 0) {
+		if (val < 1 || val > 256) {
+			dev_err(dev, "scanning_period must be [1-256]\n");
+			return -EINVAL;
+		}
+		priv->cfg_params.scanning_period = val;
+	}
+
+	if (of_property_read_u32(np, "debounce_timeout", &val) >= 0) {
+		if (val < 0 || val > 255) {
+			dev_err(dev, "debounce_timeout must be [0-255]\n");
+			return -EINVAL;
+		}
+		priv->cfg_params.debounce_timeout = val;
+	}
+
+	if (of_property_read_u32(np, "settling_timeout", &val) >= 0) {
+		if (val < 0 || val > 11) {
+			dev_err(dev, "settling_timeout must be [0-11]\n");
+			return -EINVAL;
+		}
+		priv->cfg_params.settling_timeout = val;
+	}
+
+	if (of_property_read_u32(np, "touch_timeout", &val) >= 0) {
+		if (val < 0 || val > 255) {
+			dev_err(dev, "touch_timeout must be [0-255]\n");
+			return -EINVAL;
+		}
+		priv->cfg_params.touch_timeout = val;
+	}
+
+	if (of_property_read_u32(np, "average_data", &val) >= 0) {
+		if (val < 0 || val > 8) {
+			dev_err(dev, "average_data must be [0-8]\n");
+			return -EINVAL;
+		}
+		priv->cfg_params.average_data = val;
+	}
+
+	if (of_property_read_u32(np, "fifo_threshold", &val) >= 0) {
Quoted 8 lines

drivers/input/touchscreen/bcm_iproc_tsc.c line 416

Quoted 6 lines
drivers/input/touchscreen/bcm_iproc_tsc.c new file +6 -0
+		if (val < 0 || val > 31) {
+			dev_err(dev, "fifo_threshold must be [0-31]\n");
+			return -EINVAL;
+		}
+		priv->cfg_params.fifo_threshold = val;
+	}

I think these are dveice specific and thus should have "brcm," prefix.

Quoted 2 lines

I'm confused as to why we need the brcm prefix? Other device tree bindings we have for other drivers do not need such prefix.

Properties that are not standard on the system (reg, interrupts, clkocks, etc) or subsystem level customarily carry the vendor prefix so that they do not clash with newly added global or subsystem properties.

Quoted 5 lines
Quoted 2 lines

Is this
convention documented somewhere?

Not sure. I glanced through Documentation/devicetree and do not see it spelled out. Device tree overlords, what say you?

Let me know. I haven't seen this before either. I will change the entries to use dashes though instead of underscores but will wait until these other issues are decided on before sending out another patch.

Quoted 13 lines
Quoted 13 lines
Quoted 13 lines

drivers/input/touchscreen/bcm_iproc_tsc.c line 423

Quoted 9 lines
drivers/input/touchscreen/bcm_iproc_tsc.c new file +7 -0
+
+	priv->ts_rotation = TS_ROTATION_0;
+	if (of_property_read_u32(np, "ts-rotation", &val) >= 0) {
+		priv->ts_rotation = val;
+		dev_dbg(dev, "ts rotation [%d] degrees\n",
+			90 * priv->ts_rotation);
+	}

This I am not quite sure about - if we want rotation or swap+invert. You are CCed on another email (tsc2007) that talks about need of generic touchscreen transforms in input core/of bindings.

Quoted 6 lines
Quoted 3 lines

Does such generic binding exist today? If not, I would like to go with this implementation and update to the new binding if/when it exists?

Not yet but there several people interested. I think we have enough time till 3.20 to hash it out properly.

I think the rotation is simpler personally. Everyone would understand rotation refers to how it's oriented but I'm not sure everyone would immediately know how it is wired. Let me know what is decided and I'll make any changes required.

Thanks,
Jon

Quoted 3 lines

Thanks.

Signature · 1 line
Dmitry
#55 lore raw

Re: [PATCH v2 1/2] Input: touchscreen-iproc: Add Broadcom iProc touchscreen driver

Hi Dmitry,

Thanks. I'll go through his patch and make the appropriate changes to our driver.

Jon

Quoted 131 lines · Dmitry Torokhov

Jonathan,

Quoted 4 lines · Jonathan Richardson

Pinging maintainers... Am I ok to go ahead with the current rotation implementation? I haven't heard anything further. Any feedback on naming conventions from DT people?

I believe we should go with touchscreen-inverted-x, touchscreen-inverted-y and touchscreen-swapped-x-y properties since rotation can't really describe all permutations of potential connections.

I'll be taking Hans de Goede's patch adding this new property to the bindings (adjusting the name slightly).

Thanks.

Quoted 111 lines

Thanks!

Quoted 107 lines · Jonathan Richardson

Hi Dmitry,

Quoted 61 lines · Dmitry Torokhov
Quoted 53 lines · Scott Branden
Quoted 44 lines · Dmitry Torokhov

Hi Jonathan,

Quoted 41 lines · Jonathan Richardson
(quoted diff) +41 -0
+	if (of_property_read_u32(np, "scanning_period", &val) >= 0) {
+		if (val < 1 || val > 256) {
+			dev_err(dev, "scanning_period must be [1-256]\n");
+			return -EINVAL;
+		}
+		priv->cfg_params.scanning_period = val;
+	}
+
+	if (of_property_read_u32(np, "debounce_timeout", &val) >= 0) {
+		if (val < 0 || val > 255) {
+			dev_err(dev, "debounce_timeout must be [0-255]\n");
+			return -EINVAL;
+		}
+		priv->cfg_params.debounce_timeout = val;
+	}
+
+	if (of_property_read_u32(np, "settling_timeout", &val) >= 0) {
+		if (val < 0 || val > 11) {
+			dev_err(dev, "settling_timeout must be [0-11]\n");
+			return -EINVAL;
+		}
+		priv->cfg_params.settling_timeout = val;
+	}
+
+	if (of_property_read_u32(np, "touch_timeout", &val) >= 0) {
+		if (val < 0 || val > 255) {
+			dev_err(dev, "touch_timeout must be [0-255]\n");
+			return -EINVAL;
+		}
+		priv->cfg_params.touch_timeout = val;
+	}
+
+	if (of_property_read_u32(np, "average_data", &val) >= 0) {
+		if (val < 0 || val > 8) {
+			dev_err(dev, "average_data must be [0-8]\n");
+			return -EINVAL;
+		}
+		priv->cfg_params.average_data = val;
+	}
+
+	if (of_property_read_u32(np, "fifo_threshold", &val) >= 0) {
Quoted 8 lines

Review

Quoted 6 lines
(quoted diff) +6 -0
+		if (val < 0 || val > 31) {
+			dev_err(dev, "fifo_threshold must be [0-31]\n");
+			return -EINVAL;
+		}
+		priv->cfg_params.fifo_threshold = val;
+	}

I think these are dveice specific and thus should have "brcm," prefix.

Quoted 2 lines

I'm confused as to why we need the brcm prefix? Other device tree bindings we have for other drivers do not need such prefix.

Properties that are not standard on the system (reg, interrupts, clkocks, etc) or subsystem level customarily carry the vendor prefix so that they do not clash with newly added global or subsystem properties.

Quoted 5 lines
Quoted 2 lines

Is this
convention documented somewhere?

Not sure. I glanced through Documentation/devicetree and do not see it spelled out. Device tree overlords, what say you?

Let me know. I haven't seen this before either. I will change the entries to use dashes though instead of underscores but will wait until these other issues are decided on before sending out another patch.

Quoted 13 lines
Quoted 13 lines
Quoted 13 lines

Review

Quoted 9 lines
(quoted diff) +7 -0
+
+	priv->ts_rotation = TS_ROTATION_0;
+	if (of_property_read_u32(np, "ts-rotation", &val) >= 0) {
+		priv->ts_rotation = val;
+		dev_dbg(dev, "ts rotation [%d] degrees\n",
+			90 * priv->ts_rotation);
+	}

This I am not quite sure about - if we want rotation or swap+invert. You are CCed on another email (tsc2007) that talks about need of generic touchscreen transforms in input core/of bindings.

Quoted 6 lines
Quoted 3 lines

Does such generic binding exist today? If not, I would like to go with this implementation and update to the new binding if/when it exists?

Not yet but there several people interested. I think we have enough time till 3.20 to hash it out properly.

I think the rotation is simpler personally. Everyone would understand rotation refers to how it's oriented but I'm not sure everyone would immediately know how it is wired. Let me know what is decided and I'll make any changes required.

Thanks,
Jon

Quoted 3 lines

Thanks.

maintainer
#56 lore raw

Re: [PATCH v2 1/2] Input: touchscreen-iproc: Add Broadcom iProc touchscreen driver

In reply to Jonathan Richardson

Hi Jonathan,

Quoted 251 lines · Jonathan Richardson

Add initial version of the Broadcom touchscreen driver.

---
 drivers/input/touchscreen/Kconfig         |   11 +
 drivers/input/touchscreen/Makefile        |    1 +
 drivers/input/touchscreen/bcm_iproc_tsc.c |  535 +++++++++++++++++++++++++++++
 3 files changed, 547 insertions(+)
 create mode 100644 drivers/input/touchscreen/bcm_iproc_tsc.c
drivers/input/touchscreen/Kconfig +11 -0
index e1d8003..77ff531 100644
@@ -310,6 +310,17 @@ config TOUCHSCREEN_ILI210X
 	  To compile this driver as a module, choose M here: the
 	  module will be called ili210x.
 
+config TOUCHSCREEN_IPROC
+	tristate "IPROC touch panel driver support"
+	help
+	  Say Y here if you want to add support for the IPROC touch
+	  controller to your system.
+
+	  If unsure, say N.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called iproc-ts.
+
 config TOUCHSCREEN_S3C2410
 	tristate "Samsung S3C2410/generic touchscreen input driver"
 	depends on ARCH_S3C24XX || SAMSUNG_DEV_TS
drivers/input/touchscreen/Makefile +1 -0
index 090e61c..f7e6de9 100644
@@ -37,6 +37,7 @@ obj-$(CONFIG_TOUCHSCREEN_FUJITSU)	+= fujitsu_ts.o
 obj-$(CONFIG_TOUCHSCREEN_ILI210X)	+= ili210x.o
 obj-$(CONFIG_TOUCHSCREEN_INEXIO)	+= inexio.o
 obj-$(CONFIG_TOUCHSCREEN_INTEL_MID)	+= intel-mid-touch.o
+obj-$(CONFIG_TOUCHSCREEN_IPROC)		+= bcm_iproc_tsc.o
 obj-$(CONFIG_TOUCHSCREEN_LPC32XX)	+= lpc32xx_ts.o
 obj-$(CONFIG_TOUCHSCREEN_MAX11801)	+= max11801_ts.o
 obj-$(CONFIG_TOUCHSCREEN_MC13783)	+= mc13783_ts.o
drivers/input/touchscreen/bcm_iproc_tsc.c new file +198 -0
new file mode 100644
index 0000000..bf6eb7f
@@ -0,0 +1,535 @@
+/*
+* Copyright (C) 2014 Broadcom Corporation
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License as
+* published by the Free Software Foundation version 2.
+*
+* This program is distributed "as is" WITHOUT ANY WARRANTY of any
+* kind, whether express or implied; without even the implied warranty
+* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*/
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/keyboard.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/of.h>
+#include <asm/irq.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/serio.h>
+
+#define IPROC_TS_NAME "iproc-ts"
+
+#define PEN_DOWN_STATUS     1
+#define PEN_UP_STATUS       0
+
+#define X_MIN               0
+#define Y_MIN               0
+#define X_MAX               0xFFF
+#define Y_MAX               0xFFF
+
+/* Value given by controller for invalid coordinate. */
+#define INVALID_COORD       0xFFFFFFFF
+
+/* Register offsets */
+#define REGCTL1             0x00
+#define REGCTL2             0x04
+#define INTERRUPT_THRES     0x08
+#define INTERRUPT_MASK      0x0c
+
+#define INTERRUPT_STATUS    0x10
+#define CONTROLLER_STATUS   0x14
+#define FIFO_DATA           0x18
+#define FIFO_DATA_X_Y_MASK  0xFFFF
+#define ANALOG_CONTROL      0x1c
+
+#define AUX_DATA            0x20
+#define DEBOUNCE_CNTR_STAT  0x24
+#define SCAN_CNTR_STAT      0x28
+#define REM_CNTR_STAT       0x2c
+
+#define SETTLING_TIMER_STAT 0x30
+#define SPARE_REG           0x34
+#define SOFT_BYPASS_CONTROL 0x38
+#define SOFT_BYPASS_DATA    0x3c
+
+
+/* Bit values for INTERRUPT_MASK and INTERRUPT_STATUS regs */
+#define TS_PEN_INTR_MASK        BIT(0)
+#define TS_FIFO_INTR_MASK       BIT(2)
+
+/* Bit values for CONTROLLER_STATUS reg1 */
+#define TS_PEN_DOWN             BIT(0)
+
+/* Shift values for control reg1 */
+#define SCANNING_PERIOD_SHIFT   24
+#define DEBOUNCE_TIMEOUT_SHIFT  16
+#define SETTLING_TIMEOUT_SHIFT  8
+#define TOUCH_TIMEOUT_SHIFT     0
+
+/* Shift values for coordinates from fifo */
+#define X_COORD_SHIFT  0
+#define Y_COORD_SHIFT  16
+
+/* Bit values for REGCTL2 */
+#define TS_CONTROLLER_EN_BIT    BIT(16)
+#define TS_CONTROLLER_AVGDATA_SHIFT 8
+#define TS_CONTROLLER_AVGDATA_MASK (0x7 << TS_CONTROLLER_AVGDATA_SHIFT)
+#define TS_CONTROLLER_PWR_LDO   BIT(5)
+#define TS_CONTROLLER_PWR_ADC   BIT(4)
+#define TS_CONTROLLER_PWR_BGP   BIT(3)
+#define TS_CONTROLLER_PWR_TS    BIT(2)
+#define TS_WIRE_MODE_BIT        BIT(1)
+
+/*
+ * Touch screen mount angles w.r.t LCD panel left side top corner
+ * TS (x_min,y_min) placed at LCD (x_min,y_min) rotation angle is 0
+ * TS (x_min,y_max) placed at LCD (x_min,y_min) rotation angle is 90
+ * TS (x_max,y_max) placed at LCD (x_min,y_min) rotation angle is 180
+ * TS (x_max,y_min) placed at LCD (x_min,y_min) rotation angle is 270
+ */
+enum ts_rotation_angles {
+	TS_ROTATION_0,
+	TS_ROTATION_90,
+	TS_ROTATION_180,
+	TS_ROTATION_270,
+};
+
+struct tsc_param {
+	/* Each step is 1024 us.  Valid 1-256 */
+	u32 scanning_period;
+
+	/*  Each step is 512 us.  Valid 0-255 */
+	u32 debounce_timeout;
+
+	/*
+	 * The settling duration (in ms) is the amount of time the tsc
+	 * waits to allow the voltage to settle after turning on the
+	 * drivers in detection mode. Valid values: 0-11
+	 *   0 =  0.008 ms
+	 *   1 =  0.01 ms
+	 *   2 =  0.02 ms
+	 *   3 =  0.04 ms
+	 *   4 =  0.08 ms
+	 *   5 =  0.16 ms
+	 *   6 =  0.32 ms
+	 *   7 =  0.64 ms
+	 *   8 =  1.28 ms
+	 *   9 =  2.56 ms
+	 *   10 = 5.12 ms
+	 *   11 = 10.24 ms
+	 */
+	u32 settling_timeout;
+
+	/* touch timeout in sample counts */
+	u32 touch_timeout;
+
+	/*
+	 * Number of data samples which are averaged before a final data point
+	 * is placed into the FIFO
+	 */
+	u32 average_data;
+
+	/* FIFO threshold */
+	u32 fifo_threshold;
+};
+
+struct iproc_ts_priv {
+	struct platform_device *pdev;
+	struct input_dev *idev;
+
+	void __iomem *regs;
+	struct clk *tsc_clk;
+
+	int  pen_status;
+	int  ts_rotation;
+	struct tsc_param cfg_params;
+};
+
+/*
+ * Set default values the same as hardware reset values
+ * except for fifo_threshold with is set to 1.
+ */
+static struct tsc_param default_config = {
+	.scanning_period  = 0x5,  /* 1 to 256 */
+	.debounce_timeout = 0x28, /* 0 to 255 */
+	.settling_timeout = 0x7,  /* 0 to 11 */
+	.touch_timeout    = 0xa,  /* 0 to 255 */
+	.average_data     = 5,    /* entry 5 = 32 pts */
+	.fifo_threshold   = 1,    /* 0 to 31 */
+};
+
+static void ts_reg_dump(struct iproc_ts_priv *priv)
+{
+	struct device *dev = &priv->pdev->dev;
+
+	dev_dbg(dev, "regCtl1             = 0x%08x\n",
+				readl(priv->regs + REGCTL1));
+	dev_dbg(dev, "regCtl2             = 0x%08x\n",
+				readl(priv->regs + REGCTL2));
+	dev_dbg(dev, "interrupt_Thres     = 0x%08x\n",
+				readl(priv->regs + INTERRUPT_THRES));
+	dev_dbg(dev, "interrupt_Mask      = 0x%08x\n",
+				readl(priv->regs + INTERRUPT_MASK));
+	dev_dbg(dev, "interrupt_Status    = 0x%08x\n",
+				readl(priv->regs + INTERRUPT_STATUS));
+	dev_dbg(dev, "controller_Status   = 0x%08x\n",
+				readl(priv->regs + CONTROLLER_STATUS));
+	dev_dbg(dev, "FIFO_Data           = 0x%08x\n",
+				readl(priv->regs + FIFO_DATA));
+	dev_dbg(dev, "analog_Control      = 0x%08x\n",
+				readl(priv->regs + ANALOG_CONTROL));
+	dev_dbg(dev, "aux_Data            = 0x%08x\n",
+				readl(priv->regs + AUX_DATA));
+	dev_dbg(dev, "debounce_Cntr_Stat  = 0x%08x\n",
+				readl(priv->regs + DEBOUNCE_CNTR_STAT));
+	dev_dbg(dev, "scan_Cntr_Stat      = 0x%08x\n",
+				readl(priv->regs + SCAN_CNTR_STAT));
+	dev_dbg(dev, "rem_Cntr_Stat       = 0x%08x\n",
+				readl(priv->regs + REM_CNTR_STAT));
+	dev_dbg(dev, "settling_Timer_Stat = 0x%08x\n",
+				readl(priv->regs + SETTLING_TIMER_STAT));
+	dev_dbg(dev, "spare_Reg           = 0x%08x\n",

drivers/input/touchscreen/bcm_iproc_tsc.c line 208

Quoted 10 lines
drivers/input/touchscreen/bcm_iproc_tsc.c new file +10 -0
+				readl(priv->regs + SPARE_REG));
+	dev_dbg(dev, "soft_Bypass_Control = 0x%08x\n",
+				readl(priv->regs + SOFT_BYPASS_CONTROL));
+	dev_dbg(dev, "soft_Bypass_Data    = 0x%08x\n",
+				readl(priv->regs + SOFT_BYPASS_DATA));
+}
+
+static irqreturn_t iproc_touchscreen_interrupt(int irq, void *data)
+{
+	struct platform_device *pdev = (struct platform_device *)data;

No need to cast here.

drivers/input/touchscreen/bcm_iproc_tsc.c line 213

Quoted 5 lines
drivers/input/touchscreen/bcm_iproc_tsc.c new file +5 -0
+	struct iproc_ts_priv *priv;
+	u32 intr_status = 0;
+	u32 raw_coordinate = 0;
+	u16 x = 0;
+	u16 y = 0;

Why do you need all these initialized? It just hides potential problems when variable is used without assigning proper value.

drivers/input/touchscreen/bcm_iproc_tsc.c line 216

Quoted 3 lines
drivers/input/touchscreen/bcm_iproc_tsc.c new file +3 -0
+	int i;
+
+	priv = (struct iproc_ts_priv *)platform_get_drvdata(pdev);

No need to cast here.

Quoted 5 lines
drivers/input/touchscreen/bcm_iproc_tsc.c new file +5 -0
+
+	intr_status = readl(priv->regs + INTERRUPT_STATUS);
+	intr_status &= (TS_PEN_INTR_MASK | TS_FIFO_INTR_MASK);
+	if (intr_status == 0)
+		return IRQ_NONE;

drivers/input/touchscreen/bcm_iproc_tsc.c line 231

Quoted 10 lines
drivers/input/touchscreen/bcm_iproc_tsc.c new file +10 -0
+
+	/* Clear all interrupt status bits, write-1-clear */
+	writel(intr_status, priv->regs + INTERRUPT_STATUS);
+
+	/* Pen up/down */
+	if (intr_status & TS_PEN_INTR_MASK) {
+		if (readl(priv->regs + CONTROLLER_STATUS) & TS_PEN_DOWN) {
+			priv->pen_status = PEN_DOWN_STATUS;
+			input_report_key(priv->idev, BTN_TOUCH,
+				priv->pen_status);

We do not do input_sync() here... But what happens if we do not get TS_FIFO_INTR_MASK in the status? Won't we "lose" the sync?

I'd prefer you parsed the hardware state fully and then emitted all needed events based on the state.

drivers/input/touchscreen/bcm_iproc_tsc.c line 236

Quoted 5 lines
drivers/input/touchscreen/bcm_iproc_tsc.c new file +5 -0
+		} else {
+			priv->pen_status = PEN_UP_STATUS;
+			input_report_key(priv->idev, BTN_TOUCH,
+				priv->pen_status);
+			input_sync(priv->idev);

Same here. Can we be reporting coordinates from FIFO even after pen is up?

Quoted 47 lines
drivers/input/touchscreen/bcm_iproc_tsc.c new file +47 -0
+		}
+
+		dev_dbg(&priv->pdev->dev,
+			"pen up-down (%d)\n", priv->pen_status);
+	}
+
+	/* coordinates in FIFO exceed the theshold */
+	if (intr_status & TS_FIFO_INTR_MASK) {
+		for (i = 0; i < priv->cfg_params.fifo_threshold; i++) {
+			raw_coordinate = readl(priv->regs + FIFO_DATA);
+			if (raw_coordinate == INVALID_COORD)
+				continue;
+
+			/*
+			 * The x and y coordinate are 16 bits each
+			 * with the x in the lower 16 bits and y in the
+			 * upper 16 bits.
+			 */
+			x = (raw_coordinate >> X_COORD_SHIFT) &
+				FIFO_DATA_X_Y_MASK;
+			y = (raw_coordinate >> Y_COORD_SHIFT) &
+				FIFO_DATA_X_Y_MASK;
+
+			/* We only want to retain the 12 msb of the 16 */
+			x = (x >> 4) & 0x0FFF;
+			y = (y >> 4) & 0x0FFF;
+
+			/* adjust x y according to lcd tsc mount angle */
+			if (priv->ts_rotation == TS_ROTATION_90) {
+				y = Y_MAX - y;
+			} else if (priv->ts_rotation == TS_ROTATION_180) {
+				x = X_MAX - x;
+				y = Y_MAX - y;
+			} else if (priv->ts_rotation == TS_ROTATION_270) {
+				x = X_MAX - x;
+			}
+
+			input_report_abs(priv->idev, ABS_X, x);
+			input_report_abs(priv->idev, ABS_Y, y);
+			input_sync(priv->idev);
+
+			dev_dbg(&priv->pdev->dev, "xy (0x%x 0x%x)\n", x, y);
+		}
+	}
+
+	return IRQ_HANDLED;
+}

drivers/input/touchscreen/bcm_iproc_tsc.c line 293

Quoted 10 lines
drivers/input/touchscreen/bcm_iproc_tsc.c new file +10 -0
+
+static int iproc_ts_start(struct input_dev *idev)
+{
+	u32 val;
+	int ret;
+	struct iproc_ts_priv *priv;
+
+	priv = input_get_drvdata(idev);
+	if (priv == NULL)
+		return -ENODEV;

How can it be NULL? It is fully controlled by this driver and it should set it up before registering the input device.

Quoted 11 lines
drivers/input/touchscreen/bcm_iproc_tsc.c new file +11 -0
+
+	/* Enable clock */
+	ret = clk_prepare_enable(priv->tsc_clk);
+	if (ret) {
+		dev_err(&priv->pdev->dev, "%s clk_prepare_enable failed %d\n",
+			__func__, ret);
+		return ret;
+	}
+
+	/*
+	 * Interrupt is generated when:

drivers/input/touchscreen/bcm_iproc_tsc.c line 314

Quoted 10 lines
drivers/input/touchscreen/bcm_iproc_tsc.c new file +10 -0
+	 *  FIFO reaches the int_th value, and pen event(up/down)
+	 */
+	val = TS_PEN_INTR_MASK | TS_FIFO_INTR_MASK;
+	writel(val, priv->regs + INTERRUPT_MASK);
+
+	writel(priv->cfg_params.fifo_threshold, priv->regs + INTERRUPT_THRES);
+
+	/* Initialize control reg1 */
+	val = 0;
+	val |= (priv->cfg_params.scanning_period << SCANNING_PERIOD_SHIFT);

Please drop extra parentheses here and elsewhere.

Quoted 27 lines
drivers/input/touchscreen/bcm_iproc_tsc.c new file +27 -0
+	val |= (priv->cfg_params.debounce_timeout << DEBOUNCE_TIMEOUT_SHIFT);
+	val |= (priv->cfg_params.settling_timeout << SETTLING_TIMEOUT_SHIFT);
+	val |= (priv->cfg_params.touch_timeout << TOUCH_TIMEOUT_SHIFT);
+	writel(val, priv->regs + REGCTL1);
+
+	/* Try to clear all interrupt status */
+	val = readl(priv->regs + INTERRUPT_STATUS);
+	val |= (TS_FIFO_INTR_MASK | TS_PEN_INTR_MASK);
+	writel(val, priv->regs + INTERRUPT_STATUS);
+
+	/* Initialize control reg2 */
+	val = readl(priv->regs + REGCTL2);
+	val |= (TS_CONTROLLER_EN_BIT | TS_WIRE_MODE_BIT);
+
+	val &= ~(TS_CONTROLLER_AVGDATA_MASK);
+	val |= (priv->cfg_params.average_data << TS_CONTROLLER_AVGDATA_SHIFT);
+
+	val &= ~(TS_CONTROLLER_PWR_LDO |	/* PWR up LDO */
+		   TS_CONTROLLER_PWR_ADC |	/* PWR up ADC */
+		   TS_CONTROLLER_PWR_BGP |	/* PWR up BGP */
+		   TS_CONTROLLER_PWR_TS);	/* PWR up TS */
+
+	writel(val, priv->regs + REGCTL2);
+
+	ts_reg_dump(priv);
+
+	return 0;

drivers/input/touchscreen/bcm_iproc_tsc.c line 351

Quoted 10 lines
drivers/input/touchscreen/bcm_iproc_tsc.c new file +10 -0
+}
+
+static void iproc_ts_stop(struct input_dev *dev)
+{
+	u32 val;
+	struct iproc_ts_priv *priv;
+
+	priv = input_get_drvdata(dev);
+	if (priv == NULL)
+		return;

Again, no need to check it here.

Quoted 187 lines
drivers/input/touchscreen/bcm_iproc_tsc.c new file +184 -0
+
+	writel(0, priv->regs + INTERRUPT_MASK); /* Disable all interrupts */
+
+	/* Only power down touch screen controller */
+	val = readl(priv->regs + REGCTL2);
+	val |= TS_CONTROLLER_PWR_TS;
+	writel(val, priv->regs + REGCTL2);
+
+	clk_disable(priv->tsc_clk);
+}
+
+static int get_tsc_config(struct device_node *np, struct iproc_ts_priv *priv)
+{
+	u32 val;
+	struct device *dev = &priv->pdev->dev;
+
+	priv->cfg_params = default_config;
+
+	if (of_property_read_u32(np, "scanning_period", &val) >= 0) {
+		if (val < 1 || val > 256) {
+			dev_err(dev, "scanning_period must be [1-256]\n");
+			return -EINVAL;
+		}
+		priv->cfg_params.scanning_period = val;
+	}
+
+	if (of_property_read_u32(np, "debounce_timeout", &val) >= 0) {
+		if (val < 0 || val > 255) {
+			dev_err(dev, "debounce_timeout must be [0-255]\n");
+			return -EINVAL;
+		}
+		priv->cfg_params.debounce_timeout = val;
+	}
+
+	if (of_property_read_u32(np, "settling_timeout", &val) >= 0) {
+		if (val < 0 || val > 11) {
+			dev_err(dev, "settling_timeout must be [0-11]\n");
+			return -EINVAL;
+		}
+		priv->cfg_params.settling_timeout = val;
+	}
+
+	if (of_property_read_u32(np, "touch_timeout", &val) >= 0) {
+		if (val < 0 || val > 255) {
+			dev_err(dev, "touch_timeout must be [0-255]\n");
+			return -EINVAL;
+		}
+		priv->cfg_params.touch_timeout = val;
+	}
+
+	if (of_property_read_u32(np, "average_data", &val) >= 0) {
+		if (val < 0 || val > 8) {
+			dev_err(dev, "average_data must be [0-8]\n");
+			return -EINVAL;
+		}
+		priv->cfg_params.average_data = val;
+	}
+
+	if (of_property_read_u32(np, "fifo_threshold", &val) >= 0) {
+		if (val < 0 || val > 31) {
+			dev_err(dev, "fifo_threshold must be [0-31]\n");
+			return -EINVAL;
+		}
+		priv->cfg_params.fifo_threshold = val;
+	}
+
+	priv->ts_rotation = TS_ROTATION_0;
+	if (of_property_read_u32(np, "ts-rotation", &val) >= 0) {
+		priv->ts_rotation = val;
+		dev_dbg(dev, "ts rotation [%d] degrees\n",
+			90 * priv->ts_rotation);
+	}
+
+	return 0;
+}
+
+static int iproc_ts_probe(struct platform_device *pdev)
+{
+	struct iproc_ts_priv *priv;
+	struct input_dev *idev;
+	struct resource *res;
+	int ret;
+	int irq;
+
+	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	/* touchscreen controller memory mapped regs */
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	priv->regs = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(priv->regs)) {
+		dev_err(&pdev->dev, "unable to map I/O memory\n");
+		return PTR_ERR(priv->regs);
+	}
+
+	priv->tsc_clk = devm_clk_get(&pdev->dev, "tsc_clk");
+	if (IS_ERR(priv->tsc_clk)) {
+		dev_err(&pdev->dev,
+			"%s Failed getting clock tsc_clk\n", __func__);
+		return PTR_ERR(priv->tsc_clk);
+	}
+
+	ret = get_tsc_config(pdev->dev.of_node, priv);
+	if (ret != 0) {
+		dev_err(&pdev->dev, "%s get_tsc_config failed\n", __func__);
+		return ret;
+	}
+
+	idev = devm_input_allocate_device(&pdev->dev);
+	if (!idev) {
+		dev_err(&pdev->dev,
+			"%s Allocate input device failed\n", __func__);
+		return -ENOMEM;
+	}
+
+	priv->idev = idev;
+	priv->pdev = pdev;
+
+	priv->pen_status = PEN_UP_STATUS;
+
+	/* Set input device info  */
+	idev->name = IPROC_TS_NAME;
+	idev->dev.parent = &pdev->dev;
+
+	idev->id.bustype = BUS_HOST;
+	idev->id.vendor = SERIO_UNKNOWN;
+	idev->id.product = 0;
+	idev->id.version = 0;
+
+	idev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+	set_bit(BTN_TOUCH, idev->keybit);
+
+	input_set_abs_params(idev, ABS_X, X_MIN, X_MAX, 0, 0);
+	input_set_abs_params(idev, ABS_Y, Y_MIN, Y_MAX, 0, 0);
+
+	idev->open = iproc_ts_start;
+	idev->close = iproc_ts_stop;
+
+	input_set_drvdata(idev, priv);
+	platform_set_drvdata(pdev, priv);
+
+	/* get interrupt */
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0) {
+		dev_err(&pdev->dev, "%s platform_get_irq failed\n", __func__);
+		return irq;
+	}
+
+	ret = devm_request_irq(&pdev->dev, irq,
+		iproc_touchscreen_interrupt,
+		IRQF_SHARED, IPROC_TS_NAME, pdev);
+	if (ret)
+		return ret;
+
+	ret = input_register_device(priv->idev);
+	if (ret) {
+		dev_err(&pdev->dev,
+			"%s register input device failed %d\n", __func__, ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static const struct of_device_id iproc_ts_of_match[] = {
+	{.compatible = "brcm,iproc-touchscreen", },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, iproc_ts_of_match);
+
+static struct platform_driver iproc_ts_driver = {
+	.probe = iproc_ts_probe,
+	.driver = {
+		.name	= IPROC_TS_NAME,
+		.of_match_table = of_match_ptr(iproc_ts_of_match),
+	},
+};
+
+module_platform_driver(iproc_ts_driver);
+
+MODULE_DESCRIPTION("IPROC Touchscreen driver");
+MODULE_AUTHOR("Broadcom");
+MODULE_LICENSE("GPL v2");
Signature · 1 line
1.7.9.5

Thanks.

Signature · 1 line
Dmitry
#57 lore raw

Re: [PATCH v2 1/2] Input: touchscreen-iproc: Add Broadcom iProc touchscreen driver

Hi Dmitry,

Thanks for the review. I'll fix everything as suggested. One comment below. New patchset coming once I can test the latest DT bindings in Hans de Goede's patch.

Thanks,
Jon

Quoted 301 lines · Dmitry Torokhov

Hi Jonathan,

Quoted 251 lines · Jonathan Richardson

Add initial version of the Broadcom touchscreen driver.

---
 drivers/input/touchscreen/Kconfig         |   11 +
 drivers/input/touchscreen/Makefile        |    1 +
 drivers/input/touchscreen/bcm_iproc_tsc.c |  535 +++++++++++++++++++++++++++++
 3 files changed, 547 insertions(+)
 create mode 100644 drivers/input/touchscreen/bcm_iproc_tsc.c
drivers/input/touchscreen/Kconfig +11 -0
index e1d8003..77ff531 100644
@@ -310,6 +310,17 @@ config TOUCHSCREEN_ILI210X
 	  To compile this driver as a module, choose M here: the
 	  module will be called ili210x.
 
+config TOUCHSCREEN_IPROC
+	tristate "IPROC touch panel driver support"
+	help
+	  Say Y here if you want to add support for the IPROC touch
+	  controller to your system.
+
+	  If unsure, say N.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called iproc-ts.
+
 config TOUCHSCREEN_S3C2410
 	tristate "Samsung S3C2410/generic touchscreen input driver"
 	depends on ARCH_S3C24XX || SAMSUNG_DEV_TS
drivers/input/touchscreen/Makefile +1 -0
index 090e61c..f7e6de9 100644
@@ -37,6 +37,7 @@ obj-$(CONFIG_TOUCHSCREEN_FUJITSU)	+= fujitsu_ts.o
 obj-$(CONFIG_TOUCHSCREEN_ILI210X)	+= ili210x.o
 obj-$(CONFIG_TOUCHSCREEN_INEXIO)	+= inexio.o
 obj-$(CONFIG_TOUCHSCREEN_INTEL_MID)	+= intel-mid-touch.o
+obj-$(CONFIG_TOUCHSCREEN_IPROC)		+= bcm_iproc_tsc.o
 obj-$(CONFIG_TOUCHSCREEN_LPC32XX)	+= lpc32xx_ts.o
 obj-$(CONFIG_TOUCHSCREEN_MAX11801)	+= max11801_ts.o
 obj-$(CONFIG_TOUCHSCREEN_MC13783)	+= mc13783_ts.o
drivers/input/touchscreen/bcm_iproc_tsc.c new file +198 -0
new file mode 100644
index 0000000..bf6eb7f
@@ -0,0 +1,535 @@
+/*
+* Copyright (C) 2014 Broadcom Corporation
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License as
+* published by the Free Software Foundation version 2.
+*
+* This program is distributed "as is" WITHOUT ANY WARRANTY of any
+* kind, whether express or implied; without even the implied warranty
+* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*/
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/keyboard.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/of.h>
+#include <asm/irq.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/serio.h>
+
+#define IPROC_TS_NAME "iproc-ts"
+
+#define PEN_DOWN_STATUS     1
+#define PEN_UP_STATUS       0
+
+#define X_MIN               0
+#define Y_MIN               0
+#define X_MAX               0xFFF
+#define Y_MAX               0xFFF
+
+/* Value given by controller for invalid coordinate. */
+#define INVALID_COORD       0xFFFFFFFF
+
+/* Register offsets */
+#define REGCTL1             0x00
+#define REGCTL2             0x04
+#define INTERRUPT_THRES     0x08
+#define INTERRUPT_MASK      0x0c
+
+#define INTERRUPT_STATUS    0x10
+#define CONTROLLER_STATUS   0x14
+#define FIFO_DATA           0x18
+#define FIFO_DATA_X_Y_MASK  0xFFFF
+#define ANALOG_CONTROL      0x1c
+
+#define AUX_DATA            0x20
+#define DEBOUNCE_CNTR_STAT  0x24
+#define SCAN_CNTR_STAT      0x28
+#define REM_CNTR_STAT       0x2c
+
+#define SETTLING_TIMER_STAT 0x30
+#define SPARE_REG           0x34
+#define SOFT_BYPASS_CONTROL 0x38
+#define SOFT_BYPASS_DATA    0x3c
+
+
+/* Bit values for INTERRUPT_MASK and INTERRUPT_STATUS regs */
+#define TS_PEN_INTR_MASK        BIT(0)
+#define TS_FIFO_INTR_MASK       BIT(2)
+
+/* Bit values for CONTROLLER_STATUS reg1 */
+#define TS_PEN_DOWN             BIT(0)
+
+/* Shift values for control reg1 */
+#define SCANNING_PERIOD_SHIFT   24
+#define DEBOUNCE_TIMEOUT_SHIFT  16
+#define SETTLING_TIMEOUT_SHIFT  8
+#define TOUCH_TIMEOUT_SHIFT     0
+
+/* Shift values for coordinates from fifo */
+#define X_COORD_SHIFT  0
+#define Y_COORD_SHIFT  16
+
+/* Bit values for REGCTL2 */
+#define TS_CONTROLLER_EN_BIT    BIT(16)
+#define TS_CONTROLLER_AVGDATA_SHIFT 8
+#define TS_CONTROLLER_AVGDATA_MASK (0x7 << TS_CONTROLLER_AVGDATA_SHIFT)
+#define TS_CONTROLLER_PWR_LDO   BIT(5)
+#define TS_CONTROLLER_PWR_ADC   BIT(4)
+#define TS_CONTROLLER_PWR_BGP   BIT(3)
+#define TS_CONTROLLER_PWR_TS    BIT(2)
+#define TS_WIRE_MODE_BIT        BIT(1)
+
+/*
+ * Touch screen mount angles w.r.t LCD panel left side top corner
+ * TS (x_min,y_min) placed at LCD (x_min,y_min) rotation angle is 0
+ * TS (x_min,y_max) placed at LCD (x_min,y_min) rotation angle is 90
+ * TS (x_max,y_max) placed at LCD (x_min,y_min) rotation angle is 180
+ * TS (x_max,y_min) placed at LCD (x_min,y_min) rotation angle is 270
+ */
+enum ts_rotation_angles {
+	TS_ROTATION_0,
+	TS_ROTATION_90,
+	TS_ROTATION_180,
+	TS_ROTATION_270,
+};
+
+struct tsc_param {
+	/* Each step is 1024 us.  Valid 1-256 */
+	u32 scanning_period;
+
+	/*  Each step is 512 us.  Valid 0-255 */
+	u32 debounce_timeout;
+
+	/*
+	 * The settling duration (in ms) is the amount of time the tsc
+	 * waits to allow the voltage to settle after turning on the
+	 * drivers in detection mode. Valid values: 0-11
+	 *   0 =  0.008 ms
+	 *   1 =  0.01 ms
+	 *   2 =  0.02 ms
+	 *   3 =  0.04 ms
+	 *   4 =  0.08 ms
+	 *   5 =  0.16 ms
+	 *   6 =  0.32 ms
+	 *   7 =  0.64 ms
+	 *   8 =  1.28 ms
+	 *   9 =  2.56 ms
+	 *   10 = 5.12 ms
+	 *   11 = 10.24 ms
+	 */
+	u32 settling_timeout;
+
+	/* touch timeout in sample counts */
+	u32 touch_timeout;
+
+	/*
+	 * Number of data samples which are averaged before a final data point
+	 * is placed into the FIFO
+	 */
+	u32 average_data;
+
+	/* FIFO threshold */
+	u32 fifo_threshold;
+};
+
+struct iproc_ts_priv {
+	struct platform_device *pdev;
+	struct input_dev *idev;
+
+	void __iomem *regs;
+	struct clk *tsc_clk;
+
+	int  pen_status;
+	int  ts_rotation;
+	struct tsc_param cfg_params;
+};
+
+/*
+ * Set default values the same as hardware reset values
+ * except for fifo_threshold with is set to 1.
+ */
+static struct tsc_param default_config = {
+	.scanning_period  = 0x5,  /* 1 to 256 */
+	.debounce_timeout = 0x28, /* 0 to 255 */
+	.settling_timeout = 0x7,  /* 0 to 11 */
+	.touch_timeout    = 0xa,  /* 0 to 255 */
+	.average_data     = 5,    /* entry 5 = 32 pts */
+	.fifo_threshold   = 1,    /* 0 to 31 */
+};
+
+static void ts_reg_dump(struct iproc_ts_priv *priv)
+{
+	struct device *dev = &priv->pdev->dev;
+
+	dev_dbg(dev, "regCtl1             = 0x%08x\n",
+				readl(priv->regs + REGCTL1));
+	dev_dbg(dev, "regCtl2             = 0x%08x\n",
+				readl(priv->regs + REGCTL2));
+	dev_dbg(dev, "interrupt_Thres     = 0x%08x\n",
+				readl(priv->regs + INTERRUPT_THRES));
+	dev_dbg(dev, "interrupt_Mask      = 0x%08x\n",
+				readl(priv->regs + INTERRUPT_MASK));
+	dev_dbg(dev, "interrupt_Status    = 0x%08x\n",
+				readl(priv->regs + INTERRUPT_STATUS));
+	dev_dbg(dev, "controller_Status   = 0x%08x\n",
+				readl(priv->regs + CONTROLLER_STATUS));
+	dev_dbg(dev, "FIFO_Data           = 0x%08x\n",
+				readl(priv->regs + FIFO_DATA));
+	dev_dbg(dev, "analog_Control      = 0x%08x\n",
+				readl(priv->regs + ANALOG_CONTROL));
+	dev_dbg(dev, "aux_Data            = 0x%08x\n",
+				readl(priv->regs + AUX_DATA));
+	dev_dbg(dev, "debounce_Cntr_Stat  = 0x%08x\n",
+				readl(priv->regs + DEBOUNCE_CNTR_STAT));
+	dev_dbg(dev, "scan_Cntr_Stat      = 0x%08x\n",
+				readl(priv->regs + SCAN_CNTR_STAT));
+	dev_dbg(dev, "rem_Cntr_Stat       = 0x%08x\n",
+				readl(priv->regs + REM_CNTR_STAT));
+	dev_dbg(dev, "settling_Timer_Stat = 0x%08x\n",
+				readl(priv->regs + SETTLING_TIMER_STAT));
+	dev_dbg(dev, "spare_Reg           = 0x%08x\n",

drivers/input/touchscreen/bcm_iproc_tsc.c line 208

Quoted 10 lines
drivers/input/touchscreen/bcm_iproc_tsc.c new file +10 -0
+				readl(priv->regs + SPARE_REG));
+	dev_dbg(dev, "soft_Bypass_Control = 0x%08x\n",
+				readl(priv->regs + SOFT_BYPASS_CONTROL));
+	dev_dbg(dev, "soft_Bypass_Data    = 0x%08x\n",
+				readl(priv->regs + SOFT_BYPASS_DATA));
+}
+
+static irqreturn_t iproc_touchscreen_interrupt(int irq, void *data)
+{
+	struct platform_device *pdev = (struct platform_device *)data;

No need to cast here.

drivers/input/touchscreen/bcm_iproc_tsc.c line 213

Quoted 5 lines
drivers/input/touchscreen/bcm_iproc_tsc.c new file +5 -0
+	struct iproc_ts_priv *priv;
+	u32 intr_status = 0;
+	u32 raw_coordinate = 0;
+	u16 x = 0;
+	u16 y = 0;

Why do you need all these initialized? It just hides potential problems when variable is used without assigning proper value.

drivers/input/touchscreen/bcm_iproc_tsc.c line 216

Quoted 3 lines
drivers/input/touchscreen/bcm_iproc_tsc.c new file +3 -0
+	int i;
+
+	priv = (struct iproc_ts_priv *)platform_get_drvdata(pdev);

No need to cast here.

Quoted 5 lines
drivers/input/touchscreen/bcm_iproc_tsc.c new file +5 -0
+
+	intr_status = readl(priv->regs + INTERRUPT_STATUS);
+	intr_status &= (TS_PEN_INTR_MASK | TS_FIFO_INTR_MASK);
+	if (intr_status == 0)
+		return IRQ_NONE;

drivers/input/touchscreen/bcm_iproc_tsc.c line 231

Quoted 10 lines
drivers/input/touchscreen/bcm_iproc_tsc.c new file +10 -0
+
+	/* Clear all interrupt status bits, write-1-clear */
+	writel(intr_status, priv->regs + INTERRUPT_STATUS);
+
+	/* Pen up/down */
+	if (intr_status & TS_PEN_INTR_MASK) {
+		if (readl(priv->regs + CONTROLLER_STATUS) & TS_PEN_DOWN) {
+			priv->pen_status = PEN_DOWN_STATUS;
+			input_report_key(priv->idev, BTN_TOUCH,
+				priv->pen_status);

We do not do input_sync() here... But what happens if we do not get TS_FIFO_INTR_MASK in the status? Won't we "lose" the sync?

Quoted 2 lines

I'd prefer you parsed the hardware state fully and then emitted all needed events based on the state.

I'll change this to one input_sync() call for all events.

Quoted 9 lines

drivers/input/touchscreen/bcm_iproc_tsc.c line 236

Quoted 6 lines
drivers/input/touchscreen/bcm_iproc_tsc.c new file +5 -0
+		} else {
+			priv->pen_status = PEN_UP_STATUS;
+			input_report_key(priv->idev, BTN_TOUCH,
+				priv->pen_status);
+			input_sync(priv->idev);

Same here. Can we be reporting coordinates from FIFO even after pen is up?

The h/w doesn't seem to. I couldn't see it generate a pen down without fifo data nor fifo data with pen up. But probably better not to assume it will never. One call to input_sync() as suggested above should fix the problem.

Quoted 316 lines
Quoted 48 lines
drivers/input/touchscreen/bcm_iproc_tsc.c new file +47 -0
+		}
+
+		dev_dbg(&priv->pdev->dev,
+			"pen up-down (%d)\n", priv->pen_status);
+	}
+
+	/* coordinates in FIFO exceed the theshold */
+	if (intr_status & TS_FIFO_INTR_MASK) {
+		for (i = 0; i < priv->cfg_params.fifo_threshold; i++) {
+			raw_coordinate = readl(priv->regs + FIFO_DATA);
+			if (raw_coordinate == INVALID_COORD)
+				continue;
+
+			/*
+			 * The x and y coordinate are 16 bits each
+			 * with the x in the lower 16 bits and y in the
+			 * upper 16 bits.
+			 */
+			x = (raw_coordinate >> X_COORD_SHIFT) &
+				FIFO_DATA_X_Y_MASK;
+			y = (raw_coordinate >> Y_COORD_SHIFT) &
+				FIFO_DATA_X_Y_MASK;
+
+			/* We only want to retain the 12 msb of the 16 */
+			x = (x >> 4) & 0x0FFF;
+			y = (y >> 4) & 0x0FFF;
+
+			/* adjust x y according to lcd tsc mount angle */
+			if (priv->ts_rotation == TS_ROTATION_90) {
+				y = Y_MAX - y;
+			} else if (priv->ts_rotation == TS_ROTATION_180) {
+				x = X_MAX - x;
+				y = Y_MAX - y;
+			} else if (priv->ts_rotation == TS_ROTATION_270) {
+				x = X_MAX - x;
+			}
+
+			input_report_abs(priv->idev, ABS_X, x);
+			input_report_abs(priv->idev, ABS_Y, y);
+			input_sync(priv->idev);
+
+			dev_dbg(&priv->pdev->dev, "xy (0x%x 0x%x)\n", x, y);
+		}
+	}
+
+	return IRQ_HANDLED;
+}

drivers/input/touchscreen/bcm_iproc_tsc.c line 293

Quoted 10 lines
drivers/input/touchscreen/bcm_iproc_tsc.c new file +10 -0
+
+static int iproc_ts_start(struct input_dev *idev)
+{
+	u32 val;
+	int ret;
+	struct iproc_ts_priv *priv;
+
+	priv = input_get_drvdata(idev);
+	if (priv == NULL)
+		return -ENODEV;

How can it be NULL? It is fully controlled by this driver and it should set it up before registering the input device.

Quoted 11 lines
drivers/input/touchscreen/bcm_iproc_tsc.c new file +11 -0
+
+	/* Enable clock */
+	ret = clk_prepare_enable(priv->tsc_clk);
+	if (ret) {
+		dev_err(&priv->pdev->dev, "%s clk_prepare_enable failed %d\n",
+			__func__, ret);
+		return ret;
+	}
+
+	/*
+	 * Interrupt is generated when:

drivers/input/touchscreen/bcm_iproc_tsc.c line 314

Quoted 10 lines
drivers/input/touchscreen/bcm_iproc_tsc.c new file +10 -0
+	 *  FIFO reaches the int_th value, and pen event(up/down)
+	 */
+	val = TS_PEN_INTR_MASK | TS_FIFO_INTR_MASK;
+	writel(val, priv->regs + INTERRUPT_MASK);
+
+	writel(priv->cfg_params.fifo_threshold, priv->regs + INTERRUPT_THRES);
+
+	/* Initialize control reg1 */
+	val = 0;
+	val |= (priv->cfg_params.scanning_period << SCANNING_PERIOD_SHIFT);

Please drop extra parentheses here and elsewhere.

Quoted 27 lines
drivers/input/touchscreen/bcm_iproc_tsc.c new file +27 -0
+	val |= (priv->cfg_params.debounce_timeout << DEBOUNCE_TIMEOUT_SHIFT);
+	val |= (priv->cfg_params.settling_timeout << SETTLING_TIMEOUT_SHIFT);
+	val |= (priv->cfg_params.touch_timeout << TOUCH_TIMEOUT_SHIFT);
+	writel(val, priv->regs + REGCTL1);
+
+	/* Try to clear all interrupt status */
+	val = readl(priv->regs + INTERRUPT_STATUS);
+	val |= (TS_FIFO_INTR_MASK | TS_PEN_INTR_MASK);
+	writel(val, priv->regs + INTERRUPT_STATUS);
+
+	/* Initialize control reg2 */
+	val = readl(priv->regs + REGCTL2);
+	val |= (TS_CONTROLLER_EN_BIT | TS_WIRE_MODE_BIT);
+
+	val &= ~(TS_CONTROLLER_AVGDATA_MASK);
+	val |= (priv->cfg_params.average_data << TS_CONTROLLER_AVGDATA_SHIFT);
+
+	val &= ~(TS_CONTROLLER_PWR_LDO |	/* PWR up LDO */
+		   TS_CONTROLLER_PWR_ADC |	/* PWR up ADC */
+		   TS_CONTROLLER_PWR_BGP |	/* PWR up BGP */
+		   TS_CONTROLLER_PWR_TS);	/* PWR up TS */
+
+	writel(val, priv->regs + REGCTL2);
+
+	ts_reg_dump(priv);
+
+	return 0;

drivers/input/touchscreen/bcm_iproc_tsc.c line 351

Quoted 10 lines
drivers/input/touchscreen/bcm_iproc_tsc.c new file +10 -0
+}
+
+static void iproc_ts_stop(struct input_dev *dev)
+{
+	u32 val;
+	struct iproc_ts_priv *priv;
+
+	priv = input_get_drvdata(dev);
+	if (priv == NULL)
+		return;

Again, no need to check it here.

Quoted 187 lines
drivers/input/touchscreen/bcm_iproc_tsc.c new file +184 -0
+
+	writel(0, priv->regs + INTERRUPT_MASK); /* Disable all interrupts */
+
+	/* Only power down touch screen controller */
+	val = readl(priv->regs + REGCTL2);
+	val |= TS_CONTROLLER_PWR_TS;
+	writel(val, priv->regs + REGCTL2);
+
+	clk_disable(priv->tsc_clk);
+}
+
+static int get_tsc_config(struct device_node *np, struct iproc_ts_priv *priv)
+{
+	u32 val;
+	struct device *dev = &priv->pdev->dev;
+
+	priv->cfg_params = default_config;
+
+	if (of_property_read_u32(np, "scanning_period", &val) >= 0) {
+		if (val < 1 || val > 256) {
+			dev_err(dev, "scanning_period must be [1-256]\n");
+			return -EINVAL;
+		}
+		priv->cfg_params.scanning_period = val;
+	}
+
+	if (of_property_read_u32(np, "debounce_timeout", &val) >= 0) {
+		if (val < 0 || val > 255) {
+			dev_err(dev, "debounce_timeout must be [0-255]\n");
+			return -EINVAL;
+		}
+		priv->cfg_params.debounce_timeout = val;
+	}
+
+	if (of_property_read_u32(np, "settling_timeout", &val) >= 0) {
+		if (val < 0 || val > 11) {
+			dev_err(dev, "settling_timeout must be [0-11]\n");
+			return -EINVAL;
+		}
+		priv->cfg_params.settling_timeout = val;
+	}
+
+	if (of_property_read_u32(np, "touch_timeout", &val) >= 0) {
+		if (val < 0 || val > 255) {
+			dev_err(dev, "touch_timeout must be [0-255]\n");
+			return -EINVAL;
+		}
+		priv->cfg_params.touch_timeout = val;
+	}
+
+	if (of_property_read_u32(np, "average_data", &val) >= 0) {
+		if (val < 0 || val > 8) {
+			dev_err(dev, "average_data must be [0-8]\n");
+			return -EINVAL;
+		}
+		priv->cfg_params.average_data = val;
+	}
+
+	if (of_property_read_u32(np, "fifo_threshold", &val) >= 0) {
+		if (val < 0 || val > 31) {
+			dev_err(dev, "fifo_threshold must be [0-31]\n");
+			return -EINVAL;
+		}
+		priv->cfg_params.fifo_threshold = val;
+	}
+
+	priv->ts_rotation = TS_ROTATION_0;
+	if (of_property_read_u32(np, "ts-rotation", &val) >= 0) {
+		priv->ts_rotation = val;
+		dev_dbg(dev, "ts rotation [%d] degrees\n",
+			90 * priv->ts_rotation);
+	}
+
+	return 0;
+}
+
+static int iproc_ts_probe(struct platform_device *pdev)
+{
+	struct iproc_ts_priv *priv;
+	struct input_dev *idev;
+	struct resource *res;
+	int ret;
+	int irq;
+
+	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	/* touchscreen controller memory mapped regs */
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	priv->regs = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(priv->regs)) {
+		dev_err(&pdev->dev, "unable to map I/O memory\n");
+		return PTR_ERR(priv->regs);
+	}
+
+	priv->tsc_clk = devm_clk_get(&pdev->dev, "tsc_clk");
+	if (IS_ERR(priv->tsc_clk)) {
+		dev_err(&pdev->dev,
+			"%s Failed getting clock tsc_clk\n", __func__);
+		return PTR_ERR(priv->tsc_clk);
+	}
+
+	ret = get_tsc_config(pdev->dev.of_node, priv);
+	if (ret != 0) {
+		dev_err(&pdev->dev, "%s get_tsc_config failed\n", __func__);
+		return ret;
+	}
+
+	idev = devm_input_allocate_device(&pdev->dev);
+	if (!idev) {
+		dev_err(&pdev->dev,
+			"%s Allocate input device failed\n", __func__);
+		return -ENOMEM;
+	}
+
+	priv->idev = idev;
+	priv->pdev = pdev;
+
+	priv->pen_status = PEN_UP_STATUS;
+
+	/* Set input device info  */
+	idev->name = IPROC_TS_NAME;
+	idev->dev.parent = &pdev->dev;
+
+	idev->id.bustype = BUS_HOST;
+	idev->id.vendor = SERIO_UNKNOWN;
+	idev->id.product = 0;
+	idev->id.version = 0;
+
+	idev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+	set_bit(BTN_TOUCH, idev->keybit);
+
+	input_set_abs_params(idev, ABS_X, X_MIN, X_MAX, 0, 0);
+	input_set_abs_params(idev, ABS_Y, Y_MIN, Y_MAX, 0, 0);
+
+	idev->open = iproc_ts_start;
+	idev->close = iproc_ts_stop;
+
+	input_set_drvdata(idev, priv);
+	platform_set_drvdata(pdev, priv);
+
+	/* get interrupt */
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0) {
+		dev_err(&pdev->dev, "%s platform_get_irq failed\n", __func__);
+		return irq;
+	}
+
+	ret = devm_request_irq(&pdev->dev, irq,
+		iproc_touchscreen_interrupt,
+		IRQF_SHARED, IPROC_TS_NAME, pdev);
+	if (ret)
+		return ret;
+
+	ret = input_register_device(priv->idev);
+	if (ret) {
+		dev_err(&pdev->dev,
+			"%s register input device failed %d\n", __func__, ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static const struct of_device_id iproc_ts_of_match[] = {
+	{.compatible = "brcm,iproc-touchscreen", },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, iproc_ts_of_match);
+
+static struct platform_driver iproc_ts_driver = {
+	.probe = iproc_ts_probe,
+	.driver = {
+		.name	= IPROC_TS_NAME,
+		.of_match_table = of_match_ptr(iproc_ts_of_match),
+	},
+};
+
+module_platform_driver(iproc_ts_driver);
+
+MODULE_DESCRIPTION("IPROC Touchscreen driver");
+MODULE_AUTHOR("Broadcom");
+MODULE_LICENSE("GPL v2");
Signature · 1 line
1.7.9.5

Thanks.

#58 lore raw

PATCH v2 2/2 Input: touchscreen-iproc: add device tree bindings

In reply to Jonathan Richardson

Documents the touchscreen device tree binding for Broadcom iProc family of SoCs.

---
 .../input/touchscreen/brcm,iproc-touchscreen.txt   |   70 ++++++++++++++++++++
 1 file changed, 70 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/input/touchscreen/brcm,iproc-touchscreen.txt
Documentation/devicetree/bindings/input/touchscreen/brcm,iproc-touchscreen.txt new file +70 -0
new file mode 100644
index 0000000..eb28822
@@ -0,0 +1,70 @@
+* Broadcom's IPROC Touchscreen Controller
+
+Required properties:
+- compatible: must be "brcm,iproc-touchscreen"
+- reg: physical base address of the controller and length of memory mapped
+  region.
+- clocks:  The clock provided by the SOC to driver the tsc
+- clock-name:  name for the clock
+- interrupts: The touchscreen controller's interrupt
+
+Optional properties:
+- scanning_period: Time between scans. Each step is 1024 us.  Valid 1-256.
+- debounce_timeout: Each step is 512 us.  Valid 0-255
+- settling_timeout: The settling duration (in ms) is the amount of time
+                    the tsc waits to allow the voltage to settle after
+                    turning on the drivers in detection mode.
+                    Valid values: 0-11
+                    0 =  0.008 ms
+                    1 =  0.01 ms
+                    2 =  0.02 ms
+                    3 =  0.04 ms
+                    4 =  0.08 ms
+                    5 =  0.16 ms
+                    6 =  0.32 ms
+                    7 =  0.64 ms
+                    8 =  1.28 ms
+                    9 =  2.56 ms
+                   10 =  5.12 ms
+                   11 = 10.24 ms
+- touch_timeout: The continuous number of scan periods in which touch is
+                not detected before the controller returns to idle state.
+                Valid values 0-255.
+- average_data: Number of data samples which are averaged before a final
+                data point is placed into the FIFO
+                Valid values 0-7
+                0 =   1 sample
+                1 =   2 samples
+                2 =   4 samples
+                3 =   8 samples
+                4 =  16 samples
+                5 =  32 samples
+                6 =  64 samples
+                7 = 128 samples
+- fifo_threshold: Interrupt is generated whenever the number of fifo
+                entries exceeds this value
+                Valid values 0-31
+- ts-rotation: Touch screen controller and display panel orientation angle.
+		0 = Tsc x_min y_min placed at LCD x_min y_min. None
+		1 = Tsc x_min y_max placed at LCD x_min y_min. 90 degrees
+		2 = Tsc x_max y_max placed at LCD x_min y_min. 180 degrees
+		3 = Tsc x_max y_min placed at LCD x_min y_min. 270 degrees
+Example:
+
+	touchscreen: tsc at 0x180A6000 {
+		compatible = "brcm,iproc-touchscreen";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		reg = <0x180A6000 0x40>;
+		clocks = <&adc_clk>;
+		clock-names = "tsc_clk";
+		interrupts = <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>;
+
+		scanning_period = <5>;
+		debounce_timeout = <40>;
+		settling_timeout = <7>;
+		touch_timeout = <10>;
+		average_data = <5>;
+		fifo_threshold = <1>;
+		ts-rotation = <2>;
+	};
Signature · 1 line
1.7.9.5
#59 lore raw

v4 cover Fix bugs in kona pwm driver and pwm core

In reply to a message not in the archive

This patchset fixes a number of bugs in the Broadcom Kona pwm driver. It also fixes a bug in the pwm core where the state was incorrect on failed calls to enable.

Changes from v3:
- Removed setting the pwm set to disabled if enable fails. This is now done in the pwm core.
- Removed previous change in kona_pwmc_config() that returned right away if the state was disabled. The loop needs to execute to ensure that the period and duty cycle are valid. Delaying this check to when the pwm is enabled is incorrect.
- Added comments to clarify code.
- Changed commit messages to more accurately reflect the code changes.

Jonathan Richardson (3):
pwm: kona: Fix incorrect config, disable, and polarity procedures
pwm: kona: Remove setting default smooth type and polarity for all
channels
pwm: core: Set enable state properly on failed call to enable

 drivers/pwm/core.c         |   10 +++-
 drivers/pwm/pwm-bcm-kona.c |  116 ++++++++++++++++++++++++++++++++++++--------
 2 files changed, 104 insertions(+), 22 deletions(-)
Signature · 1 line
1.7.9.5
#60 lore raw

PATCH v4 1/3 pwm: kona: Fix incorrect config, disable, and polarity procedures

The config procedure didn't follow the spec which periodically resulted in failing to enable the output signal. This happened one in ten or twenty attempts. Following the spec and adding a 400ns delay in the appropriate locations resolves this problem.

The disable procedure now also follows the spec. The old disable procedure would result in no change in signal when called.

The polarity procedure no longer applies the settings to change the output signal because it can't be called when the pwm is enabled anyway. The polarity is only updated in the control register. The correct polarity will be applied on enable. The old method of applying changes would result in no signal when the polarity was changed. The new apply_settings function would fix this problem but it isn't required anyway.

---
 drivers/pwm/pwm-bcm-kona.c |   75 +++++++++++++++++++++++++++++++++++---------
 1 file changed, 60 insertions(+), 15 deletions(-)
drivers/pwm/pwm-bcm-kona.c +60 -15
index 02bc048..5ae4bf7 100644
@@ -80,15 +80,19 @@ static void kona_pwmc_apply_settings(struct kona_pwmc *kp, unsigned int chan)
 {
 	unsigned int value = readl(kp->base + PWM_CONTROL_OFFSET);
 
-	/* Clear trigger bit but set smooth bit to maintain old output */
-	value |= 1 << PWM_CONTROL_SMOOTH_SHIFT(chan);
-	value &= ~(1 << PWM_CONTROL_TRIGGER_SHIFT(chan));
-	writel(value, kp->base + PWM_CONTROL_OFFSET);
+	/*
+	 * There must be a min 400ns delay between clearing enable and setting
+	 * it. Failing to do this may result in no PWM signal.
+	 */
+	ndelay(400);
 
 	/* Set trigger bit and clear smooth bit to apply new settings */
 	value &= ~(1 << PWM_CONTROL_SMOOTH_SHIFT(chan));
 	value |= 1 << PWM_CONTROL_TRIGGER_SHIFT(chan);
 	writel(value, kp->base + PWM_CONTROL_OFFSET);
+
+	/* PWMOUT_ENABLE must be held high for at least 400 ns. */
+	ndelay(400);
 }
 
 static int kona_pwmc_config(struct pwm_chip *chip, struct pwm_device *pwm,
@@ -121,20 +125,56 @@ static int kona_pwmc_config(struct pwm_chip *chip, struct pwm_device *pwm,
 		dc = div64_u64(val, div);
 
 		/* If duty_ns or period_ns are not achievable then return */
-		if (pc < PERIOD_COUNT_MIN || dc < DUTY_CYCLE_HIGH_MIN)
+		if (pc < PERIOD_COUNT_MIN) {
+			dev_warn(chip->dev,
+				"%s: pwm[%d]: period=%d is not achievable, pc=%lu, prescale=%lu\n",
+				__func__, chan, period_ns, pc, prescale);
+			return -EINVAL;
+		}
+
+		/* If duty_ns is not achievable then return */
+		if (dc < DUTY_CYCLE_HIGH_MIN) {
+			if (0 != duty_ns) {
+				dev_warn(chip->dev,
+					"%s: pwm[%d]: duty cycle=%d is not achievable, dc=%lu, prescale=%lu\n",
+					__func__, chan, duty_ns, dc, prescale);
+			}
 			return -EINVAL;
+		}
 
 		/* If pc and dc are in bounds, the calculation is done */
 		if (pc <= PERIOD_COUNT_MAX && dc <= DUTY_CYCLE_HIGH_MAX)
 			break;
 
 		/* Otherwise, increase prescale and recalculate pc and dc */
-		if (++prescale > PRESCALE_MAX)
+		if (++prescale > PRESCALE_MAX) {
+			dev_warn(chip->dev,
+				"%s: pwm[%d]: Prescale (=%lu) within max (=%d) for period=%d and duty cycle=%d is not achievable\n",
+				__func__, chan, prescale, PRESCALE_MAX,
+				period_ns, duty_ns);
 			return -EINVAL;
+		}
 	}
 
-	/* If the PWM channel is enabled, write the settings to the HW */
+	dev_dbg(chip->dev, "pwm[%d]: period=%lu, duty_high=%lu, prescale=%lu\n",
+		chan, pc, dc, prescale);
+
+	/*
+	 * Don't apply settings if disabled. The period and duty cycle are
+	 * always calculated above to ensure the new values are
+	 * validated immediately instead of on enable.
+	 */
 	if (test_bit(PWMF_ENABLED, &pwm->flags)) {
+		value = readl(kp->base + PWM_CONTROL_OFFSET);
+
+		/*
+		 * Clear trigger bit but set smooth bit to maintain old
+		 * output.
+		 */
+		value |= 1 << PWM_CONTROL_SMOOTH_SHIFT(chan);
+		value &= ~(1 << PWM_CONTROL_TRIGGER_SHIFT(chan));
+		writel(value, kp->base + PWM_CONTROL_OFFSET);
+
 		value = readl(kp->base + PRESCALE_OFFSET);
 		value &= ~PRESCALE_MASK(chan);
 		value |= prescale << PRESCALE_SHIFT(chan);
@@ -173,11 +213,6 @@ static int kona_pwmc_set_polarity(struct pwm_chip *chip, struct pwm_device *pwm,
 
 	writel(value, kp->base + PWM_CONTROL_OFFSET);
 
-	kona_pwmc_apply_settings(kp, chan);
-
-	/* Wait for waveform to settle before gating off the clock */
-	ndelay(400);
-
 	clk_disable_unprepare(kp->clk);
 
 	return 0;
@@ -207,13 +242,23 @@ static void kona_pwmc_disable(struct pwm_chip *chip, struct pwm_device *pwm)
 {
 	struct kona_pwmc *kp = to_kona_pwmc(chip);
 	unsigned int chan = pwm->hwpwm;
+	unsigned int value = readl(kp->base + PWM_CONTROL_OFFSET);
+
+	/* Set smooth type to 1 and disable */
+	value |= 1 << PWM_CONTROL_SMOOTH_SHIFT(chan);
+	value &= ~(1 << PWM_CONTROL_TRIGGER_SHIFT(chan));
+	writel(value, kp->base + PWM_CONTROL_OFFSET);
 
 	/* Simulate a disable by configuring for zero duty */
 	writel(0, kp->base + DUTY_CYCLE_HIGH_OFFSET(chan));
-	kona_pwmc_apply_settings(kp, chan);
+	writel(0, kp->base + PERIOD_COUNT_OFFSET(chan));
 
-	/* Wait for waveform to settle before gating off the clock */
-	ndelay(400);
+	/* Set prescale to 0 for this channel */
+	value = readl(kp->base + PRESCALE_OFFSET);
+	value &= ~PRESCALE_MASK(chan);
+	writel(value, kp->base + PRESCALE_OFFSET);
+
+	kona_pwmc_apply_settings(kp, chan);
 
 	clk_disable_unprepare(kp->clk);
 }
Signature · 1 line
1.7.9.5
#61 lore raw

PATCH v4 2/3 pwm: kona: Remove setting default smooth type and polarity for all channels

In reply to Jonathan Richardson

Setting the default polarity in probe to normal for all channels caused the speaker pwm channel to click. The polarity does need to be set to normal because the hw default is inversed whereas the pwm framework defaults to normal. If a channel is enabled without setting the polarity then the signal would be inversed while linux reports normal. A check is now done prior to enabling the channel to ensure that the hw polarity matches the desired polarity and is changed if there is a discrepency. This prevents unnecessary settings being applied to unused channels but still ensures the correct polarity to be set.

---
 drivers/pwm/pwm-bcm-kona.c |   41 ++++++++++++++++++++++++++++++++++++-----
 1 file changed, 36 insertions(+), 5 deletions(-)
drivers/pwm/pwm-bcm-kona.c +36 -5
index 5ae4bf7..34d434a 100644
@@ -95,6 +95,32 @@ static void kona_pwmc_apply_settings(struct kona_pwmc *kp, unsigned int chan)
 	ndelay(400);
 }
 
+static void kona_pwmc_check_set_polarity(struct pwm_chip *chip,
+	struct pwm_device *pwm)
+{
+	struct kona_pwmc *kp = to_kona_pwmc(chip);
+	unsigned int chan = pwm->hwpwm;
+	enum pwm_polarity polarity = pwm->polarity;
+	unsigned int hw_pol;
+	unsigned int value = 0;
+
+	value = hw_pol = readl(kp->base + PWM_CONTROL_OFFSET);
+	hw_pol = (hw_pol >> PWM_CONTROL_POLARITY_SHIFT(chan)) & 0x1;
+
+	/*
+	 * If current polarity not the same as h/w then set polarity so that
+	 * they match.
+	 */
+	if (!hw_pol != polarity) {
+		if (polarity == PWM_POLARITY_NORMAL)
+			value |= 1 << PWM_CONTROL_POLARITY_SHIFT(chan);
+		else
+			value &= ~(1 << PWM_CONTROL_POLARITY_SHIFT(chan));
+
+		writel(value, kp->base + PWM_CONTROL_OFFSET);
+	}
+}
+
 static int kona_pwmc_config(struct pwm_chip *chip, struct pwm_device *pwm,
 			    int duty_ns, int period_ns)
 {
@@ -165,6 +191,14 @@ static int kona_pwmc_config(struct pwm_chip *chip, struct pwm_device *pwm,
 	 * validated immediately instead of on enable.
 	 */
 	if (test_bit(PWMF_ENABLED, &pwm->flags)) {
+		/*
+		 * Ensure polarity is set properly. The default value
+		 * for h/w and the PWM framework are different. If a
+		 * channel is enabled without setting the polarity, the
+		 * default value would be inconsistent to the signal.
+		 */
+		kona_pwmc_check_set_polarity(chip, pwm);
+
 		value = readl(kp->base + PWM_CONTROL_OFFSET);
 
 		/*
@@ -311,12 +345,9 @@ static int kona_pwmc_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	/* Set smooth mode, push/pull, and normal polarity for all channels */
-	for (chan = 0; chan < kp->chip.npwm; chan++) {
-		value |= (1 << PWM_CONTROL_SMOOTH_SHIFT(chan));
+	/* Set push/pull for all channels */
+	for (chan = 0; chan < kp->chip.npwm; chan++)
 		value |= (1 << PWM_CONTROL_TYPE_SHIFT(chan));
-		value |= (1 << PWM_CONTROL_POLARITY_SHIFT(chan));
-	}
 
 	writel(value, kp->base + PWM_CONTROL_OFFSET);
 
Signature · 1 line
1.7.9.5
#62 lore raw

Re: [PATCH v4 2/3] pwm: kona: Remove setting default smooth type and polarity for all channels

Quoted 9 lines · Jonathan Richardson

Setting the default polarity in probe to normal for all channels caused the speaker pwm channel to click. The polarity does need to be set to normal because the hw default is inversed whereas the pwm framework defaults to normal. If a channel is enabled without setting the polarity then the signal would be inversed while linux reports normal. A check is now done prior to enabling the channel to ensure that the hw polarity matches the desired polarity and is changed if there is a discrepency. This prevents unnecessary settings being applied to unused channels but still ensures the correct polarity to be set.

A more direct solution that avoids the potentially undesirable consequences of delaying when polarity changes are written to hardware would be to update the PWM framework to allow for the registration of chips with inversed default polarity.

I will post a patch for your review.

#63 lore raw

Re: [PATCH v4 2/3] pwm: kona: Remove setting default smooth type and polarity for all channels

Quoted 12 lines · Tim Kryger
Quoted 9 lines · Jonathan Richardson

Setting the default polarity in probe to normal for all channels caused the speaker pwm channel to click. The polarity does need to be set to normal because the hw default is inversed whereas the pwm framework defaults to normal. If a channel is enabled without setting the polarity then the signal would be inversed while linux reports normal. A check is now done prior to enabling the channel to ensure that the hw polarity matches the desired polarity and is changed if there is a discrepency. This prevents unnecessary settings being applied to unused channels but still ensures the correct polarity to be set.

Quoted 6 lines

A more direct solution that avoids the potentially undesirable consequences of delaying when polarity changes are written to hardware would be to update the PWM framework to allow for the registration of chips with inversed default polarity.

I will post a patch for your review.

Please see: https://lkml.org/lkml/2015/1/4/199

#64 lore raw

PATCH v4 3/3 pwm: core: Set enable state properly on failed call to enable

In reply to Jonathan Richardson

The pwm_enable function didn't clear the enabled bit if a call to a clients enable function returned an error. The result was that the state of the pwm core was wrong. Clearing the bit when enable returns an error ensures the state is properly set.

---
 drivers/pwm/core.c |   10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)
drivers/pwm/core.c +8 -2
index 966497d..641f6ec 100644
@@ -457,8 +457,14 @@ EXPORT_SYMBOL_GPL(pwm_set_polarity);
  */
 int pwm_enable(struct pwm_device *pwm)
 {
-	if (pwm && !test_and_set_bit(PWMF_ENABLED, &pwm->flags))
-		return pwm->chip->ops->enable(pwm->chip, pwm);
+	int err;
+
+	if (pwm && !test_and_set_bit(PWMF_ENABLED, &pwm->flags)) {
+		err = pwm->chip->ops->enable(pwm->chip, pwm);
+		if (err)
+			clear_bit(PWMF_ENABLED, &pwm->flags);
+		return err;
+	}
 
 	return pwm ? 0 : -EINVAL;
 }
Signature · 1 line
1.7.9.5
#65 lore raw

v5 cover Fix bugs in kona pwm driver and pwm core

In reply to a message not in the archive

This patchset fixes a number of bugs in the Broadcom Kona pwm driver. It also fixes a bug in the pwm core where the state was incorrect on failed calls to enable.

Changes from v4:
- Rebased to Tim Kryger's patch that adds support in pwm core to add driver with inversed polarity.
- Removed patch 2 that resolved difference between hardware default polarity and pwm framework default polarity. The default polarity is set properly now when the pwm driver is registered with the pwm framework.

Jonathan Richardson (2):
pwm: kona: Fix incorrect config, disable, and polarity procedures
pwm: core: Set enable state properly on failed call to enable

 drivers/pwm/core.c         |   10 ++++--
 drivers/pwm/pwm-bcm-kona.c |   75 +++++++++++++++++++++++++++++++++++---------
 2 files changed, 68 insertions(+), 17 deletions(-)
Signature · 1 line
1.7.9.5
#66 lore raw

PATCH v5 1/2 pwm: kona: Fix incorrect config, disable, and polarity procedures

The config procedure didn't follow the spec which periodically resulted in failing to enable the output signal. This happened one in ten or twenty attempts. Following the spec and adding a 400ns delay in the appropriate locations resolves this problem.

The disable procedure now also follows the spec. The old disable procedure would result in no change in signal when called.

The polarity procedure no longer applies the settings to change the output signal because it can't be called when the pwm is enabled anyway. The polarity is only updated in the control register. The correct polarity will be applied on enable. The old method of applying changes would result in no signal when the polarity was changed. The new apply_settings function would fix this problem but it isn't required anyway.

---
 drivers/pwm/pwm-bcm-kona.c |   75 +++++++++++++++++++++++++++++++++++---------
 1 file changed, 60 insertions(+), 15 deletions(-)
drivers/pwm/pwm-bcm-kona.c +60 -15
index 32b3ec6..8a1dfba 100644
@@ -80,15 +80,19 @@ static void kona_pwmc_apply_settings(struct kona_pwmc *kp, unsigned int chan)
 {
 	unsigned int value = readl(kp->base + PWM_CONTROL_OFFSET);
 
-	/* Clear trigger bit but set smooth bit to maintain old output */
-	value |= 1 << PWM_CONTROL_SMOOTH_SHIFT(chan);
-	value &= ~(1 << PWM_CONTROL_TRIGGER_SHIFT(chan));
-	writel(value, kp->base + PWM_CONTROL_OFFSET);
+	/*
+	 * There must be a min 400ns delay between clearing enable and setting
+	 * it. Failing to do this may result in no PWM signal.
+	 */
+	ndelay(400);
 
 	/* Set trigger bit and clear smooth bit to apply new settings */
 	value &= ~(1 << PWM_CONTROL_SMOOTH_SHIFT(chan));
 	value |= 1 << PWM_CONTROL_TRIGGER_SHIFT(chan);
 	writel(value, kp->base + PWM_CONTROL_OFFSET);
+
+	/* PWMOUT_ENABLE must be held high for at least 400 ns. */
+	ndelay(400);
 }
 
 static int kona_pwmc_config(struct pwm_chip *chip, struct pwm_device *pwm,
@@ -121,20 +125,56 @@ static int kona_pwmc_config(struct pwm_chip *chip, struct pwm_device *pwm,
 		dc = div64_u64(val, div);
 
 		/* If duty_ns or period_ns are not achievable then return */
-		if (pc < PERIOD_COUNT_MIN || dc < DUTY_CYCLE_HIGH_MIN)
+		if (pc < PERIOD_COUNT_MIN) {
+			dev_warn(chip->dev,
+				"%s: pwm[%d]: period=%d is not achievable, pc=%lu, prescale=%lu\n",
+				__func__, chan, period_ns, pc, prescale);
+			return -EINVAL;
+		}
+
+		/* If duty_ns is not achievable then return */
+		if (dc < DUTY_CYCLE_HIGH_MIN) {
+			if (0 != duty_ns) {
+				dev_warn(chip->dev,
+					"%s: pwm[%d]: duty cycle=%d is not achievable, dc=%lu, prescale=%lu\n",
+					__func__, chan, duty_ns, dc, prescale);
+			}
 			return -EINVAL;
+		}
 
 		/* If pc and dc are in bounds, the calculation is done */
 		if (pc <= PERIOD_COUNT_MAX && dc <= DUTY_CYCLE_HIGH_MAX)
 			break;
 
 		/* Otherwise, increase prescale and recalculate pc and dc */
-		if (++prescale > PRESCALE_MAX)
+		if (++prescale > PRESCALE_MAX) {
+			dev_warn(chip->dev,
+				"%s: pwm[%d]: Prescale (=%lu) within max (=%d) for period=%d and duty cycle=%d is not achievable\n",
+				__func__, chan, prescale, PRESCALE_MAX,
+				period_ns, duty_ns);
 			return -EINVAL;
+		}
 	}
 
-	/* If the PWM channel is enabled, write the settings to the HW */
+	dev_dbg(chip->dev, "pwm[%d]: period=%lu, duty_high=%lu, prescale=%lu\n",
+		chan, pc, dc, prescale);
+
+	/*
+	 * Don't apply settings if disabled. The period and duty cycle are
+	 * always calculated above to ensure the new values are
+	 * validated immediately instead of on enable.
+	 */
 	if (test_bit(PWMF_ENABLED, &pwm->flags)) {
+		value = readl(kp->base + PWM_CONTROL_OFFSET);
+
+		/*
+		 * Clear trigger bit but set smooth bit to maintain old
+		 * output.
+		 */
+		value |= 1 << PWM_CONTROL_SMOOTH_SHIFT(chan);
+		value &= ~(1 << PWM_CONTROL_TRIGGER_SHIFT(chan));
+		writel(value, kp->base + PWM_CONTROL_OFFSET);
+
 		value = readl(kp->base + PRESCALE_OFFSET);
 		value &= ~PRESCALE_MASK(chan);
 		value |= prescale << PRESCALE_SHIFT(chan);
@@ -173,11 +213,6 @@ static int kona_pwmc_set_polarity(struct pwm_chip *chip, struct pwm_device *pwm,
 
 	writel(value, kp->base + PWM_CONTROL_OFFSET);
 
-	kona_pwmc_apply_settings(kp, chan);
-
-	/* Wait for waveform to settle before gating off the clock */
-	ndelay(400);
-
 	clk_disable_unprepare(kp->clk);
 
 	return 0;
@@ -207,13 +242,23 @@ static void kona_pwmc_disable(struct pwm_chip *chip, struct pwm_device *pwm)
 {
 	struct kona_pwmc *kp = to_kona_pwmc(chip);
 	unsigned int chan = pwm->hwpwm;
+	unsigned int value = readl(kp->base + PWM_CONTROL_OFFSET);
+
+	/* Set smooth type to 1 and disable */
+	value |= 1 << PWM_CONTROL_SMOOTH_SHIFT(chan);
+	value &= ~(1 << PWM_CONTROL_TRIGGER_SHIFT(chan));
+	writel(value, kp->base + PWM_CONTROL_OFFSET);
 
 	/* Simulate a disable by configuring for zero duty */
 	writel(0, kp->base + DUTY_CYCLE_HIGH_OFFSET(chan));
-	kona_pwmc_apply_settings(kp, chan);
+	writel(0, kp->base + PERIOD_COUNT_OFFSET(chan));
 
-	/* Wait for waveform to settle before gating off the clock */
-	ndelay(400);
+	/* Set prescale to 0 for this channel */
+	value = readl(kp->base + PRESCALE_OFFSET);
+	value &= ~PRESCALE_MASK(chan);
+	writel(value, kp->base + PRESCALE_OFFSET);
+
+	kona_pwmc_apply_settings(kp, chan);
 
 	clk_disable_unprepare(kp->clk);
 }
Signature · 1 line
1.7.9.5
#67 lore raw

PATCH v5 2/2 pwm: core: Set enable state properly on failed call to enable

In reply to Jonathan Richardson

The pwm_enable function didn't clear the enabled bit if a call to a clients enable function returned an error. The result was that the state of the pwm core was wrong. Clearing the bit when enable returns an error ensures the state is properly set.

---
 drivers/pwm/core.c |   10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)
drivers/pwm/core.c +8 -2
index f28c4ce..c33e24f 100644
@@ -477,8 +477,14 @@ EXPORT_SYMBOL_GPL(pwm_set_polarity);
  */
 int pwm_enable(struct pwm_device *pwm)
 {
-	if (pwm && !test_and_set_bit(PWMF_ENABLED, &pwm->flags))
-		return pwm->chip->ops->enable(pwm->chip, pwm);
+	int err;
+
+	if (pwm && !test_and_set_bit(PWMF_ENABLED, &pwm->flags)) {
+		err = pwm->chip->ops->enable(pwm->chip, pwm);
+		if (err)
+			clear_bit(PWMF_ENABLED, &pwm->flags);
+		return err;
+	}
 
 	return pwm ? 0 : -EINVAL;
 }
Signature · 1 line
1.7.9.5
maintainer Reviewed-by on v5 2/2
#68 lore raw

Re: [PATCH v5 2/2] pwm: core: Set enable state properly on failed call to enable

Quoted 21 lines · Jonathan Richardson

The pwm_enable function didn't clear the enabled bit if a call to a clients enable function returned an error. The result was that the state of the pwm core was wrong. Clearing the bit when enable returns an error ensures the state is properly set.

---
 drivers/pwm/core.c |   10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)
drivers/pwm/core.c +0 -2
index f28c4ce..c33e24f 100644
@@ -477,8 +477,14 @@ EXPORT_SYMBOL_GPL(pwm_set_polarity);
  */
 int pwm_enable(struct pwm_device *pwm)
 {
-	if (pwm && !test_and_set_bit(PWMF_ENABLED, &pwm->flags))
-		return pwm->chip->ops->enable(pwm->chip, pwm);

drivers/pwm/core.c EXPORT_SYMBOL_GPL(pwm_set_polarity); · line 489

Quoted 10 lines
drivers/pwm/core.c +8 -0
+	int err;
+
+	if (pwm && !test_and_set_bit(PWMF_ENABLED, &pwm->flags)) {
+		err = pwm->chip->ops->enable(pwm->chip, pwm);
+		if (err)
+			clear_bit(PWMF_ENABLED, &pwm->flags);
+		return err;
+	}
 
 	return pwm ? 0 : -EINVAL;

Seems fine in principle, but somewhat messy. Can we do the following:

int pwm_enable(struct pwm_device *pwm)

{
	int err;

	if (!pwm)
		return -EINVAL;

	if (!test_and_set_bit(PWMF_ENABLED, &pwm->flags)) {
		err = pwm->chip->ops->enable(pwm->chip, pwm);
		if (err) {
			clear_bit(PWMF_ENABLED, &pwm->flags);
			return err;
		}
	}

	return 0;
}

Otherwise:

Thanks.

Signature · 1 line
Dmitry
#69 lore raw

cover Enable Broadcom Cygnus BCM958305K

In reply to a message not in the archive

This patchset adds a DTS file to enable the BCM58305 Wireless Audio reference design based on Cygnus. It will be kept up to date as Cygnus drivers are accepted into the mainline.

Jonathan Richardson (1):
ARM: dts: Enable Broadcom Cygnus BCM958305K

 arch/arm/boot/dts/Makefile       |    3 ++-
 arch/arm/boot/dts/bcm958305k.dts |   53 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 55 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/boot/dts/bcm958305k.dts
Signature · 1 line
1.7.9.5
#70 lore raw

PATCH 1/1 ARM: dts: Enable Broadcom Cygnus BCM958305K

DT file to enable the Wireless Audio reference design based on the BCM58305.

---
 arch/arm/boot/dts/Makefile       |    3 ++-
 arch/arm/boot/dts/bcm958305k.dts |   53 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 55 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/boot/dts/bcm958305k.dts
arch/arm/boot/dts/Makefile +2 -1
index 91bd5bd..24b6084 100644
@@ -64,7 +64,8 @@ dtb-$(CONFIG_ARCH_BCM_5301X) += \
 dtb-$(CONFIG_ARCH_BCM_63XX) += bcm963138dvt.dtb
 dtb-$(CONFIG_ARCH_BCM_CYGNUS) += bcm911360_entphn.dtb \
 	bcm911360k.dtb \
-	bcm958300k.dtb
+	bcm958300k.dtb \
+	bcm958305k.dtb
 dtb-$(CONFIG_ARCH_BCM_MOBILE) += bcm28155-ap.dtb \
 	bcm21664-garnet.dtb
 dtb-$(CONFIG_ARCH_BERLIN) += \
arch/arm/boot/dts/bcm958305k.dts new file +53 -0

53 lines not on this page · raw message

Signature · 1 line
1.7.9.5
#71 lore raw

cover Synopsis 8250 serial port driver fix

In reply to a message not in the archive

Hi,

This patchset fixes a bug in the Synopsis 8250 serial driver which causes the driver to hang. The bug occurs on simple 2 wire serial ports when modem control signalling has been enabled. It can be reproduced from user space by enabling modem control signals (stty -clocal), then opening a serial port and polling for data available to read with a timeout. A properly implemented driver will ignore the control signals and the call to poll will return. The current version of the driver hangs forever on the call to poll despite the timeout.

Jon

Desmond Liu (1):
serial: 8250_dw: Fix get_mctrl behaviour

 .../bindings/serial/snps-dw-apb-uart.txt           |    7 ++++
 drivers/tty/serial/8250/8250_dw.c                  |   41 ++++++++++++++++++++
 2 files changed, 48 insertions(+)
Signature · 1 line
1.7.9.5
#72 lore raw

PATCH 1/1 serial: 8250_dw: Fix get_mctrl behaviour

Fixed behaviour of get_mctrl() serial driver function as documented in:
https://www.kernel.org/doc/Documentation/serial/driver

Added device-tree property 'msr-override' specific to the Synopsis 8250 DesignWare UART driver. Allows one to force Data Carrier Detect, Clear To Send, and Data Set Ready signals to permanently be reported as active. The Ring indicator can be forced to be reported as inactive.

It is possible that if modem control signalling is enabled on a port that doesn't have these pins (e.g. - a simple two wire Tx/Rx port), the driver can hang indefinitely waiting for the state to change. The new DT properties allow the driver to ignore the state of these pins on serial ports that don't support them, as recommended in the kernel documentation.

---
 .../bindings/serial/snps-dw-apb-uart.txt           |    7 ++++
 drivers/tty/serial/8250/8250_dw.c                  |   41 ++++++++++++++++++++
 2 files changed, 48 insertions(+)
Documentation/devicetree/bindings/serial/snps-dw-apb-uart.txt +7 -0
index 7f76214..010e52b 100644
@@ -21,6 +21,12 @@ Optional properties:
 - reg-io-width : the size (in bytes) of the IO accesses that should be
   performed on the device.  If this property is not present then single byte
   accesses are used.
+- msr-override : array of strings to be used to override the individual
+  modem status signals for DCD, DSR, CTS, and RI.  If the property is not
+  present, the individual signals are obtained from the modem status register.
+  Strings accepted are "dcd", "dsr", "cts", and "ri". If "dcd", "dsr", or
+  "cts" are present, these signals will always be reported as active. If
+  "ri" is present, this signal will always be reported as inactive.
 
 Example:
 
@@ -31,6 +37,7 @@ Example:
 		interrupts = <10>;
 		reg-shift = <2>;
 		reg-io-width = <4>;
+		msr-override = "dcd", "dsr", cts", "ri"
 	};
 
 Example with one clock:
drivers/tty/serial/8250/8250_dw.c +41 -0

65 lines not on this page · raw message

Signature · 1 line
1.7.9.5
maintainer
#73 lore raw

Re: [PATCH 1/1] serial: 8250_dw: Fix get_mctrl behaviour

Documentation/devicetree/bindings/serial/snps-dw-apb-uart.txt Optional properties: · line 29

Quoted 7 lines · On Wednesday 25 February 2015 11:04:16 Jonathan Richardson wrote:

+- msr-override : array of strings to be used to override the individual

Documentation/devicetree/bindings/serial/snps-dw-apb-uart.txt +5 -0
+  modem status signals for DCD, DSR, CTS, and RI.  If the property is not
+  present, the individual signals are obtained from the modem status register.
+  Strings accepted are "dcd", "dsr", "cts", and "ri". If "dcd", "dsr", or
+  "cts" are present, these signals will always be reported as active. If
+  "ri" is present, this signal will always be reported as inactive.

Did you copy this definition from another driver? If not, we should try to come up with a more natural way to do it. How about defining four boolean properties instead, like

dcd-override
dsr-override
cts-override
ri-override

Simplifies the parser and the binding.

Arnd

#74 lore raw

Re: [PATCH 1/1] serial: 8250_dw: Fix get_mctrl behaviour

Hi Arnd,

Quoted 13 lines · Arnd Bergmann

Documentation/devicetree/bindings/serial/snps-dw-apb-uart.txt Optional properties: · line 29

Quoted 7 lines · On Wednesday 25 February 2015 11:04:16 Jonathan Richardson wrote:

+- msr-override : array of strings to be used to override the individual

Documentation/devicetree/bindings/serial/snps-dw-apb-uart.txt +5 -0
+  modem status signals for DCD, DSR, CTS, and RI.  If the property is not
+  present, the individual signals are obtained from the modem status register.
+  Strings accepted are "dcd", "dsr", "cts", and "ri". If "dcd", "dsr", or
+  "cts" are present, these signals will always be reported as active. If
+  "ri" is present, this signal will always be reported as inactive.

Did you copy this definition from another driver? If not, we should try to come up with a more natural way to do it. How about defining four boolean properties instead, like

Quoted 6 lines

dcd-override
dsr-override
cts-override
ri-override

Simplifies the parser and the binding.

I didn't see anything similar in another driver. I agree with the bools instead of strings. Did you want to keep these in the Synopsis driver for now or were you thinking of putting them somewhere that they could be re-used?

Thanks.

Quoted 3 lines

Arnd

maintainer
#75 lore raw

Re: [PATCH 1/1] serial: 8250_dw: Fix get_mctrl behaviour

Quoted 19 lines · On Wednesday 25 February 2015 12:00:15 Jonathan Richardson wrote:
Quoted 18 lines · Arnd Bergmann

Documentation/devicetree/bindings/serial/snps-dw-apb-uart.txt Optional properties: · line 29

Quoted 7 lines · On Wednesday 25 February 2015 11:04:16 Jonathan Richardson wrote:

+- msr-override : array of strings to be used to override the individual

Documentation/devicetree/bindings/serial/snps-dw-apb-uart.txt +5 -0
+  modem status signals for DCD, DSR, CTS, and RI.  If the property is not
+  present, the individual signals are obtained from the modem status register.
+  Strings accepted are "dcd", "dsr", "cts", and "ri". If "dcd", "dsr", or
+  "cts" are present, these signals will always be reported as active. If
+  "ri" is present, this signal will always be reported as inactive.

Did you copy this definition from another driver? If not, we should try to come up with a more natural way to do it. How about defining four boolean properties instead, like

dcd-override
dsr-override
cts-override
ri-override

Quoted 6 lines
Quoted 1 line

Simplifies the parser and the binding.

I didn't see anything similar in another driver. I agree with the bools instead of strings. Did you want to keep these in the Synopsis driver for now or were you thinking of putting them somewhere that they could be re-used?

I'm fine with it either way. Unless someone else has an opinion on the matter, feel free to pick what makes sense to you.

Arnd

#76 lore raw

v2 cover Synopsis 8250 serial port driver fix

In reply to a message not in the archive

Hi,

This patchset fixes a bug in the Synopsis 8250 serial driver which causes the driver to hang. The bug occurs on simple 2 wire serial ports when modem control signalling has been enabled. It can be reproduced from user space by enabling modem control signals (stty -clocal), then opening a serial port and polling for data available to read with a timeout. A properly implemented driver will ignore the control signals and the call to poll will return. The current version of the driver hangs forever on the call to poll despite the timeout.

Jon

Changes from v1:
- Changed DT properties from strings to booleans as suggested by Arnd. Documentation updated accordingly.

Desmond Liu (1):
serial: 8250_dw: Fix get_mctrl behaviour

 .../bindings/serial/snps-dw-apb-uart.txt           |   16 ++++++++++
 drivers/tty/serial/8250/8250_dw.c                  |   32 ++++++++++++++++++++
 2 files changed, 48 insertions(+)
Signature · 1 line
1.7.9.5
#77 lore raw

PATCH v2 1/1 serial: 8250_dw: Fix get_mctrl behaviour

From: Desmond Liu <[email protected]>

Fixed behaviour of get_mctrl() serial driver function as documented in:
https://www.kernel.org/doc/Documentation/serial/driver

Added device-tree properties 'dcd-override', 'dsr-override', 'cts-override', and 'ri-override' specific to the Synopsis 8250 DesignWare UART driver. Allows one to force Data Carrier Detect, Clear To Send, and Data Set Ready signals to permanently be reported as active. The Ring indicator can be forced to be reported as inactive.

It is possible that if modem control signalling is enabled on a port that doesn't have these pins (e.g. - a simple two wire Tx/Rx port), the driver can hang indefinitely waiting for the state to change. The new DT properties allow the driver to ignore the state of these pins on serial ports that don't support them, as recommended in the kernel documentation.

---
 .../bindings/serial/snps-dw-apb-uart.txt           |   16 ++++++++++
 drivers/tty/serial/8250/8250_dw.c                  |   32 ++++++++++++++++++++
 2 files changed, 48 insertions(+)
Documentation/devicetree/bindings/serial/snps-dw-apb-uart.txt +16 -0
index 7f76214..289c40e 100644
@@ -21,6 +21,18 @@ Optional properties:
 - reg-io-width : the size (in bytes) of the IO accesses that should be
   performed on the device.  If this property is not present then single byte
   accesses are used.
+- dcd-override : Override the DCD modem status signal. This signal will always
+  be reported as active instead of being obtained from the modem status
+  register. Define this if your serial port does not use this pin.
+- dsr-override : Override the DTS modem status signal. This signal will always
+  be reported as active instead of being obtained from the modem status
+  register. Define this if your serial port does not use this pin.
+- cts-override : Override the CTS modem status signal. This signal will always
+  be reported as active instead of being obtained from the modem status
+  register. Define this if your serial port does not use this pin.
+- ri-override : Override the RI modem status signal. This signal will always be
+  reported as inactive instead of being obtained from the modem status register.
+  Define this if your serial port does not use this pin.
 
 Example:
 
@@ -31,6 +43,10 @@ Example:
 		interrupts = <10>;
 		reg-shift = <2>;
 		reg-io-width = <4>;
+		dcd-override;
+		dsr-override;
+		cts-override;
+		ri-override;
 	};
 
 Example with one clock:
drivers/tty/serial/8250/8250_dw.c +32 -0
index 555de07..1f1d2e6 100644
@@ -59,6 +59,8 @@ struct dw8250_data {
 	u8			usr_reg;
 	int			last_mcr;
 	int			line;
+	int			msr_mask_on;
+	int			msr_mask_off;
 	struct clk		*clk;
 	struct clk		*pclk;
 	struct reset_control	*rst;
@@ -81,6 +83,12 @@ static inline int dw8250_modify_msr(struct uart_port *p, int offset, int value)
 		value &= ~UART_MSR_DCTS;
 	}
 
+	/* Override any modem control signals if needed */
+	if (offset == UART_MSR) {
+		value |= d->msr_mask_on;
+		value &= ~d->msr_mask_off;
+	}
+
 	return value;
 }
 
@@ -334,6 +342,30 @@ static int dw8250_probe_of(struct uart_port *p,
 	if (id >= 0)
 		p->line = id;
 
+	if (of_property_read_bool(np, "dcd-override")) {
+		/* Always report DCD as active */
+		data->msr_mask_on |= UART_MSR_DCD;
+		data->msr_mask_off |= UART_MSR_DDCD;
+	}
+
+	if (of_property_read_bool(np, "dsr-override")) {
+		/* Always report DSR as active */
+		data->msr_mask_on |= UART_MSR_DSR;
+		data->msr_mask_off |= UART_MSR_DDSR;
+	}
+
+	if (of_property_read_bool(np, "cts-override")) {
+		/* Always report DSR as active */
+		data->msr_mask_on |= UART_MSR_DSR;
+		data->msr_mask_off |= UART_MSR_DDSR;
+	}
+
+	if (of_property_read_bool(np, "ri-override")) {
+		/* Always report Ring indicator as inactive */
+		data->msr_mask_off |= UART_MSR_RI;
+		data->msr_mask_off |= UART_MSR_TERI;
+	}
+
 	/* clock got configured through clk api, all done */
 	if (p->uartclk)
 		return 0;
Signature · 1 line
1.7.9.5
#78 lore raw

Re: [PATCH v2 1/1] serial: 8250_dw: Fix get_mctrl behaviour

Quoted 16 lines · Jonathan Richardson
drivers/tty/serial/8250/8250_dw.c +12 -0
@@ -334,6 +342,30 @@ static int dw8250_probe_of(struct uart_port *p,
        if (id >= 0)
                p->line = id;
 
+       if (of_property_read_bool(np, "dcd-override")) {
+               /* Always report DCD as active */
+               data->msr_mask_on |= UART_MSR_DCD;
+               data->msr_mask_off |= UART_MSR_DDCD;
+       }
+
+       if (of_property_read_bool(np, "dsr-override")) {
+               /* Always report DSR as active */
+               data->msr_mask_on |= UART_MSR_DSR;
+               data->msr_mask_off |= UART_MSR_DDSR;
+       }
+

drivers/tty/serial/8250/8250_dw.c static int dw8250_probe_of(struct uart_port *p, · line 366

Quoted 10 lines
drivers/tty/serial/8250/8250_dw.c +10 -0
+       if (of_property_read_bool(np, "cts-override")) {
+               /* Always report DSR as active */
+               data->msr_mask_on |= UART_MSR_DSR;
+               data->msr_mask_off |= UART_MSR_DDSR;
+       }
+
+       if (of_property_read_bool(np, "ri-override")) {
+               /* Always report Ring indicator as inactive */
+               data->msr_mask_off |= UART_MSR_RI;
+               data->msr_mask_off |= UART_MSR_TERI;

This looks like a typo. Should the 1st line be data->msr_mask_on by any chance?

Thanks,
Dmitry

A message that is not in the archive (sent off-list or not yet received): CAE_wzQ-43+oGAmyJ_cgso1XfnCYFGVczPvePG++x=povcAPOdA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org

#80 lore raw

Re: [PATCH v2 1/1] serial: 8250_dw: Fix get_mctrl behaviour

Quoted 22 lines · Dmitry Torokhov
Quoted 20 lines · Jonathan Richardson
drivers/tty/serial/8250/8250_dw.c +16 -0
@@ -334,6 +342,30 @@ static int dw8250_probe_of(struct uart_port *p,
        if (id >= 0)
                p->line = id;
 
+       if (of_property_read_bool(np, "dcd-override")) {
+               /* Always report DCD as active */
+               data->msr_mask_on |= UART_MSR_DCD;
+               data->msr_mask_off |= UART_MSR_DDCD;
+       }
+
+       if (of_property_read_bool(np, "dsr-override")) {
+               /* Always report DSR as active */
+               data->msr_mask_on |= UART_MSR_DSR;
+               data->msr_mask_off |= UART_MSR_DDSR;
+       }
+
+       if (of_property_read_bool(np, "cts-override")) {
+               /* Always report DSR as active */
+               data->msr_mask_on |= UART_MSR_DSR;
+               data->msr_mask_off |= UART_MSR_DDSR;
Quoted 8 lines

drivers/tty/serial/8250/8250_dw.c static int dw8250_probe_of(struct uart_port *p, · line 366

Quoted 6 lines
drivers/tty/serial/8250/8250_dw.c +6 -0
+       }
+
+       if (of_property_read_bool(np, "ri-override")) {
+               /* Always report Ring indicator as inactive */
+               data->msr_mask_off |= UART_MSR_RI;
+               data->msr_mask_off |= UART_MSR_TERI;

This looks like a typo. Should the 1st line be data->msr_mask_on by any chance?

I think the code is correct. The signals other than ri need to be reported as active (masked on) if specified, but ri needs to be inactive (masked off) unlike the other 3. This is stated in the kernel docs mentioned in the commit. ri behaves differently than the others.

Quoted 9 lines

Thanks,
Dmitry
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

#81 lore raw

cover Enable Broadcom Cygnus BCM958305K

In reply to a message not in the archive

This patchset adds a DTS file to enable the BCM58305 Wireless Audio reference design based on Cygnus. It will be kept up to date as Cygnus drivers are accepted into the mainline.

Jonathan Richardson (1):
ARM: dts: Enable Broadcom Cygnus BCM958305K

 arch/arm/boot/dts/Makefile       |    3 ++-
 arch/arm/boot/dts/bcm958305k.dts |   53 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 55 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/boot/dts/bcm958305k.dts
Signature · 1 line
1.7.9.5
#82 lore raw

PATCH RESEND 1/1 ARM: dts: Enable Broadcom Cygnus BCM958305K

DT file to enable the Wireless Audio reference design based on the BCM58305.

---
 arch/arm/boot/dts/Makefile       |    3 ++-
 arch/arm/boot/dts/bcm958305k.dts |   53 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 55 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/boot/dts/bcm958305k.dts
arch/arm/boot/dts/Makefile +2 -1
index 91bd5bd..24b6084 100644
@@ -64,7 +64,8 @@ dtb-$(CONFIG_ARCH_BCM_5301X) += \
 dtb-$(CONFIG_ARCH_BCM_63XX) += bcm963138dvt.dtb
 dtb-$(CONFIG_ARCH_BCM_CYGNUS) += bcm911360_entphn.dtb \
 	bcm911360k.dtb \
-	bcm958300k.dtb
+	bcm958300k.dtb \
+	bcm958305k.dtb
 dtb-$(CONFIG_ARCH_BCM_MOBILE) += bcm28155-ap.dtb \
 	bcm21664-garnet.dtb
 dtb-$(CONFIG_ARCH_BERLIN) += \
arch/arm/boot/dts/bcm958305k.dts new file +53 -0

53 lines not on this page · raw message

Signature · 1 line
1.7.9.5
#83 lore raw

Re: [PATCH RESEND 1/1] ARM: dts: Enable Broadcom Cygnus BCM958305K

Quoted 7 lines · Jonathan Richardson

DT file to enable the Wireless Audio reference design based on the BCM58305.

Applied to devicetree/next at github.com/stblinux, thanks!

Signature · 1 line
Florian
#84 lore raw

v3 cover Add support for Broadcom iProc touchscreen

In reply to a message not in the archive

This patchset contains initial support for the touchscreen on the Broadcom iProc family of SoCs. This driver has been validated with Cygnus and is expected to work on other iProc family of SoCs that use the same touchscreen controller.

Changes from v2:
- Misc style changes.
- Removed assumptions about interrupts generated in ISR. It now emits all events and then syncs if necessary.
- Removed our rotation property and replaced with the latest touchscreen-inverted-x/y. Also added support for the standard optional properties touchscreen-size-x/y and touchscreen-fuzz-x/y. Did not add support for inverted-x/y at this time as our touchscreen is currently only oriented 180 degres.

Changes from v1:
- Add missing newlines to debug messages
- Use BIT macro for defines
- Fix logic in get_tsc_config to improve readability
- Get rid of unnecessary remove() function

Jonathan Richardson (2):
Input: touchscreen-iproc: Add Broadcom iProc touchscreen driver
Input: touchscreen-iproc: add device tree bindings

 .../input/touchscreen/brcm,iproc-touchscreen.txt   |   76 +++
 drivers/input/touchscreen/Kconfig                  |   11 +
 drivers/input/touchscreen/Makefile                 |    1 +
 drivers/input/touchscreen/bcm_iproc_tsc.c          |  527 ++++++++++++++++++++
 4 files changed, 615 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/input/touchscreen/brcm,iproc-touchscreen.txt
 create mode 100644 drivers/input/touchscreen/bcm_iproc_tsc.c
Signature · 1 line
1.7.9.5
#85 lore raw

PATCH v3 1/2 Input: touchscreen-iproc: Add Broadcom iProc touchscreen driver

Add initial version of the Broadcom touchscreen driver.

---
 drivers/input/touchscreen/Kconfig         |   11 +
 drivers/input/touchscreen/Makefile        |    1 +
 drivers/input/touchscreen/bcm_iproc_tsc.c |  527 +++++++++++++++++++++++++++++
 3 files changed, 539 insertions(+)
 create mode 100644 drivers/input/touchscreen/bcm_iproc_tsc.c
drivers/input/touchscreen/Kconfig +11 -0
index 5891752..1290486 100644
@@ -323,6 +323,17 @@ config TOUCHSCREEN_ILI210X
 	  To compile this driver as a module, choose M here: the
 	  module will be called ili210x.
 
+config TOUCHSCREEN_IPROC
+	tristate "IPROC touch panel driver support"
+	help
+	  Say Y here if you want to add support for the IPROC touch
+	  controller to your system.
+
+	  If unsure, say N.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called iproc-ts.
+
 config TOUCHSCREEN_S3C2410
 	tristate "Samsung S3C2410/generic touchscreen input driver"
 	depends on ARCH_S3C24XX || SAMSUNG_DEV_TS
drivers/input/touchscreen/Makefile +1 -0
index 0242fea..68f69bc 100644
@@ -39,6 +39,7 @@ obj-$(CONFIG_TOUCHSCREEN_GOODIX)	+= goodix.o
 obj-$(CONFIG_TOUCHSCREEN_ILI210X)	+= ili210x.o
 obj-$(CONFIG_TOUCHSCREEN_INEXIO)	+= inexio.o
 obj-$(CONFIG_TOUCHSCREEN_INTEL_MID)	+= intel-mid-touch.o
+obj-$(CONFIG_TOUCHSCREEN_IPROC)		+= bcm_iproc_tsc.o
 obj-$(CONFIG_TOUCHSCREEN_LPC32XX)	+= lpc32xx_ts.o
 obj-$(CONFIG_TOUCHSCREEN_MAX11801)	+= max11801_ts.o
 obj-$(CONFIG_TOUCHSCREEN_MC13783)	+= mc13783_ts.o
drivers/input/touchscreen/bcm_iproc_tsc.c new file +527 -0

527 lines not on this page · raw message

Signature · 1 line
1.7.9.5
#86 lore raw

Re: [PATCH v3 1/2] Input: touchscreen-iproc: Add Broadcom iProc touchscreen driver

One nit is all I can report.

drivers/input/touchscreen/Kconfig config TOUCHSCREEN_ILI210X · line 335

Quoted 13 lines · Jonathan Richardson
drivers/input/touchscreen/Kconfig +10 -0
 
+config TOUCHSCREEN_IPROC
+	tristate "IPROC touch panel driver support"
+	help
+	  Say Y here if you want to add support for the IPROC touch
+	  controller to your system.
+
+	  If unsure, say N.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called iproc-ts.

The module will be called "bcm_iproc_tsc", won't it?

drivers/input/touchscreen/Makefile

Quoted 4 lines
drivers/input/touchscreen/Makefile +1 -0
 
+obj-$(CONFIG_TOUCHSCREEN_IPROC)		+= bcm_iproc_tsc.o

Paul Bolle

#87 lore raw

Re: [PATCH v3 1/2] Input: touchscreen-iproc: Add Broadcom iProc touchscreen driver

Hi Paul,

Yes, I didn't notice that. I'll include it in the next patch. Thanks for the review.

Jon

Quoted 27 lines · Paul Bolle

One nit is all I can report.

drivers/input/touchscreen/Kconfig config TOUCHSCREEN_ILI210X · line 335

Quoted 13 lines · Jonathan Richardson
drivers/input/touchscreen/Kconfig +10 -0
 
+config TOUCHSCREEN_IPROC
+	tristate "IPROC touch panel driver support"
+	help
+	  Say Y here if you want to add support for the IPROC touch
+	  controller to your system.
+
+	  If unsure, say N.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called iproc-ts.

The module will be called "bcm_iproc_tsc", won't it?

drivers/input/touchscreen/Makefile

Quoted 4 lines
drivers/input/touchscreen/Makefile +1 -0
 
+obj-$(CONFIG_TOUCHSCREEN_IPROC)		+= bcm_iproc_tsc.o

Paul Bolle

#88 lore raw

PATCH v3 2/2 Input: touchscreen-iproc: add device tree bindings

In reply to Jonathan Richardson

Documents the touchscreen device tree binding for Broadcom iProc family of SoCs.

---
 .../input/touchscreen/brcm,iproc-touchscreen.txt   |   76 ++++++++++++++++++++
 1 file changed, 76 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/input/touchscreen/brcm,iproc-touchscreen.txt
Documentation/devicetree/bindings/input/touchscreen/brcm,iproc-touchscreen.txt new file +76 -0
new file mode 100644
index 0000000..34e3382
@@ -0,0 +1,76 @@
+* Broadcom's IPROC Touchscreen Controller
+
+Required properties:
+- compatible: must be "brcm,iproc-touchscreen"
+- reg: physical base address of the controller and length of memory mapped
+  region.
+- clocks:  The clock provided by the SOC to driver the tsc
+- clock-name:  name for the clock
+- interrupts: The touchscreen controller's interrupt
+
+Optional properties:
+- scanning_period: Time between scans. Each step is 1024 us.  Valid 1-256.
+- debounce_timeout: Each step is 512 us.  Valid 0-255
+- settling_timeout: The settling duration (in ms) is the amount of time
+                    the tsc waits to allow the voltage to settle after
+                    turning on the drivers in detection mode.
+                    Valid values: 0-11
+                    0 =  0.008 ms
+                    1 =  0.01 ms
+                    2 =  0.02 ms
+                    3 =  0.04 ms
+                    4 =  0.08 ms
+                    5 =  0.16 ms
+                    6 =  0.32 ms
+                    7 =  0.64 ms
+                    8 =  1.28 ms
+                    9 =  2.56 ms
+                   10 =  5.12 ms
+                   11 = 10.24 ms
+- touch_timeout: The continuous number of scan periods in which touch is
+                not detected before the controller returns to idle state.
+                Valid values 0-255.
+- average_data: Number of data samples which are averaged before a final
+                data point is placed into the FIFO
+                Valid values 0-7
+                0 =   1 sample
+                1 =   2 samples
+                2 =   4 samples
+                3 =   8 samples
+                4 =  16 samples
+                5 =  32 samples
+                6 =  64 samples
+                7 = 128 samples
+- fifo_threshold: Interrupt is generated whenever the number of fifo
+                entries exceeds this value
+                Valid values 0-31
+- touchscreen-size-x: horizontal resolution of touchscreen (in pixels)
+- touchscreen-size-y: vertical resolution of touchscreen (in pixels)
+- touchscreen-fuzz-x: horizontal noise value of the absolute input
+                      device (in pixels)
+- touchscreen-fuzz-y: vertical noise value of the absolute input
+                      device (in pixels)
+- touchscreen-inverted-x: X axis is inverted (boolean)
+- touchscreen-inverted-y: Y axis is inverted (boolean)
+
+Example:
+
+	touchscreen: tsc@0x180A6000 {
+		compatible = "brcm,iproc-touchscreen";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		reg = <0x180A6000 0x40>;
+		clocks = <&adc_clk>;
+		clock-names = "tsc_clk";
+		interrupts = <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>;
+
+		scanning_period = <5>;
+		debounce_timeout = <40>;
+		settling_timeout = <7>;
+		touch_timeout = <10>;
+		average_data = <5>;
+		fifo_threshold = <1>;
+		/* Touchscreen is rotated 180 degrees. */
+		touchscreen-inverted-x;
+		touchscreen-inverted-y;
+	};
Signature · 1 line
1.7.9.5
#89 lore raw

v4 cover Add support for Broadcom iProc touchscreen

In reply to a message not in the archive

This patchset contains initial support for the touchscreen on the Broadcom iProc family of SoCs. This driver has been validated with Cygnus and is expected to work on other iProc family of SoCs that use the same touchscreen controller.

Changes from v3:
- Fixed typo in Kconfig.

Changes from v2:
- Misc style changes.
- Removed assumptions about interrupts generated in ISR. It now emits all events and then syncs if necessary.
- Removed our rotation property and replaced with the latest touchscreen-inverted-x/y. Also added support for the standard optional properties touchscreen-size-x/y and touchscreen-fuzz-x/y. Did not add support for inverted-x/y at this time as our touchscreen is currently only oriented 180 degres.

Changes from v1:
- Add missing newlines to debug messages
- Use BIT macro for defines
- Fix logic in get_tsc_config to improve readability
- Get rid of unnecessary remove() function

Jonathan Richardson (2):
Input: touchscreen-iproc: Add Broadcom iProc touchscreen driver
Input: touchscreen-iproc: add device tree bindings

 .../input/touchscreen/brcm,iproc-touchscreen.txt   |   76 +++
 drivers/input/touchscreen/Kconfig                  |   11 +
 drivers/input/touchscreen/Makefile                 |    1 +
 drivers/input/touchscreen/bcm_iproc_tsc.c          |  527 ++++++++++++++++++++
 4 files changed, 615 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/input/touchscreen/brcm,iproc-touchscreen.txt
 create mode 100644 drivers/input/touchscreen/bcm_iproc_tsc.c
Signature · 1 line
1.7.9.5
#90 lore raw

PATCH v4 1/2 Input: touchscreen-iproc: Add Broadcom iProc touchscreen driver

Add initial version of the Broadcom touchscreen driver.

---
 drivers/input/touchscreen/Kconfig         |   11 +
 drivers/input/touchscreen/Makefile        |    1 +
 drivers/input/touchscreen/bcm_iproc_tsc.c |  527 +++++++++++++++++++++++++++++
 3 files changed, 539 insertions(+)
 create mode 100644 drivers/input/touchscreen/bcm_iproc_tsc.c
drivers/input/touchscreen/Kconfig +11 -0
index 6261fd6..4a8b0e5 100644
@@ -323,6 +323,17 @@ config TOUCHSCREEN_ILI210X
 	  To compile this driver as a module, choose M here: the
 	  module will be called ili210x.
 
+config TOUCHSCREEN_IPROC
+	tristate "IPROC touch panel driver support"
+	help
+	  Say Y here if you want to add support for the IPROC touch
+	  controller to your system.
+
+	  If unsure, say N.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called bcm_iproc_tsc.
+
 config TOUCHSCREEN_S3C2410
 	tristate "Samsung S3C2410/generic touchscreen input driver"
 	depends on ARCH_S3C24XX || SAMSUNG_DEV_TS
drivers/input/touchscreen/Makefile +1 -0
index 0242fea..68f69bc 100644
@@ -39,6 +39,7 @@ obj-$(CONFIG_TOUCHSCREEN_GOODIX)	+= goodix.o
 obj-$(CONFIG_TOUCHSCREEN_ILI210X)	+= ili210x.o
 obj-$(CONFIG_TOUCHSCREEN_INEXIO)	+= inexio.o
 obj-$(CONFIG_TOUCHSCREEN_INTEL_MID)	+= intel-mid-touch.o
+obj-$(CONFIG_TOUCHSCREEN_IPROC)		+= bcm_iproc_tsc.o
 obj-$(CONFIG_TOUCHSCREEN_LPC32XX)	+= lpc32xx_ts.o
 obj-$(CONFIG_TOUCHSCREEN_MAX11801)	+= max11801_ts.o
 obj-$(CONFIG_TOUCHSCREEN_MC13783)	+= mc13783_ts.o
drivers/input/touchscreen/bcm_iproc_tsc.c new file +527 -0

527 lines not on this page · raw message

Signature · 1 line
1.7.9.5
#91 lore raw

Re: [PATCH v4 1/2] Input: touchscreen-iproc: Add Broadcom iProc touchscreen driver

Quoted 1 line · Jonathan Richardson

Add initial version of the Broadcom touchscreen driver.

style trivia:
(any of which could be fixed/improved/ignored later)

drivers/input/touchscreen/bcm_iproc_tsc.c

Quoted 1 line
drivers/input/touchscreen/bcm_iproc_tsc.c +0 -0

[]

drivers/input/touchscreen/bcm_iproc_tsc.c line 168

Quoted 6 lines
drivers/input/touchscreen/bcm_iproc_tsc.c +6 -0
+static void ts_reg_dump(struct iproc_ts_priv *priv)
+{
+	struct device *dev = &priv->pdev->dev;
+
+	dev_dbg(dev, "regCtl1             = 0x%08x\n",
+				readl(priv->regs + REGCTL1));

The output case here generally isn't very important so sometimes it's better to use a macro like:

#define dbg_reg(dev, priv, reg)						\
	dev_dbg(dev, "%20s= 0x%08x\n", #reg, readl((priv)->regs + reg))

drivers/input/touchscreen/bcm_iproc_tsc.c line 170

Quoted 2 lines
drivers/input/touchscreen/bcm_iproc_tsc.c +2 -0
+	dev_dbg(dev, "regCtl2             = 0x%08x\n",
+				readl(priv->regs + REGCTL2));

so these become

	dbg_reg(dev, priv, INTERRUPT_THRES);
	dbg_reg(dev, priv, INTERRUPT_MASK);

etc...

This style can reduce typo and copy/paste defects.

Quoted 19 lines
drivers/input/touchscreen/bcm_iproc_tsc.c +19 -0
+	dev_dbg(dev, "interrupt_Thres     = 0x%08x\n",
+				readl(priv->regs + INTERRUPT_THRES));
+	dev_dbg(dev, "interrupt_Mask      = 0x%08x\n",
+				readl(priv->regs + INTERRUPT_MASK));
+	dev_dbg(dev, "interrupt_Status    = 0x%08x\n",
+				readl(priv->regs + INTERRUPT_STATUS));
+	dev_dbg(dev, "controller_Status   = 0x%08x\n",
+				readl(priv->regs + CONTROLLER_STATUS));
+	dev_dbg(dev, "FIFO_Data           = 0x%08x\n",
+				readl(priv->regs + FIFO_DATA));
+	dev_dbg(dev, "analog_Control      = 0x%08x\n",
+				readl(priv->regs + ANALOG_CONTROL));
+	dev_dbg(dev, "aux_Data            = 0x%08x\n",
+				readl(priv->regs + AUX_DATA));
+	dev_dbg(dev, "debounce_Cntr_Stat  = 0x%08x\n",
+				readl(priv->regs + DEBOUNCE_CNTR_STAT));
+	dev_dbg(dev, "scan_Cntr_Stat      = 0x%08x\n",
+				readl(priv->regs + SCAN_CNTR_STAT));
+	dev_dbg(dev, "rem_Cntr_Stat       = 0x%08x\n",

drivers/input/touchscreen/bcm_iproc_tsc.c line 199

Quoted 10 lines
drivers/input/touchscreen/bcm_iproc_tsc.c +10 -0
+				readl(priv->regs + REM_CNTR_STAT));
+	dev_dbg(dev, "settling_Timer_Stat = 0x%08x\n",
+				readl(priv->regs + SETTLING_TIMER_STAT));
+	dev_dbg(dev, "spare_Reg           = 0x%08x\n",
+				readl(priv->regs + SPARE_REG));
+	dev_dbg(dev, "soft_Bypass_Control = 0x%08x\n",
+				readl(priv->regs + SOFT_BYPASS_CONTROL));
+	dev_dbg(dev, "soft_Bypass_Data    = 0x%08x\n",
+				readl(priv->regs + SOFT_BYPASS_DATA));
+}

[]

drivers/input/touchscreen/bcm_iproc_tsc.c line 348

Quoted 3 lines
drivers/input/touchscreen/bcm_iproc_tsc.c +3 -0
+static int get_tsc_config(struct device_node *np, struct iproc_ts_priv *priv)
+{
+	u32 val;

[]

drivers/input/touchscreen/bcm_iproc_tsc.c

Quoted 2 lines
drivers/input/touchscreen/bcm_iproc_tsc.c +2 -0
+	if (of_property_read_u32(np, "debounce_timeout", &val) >= 0) {
+		if (val < 0 || val > 255) {

testing u32 < 0 isn't necessary.

Maybe it'd be better to emit the out of range value too

drivers/input/touchscreen/bcm_iproc_tsc.c line 363

Quoted 1 line
drivers/input/touchscreen/bcm_iproc_tsc.c +1 -0
+			dev_err(dev, "debounce_timeout must be [0-255]\n");
			dev_err(dev, "debounce_timeout (%u) must be [0-255]\n", val);

A message that is not in the archive (sent off-list or not yet received): [email protected]

#93 lore raw

Re: [PATCH v4 1/2] Input: touchscreen-iproc: Add Broadcom iProc touchscreen driver

Quoted 73 lines · Joe Perches
Quoted 1 line · Jonathan Richardson

Add initial version of the Broadcom touchscreen driver.

style trivia:
(any of which could be fixed/improved/ignored later)

drivers/input/touchscreen/bcm_iproc_tsc.c

Quoted 1 line
drivers/input/touchscreen/bcm_iproc_tsc.c +0 -0

[]

drivers/input/touchscreen/bcm_iproc_tsc.c line 168

Quoted 6 lines
drivers/input/touchscreen/bcm_iproc_tsc.c +6 -0
+static void ts_reg_dump(struct iproc_ts_priv *priv)
+{
+	struct device *dev = &priv->pdev->dev;
+
+	dev_dbg(dev, "regCtl1             = 0x%08x\n",
+				readl(priv->regs + REGCTL1));

The output case here generally isn't very important so sometimes it's better to use a macro like:

#define dbg_reg(dev, priv, reg)						\
	dev_dbg(dev, "%20s= 0x%08x\n", #reg, readl((priv)->regs + reg))

drivers/input/touchscreen/bcm_iproc_tsc.c line 170

Quoted 2 lines
drivers/input/touchscreen/bcm_iproc_tsc.c +2 -0
+	dev_dbg(dev, "regCtl2             = 0x%08x\n",
+				readl(priv->regs + REGCTL2));

so these become

	dbg_reg(dev, priv, INTERRUPT_THRES);
	dbg_reg(dev, priv, INTERRUPT_MASK);

etc...

This style can reduce typo and copy/paste defects.

Quoted 19 lines
drivers/input/touchscreen/bcm_iproc_tsc.c +19 -0
+	dev_dbg(dev, "interrupt_Thres     = 0x%08x\n",
+				readl(priv->regs + INTERRUPT_THRES));
+	dev_dbg(dev, "interrupt_Mask      = 0x%08x\n",
+				readl(priv->regs + INTERRUPT_MASK));
+	dev_dbg(dev, "interrupt_Status    = 0x%08x\n",
+				readl(priv->regs + INTERRUPT_STATUS));
+	dev_dbg(dev, "controller_Status   = 0x%08x\n",
+				readl(priv->regs + CONTROLLER_STATUS));
+	dev_dbg(dev, "FIFO_Data           = 0x%08x\n",
+				readl(priv->regs + FIFO_DATA));
+	dev_dbg(dev, "analog_Control      = 0x%08x\n",
+				readl(priv->regs + ANALOG_CONTROL));
+	dev_dbg(dev, "aux_Data            = 0x%08x\n",
+				readl(priv->regs + AUX_DATA));
+	dev_dbg(dev, "debounce_Cntr_Stat  = 0x%08x\n",
+				readl(priv->regs + DEBOUNCE_CNTR_STAT));
+	dev_dbg(dev, "scan_Cntr_Stat      = 0x%08x\n",
+				readl(priv->regs + SCAN_CNTR_STAT));
+	dev_dbg(dev, "rem_Cntr_Stat       = 0x%08x\n",

drivers/input/touchscreen/bcm_iproc_tsc.c line 199

Quoted 10 lines
drivers/input/touchscreen/bcm_iproc_tsc.c +10 -0
+				readl(priv->regs + REM_CNTR_STAT));
+	dev_dbg(dev, "settling_Timer_Stat = 0x%08x\n",
+				readl(priv->regs + SETTLING_TIMER_STAT));
+	dev_dbg(dev, "spare_Reg           = 0x%08x\n",
+				readl(priv->regs + SPARE_REG));
+	dev_dbg(dev, "soft_Bypass_Control = 0x%08x\n",
+				readl(priv->regs + SOFT_BYPASS_CONTROL));
+	dev_dbg(dev, "soft_Bypass_Data    = 0x%08x\n",
+				readl(priv->regs + SOFT_BYPASS_DATA));
+}

[]

drivers/input/touchscreen/bcm_iproc_tsc.c line 348

Quoted 3 lines
drivers/input/touchscreen/bcm_iproc_tsc.c +3 -0
+static int get_tsc_config(struct device_node *np, struct iproc_ts_priv *priv)
+{
+	u32 val;

[]

drivers/input/touchscreen/bcm_iproc_tsc.c

Quoted 2 lines
drivers/input/touchscreen/bcm_iproc_tsc.c +2 -0
+	if (of_property_read_u32(np, "debounce_timeout", &val) >= 0) {
+		if (val < 0 || val > 255) {

testing u32 < 0 isn't necessary.

Quoted 7 lines

Maybe it'd be better to emit the out of range value too

drivers/input/touchscreen/bcm_iproc_tsc.c line 363

Quoted 1 line
drivers/input/touchscreen/bcm_iproc_tsc.c +1 -0
+			dev_err(dev, "debounce_timeout must be [0-255]\n");
			dev_err(dev, "debounce_timeout (%u) must be [0-255]\n", val);

Thanks. I'll make the suggested changes and send out a new patch.

Jon

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

#94 lore raw

PATCH v4 2/2 Input: touchscreen-iproc: add device tree bindings

In reply to Jonathan Richardson

Documents the touchscreen device tree binding for Broadcom iProc family of SoCs.

---
 .../input/touchscreen/brcm,iproc-touchscreen.txt   |   76 ++++++++++++++++++++
 1 file changed, 76 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/input/touchscreen/brcm,iproc-touchscreen.txt
Documentation/devicetree/bindings/input/touchscreen/brcm,iproc-touchscreen.txt new file +76 -0
new file mode 100644
index 0000000..34e3382
@@ -0,0 +1,76 @@
+* Broadcom's IPROC Touchscreen Controller
+
+Required properties:
+- compatible: must be "brcm,iproc-touchscreen"
+- reg: physical base address of the controller and length of memory mapped
+  region.
+- clocks:  The clock provided by the SOC to driver the tsc
+- clock-name:  name for the clock
+- interrupts: The touchscreen controller's interrupt
+
+Optional properties:
+- scanning_period: Time between scans. Each step is 1024 us.  Valid 1-256.
+- debounce_timeout: Each step is 512 us.  Valid 0-255
+- settling_timeout: The settling duration (in ms) is the amount of time
+                    the tsc waits to allow the voltage to settle after
+                    turning on the drivers in detection mode.
+                    Valid values: 0-11
+                    0 =  0.008 ms
+                    1 =  0.01 ms
+                    2 =  0.02 ms
+                    3 =  0.04 ms
+                    4 =  0.08 ms
+                    5 =  0.16 ms
+                    6 =  0.32 ms
+                    7 =  0.64 ms
+                    8 =  1.28 ms
+                    9 =  2.56 ms
+                   10 =  5.12 ms
+                   11 = 10.24 ms
+- touch_timeout: The continuous number of scan periods in which touch is
+                not detected before the controller returns to idle state.
+                Valid values 0-255.
+- average_data: Number of data samples which are averaged before a final
+                data point is placed into the FIFO
+                Valid values 0-7
+                0 =   1 sample
+                1 =   2 samples
+                2 =   4 samples
+                3 =   8 samples
+                4 =  16 samples
+                5 =  32 samples
+                6 =  64 samples
+                7 = 128 samples
+- fifo_threshold: Interrupt is generated whenever the number of fifo
+                entries exceeds this value
+                Valid values 0-31
+- touchscreen-size-x: horizontal resolution of touchscreen (in pixels)
+- touchscreen-size-y: vertical resolution of touchscreen (in pixels)
+- touchscreen-fuzz-x: horizontal noise value of the absolute input
+                      device (in pixels)
+- touchscreen-fuzz-y: vertical noise value of the absolute input
+                      device (in pixels)
+- touchscreen-inverted-x: X axis is inverted (boolean)
+- touchscreen-inverted-y: Y axis is inverted (boolean)
+
+Example:
+
+	touchscreen: tsc@0x180A6000 {
+		compatible = "brcm,iproc-touchscreen";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		reg = <0x180A6000 0x40>;
+		clocks = <&adc_clk>;
+		clock-names = "tsc_clk";
+		interrupts = <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>;
+
+		scanning_period = <5>;
+		debounce_timeout = <40>;
+		settling_timeout = <7>;
+		touch_timeout = <10>;
+		average_data = <5>;
+		fifo_threshold = <1>;
+		/* Touchscreen is rotated 180 degrees. */
+		touchscreen-inverted-x;
+		touchscreen-inverted-y;
+	};
Signature · 1 line
1.7.9.5