On 09/11/2012 04:06 AM, Kuninori Morimoto wrote:
This patch adds Renesas R-Car USB phy driver.
It supports R8A7779 chip at this point.
R-Car has some USB controllers, but has only one phy-initializer.
So, this driver is counting users.
Signed-off-by: Kuninori Morimoto kuninori.morimoto...@renesas.com
---
v3 - v4
- rcar_usb_phy_shutdown() became static
- used priv-counter == x
- removed dev_info()
- MODULE_LICENSE(GPL v2)
drivers/usb/phy/Kconfig| 12 +++
drivers/usb/phy/Makefile |1 +
drivers/usb/phy/rcar-phy.c | 225
3 files changed, 238 insertions(+)
create mode 100644 drivers/usb/phy/rcar-phy.c
diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig
index 63c339b..7eb73c5 100644
--- a/drivers/usb/phy/Kconfig
+++ b/drivers/usb/phy/Kconfig
@@ -32,3 +32,15 @@ config MV_U3D_PHY
help
Enable this to support Marvell USB 3.0 phy controller for Marvell
SoC.
+
+config USB_RCAR_PHY
+ tristate Renesas R-Car USB phy support
+ depends on USB || USB_GADGET
+ select USB_OTG_UTILS
+ help
+ Say Y here to add support for the Renesas R-Car USB phy driver.
+ This chip is typically used as USB phy for USB host, gadget.
+ This driver supports: R8A7779
+
+ To compile this driver as a module, choose M here: the
+ module will be called rcar-phy.
diff --git a/drivers/usb/phy/Makefile b/drivers/usb/phy/Makefile
index b069f29..1a579a8 100644
--- a/drivers/usb/phy/Makefile
+++ b/drivers/usb/phy/Makefile
@@ -8,3 +8,4 @@ obj-$(CONFIG_OMAP_USB2) += omap-usb2.o
obj-$(CONFIG_USB_ISP1301)+= isp1301.o
obj-$(CONFIG_MV_U3D_PHY) += mv_u3d_phy.o
obj-$(CONFIG_USB_EHCI_TEGRA) += tegra_usb_phy.o
+obj-$(CONFIG_USB_RCAR_PHY) += rcar-phy.o
diff --git a/drivers/usb/phy/rcar-phy.c b/drivers/usb/phy/rcar-phy.c
new file mode 100644
index 000..3fce889
--- /dev/null
+++ b/drivers/usb/phy/rcar-phy.c
@@ -0,0 +1,225 @@
+/*
+ * Renesas R-Car USB phy driver
+ *
+ * Copyright (C) 2012 Renesas Solutions Corp.
+ * Kuninori Morimoto kuninori.morimoto...@renesas.com
+ *
+
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include linux/delay.h
+#include linux/io.h
+#include linux/usb/otg.h
+#include linux/platform_device.h
+#include linux/spinlock.h
+#include linux/module.h
+
+/* USBH common register */
+#define USBPCTRL00x0800
+#define USBPCTRL10x0804
+#define USBST0x0808
+#define USBEH0 0x080C
+#define USBOH0 0x081C
+#define USBCTL0 0x0858
+#define EIIBC1 0x0094
+#define EIIBC2 0x009C
+
+#ifdef CONFIG_ARCH_SUPPORTS_BIG_ENDIAN
That symbol is only defined on ARM's mach-ixp4xx. If you want to support
big endian hosts in general, you have to use a different symbol.
+# define PHY_ENDIAN BIG
^^
It this used?
+# define PHY_NO_SWAP 0x0003
+#else
+# define PHY_ENDIAN LITTLE
+# define PHY_NO_SWAP 0x
+#endif
+
+/* USBPCTRL1 */
+#define PHY_RST (1 2)
+#define PLL_ENB (1 1)
+#define PHY_ENB (1 0)
+
+/* USBST */
+#define ACT (1 31)
+#define PLL (1 30)
+
+struct rcar_usb_phy_priv {
+ struct usb_phy phy;
+ spinlock_t lock;
+
+ void __iomem *reg0;
+ void __iomem *reg1;
+ int counter;
+};
+
+#define usb_phy_to_priv(p) container_of(p, struct rcar_usb_phy_priv, phy)
+
+
+/*
+ * USB initial/install operation.
+ *
+ * This function setup USB phy.
+ * The used value and setting order came from
+ * [USB :: Initial setting] on datasheet.
+ */
+static int rcar_usb_phy_init(struct usb_phy *phy)
+{
+ struct rcar_usb_phy_priv *priv = usb_phy_to_priv(phy);
+ struct device *dev = phy-dev;
+ void __iomem *reg0 = priv-reg0;
+ void __iomem *reg1 = priv-reg1;
+ int i;
+ u32 val;
+ unsigned long flags;
+
+ spin_lock_irqsave(priv-lock, flags);
+ if (priv-counter == 0) {
+
+ /*
+ * USB phy start-up
+ */
+
+ /* (1) USB-PHY standby release */
+ iowrite32(PHY_ENB, (reg0 + USBPCTRL1));
+
+ /* (2) start USB-PHY internal PLL */
+ iowrite32(PHY_ENB | PLL_ENB, (reg0 + USBPCTRL1));
+
+ /* (3) USB module status check */
+ for (i = 0; i 1024; i++) {
+ udelay(10);
+ val = ioread32(reg0 + USBST);
+ if ((ACT | PLL) == val)
nitpick:
It' more common to write the comparison the other way round:
if (val == (ACT | PLL))
The compiler will warn you, if you do an assignment instead of a comparison.
+