All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v8 0/2] usb: phy: samsung: Introducing usb phy driver for samsung SoCs
@ 2012-11-14 10:27 ` Praveen Paneri
  0 siblings, 0 replies; 28+ messages in thread
From: Praveen Paneri @ 2012-11-14 10:27 UTC (permalink / raw)
  To: linux-usb-u79uwXL29TY76Z2rM5mHXA
  Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-samsung-soc-u79uwXL29TY76Z2rM5mHXA,
	kgene.kim-Sze3O3UU22JBDgjK7y7TUQ, balbi-l0cyMroinI0,
	gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
	thomas.abraham-QSEj5FYQhm4dnm+yROfE0A,
	ben-linux-elnMNo+KYs3YtjvyW6yDsg,
	broonie-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E,
	l.majewski-Sze3O3UU22JBDgjK7y7TUQ,
	kyungmin.park-Sze3O3UU22JBDgjK7y7TUQ,
	grant.likely-s3s/WqlpOiPyB63q8FvJNQ,
	heiko-4mtYJXux2i+zQB+pC5nmwQ, t.figa-Sze3O3UU22JBDgjK7y7TUQ,
	gautam.vivek-Sze3O3UU22JBDgjK7y7TUQ

Changes from v7:
Rebased to the latest usb-next branch.
Separating arch patches from these driver patches.

Changes from v6:
Modified register definitions according to the existing ones.
Changed default PHY clk selection for SoCs.
Improved binding text and rebased to the latest usb-next.

Changes from v5:
Moved clk_get() to driver's probe function. Now reference clock frequency
selection value is stored in samsung_usbphy structure for later use. Used
IS_ENABLED() instead of #ifdef in samsung_usbphy_get_driver_data().

Changes from v4:
Moved header file contents to driver's source file
Removed unnecessary print message from driver's probe function
Dropped the Free Software Foundation address from the header

Changes from v3:
Replaced susbsys_initcall()/module_exit() by module_platform_driver().
Accordingly in the hsotg driver returned -EPROBE_DEFER until phy driver
is registered
Removed unnecessary devm_usb_put_phy() call from the hsotg driver remove.

Changes from v2:
Changed the driver filenames to samsung-usbphy
Rectified coding style related errors

Changes from v1:
Rebased patches to latest usb-next branch
Changed the name 'sec_usbphy' to 'samsung_usbphy'

This patch set introduces a phy driver for samsung SoCs. It uses the existing
transceiver infrastructure to provide phy control functions. Use of this driver
can be extended for usb host phy as well. Over the period of time all the phy
related code for most of the samsung SoCs can be integrated here.
Removing the existing phy code from mach-s3c64xx. Same can be done for other SoCs
when they start supporting this phy driver. 
This driver is tested with smdk6410 and Exynos4210(with DT).

Praveen Paneri (2):
  usb: phy: samsung: Introducing usb phy driver for hsotg
  usb: s3c-hsotg: Adding phy driver support

 .../devicetree/bindings/usb/samsung-usbphy.txt     |   11 +
 drivers/usb/gadget/s3c-hsotg.c                     |   37 ++-
 drivers/usb/phy/Kconfig                            |    8 +
 drivers/usb/phy/Makefile                           |    1 +
 drivers/usb/phy/samsung-usbphy.c                   |  360 ++++++++++++++++++++
 include/linux/platform_data/samsung-usbphy.h       |   27 ++
 6 files changed, 434 insertions(+), 10 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/usb/samsung-usbphy.txt
 create mode 100644 drivers/usb/phy/samsung-usbphy.c
 create mode 100644 include/linux/platform_data/samsung-usbphy.h

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

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

* [PATCH v8 0/2] usb: phy: samsung: Introducing usb phy driver for samsung SoCs
@ 2012-11-14 10:27 ` Praveen Paneri
  0 siblings, 0 replies; 28+ messages in thread
From: Praveen Paneri @ 2012-11-14 10:27 UTC (permalink / raw)
  To: linux-arm-kernel

Changes from v7:
Rebased to the latest usb-next branch.
Separating arch patches from these driver patches.

Changes from v6:
Modified register definitions according to the existing ones.
Changed default PHY clk selection for SoCs.
Improved binding text and rebased to the latest usb-next.

Changes from v5:
Moved clk_get() to driver's probe function. Now reference clock frequency
selection value is stored in samsung_usbphy structure for later use. Used
IS_ENABLED() instead of #ifdef in samsung_usbphy_get_driver_data().

Changes from v4:
Moved header file contents to driver's source file
Removed unnecessary print message from driver's probe function
Dropped the Free Software Foundation address from the header

Changes from v3:
Replaced susbsys_initcall()/module_exit() by module_platform_driver().
Accordingly in the hsotg driver returned -EPROBE_DEFER until phy driver
is registered
Removed unnecessary devm_usb_put_phy() call from the hsotg driver remove.

Changes from v2:
Changed the driver filenames to samsung-usbphy
Rectified coding style related errors

Changes from v1:
Rebased patches to latest usb-next branch
Changed the name 'sec_usbphy' to 'samsung_usbphy'

This patch set introduces a phy driver for samsung SoCs. It uses the existing
transceiver infrastructure to provide phy control functions. Use of this driver
can be extended for usb host phy as well. Over the period of time all the phy
related code for most of the samsung SoCs can be integrated here.
Removing the existing phy code from mach-s3c64xx. Same can be done for other SoCs
when they start supporting this phy driver. 
This driver is tested with smdk6410 and Exynos4210(with DT).

Praveen Paneri (2):
  usb: phy: samsung: Introducing usb phy driver for hsotg
  usb: s3c-hsotg: Adding phy driver support

 .../devicetree/bindings/usb/samsung-usbphy.txt     |   11 +
 drivers/usb/gadget/s3c-hsotg.c                     |   37 ++-
 drivers/usb/phy/Kconfig                            |    8 +
 drivers/usb/phy/Makefile                           |    1 +
 drivers/usb/phy/samsung-usbphy.c                   |  360 ++++++++++++++++++++
 include/linux/platform_data/samsung-usbphy.h       |   27 ++
 6 files changed, 434 insertions(+), 10 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/usb/samsung-usbphy.txt
 create mode 100644 drivers/usb/phy/samsung-usbphy.c
 create mode 100644 include/linux/platform_data/samsung-usbphy.h

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

* [PATCH v8 1/2] usb: phy: samsung: Introducing usb phy driver for hsotg
  2012-11-14 10:27 ` Praveen Paneri
@ 2012-11-14 10:27     ` Praveen Paneri
  -1 siblings, 0 replies; 28+ messages in thread
From: Praveen Paneri @ 2012-11-14 10:27 UTC (permalink / raw)
  To: linux-usb-u79uwXL29TY76Z2rM5mHXA
  Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-samsung-soc-u79uwXL29TY76Z2rM5mHXA,
	kgene.kim-Sze3O3UU22JBDgjK7y7TUQ, balbi-l0cyMroinI0,
	gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
	thomas.abraham-QSEj5FYQhm4dnm+yROfE0A,
	ben-linux-elnMNo+KYs3YtjvyW6yDsg,
	broonie-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E,
	l.majewski-Sze3O3UU22JBDgjK7y7TUQ,
	kyungmin.park-Sze3O3UU22JBDgjK7y7TUQ,
	grant.likely-s3s/WqlpOiPyB63q8FvJNQ,
	heiko-4mtYJXux2i+zQB+pC5nmwQ, t.figa-Sze3O3UU22JBDgjK7y7TUQ,
	gautam.vivek-Sze3O3UU22JBDgjK7y7TUQ

This driver uses usb_phy interface to interact with s3c-hsotg. Supports
phy_init and phy_shutdown functions to enable/disable usb phy. Support
will be extended to host controllers and more Samsung SoCs.

Signed-off-by: Praveen Paneri <p.paneri-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
Acked-by: Heiko Stuebner <heiko-4mtYJXux2i+zQB+pC5nmwQ@public.gmane.org>
Acked-by: Kyungmin Park <kyungmin.park-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
---
 .../devicetree/bindings/usb/samsung-usbphy.txt     |   11 +
 drivers/usb/phy/Kconfig                            |    8 +
 drivers/usb/phy/Makefile                           |    1 +
 drivers/usb/phy/samsung-usbphy.c                   |  360 ++++++++++++++++++++
 include/linux/platform_data/samsung-usbphy.h       |   27 ++
 5 files changed, 407 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/usb/samsung-usbphy.txt
 create mode 100644 drivers/usb/phy/samsung-usbphy.c
 create mode 100644 include/linux/platform_data/samsung-usbphy.h

diff --git a/Documentation/devicetree/bindings/usb/samsung-usbphy.txt b/Documentation/devicetree/bindings/usb/samsung-usbphy.txt
new file mode 100644
index 0000000..7b26e2d
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/samsung-usbphy.txt
@@ -0,0 +1,11 @@
+* Samsung's usb phy transceiver
+
+The Samsung's phy transceiver is used for controlling usb otg phy for
+s3c-hsotg usb device controller.
+TODO: Adding the PHY binding with controller(s) according to the under
+developement generic PHY driver.
+
+Required properties:
+- compatible : should be "samsung,exynos4210-usbphy"
+- reg : base physical address of the phy registers and length of memory mapped
+	region.
diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig
index 7eb73c5..17ad743 100644
--- a/drivers/usb/phy/Kconfig
+++ b/drivers/usb/phy/Kconfig
@@ -44,3 +44,11 @@ config USB_RCAR_PHY
 
 	  To compile this driver as a module, choose M here: the
 	  module will be called rcar-phy.
+
+config SAMSUNG_USBPHY
+	bool "Samsung USB PHY controller Driver"
+	depends on USB_S3C_HSOTG
+	select USB_OTG_UTILS
+	help
+	  Enable this to support Samsung USB phy controller for samsung
+	  SoCs.
diff --git a/drivers/usb/phy/Makefile b/drivers/usb/phy/Makefile
index 1a579a8..ec304f6 100644
--- a/drivers/usb/phy/Makefile
+++ b/drivers/usb/phy/Makefile
@@ -9,3 +9,4 @@ 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
+obj-$(CONFIG_SAMSUNG_USBPHY)		+= samsung-usbphy.o
diff --git a/drivers/usb/phy/samsung-usbphy.c b/drivers/usb/phy/samsung-usbphy.c
new file mode 100644
index 0000000..3c84aab
--- /dev/null
+++ b/drivers/usb/phy/samsung-usbphy.c
@@ -0,0 +1,360 @@
+/* linux/drivers/usb/phy/samsung-usbphy.c
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *              http://www.samsung.com
+ *
+ * Author: Praveen Paneri <p.paneri-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
+ *
+ * Samsung USB2.0 High-speed OTG transceiver, talks to S3C HS OTG controller
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; 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/platform_device.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/usb/otg.h>
+#include <linux/platform_data/samsung-usbphy.h>
+
+/* Register definitions */
+
+#define SAMSUNG_PHYPWR				(0x00)
+
+#define PHYPWR_NORMAL_MASK			(0x19 << 0)
+#define PHYPWR_OTG_DISABLE			(0x1 << 4)
+#define PHYPWR_ANALOG_POWERDOWN			(0x1 << 3)
+#define PHYPWR_FORCE_SUSPEND			(0x1 << 1)
+/* For Exynos4 */
+#define PHYPWR_NORMAL_MASK_PHY0			(0x39 << 0)
+#define PHYPWR_SLEEP_PHY0			(0x1 << 5)
+
+#define SAMSUNG_PHYCLK				(0x04)
+
+#define PHYCLK_MODE_USB11			(0x1 << 6)
+#define PHYCLK_EXT_OSC				(0x1 << 5)
+#define PHYCLK_COMMON_ON_N			(0x1 << 4)
+#define PHYCLK_ID_PULL				(0x1 << 2)
+#define PHYCLK_CLKSEL_MASK			(0x3 << 0)
+#define PHYCLK_CLKSEL_48M			(0x0 << 0)
+#define PHYCLK_CLKSEL_12M			(0x2 << 0)
+#define PHYCLK_CLKSEL_24M			(0x3 << 0)
+
+#define SAMSUNG_RSTCON				(0x08)
+
+#define RSTCON_PHYLINK_SWRST			(0x1 << 2)
+#define RSTCON_HLINK_SWRST			(0x1 << 1)
+#define RSTCON_SWRST				(0x1 << 0)
+
+#ifndef MHZ
+#define MHZ (1000*1000)
+#endif
+
+enum samsung_cpu_type {
+	TYPE_S3C64XX,
+	TYPE_EXYNOS4210,
+};
+
+/*
+ * struct samsung_usbphy - transceiver driver state
+ * @phy: transceiver structure
+ * @plat: platform data
+ * @dev: The parent device supplied to the probe function
+ * @clk: usb phy clock
+ * @regs: usb phy register memory base
+ * @ref_clk_freq: reference clock frequency selection
+ * @cpu_type: machine identifier
+ */
+struct samsung_usbphy {
+	struct usb_phy	phy;
+	struct samsung_usbphy_data *plat;
+	struct device	*dev;
+	struct clk	*clk;
+	void __iomem	*regs;
+	int		ref_clk_freq;
+	int		cpu_type;
+};
+
+#define phy_to_sphy(x)		container_of((x), struct samsung_usbphy, phy)
+
+/*
+ * Returns reference clock frequency selection value
+ */
+static int samsung_usbphy_get_refclk_freq(struct samsung_usbphy *sphy)
+{
+	struct clk *ref_clk;
+	int refclk_freq = 0;
+
+	ref_clk = clk_get(sphy->dev, "xusbxti");
+	if (IS_ERR(ref_clk)) {
+		dev_err(sphy->dev, "Failed to get reference clock\n");
+		return PTR_ERR(ref_clk);
+	}
+
+	switch (clk_get_rate(ref_clk)) {
+	case 12 * MHZ:
+		refclk_freq = PHYCLK_CLKSEL_12M;
+		break;
+	case 24 * MHZ:
+		refclk_freq = PHYCLK_CLKSEL_24M;
+		break;
+	case 48 * MHZ:
+		refclk_freq = PHYCLK_CLKSEL_48M;
+		break;
+	default:
+		if (sphy->cpu_type == TYPE_S3C64XX)
+			refclk_freq = PHYCLK_CLKSEL_48M;
+		else
+			refclk_freq = PHYCLK_CLKSEL_24M;
+		break;
+	}
+	clk_put(ref_clk);
+
+	return refclk_freq;
+}
+
+static void samsung_usbphy_enable(struct samsung_usbphy *sphy)
+{
+	void __iomem *regs = sphy->regs;
+	u32 phypwr;
+	u32 phyclk;
+	u32 rstcon;
+
+	/* set clock frequency for PLL */
+	phyclk = sphy->ref_clk_freq;
+	phypwr = readl(regs + SAMSUNG_PHYPWR);
+	rstcon = readl(regs + SAMSUNG_RSTCON);
+
+	switch (sphy->cpu_type) {
+	case TYPE_S3C64XX:
+		phyclk &= ~PHYCLK_COMMON_ON_N;
+		phypwr &= ~PHYPWR_NORMAL_MASK;
+		rstcon |= RSTCON_SWRST;
+		break;
+	case TYPE_EXYNOS4210:
+		phypwr &= ~PHYPWR_NORMAL_MASK_PHY0;
+		rstcon |= RSTCON_SWRST;
+	default:
+		break;
+	}
+
+	writel(phyclk, regs + SAMSUNG_PHYCLK);
+	/* set to normal of PHY0 */
+	writel(phypwr, regs + SAMSUNG_PHYPWR);
+	/* reset all ports of PHY and Link */
+	writel(rstcon, regs + SAMSUNG_RSTCON);
+	udelay(10);
+	rstcon &= ~RSTCON_SWRST;
+	writel(rstcon, regs + SAMSUNG_RSTCON);
+}
+
+static void samsung_usbphy_disable(struct samsung_usbphy *sphy)
+{
+	void __iomem *regs = sphy->regs;
+	u32 phypwr;
+
+	phypwr = readl(regs + SAMSUNG_PHYPWR);
+
+	switch (sphy->cpu_type) {
+	case TYPE_S3C64XX:
+		phypwr |= PHYPWR_NORMAL_MASK;
+		break;
+	case TYPE_EXYNOS4210:
+		phypwr |= PHYPWR_NORMAL_MASK_PHY0;
+	default:
+		break;
+	}
+
+	/* unset to normal of PHY0 */
+	writel(phypwr, regs + SAMSUNG_PHYPWR);
+}
+
+/*
+ * The function passed to the usb driver for phy initialization
+ */
+static int samsung_usbphy_init(struct usb_phy *phy)
+{
+	struct samsung_usbphy *sphy;
+	int ret = 0;
+
+	sphy = phy_to_sphy(phy);
+
+	/* Enable the phy clock */
+	ret = clk_prepare_enable(sphy->clk);
+	if (ret) {
+		dev_err(sphy->dev, "%s: clk_prepare_enable failed\n", __func__);
+		return ret;
+	}
+
+	/* Disable phy isolation */
+	if (sphy->plat && sphy->plat->pmu_isolation)
+		sphy->plat->pmu_isolation(false);
+
+	/* Initialize usb phy registers */
+	samsung_usbphy_enable(sphy);
+
+	/* Disable the phy clock */
+	clk_disable_unprepare(sphy->clk);
+	return ret;
+}
+
+/*
+ * The function passed to the usb driver for phy shutdown
+ */
+static void samsung_usbphy_shutdown(struct usb_phy *phy)
+{
+	struct samsung_usbphy *sphy;
+
+	sphy = phy_to_sphy(phy);
+
+	if (clk_prepare_enable(sphy->clk)) {
+		dev_err(sphy->dev, "%s: clk_prepare_enable failed\n", __func__);
+		return;
+	}
+
+	/* De-initialize usb phy registers */
+	samsung_usbphy_disable(sphy);
+
+	/* Enable phy isolation */
+	if (sphy->plat && sphy->plat->pmu_isolation)
+		sphy->plat->pmu_isolation(true);
+
+	clk_disable_unprepare(sphy->clk);
+}
+
+static const struct of_device_id samsung_usbphy_dt_match[];
+
+static inline int samsung_usbphy_get_driver_data(struct platform_device *pdev)
+{
+	if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node) {
+		int data;
+		const struct of_device_id *match;
+		match = of_match_node(samsung_usbphy_dt_match,
+							pdev->dev.of_node);
+		data = (int) match->data;
+		return data;
+	}
+
+	return platform_get_device_id(pdev)->driver_data;
+}
+
+static int __devinit samsung_usbphy_probe(struct platform_device *pdev)
+{
+	struct samsung_usbphy *sphy;
+	struct samsung_usbphy_data *pdata;
+	struct device *dev = &pdev->dev;
+	struct resource *phy_mem;
+	void __iomem	*phy_base;
+	struct clk *clk;
+	int	ret = 0;
+
+	pdata = pdev->dev.platform_data;
+	if (!pdata) {
+		dev_err(&pdev->dev, "%s: no platform data defined\n", __func__);
+		return -EINVAL;
+	}
+
+	phy_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!phy_mem) {
+		dev_err(dev, "%s: missing mem resource\n", __func__);
+		return -ENODEV;
+	}
+
+	phy_base = devm_request_and_ioremap(dev, phy_mem);
+	if (!phy_base) {
+		dev_err(dev, "%s: register mapping failed\n", __func__);
+		return -ENXIO;
+	}
+
+	sphy = devm_kzalloc(dev, sizeof(*sphy), GFP_KERNEL);
+	if (!sphy)
+		return -ENOMEM;
+
+	clk = devm_clk_get(dev, "otg");
+	if (IS_ERR(clk)) {
+		dev_err(dev, "Failed to get otg clock\n");
+		return PTR_ERR(clk);
+	}
+
+	sphy->dev		= &pdev->dev;
+	sphy->plat		= pdata;
+	sphy->regs		= phy_base;
+	sphy->clk		= clk;
+	sphy->phy.dev		= sphy->dev;
+	sphy->phy.label		= "samsung-usbphy";
+	sphy->phy.init		= samsung_usbphy_init;
+	sphy->phy.shutdown	= samsung_usbphy_shutdown;
+	sphy->cpu_type		= samsung_usbphy_get_driver_data(pdev);
+	sphy->ref_clk_freq	= samsung_usbphy_get_refclk_freq(sphy);
+
+	platform_set_drvdata(pdev, sphy);
+
+	ret = usb_add_phy(&sphy->phy, USB_PHY_TYPE_USB2);
+	return ret;
+}
+
+static int __exit samsung_usbphy_remove(struct platform_device *pdev)
+{
+	struct samsung_usbphy *sphy = platform_get_drvdata(pdev);
+
+	usb_remove_phy(&sphy->phy);
+
+	return 0;
+}
+
+#ifdef CONFIG_OF
+static const struct of_device_id samsung_usbphy_dt_match[] = {
+	{
+		.compatible = "samsung,s3c64xx-usbphy",
+		.data = (void *)TYPE_S3C64XX,
+	}, {
+		.compatible = "samsung,exynos4210-usbphy",
+		.data = (void *)TYPE_EXYNOS4210,
+	},
+	{},
+};
+MODULE_DEVICE_TABLE(of, samsung_usbphy_dt_match);
+#else
+#define samsung_usbphy_dt_match NULL
+#endif
+
+static struct platform_device_id samsung_usbphy_driver_ids[] = {
+	{
+		.name		= "s3c64xx-usbphy",
+		.driver_data	= TYPE_S3C64XX,
+	}, {
+		.name		= "exynos4210-usbphy",
+		.driver_data	= TYPE_EXYNOS4210,
+	},
+	{},
+};
+
+MODULE_DEVICE_TABLE(platform, samsung_usbphy_driver_ids);
+
+static struct platform_driver samsung_usbphy_driver = {
+	.probe		= samsung_usbphy_probe,
+	.remove		= __devexit_p(samsung_usbphy_remove),
+	.id_table	= samsung_usbphy_driver_ids,
+	.driver		= {
+		.name	= "samsung-usbphy",
+		.owner	= THIS_MODULE,
+		.of_match_table = samsung_usbphy_dt_match,
+	},
+};
+
+module_platform_driver(samsung_usbphy_driver);
+
+MODULE_DESCRIPTION("Samsung USB phy controller");
+MODULE_AUTHOR("Praveen Paneri <p.paneri-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:samsung-usbphy");
diff --git a/include/linux/platform_data/samsung-usbphy.h b/include/linux/platform_data/samsung-usbphy.h
new file mode 100644
index 0000000..1bd24cb
--- /dev/null
+++ b/include/linux/platform_data/samsung-usbphy.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2012 Samsung Electronics Co.Ltd
+ *		http://www.samsung.com/
+ * Author: Praveen Paneri <p.paneri-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
+ *
+ * Defines platform data for samsung usb phy driver.
+ *
+ * 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;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#ifndef __SAMSUNG_USBPHY_PLATFORM_H
+#define __SAMSUNG_USBPHY_PLATFORM_H
+
+/**
+ * samsung_usbphy_data - Platform data for USB PHY driver.
+ * @pmu_isolation: Function to control usb phy isolation in PMU.
+ */
+struct samsung_usbphy_data {
+	void (*pmu_isolation)(int on);
+};
+
+extern void samsung_usbphy_set_pdata(struct samsung_usbphy_data *pd);
+
+#endif /* __SAMSUNG_USBPHY_PLATFORM_H */
-- 
1.7.1

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

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

* [PATCH v8 1/2] usb: phy: samsung: Introducing usb phy driver for hsotg
@ 2012-11-14 10:27     ` Praveen Paneri
  0 siblings, 0 replies; 28+ messages in thread
From: Praveen Paneri @ 2012-11-14 10:27 UTC (permalink / raw)
  To: linux-arm-kernel

This driver uses usb_phy interface to interact with s3c-hsotg. Supports
phy_init and phy_shutdown functions to enable/disable usb phy. Support
will be extended to host controllers and more Samsung SoCs.

Signed-off-by: Praveen Paneri <p.paneri@samsung.com>
Acked-by: Heiko Stuebner <heiko@sntech.de>
Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 .../devicetree/bindings/usb/samsung-usbphy.txt     |   11 +
 drivers/usb/phy/Kconfig                            |    8 +
 drivers/usb/phy/Makefile                           |    1 +
 drivers/usb/phy/samsung-usbphy.c                   |  360 ++++++++++++++++++++
 include/linux/platform_data/samsung-usbphy.h       |   27 ++
 5 files changed, 407 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/usb/samsung-usbphy.txt
 create mode 100644 drivers/usb/phy/samsung-usbphy.c
 create mode 100644 include/linux/platform_data/samsung-usbphy.h

diff --git a/Documentation/devicetree/bindings/usb/samsung-usbphy.txt b/Documentation/devicetree/bindings/usb/samsung-usbphy.txt
new file mode 100644
index 0000000..7b26e2d
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/samsung-usbphy.txt
@@ -0,0 +1,11 @@
+* Samsung's usb phy transceiver
+
+The Samsung's phy transceiver is used for controlling usb otg phy for
+s3c-hsotg usb device controller.
+TODO: Adding the PHY binding with controller(s) according to the under
+developement generic PHY driver.
+
+Required properties:
+- compatible : should be "samsung,exynos4210-usbphy"
+- reg : base physical address of the phy registers and length of memory mapped
+	region.
diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig
index 7eb73c5..17ad743 100644
--- a/drivers/usb/phy/Kconfig
+++ b/drivers/usb/phy/Kconfig
@@ -44,3 +44,11 @@ config USB_RCAR_PHY
 
 	  To compile this driver as a module, choose M here: the
 	  module will be called rcar-phy.
+
+config SAMSUNG_USBPHY
+	bool "Samsung USB PHY controller Driver"
+	depends on USB_S3C_HSOTG
+	select USB_OTG_UTILS
+	help
+	  Enable this to support Samsung USB phy controller for samsung
+	  SoCs.
diff --git a/drivers/usb/phy/Makefile b/drivers/usb/phy/Makefile
index 1a579a8..ec304f6 100644
--- a/drivers/usb/phy/Makefile
+++ b/drivers/usb/phy/Makefile
@@ -9,3 +9,4 @@ 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
+obj-$(CONFIG_SAMSUNG_USBPHY)		+= samsung-usbphy.o
diff --git a/drivers/usb/phy/samsung-usbphy.c b/drivers/usb/phy/samsung-usbphy.c
new file mode 100644
index 0000000..3c84aab
--- /dev/null
+++ b/drivers/usb/phy/samsung-usbphy.c
@@ -0,0 +1,360 @@
+/* linux/drivers/usb/phy/samsung-usbphy.c
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *              http://www.samsung.com
+ *
+ * Author: Praveen Paneri <p.paneri@samsung.com>
+ *
+ * Samsung USB2.0 High-speed OTG transceiver, talks to S3C HS OTG controller
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; 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/platform_device.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/usb/otg.h>
+#include <linux/platform_data/samsung-usbphy.h>
+
+/* Register definitions */
+
+#define SAMSUNG_PHYPWR				(0x00)
+
+#define PHYPWR_NORMAL_MASK			(0x19 << 0)
+#define PHYPWR_OTG_DISABLE			(0x1 << 4)
+#define PHYPWR_ANALOG_POWERDOWN			(0x1 << 3)
+#define PHYPWR_FORCE_SUSPEND			(0x1 << 1)
+/* For Exynos4 */
+#define PHYPWR_NORMAL_MASK_PHY0			(0x39 << 0)
+#define PHYPWR_SLEEP_PHY0			(0x1 << 5)
+
+#define SAMSUNG_PHYCLK				(0x04)
+
+#define PHYCLK_MODE_USB11			(0x1 << 6)
+#define PHYCLK_EXT_OSC				(0x1 << 5)
+#define PHYCLK_COMMON_ON_N			(0x1 << 4)
+#define PHYCLK_ID_PULL				(0x1 << 2)
+#define PHYCLK_CLKSEL_MASK			(0x3 << 0)
+#define PHYCLK_CLKSEL_48M			(0x0 << 0)
+#define PHYCLK_CLKSEL_12M			(0x2 << 0)
+#define PHYCLK_CLKSEL_24M			(0x3 << 0)
+
+#define SAMSUNG_RSTCON				(0x08)
+
+#define RSTCON_PHYLINK_SWRST			(0x1 << 2)
+#define RSTCON_HLINK_SWRST			(0x1 << 1)
+#define RSTCON_SWRST				(0x1 << 0)
+
+#ifndef MHZ
+#define MHZ (1000*1000)
+#endif
+
+enum samsung_cpu_type {
+	TYPE_S3C64XX,
+	TYPE_EXYNOS4210,
+};
+
+/*
+ * struct samsung_usbphy - transceiver driver state
+ * @phy: transceiver structure
+ * @plat: platform data
+ * @dev: The parent device supplied to the probe function
+ * @clk: usb phy clock
+ * @regs: usb phy register memory base
+ * @ref_clk_freq: reference clock frequency selection
+ * @cpu_type: machine identifier
+ */
+struct samsung_usbphy {
+	struct usb_phy	phy;
+	struct samsung_usbphy_data *plat;
+	struct device	*dev;
+	struct clk	*clk;
+	void __iomem	*regs;
+	int		ref_clk_freq;
+	int		cpu_type;
+};
+
+#define phy_to_sphy(x)		container_of((x), struct samsung_usbphy, phy)
+
+/*
+ * Returns reference clock frequency selection value
+ */
+static int samsung_usbphy_get_refclk_freq(struct samsung_usbphy *sphy)
+{
+	struct clk *ref_clk;
+	int refclk_freq = 0;
+
+	ref_clk = clk_get(sphy->dev, "xusbxti");
+	if (IS_ERR(ref_clk)) {
+		dev_err(sphy->dev, "Failed to get reference clock\n");
+		return PTR_ERR(ref_clk);
+	}
+
+	switch (clk_get_rate(ref_clk)) {
+	case 12 * MHZ:
+		refclk_freq = PHYCLK_CLKSEL_12M;
+		break;
+	case 24 * MHZ:
+		refclk_freq = PHYCLK_CLKSEL_24M;
+		break;
+	case 48 * MHZ:
+		refclk_freq = PHYCLK_CLKSEL_48M;
+		break;
+	default:
+		if (sphy->cpu_type == TYPE_S3C64XX)
+			refclk_freq = PHYCLK_CLKSEL_48M;
+		else
+			refclk_freq = PHYCLK_CLKSEL_24M;
+		break;
+	}
+	clk_put(ref_clk);
+
+	return refclk_freq;
+}
+
+static void samsung_usbphy_enable(struct samsung_usbphy *sphy)
+{
+	void __iomem *regs = sphy->regs;
+	u32 phypwr;
+	u32 phyclk;
+	u32 rstcon;
+
+	/* set clock frequency for PLL */
+	phyclk = sphy->ref_clk_freq;
+	phypwr = readl(regs + SAMSUNG_PHYPWR);
+	rstcon = readl(regs + SAMSUNG_RSTCON);
+
+	switch (sphy->cpu_type) {
+	case TYPE_S3C64XX:
+		phyclk &= ~PHYCLK_COMMON_ON_N;
+		phypwr &= ~PHYPWR_NORMAL_MASK;
+		rstcon |= RSTCON_SWRST;
+		break;
+	case TYPE_EXYNOS4210:
+		phypwr &= ~PHYPWR_NORMAL_MASK_PHY0;
+		rstcon |= RSTCON_SWRST;
+	default:
+		break;
+	}
+
+	writel(phyclk, regs + SAMSUNG_PHYCLK);
+	/* set to normal of PHY0 */
+	writel(phypwr, regs + SAMSUNG_PHYPWR);
+	/* reset all ports of PHY and Link */
+	writel(rstcon, regs + SAMSUNG_RSTCON);
+	udelay(10);
+	rstcon &= ~RSTCON_SWRST;
+	writel(rstcon, regs + SAMSUNG_RSTCON);
+}
+
+static void samsung_usbphy_disable(struct samsung_usbphy *sphy)
+{
+	void __iomem *regs = sphy->regs;
+	u32 phypwr;
+
+	phypwr = readl(regs + SAMSUNG_PHYPWR);
+
+	switch (sphy->cpu_type) {
+	case TYPE_S3C64XX:
+		phypwr |= PHYPWR_NORMAL_MASK;
+		break;
+	case TYPE_EXYNOS4210:
+		phypwr |= PHYPWR_NORMAL_MASK_PHY0;
+	default:
+		break;
+	}
+
+	/* unset to normal of PHY0 */
+	writel(phypwr, regs + SAMSUNG_PHYPWR);
+}
+
+/*
+ * The function passed to the usb driver for phy initialization
+ */
+static int samsung_usbphy_init(struct usb_phy *phy)
+{
+	struct samsung_usbphy *sphy;
+	int ret = 0;
+
+	sphy = phy_to_sphy(phy);
+
+	/* Enable the phy clock */
+	ret = clk_prepare_enable(sphy->clk);
+	if (ret) {
+		dev_err(sphy->dev, "%s: clk_prepare_enable failed\n", __func__);
+		return ret;
+	}
+
+	/* Disable phy isolation */
+	if (sphy->plat && sphy->plat->pmu_isolation)
+		sphy->plat->pmu_isolation(false);
+
+	/* Initialize usb phy registers */
+	samsung_usbphy_enable(sphy);
+
+	/* Disable the phy clock */
+	clk_disable_unprepare(sphy->clk);
+	return ret;
+}
+
+/*
+ * The function passed to the usb driver for phy shutdown
+ */
+static void samsung_usbphy_shutdown(struct usb_phy *phy)
+{
+	struct samsung_usbphy *sphy;
+
+	sphy = phy_to_sphy(phy);
+
+	if (clk_prepare_enable(sphy->clk)) {
+		dev_err(sphy->dev, "%s: clk_prepare_enable failed\n", __func__);
+		return;
+	}
+
+	/* De-initialize usb phy registers */
+	samsung_usbphy_disable(sphy);
+
+	/* Enable phy isolation */
+	if (sphy->plat && sphy->plat->pmu_isolation)
+		sphy->plat->pmu_isolation(true);
+
+	clk_disable_unprepare(sphy->clk);
+}
+
+static const struct of_device_id samsung_usbphy_dt_match[];
+
+static inline int samsung_usbphy_get_driver_data(struct platform_device *pdev)
+{
+	if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node) {
+		int data;
+		const struct of_device_id *match;
+		match = of_match_node(samsung_usbphy_dt_match,
+							pdev->dev.of_node);
+		data = (int) match->data;
+		return data;
+	}
+
+	return platform_get_device_id(pdev)->driver_data;
+}
+
+static int __devinit samsung_usbphy_probe(struct platform_device *pdev)
+{
+	struct samsung_usbphy *sphy;
+	struct samsung_usbphy_data *pdata;
+	struct device *dev = &pdev->dev;
+	struct resource *phy_mem;
+	void __iomem	*phy_base;
+	struct clk *clk;
+	int	ret = 0;
+
+	pdata = pdev->dev.platform_data;
+	if (!pdata) {
+		dev_err(&pdev->dev, "%s: no platform data defined\n", __func__);
+		return -EINVAL;
+	}
+
+	phy_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!phy_mem) {
+		dev_err(dev, "%s: missing mem resource\n", __func__);
+		return -ENODEV;
+	}
+
+	phy_base = devm_request_and_ioremap(dev, phy_mem);
+	if (!phy_base) {
+		dev_err(dev, "%s: register mapping failed\n", __func__);
+		return -ENXIO;
+	}
+
+	sphy = devm_kzalloc(dev, sizeof(*sphy), GFP_KERNEL);
+	if (!sphy)
+		return -ENOMEM;
+
+	clk = devm_clk_get(dev, "otg");
+	if (IS_ERR(clk)) {
+		dev_err(dev, "Failed to get otg clock\n");
+		return PTR_ERR(clk);
+	}
+
+	sphy->dev		= &pdev->dev;
+	sphy->plat		= pdata;
+	sphy->regs		= phy_base;
+	sphy->clk		= clk;
+	sphy->phy.dev		= sphy->dev;
+	sphy->phy.label		= "samsung-usbphy";
+	sphy->phy.init		= samsung_usbphy_init;
+	sphy->phy.shutdown	= samsung_usbphy_shutdown;
+	sphy->cpu_type		= samsung_usbphy_get_driver_data(pdev);
+	sphy->ref_clk_freq	= samsung_usbphy_get_refclk_freq(sphy);
+
+	platform_set_drvdata(pdev, sphy);
+
+	ret = usb_add_phy(&sphy->phy, USB_PHY_TYPE_USB2);
+	return ret;
+}
+
+static int __exit samsung_usbphy_remove(struct platform_device *pdev)
+{
+	struct samsung_usbphy *sphy = platform_get_drvdata(pdev);
+
+	usb_remove_phy(&sphy->phy);
+
+	return 0;
+}
+
+#ifdef CONFIG_OF
+static const struct of_device_id samsung_usbphy_dt_match[] = {
+	{
+		.compatible = "samsung,s3c64xx-usbphy",
+		.data = (void *)TYPE_S3C64XX,
+	}, {
+		.compatible = "samsung,exynos4210-usbphy",
+		.data = (void *)TYPE_EXYNOS4210,
+	},
+	{},
+};
+MODULE_DEVICE_TABLE(of, samsung_usbphy_dt_match);
+#else
+#define samsung_usbphy_dt_match NULL
+#endif
+
+static struct platform_device_id samsung_usbphy_driver_ids[] = {
+	{
+		.name		= "s3c64xx-usbphy",
+		.driver_data	= TYPE_S3C64XX,
+	}, {
+		.name		= "exynos4210-usbphy",
+		.driver_data	= TYPE_EXYNOS4210,
+	},
+	{},
+};
+
+MODULE_DEVICE_TABLE(platform, samsung_usbphy_driver_ids);
+
+static struct platform_driver samsung_usbphy_driver = {
+	.probe		= samsung_usbphy_probe,
+	.remove		= __devexit_p(samsung_usbphy_remove),
+	.id_table	= samsung_usbphy_driver_ids,
+	.driver		= {
+		.name	= "samsung-usbphy",
+		.owner	= THIS_MODULE,
+		.of_match_table = samsung_usbphy_dt_match,
+	},
+};
+
+module_platform_driver(samsung_usbphy_driver);
+
+MODULE_DESCRIPTION("Samsung USB phy controller");
+MODULE_AUTHOR("Praveen Paneri <p.paneri@samsung.com>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:samsung-usbphy");
diff --git a/include/linux/platform_data/samsung-usbphy.h b/include/linux/platform_data/samsung-usbphy.h
new file mode 100644
index 0000000..1bd24cb
--- /dev/null
+++ b/include/linux/platform_data/samsung-usbphy.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2012 Samsung Electronics Co.Ltd
+ *		http://www.samsung.com/
+ * Author: Praveen Paneri <p.paneri@samsung.com>
+ *
+ * Defines platform data for samsung usb phy driver.
+ *
+ * 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;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#ifndef __SAMSUNG_USBPHY_PLATFORM_H
+#define __SAMSUNG_USBPHY_PLATFORM_H
+
+/**
+ * samsung_usbphy_data - Platform data for USB PHY driver.
+ * @pmu_isolation: Function to control usb phy isolation in PMU.
+ */
+struct samsung_usbphy_data {
+	void (*pmu_isolation)(int on);
+};
+
+extern void samsung_usbphy_set_pdata(struct samsung_usbphy_data *pd);
+
+#endif /* __SAMSUNG_USBPHY_PLATFORM_H */
-- 
1.7.1

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

* [PATCH v8 2/2] usb: s3c-hsotg: Adding phy driver support
  2012-11-14 10:27 ` Praveen Paneri
@ 2012-11-14 10:27   ` Praveen Paneri
  -1 siblings, 0 replies; 28+ messages in thread
From: Praveen Paneri @ 2012-11-14 10:27 UTC (permalink / raw)
  To: linux-usb
  Cc: devicetree-discuss, linux-arm-kernel, linux-samsung-soc,
	kgene.kim, balbi, gregkh, thomas.abraham, ben-linux, broonie,
	l.majewski, kyungmin.park, grant.likely, heiko, t.figa,
	gautam.vivek

Adding the transceiver to hsotg driver. Keeping the platform data
for continuing the smooth operation for boards which still uses it

Signed-off-by: Praveen Paneri <p.paneri@samsung.com>
Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 drivers/usb/gadget/s3c-hsotg.c |   37 +++++++++++++++++++++++++++----------
 1 files changed, 27 insertions(+), 10 deletions(-)

diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c
index 6f696ee..bc30a2d 100644
--- a/drivers/usb/gadget/s3c-hsotg.c
+++ b/drivers/usb/gadget/s3c-hsotg.c
@@ -32,6 +32,7 @@
 
 #include <linux/usb/ch9.h>
 #include <linux/usb/gadget.h>
+#include <linux/usb/phy.h>
 #include <linux/platform_data/s3c-hsotg.h>
 
 #include <mach/map.h>
@@ -133,7 +134,9 @@ struct s3c_hsotg_ep {
  * struct s3c_hsotg - driver state.
  * @dev: The parent device supplied to the probe function
  * @driver: USB gadget driver
- * @plat: The platform specific configuration data.
+ * @phy: The otg phy transceiver structure for phy control.
+ * @plat: The platform specific configuration data. This can be removed once
+ * all SoCs support usb transceiver.
  * @regs: The memory area mapped for accessing registers.
  * @irq: The IRQ number we are using
  * @supplies: Definition of USB power supplies
@@ -153,6 +156,7 @@ struct s3c_hsotg_ep {
 struct s3c_hsotg {
 	struct device		 *dev;
 	struct usb_gadget_driver *driver;
+	struct usb_phy		*phy;
 	struct s3c_hsotg_plat	 *plat;
 
 	spinlock_t              lock;
@@ -2854,7 +2858,10 @@ static void s3c_hsotg_phy_enable(struct s3c_hsotg *hsotg)
 	struct platform_device *pdev = to_platform_device(hsotg->dev);
 
 	dev_dbg(hsotg->dev, "pdev 0x%p\n", pdev);
-	if (hsotg->plat->phy_init)
+
+	if (hsotg->phy)
+		usb_phy_init(hsotg->phy);
+	else if (hsotg->plat->phy_init)
 		hsotg->plat->phy_init(pdev, hsotg->plat->phy_type);
 }
 
@@ -2869,7 +2876,9 @@ static void s3c_hsotg_phy_disable(struct s3c_hsotg *hsotg)
 {
 	struct platform_device *pdev = to_platform_device(hsotg->dev);
 
-	if (hsotg->plat->phy_exit)
+	if (hsotg->phy)
+		usb_phy_shutdown(hsotg->phy);
+	else if (hsotg->plat->phy_exit)
 		hsotg->plat->phy_exit(pdev, hsotg->plat->phy_type);
 }
 
@@ -3493,6 +3502,7 @@ static void s3c_hsotg_release(struct device *dev)
 static int __devinit s3c_hsotg_probe(struct platform_device *pdev)
 {
 	struct s3c_hsotg_plat *plat = pdev->dev.platform_data;
+	struct usb_phy *phy;
 	struct device *dev = &pdev->dev;
 	struct s3c_hsotg_ep *eps;
 	struct s3c_hsotg *hsotg;
@@ -3501,20 +3511,27 @@ static int __devinit s3c_hsotg_probe(struct platform_device *pdev)
 	int ret;
 	int i;
 
-	plat = pdev->dev.platform_data;
-	if (!plat) {
-		dev_err(&pdev->dev, "no platform data defined\n");
-		return -EINVAL;
-	}
-
 	hsotg = devm_kzalloc(&pdev->dev, sizeof(struct s3c_hsotg), GFP_KERNEL);
 	if (!hsotg) {
 		dev_err(dev, "cannot get memory\n");
 		return -ENOMEM;
 	}
 
+	phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2);
+	if (IS_ERR_OR_NULL(phy)) {
+		/* Fallback for pdata */
+		plat = pdev->dev.platform_data;
+		if (!plat) {
+			dev_err(&pdev->dev, "no platform data or transceiver defined\n");
+			return -EPROBE_DEFER;
+		} else {
+			hsotg->plat = plat;
+		}
+	} else {
+		hsotg->phy = phy;
+	}
+
 	hsotg->dev = dev;
-	hsotg->plat = plat;
 
 	hsotg->clk = devm_clk_get(&pdev->dev, "otg");
 	if (IS_ERR(hsotg->clk)) {
-- 
1.7.1

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

* [PATCH v8 2/2] usb: s3c-hsotg: Adding phy driver support
@ 2012-11-14 10:27   ` Praveen Paneri
  0 siblings, 0 replies; 28+ messages in thread
From: Praveen Paneri @ 2012-11-14 10:27 UTC (permalink / raw)
  To: linux-arm-kernel

Adding the transceiver to hsotg driver. Keeping the platform data
for continuing the smooth operation for boards which still uses it

Signed-off-by: Praveen Paneri <p.paneri@samsung.com>
Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 drivers/usb/gadget/s3c-hsotg.c |   37 +++++++++++++++++++++++++++----------
 1 files changed, 27 insertions(+), 10 deletions(-)

diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c
index 6f696ee..bc30a2d 100644
--- a/drivers/usb/gadget/s3c-hsotg.c
+++ b/drivers/usb/gadget/s3c-hsotg.c
@@ -32,6 +32,7 @@
 
 #include <linux/usb/ch9.h>
 #include <linux/usb/gadget.h>
+#include <linux/usb/phy.h>
 #include <linux/platform_data/s3c-hsotg.h>
 
 #include <mach/map.h>
@@ -133,7 +134,9 @@ struct s3c_hsotg_ep {
  * struct s3c_hsotg - driver state.
  * @dev: The parent device supplied to the probe function
  * @driver: USB gadget driver
- * @plat: The platform specific configuration data.
+ * @phy: The otg phy transceiver structure for phy control.
+ * @plat: The platform specific configuration data. This can be removed once
+ * all SoCs support usb transceiver.
  * @regs: The memory area mapped for accessing registers.
  * @irq: The IRQ number we are using
  * @supplies: Definition of USB power supplies
@@ -153,6 +156,7 @@ struct s3c_hsotg_ep {
 struct s3c_hsotg {
 	struct device		 *dev;
 	struct usb_gadget_driver *driver;
+	struct usb_phy		*phy;
 	struct s3c_hsotg_plat	 *plat;
 
 	spinlock_t              lock;
@@ -2854,7 +2858,10 @@ static void s3c_hsotg_phy_enable(struct s3c_hsotg *hsotg)
 	struct platform_device *pdev = to_platform_device(hsotg->dev);
 
 	dev_dbg(hsotg->dev, "pdev 0x%p\n", pdev);
-	if (hsotg->plat->phy_init)
+
+	if (hsotg->phy)
+		usb_phy_init(hsotg->phy);
+	else if (hsotg->plat->phy_init)
 		hsotg->plat->phy_init(pdev, hsotg->plat->phy_type);
 }
 
@@ -2869,7 +2876,9 @@ static void s3c_hsotg_phy_disable(struct s3c_hsotg *hsotg)
 {
 	struct platform_device *pdev = to_platform_device(hsotg->dev);
 
-	if (hsotg->plat->phy_exit)
+	if (hsotg->phy)
+		usb_phy_shutdown(hsotg->phy);
+	else if (hsotg->plat->phy_exit)
 		hsotg->plat->phy_exit(pdev, hsotg->plat->phy_type);
 }
 
@@ -3493,6 +3502,7 @@ static void s3c_hsotg_release(struct device *dev)
 static int __devinit s3c_hsotg_probe(struct platform_device *pdev)
 {
 	struct s3c_hsotg_plat *plat = pdev->dev.platform_data;
+	struct usb_phy *phy;
 	struct device *dev = &pdev->dev;
 	struct s3c_hsotg_ep *eps;
 	struct s3c_hsotg *hsotg;
@@ -3501,20 +3511,27 @@ static int __devinit s3c_hsotg_probe(struct platform_device *pdev)
 	int ret;
 	int i;
 
-	plat = pdev->dev.platform_data;
-	if (!plat) {
-		dev_err(&pdev->dev, "no platform data defined\n");
-		return -EINVAL;
-	}
-
 	hsotg = devm_kzalloc(&pdev->dev, sizeof(struct s3c_hsotg), GFP_KERNEL);
 	if (!hsotg) {
 		dev_err(dev, "cannot get memory\n");
 		return -ENOMEM;
 	}
 
+	phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2);
+	if (IS_ERR_OR_NULL(phy)) {
+		/* Fallback for pdata */
+		plat = pdev->dev.platform_data;
+		if (!plat) {
+			dev_err(&pdev->dev, "no platform data or transceiver defined\n");
+			return -EPROBE_DEFER;
+		} else {
+			hsotg->plat = plat;
+		}
+	} else {
+		hsotg->phy = phy;
+	}
+
 	hsotg->dev = dev;
-	hsotg->plat = plat;
 
 	hsotg->clk = devm_clk_get(&pdev->dev, "otg");
 	if (IS_ERR(hsotg->clk)) {
-- 
1.7.1

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

* Re: [PATCH v8 1/2] usb: phy: samsung: Introducing usb phy driver for hsotg
  2012-11-14 10:27     ` Praveen Paneri
@ 2012-11-21 20:06         ` Tomasz Figa
  -1 siblings, 0 replies; 28+ messages in thread
From: Tomasz Figa @ 2012-11-21 20:06 UTC (permalink / raw)
  To: Praveen Paneri
  Cc: linux-usb-u79uwXL29TY76Z2rM5mHXA,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-samsung-soc-u79uwXL29TY76Z2rM5mHXA,
	kgene.kim-Sze3O3UU22JBDgjK7y7TUQ, balbi-l0cyMroinI0,
	gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
	thomas.abraham-QSEj5FYQhm4dnm+yROfE0A,
	ben-linux-elnMNo+KYs3YtjvyW6yDsg,
	broonie-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E,
	l.majewski-Sze3O3UU22JBDgjK7y7TUQ,
	kyungmin.park-Sze3O3UU22JBDgjK7y7TUQ,
	grant.likely-s3s/WqlpOiPyB63q8FvJNQ,
	heiko-4mtYJXux2i+zQB+pC5nmwQ, t.figa-Sze3O3UU22JBDgjK7y7TUQ,
	gautam.vivek-Sze3O3UU22JBDgjK7y7TUQ

Hi Praveen,

See some minor comments inline.

On Wednesday 14 of November 2012 15:57:15 Praveen Paneri wrote:
> This driver uses usb_phy interface to interact with s3c-hsotg. Supports
> phy_init and phy_shutdown functions to enable/disable usb phy. Support
> will be extended to host controllers and more Samsung SoCs.
> 
> Signed-off-by: Praveen Paneri <p.paneri-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
> Acked-by: Heiko Stuebner <heiko-4mtYJXux2i+zQB+pC5nmwQ@public.gmane.org>
> Acked-by: Kyungmin Park <kyungmin.park-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
> ---
>  .../devicetree/bindings/usb/samsung-usbphy.txt     |   11 +
>  drivers/usb/phy/Kconfig                            |    8 +
>  drivers/usb/phy/Makefile                           |    1 +
>  drivers/usb/phy/samsung-usbphy.c                   |  360
> ++++++++++++++++++++ include/linux/platform_data/samsung-usbphy.h      
> |   27 ++
>  5 files changed, 407 insertions(+), 0 deletions(-)
>  create mode 100644
> Documentation/devicetree/bindings/usb/samsung-usbphy.txt create mode
> 100644 drivers/usb/phy/samsung-usbphy.c
>  create mode 100644 include/linux/platform_data/samsung-usbphy.h
> 
> diff --git a/Documentation/devicetree/bindings/usb/samsung-usbphy.txt
> b/Documentation/devicetree/bindings/usb/samsung-usbphy.txt new file
> mode 100644
> index 0000000..7b26e2d
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/usb/samsung-usbphy.txt
> @@ -0,0 +1,11 @@
> +* Samsung's usb phy transceiver
> +
> +The Samsung's phy transceiver is used for controlling usb otg phy for
> +s3c-hsotg usb device controller.
> +TODO: Adding the PHY binding with controller(s) according to the under
> +developement generic PHY driver.
> +
> +Required properties:
> +- compatible : should be "samsung,exynos4210-usbphy"
> +- reg : base physical address of the phy registers and length of memory
> mapped +	region.
> diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig
> index 7eb73c5..17ad743 100644
> --- a/drivers/usb/phy/Kconfig
> +++ b/drivers/usb/phy/Kconfig
> @@ -44,3 +44,11 @@ config USB_RCAR_PHY
> 
>  	  To compile this driver as a module, choose M here: the
>  	  module will be called rcar-phy.
> +
> +config SAMSUNG_USBPHY
> +	bool "Samsung USB PHY controller Driver"
> +	depends on USB_S3C_HSOTG
> +	select USB_OTG_UTILS
> +	help
> +	  Enable this to support Samsung USB phy controller for samsung
> +	  SoCs.
> diff --git a/drivers/usb/phy/Makefile b/drivers/usb/phy/Makefile
> index 1a579a8..ec304f6 100644
> --- a/drivers/usb/phy/Makefile
> +++ b/drivers/usb/phy/Makefile
> @@ -9,3 +9,4 @@ 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
> +obj-$(CONFIG_SAMSUNG_USBPHY)		+= samsung-usbphy.o
> diff --git a/drivers/usb/phy/samsung-usbphy.c
> b/drivers/usb/phy/samsung-usbphy.c new file mode 100644
> index 0000000..3c84aab
> --- /dev/null
> +++ b/drivers/usb/phy/samsung-usbphy.c
> @@ -0,0 +1,360 @@
> +/* linux/drivers/usb/phy/samsung-usbphy.c
> + *
> + * Copyright (c) 2012 Samsung Electronics Co., Ltd.
> + *              http://www.samsung.com
> + *
> + * Author: Praveen Paneri <p.paneri-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
> + *
> + * Samsung USB2.0 High-speed OTG transceiver, talks to S3C HS OTG
> controller + *
> + * 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.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; 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/platform_device.h>
> +#include <linux/clk.h>
> +#include <linux/delay.h>
> +#include <linux/err.h>
> +#include <linux/io.h>
> +#include <linux/of.h>
> +#include <linux/usb/otg.h>
> +#include <linux/platform_data/samsung-usbphy.h>
> +
> +/* Register definitions */
> +
> +#define SAMSUNG_PHYPWR				(0x00)
> +
> +#define PHYPWR_NORMAL_MASK			(0x19 << 0)
> +#define PHYPWR_OTG_DISABLE			(0x1 << 4)
> +#define PHYPWR_ANALOG_POWERDOWN			(0x1 << 3)
> +#define PHYPWR_FORCE_SUSPEND			(0x1 << 1)
> +/* For Exynos4 */
> +#define PHYPWR_NORMAL_MASK_PHY0			(0x39 << 0)
> +#define PHYPWR_SLEEP_PHY0			(0x1 << 5)
> +
> +#define SAMSUNG_PHYCLK				(0x04)
> +
> +#define PHYCLK_MODE_USB11			(0x1 << 6)
> +#define PHYCLK_EXT_OSC				(0x1 << 5)
> +#define PHYCLK_COMMON_ON_N			(0x1 << 4)
> +#define PHYCLK_ID_PULL				(0x1 << 2)
> +#define PHYCLK_CLKSEL_MASK			(0x3 << 0)
> +#define PHYCLK_CLKSEL_48M			(0x0 << 0)
> +#define PHYCLK_CLKSEL_12M			(0x2 << 0)
> +#define PHYCLK_CLKSEL_24M			(0x3 << 0)
> +
> +#define SAMSUNG_RSTCON				(0x08)
> +
> +#define RSTCON_PHYLINK_SWRST			(0x1 << 2)
> +#define RSTCON_HLINK_SWRST			(0x1 << 1)
> +#define RSTCON_SWRST				(0x1 << 0)
> +
> +#ifndef MHZ
> +#define MHZ (1000*1000)
> +#endif
> +
> +enum samsung_cpu_type {
> +	TYPE_S3C64XX,
> +	TYPE_EXYNOS4210,
> +};
> +
> +/*
> + * struct samsung_usbphy - transceiver driver state
> + * @phy: transceiver structure
> + * @plat: platform data
> + * @dev: The parent device supplied to the probe function
> + * @clk: usb phy clock
> + * @regs: usb phy register memory base
> + * @ref_clk_freq: reference clock frequency selection
> + * @cpu_type: machine identifier
> + */
> +struct samsung_usbphy {
> +	struct usb_phy	phy;
> +	struct samsung_usbphy_data *plat;
> +	struct device	*dev;
> +	struct clk	*clk;
> +	void __iomem	*regs;
> +	int		ref_clk_freq;
> +	int		cpu_type;
> +};
> +
> +#define phy_to_sphy(x)		container_of((x), struct samsung_usbphy, 
phy)
> +
> +/*
> + * Returns reference clock frequency selection value
> + */
> +static int samsung_usbphy_get_refclk_freq(struct samsung_usbphy *sphy)
> +{
> +	struct clk *ref_clk;
> +	int refclk_freq = 0;
> +
> +	ref_clk = clk_get(sphy->dev, "xusbxti");
> +	if (IS_ERR(ref_clk)) {
> +		dev_err(sphy->dev, "Failed to get reference clock\n");
> +		return PTR_ERR(ref_clk);
> +	}
> +
> +	switch (clk_get_rate(ref_clk)) {
> +	case 12 * MHZ:
> +		refclk_freq = PHYCLK_CLKSEL_12M;
> +		break;
> +	case 24 * MHZ:
> +		refclk_freq = PHYCLK_CLKSEL_24M;
> +		break;
> +	case 48 * MHZ:
> +		refclk_freq = PHYCLK_CLKSEL_48M;
> +		break;
> +	default:
> +		if (sphy->cpu_type == TYPE_S3C64XX)
> +			refclk_freq = PHYCLK_CLKSEL_48M;
> +		else
> +			refclk_freq = PHYCLK_CLKSEL_24M;
> +		break;
> +	}
> +	clk_put(ref_clk);
> +
> +	return refclk_freq;
> +}
> +
> +static void samsung_usbphy_enable(struct samsung_usbphy *sphy)
> +{
> +	void __iomem *regs = sphy->regs;
> +	u32 phypwr;
> +	u32 phyclk;
> +	u32 rstcon;
> +
> +	/* set clock frequency for PLL */
> +	phyclk = sphy->ref_clk_freq;
> +	phypwr = readl(regs + SAMSUNG_PHYPWR);
> +	rstcon = readl(regs + SAMSUNG_RSTCON);
> +
> +	switch (sphy->cpu_type) {
> +	case TYPE_S3C64XX:
> +		phyclk &= ~PHYCLK_COMMON_ON_N;
> +		phypwr &= ~PHYPWR_NORMAL_MASK;
> +		rstcon |= RSTCON_SWRST;
> +		break;
> +	case TYPE_EXYNOS4210:
> +		phypwr &= ~PHYPWR_NORMAL_MASK_PHY0;
> +		rstcon |= RSTCON_SWRST;
> +	default:
> +		break;
> +	}
> +
> +	writel(phyclk, regs + SAMSUNG_PHYCLK);
> +	/* set to normal of PHY0 */

I don't understand this comment.

> +	writel(phypwr, regs + SAMSUNG_PHYPWR);
> +	/* reset all ports of PHY and Link */
> +	writel(rstcon, regs + SAMSUNG_RSTCON);
> +	udelay(10);
> +	rstcon &= ~RSTCON_SWRST;
> +	writel(rstcon, regs + SAMSUNG_RSTCON);
> +}
> +
> +static void samsung_usbphy_disable(struct samsung_usbphy *sphy)
> +{
> +	void __iomem *regs = sphy->regs;
> +	u32 phypwr;
> +
> +	phypwr = readl(regs + SAMSUNG_PHYPWR);
> +
> +	switch (sphy->cpu_type) {
> +	case TYPE_S3C64XX:
> +		phypwr |= PHYPWR_NORMAL_MASK;
> +		break;
> +	case TYPE_EXYNOS4210:
> +		phypwr |= PHYPWR_NORMAL_MASK_PHY0;
> +	default:
> +		break;
> +	}
> +
> +	/* unset to normal of PHY0 */

I don't understand this comment.

> +	writel(phypwr, regs + SAMSUNG_PHYPWR);
> +}
> +
> +/*
> + * The function passed to the usb driver for phy initialization
> + */
> +static int samsung_usbphy_init(struct usb_phy *phy)
> +{
> +	struct samsung_usbphy *sphy;
> +	int ret = 0;
> +
> +	sphy = phy_to_sphy(phy);
> +
> +	/* Enable the phy clock */
> +	ret = clk_prepare_enable(sphy->clk);
> +	if (ret) {
> +		dev_err(sphy->dev, "%s: clk_prepare_enable failed\n", 
__func__);
> +		return ret;
> +	}
> +
> +	/* Disable phy isolation */
> +	if (sphy->plat && sphy->plat->pmu_isolation)
> +		sphy->plat->pmu_isolation(false);
> +
> +	/* Initialize usb phy registers */
> +	samsung_usbphy_enable(sphy);
> +
> +	/* Disable the phy clock */
> +	clk_disable_unprepare(sphy->clk);
> +	return ret;
> +}
> +
> +/*
> + * The function passed to the usb driver for phy shutdown
> + */
> +static void samsung_usbphy_shutdown(struct usb_phy *phy)
> +{
> +	struct samsung_usbphy *sphy;
> +
> +	sphy = phy_to_sphy(phy);
> +
> +	if (clk_prepare_enable(sphy->clk)) {
> +		dev_err(sphy->dev, "%s: clk_prepare_enable failed\n", 
__func__);
> +		return;
> +	}
> +
> +	/* De-initialize usb phy registers */
> +	samsung_usbphy_disable(sphy);
> +
> +	/* Enable phy isolation */
> +	if (sphy->plat && sphy->plat->pmu_isolation)
> +		sphy->plat->pmu_isolation(true);
> +
> +	clk_disable_unprepare(sphy->clk);
> +}
> +
> +static const struct of_device_id samsung_usbphy_dt_match[];
> +
> +static inline int samsung_usbphy_get_driver_data(struct platform_device
> *pdev) +{
> +	if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node) {

if (pdev->dev.of_node) {

CONFIG_OF is not needed to check whether dev.of_node is not NULL and if 
dev.of_node is always NULL with CONFIG_OF disabled, so this check is 
enough.

> +		int data;

You can remove this variable and...

> +		const struct of_device_id *match;
> +		match = of_match_node(samsung_usbphy_dt_match,
> +							pdev->dev.of_node);
> +		data = (int) match->data;
> +		return data;

return (int) match->data;

> +	}
> +
> +	return platform_get_device_id(pdev)->driver_data;
> +}
> +
> +static int __devinit samsung_usbphy_probe(struct platform_device *pdev)
> +{
> +	struct samsung_usbphy *sphy;
> +	struct samsung_usbphy_data *pdata;
> +	struct device *dev = &pdev->dev;
> +	struct resource *phy_mem;
> +	void __iomem	*phy_base;
> +	struct clk *clk;
> +	int	ret = 0;
> +
> +	pdata = pdev->dev.platform_data;
> +	if (!pdata) {
> +		dev_err(&pdev->dev, "%s: no platform data defined\n", 
__func__);
> +		return -EINVAL;
> +	}
> +
> +	phy_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	if (!phy_mem) {
> +		dev_err(dev, "%s: missing mem resource\n", __func__);
> +		return -ENODEV;
> +	}
> +
> +	phy_base = devm_request_and_ioremap(dev, phy_mem);
> +	if (!phy_base) {
> +		dev_err(dev, "%s: register mapping failed\n", __func__);
> +		return -ENXIO;
> +	}
> +
> +	sphy = devm_kzalloc(dev, sizeof(*sphy), GFP_KERNEL);
> +	if (!sphy)
> +		return -ENOMEM;
> +
> +	clk = devm_clk_get(dev, "otg");
> +	if (IS_ERR(clk)) {
> +		dev_err(dev, "Failed to get otg clock\n");
> +		return PTR_ERR(clk);
> +	}
> +
> +	sphy->dev		= &pdev->dev;
> +	sphy->plat		= pdata;
> +	sphy->regs		= phy_base;
> +	sphy->clk		= clk;
> +	sphy->phy.dev		= sphy->dev;
> +	sphy->phy.label		= "samsung-usbphy";
> +	sphy->phy.init		= samsung_usbphy_init;
> +	sphy->phy.shutdown	= samsung_usbphy_shutdown;
> +	sphy->cpu_type		= samsung_usbphy_get_driver_data(pdev);
> +	sphy->ref_clk_freq	= samsung_usbphy_get_refclk_freq(sphy);
> +
> +	platform_set_drvdata(pdev, sphy);
> +
> +	ret = usb_add_phy(&sphy->phy, USB_PHY_TYPE_USB2);
> +	return ret;

return usb_add_phy(&sphy->phy, USB_PHY_TYPE_USB2);

> +}
> +
> +static int __exit samsung_usbphy_remove(struct platform_device *pdev)
> +{
> +	struct samsung_usbphy *sphy = platform_get_drvdata(pdev);
> +
> +	usb_remove_phy(&sphy->phy);
> +
> +	return 0;
> +}
> +
> +#ifdef CONFIG_OF
> +static const struct of_device_id samsung_usbphy_dt_match[] = {
> +	{
> +		.compatible = "samsung,s3c64xx-usbphy",
> +		.data = (void *)TYPE_S3C64XX,
> +	}, {
> +		.compatible = "samsung,exynos4210-usbphy",
> +		.data = (void *)TYPE_EXYNOS4210,
> +	},
> +	{},
> +};
> +MODULE_DEVICE_TABLE(of, samsung_usbphy_dt_match);
> +#else
> +#define samsung_usbphy_dt_match NULL
> +#endif

Instead of using else and defining samsung_usbphy_dt_match manually, 
instead you can use of_match_ptr macro. (See my next comment.)

> +
> +static struct platform_device_id samsung_usbphy_driver_ids[] = {
> +	{
> +		.name		= "s3c64xx-usbphy",
> +		.driver_data	= TYPE_S3C64XX,
> +	}, {
> +		.name		= "exynos4210-usbphy",
> +		.driver_data	= TYPE_EXYNOS4210,
> +	},
> +	{},
> +};
> +
> +MODULE_DEVICE_TABLE(platform, samsung_usbphy_driver_ids);
> +
> +static struct platform_driver samsung_usbphy_driver = {
> +	.probe		= samsung_usbphy_probe,
> +	.remove		= __devexit_p(samsung_usbphy_remove),
> +	.id_table	= samsung_usbphy_driver_ids,
> +	.driver		= {
> +		.name	= "samsung-usbphy",
> +		.owner	= THIS_MODULE,
> +		.of_match_table = samsung_usbphy_dt_match,

.of_match_table = of_match_ptr(samsung_usbphy_dt_match),

> +	},
> +};
> +
> +module_platform_driver(samsung_usbphy_driver);
> +
> +MODULE_DESCRIPTION("Samsung USB phy controller");
> +MODULE_AUTHOR("Praveen Paneri <p.paneri-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>");
> +MODULE_LICENSE("GPL");
> +MODULE_ALIAS("platform:samsung-usbphy");
> diff --git a/include/linux/platform_data/samsung-usbphy.h
> b/include/linux/platform_data/samsung-usbphy.h new file mode 100644
> index 0000000..1bd24cb
> --- /dev/null
> +++ b/include/linux/platform_data/samsung-usbphy.h
> @@ -0,0 +1,27 @@
> +/*
> + * Copyright (C) 2012 Samsung Electronics Co.Ltd
> + *		http://www.samsung.com/
> + * Author: Praveen Paneri <p.paneri-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
> + *
> + * Defines platform data for samsung usb phy driver.
> + *
> + * 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;  either version 2 of the
>  License, or (at your + * option) any later version.
> + */
> +
> +#ifndef __SAMSUNG_USBPHY_PLATFORM_H
> +#define __SAMSUNG_USBPHY_PLATFORM_H
> +
> +/**
> + * samsung_usbphy_data - Platform data for USB PHY driver.
> + * @pmu_isolation: Function to control usb phy isolation in PMU.
> + */
> +struct samsung_usbphy_data {
> +	void (*pmu_isolation)(int on);

I believe this should be named in a generic way. This is called PMU 
isolation on Exynos SoCs, but on S3C64xx it's USB PHY mask.

Best regards,
Tomasz Figa

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

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

* [PATCH v8 1/2] usb: phy: samsung: Introducing usb phy driver for hsotg
@ 2012-11-21 20:06         ` Tomasz Figa
  0 siblings, 0 replies; 28+ messages in thread
From: Tomasz Figa @ 2012-11-21 20:06 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Praveen,

See some minor comments inline.

On Wednesday 14 of November 2012 15:57:15 Praveen Paneri wrote:
> This driver uses usb_phy interface to interact with s3c-hsotg. Supports
> phy_init and phy_shutdown functions to enable/disable usb phy. Support
> will be extended to host controllers and more Samsung SoCs.
> 
> Signed-off-by: Praveen Paneri <p.paneri@samsung.com>
> Acked-by: Heiko Stuebner <heiko@sntech.de>
> Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
> ---
>  .../devicetree/bindings/usb/samsung-usbphy.txt     |   11 +
>  drivers/usb/phy/Kconfig                            |    8 +
>  drivers/usb/phy/Makefile                           |    1 +
>  drivers/usb/phy/samsung-usbphy.c                   |  360
> ++++++++++++++++++++ include/linux/platform_data/samsung-usbphy.h      
> |   27 ++
>  5 files changed, 407 insertions(+), 0 deletions(-)
>  create mode 100644
> Documentation/devicetree/bindings/usb/samsung-usbphy.txt create mode
> 100644 drivers/usb/phy/samsung-usbphy.c
>  create mode 100644 include/linux/platform_data/samsung-usbphy.h
> 
> diff --git a/Documentation/devicetree/bindings/usb/samsung-usbphy.txt
> b/Documentation/devicetree/bindings/usb/samsung-usbphy.txt new file
> mode 100644
> index 0000000..7b26e2d
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/usb/samsung-usbphy.txt
> @@ -0,0 +1,11 @@
> +* Samsung's usb phy transceiver
> +
> +The Samsung's phy transceiver is used for controlling usb otg phy for
> +s3c-hsotg usb device controller.
> +TODO: Adding the PHY binding with controller(s) according to the under
> +developement generic PHY driver.
> +
> +Required properties:
> +- compatible : should be "samsung,exynos4210-usbphy"
> +- reg : base physical address of the phy registers and length of memory
> mapped +	region.
> diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig
> index 7eb73c5..17ad743 100644
> --- a/drivers/usb/phy/Kconfig
> +++ b/drivers/usb/phy/Kconfig
> @@ -44,3 +44,11 @@ config USB_RCAR_PHY
> 
>  	  To compile this driver as a module, choose M here: the
>  	  module will be called rcar-phy.
> +
> +config SAMSUNG_USBPHY
> +	bool "Samsung USB PHY controller Driver"
> +	depends on USB_S3C_HSOTG
> +	select USB_OTG_UTILS
> +	help
> +	  Enable this to support Samsung USB phy controller for samsung
> +	  SoCs.
> diff --git a/drivers/usb/phy/Makefile b/drivers/usb/phy/Makefile
> index 1a579a8..ec304f6 100644
> --- a/drivers/usb/phy/Makefile
> +++ b/drivers/usb/phy/Makefile
> @@ -9,3 +9,4 @@ 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
> +obj-$(CONFIG_SAMSUNG_USBPHY)		+= samsung-usbphy.o
> diff --git a/drivers/usb/phy/samsung-usbphy.c
> b/drivers/usb/phy/samsung-usbphy.c new file mode 100644
> index 0000000..3c84aab
> --- /dev/null
> +++ b/drivers/usb/phy/samsung-usbphy.c
> @@ -0,0 +1,360 @@
> +/* linux/drivers/usb/phy/samsung-usbphy.c
> + *
> + * Copyright (c) 2012 Samsung Electronics Co., Ltd.
> + *              http://www.samsung.com
> + *
> + * Author: Praveen Paneri <p.paneri@samsung.com>
> + *
> + * Samsung USB2.0 High-speed OTG transceiver, talks to S3C HS OTG
> controller + *
> + * 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.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; 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/platform_device.h>
> +#include <linux/clk.h>
> +#include <linux/delay.h>
> +#include <linux/err.h>
> +#include <linux/io.h>
> +#include <linux/of.h>
> +#include <linux/usb/otg.h>
> +#include <linux/platform_data/samsung-usbphy.h>
> +
> +/* Register definitions */
> +
> +#define SAMSUNG_PHYPWR				(0x00)
> +
> +#define PHYPWR_NORMAL_MASK			(0x19 << 0)
> +#define PHYPWR_OTG_DISABLE			(0x1 << 4)
> +#define PHYPWR_ANALOG_POWERDOWN			(0x1 << 3)
> +#define PHYPWR_FORCE_SUSPEND			(0x1 << 1)
> +/* For Exynos4 */
> +#define PHYPWR_NORMAL_MASK_PHY0			(0x39 << 0)
> +#define PHYPWR_SLEEP_PHY0			(0x1 << 5)
> +
> +#define SAMSUNG_PHYCLK				(0x04)
> +
> +#define PHYCLK_MODE_USB11			(0x1 << 6)
> +#define PHYCLK_EXT_OSC				(0x1 << 5)
> +#define PHYCLK_COMMON_ON_N			(0x1 << 4)
> +#define PHYCLK_ID_PULL				(0x1 << 2)
> +#define PHYCLK_CLKSEL_MASK			(0x3 << 0)
> +#define PHYCLK_CLKSEL_48M			(0x0 << 0)
> +#define PHYCLK_CLKSEL_12M			(0x2 << 0)
> +#define PHYCLK_CLKSEL_24M			(0x3 << 0)
> +
> +#define SAMSUNG_RSTCON				(0x08)
> +
> +#define RSTCON_PHYLINK_SWRST			(0x1 << 2)
> +#define RSTCON_HLINK_SWRST			(0x1 << 1)
> +#define RSTCON_SWRST				(0x1 << 0)
> +
> +#ifndef MHZ
> +#define MHZ (1000*1000)
> +#endif
> +
> +enum samsung_cpu_type {
> +	TYPE_S3C64XX,
> +	TYPE_EXYNOS4210,
> +};
> +
> +/*
> + * struct samsung_usbphy - transceiver driver state
> + * @phy: transceiver structure
> + * @plat: platform data
> + * @dev: The parent device supplied to the probe function
> + * @clk: usb phy clock
> + * @regs: usb phy register memory base
> + * @ref_clk_freq: reference clock frequency selection
> + * @cpu_type: machine identifier
> + */
> +struct samsung_usbphy {
> +	struct usb_phy	phy;
> +	struct samsung_usbphy_data *plat;
> +	struct device	*dev;
> +	struct clk	*clk;
> +	void __iomem	*regs;
> +	int		ref_clk_freq;
> +	int		cpu_type;
> +};
> +
> +#define phy_to_sphy(x)		container_of((x), struct samsung_usbphy, 
phy)
> +
> +/*
> + * Returns reference clock frequency selection value
> + */
> +static int samsung_usbphy_get_refclk_freq(struct samsung_usbphy *sphy)
> +{
> +	struct clk *ref_clk;
> +	int refclk_freq = 0;
> +
> +	ref_clk = clk_get(sphy->dev, "xusbxti");
> +	if (IS_ERR(ref_clk)) {
> +		dev_err(sphy->dev, "Failed to get reference clock\n");
> +		return PTR_ERR(ref_clk);
> +	}
> +
> +	switch (clk_get_rate(ref_clk)) {
> +	case 12 * MHZ:
> +		refclk_freq = PHYCLK_CLKSEL_12M;
> +		break;
> +	case 24 * MHZ:
> +		refclk_freq = PHYCLK_CLKSEL_24M;
> +		break;
> +	case 48 * MHZ:
> +		refclk_freq = PHYCLK_CLKSEL_48M;
> +		break;
> +	default:
> +		if (sphy->cpu_type == TYPE_S3C64XX)
> +			refclk_freq = PHYCLK_CLKSEL_48M;
> +		else
> +			refclk_freq = PHYCLK_CLKSEL_24M;
> +		break;
> +	}
> +	clk_put(ref_clk);
> +
> +	return refclk_freq;
> +}
> +
> +static void samsung_usbphy_enable(struct samsung_usbphy *sphy)
> +{
> +	void __iomem *regs = sphy->regs;
> +	u32 phypwr;
> +	u32 phyclk;
> +	u32 rstcon;
> +
> +	/* set clock frequency for PLL */
> +	phyclk = sphy->ref_clk_freq;
> +	phypwr = readl(regs + SAMSUNG_PHYPWR);
> +	rstcon = readl(regs + SAMSUNG_RSTCON);
> +
> +	switch (sphy->cpu_type) {
> +	case TYPE_S3C64XX:
> +		phyclk &= ~PHYCLK_COMMON_ON_N;
> +		phypwr &= ~PHYPWR_NORMAL_MASK;
> +		rstcon |= RSTCON_SWRST;
> +		break;
> +	case TYPE_EXYNOS4210:
> +		phypwr &= ~PHYPWR_NORMAL_MASK_PHY0;
> +		rstcon |= RSTCON_SWRST;
> +	default:
> +		break;
> +	}
> +
> +	writel(phyclk, regs + SAMSUNG_PHYCLK);
> +	/* set to normal of PHY0 */

I don't understand this comment.

> +	writel(phypwr, regs + SAMSUNG_PHYPWR);
> +	/* reset all ports of PHY and Link */
> +	writel(rstcon, regs + SAMSUNG_RSTCON);
> +	udelay(10);
> +	rstcon &= ~RSTCON_SWRST;
> +	writel(rstcon, regs + SAMSUNG_RSTCON);
> +}
> +
> +static void samsung_usbphy_disable(struct samsung_usbphy *sphy)
> +{
> +	void __iomem *regs = sphy->regs;
> +	u32 phypwr;
> +
> +	phypwr = readl(regs + SAMSUNG_PHYPWR);
> +
> +	switch (sphy->cpu_type) {
> +	case TYPE_S3C64XX:
> +		phypwr |= PHYPWR_NORMAL_MASK;
> +		break;
> +	case TYPE_EXYNOS4210:
> +		phypwr |= PHYPWR_NORMAL_MASK_PHY0;
> +	default:
> +		break;
> +	}
> +
> +	/* unset to normal of PHY0 */

I don't understand this comment.

> +	writel(phypwr, regs + SAMSUNG_PHYPWR);
> +}
> +
> +/*
> + * The function passed to the usb driver for phy initialization
> + */
> +static int samsung_usbphy_init(struct usb_phy *phy)
> +{
> +	struct samsung_usbphy *sphy;
> +	int ret = 0;
> +
> +	sphy = phy_to_sphy(phy);
> +
> +	/* Enable the phy clock */
> +	ret = clk_prepare_enable(sphy->clk);
> +	if (ret) {
> +		dev_err(sphy->dev, "%s: clk_prepare_enable failed\n", 
__func__);
> +		return ret;
> +	}
> +
> +	/* Disable phy isolation */
> +	if (sphy->plat && sphy->plat->pmu_isolation)
> +		sphy->plat->pmu_isolation(false);
> +
> +	/* Initialize usb phy registers */
> +	samsung_usbphy_enable(sphy);
> +
> +	/* Disable the phy clock */
> +	clk_disable_unprepare(sphy->clk);
> +	return ret;
> +}
> +
> +/*
> + * The function passed to the usb driver for phy shutdown
> + */
> +static void samsung_usbphy_shutdown(struct usb_phy *phy)
> +{
> +	struct samsung_usbphy *sphy;
> +
> +	sphy = phy_to_sphy(phy);
> +
> +	if (clk_prepare_enable(sphy->clk)) {
> +		dev_err(sphy->dev, "%s: clk_prepare_enable failed\n", 
__func__);
> +		return;
> +	}
> +
> +	/* De-initialize usb phy registers */
> +	samsung_usbphy_disable(sphy);
> +
> +	/* Enable phy isolation */
> +	if (sphy->plat && sphy->plat->pmu_isolation)
> +		sphy->plat->pmu_isolation(true);
> +
> +	clk_disable_unprepare(sphy->clk);
> +}
> +
> +static const struct of_device_id samsung_usbphy_dt_match[];
> +
> +static inline int samsung_usbphy_get_driver_data(struct platform_device
> *pdev) +{
> +	if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node) {

if (pdev->dev.of_node) {

CONFIG_OF is not needed to check whether dev.of_node is not NULL and if 
dev.of_node is always NULL with CONFIG_OF disabled, so this check is 
enough.

> +		int data;

You can remove this variable and...

> +		const struct of_device_id *match;
> +		match = of_match_node(samsung_usbphy_dt_match,
> +							pdev->dev.of_node);
> +		data = (int) match->data;
> +		return data;

return (int) match->data;

> +	}
> +
> +	return platform_get_device_id(pdev)->driver_data;
> +}
> +
> +static int __devinit samsung_usbphy_probe(struct platform_device *pdev)
> +{
> +	struct samsung_usbphy *sphy;
> +	struct samsung_usbphy_data *pdata;
> +	struct device *dev = &pdev->dev;
> +	struct resource *phy_mem;
> +	void __iomem	*phy_base;
> +	struct clk *clk;
> +	int	ret = 0;
> +
> +	pdata = pdev->dev.platform_data;
> +	if (!pdata) {
> +		dev_err(&pdev->dev, "%s: no platform data defined\n", 
__func__);
> +		return -EINVAL;
> +	}
> +
> +	phy_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	if (!phy_mem) {
> +		dev_err(dev, "%s: missing mem resource\n", __func__);
> +		return -ENODEV;
> +	}
> +
> +	phy_base = devm_request_and_ioremap(dev, phy_mem);
> +	if (!phy_base) {
> +		dev_err(dev, "%s: register mapping failed\n", __func__);
> +		return -ENXIO;
> +	}
> +
> +	sphy = devm_kzalloc(dev, sizeof(*sphy), GFP_KERNEL);
> +	if (!sphy)
> +		return -ENOMEM;
> +
> +	clk = devm_clk_get(dev, "otg");
> +	if (IS_ERR(clk)) {
> +		dev_err(dev, "Failed to get otg clock\n");
> +		return PTR_ERR(clk);
> +	}
> +
> +	sphy->dev		= &pdev->dev;
> +	sphy->plat		= pdata;
> +	sphy->regs		= phy_base;
> +	sphy->clk		= clk;
> +	sphy->phy.dev		= sphy->dev;
> +	sphy->phy.label		= "samsung-usbphy";
> +	sphy->phy.init		= samsung_usbphy_init;
> +	sphy->phy.shutdown	= samsung_usbphy_shutdown;
> +	sphy->cpu_type		= samsung_usbphy_get_driver_data(pdev);
> +	sphy->ref_clk_freq	= samsung_usbphy_get_refclk_freq(sphy);
> +
> +	platform_set_drvdata(pdev, sphy);
> +
> +	ret = usb_add_phy(&sphy->phy, USB_PHY_TYPE_USB2);
> +	return ret;

return usb_add_phy(&sphy->phy, USB_PHY_TYPE_USB2);

> +}
> +
> +static int __exit samsung_usbphy_remove(struct platform_device *pdev)
> +{
> +	struct samsung_usbphy *sphy = platform_get_drvdata(pdev);
> +
> +	usb_remove_phy(&sphy->phy);
> +
> +	return 0;
> +}
> +
> +#ifdef CONFIG_OF
> +static const struct of_device_id samsung_usbphy_dt_match[] = {
> +	{
> +		.compatible = "samsung,s3c64xx-usbphy",
> +		.data = (void *)TYPE_S3C64XX,
> +	}, {
> +		.compatible = "samsung,exynos4210-usbphy",
> +		.data = (void *)TYPE_EXYNOS4210,
> +	},
> +	{},
> +};
> +MODULE_DEVICE_TABLE(of, samsung_usbphy_dt_match);
> +#else
> +#define samsung_usbphy_dt_match NULL
> +#endif

Instead of using else and defining samsung_usbphy_dt_match manually, 
instead you can use of_match_ptr macro. (See my next comment.)

> +
> +static struct platform_device_id samsung_usbphy_driver_ids[] = {
> +	{
> +		.name		= "s3c64xx-usbphy",
> +		.driver_data	= TYPE_S3C64XX,
> +	}, {
> +		.name		= "exynos4210-usbphy",
> +		.driver_data	= TYPE_EXYNOS4210,
> +	},
> +	{},
> +};
> +
> +MODULE_DEVICE_TABLE(platform, samsung_usbphy_driver_ids);
> +
> +static struct platform_driver samsung_usbphy_driver = {
> +	.probe		= samsung_usbphy_probe,
> +	.remove		= __devexit_p(samsung_usbphy_remove),
> +	.id_table	= samsung_usbphy_driver_ids,
> +	.driver		= {
> +		.name	= "samsung-usbphy",
> +		.owner	= THIS_MODULE,
> +		.of_match_table = samsung_usbphy_dt_match,

.of_match_table = of_match_ptr(samsung_usbphy_dt_match),

> +	},
> +};
> +
> +module_platform_driver(samsung_usbphy_driver);
> +
> +MODULE_DESCRIPTION("Samsung USB phy controller");
> +MODULE_AUTHOR("Praveen Paneri <p.paneri@samsung.com>");
> +MODULE_LICENSE("GPL");
> +MODULE_ALIAS("platform:samsung-usbphy");
> diff --git a/include/linux/platform_data/samsung-usbphy.h
> b/include/linux/platform_data/samsung-usbphy.h new file mode 100644
> index 0000000..1bd24cb
> --- /dev/null
> +++ b/include/linux/platform_data/samsung-usbphy.h
> @@ -0,0 +1,27 @@
> +/*
> + * Copyright (C) 2012 Samsung Electronics Co.Ltd
> + *		http://www.samsung.com/
> + * Author: Praveen Paneri <p.paneri@samsung.com>
> + *
> + * Defines platform data for samsung usb phy driver.
> + *
> + * 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;  either version 2 of the
>  License, or (at your + * option) any later version.
> + */
> +
> +#ifndef __SAMSUNG_USBPHY_PLATFORM_H
> +#define __SAMSUNG_USBPHY_PLATFORM_H
> +
> +/**
> + * samsung_usbphy_data - Platform data for USB PHY driver.
> + * @pmu_isolation: Function to control usb phy isolation in PMU.
> + */
> +struct samsung_usbphy_data {
> +	void (*pmu_isolation)(int on);

I believe this should be named in a generic way. This is called PMU 
isolation on Exynos SoCs, but on S3C64xx it's USB PHY mask.

Best regards,
Tomasz Figa

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

* Re: [PATCH v8 2/2] usb: s3c-hsotg: Adding phy driver support
  2012-11-14 10:27   ` Praveen Paneri
@ 2012-11-21 20:11       ` Tomasz Figa
  -1 siblings, 0 replies; 28+ messages in thread
From: Tomasz Figa @ 2012-11-21 20:11 UTC (permalink / raw)
  To: Praveen Paneri
  Cc: linux-usb-u79uwXL29TY76Z2rM5mHXA,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-samsung-soc-u79uwXL29TY76Z2rM5mHXA,
	kgene.kim-Sze3O3UU22JBDgjK7y7TUQ, balbi-l0cyMroinI0,
	gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
	thomas.abraham-QSEj5FYQhm4dnm+yROfE0A,
	ben-linux-elnMNo+KYs3YtjvyW6yDsg,
	broonie-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E,
	l.majewski-Sze3O3UU22JBDgjK7y7TUQ,
	kyungmin.park-Sze3O3UU22JBDgjK7y7TUQ,
	grant.likely-s3s/WqlpOiPyB63q8FvJNQ,
	heiko-4mtYJXux2i+zQB+pC5nmwQ, t.figa-Sze3O3UU22JBDgjK7y7TUQ,
	gautam.vivek-Sze3O3UU22JBDgjK7y7TUQ

Hi Praveen,

On Wednesday 14 of November 2012 15:57:16 Praveen Paneri wrote:
> Adding the transceiver to hsotg driver. Keeping the platform data
> for continuing the smooth operation for boards which still uses it
> 
> Signed-off-by: Praveen Paneri <p.paneri-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
> Acked-by: Kyungmin Park <kyungmin.park-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
> ---
>  drivers/usb/gadget/s3c-hsotg.c |   37
> +++++++++++++++++++++++++++---------- 1 files changed, 27
> insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/usb/gadget/s3c-hsotg.c
> b/drivers/usb/gadget/s3c-hsotg.c index 6f696ee..bc30a2d 100644
> --- a/drivers/usb/gadget/s3c-hsotg.c
> +++ b/drivers/usb/gadget/s3c-hsotg.c
> @@ -32,6 +32,7 @@
> 
>  #include <linux/usb/ch9.h>
>  #include <linux/usb/gadget.h>
> +#include <linux/usb/phy.h>
>  #include <linux/platform_data/s3c-hsotg.h>
> 
>  #include <mach/map.h>
> @@ -133,7 +134,9 @@ struct s3c_hsotg_ep {
>   * struct s3c_hsotg - driver state.
>   * @dev: The parent device supplied to the probe function
>   * @driver: USB gadget driver
> - * @plat: The platform specific configuration data.
> + * @phy: The otg phy transceiver structure for phy control.
> + * @plat: The platform specific configuration data. This can be removed
> once + * all SoCs support usb transceiver.
>   * @regs: The memory area mapped for accessing registers.
>   * @irq: The IRQ number we are using
>   * @supplies: Definition of USB power supplies
> @@ -153,6 +156,7 @@ struct s3c_hsotg_ep {
>  struct s3c_hsotg {
>  	struct device		 *dev;
>  	struct usb_gadget_driver *driver;
> +	struct usb_phy		*phy;
>  	struct s3c_hsotg_plat	 *plat;
> 
>  	spinlock_t              lock;
> @@ -2854,7 +2858,10 @@ static void s3c_hsotg_phy_enable(struct s3c_hsotg
> *hsotg) struct platform_device *pdev = to_platform_device(hsotg->dev);
> 
>  	dev_dbg(hsotg->dev, "pdev 0x%p\n", pdev);
> -	if (hsotg->plat->phy_init)
> +
> +	if (hsotg->phy)
> +		usb_phy_init(hsotg->phy);
> +	else if (hsotg->plat->phy_init)
>  		hsotg->plat->phy_init(pdev, hsotg->plat->phy_type);
>  }
> 
> @@ -2869,7 +2876,9 @@ static void s3c_hsotg_phy_disable(struct s3c_hsotg
> *hsotg) {
>  	struct platform_device *pdev = to_platform_device(hsotg->dev);
> 
> -	if (hsotg->plat->phy_exit)
> +	if (hsotg->phy)
> +		usb_phy_shutdown(hsotg->phy);
> +	else if (hsotg->plat->phy_exit)
>  		hsotg->plat->phy_exit(pdev, hsotg->plat->phy_type);
>  }
> 
> @@ -3493,6 +3502,7 @@ static void s3c_hsotg_release(struct device *dev)
>  static int __devinit s3c_hsotg_probe(struct platform_device *pdev)
>  {
>  	struct s3c_hsotg_plat *plat = pdev->dev.platform_data;
> +	struct usb_phy *phy;
>  	struct device *dev = &pdev->dev;
>  	struct s3c_hsotg_ep *eps;
>  	struct s3c_hsotg *hsotg;
> @@ -3501,20 +3511,27 @@ static int __devinit s3c_hsotg_probe(struct
> platform_device *pdev) int ret;
>  	int i;
> 
> -	plat = pdev->dev.platform_data;
> -	if (!plat) {
> -		dev_err(&pdev->dev, "no platform data defined\n");
> -		return -EINVAL;
> -	}
> -
>  	hsotg = devm_kzalloc(&pdev->dev, sizeof(struct s3c_hsotg),
> GFP_KERNEL); if (!hsotg) {
>  		dev_err(dev, "cannot get memory\n");
>  		return -ENOMEM;
>  	}
> 
> +	phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2);
> +	if (IS_ERR_OR_NULL(phy)) {
> +		/* Fallback for pdata */
> +		plat = pdev->dev.platform_data;
> +		if (!plat) {
> +			dev_err(&pdev->dev, "no platform data or transceiver 
defined\n");
> +			return -EPROBE_DEFER;
> +		} else {
> +			hsotg->plat = plat;
> +		}

nitpick: The hsotg->plat = plat; assignment can be made without the else 
statement as well.

Best regards,
Tomasz Figa

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

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

* [PATCH v8 2/2] usb: s3c-hsotg: Adding phy driver support
@ 2012-11-21 20:11       ` Tomasz Figa
  0 siblings, 0 replies; 28+ messages in thread
From: Tomasz Figa @ 2012-11-21 20:11 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Praveen,

On Wednesday 14 of November 2012 15:57:16 Praveen Paneri wrote:
> Adding the transceiver to hsotg driver. Keeping the platform data
> for continuing the smooth operation for boards which still uses it
> 
> Signed-off-by: Praveen Paneri <p.paneri@samsung.com>
> Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
> ---
>  drivers/usb/gadget/s3c-hsotg.c |   37
> +++++++++++++++++++++++++++---------- 1 files changed, 27
> insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/usb/gadget/s3c-hsotg.c
> b/drivers/usb/gadget/s3c-hsotg.c index 6f696ee..bc30a2d 100644
> --- a/drivers/usb/gadget/s3c-hsotg.c
> +++ b/drivers/usb/gadget/s3c-hsotg.c
> @@ -32,6 +32,7 @@
> 
>  #include <linux/usb/ch9.h>
>  #include <linux/usb/gadget.h>
> +#include <linux/usb/phy.h>
>  #include <linux/platform_data/s3c-hsotg.h>
> 
>  #include <mach/map.h>
> @@ -133,7 +134,9 @@ struct s3c_hsotg_ep {
>   * struct s3c_hsotg - driver state.
>   * @dev: The parent device supplied to the probe function
>   * @driver: USB gadget driver
> - * @plat: The platform specific configuration data.
> + * @phy: The otg phy transceiver structure for phy control.
> + * @plat: The platform specific configuration data. This can be removed
> once + * all SoCs support usb transceiver.
>   * @regs: The memory area mapped for accessing registers.
>   * @irq: The IRQ number we are using
>   * @supplies: Definition of USB power supplies
> @@ -153,6 +156,7 @@ struct s3c_hsotg_ep {
>  struct s3c_hsotg {
>  	struct device		 *dev;
>  	struct usb_gadget_driver *driver;
> +	struct usb_phy		*phy;
>  	struct s3c_hsotg_plat	 *plat;
> 
>  	spinlock_t              lock;
> @@ -2854,7 +2858,10 @@ static void s3c_hsotg_phy_enable(struct s3c_hsotg
> *hsotg) struct platform_device *pdev = to_platform_device(hsotg->dev);
> 
>  	dev_dbg(hsotg->dev, "pdev 0x%p\n", pdev);
> -	if (hsotg->plat->phy_init)
> +
> +	if (hsotg->phy)
> +		usb_phy_init(hsotg->phy);
> +	else if (hsotg->plat->phy_init)
>  		hsotg->plat->phy_init(pdev, hsotg->plat->phy_type);
>  }
> 
> @@ -2869,7 +2876,9 @@ static void s3c_hsotg_phy_disable(struct s3c_hsotg
> *hsotg) {
>  	struct platform_device *pdev = to_platform_device(hsotg->dev);
> 
> -	if (hsotg->plat->phy_exit)
> +	if (hsotg->phy)
> +		usb_phy_shutdown(hsotg->phy);
> +	else if (hsotg->plat->phy_exit)
>  		hsotg->plat->phy_exit(pdev, hsotg->plat->phy_type);
>  }
> 
> @@ -3493,6 +3502,7 @@ static void s3c_hsotg_release(struct device *dev)
>  static int __devinit s3c_hsotg_probe(struct platform_device *pdev)
>  {
>  	struct s3c_hsotg_plat *plat = pdev->dev.platform_data;
> +	struct usb_phy *phy;
>  	struct device *dev = &pdev->dev;
>  	struct s3c_hsotg_ep *eps;
>  	struct s3c_hsotg *hsotg;
> @@ -3501,20 +3511,27 @@ static int __devinit s3c_hsotg_probe(struct
> platform_device *pdev) int ret;
>  	int i;
> 
> -	plat = pdev->dev.platform_data;
> -	if (!plat) {
> -		dev_err(&pdev->dev, "no platform data defined\n");
> -		return -EINVAL;
> -	}
> -
>  	hsotg = devm_kzalloc(&pdev->dev, sizeof(struct s3c_hsotg),
> GFP_KERNEL); if (!hsotg) {
>  		dev_err(dev, "cannot get memory\n");
>  		return -ENOMEM;
>  	}
> 
> +	phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2);
> +	if (IS_ERR_OR_NULL(phy)) {
> +		/* Fallback for pdata */
> +		plat = pdev->dev.platform_data;
> +		if (!plat) {
> +			dev_err(&pdev->dev, "no platform data or transceiver 
defined\n");
> +			return -EPROBE_DEFER;
> +		} else {
> +			hsotg->plat = plat;
> +		}

nitpick: The hsotg->plat = plat; assignment can be made without the else 
statement as well.

Best regards,
Tomasz Figa

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

* Re: [PATCH v8 2/2] usb: s3c-hsotg: Adding phy driver support
  2012-11-21 20:11       ` Tomasz Figa
@ 2012-11-23  4:24         ` Praveen Paneri
  -1 siblings, 0 replies; 28+ messages in thread
From: Praveen Paneri @ 2012-11-23  4:24 UTC (permalink / raw)
  To: Tomasz Figa
  Cc: linux-usb, devicetree-discuss, linux-arm-kernel,
	linux-samsung-soc, Kukjin Kim, Felipe Balbi, gregkh,
	Thomas Abraham, ben-linux, broonie, Lukasz Majewski,
	Kyungmin Park, Grant Likely, Heiko Stübner, t.figa,
	Vivek Gautam

On Thu, Nov 22, 2012 at 1:41 AM, Tomasz Figa <tomasz.figa@gmail.com> wrote:
> Hi Praveen,
>
> On Wednesday 14 of November 2012 15:57:16 Praveen Paneri wrote:
>> Adding the transceiver to hsotg driver. Keeping the platform data
>> for continuing the smooth operation for boards which still uses it
>>
>> Signed-off-by: Praveen Paneri <p.paneri@samsung.com>
>> Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
>> ---
>>  drivers/usb/gadget/s3c-hsotg.c |   37
>> +++++++++++++++++++++++++++---------- 1 files changed, 27
>> insertions(+), 10 deletions(-)
>>
>> diff --git a/drivers/usb/gadget/s3c-hsotg.c
>> b/drivers/usb/gadget/s3c-hsotg.c index 6f696ee..bc30a2d 100644
>> --- a/drivers/usb/gadget/s3c-hsotg.c
>> +++ b/drivers/usb/gadget/s3c-hsotg.c
>> @@ -32,6 +32,7 @@
>>
>>  #include <linux/usb/ch9.h>
>>  #include <linux/usb/gadget.h>
>> +#include <linux/usb/phy.h>
>>  #include <linux/platform_data/s3c-hsotg.h>
>>
>>  #include <mach/map.h>
>> @@ -133,7 +134,9 @@ struct s3c_hsotg_ep {
>>   * struct s3c_hsotg - driver state.
>>   * @dev: The parent device supplied to the probe function
>>   * @driver: USB gadget driver
>> - * @plat: The platform specific configuration data.
>> + * @phy: The otg phy transceiver structure for phy control.
>> + * @plat: The platform specific configuration data. This can be removed
>> once + * all SoCs support usb transceiver.
>>   * @regs: The memory area mapped for accessing registers.
>>   * @irq: The IRQ number we are using
>>   * @supplies: Definition of USB power supplies
>> @@ -153,6 +156,7 @@ struct s3c_hsotg_ep {
>>  struct s3c_hsotg {
>>       struct device            *dev;
>>       struct usb_gadget_driver *driver;
>> +     struct usb_phy          *phy;
>>       struct s3c_hsotg_plat    *plat;
>>
>>       spinlock_t              lock;
>> @@ -2854,7 +2858,10 @@ static void s3c_hsotg_phy_enable(struct s3c_hsotg
>> *hsotg) struct platform_device *pdev = to_platform_device(hsotg->dev);
>>
>>       dev_dbg(hsotg->dev, "pdev 0x%p\n", pdev);
>> -     if (hsotg->plat->phy_init)
>> +
>> +     if (hsotg->phy)
>> +             usb_phy_init(hsotg->phy);
>> +     else if (hsotg->plat->phy_init)
>>               hsotg->plat->phy_init(pdev, hsotg->plat->phy_type);
>>  }
>>
>> @@ -2869,7 +2876,9 @@ static void s3c_hsotg_phy_disable(struct s3c_hsotg
>> *hsotg) {
>>       struct platform_device *pdev = to_platform_device(hsotg->dev);
>>
>> -     if (hsotg->plat->phy_exit)
>> +     if (hsotg->phy)
>> +             usb_phy_shutdown(hsotg->phy);
>> +     else if (hsotg->plat->phy_exit)
>>               hsotg->plat->phy_exit(pdev, hsotg->plat->phy_type);
>>  }
>>
>> @@ -3493,6 +3502,7 @@ static void s3c_hsotg_release(struct device *dev)
>>  static int __devinit s3c_hsotg_probe(struct platform_device *pdev)
>>  {
>>       struct s3c_hsotg_plat *plat = pdev->dev.platform_data;
>> +     struct usb_phy *phy;
>>       struct device *dev = &pdev->dev;
>>       struct s3c_hsotg_ep *eps;
>>       struct s3c_hsotg *hsotg;
>> @@ -3501,20 +3511,27 @@ static int __devinit s3c_hsotg_probe(struct
>> platform_device *pdev) int ret;
>>       int i;
>>
>> -     plat = pdev->dev.platform_data;
>> -     if (!plat) {
>> -             dev_err(&pdev->dev, "no platform data defined\n");
>> -             return -EINVAL;
>> -     }
>> -
>>       hsotg = devm_kzalloc(&pdev->dev, sizeof(struct s3c_hsotg),
>> GFP_KERNEL); if (!hsotg) {
>>               dev_err(dev, "cannot get memory\n");
>>               return -ENOMEM;
>>       }
>>
>> +     phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2);
>> +     if (IS_ERR_OR_NULL(phy)) {
>> +             /* Fallback for pdata */
>> +             plat = pdev->dev.platform_data;
>> +             if (!plat) {
>> +                     dev_err(&pdev->dev, "no platform data or transceiver
> defined\n");
>> +                     return -EPROBE_DEFER;
>> +             } else {
>> +                     hsotg->plat = plat;
>> +             }
>
> nitpick: The hsotg->plat = plat; assignment can be made without the else
> statement as well.
True!
We will anyway remove the platform data part soon. If you say I can
resend it again.

>
> Best regards,
> Tomasz Figa
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH v8 2/2] usb: s3c-hsotg: Adding phy driver support
@ 2012-11-23  4:24         ` Praveen Paneri
  0 siblings, 0 replies; 28+ messages in thread
From: Praveen Paneri @ 2012-11-23  4:24 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Nov 22, 2012 at 1:41 AM, Tomasz Figa <tomasz.figa@gmail.com> wrote:
> Hi Praveen,
>
> On Wednesday 14 of November 2012 15:57:16 Praveen Paneri wrote:
>> Adding the transceiver to hsotg driver. Keeping the platform data
>> for continuing the smooth operation for boards which still uses it
>>
>> Signed-off-by: Praveen Paneri <p.paneri@samsung.com>
>> Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
>> ---
>>  drivers/usb/gadget/s3c-hsotg.c |   37
>> +++++++++++++++++++++++++++---------- 1 files changed, 27
>> insertions(+), 10 deletions(-)
>>
>> diff --git a/drivers/usb/gadget/s3c-hsotg.c
>> b/drivers/usb/gadget/s3c-hsotg.c index 6f696ee..bc30a2d 100644
>> --- a/drivers/usb/gadget/s3c-hsotg.c
>> +++ b/drivers/usb/gadget/s3c-hsotg.c
>> @@ -32,6 +32,7 @@
>>
>>  #include <linux/usb/ch9.h>
>>  #include <linux/usb/gadget.h>
>> +#include <linux/usb/phy.h>
>>  #include <linux/platform_data/s3c-hsotg.h>
>>
>>  #include <mach/map.h>
>> @@ -133,7 +134,9 @@ struct s3c_hsotg_ep {
>>   * struct s3c_hsotg - driver state.
>>   * @dev: The parent device supplied to the probe function
>>   * @driver: USB gadget driver
>> - * @plat: The platform specific configuration data.
>> + * @phy: The otg phy transceiver structure for phy control.
>> + * @plat: The platform specific configuration data. This can be removed
>> once + * all SoCs support usb transceiver.
>>   * @regs: The memory area mapped for accessing registers.
>>   * @irq: The IRQ number we are using
>>   * @supplies: Definition of USB power supplies
>> @@ -153,6 +156,7 @@ struct s3c_hsotg_ep {
>>  struct s3c_hsotg {
>>       struct device            *dev;
>>       struct usb_gadget_driver *driver;
>> +     struct usb_phy          *phy;
>>       struct s3c_hsotg_plat    *plat;
>>
>>       spinlock_t              lock;
>> @@ -2854,7 +2858,10 @@ static void s3c_hsotg_phy_enable(struct s3c_hsotg
>> *hsotg) struct platform_device *pdev = to_platform_device(hsotg->dev);
>>
>>       dev_dbg(hsotg->dev, "pdev 0x%p\n", pdev);
>> -     if (hsotg->plat->phy_init)
>> +
>> +     if (hsotg->phy)
>> +             usb_phy_init(hsotg->phy);
>> +     else if (hsotg->plat->phy_init)
>>               hsotg->plat->phy_init(pdev, hsotg->plat->phy_type);
>>  }
>>
>> @@ -2869,7 +2876,9 @@ static void s3c_hsotg_phy_disable(struct s3c_hsotg
>> *hsotg) {
>>       struct platform_device *pdev = to_platform_device(hsotg->dev);
>>
>> -     if (hsotg->plat->phy_exit)
>> +     if (hsotg->phy)
>> +             usb_phy_shutdown(hsotg->phy);
>> +     else if (hsotg->plat->phy_exit)
>>               hsotg->plat->phy_exit(pdev, hsotg->plat->phy_type);
>>  }
>>
>> @@ -3493,6 +3502,7 @@ static void s3c_hsotg_release(struct device *dev)
>>  static int __devinit s3c_hsotg_probe(struct platform_device *pdev)
>>  {
>>       struct s3c_hsotg_plat *plat = pdev->dev.platform_data;
>> +     struct usb_phy *phy;
>>       struct device *dev = &pdev->dev;
>>       struct s3c_hsotg_ep *eps;
>>       struct s3c_hsotg *hsotg;
>> @@ -3501,20 +3511,27 @@ static int __devinit s3c_hsotg_probe(struct
>> platform_device *pdev) int ret;
>>       int i;
>>
>> -     plat = pdev->dev.platform_data;
>> -     if (!plat) {
>> -             dev_err(&pdev->dev, "no platform data defined\n");
>> -             return -EINVAL;
>> -     }
>> -
>>       hsotg = devm_kzalloc(&pdev->dev, sizeof(struct s3c_hsotg),
>> GFP_KERNEL); if (!hsotg) {
>>               dev_err(dev, "cannot get memory\n");
>>               return -ENOMEM;
>>       }
>>
>> +     phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2);
>> +     if (IS_ERR_OR_NULL(phy)) {
>> +             /* Fallback for pdata */
>> +             plat = pdev->dev.platform_data;
>> +             if (!plat) {
>> +                     dev_err(&pdev->dev, "no platform data or transceiver
> defined\n");
>> +                     return -EPROBE_DEFER;
>> +             } else {
>> +                     hsotg->plat = plat;
>> +             }
>
> nitpick: The hsotg->plat = plat; assignment can be made without the else
> statement as well.
True!
We will anyway remove the platform data part soon. If you say I can
resend it again.

>
> Best regards,
> Tomasz Figa
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH v8 1/2] usb: phy: samsung: Introducing usb phy driver for hsotg
  2012-11-21 20:06         ` Tomasz Figa
@ 2012-11-23  4:26           ` Praveen Paneri
  -1 siblings, 0 replies; 28+ messages in thread
From: Praveen Paneri @ 2012-11-23  4:26 UTC (permalink / raw)
  To: Tomasz Figa
  Cc: linux-usb, devicetree-discuss, linux-arm-kernel,
	linux-samsung-soc, Kukjin Kim, Felipe Balbi, gregkh,
	Thomas Abraham, ben-linux, broonie, Lukasz Majewski,
	Kyungmin Park, Grant Likely, Heiko Stübner, t.figa,
	Vivek Gautam

Hi Tomasz,

On Thu, Nov 22, 2012 at 1:36 AM, Tomasz Figa <tomasz.figa@gmail.com> wrote:
> Hi Praveen,
>
> See some minor comments inline.
Thanks for your comments
>
> On Wednesday 14 of November 2012 15:57:15 Praveen Paneri wrote:
>> This driver uses usb_phy interface to interact with s3c-hsotg. Supports
>> phy_init and phy_shutdown functions to enable/disable usb phy. Support
>> will be extended to host controllers and more Samsung SoCs.
>>
>> Signed-off-by: Praveen Paneri <p.paneri@samsung.com>
>> Acked-by: Heiko Stuebner <heiko@sntech.de>
>> Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
>> ---
>>  .../devicetree/bindings/usb/samsung-usbphy.txt     |   11 +
>>  drivers/usb/phy/Kconfig                            |    8 +
>>  drivers/usb/phy/Makefile                           |    1 +
>>  drivers/usb/phy/samsung-usbphy.c                   |  360
>> ++++++++++++++++++++ include/linux/platform_data/samsung-usbphy.h
>> |   27 ++
>>  5 files changed, 407 insertions(+), 0 deletions(-)
>>  create mode 100644
>> Documentation/devicetree/bindings/usb/samsung-usbphy.txt create mode
>> 100644 drivers/usb/phy/samsung-usbphy.c
>>  create mode 100644 include/linux/platform_data/samsung-usbphy.h
>>
>> diff --git a/Documentation/devicetree/bindings/usb/samsung-usbphy.txt
>> b/Documentation/devicetree/bindings/usb/samsung-usbphy.txt new file
>> mode 100644
>> index 0000000..7b26e2d
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/usb/samsung-usbphy.txt
>> @@ -0,0 +1,11 @@
>> +* Samsung's usb phy transceiver
>> +
>> +The Samsung's phy transceiver is used for controlling usb otg phy for
>> +s3c-hsotg usb device controller.
>> +TODO: Adding the PHY binding with controller(s) according to the under
>> +developement generic PHY driver.
>> +
>> +Required properties:
>> +- compatible : should be "samsung,exynos4210-usbphy"
>> +- reg : base physical address of the phy registers and length of memory
>> mapped +      region.
>> diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig
>> index 7eb73c5..17ad743 100644
>> --- a/drivers/usb/phy/Kconfig
>> +++ b/drivers/usb/phy/Kconfig
>> @@ -44,3 +44,11 @@ config USB_RCAR_PHY
>>
>>         To compile this driver as a module, choose M here: the
>>         module will be called rcar-phy.
>> +
>> +config SAMSUNG_USBPHY
>> +     bool "Samsung USB PHY controller Driver"
>> +     depends on USB_S3C_HSOTG
>> +     select USB_OTG_UTILS
>> +     help
>> +       Enable this to support Samsung USB phy controller for samsung
>> +       SoCs.
>> diff --git a/drivers/usb/phy/Makefile b/drivers/usb/phy/Makefile
>> index 1a579a8..ec304f6 100644
>> --- a/drivers/usb/phy/Makefile
>> +++ b/drivers/usb/phy/Makefile
>> @@ -9,3 +9,4 @@ 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
>> +obj-$(CONFIG_SAMSUNG_USBPHY)         += samsung-usbphy.o
>> diff --git a/drivers/usb/phy/samsung-usbphy.c
>> b/drivers/usb/phy/samsung-usbphy.c new file mode 100644
>> index 0000000..3c84aab
>> --- /dev/null
>> +++ b/drivers/usb/phy/samsung-usbphy.c
>> @@ -0,0 +1,360 @@
>> +/* linux/drivers/usb/phy/samsung-usbphy.c
>> + *
>> + * Copyright (c) 2012 Samsung Electronics Co., Ltd.
>> + *              http://www.samsung.com
>> + *
>> + * Author: Praveen Paneri <p.paneri@samsung.com>
>> + *
>> + * Samsung USB2.0 High-speed OTG transceiver, talks to S3C HS OTG
>> controller + *
>> + * 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.
>> + *
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; 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/platform_device.h>
>> +#include <linux/clk.h>
>> +#include <linux/delay.h>
>> +#include <linux/err.h>
>> +#include <linux/io.h>
>> +#include <linux/of.h>
>> +#include <linux/usb/otg.h>
>> +#include <linux/platform_data/samsung-usbphy.h>
>> +
>> +/* Register definitions */
>> +
>> +#define SAMSUNG_PHYPWR                               (0x00)
>> +
>> +#define PHYPWR_NORMAL_MASK                   (0x19 << 0)
>> +#define PHYPWR_OTG_DISABLE                   (0x1 << 4)
>> +#define PHYPWR_ANALOG_POWERDOWN                      (0x1 << 3)
>> +#define PHYPWR_FORCE_SUSPEND                 (0x1 << 1)
>> +/* For Exynos4 */
>> +#define PHYPWR_NORMAL_MASK_PHY0                      (0x39 << 0)
>> +#define PHYPWR_SLEEP_PHY0                    (0x1 << 5)
>> +
>> +#define SAMSUNG_PHYCLK                               (0x04)
>> +
>> +#define PHYCLK_MODE_USB11                    (0x1 << 6)
>> +#define PHYCLK_EXT_OSC                               (0x1 << 5)
>> +#define PHYCLK_COMMON_ON_N                   (0x1 << 4)
>> +#define PHYCLK_ID_PULL                               (0x1 << 2)
>> +#define PHYCLK_CLKSEL_MASK                   (0x3 << 0)
>> +#define PHYCLK_CLKSEL_48M                    (0x0 << 0)
>> +#define PHYCLK_CLKSEL_12M                    (0x2 << 0)
>> +#define PHYCLK_CLKSEL_24M                    (0x3 << 0)
>> +
>> +#define SAMSUNG_RSTCON                               (0x08)
>> +
>> +#define RSTCON_PHYLINK_SWRST                 (0x1 << 2)
>> +#define RSTCON_HLINK_SWRST                   (0x1 << 1)
>> +#define RSTCON_SWRST                         (0x1 << 0)
>> +
>> +#ifndef MHZ
>> +#define MHZ (1000*1000)
>> +#endif
>> +
>> +enum samsung_cpu_type {
>> +     TYPE_S3C64XX,
>> +     TYPE_EXYNOS4210,
>> +};
>> +
>> +/*
>> + * struct samsung_usbphy - transceiver driver state
>> + * @phy: transceiver structure
>> + * @plat: platform data
>> + * @dev: The parent device supplied to the probe function
>> + * @clk: usb phy clock
>> + * @regs: usb phy register memory base
>> + * @ref_clk_freq: reference clock frequency selection
>> + * @cpu_type: machine identifier
>> + */
>> +struct samsung_usbphy {
>> +     struct usb_phy  phy;
>> +     struct samsung_usbphy_data *plat;
>> +     struct device   *dev;
>> +     struct clk      *clk;
>> +     void __iomem    *regs;
>> +     int             ref_clk_freq;
>> +     int             cpu_type;
>> +};
>> +
>> +#define phy_to_sphy(x)               container_of((x), struct samsung_usbphy,
> phy)
>> +
>> +/*
>> + * Returns reference clock frequency selection value
>> + */
>> +static int samsung_usbphy_get_refclk_freq(struct samsung_usbphy *sphy)
>> +{
>> +     struct clk *ref_clk;
>> +     int refclk_freq = 0;
>> +
>> +     ref_clk = clk_get(sphy->dev, "xusbxti");
>> +     if (IS_ERR(ref_clk)) {
>> +             dev_err(sphy->dev, "Failed to get reference clock\n");
>> +             return PTR_ERR(ref_clk);
>> +     }
>> +
>> +     switch (clk_get_rate(ref_clk)) {
>> +     case 12 * MHZ:
>> +             refclk_freq = PHYCLK_CLKSEL_12M;
>> +             break;
>> +     case 24 * MHZ:
>> +             refclk_freq = PHYCLK_CLKSEL_24M;
>> +             break;
>> +     case 48 * MHZ:
>> +             refclk_freq = PHYCLK_CLKSEL_48M;
>> +             break;
>> +     default:
>> +             if (sphy->cpu_type == TYPE_S3C64XX)
>> +                     refclk_freq = PHYCLK_CLKSEL_48M;
>> +             else
>> +                     refclk_freq = PHYCLK_CLKSEL_24M;
>> +             break;
>> +     }
>> +     clk_put(ref_clk);
>> +
>> +     return refclk_freq;
>> +}
>> +
>> +static void samsung_usbphy_enable(struct samsung_usbphy *sphy)
>> +{
>> +     void __iomem *regs = sphy->regs;
>> +     u32 phypwr;
>> +     u32 phyclk;
>> +     u32 rstcon;
>> +
>> +     /* set clock frequency for PLL */
>> +     phyclk = sphy->ref_clk_freq;
>> +     phypwr = readl(regs + SAMSUNG_PHYPWR);
>> +     rstcon = readl(regs + SAMSUNG_RSTCON);
>> +
>> +     switch (sphy->cpu_type) {
>> +     case TYPE_S3C64XX:
>> +             phyclk &= ~PHYCLK_COMMON_ON_N;
>> +             phypwr &= ~PHYPWR_NORMAL_MASK;
>> +             rstcon |= RSTCON_SWRST;
>> +             break;
>> +     case TYPE_EXYNOS4210:
>> +             phypwr &= ~PHYPWR_NORMAL_MASK_PHY0;
>> +             rstcon |= RSTCON_SWRST;
>> +     default:
>> +             break;
>> +     }
>> +
>> +     writel(phyclk, regs + SAMSUNG_PHYCLK);
>> +     /* set to normal of PHY0 */
>
> I don't understand this comment.
Will change it to " Configure PHY0 for normal operation"
That should be more clear, I suppose.
>
>> +     writel(phypwr, regs + SAMSUNG_PHYPWR);
>> +     /* reset all ports of PHY and Link */
>> +     writel(rstcon, regs + SAMSUNG_RSTCON);
>> +     udelay(10);
>> +     rstcon &= ~RSTCON_SWRST;
>> +     writel(rstcon, regs + SAMSUNG_RSTCON);
>> +}
>> +
>> +static void samsung_usbphy_disable(struct samsung_usbphy *sphy)
>> +{
>> +     void __iomem *regs = sphy->regs;
>> +     u32 phypwr;
>> +
>> +     phypwr = readl(regs + SAMSUNG_PHYPWR);
>> +
>> +     switch (sphy->cpu_type) {
>> +     case TYPE_S3C64XX:
>> +             phypwr |= PHYPWR_NORMAL_MASK;
>> +             break;
>> +     case TYPE_EXYNOS4210:
>> +             phypwr |= PHYPWR_NORMAL_MASK_PHY0;
>> +     default:
>> +             break;
>> +     }
>> +
>> +     /* unset to normal of PHY0 */
Will change this as well
>
> I don't understand this comment.
>
>> +     writel(phypwr, regs + SAMSUNG_PHYPWR);
>> +}
>> +
>> +/*
>> + * The function passed to the usb driver for phy initialization
>> + */
>> +static int samsung_usbphy_init(struct usb_phy *phy)
>> +{
>> +     struct samsung_usbphy *sphy;
>> +     int ret = 0;
>> +
>> +     sphy = phy_to_sphy(phy);
>> +
>> +     /* Enable the phy clock */
>> +     ret = clk_prepare_enable(sphy->clk);
>> +     if (ret) {
>> +             dev_err(sphy->dev, "%s: clk_prepare_enable failed\n",
> __func__);
>> +             return ret;
>> +     }
>> +
>> +     /* Disable phy isolation */
>> +     if (sphy->plat && sphy->plat->pmu_isolation)
>> +             sphy->plat->pmu_isolation(false);
>> +
>> +     /* Initialize usb phy registers */
>> +     samsung_usbphy_enable(sphy);
>> +
>> +     /* Disable the phy clock */
>> +     clk_disable_unprepare(sphy->clk);
>> +     return ret;
>> +}
>> +
>> +/*
>> + * The function passed to the usb driver for phy shutdown
>> + */
>> +static void samsung_usbphy_shutdown(struct usb_phy *phy)
>> +{
>> +     struct samsung_usbphy *sphy;
>> +
>> +     sphy = phy_to_sphy(phy);
>> +
>> +     if (clk_prepare_enable(sphy->clk)) {
>> +             dev_err(sphy->dev, "%s: clk_prepare_enable failed\n",
> __func__);
>> +             return;
>> +     }
>> +
>> +     /* De-initialize usb phy registers */
>> +     samsung_usbphy_disable(sphy);
>> +
>> +     /* Enable phy isolation */
>> +     if (sphy->plat && sphy->plat->pmu_isolation)
>> +             sphy->plat->pmu_isolation(true);
>> +
>> +     clk_disable_unprepare(sphy->clk);
>> +}
>> +
>> +static const struct of_device_id samsung_usbphy_dt_match[];
>> +
>> +static inline int samsung_usbphy_get_driver_data(struct platform_device
>> *pdev) +{
>> +     if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node) {
>
> if (pdev->dev.of_node) {
>
> CONFIG_OF is not needed to check whether dev.of_node is not NULL and if
> dev.of_node is always NULL with CONFIG_OF disabled, so this check is
> enough.
>
Right! Sorry I guess you had pointed it our earlier also. Will update :)
>> +             int data;
>
> You can remove this variable and...
>
>> +             const struct of_device_id *match;
>> +             match = of_match_node(samsung_usbphy_dt_match,
>> +                                                     pdev->dev.of_node);
>> +             data = (int) match->data;
>> +             return data;
>
> return (int) match->data;
>
>> +     }
>> +
>> +     return platform_get_device_id(pdev)->driver_data;
>> +}
>> +
>> +static int __devinit samsung_usbphy_probe(struct platform_device *pdev)
>> +{
>> +     struct samsung_usbphy *sphy;
>> +     struct samsung_usbphy_data *pdata;
>> +     struct device *dev = &pdev->dev;
>> +     struct resource *phy_mem;
>> +     void __iomem    *phy_base;
>> +     struct clk *clk;
>> +     int     ret = 0;
>> +
>> +     pdata = pdev->dev.platform_data;
>> +     if (!pdata) {
>> +             dev_err(&pdev->dev, "%s: no platform data defined\n",
> __func__);
>> +             return -EINVAL;
>> +     }
>> +
>> +     phy_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>> +     if (!phy_mem) {
>> +             dev_err(dev, "%s: missing mem resource\n", __func__);
>> +             return -ENODEV;
>> +     }
>> +
>> +     phy_base = devm_request_and_ioremap(dev, phy_mem);
>> +     if (!phy_base) {
>> +             dev_err(dev, "%s: register mapping failed\n", __func__);
>> +             return -ENXIO;
>> +     }
>> +
>> +     sphy = devm_kzalloc(dev, sizeof(*sphy), GFP_KERNEL);
>> +     if (!sphy)
>> +             return -ENOMEM;
>> +
>> +     clk = devm_clk_get(dev, "otg");
>> +     if (IS_ERR(clk)) {
>> +             dev_err(dev, "Failed to get otg clock\n");
>> +             return PTR_ERR(clk);
>> +     }
>> +
>> +     sphy->dev               = &pdev->dev;
>> +     sphy->plat              = pdata;
>> +     sphy->regs              = phy_base;
>> +     sphy->clk               = clk;
>> +     sphy->phy.dev           = sphy->dev;
>> +     sphy->phy.label         = "samsung-usbphy";
>> +     sphy->phy.init          = samsung_usbphy_init;
>> +     sphy->phy.shutdown      = samsung_usbphy_shutdown;
>> +     sphy->cpu_type          = samsung_usbphy_get_driver_data(pdev);
>> +     sphy->ref_clk_freq      = samsung_usbphy_get_refclk_freq(sphy);
>> +
>> +     platform_set_drvdata(pdev, sphy);
>> +
>> +     ret = usb_add_phy(&sphy->phy, USB_PHY_TYPE_USB2);
>> +     return ret;
>
> return usb_add_phy(&sphy->phy, USB_PHY_TYPE_USB2);
>
>> +}
>> +
>> +static int __exit samsung_usbphy_remove(struct platform_device *pdev)
>> +{
>> +     struct samsung_usbphy *sphy = platform_get_drvdata(pdev);
>> +
>> +     usb_remove_phy(&sphy->phy);
>> +
>> +     return 0;
>> +}
>> +
>> +#ifdef CONFIG_OF
>> +static const struct of_device_id samsung_usbphy_dt_match[] = {
>> +     {
>> +             .compatible = "samsung,s3c64xx-usbphy",
>> +             .data = (void *)TYPE_S3C64XX,
>> +     }, {
>> +             .compatible = "samsung,exynos4210-usbphy",
>> +             .data = (void *)TYPE_EXYNOS4210,
>> +     },
>> +     {},
>> +};
>> +MODULE_DEVICE_TABLE(of, samsung_usbphy_dt_match);
>> +#else
>> +#define samsung_usbphy_dt_match NULL
>> +#endif
>
> Instead of using else and defining samsung_usbphy_dt_match manually,
> instead you can use of_match_ptr macro. (See my next comment.)
sure
>
>> +
>> +static struct platform_device_id samsung_usbphy_driver_ids[] = {
>> +     {
>> +             .name           = "s3c64xx-usbphy",
>> +             .driver_data    = TYPE_S3C64XX,
>> +     }, {
>> +             .name           = "exynos4210-usbphy",
>> +             .driver_data    = TYPE_EXYNOS4210,
>> +     },
>> +     {},
>> +};
>> +
>> +MODULE_DEVICE_TABLE(platform, samsung_usbphy_driver_ids);
>> +
>> +static struct platform_driver samsung_usbphy_driver = {
>> +     .probe          = samsung_usbphy_probe,
>> +     .remove         = __devexit_p(samsung_usbphy_remove),
>> +     .id_table       = samsung_usbphy_driver_ids,
>> +     .driver         = {
>> +             .name   = "samsung-usbphy",
>> +             .owner  = THIS_MODULE,
>> +             .of_match_table = samsung_usbphy_dt_match,
>
> .of_match_table = of_match_ptr(samsung_usbphy_dt_match),
>
>> +     },
>> +};
>> +
>> +module_platform_driver(samsung_usbphy_driver);
>> +
>> +MODULE_DESCRIPTION("Samsung USB phy controller");
>> +MODULE_AUTHOR("Praveen Paneri <p.paneri@samsung.com>");
>> +MODULE_LICENSE("GPL");
>> +MODULE_ALIAS("platform:samsung-usbphy");
>> diff --git a/include/linux/platform_data/samsung-usbphy.h
>> b/include/linux/platform_data/samsung-usbphy.h new file mode 100644
>> index 0000000..1bd24cb
>> --- /dev/null
>> +++ b/include/linux/platform_data/samsung-usbphy.h
>> @@ -0,0 +1,27 @@
>> +/*
>> + * Copyright (C) 2012 Samsung Electronics Co.Ltd
>> + *           http://www.samsung.com/
>> + * Author: Praveen Paneri <p.paneri@samsung.com>
>> + *
>> + * Defines platform data for samsung usb phy driver.
>> + *
>> + * 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;  either version 2 of the
>>  License, or (at your + * option) any later version.
>> + */
>> +
>> +#ifndef __SAMSUNG_USBPHY_PLATFORM_H
>> +#define __SAMSUNG_USBPHY_PLATFORM_H
>> +
>> +/**
>> + * samsung_usbphy_data - Platform data for USB PHY driver.
>> + * @pmu_isolation: Function to control usb phy isolation in PMU.
>> + */
>> +struct samsung_usbphy_data {
>> +     void (*pmu_isolation)(int on);
>
> I believe this should be named in a generic way. This is called PMU
> isolation on Exynos SoCs, but on S3C64xx it's USB PHY mask.
Yes! I am aware of it. The fact that this ( MASK or ISOLATION) has
always been part of the PMU, pmu_isolation seems quite generic that
way. Though you can suggest a better name.

Regards,
Praveen
>
> Best regards,
> Tomasz Figa
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-usb" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH v8 1/2] usb: phy: samsung: Introducing usb phy driver for hsotg
@ 2012-11-23  4:26           ` Praveen Paneri
  0 siblings, 0 replies; 28+ messages in thread
From: Praveen Paneri @ 2012-11-23  4:26 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Tomasz,

On Thu, Nov 22, 2012 at 1:36 AM, Tomasz Figa <tomasz.figa@gmail.com> wrote:
> Hi Praveen,
>
> See some minor comments inline.
Thanks for your comments
>
> On Wednesday 14 of November 2012 15:57:15 Praveen Paneri wrote:
>> This driver uses usb_phy interface to interact with s3c-hsotg. Supports
>> phy_init and phy_shutdown functions to enable/disable usb phy. Support
>> will be extended to host controllers and more Samsung SoCs.
>>
>> Signed-off-by: Praveen Paneri <p.paneri@samsung.com>
>> Acked-by: Heiko Stuebner <heiko@sntech.de>
>> Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
>> ---
>>  .../devicetree/bindings/usb/samsung-usbphy.txt     |   11 +
>>  drivers/usb/phy/Kconfig                            |    8 +
>>  drivers/usb/phy/Makefile                           |    1 +
>>  drivers/usb/phy/samsung-usbphy.c                   |  360
>> ++++++++++++++++++++ include/linux/platform_data/samsung-usbphy.h
>> |   27 ++
>>  5 files changed, 407 insertions(+), 0 deletions(-)
>>  create mode 100644
>> Documentation/devicetree/bindings/usb/samsung-usbphy.txt create mode
>> 100644 drivers/usb/phy/samsung-usbphy.c
>>  create mode 100644 include/linux/platform_data/samsung-usbphy.h
>>
>> diff --git a/Documentation/devicetree/bindings/usb/samsung-usbphy.txt
>> b/Documentation/devicetree/bindings/usb/samsung-usbphy.txt new file
>> mode 100644
>> index 0000000..7b26e2d
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/usb/samsung-usbphy.txt
>> @@ -0,0 +1,11 @@
>> +* Samsung's usb phy transceiver
>> +
>> +The Samsung's phy transceiver is used for controlling usb otg phy for
>> +s3c-hsotg usb device controller.
>> +TODO: Adding the PHY binding with controller(s) according to the under
>> +developement generic PHY driver.
>> +
>> +Required properties:
>> +- compatible : should be "samsung,exynos4210-usbphy"
>> +- reg : base physical address of the phy registers and length of memory
>> mapped +      region.
>> diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig
>> index 7eb73c5..17ad743 100644
>> --- a/drivers/usb/phy/Kconfig
>> +++ b/drivers/usb/phy/Kconfig
>> @@ -44,3 +44,11 @@ config USB_RCAR_PHY
>>
>>         To compile this driver as a module, choose M here: the
>>         module will be called rcar-phy.
>> +
>> +config SAMSUNG_USBPHY
>> +     bool "Samsung USB PHY controller Driver"
>> +     depends on USB_S3C_HSOTG
>> +     select USB_OTG_UTILS
>> +     help
>> +       Enable this to support Samsung USB phy controller for samsung
>> +       SoCs.
>> diff --git a/drivers/usb/phy/Makefile b/drivers/usb/phy/Makefile
>> index 1a579a8..ec304f6 100644
>> --- a/drivers/usb/phy/Makefile
>> +++ b/drivers/usb/phy/Makefile
>> @@ -9,3 +9,4 @@ 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
>> +obj-$(CONFIG_SAMSUNG_USBPHY)         += samsung-usbphy.o
>> diff --git a/drivers/usb/phy/samsung-usbphy.c
>> b/drivers/usb/phy/samsung-usbphy.c new file mode 100644
>> index 0000000..3c84aab
>> --- /dev/null
>> +++ b/drivers/usb/phy/samsung-usbphy.c
>> @@ -0,0 +1,360 @@
>> +/* linux/drivers/usb/phy/samsung-usbphy.c
>> + *
>> + * Copyright (c) 2012 Samsung Electronics Co., Ltd.
>> + *              http://www.samsung.com
>> + *
>> + * Author: Praveen Paneri <p.paneri@samsung.com>
>> + *
>> + * Samsung USB2.0 High-speed OTG transceiver, talks to S3C HS OTG
>> controller + *
>> + * 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.
>> + *
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; 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/platform_device.h>
>> +#include <linux/clk.h>
>> +#include <linux/delay.h>
>> +#include <linux/err.h>
>> +#include <linux/io.h>
>> +#include <linux/of.h>
>> +#include <linux/usb/otg.h>
>> +#include <linux/platform_data/samsung-usbphy.h>
>> +
>> +/* Register definitions */
>> +
>> +#define SAMSUNG_PHYPWR                               (0x00)
>> +
>> +#define PHYPWR_NORMAL_MASK                   (0x19 << 0)
>> +#define PHYPWR_OTG_DISABLE                   (0x1 << 4)
>> +#define PHYPWR_ANALOG_POWERDOWN                      (0x1 << 3)
>> +#define PHYPWR_FORCE_SUSPEND                 (0x1 << 1)
>> +/* For Exynos4 */
>> +#define PHYPWR_NORMAL_MASK_PHY0                      (0x39 << 0)
>> +#define PHYPWR_SLEEP_PHY0                    (0x1 << 5)
>> +
>> +#define SAMSUNG_PHYCLK                               (0x04)
>> +
>> +#define PHYCLK_MODE_USB11                    (0x1 << 6)
>> +#define PHYCLK_EXT_OSC                               (0x1 << 5)
>> +#define PHYCLK_COMMON_ON_N                   (0x1 << 4)
>> +#define PHYCLK_ID_PULL                               (0x1 << 2)
>> +#define PHYCLK_CLKSEL_MASK                   (0x3 << 0)
>> +#define PHYCLK_CLKSEL_48M                    (0x0 << 0)
>> +#define PHYCLK_CLKSEL_12M                    (0x2 << 0)
>> +#define PHYCLK_CLKSEL_24M                    (0x3 << 0)
>> +
>> +#define SAMSUNG_RSTCON                               (0x08)
>> +
>> +#define RSTCON_PHYLINK_SWRST                 (0x1 << 2)
>> +#define RSTCON_HLINK_SWRST                   (0x1 << 1)
>> +#define RSTCON_SWRST                         (0x1 << 0)
>> +
>> +#ifndef MHZ
>> +#define MHZ (1000*1000)
>> +#endif
>> +
>> +enum samsung_cpu_type {
>> +     TYPE_S3C64XX,
>> +     TYPE_EXYNOS4210,
>> +};
>> +
>> +/*
>> + * struct samsung_usbphy - transceiver driver state
>> + * @phy: transceiver structure
>> + * @plat: platform data
>> + * @dev: The parent device supplied to the probe function
>> + * @clk: usb phy clock
>> + * @regs: usb phy register memory base
>> + * @ref_clk_freq: reference clock frequency selection
>> + * @cpu_type: machine identifier
>> + */
>> +struct samsung_usbphy {
>> +     struct usb_phy  phy;
>> +     struct samsung_usbphy_data *plat;
>> +     struct device   *dev;
>> +     struct clk      *clk;
>> +     void __iomem    *regs;
>> +     int             ref_clk_freq;
>> +     int             cpu_type;
>> +};
>> +
>> +#define phy_to_sphy(x)               container_of((x), struct samsung_usbphy,
> phy)
>> +
>> +/*
>> + * Returns reference clock frequency selection value
>> + */
>> +static int samsung_usbphy_get_refclk_freq(struct samsung_usbphy *sphy)
>> +{
>> +     struct clk *ref_clk;
>> +     int refclk_freq = 0;
>> +
>> +     ref_clk = clk_get(sphy->dev, "xusbxti");
>> +     if (IS_ERR(ref_clk)) {
>> +             dev_err(sphy->dev, "Failed to get reference clock\n");
>> +             return PTR_ERR(ref_clk);
>> +     }
>> +
>> +     switch (clk_get_rate(ref_clk)) {
>> +     case 12 * MHZ:
>> +             refclk_freq = PHYCLK_CLKSEL_12M;
>> +             break;
>> +     case 24 * MHZ:
>> +             refclk_freq = PHYCLK_CLKSEL_24M;
>> +             break;
>> +     case 48 * MHZ:
>> +             refclk_freq = PHYCLK_CLKSEL_48M;
>> +             break;
>> +     default:
>> +             if (sphy->cpu_type == TYPE_S3C64XX)
>> +                     refclk_freq = PHYCLK_CLKSEL_48M;
>> +             else
>> +                     refclk_freq = PHYCLK_CLKSEL_24M;
>> +             break;
>> +     }
>> +     clk_put(ref_clk);
>> +
>> +     return refclk_freq;
>> +}
>> +
>> +static void samsung_usbphy_enable(struct samsung_usbphy *sphy)
>> +{
>> +     void __iomem *regs = sphy->regs;
>> +     u32 phypwr;
>> +     u32 phyclk;
>> +     u32 rstcon;
>> +
>> +     /* set clock frequency for PLL */
>> +     phyclk = sphy->ref_clk_freq;
>> +     phypwr = readl(regs + SAMSUNG_PHYPWR);
>> +     rstcon = readl(regs + SAMSUNG_RSTCON);
>> +
>> +     switch (sphy->cpu_type) {
>> +     case TYPE_S3C64XX:
>> +             phyclk &= ~PHYCLK_COMMON_ON_N;
>> +             phypwr &= ~PHYPWR_NORMAL_MASK;
>> +             rstcon |= RSTCON_SWRST;
>> +             break;
>> +     case TYPE_EXYNOS4210:
>> +             phypwr &= ~PHYPWR_NORMAL_MASK_PHY0;
>> +             rstcon |= RSTCON_SWRST;
>> +     default:
>> +             break;
>> +     }
>> +
>> +     writel(phyclk, regs + SAMSUNG_PHYCLK);
>> +     /* set to normal of PHY0 */
>
> I don't understand this comment.
Will change it to " Configure PHY0 for normal operation"
That should be more clear, I suppose.
>
>> +     writel(phypwr, regs + SAMSUNG_PHYPWR);
>> +     /* reset all ports of PHY and Link */
>> +     writel(rstcon, regs + SAMSUNG_RSTCON);
>> +     udelay(10);
>> +     rstcon &= ~RSTCON_SWRST;
>> +     writel(rstcon, regs + SAMSUNG_RSTCON);
>> +}
>> +
>> +static void samsung_usbphy_disable(struct samsung_usbphy *sphy)
>> +{
>> +     void __iomem *regs = sphy->regs;
>> +     u32 phypwr;
>> +
>> +     phypwr = readl(regs + SAMSUNG_PHYPWR);
>> +
>> +     switch (sphy->cpu_type) {
>> +     case TYPE_S3C64XX:
>> +             phypwr |= PHYPWR_NORMAL_MASK;
>> +             break;
>> +     case TYPE_EXYNOS4210:
>> +             phypwr |= PHYPWR_NORMAL_MASK_PHY0;
>> +     default:
>> +             break;
>> +     }
>> +
>> +     /* unset to normal of PHY0 */
Will change this as well
>
> I don't understand this comment.
>
>> +     writel(phypwr, regs + SAMSUNG_PHYPWR);
>> +}
>> +
>> +/*
>> + * The function passed to the usb driver for phy initialization
>> + */
>> +static int samsung_usbphy_init(struct usb_phy *phy)
>> +{
>> +     struct samsung_usbphy *sphy;
>> +     int ret = 0;
>> +
>> +     sphy = phy_to_sphy(phy);
>> +
>> +     /* Enable the phy clock */
>> +     ret = clk_prepare_enable(sphy->clk);
>> +     if (ret) {
>> +             dev_err(sphy->dev, "%s: clk_prepare_enable failed\n",
> __func__);
>> +             return ret;
>> +     }
>> +
>> +     /* Disable phy isolation */
>> +     if (sphy->plat && sphy->plat->pmu_isolation)
>> +             sphy->plat->pmu_isolation(false);
>> +
>> +     /* Initialize usb phy registers */
>> +     samsung_usbphy_enable(sphy);
>> +
>> +     /* Disable the phy clock */
>> +     clk_disable_unprepare(sphy->clk);
>> +     return ret;
>> +}
>> +
>> +/*
>> + * The function passed to the usb driver for phy shutdown
>> + */
>> +static void samsung_usbphy_shutdown(struct usb_phy *phy)
>> +{
>> +     struct samsung_usbphy *sphy;
>> +
>> +     sphy = phy_to_sphy(phy);
>> +
>> +     if (clk_prepare_enable(sphy->clk)) {
>> +             dev_err(sphy->dev, "%s: clk_prepare_enable failed\n",
> __func__);
>> +             return;
>> +     }
>> +
>> +     /* De-initialize usb phy registers */
>> +     samsung_usbphy_disable(sphy);
>> +
>> +     /* Enable phy isolation */
>> +     if (sphy->plat && sphy->plat->pmu_isolation)
>> +             sphy->plat->pmu_isolation(true);
>> +
>> +     clk_disable_unprepare(sphy->clk);
>> +}
>> +
>> +static const struct of_device_id samsung_usbphy_dt_match[];
>> +
>> +static inline int samsung_usbphy_get_driver_data(struct platform_device
>> *pdev) +{
>> +     if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node) {
>
> if (pdev->dev.of_node) {
>
> CONFIG_OF is not needed to check whether dev.of_node is not NULL and if
> dev.of_node is always NULL with CONFIG_OF disabled, so this check is
> enough.
>
Right! Sorry I guess you had pointed it our earlier also. Will update :)
>> +             int data;
>
> You can remove this variable and...
>
>> +             const struct of_device_id *match;
>> +             match = of_match_node(samsung_usbphy_dt_match,
>> +                                                     pdev->dev.of_node);
>> +             data = (int) match->data;
>> +             return data;
>
> return (int) match->data;
>
>> +     }
>> +
>> +     return platform_get_device_id(pdev)->driver_data;
>> +}
>> +
>> +static int __devinit samsung_usbphy_probe(struct platform_device *pdev)
>> +{
>> +     struct samsung_usbphy *sphy;
>> +     struct samsung_usbphy_data *pdata;
>> +     struct device *dev = &pdev->dev;
>> +     struct resource *phy_mem;
>> +     void __iomem    *phy_base;
>> +     struct clk *clk;
>> +     int     ret = 0;
>> +
>> +     pdata = pdev->dev.platform_data;
>> +     if (!pdata) {
>> +             dev_err(&pdev->dev, "%s: no platform data defined\n",
> __func__);
>> +             return -EINVAL;
>> +     }
>> +
>> +     phy_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>> +     if (!phy_mem) {
>> +             dev_err(dev, "%s: missing mem resource\n", __func__);
>> +             return -ENODEV;
>> +     }
>> +
>> +     phy_base = devm_request_and_ioremap(dev, phy_mem);
>> +     if (!phy_base) {
>> +             dev_err(dev, "%s: register mapping failed\n", __func__);
>> +             return -ENXIO;
>> +     }
>> +
>> +     sphy = devm_kzalloc(dev, sizeof(*sphy), GFP_KERNEL);
>> +     if (!sphy)
>> +             return -ENOMEM;
>> +
>> +     clk = devm_clk_get(dev, "otg");
>> +     if (IS_ERR(clk)) {
>> +             dev_err(dev, "Failed to get otg clock\n");
>> +             return PTR_ERR(clk);
>> +     }
>> +
>> +     sphy->dev               = &pdev->dev;
>> +     sphy->plat              = pdata;
>> +     sphy->regs              = phy_base;
>> +     sphy->clk               = clk;
>> +     sphy->phy.dev           = sphy->dev;
>> +     sphy->phy.label         = "samsung-usbphy";
>> +     sphy->phy.init          = samsung_usbphy_init;
>> +     sphy->phy.shutdown      = samsung_usbphy_shutdown;
>> +     sphy->cpu_type          = samsung_usbphy_get_driver_data(pdev);
>> +     sphy->ref_clk_freq      = samsung_usbphy_get_refclk_freq(sphy);
>> +
>> +     platform_set_drvdata(pdev, sphy);
>> +
>> +     ret = usb_add_phy(&sphy->phy, USB_PHY_TYPE_USB2);
>> +     return ret;
>
> return usb_add_phy(&sphy->phy, USB_PHY_TYPE_USB2);
>
>> +}
>> +
>> +static int __exit samsung_usbphy_remove(struct platform_device *pdev)
>> +{
>> +     struct samsung_usbphy *sphy = platform_get_drvdata(pdev);
>> +
>> +     usb_remove_phy(&sphy->phy);
>> +
>> +     return 0;
>> +}
>> +
>> +#ifdef CONFIG_OF
>> +static const struct of_device_id samsung_usbphy_dt_match[] = {
>> +     {
>> +             .compatible = "samsung,s3c64xx-usbphy",
>> +             .data = (void *)TYPE_S3C64XX,
>> +     }, {
>> +             .compatible = "samsung,exynos4210-usbphy",
>> +             .data = (void *)TYPE_EXYNOS4210,
>> +     },
>> +     {},
>> +};
>> +MODULE_DEVICE_TABLE(of, samsung_usbphy_dt_match);
>> +#else
>> +#define samsung_usbphy_dt_match NULL
>> +#endif
>
> Instead of using else and defining samsung_usbphy_dt_match manually,
> instead you can use of_match_ptr macro. (See my next comment.)
sure
>
>> +
>> +static struct platform_device_id samsung_usbphy_driver_ids[] = {
>> +     {
>> +             .name           = "s3c64xx-usbphy",
>> +             .driver_data    = TYPE_S3C64XX,
>> +     }, {
>> +             .name           = "exynos4210-usbphy",
>> +             .driver_data    = TYPE_EXYNOS4210,
>> +     },
>> +     {},
>> +};
>> +
>> +MODULE_DEVICE_TABLE(platform, samsung_usbphy_driver_ids);
>> +
>> +static struct platform_driver samsung_usbphy_driver = {
>> +     .probe          = samsung_usbphy_probe,
>> +     .remove         = __devexit_p(samsung_usbphy_remove),
>> +     .id_table       = samsung_usbphy_driver_ids,
>> +     .driver         = {
>> +             .name   = "samsung-usbphy",
>> +             .owner  = THIS_MODULE,
>> +             .of_match_table = samsung_usbphy_dt_match,
>
> .of_match_table = of_match_ptr(samsung_usbphy_dt_match),
>
>> +     },
>> +};
>> +
>> +module_platform_driver(samsung_usbphy_driver);
>> +
>> +MODULE_DESCRIPTION("Samsung USB phy controller");
>> +MODULE_AUTHOR("Praveen Paneri <p.paneri@samsung.com>");
>> +MODULE_LICENSE("GPL");
>> +MODULE_ALIAS("platform:samsung-usbphy");
>> diff --git a/include/linux/platform_data/samsung-usbphy.h
>> b/include/linux/platform_data/samsung-usbphy.h new file mode 100644
>> index 0000000..1bd24cb
>> --- /dev/null
>> +++ b/include/linux/platform_data/samsung-usbphy.h
>> @@ -0,0 +1,27 @@
>> +/*
>> + * Copyright (C) 2012 Samsung Electronics Co.Ltd
>> + *           http://www.samsung.com/
>> + * Author: Praveen Paneri <p.paneri@samsung.com>
>> + *
>> + * Defines platform data for samsung usb phy driver.
>> + *
>> + * 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;  either version 2 of the
>>  License, or (at your + * option) any later version.
>> + */
>> +
>> +#ifndef __SAMSUNG_USBPHY_PLATFORM_H
>> +#define __SAMSUNG_USBPHY_PLATFORM_H
>> +
>> +/**
>> + * samsung_usbphy_data - Platform data for USB PHY driver.
>> + * @pmu_isolation: Function to control usb phy isolation in PMU.
>> + */
>> +struct samsung_usbphy_data {
>> +     void (*pmu_isolation)(int on);
>
> I believe this should be named in a generic way. This is called PMU
> isolation on Exynos SoCs, but on S3C64xx it's USB PHY mask.
Yes! I am aware of it. The fact that this ( MASK or ISOLATION) has
always been part of the PMU, pmu_isolation seems quite generic that
way. Though you can suggest a better name.

Regards,
Praveen
>
> Best regards,
> Tomasz Figa
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-usb" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH v9 1/2] usb: phy: samsung: Introducing usb phy driver for hsotg
  2012-11-23  4:26           ` Praveen Paneri
@ 2012-11-23 10:33               ` Praveen Paneri
  -1 siblings, 0 replies; 28+ messages in thread
From: Praveen Paneri @ 2012-11-23 10:33 UTC (permalink / raw)
  To: linux-usb-u79uwXL29TY76Z2rM5mHXA
  Cc: l.majewski-Sze3O3UU22JBDgjK7y7TUQ,
	kgene.kim-Sze3O3UU22JBDgjK7y7TUQ, heiko-4mtYJXux2i+zQB+pC5nmwQ,
	gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	broonie-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E,
	balbi-l0cyMroinI0, kyungmin.park-Sze3O3UU22JBDgjK7y7TUQ,
	linux-samsung-soc-u79uwXL29TY76Z2rM5mHXA,
	gautam.vivek-Sze3O3UU22JBDgjK7y7TUQ,
	ben-linux-elnMNo+KYs3YtjvyW6yDsg,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

This driver uses usb_phy interface to interact with s3c-hsotg. Supports
phy_init and phy_shutdown functions to enable/disable usb phy. Support
will be extended to host controllers and more Samsung SoCs.

Signed-off-by: Praveen Paneri <p.paneri-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
Acked-by: Heiko Stuebner <heiko-4mtYJXux2i+zQB+pC5nmwQ@public.gmane.org>
Acked-by: Kyungmin Park <kyungmin.park-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
---
 .../devicetree/bindings/usb/samsung-usbphy.txt     |   11 +
 drivers/usb/phy/Kconfig                            |    8 +
 drivers/usb/phy/Makefile                           |    1 +
 drivers/usb/phy/samsung-usbphy.c                   |  354 ++++++++++++++++++++
 include/linux/platform_data/samsung-usbphy.h       |   27 ++
 5 files changed, 401 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/usb/samsung-usbphy.txt
 create mode 100644 drivers/usb/phy/samsung-usbphy.c
 create mode 100644 include/linux/platform_data/samsung-usbphy.h

diff --git a/Documentation/devicetree/bindings/usb/samsung-usbphy.txt b/Documentation/devicetree/bindings/usb/samsung-usbphy.txt
new file mode 100644
index 0000000..7b26e2d
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/samsung-usbphy.txt
@@ -0,0 +1,11 @@
+* Samsung's usb phy transceiver
+
+The Samsung's phy transceiver is used for controlling usb otg phy for
+s3c-hsotg usb device controller.
+TODO: Adding the PHY binding with controller(s) according to the under
+developement generic PHY driver.
+
+Required properties:
+- compatible : should be "samsung,exynos4210-usbphy"
+- reg : base physical address of the phy registers and length of memory mapped
+	region.
diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig
index 7eb73c5..17ad743 100644
--- a/drivers/usb/phy/Kconfig
+++ b/drivers/usb/phy/Kconfig
@@ -44,3 +44,11 @@ config USB_RCAR_PHY
 
 	  To compile this driver as a module, choose M here: the
 	  module will be called rcar-phy.
+
+config SAMSUNG_USBPHY
+	bool "Samsung USB PHY controller Driver"
+	depends on USB_S3C_HSOTG
+	select USB_OTG_UTILS
+	help
+	  Enable this to support Samsung USB phy controller for samsung
+	  SoCs.
diff --git a/drivers/usb/phy/Makefile b/drivers/usb/phy/Makefile
index 1a579a8..ec304f6 100644
--- a/drivers/usb/phy/Makefile
+++ b/drivers/usb/phy/Makefile
@@ -9,3 +9,4 @@ 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
+obj-$(CONFIG_SAMSUNG_USBPHY)		+= samsung-usbphy.o
diff --git a/drivers/usb/phy/samsung-usbphy.c b/drivers/usb/phy/samsung-usbphy.c
new file mode 100644
index 0000000..5c5e1bb
--- /dev/null
+++ b/drivers/usb/phy/samsung-usbphy.c
@@ -0,0 +1,354 @@
+/* linux/drivers/usb/phy/samsung-usbphy.c
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *              http://www.samsung.com
+ *
+ * Author: Praveen Paneri <p.paneri-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
+ *
+ * Samsung USB2.0 High-speed OTG transceiver, talks to S3C HS OTG controller
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; 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/platform_device.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/usb/otg.h>
+#include <linux/platform_data/samsung-usbphy.h>
+
+/* Register definitions */
+
+#define SAMSUNG_PHYPWR				(0x00)
+
+#define PHYPWR_NORMAL_MASK			(0x19 << 0)
+#define PHYPWR_OTG_DISABLE			(0x1 << 4)
+#define PHYPWR_ANALOG_POWERDOWN			(0x1 << 3)
+#define PHYPWR_FORCE_SUSPEND			(0x1 << 1)
+/* For Exynos4 */
+#define PHYPWR_NORMAL_MASK_PHY0			(0x39 << 0)
+#define PHYPWR_SLEEP_PHY0			(0x1 << 5)
+
+#define SAMSUNG_PHYCLK				(0x04)
+
+#define PHYCLK_MODE_USB11			(0x1 << 6)
+#define PHYCLK_EXT_OSC				(0x1 << 5)
+#define PHYCLK_COMMON_ON_N			(0x1 << 4)
+#define PHYCLK_ID_PULL				(0x1 << 2)
+#define PHYCLK_CLKSEL_MASK			(0x3 << 0)
+#define PHYCLK_CLKSEL_48M			(0x0 << 0)
+#define PHYCLK_CLKSEL_12M			(0x2 << 0)
+#define PHYCLK_CLKSEL_24M			(0x3 << 0)
+
+#define SAMSUNG_RSTCON				(0x08)
+
+#define RSTCON_PHYLINK_SWRST			(0x1 << 2)
+#define RSTCON_HLINK_SWRST			(0x1 << 1)
+#define RSTCON_SWRST				(0x1 << 0)
+
+#ifndef MHZ
+#define MHZ (1000*1000)
+#endif
+
+enum samsung_cpu_type {
+	TYPE_S3C64XX,
+	TYPE_EXYNOS4210,
+};
+
+/*
+ * struct samsung_usbphy - transceiver driver state
+ * @phy: transceiver structure
+ * @plat: platform data
+ * @dev: The parent device supplied to the probe function
+ * @clk: usb phy clock
+ * @regs: usb phy register memory base
+ * @ref_clk_freq: reference clock frequency selection
+ * @cpu_type: machine identifier
+ */
+struct samsung_usbphy {
+	struct usb_phy	phy;
+	struct samsung_usbphy_data *plat;
+	struct device	*dev;
+	struct clk	*clk;
+	void __iomem	*regs;
+	int		ref_clk_freq;
+	int		cpu_type;
+};
+
+#define phy_to_sphy(x)		container_of((x), struct samsung_usbphy, phy)
+
+/*
+ * Returns reference clock frequency selection value
+ */
+static int samsung_usbphy_get_refclk_freq(struct samsung_usbphy *sphy)
+{
+	struct clk *ref_clk;
+	int refclk_freq = 0;
+
+	ref_clk = clk_get(sphy->dev, "xusbxti");
+	if (IS_ERR(ref_clk)) {
+		dev_err(sphy->dev, "Failed to get reference clock\n");
+		return PTR_ERR(ref_clk);
+	}
+
+	switch (clk_get_rate(ref_clk)) {
+	case 12 * MHZ:
+		refclk_freq = PHYCLK_CLKSEL_12M;
+		break;
+	case 24 * MHZ:
+		refclk_freq = PHYCLK_CLKSEL_24M;
+		break;
+	case 48 * MHZ:
+		refclk_freq = PHYCLK_CLKSEL_48M;
+		break;
+	default:
+		if (sphy->cpu_type == TYPE_S3C64XX)
+			refclk_freq = PHYCLK_CLKSEL_48M;
+		else
+			refclk_freq = PHYCLK_CLKSEL_24M;
+		break;
+	}
+	clk_put(ref_clk);
+
+	return refclk_freq;
+}
+
+static void samsung_usbphy_enable(struct samsung_usbphy *sphy)
+{
+	void __iomem *regs = sphy->regs;
+	u32 phypwr;
+	u32 phyclk;
+	u32 rstcon;
+
+	/* set clock frequency for PLL */
+	phyclk = sphy->ref_clk_freq;
+	phypwr = readl(regs + SAMSUNG_PHYPWR);
+	rstcon = readl(regs + SAMSUNG_RSTCON);
+
+	switch (sphy->cpu_type) {
+	case TYPE_S3C64XX:
+		phyclk &= ~PHYCLK_COMMON_ON_N;
+		phypwr &= ~PHYPWR_NORMAL_MASK;
+		rstcon |= RSTCON_SWRST;
+		break;
+	case TYPE_EXYNOS4210:
+		phypwr &= ~PHYPWR_NORMAL_MASK_PHY0;
+		rstcon |= RSTCON_SWRST;
+	default:
+		break;
+	}
+
+	writel(phyclk, regs + SAMSUNG_PHYCLK);
+	/* Configure PHY0 for normal operation*/
+	writel(phypwr, regs + SAMSUNG_PHYPWR);
+	/* reset all ports of PHY and Link */
+	writel(rstcon, regs + SAMSUNG_RSTCON);
+	udelay(10);
+	rstcon &= ~RSTCON_SWRST;
+	writel(rstcon, regs + SAMSUNG_RSTCON);
+}
+
+static void samsung_usbphy_disable(struct samsung_usbphy *sphy)
+{
+	void __iomem *regs = sphy->regs;
+	u32 phypwr;
+
+	phypwr = readl(regs + SAMSUNG_PHYPWR);
+
+	switch (sphy->cpu_type) {
+	case TYPE_S3C64XX:
+		phypwr |= PHYPWR_NORMAL_MASK;
+		break;
+	case TYPE_EXYNOS4210:
+		phypwr |= PHYPWR_NORMAL_MASK_PHY0;
+	default:
+		break;
+	}
+
+	/* Disable analog and otg block power */
+	writel(phypwr, regs + SAMSUNG_PHYPWR);
+}
+
+/*
+ * The function passed to the usb driver for phy initialization
+ */
+static int samsung_usbphy_init(struct usb_phy *phy)
+{
+	struct samsung_usbphy *sphy;
+	int ret = 0;
+
+	sphy = phy_to_sphy(phy);
+
+	/* Enable the phy clock */
+	ret = clk_prepare_enable(sphy->clk);
+	if (ret) {
+		dev_err(sphy->dev, "%s: clk_prepare_enable failed\n", __func__);
+		return ret;
+	}
+
+	/* Disable phy isolation */
+	if (sphy->plat && sphy->plat->pmu_isolation)
+		sphy->plat->pmu_isolation(false);
+
+	/* Initialize usb phy registers */
+	samsung_usbphy_enable(sphy);
+
+	/* Disable the phy clock */
+	clk_disable_unprepare(sphy->clk);
+	return ret;
+}
+
+/*
+ * The function passed to the usb driver for phy shutdown
+ */
+static void samsung_usbphy_shutdown(struct usb_phy *phy)
+{
+	struct samsung_usbphy *sphy;
+
+	sphy = phy_to_sphy(phy);
+
+	if (clk_prepare_enable(sphy->clk)) {
+		dev_err(sphy->dev, "%s: clk_prepare_enable failed\n", __func__);
+		return;
+	}
+
+	/* De-initialize usb phy registers */
+	samsung_usbphy_disable(sphy);
+
+	/* Enable phy isolation */
+	if (sphy->plat && sphy->plat->pmu_isolation)
+		sphy->plat->pmu_isolation(true);
+
+	clk_disable_unprepare(sphy->clk);
+}
+
+static const struct of_device_id samsung_usbphy_dt_match[];
+
+static inline int samsung_usbphy_get_driver_data(struct platform_device *pdev)
+{
+	if (pdev->dev.of_node) {
+		const struct of_device_id *match;
+		match = of_match_node(samsung_usbphy_dt_match,
+							pdev->dev.of_node);
+		return (int) match->data;
+	}
+
+	return platform_get_device_id(pdev)->driver_data;
+}
+
+static int __devinit samsung_usbphy_probe(struct platform_device *pdev)
+{
+	struct samsung_usbphy *sphy;
+	struct samsung_usbphy_data *pdata;
+	struct device *dev = &pdev->dev;
+	struct resource *phy_mem;
+	void __iomem	*phy_base;
+	struct clk *clk;
+
+	pdata = pdev->dev.platform_data;
+	if (!pdata) {
+		dev_err(&pdev->dev, "%s: no platform data defined\n", __func__);
+		return -EINVAL;
+	}
+
+	phy_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!phy_mem) {
+		dev_err(dev, "%s: missing mem resource\n", __func__);
+		return -ENODEV;
+	}
+
+	phy_base = devm_request_and_ioremap(dev, phy_mem);
+	if (!phy_base) {
+		dev_err(dev, "%s: register mapping failed\n", __func__);
+		return -ENXIO;
+	}
+
+	sphy = devm_kzalloc(dev, sizeof(*sphy), GFP_KERNEL);
+	if (!sphy)
+		return -ENOMEM;
+
+	clk = devm_clk_get(dev, "otg");
+	if (IS_ERR(clk)) {
+		dev_err(dev, "Failed to get otg clock\n");
+		return PTR_ERR(clk);
+	}
+
+	sphy->dev		= &pdev->dev;
+	sphy->plat		= pdata;
+	sphy->regs		= phy_base;
+	sphy->clk		= clk;
+	sphy->phy.dev		= sphy->dev;
+	sphy->phy.label		= "samsung-usbphy";
+	sphy->phy.init		= samsung_usbphy_init;
+	sphy->phy.shutdown	= samsung_usbphy_shutdown;
+	sphy->cpu_type		= samsung_usbphy_get_driver_data(pdev);
+	sphy->ref_clk_freq	= samsung_usbphy_get_refclk_freq(sphy);
+
+	platform_set_drvdata(pdev, sphy);
+
+	return usb_add_phy(&sphy->phy, USB_PHY_TYPE_USB2);
+}
+
+static int __exit samsung_usbphy_remove(struct platform_device *pdev)
+{
+	struct samsung_usbphy *sphy = platform_get_drvdata(pdev);
+
+	usb_remove_phy(&sphy->phy);
+
+	return 0;
+}
+
+#ifdef CONFIG_OF
+static const struct of_device_id samsung_usbphy_dt_match[] = {
+	{
+		.compatible = "samsung,s3c64xx-usbphy",
+		.data = (void *)TYPE_S3C64XX,
+	}, {
+		.compatible = "samsung,exynos4210-usbphy",
+		.data = (void *)TYPE_EXYNOS4210,
+	},
+	{},
+};
+MODULE_DEVICE_TABLE(of, samsung_usbphy_dt_match);
+#endif
+
+static struct platform_device_id samsung_usbphy_driver_ids[] = {
+	{
+		.name		= "s3c64xx-usbphy",
+		.driver_data	= TYPE_S3C64XX,
+	}, {
+		.name		= "exynos4210-usbphy",
+		.driver_data	= TYPE_EXYNOS4210,
+	},
+	{},
+};
+
+MODULE_DEVICE_TABLE(platform, samsung_usbphy_driver_ids);
+
+static struct platform_driver samsung_usbphy_driver = {
+	.probe		= samsung_usbphy_probe,
+	.remove		= __devexit_p(samsung_usbphy_remove),
+	.id_table	= samsung_usbphy_driver_ids,
+	.driver		= {
+		.name	= "samsung-usbphy",
+		.owner	= THIS_MODULE,
+		.of_match_table = of_match_ptr(samsung_usbphy_dt_match),
+	},
+};
+
+module_platform_driver(samsung_usbphy_driver);
+
+MODULE_DESCRIPTION("Samsung USB phy controller");
+MODULE_AUTHOR("Praveen Paneri <p.paneri-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:samsung-usbphy");
diff --git a/include/linux/platform_data/samsung-usbphy.h b/include/linux/platform_data/samsung-usbphy.h
new file mode 100644
index 0000000..1bd24cb
--- /dev/null
+++ b/include/linux/platform_data/samsung-usbphy.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2012 Samsung Electronics Co.Ltd
+ *		http://www.samsung.com/
+ * Author: Praveen Paneri <p.paneri-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
+ *
+ * Defines platform data for samsung usb phy driver.
+ *
+ * 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;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#ifndef __SAMSUNG_USBPHY_PLATFORM_H
+#define __SAMSUNG_USBPHY_PLATFORM_H
+
+/**
+ * samsung_usbphy_data - Platform data for USB PHY driver.
+ * @pmu_isolation: Function to control usb phy isolation in PMU.
+ */
+struct samsung_usbphy_data {
+	void (*pmu_isolation)(int on);
+};
+
+extern void samsung_usbphy_set_pdata(struct samsung_usbphy_data *pd);
+
+#endif /* __SAMSUNG_USBPHY_PLATFORM_H */
-- 
1.7.1

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

* [PATCH v9 1/2] usb: phy: samsung: Introducing usb phy driver for hsotg
@ 2012-11-23 10:33               ` Praveen Paneri
  0 siblings, 0 replies; 28+ messages in thread
From: Praveen Paneri @ 2012-11-23 10:33 UTC (permalink / raw)
  To: linux-arm-kernel

This driver uses usb_phy interface to interact with s3c-hsotg. Supports
phy_init and phy_shutdown functions to enable/disable usb phy. Support
will be extended to host controllers and more Samsung SoCs.

Signed-off-by: Praveen Paneri <p.paneri@samsung.com>
Acked-by: Heiko Stuebner <heiko@sntech.de>
Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 .../devicetree/bindings/usb/samsung-usbphy.txt     |   11 +
 drivers/usb/phy/Kconfig                            |    8 +
 drivers/usb/phy/Makefile                           |    1 +
 drivers/usb/phy/samsung-usbphy.c                   |  354 ++++++++++++++++++++
 include/linux/platform_data/samsung-usbphy.h       |   27 ++
 5 files changed, 401 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/usb/samsung-usbphy.txt
 create mode 100644 drivers/usb/phy/samsung-usbphy.c
 create mode 100644 include/linux/platform_data/samsung-usbphy.h

diff --git a/Documentation/devicetree/bindings/usb/samsung-usbphy.txt b/Documentation/devicetree/bindings/usb/samsung-usbphy.txt
new file mode 100644
index 0000000..7b26e2d
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/samsung-usbphy.txt
@@ -0,0 +1,11 @@
+* Samsung's usb phy transceiver
+
+The Samsung's phy transceiver is used for controlling usb otg phy for
+s3c-hsotg usb device controller.
+TODO: Adding the PHY binding with controller(s) according to the under
+developement generic PHY driver.
+
+Required properties:
+- compatible : should be "samsung,exynos4210-usbphy"
+- reg : base physical address of the phy registers and length of memory mapped
+	region.
diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig
index 7eb73c5..17ad743 100644
--- a/drivers/usb/phy/Kconfig
+++ b/drivers/usb/phy/Kconfig
@@ -44,3 +44,11 @@ config USB_RCAR_PHY
 
 	  To compile this driver as a module, choose M here: the
 	  module will be called rcar-phy.
+
+config SAMSUNG_USBPHY
+	bool "Samsung USB PHY controller Driver"
+	depends on USB_S3C_HSOTG
+	select USB_OTG_UTILS
+	help
+	  Enable this to support Samsung USB phy controller for samsung
+	  SoCs.
diff --git a/drivers/usb/phy/Makefile b/drivers/usb/phy/Makefile
index 1a579a8..ec304f6 100644
--- a/drivers/usb/phy/Makefile
+++ b/drivers/usb/phy/Makefile
@@ -9,3 +9,4 @@ 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
+obj-$(CONFIG_SAMSUNG_USBPHY)		+= samsung-usbphy.o
diff --git a/drivers/usb/phy/samsung-usbphy.c b/drivers/usb/phy/samsung-usbphy.c
new file mode 100644
index 0000000..5c5e1bb
--- /dev/null
+++ b/drivers/usb/phy/samsung-usbphy.c
@@ -0,0 +1,354 @@
+/* linux/drivers/usb/phy/samsung-usbphy.c
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *              http://www.samsung.com
+ *
+ * Author: Praveen Paneri <p.paneri@samsung.com>
+ *
+ * Samsung USB2.0 High-speed OTG transceiver, talks to S3C HS OTG controller
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; 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/platform_device.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/usb/otg.h>
+#include <linux/platform_data/samsung-usbphy.h>
+
+/* Register definitions */
+
+#define SAMSUNG_PHYPWR				(0x00)
+
+#define PHYPWR_NORMAL_MASK			(0x19 << 0)
+#define PHYPWR_OTG_DISABLE			(0x1 << 4)
+#define PHYPWR_ANALOG_POWERDOWN			(0x1 << 3)
+#define PHYPWR_FORCE_SUSPEND			(0x1 << 1)
+/* For Exynos4 */
+#define PHYPWR_NORMAL_MASK_PHY0			(0x39 << 0)
+#define PHYPWR_SLEEP_PHY0			(0x1 << 5)
+
+#define SAMSUNG_PHYCLK				(0x04)
+
+#define PHYCLK_MODE_USB11			(0x1 << 6)
+#define PHYCLK_EXT_OSC				(0x1 << 5)
+#define PHYCLK_COMMON_ON_N			(0x1 << 4)
+#define PHYCLK_ID_PULL				(0x1 << 2)
+#define PHYCLK_CLKSEL_MASK			(0x3 << 0)
+#define PHYCLK_CLKSEL_48M			(0x0 << 0)
+#define PHYCLK_CLKSEL_12M			(0x2 << 0)
+#define PHYCLK_CLKSEL_24M			(0x3 << 0)
+
+#define SAMSUNG_RSTCON				(0x08)
+
+#define RSTCON_PHYLINK_SWRST			(0x1 << 2)
+#define RSTCON_HLINK_SWRST			(0x1 << 1)
+#define RSTCON_SWRST				(0x1 << 0)
+
+#ifndef MHZ
+#define MHZ (1000*1000)
+#endif
+
+enum samsung_cpu_type {
+	TYPE_S3C64XX,
+	TYPE_EXYNOS4210,
+};
+
+/*
+ * struct samsung_usbphy - transceiver driver state
+ * @phy: transceiver structure
+ * @plat: platform data
+ * @dev: The parent device supplied to the probe function
+ * @clk: usb phy clock
+ * @regs: usb phy register memory base
+ * @ref_clk_freq: reference clock frequency selection
+ * @cpu_type: machine identifier
+ */
+struct samsung_usbphy {
+	struct usb_phy	phy;
+	struct samsung_usbphy_data *plat;
+	struct device	*dev;
+	struct clk	*clk;
+	void __iomem	*regs;
+	int		ref_clk_freq;
+	int		cpu_type;
+};
+
+#define phy_to_sphy(x)		container_of((x), struct samsung_usbphy, phy)
+
+/*
+ * Returns reference clock frequency selection value
+ */
+static int samsung_usbphy_get_refclk_freq(struct samsung_usbphy *sphy)
+{
+	struct clk *ref_clk;
+	int refclk_freq = 0;
+
+	ref_clk = clk_get(sphy->dev, "xusbxti");
+	if (IS_ERR(ref_clk)) {
+		dev_err(sphy->dev, "Failed to get reference clock\n");
+		return PTR_ERR(ref_clk);
+	}
+
+	switch (clk_get_rate(ref_clk)) {
+	case 12 * MHZ:
+		refclk_freq = PHYCLK_CLKSEL_12M;
+		break;
+	case 24 * MHZ:
+		refclk_freq = PHYCLK_CLKSEL_24M;
+		break;
+	case 48 * MHZ:
+		refclk_freq = PHYCLK_CLKSEL_48M;
+		break;
+	default:
+		if (sphy->cpu_type == TYPE_S3C64XX)
+			refclk_freq = PHYCLK_CLKSEL_48M;
+		else
+			refclk_freq = PHYCLK_CLKSEL_24M;
+		break;
+	}
+	clk_put(ref_clk);
+
+	return refclk_freq;
+}
+
+static void samsung_usbphy_enable(struct samsung_usbphy *sphy)
+{
+	void __iomem *regs = sphy->regs;
+	u32 phypwr;
+	u32 phyclk;
+	u32 rstcon;
+
+	/* set clock frequency for PLL */
+	phyclk = sphy->ref_clk_freq;
+	phypwr = readl(regs + SAMSUNG_PHYPWR);
+	rstcon = readl(regs + SAMSUNG_RSTCON);
+
+	switch (sphy->cpu_type) {
+	case TYPE_S3C64XX:
+		phyclk &= ~PHYCLK_COMMON_ON_N;
+		phypwr &= ~PHYPWR_NORMAL_MASK;
+		rstcon |= RSTCON_SWRST;
+		break;
+	case TYPE_EXYNOS4210:
+		phypwr &= ~PHYPWR_NORMAL_MASK_PHY0;
+		rstcon |= RSTCON_SWRST;
+	default:
+		break;
+	}
+
+	writel(phyclk, regs + SAMSUNG_PHYCLK);
+	/* Configure PHY0 for normal operation*/
+	writel(phypwr, regs + SAMSUNG_PHYPWR);
+	/* reset all ports of PHY and Link */
+	writel(rstcon, regs + SAMSUNG_RSTCON);
+	udelay(10);
+	rstcon &= ~RSTCON_SWRST;
+	writel(rstcon, regs + SAMSUNG_RSTCON);
+}
+
+static void samsung_usbphy_disable(struct samsung_usbphy *sphy)
+{
+	void __iomem *regs = sphy->regs;
+	u32 phypwr;
+
+	phypwr = readl(regs + SAMSUNG_PHYPWR);
+
+	switch (sphy->cpu_type) {
+	case TYPE_S3C64XX:
+		phypwr |= PHYPWR_NORMAL_MASK;
+		break;
+	case TYPE_EXYNOS4210:
+		phypwr |= PHYPWR_NORMAL_MASK_PHY0;
+	default:
+		break;
+	}
+
+	/* Disable analog and otg block power */
+	writel(phypwr, regs + SAMSUNG_PHYPWR);
+}
+
+/*
+ * The function passed to the usb driver for phy initialization
+ */
+static int samsung_usbphy_init(struct usb_phy *phy)
+{
+	struct samsung_usbphy *sphy;
+	int ret = 0;
+
+	sphy = phy_to_sphy(phy);
+
+	/* Enable the phy clock */
+	ret = clk_prepare_enable(sphy->clk);
+	if (ret) {
+		dev_err(sphy->dev, "%s: clk_prepare_enable failed\n", __func__);
+		return ret;
+	}
+
+	/* Disable phy isolation */
+	if (sphy->plat && sphy->plat->pmu_isolation)
+		sphy->plat->pmu_isolation(false);
+
+	/* Initialize usb phy registers */
+	samsung_usbphy_enable(sphy);
+
+	/* Disable the phy clock */
+	clk_disable_unprepare(sphy->clk);
+	return ret;
+}
+
+/*
+ * The function passed to the usb driver for phy shutdown
+ */
+static void samsung_usbphy_shutdown(struct usb_phy *phy)
+{
+	struct samsung_usbphy *sphy;
+
+	sphy = phy_to_sphy(phy);
+
+	if (clk_prepare_enable(sphy->clk)) {
+		dev_err(sphy->dev, "%s: clk_prepare_enable failed\n", __func__);
+		return;
+	}
+
+	/* De-initialize usb phy registers */
+	samsung_usbphy_disable(sphy);
+
+	/* Enable phy isolation */
+	if (sphy->plat && sphy->plat->pmu_isolation)
+		sphy->plat->pmu_isolation(true);
+
+	clk_disable_unprepare(sphy->clk);
+}
+
+static const struct of_device_id samsung_usbphy_dt_match[];
+
+static inline int samsung_usbphy_get_driver_data(struct platform_device *pdev)
+{
+	if (pdev->dev.of_node) {
+		const struct of_device_id *match;
+		match = of_match_node(samsung_usbphy_dt_match,
+							pdev->dev.of_node);
+		return (int) match->data;
+	}
+
+	return platform_get_device_id(pdev)->driver_data;
+}
+
+static int __devinit samsung_usbphy_probe(struct platform_device *pdev)
+{
+	struct samsung_usbphy *sphy;
+	struct samsung_usbphy_data *pdata;
+	struct device *dev = &pdev->dev;
+	struct resource *phy_mem;
+	void __iomem	*phy_base;
+	struct clk *clk;
+
+	pdata = pdev->dev.platform_data;
+	if (!pdata) {
+		dev_err(&pdev->dev, "%s: no platform data defined\n", __func__);
+		return -EINVAL;
+	}
+
+	phy_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!phy_mem) {
+		dev_err(dev, "%s: missing mem resource\n", __func__);
+		return -ENODEV;
+	}
+
+	phy_base = devm_request_and_ioremap(dev, phy_mem);
+	if (!phy_base) {
+		dev_err(dev, "%s: register mapping failed\n", __func__);
+		return -ENXIO;
+	}
+
+	sphy = devm_kzalloc(dev, sizeof(*sphy), GFP_KERNEL);
+	if (!sphy)
+		return -ENOMEM;
+
+	clk = devm_clk_get(dev, "otg");
+	if (IS_ERR(clk)) {
+		dev_err(dev, "Failed to get otg clock\n");
+		return PTR_ERR(clk);
+	}
+
+	sphy->dev		= &pdev->dev;
+	sphy->plat		= pdata;
+	sphy->regs		= phy_base;
+	sphy->clk		= clk;
+	sphy->phy.dev		= sphy->dev;
+	sphy->phy.label		= "samsung-usbphy";
+	sphy->phy.init		= samsung_usbphy_init;
+	sphy->phy.shutdown	= samsung_usbphy_shutdown;
+	sphy->cpu_type		= samsung_usbphy_get_driver_data(pdev);
+	sphy->ref_clk_freq	= samsung_usbphy_get_refclk_freq(sphy);
+
+	platform_set_drvdata(pdev, sphy);
+
+	return usb_add_phy(&sphy->phy, USB_PHY_TYPE_USB2);
+}
+
+static int __exit samsung_usbphy_remove(struct platform_device *pdev)
+{
+	struct samsung_usbphy *sphy = platform_get_drvdata(pdev);
+
+	usb_remove_phy(&sphy->phy);
+
+	return 0;
+}
+
+#ifdef CONFIG_OF
+static const struct of_device_id samsung_usbphy_dt_match[] = {
+	{
+		.compatible = "samsung,s3c64xx-usbphy",
+		.data = (void *)TYPE_S3C64XX,
+	}, {
+		.compatible = "samsung,exynos4210-usbphy",
+		.data = (void *)TYPE_EXYNOS4210,
+	},
+	{},
+};
+MODULE_DEVICE_TABLE(of, samsung_usbphy_dt_match);
+#endif
+
+static struct platform_device_id samsung_usbphy_driver_ids[] = {
+	{
+		.name		= "s3c64xx-usbphy",
+		.driver_data	= TYPE_S3C64XX,
+	}, {
+		.name		= "exynos4210-usbphy",
+		.driver_data	= TYPE_EXYNOS4210,
+	},
+	{},
+};
+
+MODULE_DEVICE_TABLE(platform, samsung_usbphy_driver_ids);
+
+static struct platform_driver samsung_usbphy_driver = {
+	.probe		= samsung_usbphy_probe,
+	.remove		= __devexit_p(samsung_usbphy_remove),
+	.id_table	= samsung_usbphy_driver_ids,
+	.driver		= {
+		.name	= "samsung-usbphy",
+		.owner	= THIS_MODULE,
+		.of_match_table = of_match_ptr(samsung_usbphy_dt_match),
+	},
+};
+
+module_platform_driver(samsung_usbphy_driver);
+
+MODULE_DESCRIPTION("Samsung USB phy controller");
+MODULE_AUTHOR("Praveen Paneri <p.paneri@samsung.com>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:samsung-usbphy");
diff --git a/include/linux/platform_data/samsung-usbphy.h b/include/linux/platform_data/samsung-usbphy.h
new file mode 100644
index 0000000..1bd24cb
--- /dev/null
+++ b/include/linux/platform_data/samsung-usbphy.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2012 Samsung Electronics Co.Ltd
+ *		http://www.samsung.com/
+ * Author: Praveen Paneri <p.paneri@samsung.com>
+ *
+ * Defines platform data for samsung usb phy driver.
+ *
+ * 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;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#ifndef __SAMSUNG_USBPHY_PLATFORM_H
+#define __SAMSUNG_USBPHY_PLATFORM_H
+
+/**
+ * samsung_usbphy_data - Platform data for USB PHY driver.
+ * @pmu_isolation: Function to control usb phy isolation in PMU.
+ */
+struct samsung_usbphy_data {
+	void (*pmu_isolation)(int on);
+};
+
+extern void samsung_usbphy_set_pdata(struct samsung_usbphy_data *pd);
+
+#endif /* __SAMSUNG_USBPHY_PLATFORM_H */
-- 
1.7.1

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

* Re: [PATCH v8 1/2] usb: phy: samsung: Introducing usb phy driver for hsotg
  2012-11-23  4:26           ` Praveen Paneri
@ 2012-11-28 13:02               ` Tomasz Figa
  -1 siblings, 0 replies; 28+ messages in thread
From: Tomasz Figa @ 2012-11-28 13:02 UTC (permalink / raw)
  To: Praveen Paneri
  Cc: Tomasz Figa, linux-usb-u79uwXL29TY76Z2rM5mHXA,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-samsung-soc-u79uwXL29TY76Z2rM5mHXA, Kukjin Kim,
	Felipe Balbi, gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
	Thomas Abraham, ben-linux-elnMNo+KYs3YtjvyW6yDsg,
	broonie-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E,
	Lukasz Majewski, Kyungmin Park, Grant Likely, Heiko Stübner,
	Vivek Gautam

Hi Praveen,

On Friday 23 of November 2012 09:56:37 Praveen Paneri wrote:
> >> +static void samsung_usbphy_enable(struct samsung_usbphy *sphy)
> >> +{
> >> +     void __iomem *regs = sphy->regs;
> >> +     u32 phypwr;
> >> +     u32 phyclk;
> >> +     u32 rstcon;
> >> +
> >> +     /* set clock frequency for PLL */
> >> +     phyclk = sphy->ref_clk_freq;
> >> +     phypwr = readl(regs + SAMSUNG_PHYPWR);
> >> +     rstcon = readl(regs + SAMSUNG_RSTCON);
> >> +
> >> +     switch (sphy->cpu_type) {
> >> +     case TYPE_S3C64XX:
> >> +             phyclk &= ~PHYCLK_COMMON_ON_N;
> >> +             phypwr &= ~PHYPWR_NORMAL_MASK;
> >> +             rstcon |= RSTCON_SWRST;
> >> +             break;
> >> +     case TYPE_EXYNOS4210:
> >> +             phypwr &= ~PHYPWR_NORMAL_MASK_PHY0;
> >> +             rstcon |= RSTCON_SWRST;
> >> +     default:
> >> +             break;
> >> +     }
> >> +
> >> +     writel(phyclk, regs + SAMSUNG_PHYCLK);
> >> +     /* set to normal of PHY0 */
> > 
> > I don't understand this comment.
> 
> Will change it to " Configure PHY0 for normal operation"
> That should be more clear, I suppose.

Yes, much better.

> >> + */
> >> +
> >> +#ifndef __SAMSUNG_USBPHY_PLATFORM_H
> >> +#define __SAMSUNG_USBPHY_PLATFORM_H
> >> +
> >> +/**
> >> + * samsung_usbphy_data - Platform data for USB PHY driver.
> >> + * @pmu_isolation: Function to control usb phy isolation in PMU.
> >> + */
> >> +struct samsung_usbphy_data {
> >> +     void (*pmu_isolation)(int on);
> > 
> > I believe this should be named in a generic way. This is called PMU
> > isolation on Exynos SoCs, but on S3C64xx it's USB PHY mask.
> 
> Yes! I am aware of it. The fact that this ( MASK or ISOLATION) has
> always been part of the PMU, pmu_isolation seems quite generic that
> way. Though you can suggest a better name.

What do you think about set_isolation(int on) or power_isolation(int on)?

Best regards,
-- 
Tomasz Figa
Samsung Poland R&D Center
SW Solution Development, Linux Platform

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

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

* [PATCH v8 1/2] usb: phy: samsung: Introducing usb phy driver for hsotg
@ 2012-11-28 13:02               ` Tomasz Figa
  0 siblings, 0 replies; 28+ messages in thread
From: Tomasz Figa @ 2012-11-28 13:02 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Praveen,

On Friday 23 of November 2012 09:56:37 Praveen Paneri wrote:
> >> +static void samsung_usbphy_enable(struct samsung_usbphy *sphy)
> >> +{
> >> +     void __iomem *regs = sphy->regs;
> >> +     u32 phypwr;
> >> +     u32 phyclk;
> >> +     u32 rstcon;
> >> +
> >> +     /* set clock frequency for PLL */
> >> +     phyclk = sphy->ref_clk_freq;
> >> +     phypwr = readl(regs + SAMSUNG_PHYPWR);
> >> +     rstcon = readl(regs + SAMSUNG_RSTCON);
> >> +
> >> +     switch (sphy->cpu_type) {
> >> +     case TYPE_S3C64XX:
> >> +             phyclk &= ~PHYCLK_COMMON_ON_N;
> >> +             phypwr &= ~PHYPWR_NORMAL_MASK;
> >> +             rstcon |= RSTCON_SWRST;
> >> +             break;
> >> +     case TYPE_EXYNOS4210:
> >> +             phypwr &= ~PHYPWR_NORMAL_MASK_PHY0;
> >> +             rstcon |= RSTCON_SWRST;
> >> +     default:
> >> +             break;
> >> +     }
> >> +
> >> +     writel(phyclk, regs + SAMSUNG_PHYCLK);
> >> +     /* set to normal of PHY0 */
> > 
> > I don't understand this comment.
> 
> Will change it to " Configure PHY0 for normal operation"
> That should be more clear, I suppose.

Yes, much better.

> >> + */
> >> +
> >> +#ifndef __SAMSUNG_USBPHY_PLATFORM_H
> >> +#define __SAMSUNG_USBPHY_PLATFORM_H
> >> +
> >> +/**
> >> + * samsung_usbphy_data - Platform data for USB PHY driver.
> >> + * @pmu_isolation: Function to control usb phy isolation in PMU.
> >> + */
> >> +struct samsung_usbphy_data {
> >> +     void (*pmu_isolation)(int on);
> > 
> > I believe this should be named in a generic way. This is called PMU
> > isolation on Exynos SoCs, but on S3C64xx it's USB PHY mask.
> 
> Yes! I am aware of it. The fact that this ( MASK or ISOLATION) has
> always been part of the PMU, pmu_isolation seems quite generic that
> way. Though you can suggest a better name.

What do you think about set_isolation(int on) or power_isolation(int on)?

Best regards,
-- 
Tomasz Figa
Samsung Poland R&D Center
SW Solution Development, Linux Platform

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

* Re: [PATCH v8 2/2] usb: s3c-hsotg: Adding phy driver support
  2012-11-23  4:24         ` Praveen Paneri
@ 2012-11-28 13:20             ` Tomasz Figa
  -1 siblings, 0 replies; 28+ messages in thread
From: Tomasz Figa @ 2012-11-28 13:20 UTC (permalink / raw)
  To: Praveen Paneri
  Cc: Lukasz Majewski, Kukjin Kim,
	gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-usb-u79uwXL29TY76Z2rM5mHXA, Tomasz Figa, Felipe Balbi,
	Kyungmin Park, linux-samsung-soc-u79uwXL29TY76Z2rM5mHXA,
	Vivek Gautam, ben-linux-elnMNo+KYs3YtjvyW6yDsg,
	broonie-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

Hi Praveen,

On Friday 23 of November 2012 09:54:51 Praveen Paneri wrote:
> We will anyway remove the platform data part soon. If you say I can
> resend it again.

I think that the requirement for platform data on DT-enabled systems 
should be removed before this series get merged, because there are already 
patches being worked on to remove auxdata tables (common clock framework 
support by Thomas Abraham).

Adding next auxdata entry (containing platform data that must be provided) 
would make them depend on phy platform data removal patch, which would 
complicate things.

Best regards,
-- 
Tomasz Figa
Samsung Poland R&D Center
SW Solution Development, Linux Platform

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

* [PATCH v8 2/2] usb: s3c-hsotg: Adding phy driver support
@ 2012-11-28 13:20             ` Tomasz Figa
  0 siblings, 0 replies; 28+ messages in thread
From: Tomasz Figa @ 2012-11-28 13:20 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Praveen,

On Friday 23 of November 2012 09:54:51 Praveen Paneri wrote:
> We will anyway remove the platform data part soon. If you say I can
> resend it again.

I think that the requirement for platform data on DT-enabled systems 
should be removed before this series get merged, because there are already 
patches being worked on to remove auxdata tables (common clock framework 
support by Thomas Abraham).

Adding next auxdata entry (containing platform data that must be provided) 
would make them depend on phy platform data removal patch, which would 
complicate things.

Best regards,
-- 
Tomasz Figa
Samsung Poland R&D Center
SW Solution Development, Linux Platform

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

* Re: [PATCH v8 2/2] usb: s3c-hsotg: Adding phy driver support
  2012-11-28 13:20             ` Tomasz Figa
@ 2012-11-30 12:24               ` Praveen Paneri
  -1 siblings, 0 replies; 28+ messages in thread
From: Praveen Paneri @ 2012-11-30 12:24 UTC (permalink / raw)
  To: Tomasz Figa
  Cc: Tomasz Figa, linux-usb, devicetree-discuss, linux-arm-kernel,
	linux-samsung-soc, Kukjin Kim, Felipe Balbi, gregkh,
	Thomas Abraham, ben-linux, broonie, Lukasz Majewski,
	Kyungmin Park, Grant Likely, Heiko Stübner, Vivek Gautam

On Wed, Nov 28, 2012 at 6:50 PM, Tomasz Figa <t.figa@samsung.com> wrote:
> Hi Praveen,
>
> On Friday 23 of November 2012 09:54:51 Praveen Paneri wrote:
>> We will anyway remove the platform data part soon. If you say I can
>> resend it again.
>
> I think that the requirement for platform data on DT-enabled systems
> should be removed before this series get merged, because there are already
> patches being worked on to remove auxdata tables (common clock framework
> support by Thomas Abraham).
Next is to add support for 4210, 4x12 and Exynos5 (patches were sent
by vivek Gautam already). Not only s3c-hsotg but ehci, ohci and dwc
will start using phy driver.
This will remove phy related platform data passed to these drivers and...
>
> Adding next auxdata entry (containing platform data that must be provided)
> would make them depend on phy platform data removal patch, which would
> complicate things.
s3c-hsotg platform data is also passing "is_osc" (Clock source info)
and "dma" (dma mode info) from platform_data. IT seems they both are
not used as on now. May be Lukasz can tell if we can move that to
config option and get rid of s3c-hsotg_plat completely.

Once that is done only AUXDATA entry, which will be remaining, will be
that of phy driver and I understand that we have to work towards
removal of that as well but I guess this is a good first step towards
the goal.

>
> Best regards,
> --
> Tomasz Figa
> Samsung Poland R&D Center
> SW Solution Development, Linux Platform
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH v8 2/2] usb: s3c-hsotg: Adding phy driver support
@ 2012-11-30 12:24               ` Praveen Paneri
  0 siblings, 0 replies; 28+ messages in thread
From: Praveen Paneri @ 2012-11-30 12:24 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Nov 28, 2012 at 6:50 PM, Tomasz Figa <t.figa@samsung.com> wrote:
> Hi Praveen,
>
> On Friday 23 of November 2012 09:54:51 Praveen Paneri wrote:
>> We will anyway remove the platform data part soon. If you say I can
>> resend it again.
>
> I think that the requirement for platform data on DT-enabled systems
> should be removed before this series get merged, because there are already
> patches being worked on to remove auxdata tables (common clock framework
> support by Thomas Abraham).
Next is to add support for 4210, 4x12 and Exynos5 (patches were sent
by vivek Gautam already). Not only s3c-hsotg but ehci, ohci and dwc
will start using phy driver.
This will remove phy related platform data passed to these drivers and...
>
> Adding next auxdata entry (containing platform data that must be provided)
> would make them depend on phy platform data removal patch, which would
> complicate things.
s3c-hsotg platform data is also passing "is_osc" (Clock source info)
and "dma" (dma mode info) from platform_data. IT seems they both are
not used as on now. May be Lukasz can tell if we can move that to
config option and get rid of s3c-hsotg_plat completely.

Once that is done only AUXDATA entry, which will be remaining, will be
that of phy driver and I understand that we have to work towards
removal of that as well but I guess this is a good first step towards
the goal.

>
> Best regards,
> --
> Tomasz Figa
> Samsung Poland R&D Center
> SW Solution Development, Linux Platform
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH v8 1/2] usb: phy: samsung: Introducing usb phy driver for hsotg
  2012-11-28 13:02               ` Tomasz Figa
@ 2013-01-09  5:58                 ` Praveen Paneri
  -1 siblings, 0 replies; 28+ messages in thread
From: Praveen Paneri @ 2013-01-09  5:58 UTC (permalink / raw)
  To: Tomasz Figa
  Cc: Tomasz Figa, linux-usb, devicetree-discuss, linux-arm-kernel,
	linux-samsung-soc, Kukjin Kim, Felipe Balbi, gregkh,
	Thomas Abraham, ben-linux, broonie, Lukasz Majewski,
	Kyungmin Park, Grant Likely, Heiko Stübner, Vivek Gautam

Hi Tomasz,

Sorry! I I missed this comment of yours. Is it okay if we keep
pmu_isolation as it is (as it does not seem much out of the line). We
have already gone through a lot of rework and there has been no
fruitful result :(
Also after Viveks work, this is only milited to non DT SoCs.

Thanks,
Praveen

On Wed, Nov 28, 2012 at 6:32 PM, Tomasz Figa <t.figa@samsung.com> wrote:
> Hi Praveen,
>
> On Friday 23 of November 2012 09:56:37 Praveen Paneri wrote:
>> >> +static void samsung_usbphy_enable(struct samsung_usbphy *sphy)
>> >> +{
>> >> +     void __iomem *regs = sphy->regs;
>> >> +     u32 phypwr;
>> >> +     u32 phyclk;
>> >> +     u32 rstcon;
>> >> +
>> >> +     /* set clock frequency for PLL */
>> >> +     phyclk = sphy->ref_clk_freq;
>> >> +     phypwr = readl(regs + SAMSUNG_PHYPWR);
>> >> +     rstcon = readl(regs + SAMSUNG_RSTCON);
>> >> +
>> >> +     switch (sphy->cpu_type) {
>> >> +     case TYPE_S3C64XX:
>> >> +             phyclk &= ~PHYCLK_COMMON_ON_N;
>> >> +             phypwr &= ~PHYPWR_NORMAL_MASK;
>> >> +             rstcon |= RSTCON_SWRST;
>> >> +             break;
>> >> +     case TYPE_EXYNOS4210:
>> >> +             phypwr &= ~PHYPWR_NORMAL_MASK_PHY0;
>> >> +             rstcon |= RSTCON_SWRST;
>> >> +     default:
>> >> +             break;
>> >> +     }
>> >> +
>> >> +     writel(phyclk, regs + SAMSUNG_PHYCLK);
>> >> +     /* set to normal of PHY0 */
>> >
>> > I don't understand this comment.
>>
>> Will change it to " Configure PHY0 for normal operation"
>> That should be more clear, I suppose.
>
> Yes, much better.
>
>> >> + */
>> >> +
>> >> +#ifndef __SAMSUNG_USBPHY_PLATFORM_H
>> >> +#define __SAMSUNG_USBPHY_PLATFORM_H
>> >> +
>> >> +/**
>> >> + * samsung_usbphy_data - Platform data for USB PHY driver.
>> >> + * @pmu_isolation: Function to control usb phy isolation in PMU.
>> >> + */
>> >> +struct samsung_usbphy_data {
>> >> +     void (*pmu_isolation)(int on);
>> >
>> > I believe this should be named in a generic way. This is called PMU
>> > isolation on Exynos SoCs, but on S3C64xx it's USB PHY mask.
>>
>> Yes! I am aware of it. The fact that this ( MASK or ISOLATION) has
>> always been part of the PMU, pmu_isolation seems quite generic that
>> way. Though you can suggest a better name.
>
> What do you think about set_isolation(int on) or power_isolation(int on)?
Sorry! I don't understand the point here.Why to invest so much of time
and evergy on things we want to remove soon.
I am a bit reluctant to change this now, after sending 9 versions of
the same code.
Lets concentrate on more important things like AUXDATA removal or
adding support for all DT enabled machines.
>
> Best regards,
> --
> Tomasz Figa
> Samsung Poland R&D Center
> SW Solution Development, Linux Platform
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH v8 1/2] usb: phy: samsung: Introducing usb phy driver for hsotg
@ 2013-01-09  5:58                 ` Praveen Paneri
  0 siblings, 0 replies; 28+ messages in thread
From: Praveen Paneri @ 2013-01-09  5:58 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Tomasz,

Sorry! I I missed this comment of yours. Is it okay if we keep
pmu_isolation as it is (as it does not seem much out of the line). We
have already gone through a lot of rework and there has been no
fruitful result :(
Also after Viveks work, this is only milited to non DT SoCs.

Thanks,
Praveen

On Wed, Nov 28, 2012 at 6:32 PM, Tomasz Figa <t.figa@samsung.com> wrote:
> Hi Praveen,
>
> On Friday 23 of November 2012 09:56:37 Praveen Paneri wrote:
>> >> +static void samsung_usbphy_enable(struct samsung_usbphy *sphy)
>> >> +{
>> >> +     void __iomem *regs = sphy->regs;
>> >> +     u32 phypwr;
>> >> +     u32 phyclk;
>> >> +     u32 rstcon;
>> >> +
>> >> +     /* set clock frequency for PLL */
>> >> +     phyclk = sphy->ref_clk_freq;
>> >> +     phypwr = readl(regs + SAMSUNG_PHYPWR);
>> >> +     rstcon = readl(regs + SAMSUNG_RSTCON);
>> >> +
>> >> +     switch (sphy->cpu_type) {
>> >> +     case TYPE_S3C64XX:
>> >> +             phyclk &= ~PHYCLK_COMMON_ON_N;
>> >> +             phypwr &= ~PHYPWR_NORMAL_MASK;
>> >> +             rstcon |= RSTCON_SWRST;
>> >> +             break;
>> >> +     case TYPE_EXYNOS4210:
>> >> +             phypwr &= ~PHYPWR_NORMAL_MASK_PHY0;
>> >> +             rstcon |= RSTCON_SWRST;
>> >> +     default:
>> >> +             break;
>> >> +     }
>> >> +
>> >> +     writel(phyclk, regs + SAMSUNG_PHYCLK);
>> >> +     /* set to normal of PHY0 */
>> >
>> > I don't understand this comment.
>>
>> Will change it to " Configure PHY0 for normal operation"
>> That should be more clear, I suppose.
>
> Yes, much better.
>
>> >> + */
>> >> +
>> >> +#ifndef __SAMSUNG_USBPHY_PLATFORM_H
>> >> +#define __SAMSUNG_USBPHY_PLATFORM_H
>> >> +
>> >> +/**
>> >> + * samsung_usbphy_data - Platform data for USB PHY driver.
>> >> + * @pmu_isolation: Function to control usb phy isolation in PMU.
>> >> + */
>> >> +struct samsung_usbphy_data {
>> >> +     void (*pmu_isolation)(int on);
>> >
>> > I believe this should be named in a generic way. This is called PMU
>> > isolation on Exynos SoCs, but on S3C64xx it's USB PHY mask.
>>
>> Yes! I am aware of it. The fact that this ( MASK or ISOLATION) has
>> always been part of the PMU, pmu_isolation seems quite generic that
>> way. Though you can suggest a better name.
>
> What do you think about set_isolation(int on) or power_isolation(int on)?
Sorry! I don't understand the point here.Why to invest so much of time
and evergy on things we want to remove soon.
I am a bit reluctant to change this now, after sending 9 versions of
the same code.
Lets concentrate on more important things like AUXDATA removal or
adding support for all DT enabled machines.
>
> Best regards,
> --
> Tomasz Figa
> Samsung Poland R&D Center
> SW Solution Development, Linux Platform
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH v8 1/2] usb: phy: samsung: Introducing usb phy driver for hsotg
  2013-01-09  5:58                 ` Praveen Paneri
@ 2013-01-09  6:08                     ` Praveen Paneri
  -1 siblings, 0 replies; 28+ messages in thread
From: Praveen Paneri @ 2013-01-09  6:08 UTC (permalink / raw)
  To: Tomasz Figa
  Cc: Lukasz Majewski, Kukjin Kim,
	gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-usb-u79uwXL29TY76Z2rM5mHXA, Tomasz Figa, Felipe Balbi,
	Kyungmin Park, linux-samsung-soc-u79uwXL29TY76Z2rM5mHXA,
	Vivek Gautam, ben-linux-elnMNo+KYs3YtjvyW6yDsg,
	broonie-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

Hi Tomasz,

On Wed, Jan 9, 2013 at 11:28 AM, Praveen Paneri <p.paneri-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org> wrote:
> Hi Tomasz,
>
> Sorry! I I missed this comment of yours. Is it okay if we keep
> pmu_isolation as it is (as it does not seem much out of the line). We
> have already gone through a lot of rework and there has been no
> fruitful result :(
> Also after Viveks work, this is only milited to non DT SoCs.
>
> Thanks,
> Praveen
>
> On Wed, Nov 28, 2012 at 6:32 PM, Tomasz Figa <t.figa-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org> wrote:
>> Hi Praveen,
>>
>> On Friday 23 of November 2012 09:56:37 Praveen Paneri wrote:
>>> >> +static void samsung_usbphy_enable(struct samsung_usbphy *sphy)
>>> >> +{
>>> >> +     void __iomem *regs = sphy->regs;
>>> >> +     u32 phypwr;
>>> >> +     u32 phyclk;
>>> >> +     u32 rstcon;
>>> >> +
>>> >> +     /* set clock frequency for PLL */
>>> >> +     phyclk = sphy->ref_clk_freq;
>>> >> +     phypwr = readl(regs + SAMSUNG_PHYPWR);
>>> >> +     rstcon = readl(regs + SAMSUNG_RSTCON);
>>> >> +
>>> >> +     switch (sphy->cpu_type) {
>>> >> +     case TYPE_S3C64XX:
>>> >> +             phyclk &= ~PHYCLK_COMMON_ON_N;
>>> >> +             phypwr &= ~PHYPWR_NORMAL_MASK;
>>> >> +             rstcon |= RSTCON_SWRST;
>>> >> +             break;
>>> >> +     case TYPE_EXYNOS4210:
>>> >> +             phypwr &= ~PHYPWR_NORMAL_MASK_PHY0;
>>> >> +             rstcon |= RSTCON_SWRST;
>>> >> +     default:
>>> >> +             break;
>>> >> +     }
>>> >> +
>>> >> +     writel(phyclk, regs + SAMSUNG_PHYCLK);
>>> >> +     /* set to normal of PHY0 */
>>> >
>>> > I don't understand this comment.
>>>
>>> Will change it to " Configure PHY0 for normal operation"
>>> That should be more clear, I suppose.
>>
>> Yes, much better.
>>
>>> >> + */
>>> >> +
>>> >> +#ifndef __SAMSUNG_USBPHY_PLATFORM_H
>>> >> +#define __SAMSUNG_USBPHY_PLATFORM_H
>>> >> +
>>> >> +/**
>>> >> + * samsung_usbphy_data - Platform data for USB PHY driver.
>>> >> + * @pmu_isolation: Function to control usb phy isolation in PMU.
>>> >> + */
>>> >> +struct samsung_usbphy_data {
>>> >> +     void (*pmu_isolation)(int on);
>>> >
>>> > I believe this should be named in a generic way. This is called PMU
>>> > isolation on Exynos SoCs, but on S3C64xx it's USB PHY mask.
>>>
>>> Yes! I am aware of it. The fact that this ( MASK or ISOLATION) has
>>> always been part of the PMU, pmu_isolation seems quite generic that
>>> way. Though you can suggest a better name.
>>
>> What do you think about set_isolation(int on) or power_isolation(int on)?
Please ignore the below text. I did not plan to send this :P
It was just an old draft written in a bad mood :(

Regards,
Praveen
> Sorry! I don't understand the point here.Why to invest so much of time
> and evergy on things we want to remove soon.
> I am a bit reluctant to change this now, after sending 9 versions of
> the same code.
> Lets concentrate on more important things like AUXDATA removal or
> adding support for all DT enabled machines.
>>
>> Best regards,
>> --
>> Tomasz Figa
>> Samsung Poland R&D Center
>> SW Solution Development, Linux Platform
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in
>> the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH v8 1/2] usb: phy: samsung: Introducing usb phy driver for hsotg
@ 2013-01-09  6:08                     ` Praveen Paneri
  0 siblings, 0 replies; 28+ messages in thread
From: Praveen Paneri @ 2013-01-09  6:08 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Tomasz,

On Wed, Jan 9, 2013 at 11:28 AM, Praveen Paneri <p.paneri@samsung.com> wrote:
> Hi Tomasz,
>
> Sorry! I I missed this comment of yours. Is it okay if we keep
> pmu_isolation as it is (as it does not seem much out of the line). We
> have already gone through a lot of rework and there has been no
> fruitful result :(
> Also after Viveks work, this is only milited to non DT SoCs.
>
> Thanks,
> Praveen
>
> On Wed, Nov 28, 2012 at 6:32 PM, Tomasz Figa <t.figa@samsung.com> wrote:
>> Hi Praveen,
>>
>> On Friday 23 of November 2012 09:56:37 Praveen Paneri wrote:
>>> >> +static void samsung_usbphy_enable(struct samsung_usbphy *sphy)
>>> >> +{
>>> >> +     void __iomem *regs = sphy->regs;
>>> >> +     u32 phypwr;
>>> >> +     u32 phyclk;
>>> >> +     u32 rstcon;
>>> >> +
>>> >> +     /* set clock frequency for PLL */
>>> >> +     phyclk = sphy->ref_clk_freq;
>>> >> +     phypwr = readl(regs + SAMSUNG_PHYPWR);
>>> >> +     rstcon = readl(regs + SAMSUNG_RSTCON);
>>> >> +
>>> >> +     switch (sphy->cpu_type) {
>>> >> +     case TYPE_S3C64XX:
>>> >> +             phyclk &= ~PHYCLK_COMMON_ON_N;
>>> >> +             phypwr &= ~PHYPWR_NORMAL_MASK;
>>> >> +             rstcon |= RSTCON_SWRST;
>>> >> +             break;
>>> >> +     case TYPE_EXYNOS4210:
>>> >> +             phypwr &= ~PHYPWR_NORMAL_MASK_PHY0;
>>> >> +             rstcon |= RSTCON_SWRST;
>>> >> +     default:
>>> >> +             break;
>>> >> +     }
>>> >> +
>>> >> +     writel(phyclk, regs + SAMSUNG_PHYCLK);
>>> >> +     /* set to normal of PHY0 */
>>> >
>>> > I don't understand this comment.
>>>
>>> Will change it to " Configure PHY0 for normal operation"
>>> That should be more clear, I suppose.
>>
>> Yes, much better.
>>
>>> >> + */
>>> >> +
>>> >> +#ifndef __SAMSUNG_USBPHY_PLATFORM_H
>>> >> +#define __SAMSUNG_USBPHY_PLATFORM_H
>>> >> +
>>> >> +/**
>>> >> + * samsung_usbphy_data - Platform data for USB PHY driver.
>>> >> + * @pmu_isolation: Function to control usb phy isolation in PMU.
>>> >> + */
>>> >> +struct samsung_usbphy_data {
>>> >> +     void (*pmu_isolation)(int on);
>>> >
>>> > I believe this should be named in a generic way. This is called PMU
>>> > isolation on Exynos SoCs, but on S3C64xx it's USB PHY mask.
>>>
>>> Yes! I am aware of it. The fact that this ( MASK or ISOLATION) has
>>> always been part of the PMU, pmu_isolation seems quite generic that
>>> way. Though you can suggest a better name.
>>
>> What do you think about set_isolation(int on) or power_isolation(int on)?
Please ignore the below text. I did not plan to send this :P
It was just an old draft written in a bad mood :(

Regards,
Praveen
> Sorry! I don't understand the point here.Why to invest so much of time
> and evergy on things we want to remove soon.
> I am a bit reluctant to change this now, after sending 9 versions of
> the same code.
> Lets concentrate on more important things like AUXDATA removal or
> adding support for all DT enabled machines.
>>
>> Best regards,
>> --
>> Tomasz Figa
>> Samsung Poland R&D Center
>> SW Solution Development, Linux Platform
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in
>> the body of a message to majordomo at vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH v9 1/2] usb: phy: samsung: Introducing usb phy driver for hsotg
  2012-11-23 10:33               ` Praveen Paneri
@ 2013-01-09  6:30                   ` Praveen Paneri
  -1 siblings, 0 replies; 28+ messages in thread
From: Praveen Paneri @ 2013-01-09  6:30 UTC (permalink / raw)
  To: linux-usb-u79uwXL29TY76Z2rM5mHXA
  Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-samsung-soc-u79uwXL29TY76Z2rM5mHXA, Kukjin Kim,
	Felipe Balbi, gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
	Thomas Abraham, ben-linux-elnMNo+KYs3YtjvyW6yDsg,
	broonie-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E,
	Lukasz Majewski, Kyungmin Park, Grant Likely, Heiko Stübner,
	Tomasz Figa, Vivek Gautam

Hi Kukjin,

It has been a long time since I posted these patches. It will be very
kind of you to express your views about this series.
If this looks fine to you, please ack.

Thanks,
Praveen

On Fri, Nov 23, 2012 at 4:03 PM, Praveen Paneri <p.paneri-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org> wrote:
> This driver uses usb_phy interface to interact with s3c-hsotg. Supports
> phy_init and phy_shutdown functions to enable/disable usb phy. Support
> will be extended to host controllers and more Samsung SoCs.
>
> Signed-off-by: Praveen Paneri <p.paneri-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
> Acked-by: Heiko Stuebner <heiko-4mtYJXux2i+zQB+pC5nmwQ@public.gmane.org>
> Acked-by: Kyungmin Park <kyungmin.park-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
> ---
>  .../devicetree/bindings/usb/samsung-usbphy.txt     |   11 +
>  drivers/usb/phy/Kconfig                            |    8 +
>  drivers/usb/phy/Makefile                           |    1 +
>  drivers/usb/phy/samsung-usbphy.c                   |  354 ++++++++++++++++++++
>  include/linux/platform_data/samsung-usbphy.h       |   27 ++
>  5 files changed, 401 insertions(+), 0 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/usb/samsung-usbphy.txt
>  create mode 100644 drivers/usb/phy/samsung-usbphy.c
>  create mode 100644 include/linux/platform_data/samsung-usbphy.h
>
> diff --git a/Documentation/devicetree/bindings/usb/samsung-usbphy.txt b/Documentation/devicetree/bindings/usb/samsung-usbphy.txt
> new file mode 100644
> index 0000000..7b26e2d
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/usb/samsung-usbphy.txt
> @@ -0,0 +1,11 @@
> +* Samsung's usb phy transceiver
> +
> +The Samsung's phy transceiver is used for controlling usb otg phy for
> +s3c-hsotg usb device controller.
> +TODO: Adding the PHY binding with controller(s) according to the under
> +developement generic PHY driver.
> +
> +Required properties:
> +- compatible : should be "samsung,exynos4210-usbphy"
> +- reg : base physical address of the phy registers and length of memory mapped
> +       region.
> diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig
> index 7eb73c5..17ad743 100644
> --- a/drivers/usb/phy/Kconfig
> +++ b/drivers/usb/phy/Kconfig
> @@ -44,3 +44,11 @@ config USB_RCAR_PHY
>
>           To compile this driver as a module, choose M here: the
>           module will be called rcar-phy.
> +
> +config SAMSUNG_USBPHY
> +       bool "Samsung USB PHY controller Driver"
> +       depends on USB_S3C_HSOTG
> +       select USB_OTG_UTILS
> +       help
> +         Enable this to support Samsung USB phy controller for samsung
> +         SoCs.
> diff --git a/drivers/usb/phy/Makefile b/drivers/usb/phy/Makefile
> index 1a579a8..ec304f6 100644
> --- a/drivers/usb/phy/Makefile
> +++ b/drivers/usb/phy/Makefile
> @@ -9,3 +9,4 @@ 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
> +obj-$(CONFIG_SAMSUNG_USBPHY)           += samsung-usbphy.o
> diff --git a/drivers/usb/phy/samsung-usbphy.c b/drivers/usb/phy/samsung-usbphy.c
> new file mode 100644
> index 0000000..5c5e1bb
> --- /dev/null
> +++ b/drivers/usb/phy/samsung-usbphy.c
> @@ -0,0 +1,354 @@
> +/* linux/drivers/usb/phy/samsung-usbphy.c
> + *
> + * Copyright (c) 2012 Samsung Electronics Co., Ltd.
> + *              http://www.samsung.com
> + *
> + * Author: Praveen Paneri <p.paneri-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
> + *
> + * Samsung USB2.0 High-speed OTG transceiver, talks to S3C HS OTG controller
> + *
> + * 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.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; 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/platform_device.h>
> +#include <linux/clk.h>
> +#include <linux/delay.h>
> +#include <linux/err.h>
> +#include <linux/io.h>
> +#include <linux/of.h>
> +#include <linux/usb/otg.h>
> +#include <linux/platform_data/samsung-usbphy.h>
> +
> +/* Register definitions */
> +
> +#define SAMSUNG_PHYPWR                         (0x00)
> +
> +#define PHYPWR_NORMAL_MASK                     (0x19 << 0)
> +#define PHYPWR_OTG_DISABLE                     (0x1 << 4)
> +#define PHYPWR_ANALOG_POWERDOWN                        (0x1 << 3)
> +#define PHYPWR_FORCE_SUSPEND                   (0x1 << 1)
> +/* For Exynos4 */
> +#define PHYPWR_NORMAL_MASK_PHY0                        (0x39 << 0)
> +#define PHYPWR_SLEEP_PHY0                      (0x1 << 5)
> +
> +#define SAMSUNG_PHYCLK                         (0x04)
> +
> +#define PHYCLK_MODE_USB11                      (0x1 << 6)
> +#define PHYCLK_EXT_OSC                         (0x1 << 5)
> +#define PHYCLK_COMMON_ON_N                     (0x1 << 4)
> +#define PHYCLK_ID_PULL                         (0x1 << 2)
> +#define PHYCLK_CLKSEL_MASK                     (0x3 << 0)
> +#define PHYCLK_CLKSEL_48M                      (0x0 << 0)
> +#define PHYCLK_CLKSEL_12M                      (0x2 << 0)
> +#define PHYCLK_CLKSEL_24M                      (0x3 << 0)
> +
> +#define SAMSUNG_RSTCON                         (0x08)
> +
> +#define RSTCON_PHYLINK_SWRST                   (0x1 << 2)
> +#define RSTCON_HLINK_SWRST                     (0x1 << 1)
> +#define RSTCON_SWRST                           (0x1 << 0)
> +
> +#ifndef MHZ
> +#define MHZ (1000*1000)
> +#endif
> +
> +enum samsung_cpu_type {
> +       TYPE_S3C64XX,
> +       TYPE_EXYNOS4210,
> +};
> +
> +/*
> + * struct samsung_usbphy - transceiver driver state
> + * @phy: transceiver structure
> + * @plat: platform data
> + * @dev: The parent device supplied to the probe function
> + * @clk: usb phy clock
> + * @regs: usb phy register memory base
> + * @ref_clk_freq: reference clock frequency selection
> + * @cpu_type: machine identifier
> + */
> +struct samsung_usbphy {
> +       struct usb_phy  phy;
> +       struct samsung_usbphy_data *plat;
> +       struct device   *dev;
> +       struct clk      *clk;
> +       void __iomem    *regs;
> +       int             ref_clk_freq;
> +       int             cpu_type;
> +};
> +
> +#define phy_to_sphy(x)         container_of((x), struct samsung_usbphy, phy)
> +
> +/*
> + * Returns reference clock frequency selection value
> + */
> +static int samsung_usbphy_get_refclk_freq(struct samsung_usbphy *sphy)
> +{
> +       struct clk *ref_clk;
> +       int refclk_freq = 0;
> +
> +       ref_clk = clk_get(sphy->dev, "xusbxti");
> +       if (IS_ERR(ref_clk)) {
> +               dev_err(sphy->dev, "Failed to get reference clock\n");
> +               return PTR_ERR(ref_clk);
> +       }
> +
> +       switch (clk_get_rate(ref_clk)) {
> +       case 12 * MHZ:
> +               refclk_freq = PHYCLK_CLKSEL_12M;
> +               break;
> +       case 24 * MHZ:
> +               refclk_freq = PHYCLK_CLKSEL_24M;
> +               break;
> +       case 48 * MHZ:
> +               refclk_freq = PHYCLK_CLKSEL_48M;
> +               break;
> +       default:
> +               if (sphy->cpu_type == TYPE_S3C64XX)
> +                       refclk_freq = PHYCLK_CLKSEL_48M;
> +               else
> +                       refclk_freq = PHYCLK_CLKSEL_24M;
> +               break;
> +       }
> +       clk_put(ref_clk);
> +
> +       return refclk_freq;
> +}
> +
> +static void samsung_usbphy_enable(struct samsung_usbphy *sphy)
> +{
> +       void __iomem *regs = sphy->regs;
> +       u32 phypwr;
> +       u32 phyclk;
> +       u32 rstcon;
> +
> +       /* set clock frequency for PLL */
> +       phyclk = sphy->ref_clk_freq;
> +       phypwr = readl(regs + SAMSUNG_PHYPWR);
> +       rstcon = readl(regs + SAMSUNG_RSTCON);
> +
> +       switch (sphy->cpu_type) {
> +       case TYPE_S3C64XX:
> +               phyclk &= ~PHYCLK_COMMON_ON_N;
> +               phypwr &= ~PHYPWR_NORMAL_MASK;
> +               rstcon |= RSTCON_SWRST;
> +               break;
> +       case TYPE_EXYNOS4210:
> +               phypwr &= ~PHYPWR_NORMAL_MASK_PHY0;
> +               rstcon |= RSTCON_SWRST;
> +       default:
> +               break;
> +       }
> +
> +       writel(phyclk, regs + SAMSUNG_PHYCLK);
> +       /* Configure PHY0 for normal operation*/
> +       writel(phypwr, regs + SAMSUNG_PHYPWR);
> +       /* reset all ports of PHY and Link */
> +       writel(rstcon, regs + SAMSUNG_RSTCON);
> +       udelay(10);
> +       rstcon &= ~RSTCON_SWRST;
> +       writel(rstcon, regs + SAMSUNG_RSTCON);
> +}
> +
> +static void samsung_usbphy_disable(struct samsung_usbphy *sphy)
> +{
> +       void __iomem *regs = sphy->regs;
> +       u32 phypwr;
> +
> +       phypwr = readl(regs + SAMSUNG_PHYPWR);
> +
> +       switch (sphy->cpu_type) {
> +       case TYPE_S3C64XX:
> +               phypwr |= PHYPWR_NORMAL_MASK;
> +               break;
> +       case TYPE_EXYNOS4210:
> +               phypwr |= PHYPWR_NORMAL_MASK_PHY0;
> +       default:
> +               break;
> +       }
> +
> +       /* Disable analog and otg block power */
> +       writel(phypwr, regs + SAMSUNG_PHYPWR);
> +}
> +
> +/*
> + * The function passed to the usb driver for phy initialization
> + */
> +static int samsung_usbphy_init(struct usb_phy *phy)
> +{
> +       struct samsung_usbphy *sphy;
> +       int ret = 0;
> +
> +       sphy = phy_to_sphy(phy);
> +
> +       /* Enable the phy clock */
> +       ret = clk_prepare_enable(sphy->clk);
> +       if (ret) {
> +               dev_err(sphy->dev, "%s: clk_prepare_enable failed\n", __func__);
> +               return ret;
> +       }
> +
> +       /* Disable phy isolation */
> +       if (sphy->plat && sphy->plat->pmu_isolation)
> +               sphy->plat->pmu_isolation(false);
> +
> +       /* Initialize usb phy registers */
> +       samsung_usbphy_enable(sphy);
> +
> +       /* Disable the phy clock */
> +       clk_disable_unprepare(sphy->clk);
> +       return ret;
> +}
> +
> +/*
> + * The function passed to the usb driver for phy shutdown
> + */
> +static void samsung_usbphy_shutdown(struct usb_phy *phy)
> +{
> +       struct samsung_usbphy *sphy;
> +
> +       sphy = phy_to_sphy(phy);
> +
> +       if (clk_prepare_enable(sphy->clk)) {
> +               dev_err(sphy->dev, "%s: clk_prepare_enable failed\n", __func__);
> +               return;
> +       }
> +
> +       /* De-initialize usb phy registers */
> +       samsung_usbphy_disable(sphy);
> +
> +       /* Enable phy isolation */
> +       if (sphy->plat && sphy->plat->pmu_isolation)
> +               sphy->plat->pmu_isolation(true);
> +
> +       clk_disable_unprepare(sphy->clk);
> +}
> +
> +static const struct of_device_id samsung_usbphy_dt_match[];
> +
> +static inline int samsung_usbphy_get_driver_data(struct platform_device *pdev)
> +{
> +       if (pdev->dev.of_node) {
> +               const struct of_device_id *match;
> +               match = of_match_node(samsung_usbphy_dt_match,
> +                                                       pdev->dev.of_node);
> +               return (int) match->data;
> +       }
> +
> +       return platform_get_device_id(pdev)->driver_data;
> +}
> +
> +static int __devinit samsung_usbphy_probe(struct platform_device *pdev)
> +{
> +       struct samsung_usbphy *sphy;
> +       struct samsung_usbphy_data *pdata;
> +       struct device *dev = &pdev->dev;
> +       struct resource *phy_mem;
> +       void __iomem    *phy_base;
> +       struct clk *clk;
> +
> +       pdata = pdev->dev.platform_data;
> +       if (!pdata) {
> +               dev_err(&pdev->dev, "%s: no platform data defined\n", __func__);
> +               return -EINVAL;
> +       }
> +
> +       phy_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +       if (!phy_mem) {
> +               dev_err(dev, "%s: missing mem resource\n", __func__);
> +               return -ENODEV;
> +       }
> +
> +       phy_base = devm_request_and_ioremap(dev, phy_mem);
> +       if (!phy_base) {
> +               dev_err(dev, "%s: register mapping failed\n", __func__);
> +               return -ENXIO;
> +       }
> +
> +       sphy = devm_kzalloc(dev, sizeof(*sphy), GFP_KERNEL);
> +       if (!sphy)
> +               return -ENOMEM;
> +
> +       clk = devm_clk_get(dev, "otg");
> +       if (IS_ERR(clk)) {
> +               dev_err(dev, "Failed to get otg clock\n");
> +               return PTR_ERR(clk);
> +       }
> +
> +       sphy->dev               = &pdev->dev;
> +       sphy->plat              = pdata;
> +       sphy->regs              = phy_base;
> +       sphy->clk               = clk;
> +       sphy->phy.dev           = sphy->dev;
> +       sphy->phy.label         = "samsung-usbphy";
> +       sphy->phy.init          = samsung_usbphy_init;
> +       sphy->phy.shutdown      = samsung_usbphy_shutdown;
> +       sphy->cpu_type          = samsung_usbphy_get_driver_data(pdev);
> +       sphy->ref_clk_freq      = samsung_usbphy_get_refclk_freq(sphy);
> +
> +       platform_set_drvdata(pdev, sphy);
> +
> +       return usb_add_phy(&sphy->phy, USB_PHY_TYPE_USB2);
> +}
> +
> +static int __exit samsung_usbphy_remove(struct platform_device *pdev)
> +{
> +       struct samsung_usbphy *sphy = platform_get_drvdata(pdev);
> +
> +       usb_remove_phy(&sphy->phy);
> +
> +       return 0;
> +}
> +
> +#ifdef CONFIG_OF
> +static const struct of_device_id samsung_usbphy_dt_match[] = {
> +       {
> +               .compatible = "samsung,s3c64xx-usbphy",
> +               .data = (void *)TYPE_S3C64XX,
> +       }, {
> +               .compatible = "samsung,exynos4210-usbphy",
> +               .data = (void *)TYPE_EXYNOS4210,
> +       },
> +       {},
> +};
> +MODULE_DEVICE_TABLE(of, samsung_usbphy_dt_match);
> +#endif
> +
> +static struct platform_device_id samsung_usbphy_driver_ids[] = {
> +       {
> +               .name           = "s3c64xx-usbphy",
> +               .driver_data    = TYPE_S3C64XX,
> +       }, {
> +               .name           = "exynos4210-usbphy",
> +               .driver_data    = TYPE_EXYNOS4210,
> +       },
> +       {},
> +};
> +
> +MODULE_DEVICE_TABLE(platform, samsung_usbphy_driver_ids);
> +
> +static struct platform_driver samsung_usbphy_driver = {
> +       .probe          = samsung_usbphy_probe,
> +       .remove         = __devexit_p(samsung_usbphy_remove),
> +       .id_table       = samsung_usbphy_driver_ids,
> +       .driver         = {
> +               .name   = "samsung-usbphy",
> +               .owner  = THIS_MODULE,
> +               .of_match_table = of_match_ptr(samsung_usbphy_dt_match),
> +       },
> +};
> +
> +module_platform_driver(samsung_usbphy_driver);
> +
> +MODULE_DESCRIPTION("Samsung USB phy controller");
> +MODULE_AUTHOR("Praveen Paneri <p.paneri-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>");
> +MODULE_LICENSE("GPL");
> +MODULE_ALIAS("platform:samsung-usbphy");
> diff --git a/include/linux/platform_data/samsung-usbphy.h b/include/linux/platform_data/samsung-usbphy.h
> new file mode 100644
> index 0000000..1bd24cb
> --- /dev/null
> +++ b/include/linux/platform_data/samsung-usbphy.h
> @@ -0,0 +1,27 @@
> +/*
> + * Copyright (C) 2012 Samsung Electronics Co.Ltd
> + *             http://www.samsung.com/
> + * Author: Praveen Paneri <p.paneri-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
> + *
> + * Defines platform data for samsung usb phy driver.
> + *
> + * 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;  either version 2 of the  License, or (at your
> + * option) any later version.
> + */
> +
> +#ifndef __SAMSUNG_USBPHY_PLATFORM_H
> +#define __SAMSUNG_USBPHY_PLATFORM_H
> +
> +/**
> + * samsung_usbphy_data - Platform data for USB PHY driver.
> + * @pmu_isolation: Function to control usb phy isolation in PMU.
> + */
> +struct samsung_usbphy_data {
> +       void (*pmu_isolation)(int on);
> +};
> +
> +extern void samsung_usbphy_set_pdata(struct samsung_usbphy_data *pd);
> +
> +#endif /* __SAMSUNG_USBPHY_PLATFORM_H */
> --
> 1.7.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-usb" in
> the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH v9 1/2] usb: phy: samsung: Introducing usb phy driver for hsotg
@ 2013-01-09  6:30                   ` Praveen Paneri
  0 siblings, 0 replies; 28+ messages in thread
From: Praveen Paneri @ 2013-01-09  6:30 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Kukjin,

It has been a long time since I posted these patches. It will be very
kind of you to express your views about this series.
If this looks fine to you, please ack.

Thanks,
Praveen

On Fri, Nov 23, 2012 at 4:03 PM, Praveen Paneri <p.paneri@samsung.com> wrote:
> This driver uses usb_phy interface to interact with s3c-hsotg. Supports
> phy_init and phy_shutdown functions to enable/disable usb phy. Support
> will be extended to host controllers and more Samsung SoCs.
>
> Signed-off-by: Praveen Paneri <p.paneri@samsung.com>
> Acked-by: Heiko Stuebner <heiko@sntech.de>
> Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
> ---
>  .../devicetree/bindings/usb/samsung-usbphy.txt     |   11 +
>  drivers/usb/phy/Kconfig                            |    8 +
>  drivers/usb/phy/Makefile                           |    1 +
>  drivers/usb/phy/samsung-usbphy.c                   |  354 ++++++++++++++++++++
>  include/linux/platform_data/samsung-usbphy.h       |   27 ++
>  5 files changed, 401 insertions(+), 0 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/usb/samsung-usbphy.txt
>  create mode 100644 drivers/usb/phy/samsung-usbphy.c
>  create mode 100644 include/linux/platform_data/samsung-usbphy.h
>
> diff --git a/Documentation/devicetree/bindings/usb/samsung-usbphy.txt b/Documentation/devicetree/bindings/usb/samsung-usbphy.txt
> new file mode 100644
> index 0000000..7b26e2d
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/usb/samsung-usbphy.txt
> @@ -0,0 +1,11 @@
> +* Samsung's usb phy transceiver
> +
> +The Samsung's phy transceiver is used for controlling usb otg phy for
> +s3c-hsotg usb device controller.
> +TODO: Adding the PHY binding with controller(s) according to the under
> +developement generic PHY driver.
> +
> +Required properties:
> +- compatible : should be "samsung,exynos4210-usbphy"
> +- reg : base physical address of the phy registers and length of memory mapped
> +       region.
> diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig
> index 7eb73c5..17ad743 100644
> --- a/drivers/usb/phy/Kconfig
> +++ b/drivers/usb/phy/Kconfig
> @@ -44,3 +44,11 @@ config USB_RCAR_PHY
>
>           To compile this driver as a module, choose M here: the
>           module will be called rcar-phy.
> +
> +config SAMSUNG_USBPHY
> +       bool "Samsung USB PHY controller Driver"
> +       depends on USB_S3C_HSOTG
> +       select USB_OTG_UTILS
> +       help
> +         Enable this to support Samsung USB phy controller for samsung
> +         SoCs.
> diff --git a/drivers/usb/phy/Makefile b/drivers/usb/phy/Makefile
> index 1a579a8..ec304f6 100644
> --- a/drivers/usb/phy/Makefile
> +++ b/drivers/usb/phy/Makefile
> @@ -9,3 +9,4 @@ 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
> +obj-$(CONFIG_SAMSUNG_USBPHY)           += samsung-usbphy.o
> diff --git a/drivers/usb/phy/samsung-usbphy.c b/drivers/usb/phy/samsung-usbphy.c
> new file mode 100644
> index 0000000..5c5e1bb
> --- /dev/null
> +++ b/drivers/usb/phy/samsung-usbphy.c
> @@ -0,0 +1,354 @@
> +/* linux/drivers/usb/phy/samsung-usbphy.c
> + *
> + * Copyright (c) 2012 Samsung Electronics Co., Ltd.
> + *              http://www.samsung.com
> + *
> + * Author: Praveen Paneri <p.paneri@samsung.com>
> + *
> + * Samsung USB2.0 High-speed OTG transceiver, talks to S3C HS OTG controller
> + *
> + * 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.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; 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/platform_device.h>
> +#include <linux/clk.h>
> +#include <linux/delay.h>
> +#include <linux/err.h>
> +#include <linux/io.h>
> +#include <linux/of.h>
> +#include <linux/usb/otg.h>
> +#include <linux/platform_data/samsung-usbphy.h>
> +
> +/* Register definitions */
> +
> +#define SAMSUNG_PHYPWR                         (0x00)
> +
> +#define PHYPWR_NORMAL_MASK                     (0x19 << 0)
> +#define PHYPWR_OTG_DISABLE                     (0x1 << 4)
> +#define PHYPWR_ANALOG_POWERDOWN                        (0x1 << 3)
> +#define PHYPWR_FORCE_SUSPEND                   (0x1 << 1)
> +/* For Exynos4 */
> +#define PHYPWR_NORMAL_MASK_PHY0                        (0x39 << 0)
> +#define PHYPWR_SLEEP_PHY0                      (0x1 << 5)
> +
> +#define SAMSUNG_PHYCLK                         (0x04)
> +
> +#define PHYCLK_MODE_USB11                      (0x1 << 6)
> +#define PHYCLK_EXT_OSC                         (0x1 << 5)
> +#define PHYCLK_COMMON_ON_N                     (0x1 << 4)
> +#define PHYCLK_ID_PULL                         (0x1 << 2)
> +#define PHYCLK_CLKSEL_MASK                     (0x3 << 0)
> +#define PHYCLK_CLKSEL_48M                      (0x0 << 0)
> +#define PHYCLK_CLKSEL_12M                      (0x2 << 0)
> +#define PHYCLK_CLKSEL_24M                      (0x3 << 0)
> +
> +#define SAMSUNG_RSTCON                         (0x08)
> +
> +#define RSTCON_PHYLINK_SWRST                   (0x1 << 2)
> +#define RSTCON_HLINK_SWRST                     (0x1 << 1)
> +#define RSTCON_SWRST                           (0x1 << 0)
> +
> +#ifndef MHZ
> +#define MHZ (1000*1000)
> +#endif
> +
> +enum samsung_cpu_type {
> +       TYPE_S3C64XX,
> +       TYPE_EXYNOS4210,
> +};
> +
> +/*
> + * struct samsung_usbphy - transceiver driver state
> + * @phy: transceiver structure
> + * @plat: platform data
> + * @dev: The parent device supplied to the probe function
> + * @clk: usb phy clock
> + * @regs: usb phy register memory base
> + * @ref_clk_freq: reference clock frequency selection
> + * @cpu_type: machine identifier
> + */
> +struct samsung_usbphy {
> +       struct usb_phy  phy;
> +       struct samsung_usbphy_data *plat;
> +       struct device   *dev;
> +       struct clk      *clk;
> +       void __iomem    *regs;
> +       int             ref_clk_freq;
> +       int             cpu_type;
> +};
> +
> +#define phy_to_sphy(x)         container_of((x), struct samsung_usbphy, phy)
> +
> +/*
> + * Returns reference clock frequency selection value
> + */
> +static int samsung_usbphy_get_refclk_freq(struct samsung_usbphy *sphy)
> +{
> +       struct clk *ref_clk;
> +       int refclk_freq = 0;
> +
> +       ref_clk = clk_get(sphy->dev, "xusbxti");
> +       if (IS_ERR(ref_clk)) {
> +               dev_err(sphy->dev, "Failed to get reference clock\n");
> +               return PTR_ERR(ref_clk);
> +       }
> +
> +       switch (clk_get_rate(ref_clk)) {
> +       case 12 * MHZ:
> +               refclk_freq = PHYCLK_CLKSEL_12M;
> +               break;
> +       case 24 * MHZ:
> +               refclk_freq = PHYCLK_CLKSEL_24M;
> +               break;
> +       case 48 * MHZ:
> +               refclk_freq = PHYCLK_CLKSEL_48M;
> +               break;
> +       default:
> +               if (sphy->cpu_type == TYPE_S3C64XX)
> +                       refclk_freq = PHYCLK_CLKSEL_48M;
> +               else
> +                       refclk_freq = PHYCLK_CLKSEL_24M;
> +               break;
> +       }
> +       clk_put(ref_clk);
> +
> +       return refclk_freq;
> +}
> +
> +static void samsung_usbphy_enable(struct samsung_usbphy *sphy)
> +{
> +       void __iomem *regs = sphy->regs;
> +       u32 phypwr;
> +       u32 phyclk;
> +       u32 rstcon;
> +
> +       /* set clock frequency for PLL */
> +       phyclk = sphy->ref_clk_freq;
> +       phypwr = readl(regs + SAMSUNG_PHYPWR);
> +       rstcon = readl(regs + SAMSUNG_RSTCON);
> +
> +       switch (sphy->cpu_type) {
> +       case TYPE_S3C64XX:
> +               phyclk &= ~PHYCLK_COMMON_ON_N;
> +               phypwr &= ~PHYPWR_NORMAL_MASK;
> +               rstcon |= RSTCON_SWRST;
> +               break;
> +       case TYPE_EXYNOS4210:
> +               phypwr &= ~PHYPWR_NORMAL_MASK_PHY0;
> +               rstcon |= RSTCON_SWRST;
> +       default:
> +               break;
> +       }
> +
> +       writel(phyclk, regs + SAMSUNG_PHYCLK);
> +       /* Configure PHY0 for normal operation*/
> +       writel(phypwr, regs + SAMSUNG_PHYPWR);
> +       /* reset all ports of PHY and Link */
> +       writel(rstcon, regs + SAMSUNG_RSTCON);
> +       udelay(10);
> +       rstcon &= ~RSTCON_SWRST;
> +       writel(rstcon, regs + SAMSUNG_RSTCON);
> +}
> +
> +static void samsung_usbphy_disable(struct samsung_usbphy *sphy)
> +{
> +       void __iomem *regs = sphy->regs;
> +       u32 phypwr;
> +
> +       phypwr = readl(regs + SAMSUNG_PHYPWR);
> +
> +       switch (sphy->cpu_type) {
> +       case TYPE_S3C64XX:
> +               phypwr |= PHYPWR_NORMAL_MASK;
> +               break;
> +       case TYPE_EXYNOS4210:
> +               phypwr |= PHYPWR_NORMAL_MASK_PHY0;
> +       default:
> +               break;
> +       }
> +
> +       /* Disable analog and otg block power */
> +       writel(phypwr, regs + SAMSUNG_PHYPWR);
> +}
> +
> +/*
> + * The function passed to the usb driver for phy initialization
> + */
> +static int samsung_usbphy_init(struct usb_phy *phy)
> +{
> +       struct samsung_usbphy *sphy;
> +       int ret = 0;
> +
> +       sphy = phy_to_sphy(phy);
> +
> +       /* Enable the phy clock */
> +       ret = clk_prepare_enable(sphy->clk);
> +       if (ret) {
> +               dev_err(sphy->dev, "%s: clk_prepare_enable failed\n", __func__);
> +               return ret;
> +       }
> +
> +       /* Disable phy isolation */
> +       if (sphy->plat && sphy->plat->pmu_isolation)
> +               sphy->plat->pmu_isolation(false);
> +
> +       /* Initialize usb phy registers */
> +       samsung_usbphy_enable(sphy);
> +
> +       /* Disable the phy clock */
> +       clk_disable_unprepare(sphy->clk);
> +       return ret;
> +}
> +
> +/*
> + * The function passed to the usb driver for phy shutdown
> + */
> +static void samsung_usbphy_shutdown(struct usb_phy *phy)
> +{
> +       struct samsung_usbphy *sphy;
> +
> +       sphy = phy_to_sphy(phy);
> +
> +       if (clk_prepare_enable(sphy->clk)) {
> +               dev_err(sphy->dev, "%s: clk_prepare_enable failed\n", __func__);
> +               return;
> +       }
> +
> +       /* De-initialize usb phy registers */
> +       samsung_usbphy_disable(sphy);
> +
> +       /* Enable phy isolation */
> +       if (sphy->plat && sphy->plat->pmu_isolation)
> +               sphy->plat->pmu_isolation(true);
> +
> +       clk_disable_unprepare(sphy->clk);
> +}
> +
> +static const struct of_device_id samsung_usbphy_dt_match[];
> +
> +static inline int samsung_usbphy_get_driver_data(struct platform_device *pdev)
> +{
> +       if (pdev->dev.of_node) {
> +               const struct of_device_id *match;
> +               match = of_match_node(samsung_usbphy_dt_match,
> +                                                       pdev->dev.of_node);
> +               return (int) match->data;
> +       }
> +
> +       return platform_get_device_id(pdev)->driver_data;
> +}
> +
> +static int __devinit samsung_usbphy_probe(struct platform_device *pdev)
> +{
> +       struct samsung_usbphy *sphy;
> +       struct samsung_usbphy_data *pdata;
> +       struct device *dev = &pdev->dev;
> +       struct resource *phy_mem;
> +       void __iomem    *phy_base;
> +       struct clk *clk;
> +
> +       pdata = pdev->dev.platform_data;
> +       if (!pdata) {
> +               dev_err(&pdev->dev, "%s: no platform data defined\n", __func__);
> +               return -EINVAL;
> +       }
> +
> +       phy_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +       if (!phy_mem) {
> +               dev_err(dev, "%s: missing mem resource\n", __func__);
> +               return -ENODEV;
> +       }
> +
> +       phy_base = devm_request_and_ioremap(dev, phy_mem);
> +       if (!phy_base) {
> +               dev_err(dev, "%s: register mapping failed\n", __func__);
> +               return -ENXIO;
> +       }
> +
> +       sphy = devm_kzalloc(dev, sizeof(*sphy), GFP_KERNEL);
> +       if (!sphy)
> +               return -ENOMEM;
> +
> +       clk = devm_clk_get(dev, "otg");
> +       if (IS_ERR(clk)) {
> +               dev_err(dev, "Failed to get otg clock\n");
> +               return PTR_ERR(clk);
> +       }
> +
> +       sphy->dev               = &pdev->dev;
> +       sphy->plat              = pdata;
> +       sphy->regs              = phy_base;
> +       sphy->clk               = clk;
> +       sphy->phy.dev           = sphy->dev;
> +       sphy->phy.label         = "samsung-usbphy";
> +       sphy->phy.init          = samsung_usbphy_init;
> +       sphy->phy.shutdown      = samsung_usbphy_shutdown;
> +       sphy->cpu_type          = samsung_usbphy_get_driver_data(pdev);
> +       sphy->ref_clk_freq      = samsung_usbphy_get_refclk_freq(sphy);
> +
> +       platform_set_drvdata(pdev, sphy);
> +
> +       return usb_add_phy(&sphy->phy, USB_PHY_TYPE_USB2);
> +}
> +
> +static int __exit samsung_usbphy_remove(struct platform_device *pdev)
> +{
> +       struct samsung_usbphy *sphy = platform_get_drvdata(pdev);
> +
> +       usb_remove_phy(&sphy->phy);
> +
> +       return 0;
> +}
> +
> +#ifdef CONFIG_OF
> +static const struct of_device_id samsung_usbphy_dt_match[] = {
> +       {
> +               .compatible = "samsung,s3c64xx-usbphy",
> +               .data = (void *)TYPE_S3C64XX,
> +       }, {
> +               .compatible = "samsung,exynos4210-usbphy",
> +               .data = (void *)TYPE_EXYNOS4210,
> +       },
> +       {},
> +};
> +MODULE_DEVICE_TABLE(of, samsung_usbphy_dt_match);
> +#endif
> +
> +static struct platform_device_id samsung_usbphy_driver_ids[] = {
> +       {
> +               .name           = "s3c64xx-usbphy",
> +               .driver_data    = TYPE_S3C64XX,
> +       }, {
> +               .name           = "exynos4210-usbphy",
> +               .driver_data    = TYPE_EXYNOS4210,
> +       },
> +       {},
> +};
> +
> +MODULE_DEVICE_TABLE(platform, samsung_usbphy_driver_ids);
> +
> +static struct platform_driver samsung_usbphy_driver = {
> +       .probe          = samsung_usbphy_probe,
> +       .remove         = __devexit_p(samsung_usbphy_remove),
> +       .id_table       = samsung_usbphy_driver_ids,
> +       .driver         = {
> +               .name   = "samsung-usbphy",
> +               .owner  = THIS_MODULE,
> +               .of_match_table = of_match_ptr(samsung_usbphy_dt_match),
> +       },
> +};
> +
> +module_platform_driver(samsung_usbphy_driver);
> +
> +MODULE_DESCRIPTION("Samsung USB phy controller");
> +MODULE_AUTHOR("Praveen Paneri <p.paneri@samsung.com>");
> +MODULE_LICENSE("GPL");
> +MODULE_ALIAS("platform:samsung-usbphy");
> diff --git a/include/linux/platform_data/samsung-usbphy.h b/include/linux/platform_data/samsung-usbphy.h
> new file mode 100644
> index 0000000..1bd24cb
> --- /dev/null
> +++ b/include/linux/platform_data/samsung-usbphy.h
> @@ -0,0 +1,27 @@
> +/*
> + * Copyright (C) 2012 Samsung Electronics Co.Ltd
> + *             http://www.samsung.com/
> + * Author: Praveen Paneri <p.paneri@samsung.com>
> + *
> + * Defines platform data for samsung usb phy driver.
> + *
> + * 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;  either version 2 of the  License, or (at your
> + * option) any later version.
> + */
> +
> +#ifndef __SAMSUNG_USBPHY_PLATFORM_H
> +#define __SAMSUNG_USBPHY_PLATFORM_H
> +
> +/**
> + * samsung_usbphy_data - Platform data for USB PHY driver.
> + * @pmu_isolation: Function to control usb phy isolation in PMU.
> + */
> +struct samsung_usbphy_data {
> +       void (*pmu_isolation)(int on);
> +};
> +
> +extern void samsung_usbphy_set_pdata(struct samsung_usbphy_data *pd);
> +
> +#endif /* __SAMSUNG_USBPHY_PLATFORM_H */
> --
> 1.7.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-usb" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

end of thread, other threads:[~2013-01-09  6:30 UTC | newest]

Thread overview: 28+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-11-14 10:27 [PATCH v8 0/2] usb: phy: samsung: Introducing usb phy driver for samsung SoCs Praveen Paneri
2012-11-14 10:27 ` Praveen Paneri
     [not found] ` <1352888836-17192-1-git-send-email-p.paneri-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
2012-11-14 10:27   ` [PATCH v8 1/2] usb: phy: samsung: Introducing usb phy driver for hsotg Praveen Paneri
2012-11-14 10:27     ` Praveen Paneri
     [not found]     ` <1352888836-17192-2-git-send-email-p.paneri-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
2012-11-21 20:06       ` Tomasz Figa
2012-11-21 20:06         ` Tomasz Figa
2012-11-23  4:26         ` Praveen Paneri
2012-11-23  4:26           ` Praveen Paneri
     [not found]           ` <CAD6zSYO77GTqVux7B0wDsrj0+332-jU0ivqKY7ExRSKZuHYjDQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2012-11-23 10:33             ` [PATCH v9 " Praveen Paneri
2012-11-23 10:33               ` Praveen Paneri
     [not found]               ` <1353666786-10584-1-git-send-email-p.paneri-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
2013-01-09  6:30                 ` Praveen Paneri
2013-01-09  6:30                   ` Praveen Paneri
2012-11-28 13:02             ` [PATCH v8 " Tomasz Figa
2012-11-28 13:02               ` Tomasz Figa
2013-01-09  5:58               ` Praveen Paneri
2013-01-09  5:58                 ` Praveen Paneri
     [not found]                 ` <CAD6zSYPvAm2cSZ7wABYM3QNs9qbKf6yPKxdkP-RripK5OGrWag-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2013-01-09  6:08                   ` Praveen Paneri
2013-01-09  6:08                     ` Praveen Paneri
2012-11-14 10:27 ` [PATCH v8 2/2] usb: s3c-hsotg: Adding phy driver support Praveen Paneri
2012-11-14 10:27   ` Praveen Paneri
     [not found]   ` <1352888836-17192-3-git-send-email-p.paneri-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
2012-11-21 20:11     ` Tomasz Figa
2012-11-21 20:11       ` Tomasz Figa
2012-11-23  4:24       ` Praveen Paneri
2012-11-23  4:24         ` Praveen Paneri
     [not found]         ` <CAD6zSYMNSX8ASPBLpft-0riBi-xeD_b=BjCjSrftX_5_F2+TDA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2012-11-28 13:20           ` Tomasz Figa
2012-11-28 13:20             ` Tomasz Figa
2012-11-30 12:24             ` Praveen Paneri
2012-11-30 12:24               ` Praveen Paneri

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.